From 7ef263307ae23051950b69e7ef1b01c046e30676 Mon Sep 17 00:00:00 2001 From: Nizar Benalla Date: Thu, 14 Nov 2024 22:01:17 +0000 Subject: [PATCH 001/311] 8344128: Regression: make help broken after JDK-8340818 Reviewed-by: rriggs, dholmes, ihse --- make/Global.gmk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/make/Global.gmk b/make/Global.gmk index 16a5b05cccb..3e6721f994c 100644 --- a/make/Global.gmk +++ b/make/Global.gmk @@ -102,7 +102,7 @@ help: $(info $(_) # method is 'auto', 'ignore' or 'fail' (default)) $(info $(_) TEST="test1 ..." # Use the given test descriptor(s) for testing, e.g.) $(info $(_) # make test TEST="jdk_lang gtest:all") - $(info $(_) TEST_DEPS="dependency1 ..." # Specify additional dependencies for running tests, e.g docs-jdk + $(info $(_) TEST_DEPS="dependency1 ..." # Specify additional dependencies for running tests, e.g docs-jdk) $(info $(_) JTREG="OPT1=x;OPT2=y" # Control the JTREG test harness, use 'make test-only JTREG=help' to list) $(info $(_) GTEST="OPT1=x;OPT2=y" # Control the GTEST test harness, use 'make test-only GTEST=help' to list) $(info $(_) MICRO="OPT1=x;OPT2=y" # Control the MICRO test harness, use 'make test-only MICRO=help' to list) From db56266ad164b4ecae59451dc0a832097dbfbd8e Mon Sep 17 00:00:00 2001 From: David Holmes Date: Thu, 14 Nov 2024 22:23:16 +0000 Subject: [PATCH 002/311] 8344250: Obsolete the DontYieldALot flag Reviewed-by: darcy, matsaave, iklam --- src/hotspot/os/posix/os_posix.cpp | 4 ---- src/hotspot/os/windows/os_windows.cpp | 6 ------ src/hotspot/os_cpu/aix_ppc/globals_aix_ppc.hpp | 3 +-- src/hotspot/os_cpu/bsd_aarch64/globals_bsd_aarch64.hpp | 3 +-- src/hotspot/os_cpu/bsd_x86/globals_bsd_x86.hpp | 3 +-- src/hotspot/os_cpu/bsd_zero/globals_bsd_zero.hpp | 3 +-- src/hotspot/os_cpu/linux_aarch64/globals_linux_aarch64.hpp | 4 +--- src/hotspot/os_cpu/linux_arm/globals_linux_arm.hpp | 3 +-- src/hotspot/os_cpu/linux_ppc/globals_linux_ppc.hpp | 3 +-- src/hotspot/os_cpu/linux_riscv/globals_linux_riscv.hpp | 3 +-- src/hotspot/os_cpu/linux_s390/globals_linux_s390.hpp | 3 +-- src/hotspot/os_cpu/linux_x86/globals_linux_x86.hpp | 3 +-- src/hotspot/os_cpu/linux_zero/globals_linux_zero.hpp | 3 +-- .../os_cpu/windows_aarch64/globals_windows_aarch64.hpp | 2 -- src/hotspot/os_cpu/windows_x86/globals_windows_x86.hpp | 4 +--- src/hotspot/share/prims/jvm.cpp | 1 - src/hotspot/share/runtime/globals.hpp | 3 --- src/hotspot/share/runtime/os.hpp | 2 -- 18 files changed, 12 insertions(+), 44 deletions(-) diff --git a/src/hotspot/os/posix/os_posix.cpp b/src/hotspot/os/posix/os_posix.cpp index 72330190b53..9aae3b5c143 100644 --- a/src/hotspot/os/posix/os_posix.cpp +++ b/src/hotspot/os/posix/os_posix.cpp @@ -931,10 +931,6 @@ void os::_exit(int num) { ALLOW_C_FUNCTION(::_exit, ::_exit(num);) } -bool os::dont_yield() { - return DontYieldALot; -} - void os::naked_yield() { sched_yield(); } diff --git a/src/hotspot/os/windows/os_windows.cpp b/src/hotspot/os/windows/os_windows.cpp index 9d514e584a4..fd857c2cd95 100644 --- a/src/hotspot/os/windows/os_windows.cpp +++ b/src/hotspot/os/windows/os_windows.cpp @@ -4856,12 +4856,6 @@ int os::loadavg(double loadavg[], int nelem) { return -1; } - -// DontYieldALot=false by default: dutifully perform all yields as requested by JVM_Yield() -bool os::dont_yield() { - return DontYieldALot; -} - int os::open(const char *path, int oflag, int mode) { errno_t err; wchar_t* wide_path = wide_abs_unc_path(path, err); diff --git a/src/hotspot/os_cpu/aix_ppc/globals_aix_ppc.hpp b/src/hotspot/os_cpu/aix_ppc/globals_aix_ppc.hpp index b946ce15fa0..e8b04add19d 100644 --- a/src/hotspot/os_cpu/aix_ppc/globals_aix_ppc.hpp +++ b/src/hotspot/os_cpu/aix_ppc/globals_aix_ppc.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2024, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2012, 2015 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -29,7 +29,6 @@ // Sets the default values for platform dependent flags used by the runtime system. // (see globals.hpp) -define_pd_global(bool, DontYieldALot, false); define_pd_global(intx, ThreadStackSize, 2048); // 0 => use system default define_pd_global(intx, VMThreadStackSize, 2048); diff --git a/src/hotspot/os_cpu/bsd_aarch64/globals_bsd_aarch64.hpp b/src/hotspot/os_cpu/bsd_aarch64/globals_bsd_aarch64.hpp index c18c4506ac9..4a10e7af091 100644 --- a/src/hotspot/os_cpu/bsd_aarch64/globals_bsd_aarch64.hpp +++ b/src/hotspot/os_cpu/bsd_aarch64/globals_bsd_aarch64.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2024, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2014, Red Hat Inc. All rights reserved. * Copyright (c) 2021, Azul Systems, Inc. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. @@ -31,7 +31,6 @@ // Sets the default values for platform dependent flags used by the runtime system. // (see globals.hpp) -define_pd_global(bool, DontYieldALot, false); define_pd_global(intx, ThreadStackSize, 2048); // 0 => use system default define_pd_global(intx, VMThreadStackSize, 2048); diff --git a/src/hotspot/os_cpu/bsd_x86/globals_bsd_x86.hpp b/src/hotspot/os_cpu/bsd_x86/globals_bsd_x86.hpp index a434e329a8b..f67bb15c69e 100644 --- a/src/hotspot/os_cpu/bsd_x86/globals_bsd_x86.hpp +++ b/src/hotspot/os_cpu/bsd_x86/globals_bsd_x86.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -29,7 +29,6 @@ // Sets the default values for platform dependent flags used by the runtime system. // (see globals.hpp) // -define_pd_global(bool, DontYieldALot, false); #ifdef AMD64 define_pd_global(intx, CompilerThreadStackSize, 1024); define_pd_global(intx, ThreadStackSize, 1024); // 0 => use system default diff --git a/src/hotspot/os_cpu/bsd_zero/globals_bsd_zero.hpp b/src/hotspot/os_cpu/bsd_zero/globals_bsd_zero.hpp index 71aa9043e9e..daf2fd8f2a6 100644 --- a/src/hotspot/os_cpu/bsd_zero/globals_bsd_zero.hpp +++ b/src/hotspot/os_cpu/bsd_zero/globals_bsd_zero.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2024, Oracle and/or its affiliates. All rights reserved. * Copyright 2007, 2008, 2010 Red Hat, Inc. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -31,7 +31,6 @@ // runtime system. See globals.hpp for details of what they do. // -define_pd_global(bool, DontYieldALot, false); define_pd_global(intx, ThreadStackSize, 1536); #ifdef _LP64 define_pd_global(intx, VMThreadStackSize, 1024); diff --git a/src/hotspot/os_cpu/linux_aarch64/globals_linux_aarch64.hpp b/src/hotspot/os_cpu/linux_aarch64/globals_linux_aarch64.hpp index c4219c2bac3..955a0ae9dcd 100644 --- a/src/hotspot/os_cpu/linux_aarch64/globals_linux_aarch64.hpp +++ b/src/hotspot/os_cpu/linux_aarch64/globals_linux_aarch64.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2024, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2014, Red Hat Inc. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -29,8 +29,6 @@ // Sets the default values for platform dependent flags used by the runtime system. // (see globals.hpp) -define_pd_global(bool, DontYieldALot, false); - // Set default stack sizes < 2MB so as to prevent stacks from getting // large-page aligned and backed by THPs on systems where 2MB is the // default huge page size. For non-JavaThreads, glibc may add an additional diff --git a/src/hotspot/os_cpu/linux_arm/globals_linux_arm.hpp b/src/hotspot/os_cpu/linux_arm/globals_linux_arm.hpp index 4f2d3918a4d..c4ffdf2c02e 100644 --- a/src/hotspot/os_cpu/linux_arm/globals_linux_arm.hpp +++ b/src/hotspot/os_cpu/linux_arm/globals_linux_arm.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -29,7 +29,6 @@ // Sets the default values for platform dependent flags used by the runtime system. // (see globals.hpp) // -define_pd_global(bool, DontYieldALot, false); define_pd_global(intx, CompilerThreadStackSize, 512); // System default ThreadStackSize appears to be 512 which is too big. define_pd_global(intx, ThreadStackSize, 320); diff --git a/src/hotspot/os_cpu/linux_ppc/globals_linux_ppc.hpp b/src/hotspot/os_cpu/linux_ppc/globals_linux_ppc.hpp index 182c55b9f96..96dcf0a8c0e 100644 --- a/src/hotspot/os_cpu/linux_ppc/globals_linux_ppc.hpp +++ b/src/hotspot/os_cpu/linux_ppc/globals_linux_ppc.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2024, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2012, 2015 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -29,7 +29,6 @@ // Sets the default values for platform dependent flags used by the runtime system. // (see globals.hpp) -define_pd_global(bool, DontYieldALot, false); define_pd_global(intx, ThreadStackSize, 2048); // 0 => use system default define_pd_global(intx, VMThreadStackSize, 2048); diff --git a/src/hotspot/os_cpu/linux_riscv/globals_linux_riscv.hpp b/src/hotspot/os_cpu/linux_riscv/globals_linux_riscv.hpp index 297414bfcd5..16e4b205547 100644 --- a/src/hotspot/os_cpu/linux_riscv/globals_linux_riscv.hpp +++ b/src/hotspot/os_cpu/linux_riscv/globals_linux_riscv.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2024, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2020, 2022, Huawei Technologies Co., Ltd. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -29,7 +29,6 @@ // Sets the default values for platform dependent flags used by the runtime system. // (see globals.hpp) -define_pd_global(bool, DontYieldALot, false); define_pd_global(intx, ThreadStackSize, 2048); // 0 => use system default define_pd_global(intx, VMThreadStackSize, 2048); diff --git a/src/hotspot/os_cpu/linux_s390/globals_linux_s390.hpp b/src/hotspot/os_cpu/linux_s390/globals_linux_s390.hpp index 295dd665d2d..49607e24d15 100644 --- a/src/hotspot/os_cpu/linux_s390/globals_linux_s390.hpp +++ b/src/hotspot/os_cpu/linux_s390/globals_linux_s390.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2024, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2016 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -31,7 +31,6 @@ // Sets the default values for platform dependent flags used by the // runtime system (see globals.hpp). -define_pd_global(bool, DontYieldALot, false); define_pd_global(intx, ThreadStackSize, 1024); // 0 => Use system default. define_pd_global(intx, VMThreadStackSize, 1024); // Some jck tests in lang/fp/fpl038 run out of compile thread stack. diff --git a/src/hotspot/os_cpu/linux_x86/globals_linux_x86.hpp b/src/hotspot/os_cpu/linux_x86/globals_linux_x86.hpp index 8f1f64c2d9e..97a5732d00a 100644 --- a/src/hotspot/os_cpu/linux_x86/globals_linux_x86.hpp +++ b/src/hotspot/os_cpu/linux_x86/globals_linux_x86.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -28,7 +28,6 @@ // Sets the default values for platform dependent flags used by the runtime system. // (see globals.hpp) -define_pd_global(bool, DontYieldALot, false); #ifdef AMD64 define_pd_global(intx, CompilerThreadStackSize, 1024); define_pd_global(intx, ThreadStackSize, 1024); // 0 => use system default diff --git a/src/hotspot/os_cpu/linux_zero/globals_linux_zero.hpp b/src/hotspot/os_cpu/linux_zero/globals_linux_zero.hpp index 957c5c4a12a..ed09bf8372e 100644 --- a/src/hotspot/os_cpu/linux_zero/globals_linux_zero.hpp +++ b/src/hotspot/os_cpu/linux_zero/globals_linux_zero.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2024, Oracle and/or its affiliates. All rights reserved. * Copyright 2007, 2008, 2010 Red Hat, Inc. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -31,7 +31,6 @@ // runtime system. See globals.hpp for details of what they do. // -define_pd_global(bool, DontYieldALot, false); define_pd_global(intx, ThreadStackSize, 1536); #ifdef _LP64 define_pd_global(intx, VMThreadStackSize, 1024); diff --git a/src/hotspot/os_cpu/windows_aarch64/globals_windows_aarch64.hpp b/src/hotspot/os_cpu/windows_aarch64/globals_windows_aarch64.hpp index 836fb463206..a438e438cdb 100644 --- a/src/hotspot/os_cpu/windows_aarch64/globals_windows_aarch64.hpp +++ b/src/hotspot/os_cpu/windows_aarch64/globals_windows_aarch64.hpp @@ -28,8 +28,6 @@ // Sets the default values for platform dependent flags used by the runtime system. // (see globals.hpp) -define_pd_global(bool, DontYieldALot, false); - // Default stack size on Windows is determined by the executable (java.exe // has a default value of 320K/1MB [32bit/64bit]). Depending on Windows version, changing // ThreadStackSize to non-zero may have significant impact on memory usage. diff --git a/src/hotspot/os_cpu/windows_x86/globals_windows_x86.hpp b/src/hotspot/os_cpu/windows_x86/globals_windows_x86.hpp index c94796b097a..811fa2e07e9 100644 --- a/src/hotspot/os_cpu/windows_x86/globals_windows_x86.hpp +++ b/src/hotspot/os_cpu/windows_x86/globals_windows_x86.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -28,8 +28,6 @@ // Sets the default values for platform dependent flags used by the runtime system. // (see globals.hpp) -define_pd_global(bool, DontYieldALot, false); - // Default stack size on Windows is determined by the executable (java.exe // has a default value of 320K/1MB [32bit/64bit]). Depending on Windows version, changing // ThreadStackSize to non-zero may have significant impact on memory usage. diff --git a/src/hotspot/share/prims/jvm.cpp b/src/hotspot/share/prims/jvm.cpp index e91cee86c50..12ed10630fc 100644 --- a/src/hotspot/share/prims/jvm.cpp +++ b/src/hotspot/share/prims/jvm.cpp @@ -2951,7 +2951,6 @@ JVM_END JVM_LEAF(void, JVM_Yield(JNIEnv *env, jclass threadClass)) - if (os::dont_yield()) return; HOTSPOT_THREAD_YIELD(); os::naked_yield(); JVM_END diff --git a/src/hotspot/share/runtime/globals.hpp b/src/hotspot/share/runtime/globals.hpp index 70b537bf2d7..11c13fe3c9e 100644 --- a/src/hotspot/share/runtime/globals.hpp +++ b/src/hotspot/share/runtime/globals.hpp @@ -697,9 +697,6 @@ const int ObjectAlignmentInBytes = 8; "Allow parallel defineClass requests for class loaders " \ "registering as parallel capable") \ \ - product_pd(bool, DontYieldALot, \ - "(Deprecated) Throw away obvious excess yield calls") \ - \ product(bool, DisablePrimordialThreadGuardPages, false, EXPERIMENTAL, \ "Disable the use of stack guard pages if the JVM is loaded " \ "on the primordial process thread") \ diff --git a/src/hotspot/share/runtime/os.hpp b/src/hotspot/share/runtime/os.hpp index 2f665df5bba..54771f622e9 100644 --- a/src/hotspot/share/runtime/os.hpp +++ b/src/hotspot/share/runtime/os.hpp @@ -1042,8 +1042,6 @@ class os: AllStatic { // debugging support (mostly used by debug.cpp but also fatal error handler) static bool find(address pc, outputStream* st = tty); // OS specific function to make sense out of an address - static bool dont_yield(); // when true, JVM_Yield() is nop - // Thread priority helpers (implemented in OS-specific part) static OSReturn set_native_priority(Thread* thread, int native_prio); static OSReturn get_native_priority(const Thread* const thread, int* priority_ptr); From 99070658fd09ee3d1835f814c939d62e249c5704 Mon Sep 17 00:00:00 2001 From: Phil Race Date: Fri, 15 Nov 2024 04:51:55 +0000 Subject: [PATCH 003/311] 8344065: Remove SecurityManager uses from the java.datatransfer module Reviewed-by: serb --- src/java.base/share/classes/module-info.java | 1 - .../java/awt/datatransfer/DataFlavor.java | 37 +++++++------------ .../awt/datatransfer/SystemFlavorMap.java | 8 +--- 3 files changed, 14 insertions(+), 32 deletions(-) diff --git a/src/java.base/share/classes/module-info.java b/src/java.base/share/classes/module-info.java index 85ccb2192fb..d683d837a09 100644 --- a/src/java.base/share/classes/module-info.java +++ b/src/java.base/share/classes/module-info.java @@ -313,7 +313,6 @@ java.desktop; exports sun.reflect.misc to java.desktop, - java.datatransfer, java.management, java.management.rmi, java.rmi, diff --git a/src/java.datatransfer/share/classes/java/awt/datatransfer/DataFlavor.java b/src/java.datatransfer/share/classes/java/awt/datatransfer/DataFlavor.java index 757c4f99f45..f228f1a4da1 100644 --- a/src/java.datatransfer/share/classes/java/awt/datatransfer/DataFlavor.java +++ b/src/java.datatransfer/share/classes/java/awt/datatransfer/DataFlavor.java @@ -45,7 +45,6 @@ import java.util.Objects; import sun.datatransfer.DataFlavorUtil; -import sun.reflect.misc.ReflectUtil; /** * A {@code DataFlavor} provides meta information about data. {@code DataFlavor} @@ -131,32 +130,22 @@ protected static final Class tryToLoadClass(String className, ClassLoader fallback) throws ClassNotFoundException { - ReflectUtil.checkPackageAccess(className); + ClassLoader loader = ClassLoader.getSystemClassLoader(); try { - @SuppressWarnings("removal") - SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - sm.checkPermission(new RuntimePermission("getClassLoader")); - } - ClassLoader loader = ClassLoader.getSystemClassLoader(); - try { - // bootstrap class loader and system class loader if present - return Class.forName(className, true, loader); - } - catch (ClassNotFoundException exception) { - // thread context class loader if and only if present - loader = Thread.currentThread().getContextClassLoader(); - if (loader != null) { - try { - return Class.forName(className, true, loader); - } - catch (ClassNotFoundException e) { - // fallback to user's class loader - } + // bootstrap class loader and system class loader if present + return Class.forName(className, true, loader); + } + catch (ClassNotFoundException exception) { + // thread context class loader if and only if present + loader = Thread.currentThread().getContextClassLoader(); + if (loader != null) { + try { + return Class.forName(className, true, loader); + } + catch (ClassNotFoundException e) { + // fallback to user's class loader } } - } catch (SecurityException exception) { - // ignore secured class loaders } return Class.forName(className, true, fallback); } diff --git a/src/java.datatransfer/share/classes/java/awt/datatransfer/SystemFlavorMap.java b/src/java.datatransfer/share/classes/java/awt/datatransfer/SystemFlavorMap.java index 6b2dc14c05f..deea133b734 100644 --- a/src/java.datatransfer/share/classes/java/awt/datatransfer/SystemFlavorMap.java +++ b/src/java.datatransfer/share/classes/java/awt/datatransfer/SystemFlavorMap.java @@ -30,8 +30,6 @@ import java.io.InputStream; import java.io.InputStreamReader; import java.lang.ref.SoftReference; -import java.security.AccessController; -import java.security.PrivilegedAction; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; @@ -202,12 +200,8 @@ private void initSystemFlavorMap() { } isMapInitialized = true; - @SuppressWarnings("removal") - InputStream is = AccessController.doPrivileged( - (PrivilegedAction) () -> { - return SystemFlavorMap.class.getResourceAsStream( + InputStream is = SystemFlavorMap.class.getResourceAsStream( "/sun/datatransfer/resources/flavormap.properties"); - }); if (is == null) { throw new InternalError("Default flavor mapping not found"); } From 0ae5748f74fda79cff8c62eafbef144cde7abf14 Mon Sep 17 00:00:00 2001 From: Alan Bateman Date: Fri, 15 Nov 2024 07:16:34 +0000 Subject: [PATCH 004/311] 8343982: Remove usage of security manager from ClassLoader and related classes Reviewed-by: jpai, yzheng, lancea --- .../share/classes/java/lang/ClassLoader.java | 82 +------- .../jdk/internal/loader/BootLoader.java | 54 ++--- .../internal/loader/BuiltinClassLoader.java | 187 ++++-------------- .../jdk/internal/loader/ClassLoaders.java | 30 +-- .../classes/jdk/internal/loader/Loader.java | 117 +---------- .../jdk/internal/loader/NativeLibraries.java | 22 +-- .../internal/loader/RawNativeLibraries.java | 19 +- 7 files changed, 78 insertions(+), 433 deletions(-) diff --git a/src/java.base/share/classes/java/lang/ClassLoader.java b/src/java.base/share/classes/java/lang/ClassLoader.java index 85fc315c767..55341635d8a 100644 --- a/src/java.base/share/classes/java/lang/ClassLoader.java +++ b/src/java.base/share/classes/java/lang/ClassLoader.java @@ -64,7 +64,6 @@ import jdk.internal.reflect.CallerSensitiveAdapter; import jdk.internal.reflect.Reflection; import jdk.internal.util.StaticProperty; -import sun.security.util.SecurityConstants; /** * A class loader is an object that is responsible for loading classes. The @@ -357,12 +356,6 @@ private static Void checkCreateClassLoader(String name) { if (name != null && name.isEmpty()) { throw new IllegalArgumentException("name must be non-empty or null"); } - - @SuppressWarnings("removal") - SecurityManager security = System.getSecurityManager(); - if (security != null) { - security.checkCreateClassLoader(); - } return null; } @@ -1735,18 +1728,7 @@ public static InputStream getSystemResourceAsStream(String name) { * * @since 1.2 */ - @CallerSensitive public final ClassLoader getParent() { - if (parent == null) - return null; - @SuppressWarnings("removal") - SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - // Check access to the parent class loader - // If the caller's class loader is same as this class loader, - // permission check is performed. - checkClassLoaderPermission(parent, Reflection.getCallerClass()); - } return parent; } @@ -1774,15 +1756,8 @@ public final Module getUnnamedModule() { * * @since 9 */ - @CallerSensitive public static ClassLoader getPlatformClassLoader() { - @SuppressWarnings("removal") - SecurityManager sm = System.getSecurityManager(); - ClassLoader loader = getBuiltinPlatformClassLoader(); - if (sm != null) { - checkClassLoaderPermission(loader, Reflection.getCallerClass()); - } - return loader; + return getBuiltinPlatformClassLoader(); } /** @@ -1853,7 +1828,6 @@ public static ClassLoader getPlatformClassLoader() { * underlying cause of the error can be retrieved via the * {@link Throwable#getCause()} method. */ - @CallerSensitive public static ClassLoader getSystemClassLoader() { switch (VM.initLevel()) { case 0: @@ -1867,11 +1841,6 @@ public static ClassLoader getSystemClassLoader() { default: // system fully initialized assert VM.isBooted() && scl != null; - @SuppressWarnings("removal") - SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - checkClassLoaderPermission(scl, Reflection.getCallerClass()); - } return scl; } } @@ -1902,8 +1871,6 @@ static synchronized ClassLoader initSystemClassLoader() { } ClassLoader builtinLoader = getBuiltinAppClassLoader(); - - // All are privileged frames. No need to call doPrivileged. String cn = System.getProperty("java.system.class.loader"); if (cn != null) { try { @@ -1930,36 +1897,6 @@ static synchronized ClassLoader initSystemClassLoader() { return scl; } - // Returns true if the specified class loader can be found in this class - // loader's delegation chain. - boolean isAncestor(ClassLoader cl) { - ClassLoader acl = this; - do { - acl = acl.parent; - if (cl == acl) { - return true; - } - } while (acl != null); - return false; - } - - // Tests if class loader access requires "getClassLoader" permission - // check. A class loader 'from' can access class loader 'to' if - // class loader 'from' is same as class loader 'to' or an ancestor - // of 'to'. The class loader in a system domain can access - // any class loader. - private static boolean needsClassLoaderPermissionCheck(ClassLoader from, - ClassLoader to) - { - if (from == to) - return false; - - if (from == null) - return false; - - return !to.isAncestor(from); - } - // Returns the class's class loader, or null if none. static ClassLoader getClassLoader(Class caller) { // This can be null if the VM is requesting it @@ -1970,23 +1907,6 @@ static ClassLoader getClassLoader(Class caller) { return caller.getClassLoader0(); } - /* - * Checks RuntimePermission("getClassLoader") permission - * if caller's class loader is not null and caller's class loader - * is not the same as or an ancestor of the given cl argument. - */ - static void checkClassLoaderPermission(ClassLoader cl, Class caller) { - @SuppressWarnings("removal") - SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - // caller can be null if the VM is requesting it - ClassLoader ccl = getClassLoader(caller); - if (needsClassLoaderPermissionCheck(ccl, cl)) { - sm.checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION); - } - } - } - // The system class loader // @GuardedBy("ClassLoader.class") private static volatile ClassLoader scl; diff --git a/src/java.base/share/classes/jdk/internal/loader/BootLoader.java b/src/java.base/share/classes/jdk/internal/loader/BootLoader.java index 98ff60a7309..c845146a838 100644 --- a/src/java.base/share/classes/jdk/internal/loader/BootLoader.java +++ b/src/java.base/share/classes/jdk/internal/loader/BootLoader.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -32,8 +32,6 @@ import java.net.URL; import java.nio.file.Files; import java.nio.file.Path; -import java.security.AccessController; -import java.security.PrivilegedAction; import java.util.Arrays; import java.util.Enumeration; import java.util.concurrent.ConcurrentHashMap; @@ -143,18 +141,8 @@ public static Class loadClass(Module module, String name) { /** * Loads a native library from the system library path. */ - @SuppressWarnings("removal") public static void loadLibrary(String name) { - if (System.getSecurityManager() == null) { - BootLoader.getNativeLibraries().loadLibrary(name); - } else { - AccessController.doPrivileged(new java.security.PrivilegedAction<>() { - public Void run() { - BootLoader.getNativeLibraries().loadLibrary(name); - return null; - } - }); - } + getNativeLibraries().loadLibrary(name); } /** @@ -294,38 +282,28 @@ private static Module findModule(String location) { /** * Returns URL if the given location is a regular file path. */ - @SuppressWarnings("removal") private static URL toFileURL(String location) { - return AccessController.doPrivileged(new PrivilegedAction<>() { - public URL run() { - Path path = Path.of(location); - if (Files.isRegularFile(path)) { - try { - return path.toUri().toURL(); - } catch (MalformedURLException e) {} - } - return null; - } - }); + Path path = Path.of(location); + if (Files.isRegularFile(path)) { + try { + return path.toUri().toURL(); + } catch (MalformedURLException e) {} + } + return null; } /** * Returns the Manifest if the given location is a JAR file * containing a manifest. */ - @SuppressWarnings("removal") private static Manifest getManifest(String location) { - return AccessController.doPrivileged(new PrivilegedAction<>() { - public Manifest run() { - Path jar = Path.of(location); - try (InputStream in = Files.newInputStream(jar); - JarInputStream jis = new JarInputStream(in, false)) { - return jis.getManifest(); - } catch (IOException e) { - return null; - } - } - }); + Path jar = Path.of(location); + try (InputStream in = Files.newInputStream(jar); + JarInputStream jis = new JarInputStream(in, false)) { + return jis.getManifest(); + } catch (IOException e) { + return null; + } } } diff --git a/src/java.base/share/classes/jdk/internal/loader/BuiltinClassLoader.java b/src/java.base/share/classes/jdk/internal/loader/BuiltinClassLoader.java index 84e5c50672d..ddf35a88d0a 100644 --- a/src/java.base/share/classes/jdk/internal/loader/BuiltinClassLoader.java +++ b/src/java.base/share/classes/jdk/internal/loader/BuiltinClassLoader.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -35,13 +35,8 @@ import java.net.URI; import java.net.URL; import java.nio.ByteBuffer; -import java.security.AccessController; import java.security.CodeSigner; import java.security.CodeSource; -import java.security.PermissionCollection; -import java.security.PrivilegedAction; -import java.security.PrivilegedActionException; -import java.security.PrivilegedExceptionAction; import java.security.SecureClassLoader; import java.util.ArrayList; import java.util.Collections; @@ -62,7 +57,6 @@ import jdk.internal.module.ModulePatcher.PatchedModuleReader; import jdk.internal.module.Resources; import jdk.internal.vm.annotation.Stable; -import sun.security.util.LazyCodeSourcePermissionCollection; /** @@ -281,31 +275,30 @@ public URL findResource(String mn, String name) throws IOException { url = findResourceOnClassPath(name); } - return checkURL(url); // check access before returning + return url; } /** * Returns an input stream to a resource of the given name in a module * defined to this class loader. */ - @SuppressWarnings("removal") public InputStream findResourceAsStream(String mn, String name) throws IOException { - // Need URL to resource when running with a security manager so that - // the right permission check is done. - if (System.getSecurityManager() != null || mn == null) { - URL url = findResource(mn, name); - return (url != null) ? url.openStream() : null; - } - - // find in module defined to this loader, no security manager - ModuleReference mref = nameToModule.get(mn); - if (mref != null) { - return moduleReaderFor(mref).open(name).orElse(null); + InputStream in = null; + if (mn != null) { + // find in module defined to this loader + ModuleReference mref = nameToModule.get(mn); + if (mref != null) { + in = moduleReaderFor(mref).open(name).orElse(null); + } } else { - return null; + URL url = findResourceOnClassPath(name); + if (url != null) { + in = url.openStream(); + } } + return in; } /** @@ -342,7 +335,7 @@ public URL findResource(String name) { if (!urls.isEmpty()) { URL url = urls.get(0); if (url != null) { - return checkURL(url); // check access before returning + return url; } } } catch (IOException ioe) { @@ -352,8 +345,7 @@ public URL findResource(String name) { } // search class path - URL url = findResourceOnClassPath(name); - return checkURL(url); + return findResourceOnClassPath(name); } /** @@ -383,7 +375,6 @@ public Enumeration findResources(String name) throws IOException { } else { // not in a package of a module defined to this loader for (URL url : findMiscResource(name)) { - url = checkURL(url); if (url != null) { checked.add(url); } @@ -406,7 +397,7 @@ private boolean hasNext() { } else { // need to check each URL while (e.hasMoreElements() && next == null) { - next = checkURL(e.nextElement()); + next = e.nextElement(); } return next != null; } @@ -436,7 +427,6 @@ public URL nextElement() { * * The cache used by this method avoids repeated searching of all modules. */ - @SuppressWarnings("removal") private List findMiscResource(String name) throws IOException { SoftReference>> ref = this.resourceCache; Map> map = (ref != null) ? ref.get() : null; @@ -453,30 +443,20 @@ private List findMiscResource(String name) throws IOException { } // search all modules for the resource - List urls; - try { - urls = AccessController.doPrivileged( - new PrivilegedExceptionAction<>() { - @Override - public List run() throws IOException { - List result = null; - for (ModuleReference mref : nameToModule.values()) { - URI u = moduleReaderFor(mref).find(name).orElse(null); - if (u != null) { - try { - if (result == null) - result = new ArrayList<>(); - result.add(u.toURL()); - } catch (MalformedURLException | - IllegalArgumentException e) { - } - } - } - return (result != null) ? result : Collections.emptyList(); - } - }); - } catch (PrivilegedActionException pae) { - throw (IOException) pae.getCause(); + List urls = null; + for (ModuleReference mref : nameToModule.values()) { + URI u = moduleReaderFor(mref).find(name).orElse(null); + if (u != null) { + try { + if (urls == null) + urls = new ArrayList<>(); + urls.add(u.toURL()); + } catch (MalformedURLException | IllegalArgumentException e) { + } + } + } + if (urls == null) { + urls = List.of(); } // only cache resources after VM is fully initialized @@ -490,23 +470,8 @@ public List run() throws IOException { /** * Returns the URL to a resource in a module or {@code null} if not found. */ - @SuppressWarnings("removal") private URL findResource(ModuleReference mref, String name) throws IOException { - URI u; - if (System.getSecurityManager() == null) { - u = moduleReaderFor(mref).find(name).orElse(null); - } else { - try { - u = AccessController.doPrivileged(new PrivilegedExceptionAction<> () { - @Override - public URI run() throws IOException { - return moduleReaderFor(mref).find(name).orElse(null); - } - }); - } catch (PrivilegedActionException pae) { - throw (IOException) pae.getCause(); - } - } + URI u = moduleReaderFor(mref).find(name).orElse(null); if (u != null) { try { return u.toURL(); @@ -515,30 +480,12 @@ public URI run() throws IOException { return null; } - /** - * Returns the URL to a resource in a module. Returns {@code null} if not found - * or an I/O error occurs. - */ - private URL findResourceOrNull(ModuleReference mref, String name) { - try { - return findResource(mref, name); - } catch (IOException ignore) { - return null; - } - } - /** * Returns a URL to a resource on the class path. */ - @SuppressWarnings("removal") private URL findResourceOnClassPath(String name) { if (hasClassPath()) { - if (System.getSecurityManager() == null) { - return ucp.findResource(name, false); - } else { - PrivilegedAction pa = () -> ucp.findResource(name, false); - return AccessController.doPrivileged(pa); - } + return ucp.findResource(name, false); } else { // no class path return null; @@ -548,16 +495,9 @@ private URL findResourceOnClassPath(String name) { /** * Returns the URLs of all resources of the given name on the class path. */ - @SuppressWarnings("removal") private Enumeration findResourcesOnClassPath(String name) { if (hasClassPath()) { - if (System.getSecurityManager() == null) { - return ucp.findResources(name, false); - } else { - PrivilegedAction> pa; - pa = () -> ucp.findResources(name, false); - return AccessController.doPrivileged(pa); - } + return ucp.findResources(name, false); } else { // no class path return Collections.emptyEnumeration(); @@ -735,14 +675,8 @@ private LoadedModule findLoadedModule(String mn, String cn) { * * @return the resulting Class or {@code null} if not found */ - @SuppressWarnings("removal") private Class findClassInModuleOrNull(LoadedModule loadedModule, String cn) { - if (System.getSecurityManager() == null) { - return defineClass(cn, loadedModule); - } else { - PrivilegedAction> pa = () -> defineClass(cn, loadedModule); - return AccessController.doPrivileged(pa); - } + return defineClass(cn, loadedModule); } /** @@ -750,36 +684,17 @@ private Class findClassInModuleOrNull(LoadedModule loadedModule, String cn) { * * @return the resulting Class or {@code null} if not found */ - @SuppressWarnings("removal") private Class findClassOnClassPathOrNull(String cn) { String path = cn.replace('.', '/').concat(".class"); - if (System.getSecurityManager() == null) { - Resource res = ucp.getResource(path, false); - if (res != null) { - try { - return defineClass(cn, res); - } catch (IOException ioe) { - // TBD on how I/O errors should be propagated - } + Resource res = ucp.getResource(path, false); + if (res != null) { + try { + return defineClass(cn, res); + } catch (IOException ioe) { + // TBD on how I/O errors should be propagated } - return null; - } else { - // avoid use of lambda here - PrivilegedAction> pa = new PrivilegedAction<>() { - public Class run() { - Resource res = ucp.getResource(path, false); - if (res != null) { - try { - return defineClass(cn, res); - } catch (IOException ioe) { - // TBD on how I/O errors should be propagated - } - } - return null; - } - }; - return AccessController.doPrivileged(pa); } + return null; } /** @@ -998,16 +913,6 @@ private boolean isSealed(String pn, Manifest man) { return "true".equalsIgnoreCase(sealed); } - // -- permissions - - /** - * Returns the permissions for the given CodeSource. - */ - @Override - protected PermissionCollection getPermissions(CodeSource cs) { - return new LazyCodeSourcePermissionCollection(super.getPermissions(cs), cs); - } - // -- miscellaneous supporting methods /** @@ -1072,14 +977,6 @@ private boolean isOpen(ModuleReference mref, String pn) { return false; } - /** - * Checks access to the given URL. We use URLClassPath for consistent - * checking with java.net.URLClassLoader. - */ - private static URL checkURL(URL url) { - return URLClassPath.checkURL(url); - } - // Called from VM only, during -Xshare:dump private void resetArchivedStates() { ucp = null; diff --git a/src/java.base/share/classes/jdk/internal/loader/ClassLoaders.java b/src/java.base/share/classes/jdk/internal/loader/ClassLoaders.java index ab4aa3fb907..1a61d4b1522 100644 --- a/src/java.base/share/classes/jdk/internal/loader/ClassLoaders.java +++ b/src/java.base/share/classes/jdk/internal/loader/ClassLoaders.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -29,8 +29,6 @@ import java.net.URL; import java.nio.file.InvalidPathException; import java.nio.file.Path; -import java.security.CodeSource; -import java.security.PermissionCollection; import java.util.jar.Manifest; import jdk.internal.access.JavaLangAccess; @@ -170,31 +168,6 @@ private static class AppClassLoader extends BuiltinClassLoader { super("app", parent, ucp); } - @Override - protected Class loadClass(String cn, boolean resolve) - throws ClassNotFoundException - { - // for compatibility reasons, say where restricted package list has - // been updated to list API packages in the unnamed module. - @SuppressWarnings("removal") - SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - int i = cn.lastIndexOf('.'); - if (i != -1) { - sm.checkPackageAccess(cn.substring(0, i)); - } - } - - return super.loadClass(cn, resolve); - } - - @Override - protected PermissionCollection getPermissions(CodeSource cs) { - PermissionCollection perms = super.getPermissions(cs); - perms.add(new RuntimePermission("exitVM")); - return perms; - } - /** * Called by the VM to support dynamic additions to the class path * @@ -207,6 +180,7 @@ void appendToClassPathForInstrumentation(String path) { /** * Called by the VM to support define package for AppCDS */ + @Override protected Package defineOrCheckPackage(String pn, Manifest man, URL url) { return super.defineOrCheckPackage(pn, man, url); } diff --git a/src/java.base/share/classes/jdk/internal/loader/Loader.java b/src/java.base/share/classes/jdk/internal/loader/Loader.java index fbd16467da7..c4f9023482d 100644 --- a/src/java.base/share/classes/jdk/internal/loader/Loader.java +++ b/src/java.base/share/classes/jdk/internal/loader/Loader.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,8 +25,6 @@ package jdk.internal.loader; -import java.io.File; -import java.io.FilePermission; import java.io.IOException; import java.lang.module.Configuration; import java.lang.module.ModuleDescriptor; @@ -37,15 +35,8 @@ import java.net.URI; import java.net.URL; import java.nio.ByteBuffer; -import java.security.AccessControlContext; -import java.security.AccessController; import java.security.CodeSigner; import java.security.CodeSource; -import java.security.Permission; -import java.security.PermissionCollection; -import java.security.PrivilegedAction; -import java.security.PrivilegedActionException; -import java.security.PrivilegedExceptionAction; import java.security.SecureClassLoader; import java.util.ArrayList; import java.util.Collection; @@ -110,16 +101,11 @@ public final class Loader extends SecureClassLoader { private final Map moduleToReader = new ConcurrentHashMap<>(); - // ACC used when loading classes and resources - @SuppressWarnings("removal") - private final AccessControlContext acc; - /** * A module defined/loaded to a {@code Loader}. */ private static class LoadedModule { private final ModuleReference mref; - private final URL url; // may be null private final CodeSource cs; LoadedModule(ModuleReference mref) { @@ -130,13 +116,11 @@ private static class LoadedModule { } catch (MalformedURLException | IllegalArgumentException e) { } } this.mref = mref; - this.url = url; this.cs = new CodeSource(url, (CodeSigner[]) null); } ModuleReference mref() { return mref; } String name() { return mref.descriptor().name(); } - URL location() { return url; } CodeSource codeSource() { return cs; } } @@ -145,7 +129,6 @@ private static class LoadedModule { * Creates a {@code Loader} in a loader pool that loads classes/resources * from one module. */ - @SuppressWarnings("removal") public Loader(ResolvedModule resolvedModule, LoaderPool pool, ClassLoader parent) @@ -164,8 +147,6 @@ public Loader(ResolvedModule resolvedModule, LoadedModule lm = new LoadedModule(mref); descriptor.packages().forEach(pn -> localPackageToModule.put(pn, lm)); this.localPackageToModule = localPackageToModule; - - this.acc = AccessController.getContext(); } /** @@ -175,7 +156,6 @@ public Loader(ResolvedModule resolvedModule, * @throws IllegalArgumentException * If two or more modules have the same package */ - @SuppressWarnings("removal") public Loader(Collection modules, ClassLoader parent) { super(parent); @@ -197,8 +177,6 @@ public Loader(Collection modules, ClassLoader parent) { } this.nameToModule = nameToModule; this.localPackageToModule = localPackageToModule; - - this.acc = AccessController.getContext(); } /** @@ -326,7 +304,6 @@ public LoaderPool pool() { * Returns a URL to a resource of the given name in a module defined to * this class loader. */ - @SuppressWarnings("removal") @Override protected URL findResource(String mn, String name) throws IOException { ModuleReference mref = (mn != null) ? nameToModule.get(mn) : null; @@ -335,41 +312,12 @@ protected URL findResource(String mn, String name) throws IOException { // locate resource URL url = null; - try { - url = AccessController.doPrivileged( - new PrivilegedExceptionAction() { - @Override - public URL run() throws IOException { - Optional ouri = moduleReaderFor(mref).find(name); - if (ouri.isPresent()) { - try { - return ouri.get().toURL(); - } catch (MalformedURLException | - IllegalArgumentException e) { } - } - return null; - } - }); - } catch (PrivilegedActionException pae) { - throw (IOException) pae.getCause(); - } - - // check access with permissions restricted by ACC - if (url != null && System.getSecurityManager() != null) { + Optional ouri = moduleReaderFor(mref).find(name); + if (ouri.isPresent()) { try { - URL urlToCheck = url; - url = AccessController.doPrivileged( - new PrivilegedExceptionAction() { - @Override - public URL run() throws IOException { - return URLClassPath.checkURL(urlToCheck); - } - }, acc); - } catch (PrivilegedActionException pae) { - url = null; - } + url = ouri.get().toURL(); + } catch (MalformedURLException | IllegalArgumentException e) { } } - return url; } @@ -525,15 +473,6 @@ protected Class findClass(String mn, String cn) { protected Class loadClass(String cn, boolean resolve) throws ClassNotFoundException { - @SuppressWarnings("removal") - SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - String pn = packageName(cn); - if (!pn.isEmpty()) { - sm.checkPackageAccess(pn); - } - } - synchronized (getClassLoadingLock(cn)) { // check if already loaded Class c = findLoadedClass(cn); @@ -584,19 +523,7 @@ protected Class loadClass(String cn, boolean resolve) * * @return the resulting Class or {@code null} if not found */ - @SuppressWarnings("removal") private Class findClassInModuleOrNull(LoadedModule loadedModule, String cn) { - PrivilegedAction> pa = () -> defineClass(cn, loadedModule); - return AccessController.doPrivileged(pa, acc); - } - - /** - * Defines the given binary class name to the VM, loading the class - * bytes from the given module. - * - * @return the resulting Class or {@code null} if an I/O error occurs - */ - private Class defineClass(String cn, LoadedModule loadedModule) { ModuleReader reader = moduleReaderFor(loadedModule.mref()); try { @@ -620,40 +547,6 @@ private Class defineClass(String cn, LoadedModule loadedModule) { } } - - // -- permissions - - /** - * Returns the permissions for the given CodeSource. - */ - @Override - protected PermissionCollection getPermissions(CodeSource cs) { - PermissionCollection perms = super.getPermissions(cs); - - URL url = cs.getLocation(); - if (url == null) - return perms; - - // add the permission to access the resource - try { - Permission p = url.openConnection().getPermission(); - if (p != null) { - // for directories then need recursive access - if (p instanceof FilePermission) { - String path = p.getName(); - if (path.endsWith(File.separator)) { - path += "-"; - p = new FilePermission(path, "read"); - } - } - perms.add(p); - } - } catch (IOException ioe) { } - - return perms; - } - - // -- miscellaneous supporting methods /** diff --git a/src/java.base/share/classes/jdk/internal/loader/NativeLibraries.java b/src/java.base/share/classes/jdk/internal/loader/NativeLibraries.java index 64a3813a914..02dc79f0288 100644 --- a/src/java.base/share/classes/jdk/internal/loader/NativeLibraries.java +++ b/src/java.base/share/classes/jdk/internal/loader/NativeLibraries.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -114,25 +114,17 @@ public long find(String name) { * @param file the path of the native library * @throws UnsatisfiedLinkError if any error in loading the native library */ - @SuppressWarnings("removal") public NativeLibrary loadLibrary(Class fromClass, File file) { // Check to see if we're attempting to access a static library String name = findBuiltinLib(file.getName()); boolean isBuiltin = (name != null); if (!isBuiltin) { - name = AccessController.doPrivileged(new PrivilegedAction<>() { - public String run() { - try { - if (loadLibraryOnlyIfPresent && !file.exists()) { - return null; - } - return file.getCanonicalPath(); - } catch (IOException e) { - return null; - } - } - }); - if (name == null) { + try { + if (loadLibraryOnlyIfPresent && !file.exists()) { + return null; + } + name = file.getCanonicalPath(); + } catch (IOException e) { return null; } } diff --git a/src/java.base/share/classes/jdk/internal/loader/RawNativeLibraries.java b/src/java.base/share/classes/jdk/internal/loader/RawNativeLibraries.java index 35ed4701c99..fa4c1390c1a 100644 --- a/src/java.base/share/classes/jdk/internal/loader/RawNativeLibraries.java +++ b/src/java.base/share/classes/jdk/internal/loader/RawNativeLibraries.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -29,8 +29,6 @@ import java.io.IOException; import java.lang.invoke.MethodHandles; import java.nio.file.Path; -import java.security.AccessController; -import java.security.PrivilegedAction; import java.util.Objects; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; @@ -78,18 +76,11 @@ public static RawNativeLibraries newInstance(MethodHandles.Lookup trustedCaller) * * @param path the path of the native library */ - @SuppressWarnings("removal") public NativeLibrary load(Path path) { - String name = AccessController.doPrivileged(new PrivilegedAction<>() { - public String run() { - try { - return path.toRealPath().toString(); - } catch (IOException e) { - return null; - } - } - }); - if (name == null) { + String name; + try { + name = path.toRealPath().toString(); + } catch (IOException e) { return null; } return load(name); From 21966942b6b5341d0d221d10c3eaa629e543d017 Mon Sep 17 00:00:00 2001 From: Emanuel Peter Date: Fri, 15 Nov 2024 07:31:55 +0000 Subject: [PATCH 005/311] 8344104: TestMergeStores fails with ArrayIndexOutOfBoundException Reviewed-by: shade, chagedorn, dlong --- test/hotspot/jtreg/compiler/c2/TestMergeStores.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/hotspot/jtreg/compiler/c2/TestMergeStores.java b/test/hotspot/jtreg/compiler/c2/TestMergeStores.java index c8e8bd337ad..3598b8eae71 100644 --- a/test/hotspot/jtreg/compiler/c2/TestMergeStores.java +++ b/test/hotspot/jtreg/compiler/c2/TestMergeStores.java @@ -340,8 +340,8 @@ public void runTests(RunInfo info) { set_random(aL); set_random(bL); - offset1 = Math.abs(RANDOM.nextInt()) % 100; - offset2 = Math.abs(RANDOM.nextInt()) % 100; + offset1 = RANDOM.nextInt(100); + offset2 = RANDOM.nextInt(100); vB1 = (byte)RANDOM.nextInt(); vB2 = (byte)RANDOM.nextInt(); vS1 = (short)RANDOM.nextInt(); From 857f68c60f9c82c38f3b3a83692477dfe50a6ea4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eirik=20Bj=C3=B8rsn=C3=B8s?= Date: Fri, 15 Nov 2024 07:47:11 +0000 Subject: [PATCH 006/311] 8344179: SecurityManager cleanup in the ZIP and JAR areas Reviewed-by: lancea, rriggs, mullan, jpai --- .../share/classes/java/util/jar/JarFile.java | 7 +++---- .../share/classes/java/util/zip/ZipFile.java | 12 +----------- .../share/classes/java/util/zip/ZipOutputStream.java | 3 +-- 3 files changed, 5 insertions(+), 17 deletions(-) diff --git a/src/java.base/share/classes/java/util/jar/JarFile.java b/src/java.base/share/classes/java/util/jar/JarFile.java index a14821d8046..7b64e3cdd04 100644 --- a/src/java.base/share/classes/java/util/jar/JarFile.java +++ b/src/java.base/share/classes/java/util/jar/JarFile.java @@ -28,7 +28,6 @@ import jdk.internal.access.SharedSecrets; import jdk.internal.access.JavaUtilZipFileAccess; import jdk.internal.misc.ThreadTracker; -import sun.security.action.GetPropertyAction; import sun.security.util.ManifestEntryVerifier; import sun.security.util.SignatureFileVerifier; @@ -171,7 +170,7 @@ public class JarFile extends ZipFile { // multi-release jar file versions >= 9 BASE_VERSION = Runtime.Version.parse(Integer.toString(8)); BASE_VERSION_FEATURE = BASE_VERSION.feature(); - String jarVersion = GetPropertyAction.privilegedGetProperty("jdk.util.jar.version"); + String jarVersion = System.getProperty("jdk.util.jar.version"); int runtimeVersion = Runtime.version().feature(); if (jarVersion != null) { int jarVer = Integer.parseInt(jarVersion); @@ -180,8 +179,8 @@ public class JarFile extends ZipFile { : Math.max(jarVer, BASE_VERSION_FEATURE); } RUNTIME_VERSION = Runtime.Version.parse(Integer.toString(runtimeVersion)); - String enableMultiRelease = GetPropertyAction - .privilegedGetProperty("jdk.util.jar.enableMultiRelease", "true"); + String enableMultiRelease = System. + getProperty("jdk.util.jar.enableMultiRelease", "true"); switch (enableMultiRelease) { case "false" -> { MULTI_RELEASE_ENABLED = false; diff --git a/src/java.base/share/classes/java/util/zip/ZipFile.java b/src/java.base/share/classes/java/util/zip/ZipFile.java index a08d3bc7a1b..f736a092099 100644 --- a/src/java.base/share/classes/java/util/zip/ZipFile.java +++ b/src/java.base/share/classes/java/util/zip/ZipFile.java @@ -55,7 +55,6 @@ import jdk.internal.vm.annotation.Stable; import sun.nio.cs.UTF_8; import sun.nio.fs.DefaultFileSystemProvider; -import sun.security.action.GetPropertyAction; import sun.security.util.SignatureFileVerifier; import static java.util.zip.ZipConstants64.*; @@ -193,14 +192,6 @@ public ZipFile(File file, int mode, Charset charset) throws IOException } String name = file.getPath(); file = new File(name); - @SuppressWarnings("removal") - SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - sm.checkRead(name); - if ((mode & OPEN_DELETE) != 0) { - sm.checkDelete(name); - } - } Objects.requireNonNull(charset, "charset"); this.filePath = name; @@ -1059,8 +1050,7 @@ private BitSet getMetaInfVersions(String name) { */ static boolean getDisableZip64ExtraFieldValidation() { boolean result; - String value = GetPropertyAction.privilegedGetProperty( - "jdk.util.zip.disableZip64ExtraFieldValidation"); + String value = System.getProperty("jdk.util.zip.disableZip64ExtraFieldValidation"); if (value == null) { result = false; } else { diff --git a/src/java.base/share/classes/java/util/zip/ZipOutputStream.java b/src/java.base/share/classes/java/util/zip/ZipOutputStream.java index 3fe992ab440..47499858a37 100644 --- a/src/java.base/share/classes/java/util/zip/ZipOutputStream.java +++ b/src/java.base/share/classes/java/util/zip/ZipOutputStream.java @@ -35,7 +35,6 @@ import static java.util.zip.ZipEntry.isCENHeaderValid; import static java.util.zip.ZipUtils.*; import sun.nio.cs.UTF_8; -import sun.security.action.GetBooleanAction; /** * This class implements an output stream filter for writing files in the @@ -58,7 +57,7 @@ public class ZipOutputStream extends DeflaterOutputStream implements ZipConstant * some in jdk7. */ private static final boolean inhibitZip64 = - GetBooleanAction.privilegedGetProperty("jdk.util.zip.inhibitZip64"); + Boolean.getBoolean("jdk.util.zip.inhibitZip64"); private static class XEntry { final ZipEntry entry; From bfee766f035fb1b122cd3f3703b9e2a2d85abfe6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eirik=20Bj=C3=B8rsn=C3=B8s?= Date: Fri, 15 Nov 2024 07:48:15 +0000 Subject: [PATCH 007/311] 8344183: (zipfs) SecurityManager cleanup in the ZipFS area Reviewed-by: mullan, lancea --- .../classes/jdk/nio/zipfs/ZipFileSystem.java | 58 +++++-------------- .../jdk/nio/zipfs/ZipFileSystemProvider.java | 15 +---- test/jdk/jdk/nio/zipfs/TestPosix.java | 37 +++++------- 3 files changed, 28 insertions(+), 82 deletions(-) diff --git a/src/jdk.zipfs/share/classes/jdk/nio/zipfs/ZipFileSystem.java b/src/jdk.zipfs/share/classes/jdk/nio/zipfs/ZipFileSystem.java index 20ed86eae4f..9ea935551b8 100644 --- a/src/jdk.zipfs/share/classes/jdk/nio/zipfs/ZipFileSystem.java +++ b/src/jdk.zipfs/share/classes/jdk/nio/zipfs/ZipFileSystem.java @@ -44,10 +44,6 @@ import java.nio.file.*; import java.nio.file.attribute.*; import java.nio.file.spi.FileSystemProvider; -import java.security.AccessController; -import java.security.PrivilegedAction; -import java.security.PrivilegedActionException; -import java.security.PrivilegedExceptionAction; import java.util.*; import java.util.concurrent.locks.ReadWriteLock; import java.util.concurrent.locks.ReentrantReadWriteLock; @@ -82,10 +78,8 @@ */ class ZipFileSystem extends FileSystem { // statics - @SuppressWarnings("removal") - private static final boolean isWindows = AccessController.doPrivileged( - (PrivilegedAction)()->System.getProperty("os.name") - .startsWith("Windows")); + private static final boolean isWindows = System.getProperty("os.name") + .startsWith("Windows"); private static final byte[] ROOTPATH = new byte[] { '/' }; private static final String PROPERTY_POSIX = "enablePosixFileAttributes"; private static final String PROPERTY_DEFAULT_OWNER = "defaultOwner"; @@ -168,9 +162,7 @@ class ZipFileSystem extends FileSystem { } // sm and existence check zfpath.getFileSystem().provider().checkAccess(zfpath, AccessMode.READ); - @SuppressWarnings("removal") - boolean writeable = AccessController.doPrivileged( - (PrivilegedAction)()->Files.isWritable(zfpath)); + boolean writeable = Files.isWritable(zfpath); this.readOnly = !writeable; this.zc = ZipCoder.get(nameEncoding); this.rootdir = new ZipPath(this, new byte[]{'/'}); @@ -244,23 +236,14 @@ private static boolean isTrue(Map env, String name) { // If not specified in env, it is the owner of the archive. If no owner can // be determined, we try to go with system property "user.name". If that's not // accessible, we return "". - @SuppressWarnings("removal") private UserPrincipal initOwner(Path zfpath, Map env) throws IOException { Object o = env.get(PROPERTY_DEFAULT_OWNER); if (o == null) { try { - PrivilegedExceptionAction pa = ()->Files.getOwner(zfpath); - return AccessController.doPrivileged(pa); - } catch (UnsupportedOperationException | PrivilegedActionException e) { - if (e instanceof UnsupportedOperationException || - e.getCause() instanceof NoSuchFileException) - { - PrivilegedAction pa = ()->System.getProperty("user.name"); - String userName = AccessController.doPrivileged(pa); - return ()->userName; - } else { - throw new IOException(e); - } + return Files.getOwner(zfpath); + } catch (UnsupportedOperationException | NoSuchFileException e) { + String userName = System.getProperty("user.name"); + return ()->userName; } } if (o instanceof String) { @@ -282,7 +265,6 @@ private UserPrincipal initOwner(Path zfpath, Map env) throws IOExcept // If not specified in env, we try to determine the group of the zip archive itself. // If this is not possible/unsupported, we will return a group principal going by // the same name as the default owner. - @SuppressWarnings("removal") private GroupPrincipal initGroup(Path zfpath, Map env) throws IOException { Object o = env.get(PROPERTY_DEFAULT_GROUP); if (o == null) { @@ -291,16 +273,9 @@ private GroupPrincipal initGroup(Path zfpath, Map env) throws IOExcep if (zfpv == null) { return defaultOwner::getName; } - PrivilegedExceptionAction pa = ()->zfpv.readAttributes().group(); - return AccessController.doPrivileged(pa); - } catch (UnsupportedOperationException | PrivilegedActionException e) { - if (e instanceof UnsupportedOperationException || - e.getCause() instanceof NoSuchFileException) - { - return defaultOwner::getName; - } else { - throw new IOException(e); - } + return zfpv.readAttributes().group(); + } catch (UnsupportedOperationException | NoSuchFileException e) { + return defaultOwner::getName; } } if (o instanceof String) { @@ -462,7 +437,6 @@ public PathMatcher getPathMatcher(String syntaxAndInput) { return (path)->pattern.matcher(path.toString()).matches(); } - @SuppressWarnings("removal") @Override public void close() throws IOException { beginWrite(); @@ -480,13 +454,9 @@ public void close() throws IOException { } beginWrite(); // lock and sync try { - AccessController.doPrivileged((PrivilegedExceptionAction)() -> { - sync(); return null; - }); + sync(); ch.close(); // close the ch just in case no update // and sync didn't close the ch - } catch (PrivilegedActionException e) { - throw (IOException)e.getException(); } finally { endWrite(); } @@ -512,10 +482,8 @@ public void close() throws IOException { synchronized (tmppaths) { for (Path p : tmppaths) { try { - AccessController.doPrivileged( - (PrivilegedExceptionAction)() -> Files.deleteIfExists(p)); - } catch (PrivilegedActionException e) { - IOException x = (IOException)e.getException(); + Files.deleteIfExists(p); + } catch (IOException x) { if (ioe == null) ioe = x; else diff --git a/src/jdk.zipfs/share/classes/jdk/nio/zipfs/ZipFileSystemProvider.java b/src/jdk.zipfs/share/classes/jdk/nio/zipfs/ZipFileSystemProvider.java index 615d2a42e20..a8336b0f8f6 100644 --- a/src/jdk.zipfs/share/classes/jdk/nio/zipfs/ZipFileSystemProvider.java +++ b/src/jdk.zipfs/share/classes/jdk/nio/zipfs/ZipFileSystemProvider.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -39,9 +39,6 @@ import java.nio.file.attribute.FileAttribute; import java.nio.file.attribute.FileAttributeView; import java.nio.file.spi.FileSystemProvider; -import java.security.AccessController; -import java.security.PrivilegedActionException; -import java.security.PrivilegedExceptionAction; import java.util.HashMap; import java.util.Map; import java.util.Set; @@ -317,17 +314,9 @@ public void setAttribute(Path path, String attribute, } ////////////////////////////////////////////////////////////// - @SuppressWarnings("removal") void removeFileSystem(Path zfpath, ZipFileSystem zfs) throws IOException { synchronized (filesystems) { - Path tempPath = zfpath; - PrivilegedExceptionAction action = tempPath::toRealPath; - try { - zfpath = AccessController.doPrivileged(action); - } catch (PrivilegedActionException e) { - throw (IOException) e.getException(); - } - filesystems.remove(zfpath, zfs); + filesystems.remove(zfpath.toRealPath(), zfs); } } } diff --git a/test/jdk/jdk/nio/zipfs/TestPosix.java b/test/jdk/jdk/nio/zipfs/TestPosix.java index f63f091c32e..420c1618e12 100644 --- a/test/jdk/jdk/nio/zipfs/TestPosix.java +++ b/test/jdk/jdk/nio/zipfs/TestPosix.java @@ -29,10 +29,6 @@ import java.nio.ByteOrder; import java.nio.file.*; import java.nio.file.attribute.*; -import java.security.AccessController; -import java.security.PrivilegedAction; -import java.security.PrivilegedActionException; -import java.security.PrivilegedExceptionAction; import java.time.Instant; import java.util.*; import java.util.concurrent.atomic.AtomicInteger; @@ -219,35 +215,28 @@ static interface Executor { private static String expectedDefaultOwner(Path zf) { try { - try { - PrivilegedExceptionAction pa = ()->Files.getOwner(zf).getName(); - return AccessController.doPrivileged(pa); - } catch (UnsupportedOperationException e) { - // if we can't get the owner of the file, we fall back to system property user.name - PrivilegedAction pa = ()->System.getProperty("user.name"); - return AccessController.doPrivileged(pa); - } - } catch (PrivilegedActionException | SecurityException e) { + return Files.getOwner(zf).getName(); + } catch (UnsupportedOperationException e) { + // if we can't get the owner of the file, we fall back to system property user.name + return System.getProperty("user.name"); + } catch (IOException e) { System.out.println("Caught " + e.getClass().getName() + "(" + e.getMessage() + - ") when running a privileged operation to get the default owner."); + ") when getting the default owner."); return null; } } private static String expectedDefaultGroup(Path zf, String defaultOwner) { try { - try { - PosixFileAttributeView zfpv = Files.getFileAttributeView(zf, PosixFileAttributeView.class); - if (zfpv == null) { - return defaultOwner; - } - PrivilegedExceptionAction pa = ()->zfpv.readAttributes().group().getName(); - return AccessController.doPrivileged(pa); - } catch (UnsupportedOperationException e) { + PosixFileAttributeView zfpv = Files.getFileAttributeView(zf, PosixFileAttributeView.class); + if (zfpv == null) { return defaultOwner; } - } catch (PrivilegedActionException | SecurityException e) { - System.out.println("Caught an exception when running a privileged operation to get the default group."); + return zfpv.readAttributes().group().getName(); + } catch (UnsupportedOperationException e) { + return defaultOwner; + } catch (IOException e) { + System.out.println("Caught an exception when getting the default group."); e.printStackTrace(); return null; } From 0c191f66299900d5de2629f6c6a761c55c7a97b5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eirik=20Bj=C3=B8rsn=C3=B8s?= Date: Fri, 15 Nov 2024 09:47:43 +0000 Subject: [PATCH 008/311] 8344185: Remove calls to SecurityManager in sun.net.ftp Reviewed-by: alanb, michaelm, dfuchs --- .../share/classes/sun/net/ftp/FtpClient.java | 6 +-- .../sun/net/ftp/FtpClientProvider.java | 38 ++++--------- .../classes/sun/net/ftp/impl/FtpClient.java | 53 ++++--------------- 3 files changed, 22 insertions(+), 75 deletions(-) diff --git a/src/java.base/share/classes/sun/net/ftp/FtpClient.java b/src/java.base/share/classes/sun/net/ftp/FtpClient.java index da0cffd3f20..970d095242c 100644 --- a/src/java.base/share/classes/sun/net/ftp/FtpClient.java +++ b/src/java.base/share/classes/sun/net/ftp/FtpClient.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -234,8 +234,6 @@ public static FtpClient create(String dest) throws FtpProtocolException, IOExcep * @param dest the address of the destination server * @return this FtpClient * @throws IOException if connection failed. - * @throws SecurityException if there is a SecurityManager installed and it - * denied the authorization to connect to the destination. * @throws FtpProtocolException */ public abstract FtpClient connect(SocketAddress dest) throws FtpProtocolException, IOException; @@ -247,8 +245,6 @@ public static FtpClient create(String dest) throws FtpProtocolException, IOExcep * @param timeout the value, in milliseconds, to use as a connection timeout * @return this FtpClient * @throws IOException if connection failed. - * @throws SecurityException if there is a SecurityManager installed and it - * denied the authorization to connect to the destination. * @throws FtpProtocolException */ public abstract FtpClient connect(SocketAddress dest, int timeout) throws FtpProtocolException, IOException; diff --git a/src/java.base/share/classes/sun/net/ftp/FtpClientProvider.java b/src/java.base/share/classes/sun/net/ftp/FtpClientProvider.java index ad5d092aab1..94136d85f1d 100644 --- a/src/java.base/share/classes/sun/net/ftp/FtpClientProvider.java +++ b/src/java.base/share/classes/sun/net/ftp/FtpClientProvider.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -24,8 +24,6 @@ */ package sun.net.ftp; -import java.security.AccessController; -import java.security.PrivilegedAction; import java.util.ServiceConfigurationError; //import java.util.ServiceLoader; @@ -50,16 +48,8 @@ public abstract class FtpClientProvider { /** * Initializes a new instance of this class. - * - * @throws SecurityException if a security manager is installed and it denies - * {@link RuntimePermission}{@code ("ftpClientProvider")} */ protected FtpClientProvider() { - @SuppressWarnings("removal") - SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - sm.checkPermission(new RuntimePermission("ftpClientProvider")); - } } private static boolean loadProviderFromProperty() { @@ -74,8 +64,7 @@ private static boolean loadProviderFromProperty() { return true; } catch (ClassNotFoundException | IllegalAccessException | - InstantiationException | - SecurityException x) { + InstantiationException x) { throw new ServiceConfigurationError(x.toString()); } } @@ -135,26 +124,19 @@ private static boolean loadProviderAsService() { * * @return The system-wide default FtpClientProvider */ - @SuppressWarnings("removal") public static FtpClientProvider provider() { synchronized (lock) { if (provider != null) { return provider; } - return (FtpClientProvider) AccessController.doPrivileged( - new PrivilegedAction() { - - public Object run() { - if (loadProviderFromProperty()) { - return provider; - } - if (loadProviderAsService()) { - return provider; - } - provider = new sun.net.ftp.impl.DefaultFtpClientProvider(); - return provider; - } - }); + if (loadProviderFromProperty()) { + return provider; + } + if (loadProviderAsService()) { + return provider; + } + provider = new sun.net.ftp.impl.DefaultFtpClientProvider(); + return provider; } } } diff --git a/src/java.base/share/classes/sun/net/ftp/impl/FtpClient.java b/src/java.base/share/classes/sun/net/ftp/impl/FtpClient.java index 8b6dd9c5ec7..bfc10028ae0 100644 --- a/src/java.base/share/classes/sun/net/ftp/impl/FtpClient.java +++ b/src/java.base/share/classes/sun/net/ftp/impl/FtpClient.java @@ -44,9 +44,6 @@ import java.net.ServerSocket; import java.net.Socket; import java.net.SocketAddress; -import java.security.AccessController; -import java.security.PrivilegedAction; -import java.security.PrivilegedExceptionAction; import java.text.DateFormat; import java.time.ZoneOffset; import java.time.ZonedDateTime; @@ -133,31 +130,17 @@ public class FtpClient extends sun.net.ftp.FtpClient { private DateFormat df = DateFormat.getDateInstance(DateFormat.MEDIUM, java.util.Locale.US); private static final boolean acceptPasvAddressVal; static { - final int vals[] = {0, 0}; - final String acceptPasvAddress[] = {null}; - @SuppressWarnings("removal") - final String enc = AccessController.doPrivileged( - new PrivilegedAction() { - public String run() { - acceptPasvAddress[0] = System.getProperty("jdk.net.ftp.trustPasvAddress", "false"); - vals[0] = Integer.getInteger("sun.net.client.defaultReadTimeout", 300_000).intValue(); - vals[1] = Integer.getInteger("sun.net.client.defaultConnectTimeout", 300_000).intValue(); - return System.getProperty("file.encoding", "ISO8859_1"); - } - }); - if (vals[0] == 0) { + defaultSoTimeout = Integer.getInteger("sun.net.client.defaultReadTimeout", 300_000).intValue(); + if (defaultSoTimeout == 0) { defaultSoTimeout = -1; - } else { - defaultSoTimeout = vals[0]; } - if (vals[1] == 0) { + defaultConnectTimeout = Integer.getInteger("sun.net.client.defaultConnectTimeout", 300_000).intValue(); + if (defaultConnectTimeout == 0) { defaultConnectTimeout = -1; - } else { - defaultConnectTimeout = vals[1]; } - encoding = enc; + encoding = System.getProperty("file.encoding", "ISO8859_1"); try { if (!isASCIISuperset(encoding)) { encoding = "ISO8859_1"; @@ -171,7 +154,7 @@ public String run() { patterns[i] = Pattern.compile(patStrings[i]); } - acceptPasvAddressVal = Boolean.parseBoolean(acceptPasvAddress[0]); + acceptPasvAddressVal = Boolean.getBoolean("jdk.net.ftp.trustPasvAddress"); } /** @@ -662,10 +645,7 @@ private Socket openPassiveDataConnection(String cmd) throws sun.net.ftp.FtpProto Socket s; if (proxy != null) { if (proxy.type() == Proxy.Type.SOCKS) { - PrivilegedAction pa = () -> new Socket(proxy); - @SuppressWarnings("removal") - var tmp = AccessController.doPrivileged(pa); - s = tmp; + s = new Socket(proxy); } else { s = new Socket(Proxy.NO_PROXY); } @@ -673,9 +653,7 @@ private Socket openPassiveDataConnection(String cmd) throws sun.net.ftp.FtpProto s = new Socket(); } - PrivilegedAction pa = () -> server.getLocalAddress(); - @SuppressWarnings("removal") - InetAddress serverAddress = AccessController.doPrivileged(pa); + InetAddress serverAddress = server.getLocalAddress(); // Bind the socket to the same address as the control channel. This // is needed in case of multi-homed systems. @@ -761,11 +739,8 @@ private InetSocketAddress validatePasvAddress(int port, String s, InetAddress ad } private static InetAddress privilegedLocalHost() throws FtpProtocolException { - PrivilegedExceptionAction action = InetAddress::getLocalHost; try { - @SuppressWarnings("removal") - var tmp = AccessController.doPrivileged(action); - return tmp; + return InetAddress.getLocalHost(); } catch (Exception e) { var ftpEx = new FtpProtocolException(ERROR_MSG); ftpEx.initCause(e); @@ -774,11 +749,8 @@ private static InetAddress privilegedLocalHost() throws FtpProtocolException { } private static InetAddress[] privilegedGetAllByName(String hostName) throws FtpProtocolException { - PrivilegedExceptionAction pAction = () -> InetAddress.getAllByName(hostName); try { - @SuppressWarnings("removal") - var tmp =AccessController.doPrivileged(pAction); - return tmp; + return InetAddress.getAllByName(hostName); } catch (Exception e) { var ftpEx = new FtpProtocolException(ERROR_MSG); ftpEx.initCause(e); @@ -1021,10 +993,7 @@ private Socket doConnect(InetSocketAddress dest, int timeout) throws IOException Socket s; if (proxy != null) { if (proxy.type() == Proxy.Type.SOCKS) { - PrivilegedAction pa = () -> new Socket(proxy); - @SuppressWarnings("removal") - var tmp = AccessController.doPrivileged(pa); - s = tmp; + s = new Socket(proxy); } else { s = new Socket(Proxy.NO_PROXY); } From 5b9932f8f3c320f1d2c95403478a6069d05da52a Mon Sep 17 00:00:00 2001 From: Maurizio Cimadamore Date: Fri, 15 Nov 2024 10:07:18 +0000 Subject: [PATCH 009/311] 8338288: Compiler Implementation for Flexible Constructor Bodies (Third Preview) 8322882: Null pointer error when compiling Static initializer in a local class 8334248: Invalid error for early construction local class constructor method reference 8330037: Compiler produces invalid bytecode for method class creation from static method Reviewed-by: jlahoda, vromero --- .../com/sun/tools/javac/code/Kinds.java | 1 - .../com/sun/tools/javac/comp/Attr.java | 34 ++-- .../com/sun/tools/javac/comp/Resolve.java | 179 +++++++++--------- .../tools/javac/resources/compiler.properties | 10 +- .../javac/LocalFreeVarStaticInstantiate.java | 44 +++++ .../javac/LocalFreeVarStaticInstantiate.out | 5 + .../QualifiedAccess/QualifiedAccess_2.java | 2 +- .../SuperInit/EarlyIndirectOuterCapture.java | 29 +++ .../SuperInit/EarlyIndirectOuterCapture.out | 2 + .../javac/SuperInit/EarlyLocalCtorRef.java | 45 +++++ .../javac/SuperInit/EarlyLocalTest2.java | 43 +++++ .../javac/SuperInit/EarlyLocalTest3.java | 43 +++++ .../javac/SuperInit/EarlyLocalTest8.java | 49 +++++ ...r.java => LocalClassCantBeInstStatic.java} | 24 +-- .../tools/javac/lambda/MethodReference23.out | 8 +- .../tools/javac/lambda/MethodReference37.out | 4 +- .../lambda/MethodReferenceNoThisTest.out | 2 +- .../MethodRefToInnerWithoutOuter.out | 2 +- 18 files changed, 393 insertions(+), 133 deletions(-) create mode 100644 test/langtools/tools/javac/LocalFreeVarStaticInstantiate.java create mode 100644 test/langtools/tools/javac/LocalFreeVarStaticInstantiate.out create mode 100644 test/langtools/tools/javac/SuperInit/EarlyIndirectOuterCapture.java create mode 100644 test/langtools/tools/javac/SuperInit/EarlyIndirectOuterCapture.out create mode 100644 test/langtools/tools/javac/SuperInit/EarlyLocalCtorRef.java create mode 100644 test/langtools/tools/javac/SuperInit/EarlyLocalTest2.java create mode 100644 test/langtools/tools/javac/SuperInit/EarlyLocalTest3.java create mode 100644 test/langtools/tools/javac/SuperInit/EarlyLocalTest8.java rename test/langtools/tools/javac/diags/examples/{CantAccessInnerClsConstr.java => LocalClassCantBeInstStatic.java} (72%) diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Kinds.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Kinds.java index e5d9a9e2ac4..2491cd31f0d 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Kinds.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Kinds.java @@ -70,7 +70,6 @@ public enum Kind { AMBIGUOUS(Category.RESOLUTION_TARGET), // overloaded target HIDDEN(Category.RESOLUTION_TARGET), // not overloaded non-target STATICERR(Category.RESOLUTION_TARGET), // overloaded? target - MISSING_ENCL(Category.RESOLUTION), // not overloaded non-target BAD_RESTRICTED_TYPE(Category.RESOLUTION), // not overloaded non-target ABSENT_VAR(Category.RESOLUTION_TARGET, KindName.VAR), // not overloaded non-target WRONG_MTHS(Category.RESOLUTION_TARGET, KindName.METHOD), // overloaded target diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java index 07a136c1700..f565cff0788 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java @@ -2590,8 +2590,7 @@ public void visitApply(JCMethodInvocation tree) { } else if (methName == names._super) { // qualifier omitted; check for existence // of an appropriate implicit qualifier. - rs.resolveImplicitThis(tree.meth.pos(), - localEnv, site, true); + checkNewInnerClass(tree.meth.pos(), localEnv, site, true); } } else if (tree.meth.hasTag(SELECT)) { log.error(tree.meth.pos(), @@ -2798,11 +2797,9 @@ public void visitNewClass(final JCNewClass tree) { log.error(tree.encl.pos(), Errors.QualifiedNewOfStaticClass(clazztype.tsym)); } } - } else if (!clazztype.tsym.isInterface() && - (clazztype.tsym.flags_field & NOOUTERTHIS) == 0 && - clazztype.getEnclosingType().hasTag(CLASS)) { + } else { // Check for the existence of an apropos outer instance - rs.resolveImplicitThis(tree.pos(), env, clazztype); + checkNewInnerClass(tree.pos(), env, clazztype, false); } // Attribute constructor arguments. @@ -3067,6 +3064,24 @@ public void report(DiagnosticPosition _unused, JCDiagnostic details) { }; } + void checkNewInnerClass(DiagnosticPosition pos, Env env, Type type, boolean isSuper) { + boolean isLocal = type.tsym.owner.kind == MTH; + if ((type.tsym.flags() & (INTERFACE | ENUM | RECORD)) != 0 || + (!isLocal && !type.tsym.isInner()) || + (isSuper && env.enclClass.sym.isAnonymous())) { + // nothing to check + return; + } + Symbol res = isLocal ? + rs.findLocalClassOwner(env, type.tsym) : + rs.findSelfContaining(pos, env, type.getEnclosingType().tsym, isSuper); + if (res.exists()) { + rs.accessBase(res, pos, env.enclClass.sym.type, names._this, true); + } else { + log.error(pos, Errors.EnclClassRequired(type.tsym)); + } + } + /** Make an attributed null check tree. */ public JCExpression makeNullCheck(JCExpression arg) { @@ -3639,7 +3654,6 @@ public void visitReference(final JCMemberReference that) { boolean targetError; switch (refSym.kind) { case ABSENT_MTH: - case MISSING_ENCL: targetError = false; break; case WRONG_MTH: @@ -3690,11 +3704,7 @@ public void visitReference(final JCMemberReference that) { } if (!env.info.attributionMode.isSpeculative && that.getMode() == JCMemberReference.ReferenceMode.NEW) { - Type enclosingType = exprType.getEnclosingType(); - if (enclosingType != null && enclosingType.hasTag(CLASS)) { - // Check for the existence of an appropriate outer instance - rs.resolveImplicitThis(that.pos(), env, exprType); - } + checkNewInnerClass(that.pos(), env, exprType, false); } if (resultInfo.checkContext.deferredAttrContext().mode == AttrMode.CHECK) { diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Resolve.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Resolve.java index a9527171749..43a0c61a069 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Resolve.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Resolve.java @@ -3744,11 +3744,10 @@ class ConstructorReferenceLookupHelper extends ReferenceLookupHelper { @Override protected Symbol lookup(Env env, MethodResolutionPhase phase) { - Symbol sym = needsInference ? + return needsInference ? findDiamond(env, site, argtypes, typeargtypes, phase.isBoxingRequired(), phase.isVarargsRequired()) : findMethod(env, site, name, argtypes, typeargtypes, phase.isBoxingRequired(), phase.isVarargsRequired()); - return enclosingInstanceMissing(env, site) ? new BadConstructorReferenceError(sym) : sym; } @Override @@ -3793,6 +3792,63 @@ Symbol lookupMethod(Env env, DiagnosticPosition pos, Symbol locatio } } + /** + * Find a "valid" reference to an enclosing 'A.this' such that A is a subclass of the provided class symbol. + * A reference to an enclosing 'A.this' is "valid" if (a) we're not in the early-construction context for A + * and (b) if the current class is not an inner class of A. + */ + Symbol findSelfContaining(DiagnosticPosition pos, + Env env, + TypeSymbol c, + boolean isSuper) { + Env env1 = isSuper ? env.outer : env; + boolean staticOnly = false; + while (env1.outer != null) { + if (isStatic(env1)) staticOnly = true; + if (env1.enclClass.sym.isSubClass(c, types)) { + Symbol sym = env1.info.scope.findFirst(names._this); + if (sym != null) { + if (staticOnly) { + // current class is not an inner class, stop search + return new StaticError(sym); + } else if (env1.info.ctorPrologue && !isAllowedEarlyReference(pos, env1, (VarSymbol)sym)) { + // early construction context, stop search + return new RefBeforeCtorCalledError(sym); + } else { + // found it + return sym; + } + } + } + if ((env1.enclClass.sym.flags() & STATIC) != 0) staticOnly = true; + env1 = env1.outer; + } + return varNotFound; + } + + /** + * Resolve the (method) owner of a local class. This can fail if the local class + * is referenced from a static context nested inside the local class. Effectively, + * this lookup succeeds if we can access a local variable declared inside the owner + * method from the provided env. + */ + Symbol findLocalClassOwner(Env env, TypeSymbol c) { + Symbol owner = c.owner; + Assert.check(owner.kind == MTH); + Env env1 = env; + boolean staticOnly = false; + while (env1.outer != null) { + if (env1.info.scope.owner == owner) { + return (staticOnly) ? + new BadLocalClassCreation(c) : + owner; + } + if (isStatic(env1)) staticOnly = true; + env1 = env1.outer; + } + return methodNotFound; + } + /** * Resolve `c.name' where name == this or name == super. * @param pos The position to use for error reporting. @@ -3817,15 +3873,15 @@ Symbol resolveSelf(DiagnosticPosition pos, else if (env1.info.ctorPrologue && !isAllowedEarlyReference(pos, env1, (VarSymbol)sym)) sym = new RefBeforeCtorCalledError(sym); return accessBase(sym, pos, env.enclClass.sym.type, - name, true); + name, true); } } if ((env1.enclClass.sym.flags() & STATIC) != 0) staticOnly = true; env1 = env1.outer; } if (c.isInterface() && - name == names._super && !isStatic(env) && - types.isDirectSuperInterface(c, env.enclClass.sym)) { + name == names._super && !isStatic(env) && + types.isDirectSuperInterface(c, env.enclClass.sym)) { //this might be a default super call if one of the superinterfaces is 'c' for (Type t : pruneInterfaces(env.enclClass.type)) { if (t.tsym == c) { @@ -3840,8 +3896,8 @@ else if (env1.info.ctorPrologue && !isAllowedEarlyReference(pos, env1, (VarSymbo for (Type i : types.directSupertypes(env.enclClass.type)) { if (i.tsym.isSubClass(c, types) && i.tsym != c) { log.error(pos, - Errors.IllegalDefaultSuperCall(c, - Fragments.RedundantSupertype(c, i))); + Errors.IllegalDefaultSuperCall(c, + Fragments.RedundantSupertype(c, i))); return syms.errSymbol; } } @@ -3948,76 +4004,6 @@ public boolean isEarlyReference(Env env, JCTree base, VarSymbol v) (base == null || TreeInfo.isExplicitThisReference(types, (ClassType)env.enclClass.type, base)); } - /** - * Resolve `c.this' for an enclosing class c that contains the - * named member. - * @param pos The position to use for error reporting. - * @param env The environment current at the expression. - * @param member The member that must be contained in the result. - */ - Symbol resolveSelfContaining(DiagnosticPosition pos, - Env env, - Symbol member, - boolean isSuperCall) { - Symbol sym = resolveSelfContainingInternal(env, member, isSuperCall); - if (sym == null) { - log.error(pos, Errors.EnclClassRequired(member)); - return syms.errSymbol; - } else { - return accessBase(sym, pos, env.enclClass.sym.type, sym.name, true); - } - } - - boolean enclosingInstanceMissing(Env env, Type type) { - if (type.hasTag(CLASS) && type.getEnclosingType().hasTag(CLASS)) { - Symbol encl = resolveSelfContainingInternal(env, type.tsym, false); - return encl == null || encl.kind.isResolutionError(); - } - return false; - } - - private Symbol resolveSelfContainingInternal(Env env, - Symbol member, - boolean isSuperCall) { - Name name = names._this; - Env env1 = isSuperCall ? env.outer : env; - boolean staticOnly = false; - if (env1 != null) { - while (env1 != null && env1.outer != null) { - if (isStatic(env1)) staticOnly = true; - if (env1.enclClass.sym.isSubClass(member.owner.enclClass(), types)) { - Symbol sym = env1.info.scope.findFirst(name); - if (sym != null) { - if (staticOnly) sym = new StaticError(sym); - return sym; - } - } - if ((env1.enclClass.sym.flags() & STATIC) != 0) - staticOnly = true; - env1 = env1.outer; - } - } - return null; - } - - /** - * Resolve an appropriate implicit this instance for t's container. - * JLS 8.8.5.1 and 15.9.2 - */ - Type resolveImplicitThis(DiagnosticPosition pos, Env env, Type t) { - return resolveImplicitThis(pos, env, t, false); - } - - Type resolveImplicitThis(DiagnosticPosition pos, Env env, Type t, boolean isSuperCall) { - Type thisType = (t.tsym.owner.kind.matches(KindSelector.VAL_MTH) - ? resolveSelf(pos, env, t.getEnclosingType().tsym, names._this) - : resolveSelfContaining(pos, env, t.tsym, isSuperCall)).type; - if (env.info.ctorPrologue && thisType.tsym == env.enclClass.sym) { - log.error(pos, Errors.CantRefBeforeCtorCalled(names._this)); - } - return thisType; - } - /* *************************************************************************** * ResolveError classes, indicating error situations when accessing symbols ****************************************************************************/ @@ -4741,6 +4727,28 @@ JCDiagnostic getDiagnostic(JCDiagnostic.DiagnosticType dkind, } } + /** + * Specialization of {@link StaticError} for illegal + * creation of local class instances from a static context. + */ + class BadLocalClassCreation extends StaticError { + BadLocalClassCreation(Symbol sym) { + super(sym, "bad local class creation"); + } + + @Override + JCDiagnostic getDiagnostic(JCDiagnostic.DiagnosticType dkind, + DiagnosticPosition pos, + Symbol location, + Type site, + Name name, + List argtypes, + List typeargtypes) { + return diags.create(dkind, log.currentSource(), pos, + "local.cant.be.inst.static", kindName(sym), sym); + } + } + /** * Specialization of {@link InvalidSymbolError} for illegal * early accesses within a constructor prologue. @@ -4900,23 +4908,6 @@ JCDiagnostic getDiagnostic(DiagnosticType dkind, DiagnosticPosition pos, Symbol } } - /** - * BadConstructorReferenceError error class indicating that a constructor reference symbol has been found, - * but pointing to a class for which an enclosing instance is not available. - */ - class BadConstructorReferenceError extends InvalidSymbolError { - - public BadConstructorReferenceError(Symbol sym) { - super(MISSING_ENCL, sym, "BadConstructorReferenceError"); - } - - @Override - JCDiagnostic getDiagnostic(DiagnosticType dkind, DiagnosticPosition pos, Symbol location, Type site, Name name, List argtypes, List typeargtypes) { - return diags.create(dkind, log.currentSource(), pos, - "cant.access.inner.cls.constr", site.tsym.name, argtypes, site.getEnclosingType()); - } - } - class BadClassFileError extends InvalidSymbolError { private final CompletionFailure ex; diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties b/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties index 9e42c2f377a..bd666f3427d 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/resources/compiler.properties @@ -1095,11 +1095,6 @@ compiler.misc.not.def.access.class.intf.cant.access.reason=\ {1}.{0} in package {2} is not accessible\n\ ({3}) -# 0: symbol, 1: list of type, 2: type -compiler.misc.cant.access.inner.cls.constr=\ - cannot access constructor {0}({1})\n\ - an enclosing instance of type {2} is not in scope - # 0: symbol, 1: symbol compiler.err.not.def.public.cant.access=\ {0} is not public in {1}; cannot be accessed from outside package @@ -2883,6 +2878,11 @@ compiler.err.abstract.cant.be.accessed.directly=\ compiler.err.non-static.cant.be.ref=\ non-static {0} {1} cannot be referenced from a static context +## The first argument ({0}) is a "kindname". +# 0: symbol kind, 1: symbol +compiler.err.local.cant.be.inst.static=\ + local {0} {1} cannot be instantiated from a static context + # 0: symbol kind, 1: symbol compiler.misc.bad.static.method.in.unbound.lookup=\ unexpected static {0} {1} found in unbound lookup diff --git a/test/langtools/tools/javac/LocalFreeVarStaticInstantiate.java b/test/langtools/tools/javac/LocalFreeVarStaticInstantiate.java new file mode 100644 index 00000000000..39b419c694a --- /dev/null +++ b/test/langtools/tools/javac/LocalFreeVarStaticInstantiate.java @@ -0,0 +1,44 @@ +/* + * @test /nodynamiccopyright/ + * @bug 8322882 + * @summary Disallow attempts to access a free variable proxy field from a static method + * @compile/fail/ref=LocalFreeVarStaticInstantiate.out -XDrawDiagnostics LocalFreeVarStaticInstantiate.java + */ + +class LocalFreeVarStaticInstantiate { + + // local class in method + static void foo(Object there) { + class Local { + { + there.hashCode(); + } + + static { + new Local(); // can't get there from here + } + + static Runnable r = () -> { + new Local(); // can't get there from here + }; + } + } + + // local class in lambda + static Runnable foo = () -> { + Object there = ""; + class Local { + { + there.hashCode(); + } + + static { + new Local(); // can't get there from here + } + + static Runnable r = () -> { + new Local(); // can't get there from here + }; + } + }; +} diff --git a/test/langtools/tools/javac/LocalFreeVarStaticInstantiate.out b/test/langtools/tools/javac/LocalFreeVarStaticInstantiate.out new file mode 100644 index 00000000000..50e913083b0 --- /dev/null +++ b/test/langtools/tools/javac/LocalFreeVarStaticInstantiate.out @@ -0,0 +1,5 @@ +LocalFreeVarStaticInstantiate.java:18:17: compiler.err.local.cant.be.inst.static: kindname.class, Local +LocalFreeVarStaticInstantiate.java:22:17: compiler.err.local.cant.be.inst.static: kindname.class, Local +LocalFreeVarStaticInstantiate.java:36:17: compiler.err.local.cant.be.inst.static: kindname.class, Local +LocalFreeVarStaticInstantiate.java:40:17: compiler.err.local.cant.be.inst.static: kindname.class, Local +4 errors diff --git a/test/langtools/tools/javac/QualifiedAccess/QualifiedAccess_2.java b/test/langtools/tools/javac/QualifiedAccess/QualifiedAccess_2.java index de36f070766..d16c8194a53 100644 --- a/test/langtools/tools/javac/QualifiedAccess/QualifiedAccess_2.java +++ b/test/langtools/tools/javac/QualifiedAccess/QualifiedAccess_2.java @@ -7,7 +7,7 @@ * * @compile pack1/P1.java * @compile pack1/P2.java - * @compile/fail/ref=QualifiedAccess_2.out -XDrawDiagnostics QualifiedAccess_2.java + * @compile/fail/ref=QualifiedAccess_2.out -XDdev -XDrawDiagnostics QualifiedAccess_2.java */ import pack1.P1; diff --git a/test/langtools/tools/javac/SuperInit/EarlyIndirectOuterCapture.java b/test/langtools/tools/javac/SuperInit/EarlyIndirectOuterCapture.java new file mode 100644 index 00000000000..9336c4dc183 --- /dev/null +++ b/test/langtools/tools/javac/SuperInit/EarlyIndirectOuterCapture.java @@ -0,0 +1,29 @@ +/* + * @test /nodynamiccopyright/ + * @bug 8334248 + * @summary Invalid error for early construction local class constructor method reference + * @compile/fail/ref=EarlyIndirectOuterCapture.out -XDrawDiagnostics EarlyIndirectOuterCapture.java + */ + +public class EarlyIndirectOuterCapture { + + EarlyIndirectOuterCapture() { + this(null); + } + + EarlyIndirectOuterCapture(InnerSuperclass inner) { } + + class InnerSuperclass { } + + static class InnerOuter extends EarlyIndirectOuterCapture { // accessible + class InnerInnerOuter extends EarlyIndirectOuterCapture { // not accessible + InnerInnerOuter() { + super(/* which enclosing instance here ? */new InnerSuperclass() { }); + } + + InnerInnerOuter(boolean b) { + super(InnerOuter.this.new InnerSuperclass() { }); // ok, explicit + } + } + } +} diff --git a/test/langtools/tools/javac/SuperInit/EarlyIndirectOuterCapture.out b/test/langtools/tools/javac/SuperInit/EarlyIndirectOuterCapture.out new file mode 100644 index 00000000000..7b96671a2bd --- /dev/null +++ b/test/langtools/tools/javac/SuperInit/EarlyIndirectOuterCapture.out @@ -0,0 +1,2 @@ +EarlyIndirectOuterCapture.java:21:60: compiler.err.cant.ref.before.ctor.called: this +1 error diff --git a/test/langtools/tools/javac/SuperInit/EarlyLocalCtorRef.java b/test/langtools/tools/javac/SuperInit/EarlyLocalCtorRef.java new file mode 100644 index 00000000000..3346d6ff4f7 --- /dev/null +++ b/test/langtools/tools/javac/SuperInit/EarlyLocalCtorRef.java @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +/* + * @test + * @bug 8334248 + * @summary Allow early construction local class constructor method references + * @enablePreview + */ + +import java.util.function.Supplier; + +public class EarlyLocalCtorRef { + + public EarlyLocalCtorRef() { + class InnerLocal { } + this(InnerLocal::new); + } + + public EarlyLocalCtorRef(Supplier s) { + } + + public static void main(String[] args) { + new EarlyLocalCtorRef(); + } +} diff --git a/test/langtools/tools/javac/SuperInit/EarlyLocalTest2.java b/test/langtools/tools/javac/SuperInit/EarlyLocalTest2.java new file mode 100644 index 00000000000..ba90f06dc5e --- /dev/null +++ b/test/langtools/tools/javac/SuperInit/EarlyLocalTest2.java @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +/* + * @test + * @bug 8333313 + * @summary Verify references to local classes declared in early construction contexts + * @enablePreview + */ +public class EarlyLocalTest2 { + + class Test { + Test() { + class InnerLocal { } + Runnable r = () -> new InnerLocal() { }; + r.run(); + super(); + } + } + + public static void main(String[] args) { + new EarlyLocalTest2().new Test(); + } +} diff --git a/test/langtools/tools/javac/SuperInit/EarlyLocalTest3.java b/test/langtools/tools/javac/SuperInit/EarlyLocalTest3.java new file mode 100644 index 00000000000..bf8d6faa099 --- /dev/null +++ b/test/langtools/tools/javac/SuperInit/EarlyLocalTest3.java @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +/* + * @test + * @bug 8333313 + * @summary Verify references to local classes declared in early construction contexts + * @enablePreview + */ +public class EarlyLocalTest3 { + + class Test { + Test() { + class InnerLocal { } + Runnable r = InnerLocal::new; + r.run(); + super(); + } + } + + public static void main(String[] args) { + new EarlyLocalTest3().new Test(); + } +} diff --git a/test/langtools/tools/javac/SuperInit/EarlyLocalTest8.java b/test/langtools/tools/javac/SuperInit/EarlyLocalTest8.java new file mode 100644 index 00000000000..806903e9017 --- /dev/null +++ b/test/langtools/tools/javac/SuperInit/EarlyLocalTest8.java @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +/* + * @test + * @bug 8333313 + * @summary Verify references to local classes declared in early construction contexts + * @enablePreview + */ +import java.util.concurrent.atomic.AtomicReference; + +public class EarlyLocalTest8 { + + class Test extends AtomicReference { + Test(int x) { + super( + switch (x) { + case 0 -> null; + default -> { + class InnerLocal { } + yield () -> new InnerLocal() { { System.out.println(EarlyLocalTest8.this); } }; + } + }); + } + } + + public static void main(String[] args) { + new EarlyLocalTest8().new Test(42); + } +} diff --git a/test/langtools/tools/javac/diags/examples/CantAccessInnerClsConstr.java b/test/langtools/tools/javac/diags/examples/LocalClassCantBeInstStatic.java similarity index 72% rename from test/langtools/tools/javac/diags/examples/CantAccessInnerClsConstr.java rename to test/langtools/tools/javac/diags/examples/LocalClassCantBeInstStatic.java index 112862cd2ef..80301cbbb77 100644 --- a/test/langtools/tools/javac/diags/examples/CantAccessInnerClsConstr.java +++ b/test/langtools/tools/javac/diags/examples/LocalClassCantBeInstStatic.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,18 +21,18 @@ * questions. */ -// key: compiler.misc.cant.access.inner.cls.constr -// key: compiler.err.invalid.mref +// key: compiler.err.local.cant.be.inst.static -class CantAccessInnerClsConstructor { +class LocalClassCantBeInstStatic { + static void foo(Object there) { + class Local { + { + there.hashCode(); + } - interface SAM { - Outer m(); - } - - class Outer { } - - static void test() { - SAM s = Outer::new; + static { + new Local(); // can't get there from here + } + } } } diff --git a/test/langtools/tools/javac/lambda/MethodReference23.out b/test/langtools/tools/javac/lambda/MethodReference23.out index 456a002bd99..6f7e1c5c909 100644 --- a/test/langtools/tools/javac/lambda/MethodReference23.out +++ b/test/langtools/tools/javac/lambda/MethodReference23.out @@ -1,6 +1,6 @@ -MethodReference23.java:52:19: compiler.err.invalid.mref: kindname.constructor, (compiler.misc.cant.access.inner.cls.constr: Inner1, MethodReference23, MethodReference23) -MethodReference23.java:53:16: compiler.err.invalid.mref: kindname.constructor, (compiler.misc.cant.access.inner.cls.constr: Inner1, MethodReference23, MethodReference23) -MethodReference23.java:57:19: compiler.err.invalid.mref: kindname.constructor, (compiler.misc.cant.access.inner.cls.constr: Inner1, , MethodReference23) -MethodReference23.java:58:16: compiler.err.invalid.mref: kindname.constructor, (compiler.misc.cant.access.inner.cls.constr: Inner1, , MethodReference23) +MethodReference23.java:52:19: compiler.err.non-static.cant.be.ref: kindname.variable, this +MethodReference23.java:53:16: compiler.err.non-static.cant.be.ref: kindname.variable, this +MethodReference23.java:57:19: compiler.err.non-static.cant.be.ref: kindname.variable, this +MethodReference23.java:58:16: compiler.err.non-static.cant.be.ref: kindname.variable, this MethodReference23.java:72:9: compiler.err.ref.ambiguous: call3, kindname.method, call3(MethodReference23.SAM21), MethodReference23, kindname.method, call3(MethodReference23.SAM22), MethodReference23 5 errors diff --git a/test/langtools/tools/javac/lambda/MethodReference37.out b/test/langtools/tools/javac/lambda/MethodReference37.out index 8db8e456daf..09dc966bd4a 100644 --- a/test/langtools/tools/javac/lambda/MethodReference37.out +++ b/test/langtools/tools/javac/lambda/MethodReference37.out @@ -1,5 +1,5 @@ MethodReference37.java:24:38: compiler.err.prob.found.req: (compiler.misc.invalid.mref: kindname.constructor, (compiler.misc.cant.apply.symbol: kindname.constructor, Inner, compiler.misc.no.args, MethodReference37.Outer, kindname.class, MethodReference37.Outer.Inner, (compiler.misc.arg.length.mismatch))) MethodReference37.java:29:39: compiler.err.prob.found.req: (compiler.misc.invalid.mref: kindname.constructor, (compiler.misc.cant.apply.symbol: kindname.constructor, Inner, compiler.misc.no.args, MethodReference37.Outer, kindname.class, MethodReference37.Outer.Inner, (compiler.misc.arg.length.mismatch))) -MethodReference37.java:34:40: compiler.err.invalid.mref: kindname.constructor, (compiler.misc.cant.access.inner.cls.constr: Inner, MethodReference37.Outer, MethodReference37.Outer) -MethodReference37.java:38:41: compiler.err.invalid.mref: kindname.constructor, (compiler.misc.cant.access.inner.cls.constr: Inner, MethodReference37.Outer, MethodReference37.Outer) +MethodReference37.java:34:40: compiler.err.prob.found.req: (compiler.misc.invalid.mref: kindname.constructor, (compiler.misc.cant.apply.symbol: kindname.constructor, Inner, compiler.misc.no.args, MethodReference37.Outer, kindname.class, MethodReference37.Outer.Inner, (compiler.misc.arg.length.mismatch))) +MethodReference37.java:38:41: compiler.err.prob.found.req: (compiler.misc.invalid.mref: kindname.constructor, (compiler.misc.cant.apply.symbol: kindname.constructor, Inner, compiler.misc.no.args, MethodReference37.Outer, kindname.class, MethodReference37.Outer.Inner, (compiler.misc.arg.length.mismatch))) 4 errors diff --git a/test/langtools/tools/javac/lambda/MethodReferenceNoThisTest.out b/test/langtools/tools/javac/lambda/MethodReferenceNoThisTest.out index 2dff751f68d..a411c340484 100644 --- a/test/langtools/tools/javac/lambda/MethodReferenceNoThisTest.out +++ b/test/langtools/tools/javac/lambda/MethodReferenceNoThisTest.out @@ -1,2 +1,2 @@ MethodReferenceNoThisTest.java:22:15: compiler.err.cant.ref.before.ctor.called: this -1 error \ No newline at end of file +1 error diff --git a/test/langtools/tools/javac/lambda/methodReference/MethodRefToInnerWithoutOuter.out b/test/langtools/tools/javac/lambda/methodReference/MethodRefToInnerWithoutOuter.out index 03b3d338369..66c50ed315b 100644 --- a/test/langtools/tools/javac/lambda/methodReference/MethodRefToInnerWithoutOuter.out +++ b/test/langtools/tools/javac/lambda/methodReference/MethodRefToInnerWithoutOuter.out @@ -1,2 +1,2 @@ -MethodRefToInnerWithoutOuter.java:22:31: compiler.err.invalid.mref: kindname.constructor, (compiler.misc.cant.access.inner.cls.constr: TestString, java.lang.String, MethodRefToInnerBase) +MethodRefToInnerWithoutOuter.java:22:31: compiler.err.non-static.cant.be.ref: kindname.variable, this 1 error From 3eece6e941035e091e8ece7dd44a1837417c9b87 Mon Sep 17 00:00:00 2001 From: Pavel Rappo Date: Fri, 15 Nov 2024 10:20:08 +0000 Subject: [PATCH 010/311] 8341907: javac -Xlint should ignore /// on first line of source file Reviewed-by: jjg --- .../com/sun/tools/javac/code/Lint.java | 2 +- .../sun/tools/javac/parser/JavacParser.java | 11 ++++- .../danglingDocComments/JBangException1.java | 19 +++++++++ .../JBangException2.enabled.out | 2 + .../danglingDocComments/JBangException2.java | 19 +++++++++ .../JBangException3.enabled.out | 2 + .../danglingDocComments/JBangException3.java | 22 ++++++++++ .../JBangExceptionTest.java | 40 +++++++++++++++++++ 8 files changed, 115 insertions(+), 2 deletions(-) create mode 100644 test/langtools/tools/javac/danglingDocComments/JBangException1.java create mode 100644 test/langtools/tools/javac/danglingDocComments/JBangException2.enabled.out create mode 100644 test/langtools/tools/javac/danglingDocComments/JBangException2.java create mode 100644 test/langtools/tools/javac/danglingDocComments/JBangException3.enabled.out create mode 100644 test/langtools/tools/javac/danglingDocComments/JBangException3.java create mode 100644 test/langtools/tools/javac/danglingDocComments/JBangExceptionTest.java diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Lint.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Lint.java index d024dc75225..622c13d8b47 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Lint.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Lint.java @@ -181,7 +181,7 @@ public enum LintCategory { CLASSFILE("classfile"), /** - * Warn about"dangling" documentation comments, + * Warn about "dangling" documentation comments, * not attached to any declaration. */ DANGLING_DOC_COMMENTS("dangling-doc-comments"), diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/JavacParser.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/JavacParser.java index a93f5a9a794..0bbcd56293f 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/JavacParser.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/JavacParser.java @@ -667,7 +667,8 @@ void reportDanglingDocComment(Comment c) { var pos = c.getPos(); if (pos != null) { deferredLintHandler.report(lint -> { - if (lint.isEnabled(Lint.LintCategory.DANGLING_DOC_COMMENTS)) { + if (lint.isEnabled(Lint.LintCategory.DANGLING_DOC_COMMENTS) && + !shebang(c, pos)) { log.warning(Lint.LintCategory.DANGLING_DOC_COMMENTS, pos, Warnings.DanglingDocComment); } @@ -675,6 +676,14 @@ void reportDanglingDocComment(Comment c) { } } + /** Returns true for a comment that acts similarly to shebang in UNIX */ + private boolean shebang(Comment c, JCDiagnostic.DiagnosticPosition pos) { + var src = log.currentSource(); + return c.getStyle() == Comment.CommentStyle.JAVADOC_LINE && + c.getPos().getStartPosition() == 0 && + src.getLineNumber(pos.getEndPosition(src.getEndPosTable())) == 1; + } + /** * Ignores any recent documentation comments found by the scanner, * such as those that cannot be associated with a nearby declaration. diff --git a/test/langtools/tools/javac/danglingDocComments/JBangException1.java b/test/langtools/tools/javac/danglingDocComments/JBangException1.java new file mode 100644 index 00000000000..123451aff7c --- /dev/null +++ b/test/langtools/tools/javac/danglingDocComments/JBangException1.java @@ -0,0 +1,19 @@ +///usr/bin/env jbang "$0" "$@" ; exit $? +// /nodynamiccopyright/ + +/** A class comment */ +public class JBangException1 { + + /** + * A method comment + * + * @param args a parameter comment + */ + public static void main(String[] args) { + if (args.length == 0) { + System.out.println("Hello World!"); + } else { + System.out.println("Hello " + args[0]); + } + } +} \ No newline at end of file diff --git a/test/langtools/tools/javac/danglingDocComments/JBangException2.enabled.out b/test/langtools/tools/javac/danglingDocComments/JBangException2.enabled.out new file mode 100644 index 00000000000..8934c449e3b --- /dev/null +++ b/test/langtools/tools/javac/danglingDocComments/JBangException2.enabled.out @@ -0,0 +1,2 @@ +JBangException2.java:1:1: compiler.warn.dangling.doc.comment +1 warning diff --git a/test/langtools/tools/javac/danglingDocComments/JBangException2.java b/test/langtools/tools/javac/danglingDocComments/JBangException2.java new file mode 100644 index 00000000000..1514542f3fc --- /dev/null +++ b/test/langtools/tools/javac/danglingDocComments/JBangException2.java @@ -0,0 +1,19 @@ +/** /usr/bin/env jbang "$0" "$@" ; exit $? */ +// /nodynamiccopyright/ + +/** A class comment */ +public class JBangException2 { + + /** + * A method comment + * + * @param args a parameter comment + */ + public static void main(String[] args) { + if (args.length == 0) { + System.out.println("Hello World!"); + } else { + System.out.println("Hello " + args[0]); + } + } +} \ No newline at end of file diff --git a/test/langtools/tools/javac/danglingDocComments/JBangException3.enabled.out b/test/langtools/tools/javac/danglingDocComments/JBangException3.enabled.out new file mode 100644 index 00000000000..9b08300a7c0 --- /dev/null +++ b/test/langtools/tools/javac/danglingDocComments/JBangException3.enabled.out @@ -0,0 +1,2 @@ +JBangException3.java:1:1: compiler.warn.dangling.doc.comment +1 warning diff --git a/test/langtools/tools/javac/danglingDocComments/JBangException3.java b/test/langtools/tools/javac/danglingDocComments/JBangException3.java new file mode 100644 index 00000000000..9e14dfc0b55 --- /dev/null +++ b/test/langtools/tools/javac/danglingDocComments/JBangException3.java @@ -0,0 +1,22 @@ +/// A +/// multiline +/// dangling +/// comment +// /nodynamiccopyright/ + +/** A class comment */ +public class JBangException3 { + + /** + * A method comment + * + * @param args a parameter comment + */ + public static void main(String[] args) { + if (args.length == 0) { + System.out.println("Hello World!"); + } else { + System.out.println("Hello " + args[0]); + } + } +} \ No newline at end of file diff --git a/test/langtools/tools/javac/danglingDocComments/JBangExceptionTest.java b/test/langtools/tools/javac/danglingDocComments/JBangExceptionTest.java new file mode 100644 index 00000000000..4308335f4c5 --- /dev/null +++ b/test/langtools/tools/javac/danglingDocComments/JBangExceptionTest.java @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * + * @compile/ref=empty.out -XDrawDiagnostics JBangException1.java + * @compile/ref=empty.out -XDrawDiagnostics -Xlint:dangling-doc-comments JBangException1.java + * + * @compile/ref=empty.out -XDrawDiagnostics JBangException2.java + * @compile/ref=JBangException2.enabled.out -XDrawDiagnostics -Xlint:dangling-doc-comments JBangException2.java + * + * @compile/ref=empty.out -XDrawDiagnostics JBangException3.java + * @compile/ref=JBangException3.enabled.out -XDrawDiagnostics -Xlint:dangling-doc-comments JBangException3.java + */ + +// The classes being tested reside in files separate from this one because +// the classes need to provide the initial dangling comment, which would +// otherwise interfere with the JTReg test comment. For similar reasons, +// the files with test classes do __NOT__ have a copyright header. From 75c651f859c1372175040a06c68a08298d4da0f1 Mon Sep 17 00:00:00 2001 From: Casper Norrbin Date: Fri, 15 Nov 2024 11:28:02 +0000 Subject: [PATCH 011/311] 8327156: Avoid copying in StringTable::intern(oop, TRAPS) 8326865: Avoid copying in StringTable::intern(Symbol*, TRAPS) 8327825: StringTable::intern is slow Reviewed-by: dholmes, coleenp, jsjolen --- src/hotspot/share/classfile/javaClasses.cpp | 35 ++- src/hotspot/share/classfile/javaClasses.hpp | 17 +- src/hotspot/share/classfile/stringTable.cpp | 294 +++++++++++++----- src/hotspot/share/classfile/stringTable.hpp | 22 +- .../gtest/classfile/test_stringConversion.cpp | 194 ++++++++++++ .../gtest/classfile/test_stringIntern.cpp | 71 +++++ 6 files changed, 548 insertions(+), 85 deletions(-) create mode 100644 test/hotspot/gtest/classfile/test_stringConversion.cpp create mode 100644 test/hotspot/gtest/classfile/test_stringIntern.cpp diff --git a/src/hotspot/share/classfile/javaClasses.cpp b/src/hotspot/share/classfile/javaClasses.cpp index 0dd183e06d4..e17de0f2264 100644 --- a/src/hotspot/share/classfile/javaClasses.cpp +++ b/src/hotspot/share/classfile/javaClasses.cpp @@ -347,7 +347,7 @@ Handle java_lang_String::create_from_str(const char* utf8_str, TRAPS) { #ifdef ASSERT // This check is too strict when the input string is not a valid UTF8. // For example, it may be created with arbitrary content via jni_NewStringUTF. - if (UTF8::is_legal_utf8((const unsigned char*)utf8_str, strlen(utf8_str), false)) { + if (UTF8::is_legal_utf8((const unsigned char*)utf8_str, strlen(utf8_str), /*version_leq_47*/false)) { ResourceMark rm; const char* expected = utf8_str; char* actual = as_utf8_string(h_obj()); @@ -365,7 +365,7 @@ oop java_lang_String::create_oop_from_str(const char* utf8_str, TRAPS) { return h_obj(); } -Handle java_lang_String::create_from_symbol(Symbol* symbol, TRAPS) { +Handle java_lang_String::create_from_symbol(const Symbol* symbol, TRAPS) { const char* utf8_str = (char*)symbol->bytes(); int utf8_len = symbol->utf8_length(); @@ -389,6 +389,8 @@ Handle java_lang_String::create_from_symbol(Symbol* symbol, TRAPS) { } #ifdef ASSERT + // This check is too strict on older classfile versions + if (UTF8::is_legal_utf8((const unsigned char*)utf8_str, utf8_len, /*version_leq_47*/false)) { ResourceMark rm; const char* expected = symbol->as_utf8(); @@ -755,6 +757,35 @@ bool java_lang_String::equals(oop java_string, const jchar* chars, int len) { return true; } +bool java_lang_String::equals(oop java_string, const char* utf8_string, size_t utf8_len) { + assert(java_string->klass() == vmClasses::String_klass(), + "must be java_string"); + typeArrayOop value = java_lang_String::value_no_keepalive(java_string); + int length = java_lang_String::length(java_string, value); + int unicode_length = UTF8::unicode_length(utf8_string, utf8_len); + if (length != unicode_length) { + return false; + } + bool is_latin1 = java_lang_String::is_latin1(java_string); + jchar c; + if (!is_latin1) { + for (int i = 0; i < unicode_length; i++) { + utf8_string = UTF8::next(utf8_string, &c); + if (value->char_at(i) != c) { + return false; + } + } + } else { + for (int i = 0; i < unicode_length; i++) { + utf8_string = UTF8::next(utf8_string, &c); + if ((((jchar) value->byte_at(i)) & 0xff) != c) { + return false; + } + } + } + return true; +} + bool java_lang_String::equals(oop str1, oop str2) { assert(str1->klass() == vmClasses::String_klass(), "must be java String"); diff --git a/src/hotspot/share/classfile/javaClasses.hpp b/src/hotspot/share/classfile/javaClasses.hpp index e0123595810..a2e6ad7349c 100644 --- a/src/hotspot/share/classfile/javaClasses.hpp +++ b/src/hotspot/share/classfile/javaClasses.hpp @@ -32,6 +32,7 @@ #include "runtime/handles.hpp" #include "runtime/os.hpp" #include "utilities/macros.hpp" +#include "utilities/utf8.hpp" #include "utilities/vmEnums.hpp" class JvmtiThreadState; @@ -99,7 +100,7 @@ class java_lang_String : AllStatic { static oop create_oop_from_unicode(const jchar* unicode, int len, TRAPS); static Handle create_from_str(const char* utf8_str, TRAPS); static oop create_oop_from_str(const char* utf8_str, TRAPS); - static Handle create_from_symbol(Symbol* symbol, TRAPS); + static Handle create_from_symbol(const Symbol* symbol, TRAPS); static Handle create_from_platform_dependent_str(const char* str, TRAPS); static void set_compact_strings(bool value); @@ -180,10 +181,24 @@ class java_lang_String : AllStatic { return h; } + static unsigned int hash_code(const char* utf8_str, size_t utf8_len) { + unsigned int h = 0; + int unicode_length = UTF8::unicode_length(utf8_str, utf8_len); + + jchar c; + while (unicode_length-- > 0) { + utf8_str = UTF8::next(utf8_str, &c); + h = 31 * h + ((unsigned int)c); + } + return h; + } + static unsigned int hash_code(oop java_string); static unsigned int hash_code_noupdate(oop java_string); + // Compare strings (of different types/encodings), length is the string (array) length static bool equals(oop java_string, const jchar* chars, int len); + static bool equals(oop java_string, const char* utf8_str, size_t utf8_len); static bool equals(oop str1, oop str2); static inline bool value_equals(typeArrayOop str_value1, typeArrayOop str_value2); diff --git a/src/hotspot/share/classfile/stringTable.cpp b/src/hotspot/share/classfile/stringTable.cpp index 3a6cf166ff5..4de4b8e333c 100644 --- a/src/hotspot/share/classfile/stringTable.cpp +++ b/src/hotspot/share/classfile/stringTable.cpp @@ -99,9 +99,9 @@ inline oop StringTable::read_string_from_compact_hashtable(address base_address, } typedef CompactHashtable< - const jchar*, oop, + const StringTable::StringWrapper&, oop, StringTable::read_string_from_compact_hashtable, - java_lang_String::equals> SharedStringTable; + StringTable::wrapped_string_equals> SharedStringTable; static SharedStringTable _shared_table; #endif @@ -123,12 +123,69 @@ volatile bool _alt_hash = false; static bool _rehashed = false; static uint64_t _alt_hash_seed = 0; +enum class StringType { + OopStr, UnicodeStr, SymbolStr, UTF8Str +}; + +struct StringWrapperInternal { + union { + const Handle oop_str; + const jchar* unicode_str; + const Symbol* symbol_str; + const char* utf8_str; + }; + const StringType type; + const size_t length; + + StringWrapperInternal(const Handle oop_str, const size_t length) : oop_str(oop_str), type(StringType::OopStr), length(length) {} + StringWrapperInternal(const jchar* unicode_str, const size_t length) : unicode_str(unicode_str), type(StringType::UnicodeStr), length(length) {} + StringWrapperInternal(const Symbol* symbol_str, const size_t length) : symbol_str(symbol_str), type(StringType::SymbolStr), length(length) {} + StringWrapperInternal(const char* utf8_str, const size_t length) : utf8_str(utf8_str), type(StringType::UTF8Str), length(length) {} +}; + static unsigned int hash_string(const jchar* s, int len, bool useAlt) { return useAlt ? AltHashing::halfsiphash_32(_alt_hash_seed, s, len) : java_lang_String::hash_code(s, len); } +const char* StringTable::get_symbol_utf8(const StringWrapper& symbol) { + return reinterpret_cast(symbol.symbol_str->bytes()); +} + +unsigned int StringTable::hash_wrapped_string(const StringWrapper& wrapped_str) { + switch (wrapped_str.type) { + case StringType::OopStr: + return java_lang_String::hash_code(wrapped_str.oop_str()); + case StringType::UnicodeStr: + return java_lang_String::hash_code(wrapped_str.unicode_str, static_cast(wrapped_str.length)); + case StringType::SymbolStr: + return java_lang_String::hash_code(get_symbol_utf8(wrapped_str), wrapped_str.length); + case StringType::UTF8Str: + return java_lang_String::hash_code(wrapped_str.utf8_str, wrapped_str.length); + default: + ShouldNotReachHere(); + } + return 0; +} + +// Unnamed int needed to fit CompactHashtable's equals type signature +bool StringTable::wrapped_string_equals(oop java_string, const StringWrapper& wrapped_str, int) { + switch (wrapped_str.type) { + case StringType::OopStr: + return java_lang_String::equals(java_string, wrapped_str.oop_str()); + case StringType::UnicodeStr: + return java_lang_String::equals(java_string, wrapped_str.unicode_str, static_cast(wrapped_str.length)); + case StringType::SymbolStr: + return java_lang_String::equals(java_string, get_symbol_utf8(wrapped_str), wrapped_str.length); + case StringType::UTF8Str: + return java_lang_String::equals(java_string, wrapped_str.utf8_str, wrapped_str.length); + default: + ShouldNotReachHere(); + } + return false; +} + class StringTableConfig : public StackObj { private: public: @@ -163,22 +220,33 @@ class StringTableConfig : public StackObj { } }; -class StringTableLookupJchar : StackObj { - private: - Thread* _thread; +class StringTableLookup : StackObj { uintx _hash; - int _len; - const jchar* _str; + +protected: + Thread* _thread; Handle _found; - public: - StringTableLookupJchar(Thread* thread, uintx hash, const jchar* key, int len) - : _thread(thread), _hash(hash), _len(len), _str(key) { - } - uintx get_hash() const { - return _hash; +public: + StringTableLookup(Thread* thread, uintx hash) + : _hash(hash), _thread(thread) {} + uintx get_hash() const { return _hash; } + bool is_dead(WeakHandle* value) { + oop val_oop = value->peek(); + return val_oop == nullptr; } - bool equals(WeakHandle* value) { +}; + +class StringTableLookupUnicode : public StringTableLookup { +private: + const jchar* _str; + int _len; + +public: + StringTableLookupUnicode(Thread* thread, uintx hash, const jchar* key, int len) + : StringTableLookup(thread, hash), _str(key), _len(len) {} + + bool equals(const WeakHandle* value) { oop val_oop = value->peek(); if (val_oop == nullptr) { return false; @@ -188,29 +256,42 @@ class StringTableLookupJchar : StackObj { return false; } // Need to resolve weak handle and Handleize through possible safepoint. - _found = Handle(_thread, value->resolve()); + _found = Handle(_thread, value->resolve()); return true; } - bool is_dead(WeakHandle* value) { +}; + +class StringTableLookupUTF8 : public StringTableLookup { +private: + const char* _str; + size_t _utf8_len; + +public: + StringTableLookupUTF8(Thread* thread, uintx hash, const char* key, size_t utf8_len) + : StringTableLookup(thread, hash), _str(key), _utf8_len(utf8_len) {} + + bool equals(const WeakHandle* value) { oop val_oop = value->peek(); - return val_oop == nullptr; + if (val_oop == nullptr) { + return false; + } + bool equals = java_lang_String::equals(val_oop, _str, _utf8_len); + if (!equals) { + return false; + } + // Need to resolve weak handle and Handleize through possible safepoint. + _found = Handle(_thread, value->resolve()); + return true; } }; -class StringTableLookupOop : public StackObj { - private: - Thread* _thread; - uintx _hash; +class StringTableLookupOop : public StringTableLookup { +private: Handle _find; - Handle _found; // Might be a different oop with the same value that's already - // in the table, which is the point. - public: - StringTableLookupOop(Thread* thread, uintx hash, Handle handle) - : _thread(thread), _hash(hash), _find(handle) { } - uintx get_hash() const { - return _hash; - } +public: + StringTableLookupOop(Thread* thread, uintx hash, Handle handle) + : StringTableLookup(thread, hash), _find(handle) {} bool equals(WeakHandle* value) { oop val_oop = value->peek(); @@ -225,11 +306,6 @@ class StringTableLookupOop : public StackObj { _found = Handle(_thread, value->resolve()); return true; } - - bool is_dead(WeakHandle* value) { - oop val_oop = value->peek(); - return val_oop == nullptr; - } }; void StringTable::create_table() { @@ -291,14 +367,15 @@ oop StringTable::lookup(Symbol* symbol) { oop StringTable::lookup(const jchar* name, int len) { unsigned int hash = java_lang_String::hash_code(name, len); - oop string = lookup_shared(name, len, hash); + StringWrapper wrapped_name(name, len); + oop string = lookup_shared(wrapped_name, hash); if (string != nullptr) { return string; } if (_alt_hash) { hash = hash_string(name, len, true); } - return do_lookup(name, len, hash); + return do_lookup(wrapped_name, hash); } class StringTableGet : public StackObj { @@ -323,80 +400,140 @@ void StringTable::update_needs_rehash(bool rehash) { } } -oop StringTable::do_lookup(const jchar* name, int len, uintx hash) { +oop StringTable::do_lookup(const StringWrapper& name, uintx hash) { Thread* thread = Thread::current(); - StringTableLookupJchar lookup(thread, hash, name, len); StringTableGet stg(thread); bool rehash_warning; - _local_table->get(thread, lookup, stg, &rehash_warning); + + switch (name.type) { + case StringType::OopStr: { + StringTableLookupOop lookup(thread, hash, name.oop_str); + _local_table->get(thread, lookup, stg, &rehash_warning); + break; + } + case StringType::UnicodeStr: { + StringTableLookupUnicode lookup(thread, hash, name.unicode_str, static_cast(name.length)); + _local_table->get(thread, lookup, stg, &rehash_warning); + break; + } + case StringType::SymbolStr: { + StringTableLookupUTF8 lookup(thread, hash, get_symbol_utf8(name), name.length); + _local_table->get(thread, lookup, stg, &rehash_warning); + break; + } + case StringType::UTF8Str: { + StringTableLookupUTF8 lookup(thread, hash, name.utf8_str, name.length); + _local_table->get(thread, lookup, stg, &rehash_warning); + break; + } + default: + ShouldNotReachHere(); + } + update_needs_rehash(rehash_warning); return stg.get_res_oop(); } +// Converts and allocates to a unicode string and stores the unicode length in len +const jchar* StringTable::to_unicode(const StringWrapper& wrapped_str, int &len, TRAPS) { + switch (wrapped_str.type) { + case StringType::UnicodeStr: + len = static_cast(wrapped_str.length); + return wrapped_str.unicode_str; + case StringType::OopStr: + return java_lang_String::as_unicode_string(wrapped_str.oop_str(), len, CHECK_NULL); + case StringType::SymbolStr: { + const char* utf8_str = get_symbol_utf8(wrapped_str); + int unicode_length = UTF8::unicode_length(utf8_str, wrapped_str.symbol_str->utf8_length()); + jchar* chars = NEW_RESOURCE_ARRAY(jchar, unicode_length); + UTF8::convert_to_unicode(utf8_str, chars, unicode_length); + len = unicode_length; + return chars; + } + case StringType::UTF8Str: { + int unicode_length = UTF8::unicode_length(wrapped_str.utf8_str); + jchar* chars = NEW_RESOURCE_ARRAY(jchar, unicode_length); + UTF8::convert_to_unicode(wrapped_str.utf8_str, chars, unicode_length); + len = unicode_length; + return chars; + } + default: + ShouldNotReachHere(); + } + return nullptr; +} + +Handle StringTable::handle_from_wrapped_string(const StringWrapper& wrapped_str, TRAPS) { + switch (wrapped_str.type) { + case StringType::OopStr: + return wrapped_str.oop_str; + case StringType::UnicodeStr: + return java_lang_String::create_from_unicode(wrapped_str.unicode_str, static_cast(wrapped_str.length), THREAD); + case StringType::SymbolStr: + return java_lang_String::create_from_symbol(wrapped_str.symbol_str, THREAD); + case StringType::UTF8Str: + return java_lang_String::create_from_str(wrapped_str.utf8_str, THREAD); + default: + ShouldNotReachHere(); + } + return Handle(); +} + // Interning oop StringTable::intern(Symbol* symbol, TRAPS) { if (symbol == nullptr) return nullptr; - ResourceMark rm(THREAD); - int length; - jchar* chars = symbol->as_unicode(length); - Handle string; - oop result = intern(string, chars, length, CHECK_NULL); + int length = symbol->utf8_length(); + StringWrapper name(symbol, length); + oop result = intern(name, CHECK_NULL); return result; } oop StringTable::intern(oop string, TRAPS) { if (string == nullptr) return nullptr; - ResourceMark rm(THREAD); - int length; + int length = java_lang_String::length(string); Handle h_string (THREAD, string); - jchar* chars = java_lang_String::as_unicode_string(string, length, - CHECK_NULL); - oop result = intern(h_string, chars, length, CHECK_NULL); + StringWrapper name(h_string, length); + oop result = intern(name, CHECK_NULL); return result; } oop StringTable::intern(const char* utf8_string, TRAPS) { if (utf8_string == nullptr) return nullptr; - ResourceMark rm(THREAD); - int length = UTF8::unicode_length(utf8_string); - jchar* chars = NEW_RESOURCE_ARRAY(jchar, length); - UTF8::convert_to_unicode(utf8_string, chars, length); - Handle string; - oop result = intern(string, chars, length, CHECK_NULL); + size_t length = strlen(utf8_string); + StringWrapper name(utf8_string, length); + oop result = intern(name, CHECK_NULL); return result; } -oop StringTable::intern(Handle string_or_null_h, const jchar* name, int len, TRAPS) { +oop StringTable::intern(const StringWrapper& name, TRAPS) { // shared table always uses java_lang_String::hash_code - unsigned int hash = java_lang_String::hash_code(name, len); - oop found_string = lookup_shared(name, len, hash); + unsigned int hash = hash_wrapped_string(name); + oop found_string = lookup_shared(name, hash); if (found_string != nullptr) { return found_string; } + if (_alt_hash) { - hash = hash_string(name, len, true); + ResourceMark rm(THREAD); + // Convert to unicode for alt hashing + int unicode_length; + const jchar* chars = to_unicode(name, unicode_length, CHECK_NULL); + hash = hash_string(chars, unicode_length, true); } - found_string = do_lookup(name, len, hash); + + found_string = do_lookup(name, hash); if (found_string != nullptr) { return found_string; } - return do_intern(string_or_null_h, name, len, hash, THREAD); + return do_intern(name, hash, THREAD); } -oop StringTable::do_intern(Handle string_or_null_h, const jchar* name, - int len, uintx hash, TRAPS) { +oop StringTable::do_intern(const StringWrapper& name, uintx hash, TRAPS) { HandleMark hm(THREAD); // cleanup strings created - Handle string_h; - - if (!string_or_null_h.is_null()) { - string_h = string_or_null_h; - } else { - string_h = java_lang_String::create_from_unicode(name, len, CHECK_NULL); - } + Handle string_h = handle_from_wrapped_string(name, CHECK_NULL); - assert(java_lang_String::equals(string_h(), name, len), + assert(StringTable::wrapped_string_equals(string_h(), name), "string must be properly initialized"); - assert(len == java_lang_String::length(string_h()), "Must be same length"); // Notify deduplication support that the string is being interned. A string // must never be deduplicated after it has been interned. Doing so interferes @@ -410,7 +547,7 @@ oop StringTable::do_intern(Handle string_or_null_h, const jchar* name, bool rehash_warning; do { - // Callers have already looked up the String using the jchar* name, so just go to add. + // Callers have already looked up the String, so just go to add. WeakHandle wh(_oop_storage, string_h); // The hash table takes ownership of the WeakHandle, even if it's not inserted. if (_local_table->insert(THREAD, lookup, wh, &rehash_warning)) { @@ -775,14 +912,17 @@ size_t StringTable::shared_entry_count() { return _shared_table.entry_count(); } -oop StringTable::lookup_shared(const jchar* name, int len, unsigned int hash) { - assert(hash == java_lang_String::hash_code(name, len), +oop StringTable::lookup_shared(const StringWrapper& name, unsigned int hash) { + assert(hash == hash_wrapped_string(name), "hash must be computed using java_lang_String::hash_code"); - return _shared_table.lookup(name, hash, len); + // len is required but is already part of StringWrapper, so 0 is used + return _shared_table.lookup(name, hash, 0); } oop StringTable::lookup_shared(const jchar* name, int len) { - return _shared_table.lookup(name, java_lang_String::hash_code(name, len), len); + StringWrapper wrapped_name(name, len); + // len is required but is already part of StringWrapper, so 0 is used + return _shared_table.lookup(wrapped_name, java_lang_String::hash_code(name, len), 0); } // This is called BEFORE we enter the CDS safepoint. We can allocate heap objects. diff --git a/src/hotspot/share/classfile/stringTable.hpp b/src/hotspot/share/classfile/stringTable.hpp index 9f49e797182..38abb9c875c 100644 --- a/src/hotspot/share/classfile/stringTable.hpp +++ b/src/hotspot/share/classfile/stringTable.hpp @@ -56,6 +56,18 @@ class StringTable : AllStatic { static double get_load_factor(); static double get_dead_factor(size_t num_dead); +public: + typedef struct StringWrapperInternal StringWrapper; + + // Unnamed int needed to fit CompactHashtable's equals type signature + static bool wrapped_string_equals(oop java_string, const StringWrapper& wrapped_str, int = 0); + +private: + static const char* get_symbol_utf8(const StringWrapper& symbol_str); + static unsigned int hash_wrapped_string(const StringWrapper& wrapped_str); + static const jchar* to_unicode(const StringWrapper& wrapped_str, int &len, TRAPS); + static Handle handle_from_wrapped_string(const StringWrapper& wrapped_str, TRAPS); + // GC support // Callback for GC to notify of changes that might require cleaning or resize. @@ -65,9 +77,9 @@ class StringTable : AllStatic { static void item_added(); static void item_removed(); - static oop intern(Handle string_or_null_h, const jchar* name, int len, TRAPS); - static oop do_intern(Handle string_or_null, const jchar* name, int len, uintx hash, TRAPS); - static oop do_lookup(const jchar* name, int len, uintx hash); + static oop intern(const StringWrapper& name, TRAPS); + static oop do_intern(const StringWrapper& name, uintx hash, TRAPS); + static oop do_lookup(const StringWrapper& name, uintx hash); static void print_table_statistics(outputStream* st); @@ -87,7 +99,7 @@ class StringTable : AllStatic { // Interning static oop intern(Symbol* symbol, TRAPS); static oop intern(oop string, TRAPS); - static oop intern(const char *utf8_string, TRAPS); + static oop intern(const char* utf8_string, TRAPS); // Rehash the string table if it gets out of balance private: @@ -131,7 +143,7 @@ class StringTable : AllStatic { #endif // INCLUDE_CDS_JAVA_HEAP private: - static oop lookup_shared(const jchar* name, int len, unsigned int hash) NOT_CDS_JAVA_HEAP_RETURN_(nullptr); + static oop lookup_shared(const StringWrapper& name, unsigned int hash) NOT_CDS_JAVA_HEAP_RETURN_(nullptr); public: static oop lookup_shared(const jchar* name, int len) NOT_CDS_JAVA_HEAP_RETURN_(nullptr); static size_t shared_entry_count() NOT_CDS_JAVA_HEAP_RETURN_(0); diff --git a/test/hotspot/gtest/classfile/test_stringConversion.cpp b/test/hotspot/gtest/classfile/test_stringConversion.cpp new file mode 100644 index 00000000000..13553464229 --- /dev/null +++ b/test/hotspot/gtest/classfile/test_stringConversion.cpp @@ -0,0 +1,194 @@ +/* + * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +#include "precompiled.hpp" +#include "runtime/interfaceSupport.inline.hpp" +#include "unittest.hpp" + +// Tests that string functions (hash code/equals) stay consistant when comparing equal strings and converting between strings types + +// Simple ASCII string "Java(R)!!" +// Same length in both UTF8 and Unicode +static const char static_ascii_utf8_str[] = {0x4A, 0x61, 0x76, 0x61, 0x28, 0x52, 0x29, 0x21, 0x21}; +static const jchar static_ascii_unicode_str[] = {0x004A, 0x0061, 0x0076, 0x0061, 0x0028, 0x0052, 0x0029, 0x0021, 0x0021}; + +// Complex string "Jāvá®!☺☻", UTF8 has character lengths 13122133 = 16 +static const unsigned char static_utf8_str[] = {0x4A, 0x61, 0xCC, 0x84, 0x76, 0xC3, 0xA1, 0xC2, 0xAE, 0x21, 0xE2, 0x98, 0xBA, 0xE2, 0x98, 0xBB}; +static const jchar static_unicode_str[] = { 0x004A, 0x0061, 0x0304, 0x0076, 0x00E1, 0x00AE, 0x0021, 0x263A, 0x263B}; + +static const int ASCII_LENGTH = 9; +static const size_t UTF8_LENGTH = 16; +static const int UNICODE_LENGTH = 9; + +void compare_utf8_utf8(const char* utf8_str1, const char* utf8_str2, size_t utf8_len) { + EXPECT_EQ(java_lang_String::hash_code(utf8_str1, utf8_len), java_lang_String::hash_code(utf8_str2, utf8_len)); + EXPECT_STREQ(utf8_str1, utf8_str2); +} + +void compare_utf8_unicode(const char* utf8_str, const jchar* unicode_str, size_t utf8_len, int unicode_len) { + EXPECT_EQ(java_lang_String::hash_code(utf8_str, utf8_len), java_lang_String::hash_code(unicode_str, unicode_len)); +} + +void compare_utf8_oop(const char* utf8_str, Handle oop_str, size_t utf8_len, int unicode_len) { + EXPECT_EQ(java_lang_String::hash_code(utf8_str, utf8_len), java_lang_String::hash_code(oop_str())); + EXPECT_TRUE(java_lang_String::equals(oop_str(), utf8_str, utf8_len)); +} + +void compare_unicode_unicode(const jchar* unicode_str1, const jchar* unicode_str2, int unicode_len) { + EXPECT_EQ(java_lang_String::hash_code(unicode_str1, unicode_len), java_lang_String::hash_code(unicode_str2, unicode_len)); + for (int i = 0; i < unicode_len; i++) { + EXPECT_EQ(unicode_str1[i], unicode_str2[i]); + } +} + +void compare_unicode_oop(const jchar* unicode_str, Handle oop_str, int unicode_len) { + EXPECT_EQ(java_lang_String::hash_code(unicode_str, unicode_len), java_lang_String::hash_code(oop_str())); + EXPECT_TRUE(java_lang_String::equals(oop_str(), unicode_str, unicode_len)); +} + +void compare_oop_oop(Handle oop_str1, Handle oop_str2) { + EXPECT_EQ(java_lang_String::hash_code(oop_str1()), java_lang_String::hash_code(oop_str2())); + EXPECT_TRUE(java_lang_String::equals(oop_str1(), oop_str2())); +} + +void test_utf8_convert(const char* utf8_str, size_t utf8_len, int unicode_len) { + EXPECT_TRUE(UTF8::is_legal_utf8((unsigned char*)utf8_str, strlen(utf8_str), false)); + + JavaThread* THREAD = JavaThread::current(); + ThreadInVMfromNative ThreadInVMfromNative(THREAD); + ResourceMark rm(THREAD); + HandleMark hm(THREAD); + + jchar* unicode_str_from_utf8 = NEW_RESOURCE_ARRAY(jchar, unicode_len); + UTF8::convert_to_unicode(utf8_str, unicode_str_from_utf8, unicode_len); + Handle oop_str_from_utf8 = java_lang_String::create_from_str(utf8_str, THREAD); + + compare_utf8_unicode(utf8_str, unicode_str_from_utf8, utf8_len, unicode_len); + compare_utf8_oop(utf8_str, oop_str_from_utf8, utf8_len, unicode_len); + + size_t length = unicode_len; + const char* utf8_str_from_unicode = UNICODE::as_utf8(unicode_str_from_utf8, length); + const char* utf8_str_from_oop = java_lang_String::as_utf8_string(oop_str_from_utf8()); + + EXPECT_TRUE(UTF8::is_legal_utf8((unsigned char*)utf8_str_from_unicode, strlen(utf8_str_from_unicode), false)); + EXPECT_TRUE(UTF8::is_legal_utf8((unsigned char*)utf8_str_from_oop, strlen(utf8_str_from_oop), false)); + + compare_utf8_utf8(utf8_str, utf8_str_from_unicode, utf8_len); + compare_utf8_utf8(utf8_str, utf8_str_from_oop, utf8_len); +} + +void test_unicode_convert(const jchar* unicode_str, size_t utf8_len, int unicode_len) { + JavaThread* THREAD = JavaThread::current(); + ThreadInVMfromNative ThreadInVMfromNative(THREAD); + ResourceMark rm(THREAD); + HandleMark hm(THREAD); + + size_t length = unicode_len; + const char* utf8_str_from_unicode = UNICODE::as_utf8(unicode_str, length); + Handle oop_str_from_unicode = java_lang_String::create_from_unicode(unicode_str, unicode_len, THREAD); + + EXPECT_TRUE(UTF8::is_legal_utf8((unsigned char*)utf8_str_from_unicode, strlen(utf8_str_from_unicode), false)); + + compare_utf8_unicode(utf8_str_from_unicode, unicode_str, utf8_len, unicode_len); + compare_unicode_oop(unicode_str, oop_str_from_unicode, unicode_len); + + int _; + jchar* unicode_str_from_utf8 = NEW_RESOURCE_ARRAY(jchar, unicode_len); + UTF8::convert_to_unicode(utf8_str_from_unicode, unicode_str_from_utf8, unicode_len); + const jchar* unicode_str_from_oop = java_lang_String::as_unicode_string(oop_str_from_unicode(), _, THREAD); + + compare_unicode_unicode(unicode_str, unicode_str_from_utf8, unicode_len); + compare_unicode_unicode(unicode_str, unicode_str_from_oop, unicode_len); +} + +void test_utf8_unicode_cross(const char* utf8_str, const jchar* unicode_str, size_t utf8_len, int unicode_len) { + compare_utf8_unicode(utf8_str, unicode_str, utf8_len, unicode_len); + + JavaThread* THREAD = JavaThread::current(); + ThreadInVMfromNative ThreadInVMfromNative(THREAD); + ResourceMark rm(THREAD); + HandleMark hm(THREAD); + + size_t length = unicode_len; + const char* utf8_str_from_unicode = UNICODE::as_utf8(unicode_str, length); + + jchar* unicode_str_from_utf8 = NEW_RESOURCE_ARRAY(jchar, unicode_len); + UTF8::convert_to_unicode(utf8_str, unicode_str_from_utf8, unicode_len); + + Handle oop_str_from_unicode = java_lang_String::create_from_unicode(unicode_str, unicode_len, THREAD); + Handle oop_str_from_utf8 = java_lang_String::create_from_str(utf8_str, THREAD); + + compare_utf8_utf8(utf8_str, utf8_str_from_unicode, utf8_len); + compare_utf8_oop(utf8_str, oop_str_from_unicode, utf8_len, unicode_len); + + compare_unicode_unicode(unicode_str, unicode_str_from_utf8, unicode_len); + compare_unicode_oop(unicode_str, oop_str_from_utf8, unicode_len); + + compare_utf8_oop(utf8_str_from_unicode, oop_str_from_utf8, utf8_len, unicode_len); + compare_unicode_oop(unicode_str_from_utf8, oop_str_from_unicode, unicode_len); + + compare_utf8_unicode(utf8_str_from_unicode, unicode_str_from_utf8, utf8_len, unicode_len); + compare_oop_oop(oop_str_from_utf8, oop_str_from_unicode); +} + +TEST_VM(StringConversion, fromUTF8_ascii) { + const char utf8_str[ASCII_LENGTH + 1] = { }; + memcpy((unsigned char*)utf8_str, static_ascii_utf8_str, ASCII_LENGTH); + test_utf8_convert(utf8_str, ASCII_LENGTH, ASCII_LENGTH); +} + +TEST_VM(StringConversion, fromUTF8_varlen) { + const char utf8_str[UTF8_LENGTH + 1] = { }; + memcpy((unsigned char*)utf8_str, static_utf8_str, UTF8_LENGTH); + test_utf8_convert(utf8_str, UTF8_LENGTH, UNICODE_LENGTH); +} + +TEST_VM(StringConversion, fromUnicode_ascii) { + jchar unicode_str[ASCII_LENGTH] = { }; + memcpy(unicode_str, static_ascii_unicode_str, ASCII_LENGTH * sizeof(jchar)); + test_unicode_convert(unicode_str, ASCII_LENGTH, ASCII_LENGTH); +} + +TEST_VM(StringConversion, fromUnicode_varlen) { + jchar unicode_str[UNICODE_LENGTH] = { }; + memcpy(unicode_str, static_unicode_str, UNICODE_LENGTH * sizeof(jchar)); + test_unicode_convert(unicode_str, UTF8_LENGTH, UNICODE_LENGTH); +} + +TEST_VM(StringConversion, cross_ascii) { + const char utf8_str[ASCII_LENGTH + 1] = { }; + jchar unicode_str[ASCII_LENGTH] = { }; + memcpy((unsigned char*)utf8_str, static_ascii_utf8_str, ASCII_LENGTH); + memcpy(unicode_str, static_ascii_unicode_str, ASCII_LENGTH * sizeof(jchar)); + + test_utf8_unicode_cross(utf8_str, unicode_str, ASCII_LENGTH, ASCII_LENGTH); +} + +TEST_VM(StringConversion, cross_varlen) { + const char utf8_str[UTF8_LENGTH + 1] = { }; + jchar unicode_str[UNICODE_LENGTH] = { }; + memcpy((unsigned char*)utf8_str, static_utf8_str, UTF8_LENGTH); + memcpy(unicode_str, static_unicode_str, UNICODE_LENGTH * sizeof(jchar)); + + test_utf8_unicode_cross(utf8_str, unicode_str, UTF8_LENGTH, UNICODE_LENGTH); +} diff --git a/test/hotspot/gtest/classfile/test_stringIntern.cpp b/test/hotspot/gtest/classfile/test_stringIntern.cpp new file mode 100644 index 00000000000..69c0a5b2aa4 --- /dev/null +++ b/test/hotspot/gtest/classfile/test_stringIntern.cpp @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +#include "precompiled.hpp" +#include "classfile/stringTable.hpp" +#include "classfile/symbolTable.hpp" +#include "runtime/interfaceSupport.inline.hpp" +#include "unittest.hpp" + +// Tests that strings are interned and returns the same string when interning from different string types + +// Simple ASCII string "Java(R)!!" +static const char static_ascii_utf8_str[] = {0x4A, 0x61, 0x76, 0x61, 0x28, 0x52, 0x29, 0x21, 0x21}; +static const size_t ASCII_LENGTH = 9; + +// Complex string "Jāvá®!☺☻", has character lengths 13122133 = 16 +static const unsigned char static_utf8_str[] = {0x4A, 0x61, 0xCC, 0x84, 0x76, 0xC3, 0xA1, 0xC2, 0xAE, 0x21, 0xE2, 0x98, 0xBA, 0xE2, 0x98, 0xBB}; +static const size_t COMPLEX_LENGTH = 16; + +void test_intern(const char* utf8_str, size_t utf8_length) { + JavaThread* THREAD = JavaThread::current(); + ThreadInVMfromNative ThreadInVMfromNative(THREAD); + HandleMark hm(THREAD); + + oop interned_string_from_utf8 = StringTable::intern(utf8_str, THREAD); + + EXPECT_TRUE(java_lang_String::equals(interned_string_from_utf8, utf8_str, utf8_length)); + EXPECT_EQ(java_lang_String::hash_code(utf8_str, utf8_length),java_lang_String::hash_code(interned_string_from_utf8)); + + Symbol* symbol_from_utf8 = SymbolTable::new_symbol(utf8_str, static_cast(utf8_length)); + oop interned_string_from_symbol = StringTable::intern(symbol_from_utf8, THREAD); + + EXPECT_EQ(interned_string_from_utf8, interned_string_from_symbol); + + oop interned_string_from_oop1 = StringTable::intern(interned_string_from_utf8, THREAD); + + EXPECT_EQ(interned_string_from_utf8, interned_string_from_oop1); + +} + +TEST_VM(StringIntern, intern_ascii) { + const char utf8_str[ASCII_LENGTH + 1] = { }; + memcpy((unsigned char*)utf8_str, static_ascii_utf8_str, ASCII_LENGTH); + test_intern(utf8_str, ASCII_LENGTH); +} + +TEST_VM(StringIntern, intern_varlen) { + const char utf8_str[COMPLEX_LENGTH + 1] = { }; + memcpy((unsigned char*)utf8_str, static_utf8_str, COMPLEX_LENGTH); + test_intern(utf8_str, COMPLEX_LENGTH); +} From ba39321902400e103cdce0b326d0005123b1d87e Mon Sep 17 00:00:00 2001 From: Adam Sotona Date: Fri, 15 Nov 2024 11:40:15 +0000 Subject: [PATCH 012/311] 8343881: java.lang.classfile.Attribute attributeName() method should return Utf8Entry Reviewed-by: liach --- .../java/lang/classfile/Attribute.java | 3 +- .../java/lang/classfile/CustomAttribute.java | 6 +- .../impl/AbstractAttributeMapper.java | 2 +- .../classfile/impl/BoundAttribute.java | 8 +- .../classfile/impl/ClassPrinterImpl.java | 10 +- .../classfile/impl/DirectCodeBuilder.java | 25 ++ .../classfile/impl/SplitConstantPool.java | 5 + .../classfile/impl/StackMapGenerator.java | 6 + .../classfile/impl/UnboundAttribute.java | 282 +++++++++++++++++- .../jdk/internal/classfile/impl/Util.java | 5 + .../impl/verifier/ParserVerifier.java | 6 +- .../com/sun/tools/javap/AttributeWriter.java | 2 +- .../jdk/jdk/classfile/BoundAttributeTest.java | 6 + test/jdk/jdk/classfile/CorpusTest.java | 15 + test/jdk/jdk/classfile/LimitsTest.java | 26 +- .../jdk/classfile/LowJCovAttributeTest.java | 2 +- test/jdk/jdk/classfile/LowModuleTest.java | 2 +- test/jdk/jdk/classfile/VerifierSelfTest.java | 11 +- .../jdk/classfile/helpers/ClassRecord.java | 2 +- .../helpers/RebuildingTransformation.java | 16 +- .../AnnotationDefaultTest.java | 2 +- .../EnclosingMethod/EnclosingMethodTest.java | 2 +- .../LineNumberTable/LineNumberTestBase.java | 2 +- .../attributes/Signature/Driver.java | 2 +- .../SourceFile/SourceFileTestBase.java | 2 +- .../attributes/deprecated/DeprecatedTest.java | 2 +- .../innerclasses/InnerClassesTestBase.java | 2 +- .../sealed/CheckSubtypesOfSealedTest.java | 4 +- test/langtools/tools/javap/T6716452.java | 2 +- 29 files changed, 415 insertions(+), 45 deletions(-) diff --git a/src/java.base/share/classes/java/lang/classfile/Attribute.java b/src/java.base/share/classes/java/lang/classfile/Attribute.java index e2f0072d396..2d559552684 100644 --- a/src/java.base/share/classes/java/lang/classfile/Attribute.java +++ b/src/java.base/share/classes/java/lang/classfile/Attribute.java @@ -25,6 +25,7 @@ package java.lang.classfile; import java.lang.classfile.attribute.*; +import java.lang.classfile.constantpool.Utf8Entry; import jdk.internal.classfile.impl.BoundAttribute; import jdk.internal.classfile.impl.UnboundAttribute; @@ -65,7 +66,7 @@ public sealed interface Attribute> /** * {@return the name of the attribute} */ - String attributeName(); + Utf8Entry attributeName(); /** * {@return the {@link AttributeMapper} associated with this attribute} diff --git a/src/java.base/share/classes/java/lang/classfile/CustomAttribute.java b/src/java.base/share/classes/java/lang/classfile/CustomAttribute.java index 9fe492dc22c..6c3a0de2b7a 100644 --- a/src/java.base/share/classes/java/lang/classfile/CustomAttribute.java +++ b/src/java.base/share/classes/java/lang/classfile/CustomAttribute.java @@ -24,6 +24,8 @@ */ package java.lang.classfile; +import java.lang.classfile.constantpool.Utf8Entry; +import jdk.internal.classfile.impl.TemporaryConstantPool; import jdk.internal.javac.PreviewFeature; /** @@ -55,8 +57,8 @@ public final AttributeMapper attributeMapper() { } @Override - public final String attributeName() { - return mapper.name(); + public Utf8Entry attributeName() { + return TemporaryConstantPool.INSTANCE.utf8Entry(mapper.name()); } @Override diff --git a/src/java.base/share/classes/jdk/internal/classfile/impl/AbstractAttributeMapper.java b/src/java.base/share/classes/jdk/internal/classfile/impl/AbstractAttributeMapper.java index b29b9f6f955..648582b8a7d 100644 --- a/src/java.base/share/classes/jdk/internal/classfile/impl/AbstractAttributeMapper.java +++ b/src/java.base/share/classes/jdk/internal/classfile/impl/AbstractAttributeMapper.java @@ -64,7 +64,7 @@ public final String name() { @Override public final void writeAttribute(BufWriter writer, T attr) { BufWriterImpl buf = (BufWriterImpl) writer; - buf.writeIndex(buf.constantPool().utf8Entry(name)); + buf.writeIndex(attr.attributeName()); int lengthIndex = buf.skip(4); writeBody(buf, attr); int written = buf.size() - lengthIndex - 4; diff --git a/src/java.base/share/classes/jdk/internal/classfile/impl/BoundAttribute.java b/src/java.base/share/classes/jdk/internal/classfile/impl/BoundAttribute.java index 59a2b03c91e..114101b02e5 100644 --- a/src/java.base/share/classes/jdk/internal/classfile/impl/BoundAttribute.java +++ b/src/java.base/share/classes/jdk/internal/classfile/impl/BoundAttribute.java @@ -47,6 +47,7 @@ public abstract sealed class BoundAttribute> private final AttributeMapper mapper; final ClassReaderImpl classReader; final int payloadStart; + Utf8Entry name; BoundAttribute(ClassReader classReader, AttributeMapper mapper, int payloadStart) { this.mapper = mapper; @@ -59,8 +60,11 @@ public int payloadLen() { } @Override - public String attributeName() { - return mapper.name(); + public Utf8Entry attributeName() { + if (name == null) { + name = classReader.readEntry(payloadStart - 6, Utf8Entry.class); + } + return name; } @Override diff --git a/src/java.base/share/classes/jdk/internal/classfile/impl/ClassPrinterImpl.java b/src/java.base/share/classes/jdk/internal/classfile/impl/ClassPrinterImpl.java index b8fce2fd288..1ded017f2a2 100644 --- a/src/java.base/share/classes/jdk/internal/classfile/impl/ClassPrinterImpl.java +++ b/src/java.base/share/classes/jdk/internal/classfile/impl/ClassPrinterImpl.java @@ -574,7 +574,7 @@ private static MapNode classToTree(ClassModel clm, Verbosity verbosity) { list("flags", "flag", clm.flags().flags().stream().map(AccessFlag::name)), leaf("superclass", clm.superclass().map(ClassEntry::asInternalName).orElse("")), list("interfaces", "interface", clm.interfaces().stream().map(ClassEntry::asInternalName)), - list("attributes", "attribute", clm.attributes().stream().map(Attribute::attributeName))) + list("attributes", "attribute", clm.attributes().stream().map(Attribute::attributeName).map(Utf8Entry::stringValue))) .with(constantPoolToTree(clm.constantPool(), verbosity)) .with(attributesToTree(clm.attributes(), verbosity)) .with(new ListNodeImpl(BLOCK, "fields", clm.fields().stream().map(f -> @@ -672,7 +672,7 @@ private static MapNode fieldToTree(FieldModel f, Verbosity verbosity) { "flag", f.flags().flags().stream().map(AccessFlag::name)), leaf("field type", f.fieldType().stringValue()), list("attributes", - "attribute", f.attributes().stream().map(Attribute::attributeName))) + "attribute", f.attributes().stream().map(Attribute::attributeName).map(Utf8Entry::stringValue))) .with(attributesToTree(f.attributes(), verbosity)); } @@ -683,7 +683,7 @@ public static MapNode methodToTree(MethodModel m, Verbosity verbosity) { "flag", m.flags().flags().stream().map(AccessFlag::name)), leaf("method type", m.methodType().stringValue()), list("attributes", - "attribute", m.attributes().stream().map(Attribute::attributeName))) + "attribute", m.attributes().stream().map(Attribute::attributeName).map(Utf8Entry::stringValue))) .with(attributesToTree(m.attributes(), verbosity)) .with(codeToTree((CodeAttribute)m.code().orElse(null), verbosity)); } @@ -694,7 +694,7 @@ private static MapNode codeToTree(CodeAttribute com, Verbosity verbosity) { codeNode.with(leaf("max stack", com.maxStack())); codeNode.with(leaf("max locals", com.maxLocals())); codeNode.with(list("attributes", - "attribute", com.attributes().stream().map(Attribute::attributeName))); + "attribute", com.attributes().stream().map(Attribute::attributeName).map(Utf8Entry::stringValue))); var stackMap = new MapNodeImpl(BLOCK, "stack map frames"); var visibleTypeAnnos = new LinkedHashMap>(); var invisibleTypeAnnos = new LinkedHashMap>(); @@ -996,7 +996,7 @@ private static Node[] attributesToTree(List> attributes, Verbosity "name", rc.name().stringValue(), "type", rc.descriptor().stringValue())) .with(list("attributes", "attribute", rc.attributes().stream() - .map(Attribute::attributeName))) + .map(Attribute::attributeName).map(Utf8Entry::stringValue))) .with(attributesToTree(rc.attributes(), verbosity))))); case AnnotationDefaultAttribute ada -> nodes.add(new MapNodeImpl(FLOW, "annotation default").with(elementValueToTree(ada.defaultValue()))); diff --git a/src/java.base/share/classes/jdk/internal/classfile/impl/DirectCodeBuilder.java b/src/java.base/share/classes/jdk/internal/classfile/impl/DirectCodeBuilder.java index 7d554a35974..5093f6408c8 100644 --- a/src/java.base/share/classes/jdk/internal/classfile/impl/DirectCodeBuilder.java +++ b/src/java.base/share/classes/jdk/internal/classfile/impl/DirectCodeBuilder.java @@ -241,6 +241,11 @@ public void writeBody(BufWriterImpl b) { if (crSize < characterRangesCount) b.patchU2(pos, crSize); } + + @Override + public Utf8Entry attributeName() { + return constantPool.utf8Entry(Attributes.NAME_CHARACTER_RANGE_TABLE); + } }; attributes.withAttribute(a); } @@ -265,6 +270,11 @@ public void writeBody(BufWriterImpl b) { if (lvSize < localVariablesCount) b.patchU2(pos, lvSize); } + + @Override + public Utf8Entry attributeName() { + return constantPool.utf8Entry(Attributes.NAME_LOCAL_VARIABLE_TABLE); + } }; attributes.withAttribute(a); } @@ -289,6 +299,11 @@ public void writeBody(BufWriterImpl b) { if (lvtSize < localVariableTypesCount) b.patchU2(pos, lvtSize); } + + @Override + public Utf8Entry attributeName() { + return constantPool.utf8Entry(Attributes.NAME_LOCAL_VARIABLE_TYPE_TABLE); + } }; attributes.withAttribute(a); } @@ -371,6 +386,11 @@ public void writeBody(BufWriterImpl buf) { dcb.attributes.writeTo(buf); buf.setLabelContext(null); } + + @Override + public Utf8Entry attributeName() { + return constantPool.utf8Entry(Attributes.NAME_CODE); + } }; } @@ -416,6 +436,11 @@ public void writeTo(BufWriterImpl b) { b.writeU2(buf.size() / 4); b.writeBytes(buf); } + + @Override + public Utf8Entry attributeName() { + return buf.constantPool().utf8Entry(Attributes.NAME_LINE_NUMBER_TABLE); + } } private boolean codeAndExceptionsMatch(int codeLength) { diff --git a/src/java.base/share/classes/jdk/internal/classfile/impl/SplitConstantPool.java b/src/java.base/share/classes/jdk/internal/classfile/impl/SplitConstantPool.java index 0e26a8941e0..5ba81fc2927 100644 --- a/src/java.base/share/classes/jdk/internal/classfile/impl/SplitConstantPool.java +++ b/src/java.base/share/classes/jdk/internal/classfile/impl/SplitConstantPool.java @@ -146,6 +146,11 @@ public void writeBody(BufWriterImpl b) { for (int i = 0; i < bsmSize; i++) bootstrapMethodEntry(i).writeTo(buf); } + + @Override + public Utf8Entry attributeName() { + return utf8Entry(Attributes.NAME_BOOTSTRAP_METHODS); + } }; a.writeTo(buf); } diff --git a/src/java.base/share/classes/jdk/internal/classfile/impl/StackMapGenerator.java b/src/java.base/share/classes/jdk/internal/classfile/impl/StackMapGenerator.java index a83c32dc05a..7e16aea5a52 100644 --- a/src/java.base/share/classes/jdk/internal/classfile/impl/StackMapGenerator.java +++ b/src/java.base/share/classes/jdk/internal/classfile/impl/StackMapGenerator.java @@ -35,6 +35,7 @@ import java.lang.classfile.constantpool.ConstantPoolBuilder; import java.lang.classfile.constantpool.InvokeDynamicEntry; import java.lang.classfile.constantpool.MemberRefEntry; +import java.lang.classfile.constantpool.Utf8Entry; import java.lang.constant.ClassDesc; import java.lang.constant.MethodTypeDesc; import java.util.ArrayList; @@ -401,6 +402,11 @@ public void writeBody(BufWriterImpl b) { prevFrame = fr; } } + + @Override + public Utf8Entry attributeName() { + return cp.utf8Entry(Attributes.NAME_STACK_MAP_TABLE); + } }; } diff --git a/src/java.base/share/classes/jdk/internal/classfile/impl/UnboundAttribute.java b/src/java.base/share/classes/jdk/internal/classfile/impl/UnboundAttribute.java index dfad66a897c..0b0f1836f66 100644 --- a/src/java.base/share/classes/jdk/internal/classfile/impl/UnboundAttribute.java +++ b/src/java.base/share/classes/jdk/internal/classfile/impl/UnboundAttribute.java @@ -54,11 +54,6 @@ public AttributeMapper attributeMapper() { return mapper; } - @Override - public String attributeName() { - return mapper.name(); - } - @Override @SuppressWarnings("unchecked") public void writeTo(BufWriterImpl buf) { @@ -93,6 +88,8 @@ public static final class UnboundConstantValueAttribute extends UnboundAttribute implements ConstantValueAttribute { + private static final Utf8Entry NAME = TemporaryConstantPool.INSTANCE.utf8Entry(Attributes.NAME_CONSTANT_VALUE); + private final ConstantValueEntry entry; public UnboundConstantValueAttribute(ConstantValueEntry entry) { @@ -105,27 +102,50 @@ public ConstantValueEntry constant() { return entry; } + @Override + public Utf8Entry attributeName() { + return NAME; + } } public static final class UnboundDeprecatedAttribute extends UnboundAttribute implements DeprecatedAttribute { + + private static final Utf8Entry NAME = TemporaryConstantPool.INSTANCE.utf8Entry(Attributes.NAME_DEPRECATED); + public UnboundDeprecatedAttribute() { super(Attributes.deprecated()); } + + @Override + public Utf8Entry attributeName() { + return NAME; + } } public static final class UnboundSyntheticAttribute extends UnboundAttribute implements SyntheticAttribute { + + private static final Utf8Entry NAME = TemporaryConstantPool.INSTANCE.utf8Entry(Attributes.NAME_SYNTHETIC); + public UnboundSyntheticAttribute() { super(Attributes.synthetic()); } + + @Override + public Utf8Entry attributeName() { + return NAME; + } } public static final class UnboundSignatureAttribute extends UnboundAttribute implements SignatureAttribute { + + private static final Utf8Entry NAME = TemporaryConstantPool.INSTANCE.utf8Entry(Attributes.NAME_SIGNATURE); + private final Utf8Entry signature; public UnboundSignatureAttribute(Utf8Entry signature) { @@ -137,11 +157,19 @@ public UnboundSignatureAttribute(Utf8Entry signature) { public Utf8Entry signature() { return signature; } + + @Override + public Utf8Entry attributeName() { + return NAME; + } } public static final class UnboundExceptionsAttribute extends UnboundAttribute implements ExceptionsAttribute { + + private static final Utf8Entry NAME = TemporaryConstantPool.INSTANCE.utf8Entry(Attributes.NAME_EXCEPTIONS); + private final List exceptions; public UnboundExceptionsAttribute(List exceptions) { @@ -153,11 +181,19 @@ public UnboundExceptionsAttribute(List exceptions) { public List exceptions() { return exceptions; } + + @Override + public Utf8Entry attributeName() { + return NAME; + } } public static final class UnboundAnnotationDefaultAttribute extends UnboundAttribute implements AnnotationDefaultAttribute { + + private static final Utf8Entry NAME = TemporaryConstantPool.INSTANCE.utf8Entry(Attributes.NAME_ANNOTATION_DEFAULT); + private final AnnotationValue annotationDefault; public UnboundAnnotationDefaultAttribute(AnnotationValue annotationDefault) { @@ -169,10 +205,18 @@ public UnboundAnnotationDefaultAttribute(AnnotationValue annotationDefault) { public AnnotationValue defaultValue() { return annotationDefault; } + + @Override + public Utf8Entry attributeName() { + return NAME; + } } public static final class UnboundSourceFileAttribute extends UnboundAttribute implements SourceFileAttribute { + + private static final Utf8Entry NAME = TemporaryConstantPool.INSTANCE.utf8Entry(Attributes.NAME_SOURCE_FILE); + private final Utf8Entry sourceFile; public UnboundSourceFileAttribute(Utf8Entry sourceFile) { @@ -185,10 +229,17 @@ public Utf8Entry sourceFile() { return sourceFile; } + @Override + public Utf8Entry attributeName() { + return NAME; + } } public static final class UnboundStackMapTableAttribute extends UnboundAttribute implements StackMapTableAttribute { + + private static final Utf8Entry NAME = TemporaryConstantPool.INSTANCE.utf8Entry(Attributes.NAME_STACK_MAP_TABLE); + private final List entries; public UnboundStackMapTableAttribute(List entries) { @@ -200,11 +251,19 @@ public UnboundStackMapTableAttribute(List entries) { public List entries() { return entries; } + + @Override + public Utf8Entry attributeName() { + return NAME; + } } public static final class UnboundInnerClassesAttribute extends UnboundAttribute implements InnerClassesAttribute { + + private static final Utf8Entry NAME = TemporaryConstantPool.INSTANCE.utf8Entry(Attributes.NAME_INNER_CLASSES); + private final List innerClasses; public UnboundInnerClassesAttribute(List innerClasses) { @@ -216,11 +275,19 @@ public UnboundInnerClassesAttribute(List innerClasses) { public List classes() { return innerClasses; } + + @Override + public Utf8Entry attributeName() { + return NAME; + } } public static final class UnboundRecordAttribute extends UnboundAttribute implements RecordAttribute { + + private static final Utf8Entry NAME = TemporaryConstantPool.INSTANCE.utf8Entry(Attributes.NAME_RECORD); + private final List components; public UnboundRecordAttribute(List components) { @@ -232,11 +299,19 @@ public UnboundRecordAttribute(List components) { public List components() { return components; } + + @Override + public Utf8Entry attributeName() { + return NAME; + } } public static final class UnboundEnclosingMethodAttribute extends UnboundAttribute implements EnclosingMethodAttribute { + + private static final Utf8Entry NAME = TemporaryConstantPool.INSTANCE.utf8Entry(Attributes.NAME_ENCLOSING_METHOD); + private final ClassEntry classEntry; private final NameAndTypeEntry method; @@ -255,11 +330,19 @@ public ClassEntry enclosingClass() { public Optional enclosingMethod() { return Optional.ofNullable(method); } + + @Override + public Utf8Entry attributeName() { + return NAME; + } } public static final class UnboundMethodParametersAttribute extends UnboundAttribute implements MethodParametersAttribute { + + private static final Utf8Entry NAME = TemporaryConstantPool.INSTANCE.utf8Entry(Attributes.NAME_METHOD_PARAMETERS); + private final List parameters; public UnboundMethodParametersAttribute(List parameters) { @@ -271,11 +354,19 @@ public UnboundMethodParametersAttribute(List parameters) { public List parameters() { return parameters; } + + @Override + public Utf8Entry attributeName() { + return NAME; + } } public static final class UnboundModuleTargetAttribute extends UnboundAttribute implements ModuleTargetAttribute { + + private static final Utf8Entry NAME = TemporaryConstantPool.INSTANCE.utf8Entry(Attributes.NAME_MODULE_TARGET); + final Utf8Entry moduleTarget; public UnboundModuleTargetAttribute(Utf8Entry moduleTarget) { @@ -287,11 +378,19 @@ public UnboundModuleTargetAttribute(Utf8Entry moduleTarget) { public Utf8Entry targetPlatform() { return moduleTarget; } + + @Override + public Utf8Entry attributeName() { + return NAME; + } } public static final class UnboundModuleMainClassAttribute extends UnboundAttribute implements ModuleMainClassAttribute { + + private static final Utf8Entry NAME = TemporaryConstantPool.INSTANCE.utf8Entry(Attributes.NAME_MODULE_MAIN_CLASS); + final ClassEntry mainClass; public UnboundModuleMainClassAttribute(ClassEntry mainClass) { @@ -303,11 +402,19 @@ public UnboundModuleMainClassAttribute(ClassEntry mainClass) { public ClassEntry mainClass() { return mainClass; } + + @Override + public Utf8Entry attributeName() { + return NAME; + } } public static final class UnboundModuleHashesAttribute extends UnboundAttribute implements ModuleHashesAttribute { + + private static final Utf8Entry NAME = TemporaryConstantPool.INSTANCE.utf8Entry(Attributes.NAME_MODULE_HASHES); + private final Utf8Entry algorithm; private final List hashes; @@ -326,11 +433,19 @@ public Utf8Entry algorithm() { public List hashes() { return hashes; } + + @Override + public Utf8Entry attributeName() { + return NAME; + } } public static final class UnboundModulePackagesAttribute extends UnboundAttribute implements ModulePackagesAttribute { + + private static final Utf8Entry NAME = TemporaryConstantPool.INSTANCE.utf8Entry(Attributes.NAME_MODULE_PACKAGES); + private final Collection packages; public UnboundModulePackagesAttribute(Collection packages) { @@ -342,11 +457,19 @@ public UnboundModulePackagesAttribute(Collection packages) { public List packages() { return List.copyOf(packages); } + + @Override + public Utf8Entry attributeName() { + return NAME; + } } public static final class UnboundModuleResolutionAttribute extends UnboundAttribute implements ModuleResolutionAttribute { + + private static final Utf8Entry NAME = TemporaryConstantPool.INSTANCE.utf8Entry(Attributes.NAME_MODULE_RESOLUTION); + private final int resolutionFlags; public UnboundModuleResolutionAttribute(int flags) { @@ -358,11 +481,19 @@ public UnboundModuleResolutionAttribute(int flags) { public int resolutionFlags() { return resolutionFlags; } + + @Override + public Utf8Entry attributeName() { + return NAME; + } } public static final class UnboundPermittedSubclassesAttribute extends UnboundAttribute implements PermittedSubclassesAttribute { + + private static final Utf8Entry NAME = TemporaryConstantPool.INSTANCE.utf8Entry(Attributes.NAME_PERMITTED_SUBCLASSES); + private final List permittedSubclasses; public UnboundPermittedSubclassesAttribute(List permittedSubclasses) { @@ -374,11 +505,19 @@ public UnboundPermittedSubclassesAttribute(List permittedSubclasses) public List permittedSubclasses() { return permittedSubclasses; } + + @Override + public Utf8Entry attributeName() { + return NAME; + } } public static final class UnboundNestMembersAttribute extends UnboundAttribute implements NestMembersAttribute { + + private static final Utf8Entry NAME = TemporaryConstantPool.INSTANCE.utf8Entry(Attributes.NAME_NEST_MEMBERS); + private final List memberEntries; public UnboundNestMembersAttribute(List memberEntries) { @@ -390,11 +529,19 @@ public UnboundNestMembersAttribute(List memberEntries) { public List nestMembers() { return memberEntries; } + + @Override + public Utf8Entry attributeName() { + return NAME; + } } public static final class UnboundNestHostAttribute extends UnboundAttribute implements NestHostAttribute { + + private static final Utf8Entry NAME = TemporaryConstantPool.INSTANCE.utf8Entry(Attributes.NAME_NEST_HOST); + private final ClassEntry hostEntry; public UnboundNestHostAttribute(ClassEntry hostEntry) { @@ -406,11 +553,19 @@ public UnboundNestHostAttribute(ClassEntry hostEntry) { public ClassEntry nestHost() { return hostEntry; } + + @Override + public Utf8Entry attributeName() { + return NAME; + } } public static final class UnboundCompilationIDAttribute extends UnboundAttribute implements CompilationIDAttribute { + + private static final Utf8Entry NAME = TemporaryConstantPool.INSTANCE.utf8Entry(Attributes.NAME_COMPILATION_ID); + private final Utf8Entry idEntry; public UnboundCompilationIDAttribute(Utf8Entry idEntry) { @@ -422,11 +577,19 @@ public UnboundCompilationIDAttribute(Utf8Entry idEntry) { public Utf8Entry compilationId() { return idEntry; } + + @Override + public Utf8Entry attributeName() { + return NAME; + } } public static final class UnboundSourceIDAttribute extends UnboundAttribute implements SourceIDAttribute { + + private static final Utf8Entry NAME = TemporaryConstantPool.INSTANCE.utf8Entry(Attributes.NAME_SOURCE_ID); + private final Utf8Entry idEntry; public UnboundSourceIDAttribute(Utf8Entry idEntry) { @@ -438,11 +601,19 @@ public UnboundSourceIDAttribute(Utf8Entry idEntry) { public Utf8Entry sourceId() { return idEntry; } + + @Override + public Utf8Entry attributeName() { + return NAME; + } } public static final class UnboundSourceDebugExtensionAttribute extends UnboundAttribute implements SourceDebugExtensionAttribute { + + private static final Utf8Entry NAME = TemporaryConstantPool.INSTANCE.utf8Entry(Attributes.NAME_SOURCE_DEBUG_EXTENSION); + private final byte[] contents; public UnboundSourceDebugExtensionAttribute(byte[] contents) { @@ -454,11 +625,19 @@ public UnboundSourceDebugExtensionAttribute(byte[] contents) { public byte[] contents() { return contents; } + + @Override + public Utf8Entry attributeName() { + return NAME; + } } public static final class UnboundCharacterRangeTableAttribute extends UnboundAttribute implements CharacterRangeTableAttribute { + + private static final Utf8Entry NAME = TemporaryConstantPool.INSTANCE.utf8Entry(Attributes.NAME_CHARACTER_RANGE_TABLE); + private final List ranges; public UnboundCharacterRangeTableAttribute(List ranges) { @@ -470,11 +649,19 @@ public UnboundCharacterRangeTableAttribute(List ranges) { public List characterRangeTable() { return ranges; } + + @Override + public Utf8Entry attributeName() { + return NAME; + } } public static final class UnboundLineNumberTableAttribute extends UnboundAttribute implements LineNumberTableAttribute { + + private static final Utf8Entry NAME = TemporaryConstantPool.INSTANCE.utf8Entry(Attributes.NAME_LINE_NUMBER_TABLE); + private final List lines; public UnboundLineNumberTableAttribute(List lines) { @@ -486,11 +673,19 @@ public UnboundLineNumberTableAttribute(List lines) { public List lineNumbers() { return lines; } + + @Override + public Utf8Entry attributeName() { + return NAME; + } } public static final class UnboundLocalVariableTableAttribute extends UnboundAttribute implements LocalVariableTableAttribute { + + private static final Utf8Entry NAME = TemporaryConstantPool.INSTANCE.utf8Entry(Attributes.NAME_LOCAL_VARIABLE_TABLE); + private final List locals; public UnboundLocalVariableTableAttribute(List locals) { @@ -502,11 +697,19 @@ public UnboundLocalVariableTableAttribute(List locals) { public List localVariables() { return locals; } + + @Override + public Utf8Entry attributeName() { + return NAME; + } } public static final class UnboundLocalVariableTypeTableAttribute extends UnboundAttribute implements LocalVariableTypeTableAttribute { + + private static final Utf8Entry NAME = TemporaryConstantPool.INSTANCE.utf8Entry(Attributes.NAME_LOCAL_VARIABLE_TYPE_TABLE); + private final List locals; public UnboundLocalVariableTypeTableAttribute(List locals) { @@ -518,11 +721,19 @@ public UnboundLocalVariableTypeTableAttribute(List locals public List localVariableTypes() { return locals; } + + @Override + public Utf8Entry attributeName() { + return NAME; + } } public static final class UnboundRuntimeVisibleAnnotationsAttribute extends UnboundAttribute implements RuntimeVisibleAnnotationsAttribute { + + private static final Utf8Entry NAME = TemporaryConstantPool.INSTANCE.utf8Entry(Attributes.NAME_RUNTIME_VISIBLE_ANNOTATIONS); + private final List elements; public UnboundRuntimeVisibleAnnotationsAttribute(List elements) { @@ -534,11 +745,19 @@ public UnboundRuntimeVisibleAnnotationsAttribute(List elements) { public List annotations() { return elements; } + + @Override + public Utf8Entry attributeName() { + return NAME; + } } public static final class UnboundRuntimeInvisibleAnnotationsAttribute extends UnboundAttribute implements RuntimeInvisibleAnnotationsAttribute { + + private static final Utf8Entry NAME = TemporaryConstantPool.INSTANCE.utf8Entry(Attributes.NAME_RUNTIME_INVISIBLE_ANNOTATIONS); + private final List elements; public UnboundRuntimeInvisibleAnnotationsAttribute(List elements) { @@ -550,11 +769,19 @@ public UnboundRuntimeInvisibleAnnotationsAttribute(List elements) { public List annotations() { return elements; } + + @Override + public Utf8Entry attributeName() { + return NAME; + } } public static final class UnboundRuntimeVisibleParameterAnnotationsAttribute extends UnboundAttribute implements RuntimeVisibleParameterAnnotationsAttribute { + + private static final Utf8Entry NAME = TemporaryConstantPool.INSTANCE.utf8Entry(Attributes.NAME_RUNTIME_VISIBLE_PARAMETER_ANNOTATIONS); + private final List> elements; public UnboundRuntimeVisibleParameterAnnotationsAttribute(List> elements) { @@ -572,11 +799,19 @@ public UnboundRuntimeVisibleParameterAnnotationsAttribute(List> public List> parameterAnnotations() { return elements; } + + @Override + public Utf8Entry attributeName() { + return NAME; + } } public static final class UnboundRuntimeInvisibleParameterAnnotationsAttribute extends UnboundAttribute implements RuntimeInvisibleParameterAnnotationsAttribute { + + private static final Utf8Entry NAME = TemporaryConstantPool.INSTANCE.utf8Entry(Attributes.NAME_RUNTIME_INVISIBLE_PARAMETER_ANNOTATIONS); + private final List> elements; public UnboundRuntimeInvisibleParameterAnnotationsAttribute(List> elements) { @@ -594,11 +829,19 @@ public UnboundRuntimeInvisibleParameterAnnotationsAttribute(List> parameterAnnotations() { return elements; } + + @Override + public Utf8Entry attributeName() { + return NAME; + } } public static final class UnboundRuntimeVisibleTypeAnnotationsAttribute extends UnboundAttribute implements RuntimeVisibleTypeAnnotationsAttribute { + + private static final Utf8Entry NAME = TemporaryConstantPool.INSTANCE.utf8Entry(Attributes.NAME_RUNTIME_VISIBLE_TYPE_ANNOTATIONS); + private final List elements; public UnboundRuntimeVisibleTypeAnnotationsAttribute(List elements) { @@ -610,11 +853,19 @@ public UnboundRuntimeVisibleTypeAnnotationsAttribute(List elemen public List annotations() { return elements; } + + @Override + public Utf8Entry attributeName() { + return NAME; + } } public static final class UnboundRuntimeInvisibleTypeAnnotationsAttribute extends UnboundAttribute implements RuntimeInvisibleTypeAnnotationsAttribute { + + private static final Utf8Entry NAME = TemporaryConstantPool.INSTANCE.utf8Entry(Attributes.NAME_RUNTIME_INVISIBLE_TYPE_ANNOTATIONS); + private final List elements; public UnboundRuntimeInvisibleTypeAnnotationsAttribute(List elements) { @@ -626,6 +877,11 @@ public UnboundRuntimeInvisibleTypeAnnotationsAttribute(List elem public List annotations() { return elements; } + + @Override + public Utf8Entry attributeName() { + return NAME; + } } public record UnboundCharacterRangeInfo(int startPc, int endPc, @@ -749,6 +1005,9 @@ public record TypePathComponentImpl(TypeAnnotation.TypePathComponent.Kind typePa implements TypeAnnotation.TypePathComponent {} public static final class UnboundModuleAttribute extends UnboundAttribute implements ModuleAttribute { + + private static final Utf8Entry NAME = TemporaryConstantPool.INSTANCE.utf8Entry(Attributes.NAME_MODULE); + private final ModuleEntry moduleName; private final int moduleFlags; private final Utf8Entry moduleVersion; @@ -817,6 +1076,11 @@ public List uses() { public List provides() { return provides; } + + @Override + public Utf8Entry attributeName() { + return NAME; + } } public abstract static non-sealed class AdHocAttribute> @@ -841,6 +1105,9 @@ public void writeTo(BufWriterImpl b) { public static final class EmptyBootstrapAttribute extends UnboundAttribute implements BootstrapMethodsAttribute { + + private static final Utf8Entry NAME = TemporaryConstantPool.INSTANCE.utf8Entry(Attributes.NAME_BOOTSTRAP_METHODS); + public EmptyBootstrapAttribute() { super(Attributes.bootstrapMethods()); } @@ -854,5 +1121,10 @@ public int bootstrapMethodsSize() { public List bootstrapMethods() { return List.of(); } + + @Override + public Utf8Entry attributeName() { + return NAME; + } } } diff --git a/src/java.base/share/classes/jdk/internal/classfile/impl/Util.java b/src/java.base/share/classes/jdk/internal/classfile/impl/Util.java index 1088724d8b4..fc6099f3e5b 100644 --- a/src/java.base/share/classes/jdk/internal/classfile/impl/Util.java +++ b/src/java.base/share/classes/jdk/internal/classfile/impl/Util.java @@ -281,6 +281,11 @@ public void writeBody(BufWriterImpl b) { b.writeBytes(bytecode.array(), 0, bytecode.length()); b.writeU2U2(0, 0);//exception handlers & attributes } + + @Override + public Utf8Entry attributeName() { + return cp.utf8Entry(Attributes.NAME_CODE); + } })))); ClassPrinter.toYaml(clm.methods().get(0).code().get(), ClassPrinter.Verbosity.TRACE_ALL, dump); } catch (Error | Exception _) { diff --git a/src/java.base/share/classes/jdk/internal/classfile/impl/verifier/ParserVerifier.java b/src/java.base/share/classes/jdk/internal/classfile/impl/verifier/ParserVerifier.java index 521d74ae133..b7ddaace116 100644 --- a/src/java.base/share/classes/jdk/internal/classfile/impl/verifier/ParserVerifier.java +++ b/src/java.base/share/classes/jdk/internal/classfile/impl/verifier/ParserVerifier.java @@ -176,8 +176,8 @@ private void verifyAttributes(ClassFileElement cfe, List errors) { if (cfe instanceof AttributedElement ae) { var attrNames = new HashSet(); for (var a : ae.attributes()) { - if (!a.attributeMapper().allowMultiple() && !attrNames.add(a.attributeName())) { - errors.add(new VerifyError("Multiple %s attributes in %s".formatted(a.attributeName(), toString(ae)))); + if (!a.attributeMapper().allowMultiple() && !attrNames.add(a.attributeName().stringValue())) { + errors.add(new VerifyError("Multiple %s attributes in %s".formatted(a.attributeName().stringValue(), toString(ae)))); } verifyAttribute(ae, a, errors); } @@ -331,7 +331,7 @@ private void verifyAttribute(AttributedElement ae, Attribute a, List= 0 && size != ((BoundAttribute)a).payloadLen()) { - errors.add(new VerifyError("Wrong %s attribute length in %s".formatted(a.attributeName(), toString(ae)))); + errors.add(new VerifyError("Wrong %s attribute length in %s".formatted(a.attributeName().stringValue(), toString(ae)))); } } diff --git a/src/jdk.jdeps/share/classes/com/sun/tools/javap/AttributeWriter.java b/src/jdk.jdeps/share/classes/com/sun/tools/javap/AttributeWriter.java index cccbaf14f53..2335d882ab1 100644 --- a/src/jdk.jdeps/share/classes/com/sun/tools/javap/AttributeWriter.java +++ b/src/jdk.jdeps/share/classes/com/sun/tools/javap/AttributeWriter.java @@ -84,7 +84,7 @@ public void write(Attribute a, CodeAttribute lr) { int i = 0; int j = 0; print(" "); - print(attr.attributeName()); + print(attr.attributeName().stringValue()); print(": "); print("length = 0x" + toHex(data.length)); print(" (unknown attribute)"); diff --git a/test/jdk/jdk/classfile/BoundAttributeTest.java b/test/jdk/jdk/classfile/BoundAttributeTest.java index 6a164bec2f9..e8f12356128 100644 --- a/test/jdk/jdk/classfile/BoundAttributeTest.java +++ b/test/jdk/jdk/classfile/BoundAttributeTest.java @@ -41,6 +41,7 @@ import java.lang.classfile.attribute.MethodParameterInfo; import java.lang.classfile.attribute.MethodParametersAttribute; import java.lang.classfile.constantpool.ConstantPoolException; +import java.lang.classfile.constantpool.Utf8Entry; import java.lang.constant.ClassDesc; import java.lang.constant.ConstantDescs; import java.lang.constant.MethodTypeDesc; @@ -89,6 +90,11 @@ public void writeBody(BufWriterImpl b) { b.writeIndex(oneClass); b.writeIndex(oneClassString); } + + @Override + public Utf8Entry attributeName() { + return cp.utf8Entry(Attributes.NAME_NEST_MEMBERS); + } }); }); diff --git a/test/jdk/jdk/classfile/CorpusTest.java b/test/jdk/jdk/classfile/CorpusTest.java index 631e2f8afaa..513005370e7 100644 --- a/test/jdk/jdk/classfile/CorpusTest.java +++ b/test/jdk/jdk/classfile/CorpusTest.java @@ -93,6 +93,11 @@ public void writeBody(BufWriterImpl b) { b.writeU2(curPc); b.writeU2(ln.line()); } + + @Override + public Utf8Entry attributeName() { + return cob.constantPool().utf8Entry(Attributes.NAME_LINE_NUMBER_TABLE); + } }); case LocalVariable lv -> dcob.writeAttribute(new UnboundAttribute.AdHocAttribute<>(Attributes.localVariableTable()) { @Override @@ -100,6 +105,11 @@ public void writeBody(BufWriterImpl b) { b.writeU2(1); Util.writeLocalVariable(b, lv); } + + @Override + public Utf8Entry attributeName() { + return cob.constantPool().utf8Entry(Attributes.NAME_LOCAL_VARIABLE_TABLE); + } }); case LocalVariableType lvt -> dcob.writeAttribute(new UnboundAttribute.AdHocAttribute<>(Attributes.localVariableTypeTable()) { @Override @@ -107,6 +117,11 @@ public void writeBody(BufWriterImpl b) { b.writeU2(1); Util.writeLocalVariable(b, lvt); } + + @Override + public Utf8Entry attributeName() { + return cob.constantPool().utf8Entry(Attributes.NAME_LOCAL_VARIABLE_TYPE_TABLE); + } }); default -> cob.with(coe); } diff --git a/test/jdk/jdk/classfile/LimitsTest.java b/test/jdk/jdk/classfile/LimitsTest.java index a1899ac1c84..6f3dc04c665 100644 --- a/test/jdk/jdk/classfile/LimitsTest.java +++ b/test/jdk/jdk/classfile/LimitsTest.java @@ -41,6 +41,7 @@ import java.lang.classfile.constantpool.ConstantPoolBuilder; import java.lang.classfile.constantpool.ConstantPoolException; import java.lang.classfile.constantpool.IntegerEntry; +import java.lang.classfile.constantpool.Utf8Entry; import java.util.List; import jdk.internal.classfile.impl.BufWriterImpl; @@ -49,6 +50,7 @@ import jdk.internal.classfile.impl.LabelContext; import jdk.internal.classfile.impl.UnboundAttribute; import org.junit.jupiter.api.Test; + import static org.junit.jupiter.api.Assertions.*; class LimitsTest { @@ -145,7 +147,13 @@ public void writeBody(BufWriterImpl b) { b.writeInt(-2); //npairs to jump back and cause OOME if not checked b.writeU2(0);//exception handlers b.writeU2(0);//attributes - }})))).methods().get(0).code().get().elementList()); + } + + @Override + public Utf8Entry attributeName() { + return mb.constantPool().utf8Entry(Attributes.NAME_CODE); + } + })))).methods().get(0).code().get().elementList()); } @Test @@ -167,7 +175,13 @@ public void writeBody(BufWriterImpl b) { b.writeInt(-5); //high to jump back and cause OOME if not checked b.writeU2(0);//exception handlers b.writeU2(0);//attributes - }})))).methods().get(0).code().get().elementList()); + } + + @Override + public Utf8Entry attributeName() { + return mb.constantPool().utf8Entry(Attributes.NAME_CODE); + } + })))).methods().get(0).code().get().elementList()); assertThrows(IllegalArgumentException.class, () -> ClassFile.of().parse(ClassFile.of().build(ClassDesc.of("TableSwitchClass"), cb -> cb.withMethod( "tableSwitchMethod", MethodTypeDesc.of(ConstantDescs.CD_void), 0, mb -> @@ -189,7 +203,13 @@ public void writeBody(BufWriterImpl b) { b.writeInt(Integer.MAX_VALUE - 4); //high to jump back and cause infinite loop b.writeU2(0);//exception handlers b.writeU2(0);//attributes - }})))).methods().get(0).code().get().elementList()); + } + + @Override + public Utf8Entry attributeName() { + return mb.constantPool().utf8Entry(Attributes.NAME_CODE); + } + })))).methods().get(0).code().get().elementList()); } @Test diff --git a/test/jdk/jdk/classfile/LowJCovAttributeTest.java b/test/jdk/jdk/classfile/LowJCovAttributeTest.java index 858b9c90416..ed29a057357 100644 --- a/test/jdk/jdk/classfile/LowJCovAttributeTest.java +++ b/test/jdk/jdk/classfile/LowJCovAttributeTest.java @@ -76,7 +76,7 @@ void testRead() { private void testRead0() { int[] mask = new int[1]; for (Attribute attr : classLow.attributes()) { - switch (attr.attributeName()) { + switch (attr.attributeName().stringValue()) { case Attributes.NAME_COMPILATION_ID: { CompilationIDAttribute cid = (CompilationIDAttribute) attr; Utf8Entry v = cid.compilationId(); diff --git a/test/jdk/jdk/classfile/LowModuleTest.java b/test/jdk/jdk/classfile/LowModuleTest.java index e78eff74d1d..b017fe84756 100644 --- a/test/jdk/jdk/classfile/LowModuleTest.java +++ b/test/jdk/jdk/classfile/LowModuleTest.java @@ -77,7 +77,7 @@ void testRead(Path path, TestInfo test) throws Exception { private void testRead0(ClassModel classLow) { for (Attribute attr : classLow.attributes()) { - switch (attr.attributeName()) { + switch (attr.attributeName().stringValue()) { case Attributes.NAME_SOURCE_FILE: { SourceFileAttribute sfa = (SourceFileAttribute) attr; Utf8Entry sf = sfa.sourceFile(); diff --git a/test/jdk/jdk/classfile/VerifierSelfTest.java b/test/jdk/jdk/classfile/VerifierSelfTest.java index b6a2f08c9ec..1f9f199a33b 100644 --- a/test/jdk/jdk/classfile/VerifierSelfTest.java +++ b/test/jdk/jdk/classfile/VerifierSelfTest.java @@ -31,7 +31,9 @@ import java.io.IOException; import java.lang.classfile.constantpool.PoolEntry; import java.lang.constant.ClassDesc; + import static java.lang.constant.ConstantDescs.*; + import java.lang.invoke.MethodHandleInfo; import java.net.URI; import java.nio.file.FileSystem; @@ -47,12 +49,14 @@ import java.lang.classfile.*; import java.lang.classfile.attribute.*; import java.lang.classfile.components.ClassPrinter; +import java.lang.classfile.constantpool.Utf8Entry; import java.lang.constant.ModuleDesc; import jdk.internal.classfile.impl.BufWriterImpl; import jdk.internal.classfile.impl.DirectClassBuilder; import jdk.internal.classfile.impl.UnboundAttribute; import org.junit.jupiter.api.Test; + import static org.junit.jupiter.api.Assertions.*; class VerifierSelfTest { @@ -109,6 +113,11 @@ void testInvalidAttrLocation() { public void writeBody(BufWriterImpl b) { b.writeU2(0); } + + @Override + public Utf8Entry attributeName() { + return cb.constantPool().utf8Entry(Attributes.NAME_LOCAL_VARIABLE_TABLE); + } })); assertTrue(cc.verify(bytes).stream().anyMatch(e -> e.getMessage().contains("Invalid LocalVariableTable attribute location"))); } @@ -366,7 +375,7 @@ private static class CloneAttribute extends CustomAttribute { super(new AttributeMapper(){ @Override public String name() { - return a.attributeName(); + return a.attributeName().stringValue(); } @Override diff --git a/test/jdk/jdk/classfile/helpers/ClassRecord.java b/test/jdk/jdk/classfile/helpers/ClassRecord.java index e7a239015f6..c663721ec9f 100644 --- a/test/jdk/jdk/classfile/helpers/ClassRecord.java +++ b/test/jdk/jdk/classfile/helpers/ClassRecord.java @@ -234,7 +234,7 @@ public record AttributesRecord( public static AttributesRecord ofStreamingElements(Supplier> elements, ConstantPool cp, CompatibilityFilter... cf) { Map> attrs = elements.get().filter(e -> e instanceof Attribute) .map(e -> (Attribute) e) - .collect(toMap(Attribute::attributeName, e -> e)); + .collect(toMap(a -> a.attributeName().stringValue(), e -> e)); return new AttributesRecord( mapAttr(attrs, annotationDefault(), a -> ElementValueRecord.ofElementValue(a.defaultValue())), cp == null ? null : IntStream.range(0, cp.bootstrapMethodCount()).mapToObj(i -> BootstrapMethodRecord.ofBootstrapMethodEntry(cp.bootstrapMethodEntry(i))).collect(toSetOrNull()), diff --git a/test/jdk/jdk/classfile/helpers/RebuildingTransformation.java b/test/jdk/jdk/classfile/helpers/RebuildingTransformation.java index c1d9781b6ce..b0e1d6c312d 100644 --- a/test/jdk/jdk/classfile/helpers/RebuildingTransformation.java +++ b/test/jdk/jdk/classfile/helpers/RebuildingTransformation.java @@ -59,8 +59,8 @@ static byte[] transform(ClassModel clm) { case RuntimeVisibleTypeAnnotationsAttribute a -> fb.with(RuntimeVisibleTypeAnnotationsAttribute.of(transformTypeAnnotations(a.annotations(), null, null))); case SignatureAttribute a -> fb.with(SignatureAttribute.of(Signature.parseFrom(a.asTypeSignature().signatureString()))); case SyntheticAttribute a -> fb.with(SyntheticAttribute.of()); - case CustomAttribute a -> throw new AssertionError("Unexpected custom attribute: " + a.attributeName()); - case UnknownAttribute a -> throw new AssertionError("Unexpected unknown attribute: " + a.attributeName()); + case CustomAttribute a -> throw new AssertionError("Unexpected custom attribute: " + a.attributeName().stringValue()); + case UnknownAttribute a -> throw new AssertionError("Unexpected unknown attribute: " + a.attributeName().stringValue()); } } }); @@ -91,8 +91,8 @@ static byte[] transform(ClassModel clm) { case RuntimeVisibleTypeAnnotationsAttribute a -> mb.with(RuntimeVisibleTypeAnnotationsAttribute.of(transformTypeAnnotations(a.annotations(), null, null))); case SignatureAttribute a -> mb.with(SignatureAttribute.of(MethodSignature.parseFrom(a.asMethodSignature().signatureString()))); case SyntheticAttribute a -> mb.with(SyntheticAttribute.of()); - case CustomAttribute a -> throw new AssertionError("Unexpected custom attribute: " + a.attributeName()); - case UnknownAttribute a -> throw new AssertionError("Unexpected unknown attribute: " + a.attributeName()); + case CustomAttribute a -> throw new AssertionError("Unexpected custom attribute: " + a.attributeName().stringValue()); + case UnknownAttribute a -> throw new AssertionError("Unexpected unknown attribute: " + a.attributeName().stringValue()); } } }); @@ -131,7 +131,7 @@ static byte[] transform(ClassModel clm) { case RuntimeVisibleAnnotationsAttribute rvaa -> rcac.accept(RuntimeVisibleAnnotationsAttribute.of(transformAnnotations(rvaa.annotations()))); case RuntimeVisibleTypeAnnotationsAttribute rvtaa -> rcac.accept(RuntimeVisibleTypeAnnotationsAttribute.of(transformTypeAnnotations(rvtaa.annotations(), null, null))); case SignatureAttribute sa -> rcac.accept(SignatureAttribute.of(Signature.parseFrom(sa.asTypeSignature().signatureString()))); - default -> throw new AssertionError("Unexpected record component attribute: " + rca.attributeName()); + default -> throw new AssertionError("Unexpected record component attribute: " + rca.attributeName().stringValue()); }}).toArray(Attribute[]::new))).toArray(RecordComponentInfo[]::new))); case RuntimeInvisibleAnnotationsAttribute a -> clb.with(RuntimeInvisibleAnnotationsAttribute.of(transformAnnotations(a.annotations()))); case RuntimeInvisibleTypeAnnotationsAttribute a -> clb.with(RuntimeInvisibleTypeAnnotationsAttribute.of(transformTypeAnnotations(a.annotations(), null, null))); @@ -142,8 +142,8 @@ static byte[] transform(ClassModel clm) { case SourceFileAttribute a -> clb.with(SourceFileAttribute.of(a.sourceFile().stringValue())); case SourceIDAttribute a -> clb.with(SourceIDAttribute.of(a.sourceId().stringValue())); case SyntheticAttribute a -> clb.with(SyntheticAttribute.of()); - case CustomAttribute a -> throw new AssertionError("Unexpected custom attribute: " + a.attributeName()); - case UnknownAttribute a -> throw new AssertionError("Unexpected unknown attribute: " + a.attributeName()); + case CustomAttribute a -> throw new AssertionError("Unexpected custom attribute: " + a.attributeName().stringValue()); + case UnknownAttribute a -> throw new AssertionError("Unexpected unknown attribute: " + a.attributeName().stringValue()); } } }); @@ -595,7 +595,7 @@ else switch (i.constantValue()) { transformFrameTypeInfos(fr.locals(), cob, labels), transformFrameTypeInfos(fr.stack(), cob, labels))).toList())); case CustomAttribute a -> - throw new AssertionError("Unexpected custom attribute: " + a.attributeName()); + throw new AssertionError("Unexpected custom attribute: " + a.attributeName().stringValue()); } } } diff --git a/test/langtools/tools/javac/classfiles/attributes/AnnotationDefault/AnnotationDefaultTest.java b/test/langtools/tools/javac/classfiles/attributes/AnnotationDefault/AnnotationDefaultTest.java index d9a3320ecc2..2911e58820f 100644 --- a/test/langtools/tools/javac/classfiles/attributes/AnnotationDefault/AnnotationDefaultTest.java +++ b/test/langtools/tools/javac/classfiles/attributes/AnnotationDefault/AnnotationDefaultTest.java @@ -88,7 +88,7 @@ private void test(String template, Map replacements, boolean has checkEquals(countNumberOfAttributes(method.attributes()), 1L, "Number of AnnotationDefault attribute"); - checkEquals(attr.attributeName(), + checkEquals(attr.attributeName().stringValue(), "AnnotationDefault", "attribute_name_index"); ExpectedValues expectedValue = expectedValues.get(methodName); diff --git a/test/langtools/tools/javac/classfiles/attributes/EnclosingMethod/EnclosingMethodTest.java b/test/langtools/tools/javac/classfiles/attributes/EnclosingMethod/EnclosingMethodTest.java index f15771840f5..924916f5cbd 100644 --- a/test/langtools/tools/javac/classfiles/attributes/EnclosingMethod/EnclosingMethodTest.java +++ b/test/langtools/tools/javac/classfiles/attributes/EnclosingMethod/EnclosingMethodTest.java @@ -169,7 +169,7 @@ private void testEnclosingMethodAttribute() { // stop checking, attr is null. test case failed return; } - checkEquals(attr.attributeName(), + checkEquals(attr.attributeName().stringValue(), "EnclosingMethod", "attribute_name_index of EnclosingMethod attribute in the class : " + className); checkEquals(((BoundAttribute)attr).payloadLen(), 4, diff --git a/test/langtools/tools/javac/classfiles/attributes/LineNumberTable/LineNumberTestBase.java b/test/langtools/tools/javac/classfiles/attributes/LineNumberTable/LineNumberTestBase.java index be4a5aaea91..531d5e617d0 100644 --- a/test/langtools/tools/javac/classfiles/attributes/LineNumberTable/LineNumberTestBase.java +++ b/test/langtools/tools/javac/classfiles/attributes/LineNumberTable/LineNumberTestBase.java @@ -138,7 +138,7 @@ private void verifyCoveredLines(Set actualCoveredLines, TestCase.Method private > int countAttributes(AttributeMapper attr, AttributedElement attributedElement) { int i = 0; for (Attribute attribute : attributedElement.attributes()) { - if (attribute.attributeName().equals(attr.name())) { + if (attribute.attributeName().equalsString(attr.name())) { i++; } } diff --git a/test/langtools/tools/javac/classfiles/attributes/Signature/Driver.java b/test/langtools/tools/javac/classfiles/attributes/Signature/Driver.java index 72f7d2a6b9b..7b75ffa5f9c 100644 --- a/test/langtools/tools/javac/classfiles/attributes/Signature/Driver.java +++ b/test/langtools/tools/javac/classfiles/attributes/Signature/Driver.java @@ -219,7 +219,7 @@ private void testAttribute( SignatureAttribute attribute = sup.get(); if (expectedSignature != null && checkNotNull(attribute, memberName + " must have attribute")) { - checkEquals(attribute.attributeName(), + checkEquals(attribute.attributeName().stringValue(), "Signature", "Attribute's name : " + memberName); checkEquals(((BoundAttribute)attribute).payloadLen(), 2, "Attribute's length : " + memberName); checkEquals(attribute.signature().stringValue(), diff --git a/test/langtools/tools/javac/classfiles/attributes/SourceFile/SourceFileTestBase.java b/test/langtools/tools/javac/classfiles/attributes/SourceFile/SourceFileTestBase.java index 52d53f9dce4..0d81fc2c282 100644 --- a/test/langtools/tools/javac/classfiles/attributes/SourceFile/SourceFileTestBase.java +++ b/test/langtools/tools/javac/classfiles/attributes/SourceFile/SourceFileTestBase.java @@ -108,7 +108,7 @@ private void assertAttributePresent(ClassModel classFile, String fileName) throw SourceFileAttribute attribute = sourceFileAttributes.get(0); - assertEquals(attribute.attributeName(), Attributes.sourceFile().name(), "Incorrect attribute name"); + assertEquals(attribute.attributeName().stringValue(), Attributes.sourceFile().name(), "Incorrect attribute name"); assertEquals(attribute.sourceFile().stringValue(), fileName, "Incorrect source file name"); assertEquals(((BoundAttribute)attribute).payloadLen(), 2, "Incorrect attribute length"); diff --git a/test/langtools/tools/javac/classfiles/attributes/deprecated/DeprecatedTest.java b/test/langtools/tools/javac/classfiles/attributes/deprecated/DeprecatedTest.java index 425760ea137..6467f3d8027 100644 --- a/test/langtools/tools/javac/classfiles/attributes/deprecated/DeprecatedTest.java +++ b/test/langtools/tools/javac/classfiles/attributes/deprecated/DeprecatedTest.java @@ -302,7 +302,7 @@ private void testDeprecatedAttribute(String name, DeprecatedAttribute attr, Clas if (checkNotNull(attr, name + " must have deprecated attribute")) { checkEquals(0, ((BoundAttribute)attr).payloadLen(), "attribute_length should equal to 0"); - checkEquals("Deprecated", attr.attributeName(), + checkEquals("Deprecated", attr.attributeName().stringValue(), name + " attribute_name_index"); } } diff --git a/test/langtools/tools/javac/classfiles/attributes/innerclasses/InnerClassesTestBase.java b/test/langtools/tools/javac/classfiles/attributes/innerclasses/InnerClassesTestBase.java index 26972de3544..aa46d8a9b9d 100644 --- a/test/langtools/tools/javac/classfiles/attributes/innerclasses/InnerClassesTestBase.java +++ b/test/langtools/tools/javac/classfiles/attributes/innerclasses/InnerClassesTestBase.java @@ -206,7 +206,7 @@ private void test(String classToTest, TestCase test, String...skipClasses) { if (!checkNotNull(innerClasses, "InnerClasses attribute should not be null")) { return; } - checkEquals(innerClasses.attributeName(), "InnerClasses", + checkEquals(innerClasses.attributeName().stringValue(), "InnerClasses", "innerClasses.attribute_name_index"); // Inner Classes attribute consists of length (2 bytes) // and 8 bytes for each inner class's entry. diff --git a/test/langtools/tools/javac/sealed/CheckSubtypesOfSealedTest.java b/test/langtools/tools/javac/sealed/CheckSubtypesOfSealedTest.java index 0366d4982ca..0f9634423ec 100644 --- a/test/langtools/tools/javac/sealed/CheckSubtypesOfSealedTest.java +++ b/test/langtools/tools/javac/sealed/CheckSubtypesOfSealedTest.java @@ -76,7 +76,7 @@ enum CheckFor { void check(ClassModel classFile) throws Exception { boolean found = false; for (Attribute attr: classFile.attributes()) { - if (attr.attributeName().equals("PermittedSubclasses")) { + if (attr.attributeName().equalsString("PermittedSubclasses")) { PermittedSubclassesAttribute permittedSubclasses = (PermittedSubclassesAttribute)attr; found = true; if (permittedSubclasses.permittedSubclasses().isEmpty()) { @@ -99,7 +99,7 @@ void check(ClassModel classFile) throws Exception { NOT_SEALED { void check(ClassModel classFile) throws Exception { for (Attribute attr: classFile.attributes()) { - if (attr.attributeName().equals("PermittedSubclasses")) { + if (attr.attributeName().equalsString("PermittedSubclasses")) { throw new AssertionError(classFile.thisClass().name() + " should not be sealed"); } } diff --git a/test/langtools/tools/javap/T6716452.java b/test/langtools/tools/javap/T6716452.java index 63ccead52e7..20c382918c3 100644 --- a/test/langtools/tools/javap/T6716452.java +++ b/test/langtools/tools/javap/T6716452.java @@ -70,7 +70,7 @@ > void test(MethodModel mm, AttributeMapper attr, Clas if (!c.isAssignableFrom(mm.attributes().get(index).getClass())) { error(mm + ": unexpected attribute found," + " expected " + c.getName() - + " found " + mm.attributes().get(index).attributeName()); + + " found " + mm.attributes().get(index).attributeName().stringValue()); } } else { error(mm + ": expected attribute " + attr.name() + " not found"); From 5e2760856c3844d9ad6200fef0c09ece0acac73a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eirik=20Bj=C3=B8rsn=C3=B8s?= Date: Fri, 15 Nov 2024 12:18:53 +0000 Subject: [PATCH 013/311] 8344188: Cleanup sun.net.www.protocol.jar.JarFileFactory after JEP 486 integration Reviewed-by: jpai, dfuchs --- .../net/www/protocol/jar/JarFileFactory.java | 43 +------------------ 1 file changed, 1 insertion(+), 42 deletions(-) diff --git a/src/java.base/share/classes/sun/net/www/protocol/jar/JarFileFactory.java b/src/java.base/share/classes/sun/net/www/protocol/jar/JarFileFactory.java index 17ca43d4ace..9afbea8bf76 100644 --- a/src/java.base/share/classes/sun/net/www/protocol/jar/JarFileFactory.java +++ b/src/java.base/share/classes/sun/net/www/protocol/jar/JarFileFactory.java @@ -31,7 +31,6 @@ import java.net.URLConnection; import java.util.HashMap; import java.util.jar.JarFile; -import java.security.Permission; import jdk.internal.util.OperatingSystem; import sun.net.util.URLUtil; @@ -219,35 +218,7 @@ public void close(JarFile jarFile) { private JarFile getCachedJarFile(URL url) { assert Thread.holdsLock(instance); - JarFile result = fileCache.get(urlKey(url)); - - /* if the JAR file is cached, the permission will always be there */ - if (result != null) { - @SuppressWarnings("removal") - SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - Permission perm = getPermission(result); - if (perm != null) { - try { - sm.checkPermission(perm); - } catch (SecurityException se) { - // fallback to checkRead/checkConnect for pre 1.2 - // security managers - if ((perm instanceof java.io.FilePermission) && - perm.getActions().contains("read")) { - sm.checkRead(perm.getName()); - } else if ((perm instanceof - java.net.SocketPermission) && - perm.getActions().contains("connect")) { - sm.checkConnect(url.getHost(), url.getPort()); - } else { - throw se; - } - } - } - } - } - return result; + return fileCache.get(urlKey(url)); } private String urlKey(URL url) { @@ -255,16 +226,4 @@ private String urlKey(URL url) { if ("runtime".equals(url.getRef())) urlstr += "#runtime"; return urlstr; } - - private Permission getPermission(JarFile jarFile) { - try { - URLConnection uc = getConnection(jarFile); - if (uc != null) - return uc.getPermission(); - } catch (IOException ioe) { - // gulp - } - - return null; - } } From 3245f56e53792b3cfc9788799ba1594d6af15bea Mon Sep 17 00:00:00 2001 From: Amit Kumar Date: Fri, 15 Nov 2024 12:45:48 +0000 Subject: [PATCH 014/311] 8344164: [s390x] ProblemList hotspot/jtreg/runtime/NMT/VirtualAllocCommitMerge.java Reviewed-by: lucy --- test/hotspot/jtreg/ProblemList.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/test/hotspot/jtreg/ProblemList.txt b/test/hotspot/jtreg/ProblemList.txt index a74b716f75d..ba1851708b2 100644 --- a/test/hotspot/jtreg/ProblemList.txt +++ b/test/hotspot/jtreg/ProblemList.txt @@ -116,6 +116,7 @@ runtime/cds/appcds/customLoader/HelloCustom_JFR.java 8241075 linux-all,windows-x runtime/Dictionary/CleanProtectionDomain.java 8341916 generic-all runtime/Dictionary/ProtectionDomainCacheTest.java 8341916 generic-all runtime/logging/ProtectionDomainVerificationTest.java 8341916 generic-all +runtime/NMT/VirtualAllocCommitMerge.java 8309698 linux-s390x # Fails with +UseCompactObjectHeaders on aarch64 runtime/cds/appcds/SharedBaseAddress.java 8340212 linux-aarch64,macosx-aarch64 From a672138aa7cb61c4f905de365628c0bbed6901ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20Gr=C3=B6nlund?= Date: Fri, 15 Nov 2024 13:38:52 +0000 Subject: [PATCH 015/311] 8344161: Argument type mismatch for jfr_type_id Reviewed-by: kbarrett --- src/hotspot/share/jfr/jni/jfrJniMethod.cpp | 2 +- src/hotspot/share/jfr/jni/jfrJniMethod.hpp | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/hotspot/share/jfr/jni/jfrJniMethod.cpp b/src/hotspot/share/jfr/jni/jfrJniMethod.cpp index d60baa3c1cc..143248ef714 100644 --- a/src/hotspot/share/jfr/jni/jfrJniMethod.cpp +++ b/src/hotspot/share/jfr/jni/jfrJniMethod.cpp @@ -169,7 +169,7 @@ NO_TRANSITION(jboolean, jfr_set_throttle(JNIEnv* env, jclass jvm, jlong event_ty return JNI_TRUE; NO_TRANSITION_END -NO_TRANSITION(void, jfr_set_miscellaneous(JNIEnv* env, jobject jvm, jlong event_type_id, jlong value)) +NO_TRANSITION(void, jfr_set_miscellaneous(JNIEnv* env, jclass jvm, jlong event_type_id, jlong value)) JfrEventSetting::set_miscellaneous(event_type_id, value); const JfrEventId typed_event_id = (JfrEventId)event_type_id; if (EventDeprecatedInvocation::eventId == typed_event_id) { diff --git a/src/hotspot/share/jfr/jni/jfrJniMethod.hpp b/src/hotspot/share/jfr/jni/jfrJniMethod.hpp index ece4425782d..5020920945e 100644 --- a/src/hotspot/share/jfr/jni/jfrJniMethod.hpp +++ b/src/hotspot/share/jfr/jni/jfrJniMethod.hpp @@ -101,7 +101,7 @@ jboolean JNICALL jfr_is_available(JNIEnv* env, jclass jvm); jdouble JNICALL jfr_time_conv_factor(JNIEnv* env, jclass jvm); -jlong JNICALL jfr_type_id(JNIEnv* env, jobject jvm, jclass jc); +jlong JNICALL jfr_type_id(JNIEnv* env, jclass jvm, jclass jc); void JNICALL jfr_set_repository_location(JNIEnv* env, jclass jvm, jstring location); @@ -129,7 +129,7 @@ jlong JNICALL jfr_get_unloaded_event_classes_count(JNIEnv* env, jclass jvm); jboolean JNICALL jfr_set_throttle(JNIEnv* env, jclass jvm, jlong event_type_id, jlong event_sample_size, jlong period_ms); -void JNICALL jfr_set_miscellaneous(JNIEnv* env, jobject jvm, jlong id, jlong value); +void JNICALL jfr_set_miscellaneous(JNIEnv* env, jclass jvm, jlong id, jlong value); void JNICALL jfr_emit_old_object_samples(JNIEnv* env, jclass jvm, jlong cutoff_ticks, jboolean, jboolean); From 6cdebf0e4ce274fcaaff0bad292d467e31d698d8 Mon Sep 17 00:00:00 2001 From: Sonia Zaldana Calles Date: Fri, 15 Nov 2024 14:07:32 +0000 Subject: [PATCH 016/311] 8343599: Kmem limit and max values swapped when printing container information Reviewed-by: sjohanss, sgehwolf --- src/hotspot/os/linux/cgroupV1Subsystem_linux.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/hotspot/os/linux/cgroupV1Subsystem_linux.cpp b/src/hotspot/os/linux/cgroupV1Subsystem_linux.cpp index 388ee5c6ea0..a6ac2822b25 100644 --- a/src/hotspot/os/linux/cgroupV1Subsystem_linux.cpp +++ b/src/hotspot/os/linux/cgroupV1Subsystem_linux.cpp @@ -300,9 +300,9 @@ void CgroupV1MemoryController::print_version_specific_info(outputStream* st, jul jlong kmem_limit = kernel_memory_limit_in_bytes(phys_mem); jlong kmem_max_usage = kernel_memory_max_usage_in_bytes(); + OSContainer::print_container_helper(st, kmem_limit, "kernel_memory_limit_in_bytes"); OSContainer::print_container_helper(st, kmem_usage, "kernel_memory_usage_in_bytes"); - OSContainer::print_container_helper(st, kmem_limit, "kernel_memory_max_usage_in_bytes"); - OSContainer::print_container_helper(st, kmem_max_usage, "kernel_memory_limit_in_bytes"); + OSContainer::print_container_helper(st, kmem_max_usage, "kernel_memory_max_usage_in_bytes"); } char* CgroupV1Subsystem::cpu_cpuset_cpus() { From 84ffb64cd73f8af11cf3670c6f19d282c2ac6961 Mon Sep 17 00:00:00 2001 From: Adam Sotona Date: Fri, 15 Nov 2024 14:38:17 +0000 Subject: [PATCH 017/311] 8334714: Implement JEP 484: Class-File API Reviewed-by: liach, vromero --- .../java/lang/classfile/AccessFlags.java | 4 +- .../java/lang/classfile/Annotation.java | 4 +- .../lang/classfile/AnnotationElement.java | 4 +- .../java/lang/classfile/AnnotationValue.java | 46 ++++++----------- .../java/lang/classfile/Attribute.java | 4 +- .../java/lang/classfile/AttributeMapper.java | 8 +-- .../lang/classfile/AttributedElement.java | 4 +- .../java/lang/classfile/Attributes.java | 42 +--------------- .../lang/classfile/BootstrapMethodEntry.java | 4 +- .../java/lang/classfile/BufWriter.java | 4 +- .../java/lang/classfile/ClassBuilder.java | 4 +- .../java/lang/classfile/ClassElement.java | 7 +-- .../java/lang/classfile/ClassFile.java | 47 ++++++------------ .../java/lang/classfile/ClassFileBuilder.java | 4 +- .../java/lang/classfile/ClassFileElement.java | 5 +- .../lang/classfile/ClassFileTransform.java | 5 +- .../java/lang/classfile/ClassFileVersion.java | 6 +-- .../classfile/ClassHierarchyResolver.java | 7 +-- .../java/lang/classfile/ClassModel.java | 4 +- .../java/lang/classfile/ClassReader.java | 5 +- .../java/lang/classfile/ClassSignature.java | 12 +---- .../java/lang/classfile/ClassTransform.java | 4 +- .../java/lang/classfile/CodeBuilder.java | 24 ++------- .../java/lang/classfile/CodeElement.java | 7 +-- .../java/lang/classfile/CodeModel.java | 4 +- .../java/lang/classfile/CodeTransform.java | 4 +- .../java/lang/classfile/CompoundElement.java | 5 +- .../java/lang/classfile/CustomAttribute.java | 4 +- .../java/lang/classfile/FieldBuilder.java | 4 +- .../java/lang/classfile/FieldElement.java | 7 +-- .../java/lang/classfile/FieldModel.java | 4 +- .../java/lang/classfile/FieldTransform.java | 4 +- .../java/lang/classfile/Instruction.java | 6 +-- .../java/lang/classfile/Interfaces.java | 6 +-- .../classes/java/lang/classfile/Label.java | 6 +-- .../java/lang/classfile/MethodBuilder.java | 4 +- .../java/lang/classfile/MethodElement.java | 7 +-- .../java/lang/classfile/MethodModel.java | 4 +- .../java/lang/classfile/MethodSignature.java | 4 +- .../java/lang/classfile/MethodTransform.java | 4 +- .../classes/java/lang/classfile/Opcode.java | 7 +-- .../lang/classfile/PseudoInstruction.java | 6 +-- .../java/lang/classfile/Signature.java | 42 +++++----------- .../java/lang/classfile/Superclass.java | 6 +-- .../java/lang/classfile/TypeAnnotation.java | 49 ++++++------------- .../classes/java/lang/classfile/TypeKind.java | 6 +-- .../attribute/AnnotationDefaultAttribute.java | 4 +- .../attribute/BootstrapMethodsAttribute.java | 4 +- .../attribute/CharacterRangeInfo.java | 4 +- .../CharacterRangeTableAttribute.java | 6 +-- .../classfile/attribute/CodeAttribute.java | 4 +- .../attribute/CompilationIDAttribute.java | 6 +-- .../attribute/ConstantValueAttribute.java | 4 +- .../attribute/DeprecatedAttribute.java | 4 +- .../attribute/EnclosingMethodAttribute.java | 4 +- .../attribute/ExceptionsAttribute.java | 4 +- .../classfile/attribute/InnerClassInfo.java | 6 +-- .../attribute/InnerClassesAttribute.java | 4 +- .../classfile/attribute/LineNumberInfo.java | 6 +-- .../attribute/LineNumberTableAttribute.java | 4 +- .../attribute/LocalVariableInfo.java | 6 +-- .../LocalVariableTableAttribute.java | 4 +- .../attribute/LocalVariableTypeInfo.java | 6 +-- .../LocalVariableTypeTableAttribute.java | 4 +- .../attribute/MethodParameterInfo.java | 6 +-- .../attribute/MethodParametersAttribute.java | 4 +- .../classfile/attribute/ModuleAttribute.java | 7 +-- .../classfile/attribute/ModuleExportInfo.java | 6 +-- .../classfile/attribute/ModuleHashInfo.java | 6 +-- .../attribute/ModuleHashesAttribute.java | 6 +-- .../attribute/ModuleMainClassAttribute.java | 4 +- .../classfile/attribute/ModuleOpenInfo.java | 6 +-- .../attribute/ModulePackagesAttribute.java | 4 +- .../attribute/ModuleProvideInfo.java | 6 +-- .../attribute/ModuleRequireInfo.java | 6 +-- .../attribute/ModuleResolutionAttribute.java | 6 +-- .../attribute/ModuleTargetAttribute.java | 6 +-- .../attribute/NestHostAttribute.java | 4 +- .../attribute/NestMembersAttribute.java | 4 +- .../PermittedSubclassesAttribute.java | 4 +- .../classfile/attribute/RecordAttribute.java | 4 +- .../attribute/RecordComponentInfo.java | 6 +-- .../RuntimeInvisibleAnnotationsAttribute.java | 4 +- ...nvisibleParameterAnnotationsAttribute.java | 4 +- ...timeInvisibleTypeAnnotationsAttribute.java | 4 +- .../RuntimeVisibleAnnotationsAttribute.java | 4 +- ...eVisibleParameterAnnotationsAttribute.java | 4 +- ...untimeVisibleTypeAnnotationsAttribute.java | 4 +- .../attribute/SignatureAttribute.java | 4 +- .../SourceDebugExtensionAttribute.java | 6 +-- .../attribute/SourceFileAttribute.java | 4 +- .../attribute/SourceIDAttribute.java | 6 +-- .../attribute/StackMapFrameInfo.java | 16 ++---- .../attribute/StackMapTableAttribute.java | 4 +- .../attribute/SyntheticAttribute.java | 4 +- .../classfile/attribute/UnknownAttribute.java | 6 +-- .../classfile/attribute/package-info.java | 6 +-- .../classfile/components/ClassPrinter.java | 21 +++----- .../classfile/components/ClassRemapper.java | 4 +- .../components/CodeLocalsShifter.java | 6 +-- .../classfile/components/CodeRelabeler.java | 4 +- .../components/CodeStackTracker.java | 4 +- .../classfile/components/package-info.java | 6 +-- .../AnnotationConstantValueEntry.java | 5 +- .../classfile/constantpool/ClassEntry.java | 6 +-- .../constantpool/ConstantDynamicEntry.java | 6 +-- .../classfile/constantpool/ConstantPool.java | 6 +-- .../constantpool/ConstantPoolBuilder.java | 4 +- .../constantpool/ConstantPoolException.java | 6 +-- .../constantpool/ConstantValueEntry.java | 5 +- .../classfile/constantpool/DoubleEntry.java | 4 +- .../DynamicConstantPoolEntry.java | 7 +-- .../classfile/constantpool/FieldRefEntry.java | 6 +-- .../classfile/constantpool/FloatEntry.java | 4 +- .../classfile/constantpool/IntegerEntry.java | 4 +- .../constantpool/InterfaceMethodRefEntry.java | 6 +-- .../constantpool/InvokeDynamicEntry.java | 6 +-- .../constantpool/LoadableConstantEntry.java | 5 +- .../classfile/constantpool/LongEntry.java | 4 +- .../constantpool/MemberRefEntry.java | 6 +-- .../constantpool/MethodHandleEntry.java | 4 +- .../constantpool/MethodRefEntry.java | 6 +-- .../constantpool/MethodTypeEntry.java | 6 +-- .../classfile/constantpool/ModuleEntry.java | 6 +-- .../constantpool/NameAndTypeEntry.java | 6 +-- .../classfile/constantpool/PackageEntry.java | 6 +-- .../classfile/constantpool/PoolEntry.java | 5 +- .../classfile/constantpool/StringEntry.java | 6 +-- .../classfile/constantpool/Utf8Entry.java | 6 +-- .../classfile/constantpool/package-info.java | 6 +-- .../instruction/ArrayLoadInstruction.java | 4 +- .../instruction/ArrayStoreInstruction.java | 4 +- .../instruction/BranchInstruction.java | 6 +-- .../classfile/instruction/CharacterRange.java | 4 +- .../instruction/ConstantInstruction.java | 13 ++--- .../instruction/ConvertInstruction.java | 6 +-- .../instruction/DiscontinuedInstruction.java | 10 ++-- .../classfile/instruction/ExceptionCatch.java | 6 +-- .../instruction/FieldInstruction.java | 6 +-- .../instruction/IncrementInstruction.java | 6 +-- .../instruction/InvokeDynamicInstruction.java | 6 +-- .../instruction/InvokeInstruction.java | 4 +- .../classfile/instruction/LabelTarget.java | 6 +-- .../classfile/instruction/LineNumber.java | 6 +-- .../instruction/LoadInstruction.java | 6 +-- .../classfile/instruction/LocalVariable.java | 4 +- .../instruction/LocalVariableType.java | 4 +- .../instruction/LookupSwitchInstruction.java | 6 +-- .../instruction/MonitorInstruction.java | 6 +-- .../instruction/NewMultiArrayInstruction.java | 6 +-- .../instruction/NewObjectInstruction.java | 6 +-- .../NewPrimitiveArrayInstruction.java | 4 +- .../NewReferenceArrayInstruction.java | 6 +-- .../classfile/instruction/NopInstruction.java | 6 +-- .../instruction/OperatorInstruction.java | 6 +-- .../instruction/ReturnInstruction.java | 6 +-- .../instruction/StackInstruction.java | 6 +-- .../instruction/StoreInstruction.java | 6 +-- .../classfile/instruction/SwitchCase.java | 6 +-- .../instruction/TableSwitchInstruction.java | 6 +-- .../instruction/ThrowInstruction.java | 6 +-- .../instruction/TypeCheckInstruction.java | 6 +-- .../classfile/instruction/package-info.java | 6 +-- .../java/lang/classfile/package-info.java | 5 +- .../jdk/internal/javac/PreviewFeature.java | 2 - 165 files changed, 312 insertions(+), 799 deletions(-) diff --git a/src/java.base/share/classes/java/lang/classfile/AccessFlags.java b/src/java.base/share/classes/java/lang/classfile/AccessFlags.java index 4abe17c1cf5..b1d026f52e4 100644 --- a/src/java.base/share/classes/java/lang/classfile/AccessFlags.java +++ b/src/java.base/share/classes/java/lang/classfile/AccessFlags.java @@ -28,16 +28,14 @@ import java.util.Set; import jdk.internal.classfile.impl.AccessFlagsImpl; -import jdk.internal.javac.PreviewFeature; /** * Models the access flags for a class, method, or field. Delivered as a * {@link ClassElement}, {@link FieldElement}, or {@link MethodElement} * when traversing the corresponding model type. * - * @since 22 + * @since 24 */ -@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) public sealed interface AccessFlags extends ClassElement, MethodElement, FieldElement permits AccessFlagsImpl { diff --git a/src/java.base/share/classes/java/lang/classfile/Annotation.java b/src/java.base/share/classes/java/lang/classfile/Annotation.java index 4f222084cb7..98b6ea783d5 100644 --- a/src/java.base/share/classes/java/lang/classfile/Annotation.java +++ b/src/java.base/share/classes/java/lang/classfile/Annotation.java @@ -35,7 +35,6 @@ import jdk.internal.classfile.impl.AnnotationImpl; import jdk.internal.classfile.impl.TemporaryConstantPool; import jdk.internal.classfile.impl.Util; -import jdk.internal.javac.PreviewFeature; /** * Models an {@code annotation} structure (JVMS {@jvms 4.7.16}) or part of a {@code @@ -63,9 +62,8 @@ * @see RuntimeVisibleParameterAnnotationsAttribute * @see RuntimeInvisibleParameterAnnotationsAttribute * - * @since 22 + * @since 24 */ -@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) public sealed interface Annotation permits AnnotationImpl { diff --git a/src/java.base/share/classes/java/lang/classfile/AnnotationElement.java b/src/java.base/share/classes/java/lang/classfile/AnnotationElement.java index 7c4283c49bf..4381bb9733a 100644 --- a/src/java.base/share/classes/java/lang/classfile/AnnotationElement.java +++ b/src/java.base/share/classes/java/lang/classfile/AnnotationElement.java @@ -29,7 +29,6 @@ import jdk.internal.classfile.impl.AnnotationImpl; import jdk.internal.classfile.impl.TemporaryConstantPool; -import jdk.internal.javac.PreviewFeature; /** * Models an element-value pair in the {@code element_value_pairs} @@ -43,9 +42,8 @@ * @see Annotation * @see AnnotationValue * - * @since 22 + * @since 24 */ -@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) public sealed interface AnnotationElement permits AnnotationImpl.AnnotationElementImpl { diff --git a/src/java.base/share/classes/java/lang/classfile/AnnotationValue.java b/src/java.base/share/classes/java/lang/classfile/AnnotationValue.java index e1e91f2c9ed..8e92ef59a50 100644 --- a/src/java.base/share/classes/java/lang/classfile/AnnotationValue.java +++ b/src/java.base/share/classes/java/lang/classfile/AnnotationValue.java @@ -33,7 +33,6 @@ import jdk.internal.classfile.impl.AnnotationImpl; import jdk.internal.classfile.impl.TemporaryConstantPool; import jdk.internal.classfile.impl.Util; -import jdk.internal.javac.PreviewFeature; import static java.util.Objects.requireNonNull; @@ -48,18 +47,16 @@ * @see AnnotationElement * * @sealedGraph - * @since 22 + * @since 24 */ -@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) public sealed interface AnnotationValue { /** * Models an annotation value of an element-value pair. * The {@linkplain #tag tag} of this value is {@value TAG_ANNOTATION}. * - * @since 22 + * @since 24 */ - @PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) sealed interface OfAnnotation extends AnnotationValue permits AnnotationImpl.OfAnnotationImpl { /** {@return the annotation value} */ @@ -70,9 +67,8 @@ sealed interface OfAnnotation extends AnnotationValue * Models an array value of an element-value pair. * The {@linkplain #tag tag} of this value is {@value TAG_ARRAY}. * - * @since 22 + * @since 24 */ - @PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) sealed interface OfArray extends AnnotationValue permits AnnotationImpl.OfArrayImpl { /** @@ -91,9 +87,8 @@ sealed interface OfArray extends AnnotationValue * Models a constant value of an element-value pair. * * @sealedGraph - * @since 22 + * @since 24 */ - @PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) sealed interface OfConstant extends AnnotationValue { /** * {@return the constant pool entry backing this constant element} @@ -128,9 +123,8 @@ sealed interface OfConstant extends AnnotationValue { * Models a string value of an element-value pair. * The {@linkplain #tag tag} of this value is {@value TAG_STRING}. * - * @since 22 + * @since 24 */ - @PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) sealed interface OfString extends OfConstant permits AnnotationImpl.OfStringImpl { /** {@return the backing UTF8 entry} */ @@ -156,9 +150,8 @@ default String resolvedValue() { * Models a double value of an element-value pair. * The {@linkplain #tag tag} of this value is {@value TAG_DOUBLE}. * - * @since 22 + * @since 24 */ - @PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) sealed interface OfDouble extends OfConstant permits AnnotationImpl.OfDoubleImpl { /** {@return the backing double entry} */ @@ -184,9 +177,8 @@ default Double resolvedValue() { * Models a float value of an element-value pair. * The {@linkplain #tag tag} of this value is {@value TAG_FLOAT}. * - * @since 22 + * @since 24 */ - @PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) sealed interface OfFloat extends OfConstant permits AnnotationImpl.OfFloatImpl { /** {@return the backing float entry} */ @@ -212,9 +204,8 @@ default Float resolvedValue() { * Models a long value of an element-value pair. * The {@linkplain #tag tag} of this value is {@value TAG_LONG}. * - * @since 22 + * @since 24 */ - @PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) sealed interface OfLong extends OfConstant permits AnnotationImpl.OfLongImpl { /** {@return the backing long entry} */ @@ -240,9 +231,8 @@ default Long resolvedValue() { * Models an int value of an element-value pair. * The {@linkplain #tag tag} of this value is {@value TAG_INT}. * - * @since 22 + * @since 24 */ - @PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) sealed interface OfInt extends OfConstant permits AnnotationImpl.OfIntImpl { /** {@return the backing integer entry} */ @@ -268,9 +258,8 @@ default Integer resolvedValue() { * Models a short value of an element-value pair. * The {@linkplain #tag tag} of this value is {@value TAG_SHORT}. * - * @since 22 + * @since 24 */ - @PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) sealed interface OfShort extends OfConstant permits AnnotationImpl.OfShortImpl { /** {@return the backing integer entry} */ @@ -299,9 +288,8 @@ default Short resolvedValue() { * Models a char value of an element-value pair. * The {@linkplain #tag tag} of this value is {@value TAG_CHAR}. * - * @since 22 + * @since 24 */ - @PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) sealed interface OfChar extends OfConstant permits AnnotationImpl.OfCharImpl { /** {@return the backing integer entry} */ @@ -330,9 +318,8 @@ default Character resolvedValue() { * Models a byte value of an element-value pair. * The {@linkplain #tag tag} of this value is {@value TAG_BYTE}. * - * @since 22 + * @since 24 */ - @PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) sealed interface OfByte extends OfConstant permits AnnotationImpl.OfByteImpl { /** {@return the backing integer entry} */ @@ -361,9 +348,8 @@ default Byte resolvedValue() { * Models a boolean value of an element-value pair. * The {@linkplain #tag tag} of this value is {@value TAG_BOOLEAN}. * - * @since 22 + * @since 24 */ - @PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) sealed interface OfBoolean extends OfConstant permits AnnotationImpl.OfBooleanImpl { /** {@return the backing integer entry} */ @@ -392,9 +378,8 @@ default Boolean resolvedValue() { * Models a class value of an element-value pair. * The {@linkplain #tag tag} of this value is {@value TAG_CLASS}. * - * @since 22 + * @since 24 */ - @PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) sealed interface OfClass extends AnnotationValue permits AnnotationImpl.OfClassImpl { /** {@return the class descriptor string} */ @@ -410,9 +395,8 @@ default ClassDesc classSymbol() { * Models an enum value of an element-value pair. * The {@linkplain #tag tag} of this value is {@value TAG_ENUM}. * - * @since 22 + * @since 24 */ - @PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) sealed interface OfEnum extends AnnotationValue permits AnnotationImpl.OfEnumImpl { /** {@return the enum class descriptor string} */ diff --git a/src/java.base/share/classes/java/lang/classfile/Attribute.java b/src/java.base/share/classes/java/lang/classfile/Attribute.java index 2d559552684..bb5c7bdf8ea 100644 --- a/src/java.base/share/classes/java/lang/classfile/Attribute.java +++ b/src/java.base/share/classes/java/lang/classfile/Attribute.java @@ -29,7 +29,6 @@ import jdk.internal.classfile.impl.BoundAttribute; import jdk.internal.classfile.impl.UnboundAttribute; -import jdk.internal.javac.PreviewFeature; /** * Models a classfile attribute (JVMS {@jvms 4.7}). Many, though not all, subtypes of @@ -42,9 +41,8 @@ * @param the attribute type * * @sealedGraph - * @since 22 + * @since 24 */ -@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) public sealed interface Attribute> extends ClassFileElement permits AnnotationDefaultAttribute, BootstrapMethodsAttribute, diff --git a/src/java.base/share/classes/java/lang/classfile/AttributeMapper.java b/src/java.base/share/classes/java/lang/classfile/AttributeMapper.java index 0b46055423a..993da9aa4a8 100644 --- a/src/java.base/share/classes/java/lang/classfile/AttributeMapper.java +++ b/src/java.base/share/classes/java/lang/classfile/AttributeMapper.java @@ -24,8 +24,6 @@ */ package java.lang.classfile; -import jdk.internal.javac.PreviewFeature; - /** * Bidirectional mapper between the classfile representation of an attribute and * how that attribute is modeled in the API. The attribute mapper is used @@ -37,17 +35,15 @@ * CustomAttribute}. * @param the attribute type * - * @since 22 + * @since 24 */ -@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) public interface AttributeMapper> { /** * Attribute stability indicator * - * @since 22 + * @since 24 */ - @PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) enum AttributeStability { /** diff --git a/src/java.base/share/classes/java/lang/classfile/AttributedElement.java b/src/java.base/share/classes/java/lang/classfile/AttributedElement.java index fb1bf817480..478ad1e3f0a 100644 --- a/src/java.base/share/classes/java/lang/classfile/AttributedElement.java +++ b/src/java.base/share/classes/java/lang/classfile/AttributedElement.java @@ -31,7 +31,6 @@ import java.util.Optional; import jdk.internal.classfile.impl.AbstractUnboundModel; -import jdk.internal.javac.PreviewFeature; import static java.util.Objects.requireNonNull; @@ -40,9 +39,8 @@ * as a class, field, method, code attribute, or record component. * * @sealedGraph - * @since 22 + * @since 24 */ -@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) public sealed interface AttributedElement extends ClassFileElement permits ClassModel, CodeModel, FieldModel, MethodModel, RecordComponentInfo, AbstractUnboundModel { diff --git a/src/java.base/share/classes/java/lang/classfile/Attributes.java b/src/java.base/share/classes/java/lang/classfile/Attributes.java index ad63eec75de..24684a36b02 100644 --- a/src/java.base/share/classes/java/lang/classfile/Attributes.java +++ b/src/java.base/share/classes/java/lang/classfile/Attributes.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -28,7 +28,6 @@ import java.lang.classfile.attribute.*; import jdk.internal.classfile.impl.AbstractAttributeMapper.*; -import jdk.internal.javac.PreviewFeature; /** * Attribute mappers for standard classfile attributes. @@ -89,9 +88,8 @@ * * @see AttributeMapper * - * @since 22 + * @since 24 */ -@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) public final class Attributes { /** AnnotationDefault */ @@ -207,7 +205,6 @@ private Attributes() { /** * {@return Attribute mapper for the {@code AnnotationDefault} attribute} - * @since 23 */ public static AttributeMapper annotationDefault() { return AnnotationDefaultMapper.INSTANCE; @@ -215,7 +212,6 @@ public static AttributeMapper annotationDefault() { /** * {@return Attribute mapper for the {@code BootstrapMethods} attribute} - * @since 23 */ public static AttributeMapper bootstrapMethods() { return BootstrapMethodsMapper.INSTANCE; @@ -224,7 +220,6 @@ public static AttributeMapper bootstrapMethods() { /** * {@return Attribute mapper for the {@code CharacterRangeTable} attribute} * The mapper permits multiple instances in a given location. - * @since 23 */ public static AttributeMapper characterRangeTable() { return CharacterRangeTableMapper.INSTANCE; @@ -232,7 +227,6 @@ public static AttributeMapper characterRangeTable( /** * {@return Attribute mapper for the {@code Code} attribute} - * @since 23 */ public static AttributeMapper code() { return CodeMapper.INSTANCE; @@ -240,7 +234,6 @@ public static AttributeMapper code() { /** * {@return Attribute mapper for the {@code CompilationID} attribute} - * @since 23 */ public static AttributeMapper compilationId() { return CompilationIDMapper.INSTANCE; @@ -248,7 +241,6 @@ public static AttributeMapper compilationId() { /** * {@return Attribute mapper for the {@code ConstantValue} attribute} - * @since 23 */ public static AttributeMapper constantValue() { return ConstantValueMapper.INSTANCE; @@ -257,7 +249,6 @@ public static AttributeMapper constantValue() { /** * {@return Attribute mapper for the {@code Deprecated} attribute} * The mapper permits multiple instances in a given location. - * @since 23 */ public static AttributeMapper deprecated() { return DeprecatedMapper.INSTANCE; @@ -265,7 +256,6 @@ public static AttributeMapper deprecated() { /** * {@return Attribute mapper for the {@code EnclosingMethod} attribute} - * @since 23 */ public static AttributeMapper enclosingMethod() { return EnclosingMethodMapper.INSTANCE; @@ -273,7 +263,6 @@ public static AttributeMapper enclosingMethod() { /** * {@return Attribute mapper for the {@code Exceptions} attribute} - * @since 23 */ public static AttributeMapper exceptions() { return ExceptionsMapper.INSTANCE; @@ -281,7 +270,6 @@ public static AttributeMapper exceptions() { /** * {@return Attribute mapper for the {@code InnerClasses} attribute} - * @since 23 */ public static AttributeMapper innerClasses() { return InnerClassesMapper.INSTANCE; @@ -290,7 +278,6 @@ public static AttributeMapper innerClasses() { /** * {@return Attribute mapper for the {@code LineNumberTable} attribute} * The mapper permits multiple instances in a given location. - * @since 23 */ public static AttributeMapper lineNumberTable() { return LineNumberTableMapper.INSTANCE; @@ -299,7 +286,6 @@ public static AttributeMapper lineNumberTable() { /** * {@return Attribute mapper for the {@code LocalVariableTable} attribute} * The mapper permits multiple instances in a given location. - * @since 23 */ public static AttributeMapper localVariableTable() { return LocalVariableTableMapper.INSTANCE; @@ -308,7 +294,6 @@ public static AttributeMapper localVariableTable() /** * {@return Attribute mapper for the {@code LocalVariableTypeTable} attribute} * The mapper permits multiple instances in a given location. - * @since 23 */ public static AttributeMapper localVariableTypeTable() { return LocalVariableTypeTableMapper.INSTANCE; @@ -316,7 +301,6 @@ public static AttributeMapper localVariableType /** * {@return Attribute mapper for the {@code MethodParameters} attribute} - * @since 23 */ public static AttributeMapper methodParameters() { return MethodParametersMapper.INSTANCE; @@ -324,7 +308,6 @@ public static AttributeMapper methodParameters() { /** * {@return Attribute mapper for the {@code Module} attribute} - * @since 23 */ public static AttributeMapper module() { return ModuleMapper.INSTANCE; @@ -332,7 +315,6 @@ public static AttributeMapper module() { /** * {@return Attribute mapper for the {@code ModuleHashes} attribute} - * @since 23 */ public static AttributeMapper moduleHashes() { return ModuleHashesMapper.INSTANCE; @@ -340,7 +322,6 @@ public static AttributeMapper moduleHashes() { /** * {@return Attribute mapper for the {@code ModuleMainClass} attribute} - * @since 23 */ public static AttributeMapper moduleMainClass() { return ModuleMainClassMapper.INSTANCE; @@ -348,7 +329,6 @@ public static AttributeMapper moduleMainClass() { /** * {@return Attribute mapper for the {@code ModulePackages} attribute} - * @since 23 */ public static AttributeMapper modulePackages() { return ModulePackagesMapper.INSTANCE; @@ -356,7 +336,6 @@ public static AttributeMapper modulePackages() { /** * {@return Attribute mapper for the {@code ModuleResolution} attribute} - * @since 23 */ public static AttributeMapper moduleResolution() { return ModuleResolutionMapper.INSTANCE; @@ -364,7 +343,6 @@ public static AttributeMapper moduleResolution() { /** * {@return Attribute mapper for the {@code ModuleTarget} attribute} - * @since 23 */ public static AttributeMapper moduleTarget() { return ModuleTargetMapper.INSTANCE; @@ -372,7 +350,6 @@ public static AttributeMapper moduleTarget() { /** * {@return Attribute mapper for the {@code NestHost} attribute} - * @since 23 */ public static AttributeMapper nestHost() { return NestHostMapper.INSTANCE; @@ -380,7 +357,6 @@ public static AttributeMapper nestHost() { /** * {@return Attribute mapper for the {@code NestMembers} attribute} - * @since 23 */ public static AttributeMapper nestMembers() { return NestMembersMapper.INSTANCE; @@ -388,7 +364,6 @@ public static AttributeMapper nestMembers() { /** * {@return Attribute mapper for the {@code PermittedSubclasses} attribute} - * @since 23 */ public static AttributeMapper permittedSubclasses() { return PermittedSubclassesMapper.INSTANCE; @@ -396,7 +371,6 @@ public static AttributeMapper permittedSubclasses( /** * {@return Attribute mapper for the {@code Record} attribute} - * @since 23 */ public static AttributeMapper record() { return RecordMapper.INSTANCE; @@ -404,7 +378,6 @@ public static AttributeMapper record() { /** * {@return Attribute mapper for the {@code RuntimeInvisibleAnnotations} attribute} - * @since 23 */ public static AttributeMapper runtimeInvisibleAnnotations() { return RuntimeInvisibleAnnotationsMapper.INSTANCE; @@ -412,7 +385,6 @@ public static AttributeMapper runtimeInvis /** * {@return Attribute mapper for the {@code RuntimeInvisibleParameterAnnotations} attribute} - * @since 23 */ public static AttributeMapper runtimeInvisibleParameterAnnotations() { return RuntimeInvisibleParameterAnnotationsMapper.INSTANCE; @@ -420,7 +392,6 @@ public static AttributeMapper run /** * {@return Attribute mapper for the {@code RuntimeInvisibleTypeAnnotations} attribute} - * @since 23 */ public static AttributeMapper runtimeInvisibleTypeAnnotations() { return RuntimeInvisibleTypeAnnotationsMapper.INSTANCE; @@ -428,7 +399,6 @@ public static AttributeMapper runtimeI /** * {@return Attribute mapper for the {@code RuntimeVisibleAnnotations} attribute} - * @since 23 */ public static AttributeMapper runtimeVisibleAnnotations() { return RuntimeVisibleAnnotationsMapper.INSTANCE; @@ -436,7 +406,6 @@ public static AttributeMapper runtimeVisible /** * {@return Attribute mapper for the {@code RuntimeVisibleParameterAnnotations} attribute} - * @since 23 */ public static AttributeMapper runtimeVisibleParameterAnnotations() { return RuntimeVisibleParameterAnnotationsMapper.INSTANCE; @@ -444,7 +413,6 @@ public static AttributeMapper runti /** * {@return Attribute mapper for the {@code RuntimeVisibleTypeAnnotations} attribute} - * @since 23 */ public static AttributeMapper runtimeVisibleTypeAnnotations() { return RuntimeVisibleTypeAnnotationsMapper.INSTANCE; @@ -452,7 +420,6 @@ public static AttributeMapper runtimeVis /** * {@return Attribute mapper for the {@code Signature} attribute} - * @since 23 */ public static AttributeMapper signature() { return SignatureMapper.INSTANCE; @@ -460,7 +427,6 @@ public static AttributeMapper signature() { /** * {@return Attribute mapper for the {@code SourceDebugExtension} attribute} - * @since 23 */ public static AttributeMapper sourceDebugExtension() { return SourceDebugExtensionMapper.INSTANCE; @@ -468,7 +434,6 @@ public static AttributeMapper sourceDebugExtensio /** * {@return Attribute mapper for the {@code SourceFile} attribute} - * @since 23 */ public static AttributeMapper sourceFile() { return SourceFileMapper.INSTANCE; @@ -476,7 +441,6 @@ public static AttributeMapper sourceFile() { /** * {@return Attribute mapper for the {@code SourceID} attribute} - * @since 23 */ public static AttributeMapper sourceId() { return SourceIDMapper.INSTANCE; @@ -484,7 +448,6 @@ public static AttributeMapper sourceId() { /** * {@return Attribute mapper for the {@code StackMapTable} attribute} - * @since 23 */ public static AttributeMapper stackMapTable() { return StackMapTableMapper.INSTANCE; @@ -493,7 +456,6 @@ public static AttributeMapper stackMapTable() { /** * {@return Attribute mapper for the {@code Synthetic} attribute} * The mapper permits multiple instances in a given location. - * @since 23 */ public static AttributeMapper synthetic() { return SyntheticMapper.INSTANCE; diff --git a/src/java.base/share/classes/java/lang/classfile/BootstrapMethodEntry.java b/src/java.base/share/classes/java/lang/classfile/BootstrapMethodEntry.java index 964976e0fd5..1608e77bee6 100644 --- a/src/java.base/share/classes/java/lang/classfile/BootstrapMethodEntry.java +++ b/src/java.base/share/classes/java/lang/classfile/BootstrapMethodEntry.java @@ -31,7 +31,6 @@ import java.util.List; import jdk.internal.classfile.impl.BootstrapMethodEntryImpl; -import jdk.internal.javac.PreviewFeature; /** * Models an entry in the bootstrap method table. The bootstrap method table @@ -39,9 +38,8 @@ * the {@link ConstantPool}, since the bootstrap method table is logically * part of the constant pool. * - * @since 22 + * @since 24 */ -@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) public sealed interface BootstrapMethodEntry permits BootstrapMethodEntryImpl { diff --git a/src/java.base/share/classes/java/lang/classfile/BufWriter.java b/src/java.base/share/classes/java/lang/classfile/BufWriter.java index d60447c1388..c6779583eb1 100644 --- a/src/java.base/share/classes/java/lang/classfile/BufWriter.java +++ b/src/java.base/share/classes/java/lang/classfile/BufWriter.java @@ -29,16 +29,14 @@ import java.lang.classfile.constantpool.PoolEntry; import jdk.internal.classfile.impl.BufWriterImpl; -import jdk.internal.javac.PreviewFeature; /** * Supports writing portions of a classfile to a growable buffer. Methods * are provided to write various standard entities (e.g., {@code u2}, {@code u4}) * to the end of the buffer, as well as to create constant pool entries. * - * @since 22 + * @since 24 */ -@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) public sealed interface BufWriter permits BufWriterImpl { diff --git a/src/java.base/share/classes/java/lang/classfile/ClassBuilder.java b/src/java.base/share/classes/java/lang/classfile/ClassBuilder.java index 71f1cc53194..996c63ddd01 100644 --- a/src/java.base/share/classes/java/lang/classfile/ClassBuilder.java +++ b/src/java.base/share/classes/java/lang/classfile/ClassBuilder.java @@ -39,7 +39,6 @@ import jdk.internal.classfile.impl.ChainedClassBuilder; import jdk.internal.classfile.impl.DirectClassBuilder; import jdk.internal.classfile.impl.Util; -import jdk.internal.javac.PreviewFeature; /** * A builder for classfiles. Builders are not created directly; they are passed @@ -50,9 +49,8 @@ * * @see ClassTransform * - * @since 22 + * @since 24 */ -@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) public sealed interface ClassBuilder extends ClassFileBuilder permits ChainedClassBuilder, DirectClassBuilder { diff --git a/src/java.base/share/classes/java/lang/classfile/ClassElement.java b/src/java.base/share/classes/java/lang/classfile/ClassElement.java index 6c918b7de4a..c39ab3c4a64 100644 --- a/src/java.base/share/classes/java/lang/classfile/ClassElement.java +++ b/src/java.base/share/classes/java/lang/classfile/ClassElement.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,16 +26,13 @@ import java.lang.classfile.attribute.*; -import jdk.internal.javac.PreviewFeature; - /** * A marker interface for elements that can appear when traversing * a {@link ClassModel} or be presented to a {@link ClassBuilder}. * * @sealedGraph - * @since 22 + * @since 24 */ -@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) public sealed interface ClassElement extends ClassFileElement permits AccessFlags, Superclass, Interfaces, ClassFileVersion, FieldModel, MethodModel, diff --git a/src/java.base/share/classes/java/lang/classfile/ClassFile.java b/src/java.base/share/classes/java/lang/classfile/ClassFile.java index 7051228c827..db293f41588 100644 --- a/src/java.base/share/classes/java/lang/classfile/ClassFile.java +++ b/src/java.base/share/classes/java/lang/classfile/ClassFile.java @@ -43,7 +43,6 @@ import jdk.internal.classfile.impl.ClassFileImpl; import jdk.internal.classfile.impl.TemporaryConstantPool; -import jdk.internal.javac.PreviewFeature; import static java.util.Objects.requireNonNull; import static jdk.internal.constant.ConstantUtils.CD_module_info; @@ -53,9 +52,8 @@ * A {@code ClassFile} has a set of options that condition how parsing and * generation is done. * - * @since 22 + * @since 24 */ -@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) public sealed interface ClassFile permits ClassFileImpl { @@ -84,9 +82,8 @@ static ClassFile of(Option... options) { * An option that affects the parsing and writing of classfiles. * * @sealedGraph - * @since 22 + * @since 24 */ - @PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) sealed interface Option { } @@ -94,9 +91,8 @@ sealed interface Option { * Option describing attribute mappers for custom attributes. * Default is only to process standard attributes. * - * @since 22 + * @since 24 */ - @PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) sealed interface AttributeMapperOption extends Option permits ClassFileImpl.AttributeMapperOptionImpl { @@ -119,9 +115,8 @@ static AttributeMapperOption of(Function> attribut * Option describing the class hierarchy resolver to use when generating * stack maps. * - * @since 22 + * @since 24 */ - @PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) sealed interface ClassHierarchyResolverOption extends Option permits ClassFileImpl.ClassHierarchyResolverOptionImpl { @@ -150,9 +145,8 @@ static ClassHierarchyResolverOption of(ClassHierarchyResolver classHierarchyReso * Default is {@code SHARED_POOL} to preserve the original constant * pool. * - * @since 22 + * @since 24 */ - @PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) enum ConstantPoolSharingOption implements Option { /** Preserves the original constant pool when transforming classfile */ @@ -167,9 +161,8 @@ enum ConstantPoolSharingOption implements Option { * Default is {@code PATCH_DEAD_CODE} to automatically patch out unreachable * code with NOPs. * - * @since 22 + * @since 24 */ - @PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) enum DeadCodeOption implements Option { /** Patch unreachable code */ @@ -188,9 +181,8 @@ enum DeadCodeOption implements Option { * Setting this option to {@code DROP_DEAD_LABELS} filters the above * elements instead. * - * @since 22 + * @since 24 */ - @PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) enum DeadLabelsOption implements Option { /** Fail on unresolved labels */ @@ -207,9 +199,8 @@ enum DeadLabelsOption implements Option { * reduce the overhead of parsing or transforming classfiles. * Default is {@code PASS_DEBUG} to process debug elements. * - * @since 22 + * @since 24 */ - @PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) enum DebugElementsOption implements Option { /** Process debug elements */ @@ -225,9 +216,8 @@ enum DebugElementsOption implements Option { * classfiles. * Default is {@code PASS_LINE_NUMBERS} to process line numbers. * - * @since 22 + * @since 24 */ - @PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) enum LineNumbersOption implements Option { /** Process line numbers */ @@ -243,9 +233,8 @@ enum LineNumbersOption implements Option { * Default is {@code FIX_SHORT_JUMPS} to automatically rewrite jump * instructions. * - * @since 22 + * @since 24 */ - @PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) enum ShortJumpsOption implements Option { /** Automatically convert short jumps to long when necessary */ @@ -262,9 +251,8 @@ enum ShortJumpsOption implements Option { * {@link #JAVA_6_VERSION} the stack maps may not be generated. * @jvms 4.10.1 Verification by Type Checking * - * @since 22 + * @since 24 */ - @PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) enum StackMapsOption implements Option { /** Generate stack maps when required */ @@ -284,9 +272,8 @@ enum StackMapsOption implements Option { * Default is {@code PASS_ALL_ATTRIBUTES} to process all original attributes. * @see AttributeMapper.AttributeStability * - * @since 22 + * @since 24 */ - @PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) enum AttributesProcessingOption implements Option { /** Process all original attributes during transformation */ @@ -648,16 +635,10 @@ default List verify(Path path) throws IOException { /** The class major version of JAVA_22. */ int JAVA_22_VERSION = 66; - /** - * The class major version of JAVA_23. - * @since 23 - */ + /** The class major version of JAVA_23. */ int JAVA_23_VERSION = 67; - /** - * The class major version of JAVA_24. - * @since 24 - */ + /** The class major version of JAVA_24. */ int JAVA_24_VERSION = 68; /** diff --git a/src/java.base/share/classes/java/lang/classfile/ClassFileBuilder.java b/src/java.base/share/classes/java/lang/classfile/ClassFileBuilder.java index 8b3f6544fff..01eeefd0b9b 100644 --- a/src/java.base/share/classes/java/lang/classfile/ClassFileBuilder.java +++ b/src/java.base/share/classes/java/lang/classfile/ClassFileBuilder.java @@ -29,7 +29,6 @@ import java.util.function.Consumer; import jdk.internal.classfile.impl.TransformImpl; -import jdk.internal.javac.PreviewFeature; /** * A builder for a classfile or portion of a classfile. Builders are rarely @@ -44,9 +43,8 @@ * @see ClassFileTransform * * @sealedGraph - * @since 22 + * @since 24 */ -@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) public sealed interface ClassFileBuilder> extends Consumer permits ClassBuilder, FieldBuilder, MethodBuilder, CodeBuilder { diff --git a/src/java.base/share/classes/java/lang/classfile/ClassFileElement.java b/src/java.base/share/classes/java/lang/classfile/ClassFileElement.java index a4a8203038f..ed84eb39d53 100644 --- a/src/java.base/share/classes/java/lang/classfile/ClassFileElement.java +++ b/src/java.base/share/classes/java/lang/classfile/ClassFileElement.java @@ -24,8 +24,6 @@ */ package java.lang.classfile; -import jdk.internal.javac.PreviewFeature; - /** * Immutable model for a portion of (or the entirety of) a classfile. Elements * that model parts of the classfile that have attributes will implement {@link @@ -35,9 +33,8 @@ * will implement {@link ClassElement}, {@link MethodElement}, etc. * * @sealedGraph - * @since 22 + * @since 24 */ -@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) public sealed interface ClassFileElement permits AttributedElement, CompoundElement, Attribute, ClassElement, CodeElement, FieldElement, MethodElement { diff --git a/src/java.base/share/classes/java/lang/classfile/ClassFileTransform.java b/src/java.base/share/classes/java/lang/classfile/ClassFileTransform.java index b9c5210881c..9fdafdf4331 100644 --- a/src/java.base/share/classes/java/lang/classfile/ClassFileTransform.java +++ b/src/java.base/share/classes/java/lang/classfile/ClassFileTransform.java @@ -27,8 +27,6 @@ import java.lang.classfile.attribute.RuntimeVisibleAnnotationsAttribute; import java.util.function.Supplier; -import jdk.internal.javac.PreviewFeature; - /** * A transformation on streams of elements. Transforms are used during * transformation of classfile entities; a transform is provided to a method like @@ -73,9 +71,8 @@ * @param the builder type * * @sealedGraph - * @since 22 + * @since 24 */ -@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) public sealed interface ClassFileTransform< C extends ClassFileTransform, E extends ClassFileElement, diff --git a/src/java.base/share/classes/java/lang/classfile/ClassFileVersion.java b/src/java.base/share/classes/java/lang/classfile/ClassFileVersion.java index b6ef3e57f61..1916a185cc8 100644 --- a/src/java.base/share/classes/java/lang/classfile/ClassFileVersion.java +++ b/src/java.base/share/classes/java/lang/classfile/ClassFileVersion.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,16 +25,14 @@ package java.lang.classfile; import jdk.internal.classfile.impl.ClassFileVersionImpl; -import jdk.internal.javac.PreviewFeature; /** * Models the classfile version information for a class. Delivered as a {@link * java.lang.classfile.ClassElement} when traversing the elements of a {@link * ClassModel}. * - * @since 22 + * @since 24 */ -@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) public sealed interface ClassFileVersion extends ClassElement permits ClassFileVersionImpl { diff --git a/src/java.base/share/classes/java/lang/classfile/ClassHierarchyResolver.java b/src/java.base/share/classes/java/lang/classfile/ClassHierarchyResolver.java index c2719e7aae0..2c612854a64 100644 --- a/src/java.base/share/classes/java/lang/classfile/ClassHierarchyResolver.java +++ b/src/java.base/share/classes/java/lang/classfile/ClassHierarchyResolver.java @@ -37,7 +37,6 @@ import jdk.internal.classfile.impl.ClassHierarchyImpl.ClassLoadingClassHierarchyResolver; import jdk.internal.classfile.impl.ClassHierarchyImpl.StaticClassHierarchyResolver; import jdk.internal.classfile.impl.Util; -import jdk.internal.javac.PreviewFeature; import static java.lang.constant.ConstantDescs.CD_Object; import static java.util.Objects.requireNonNull; @@ -46,9 +45,8 @@ * Provides class hierarchy information for generating correct stack maps * during code building. * - * @since 22 + * @since 24 */ -@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) @FunctionalInterface public interface ClassHierarchyResolver { @@ -71,9 +69,8 @@ static ClassHierarchyResolver defaultResolver() { /** * Information about a resolved class. * - * @since 22 + * @since 24 */ - @PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) sealed interface ClassHierarchyInfo permits ClassHierarchyImpl.ClassHierarchyInfoImpl { /** diff --git a/src/java.base/share/classes/java/lang/classfile/ClassModel.java b/src/java.base/share/classes/java/lang/classfile/ClassModel.java index 915b662b488..db804348cfe 100644 --- a/src/java.base/share/classes/java/lang/classfile/ClassModel.java +++ b/src/java.base/share/classes/java/lang/classfile/ClassModel.java @@ -31,16 +31,14 @@ import java.util.Optional; import jdk.internal.classfile.impl.ClassImpl; -import jdk.internal.javac.PreviewFeature; /** * Models a classfile. The contents of the classfile can be traversed via * a streaming view, or via random access (e.g., * {@link #flags()}), or by freely mixing the two. * - * @since 22 + * @since 24 */ -@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) public sealed interface ClassModel extends CompoundElement, AttributedElement permits ClassImpl { diff --git a/src/java.base/share/classes/java/lang/classfile/ClassReader.java b/src/java.base/share/classes/java/lang/classfile/ClassReader.java index 58ee2aae5e5..93f2ac5c810 100644 --- a/src/java.base/share/classes/java/lang/classfile/ClassReader.java +++ b/src/java.base/share/classes/java/lang/classfile/ClassReader.java @@ -33,7 +33,6 @@ import java.util.function.Function; import jdk.internal.classfile.impl.ClassReaderImpl; -import jdk.internal.javac.PreviewFeature; /** * Supports reading from a classfile. Methods are provided to read data of @@ -42,9 +41,8 @@ * Encapsulates additional reading context such as mappers for custom attributes * and processing options. * - * @since 22 + * @since 24 */ -@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) public sealed interface ClassReader extends ConstantPool permits ClassReaderImpl { @@ -122,7 +120,6 @@ public sealed interface ClassReader extends ConstantPool * @param cls the entry type * @throws ConstantPoolException if the index is out of range of the * constant pool size, or zero, or the entry is not of the given type - * @since 23 */ T readEntryOrNull(int offset, Class cls); diff --git a/src/java.base/share/classes/java/lang/classfile/ClassSignature.java b/src/java.base/share/classes/java/lang/classfile/ClassSignature.java index 5a57144c4ab..0e1329fd167 100644 --- a/src/java.base/share/classes/java/lang/classfile/ClassSignature.java +++ b/src/java.base/share/classes/java/lang/classfile/ClassSignature.java @@ -27,27 +27,21 @@ import java.util.List; import jdk.internal.classfile.impl.SignaturesImpl; -import jdk.internal.javac.PreviewFeature; import static java.util.Objects.requireNonNull; /** * Models the generic signature of a class file, as defined by JVMS {@jvms 4.7.9}. * - * @since 22 + * @since 24 */ -@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) public sealed interface ClassSignature permits SignaturesImpl.ClassSignatureImpl { /** {@return the type parameters of this class} */ List typeParameters(); - /** - * {@return the instantiation of the superclass in this signature} - * - * @since 23 - */ + /** {@return the instantiation of the superclass in this signature} */ Signature.ClassTypeSig superclassSignature(); /** {@return the instantiation of the interfaces in this signature} */ @@ -60,7 +54,6 @@ public sealed interface ClassSignature * {@return a class signature} * @param superclassSignature the superclass * @param superinterfaceSignatures the interfaces - * @since 23 */ public static ClassSignature of(Signature.ClassTypeSig superclassSignature, Signature.ClassTypeSig... superinterfaceSignatures) { @@ -72,7 +65,6 @@ public static ClassSignature of(Signature.ClassTypeSig superclassSignature, * @param typeParameters the type parameters * @param superclassSignature the superclass * @param superinterfaceSignatures the interfaces - * @since 23 */ public static ClassSignature of(List typeParameters, Signature.ClassTypeSig superclassSignature, diff --git a/src/java.base/share/classes/java/lang/classfile/ClassTransform.java b/src/java.base/share/classes/java/lang/classfile/ClassTransform.java index f512683a9b6..82b61a15089 100644 --- a/src/java.base/share/classes/java/lang/classfile/ClassTransform.java +++ b/src/java.base/share/classes/java/lang/classfile/ClassTransform.java @@ -30,7 +30,6 @@ import java.util.function.Supplier; import jdk.internal.classfile.impl.TransformImpl; -import jdk.internal.javac.PreviewFeature; import static java.util.Objects.requireNonNull; @@ -39,9 +38,8 @@ * * @see ClassFileTransform * - * @since 22 + * @since 24 */ -@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) @FunctionalInterface public non-sealed interface ClassTransform extends ClassFileTransform { diff --git a/src/java.base/share/classes/java/lang/classfile/CodeBuilder.java b/src/java.base/share/classes/java/lang/classfile/CodeBuilder.java index 11e83550d23..1a074c1554a 100644 --- a/src/java.base/share/classes/java/lang/classfile/CodeBuilder.java +++ b/src/java.base/share/classes/java/lang/classfile/CodeBuilder.java @@ -39,7 +39,6 @@ import java.util.function.Consumer; import jdk.internal.classfile.impl.*; -import jdk.internal.javac.PreviewFeature; import static java.util.Objects.requireNonNull; import static jdk.internal.classfile.impl.BytecodeHelpers.handleDescToHandleInfo; @@ -75,9 +74,8 @@ * * @see CodeTransform * - * @since 22 + * @since 24 */ -@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) public sealed interface CodeBuilder extends ClassFileBuilder permits CodeBuilder.BlockCodeBuilder, ChainedCodeBuilder, TerminalCodeBuilder, NonterminalCodeBuilder { @@ -149,9 +147,8 @@ default CodeBuilder transforming(CodeTransform transform, Consumer /** * A builder for blocks of code. * - * @since 22 + * @since 24 */ - @PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) sealed interface BlockCodeBuilder extends CodeBuilder permits BlockCodeBuilderImpl { /** @@ -290,9 +287,8 @@ default CodeBuilder ifThenElse(Opcode opcode, * * @see #trying * - * @since 22 + * @since 24 */ - @PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) sealed interface CatchBuilder permits CatchBuilderImpl { /** * Adds a catch block that catches an exception of the given type. @@ -385,7 +381,6 @@ default CodeBuilder trying(Consumer tryHandler, * @return this builder * @throws IllegalArgumentException if {@code tk} is {@link TypeKind#VOID void} * or {@code slot} is out of range - * @since 23 */ default CodeBuilder loadLocal(TypeKind tk, int slot) { return with(LoadInstruction.of(tk, slot)); @@ -398,7 +393,6 @@ default CodeBuilder loadLocal(TypeKind tk, int slot) { * @return this builder * @throws IllegalArgumentException if {@code tk} is {@link TypeKind#VOID void} * or {@code slot} is out of range - * @since 23 */ default CodeBuilder storeLocal(TypeKind tk, int slot) { return with(StoreInstruction.of(tk, slot)); @@ -410,7 +404,6 @@ default CodeBuilder storeLocal(TypeKind tk, int slot) { * @param op the branch opcode * @param target the branch target * @return this builder - * @since 23 */ default CodeBuilder branch(Opcode op, Label target) { return with(BranchInstruction.of(op, target)); @@ -420,7 +413,6 @@ default CodeBuilder branch(Opcode op, Label target) { * Generate return instruction * @param tk the return type * @return this builder - * @since 23 */ default CodeBuilder return_(TypeKind tk) { return with(ReturnInstruction.of(tk)); @@ -432,7 +424,6 @@ default CodeBuilder return_(TypeKind tk) { * @param opcode the field access opcode * @param ref the field reference * @return this builder - * @since 23 */ default CodeBuilder fieldAccess(Opcode opcode, FieldRefEntry ref) { return with(FieldInstruction.of(opcode, ref)); @@ -446,7 +437,6 @@ default CodeBuilder fieldAccess(Opcode opcode, FieldRefEntry ref) { * @param name the field name * @param type the field type * @return this builder - * @since 23 */ default CodeBuilder fieldAccess(Opcode opcode, ClassDesc owner, String name, ClassDesc type) { return fieldAccess(opcode, constantPool().fieldRefEntry(owner, name, type)); @@ -458,7 +448,6 @@ default CodeBuilder fieldAccess(Opcode opcode, ClassDesc owner, String name, Cla * @param opcode the invoke opcode * @param ref the interface method or method reference * @return this builder - * @since 23 */ default CodeBuilder invoke(Opcode opcode, MemberRefEntry ref) { return with(InvokeInstruction.of(opcode, ref)); @@ -473,7 +462,6 @@ default CodeBuilder invoke(Opcode opcode, MemberRefEntry ref) { * @param desc the method type * @param isInterface the interface method invocation indication * @return this builder - * @since 23 */ default CodeBuilder invoke(Opcode opcode, ClassDesc owner, String name, MethodTypeDesc desc, boolean isInterface) { return invoke(opcode, @@ -485,7 +473,6 @@ default CodeBuilder invoke(Opcode opcode, ClassDesc owner, String name, MethodTy * Generate an instruction to load from an array * @param tk the array element type * @return this builder - * @since 23 */ default CodeBuilder arrayLoad(TypeKind tk) { Opcode opcode = BytecodeHelpers.arrayLoadOpcode(tk); @@ -496,7 +483,6 @@ default CodeBuilder arrayLoad(TypeKind tk) { * Generate an instruction to store into an array * @param tk the array element type * @return this builder - * @since 23 */ default CodeBuilder arrayStore(TypeKind tk) { Opcode opcode = BytecodeHelpers.arrayStoreOpcode(tk); @@ -510,7 +496,6 @@ default CodeBuilder arrayStore(TypeKind tk) { * @return this builder * @throws IllegalArgumentException for conversions of {@link TypeKind#VOID void} or * {@link TypeKind#REFERENCE reference} - * @since 23 */ default CodeBuilder conversion(TypeKind fromType, TypeKind toType) { var computationalFrom = fromType.asLoadable(); @@ -566,7 +551,6 @@ default CodeBuilder conversion(TypeKind fromType, TypeKind toType) { * Generate an instruction pushing a constant onto the operand stack * @param value the constant value * @return this builder - * @since 23 */ default CodeBuilder loadConstant(ConstantDesc value) { //avoid switch expressions here @@ -1740,7 +1724,6 @@ default CodeBuilder ineg() { * * @param target the target type * @return this builder - * @since 23 */ default CodeBuilder instanceOf(ClassEntry target) { return with(TypeCheckInstruction.of(Opcode.INSTANCEOF, target)); @@ -1756,7 +1739,6 @@ default CodeBuilder instanceOf(ClassEntry target) { * @param target the target type * @return this builder * @throws IllegalArgumentException if {@code target} represents a primitive type - * @since 23 */ default CodeBuilder instanceOf(ClassDesc target) { return instanceOf(constantPool().classEntry(target)); diff --git a/src/java.base/share/classes/java/lang/classfile/CodeElement.java b/src/java.base/share/classes/java/lang/classfile/CodeElement.java index 1cec4b8e604..63669d41014 100644 --- a/src/java.base/share/classes/java/lang/classfile/CodeElement.java +++ b/src/java.base/share/classes/java/lang/classfile/CodeElement.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -28,8 +28,6 @@ import java.lang.classfile.attribute.RuntimeVisibleTypeAnnotationsAttribute; import java.lang.classfile.attribute.StackMapTableAttribute; -import jdk.internal.javac.PreviewFeature; - /** * A marker interface for elements that can appear when traversing * a {@link CodeModel} or be presented to a {@link CodeBuilder}. Code elements @@ -39,9 +37,8 @@ * exception metadata, label target metadata, etc. * * @sealedGraph - * @since 22 + * @since 24 */ -@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) public sealed interface CodeElement extends ClassFileElement permits Instruction, PseudoInstruction, CustomAttribute, RuntimeVisibleTypeAnnotationsAttribute, RuntimeInvisibleTypeAnnotationsAttribute, diff --git a/src/java.base/share/classes/java/lang/classfile/CodeModel.java b/src/java.base/share/classes/java/lang/classfile/CodeModel.java index 759aacc18c9..644f7660564 100644 --- a/src/java.base/share/classes/java/lang/classfile/CodeModel.java +++ b/src/java.base/share/classes/java/lang/classfile/CodeModel.java @@ -31,15 +31,13 @@ import java.util.Optional; import jdk.internal.classfile.impl.BufferedCodeBuilder; -import jdk.internal.javac.PreviewFeature; /** * Models the body of a method (the {@code Code} attribute). The instructions * of the method body are accessed via a streaming view. * - * @since 22 + * @since 24 */ -@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) public sealed interface CodeModel extends CompoundElement, AttributedElement, MethodElement permits CodeAttribute, BufferedCodeBuilder.Model { diff --git a/src/java.base/share/classes/java/lang/classfile/CodeTransform.java b/src/java.base/share/classes/java/lang/classfile/CodeTransform.java index 0474e0c9c67..b76c02bf5fb 100644 --- a/src/java.base/share/classes/java/lang/classfile/CodeTransform.java +++ b/src/java.base/share/classes/java/lang/classfile/CodeTransform.java @@ -28,7 +28,6 @@ import java.util.function.Supplier; import jdk.internal.classfile.impl.TransformImpl; -import jdk.internal.javac.PreviewFeature; import static java.util.Objects.requireNonNull; @@ -37,9 +36,8 @@ * * @see ClassFileTransform * - * @since 22 + * @since 24 */ -@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) @FunctionalInterface public non-sealed interface CodeTransform extends ClassFileTransform { diff --git a/src/java.base/share/classes/java/lang/classfile/CompoundElement.java b/src/java.base/share/classes/java/lang/classfile/CompoundElement.java index 5dfeac6f00d..38d149623e1 100644 --- a/src/java.base/share/classes/java/lang/classfile/CompoundElement.java +++ b/src/java.base/share/classes/java/lang/classfile/CompoundElement.java @@ -34,8 +34,6 @@ import java.util.stream.Stream; import java.util.stream.StreamSupport; -import jdk.internal.javac.PreviewFeature; - /** * A {@link ClassFileElement} that has complex structure defined in terms of * other classfile elements, such as a method, field, method body, or entire @@ -46,9 +44,8 @@ * @param the element type * * @sealedGraph - * @since 22 + * @since 24 */ -@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) public sealed interface CompoundElement extends ClassFileElement, Iterable permits ClassModel, CodeModel, FieldModel, MethodModel, jdk.internal.classfile.impl.AbstractUnboundModel { diff --git a/src/java.base/share/classes/java/lang/classfile/CustomAttribute.java b/src/java.base/share/classes/java/lang/classfile/CustomAttribute.java index 6c3a0de2b7a..f47ce9f055b 100644 --- a/src/java.base/share/classes/java/lang/classfile/CustomAttribute.java +++ b/src/java.base/share/classes/java/lang/classfile/CustomAttribute.java @@ -26,7 +26,6 @@ import java.lang.classfile.constantpool.Utf8Entry; import jdk.internal.classfile.impl.TemporaryConstantPool; -import jdk.internal.javac.PreviewFeature; /** * Models a non-standard attribute of a classfile. Clients should extend @@ -35,9 +34,8 @@ * format and the {@linkplain CustomAttribute} representation. * @param the custom attribute type * - * @since 22 + * @since 24 */ -@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) public abstract non-sealed class CustomAttribute> implements Attribute, CodeElement, ClassElement, MethodElement, FieldElement { diff --git a/src/java.base/share/classes/java/lang/classfile/FieldBuilder.java b/src/java.base/share/classes/java/lang/classfile/FieldBuilder.java index d3183644657..c473e09cab7 100644 --- a/src/java.base/share/classes/java/lang/classfile/FieldBuilder.java +++ b/src/java.base/share/classes/java/lang/classfile/FieldBuilder.java @@ -32,7 +32,6 @@ import jdk.internal.classfile.impl.AccessFlagsImpl; import jdk.internal.classfile.impl.ChainedFieldBuilder; import jdk.internal.classfile.impl.TerminalFieldBuilder; -import jdk.internal.javac.PreviewFeature; /** * A builder for fields. Builders are not created directly; they are passed @@ -43,9 +42,8 @@ * * @see FieldTransform * - * @since 22 + * @since 24 */ -@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) public sealed interface FieldBuilder extends ClassFileBuilder permits TerminalFieldBuilder, ChainedFieldBuilder { diff --git a/src/java.base/share/classes/java/lang/classfile/FieldElement.java b/src/java.base/share/classes/java/lang/classfile/FieldElement.java index b4af9971981..a2c1b22751e 100644 --- a/src/java.base/share/classes/java/lang/classfile/FieldElement.java +++ b/src/java.base/share/classes/java/lang/classfile/FieldElement.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,16 +26,13 @@ import java.lang.classfile.attribute.*; -import jdk.internal.javac.PreviewFeature; - /** * A marker interface for elements that can appear when traversing * a {@link FieldModel} or be presented to a {@link FieldBuilder}. * * @sealedGraph - * @since 22 + * @since 24 */ -@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) public sealed interface FieldElement extends ClassFileElement permits AccessFlags, CustomAttribute, ConstantValueAttribute, DeprecatedAttribute, diff --git a/src/java.base/share/classes/java/lang/classfile/FieldModel.java b/src/java.base/share/classes/java/lang/classfile/FieldModel.java index c45f3e88d5d..89fa1e192b0 100644 --- a/src/java.base/share/classes/java/lang/classfile/FieldModel.java +++ b/src/java.base/share/classes/java/lang/classfile/FieldModel.java @@ -32,16 +32,14 @@ import jdk.internal.classfile.impl.BufferedFieldBuilder; import jdk.internal.classfile.impl.FieldImpl; import jdk.internal.classfile.impl.Util; -import jdk.internal.javac.PreviewFeature; /** * Models a field. The contents of the field can be traversed via * a streaming view, or via random access (e.g., * {@link #flags()}), or by freely mixing the two. * - * @since 22 + * @since 24 */ -@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) public sealed interface FieldModel extends CompoundElement, AttributedElement, ClassElement permits BufferedFieldBuilder.Model, FieldImpl { diff --git a/src/java.base/share/classes/java/lang/classfile/FieldTransform.java b/src/java.base/share/classes/java/lang/classfile/FieldTransform.java index 78a6f5ead2f..90313ae48f0 100644 --- a/src/java.base/share/classes/java/lang/classfile/FieldTransform.java +++ b/src/java.base/share/classes/java/lang/classfile/FieldTransform.java @@ -29,7 +29,6 @@ import java.util.function.Supplier; import jdk.internal.classfile.impl.TransformImpl; -import jdk.internal.javac.PreviewFeature; import static java.util.Objects.requireNonNull; @@ -38,9 +37,8 @@ * * @see ClassFileTransform * - * @since 22 + * @since 24 */ -@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) @FunctionalInterface public non-sealed interface FieldTransform extends ClassFileTransform { diff --git a/src/java.base/share/classes/java/lang/classfile/Instruction.java b/src/java.base/share/classes/java/lang/classfile/Instruction.java index 210c1e1b0da..2fe0ec5a588 100644 --- a/src/java.base/share/classes/java/lang/classfile/Instruction.java +++ b/src/java.base/share/classes/java/lang/classfile/Instruction.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -28,14 +28,12 @@ import java.lang.classfile.instruction.*; import jdk.internal.classfile.impl.AbstractInstruction; -import jdk.internal.javac.PreviewFeature; /** * Models an executable instruction in a method body. * - * @since 22 + * @since 24 */ -@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) public sealed interface Instruction extends CodeElement permits ArrayLoadInstruction, ArrayStoreInstruction, BranchInstruction, ConstantInstruction, ConvertInstruction, DiscontinuedInstruction, diff --git a/src/java.base/share/classes/java/lang/classfile/Interfaces.java b/src/java.base/share/classes/java/lang/classfile/Interfaces.java index ff1dda17de8..2c0e5b2e54b 100644 --- a/src/java.base/share/classes/java/lang/classfile/Interfaces.java +++ b/src/java.base/share/classes/java/lang/classfile/Interfaces.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -31,15 +31,13 @@ import jdk.internal.classfile.impl.InterfacesImpl; import jdk.internal.classfile.impl.Util; -import jdk.internal.javac.PreviewFeature; /** * Models the interfaces of a class. Delivered as a {@link * java.lang.classfile.ClassElement} when traversing a {@link ClassModel}. * - * @since 22 + * @since 24 */ -@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) public sealed interface Interfaces extends ClassElement permits InterfacesImpl { diff --git a/src/java.base/share/classes/java/lang/classfile/Label.java b/src/java.base/share/classes/java/lang/classfile/Label.java index 5069b935935..e958e116084 100644 --- a/src/java.base/share/classes/java/lang/classfile/Label.java +++ b/src/java.base/share/classes/java/lang/classfile/Label.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,7 +25,6 @@ package java.lang.classfile; import jdk.internal.classfile.impl.LabelImpl; -import jdk.internal.javac.PreviewFeature; /** * A marker for a position within the instructions of a method body. The @@ -40,9 +39,8 @@ * can be bound to the current position within a {@linkplain CodeBuilder} via * {@link CodeBuilder#labelBinding(Label)} or {@link CodeBuilder#with(ClassFileElement)}. * - * @since 22 + * @since 24 */ -@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) public sealed interface Label permits LabelImpl { } diff --git a/src/java.base/share/classes/java/lang/classfile/MethodBuilder.java b/src/java.base/share/classes/java/lang/classfile/MethodBuilder.java index 6607d19b0ac..747cbe2e107 100644 --- a/src/java.base/share/classes/java/lang/classfile/MethodBuilder.java +++ b/src/java.base/share/classes/java/lang/classfile/MethodBuilder.java @@ -32,7 +32,6 @@ import jdk.internal.classfile.impl.AccessFlagsImpl; import jdk.internal.classfile.impl.ChainedMethodBuilder; import jdk.internal.classfile.impl.TerminalMethodBuilder; -import jdk.internal.javac.PreviewFeature; /** * A builder for methods. Builders are not created directly; they are passed @@ -43,9 +42,8 @@ * * @see MethodTransform * - * @since 22 + * @since 24 */ -@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) public sealed interface MethodBuilder extends ClassFileBuilder permits ChainedMethodBuilder, TerminalMethodBuilder { diff --git a/src/java.base/share/classes/java/lang/classfile/MethodElement.java b/src/java.base/share/classes/java/lang/classfile/MethodElement.java index dd23548c360..77254a6a82c 100644 --- a/src/java.base/share/classes/java/lang/classfile/MethodElement.java +++ b/src/java.base/share/classes/java/lang/classfile/MethodElement.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,16 +26,13 @@ import java.lang.classfile.attribute.*; -import jdk.internal.javac.PreviewFeature; - /** * A marker interface for elements that can appear when traversing * a {@link MethodModel} or be presented to a {@link MethodBuilder}. * * @sealedGraph - * @since 22 + * @since 24 */ -@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) public sealed interface MethodElement extends ClassFileElement permits AccessFlags, CodeModel, CustomAttribute, diff --git a/src/java.base/share/classes/java/lang/classfile/MethodModel.java b/src/java.base/share/classes/java/lang/classfile/MethodModel.java index 568036e464d..d88051a5eb3 100644 --- a/src/java.base/share/classes/java/lang/classfile/MethodModel.java +++ b/src/java.base/share/classes/java/lang/classfile/MethodModel.java @@ -32,16 +32,14 @@ import jdk.internal.classfile.impl.BufferedMethodBuilder; import jdk.internal.classfile.impl.MethodImpl; import jdk.internal.classfile.impl.Util; -import jdk.internal.javac.PreviewFeature; /** * Models a method. The contents of the method can be traversed via * a streaming view, or via random access (e.g., * {@link #flags()}), or by freely mixing the two. * - * @since 22 + * @since 24 */ -@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) public sealed interface MethodModel extends CompoundElement, AttributedElement, ClassElement permits BufferedMethodBuilder.Model, MethodImpl { diff --git a/src/java.base/share/classes/java/lang/classfile/MethodSignature.java b/src/java.base/share/classes/java/lang/classfile/MethodSignature.java index 7235c368a45..e3889395e32 100644 --- a/src/java.base/share/classes/java/lang/classfile/MethodSignature.java +++ b/src/java.base/share/classes/java/lang/classfile/MethodSignature.java @@ -29,16 +29,14 @@ import jdk.internal.classfile.impl.SignaturesImpl; import jdk.internal.classfile.impl.Util; -import jdk.internal.javac.PreviewFeature; import static java.util.Objects.requireNonNull; /** * Models the generic signature of a method, as defined by JVMS {@jvms 4.7.9}. * - * @since 22 + * @since 24 */ -@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) public sealed interface MethodSignature permits SignaturesImpl.MethodSignatureImpl { diff --git a/src/java.base/share/classes/java/lang/classfile/MethodTransform.java b/src/java.base/share/classes/java/lang/classfile/MethodTransform.java index bf5786f3dc7..865fadbae87 100644 --- a/src/java.base/share/classes/java/lang/classfile/MethodTransform.java +++ b/src/java.base/share/classes/java/lang/classfile/MethodTransform.java @@ -29,7 +29,6 @@ import java.util.function.Supplier; import jdk.internal.classfile.impl.TransformImpl; -import jdk.internal.javac.PreviewFeature; import static java.util.Objects.requireNonNull; @@ -38,9 +37,8 @@ * * @see ClassFileTransform * - * @since 22 + * @since 24 */ -@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) @FunctionalInterface public non-sealed interface MethodTransform extends ClassFileTransform { diff --git a/src/java.base/share/classes/java/lang/classfile/Opcode.java b/src/java.base/share/classes/java/lang/classfile/Opcode.java index 735510dbcea..4d333400001 100644 --- a/src/java.base/share/classes/java/lang/classfile/Opcode.java +++ b/src/java.base/share/classes/java/lang/classfile/Opcode.java @@ -25,7 +25,6 @@ package java.lang.classfile; import jdk.internal.classfile.impl.RawBytecodeHelper; -import jdk.internal.javac.PreviewFeature; /** * Describes the opcodes of the JVM instruction set, as described in JVMS {@jvms 6.5}. @@ -35,9 +34,8 @@ * @see Instruction * @see PseudoInstruction * - * @since 22 + * @since 24 */ -@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) public enum Opcode { /** Do nothing */ @@ -697,9 +695,8 @@ public enum Opcode { /** * Kinds of opcodes. * - * @since 22 + * @since 24 */ - @PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) public static enum Kind { /** diff --git a/src/java.base/share/classes/java/lang/classfile/PseudoInstruction.java b/src/java.base/share/classes/java/lang/classfile/PseudoInstruction.java index b152756acfd..456bce04c80 100644 --- a/src/java.base/share/classes/java/lang/classfile/PseudoInstruction.java +++ b/src/java.base/share/classes/java/lang/classfile/PseudoInstruction.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -33,7 +33,6 @@ import java.lang.classfile.instruction.LocalVariableType; import jdk.internal.classfile.impl.AbstractPseudoInstruction; -import jdk.internal.javac.PreviewFeature; /** * Models metadata about a {@link CodeAttribute}, such as entries in the @@ -43,9 +42,8 @@ * pseudo-instructions can be disabled by modifying the value of classfile * options (e.g., {@link ClassFile.DebugElementsOption}). * - * @since 22 + * @since 24 */ -@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) public sealed interface PseudoInstruction extends CodeElement permits CharacterRange, ExceptionCatch, LabelTarget, LineNumber, LocalVariable, LocalVariableType, AbstractPseudoInstruction { diff --git a/src/java.base/share/classes/java/lang/classfile/Signature.java b/src/java.base/share/classes/java/lang/classfile/Signature.java index 7255a41528c..ad2dca0ad46 100644 --- a/src/java.base/share/classes/java/lang/classfile/Signature.java +++ b/src/java.base/share/classes/java/lang/classfile/Signature.java @@ -30,7 +30,6 @@ import jdk.internal.classfile.impl.SignaturesImpl; import jdk.internal.classfile.impl.Util; -import jdk.internal.javac.PreviewFeature; import static java.util.Objects.requireNonNull; @@ -38,9 +37,8 @@ * Models generic Java type signatures, as defined in JVMS {@jvms 4.7.9.1}. * * @sealedGraph - * @since 22 + * @since 24 */ -@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) public sealed interface Signature { /** {@return the raw signature string} */ @@ -71,9 +69,8 @@ public static Signature of(ClassDesc classDesc) { /** * Models the signature of a primitive type or void * - * @since 22 + * @since 24 */ - @PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) public sealed interface BaseTypeSig extends Signature permits SignaturesImpl.BaseTypeSigImpl { @@ -108,9 +105,8 @@ public static BaseTypeSig of(char baseType) { * type variable, or array type. * * @sealedGraph - * @since 22 + * @since 24 */ - @PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) public sealed interface RefTypeSig extends Signature permits ArrayTypeSig, ClassTypeSig, TypeVarSig { @@ -119,9 +115,8 @@ public sealed interface RefTypeSig /** * Models the signature of a possibly-parameterized class or interface type. * - * @since 22 + * @since 24 */ - @PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) public sealed interface ClassTypeSig extends RefTypeSig, ThrowableSig permits SignaturesImpl.ClassTypeSigImpl { @@ -187,31 +182,27 @@ public static ClassTypeSig of(ClassTypeSig outerType, String className, TypeArg. * Models the type argument. * * @sealedGraph - * @since 22 + * @since 24 */ - @PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) public sealed interface TypeArg { /** * Models an unbounded type argument {@code *}. - * @since 23 + * @since 24 */ - @PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) public sealed interface Unbounded extends TypeArg permits SignaturesImpl.UnboundedTypeArgImpl { } /** * Models a type argument with an explicit bound type. - * @since 23 + * @since 24 */ - @PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) public sealed interface Bounded extends TypeArg permits SignaturesImpl.TypeArgImpl { /** * Models a type argument's wildcard indicator. - * @since 23 + * @since 24 */ - @PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) public enum WildcardIndicator { /** @@ -243,7 +234,6 @@ public enum WildcardIndicator { /** * {@return a bounded type arg} * @param boundType the bound - * @since 23 */ public static TypeArg.Bounded of(RefTypeSig boundType) { requireNonNull(boundType); @@ -252,7 +242,6 @@ public static TypeArg.Bounded of(RefTypeSig boundType) { /** * {@return an unbounded type arg} - * @since 23 */ public static TypeArg.Unbounded unbounded() { return SignaturesImpl.UnboundedTypeArgImpl.INSTANCE; @@ -261,7 +250,6 @@ public static TypeArg.Unbounded unbounded() { /** * {@return an upper-bounded type arg} * @param boundType the upper bound - * @since 23 */ public static TypeArg.Bounded extendsOf(RefTypeSig boundType) { requireNonNull(boundType); @@ -271,7 +259,6 @@ public static TypeArg.Bounded extendsOf(RefTypeSig boundType) { /** * {@return a lower-bounded type arg} * @param boundType the lower bound - * @since 23 */ public static TypeArg.Bounded superOf(RefTypeSig boundType) { requireNonNull(boundType); @@ -282,7 +269,6 @@ public static TypeArg.Bounded superOf(RefTypeSig boundType) { * {@return a bounded type arg} * @param wildcard the wild card * @param boundType optional bound type - * @since 23 */ public static TypeArg.Bounded bounded(Bounded.WildcardIndicator wildcard, RefTypeSig boundType) { requireNonNull(wildcard); @@ -294,9 +280,8 @@ public static TypeArg.Bounded bounded(Bounded.WildcardIndicator wildcard, RefTyp /** * Models the signature of a type variable. * - * @since 22 + * @since 24 */ - @PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) public sealed interface TypeVarSig extends RefTypeSig, ThrowableSig permits SignaturesImpl.TypeVarSigImpl { @@ -316,9 +301,8 @@ public static TypeVarSig of(String identifier) { /** * Models the signature of an array type. * - * @since 22 + * @since 24 */ - @PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) public sealed interface ArrayTypeSig extends RefTypeSig permits SignaturesImpl.ArrayTypeSigImpl { @@ -352,9 +336,8 @@ public static ArrayTypeSig of(int dims, Signature componentSignature) { /** * Models a signature for a type parameter of a generic class or method. * - * @since 22 + * @since 24 */ - @PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) public sealed interface TypeParam permits SignaturesImpl.TypeParamImpl { @@ -398,9 +381,8 @@ public static TypeParam of(String identifier, Optional classBound, R * Models a signature for a throwable type. * * @sealedGraph - * @since 22 + * @since 24 */ - @PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) public sealed interface ThrowableSig extends Signature { } } diff --git a/src/java.base/share/classes/java/lang/classfile/Superclass.java b/src/java.base/share/classes/java/lang/classfile/Superclass.java index a69fac6341a..fe30fe8a8e3 100644 --- a/src/java.base/share/classes/java/lang/classfile/Superclass.java +++ b/src/java.base/share/classes/java/lang/classfile/Superclass.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -27,15 +27,13 @@ import java.lang.classfile.constantpool.ClassEntry; import jdk.internal.classfile.impl.SuperclassImpl; -import jdk.internal.javac.PreviewFeature; /** * Models the superclass of a class. Delivered as a {@link * java.lang.classfile.ClassElement} when traversing a {@link ClassModel}. * - * @since 22 + * @since 24 */ -@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) public sealed interface Superclass extends ClassElement permits SuperclassImpl { diff --git a/src/java.base/share/classes/java/lang/classfile/TypeAnnotation.java b/src/java.base/share/classes/java/lang/classfile/TypeAnnotation.java index 38e5ea09a93..9353b30a643 100644 --- a/src/java.base/share/classes/java/lang/classfile/TypeAnnotation.java +++ b/src/java.base/share/classes/java/lang/classfile/TypeAnnotation.java @@ -31,7 +31,6 @@ import jdk.internal.classfile.impl.TargetInfoImpl; import jdk.internal.classfile.impl.UnboundAttribute; -import jdk.internal.javac.PreviewFeature; import static java.lang.classfile.TypeAnnotation.TargetInfo.*; @@ -52,18 +51,16 @@ * @see RuntimeVisibleTypeAnnotationsAttribute * @see RuntimeInvisibleTypeAnnotationsAttribute * - * @since 22 + * @since 24 */ -@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) public sealed interface TypeAnnotation permits UnboundAttribute.UnboundTypeAnnotation { /** * The kind of target on which the annotation appears, as defined in JVMS {@jvms 4.7.20.1}. * - * @since 22 + * @since 24 */ - @PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) public enum TargetType { /** For annotations on a class type parameter declaration. */ CLASS_TYPE_PARAMETER(TARGET_CLASS_TYPE_PARAMETER, 1), @@ -193,9 +190,8 @@ static TypeAnnotation of(TargetInfo targetInfo, List targetPa * Specifies which type in a declaration or expression is being annotated. * * @sealedGraph - * @since 22 + * @since 24 */ - @PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) sealed interface TargetInfo { /** @@ -611,9 +607,8 @@ static TypeArgumentTarget ofMethodReferenceTypeArgument(Label target, int typeAr * parameter of a generic class, generic interface, generic method, or * generic constructor. * - * @since 22 + * @since 24 */ - @PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) sealed interface TypeParameterTarget extends TargetInfo permits TargetInfoImpl.TypeParameterTargetImpl { @@ -630,9 +625,8 @@ sealed interface TypeParameterTarget extends TargetInfo * Indicates that an annotation appears on a type in the extends or implements * clause of a class or interface declaration. * - * @since 22 + * @since 24 */ - @PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) sealed interface SupertypeTarget extends TargetInfo permits TargetInfoImpl.SupertypeTargetImpl { @@ -654,9 +648,8 @@ sealed interface SupertypeTarget extends TargetInfo * type parameter declaration of a generic class, interface, method, or * constructor. * - * @since 22 + * @since 24 */ - @PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) sealed interface TypeParameterBoundTarget extends TargetInfo permits TargetInfoImpl.TypeParameterBoundTargetImpl { @@ -680,9 +673,8 @@ sealed interface TypeParameterBoundTarget extends TargetInfo * declaration, the return type of a method, the type of a newly constructed * object, or the receiver type of a method or constructor. * - * @since 22 + * @since 24 */ - @PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) sealed interface EmptyTarget extends TargetInfo permits TargetInfoImpl.EmptyTargetImpl { } @@ -691,9 +683,8 @@ sealed interface EmptyTarget extends TargetInfo * Indicates that an annotation appears on the type in a formal parameter * declaration of a method, constructor, or lambda expression. * - * @since 22 + * @since 24 */ - @PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) sealed interface FormalParameterTarget extends TargetInfo permits TargetInfoImpl.FormalParameterTargetImpl { @@ -710,9 +701,8 @@ sealed interface FormalParameterTarget extends TargetInfo * Indicates that an annotation appears on the i'th type in the throws * clause of a method or constructor declaration. * - * @since 22 + * @since 24 */ - @PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) sealed interface ThrowsTarget extends TargetInfo permits TargetInfoImpl.ThrowsTargetImpl { @@ -730,9 +720,8 @@ sealed interface ThrowsTarget extends TargetInfo * Indicates that an annotation appears on the type in a local variable declaration, * including a variable declared as a resource in a try-with-resources statement. * - * @since 22 + * @since 24 */ - @PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) sealed interface LocalVarTarget extends TargetInfo permits TargetInfoImpl.LocalVarTargetImpl { @@ -747,9 +736,8 @@ sealed interface LocalVarTarget extends TargetInfo * has a value, and the index into the local variable array of the current * frame at which that local variable can be found. * - * @since 22 + * @since 24 */ - @PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) sealed interface LocalVarTargetInfo permits TargetInfoImpl.LocalVarTargetInfoImpl { @@ -794,9 +782,8 @@ static LocalVarTargetInfo of(Label startLabel, Label endLabel, int index) { * Indicates that an annotation appears on the i'th type in an exception parameter * declaration. * - * @since 22 + * @since 24 */ - @PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) sealed interface CatchTarget extends TargetInfo permits TargetInfoImpl.CatchTargetImpl { @@ -813,9 +800,8 @@ sealed interface CatchTarget extends TargetInfo * Indicates that an annotation appears on either the type in an instanceof expression * or a new expression, or the type before the :: in a method reference expression. * - * @since 22 + * @since 24 */ - @PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) sealed interface OffsetTarget extends TargetInfo permits TargetInfoImpl.OffsetTargetImpl { @@ -835,9 +821,8 @@ sealed interface OffsetTarget extends TargetInfo * expression, an explicit constructor invocation statement, a method invocation expression, or a method reference * expression. * - * @since 22 + * @since 24 */ - @PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) sealed interface TypeArgumentTarget extends TargetInfo permits TargetInfoImpl.TypeArgumentTargetImpl { @@ -871,18 +856,16 @@ sealed interface TypeArgumentTarget extends TargetInfo * JVMS: Type_path structure identifies which part of the type is annotated, * as defined in JVMS {@jvms 4.7.20.2} * - * @since 22 + * @since 24 */ - @PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) sealed interface TypePathComponent permits UnboundAttribute.TypePathComponentImpl { /** * Type path kind, as defined in JVMS {@jvms 4.7.20.2} * - * @since 22 + * @since 24 */ - @PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) public enum Kind { /** Annotation is deeper in an array type */ diff --git a/src/java.base/share/classes/java/lang/classfile/TypeKind.java b/src/java.base/share/classes/java/lang/classfile/TypeKind.java index bdbea7c8c54..5a6475aa801 100644 --- a/src/java.base/share/classes/java/lang/classfile/TypeKind.java +++ b/src/java.base/share/classes/java/lang/classfile/TypeKind.java @@ -30,7 +30,6 @@ import java.lang.constant.ConstantDescs; import java.lang.invoke.TypeDescriptor; -import jdk.internal.javac.PreviewFeature; import jdk.internal.vm.annotation.Stable; /** @@ -54,9 +53,8 @@ * * @jvms 2.2 Data Types * @jvms 2.11.1 Types and the Java Virtual Machine - * @since 22 + * @since 24 */ -@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) public enum TypeKind { // Elements are grouped so frequently used switch ranges such as // primitives (boolean - double) and computational (int - void) are together. @@ -166,7 +164,6 @@ private ClassDesc fetchUpperBound() { /** * {@return the code used by the {@link Opcode#NEWARRAY newarray} instruction to create an array * of this component type, or {@code -1} if this type is not supported by {@code newarray}} - * @since 23 * @jvms 6.5.newarray newarray */ public int newarrayCode() { @@ -198,7 +195,6 @@ public TypeKind asLoadable() { * newarray}} * @param newarrayCode the operand of the {@code newarray} instruction * @throws IllegalArgumentException if the code is invalid - * @since 23 * @jvms 6.5.newarray newarray */ public static TypeKind fromNewarrayCode(int newarrayCode) { diff --git a/src/java.base/share/classes/java/lang/classfile/attribute/AnnotationDefaultAttribute.java b/src/java.base/share/classes/java/lang/classfile/attribute/AnnotationDefaultAttribute.java index 4f147b0d63a..206c0a84087 100644 --- a/src/java.base/share/classes/java/lang/classfile/attribute/AnnotationDefaultAttribute.java +++ b/src/java.base/share/classes/java/lang/classfile/attribute/AnnotationDefaultAttribute.java @@ -32,7 +32,6 @@ import jdk.internal.classfile.impl.BoundAttribute; import jdk.internal.classfile.impl.UnboundAttribute; -import jdk.internal.javac.PreviewFeature; /** * Models the {@code AnnotationDefault} attribute (JVMS {@jvms 4.7.22}), which can @@ -46,9 +45,8 @@ *

* The attribute was introduced in the Java SE Platform version 5.0. * - * @since 22 + * @since 24 */ -@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) public sealed interface AnnotationDefaultAttribute extends Attribute, MethodElement permits BoundAttribute.BoundAnnotationDefaultAttr, diff --git a/src/java.base/share/classes/java/lang/classfile/attribute/BootstrapMethodsAttribute.java b/src/java.base/share/classes/java/lang/classfile/attribute/BootstrapMethodsAttribute.java index 26ef1d3ddaf..bbea96dc162 100644 --- a/src/java.base/share/classes/java/lang/classfile/attribute/BootstrapMethodsAttribute.java +++ b/src/java.base/share/classes/java/lang/classfile/attribute/BootstrapMethodsAttribute.java @@ -32,7 +32,6 @@ import jdk.internal.classfile.impl.BoundAttribute; import jdk.internal.classfile.impl.UnboundAttribute; -import jdk.internal.javac.PreviewFeature; /** * Models the {@code BootstrapMethods} attribute (JVMS {@jvms 4.7.23}), which serves as @@ -45,9 +44,8 @@ *

* The attribute was introduced in the Java SE Platform version 7. * - * @since 22 + * @since 24 */ -@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) public sealed interface BootstrapMethodsAttribute extends Attribute permits BoundAttribute.BoundBootstrapMethodsAttribute, diff --git a/src/java.base/share/classes/java/lang/classfile/attribute/CharacterRangeInfo.java b/src/java.base/share/classes/java/lang/classfile/attribute/CharacterRangeInfo.java index 126ba1037ce..ab37c372c29 100644 --- a/src/java.base/share/classes/java/lang/classfile/attribute/CharacterRangeInfo.java +++ b/src/java.base/share/classes/java/lang/classfile/attribute/CharacterRangeInfo.java @@ -27,14 +27,12 @@ import java.lang.classfile.instruction.CharacterRange; import jdk.internal.classfile.impl.UnboundAttribute; -import jdk.internal.javac.PreviewFeature; /** * Models a single character range in the {@link CharacterRangeTableAttribute}. * - * @since 22 + * @since 24 */ -@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) public sealed interface CharacterRangeInfo permits UnboundAttribute.UnboundCharacterRangeInfo { diff --git a/src/java.base/share/classes/java/lang/classfile/attribute/CharacterRangeTableAttribute.java b/src/java.base/share/classes/java/lang/classfile/attribute/CharacterRangeTableAttribute.java index a4b79be62f0..42a8443f2f6 100644 --- a/src/java.base/share/classes/java/lang/classfile/attribute/CharacterRangeTableAttribute.java +++ b/src/java.base/share/classes/java/lang/classfile/attribute/CharacterRangeTableAttribute.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -30,7 +30,6 @@ import jdk.internal.classfile.impl.BoundAttribute; import jdk.internal.classfile.impl.UnboundAttribute; -import jdk.internal.javac.PreviewFeature; /** * The CharacterRangeTable attribute is an optional variable-length attribute in @@ -58,9 +57,8 @@ *

* The attribute permits multiple instances in a given location. * - * @since 22 + * @since 24 */ -@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) public sealed interface CharacterRangeTableAttribute extends Attribute permits BoundAttribute.BoundCharacterRangeTableAttribute, diff --git a/src/java.base/share/classes/java/lang/classfile/attribute/CodeAttribute.java b/src/java.base/share/classes/java/lang/classfile/attribute/CodeAttribute.java index 3342c2648ed..9bc9e975d12 100644 --- a/src/java.base/share/classes/java/lang/classfile/attribute/CodeAttribute.java +++ b/src/java.base/share/classes/java/lang/classfile/attribute/CodeAttribute.java @@ -30,7 +30,6 @@ import java.lang.classfile.Label; import jdk.internal.classfile.impl.BoundAttribute; -import jdk.internal.javac.PreviewFeature; /** * Models the {@code Code} attribute (JVMS {@jvms 4.7.3}), appears on non-native, @@ -42,9 +41,8 @@ * Subsequent occurrence of the attribute takes precedence during the attributed * element build or transformation. * - * @since 22 + * @since 24 */ -@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) public sealed interface CodeAttribute extends Attribute, CodeModel permits BoundAttribute.BoundCodeAttribute { diff --git a/src/java.base/share/classes/java/lang/classfile/attribute/CompilationIDAttribute.java b/src/java.base/share/classes/java/lang/classfile/attribute/CompilationIDAttribute.java index 292b449c628..8311a8e045c 100644 --- a/src/java.base/share/classes/java/lang/classfile/attribute/CompilationIDAttribute.java +++ b/src/java.base/share/classes/java/lang/classfile/attribute/CompilationIDAttribute.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -32,7 +32,6 @@ import jdk.internal.classfile.impl.BoundAttribute; import jdk.internal.classfile.impl.TemporaryConstantPool; import jdk.internal.classfile.impl.UnboundAttribute; -import jdk.internal.javac.PreviewFeature; /** * Models the {@code CompilationID} attribute (@@@ need reference), which can @@ -44,9 +43,8 @@ * Subsequent occurrence of the attribute takes precedence during the attributed * element build or transformation. * - * @since 22 + * @since 24 */ -@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) public sealed interface CompilationIDAttribute extends Attribute, ClassElement permits BoundAttribute.BoundCompilationIDAttribute, diff --git a/src/java.base/share/classes/java/lang/classfile/attribute/ConstantValueAttribute.java b/src/java.base/share/classes/java/lang/classfile/attribute/ConstantValueAttribute.java index cd874648551..54f4742ab0c 100644 --- a/src/java.base/share/classes/java/lang/classfile/attribute/ConstantValueAttribute.java +++ b/src/java.base/share/classes/java/lang/classfile/attribute/ConstantValueAttribute.java @@ -32,7 +32,6 @@ import jdk.internal.classfile.impl.BoundAttribute; import jdk.internal.classfile.impl.TemporaryConstantPool; import jdk.internal.classfile.impl.UnboundAttribute; -import jdk.internal.javac.PreviewFeature; /** * Models the {@code ConstantValue} attribute (JVMS {@jvms 4.7.2}), which can appear on @@ -44,9 +43,8 @@ * Subsequent occurrence of the attribute takes precedence during the attributed * element build or transformation. * - * @since 22 + * @since 24 */ -@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) public sealed interface ConstantValueAttribute extends Attribute, FieldElement permits BoundAttribute.BoundConstantValueAttribute, diff --git a/src/java.base/share/classes/java/lang/classfile/attribute/DeprecatedAttribute.java b/src/java.base/share/classes/java/lang/classfile/attribute/DeprecatedAttribute.java index 47c85c4b6c1..9e470711e1f 100644 --- a/src/java.base/share/classes/java/lang/classfile/attribute/DeprecatedAttribute.java +++ b/src/java.base/share/classes/java/lang/classfile/attribute/DeprecatedAttribute.java @@ -31,7 +31,6 @@ import jdk.internal.classfile.impl.BoundAttribute; import jdk.internal.classfile.impl.UnboundAttribute; -import jdk.internal.javac.PreviewFeature; /** * Models the {@code Deprecated} attribute (JVMS {@jvms 4.7.15}), which can appear on @@ -41,9 +40,8 @@ *

* The attribute permits multiple instances in a given location. * - * @since 22 + * @since 24 */ -@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) public sealed interface DeprecatedAttribute extends Attribute, ClassElement, MethodElement, FieldElement diff --git a/src/java.base/share/classes/java/lang/classfile/attribute/EnclosingMethodAttribute.java b/src/java.base/share/classes/java/lang/classfile/attribute/EnclosingMethodAttribute.java index c760fdee04b..06ded8c82a5 100644 --- a/src/java.base/share/classes/java/lang/classfile/attribute/EnclosingMethodAttribute.java +++ b/src/java.base/share/classes/java/lang/classfile/attribute/EnclosingMethodAttribute.java @@ -37,7 +37,6 @@ import jdk.internal.classfile.impl.TemporaryConstantPool; import jdk.internal.classfile.impl.UnboundAttribute; import jdk.internal.classfile.impl.Util; -import jdk.internal.javac.PreviewFeature; /** * Models the {@code EnclosingMethod} attribute (JVMS {@jvms 4.7.7}), which can appear @@ -51,9 +50,8 @@ *

* The attribute was introduced in the Java SE Platform version 5.0. * - * @since 22 + * @since 24 */ -@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) public sealed interface EnclosingMethodAttribute extends Attribute, ClassElement permits BoundAttribute.BoundEnclosingMethodAttribute, diff --git a/src/java.base/share/classes/java/lang/classfile/attribute/ExceptionsAttribute.java b/src/java.base/share/classes/java/lang/classfile/attribute/ExceptionsAttribute.java index 91f07d94de9..67732e10e81 100644 --- a/src/java.base/share/classes/java/lang/classfile/attribute/ExceptionsAttribute.java +++ b/src/java.base/share/classes/java/lang/classfile/attribute/ExceptionsAttribute.java @@ -34,7 +34,6 @@ import jdk.internal.classfile.impl.BoundAttribute; import jdk.internal.classfile.impl.UnboundAttribute; import jdk.internal.classfile.impl.Util; -import jdk.internal.javac.PreviewFeature; /** * Models the {@code Exceptions} attribute (JVMS {@jvms 4.7.5}), which can appear on @@ -46,9 +45,8 @@ * Subsequent occurrence of the attribute takes precedence during the attributed * element build or transformation. * - * @since 22 + * @since 24 */ -@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) public sealed interface ExceptionsAttribute extends Attribute, MethodElement permits BoundAttribute.BoundExceptionsAttribute, diff --git a/src/java.base/share/classes/java/lang/classfile/attribute/InnerClassInfo.java b/src/java.base/share/classes/java/lang/classfile/attribute/InnerClassInfo.java index fca8cce7faa..6965d5fdfd2 100644 --- a/src/java.base/share/classes/java/lang/classfile/attribute/InnerClassInfo.java +++ b/src/java.base/share/classes/java/lang/classfile/attribute/InnerClassInfo.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -34,14 +34,12 @@ import jdk.internal.classfile.impl.TemporaryConstantPool; import jdk.internal.classfile.impl.UnboundAttribute; import jdk.internal.classfile.impl.Util; -import jdk.internal.javac.PreviewFeature; /** * Models a single inner class in the {@link InnerClassesAttribute}. * - * @since 22 + * @since 24 */ -@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) public sealed interface InnerClassInfo permits UnboundAttribute.UnboundInnerClassInfo { diff --git a/src/java.base/share/classes/java/lang/classfile/attribute/InnerClassesAttribute.java b/src/java.base/share/classes/java/lang/classfile/attribute/InnerClassesAttribute.java index 3b5d63822c4..463a29f9398 100644 --- a/src/java.base/share/classes/java/lang/classfile/attribute/InnerClassesAttribute.java +++ b/src/java.base/share/classes/java/lang/classfile/attribute/InnerClassesAttribute.java @@ -31,7 +31,6 @@ import jdk.internal.classfile.impl.BoundAttribute; import jdk.internal.classfile.impl.UnboundAttribute; -import jdk.internal.javac.PreviewFeature; /** * Models the {@code InnerClasses} attribute (JVMS {@jvms 4.7.6}), which can @@ -43,9 +42,8 @@ * Subsequent occurrence of the attribute takes precedence during the attributed * element build or transformation. * - * @since 22 + * @since 24 */ -@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) public sealed interface InnerClassesAttribute extends Attribute, ClassElement permits BoundAttribute.BoundInnerClassesAttribute, diff --git a/src/java.base/share/classes/java/lang/classfile/attribute/LineNumberInfo.java b/src/java.base/share/classes/java/lang/classfile/attribute/LineNumberInfo.java index 6e83284f6b1..7e148cec9c1 100644 --- a/src/java.base/share/classes/java/lang/classfile/attribute/LineNumberInfo.java +++ b/src/java.base/share/classes/java/lang/classfile/attribute/LineNumberInfo.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,14 +25,12 @@ package java.lang.classfile.attribute; import jdk.internal.classfile.impl.UnboundAttribute; -import jdk.internal.javac.PreviewFeature; /** * Models a single line number in the {@link LineNumberTableAttribute}. * - * @since 22 + * @since 24 */ -@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) public sealed interface LineNumberInfo permits UnboundAttribute.UnboundLineNumberInfo { diff --git a/src/java.base/share/classes/java/lang/classfile/attribute/LineNumberTableAttribute.java b/src/java.base/share/classes/java/lang/classfile/attribute/LineNumberTableAttribute.java index bb636a8113f..1c00745218a 100644 --- a/src/java.base/share/classes/java/lang/classfile/attribute/LineNumberTableAttribute.java +++ b/src/java.base/share/classes/java/lang/classfile/attribute/LineNumberTableAttribute.java @@ -29,7 +29,6 @@ import jdk.internal.classfile.impl.BoundAttribute; import jdk.internal.classfile.impl.UnboundAttribute; -import jdk.internal.javac.PreviewFeature; /** * Models the {@code LineNumberTable} attribute (JVMS {@jvms 4.7.12}), which can appear @@ -41,9 +40,8 @@ *

* The attribute permits multiple instances in a given location. * - * @since 22 + * @since 24 */ -@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) public sealed interface LineNumberTableAttribute extends Attribute permits BoundAttribute.BoundLineNumberTableAttribute, diff --git a/src/java.base/share/classes/java/lang/classfile/attribute/LocalVariableInfo.java b/src/java.base/share/classes/java/lang/classfile/attribute/LocalVariableInfo.java index 177fc842483..2b4030b46a6 100644 --- a/src/java.base/share/classes/java/lang/classfile/attribute/LocalVariableInfo.java +++ b/src/java.base/share/classes/java/lang/classfile/attribute/LocalVariableInfo.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -30,14 +30,12 @@ import jdk.internal.classfile.impl.BoundLocalVariable; import jdk.internal.classfile.impl.UnboundAttribute; import jdk.internal.classfile.impl.Util; -import jdk.internal.javac.PreviewFeature; /** * Models a single local variable in the {@link LocalVariableTableAttribute}. * - * @since 22 + * @since 24 */ -@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) public sealed interface LocalVariableInfo permits UnboundAttribute.UnboundLocalVariableInfo, BoundLocalVariable { diff --git a/src/java.base/share/classes/java/lang/classfile/attribute/LocalVariableTableAttribute.java b/src/java.base/share/classes/java/lang/classfile/attribute/LocalVariableTableAttribute.java index ad4e732073e..8f44ab2905f 100644 --- a/src/java.base/share/classes/java/lang/classfile/attribute/LocalVariableTableAttribute.java +++ b/src/java.base/share/classes/java/lang/classfile/attribute/LocalVariableTableAttribute.java @@ -29,7 +29,6 @@ import jdk.internal.classfile.impl.BoundAttribute; import jdk.internal.classfile.impl.UnboundAttribute; -import jdk.internal.javac.PreviewFeature; /** * Models the {@code LocalVariableTable} attribute (JVMS {@jvms 4.7.13}), which can appear @@ -41,9 +40,8 @@ *

* The attribute permits multiple instances in a given location. * - * @since 22 + * @since 24 */ -@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) public sealed interface LocalVariableTableAttribute extends Attribute permits BoundAttribute.BoundLocalVariableTableAttribute, UnboundAttribute.UnboundLocalVariableTableAttribute { diff --git a/src/java.base/share/classes/java/lang/classfile/attribute/LocalVariableTypeInfo.java b/src/java.base/share/classes/java/lang/classfile/attribute/LocalVariableTypeInfo.java index 6ba5b409b5b..e7a137102ae 100644 --- a/src/java.base/share/classes/java/lang/classfile/attribute/LocalVariableTypeInfo.java +++ b/src/java.base/share/classes/java/lang/classfile/attribute/LocalVariableTypeInfo.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -28,14 +28,12 @@ import jdk.internal.classfile.impl.BoundLocalVariableType; import jdk.internal.classfile.impl.UnboundAttribute; -import jdk.internal.javac.PreviewFeature; /** * Models a single local variable in the {@link LocalVariableTypeTableAttribute}. * - * @since 22 + * @since 24 */ -@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) public sealed interface LocalVariableTypeInfo permits UnboundAttribute.UnboundLocalVariableTypeInfo, BoundLocalVariableType { diff --git a/src/java.base/share/classes/java/lang/classfile/attribute/LocalVariableTypeTableAttribute.java b/src/java.base/share/classes/java/lang/classfile/attribute/LocalVariableTypeTableAttribute.java index 084b72d6838..2bf7b7a87b3 100644 --- a/src/java.base/share/classes/java/lang/classfile/attribute/LocalVariableTypeTableAttribute.java +++ b/src/java.base/share/classes/java/lang/classfile/attribute/LocalVariableTypeTableAttribute.java @@ -30,7 +30,6 @@ import jdk.internal.classfile.impl.BoundAttribute; import jdk.internal.classfile.impl.UnboundAttribute; -import jdk.internal.javac.PreviewFeature; /** * Models the {@code LocalVariableTypeTable} attribute (JVMS {@jvms 4.7.14}), which can appear @@ -44,9 +43,8 @@ *

* The attribute was introduced in the Java SE Platform version 5.0. * - * @since 22 + * @since 24 */ -@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) public sealed interface LocalVariableTypeTableAttribute extends Attribute permits BoundAttribute.BoundLocalVariableTypeTableAttribute, UnboundAttribute.UnboundLocalVariableTypeTableAttribute { diff --git a/src/java.base/share/classes/java/lang/classfile/attribute/MethodParameterInfo.java b/src/java.base/share/classes/java/lang/classfile/attribute/MethodParameterInfo.java index b0961bf1476..35301a30284 100644 --- a/src/java.base/share/classes/java/lang/classfile/attribute/MethodParameterInfo.java +++ b/src/java.base/share/classes/java/lang/classfile/attribute/MethodParameterInfo.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -33,14 +33,12 @@ import jdk.internal.classfile.impl.TemporaryConstantPool; import jdk.internal.classfile.impl.UnboundAttribute; import jdk.internal.classfile.impl.Util; -import jdk.internal.javac.PreviewFeature; /** * Models a single method parameter in the {@link MethodParametersAttribute}. * - * @since 22 + * @since 24 */ -@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) public sealed interface MethodParameterInfo permits UnboundAttribute.UnboundMethodParameterInfo { /** diff --git a/src/java.base/share/classes/java/lang/classfile/attribute/MethodParametersAttribute.java b/src/java.base/share/classes/java/lang/classfile/attribute/MethodParametersAttribute.java index 43a43d25bb7..3b3bacbbca5 100644 --- a/src/java.base/share/classes/java/lang/classfile/attribute/MethodParametersAttribute.java +++ b/src/java.base/share/classes/java/lang/classfile/attribute/MethodParametersAttribute.java @@ -31,7 +31,6 @@ import jdk.internal.classfile.impl.BoundAttribute; import jdk.internal.classfile.impl.UnboundAttribute; -import jdk.internal.javac.PreviewFeature; /** * Models the {@code MethodParameters} attribute (JVMS {@jvms 4.7.24}), which can @@ -45,9 +44,8 @@ *

* The attribute was introduced in the Java SE Platform version 8. * - * @since 22 + * @since 24 */ -@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) public sealed interface MethodParametersAttribute extends Attribute, MethodElement permits BoundAttribute.BoundMethodParametersAttribute, diff --git a/src/java.base/share/classes/java/lang/classfile/attribute/ModuleAttribute.java b/src/java.base/share/classes/java/lang/classfile/attribute/ModuleAttribute.java index 7091bbd5c42..07e0f2baa12 100644 --- a/src/java.base/share/classes/java/lang/classfile/attribute/ModuleAttribute.java +++ b/src/java.base/share/classes/java/lang/classfile/attribute/ModuleAttribute.java @@ -43,7 +43,6 @@ import jdk.internal.classfile.impl.ModuleAttributeBuilderImpl; import jdk.internal.classfile.impl.UnboundAttribute; import jdk.internal.classfile.impl.Util; -import jdk.internal.javac.PreviewFeature; /** * Models the {@code Module} attribute (JVMS {@jvms 4.7.25}), which can @@ -57,9 +56,8 @@ *

* The attribute was introduced in the Java SE Platform version 9. * - * @since 22 + * @since 24 */ -@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) public sealed interface ModuleAttribute extends Attribute, ClassElement permits BoundAttribute.BoundModuleAttribute, UnboundAttribute.UnboundModuleAttribute { @@ -172,9 +170,8 @@ static ModuleAttribute of(ModuleEntry moduleName, /** * A builder for module attributes. * - * @since 22 + * @since 24 */ - @PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) public sealed interface ModuleAttributeBuilder permits ModuleAttributeBuilderImpl { diff --git a/src/java.base/share/classes/java/lang/classfile/attribute/ModuleExportInfo.java b/src/java.base/share/classes/java/lang/classfile/attribute/ModuleExportInfo.java index 4a534894e9e..69290c55994 100644 --- a/src/java.base/share/classes/java/lang/classfile/attribute/ModuleExportInfo.java +++ b/src/java.base/share/classes/java/lang/classfile/attribute/ModuleExportInfo.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -37,14 +37,12 @@ import jdk.internal.classfile.impl.TemporaryConstantPool; import jdk.internal.classfile.impl.UnboundAttribute; import jdk.internal.classfile.impl.Util; -import jdk.internal.javac.PreviewFeature; /** * Models a single "exports" declaration in the {@link ModuleAttribute}. * - * @since 22 + * @since 24 */ -@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) public sealed interface ModuleExportInfo permits UnboundAttribute.UnboundModuleExportInfo { diff --git a/src/java.base/share/classes/java/lang/classfile/attribute/ModuleHashInfo.java b/src/java.base/share/classes/java/lang/classfile/attribute/ModuleHashInfo.java index 0c85dd14125..07616757daa 100644 --- a/src/java.base/share/classes/java/lang/classfile/attribute/ModuleHashInfo.java +++ b/src/java.base/share/classes/java/lang/classfile/attribute/ModuleHashInfo.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -29,14 +29,12 @@ import jdk.internal.classfile.impl.TemporaryConstantPool; import jdk.internal.classfile.impl.UnboundAttribute; -import jdk.internal.javac.PreviewFeature; /** * Models hash information for a single module in the {@link ModuleHashesAttribute}. * - * @since 22 + * @since 24 */ -@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) public sealed interface ModuleHashInfo permits UnboundAttribute.UnboundModuleHashInfo { diff --git a/src/java.base/share/classes/java/lang/classfile/attribute/ModuleHashesAttribute.java b/src/java.base/share/classes/java/lang/classfile/attribute/ModuleHashesAttribute.java index 0d2eb701484..918d18bda1e 100644 --- a/src/java.base/share/classes/java/lang/classfile/attribute/ModuleHashesAttribute.java +++ b/src/java.base/share/classes/java/lang/classfile/attribute/ModuleHashesAttribute.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -33,7 +33,6 @@ import jdk.internal.classfile.impl.BoundAttribute; import jdk.internal.classfile.impl.TemporaryConstantPool; import jdk.internal.classfile.impl.UnboundAttribute; -import jdk.internal.javac.PreviewFeature; /** * Models the {@code ModuleHashes} attribute, which can @@ -68,9 +67,8 @@ * Subsequent occurrence of the attribute takes precedence during the attributed * element build or transformation. * - * @since 22 + * @since 24 */ -@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) public sealed interface ModuleHashesAttribute extends Attribute, ClassElement permits BoundAttribute.BoundModuleHashesAttribute, UnboundAttribute.UnboundModuleHashesAttribute { diff --git a/src/java.base/share/classes/java/lang/classfile/attribute/ModuleMainClassAttribute.java b/src/java.base/share/classes/java/lang/classfile/attribute/ModuleMainClassAttribute.java index 67d6e5cc15c..7f06eb0f95b 100644 --- a/src/java.base/share/classes/java/lang/classfile/attribute/ModuleMainClassAttribute.java +++ b/src/java.base/share/classes/java/lang/classfile/attribute/ModuleMainClassAttribute.java @@ -33,7 +33,6 @@ import jdk.internal.classfile.impl.BoundAttribute; import jdk.internal.classfile.impl.TemporaryConstantPool; import jdk.internal.classfile.impl.UnboundAttribute; -import jdk.internal.javac.PreviewFeature; /** * Models the {@code ModuleMainClass} attribute (JVMS {@jvms 4.7.27}), which can @@ -47,9 +46,8 @@ *

* The attribute was introduced in the Java SE Platform version 9. * - * @since 22 + * @since 24 */ -@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) public sealed interface ModuleMainClassAttribute extends Attribute, ClassElement permits BoundAttribute.BoundModuleMainClassAttribute, UnboundAttribute.UnboundModuleMainClassAttribute { diff --git a/src/java.base/share/classes/java/lang/classfile/attribute/ModuleOpenInfo.java b/src/java.base/share/classes/java/lang/classfile/attribute/ModuleOpenInfo.java index 7c5fe948d78..a16c9973627 100644 --- a/src/java.base/share/classes/java/lang/classfile/attribute/ModuleOpenInfo.java +++ b/src/java.base/share/classes/java/lang/classfile/attribute/ModuleOpenInfo.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -36,14 +36,12 @@ import jdk.internal.classfile.impl.TemporaryConstantPool; import jdk.internal.classfile.impl.UnboundAttribute; import jdk.internal.classfile.impl.Util; -import jdk.internal.javac.PreviewFeature; /** * Models a single "opens" declaration in the {@link ModuleAttribute}. * - * @since 22 + * @since 24 */ -@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) public sealed interface ModuleOpenInfo permits UnboundAttribute.UnboundModuleOpenInfo { diff --git a/src/java.base/share/classes/java/lang/classfile/attribute/ModulePackagesAttribute.java b/src/java.base/share/classes/java/lang/classfile/attribute/ModulePackagesAttribute.java index f2b34ad107d..ec0a65742b4 100644 --- a/src/java.base/share/classes/java/lang/classfile/attribute/ModulePackagesAttribute.java +++ b/src/java.base/share/classes/java/lang/classfile/attribute/ModulePackagesAttribute.java @@ -34,7 +34,6 @@ import jdk.internal.classfile.impl.BoundAttribute; import jdk.internal.classfile.impl.TemporaryConstantPool; import jdk.internal.classfile.impl.UnboundAttribute; -import jdk.internal.javac.PreviewFeature; /** * Models the {@code ModulePackages} attribute (JVMS {@jvms 4.7.26}), which can @@ -48,9 +47,8 @@ *

* The attribute was introduced in the Java SE Platform version 9. * - * @since 22 + * @since 24 */ -@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) public sealed interface ModulePackagesAttribute extends Attribute, ClassElement permits BoundAttribute.BoundModulePackagesAttribute, diff --git a/src/java.base/share/classes/java/lang/classfile/attribute/ModuleProvideInfo.java b/src/java.base/share/classes/java/lang/classfile/attribute/ModuleProvideInfo.java index 266c73de04f..ce68848d4dc 100644 --- a/src/java.base/share/classes/java/lang/classfile/attribute/ModuleProvideInfo.java +++ b/src/java.base/share/classes/java/lang/classfile/attribute/ModuleProvideInfo.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -32,14 +32,12 @@ import jdk.internal.classfile.impl.TemporaryConstantPool; import jdk.internal.classfile.impl.UnboundAttribute; import jdk.internal.classfile.impl.Util; -import jdk.internal.javac.PreviewFeature; /** * Models a single "provides" declaration in the {@link ModuleAttribute}. * - * @since 22 + * @since 24 */ -@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) public sealed interface ModuleProvideInfo permits UnboundAttribute.UnboundModuleProvideInfo { diff --git a/src/java.base/share/classes/java/lang/classfile/attribute/ModuleRequireInfo.java b/src/java.base/share/classes/java/lang/classfile/attribute/ModuleRequireInfo.java index d072d0fead8..578a783f277 100644 --- a/src/java.base/share/classes/java/lang/classfile/attribute/ModuleRequireInfo.java +++ b/src/java.base/share/classes/java/lang/classfile/attribute/ModuleRequireInfo.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -35,14 +35,12 @@ import jdk.internal.classfile.impl.TemporaryConstantPool; import jdk.internal.classfile.impl.UnboundAttribute; import jdk.internal.classfile.impl.Util; -import jdk.internal.javac.PreviewFeature; /** * Models a single "requires" declaration in the {@link ModuleAttribute}. * - * @since 22 + * @since 24 */ -@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) public sealed interface ModuleRequireInfo permits UnboundAttribute.UnboundModuleRequiresInfo { diff --git a/src/java.base/share/classes/java/lang/classfile/attribute/ModuleResolutionAttribute.java b/src/java.base/share/classes/java/lang/classfile/attribute/ModuleResolutionAttribute.java index a6b17fa4041..3457cb8073e 100644 --- a/src/java.base/share/classes/java/lang/classfile/attribute/ModuleResolutionAttribute.java +++ b/src/java.base/share/classes/java/lang/classfile/attribute/ModuleResolutionAttribute.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -30,7 +30,6 @@ import jdk.internal.classfile.impl.BoundAttribute; import jdk.internal.classfile.impl.UnboundAttribute; -import jdk.internal.javac.PreviewFeature; /** * Models the {@code ModuleResolution} attribute, which can @@ -63,9 +62,8 @@ * Subsequent occurrence of the attribute takes precedence during the attributed * element build or transformation. * - * @since 22 + * @since 24 */ -@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) public sealed interface ModuleResolutionAttribute extends Attribute, ClassElement permits BoundAttribute.BoundModuleResolutionAttribute, UnboundAttribute.UnboundModuleResolutionAttribute { diff --git a/src/java.base/share/classes/java/lang/classfile/attribute/ModuleTargetAttribute.java b/src/java.base/share/classes/java/lang/classfile/attribute/ModuleTargetAttribute.java index 226412eccf3..ac390c3d391 100644 --- a/src/java.base/share/classes/java/lang/classfile/attribute/ModuleTargetAttribute.java +++ b/src/java.base/share/classes/java/lang/classfile/attribute/ModuleTargetAttribute.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -32,7 +32,6 @@ import jdk.internal.classfile.impl.BoundAttribute; import jdk.internal.classfile.impl.TemporaryConstantPool; import jdk.internal.classfile.impl.UnboundAttribute; -import jdk.internal.javac.PreviewFeature; /** * Models the {@code ModuleTarget} attribute, which can @@ -58,9 +57,8 @@ * Subsequent occurrence of the attribute takes precedence during the attributed * element build or transformation. * - * @since 22 + * @since 24 */ -@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) public sealed interface ModuleTargetAttribute extends Attribute, ClassElement permits BoundAttribute.BoundModuleTargetAttribute, UnboundAttribute.UnboundModuleTargetAttribute { diff --git a/src/java.base/share/classes/java/lang/classfile/attribute/NestHostAttribute.java b/src/java.base/share/classes/java/lang/classfile/attribute/NestHostAttribute.java index 6b69f9cbe08..ccfb61242cd 100644 --- a/src/java.base/share/classes/java/lang/classfile/attribute/NestHostAttribute.java +++ b/src/java.base/share/classes/java/lang/classfile/attribute/NestHostAttribute.java @@ -33,7 +33,6 @@ import jdk.internal.classfile.impl.BoundAttribute; import jdk.internal.classfile.impl.TemporaryConstantPool; import jdk.internal.classfile.impl.UnboundAttribute; -import jdk.internal.javac.PreviewFeature; /** * Models the {@code NestHost} attribute (JVMS {@jvms 4.7.28}), which can @@ -47,9 +46,8 @@ *

* The attribute was introduced in the Java SE Platform version 11. * - * @since 22 + * @since 24 */ -@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) public sealed interface NestHostAttribute extends Attribute, ClassElement permits BoundAttribute.BoundNestHostAttribute, UnboundAttribute.UnboundNestHostAttribute { diff --git a/src/java.base/share/classes/java/lang/classfile/attribute/NestMembersAttribute.java b/src/java.base/share/classes/java/lang/classfile/attribute/NestMembersAttribute.java index 8826b4953a5..b01c05542de 100644 --- a/src/java.base/share/classes/java/lang/classfile/attribute/NestMembersAttribute.java +++ b/src/java.base/share/classes/java/lang/classfile/attribute/NestMembersAttribute.java @@ -34,7 +34,6 @@ import jdk.internal.classfile.impl.BoundAttribute; import jdk.internal.classfile.impl.UnboundAttribute; import jdk.internal.classfile.impl.Util; -import jdk.internal.javac.PreviewFeature; /** * Models the {@code NestMembers} attribute (JVMS {@jvms 4.7.29}), which can @@ -48,9 +47,8 @@ *

* The attribute was introduced in the Java SE Platform version 11. * - * @since 22 + * @since 24 */ -@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) public sealed interface NestMembersAttribute extends Attribute, ClassElement permits BoundAttribute.BoundNestMembersAttribute, UnboundAttribute.UnboundNestMembersAttribute { diff --git a/src/java.base/share/classes/java/lang/classfile/attribute/PermittedSubclassesAttribute.java b/src/java.base/share/classes/java/lang/classfile/attribute/PermittedSubclassesAttribute.java index 1242bc6e045..dac63c73435 100644 --- a/src/java.base/share/classes/java/lang/classfile/attribute/PermittedSubclassesAttribute.java +++ b/src/java.base/share/classes/java/lang/classfile/attribute/PermittedSubclassesAttribute.java @@ -34,7 +34,6 @@ import jdk.internal.classfile.impl.BoundAttribute; import jdk.internal.classfile.impl.UnboundAttribute; import jdk.internal.classfile.impl.Util; -import jdk.internal.javac.PreviewFeature; /** * Models the {@code PermittedSubclasses} attribute (JVMS {@jvms 4.7.31}), which can @@ -48,9 +47,8 @@ *

* The attribute was introduced in the Java SE Platform version 17. * - * @since 22 + * @since 24 */ -@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) public sealed interface PermittedSubclassesAttribute extends Attribute, ClassElement permits BoundAttribute.BoundPermittedSubclassesAttribute, UnboundAttribute.UnboundPermittedSubclassesAttribute { diff --git a/src/java.base/share/classes/java/lang/classfile/attribute/RecordAttribute.java b/src/java.base/share/classes/java/lang/classfile/attribute/RecordAttribute.java index 7ef3b6f41b6..b0c4fa7c61c 100644 --- a/src/java.base/share/classes/java/lang/classfile/attribute/RecordAttribute.java +++ b/src/java.base/share/classes/java/lang/classfile/attribute/RecordAttribute.java @@ -31,7 +31,6 @@ import jdk.internal.classfile.impl.BoundAttribute; import jdk.internal.classfile.impl.UnboundAttribute; -import jdk.internal.javac.PreviewFeature; /** * Models the {@code Record} attribute (JVMS {@jvms 4.7.30}), which can @@ -45,9 +44,8 @@ *

* The attribute was introduced in the Java SE Platform version 16. * - * @since 22 + * @since 24 */ -@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) public sealed interface RecordAttribute extends Attribute, ClassElement permits BoundAttribute.BoundRecordAttribute, UnboundAttribute.UnboundRecordAttribute { diff --git a/src/java.base/share/classes/java/lang/classfile/attribute/RecordComponentInfo.java b/src/java.base/share/classes/java/lang/classfile/attribute/RecordComponentInfo.java index ef6385653ed..73e4497915e 100644 --- a/src/java.base/share/classes/java/lang/classfile/attribute/RecordComponentInfo.java +++ b/src/java.base/share/classes/java/lang/classfile/attribute/RecordComponentInfo.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -34,14 +34,12 @@ import jdk.internal.classfile.impl.TemporaryConstantPool; import jdk.internal.classfile.impl.UnboundAttribute; import jdk.internal.classfile.impl.Util; -import jdk.internal.javac.PreviewFeature; /** * Models a single record component in the {@link java.lang.classfile.attribute.RecordAttribute}. * - * @since 22 + * @since 24 */ -@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) public sealed interface RecordComponentInfo extends AttributedElement permits BoundRecordComponentInfo, UnboundAttribute.UnboundRecordComponentInfo { diff --git a/src/java.base/share/classes/java/lang/classfile/attribute/RuntimeInvisibleAnnotationsAttribute.java b/src/java.base/share/classes/java/lang/classfile/attribute/RuntimeInvisibleAnnotationsAttribute.java index 05635af4beb..58903859464 100644 --- a/src/java.base/share/classes/java/lang/classfile/attribute/RuntimeInvisibleAnnotationsAttribute.java +++ b/src/java.base/share/classes/java/lang/classfile/attribute/RuntimeInvisibleAnnotationsAttribute.java @@ -34,7 +34,6 @@ import jdk.internal.classfile.impl.BoundAttribute; import jdk.internal.classfile.impl.UnboundAttribute; -import jdk.internal.javac.PreviewFeature; /** * Models the {@code RuntimeInvisibleAnnotations} attribute (JVMS {@jvms 4.7.17}), which @@ -48,9 +47,8 @@ *

* The attribute was introduced in the Java SE Platform version 5.0. * - * @since 22 + * @since 24 */ -@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) public sealed interface RuntimeInvisibleAnnotationsAttribute extends Attribute, ClassElement, MethodElement, FieldElement diff --git a/src/java.base/share/classes/java/lang/classfile/attribute/RuntimeInvisibleParameterAnnotationsAttribute.java b/src/java.base/share/classes/java/lang/classfile/attribute/RuntimeInvisibleParameterAnnotationsAttribute.java index edb82c49900..f1c02b77e1e 100644 --- a/src/java.base/share/classes/java/lang/classfile/attribute/RuntimeInvisibleParameterAnnotationsAttribute.java +++ b/src/java.base/share/classes/java/lang/classfile/attribute/RuntimeInvisibleParameterAnnotationsAttribute.java @@ -33,7 +33,6 @@ import jdk.internal.classfile.impl.BoundAttribute; import jdk.internal.classfile.impl.UnboundAttribute; -import jdk.internal.javac.PreviewFeature; /** * Models the {@code RuntimeInvisibleParameterAnnotations} attribute @@ -46,9 +45,8 @@ *

* The attribute was introduced in the Java SE Platform version 5.0. * - * @since 22 + * @since 24 */ -@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) public sealed interface RuntimeInvisibleParameterAnnotationsAttribute extends Attribute, MethodElement permits BoundAttribute.BoundRuntimeInvisibleParameterAnnotationsAttribute, diff --git a/src/java.base/share/classes/java/lang/classfile/attribute/RuntimeInvisibleTypeAnnotationsAttribute.java b/src/java.base/share/classes/java/lang/classfile/attribute/RuntimeInvisibleTypeAnnotationsAttribute.java index df3a035d620..7500d39fc19 100644 --- a/src/java.base/share/classes/java/lang/classfile/attribute/RuntimeInvisibleTypeAnnotationsAttribute.java +++ b/src/java.base/share/classes/java/lang/classfile/attribute/RuntimeInvisibleTypeAnnotationsAttribute.java @@ -35,7 +35,6 @@ import jdk.internal.classfile.impl.BoundAttribute; import jdk.internal.classfile.impl.UnboundAttribute; -import jdk.internal.javac.PreviewFeature; /** * Models the {@code RuntimeInvisibleTypeAnnotations} attribute (JVMS {@jvms 4.7.21}), which @@ -50,9 +49,8 @@ *

* The attribute was introduced in the Java SE Platform version 8. * - * @since 22 + * @since 24 */ -@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) public sealed interface RuntimeInvisibleTypeAnnotationsAttribute extends Attribute, ClassElement, MethodElement, FieldElement, CodeElement diff --git a/src/java.base/share/classes/java/lang/classfile/attribute/RuntimeVisibleAnnotationsAttribute.java b/src/java.base/share/classes/java/lang/classfile/attribute/RuntimeVisibleAnnotationsAttribute.java index 69095188818..d41fcf3794b 100644 --- a/src/java.base/share/classes/java/lang/classfile/attribute/RuntimeVisibleAnnotationsAttribute.java +++ b/src/java.base/share/classes/java/lang/classfile/attribute/RuntimeVisibleAnnotationsAttribute.java @@ -34,7 +34,6 @@ import jdk.internal.classfile.impl.BoundAttribute; import jdk.internal.classfile.impl.UnboundAttribute; -import jdk.internal.javac.PreviewFeature; /** * Models the {@code RuntimeVisibleAnnotations} attribute (JVMS {@jvms 4.7.16}), which @@ -48,9 +47,8 @@ *

* The attribute was introduced in the Java SE Platform version 5.0. * - * @since 22 + * @since 24 */ -@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) public sealed interface RuntimeVisibleAnnotationsAttribute extends Attribute, ClassElement, MethodElement, FieldElement diff --git a/src/java.base/share/classes/java/lang/classfile/attribute/RuntimeVisibleParameterAnnotationsAttribute.java b/src/java.base/share/classes/java/lang/classfile/attribute/RuntimeVisibleParameterAnnotationsAttribute.java index ef58d21f14a..5ed9817eeb9 100644 --- a/src/java.base/share/classes/java/lang/classfile/attribute/RuntimeVisibleParameterAnnotationsAttribute.java +++ b/src/java.base/share/classes/java/lang/classfile/attribute/RuntimeVisibleParameterAnnotationsAttribute.java @@ -33,7 +33,6 @@ import jdk.internal.classfile.impl.BoundAttribute; import jdk.internal.classfile.impl.UnboundAttribute; -import jdk.internal.javac.PreviewFeature; /** * Models the {@code RuntimeVisibleParameterAnnotations} attribute (JVMS {@jvms 4.7.18}), which @@ -46,9 +45,8 @@ *

* The attribute was introduced in the Java SE Platform version 5.0. * - * @since 22 + * @since 24 */ -@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) public sealed interface RuntimeVisibleParameterAnnotationsAttribute extends Attribute, MethodElement permits BoundAttribute.BoundRuntimeVisibleParameterAnnotationsAttribute, diff --git a/src/java.base/share/classes/java/lang/classfile/attribute/RuntimeVisibleTypeAnnotationsAttribute.java b/src/java.base/share/classes/java/lang/classfile/attribute/RuntimeVisibleTypeAnnotationsAttribute.java index 20dc89d700c..a4e780c4536 100644 --- a/src/java.base/share/classes/java/lang/classfile/attribute/RuntimeVisibleTypeAnnotationsAttribute.java +++ b/src/java.base/share/classes/java/lang/classfile/attribute/RuntimeVisibleTypeAnnotationsAttribute.java @@ -35,7 +35,6 @@ import jdk.internal.classfile.impl.BoundAttribute; import jdk.internal.classfile.impl.UnboundAttribute; -import jdk.internal.javac.PreviewFeature; /** * Models the {@code RuntimeVisibleTypeAnnotations} attribute (JVMS {@jvms 4.7.20}), which @@ -50,9 +49,8 @@ *

* The attribute was introduced in the Java SE Platform version 8. * - * @since 22 + * @since 24 */ -@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) public sealed interface RuntimeVisibleTypeAnnotationsAttribute extends Attribute, ClassElement, MethodElement, FieldElement, CodeElement diff --git a/src/java.base/share/classes/java/lang/classfile/attribute/SignatureAttribute.java b/src/java.base/share/classes/java/lang/classfile/attribute/SignatureAttribute.java index ca4cc62852a..8f06e16a1b1 100644 --- a/src/java.base/share/classes/java/lang/classfile/attribute/SignatureAttribute.java +++ b/src/java.base/share/classes/java/lang/classfile/attribute/SignatureAttribute.java @@ -31,7 +31,6 @@ import jdk.internal.classfile.impl.BoundAttribute; import jdk.internal.classfile.impl.TemporaryConstantPool; import jdk.internal.classfile.impl.UnboundAttribute; -import jdk.internal.javac.PreviewFeature; /** * Models the {@code Signature} attribute (JVMS {@jvms 4.7.9}), which @@ -46,9 +45,8 @@ *

* The attribute was introduced in the Java SE Platform version 5.0. * - * @since 22 + * @since 24 */ -@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) public sealed interface SignatureAttribute extends Attribute, ClassElement, MethodElement, FieldElement diff --git a/src/java.base/share/classes/java/lang/classfile/attribute/SourceDebugExtensionAttribute.java b/src/java.base/share/classes/java/lang/classfile/attribute/SourceDebugExtensionAttribute.java index e181b7fb14a..0e6b7267263 100644 --- a/src/java.base/share/classes/java/lang/classfile/attribute/SourceDebugExtensionAttribute.java +++ b/src/java.base/share/classes/java/lang/classfile/attribute/SourceDebugExtensionAttribute.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -30,7 +30,6 @@ import jdk.internal.classfile.impl.BoundAttribute; import jdk.internal.classfile.impl.UnboundAttribute; -import jdk.internal.javac.PreviewFeature; /** * Models the {@code SourceDebugExtension} attribute. @@ -43,9 +42,8 @@ *

* The attribute was introduced in the Java SE Platform version 5.0. * - * @since 22 + * @since 24 */ -@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) public sealed interface SourceDebugExtensionAttribute extends Attribute, ClassElement permits BoundAttribute.BoundSourceDebugExtensionAttribute, UnboundAttribute.UnboundSourceDebugExtensionAttribute { diff --git a/src/java.base/share/classes/java/lang/classfile/attribute/SourceFileAttribute.java b/src/java.base/share/classes/java/lang/classfile/attribute/SourceFileAttribute.java index d6c40058e7b..70f3d1e72ce 100644 --- a/src/java.base/share/classes/java/lang/classfile/attribute/SourceFileAttribute.java +++ b/src/java.base/share/classes/java/lang/classfile/attribute/SourceFileAttribute.java @@ -33,7 +33,6 @@ import jdk.internal.classfile.impl.BoundAttribute; import jdk.internal.classfile.impl.TemporaryConstantPool; import jdk.internal.classfile.impl.UnboundAttribute; -import jdk.internal.javac.PreviewFeature; /** * Models the {@code SourceFile} attribute (JVMS {@jvms 4.7.10}), which @@ -44,9 +43,8 @@ * Subsequent occurrence of the attribute takes precedence during the attributed * element build or transformation. * - * @since 22 + * @since 24 */ -@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) public sealed interface SourceFileAttribute extends Attribute, ClassElement permits BoundAttribute.BoundSourceFileAttribute, UnboundAttribute.UnboundSourceFileAttribute { diff --git a/src/java.base/share/classes/java/lang/classfile/attribute/SourceIDAttribute.java b/src/java.base/share/classes/java/lang/classfile/attribute/SourceIDAttribute.java index 69ff3bf57fd..71fd9d5b059 100644 --- a/src/java.base/share/classes/java/lang/classfile/attribute/SourceIDAttribute.java +++ b/src/java.base/share/classes/java/lang/classfile/attribute/SourceIDAttribute.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -33,7 +33,6 @@ import jdk.internal.classfile.impl.BoundAttribute; import jdk.internal.classfile.impl.TemporaryConstantPool; import jdk.internal.classfile.impl.UnboundAttribute; -import jdk.internal.javac.PreviewFeature; /** * Models the {@code SourceID} attribute, which can @@ -44,9 +43,8 @@ * Subsequent occurrence of the attribute takes precedence during the attributed * element build or transformation. * - * @since 22 + * @since 24 */ -@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) public sealed interface SourceIDAttribute extends Attribute, ClassElement permits BoundAttribute.BoundSourceIDAttribute, UnboundAttribute.UnboundSourceIDAttribute { diff --git a/src/java.base/share/classes/java/lang/classfile/attribute/StackMapFrameInfo.java b/src/java.base/share/classes/java/lang/classfile/attribute/StackMapFrameInfo.java index d041a73c58a..920db8ac9d7 100644 --- a/src/java.base/share/classes/java/lang/classfile/attribute/StackMapFrameInfo.java +++ b/src/java.base/share/classes/java/lang/classfile/attribute/StackMapFrameInfo.java @@ -32,14 +32,12 @@ import jdk.internal.classfile.impl.StackMapDecoder; import jdk.internal.classfile.impl.TemporaryConstantPool; -import jdk.internal.javac.PreviewFeature; /** * Models stack map frame of {@code StackMapTable} attribute (JVMS {@jvms 4.7.4}). * - * @since 22 + * @since 24 */ -@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) public sealed interface StackMapFrameInfo permits StackMapDecoder.StackMapFrameImpl { @@ -79,9 +77,8 @@ public static StackMapFrameInfo of(Label target, /** * The type of a stack value. * - * @since 22 + * @since 24 */ - @PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) sealed interface VerificationTypeInfo { /** The {@link #tag() tag} for verification type info {@link SimpleVerificationTypeInfo#TOP TOP}. */ @@ -124,9 +121,8 @@ sealed interface VerificationTypeInfo { /** * A simple stack value. * - * @since 22 + * @since 24 */ - @PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) public enum SimpleVerificationTypeInfo implements VerificationTypeInfo { /** verification type top */ @@ -166,9 +162,8 @@ public int tag() { /** * A stack value for an object type. Its {@link #tag() tag} is {@value #ITEM_OBJECT}. * - * @since 22 + * @since 24 */ - @PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) sealed interface ObjectVerificationTypeInfo extends VerificationTypeInfo permits StackMapDecoder.ObjectVerificationTypeInfoImpl { @@ -205,9 +200,8 @@ default ClassDesc classSymbol() { /** * An uninitialized stack value. Its {@link #tag() tag} is {@value #ITEM_UNINITIALIZED}. * - * @since 22 + * @since 24 */ - @PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) sealed interface UninitializedVerificationTypeInfo extends VerificationTypeInfo permits StackMapDecoder.UninitializedVerificationTypeInfoImpl { diff --git a/src/java.base/share/classes/java/lang/classfile/attribute/StackMapTableAttribute.java b/src/java.base/share/classes/java/lang/classfile/attribute/StackMapTableAttribute.java index a8aef4795d7..0d577fb6cd5 100644 --- a/src/java.base/share/classes/java/lang/classfile/attribute/StackMapTableAttribute.java +++ b/src/java.base/share/classes/java/lang/classfile/attribute/StackMapTableAttribute.java @@ -31,7 +31,6 @@ import jdk.internal.classfile.impl.BoundAttribute; import jdk.internal.classfile.impl.UnboundAttribute; -import jdk.internal.javac.PreviewFeature; /** * Models the {@code StackMapTable} attribute (JVMS {@jvms 4.7.4}), which can appear @@ -43,9 +42,8 @@ *

* The attribute was introduced in the Java SE Platform version 6. * - * @since 22 + * @since 24 */ -@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) public sealed interface StackMapTableAttribute extends Attribute, CodeElement permits BoundAttribute.BoundStackMapTableAttribute, UnboundAttribute.UnboundStackMapTableAttribute { diff --git a/src/java.base/share/classes/java/lang/classfile/attribute/SyntheticAttribute.java b/src/java.base/share/classes/java/lang/classfile/attribute/SyntheticAttribute.java index e5b5da7fbfe..1e6b706ec08 100644 --- a/src/java.base/share/classes/java/lang/classfile/attribute/SyntheticAttribute.java +++ b/src/java.base/share/classes/java/lang/classfile/attribute/SyntheticAttribute.java @@ -32,7 +32,6 @@ import jdk.internal.classfile.impl.BoundAttribute; import jdk.internal.classfile.impl.UnboundAttribute; -import jdk.internal.javac.PreviewFeature; /** * Models the {@code Synthetic} attribute (JVMS {@jvms 4.7.8}), which can appear on @@ -42,9 +41,8 @@ *

* The attribute permits multiple instances in a given location. * - * @since 22 + * @since 24 */ -@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) public sealed interface SyntheticAttribute extends Attribute, ClassElement, MethodElement, FieldElement diff --git a/src/java.base/share/classes/java/lang/classfile/attribute/UnknownAttribute.java b/src/java.base/share/classes/java/lang/classfile/attribute/UnknownAttribute.java index 5c1369e1308..ad47f35a856 100644 --- a/src/java.base/share/classes/java/lang/classfile/attribute/UnknownAttribute.java +++ b/src/java.base/share/classes/java/lang/classfile/attribute/UnknownAttribute.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -31,14 +31,12 @@ import java.lang.classfile.MethodElement; import jdk.internal.classfile.impl.BoundAttribute; -import jdk.internal.javac.PreviewFeature; /** * Models an unknown attribute on a class, method, or field. * - * @since 22 + * @since 24 */ -@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) public sealed interface UnknownAttribute extends Attribute, ClassElement, MethodElement, FieldElement diff --git a/src/java.base/share/classes/java/lang/classfile/attribute/package-info.java b/src/java.base/share/classes/java/lang/classfile/attribute/package-info.java index 3047ef659e5..08bd28cbc58 100644 --- a/src/java.base/share/classes/java/lang/classfile/attribute/package-info.java +++ b/src/java.base/share/classes/java/lang/classfile/attribute/package-info.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -28,9 +28,7 @@ * * The {@code java.lang.classfile.attribute} package contains interfaces describing classfile attributes. * - * @since 22 + * @since 24 */ -@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) package java.lang.classfile.attribute; -import jdk.internal.javac.PreviewFeature; diff --git a/src/java.base/share/classes/java/lang/classfile/components/ClassPrinter.java b/src/java.base/share/classes/java/lang/classfile/components/ClassPrinter.java index 85768cbe6a4..7237dc54580 100644 --- a/src/java.base/share/classes/java/lang/classfile/components/ClassPrinter.java +++ b/src/java.base/share/classes/java/lang/classfile/components/ClassPrinter.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -36,7 +36,6 @@ import java.util.stream.Stream; import jdk.internal.classfile.impl.ClassPrinterImpl; -import jdk.internal.javac.PreviewFeature; /** * A printer of classfiles and its elements. @@ -60,9 +59,8 @@ * Another use case for {@link ClassPrinter} is to simplify writing of automated tests: * {@snippet lang="java" class="PackageSnippets" region="printNodesInTest"} * - * @since 22 + * @since 24 */ -@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) public final class ClassPrinter { private ClassPrinter() { @@ -71,9 +69,8 @@ private ClassPrinter() { /** * Level of detail to print or export. * - * @since 22 + * @since 24 */ - @PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) public enum Verbosity { /** @@ -106,9 +103,8 @@ public enum Verbosity { /** * Named, traversable, and printable node parent. * - * @since 22 + * @since 24 */ - @PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) public sealed interface Node { /** @@ -151,9 +147,8 @@ default void toYaml(Consumer out) { /** * A leaf node holding single printable value. * - * @since 22 + * @since 24 */ - @PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) public sealed interface LeafNode extends Node permits ClassPrinterImpl.LeafNodeImpl { @@ -167,9 +162,8 @@ public sealed interface LeafNode extends Node /** * A tree node holding {@link List} of nested nodes. * - * @since 22 + * @since 24 */ - @PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) public sealed interface ListNode extends Node, List permits ClassPrinterImpl.ListNodeImpl { } @@ -179,9 +173,8 @@ public sealed interface ListNode extends Node, List *

* Each {@link Map.Entry#getKey()} == {@link Map.Entry#getValue()}.{@link #name()}. * - * @since 22 + * @since 24 */ - @PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) public sealed interface MapNode extends Node, Map permits ClassPrinterImpl.MapNodeImpl { } diff --git a/src/java.base/share/classes/java/lang/classfile/components/ClassRemapper.java b/src/java.base/share/classes/java/lang/classfile/components/ClassRemapper.java index 4f7bd3199d5..4a2808ad4f0 100644 --- a/src/java.base/share/classes/java/lang/classfile/components/ClassRemapper.java +++ b/src/java.base/share/classes/java/lang/classfile/components/ClassRemapper.java @@ -35,7 +35,6 @@ import java.util.function.Function; import jdk.internal.classfile.impl.ClassRemapperImpl; -import jdk.internal.javac.PreviewFeature; import static java.util.Objects.requireNonNull; @@ -55,9 +54,8 @@ * Arrays of reference types are always decomposed, mapped as the base reference * types and composed back to arrays. * - * @since 22 + * @since 24 */ -@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) public sealed interface ClassRemapper extends ClassTransform permits ClassRemapperImpl { /** diff --git a/src/java.base/share/classes/java/lang/classfile/components/CodeLocalsShifter.java b/src/java.base/share/classes/java/lang/classfile/components/CodeLocalsShifter.java index 49838722461..9db85f54a45 100644 --- a/src/java.base/share/classes/java/lang/classfile/components/CodeLocalsShifter.java +++ b/src/java.base/share/classes/java/lang/classfile/components/CodeLocalsShifter.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -31,7 +31,6 @@ import java.lang.reflect.AccessFlag; import jdk.internal.classfile.impl.CodeLocalsShifterImpl; -import jdk.internal.javac.PreviewFeature; /** * {@link CodeLocalsShifter} is a {@link CodeTransform} shifting locals to @@ -39,9 +38,8 @@ * Locals pointing to the receiver or to method arguments slots are never shifted. * All locals pointing beyond the method arguments are re-indexed in order of appearance. * - * @since 22 + * @since 24 */ -@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) public sealed interface CodeLocalsShifter extends CodeTransform permits CodeLocalsShifterImpl { /** diff --git a/src/java.base/share/classes/java/lang/classfile/components/CodeRelabeler.java b/src/java.base/share/classes/java/lang/classfile/components/CodeRelabeler.java index 247d712e4f3..4ef82adfdb9 100644 --- a/src/java.base/share/classes/java/lang/classfile/components/CodeRelabeler.java +++ b/src/java.base/share/classes/java/lang/classfile/components/CodeRelabeler.java @@ -32,7 +32,6 @@ import java.util.function.BiFunction; import jdk.internal.classfile.impl.CodeRelabelerImpl; -import jdk.internal.javac.PreviewFeature; import static java.util.Objects.requireNonNull; @@ -46,9 +45,8 @@ * Repeated injection of the same code block must be relabeled, so each instance of * {@link java.lang.classfile.Label} is bound in the target bytecode exactly once. * - * @since 22 + * @since 24 */ -@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) public sealed interface CodeRelabeler extends CodeTransform permits CodeRelabelerImpl { /** diff --git a/src/java.base/share/classes/java/lang/classfile/components/CodeStackTracker.java b/src/java.base/share/classes/java/lang/classfile/components/CodeStackTracker.java index 1ee0b0948e1..3761e53ff19 100644 --- a/src/java.base/share/classes/java/lang/classfile/components/CodeStackTracker.java +++ b/src/java.base/share/classes/java/lang/classfile/components/CodeStackTracker.java @@ -31,7 +31,6 @@ import java.util.Optional; import jdk.internal.classfile.impl.CodeStackTrackerImpl; -import jdk.internal.javac.PreviewFeature; /** * {@link CodeStackTracker} is a {@link CodeTransform} tracking stack content @@ -51,9 +50,8 @@ * }); * } * - * @since 22 + * @since 24 */ -@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) public sealed interface CodeStackTracker extends CodeTransform permits CodeStackTrackerImpl { /** diff --git a/src/java.base/share/classes/java/lang/classfile/components/package-info.java b/src/java.base/share/classes/java/lang/classfile/components/package-info.java index 98a0095587d..be650f4c77c 100644 --- a/src/java.base/share/classes/java/lang/classfile/components/package-info.java +++ b/src/java.base/share/classes/java/lang/classfile/components/package-info.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -111,9 +111,7 @@ * instrumenting transformation: * {@snippet lang="java" class="PackageSnippets" region="classInstrumentation"} * - * @since 22 + * @since 24 */ -@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) package java.lang.classfile.components; -import jdk.internal.javac.PreviewFeature; diff --git a/src/java.base/share/classes/java/lang/classfile/constantpool/AnnotationConstantValueEntry.java b/src/java.base/share/classes/java/lang/classfile/constantpool/AnnotationConstantValueEntry.java index 6365fc3636a..5255ceb1ef7 100644 --- a/src/java.base/share/classes/java/lang/classfile/constantpool/AnnotationConstantValueEntry.java +++ b/src/java.base/share/classes/java/lang/classfile/constantpool/AnnotationConstantValueEntry.java @@ -27,8 +27,6 @@ import java.lang.classfile.AnnotationValue; import java.lang.constant.ConstantDesc; -import jdk.internal.javac.PreviewFeature; - /** * A constant pool entry that may be used by annotation constant values, * which includes the four kinds of primitive constants and UTF8 constants. @@ -43,9 +41,8 @@ * * @see AnnotationValue.OfConstant * @sealedGraph - * @since 22 + * @since 24 */ -@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) public sealed interface AnnotationConstantValueEntry extends PoolEntry permits DoubleEntry, FloatEntry, IntegerEntry, LongEntry, Utf8Entry { diff --git a/src/java.base/share/classes/java/lang/classfile/constantpool/ClassEntry.java b/src/java.base/share/classes/java/lang/classfile/constantpool/ClassEntry.java index 9e5f1f52049..2a3bd95da22 100644 --- a/src/java.base/share/classes/java/lang/classfile/constantpool/ClassEntry.java +++ b/src/java.base/share/classes/java/lang/classfile/constantpool/ClassEntry.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -28,16 +28,14 @@ import java.lang.constant.ConstantDesc; import jdk.internal.classfile.impl.AbstractPoolEntry; -import jdk.internal.javac.PreviewFeature; /** * Models a {@code CONSTANT_Class_info} constant in the constant pool of a * classfile. * @jvms 4.4.1 The CONSTANT_Class_info Structure * - * @since 22 + * @since 24 */ -@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) public sealed interface ClassEntry extends LoadableConstantEntry permits AbstractPoolEntry.ClassEntryImpl { diff --git a/src/java.base/share/classes/java/lang/classfile/constantpool/ConstantDynamicEntry.java b/src/java.base/share/classes/java/lang/classfile/constantpool/ConstantDynamicEntry.java index 7c55a09f3f4..72050cd9b8f 100644 --- a/src/java.base/share/classes/java/lang/classfile/constantpool/ConstantDynamicEntry.java +++ b/src/java.base/share/classes/java/lang/classfile/constantpool/ConstantDynamicEntry.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -31,16 +31,14 @@ import jdk.internal.classfile.impl.AbstractPoolEntry; import jdk.internal.classfile.impl.Util; -import jdk.internal.javac.PreviewFeature; /** * Models a {@code CONSTANT_Dynamic_info} constant in the constant pool of a * classfile. * @jvms 4.4.10 The CONSTANT_Dynamic_info and CONSTANT_InvokeDynamic_info Structures * - * @since 22 + * @since 24 */ -@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) public sealed interface ConstantDynamicEntry extends DynamicConstantPoolEntry, LoadableConstantEntry permits AbstractPoolEntry.ConstantDynamicEntryImpl { diff --git a/src/java.base/share/classes/java/lang/classfile/constantpool/ConstantPool.java b/src/java.base/share/classes/java/lang/classfile/constantpool/ConstantPool.java index 0225f6ec77d..91dc8906b7b 100644 --- a/src/java.base/share/classes/java/lang/classfile/constantpool/ConstantPool.java +++ b/src/java.base/share/classes/java/lang/classfile/constantpool/ConstantPool.java @@ -30,17 +30,14 @@ import java.util.Iterator; import java.util.NoSuchElementException; -import jdk.internal.javac.PreviewFeature; - /** * Provides read access to the constant pool and bootstrap method table of a * classfile. * @jvms 4.4 The Constant Pool * * @sealedGraph - * @since 22 + * @since 24 */ -@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) public sealed interface ConstantPool extends Iterable permits ClassReader, ConstantPoolBuilder { @@ -70,7 +67,6 @@ public sealed interface ConstantPool extends Iterable * @param cls the entry type * @throws ConstantPoolException if the index is out of range of the * constant pool, or the entry is not of the given type - * @since 23 */ T entryByIndex(int index, Class cls); diff --git a/src/java.base/share/classes/java/lang/classfile/constantpool/ConstantPoolBuilder.java b/src/java.base/share/classes/java/lang/classfile/constantpool/ConstantPoolBuilder.java index 0ce4a6868c8..2dc2a390bd1 100644 --- a/src/java.base/share/classes/java/lang/classfile/constantpool/ConstantPoolBuilder.java +++ b/src/java.base/share/classes/java/lang/classfile/constantpool/ConstantPoolBuilder.java @@ -35,7 +35,6 @@ import jdk.internal.classfile.impl.SplitConstantPool; import jdk.internal.classfile.impl.TemporaryConstantPool; import jdk.internal.classfile.impl.Util; -import jdk.internal.javac.PreviewFeature; import static java.util.Objects.requireNonNull; @@ -48,9 +47,8 @@ * The {@linkplain ConstantPoolBuilder} also provides access to some of the * state of the {@linkplain ClassBuilder}, such as classfile processing options. * - * @since 22 + * @since 24 */ -@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) public sealed interface ConstantPoolBuilder extends ConstantPool permits SplitConstantPool, TemporaryConstantPool { diff --git a/src/java.base/share/classes/java/lang/classfile/constantpool/ConstantPoolException.java b/src/java.base/share/classes/java/lang/classfile/constantpool/ConstantPoolException.java index 260c9af64d4..ce5ed26c4c9 100644 --- a/src/java.base/share/classes/java/lang/classfile/constantpool/ConstantPoolException.java +++ b/src/java.base/share/classes/java/lang/classfile/constantpool/ConstantPoolException.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -24,15 +24,13 @@ */ package java.lang.classfile.constantpool; -import jdk.internal.javac.PreviewFeature; /** * Thrown to indicate that requested entry cannot be obtained from the constant * pool. * - * @since 22 + * @since 24 */ -@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) public class ConstantPoolException extends IllegalArgumentException { @java.io.Serial diff --git a/src/java.base/share/classes/java/lang/classfile/constantpool/ConstantValueEntry.java b/src/java.base/share/classes/java/lang/classfile/constantpool/ConstantValueEntry.java index 924d0aca710..ae746042aa4 100644 --- a/src/java.base/share/classes/java/lang/classfile/constantpool/ConstantValueEntry.java +++ b/src/java.base/share/classes/java/lang/classfile/constantpool/ConstantValueEntry.java @@ -27,17 +27,14 @@ import java.lang.classfile.Attributes; import java.lang.constant.ConstantDesc; -import jdk.internal.javac.PreviewFeature; - /** * Models a constant pool entry that can be used as the constant in a * {@link Attributes#constantValue() ConstantValue} attribute; this includes the four * primitive constant types and {@linkplain String} constants. * * @sealedGraph - * @since 22 + * @since 24 */ -@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) public sealed interface ConstantValueEntry extends LoadableConstantEntry permits DoubleEntry, FloatEntry, IntegerEntry, LongEntry, StringEntry { diff --git a/src/java.base/share/classes/java/lang/classfile/constantpool/DoubleEntry.java b/src/java.base/share/classes/java/lang/classfile/constantpool/DoubleEntry.java index 8dd4ba1ffd9..ebc3a837bb0 100644 --- a/src/java.base/share/classes/java/lang/classfile/constantpool/DoubleEntry.java +++ b/src/java.base/share/classes/java/lang/classfile/constantpool/DoubleEntry.java @@ -27,16 +27,14 @@ import java.lang.classfile.TypeKind; import jdk.internal.classfile.impl.AbstractPoolEntry; -import jdk.internal.javac.PreviewFeature; /** * Models a {@code CONSTANT_Double_info} constant in the constant pool of a * classfile. * @jvms 4.4.5 The CONSTANT_Long_info and CONSTANT_Double_info Structures * - * @since 22 + * @since 24 */ -@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) public sealed interface DoubleEntry extends AnnotationConstantValueEntry, ConstantValueEntry permits AbstractPoolEntry.DoubleEntryImpl { diff --git a/src/java.base/share/classes/java/lang/classfile/constantpool/DynamicConstantPoolEntry.java b/src/java.base/share/classes/java/lang/classfile/constantpool/DynamicConstantPoolEntry.java index ac763049410..3ec4fbbdbee 100644 --- a/src/java.base/share/classes/java/lang/classfile/constantpool/DynamicConstantPoolEntry.java +++ b/src/java.base/share/classes/java/lang/classfile/constantpool/DynamicConstantPoolEntry.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,17 +26,14 @@ import java.lang.classfile.BootstrapMethodEntry; -import jdk.internal.javac.PreviewFeature; - /** * Models a dynamic constant pool entry, which is either {@link ConstantDynamicEntry} * or {@link InvokeDynamicEntry}. * @jvms 4.4.10 The CONSTANT_Dynamic_info and CONSTANT_InvokeDynamic_info Structures * * @sealedGraph - * @since 22 + * @since 24 */ -@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) public sealed interface DynamicConstantPoolEntry extends PoolEntry permits ConstantDynamicEntry, InvokeDynamicEntry { diff --git a/src/java.base/share/classes/java/lang/classfile/constantpool/FieldRefEntry.java b/src/java.base/share/classes/java/lang/classfile/constantpool/FieldRefEntry.java index ab122f410b6..47f5b6710d8 100644 --- a/src/java.base/share/classes/java/lang/classfile/constantpool/FieldRefEntry.java +++ b/src/java.base/share/classes/java/lang/classfile/constantpool/FieldRefEntry.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -28,16 +28,14 @@ import jdk.internal.classfile.impl.AbstractPoolEntry; import jdk.internal.classfile.impl.Util; -import jdk.internal.javac.PreviewFeature; /** * Models a {@code CONSTANT_Fieldref_info} constant in the constant pool of a * classfile. * @jvms 4.4.2 The CONSTANT_Fieldref_info, CONSTANT_Methodref_info, and CONSTANT_InterfaceMethodref_info Structures * - * @since 22 + * @since 24 */ -@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) public sealed interface FieldRefEntry extends MemberRefEntry permits AbstractPoolEntry.FieldRefEntryImpl { diff --git a/src/java.base/share/classes/java/lang/classfile/constantpool/FloatEntry.java b/src/java.base/share/classes/java/lang/classfile/constantpool/FloatEntry.java index 7a91dd11153..eeb44e92b7c 100644 --- a/src/java.base/share/classes/java/lang/classfile/constantpool/FloatEntry.java +++ b/src/java.base/share/classes/java/lang/classfile/constantpool/FloatEntry.java @@ -27,16 +27,14 @@ import java.lang.classfile.TypeKind; import jdk.internal.classfile.impl.AbstractPoolEntry; -import jdk.internal.javac.PreviewFeature; /** * Models a {@code CONSTANT_Float_info} constant in the constant pool of a * classfile. * @jvms 4.4.4 The CONSTANT_Integer_info and CONSTANT_Float_info Structures * - * @since 22 + * @since 24 */ -@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) public sealed interface FloatEntry extends AnnotationConstantValueEntry, ConstantValueEntry permits AbstractPoolEntry.FloatEntryImpl { diff --git a/src/java.base/share/classes/java/lang/classfile/constantpool/IntegerEntry.java b/src/java.base/share/classes/java/lang/classfile/constantpool/IntegerEntry.java index 7cd21e37db8..908f17d1cb7 100644 --- a/src/java.base/share/classes/java/lang/classfile/constantpool/IntegerEntry.java +++ b/src/java.base/share/classes/java/lang/classfile/constantpool/IntegerEntry.java @@ -27,16 +27,14 @@ import java.lang.classfile.TypeKind; import jdk.internal.classfile.impl.AbstractPoolEntry; -import jdk.internal.javac.PreviewFeature; /** * Models a {@code CONSTANT_Integer_info} constant in the constant pool of a * classfile. * @jvms 4.4.4 The CONSTANT_Integer_info and CONSTANT_Float_info Structures * - * @since 22 + * @since 24 */ -@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) public sealed interface IntegerEntry extends AnnotationConstantValueEntry, ConstantValueEntry permits AbstractPoolEntry.IntegerEntryImpl { diff --git a/src/java.base/share/classes/java/lang/classfile/constantpool/InterfaceMethodRefEntry.java b/src/java.base/share/classes/java/lang/classfile/constantpool/InterfaceMethodRefEntry.java index 8f15053e5b7..7b1a94f123a 100644 --- a/src/java.base/share/classes/java/lang/classfile/constantpool/InterfaceMethodRefEntry.java +++ b/src/java.base/share/classes/java/lang/classfile/constantpool/InterfaceMethodRefEntry.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -28,16 +28,14 @@ import jdk.internal.classfile.impl.AbstractPoolEntry; import jdk.internal.classfile.impl.Util; -import jdk.internal.javac.PreviewFeature; /** * Models a {@code CONSTANT_InterfaceMethodRef_info} constant in the constant pool of a * classfile. * @jvms 4.4.2 The CONSTANT_Fieldref_info, CONSTANT_Methodref_info, and CONSTANT_InterfaceMethodref_info Structures * - * @since 22 + * @since 24 */ -@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) public sealed interface InterfaceMethodRefEntry extends MemberRefEntry permits AbstractPoolEntry.InterfaceMethodRefEntryImpl { diff --git a/src/java.base/share/classes/java/lang/classfile/constantpool/InvokeDynamicEntry.java b/src/java.base/share/classes/java/lang/classfile/constantpool/InvokeDynamicEntry.java index f06c3d4c782..0cc8b6823df 100644 --- a/src/java.base/share/classes/java/lang/classfile/constantpool/InvokeDynamicEntry.java +++ b/src/java.base/share/classes/java/lang/classfile/constantpool/InvokeDynamicEntry.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -30,15 +30,13 @@ import jdk.internal.classfile.impl.AbstractPoolEntry; import jdk.internal.classfile.impl.Util; -import jdk.internal.javac.PreviewFeature; /** * Models a constant pool entry for a dynamic call site. * @jvms 4.4.10 The CONSTANT_Dynamic_info and CONSTANT_InvokeDynamic_info Structures * - * @since 22 + * @since 24 */ -@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) public sealed interface InvokeDynamicEntry extends DynamicConstantPoolEntry permits AbstractPoolEntry.InvokeDynamicEntryImpl { diff --git a/src/java.base/share/classes/java/lang/classfile/constantpool/LoadableConstantEntry.java b/src/java.base/share/classes/java/lang/classfile/constantpool/LoadableConstantEntry.java index c963e2425ea..32f85f64c7e 100644 --- a/src/java.base/share/classes/java/lang/classfile/constantpool/LoadableConstantEntry.java +++ b/src/java.base/share/classes/java/lang/classfile/constantpool/LoadableConstantEntry.java @@ -27,16 +27,13 @@ import java.lang.classfile.TypeKind; import java.lang.constant.ConstantDesc; -import jdk.internal.javac.PreviewFeature; - /** * Marker interface for constant pool entries suitable for loading via the * {@code LDC} instructions. * * @sealedGraph - * @since 22 + * @since 24 */ -@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) public sealed interface LoadableConstantEntry extends PoolEntry permits ClassEntry, ConstantDynamicEntry, ConstantValueEntry, MethodHandleEntry, MethodTypeEntry { diff --git a/src/java.base/share/classes/java/lang/classfile/constantpool/LongEntry.java b/src/java.base/share/classes/java/lang/classfile/constantpool/LongEntry.java index 75e02b19441..cd38dcfe014 100644 --- a/src/java.base/share/classes/java/lang/classfile/constantpool/LongEntry.java +++ b/src/java.base/share/classes/java/lang/classfile/constantpool/LongEntry.java @@ -27,16 +27,14 @@ import java.lang.classfile.TypeKind; import jdk.internal.classfile.impl.AbstractPoolEntry; -import jdk.internal.javac.PreviewFeature; /** * Models a {@code CONSTANT_Long_info} constant in the constant pool of a * classfile. * @jvms 4.4.5 The CONSTANT_Long_info and CONSTANT_Double_info Structures * - * @since 22 + * @since 24 */ -@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) public sealed interface LongEntry extends AnnotationConstantValueEntry, ConstantValueEntry permits AbstractPoolEntry.LongEntryImpl { diff --git a/src/java.base/share/classes/java/lang/classfile/constantpool/MemberRefEntry.java b/src/java.base/share/classes/java/lang/classfile/constantpool/MemberRefEntry.java index 7c9292c8f04..12d68796dd7 100644 --- a/src/java.base/share/classes/java/lang/classfile/constantpool/MemberRefEntry.java +++ b/src/java.base/share/classes/java/lang/classfile/constantpool/MemberRefEntry.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,16 +25,14 @@ package java.lang.classfile.constantpool; import jdk.internal.classfile.impl.AbstractPoolEntry; -import jdk.internal.javac.PreviewFeature; /** * Models a member reference constant in the constant pool of a classfile, * which includes references to fields, methods, and interface methods. * * @sealedGraph - * @since 22 + * @since 24 */ -@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) public sealed interface MemberRefEntry extends PoolEntry permits FieldRefEntry, InterfaceMethodRefEntry, MethodRefEntry, AbstractPoolEntry.AbstractMemberRefEntry { /** diff --git a/src/java.base/share/classes/java/lang/classfile/constantpool/MethodHandleEntry.java b/src/java.base/share/classes/java/lang/classfile/constantpool/MethodHandleEntry.java index 37ec30648ab..d2e08ef178c 100644 --- a/src/java.base/share/classes/java/lang/classfile/constantpool/MethodHandleEntry.java +++ b/src/java.base/share/classes/java/lang/classfile/constantpool/MethodHandleEntry.java @@ -28,16 +28,14 @@ import java.lang.constant.DirectMethodHandleDesc; import jdk.internal.classfile.impl.AbstractPoolEntry; -import jdk.internal.javac.PreviewFeature; /** * Models a {@code CONSTANT_MethodHandle_info} constant in the constant pool of a * classfile. * @jvms 4.4.8 The CONSTANT_MethodHandle_info Structure * - * @since 22 + * @since 24 */ -@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) public sealed interface MethodHandleEntry extends LoadableConstantEntry permits AbstractPoolEntry.MethodHandleEntryImpl { diff --git a/src/java.base/share/classes/java/lang/classfile/constantpool/MethodRefEntry.java b/src/java.base/share/classes/java/lang/classfile/constantpool/MethodRefEntry.java index ff3f5e5220c..5be9e88fa2f 100644 --- a/src/java.base/share/classes/java/lang/classfile/constantpool/MethodRefEntry.java +++ b/src/java.base/share/classes/java/lang/classfile/constantpool/MethodRefEntry.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -28,16 +28,14 @@ import jdk.internal.classfile.impl.AbstractPoolEntry; import jdk.internal.classfile.impl.Util; -import jdk.internal.javac.PreviewFeature; /** * Models a {@code CONSTANT_MethodRef_info} constant in the constant pool of a * classfile. * @jvms 4.4.2 The CONSTANT_Fieldref_info, CONSTANT_Methodref_info, and CONSTANT_InterfaceMethodref_info Structures * - * @since 22 + * @since 24 */ -@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) public sealed interface MethodRefEntry extends MemberRefEntry permits AbstractPoolEntry.MethodRefEntryImpl { diff --git a/src/java.base/share/classes/java/lang/classfile/constantpool/MethodTypeEntry.java b/src/java.base/share/classes/java/lang/classfile/constantpool/MethodTypeEntry.java index d626aeb4900..b6fad856358 100644 --- a/src/java.base/share/classes/java/lang/classfile/constantpool/MethodTypeEntry.java +++ b/src/java.base/share/classes/java/lang/classfile/constantpool/MethodTypeEntry.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -28,16 +28,14 @@ import java.lang.constant.MethodTypeDesc; import jdk.internal.classfile.impl.AbstractPoolEntry; -import jdk.internal.javac.PreviewFeature; /** * Models a {@code CONSTANT_MethodType_info} constant in the constant pool of a * classfile. * @jvms 4.4.9 The CONSTANT_MethodType_info Structure * - * @since 22 + * @since 24 */ -@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) public sealed interface MethodTypeEntry extends LoadableConstantEntry permits AbstractPoolEntry.MethodTypeEntryImpl { diff --git a/src/java.base/share/classes/java/lang/classfile/constantpool/ModuleEntry.java b/src/java.base/share/classes/java/lang/classfile/constantpool/ModuleEntry.java index db7aa1f76fe..d0cdae5678f 100644 --- a/src/java.base/share/classes/java/lang/classfile/constantpool/ModuleEntry.java +++ b/src/java.base/share/classes/java/lang/classfile/constantpool/ModuleEntry.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -27,16 +27,14 @@ import java.lang.constant.ModuleDesc; import jdk.internal.classfile.impl.AbstractPoolEntry; -import jdk.internal.javac.PreviewFeature; /** * Models a {@code CONSTANT_Module_info} constant in the constant pool of a * classfile. * @jvms 4.4.11 The CONSTANT_Module_info Structure * - * @since 22 + * @since 24 */ -@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) public sealed interface ModuleEntry extends PoolEntry permits AbstractPoolEntry.ModuleEntryImpl { /** diff --git a/src/java.base/share/classes/java/lang/classfile/constantpool/NameAndTypeEntry.java b/src/java.base/share/classes/java/lang/classfile/constantpool/NameAndTypeEntry.java index d4beff2aff7..eff7e3456d1 100644 --- a/src/java.base/share/classes/java/lang/classfile/constantpool/NameAndTypeEntry.java +++ b/src/java.base/share/classes/java/lang/classfile/constantpool/NameAndTypeEntry.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,16 +25,14 @@ package java.lang.classfile.constantpool; import jdk.internal.classfile.impl.AbstractPoolEntry; -import jdk.internal.javac.PreviewFeature; /** * Models a {@code CONSTANT_NameAndType_info} constant in the constant pool of a * classfile. * @jvms 4.4.6 The CONSTANT_NameAndType_info Structure * - * @since 22 + * @since 24 */ -@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) public sealed interface NameAndTypeEntry extends PoolEntry permits AbstractPoolEntry.NameAndTypeEntryImpl { diff --git a/src/java.base/share/classes/java/lang/classfile/constantpool/PackageEntry.java b/src/java.base/share/classes/java/lang/classfile/constantpool/PackageEntry.java index 5725d411028..54ea2fc38e5 100644 --- a/src/java.base/share/classes/java/lang/classfile/constantpool/PackageEntry.java +++ b/src/java.base/share/classes/java/lang/classfile/constantpool/PackageEntry.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -27,16 +27,14 @@ import java.lang.constant.PackageDesc; import jdk.internal.classfile.impl.AbstractPoolEntry; -import jdk.internal.javac.PreviewFeature; /** * Models a {@code CONSTANT_Package_info} constant in the constant pool of a * classfile. * @jvms 4.4.12 The CONSTANT_Package_info Structure * - * @since 22 + * @since 24 */ -@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) public sealed interface PackageEntry extends PoolEntry permits AbstractPoolEntry.PackageEntryImpl { /** diff --git a/src/java.base/share/classes/java/lang/classfile/constantpool/PoolEntry.java b/src/java.base/share/classes/java/lang/classfile/constantpool/PoolEntry.java index d2af4c7c11a..fdb8b497ff9 100644 --- a/src/java.base/share/classes/java/lang/classfile/constantpool/PoolEntry.java +++ b/src/java.base/share/classes/java/lang/classfile/constantpool/PoolEntry.java @@ -24,15 +24,12 @@ */ package java.lang.classfile.constantpool; -import jdk.internal.javac.PreviewFeature; - /** * Models an entry in the constant pool of a classfile. * * @sealedGraph - * @since 22 + * @since 24 */ -@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) public sealed interface PoolEntry permits AnnotationConstantValueEntry, DynamicConstantPoolEntry, LoadableConstantEntry, MemberRefEntry, ModuleEntry, NameAndTypeEntry, diff --git a/src/java.base/share/classes/java/lang/classfile/constantpool/StringEntry.java b/src/java.base/share/classes/java/lang/classfile/constantpool/StringEntry.java index 65f75a6a062..03ff7652f67 100644 --- a/src/java.base/share/classes/java/lang/classfile/constantpool/StringEntry.java +++ b/src/java.base/share/classes/java/lang/classfile/constantpool/StringEntry.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,16 +25,14 @@ package java.lang.classfile.constantpool; import jdk.internal.classfile.impl.AbstractPoolEntry; -import jdk.internal.javac.PreviewFeature; /** * Models a {@code CONSTANT_String_info} constant in the constant pool of a * classfile. * @jvms 4.4.3 The CONSTANT_String_info Structure * - * @since 22 + * @since 24 */ -@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) public sealed interface StringEntry extends ConstantValueEntry permits AbstractPoolEntry.StringEntryImpl { diff --git a/src/java.base/share/classes/java/lang/classfile/constantpool/Utf8Entry.java b/src/java.base/share/classes/java/lang/classfile/constantpool/Utf8Entry.java index b379854cfcb..db03bf6a403 100644 --- a/src/java.base/share/classes/java/lang/classfile/constantpool/Utf8Entry.java +++ b/src/java.base/share/classes/java/lang/classfile/constantpool/Utf8Entry.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,16 +25,14 @@ package java.lang.classfile.constantpool; import jdk.internal.classfile.impl.AbstractPoolEntry; -import jdk.internal.javac.PreviewFeature; /** * Models a {@code CONSTANT_UTF8_info} constant in the constant pool of a * classfile. * @jvms 4.4.7 The CONSTANT_Utf8_info Structure * - * @since 22 + * @since 24 */ -@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) public sealed interface Utf8Entry extends CharSequence, AnnotationConstantValueEntry permits AbstractPoolEntry.Utf8EntryImpl { diff --git a/src/java.base/share/classes/java/lang/classfile/constantpool/package-info.java b/src/java.base/share/classes/java/lang/classfile/constantpool/package-info.java index 1ba2b63b6a1..83039c6565c 100644 --- a/src/java.base/share/classes/java/lang/classfile/constantpool/package-info.java +++ b/src/java.base/share/classes/java/lang/classfile/constantpool/package-info.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -28,9 +28,7 @@ * * The {@code java.lang.classfile.constantpool} package contains interfaces describing classfile constant pool entries. * - * @since 22 + * @since 24 */ -@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) package java.lang.classfile.constantpool; -import jdk.internal.javac.PreviewFeature; diff --git a/src/java.base/share/classes/java/lang/classfile/instruction/ArrayLoadInstruction.java b/src/java.base/share/classes/java/lang/classfile/instruction/ArrayLoadInstruction.java index b66627ef212..cc0e0b89f80 100644 --- a/src/java.base/share/classes/java/lang/classfile/instruction/ArrayLoadInstruction.java +++ b/src/java.base/share/classes/java/lang/classfile/instruction/ArrayLoadInstruction.java @@ -32,7 +32,6 @@ import jdk.internal.classfile.impl.AbstractInstruction; import jdk.internal.classfile.impl.Util; -import jdk.internal.javac.PreviewFeature; /** * Models an array load instruction in the {@code code} array of a {@code Code} @@ -40,9 +39,8 @@ * Opcode.Kind#ARRAY_LOAD}. Delivered as a {@link CodeElement} when * traversing the elements of a {@link CodeModel}. * - * @since 22 + * @since 24 */ -@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) public sealed interface ArrayLoadInstruction extends Instruction permits AbstractInstruction.UnboundArrayLoadInstruction { /** diff --git a/src/java.base/share/classes/java/lang/classfile/instruction/ArrayStoreInstruction.java b/src/java.base/share/classes/java/lang/classfile/instruction/ArrayStoreInstruction.java index f009cfca361..c350b3a5928 100644 --- a/src/java.base/share/classes/java/lang/classfile/instruction/ArrayStoreInstruction.java +++ b/src/java.base/share/classes/java/lang/classfile/instruction/ArrayStoreInstruction.java @@ -32,7 +32,6 @@ import jdk.internal.classfile.impl.AbstractInstruction; import jdk.internal.classfile.impl.Util; -import jdk.internal.javac.PreviewFeature; /** * Models an array store instruction in the {@code code} array of a {@code Code} @@ -40,9 +39,8 @@ * Opcode.Kind#ARRAY_STORE}. Delivered as a {@link CodeElement} when * traversing the elements of a {@link CodeModel}. * - * @since 22 + * @since 24 */ -@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) public sealed interface ArrayStoreInstruction extends Instruction permits AbstractInstruction.UnboundArrayStoreInstruction { /** diff --git a/src/java.base/share/classes/java/lang/classfile/instruction/BranchInstruction.java b/src/java.base/share/classes/java/lang/classfile/instruction/BranchInstruction.java index 6b2142fa0e1..2fdc00fced1 100644 --- a/src/java.base/share/classes/java/lang/classfile/instruction/BranchInstruction.java +++ b/src/java.base/share/classes/java/lang/classfile/instruction/BranchInstruction.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -32,7 +32,6 @@ import jdk.internal.classfile.impl.AbstractInstruction; import jdk.internal.classfile.impl.Util; -import jdk.internal.javac.PreviewFeature; /** * Models a branching instruction (conditional or unconditional) in the {@code @@ -40,9 +39,8 @@ * {@code kind} of {@link Opcode.Kind#BRANCH}. Delivered as a {@link * CodeElement} when traversing the elements of a {@link CodeModel}. * - * @since 22 + * @since 24 */ -@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) public sealed interface BranchInstruction extends Instruction permits AbstractInstruction.BoundBranchInstruction, AbstractInstruction.UnboundBranchInstruction { diff --git a/src/java.base/share/classes/java/lang/classfile/instruction/CharacterRange.java b/src/java.base/share/classes/java/lang/classfile/instruction/CharacterRange.java index 3d04473ab37..d47639d7dd7 100644 --- a/src/java.base/share/classes/java/lang/classfile/instruction/CharacterRange.java +++ b/src/java.base/share/classes/java/lang/classfile/instruction/CharacterRange.java @@ -34,7 +34,6 @@ import jdk.internal.classfile.impl.AbstractPseudoInstruction; import jdk.internal.classfile.impl.BoundCharacterRange; -import jdk.internal.javac.PreviewFeature; /** * A pseudo-instruction which models a single entry in the @@ -42,9 +41,8 @@ * during traversal of the elements of a {@link CodeModel}, according to * the setting of the {@link ClassFile.DebugElementsOption} option. * - * @since 22 + * @since 24 */ -@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) public sealed interface CharacterRange extends PseudoInstruction permits AbstractPseudoInstruction.UnboundCharacterRange, BoundCharacterRange { diff --git a/src/java.base/share/classes/java/lang/classfile/instruction/ConstantInstruction.java b/src/java.base/share/classes/java/lang/classfile/instruction/ConstantInstruction.java index c41793c614e..312c1868f19 100644 --- a/src/java.base/share/classes/java/lang/classfile/instruction/ConstantInstruction.java +++ b/src/java.base/share/classes/java/lang/classfile/instruction/ConstantInstruction.java @@ -35,7 +35,6 @@ import jdk.internal.classfile.impl.AbstractInstruction; import jdk.internal.classfile.impl.BytecodeHelpers; import jdk.internal.classfile.impl.Util; -import jdk.internal.javac.PreviewFeature; /** * Models a constant-load instruction in the {@code code} array of a {@code @@ -45,9 +44,8 @@ * a {@code kind} of {@link Opcode.Kind#CONSTANT}. Delivered as a {@link * CodeElement} when traversing the elements of a {@link CodeModel}. * - * @since 22 + * @since 24 */ -@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) public sealed interface ConstantInstruction extends Instruction { /** @@ -64,9 +62,8 @@ public sealed interface ConstantInstruction extends Instruction { * Models an "intrinsic constant" instruction (e.g., {@code * iconst_0}). * - * @since 22 + * @since 24 */ - @PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) sealed interface IntrinsicConstantInstruction extends ConstantInstruction permits AbstractInstruction.UnboundIntrinsicConstantInstruction { @@ -83,9 +80,8 @@ default TypeKind typeKind() { * Models an "argument constant" instruction (e.g., {@code * bipush}). * - * @since 22 + * @since 24 */ - @PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) sealed interface ArgumentConstantInstruction extends ConstantInstruction permits AbstractInstruction.BoundArgumentConstantInstruction, AbstractInstruction.UnboundArgumentConstantInstruction { @@ -106,9 +102,8 @@ default TypeKind typeKind() { * Models a "load constant" instruction (e.g., {@code * ldc}). * - * @since 22 + * @since 24 */ - @PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) sealed interface LoadConstantInstruction extends ConstantInstruction permits AbstractInstruction.BoundLoadConstantInstruction, AbstractInstruction.UnboundLoadConstantInstruction { diff --git a/src/java.base/share/classes/java/lang/classfile/instruction/ConvertInstruction.java b/src/java.base/share/classes/java/lang/classfile/instruction/ConvertInstruction.java index ec48c2f4663..468685779b9 100644 --- a/src/java.base/share/classes/java/lang/classfile/instruction/ConvertInstruction.java +++ b/src/java.base/share/classes/java/lang/classfile/instruction/ConvertInstruction.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -33,7 +33,6 @@ import jdk.internal.classfile.impl.AbstractInstruction; import jdk.internal.classfile.impl.BytecodeHelpers; import jdk.internal.classfile.impl.Util; -import jdk.internal.javac.PreviewFeature; /** * Models a primitive conversion instruction in the {@code code} array of a @@ -41,9 +40,8 @@ * a {@code kind} of {@link Opcode.Kind#CONVERT}. Delivered as a {@link * CodeElement} when traversing the elements of a {@link CodeModel}. * - * @since 22 + * @since 24 */ -@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) public sealed interface ConvertInstruction extends Instruction permits AbstractInstruction.UnboundConvertInstruction { /** diff --git a/src/java.base/share/classes/java/lang/classfile/instruction/DiscontinuedInstruction.java b/src/java.base/share/classes/java/lang/classfile/instruction/DiscontinuedInstruction.java index 0e4718a1c77..4e8ddcef385 100644 --- a/src/java.base/share/classes/java/lang/classfile/instruction/DiscontinuedInstruction.java +++ b/src/java.base/share/classes/java/lang/classfile/instruction/DiscontinuedInstruction.java @@ -33,16 +33,14 @@ import jdk.internal.classfile.impl.AbstractInstruction; import jdk.internal.classfile.impl.BytecodeHelpers; import jdk.internal.classfile.impl.Util; -import jdk.internal.javac.PreviewFeature; /** * Models instruction discontinued from the {@code code} array of a {@code Code} * attribute. Delivered as a {@link CodeElement} when traversing the elements of * a {@link CodeModel}. * - * @since 22 + * @since 24 */ -@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) public sealed interface DiscontinuedInstruction extends Instruction { /** @@ -52,9 +50,8 @@ public sealed interface DiscontinuedInstruction extends Instruction { * {@link Opcode.Kind#DISCONTINUED_JSR}. Delivered as a {@link CodeElement} * when traversing the elements of a {@link CodeModel}. * - * @since 22 + * @since 24 */ - @PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) sealed interface JsrInstruction extends DiscontinuedInstruction permits AbstractInstruction.BoundJsrInstruction, AbstractInstruction.UnboundJsrInstruction { @@ -95,9 +92,8 @@ static JsrInstruction of(Label target) { * {@link Opcode.Kind#DISCONTINUED_RET}. Delivered as a {@link CodeElement} * when traversing the elements of a {@link CodeModel}. * - * @since 22 + * @since 24 */ - @PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) sealed interface RetInstruction extends DiscontinuedInstruction permits AbstractInstruction.BoundRetInstruction, AbstractInstruction.UnboundRetInstruction { diff --git a/src/java.base/share/classes/java/lang/classfile/instruction/ExceptionCatch.java b/src/java.base/share/classes/java/lang/classfile/instruction/ExceptionCatch.java index 22b6f632abc..885f029d108 100644 --- a/src/java.base/share/classes/java/lang/classfile/instruction/ExceptionCatch.java +++ b/src/java.base/share/classes/java/lang/classfile/instruction/ExceptionCatch.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -32,7 +32,6 @@ import java.util.Optional; import jdk.internal.classfile.impl.AbstractPseudoInstruction; -import jdk.internal.javac.PreviewFeature; /** * A pseudo-instruction modeling an entry in the exception table of a code @@ -42,9 +41,8 @@ * * @see PseudoInstruction * - * @since 22 + * @since 24 */ -@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) public sealed interface ExceptionCatch extends PseudoInstruction permits AbstractPseudoInstruction.ExceptionCatchImpl { /** diff --git a/src/java.base/share/classes/java/lang/classfile/instruction/FieldInstruction.java b/src/java.base/share/classes/java/lang/classfile/instruction/FieldInstruction.java index c8a82fe7dfa..b547abd18ab 100644 --- a/src/java.base/share/classes/java/lang/classfile/instruction/FieldInstruction.java +++ b/src/java.base/share/classes/java/lang/classfile/instruction/FieldInstruction.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -37,7 +37,6 @@ import jdk.internal.classfile.impl.AbstractInstruction; import jdk.internal.classfile.impl.TemporaryConstantPool; import jdk.internal.classfile.impl.Util; -import jdk.internal.javac.PreviewFeature; /** * Models a field access instruction in the {@code code} array of a {@code Code} @@ -45,9 +44,8 @@ * Opcode.Kind#FIELD_ACCESS}. Delivered as a {@link CodeElement} when * traversing the elements of a {@link CodeModel}. * - * @since 22 + * @since 24 */ -@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) public sealed interface FieldInstruction extends Instruction permits AbstractInstruction.BoundFieldInstruction, AbstractInstruction.UnboundFieldInstruction { /** diff --git a/src/java.base/share/classes/java/lang/classfile/instruction/IncrementInstruction.java b/src/java.base/share/classes/java/lang/classfile/instruction/IncrementInstruction.java index 74fd6a4465a..7ea516c7cc5 100644 --- a/src/java.base/share/classes/java/lang/classfile/instruction/IncrementInstruction.java +++ b/src/java.base/share/classes/java/lang/classfile/instruction/IncrementInstruction.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -30,7 +30,6 @@ import java.lang.classfile.Opcode; import jdk.internal.classfile.impl.AbstractInstruction; -import jdk.internal.javac.PreviewFeature; /** * Models a local variable increment instruction in the {@code code} array of a @@ -38,9 +37,8 @@ * {@link Opcode.Kind#INCREMENT}. Delivered as a {@link CodeElement} when * traversing the elements of a {@link CodeModel}. * - * @since 22 + * @since 24 */ -@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) public sealed interface IncrementInstruction extends Instruction permits AbstractInstruction.BoundIncrementInstruction, AbstractInstruction.UnboundIncrementInstruction { diff --git a/src/java.base/share/classes/java/lang/classfile/instruction/InvokeDynamicInstruction.java b/src/java.base/share/classes/java/lang/classfile/instruction/InvokeDynamicInstruction.java index 6df960b88fa..43907b2a518 100644 --- a/src/java.base/share/classes/java/lang/classfile/instruction/InvokeDynamicInstruction.java +++ b/src/java.base/share/classes/java/lang/classfile/instruction/InvokeDynamicInstruction.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -38,16 +38,14 @@ import jdk.internal.classfile.impl.AbstractInstruction; import jdk.internal.classfile.impl.Util; -import jdk.internal.javac.PreviewFeature; /** * Models an {@code invokedynamic} instruction in the {@code code} array of a * {@code Code} attribute. Delivered as a {@link CodeElement} when traversing * the elements of a {@link CodeModel}. * - * @since 22 + * @since 24 */ -@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) public sealed interface InvokeDynamicInstruction extends Instruction permits AbstractInstruction.BoundInvokeDynamicInstruction, AbstractInstruction.UnboundInvokeDynamicInstruction { /** diff --git a/src/java.base/share/classes/java/lang/classfile/instruction/InvokeInstruction.java b/src/java.base/share/classes/java/lang/classfile/instruction/InvokeInstruction.java index 41ca5fd1519..904a17375ac 100644 --- a/src/java.base/share/classes/java/lang/classfile/instruction/InvokeInstruction.java +++ b/src/java.base/share/classes/java/lang/classfile/instruction/InvokeInstruction.java @@ -39,7 +39,6 @@ import jdk.internal.classfile.impl.AbstractInstruction; import jdk.internal.classfile.impl.TemporaryConstantPool; import jdk.internal.classfile.impl.Util; -import jdk.internal.javac.PreviewFeature; /** * Models a method invocation instruction in the {@code code} array of a {@code @@ -47,9 +46,8 @@ * will have a {@code kind} of {@link Opcode.Kind#INVOKE}. Delivered as a * {@link CodeElement} when traversing the elements of a {@link CodeModel}. * - * @since 22 + * @since 24 */ -@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) public sealed interface InvokeInstruction extends Instruction permits AbstractInstruction.BoundInvokeInterfaceInstruction, AbstractInstruction.BoundInvokeInstruction, AbstractInstruction.UnboundInvokeInstruction { /** diff --git a/src/java.base/share/classes/java/lang/classfile/instruction/LabelTarget.java b/src/java.base/share/classes/java/lang/classfile/instruction/LabelTarget.java index 8682d0ee508..bc1deffc98b 100644 --- a/src/java.base/share/classes/java/lang/classfile/instruction/LabelTarget.java +++ b/src/java.base/share/classes/java/lang/classfile/instruction/LabelTarget.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -30,7 +30,6 @@ import java.lang.classfile.PseudoInstruction; import jdk.internal.classfile.impl.LabelImpl; -import jdk.internal.javac.PreviewFeature; /** * A pseudo-instruction which indicates that the specified label corresponds to @@ -39,9 +38,8 @@ * * @see PseudoInstruction * - * @since 22 + * @since 24 */ -@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) public sealed interface LabelTarget extends PseudoInstruction permits LabelImpl { diff --git a/src/java.base/share/classes/java/lang/classfile/instruction/LineNumber.java b/src/java.base/share/classes/java/lang/classfile/instruction/LineNumber.java index a06e7cfceba..a9a497708c0 100644 --- a/src/java.base/share/classes/java/lang/classfile/instruction/LineNumber.java +++ b/src/java.base/share/classes/java/lang/classfile/instruction/LineNumber.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -31,7 +31,6 @@ import java.lang.classfile.attribute.LineNumberTableAttribute; import jdk.internal.classfile.impl.LineNumberImpl; -import jdk.internal.javac.PreviewFeature; /** * A pseudo-instruction which models a single entry in the @@ -41,9 +40,8 @@ * * @see PseudoInstruction * - * @since 22 + * @since 24 */ -@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) public sealed interface LineNumber extends PseudoInstruction permits LineNumberImpl { diff --git a/src/java.base/share/classes/java/lang/classfile/instruction/LoadInstruction.java b/src/java.base/share/classes/java/lang/classfile/instruction/LoadInstruction.java index ce6463ef924..c499dcc9944 100644 --- a/src/java.base/share/classes/java/lang/classfile/instruction/LoadInstruction.java +++ b/src/java.base/share/classes/java/lang/classfile/instruction/LoadInstruction.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -33,7 +33,6 @@ import jdk.internal.classfile.impl.AbstractInstruction; import jdk.internal.classfile.impl.BytecodeHelpers; import jdk.internal.classfile.impl.Util; -import jdk.internal.javac.PreviewFeature; /** * Models a local variable load instruction in the {@code code} array of a @@ -41,9 +40,8 @@ * {@link Opcode.Kind#LOAD}. Delivered as a {@link CodeElement} when * traversing the elements of a {@link CodeModel}. * - * @since 22 + * @since 24 */ -@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) public sealed interface LoadInstruction extends Instruction permits AbstractInstruction.BoundLoadInstruction, AbstractInstruction.UnboundLoadInstruction { diff --git a/src/java.base/share/classes/java/lang/classfile/instruction/LocalVariable.java b/src/java.base/share/classes/java/lang/classfile/instruction/LocalVariable.java index 390034bd666..0f8cb672e51 100644 --- a/src/java.base/share/classes/java/lang/classfile/instruction/LocalVariable.java +++ b/src/java.base/share/classes/java/lang/classfile/instruction/LocalVariable.java @@ -37,7 +37,6 @@ import jdk.internal.classfile.impl.BoundLocalVariable; import jdk.internal.classfile.impl.TemporaryConstantPool; import jdk.internal.classfile.impl.Util; -import jdk.internal.javac.PreviewFeature; /** * A pseudo-instruction which models a single entry in the @@ -47,9 +46,8 @@ * * @see PseudoInstruction * - * @since 22 + * @since 24 */ -@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) public sealed interface LocalVariable extends PseudoInstruction permits AbstractPseudoInstruction.UnboundLocalVariable, BoundLocalVariable { /** diff --git a/src/java.base/share/classes/java/lang/classfile/instruction/LocalVariableType.java b/src/java.base/share/classes/java/lang/classfile/instruction/LocalVariableType.java index d0d2cd1581f..c9427491733 100644 --- a/src/java.base/share/classes/java/lang/classfile/instruction/LocalVariableType.java +++ b/src/java.base/share/classes/java/lang/classfile/instruction/LocalVariableType.java @@ -36,7 +36,6 @@ import jdk.internal.classfile.impl.AbstractPseudoInstruction; import jdk.internal.classfile.impl.BoundLocalVariableType; import jdk.internal.classfile.impl.TemporaryConstantPool; -import jdk.internal.javac.PreviewFeature; /** * A pseudo-instruction which models a single entry in the {@link @@ -44,9 +43,8 @@ * traversal of the elements of a {@link CodeModel}, according to the setting of * the {@link ClassFile.DebugElementsOption} option. * - * @since 22 + * @since 24 */ -@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) public sealed interface LocalVariableType extends PseudoInstruction permits AbstractPseudoInstruction.UnboundLocalVariableType, BoundLocalVariableType { /** diff --git a/src/java.base/share/classes/java/lang/classfile/instruction/LookupSwitchInstruction.java b/src/java.base/share/classes/java/lang/classfile/instruction/LookupSwitchInstruction.java index ce6c0cce109..7b286e9cfd2 100644 --- a/src/java.base/share/classes/java/lang/classfile/instruction/LookupSwitchInstruction.java +++ b/src/java.base/share/classes/java/lang/classfile/instruction/LookupSwitchInstruction.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -31,16 +31,14 @@ import java.util.List; import jdk.internal.classfile.impl.AbstractInstruction; -import jdk.internal.javac.PreviewFeature; /** * Models a {@code lookupswitch} instruction in the {@code code} array of a * {@code Code} attribute. Delivered as a {@link CodeElement} when traversing * the elements of a {@link CodeModel}. * - * @since 22 + * @since 24 */ -@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) public sealed interface LookupSwitchInstruction extends Instruction permits AbstractInstruction.BoundLookupSwitchInstruction, AbstractInstruction.UnboundLookupSwitchInstruction { diff --git a/src/java.base/share/classes/java/lang/classfile/instruction/MonitorInstruction.java b/src/java.base/share/classes/java/lang/classfile/instruction/MonitorInstruction.java index 9bec7805339..1c8268cddd6 100644 --- a/src/java.base/share/classes/java/lang/classfile/instruction/MonitorInstruction.java +++ b/src/java.base/share/classes/java/lang/classfile/instruction/MonitorInstruction.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -31,16 +31,14 @@ import jdk.internal.classfile.impl.AbstractInstruction; import jdk.internal.classfile.impl.Util; -import jdk.internal.javac.PreviewFeature; /** * Models a {@code monitorenter} or {@code monitorexit} instruction in the * {@code code} array of a {@code Code} attribute. Delivered as a {@link * CodeElement} when traversing the elements of a {@link CodeModel}. * - * @since 22 + * @since 24 */ -@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) public sealed interface MonitorInstruction extends Instruction permits AbstractInstruction.UnboundMonitorInstruction { diff --git a/src/java.base/share/classes/java/lang/classfile/instruction/NewMultiArrayInstruction.java b/src/java.base/share/classes/java/lang/classfile/instruction/NewMultiArrayInstruction.java index f5e0129205c..4a1f6cfd170 100644 --- a/src/java.base/share/classes/java/lang/classfile/instruction/NewMultiArrayInstruction.java +++ b/src/java.base/share/classes/java/lang/classfile/instruction/NewMultiArrayInstruction.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -31,16 +31,14 @@ import jdk.internal.classfile.impl.AbstractInstruction; import jdk.internal.classfile.impl.BytecodeHelpers; -import jdk.internal.javac.PreviewFeature; /** * Models a {@code multianewarray} invocation instruction in the {@code code} * array of a {@code Code} attribute. Delivered as a {@link CodeElement} * when traversing the elements of a {@link CodeModel}. * - * @since 22 + * @since 24 */ -@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) public sealed interface NewMultiArrayInstruction extends Instruction permits AbstractInstruction.BoundNewMultidimensionalArrayInstruction, AbstractInstruction.UnboundNewMultidimensionalArrayInstruction { diff --git a/src/java.base/share/classes/java/lang/classfile/instruction/NewObjectInstruction.java b/src/java.base/share/classes/java/lang/classfile/instruction/NewObjectInstruction.java index e6e8fc64d17..f063733b64f 100644 --- a/src/java.base/share/classes/java/lang/classfile/instruction/NewObjectInstruction.java +++ b/src/java.base/share/classes/java/lang/classfile/instruction/NewObjectInstruction.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -30,16 +30,14 @@ import java.lang.classfile.constantpool.ClassEntry; import jdk.internal.classfile.impl.AbstractInstruction; -import jdk.internal.javac.PreviewFeature; /** * Models a {@code new} instruction in the {@code code} array of a {@code Code} * attribute. Delivered as a {@link CodeElement} when traversing the elements * of a {@link CodeModel}. * - * @since 22 + * @since 24 */ -@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) public sealed interface NewObjectInstruction extends Instruction permits AbstractInstruction.BoundNewObjectInstruction, AbstractInstruction.UnboundNewObjectInstruction { diff --git a/src/java.base/share/classes/java/lang/classfile/instruction/NewPrimitiveArrayInstruction.java b/src/java.base/share/classes/java/lang/classfile/instruction/NewPrimitiveArrayInstruction.java index 4adc7536c2c..411bf7f6b55 100644 --- a/src/java.base/share/classes/java/lang/classfile/instruction/NewPrimitiveArrayInstruction.java +++ b/src/java.base/share/classes/java/lang/classfile/instruction/NewPrimitiveArrayInstruction.java @@ -30,16 +30,14 @@ import java.lang.classfile.TypeKind; import jdk.internal.classfile.impl.AbstractInstruction; -import jdk.internal.javac.PreviewFeature; /** * Models a {@code newarray} invocation instruction in the {@code code} * array of a {@code Code} attribute. Delivered as a {@link CodeElement} * when traversing the elements of a {@link CodeModel}. * - * @since 22 + * @since 24 */ -@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) public sealed interface NewPrimitiveArrayInstruction extends Instruction permits AbstractInstruction.BoundNewPrimitiveArrayInstruction, AbstractInstruction.UnboundNewPrimitiveArrayInstruction { diff --git a/src/java.base/share/classes/java/lang/classfile/instruction/NewReferenceArrayInstruction.java b/src/java.base/share/classes/java/lang/classfile/instruction/NewReferenceArrayInstruction.java index b622f915c46..c85ed9dd3d9 100644 --- a/src/java.base/share/classes/java/lang/classfile/instruction/NewReferenceArrayInstruction.java +++ b/src/java.base/share/classes/java/lang/classfile/instruction/NewReferenceArrayInstruction.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -30,16 +30,14 @@ import java.lang.classfile.constantpool.ClassEntry; import jdk.internal.classfile.impl.AbstractInstruction; -import jdk.internal.javac.PreviewFeature; /** * Models a {@code anewarray} invocation instruction in the {@code code} * array of a {@code Code} attribute. Delivered as a {@link CodeElement} * when traversing the elements of a {@link CodeModel}. * - * @since 22 + * @since 24 */ -@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) public sealed interface NewReferenceArrayInstruction extends Instruction permits AbstractInstruction.BoundNewReferenceArrayInstruction, AbstractInstruction.UnboundNewReferenceArrayInstruction { /** diff --git a/src/java.base/share/classes/java/lang/classfile/instruction/NopInstruction.java b/src/java.base/share/classes/java/lang/classfile/instruction/NopInstruction.java index 3183ad88816..3c11803109a 100644 --- a/src/java.base/share/classes/java/lang/classfile/instruction/NopInstruction.java +++ b/src/java.base/share/classes/java/lang/classfile/instruction/NopInstruction.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -29,16 +29,14 @@ import java.lang.classfile.Instruction; import jdk.internal.classfile.impl.AbstractInstruction; -import jdk.internal.javac.PreviewFeature; /** * Models a {@code nop} invocation instruction in the {@code code} * array of a {@code Code} attribute. Delivered as a {@link CodeElement} * when traversing the elements of a {@link CodeModel}. * - * @since 22 + * @since 24 */ -@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) public sealed interface NopInstruction extends Instruction permits AbstractInstruction.UnboundNopInstruction { /** diff --git a/src/java.base/share/classes/java/lang/classfile/instruction/OperatorInstruction.java b/src/java.base/share/classes/java/lang/classfile/instruction/OperatorInstruction.java index 602f34ec03e..d1eb8aa1a3d 100644 --- a/src/java.base/share/classes/java/lang/classfile/instruction/OperatorInstruction.java +++ b/src/java.base/share/classes/java/lang/classfile/instruction/OperatorInstruction.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -32,7 +32,6 @@ import jdk.internal.classfile.impl.AbstractInstruction; import jdk.internal.classfile.impl.Util; -import jdk.internal.javac.PreviewFeature; /** * Models an arithmetic operator instruction in the {@code code} array of a @@ -40,9 +39,8 @@ * {@link Opcode.Kind#OPERATOR}. Delivered as a {@link CodeElement} when * traversing the elements of a {@link CodeModel}. * - * @since 22 + * @since 24 */ -@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) public sealed interface OperatorInstruction extends Instruction permits AbstractInstruction.UnboundOperatorInstruction { /** diff --git a/src/java.base/share/classes/java/lang/classfile/instruction/ReturnInstruction.java b/src/java.base/share/classes/java/lang/classfile/instruction/ReturnInstruction.java index 6596404a582..3bbb96b1cbe 100644 --- a/src/java.base/share/classes/java/lang/classfile/instruction/ReturnInstruction.java +++ b/src/java.base/share/classes/java/lang/classfile/instruction/ReturnInstruction.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -33,7 +33,6 @@ import jdk.internal.classfile.impl.AbstractInstruction; import jdk.internal.classfile.impl.BytecodeHelpers; import jdk.internal.classfile.impl.Util; -import jdk.internal.javac.PreviewFeature; /** * Models a return-from-method instruction in the {@code code} array of a @@ -41,9 +40,8 @@ * {@link Opcode.Kind#RETURN}. Delivered as a {@link CodeElement} when * traversing the elements of a {@link CodeModel}. * - * @since 22 + * @since 24 */ -@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) public sealed interface ReturnInstruction extends Instruction permits AbstractInstruction.UnboundReturnInstruction { diff --git a/src/java.base/share/classes/java/lang/classfile/instruction/StackInstruction.java b/src/java.base/share/classes/java/lang/classfile/instruction/StackInstruction.java index 17e9496652b..b01b206e368 100644 --- a/src/java.base/share/classes/java/lang/classfile/instruction/StackInstruction.java +++ b/src/java.base/share/classes/java/lang/classfile/instruction/StackInstruction.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -31,7 +31,6 @@ import jdk.internal.classfile.impl.AbstractInstruction; import jdk.internal.classfile.impl.Util; -import jdk.internal.javac.PreviewFeature; /** * Models a stack manipulation instruction in the {@code code} array of a @@ -39,9 +38,8 @@ * {@link Opcode.Kind#STACK}. Delivered as a {@link CodeElement} when * traversing the elements of a {@link CodeModel}. * - * @since 22 + * @since 24 */ -@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) public sealed interface StackInstruction extends Instruction permits AbstractInstruction.UnboundStackInstruction { diff --git a/src/java.base/share/classes/java/lang/classfile/instruction/StoreInstruction.java b/src/java.base/share/classes/java/lang/classfile/instruction/StoreInstruction.java index 68bf54e61c2..1d7bdce1fdf 100644 --- a/src/java.base/share/classes/java/lang/classfile/instruction/StoreInstruction.java +++ b/src/java.base/share/classes/java/lang/classfile/instruction/StoreInstruction.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -33,7 +33,6 @@ import jdk.internal.classfile.impl.AbstractInstruction; import jdk.internal.classfile.impl.BytecodeHelpers; import jdk.internal.classfile.impl.Util; -import jdk.internal.javac.PreviewFeature; /** * Models a local variable store instruction in the {@code code} array of a @@ -41,9 +40,8 @@ * {@link Opcode.Kind#STORE}. Delivered as a {@link CodeElement} when * traversing the elements of a {@link CodeModel}. * - * @since 22 + * @since 24 */ -@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) public sealed interface StoreInstruction extends Instruction permits AbstractInstruction.BoundStoreInstruction, AbstractInstruction.UnboundStoreInstruction { diff --git a/src/java.base/share/classes/java/lang/classfile/instruction/SwitchCase.java b/src/java.base/share/classes/java/lang/classfile/instruction/SwitchCase.java index 6149945532b..3f5f91031b6 100644 --- a/src/java.base/share/classes/java/lang/classfile/instruction/SwitchCase.java +++ b/src/java.base/share/classes/java/lang/classfile/instruction/SwitchCase.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -27,7 +27,6 @@ import java.lang.classfile.Label; import jdk.internal.classfile.impl.AbstractInstruction; -import jdk.internal.javac.PreviewFeature; /** * Models a single case in a {@code lookupswitch} or {@code tableswitch} @@ -36,9 +35,8 @@ * @see LookupSwitchInstruction * @see TableSwitchInstruction * - * @since 22 + * @since 24 */ -@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) public sealed interface SwitchCase permits AbstractInstruction.SwitchCaseImpl { diff --git a/src/java.base/share/classes/java/lang/classfile/instruction/TableSwitchInstruction.java b/src/java.base/share/classes/java/lang/classfile/instruction/TableSwitchInstruction.java index a8bce119db2..bbe7a4d6c0c 100644 --- a/src/java.base/share/classes/java/lang/classfile/instruction/TableSwitchInstruction.java +++ b/src/java.base/share/classes/java/lang/classfile/instruction/TableSwitchInstruction.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -31,16 +31,14 @@ import java.util.List; import jdk.internal.classfile.impl.AbstractInstruction; -import jdk.internal.javac.PreviewFeature; /** * Models a {@code tableswitch} instruction in the {@code code} array of a * {@code Code} attribute. Delivered as a {@link CodeElement} when traversing * the elements of a {@link CodeModel}. * - * @since 22 + * @since 24 */ -@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) public sealed interface TableSwitchInstruction extends Instruction permits AbstractInstruction.BoundTableSwitchInstruction, AbstractInstruction.UnboundTableSwitchInstruction { /** diff --git a/src/java.base/share/classes/java/lang/classfile/instruction/ThrowInstruction.java b/src/java.base/share/classes/java/lang/classfile/instruction/ThrowInstruction.java index 68d861ba06d..ec6fdc38626 100644 --- a/src/java.base/share/classes/java/lang/classfile/instruction/ThrowInstruction.java +++ b/src/java.base/share/classes/java/lang/classfile/instruction/ThrowInstruction.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -29,16 +29,14 @@ import java.lang.classfile.Instruction; import jdk.internal.classfile.impl.AbstractInstruction; -import jdk.internal.javac.PreviewFeature; /** * Models an {@code athrow} instruction in the {@code code} array of a * {@code Code} attribute. Delivered as a {@link CodeElement} when traversing * the elements of a {@link CodeModel}. * - * @since 22 + * @since 24 */ -@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) public sealed interface ThrowInstruction extends Instruction permits AbstractInstruction.UnboundThrowInstruction { diff --git a/src/java.base/share/classes/java/lang/classfile/instruction/TypeCheckInstruction.java b/src/java.base/share/classes/java/lang/classfile/instruction/TypeCheckInstruction.java index a4b9818a4be..032e7a8462b 100644 --- a/src/java.base/share/classes/java/lang/classfile/instruction/TypeCheckInstruction.java +++ b/src/java.base/share/classes/java/lang/classfile/instruction/TypeCheckInstruction.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -34,16 +34,14 @@ import jdk.internal.classfile.impl.AbstractInstruction; import jdk.internal.classfile.impl.TemporaryConstantPool; import jdk.internal.classfile.impl.Util; -import jdk.internal.javac.PreviewFeature; /** * Models an {@code instanceof} or {@code checkcast} instruction in the {@code * code} array of a {@code Code} attribute. Delivered as a {@link CodeElement} * when traversing the elements of a {@link CodeModel}. * - * @since 22 + * @since 24 */ -@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) public sealed interface TypeCheckInstruction extends Instruction permits AbstractInstruction.BoundTypeCheckInstruction, AbstractInstruction.UnboundTypeCheckInstruction { diff --git a/src/java.base/share/classes/java/lang/classfile/instruction/package-info.java b/src/java.base/share/classes/java/lang/classfile/instruction/package-info.java index 2bb35494da0..d2a36e16615 100644 --- a/src/java.base/share/classes/java/lang/classfile/instruction/package-info.java +++ b/src/java.base/share/classes/java/lang/classfile/instruction/package-info.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -28,9 +28,7 @@ * * The {@code java.lang.classfile.attribute} package contains interfaces describing code instructions. * - * @since 22 + * @since 24 */ -@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) package java.lang.classfile.instruction; -import jdk.internal.javac.PreviewFeature; diff --git a/src/java.base/share/classes/java/lang/classfile/package-info.java b/src/java.base/share/classes/java/lang/classfile/package-info.java index 6e9ecfe4819..2d6a8959a2d 100644 --- a/src/java.base/share/classes/java/lang/classfile/package-info.java +++ b/src/java.base/share/classes/java/lang/classfile/package-info.java @@ -546,9 +546,6 @@ * | CharacterRange(int rangeStart, int rangeEnd, int flags, Label startScope, Label endScope) * } * - * @since 22 + * @since 24 */ -@PreviewFeature(feature = PreviewFeature.Feature.CLASSFILE_API) package java.lang.classfile; - -import jdk.internal.javac.PreviewFeature; diff --git a/src/java.base/share/classes/jdk/internal/javac/PreviewFeature.java b/src/java.base/share/classes/jdk/internal/javac/PreviewFeature.java index 0dff7c8ce42..269a9a8416e 100644 --- a/src/java.base/share/classes/jdk/internal/javac/PreviewFeature.java +++ b/src/java.base/share/classes/jdk/internal/javac/PreviewFeature.java @@ -74,8 +74,6 @@ public enum Feature { SCOPED_VALUES, @JEP(number=480, title="Structured Concurrency", status="Third Preview") STRUCTURED_CONCURRENCY, - @JEP(number=466, title="ClassFile API", status="Second Preview") - CLASSFILE_API, STREAM_GATHERERS, @JEP(number=494, title="Module Import Declarations", status="Second Preview") MODULE_IMPORTS, From 40a055ebd2cdeda237108bb506126a09460de5b5 Mon Sep 17 00:00:00 2001 From: Daniel Fuchs Date: Fri, 15 Nov 2024 15:05:33 +0000 Subject: [PATCH 018/311] 8344228: Revisit SecurityManager usage in java.net.http after JEP 486 integration Reviewed-by: jpai --- .../classes/java/net/http/HttpClient.java | 3 - .../jdk/internal/net/http/Exchange.java | 155 +----------------- .../net/http/HttpClientBuilderImpl.java | 3 +- .../jdk/internal/net/http/HttpClientImpl.java | 51 +----- .../internal/net/http/HttpRequestImpl.java | 15 +- .../jdk/internal/net/http/MultiExchange.java | 14 +- .../net/http/PlainHttpConnection.java | 20 +-- .../net/http/PlainTunnelingConnection.java | 4 +- .../internal/net/http/PrivilegedExecutor.java | 72 -------- .../internal/net/http/RequestPublishers.java | 82 +-------- .../net/http/ResponseBodyHandlers.java | 85 +--------- .../net/http/ResponseSubscribers.java | 108 +----------- .../common/ImmutableExtendedSSLSession.java | 3 +- .../jdk/internal/net/http/common/Utils.java | 68 +------- .../jdk/internal/net/http/hpack/HPACK.java | 8 +- .../net/http/websocket/OpeningHandshake.java | 37 +---- .../java/net/httpclient/DebugLoggerTest.java | 4 +- .../FilePublisher/FilePublisherPermsTest.java | 4 - .../FilePublisher/SecureZipFSProvider.java | 9 +- test/jdk/java/net/httpclient/ProxyServer.java | 22 +-- .../lib/common/TestServerConfigurator.java | 14 +- .../FileProcessorPermissionTest.java | 10 +- .../net/http/AuthenticationFilterTest.java | 24 +-- .../jdk/internal/net/http/RawChannelTest.java | 3 +- .../internal/net/http/SimpleSSLContext.java | 27 +-- 25 files changed, 86 insertions(+), 759 deletions(-) delete mode 100644 src/java.net.http/share/classes/jdk/internal/net/http/PrivilegedExecutor.java diff --git a/src/java.net.http/share/classes/java/net/http/HttpClient.java b/src/java.net.http/share/classes/java/net/http/HttpClient.java index c1269eed823..fbd2e2aba36 100644 --- a/src/java.net.http/share/classes/java/net/http/HttpClient.java +++ b/src/java.net.http/share/classes/java/net/http/HttpClient.java @@ -37,9 +37,6 @@ import java.net.InetSocketAddress; import java.net.Proxy; import java.net.ProxySelector; -import java.net.URLPermission; -import java.security.AccessController; -import java.security.PrivilegedAction; import java.time.Duration; import java.util.Objects; import java.util.Optional; diff --git a/src/java.net.http/share/classes/jdk/internal/net/http/Exchange.java b/src/java.net.http/share/classes/jdk/internal/net/http/Exchange.java index 1ff1e5f4733..71e4e05d2c5 100644 --- a/src/java.net.http/share/classes/jdk/internal/net/http/Exchange.java +++ b/src/java.net.http/share/classes/jdk/internal/net/http/Exchange.java @@ -26,25 +26,15 @@ package jdk.internal.net.http; import java.io.IOException; -import java.net.InetSocketAddress; import java.net.ProtocolException; -import java.net.ProxySelector; -import java.net.URI; -import java.net.URISyntaxException; -import java.net.URLPermission; -import java.security.AccessControlContext; import java.time.Duration; -import java.util.List; -import java.util.Map; import java.util.Optional; import java.util.concurrent.CompletableFuture; import java.util.concurrent.Executor; import java.util.concurrent.TimeUnit; -import java.util.concurrent.TimeoutException; import java.util.concurrent.atomic.AtomicInteger; import java.util.function.Function; import java.net.http.HttpClient; -import java.net.http.HttpHeaders; import java.net.http.HttpResponse; import java.net.http.HttpTimeoutException; @@ -53,20 +43,11 @@ import jdk.internal.net.http.common.Utils; import jdk.internal.net.http.common.Log; -import static jdk.internal.net.http.common.Utils.permissionForProxy; - /** * One request/response exchange (handles 100/101 intermediate response also). * depth field used to track number of times a new request is being sent * for a given API request. If limit exceeded exception is thrown. * - * Security check is performed here: - * - uses AccessControlContext captured at API level - * - checks for appropriate URLPermission for request - * - if permission allowed, grants equivalent SocketPermission to call - * - in case of direct HTTP proxy, checks additionally for access to proxy - * (CONNECT proxying uses its own Exchange, so check done there) - * */ final class Exchange { @@ -83,8 +64,6 @@ final class Exchange { // used to record possible cancellation raised before the exchImpl // has been established. private volatile IOException failed; - @SuppressWarnings("removal") - final AccessControlContext acc; final MultiExchange multi; final Executor parentExecutor; volatile boolean upgrading; // to HTTP/2 @@ -103,22 +82,6 @@ final class Exchange { this.upgrading = false; this.client = multi.client(); this.multi = multi; - this.acc = multi.acc; - this.parentExecutor = multi.executor; - this.pushGroup = multi.pushGroup; - this.dbgTag = "Exchange"; - } - - /* If different AccessControlContext to be used */ - Exchange(HttpRequestImpl request, - MultiExchange multi, - @SuppressWarnings("removal") AccessControlContext acc) - { - this.request = request; - this.acc = acc; - this.upgrading = false; - this.client = multi.client(); - this.multi = multi; this.parentExecutor = multi.executor; this.pushGroup = multi.pushGroup; this.dbgTag = "Exchange"; @@ -338,7 +301,7 @@ private void checkCancelled() { } } - CompletableFuture checkCancelled(CompletableFuture cf, HttpConnection connection) { + CompletableFuture checkCancelled(CompletableFuture cf, HttpConnection connection) { return cf.handle((r,t) -> { if (t == null) { if (multi.requestCancelled()) { @@ -354,7 +317,7 @@ CompletableFuture checkCancelled(CompletableFuture cf, HttpConnection } catch (Throwable x) { if (debug.on()) debug.log("Failed to close connection", x); } - return MinimalFuture.failedFuture(t); + return MinimalFuture.failedFuture(t); } } } @@ -422,15 +385,6 @@ public CompletableFuture responseAsync() { return responseAsyncImpl(null); } - CompletableFuture responseAsyncImpl(HttpConnection connection) { - SecurityException e = checkPermissions(); - if (e != null) { - return MinimalFuture.failedFuture(e); - } else { - return responseAsyncImpl0(connection); - } - } - // check whether the headersSentCF was completed exceptionally with // ProxyAuthorizationRequired. If so the Response embedded in the // exception is returned. Otherwise we proceed. @@ -584,7 +538,7 @@ private CompletableFuture ignore1xxResponse(final Response rsp) { } } - CompletableFuture responseAsyncImpl0(HttpConnection connection) { + CompletableFuture responseAsyncImpl(HttpConnection connection) { Function, CompletableFuture> after407Check; bodyIgnored = null; if (request.expectContinue()) { @@ -735,109 +689,6 @@ HttpResponse.BodySubscriber ignoreBody(HttpResponse.ResponseInfo hdrs) { return MinimalFuture.completedFuture(resp); } - private URI getURIForSecurityCheck() { - URI u; - String method = request.method(); - InetSocketAddress authority = request.authority(); - URI uri = request.uri(); - - // CONNECT should be restricted at API level - if (method.equalsIgnoreCase("CONNECT")) { - try { - u = new URI("socket", - null, - authority.getHostString(), - authority.getPort(), - null, - null, - null); - } catch (URISyntaxException e) { - throw new InternalError(e); // shouldn't happen - } - } else { - u = uri; - } - return u; - } - - /** - * Returns the security permission required for the given details. - * If method is CONNECT, then uri must be of form "scheme://host:port" - */ - private static URLPermission permissionForServer(URI uri, - String method, - Map> headers) { - if (method.equals("CONNECT")) { - return new URLPermission(uri.toString(), "CONNECT"); - } else { - return Utils.permissionForServer(uri, method, headers.keySet().stream()); - } - } - - /** - * Performs the necessary security permission checks required to retrieve - * the response. Returns a security exception representing the denied - * permission, or null if all checks pass or there is no security manager. - */ - private SecurityException checkPermissions() { - String method = request.method(); - @SuppressWarnings("removal") - SecurityManager sm = System.getSecurityManager(); - if (sm == null || method.equals("CONNECT")) { - // tunneling will have a null acc, which is fine. The proxy - // permission check will have already been preformed. - return null; - } - - HttpHeaders userHeaders = request.getUserHeaders(); - URI u = getURIForSecurityCheck(); - URLPermission p = permissionForServer(u, method, userHeaders.map()); - - try { - assert acc != null; - sm.checkPermission(p, acc); - } catch (SecurityException e) { - return e; - } - String hostHeader = userHeaders.firstValue("Host").orElse(null); - if (hostHeader != null && !hostHeader.equalsIgnoreCase(u.getHost())) { - // user has set a Host header different to request URI - // must check that for URLPermission also - URI u1 = replaceHostInURI(u, hostHeader); - URLPermission p1 = permissionForServer(u1, method, userHeaders.map()); - try { - assert acc != null; - sm.checkPermission(p1, acc); - } catch (SecurityException e) { - return e; - } - } - ProxySelector ps = client.proxySelector(); - if (ps != null) { - if (!method.equals("CONNECT")) { - // a non-tunneling HTTP proxy. Need to check access - URLPermission proxyPerm = permissionForProxy(request.proxy()); - if (proxyPerm != null) { - try { - sm.checkPermission(proxyPerm, acc); - } catch (SecurityException e) { - return e; - } - } - } - } - return null; - } - - private static URI replaceHostInURI(URI u, String hostPort) { - StringBuilder sb = new StringBuilder(); - sb.append(u.getScheme()) - .append("://") - .append(hostPort) - .append(u.getRawPath()); - return URI.create(sb.toString()); - } - HttpClient.Version version() { return multi.version(); } diff --git a/src/java.net.http/share/classes/jdk/internal/net/http/HttpClientBuilderImpl.java b/src/java.net.http/share/classes/jdk/internal/net/http/HttpClientBuilderImpl.java index c4157b3c74c..65e9210f9cb 100644 --- a/src/java.net.http/share/classes/jdk/internal/net/http/HttpClientBuilderImpl.java +++ b/src/java.net.http/share/classes/jdk/internal/net/http/HttpClientBuilderImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -46,7 +46,6 @@ public class HttpClientBuilderImpl implements HttpClient.Builder { Authenticator authenticator; HttpClient.Version version; Executor executor; - // Security parameters SSLContext sslContext; SSLParameters sslParams; int priority = -1; diff --git a/src/java.net.http/share/classes/jdk/internal/net/http/HttpClientImpl.java b/src/java.net.http/share/classes/jdk/internal/net/http/HttpClientImpl.java index e1f4ec16dcd..4d7518d4054 100644 --- a/src/java.net.http/share/classes/jdk/internal/net/http/HttpClientImpl.java +++ b/src/java.net.http/share/classes/jdk/internal/net/http/HttpClientImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -48,10 +48,7 @@ import java.nio.channels.SelectableChannel; import java.nio.channels.SelectionKey; import java.nio.channels.Selector; -import java.security.AccessControlContext; -import java.security.AccessController; import java.security.NoSuchAlgorithmException; -import java.security.PrivilegedAction; import java.time.Duration; import java.time.temporal.ChronoUnit; import java.util.ArrayList; @@ -97,7 +94,6 @@ import jdk.internal.net.http.common.OperationTrackers.Trackable; import jdk.internal.net.http.common.OperationTrackers.Tracker; import jdk.internal.net.http.websocket.BuilderImpl; -import jdk.internal.misc.InnocuousThread; /** * Client implementation. Contains all configuration information and also @@ -131,16 +127,10 @@ private static final class DefaultThreadFactory implements ThreadFactory { namePrefix = "HttpClient-" + clientID + "-Worker-"; } - @SuppressWarnings("removal") @Override public Thread newThread(Runnable r) { String name = namePrefix + nextId.getAndIncrement(); - Thread t; - if (System.getSecurityManager() == null) { - t = new Thread(null, r, name, 0, false); - } else { - t = InnocuousThread.newThread(name, r); - } + Thread t = new Thread(null, r, name, 0, false); t.setDaemon(true); return t; } @@ -188,15 +178,9 @@ public void ensureExecutedAsync(Runnable command) { } } - @SuppressWarnings("removal") private void shutdown() { if (delegate instanceof ExecutorService service) { - PrivilegedAction action = () -> { - service.shutdown(); - return null; - }; - AccessController.doPrivileged(action, null, - new RuntimePermission("modifyThread")); + service.shutdown(); } } } @@ -336,7 +320,6 @@ static void abortPendingRequests(HttpClientImpl client, Throwable reason) { private final ConnectionPool connections; private final DelegatingExecutor delegatingExecutor; private final boolean isDefaultExecutor; - // Security parameters private final SSLContext sslContext; private final SSLParameters sslParams; private final SelectorManager selmgr; @@ -445,16 +428,6 @@ private HttpClientImpl(HttpClientBuilderImpl builder, SingleFacadeFactory facadeFactory) { id = CLIENT_IDS.incrementAndGet(); dbgTag = "HttpClientImpl(" + id +")"; - @SuppressWarnings("removal") - var sm = System.getSecurityManager(); - if (sm != null && builder.localAddr != null) { - // when a specific local address is configured, it will eventually - // lead to the SocketChannel.bind(...) call with an InetSocketAddress - // whose InetAddress is the local address and the port is 0. That ultimately - // leads to a SecurityManager.checkListen permission check for that port. - // so we do that security manager check here with port 0. - sm.checkListen(0); - } localAddr = builder.localAddr; if (builder.sslContext == null) { try { @@ -484,7 +457,7 @@ private HttpClientImpl(HttpClientBuilderImpl builder, Redirect.NEVER : builder.followRedirects; this.userProxySelector = builder.proxy; this.proxySelector = Optional.ofNullable(userProxySelector) - .orElseGet(HttpClientImpl::getDefaultProxySelector); + .orElseGet(ProxySelector::getDefault); if (debug.on()) debug.log("proxySelector is %s (user-supplied=%s)", this.proxySelector, userProxySelector != null); @@ -642,12 +615,6 @@ private static SSLParameters getDefaultParams(SSLContext ctx) { return params; } - @SuppressWarnings("removal") - private static ProxySelector getDefaultProxySelector() { - PrivilegedAction action = ProxySelector::getDefault; - return AccessController.doPrivileged(action); - } - // Returns the facade that was returned to the application code. // May be null if that facade is no longer referenced. final HttpClientFacade facade() { @@ -992,7 +959,6 @@ private void debugCompleted(String tag, long startNanos, HttpRequest req) { return sendAsync(userRequest, responseHandler, pushPromiseHandler, delegatingExecutor.delegate); } - @SuppressWarnings("removal") private CompletableFuture> sendAsync(HttpRequest userRequest, BodyHandler responseHandler, @@ -1012,11 +978,7 @@ private void debugCompleted(String tag, long startNanos, HttpRequest req) { return MinimalFuture.failedFuture(selmgr.selectorClosedException()); } - AccessControlContext acc = null; - if (System.getSecurityManager() != null) - acc = AccessController.getContext(); - - // Clone the, possibly untrusted, HttpRequest + // Clone the possibly untrusted HttpRequest HttpRequestImpl requestImpl = new HttpRequestImpl(userRequest, proxySelector); if (requestImpl.method().equals("CONNECT")) throw new IllegalArgumentException("Unsupported method CONNECT"); @@ -1049,8 +1011,7 @@ private void debugCompleted(String tag, long startNanos, HttpRequest req) { requestImpl, this, responseHandler, - pushPromiseHandler, - acc); + pushPromiseHandler); CompletableFuture> mexCf = mex.responseAsync(executor); CompletableFuture> res = mexCf.whenComplete((b,t) -> requestUnreference()); if (DEBUGELAPSED) { diff --git a/src/java.net.http/share/classes/jdk/internal/net/http/HttpRequestImpl.java b/src/java.net.http/share/classes/jdk/internal/net/http/HttpRequestImpl.java index 839b6a6185d..bb794031508 100644 --- a/src/java.net.http/share/classes/jdk/internal/net/http/HttpRequestImpl.java +++ b/src/java.net.http/share/classes/jdk/internal/net/http/HttpRequestImpl.java @@ -31,9 +31,6 @@ import java.net.Proxy; import java.net.ProxySelector; import java.net.URI; -import java.security.AccessControlContext; -import java.security.AccessController; -import java.security.PrivilegedAction; import java.time.Duration; import java.util.List; import java.util.Locale; @@ -65,17 +62,13 @@ public class HttpRequestImpl extends HttpRequest implements WebSocketRequest { final boolean secure; final boolean expectContinue; private volatile boolean isWebSocket; - @SuppressWarnings("removal") - private volatile AccessControlContext acc; private final Duration timeout; // may be null private final Optional version; private volatile boolean userSetAuthorization; private volatile boolean userSetProxyAuthorization; private static String userAgent() { - PrivilegedAction pa = () -> System.getProperty("java.version"); - @SuppressWarnings("removal") - String version = AccessController.doPrivileged(pa); + String version = System.getProperty("java.version"); return "Java-http-client/" + version; } @@ -196,7 +189,6 @@ private HttpRequestImpl(URI uri, this.expectContinue = other.expectContinue; this.secure = uri.getScheme().toLowerCase(Locale.US).equals("https"); this.requestPublisher = mayHaveBody ? publisher(other) : null; // may be null - this.acc = other.acc; this.timeout = other.timeout; this.version = other.version(); this.authority = null; @@ -274,7 +266,6 @@ private HttpRequestImpl(HttpRequestImpl parent, HttpHeaders headers) this.expectContinue = parent.expectContinue; this.secure = parent.secure; this.requestPublisher = parent.requestPublisher; - this.acc = parent.acc; this.timeout = parent.timeout; this.version = parent.version; this.authority = null; @@ -395,7 +386,6 @@ public void setSystemHeader(String name, String value) { systemHeadersBuilder.setHeader(name, value); } - @SuppressWarnings("removal") InetSocketAddress getAddress() { URI uri = uri(); if (uri == null) { @@ -412,8 +402,7 @@ InetSocketAddress getAddress() { final String host = uri.getHost(); final int port = p; if (proxy() == null) { - PrivilegedAction pa = () -> new InetSocketAddress(host, port); - return AccessController.doPrivileged(pa); + return new InetSocketAddress(host, port); } else { return InetSocketAddress.createUnresolved(host, port); } diff --git a/src/java.net.http/share/classes/jdk/internal/net/http/MultiExchange.java b/src/java.net.http/share/classes/jdk/internal/net/http/MultiExchange.java index 2c15a704ef9..a7fe5f19e02 100644 --- a/src/java.net.http/share/classes/jdk/internal/net/http/MultiExchange.java +++ b/src/java.net.http/share/classes/jdk/internal/net/http/MultiExchange.java @@ -30,7 +30,6 @@ import java.net.ConnectException; import java.net.http.HttpConnectTimeoutException; import java.time.Duration; -import java.security.AccessControlContext; import java.util.List; import java.util.ListIterator; import java.util.Objects; @@ -79,8 +78,6 @@ class MultiExchange implements Cancelable { private final HttpRequest userRequest; // the user request private final HttpRequestImpl request; // a copy of the user request private final ConnectTimeoutTracker connectTimeout; // null if no timeout - @SuppressWarnings("removal") - final AccessControlContext acc; final HttpClientImpl client; final HttpResponse.BodyHandler responseHandler; final HttpClientImpl.DelegatingExecutor executor; @@ -155,8 +152,7 @@ Duration getRemaining() { HttpRequestImpl requestImpl, HttpClientImpl client, HttpResponse.BodyHandler responseHandler, - PushPromiseHandler pushPromiseHandler, - @SuppressWarnings("removal") AccessControlContext acc) { + PushPromiseHandler pushPromiseHandler) { this.previous = null; this.userRequest = userRequest; this.request = requestImpl; @@ -164,15 +160,11 @@ Duration getRemaining() { this.previousreq = null; this.client = client; this.filters = client.filterChain(); - this.acc = acc; this.executor = client.theExecutor(); this.responseHandler = responseHandler; if (pushPromiseHandler != null) { - Executor ensureExecutedAsync = this.executor::ensureExecutedAsync; - Executor executor = acc == null - ? ensureExecutedAsync - : new PrivilegedExecutor(ensureExecutedAsync, acc); + Executor executor = this.executor::ensureExecutedAsync; this.pushGroup = new PushGroup<>(pushPromiseHandler, request, executor); } else { pushGroup = null; @@ -470,7 +462,7 @@ private CompletableFuture responseAsyncImpl() { previousreq = currentreq; currentreq = newrequest; retriedOnce = false; - setExchange(new Exchange<>(currentreq, this, acc)); + setExchange(new Exchange<>(currentreq, this)); return responseAsyncImpl(); }).thenCompose(Function.identity()); } }) diff --git a/src/java.net.http/share/classes/jdk/internal/net/http/PlainHttpConnection.java b/src/java.net.http/share/classes/jdk/internal/net/http/PlainHttpConnection.java index 1b42801e9ba..747945701f8 100644 --- a/src/java.net.http/share/classes/jdk/internal/net/http/PlainHttpConnection.java +++ b/src/java.net.http/share/classes/jdk/internal/net/http/PlainHttpConnection.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -32,9 +32,6 @@ import java.nio.channels.SelectableChannel; import java.nio.channels.SelectionKey; import java.nio.channels.SocketChannel; -import java.security.AccessController; -import java.security.PrivilegedActionException; -import java.security.PrivilegedExceptionAction; import java.time.Duration; import java.util.concurrent.CompletableFuture; import java.util.concurrent.locks.ReentrantLock; @@ -167,7 +164,6 @@ public void abort(IOException ioe) { } } - @SuppressWarnings("removal") @Override public CompletableFuture connectAsync(Exchange exchange) { CompletableFuture cf = new MinimalFuture<>(); @@ -191,14 +187,12 @@ public CompletableFuture connectAsync(Exchange exchange) { debug.log("binding to configured local address " + localAddr); } var sockAddr = new InetSocketAddress(localAddr, 0); - PrivilegedExceptionAction pa = () -> chan.bind(sockAddr); try { - AccessController.doPrivileged(pa); + chan.bind(sockAddr); if (debug.on()) { debug.log("bind completed " + localAddr); } - } catch (PrivilegedActionException e) { - var cause = e.getCause(); + } catch (IOException cause) { if (debug.on()) { debug.log("bind to " + localAddr + " failed: " + cause.getMessage()); } @@ -206,13 +200,7 @@ public CompletableFuture connectAsync(Exchange exchange) { } } - PrivilegedExceptionAction pa = - () -> chan.connect(Utils.resolveAddress(address)); - try { - finished = AccessController.doPrivileged(pa); - } catch (PrivilegedActionException e) { - throw e.getCause(); - } + finished = chan.connect(Utils.resolveAddress(address)); if (finished) { if (debug.on()) debug.log("connect finished without blocking"); if (connectionOpened()) { diff --git a/src/java.net.http/share/classes/jdk/internal/net/http/PlainTunnelingConnection.java b/src/java.net.http/share/classes/jdk/internal/net/http/PlainTunnelingConnection.java index 4565514f577..80ca6ba8a3a 100644 --- a/src/java.net.http/share/classes/jdk/internal/net/http/PlainTunnelingConnection.java +++ b/src/java.net.http/share/classes/jdk/internal/net/http/PlainTunnelingConnection.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -72,7 +72,7 @@ public CompletableFuture connectAsync(Exchange exchange) { assert client != null; HttpRequestImpl req = new HttpRequestImpl("CONNECT", address, proxyHeaders); MultiExchange mulEx = new MultiExchange<>(null, req, - client, discarding(), null, null); + client, discarding(), null); Exchange connectExchange = mulEx.getExchange(); return connectExchange diff --git a/src/java.net.http/share/classes/jdk/internal/net/http/PrivilegedExecutor.java b/src/java.net.http/share/classes/jdk/internal/net/http/PrivilegedExecutor.java deleted file mode 100644 index 72518f2c4e8..00000000000 --- a/src/java.net.http/share/classes/jdk/internal/net/http/PrivilegedExecutor.java +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright (c) 2015, 2021, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.internal.net.http; - -import java.security.AccessControlContext; -import java.security.AccessController; -import java.security.PrivilegedAction; -import java.util.Objects; -import java.util.concurrent.Executor; - -/** - * Executes tasks within a given access control context, and by a given executor. - */ -class PrivilegedExecutor implements Executor { - - /** The underlying executor. May be provided by the user. */ - final Executor executor; - /** The ACC to execute the tasks within. */ - @SuppressWarnings("removal") - final AccessControlContext acc; - - public PrivilegedExecutor(Executor executor, @SuppressWarnings("removal") AccessControlContext acc) { - Objects.requireNonNull(executor); - Objects.requireNonNull(acc); - this.executor = executor; - this.acc = acc; - } - - private static class PrivilegedRunnable implements Runnable { - private final Runnable r; - @SuppressWarnings("removal") - private final AccessControlContext acc; - PrivilegedRunnable(Runnable r, @SuppressWarnings("removal") AccessControlContext acc) { - this.r = r; - this.acc = acc; - } - @SuppressWarnings("removal") - @Override - public void run() { - PrivilegedAction pa = () -> { r.run(); return null; }; - AccessController.doPrivileged(pa, acc); - } - } - - @Override - public void execute(Runnable r) { - executor.execute(new PrivilegedRunnable(r, acc)); - } -} diff --git a/src/java.net.http/share/classes/jdk/internal/net/http/RequestPublishers.java b/src/java.net.http/share/classes/jdk/internal/net/http/RequestPublishers.java index cfb0a20fe94..ecf88eb6566 100644 --- a/src/java.net.http/share/classes/jdk/internal/net/http/RequestPublishers.java +++ b/src/java.net.http/share/classes/jdk/internal/net/http/RequestPublishers.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -27,7 +27,6 @@ import java.io.FileInputStream; import java.io.FileNotFoundException; -import java.io.FilePermission; import java.io.IOException; import java.io.InputStream; import java.io.UncheckedIOException; @@ -37,11 +36,6 @@ import java.nio.charset.Charset; import java.nio.file.Files; import java.nio.file.Path; -import java.security.AccessControlContext; -import java.security.AccessController; -import java.security.Permission; -import java.security.PrivilegedActionException; -import java.security.PrivilegedExceptionAction; import java.util.ArrayList; import java.util.Collections; import java.util.Iterator; @@ -229,11 +223,6 @@ public void subscribe(Flow.Subscriber subscriber) { /** * Publishes the content of a given file. - *

- * Privileged actions are performed within a limited doPrivileged that only - * asserts the specific, read, file permission that was checked during the - * construction of this FilePublisher. This only applies if the file system - * that created the file provides interoperability with {@code java.io.File}. */ public static class FilePublisher implements BodyPublisher { @@ -241,62 +230,27 @@ public static class FilePublisher implements BodyPublisher { private final long length; private final Function inputStreamSupplier; - private static String pathForSecurityCheck(Path path) { - return path.toFile().getPath(); - } - /** * Factory for creating FilePublisher. - * - * Permission checks are performed here before construction of the - * FilePublisher. Permission checking and construction are deliberately - * and tightly co-located. */ public static FilePublisher create(Path path) throws FileNotFoundException { - @SuppressWarnings("removal") - SecurityManager sm = System.getSecurityManager(); - FilePermission filePermission = null; boolean defaultFS = true; try { - String fn = pathForSecurityCheck(path); - if (sm != null) { - FilePermission readPermission = new FilePermission(fn, "read"); - sm.checkPermission(readPermission); - filePermission = readPermission; - } + path.toFile().getPath(); } catch (UnsupportedOperationException uoe) { + // path not associated with the default file system provider defaultFS = false; - // Path not associated with the default file system - // Test early if an input stream can still be obtained - try { - if (sm != null) { - Files.newInputStream(path).close(); - } - } catch (IOException ioe) { - if (ioe instanceof FileNotFoundException) { - throw (FileNotFoundException) ioe; - } else { - var ex = new FileNotFoundException(ioe.getMessage()); - ex.initCause(ioe); - throw ex; - } - } } - // existence check must be after permission checks + // existence check must be after FS checks if (Files.notExists(path)) throw new FileNotFoundException(path + " not found"); - Permission perm = filePermission; - assert perm == null || perm.getActions().equals("read"); - @SuppressWarnings("removal") - AccessControlContext acc = sm != null ? - AccessController.getContext() : null; boolean finalDefaultFS = defaultFS; Function inputStreamSupplier = (p) -> - createInputStream(p, acc, perm, finalDefaultFS); + createInputStream(p, finalDefaultFS); long length; try { @@ -308,41 +262,17 @@ public static FilePublisher create(Path path) return new FilePublisher(path, length, inputStreamSupplier); } - @SuppressWarnings("removal") private static InputStream createInputStream(Path path, - AccessControlContext acc, - Permission perm, boolean defaultFS) { try { - if (acc != null) { - PrivilegedExceptionAction pa = defaultFS - ? () -> new FileInputStream(path.toFile()) - : () -> Files.newInputStream(path); - return perm != null - ? AccessController.doPrivileged(pa, acc, perm) - : AccessController.doPrivileged(pa, acc); - } else { - return defaultFS + return defaultFS ? new FileInputStream(path.toFile()) : Files.newInputStream(path); - } - } catch (PrivilegedActionException pae) { - throw toUncheckedException(pae.getCause()); } catch (IOException io) { throw new UncheckedIOException(io); } } - private static RuntimeException toUncheckedException(Throwable t) { - if (t instanceof RuntimeException) - throw (RuntimeException) t; - if (t instanceof Error) - throw (Error) t; - if (t instanceof IOException) - throw new UncheckedIOException((IOException) t); - throw new UndeclaredThrowableException(t); - } - private FilePublisher(Path name, long length, Function inputStreamSupplier) { diff --git a/src/java.net.http/share/classes/jdk/internal/net/http/ResponseBodyHandlers.java b/src/java.net.http/share/classes/jdk/internal/net/http/ResponseBodyHandlers.java index 22e03238d21..79b2332ae37 100644 --- a/src/java.net.http/share/classes/jdk/internal/net/http/ResponseBodyHandlers.java +++ b/src/java.net.http/share/classes/jdk/internal/net/http/ResponseBodyHandlers.java @@ -25,8 +25,6 @@ package jdk.internal.net.http; -import java.io.File; -import java.io.FilePermission; import java.io.IOException; import java.io.UncheckedIOException; import java.net.URI; @@ -34,10 +32,8 @@ import java.nio.file.OpenOption; import java.nio.file.Path; import java.nio.file.Paths; -import java.security.AccessControlContext; -import java.security.AccessController; import java.util.List; -import java.util.Objects; + import java.util.concurrent.CompletableFuture; import java.util.concurrent.ConcurrentMap; import java.util.function.Function; @@ -56,62 +52,31 @@ public final class ResponseBodyHandlers { private ResponseBodyHandlers() { } - private static final String pathForSecurityCheck(Path path) { - return path.toFile().getPath(); - } - /** * A Path body handler. */ public static class PathBodyHandler implements BodyHandler{ private final Path file; private final List openOptions; // immutable list - @SuppressWarnings("removal") - private final AccessControlContext acc; - private final FilePermission filePermission; /** * Factory for creating PathBodyHandler. - * - * Permission checks are performed here before construction of the - * PathBodyHandler. Permission checking and construction are - * deliberately and tightly co-located. */ public static PathBodyHandler create(Path file, List openOptions) { - FilePermission filePermission = null; - @SuppressWarnings("removal") - SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - try { - String fn = pathForSecurityCheck(file); - FilePermission writePermission = new FilePermission(fn, "write"); - sm.checkPermission(writePermission); - filePermission = writePermission; - } catch (UnsupportedOperationException ignored) { - // path not associated with the default file system provider - } - } - assert filePermission == null || filePermission.getActions().equals("write"); - @SuppressWarnings("removal") - var acc = sm != null ? AccessController.getContext() : null; - return new PathBodyHandler(file, openOptions, acc, filePermission); + return new PathBodyHandler(file, openOptions); } private PathBodyHandler(Path file, - List openOptions, - @SuppressWarnings("removal") AccessControlContext acc, - FilePermission filePermission) { + List openOptions) { this.file = file; this.openOptions = openOptions; - this.acc = acc; - this.filePermission = filePermission; } @Override public BodySubscriber apply(ResponseInfo responseInfo) { - return new PathSubscriber(file, openOptions, acc, filePermission); + return new PathSubscriber(file, openOptions); } } @@ -170,44 +135,20 @@ public void applyPushPromise( public static class FileDownloadBodyHandler implements BodyHandler { private final Path directory; private final List openOptions; - @SuppressWarnings("removal") - private final AccessControlContext acc; - private final FilePermission[] filePermissions; // may be null /** * Factory for creating FileDownloadBodyHandler. - * - * Permission checks are performed here before construction of the - * FileDownloadBodyHandler. Permission checking and construction are - * deliberately and tightly co-located. */ public static FileDownloadBodyHandler create(Path directory, List openOptions) { - String fn; try { - fn = pathForSecurityCheck(directory); + directory.toFile().getPath(); } catch (UnsupportedOperationException uoe) { // directory not associated with the default file system provider throw new IllegalArgumentException("invalid path: " + directory, uoe); } - FilePermission filePermissions[] = null; - @SuppressWarnings("removal") - SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - FilePermission writePermission = new FilePermission(fn, "write"); - String writePathPerm = fn + File.separatorChar + "*"; - FilePermission writeInDirPermission = new FilePermission(writePathPerm, "write"); - sm.checkPermission(writeInDirPermission); - FilePermission readPermission = new FilePermission(fn, "read"); - sm.checkPermission(readPermission); - - // read permission is only needed before determine the below checks - // only write permission is required when downloading to the file - filePermissions = new FilePermission[] { writePermission, writeInDirPermission }; - } - - // existence, etc, checks must be after permission checks + // existence, etc, checks must be after FS checks if (Files.notExists(directory)) throw new IllegalArgumentException("non-existent directory: " + directory); if (!Files.isDirectory(directory)) @@ -215,21 +156,13 @@ public static FileDownloadBodyHandler create(Path directory, if (!Files.isWritable(directory)) throw new IllegalArgumentException("non-writable directory: " + directory); - assert filePermissions == null || (filePermissions[0].getActions().equals("write") - && filePermissions[1].getActions().equals("write")); - @SuppressWarnings("removal") - var acc = sm != null ? AccessController.getContext() : null; - return new FileDownloadBodyHandler(directory, openOptions, acc, filePermissions); + return new FileDownloadBodyHandler(directory, openOptions); } private FileDownloadBodyHandler(Path directory, - List openOptions, - @SuppressWarnings("removal") AccessControlContext acc, - FilePermission... filePermissions) { + List openOptions) { this.directory = directory; this.openOptions = openOptions; - this.acc = acc; - this.filePermissions = filePermissions; } /** The "attachment" disposition-type and separator. */ @@ -394,7 +327,7 @@ public BodySubscriber apply(ResponseInfo responseInfo) { "Resulting file, " + file.toString() + ", outside of given directory"); } - return new PathSubscriber(file, openOptions, acc, filePermissions); + return new PathSubscriber(file, openOptions); } } } diff --git a/src/java.net.http/share/classes/jdk/internal/net/http/ResponseSubscribers.java b/src/java.net.http/share/classes/jdk/internal/net/http/ResponseSubscribers.java index 09ad87f9205..04d019e4c81 100644 --- a/src/java.net.http/share/classes/jdk/internal/net/http/ResponseSubscribers.java +++ b/src/java.net.http/share/classes/jdk/internal/net/http/ResponseSubscribers.java @@ -26,7 +26,6 @@ package jdk.internal.net.http; import java.io.BufferedReader; -import java.io.FilePermission; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; @@ -35,11 +34,6 @@ import java.nio.charset.Charset; import java.nio.file.OpenOption; import java.nio.file.Path; -import java.security.AccessControlContext; -import java.security.AccessController; -import java.security.PrivilegedAction; -import java.security.PrivilegedActionException; -import java.security.PrivilegedExceptionAction; import java.util.ArrayList; import java.util.Iterator; import java.util.List; @@ -164,83 +158,31 @@ public void onComplete() { /** * A Subscriber that writes the flow of data to a given file. - * - * Privileged actions are performed within a limited doPrivileged that only - * asserts the specific, write, file permissions that were checked during - * the construction of this PathSubscriber. */ public static class PathSubscriber implements TrustedSubscriber { - - private static final FilePermission[] EMPTY_FILE_PERMISSIONS = new FilePermission[0]; - private final Path file; private final OpenOption[] options; - @SuppressWarnings("removal") - private final AccessControlContext acc; - private final FilePermission[] filePermissions; - private final boolean isDefaultFS; private final CompletableFuture result = new MinimalFuture<>(); private final AtomicBoolean subscribed = new AtomicBoolean(); private volatile Flow.Subscription subscription; private volatile FileChannel out; - private static final String pathForSecurityCheck(Path path) { - return path.toFile().getPath(); - } - /** * Factory for creating PathSubscriber. - * - * Permission checks are performed here before construction of the - * PathSubscriber. Permission checking and construction are deliberately - * and tightly co-located. */ public static PathSubscriber create(Path file, List options) { - @SuppressWarnings("removal") - SecurityManager sm = System.getSecurityManager(); - FilePermission filePermission = null; - if (sm != null) { - try { - String fn = pathForSecurityCheck(file); - FilePermission writePermission = new FilePermission(fn, "write"); - sm.checkPermission(writePermission); - filePermission = writePermission; - } catch (UnsupportedOperationException ignored) { - // path not associated with the default file system provider - } - } - - assert filePermission == null || filePermission.getActions().equals("write"); - @SuppressWarnings("removal") - AccessControlContext acc = sm != null ? AccessController.getContext() : null; - return new PathSubscriber(file, options, acc, filePermission); + return new PathSubscriber(file, options); } // pp so handler implementations in the same package can construct /*package-private*/ PathSubscriber(Path file, - List options, - @SuppressWarnings("removal") AccessControlContext acc, - FilePermission... filePermissions) { + List options) { this.file = file; this.options = options.stream().toArray(OpenOption[]::new); - this.acc = acc; - this.filePermissions = filePermissions == null || filePermissions[0] == null - ? EMPTY_FILE_PERMISSIONS : filePermissions; - this.isDefaultFS = isDefaultFS(file); - } - - private static boolean isDefaultFS(Path file) { - try { - file.toFile(); - return true; - } catch (UnsupportedOperationException uoe) { - return false; - } } - @SuppressWarnings("removal") @Override public void onSubscribe(Flow.Subscription subscription) { Objects.requireNonNull(subscription); @@ -250,31 +192,12 @@ public void onSubscribe(Flow.Subscription subscription) { } this.subscription = subscription; - if (acc == null) { - try { - out = FileChannel.open(file, options); - } catch (IOException ioe) { - result.completeExceptionally(ioe); - subscription.cancel(); - return; - } - } else { - try { - PrivilegedExceptionAction pa = - () -> FileChannel.open(file, options); - out = isDefaultFS - ? AccessController.doPrivileged(pa, acc, filePermissions) - : AccessController.doPrivileged(pa, acc); - } catch (PrivilegedActionException pae) { - Throwable t = pae.getCause() != null ? pae.getCause() : pae; - result.completeExceptionally(t); - subscription.cancel(); - return; - } catch (Exception e) { - result.completeExceptionally(e); - subscription.cancel(); - return; - } + try { + out = FileChannel.open(file, options); + } catch (IOException ioe) { + result.completeExceptionally(ioe); + subscription.cancel(); + return; } subscription.request(1); } @@ -311,21 +234,8 @@ public CompletionStage getBody() { return result; } - @SuppressWarnings("removal") private void close() { - if (acc == null) { - Utils.close(out); - } else { - PrivilegedAction pa = () -> { - Utils.close(out); - return null; - }; - if (isDefaultFS) { - AccessController.doPrivileged(pa, acc, filePermissions); - } else { - AccessController.doPrivileged(pa, acc); - } - } + Utils.close(out); } } diff --git a/src/java.net.http/share/classes/jdk/internal/net/http/common/ImmutableExtendedSSLSession.java b/src/java.net.http/share/classes/jdk/internal/net/http/common/ImmutableExtendedSSLSession.java index bb6540e44b9..2a5f125c0c4 100644 --- a/src/java.net.http/share/classes/jdk/internal/net/http/common/ImmutableExtendedSSLSession.java +++ b/src/java.net.http/share/classes/jdk/internal/net/http/common/ImmutableExtendedSSLSession.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -27,7 +27,6 @@ import java.security.Principal; import java.util.List; -import javax.net.ssl.SSLSession; import javax.net.ssl.ExtendedSSLSession; import javax.net.ssl.SSLSessionContext; import javax.net.ssl.SSLPeerUnverifiedException; diff --git a/src/java.net.http/share/classes/jdk/internal/net/http/common/Utils.java b/src/java.net.http/share/classes/jdk/internal/net/http/common/Utils.java index ef5af764e76..511b17d7813 100644 --- a/src/java.net.http/share/classes/jdk/internal/net/http/common/Utils.java +++ b/src/java.net.http/share/classes/jdk/internal/net/http/common/Utils.java @@ -39,8 +39,6 @@ import java.net.ConnectException; import java.net.InetSocketAddress; import java.net.URI; -import java.net.URLPermission; -import java.net.http.HttpClient; import java.net.http.HttpHeaders; import java.net.http.HttpTimeoutException; import java.nio.ByteBuffer; @@ -51,8 +49,6 @@ import java.nio.charset.Charset; import java.nio.charset.CodingErrorAction; import java.nio.charset.StandardCharsets; -import java.security.AccessController; -import java.security.PrivilegedAction; import java.text.Normalizer; import java.util.Arrays; import java.util.Collection; @@ -100,10 +96,7 @@ public final class Utils { // public static final boolean TESTING; // static { -// if (ASSERTIONSENABLED) { -// PrivilegedAction action = () -> System.getProperty("test.src"); -// TESTING = AccessController.doPrivileged(action) != null; -// } else TESTING = false; +// TESTING = ASSERTIONSENABLED ? System.getProperty("test.src") != null : false; // } public static final LoggerConfig DEBUG_CONFIG = getLoggerConfig(DebugLogger.HTTP_NAME, LoggerConfig.OFF); @@ -120,9 +113,7 @@ public final class Utils { hostnameVerificationDisabledValue(); private static LoggerConfig getLoggerConfig(String loggerName, LoggerConfig def) { - PrivilegedAction action = () -> System.getProperty(loggerName); - @SuppressWarnings("removal") - var prop = AccessController.doPrivileged(action); + var prop = System.getProperty(loggerName); if (prop == null) return def; var config = LoggerConfig.OFF; for (var s : prop.split(",")) { @@ -449,41 +440,6 @@ public static Throwable wrapWithExtraDetail(Throwable t, private Utils() { } - /** - * Returns the security permissions required to connect to the proxy, or - * {@code null} if none is required or applicable. - */ - public static URLPermission permissionForProxy(InetSocketAddress proxyAddress) { - if (proxyAddress == null) - return null; - - StringBuilder sb = new StringBuilder(); - sb.append("socket://") - .append(proxyAddress.getHostString()).append(":") - .append(proxyAddress.getPort()); - String urlString = sb.toString(); - return new URLPermission(urlString, "CONNECT"); - } - - /** - * Returns the security permission required for the given details. - */ - public static URLPermission permissionForServer(URI uri, - String method, - Stream headers) { - String urlString = new StringBuilder() - .append(uri.getScheme()).append("://") - .append(uri.getRawAuthority()) - .append(uri.getRawPath()).toString(); - - StringBuilder actionStringBuilder = new StringBuilder(method); - String collected = headers.collect(joining(",")); - if (!collected.isEmpty()) { - actionStringBuilder.append(":").append(collected); - } - return new URLPermission(urlString, actionStringBuilder.toString()); - } - private static final boolean[] LOWER_CASE_CHARS = new boolean[128]; // ABNF primitives defined in RFC 7230 @@ -587,34 +543,24 @@ public static boolean isValidValue(String token) { return true; } - @SuppressWarnings("removal") public static int getIntegerNetProperty(String name, int defaultValue) { - return AccessController.doPrivileged((PrivilegedAction) () -> - NetProperties.getInteger(name, defaultValue)); + return NetProperties.getInteger(name, defaultValue); } - @SuppressWarnings("removal") public static String getNetProperty(String name) { - return AccessController.doPrivileged((PrivilegedAction) () -> - NetProperties.get(name)); + return NetProperties.get(name); } - @SuppressWarnings("removal") public static boolean getBooleanProperty(String name, boolean def) { - return AccessController.doPrivileged((PrivilegedAction) () -> - Boolean.parseBoolean(System.getProperty(name, String.valueOf(def)))); + return Boolean.parseBoolean(System.getProperty(name, String.valueOf(def))); } - @SuppressWarnings("removal") public static String getProperty(String name) { - return AccessController.doPrivileged((PrivilegedAction) () -> - System.getProperty(name)); + return System.getProperty(name); } - @SuppressWarnings("removal") public static int getIntegerProperty(String name, int defaultValue) { - return AccessController.doPrivileged((PrivilegedAction) () -> - Integer.parseInt(System.getProperty(name, String.valueOf(defaultValue)))); + return Integer.parseInt(System.getProperty(name, String.valueOf(defaultValue))); } public static int getIntegerNetProperty(String property, int min, int max, int defaultValue, boolean log) { diff --git a/src/java.net.http/share/classes/jdk/internal/net/http/hpack/HPACK.java b/src/java.net.http/share/classes/jdk/internal/net/http/hpack/HPACK.java index abecde71665..d49b8c391cb 100644 --- a/src/java.net.http/share/classes/jdk/internal/net/http/hpack/HPACK.java +++ b/src/java.net.http/share/classes/jdk/internal/net/http/hpack/HPACK.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -28,8 +28,6 @@ import jdk.internal.net.http.hpack.HPACK.Logger.Level; import java.nio.ByteBuffer; -import java.security.AccessController; -import java.security.PrivilegedAction; import java.util.Map; import java.util.ResourceBundle; import java.util.function.Supplier; @@ -52,9 +50,7 @@ public final class HPACK { static { String PROPERTY = "jdk.internal.httpclient.hpack.log.level"; - @SuppressWarnings("removal") - String value = AccessController.doPrivileged( - (PrivilegedAction) () -> System.getProperty(PROPERTY)); + String value = System.getProperty(PROPERTY); if (value == null) { LOGGER = new RootLogger(NONE); diff --git a/src/java.net.http/share/classes/jdk/internal/net/http/websocket/OpeningHandshake.java b/src/java.net.http/share/classes/jdk/internal/net/http/websocket/OpeningHandshake.java index f88ec774dc0..c1c0853504c 100644 --- a/src/java.net.http/share/classes/jdk/internal/net/http/websocket/OpeningHandshake.java +++ b/src/java.net.http/share/classes/jdk/internal/net/http/websocket/OpeningHandshake.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -39,17 +39,13 @@ import jdk.internal.net.http.common.Utils; import java.io.IOException; -import java.net.InetSocketAddress; import java.net.Proxy; import java.net.ProxySelector; import java.net.URI; import java.net.URISyntaxException; -import java.net.URLPermission; import java.nio.charset.StandardCharsets; -import java.security.AccessController; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; -import java.security.PrivilegedAction; import java.security.SecureRandom; import java.time.Duration; import java.util.Base64; @@ -61,11 +57,9 @@ import java.util.Set; import java.util.TreeSet; import java.util.concurrent.CompletableFuture; -import java.util.stream.Stream; import static java.lang.String.format; import static jdk.internal.net.http.common.Utils.isValidName; -import static jdk.internal.net.http.common.Utils.permissionForProxy; import static jdk.internal.net.http.common.Utils.stringOf; public class OpeningHandshake { @@ -112,7 +106,6 @@ public class OpeningHandshake { public OpeningHandshake(BuilderImpl b) { checkURI(b.getUri()); Proxy proxy = proxyFor(b.getProxySelector(), b.getUri()); - checkPermissions(b, proxy); this.client = b.getClient(); URI httpURI = createRequestURI(b.getUri()); HttpRequestBuilderImpl requestBuilder = new HttpRequestBuilderImpl(httpURI); @@ -185,12 +178,9 @@ static URI createRequestURI(URI uri) { } } - @SuppressWarnings("removal") public CompletableFuture send() { - PrivilegedAction> pa = () -> - client.sendAsync(this.request, BodyHandlers.ofString()) + return client.sendAsync(this.request, BodyHandlers.ofString()) .thenCompose(this::resultFrom); - return AccessController.doPrivileged(pa); } /* @@ -376,27 +366,4 @@ private static Proxy proxyFor(Optional selector, URI uri) { return proxy; } - /** - * Performs the necessary security permissions checks to connect ( possibly - * through a proxy ) to the builders WebSocket URI. - * - * @throws SecurityException if the security manager denies access - */ - static void checkPermissions(BuilderImpl b, Proxy proxy) { - @SuppressWarnings("removal") - SecurityManager sm = System.getSecurityManager(); - if (sm == null) { - return; - } - Stream headers = b.getHeaders().stream().map(p -> p.first).distinct(); - URLPermission perm1 = Utils.permissionForServer(b.getUri(), "", headers); - sm.checkPermission(perm1); - if (proxy == null) { - return; - } - URLPermission perm2 = permissionForProxy((InetSocketAddress) proxy.address()); - if (perm2 != null) { - sm.checkPermission(perm2); - } - } } diff --git a/test/jdk/java/net/httpclient/DebugLoggerTest.java b/test/jdk/java/net/httpclient/DebugLoggerTest.java index ec36d62e38e..8d81e5cbe69 100644 --- a/test/jdk/java/net/httpclient/DebugLoggerTest.java +++ b/test/jdk/java/net/httpclient/DebugLoggerTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -213,7 +213,7 @@ public void publish(LogRecord record) { public void flush() { } @Override - public void close() throws SecurityException { + public void close() { } } diff --git a/test/jdk/java/net/httpclient/FilePublisher/FilePublisherPermsTest.java b/test/jdk/java/net/httpclient/FilePublisher/FilePublisherPermsTest.java index 29976edec9a..bafe1496a86 100644 --- a/test/jdk/java/net/httpclient/FilePublisher/FilePublisherPermsTest.java +++ b/test/jdk/java/net/httpclient/FilePublisher/FilePublisherPermsTest.java @@ -40,7 +40,6 @@ import javax.net.ssl.SSLContext; import java.io.FileNotFoundException; -import java.io.FilePermission; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; @@ -211,9 +210,6 @@ public void handle(HttpServerAdapters.HttpTestExchange t) throws IOException { @BeforeTest public void setup() throws Exception { - policyFile = System.getProperty("java.security.policy"); - out.println(policyFile); - sslContext = new SimpleSSLContext().get(); if (sslContext == null) throw new AssertionError("Unexpected null sslContext"); diff --git a/test/jdk/java/net/httpclient/FilePublisher/SecureZipFSProvider.java b/test/jdk/java/net/httpclient/FilePublisher/SecureZipFSProvider.java index 333996496cd..00f532ba47c 100644 --- a/test/jdk/java/net/httpclient/FilePublisher/SecureZipFSProvider.java +++ b/test/jdk/java/net/httpclient/FilePublisher/SecureZipFSProvider.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -92,13 +92,6 @@ public Path getPath(URI uri) { public InputStream newInputStream(Path path, OpenOption... options) throws IOException { Path p = toTestPath(path).unwrap(); - - // Added permission checks before opening the file - SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - sm.checkPermission(new RuntimePermission("customPermission")); - sm.checkRead(p.toString()); - } return defaultProvider.newInputStream(p, options); } diff --git a/test/jdk/java/net/httpclient/ProxyServer.java b/test/jdk/java/net/httpclient/ProxyServer.java index 7de14a79225..747a20772d1 100644 --- a/test/jdk/java/net/httpclient/ProxyServer.java +++ b/test/jdk/java/net/httpclient/ProxyServer.java @@ -27,10 +27,8 @@ import java.nio.channels.ServerSocketChannel; import java.nio.channels.SocketChannel; import java.util.*; -import java.security.*; import java.util.concurrent.CopyOnWriteArrayList; -import static java.nio.charset.StandardCharsets.US_ASCII; import static java.nio.charset.StandardCharsets.UTF_8; import static java.nio.charset.StandardCharsets.ISO_8859_1; import static java.util.Arrays.asList; @@ -49,9 +47,9 @@ public class ProxyServer extends Thread implements Closeable { // build it. Let's keep it simple. static final boolean IS_WINDOWS; static { - PrivilegedAction action = - () -> System.getProperty("os.name", "unknown"); - String osName = AccessController.doPrivileged(action); + // Parses os.name directly in order to avoid depending on test + // libraries in an auxiliary test class + String osName = System.getProperty("os.name", "unknown"); IS_WINDOWS = osName.toLowerCase(Locale.ROOT).startsWith("win"); } @@ -151,20 +149,6 @@ public void close() throws IOException { volatile boolean done; public void run() { - if (System.getSecurityManager() == null) { - execute(); - } else { - // so calling domain does not need to have socket permission - AccessController.doPrivileged(new PrivilegedAction() { - public Void run() { - execute(); - return null; - } - }); - } - } - - public void execute() { int id = 0; try { while (!done) { diff --git a/test/jdk/java/net/httpclient/lib/jdk/httpclient/test/lib/common/TestServerConfigurator.java b/test/jdk/java/net/httpclient/lib/jdk/httpclient/test/lib/common/TestServerConfigurator.java index 5d16ac24155..a471f3ce07f 100644 --- a/test/jdk/java/net/httpclient/lib/jdk/httpclient/test/lib/common/TestServerConfigurator.java +++ b/test/jdk/java/net/httpclient/lib/jdk/httpclient/test/lib/common/TestServerConfigurator.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,8 +23,6 @@ package jdk.httpclient.test.lib.common; import java.net.InetAddress; -import java.security.AccessController; -import java.security.PrivilegedAction; import java.util.List; import javax.net.ssl.SNIMatcher; @@ -59,14 +57,8 @@ public TestServerConfigurator(final InetAddress serverAddr, final SSLContext con @Override public void configure(final HttpsParameters params) { final SSLParameters sslParams = getSSLContext().getDefaultSSLParameters(); - @SuppressWarnings("removal") final SecurityManager sm = System.getSecurityManager(); - final String hostname; - if (sm == null) { - hostname = serverAddr.getHostName(); - } else { - final PrivilegedAction action = () -> serverAddr.getHostName(); - hostname = AccessController.doPrivileged(action); - } + final String hostname = serverAddr.getHostName(); + final List sniMatchers = List.of(new ServerNameMatcher(hostname)); sslParams.setSNIMatchers(sniMatchers); // configure the server with these custom SSLParameters diff --git a/test/jdk/java/net/httpclient/security/filePerms/FileProcessorPermissionTest.java b/test/jdk/java/net/httpclient/security/filePerms/FileProcessorPermissionTest.java index 3c857ba1b48..c8920771727 100644 --- a/test/jdk/java/net/httpclient/security/filePerms/FileProcessorPermissionTest.java +++ b/test/jdk/java/net/httpclient/security/filePerms/FileProcessorPermissionTest.java @@ -29,7 +29,6 @@ import java.nio.file.Path; import java.nio.file.Paths; -import java.security.PrivilegedExceptionAction; import java.util.List; import java.net.http.HttpRequest; import java.net.http.HttpResponse.BodyHandlers; @@ -43,11 +42,14 @@ public class FileProcessorPermissionTest { static final Path fromFilePath = Paths.get(testSrc, "FileProcessorPermissionTest.java"); static final Path asFilePath = Paths.get(testSrc, "asFile.txt"); static final Path CWD = Paths.get("."); - static final Class SE = SecurityException.class; + + interface ExceptionAction { + T run() throws Exception; + } @Test public void test() throws Exception { - List> list = List.of( + List> list = List.of( () -> HttpRequest.BodyPublishers.ofFile(fromFilePath), () -> BodyHandlers.ofFile(asFilePath), @@ -59,7 +61,7 @@ public void test() throws Exception { () -> BodyHandlers.ofFileDownload(CWD, CREATE, WRITE) ); - for (PrivilegedExceptionAction pa : list) { + for (ExceptionAction pa : list) { pa.run(); } diff --git a/test/jdk/java/net/httpclient/whitebox/java.net.http/jdk/internal/net/http/AuthenticationFilterTest.java b/test/jdk/java/net/httpclient/whitebox/java.net.http/jdk/internal/net/http/AuthenticationFilterTest.java index 7a960892aec..415caeb1196 100644 --- a/test/jdk/java/net/httpclient/whitebox/java.net.http/jdk/internal/net/http/AuthenticationFilterTest.java +++ b/test/jdk/java/net/httpclient/whitebox/java.net.http/jdk/internal/net/http/AuthenticationFilterTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -38,7 +38,6 @@ import java.net.http.HttpHeaders; import java.net.http.HttpResponse; import java.net.http.HttpResponse.BodyHandlers; -import java.security.AccessController; import java.util.Arrays; import java.util.Base64; import java.util.Collections; @@ -196,8 +195,7 @@ private void doTestAuthentication(String uri, Version v, String proxy) throws Ex HttpRequestImpl origReq = new HttpRequestImpl(reqBuilder); HttpRequestImpl req = new HttpRequestImpl(origReq, ps); MultiExchange multi = new MultiExchange(origReq, req, client, - BodyHandlers.replacing(null), - null, AccessController.getContext()); + BodyHandlers.replacing(null), null); Exchange exchange = new Exchange<>(req, multi); out.println("\nSimulating unauthenticated request to " + uri); filter.request(req, multi); @@ -266,8 +264,7 @@ private void doTestAuthentication(String uri, Version v, String proxy) throws Ex HttpRequestImpl origReq2 = new HttpRequestImpl(reqBuilder2); HttpRequestImpl req2 = new HttpRequestImpl(origReq2, ps); MultiExchange multi2 = new MultiExchange(origReq2, req2, client, - HttpResponse.BodyHandlers.replacing(null), - null, AccessController.getContext()); + HttpResponse.BodyHandlers.replacing(null), null); filter.request(req2, multi2); out.println("Check that filter has added credentials from cache for " + reqURI2 + " with proxy " + req2.proxy()); @@ -298,8 +295,7 @@ && isNullOrEmpty(reqURI.getFragment()) HttpRequestImpl origReq3 = new HttpRequestImpl(reqBuilder3); HttpRequestImpl req3 = new HttpRequestImpl(origReq3, ps); MultiExchange multi3 = new MultiExchange(origReq3, req3, client, - HttpResponse.BodyHandlers.replacing(null), - null, AccessController.getContext()); + HttpResponse.BodyHandlers.replacing(null), null); filter.request(req3, multi3); HttpHeaders h3 = req3.getSystemHeadersBuilder().build(); if (proxy == null) { @@ -342,8 +338,7 @@ && isNullOrEmpty(reqURI.getFragment()) HttpRequestImpl origReq4 = new HttpRequestImpl(reqBuilder4); HttpRequestImpl req4 = new HttpRequestImpl(origReq4, fakeProxy); MultiExchange multi4 = new MultiExchange(origReq4, req4, client, - HttpResponse.BodyHandlers.replacing(null), null, - AccessController.getContext()); + HttpResponse.BodyHandlers.replacing(null), null); out.println("Simulating new request to " + reqURI4 + " with a proxy " + req4.proxy()); assertTrue((req4.proxy() == null) == (proxy != null), "(req4.proxy() == null) == (proxy != null) should be true"); @@ -383,8 +378,7 @@ && isNullOrEmpty(reqURI.getFragment()) HttpRequestImpl origReq5 = new HttpRequestImpl(reqBuilder5); HttpRequestImpl req5 = new HttpRequestImpl(origReq5, NO_PROXY); MultiExchange multi5 = new MultiExchange(origReq5, req5, client, - HttpResponse.BodyHandlers.replacing(null), null, - AccessController.getContext()); + HttpResponse.BodyHandlers.replacing(null), null); out.println("Simulating new request to " + reqURI + " with a proxy " + req5.proxy()); assertTrue(req5.proxy() == null, "req5.proxy() should be null"); Exchange exchange5 = new Exchange<>(req5, multi5); @@ -437,8 +431,7 @@ && isNullOrEmpty(reqURI.getFragment()) HttpRequestImpl origReq6 = new HttpRequestImpl(reqBuilder6); HttpRequestImpl req6 = new HttpRequestImpl(origReq6, ps); MultiExchange multi6 = new MultiExchange(origReq6, req6, client, - HttpResponse.BodyHandlers.replacing(null), null, - AccessController.getContext()); + HttpResponse.BodyHandlers.replacing(null), null); out.println("Simulating new request to " + reqURI + " with a proxy " + req6.proxy()); assertTrue(req6.proxy() != null, "req6.proxy() should not be null"); Exchange exchange6 = new Exchange<>(req6, multi6); @@ -461,8 +454,7 @@ && isNullOrEmpty(reqURI.getFragment()) HttpRequestImpl origReq7 = new HttpRequestImpl(reqBuilder7); HttpRequestImpl req7 = new HttpRequestImpl(origReq7, ps); MultiExchange multi7 = new MultiExchange(origReq7, req7, client, - HttpResponse.BodyHandlers.replacing(null), null, - AccessController.getContext()); + HttpResponse.BodyHandlers.replacing(null), null); out.println("Simulating new request to " + reqURI7 + " with a proxy " + req7.proxy()); assertTrue(req7.proxy() == null, "req7.proxy() should be null"); Exchange exchange7 = new Exchange<>(req7, multi7); diff --git a/test/jdk/java/net/httpclient/whitebox/java.net.http/jdk/internal/net/http/RawChannelTest.java b/test/jdk/java/net/httpclient/whitebox/java.net.http/jdk/internal/net/http/RawChannelTest.java index 6619eff008a..9b5764735b2 100644 --- a/test/jdk/java/net/httpclient/whitebox/java.net.http/jdk/internal/net/http/RawChannelTest.java +++ b/test/jdk/java/net/httpclient/whitebox/java.net.http/jdk/internal/net/http/RawChannelTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -221,7 +221,6 @@ private static RawChannel channelOf(int port) throws Exception { requestImpl, clientImpl, discarding(), - null, null); HttpResponse r = mex.responseAsync(clientImpl.theExecutor()) .get(30, SECONDS); diff --git a/test/jdk/java/net/httpclient/whitebox/java.net.http/jdk/internal/net/http/SimpleSSLContext.java b/test/jdk/java/net/httpclient/whitebox/java.net.http/jdk/internal/net/http/SimpleSSLContext.java index 5277eed3ac0..e6897a83de4 100644 --- a/test/jdk/java/net/httpclient/whitebox/java.net.http/jdk/internal/net/http/SimpleSSLContext.java +++ b/test/jdk/java/net/httpclient/whitebox/java.net.http/jdk/internal/net/http/SimpleSSLContext.java @@ -42,13 +42,6 @@ /** * Creates a simple usable SSLContext for SSLSocketFactory * or a HttpsServer using a default keystore in the test tree. - *

- * Using this class with a security manager requires the following - * permissions to be granted: - *

- * permission "java.util.PropertyPermission" "test.src.path", "read"; - * permission java.io.FilePermission "/path/to/test/lib/jdk/test/lib/testkeys", "read"; - * The exact path above depends on the location of the test. */ public class SimpleSSLContext { @@ -60,27 +53,17 @@ public class SimpleSSLContext { public SimpleSSLContext() throws IOException { String paths = System.getProperty("test.src.path"); StringTokenizer st = new StringTokenizer(paths, File.pathSeparator); - boolean securityExceptions = false; SSLContext sslContext = null; while (st.hasMoreTokens()) { String path = st.nextToken(); - try { - File f = new File(path, "../../../../../lib/jdk/test/lib/net/testkeys"); - if (f.exists()) { - try (FileInputStream fis = new FileInputStream(f)) { - sslContext = init(fis); - break; - } + File f = new File(path, "../../../../../lib/jdk/test/lib/net/testkeys"); + if (f.exists()) { + try (FileInputStream fis = new FileInputStream(f)) { + sslContext = init(fis); + break; } - } catch (SecurityException e) { - // catch and ignore because permission only required - // for one entry on path (at most) - securityExceptions = true; } } - if (securityExceptions) { - System.out.println("SecurityExceptions thrown on loading testkeys"); - } ssl = sslContext; } From 3c38ed4128f8762d04ae093d7e8f015bfd4fc2da Mon Sep 17 00:00:00 2001 From: Adam Sotona Date: Fri, 15 Nov 2024 15:57:34 +0000 Subject: [PATCH 019/311] 8344314: Revert removal of jdk.internal.java.PreviewFeature.CLASSFILE_API Reviewed-by: liach --- .../share/classes/jdk/internal/javac/PreviewFeature.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/java.base/share/classes/jdk/internal/javac/PreviewFeature.java b/src/java.base/share/classes/jdk/internal/javac/PreviewFeature.java index 269a9a8416e..b8db00998c0 100644 --- a/src/java.base/share/classes/jdk/internal/javac/PreviewFeature.java +++ b/src/java.base/share/classes/jdk/internal/javac/PreviewFeature.java @@ -74,6 +74,7 @@ public enum Feature { SCOPED_VALUES, @JEP(number=480, title="Structured Concurrency", status="Third Preview") STRUCTURED_CONCURRENCY, + CLASSFILE_API, STREAM_GATHERERS, @JEP(number=494, title="Module Import Declarations", status="Second Preview") MODULE_IMPORTS, From 0b9b82af0376a3e81c118e9219b896c7c40a52d3 Mon Sep 17 00:00:00 2001 From: Brian Burkhalter Date: Fri, 15 Nov 2024 16:11:34 +0000 Subject: [PATCH 020/311] 8343039: Remove jdk.internal.misc.InternalLock and usages from java.io Reviewed-by: liach, alanb --- .../classes/java/io/BufferedInputStream.java | 130 +----- .../classes/java/io/BufferedOutputStream.java | 64 +-- .../share/classes/java/io/BufferedReader.java | 395 ++++++----------- .../share/classes/java/io/BufferedWriter.java | 201 +++------ .../classes/java/io/InputStreamReader.java | 25 +- .../classes/java/io/OutputStreamWriter.java | 25 +- .../share/classes/java/io/PrintStream.java | 331 ++++---------- .../share/classes/java/io/PrintWriter.java | 406 ++++-------------- .../classes/java/io/PushbackInputStream.java | 41 +- .../share/classes/java/io/Reader.java | 52 +-- .../share/classes/java/io/Writer.java | 76 +--- .../share/classes/java/lang/Throwable.java | 59 +-- .../access/JavaIOPrintStreamAccess.java | 31 -- .../access/JavaIOPrintWriterAccess.java | 31 -- .../jdk/internal/access/SharedSecrets.java | 28 -- .../jdk/internal/misc/InternalLock.java | 84 ---- .../classes/sun/nio/cs/StreamDecoder.java | 211 +++------ .../classes/sun/nio/cs/StreamEncoder.java | 121 ++---- test/jdk/java/lang/ProcessBuilder/Basic.java | 12 - 19 files changed, 541 insertions(+), 1782 deletions(-) delete mode 100644 src/java.base/share/classes/jdk/internal/access/JavaIOPrintStreamAccess.java delete mode 100644 src/java.base/share/classes/jdk/internal/access/JavaIOPrintWriterAccess.java delete mode 100644 src/java.base/share/classes/jdk/internal/misc/InternalLock.java diff --git a/src/java.base/share/classes/java/io/BufferedInputStream.java b/src/java.base/share/classes/java/io/BufferedInputStream.java index c401873ce12..5ca55d838ae 100644 --- a/src/java.base/share/classes/java/io/BufferedInputStream.java +++ b/src/java.base/share/classes/java/io/BufferedInputStream.java @@ -28,7 +28,6 @@ import java.util.Arrays; import java.util.Objects; -import jdk.internal.misc.InternalLock; import jdk.internal.misc.Unsafe; import jdk.internal.util.ArraysSupport; @@ -74,9 +73,6 @@ public class BufferedInputStream extends FilterInputStream { private static final long BUF_OFFSET = U.objectFieldOffset(BufferedInputStream.class, "buf"); - // initialized to null when BufferedInputStream is sub-classed - private final InternalLock lock; - // initial buffer size (DEFAULT_BUFFER_SIZE or size specified to constructor) private final int initialSize; @@ -243,12 +239,9 @@ public BufferedInputStream(InputStream in, int size) { } initialSize = size; if (getClass() == BufferedInputStream.class) { - // use internal lock and lazily create buffer when not subclassed - lock = InternalLock.newLockOrNull(); + // lazily create buffer when not subclassed buf = EMPTY; } else { - // use monitors and eagerly create buffer when subclassed - lock = null; buf = new byte[size]; } } @@ -256,7 +249,7 @@ public BufferedInputStream(InputStream in, int size) { /** * Fills the buffer with more data, taking into account * shuffling and other tricks for dealing with marks. - * Assumes that it is being called by a locked method. + * Assumes that it is being called by a synchronized method. * This method also assumes that all data has already been read in, * hence pos > count. */ @@ -310,22 +303,7 @@ else if (pos >= buffer.length) { /* no room left in buffer */ * or an I/O error occurs. * @see java.io.FilterInputStream#in */ - public int read() throws IOException { - if (lock != null) { - lock.lock(); - try { - return implRead(); - } finally { - lock.unlock(); - } - } else { - synchronized (this) { - return implRead(); - } - } - } - - private int implRead() throws IOException { + public synchronized int read() throws IOException { if (pos >= count) { fill(); if (pos >= count) @@ -397,22 +375,7 @@ private int read1(byte[] b, int off, int len) throws IOException { * or an I/O error occurs. * @throws IndexOutOfBoundsException {@inheritDoc} */ - public int read(byte[] b, int off, int len) throws IOException { - if (lock != null) { - lock.lock(); - try { - return implRead(b, off, len); - } finally { - lock.unlock(); - } - } else { - synchronized (this) { - return implRead(b, off, len); - } - } - } - - private int implRead(byte[] b, int off, int len) throws IOException { + public synchronized int read(byte[] b, int off, int len) throws IOException { ensureOpen(); if ((off | len | (off + len) | (b.length - (off + len))) < 0) { throw new IndexOutOfBoundsException(); @@ -444,22 +407,7 @@ private int implRead(byte[] b, int off, int len) throws IOException { * {@code in.skip(n)} throws an IOException, * or an I/O error occurs. */ - public long skip(long n) throws IOException { - if (lock != null) { - lock.lock(); - try { - return implSkip(n); - } finally { - lock.unlock(); - } - } else { - synchronized (this) { - return implSkip(n); - } - } - } - - private long implSkip(long n) throws IOException { + public synchronized long skip(long n) throws IOException { ensureOpen(); if (n <= 0) { return 0; @@ -500,22 +448,7 @@ private long implSkip(long n) throws IOException { * invoking its {@link #close()} method, * or an I/O error occurs. */ - public int available() throws IOException { - if (lock != null) { - lock.lock(); - try { - return implAvailable(); - } finally { - lock.unlock(); - } - } else { - synchronized (this) { - return implAvailable(); - } - } - } - - private int implAvailable() throws IOException { + public synchronized int available() throws IOException { int n = count - pos; int avail = getInIfOpen().available(); return n > (Integer.MAX_VALUE - avail) @@ -531,22 +464,7 @@ private int implAvailable() throws IOException { * the mark position becomes invalid. * @see java.io.BufferedInputStream#reset() */ - public void mark(int readlimit) { - if (lock != null) { - lock.lock(); - try { - implMark(readlimit); - } finally { - lock.unlock(); - } - } else { - synchronized (this) { - implMark(readlimit); - } - } - } - - private void implMark(int readlimit) { + public synchronized void mark(int readlimit) { marklimit = readlimit; markpos = pos; } @@ -567,22 +485,7 @@ private void implMark(int readlimit) { * method, or an I/O error occurs. * @see java.io.BufferedInputStream#mark(int) */ - public void reset() throws IOException { - if (lock != null) { - lock.lock(); - try { - implReset(); - } finally { - lock.unlock(); - } - } else { - synchronized (this) { - implReset(); - } - } - } - - private void implReset() throws IOException { + public synchronized void reset() throws IOException { ensureOpen(); if (markpos < 0) throw new IOException("Resetting to invalid mark"); @@ -628,23 +531,8 @@ public void close() throws IOException { } @Override - public long transferTo(OutputStream out) throws IOException { + public synchronized long transferTo(OutputStream out) throws IOException { Objects.requireNonNull(out, "out"); - if (lock != null) { - lock.lock(); - try { - return implTransferTo(out); - } finally { - lock.unlock(); - } - } else { - synchronized (this) { - return implTransferTo(out); - } - } - } - - private long implTransferTo(OutputStream out) throws IOException { if (getClass() == BufferedInputStream.class && markpos == -1) { int avail = count - pos; if (avail > 0) { diff --git a/src/java.base/share/classes/java/io/BufferedOutputStream.java b/src/java.base/share/classes/java/io/BufferedOutputStream.java index 687f0c91bc4..2ad9adad5ad 100644 --- a/src/java.base/share/classes/java/io/BufferedOutputStream.java +++ b/src/java.base/share/classes/java/io/BufferedOutputStream.java @@ -26,7 +26,6 @@ package java.io; import java.util.Arrays; -import jdk.internal.misc.InternalLock; import jdk.internal.misc.VM; /** @@ -47,9 +46,6 @@ public class BufferedOutputStream extends FilterOutputStream { private static final int DEFAULT_INITIAL_BUFFER_SIZE = 512; private static final int DEFAULT_MAX_BUFFER_SIZE = 8192; - // initialized to null when BufferedOutputStream is sub-classed - private final InternalLock lock; - /** * The internal buffer where data is stored. */ @@ -90,12 +86,9 @@ private BufferedOutputStream(OutputStream out, int initialSize, int maxSize) { } if (getClass() == BufferedOutputStream.class) { - // use InternalLock and resizable buffer when not sub-classed - this.lock = InternalLock.newLockOrNull(); - this.buf = new byte[initialSize]; // resizable + // resizable when not sub-classed + this.buf = new byte[initialSize]; } else { - // use monitors and no resizing when sub-classed - this.lock = null; this.buf = new byte[maxSize]; } this.maxBufSize = maxSize; @@ -136,8 +129,6 @@ private void flushBuffer() throws IOException { * Grow buf to fit an additional len bytes if needed. * If possible, it grows by len+1 to avoid flushing when len bytes * are added. A no-op if the buffer is not resizable. - * - * This method should only be called while holding the lock. */ private void growIfNeeded(int len) { int neededSize = count + len + 1; @@ -157,22 +148,7 @@ private void growIfNeeded(int len) { * @throws IOException if an I/O error occurs. */ @Override - public void write(int b) throws IOException { - if (lock != null) { - lock.lock(); - try { - implWrite(b); - } finally { - lock.unlock(); - } - } else { - synchronized (this) { - implWrite(b); - } - } - } - - private void implWrite(int b) throws IOException { + public synchronized void write(int b) throws IOException { growIfNeeded(1); if (count >= buf.length) { flushBuffer(); @@ -198,22 +174,7 @@ private void implWrite(int b) throws IOException { * @throws IndexOutOfBoundsException {@inheritDoc} */ @Override - public void write(byte[] b, int off, int len) throws IOException { - if (lock != null) { - lock.lock(); - try { - implWrite(b, off, len); - } finally { - lock.unlock(); - } - } else { - synchronized (this) { - implWrite(b, off, len); - } - } - } - - private void implWrite(byte[] b, int off, int len) throws IOException { + public synchronized void write(byte[] b, int off, int len) throws IOException { if (len >= maxBufSize) { /* If the request length exceeds the max size of the output buffer, flush the output buffer and then write the data directly. @@ -238,22 +199,7 @@ private void implWrite(byte[] b, int off, int len) throws IOException { * @see java.io.FilterOutputStream#out */ @Override - public void flush() throws IOException { - if (lock != null) { - lock.lock(); - try { - implFlush(); - } finally { - lock.unlock(); - } - } else { - synchronized (this) { - implFlush(); - } - } - } - - private void implFlush() throws IOException { + public synchronized void flush() throws IOException { flushBuffer(); out.flush(); } diff --git a/src/java.base/share/classes/java/io/BufferedReader.java b/src/java.base/share/classes/java/io/BufferedReader.java index c2f6b89e086..a51f0acaf00 100644 --- a/src/java.base/share/classes/java/io/BufferedReader.java +++ b/src/java.base/share/classes/java/io/BufferedReader.java @@ -32,7 +32,6 @@ import java.util.Spliterators; import java.util.stream.Stream; import java.util.stream.StreamSupport; -import jdk.internal.misc.InternalLock; /** * Reads text from a character-input stream, buffering characters so as to @@ -181,37 +180,23 @@ private void fill() throws IOException { * @throws IOException If an I/O error occurs */ public int read() throws IOException { - Object lock = this.lock; - if (lock instanceof InternalLock locker) { - locker.lock(); - try { - return implRead(); - } finally { - locker.unlock(); - } - } else { - synchronized (lock) { - return implRead(); - } - } - } - - private int implRead() throws IOException { - ensureOpen(); - for (;;) { - if (nextChar >= nChars) { - fill(); - if (nextChar >= nChars) - return -1; - } - if (skipLF) { - skipLF = false; - if (cb[nextChar] == '\n') { - nextChar++; - continue; + synchronized (lock) { + ensureOpen(); + for (;;) { + if (nextChar >= nChars) { + fill(); + if (nextChar >= nChars) + return -1; + } + if (skipLF) { + skipLF = false; + if (cb[nextChar] == '\n') { + nextChar++; + continue; + } } + return cb[nextChar++]; } - return cb[nextChar++]; } } @@ -296,36 +281,22 @@ private int read1(char[] cbuf, int off, int len) throws IOException { * @throws IOException {@inheritDoc} */ public int read(char[] cbuf, int off, int len) throws IOException { - Object lock = this.lock; - if (lock instanceof InternalLock locker) { - locker.lock(); - try { - return implRead(cbuf, off, len); - } finally { - locker.unlock(); - } - } else { - synchronized (lock) { - return implRead(cbuf, off, len); + synchronized (lock) { + ensureOpen(); + Objects.checkFromIndexSize(off, len, cbuf.length); + if (len == 0) { + return 0; } - } - } - - private int implRead(char[] cbuf, int off, int len) throws IOException { - ensureOpen(); - Objects.checkFromIndexSize(off, len, cbuf.length); - if (len == 0) { - return 0; - } - int n = read1(cbuf, off, len); - if (n <= 0) return n; - while ((n < len) && in.ready()) { - int n1 = read1(cbuf, off + n, len - n); - if (n1 <= 0) break; - n += n1; + int n = read1(cbuf, off, len); + if (n <= 0) return n; + while ((n < len) && in.ready()) { + int n1 = read1(cbuf, off + n, len - n); + if (n1 <= 0) break; + n += n1; + } + return n; } - return n; } /** @@ -347,81 +318,67 @@ private int implRead(char[] cbuf, int off, int len) throws IOException { * @throws IOException If an I/O error occurs */ String readLine(boolean ignoreLF, boolean[] term) throws IOException { - Object lock = this.lock; - if (lock instanceof InternalLock locker) { - locker.lock(); - try { - return implReadLine(ignoreLF, term); - } finally { - locker.unlock(); - } - } else { - synchronized (lock) { - return implReadLine(ignoreLF, term); - } - } - } + synchronized (lock) { + StringBuilder s = null; + int startChar; - private String implReadLine(boolean ignoreLF, boolean[] term) throws IOException { - StringBuilder s = null; - int startChar; + ensureOpen(); + boolean omitLF = ignoreLF || skipLF; + if (term != null) term[0] = false; - ensureOpen(); - boolean omitLF = ignoreLF || skipLF; - if (term != null) term[0] = false; + bufferLoop: + for (;;) { - bufferLoop: - for (;;) { - - if (nextChar >= nChars) - fill(); - if (nextChar >= nChars) { /* EOF */ - if (s != null && s.length() > 0) - return s.toString(); - else - return null; - } - boolean eol = false; - char c = 0; - int i; + if (nextChar >= nChars) + fill(); + if (nextChar >= nChars) { /* EOF */ + if (s != null && s.length() > 0) + return s.toString(); + else + return null; + } + boolean eol = false; + char c = 0; + int i; - /* Skip a leftover '\n', if necessary */ - if (omitLF && (cb[nextChar] == '\n')) - nextChar++; - skipLF = false; - omitLF = false; - - charLoop: - for (i = nextChar; i < nChars; i++) { - c = cb[i]; - if ((c == '\n') || (c == '\r')) { - if (term != null) term[0] = true; - eol = true; - break charLoop; + /* Skip a leftover '\n', if necessary */ + if (omitLF && (cb[nextChar] == '\n')) + nextChar++; + skipLF = false; + omitLF = false; + + charLoop: + for (i = nextChar; i < nChars; i++) { + c = cb[i]; + if ((c == '\n') || (c == '\r')) { + if (term != null) term[0] = true; + eol = true; + break charLoop; + } } - } - startChar = nextChar; - nextChar = i; + startChar = nextChar; + nextChar = i; - if (eol) { - String str; - if (s == null) { - str = new String(cb, startChar, i - startChar); - } else { - s.append(cb, startChar, i - startChar); - str = s.toString(); - } - nextChar++; - if (c == '\r') { - skipLF = true; + if (eol) { + String str; + if (s == null) { + str = new String(cb, startChar, i - startChar); + } else { + s.append(cb, startChar, i - startChar); + str = s.toString(); + } + nextChar++; + if (c == '\r') { + skipLF = true; + } + return str; } - return str; - } - if (s == null) - s = new StringBuilder(DEFAULT_EXPECTED_LINE_LENGTH); - s.append(cb, startChar, i - startChar); + if (s == null) + s = new StringBuilder(DEFAULT_EXPECTED_LINE_LENGTH); + s.append(cb, startChar, i - startChar); + } } } @@ -450,47 +407,33 @@ public long skip(long n) throws IOException { if (n < 0L) { throw new IllegalArgumentException("skip value is negative"); } - Object lock = this.lock; - if (lock instanceof InternalLock locker) { - locker.lock(); - try { - return implSkip(n); - } finally { - locker.unlock(); - } - } else { - synchronized (lock) { - return implSkip(n); - } - } - } - - private long implSkip(long n) throws IOException { - ensureOpen(); - long r = n; - while (r > 0) { - if (nextChar >= nChars) - fill(); - if (nextChar >= nChars) /* EOF */ - break; - if (skipLF) { - skipLF = false; - if (cb[nextChar] == '\n') { - nextChar++; + synchronized (lock) { + ensureOpen(); + long r = n; + while (r > 0) { + if (nextChar >= nChars) + fill(); + if (nextChar >= nChars) /* EOF */ + break; + if (skipLF) { + skipLF = false; + if (cb[nextChar] == '\n') { + nextChar++; + } + } + long d = nChars - nextChar; + if (r <= d) { + nextChar += (int)r; + r = 0; + break; + } + else { + r -= d; + nextChar = nChars; } } - long d = nChars - nextChar; - if (r <= d) { - nextChar += (int)r; - r = 0; - break; - } - else { - r -= d; - nextChar = nChars; - } + return n - r; } - return n - r; } /** @@ -501,42 +444,28 @@ private long implSkip(long n) throws IOException { * @throws IOException If an I/O error occurs */ public boolean ready() throws IOException { - Object lock = this.lock; - if (lock instanceof InternalLock locker) { - locker.lock(); - try { - return implReady(); - } finally { - locker.unlock(); - } - } else { - synchronized (lock) { - return implReady(); - } - } - } + synchronized (lock) { + ensureOpen(); - private boolean implReady() throws IOException { - ensureOpen(); - - /* - * If newline needs to be skipped and the next char to be read - * is a newline character, then just skip it right away. - */ - if (skipLF) { - /* Note that in.ready() will return true if and only if the next - * read on the stream will not block. + /* + * If newline needs to be skipped and the next char to be read + * is a newline character, then just skip it right away. */ - if (nextChar >= nChars && in.ready()) { - fill(); - } - if (nextChar < nChars) { - if (cb[nextChar] == '\n') - nextChar++; - skipLF = false; + if (skipLF) { + /* Note that in.ready() will return true if and only if the next + * read on the stream will not block. + */ + if (nextChar >= nChars && in.ready()) { + fill(); + } + if (nextChar < nChars) { + if (cb[nextChar] == '\n') + nextChar++; + skipLF = false; + } } + return (nextChar < nChars) || in.ready(); } - return (nextChar < nChars) || in.ready(); } /** @@ -566,28 +495,14 @@ public void mark(int readAheadLimit) throws IOException { if (readAheadLimit < 0) { throw new IllegalArgumentException("Read-ahead limit < 0"); } - Object lock = this.lock; - if (lock instanceof InternalLock locker) { - locker.lock(); - try { - implMark(readAheadLimit); - } finally { - locker.unlock(); - } - } else { - synchronized (lock) { - implMark(readAheadLimit); - } + synchronized (lock) { + ensureOpen(); + this.readAheadLimit = readAheadLimit; + markedChar = nextChar; + markedSkipLF = skipLF; } } - private void implMark(int readAheadLimit) throws IOException { - ensureOpen(); - this.readAheadLimit = readAheadLimit; - markedChar = nextChar; - markedSkipLF = skipLF; - } - /** * Resets the stream to the most recent mark. * @@ -595,55 +510,27 @@ private void implMark(int readAheadLimit) throws IOException { * or if the mark has been invalidated */ public void reset() throws IOException { - Object lock = this.lock; - if (lock instanceof InternalLock locker) { - locker.lock(); - try { - implReset(); - } finally { - locker.unlock(); - } - } else { - synchronized (lock) { - implReset(); - } + synchronized (lock) { + ensureOpen(); + if (markedChar < 0) + throw new IOException((markedChar == INVALIDATED) + ? "Mark invalid" + : "Stream not marked"); + nextChar = markedChar; + skipLF = markedSkipLF; } } - private void implReset() throws IOException { - ensureOpen(); - if (markedChar < 0) - throw new IOException((markedChar == INVALIDATED) - ? "Mark invalid" - : "Stream not marked"); - nextChar = markedChar; - skipLF = markedSkipLF; - } - public void close() throws IOException { - Object lock = this.lock; - if (lock instanceof InternalLock locker) { - locker.lock(); + synchronized (lock) { + if (in == null) + return; try { - implClose(); + in.close(); } finally { - locker.unlock(); + in = null; + cb = null; } - } else { - synchronized (lock) { - implClose(); - } - } - } - - private void implClose() throws IOException { - if (in == null) - return; - try { - in.close(); - } finally { - in = null; - cb = null; } } diff --git a/src/java.base/share/classes/java/io/BufferedWriter.java b/src/java.base/share/classes/java/io/BufferedWriter.java index 17862a265ae..e3f8a21fe60 100644 --- a/src/java.base/share/classes/java/io/BufferedWriter.java +++ b/src/java.base/share/classes/java/io/BufferedWriter.java @@ -27,7 +27,6 @@ import java.util.Arrays; import java.util.Objects; -import jdk.internal.misc.InternalLock; import jdk.internal.misc.VM; /** @@ -162,58 +161,30 @@ private void growIfNeeded(int len) { * may be invoked by PrintStream. */ void flushBuffer() throws IOException { - Object lock = this.lock; - if (lock instanceof InternalLock locker) { - locker.lock(); - try { - implFlushBuffer(); - } finally { - locker.unlock(); - } - } else { - synchronized (lock) { - implFlushBuffer(); - } + synchronized (lock) { + ensureOpen(); + if (nextChar == 0) + return; + out.write(cb, 0, nextChar); + nextChar = 0; } } - private void implFlushBuffer() throws IOException { - ensureOpen(); - if (nextChar == 0) - return; - out.write(cb, 0, nextChar); - nextChar = 0; - } - /** * Writes a single character. * * @throws IOException If an I/O error occurs */ public void write(int c) throws IOException { - Object lock = this.lock; - if (lock instanceof InternalLock locker) { - locker.lock(); - try { - implWrite(c); - } finally { - locker.unlock(); - } - } else { - synchronized (lock) { - implWrite(c); - } + synchronized (lock) { + ensureOpen(); + growIfNeeded(1); + if (nextChar >= nChars) + flushBuffer(); + cb[nextChar++] = (char) c; } } - private void implWrite(int c) throws IOException { - ensureOpen(); - growIfNeeded(1); - if (nextChar >= nChars) - flushBuffer(); - cb[nextChar++] = (char) c; - } - /** * Our own little min method, to avoid loading java.lang.Math if we've run * out of file descriptors and we're trying to print a stack trace. @@ -245,46 +216,32 @@ private int min(int a, int b) { * @throws IOException If an I/O error occurs */ public void write(char[] cbuf, int off, int len) throws IOException { - Object lock = this.lock; - if (lock instanceof InternalLock locker) { - locker.lock(); - try { - implWrite(cbuf, off, len); - } finally { - locker.unlock(); - } - } else { - synchronized (lock) { - implWrite(cbuf, off, len); + synchronized (lock) { + ensureOpen(); + Objects.checkFromIndexSize(off, len, cbuf.length); + if (len == 0) { + return; } - } - } - private void implWrite(char[] cbuf, int off, int len) throws IOException { - ensureOpen(); - Objects.checkFromIndexSize(off, len, cbuf.length); - if (len == 0) { - return; - } - - if (len >= maxChars) { - /* If the request length exceeds the max size of the output buffer, - flush the buffer and then write the data directly. In this - way buffered streams will cascade harmlessly. */ - flushBuffer(); - out.write(cbuf, off, len); - return; - } - - growIfNeeded(len); - int b = off, t = off + len; - while (b < t) { - int d = min(nChars - nextChar, t - b); - System.arraycopy(cbuf, b, cb, nextChar, d); - b += d; - nextChar += d; - if (nextChar >= nChars) { + if (len >= maxChars) { + /* If the request length exceeds the max size of the output buffer, + flush the buffer and then write the data directly. In this + way buffered streams will cascade harmlessly. */ flushBuffer(); + out.write(cbuf, off, len); + return; + } + + growIfNeeded(len); + int b = off, t = off + len; + while (b < t) { + int d = min(nChars - nextChar, t - b); + System.arraycopy(cbuf, b, cb, nextChar, d); + b += d; + nextChar += d; + if (nextChar >= nChars) { + flushBuffer(); + } } } } @@ -312,35 +269,21 @@ private void implWrite(char[] cbuf, int off, int len) throws IOException { * @throws IOException If an I/O error occurs */ public void write(String s, int off, int len) throws IOException { - Object lock = this.lock; - if (lock instanceof InternalLock locker) { - locker.lock(); - try { - implWrite(s, off, len); - } finally { - locker.unlock(); - } - } else { - synchronized (lock) { - implWrite(s, off, len); + synchronized (lock) { + ensureOpen(); + growIfNeeded(len); + int b = off, t = off + len; + while (b < t) { + int d = min(nChars - nextChar, t - b); + s.getChars(b, b + d, cb, nextChar); + b += d; + nextChar += d; + if (nextChar >= nChars) + flushBuffer(); } } } - private void implWrite(String s, int off, int len) throws IOException { - ensureOpen(); - growIfNeeded(len); - int b = off, t = off + len; - while (b < t) { - int d = min(nChars - nextChar, t - b); - s.getChars(b, b + d, cb, nextChar); - b += d; - nextChar += d; - if (nextChar >= nChars) - flushBuffer(); - } - } - /** * Writes a line separator. The line separator string is defined by the * system property {@code line.separator}, and is not necessarily a single @@ -358,52 +301,24 @@ public void newLine() throws IOException { * @throws IOException If an I/O error occurs */ public void flush() throws IOException { - Object lock = this.lock; - if (lock instanceof InternalLock locker) { - locker.lock(); - try { - implFlush(); - } finally { - locker.unlock(); - } - } else { - synchronized (lock) { - implFlush(); - } + synchronized (lock) { + flushBuffer(); + out.flush(); } } - private void implFlush() throws IOException { - flushBuffer(); - out.flush(); - } - + @SuppressWarnings("try") public void close() throws IOException { - Object lock = this.lock; - if (lock instanceof InternalLock locker) { - locker.lock(); - try { - implClose(); - } finally { - locker.unlock(); + synchronized (lock) { + if (out == null) { + return; } - } else { - synchronized (lock) { - implClose(); + try (Writer w = out) { + flushBuffer(); + } finally { + out = null; + cb = null; } } } - - @SuppressWarnings("try") - private void implClose() throws IOException { - if (out == null) { - return; - } - try (Writer w = out) { - flushBuffer(); - } finally { - out = null; - cb = null; - } - } } diff --git a/src/java.base/share/classes/java/io/InputStreamReader.java b/src/java.base/share/classes/java/io/InputStreamReader.java index d3033b15b9f..6d43c4ae0cd 100644 --- a/src/java.base/share/classes/java/io/InputStreamReader.java +++ b/src/java.base/share/classes/java/io/InputStreamReader.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -28,7 +28,6 @@ import java.nio.CharBuffer; import java.nio.charset.Charset; import java.nio.charset.CharsetDecoder; -import jdk.internal.misc.InternalLock; import sun.nio.cs.StreamDecoder; /** @@ -62,20 +61,6 @@ public class InputStreamReader extends Reader { private final StreamDecoder sd; - /** - * Return the lock object for the given reader's stream decoder. - * If the reader type is trusted then an internal lock can be used. If the - * reader type is not trusted then the reader object is the lock. - */ - private static Object lockFor(InputStreamReader reader) { - Class clazz = reader.getClass(); - if (clazz == InputStreamReader.class || clazz == FileReader.class) { - return InternalLock.newLockOr(reader); - } else { - return reader; - } - } - /** * Creates an InputStreamReader that uses the * {@link Charset#defaultCharset() default charset}. @@ -88,7 +73,7 @@ private static Object lockFor(InputStreamReader reader) { public InputStreamReader(InputStream in) { super(in); Charset cs = Charset.defaultCharset(); - sd = StreamDecoder.forInputStreamReader(in, lockFor(this), cs); + sd = StreamDecoder.forInputStreamReader(in, this, cs); } /** @@ -110,7 +95,7 @@ public InputStreamReader(InputStream in, String charsetName) super(in); if (charsetName == null) throw new NullPointerException("charsetName"); - sd = StreamDecoder.forInputStreamReader(in, lockFor(this), charsetName); + sd = StreamDecoder.forInputStreamReader(in, this, charsetName); } /** @@ -126,7 +111,7 @@ public InputStreamReader(InputStream in, Charset cs) { super(in); if (cs == null) throw new NullPointerException("charset"); - sd = StreamDecoder.forInputStreamReader(in, lockFor(this), cs); + sd = StreamDecoder.forInputStreamReader(in, this, cs); } /** @@ -142,7 +127,7 @@ public InputStreamReader(InputStream in, CharsetDecoder dec) { super(in); if (dec == null) throw new NullPointerException("charset decoder"); - sd = StreamDecoder.forInputStreamReader(in, lockFor(this), dec); + sd = StreamDecoder.forInputStreamReader(in, this, dec); } /** diff --git a/src/java.base/share/classes/java/io/OutputStreamWriter.java b/src/java.base/share/classes/java/io/OutputStreamWriter.java index cda9fead18e..9a16aa140bc 100644 --- a/src/java.base/share/classes/java/io/OutputStreamWriter.java +++ b/src/java.base/share/classes/java/io/OutputStreamWriter.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -28,7 +28,6 @@ import java.nio.CharBuffer; import java.nio.charset.Charset; import java.nio.charset.CharsetEncoder; -import jdk.internal.misc.InternalLock; import sun.nio.cs.StreamEncoder; /** @@ -75,20 +74,6 @@ public class OutputStreamWriter extends Writer { private final StreamEncoder se; - /** - * Return the lock object for the given writer's stream encoder. - * If the writer type is trusted then an internal lock can be used. If the - * writer type is not trusted then the writer object is the lock. - */ - private static Object lockFor(OutputStreamWriter writer) { - Class clazz = writer.getClass(); - if (clazz == OutputStreamWriter.class || clazz == FileWriter.class) { - return InternalLock.newLockOr(writer); - } else { - return writer; - } - } - /** * Creates an OutputStreamWriter that uses the named charset. * @@ -108,7 +93,7 @@ public OutputStreamWriter(OutputStream out, String charsetName) super(out); if (charsetName == null) throw new NullPointerException("charsetName"); - se = StreamEncoder.forOutputStreamWriter(out, lockFor(this), charsetName); + se = StreamEncoder.forOutputStreamWriter(out, this, charsetName); } /** @@ -122,7 +107,7 @@ public OutputStreamWriter(OutputStream out, String charsetName) @SuppressWarnings("this-escape") public OutputStreamWriter(OutputStream out) { super(out); - se = StreamEncoder.forOutputStreamWriter(out, lockFor(this), + se = StreamEncoder.forOutputStreamWriter(out, this, out instanceof PrintStream ps ? ps.charset() : Charset.defaultCharset()); } @@ -142,7 +127,7 @@ public OutputStreamWriter(OutputStream out, Charset cs) { super(out); if (cs == null) throw new NullPointerException("charset"); - se = StreamEncoder.forOutputStreamWriter(out, lockFor(this), cs); + se = StreamEncoder.forOutputStreamWriter(out, this, cs); } /** @@ -161,7 +146,7 @@ public OutputStreamWriter(OutputStream out, CharsetEncoder enc) { super(out); if (enc == null) throw new NullPointerException("charset encoder"); - se = StreamEncoder.forOutputStreamWriter(out, lockFor(this), enc); + se = StreamEncoder.forOutputStreamWriter(out, this, enc); } /** diff --git a/src/java.base/share/classes/java/io/PrintStream.java b/src/java.base/share/classes/java/io/PrintStream.java index 3096f2356f5..0c1dd20e668 100644 --- a/src/java.base/share/classes/java/io/PrintStream.java +++ b/src/java.base/share/classes/java/io/PrintStream.java @@ -30,9 +30,6 @@ import java.nio.charset.Charset; import java.nio.charset.IllegalCharsetNameException; import java.nio.charset.UnsupportedCharsetException; -import jdk.internal.access.JavaIOPrintStreamAccess; -import jdk.internal.access.SharedSecrets; -import jdk.internal.misc.InternalLock; /** * A {@code PrintStream} adds functionality to another output stream, @@ -67,9 +64,6 @@ public class PrintStream extends FilterOutputStream implements Appendable, Closeable { - // initialized to null when PrintStream is sub-classed - private final InternalLock lock; - private final boolean autoFlush; private boolean trouble = false; private Formatter formatter; @@ -117,13 +111,6 @@ private PrintStream(boolean autoFlush, OutputStream out) { this.charset = out instanceof PrintStream ps ? ps.charset() : Charset.defaultCharset(); this.charOut = new OutputStreamWriter(this, charset); this.textOut = new BufferedWriter(charOut); - - // use monitors when PrintStream is sub-classed - if (getClass() == PrintStream.class) { - lock = InternalLock.newLockOrNull(); - } else { - lock = null; - } } /* Variant of the private constructor so that the given charset name @@ -220,13 +207,6 @@ public PrintStream(OutputStream out, boolean autoFlush, Charset charset) { this.charOut = new OutputStreamWriter(this, charset); this.textOut = new BufferedWriter(charOut); this.charset = charset; - - // use monitors when PrintStream is sub-classed - if (getClass() == PrintStream.class) { - lock = InternalLock.newLockOrNull(); - } else { - lock = null; - } } /** @@ -420,30 +400,17 @@ private void ensureOpen() throws IOException { */ @Override public void flush() { - if (lock != null) { - lock.lock(); + synchronized (this) { try { - implFlush(); - } finally { - lock.unlock(); + ensureOpen(); + out.flush(); } - } else { - synchronized (this) { - implFlush(); + catch (IOException x) { + trouble = true; } } } - private void implFlush() { - try { - ensureOpen(); - out.flush(); - } - catch (IOException x) { - trouble = true; - } - } - private boolean closing = false; /* To avoid recursive closing */ /** @@ -454,33 +421,20 @@ private void implFlush() { */ @Override public void close() { - if (lock != null) { - lock.lock(); - try { - implClose(); - } finally { - lock.unlock(); - } - } else { - synchronized (this) { - implClose(); - } - } - } - - private void implClose() { - if (!closing) { - closing = true; - try { - textOut.close(); - out.close(); - } - catch (IOException x) { - trouble = true; + synchronized (this) { + if (!closing) { + closing = true; + try { + textOut.close(); + out.close(); + } + catch (IOException x) { + trouble = true; + } + textOut = null; + charOut = null; + out = null; } - textOut = null; - charOut = null; - out = null; } } @@ -547,17 +501,11 @@ protected void clearError() { @Override public void write(int b) { try { - if (lock != null) { - lock.lock(); - try { - implWrite(b); - } finally { - lock.unlock(); - } - } else { - synchronized (this) { - implWrite(b); - } + synchronized (this) { + ensureOpen(); + out.write(b); + if ((b == '\n') && autoFlush) + out.flush(); } } catch (InterruptedIOException x) { @@ -568,13 +516,6 @@ public void write(int b) { } } - private void implWrite(int b) throws IOException { - ensureOpen(); - out.write(b); - if ((b == '\n') && autoFlush) - out.flush(); - } - /** * Writes {@code len} bytes from the specified byte array starting at * offset {@code off} to this stream. If automatic flushing is @@ -593,17 +534,11 @@ private void implWrite(int b) throws IOException { @Override public void write(byte[] buf, int off, int len) { try { - if (lock != null) { - lock.lock(); - try { - implWrite(buf, off, len); - } finally { - lock.unlock(); - } - } else { - synchronized (this) { - implWrite(buf, off, len); - } + synchronized (this) { + ensureOpen(); + out.write(buf, off, len); + if (autoFlush) + out.flush(); } } catch (InterruptedIOException x) { @@ -614,14 +549,6 @@ public void write(byte[] buf, int off, int len) { } } - private void implWrite(byte[] buf, int off, int len) throws IOException { - ensureOpen(); - out.write(buf, off, len); - if (autoFlush) - out.flush(); - } - - /** * Writes all bytes from the specified byte array to this stream. If * automatic flushing is enabled then the {@code flush} method will be @@ -686,16 +613,17 @@ public void writeBytes(byte[] buf) { private void write(char[] buf) { try { - if (lock != null) { - lock.lock(); - try { - implWrite(buf); - } finally { - lock.unlock(); - } - } else { - synchronized (this) { - implWrite(buf); + synchronized (this) { + ensureOpen(); + textOut.write(buf); + textOut.flushBuffer(); + charOut.flushBuffer(); + if (autoFlush) { + for (int i = 0; i < buf.length; i++) + if (buf[i] == '\n') { + out.flush(); + break; + } } } } catch (InterruptedIOException x) { @@ -705,37 +633,20 @@ private void write(char[] buf) { } } - private void implWrite(char[] buf) throws IOException { - ensureOpen(); - textOut.write(buf); - textOut.flushBuffer(); - charOut.flushBuffer(); - if (autoFlush) { - for (int i = 0; i < buf.length; i++) - if (buf[i] == '\n') { - out.flush(); - break; - } - } - } - // Used to optimize away back-to-back flushing and synchronization when // using println, but since subclasses could exist which depend on // observing a call to print followed by newLine() we only use this if // getClass() == PrintStream.class to avoid compatibility issues. private void writeln(char[] buf) { try { - if (lock != null) { - lock.lock(); - try { - implWriteln(buf); - } finally { - lock.unlock(); - } - } else { - synchronized (this) { - implWriteln(buf); - } + synchronized (this) { + ensureOpen(); + textOut.write(buf); + textOut.newLine(); + textOut.flushBuffer(); + charOut.flushBuffer(); + if (autoFlush) + out.flush(); } } catch (InterruptedIOException x) { @@ -746,29 +657,15 @@ private void writeln(char[] buf) { } } - private void implWriteln(char[] buf) throws IOException { - ensureOpen(); - textOut.write(buf); - textOut.newLine(); - textOut.flushBuffer(); - charOut.flushBuffer(); - if (autoFlush) - out.flush(); - } - private void write(String s) { try { - if (lock != null) { - lock.lock(); - try { - implWrite(s); - } finally { - lock.unlock(); - } - } else { - synchronized (this) { - implWrite(s); - } + synchronized (this) { + ensureOpen(); + textOut.write(s); + textOut.flushBuffer(); + charOut.flushBuffer(); + if (autoFlush && (s.indexOf('\n') >= 0)) + out.flush(); } } catch (InterruptedIOException x) { @@ -779,32 +676,20 @@ private void write(String s) { } } - private void implWrite(String s) throws IOException { - ensureOpen(); - textOut.write(s); - textOut.flushBuffer(); - charOut.flushBuffer(); - if (autoFlush && (s.indexOf('\n') >= 0)) - out.flush(); - } - // Used to optimize away back-to-back flushing and synchronization when // using println, but since subclasses could exist which depend on // observing a call to print followed by newLine we only use this if // getClass() == PrintStream.class to avoid compatibility issues. private void writeln(String s) { try { - if (lock != null) { - lock.lock(); - try { - implWriteln(s); - } finally { - lock.unlock(); - } - } else { - synchronized (this) { - implWriteln(s); - } + synchronized (this) { + ensureOpen(); + textOut.write(s); + textOut.newLine(); + textOut.flushBuffer(); + charOut.flushBuffer(); + if (autoFlush) + out.flush(); } } catch (InterruptedIOException x) { @@ -815,29 +700,15 @@ private void writeln(String s) { } } - private void implWriteln(String s) throws IOException { - ensureOpen(); - textOut.write(s); - textOut.newLine(); - textOut.flushBuffer(); - charOut.flushBuffer(); - if (autoFlush) - out.flush(); - } - private void newLine() { try { - if (lock != null) { - lock.lock(); - try { - implNewLine(); - } finally { - lock.unlock(); - } - } else { - synchronized (this) { - implNewLine(); - } + synchronized (this) { + ensureOpen(); + textOut.newLine(); + textOut.flushBuffer(); + charOut.flushBuffer(); + if (autoFlush) + out.flush(); } } catch (InterruptedIOException x) { @@ -848,15 +719,6 @@ private void newLine() { } } - private void implNewLine() throws IOException { - ensureOpen(); - textOut.newLine(); - textOut.flushBuffer(); - charOut.flushBuffer(); - if (autoFlush) - out.flush(); - } - /* Methods that do not terminate lines */ /** @@ -1314,17 +1176,11 @@ public PrintStream printf(Locale l, String format, Object ... args) { */ public PrintStream format(String format, Object ... args) { try { - if (lock != null) { - lock.lock(); - try { - implFormat(format, args); - } finally { - lock.unlock(); - } - } else { - synchronized (this) { - implFormat(format, args); - } + synchronized (this) { + ensureOpen(); + if ((formatter == null) || (formatter.locale() != Locale.getDefault(Locale.Category.FORMAT))) + formatter = new Formatter((Appendable) this); + formatter.format(Locale.getDefault(Locale.Category.FORMAT), format, args); } } catch (InterruptedIOException x) { Thread.currentThread().interrupt(); @@ -1334,13 +1190,6 @@ public PrintStream format(String format, Object ... args) { return this; } - private void implFormat(String format, Object ... args) throws IOException { - ensureOpen(); - if ((formatter == null) || (formatter.locale() != Locale.getDefault(Locale.Category.FORMAT))) - formatter = new Formatter((Appendable) this); - formatter.format(Locale.getDefault(Locale.Category.FORMAT), format, args); - } - /** * Writes a formatted string to this output stream using the specified * format string and arguments. @@ -1383,17 +1232,11 @@ private void implFormat(String format, Object ... args) throws IOException { */ public PrintStream format(Locale l, String format, Object ... args) { try { - if (lock != null) { - lock.lock(); - try { - implFormat(l, format, args); - } finally { - lock.unlock(); - } - } else { - synchronized (this) { - implFormat(l, format, args); - } + synchronized (this) { + ensureOpen(); + if ((formatter == null) || (formatter.locale() != l)) + formatter = new Formatter(this, l); + formatter.format(l, format, args); } } catch (InterruptedIOException x) { Thread.currentThread().interrupt(); @@ -1403,13 +1246,6 @@ public PrintStream format(Locale l, String format, Object ... args) { return this; } - private void implFormat(Locale l, String format, Object ... args) throws IOException { - ensureOpen(); - if ((formatter == null) || (formatter.locale() != l)) - formatter = new Formatter(this, l); - formatter.format(l, format, args); - } - /** * Appends the specified character sequence to this output stream. * @@ -1511,13 +1347,4 @@ public PrintStream append(char c) { public Charset charset() { return charset; } - - static { - SharedSecrets.setJavaIOCPrintStreamAccess(new JavaIOPrintStreamAccess() { - public Object lock(PrintStream ps) { - Object lock = ps.lock; - return (lock != null) ? lock : ps; - } - }); - } } diff --git a/src/java.base/share/classes/java/io/PrintWriter.java b/src/java.base/share/classes/java/io/PrintWriter.java index 55baa2e0a57..dd6deb75ab7 100644 --- a/src/java.base/share/classes/java/io/PrintWriter.java +++ b/src/java.base/share/classes/java/io/PrintWriter.java @@ -31,9 +31,6 @@ import java.nio.charset.Charset; import java.nio.charset.IllegalCharsetNameException; import java.nio.charset.UnsupportedCharsetException; -import jdk.internal.access.JavaIOPrintWriterAccess; -import jdk.internal.access.SharedSecrets; -import jdk.internal.misc.InternalLock; /** * Prints formatted representations of objects to a text-output stream. This @@ -377,30 +374,16 @@ private void ensureOpen() throws IOException { * @see #checkError() */ public void flush() { - Object lock = this.lock; - if (lock instanceof InternalLock locker) { - locker.lock(); + synchronized (lock) { try { - implFlush(); - } finally { - locker.unlock(); - } - } else { - synchronized (lock) { - implFlush(); + ensureOpen(); + out.flush(); + } catch (IOException x) { + trouble = true; } } } - private void implFlush() { - try { - ensureOpen(); - out.flush(); - } catch (IOException x) { - trouble = true; - } - } - /** * Closes the stream and releases any system resources associated * with it. Closing a previously closed stream has no effect. @@ -408,32 +391,18 @@ private void implFlush() { * @see #checkError() */ public void close() { - Object lock = this.lock; - if (lock instanceof InternalLock locker) { - locker.lock(); + synchronized (lock) { try { - implClose(); - } finally { - locker.unlock(); - } - } else { - synchronized (lock) { - implClose(); + if (out != null) { + out.close(); + out = null; + } + } catch (IOException x) { + trouble = true; } } } - private void implClose() { - try { - if (out != null) { - out.close(); - out = null; - } - } catch (IOException x) { - trouble = true; - } - } - /** * Flushes the stream if it's not closed and checks its error state. * @@ -487,32 +456,18 @@ protected void clearError() { * @param c int specifying a character to be written. */ public void write(int c) { - Object lock = this.lock; - if (lock instanceof InternalLock locker) { - locker.lock(); + synchronized (lock) { try { - implWrite(c); - } finally { - locker.unlock(); - } - } else { - synchronized (lock) { - implWrite(c); + ensureOpen(); + out.write(c); + } catch (InterruptedIOException x) { + Thread.currentThread().interrupt(); + } catch (IOException x) { + trouble = true; } } } - private void implWrite(int c) { - try { - ensureOpen(); - out.write(c); - } catch (InterruptedIOException x) { - Thread.currentThread().interrupt(); - } catch (IOException x) { - trouble = true; - } - } - /** * Writes A Portion of an array of characters. * @param buf Array of characters @@ -525,29 +480,15 @@ private void implWrite(int c) { * to throw an {@code IndexOutOfBoundsException} */ public void write(char[] buf, int off, int len) { - Object lock = this.lock; - if (lock instanceof InternalLock locker) { - locker.lock(); + synchronized (lock) { try { - implWrite(buf, off, len); - } finally { - locker.unlock(); + ensureOpen(); + out.write(buf, off, len); + } catch (InterruptedIOException x) { + Thread.currentThread().interrupt(); + } catch (IOException x) { + trouble = true; } - } else { - synchronized (lock) { - implWrite(buf, off, len); - } - } - } - - private void implWrite(char[] buf, int off, int len) { - try { - ensureOpen(); - out.write(buf, off, len); - } catch (InterruptedIOException x) { - Thread.currentThread().interrupt(); - } catch (IOException x) { - trouble = true; } } @@ -572,29 +513,15 @@ public void write(char[] buf) { * to throw an {@code IndexOutOfBoundsException} */ public void write(String s, int off, int len) { - Object lock = this.lock; - if (lock instanceof InternalLock locker) { - locker.lock(); + synchronized (lock) { try { - implWrite(s, off, len); - } finally { - locker.unlock(); + ensureOpen(); + out.write(s, off, len); + } catch (InterruptedIOException x) { + Thread.currentThread().interrupt(); + } catch (IOException x) { + trouble = true; } - } else { - synchronized (lock) { - implWrite(s, off, len); - } - } - } - - private void implWrite(String s, int off, int len) { - try { - ensureOpen(); - out.write(s, off, len); - } catch (InterruptedIOException x) { - Thread.currentThread().interrupt(); - } catch (IOException x) { - trouble = true; } } @@ -608,34 +535,20 @@ public void write(String s) { } private void newLine() { - Object lock = this.lock; - if (lock instanceof InternalLock locker) { - locker.lock(); + synchronized (lock) { try { - implNewLine(); - } finally { - locker.unlock(); - } - } else { - synchronized (lock) { - implNewLine(); + ensureOpen(); + out.write(System.lineSeparator()); + if (autoFlush) + out.flush(); + } catch (InterruptedIOException x) { + Thread.currentThread().interrupt(); + } catch (IOException x) { + trouble = true; } } } - private void implNewLine() { - try { - ensureOpen(); - out.write(System.lineSeparator()); - if (autoFlush) - out.flush(); - } catch (InterruptedIOException x) { - Thread.currentThread().interrupt(); - } catch (IOException x) { - trouble = true; - } - } - /* Methods that do not terminate lines */ /** @@ -788,20 +701,9 @@ public void println() { * @param x the {@code boolean} value to be printed */ public void println(boolean x) { - Object lock = this.lock; - if (lock instanceof InternalLock locker) { - locker.lock(); - try { - print(x); - println(); - } finally { - locker.unlock(); - } - } else { - synchronized (lock) { - print(x); - println(); - } + synchronized (lock) { + print(x); + println(); } } @@ -813,20 +715,9 @@ public void println(boolean x) { * @param x the {@code char} value to be printed */ public void println(char x) { - Object lock = this.lock; - if (lock instanceof InternalLock locker) { - locker.lock(); - try { - print(x); - println(); - } finally { - locker.unlock(); - } - } else { - synchronized (lock) { - print(x); - println(); - } + synchronized (lock) { + print(x); + println(); } } @@ -838,20 +729,9 @@ public void println(char x) { * @param x the {@code int} value to be printed */ public void println(int x) { - Object lock = this.lock; - if (lock instanceof InternalLock locker) { - locker.lock(); - try { - print(x); - println(); - } finally { - locker.unlock(); - } - } else { - synchronized (lock) { - print(x); - println(); - } + synchronized (lock) { + print(x); + println(); } } @@ -863,20 +743,9 @@ public void println(int x) { * @param x the {@code long} value to be printed */ public void println(long x) { - Object lock = this.lock; - if (lock instanceof InternalLock locker) { - locker.lock(); - try { - print(x); - println(); - } finally { - locker.unlock(); - } - } else { - synchronized (lock) { - print(x); - println(); - } + synchronized (lock) { + print(x); + println(); } } @@ -888,20 +757,9 @@ public void println(long x) { * @param x the {@code float} value to be printed */ public void println(float x) { - Object lock = this.lock; - if (lock instanceof InternalLock locker) { - locker.lock(); - try { - print(x); - println(); - } finally { - locker.unlock(); - } - } else { - synchronized (lock) { - print(x); - println(); - } + synchronized (lock) { + print(x); + println(); } } @@ -913,20 +771,9 @@ public void println(float x) { * @param x the {@code double} value to be printed */ public void println(double x) { - Object lock = this.lock; - if (lock instanceof InternalLock locker) { - locker.lock(); - try { - print(x); - println(); - } finally { - locker.unlock(); - } - } else { - synchronized (lock) { - print(x); - println(); - } + synchronized (lock) { + print(x); + println(); } } @@ -938,20 +785,9 @@ public void println(double x) { * @param x the array of {@code char} values to be printed */ public void println(char[] x) { - Object lock = this.lock; - if (lock instanceof InternalLock locker) { - locker.lock(); - try { - print(x); - println(); - } finally { - locker.unlock(); - } - } else { - synchronized (lock) { - print(x); - println(); - } + synchronized (lock) { + print(x); + println(); } } @@ -963,20 +799,9 @@ public void println(char[] x) { * @param x the {@code String} value to be printed */ public void println(String x) { - Object lock = this.lock; - if (lock instanceof InternalLock locker) { - locker.lock(); - try { - print(x); - println(); - } finally { - locker.unlock(); - } - } else { - synchronized (lock) { - print(x); - println(); - } + synchronized (lock) { + print(x); + println(); } } @@ -991,20 +816,9 @@ public void println(String x) { */ public void println(Object x) { String s = String.valueOf(x); - Object lock = this.lock; - if (lock instanceof InternalLock locker) { - locker.lock(); - try { - print(s); - println(); - } finally { - locker.unlock(); - } - } else { - synchronized (lock) { - print(s); - println(); - } + synchronized (lock) { + print(s); + println(); } } @@ -1150,38 +964,24 @@ public PrintWriter printf(Locale l, String format, Object ... args) { * @since 1.5 */ public PrintWriter format(String format, Object ... args) { - Object lock = this.lock; - if (lock instanceof InternalLock locker) { - locker.lock(); + synchronized (lock) { try { - implFormat(format, args); - } finally { - locker.unlock(); - } - } else { - synchronized (lock) { - implFormat(format, args); + ensureOpen(); + if ((formatter == null) + || (formatter.locale() != Locale.getDefault())) + formatter = new Formatter(this); + formatter.format(Locale.getDefault(), format, args); + if (autoFlush) + out.flush(); + } catch (InterruptedIOException x) { + Thread.currentThread().interrupt(); + } catch (IOException x) { + trouble = true; } } return this; } - private void implFormat(String format, Object ... args) { - try { - ensureOpen(); - if ((formatter == null) - || (formatter.locale() != Locale.getDefault())) - formatter = new Formatter(this); - formatter.format(Locale.getDefault(), format, args); - if (autoFlush) - out.flush(); - } catch (InterruptedIOException x) { - Thread.currentThread().interrupt(); - } catch (IOException x) { - trouble = true; - } - } - /** * Writes a formatted string to this writer using the specified format * string and arguments. If automatic flushing is enabled, calls to this @@ -1224,37 +1024,23 @@ private void implFormat(String format, Object ... args) { * @since 1.5 */ public PrintWriter format(Locale l, String format, Object ... args) { - Object lock = this.lock; - if (lock instanceof InternalLock locker) { - locker.lock(); + synchronized (lock) { try { - implFormat(l, format, args); - } finally { - locker.unlock(); - } - } else { - synchronized (lock) { - implFormat(l, format, args); + ensureOpen(); + if ((formatter == null) || (formatter.locale() != l)) + formatter = new Formatter(this, l); + formatter.format(l, format, args); + if (autoFlush) + out.flush(); + } catch (InterruptedIOException x) { + Thread.currentThread().interrupt(); + } catch (IOException x) { + trouble = true; } } return this; } - private void implFormat(Locale l, String format, Object ... args) { - try { - ensureOpen(); - if ((formatter == null) || (formatter.locale() != l)) - formatter = new Formatter(this, l); - formatter.format(l, format, args); - if (autoFlush) - out.flush(); - } catch (InterruptedIOException x) { - Thread.currentThread().interrupt(); - } catch (IOException x) { - trouble = true; - } - } - /** * Appends the specified character sequence to this writer. * @@ -1346,12 +1132,4 @@ public PrintWriter append(char c) { write(c); return this; } - - static { - SharedSecrets.setJavaIOCPrintWriterAccess(new JavaIOPrintWriterAccess() { - public Object lock(PrintWriter pw) { - return pw.lock; - } - }); - } } diff --git a/src/java.base/share/classes/java/io/PushbackInputStream.java b/src/java.base/share/classes/java/io/PushbackInputStream.java index 0c74205ba0e..5aa0e133df9 100644 --- a/src/java.base/share/classes/java/io/PushbackInputStream.java +++ b/src/java.base/share/classes/java/io/PushbackInputStream.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1994, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1994, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -27,7 +27,6 @@ import java.util.Arrays; import java.util.Objects; -import jdk.internal.misc.InternalLock; /** * A {@code PushbackInputStream} adds @@ -54,10 +53,6 @@ * @since 1.0 */ public class PushbackInputStream extends FilterInputStream { - - // initialized to null when PushbackInputStream is sub-classed - private final InternalLock closeLock; - /** * The pushback buffer. * @since 1.1 @@ -101,13 +96,6 @@ public PushbackInputStream(InputStream in, int size) { } this.buf = new byte[size]; this.pos = size; - - // use monitors when PushbackInputStream is sub-classed - if (getClass() == PushbackInputStream.class) { - closeLock = InternalLock.newLockOrNull(); - } else { - closeLock = null; - } } /** @@ -386,27 +374,12 @@ public void reset() throws IOException { * * @throws IOException if an I/O error occurs. */ - public void close() throws IOException { - if (closeLock != null) { - closeLock.lock(); - try { - implClose(); - } finally { - closeLock.unlock(); - } - } else { - synchronized (this) { - implClose(); - } - } - } - - private void implClose() throws IOException { - if (in != null) { - in.close(); - in = null; - buf = null; - } + public synchronized void close() throws IOException { + if (in == null) + return; + in.close(); + in = null; + buf = null; } @Override diff --git a/src/java.base/share/classes/java/io/Reader.java b/src/java.base/share/classes/java/io/Reader.java index 9fca28a3a96..1654156bee1 100644 --- a/src/java.base/share/classes/java/io/Reader.java +++ b/src/java.base/share/classes/java/io/Reader.java @@ -28,7 +28,6 @@ import java.nio.CharBuffer; import java.nio.ReadOnlyBufferException; import java.util.Objects; -import jdk.internal.misc.InternalLock; /** * Abstract class for reading character streams. The only methods that a @@ -283,21 +282,6 @@ protected Reader(Object lock) { this.lock = lock; } - /** - * For use by BufferedReader to create a character-stream reader that uses an - * internal lock when BufferedReader is not extended and the given reader is - * trusted, otherwise critical sections will synchronize on the given reader. - */ - Reader(Reader in) { - Class clazz = in.getClass(); - if (getClass() == BufferedReader.class && - (clazz == InputStreamReader.class || clazz == FileReader.class)) { - this.lock = InternalLock.newLockOr(in); - } else { - this.lock = in; - } - } - /** * Attempts to read characters into the specified character buffer. * The buffer is used as a repository of characters as-is: the only @@ -429,33 +413,19 @@ public int read(char[] cbuf) throws IOException { public long skip(long n) throws IOException { if (n < 0L) throw new IllegalArgumentException("skip value is negative"); - Object lock = this.lock; - if (lock instanceof InternalLock locker) { - locker.lock(); - try { - return implSkip(n); - } finally { - locker.unlock(); + synchronized (lock) { + int nn = (int) Math.min(n, maxSkipBufferSize); + if ((skipBuffer == null) || (skipBuffer.length < nn)) + skipBuffer = new char[nn]; + long r = n; + while (r > 0) { + int nc = read(skipBuffer, 0, (int)Math.min(r, nn)); + if (nc == -1) + break; + r -= nc; } - } else { - synchronized (lock) { - return implSkip(n); - } - } - } - - private long implSkip(long n) throws IOException { - int nn = (int) Math.min(n, maxSkipBufferSize); - if ((skipBuffer == null) || (skipBuffer.length < nn)) - skipBuffer = new char[nn]; - long r = n; - while (r > 0) { - int nc = read(skipBuffer, 0, (int)Math.min(r, nn)); - if (nc == -1) - break; - r -= nc; + return n - r; } - return n - r; } /** diff --git a/src/java.base/share/classes/java/io/Writer.java b/src/java.base/share/classes/java/io/Writer.java index 62fe6b053e5..433a116a4bb 100644 --- a/src/java.base/share/classes/java/io/Writer.java +++ b/src/java.base/share/classes/java/io/Writer.java @@ -26,7 +26,6 @@ package java.io; import java.util.Objects; -import jdk.internal.misc.InternalLock; /** * Abstract class for writing to character streams. The only methods that a @@ -162,21 +161,6 @@ protected Writer() { this.lock = this; } - /** - * For use by BufferedWriter to create a character-stream writer that uses an - * internal lock when BufferedWriter is not extended and the given writer is - * trusted, otherwise critical sections will synchronize on the given writer. - */ - Writer(Writer writer) { - Class clazz = writer.getClass(); - if (getClass() == BufferedWriter.class && - (clazz == OutputStreamWriter.class || clazz == FileWriter.class)) { - this.lock = InternalLock.newLockOr(writer); - } else { - this.lock = writer; - } - } - /** * Creates a new character-stream writer whose critical sections will * synchronize on the given object. @@ -206,29 +190,15 @@ protected Writer(Object lock) { * If an I/O error occurs */ public void write(int c) throws IOException { - Object lock = this.lock; - if (lock instanceof InternalLock locker) { - locker.lock(); - try { - implWrite(c); - } finally { - locker.unlock(); - } - } else { - synchronized (lock) { - implWrite(c); + synchronized (lock) { + if (writeBuffer == null){ + writeBuffer = new char[WRITE_BUFFER_SIZE]; } + writeBuffer[0] = (char) c; + write(writeBuffer, 0, 1); } } - private void implWrite(int c) throws IOException { - if (writeBuffer == null){ - writeBuffer = new char[WRITE_BUFFER_SIZE]; - } - writeBuffer[0] = (char) c; - write(writeBuffer, 0, 1); - } - /** * Writes an array of characters. * @@ -305,33 +275,19 @@ public void write(String str) throws IOException { * If an I/O error occurs */ public void write(String str, int off, int len) throws IOException { - Object lock = this.lock; - if (lock instanceof InternalLock locker) { - locker.lock(); - try { - implWrite(str, off, len); - } finally { - locker.unlock(); - } - } else { - synchronized (lock) { - implWrite(str, off, len); - } - } - } - - private void implWrite(String str, int off, int len) throws IOException { - char cbuf[]; - if (len <= WRITE_BUFFER_SIZE) { - if (writeBuffer == null) { - writeBuffer = new char[WRITE_BUFFER_SIZE]; + synchronized (lock) { + char cbuf[]; + if (len <= WRITE_BUFFER_SIZE) { + if (writeBuffer == null) { + writeBuffer = new char[WRITE_BUFFER_SIZE]; + } + cbuf = writeBuffer; + } else { // Don't permanently allocate very large buffers. + cbuf = new char[len]; } - cbuf = writeBuffer; - } else { // Don't permanently allocate very large buffers. - cbuf = new char[len]; + str.getChars(off, (off + len), cbuf, 0); + write(cbuf, 0, len); } - str.getChars(off, (off + len), cbuf, 0); - write(cbuf, 0, len); } /** diff --git a/src/java.base/share/classes/java/lang/Throwable.java b/src/java.base/share/classes/java/lang/Throwable.java index 275961a9a9f..8c0ce29dbee 100644 --- a/src/java.base/share/classes/java/lang/Throwable.java +++ b/src/java.base/share/classes/java/lang/Throwable.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1994, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1994, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -27,9 +27,7 @@ import java.io.*; import java.util.*; -import jdk.internal.access.SharedSecrets; import jdk.internal.event.ThrowableTracer; -import jdk.internal.misc.InternalLock; /** * The {@code Throwable} class is the superclass of all errors and @@ -689,39 +687,27 @@ public void printStackTrace(PrintStream s) { } private void printStackTrace(PrintStreamOrWriter s) { - Object lock = s.lock(); - if (lock instanceof InternalLock locker) { - locker.lock(); - try { - lockedPrintStackTrace(s); - } finally { - locker.unlock(); - } - } else synchronized (lock) { - lockedPrintStackTrace(s); - } - } - - private void lockedPrintStackTrace(PrintStreamOrWriter s) { // Guard against malicious overrides of Throwable.equals by // using a Set with identity equality semantics. Set dejaVu = Collections.newSetFromMap(new IdentityHashMap<>()); dejaVu.add(this); - // Print our stack trace - s.println(this); - StackTraceElement[] trace = getOurStackTrace(); - for (StackTraceElement traceElement : trace) - s.println("\tat " + traceElement); + synchronized(s.lock()) { + // Print our stack trace + s.println(this); + StackTraceElement[] trace = getOurStackTrace(); + for (StackTraceElement traceElement : trace) + s.println("\tat " + traceElement); - // Print suppressed exceptions, if any - for (Throwable se : getSuppressed()) - se.printEnclosedStackTrace(s, trace, SUPPRESSED_CAPTION, "\t", dejaVu); + // Print suppressed exceptions, if any + for (Throwable se : getSuppressed()) + se.printEnclosedStackTrace(s, trace, SUPPRESSED_CAPTION, "\t", dejaVu); - // Print cause, if any - Throwable ourCause = getCause(); - if (ourCause != null) - ourCause.printEnclosedStackTrace(s, trace, CAUSE_CAPTION, "", dejaVu); + // Print cause, if any + Throwable ourCause = getCause(); + if (ourCause != null) + ourCause.printEnclosedStackTrace(s, trace, CAUSE_CAPTION, "", dejaVu); + } } /** @@ -733,7 +719,7 @@ private void printEnclosedStackTrace(PrintStreamOrWriter s, String caption, String prefix, Set dejaVu) { - assert s.isLockedByCurrentThread(); + assert Thread.holdsLock(s.lock()); if (dejaVu.contains(this)) { s.println(prefix + caption + "[CIRCULAR REFERENCE: " + this + "]"); } else { @@ -785,15 +771,6 @@ private abstract static class PrintStreamOrWriter { /** Returns the object to be locked when using this StreamOrWriter */ abstract Object lock(); - boolean isLockedByCurrentThread() { - Object lock = lock(); - if (lock instanceof InternalLock locker) { - return locker.isHeldByCurrentThread(); - } else { - return Thread.holdsLock(lock); - } - } - /** Prints the specified string as a line on this StreamOrWriter */ abstract void println(Object o); } @@ -806,7 +783,7 @@ private static class WrappedPrintStream extends PrintStreamOrWriter { } Object lock() { - return SharedSecrets.getJavaIOPrintStreamAccess().lock(printStream); + return printStream; } void println(Object o) { @@ -822,7 +799,7 @@ private static class WrappedPrintWriter extends PrintStreamOrWriter { } Object lock() { - return SharedSecrets.getJavaIOPrintWriterAccess().lock(printWriter); + return printWriter; } void println(Object o) { diff --git a/src/java.base/share/classes/jdk/internal/access/JavaIOPrintStreamAccess.java b/src/java.base/share/classes/jdk/internal/access/JavaIOPrintStreamAccess.java deleted file mode 100644 index ec205e27dca..00000000000 --- a/src/java.base/share/classes/jdk/internal/access/JavaIOPrintStreamAccess.java +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright (c) 2020, 2022, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package jdk.internal.access; - -import java.io.PrintStream; - -public interface JavaIOPrintStreamAccess { - Object lock(PrintStream ps); -} diff --git a/src/java.base/share/classes/jdk/internal/access/JavaIOPrintWriterAccess.java b/src/java.base/share/classes/jdk/internal/access/JavaIOPrintWriterAccess.java deleted file mode 100644 index 8be54a76b0a..00000000000 --- a/src/java.base/share/classes/jdk/internal/access/JavaIOPrintWriterAccess.java +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright (c) 2020, 2022, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package jdk.internal.access; - -import java.io.PrintWriter; - -public interface JavaIOPrintWriterAccess { - Object lock(PrintWriter pw); -} diff --git a/src/java.base/share/classes/jdk/internal/access/SharedSecrets.java b/src/java.base/share/classes/jdk/internal/access/SharedSecrets.java index 5acafe01a89..c29d0dd01a5 100644 --- a/src/java.base/share/classes/jdk/internal/access/SharedSecrets.java +++ b/src/java.base/share/classes/jdk/internal/access/SharedSecrets.java @@ -71,8 +71,6 @@ public class SharedSecrets { private static JavaLangRefAccess javaLangRefAccess; private static JavaLangReflectAccess javaLangReflectAccess; private static JavaIOAccess javaIOAccess; - private static JavaIOPrintStreamAccess javaIOPrintStreamAccess; - private static JavaIOPrintWriterAccess javaIOPrintWriterAccess; private static JavaIOFileDescriptorAccess javaIOFileDescriptorAccess; private static JavaIOFilePermissionAccess javaIOFilePermissionAccess; private static JavaIORandomAccessFileAccess javaIORandomAccessFileAccess; @@ -288,32 +286,6 @@ public static JavaIOAccess getJavaIOAccess() { return access; } - public static void setJavaIOCPrintWriterAccess(JavaIOPrintWriterAccess a) { - javaIOPrintWriterAccess = a; - } - - public static JavaIOPrintWriterAccess getJavaIOPrintWriterAccess() { - var access = javaIOPrintWriterAccess; - if (access == null) { - ensureClassInitialized(PrintWriter.class); - access = javaIOPrintWriterAccess; - } - return access; - } - - public static void setJavaIOCPrintStreamAccess(JavaIOPrintStreamAccess a) { - javaIOPrintStreamAccess = a; - } - - public static JavaIOPrintStreamAccess getJavaIOPrintStreamAccess() { - var access = javaIOPrintStreamAccess; - if (access == null) { - ensureClassInitialized(PrintStream.class); - access = javaIOPrintStreamAccess; - } - return access; - } - public static void setJavaIOFileDescriptorAccess(JavaIOFileDescriptorAccess jiofda) { javaIOFileDescriptorAccess = jiofda; } diff --git a/src/java.base/share/classes/jdk/internal/misc/InternalLock.java b/src/java.base/share/classes/jdk/internal/misc/InternalLock.java deleted file mode 100644 index 822b64f74ca..00000000000 --- a/src/java.base/share/classes/jdk/internal/misc/InternalLock.java +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright (c) 2021, 2024, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.internal.misc; - -import java.util.concurrent.locks.ReentrantLock; - -/** - * A reentrant mutual exclusion lock for internal use. The lock does not - * implement {@link java.util.concurrent.locks.Lock} or extend {@link - * java.util.concurrent.locks.ReentrantLock} so that it can be distinguished - * from lock objects accessible to subclasses of {@link java.io.Reader} and - * {@link java.io.Writer} (it is possible to create a Reader that uses a - * lock object of type ReentrantLock for example). - */ -public class InternalLock { - private static final boolean CAN_USE_INTERNAL_LOCK; - static { - String s = System.getProperty("jdk.io.useMonitors"); - if (s != null && s.equals("false")) { - CAN_USE_INTERNAL_LOCK = true; - } else { - CAN_USE_INTERNAL_LOCK = false; - } - } - - private final ReentrantLock lock; - - private InternalLock() { - this.lock = new ReentrantLock(); - } - - /** - * Returns a new InternalLock or null. - */ - public static InternalLock newLockOrNull() { - return (CAN_USE_INTERNAL_LOCK) ? new InternalLock() : null; - } - - /** - * Returns a new InternalLock or the given object. - */ - public static Object newLockOr(Object obj) { - return (CAN_USE_INTERNAL_LOCK) ? new InternalLock() : obj; - } - - public boolean tryLock() { - return lock.tryLock(); - } - - public void lock() { - lock.lock(); - } - - public void unlock() { - lock.unlock(); - } - - public boolean isHeldByCurrentThread() { - return lock.isHeldByCurrentThread(); - } -} diff --git a/src/java.base/share/classes/sun/nio/cs/StreamDecoder.java b/src/java.base/share/classes/sun/nio/cs/StreamDecoder.java index a2026744f04..124e41b77c9 100644 --- a/src/java.base/share/classes/sun/nio/cs/StreamDecoder.java +++ b/src/java.base/share/classes/sun/nio/cs/StreamDecoder.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -44,8 +44,6 @@ import java.nio.charset.UnsupportedCharsetException; import java.util.Arrays; -import jdk.internal.misc.InternalLock; - public class StreamDecoder extends Reader { private static final int MIN_BYTE_BUFFER_SIZE = 32; @@ -121,178 +119,109 @@ public int read() throws IOException { return read0(); } + @SuppressWarnings("fallthrough") private int read0() throws IOException { - Object lock = this.lock; - if (lock instanceof InternalLock locker) { - locker.lock(); - try { - return lockedRead0(); - } finally { - locker.unlock(); - } - } else { - synchronized (lock) { - return lockedRead0(); + synchronized (lock) { + // Return the leftover char, if there is one + if (haveLeftoverChar) { + haveLeftoverChar = false; + return leftoverChar; } - } - } - - @SuppressWarnings("fallthrough") - private int lockedRead0() throws IOException { - // Return the leftover char, if there is one - if (haveLeftoverChar) { - haveLeftoverChar = false; - return leftoverChar; - } - // Convert more bytes - char[] cb = new char[2]; - int n = read(cb, 0, 2); - switch (n) { - case -1: - return -1; - case 2: - leftoverChar = cb[1]; - haveLeftoverChar = true; - // FALL THROUGH - case 1: - return cb[0]; - default: - assert false : n; - return -1; + // Convert more bytes + char[] cb = new char[2]; + int n = read(cb, 0, 2); + switch (n) { + case -1: + return -1; + case 2: + leftoverChar = cb[1]; + haveLeftoverChar = true; + // FALL THROUGH + case 1: + return cb[0]; + default: + assert false : n; + return -1; + } } } public int read(char[] cbuf, int offset, int length) throws IOException { - Object lock = this.lock; - if (lock instanceof InternalLock locker) { - locker.lock(); - try { - return lockedRead(cbuf, offset, length); - } finally { - locker.unlock(); + synchronized (lock) { + int off = offset; + int len = length; + + ensureOpen(); + if ((off < 0) || (off > cbuf.length) || (len < 0) || + ((off + len) > cbuf.length) || ((off + len) < 0)) { + throw new IndexOutOfBoundsException(); } - } else { - synchronized (lock) { - return lockedRead(cbuf, offset, length); + if (len == 0) + return 0; + + int n = 0; + + if (haveLeftoverChar) { + // Copy the leftover char into the buffer + cbuf[off] = leftoverChar; + off++; len--; + haveLeftoverChar = false; + n = 1; + if ((len == 0) || !implReady()) + // Return now if this is all we can produce w/o blocking + return n; } - } - } - private int lockedRead(char[] cbuf, int offset, int length) throws IOException { - int off = offset; - int len = length; + if (len == 1) { + // Treat single-character array reads just like read() + int c = read0(); + if (c == -1) + return (n == 0) ? -1 : n; + cbuf[off] = (char)c; + return n + 1; + } - ensureOpen(); - if ((off < 0) || (off > cbuf.length) || (len < 0) || - ((off + len) > cbuf.length) || ((off + len) < 0)) { - throw new IndexOutOfBoundsException(); - } - if (len == 0) - return 0; - - int n = 0; - - if (haveLeftoverChar) { - // Copy the leftover char into the buffer - cbuf[off] = leftoverChar; - off++; len--; - haveLeftoverChar = false; - n = 1; - if ((len == 0) || !implReady()) - // Return now if this is all we can produce w/o blocking - return n; - } + // Read remaining characters + int nr = implRead(cbuf, off, off + len); - if (len == 1) { - // Treat single-character array reads just like read() - int c = read0(); - if (c == -1) - return (n == 0) ? -1 : n; - cbuf[off] = (char)c; - return n + 1; + // At this point, n is either 1 if a leftover character was read, + // or 0 if no leftover character was read. If n is 1 and nr is -1, + // indicating EOF, then we don't return their sum as this loses data. + return (nr < 0) ? (n == 1 ? 1 : nr) : (n + nr); } - - // Read remaining characters - int nr = implRead(cbuf, off, off + len); - - // At this point, n is either 1 if a leftover character was read, - // or 0 if no leftover character was read. If n is 1 and nr is -1, - // indicating EOF, then we don't return their sum as this loses data. - return (nr < 0) ? (n == 1 ? 1 : nr) : (n + nr); } public boolean ready() throws IOException { - Object lock = this.lock; - if (lock instanceof InternalLock locker) { - locker.lock(); - try { - return lockedReady(); - } finally { - locker.unlock(); - } - } else { - synchronized (lock) { - return lockedReady(); - } + synchronized (lock) { + ensureOpen(); + return haveLeftoverChar || implReady(); } } - private boolean lockedReady() throws IOException { - ensureOpen(); - return haveLeftoverChar || implReady(); - } - public void close() throws IOException { - Object lock = this.lock; - if (lock instanceof InternalLock locker) { - locker.lock(); + synchronized (lock) { + if (closed) + return; try { - lockedClose(); + implClose(); } finally { - locker.unlock(); - } - } else { - synchronized (lock) { - lockedClose(); + closed = true; } } } - private void lockedClose() throws IOException { - if (closed) - return; - try { - implClose(); - } finally { - closed = true; - } - } - private boolean isOpen() { return !closed; } public void fillZeroToPosition() throws IOException { - Object lock = this.lock; - if (lock instanceof InternalLock locker) { - locker.lock(); - try { - lockedFillZeroToPosition(); - } finally { - locker.unlock(); - } - } else { - synchronized (lock) { - lockedFillZeroToPosition(); - } + synchronized (lock) { + Arrays.fill(bb.array(), bb.arrayOffset(), + bb.arrayOffset() + bb.position(), (byte)0); } } - private void lockedFillZeroToPosition() { - Arrays.fill(bb.array(), bb.arrayOffset(), bb.arrayOffset() + bb.position(), (byte)0); - } - // -- Charset-based stream decoder impl -- private final Charset cs; diff --git a/src/java.base/share/classes/sun/nio/cs/StreamEncoder.java b/src/java.base/share/classes/sun/nio/cs/StreamEncoder.java index 3a82030121a..b580ad2f921 100644 --- a/src/java.base/share/classes/sun/nio/cs/StreamEncoder.java +++ b/src/java.base/share/classes/sun/nio/cs/StreamEncoder.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -37,7 +37,6 @@ import java.nio.charset.CodingErrorAction; import java.nio.charset.IllegalCharsetNameException; import java.nio.charset.UnsupportedCharsetException; -import jdk.internal.misc.InternalLock; public final class StreamEncoder extends Writer { @@ -97,28 +96,14 @@ public String getEncoding() { } public void flushBuffer() throws IOException { - Object lock = this.lock; - if (lock instanceof InternalLock locker) { - locker.lock(); - try { - lockedFlushBuffer(); - } finally { - locker.unlock(); - } - } else { - synchronized (lock) { - lockedFlushBuffer(); - } + synchronized (lock) { + if (isOpen()) + implFlushBuffer(); + else + throw new IOException("Stream closed"); } } - private void lockedFlushBuffer() throws IOException { - if (isOpen()) - implFlushBuffer(); - else - throw new IOException("Stream closed"); - } - public void write(int c) throws IOException { char[] cbuf = new char[1]; cbuf[0] = (char) c; @@ -126,30 +111,16 @@ public void write(int c) throws IOException { } public void write(char[] cbuf, int off, int len) throws IOException { - Object lock = this.lock; - if (lock instanceof InternalLock locker) { - locker.lock(); - try { - lockedWrite(cbuf, off, len); - } finally { - locker.unlock(); - } - } else { - synchronized (lock) { - lockedWrite(cbuf, off, len); - } - } - } - - private void lockedWrite(char[] cbuf, int off, int len) throws IOException { - ensureOpen(); - if ((off < 0) || (off > cbuf.length) || (len < 0) || + synchronized (lock) { + ensureOpen(); + if ((off < 0) || (off > cbuf.length) || (len < 0) || ((off + len) > cbuf.length) || ((off + len) < 0)) { - throw new IndexOutOfBoundsException(); - } else if (len == 0) { - return; + throw new IndexOutOfBoundsException(); + } else if (len == 0) { + return; + } + implWrite(cbuf, off, len); } - implWrite(cbuf, off, len); } public void write(String str, int off, int len) throws IOException { @@ -164,76 +135,34 @@ public void write(String str, int off, int len) throws IOException { public void write(CharBuffer cb) throws IOException { int position = cb.position(); try { - Object lock = this.lock; - if (lock instanceof InternalLock locker) { - locker.lock(); - try { - lockedWrite(cb); - } finally { - locker.unlock(); - } - } else { - synchronized (lock) { - lockedWrite(cb); - } + synchronized (lock) { + ensureOpen(); + implWrite(cb); } } finally { cb.position(position); } } - private void lockedWrite(CharBuffer cb) throws IOException { - ensureOpen(); - implWrite(cb); - } - public void flush() throws IOException { - Object lock = this.lock; - if (lock instanceof InternalLock locker) { - locker.lock(); - try { - lockedFlush(); - } finally { - locker.unlock(); - } - } else { - synchronized (lock) { - lockedFlush(); - } + synchronized (lock) { + ensureOpen(); + implFlush(); } } - private void lockedFlush() throws IOException { - ensureOpen(); - implFlush(); - } - public void close() throws IOException { - Object lock = this.lock; - if (lock instanceof InternalLock locker) { - locker.lock(); + synchronized (lock) { + if (closed) + return; try { - lockedClose(); + implClose(); } finally { - locker.unlock(); - } - } else { - synchronized (lock) { - lockedClose(); + closed = true; } } } - private void lockedClose() throws IOException { - if (closed) - return; - try { - implClose(); - } finally { - closed = true; - } - } - private boolean isOpen() { return !closed; } diff --git a/test/jdk/java/lang/ProcessBuilder/Basic.java b/test/jdk/java/lang/ProcessBuilder/Basic.java index e1e2cef9a8a..68b3ab56b6d 100644 --- a/test/jdk/java/lang/ProcessBuilder/Basic.java +++ b/test/jdk/java/lang/ProcessBuilder/Basic.java @@ -32,7 +32,6 @@ * @summary Basic tests for Process and Environment Variable code * @modules java.base/java.lang:open * java.base/java.io:open - * java.base/jdk.internal.misc * @requires !vm.musl * @requires vm.flagless * @library /test/lib @@ -2676,17 +2675,6 @@ static void THROWS(Class k, Fun... fs) { else unexpected(t);}} static boolean isLocked(BufferedInputStream bis) throws Exception { - Field lockField = BufferedInputStream.class.getDeclaredField("lock"); - lockField.setAccessible(true); - var lock = (jdk.internal.misc.InternalLock) lockField.get(bis); - if (lock != null) { - if (lock.tryLock()) { - lock.unlock(); - return false; - } else { - return true; - } - } return new Thread() { volatile boolean unlocked; From 1866c0c2ce925ed5236532cb7e3bdc61a6cd18d5 Mon Sep 17 00:00:00 2001 From: Paul Sandoz Date: Fri, 15 Nov 2024 17:22:11 +0000 Subject: [PATCH 021/311] 8344259: Annotate Float16 with jdk.internal.ValueBased Reviewed-by: liach, darcy --- src/java.base/share/classes/module-info.java | 2 ++ .../share/classes/jdk/incubator/vector/Float16.java | 5 ++--- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/java.base/share/classes/module-info.java b/src/java.base/share/classes/module-info.java index d683d837a09..828e0d41504 100644 --- a/src/java.base/share/classes/module-info.java +++ b/src/java.base/share/classes/module-info.java @@ -146,6 +146,8 @@ jdk.compiler; exports com.sun.security.ntlm to java.security.sasl; + exports jdk.internal to + jdk.incubator.vector; // Note: all modules in the exported list participate in preview features // and therefore if they use preview features they do not need to be // compiled with "--enable-preview". diff --git a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Float16.java b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Float16.java index 5a7cdb89dde..f5f5a5a4e7e 100644 --- a/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Float16.java +++ b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/Float16.java @@ -95,8 +95,7 @@ // Currently Float16 is a value-based class and in future it is // expected to be aligned with Value Classes and Object as described in // JEP-401 (https://openjdk.org/jeps/401). -// @jdk.internal.MigratedValueClass -// @jdk.internal.ValueBased +@jdk.internal.ValueBased public final class Float16 extends Number implements Comparable { @@ -323,7 +322,7 @@ public static Float16 valueOf(long value) { * @param f a {@code float} */ public static Float16 valueOf(float f) { - return new Float16(Float.floatToFloat16(f)); + return new Float16(floatToFloat16(f)); } /** From ff12ff534abb2e08d1bb44a83ef4f84b8476f94c Mon Sep 17 00:00:00 2001 From: Roman Kennke Date: Fri, 15 Nov 2024 18:10:30 +0000 Subject: [PATCH 022/311] 8340453: C2: Improve encoding of LoadNKlass for compact headers Reviewed-by: rcastanedalo, mli --- src/hotspot/cpu/aarch64/aarch64.ad | 17 +++++++++-------- .../cpu/aarch64/c2_MacroAssembler_aarch64.cpp | 9 --------- .../cpu/aarch64/c2_MacroAssembler_aarch64.hpp | 2 -- src/hotspot/cpu/x86/c2_MacroAssembler_x86.cpp | 10 ---------- src/hotspot/cpu/x86/c2_MacroAssembler_x86.hpp | 4 ---- src/hotspot/cpu/x86/x86_64.ad | 10 +++++++--- src/hotspot/share/oops/markWord.hpp | 2 ++ src/hotspot/share/oops/oop.hpp | 8 ++------ src/hotspot/share/opto/memnode.hpp | 6 ++++++ 9 files changed, 26 insertions(+), 42 deletions(-) diff --git a/src/hotspot/cpu/aarch64/aarch64.ad b/src/hotspot/cpu/aarch64/aarch64.ad index a97d01b7683..1015b631643 100644 --- a/src/hotspot/cpu/aarch64/aarch64.ad +++ b/src/hotspot/cpu/aarch64/aarch64.ad @@ -5755,10 +5755,6 @@ opclass memory(indirect, indIndexScaled, indIndexScaledI2L, indIndexI2L, indInde indirectN, indIndexScaledN, indIndexScaledI2LN, indIndexI2LN, indIndexN, indOffIN, indOffLN, indirectX2P, indOffX2P); -opclass memory_noindex(indirect, - indOffI1, indOffL1,indOffI2, indOffL2, indOffI4, indOffL4, indOffI8, indOffL8, - indirectN, indOffIN, indOffLN, indirectX2P, indOffX2P); - // iRegIorL2I is used for src inputs in rules for 32 bit int (I) // operations. it allows the src to be either an iRegI or a (ConvL2I // iRegL). in the latter case the l2i normally planted for a ConvL2I @@ -6695,16 +6691,21 @@ instruct loadNKlass(iRegNNoSp dst, memory4 mem) ins_pipe(iload_reg_mem); %} -instruct loadNKlassCompactHeaders(iRegNNoSp dst, memory_noindex mem) +instruct loadNKlassCompactHeaders(iRegNNoSp dst, memory4 mem) %{ match(Set dst (LoadNKlass mem)); predicate(!needs_acquiring_load(n) && UseCompactObjectHeaders); ins_cost(4 * INSN_COST); - format %{ "load_narrow_klass_compact $dst, $mem\t# compressed class ptr" %} + format %{ + "ldrw $dst, $mem\t# compressed class ptr, shifted\n\t" + "lsrw $dst, $dst, markWord::klass_shift_at_offset" + %} ins_encode %{ - assert($mem$$index$$Register == noreg, "must not have indexed address"); - __ load_narrow_klass_compact_c2($dst$$Register, $mem$$base$$Register, $mem$$disp); + // inlined aarch64_enc_ldrw + loadStore(masm, &MacroAssembler::ldrw, $dst$$Register, $mem->opcode(), + as_Register($mem$$base), $mem$$index, $mem$$scale, $mem$$disp, 4); + __ lsrw($dst$$Register, $dst$$Register, markWord::klass_shift_at_offset); %} ins_pipe(iload_reg_mem); %} diff --git a/src/hotspot/cpu/aarch64/c2_MacroAssembler_aarch64.cpp b/src/hotspot/cpu/aarch64/c2_MacroAssembler_aarch64.cpp index 4c22133c056..3b0c8ae432c 100644 --- a/src/hotspot/cpu/aarch64/c2_MacroAssembler_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/c2_MacroAssembler_aarch64.cpp @@ -2690,12 +2690,3 @@ bool C2_MacroAssembler::in_scratch_emit_size() { } return MacroAssembler::in_scratch_emit_size(); } - -void C2_MacroAssembler::load_narrow_klass_compact_c2(Register dst, Register obj, int disp) { - // Note: Don't clobber obj anywhere in that method! - - // The incoming address is pointing into obj-start + klass_offset_in_bytes. We need to extract - // obj-start, so that we can load from the object's mark-word instead. - ldr(dst, Address(obj, disp - oopDesc::klass_offset_in_bytes())); - lsr(dst, dst, markWord::klass_shift); -} diff --git a/src/hotspot/cpu/aarch64/c2_MacroAssembler_aarch64.hpp b/src/hotspot/cpu/aarch64/c2_MacroAssembler_aarch64.hpp index c6ddcf46cba..d61b050407d 100644 --- a/src/hotspot/cpu/aarch64/c2_MacroAssembler_aarch64.hpp +++ b/src/hotspot/cpu/aarch64/c2_MacroAssembler_aarch64.hpp @@ -186,6 +186,4 @@ void vector_signum_sve(FloatRegister dst, FloatRegister src, FloatRegister zero, FloatRegister one, FloatRegister vtmp, PRegister pgtmp, SIMD_RegVariant T); - void load_narrow_klass_compact_c2(Register dst, Register obj, int disp); - #endif // CPU_AARCH64_C2_MACROASSEMBLER_AARCH64_HPP diff --git a/src/hotspot/cpu/x86/c2_MacroAssembler_x86.cpp b/src/hotspot/cpu/x86/c2_MacroAssembler_x86.cpp index 06d93ddea26..8d0af29e91d 100644 --- a/src/hotspot/cpu/x86/c2_MacroAssembler_x86.cpp +++ b/src/hotspot/cpu/x86/c2_MacroAssembler_x86.cpp @@ -7073,13 +7073,3 @@ void C2_MacroAssembler::vector_saturating_op(int ideal_opc, BasicType elem_bt, X vector_saturating_op(ideal_opc, elem_bt, dst, src1, src2, vlen_enc); } } - -#ifdef _LP64 -void C2_MacroAssembler::load_narrow_klass_compact_c2(Register dst, Address src) { - // The incoming address is pointing into obj-start + klass_offset_in_bytes. We need to extract - // obj-start, so that we can load from the object's mark-word instead. Usually the address - // comes as obj-start in obj and klass_offset_in_bytes in disp. - movq(dst, src.plus_disp(-oopDesc::klass_offset_in_bytes())); - shrq(dst, markWord::klass_shift); -} -#endif diff --git a/src/hotspot/cpu/x86/c2_MacroAssembler_x86.hpp b/src/hotspot/cpu/x86/c2_MacroAssembler_x86.hpp index 523200486cc..3a36fd75e3f 100644 --- a/src/hotspot/cpu/x86/c2_MacroAssembler_x86.hpp +++ b/src/hotspot/cpu/x86/c2_MacroAssembler_x86.hpp @@ -583,8 +583,4 @@ void select_from_two_vectors_evex(BasicType elem_bt, XMMRegister dst, XMMRegister src1, XMMRegister src2, int vlen_enc); -#ifdef _LP64 - void load_narrow_klass_compact_c2(Register dst, Address src); -#endif - #endif // CPU_X86_C2_MACROASSEMBLER_X86_HPP diff --git a/src/hotspot/cpu/x86/x86_64.ad b/src/hotspot/cpu/x86/x86_64.ad index fc083ecfa24..550c8047034 100644 --- a/src/hotspot/cpu/x86/x86_64.ad +++ b/src/hotspot/cpu/x86/x86_64.ad @@ -4368,11 +4368,15 @@ instruct loadNKlassCompactHeaders(rRegN dst, memory mem, rFlagsReg cr) match(Set dst (LoadNKlass mem)); effect(KILL cr); ins_cost(125); // XXX - format %{ "load_narrow_klass_compact $dst, $mem\t# compressed klass ptr" %} + format %{ + "movl $dst, $mem\t# compressed klass ptr, shifted\n\t" + "shrl $dst, markWord::klass_shift_at_offset" + %} ins_encode %{ - __ load_narrow_klass_compact_c2($dst$$Register, $mem$$Address); + __ movl($dst$$Register, $mem$$Address); + __ shrl($dst$$Register, markWord::klass_shift_at_offset); %} - ins_pipe(pipe_slow); // XXX + ins_pipe(ialu_reg_mem); // XXX %} // Load Float diff --git a/src/hotspot/share/oops/markWord.hpp b/src/hotspot/share/oops/markWord.hpp index 7d2bff1efc0..1e1b8d77a90 100644 --- a/src/hotspot/share/oops/markWord.hpp +++ b/src/hotspot/share/oops/markWord.hpp @@ -133,7 +133,9 @@ class markWord { // We store the (narrow) Klass* in the bits 43 to 64. // These are for bit-precise extraction of the narrow Klass* from the 64-bit Markword + static constexpr int klass_offset_in_bytes = 4; static constexpr int klass_shift = hash_shift + hash_bits; + static constexpr int klass_shift_at_offset = klass_shift - klass_offset_in_bytes * BitsPerByte; static constexpr int klass_bits = 22; static constexpr uintptr_t klass_mask = right_n_bits(klass_bits); static constexpr uintptr_t klass_mask_in_place = klass_mask << klass_shift; diff --git a/src/hotspot/share/oops/oop.hpp b/src/hotspot/share/oops/oop.hpp index dcf42c7343b..18e421d620c 100644 --- a/src/hotspot/share/oops/oop.hpp +++ b/src/hotspot/share/oops/oop.hpp @@ -332,12 +332,8 @@ class oopDesc { #ifdef _LP64 if (UseCompactObjectHeaders) { // NOTE: The only places where this is used with compact headers are the C2 - // compiler and JVMCI, and even there we don't use it to access the (narrow)Klass* - // directly. It is used only as a placeholder to identify the special memory slice - // containing Klass* info. This value could be any value that is not a valid - // field offset. Use an offset halfway into the markWord, as the markWord is never - // partially loaded from C2 and JVMCI. - return mark_offset_in_bytes() + 4; + // compiler and JVMCI. + return mark_offset_in_bytes() + markWord::klass_offset_in_bytes; } else #endif { diff --git a/src/hotspot/share/opto/memnode.hpp b/src/hotspot/share/opto/memnode.hpp index 1ca3a4b16ce..83ac80c043f 100644 --- a/src/hotspot/share/opto/memnode.hpp +++ b/src/hotspot/share/opto/memnode.hpp @@ -541,6 +541,12 @@ class LoadKlassNode : public LoadPNode { //------------------------------LoadNKlassNode--------------------------------- // Load a narrow Klass from an object. +// With compact headers, the input address (adr) does not point at the exact +// header position where the (narrow) class pointer is located, but into the +// middle of the mark word (see oopDesc::klass_offset_in_bytes()). This node +// implicitly shifts the loaded value (markWord::klass_shift_at_offset bits) to +// extract the actual class pointer. C2's type system is agnostic on whether the +// input address directly points into the class pointer. class LoadNKlassNode : public LoadNNode { public: LoadNKlassNode(Node *c, Node *mem, Node *adr, const TypePtr *at, const TypeNarrowKlass *tk, MemOrd mo) From fc8fb34f3dcef2435bb35d54b3eb77cad4945dd3 Mon Sep 17 00:00:00 2001 From: Sean Mullan Date: Fri, 15 Nov 2024 19:02:13 +0000 Subject: [PATCH 023/311] 8344214: Remove Security Manager dependencies from jdk.crypto.mscapi module Reviewed-by: rriggs, ascarpino --- .../sun/security/mscapi/CKeyStore.java | 23 +- .../sun/security/mscapi/SunMSCAPI.java | 224 +++++++++--------- 2 files changed, 110 insertions(+), 137 deletions(-) diff --git a/src/jdk.crypto.mscapi/windows/classes/sun/security/mscapi/CKeyStore.java b/src/jdk.crypto.mscapi/windows/classes/sun/security/mscapi/CKeyStore.java index 4e352bf4950..41580151f2b 100644 --- a/src/jdk.crypto.mscapi/windows/classes/sun/security/mscapi/CKeyStore.java +++ b/src/jdk.crypto.mscapi/windows/classes/sun/security/mscapi/CKeyStore.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -29,15 +29,12 @@ import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; -import java.security.AccessController; import java.security.InvalidKeyException; import java.security.Key; import java.security.KeyStoreSpi; import java.security.KeyStoreException; -import java.security.PrivilegedAction; import java.security.UnrecoverableKeyException; import java.security.NoSuchAlgorithmException; -import java.security.SecurityPermission; import java.security.cert.X509Certificate; import java.security.cert.Certificate; import java.security.cert.CertificateException; @@ -242,9 +239,7 @@ public void delete() throws KeyStoreException { CKeyStore(String storeName, int storeLocation) { // Get the compatibility mode - @SuppressWarnings("removal") - String prop = AccessController.doPrivileged( - (PrivilegedAction) () -> System.getProperty(KEYSTORE_COMPATIBILITY_MODE_PROP)); + String prop = System.getProperty(KEYSTORE_COMPATIBILITY_MODE_PROP); if ("false".equalsIgnoreCase(prop)) { keyStoreCompatibilityMode = false; @@ -695,10 +690,6 @@ public void engineStore(OutputStream stream, char[] password) * the integrity of the keystore cannot be found * @exception CertificateException if any of the certificates in the * keystore could not be loaded - * @exception SecurityException if the security check for - * SecurityPermission("authProvider.name") does not - * pass, where name is the value returned by - * this provider's getName method. */ public void engineLoad(InputStream stream, char[] password) throws IOException, NoSuchAlgorithmException, CertificateException { @@ -710,16 +701,6 @@ public void engineLoad(InputStream stream, char[] password) throw new IOException("Keystore password must be null"); } - /* - * Use the same security check as AuthProvider.login - */ - @SuppressWarnings("removal") - SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - sm.checkPermission(new SecurityPermission( - "authProvider.SunMSCAPI")); - } - // Clear all key entries entries.clear(); diff --git a/src/jdk.crypto.mscapi/windows/classes/sun/security/mscapi/SunMSCAPI.java b/src/jdk.crypto.mscapi/windows/classes/sun/security/mscapi/SunMSCAPI.java index e57fe331f28..8ee16cf6bb8 100644 --- a/src/jdk.crypto.mscapi/windows/classes/sun/security/mscapi/SunMSCAPI.java +++ b/src/jdk.crypto.mscapi/windows/classes/sun/security/mscapi/SunMSCAPI.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,8 +25,6 @@ package sun.security.mscapi; -import java.security.AccessController; -import java.security.PrivilegedAction; import java.security.Provider; import java.security.NoSuchAlgorithmException; import java.security.InvalidParameterException; @@ -50,14 +48,14 @@ public final class SunMSCAPI extends Provider { private static final String INFO = "Sun's Microsoft Crypto API provider"; static { - @SuppressWarnings({"removal", "restricted"}) - var dummy = AccessController.doPrivileged(new PrivilegedAction() { - public Void run() { - System.loadLibrary("sunmscapi"); - return null; - } - }); + loadLibrary(); + } + + @SuppressWarnings("restricted") + private static void loadLibrary() { + System.loadLibrary("sunmscapi"); } + private static class ProviderServiceA extends ProviderService { ProviderServiceA(Provider p, String type, String algo, String cn, HashMap attrs) { @@ -148,119 +146,113 @@ public Object newInstance(Object ctrParamObj) } } - @SuppressWarnings("removal") public SunMSCAPI() { super("SunMSCAPI", PROVIDER_VER, INFO); final Provider p = this; - AccessController.doPrivileged(new PrivilegedAction() { - public Void run() { - /* - * Secure random - */ - HashMap srattrs = new HashMap<>(1); - srattrs.put("ThreadSafe", "true"); - putService(new ProviderService(p, "SecureRandom", - "Windows-PRNG", "sun.security.mscapi.PRNG", - null, srattrs)); + /* + * Secure random + */ + HashMap srattrs = new HashMap<>(1); + srattrs.put("ThreadSafe", "true"); + putService(new ProviderService(p, "SecureRandom", + "Windows-PRNG", "sun.security.mscapi.PRNG", + null, srattrs)); - /* - * Key store - */ - putService(new ProviderService(p, "KeyStore", - "Windows-MY", "sun.security.mscapi.CKeyStore$MY")); - putService(new ProviderService(p, "KeyStore", - "Windows-MY-CURRENTUSER", "sun.security.mscapi.CKeyStore$MY")); - putService(new ProviderService(p, "KeyStore", - "Windows-ROOT", "sun.security.mscapi.CKeyStore$ROOT")); - putService(new ProviderService(p, "KeyStore", - "Windows-ROOT-CURRENTUSER", "sun.security.mscapi.CKeyStore$ROOT")); - putService(new ProviderService(p, "KeyStore", - "Windows-MY-LOCALMACHINE", "sun.security.mscapi.CKeyStore$MYLocalMachine")); - putService(new ProviderService(p, "KeyStore", - "Windows-ROOT-LOCALMACHINE", "sun.security.mscapi.CKeyStore$ROOTLocalMachine")); + /* + * Key store + */ + putService(new ProviderService(p, "KeyStore", + "Windows-MY", "sun.security.mscapi.CKeyStore$MY")); + putService(new ProviderService(p, "KeyStore", + "Windows-MY-CURRENTUSER", "sun.security.mscapi.CKeyStore$MY")); + putService(new ProviderService(p, "KeyStore", + "Windows-ROOT", "sun.security.mscapi.CKeyStore$ROOT")); + putService(new ProviderService(p, "KeyStore", + "Windows-ROOT-CURRENTUSER", "sun.security.mscapi.CKeyStore$ROOT")); + putService(new ProviderService(p, "KeyStore", + "Windows-MY-LOCALMACHINE", "sun.security.mscapi.CKeyStore$MYLocalMachine")); + putService(new ProviderService(p, "KeyStore", + "Windows-ROOT-LOCALMACHINE", "sun.security.mscapi.CKeyStore$ROOTLocalMachine")); - /* - * Signature engines - */ - HashMap attrs = new HashMap<>(1); - attrs.put("SupportedKeyClasses", "sun.security.mscapi.CKey"); + /* + * Signature engines + */ + HashMap attrs = new HashMap<>(1); + attrs.put("SupportedKeyClasses", "sun.security.mscapi.CKey"); - // NONEwithRSA must be supplied with a pre-computed message digest. - // Only the following digest algorithms are supported: MD5, SHA-1, - // SHA-256, SHA-384, SHA-512 and a special-purpose digest - // algorithm which is a concatenation of SHA-1 and MD5 digests. - putService(new ProviderService(p, "Signature", - "NONEwithRSA", "sun.security.mscapi.CSignature$NONEwithRSA", - null, attrs)); - putService(new ProviderService(p, "Signature", - "SHA1withRSA", "sun.security.mscapi.CSignature$SHA1withRSA", - null, attrs)); - putService(new ProviderServiceA(p, "Signature", - "SHA256withRSA", - "sun.security.mscapi.CSignature$SHA256withRSA", - attrs)); - putService(new ProviderServiceA(p, "Signature", - "SHA384withRSA", - "sun.security.mscapi.CSignature$SHA384withRSA", - attrs)); - putService(new ProviderServiceA(p, "Signature", - "SHA512withRSA", - "sun.security.mscapi.CSignature$SHA512withRSA", - attrs)); - putService(new ProviderServiceA(p, "Signature", - "RSASSA-PSS", "sun.security.mscapi.CSignature$PSS", - attrs)); - putService(new ProviderService(p, "Signature", - "MD5withRSA", "sun.security.mscapi.CSignature$MD5withRSA", - null, attrs)); - putService(new ProviderService(p, "Signature", - "MD2withRSA", "sun.security.mscapi.CSignature$MD2withRSA", - null, attrs)); - putService(new ProviderServiceA(p, "Signature", - "SHA1withECDSA", - "sun.security.mscapi.CSignature$SHA1withECDSA", - attrs)); - putService(new ProviderServiceA(p, "Signature", - "SHA224withECDSA", - "sun.security.mscapi.CSignature$SHA224withECDSA", - attrs)); - putService(new ProviderServiceA(p, "Signature", - "SHA256withECDSA", - "sun.security.mscapi.CSignature$SHA256withECDSA", - attrs)); - putService(new ProviderServiceA(p, "Signature", - "SHA384withECDSA", - "sun.security.mscapi.CSignature$SHA384withECDSA", - attrs)); - putService(new ProviderServiceA(p, "Signature", - "SHA512withECDSA", - "sun.security.mscapi.CSignature$SHA512withECDSA", - attrs)); - /* - * Key Pair Generator engines - */ - attrs.clear(); - attrs.put("KeySize", "16384"); - putService(new ProviderService(p, "KeyPairGenerator", - "RSA", "sun.security.mscapi.CKeyPairGenerator$RSA", - null, attrs)); + // NONEwithRSA must be supplied with a pre-computed message digest. + // Only the following digest algorithms are supported: MD5, SHA-1, + // SHA-256, SHA-384, SHA-512 and a special-purpose digest + // algorithm which is a concatenation of SHA-1 and MD5 digests. + putService(new ProviderService(p, "Signature", + "NONEwithRSA", "sun.security.mscapi.CSignature$NONEwithRSA", + null, attrs)); + putService(new ProviderService(p, "Signature", + "SHA1withRSA", "sun.security.mscapi.CSignature$SHA1withRSA", + null, attrs)); + putService(new ProviderServiceA(p, "Signature", + "SHA256withRSA", + "sun.security.mscapi.CSignature$SHA256withRSA", + attrs)); + putService(new ProviderServiceA(p, "Signature", + "SHA384withRSA", + "sun.security.mscapi.CSignature$SHA384withRSA", + attrs)); + putService(new ProviderServiceA(p, "Signature", + "SHA512withRSA", + "sun.security.mscapi.CSignature$SHA512withRSA", + attrs)); + putService(new ProviderServiceA(p, "Signature", + "RSASSA-PSS", "sun.security.mscapi.CSignature$PSS", + attrs)); + putService(new ProviderService(p, "Signature", + "MD5withRSA", "sun.security.mscapi.CSignature$MD5withRSA", + null, attrs)); + putService(new ProviderService(p, "Signature", + "MD2withRSA", "sun.security.mscapi.CSignature$MD2withRSA", + null, attrs)); + putService(new ProviderServiceA(p, "Signature", + "SHA1withECDSA", + "sun.security.mscapi.CSignature$SHA1withECDSA", + attrs)); + putService(new ProviderServiceA(p, "Signature", + "SHA224withECDSA", + "sun.security.mscapi.CSignature$SHA224withECDSA", + attrs)); + putService(new ProviderServiceA(p, "Signature", + "SHA256withECDSA", + "sun.security.mscapi.CSignature$SHA256withECDSA", + attrs)); + putService(new ProviderServiceA(p, "Signature", + "SHA384withECDSA", + "sun.security.mscapi.CSignature$SHA384withECDSA", + attrs)); + putService(new ProviderServiceA(p, "Signature", + "SHA512withECDSA", + "sun.security.mscapi.CSignature$SHA512withECDSA", + attrs)); + /* + * Key Pair Generator engines + */ + attrs.clear(); + attrs.put("KeySize", "16384"); + putService(new ProviderService(p, "KeyPairGenerator", + "RSA", "sun.security.mscapi.CKeyPairGenerator$RSA", + null, attrs)); - /* - * Cipher engines - */ - attrs.clear(); - attrs.put("SupportedModes", "ECB"); - attrs.put("SupportedPaddings", "PKCS1PADDING"); - attrs.put("SupportedKeyClasses", "sun.security.mscapi.CKey"); - putService(new ProviderService(p, "Cipher", - "RSA", "sun.security.mscapi.CRSACipher", - null, attrs)); - putService(new ProviderService(p, "Cipher", - "RSA/ECB/PKCS1Padding", "sun.security.mscapi.CRSACipher", - null, attrs)); - return null; - } - }); + /* + * Cipher engines + */ + attrs.clear(); + attrs.put("SupportedModes", "ECB"); + attrs.put("SupportedPaddings", "PKCS1PADDING"); + attrs.put("SupportedKeyClasses", "sun.security.mscapi.CKey"); + putService(new ProviderService(p, "Cipher", + "RSA", "sun.security.mscapi.CRSACipher", + null, attrs)); + putService(new ProviderService(p, "Cipher", + "RSA/ECB/PKCS1Padding", "sun.security.mscapi.CRSACipher", + null, attrs)); } } From 1bb0d3baaa3e6b0bf81445f818e74a41394df22b Mon Sep 17 00:00:00 2001 From: Phil Race Date: Fri, 15 Nov 2024 19:02:29 +0000 Subject: [PATCH 024/311] 8344062: Remove doPrivileged calls from awt and beans classes in the java.desktop module Reviewed-by: serb --- .../share/classes/java/awt/Component.java | 27 +---- .../share/classes/java/awt/Container.java | 41 ++------ .../share/classes/java/awt/Cursor.java | 19 +--- .../java/awt/DefaultKeyboardFocusManager.java | 13 +-- .../share/classes/java/awt/Desktop.java | 8 +- .../share/classes/java/awt/Dialog.java | 6 +- .../share/classes/java/awt/EventQueue.java | 99 ++++--------------- .../share/classes/java/awt/Font.java | 29 +----- .../classes/java/awt/GraphicsEnvironment.java | 20 ++-- .../java/awt/KeyboardFocusManager.java | 19 +--- .../classes/java/awt/SequencedEvent.java | 10 +- .../share/classes/java/awt/SplashScreen.java | 8 +- .../share/classes/java/awt/Toolkit.java | 61 ++++-------- .../classes/java/awt/WaitDispatchSupport.java | 11 +-- .../share/classes/java/awt/Window.java | 29 +----- .../classes/java/awt/color/ICC_Profile.java | 9 +- .../classes/java/awt/dnd/DragSource.java | 5 +- .../java/awt/event/NativeLibLoader.java | 10 +- .../classes/java/awt/image/BufferedImage.java | 20 +--- .../classes/java/awt/image/ColorModel.java | 10 +- .../classes/java/beans/EventHandler.java | 27 +---- .../share/classes/java/beans/MetaData.java | 29 ++---- .../classes/java/beans/SimpleBeanInfo.java | 6 +- .../share/classes/java/beans/Statement.java | 27 ----- .../share/classes/java/beans/XMLDecoder.java | 16 +-- 25 files changed, 97 insertions(+), 462 deletions(-) diff --git a/src/java.desktop/share/classes/java/awt/Component.java b/src/java.desktop/share/classes/java/awt/Component.java index ad0b87fd3fc..a1f8461c802 100644 --- a/src/java.desktop/share/classes/java/awt/Component.java +++ b/src/java.desktop/share/classes/java/awt/Component.java @@ -627,14 +627,10 @@ static class AWTTreeLock {} initIDs(); } - @SuppressWarnings("removal") - String s = java.security.AccessController.doPrivileged( - new GetPropertyAction("awt.image.incrementaldraw")); + String s = System.getProperty("awt.image.incrementaldraw"); isInc = (s == null || s.equals("true")); - @SuppressWarnings("removal") - String s2 = java.security.AccessController.doPrivileged( - new GetPropertyAction("awt.image.redrawrate")); + String s2 = System.getProperty("awt.image.redrawrate"); incRate = (s2 != null) ? Integer.parseInt(s2) : 100; } @@ -1431,15 +1427,7 @@ public Point getMousePosition() throws HeadlessException { throw new HeadlessException(); } - @SuppressWarnings("removal") - PointerInfo pi = java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction() { - public PointerInfo run() { - return MouseInfo.getPointerInfo(); - } - } - ); - + PointerInfo pi = MouseInfo.getPointerInfo(); synchronized (getTreeLock()) { Component inTheSameWindow = findUnderMouseInWindow(pi); if (!isSameOrAncestorOf(inTheSameWindow, true)) { @@ -6253,14 +6241,7 @@ private boolean checkCoalescing() { } // Need to check non-bootstraps. - @SuppressWarnings("removal") - Boolean enabled = java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction() { - public Boolean run() { - return isCoalesceEventsOverriden(clazz); - } - } - ); + Boolean enabled = isCoalesceEventsOverriden(clazz); coalesceMap.put(clazz, enabled); return enabled; } diff --git a/src/java.desktop/share/classes/java/awt/Container.java b/src/java.desktop/share/classes/java/awt/Container.java index c8289aa7fcc..2eb2c923de0 100644 --- a/src/java.desktop/share/classes/java/awt/Container.java +++ b/src/java.desktop/share/classes/java/awt/Container.java @@ -1576,10 +1576,8 @@ public boolean isValidateRoot() { } // Don't lazy-read because every app uses invalidate() - @SuppressWarnings("removal") - private static final boolean isJavaAwtSmartInvalidate - = AccessController.doPrivileged( - new GetBooleanAction("java.awt.smartInvalidate")); + private static final boolean isJavaAwtSmartInvalidate = + Boolean.getBoolean("java.awt.smartInvalidate"); /** * Invalidates the parent of the container unless the container @@ -2632,14 +2630,7 @@ public Point getMousePosition(boolean allowChildren) throws HeadlessException { if (GraphicsEnvironment.isHeadless()) { throw new HeadlessException(); } - @SuppressWarnings("removal") - PointerInfo pi = java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction() { - public PointerInfo run() { - return MouseInfo.getPointerInfo(); - } - } - ); + PointerInfo pi = MouseInfo.getPointerInfo(); synchronized (getTreeLock()) { Component inTheSameWindow = findUnderMouseInWindow(pi); if (isSameOrAncestorOf(inTheSameWindow, allowChildren)) { @@ -4738,33 +4729,17 @@ private Component retargetMouseEnterExit(Component targetOver, MouseEvent e, * from other heavyweight containers will generate enter/exit * events in this container */ - @SuppressWarnings("removal") private void startListeningForOtherDrags() { //System.out.println("Adding AWTEventListener"); - java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction() { - public Object run() { - nativeContainer.getToolkit().addAWTEventListener( - LightweightDispatcher.this, - AWTEvent.MOUSE_EVENT_MASK | - AWTEvent.MOUSE_MOTION_EVENT_MASK); - return null; - } - } - ); + nativeContainer.getToolkit().addAWTEventListener( + LightweightDispatcher.this, + AWTEvent.MOUSE_EVENT_MASK | + AWTEvent.MOUSE_MOTION_EVENT_MASK); } - @SuppressWarnings("removal") private void stopListeningForOtherDrags() { //System.out.println("Removing AWTEventListener"); - java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction() { - public Object run() { - nativeContainer.getToolkit().removeAWTEventListener(LightweightDispatcher.this); - return null; - } - } - ); + nativeContainer.getToolkit().removeAWTEventListener(LightweightDispatcher.this); } /* diff --git a/src/java.desktop/share/classes/java/awt/Cursor.java b/src/java.desktop/share/classes/java/awt/Cursor.java index cfccf06723b..8a595f61285 100644 --- a/src/java.desktop/share/classes/java/awt/Cursor.java +++ b/src/java.desktop/share/classes/java/awt/Cursor.java @@ -29,8 +29,6 @@ import java.io.InputStream; import java.io.Serial; import java.security.AccessController; -import java.security.PrivilegedAction; -import java.security.PrivilegedExceptionAction; import java.util.Hashtable; import java.util.Properties; import java.util.StringTokenizer; @@ -332,11 +330,7 @@ public static Cursor getSystemCustomCursor(final String name) } final Toolkit toolkit = Toolkit.getDefaultToolkit(); final String file = RESOURCE_PREFIX + fileName; - @SuppressWarnings("removal") - final InputStream in = AccessController.doPrivileged( - (PrivilegedAction) () -> { - return Cursor.class.getResourceAsStream(file); - }); + final InputStream in = Cursor.class.getResourceAsStream(file); try (in) { Image image = toolkit.createImage(in.readAllBytes()); cursor = toolkit.createCustomCursor(image, hotPoint, localized); @@ -428,7 +422,6 @@ public String toString() { /* * load the cursor.properties file */ - @SuppressWarnings("removal") private static void loadSystemCustomCursorProperties() throws AWTException { synchronized (systemCustomCursors) { if (systemCustomCursorProperties != null) { @@ -437,14 +430,8 @@ private static void loadSystemCustomCursorProperties() throws AWTException { systemCustomCursorProperties = new Properties(); try { - AccessController.doPrivileged( - (PrivilegedExceptionAction) () -> { - try (InputStream is = Cursor.class - .getResourceAsStream(PROPERTIES_FILE)) { - systemCustomCursorProperties.load(is); - } - return null; - }); + InputStream is = Cursor.class.getResourceAsStream(PROPERTIES_FILE); + systemCustomCursorProperties.load(is); } catch (Exception e) { systemCustomCursorProperties = null; throw new AWTException("Exception: " + e.getClass() + " " + diff --git a/src/java.desktop/share/classes/java/awt/DefaultKeyboardFocusManager.java b/src/java.desktop/share/classes/java/awt/DefaultKeyboardFocusManager.java index e416e791e8d..3c57ec3a8d9 100644 --- a/src/java.desktop/share/classes/java/awt/DefaultKeyboardFocusManager.java +++ b/src/java.desktop/share/classes/java/awt/DefaultKeyboardFocusManager.java @@ -32,8 +32,6 @@ import java.awt.peer.LightweightPeer; import java.io.Serial; import java.lang.ref.WeakReference; -import java.security.AccessController; -import java.security.PrivilegedAction; import java.util.Iterator; import java.util.LinkedList; import java.util.ListIterator; @@ -86,21 +84,14 @@ public class DefaultKeyboardFocusManager extends KeyboardFocusManager { initStatic(); } - @SuppressWarnings("removal") private static void initStatic() { AWTAccessor.setDefaultKeyboardFocusManagerAccessor( new AWTAccessor.DefaultKeyboardFocusManagerAccessor() { public void consumeNextKeyTyped(DefaultKeyboardFocusManager dkfm, KeyEvent e) { dkfm.consumeNextKeyTyped(e); - } + } }); - AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { - fxAppThreadIsDispatchThread = - "true".equals(System.getProperty("javafx.embed.singleThread")); - return null; - } - }); + fxAppThreadIsDispatchThread = "true".equals(System.getProperty("javafx.embed.singleThread")); } /** diff --git a/src/java.desktop/share/classes/java/awt/Desktop.java b/src/java.desktop/share/classes/java/awt/Desktop.java index 025889755b8..89a78518873 100644 --- a/src/java.desktop/share/classes/java/awt/Desktop.java +++ b/src/java.desktop/share/classes/java/awt/Desktop.java @@ -42,8 +42,6 @@ import java.io.IOException; import java.net.URI; import java.net.URISyntaxException; -import java.security.AccessController; -import java.security.PrivilegedAction; import java.util.Objects; import javax.swing.JMenuBar; @@ -936,11 +934,7 @@ public boolean moveToTrash(File file) { sm.checkDelete(file.getPath()); } checkActionSupport(Action.MOVE_TO_TRASH); - final File finalFile = file; - AccessController.doPrivileged((PrivilegedAction) () -> { - checkFileValidation(finalFile); - return null; - }); + checkFileValidation(file); return peer.moveToTrash(file); } } diff --git a/src/java.desktop/share/classes/java/awt/Dialog.java b/src/java.desktop/share/classes/java/awt/Dialog.java index a0d22fbb327..03449200478 100644 --- a/src/java.desktop/share/classes/java/awt/Dialog.java +++ b/src/java.desktop/share/classes/java/awt/Dialog.java @@ -34,8 +34,6 @@ import java.io.ObjectInputStream; import java.io.Serial; import java.security.AccessControlException; -import java.security.AccessController; -import java.security.PrivilegedAction; import java.util.Iterator; import java.util.concurrent.atomic.AtomicLong; @@ -1052,9 +1050,7 @@ public void show() { modalityPushed(); try { - @SuppressWarnings("removal") - final EventQueue eventQueue = AccessController.doPrivileged( - (PrivilegedAction) Toolkit.getDefaultToolkit()::getSystemEventQueue); + EventQueue eventQueue = Toolkit.getDefaultToolkit().getSystemEventQueue(); secondaryLoop = eventQueue.createSecondaryLoop(() -> true, modalFilter, 0); if (!secondaryLoop.enter()) { secondaryLoop = null; diff --git a/src/java.desktop/share/classes/java/awt/EventQueue.java b/src/java.desktop/share/classes/java/awt/EventQueue.java index 4dce257f727..57a9a6cf567 100644 --- a/src/java.desktop/share/classes/java/awt/EventQueue.java +++ b/src/java.desktop/share/classes/java/awt/EventQueue.java @@ -32,9 +32,6 @@ import java.lang.ref.WeakReference; import java.lang.reflect.InvocationTargetException; -import java.security.AccessController; -import java.security.PrivilegedAction; - import java.util.EmptyStackException; import sun.awt.*; @@ -45,11 +42,6 @@ import java.util.concurrent.locks.Lock; import java.util.concurrent.atomic.AtomicInteger; -import java.security.AccessControlContext; - -import jdk.internal.access.SharedSecrets; -import jdk.internal.access.JavaSecurityAccess; - /** * {@code EventQueue} is a platform-independent class * that queues events, both from the underlying peer classes @@ -229,13 +221,8 @@ public long getMostRecentEventTime(EventQueue eventQueue) { }); } - @SuppressWarnings("removal") private static boolean fxAppThreadIsDispatchThread = - AccessController.doPrivileged(new PrivilegedAction() { - public Boolean run() { - return "true".equals(System.getProperty("javafx.embed.singleThread")); - } - }); + "true".equals(System.getProperty("javafx.embed.singleThread")); /** * Initializes a new instance of {@code EventQueue}. @@ -668,9 +655,6 @@ public AWTEvent peekEvent(int id) { return null; } - private static final JavaSecurityAccess javaSecurityAccess = - SharedSecrets.getJavaSecurityAccess(); - /** * Dispatches an event. The manner in which the event is * dispatched depends upon the type of the event and the @@ -711,59 +695,25 @@ public AWTEvent peekEvent(int id) { */ protected void dispatchEvent(final AWTEvent event) { final Object src = event.getSource(); - final PrivilegedAction action = new PrivilegedAction() { - public Void run() { - // In case fwDispatcher is installed and we're already on the - // dispatch thread (e.g. performing DefaultKeyboardFocusManager.sendMessage), - // dispatch the event straight away. - if (fwDispatcher == null || isDispatchThreadImpl()) { - dispatchEventImpl(event, src); - } else { - fwDispatcher.scheduleDispatch(new Runnable() { - @Override - public void run() { - if (dispatchThread.filterAndCheckEvent(event)) { - dispatchEventImpl(event, src); - } - } - }); - } - return null; - } - }; - - @SuppressWarnings("removal") - final AccessControlContext stack = AccessController.getContext(); - @SuppressWarnings("removal") - final AccessControlContext srcAcc = getAccessControlContextFrom(src); - @SuppressWarnings("removal") - final AccessControlContext eventAcc = event.getAccessControlContext(); - if (srcAcc == null) { - javaSecurityAccess.doIntersectionPrivilege(action, stack, eventAcc); + // In case fwDispatcher is installed and we're already on the + // dispatch thread (e.g. performing DefaultKeyboardFocusManager.sendMessage), + // dispatch the event straight away. + if (fwDispatcher == null || isDispatchThreadImpl()) { + dispatchEventImpl(event, src); } else { - javaSecurityAccess.doIntersectionPrivilege( - new PrivilegedAction() { - public Void run() { - javaSecurityAccess.doIntersectionPrivilege(action, eventAcc); - return null; + fwDispatcher.scheduleDispatch(new Runnable() { + @Override + public void run() { + if (dispatchThread.filterAndCheckEvent(event)) { + dispatchEventImpl(event, src); } - }, stack, srcAcc); + } + }); } } - @SuppressWarnings("removal") - private static AccessControlContext getAccessControlContextFrom(Object src) { - return src instanceof Component ? - ((Component)src).getAccessControlContext() : - src instanceof MenuComponent ? - ((MenuComponent)src).getAccessControlContext() : - src instanceof TrayIcon ? - ((TrayIcon)src).getAccessControlContext() : - null; - } - /** - * Called from dispatchEvent() under a correct AccessControlContext + * Called from dispatchEvent() */ private void dispatchEventImpl(final AWTEvent event, final Object src) { event.isPosted = true; @@ -1113,21 +1063,12 @@ final void initDispatchThread() { pushPopLock.lock(); try { if (dispatchThread == null && !threadGroup.isDestroyed() && !appContext.isDisposed()) { - dispatchThread = AccessController.doPrivileged( - new PrivilegedAction() { - public EventDispatchThread run() { - EventDispatchThread t = - new EventDispatchThread(threadGroup, - name, - EventQueue.this); - t.setContextClassLoader(classLoader); - t.setPriority(Thread.NORM_PRIORITY + 1); - t.setDaemon(false); - AWTAutoShutdown.getInstance().notifyThreadBusy(t); - return t; - } - } - ); + EventDispatchThread t = new EventDispatchThread(threadGroup, name, EventQueue.this); + t.setContextClassLoader(classLoader); + t.setPriority(Thread.NORM_PRIORITY + 1); + t.setDaemon(false); + AWTAutoShutdown.getInstance().notifyThreadBusy(t); + dispatchThread = t; dispatchThread.start(); } } finally { diff --git a/src/java.desktop/share/classes/java/awt/Font.java b/src/java.desktop/share/classes/java/awt/Font.java index ff5c29a2758..3df4632f9d3 100644 --- a/src/java.desktop/share/classes/java/awt/Font.java +++ b/src/java.desktop/share/classes/java/awt/Font.java @@ -44,8 +44,6 @@ import java.io.Serial; import java.lang.ref.SoftReference; import java.nio.file.Files; -import java.security.AccessController; -import java.security.PrivilegedExceptionAction; import java.text.AttributedCharacterIterator.Attribute; import java.text.CharacterIterator; import java.util.EventListener; @@ -1095,7 +1093,6 @@ public static Font createFont(int fontFormat, InputStream fontStream) } } - @SuppressWarnings("removal") private static Font[] createFont0(int fontFormat, InputStream fontStream, boolean allFonts, CreatedFontTracker tracker) @@ -1107,27 +1104,14 @@ private static Font[] createFont0(int fontFormat, InputStream fontStream, } boolean copiedFontData = false; try { - final File tFile = AccessController.doPrivileged( - new PrivilegedExceptionAction() { - public File run() throws IOException { - return Files.createTempFile("+~JF", ".tmp").toFile(); - } - } - ); + final File tFile = Files.createTempFile("+~JF", ".tmp").toFile(); if (tracker != null) { tracker.add(tFile); } int totalSize = 0; try { - final OutputStream outStream = - AccessController.doPrivileged( - new PrivilegedExceptionAction() { - public OutputStream run() throws IOException { - return new FileOutputStream(tFile); - } - } - ); + final OutputStream outStream = new FileOutputStream(tFile); if (tracker != null) { tracker.set(tFile, outStream); } @@ -1181,14 +1165,7 @@ public OutputStream run() throws IOException { if (tracker != null) { tracker.subBytes(totalSize); } - AccessController.doPrivileged( - new PrivilegedExceptionAction() { - public Void run() { - tFile.delete(); - return null; - } - } - ); + tFile.delete(); } } } catch (Throwable t) { diff --git a/src/java.desktop/share/classes/java/awt/GraphicsEnvironment.java b/src/java.desktop/share/classes/java/awt/GraphicsEnvironment.java index 2e89aa6f672..4936d5d396d 100644 --- a/src/java.desktop/share/classes/java/awt/GraphicsEnvironment.java +++ b/src/java.desktop/share/classes/java/awt/GraphicsEnvironment.java @@ -26,8 +26,6 @@ package java.awt; import java.awt.image.BufferedImage; -import java.security.AccessController; -import java.security.PrivilegedAction; import java.util.Locale; import sun.awt.PlatformGraphicsInfo; @@ -137,20 +135,16 @@ static String getHeadlessMessage() { * @return the value of the property "java.awt.headless" * @since 1.4 */ - @SuppressWarnings("removal") private static boolean getHeadlessProperty() { if (headless == null) { - AccessController.doPrivileged((PrivilegedAction) () -> { - String nm = System.getProperty("java.awt.headless"); + String nm = System.getProperty("java.awt.headless"); - if (nm == null) { - headless = defaultHeadless = - PlatformGraphicsInfo.getDefaultHeadlessProperty(); - } else { - headless = Boolean.valueOf(nm); - } - return null; - }); + if (nm == null) { + headless = defaultHeadless = + PlatformGraphicsInfo.getDefaultHeadlessProperty(); + } else { + headless = Boolean.valueOf(nm); + } } return headless; } diff --git a/src/java.desktop/share/classes/java/awt/KeyboardFocusManager.java b/src/java.desktop/share/classes/java/awt/KeyboardFocusManager.java index 0ca86f3433b..eb623213a77 100644 --- a/src/java.desktop/share/classes/java/awt/KeyboardFocusManager.java +++ b/src/java.desktop/share/classes/java/awt/KeyboardFocusManager.java @@ -40,9 +40,6 @@ import java.lang.ref.WeakReference; -import java.security.AccessController; -import java.security.PrivilegedAction; - import java.util.Collections; import java.util.HashSet; import java.util.Iterator; @@ -601,14 +598,8 @@ private void _clearGlobalFocusOwner() { peer.clearGlobalFocusOwner(activeWindow); } - @SuppressWarnings("removal") void clearGlobalFocusOwnerPriv() { - AccessController.doPrivileged(new PrivilegedAction() { - public Void run() { - clearGlobalFocusOwner(); - return null; - } - }); + clearGlobalFocusOwner(); } Component getNativeFocusOwner() { @@ -1194,14 +1185,8 @@ public void setGlobalCurrentFocusCycleRoot(Container newFocusCycleRoot) { newFocusCycleRoot); } - @SuppressWarnings("removal") void setGlobalCurrentFocusCycleRootPriv(final Container newFocusCycleRoot) { - AccessController.doPrivileged(new PrivilegedAction() { - public Void run() { - setGlobalCurrentFocusCycleRoot(newFocusCycleRoot); - return null; - } - }); + setGlobalCurrentFocusCycleRoot(newFocusCycleRoot); } /** diff --git a/src/java.desktop/share/classes/java/awt/SequencedEvent.java b/src/java.desktop/share/classes/java/awt/SequencedEvent.java index 410437a5c9e..a671814a57b 100644 --- a/src/java.desktop/share/classes/java/awt/SequencedEvent.java +++ b/src/java.desktop/share/classes/java/awt/SequencedEvent.java @@ -26,8 +26,6 @@ package java.awt; import java.io.Serial; -import java.security.AccessController; -import java.security.PrivilegedAction; import java.util.LinkedList; import sun.awt.AWTAccessor; @@ -80,13 +78,7 @@ public AWTEvent create(AWTEvent event) { return new SequencedEvent(event); } }); - AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { - fxAppThreadIsDispatchThread = - "true".equals(System.getProperty("javafx.embed.singleThread")); - return null; - } - }); + fxAppThreadIsDispatchThread = "true".equals(System.getProperty("javafx.embed.singleThread")); } private static final class SequencedEventsFilter implements EventFilter { diff --git a/src/java.desktop/share/classes/java/awt/SplashScreen.java b/src/java.desktop/share/classes/java/awt/SplashScreen.java index 78ec4ed7aa0..7f522026b8a 100644 --- a/src/java.desktop/share/classes/java/awt/SplashScreen.java +++ b/src/java.desktop/share/classes/java/awt/SplashScreen.java @@ -129,13 +129,7 @@ public static SplashScreen getSplashScreen() { } // SplashScreen class is now a singleton if (!wasClosed && theInstance == null) { - java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction() { - public Void run() { - System.loadLibrary("splashscreen"); - return null; - } - }); + System.loadLibrary("splashscreen"); long ptr = _getInstance(); if (ptr != 0 && _isVisible(ptr)) { theInstance = new SplashScreen(ptr); diff --git a/src/java.desktop/share/classes/java/awt/Toolkit.java b/src/java.desktop/share/classes/java/awt/Toolkit.java index 19b0ab9019a..d181fb6f536 100644 --- a/src/java.desktop/share/classes/java/awt/Toolkit.java +++ b/src/java.desktop/share/classes/java/awt/Toolkit.java @@ -56,8 +56,6 @@ import java.io.File; import java.io.FileInputStream; import java.net.URL; -import java.security.AccessController; -import java.security.PrivilegedAction; import java.util.ArrayList; import java.util.Arrays; import java.util.EventListener; @@ -396,18 +394,12 @@ public abstract ColorModel getColorModel() * properties are set up properly before any classes dependent upon them * are initialized. */ - @SuppressWarnings("removal") private static void initAssistiveTechnologies() { // Get accessibility properties final String sep = File.separator; final Properties properties = new Properties(); - - atNames = java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction() { - public String run() { - // Try loading the per-user accessibility properties file. try { File propsFile = new File( @@ -459,9 +451,7 @@ public String run() { System.setProperty("javax.accessibility.assistive_technologies", classNames); } } - return classNames; - } - }); + atNames = classNames; } /** @@ -512,7 +502,6 @@ private static void fallbackToLoadClassForAT(String atName) { * {@code null} it is ignored. All other errors are handled via an AWTError * exception. */ - @SuppressWarnings("removal") private static void loadAssistiveTechnologies() { // Load any assistive technologies if (atNames != null && !atNames.isBlank()) { @@ -521,20 +510,17 @@ private static void loadAssistiveTechnologies() { .map(String::trim) .collect(Collectors.toSet()); final Map providers = new HashMap<>(); - AccessController.doPrivileged((PrivilegedAction) () -> { - try { - for (AccessibilityProvider p : ServiceLoader.load(AccessibilityProvider.class, cl)) { - String name = p.getName(); - if (names.contains(name) && !providers.containsKey(name)) { - p.activate(); - providers.put(name, p); - } + try { + for (AccessibilityProvider p : ServiceLoader.load(AccessibilityProvider.class, cl)) { + String name = p.getName(); + if (names.contains(name) && !providers.containsKey(name)) { + p.activate(); + providers.put(name, p); } - } catch (java.util.ServiceConfigurationError | Exception e) { - newAWTError(e, "Could not load or activate service provider"); } - return null; - }); + } catch (java.util.ServiceConfigurationError | Exception e) { + newAWTError(e, "Could not load or activate service provider"); + } names.stream() .filter(n -> !providers.containsKey(n)) .forEach(Toolkit::fallbackToLoadClassForAT); @@ -1302,16 +1288,10 @@ private static void setPlatformResources(ResourceBundle bundle) { * directly. -hung */ private static boolean loaded = false; - @SuppressWarnings({"removal", "restricted"}) + @SuppressWarnings("restricted") static void loadLibraries() { if (!loaded) { - java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction() { - public Void run() { - System.loadLibrary("awt"); - return null; - } - }); + System.loadLibrary("awt"); loaded = true; } } @@ -1320,7 +1300,6 @@ public Void run() { initStatic(); } - @SuppressWarnings("removal") private static void initStatic() { AWTAccessor.setToolkitAccessor( new AWTAccessor.ToolkitAccessor() { @@ -1330,17 +1309,11 @@ public void setPlatformResources(ResourceBundle bundle) { } }); - java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction() { - public Void run() { - try { - resources = ResourceBundle.getBundle("sun.awt.resources.awt"); - } catch (MissingResourceException e) { - // No resource file; defaults will be used. - } - return null; - } - }); + try { + resources = ResourceBundle.getBundle("sun.awt.resources.awt"); + } catch (MissingResourceException e) { + // No resource file; defaults will be used. + } // ensure that the proper libraries are loaded loadLibraries(); diff --git a/src/java.desktop/share/classes/java/awt/WaitDispatchSupport.java b/src/java.desktop/share/classes/java/awt/WaitDispatchSupport.java index d239a600697..2968c9ad3ef 100644 --- a/src/java.desktop/share/classes/java/awt/WaitDispatchSupport.java +++ b/src/java.desktop/share/classes/java/awt/WaitDispatchSupport.java @@ -29,9 +29,6 @@ import java.util.TimerTask; import java.util.concurrent.atomic.AtomicBoolean; -import java.security.PrivilegedAction; -import java.security.AccessController; - import sun.awt.PeerEvent; import sun.util.logging.PlatformLogger; @@ -230,13 +227,7 @@ public void run() { // The event will be handled after the new event pump // starts. Thus, the enter() method will not hang. // - // Event pump should be privileged. See 6300270. - AccessController.doPrivileged(new PrivilegedAction() { - public Void run() { - run.run(); - return null; - } - }); + run.run(); } else { if (log.isLoggable(PlatformLogger.Level.FINEST)) { log.finest("On non-dispatch thread: " + currentThread); diff --git a/src/java.desktop/share/classes/java/awt/Window.java b/src/java.desktop/share/classes/java/awt/Window.java index a1e9d48d9d4..1a5395431ab 100644 --- a/src/java.desktop/share/classes/java/awt/Window.java +++ b/src/java.desktop/share/classes/java/awt/Window.java @@ -48,7 +48,6 @@ import java.io.Serializable; import java.lang.ref.WeakReference; import java.lang.reflect.InvocationTargetException; -import java.security.AccessController; import java.util.ArrayList; import java.util.Arrays; import java.util.EventListener; @@ -414,13 +413,9 @@ public static enum Type { initIDs(); } - @SuppressWarnings("removal") - String s = java.security.AccessController.doPrivileged( - new GetPropertyAction("java.awt.syncLWRequests")); + String s = System.getProperty("java.awt.syncLWRequests"); systemSyncLWRequests = "true".equals(s); - @SuppressWarnings("removal") - String s2 = java.security.AccessController.doPrivileged( - new GetPropertyAction("java.awt.Window.locationByPlatform")); + String s2 = System.getProperty("java.awt.Window.locationByPlatform"); locationByPlatformProp = "true".equals(s2); } @@ -505,7 +500,6 @@ private void init(GraphicsConfiguration gc) { weakThis = new WeakReference(this); addToWindowList(); - setWarningString(); this.cursor = Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR); this.visible = false; @@ -1376,24 +1370,6 @@ public final String getWarningString() { return warningString; } - @SuppressWarnings("removal") - private void setWarningString() { - warningString = null; - SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - try { - sm.checkPermission(AWTPermissions.TOPLEVEL_WINDOW_PERMISSION); - } catch (SecurityException se) { - // make sure the privileged action is only - // for getting the property! We don't want the - // above checkPermission call to always succeed! - warningString = AccessController.doPrivileged( - new GetPropertyAction("awt.appletWarning", - "Java Applet Window")); - } - } - } - /** * Gets the {@code Locale} object that is associated * with this window, if the locale has been set. @@ -2978,7 +2954,6 @@ private void writeObject(ObjectOutputStream s) throws IOException { // user's code. // private void initDeserializedWindow() { - setWarningString(); inputContextLock = new Object(); // Deserialized Windows are not yet visible. diff --git a/src/java.desktop/share/classes/java/awt/color/ICC_Profile.java b/src/java.desktop/share/classes/java/awt/color/ICC_Profile.java index b4e71b3c839..729d8123a24 100644 --- a/src/java.desktop/share/classes/java/awt/color/ICC_Profile.java +++ b/src/java.desktop/share/classes/java/awt/color/ICC_Profile.java @@ -48,8 +48,6 @@ import java.io.OutputStream; import java.io.Serial; import java.io.Serializable; -import java.security.AccessController; -import java.security.PrivilegedAction; import java.util.Objects; import java.util.StringTokenizer; @@ -1341,13 +1339,8 @@ private static File getProfileFile(String fileName) { * fileName. If there is no built-in profile with such name, then the method * returns {@code null}. */ - @SuppressWarnings("removal") private static InputStream getStandardProfileInputStream(String fileName) { - return AccessController.doPrivileged( - (PrivilegedAction) () -> { - return PCMM.class.getResourceAsStream("profiles/" + fileName); - }, null, new FilePermission("<>", "read"), - new RuntimePermission("accessSystemModules")); + return PCMM.class.getResourceAsStream("profiles/" + fileName); } /** diff --git a/src/java.desktop/share/classes/java/awt/dnd/DragSource.java b/src/java.desktop/share/classes/java/awt/dnd/DragSource.java index 01945662e46..8477bc6376d 100644 --- a/src/java.desktop/share/classes/java/awt/dnd/DragSource.java +++ b/src/java.desktop/share/classes/java/awt/dnd/DragSource.java @@ -40,13 +40,11 @@ import java.io.ObjectOutputStream; import java.io.Serial; import java.io.Serializable; -import java.security.AccessController; import java.util.EventListener; import sun.awt.AWTAccessor; import sun.awt.AWTAccessor.DragSourceContextAccessor; import sun.awt.dnd.SunDragSourceContextPeer; -import sun.security.action.GetIntegerAction; /** * The {@code DragSource} is the entity responsible @@ -908,8 +906,7 @@ private void readObject(ObjectInputStream s) */ public static int getDragThreshold() { @SuppressWarnings("removal") - int ts = AccessController.doPrivileged( - new GetIntegerAction("awt.dnd.drag.threshold", 0)).intValue(); + int ts = Integer.getInteger("awt.dnd.drag.threshold", 0); if (ts > 0) { return ts; } else { diff --git a/src/java.desktop/share/classes/java/awt/event/NativeLibLoader.java b/src/java.desktop/share/classes/java/awt/event/NativeLibLoader.java index 27a2c439747..8b0d46d05e0 100644 --- a/src/java.desktop/share/classes/java/awt/event/NativeLibLoader.java +++ b/src/java.desktop/share/classes/java/awt/event/NativeLibLoader.java @@ -52,14 +52,8 @@ class NativeLibLoader { * For now, we know it's done by the implementation, and we assume * that the name of the library is "awt". -br. */ - @SuppressWarnings({"removal", "restricted"}) + @SuppressWarnings("restricted") static void loadLibraries() { - java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction() { - public Void run() { - System.loadLibrary("awt"); - return null; - } - }); + System.loadLibrary("awt"); } } diff --git a/src/java.desktop/share/classes/java/awt/image/BufferedImage.java b/src/java.desktop/share/classes/java/awt/image/BufferedImage.java index cfbebd68710..09c96a6560f 100644 --- a/src/java.desktop/share/classes/java/awt/image/BufferedImage.java +++ b/src/java.desktop/share/classes/java/awt/image/BufferedImage.java @@ -31,8 +31,6 @@ import java.awt.Rectangle; import java.awt.Transparency; import java.awt.color.ColorSpace; -import java.security.AccessController; -import java.security.PrivilegedAction; import java.util.Hashtable; import java.util.Set; import java.util.Vector; @@ -800,26 +798,16 @@ else if (offs[3] == 0 && ccm.hasAlpha()) { } // else if ((raster instanceof ByteComponentRaster) && } - @SuppressWarnings("removal") private static boolean isStandard(ColorModel cm, WritableRaster wr) { final Class cmClass = cm.getClass(); final Class wrClass = wr.getClass(); final Class smClass = wr.getSampleModel().getClass(); - final PrivilegedAction checkClassLoadersAction = - new PrivilegedAction() - { - - @Override - public Boolean run() { - final ClassLoader std = System.class.getClassLoader(); + final ClassLoader std = System.class.getClassLoader(); - return (cmClass.getClassLoader() == std) && - (smClass.getClassLoader() == std) && - (wrClass.getClassLoader() == std); - } - }; - return AccessController.doPrivileged(checkClassLoadersAction); + return (cmClass.getClassLoader() == std) && + (smClass.getClassLoader() == std) && + (wrClass.getClassLoader() == std); } /** diff --git a/src/java.desktop/share/classes/java/awt/image/ColorModel.java b/src/java.desktop/share/classes/java/awt/image/ColorModel.java index a0aa8fddc10..b2d568cb09f 100644 --- a/src/java.desktop/share/classes/java/awt/image/ColorModel.java +++ b/src/java.desktop/share/classes/java/awt/image/ColorModel.java @@ -202,16 +202,10 @@ public abstract class ColorModel implements Transparency{ * that the name of the library is "awt". -br. */ private static boolean loaded = false; - @SuppressWarnings({"removal", "restricted"}) + @SuppressWarnings("restricted") static void loadLibraries() { if (!loaded) { - java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction() { - public Void run() { - System.loadLibrary("awt"); - return null; - } - }); + System.loadLibrary("awt"); loaded = true; } } diff --git a/src/java.desktop/share/classes/java/beans/EventHandler.java b/src/java.desktop/share/classes/java/beans/EventHandler.java index b3c630ae5c9..eb892f34985 100644 --- a/src/java.desktop/share/classes/java/beans/EventHandler.java +++ b/src/java.desktop/share/classes/java/beans/EventHandler.java @@ -28,9 +28,6 @@ import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Proxy; import java.lang.reflect.Method; -import java.security.AccessControlContext; -import java.security.AccessController; -import java.security.PrivilegedAction; import sun.reflect.misc.MethodUtil; import sun.reflect.misc.ReflectUtil; @@ -281,8 +278,6 @@ public class EventHandler implements InvocationHandler { private String action; private final String eventPropertyName; private final String listenerMethodName; - @SuppressWarnings("removal") - private final AccessControlContext acc = AccessController.getContext(); /** * Creates a new {@code EventHandler} object; @@ -421,20 +416,7 @@ private Object applyGetters(Object target, String getters) { * * @see EventHandler */ - @SuppressWarnings("removal") public Object invoke(final Object proxy, final Method method, final Object[] arguments) { - AccessControlContext acc = this.acc; - if ((acc == null) && (System.getSecurityManager() != null)) { - throw new SecurityException("AccessControlContext is not set"); - } - return AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { - return invokeInternal(proxy, method, arguments); - } - }, acc); - } - - private Object invokeInternal(Object proxy, Method method, Object[] arguments) { String methodName = method.getName(); if (method.getDeclaringClass() == Object.class) { // Handle the Object public methods. @@ -689,7 +671,7 @@ public static T create(Class listenerInterface, * @see EventHandler * @see Proxy#newProxyInstance */ - @SuppressWarnings("removal") + @SuppressWarnings("unchecked") public static T create(Class listenerInterface, Object target, String action, String eventPropertyName, @@ -705,12 +687,7 @@ public static T create(Class listenerInterface, } final ClassLoader loader = getClassLoader(listenerInterface); final Class[] interfaces = {listenerInterface}; - return AccessController.doPrivileged(new PrivilegedAction() { - @SuppressWarnings("unchecked") - public T run() { - return (T) Proxy.newProxyInstance(loader, interfaces, handler); - } - }); + return (T) Proxy.newProxyInstance(loader, interfaces, handler); } private static ClassLoader getClassLoader(Class type) { diff --git a/src/java.desktop/share/classes/java/beans/MetaData.java b/src/java.desktop/share/classes/java/beans/MetaData.java index e3cf55a85c5..0a12e7dcee8 100644 --- a/src/java.desktop/share/classes/java/beans/MetaData.java +++ b/src/java.desktop/share/classes/java/beans/MetaData.java @@ -41,9 +41,6 @@ import java.lang.reflect.Modifier; import java.lang.reflect.InvocationTargetException; -import java.security.AccessController; -import java.security.PrivilegedAction; - import java.util.*; import javax.swing.Box; @@ -1319,28 +1316,22 @@ private static Object getBeanAttribute(Class type, String attribute) { } } - @SuppressWarnings("removal") static Object getPrivateFieldValue(Object instance, String name) { Field field = fields.get(name); if (field == null) { int index = name.lastIndexOf('.'); final String className = name.substring(0, index); final String fieldName = name.substring(1 + index); - field = AccessController.doPrivileged(new PrivilegedAction() { - public Field run() { - try { - Field field = Class.forName(className).getDeclaredField(fieldName); - field.setAccessible(true); - return field; - } - catch (ClassNotFoundException exception) { - throw new IllegalStateException("Could not find class", exception); - } - catch (NoSuchFieldException exception) { - throw new IllegalStateException("Could not find field", exception); - } - } - }); + try { + field = Class.forName(className).getDeclaredField(fieldName); + field.setAccessible(true); + } + catch (ClassNotFoundException exception) { + throw new IllegalStateException("Could not find class", exception); + } + catch (NoSuchFieldException exception) { + throw new IllegalStateException("Could not find field", exception); + } fields.put(name, field); } try { diff --git a/src/java.desktop/share/classes/java/beans/SimpleBeanInfo.java b/src/java.desktop/share/classes/java/beans/SimpleBeanInfo.java index 34ca9d20403..7b6fd131c24 100644 --- a/src/java.desktop/share/classes/java/beans/SimpleBeanInfo.java +++ b/src/java.desktop/share/classes/java/beans/SimpleBeanInfo.java @@ -29,8 +29,6 @@ import java.awt.Toolkit; import java.awt.image.ImageProducer; import java.net.URL; -import java.security.AccessController; -import java.security.PrivilegedAction; /** * This is a support class to make it easier for people to provide @@ -154,10 +152,8 @@ public Image getIcon(final int iconKind) { * @return an image object. May be null if the load failed. * @see java.beans.SimpleBeanInfo#loadImage(String) */ - @SuppressWarnings("removal") private Image loadStandardImage(final String resourceName) { - return AccessController.doPrivileged( - (PrivilegedAction) () -> loadImage(resourceName)); + return loadImage(resourceName); } /** diff --git a/src/java.desktop/share/classes/java/beans/Statement.java b/src/java.desktop/share/classes/java/beans/Statement.java index d079a0b24a9..bf1c62be78b 100644 --- a/src/java.desktop/share/classes/java/beans/Statement.java +++ b/src/java.desktop/share/classes/java/beans/Statement.java @@ -29,10 +29,6 @@ import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; -import java.security.AccessControlContext; -import java.security.AccessController; -import java.security.PrivilegedActionException; -import java.security.PrivilegedExceptionAction; import com.sun.beans.finder.ClassFinder; import com.sun.beans.finder.ConstructorFinder; @@ -69,8 +65,6 @@ public void exceptionThrown(Exception e) { } }; - @SuppressWarnings("removal") - private final AccessControlContext acc = AccessController.getContext(); private final Object target; private final String methodName; private final Object[] arguments; @@ -174,28 +168,7 @@ public void execute() throws Exception { invoke(); } - @SuppressWarnings("removal") Object invoke() throws Exception { - AccessControlContext acc = this.acc; - if ((acc == null) && (System.getSecurityManager() != null)) { - throw new SecurityException("AccessControlContext is not set"); - } - try { - return AccessController.doPrivileged( - new PrivilegedExceptionAction() { - public Object run() throws Exception { - return invokeInternal(); - } - }, - acc - ); - } - catch (PrivilegedActionException exception) { - throw exception.getException(); - } - } - - private Object invokeInternal() throws Exception { Object target = getTarget(); String methodName = getMethodName(); diff --git a/src/java.desktop/share/classes/java/beans/XMLDecoder.java b/src/java.desktop/share/classes/java/beans/XMLDecoder.java index 8a7e6b9984a..febba84d2a1 100644 --- a/src/java.desktop/share/classes/java/beans/XMLDecoder.java +++ b/src/java.desktop/share/classes/java/beans/XMLDecoder.java @@ -29,9 +29,6 @@ import java.io.Closeable; import java.io.InputStream; import java.io.IOException; -import java.security.AccessControlContext; -import java.security.AccessController; -import java.security.PrivilegedAction; import org.xml.sax.InputSource; import org.xml.sax.helpers.DefaultHandler; @@ -64,8 +61,6 @@ * @author Philip Milne */ public class XMLDecoder implements AutoCloseable { - @SuppressWarnings("removal") - private final AccessControlContext acc = AccessController.getContext(); private final DocumentHandler handler = new DocumentHandler(); private final InputSource input; private Object owner; @@ -189,21 +184,12 @@ private void close(Closeable in) { } } - @SuppressWarnings("removal") private boolean parsingComplete() { if (this.input == null) { return false; } if (this.array == null) { - if ((this.acc == null) && (null != System.getSecurityManager())) { - throw new SecurityException("AccessControlContext is not set"); - } - AccessController.doPrivileged(new PrivilegedAction() { - public Void run() { - XMLDecoder.this.handler.parse(XMLDecoder.this.input); - return null; - } - }, this.acc); + XMLDecoder.this.handler.parse(XMLDecoder.this.input); this.array = this.handler.getObjects(); } return true; From f62e05ee96085675041c5cb94762f78abbc89783 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eirik=20Bj=C3=B8rsn=C3=B8s?= Date: Fri, 15 Nov 2024 19:21:07 +0000 Subject: [PATCH 025/311] 8344231: SecurityManager cleanup in java.lang.module and jdk.internal.module Reviewed-by: alanb --- .../java/lang/module/ModuleFinder.java | 13 +----- .../jdk/internal/module/ModuleReferences.java | 10 +--- .../classes/jdk/internal/module/Modules.java | 7 +-- .../internal/module/SystemModuleFinders.java | 46 ++----------------- 4 files changed, 8 insertions(+), 68 deletions(-) diff --git a/src/java.base/share/classes/java/lang/module/ModuleFinder.java b/src/java.base/share/classes/java/lang/module/ModuleFinder.java index 6b2e9228ad5..bc470633039 100644 --- a/src/java.base/share/classes/java/lang/module/ModuleFinder.java +++ b/src/java.base/share/classes/java/lang/module/ModuleFinder.java @@ -26,9 +26,6 @@ package java.lang.module; import java.nio.file.Path; -import java.security.AccessController; -import java.security.Permission; -import java.security.PrivilegedAction; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; @@ -130,16 +127,8 @@ public interface ModuleFinder { * * @return A {@code ModuleFinder} that locates the system modules */ - @SuppressWarnings("removal") static ModuleFinder ofSystem() { - SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - sm.checkPermission(new RuntimePermission("accessSystemModules")); - PrivilegedAction pa = SystemModuleFinders::ofSystem; - return AccessController.doPrivileged(pa); - } else { - return SystemModuleFinders.ofSystem(); - } + return SystemModuleFinders.ofSystem(); } /** diff --git a/src/java.base/share/classes/jdk/internal/module/ModuleReferences.java b/src/java.base/share/classes/jdk/internal/module/ModuleReferences.java index a5ad79eb7c6..c87c039c133 100644 --- a/src/java.base/share/classes/jdk/internal/module/ModuleReferences.java +++ b/src/java.base/share/classes/jdk/internal/module/ModuleReferences.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -370,14 +370,6 @@ static class ExplodedModuleReader implements ModuleReader { ExplodedModuleReader(Path dir) { this.dir = dir; - - // when running with a security manager then check that the caller - // has access to the directory. - @SuppressWarnings("removal") - SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - boolean unused = Files.isDirectory(dir); - } } /** diff --git a/src/java.base/share/classes/jdk/internal/module/Modules.java b/src/java.base/share/classes/jdk/internal/module/Modules.java index 11ca2d5e521..3c3d148e196 100644 --- a/src/java.base/share/classes/jdk/internal/module/Modules.java +++ b/src/java.base/share/classes/jdk/internal/module/Modules.java @@ -32,8 +32,6 @@ import java.lang.module.ModuleReference; import java.lang.module.ResolvedModule; import java.net.URI; -import java.security.AccessController; -import java.security.PrivilegedAction; import java.util.Collection; import java.util.List; import java.util.Map; @@ -155,10 +153,7 @@ public static void addUses(Module m, Class service) { public static void addProvides(Module m, Class service, Class impl) { ModuleLayer layer = m.getLayer(); - PrivilegedAction pa = m::getClassLoader; - @SuppressWarnings("removal") - ClassLoader loader = AccessController.doPrivileged(pa); - + ClassLoader loader = m.getClassLoader(); ClassLoader platformClassLoader = ClassLoaders.platformClassLoader(); if (layer == null || loader == null || loader == platformClassLoader) { // update ClassLoader catalog diff --git a/src/java.base/share/classes/jdk/internal/module/SystemModuleFinders.java b/src/java.base/share/classes/jdk/internal/module/SystemModuleFinders.java index 74af7570d57..c520e6e636a 100644 --- a/src/java.base/share/classes/jdk/internal/module/SystemModuleFinders.java +++ b/src/java.base/share/classes/jdk/internal/module/SystemModuleFinders.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -38,8 +38,6 @@ import java.nio.ByteBuffer; import java.nio.file.Files; import java.nio.file.Path; -import java.security.AccessController; -import java.security.PrivilegedAction; import java.util.ArrayDeque; import java.util.Collections; import java.util.Deque; @@ -208,21 +206,7 @@ public static ModuleFinder ofSystem() { Path dir = Path.of(home, "modules"); if (!Files.isDirectory(dir)) throw new InternalError("Unable to detect the run-time image"); - ModuleFinder f = ModulePath.of(ModuleBootstrap.patcher(), dir); - return new ModuleFinder() { - @SuppressWarnings("removal") - @Override - public Optional find(String name) { - PrivilegedAction> pa = () -> f.find(name); - return AccessController.doPrivileged(pa); - } - @SuppressWarnings("removal") - @Override - public Set findAll() { - PrivilegedAction> pa = f::findAll; - return AccessController.doPrivileged(pa); - } - }; + return ModulePath.of(ModuleBootstrap.patcher(), dir); } /** @@ -314,7 +298,7 @@ static ModuleReference toModuleReference(ModuleDescriptor descriptor, Supplier readerSupplier = new Supplier<>() { @Override public ModuleReader get() { - return new SystemModuleReader(mn, uri); + return new SystemModuleReader(mn); } }; @@ -377,9 +361,7 @@ public byte[] generate(String algorithm) { } /** - * Holder class for the ImageReader - * - * @apiNote This class must be loaded before a security manager is set. + * Holder class for the ImageReader. */ private static class SystemImage { static final ImageReader READER = ImageReaderFactory.getImageReader(); @@ -396,25 +378,7 @@ private static class SystemModuleReader implements ModuleReader { private final String module; private volatile boolean closed; - /** - * If there is a security manager set then check permission to - * connect to the run-time image. - */ - private static void checkPermissionToConnect(URI uri) { - @SuppressWarnings("removal") - SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - try { - URLConnection uc = uri.toURL().openConnection(); - sm.checkPermission(uc.getPermission()); - } catch (IOException ioe) { - throw new UncheckedIOException(ioe); - } - } - } - - SystemModuleReader(String module, URI uri) { - checkPermissionToConnect(uri); + SystemModuleReader(String module) { this.module = module; } From 73fd8919f581cd79d285d7f30bfac3457ef1127d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eirik=20Bj=C3=B8rsn=C3=B8s?= Date: Fri, 15 Nov 2024 19:21:30 +0000 Subject: [PATCH 026/311] 8344216: Remove calls to SecurityManager and and doPrivileged in java.net.Authenticator, java.net.CookieHandler, and java.net.ResponseCache after JEP 486 integration Reviewed-by: dfuchs --- .../share/classes/java/net/Authenticator.java | 47 ------------------- .../share/classes/java/net/CookieHandler.java | 11 ----- .../share/classes/java/net/ResponseCache.java | 11 ----- .../sun/security/util/SecurityConstants.java | 18 +------ 4 files changed, 1 insertion(+), 86 deletions(-) diff --git a/src/java.base/share/classes/java/net/Authenticator.java b/src/java.base/share/classes/java/net/Authenticator.java index 0935366abc1..9ac504f9a62 100644 --- a/src/java.base/share/classes/java/net/Authenticator.java +++ b/src/java.base/share/classes/java/net/Authenticator.java @@ -112,14 +112,6 @@ private void reset() { * any previously set authenticator is removed. */ public static synchronized void setDefault(Authenticator a) { - @SuppressWarnings("removal") - SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - NetPermission setDefaultPermission - = new NetPermission("setDefaultAuthenticator"); - sm.checkPermission(setDefaultPermission); - } - theAuthenticator = a; } @@ -130,13 +122,6 @@ public static synchronized void setDefault(Authenticator a) { * @since 9 */ public static Authenticator getDefault() { - @SuppressWarnings("removal") - SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - NetPermission requestPermission - = new NetPermission("requestPasswordAuthentication"); - sm.checkPermission(requestPermission); - } return theAuthenticator; } @@ -161,14 +146,6 @@ public static PasswordAuthentication requestPasswordAuthentication( String prompt, String scheme) { - @SuppressWarnings("removal") - SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - NetPermission requestPermission - = new NetPermission("requestPasswordAuthentication"); - sm.checkPermission(requestPermission); - } - Authenticator a = theAuthenticator; if (a == null) { return null; @@ -212,14 +189,6 @@ public static PasswordAuthentication requestPasswordAuthentication( String prompt, String scheme) { - @SuppressWarnings("removal") - SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - NetPermission requestPermission - = new NetPermission("requestPasswordAuthentication"); - sm.checkPermission(requestPermission); - } - Authenticator a = theAuthenticator; if (a == null) { return null; @@ -267,14 +236,6 @@ public static PasswordAuthentication requestPasswordAuthentication( URL url, RequestorType reqType) { - @SuppressWarnings("removal") - SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - NetPermission requestPermission - = new NetPermission("requestPasswordAuthentication"); - sm.checkPermission(requestPermission); - } - Authenticator a = theAuthenticator; if (a == null) { return null; @@ -328,14 +289,6 @@ public static PasswordAuthentication requestPasswordAuthentication( URL url, RequestorType reqType) { - @SuppressWarnings("removal") - SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - NetPermission requestPermission - = new NetPermission("requestPasswordAuthentication"); - sm.checkPermission(requestPermission); - } - Authenticator a = authenticator == null ? theAuthenticator : authenticator; if (a == null) { return null; diff --git a/src/java.base/share/classes/java/net/CookieHandler.java b/src/java.base/share/classes/java/net/CookieHandler.java index 4b5e3ebedd8..ec20c860591 100644 --- a/src/java.base/share/classes/java/net/CookieHandler.java +++ b/src/java.base/share/classes/java/net/CookieHandler.java @@ -28,7 +28,6 @@ import java.util.Map; import java.util.List; import java.io.IOException; -import sun.security.util.SecurityConstants; /** * A CookieHandler object provides a callback mechanism to hook up a @@ -73,11 +72,6 @@ public CookieHandler() {} * @see #setDefault(CookieHandler) */ public static synchronized CookieHandler getDefault() { - @SuppressWarnings("removal") - SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - sm.checkPermission(SecurityConstants.GET_COOKIEHANDLER_PERMISSION); - } return cookieHandler; } @@ -91,11 +85,6 @@ public static synchronized CookieHandler getDefault() { * @see #getDefault() */ public static synchronized void setDefault(CookieHandler cHandler) { - @SuppressWarnings("removal") - SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - sm.checkPermission(SecurityConstants.SET_COOKIEHANDLER_PERMISSION); - } cookieHandler = cHandler; } diff --git a/src/java.base/share/classes/java/net/ResponseCache.java b/src/java.base/share/classes/java/net/ResponseCache.java index 292c1b7610d..3339f41883b 100644 --- a/src/java.base/share/classes/java/net/ResponseCache.java +++ b/src/java.base/share/classes/java/net/ResponseCache.java @@ -28,7 +28,6 @@ import java.io.IOException; import java.util.Map; import java.util.List; -import sun.security.util.SecurityConstants; /** * Represents implementations of URLConnection caches. An instance of @@ -84,11 +83,6 @@ public ResponseCache() {} * @since 1.5 */ public static synchronized ResponseCache getDefault() { - @SuppressWarnings("removal") - SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - sm.checkPermission(SecurityConstants.GET_RESPONSECACHE_PERMISSION); - } return theResponseCache; } @@ -104,11 +98,6 @@ public static synchronized ResponseCache getDefault() { * @since 1.5 */ public static synchronized void setDefault(ResponseCache responseCache) { - @SuppressWarnings("removal") - SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - sm.checkPermission(SecurityConstants.SET_RESPONSECACHE_PERMISSION); - } theResponseCache = responseCache; } diff --git a/src/java.base/share/classes/sun/security/util/SecurityConstants.java b/src/java.base/share/classes/sun/security/util/SecurityConstants.java index df2861f3034..617e7a35a54 100644 --- a/src/java.base/share/classes/sun/security/util/SecurityConstants.java +++ b/src/java.base/share/classes/sun/security/util/SecurityConstants.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -80,22 +80,6 @@ private SecurityConstants () { public static final NetPermission GET_PROXYSELECTOR_PERMISSION = new NetPermission("getProxySelector"); - // java.net.CookieHandler - public static final NetPermission SET_COOKIEHANDLER_PERMISSION = - new NetPermission("setCookieHandler"); - - // java.net.CookieHandler - public static final NetPermission GET_COOKIEHANDLER_PERMISSION = - new NetPermission("getCookieHandler"); - - // java.net.ResponseCache - public static final NetPermission SET_RESPONSECACHE_PERMISSION = - new NetPermission("setResponseCache"); - - // java.net.ResponseCache - public static final NetPermission GET_RESPONSECACHE_PERMISSION = - new NetPermission("getResponseCache"); - // java.net.ServerSocket, java.net.Socket public static final NetPermission SET_SOCKETIMPL_PERMISSION = new NetPermission("setSocketImpl"); From f3168082b809dfe39afdf7064a83e7a39a1d3094 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eirik=20Bj=C3=B8rsn=C3=B8s?= Date: Fri, 15 Nov 2024 19:22:30 +0000 Subject: [PATCH 027/311] 8344189: Cleanup code in sun.net.www.protocol.mailto.MailToURLConnection and sun.net.smtp after JEP 486 integration Reviewed-by: dfuchs --- .../classes/sun/net/smtp/SmtpClient.java | 7 +++---- .../protocol/mailto/MailToURLConnection.java | 21 +------------------ 2 files changed, 4 insertions(+), 24 deletions(-) diff --git a/src/java.base/share/classes/sun/net/smtp/SmtpClient.java b/src/java.base/share/classes/sun/net/smtp/SmtpClient.java index 59c60ce70dc..494bcf19987 100644 --- a/src/java.base/share/classes/sun/net/smtp/SmtpClient.java +++ b/src/java.base/share/classes/sun/net/smtp/SmtpClient.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1995, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1995, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -28,7 +28,6 @@ import java.io.*; import java.net.*; import sun.net.TransferProtocolClient; -import sun.security.action.GetPropertyAction; /** * This class implements the SMTP client. @@ -167,7 +166,7 @@ public SmtpClient (String host) throws IOException { } try { String s; - mailhost = GetPropertyAction.privilegedGetProperty("mail.host"); + mailhost = System.getProperty("mail.host"); if (mailhost != null) { openServer(mailhost); return; @@ -193,7 +192,7 @@ public SmtpClient(int to) throws IOException { setConnectTimeout(to); try { String s; - mailhost = GetPropertyAction.privilegedGetProperty("mail.host"); + mailhost = System.getProperty("mail.host"); if (mailhost != null) { openServer(mailhost); return; diff --git a/src/java.base/share/classes/sun/net/www/protocol/mailto/MailToURLConnection.java b/src/java.base/share/classes/sun/net/www/protocol/mailto/MailToURLConnection.java index 555279f71ee..7791d07a8ca 100644 --- a/src/java.base/share/classes/sun/net/www/protocol/mailto/MailToURLConnection.java +++ b/src/java.base/share/classes/sun/net/www/protocol/mailto/MailToURLConnection.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -27,9 +27,7 @@ import java.net.URL; import java.net.InetAddress; -import java.net.SocketPermission; import java.io.*; -import java.security.Permission; import jdk.internal.util.StaticProperty; import sun.net.www.*; @@ -48,7 +46,6 @@ public class MailToURLConnection extends URLConnection { OutputStream os = null; SmtpClient client; - Permission permission; private int connectTimeout = -1; private int readTimeout = -1; @@ -67,12 +64,6 @@ public class MailToURLConnection extends URLConnection { String getFromAddress() { String str = System.getProperty("user.fromaddr"); if (str == null) { - // Perform the property security check for user.name - @SuppressWarnings("removal") - SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - sm.checkPropertyAccess("user.name"); - } str = StaticProperty.userName(); if (str != null) { String host = System.getProperty("mail.host"); @@ -112,16 +103,6 @@ public synchronized OutputStream getOutputStream() throws IOException { return os; } - @Override - public Permission getPermission() throws IOException { - if (permission == null) { - connect(); - String host = client.getMailHost() + ":" + 25; - permission = new SocketPermission(host, "connect"); - } - return permission; - } - @Override public void setConnectTimeout(int timeout) { if (timeout < 0) From 59ffac84d39250623b0e6bcb871b5b3fe9c9cfe6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Volkan=20Yaz=C4=B1c=C4=B1?= Date: Fri, 15 Nov 2024 19:56:48 +0000 Subject: [PATCH 028/311] 8342811: java/net/httpclient/PlainProxyConnectionTest.java failed: Unexpected connection count: 5 Reviewed-by: dfuchs --- .../httpclient/PlainProxyConnectionTest.java | 27 ++++++++++++++----- 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/test/jdk/java/net/httpclient/PlainProxyConnectionTest.java b/test/jdk/java/net/httpclient/PlainProxyConnectionTest.java index a3157b0ac37..f8671103ec4 100644 --- a/test/jdk/java/net/httpclient/PlainProxyConnectionTest.java +++ b/test/jdk/java/net/httpclient/PlainProxyConnectionTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,6 +25,8 @@ import com.sun.net.httpserver.HttpExchange; import com.sun.net.httpserver.HttpHandler; import com.sun.net.httpserver.HttpServer; +import jdk.httpclient.test.lib.common.HttpServerAdapters; + import java.io.IOException; import java.io.InputStream; import java.net.HttpURLConnection; @@ -54,15 +56,28 @@ * @bug 8230526 * @summary Verifies that PlainProxyConnections are cached and reused properly. We do this by * verifying that the remote address of the HTTP exchange (on the fake proxy server) - * is always the same InetSocketAddress. - * @modules jdk.httpserver - * @run main/othervm -Djdk.tracePinnedThreads=full PlainProxyConnectionTest - * @author danielfuchs + * is always the same InetSocketAddress. Logging verbosity is increased to aid in + * diagnosis of intermittent failures. + * @library /test/lib + * /test/jdk/java/net/httpclient/lib + * @run main/othervm -Djdk.tracePinnedThreads=full + * -Djdk.httpclient.HttpClient.log=headers,requests,trace + * -Djdk.internal.httpclient.debug=true + * PlainProxyConnectionTest */ public class PlainProxyConnectionTest { + // Increase logging verbosity to troubleshoot intermittent failures + static { + HttpServerAdapters.enableServerLogging(); + } + static final String RESPONSE = "

Hello World!"; - static final String PATH = "/foo/"; + + // Adding some salt to the path to avoid other parallel running tests mistakenly connect to our test server + private static final String PATH = String.format( + "/%s-%d", PlainProxyConnectionTest.class.getSimpleName(), PlainProxyConnectionTest.class.hashCode()); + static final ConcurrentLinkedQueue connections = new ConcurrentLinkedQueue<>(); private static final AtomicInteger IDS = new AtomicInteger(); From c5b6ed8ca0d4f9862fd6a890bcd457f73582696d Mon Sep 17 00:00:00 2001 From: Roger Riggs Date: Fri, 15 Nov 2024 20:29:14 +0000 Subject: [PATCH 029/311] 8344252: SM cleanup in java.util classes Reviewed-by: naoto, smarks --- .../share/classes/java/util/Arrays.java | 5 +- .../share/classes/java/util/Calendar.java | 34 +-- .../share/classes/java/util/Currency.java | 100 ++++---- .../share/classes/java/util/Locale.java | 4 - .../share/classes/java/util/Properties.java | 3 - .../java/util/PropertyResourceBundle.java | 9 +- .../classes/java/util/ResourceBundle.java | 240 +++++++----------- .../share/classes/java/util/TimeZone.java | 9 +- .../share/classes/java/util/Tripwire.java | 9 +- .../spi/AbstractResourceBundleProvider.java | 40 +-- .../java/util/spi/LocaleServiceProvider.java | 14 +- .../classes/java/util/spi/ToolProvider.java | 20 +- .../classes/java/util/stream/Tripwire.java | 9 +- 13 files changed, 163 insertions(+), 333 deletions(-) diff --git a/src/java.base/share/classes/java/util/Arrays.java b/src/java.base/share/classes/java/util/Arrays.java index 589c027b2dc..03fdf7a3c99 100644 --- a/src/java.base/share/classes/java/util/Arrays.java +++ b/src/java.base/share/classes/java/util/Arrays.java @@ -985,11 +985,8 @@ public static void parallelSort(T[] a, int fromIndex, int toIndex, * circular dependencies. To be removed in a future release. */ static final class LegacyMergeSort { - @SuppressWarnings("removal") private static final boolean userRequested = - java.security.AccessController.doPrivileged( - new sun.security.action.GetBooleanAction( - "java.util.Arrays.useLegacyMergeSort")).booleanValue(); + Boolean.getBoolean("java.util.Arrays.useLegacyMergeSort"); } /** diff --git a/src/java.base/share/classes/java/util/Calendar.java b/src/java.base/share/classes/java/util/Calendar.java index 7ac98c02297..7cf389df42b 100644 --- a/src/java.base/share/classes/java/util/Calendar.java +++ b/src/java.base/share/classes/java/util/Calendar.java @@ -43,12 +43,6 @@ import java.io.ObjectOutputStream; import java.io.OptionalDataException; import java.io.Serializable; -import java.security.AccessControlContext; -import java.security.AccessController; -import java.security.PermissionCollection; -import java.security.PrivilegedActionException; -import java.security.PrivilegedExceptionAction; -import java.security.ProtectionDomain; import java.text.DateFormat; import java.text.DateFormatSymbols; import java.time.Instant; @@ -3564,25 +3558,9 @@ private synchronized void writeObject(ObjectOutputStream stream) } } - @SuppressWarnings("removal") - private static class CalendarAccessControlContext { - private static final AccessControlContext INSTANCE; - static { - RuntimePermission perm = new RuntimePermission("accessClassInPackage.sun.util.calendar"); - PermissionCollection perms = perm.newPermissionCollection(); - perms.add(perm); - INSTANCE = new AccessControlContext(new ProtectionDomain[] { - new ProtectionDomain(null, perms) - }); - } - private CalendarAccessControlContext() { - } - } - /** * Reconstitutes this object from a stream (i.e., deserialize it). */ - @SuppressWarnings("removal") @java.io.Serial private void readObject(ObjectInputStream stream) throws IOException, ClassNotFoundException @@ -3617,16 +3595,8 @@ else if (serialVersionOnStream >= 0) // If there's a ZoneInfo object, use it for zone. ZoneInfo zi = null; try { - zi = AccessController.doPrivileged( - new PrivilegedExceptionAction<>() { - @Override - public ZoneInfo run() throws Exception { - return (ZoneInfo) input.readObject(); - } - }, - CalendarAccessControlContext.INSTANCE); - } catch (PrivilegedActionException pae) { - Exception e = pae.getException(); + zi = (ZoneInfo) input.readObject(); + } catch (Exception e) { if (!(e instanceof OptionalDataException)) { if (e instanceof RuntimeException) { throw (RuntimeException) e; diff --git a/src/java.base/share/classes/java/util/Currency.java b/src/java.base/share/classes/java/util/Currency.java index 0bc86f3281e..b639855b3bf 100644 --- a/src/java.base/share/classes/java/util/Currency.java +++ b/src/java.base/share/classes/java/util/Currency.java @@ -32,8 +32,6 @@ import java.io.InputStream; import java.io.IOException; import java.io.Serializable; -import java.security.AccessController; -import java.security.PrivilegedAction; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.concurrent.ConcurrentHashMap; @@ -213,63 +211,57 @@ public final class Currency implements Serializable { initStatic(); } - @SuppressWarnings("removal") private static void initStatic() { - AccessController.doPrivileged(new PrivilegedAction<>() { - @Override - public Void run() { - try { - try (InputStream in = getClass().getResourceAsStream("/java/util/currency.data")) { - if (in == null) { - throw new InternalError("Currency data not found"); - } - DataInputStream dis = new DataInputStream(new BufferedInputStream(in)); - if (dis.readInt() != MAGIC_NUMBER) { - throw new InternalError("Currency data is possibly corrupted"); - } - formatVersion = dis.readInt(); - if (formatVersion != VALID_FORMAT_VERSION) { - throw new InternalError("Currency data format is incorrect"); - } - dataVersion = dis.readInt(); - mainTable = readIntArray(dis, A_TO_Z * A_TO_Z); - int scCount = dis.readInt(); - specialCasesList = readSpecialCases(dis, scCount); - int ocCount = dis.readInt(); - otherCurrenciesList = readOtherCurrencies(dis, ocCount); - } - } catch (IOException e) { - throw new InternalError(e); - } - // look for the properties file for overrides - String propsFile = System.getProperty("java.util.currency.data"); - if (propsFile == null) { - propsFile = StaticProperty.javaHome() + File.separator + "lib" + - File.separator + "currency.properties"; + try { + try (InputStream in = Currency.class.getResourceAsStream("/java/util/currency.data")) { + if (in == null) { + throw new InternalError("Currency data not found"); } - try { - File propFile = new File(propsFile); - if (propFile.exists()) { - Properties props = new Properties(); - try (FileReader fr = new FileReader(propFile)) { - props.load(fr); - } - Pattern propertiesPattern = - Pattern.compile("([A-Z]{3})\\s*,\\s*(\\d{3})\\s*,\\s*" + - "(\\d+)\\s*,?\\s*(\\d{4}-\\d{2}-\\d{2}T\\d{2}:" + - "\\d{2}:\\d{2})?"); - List currencyEntries - = getValidCurrencyData(props, propertiesPattern); - currencyEntries.forEach(Currency::replaceCurrencyData); - } - } catch (IOException e) { - CurrencyProperty.info("currency.properties is ignored" - + " because of an IOException", e); + DataInputStream dis = new DataInputStream(new BufferedInputStream(in)); + if (dis.readInt() != MAGIC_NUMBER) { + throw new InternalError("Currency data is possibly corrupted"); } - return null; + formatVersion = dis.readInt(); + if (formatVersion != VALID_FORMAT_VERSION) { + throw new InternalError("Currency data format is incorrect"); + } + dataVersion = dis.readInt(); + mainTable = readIntArray(dis, A_TO_Z * A_TO_Z); + int scCount = dis.readInt(); + specialCasesList = readSpecialCases(dis, scCount); + int ocCount = dis.readInt(); + otherCurrenciesList = readOtherCurrencies(dis, ocCount); } - }); + } catch (IOException e) { + throw new InternalError(e); + } + + // look for the properties file for overrides + String propsFile = System.getProperty("java.util.currency.data"); + if (propsFile == null) { + propsFile = StaticProperty.javaHome() + File.separator + "lib" + + File.separator + "currency.properties"; + } + try { + File propFile = new File(propsFile); + if (propFile.exists()) { + Properties props = new Properties(); + try (FileReader fr = new FileReader(propFile)) { + props.load(fr); + } + Pattern propertiesPattern = + Pattern.compile("([A-Z]{3})\\s*,\\s*(\\d{3})\\s*,\\s*" + + "(\\d+)\\s*,?\\s*(\\d{4}-\\d{2}-\\d{2}T\\d{2}:" + + "\\d{2}:\\d{2})?"); + List currencyEntries + = getValidCurrencyData(props, propertiesPattern); + currencyEntries.forEach(Currency::replaceCurrencyData); + } + } catch (IOException e) { + CurrencyProperty.info("currency.properties is ignored" + + " because of an IOException", e); + } } /** diff --git a/src/java.base/share/classes/java/util/Locale.java b/src/java.base/share/classes/java/util/Locale.java index 600b20de639..c055c160367 100644 --- a/src/java.base/share/classes/java/util/Locale.java +++ b/src/java.base/share/classes/java/util/Locale.java @@ -1216,10 +1216,6 @@ public static synchronized void setDefault(Locale.Category category, if (newLocale == null) throw new NullPointerException("Can't set default locale to NULL"); - @SuppressWarnings("removal") - SecurityManager sm = System.getSecurityManager(); - if (sm != null) sm.checkPermission(new PropertyPermission - ("user.language", "write")); switch (category) { case DISPLAY: defaultDisplayLocale = newLocale; diff --git a/src/java.base/share/classes/java/util/Properties.java b/src/java.base/share/classes/java/util/Properties.java index 45ca0363660..015cdbc7107 100644 --- a/src/java.base/share/classes/java/util/Properties.java +++ b/src/java.base/share/classes/java/util/Properties.java @@ -949,9 +949,6 @@ private void store0(BufferedWriter bw, String comments, boolean escUnicode) } private static void writeDateComment(BufferedWriter bw) throws IOException { - // value of java.properties.date system property isn't sensitive - // and so doesn't need any security manager checks to make the value accessible - // to the callers String sysPropVal = StaticProperty.javaPropertiesDate(); if (sysPropVal != null && !sysPropVal.isEmpty()) { writeComments(bw, sysPropVal); diff --git a/src/java.base/share/classes/java/util/PropertyResourceBundle.java b/src/java.base/share/classes/java/util/PropertyResourceBundle.java index 02391fa2de2..aba65cbcd88 100644 --- a/src/java.base/share/classes/java/util/PropertyResourceBundle.java +++ b/src/java.base/share/classes/java/util/PropertyResourceBundle.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -46,7 +46,6 @@ import java.nio.charset.MalformedInputException; import java.nio.charset.UnmappableCharacterException; import sun.nio.cs.ISO_8859_1; -import sun.security.action.GetPropertyAction; import sun.util.PropertyResourceBundleCharset; import sun.util.ResourceBundleEnumeration; @@ -132,9 +131,9 @@ public class PropertyResourceBundle extends ResourceBundle { // Check whether the strict encoding is specified. // The possible encoding is either "ISO-8859-1" or "UTF-8". - private static final String encoding = GetPropertyAction - .privilegedGetProperty("java.util.PropertyResourceBundle.encoding", "") - .toUpperCase(Locale.ROOT); + private static final String encoding = + System.getProperty("java.util.PropertyResourceBundle.encoding", "") + .toUpperCase(Locale.ROOT); /** * Creates a property resource bundle from an {@link java.io.InputStream diff --git a/src/java.base/share/classes/java/util/ResourceBundle.java b/src/java.base/share/classes/java/util/ResourceBundle.java index 83f58b8506f..989cc09f388 100644 --- a/src/java.base/share/classes/java/util/ResourceBundle.java +++ b/src/java.base/share/classes/java/util/ResourceBundle.java @@ -42,7 +42,6 @@ import java.io.IOException; import java.io.InputStream; -import java.io.UncheckedIOException; import java.lang.ref.Reference; import java.lang.ref.ReferenceQueue; import java.lang.ref.SoftReference; @@ -53,10 +52,6 @@ import java.net.JarURLConnection; import java.net.URL; import java.net.URLConnection; -import java.security.AccessController; -import java.security.PrivilegedAction; -import java.security.PrivilegedActionException; -import java.security.PrivilegedExceptionAction; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; import java.util.jar.JarEntry; @@ -70,12 +65,9 @@ import jdk.internal.reflect.CallerSensitive; import jdk.internal.reflect.Reflection; import jdk.internal.util.ReferencedKeyMap; -import sun.security.action.GetPropertyAction; import sun.util.locale.BaseLocale; import sun.util.resources.Bundles; -import static sun.security.util.SecurityConstants.GET_CLASSLOADER_PERMISSION; - /** * @@ -581,10 +573,8 @@ public Locale getLocale() { return locale; } - @SuppressWarnings("removal") private static ClassLoader getLoader(Module module) { - PrivilegedAction pa = module::getClassLoader; - return AccessController.doPrivileged(pa); + return module.getClassLoader(); } /** @@ -1506,15 +1496,12 @@ private static Control getDefaultControl(Module targetModule, String baseName) { } private static class ResourceBundleControlProviderHolder { - private static final PrivilegedAction> pa = - () -> ServiceLoader.load(ResourceBundleControlProvider.class, - ClassLoader.getSystemClassLoader()).stream() - .map(ServiceLoader.Provider::get) - .toList(); - @SuppressWarnings("removal") private static final List CONTROL_PROVIDERS = - AccessController.doPrivileged(pa); + ServiceLoader.load(ResourceBundleControlProvider.class, + ClassLoader.getSystemClassLoader()).stream() + .map(ServiceLoader.Provider::get) + .toList(); private static Control getControl(String baseName) { return CONTROL_PROVIDERS.isEmpty() ? @@ -1594,13 +1581,6 @@ private static ResourceBundle getBundleFromModule(Class caller, Control control) { Objects.requireNonNull(module); Module callerModule = getCallerModule(caller); - if (callerModule != module) { - @SuppressWarnings("removal") - SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - sm.checkPermission(GET_CLASSLOADER_PERMISSION); - } - } return getBundleImpl(callerModule, module, baseName, locale, control); } @@ -1885,7 +1865,6 @@ private static ServiceLoader getServiceLoader(Module mod * Returns the service type of the given baseName that is visible * to the given class loader */ - @SuppressWarnings("removal") private static Class getResourceBundleProviderType(String baseName, ClassLoader loader) { @@ -1900,27 +1879,20 @@ private static ServiceLoader getServiceLoader(Module mod // Use the class loader of the getBundle caller so that the caller's // visibility of the provider type is checked. - return AccessController.doPrivileged( - new PrivilegedAction<>() { - @Override - public Class run() { - try { - Class c = Class.forName(providerName, false, loader); - if (ResourceBundleProvider.class.isAssignableFrom(c)) { - @SuppressWarnings("unchecked") - Class s = (Class) c; - return s; - } - } catch (ClassNotFoundException e) {} - return null; - } - }); + try { + Class c = Class.forName(providerName, false, loader); + if (ResourceBundleProvider.class.isAssignableFrom(c)) { + @SuppressWarnings("unchecked") + Class s = (Class) c; + return s; + } + } catch (ClassNotFoundException _) {} + return null; } /** * Loads ResourceBundle from service providers. */ - @SuppressWarnings("removal") private static ResourceBundle loadBundleFromProviders(String baseName, Locale locale, ServiceLoader providers, @@ -1928,34 +1900,28 @@ private static ResourceBundle loadBundleFromProviders(String baseName, { if (providers == null) return null; - return AccessController.doPrivileged( - new PrivilegedAction<>() { - public ResourceBundle run() { - for (Iterator itr = providers.iterator(); itr.hasNext(); ) { - try { - ResourceBundleProvider provider = itr.next(); - if (cacheKey != null && cacheKey.callerHasProvider == null - && cacheKey.getModule() == provider.getClass().getModule()) { - cacheKey.callerHasProvider = Boolean.TRUE; - } - ResourceBundle bundle = provider.getBundle(baseName, locale); - trace("provider %s %s locale: %s bundle: %s%n", provider, baseName, locale, bundle); - if (bundle != null) { - return bundle; - } - } catch (ServiceConfigurationError | SecurityException e) { - if (cacheKey != null) { - cacheKey.setCause(e); - } - } - } - if (cacheKey != null && cacheKey.callerHasProvider == null) { - cacheKey.callerHasProvider = Boolean.FALSE; - } - return null; - } - }); - + for (Iterator itr = providers.iterator(); itr.hasNext(); ) { + try { + ResourceBundleProvider provider = itr.next(); + if (cacheKey != null && cacheKey.callerHasProvider == null + && cacheKey.getModule() == provider.getClass().getModule()) { + cacheKey.callerHasProvider = Boolean.TRUE; + } + ResourceBundle bundle = provider.getBundle(baseName, locale); + trace("provider %s %s locale: %s bundle: %s%n", provider, baseName, locale, bundle); + if (bundle != null) { + return bundle; + } + } catch (ServiceConfigurationError e) { + if (cacheKey != null) { + cacheKey.setCause(e); + } + } + } + if (cacheKey != null && cacheKey.callerHasProvider == null) { + cacheKey.callerHasProvider = Boolean.FALSE; + } + return null; } /* @@ -3153,7 +3119,6 @@ public ResourceBundle newBundle(String baseName, Locale locale, String format, return bundle; } - @SuppressWarnings("removal") private ResourceBundle newBundle0(String bundleName, String format, ClassLoader loader, boolean reload) throws IllegalAccessException, InstantiationException, IOException { @@ -3177,28 +3142,20 @@ private ResourceBundle newBundle0(String bundleName, String format, bundleClass.getName() + " in " + m.toString()); } try { - Constructor ctor = AccessController.doPrivileged( - new PrivilegedExceptionAction<>() { - @Override - public Constructor run() throws NoSuchMethodException { - return bundleClass.getDeclaredConstructor(); - } - }); + Constructor ctor = bundleClass.getDeclaredConstructor(); if (!Modifier.isPublic(ctor.getModifiers())) { throw new IllegalAccessException("no-arg constructor in " + bundleClass.getName() + " is not publicly accessible."); } // java.base may not be able to read the bundleClass's module. - PrivilegedAction pa1 = () -> { ctor.setAccessible(true); return null; }; - AccessController.doPrivileged(pa1); + ctor.setAccessible(true); bundle = ctor.newInstance((Object[]) null); } catch (InvocationTargetException e) { uncheckedThrow(e); - } catch (PrivilegedActionException e) { - assert e.getCause() instanceof NoSuchMethodException; + } catch (NoSuchMethodException e) { throw new InstantiationException("public no-arg constructor " + - "does not exist in " + bundleClass.getName()); + "does not exist in " + bundleClass.getName()); } } else { throw new ClassCastException(c.getName() @@ -3212,27 +3169,16 @@ public Constructor run() throws NoSuchMethodException { return bundle; } - final boolean reloadFlag = reload; - InputStream stream = null; - try { - stream = AccessController.doPrivileged( - new PrivilegedExceptionAction<>() { - public InputStream run() throws IOException { - URL url = loader.getResource(resourceName); - if (url == null) return null; - - URLConnection connection = url.openConnection(); - if (reloadFlag) { - // Disable caches to get fresh data for - // reloading. - connection.setUseCaches(false); - } - return connection.getInputStream(); - } - }); - } catch (PrivilegedActionException e) { - throw (IOException) e.getCause(); + URL url = loader.getResource(resourceName); + if (url == null) return null; + + URLConnection connection = url.openConnection(); + if (reload) { + // Disable caches to get fresh data for + // reloading. + connection.setUseCaches(false); } + InputStream stream = connection.getInputStream(); if (stream != null) { try { bundle = new PropertyResourceBundle(stream); @@ -3563,7 +3509,6 @@ private static class ResourceBundleProviderHelper { /** * Returns a new ResourceBundle instance of the given bundleClass */ - @SuppressWarnings("removal") static ResourceBundle newResourceBundle(Class bundleClass) { try { @SuppressWarnings("unchecked") @@ -3573,8 +3518,7 @@ static ResourceBundle newResourceBundle(Class bundleCl return null; } // java.base may not be able to read the bundleClass's module. - PrivilegedAction pa = () -> { ctor.setAccessible(true); return null;}; - AccessController.doPrivileged(pa); + ctor.setAccessible(true); try { return ctor.newInstance((Object[]) null); } catch (InvocationTargetException e) { @@ -3602,9 +3546,7 @@ static ResourceBundle loadResourceBundle(Module callerModule, { String bundleName = Control.INSTANCE.toBundleName(baseName, locale); try { - PrivilegedAction> pa = () -> Class.forName(module, bundleName); - @SuppressWarnings("removal") - Class c = AccessController.doPrivileged(pa, null, GET_CLASSLOADER_PERMISSION); + Class c = Class.forName(module, bundleName); trace("local in %s %s caller %s: %s%n", module, bundleName, callerModule, c); if (c == null) { @@ -3662,56 +3604,46 @@ static ResourceBundle loadPropertyResourceBundle(Module callerModule, { String bundleName = Control.INSTANCE.toBundleName(baseName, locale); - PrivilegedAction pa = () -> { - try { - String resourceName = Control.INSTANCE - .toResourceName0(bundleName, "properties"); - if (resourceName == null) { - return null; - } - trace("local in %s %s caller %s%n", module, resourceName, callerModule); - - // if the package is in the given module but not opened - // locate it from the given module first. - String pn = toPackageName(bundleName); - trace(" %s/%s is accessible to %s : %s%n", - module.getName(), pn, callerModule, - isAccessible(callerModule, module, pn)); - if (isAccessible(callerModule, module, pn)) { - InputStream in = module.getResourceAsStream(resourceName); - if (in != null) { - return in; - } - } - - ClassLoader loader = module.getClassLoader(); - trace("loader for %s %s caller %s%n", module, resourceName, callerModule); - - try { - if (loader != null) { - return loader.getResourceAsStream(resourceName); - } else { - URL url = BootLoader.findResource(resourceName); - if (url != null) { - return url.openStream(); - } - } - } catch (Exception e) {} - return null; - - } catch (IOException e) { - throw new UncheckedIOException(e); + String resourceName = Control.INSTANCE + .toResourceName0(bundleName, "properties"); + if (resourceName == null) { + return null; + } + trace("local in %s %s caller %s%n", module, resourceName, callerModule); + + + // if the package is in the given module but not opened + // locate it from the given module first. + String pn = toPackageName(bundleName); + trace(" %s/%s is accessible to %s : %s%n", + module.getName(), pn, callerModule, + isAccessible(callerModule, module, pn)); + if (isAccessible(callerModule, module, pn)) { + InputStream in = module.getResourceAsStream(resourceName); + if (in != null) { + return new PropertyResourceBundle(in); } - }; + } + ClassLoader loader = module.getClassLoader(); + trace("loader for %s %s caller %s%n", module, resourceName, callerModule); - try (@SuppressWarnings("removal") InputStream stream = AccessController.doPrivileged(pa)) { + try { + InputStream stream = null; + if (loader != null) { + stream = loader.getResourceAsStream(resourceName); + } else { + URL url = BootLoader.findResource(resourceName); + if (url != null) { + stream = url.openStream(); + } + } if (stream != null) { return new PropertyResourceBundle(stream); } else { return null; } - } catch (UncheckedIOException e) { - throw e.getCause(); + } catch (Exception e) { + return null; } } @@ -3722,8 +3654,8 @@ private static String toPackageName(String bundleName) { } - private static final boolean TRACE_ON = Boolean.parseBoolean( - GetPropertyAction.privilegedGetProperty("resource.bundle.debug", "false")); + private static final boolean TRACE_ON = Boolean.getBoolean( + System.getProperty("resource.bundle.debug", "false")); private static void trace(String format, Object... params) { if (TRACE_ON) diff --git a/src/java.base/share/classes/java/util/TimeZone.java b/src/java.base/share/classes/java/util/TimeZone.java index f1a2d92b6ba..f0b122418c9 100644 --- a/src/java.base/share/classes/java/util/TimeZone.java +++ b/src/java.base/share/classes/java/util/TimeZone.java @@ -43,7 +43,6 @@ import java.time.ZoneOffset; import jdk.internal.util.StaticProperty; -import sun.security.action.GetPropertyAction; import sun.util.calendar.ZoneInfo; import sun.util.calendar.ZoneInfoFile; import sun.util.locale.provider.TimeZoneNameUtility; @@ -683,7 +682,7 @@ static TimeZone getDefaultRef() { private static synchronized TimeZone setDefaultZone() { TimeZone tz; // get the time zone ID from the system properties - Properties props = GetPropertyAction.privilegedGetProperties(); + Properties props = System.getProperties(); String zoneID = props.getProperty("user.timezone"); // if the time zone ID is not set (yet), perform the @@ -729,12 +728,6 @@ private static synchronized TimeZone setDefaultZone() { */ public static void setDefault(TimeZone zone) { - @SuppressWarnings("removal") - SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - sm.checkPermission(new PropertyPermission - ("user.timezone", "write")); - } // by saving a defensive clone and returning a clone in getDefault() too, // the defaultTimeZone instance is isolated from user code which makes it // effectively immutable. This is important to avoid races when the diff --git a/src/java.base/share/classes/java/util/Tripwire.java b/src/java.base/share/classes/java/util/Tripwire.java index c807a419619..ec20b956375 100644 --- a/src/java.base/share/classes/java/util/Tripwire.java +++ b/src/java.base/share/classes/java/util/Tripwire.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,9 +26,6 @@ import sun.util.logging.PlatformLogger; -import java.security.AccessController; -import java.security.PrivilegedAction; - /** * Utility class for detecting inadvertent uses of boxing in * {@code java.util} classes. The detection is turned on or off based on @@ -49,9 +46,7 @@ final class Tripwire { private static final String TRIPWIRE_PROPERTY = "org.openjdk.java.util.stream.tripwire"; /** Should debugging checks be enabled? */ - @SuppressWarnings("removal") - static final boolean ENABLED = AccessController.doPrivileged( - (PrivilegedAction) () -> Boolean.getBoolean(TRIPWIRE_PROPERTY)); + static final boolean ENABLED = Boolean.getBoolean(TRIPWIRE_PROPERTY); private Tripwire() { } diff --git a/src/java.base/share/classes/java/util/spi/AbstractResourceBundleProvider.java b/src/java.base/share/classes/java/util/spi/AbstractResourceBundleProvider.java index 6eb35aed691..8db27ec586d 100644 --- a/src/java.base/share/classes/java/util/spi/AbstractResourceBundleProvider.java +++ b/src/java.base/share/classes/java/util/spi/AbstractResourceBundleProvider.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -32,12 +32,9 @@ import java.io.IOException; import java.io.InputStream; import java.io.UncheckedIOException; -import java.security.AccessController; -import java.security.PrivilegedAction; import java.util.Locale; import java.util.PropertyResourceBundle; import java.util.ResourceBundle; -import static sun.security.util.SecurityConstants.GET_CLASSLOADER_PERMISSION; /** * {@code AbstractResourceBundleProvider} is an abstract class that provides @@ -78,11 +75,10 @@ * return null; * } * }} - * + *

* Refer to {@link ResourceBundleProvider} for details. * - * @see - * Resource Bundles and Named Modules + * @see ResourceBundle##resource-bundle-modules Resource Bundles and Named Modules * @since 9 */ public abstract class AbstractResourceBundleProvider implements ResourceBundleProvider { @@ -222,11 +218,8 @@ private ResourceBundle getBundle0(Module module, String bundleName) { * Returns the ResourceBundle of .class format if found in the module * of this provider. */ - private static ResourceBundle loadResourceBundle(Module module, String bundleName) - { - PrivilegedAction> pa = () -> Class.forName(module, bundleName); - @SuppressWarnings("removal") - Class c = AccessController.doPrivileged(pa, null, GET_CLASSLOADER_PERMISSION); + private static ResourceBundle loadResourceBundle(Module module, String bundleName) { + Class c = Class.forName(module, bundleName); if (c != null && ResourceBundle.class.isAssignableFrom(c)) { @SuppressWarnings("unchecked") Class bundleClass = (Class) c; @@ -241,28 +234,17 @@ private static ResourceBundle loadResourceBundle(Module module, String bundleNam */ private static ResourceBundle loadPropertyResourceBundle(Module module, String bundleName) - throws IOException - { + throws IOException { String resourceName = toResourceName(bundleName, "properties"); if (resourceName == null) { return null; } - PrivilegedAction pa = () -> { - try { - return module.getResourceAsStream(resourceName); - } catch (IOException e) { - throw new UncheckedIOException(e); - } - }; - try (@SuppressWarnings("removal") InputStream stream = AccessController.doPrivileged(pa)) { - if (stream != null) { - return new PropertyResourceBundle(stream); - } else { - return null; - } - } catch (UncheckedIOException e) { - throw e.getCause(); + InputStream stream = module.getResourceAsStream(resourceName); + if (stream != null) { + return new PropertyResourceBundle(stream); + } else { + return null; } } diff --git a/src/java.base/share/classes/java/util/spi/LocaleServiceProvider.java b/src/java.base/share/classes/java/util/spi/LocaleServiceProvider.java index 46712e5c80b..6e130872bd4 100644 --- a/src/java.base/share/classes/java/util/spi/LocaleServiceProvider.java +++ b/src/java.base/share/classes/java/util/spi/LocaleServiceProvider.java @@ -222,22 +222,10 @@ */ public abstract class LocaleServiceProvider { - private static Void checkPermission() { - @SuppressWarnings("removal") - SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - sm.checkPermission(new RuntimePermission("localeServiceProvider")); - } - return null; - } - private LocaleServiceProvider(Void ignore) { } - /** * Initializes a new locale service provider. */ - protected LocaleServiceProvider() { - this(checkPermission()); - } + protected LocaleServiceProvider() {} /** * {@return an array of all locales for which this locale service provider diff --git a/src/java.base/share/classes/java/util/spi/ToolProvider.java b/src/java.base/share/classes/java/util/spi/ToolProvider.java index 1a3a710e0be..20909522859 100644 --- a/src/java.base/share/classes/java/util/spi/ToolProvider.java +++ b/src/java.base/share/classes/java/util/spi/ToolProvider.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -27,8 +27,6 @@ import java.io.PrintStream; import java.io.PrintWriter; -import java.security.AccessController; -import java.security.PrivilegedAction; import java.util.Objects; import java.util.Optional; import java.util.ServiceLoader; @@ -178,18 +176,14 @@ default int run(PrintStream out, PrintStream err, String... args) { * * @throws NullPointerException if {@code name} is {@code null} */ - @SuppressWarnings("removal") static Optional findFirst(String name) { Objects.requireNonNull(name); ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader(); - return AccessController.doPrivileged( - (PrivilegedAction>) () -> { - ServiceLoader sl = - ServiceLoader.load(ToolProvider.class, systemClassLoader); - return StreamSupport.stream(sl.spliterator(), false) - .filter(p -> p.name().equals(name)) - .findFirst(); - }); + + ServiceLoader sl = + ServiceLoader.load(ToolProvider.class, systemClassLoader); + return StreamSupport.stream(sl.spliterator(), false) + .filter(p -> p.name().equals(name)) + .findFirst(); } } - diff --git a/src/java.base/share/classes/java/util/stream/Tripwire.java b/src/java.base/share/classes/java/util/stream/Tripwire.java index 962c7d3e1b0..6aae5e67e50 100644 --- a/src/java.base/share/classes/java/util/stream/Tripwire.java +++ b/src/java.base/share/classes/java/util/stream/Tripwire.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -24,9 +24,6 @@ */ package java.util.stream; -import java.security.AccessController; -import java.security.PrivilegedAction; - import sun.util.logging.PlatformLogger; /** @@ -49,9 +46,7 @@ final class Tripwire { private static final String TRIPWIRE_PROPERTY = "org.openjdk.java.util.stream.tripwire"; /** Should debugging checks be enabled? */ - @SuppressWarnings("removal") - static final boolean ENABLED = AccessController.doPrivileged( - (PrivilegedAction) () -> Boolean.getBoolean(TRIPWIRE_PROPERTY)); + static final boolean ENABLED = Boolean.getBoolean(TRIPWIRE_PROPERTY); private Tripwire() { } From c388455d0a463c9cb52ad18050f1155ec4ac0e6c Mon Sep 17 00:00:00 2001 From: Roger Riggs Date: Fri, 15 Nov 2024 20:30:04 +0000 Subject: [PATCH 030/311] 8344197: SM cleanup in java.util.concurrent Reviewed-by: alanb, dl --- .../concurrent/ConcurrentSkipListSet.java | 15 +-- .../util/concurrent/CopyOnWriteArrayList.java | 15 +-- .../java/util/concurrent/Executors.java | 98 ++++--------------- .../util/concurrent/StructuredTaskScope.java | 17 +--- .../util/concurrent/ThreadLocalRandom.java | 1 - .../concurrent/ThreadPerTaskExecutor.java | 17 ---- .../util/concurrent/ThreadPoolExecutor.java | 57 +---------- .../atomic/AtomicIntegerFieldUpdater.java | 19 +--- .../atomic/AtomicLongFieldUpdater.java | 19 +--- .../atomic/AtomicReferenceArray.java | 16 +-- .../atomic/AtomicReferenceFieldUpdater.java | 19 +--- .../util/concurrent/atomic/Striped64.java | 17 ++-- 12 files changed, 40 insertions(+), 270 deletions(-) diff --git a/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListSet.java b/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListSet.java index 2a2fbc54d86..0bcb7978e90 100644 --- a/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListSet.java +++ b/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListSet.java @@ -527,20 +527,11 @@ public Spliterator spliterator() { /** Initializes map field; for use in clone. */ private void setMap(ConcurrentNavigableMap map) { - @SuppressWarnings("removal") - Field mapField = java.security.AccessController.doPrivileged( - (java.security.PrivilegedAction) () -> { - try { - Field f = ConcurrentSkipListSet.class - .getDeclaredField("m"); - f.setAccessible(true); - return f; - } catch (ReflectiveOperationException e) { - throw new Error(e); - }}); try { + Field mapField = ConcurrentSkipListSet.class.getDeclaredField("m"); + mapField.setAccessible(true); mapField.set(this, map); - } catch (IllegalAccessException e) { + } catch (IllegalAccessException | NoSuchFieldException e) { throw new Error(e); } } diff --git a/src/java.base/share/classes/java/util/concurrent/CopyOnWriteArrayList.java b/src/java.base/share/classes/java/util/concurrent/CopyOnWriteArrayList.java index f0f60730eb6..f5069c61d45 100644 --- a/src/java.base/share/classes/java/util/concurrent/CopyOnWriteArrayList.java +++ b/src/java.base/share/classes/java/util/concurrent/CopyOnWriteArrayList.java @@ -2096,20 +2096,11 @@ public List reversed() { /** Initializes the lock; for use when deserializing or cloning. */ private void resetLock() { - @SuppressWarnings("removal") - Field lockField = java.security.AccessController.doPrivileged( - (java.security.PrivilegedAction) () -> { - try { - Field f = CopyOnWriteArrayList.class - .getDeclaredField("lock"); - f.setAccessible(true); - return f; - } catch (ReflectiveOperationException e) { - throw new Error(e); - }}); try { + Field lockField = CopyOnWriteArrayList.class.getDeclaredField("lock"); + lockField.setAccessible(true); lockField.set(this, new Object()); - } catch (IllegalAccessException e) { + } catch (IllegalAccessException | NoSuchFieldException e) { throw new Error(e); } } diff --git a/src/java.base/share/classes/java/util/concurrent/Executors.java b/src/java.base/share/classes/java/util/concurrent/Executors.java index a0a25b1a70d..f804e225790 100644 --- a/src/java.base/share/classes/java/util/concurrent/Executors.java +++ b/src/java.base/share/classes/java/util/concurrent/Executors.java @@ -37,16 +37,12 @@ import static java.lang.ref.Reference.reachabilityFence; import java.lang.ref.Cleaner.Cleanable; -import java.security.AccessControlContext; -import java.security.AccessController; import java.security.PrivilegedAction; -import java.security.PrivilegedActionException; import java.security.PrivilegedExceptionAction; import java.util.Collection; import java.util.List; import java.util.concurrent.atomic.AtomicInteger; import jdk.internal.ref.CleanerFactory; -import sun.security.util.SecurityConstants; /** * Factory and utility methods for {@link Executor}, {@link @@ -559,27 +555,13 @@ public String toString() { */ private static final class PrivilegedCallable implements Callable { final Callable task; - @SuppressWarnings("removal") - final AccessControlContext acc; - @SuppressWarnings("removal") PrivilegedCallable(Callable task) { this.task = task; - this.acc = AccessController.getContext(); } - @SuppressWarnings("removal") public T call() throws Exception { - try { - return AccessController.doPrivileged( - new PrivilegedExceptionAction() { - public T run() throws Exception { - return task.call(); - } - }, acc); - } catch (PrivilegedActionException e) { - throw e.getException(); - } + return task.call(); } public String toString() { @@ -595,49 +577,26 @@ private static final class PrivilegedCallableUsingCurrentClassLoader implements Callable { final Callable task; @SuppressWarnings("removal") - final AccessControlContext acc; final ClassLoader ccl; @SuppressWarnings("removal") PrivilegedCallableUsingCurrentClassLoader(Callable task) { - SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - // Calls to getContextClassLoader from this class - // never trigger a security check, but we check - // whether our callers have this permission anyways. - sm.checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION); - - // Whether setContextClassLoader turns out to be necessary - // or not, we fail fast if permission is not available. - sm.checkPermission(new RuntimePermission("setContextClassLoader")); - } this.task = task; - this.acc = AccessController.getContext(); this.ccl = Thread.currentThread().getContextClassLoader(); } - @SuppressWarnings("removal") public T call() throws Exception { - try { - return AccessController.doPrivileged( - new PrivilegedExceptionAction() { - public T run() throws Exception { - Thread t = Thread.currentThread(); - ClassLoader cl = t.getContextClassLoader(); - if (ccl == cl) { - return task.call(); - } else { - t.setContextClassLoader(ccl); - try { - return task.call(); - } finally { - t.setContextClassLoader(cl); - } - } - } - }, acc); - } catch (PrivilegedActionException e) { - throw e.getException(); + Thread t = Thread.currentThread(); + ClassLoader cl = t.getContextClassLoader(); + if (ccl == cl) { + return task.call(); + } else { + t.setContextClassLoader(ccl); + try { + return task.call(); + } finally { + t.setContextClassLoader(cl); + } } } @@ -656,10 +615,7 @@ private static class DefaultThreadFactory implements ThreadFactory { private final String namePrefix; DefaultThreadFactory() { - @SuppressWarnings("removal") - SecurityManager s = System.getSecurityManager(); - group = (s != null) ? s.getThreadGroup() : - Thread.currentThread().getThreadGroup(); + group = Thread.currentThread().getThreadGroup(); namePrefix = "pool-" + poolNumber.getAndIncrement() + "-thread-"; @@ -678,27 +634,14 @@ public Thread newThread(Runnable r) { } /** - * Thread factory capturing access control context and class loader. + * Thread factory capturing the current class loader. */ private static class PrivilegedThreadFactory extends DefaultThreadFactory { @SuppressWarnings("removal") - final AccessControlContext acc; final ClassLoader ccl; - @SuppressWarnings("removal") PrivilegedThreadFactory() { super(); - SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - // Calls to getContextClassLoader from this class - // never trigger a security check, but we check - // whether our callers have this permission anyways. - sm.checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION); - - // Fail fast - sm.checkPermission(new RuntimePermission("setContextClassLoader")); - } - this.acc = AccessController.getContext(); this.ccl = Thread.currentThread().getContextClassLoader(); } @@ -706,13 +649,8 @@ public Thread newThread(final Runnable r) { return super.newThread(new Runnable() { @SuppressWarnings("removal") public void run() { - AccessController.doPrivileged(new PrivilegedAction<>() { - public Void run() { - Thread.currentThread().setContextClassLoader(ccl); - r.run(); - return null; - } - }, acc); + Thread.currentThread().setContextClassLoader(ccl); + r.run(); } }); } @@ -811,9 +749,7 @@ private static class AutoShutdownDelegatedExecutorService super(executor); Runnable action = () -> { if (!executor.isShutdown()) { - PrivilegedAction pa = () -> { executor.shutdown(); return null; }; - @SuppressWarnings("removal") - var ignore = AccessController.doPrivileged(pa); + executor.shutdown(); } }; cleanable = CleanerFactory.cleaner().register(this, action); diff --git a/src/java.base/share/classes/java/util/concurrent/StructuredTaskScope.java b/src/java.base/share/classes/java/util/concurrent/StructuredTaskScope.java index 17448e9bf3d..41c6b4914b9 100644 --- a/src/java.base/share/classes/java/util/concurrent/StructuredTaskScope.java +++ b/src/java.base/share/classes/java/util/concurrent/StructuredTaskScope.java @@ -26,8 +26,6 @@ import java.lang.invoke.MethodHandles; import java.lang.invoke.VarHandle; -import java.security.AccessController; -import java.security.PrivilegedAction; import java.time.Duration; import java.time.Instant; import java.util.Objects; @@ -688,7 +686,7 @@ public StructuredTaskScope joinUntil(Instant deadline) /** * Interrupt all unfinished threads. */ - private void implInterruptAll() { + private void interruptAll() { flock.threads() .filter(t -> t != Thread.currentThread()) .forEach(t -> { @@ -698,19 +696,6 @@ private void implInterruptAll() { }); } - @SuppressWarnings("removal") - private void interruptAll() { - if (System.getSecurityManager() == null) { - implInterruptAll(); - } else { - PrivilegedAction pa = () -> { - implInterruptAll(); - return null; - }; - AccessController.doPrivileged(pa); - } - } - /** * Shutdown the task scope if not already shutdown. Return true if this method * shutdowns the task scope, false if already shutdown. diff --git a/src/java.base/share/classes/java/util/concurrent/ThreadLocalRandom.java b/src/java.base/share/classes/java/util/concurrent/ThreadLocalRandom.java index 751c190acc0..19eb3122947 100644 --- a/src/java.base/share/classes/java/util/concurrent/ThreadLocalRandom.java +++ b/src/java.base/share/classes/java/util/concurrent/ThreadLocalRandom.java @@ -39,7 +39,6 @@ package java.util.concurrent; import java.io.ObjectStreamField; -import java.security.AccessControlContext; import java.util.Random; import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicLong; diff --git a/src/java.base/share/classes/java/util/concurrent/ThreadPerTaskExecutor.java b/src/java.base/share/classes/java/util/concurrent/ThreadPerTaskExecutor.java index e98ece084c0..f37ef6c956e 100644 --- a/src/java.base/share/classes/java/util/concurrent/ThreadPerTaskExecutor.java +++ b/src/java.base/share/classes/java/util/concurrent/ThreadPerTaskExecutor.java @@ -26,7 +26,6 @@ import java.lang.invoke.MethodHandles; import java.lang.invoke.VarHandle; -import java.security.Permission; import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; @@ -48,7 +47,6 @@ */ class ThreadPerTaskExecutor extends ThreadContainer implements ExecutorService { private static final JavaLangAccess JLA = SharedSecrets.getJavaLangAccess(); - private static final Permission MODIFY_THREAD = new RuntimePermission("modifyThread"); private static final VarHandle STATE = MhUtil.findVarHandle( MethodHandles.lookup(), "state", int.class); @@ -80,18 +78,6 @@ static ThreadPerTaskExecutor create(ThreadFactory factory) { return executor; } - /** - * Throws SecurityException if there is a security manager set and it denies - * RuntimePermission("modifyThread"). - */ - @SuppressWarnings("removal") - private void checkPermission() { - SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - sm.checkPermission(MODIFY_THREAD); - } - } - /** * Throws RejectedExecutionException if the executor has been shutdown. */ @@ -143,14 +129,12 @@ public long threadCount() { @Override public void shutdown() { - checkPermission(); if (!isShutdown()) tryShutdownAndTerminate(false); } @Override public List shutdownNow() { - checkPermission(); if (!isTerminated()) tryShutdownAndTerminate(true); return List.of(); @@ -202,7 +186,6 @@ private void awaitTermination() { @Override public void close() { - checkPermission(); awaitTermination(); } diff --git a/src/java.base/share/classes/java/util/concurrent/ThreadPoolExecutor.java b/src/java.base/share/classes/java/util/concurrent/ThreadPoolExecutor.java index 65217849f19..e34810fe966 100644 --- a/src/java.base/share/classes/java/util/concurrent/ThreadPoolExecutor.java +++ b/src/java.base/share/classes/java/util/concurrent/ThreadPoolExecutor.java @@ -566,29 +566,6 @@ private void decrementWorkerCount() { private static final RejectedExecutionHandler defaultHandler = new AbortPolicy(); - /** - * Permission required for callers of shutdown and shutdownNow. - * We additionally require (see checkShutdownAccess) that callers - * have permission to actually interrupt threads in the worker set - * (as governed by Thread.interrupt, which relies on - * ThreadGroup.checkAccess, which in turn relies on - * SecurityManager.checkAccess). Shutdowns are attempted only if - * these checks pass. - * - * All actual invocations of Thread.interrupt (see - * interruptIdleWorkers and interruptWorkers) ignore - * SecurityExceptions, meaning that the attempted interrupts - * silently fail. In the case of shutdown, they should not fail - * unless the SecurityManager has inconsistent policies, sometimes - * allowing access to a thread and sometimes not. In such cases, - * failure to actually interrupt threads may disable or delay full - * termination. Other uses of interruptIdleWorkers are advisory, - * and failure to actually interrupt will merely delay response to - * configuration changes so is not handled exceptionally. - */ - private static final RuntimePermission shutdownPerm = - new RuntimePermission("modifyThread"); - /** * Class Worker mainly maintains interrupt control state for * threads running tasks, along with other minor bookkeeping. @@ -673,10 +650,7 @@ protected boolean tryRelease(int unused) { void interruptIfStarted() { Thread t; if (getState() >= 0 && (t = thread) != null && !t.isInterrupted()) { - try { - t.interrupt(); - } catch (SecurityException ignore) { - } + t.interrupt(); } } } @@ -749,27 +723,7 @@ final void tryTerminate() { */ /** - * If there is a security manager, makes sure caller has - * permission to shut down threads in general (see shutdownPerm). - * If this passes, additionally makes sure the caller is allowed - * to interrupt each worker thread. This might not be true even if - * first check passed, if the SecurityManager treats some threads - * specially. - */ - private void checkShutdownAccess() { - // assert mainLock.isHeldByCurrentThread(); - @SuppressWarnings("removal") - SecurityManager security = System.getSecurityManager(); - if (security != null) { - security.checkPermission(shutdownPerm); - for (Worker w : workers) - security.checkAccess(w.thread); - } - } - - /** - * Interrupts all threads, even if active. Ignores SecurityExceptions - * (in which case some threads may remain uninterrupted). + * Interrupts all threads, even if active. */ private void interruptWorkers() { // assert mainLock.isHeldByCurrentThread(); @@ -780,9 +734,7 @@ private void interruptWorkers() { /** * Interrupts threads that might be waiting for tasks (as * indicated by not being locked) so they can check for - * termination or configuration changes. Ignores - * SecurityExceptions (in which case some threads may remain - * uninterrupted). + * termination or configuration changes. * * @param onlyOne If true, interrupt at most one worker. This is * called only from tryTerminate when termination is otherwise @@ -805,7 +757,6 @@ private void interruptIdleWorkers(boolean onlyOne) { if (!t.isInterrupted() && w.tryLock()) { try { t.interrupt(); - } catch (SecurityException ignore) { } finally { w.unlock(); } @@ -1390,7 +1341,6 @@ public void shutdown() { final ReentrantLock mainLock = this.mainLock; mainLock.lock(); try { - checkShutdownAccess(); advanceRunState(SHUTDOWN); interruptIdleWorkers(); onShutdown(); // hook for ScheduledThreadPoolExecutor @@ -1420,7 +1370,6 @@ public List shutdownNow() { final ReentrantLock mainLock = this.mainLock; mainLock.lock(); try { - checkShutdownAccess(); advanceRunState(STOP); interruptWorkers(); tasks = drainQueue(); diff --git a/src/java.base/share/classes/java/util/concurrent/atomic/AtomicIntegerFieldUpdater.java b/src/java.base/share/classes/java/util/concurrent/atomic/AtomicIntegerFieldUpdater.java index 6d412315153..e01b3ec7d50 100644 --- a/src/java.base/share/classes/java/util/concurrent/atomic/AtomicIntegerFieldUpdater.java +++ b/src/java.base/share/classes/java/util/concurrent/atomic/AtomicIntegerFieldUpdater.java @@ -37,9 +37,6 @@ import java.lang.reflect.Field; import java.lang.reflect.Modifier; -import java.security.AccessController; -import java.security.PrivilegedActionException; -import java.security.PrivilegedExceptionAction; import java.util.function.IntBinaryOperator; import java.util.function.IntUnaryOperator; import jdk.internal.misc.Unsafe; @@ -385,30 +382,16 @@ private static final class AtomicIntegerFieldUpdaterImpl /** class holding the field */ private final Class tclass; - @SuppressWarnings("removal") AtomicIntegerFieldUpdaterImpl(final Class tclass, final String fieldName, final Class caller) { final Field field; final int modifiers; try { - field = AccessController.doPrivileged( - new PrivilegedExceptionAction() { - public Field run() throws NoSuchFieldException { - return tclass.getDeclaredField(fieldName); - } - }); + field = tclass.getDeclaredField(fieldName); modifiers = field.getModifiers(); sun.reflect.misc.ReflectUtil.ensureMemberAccess( caller, tclass, null, modifiers); - ClassLoader cl = tclass.getClassLoader(); - ClassLoader ccl = caller.getClassLoader(); - if ((ccl != null) && (ccl != cl) && - ((cl == null) || !isAncestor(cl, ccl))) { - sun.reflect.misc.ReflectUtil.checkPackageAccess(tclass); - } - } catch (PrivilegedActionException pae) { - throw new RuntimeException(pae.getException()); } catch (Exception ex) { throw new RuntimeException(ex); } diff --git a/src/java.base/share/classes/java/util/concurrent/atomic/AtomicLongFieldUpdater.java b/src/java.base/share/classes/java/util/concurrent/atomic/AtomicLongFieldUpdater.java index 0e496dbd6a5..57722f33371 100644 --- a/src/java.base/share/classes/java/util/concurrent/atomic/AtomicLongFieldUpdater.java +++ b/src/java.base/share/classes/java/util/concurrent/atomic/AtomicLongFieldUpdater.java @@ -37,9 +37,6 @@ import java.lang.reflect.Field; import java.lang.reflect.Modifier; -import java.security.AccessController; -import java.security.PrivilegedActionException; -import java.security.PrivilegedExceptionAction; import java.util.function.LongBinaryOperator; import java.util.function.LongUnaryOperator; import jdk.internal.misc.Unsafe; @@ -381,29 +378,15 @@ private static final class CASUpdater extends AtomicLongFieldUpdater { /** class holding the field */ private final Class tclass; - @SuppressWarnings("removal") CASUpdater(final Class tclass, final String fieldName, final Class caller) { final Field field; final int modifiers; try { - field = AccessController.doPrivileged( - new PrivilegedExceptionAction() { - public Field run() throws NoSuchFieldException { - return tclass.getDeclaredField(fieldName); - } - }); + field = tclass.getDeclaredField(fieldName); modifiers = field.getModifiers(); sun.reflect.misc.ReflectUtil.ensureMemberAccess( caller, tclass, null, modifiers); - ClassLoader cl = tclass.getClassLoader(); - ClassLoader ccl = caller.getClassLoader(); - if ((ccl != null) && (ccl != cl) && - ((cl == null) || !isAncestor(cl, ccl))) { - sun.reflect.misc.ReflectUtil.checkPackageAccess(tclass); - } - } catch (PrivilegedActionException pae) { - throw new RuntimeException(pae.getException()); } catch (Exception ex) { throw new RuntimeException(ex); } diff --git a/src/java.base/share/classes/java/util/concurrent/atomic/AtomicReferenceArray.java b/src/java.base/share/classes/java/util/concurrent/atomic/AtomicReferenceArray.java index ec00f40a568..dbec6b81dd9 100644 --- a/src/java.base/share/classes/java/util/concurrent/atomic/AtomicReferenceArray.java +++ b/src/java.base/share/classes/java/util/concurrent/atomic/AtomicReferenceArray.java @@ -329,20 +329,12 @@ private void readObject(java.io.ObjectInputStream s) throw new java.io.InvalidObjectException("Not array type"); if (a.getClass() != Object[].class) a = Arrays.copyOf((Object[])a, Array.getLength(a), Object[].class); - @SuppressWarnings("removal") - Field arrayField = java.security.AccessController.doPrivileged( - (java.security.PrivilegedAction) () -> { - try { - Field f = AtomicReferenceArray.class - .getDeclaredField("array"); - f.setAccessible(true); - return f; - } catch (ReflectiveOperationException e) { - throw new Error(e); - }}); try { + + Field arrayField = AtomicReferenceArray.class.getDeclaredField("array"); + arrayField.setAccessible(true); arrayField.set(this, a); - } catch (IllegalAccessException e) { + } catch (NoSuchFieldException | IllegalAccessException e) { throw new Error(e); } } diff --git a/src/java.base/share/classes/java/util/concurrent/atomic/AtomicReferenceFieldUpdater.java b/src/java.base/share/classes/java/util/concurrent/atomic/AtomicReferenceFieldUpdater.java index b9dcdac9ba5..1c0c6d0afd0 100644 --- a/src/java.base/share/classes/java/util/concurrent/atomic/AtomicReferenceFieldUpdater.java +++ b/src/java.base/share/classes/java/util/concurrent/atomic/AtomicReferenceFieldUpdater.java @@ -37,9 +37,6 @@ import java.lang.reflect.Field; import java.lang.reflect.Modifier; -import java.security.AccessController; -import java.security.PrivilegedActionException; -import java.security.PrivilegedExceptionAction; import java.util.function.BinaryOperator; import java.util.function.UnaryOperator; import jdk.internal.misc.Unsafe; @@ -320,7 +317,6 @@ private static final class AtomicReferenceFieldUpdaterImpl * screenings fail. */ - @SuppressWarnings("removal") AtomicReferenceFieldUpdaterImpl(final Class tclass, final Class vclass, final String fieldName, @@ -329,24 +325,11 @@ private static final class AtomicReferenceFieldUpdaterImpl final Class fieldClass; final int modifiers; try { - field = AccessController.doPrivileged( - new PrivilegedExceptionAction() { - public Field run() throws NoSuchFieldException { - return tclass.getDeclaredField(fieldName); - } - }); + field = tclass.getDeclaredField(fieldName); modifiers = field.getModifiers(); sun.reflect.misc.ReflectUtil.ensureMemberAccess( caller, tclass, null, modifiers); - ClassLoader cl = tclass.getClassLoader(); - ClassLoader ccl = caller.getClassLoader(); - if ((ccl != null) && (ccl != cl) && - ((cl == null) || !isAncestor(cl, ccl))) { - sun.reflect.misc.ReflectUtil.checkPackageAccess(tclass); - } fieldClass = field.getType(); - } catch (PrivilegedActionException pae) { - throw new RuntimeException(pae.getException()); } catch (Exception ex) { throw new RuntimeException(ex); } diff --git a/src/java.base/share/classes/java/util/concurrent/atomic/Striped64.java b/src/java.base/share/classes/java/util/concurrent/atomic/Striped64.java index 04ae2b45158..ad230f62ab6 100644 --- a/src/java.base/share/classes/java/util/concurrent/atomic/Striped64.java +++ b/src/java.base/share/classes/java/util/concurrent/atomic/Striped64.java @@ -380,17 +380,12 @@ else if (casBase(v = base, apply(fn, v, x))) BASE = MhUtil.findVarHandle(l1, "base", long.class); CELLSBUSY = MhUtil.findVarHandle(l1, "cellsBusy", int.class); - @SuppressWarnings("removal") - MethodHandles.Lookup l2 = java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction<>() { - public MethodHandles.Lookup run() { - try { - return MethodHandles.privateLookupIn(Thread.class, MethodHandles.lookup()); - } catch (ReflectiveOperationException e) { - throw new ExceptionInInitializerError(e); - } - }}); - THREAD_PROBE = MhUtil.findVarHandle(l2, "threadLocalRandomProbe", int.class); + try { + MethodHandles.Lookup l2 = MethodHandles.privateLookupIn(Thread.class, l1); + THREAD_PROBE = MhUtil.findVarHandle(l2, "threadLocalRandomProbe", int.class); + } catch (ReflectiveOperationException e) { + throw new ExceptionInInitializerError(e); + } } } From 276251c44a1a5b9dc36b27ecbaed37de62fc7558 Mon Sep 17 00:00:00 2001 From: Roman Kennke Date: Fri, 15 Nov 2024 21:21:03 +0000 Subject: [PATCH 031/311] 8342826: Improve performance of oopDesc::klass() after JDK-8305895 Reviewed-by: coleenp, shade, mli --- src/hotspot/share/oops/objLayout.cpp | 50 ++++++++++++++++ src/hotspot/share/oops/objLayout.hpp | 66 +++++++++++++++++++++ src/hotspot/share/oops/objLayout.inline.hpp | 48 +++++++++++++++ src/hotspot/share/oops/oop.cpp | 4 -- src/hotspot/share/oops/oop.hpp | 15 ++--- src/hotspot/share/oops/oop.inline.hpp | 56 +++++++++-------- src/hotspot/share/runtime/arguments.cpp | 2 + 7 files changed, 202 insertions(+), 39 deletions(-) create mode 100644 src/hotspot/share/oops/objLayout.cpp create mode 100644 src/hotspot/share/oops/objLayout.hpp create mode 100644 src/hotspot/share/oops/objLayout.inline.hpp diff --git a/src/hotspot/share/oops/objLayout.cpp b/src/hotspot/share/oops/objLayout.cpp new file mode 100644 index 00000000000..3d18d319ed2 --- /dev/null +++ b/src/hotspot/share/oops/objLayout.cpp @@ -0,0 +1,50 @@ +/* + * Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#include "precompiled.hpp" +#include "oops/markWord.hpp" +#include "oops/objLayout.hpp" +#include "runtime/globals.hpp" +#include "utilities/debug.hpp" + +ObjLayout::Mode ObjLayout::_klass_mode = ObjLayout::Undefined; +int ObjLayout::_oop_base_offset_in_bytes = 0; +bool ObjLayout::_oop_has_klass_gap = false; + +void ObjLayout::initialize() { + assert(_klass_mode == Undefined, "ObjLayout initialized twice"); + if (UseCompactObjectHeaders) { + _klass_mode = Compact; + _oop_base_offset_in_bytes = sizeof(markWord); + _oop_has_klass_gap = false; + } else if (UseCompressedClassPointers) { + _klass_mode = Compressed; + _oop_base_offset_in_bytes = sizeof(markWord) + sizeof(narrowKlass); + _oop_has_klass_gap = true; + } else { + _klass_mode = Uncompressed; + _oop_base_offset_in_bytes = sizeof(markWord) + sizeof(Klass*); + _oop_has_klass_gap = false; + } +} diff --git a/src/hotspot/share/oops/objLayout.hpp b/src/hotspot/share/oops/objLayout.hpp new file mode 100644 index 00000000000..e434524d4b0 --- /dev/null +++ b/src/hotspot/share/oops/objLayout.hpp @@ -0,0 +1,66 @@ +/* + * Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#ifndef SHARE_OOPS_OBJLAYOUT_HPP +#define SHARE_OOPS_OBJLAYOUT_HPP + +/* + * This class helps to avoid loading more than one flag in some + * operations that require checking UseCompressedClassPointers, + * UseCompactObjectHeaders and possibly more. + * + * This is important on some performance critical paths, e.g. where + * the Klass* is accessed frequently, especially by GC oop iterators + * and stack-trace builders. + */ +class ObjLayout { +public: + enum Mode { + // +UseCompactObjectHeaders (implies +UseCompressedClassPointers) + Compact, + // +UseCompressedClassPointers (-UseCompactObjectHeaders) + Compressed, + // -UseCompressedClassPointers (-UseCompactObjectHeaders) + Uncompressed, + // Not yet initialized + Undefined + }; + +private: + static Mode _klass_mode; + static int _oop_base_offset_in_bytes; + static bool _oop_has_klass_gap; + +public: + static void initialize(); + static inline Mode klass_mode(); + static inline int oop_base_offset_in_bytes() { + return _oop_base_offset_in_bytes; + } + static inline bool oop_has_klass_gap() { + return _oop_has_klass_gap; + } +}; + +#endif // SHARE_OOPS_OBJLAYOUT_HPP diff --git a/src/hotspot/share/oops/objLayout.inline.hpp b/src/hotspot/share/oops/objLayout.inline.hpp new file mode 100644 index 00000000000..677c1a933bd --- /dev/null +++ b/src/hotspot/share/oops/objLayout.inline.hpp @@ -0,0 +1,48 @@ +/* + * Copyright Amazon.com Inc. or its affiliates. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#ifndef SHARE_OOPS_OBJLAYOUT_INLINE_HPP +#define SHARE_OOPS_OBJLAYOUT_INLINE_HPP + +#include "oops/objLayout.hpp" + +inline ObjLayout::Mode ObjLayout::klass_mode() { +#ifdef ASSERT + assert(_klass_mode != Undefined, "KlassMode not yet initialized"); + if (UseCompactObjectHeaders) { + assert(_klass_mode == Compact, "Klass mode does not match flags"); + } else if (UseCompressedClassPointers) { + assert(_klass_mode == Compressed, "Klass mode does not match flags"); + } else { + assert(_klass_mode == Uncompressed, "Klass mode does not match flags"); + } +#endif +#ifdef _LP64 + return _klass_mode; +#else + return Uncompressed; +#endif +} + +#endif // SHARE_OOPS_OBJLAYOUT_INLINE_HPP diff --git a/src/hotspot/share/oops/oop.cpp b/src/hotspot/share/oops/oop.cpp index 9385379a617..11cab4c043b 100644 --- a/src/hotspot/share/oops/oop.cpp +++ b/src/hotspot/share/oops/oop.cpp @@ -152,10 +152,6 @@ bool oopDesc::is_array_noinline() const { return is_array(); } bool oopDesc::is_objArray_noinline() const { return is_objArray(); } bool oopDesc::is_typeArray_noinline() const { return is_typeArray(); } -bool oopDesc::has_klass_gap() { - return UseCompressedClassPointers && !UseCompactObjectHeaders; -} - #if INCLUDE_CDS_JAVA_HEAP void oopDesc::set_narrow_klass(narrowKlass nk) { assert(CDSConfig::is_dumping_heap(), "Used by CDS only. Do not abuse!"); diff --git a/src/hotspot/share/oops/oop.hpp b/src/hotspot/share/oops/oop.hpp index 18e421d620c..f52baab0de6 100644 --- a/src/hotspot/share/oops/oop.hpp +++ b/src/hotspot/share/oops/oop.hpp @@ -31,6 +31,7 @@ #include "oops/accessDecorators.hpp" #include "oops/markWord.hpp" #include "oops/metadata.hpp" +#include "oops/objLayout.hpp" #include "runtime/atomic.hpp" #include "utilities/globalDefinitions.hpp" #include "utilities/macros.hpp" @@ -324,7 +325,9 @@ class oopDesc { inline bool mark_must_be_preserved() const; inline bool mark_must_be_preserved(markWord m) const; - static bool has_klass_gap(); + inline static bool has_klass_gap() { + return ObjLayout::oop_has_klass_gap(); + } // for code generation static int mark_offset_in_bytes() { return (int)offset_of(oopDesc, _mark); } @@ -346,15 +349,7 @@ class oopDesc { } static int base_offset_in_bytes() { - if (UseCompactObjectHeaders) { - // With compact headers, the Klass* field is not used for the Klass* - // and is used for the object fields instead. - return sizeof(markWord); - } else if (UseCompressedClassPointers) { - return sizeof(markWord) + sizeof(narrowKlass); - } else { - return sizeof(markWord) + sizeof(Klass*); - } + return ObjLayout::oop_base_offset_in_bytes(); } // for error reporting diff --git a/src/hotspot/share/oops/oop.inline.hpp b/src/hotspot/share/oops/oop.inline.hpp index 098e6bfa90f..45902e63147 100644 --- a/src/hotspot/share/oops/oop.inline.hpp +++ b/src/hotspot/share/oops/oop.inline.hpp @@ -34,6 +34,7 @@ #include "oops/arrayOop.hpp" #include "oops/compressedKlass.inline.hpp" #include "oops/instanceKlass.hpp" +#include "oops/objLayout.inline.hpp" #include "oops/markWord.inline.hpp" #include "oops/oopsHierarchy.hpp" #include "runtime/atomic.hpp" @@ -95,43 +96,48 @@ void oopDesc::init_mark() { } Klass* oopDesc::klass() const { - if (UseCompactObjectHeaders) { - return mark().klass(); - } else if (UseCompressedClassPointers) { - return CompressedKlassPointers::decode_not_null(_metadata._compressed_klass); - } else { - return _metadata._klass; + switch (ObjLayout::klass_mode()) { + case ObjLayout::Compact: + return mark().klass(); + case ObjLayout::Compressed: + return CompressedKlassPointers::decode_not_null(_metadata._compressed_klass); + default: + return _metadata._klass; } } Klass* oopDesc::klass_or_null() const { - if (UseCompactObjectHeaders) { - return mark().klass_or_null(); - } else if (UseCompressedClassPointers) { - return CompressedKlassPointers::decode(_metadata._compressed_klass); - } else { - return _metadata._klass; + switch (ObjLayout::klass_mode()) { + case ObjLayout::Compact: + return mark().klass_or_null(); + case ObjLayout::Compressed: + return CompressedKlassPointers::decode(_metadata._compressed_klass); + default: + return _metadata._klass; } } Klass* oopDesc::klass_or_null_acquire() const { - if (UseCompactObjectHeaders) { - return mark_acquire().klass(); - } else if (UseCompressedClassPointers) { - narrowKlass narrow_klass = Atomic::load_acquire(&_metadata._compressed_klass); - return CompressedKlassPointers::decode(narrow_klass); - } else { - return Atomic::load_acquire(&_metadata._klass); + switch (ObjLayout::klass_mode()) { + case ObjLayout::Compact: + return mark_acquire().klass(); + case ObjLayout::Compressed: { + narrowKlass narrow_klass = Atomic::load_acquire(&_metadata._compressed_klass); + return CompressedKlassPointers::decode(narrow_klass); + } + default: + return Atomic::load_acquire(&_metadata._klass); } } Klass* oopDesc::klass_without_asserts() const { - if (UseCompactObjectHeaders) { - return mark().klass_without_asserts(); - } else if (UseCompressedClassPointers) { - return CompressedKlassPointers::decode_without_asserts(_metadata._compressed_klass); - } else { - return _metadata._klass; + switch (ObjLayout::klass_mode()) { + case ObjLayout::Compact: + return mark().klass_without_asserts(); + case ObjLayout::Compressed: + return CompressedKlassPointers::decode_without_asserts(_metadata._compressed_klass); + default: + return _metadata._klass; } } diff --git a/src/hotspot/share/runtime/arguments.cpp b/src/hotspot/share/runtime/arguments.cpp index e9262a48086..7b8604659a0 100644 --- a/src/hotspot/share/runtime/arguments.cpp +++ b/src/hotspot/share/runtime/arguments.cpp @@ -46,6 +46,7 @@ #include "nmt/nmtCommon.hpp" #include "oops/compressedKlass.hpp" #include "oops/instanceKlass.hpp" +#include "oops/objLayout.hpp" #include "oops/oop.inline.hpp" #include "prims/jvmtiAgentList.hpp" #include "prims/jvmtiExport.hpp" @@ -3673,6 +3674,7 @@ jint Arguments::parse(const JavaVMInitArgs* initial_cmd_args) { if (UseCompactObjectHeaders && !UseCompressedClassPointers) { FLAG_SET_DEFAULT(UseCompressedClassPointers, true); } + ObjLayout::initialize(); #endif return JNI_OK; From 41a2d49f0a1ed298b8ab023ce634335464454fe7 Mon Sep 17 00:00:00 2001 From: Ioi Lam Date: Fri, 15 Nov 2024 22:28:54 +0000 Subject: [PATCH 032/311] 8331497: Implement JEP 483: Ahead-of-Time Class Loading & Linking Reviewed-by: jrose, kvn, heidinga, asmehra, vlivanov --- make/RunTests.gmk | 72 +- src/hotspot/share/cds/aotClassInitializer.cpp | 359 ++++++++ src/hotspot/share/cds/aotClassInitializer.hpp | 46 + src/hotspot/share/cds/aotClassLinker.cpp | 319 +++++++ src/hotspot/share/cds/aotClassLinker.hpp | 129 +++ .../share/cds/aotConstantPoolResolver.cpp | 573 ++++++++++++ ...linker.hpp => aotConstantPoolResolver.hpp} | 40 +- .../share/cds/aotLinkedClassBulkLoader.cpp | 397 ++++++++ .../share/cds/aotLinkedClassBulkLoader.hpp | 69 ++ src/hotspot/share/cds/aotLinkedClassTable.cpp | 40 + src/hotspot/share/cds/aotLinkedClassTable.hpp | 77 ++ src/hotspot/share/cds/archiveBuilder.cpp | 174 +++- src/hotspot/share/cds/archiveBuilder.hpp | 7 +- src/hotspot/share/cds/archiveHeapLoader.cpp | 4 - src/hotspot/share/cds/archiveHeapWriter.cpp | 18 +- src/hotspot/share/cds/archiveUtils.cpp | 9 + src/hotspot/share/cds/archiveUtils.hpp | 5 + src/hotspot/share/cds/archiveUtils.inline.hpp | 20 +- src/hotspot/share/cds/cdsConfig.cpp | 160 +++- src/hotspot/share/cds/cdsConfig.hpp | 43 +- src/hotspot/share/cds/cdsEnumKlass.cpp | 2 +- src/hotspot/share/cds/cdsHeapVerifier.cpp | 117 ++- src/hotspot/share/cds/cds_globals.hpp | 24 + src/hotspot/share/cds/classListParser.cpp | 34 +- src/hotspot/share/cds/classListWriter.cpp | 30 +- src/hotspot/share/cds/classPrelinker.cpp | 345 ------- src/hotspot/share/cds/dumpAllocStats.cpp | 7 + src/hotspot/share/cds/dumpAllocStats.hpp | 12 + src/hotspot/share/cds/dumpTimeClassInfo.hpp | 12 +- src/hotspot/share/cds/dynamicArchive.cpp | 21 +- src/hotspot/share/cds/filemap.cpp | 78 +- src/hotspot/share/cds/filemap.hpp | 6 +- src/hotspot/share/cds/heapShared.cpp | 856 ++++++++++++++++-- src/hotspot/share/cds/heapShared.hpp | 51 +- src/hotspot/share/cds/lambdaFormInvokers.cpp | 17 +- src/hotspot/share/cds/metaspaceShared.cpp | 107 ++- src/hotspot/share/cds/metaspaceShared.hpp | 6 + src/hotspot/share/cds/runTimeClassInfo.cpp | 2 +- src/hotspot/share/cds/runTimeClassInfo.hpp | 6 +- src/hotspot/share/classfile/classLoader.cpp | 43 +- src/hotspot/share/classfile/classLoader.hpp | 2 + src/hotspot/share/classfile/javaClasses.cpp | 33 +- src/hotspot/share/classfile/javaClasses.hpp | 2 + .../share/classfile/systemDictionary.cpp | 84 +- .../share/classfile/systemDictionary.hpp | 10 + .../classfile/systemDictionaryShared.cpp | 182 +++- .../classfile/systemDictionaryShared.hpp | 8 +- src/hotspot/share/classfile/vmClassMacros.hpp | 3 +- src/hotspot/share/classfile/vmClasses.cpp | 4 + src/hotspot/share/classfile/vmSymbols.hpp | 5 + .../share/interpreter/interpreterRuntime.cpp | 17 + .../share/interpreter/interpreterRuntime.hpp | 7 +- src/hotspot/share/logging/logTag.hpp | 1 + src/hotspot/share/memory/iterator.inline.hpp | 9 +- src/hotspot/share/oops/constantPool.cpp | 104 ++- src/hotspot/share/oops/constantPool.hpp | 10 +- src/hotspot/share/oops/cpCache.cpp | 67 +- src/hotspot/share/oops/cpCache.hpp | 3 +- src/hotspot/share/oops/instanceKlass.cpp | 146 ++- src/hotspot/share/oops/instanceKlass.hpp | 8 + src/hotspot/share/oops/klass.hpp | 24 +- src/hotspot/share/oops/method.cpp | 11 + src/hotspot/share/oops/method.hpp | 1 + src/hotspot/share/prims/jvm.cpp | 2 +- src/hotspot/share/prims/jvmtiExport.cpp | 10 + src/hotspot/share/prims/jvmtiExport.hpp | 1 + src/hotspot/share/runtime/arguments.cpp | 4 + .../share/runtime/flags/jvmFlagAccess.cpp | 13 +- .../flags/jvmFlagConstraintsRuntime.cpp | 17 +- .../flags/jvmFlagConstraintsRuntime.hpp | 3 +- src/hotspot/share/runtime/threads.cpp | 23 + .../share/classes/java/lang/Class.java | 14 + .../java/lang/invoke/LambdaFormEditor.java | 21 +- .../java/lang/invoke/MethodHandleNatives.java | 23 +- .../classes/java/lang/invoke/MethodType.java | 42 + .../java/lang/invoke/MethodTypeForm.java | 63 +- .../java/lang/invoke/StringConcatFactory.java | 2 + .../util/concurrent/ConcurrentHashMap.java | 12 +- .../classes/jdk/internal/misc/Unsafe.java | 5 + test/hotspot/jtreg/ProblemList-AotJdk.txt | 18 + test/hotspot/jtreg/TEST.ROOT | 1 + test/hotspot/jtreg/TEST.groups | 63 ++ .../jtreg/runtime/cds/SharedBaseAddress.java | 21 +- .../jtreg/runtime/cds/appcds/AOTFlags.java | 203 +++++ .../runtime/cds/appcds/ClassPathAttr.java | 17 +- .../cds/appcds/LambdaContainsOldInf.java | 8 +- .../cds/appcds/LambdaWithOldClass.java | 8 +- .../appcds/LambdaWithUseImplMethodHandle.java | 10 +- .../cds/appcds/TestParallelGCWithCDS.java | 1 + .../AOTClassLinkingVMOptions.java | 183 ++++ .../aotClassLinking/BulkLoaderTest.java | 241 +++++ .../InitiatingLoaderTester.jasm | 56 ++ .../cacheObject/ArchiveHeapTestClass.java | 202 ++++- .../customLoader/CustomClassListDump.java | 4 +- .../appcds/jvmti/ClassFileLoadHookTest.java | 20 +- .../OldClassAndRedefineClass.java | 4 +- .../resolvedConstants/AOTLinkedLambdas.java | 388 ++++++++ .../AOTLinkedVarHandles.java | 128 +++ .../resolvedConstants/ResolvedConstants.java | 211 ++++- .../StringConcatTestOld.jasm | 78 ++ .../cds/appcds/test-classes/OldConsumer.jasm | 53 ++ test/jdk/ProblemList-AotJdk.txt | 11 + .../internal/misc/CDS/ArchivedEnumTest.java | 5 +- test/jtreg-ext/requires/VMProps.java | 9 + test/lib/jdk/test/lib/cds/CDSAppTester.java | 53 +- test/lib/jdk/test/lib/cds/CDSTestUtils.java | 26 +- 106 files changed, 6598 insertions(+), 757 deletions(-) create mode 100644 src/hotspot/share/cds/aotClassInitializer.cpp create mode 100644 src/hotspot/share/cds/aotClassInitializer.hpp create mode 100644 src/hotspot/share/cds/aotClassLinker.cpp create mode 100644 src/hotspot/share/cds/aotClassLinker.hpp create mode 100644 src/hotspot/share/cds/aotConstantPoolResolver.cpp rename src/hotspot/share/cds/{classPrelinker.hpp => aotConstantPoolResolver.hpp} (73%) create mode 100644 src/hotspot/share/cds/aotLinkedClassBulkLoader.cpp create mode 100644 src/hotspot/share/cds/aotLinkedClassBulkLoader.hpp create mode 100644 src/hotspot/share/cds/aotLinkedClassTable.cpp create mode 100644 src/hotspot/share/cds/aotLinkedClassTable.hpp delete mode 100644 src/hotspot/share/cds/classPrelinker.cpp create mode 100644 test/hotspot/jtreg/ProblemList-AotJdk.txt create mode 100644 test/hotspot/jtreg/runtime/cds/appcds/AOTFlags.java create mode 100644 test/hotspot/jtreg/runtime/cds/appcds/aotClassLinking/AOTClassLinkingVMOptions.java create mode 100644 test/hotspot/jtreg/runtime/cds/appcds/aotClassLinking/BulkLoaderTest.java create mode 100644 test/hotspot/jtreg/runtime/cds/appcds/aotClassLinking/InitiatingLoaderTester.jasm create mode 100644 test/hotspot/jtreg/runtime/cds/appcds/resolvedConstants/AOTLinkedLambdas.java create mode 100644 test/hotspot/jtreg/runtime/cds/appcds/resolvedConstants/AOTLinkedVarHandles.java create mode 100644 test/hotspot/jtreg/runtime/cds/appcds/resolvedConstants/StringConcatTestOld.jasm create mode 100644 test/hotspot/jtreg/runtime/cds/appcds/test-classes/OldConsumer.jasm create mode 100644 test/jdk/ProblemList-AotJdk.txt diff --git a/make/RunTests.gmk b/make/RunTests.gmk index 747d8f84dbc..636d1ed18b2 100644 --- a/make/RunTests.gmk +++ b/make/RunTests.gmk @@ -45,7 +45,7 @@ ifneq ($(TEST_VM_OPTS), ) endif $(eval $(call ParseKeywordVariable, TEST_OPTS, \ - SINGLE_KEYWORDS := JOBS TIMEOUT_FACTOR JCOV JCOV_DIFF_CHANGESET, \ + SINGLE_KEYWORDS := JOBS TIMEOUT_FACTOR JCOV JCOV_DIFF_CHANGESET AOT_JDK, \ STRING_KEYWORDS := VM_OPTIONS JAVA_OPTIONS, \ )) @@ -202,11 +202,12 @@ $(eval $(call SetTestOpt,JOBS,JTREG)) $(eval $(call SetTestOpt,TIMEOUT_FACTOR,JTREG)) $(eval $(call SetTestOpt,FAILURE_HANDLER_TIMEOUT,JTREG)) $(eval $(call SetTestOpt,REPORT,JTREG)) +$(eval $(call SetTestOpt,AOT_JDK,JTREG)) $(eval $(call ParseKeywordVariable, JTREG, \ SINGLE_KEYWORDS := JOBS TIMEOUT_FACTOR FAILURE_HANDLER_TIMEOUT \ TEST_MODE ASSERT VERBOSE RETAIN TEST_THREAD_FACTORY MAX_MEM RUN_PROBLEM_LISTS \ - RETRY_COUNT REPEAT_COUNT MAX_OUTPUT REPORT $(CUSTOM_JTREG_SINGLE_KEYWORDS), \ + RETRY_COUNT REPEAT_COUNT MAX_OUTPUT REPORT AOT_JDK $(CUSTOM_JTREG_SINGLE_KEYWORDS), \ STRING_KEYWORDS := OPTIONS JAVA_OPTIONS VM_OPTIONS KEYWORDS \ EXTRA_PROBLEM_LISTS LAUNCHER_OPTIONS \ $(CUSTOM_JTREG_STRING_KEYWORDS), \ @@ -702,6 +703,58 @@ define SetJtregValue endif endef + +# Parameter 1 is the name of the rule. +# +# Remaining parameters are named arguments. +# VM_OPTIONS List of JVM arguments to use when creating AOT cache +# +# After calling this, the following variables are defined +# $1_AOT_TARGETS List of all targets that the test rule will need to depend on +# $1_AOT_JDK_CACHE The AOT cache file to be used to run the test with +# +SetupAot = $(NamedParamsMacroTemplate) +define SetupAotBody + $1_AOT_JDK_CONF := $$($1_TEST_SUPPORT_DIR)/aot/jdk.aotconf + $1_AOT_JDK_CACHE := $$($1_TEST_SUPPORT_DIR)/aot/jdk.aotcache + + $1_JAVA_TOOL_OPTS := $$(addprefix -J, $$($1_VM_OPTIONS)) + + $$($1_AOT_JDK_CACHE): $$(JDK_IMAGE_DIR)/release + $$(call MakeDir, $$($1_TEST_SUPPORT_DIR)/aot) + + $(foreach jtool, javac javap jlink jar, \ + $(info AOT: Create cache configuration for $(jtool)) \ + $$(call ExecuteWithLog, $$($1_TEST_SUPPORT_DIR)/aot.$(jtool), ( \ + $$(FIXPATH) $(JDK_UNDER_TEST)/bin/$(jtool) $$($1_JAVA_TOOL_OPTS) \ + -J-XX:AOTMode=record -J-XX:AOTConfiguration=$$($1_AOT_JDK_CONF).$(jtool) --help \ + )) + ) + + $$(info AOT: Copy $(JDK_UNDER_TEST)/lib/classlist to $$($1_AOT_JDK_CONF).jdk ) + $$(call ExecuteWithLog, $$($1_TEST_SUPPORT_DIR)/aot, ( \ + $$(FIXPATH) $(CP) $(JDK_UNDER_TEST)/lib/classlist $$($1_AOT_JDK_CONF).jdk \ + )) + + $$(FIXPATH) $$(CAT) $$($1_AOT_JDK_CONF).* > $$($1_AOT_JDK_CONF).temp + $$(FIXPATH) $$(CAT) $$($1_AOT_JDK_CONF).temp | $(GREP) -v '#' | $(GREP) -v '@' | $(SORT) | \ + $(SED) -e 's/id:.*//g' | uniq \ + > $$($1_AOT_JDK_CONF) + $$(FIXPATH) $$(CAT) $$($1_AOT_JDK_CONF).temp | $(GREP) '@cp' | $(SORT) \ + >> $$($1_AOT_JDK_CONF) + + $$(info AOT: Generate AOT cache $$($1_AOT_JDK_CACHE) with flags: $$($1_VM_OPTIONS)) + $$(call ExecuteWithLog, $$($1_TEST_SUPPORT_DIR)/aot, ( \ + $$(FIXPATH) $(JDK_UNDER_TEST)/bin/java \ + $$($1_VM_OPTIONS) -Xlog:cds,cds+class=debug:file=$$($1_AOT_JDK_CACHE).log \ + -XX:AOTMode=create -XX:AOTConfiguration=$$($1_AOT_JDK_CONF) -XX:AOTCache=$$($1_AOT_JDK_CACHE) \ + )) + + $1_AOT_TARGETS += $$($1_AOT_JDK_CACHE) + +endef + + SetupRunJtregTest = $(NamedParamsMacroTemplate) define SetupRunJtregTestBody $1_TEST_RESULTS_DIR := $$(TEST_RESULTS_DIR)/$1 @@ -762,6 +815,7 @@ define SetupRunJtregTestBody JTREG_RETRY_COUNT ?= 0 JTREG_REPEAT_COUNT ?= 0 JTREG_REPORT ?= files + JTREG_AOT_JDK ?= false ifneq ($$(JTREG_RETRY_COUNT), 0) ifneq ($$(JTREG_REPEAT_COUNT), 0) @@ -891,6 +945,17 @@ define SetupRunJtregTestBody endif endif + ifeq ($$(JTREG_AOT_JDK), true) + $$(info Add AOT target for $1) + $$(eval $$(call SetupAot, $1, VM_OPTIONS := $$(JTREG_ALL_OPTIONS) )) + + $$(info AOT_TARGETS=$$($1_AOT_TARGETS)) + $$(info AOT_JDK_CACHE=$$($1_AOT_JDK_CACHE)) + + $1_JTREG_BASIC_OPTIONS += -vmoption:-XX:AOTCache="$$($1_AOT_JDK_CACHE)" + endif + + $$(eval $$(call SetupRunJtregTestCustom, $1)) # SetupRunJtregTestCustom might also adjust JTREG_AUTO_ variables @@ -906,6 +971,7 @@ define SetupRunJtregTestBody JTREG_TIMEOUT_FACTOR ?= $$(JTREG_AUTO_TIMEOUT_FACTOR) clean-outputdirs-$1: + $$(call LogWarn, Clean up dirs for $1) $$(RM) -r $$($1_TEST_SUPPORT_DIR) $$(RM) -r $$($1_TEST_RESULTS_DIR) @@ -953,7 +1019,7 @@ define SetupRunJtregTestBody done endif - run-test-$1: pre-run-test clean-outputdirs-$1 + run-test-$1: clean-outputdirs-$1 pre-run-test $$($1_AOT_TARGETS) $$(call LogWarn) $$(call LogWarn, Running test '$$($1_TEST)') $$(call MakeDir, $$($1_TEST_RESULTS_DIR) $$($1_TEST_SUPPORT_DIR) \ diff --git a/src/hotspot/share/cds/aotClassInitializer.cpp b/src/hotspot/share/cds/aotClassInitializer.cpp new file mode 100644 index 00000000000..b09dfcde6b1 --- /dev/null +++ b/src/hotspot/share/cds/aotClassInitializer.cpp @@ -0,0 +1,359 @@ +/* + * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#include "precompiled.hpp" +#include "cds/aotClassInitializer.hpp" +#include "cds/archiveBuilder.hpp" +#include "cds/cdsConfig.hpp" +#include "cds/heapShared.hpp" +#include "classfile/vmSymbols.hpp" +#include "oops/instanceKlass.inline.hpp" +#include "oops/symbol.hpp" +#include "runtime/javaCalls.hpp" + +// Detector for class names we wish to handle specially. +// It is either an exact string match or a string prefix match. +class AOTClassInitializer::AllowedSpec { + const char* _class_name; + bool _is_prefix; + int _len; +public: + AllowedSpec(const char* class_name, bool is_prefix = false) + : _class_name(class_name), _is_prefix(is_prefix) + { + _len = (class_name == nullptr) ? 0 : (int)strlen(class_name); + } + const char* class_name() { return _class_name; } + + bool matches(Symbol* name, int len) { + assert(_class_name != nullptr, "caller resp."); + if (_is_prefix) { + return len >= _len && name->starts_with(_class_name); + } else { + return len == _len && name->equals(_class_name); + } + } +}; + + +// Tell if ik has a name that matches one of the given specs. +bool AOTClassInitializer::is_allowed(AllowedSpec* specs, InstanceKlass* ik) { + Symbol* name = ik->name(); + int len = name->utf8_length(); + for (AllowedSpec* s = specs; s->class_name() != nullptr; s++) { + if (s->matches(name, len)) { + // If a type is included in the tables inside can_archive_initialized_mirror(), we require that + // - all super classes must be included + // - all super interfaces that have must be included. + // This ensures that in the production run, we don't run the of a supertype but skips + // ik's . + if (ik->java_super() != nullptr) { + DEBUG_ONLY(ResourceMark rm); + assert(AOTClassInitializer::can_archive_initialized_mirror(ik->java_super()), + "super class %s of %s must be aot-initialized", ik->java_super()->external_name(), + ik->external_name()); + } + + Array* interfaces = ik->local_interfaces(); + int len = interfaces->length(); + for (int i = 0; i < len; i++) { + InstanceKlass* intf = interfaces->at(i); + if (intf->class_initializer() != nullptr) { + assert(AOTClassInitializer::can_archive_initialized_mirror(intf), + "super interface %s (which has ) of %s must be aot-initialized", intf->external_name(), + ik->external_name()); + } + } + + return true; + } + } + return false; +} + + +bool AOTClassInitializer::can_archive_initialized_mirror(InstanceKlass* ik) { + assert(!ArchiveBuilder::current()->is_in_buffer_space(ik), "must be source klass"); + if (!CDSConfig::is_initing_classes_at_dump_time()) { + return false; + } + + if (!ik->is_initialized()) { + return false; + } + + if (ik->is_hidden()) { + return HeapShared::is_archivable_hidden_klass(ik); + } + + if (ik->is_enum_subclass()) { + return true; + } + + // About "static field that may hold a different value" errors: + // + // Automatic selection for aot-inited classes + // ========================================== + // + // When CDSConfig::is_initing_classes_at_dump_time() is enabled, + // HeapShared::find_all_aot_initialized_classes() finds the classes of all + // heap objects that are reachable from HeapShared::_run_time_special_subgraph, + // and mark these classes as aot-inited. This preserves the initialized + // mirrors of these classes, and their methods are NOT executed + // at runtime. + // + // For example, with -XX:+AOTInvokeDynamicLinking, _run_time_special_subgraph + // will contain some DirectMethodHandle objects. As a result, the DirectMethodHandle + // class is automatically marked as aot-inited. + // + // When a class is aot-inited, its static fields are already set up + // by executing the method at AOT assembly time. Later on + // in the production run, when the class would normally be + // initialized, the VM performs guarding and synchronization as if + // it were going to run the again, but instead it simply + // observes that that class was aot-inited. The VM assumes that, if + // it were to run again, it would get a semantically + // equivalent set of final field values, so it just adopts the + // existing field values (from AOT assembly) and skips the call to + // . There may at that point be fixups performed by ad hoc + // code, if the VM recognizes a request in the library. + // + // It is true that this is not generally correct for all possible + // Java code. A method might have a side effect beyond + // initializing the static fields. It might send an email somewhere + // noting the current time of day. In that case, such an email + // would have been sent during the AOT assembly phase, and the email + // would NOT be sent again during production. This is clearly NOT + // what a user would want, if this were a general purpose facility. + // But in fact it is only for certain well-behaved classes, which + // are known NOT to have such side effects. We know this because + // the optimization (of skipping for aot-init classes) is + // only applied to classes fully defined by the JDK. + // + // (A day may come when we figure out how to gracefully extend this + // optimization to untrusted third parties, but it is not this day.) + // + // Manual selection + // ================ + // + // There are important cases where one aot-init class has a side + // effect on another aot-class, a side effect which is not captured + // in any static field value in either class. The simplest example + // is class A forces the initialization of class B. In that case, + // we need to aot-init either both classes or neither. From looking + // at the JDK state after AOT assembly is done, it is hard to tell + // that A "touched" B and B might escape our notice. Another common + // example is A copying a field value from B. We don't know where A + // got the value, but it would be wrong to re-initialize B at + // startup, while keeping the snapshot of the old B value in A. In + // general, if we aot-init A, we need to aot-init every class B that + // somehow contributed to A's initial state, and every class C that + // was somehow side-effected by A's initialization. We say that the + // aot-init of A is "init-coupled" to those of B and C. + // + // So there are init-coupled classes that cannot be automatically discovered. For + // example, DirectMethodHandle::IMPL_NAMES points to MethodHandles::IMPL_NAMES, + // but the MethodHandles class is not automatically marked because there are + // no archived instances of the MethodHandles type. + // + // If we aot-initialize DirectMethodHandle, but allow MethodHandles to be + // initialized at runtime, MethodHandles::IMPL_NAMES will get a different + // value than DirectMethodHandle::IMPL_NAMES. This *may or may not* be a problem, + // but to ensure compatibility, we should try to preserve the identity equality + // of these two fields. + // + // To do that, we add MethodHandles to the indy_specs[] table below. + // + // Luckily we do not need to be all-knowing in order to choose which + // items to add to that table. We have tools to help detect couplings. + // + // Automatic validation + // ==================== + // + // CDSHeapVerifier is used to detect potential problems with identity equality. + // + // A class B is assumed to be init-coupled to some aot-init class if + // B has a field which points to a live object X in the AOT heap. + // The live object X was created by some other class A which somehow + // used B's reference to X, perhaps with the help of an intermediate + // class Z. Or, B pulled the reference to X from some other class + // Y, and B obtained that reference from Y (or an intermediate Z). + // It is not certain how X got into the heap, nor whether B + // contributed it, but it is a good heuristic that B is init-coupled + // to X's class or some other aot-init class. In any case, B should + // be made an aot-init class as well, unless a manual inspection + // shows that would be a problem. If there is a problem, then the + // JDK code for B and/or X probably needs refactoring. If there is + // no problem, we add B to the list. Typically the same scan will + // find any other accomplices Y, Z, etc. One failure would be a + // class Q whose only initialization action is to scribble a special + // value into B, from which the value X is derived and then makes + // its way into the heap. In that case, the heuristic does not + // identify Q. It is (currently) a human responsibility, of JDK + // engineers, not to write such dirty JDK code, or to repair it if + // it crops up. Eventually we may have tools, or even a user mode + // with design rules and checks, that will vet our code base more + // automatically. + // + // To see how the tool detects the problem with MethodHandles::IMPL_NAMES: + // + // - Comment out all the lines in indy_specs[] except the {nullptr} line. + // - Rebuild the JDK + // + // Then run the following: + // java -XX:AOTMode=record -XX:AOTConfiguration=jc.aotconfig com.sun.tools.javac.Main + // java -XX:AOTMode=create -Xlog:cds -XX:AOTCache=jc.aot -XX:AOTConfiguration=jc.aotconfig + // + // You will see an error like this: + // + // Archive heap points to a static field that may hold a different value at runtime: + // Field: java/lang/invoke/MethodHandles::IMPL_NAMES + // Value: java.lang.invoke.MemberName$Factory + // {0x000000060e906ae8} - klass: 'java/lang/invoke/MemberName$Factory' - flags: + // + // - ---- fields (total size 2 words): + // --- trace begin --- + // [ 0] {0x000000060e8deeb0} java.lang.Class (java.lang.invoke.DirectMethodHandle::IMPL_NAMES) + // [ 1] {0x000000060e906ae8} java.lang.invoke.MemberName$Factory + // --- trace end --- + // + // Trouble-shooting + // ================ + // + // If you see a "static field that may hold a different value" error, it's probably + // because you've made some changes in the JDK core libraries (most likely + // java.lang.invoke). + // + // - Did you add a new static field to a class that could be referenced by + // cached object instances of MethodType, MethodHandle, etc? You may need + // to add that class to indy_specs[]. + // - Did you modify the of the classes in java.lang.invoke such that + // a static field now points to an object that should not be cached (e.g., + // a native resource such as a file descriptior, or a Thread)? + // + // Note that these potential problems only occur when one class gets + // the aot-init treatment, AND another class is init-coupled to it, + // AND the coupling is not detected. Currently there are a number + // classes that get the aot-init treatment, in java.lang.invoke + // because of invokedynamic. They are few enough for now to be + // manually tracked. There may be more in the future. + + // IS_PREFIX means that we match all class names that start with a + // prefix. Otherwise, it is an exact match, of just one class name. + const bool IS_PREFIX = true; + + { + static AllowedSpec specs[] = { + // everybody's favorite super + {"java/lang/Object"}, + + // above we selected all enums; we must include their super as well + {"java/lang/Enum"}, + {nullptr} + }; + if (is_allowed(specs, ik)) { + return true; + } + } + + if (CDSConfig::is_dumping_invokedynamic()) { + // This table was created with the help of CDSHeapVerifier. + // Also, some $Holder classes are needed. E.g., Invokers. explicitly + // initializes Invokers$Holder. Since Invokers. won't be executed + // at runtime, we need to make sure Invokers$Holder is also aot-inited. + // + // We hope we can reduce the size of this list over time, and move + // the responsibility for identifying such classes into the JDK + // code itself. See tracking RFE JDK-8342481. + static AllowedSpec indy_specs[] = { + {"java/lang/constant/ConstantDescs"}, + {"java/lang/constant/DynamicConstantDesc"}, + {"java/lang/invoke/BoundMethodHandle"}, + {"java/lang/invoke/BoundMethodHandle$Specializer"}, + {"java/lang/invoke/BoundMethodHandle$Species_", IS_PREFIX}, + {"java/lang/invoke/ClassSpecializer"}, + {"java/lang/invoke/ClassSpecializer$", IS_PREFIX}, + {"java/lang/invoke/DelegatingMethodHandle"}, + {"java/lang/invoke/DelegatingMethodHandle$Holder"}, // UNSAFE.ensureClassInitialized() + {"java/lang/invoke/DirectMethodHandle"}, + {"java/lang/invoke/DirectMethodHandle$Constructor"}, + {"java/lang/invoke/DirectMethodHandle$Holder"}, // UNSAFE.ensureClassInitialized() + {"java/lang/invoke/Invokers"}, + {"java/lang/invoke/Invokers$Holder"}, // UNSAFE.ensureClassInitialized() + {"java/lang/invoke/LambdaForm"}, + {"java/lang/invoke/LambdaForm$Holder"}, // UNSAFE.ensureClassInitialized() + {"java/lang/invoke/LambdaForm$NamedFunction"}, + {"java/lang/invoke/MethodHandle"}, + {"java/lang/invoke/MethodHandles"}, + {"java/lang/invoke/SimpleMethodHandle"}, + {"java/util/Collections"}, + {"java/util/stream/Collectors"}, + {"jdk/internal/constant/ConstantUtils"}, + {"jdk/internal/constant/PrimitiveClassDescImpl"}, + {"jdk/internal/constant/ReferenceClassDescImpl"}, + + // Can't include this, as it will pull in MethodHandleStatics which has many environment + // dependencies (on system properties, etc). + // MethodHandleStatics is an example of a class that must NOT get the aot-init treatment, + // because of its strong reliance on (a) final fields which are (b) environmentally determined. + //{"java/lang/invoke/InvokerBytecodeGenerator"}, + + {nullptr} + }; + if (is_allowed(indy_specs, ik)) { + return true; + } + } + + return false; +} + +// TODO: currently we have a hard-coded list. We should turn this into +// an annotation: @jdk.internal.vm.annotation.RuntimeSetupRequired +// See JDK-8342481. +bool AOTClassInitializer::is_runtime_setup_required(InstanceKlass* ik) { + return ik == vmClasses::Class_klass() || + ik == vmClasses::internal_Unsafe_klass() || + ik == vmClasses::ConcurrentHashMap_klass(); +} + +void AOTClassInitializer::call_runtime_setup(JavaThread* current, InstanceKlass* ik) { + assert(ik->has_aot_initialized_mirror(), "sanity"); + if (ik->is_runtime_setup_required()) { + if (log_is_enabled(Info, cds, init)) { + ResourceMark rm; + log_info(cds, init)("Calling %s::runtimeSetup()", ik->external_name()); + } + JavaValue result(T_VOID); + JavaCalls::call_static(&result, ik, + vmSymbols::runtimeSetup(), + vmSymbols::void_method_signature(), current); + if (current->has_pending_exception()) { + // We cannot continue, as we might have cached instances of ik in the heap, but propagating the + // exception would cause ik to be in an error state. + AOTLinkedClassBulkLoader::exit_on_exception(current); + } + } +} + diff --git a/src/hotspot/share/cds/aotClassInitializer.hpp b/src/hotspot/share/cds/aotClassInitializer.hpp new file mode 100644 index 00000000000..c8693a0add3 --- /dev/null +++ b/src/hotspot/share/cds/aotClassInitializer.hpp @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#ifndef SHARE_CDS_AOTCLASSINITIALIZER_HPP +#define SHARE_CDS_AOTCLASSINITIALIZER_HPP + +#include "memory/allStatic.hpp" +#include "utilities/exceptions.hpp" + +class InstanceKlass; + +class AOTClassInitializer : AllStatic { + class AllowedSpec; + static bool is_allowed(AllowedSpec* specs, InstanceKlass* ik); + +public: + // Called by heapShared.cpp to see if src_ik->java_mirror() can be archived in + // the initialized state. + static bool can_archive_initialized_mirror(InstanceKlass* src_ik); + + static bool is_runtime_setup_required(InstanceKlass* ik); + static void call_runtime_setup(JavaThread* current, InstanceKlass* ik); +}; + +#endif // SHARE_CDS_AOTCLASSINITIALIZER_HPP diff --git a/src/hotspot/share/cds/aotClassLinker.cpp b/src/hotspot/share/cds/aotClassLinker.cpp new file mode 100644 index 00000000000..8525ce928a8 --- /dev/null +++ b/src/hotspot/share/cds/aotClassLinker.cpp @@ -0,0 +1,319 @@ +/* + * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#include "precompiled.hpp" +#include "cds/aotClassLinker.hpp" +#include "cds/aotConstantPoolResolver.hpp" +#include "cds/aotLinkedClassTable.hpp" +#include "cds/archiveBuilder.hpp" +#include "cds/archiveUtils.inline.hpp" +#include "cds/cdsConfig.hpp" +#include "cds/heapShared.hpp" +#include "cds/lambdaFormInvokers.inline.hpp" +#include "classfile/classLoader.hpp" +#include "classfile/dictionary.hpp" +#include "classfile/systemDictionary.hpp" +#include "classfile/systemDictionaryShared.hpp" +#include "classfile/vmClasses.hpp" +#include "memory/resourceArea.hpp" +#include "oops/constantPool.inline.hpp" +#include "oops/instanceKlass.hpp" +#include "oops/klass.inline.hpp" +#include "runtime/handles.inline.hpp" + +AOTClassLinker::ClassesTable* AOTClassLinker::_vm_classes = nullptr; +AOTClassLinker::ClassesTable* AOTClassLinker::_candidates = nullptr; +GrowableArrayCHeap* AOTClassLinker::_sorted_candidates = nullptr; + +#ifdef ASSERT +bool AOTClassLinker::is_initialized() { + assert(CDSConfig::is_dumping_archive(), "AOTClassLinker is for CDS dumping only"); + return _vm_classes != nullptr; +} +#endif + +void AOTClassLinker::initialize() { + assert(!is_initialized(), "sanity"); + + _vm_classes = new (mtClass)ClassesTable(); + _candidates = new (mtClass)ClassesTable(); + _sorted_candidates = new GrowableArrayCHeap(1000); + + for (auto id : EnumRange{}) { + add_vm_class(vmClasses::klass_at(id)); + } + + assert(is_initialized(), "sanity"); + + AOTConstantPoolResolver::initialize(); +} + +void AOTClassLinker::dispose() { + assert(is_initialized(), "sanity"); + + delete _vm_classes; + delete _candidates; + delete _sorted_candidates; + _vm_classes = nullptr; + _candidates = nullptr; + _sorted_candidates = nullptr; + + assert(!is_initialized(), "sanity"); + + AOTConstantPoolResolver::dispose(); +} + +bool AOTClassLinker::is_vm_class(InstanceKlass* ik) { + assert(is_initialized(), "sanity"); + return (_vm_classes->get(ik) != nullptr); +} + +void AOTClassLinker::add_vm_class(InstanceKlass* ik) { + assert(is_initialized(), "sanity"); + bool created; + _vm_classes->put_if_absent(ik, &created); + if (created) { + if (CDSConfig::is_dumping_aot_linked_classes()) { + bool v = try_add_candidate(ik); + assert(v, "must succeed for VM class"); + } + InstanceKlass* super = ik->java_super(); + if (super != nullptr) { + add_vm_class(super); + } + Array* ifs = ik->local_interfaces(); + for (int i = 0; i < ifs->length(); i++) { + add_vm_class(ifs->at(i)); + } + } +} + +bool AOTClassLinker::is_candidate(InstanceKlass* ik) { + return (_candidates->get(ik) != nullptr); +} + +void AOTClassLinker::add_new_candidate(InstanceKlass* ik) { + assert(!is_candidate(ik), "caller need to check"); + _candidates->put_when_absent(ik, true); + _sorted_candidates->append(ik); + + if (log_is_enabled(Info, cds, aot, link)) { + ResourceMark rm; + log_info(cds, aot, link)("%s %s %p", class_category_name(ik), ik->external_name(), ik); + } +} + +// ik is a candidate for aot-linking; see if it can really work +// that way, and return success or failure. Not only must ik itself +// look like a class that can be aot-linked but its supers must also be +// aot-linkable. +bool AOTClassLinker::try_add_candidate(InstanceKlass* ik) { + assert(is_initialized(), "sanity"); + assert(CDSConfig::is_dumping_aot_linked_classes(), "sanity"); + + if (!SystemDictionaryShared::is_builtin(ik)) { + // not loaded by a class loader which we know about + return false; + } + + if (is_candidate(ik)) { // already checked. + return true; + } + + if (ik->is_hidden()) { + assert(ik->shared_class_loader_type() != ClassLoader::OTHER, "must have been set"); + if (!CDSConfig::is_dumping_invokedynamic()) { + return false; + } + if (!SystemDictionaryShared::should_hidden_class_be_archived(ik)) { + return false; + } + if (HeapShared::is_lambda_proxy_klass(ik)) { + InstanceKlass* nest_host = ik->nest_host_not_null(); + if (!try_add_candidate(nest_host)) { + ResourceMark rm; + log_warning(cds, aot, link)("%s cannot be aot-linked because it nest host is not aot-linked", ik->external_name()); + return false; + } + } + } + + InstanceKlass* s = ik->java_super(); + if (s != nullptr && !try_add_candidate(s)) { + return false; + } + + Array* interfaces = ik->local_interfaces(); + int num_interfaces = interfaces->length(); + for (int index = 0; index < num_interfaces; index++) { + InstanceKlass* intf = interfaces->at(index); + if (!try_add_candidate(intf)) { + return false; + } + } + + // There are no loops in the class hierarchy, and this function is always called single-threaded, so + // we know ik has not been added yet. + assert(CDSConfig::current_thread_is_vm_or_dumper(), "that's why we don't need locks"); + add_new_candidate(ik); + + return true; +} + +void AOTClassLinker::add_candidates() { + assert_at_safepoint(); + if (CDSConfig::is_dumping_aot_linked_classes()) { + GrowableArray* klasses = ArchiveBuilder::current()->klasses(); + for (GrowableArrayIterator it = klasses->begin(); it != klasses->end(); ++it) { + Klass* k = *it; + if (k->is_instance_klass()) { + try_add_candidate(InstanceKlass::cast(k)); + } + } + } +} + +void AOTClassLinker::write_to_archive() { + assert(is_initialized(), "sanity"); + assert_at_safepoint(); + + if (CDSConfig::is_dumping_aot_linked_classes()) { + AOTLinkedClassTable* table = AOTLinkedClassTable::get(CDSConfig::is_dumping_static_archive()); + table->set_boot(write_classes(nullptr, true)); + table->set_boot2(write_classes(nullptr, false)); + table->set_platform(write_classes(SystemDictionary::java_platform_loader(), false)); + table->set_app(write_classes(SystemDictionary::java_system_loader(), false)); + } +} + +Array* AOTClassLinker::write_classes(oop class_loader, bool is_javabase) { + ResourceMark rm; + GrowableArray list; + + for (int i = 0; i < _sorted_candidates->length(); i++) { + InstanceKlass* ik = _sorted_candidates->at(i); + if (ik->class_loader() != class_loader) { + continue; + } + if ((ik->module() == ModuleEntryTable::javabase_moduleEntry()) != is_javabase) { + continue; + } + + if (ik->is_shared() && CDSConfig::is_dumping_dynamic_archive()) { + if (CDSConfig::is_using_aot_linked_classes()) { + // This class was recorded as AOT-linked for the base archive, + // so there's no need to do so again for the dynamic archive. + } else { + list.append(ik); + } + } else { + list.append(ArchiveBuilder::current()->get_buffered_addr(ik)); + } + } + + if (list.length() == 0) { + return nullptr; + } else { + const char* category = class_category_name(list.at(0)); + log_info(cds, aot, link)("wrote %d class(es) for category %s", list.length(), category); + return ArchiveUtils::archive_array(&list); + } +} + +int AOTClassLinker::num_platform_initiated_classes() { + if (CDSConfig::is_dumping_aot_linked_classes()) { + // AOTLinkedClassBulkLoader will initiate loading of all public boot classes in the platform loader. + return count_public_classes(nullptr); + } else { + return 0; + } +} + +int AOTClassLinker::num_app_initiated_classes() { + if (CDSConfig::is_dumping_aot_linked_classes()) { + // AOTLinkedClassBulkLoader will initiate loading of all public boot/platform classes in the app loader. + return count_public_classes(nullptr) + count_public_classes(SystemDictionary::java_platform_loader()); + } else { + return 0; + } +} + +int AOTClassLinker::count_public_classes(oop loader) { + int n = 0; + for (int i = 0; i < _sorted_candidates->length(); i++) { + InstanceKlass* ik = _sorted_candidates->at(i); + if (ik->is_public() && !ik->is_hidden() && ik->class_loader() == loader) { + n++; + } + } + + return n; +} + +// Used in logging: "boot1", "boot2", "plat", "app" and "unreg", or "array" +const char* AOTClassLinker::class_category_name(Klass* k) { + if (ArchiveBuilder::is_active() && ArchiveBuilder::current()->is_in_buffer_space(k)) { + k = ArchiveBuilder::current()->get_source_addr(k); + } + + if (k->is_array_klass()) { + return "array"; + } else { + oop loader = k->class_loader(); + if (loader == nullptr) { + if (k->module() != nullptr && + k->module()->name() != nullptr && + k->module()->name()->equals("java.base")) { + return "boot1"; // boot classes in java.base are loaded in the 1st phase + } else { + return "boot2"; // boot classes outside of java.base are loaded in the 2nd phase phase + } + } else { + if (loader == SystemDictionary::java_platform_loader()) { + return "plat"; + } else if (loader == SystemDictionary::java_system_loader()) { + return "app"; + } else { + return "unreg"; + } + } + } +} + +const char* AOTClassLinker::class_category_name(AOTLinkedClassCategory category) { + switch (category) { + case AOTLinkedClassCategory::BOOT1: + return "boot1"; + case AOTLinkedClassCategory::BOOT2: + return "boot2"; + case AOTLinkedClassCategory::PLATFORM: + return "plat"; + case AOTLinkedClassCategory::APP: + return "app"; + case AOTLinkedClassCategory::UNREGISTERED: + default: + return "unreg"; + } +} + diff --git a/src/hotspot/share/cds/aotClassLinker.hpp b/src/hotspot/share/cds/aotClassLinker.hpp new file mode 100644 index 00000000000..f15684a1ad2 --- /dev/null +++ b/src/hotspot/share/cds/aotClassLinker.hpp @@ -0,0 +1,129 @@ +/* + * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#ifndef SHARE_CDS_AOTCLASSLINKER_HPP +#define SHARE_CDS_AOTCLASSLINKER_HPP + +#include "interpreter/bytecodes.hpp" +#include "memory/allocation.hpp" +#include "memory/allStatic.hpp" +#include "oops/oopsHierarchy.hpp" +#include "utilities/exceptions.hpp" +#include "utilities/growableArray.hpp" +#include "utilities/macros.hpp" +#include "utilities/resourceHash.hpp" + +class AOTLinkedClassTable; +class InstanceKlass; +class SerializeClosure; +template class Array; +enum class AOTLinkedClassCategory : int; + +// AOTClassLinker is used during the AOTCache Assembly Phase. +// It links eligible classes before they are written into the AOTCache +// +// The classes linked by AOTClassLinker are recorded in an AOTLinkedClassTable, +// which is also written into the AOTCache. +// +// AOTClassLinker is enabled by the -XX:+AOTClassLinking option. If this option +// is disabled, an empty AOTLinkedClassTable will be included in the AOTCache. +// +// For each class C in the AOTLinkedClassTable, the following properties for C +// are assigned by AOTClassLinker and cannot be changed thereafter. +// - The CodeSource for C +// - The bytecodes in C +// - The supertypes of C +// - The ClassLoader, Package and Module of C +// - The visibility of C +// +// During a production run, the JVM can use an AOTCache with an AOTLinkedClassTable +// only if it's guaranteed to produce the same results for the above set of properties +// for each class C in the AOTLinkedClassTable. +// +// For example, +// - C may be loaded from a different CodeSource when the CLASSPATH is changed. +// - Some JVMTI agent may allow the bytecodes of C to be modified. +// - C may be made invisible by module options such as --add-modules +// In such situations, the JVM will refuse to load the AOTCache. +// +class AOTClassLinker : AllStatic { + static const int TABLE_SIZE = 15889; // prime number + using ClassesTable = ResourceHashtable; + + // Classes loaded inside vmClasses::resolve_all() + static ClassesTable* _vm_classes; + + // Classes that should be automatically loaded into system dictionary at VM start-up + static ClassesTable* _candidates; + + // Sorted list such that super types come first. + static GrowableArrayCHeap* _sorted_candidates; + + DEBUG_ONLY(static bool is_initialized()); + + static void add_vm_class(InstanceKlass* ik); + static void add_new_candidate(InstanceKlass* ik); + + static Array* write_classes(oop class_loader, bool is_javabase); + static int count_public_classes(oop loader); + +public: + static void initialize(); + static void add_candidates(); + static void write_to_archive(); + static void dispose(); + + // Is this class resolved as part of vmClasses::resolve_all()? + static bool is_vm_class(InstanceKlass* ik); + + // When CDS is enabled, is ik guaranteed to be linked at deployment time (and + // cannot be replaced by JVMTI, etc)? + // This is a necessary (but not sufficient) condition for keeping a direct pointer + // to ik in AOT-computed data (such as ConstantPool entries in archived classes, + // or in AOT-compiled code). + static bool is_candidate(InstanceKlass* ik); + + // Request that ik be added to the candidates table. This will return true only if + // ik is allowed to be aot-linked. + static bool try_add_candidate(InstanceKlass* ik); + + static int num_app_initiated_classes(); + static int num_platform_initiated_classes(); + + // Used in logging: "boot1", "boot2", "plat", "app" and "unreg"; + static const char* class_category_name(AOTLinkedClassCategory category); + static const char* class_category_name(Klass* k); +}; + +// AOT-linked classes are divided into different categories and are loaded +// in two phases during the production run. +enum class AOTLinkedClassCategory : int { + BOOT1, // Only java.base classes are loaded in the 1st phase + BOOT2, // All boot classes that not in java.base are loaded in the 2nd phase + PLATFORM, // Classes for platform loader, loaded in the 2nd phase + APP, // Classes for the app loader, loaded in the 2nd phase + UNREGISTERED // classes loaded outside of the boot/platform/app loaders; currently not supported by AOTClassLinker +}; + +#endif // SHARE_CDS_AOTCLASSLINKER_HPP diff --git a/src/hotspot/share/cds/aotConstantPoolResolver.cpp b/src/hotspot/share/cds/aotConstantPoolResolver.cpp new file mode 100644 index 00000000000..cc500557c8d --- /dev/null +++ b/src/hotspot/share/cds/aotConstantPoolResolver.cpp @@ -0,0 +1,573 @@ +/* + * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#include "precompiled.hpp" +#include "cds/aotClassLinker.hpp" +#include "cds/aotConstantPoolResolver.hpp" +#include "cds/archiveBuilder.hpp" +#include "cds/cdsConfig.hpp" +#include "classfile/systemDictionary.hpp" +#include "classfile/systemDictionaryShared.hpp" +#include "classfile/vmClasses.hpp" +#include "interpreter/bytecodeStream.hpp" +#include "interpreter/interpreterRuntime.hpp" +#include "memory/resourceArea.hpp" +#include "oops/constantPool.inline.hpp" +#include "oops/instanceKlass.hpp" +#include "oops/klass.inline.hpp" +#include "runtime/handles.inline.hpp" + +AOTConstantPoolResolver::ClassesTable* AOTConstantPoolResolver::_processed_classes = nullptr; + +void AOTConstantPoolResolver::initialize() { + assert(_processed_classes == nullptr, "must be"); + _processed_classes = new (mtClass)ClassesTable(); +} + +void AOTConstantPoolResolver::dispose() { + assert(_processed_classes != nullptr, "must be"); + delete _processed_classes; + _processed_classes = nullptr; +} + +// Returns true if we CAN PROVE that cp_index will always resolve to +// the same information at both dump time and run time. This is a +// necessary (but not sufficient) condition for pre-resolving cp_index +// during CDS archive assembly. +bool AOTConstantPoolResolver::is_resolution_deterministic(ConstantPool* cp, int cp_index) { + assert(!is_in_archivebuilder_buffer(cp), "sanity"); + + if (cp->tag_at(cp_index).is_klass()) { + // We require cp_index to be already resolved. This is fine for now, are we + // currently archive only CP entries that are already resolved. + Klass* resolved_klass = cp->resolved_klass_at(cp_index); + return resolved_klass != nullptr && is_class_resolution_deterministic(cp->pool_holder(), resolved_klass); + } else if (cp->tag_at(cp_index).is_invoke_dynamic()) { + return is_indy_resolution_deterministic(cp, cp_index); + } else if (cp->tag_at(cp_index).is_field() || + cp->tag_at(cp_index).is_method() || + cp->tag_at(cp_index).is_interface_method()) { + int klass_cp_index = cp->uncached_klass_ref_index_at(cp_index); + if (!cp->tag_at(klass_cp_index).is_klass()) { + // Not yet resolved + return false; + } + Klass* k = cp->resolved_klass_at(klass_cp_index); + if (!is_class_resolution_deterministic(cp->pool_holder(), k)) { + return false; + } + + if (!k->is_instance_klass()) { + // TODO: support non instance klasses as well. + return false; + } + + // Here, We don't check if this entry can actually be resolved to a valid Field/Method. + // This method should be called by the ConstantPool to check Fields/Methods that + // have already been successfully resolved. + return true; + } else { + return false; + } +} + +bool AOTConstantPoolResolver::is_class_resolution_deterministic(InstanceKlass* cp_holder, Klass* resolved_class) { + assert(!is_in_archivebuilder_buffer(cp_holder), "sanity"); + assert(!is_in_archivebuilder_buffer(resolved_class), "sanity"); + + if (resolved_class->is_instance_klass()) { + InstanceKlass* ik = InstanceKlass::cast(resolved_class); + + if (!ik->is_shared() && SystemDictionaryShared::is_excluded_class(ik)) { + return false; + } + + if (cp_holder->is_subtype_of(ik)) { + // All super types of ik will be resolved in ik->class_loader() before + // ik is defined in this loader, so it's safe to archive the resolved klass reference. + return true; + } + + if (CDSConfig::is_dumping_aot_linked_classes()) { + // Need to call try_add_candidate instead of is_candidate, as this may be called + // before AOTClassLinker::add_candidates(). + if (AOTClassLinker::try_add_candidate(ik)) { + return true; + } else { + return false; + } + } else if (AOTClassLinker::is_vm_class(ik)) { + if (ik->class_loader() != cp_holder->class_loader()) { + // At runtime, cp_holder() may not be able to resolve to the same + // ik. For example, a different version of ik may be defined in + // cp->pool_holder()'s loader using MethodHandles.Lookup.defineClass(). + return false; + } else { + return true; + } + } else { + return false; + } + } else if (resolved_class->is_objArray_klass()) { + Klass* elem = ObjArrayKlass::cast(resolved_class)->bottom_klass(); + if (elem->is_instance_klass()) { + return is_class_resolution_deterministic(cp_holder, InstanceKlass::cast(elem)); + } else if (elem->is_typeArray_klass()) { + return true; + } else { + return false; + } + } else if (resolved_class->is_typeArray_klass()) { + return true; + } else { + return false; + } +} + +void AOTConstantPoolResolver::dumptime_resolve_constants(InstanceKlass* ik, TRAPS) { + if (!ik->is_linked()) { + return; + } + bool first_time; + _processed_classes->put_if_absent(ik, &first_time); + if (!first_time) { + // We have already resolved the constants in class, so no need to do it again. + return; + } + + constantPoolHandle cp(THREAD, ik->constants()); + for (int cp_index = 1; cp_index < cp->length(); cp_index++) { // Index 0 is unused + switch (cp->tag_at(cp_index).value()) { + case JVM_CONSTANT_String: + resolve_string(cp, cp_index, CHECK); // may throw OOM when interning strings. + break; + } + } +} + +// This works only for the boot/platform/app loaders +Klass* AOTConstantPoolResolver::find_loaded_class(Thread* current, oop class_loader, Symbol* name) { + HandleMark hm(current); + Handle h_loader(current, class_loader); + Klass* k = SystemDictionary::find_instance_or_array_klass(current, name, + h_loader, + Handle()); + if (k != nullptr) { + return k; + } + if (h_loader() == SystemDictionary::java_system_loader()) { + return find_loaded_class(current, SystemDictionary::java_platform_loader(), name); + } else if (h_loader() == SystemDictionary::java_platform_loader()) { + return find_loaded_class(current, nullptr, name); + } else { + assert(h_loader() == nullptr, "This function only works for boot/platform/app loaders %p %p %p", + cast_from_oop

(h_loader()), + cast_from_oop
(SystemDictionary::java_system_loader()), + cast_from_oop
(SystemDictionary::java_platform_loader())); + } + + return nullptr; +} + +Klass* AOTConstantPoolResolver::find_loaded_class(Thread* current, ConstantPool* cp, int class_cp_index) { + Symbol* name = cp->klass_name_at(class_cp_index); + return find_loaded_class(current, cp->pool_holder()->class_loader(), name); +} + +#if INCLUDE_CDS_JAVA_HEAP +void AOTConstantPoolResolver::resolve_string(constantPoolHandle cp, int cp_index, TRAPS) { + if (CDSConfig::is_dumping_heap()) { + int cache_index = cp->cp_to_object_index(cp_index); + ConstantPool::string_at_impl(cp, cp_index, cache_index, CHECK); + } +} +#endif + +void AOTConstantPoolResolver::preresolve_class_cp_entries(JavaThread* current, InstanceKlass* ik, GrowableArray* preresolve_list) { + if (!SystemDictionaryShared::is_builtin_loader(ik->class_loader_data())) { + return; + } + + JavaThread* THREAD = current; + constantPoolHandle cp(THREAD, ik->constants()); + for (int cp_index = 1; cp_index < cp->length(); cp_index++) { + if (cp->tag_at(cp_index).value() == JVM_CONSTANT_UnresolvedClass) { + if (preresolve_list != nullptr && preresolve_list->at(cp_index) == false) { + // This class was not resolved during trial run. Don't attempt to resolve it. Otherwise + // the compiler may generate less efficient code. + continue; + } + if (find_loaded_class(current, cp(), cp_index) == nullptr) { + // Do not resolve any class that has not been loaded yet + continue; + } + Klass* resolved_klass = cp->klass_at(cp_index, THREAD); + if (HAS_PENDING_EXCEPTION) { + CLEAR_PENDING_EXCEPTION; // just ignore + } else { + log_trace(cds, resolve)("Resolved class [%3d] %s -> %s", cp_index, ik->external_name(), + resolved_klass->external_name()); + } + } + } +} + +void AOTConstantPoolResolver::preresolve_field_and_method_cp_entries(JavaThread* current, InstanceKlass* ik, GrowableArray* preresolve_list) { + JavaThread* THREAD = current; + constantPoolHandle cp(THREAD, ik->constants()); + if (cp->cache() == nullptr) { + return; + } + for (int i = 0; i < ik->methods()->length(); i++) { + Method* m = ik->methods()->at(i); + BytecodeStream bcs(methodHandle(THREAD, m)); + while (!bcs.is_last_bytecode()) { + bcs.next(); + Bytecodes::Code raw_bc = bcs.raw_code(); + switch (raw_bc) { + case Bytecodes::_getfield: + case Bytecodes::_putfield: + maybe_resolve_fmi_ref(ik, m, raw_bc, bcs.get_index_u2(), preresolve_list, THREAD); + if (HAS_PENDING_EXCEPTION) { + CLEAR_PENDING_EXCEPTION; // just ignore + } + break; + case Bytecodes::_invokehandle: + case Bytecodes::_invokespecial: + case Bytecodes::_invokevirtual: + case Bytecodes::_invokeinterface: + maybe_resolve_fmi_ref(ik, m, raw_bc, bcs.get_index_u2(), preresolve_list, THREAD); + if (HAS_PENDING_EXCEPTION) { + CLEAR_PENDING_EXCEPTION; // just ignore + } + break; + default: + break; + } + } + } +} + +void AOTConstantPoolResolver::maybe_resolve_fmi_ref(InstanceKlass* ik, Method* m, Bytecodes::Code bc, int raw_index, + GrowableArray* preresolve_list, TRAPS) { + methodHandle mh(THREAD, m); + constantPoolHandle cp(THREAD, ik->constants()); + HandleMark hm(THREAD); + int cp_index = cp->to_cp_index(raw_index, bc); + + if (cp->is_resolved(raw_index, bc)) { + return; + } + + if (preresolve_list != nullptr && preresolve_list->at(cp_index) == false) { + // This field wasn't resolved during the trial run. Don't attempt to resolve it. Otherwise + // the compiler may generate less efficient code. + return; + } + + int klass_cp_index = cp->uncached_klass_ref_index_at(cp_index); + if (find_loaded_class(THREAD, cp(), klass_cp_index) == nullptr) { + // Do not resolve any field/methods from a class that has not been loaded yet. + return; + } + + Klass* resolved_klass = cp->klass_ref_at(raw_index, bc, CHECK); + + switch (bc) { + case Bytecodes::_getfield: + case Bytecodes::_putfield: + InterpreterRuntime::resolve_get_put(bc, raw_index, mh, cp, false /*initialize_holder*/, CHECK); + break; + + case Bytecodes::_invokevirtual: + case Bytecodes::_invokespecial: + case Bytecodes::_invokeinterface: + InterpreterRuntime::cds_resolve_invoke(bc, raw_index, cp, CHECK); + break; + + case Bytecodes::_invokehandle: + InterpreterRuntime::cds_resolve_invokehandle(raw_index, cp, CHECK); + break; + + default: + ShouldNotReachHere(); + } + + if (log_is_enabled(Trace, cds, resolve)) { + ResourceMark rm(THREAD); + bool resolved = cp->is_resolved(raw_index, bc); + Symbol* name = cp->name_ref_at(raw_index, bc); + Symbol* signature = cp->signature_ref_at(raw_index, bc); + log_trace(cds, resolve)("%s %s [%3d] %s -> %s.%s:%s", + (resolved ? "Resolved" : "Failed to resolve"), + Bytecodes::name(bc), cp_index, ik->external_name(), + resolved_klass->external_name(), + name->as_C_string(), signature->as_C_string()); + } +} + +void AOTConstantPoolResolver::preresolve_indy_cp_entries(JavaThread* current, InstanceKlass* ik, GrowableArray* preresolve_list) { + JavaThread* THREAD = current; + constantPoolHandle cp(THREAD, ik->constants()); + if (!CDSConfig::is_dumping_invokedynamic() || cp->cache() == nullptr) { + return; + } + + assert(preresolve_list != nullptr, "preresolve_indy_cp_entries() should not be called for " + "regenerated LambdaForm Invoker classes, which should not have indys anyway."); + + Array* indy_entries = cp->cache()->resolved_indy_entries(); + for (int i = 0; i < indy_entries->length(); i++) { + ResolvedIndyEntry* rie = indy_entries->adr_at(i); + int cp_index = rie->constant_pool_index(); + if (preresolve_list->at(cp_index) == true) { + if (!rie->is_resolved() && is_indy_resolution_deterministic(cp(), cp_index)) { + InterpreterRuntime::cds_resolve_invokedynamic(i, cp, THREAD); + if (HAS_PENDING_EXCEPTION) { + CLEAR_PENDING_EXCEPTION; // just ignore + } + } + if (log_is_enabled(Trace, cds, resolve)) { + ResourceMark rm(THREAD); + log_trace(cds, resolve)("%s indy [%3d] %s", + rie->is_resolved() ? "Resolved" : "Failed to resolve", + cp_index, ik->external_name()); + } + } + } +} + +// Check the MethodType signatures used by parameters to the indy BSMs. Make sure we don't +// use types that have been excluded, or else we might end up creating MethodTypes that cannot be stored +// in the AOT cache. +bool AOTConstantPoolResolver::check_methodtype_signature(ConstantPool* cp, Symbol* sig, Klass** return_type_ret) { + ResourceMark rm; + for (SignatureStream ss(sig); !ss.is_done(); ss.next()) { + if (ss.is_reference()) { + Symbol* type = ss.as_symbol(); + Klass* k = find_loaded_class(Thread::current(), cp->pool_holder()->class_loader(), type); + if (k == nullptr) { + return false; + } + + if (SystemDictionaryShared::should_be_excluded(k)) { + if (log_is_enabled(Warning, cds, resolve)) { + ResourceMark rm; + log_warning(cds, resolve)("Cannot aot-resolve Lambda proxy because %s is excluded", k->external_name()); + } + return false; + } + + if (ss.at_return_type() && return_type_ret != nullptr) { + *return_type_ret = k; + } + } + } + return true; +} + +bool AOTConstantPoolResolver::check_lambda_metafactory_signature(ConstantPool* cp, Symbol* sig) { + Klass* k; + if (!check_methodtype_signature(cp, sig, &k)) { + return false; + } + + // is the interface type implemented by the lambda proxy + if (!k->is_interface()) { + // cp->pool_holder() doesn't look like a valid class generated by javac + return false; + } + + + // The linked lambda callsite has an instance of the interface implemented by this lambda. If this + // interface requires its to be executed, then we must delay the execution to the production run + // as can have side effects ==> exclude such cases. + InstanceKlass* intf = InstanceKlass::cast(k); + bool exclude = intf->interface_needs_clinit_execution_as_super(); + if (log_is_enabled(Debug, cds, resolve)) { + ResourceMark rm; + log_debug(cds, resolve)("%s aot-resolve Lambda proxy of interface type %s", + exclude ? "Cannot" : "Can", k->external_name()); + } + return !exclude; +} + +bool AOTConstantPoolResolver::check_lambda_metafactory_methodtype_arg(ConstantPool* cp, int bsms_attribute_index, int arg_i) { + int mt_index = cp->operand_argument_index_at(bsms_attribute_index, arg_i); + if (!cp->tag_at(mt_index).is_method_type()) { + // malformed class? + return false; + } + + Symbol* sig = cp->method_type_signature_at(mt_index); + if (log_is_enabled(Debug, cds, resolve)) { + ResourceMark rm; + log_debug(cds, resolve)("Checking MethodType for LambdaMetafactory BSM arg %d: %s", arg_i, sig->as_C_string()); + } + + return check_methodtype_signature(cp, sig); +} + +bool AOTConstantPoolResolver::check_lambda_metafactory_methodhandle_arg(ConstantPool* cp, int bsms_attribute_index, int arg_i) { + int mh_index = cp->operand_argument_index_at(bsms_attribute_index, arg_i); + if (!cp->tag_at(mh_index).is_method_handle()) { + // malformed class? + return false; + } + + Symbol* sig = cp->method_handle_signature_ref_at(mh_index); + if (log_is_enabled(Debug, cds, resolve)) { + ResourceMark rm; + log_debug(cds, resolve)("Checking MethodType of MethodHandle for LambdaMetafactory BSM arg %d: %s", arg_i, sig->as_C_string()); + } + return check_methodtype_signature(cp, sig); +} + +bool AOTConstantPoolResolver::is_indy_resolution_deterministic(ConstantPool* cp, int cp_index) { + assert(cp->tag_at(cp_index).is_invoke_dynamic(), "sanity"); + if (!CDSConfig::is_dumping_invokedynamic()) { + return false; + } + + InstanceKlass* pool_holder = cp->pool_holder(); + if (!SystemDictionaryShared::is_builtin(pool_holder)) { + return false; + } + + int bsm = cp->bootstrap_method_ref_index_at(cp_index); + int bsm_ref = cp->method_handle_index_at(bsm); + Symbol* bsm_name = cp->uncached_name_ref_at(bsm_ref); + Symbol* bsm_signature = cp->uncached_signature_ref_at(bsm_ref); + Symbol* bsm_klass = cp->klass_name_at(cp->uncached_klass_ref_index_at(bsm_ref)); + + // We currently support only StringConcatFactory::makeConcatWithConstants() and LambdaMetafactory::metafactory() + // We should mark the allowed BSMs in the JDK code using a private annotation. + // See notes on RFE JDK-8342481. + + if (bsm_klass->equals("java/lang/invoke/StringConcatFactory") && + bsm_name->equals("makeConcatWithConstants") && + bsm_signature->equals("(Ljava/lang/invoke/MethodHandles$Lookup;" + "Ljava/lang/String;" + "Ljava/lang/invoke/MethodType;" + "Ljava/lang/String;" + "[Ljava/lang/Object;" + ")Ljava/lang/invoke/CallSite;")) { + Symbol* factory_type_sig = cp->uncached_signature_ref_at(cp_index); + if (log_is_enabled(Debug, cds, resolve)) { + ResourceMark rm; + log_debug(cds, resolve)("Checking StringConcatFactory callsite signature [%d]: %s", cp_index, factory_type_sig->as_C_string()); + } + + Klass* k; + if (!check_methodtype_signature(cp, factory_type_sig, &k)) { + return false; + } + if (k != vmClasses::String_klass()) { + // bad class file? + return false; + } + + return true; + } + + if (bsm_klass->equals("java/lang/invoke/LambdaMetafactory") && + bsm_name->equals("metafactory") && + bsm_signature->equals("(Ljava/lang/invoke/MethodHandles$Lookup;" + "Ljava/lang/String;" + "Ljava/lang/invoke/MethodType;" + "Ljava/lang/invoke/MethodType;" + "Ljava/lang/invoke/MethodHandle;" + "Ljava/lang/invoke/MethodType;" + ")Ljava/lang/invoke/CallSite;")) { + /* + * An indy callsite is associated with the following MethodType and MethodHandles: + * + * https://github.com/openjdk/jdk/blob/580eb62dc097efeb51c76b095c1404106859b673/src/java.base/share/classes/java/lang/invoke/LambdaMetafactory.java#L293-L309 + * + * MethodType factoryType The expected signature of the {@code CallSite}. The + * parameter types represent the types of capture variables; + * the return type is the interface to implement. When + * used with {@code invokedynamic}, this is provided by + * the {@code NameAndType} of the {@code InvokeDynamic} + * + * MethodType interfaceMethodType Signature and return type of method to be + * implemented by the function object. + * + * MethodHandle implementation A direct method handle describing the implementation + * method which should be called (with suitable adaptation + * of argument types and return types, and with captured + * arguments prepended to the invocation arguments) at + * invocation time. + * + * MethodType dynamicMethodType The signature and return type that should + * be enforced dynamically at invocation time. + * In simple use cases this is the same as + * {@code interfaceMethodType}. + */ + Symbol* factory_type_sig = cp->uncached_signature_ref_at(cp_index); + if (log_is_enabled(Debug, cds, resolve)) { + ResourceMark rm; + log_debug(cds, resolve)("Checking indy callsite signature [%d]: %s", cp_index, factory_type_sig->as_C_string()); + } + + if (!check_lambda_metafactory_signature(cp, factory_type_sig)) { + return false; + } + + int bsms_attribute_index = cp->bootstrap_methods_attribute_index(cp_index); + int arg_count = cp->operand_argument_count_at(bsms_attribute_index); + if (arg_count != 3) { + // Malformed class? + return false; + } + + // interfaceMethodType + if (!check_lambda_metafactory_methodtype_arg(cp, bsms_attribute_index, 0)) { + return false; + } + + // implementation + if (!check_lambda_metafactory_methodhandle_arg(cp, bsms_attribute_index, 1)) { + return false; + } + + // dynamicMethodType + if (!check_lambda_metafactory_methodtype_arg(cp, bsms_attribute_index, 2)) { + return false; + } + + return true; + } + + return false; +} +#ifdef ASSERT +bool AOTConstantPoolResolver::is_in_archivebuilder_buffer(address p) { + if (!Thread::current()->is_VM_thread() || ArchiveBuilder::current() == nullptr) { + return false; + } else { + return ArchiveBuilder::current()->is_in_buffer_space(p); + } +} +#endif diff --git a/src/hotspot/share/cds/classPrelinker.hpp b/src/hotspot/share/cds/aotConstantPoolResolver.hpp similarity index 73% rename from src/hotspot/share/cds/classPrelinker.hpp rename to src/hotspot/share/cds/aotConstantPoolResolver.hpp index 41588961d8b..2f65849fbb4 100644 --- a/src/hotspot/share/cds/classPrelinker.hpp +++ b/src/hotspot/share/cds/aotConstantPoolResolver.hpp @@ -22,13 +22,13 @@ * */ -#ifndef SHARE_CDS_CLASSPRELINKER_HPP -#define SHARE_CDS_CLASSPRELINKER_HPP +#ifndef SHARE_CDS_AOTCONSTANTPOOLRESOLVER_HPP +#define SHARE_CDS_AOTCONSTANTPOOLRESOLVER_HPP #include "interpreter/bytecodes.hpp" -#include "oops/oopsHierarchy.hpp" #include "memory/allStatic.hpp" #include "memory/allocation.hpp" +#include "oops/oopsHierarchy.hpp" #include "runtime/handles.hpp" #include "utilities/exceptions.hpp" #include "utilities/macros.hpp" @@ -39,7 +39,9 @@ class constantPoolHandle; class InstanceKlass; class Klass; -// ClassPrelinker is used to perform ahead-of-time linking of ConstantPool entries +template class GrowableArray; + +// AOTConstantPoolResolver is used to perform ahead-of-time linking of ConstantPool entries // for archived InstanceKlasses. // // At run time, Java classes are loaded dynamically and may be replaced with JVMTI. @@ -49,23 +51,21 @@ class Klass; // For example, a JVM_CONSTANT_Class reference to a supertype can be safely resolved // at dump time, because at run time we will load a class from the CDS archive only // if all of its supertypes are loaded from the CDS archive. -class ClassPrelinker : AllStatic { - using ClassesTable = ResourceHashtable ; +class AOTConstantPoolResolver : AllStatic { + static const int TABLE_SIZE = 15889; // prime number + using ClassesTable = ResourceHashtable ; static ClassesTable* _processed_classes; - static ClassesTable* _vm_classes; - - static void add_one_vm_class(InstanceKlass* ik); #ifdef ASSERT + template static bool is_in_archivebuilder_buffer(T p) { + return is_in_archivebuilder_buffer((address)(p)); + } static bool is_in_archivebuilder_buffer(address p); #endif - template - static bool is_in_archivebuilder_buffer(T p) { - return is_in_archivebuilder_buffer((address)(p)); - } static void resolve_string(constantPoolHandle cp, int cp_index, TRAPS) NOT_CDS_JAVA_HEAP_RETURN; static bool is_class_resolution_deterministic(InstanceKlass* cp_holder, Klass* resolved_class); + static bool is_indy_resolution_deterministic(ConstantPool* cp, int cp_index); static Klass* find_loaded_class(Thread* current, oop class_loader, Symbol* name); static Klass* find_loaded_class(Thread* current, ConstantPool* cp, int class_cp_index); @@ -73,18 +73,20 @@ class ClassPrelinker : AllStatic { // fmi = FieldRef/MethodRef/InterfaceMethodRef static void maybe_resolve_fmi_ref(InstanceKlass* ik, Method* m, Bytecodes::Code bc, int raw_index, GrowableArray* resolve_fmi_list, TRAPS); + + static bool check_methodtype_signature(ConstantPool* cp, Symbol* sig, Klass** return_type_ret = nullptr); + static bool check_lambda_metafactory_signature(ConstantPool* cp, Symbol* sig); + static bool check_lambda_metafactory_methodtype_arg(ConstantPool* cp, int bsms_attribute_index, int arg_i); + static bool check_lambda_metafactory_methodhandle_arg(ConstantPool* cp, int bsms_attribute_index, int arg_i); + public: static void initialize(); static void dispose(); static void preresolve_class_cp_entries(JavaThread* current, InstanceKlass* ik, GrowableArray* preresolve_list); static void preresolve_field_and_method_cp_entries(JavaThread* current, InstanceKlass* ik, GrowableArray* preresolve_list); + static void preresolve_indy_cp_entries(JavaThread* current, InstanceKlass* ik, GrowableArray* preresolve_list); - // Is this class resolved as part of vmClasses::resolve_all()? If so, these - // classes are guatanteed to be loaded at runtime (and cannot be replaced by JVMTI) - // when CDS is enabled. Therefore, we can safely keep a direct reference to these - // classes. - static bool is_vm_class(InstanceKlass* ik); // Resolve all constant pool entries that are safe to be stored in the // CDS archive. @@ -93,4 +95,4 @@ class ClassPrelinker : AllStatic { static bool is_resolution_deterministic(ConstantPool* cp, int cp_index); }; -#endif // SHARE_CDS_CLASSPRELINKER_HPP +#endif // SHARE_CDS_AOTCONSTANTPOOLRESOLVER_HPP diff --git a/src/hotspot/share/cds/aotLinkedClassBulkLoader.cpp b/src/hotspot/share/cds/aotLinkedClassBulkLoader.cpp new file mode 100644 index 00000000000..d823db9e8d7 --- /dev/null +++ b/src/hotspot/share/cds/aotLinkedClassBulkLoader.cpp @@ -0,0 +1,397 @@ +/* + * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#include "precompiled.hpp" +#include "cds/aotClassInitializer.hpp" +#include "cds/aotClassLinker.hpp" +#include "cds/aotLinkedClassBulkLoader.hpp" +#include "cds/aotLinkedClassTable.hpp" +#include "cds/cdsConfig.hpp" +#include "cds/heapShared.hpp" +#include "classfile/classLoaderData.hpp" +#include "classfile/systemDictionary.hpp" +#include "classfile/systemDictionaryShared.hpp" +#include "classfile/vmClasses.hpp" +#include "gc/shared/gcVMOperations.hpp" +#include "memory/resourceArea.hpp" +#include "oops/instanceKlass.hpp" +#include "oops/klass.inline.hpp" +#include "runtime/handles.inline.hpp" +#include "runtime/java.hpp" + +bool AOTLinkedClassBulkLoader::_boot2_completed = false; +bool AOTLinkedClassBulkLoader::_platform_completed = false; +bool AOTLinkedClassBulkLoader::_app_completed = false; +bool AOTLinkedClassBulkLoader::_all_completed = false; + +void AOTLinkedClassBulkLoader::serialize(SerializeClosure* soc, bool is_static_archive) { + AOTLinkedClassTable::get(is_static_archive)->serialize(soc); +} + +void AOTLinkedClassBulkLoader::load_javabase_classes(JavaThread* current) { + assert(CDSConfig::is_using_aot_linked_classes(), "sanity"); + load_classes_in_loader(current, AOTLinkedClassCategory::BOOT1, nullptr); // only java.base classes +} + +void AOTLinkedClassBulkLoader::load_non_javabase_classes(JavaThread* current) { + assert(CDSConfig::is_using_aot_linked_classes(), "sanity"); + + // is_using_aot_linked_classes() requires is_using_full_module_graph(). As a result, + // the platform/system class loader should already have been initialized as part + // of the FMG support. + assert(CDSConfig::is_using_full_module_graph(), "must be"); + assert(SystemDictionary::java_platform_loader() != nullptr, "must be"); + assert(SystemDictionary::java_system_loader() != nullptr, "must be"); + + load_classes_in_loader(current, AOTLinkedClassCategory::BOOT2, nullptr); // all boot classes outside of java.base + _boot2_completed = true; + + load_classes_in_loader(current, AOTLinkedClassCategory::PLATFORM, SystemDictionary::java_platform_loader()); + _platform_completed = true; + + load_classes_in_loader(current, AOTLinkedClassCategory::APP, SystemDictionary::java_system_loader()); + _app_completed = true; + _all_completed = true; +} + +void AOTLinkedClassBulkLoader::load_classes_in_loader(JavaThread* current, AOTLinkedClassCategory class_category, oop class_loader_oop) { + load_classes_in_loader_impl(class_category, class_loader_oop, current); + if (current->has_pending_exception()) { + // We cannot continue, as we might have loaded some of the aot-linked classes, which + // may have dangling C++ pointers to other aot-linked classes that we have failed to load. + exit_on_exception(current); + } +} + +void AOTLinkedClassBulkLoader::exit_on_exception(JavaThread* current) { + assert(current->has_pending_exception(), "precondition"); + ResourceMark rm(current); + if (current->pending_exception()->is_a(vmClasses::OutOfMemoryError_klass())) { + log_error(cds)("Out of memory. Please run with a larger Java heap, current MaxHeapSize = " + SIZE_FORMAT "M", MaxHeapSize/M); + } else { + log_error(cds)("%s: %s", current->pending_exception()->klass()->external_name(), + java_lang_String::as_utf8_string(java_lang_Throwable::message(current->pending_exception()))); + } + vm_exit_during_initialization("Unexpected exception when loading aot-linked classes."); +} + +void AOTLinkedClassBulkLoader::load_classes_in_loader_impl(AOTLinkedClassCategory class_category, oop class_loader_oop, TRAPS) { + Handle h_loader(THREAD, class_loader_oop); + load_table(AOTLinkedClassTable::for_static_archive(), class_category, h_loader, CHECK); + load_table(AOTLinkedClassTable::for_dynamic_archive(), class_category, h_loader, CHECK); + + // Initialize the InstanceKlasses of all archived heap objects that are reachable from the + // archived java class mirrors. + // + // Only the classes in the static archive can have archived mirrors. + AOTLinkedClassTable* static_table = AOTLinkedClassTable::for_static_archive(); + switch (class_category) { + case AOTLinkedClassCategory::BOOT1: + // Delayed until finish_loading_javabase_classes(), as the VM is not ready to + // execute some of the methods. + break; + case AOTLinkedClassCategory::BOOT2: + init_required_classes_for_loader(h_loader, static_table->boot2(), CHECK); + break; + case AOTLinkedClassCategory::PLATFORM: + init_required_classes_for_loader(h_loader, static_table->platform(), CHECK); + break; + case AOTLinkedClassCategory::APP: + init_required_classes_for_loader(h_loader, static_table->app(), CHECK); + break; + case AOTLinkedClassCategory::UNREGISTERED: + ShouldNotReachHere(); + break; + } + + if (Universe::is_fully_initialized() && VerifyDuringStartup) { + // Make sure we're still in a clean state. + VM_Verify verify_op; + VMThread::execute(&verify_op); + } +} + +void AOTLinkedClassBulkLoader::load_table(AOTLinkedClassTable* table, AOTLinkedClassCategory class_category, Handle loader, TRAPS) { + if (class_category != AOTLinkedClassCategory::BOOT1) { + assert(Universe::is_module_initialized(), "sanity"); + } + + const char* category_name = AOTClassLinker::class_category_name(class_category); + switch (class_category) { + case AOTLinkedClassCategory::BOOT1: + load_classes_impl(class_category, table->boot(), category_name, loader, CHECK); + break; + + case AOTLinkedClassCategory::BOOT2: + load_classes_impl(class_category, table->boot2(), category_name, loader, CHECK); + break; + + case AOTLinkedClassCategory::PLATFORM: + { + initiate_loading(THREAD, category_name, loader, table->boot()); + initiate_loading(THREAD, category_name, loader, table->boot2()); + load_classes_impl(class_category, table->platform(), category_name, loader, CHECK); + } + break; + case AOTLinkedClassCategory::APP: + { + initiate_loading(THREAD, category_name, loader, table->boot()); + initiate_loading(THREAD, category_name, loader, table->boot2()); + initiate_loading(THREAD, category_name, loader, table->platform()); + load_classes_impl(class_category, table->app(), category_name, loader, CHECK); + } + break; + case AOTLinkedClassCategory::UNREGISTERED: + default: + ShouldNotReachHere(); // Currently aot-linked classes are not supported for this category. + break; + } +} + +void AOTLinkedClassBulkLoader::load_classes_impl(AOTLinkedClassCategory class_category, Array* classes, + const char* category_name, Handle loader, TRAPS) { + if (classes == nullptr) { + return; + } + + ClassLoaderData* loader_data = ClassLoaderData::class_loader_data(loader()); + + for (int i = 0; i < classes->length(); i++) { + InstanceKlass* ik = classes->at(i); + if (log_is_enabled(Info, cds, aot, load)) { + ResourceMark rm(THREAD); + log_info(cds, aot, load)("%-5s %s%s%s", category_name, ik->external_name(), + ik->is_loaded() ? " (already loaded)" : "", + ik->is_hidden() ? " (hidden)" : ""); + } + + if (!ik->is_loaded()) { + if (ik->is_hidden()) { + load_hidden_class(loader_data, ik, CHECK); + } else { + InstanceKlass* actual; + if (loader_data == ClassLoaderData::the_null_class_loader_data()) { + actual = SystemDictionary::load_instance_class(ik->name(), loader, CHECK); + } else { + actual = SystemDictionaryShared::find_or_load_shared_class(ik->name(), loader, CHECK); + } + + if (actual != ik) { + ResourceMark rm(THREAD); + log_error(cds)("Unable to resolve %s class from CDS archive: %s", category_name, ik->external_name()); + log_error(cds)("Expected: " INTPTR_FORMAT ", actual: " INTPTR_FORMAT, p2i(ik), p2i(actual)); + log_error(cds)("JVMTI class retransformation is not supported when archive was generated with -XX:+AOTClassLinking."); + MetaspaceShared::unrecoverable_loading_error(); + } + assert(actual->is_loaded(), "must be"); + } + } + } +} + +// Initiate loading of the in the . The should have already been loaded +// by a parent loader of the . This is necessary for handling pre-resolved CP entries. +// +// For example, we initiate the loading of java/lang/String in the AppClassLoader. This will allow +// any App classes to have a pre-resolved ConstantPool entry that references java/lang/String. +// +// TODO: we can limit the number of initiated classes to only those that are actually referenced by +// AOT-linked classes loaded by . +void AOTLinkedClassBulkLoader::initiate_loading(JavaThread* current, const char* category_name, + Handle initiating_loader, Array* classes) { + if (classes == nullptr) { + return; + } + + assert(initiating_loader() == SystemDictionary::java_platform_loader() || + initiating_loader() == SystemDictionary::java_system_loader(), "must be"); + ClassLoaderData* loader_data = ClassLoaderData::class_loader_data(initiating_loader()); + MonitorLocker mu1(SystemDictionary_lock); + + for (int i = 0; i < classes->length(); i++) { + InstanceKlass* ik = classes->at(i); + assert(ik->is_loaded(), "must have already been loaded by a parent loader"); + assert(ik->class_loader() != initiating_loader(), "must be a parent loader"); + assert(ik->class_loader() == nullptr || + ik->class_loader() == SystemDictionary::java_platform_loader(), "must be"); + if (ik->is_public() && !ik->is_hidden()) { + if (log_is_enabled(Info, cds, aot, load)) { + ResourceMark rm(current); + const char* defining_loader = (ik->class_loader() == nullptr ? "boot" : "plat"); + log_info(cds, aot, load)("%s %s (initiated, defined by %s)", category_name, ik->external_name(), + defining_loader); + } + SystemDictionary::add_to_initiating_loader(current, ik, loader_data); + } + } +} + +// Currently, we archive only three types of hidden classes: +// - LambdaForms +// - lambda proxy classes +// - StringConcat classes +// See HeapShared::is_archivable_hidden_klass(). +// +// LambdaForm classes (with names like java/lang/invoke/LambdaForm$MH+0x800000015) logically +// belong to the boot loader, but they are usually stored in their own special ClassLoaderData to +// facilitate class unloading, as a LambdaForm may refer to a class loaded by a custom loader +// that may be unloaded. +// +// We only support AOT-resolution of indys in the boot/platform/app loader, so there's no need +// to support class unloading. For simplicity, we put all archived LambdaForm classes in the +// "main" ClassLoaderData of the boot loader. +// +// (Even if we were to support other loaders, we would still feel free to ignore any requirement +// of class unloading, for any class asset in the AOT cache. Anything that makes it into the AOT +// cache has a lifetime dispensation from unloading. After all, the AOT cache never grows, and +// we can assume that the user is content with its size, and doesn't need its footprint to shrink.) +// +// Lambda proxy classes are normally stored in the same ClassLoaderData as their nest hosts, and +// StringConcat are normally stored in the main ClassLoaderData of the boot class loader. We +// do the same for the archived copies of such classes. +void AOTLinkedClassBulkLoader::load_hidden_class(ClassLoaderData* loader_data, InstanceKlass* ik, TRAPS) { + assert(HeapShared::is_lambda_form_klass(ik) || + HeapShared::is_lambda_proxy_klass(ik) || + HeapShared::is_string_concat_klass(ik), "sanity"); + DEBUG_ONLY({ + assert(ik->java_super()->is_loaded(), "must be"); + for (int i = 0; i < ik->local_interfaces()->length(); i++) { + assert(ik->local_interfaces()->at(i)->is_loaded(), "must be"); + } + }); + + Handle pd; + PackageEntry* pkg_entry = nullptr; + + // Since a hidden class does not have a name, it cannot be reloaded + // normally via the system dictionary. Instead, we have to finish the + // loading job here. + + if (HeapShared::is_lambda_proxy_klass(ik)) { + InstanceKlass* nest_host = ik->nest_host_not_null(); + assert(nest_host->is_loaded(), "must be"); + pd = Handle(THREAD, nest_host->protection_domain()); + pkg_entry = nest_host->package(); + } + + ik->restore_unshareable_info(loader_data, pd, pkg_entry, CHECK); + SystemDictionary::load_shared_class_misc(ik, loader_data); + ik->add_to_hierarchy(THREAD); + assert(ik->is_loaded(), "Must be in at least loaded state"); + + DEBUG_ONLY({ + // Make sure we don't make this hidden class available by name, even if we don't + // use any special ClassLoaderData. + Handle loader(THREAD, loader_data->class_loader()); + ResourceMark rm(THREAD); + assert(SystemDictionary::resolve_or_null(ik->name(), loader, pd, THREAD) == nullptr, + "hidden classes cannot be accessible by name: %s", ik->external_name()); + if (HAS_PENDING_EXCEPTION) { + CLEAR_PENDING_EXCEPTION; + } + }); +} + +void AOTLinkedClassBulkLoader::finish_loading_javabase_classes(TRAPS) { + init_required_classes_for_loader(Handle(), AOTLinkedClassTable::for_static_archive()->boot(), CHECK); +} + +// Some AOT-linked classes for must be initialized early. This includes +// - classes that were AOT-initialized by AOTClassInitializer +// - the classes of all objects that are reachable from the archived mirrors of +// the AOT-linked classes for . +void AOTLinkedClassBulkLoader::init_required_classes_for_loader(Handle class_loader, Array* classes, TRAPS) { + if (classes != nullptr) { + for (int i = 0; i < classes->length(); i++) { + InstanceKlass* ik = classes->at(i); + if (ik->class_loader_data() == nullptr) { + // This class is not yet loaded. We will initialize it in a later phase. + // For example, we have loaded only AOTLinkedClassCategory::BOOT1 classes + // but k is part of AOTLinkedClassCategory::BOOT2. + continue; + } + if (ik->has_aot_initialized_mirror()) { + ik->initialize_with_aot_initialized_mirror(CHECK); + } else { + // Some cached heap objects may hold references to methods in aot-linked + // classes (via MemberName). We need to make sure all classes are + // linked to allow such MemberNames to be invoked. + ik->link_class(CHECK); + } + } + } + + HeapShared::init_classes_for_special_subgraph(class_loader, CHECK); +} + +bool AOTLinkedClassBulkLoader::is_pending_aot_linked_class(Klass* k) { + if (!CDSConfig::is_using_aot_linked_classes()) { + return false; + } + + if (_all_completed) { // no more pending aot-linked classes + return false; + } + + if (k->is_objArray_klass()) { + k = ObjArrayKlass::cast(k)->bottom_klass(); + } + if (!k->is_instance_klass()) { + // type array klasses (and their higher dimensions), + // must have been loaded before a GC can ever happen. + return false; + } + + // There's a small window during VM start-up where a not-yet loaded aot-linked + // class k may be discovered by the GC during VM initialization. This can happen + // when the heap contains an aot-cached instance of k, but k is not ready to be + // loaded yet. (TODO: JDK-8342429 eliminates this possibility) + // + // The following checks try to limit this window as much as possible for each of + // the four AOTLinkedClassCategory of classes that can be aot-linked. + + InstanceKlass* ik = InstanceKlass::cast(k); + if (ik->is_shared_boot_class()) { + if (ik->module() != nullptr && ik->in_javabase_module()) { + // AOTLinkedClassCategory::BOOT1 -- all aot-linked classes in + // java.base must have been loaded before a GC can ever happen. + return false; + } else { + // AOTLinkedClassCategory::BOOT2 classes cannot be loaded until + // module system is ready. + return !_boot2_completed; + } + } else if (ik->is_shared_platform_class()) { + // AOTLinkedClassCategory::PLATFORM classes cannot be loaded until + // the platform class loader is initialized. + return !_platform_completed; + } else if (ik->is_shared_app_class()) { + // AOTLinkedClassCategory::APP cannot be loaded until the app class loader + // is initialized. + return !_app_completed; + } else { + return false; + } +} diff --git a/src/hotspot/share/cds/aotLinkedClassBulkLoader.hpp b/src/hotspot/share/cds/aotLinkedClassBulkLoader.hpp new file mode 100644 index 00000000000..a8e6365b899 --- /dev/null +++ b/src/hotspot/share/cds/aotLinkedClassBulkLoader.hpp @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#ifndef SHARE_CDS_AOTLINKEDCLASSBULKLOADER_HPP +#define SHARE_CDS_AOTLINKEDCLASSBULKLOADER_HPP + +#include "memory/allStatic.hpp" +#include "memory/allocation.hpp" +#include "runtime/handles.hpp" +#include "utilities/exceptions.hpp" +#include "utilities/macros.hpp" + +class AOTLinkedClassTable; +class ClassLoaderData; +class InstanceKlass; +class SerializeClosure; +template class Array; +enum class AOTLinkedClassCategory : int; + +// During a Production Run, the AOTLinkedClassBulkLoader loads all classes from +// a AOTLinkedClassTable into their respective ClassLoaders. This happens very early +// in the JVM bootstrap stage, before any application code is executed. +// +class AOTLinkedClassBulkLoader : AllStatic { + static bool _boot2_completed; + static bool _platform_completed; + static bool _app_completed; + static bool _all_completed; + static void load_classes_in_loader(JavaThread* current, AOTLinkedClassCategory class_category, oop class_loader_oop); + static void load_classes_in_loader_impl(AOTLinkedClassCategory class_category, oop class_loader_oop, TRAPS); + static void load_table(AOTLinkedClassTable* table, AOTLinkedClassCategory class_category, Handle loader, TRAPS); + static void initiate_loading(JavaThread* current, const char* category, Handle initiating_loader, Array* classes); + static void load_classes_impl(AOTLinkedClassCategory class_category, Array* classes, + const char* category_name, Handle loader, TRAPS); + static void load_hidden_class(ClassLoaderData* loader_data, InstanceKlass* ik, TRAPS); + static void init_required_classes_for_loader(Handle class_loader, Array* classes, TRAPS); +public: + static void serialize(SerializeClosure* soc, bool is_static_archive) NOT_CDS_RETURN; + + static void load_javabase_classes(JavaThread* current) NOT_CDS_RETURN; + static void load_non_javabase_classes(JavaThread* current) NOT_CDS_RETURN; + static void finish_loading_javabase_classes(TRAPS) NOT_CDS_RETURN; + static void exit_on_exception(JavaThread* current); + + static bool is_pending_aot_linked_class(Klass* k) NOT_CDS_RETURN_(false); +}; + +#endif // SHARE_CDS_AOTLINKEDCLASSBULKLOADER_HPP diff --git a/src/hotspot/share/cds/aotLinkedClassTable.cpp b/src/hotspot/share/cds/aotLinkedClassTable.cpp new file mode 100644 index 00000000000..bed090f00a9 --- /dev/null +++ b/src/hotspot/share/cds/aotLinkedClassTable.cpp @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#include "precompiled.hpp" +#include "cds/aotLinkedClassTable.hpp" +#include "cds/cdsConfig.hpp" +#include "cds/serializeClosure.hpp" +#include "oops/array.hpp" + +AOTLinkedClassTable AOTLinkedClassTable::_for_static_archive; +AOTLinkedClassTable AOTLinkedClassTable::_for_dynamic_archive; + +void AOTLinkedClassTable::serialize(SerializeClosure* soc) { + soc->do_ptr((void**)&_boot); + soc->do_ptr((void**)&_boot2); + soc->do_ptr((void**)&_platform); + soc->do_ptr((void**)&_app); +} + diff --git a/src/hotspot/share/cds/aotLinkedClassTable.hpp b/src/hotspot/share/cds/aotLinkedClassTable.hpp new file mode 100644 index 00000000000..2a199c15edd --- /dev/null +++ b/src/hotspot/share/cds/aotLinkedClassTable.hpp @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +#ifndef SHARE_CDS_AOTLINKEDCLASSTABLE_HPP +#define SHARE_CDS_AOTLINKEDCLASSTABLE_HPP + +#include "utilities/globalDefinitions.hpp" + +template class Array; +class InstanceKlass; +class SerializeClosure; + +// Classes to be bulk-loaded, in the "linked" state, at VM bootstrap. +// +// AOTLinkedClassTable is produced by AOTClassLinker when an AOTCache is assembled. +// +// AOTLinkedClassTable is consumed by AOTLinkedClassBulkLoader when an AOTCache is used +// in a production run. +// +class AOTLinkedClassTable { + // The VM may load up to 2 CDS archives -- static and dynamic. Each + // archive can have its own AOTLinkedClassTable. + static AOTLinkedClassTable _for_static_archive; + static AOTLinkedClassTable _for_dynamic_archive; + + Array* _boot; // only java.base classes + Array* _boot2; // boot classes in other modules + Array* _platform; + Array* _app; + +public: + AOTLinkedClassTable() : + _boot(nullptr), _boot2(nullptr), + _platform(nullptr), _app(nullptr) {} + + static AOTLinkedClassTable* for_static_archive() { return &_for_static_archive; } + static AOTLinkedClassTable* for_dynamic_archive() { return &_for_dynamic_archive; } + + static AOTLinkedClassTable* get(bool is_static_archive) { + return is_static_archive ? for_static_archive() : for_dynamic_archive(); + } + + Array* boot() const { return _boot; } + Array* boot2() const { return _boot2; } + Array* platform() const { return _platform; } + Array* app() const { return _app; } + + void set_boot (Array* value) { _boot = value; } + void set_boot2 (Array* value) { _boot2 = value; } + void set_platform(Array* value) { _platform = value; } + void set_app (Array* value) { _app = value; } + + void serialize(SerializeClosure* soc); +}; + +#endif // SHARE_CDS_AOTLINKEDCLASSTABLE_HPP diff --git a/src/hotspot/share/cds/archiveBuilder.cpp b/src/hotspot/share/cds/archiveBuilder.cpp index a181257a519..da4319955ea 100644 --- a/src/hotspot/share/cds/archiveBuilder.cpp +++ b/src/hotspot/share/cds/archiveBuilder.cpp @@ -23,6 +23,8 @@ */ #include "precompiled.hpp" +#include "cds/aotClassLinker.hpp" +#include "cds/aotLinkedClassBulkLoader.hpp" #include "cds/archiveBuilder.hpp" #include "cds/archiveHeapWriter.hpp" #include "cds/archiveUtils.hpp" @@ -33,7 +35,9 @@ #include "cds/heapShared.hpp" #include "cds/metaspaceShared.hpp" #include "cds/regeneratedClasses.hpp" +#include "classfile/classLoader.hpp" #include "classfile/classLoaderDataShared.hpp" +#include "classfile/classLoaderExt.hpp" #include "classfile/javaClasses.hpp" #include "classfile/symbolTable.hpp" #include "classfile/systemDictionaryShared.hpp" @@ -226,6 +230,10 @@ bool ArchiveBuilder::gather_klass_and_symbol(MetaspaceClosure::Ref* ref, bool re assert(klass->is_klass(), "must be"); if (!is_excluded(klass)) { _klasses->append(klass); + if (klass->is_hidden()) { + assert(klass->is_instance_klass(), "must be"); + assert(SystemDictionaryShared::should_hidden_class_be_archived(InstanceKlass::cast(klass)), "must be"); + } } // See RunTimeClassInfo::get_for(): make sure we have enough space for both maximum // Klass alignment as well as the RuntimeInfo* pointer we will embed in front of a Klass. @@ -284,6 +292,8 @@ void ArchiveBuilder::gather_klasses_and_symbols() { // but this should be enough for now _estimated_metaspaceobj_bytes += 200 * 1024 * 1024; } + + AOTClassLinker::add_candidates(); } int ArchiveBuilder::compare_symbols_by_address(Symbol** a, Symbol** b) { @@ -310,6 +320,15 @@ size_t ArchiveBuilder::estimate_archive_size() { size_t dictionary_est = SystemDictionaryShared::estimate_size_for_archive(); _estimated_hashtable_bytes = symbol_table_est + dictionary_est; + if (CDSConfig::is_dumping_aot_linked_classes()) { + // This is difficult to estimate when dumping the dynamic archive, as the + // AOTLinkedClassTable may need to contain classes in the static archive as well. + // + // Just give a generous estimate for now. We will remove estimate_archive_size() + // in JDK-8340416 + _estimated_hashtable_bytes += 20 * 1024 * 1024; + } + size_t total = 0; total += _estimated_metaspaceobj_bytes; @@ -423,11 +442,12 @@ bool ArchiveBuilder::gather_one_source_obj(MetaspaceClosure::Ref* ref, bool read if (src_obj == nullptr) { return false; } + + remember_embedded_pointer_in_enclosing_obj(ref); if (RegeneratedClasses::has_been_regenerated(src_obj)) { // No need to copy it. We will later relocate it to point to the regenerated klass/method. return false; } - remember_embedded_pointer_in_enclosing_obj(ref); FollowMode follow_mode = get_follow_mode(ref); SourceObjInfo src_info(ref, read_only, follow_mode); @@ -740,6 +760,16 @@ void ArchiveBuilder::mark_and_relocate_to_buffered_addr(address* ptr_location) { ArchivePtrMarker::mark_pointer(ptr_location); } +bool ArchiveBuilder::has_been_buffered(address src_addr) const { + if (RegeneratedClasses::has_been_regenerated(src_addr) || + _src_obj_table.get(src_addr) == nullptr || + get_buffered_addr(src_addr) == nullptr) { + return false; + } else { + return true; + } +} + address ArchiveBuilder::get_buffered_addr(address src_addr) const { SourceObjInfo* p = _src_obj_table.get(src_addr); assert(p != nullptr, "src_addr " INTPTR_FORMAT " is used but has not been archived", @@ -767,17 +797,35 @@ void ArchiveBuilder::relocate_metaspaceobj_embedded_pointers() { relocate_embedded_pointers(&_ro_src_objs); } +#define ADD_COUNT(x) \ + x += 1; \ + x ## _a += aotlinked ? 1 : 0; \ + x ## _i += inited ? 1 : 0; + +#define DECLARE_INSTANCE_KLASS_COUNTER(x) \ + int x = 0; \ + int x ## _a = 0; \ + int x ## _i = 0; + void ArchiveBuilder::make_klasses_shareable() { - int num_instance_klasses = 0; - int num_boot_klasses = 0; - int num_platform_klasses = 0; - int num_app_klasses = 0; - int num_hidden_klasses = 0; + DECLARE_INSTANCE_KLASS_COUNTER(num_instance_klasses); + DECLARE_INSTANCE_KLASS_COUNTER(num_boot_klasses); + DECLARE_INSTANCE_KLASS_COUNTER(num_vm_klasses); + DECLARE_INSTANCE_KLASS_COUNTER(num_platform_klasses); + DECLARE_INSTANCE_KLASS_COUNTER(num_app_klasses); + DECLARE_INSTANCE_KLASS_COUNTER(num_old_klasses); + DECLARE_INSTANCE_KLASS_COUNTER(num_hidden_klasses); + DECLARE_INSTANCE_KLASS_COUNTER(num_enum_klasses); + DECLARE_INSTANCE_KLASS_COUNTER(num_unregistered_klasses); int num_unlinked_klasses = 0; - int num_unregistered_klasses = 0; int num_obj_array_klasses = 0; int num_type_array_klasses = 0; + int boot_unlinked = 0; + int platform_unlinked = 0; + int app_unlinked = 0; + int unreg_unlinked = 0; + for (int i = 0; i < klasses()->length(); i++) { // Some of the code in ConstantPool::remove_unshareable_info() requires the classes // to be in linked state, so it must be call here before the next loop, which returns @@ -791,8 +839,12 @@ void ArchiveBuilder::make_klasses_shareable() { for (int i = 0; i < klasses()->length(); i++) { const char* type; const char* unlinked = ""; + const char* kind = ""; const char* hidden = ""; + const char* old = ""; const char* generated = ""; + const char* aotlinked_msg = ""; + const char* inited_msg = ""; Klass* k = get_buffered_addr(klasses()->at(i)); k->remove_java_mirror(); #ifdef _LP64 @@ -815,60 +867,127 @@ void ArchiveBuilder::make_klasses_shareable() { k->remove_unshareable_info(); } else { assert(k->is_instance_klass(), " must be"); - num_instance_klasses ++; InstanceKlass* ik = InstanceKlass::cast(k); - if (ik->is_shared_boot_class()) { + InstanceKlass* src_ik = get_source_addr(ik); + bool aotlinked = AOTClassLinker::is_candidate(src_ik); + bool inited = ik->has_aot_initialized_mirror(); + ADD_COUNT(num_instance_klasses); + if (CDSConfig::is_dumping_dynamic_archive()) { + // For static dump, class loader type are already set. + ik->assign_class_loader_type(); + } + if (ik->is_hidden()) { + ADD_COUNT(num_hidden_klasses); + hidden = " hidden"; + oop loader = k->class_loader(); + if (loader == nullptr) { + type = "boot"; + ADD_COUNT(num_boot_klasses); + } else if (loader == SystemDictionary::java_platform_loader()) { + type = "plat"; + ADD_COUNT(num_platform_klasses); + } else if (loader == SystemDictionary::java_system_loader()) { + type = "app"; + ADD_COUNT(num_app_klasses); + } else { + type = "bad"; + assert(0, "shouldn't happen"); + } + if (CDSConfig::is_dumping_invokedynamic()) { + assert(HeapShared::is_archivable_hidden_klass(ik), "sanity"); + } else { + // Legacy CDS support for lambda proxies + assert(HeapShared::is_lambda_proxy_klass(ik), "sanity"); + } + } else if (ik->is_shared_boot_class()) { type = "boot"; - num_boot_klasses ++; + ADD_COUNT(num_boot_klasses); } else if (ik->is_shared_platform_class()) { type = "plat"; - num_platform_klasses ++; + ADD_COUNT(num_platform_klasses); } else if (ik->is_shared_app_class()) { type = "app"; - num_app_klasses ++; + ADD_COUNT(num_app_klasses); } else { assert(ik->is_shared_unregistered_class(), "must be"); type = "unreg"; - num_unregistered_klasses ++; + ADD_COUNT(num_unregistered_klasses); + } + + if (AOTClassLinker::is_vm_class(src_ik)) { + ADD_COUNT(num_vm_klasses); } if (!ik->is_linked()) { num_unlinked_klasses ++; - unlinked = " ** unlinked"; + unlinked = " unlinked"; + if (ik->is_shared_boot_class()) { + boot_unlinked ++; + } else if (ik->is_shared_platform_class()) { + platform_unlinked ++; + } else if (ik->is_shared_app_class()) { + app_unlinked ++; + } else { + unreg_unlinked ++; + } } - if (ik->is_hidden()) { - num_hidden_klasses ++; - hidden = " ** hidden"; + if (ik->is_interface()) { + kind = " interface"; + } else if (src_ik->is_enum_subclass()) { + kind = " enum"; + ADD_COUNT(num_enum_klasses); + } + + if (!ik->can_be_verified_at_dumptime()) { + ADD_COUNT(num_old_klasses); + old = " old"; } if (ik->is_generated_shared_class()) { - generated = " ** generated"; + generated = " generated"; + } + if (aotlinked) { + aotlinked_msg = " aot-linked"; } + if (inited) { + inited_msg = " inited"; + } + MetaspaceShared::rewrite_nofast_bytecodes_and_calculate_fingerprints(Thread::current(), ik); ik->remove_unshareable_info(); } if (log_is_enabled(Debug, cds, class)) { ResourceMark rm; - log_debug(cds, class)("klasses[%5d] = " PTR_FORMAT " %-5s %s%s%s%s", i, + log_debug(cds, class)("klasses[%5d] = " PTR_FORMAT " %-5s %s%s%s%s%s%s%s%s", i, p2i(to_requested(k)), type, k->external_name(), - hidden, unlinked, generated); + kind, hidden, old, unlinked, generated, aotlinked_msg, inited_msg); } } +#define STATS_FORMAT "= %5d, aot-linked = %5d, inited = %5d" +#define STATS_PARAMS(x) num_ ## x, num_ ## x ## _a, num_ ## x ## _i + log_info(cds)("Number of classes %d", num_instance_klasses + num_obj_array_klasses + num_type_array_klasses); - log_info(cds)(" instance classes = %5d", num_instance_klasses); - log_info(cds)(" boot = %5d", num_boot_klasses); - log_info(cds)(" app = %5d", num_app_klasses); - log_info(cds)(" platform = %5d", num_platform_klasses); - log_info(cds)(" unregistered = %5d", num_unregistered_klasses); - log_info(cds)(" (hidden) = %5d", num_hidden_klasses); - log_info(cds)(" (unlinked) = %5d", num_unlinked_klasses); + log_info(cds)(" instance classes " STATS_FORMAT, STATS_PARAMS(instance_klasses)); + log_info(cds)(" boot " STATS_FORMAT, STATS_PARAMS(boot_klasses)); + log_info(cds)(" vm " STATS_FORMAT, STATS_PARAMS(vm_klasses)); + log_info(cds)(" platform " STATS_FORMAT, STATS_PARAMS(platform_klasses)); + log_info(cds)(" app " STATS_FORMAT, STATS_PARAMS(app_klasses)); + log_info(cds)(" unregistered " STATS_FORMAT, STATS_PARAMS(unregistered_klasses)); + log_info(cds)(" (enum) " STATS_FORMAT, STATS_PARAMS(enum_klasses)); + log_info(cds)(" (hidden) " STATS_FORMAT, STATS_PARAMS(hidden_klasses)); + log_info(cds)(" (old) " STATS_FORMAT, STATS_PARAMS(old_klasses)); + log_info(cds)(" (unlinked) = %5d, boot = %d, plat = %d, app = %d, unreg = %d", + num_unlinked_klasses, boot_unlinked, platform_unlinked, app_unlinked, unreg_unlinked); log_info(cds)(" obj array classes = %5d", num_obj_array_klasses); log_info(cds)(" type array classes = %5d", num_type_array_klasses); log_info(cds)(" symbols = %5d", _symbols->length()); +#undef STATS_FORMAT +#undef STATS_PARAMS + DynamicArchive::make_array_klasses_shareable(); } @@ -876,6 +995,7 @@ void ArchiveBuilder::serialize_dynamic_archivable_items(SerializeClosure* soc) { SymbolTable::serialize_shared_table_header(soc, false); SystemDictionaryShared::serialize_dictionary_headers(soc, false); DynamicArchive::serialize_array_klasses(soc); + AOTLinkedClassBulkLoader::serialize(soc, false); } uintx ArchiveBuilder::buffer_to_offset(address p) const { diff --git a/src/hotspot/share/cds/archiveBuilder.hpp b/src/hotspot/share/cds/archiveBuilder.hpp index f306e4676b3..39fffc26c37 100644 --- a/src/hotspot/share/cds/archiveBuilder.hpp +++ b/src/hotspot/share/cds/archiveBuilder.hpp @@ -292,7 +292,7 @@ class ArchiveBuilder : public StackObj { intx buffer_to_requested_delta() const { return _buffer_to_requested_delta; } bool is_in_buffer_space(address p) const { - return (buffer_bottom() <= p && p < buffer_top()); + return (buffer_bottom() != nullptr && buffer_bottom() <= p && p < buffer_top()); } template bool is_in_requested_static_archive(T p) const { @@ -420,6 +420,11 @@ class ArchiveBuilder : public StackObj { mark_and_relocate_to_buffered_addr((address*)ptr_location); } + bool has_been_buffered(address src_addr) const; + template bool has_been_buffered(T src_addr) const { + return has_been_buffered((address)src_addr); + } + address get_buffered_addr(address src_addr) const; template T get_buffered_addr(T src_addr) const { return (T)get_buffered_addr((address)src_addr); diff --git a/src/hotspot/share/cds/archiveHeapLoader.cpp b/src/hotspot/share/cds/archiveHeapLoader.cpp index 01831cf0f3e..b05fd20f4f5 100644 --- a/src/hotspot/share/cds/archiveHeapLoader.cpp +++ b/src/hotspot/share/cds/archiveHeapLoader.cpp @@ -449,10 +449,6 @@ class PatchNativePointers: public BitMapClosure { bool do_bit(size_t offset) { Metadata** p = _start + offset; *p = (Metadata*)(address(*p) + MetaspaceShared::relocation_delta()); - // Currently we have only Klass pointers in heap objects. - // This needs to be relaxed when we support other types of native - // pointers such as Method. - assert(((Klass*)(*p))->is_klass(), "must be"); return true; } }; diff --git a/src/hotspot/share/cds/archiveHeapWriter.cpp b/src/hotspot/share/cds/archiveHeapWriter.cpp index 636b368117d..be821044a96 100644 --- a/src/hotspot/share/cds/archiveHeapWriter.cpp +++ b/src/hotspot/share/cds/archiveHeapWriter.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -27,14 +27,15 @@ #include "cds/cdsConfig.hpp" #include "cds/filemap.hpp" #include "cds/heapShared.hpp" +#include "classfile/javaClasses.hpp" #include "classfile/systemDictionary.hpp" #include "gc/shared/collectedHeap.hpp" #include "memory/iterator.inline.hpp" #include "memory/oopFactory.hpp" #include "memory/universe.hpp" #include "oops/compressedOops.hpp" -#include "oops/oop.inline.hpp" #include "oops/objArrayOop.inline.hpp" +#include "oops/oop.inline.hpp" #include "oops/oopHandle.inline.hpp" #include "oops/typeArrayKlass.hpp" #include "oops/typeArrayOop.hpp" @@ -535,7 +536,14 @@ oop ArchiveHeapWriter::load_oop_from_buffer(narrowOop* buffered_addr) { template void ArchiveHeapWriter::relocate_field_in_buffer(T* field_addr_in_buffer, CHeapBitMap* oopmap) { oop source_referent = load_source_oop_from_buffer(field_addr_in_buffer); - if (!CompressedOops::is_null(source_referent)) { + if (source_referent != nullptr) { + if (java_lang_Class::is_instance(source_referent)) { + // When the source object points to a "real" mirror, the buffered object should point + // to the "scratch" mirror, which has all unarchivable fields scrubbed (to be reinstated + // at run time). + source_referent = HeapShared::scratch_java_mirror(source_referent); + assert(source_referent != nullptr, "must be"); + } oop request_referent = source_obj_to_requested_obj(source_referent); store_requested_oop_in_buffer(field_addr_in_buffer, request_referent); mark_oop_pointer(field_addr_in_buffer, oopmap); @@ -731,7 +739,9 @@ void ArchiveHeapWriter::compute_ptrmap(ArchiveHeapInfo* heap_info) { Metadata** buffered_field_addr = requested_addr_to_buffered_addr(requested_field_addr); Metadata* native_ptr = *buffered_field_addr; - assert(native_ptr != nullptr, "sanity"); + guarantee(native_ptr != nullptr, "sanity"); + guarantee(ArchiveBuilder::current()->has_been_buffered((address)native_ptr), + "Metadata %p should have been archived", native_ptr); address buffered_native_ptr = ArchiveBuilder::current()->get_buffered_addr((address)native_ptr); address requested_native_ptr = ArchiveBuilder::current()->to_requested(buffered_native_ptr); diff --git a/src/hotspot/share/cds/archiveUtils.cpp b/src/hotspot/share/cds/archiveUtils.cpp index c7282f7d97c..4d717879e0f 100644 --- a/src/hotspot/share/cds/archiveUtils.cpp +++ b/src/hotspot/share/cds/archiveUtils.cpp @@ -39,6 +39,7 @@ #include "memory/metaspaceUtils.hpp" #include "memory/resourceArea.hpp" #include "oops/compressedOops.inline.hpp" +#include "oops/klass.inline.hpp" #include "runtime/arguments.hpp" #include "utilities/bitMap.inline.hpp" #include "utilities/debug.hpp" @@ -370,6 +371,14 @@ void ArchiveUtils::log_to_classlist(BootstrapInfo* bootstrap_specifier, TRAPS) { } } +bool ArchiveUtils::has_aot_initialized_mirror(InstanceKlass* src_ik) { + if (SystemDictionaryShared::is_excluded_class(src_ik)) { + assert(!ArchiveBuilder::current()->has_been_buffered(src_ik), "sanity"); + return false; + } + return ArchiveBuilder::current()->get_buffered_addr(src_ik)->has_aot_initialized_mirror(); +} + size_t HeapRootSegments::size_in_bytes(size_t seg_idx) { assert(seg_idx < _count, "In range"); return objArrayOopDesc::object_size(size_in_elems(seg_idx)) * HeapWordSize; diff --git a/src/hotspot/share/cds/archiveUtils.hpp b/src/hotspot/share/cds/archiveUtils.hpp index 7fb8e538084..606f5137e9d 100644 --- a/src/hotspot/share/cds/archiveUtils.hpp +++ b/src/hotspot/share/cds/archiveUtils.hpp @@ -38,6 +38,9 @@ class BootstrapInfo; class ReservedSpace; class VirtualSpace; +template class Array; +template class GrowableArray; + // ArchivePtrMarker is used to mark the location of pointers embedded in a CDS archive. E.g., when an // InstanceKlass k is dumped, we mark the location of the k->_name pointer by effectively calling // mark_pointer(/*ptr_loc=*/&k->_name). It's required that (_prt_base <= ptr_loc < _ptr_end). _ptr_base is @@ -253,6 +256,8 @@ class ArchiveUtils { public: static const uintx MAX_SHARED_DELTA = 0x7FFFFFFF; static void log_to_classlist(BootstrapInfo* bootstrap_specifier, TRAPS) NOT_CDS_RETURN; + static bool has_aot_initialized_mirror(InstanceKlass* src_ik); + template static Array* archive_array(GrowableArray* tmp_array); // offset must represent an object of type T in the mapped shared space. Return // a direct pointer to this object. diff --git a/src/hotspot/share/cds/archiveUtils.inline.hpp b/src/hotspot/share/cds/archiveUtils.inline.hpp index 7df344e3701..537b3d1670c 100644 --- a/src/hotspot/share/cds/archiveUtils.inline.hpp +++ b/src/hotspot/share/cds/archiveUtils.inline.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -27,7 +27,10 @@ #include "cds/archiveUtils.hpp" +#include "cds/archiveBuilder.hpp" +#include "oops/array.hpp" #include "utilities/bitMap.inline.hpp" +#include "utilities/growableArray.hpp" inline bool SharedDataRelocator::do_bit(size_t offset) { address* p = _patch_base + offset; @@ -47,4 +50,19 @@ inline bool SharedDataRelocator::do_bit(size_t offset) { return true; // keep iterating } +// Returns the address of an Array that's allocated in the ArchiveBuilder "buffer" space. +template +Array* ArchiveUtils::archive_array(GrowableArray* tmp_array) { + Array* archived_array = ArchiveBuilder::new_ro_array(tmp_array->length()); + for (int i = 0; i < tmp_array->length(); i++) { + archived_array->at_put(i, tmp_array->at(i)); + if (std::is_pointer::value) { + ArchivePtrMarker::mark_pointer(archived_array->adr_at(i)); + } + } + + return archived_array; +} + + #endif // SHARE_CDS_ARCHIVEUTILS_INLINE_HPP diff --git a/src/hotspot/share/cds/cdsConfig.cpp b/src/hotspot/share/cds/cdsConfig.cpp index 691a1983732..ba5d12e6450 100644 --- a/src/hotspot/share/cds/cdsConfig.cpp +++ b/src/hotspot/share/cds/cdsConfig.cpp @@ -33,19 +33,27 @@ #include "logging/log.hpp" #include "memory/universe.hpp" #include "runtime/arguments.hpp" +#include "runtime/globals_extension.hpp" #include "runtime/java.hpp" +#include "runtime/vmThread.hpp" #include "utilities/defaultStream.hpp" +#include "utilities/formatBuffer.hpp" bool CDSConfig::_is_dumping_static_archive = false; bool CDSConfig::_is_dumping_dynamic_archive = false; bool CDSConfig::_is_using_optimized_module_handling = true; bool CDSConfig::_is_dumping_full_module_graph = true; bool CDSConfig::_is_using_full_module_graph = true; +bool CDSConfig::_has_aot_linked_classes = false; +bool CDSConfig::_has_archived_invokedynamic = false; +bool CDSConfig::_old_cds_flags_used = false; char* CDSConfig::_default_archive_path = nullptr; char* CDSConfig::_static_archive_path = nullptr; char* CDSConfig::_dynamic_archive_path = nullptr; +JavaThread* CDSConfig::_dumper_thread = nullptr; + int CDSConfig::get_status() { assert(Universe::is_fully_initialized(), "status is finalized only after Universe is initialized"); return (is_dumping_archive() ? IS_DUMPING_ARCHIVE : 0) | @@ -54,7 +62,6 @@ int CDSConfig::get_status() { (is_using_archive() ? IS_USING_ARCHIVE : 0); } - void CDSConfig::initialize() { if (is_dumping_static_archive()) { if (RequireSharedSpaces) { @@ -334,7 +341,95 @@ bool CDSConfig::has_unsupported_runtime_module_options() { return false; } +#define CHECK_ALIAS(f) check_flag_alias(FLAG_IS_DEFAULT(f), #f) + +void CDSConfig::check_flag_alias(bool alias_is_default, const char* alias_name) { + if (_old_cds_flags_used && !alias_is_default) { + vm_exit_during_initialization(err_msg("Option %s cannot be used at the same time with " + "-Xshare:on, -Xshare:auto, -Xshare:off, -Xshare:dump, " + "DumpLoadedClassList, SharedClassListFile, or SharedArchiveFile", + alias_name)); + } +} + +void CDSConfig::check_flag_aliases() { + if (!FLAG_IS_DEFAULT(DumpLoadedClassList) || + !FLAG_IS_DEFAULT(SharedClassListFile) || + !FLAG_IS_DEFAULT(SharedArchiveFile)) { + _old_cds_flags_used = true; + } + + CHECK_ALIAS(AOTCache); + CHECK_ALIAS(AOTConfiguration); + CHECK_ALIAS(AOTMode); + + if (FLAG_IS_DEFAULT(AOTCache) && FLAG_IS_DEFAULT(AOTConfiguration) && FLAG_IS_DEFAULT(AOTMode)) { + // Aliases not used. + return; + } + + if (FLAG_IS_DEFAULT(AOTMode) || strcmp(AOTMode, "auto") == 0 || strcmp(AOTMode, "on") == 0) { + if (!FLAG_IS_DEFAULT(AOTConfiguration)) { + vm_exit_during_initialization("AOTConfiguration can only be used with -XX:AOTMode=record or -XX:AOTMode=create"); + } + + if (!FLAG_IS_DEFAULT(AOTCache)) { + assert(FLAG_IS_DEFAULT(SharedArchiveFile), "already checked"); + FLAG_SET_ERGO(SharedArchiveFile, AOTCache); + } + + UseSharedSpaces = true; + if (FLAG_IS_DEFAULT(AOTMode) || (strcmp(AOTMode, "auto") == 0)) { + RequireSharedSpaces = false; + } else { + assert(strcmp(AOTMode, "on") == 0, "already checked"); + RequireSharedSpaces = true; + } + } else if (strcmp(AOTMode, "off") == 0) { + UseSharedSpaces = false; + RequireSharedSpaces = false; + } else { + // AOTMode is record or create + if (FLAG_IS_DEFAULT(AOTConfiguration)) { + vm_exit_during_initialization(err_msg("-XX:AOTMode=%s cannot be used without setting AOTConfiguration", AOTMode)); + } + + if (strcmp(AOTMode, "record") == 0) { + if (!FLAG_IS_DEFAULT(AOTCache)) { + vm_exit_during_initialization("AOTCache must not be specified when using -XX:AOTMode=record"); + } + + assert(FLAG_IS_DEFAULT(DumpLoadedClassList), "already checked"); + FLAG_SET_ERGO(DumpLoadedClassList, AOTConfiguration); + UseSharedSpaces = false; + RequireSharedSpaces = false; + } else { + assert(strcmp(AOTMode, "create") == 0, "checked by AOTModeConstraintFunc"); + if (FLAG_IS_DEFAULT(AOTCache)) { + vm_exit_during_initialization("AOTCache must be specified when using -XX:AOTMode=create"); + } + + assert(FLAG_IS_DEFAULT(SharedClassListFile), "already checked"); + FLAG_SET_ERGO(SharedClassListFile, AOTConfiguration); + assert(FLAG_IS_DEFAULT(SharedArchiveFile), "already checked"); + FLAG_SET_ERGO(SharedArchiveFile, AOTCache); + + CDSConfig::enable_dumping_static_archive(); + } + } +} + bool CDSConfig::check_vm_args_consistency(bool patch_mod_javabase, bool mode_flag_cmd_line) { + check_flag_aliases(); + + if (AOTClassLinking) { + // If AOTClassLinking is specified, enable all AOT optimizations by default. + FLAG_SET_ERGO_IF_DEFAULT(AOTInvokeDynamicLinking, true); + } else { + // AOTInvokeDynamicLinking depends on AOTClassLinking. + FLAG_SET_ERGO(AOTInvokeDynamicLinking, false); + } + if (is_dumping_static_archive()) { if (!mode_flag_cmd_line) { // By default, -Xshare:dump runs in interpreter-only mode, which is required for deterministic archive. @@ -353,6 +448,9 @@ bool CDSConfig::check_vm_args_consistency(bool patch_mod_javabase, bool mode_fla // run to another which resulting in non-determinstic CDS archives. // Disable UseStringDeduplication while dumping CDS archive. UseStringDeduplication = false; + + // Don't use SoftReferences so that objects used by java.lang.invoke tables can be archived. + Arguments::PropertyList_add(new SystemProperty("java.lang.invoke.MethodHandleNatives.USE_SOFT_CACHE", "false", false)); } // RecordDynamicDumpInfo is not compatible with ArchiveClassesAtExit @@ -397,6 +495,11 @@ bool CDSConfig::check_vm_args_consistency(bool patch_mod_javabase, bool mode_fla return true; } +bool CDSConfig::allow_only_single_java_thread() { + // See comments in JVM_StartThread() + return is_dumping_static_archive(); +} + bool CDSConfig::is_using_archive() { return UseSharedSpaces; } @@ -411,12 +514,32 @@ void CDSConfig::stop_using_optimized_module_handling() { _is_using_full_module_graph = false; // This requires is_using_optimized_module_handling() } + +CDSConfig::DumperThreadMark::DumperThreadMark(JavaThread* current) { + assert(_dumper_thread == nullptr, "sanity"); + _dumper_thread = current; +} + +CDSConfig::DumperThreadMark::~DumperThreadMark() { + assert(_dumper_thread != nullptr, "sanity"); + _dumper_thread = nullptr; +} + +bool CDSConfig::current_thread_is_vm_or_dumper() { + Thread* t = Thread::current(); + return t != nullptr && (t->is_VM_thread() || t == _dumper_thread); +} + #if INCLUDE_CDS_JAVA_HEAP bool CDSConfig::is_dumping_heap() { // heap dump is not supported in dynamic dump return is_dumping_static_archive() && HeapShared::can_write(); } +bool CDSConfig::is_loading_heap() { + return ArchiveHeapLoader::is_in_use(); +} + bool CDSConfig::is_using_full_module_graph() { if (ClassLoaderDataShared::is_full_module_graph_loaded()) { return true; @@ -455,4 +578,39 @@ void CDSConfig::stop_using_full_module_graph(const char* reason) { } } } + +bool CDSConfig::is_dumping_aot_linked_classes() { + if (is_dumping_dynamic_archive()) { + return is_using_full_module_graph() && AOTClassLinking; + } else if (is_dumping_static_archive()) { + return is_dumping_full_module_graph() && AOTClassLinking; + } else { + return false; + } +} + +bool CDSConfig::is_using_aot_linked_classes() { + // Make sure we have the exact same module graph as in the assembly phase, or else + // some aot-linked classes may not be visible so cannot be loaded. + return is_using_full_module_graph() && _has_aot_linked_classes; +} + +void CDSConfig::set_has_aot_linked_classes(bool has_aot_linked_classes) { + _has_aot_linked_classes |= has_aot_linked_classes; +} + +bool CDSConfig::is_initing_classes_at_dump_time() { + return is_dumping_heap() && is_dumping_aot_linked_classes(); +} + +bool CDSConfig::is_dumping_invokedynamic() { + // Requires is_dumping_aot_linked_classes(). Otherwise the classes of some archived heap + // objects used by the archive indy callsites may be replaced at runtime. + return AOTInvokeDynamicLinking && is_dumping_aot_linked_classes() && is_dumping_heap(); +} + +bool CDSConfig::is_loading_invokedynamic() { + return UseSharedSpaces && is_using_full_module_graph() && _has_archived_invokedynamic; +} + #endif // INCLUDE_CDS_JAVA_HEAP diff --git a/src/hotspot/share/cds/cdsConfig.hpp b/src/hotspot/share/cds/cdsConfig.hpp index 7711a2ea1e2..cceaceeb6d7 100644 --- a/src/hotspot/share/cds/cdsConfig.hpp +++ b/src/hotspot/share/cds/cdsConfig.hpp @@ -29,6 +29,8 @@ #include "utilities/globalDefinitions.hpp" #include "utilities/macros.hpp" +class JavaThread; + class CDSConfig : public AllStatic { #if INCLUDE_CDS static bool _is_dumping_static_archive; @@ -36,10 +38,16 @@ class CDSConfig : public AllStatic { static bool _is_using_optimized_module_handling; static bool _is_dumping_full_module_graph; static bool _is_using_full_module_graph; + static bool _has_aot_linked_classes; + static bool _has_archived_invokedynamic; static char* _default_archive_path; static char* _static_archive_path; static char* _dynamic_archive_path; + + static bool _old_cds_flags_used; + + static JavaThread* _dumper_thread; #endif static void extract_shared_archive_paths(const char* archive_path, @@ -47,6 +55,9 @@ class CDSConfig : public AllStatic { char** top_archive_path); static void init_shared_archive_paths(); + static void check_flag_alias(bool alias_is_default, const char* alias_name); + static void check_flag_aliases(); + public: // Used by jdk.internal.misc.CDS.getCDSConfigStatus(); static const int IS_DUMPING_ARCHIVE = 1 << 0; @@ -57,6 +68,8 @@ class CDSConfig : public AllStatic { // Initialization and command-line checking static void initialize() NOT_CDS_RETURN; + static void set_old_cds_flags_used() { CDS_ONLY(_old_cds_flags_used = true); } + static bool old_cds_flags_used() { return CDS_ONLY(_old_cds_flags_used) NOT_CDS(false); } static void check_internal_module_property(const char* key, const char* value) NOT_CDS_RETURN; static void check_incompatible_property(const char* key, const char* value) NOT_CDS_RETURN; static void check_unsupported_dumping_module_options() NOT_CDS_RETURN; @@ -79,12 +92,19 @@ class CDSConfig : public AllStatic { static void enable_dumping_dynamic_archive() { CDS_ONLY(_is_dumping_dynamic_archive = true); } static void disable_dumping_dynamic_archive() { CDS_ONLY(_is_dumping_dynamic_archive = false); } + // Misc CDS features + static bool allow_only_single_java_thread() NOT_CDS_RETURN_(false); + // optimized_module_handling -- can we skip some expensive operations related to modules? static bool is_using_optimized_module_handling() { return CDS_ONLY(_is_using_optimized_module_handling) NOT_CDS(false); } static void stop_using_optimized_module_handling() NOT_CDS_RETURN; static bool is_logging_lambda_form_invokers() NOT_CDS_RETURN_(false); + static bool is_dumping_aot_linked_classes() NOT_CDS_JAVA_HEAP_RETURN_(false); + static bool is_using_aot_linked_classes() NOT_CDS_JAVA_HEAP_RETURN_(false); + static void set_has_aot_linked_classes(bool has_aot_linked_classes) NOT_CDS_JAVA_HEAP_RETURN; + // archive_path // Points to the classes.jsa in $JAVA_HOME @@ -96,13 +116,34 @@ class CDSConfig : public AllStatic { // --- Archived java objects - static bool is_dumping_heap() NOT_CDS_JAVA_HEAP_RETURN_(false); + static bool is_dumping_heap() NOT_CDS_JAVA_HEAP_RETURN_(false); + static bool is_loading_heap() NOT_CDS_JAVA_HEAP_RETURN_(false); + static bool is_initing_classes_at_dump_time() NOT_CDS_JAVA_HEAP_RETURN_(false); + + static bool is_dumping_invokedynamic() NOT_CDS_JAVA_HEAP_RETURN_(false); + static bool is_loading_invokedynamic() NOT_CDS_JAVA_HEAP_RETURN_(false); + static void set_has_archived_invokedynamic() { CDS_JAVA_HEAP_ONLY(_has_archived_invokedynamic = true); } // full_module_graph (requires optimized_module_handling) static bool is_dumping_full_module_graph() { return CDS_ONLY(_is_dumping_full_module_graph) NOT_CDS(false); } static bool is_using_full_module_graph() NOT_CDS_JAVA_HEAP_RETURN_(false); static void stop_dumping_full_module_graph(const char* reason = nullptr) NOT_CDS_JAVA_HEAP_RETURN; static void stop_using_full_module_graph(const char* reason = nullptr) NOT_CDS_JAVA_HEAP_RETURN; + + + // Some CDS functions assume that they are called only within a single-threaded context. I.e., + // they are called from: + // - The VM thread (e.g., inside VM_PopulateDumpSharedSpace) + // - The thread that performs prepatory steps before switching to the VM thread + // Since these two threads never execute concurrently, we can avoid using locks in these CDS + // function. For safety, these functions should assert with CDSConfig::current_thread_is_vm_or_dumper(). + class DumperThreadMark { + public: + DumperThreadMark(JavaThread* current); + ~DumperThreadMark(); + }; + + static bool current_thread_is_vm_or_dumper() NOT_CDS_RETURN_(false); }; #endif // SHARE_CDS_CDSCONFIG_HPP diff --git a/src/hotspot/share/cds/cdsEnumKlass.cpp b/src/hotspot/share/cds/cdsEnumKlass.cpp index b77f2fd9d16..17438428c80 100644 --- a/src/hotspot/share/cds/cdsEnumKlass.cpp +++ b/src/hotspot/share/cds/cdsEnumKlass.cpp @@ -39,7 +39,7 @@ bool CDSEnumKlass::is_enum_obj(oop orig_obj) { Klass* k = orig_obj->klass(); Klass* buffered_k = ArchiveBuilder::get_buffered_klass(k); return k->is_instance_klass() && - InstanceKlass::cast(k)->java_super() == vmClasses::Enum_klass(); + InstanceKlass::cast(k)->is_enum_subclass(); } // -- Handling of Enum objects diff --git a/src/hotspot/share/cds/cdsHeapVerifier.cpp b/src/hotspot/share/cds/cdsHeapVerifier.cpp index 29e5af97c6a..fbc58e503ca 100644 --- a/src/hotspot/share/cds/cdsHeapVerifier.cpp +++ b/src/hotspot/share/cds/cdsHeapVerifier.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,10 +23,14 @@ */ #include "precompiled.hpp" +#include "cds/aotClassInitializer.hpp" #include "cds/archiveBuilder.hpp" #include "cds/cdsHeapVerifier.hpp" #include "classfile/classLoaderDataGraph.hpp" #include "classfile/javaClasses.inline.hpp" +#include "classfile/moduleEntry.hpp" +#include "classfile/systemDictionaryShared.hpp" +#include "classfile/vmSymbols.hpp" #include "logging/log.hpp" #include "logging/logStream.hpp" #include "memory/resourceArea.hpp" @@ -38,12 +42,13 @@ #if INCLUDE_CDS_JAVA_HEAP // CDSHeapVerifier is used to check for problems where an archived object references a -// static field that may be reinitialized at runtime. In the following example, +// static field that may be get a different value at runtime. In the following example, // Foo.get.test() -// correctly returns true when CDS disabled, but incorrectly returns false when CDS is enabled. +// correctly returns true when CDS disabled, but incorrectly returns false when CDS is enabled, +// because the archived archivedFoo.bar value is different than Bar.bar. // // class Foo { -// final Foo archivedFoo; // this field is archived by CDS +// static final Foo archivedFoo; // this field is archived by CDS // Bar bar; // static { // CDS.initializeFromArchive(Foo.class); @@ -68,8 +73,8 @@ // [2] CDSHeapVerifier::do_entry() checks all the archived objects. None of them // should be in [1] // -// However, it's legal for *some* static fields to be references. This leads to the -// table of ADD_EXCL below. +// However, it's legal for *some* static fields to be referenced. The reasons are explained +// in the table of ADD_EXCL below. // // [A] In most of the cases, the module bootstrap code will update the static field // to point to part of the archived module graph. E.g., @@ -123,6 +128,12 @@ CDSHeapVerifier::CDSHeapVerifier() : _archived_objs(0), _problems(0) ADD_EXCL("sun/invoke/util/ValueConversions", "ONE_INT", // E "ZERO_INT"); // E + if (CDSConfig::is_dumping_invokedynamic()) { + ADD_EXCL("java/lang/invoke/InvokerBytecodeGenerator", "MEMBERNAME_FACTORY", // D + "CD_Object_array", // E same as <...>ConstantUtils.CD_Object_array::CD_Object + "INVOKER_SUPER_DESC"); // E same as java.lang.constant.ConstantDescs::CD_Object + } + # undef ADD_EXCL ClassLoaderDataGraph::classes_do(this); @@ -130,15 +141,16 @@ CDSHeapVerifier::CDSHeapVerifier() : _archived_objs(0), _problems(0) CDSHeapVerifier::~CDSHeapVerifier() { if (_problems > 0) { - log_warning(cds, heap)("Scanned %d objects. Found %d case(s) where " - "an object points to a static field that may be " - "reinitialized at runtime.", _archived_objs, _problems); + log_error(cds, heap)("Scanned %d objects. Found %d case(s) where " + "an object points to a static field that " + "may hold a different value at runtime.", _archived_objs, _problems); + MetaspaceShared::unrecoverable_writing_error(); } } class CDSHeapVerifier::CheckStaticFields : public FieldClosure { CDSHeapVerifier* _verifier; - InstanceKlass* _ik; + InstanceKlass* _ik; // The class whose static fields are being checked. const char** _exclusions; public: CheckStaticFields(CDSHeapVerifier* verifier, InstanceKlass* ik) @@ -151,9 +163,14 @@ class CDSHeapVerifier::CheckStaticFields : public FieldClosure { return; } + if (fd->signature()->equals("Ljdk/internal/access/JavaLangAccess;")) { + // A few classes have static fields that point to SharedSecrets.getJavaLangAccess(). + // This object carries no state and we can create a new one in the production run. + return; + } oop static_obj_field = _ik->java_mirror()->obj_field(fd->offset()); if (static_obj_field != nullptr) { - Klass* klass = static_obj_field->klass(); + Klass* field_type = static_obj_field->klass(); if (_exclusions != nullptr) { for (const char** p = _exclusions; *p != nullptr; p++) { if (fd->name()->equals(*p)) { @@ -173,11 +190,35 @@ class CDSHeapVerifier::CheckStaticFields : public FieldClosure { // This field points to an archived mirror. return; } - if (klass->has_archived_enum_objs()) { - // This klass is a subclass of java.lang.Enum. If any instance of this klass - // has been archived, we will archive all static fields of this klass. - // See HeapShared::initialize_enum_klass(). - return; + + if (field_type->is_instance_klass()) { + InstanceKlass* field_ik = InstanceKlass::cast(field_type); + if (field_ik->is_enum_subclass()) { + if (field_ik->has_archived_enum_objs() || ArchiveUtils::has_aot_initialized_mirror(field_ik)) { + // This field is an Enum. If any instance of this Enum has been archived, we will archive + // all static fields of this Enum as well. + return; + } + } + + if (field_ik->is_hidden() && ArchiveUtils::has_aot_initialized_mirror(field_ik)) { + // We have a static field in a core-library class that points to a method reference, which + // are safe to archive. + guarantee(_ik->module()->name() == vmSymbols::java_base(), "sanity"); + return; + } + + if (field_ik == vmClasses::MethodType_klass()) { + // The identity of MethodTypes are preserved between assembly phase and production runs + // (by MethodType::AOTHolder::archivedMethodTypes). No need to check. + return; + } + + if (field_ik == vmClasses::internal_Unsafe_klass() && ArchiveUtils::has_aot_initialized_mirror(field_ik)) { + // There's only a single instance of jdk/internal/misc/Unsafe, so all references will + // be pointing to this singleton, which has been archived. + return; + } } // This field *may* be initialized to a different value at runtime. Remember it @@ -188,7 +229,8 @@ class CDSHeapVerifier::CheckStaticFields : public FieldClosure { }; // Remember all the static object fields of every class that are currently -// loaded. +// loaded. Later, we will check if any archived objects reference one of +// these fields. void CDSHeapVerifier::do_klass(Klass* k) { if (k->is_instance_klass()) { InstanceKlass* ik = InstanceKlass::cast(k); @@ -200,6 +242,12 @@ void CDSHeapVerifier::do_klass(Klass* k) { return; } + if (ArchiveUtils::has_aot_initialized_mirror(ik)) { + // ik's won't be executed at runtime, the static fields in + // ik will carry their values to runtime. + return; + } + CheckStaticFields csf(this, ik); ik->do_local_static_fields(&csf); } @@ -221,10 +269,15 @@ inline bool CDSHeapVerifier::do_entry(oop& orig_obj, HeapShared::CachedOopInfo& // should be flagged by CDSHeapVerifier. return true; /* keep on iterating */ } + if (info->_holder->is_hidden()) { + return true; + } ResourceMark rm; + char* class_name = info->_holder->name()->as_C_string(); + char* field_name = info->_name->as_C_string(); LogStream ls(Log(cds, heap)::warning()); - ls.print_cr("Archive heap points to a static field that may be reinitialized at runtime:"); - ls.print_cr("Field: %s::%s", info->_holder->name()->as_C_string(), info->_name->as_C_string()); + ls.print_cr("Archive heap points to a static field that may hold a different value at runtime:"); + ls.print_cr("Field: %s::%s", class_name, field_name); ls.print("Value: "); orig_obj->print_on(&ls); ls.print_cr("--- trace begin ---"); @@ -266,6 +319,29 @@ void CDSHeapVerifier::trace_to_root(outputStream* st, oop orig_obj) { } } +const char* static_field_name(oop mirror, oop field) { + Klass* k = java_lang_Class::as_Klass(mirror); + if (k->is_instance_klass()) { + for (JavaFieldStream fs(InstanceKlass::cast(k)); !fs.done(); fs.next()) { + if (fs.access_flags().is_static()) { + fieldDescriptor& fd = fs.field_descriptor(); + switch (fd.field_type()) { + case T_OBJECT: + case T_ARRAY: + if (mirror->obj_field(fd.offset()) == field) { + return fs.name()->as_C_string(); + } + break; + default: + break; + } + } + } + } + + return ""; +} + int CDSHeapVerifier::trace_to_root(outputStream* st, oop orig_obj, oop orig_field, HeapShared::CachedOopInfo* info) { int level = 0; if (info->orig_referrer() != nullptr) { @@ -280,6 +356,9 @@ int CDSHeapVerifier::trace_to_root(outputStream* st, oop orig_obj, oop orig_fiel st->print("[%2d] ", level); orig_obj->print_address_on(st); st->print(" %s", k->internal_name()); + if (java_lang_Class::is_instance(orig_obj)) { + st->print(" (%s::%s)", java_lang_Class::as_Klass(orig_obj)->external_name(), static_field_name(orig_obj, orig_field)); + } if (orig_field != nullptr) { if (k->is_instance_klass()) { TraceFields clo(orig_obj, orig_field, st); diff --git a/src/hotspot/share/cds/cds_globals.hpp b/src/hotspot/share/cds/cds_globals.hpp index 828393a7b6b..38f5d8f46a6 100644 --- a/src/hotspot/share/cds/cds_globals.hpp +++ b/src/hotspot/share/cds/cds_globals.hpp @@ -94,6 +94,30 @@ "(2) always map at preferred address, and if unsuccessful, " \ "do not map the archive") \ range(0, 2) \ + \ + /*========== New "AOT" flags =========================================*/ \ + /* The following 3 flags are aliases of -Xshare:dump, */ \ + /* -XX:SharedArchiveFile=..., etc. See CDSConfig::check_flag_aliases()*/ \ + \ + product(ccstr, AOTMode, nullptr, \ + "Specifies how AOTCache should be created or used. Valid values " \ + "are: off, record, create, auto, on; the default is auto") \ + constraint(AOTModeConstraintFunc, AtParse) \ + \ + product(ccstr, AOTConfiguration, nullptr, \ + "Configuration information used by CreateAOTCache") \ + \ + product(ccstr, AOTCache, nullptr, \ + "Cache for improving start up and warm up") \ + \ + product(bool, AOTInvokeDynamicLinking, false, DIAGNOSTIC, \ + "AOT-link JVM_CONSTANT_InvokeDynamic entries in cached " \ + "ConstantPools") \ + \ + product(bool, AOTClassLinking, false, \ + "Load/link all archived classes for the boot/platform/app " \ + "loaders before application main") \ + // end of CDS_FLAGS DECLARE_FLAGS(CDS_FLAGS) diff --git a/src/hotspot/share/cds/classListParser.cpp b/src/hotspot/share/cds/classListParser.cpp index 694a179d7ee..57d14229795 100644 --- a/src/hotspot/share/cds/classListParser.cpp +++ b/src/hotspot/share/cds/classListParser.cpp @@ -23,9 +23,9 @@ */ #include "precompiled.hpp" +#include "cds/aotConstantPoolResolver.hpp" #include "cds/archiveUtils.hpp" #include "cds/classListParser.hpp" -#include "cds/classPrelinker.hpp" #include "cds/lambdaFormInvokers.hpp" #include "cds/metaspaceShared.hpp" #include "cds/unregisteredClasses.hpp" @@ -46,6 +46,7 @@ #include "memory/resourceArea.hpp" #include "oops/constantPool.inline.hpp" #include "runtime/atomic.hpp" +#include "runtime/globals_extension.hpp" #include "runtime/handles.inline.hpp" #include "runtime/java.hpp" #include "runtime/javaCalls.hpp" @@ -69,9 +70,13 @@ ClassListParser::ClassListParser(const char* file, ParseMode parse_mode) : log_info(cds)("Parsing %s%s", file, parse_lambda_forms_invokers_only() ? " (lambda form invokers only)" : ""); if (!_file_input.is_open()) { - char errmsg[JVM_MAXPATHLEN]; - os::lasterror(errmsg, JVM_MAXPATHLEN); - vm_exit_during_initialization("Loading classlist failed", errmsg); + char reason[JVM_MAXPATHLEN]; + os::lasterror(reason, JVM_MAXPATHLEN); + vm_exit_during_initialization(err_msg("Loading %s %s failed", + FLAG_IS_DEFAULT(AOTConfiguration) ? + "classlist" : "AOTConfiguration file", + file), + reason); } _token = _line = nullptr; _interfaces = new (mtClass) GrowableArray(10, mtClass); @@ -594,6 +599,18 @@ void ClassListParser::resolve_indy(JavaThread* current, Symbol* class_name_symbo } void ClassListParser::resolve_indy_impl(Symbol* class_name_symbol, TRAPS) { + if (CDSConfig::is_dumping_invokedynamic()) { + // The CP entry for the invokedynamic instruction will be resolved. + // No need to do the following. + return; + } + + // This is an older CDS optimization: + // We store a pre-generated version of the lambda proxy class in the AOT cache, + // which will be loaded via JVM_LookupLambdaProxyClassFromArchive(). + // This eliminate dynamic class generation of the proxy class, but we still need to + // resolve the CP entry for the invokedynamic instruction, which may result in + // generation of LambdaForm classes. Handle class_loader(THREAD, SystemDictionary::java_system_loader()); Handle protection_domain; Klass* klass = SystemDictionary::resolve_or_fail(class_name_symbol, class_loader, protection_domain, true, CHECK); @@ -836,6 +853,8 @@ void ClassListParser::parse_constant_pool_tag() { case JVM_CONSTANT_InterfaceMethodref: preresolve_fmi = true; break; + case JVM_CONSTANT_InvokeDynamic: + preresolve_indy = true; break; default: constant_pool_resolution_warning("Unsupported constant pool index %d: %s (type=%d)", @@ -845,9 +864,12 @@ void ClassListParser::parse_constant_pool_tag() { } if (preresolve_class) { - ClassPrelinker::preresolve_class_cp_entries(THREAD, ik, &preresolve_list); + AOTConstantPoolResolver::preresolve_class_cp_entries(THREAD, ik, &preresolve_list); } if (preresolve_fmi) { - ClassPrelinker::preresolve_field_and_method_cp_entries(THREAD, ik, &preresolve_list); + AOTConstantPoolResolver::preresolve_field_and_method_cp_entries(THREAD, ik, &preresolve_list); + } + if (preresolve_indy) { + AOTConstantPoolResolver::preresolve_indy_cp_entries(THREAD, ik, &preresolve_list); } } diff --git a/src/hotspot/share/cds/classListWriter.cpp b/src/hotspot/share/cds/classListWriter.cpp index 1b9f589f1c5..78a6857ff73 100644 --- a/src/hotspot/share/cds/classListWriter.cpp +++ b/src/hotspot/share/cds/classListWriter.cpp @@ -128,9 +128,15 @@ void ClassListWriter::write_to_stream(const InstanceKlass* k, outputStream* stre } } - // filter out java/lang/invoke/BoundMethodHandle$Species... - if (cfs != nullptr && cfs->source() != nullptr && strcmp(cfs->source(), "_ClassSpecializer_generateConcreteSpeciesCode") == 0) { - return; + if (cfs != nullptr && cfs->source() != nullptr) { + if (strcmp(cfs->source(), "_ClassSpecializer_generateConcreteSpeciesCode") == 0) { + return; + } + + if (strncmp(cfs->source(), "__", 2) == 0) { + // generated class: __dynamic_proxy__, __JVM_LookupDefineClass__, etc + return; + } } { @@ -256,6 +262,18 @@ void ClassListWriter::write_resolved_constants_for(InstanceKlass* ik) { } if (cp->cache() != nullptr) { + Array* indy_entries = cp->cache()->resolved_indy_entries(); + if (indy_entries != nullptr) { + for (int i = 0; i < indy_entries->length(); i++) { + ResolvedIndyEntry* rie = indy_entries->adr_at(i); + int cp_index = rie->constant_pool_index(); + if (rie->is_resolved()) { + list.at_put(cp_index, true); + print = true; + } + } + } + Array* field_entries = cp->cache()->resolved_field_entries(); if (field_entries != nullptr) { for (int i = 0; i < field_entries->length(); i++) { @@ -274,7 +292,8 @@ void ClassListWriter::write_resolved_constants_for(InstanceKlass* ik) { ResolvedMethodEntry* rme = method_entries->adr_at(i); if (rme->is_resolved(Bytecodes::_invokevirtual) || rme->is_resolved(Bytecodes::_invokespecial) || - rme->is_resolved(Bytecodes::_invokeinterface)) { + rme->is_resolved(Bytecodes::_invokeinterface) || + rme->is_resolved(Bytecodes::_invokehandle)) { list.at_put(rme->constant_pool_index(), true); print = true; } @@ -291,7 +310,8 @@ void ClassListWriter::write_resolved_constants_for(InstanceKlass* ik) { assert(cp_tag.value() == JVM_CONSTANT_Class || cp_tag.value() == JVM_CONSTANT_Fieldref || cp_tag.value() == JVM_CONSTANT_Methodref|| - cp_tag.value() == JVM_CONSTANT_InterfaceMethodref, "sanity"); + cp_tag.value() == JVM_CONSTANT_InterfaceMethodref || + cp_tag.value() == JVM_CONSTANT_InvokeDynamic, "sanity"); stream->print(" %d", i); } } diff --git a/src/hotspot/share/cds/classPrelinker.cpp b/src/hotspot/share/cds/classPrelinker.cpp deleted file mode 100644 index 6b866bac995..00000000000 --- a/src/hotspot/share/cds/classPrelinker.cpp +++ /dev/null @@ -1,345 +0,0 @@ -/* - * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - * - */ - -#include "precompiled.hpp" -#include "cds/archiveBuilder.hpp" -#include "cds/cdsConfig.hpp" -#include "cds/classPrelinker.hpp" -#include "cds/regeneratedClasses.hpp" -#include "classfile/systemDictionary.hpp" -#include "classfile/systemDictionaryShared.hpp" -#include "classfile/vmClasses.hpp" -#include "interpreter/bytecodeStream.hpp" -#include "interpreter/interpreterRuntime.hpp" -#include "memory/resourceArea.hpp" -#include "oops/constantPool.inline.hpp" -#include "oops/instanceKlass.hpp" -#include "oops/klass.inline.hpp" -#include "runtime/handles.inline.hpp" - -ClassPrelinker::ClassesTable* ClassPrelinker::_processed_classes = nullptr; -ClassPrelinker::ClassesTable* ClassPrelinker::_vm_classes = nullptr; - -bool ClassPrelinker::is_vm_class(InstanceKlass* ik) { - return (_vm_classes->get(ik) != nullptr); -} - -void ClassPrelinker::add_one_vm_class(InstanceKlass* ik) { - bool created; - _vm_classes->put_if_absent(ik, &created); - if (created) { - InstanceKlass* super = ik->java_super(); - if (super != nullptr) { - add_one_vm_class(super); - } - Array* ifs = ik->local_interfaces(); - for (int i = 0; i < ifs->length(); i++) { - add_one_vm_class(ifs->at(i)); - } - } -} - -void ClassPrelinker::initialize() { - assert(_vm_classes == nullptr, "must be"); - _vm_classes = new (mtClass)ClassesTable(); - _processed_classes = new (mtClass)ClassesTable(); - for (auto id : EnumRange{}) { - add_one_vm_class(vmClasses::klass_at(id)); - } -} - -void ClassPrelinker::dispose() { - assert(_vm_classes != nullptr, "must be"); - delete _vm_classes; - delete _processed_classes; - _vm_classes = nullptr; - _processed_classes = nullptr; -} - -// Returns true if we CAN PROVE that cp_index will always resolve to -// the same information at both dump time and run time. This is a -// necessary (but not sufficient) condition for pre-resolving cp_index -// during CDS archive assembly. -bool ClassPrelinker::is_resolution_deterministic(ConstantPool* cp, int cp_index) { - assert(!is_in_archivebuilder_buffer(cp), "sanity"); - - if (cp->tag_at(cp_index).is_klass()) { - // We require cp_index to be already resolved. This is fine for now, are we - // currently archive only CP entries that are already resolved. - Klass* resolved_klass = cp->resolved_klass_at(cp_index); - return resolved_klass != nullptr && is_class_resolution_deterministic(cp->pool_holder(), resolved_klass); - } else if (cp->tag_at(cp_index).is_field() || - cp->tag_at(cp_index).is_method() || - cp->tag_at(cp_index).is_interface_method()) { - int klass_cp_index = cp->uncached_klass_ref_index_at(cp_index); - if (!cp->tag_at(klass_cp_index).is_klass()) { - // Not yet resolved - return false; - } - Klass* k = cp->resolved_klass_at(klass_cp_index); - if (!is_class_resolution_deterministic(cp->pool_holder(), k)) { - return false; - } - - if (!k->is_instance_klass()) { - // TODO: support non instance klasses as well. - return false; - } - - // Here, We don't check if this entry can actually be resolved to a valid Field/Method. - // This method should be called by the ConstantPool to check Fields/Methods that - // have already been successfully resolved. - return true; - } else { - return false; - } -} - -bool ClassPrelinker::is_class_resolution_deterministic(InstanceKlass* cp_holder, Klass* resolved_class) { - assert(!is_in_archivebuilder_buffer(cp_holder), "sanity"); - assert(!is_in_archivebuilder_buffer(resolved_class), "sanity"); - - if (resolved_class->is_instance_klass()) { - InstanceKlass* ik = InstanceKlass::cast(resolved_class); - - if (!ik->is_shared() && SystemDictionaryShared::is_excluded_class(ik)) { - return false; - } - - if (cp_holder->is_subtype_of(ik)) { - // All super types of ik will be resolved in ik->class_loader() before - // ik is defined in this loader, so it's safe to archive the resolved klass reference. - return true; - } - - if (is_vm_class(ik)) { - if (ik->class_loader() != cp_holder->class_loader()) { - // At runtime, cp_holder() may not be able to resolve to the same - // ik. For example, a different version of ik may be defined in - // cp->pool_holder()'s loader using MethodHandles.Lookup.defineClass(). - return false; - } else { - return true; - } - } - } else if (resolved_class->is_objArray_klass()) { - Klass* elem = ObjArrayKlass::cast(resolved_class)->bottom_klass(); - if (elem->is_instance_klass()) { - return is_class_resolution_deterministic(cp_holder, InstanceKlass::cast(elem)); - } else if (elem->is_typeArray_klass()) { - return true; - } - } else if (resolved_class->is_typeArray_klass()) { - return true; - } - - return false; -} - -void ClassPrelinker::dumptime_resolve_constants(InstanceKlass* ik, TRAPS) { - if (!ik->is_linked()) { - return; - } - bool first_time; - _processed_classes->put_if_absent(ik, &first_time); - if (!first_time) { - // We have already resolved the constants in class, so no need to do it again. - return; - } - - constantPoolHandle cp(THREAD, ik->constants()); - for (int cp_index = 1; cp_index < cp->length(); cp_index++) { // Index 0 is unused - switch (cp->tag_at(cp_index).value()) { - case JVM_CONSTANT_String: - resolve_string(cp, cp_index, CHECK); // may throw OOM when interning strings. - break; - } - } -} - -// This works only for the boot/platform/app loaders -Klass* ClassPrelinker::find_loaded_class(Thread* current, oop class_loader, Symbol* name) { - HandleMark hm(current); - Handle h_loader(current, class_loader); - Klass* k = SystemDictionary::find_instance_or_array_klass(current, name, - h_loader, - Handle()); - if (k != nullptr) { - return k; - } - if (h_loader() == SystemDictionary::java_system_loader()) { - return find_loaded_class(current, SystemDictionary::java_platform_loader(), name); - } else if (h_loader() == SystemDictionary::java_platform_loader()) { - return find_loaded_class(current, nullptr, name); - } else { - assert(h_loader() == nullptr, "This function only works for boot/platform/app loaders %p %p %p", - cast_from_oop
(h_loader()), - cast_from_oop
(SystemDictionary::java_system_loader()), - cast_from_oop
(SystemDictionary::java_platform_loader())); - } - - return nullptr; -} - -Klass* ClassPrelinker::find_loaded_class(Thread* current, ConstantPool* cp, int class_cp_index) { - Symbol* name = cp->klass_name_at(class_cp_index); - return find_loaded_class(current, cp->pool_holder()->class_loader(), name); -} - -#if INCLUDE_CDS_JAVA_HEAP -void ClassPrelinker::resolve_string(constantPoolHandle cp, int cp_index, TRAPS) { - if (CDSConfig::is_dumping_heap()) { - int cache_index = cp->cp_to_object_index(cp_index); - ConstantPool::string_at_impl(cp, cp_index, cache_index, CHECK); - } -} -#endif - -void ClassPrelinker::preresolve_class_cp_entries(JavaThread* current, InstanceKlass* ik, GrowableArray* preresolve_list) { - if (!SystemDictionaryShared::is_builtin_loader(ik->class_loader_data())) { - return; - } - - JavaThread* THREAD = current; - constantPoolHandle cp(THREAD, ik->constants()); - for (int cp_index = 1; cp_index < cp->length(); cp_index++) { - if (cp->tag_at(cp_index).value() == JVM_CONSTANT_UnresolvedClass) { - if (preresolve_list != nullptr && preresolve_list->at(cp_index) == false) { - // This class was not resolved during trial run. Don't attempt to resolve it. Otherwise - // the compiler may generate less efficient code. - continue; - } - if (find_loaded_class(current, cp(), cp_index) == nullptr) { - // Do not resolve any class that has not been loaded yet - continue; - } - Klass* resolved_klass = cp->klass_at(cp_index, THREAD); - if (HAS_PENDING_EXCEPTION) { - CLEAR_PENDING_EXCEPTION; // just ignore - } else { - log_trace(cds, resolve)("Resolved class [%3d] %s -> %s", cp_index, ik->external_name(), - resolved_klass->external_name()); - } - } - } -} - -void ClassPrelinker::preresolve_field_and_method_cp_entries(JavaThread* current, InstanceKlass* ik, GrowableArray* preresolve_list) { - JavaThread* THREAD = current; - constantPoolHandle cp(THREAD, ik->constants()); - if (cp->cache() == nullptr) { - return; - } - for (int i = 0; i < ik->methods()->length(); i++) { - Method* m = ik->methods()->at(i); - BytecodeStream bcs(methodHandle(THREAD, m)); - while (!bcs.is_last_bytecode()) { - bcs.next(); - Bytecodes::Code raw_bc = bcs.raw_code(); - switch (raw_bc) { - case Bytecodes::_getfield: - case Bytecodes::_putfield: - maybe_resolve_fmi_ref(ik, m, raw_bc, bcs.get_index_u2(), preresolve_list, THREAD); - if (HAS_PENDING_EXCEPTION) { - CLEAR_PENDING_EXCEPTION; // just ignore - } - break; - case Bytecodes::_invokespecial: - case Bytecodes::_invokevirtual: - case Bytecodes::_invokeinterface: - maybe_resolve_fmi_ref(ik, m, raw_bc, bcs.get_index_u2(), preresolve_list, THREAD); - if (HAS_PENDING_EXCEPTION) { - CLEAR_PENDING_EXCEPTION; // just ignore - } - break; - default: - break; - } - } - } -} - -void ClassPrelinker::maybe_resolve_fmi_ref(InstanceKlass* ik, Method* m, Bytecodes::Code bc, int raw_index, - GrowableArray* preresolve_list, TRAPS) { - methodHandle mh(THREAD, m); - constantPoolHandle cp(THREAD, ik->constants()); - HandleMark hm(THREAD); - int cp_index = cp->to_cp_index(raw_index, bc); - - if (cp->is_resolved(raw_index, bc)) { - return; - } - - if (preresolve_list != nullptr && preresolve_list->at(cp_index) == false) { - // This field wasn't resolved during the trial run. Don't attempt to resolve it. Otherwise - // the compiler may generate less efficient code. - return; - } - - int klass_cp_index = cp->uncached_klass_ref_index_at(cp_index); - if (find_loaded_class(THREAD, cp(), klass_cp_index) == nullptr) { - // Do not resolve any field/methods from a class that has not been loaded yet. - return; - } - - Klass* resolved_klass = cp->klass_ref_at(raw_index, bc, CHECK); - - switch (bc) { - case Bytecodes::_getfield: - case Bytecodes::_putfield: - InterpreterRuntime::resolve_get_put(bc, raw_index, mh, cp, false /*initialize_holder*/, CHECK); - break; - - case Bytecodes::_invokevirtual: - case Bytecodes::_invokespecial: - case Bytecodes::_invokeinterface: - InterpreterRuntime::cds_resolve_invoke(bc, raw_index, cp, CHECK); - break; - - default: - ShouldNotReachHere(); - } - - if (log_is_enabled(Trace, cds, resolve)) { - ResourceMark rm(THREAD); - bool resolved = cp->is_resolved(raw_index, bc); - Symbol* name = cp->name_ref_at(raw_index, bc); - Symbol* signature = cp->signature_ref_at(raw_index, bc); - log_trace(cds, resolve)("%s %s [%3d] %s -> %s.%s:%s", - (resolved ? "Resolved" : "Failed to resolve"), - Bytecodes::name(bc), cp_index, ik->external_name(), - resolved_klass->external_name(), - name->as_C_string(), signature->as_C_string()); - } -} - -#ifdef ASSERT -bool ClassPrelinker::is_in_archivebuilder_buffer(address p) { - if (!Thread::current()->is_VM_thread() || ArchiveBuilder::current() == nullptr) { - return false; - } else { - return ArchiveBuilder::current()->is_in_buffer_space(p); - } -} -#endif diff --git a/src/hotspot/share/cds/dumpAllocStats.cpp b/src/hotspot/share/cds/dumpAllocStats.cpp index 25351f78d84..e88a77de7ad 100644 --- a/src/hotspot/share/cds/dumpAllocStats.cpp +++ b/src/hotspot/share/cds/dumpAllocStats.cpp @@ -23,6 +23,7 @@ */ #include "precompiled.hpp" +#include "cds/aotClassLinker.hpp" #include "cds/dumpAllocStats.hpp" #include "logging/log.hpp" #include "logging/logMessage.hpp" @@ -114,6 +115,12 @@ void DumpAllocStats::print_stats(int ro_all, int rw_all) { _num_method_cp_entries, _num_method_cp_entries_archived, percent_of(_num_method_cp_entries_archived, _num_method_cp_entries), _num_method_cp_entries_reverted); + msg.info("Indy CP entries = %6d, archived = %6d (%5.1f%%), reverted = %6d", + _num_indy_cp_entries, _num_indy_cp_entries_archived, + percent_of(_num_indy_cp_entries_archived, _num_indy_cp_entries), + _num_indy_cp_entries_reverted); + msg.info("Platform loader initiated classes = %5d", AOTClassLinker::num_platform_initiated_classes()); + msg.info("App loader initiated classes = %5d", AOTClassLinker::num_app_initiated_classes()); } #ifdef ASSERT diff --git a/src/hotspot/share/cds/dumpAllocStats.hpp b/src/hotspot/share/cds/dumpAllocStats.hpp index 2ff81c52392..7d651320e6f 100644 --- a/src/hotspot/share/cds/dumpAllocStats.hpp +++ b/src/hotspot/share/cds/dumpAllocStats.hpp @@ -68,6 +68,9 @@ class DumpAllocStats : public StackObj { int _num_field_cp_entries; int _num_field_cp_entries_archived; int _num_field_cp_entries_reverted; + int _num_indy_cp_entries; + int _num_indy_cp_entries_archived; + int _num_indy_cp_entries_reverted; int _num_klass_cp_entries; int _num_klass_cp_entries_archived; int _num_klass_cp_entries_reverted; @@ -84,6 +87,9 @@ class DumpAllocStats : public StackObj { _num_field_cp_entries = 0; _num_field_cp_entries_archived = 0; _num_field_cp_entries_reverted = 0; + _num_indy_cp_entries = 0; + _num_indy_cp_entries_archived = 0; + _num_indy_cp_entries_reverted = 0; _num_klass_cp_entries = 0; _num_klass_cp_entries_archived = 0; _num_klass_cp_entries_reverted = 0; @@ -122,6 +128,12 @@ class DumpAllocStats : public StackObj { _num_field_cp_entries_reverted += reverted ? 1 : 0; } + void record_indy_cp_entry(bool archived, bool reverted) { + _num_indy_cp_entries ++; + _num_indy_cp_entries_archived += archived ? 1 : 0; + _num_indy_cp_entries_reverted += reverted ? 1 : 0; + } + void record_klass_cp_entry(bool archived, bool reverted) { _num_klass_cp_entries ++; _num_klass_cp_entries_archived += archived ? 1 : 0; diff --git a/src/hotspot/share/cds/dumpTimeClassInfo.hpp b/src/hotspot/share/cds/dumpTimeClassInfo.hpp index 5ba79e54c79..c060601f1fb 100644 --- a/src/hotspot/share/cds/dumpTimeClassInfo.hpp +++ b/src/hotspot/share/cds/dumpTimeClassInfo.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -42,7 +42,8 @@ class DumpTimeClassInfo: public CHeapObj { bool _excluded; bool _is_early_klass; bool _has_checked_exclusion; - + bool _is_required_hidden_class; + bool _has_scanned_constant_pool; class DTLoaderConstraint { Symbol* _name; char _loader_type1; @@ -137,6 +138,8 @@ class DumpTimeClassInfo: public CHeapObj { _failed_verification = false; _is_archived_lambda_proxy = false; _has_checked_exclusion = false; + _is_required_hidden_class = false; + _has_scanned_constant_pool = false; _id = -1; _clsfile_size = -1; _clsfile_crc32 = -1; @@ -214,6 +217,11 @@ class DumpTimeClassInfo: public CHeapObj { InstanceKlass* nest_host() const { return _nest_host; } void set_nest_host(InstanceKlass* nest_host) { _nest_host = nest_host; } + bool is_required_hidden_class() const { return _is_required_hidden_class; } + void set_is_required_hidden_class() { _is_required_hidden_class = true; } + bool has_scanned_constant_pool() const { return _has_scanned_constant_pool; } + void set_has_scanned_constant_pool() { _has_scanned_constant_pool = true; } + size_t runtime_info_bytesize() const; }; diff --git a/src/hotspot/share/cds/dynamicArchive.cpp b/src/hotspot/share/cds/dynamicArchive.cpp index 04c60b89580..f102282f682 100644 --- a/src/hotspot/share/cds/dynamicArchive.cpp +++ b/src/hotspot/share/cds/dynamicArchive.cpp @@ -23,12 +23,12 @@ */ #include "precompiled.hpp" +#include "cds/aotClassLinker.hpp" #include "cds/archiveBuilder.hpp" #include "cds/archiveHeapWriter.hpp" #include "cds/archiveUtils.inline.hpp" #include "cds/cds_globals.hpp" #include "cds/cdsConfig.hpp" -#include "cds/classPrelinker.hpp" #include "cds/dynamicArchive.hpp" #include "cds/regeneratedClasses.hpp" #include "classfile/classLoader.hpp" @@ -47,8 +47,8 @@ #include "runtime/arguments.hpp" #include "runtime/os.hpp" #include "runtime/sharedRuntime.hpp" -#include "runtime/vmThread.hpp" #include "runtime/vmOperations.hpp" +#include "runtime/vmThread.hpp" #include "utilities/align.hpp" #include "utilities/bitMap.inline.hpp" @@ -112,7 +112,7 @@ class DynamicArchiveBuilder : public ArchiveBuilder { // Block concurrent class unloading from changing the _dumptime_table MutexLocker ml(DumpTimeTable_lock, Mutex::_no_safepoint_check_flag); - SystemDictionaryShared::check_excluded_classes(); + SystemDictionaryShared::find_all_archivable_classes(); if (SystemDictionaryShared::is_dumptime_table_empty()) { log_warning(cds, dynamic)("There is no class to be included in the dynamic archive."); @@ -135,6 +135,11 @@ class DynamicArchiveBuilder : public ArchiveBuilder { verify_estimate_size(_estimated_metaspaceobj_bytes, "MetaspaceObjs"); + sort_methods(); + + log_info(cds)("Make classes shareable"); + make_klasses_shareable(); + char* serialized_data; { // Write the symbol table and system dictionaries to the RO space. @@ -147,6 +152,7 @@ class DynamicArchiveBuilder : public ArchiveBuilder { ArchiveBuilder::OtherROAllocMark mark; SystemDictionaryShared::write_to_archive(false); DynamicArchive::dump_array_klasses(); + AOTClassLinker::write_to_archive(); serialized_data = ro_region()->top(); WriteClosure wc(ro_region()); @@ -155,11 +161,6 @@ class DynamicArchiveBuilder : public ArchiveBuilder { verify_estimate_size(_estimated_hashtable_bytes, "Hashtables"); - sort_methods(); - - log_info(cds)("Make classes shareable"); - make_klasses_shareable(); - log_info(cds)("Adjust lambda proxy class dictionary"); SystemDictionaryShared::adjust_lambda_proxy_class_dictionary(); @@ -234,7 +235,7 @@ void DynamicArchiveBuilder::release_header() { void DynamicArchiveBuilder::post_dump() { ArchivePtrMarker::reset_map_and_vs(); - ClassPrelinker::dispose(); + AOTClassLinker::dispose(); } void DynamicArchiveBuilder::sort_methods() { @@ -497,6 +498,7 @@ void DynamicArchive::check_for_dynamic_dump() { void DynamicArchive::dump_at_exit(JavaThread* current, const char* archive_name) { ExceptionMark em(current); ResourceMark rm(current); + CDSConfig::DumperThreadMark dumper_thread_mark(current); if (!CDSConfig::is_dumping_dynamic_archive() || archive_name == nullptr) { return; @@ -526,6 +528,7 @@ void DynamicArchive::dump_at_exit(JavaThread* current, const char* archive_name) // This is called by "jcmd VM.cds dynamic_dump" void DynamicArchive::dump_for_jcmd(const char* archive_name, TRAPS) { + CDSConfig::DumperThreadMark dumper_thread_mark(THREAD); assert(CDSConfig::is_using_archive() && RecordDynamicDumpInfo, "already checked in arguments.cpp"); assert(ArchiveClassesAtExit == nullptr, "already checked in arguments.cpp"); assert(CDSConfig::is_dumping_dynamic_archive(), "already checked by check_for_dynamic_dump() during VM startup"); diff --git a/src/hotspot/share/cds/filemap.cpp b/src/hotspot/share/cds/filemap.cpp index 5e88b3c47e4..00d8fba4411 100644 --- a/src/hotspot/share/cds/filemap.cpp +++ b/src/hotspot/share/cds/filemap.cpp @@ -223,7 +223,9 @@ void FileMapHeader::populate(FileMapInfo *info, size_t core_region_alignment, } _max_heap_size = MaxHeapSize; _use_optimized_module_handling = CDSConfig::is_using_optimized_module_handling(); + _has_aot_linked_classes = CDSConfig::is_dumping_aot_linked_classes(); _has_full_module_graph = CDSConfig::is_dumping_full_module_graph(); + _has_archived_invokedynamic = CDSConfig::is_dumping_invokedynamic(); // The following fields are for sanity checks for whether this archive // will function correctly with this JVM and the bootclasspath it's @@ -313,6 +315,8 @@ void FileMapHeader::print(outputStream* st) { st->print_cr("- allow_archiving_with_java_agent:%d", _allow_archiving_with_java_agent); st->print_cr("- use_optimized_module_handling: %d", _use_optimized_module_handling); st->print_cr("- has_full_module_graph %d", _has_full_module_graph); + st->print_cr("- has_aot_linked_classes %d", _has_aot_linked_classes); + st->print_cr("- has_archived_invokedynamic %d", _has_archived_invokedynamic); } void SharedClassPathEntry::init_as_non_existent(const char* path, TRAPS) { @@ -1060,7 +1064,9 @@ bool FileMapInfo::validate_shared_path_table() { } } - validate_non_existent_class_paths(); + if (!validate_non_existent_class_paths()) { + return false; + } _validating_shared_path_table = false; @@ -1076,7 +1082,7 @@ bool FileMapInfo::validate_shared_path_table() { return true; } -void FileMapInfo::validate_non_existent_class_paths() { +bool FileMapInfo::validate_non_existent_class_paths() { // All of the recorded non-existent paths came from the Class-Path: attribute from the JAR // files on the app classpath. If any of these are found to exist during runtime, // it will change how classes are loading for the app loader. For safety, disable @@ -1089,11 +1095,19 @@ void FileMapInfo::validate_non_existent_class_paths() { i++) { SharedClassPathEntry* ent = shared_path(i); if (!ent->check_non_existent()) { - log_warning(cds)("Archived non-system classes are disabled because the " - "file %s exists", ent->name()); - header()->set_has_platform_or_app_classes(false); + if (header()->has_aot_linked_classes()) { + log_error(cds)("CDS archive has aot-linked classes. It cannot be used because the " + "file %s exists", ent->name()); + return false; + } else { + log_warning(cds)("Archived non-system classes are disabled because the " + "file %s exists", ent->name()); + header()->set_has_platform_or_app_classes(false); + } } } + + return true; } // A utility class for reading/validating the GenericCDSFileMapHeader portion of @@ -2074,7 +2088,16 @@ void FileMapInfo::map_or_load_heap_region() { } if (!success) { - CDSConfig::stop_using_full_module_graph(); + if (CDSConfig::is_using_aot_linked_classes()) { + // It's too late to recover -- we have already committed to use the archived metaspace objects, but + // the archived heap objects cannot be loaded, so we don't have the archived FMG to guarantee that + // all AOT-linked classes are visible. + // + // We get here because the heap is too small. The app will fail anyway. So let's quit. + MetaspaceShared::unrecoverable_loading_error("CDS archive has aot-linked classes but the archived " + "heap objects cannot be loaded. Try increasing your heap size."); + } + CDSConfig::stop_using_full_module_graph("archive heap loading failed"); } } @@ -2429,6 +2452,34 @@ bool FileMapInfo::initialize() { return true; } +bool FileMapInfo::validate_aot_class_linking() { + // These checks need to be done after FileMapInfo::initialize(), which gets called before Universe::heap() + // is available. + if (header()->has_aot_linked_classes()) { + CDSConfig::set_has_aot_linked_classes(true); + if (JvmtiExport::should_post_class_file_load_hook()) { + log_error(cds)("CDS archive has aot-linked classes. It cannot be used when JVMTI ClassFileLoadHook is in use."); + return false; + } + if (JvmtiExport::has_early_vmstart_env()) { + log_error(cds)("CDS archive has aot-linked classes. It cannot be used when JVMTI early vm start is in use."); + return false; + } + if (!CDSConfig::is_using_full_module_graph()) { + log_error(cds)("CDS archive has aot-linked classes. It cannot be used when archived full module graph is not used."); + return false; + } + + const char* prop = Arguments::get_property("java.security.manager"); + if (prop != nullptr && strcmp(prop, "disallow") != 0) { + log_error(cds)("CDS archive has aot-linked classes. It cannot be used with -Djava.security.manager=%s.", prop); + return false; + } + } + + return true; +} + // The 2 core spaces are RW->RO FileMapRegion* FileMapInfo::first_core_region() const { return region_at(MetaspaceShared::rw); @@ -2478,6 +2529,11 @@ bool FileMapHeader::validate() { // header data const char* prop = Arguments::get_property("java.system.class.loader"); if (prop != nullptr) { + if (has_aot_linked_classes()) { + log_error(cds)("CDS archive has aot-linked classes. It cannot be used when the " + "java.system.class.loader property is specified."); + return false; + } log_warning(cds)("Archived non-system classes are disabled because the " "java.system.class.loader property is specified (value = \"%s\"). " "To use archived non-system classes, this property must not be set", prop); @@ -2542,9 +2598,15 @@ bool FileMapHeader::validate() { log_info(cds)("optimized module handling: disabled because archive was created without optimized module handling"); } - if (is_static() && !_has_full_module_graph) { + if (is_static()) { // Only the static archive can contain the full module graph. - CDSConfig::stop_using_full_module_graph("archive was created without full module graph"); + if (!_has_full_module_graph) { + CDSConfig::stop_using_full_module_graph("archive was created without full module graph"); + } + + if (_has_archived_invokedynamic) { + CDSConfig::set_has_archived_invokedynamic(); + } } return true; diff --git a/src/hotspot/share/cds/filemap.hpp b/src/hotspot/share/cds/filemap.hpp index 6a15ff03c3a..6319c51f1ce 100644 --- a/src/hotspot/share/cds/filemap.hpp +++ b/src/hotspot/share/cds/filemap.hpp @@ -228,7 +228,9 @@ class FileMapHeader: private CDSFileMapHeaderBase { bool _allow_archiving_with_java_agent; // setting of the AllowArchivingWithJavaAgent option bool _use_optimized_module_handling;// No module-relation VM options were specified, so we can skip // some expensive operations. + bool _has_aot_linked_classes; // Was the CDS archive created with -XX:+AOTClassLinking bool _has_full_module_graph; // Does this CDS archive contain the full archived module graph? + bool _has_archived_invokedynamic; // Does the archive have aot-linked invokedynamic CP entries? HeapRootSegments _heap_root_segments; // Heap root segments info size_t _heap_oopmap_start_pos; // The first bit in the oopmap corresponds to this position in the heap. size_t _heap_ptrmap_start_pos; // The first bit in the ptrmap corresponds to this position in the heap. @@ -273,6 +275,7 @@ class FileMapHeader: private CDSFileMapHeaderBase { char* mapped_base_address() const { return _mapped_base_address; } bool has_platform_or_app_classes() const { return _has_platform_or_app_classes; } bool has_non_jar_in_classpath() const { return _has_non_jar_in_classpath; } + bool has_aot_linked_classes() const { return _has_aot_linked_classes; } bool compressed_oops() const { return _compressed_oops; } bool compressed_class_pointers() const { return _compressed_class_ptrs; } int narrow_klass_pointer_bits() const { return _narrow_klass_pointer_bits; } @@ -492,7 +495,8 @@ class FileMapInfo : public CHeapObj { static void check_nonempty_dir_in_shared_path_table(); bool check_module_paths(); bool validate_shared_path_table(); - void validate_non_existent_class_paths(); + bool validate_non_existent_class_paths(); + bool validate_aot_class_linking(); static void set_shared_path_table(FileMapInfo* info) { _shared_path_table = info->header()->shared_path_table(); } diff --git a/src/hotspot/share/cds/heapShared.cpp b/src/hotspot/share/cds/heapShared.cpp index 22040448770..3a7ba936bb0 100644 --- a/src/hotspot/share/cds/heapShared.cpp +++ b/src/hotspot/share/cds/heapShared.cpp @@ -23,6 +23,7 @@ */ #include "precompiled.hpp" +#include "cds/aotClassInitializer.hpp" #include "cds/archiveBuilder.hpp" #include "cds/archiveHeapLoader.hpp" #include "cds/archiveHeapWriter.hpp" @@ -97,7 +98,7 @@ size_t HeapShared::_total_obj_size; #define ARCHIVE_TEST_FIELD_NAME "archivedObjects" static Array* _archived_ArchiveHeapTestClass = nullptr; static const char* _test_class_name = nullptr; -static const Klass* _test_class = nullptr; +static Klass* _test_class = nullptr; static const ArchivedKlassSubGraphInfoRecord* _test_class_record = nullptr; #endif @@ -119,6 +120,7 @@ static ArchivableStaticFieldInfo archive_subgraph_entry_fields[] = { {"java/lang/ModuleLayer", "EMPTY_LAYER"}, {"java/lang/module/Configuration", "EMPTY_CONFIGURATION"}, {"jdk/internal/math/FDBigInteger", "archivedCaches"}, + #ifndef PRODUCT {nullptr, nullptr}, // Extra slot for -XX:ArchiveHeapTestClass #endif @@ -133,7 +135,8 @@ static ArchivableStaticFieldInfo fmg_archive_subgraph_entry_fields[] = { {nullptr, nullptr}, }; -KlassSubGraphInfo* HeapShared::_default_subgraph_info; +KlassSubGraphInfo* HeapShared::_dump_time_special_subgraph; +ArchivedKlassSubGraphInfoRecord* HeapShared::_run_time_special_subgraph; GrowableArrayCHeap* HeapShared::_pending_roots = nullptr; GrowableArrayCHeap* HeapShared::_root_segments; int HeapShared::_root_segment_max_size_elems; @@ -298,6 +301,7 @@ bool HeapShared::archive_object(oop obj) { if (ArchiveHeapWriter::is_too_large_to_archive(obj->size())) { log_debug(cds, heap)("Cannot archive, object (" PTR_FORMAT ") is too large: " SIZE_FORMAT, p2i(obj), obj->size()); + debug_trace(); return false; } else { count_allocation(obj->size()); @@ -309,8 +313,19 @@ bool HeapShared::archive_object(oop obj) { if (log_is_enabled(Debug, cds, heap)) { ResourceMark rm; - log_debug(cds, heap)("Archived heap object " PTR_FORMAT " : %s", - p2i(obj), obj->klass()->external_name()); + LogTarget(Debug, cds, heap) log; + LogStream out(log); + out.print("Archived heap object " PTR_FORMAT " : %s ", + p2i(obj), obj->klass()->external_name()); + if (java_lang_Class::is_instance(obj)) { + Klass* k = java_lang_Class::as_Klass(obj); + if (k != nullptr) { + out.print("%s", k->external_name()); + } else { + out.print("primitive"); + } + } + out.cr(); } if (java_lang_Module::is_instance(obj) && Modules::check_archived_module_oop(obj)) { @@ -371,6 +386,31 @@ void HeapShared::init_scratch_objects(TRAPS) { _scratch_references_table = new (mtClass)MetaspaceObjToOopHandleTable(); } +// Given java_mirror that represents a (primitive or reference) type T, +// return the "scratch" version that represents the same type T. +// Note that if java_mirror will be returned if it's already a +// scratch mirror. +// +// See java_lang_Class::create_scratch_mirror() for more info. +oop HeapShared::scratch_java_mirror(oop java_mirror) { + assert(java_lang_Class::is_instance(java_mirror), "must be"); + + for (int i = T_BOOLEAN; i < T_VOID+1; i++) { + BasicType bt = (BasicType)i; + if (!is_reference_type(bt)) { + if (_scratch_basic_type_mirrors[i].resolve() == java_mirror) { + return java_mirror; + } + } + } + + if (java_lang_Class::is_primitive(java_mirror)) { + return scratch_java_mirror(java_lang_Class::as_BasicType(java_mirror)); + } else { + return scratch_java_mirror(java_lang_Class::as_Klass(java_mirror)); + } +} + oop HeapShared::scratch_java_mirror(BasicType t) { assert((uint)t < T_VOID+1, "range check"); assert(!is_reference_type(t), "sanity"); @@ -399,13 +439,134 @@ void HeapShared::remove_scratch_objects(Klass* k) { } } +//TODO: we eventually want a more direct test for these kinds of things. +//For example the JVM could record some bit of context from the creation +//of the klass, such as who called the hidden class factory. Using +//string compares on names is fragile and will break as soon as somebody +//changes the names in the JDK code. See discussion in JDK-8342481 for +//related ideas about marking AOT-related classes. +bool HeapShared::is_lambda_form_klass(InstanceKlass* ik) { + return ik->is_hidden() && + (ik->name()->starts_with("java/lang/invoke/LambdaForm$MH+") || + ik->name()->starts_with("java/lang/invoke/LambdaForm$DMH+") || + ik->name()->starts_with("java/lang/invoke/LambdaForm$BMH+") || + ik->name()->starts_with("java/lang/invoke/LambdaForm$VH+")); +} + +bool HeapShared::is_lambda_proxy_klass(InstanceKlass* ik) { + return ik->is_hidden() && (ik->name()->index_of_at(0, "$$Lambda+", 9) > 0); +} + +bool HeapShared::is_string_concat_klass(InstanceKlass* ik) { + return ik->is_hidden() && ik->name()->starts_with("java/lang/String$$StringConcat"); +} + +bool HeapShared::is_archivable_hidden_klass(InstanceKlass* ik) { + return CDSConfig::is_dumping_invokedynamic() && + (is_lambda_form_klass(ik) || is_lambda_proxy_klass(ik) || is_string_concat_klass(ik)); +} + +void HeapShared::copy_aot_initialized_mirror(Klass* orig_k, oop orig_mirror, oop m) { + assert(orig_k->is_instance_klass(), "sanity"); + InstanceKlass* ik = InstanceKlass::cast(orig_k); + InstanceKlass* buffered_ik = ArchiveBuilder::current()->get_buffered_addr(ik); + + assert(ik->is_initialized(), "must be"); + + int nfields = 0; + for (JavaFieldStream fs(ik); !fs.done(); fs.next()) { + if (fs.access_flags().is_static()) { + fieldDescriptor& fd = fs.field_descriptor(); + int offset = fd.offset(); + switch (fd.field_type()) { + case T_OBJECT: + case T_ARRAY: + m->obj_field_put(offset, orig_mirror->obj_field(offset)); + break; + case T_BOOLEAN: + m->bool_field_put(offset, orig_mirror->bool_field(offset)); + break; + case T_BYTE: + m->byte_field_put(offset, orig_mirror->byte_field(offset)); + break; + case T_SHORT: + m->short_field_put(offset, orig_mirror->short_field(offset)); + break; + case T_CHAR: + m->char_field_put(offset, orig_mirror->char_field(offset)); + break; + case T_INT: + m->int_field_put(offset, orig_mirror->int_field(offset)); + break; + case T_LONG: + m->long_field_put(offset, orig_mirror->long_field(offset)); + break; + case T_FLOAT: + m->float_field_put(offset, orig_mirror->float_field(offset)); + break; + case T_DOUBLE: + m->double_field_put(offset, orig_mirror->double_field(offset)); + break; + default: + ShouldNotReachHere(); + } + nfields ++; + } + } + + java_lang_Class::set_class_data(m, java_lang_Class::class_data(orig_mirror)); + + // Class::reflectData use SoftReference, which cannot be archived. Set it + // to null and it will be recreated at runtime. + java_lang_Class::set_reflection_data(m, nullptr); + + if (log_is_enabled(Info, cds, init)) { + ResourceMark rm; + log_debug(cds, init)("copied %3d field(s) in aot-initialized mirror %s%s", nfields, ik->external_name(), + ik->is_hidden() ? " (hidden)" : ""); + } +} + +static void copy_java_mirror_hashcode(oop orig_mirror, oop scratch_m) { + // We need to retain the identity_hash, because it may have been used by some hashtables + // in the shared heap. + if (!orig_mirror->fast_no_hash_check()) { + intptr_t src_hash = orig_mirror->identity_hash(); + if (UseCompactObjectHeaders) { + narrowKlass nk = CompressedKlassPointers::encode(orig_mirror->klass()); + scratch_m->set_mark(markWord::prototype().set_narrow_klass(nk).copy_set_hash(src_hash)); + } else { + scratch_m->set_mark(markWord::prototype().copy_set_hash(src_hash)); + } + assert(scratch_m->mark().is_unlocked(), "sanity"); + + DEBUG_ONLY(intptr_t archived_hash = scratch_m->identity_hash()); + assert(src_hash == archived_hash, "Different hash codes: original " INTPTR_FORMAT ", archived " INTPTR_FORMAT, src_hash, archived_hash); + } +} + +static objArrayOop get_archived_resolved_references(InstanceKlass* src_ik) { + InstanceKlass* buffered_ik = ArchiveBuilder::current()->get_buffered_addr(src_ik); + if (buffered_ik->is_shared_boot_class() || + buffered_ik->is_shared_platform_class() || + buffered_ik->is_shared_app_class()) { + objArrayOop rr = src_ik->constants()->resolved_references_or_null(); + if (rr != nullptr && !ArchiveHeapWriter::is_too_large_to_archive(rr)) { + return HeapShared::scratch_resolved_references(src_ik->constants()); + } + } + return nullptr; +} + void HeapShared::archive_java_mirrors() { for (int i = T_BOOLEAN; i < T_VOID+1; i++) { BasicType bt = (BasicType)i; if (!is_reference_type(bt)) { + oop orig_mirror = Universe::java_mirror(bt); oop m = _scratch_basic_type_mirrors[i].resolve(); assert(m != nullptr, "sanity"); - bool success = archive_reachable_objects_from(1, _default_subgraph_info, m); + copy_java_mirror_hashcode(orig_mirror, m); + bool success = archive_reachable_objects_from(1, _dump_time_special_subgraph, m); assert(success, "sanity"); log_trace(cds, heap, mirror)( @@ -418,12 +579,23 @@ void HeapShared::archive_java_mirrors() { GrowableArray* klasses = ArchiveBuilder::current()->klasses(); assert(klasses != nullptr, "sanity"); + for (int i = 0; i < klasses->length(); i++) { Klass* orig_k = klasses->at(i); + oop orig_mirror = orig_k->java_mirror(); + oop m = scratch_java_mirror(orig_k); + if (m != nullptr) { + copy_java_mirror_hashcode(orig_mirror, m); + } + } + + for (int i = 0; i < klasses->length(); i++) { + Klass* orig_k = klasses->at(i); + oop orig_mirror = orig_k->java_mirror(); oop m = scratch_java_mirror(orig_k); if (m != nullptr) { Klass* buffered_k = ArchiveBuilder::get_buffered_klass(orig_k); - bool success = archive_reachable_objects_from(1, _default_subgraph_info, m); + bool success = archive_reachable_objects_from(1, _dump_time_special_subgraph, m); guarantee(success, "scratch mirrors must point to only archivable objects"); buffered_k->set_archived_java_mirror(append_root(m)); ResourceMark rm; @@ -434,9 +606,9 @@ void HeapShared::archive_java_mirrors() { // archive the resolved_referenes array if (buffered_k->is_instance_klass()) { InstanceKlass* ik = InstanceKlass::cast(buffered_k); - oop rr = ik->constants()->prepare_resolved_references_for_archiving(); - if (rr != nullptr && !ArchiveHeapWriter::is_too_large_to_archive(rr)) { - bool success = HeapShared::archive_reachable_objects_from(1, _default_subgraph_info, rr); + objArrayOop rr = get_archived_resolved_references(InstanceKlass::cast(orig_k)); + if (rr != nullptr) { + bool success = HeapShared::archive_reachable_objects_from(1, _dump_time_special_subgraph, rr); assert(success, "must be"); int root_index = append_root(rr); ik->constants()->cache()->set_archived_references(root_index); @@ -448,7 +620,7 @@ void HeapShared::archive_java_mirrors() { void HeapShared::archive_strings() { oop shared_strings_array = StringTable::init_shared_table(_dumped_interned_strings); - bool success = archive_reachable_objects_from(1, _default_subgraph_info, shared_strings_array); + bool success = archive_reachable_objects_from(1, _dump_time_special_subgraph, shared_strings_array); // We must succeed because: // - _dumped_interned_strings do not contain any large strings. // - StringTable::init_shared_table() doesn't create any large arrays. @@ -457,7 +629,7 @@ void HeapShared::archive_strings() { } int HeapShared::archive_exception_instance(oop exception) { - bool success = archive_reachable_objects_from(1, _default_subgraph_info, exception); + bool success = archive_reachable_objects_from(1, _dump_time_special_subgraph, exception); assert(success, "sanity"); return append_root(exception); } @@ -466,6 +638,8 @@ void HeapShared::mark_native_pointers(oop orig_obj) { if (java_lang_Class::is_instance(orig_obj)) { ArchiveHeapWriter::mark_native_pointer(orig_obj, java_lang_Class::klass_offset()); ArchiveHeapWriter::mark_native_pointer(orig_obj, java_lang_Class::array_klass_offset()); + } else if (java_lang_invoke_ResolvedMethodName::is_instance(orig_obj)) { + ArchiveHeapWriter::mark_native_pointer(orig_obj, java_lang_invoke_ResolvedMethodName::vmtarget_offset()); } } @@ -482,11 +656,121 @@ void HeapShared::set_has_native_pointers(oop src_obj) { info->set_has_native_pointers(); } +void HeapShared::start_finding_required_hidden_classes() { + if (!CDSConfig::is_dumping_invokedynamic()) { + return; + } + NoSafepointVerifier nsv; + + init_seen_objects_table(); + + // We first scan the objects that are known to be archived (from the archive_subgraph + // tables) + find_required_hidden_classes_helper(archive_subgraph_entry_fields); + if (CDSConfig::is_dumping_full_module_graph()) { + find_required_hidden_classes_helper(fmg_archive_subgraph_entry_fields); + } + + // Later, SystemDictionaryShared::find_all_archivable_classes_impl() will start + // scanning the constant pools of all classes that it decides to archive. +} + +void HeapShared::end_finding_required_hidden_classes() { + if (!CDSConfig::is_dumping_invokedynamic()) { + return; + } + NoSafepointVerifier nsv; + + delete_seen_objects_table(); +} + +void HeapShared::find_required_hidden_classes_helper(ArchivableStaticFieldInfo fields[]) { + if (!CDSConfig::is_dumping_heap()) { + return; + } + for (int i = 0; fields[i].valid(); i++) { + ArchivableStaticFieldInfo* f = &fields[i]; + InstanceKlass* k = f->klass; + oop m = k->java_mirror(); + oop o = m->obj_field(f->offset); + if (o != nullptr) { + find_required_hidden_classes_in_object(o); + } + } +} + +class HeapShared::FindRequiredHiddenClassesOopClosure: public BasicOopIterateClosure { + GrowableArray _stack; + template void do_oop_work(T *p) { + // Recurse on a GrowableArray to avoid overflowing the C stack. + oop o = RawAccess<>::oop_load(p); + if (o != nullptr) { + _stack.append(o); + } + } + + public: + + void do_oop(narrowOop *p) { FindRequiredHiddenClassesOopClosure::do_oop_work(p); } + void do_oop( oop *p) { FindRequiredHiddenClassesOopClosure::do_oop_work(p); } + + FindRequiredHiddenClassesOopClosure(oop o) { + _stack.append(o); + } + oop pop() { + if (_stack.length() == 0) { + return nullptr; + } else { + return _stack.pop(); + } + } +}; + +static void mark_required_if_hidden_class(Klass* k) { + if (k != nullptr && k->is_instance_klass()) { + InstanceKlass* ik = InstanceKlass::cast(k); + if (ik->is_hidden()) { + SystemDictionaryShared::mark_required_hidden_class(ik); + } + } +} + + +void HeapShared::find_required_hidden_classes_in_object(oop root) { + ResourceMark rm; + FindRequiredHiddenClassesOopClosure c(root); + oop o; + while ((o = c.pop()) != nullptr) { + if (!has_been_seen_during_subgraph_recording(o)) { + set_has_been_seen_during_subgraph_recording(o); + + // Mark the klass of this object + mark_required_if_hidden_class(o->klass()); + + // For special objects, mark the klass that they contain information about. + // - a Class that refers to an hidden class + // - a ResolvedMethodName that refers to a method declared in a hidden class + if (java_lang_Class::is_instance(o)) { + mark_required_if_hidden_class(java_lang_Class::as_Klass(o)); + } else if (java_lang_invoke_ResolvedMethodName::is_instance(o)) { + Method* m = java_lang_invoke_ResolvedMethodName::vmtarget(o); + if (m != nullptr) { + mark_required_if_hidden_class(m->method_holder()); + } + } + + o->oop_iterate(&c); + } + } +} + void HeapShared::archive_objects(ArchiveHeapInfo *heap_info) { { NoSafepointVerifier nsv; - _default_subgraph_info = init_subgraph_info(vmClasses::Object_klass(), false); + // The special subgraph doesn't belong to any class. We use Object_klass() here just + // for convenience. + _dump_time_special_subgraph = init_subgraph_info(vmClasses::Object_klass(), false); // Cache for recording where the archived objects are copied to create_archived_object_cache(); @@ -501,7 +785,7 @@ void HeapShared::archive_objects(ArchiveHeapInfo *heap_info) { copy_objects(); CDSHeapVerifier::verify(); - check_default_subgraph_classes(); + check_special_subgraph_classes(); } ArchiveHeapWriter::write(_pending_roots, heap_info); @@ -513,7 +797,7 @@ void HeapShared::copy_interned_strings() { auto copier = [&] (oop s, bool value_ignored) { assert(s != nullptr, "sanity"); assert(!ArchiveHeapWriter::is_string_too_large_to_archive(s), "large strings must have been filtered"); - bool success = archive_reachable_objects_from(1, _default_subgraph_info, s); + bool success = archive_reachable_objects_from(1, _dump_time_special_subgraph, s); assert(success, "must be"); // Prevent string deduplication from changing the value field to // something not in the archive. @@ -524,20 +808,35 @@ void HeapShared::copy_interned_strings() { delete_seen_objects_table(); } -void HeapShared::copy_special_objects() { - // Archive special objects that do not belong to any subgraphs +void HeapShared::copy_special_subgraph() { + copy_interned_strings(); + init_seen_objects_table(); - archive_java_mirrors(); - archive_strings(); - Universe::archive_exception_instances(); + { + archive_java_mirrors(); + archive_strings(); + Universe::archive_exception_instances(); + } delete_seen_objects_table(); } +void HeapShared::prepare_resolved_references() { + GrowableArray* klasses = ArchiveBuilder::current()->klasses(); + for (int i = 0; i < klasses->length(); i++) { + Klass* src_k = klasses->at(i); + if (src_k->is_instance_klass()) { + InstanceKlass* buffered_ik = ArchiveBuilder::current()->get_buffered_addr(InstanceKlass::cast(src_k)); + buffered_ik->constants()->prepare_resolved_references_for_archiving(); + } + } +} + void HeapShared::copy_objects() { assert(HeapShared::can_write(), "must be"); - copy_interned_strings(); - copy_special_objects(); + prepare_resolved_references(); + find_all_aot_initialized_classes(); + copy_special_subgraph(); archive_object_subgraphs(archive_subgraph_entry_fields, false /* is_full_module_graph */); @@ -549,6 +848,198 @@ void HeapShared::copy_objects() { } } +// Closure used by HeapShared::scan_for_aot_initialized_classes() to look for all objects +// that are reachable from a given root. +class HeapShared::AOTInitializedClassScanner : public BasicOopIterateClosure { + bool _made_progress; + + template void check(T *p) { + oop obj = HeapAccess<>::oop_load(p); + if (!java_lang_Class::is_instance(obj)) { + // Don't scan the mirrors, as we may see an orig_mirror while scanning + // the object graph, .... TODO more info + _made_progress |= HeapShared::scan_for_aot_initialized_classes(obj); + } + } + +public: + AOTInitializedClassScanner() : _made_progress(false) {} + void do_oop(narrowOop *p) { check(p); } + void do_oop( oop *p) { check(p); } + bool made_progress() { return _made_progress; } +}; + +// If has been initialized during the assembly phase, mark its +// has_aot_initialized_mirror bit. And then do the same for all supertypes of +// . +// +// Note: a super interface of may not have been initialized, if +// has not declared any default methods. +// +// Note: this function doesn not call InstanceKlass::initialize() -- we are inside +// a safepoint. +// +// Returns true if one or more classes have been newly marked. +static bool mark_for_aot_initialization(InstanceKlass* buffered_ik) { + assert(SafepointSynchronize::is_at_safepoint(), "sanity"); + assert(ArchiveBuilder::current()->is_in_buffer_space(buffered_ik), "sanity"); + + if (buffered_ik->has_aot_initialized_mirror()) { // already marked + return false; + } + + bool made_progress = false; + if (buffered_ik->is_initialized()) { + if (log_is_enabled(Info, cds, init)) { + ResourceMark rm; + log_info(cds, init)("Mark class for aot-init: %s", buffered_ik->external_name()); + } + + InstanceKlass* src_ik = ArchiveBuilder::current()->get_source_addr(buffered_ik); + + // If we get here with a "wild" user class, which may have + // uncontrolled code, exit with an error. Obviously + // filtering logic upstream needs to detect APP classes and not mark + // them for aot-init in the first place, but this will be the final + // firewall. + +#ifndef PRODUCT + // ArchiveHeapTestClass is used for a very small number of internal regression + // tests (non-product builds only). It may initialize some unexpected classes. + if (ArchiveHeapTestClass == nullptr) +#endif + { + if (!src_ik->in_javabase_module()) { + // Class/interface types in the boot loader may have been initialized as side effects + // of JVM bootstrap code, so they are fine. But we need to check all other classes. + if (buffered_ik->is_interface()) { + // This probably means a bug in AOTConstantPoolResolver.::is_indy_resolution_deterministic() + guarantee(!buffered_ik->interface_needs_clinit_execution_as_super(), + "should not have initialized an interface whose might have unpredictable side effects"); + } else { + // "normal" classes + guarantee(HeapShared::is_archivable_hidden_klass(buffered_ik), + "should not have initialized any non-interface, non-hidden classes outside of java.base"); + } + } + } + + buffered_ik->set_has_aot_initialized_mirror(); + if (AOTClassInitializer::is_runtime_setup_required(src_ik)) { + buffered_ik->set_is_runtime_setup_required(); + } + made_progress = true; + + InstanceKlass* super = buffered_ik->java_super(); + if (super != nullptr) { + mark_for_aot_initialization(super); + } + + Array* interfaces = buffered_ik->transitive_interfaces(); + for (int i = 0; i < interfaces->length(); i++) { + InstanceKlass* intf = interfaces->at(i); + mark_for_aot_initialization(intf); + if (!intf->is_initialized()) { + assert(!intf->interface_needs_clinit_execution_as_super(/*also_check_supers*/false), "sanity"); + assert(!intf->has_aot_initialized_mirror(), "must not be marked"); + } + } + } + + return made_progress; +} + +void HeapShared::find_all_aot_initialized_classes() { + if (!CDSConfig::is_dumping_aot_linked_classes()) { + return; + } + + init_seen_objects_table(); + find_all_aot_initialized_classes_helper(); + delete_seen_objects_table(); +} + +// Recursively find all class that should be aot-initialized: +// - the class has at least one instance that can be reachable from the special subgraph; or +// - the class is hard-coded in AOTClassInitializer::can_archive_initialized_mirror() +void HeapShared::find_all_aot_initialized_classes_helper() { + GrowableArray* klasses = ArchiveBuilder::current()->klasses(); + assert(klasses != nullptr, "sanity"); + + // First scan all resolved constant pools references. + for (int i = 0; i < klasses->length(); i++) { + Klass* src_k = klasses->at(i); + if (src_k->is_instance_klass()) { + InstanceKlass* src_ik = InstanceKlass::cast(src_k); + InstanceKlass* buffered_ik = ArchiveBuilder::current()->get_buffered_addr(src_ik); + objArrayOop rr = get_archived_resolved_references(src_ik); + if (rr != nullptr) { + objArrayOop scratch_rr = scratch_resolved_references(src_ik->constants()); + for (int i = 0; i < scratch_rr->length(); i++) { + scan_for_aot_initialized_classes(scratch_rr->obj_at(i)); + } + } + + // If a class is hard-coded to be aot-initialize, mark it as such. + if (AOTClassInitializer::can_archive_initialized_mirror(src_ik)) { + mark_for_aot_initialization(buffered_ik); + } + } + } + + // These objects also belong to the special subgraph + scan_for_aot_initialized_classes(Universe::null_ptr_exception_instance()); + scan_for_aot_initialized_classes(Universe::arithmetic_exception_instance()); + scan_for_aot_initialized_classes(Universe::internal_error_instance()); + scan_for_aot_initialized_classes(Universe::array_index_out_of_bounds_exception_instance()); + scan_for_aot_initialized_classes(Universe::array_store_exception_instance()); + scan_for_aot_initialized_classes(Universe::class_cast_exception_instance()); + + bool made_progress; + do { + // In each pass, we copy the scratch mirrors of the classes that were marked + // as aot-init in the previous pass. We then scan these mirrors, which may + // mark more classes. Keep iterating until no more progress can be made. + made_progress = false; + for (int i = 0; i < klasses->length(); i++) { + Klass* orig_k = klasses->at(i); + if (orig_k->is_instance_klass()) { + InstanceKlass* orig_ik = InstanceKlass::cast(orig_k); + if (ArchiveBuilder::current()->get_buffered_addr(orig_ik)->has_aot_initialized_mirror()) { + oop orig_mirror = orig_ik->java_mirror(); + oop scratch_mirror = scratch_java_mirror(orig_k); + if (!has_been_seen_during_subgraph_recording(scratch_mirror)) { + // Scan scratch_mirror instead of orig_mirror (which has fields like ClassLoader that + // are not archived). + copy_aot_initialized_mirror(orig_k, orig_mirror, scratch_mirror); + made_progress |= scan_for_aot_initialized_classes(scratch_mirror); + } + } + } + } + } while (made_progress); +} + +bool HeapShared::scan_for_aot_initialized_classes(oop obj) { + if (obj == nullptr || has_been_seen_during_subgraph_recording(obj)) { + return false; + } + set_has_been_seen_during_subgraph_recording(obj); + + bool made_progress = false; + Klass* k = obj->klass(); + if (k->is_instance_klass()) { + InstanceKlass* orig_ik = InstanceKlass::cast(k); + InstanceKlass* buffered_ik = ArchiveBuilder::current()->get_buffered_addr(orig_ik); + made_progress = mark_for_aot_initialization(buffered_ik); + } + + AOTInitializedClassScanner scanner; + obj->oop_iterate(&scanner); + made_progress |= scanner.made_progress(); + return made_progress; +} + // // Subgraph archiving support // @@ -607,8 +1098,14 @@ void KlassSubGraphInfo::add_subgraph_object_klass(Klass* orig_k) { } if (buffered_k->is_instance_klass()) { - assert(InstanceKlass::cast(buffered_k)->is_shared_boot_class(), - "must be boot class"); + if (CDSConfig::is_dumping_invokedynamic()) { + assert(InstanceKlass::cast(buffered_k)->is_shared_boot_class() || + HeapShared::is_lambda_proxy_klass(InstanceKlass::cast(buffered_k)), + "we can archive only instances of boot classes or lambda proxy classes"); + } else { + assert(InstanceKlass::cast(buffered_k)->is_shared_boot_class(), + "must be boot class"); + } // vmClasses::xxx_klass() are not updated, need to check // the original Klass* if (orig_k == vmClasses::String_klass() || @@ -617,6 +1114,10 @@ void KlassSubGraphInfo::add_subgraph_object_klass(Klass* orig_k) { // to the sub-graph object class list. return; } + if (buffered_k->has_aot_initialized_mirror()) { + // No need to add to the runtime-init list. + return; + } check_allowed_klass(InstanceKlass::cast(orig_k)); } else if (buffered_k->is_objArray_klass()) { Klass* abk = ObjArrayKlass::cast(buffered_k)->bottom_klass(); @@ -653,19 +1154,30 @@ void KlassSubGraphInfo::check_allowed_klass(InstanceKlass* ik) { return; } + const char* lambda_msg = ""; + if (CDSConfig::is_dumping_invokedynamic()) { + lambda_msg = ", or a lambda proxy class"; + if (HeapShared::is_lambda_proxy_klass(ik) && + (ik->class_loader() == nullptr || + ik->class_loader() == SystemDictionary::java_platform_loader() || + ik->class_loader() == SystemDictionary::java_system_loader())) { + return; + } + } + #ifndef PRODUCT - if (!ik->module()->is_named() && ik->package() == nullptr) { + if (!ik->module()->is_named() && ik->package() == nullptr && ArchiveHeapTestClass != nullptr) { // This class is loaded by ArchiveHeapTestClass return; } - const char* extra_msg = ", or in an unnamed package of an unnamed module"; + const char* testcls_msg = ", or a test class in an unnamed package of an unnamed module"; #else - const char* extra_msg = ""; + const char* testcls_msg = ""; #endif ResourceMark rm; - log_error(cds, heap)("Class %s not allowed in archive heap. Must be in java.base%s", - ik->external_name(), extra_msg); + log_error(cds, heap)("Class %s not allowed in archive heap. Must be in java.base%s%s", + ik->external_name(), lambda_msg, testcls_msg); MetaspaceShared::unrecoverable_writing_error(); } @@ -727,13 +1239,18 @@ void ArchivedKlassSubGraphInfoRecord::init(KlassSubGraphInfo* info) { int num_subgraphs_klasses = subgraph_object_klasses->length(); _subgraph_object_klasses = ArchiveBuilder::new_ro_array(num_subgraphs_klasses); + bool is_special = (_k == ArchiveBuilder::get_buffered_klass(vmClasses::Object_klass())); for (int i = 0; i < num_subgraphs_klasses; i++) { Klass* subgraph_k = subgraph_object_klasses->at(i); if (log_is_enabled(Info, cds, heap)) { ResourceMark rm; + const char* owner_name = is_special ? "" : _k->external_name(); + if (subgraph_k->is_instance_klass()) { + InstanceKlass* src_ik = InstanceKlass::cast(ArchiveBuilder::current()->get_source_addr(subgraph_k)); + } log_info(cds, heap)( "Archived object klass %s (%2d) => %s", - _k->external_name(), i, subgraph_k->external_name()); + owner_name, i, subgraph_k->external_name()); } _subgraph_object_klasses->at_put(i, subgraph_k); ArchivePtrMarker::mark_pointer(_subgraph_object_klasses->adr_at(i)); @@ -745,16 +1262,14 @@ void ArchivedKlassSubGraphInfoRecord::init(KlassSubGraphInfo* info) { ArchivePtrMarker::mark_pointer(&_subgraph_object_klasses); } -struct CopyKlassSubGraphInfoToArchive : StackObj { +class HeapShared::CopyKlassSubGraphInfoToArchive : StackObj { CompactHashtableWriter* _writer; +public: CopyKlassSubGraphInfoToArchive(CompactHashtableWriter* writer) : _writer(writer) {} bool do_entry(Klass* klass, KlassSubGraphInfo& info) { if (info.subgraph_object_klasses() != nullptr || info.subgraph_entry_fields() != nullptr) { - ArchivedKlassSubGraphInfoRecord* record = - (ArchivedKlassSubGraphInfoRecord*)ArchiveBuilder::ro_region_alloc(sizeof(ArchivedKlassSubGraphInfoRecord)); - record->init(&info); - + ArchivedKlassSubGraphInfoRecord* record = HeapShared::archive_subgraph_info(&info); Klass* buffered_k = ArchiveBuilder::get_buffered_klass(klass); unsigned int hash = SystemDictionaryShared::hash_for_shared_dictionary((address)buffered_k); u4 delta = ArchiveBuilder::current()->any_to_offset_u4(record); @@ -764,6 +1279,16 @@ struct CopyKlassSubGraphInfoToArchive : StackObj { } }; +ArchivedKlassSubGraphInfoRecord* HeapShared::archive_subgraph_info(KlassSubGraphInfo* info) { + ArchivedKlassSubGraphInfoRecord* record = + (ArchivedKlassSubGraphInfoRecord*)ArchiveBuilder::ro_region_alloc(sizeof(ArchivedKlassSubGraphInfoRecord)); + record->init(info); + if (info == _dump_time_special_subgraph) { + _run_time_special_subgraph = record; + } + return record; +} + // Build the records of archived subgraph infos, which include: // - Entry points to all subgraphs from the containing class mirror. The entry // points are static fields in the mirror. For each entry point, the field @@ -820,6 +1345,7 @@ void HeapShared::serialize_tables(SerializeClosure* soc) { #endif _run_time_subgraph_info_table.serialize_header(soc); + soc->do_ptr(&_run_time_special_subgraph); } static void verify_the_heap(Klass* k, const char* which) { @@ -887,6 +1413,65 @@ void HeapShared::resolve_classes_for_subgraph_of(JavaThread* current, Klass* k) } } +void HeapShared::initialize_java_lang_invoke(TRAPS) { + if (CDSConfig::is_loading_invokedynamic() || CDSConfig::is_dumping_invokedynamic()) { + resolve_or_init("java/lang/invoke/Invokers$Holder", true, CHECK); + resolve_or_init("java/lang/invoke/MethodHandle", true, CHECK); + resolve_or_init("java/lang/invoke/MethodHandleNatives", true, CHECK); + resolve_or_init("java/lang/invoke/DirectMethodHandle$Holder", true, CHECK); + resolve_or_init("java/lang/invoke/DelegatingMethodHandle$Holder", true, CHECK); + resolve_or_init("java/lang/invoke/LambdaForm$Holder", true, CHECK); + resolve_or_init("java/lang/invoke/BoundMethodHandle$Species_L", true, CHECK); + } +} + +// Initialize the InstanceKlasses of objects that are reachable from the following roots: +// - interned strings +// - Klass::java_mirror() -- including aot-initialized mirrors such as those of Enum klasses. +// - ConstantPool::resolved_references() +// - Universe::_exception_instance() +// +// For example, if this enum class is initialized at AOT cache assembly time: +// +// enum Fruit { +// APPLE, ORANGE, BANANA; +// static final Set HAVE_SEEDS = new HashSet<>(Arrays.asList(APPLE, ORANGE)); +// } +// +// the aot-initialized mirror of Fruit has a static field that references HashSet, which +// should be initialized before any Java code can access the Fruit class. Note that +// HashSet itself doesn't necessary need to be an aot-initialized class. +void HeapShared::init_classes_for_special_subgraph(Handle class_loader, TRAPS) { + if (!ArchiveHeapLoader::is_in_use()) { + return; + } + + assert( _run_time_special_subgraph != nullptr, "must be"); + Array* klasses = _run_time_special_subgraph->subgraph_object_klasses(); + if (klasses != nullptr) { + for (int pass = 0; pass < 2; pass ++) { + for (int i = 0; i < klasses->length(); i++) { + Klass* k = klasses->at(i); + if (k->class_loader_data() == nullptr) { + // This class is not yet loaded. We will initialize it in a later phase. + // For example, we have loaded only AOTLinkedClassCategory::BOOT1 classes + // but k is part of AOTLinkedClassCategory::BOOT2. + continue; + } + if (k->class_loader() == class_loader()) { + if (pass == 0) { + if (k->is_instance_klass()) { + InstanceKlass::cast(k)->link_class(CHECK); + } + } else { + resolve_or_init(k, /*do_init*/true, CHECK); + } + } + } + } + } +} + void HeapShared::initialize_from_archived_subgraph(JavaThread* current, Klass* k) { JavaThread* THREAD = current; if (!ArchiveHeapLoader::is_in_use()) { @@ -990,6 +1575,19 @@ HeapShared::resolve_or_init_classes_for_subgraph_of(Klass* k, bool do_init, TRAP return record; } +void HeapShared::resolve_or_init(const char* klass_name, bool do_init, TRAPS) { + TempNewSymbol klass_name_sym = SymbolTable::new_symbol(klass_name); + InstanceKlass* k = SystemDictionaryShared::find_builtin_class(klass_name_sym); + if (k == nullptr) { + return; + } + assert(k->is_shared_boot_class(), "sanity"); + resolve_or_init(k, false, CHECK); + if (do_init) { + resolve_or_init(k, true, CHECK); + } +} + void HeapShared::resolve_or_init(Klass* k, bool do_init, TRAPS) { if (!do_init) { if (k->class_loader_data() == nullptr) { @@ -1022,7 +1620,11 @@ void HeapShared::init_archived_fields_for(Klass* k, const ArchivedKlassSubGraphI int field_offset = entry_field_records->at(i); int root_index = entry_field_records->at(i+1); oop v = get_root(root_index, /*clear=*/true); - m->obj_field_put(field_offset, v); + if (k->has_aot_initialized_mirror()) { + assert(v == m->obj_field(field_offset), "must be aot-initialized"); + } else { + m->obj_field_put(field_offset, v); + } log_debug(cds, heap)(" " PTR_FORMAT " init field @ %2d = " PTR_FORMAT, p2i(k), field_offset, p2i(v)); } @@ -1030,8 +1632,9 @@ void HeapShared::init_archived_fields_for(Klass* k, const ArchivedKlassSubGraphI // mirror after this point. if (log_is_enabled(Info, cds, heap)) { ResourceMark rm; - log_info(cds, heap)("initialize_from_archived_subgraph %s " PTR_FORMAT "%s", - k->external_name(), p2i(k), JvmtiExport::is_early_phase() ? " (early)" : ""); + log_info(cds, heap)("initialize_from_archived_subgraph %s " PTR_FORMAT "%s%s", + k->external_name(), p2i(k), JvmtiExport::is_early_phase() ? " (early)" : "", + k->has_aot_initialized_mirror() ? " (aot-inited)" : ""); } } @@ -1137,6 +1740,20 @@ HeapShared::CachedOopInfo HeapShared::make_cached_oop_info(oop obj) { return CachedOopInfo(referrer, points_to_oops_checker.result()); } +void HeapShared::init_box_classes(TRAPS) { + if (ArchiveHeapLoader::is_in_use()) { + vmClasses::Boolean_klass()->initialize(CHECK); + vmClasses::Character_klass()->initialize(CHECK); + vmClasses::Float_klass()->initialize(CHECK); + vmClasses::Double_klass()->initialize(CHECK); + vmClasses::Byte_klass()->initialize(CHECK); + vmClasses::Short_klass()->initialize(CHECK); + vmClasses::Integer_klass()->initialize(CHECK); + vmClasses::Long_klass()->initialize(CHECK); + vmClasses::Void_klass()->initialize(CHECK); + } +} + // (1) If orig_obj has not been archived yet, archive it. // (2) If orig_obj has not been seen yet (since start_recording_subgraph() was called), // trace all objects that are reachable from it, and make sure these objects are archived. @@ -1151,25 +1768,56 @@ bool HeapShared::archive_reachable_objects_from(int level, // If you get an error here, you probably made a change in the JDK library that has added // these objects that are referenced (directly or indirectly) by static fields. ResourceMark rm; - log_error(cds, heap)("Cannot archive object of class %s", orig_obj->klass()->external_name()); - if (log_is_enabled(Trace, cds, heap)) { - WalkOopAndArchiveClosure* walker = WalkOopAndArchiveClosure::current(); - if (walker != nullptr) { - LogStream ls(Log(cds, heap)::trace()); - CDSHeapVerifier::trace_to_root(&ls, walker->referencing_obj()); - } - } + log_error(cds, heap)("Cannot archive object " PTR_FORMAT " of class %s", p2i(orig_obj), orig_obj->klass()->external_name()); + debug_trace(); MetaspaceShared::unrecoverable_writing_error(); } - // java.lang.Class instances cannot be included in an archived object sub-graph. We only support - // them as Klass::_archived_mirror because they need to be specially restored at run time. - // - // If you get an error here, you probably made a change in the JDK library that has added a Class - // object that is referenced (directly or indirectly) by static fields. - if (java_lang_Class::is_instance(orig_obj) && subgraph_info != _default_subgraph_info) { - log_error(cds, heap)("(%d) Unknown java.lang.Class object is in the archived sub-graph", level); - MetaspaceShared::unrecoverable_writing_error(); + if (log_is_enabled(Debug, cds, heap) && java_lang_Class::is_instance(orig_obj)) { + ResourceMark rm; + LogTarget(Debug, cds, heap) log; + LogStream out(log); + out.print("Found java mirror " PTR_FORMAT " ", p2i(orig_obj)); + Klass* k = java_lang_Class::as_Klass(orig_obj); + if (k != nullptr) { + out.print("%s", k->external_name()); + } else { + out.print("primitive"); + } + out.print_cr("; scratch mirror = " PTR_FORMAT, + p2i(scratch_java_mirror(orig_obj))); + } + + if (CDSConfig::is_initing_classes_at_dump_time()) { + if (java_lang_Class::is_instance(orig_obj)) { + orig_obj = scratch_java_mirror(orig_obj); + assert(orig_obj != nullptr, "must be archived"); + } + } else if (java_lang_Class::is_instance(orig_obj) && subgraph_info != _dump_time_special_subgraph) { + // Without CDSConfig::is_initing_classes_at_dump_time(), we only allow archived objects to + // point to the mirrors of (1) j.l.Object, (2) primitive classes, and (3) box classes. These are initialized + // very early by HeapShared::init_box_classes(). + if (orig_obj == vmClasses::Object_klass()->java_mirror() + || java_lang_Class::is_primitive(orig_obj) + || orig_obj == vmClasses::Boolean_klass()->java_mirror() + || orig_obj == vmClasses::Character_klass()->java_mirror() + || orig_obj == vmClasses::Float_klass()->java_mirror() + || orig_obj == vmClasses::Double_klass()->java_mirror() + || orig_obj == vmClasses::Byte_klass()->java_mirror() + || orig_obj == vmClasses::Short_klass()->java_mirror() + || orig_obj == vmClasses::Integer_klass()->java_mirror() + || orig_obj == vmClasses::Long_klass()->java_mirror() + || orig_obj == vmClasses::Void_klass()->java_mirror()) { + orig_obj = scratch_java_mirror(orig_obj); + assert(orig_obj != nullptr, "must be archived"); + } else { + // If you get an error here, you probably made a change in the JDK library that has added a Class + // object that is referenced (directly or indirectly) by an ArchivableStaticFieldInfo + // defined at the top of this file. + log_error(cds, heap)("(%d) Unknown java.lang.Class object is in the archived sub-graph", level); + debug_trace(); + MetaspaceShared::unrecoverable_writing_error(); + } } if (has_been_seen_during_subgraph_recording(orig_obj)) { @@ -1209,9 +1857,15 @@ bool HeapShared::archive_reachable_objects_from(int level, WalkOopAndArchiveClosure walker(level, record_klasses_only, subgraph_info, orig_obj); orig_obj->oop_iterate(&walker); - if (CDSEnumKlass::is_enum_obj(orig_obj)) { - CDSEnumKlass::handle_enum_obj(level + 1, subgraph_info, orig_obj); + if (CDSConfig::is_initing_classes_at_dump_time()) { + // The enum klasses are archived with aot-initialized mirror. + // See AOTClassInitializer::can_archive_initialized_mirror(). + } else { + if (CDSEnumKlass::is_enum_obj(orig_obj)) { + CDSEnumKlass::handle_enum_obj(level + 1, subgraph_info, orig_obj); + } } + return true; } @@ -1329,6 +1983,10 @@ void HeapShared::verify_subgraph_from(oop orig_obj) { void HeapShared::verify_reachable_objects_from(oop obj) { _num_total_verifications ++; + if (java_lang_Class::is_instance(obj)) { + obj = scratch_java_mirror(obj); + assert(obj != nullptr, "must be"); + } if (!has_been_seen_during_subgraph_recording(obj)) { set_has_been_seen_during_subgraph_recording(obj); assert(has_been_archived(obj), "must be"); @@ -1338,35 +1996,35 @@ void HeapShared::verify_reachable_objects_from(oop obj) { } #endif -// The "default subgraph" contains special objects (see heapShared.hpp) that -// can be accessed before we load any Java classes (including java/lang/Class). -// Make sure that these are only instances of the very few specific types -// that we can handle. -void HeapShared::check_default_subgraph_classes() { - GrowableArray* klasses = _default_subgraph_info->subgraph_object_klasses(); - int num = klasses->length(); - for (int i = 0; i < num; i++) { - Klass* subgraph_k = klasses->at(i); - if (log_is_enabled(Info, cds, heap)) { - ResourceMark rm; - log_info(cds, heap)( - "Archived object klass (default subgraph %d) => %s", - i, subgraph_k->external_name()); +void HeapShared::check_special_subgraph_classes() { + if (CDSConfig::is_initing_classes_at_dump_time()) { + // We can have aot-initialized classes (such as Enums) that can reference objects + // of arbitrary types. Currently, we trust the JEP 483 implementation to only + // aot-initialize classes that are "safe". + // + // TODO: we need an automatic tool that checks the safety of aot-initialized + // classes (when we extend the set of aot-initialized classes beyond JEP 483) + return; + } else { + // In this case, the special subgraph should contain a few specific types + GrowableArray* klasses = _dump_time_special_subgraph->subgraph_object_klasses(); + int num = klasses->length(); + for (int i = 0; i < num; i++) { + Klass* subgraph_k = klasses->at(i); + Symbol* name = ArchiveBuilder::current()->get_source_addr(subgraph_k->name()); + if (subgraph_k->is_instance_klass() && + name != vmSymbols::java_lang_Class() && + name != vmSymbols::java_lang_String() && + name != vmSymbols::java_lang_ArithmeticException() && + name != vmSymbols::java_lang_ArrayIndexOutOfBoundsException() && + name != vmSymbols::java_lang_ArrayStoreException() && + name != vmSymbols::java_lang_ClassCastException() && + name != vmSymbols::java_lang_InternalError() && + name != vmSymbols::java_lang_NullPointerException()) { + ResourceMark rm; + fatal("special subgraph cannot have objects of type %s", subgraph_k->external_name()); + } } - - Symbol* name = ArchiveBuilder::current()->get_source_addr(subgraph_k->name()); - guarantee(name == vmSymbols::java_lang_Class() || - name == vmSymbols::java_lang_String() || - name == vmSymbols::java_lang_ArithmeticException() || - name == vmSymbols::java_lang_NullPointerException() || - name == vmSymbols::java_lang_InternalError() || - name == vmSymbols::java_lang_ArrayIndexOutOfBoundsException() || - name == vmSymbols::java_lang_ArrayStoreException() || - name == vmSymbols::java_lang_ClassCastException() || - name == vmSymbols::object_array_signature() || - name == vmSymbols::byte_array_signature() || - name == vmSymbols::char_array_signature(), - "default subgraph can have only these objects"); } } @@ -1572,8 +2230,8 @@ bool HeapShared::is_a_test_class_in_unnamed_module(Klass* ik) { return false; } - // See KlassSubGraphInfo::check_allowed_klass() - only two types of - // classes are allowed: + // See KlassSubGraphInfo::check_allowed_klass() - we only allow test classes + // to be: // (A) java.base classes (which must not be in the unnamed module) // (B) test classes which must be in the unnamed package of the unnamed module. // So if we see a '/' character in the class name, it must be in (A); @@ -1589,6 +2247,25 @@ bool HeapShared::is_a_test_class_in_unnamed_module(Klass* ik) { return false; } + +void HeapShared::initialize_test_class_from_archive(JavaThread* current) { + Klass* k = _test_class; + if (k != nullptr && ArchiveHeapLoader::is_in_use()) { + JavaThread* THREAD = current; + ExceptionMark em(THREAD); + const ArchivedKlassSubGraphInfoRecord* record = + resolve_or_init_classes_for_subgraph_of(k, /*do_init=*/false, THREAD); + + // The _test_class is in the unnamed module, so it can't call CDS.initializeFromArchive() + // from its method. So we set up its "archivedObjects" field first, before + // calling its . This is not strictly clean, but it's a convenient way to write unit + // test cases (see test/hotspot/jtreg/runtime/cds/appcds/cacheObject/ArchiveHeapTestClass.java). + if (record != nullptr) { + init_archived_fields_for(k, record); + } + resolve_or_init_classes_for_subgraph_of(k, /*do_init=*/true, THREAD); + } +} #endif void HeapShared::init_for_dumping(TRAPS) { @@ -1664,6 +2341,15 @@ void HeapShared::add_to_dumped_interned_strings(oop string) { } } +void HeapShared::debug_trace() { + ResourceMark rm; + WalkOopAndArchiveClosure* walker = WalkOopAndArchiveClosure::current(); + if (walker != nullptr) { + LogStream ls(Log(cds, heap)::error()); + CDSHeapVerifier::trace_to_root(&ls, walker->referencing_obj()); + } +} + #ifndef PRODUCT // At dump-time, find the location of all the non-null oop pointers in an archived heap // region. This way we can quickly relocate all the pointers without using diff --git a/src/hotspot/share/cds/heapShared.hpp b/src/hotspot/share/cds/heapShared.hpp index 317b791f5d3..618adeb308f 100644 --- a/src/hotspot/share/cds/heapShared.hpp +++ b/src/hotspot/share/cds/heapShared.hpp @@ -166,10 +166,16 @@ class HeapShared: AllStatic { static bool is_subgraph_root_class(InstanceKlass* ik); // Scratch objects for archiving Klass::java_mirror() - static oop scratch_java_mirror(BasicType t) NOT_CDS_JAVA_HEAP_RETURN_(nullptr); - static oop scratch_java_mirror(Klass* k) NOT_CDS_JAVA_HEAP_RETURN_(nullptr); + static oop scratch_java_mirror(BasicType t) NOT_CDS_JAVA_HEAP_RETURN_(nullptr); + static oop scratch_java_mirror(Klass* k) NOT_CDS_JAVA_HEAP_RETURN_(nullptr); + static oop scratch_java_mirror(oop java_mirror) NOT_CDS_JAVA_HEAP_RETURN_(nullptr); static bool is_archived_boot_layer_available(JavaThread* current) NOT_CDS_JAVA_HEAP_RETURN_(false); + // Look for all hidden classes that are referenced by archived objects. + static void start_finding_required_hidden_classes() NOT_CDS_JAVA_HEAP_RETURN; + static void find_required_hidden_classes_in_object(oop o) NOT_CDS_JAVA_HEAP_RETURN; + static void end_finding_required_hidden_classes() NOT_CDS_JAVA_HEAP_RETURN; + private: #if INCLUDE_CDS_JAVA_HEAP static bool _disable_writing; @@ -184,12 +190,15 @@ class HeapShared: AllStatic { static void count_allocation(size_t size); static void print_stats(); + static void debug_trace(); public: static unsigned oop_hash(oop const& p); static unsigned string_oop_hash(oop const& string) { return java_lang_String::hash_code(string); } + class CopyKlassSubGraphInfoToArchive; + class CachedOopInfo { // Used by CDSHeapVerifier. oop _orig_referrer; @@ -251,7 +260,11 @@ class HeapShared: AllStatic { static DumpTimeKlassSubGraphInfoTable* _dump_time_subgraph_info_table; static RunTimeKlassSubGraphInfoTable _run_time_subgraph_info_table; + class FindRequiredHiddenClassesOopClosure; + static void find_required_hidden_classes_helper(ArchivableStaticFieldInfo fields[]); + static CachedOopInfo make_cached_oop_info(oop obj); + static ArchivedKlassSubGraphInfoRecord* archive_subgraph_info(KlassSubGraphInfo* info); static void archive_object_subgraphs(ArchivableStaticFieldInfo fields[], bool is_full_module_graph); @@ -265,7 +278,7 @@ class HeapShared: AllStatic { InstanceKlass* k, int field_offset) PRODUCT_RETURN; static void verify_reachable_objects_from(oop obj) PRODUCT_RETURN; static void verify_subgraph_from(oop orig_obj) PRODUCT_RETURN; - static void check_default_subgraph_classes(); + static void check_special_subgraph_classes(); static KlassSubGraphInfo* init_subgraph_info(Klass *k, bool is_full_module_graph); static KlassSubGraphInfo* get_subgraph_info(Klass *k); @@ -287,12 +300,14 @@ class HeapShared: AllStatic { static SeenObjectsTable *_seen_objects_table; - // The "default subgraph" is the root of all archived objects that do not belong to any - // of the classes defined in the _archive_subgraph_entry_fields[] arrays: + // The "special subgraph" contains all the archived objects that are reachable + // from the following roots: // - interned strings - // - Klass::java_mirror() + // - Klass::java_mirror() -- including aot-initialized mirrors such as those of Enum klasses. // - ConstantPool::resolved_references() - static KlassSubGraphInfo* _default_subgraph_info; + // - Universe::_exception_instance() + static KlassSubGraphInfo* _dump_time_special_subgraph; // for collecting info during dump time + static ArchivedKlassSubGraphInfoRecord* _run_time_special_subgraph; // for initializing classes during run time. static GrowableArrayCHeap* _pending_roots; static GrowableArrayCHeap* _root_segments; @@ -330,7 +345,7 @@ class HeapShared: AllStatic { static bool has_been_seen_during_subgraph_recording(oop obj); static void set_has_been_seen_during_subgraph_recording(oop obj); static bool archive_object(oop obj); - + static void copy_aot_initialized_mirror(Klass* orig_k, oop orig_mirror, oop m); static void copy_interned_strings(); static void resolve_classes_for_subgraphs(JavaThread* current, ArchivableStaticFieldInfo fields[]); @@ -338,6 +353,7 @@ class HeapShared: AllStatic { static void clear_archived_roots_of(Klass* k); static const ArchivedKlassSubGraphInfoRecord* resolve_or_init_classes_for_subgraph_of(Klass* k, bool do_init, TRAPS); + static void resolve_or_init(const char* klass_name, bool do_init, TRAPS); static void resolve_or_init(Klass* k, bool do_init, TRAPS); static void init_archived_fields_for(Klass* k, const ArchivedKlassSubGraphInfoRecord* record); @@ -352,8 +368,16 @@ class HeapShared: AllStatic { static void fill_failed_loaded_region(); static void mark_native_pointers(oop orig_obj); static bool has_been_archived(oop orig_obj); + static void prepare_resolved_references(); static void archive_java_mirrors(); static void archive_strings(); + static void copy_special_subgraph(); + + class AOTInitializedClassScanner; + static void find_all_aot_initialized_classes(); + static void find_all_aot_initialized_classes_helper(); + static bool scan_for_aot_initialized_classes(oop obj); + public: static void reset_archived_object_states(TRAPS); static void create_archived_object_cache() { @@ -371,7 +395,6 @@ class HeapShared: AllStatic { static int archive_exception_instance(oop exception); static void archive_objects(ArchiveHeapInfo* heap_info); static void copy_objects(); - static void copy_special_objects(); static bool archive_reachable_objects_from(int level, KlassSubGraphInfo* subgraph_info, @@ -420,6 +443,7 @@ class HeapShared: AllStatic { static objArrayOop scratch_resolved_references(ConstantPool* src); static void add_scratch_resolved_references(ConstantPool* src, objArrayOop dest) NOT_CDS_JAVA_HEAP_RETURN; static void init_scratch_objects(TRAPS) NOT_CDS_JAVA_HEAP_RETURN; + static void init_box_classes(TRAPS) NOT_CDS_JAVA_HEAP_RETURN; static bool is_heap_region(int idx) { CDS_JAVA_HEAP_ONLY(return (idx == MetaspaceShared::hp);) NOT_CDS_JAVA_HEAP_RETURN_(false); @@ -436,7 +460,16 @@ class HeapShared: AllStatic { #ifndef PRODUCT static bool is_a_test_class_in_unnamed_module(Klass* ik) NOT_CDS_JAVA_HEAP_RETURN_(false); + static void initialize_test_class_from_archive(TRAPS) NOT_CDS_JAVA_HEAP_RETURN; #endif + + static void initialize_java_lang_invoke(TRAPS) NOT_CDS_JAVA_HEAP_RETURN; + static void init_classes_for_special_subgraph(Handle loader, TRAPS) NOT_CDS_JAVA_HEAP_RETURN; + + static bool is_lambda_form_klass(InstanceKlass* ik) NOT_CDS_JAVA_HEAP_RETURN_(false); + static bool is_lambda_proxy_klass(InstanceKlass* ik) NOT_CDS_JAVA_HEAP_RETURN_(false); + static bool is_string_concat_klass(InstanceKlass* ik) NOT_CDS_JAVA_HEAP_RETURN_(false); + static bool is_archivable_hidden_klass(InstanceKlass* ik) NOT_CDS_JAVA_HEAP_RETURN_(false); }; #if INCLUDE_CDS_JAVA_HEAP diff --git a/src/hotspot/share/cds/lambdaFormInvokers.cpp b/src/hotspot/share/cds/lambdaFormInvokers.cpp index 271c6c76d7a..5455a5e66f2 100644 --- a/src/hotspot/share/cds/lambdaFormInvokers.cpp +++ b/src/hotspot/share/cds/lambdaFormInvokers.cpp @@ -27,8 +27,8 @@ #include "cds/lambdaFormInvokers.hpp" #include "cds/metaspaceShared.hpp" #include "cds/regeneratedClasses.hpp" -#include "classfile/classLoadInfo.hpp" #include "classfile/classFileStream.hpp" +#include "classfile/classLoadInfo.hpp" #include "classfile/javaClasses.inline.hpp" #include "classfile/klassFactory.hpp" #include "classfile/symbolTable.hpp" @@ -96,6 +96,21 @@ void LambdaFormInvokers::regenerate_holder_classes(TRAPS) { return; } + if (CDSConfig::is_dumping_static_archive() && CDSConfig::is_dumping_invokedynamic()) { + // Work around JDK-8310831, as some methods in lambda form holder classes may not get generated. + log_info(cds)("Archived MethodHandles may refer to lambda form holder classes. Cannot regenerate."); + return; + } + + if (CDSConfig::is_dumping_dynamic_archive() && CDSConfig::is_dumping_aot_linked_classes() && + CDSConfig::is_using_aot_linked_classes()) { + // The base archive may have some pre-resolved CP entries that point to the lambda form holder + // classes in the base archive. If we generate new versions of these classes, those CP entries + // will be pointing to invalid classes. + log_info(cds)("Base archive already has aot-linked lambda form holder classes. Cannot regenerate."); + return; + } + ResourceMark rm(THREAD); Symbol* cds_name = vmSymbols::jdk_internal_misc_CDS(); diff --git a/src/hotspot/share/cds/metaspaceShared.cpp b/src/hotspot/share/cds/metaspaceShared.cpp index 3cb1374efb1..b2f5f420365 100644 --- a/src/hotspot/share/cds/metaspaceShared.cpp +++ b/src/hotspot/share/cds/metaspaceShared.cpp @@ -23,16 +23,17 @@ */ #include "precompiled.hpp" +#include "cds/aotClassLinker.hpp" +#include "cds/aotConstantPoolResolver.hpp" +#include "cds/aotLinkedClassBulkLoader.hpp" #include "cds/archiveBuilder.hpp" #include "cds/archiveHeapLoader.hpp" #include "cds/archiveHeapWriter.hpp" #include "cds/cds_globals.hpp" #include "cds/cdsConfig.hpp" #include "cds/cdsProtectionDomain.hpp" -#include "cds/cds_globals.hpp" #include "cds/classListParser.hpp" #include "cds/classListWriter.hpp" -#include "cds/classPrelinker.hpp" #include "cds/cppVtables.hpp" #include "cds/dumpAllocStats.hpp" #include "cds/dynamicArchive.hpp" @@ -98,6 +99,7 @@ bool MetaspaceShared::_remapped_readwrite = false; void* MetaspaceShared::_shared_metaspace_static_top = nullptr; intx MetaspaceShared::_relocation_delta; char* MetaspaceShared::_requested_base_address; +Array* MetaspaceShared::_archived_method_handle_intrinsics = nullptr; bool MetaspaceShared::_use_optimized_module_handling = true; // The CDS archive is divided into the following regions: @@ -308,8 +310,12 @@ void MetaspaceShared::post_initialize(TRAPS) { } } +// Extra java.lang.Strings to be added to the archive static GrowableArrayCHeap* _extra_interned_strings = nullptr; +// Extra Symbols to be added to the archive static GrowableArrayCHeap* _extra_symbols = nullptr; +// Methods managed by SystemDictionary::find_method_handle_intrinsic() to be added to the archive +static GrowableArray* _pending_method_handle_intrinsics = NULL; void MetaspaceShared::read_extra_data(JavaThread* current, const char* filename) { _extra_interned_strings = new GrowableArrayCHeap(10000); @@ -360,6 +366,30 @@ void MetaspaceShared::read_extra_data(JavaThread* current, const char* filename) } } +void MetaspaceShared::make_method_handle_intrinsics_shareable() { + for (int i = 0; i < _pending_method_handle_intrinsics->length(); i++) { + Method* m = ArchiveBuilder::current()->get_buffered_addr(_pending_method_handle_intrinsics->at(i)); + m->remove_unshareable_info(); + // Each method has its own constant pool (which is distinct from m->method_holder()->constants()); + m->constants()->remove_unshareable_info(); + } +} + +void MetaspaceShared::write_method_handle_intrinsics() { + int len = _pending_method_handle_intrinsics->length(); + _archived_method_handle_intrinsics = ArchiveBuilder::new_ro_array(len); + int word_size = _archived_method_handle_intrinsics->size(); + for (int i = 0; i < len; i++) { + Method* m = _pending_method_handle_intrinsics->at(i); + ArchiveBuilder::current()->write_pointer_in_buffer(_archived_method_handle_intrinsics->adr_at(i), m); + word_size += m->size() + m->constMethod()->size() + m->constants()->size(); + if (m->constants()->cache() != nullptr) { + word_size += m->constants()->cache()->size(); + } + } + log_info(cds)("Archived %d method handle intrinsics (%d bytes)", len, word_size * BytesPerWord); +} + // About "serialize" -- // // This is (probably a badly named) way to read/write a data stream of pointers and @@ -431,7 +461,7 @@ void MetaspaceShared::serialize(SerializeClosure* soc) { StringTable::serialize_shared_table_header(soc); HeapShared::serialize_tables(soc); SystemDictionaryShared::serialize_dictionary_headers(soc); - + AOTLinkedClassBulkLoader::serialize(soc, true); InstanceMirrorKlass::serialize_offsets(soc); // Dump/restore well known classes (pointers) @@ -439,6 +469,7 @@ void MetaspaceShared::serialize(SerializeClosure* soc) { soc->do_tag(--tag); CDS_JAVA_HEAP_ONLY(ClassLoaderDataShared::serialize(soc);) + soc->do_ptr((void**)&_archived_method_handle_intrinsics); LambdaFormInvokers::serialize(soc); soc->do_tag(666); @@ -526,6 +557,10 @@ class StaticArchiveBuilder : public ArchiveBuilder { it->push(_extra_symbols->adr_at(i)); } } + + for (int i = 0; i < _pending_method_handle_intrinsics->length(); i++) { + it->push(_pending_method_handle_intrinsics->adr_at(i)); + } } }; @@ -548,6 +583,8 @@ char* VM_PopulateDumpSharedSpace::dump_read_only_tables() { ArchiveBuilder::OtherROAllocMark mark; SystemDictionaryShared::write_to_archive(); + AOTClassLinker::write_to_archive(); + MetaspaceShared::write_method_handle_intrinsics(); // Write lambform lines into archive LambdaFormInvokers::dump_static_archive_invokers(); @@ -566,13 +603,20 @@ void VM_PopulateDumpSharedSpace::doit() { DEBUG_ONLY(SystemDictionaryShared::NoClassLoadingMark nclm); + _pending_method_handle_intrinsics = new (mtClassShared) GrowableArray(256, mtClassShared); + if (CDSConfig::is_dumping_aot_linked_classes()) { + // When dumping AOT-linked classes, some classes may have direct references to a method handle + // intrinsic. The easiest thing is to save all of them into the AOT cache. + SystemDictionary::get_all_method_handle_intrinsics(_pending_method_handle_intrinsics); + } + FileMapInfo::check_nonempty_dir_in_shared_path_table(); NOT_PRODUCT(SystemDictionary::verify();) // Block concurrent class unloading from changing the _dumptime_table MutexLocker ml(DumpTimeTable_lock, Mutex::_no_safepoint_check_flag); - SystemDictionaryShared::check_excluded_classes(); + SystemDictionaryShared::find_all_archivable_classes(); _builder.gather_source_objs(); _builder.reserve_buffer(); @@ -589,6 +633,7 @@ void VM_PopulateDumpSharedSpace::doit() { log_info(cds)("Make classes shareable"); _builder.make_klasses_shareable(); + MetaspaceShared::make_method_handle_intrinsics_shareable(); char* early_serialized_data = dump_early_read_only_tables(); char* serialized_data = dump_read_only_tables(); @@ -656,12 +701,12 @@ bool MetaspaceShared::link_class_for_cds(InstanceKlass* ik, TRAPS) { // cpcache to be created. Class verification is done according // to -Xverify setting. bool res = MetaspaceShared::try_link_class(THREAD, ik); - ClassPrelinker::dumptime_resolve_constants(ik, CHECK_(false)); + AOTConstantPoolResolver::dumptime_resolve_constants(ik, CHECK_(false)); return res; } void MetaspaceShared::link_shared_classes(bool jcmd_request, TRAPS) { - ClassPrelinker::initialize(); + AOTClassLinker::initialize(); if (!jcmd_request) { LambdaFormInvokers::regenerate_holder_classes(CHECK); @@ -709,6 +754,7 @@ void MetaspaceShared::prepare_for_dumping() { // Preload classes from a list, populate the shared spaces and dump to a // file. void MetaspaceShared::preload_and_dump(TRAPS) { + CDSConfig::DumperThreadMark dumper_thread_mark(THREAD); ResourceMark rm(THREAD); StaticArchiveBuilder builder; preload_and_dump_impl(builder, THREAD); @@ -723,6 +769,15 @@ void MetaspaceShared::preload_and_dump(TRAPS) { MetaspaceShared::writing_error("Unexpected exception, use -Xlog:cds,exceptions=trace for detail"); } } + + if (!CDSConfig::old_cds_flags_used()) { + // The JLI launcher only recognizes the "old" -Xshare:dump flag. + // When the new -XX:AOTMode=create flag is used, we can't return + // to the JLI launcher, as the launcher will fail when trying to + // run the main class, which is not what we want. + tty->print_cr("AOTCache creation is complete: %s", AOTCache); + vm_exit(0); + } } #if INCLUDE_CDS_JAVA_HEAP && defined(_LP64) @@ -851,6 +906,29 @@ void MetaspaceShared::preload_and_dump_impl(StaticArchiveBuilder& builder, TRAPS HeapShared::reset_archived_object_states(CHECK); } + if (CDSConfig::is_dumping_invokedynamic()) { + // This assert means that the MethodType and MethodTypeForm tables won't be + // updated concurrently when we are saving their contents into a side table. + assert(CDSConfig::allow_only_single_java_thread(), "Required"); + + JavaValue result(T_VOID); + JavaCalls::call_static(&result, vmClasses::MethodType_klass(), + vmSymbols::createArchivedObjects(), + vmSymbols::void_method_signature(), + CHECK); + + // java.lang.Class::reflectionFactory cannot be archived yet. We set this field + // to null, and it will be initialized again at runtime. + log_debug(cds)("Resetting Class::reflectionFactory"); + TempNewSymbol method_name = SymbolTable::new_symbol("resetArchivedStates"); + Symbol* method_sig = vmSymbols::void_method_signature(); + JavaCalls::call_static(&result, vmClasses::Class_klass(), + method_name, method_sig, CHECK); + + // Perhaps there is a way to avoid hard-coding these names here. + // See discussion in JDK-8342481. + } + // Do this at the very end, when no Java code will be executed. Otherwise // some new strings may be added to the intern table. StringTable::allocate_shared_strings_array(CHECK); @@ -1536,6 +1614,11 @@ MapArchiveResult MetaspaceShared::map_archive(FileMapInfo* mapinfo, char* mapped early_serialize(&rc); } + if (!mapinfo->validate_aot_class_linking()) { + unmap_archive(mapinfo); + return MAP_ARCHIVE_OTHER_FAILURE; + } + mapinfo->set_is_mapped(true); return MAP_ARCHIVE_SUCCESS; } @@ -1596,6 +1679,18 @@ void MetaspaceShared::initialize_shared_spaces() { dynamic_mapinfo->unmap_region(MetaspaceShared::bm); } + LogStreamHandle(Info, cds) lsh; + if (lsh.is_enabled()) { + lsh.print("Using AOT-linked classes: %s (static archive: %s aot-linked classes", + BOOL_TO_STR(CDSConfig::is_using_aot_linked_classes()), + static_mapinfo->header()->has_aot_linked_classes() ? "has" : "no"); + if (dynamic_mapinfo != nullptr) { + lsh.print(", dynamic archive: %s aot-linked classes", + dynamic_mapinfo->header()->has_aot_linked_classes() ? "has" : "no"); + } + lsh.print_cr(")"); + } + // Set up LambdaFormInvokers::_lambdaform_lines for dynamic dump if (CDSConfig::is_dumping_dynamic_archive()) { // Read stored LF format lines stored in static archive diff --git a/src/hotspot/share/cds/metaspaceShared.hpp b/src/hotspot/share/cds/metaspaceShared.hpp index 0b4f6f2ecd4..aaa649d3c0f 100644 --- a/src/hotspot/share/cds/metaspaceShared.hpp +++ b/src/hotspot/share/cds/metaspaceShared.hpp @@ -34,10 +34,12 @@ class ArchiveBuilder; class ArchiveHeapInfo; class FileMapInfo; +class Method; class outputStream; class SerializeClosure; class StaticArchiveBuilder; +template class Array; template class GrowableArray; enum MapArchiveResult { @@ -56,6 +58,7 @@ class MetaspaceShared : AllStatic { static intx _relocation_delta; static char* _requested_base_address; static bool _use_optimized_module_handling; + static Array* _archived_method_handle_intrinsics; public: enum { @@ -111,6 +114,9 @@ class MetaspaceShared : AllStatic { static void unrecoverable_writing_error(const char* message = nullptr); static void writing_error(const char* message = nullptr); + static void make_method_handle_intrinsics_shareable() NOT_CDS_RETURN; + static void write_method_handle_intrinsics() NOT_CDS_RETURN; + static Array* archived_method_handle_intrinsics() { return _archived_method_handle_intrinsics; } static void early_serialize(SerializeClosure* sc) NOT_CDS_RETURN; static void serialize(SerializeClosure* sc) NOT_CDS_RETURN; diff --git a/src/hotspot/share/cds/runTimeClassInfo.cpp b/src/hotspot/share/cds/runTimeClassInfo.cpp index e1329d9d2f9..5ad9c14d13e 100644 --- a/src/hotspot/share/cds/runTimeClassInfo.cpp +++ b/src/hotspot/share/cds/runTimeClassInfo.cpp @@ -62,7 +62,7 @@ void RunTimeClassInfo::init(DumpTimeClassInfo& info) { } } - if (k->is_hidden()) { + if (k->is_hidden() && info.nest_host() != nullptr) { _nest_host_offset = builder->any_to_offset_u4(info.nest_host()); } if (k->has_archived_enum_objs()) { diff --git a/src/hotspot/share/cds/runTimeClassInfo.hpp b/src/hotspot/share/cds/runTimeClassInfo.hpp index d0f02d1c095..e3c1ad4f8fe 100644 --- a/src/hotspot/share/cds/runTimeClassInfo.hpp +++ b/src/hotspot/share/cds/runTimeClassInfo.hpp @@ -177,7 +177,11 @@ class RunTimeClassInfo { InstanceKlass* nest_host() { assert(!ArchiveBuilder::is_active(), "not called when dumping archive"); - return ArchiveUtils::from_offset(_nest_host_offset); + if (_nest_host_offset == 0) { + return nullptr; + } else { + return ArchiveUtils::from_offset(_nest_host_offset); + } } RTLoaderConstraint* loader_constraints() { diff --git a/src/hotspot/share/classfile/classLoader.cpp b/src/hotspot/share/classfile/classLoader.cpp index 9cf88e7cf55..1b34f2ebede 100644 --- a/src/hotspot/share/classfile/classLoader.cpp +++ b/src/hotspot/share/classfile/classLoader.cpp @@ -26,16 +26,17 @@ #include "cds/cds_globals.hpp" #include "cds/cdsConfig.hpp" #include "cds/filemap.hpp" +#include "cds/heapShared.hpp" #include "classfile/classFileStream.hpp" #include "classfile/classLoader.inline.hpp" #include "classfile/classLoaderData.inline.hpp" #include "classfile/classLoaderExt.hpp" #include "classfile/classLoadInfo.hpp" #include "classfile/javaClasses.hpp" +#include "classfile/klassFactory.hpp" #include "classfile/moduleEntry.hpp" #include "classfile/modules.hpp" #include "classfile/packageEntry.hpp" -#include "classfile/klassFactory.hpp" #include "classfile/symbolTable.hpp" #include "classfile/systemDictionary.hpp" #include "classfile/systemDictionaryShared.hpp" @@ -1273,7 +1274,7 @@ void ClassLoader::record_result(JavaThread* current, InstanceKlass* ik, assert(stream != nullptr, "sanity"); if (ik->is_hidden()) { - // We do not archive hidden classes. + record_hidden_class(ik); return; } @@ -1375,6 +1376,44 @@ void ClassLoader::record_result(JavaThread* current, InstanceKlass* ik, assert(file_name != nullptr, "invariant"); ClassLoaderExt::record_result(checked_cast(classpath_index), ik, redefined); } + +void ClassLoader::record_hidden_class(InstanceKlass* ik) { + assert(ik->is_hidden(), "must be"); + + s2 classloader_type; + if (HeapShared::is_lambda_form_klass(ik)) { + classloader_type = ClassLoader::BOOT_LOADER; + } else { + oop loader = ik->class_loader(); + + if (loader == nullptr) { + classloader_type = ClassLoader::BOOT_LOADER; + } else if (SystemDictionary::is_platform_class_loader(loader)) { + classloader_type = ClassLoader::PLATFORM_LOADER; + } else if (SystemDictionary::is_system_class_loader(loader)) { + classloader_type = ClassLoader::APP_LOADER; + } else { + // This class won't be archived, so no need to update its + // classloader_type/classpath_index. + return; + } + } + ik->set_shared_class_loader_type(classloader_type); + + if (HeapShared::is_lambda_proxy_klass(ik)) { + InstanceKlass* nest_host = ik->nest_host_not_null(); + ik->set_shared_classpath_index(nest_host->shared_classpath_index()); + } else if (HeapShared::is_lambda_form_klass(ik)) { + ik->set_shared_classpath_index(0); + } else { + // Generated invoker classes. + if (classloader_type == ClassLoader::APP_LOADER) { + ik->set_shared_classpath_index(ClassLoaderExt::app_class_paths_start_index()); + } else { + ik->set_shared_classpath_index(0); + } + } +} #endif // INCLUDE_CDS // Initialize the class loader's access to methods in libzip. Parse and diff --git a/src/hotspot/share/classfile/classLoader.hpp b/src/hotspot/share/classfile/classLoader.hpp index e44059b7247..d6780054904 100644 --- a/src/hotspot/share/classfile/classLoader.hpp +++ b/src/hotspot/share/classfile/classLoader.hpp @@ -140,6 +140,7 @@ class ModuleClassPathList : public CHeapObj { class ClassLoader: AllStatic { public: enum ClassLoaderType { + OTHER = 0, BOOT_LOADER = 1, /* boot loader */ PLATFORM_LOADER = 2, /* PlatformClassLoader */ APP_LOADER = 3 /* AppClassLoader */ @@ -385,6 +386,7 @@ class ClassLoader: AllStatic { static char* uri_to_path(const char* uri); static void record_result(JavaThread* current, InstanceKlass* ik, const ClassFileStream* stream, bool redefined); + static void record_hidden_class(InstanceKlass* ik); #endif static char* lookup_vm_options(); diff --git a/src/hotspot/share/classfile/javaClasses.cpp b/src/hotspot/share/classfile/javaClasses.cpp index e17de0f2264..12d3ef79cd0 100644 --- a/src/hotspot/share/classfile/javaClasses.cpp +++ b/src/hotspot/share/classfile/javaClasses.cpp @@ -867,6 +867,7 @@ int java_lang_Class::_name_offset; int java_lang_Class::_source_file_offset; int java_lang_Class::_classData_offset; int java_lang_Class::_classRedefinedCount_offset; +int java_lang_Class::_reflectionData_offset; bool java_lang_Class::_offsets_computed = false; GrowableArray* java_lang_Class::_fixup_mirror_list = nullptr; @@ -1303,6 +1304,11 @@ void java_lang_Class::set_class_data(oop java_class, oop class_data) { java_class->obj_field_put(_classData_offset, class_data); } +void java_lang_Class::set_reflection_data(oop java_class, oop reflection_data) { + assert(_reflectionData_offset != 0, "must be set"); + java_class->obj_field_put(_reflectionData_offset, reflection_data); +} + void java_lang_Class::set_class_loader(oop java_class, oop loader) { assert(_class_loader_offset != 0, "offsets should have been initialized"); java_class->obj_field_put(_class_loader_offset, loader); @@ -1493,6 +1499,7 @@ oop java_lang_Class::primitive_mirror(BasicType t) { macro(_module_offset, k, "module", module_signature, false); \ macro(_name_offset, k, "name", string_signature, false); \ macro(_classData_offset, k, "classData", object_signature, false); \ + macro(_reflectionData_offset, k, "reflectionData", java_lang_ref_SoftReference_signature, false); \ macro(_signers_offset, k, "signers", object_array_signature, false); void java_lang_Class::compute_offsets() { @@ -5479,20 +5486,18 @@ void JavaClasses::serialize_offsets(SerializeClosure* soc) { bool JavaClasses::is_supported_for_archiving(oop obj) { Klass* klass = obj->klass(); - if (klass == vmClasses::ClassLoader_klass() || // ClassLoader::loader_data is malloc'ed. - // The next 3 classes are used to implement java.lang.invoke, and are not used directly in - // regular Java code. The implementation of java.lang.invoke uses generated hidden classes - // (e.g., as referenced by ResolvedMethodName::vmholder) that are not yet supported by CDS. - // So for now we cannot not support these classes for archiving. - // - // These objects typically are not referenced by static fields, but rather by resolved - // constant pool entries, so excluding them shouldn't affect the archiving of static fields. - klass == vmClasses::ResolvedMethodName_klass() || - klass == vmClasses::MemberName_klass() || - klass == vmClasses::Context_klass() || - // It's problematic to archive Reference objects. One of the reasons is that - // Reference::discovered may pull in unwanted objects (see JDK-8284336) - klass->is_subclass_of(vmClasses::Reference_klass())) { + if (!CDSConfig::is_dumping_invokedynamic()) { + // These are supported by CDS only when CDSConfig::is_dumping_invokedynamic() is enabled. + if (klass == vmClasses::ResolvedMethodName_klass() || + klass == vmClasses::MemberName_klass() || + klass == vmClasses::Context_klass()) { + return false; + } + } + + if (klass->is_subclass_of(vmClasses::Reference_klass())) { + // It's problematic to archive Reference objects. One of the reasons is that + // Reference::discovered may pull in unwanted objects (see JDK-8284336) return false; } diff --git a/src/hotspot/share/classfile/javaClasses.hpp b/src/hotspot/share/classfile/javaClasses.hpp index a2e6ad7349c..dcb94878aed 100644 --- a/src/hotspot/share/classfile/javaClasses.hpp +++ b/src/hotspot/share/classfile/javaClasses.hpp @@ -254,6 +254,7 @@ class java_lang_Class : AllStatic { static int _source_file_offset; static int _classData_offset; static int _classRedefinedCount_offset; + static int _reflectionData_offset; static bool _offsets_computed; @@ -321,6 +322,7 @@ class java_lang_Class : AllStatic { static objArrayOop signers(oop java_class); static oop class_data(oop java_class); static void set_class_data(oop java_class, oop classData); + static void set_reflection_data(oop java_class, oop reflection_data); static int component_mirror_offset() { return _component_mirror_offset; } diff --git a/src/hotspot/share/classfile/systemDictionary.cpp b/src/hotspot/share/classfile/systemDictionary.cpp index 2d0ebfb7266..b9b341c4dab 100644 --- a/src/hotspot/share/classfile/systemDictionary.cpp +++ b/src/hotspot/share/classfile/systemDictionary.cpp @@ -82,6 +82,7 @@ #include "services/diagnosticCommand.hpp" #include "services/finalizerService.hpp" #include "services/threadService.hpp" +#include "utilities/growableArray.hpp" #include "utilities/macros.hpp" #include "utilities/utf8.hpp" #if INCLUDE_CDS @@ -134,29 +135,29 @@ oop SystemDictionary::java_platform_loader() { } void SystemDictionary::compute_java_loaders(TRAPS) { - if (_java_system_loader.is_empty()) { - oop system_loader = get_system_class_loader_impl(CHECK); - _java_system_loader = OopHandle(Universe::vm_global(), system_loader); + if (_java_platform_loader.is_empty()) { + oop platform_loader = get_platform_class_loader_impl(CHECK); + _java_platform_loader = OopHandle(Universe::vm_global(), platform_loader); } else { // It must have been restored from the archived module graph assert(CDSConfig::is_using_archive(), "must be"); assert(CDSConfig::is_using_full_module_graph(), "must be"); DEBUG_ONLY( - oop system_loader = get_system_class_loader_impl(CHECK); - assert(_java_system_loader.resolve() == system_loader, "must be"); + oop platform_loader = get_platform_class_loader_impl(CHECK); + assert(_java_platform_loader.resolve() == platform_loader, "must be"); ) } - if (_java_platform_loader.is_empty()) { - oop platform_loader = get_platform_class_loader_impl(CHECK); - _java_platform_loader = OopHandle(Universe::vm_global(), platform_loader); + if (_java_system_loader.is_empty()) { + oop system_loader = get_system_class_loader_impl(CHECK); + _java_system_loader = OopHandle(Universe::vm_global(), system_loader); } else { // It must have been restored from the archived module graph assert(CDSConfig::is_using_archive(), "must be"); assert(CDSConfig::is_using_full_module_graph(), "must be"); DEBUG_ONLY( - oop platform_loader = get_platform_class_loader_impl(CHECK); - assert(_java_platform_loader.resolve() == platform_loader, "must be"); + oop system_loader = get_system_class_loader_impl(CHECK); + assert(_java_system_loader.resolve() == system_loader, "must be"); ) } } @@ -1718,6 +1719,23 @@ void SystemDictionary::update_dictionary(JavaThread* current, mu1.notify_all(); } +#if INCLUDE_CDS +// Indicate that loader_data has initiated the loading of class k, which +// has already been defined by a parent loader. +// This API should be used only by AOTLinkedClassBulkLoader +void SystemDictionary::add_to_initiating_loader(JavaThread* current, + InstanceKlass* k, + ClassLoaderData* loader_data) { + assert(CDSConfig::is_using_aot_linked_classes(), "must be"); + assert_locked_or_safepoint(SystemDictionary_lock); + Symbol* name = k->name(); + Dictionary* dictionary = loader_data->dictionary(); + assert(k->is_loaded(), "must be"); + assert(k->class_loader_data() != loader_data, "only for classes defined by a parent loader"); + assert(dictionary->find_class(current, name) == nullptr, "sanity"); + dictionary->add_klass(current, name, k); +} +#endif // Try to find a class name using the loader constraints. The // loader constraints might know about a class that isn't fully loaded @@ -2033,6 +2051,52 @@ Method* SystemDictionary::find_method_handle_intrinsic(vmIntrinsicID iid, return nullptr; } +#if INCLUDE_CDS +void SystemDictionary::get_all_method_handle_intrinsics(GrowableArray* methods) { + assert(SafepointSynchronize::is_at_safepoint(), "must be"); + auto do_method = [&] (InvokeMethodKey& key, Method*& m) { + methods->append(m); + }; + _invoke_method_intrinsic_table->iterate_all(do_method); +} + +void SystemDictionary::restore_archived_method_handle_intrinsics() { + if (UseSharedSpaces) { + EXCEPTION_MARK; + restore_archived_method_handle_intrinsics_impl(THREAD); + if (HAS_PENDING_EXCEPTION) { + // This is probably caused by OOM -- other parts of the CDS archive have direct pointers to + // the archived method handle intrinsics, so we can't really recover from this failure. + vm_exit_during_initialization(err_msg("Failed to restore archived method handle intrinsics. Try to increase heap size.")); + } + } +} + +void SystemDictionary::restore_archived_method_handle_intrinsics_impl(TRAPS) { + Array* list = MetaspaceShared::archived_method_handle_intrinsics(); + for (int i = 0; i < list->length(); i++) { + methodHandle m(THREAD, list->at(i)); + Method::restore_archived_method_handle_intrinsic(m, CHECK); + m->constants()->restore_unshareable_info(CHECK); + if (!Arguments::is_interpreter_only() || m->intrinsic_id() == vmIntrinsics::_linkToNative) { + AdapterHandlerLibrary::create_native_wrapper(m); + if (!m->has_compiled_code()) { + ResourceMark rm(THREAD); + vm_exit_during_initialization(err_msg("Failed to initialize method %s", m->external_name())); + } + } + + // There's no need to grab the InvokeMethodIntrinsicTable_lock, as we are still very early in + // VM start-up -- in init_globals2() -- so we are still running a single Java thread. It's not + // possible to have a contention. + const int iid_as_int = vmIntrinsics::as_int(m->intrinsic_id()); + InvokeMethodKey key(m->signature(), iid_as_int); + bool created = _invoke_method_intrinsic_table->put(key, m()); + assert(created, "unexpected contention"); + } +} +#endif // INCLUDE_CDS + // Helper for unpacking the return value from linkMethod and linkCallSite. static Method* unpack_method_and_appendix(Handle mname, Klass* accessing_klass, diff --git a/src/hotspot/share/classfile/systemDictionary.hpp b/src/hotspot/share/classfile/systemDictionary.hpp index 04980291716..9f5f34ee773 100644 --- a/src/hotspot/share/classfile/systemDictionary.hpp +++ b/src/hotspot/share/classfile/systemDictionary.hpp @@ -75,7 +75,10 @@ class GCTimer; class EventClassLoad; class Symbol; +template class GrowableArray; + class SystemDictionary : AllStatic { + friend class AOTLinkedClassBulkLoader; friend class BootstrapInfo; friend class vmClasses; friend class VMStructs; @@ -239,6 +242,9 @@ class SystemDictionary : AllStatic { Symbol* signature, TRAPS); + static void get_all_method_handle_intrinsics(GrowableArray* methods) NOT_CDS_RETURN; + static void restore_archived_method_handle_intrinsics() NOT_CDS_RETURN; + // compute java_mirror (java.lang.Class instance) for a type ("I", "[[B", "LFoo;", etc.) // Either the accessing_klass or the CL/PD can be non-null, but not both. static Handle find_java_mirror_for_type(Symbol* signature, @@ -293,6 +299,9 @@ class SystemDictionary : AllStatic { const char* message); static const char* find_nest_host_error(const constantPoolHandle& pool, int which); + static void add_to_initiating_loader(JavaThread* current, InstanceKlass* k, + ClassLoaderData* loader_data) NOT_CDS_RETURN; + static OopHandle _java_system_loader; static OopHandle _java_platform_loader; @@ -331,6 +340,7 @@ class SystemDictionary : AllStatic { Handle protection_domain, TRAPS); // Second part of load_shared_class static void load_shared_class_misc(InstanceKlass* ik, ClassLoaderData* loader_data) NOT_CDS_RETURN; + static void restore_archived_method_handle_intrinsics_impl(TRAPS) NOT_CDS_RETURN; protected: // Used by SystemDictionaryShared diff --git a/src/hotspot/share/classfile/systemDictionaryShared.cpp b/src/hotspot/share/classfile/systemDictionaryShared.cpp index 08f224d969f..84b7ea0d6b9 100644 --- a/src/hotspot/share/classfile/systemDictionaryShared.cpp +++ b/src/hotspot/share/classfile/systemDictionaryShared.cpp @@ -27,12 +27,13 @@ #include "cds/archiveHeapLoader.hpp" #include "cds/archiveUtils.hpp" #include "cds/cdsConfig.hpp" +#include "cds/cdsProtectionDomain.hpp" #include "cds/classListParser.hpp" #include "cds/classListWriter.hpp" +#include "cds/dumpTimeClassInfo.inline.hpp" #include "cds/dynamicArchive.hpp" #include "cds/filemap.hpp" -#include "cds/cdsProtectionDomain.hpp" -#include "cds/dumpTimeClassInfo.inline.hpp" +#include "cds/heapShared.hpp" #include "cds/metaspaceShared.hpp" #include "cds/runTimeClassInfo.hpp" #include "classfile/classFileStream.hpp" @@ -204,6 +205,15 @@ DumpTimeClassInfo* SystemDictionaryShared::get_info_locked(InstanceKlass* k) { return info; } +void SystemDictionaryShared::mark_required_hidden_class(InstanceKlass* k) { + assert(k->is_hidden(), "sanity"); + DumpTimeClassInfo* info = _dumptime_table->get(k); + ResourceMark rm; + if (info != nullptr) { + info->set_is_required_hidden_class(); + } +} + bool SystemDictionaryShared::check_for_exclusion(InstanceKlass* k, DumpTimeClassInfo* info) { if (MetaspaceShared::is_in_shared_metaspace(k)) { // We have reached a super type that's already in the base archive. Treat it @@ -287,9 +297,13 @@ bool SystemDictionaryShared::check_for_exclusion_impl(InstanceKlass* k) { if (!k->is_hidden() && k->shared_classpath_index() < 0 && is_builtin(k)) { if (k->name()->starts_with("java/lang/invoke/BoundMethodHandle$Species_")) { // This class is dynamically generated by the JDK - ResourceMark rm; - log_info(cds)("Skipping %s because it is dynamically generated", k->name()->as_C_string()); - return true; // exclude without warning + if (CDSConfig::is_dumping_aot_linked_classes()) { + k->set_shared_classpath_index(0); + } else { + ResourceMark rm; + log_info(cds)("Skipping %s because it is dynamically generated", k->name()->as_C_string()); + return true; // exclude without warning + } } else { // These are classes loaded from unsupported locations (such as those loaded by JVMTI native // agent during dump time). @@ -326,9 +340,8 @@ bool SystemDictionaryShared::check_for_exclusion_impl(InstanceKlass* k) { } } - if (k->is_hidden() && !is_registered_lambda_proxy_class(k)) { - ResourceMark rm; - log_debug(cds)("Skipping %s: Hidden class", k->name()->as_C_string()); + if (k->is_hidden() && !should_hidden_class_be_archived(k)) { + log_info(cds)("Skipping %s: Hidden class", k->name()->as_C_string()); return true; } @@ -588,7 +601,11 @@ void SystemDictionaryShared::validate_before_archiving(InstanceKlass* k) { guarantee(!info->is_excluded(), "Should not attempt to archive excluded class %s", name); if (is_builtin(k)) { if (k->is_hidden()) { - assert(is_registered_lambda_proxy_class(k), "unexpected hidden class %s", name); + if (CDSConfig::is_dumping_invokedynamic()) { + assert(should_hidden_class_be_archived(k), "unexpected hidden class %s", name); + } else { + assert(is_registered_lambda_proxy_class(k), "unexpected hidden class %s", name); + } } guarantee(!k->is_shared_unregistered_class(), "Class loader type must be set for BUILTIN class %s", name); @@ -640,7 +657,93 @@ class UnregisteredClassesDuplicationChecker : StackObj { } }; -void SystemDictionaryShared::check_excluded_classes() { +void SystemDictionaryShared::scan_constant_pool(InstanceKlass* k) { + if (CDSConfig::is_dumping_invokedynamic()) { + k->constants()->find_required_hidden_classes(); + } +} + +bool SystemDictionaryShared::should_hidden_class_be_archived(InstanceKlass* k) { + assert(k->is_hidden(), "sanity"); + if (is_registered_lambda_proxy_class(k)) { + return true; + } + + if (CDSConfig::is_dumping_invokedynamic()) { + DumpTimeClassInfo* info = _dumptime_table->get(k); + if (info != nullptr && info->is_required_hidden_class()) { + guarantee(HeapShared::is_archivable_hidden_klass(k), "required hidden class must be archivable"); + return true; + } + } + + return false; +} + +// Returns true if the class should be excluded. This can be called by +// AOTConstantPoolResolver before or after we enter the CDS safepoint. +// When called before the safepoint, we need to link the class so that +// it can be checked by check_for_exclusion(). +bool SystemDictionaryShared::should_be_excluded(Klass* k) { + assert(CDSConfig::is_dumping_archive(), "sanity"); + assert(CDSConfig::current_thread_is_vm_or_dumper(), "sanity"); + + if (k->is_objArray_klass()) { + return should_be_excluded(ObjArrayKlass::cast(k)->bottom_klass()); + } + + if (!k->is_instance_klass()) { + return false; + } else { + InstanceKlass* ik = InstanceKlass::cast(k); + + if (!SafepointSynchronize::is_at_safepoint()) { + if (!ik->is_linked()) { + // check_for_exclusion() below doesn't link unlinked classes. We come + // here only when we are trying to aot-link constant pool entries, so + // we'd better link the class. + JavaThread* THREAD = JavaThread::current(); + ik->link_class(THREAD); + if (HAS_PENDING_EXCEPTION) { + CLEAR_PENDING_EXCEPTION; + return true; // linking failed -- let's exclude it + } + } + + MutexLocker ml(DumpTimeTable_lock, Mutex::_no_safepoint_check_flag); + DumpTimeClassInfo* p = get_info_locked(ik); + if (p->is_excluded()) { + return true; + } + return check_for_exclusion(ik, p); + } else { + // No need to check for is_linked() as all eligible classes should have + // already been linked in MetaspaceShared::link_class_for_cds(). + // Can't take the lock as we are in safepoint. + DumpTimeClassInfo* p = _dumptime_table->get(ik); + if (p->is_excluded()) { + return true; + } + return check_for_exclusion(ik, p); + } + } +} + +void SystemDictionaryShared::find_all_archivable_classes() { + HeapShared::start_finding_required_hidden_classes(); + find_all_archivable_classes_impl(); + HeapShared::end_finding_required_hidden_classes(); +} + +// Iterate over all the classes in _dumptime_table, marking the ones that must be +// excluded from the archive. Those that are not excluded will be archivable. +// +// (a) Non-hidden classes are easy. They are only check by the rules in +// SystemDictionaryShared::check_for_exclusion(). +// (b) For hidden classes, we only archive those that are required (i.e., they are +// referenced by Java objects (such as CallSites) that are reachable from +// ConstantPools). This needs help from HeapShared. +void SystemDictionaryShared::find_all_archivable_classes_impl() { assert(!class_loading_may_happen(), "class loading must be disabled"); assert_lock_strong(DumpTimeTable_lock); @@ -653,10 +756,56 @@ void SystemDictionaryShared::check_excluded_classes() { dup_checker.mark_duplicated_classes(); } - auto check_for_exclusion = [&] (InstanceKlass* k, DumpTimeClassInfo& info) { - SystemDictionaryShared::check_for_exclusion(k, &info); + ResourceMark rm; + + // First, scan all non-hidden classes + auto check_non_hidden = [&] (InstanceKlass* k, DumpTimeClassInfo& info) { + if (!k->is_hidden()) { + SystemDictionaryShared::check_for_exclusion(k, &info); + if (!info.is_excluded() && !info.has_scanned_constant_pool()) { + scan_constant_pool(k); + info.set_has_scanned_constant_pool(); + } + } }; - _dumptime_table->iterate_all_live_classes(check_for_exclusion); + _dumptime_table->iterate_all_live_classes(check_non_hidden); + + // Then, scan all the hidden classes that have been marked as required to + // discover more hidden classes. Stop when we cannot make progress anymore. + bool made_progress; + do { + made_progress = false; + auto check_hidden = [&] (InstanceKlass* k, DumpTimeClassInfo& info) { + if (k->is_hidden() && should_hidden_class_be_archived(k)) { + SystemDictionaryShared::check_for_exclusion(k, &info); + if (info.is_excluded()) { + guarantee(!info.is_required_hidden_class(), "A required hidden class cannot be marked as excluded"); + } else if (!info.has_scanned_constant_pool()) { + scan_constant_pool(k); + info.set_has_scanned_constant_pool(); + // The CP entries in k *MAY* refer to other hidden classes, so scan + // every hidden class again. + made_progress = true; + } + } + }; + _dumptime_table->iterate_all_live_classes(check_hidden); + } while (made_progress); + + // Now, all hidden classes that have not yet been scanned must be marked as excluded + auto exclude_remaining_hidden = [&] (InstanceKlass* k, DumpTimeClassInfo& info) { + if (k->is_hidden()) { + SystemDictionaryShared::check_for_exclusion(k, &info); + if (CDSConfig::is_dumping_invokedynamic()) { + if (should_hidden_class_be_archived(k)) { + guarantee(!info.is_excluded(), "Must be"); + } else { + guarantee(info.is_excluded(), "Must be"); + } + } + } + }; + _dumptime_table->iterate_all_live_classes(exclude_remaining_hidden); _dumptime_table->update_counts(); cleanup_lambda_proxy_class_dictionary(); @@ -766,6 +915,11 @@ void SystemDictionaryShared::add_lambda_proxy_class(InstanceKlass* caller_ik, Method* member_method, Symbol* instantiated_method_type, TRAPS) { + if (CDSConfig::is_dumping_invokedynamic()) { + // The lambda proxy classes will be stored as part of aot-resolved constant pool entries. + // There's no need to remember them in a separate table. + return; + } assert(caller_ik->class_loader() == lambda_ik->class_loader(), "mismatched class loader"); assert(caller_ik->class_loader_data() == lambda_ik->class_loader_data(), "mismatched class loader data"); @@ -1188,7 +1342,7 @@ class CopyLambdaProxyClassInfoToArchive : StackObj { // In static dump, info._proxy_klasses->at(0) is already relocated to point to the archived class // (not the original class). // - // The following check has been moved to SystemDictionaryShared::check_excluded_classes(), which + // The following check has been moved to SystemDictionaryShared::find_all_archivable_classes(), which // happens before the classes are copied. // // if (SystemDictionaryShared::is_excluded_class(info._proxy_klasses->at(0))) { diff --git a/src/hotspot/share/classfile/systemDictionaryShared.hpp b/src/hotspot/share/classfile/systemDictionaryShared.hpp index c79821036e0..5e0c54a6ffc 100644 --- a/src/hotspot/share/classfile/systemDictionaryShared.hpp +++ b/src/hotspot/share/classfile/systemDictionaryShared.hpp @@ -188,6 +188,7 @@ class SystemDictionaryShared: public SystemDictionary { static DumpTimeClassInfo* get_info(InstanceKlass* k); static DumpTimeClassInfo* get_info_locked(InstanceKlass* k); + static void find_all_archivable_classes_impl(); static void write_dictionary(RunTimeSharedDictionary* dictionary, bool is_builtin); static void write_lambda_proxy_class_dictionary(LambdaProxyClassDictionary* dictionary); @@ -199,10 +200,12 @@ class SystemDictionaryShared: public SystemDictionary { static void remove_dumptime_info(InstanceKlass* k) NOT_CDS_RETURN; static bool has_been_redefined(InstanceKlass* k); static InstanceKlass* retrieve_lambda_proxy_class(const RunTimeLambdaProxyClassInfo* info) NOT_CDS_RETURN_(nullptr); - + static void scan_constant_pool(InstanceKlass* k); DEBUG_ONLY(static bool _class_loading_may_happen;) public: + static bool should_hidden_class_be_archived(InstanceKlass* k); + static void mark_required_hidden_class(InstanceKlass* k); static bool is_hidden_lambda_proxy(InstanceKlass* ik); static bool is_early_klass(InstanceKlass* k); // Was k loaded while JvmtiExport::is_early_phase()==true static bool has_archived_enum_objs(InstanceKlass* ik); @@ -288,7 +291,8 @@ class SystemDictionaryShared: public SystemDictionary { } static bool add_unregistered_class(Thread* current, InstanceKlass* k); - static void check_excluded_classes(); + static void find_all_archivable_classes(); + static bool should_be_excluded(Klass* k); static bool check_for_exclusion(InstanceKlass* k, DumpTimeClassInfo* info); static void validate_before_archiving(InstanceKlass* k); static bool is_excluded_class(InstanceKlass* k); diff --git a/src/hotspot/share/classfile/vmClassMacros.hpp b/src/hotspot/share/classfile/vmClassMacros.hpp index 395e718c55d..46d601d17dd 100644 --- a/src/hotspot/share/classfile/vmClassMacros.hpp +++ b/src/hotspot/share/classfile/vmClassMacros.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -175,6 +175,7 @@ do_klass(Short_klass, java_lang_Short ) \ do_klass(Integer_klass, java_lang_Integer ) \ do_klass(Long_klass, java_lang_Long ) \ + do_klass(Void_klass, java_lang_Void ) \ \ /* force inline of iterators */ \ do_klass(Iterator_klass, java_util_Iterator ) \ diff --git a/src/hotspot/share/classfile/vmClasses.cpp b/src/hotspot/share/classfile/vmClasses.cpp index b62d699dfe2..553864ef0b9 100644 --- a/src/hotspot/share/classfile/vmClasses.cpp +++ b/src/hotspot/share/classfile/vmClasses.cpp @@ -23,6 +23,7 @@ */ #include "precompiled.hpp" +#include "cds/aotLinkedClassBulkLoader.hpp" #include "cds/archiveHeapLoader.hpp" #include "cds/cdsConfig.hpp" #include "classfile/classLoader.hpp" @@ -210,6 +211,9 @@ void vmClasses::resolve_all(TRAPS) { #endif InstanceStackChunkKlass::init_offset_of_stack(); + if (CDSConfig::is_using_aot_linked_classes()) { + AOTLinkedClassBulkLoader::load_javabase_classes(THREAD); + } } #if INCLUDE_CDS diff --git a/src/hotspot/share/classfile/vmSymbols.hpp b/src/hotspot/share/classfile/vmSymbols.hpp index 34861b52d54..0728e156f82 100644 --- a/src/hotspot/share/classfile/vmSymbols.hpp +++ b/src/hotspot/share/classfile/vmSymbols.hpp @@ -89,6 +89,7 @@ class SerializeClosure; template(java_lang_Integer_IntegerCache, "java/lang/Integer$IntegerCache") \ template(java_lang_Long, "java/lang/Long") \ template(java_lang_Long_LongCache, "java/lang/Long$LongCache") \ + template(java_lang_Void, "java/lang/Void") \ \ template(jdk_internal_vm_vector_VectorSupport, "jdk/internal/vm/vector/VectorSupport") \ template(jdk_internal_vm_vector_VectorPayload, "jdk/internal/vm/vector/VectorSupport$VectorPayload") \ @@ -309,6 +310,8 @@ class SerializeClosure; template(jdk_internal_vm_annotation_JvmtiHideEvents_signature, "Ljdk/internal/vm/annotation/JvmtiHideEvents;") \ template(jdk_internal_vm_annotation_JvmtiMountTransition_signature, "Ljdk/internal/vm/annotation/JvmtiMountTransition;") \ \ + template(java_lang_ref_SoftReference_signature, "Ljava/lang/ref/SoftReference;") \ + \ /* Support for JSR 292 & invokedynamic (JDK 1.7 and above) */ \ template(java_lang_invoke_CallSite, "java/lang/invoke/CallSite") \ template(java_lang_invoke_ConstantCallSite, "java/lang/invoke/ConstantCallSite") \ @@ -726,6 +729,7 @@ class SerializeClosure; JFR_TEMPLATES(template) \ \ /* CDS */ \ + template(createArchivedObjects, "createArchivedObjects") \ template(dumpSharedArchive, "dumpSharedArchive") \ template(dumpSharedArchive_signature, "(ZLjava/lang/String;)Ljava/lang/String;") \ template(generateLambdaFormHolderClasses, "generateLambdaFormHolderClasses") \ @@ -739,6 +743,7 @@ class SerializeClosure; template(jdk_internal_misc_CDS, "jdk/internal/misc/CDS") \ template(java_util_concurrent_ConcurrentHashMap, "java/util/concurrent/ConcurrentHashMap") \ template(java_util_ArrayList, "java/util/ArrayList") \ + template(runtimeSetup, "runtimeSetup") \ template(toFileURL_name, "toFileURL") \ template(toFileURL_signature, "(Ljava/lang/String;)Ljava/net/URL;") \ template(url_array_classloader_void_signature, "([Ljava/net/URL;Ljava/lang/ClassLoader;)V") \ diff --git a/src/hotspot/share/interpreter/interpreterRuntime.cpp b/src/hotspot/share/interpreter/interpreterRuntime.cpp index 1d8268dbda6..cb85513eed0 100644 --- a/src/hotspot/share/interpreter/interpreterRuntime.cpp +++ b/src/hotspot/share/interpreter/interpreterRuntime.cpp @@ -949,6 +949,15 @@ void InterpreterRuntime::resolve_invokehandle(JavaThread* current) { pool->cache()->set_method_handle(method_index, info); } +void InterpreterRuntime::cds_resolve_invokehandle(int raw_index, + constantPoolHandle& pool, TRAPS) { + const Bytecodes::Code bytecode = Bytecodes::_invokehandle; + CallInfo info; + LinkResolver::resolve_invoke(info, Handle(), pool, raw_index, bytecode, CHECK); + + pool->cache()->set_method_handle(raw_index, info); +} + // First time execution: Resolve symbols, create a permanent CallSite object. void InterpreterRuntime::resolve_invokedynamic(JavaThread* current) { LastFrameAccessor last_frame(current); @@ -968,6 +977,14 @@ void InterpreterRuntime::resolve_invokedynamic(JavaThread* current) { pool->cache()->set_dynamic_call(info, index); } +void InterpreterRuntime::cds_resolve_invokedynamic(int raw_index, + constantPoolHandle& pool, TRAPS) { + const Bytecodes::Code bytecode = Bytecodes::_invokedynamic; + CallInfo info; + LinkResolver::resolve_invoke(info, Handle(), pool, raw_index, bytecode, CHECK); + pool->cache()->set_dynamic_call(info, raw_index); +} + // This function is the interface to the assembly code. It returns the resolved // cpCache entry. This doesn't safepoint, but the helper routines safepoint. // This function will check for redefinition! diff --git a/src/hotspot/share/interpreter/interpreterRuntime.hpp b/src/hotspot/share/interpreter/interpreterRuntime.hpp index 61041694fc6..3635433f434 100644 --- a/src/hotspot/share/interpreter/interpreterRuntime.hpp +++ b/src/hotspot/share/interpreter/interpreterRuntime.hpp @@ -92,12 +92,15 @@ class InterpreterRuntime: AllStatic { static void resolve_from_cache(JavaThread* current, Bytecodes::Code bytecode); - // Used by ClassPrelinker + // Used by AOTConstantPoolResolver static void resolve_get_put(Bytecodes::Code bytecode, int field_index, methodHandle& m, constantPoolHandle& pool, bool initialize_holder, TRAPS); static void cds_resolve_invoke(Bytecodes::Code bytecode, int method_index, constantPoolHandle& pool, TRAPS); - + static void cds_resolve_invokehandle(int raw_index, + constantPoolHandle& pool, TRAPS); + static void cds_resolve_invokedynamic(int raw_index, + constantPoolHandle& pool, TRAPS); private: // Statics & fields static void resolve_get_put(JavaThread* current, Bytecodes::Code bytecode); diff --git a/src/hotspot/share/logging/logTag.hpp b/src/hotspot/share/logging/logTag.hpp index b53a015b0f2..d9563e41ce7 100644 --- a/src/hotspot/share/logging/logTag.hpp +++ b/src/hotspot/share/logging/logTag.hpp @@ -38,6 +38,7 @@ class outputStream; LOG_TAG(age) \ LOG_TAG(alloc) \ LOG_TAG(annotation) \ + LOG_TAG(aot) \ LOG_TAG(arguments) \ LOG_TAG(array) \ LOG_TAG(attach) \ diff --git a/src/hotspot/share/memory/iterator.inline.hpp b/src/hotspot/share/memory/iterator.inline.hpp index 532782b18f1..7ed2b9b3faa 100644 --- a/src/hotspot/share/memory/iterator.inline.hpp +++ b/src/hotspot/share/memory/iterator.inline.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -27,6 +27,7 @@ #include "memory/iterator.hpp" +#include "cds/aotLinkedClassBulkLoader.hpp" #include "classfile/classLoaderData.hpp" #include "code/nmethod.hpp" #include "oops/access.inline.hpp" @@ -51,7 +52,11 @@ inline void ClaimMetadataVisitingOopIterateClosure::do_cld(ClassLoaderData* cld) inline void ClaimMetadataVisitingOopIterateClosure::do_klass(Klass* k) { ClassLoaderData* cld = k->class_loader_data(); - ClaimMetadataVisitingOopIterateClosure::do_cld(cld); + if (cld != nullptr) { + ClaimMetadataVisitingOopIterateClosure::do_cld(cld); + } else { + assert(AOTLinkedClassBulkLoader::is_pending_aot_linked_class(k), "sanity"); + } } inline void ClaimMetadataVisitingOopIterateClosure::do_nmethod(nmethod* nm) { diff --git a/src/hotspot/share/oops/constantPool.cpp b/src/hotspot/share/oops/constantPool.cpp index 7147e2588c9..a435d6e5fd3 100644 --- a/src/hotspot/share/oops/constantPool.cpp +++ b/src/hotspot/share/oops/constantPool.cpp @@ -23,11 +23,11 @@ */ #include "precompiled.hpp" -#include "cds/archiveHeapWriter.hpp" -#include "cds/archiveHeapLoader.hpp" +#include "cds/aotConstantPoolResolver.hpp" #include "cds/archiveBuilder.hpp" +#include "cds/archiveHeapLoader.hpp" +#include "cds/archiveHeapWriter.hpp" #include "cds/cdsConfig.hpp" -#include "cds/classPrelinker.hpp" #include "cds/heapShared.hpp" #include "classfile/classLoader.hpp" #include "classfile/classLoaderData.hpp" @@ -35,6 +35,7 @@ #include "classfile/metadataOnStackMark.hpp" #include "classfile/stringTable.hpp" #include "classfile/systemDictionary.hpp" +#include "classfile/systemDictionaryShared.hpp" #include "classfile/vmClasses.hpp" #include "classfile/vmSymbols.hpp" #include "code/codeCache.hpp" @@ -283,6 +284,44 @@ void ConstantPool::klass_at_put(int class_index, Klass* k) { } #if INCLUDE_CDS_JAVA_HEAP +template +void ConstantPool::iterate_archivable_resolved_references(Function function) { + objArrayOop rr = resolved_references(); + if (rr != nullptr && cache() != nullptr && CDSConfig::is_dumping_invokedynamic()) { + Array* indy_entries = cache()->resolved_indy_entries(); + if (indy_entries != nullptr) { + for (int i = 0; i < indy_entries->length(); i++) { + ResolvedIndyEntry *rie = indy_entries->adr_at(i); + if (rie->is_resolved() && AOTConstantPoolResolver::is_resolution_deterministic(this, rie->constant_pool_index())) { + int rr_index = rie->resolved_references_index(); + assert(resolved_reference_at(rr_index) != nullptr, "must exist"); + function(rr_index); + + // Save the BSM as well (sometimes the JIT looks up the BSM it for replay) + int indy_cp_index = rie->constant_pool_index(); + int bsm_mh_cp_index = bootstrap_method_ref_index_at(indy_cp_index); + int bsm_rr_index = cp_to_object_index(bsm_mh_cp_index); + assert(resolved_reference_at(bsm_rr_index) != nullptr, "must exist"); + function(bsm_rr_index); + } + } + } + + Array* method_entries = cache()->resolved_method_entries(); + if (method_entries != nullptr) { + for (int i = 0; i < method_entries->length(); i++) { + ResolvedMethodEntry* rme = method_entries->adr_at(i); + if (rme->is_resolved(Bytecodes::_invokehandle) && rme->has_appendix() && + cache()->can_archive_resolved_method(this, rme)) { + int rr_index = rme->resolved_references_index(); + assert(resolved_reference_at(rr_index) != nullptr, "must exist"); + function(rr_index); + } + } + } + } +} + // Returns the _resolved_reference array after removing unarchivable items from it. // Returns null if this class is not supported, or _resolved_reference doesn't exist. objArrayOop ConstantPool::prepare_resolved_references_for_archiving() { @@ -300,8 +339,15 @@ objArrayOop ConstantPool::prepare_resolved_references_for_archiving() { objArrayOop rr = resolved_references(); if (rr != nullptr) { + ResourceMark rm; int rr_len = rr->length(); + GrowableArray keep_resolved_refs(rr_len, rr_len, false); + ConstantPool* src_cp = ArchiveBuilder::current()->get_source_addr(this); + src_cp->iterate_archivable_resolved_references([&](int rr_index) { + keep_resolved_refs.at_put(rr_index, true); + }); + objArrayOop scratch_rr = HeapShared::scratch_resolved_references(src_cp); Array* ref_map = reference_map(); int ref_map_len = ref_map == nullptr ? 0 : ref_map->length(); @@ -316,8 +362,13 @@ objArrayOop ConstantPool::prepare_resolved_references_for_archiving() { if (!ArchiveHeapWriter::is_string_too_large_to_archive(obj)) { scratch_rr->obj_at_put(i, obj); } + continue; } } + + if (keep_resolved_refs.at(i)) { + scratch_rr->obj_at_put(i, obj); + } } } return scratch_rr; @@ -325,6 +376,32 @@ objArrayOop ConstantPool::prepare_resolved_references_for_archiving() { return rr; } +void ConstantPool::find_required_hidden_classes() { + if (_cache == nullptr) { + return; + } + + ClassLoaderData* loader_data = pool_holder()->class_loader_data(); + if (loader_data == nullptr) { + // These are custom loader classes from the preimage + return; + } + + if (!SystemDictionaryShared::is_builtin_loader(loader_data)) { + // Archiving resolved references for classes from non-builtin loaders + // is not yet supported. + return; + } + + objArrayOop rr = resolved_references(); + if (rr != nullptr) { + iterate_archivable_resolved_references([&](int rr_index) { + oop obj = rr->obj_at(rr_index); + HeapShared::find_required_hidden_classes_in_object(obj); + }); + } +} + void ConstantPool::add_dumped_interned_strings() { objArrayOop rr = resolved_references(); if (rr != nullptr) { @@ -349,6 +426,11 @@ void ConstantPool::restore_unshareable_info(TRAPS) { assert(is_constantPool(), "ensure C++ vtable is restored"); assert(on_stack(), "should always be set for shared constant pools"); assert(is_shared(), "should always be set for shared constant pools"); + if (is_for_method_handle_intrinsic()) { + // See the same check in remove_unshareable_info() below. + assert(cache() == NULL, "must not have cpCache"); + return; + } assert(_cache != nullptr, "constant pool _cache should not be null"); // Only create the new resolved references array if it hasn't been attempted before @@ -388,6 +470,14 @@ void ConstantPool::remove_unshareable_info() { // we always set _on_stack to true to avoid having to change _flags during runtime. _flags |= (_on_stack | _is_shared); + if (is_for_method_handle_intrinsic()) { + // This CP was created by Method::make_method_handle_intrinsic() and has nothing + // that need to be removed/restored. It has no cpCache since the intrinsic methods + // don't have any bytecodes. + assert(cache() == NULL, "must not have cpCache"); + return; + } + // resolved_references(): remember its length. If it cannot be restored // from the archived heap objects at run time, we need to dynamically allocate it. if (cache() != nullptr) { @@ -482,7 +572,7 @@ void ConstantPool::remove_resolved_klass_if_non_deterministic(int cp_index) { can_archive = false; } else { ConstantPool* src_cp = ArchiveBuilder::current()->get_source_addr(this); - can_archive = ClassPrelinker::is_resolution_deterministic(src_cp, cp_index); + can_archive = AOTConstantPoolResolver::is_resolution_deterministic(src_cp, cp_index); } if (!can_archive) { @@ -502,7 +592,7 @@ void ConstantPool::remove_resolved_klass_if_non_deterministic(int cp_index) { (!k->is_instance_klass() || pool_holder()->is_subtype_of(k)) ? "" : " (not supertype)"); } else { Symbol* name = klass_name_at(cp_index); - log.print(" %s", name->as_C_string()); + log.print(" => %s", name->as_C_string()); } } @@ -748,9 +838,7 @@ int ConstantPool::to_cp_index(int index, Bytecodes::Code code) { case Bytecodes::_fast_invokevfinal: // Bytecode interpreter uses this return resolved_method_entry_at(index)->constant_pool_index(); default: - tty->print_cr("Unexpected bytecode: %d", code); - ShouldNotReachHere(); // All cases should have been handled - return -1; + fatal("Unexpected bytecode: %s", Bytecodes::name(code)); } } diff --git a/src/hotspot/share/oops/constantPool.hpp b/src/hotspot/share/oops/constantPool.hpp index bcc9a08dd6c..9ada3e29d49 100644 --- a/src/hotspot/share/oops/constantPool.hpp +++ b/src/hotspot/share/oops/constantPool.hpp @@ -82,7 +82,7 @@ class ConstantPool : public Metadata { friend class JVMCIVMStructs; friend class BytecodeInterpreter; // Directly extracts a klass in the pool for fast instanceof/checkcast friend class Universe; // For null constructor - friend class ClassPrelinker; // CDS + friend class AOTConstantPoolResolver; private: // If you add a new field that points to any metaspace object, you // must add this field to ConstantPool::metaspace_pointers_do(). @@ -109,7 +109,8 @@ class ConstantPool : public Metadata { _has_preresolution = 1, // Flags _on_stack = 2, _is_shared = 4, - _has_dynamic_constant = 8 + _has_dynamic_constant = 8, + _is_for_method_handle_intrinsic = 16 }; u2 _flags; // old fashioned bit twiddling @@ -216,6 +217,9 @@ class ConstantPool : public Metadata { bool has_dynamic_constant() const { return (_flags & _has_dynamic_constant) != 0; } void set_has_dynamic_constant() { _flags |= _has_dynamic_constant; } + bool is_for_method_handle_intrinsic() const { return (_flags & _is_for_method_handle_intrinsic) != 0; } + void set_is_for_method_handle_intrinsic() { _flags |= _is_for_method_handle_intrinsic; } + // Klass holding pool InstanceKlass* pool_holder() const { return _pool_holder; } void set_pool_holder(InstanceKlass* k) { _pool_holder = k; } @@ -679,12 +683,14 @@ class ConstantPool : public Metadata { #if INCLUDE_CDS // CDS support objArrayOop prepare_resolved_references_for_archiving() NOT_CDS_JAVA_HEAP_RETURN_(nullptr); + void find_required_hidden_classes() NOT_CDS_JAVA_HEAP_RETURN; void add_dumped_interned_strings() NOT_CDS_JAVA_HEAP_RETURN; void remove_unshareable_info(); void restore_unshareable_info(TRAPS); private: void remove_unshareable_entries(); void remove_resolved_klass_if_non_deterministic(int cp_index); + template void iterate_archivable_resolved_references(Function function); #endif private: diff --git a/src/hotspot/share/oops/cpCache.cpp b/src/hotspot/share/oops/cpCache.cpp index 321d8add755..bcf3669c9df 100644 --- a/src/hotspot/share/oops/cpCache.cpp +++ b/src/hotspot/share/oops/cpCache.cpp @@ -23,9 +23,9 @@ */ #include "precompiled.hpp" +#include "cds/aotConstantPoolResolver.hpp" #include "cds/archiveBuilder.hpp" #include "cds/cdsConfig.hpp" -#include "cds/classPrelinker.hpp" #include "cds/heapShared.hpp" #include "classfile/resolutionErrors.hpp" #include "classfile/systemDictionary.hpp" @@ -401,9 +401,7 @@ void ConstantPoolCache::remove_unshareable_info() { assert(CDSConfig::is_dumping_archive(), "sanity"); if (_resolved_indy_entries != nullptr) { - for (int i = 0; i < _resolved_indy_entries->length(); i++) { - resolved_indy_entry_at(i)->remove_unshareable_info(); - } + remove_resolved_indy_entries_if_non_deterministic(); } if (_resolved_field_entries != nullptr) { remove_resolved_field_entries_if_non_deterministic(); @@ -422,7 +420,7 @@ void ConstantPoolCache::remove_resolved_field_entries_if_non_deterministic() { bool archived = false; bool resolved = rfi->is_resolved(Bytecodes::_getfield) || rfi->is_resolved(Bytecodes::_putfield); - if (resolved && ClassPrelinker::is_resolution_deterministic(src_cp, cp_index)) { + if (resolved && AOTConstantPoolResolver::is_resolution_deterministic(src_cp, cp_index)) { rfi->mark_and_relocate(); archived = true; } else { @@ -436,11 +434,10 @@ void ConstantPoolCache::remove_resolved_field_entries_if_non_deterministic() { Symbol* klass_name = cp->klass_name_at(klass_cp_index); Symbol* name = cp->uncached_name_ref_at(cp_index); Symbol* signature = cp->uncached_signature_ref_at(cp_index); - log.print("%s field CP entry [%3d]: %s %s %s.%s:%s", + log.print("%s field CP entry [%3d]: %s => %s.%s:%s", (archived ? "archived" : "reverted"), cp_index, cp->pool_holder()->name()->as_C_string(), - (archived ? "=>" : " "), klass_name->as_C_string(), name->as_C_string(), signature->as_C_string()); } } @@ -457,13 +454,13 @@ void ConstantPoolCache::remove_resolved_method_entries_if_non_deterministic() { bool archived = false; bool resolved = rme->is_resolved(Bytecodes::_invokevirtual) || rme->is_resolved(Bytecodes::_invokespecial) || - rme->is_resolved(Bytecodes::_invokeinterface); + rme->is_resolved(Bytecodes::_invokeinterface) || + rme->is_resolved(Bytecodes::_invokehandle); // Just for safety -- this should not happen, but do not archive if we ever see this. - resolved &= !(rme->is_resolved(Bytecodes::_invokehandle) || - rme->is_resolved(Bytecodes::_invokestatic)); + resolved &= !(rme->is_resolved(Bytecodes::_invokestatic)); - if (resolved && can_archive_resolved_method(rme)) { + if (resolved && can_archive_resolved_method(src_cp, rme)) { rme->mark_and_relocate(src_cp); archived = true; } else { @@ -495,7 +492,41 @@ void ConstantPoolCache::remove_resolved_method_entries_if_non_deterministic() { } } -bool ConstantPoolCache::can_archive_resolved_method(ResolvedMethodEntry* method_entry) { +void ConstantPoolCache::remove_resolved_indy_entries_if_non_deterministic() { + ConstantPool* cp = constant_pool(); + ConstantPool* src_cp = ArchiveBuilder::current()->get_source_addr(cp); + for (int i = 0; i < _resolved_indy_entries->length(); i++) { + ResolvedIndyEntry* rei = _resolved_indy_entries->adr_at(i); + int cp_index = rei->constant_pool_index(); + bool archived = false; + bool resolved = rei->is_resolved(); + if (resolved && AOTConstantPoolResolver::is_resolution_deterministic(src_cp, cp_index)) { + rei->mark_and_relocate(); + archived = true; + } else { + rei->remove_unshareable_info(); + } + if (resolved) { + LogStreamHandle(Trace, cds, resolve) log; + if (log.is_enabled()) { + ResourceMark rm; + int bsm = cp->bootstrap_method_ref_index_at(cp_index); + int bsm_ref = cp->method_handle_index_at(bsm); + Symbol* bsm_name = cp->uncached_name_ref_at(bsm_ref); + Symbol* bsm_signature = cp->uncached_signature_ref_at(bsm_ref); + Symbol* bsm_klass = cp->klass_name_at(cp->uncached_klass_ref_index_at(bsm_ref)); + log.print("%s indy CP entry [%3d]: %s (%d)", + (archived ? "archived" : "reverted"), + cp_index, cp->pool_holder()->name()->as_C_string(), i); + log.print(" %s %s.%s:%s", (archived ? "=>" : " "), bsm_klass->as_C_string(), + bsm_name->as_C_string(), bsm_signature->as_C_string()); + } + ArchiveBuilder::alloc_stats()->record_indy_cp_entry(archived, resolved && !archived); + } + } +} + +bool ConstantPoolCache::can_archive_resolved_method(ConstantPool* src_cp, ResolvedMethodEntry* method_entry) { InstanceKlass* pool_holder = constant_pool()->pool_holder(); if (!(pool_holder->is_shared_boot_class() || pool_holder->is_shared_platform_class() || pool_holder->is_shared_app_class())) { @@ -520,10 +551,9 @@ bool ConstantPoolCache::can_archive_resolved_method(ResolvedMethodEntry* method_ } int cp_index = method_entry->constant_pool_index(); - ConstantPool* src_cp = ArchiveBuilder::current()->get_source_addr(constant_pool()); assert(src_cp->tag_at(cp_index).is_method() || src_cp->tag_at(cp_index).is_interface_method(), "sanity"); - if (!ClassPrelinker::is_resolution_deterministic(src_cp, cp_index)) { + if (!AOTConstantPoolResolver::is_resolution_deterministic(src_cp, cp_index)) { return false; } @@ -531,11 +561,16 @@ bool ConstantPoolCache::can_archive_resolved_method(ResolvedMethodEntry* method_ method_entry->is_resolved(Bytecodes::_invokevirtual) || method_entry->is_resolved(Bytecodes::_invokespecial)) { return true; + } else if (method_entry->is_resolved(Bytecodes::_invokehandle)) { + if (CDSConfig::is_dumping_invokedynamic()) { + // invokehandle depends on archived MethodType and LambdaForms. + return true; + } else { + return false; + } } else { - // invokestatic and invokehandle are not supported yet. return false; } - } #endif // INCLUDE_CDS diff --git a/src/hotspot/share/oops/cpCache.hpp b/src/hotspot/share/oops/cpCache.hpp index f95f141d845..8652409a1a4 100644 --- a/src/hotspot/share/oops/cpCache.hpp +++ b/src/hotspot/share/oops/cpCache.hpp @@ -224,8 +224,9 @@ class ConstantPoolCache: public MetaspaceObj { #if INCLUDE_CDS void remove_resolved_field_entries_if_non_deterministic(); + void remove_resolved_indy_entries_if_non_deterministic(); void remove_resolved_method_entries_if_non_deterministic(); - bool can_archive_resolved_method(ResolvedMethodEntry* method_entry); + bool can_archive_resolved_method(ConstantPool* src_cp, ResolvedMethodEntry* method_entry); #endif // RedefineClasses support diff --git a/src/hotspot/share/oops/instanceKlass.cpp b/src/hotspot/share/oops/instanceKlass.cpp index a9024bf4a9f..d2761667f64 100644 --- a/src/hotspot/share/oops/instanceKlass.cpp +++ b/src/hotspot/share/oops/instanceKlass.cpp @@ -23,6 +23,7 @@ */ #include "precompiled.hpp" +#include "cds/aotClassInitializer.hpp" #include "cds/archiveUtils.hpp" #include "cds/cdsConfig.hpp" #include "cds/cdsEnumKlass.hpp" @@ -734,6 +735,18 @@ bool InstanceKlass::is_sealed() const { _permitted_subclasses != Universe::the_empty_short_array(); } +// JLS 8.9: An enum class is either implicitly final and derives +// from java.lang.Enum, or else is implicitly sealed to its +// anonymous subclasses. This query detects both kinds. +// It does not validate the finality or +// sealing conditions: it merely checks for a super of Enum. +// This is sufficient for recognizing well-formed enums. +bool InstanceKlass::is_enum_subclass() const { + InstanceKlass* s = java_super(); + return (s == vmClasses::Enum_klass() || + (s != nullptr && s->java_super() == vmClasses::Enum_klass())); +} + bool InstanceKlass::should_be_initialized() const { return !is_initialized(); } @@ -791,6 +804,68 @@ void InstanceKlass::initialize(TRAPS) { } } +#ifdef ASSERT +void InstanceKlass::assert_no_clinit_will_run_for_aot_initialized_class() const { + assert(has_aot_initialized_mirror(), "must be"); + + InstanceKlass* s = java_super(); + if (s != nullptr) { + DEBUG_ONLY(ResourceMark rm); + assert(s->is_initialized(), "super class %s of aot-inited class %s must have been initialized", + s->external_name(), external_name()); + s->assert_no_clinit_will_run_for_aot_initialized_class(); + } + + Array* interfaces = local_interfaces(); + int len = interfaces->length(); + for (int i = 0; i < len; i++) { + InstanceKlass* intf = interfaces->at(i); + if (!intf->is_initialized()) { + ResourceMark rm; + // Note: an interface needs to be marked as is_initialized() only if + // - it has a + // - it has declared a default method. + assert(!intf->interface_needs_clinit_execution_as_super(/*also_check_supers*/false), + "uninitialized super interface %s of aot-inited class %s must not have ", + intf->external_name(), external_name()); + } + } +} +#endif + +#if INCLUDE_CDS +void InstanceKlass::initialize_with_aot_initialized_mirror(TRAPS) { + assert(has_aot_initialized_mirror(), "must be"); + assert(CDSConfig::is_loading_heap(), "must be"); + assert(CDSConfig::is_using_aot_linked_classes(), "must be"); + assert_no_clinit_will_run_for_aot_initialized_class(); + + if (is_initialized()) { + return; + } + + if (log_is_enabled(Info, cds, init)) { + ResourceMark rm; + log_info(cds, init)("%s (aot-inited)", external_name()); + } + + link_class(CHECK); + +#ifdef ASSERT + { + Handle h_init_lock(THREAD, init_lock()); + ObjectLocker ol(h_init_lock, THREAD); + assert(!is_initialized(), "sanity"); + assert(!is_being_initialized(), "sanity"); + assert(!is_in_error_state(), "sanity"); + } +#endif + + set_init_thread(THREAD); + AOTClassInitializer::call_runtime_setup(THREAD, this); + set_initialization_state_and_notify(fully_initialized, CHECK); +} +#endif bool InstanceKlass::verify_code(TRAPS) { // 1) Verify the bytecodes @@ -1578,7 +1653,10 @@ void InstanceKlass::call_class_initializer(TRAPS) { #if INCLUDE_CDS // This is needed to ensure the consistency of the archived heap objects. - if (has_archived_enum_objs()) { + if (has_aot_initialized_mirror() && CDSConfig::is_loading_heap()) { + AOTClassInitializer::call_runtime_setup(THREAD, this); + return; + } else if (has_archived_enum_objs()) { assert(is_shared(), "must be"); bool initialized = CDSEnumKlass::initialize_enum_klass(this, CHECK); if (initialized) { @@ -1607,6 +1685,47 @@ void InstanceKlass::call_class_initializer(TRAPS) { } } +// If a class that implements this interface is initialized, is the JVM required +// to first execute a method declared in this interface, +// or (if also_check_supers==true) any of the super types of this interface? +// +// JVMS 5.5. Initialization, step 7: Next, if C is a class rather than +// an interface, then let SC be its superclass and let SI1, ..., SIn +// be all superinterfaces of C (whether direct or indirect) that +// declare at least one non-abstract, non-static method. +// +// So when an interface is initialized, it does not look at its +// supers. But a proper class will ensure that all of its supers have +// run their methods, except that it disregards interfaces +// that lack a non-static concrete method (i.e., a default method). +// Therefore, you should probably call this method only when the +// current class is a super of some proper class, not an interface. +bool InstanceKlass::interface_needs_clinit_execution_as_super(bool also_check_supers) const { + assert(is_interface(), "must be"); + + if (!has_nonstatic_concrete_methods()) { + // quick check: no nonstatic concrete methods are declared by this or any super interfaces + return false; + } + + // JVMS 5.5. Initialization + // ...If C is an interface that declares a non-abstract, + // non-static method, the initialization of a class that + // implements C directly or indirectly. + if (declares_nonstatic_concrete_methods() && class_initializer() != nullptr) { + return true; + } + if (also_check_supers) { + Array* all_ifs = transitive_interfaces(); + for (int i = 0; i < all_ifs->length(); ++i) { + InstanceKlass* super_intf = all_ifs->at(i); + if (super_intf->declares_nonstatic_concrete_methods() && super_intf->class_initializer() != nullptr) { + return true; + } + } + } + return false; +} void InstanceKlass::mask_for(const methodHandle& method, int bci, InterpreterOopMap* entry_for) { @@ -2497,6 +2616,7 @@ void InstanceKlass::metaspace_pointers_do(MetaspaceClosure* it) { } } + it->push(&_nest_host); it->push(&_nest_members); it->push(&_permitted_subclasses); it->push(&_record_components); @@ -2560,8 +2680,12 @@ void InstanceKlass::remove_unshareable_info() { _methods_jmethod_ids = nullptr; _jni_ids = nullptr; _oop_map_cache = nullptr; - // clear _nest_host to ensure re-load at runtime - _nest_host = nullptr; + if (CDSConfig::is_dumping_invokedynamic() && HeapShared::is_lambda_proxy_klass(this)) { + // keep _nest_host + } else { + // clear _nest_host to ensure re-load at runtime + _nest_host = nullptr; + } init_shared_package_entry(); _dep_context_last_cleaned = 0; @@ -2700,6 +2824,18 @@ bool InstanceKlass::can_be_verified_at_dumptime() const { } return true; } + +int InstanceKlass::shared_class_loader_type() const { + if (is_shared_boot_class()) { + return ClassLoader::BOOT_LOADER; + } else if (is_shared_platform_class()) { + return ClassLoader::PLATFORM_LOADER; + } else if (is_shared_app_class()) { + return ClassLoader::APP_LOADER; + } else { + return ClassLoader::OTHER; + } +} #endif // INCLUDE_CDS #if INCLUDE_JVMTI @@ -2907,6 +3043,10 @@ ModuleEntry* InstanceKlass::module() const { return class_loader_data()->unnamed_module(); } +bool InstanceKlass::in_javabase_module() const { + return module()->name() == vmSymbols::java_base(); +} + void InstanceKlass::set_package(ClassLoaderData* loader_data, PackageEntry* pkg_entry, TRAPS) { // ensure java/ packages only loaded by boot or platform builtin loaders diff --git a/src/hotspot/share/oops/instanceKlass.hpp b/src/hotspot/share/oops/instanceKlass.hpp index daaa16f2059..b3283a04d44 100644 --- a/src/hotspot/share/oops/instanceKlass.hpp +++ b/src/hotspot/share/oops/instanceKlass.hpp @@ -323,6 +323,7 @@ class InstanceKlass: public Klass { void set_shared_loading_failed() { _misc_flags.set_shared_loading_failed(true); } #if INCLUDE_CDS + int shared_class_loader_type() const; void set_shared_class_loader_type(s2 loader_type) { _misc_flags.set_shared_class_loader_type(loader_type); } void assign_class_loader_type() { _misc_flags.assign_class_loader_type(_class_loader_data); } #endif @@ -429,6 +430,9 @@ class InstanceKlass: public Klass { } bool is_record() const; + // test for enum class (or possibly an anonymous subclass within a sealed enum) + bool is_enum_subclass() const; + // permitted subclasses Array* permitted_subclasses() const { return _permitted_subclasses; } void set_permitted_subclasses(Array* s) { _permitted_subclasses = s; } @@ -475,6 +479,7 @@ class InstanceKlass: public Klass { // package PackageEntry* package() const { return _package_entry; } ModuleEntry* module() const; + bool in_javabase_module() const; bool in_unnamed_package() const { return (_package_entry == nullptr); } void set_package(ClassLoaderData* loader_data, PackageEntry* pkg_entry, TRAPS); // If the package for the InstanceKlass is in the boot loader's package entry @@ -531,12 +536,15 @@ class InstanceKlass: public Klass { // initialization (virtuals from Klass) bool should_be_initialized() const; // means that initialize should be called + void initialize_with_aot_initialized_mirror(TRAPS); + void assert_no_clinit_will_run_for_aot_initialized_class() const NOT_DEBUG_RETURN; void initialize(TRAPS); void link_class(TRAPS); bool link_class_or_fail(TRAPS); // returns false on failure void rewrite_class(TRAPS); void link_methods(TRAPS); Method* class_initializer() const; + bool interface_needs_clinit_execution_as_super(bool also_check_supers=true) const; // reference type ReferenceType reference_type() const { return (ReferenceType)_reference_type; } diff --git a/src/hotspot/share/oops/klass.hpp b/src/hotspot/share/oops/klass.hpp index 2629be64bea..8c128ab9ce6 100644 --- a/src/hotspot/share/oops/klass.hpp +++ b/src/hotspot/share/oops/klass.hpp @@ -195,7 +195,12 @@ class Klass : public Metadata { _has_archived_enum_objs = 1 << 4, // This class was not loaded from a classfile in the module image // or classpath. - _is_generated_shared_class = 1 << 5 + _is_generated_shared_class = 1 << 5, + // archived mirror already initialized by AOT-cache assembly: no further need to call + _has_aot_initialized_mirror = 1 << 6, + // If this class has been aot-inititalized, do we need to call its runtimeSetup() + // method during the production run? + _is_runtime_setup_required = 1 << 7, }; #endif @@ -377,6 +382,23 @@ class Klass : public Metadata { NOT_CDS(return false;) } + void set_has_aot_initialized_mirror() { + CDS_ONLY(_shared_class_flags |= _has_aot_initialized_mirror;) + } + bool has_aot_initialized_mirror() const { + CDS_ONLY(return (_shared_class_flags & _has_aot_initialized_mirror) != 0;) + NOT_CDS(return false;) + } + + void set_is_runtime_setup_required() { + assert(has_aot_initialized_mirror(), "sanity"); + CDS_ONLY(_shared_class_flags |= _is_runtime_setup_required;) + } + bool is_runtime_setup_required() const { + CDS_ONLY(return (_shared_class_flags & _is_runtime_setup_required) != 0;) + NOT_CDS(return false;) + } + bool is_shared() const { // shadows MetaspaceObj::is_shared)() CDS_ONLY(return (_shared_class_flags & _is_shared_class) != 0;) NOT_CDS(return false;) diff --git a/src/hotspot/share/oops/method.cpp b/src/hotspot/share/oops/method.cpp index 26a047449ed..917c93304c1 100644 --- a/src/hotspot/share/oops/method.cpp +++ b/src/hotspot/share/oops/method.cpp @@ -1432,6 +1432,7 @@ methodHandle Method::make_method_handle_intrinsic(vmIntrinsics::ID iid, cp->symbol_at_put(_imcp_invoke_name, name); cp->symbol_at_put(_imcp_invoke_signature, signature); cp->set_has_preresolution(); + cp->set_is_for_method_handle_intrinsic(); // decide on access bits: public or not? int flags_bits = (JVM_ACC_NATIVE | JVM_ACC_SYNTHETIC | JVM_ACC_FINAL); @@ -1480,6 +1481,16 @@ methodHandle Method::make_method_handle_intrinsic(vmIntrinsics::ID iid, return m; } +#if INCLUDE_CDS +void Method::restore_archived_method_handle_intrinsic(methodHandle m, TRAPS) { + m->link_method(m, CHECK); + + if (m->intrinsic_id() == vmIntrinsics::_linkToNative) { + m->set_interpreter_entry(m->adapter()->get_i2c_entry()); + } +} +#endif + Klass* Method::check_non_bcp_klass(Klass* klass) { if (klass != nullptr && klass->class_loader() != nullptr) { if (klass->is_objArray_klass()) diff --git a/src/hotspot/share/oops/method.hpp b/src/hotspot/share/oops/method.hpp index 232e5fb577e..cc3caccd16a 100644 --- a/src/hotspot/share/oops/method.hpp +++ b/src/hotspot/share/oops/method.hpp @@ -122,6 +122,7 @@ class Method : public Metadata { #if INCLUDE_CDS void remove_unshareable_info(); void restore_unshareable_info(TRAPS); + static void restore_archived_method_handle_intrinsic(methodHandle m, TRAPS); #endif // accessors for instance variables diff --git a/src/hotspot/share/prims/jvm.cpp b/src/hotspot/share/prims/jvm.cpp index 12ed10630fc..3288f2eefe4 100644 --- a/src/hotspot/share/prims/jvm.cpp +++ b/src/hotspot/share/prims/jvm.cpp @@ -2838,7 +2838,7 @@ static void thread_entry(JavaThread* thread, TRAPS) { JVM_ENTRY(void, JVM_StartThread(JNIEnv* env, jobject jthread)) #if INCLUDE_CDS - if (CDSConfig::is_dumping_static_archive()) { + if (CDSConfig::allow_only_single_java_thread()) { // During java -Xshare:dump, if we allow multiple Java threads to // execute in parallel, symbols and classes may be loaded in // random orders which will make the resulting CDS archive diff --git a/src/hotspot/share/prims/jvmtiExport.cpp b/src/hotspot/share/prims/jvmtiExport.cpp index 087f426c537..c68692a2fa1 100644 --- a/src/hotspot/share/prims/jvmtiExport.cpp +++ b/src/hotspot/share/prims/jvmtiExport.cpp @@ -1075,6 +1075,16 @@ bool JvmtiExport::has_early_class_hook_env() { return false; } +bool JvmtiExport::has_early_vmstart_env() { + JvmtiEnvIterator it; + for (JvmtiEnv* env = it.first(); env != nullptr; env = it.next(env)) { + if (env->early_vmstart_env()) { + return true; + } + } + return false; +} + bool JvmtiExport::_should_post_class_file_load_hook = false; // This flag is read by C2 during VM internal objects allocation diff --git a/src/hotspot/share/prims/jvmtiExport.hpp b/src/hotspot/share/prims/jvmtiExport.hpp index e0fb84f2c03..324e437411a 100644 --- a/src/hotspot/share/prims/jvmtiExport.hpp +++ b/src/hotspot/share/prims/jvmtiExport.hpp @@ -371,6 +371,7 @@ class JvmtiExport : public AllStatic { } static bool is_early_phase() NOT_JVMTI_RETURN_(false); static bool has_early_class_hook_env() NOT_JVMTI_RETURN_(false); + static bool has_early_vmstart_env() NOT_JVMTI_RETURN_(false); // Return true if the class was modified by the hook. static bool post_class_file_load_hook(Symbol* h_name, Handle class_loader, Handle h_protection_domain, diff --git a/src/hotspot/share/runtime/arguments.cpp b/src/hotspot/share/runtime/arguments.cpp index 7b8604659a0..175a85e33fb 100644 --- a/src/hotspot/share/runtime/arguments.cpp +++ b/src/hotspot/share/runtime/arguments.cpp @@ -2534,19 +2534,23 @@ jint Arguments::parse_each_vm_init_arg(const JavaVMInitArgs* args, bool* patch_m // -Xshare:dump } else if (match_option(option, "-Xshare:dump")) { CDSConfig::enable_dumping_static_archive(); + CDSConfig::set_old_cds_flags_used(); // -Xshare:on } else if (match_option(option, "-Xshare:on")) { UseSharedSpaces = true; RequireSharedSpaces = true; + CDSConfig::set_old_cds_flags_used(); // -Xshare:auto || -XX:ArchiveClassesAtExit= } else if (match_option(option, "-Xshare:auto")) { UseSharedSpaces = true; RequireSharedSpaces = false; xshare_auto_cmd_line = true; + CDSConfig::set_old_cds_flags_used(); // -Xshare:off } else if (match_option(option, "-Xshare:off")) { UseSharedSpaces = false; RequireSharedSpaces = false; + CDSConfig::set_old_cds_flags_used(); // -Xverify } else if (match_option(option, "-Xverify", &tail)) { if (strcmp(tail, ":all") == 0 || strcmp(tail, "") == 0) { diff --git a/src/hotspot/share/runtime/flags/jvmFlagAccess.cpp b/src/hotspot/share/runtime/flags/jvmFlagAccess.cpp index 8d9cbe33d12..843ee24c909 100644 --- a/src/hotspot/share/runtime/flags/jvmFlagAccess.cpp +++ b/src/hotspot/share/runtime/flags/jvmFlagAccess.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -310,6 +310,17 @@ JVMFlag::Error JVMFlagAccess::set_impl(JVMFlag* flag, void* value, JVMFlagOrigin JVMFlag::Error JVMFlagAccess::set_ccstr(JVMFlag* flag, ccstr* value, JVMFlagOrigin origin) { if (flag == nullptr) return JVMFlag::INVALID_FLAG; if (!flag->is_ccstr()) return JVMFlag::WRONG_FORMAT; + const JVMTypedFlagLimit* constraint = (const JVMTypedFlagLimit*)JVMFlagLimit::get_constraint(flag); + if (constraint != nullptr && constraint->phase() <= JVMFlagLimit::validating_phase()) { + bool verbose = JVMFlagLimit::verbose_checks_needed() | (origin == JVMFlagOrigin::ERGONOMIC); + JVMFlag::Error err = ((JVMFlagConstraintFunc_ccstr)constraint->constraint_func())(*value, verbose); + if (err != JVMFlag::SUCCESS) { + if (origin == JVMFlagOrigin::ERGONOMIC) { + fatal("FLAG_SET_ERGO cannot be used to set an invalid value for %s", flag->name()); + } + return err; + } + } ccstr old_value = flag->get_ccstr(); trace_flag_changed(flag, old_value, *value, origin); char* new_value = nullptr; diff --git a/src/hotspot/share/runtime/flags/jvmFlagConstraintsRuntime.cpp b/src/hotspot/share/runtime/flags/jvmFlagConstraintsRuntime.cpp index 1c02e929113..354e828372f 100644 --- a/src/hotspot/share/runtime/flags/jvmFlagConstraintsRuntime.cpp +++ b/src/hotspot/share/runtime/flags/jvmFlagConstraintsRuntime.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -32,6 +32,21 @@ #include "runtime/task.hpp" #include "utilities/powerOfTwo.hpp" +JVMFlag::Error AOTModeConstraintFunc(ccstr value, bool verbose) { + if (strcmp(value, "off") != 0 && + strcmp(value, "record") != 0 && + strcmp(value, "create") != 0 && + strcmp(value, "auto") != 0 && + strcmp(value, "on") != 0) { + JVMFlag::printError(verbose, + "Unrecognized value %s for AOTMode. Must be one of the following: " + "off, record, create, auto, on\n", + value); + return JVMFlag::VIOLATES_CONSTRAINT; + } + + return JVMFlag::SUCCESS; +} JVMFlag::Error ObjectAlignmentInBytesConstraintFunc(int value, bool verbose) { if (!is_power_of_2(value)) { JVMFlag::printError(verbose, diff --git a/src/hotspot/share/runtime/flags/jvmFlagConstraintsRuntime.hpp b/src/hotspot/share/runtime/flags/jvmFlagConstraintsRuntime.hpp index cbe28456b8a..20d420a8e7e 100644 --- a/src/hotspot/share/runtime/flags/jvmFlagConstraintsRuntime.hpp +++ b/src/hotspot/share/runtime/flags/jvmFlagConstraintsRuntime.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -34,6 +34,7 @@ */ #define RUNTIME_CONSTRAINTS(f) \ + f(ccstr, AOTModeConstraintFunc) \ f(int, ObjectAlignmentInBytesConstraintFunc) \ f(int, ContendedPaddingWidthConstraintFunc) \ f(int, PerfDataSamplingIntervalFunc) \ diff --git a/src/hotspot/share/runtime/threads.cpp b/src/hotspot/share/runtime/threads.cpp index 29386a0c368..41ac7bc6627 100644 --- a/src/hotspot/share/runtime/threads.cpp +++ b/src/hotspot/share/runtime/threads.cpp @@ -24,12 +24,15 @@ */ #include "precompiled.hpp" +#include "cds/aotLinkedClassBulkLoader.hpp" #include "cds/cds_globals.hpp" #include "cds/cdsConfig.hpp" +#include "cds/heapShared.hpp" #include "cds/metaspaceShared.hpp" #include "classfile/classLoader.hpp" #include "classfile/javaClasses.hpp" #include "classfile/javaThreadStatus.hpp" +#include "classfile/symbolTable.hpp" #include "classfile/systemDictionary.hpp" #include "classfile/vmClasses.hpp" #include "classfile/vmSymbols.hpp" @@ -350,12 +353,15 @@ void Threads::initialize_java_lang_classes(JavaThread* main_thread, TRAPS) { initialize_class(vmSymbols::java_lang_System(), CHECK); // The VM creates & returns objects of this class. Make sure it's initialized. initialize_class(vmSymbols::java_lang_Class(), CHECK); + initialize_class(vmSymbols::java_lang_ThreadGroup(), CHECK); Handle thread_group = create_initial_thread_group(CHECK); Universe::set_main_thread_group(thread_group()); initialize_class(vmSymbols::java_lang_Thread(), CHECK); create_initial_thread(thread_group, main_thread, CHECK); + HeapShared::init_box_classes(CHECK); + // The VM creates objects of this class. initialize_class(vmSymbols::java_lang_Module(), CHECK); @@ -403,6 +409,7 @@ void Threads::initialize_java_lang_classes(JavaThread* main_thread, TRAPS) { initialize_class(vmSymbols::java_lang_StackOverflowError(), CHECK); initialize_class(vmSymbols::java_lang_IllegalMonitorStateException(), CHECK); initialize_class(vmSymbols::java_lang_IllegalArgumentException(), CHECK); + initialize_class(vmSymbols::java_lang_InternalError(), CHECK); } void Threads::initialize_jsr292_core_classes(TRAPS) { @@ -412,6 +419,10 @@ void Threads::initialize_jsr292_core_classes(TRAPS) { initialize_class(vmSymbols::java_lang_invoke_ResolvedMethodName(), CHECK); initialize_class(vmSymbols::java_lang_invoke_MemberName(), CHECK); initialize_class(vmSymbols::java_lang_invoke_MethodHandleNatives(), CHECK); + + if (UseSharedSpaces) { + HeapShared::initialize_java_lang_invoke(CHECK); + } } jint Threads::create_vm(JavaVMInitArgs* args, bool* canTryAgain) { @@ -737,6 +748,11 @@ jint Threads::create_vm(JavaVMInitArgs* args, bool* canTryAgain) { } #endif + if (CDSConfig::is_using_aot_linked_classes()) { + AOTLinkedClassBulkLoader::finish_loading_javabase_classes(CHECK_JNI_ERR); + SystemDictionary::restore_archived_method_handle_intrinsics(); + } + // Start string deduplication thread if requested. if (StringDedup::is_enabled()) { StringDedup::start(); @@ -752,6 +768,13 @@ jint Threads::create_vm(JavaVMInitArgs* args, bool* canTryAgain) { // loaded until phase 2 completes call_initPhase2(CHECK_JNI_ERR); + if (CDSConfig::is_using_aot_linked_classes()) { + AOTLinkedClassBulkLoader::load_non_javabase_classes(THREAD); + } +#ifndef PRODUCT + HeapShared::initialize_test_class_from_archive(THREAD); +#endif + JFR_ONLY(Jfr::on_create_vm_2();) // Always call even when there are not JVMTI environments yet, since environments diff --git a/src/java.base/share/classes/java/lang/Class.java b/src/java.base/share/classes/java/lang/Class.java index ba63f2d538f..771084384c8 100644 --- a/src/java.base/share/classes/java/lang/Class.java +++ b/src/java.base/share/classes/java/lang/Class.java @@ -225,6 +225,11 @@ public final class Class implements java.io.Serializable, private static native void registerNatives(); static { + runtimeSetup(); + } + + // Called from JVM when loading an AOT cache + private static void runtimeSetup() { registerNatives(); } @@ -3425,6 +3430,15 @@ private static ReflectionFactory getReflectionFactory() { } private static ReflectionFactory reflectionFactory; + /** + * When CDS is enabled, the Class class may be aot-initialized. However, + * we can't archive reflectionFactory, so we reset it to null, so it + * will be allocated again at runtime. + */ + private static void resetArchivedStates() { + reflectionFactory = null; + } + /** * Returns the elements of this enum class or null if this * Class object does not represent an enum class. diff --git a/src/java.base/share/classes/java/lang/invoke/LambdaFormEditor.java b/src/java.base/share/classes/java/lang/invoke/LambdaFormEditor.java index 4de0d9c95cb..8d84c5f8096 100644 --- a/src/java.base/share/classes/java/lang/invoke/LambdaFormEditor.java +++ b/src/java.base/share/classes/java/lang/invoke/LambdaFormEditor.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -38,6 +38,7 @@ import static java.lang.invoke.MethodHandleImpl.Intrinsic; import static java.lang.invoke.MethodHandleImpl.NF_loop; import static java.lang.invoke.MethodHandleImpl.makeIntrinsic; +import static java.lang.invoke.MethodHandleNatives.USE_SOFT_CACHE; /** Transforms on LFs. * A lambda-form editor can derive new LFs from its base LF. @@ -89,12 +90,17 @@ static LambdaFormEditor lambdaFormEditor(LambdaForm lambdaForm) { * Tightly coupled with the TransformKey class, which is used to lookup existing * Transforms. */ - private static final class Transform extends SoftReference { + private static final class Transform { + final Object cache; final long packedBytes; final byte[] fullBytes; private Transform(long packedBytes, byte[] fullBytes, LambdaForm result) { - super(result); + if (USE_SOFT_CACHE) { + cache = new SoftReference(result); + } else { + cache = result; + } this.packedBytes = packedBytes; this.fullBytes = fullBytes; } @@ -135,6 +141,15 @@ public String toString() { } return buf.toString(); } + + @SuppressWarnings({"rawtypes", "unchecked"}) + public LambdaForm get() { + if (cache instanceof LambdaForm lf) { + return lf; + } else { + return ((SoftReference)cache).get(); + } + } } /** diff --git a/src/java.base/share/classes/java/lang/invoke/MethodHandleNatives.java b/src/java.base/share/classes/java/lang/invoke/MethodHandleNatives.java index ac9765ddc3b..4ffbf826317 100644 --- a/src/java.base/share/classes/java/lang/invoke/MethodHandleNatives.java +++ b/src/java.base/share/classes/java/lang/invoke/MethodHandleNatives.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -28,9 +28,11 @@ import jdk.internal.misc.VM; import jdk.internal.ref.CleanerFactory; import sun.invoke.util.Wrapper; +import sun.security.action.GetPropertyAction; import java.lang.invoke.MethodHandles.Lookup; import java.lang.reflect.Field; +import java.util.Properties; import static java.lang.invoke.MethodHandleNatives.Constants.*; import static java.lang.invoke.MethodHandleStatics.TRACE_METHOD_LINKAGE; @@ -690,4 +692,23 @@ static boolean canBeCalledVirtual(MemberName symbolicRef, Class definingClass return (definingClass.isAssignableFrom(symbolicRefClass) || // Msym overrides Mdef symbolicRefClass.isInterface()); // Mdef implements Msym } + + //--- AOTCache support + + /** + * In normal execution, this is set to true, so that LambdaFormEditor and MethodTypeForm will + * use soft references to allow class unloading. + * + * When dumping the AOTCache, this is set to false so that no cached heap objects will + * contain soft references (which are not yet supported by AOTCache - see JDK-8341587). AOTCache + * only stores LambdaFormEditors and MethodTypeForms for classes in the boot/platform/app loaders. + * Such classes will never be unloaded, so it's OK to use hard references. + */ + static final boolean USE_SOFT_CACHE; + + static { + Properties props = GetPropertyAction.privilegedGetProperties(); + USE_SOFT_CACHE = Boolean.parseBoolean( + props.getProperty("java.lang.invoke.MethodHandleNatives.USE_SOFT_CACHE", "true")); + } } diff --git a/src/java.base/share/classes/java/lang/invoke/MethodType.java b/src/java.base/share/classes/java/lang/invoke/MethodType.java index 2b3843b09e3..5e1c0f8581c 100644 --- a/src/java.base/share/classes/java/lang/invoke/MethodType.java +++ b/src/java.base/share/classes/java/lang/invoke/MethodType.java @@ -31,6 +31,8 @@ import java.util.Arrays; import java.util.Collections; import java.util.function.Supplier; +import java.util.HashMap; +import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Objects; @@ -40,6 +42,7 @@ import jdk.internal.util.ReferencedKeySet; import jdk.internal.util.ReferenceKey; +import jdk.internal.misc.CDS; import jdk.internal.vm.annotation.Stable; import sun.invoke.util.BytecodeDescriptor; import sun.invoke.util.VerifyType; @@ -391,6 +394,17 @@ private static MethodType makeImpl(Class rtype, Class[] ptypes, boolean tr ptypes = NO_PTYPES; trusted = true; } MethodType primordialMT = new MethodType(rtype, ptypes); + if (archivedMethodTypes != null) { + // If this JVM process reads from archivedMethodTypes, it never + // modifies the table. So there's no need for synchronization. + // See copyInternTable() below. + assert CDS.isUsingArchive(); + MethodType mt = archivedMethodTypes.get(primordialMT); + if (mt != null) { + return mt; + } + } + MethodType mt = internTable.get(primordialMT); if (mt != null) return mt; @@ -409,7 +423,9 @@ private static MethodType makeImpl(Class rtype, Class[] ptypes, boolean tr mt.form = MethodTypeForm.findForm(mt); return internTable.intern(mt); } + private static final @Stable MethodType[] objectOnlyTypes = new MethodType[20]; + private static @Stable HashMap archivedMethodTypes; /** * Finds or creates a method type whose components are {@code Object} with an optional trailing {@code Object[]} array. @@ -1380,4 +1396,30 @@ private Object readResolve() { wrapAlt = null; return mt; } + + static HashMap copyInternTable() { + HashMap copy = new HashMap<>(); + + for (Iterator i = internTable.iterator(); i.hasNext(); ) { + MethodType t = i.next(); + copy.put(t, t); + } + + return copy; + } + + // This is called from C code, at the very end of Java code execution + // during the AOT cache assembly phase. + static void createArchivedObjects() { + // After the archivedMethodTypes field is assigned, this table + // is never modified. So we don't need synchronization when reading from + // it (which happens only in a future JVM process, never in the current process). + // + // @implNote CDS.isDumpingStaticArchive() is mutually exclusive with + // CDS.isUsingArchive(); at most one of them can return true for any given JVM + // process. + assert CDS.isDumpingStaticArchive(); + archivedMethodTypes = copyInternTable(); + internTable.clear(); + } } diff --git a/src/java.base/share/classes/java/lang/invoke/MethodTypeForm.java b/src/java.base/share/classes/java/lang/invoke/MethodTypeForm.java index 09377618797..69545478ec4 100644 --- a/src/java.base/share/classes/java/lang/invoke/MethodTypeForm.java +++ b/src/java.base/share/classes/java/lang/invoke/MethodTypeForm.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -30,6 +30,7 @@ import java.lang.ref.SoftReference; import static java.lang.invoke.MethodHandleStatics.newIllegalArgumentException; +import static java.lang.invoke.MethodHandleNatives.USE_SOFT_CACHE; /** * Shared information for a group of method types, which differ @@ -51,7 +52,7 @@ final class MethodTypeForm { final MethodType basicType; // the canonical erasure, with primitives simplified // Cached adapter information: - final SoftReference[] methodHandles; + private final Object[] methodHandles; // Indexes into methodHandles: static final int @@ -61,7 +62,7 @@ final class MethodTypeForm { MH_LIMIT = 3; // Cached lambda form information, for basic types only: - final SoftReference[] lambdaForms; + private final Object[] lambdaForms; // Indexes into lambdaForms: static final int @@ -109,39 +110,55 @@ public MethodType basicType() { return basicType; } + @SuppressWarnings({"rawtypes", "unchecked"}) public MethodHandle cachedMethodHandle(int which) { - SoftReference entry = methodHandles[which]; - return (entry != null) ? entry.get() : null; + Object entry = methodHandles[which]; + if (entry == null) { + return null; + } else if (entry instanceof MethodHandle mh) { + return mh; + } else { + return ((SoftReference)entry).get(); + } } public synchronized MethodHandle setCachedMethodHandle(int which, MethodHandle mh) { // Simulate a CAS, to avoid racy duplication of results. - SoftReference entry = methodHandles[which]; - if (entry != null) { - MethodHandle prev = entry.get(); - if (prev != null) { - return prev; - } + MethodHandle prev = cachedMethodHandle(which); + if (prev != null) { + return prev; + } + if (USE_SOFT_CACHE) { + methodHandles[which] = new SoftReference<>(mh); + } else { + methodHandles[which] = mh; } - methodHandles[which] = new SoftReference<>(mh); return mh; } + @SuppressWarnings({"rawtypes", "unchecked"}) public LambdaForm cachedLambdaForm(int which) { - SoftReference entry = lambdaForms[which]; - return (entry != null) ? entry.get() : null; + Object entry = lambdaForms[which]; + if (entry == null) { + return null; + } else if (entry instanceof LambdaForm lf) { + return lf; + } else { + return ((SoftReference)entry).get(); + } } public synchronized LambdaForm setCachedLambdaForm(int which, LambdaForm form) { // Simulate a CAS, to avoid racy duplication of results. - SoftReference entry = lambdaForms[which]; - if (entry != null) { - LambdaForm prev = entry.get(); - if (prev != null) { - return prev; - } + LambdaForm prev = cachedLambdaForm(which); + if (prev != null) { + return prev; + } + if (USE_SOFT_CACHE) { + lambdaForms[which] = new SoftReference<>(form); + } else { + lambdaForms[which] = form; } - lambdaForms[which] = new SoftReference<>(form); return form; } @@ -191,8 +208,8 @@ protected MethodTypeForm(MethodType erasedType) { this.primitiveCount = primitiveCount; this.parameterSlotCount = (short)pslotCount; - this.lambdaForms = new SoftReference[LF_LIMIT]; - this.methodHandles = new SoftReference[MH_LIMIT]; + this.lambdaForms = new Object[LF_LIMIT]; + this.methodHandles = new Object[MH_LIMIT]; } else { this.basicType = MethodType.methodType(basicReturnType, basicPtypes, true); // fill in rest of data from the basic type: diff --git a/src/java.base/share/classes/java/lang/invoke/StringConcatFactory.java b/src/java.base/share/classes/java/lang/invoke/StringConcatFactory.java index 2f5b8f2407e..7e91057cbf4 100644 --- a/src/java.base/share/classes/java/lang/invoke/StringConcatFactory.java +++ b/src/java.base/share/classes/java/lang/invoke/StringConcatFactory.java @@ -1080,6 +1080,8 @@ private StringConcatFactory() { * without copying. */ private static final class InlineHiddenClassStrategy { + // The CLASS_NAME prefix must be the same as used by HeapShared::is_string_concat_klass() + // in the HotSpot code. static final String CLASS_NAME = "java.lang.String$$StringConcat"; static final String METHOD_NAME = "concat"; diff --git a/src/java.base/share/classes/java/util/concurrent/ConcurrentHashMap.java b/src/java.base/share/classes/java/util/concurrent/ConcurrentHashMap.java index 5a23fdb05a6..53919011c6f 100644 --- a/src/java.base/share/classes/java/util/concurrent/ConcurrentHashMap.java +++ b/src/java.base/share/classes/java/util/concurrent/ConcurrentHashMap.java @@ -70,6 +70,7 @@ import java.util.stream.Stream; import jdk.internal.misc.Unsafe; import jdk.internal.util.ArraysSupport; +import jdk.internal.vm.annotation.Stable; /** * A hash table supporting full concurrency of retrievals and @@ -595,7 +596,16 @@ public class ConcurrentHashMap extends AbstractMap static final int HASH_BITS = 0x7fffffff; // usable bits of normal node hash /** Number of CPUS, to place bounds on some sizings */ - static final int NCPU = Runtime.getRuntime().availableProcessors(); + static @Stable int NCPU; + + static { + runtimeSetup(); + } + + // Called from JVM when loading an AOT cache. + private static void runtimeSetup() { + NCPU = Runtime.getRuntime().availableProcessors(); + } /** * Serialized pseudo-fields, provided only for jdk7 compatibility. diff --git a/src/java.base/share/classes/jdk/internal/misc/Unsafe.java b/src/java.base/share/classes/jdk/internal/misc/Unsafe.java index ec6b7591282..e69690f876f 100644 --- a/src/java.base/share/classes/jdk/internal/misc/Unsafe.java +++ b/src/java.base/share/classes/jdk/internal/misc/Unsafe.java @@ -57,6 +57,11 @@ public final class Unsafe { private static native void registerNatives(); static { + runtimeSetup(); + } + + // Called from JVM when loading an AOT cache + private static void runtimeSetup() { registerNatives(); } diff --git a/test/hotspot/jtreg/ProblemList-AotJdk.txt b/test/hotspot/jtreg/ProblemList-AotJdk.txt new file mode 100644 index 00000000000..2528f8d377e --- /dev/null +++ b/test/hotspot/jtreg/ProblemList-AotJdk.txt @@ -0,0 +1,18 @@ +runtime/modules/PatchModule/PatchModuleClassList.java 0000000 generic-all +runtime/NMT/NMTWithCDS.java 0000000 generic-all +runtime/symbols/TestSharedArchiveConfigFile.java 0000000 generic-all + +gc/arguments/TestSerialHeapSizeFlags.java 0000000 generic-all +gc/TestAllocateHeapAtMultiple.java 0000000 generic-all +gc/TestAllocateHeapAt.java 0000000 generic-all + +# use -Xshare +serviceability/sa/ClhsdbCDSJstackPrintAll.java 0000000 generic-all +serviceability/sa/ClhsdbCDSCore.java 0000000 generic-all +serviceability/sa/CDSJMapClstats.java 0000000 generic-all +compiler/intrinsics/klass/TestIsPrimitive.java 0000000 generic-all + +# This test is incompatible with AOTClassLinking. +# It has the assumption about unresolved Integer. +# However when AOTClassLinking is enabled, Integer is always resolved at JVM start-up. +compiler/ciReplay/TestInliningProtectionDomain.java 0000000 generic-all diff --git a/test/hotspot/jtreg/TEST.ROOT b/test/hotspot/jtreg/TEST.ROOT index af97ff465de..1e5094bd116 100644 --- a/test/hotspot/jtreg/TEST.ROOT +++ b/test/hotspot/jtreg/TEST.ROOT @@ -74,6 +74,7 @@ requires.properties= \ vm.rtm.compiler \ vm.cds \ vm.cds.custom.loaders \ + vm.cds.supports.aot.class.linking \ vm.cds.write.archived.java.heap \ vm.continuations \ vm.jvmti \ diff --git a/test/hotspot/jtreg/TEST.groups b/test/hotspot/jtreg/TEST.groups index 575c0caa674..718ecf610f1 100644 --- a/test/hotspot/jtreg/TEST.groups +++ b/test/hotspot/jtreg/TEST.groups @@ -56,6 +56,7 @@ hotspot_runtime_no_cds = \ hotspot_runtime_non_cds_mode = \ runtime \ -runtime/cds/CheckSharingWithDefaultArchive.java \ + -runtime/cds/appcds/aotClassLinking/BulkLoaderTest.java \ -runtime/cds/appcds/dynamicArchive/DynamicSharedSymbols.java \ -runtime/cds/appcds/dynamicArchive/TestAutoCreateSharedArchive.java \ -runtime/cds/appcds/jcmd @@ -430,6 +431,7 @@ hotspot_cds_only = \ hotspot_appcds_dynamic = \ runtime/cds/appcds/ \ + -runtime/cds/appcds/applications \ -runtime/cds/appcds/cacheObject \ -runtime/cds/appcds/complexURI \ -runtime/cds/appcds/customLoader \ @@ -447,10 +449,12 @@ hotspot_appcds_dynamic = \ -runtime/cds/appcds/jvmti/redefineClasses/OldClassAndRedefineClass.java \ -runtime/cds/appcds/lambdaForm/DefaultClassListLFInvokers.java \ -runtime/cds/appcds/methodHandles \ + -runtime/cds/appcds/aotClassLinking/BulkLoaderTest.java \ -runtime/cds/appcds/sharedStrings \ -runtime/cds/appcds/resolvedConstants \ -runtime/cds/appcds/ArchiveRelocationTest.java \ -runtime/cds/appcds/BadBSM.java \ + -runtime/cds/appcds/CommandLineFlagCombo.java \ -runtime/cds/appcds/DumpClassList.java \ -runtime/cds/appcds/DumpClassListWithLF.java \ -runtime/cds/appcds/DumpRuntimeClassesTest.java \ @@ -518,6 +522,61 @@ hotspot_cds_epsilongc = \ runtime/cds/appcds/jigsaw \ runtime/cds/appcds/loaderConstraints +# Run CDS tests with -XX:+AOTClassLinking. This should include most CDS tests, except for +# those that rely on redefining classes that are already archived. +hotspot_aot_classlinking = \ + runtime/cds \ + -runtime/cds/appcds/aotClassLinking \ + -runtime/cds/appcds/BadBSM.java \ + -runtime/cds/appcds/cacheObject/ArchivedIntegerCacheTest.java \ + -runtime/cds/appcds/cacheObject/ArchivedModuleCompareTest.java \ + -runtime/cds/appcds/CDSandJFR.java \ + -runtime/cds/appcds/customLoader/HelloCustom_JFR.java \ + -runtime/cds/appcds/customLoader/ParallelTestMultiFP.java \ + -runtime/cds/appcds/customLoader/ParallelTestSingleFP.java \ + -runtime/cds/appcds/customLoader/SameNameInTwoLoadersTest.java \ + -runtime/cds/appcds/DumpClassListWithLF.java \ + -runtime/cds/appcds/dynamicArchive/ModulePath.java \ + -runtime/cds/appcds/dynamicArchive/LambdaInBaseArchive.java \ + -runtime/cds/appcds/dynamicArchive/LambdasInTwoArchives.java \ + -runtime/cds/appcds/HelloExtTest.java \ + -runtime/cds/appcds/javaldr/AnonVmClassesDuringDump.java \ + -runtime/cds/appcds/javaldr/GCDuringDump.java \ + -runtime/cds/appcds/javaldr/LockDuringDump.java \ + -runtime/cds/appcds/jigsaw/classpathtests/EmptyClassInBootClassPath.java \ + -runtime/cds/appcds/jigsaw/JigsawOptionsCombo.java \ + -runtime/cds/appcds/jigsaw/modulepath/AddOpens.java \ + -runtime/cds/appcds/jigsaw/modulepath/AddModules.java \ + -runtime/cds/appcds/jigsaw/modulepath/JvmtiAddPath.java \ + -runtime/cds/appcds/jigsaw/modulepath/MainModuleOnly.java \ + -runtime/cds/appcds/jigsaw/modulepath/ModulePathAndCP.java \ + -runtime/cds/appcds/jigsaw/modulepath/ModulePathAndCP_JFR.java \ + -runtime/cds/appcds/jigsaw/modulepath/ModulePathAndFMG.java \ + -runtime/cds/appcds/jigsaw/modulepath/OptimizeModuleHandlingTest.java \ + -runtime/cds/appcds/jigsaw/overridetests/OverrideTests.java \ + -runtime/cds/appcds/jigsaw/RedefineClassesInModuleGraph.java \ + -runtime/cds/appcds/JvmtiAddPath.java \ + -runtime/cds/appcds/jvmti \ + -runtime/cds/appcds/LambdaProxyClasslist.java \ + -runtime/cds/appcds/loaderConstraints/LoaderConstraintsTest.java \ + -runtime/cds/appcds/redefineClass \ + -runtime/cds/appcds/resolvedConstants/AOTLinkedLambdas.java \ + -runtime/cds/appcds/resolvedConstants/AOTLinkedVarHandles.java \ + -runtime/cds/appcds/resolvedConstants/ResolvedConstants.java \ + -runtime/cds/appcds/RewriteBytecodesTest.java \ + -runtime/cds/appcds/SpecifySysLoaderProp.java \ + -runtime/cds/appcds/StaticArchiveWithLambda.java \ + -runtime/cds/appcds/TestEpsilonGCWithCDS.java \ + -runtime/cds/appcds/TestParallelGCWithCDS.java \ + -runtime/cds/appcds/TestSerialGCWithCDS.java \ + -runtime/cds/appcds/TestZGCWithCDS.java \ + -runtime/cds/appcds/TestWithProfiler.java \ + -runtime/cds/serviceability/ReplaceCriticalClassesForSubgraphs.java \ + -runtime/cds/serviceability/ReplaceCriticalClasses.java \ + -runtime/cds/serviceability/transformRelatedClasses/TransformInterfaceAndImplementor.java \ + -runtime/cds/serviceability/transformRelatedClasses/TransformSuperAndSubClasses.java \ + -runtime/cds/serviceability/transformRelatedClasses/TransformSuperSubTwoPckgs.java + # needs -nativepath:/images/test/hotspot/jtreg/native/ hotspot_metaspace = \ gtest/MetaspaceGtests.java \ @@ -537,6 +596,10 @@ tier1_runtime_appcds_exclude = \ runtime/cds/appcds/ \ -:tier1_runtime_appcds +tier1_runtime_no_cds = \ + :tier1_runtime \ + -runtime/cds + # This group should be executed with "jtreg -Dtest.cds.run.with.jfr=true ..." # to test interaction between AppCDS and JFR. It also has the side effect of # testing JVMTI ClassFileLoadHook. diff --git a/test/hotspot/jtreg/runtime/cds/SharedBaseAddress.java b/test/hotspot/jtreg/runtime/cds/SharedBaseAddress.java index a7f31cf1a08..49265680ef2 100644 --- a/test/hotspot/jtreg/runtime/cds/SharedBaseAddress.java +++ b/test/hotspot/jtreg/runtime/cds/SharedBaseAddress.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -67,8 +67,23 @@ import jdk.test.lib.cds.CDSOptions; import jdk.test.lib.Platform; import jdk.test.lib.process.OutputAnalyzer; +import jtreg.SkippedException; public class SharedBaseAddress { + static final boolean skipUncompressedOopsTests; + static boolean checkSkipUncompressedOopsTests(String prop) { + String opts = System.getProperty(prop); + return opts.contains("+AOTClassLinking") && + opts.matches(".*[+]Use[A-Za-z]+GC.*") && !opts.contains("+UseG1GC"); + } + static { + // AOTClassLinking requires the ability to load archived heap objects. However, + // due to JDK-8341371, only G1GC supports loading archived heap objects + // with uncompressed oops. + skipUncompressedOopsTests = + checkSkipUncompressedOopsTests("test.vm.opts") || + checkSkipUncompressedOopsTests("test.java.opts"); + } // shared base address test table for {32, 64}bit VM private static final String[] testTableShared = { @@ -100,6 +115,10 @@ public static void test(String[] args, String[] testTable) throws Exception { int end = args[0].equals("0") ? mid : testTable.length; boolean provoke = (args.length > 1 && args[1].equals("provoke")); + if (provoke && skipUncompressedOopsTests) { + throw new SkippedException("Test skipped due to JDK-8341371"); + } + // provoke == true: we want to increase the chance that mapping the generated archive at the designated base // succeeds, to test Klass pointer encoding at that weird location. We do this by sizing heap + class space // small, and by switching off compressed oops. diff --git a/test/hotspot/jtreg/runtime/cds/appcds/AOTFlags.java b/test/hotspot/jtreg/runtime/cds/appcds/AOTFlags.java new file mode 100644 index 00000000000..3a678eefc5b --- /dev/null +++ b/test/hotspot/jtreg/runtime/cds/appcds/AOTFlags.java @@ -0,0 +1,203 @@ +/* + * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +/* + * @test + * @summary "AOT" aliases for traditional CDS command-line options + * @requires vm.cds + * @library /test/lib /test/hotspot/jtreg/runtime/cds/appcds/test-classes + * @build Hello + * @run driver jdk.test.lib.helpers.ClassFileInstaller -jar hello.jar Hello + * @run driver AOTFlags + */ + +import jdk.test.lib.cds.CDSTestUtils; +import jdk.test.lib.helpers.ClassFileInstaller; +import jdk.test.lib.process.OutputAnalyzer; +import jdk.test.lib.process.ProcessTools; + +public class AOTFlags { + static String appJar = ClassFileInstaller.getJarPath("hello.jar"); + static String aotConfigFile = "hello.aotconfig"; + static String aotCacheFile = "hello.aot"; + static String helloClass = "Hello"; + + public static void main(String[] args) throws Exception { + positiveTests(); + negativeTests(); + } + + static void positiveTests() throws Exception { + // (1) Training Run + ProcessBuilder pb = ProcessTools.createLimitedTestJavaProcessBuilder( + "-XX:AOTMode=record", + "-XX:AOTConfiguration=" + aotConfigFile, + "-cp", appJar, helloClass); + + OutputAnalyzer out = CDSTestUtils.executeAndLog(pb, "train"); + out.shouldContain("Hello World"); + out.shouldHaveExitValue(0); + + // (2) Assembly Phase + pb = ProcessTools.createLimitedTestJavaProcessBuilder( + "-XX:AOTMode=create", + "-XX:AOTConfiguration=" + aotConfigFile, + "-XX:AOTCache=" + aotCacheFile, + "-Xlog:cds", + "-cp", appJar); + out = CDSTestUtils.executeAndLog(pb, "asm"); + out.shouldContain("Dumping shared data to file:"); + out.shouldMatch("cds.*hello[.]aot"); + out.shouldHaveExitValue(0); + + // (3) Production Run with AOTCache + pb = ProcessTools.createLimitedTestJavaProcessBuilder( + "-XX:AOTCache=" + aotCacheFile, + "-Xlog:cds", + "-cp", appJar, helloClass); + out = CDSTestUtils.executeAndLog(pb, "prod"); + out.shouldContain("Opened archive hello.aot."); + out.shouldContain("Hello World"); + out.shouldHaveExitValue(0); + + // (4) AOTMode=off + pb = ProcessTools.createLimitedTestJavaProcessBuilder( + "-XX:AOTCache=" + aotCacheFile, + "--show-version", + "-Xlog:cds", + "-XX:AOTMode=off", + "-cp", appJar, helloClass); + out = CDSTestUtils.executeAndLog(pb, "prod"); + out.shouldNotContain(", sharing"); + out.shouldNotContain("Opened archive hello.aot."); + out.shouldContain("Hello World"); + out.shouldHaveExitValue(0); + + // (5) AOTMode=auto + pb = ProcessTools.createLimitedTestJavaProcessBuilder( + "-XX:AOTCache=" + aotCacheFile, + "--show-version", + "-Xlog:cds", + "-XX:AOTMode=auto", + "-cp", appJar, helloClass); + out = CDSTestUtils.executeAndLog(pb, "prod"); + out.shouldContain(", sharing"); + out.shouldContain("Opened archive hello.aot."); + out.shouldContain("Hello World"); + out.shouldHaveExitValue(0); + + // (5) AOTMode=on + pb = ProcessTools.createLimitedTestJavaProcessBuilder( + "-XX:AOTCache=" + aotCacheFile, + "--show-version", + "-Xlog:cds", + "-XX:AOTMode=on", + "-cp", appJar, helloClass); + out = CDSTestUtils.executeAndLog(pb, "prod"); + out.shouldContain(", sharing"); + out.shouldContain("Opened archive hello.aot."); + out.shouldContain("Hello World"); + out.shouldHaveExitValue(0); + } + + static void negativeTests() throws Exception { + // (1) Mixing old and new options + String mixOldNewErrSuffix = " cannot be used at the same time with -Xshare:on, -Xshare:auto, " + + "-Xshare:off, -Xshare:dump, DumpLoadedClassList, SharedClassListFile, " + + "or SharedArchiveFile"; + + ProcessBuilder pb = ProcessTools.createLimitedTestJavaProcessBuilder( + "-Xshare:off", + "-XX:AOTConfiguration=" + aotConfigFile, + "-cp", appJar, helloClass); + + OutputAnalyzer out = CDSTestUtils.executeAndLog(pb, "neg"); + out.shouldContain("Option AOTConfiguration" + mixOldNewErrSuffix); + out.shouldNotHaveExitValue(0); + + pb = ProcessTools.createLimitedTestJavaProcessBuilder( + "-XX:SharedArchiveFile=" + aotCacheFile, + "-XX:AOTCache=" + aotCacheFile, + "-cp", appJar, helloClass); + out = CDSTestUtils.executeAndLog(pb, "neg"); + out.shouldContain("Option AOTCache" + mixOldNewErrSuffix); + out.shouldNotHaveExitValue(0); + + // (2) Use AOTConfiguration without AOTMode + pb = ProcessTools.createLimitedTestJavaProcessBuilder( + "-XX:AOTConfiguration=" + aotConfigFile, + "-cp", appJar, helloClass); + + out = CDSTestUtils.executeAndLog(pb, "neg"); + out.shouldContain("AOTConfiguration can only be used with -XX:AOTMode=record or -XX:AOTMode=create"); + out.shouldNotHaveExitValue(0); + + // (3) Use AOTMode without AOTConfiguration + pb = ProcessTools.createLimitedTestJavaProcessBuilder( + "-XX:AOTMode=record", + "-cp", appJar, helloClass); + + out = CDSTestUtils.executeAndLog(pb, "neg"); + out.shouldContain("-XX:AOTMode=record cannot be used without setting AOTConfiguration"); + + pb = ProcessTools.createLimitedTestJavaProcessBuilder( + "-XX:AOTMode=create", + "-cp", appJar, helloClass); + + out = CDSTestUtils.executeAndLog(pb, "neg"); + out.shouldContain("-XX:AOTMode=create cannot be used without setting AOTConfiguration"); + out.shouldNotHaveExitValue(0); + + // (4) Bad AOTMode + pb = ProcessTools.createLimitedTestJavaProcessBuilder( + "-XX:AOTMode=foo", + "-cp", appJar, helloClass); + + out = CDSTestUtils.executeAndLog(pb, "neg"); + out.shouldContain("Unrecognized value foo for AOTMode. Must be one of the following: off, record, create, auto, on"); + out.shouldNotHaveExitValue(0); + + // (5) AOTCache specified with -XX:AOTMode=record + pb = ProcessTools.createLimitedTestJavaProcessBuilder( + "-XX:AOTMode=record", + "-XX:AOTConfiguration=" + aotConfigFile, + "-XX:AOTCache=" + aotCacheFile, + "-cp", appJar, helloClass); + + out = CDSTestUtils.executeAndLog(pb, "neg"); + out.shouldContain("AOTCache must not be specified when using -XX:AOTMode=record"); + out.shouldNotHaveExitValue(0); + + // (5) AOTCache not specified with -XX:AOTMode=create + pb = ProcessTools.createLimitedTestJavaProcessBuilder( + "-XX:AOTMode=create", + "-XX:AOTConfiguration=" + aotConfigFile, + "-cp", appJar, helloClass); + + out = CDSTestUtils.executeAndLog(pb, "neg"); + out.shouldContain("AOTCache must be specified when using -XX:AOTMode=create"); + out.shouldNotHaveExitValue(0); + + } +} diff --git a/test/hotspot/jtreg/runtime/cds/appcds/ClassPathAttr.java b/test/hotspot/jtreg/runtime/cds/appcds/ClassPathAttr.java index fe618256f65..df47e6bebc8 100644 --- a/test/hotspot/jtreg/runtime/cds/appcds/ClassPathAttr.java +++ b/test/hotspot/jtreg/runtime/cds/appcds/ClassPathAttr.java @@ -190,13 +190,20 @@ static void testNonExistentJars() throws Exception { Files.copy(Paths.get(cp), Paths.get(nonExistPath), StandardCopyOption.REPLACE_EXISTING); - TestCommon.run( + CDSTestUtils.Result result = TestCommon.run( "-Xlog:class+path", "-cp", cp, - "CpAttr6") - .assertNormalExit(output -> { - output.shouldMatch("Archived non-system classes are disabled because the file .*cpattrX.jar exists"); - }); + "CpAttr6"); + if (CDSTestUtils.isAOTClassLinkingEnabled()) { + result.assertAbnormalExit(output -> { + output.shouldMatch("CDS archive has aot-linked classes. It cannot be used because the file .*cpattrX.jar exists"); + }); + + } else { + result.assertNormalExit(output -> { + output.shouldMatch("Archived non-system classes are disabled because the file .*cpattrX.jar exists"); + }); + } } static void testClassPathAttrJarOnCP() throws Exception { diff --git a/test/hotspot/jtreg/runtime/cds/appcds/LambdaContainsOldInf.java b/test/hotspot/jtreg/runtime/cds/appcds/LambdaContainsOldInf.java index 8dec80b9f58..6d1b23628c5 100644 --- a/test/hotspot/jtreg/runtime/cds/appcds/LambdaContainsOldInf.java +++ b/test/hotspot/jtreg/runtime/cds/appcds/LambdaContainsOldInf.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -64,7 +64,11 @@ public static void main(String[] args) throws Exception { OutputAnalyzer output = CDSTestUtils.createArchiveAndCheck(opts); TestCommon.checkExecReturn(output, 0, true, "Skipping OldProvider: Old class has been linked"); - output.shouldMatch("Skipping.LambdaContainsOldInfApp[$][$]Lambda.*0x.*:.*Old.class.has.been.linked"); + if (CDSTestUtils.isAOTClassLinkingEnabled()) { + output.shouldMatch("Cannot aot-resolve Lambda proxy because OldProvider is excluded"); + } else { + output.shouldMatch("Skipping.LambdaContainsOldInfApp[$][$]Lambda.*0x.*:.*Old.class.has.been.linked"); + } // run with archive CDSOptions runOpts = (new CDSOptions()) diff --git a/test/hotspot/jtreg/runtime/cds/appcds/LambdaWithOldClass.java b/test/hotspot/jtreg/runtime/cds/appcds/LambdaWithOldClass.java index 3a0bb740387..d7ce22e3cf1 100644 --- a/test/hotspot/jtreg/runtime/cds/appcds/LambdaWithOldClass.java +++ b/test/hotspot/jtreg/runtime/cds/appcds/LambdaWithOldClass.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -68,7 +68,11 @@ public static void main(String[] args) throws Exception { .addSuffix(mainClass); OutputAnalyzer output = CDSTestUtils.runWithArchive(runOpts); output.shouldContain("[class,load] LambdaWithOldClassApp source: shared objects file") - .shouldMatch(".class.load. LambdaWithOldClassApp[$][$]Lambda.*/0x.*source:.*shared objects file") .shouldHaveExitValue(0); + if (!CDSTestUtils.isAOTClassLinkingEnabled()) { + // With AOTClassLinking, we don't archive any lambda with old classes in the method + // signatures. + output.shouldMatch(".class.load. LambdaWithOldClassApp[$][$]Lambda.*/0x.*source:.*shared objects file"); + } } } diff --git a/test/hotspot/jtreg/runtime/cds/appcds/LambdaWithUseImplMethodHandle.java b/test/hotspot/jtreg/runtime/cds/appcds/LambdaWithUseImplMethodHandle.java index 513ec57d279..360fce5879a 100644 --- a/test/hotspot/jtreg/runtime/cds/appcds/LambdaWithUseImplMethodHandle.java +++ b/test/hotspot/jtreg/runtime/cds/appcds/LambdaWithUseImplMethodHandle.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -43,6 +43,11 @@ public class LambdaWithUseImplMethodHandle { // See pkg2/Child.jcod for details about the condition that triggers JDK-8290417 public static void main(String[] args) throws Exception { + test(false); + test(true); + } + + static void test(boolean aotClassLinking) throws Exception { String appJar = ClassFileInstaller.getJarPath("test.jar"); String mainClass = "LambdaWithUseImplMethodHandleApp"; String expectedMsg = "Called BaseWithProtectedMethod::protectedMethod"; @@ -57,6 +62,9 @@ public static void main(String[] args) throws Exception { .addPrefix("-XX:ExtraSharedClassListFile=" + classList, "-cp", appJar) .setArchiveName(archiveName); + if (aotClassLinking) { + opts.addPrefix("-XX:+AOTClassLinking"); + } CDSTestUtils.createArchiveAndCheck(opts); // run with archive diff --git a/test/hotspot/jtreg/runtime/cds/appcds/TestParallelGCWithCDS.java b/test/hotspot/jtreg/runtime/cds/appcds/TestParallelGCWithCDS.java index 705df07f841..781e0276b27 100644 --- a/test/hotspot/jtreg/runtime/cds/appcds/TestParallelGCWithCDS.java +++ b/test/hotspot/jtreg/runtime/cds/appcds/TestParallelGCWithCDS.java @@ -148,6 +148,7 @@ static void test(boolean dumpWithParallel, boolean execWithParallel, boolean use } else { String pattern = "((Too small maximum heap)" + "|(GC triggered before VM initialization completed)" + + "|(CDS archive has aot-linked classes but the archived heap objects cannot be loaded)" + "|(Initial heap size set to a larger value than the maximum heap size)" + "|(java.lang.OutOfMemoryError)" + "|(Error: A JNI error has occurred, please check your installation and try again))"; diff --git a/test/hotspot/jtreg/runtime/cds/appcds/aotClassLinking/AOTClassLinkingVMOptions.java b/test/hotspot/jtreg/runtime/cds/appcds/aotClassLinking/AOTClassLinkingVMOptions.java new file mode 100644 index 00000000000..05fdf7c06d6 --- /dev/null +++ b/test/hotspot/jtreg/runtime/cds/appcds/aotClassLinking/AOTClassLinkingVMOptions.java @@ -0,0 +1,183 @@ +/* + * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +/* + * @test + * @requires vm.cds + * @requires vm.cds.supports.aot.class.linking + * @requires vm.flagless + * @summary Disable CDS when incompatible options related to AOTClassLinking are used + * @library /test/jdk/lib/testlibrary + * /test/lib + * /test/hotspot/jtreg/runtime/cds/appcds + * /test/hotspot/jtreg/runtime/cds/appcds/test-classes + * @build Hello + * @run driver jdk.test.lib.helpers.ClassFileInstaller -jar app.jar Hello + * @run driver AOTClassLinkingVMOptions + */ + +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import jdk.test.lib.cds.CDSTestUtils; +import jdk.test.lib.helpers.ClassFileInstaller; +import jdk.test.lib.process.OutputAnalyzer; +import jdk.test.lib.process.ProcessTools; + +public class AOTClassLinkingVMOptions { + static final String appJar = ClassFileInstaller.getJarPath("app.jar"); + + static int testCaseNum = 0; + static void testCase(String s) { + testCaseNum++; + System.out.println("Test case " + testCaseNum + ": " + s); + } + + public static void main(String[] args) throws Exception { + TestCommon.testDump(appJar, TestCommon.list("Hello"), + "-XX:+AOTClassLinking"); + + testCase("Archived full module graph must be enabled at runtime"); + TestCommon.run("-cp", appJar, "-Djdk.module.validation=1", "Hello") + .assertAbnormalExit("CDS archive has aot-linked classes." + + " It cannot be used when archived full module graph is not used"); + + testCase("Cannot use -Djava.system.class.loader"); + TestCommon.run("-cp", appJar, "-Djava.system.class.loader=dummy", "Hello") + .assertAbnormalExit("CDS archive has aot-linked classes." + + " It cannot be used when the java.system.class.loader property is specified."); + + testCase("Cannot use a different main module"); + TestCommon.run("-cp", appJar, "-Xlog:cds", "-m", "jdk.compiler/com.sun.tools.javac.Main") + .assertAbnormalExit("CDS archive has aot-linked classes." + + " It cannot be used when archived full module graph is not used."); + testCase("Cannot use security manager"); + TestCommon.run("-cp", appJar, "-Xlog:cds", "-Djava.security.manager=allow") + .assertAbnormalExit("CDS archive has aot-linked classes." + + " It cannot be used with -Djava.security.manager=allow."); + TestCommon.run("-cp", appJar, "-Xlog:cds", "-Djava.security.manager=default") + .assertAbnormalExit("CDS archive has aot-linked classes." + + " It cannot be used with -Djava.security.manager=default."); + + // NOTE: tests for ClassFileLoadHook + AOTClassLinking is in + // ../jvmti/ClassFileLoadHookTest.java + + boolean dynamicMode = Boolean.getBoolean("test.dynamic.cds.archive"); + if (!dynamicMode) { + // These tests need to dump the full module graph, which is not possible with + // dynamic dump. + modulePathTests(); + } + } + + static void modulePathTests() throws Exception { + CDSModulePathUtils.init(); + + testCase("Cannot use mis-matched module path"); + String goodModulePath = CDSModulePathUtils.getModulesDir().toString(); + TestCommon.testDump(null, CDSModulePathUtils.getAppClasses(), + "--module-path", goodModulePath, + "-XX:+AOTClassLinking", + "-m", CDSModulePathUtils.MAIN_MODULE); + TestCommon.run("-Xlog:cds", + "--module-path", goodModulePath, + "-m", CDSModulePathUtils.MAIN_MODULE) + .assertNormalExit("Using AOT-linked classes: true"); + + TestCommon.run("-Xlog:cds", + "--module-path", goodModulePath + "/bad", + "-m", CDSModulePathUtils.MAIN_MODULE) + .assertAbnormalExit("CDS archive has aot-linked classes. It cannot be used when archived full module graph is not used."); + + testCase("Cannot use mis-matched --add-modules"); + TestCommon.testDump(null, CDSModulePathUtils.getAppClasses(), + "--module-path", goodModulePath, + "-XX:+AOTClassLinking", + "--add-modules", CDSModulePathUtils.MAIN_MODULE); + TestCommon.run("-Xlog:cds", + "--module-path", goodModulePath, + "--add-modules", CDSModulePathUtils.MAIN_MODULE, + CDSModulePathUtils.MAIN_CLASS) + .assertNormalExit("Using AOT-linked classes: true"); + + TestCommon.run("-Xlog:cds", + "--module-path", goodModulePath + "/bad", + "--add-modules", CDSModulePathUtils.TEST_MODULE, + CDSModulePathUtils.MAIN_CLASS) + .assertAbnormalExit("Mismatched --add-modules module name(s)", + "CDS archive has aot-linked classes. It cannot be used when archived full module graph is not used."); + } +} + +// TODO: enhance and move this class to jdk.test.lib.cds.CDSModulePathUtils + +class CDSModulePathUtils { + private static String TEST_SRC = System.getProperty("test.root"); + private static Path USER_DIR = Paths.get(CDSTestUtils.getOutputDir()); + private static Path SRC_DIR = Paths.get(TEST_SRC, "runtime/cds/appcds/jigsaw/modulepath/src"); + private static Path MODS_DIR = Paths.get("mods"); + + public static String MAIN_MODULE = "com.bars"; + public static String TEST_MODULE = "com.foos"; + + public static String MAIN_CLASS = "com.bars.Main"; + public static String TEST_CLASS = "com.foos.Test"; + private static String appClasses[] = {MAIN_CLASS, TEST_CLASS}; + + private static Path modulesDir; + + // This directory contains all the modular jar files + // $USER_DIR/modules/com.bars.jar + // $USER_DIR/modules/com.foos.jar + static Path getModulesDir() { + return modulesDir; + } + + static String[] getAppClasses() { + return appClasses; + } + + static void init() throws Exception { + JarBuilder.compileModule(SRC_DIR.resolve(TEST_MODULE), + MODS_DIR.resolve(TEST_MODULE), + null); + JarBuilder.compileModule(SRC_DIR.resolve(MAIN_MODULE), + MODS_DIR.resolve(MAIN_MODULE), + MODS_DIR.toString()); + + String PATH_LIBS = "modules"; + modulesDir = Files.createTempDirectory(USER_DIR, PATH_LIBS); + Path mainJar = modulesDir.resolve(MAIN_MODULE + ".jar"); + Path testJar = modulesDir.resolve(TEST_MODULE + ".jar"); + + // modylibs contains both modules com.foos.jar, com.bars.jar + // build com.foos.jar + String classes = MODS_DIR.resolve(TEST_MODULE).toString(); + JarBuilder.createModularJar(testJar.toString(), classes, TEST_CLASS); + + // build com.bars.jar + classes = MODS_DIR.resolve(MAIN_MODULE).toString(); + JarBuilder.createModularJar(mainJar.toString(), classes, MAIN_CLASS); + } +} diff --git a/test/hotspot/jtreg/runtime/cds/appcds/aotClassLinking/BulkLoaderTest.java b/test/hotspot/jtreg/runtime/cds/appcds/aotClassLinking/BulkLoaderTest.java new file mode 100644 index 00000000000..49544f50032 --- /dev/null +++ b/test/hotspot/jtreg/runtime/cds/appcds/aotClassLinking/BulkLoaderTest.java @@ -0,0 +1,241 @@ +/* + * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +// AOT-linked classes are loaded during VM bootstrap by the C++ class AOTLinkedClassBulkLoader. +// Make sure that the Module, Package, CodeSource and ProtectionDomain of these classes are +// set up properly. + +/* + * @test id=static + * @requires vm.cds.supports.aot.class.linking + * @library /test/jdk/lib/testlibrary /test/lib + * @build InitiatingLoaderTester + * @build BulkLoaderTest + * @run driver jdk.test.lib.helpers.ClassFileInstaller -jar BulkLoaderTestApp.jar BulkLoaderTestApp MyUtil InitiatingLoaderTester + * @run driver BulkLoaderTest STATIC + */ + +/* + * @test id=dynamic + * @requires vm.cds.supports.aot.class.linking + * @library /test/jdk/lib/testlibrary /test/lib + * @build InitiatingLoaderTester + * @build BulkLoaderTest + * @run driver jdk.test.lib.helpers.ClassFileInstaller -jar BulkLoaderTestApp.jar BulkLoaderTestApp MyUtil InitiatingLoaderTester + * @run driver BulkLoaderTest DYNAMIC + */ + +import java.io.File; +import java.lang.StackWalker.StackFrame; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import java.util.stream.Collectors; +import java.util.Set; +import jdk.test.lib.cds.CDSAppTester; +import jdk.test.lib.helpers.ClassFileInstaller; +import jdk.test.lib.process.OutputAnalyzer; + +public class BulkLoaderTest { + static final String appJar = ClassFileInstaller.getJarPath("BulkLoaderTestApp.jar"); + static final String mainClass = "BulkLoaderTestApp"; + + public static void main(String[] args) throws Exception { + Tester t = new Tester(); + + // Run with archived FMG loaded + t.run(args); + + // Run with an extra classpath -- archived FMG can still load. + { + String extraVmArgs[] = { + "-cp", + appJar + File.pathSeparator + "foobar.jar" + }; + OutputAnalyzer out = t.productionRun(extraVmArgs); + out.shouldHaveExitValue(0); + } + + // Run without archived FMG -- fail to load + { + String extraVmArgs[] = { + "-Xshare:on", + "-Xlog:cds", + "-Djdk.module.showModuleResolution=true" + }; + t.setCheckExitValue(false); + OutputAnalyzer out = t.productionRun(extraVmArgs); + out.shouldHaveExitValue(1); + out.shouldContain("CDS archive has aot-linked classes. It cannot be used when archived full module graph is not used."); + t.setCheckExitValue(true); + } + } + + static class Tester extends CDSAppTester { + public Tester() { + super(mainClass); + } + + @Override + public String classpath(RunMode runMode) { + return appJar; + } + + @Override + public String[] vmArgs(RunMode runMode) { + return new String[] { + "-Xlog:cds,cds+aot+load", + "-XX:+AOTClassLinking", + }; + } + + @Override + public String[] appCommandLine(RunMode runMode) { + return new String[] { + mainClass, + }; + } + } +} + +class BulkLoaderTestApp { + static String allPerms = "null.*.*java.security.Permissions.*,*java.security.AllPermission.*.*"; + + public static void main(String args[]) throws Exception { + checkClasses(); + checkInitiatingLoader(); + } + + // Check the ClassLoader/Module/Package/ProtectionDomain/CodeSource of classes that are aot-linked + static void checkClasses() throws Exception { + check(String.class, + "null", // loader + "module java.base", + "package java.lang", + "null", + allPerms); + + check(Class.forName("sun.util.logging.internal.LoggingProviderImpl"), + "null", + "module java.logging", + "package sun.util.logging.internal", + "null", + allPerms); + + + check(javax.tools.FileObject.class, + "^jdk.internal.loader.ClassLoaders[$]PlatformClassLoader@", + "module java.compiler", + "package javax.tools", + "jrt:/java.compiler ", + "jdk.internal.loader.ClassLoaders[$]PlatformClassLoader.*.*java.security.Permissions"); + + check(BulkLoaderTestApp.class, + "jdk.internal.loader.ClassLoaders[$]AppClassLoader@", + "^unnamed module @", + "package ", + "file:.*BulkLoaderTestApp.jar ", + "jdk.internal.loader.ClassLoaders[$]AppClassLoader.*.*java.security.Permissions"); + + check(Class.forName("com.sun.tools.javac.Main"), + "jdk.internal.loader.ClassLoaders[$]AppClassLoader@", + "module jdk.compiler", + "package com.sun.tools.javac", + "jrt:/jdk.compiler ", + "jdk.internal.loader.ClassLoaders[$]AppClassLoader.*.*java.security.Permissions"); + + doit(() -> { + Class lambdaClass = MyUtil.getCallerClass(1); + check(lambdaClass, + "jdk.internal.loader.ClassLoaders[$]AppClassLoader@", + "unnamed module", + "package ", + "file:.*BulkLoaderTestApp.jar ", + "jdk.internal.loader.ClassLoaders[$]AppClassLoader.*.*java.security.Permissions"); + + }); + } + + static void check(Class c, String loader, String module, String pkg, String codeSource, String protectionDomain) { + System.out.println("===================================================================="); + System.out.println(c.getName() + ", loader = " + c.getClassLoader()); + System.out.println(c.getName() + ", module = " + c.getModule()); + System.out.println(c.getName() + ", package = " + c.getPackage()); + System.out.println(c.getName() + ", CS = " + c.getProtectionDomain().getCodeSource()); + System.out.println(c.getName() + ", PD = " + c.getProtectionDomain()); + + expectMatch("" + c.getClassLoader(), loader); + expectMatch("" + c.getModule(), module); + expectSame("" + c.getPackage(), pkg); + expectMatch("" + c.getProtectionDomain().getCodeSource(), codeSource); + expectMatch("" + c.getProtectionDomain(), protectionDomain); + } + + static void expectSame(String a, String b) { + if (!a.equals(b)) { + throw new RuntimeException("Expected \"" + b + "\" but got \"" + a + "\""); + } + } + static void expectMatch(String string, String pattern) { + Matcher matcher = Pattern.compile(pattern, Pattern.DOTALL).matcher(string); + if (!matcher.find()) { + throw new RuntimeException("Expected pattern \"" + pattern + "\" but got \"" + string + "\""); + } + } + + static void doit(Runnable t) { + t.run(); + } + + static void checkInitiatingLoader() throws Exception { + try { + InitiatingLoaderTester.tryAccess(); + } catch (IllegalAccessError t) { + if (t.getMessage().contains("cannot access class jdk.internal.misc.Unsafe (in module java.base)")) { + System.out.println("Expected exception:"); + t.printStackTrace(System.out); + // Class.forName() should still work. We just can't resolve it in CP entries. + Class c = Class.forName("jdk.internal.misc.Unsafe"); + System.out.println("App loader can still resolve by name: " + c); + return; + } + throw new RuntimeException("Unexpected exception", t); + } + + throw new RuntimeException("Should not have succeeded"); + } +} + +class MyUtil { + // depth is 0-based -- i.e., depth==0 returns the class of the immediate caller of getCallerClass + static Class getCallerClass(int depth) { + // Need to add the frame of the getCallerClass -- so the immediate caller (depth==0) of this method + // is at stack.get(1) == stack.get(depth+1); + StackWalker walker = StackWalker.getInstance( + Set.of(StackWalker.Option.RETAIN_CLASS_REFERENCE, + StackWalker.Option.SHOW_HIDDEN_FRAMES)); + List stack = walker.walk(s -> s.limit(depth+2).collect(Collectors.toList())); + return stack.get(depth+1).getDeclaringClass(); + } +} diff --git a/test/hotspot/jtreg/runtime/cds/appcds/aotClassLinking/InitiatingLoaderTester.jasm b/test/hotspot/jtreg/runtime/cds/appcds/aotClassLinking/InitiatingLoaderTester.jasm new file mode 100644 index 00000000000..ae1b38e20a9 --- /dev/null +++ b/test/hotspot/jtreg/runtime/cds/appcds/aotClassLinking/InitiatingLoaderTester.jasm @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +/* + + +class InitiatingLoaderTester { + public static Object tryAccess() { + return jdk.internal.misc.Unsafe.getUnsafe(); + } +} + + + +*/ + + +super class InitiatingLoaderTester + version 66:0 +{ + Method "":"()V" + stack 1 locals 1 + { + aload_0; + invokespecial Method java/lang/Object."":"()V"; + return; + } + public static Method tryAccess:"()Ljava/lang/Object;" + stack 2 locals 0 + { + invokestatic Method jdk/internal/misc/Unsafe."getUnsafe":"()Ljdk/internal/misc/Unsafe;"; + areturn; + } + +} // end Class InitiatingLoaderTester diff --git a/test/hotspot/jtreg/runtime/cds/appcds/cacheObject/ArchiveHeapTestClass.java b/test/hotspot/jtreg/runtime/cds/appcds/cacheObject/ArchiveHeapTestClass.java index f5975569447..1603d8430b2 100644 --- a/test/hotspot/jtreg/runtime/cds/appcds/cacheObject/ArchiveHeapTestClass.java +++ b/test/hotspot/jtreg/runtime/cds/appcds/cacheObject/ArchiveHeapTestClass.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -27,7 +27,7 @@ * @bug 8214781 8293187 * @summary Test for the -XX:ArchiveHeapTestClass flag * @requires vm.debug == true & vm.cds.write.archived.java.heap - * @modules java.base/sun.invoke.util java.logging + * @modules java.logging * @library /test/jdk/lib/testlibrary /test/lib * /test/hotspot/jtreg/runtime/cds/appcds * /test/hotspot/jtreg/runtime/cds/appcds/test-classes @@ -35,12 +35,13 @@ * @run driver jdk.test.lib.helpers.ClassFileInstaller -jar boot.jar * CDSTestClassA CDSTestClassA$XX CDSTestClassA$YY * CDSTestClassB CDSTestClassC CDSTestClassD - * CDSTestClassE CDSTestClassF CDSTestClassG + * CDSTestClassE CDSTestClassF CDSTestClassG CDSTestClassG$MyEnum CDSTestClassG$Wrapper * pkg.ClassInPackage * @run driver jdk.test.lib.helpers.ClassFileInstaller -jar app.jar Hello * @run driver ArchiveHeapTestClass */ +import jdk.test.lib.cds.CDSTestUtils; import jdk.test.lib.Platform; import jdk.test.lib.helpers.ClassFileInstaller; import jdk.test.lib.process.OutputAnalyzer; @@ -151,19 +152,24 @@ static void testDebugBuild() throws Exception { output = dumpBootAndHello(CDSTestClassD_name); mustFail(output, "Unable to find the static T_OBJECT field CDSTestClassD::archivedObjects"); - testCase("Use a disallowed class: in unnamed module but not in unname package"); - output = dumpBootAndHello(CDSTestClassE_name); - mustFail(output, "Class pkg.ClassInPackage not allowed in archive heap"); + if (!CDSTestUtils.isAOTClassLinkingEnabled()) { + testCase("Use a disallowed class: in unnamed module but not in unname package"); + output = dumpBootAndHello(CDSTestClassE_name); + mustFail(output, "Class pkg.ClassInPackage not allowed in archive heap"); - testCase("Use a disallowed class: not in java.base module"); - output = dumpBootAndHello(CDSTestClassF_name); - mustFail(output, "Class java.util.logging.Level not allowed in archive heap"); - - if (false) { // JDK-8293187 - testCase("sun.invoke.util.Wrapper"); - output = dumpBootAndHello(CDSTestClassG_name); - mustSucceed(output); + testCase("Use a disallowed class: not in java.base module"); + output = dumpBootAndHello(CDSTestClassF_name); + mustFail(output, "Class java.util.logging.Level not allowed in archive heap"); } + + testCase("Complex enums"); + output = dumpBootAndHello(CDSTestClassG_name, "-XX:+AOTClassLinking", "-Xlog:cds+class=debug"); + mustSucceed(output); + + TestCommon.run("-Xbootclasspath/a:" + bootJar, "-cp", appJar, "-Xlog:cds+heap,cds+init", + CDSTestClassG_name) + .assertNormalExit("init subgraph " + CDSTestClassG_name, + "Initialized from CDS"); } } @@ -171,12 +177,27 @@ class CDSTestClassA { static final String output = "CDSTestClassA. was executed"; static Object[] archivedObjects; static { - archivedObjects = new Object[5]; - archivedObjects[0] = output; - archivedObjects[1] = new CDSTestClassA[0]; - archivedObjects[2] = new YY(); - archivedObjects[3] = new int[0]; - archivedObjects[4] = new int[2][2]; + // The usual convention would be to call this here: + // CDS.initializeFromArchive(CDSTestClassA.class); + // However, the CDS class is not exported to the unnamed module by default, + // and we don't want to use "--add-exports java.base/jdk.internal.misc=ALL-UNNAMED", as + // that would disable the archived full module graph, which will disable + // CDSConfig::is_using_aot_linked_classes(). + // + // Instead, HeapShared::initialize_test_class_from_archive() will set up the + // "archivedObjects" field first, before calling CDSTestClassA.. So + // if we see that archivedObjects is magically non-null here, that means + // it has been restored from the CDS archive. + if (archivedObjects == null) { + archivedObjects = new Object[5]; + archivedObjects[0] = output; + archivedObjects[1] = new CDSTestClassA[0]; + archivedObjects[2] = new YY(); + archivedObjects[3] = new int[0]; + archivedObjects[4] = new int[2][2]; + } else { + System.out.println("Initialized from CDS"); + } System.out.println(output); System.out.println("CDSTestClassA module = " + CDSTestClassA.class.getModule()); System.out.println("CDSTestClassA package = " + CDSTestClassA.class.getPackage()); @@ -269,8 +290,143 @@ class CDSTestClassF { class CDSTestClassG { static Object[] archivedObjects; static { - // Not in java.base - archivedObjects = new Object[1]; - archivedObjects[0] = sun.invoke.util.Wrapper.BOOLEAN; + if (archivedObjects == null) { + archivedObjects = new Object[13]; + archivedObjects[0] = Wrapper.BOOLEAN; + archivedObjects[1] = Wrapper.INT.zero(); + archivedObjects[2] = Wrapper.DOUBLE.zero(); + archivedObjects[3] = MyEnum.DUMMY1; + + archivedObjects[4] = Boolean.class; + archivedObjects[5] = Byte.class; + archivedObjects[6] = Character.class; + archivedObjects[7] = Short.class; + archivedObjects[8] = Integer.class; + archivedObjects[9] = Long.class; + archivedObjects[10] = Float.class; + archivedObjects[11] = Double.class; + archivedObjects[12] = Void.class; + } else { + System.out.println("Initialized from CDS"); + } + } + + public static void main(String args[]) { + if (archivedObjects[0] != Wrapper.BOOLEAN) { + throw new RuntimeException("Huh 0"); + } + + if (archivedObjects[1] != Wrapper.INT.zero()) { + throw new RuntimeException("Huh 1"); + } + + if (archivedObjects[2] != Wrapper.DOUBLE.zero()) { + throw new RuntimeException("Huh 2"); + } + + if (archivedObjects[3] != MyEnum.DUMMY1) { + throw new RuntimeException("Huh 3"); + } + + if (MyEnum.BOOLEAN != true) { + throw new RuntimeException("Huh 10.1"); + } + if (MyEnum.BYTE != -128) { + throw new RuntimeException("Huh 10.2"); + } + if (MyEnum.CHAR != 'c') { + throw new RuntimeException("Huh 10.3"); + } + if (MyEnum.SHORT != -12345) { + throw new RuntimeException("Huh 10.4"); + } + if (MyEnum.INT != -123456) { + throw new RuntimeException("Huh 10.5"); + } + if (MyEnum.LONG != 0x1234567890L) { + throw new RuntimeException("Huh 10.6"); + } + if (MyEnum.LONG2 != -0x1234567890L) { + throw new RuntimeException("Huh 10.7"); + } + if (MyEnum.FLOAT != 567891.0f) { + throw new RuntimeException("Huh 10.8"); + } + if (MyEnum.DOUBLE != 12345678905678.890) { + throw new RuntimeException("Huh 10.9"); + } + + checkClass(4, Boolean.class); + checkClass(5, Byte.class); + checkClass(6, Character.class); + checkClass(7, Short.class); + checkClass(8, Integer.class); + checkClass(9, Long.class); + checkClass(10, Float.class); + checkClass(11, Double.class); + checkClass(12, Void.class); + + System.out.println("Success!"); + } + + static void checkClass(int index, Class c) { + if (archivedObjects[index] != c) { + throw new RuntimeException("archivedObjects[" + index + "] should be " + c); + } + } + + // Simplified version of sun.invoke.util.Wrapper + public enum Wrapper { + // wrapperType simple primitiveType simple char emptyArray + BOOLEAN( Boolean.class, "Boolean", boolean.class, "boolean", 'Z', new boolean[0]), + INT ( Integer.class, "Integer", int.class, "int", 'I', new int[0]), + DOUBLE ( Double.class, "Double", double.class, "double", 'D', new double[0]) + ; + + public static final int COUNT = 10; + private static final Object DOUBLE_ZERO = (Double)(double)0; + + private final Class wrapperType; + private final Class primitiveType; + private final char basicTypeChar; + private final String basicTypeString; + private final Object emptyArray; + + Wrapper(Class wtype, + String wtypeName, + Class ptype, + String ptypeName, + char tchar, + Object emptyArray) { + this.wrapperType = wtype; + this.primitiveType = ptype; + this.basicTypeChar = tchar; + this.basicTypeString = String.valueOf(this.basicTypeChar); + this.emptyArray = emptyArray; + } + + public Object zero() { + return switch (this) { + case BOOLEAN -> Boolean.FALSE; + case INT -> (Integer)0; + case DOUBLE -> DOUBLE_ZERO; + default -> null; + }; + } + } + + enum MyEnum { + DUMMY1, + DUMMY2; + + static final boolean BOOLEAN = true; + static final byte BYTE = -128; + static final short SHORT = -12345; + static final char CHAR = 'c'; + static final int INT = -123456; + static final long LONG = 0x1234567890L; + static final long LONG2 = -0x1234567890L; + static final float FLOAT = 567891.0f; + static final double DOUBLE = 12345678905678.890; } } diff --git a/test/hotspot/jtreg/runtime/cds/appcds/customLoader/CustomClassListDump.java b/test/hotspot/jtreg/runtime/cds/appcds/customLoader/CustomClassListDump.java index 625ef1fbc92..27072bea35e 100644 --- a/test/hotspot/jtreg/runtime/cds/appcds/customLoader/CustomClassListDump.java +++ b/test/hotspot/jtreg/runtime/cds/appcds/customLoader/CustomClassListDump.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -94,7 +94,7 @@ public static void main(String[] args) throws Exception { .shouldContain("unreg CustomLoadee") .shouldContain("unreg CustomLoadee2") .shouldContain("unreg CustomLoadee3Child") - .shouldContain("unreg OldClass ** unlinked"); + .shouldContain("unreg OldClass old unlinked"); // Use the dumped static archive opts = (new CDSOptions()) diff --git a/test/hotspot/jtreg/runtime/cds/appcds/jvmti/ClassFileLoadHookTest.java b/test/hotspot/jtreg/runtime/cds/appcds/jvmti/ClassFileLoadHookTest.java index 5751f62e148..7ccd4e5d312 100644 --- a/test/hotspot/jtreg/runtime/cds/appcds/jvmti/ClassFileLoadHookTest.java +++ b/test/hotspot/jtreg/runtime/cds/appcds/jvmti/ClassFileLoadHookTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -96,5 +96,23 @@ public static void main(String[] args) throws Exception { "ClassFileLoadHook", "" + ClassFileLoadHook.TestCaseId.SHARING_ON_CFLH_ON); TestCommon.checkExec(out); + + // JEP 483: if dumped with -XX:+AOTClassLinking, cannot use archive when CFLH is enabled + TestCommon.testDump(appJar, sharedClasses, useWb, "-XX:+AOTClassLinking"); + out = TestCommon.exec(appJar, + "-XX:+UnlockDiagnosticVMOptions", + "-XX:+WhiteBoxAPI", useWb, + "-agentlib:SimpleClassFileLoadHook=LoadMe,beforeHook,after_Hook", + "-Xlog:cds", + "ClassFileLoadHook", + "" + ClassFileLoadHook.TestCaseId.SHARING_ON_CFLH_ON); + if (out.contains("Using AOT-linked classes: false (static archive: no aot-linked classes")) { + // JTREG is executed with VM options that do not support -XX:+AOTClassLinking, so + // the static archive was not created with aot-linked classes. + out.shouldHaveExitValue(0); + } else { + out.shouldContain("CDS archive has aot-linked classes. It cannot be used when JVMTI ClassFileLoadHook is in use."); + out.shouldNotHaveExitValue(0); + } } } diff --git a/test/hotspot/jtreg/runtime/cds/appcds/jvmti/redefineClasses/OldClassAndRedefineClass.java b/test/hotspot/jtreg/runtime/cds/appcds/jvmti/redefineClasses/OldClassAndRedefineClass.java index 8ca8b7d952e..7581b2367aa 100644 --- a/test/hotspot/jtreg/runtime/cds/appcds/jvmti/redefineClasses/OldClassAndRedefineClass.java +++ b/test/hotspot/jtreg/runtime/cds/appcds/jvmti/redefineClasses/OldClassAndRedefineClass.java @@ -61,8 +61,8 @@ public static void runTest() throws Throwable { String agentCmdArg = "-javaagent:redefineagent.jar"; OutputAnalyzer out = TestCommon.testDump(appJar, sharedClasses, "-Xlog:cds,cds+class=debug"); - out.shouldMatch("klasses.*OldSuper.[*][*].unlinked") - .shouldMatch("klasses.*ChildOldSuper.[*][*].unlinked"); + out.shouldMatch("klasses.*OldSuper.* unlinked") + .shouldMatch("klasses.*ChildOldSuper.* unlinked"); out = TestCommon.exec( appJar, diff --git a/test/hotspot/jtreg/runtime/cds/appcds/resolvedConstants/AOTLinkedLambdas.java b/test/hotspot/jtreg/runtime/cds/appcds/resolvedConstants/AOTLinkedLambdas.java new file mode 100644 index 00000000000..5fb0a30cd61 --- /dev/null +++ b/test/hotspot/jtreg/runtime/cds/appcds/resolvedConstants/AOTLinkedLambdas.java @@ -0,0 +1,388 @@ +/* + * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +/* + * @test + * @summary AOT resolution of lambda expressions + * @bug 8340836 + * @requires vm.cds + * @requires vm.cds.supports.aot.class.linking + * @library /test/lib /test/hotspot/jtreg/runtime/cds/appcds/test-classes/ + * @build AOTLinkedLambdas + * @run driver jdk.test.lib.helpers.ClassFileInstaller -jar app.jar + * AOTLinkedLambdasApp InitTracker + * IntfWithNoClinit IntfWithNoClinit2 + * IA IB IC ID1 ID2 IE1 IE2 IF1 IF2 IG1 IG2 IH1 IH2 IH3 + * FooA FooB + * BarA BarB BarC + * @run driver AOTLinkedLambdas + */ + +import java.util.function.Supplier; +import static java.util.stream.Collectors.*; +import jdk.test.lib.cds.CDSOptions; +import jdk.test.lib.cds.CDSTestUtils; +import jdk.test.lib.helpers.ClassFileInstaller; +import jdk.test.lib.process.OutputAnalyzer; + +public class AOTLinkedLambdas { + static final String classList = "AOTLinkedLambdas.classlist"; + static final String appJar = ClassFileInstaller.getJarPath("app.jar"); + static final String mainClass = AOTLinkedLambdasApp.class.getName(); + + public static void main(String[] args) throws Exception { + CDSTestUtils.dumpClassList(classList, "-cp", appJar, mainClass) + .assertNormalExit(output -> { + output.shouldContain("Hello AOTLinkedLambdasApp"); + }); + + CDSOptions opts = (new CDSOptions()) + .addPrefix("-XX:ExtraSharedClassListFile=" + classList, + "-XX:+AOTClassLinking", + "-Xlog:cds+resolve=trace", + "-Xlog:cds+class=debug", + "-cp", appJar); + + OutputAnalyzer dumpOut = CDSTestUtils.createArchiveAndCheck(opts); + dumpOut.shouldContain("Can aot-resolve Lambda proxy of interface type IA"); + dumpOut.shouldContain("Can aot-resolve Lambda proxy of interface type IB"); + dumpOut.shouldContain("Cannot aot-resolve Lambda proxy of interface type IC"); + dumpOut.shouldContain("Can aot-resolve Lambda proxy of interface type ID2"); + dumpOut.shouldContain("Cannot aot-resolve Lambda proxy of interface type IE2"); // unsupported = IE1 + dumpOut.shouldContain("Cannot aot-resolve Lambda proxy of interface type IF2"); + dumpOut.shouldContain("Cannot aot-resolve Lambda proxy of interface type IG2"); + dumpOut.shouldContain("Cannot aot-resolve Lambda proxy of interface type IH3"); // unsupported = IH1 + + CDSOptions runOpts = (new CDSOptions()) + .setUseVersion(false) + .addPrefix("-Xlog:cds", + "-esa", // see JDK-8340836 + "-cp", appJar) + .addSuffix(mainClass); + + CDSTestUtils.run(runOpts) + .assertNormalExit("Hello AOTLinkedLambdasApp", + "hello, world"); + } +} + +class AOTLinkedLambdasApp { + static { + System.out.println("AOTLinkedLambdasApp."); + } + public static void main(String args[]) { + System.out.println("Hello AOTLinkedLambdasApp"); + + // (1) Simple tests + var words = java.util.List.of("hello", "fuzzy", "world"); + System.out.println(words.stream().filter(w->!w.contains("u")).collect(joining(", "))); + // => hello, world + + // (2) Test for order. + testClinitOrder(); + } + + + // Check that aot-linking of lambdas does not cause to be skipped or + // otherwise executed in the wrong order. + // + // A lambda is declared to implement an interface X, but it also implicitly + // implements all super interfaces of X. + // + // For any interface IN that's implemented by a lambda, if IN has declared + // a non-abstract, non-static method (JVMS 5.5. Initialization), IN must be + // initialized before the lambda can be linked. If IN:: exists, the + // initialization of IN can have side effects. + // + // AOTConstantPoolResolver::is_indy_resolution_deterministic() excludes + // any lambda if initializing its interfaces can cause side effects. This test + // checks that such exclusions are working as expected. + // + // This test also proves that is_indy_resolution_deterministic() doen't need to check + // for all other types that are mentioned by the lambda call site, as those classes + // will not be initialized as part of linking the lambda. + static void testClinitOrder() { + /* + * An indy callsite is associated with the following MethodType and MethodHandles: + * + * https://github.com/openjdk/jdk/blob/580eb62dc097efeb51c76b095c1404106859b673/src/java.base/share/classes/java/lang/invoke/LambdaMetafactory.java#L293-L309 + * + * MethodType factoryType The expected signature of the {@code CallSite}. The + * parameter types represent the types of capture variables; + * the return type is the interface to implement. When + * used with {@code invokedynamic}, this is provided by + * the {@code NameAndType} of the {@code InvokeDynamic} + * + * MethodType interfaceMethodType Signature and return type of method to be + * implemented by the function object. + * + * MethodHandle implementation A direct method handle describing the implementation + * method which should be called (with suitable adaptation + * of argument types and return types, and with captured + * arguments prepended to the invocation arguments) at + * invocation time. + * + * MethodType dynamicMethodType The signature and return type that should + * be enforced dynamically at invocation time. + * In simple use cases this is the same as + * {@code interfaceMethodType}. + */ + + // Initial condition: no used by our Foo* and Bar* types have been called. + InitTracker.assertOrder("InitTracker"); + + //============================== + // Case (i) -- Check for types used by factoryType, interfaceMethodType and dynamicMethodType + // (Note: no tests for captured variables in factoryType yet; will be tested in case (ii)) + // factoryType = "()LIntfWithNoClinit; + // interfaceMethodType = "(LFooB;)LFooA;" + // implementation = "REF_invokeStatic AOTLinkedLambdasApp.implAB:(LBarB;)LBarA;" + // dynamicMethodType = "(LBarB;)LBarA;" + IntfWithNoClinit noclinit = AOTLinkedLambdasApp::implAB; + + // None of the Foo? and Bar? types used by the lambda should have been initialized yet, even though + // the indy callsite has been resolved now. + InitTracker.assertOrder("InitTracker"); + + BarB barB = new BarB(); + InitTracker.assertOrder("InitTracker, FooB, BarB"); + BarA barA = noclinit.doit(barB); + System.out.println(barB); + InitTracker.assertOrder("InitTracker, FooB, BarB, FooA, BarA"); + + //============================== + // Case (ii) -- Check for types used by captured variables in factoryType + BarC barC = null; + IntfWithNoClinit2 noclinit2 = () -> { return barC.hashCode(); }; + try { + noclinit2.doit(); + throw new RuntimeException("NullPointerException should have been thrown"); + } catch (NullPointerException npe) { + // expected + } + // BarC shouldn't be initialized as no instances of it has been created. + InitTracker.assertOrder("InitTracker, FooB, BarB, FooA, BarA"); + + + //============================== + // (IA) No default methods -- is not initialized during lambda linking. Lambda can be archived. + IA ia = () -> {}; + ia.doit(); + InitTracker.assertOrder("InitTracker, FooB, BarB, FooA, BarA"); + System.out.println(IA._dummy); + InitTracker.assertOrder("InitTracker, FooB, BarB, FooA, BarA, IA"); + + //============================== + // (IB) Has default method but has not -- OK to initialize IB during lambda linking. Lambda can be archived. + IB ib = () -> {}; + ib.doit(); + InitTracker.assertOrder("InitTracker, FooB, BarB, FooA, BarA, IA"); + + //============================== + // (IC) Has both default method and -- cannot AOT link the lambda + IC ic = () -> {}; + InitTracker.assertOrder("InitTracker, FooB, BarB, FooA, BarA, IA, IC"); + ic.doit(); + + //============================== + // ID1 - has default method, but no + // ID2 - has , but no default method + ID2 id2 = () -> {}; + id2.doit(); + InitTracker.assertOrder("InitTracker, FooB, BarB, FooA, BarA, IA, IC"); + System.out.println(ID2._dummy); + InitTracker.assertOrder("InitTracker, FooB, BarB, FooA, BarA, IA, IC, ID2"); + + //============================== + // IE1 - has both default method and + // IE2 - has , but no default method + IE2 ie2 = () -> {}; + InitTracker.assertOrder("InitTracker, FooB, BarB, FooA, BarA, IA, IC, ID2, IE1"); + System.out.println(IE2._dummy); + InitTracker.assertOrder("InitTracker, FooB, BarB, FooA, BarA, IA, IC, ID2, IE1, IE2"); + + //============================== + // IF1 - has , but no default method + // IF2 - has both default method and + IF2 if2 = () -> {}; + InitTracker.assertOrder("InitTracker, FooB, BarB, FooA, BarA, IA, IC, ID2, IE1, IE2, IF2"); + System.out.println(IF1._dummy); + InitTracker.assertOrder("InitTracker, FooB, BarB, FooA, BarA, IA, IC, ID2, IE1, IE2, IF2, IF1"); + + //============================== + // IG1 - has both default method and + // IG2 - has both default method and + IG2 ig2 = () -> {}; + InitTracker.assertOrder("InitTracker, FooB, BarB, FooA, BarA, IA, IC, ID2, IE1, IE2, IF2, IF1, IG1, IG2"); + + //============================== + // Similar to IE1/IE2, but IH3 is one more level away from IH1 + // IH1 - has both default method and + // IH2 - has , but no default method + // IH3 - has , but no default method + IH3 ih3 = () -> {}; + InitTracker.assertOrder("InitTracker, FooB, BarB, FooA, BarA, IA, IC, ID2, IE1, IE2, IF2, IF1, IG1, IG2, IH1"); + System.out.println(IH3._dummy); + InitTracker.assertOrder("InitTracker, FooB, BarB, FooA, BarA, IA, IC, ID2, IE1, IE2, IF2, IF1, IG1, IG2, IH1, IH3"); + System.out.println(IH2._dummy); + InitTracker.assertOrder("InitTracker, FooB, BarB, FooA, BarA, IA, IC, ID2, IE1, IE2, IF2, IF1, IG1, IG2, IH1, IH3, IH2"); + } + + static BarA implAB(BarB param) { + return new BarA(param); + } +} + + +// An interface with no method. A lambda implementing this +// interface can be AOT-linked. +@FunctionalInterface +interface IntfWithNoClinit { + X doit(Y param); +} + +// Another interface with no method. A lambda implementing this +// interface can be AOT-linked. +@FunctionalInterface +interface IntfWithNoClinit2 { + int doit(); +} + + +// (IA) No default methods -- is not initialized during lambda linking. Lambda can be archived. +@FunctionalInterface interface IA { + static int _dummy = InitTracker.trackEvent("IA"); + void doit(); +} + +// (IB) Has default method but has not -- OK to initialize IB during lambda linking. Lambda can be archived. +@FunctionalInterface interface IB { + default int dummy() { return 0; } + void doit(); +} + +// (IC) Has both default method and -- cannot AOT link the lambda +@FunctionalInterface interface IC { + static int _dummy = InitTracker.trackEvent("IC"); + default int dummy() { return _dummy; } + void doit(); +} + +// (ID1/ID2) +@FunctionalInterface interface ID1 { // has default method, but no + default int dummy() { return 0; } + void doit(); +} + +@FunctionalInterface interface ID2 extends ID1 { // has , but no default method + static int _dummy = InitTracker.trackEvent("ID2"); +} + +// (IE1/IE2) +@FunctionalInterface interface IE1 { // has default method and + static int _dummy = InitTracker.trackEvent("IE1"); + default int dummy() { return _dummy; } + void doit(); +} + +@FunctionalInterface interface IE2 extends IE1 { // has , but no default method + static int _dummy = InitTracker.trackEvent("IE2"); +} + +// (IF1/IF2) +@FunctionalInterface interface IF1 { // has , but no default method + static int _dummy = InitTracker.trackEvent("IF1"); + void doit(); +} + +@FunctionalInterface interface IF2 extends IF1 { // has default method and + static int _dummy = InitTracker.trackEvent("IF2"); + default int dummy() { return 0; } +} + +// (IG1/IG2) +@FunctionalInterface interface IG1 { // has default method and + static int _dummy = InitTracker.trackEvent("IG1"); + default int dummy() { return _dummy; } + void doit(); +} + +@FunctionalInterface interface IG2 extends IG1 { // has default method and + static int _dummy = InitTracker.trackEvent("IG2"); + default int dummy() { return _dummy; } +} + +// (IH1/IH2/IH3) +@FunctionalInterface interface IH1 { // has default method and + static int _dummy = InitTracker.trackEvent("IH1"); + default int dummy() { return _dummy; } + void doit(); +} + +@FunctionalInterface interface IH2 extends IH1 { // has but no default method + static int _dummy = InitTracker.trackEvent("IH2"); +} + +@FunctionalInterface interface IH3 extends IH2 { // has but no default method + static int _dummy = InitTracker.trackEvent("IH3"); +} + + +class InitTracker { + static String actualOrder = "InitTracker"; + static int trackEvent(String event) { + actualOrder += ", " + event; + return actualOrder.lastIndexOf(','); + } + static void assertOrder(String wantOrder) { + System.out.println("wantOrder = " + wantOrder); + System.out.println("actualOrder = " + actualOrder); + if (!actualOrder.equals(wantOrder)) { + throw new RuntimeException("Want order: {" + wantOrder + "}, but got {" + actualOrder + "}"); + } + } +} + +interface FooA { + static final int _dummy = InitTracker.trackEvent("FooA"); + default int dummy() { return _dummy; } +} + +interface FooB { + static final int _dummy = InitTracker.trackEvent("FooB"); + default int dummy() { return _dummy; } +} + +class BarA implements FooA { + static {InitTracker.trackEvent("BarA");} + BarA(BarB dummy) {} +} + +class BarB implements FooB { + static {InitTracker.trackEvent("BarB");} +} + +class BarC { + static {InitTracker.trackEvent("BarC");} +} diff --git a/test/hotspot/jtreg/runtime/cds/appcds/resolvedConstants/AOTLinkedVarHandles.java b/test/hotspot/jtreg/runtime/cds/appcds/resolvedConstants/AOTLinkedVarHandles.java new file mode 100644 index 00000000000..2098ebc2c71 --- /dev/null +++ b/test/hotspot/jtreg/runtime/cds/appcds/resolvedConstants/AOTLinkedVarHandles.java @@ -0,0 +1,128 @@ +/* + * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +/* + * @test + * @summary AOT resolution of VarHandle invocation + * @bug 8343245 + * @requires vm.cds + * @requires vm.cds.supports.aot.class.linking + * @library /test/lib + * @build AOTLinkedVarHandles + * @run driver jdk.test.lib.helpers.ClassFileInstaller -jar app.jar + * AOTLinkedVarHandlesApp AOTLinkedVarHandlesApp$Data + * @run driver AOTLinkedVarHandles + */ + +import java.lang.invoke.MethodHandles; +import java.lang.invoke.VarHandle; +import jdk.test.lib.cds.CDSOptions; +import jdk.test.lib.cds.CDSTestUtils; +import jdk.test.lib.helpers.ClassFileInstaller; +import jdk.test.lib.process.OutputAnalyzer; + +public class AOTLinkedVarHandles { + static final String classList = "AOTLinkedVarHandles.classlist"; + static final String appJar = ClassFileInstaller.getJarPath("app.jar"); + static final String mainClass = AOTLinkedVarHandlesApp.class.getName(); + + public static void main(String[] args) throws Exception { + CDSTestUtils.dumpClassList(classList, "-cp", appJar, mainClass) + .assertNormalExit(output -> { + output.shouldContain("Hello AOTLinkedVarHandlesApp"); + }); + + CDSOptions opts = (new CDSOptions()) + .addPrefix("-XX:ExtraSharedClassListFile=" + classList, + "-XX:+AOTClassLinking", + "-Xlog:cds+resolve=trace", + "-Xlog:cds+class=debug", + "-cp", appJar); + + String s = "archived method CP entry.* AOTLinkedVarHandlesApp "; + OutputAnalyzer dumpOut = CDSTestUtils.createArchiveAndCheck(opts); + dumpOut.shouldMatch(s + "java/lang/invoke/VarHandle.compareAndExchangeAcquire:\\(\\[DIDI\\)D =>"); + dumpOut.shouldMatch(s + "java/lang/invoke/VarHandle.get:\\(\\[DI\\)D => "); + + CDSOptions runOpts = (new CDSOptions()) + .setUseVersion(false) + .addPrefix("-Xlog:cds", + "-esa", + "-cp", appJar) + .addSuffix(mainClass); + + CDSTestUtils.run(runOpts) + .assertNormalExit("Hello AOTLinkedVarHandlesApp"); + } +} + +class AOTLinkedVarHandlesApp { + static final VarHandle initialized; + static final VarHandle lazy; + static long longField = 5678; + static long seed; + + static { + try { + lazy = MethodHandles.lookup().findStaticVarHandle(Data.class, "longField", long.class); + initialized = MethodHandles.lookup().findStaticVarHandle(AOTLinkedVarHandlesApp.class, "longField", long.class); + } catch (ReflectiveOperationException e) { + throw new RuntimeException(e); + } + } + + static class Data { + static long longField = seed; + } + + public static void main(String args[]) { + seed = 1234; + System.out.println("Hello AOTLinkedVarHandlesApp"); + long a = (long) lazy.get(); + long b = (long) initialized.get(); + System.out.println(a); + System.out.println(b); + if (a != 1234) { + throw new RuntimeException("Data class should not be initialized: " + a); + } + if (b != 5678) { + throw new RuntimeException("VarHandle.get() failed: " + b); + } + + VarHandle vh = MethodHandles.arrayElementVarHandle(double[].class); + double[] array = new double[] {1.0}; + int index = 0; + int v = 4; + + // JDK-8343245 -- this generates "java.lang.invoke.LambdaForm$VH/0x80????" hidden class + double r = (double) vh.compareAndExchangeAcquire(array, index, 1.0, v); + if (r != 1.0) { + throw new RuntimeException("Unexpected result: " + r); + } + r = (double) vh.get(array, index); + if (r != 4.0) { + throw new RuntimeException("Unexpected result: " + r); + } + } +} diff --git a/test/hotspot/jtreg/runtime/cds/appcds/resolvedConstants/ResolvedConstants.java b/test/hotspot/jtreg/runtime/cds/appcds/resolvedConstants/ResolvedConstants.java index 474fa65d6ea..7d3335b9db6 100644 --- a/test/hotspot/jtreg/runtime/cds/appcds/resolvedConstants/ResolvedConstants.java +++ b/test/hotspot/jtreg/runtime/cds/appcds/resolvedConstants/ResolvedConstants.java @@ -24,26 +24,40 @@ /* * @test - * @summary Dump time resolutiom of constant pool entries. + * @summary Dump time resolution of constant pool entries. * @requires vm.cds + * @requires vm.cds.supports.aot.class.linking * @requires vm.compMode != "Xcomp" - * @library /test/lib + * @library /test/lib /test/hotspot/jtreg/runtime/cds/appcds/test-classes/ + * @build OldProvider OldClass OldConsumer StringConcatTestOld * @build ResolvedConstants - * @run driver jdk.test.lib.helpers.ClassFileInstaller -jar app.jar ResolvedConstantsApp ResolvedConstantsFoo ResolvedConstantsBar + * @run driver jdk.test.lib.helpers.ClassFileInstaller -jar app.jar + * ResolvedConstantsApp ResolvedConstantsFoo ResolvedConstantsBar + * MyInterface InterfaceWithClinit NormalClass + * OldProvider OldClass OldConsumer SubOfOldClass + * StringConcatTest StringConcatTestOld * @run driver ResolvedConstants */ +import java.util.function.Consumer; import jdk.test.lib.cds.CDSOptions; import jdk.test.lib.cds.CDSTestUtils; import jdk.test.lib.helpers.ClassFileInstaller; +import jdk.test.lib.process.OutputAnalyzer; public class ResolvedConstants { static final String classList = "ResolvedConstants.classlist"; static final String appJar = ClassFileInstaller.getJarPath("app.jar"); static final String mainClass = ResolvedConstantsApp.class.getName(); + static boolean aotClassLinking; public static void main(String[] args) throws Exception { - // dump class list + test(false); + test(true); + } + + static void test(boolean testMode) throws Exception { + aotClassLinking = testMode; CDSTestUtils.dumpClassList(classList, "-cp", appJar, mainClass) .assertNormalExit(output -> { output.shouldContain("Hello ResolvedConstantsApp"); @@ -52,78 +66,109 @@ public static void main(String[] args) throws Exception { CDSOptions opts = (new CDSOptions()) .addPrefix("-XX:ExtraSharedClassListFile=" + classList, "-cp", appJar, - "-Xlog:cds+resolve=trace"); - CDSTestUtils.createArchiveAndCheck(opts) + "-Xlog:cds+resolve=trace", + "-Xlog:cds+class=debug"); + if (aotClassLinking) { + opts.addPrefix("-XX:+AOTClassLinking"); + } else { + opts.addPrefix("-XX:-AOTClassLinking"); + } + + OutputAnalyzer out = CDSTestUtils.createArchiveAndCheck(opts); // Class References --- // Always resolve reference when a class references itself - .shouldMatch("cds,resolve.*archived klass.* ResolvedConstantsApp app => ResolvedConstantsApp app") + out.shouldMatch(ALWAYS("klass.* ResolvedConstantsApp app => ResolvedConstantsApp app")) // Always resolve reference when a class references a super class - .shouldMatch("cds,resolve.*archived klass.* ResolvedConstantsApp app => java/lang/Object boot") - .shouldMatch("cds,resolve.*archived klass.* ResolvedConstantsBar app => ResolvedConstantsFoo app") + .shouldMatch(ALWAYS("klass.* ResolvedConstantsApp app => java/lang/Object boot")) + .shouldMatch(ALWAYS("klass.* ResolvedConstantsBar app => ResolvedConstantsFoo app")) // Always resolve reference when a class references a super interface - .shouldMatch("cds,resolve.*archived klass.* ResolvedConstantsApp app => java/lang/Runnable boot") + .shouldMatch(ALWAYS("klass.* ResolvedConstantsApp app => java/lang/Runnable boot")) - // java/lang/System is in the root loader but ResolvedConstantsApp is loaded by the app loader. - // Even though System is in the vmClasses list, when ResolvedConstantsApp looks up - // "java/lang/System" in its ConstantPool, the app loader may not have resolved the System - // class yet (i.e., there's no initiaited class entry for System in the app loader's dictionary) - .shouldMatch("cds,resolve.*reverted klass.* ResolvedConstantsApp .*java/lang/System") + // Without -XX:+AOTClassLinking: + // java/lang/System is in the boot loader but ResolvedConstantsApp is loaded by the app loader. + // Even though System is in the vmClasses list, when ResolvedConstantsApp looks up + // "java/lang/System" in its ConstantPool, the app loader may not have resolved the System + // class yet (i.e., there's no initiaited class entry for System in the app loader's dictionary) + .shouldMatch(AOTLINK_ONLY("klass.* ResolvedConstantsApp .*java/lang/System")) // Field References --- // Always resolve references to fields in the current class or super class(es) - .shouldMatch("cds,resolve.*archived field.* ResolvedConstantsBar => ResolvedConstantsBar.b:I") - .shouldMatch("cds,resolve.*archived field.* ResolvedConstantsBar => ResolvedConstantsBar.a:I") - .shouldMatch("cds,resolve.*archived field.* ResolvedConstantsBar => ResolvedConstantsFoo.a:I") + .shouldMatch(ALWAYS("field.* ResolvedConstantsBar => ResolvedConstantsBar.b:I")) + .shouldMatch(ALWAYS("field.* ResolvedConstantsBar => ResolvedConstantsBar.a:I")) + .shouldMatch(ALWAYS("field.* ResolvedConstantsBar => ResolvedConstantsFoo.a:I")) + .shouldMatch(ALWAYS("field.* ResolvedConstantsFoo => ResolvedConstantsFoo.a:I")) - // Do not resolve field references to child classes - .shouldMatch("cds,resolve.*archived field.* ResolvedConstantsFoo => ResolvedConstantsFoo.a:I") - .shouldMatch("cds,resolve.*reverted field.* ResolvedConstantsFoo ResolvedConstantsBar.a:I") - .shouldMatch("cds,resolve.*reverted field.* ResolvedConstantsFoo ResolvedConstantsBar.b:I") + // Resolve field references to child classes ONLY when using -XX:+AOTClassLinking + .shouldMatch(AOTLINK_ONLY("field.* ResolvedConstantsFoo => ResolvedConstantsBar.a:I")) + .shouldMatch(AOTLINK_ONLY("field.* ResolvedConstantsFoo => ResolvedConstantsBar.b:I")) - // Do not resolve field references to unrelated classes - .shouldMatch("cds,resolve.*reverted field.* ResolvedConstantsApp ResolvedConstantsBar.a:I") - .shouldMatch("cds,resolve.*reverted field.* ResolvedConstantsApp ResolvedConstantsBar.b:I") + // Resolve field references to unrelated classes ONLY when using -XX:+AOTClassLinking + .shouldMatch(AOTLINK_ONLY("field.* ResolvedConstantsApp => ResolvedConstantsBar.a:I")) + .shouldMatch(AOTLINK_ONLY("field.* ResolvedConstantsApp => ResolvedConstantsBar.b:I")) // Method References --- // Should resolve references to own constructor - .shouldMatch("cds,resolve.*archived method .* ResolvedConstantsApp ResolvedConstantsApp.:") + .shouldMatch(ALWAYS("method.* ResolvedConstantsApp ResolvedConstantsApp.:")) // Should resolve references to super constructor - .shouldMatch("cds,resolve.*archived method .* ResolvedConstantsApp java/lang/Object.:") + .shouldMatch(ALWAYS("method.* ResolvedConstantsApp java/lang/Object.:")) // Should resolve interface methods in VM classes - .shouldMatch("cds,resolve.*archived interface method .* ResolvedConstantsApp java/lang/Runnable.run:") + .shouldMatch(ALWAYS("interface method .* ResolvedConstantsApp java/lang/Runnable.run:")) // Should resolve references to own non-static method (private or public) - .shouldMatch("archived method.*: ResolvedConstantsBar ResolvedConstantsBar.doBar:") - .shouldMatch("archived method.*: ResolvedConstantsApp ResolvedConstantsApp.privateInstanceCall:") - .shouldMatch("archived method.*: ResolvedConstantsApp ResolvedConstantsApp.publicInstanceCall:") + .shouldMatch(ALWAYS("method.*: ResolvedConstantsBar ResolvedConstantsBar.doBar:")) + .shouldMatch(ALWAYS("method.*: ResolvedConstantsApp ResolvedConstantsApp.privateInstanceCall:")) + .shouldMatch(ALWAYS("method.*: ResolvedConstantsApp ResolvedConstantsApp.publicInstanceCall:")) // Should not resolve references to static method - .shouldNotMatch(" archived method CP entry.*: ResolvedConstantsApp ResolvedConstantsApp.staticCall:") + .shouldNotMatch(ALWAYS("method.*: ResolvedConstantsApp ResolvedConstantsApp.staticCall:")) // Should resolve references to method in super type - .shouldMatch(" archived method CP entry.*: ResolvedConstantsBar ResolvedConstantsFoo.doBar:") + .shouldMatch(ALWAYS("method.*: ResolvedConstantsBar ResolvedConstantsFoo.doBar:")) - // App class cannot resolve references to methods in boot classes: + // Without -XX:+AOTClassLinking App class cannot resolve references to methods in boot classes: // When the app class loader tries to resolve a class X that's normally loaded by // the boot loader, it's possible for the app class loader to get a different copy of // X (by using MethodHandles.Lookup.defineClass(), etc). Therefore, let's be on // the side of safety and revert all such references. - // - // This will be addressed in JDK-8315737. - .shouldMatch("reverted method.*: ResolvedConstantsApp java/io/PrintStream.println:") - .shouldMatch("reverted method.*: ResolvedConstantsBar java/lang/Class.getName:") + .shouldMatch(AOTLINK_ONLY("method.*: ResolvedConstantsApp java/io/PrintStream.println:")) + .shouldMatch(AOTLINK_ONLY("method.*: ResolvedConstantsBar java/lang/Class.getName:")) - // Should not resolve methods in unrelated classes. - .shouldMatch("reverted method.*: ResolvedConstantsApp ResolvedConstantsBar.doit:") + // Resole resolve methods in unrelated classes ONLY when using -XX:+AOTClassLinking + .shouldMatch(AOTLINK_ONLY("method.*: ResolvedConstantsApp ResolvedConstantsBar.doit:")) // End --- ; + + + // Indy References --- + if (aotClassLinking) { + out.shouldContain("Cannot aot-resolve Lambda proxy because OldConsumer is excluded") + .shouldContain("Cannot aot-resolve Lambda proxy because OldProvider is excluded") + .shouldContain("Cannot aot-resolve Lambda proxy because OldClass is excluded") + .shouldContain("Cannot aot-resolve Lambda proxy of interface type InterfaceWithClinit") + .shouldMatch("klasses.* app *NormalClass[$][$]Lambda/.* hidden aot-linked inited") + .shouldNotMatch("klasses.* app *SubOfOldClass[$][$]Lambda/") + .shouldMatch("archived indy *CP entry.*StringConcatTest .* => java/lang/invoke/StringConcatFactory.makeConcatWithConstants") + .shouldNotMatch("archived indy *CP entry.*StringConcatTestOld .* => java/lang/invoke/StringConcatFactory.makeConcatWithConstants"); + } + } + + static String ALWAYS(String s) { + return "cds,resolve.*archived " + s; + } + + static String AOTLINK_ONLY(String s) { + if (aotClassLinking) { + return ALWAYS(s); + } else { + return "cds,resolve.*reverted " + s; + } } } @@ -142,12 +187,98 @@ public static void main(String args[]) { bar.a ++; bar.b ++; bar.doit(); + + testLambda(); + StringConcatTest.test(); + StringConcatTestOld.main(null); } private static void staticCall() {} private void privateInstanceCall() {} public void publicInstanceCall() {} public void run() {} + + static void testLambda() { + // The functional type used in the Lambda is an excluded class + OldProvider op = () -> { + return null; + }; + + // A captured value is an instance of an excluded Class + OldClass c = new OldClass(); + Runnable r = () -> { + System.out.println("Test 1 " + c); + }; + r.run(); + + // The functional interface accepts an argument that's an excluded class + MyInterface i = (o) -> { + System.out.println("Test 2 " + o); + }; + i.dispatch(c); + + // Method reference to old class + OldConsumer oldConsumer = new OldConsumer(); + Consumer wrapper = oldConsumer::consumeString; + wrapper.accept("Hello"); + + // Lambda of interfaces that have are not archived. + InterfaceWithClinit i2 = () -> { + System.out.println("Test 3"); + }; + i2.dispatch(); + + // These two classes have almost identical source code, but + // only NormalClass should have its lambdas pre-resolved. + // SubOfOldClass is "old" -- it should be excluded from the AOT cache, + // so none of its lambda proxies should be cached + NormalClass.testLambda(); // Lambda proxy should be cached + SubOfOldClass.testLambda(); // Lambda proxy shouldn't be cached + } +} + +class StringConcatTest { + static void test() { + System.out.println("StringConcatTest " + new StringConcatTest()); // concat should be aot-resolved + } +} + +/* see StringConcatTestOld.jasm + +class StringConcatTestOld { + public static void main(String args[]) { + // concat should be aot-resolved => the MethodType refers to an old class + System.out.println("StringConcatTestOld " + new OldConsumer()); + } +} +*/ + +class NormalClass { + static void testLambda() { + Runnable r = () -> { + System.out.println("NormalClass testLambda"); + }; + r.run(); + } +} + +class SubOfOldClass extends OldClass { + static void testLambda() { + Runnable r = () -> { + System.out.println("SubOfOldClass testLambda"); + }; + r.run(); + } +} + +interface MyInterface { + void dispatch(OldClass c); +} + +interface InterfaceWithClinit { + static final long X = System.currentTimeMillis(); + void dispatch(); + default long dummy() { return X; } } class ResolvedConstantsFoo { diff --git a/test/hotspot/jtreg/runtime/cds/appcds/resolvedConstants/StringConcatTestOld.jasm b/test/hotspot/jtreg/runtime/cds/appcds/resolvedConstants/StringConcatTestOld.jasm new file mode 100644 index 00000000000..76460cad0a3 --- /dev/null +++ b/test/hotspot/jtreg/runtime/cds/appcds/resolvedConstants/StringConcatTestOld.jasm @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +/* + +decompiled from + +class OldConsumer {} + +class StringConcatTestOld { + public static void main(String args[]) { + System.out.println("StringConcatTestOld " + new OldConsumer()); + } +} + + +(1) Comment out this line + + invokestatic Method java/lang/String.valueOf:"(Ljava/lang/Object;)Ljava/lang/String;"; + +(2) Change the MethodType parameter of makeConcatWithConstants from + + "(Ljava/lang/String;)Ljava/lang/String;" + -> + + "(LOldConsumer;)Ljava/lang/String;" + +*/ + +super class StringConcatTestOld + version 67:0 +{ + Method "":"()V" + stack 1 locals 1 + { + aload_0; + invokespecial Method java/lang/Object."":"()V"; + return; + } + public static Method main:"([Ljava/lang/String;)V" + stack 3 locals 1 + { + getstatic Field java/lang/System.out:"Ljava/io/PrintStream;"; + new class OldConsumer; + dup; + invokespecial Method OldConsumer."":"()V"; + //invokestatic Method java/lang/String.valueOf:"(Ljava/lang/Object;)Ljava/lang/String;"; + invokedynamic InvokeDynamic REF_invokeStatic:Method java/lang/invoke/StringConcatFactory.makeConcatWithConstants:"(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/String;[Ljava/lang/Object;)Ljava/lang/invoke/CallSite;":makeConcatWithConstants:"(LOldConsumer;)Ljava/lang/String;" { + String "StringConcatTestOld " + }; + invokevirtual Method java/io/PrintStream.println:"(Ljava/lang/String;)V"; + return; + } + + public static final InnerClass Lookup=class java/lang/invoke/MethodHandles$Lookup of class java/lang/invoke/MethodHandles; + +} // end Class StringConcatTestOld diff --git a/test/hotspot/jtreg/runtime/cds/appcds/test-classes/OldConsumer.jasm b/test/hotspot/jtreg/runtime/cds/appcds/test-classes/OldConsumer.jasm new file mode 100644 index 00000000000..bffb5a27381 --- /dev/null +++ b/test/hotspot/jtreg/runtime/cds/appcds/test-classes/OldConsumer.jasm @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ +super class OldConsumer + version 49:0 +{ + + +Method "":"()V" + stack 1 locals 1 +{ + aload_0; + invokespecial Method java/lang/Object."":"()V"; + return; +} + +public Method consumeString:"(Ljava/lang/String;)V" + stack 3 locals 2 +{ + getstatic Field java/lang/System.out:"Ljava/io/PrintStream;"; + new class java/lang/StringBuilder; + dup; + invokespecial Method java/lang/StringBuilder."":"()V"; + ldc String "Hello: "; + invokevirtual Method java/lang/StringBuilder.append:"(Ljava/lang/String;)Ljava/lang/StringBuilder;"; + aload_1; + invokevirtual Method java/lang/StringBuilder.append:"(Ljava/lang/String;)Ljava/lang/StringBuilder;"; + invokevirtual Method java/lang/StringBuilder.toString:"()Ljava/lang/String;"; + invokevirtual Method java/io/PrintStream.println:"(Ljava/lang/String;)V"; + return; +} + +} // end Class OldConsumer diff --git a/test/jdk/ProblemList-AotJdk.txt b/test/jdk/ProblemList-AotJdk.txt new file mode 100644 index 00000000000..9030ba60c78 --- /dev/null +++ b/test/jdk/ProblemList-AotJdk.txt @@ -0,0 +1,11 @@ +java/math/BigInteger/largeMemory/DivisionOverflow.java 0000000 generic-all +java/math/BigInteger/largeMemory/StringConstructorOverflow.java 0000000 generic-all + +jdk/internal/misc/CDS/ArchivedEnumTest.java 0000000 generic-all + +java/lang/module/ModuleDescriptorHashCodeTest.java 0000000 generic-all + + +# The test case is incorrect. There's no guarantee that running a JVM with the following +# parameters will always cause the class java/lang/invoke/MethodHandleStatics to be initialized +java/lang/invoke/DumpMethodHandleInternals.java 0000000 generic-all diff --git a/test/jdk/jdk/internal/misc/CDS/ArchivedEnumTest.java b/test/jdk/jdk/internal/misc/CDS/ArchivedEnumTest.java index ec1bd213834..3a2d0f9539f 100644 --- a/test/jdk/jdk/internal/misc/CDS/ArchivedEnumTest.java +++ b/test/jdk/jdk/internal/misc/CDS/ArchivedEnumTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -35,6 +35,7 @@ * @run driver ArchivedEnumTest */ +import jdk.test.lib.cds.CDSTestUtils; import jdk.test.lib.helpers.ClassFileInstaller; import jdk.test.lib.process.OutputAnalyzer; @@ -46,7 +47,7 @@ public static void main(String[] args) throws Exception { TestCommon.list("ArchivedEnumApp")); // Note: You can get the following line to fail by commenting out // the ADD_EXCL(...) lines in cdsHeapVerifier.cpp - out.shouldNotContain("object points to a static field that may be reinitialized at runtime"); + out.shouldNotContain(CDSTestUtils.MSG_STATIC_FIELD_MAY_HOLD_DIFFERENT_VALUE); TestCommon.run("-cp", appJar, "-Xlog:cds=debug", diff --git a/test/jtreg-ext/requires/VMProps.java b/test/jtreg-ext/requires/VMProps.java index 775b95959c6..5544ad1bebd 100644 --- a/test/jtreg-ext/requires/VMProps.java +++ b/test/jtreg-ext/requires/VMProps.java @@ -122,6 +122,7 @@ public Map call() { // vm.cds is true if the VM is compiled with cds support. map.put("vm.cds", this::vmCDS); map.put("vm.cds.custom.loaders", this::vmCDSForCustomLoaders); + map.put("vm.cds.supports.aot.class.linking", this::vmCDSSupportsAOTClassLinking); map.put("vm.cds.write.archived.java.heap", this::vmCDSCanWriteArchivedJavaHeap); map.put("vm.continuations", this::vmContinuations); // vm.graal.enabled is true if Graal is used as JIT @@ -457,6 +458,14 @@ protected String vmCDSCanWriteArchivedJavaHeap() { && isCDSRuntimeOptionsCompatible()); } + /** + * @return true if this VM can support the -XX:AOTClassLinking option + */ + protected String vmCDSSupportsAOTClassLinking() { + // Currently, the VM supports AOTClassLinking as long as it's able to write archived java heap. + return vmCDSCanWriteArchivedJavaHeap(); + } + /** * @return true if the VM options specified via the "test.cds.runtime.options" * property is compatible with writing Java heap objects into the CDS archive diff --git a/test/lib/jdk/test/lib/cds/CDSAppTester.java b/test/lib/jdk/test/lib/cds/CDSAppTester.java index c39e6bb8e94..d83c3c36e41 100644 --- a/test/lib/jdk/test/lib/cds/CDSAppTester.java +++ b/test/lib/jdk/test/lib/cds/CDSAppTester.java @@ -28,6 +28,7 @@ import jdk.test.lib.process.ProcessTools; import jdk.test.lib.process.OutputAnalyzer; import jdk.test.lib.StringArrayUtils; +import jtreg.SkippedException; /* * This is a base class used for testing CDS functionalities with complex applications. @@ -42,9 +43,13 @@ abstract public class CDSAppTester { private final String staticArchiveFileLog; private final String dynamicArchiveFile; private final String dynamicArchiveFileLog; - private final String productionRunLog; + private int numProductionRuns = 0; public CDSAppTester(String name) { + if (CDSTestUtils.DYNAMIC_DUMP) { + throw new SkippedException("Tests based on CDSAppTester should be excluded when -Dtest.dynamic.cds.archive is specified"); + } + // Old workflow this.name = name; classListFile = name() + ".classlist"; @@ -53,7 +58,14 @@ public CDSAppTester(String name) { staticArchiveFileLog = staticArchiveFile + ".log"; dynamicArchiveFile = name() + ".dynamic.jsa"; dynamicArchiveFileLog = dynamicArchiveFile + ".log"; - productionRunLog = name() + ".production.log"; + } + + private String productionRunLog() { + if (numProductionRuns == 0) { + return name() + ".production.log"; + } else { + return name() + ".production." + numProductionRuns + ".log"; + } } private enum Workflow { @@ -97,6 +109,11 @@ public String classpath(RunMode runMode) { public void checkExecution(OutputAnalyzer out, RunMode runMode) throws Exception {} private Workflow workflow; + private boolean checkExitValue = true; + + public final void setCheckExitValue(boolean b) { + checkExitValue = b; + } public final boolean isStaticWorkflow() { return workflow == Workflow.STATIC; @@ -134,7 +151,10 @@ private OutputAnalyzer executeAndCheck(String[] cmdLine, RunMode runMode, String for (String logFile : logFiles) { listOutputFile(logFile); } - output.shouldHaveExitValue(0); + if (checkExitValue) { + output.shouldHaveExitValue(0); + } + output.shouldNotContain(CDSTestUtils.MSG_STATIC_FIELD_MAY_HOLD_DIFFERENT_VALUE); CDSTestUtils.checkCommonExecExceptions(output); checkExecution(output, runMode); return output; @@ -189,10 +209,22 @@ private OutputAnalyzer dumpDynamicArchive() throws Exception { } private OutputAnalyzer productionRun() throws Exception { + return productionRun(null, null); + } + + public OutputAnalyzer productionRun(String[] extraVmArgs) throws Exception { + return productionRun(extraVmArgs, null); + } + + // After calling run(String[]), you can call this method to run the app again, with the AOTCache + // using different args to the VM and application. + public OutputAnalyzer productionRun(String[] extraVmArgs, String[] extraAppArgs) throws Exception { RunMode runMode = RunMode.PRODUCTION; String[] cmdLine = StringArrayUtils.concat(vmArgs(runMode), + "-XX:+UnlockDiagnosticVMOptions", + "-XX:VerifyArchivedFields=2", // make sure archived heap objects are good. "-cp", classpath(runMode), - logToFile(productionRunLog, "cds")); + logToFile(productionRunLog(), "cds")); if (isStaticWorkflow()) { cmdLine = StringArrayUtils.concat(cmdLine, "-XX:SharedArchiveFile=" + staticArchiveFile); @@ -200,8 +232,19 @@ private OutputAnalyzer productionRun() throws Exception { cmdLine = StringArrayUtils.concat(cmdLine, "-XX:SharedArchiveFile=" + dynamicArchiveFile); } + if (extraVmArgs != null) { + cmdLine = StringArrayUtils.concat(cmdLine, extraVmArgs); + } + cmdLine = StringArrayUtils.concat(cmdLine, appCommandLine(runMode)); - return executeAndCheck(cmdLine, runMode, productionRunLog); + + if (extraAppArgs != null) { + cmdLine = StringArrayUtils.concat(cmdLine, extraAppArgs); + } + + OutputAnalyzer out = executeAndCheck(cmdLine, runMode, productionRunLog()); + numProductionRuns ++; + return out; } public void run(String args[]) throws Exception { diff --git a/test/lib/jdk/test/lib/cds/CDSTestUtils.java b/test/lib/jdk/test/lib/cds/CDSTestUtils.java index 7115912380a..a913f2f9fa2 100644 --- a/test/lib/jdk/test/lib/cds/CDSTestUtils.java +++ b/test/lib/jdk/test/lib/cds/CDSTestUtils.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -51,6 +51,8 @@ public class CDSTestUtils { "Unable to allocate region, java heap range is already in use."; public static final String MSG_DYNAMIC_NOT_SUPPORTED = "-XX:ArchiveClassesAtExit is unsupported when base CDS archive is not loaded"; + public static final String MSG_STATIC_FIELD_MAY_HOLD_DIFFERENT_VALUE = + "an object points to a static field that may hold a different value at runtime"; public static final boolean DYNAMIC_DUMP = Boolean.getBoolean("test.dynamic.cds.archive"); public interface Checker { @@ -284,6 +286,7 @@ public static OutputAnalyzer checkDump(OutputAnalyzer output, String... extraMat output.shouldContain("Written dynamic archive 0x"); } output.shouldHaveExitValue(0); + output.shouldNotContain(MSG_STATIC_FIELD_MAY_HOLD_DIFFERENT_VALUE); for (String match : extraMatches) { output.shouldContain(match); @@ -296,6 +299,7 @@ public static OutputAnalyzer checkDump(OutputAnalyzer output, String... extraMat public static OutputAnalyzer checkBaseDump(OutputAnalyzer output) throws Exception { output.shouldContain("Loading classes to share"); output.shouldHaveExitValue(0); + output.shouldNotContain(MSG_STATIC_FIELD_MAY_HOLD_DIFFERENT_VALUE); return output; } @@ -859,4 +863,24 @@ public static Path copyFile(String srcFile, String destDir) throws Exception { Files.copy(srcPath, destPath, REPLACE_EXISTING, COPY_ATTRIBUTES); return destPath; } + + // Some tests were initially written without the knowledge of -XX:+AOTClassLinking. These tests need to + // be adjusted if -XX:+AOTClassLinking is specified in jtreg -vmoptions or -javaoptions: + public static boolean isAOTClassLinkingEnabled() { + return isBooleanVMOptionEnabledInCommandLine("AOTClassLinking"); + } + + public static boolean isBooleanVMOptionEnabledInCommandLine(String optionName) { + String lastMatch = null; + String pattern = "^-XX:." + optionName + "$"; + for (String s : Utils.getTestJavaOpts()) { + if (s.matches(pattern)) { + lastMatch = s; + } + } + if (lastMatch != null && lastMatch.equals("-XX:+" + optionName)) { + return true; + } + return false; + } } From 2c509a158fad63e69a8072fa4a7588eaacf37dc0 Mon Sep 17 00:00:00 2001 From: Alexey Semenyuk Date: Fri, 15 Nov 2024 23:55:45 +0000 Subject: [PATCH 033/311] 8344326: Move jpackage tests from "jdk.jpackage.tests" package to the default package Reviewed-by: almatvee --- .../jdk/jpackage/test/WindowsHelper.java | 16 ---------------- .../{jdk/jpackage/tests => }/UsrTreeTest.java | 0 .../jpackage/tests => }/AppVersionTest.java | 3 +-- .../{jdk/jpackage/tests => }/BasicTest.java | 19 ++++++------------- .../tests => }/CookedRuntimeTest.java | 3 +-- .../jpackage/tests => }/DotInNameTest.java | 3 +-- .../{jdk/jpackage/tests => }/ErrorTest.java | 5 ++--- .../jpackage/tests => }/JLinkOptionsTest.java | 3 +-- .../tests => }/JavaOptionsEqualsTest.java | 5 ++--- .../jpackage/tests => }/JavaOptionsTest.java | 3 +-- .../jpackage/tests => }/MainClassTest.java | 16 ++++++++-------- .../jpackage/tests => }/ModulePathTest.java | 3 +-- .../jpackage/tests => }/ModulePathTest2.java | 3 +-- .../jpackage/tests => }/ModulePathTest3.java | 3 +-- .../tests => }/MultipleJarAppTest.java | 3 +-- .../tests => }/NoMPathRuntimeTest.java | 3 +-- .../jpackage/tests => }/NonExistentTest.java | 3 +-- .../PredefinedAppImageErrorTest.java | 5 ++--- .../jpackage/tests => }/UnicodeArgsTest.java | 3 +-- .../{jdk/jpackage/tests => }/VendorTest.java | 5 ++--- .../tools/jpackage/windows/WinL10nTest.java | 10 +++------- 21 files changed, 37 insertions(+), 80 deletions(-) rename test/jdk/tools/jpackage/linux/{jdk/jpackage/tests => }/UsrTreeTest.java (100%) rename test/jdk/tools/jpackage/share/{jdk/jpackage/tests => }/AppVersionTest.java (98%) rename test/jdk/tools/jpackage/share/{jdk/jpackage/tests => }/BasicTest.java (95%) rename test/jdk/tools/jpackage/share/{jdk/jpackage/tests => }/CookedRuntimeTest.java (98%) rename test/jdk/tools/jpackage/share/{jdk/jpackage/tests => }/DotInNameTest.java (96%) rename test/jdk/tools/jpackage/share/{jdk/jpackage/tests => }/ErrorTest.java (97%) rename test/jdk/tools/jpackage/share/{jdk/jpackage/tests => }/JLinkOptionsTest.java (98%) rename test/jdk/tools/jpackage/share/{jdk/jpackage/tests => }/JavaOptionsEqualsTest.java (96%) rename test/jdk/tools/jpackage/share/{jdk/jpackage/tests => }/JavaOptionsTest.java (98%) rename test/jdk/tools/jpackage/share/{jdk/jpackage/tests => }/MainClassTest.java (96%) rename test/jdk/tools/jpackage/share/{jdk/jpackage/tests => }/ModulePathTest.java (98%) rename test/jdk/tools/jpackage/share/{jdk/jpackage/tests => }/ModulePathTest2.java (97%) rename test/jdk/tools/jpackage/share/{jdk/jpackage/tests => }/ModulePathTest3.java (98%) rename test/jdk/tools/jpackage/share/{jdk/jpackage/tests => }/MultipleJarAppTest.java (96%) rename test/jdk/tools/jpackage/share/{jdk/jpackage/tests => }/NoMPathRuntimeTest.java (98%) rename test/jdk/tools/jpackage/share/{jdk/jpackage/tests => }/NonExistentTest.java (97%) rename test/jdk/tools/jpackage/share/{jdk/jpackage/tests => }/PredefinedAppImageErrorTest.java (96%) rename test/jdk/tools/jpackage/share/{jdk/jpackage/tests => }/UnicodeArgsTest.java (97%) rename test/jdk/tools/jpackage/share/{jdk/jpackage/tests => }/VendorTest.java (96%) diff --git a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/WindowsHelper.java b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/WindowsHelper.java index 338ff7a767b..1976a5cf72c 100644 --- a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/WindowsHelper.java +++ b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/WindowsHelper.java @@ -64,22 +64,6 @@ private static Path getInstallationSubDirectory(JPackageCommand cmd) { return Path.of(cmd.getArgumentValue("--install-dir", cmd::name)); } - // Tests have problems on windows where path in the temp dir are too long - // for the wix tools. We can't use a tempDir outside the TKit's WorkDir, so - // we minimize both the tempRoot directory name (above) and the tempDir name - // (below) to the extension part (which is necessary to differenciate between - // the multiple PackageTypes that will be run for one JPackageCommand). - // It might be beter if the whole work dir name was shortened from: - // jtreg_open_test_jdk_tools_jpackage_share_jdk_jpackage_tests_BasicTest_java. - public static Path getTempDirectory(JPackageCommand cmd, Path tempRoot) { - String ext = cmd.outputBundle().getFileName().toString(); - int i = ext.lastIndexOf("."); - if (i > 0 && i < (ext.length() - 1)) { - ext = ext.substring(i+1); - } - return tempRoot.resolve(ext); - } - private static void runMsiexecWithRetries(Executor misexec) { Executor.Result result = null; for (int attempt = 0; attempt < 8; ++attempt) { diff --git a/test/jdk/tools/jpackage/linux/jdk/jpackage/tests/UsrTreeTest.java b/test/jdk/tools/jpackage/linux/UsrTreeTest.java similarity index 100% rename from test/jdk/tools/jpackage/linux/jdk/jpackage/tests/UsrTreeTest.java rename to test/jdk/tools/jpackage/linux/UsrTreeTest.java diff --git a/test/jdk/tools/jpackage/share/jdk/jpackage/tests/AppVersionTest.java b/test/jdk/tools/jpackage/share/AppVersionTest.java similarity index 98% rename from test/jdk/tools/jpackage/share/jdk/jpackage/tests/AppVersionTest.java rename to test/jdk/tools/jpackage/share/AppVersionTest.java index d4f28ec17be..efd025590d2 100644 --- a/test/jdk/tools/jpackage/share/jdk/jpackage/tests/AppVersionTest.java +++ b/test/jdk/tools/jpackage/share/AppVersionTest.java @@ -21,7 +21,6 @@ * questions. */ -package jdk.jpackage.tests; import java.io.IOException; import java.util.Collection; @@ -46,7 +45,7 @@ * @build jdk.jpackage.test.* * @compile AppVersionTest.java * @run main/othervm/timeout=360 -Xmx512m jdk.jpackage.test.Main - * --jpt-run=jdk.jpackage.tests.AppVersionTest + * --jpt-run=AppVersionTest */ public final class AppVersionTest { diff --git a/test/jdk/tools/jpackage/share/jdk/jpackage/tests/BasicTest.java b/test/jdk/tools/jpackage/share/BasicTest.java similarity index 95% rename from test/jdk/tools/jpackage/share/jdk/jpackage/tests/BasicTest.java rename to test/jdk/tools/jpackage/share/BasicTest.java index 1222fa95949..61668b9e878 100644 --- a/test/jdk/tools/jpackage/share/jdk/jpackage/tests/BasicTest.java +++ b/test/jdk/tools/jpackage/share/BasicTest.java @@ -21,7 +21,6 @@ * questions. */ -package jdk.jpackage.tests; import java.io.IOException; import java.nio.file.Files; @@ -45,8 +44,6 @@ import jdk.jpackage.test.Functional.ThrowingConsumer; import static jdk.jpackage.test.RunnablePackageTest.Action.CREATE_AND_UNPACK; -import static jdk.jpackage.test.WindowsHelper.getTempDirectory; - /* * @test * @summary jpackage basic testing @@ -54,7 +51,7 @@ * @build jdk.jpackage.test.* * @compile BasicTest.java * @run main/othervm/timeout=720 -Xmx512m jdk.jpackage.test.Main - * --jpt-run=jdk.jpackage.tests.BasicTest + * --jpt-run=BasicTest */ public final class BasicTest { @@ -345,7 +342,7 @@ public void testTemp(TestTempType type) throws IOException { // Force save of package bundle in test work directory. .addInitializer(JPackageCommand::setDefaultInputOutput) .addInitializer(cmd -> { - Path tempDir = getTempDirectory(cmd, tempRoot); + Path tempDir = tempRoot.resolve(cmd.packageType().name()); switch (type) { case TEMPDIR_EMPTY -> Files.createDirectories(tempDir); case TEMPDIR_NOT_EXIST -> Files.createDirectories(tempDir.getParent()); @@ -362,20 +359,16 @@ public void testTemp(TestTempType type) throws IOException { if (TestTempType.TEMPDIR_NOT_EMPTY.equals(type)) { pkgTest.setExpectedExitCode(1).addBundleVerifier(cmd -> { // Check jpackage didn't use the supplied directory. - Path tempDir = getTempDirectory(cmd, tempRoot); - String[] tempDirContents = tempDir.toFile().list(); - TKit.assertStringListEquals(List.of("foo.txt"), List.of( - tempDirContents), String.format( - "Check the contents of the supplied temporary directory [%s]", - tempDir)); + Path tempDir = Path.of(cmd.getArgumentValue("--temp")); + TKit.assertDirectoryContent(tempDir).match(Path.of("foo.txt")); TKit.assertStringListEquals(List.of("Hello Duke!"), - Files.readAllLines(tempDir.resolve(tempDirContents[0])), + Files.readAllLines(tempDir.resolve("foo.txt")), "Check the contents of the file in the supplied temporary directory"); }); } else { pkgTest.addBundleVerifier(cmd -> { // Check jpackage used the supplied directory. - Path tempDir = getTempDirectory(cmd, tempRoot); + Path tempDir = Path.of(cmd.getArgumentValue("--temp")); TKit.assertDirectoryNotEmpty(tempDir); }); } diff --git a/test/jdk/tools/jpackage/share/jdk/jpackage/tests/CookedRuntimeTest.java b/test/jdk/tools/jpackage/share/CookedRuntimeTest.java similarity index 98% rename from test/jdk/tools/jpackage/share/jdk/jpackage/tests/CookedRuntimeTest.java rename to test/jdk/tools/jpackage/share/CookedRuntimeTest.java index cfb6ec13ccf..e8bd034bfb4 100644 --- a/test/jdk/tools/jpackage/share/jdk/jpackage/tests/CookedRuntimeTest.java +++ b/test/jdk/tools/jpackage/share/CookedRuntimeTest.java @@ -21,7 +21,6 @@ * questions. */ -package jdk.jpackage.tests; import java.io.IOException; import java.nio.file.Files; @@ -46,7 +45,7 @@ * @build jdk.jpackage.test.* * @compile CookedRuntimeTest.java * @run main/othervm/timeout=360 -Xmx512m jdk.jpackage.test.Main - * --jpt-run=jdk.jpackage.tests.CookedRuntimeTest + * --jpt-run=CookedRuntimeTest */ public final class CookedRuntimeTest { diff --git a/test/jdk/tools/jpackage/share/jdk/jpackage/tests/DotInNameTest.java b/test/jdk/tools/jpackage/share/DotInNameTest.java similarity index 96% rename from test/jdk/tools/jpackage/share/jdk/jpackage/tests/DotInNameTest.java rename to test/jdk/tools/jpackage/share/DotInNameTest.java index 73be2c2e47a..2617db26183 100644 --- a/test/jdk/tools/jpackage/share/jdk/jpackage/tests/DotInNameTest.java +++ b/test/jdk/tools/jpackage/share/DotInNameTest.java @@ -21,7 +21,6 @@ * questions. */ -package jdk.jpackage.tests; import jdk.jpackage.test.JPackageCommand; import jdk.jpackage.test.HelloApp; @@ -37,7 +36,7 @@ * @build jdk.jpackage.test.* * @compile DotInNameTest.java * @run main/othervm/timeout=360 -Xmx512m jdk.jpackage.test.Main - * --jpt-run=jdk.jpackage.tests.DotInNameTest + * --jpt-run=DotInNameTest * --jpt-before-run=jdk.jpackage.test.JPackageCommand.useToolProviderByDefault */ diff --git a/test/jdk/tools/jpackage/share/jdk/jpackage/tests/ErrorTest.java b/test/jdk/tools/jpackage/share/ErrorTest.java similarity index 97% rename from test/jdk/tools/jpackage/share/jdk/jpackage/tests/ErrorTest.java rename to test/jdk/tools/jpackage/share/ErrorTest.java index 57603809607..f012eac1ced 100644 --- a/test/jdk/tools/jpackage/share/jdk/jpackage/tests/ErrorTest.java +++ b/test/jdk/tools/jpackage/share/ErrorTest.java @@ -21,7 +21,6 @@ * questions. */ -package jdk.jpackage.tests; import java.util.Collection; import java.util.List; @@ -37,7 +36,7 @@ * @build jdk.jpackage.test.* * @compile ErrorTest.java * @run main/othervm/timeout=360 -Xmx512m jdk.jpackage.test.Main - * --jpt-run=jdk.jpackage.tests.ErrorTest + * --jpt-run=ErrorTest * --jpt-before-run=jdk.jpackage.test.JPackageCommand.useExecutableByDefault */ @@ -48,7 +47,7 @@ * @build jdk.jpackage.test.* * @compile ErrorTest.java * @run main/othervm/timeout=360 -Xmx512m jdk.jpackage.test.Main - * --jpt-run=jdk.jpackage.tests.ErrorTest + * --jpt-run=ErrorTest * --jpt-before-run=jdk.jpackage.test.JPackageCommand.useToolProviderByDefault */ diff --git a/test/jdk/tools/jpackage/share/jdk/jpackage/tests/JLinkOptionsTest.java b/test/jdk/tools/jpackage/share/JLinkOptionsTest.java similarity index 98% rename from test/jdk/tools/jpackage/share/jdk/jpackage/tests/JLinkOptionsTest.java rename to test/jdk/tools/jpackage/share/JLinkOptionsTest.java index dce60890aba..d4f7bca2ae4 100644 --- a/test/jdk/tools/jpackage/share/jdk/jpackage/tests/JLinkOptionsTest.java +++ b/test/jdk/tools/jpackage/share/JLinkOptionsTest.java @@ -21,7 +21,6 @@ * questions. */ -package jdk.jpackage.tests; import java.util.Collection; import java.util.List; @@ -37,7 +36,7 @@ * @build jdk.jpackage.test.* * @compile JLinkOptionsTest.java * @run main/othervm/timeout=360 -Xmx512m jdk.jpackage.test.Main - * --jpt-run=jdk.jpackage.tests.JLinkOptionsTest + * --jpt-run=JLinkOptionsTest */ public final class JLinkOptionsTest { diff --git a/test/jdk/tools/jpackage/share/jdk/jpackage/tests/JavaOptionsEqualsTest.java b/test/jdk/tools/jpackage/share/JavaOptionsEqualsTest.java similarity index 96% rename from test/jdk/tools/jpackage/share/jdk/jpackage/tests/JavaOptionsEqualsTest.java rename to test/jdk/tools/jpackage/share/JavaOptionsEqualsTest.java index e1c809dadd3..b1f69c6395f 100644 --- a/test/jdk/tools/jpackage/share/jdk/jpackage/tests/JavaOptionsEqualsTest.java +++ b/test/jdk/tools/jpackage/share/JavaOptionsEqualsTest.java @@ -21,7 +21,6 @@ * questions. */ -package jdk.jpackage.tests; import java.util.Collection; import java.util.List; @@ -39,7 +38,7 @@ * @build jdk.jpackage.test.* * @compile JavaOptionsEqualsTest.java * @run main/othervm/timeout=360 -Xmx512m jdk.jpackage.test.Main - * --jpt-run=jdk.jpackage.tests.JavaOptionsEqualsTest + * --jpt-run=JavaOptionsEqualsTest * --jpt-before-run=jdk.jpackage.test.JPackageCommand.useExecutableByDefault */ @@ -50,7 +49,7 @@ * @build jdk.jpackage.test.* * @compile JavaOptionsEqualsTest.java * @run main/othervm/timeout=360 -Xmx512m jdk.jpackage.test.Main - * --jpt-run=jdk.jpackage.tests.JavaOptionsEqualsTest + * --jpt-run=JavaOptionsEqualsTest * --jpt-before-run=jdk.jpackage.test.JPackageCommand.useToolProviderByDefault */ diff --git a/test/jdk/tools/jpackage/share/jdk/jpackage/tests/JavaOptionsTest.java b/test/jdk/tools/jpackage/share/JavaOptionsTest.java similarity index 98% rename from test/jdk/tools/jpackage/share/jdk/jpackage/tests/JavaOptionsTest.java rename to test/jdk/tools/jpackage/share/JavaOptionsTest.java index cee455271aa..befc90accea 100644 --- a/test/jdk/tools/jpackage/share/jdk/jpackage/tests/JavaOptionsTest.java +++ b/test/jdk/tools/jpackage/share/JavaOptionsTest.java @@ -21,7 +21,6 @@ * questions. */ -package jdk.jpackage.tests; import java.util.Collection; import java.util.List; @@ -39,7 +38,7 @@ * @build jdk.jpackage.test.* * @compile JavaOptionsTest.java * @run main/othervm/timeout=360 -Xmx512m jdk.jpackage.test.Main - * --jpt-run=jdk.jpackage.tests.JavaOptionsTest + * --jpt-run=JavaOptionsTest * --jpt-before-run=jdk.jpackage.test.JPackageCommand.useToolProviderByDefault */ diff --git a/test/jdk/tools/jpackage/share/jdk/jpackage/tests/MainClassTest.java b/test/jdk/tools/jpackage/share/MainClassTest.java similarity index 96% rename from test/jdk/tools/jpackage/share/jdk/jpackage/tests/MainClassTest.java rename to test/jdk/tools/jpackage/share/MainClassTest.java index 641d0fd00bb..d9188e8f18f 100644 --- a/test/jdk/tools/jpackage/share/jdk/jpackage/tests/MainClassTest.java +++ b/test/jdk/tools/jpackage/share/MainClassTest.java @@ -21,7 +21,6 @@ * questions. */ -package jdk.jpackage.tests; import java.io.IOException; import java.nio.file.Files; @@ -46,7 +45,7 @@ import jdk.jpackage.test.Annotations.Test; import jdk.jpackage.test.CfgFile; import jdk.jpackage.test.Functional.ThrowingConsumer; -import static jdk.jpackage.tests.MainClassTest.Script.MainClassType.*; + /* @@ -56,7 +55,7 @@ * @build jdk.jpackage.test.* * @compile MainClassTest.java * @run main/othervm/timeout=720 -Xmx512m jdk.jpackage.test.Main - * --jpt-run=jdk.jpackage.tests.MainClassTest + * --jpt-run=MainClassTest */ public final class MainClassTest { @@ -82,7 +81,7 @@ Script withMainClass(MainClassType v) { } Script withJarMainClass(MainClassType v) { - appDesc.setWithMainClass(v != NotSet); + appDesc.setWithMainClass(v != MainClassType.NotSet); jarMainClass = v; return this; } @@ -172,7 +171,8 @@ public MainClassTest(Script script) { @Parameters public static Collection scripts() { - final var withMainClass = Set.of(SetWrong, SetRight); + final var withMainClass = Set.of(Script.MainClassType.SetWrong, + Script.MainClassType.SetRight); List scripts = new ArrayList<>(); for (var withJLink : List.of(true, false)) { @@ -205,7 +205,7 @@ public static Collection scripts() { @Test public void test() throws IOException { - if (script.jarMainClass == SetWrong) { + if (script.jarMainClass == Script.MainClassType.SetWrong) { initJarWithWrongMainClass(); } @@ -224,11 +224,11 @@ public void test() throws IOException { boolean appShouldSucceed = false; // Should succeed if valid main class is set on the command line. - appShouldSucceed |= (script.mainClass == SetRight); + appShouldSucceed |= (script.mainClass == Script.MainClassType.SetRight); // Should succeed if main class is not set on the command line but set // to valid value in the jar. - appShouldSucceed |= (script.mainClass == NotSet && script.jarMainClass == SetRight); + appShouldSucceed |= (script.mainClass == Script.MainClassType.NotSet && script.jarMainClass == Script.MainClassType.SetRight); if (appShouldSucceed) { cmd.executeAndAssertHelloAppImageCreated(); diff --git a/test/jdk/tools/jpackage/share/jdk/jpackage/tests/ModulePathTest.java b/test/jdk/tools/jpackage/share/ModulePathTest.java similarity index 98% rename from test/jdk/tools/jpackage/share/jdk/jpackage/tests/ModulePathTest.java rename to test/jdk/tools/jpackage/share/ModulePathTest.java index c42a24ec310..7d1e86f8ae2 100644 --- a/test/jdk/tools/jpackage/share/jdk/jpackage/tests/ModulePathTest.java +++ b/test/jdk/tools/jpackage/share/ModulePathTest.java @@ -21,7 +21,6 @@ * questions. */ -package jdk.jpackage.tests; import java.io.File; import java.io.IOException; @@ -48,7 +47,7 @@ * @build jdk.jpackage.test.* * @compile ModulePathTest.java * @run main/othervm/timeout=360 -Xmx512m jdk.jpackage.test.Main - * --jpt-run=jdk.jpackage.tests.ModulePathTest + * --jpt-run=ModulePathTest */ public final class ModulePathTest { diff --git a/test/jdk/tools/jpackage/share/jdk/jpackage/tests/ModulePathTest2.java b/test/jdk/tools/jpackage/share/ModulePathTest2.java similarity index 97% rename from test/jdk/tools/jpackage/share/jdk/jpackage/tests/ModulePathTest2.java rename to test/jdk/tools/jpackage/share/ModulePathTest2.java index 7b1ec2f5b63..34144907bdb 100644 --- a/test/jdk/tools/jpackage/share/jdk/jpackage/tests/ModulePathTest2.java +++ b/test/jdk/tools/jpackage/share/ModulePathTest2.java @@ -21,7 +21,6 @@ * questions. */ -package jdk.jpackage.tests; import java.io.IOException; import java.nio.file.Path; @@ -40,7 +39,7 @@ * @build jdk.jpackage.test.* * @compile ModulePathTest2.java * @run main/othervm/timeout=360 -Xmx512m jdk.jpackage.test.Main - * --jpt-run=jdk.jpackage.tests.ModulePathTest2 + * --jpt-run=ModulePathTest2 */ public final class ModulePathTest2 { diff --git a/test/jdk/tools/jpackage/share/jdk/jpackage/tests/ModulePathTest3.java b/test/jdk/tools/jpackage/share/ModulePathTest3.java similarity index 98% rename from test/jdk/tools/jpackage/share/jdk/jpackage/tests/ModulePathTest3.java rename to test/jdk/tools/jpackage/share/ModulePathTest3.java index d6fca043920..b4b51e1adfc 100644 --- a/test/jdk/tools/jpackage/share/jdk/jpackage/tests/ModulePathTest3.java +++ b/test/jdk/tools/jpackage/share/ModulePathTest3.java @@ -21,7 +21,6 @@ * questions. */ -package jdk.jpackage.tests; import java.io.IOException; import java.nio.file.Files; @@ -53,7 +52,7 @@ * @build jdk.jpackage.test.* * @compile ModulePathTest3.java * @run main/othervm/timeout=360 -Xmx512m jdk.jpackage.test.Main - * --jpt-run=jdk.jpackage.tests.ModulePathTest3 + * --jpt-run=ModulePathTest3 */ public final class ModulePathTest3 { diff --git a/test/jdk/tools/jpackage/share/jdk/jpackage/tests/MultipleJarAppTest.java b/test/jdk/tools/jpackage/share/MultipleJarAppTest.java similarity index 96% rename from test/jdk/tools/jpackage/share/jdk/jpackage/tests/MultipleJarAppTest.java rename to test/jdk/tools/jpackage/share/MultipleJarAppTest.java index 38878929006..0726b131d69 100644 --- a/test/jdk/tools/jpackage/share/jdk/jpackage/tests/MultipleJarAppTest.java +++ b/test/jdk/tools/jpackage/share/MultipleJarAppTest.java @@ -21,7 +21,6 @@ * questions. */ -package jdk.jpackage.tests; import java.nio.file.Path; import jdk.jpackage.test.Annotations.Test; @@ -37,7 +36,7 @@ * @build jdk.jpackage.test.* * @compile MultipleJarAppTest.java * @run main/othervm/timeout=360 -Xmx512m jdk.jpackage.test.Main - * --jpt-run=jdk.jpackage.tests.MultipleJarAppTest + * --jpt-run=MultipleJarAppTest */ public final class MultipleJarAppTest { diff --git a/test/jdk/tools/jpackage/share/jdk/jpackage/tests/NoMPathRuntimeTest.java b/test/jdk/tools/jpackage/share/NoMPathRuntimeTest.java similarity index 98% rename from test/jdk/tools/jpackage/share/jdk/jpackage/tests/NoMPathRuntimeTest.java rename to test/jdk/tools/jpackage/share/NoMPathRuntimeTest.java index 4a9aef7860d..37319971183 100644 --- a/test/jdk/tools/jpackage/share/jdk/jpackage/tests/NoMPathRuntimeTest.java +++ b/test/jdk/tools/jpackage/share/NoMPathRuntimeTest.java @@ -21,7 +21,6 @@ * questions. */ -package jdk.jpackage.tests; import java.io.IOException; import java.nio.file.Files; @@ -47,7 +46,7 @@ * @build jdk.jpackage.test.* * @compile NoMPathRuntimeTest.java * @run main/othervm/timeout=360 -Xmx512m jdk.jpackage.test.Main - * --jpt-run=jdk.jpackage.tests.NoMPathRuntimeTest + * --jpt-run=NoMPathRuntimeTest */ public final class NoMPathRuntimeTest { diff --git a/test/jdk/tools/jpackage/share/jdk/jpackage/tests/NonExistentTest.java b/test/jdk/tools/jpackage/share/NonExistentTest.java similarity index 97% rename from test/jdk/tools/jpackage/share/jdk/jpackage/tests/NonExistentTest.java rename to test/jdk/tools/jpackage/share/NonExistentTest.java index 8ca18af356c..4d50f2a5850 100644 --- a/test/jdk/tools/jpackage/share/jdk/jpackage/tests/NonExistentTest.java +++ b/test/jdk/tools/jpackage/share/NonExistentTest.java @@ -21,7 +21,6 @@ * questions. */ -package jdk.jpackage.tests; import java.util.Collection; import java.util.List; @@ -37,7 +36,7 @@ * @build jdk.jpackage.test.* * @compile NonExistentTest.java * @run main/othervm/timeout=360 -Xmx512m jdk.jpackage.test.Main - * --jpt-run=jdk.jpackage.tests.NonExistentTest + * --jpt-run=NonExistentTest */ public final class NonExistentTest { diff --git a/test/jdk/tools/jpackage/share/jdk/jpackage/tests/PredefinedAppImageErrorTest.java b/test/jdk/tools/jpackage/share/PredefinedAppImageErrorTest.java similarity index 96% rename from test/jdk/tools/jpackage/share/jdk/jpackage/tests/PredefinedAppImageErrorTest.java rename to test/jdk/tools/jpackage/share/PredefinedAppImageErrorTest.java index b01a78120db..bdb4f6bfbd7 100644 --- a/test/jdk/tools/jpackage/share/jdk/jpackage/tests/PredefinedAppImageErrorTest.java +++ b/test/jdk/tools/jpackage/share/PredefinedAppImageErrorTest.java @@ -21,7 +21,6 @@ * questions. */ -package jdk.jpackage.tests; import java.io.IOException; import java.nio.file.Path; @@ -42,11 +41,11 @@ * @compile PredefinedAppImageErrorTest.java * * @run main/othervm/timeout=360 -Xmx512m jdk.jpackage.test.Main - * --jpt-run=jdk.jpackage.tests.PredefinedAppImageErrorTest + * --jpt-run=PredefinedAppImageErrorTest * --jpt-before-run=jdk.jpackage.test.JPackageCommand.useExecutableByDefault * * @run main/othervm/timeout=360 -Xmx512m jdk.jpackage.test.Main - * --jpt-run=jdk.jpackage.tests.PredefinedAppImageErrorTest + * --jpt-run=PredefinedAppImageErrorTest * --jpt-before-run=jdk.jpackage.test.JPackageCommand.useToolProviderByDefault */ diff --git a/test/jdk/tools/jpackage/share/jdk/jpackage/tests/UnicodeArgsTest.java b/test/jdk/tools/jpackage/share/UnicodeArgsTest.java similarity index 97% rename from test/jdk/tools/jpackage/share/jdk/jpackage/tests/UnicodeArgsTest.java rename to test/jdk/tools/jpackage/share/UnicodeArgsTest.java index 29722086eec..6fa2717d15e 100644 --- a/test/jdk/tools/jpackage/share/jdk/jpackage/tests/UnicodeArgsTest.java +++ b/test/jdk/tools/jpackage/share/UnicodeArgsTest.java @@ -21,7 +21,6 @@ * questions. */ -package jdk.jpackage.tests; import java.util.stream.Collectors; import jdk.jpackage.test.TKit; @@ -38,7 +37,7 @@ * @compile UnicodeArgsTest.java * @requires (os.family == "windows") * @run main/othervm/timeout=720 -Xmx512m jdk.jpackage.test.Main - * --jpt-run=jdk.jpackage.tests.UnicodeArgsTest + * --jpt-run=UnicodeArgsTest */ public final class UnicodeArgsTest { diff --git a/test/jdk/tools/jpackage/share/jdk/jpackage/tests/VendorTest.java b/test/jdk/tools/jpackage/share/VendorTest.java similarity index 96% rename from test/jdk/tools/jpackage/share/jdk/jpackage/tests/VendorTest.java rename to test/jdk/tools/jpackage/share/VendorTest.java index b6e8f44dbf8..4c3a0ffcee2 100644 --- a/test/jdk/tools/jpackage/share/jdk/jpackage/tests/VendorTest.java +++ b/test/jdk/tools/jpackage/share/VendorTest.java @@ -21,7 +21,6 @@ * questions. */ -package jdk.jpackage.tests; import jdk.jpackage.test.PackageTest; import jdk.jpackage.test.PackageType; @@ -61,7 +60,7 @@ * @build jdk.jpackage.test.* * @compile VendorTest.java * @run main/othervm/timeout=360 -Xmx512m jdk.jpackage.test.Main - * --jpt-run=jdk.jpackage.tests.VendorTest + * --jpt-run=VendorTest */ /* @@ -74,7 +73,7 @@ * @build jdk.jpackage.test.* * @compile VendorTest.java * @run main/othervm/timeout=360 -Xmx512m jdk.jpackage.test.Main - * --jpt-run=jdk.jpackage.tests.VendorTest + * --jpt-run=VendorTest */ public class VendorTest { diff --git a/test/jdk/tools/jpackage/windows/WinL10nTest.java b/test/jdk/tools/jpackage/windows/WinL10nTest.java index d951b6f8832..814b6401f47 100644 --- a/test/jdk/tools/jpackage/windows/WinL10nTest.java +++ b/test/jdk/tools/jpackage/windows/WinL10nTest.java @@ -22,7 +22,6 @@ */ import java.io.IOException; -import java.nio.file.Files; import java.nio.file.Path; import jdk.jpackage.test.TKit; import jdk.jpackage.test.PackageTest; @@ -37,8 +36,6 @@ import java.util.stream.Stream; import jdk.jpackage.test.Executor; -import static jdk.jpackage.test.WindowsHelper.getTempDirectory; - /* * @test * @summary Custom l10n of msi installers in jpackage @@ -182,9 +179,8 @@ public void test() throws IOException { } // Preserve config dir to check the set of copied l10n files. - Path tempDir = getTempDirectory(cmd, tempRoot); - Files.createDirectories(tempDir.getParent()); - cmd.addArguments("--temp", tempDir.toString()); + Path tempDir = tempRoot.resolve(cmd.packageType().name()); + cmd.addArguments("--temp", tempDir); }) .addBundleVerifier((cmd, result) -> { if (expectedCultures != null) { @@ -213,7 +209,7 @@ public void test() throws IOException { v.createCmdOutputVerifier(wixSrcDir).apply(getBuildCommandLine(result)); } } - Path tempDir = getTempDirectory(cmd, tempRoot).toAbsolutePath(); + var tempDir = Path.of(cmd.getArgumentValue("--temp")).toAbsolutePath(); for (var v : createDefaultL10nFilesLocVerifiers(tempDir)) { v.apply(getBuildCommandLine(result)); } From da4038873622a19ec10130d617969892583073e1 Mon Sep 17 00:00:00 2001 From: Jaikiran Pai Date: Sat, 16 Nov 2024 01:23:29 +0000 Subject: [PATCH 034/311] 8344315: Clean up sun.net.www.protocol.jrt.JavaRuntimeURLConnection after JEP 486 integration Reviewed-by: dfuchs, alanb --- .../jrt/JavaRuntimeURLConnection.java | 20 +++---------------- 1 file changed, 3 insertions(+), 17 deletions(-) diff --git a/src/java.base/share/classes/sun/net/www/protocol/jrt/JavaRuntimeURLConnection.java b/src/java.base/share/classes/sun/net/www/protocol/jrt/JavaRuntimeURLConnection.java index b4cd98870ca..4e67c962a46 100644 --- a/src/java.base/share/classes/sun/net/www/protocol/jrt/JavaRuntimeURLConnection.java +++ b/src/java.base/share/classes/sun/net/www/protocol/jrt/JavaRuntimeURLConnection.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -30,15 +30,11 @@ import java.io.InputStream; import java.net.MalformedURLException; import java.net.URL; -import java.security.AccessController; -import java.security.Permission; -import java.security.PrivilegedAction; import jdk.internal.jimage.ImageLocation; import jdk.internal.jimage.ImageReader; import jdk.internal.jimage.ImageReaderFactory; -import jdk.internal.loader.URLClassPath; import jdk.internal.loader.Resource; import sun.net.www.ParseUtil; import sun.net.www.URLConnection; @@ -47,15 +43,10 @@ * URLConnection implementation that can be used to connect to resources * contained in the runtime image. */ -@SuppressWarnings("removal") public class JavaRuntimeURLConnection extends URLConnection { // ImageReader to access resources in jimage - private static final ImageReader reader; - static { - PrivilegedAction pa = ImageReaderFactory::getImageReader; - reader = AccessController.doPrivileged(pa); - } + private static final ImageReader reader = ImageReaderFactory.getImageReader(); // the module and resource name in the URL private final String module; @@ -92,7 +83,7 @@ private static Resource findResource(String module, String name) { if (reader != null) { URL url = toJrtURL(module, name); ImageLocation location = reader.findLocation(module, name); - if (location != null && URLClassPath.checkURL(url) != null) { + if (location != null) { return new Resource() { @Override public String getName() { @@ -158,11 +149,6 @@ public int getContentLength() { return len > Integer.MAX_VALUE ? -1 : (int)len; } - @Override - public Permission getPermission() { - return new RuntimePermission("accessSystemModules"); - } - /** * Returns a jrt URL for the given module and resource name. */ From d2e4b51133674381f2e220abc0e07704e5346b05 Mon Sep 17 00:00:00 2001 From: Jaikiran Pai Date: Sat, 16 Nov 2024 01:29:45 +0000 Subject: [PATCH 035/311] 8344186: Cleanup sun.net.www.MimeTable after JEP 486 integration Reviewed-by: dfuchs --- .../share/classes/sun/net/www/MimeTable.java | 49 +++++-------------- 1 file changed, 12 insertions(+), 37 deletions(-) diff --git a/src/java.base/share/classes/sun/net/www/MimeTable.java b/src/java.base/share/classes/sun/net/www/MimeTable.java index 9da69d58aa7..eea633e94fa 100644 --- a/src/java.base/share/classes/sun/net/www/MimeTable.java +++ b/src/java.base/share/classes/sun/net/www/MimeTable.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1994, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1994, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -51,15 +51,8 @@ public class MimeTable implements FileNameMap { private final Hashtable extensionMap = new Hashtable<>(); // Will be reset if in the platform-specific data file - @SuppressWarnings("removal") private static String tempFileTemplate = - java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction() { - public String run() { - return System.getProperty("content.types.temp.file.template", - "/tmp/%s"); - } - }); + System.getProperty("content.types.temp.file.template", "/tmp/%s"); private static final String filePreamble = "sun.net.www MIME content-types table"; @@ -70,16 +63,10 @@ public String run() { private static class DefaultInstanceHolder { static final MimeTable defaultInstance = getDefaultInstance(); - @SuppressWarnings("removal") static MimeTable getDefaultInstance() { - return java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction<>() { - public MimeTable run() { - MimeTable instance = new MimeTable(); - URLConnection.setFileNameMap(instance); - return instance; - } - }); + final MimeTable instance = new MimeTable(); + URLConnection.setFileNameMap(instance); + return instance; } } @@ -235,20 +222,14 @@ public synchronized Enumeration elements() { // For backward compatibility -- mailcap format files // This is not currently used, but may in the future when we add ability // to read BOTH the properties format and the mailcap format. - @SuppressWarnings("removal") protected static String[] mailcapLocations = - java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction() { - public String[] run() { - return new String[]{ - System.getProperty("user.mailcap"), - StaticProperty.userHome() + "/.mailcap", - "/etc/mailcap", - "/usr/etc/mailcap", - "/usr/local/etc/mailcap", - }; - } - }); + new String[]{ + System.getProperty("user.mailcap"), + StaticProperty.userHome() + "/.mailcap", + "/etc/mailcap", + "/usr/etc/mailcap", + "/usr/local/etc/mailcap" + }; public synchronized void load() { Properties entries = new Properties(); @@ -402,12 +383,6 @@ protected boolean saveAsProperties(File file) { Properties properties = getAsProperties(); properties.put("temp.file.template", tempFileTemplate); String tag; - // Perform the property security check for user.name - @SuppressWarnings("removal") - SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - sm.checkPropertyAccess("user.name"); - } String user = StaticProperty.userName(); if (user != null) { tag = "; customized for " + user; From a91d4c022f1ccaec68d7e3ce21be402ffc568eca Mon Sep 17 00:00:00 2001 From: Jaikiran Pai Date: Sat, 16 Nov 2024 11:39:20 +0000 Subject: [PATCH 036/311] 8344233: Remove calls to SecurityManager and doPrivileged in java.net.ProxySelector and sun.net.spi.DefaultProxySelector after JEP 486 integration Reviewed-by: dfuchs --- .../share/classes/java/net/ProxySelector.java | 12 - .../sun/net/spi/DefaultProxySelector.java | 250 ++++++++---------- .../sun/security/util/SecurityConstants.java | 8 - .../net/URLPermission/nstest/LookupTest.java | 1 - 4 files changed, 111 insertions(+), 160 deletions(-) diff --git a/src/java.base/share/classes/java/net/ProxySelector.java b/src/java.base/share/classes/java/net/ProxySelector.java index ee1f9ef3710..613fe2aa176 100644 --- a/src/java.base/share/classes/java/net/ProxySelector.java +++ b/src/java.base/share/classes/java/net/ProxySelector.java @@ -28,8 +28,6 @@ import java.io.IOException; import java.util.List; -import sun.security.util.SecurityConstants; - /** * Selects the proxy server to use, if any, when connecting to the * network resource referenced by a URL. A proxy selector is a @@ -94,11 +92,6 @@ public ProxySelector() {} * @since 1.5 */ public static ProxySelector getDefault() { - @SuppressWarnings("removal") - SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - sm.checkPermission(SecurityConstants.GET_PROXYSELECTOR_PERMISSION); - } return theProxySelector; } @@ -114,11 +107,6 @@ public static ProxySelector getDefault() { * @since 1.5 */ public static void setDefault(ProxySelector ps) { - @SuppressWarnings("removal") - SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - sm.checkPermission(SecurityConstants.SET_PROXYSELECTOR_PERMISSION); - } theProxySelector = ps; } diff --git a/src/java.base/share/classes/sun/net/spi/DefaultProxySelector.java b/src/java.base/share/classes/sun/net/spi/DefaultProxySelector.java index c944bef91e7..763b176331e 100644 --- a/src/java.base/share/classes/sun/net/spi/DefaultProxySelector.java +++ b/src/java.base/share/classes/sun/net/spi/DefaultProxySelector.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -33,8 +33,6 @@ import java.util.Collections; import java.util.List; import java.io.IOException; -import java.security.AccessController; -import java.security.PrivilegedAction; import java.util.Locale; import java.util.StringJoiner; import java.util.regex.Pattern; @@ -93,26 +91,15 @@ public class DefaultProxySelector extends ProxySelector { static { final String key = "java.net.useSystemProxies"; - @SuppressWarnings("removal") - Boolean b = AccessController.doPrivileged( - new PrivilegedAction() { - public Boolean run() { - return NetProperties.getBoolean(key); - }}); + Boolean b = NetProperties.getBoolean(key); if (b != null && b.booleanValue()) { jdk.internal.loader.BootLoader.loadLibrary("net"); hasSystemProxies = init(); } } - @SuppressWarnings("removal") public static int socksProxyVersion() { - return AccessController.doPrivileged( - new PrivilegedAction() { - @Override public Integer run() { - return NetProperties.getInteger(SOCKS_PROXY_VERSION, 5); - } - }); + return NetProperties.getInteger(SOCKS_PROXY_VERSION, 5); } /** @@ -187,148 +174,133 @@ public java.util.List select(URI uri) { throw new IllegalArgumentException("protocol = "+protocol+" host = "+host); } - NonProxyInfo pinfo = null; + NonProxyInfo nonProxyInfo = null; if ("http".equalsIgnoreCase(protocol)) { - pinfo = NonProxyInfo.httpNonProxyInfo; + nonProxyInfo = NonProxyInfo.httpNonProxyInfo; } else if ("https".equalsIgnoreCase(protocol)) { // HTTPS uses the same property as HTTP, for backward // compatibility - pinfo = NonProxyInfo.httpNonProxyInfo; + nonProxyInfo = NonProxyInfo.httpNonProxyInfo; } else if ("ftp".equalsIgnoreCase(protocol)) { - pinfo = NonProxyInfo.ftpNonProxyInfo; + nonProxyInfo = NonProxyInfo.ftpNonProxyInfo; } else if ("socket".equalsIgnoreCase(protocol)) { - pinfo = NonProxyInfo.socksNonProxyInfo; + nonProxyInfo = NonProxyInfo.socksNonProxyInfo; } - - /** - * Let's check the System properties for that protocol - */ - final String proto = protocol; - final NonProxyInfo nprop = pinfo; final String urlhost = host.toLowerCase(Locale.ROOT); - - /** - * This is one big doPrivileged call, but we're trying to optimize - * the code as much as possible. Since we're checking quite a few - * System properties it does help having only 1 call to doPrivileged. - * Be mindful what you do in here though! - */ - @SuppressWarnings("removal") - Proxy[] proxyArray = AccessController.doPrivileged( - new PrivilegedAction() { - public Proxy[] run() { - int i, j; - String phost = null; - int pport = 0; - String nphosts = null; - InetSocketAddress saddr = null; - - // Then let's walk the list of protocols in our array - for (i=0; i Date: Sat, 16 Nov 2024 13:31:06 +0000 Subject: [PATCH 037/311] 8344289: SM cleanup in jdk.internal.util Reviewed-by: liach, rriggs, bpb --- .../jdk/internal/util/ClassFileDumper.java | 67 +++++++------------ .../jdk/internal/util/StaticProperty.java | 66 +----------------- .../internal/util/random/RandomSupport.java | 6 +- 3 files changed, 27 insertions(+), 112 deletions(-) diff --git a/src/java.base/share/classes/jdk/internal/util/ClassFileDumper.java b/src/java.base/share/classes/jdk/internal/util/ClassFileDumper.java index b104b56ac0e..83dafb6b49c 100644 --- a/src/java.base/share/classes/jdk/internal/util/ClassFileDumper.java +++ b/src/java.base/share/classes/jdk/internal/util/ClassFileDumper.java @@ -29,8 +29,6 @@ import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; -import java.security.AccessController; -import java.security.PrivilegedAction; import java.util.HexFormat; import java.util.Objects; import java.util.Set; @@ -79,10 +77,6 @@ public static ClassFileDumper getInstance(String key, String path) { private final AtomicInteger counter = new AtomicInteger(); private ClassFileDumper(String key, String path) { - /* - * GetPropertyAction.privilegedGetProperty cannot be used here, Using VM.getSavedProperty to avoid a bootstrap - * circularity issue in the java/lang/String/concat/WithSecurityManager.java test - */ String value = VM.getSavedProperty(key); this.key = key; boolean enabled = value != null && value.isEmpty() ? true : Boolean.parseBoolean(value); @@ -132,50 +126,39 @@ public void dumpFailedClass(String name, byte[] bytes) { write(pathname(name + ".failed-" + counter.incrementAndGet()), bytes); } - @SuppressWarnings("removal") private void write(Path path, byte[] bytes) { - AccessController.doPrivileged(new PrivilegedAction<>() { - @Override public Void run() { - try { - Files.createDirectories(path.getParent()); - Files.write(path, bytes); - } catch (Exception ex) { - if (VM.isModuleSystemInited()) { - // log only when lambda is ready to use - System.getLogger(ClassFileDumper.class.getName()) - .log(System.Logger.Level.WARNING, "Exception writing to " + - path + " " + ex.getMessage()); - } - // simply don't care if this operation failed - } - return null; - }}); + try { + Files.createDirectories(path.getParent()); + Files.write(path, bytes); + } catch (Exception ex) { + if (VM.isModuleSystemInited()) { + // log only when lambda is ready to use + System.getLogger(ClassFileDumper.class.getName()) + .log(System.Logger.Level.WARNING, "Exception writing to " + + path + " " + ex.getMessage()); + } + // simply don't care if this operation failed + } } /* * Validate if the given dir is a writeable directory if exists. */ - @SuppressWarnings("removal") private static Path validateDumpDir(String dir) { - return AccessController.doPrivileged(new PrivilegedAction<>() { - @Override - public Path run() { - Path path = Path.of(dir); - if (Files.notExists(path)) { - try { - Files.createDirectories(path); - } catch (IOException ex) { - throw new IllegalArgumentException("Fail to create " + path, ex); - } - } - if (!Files.isDirectory(path)) { - throw new IllegalArgumentException("Path " + path + " is not a directory"); - } else if (!Files.isWritable(path)) { - throw new IllegalArgumentException("Directory " + path + " is not writable"); - } - return path; + Path path = Path.of(dir); + if (Files.notExists(path)) { + try { + Files.createDirectories(path); + } catch (IOException ex) { + throw new IllegalArgumentException("Fail to create " + path, ex); } - }); + } + if (!Files.isDirectory(path)) { + throw new IllegalArgumentException("Path " + path + " is not a directory"); + } else if (!Files.isWritable(path)) { + throw new IllegalArgumentException("Directory " + path + " is not writable"); + } + return path; } private static final HexFormat HEX = HexFormat.of().withUpperCase(); diff --git a/src/java.base/share/classes/jdk/internal/util/StaticProperty.java b/src/java.base/share/classes/jdk/internal/util/StaticProperty.java index 9dcebeca470..abe2dafa3b7 100644 --- a/src/java.base/share/classes/jdk/internal/util/StaticProperty.java +++ b/src/java.base/share/classes/jdk/internal/util/StaticProperty.java @@ -32,14 +32,11 @@ * Read-only access to System property values initialized during Phase 1 * are cached. Setting, clearing, or modifying the value using * {@link System#setProperty} or {@link System#getProperties()} is ignored. - * {@link SecurityManager#checkPropertyAccess} is NOT checked - * in these access methods. The caller of these methods should take care to ensure - * that the returned property is not made accessible to untrusted code. */ public final class StaticProperty { // The class static initialization is triggered to initialize these final - // fields during init Phase 1 and before a security manager is set. + // fields during init Phase 1. private static final String JAVA_HOME; private static final String USER_HOME; private static final String USER_DIR; @@ -143,10 +140,6 @@ private static String getProperty(Properties props, String key, /** * {@return the {@code java.home} system property} - * - * {@link SecurityManager#checkPropertyAccess} is NOT checked - * in this method. The caller of this method should take care to ensure - * that the returned property is not made accessible to untrusted code. */ public static String javaHome() { return JAVA_HOME; @@ -154,10 +147,6 @@ public static String javaHome() { /** * {@return the {@code user.home} system property} - * - * {@link SecurityManager#checkPropertyAccess} is NOT checked - * in this method. The caller of this method should take care to ensure - * that the returned property is not made accessible to untrusted code. */ public static String userHome() { return USER_HOME; @@ -165,10 +154,6 @@ public static String userHome() { /** * {@return the {@code user.dir} system property} - * - * {@link SecurityManager#checkPropertyAccess} is NOT checked - * in this method. The caller of this method should take care to ensure - * that the returned property is not made accessible to untrusted code. */ public static String userDir() { return USER_DIR; @@ -176,10 +161,6 @@ public static String userDir() { /** * {@return the {@code user.name} system property} - * - * {@link SecurityManager#checkPropertyAccess} is NOT checked - * in this method. The caller of this method should take care to ensure - * that the returned property is not made accessible to untrusted code. */ public static String userName() { return USER_NAME; @@ -187,10 +168,6 @@ public static String userName() { /** * {@return the {@code java.library.path} system property} - * - * {@link SecurityManager#checkPropertyAccess} is NOT checked - * in this method. The caller of this method should take care to ensure - * that the returned property is not made accessible to untrusted code. */ public static String javaLibraryPath() { return JAVA_LIBRARY_PATH; @@ -198,10 +175,6 @@ public static String javaLibraryPath() { /** * {@return the {@code java.io.tmpdir} system property} - * - * {@link SecurityManager#checkPropertyAccess} is NOT checked - * in this method. The caller of this method should take care to ensure - * that the returned property is not made accessible to untrusted code. */ public static String javaIoTmpDir() { return JAVA_IO_TMPDIR; @@ -209,10 +182,6 @@ public static String javaIoTmpDir() { /** * {@return the {@code sun.boot.library.path} system property} - * - * {@link SecurityManager#checkPropertyAccess} is NOT checked - * in this method. The caller of this method should take care to ensure - * that the returned property is not made accessible to untrusted code. */ public static String sunBootLibraryPath() { return SUN_BOOT_LIBRARY_PATH; @@ -221,10 +190,6 @@ public static String sunBootLibraryPath() { /** * {@return the {@code jdk.serialFilter} system property} - * - * {@link SecurityManager#checkPropertyAccess} is NOT checked - * in this method. The caller of this method should take care to ensure - * that the returned property is not made accessible to untrusted code. */ public static String jdkSerialFilter() { return JDK_SERIAL_FILTER; @@ -233,10 +198,6 @@ public static String jdkSerialFilter() { /** * {@return the {@code jdk.serialFilterFactory} system property} - * - * {@link SecurityManager#checkPropertyAccess} is NOT checked - * in this method. The caller of this method should take care to ensure - * that the returned property is not made accessible to untrusted code. */ public static String jdkSerialFilterFactory() { return JDK_SERIAL_FILTER_FACTORY; @@ -244,10 +205,6 @@ public static String jdkSerialFilterFactory() { /** * {@return the {@code native.encoding} system property} - * - * {@link SecurityManager#checkPropertyAccess} is NOT checked - * in this method. The caller of this method should take care to ensure - * that the returned property is not made accessible to untrusted code. */ public static String nativeEncoding() { return NATIVE_ENCODING; @@ -255,10 +212,6 @@ public static String nativeEncoding() { /** * {@return the {@code file.encoding} system property} - * - * {@link SecurityManager#checkPropertyAccess} is NOT checked - * in this method. The caller of this method should take care to ensure - * that the returned property is not made accessible to untrusted code. */ public static String fileEncoding() { return FILE_ENCODING; @@ -266,9 +219,6 @@ public static String fileEncoding() { /** * {@return the {@code java.properties.date} system property} - * - * {@link SecurityManager#checkPropertyAccess} is NOT checked - * in this method. */ public static String javaPropertiesDate() { return JAVA_PROPERTIES_DATE; @@ -276,10 +226,6 @@ public static String javaPropertiesDate() { /** * {@return the {@code sun.jnu.encoding} system property} - * - * {@link SecurityManager#checkPropertyAccess} is NOT checked - * in this method. The caller of this method should take care to ensure - * that the returned property is not made accessible to untrusted code. */ public static String jnuEncoding() { return SUN_JNU_ENCODING; @@ -287,10 +233,6 @@ public static String jnuEncoding() { /** * {@return the {@code java.locale.useOldISOCodes} system property} - * - * {@link SecurityManager#checkPropertyAccess} is NOT checked - * in this method. The caller of this method should take care to ensure - * that the returned property is not made accessible to untrusted code. */ public static String javaLocaleUseOldISOCodes() { return JAVA_LOCALE_USE_OLD_ISO_CODES; @@ -298,8 +240,6 @@ public static String javaLocaleUseOldISOCodes() { /** * {@return the {@code os.name} system property} - * {@link SecurityManager#checkPropertyAccess} is NOT checked - * in this method. This property is not considered security sensitive. */ public static String osName() { return OS_NAME; @@ -307,8 +247,6 @@ public static String osName() { /** * {@return the {@code os.arch} system property} - * {@link SecurityManager#checkPropertyAccess} is NOT checked - * in this method. This property is not considered security sensitive. */ public static String osArch() { return OS_ARCH; @@ -316,8 +254,6 @@ public static String osArch() { /** * {@return the {@code os.version} system property} - * {@link SecurityManager#checkPropertyAccess} is NOT checked - * in this method. This property is not considered security sensitive. */ public static String osVersion() { return OS_VERSION; diff --git a/src/java.base/share/classes/jdk/internal/util/random/RandomSupport.java b/src/java.base/share/classes/jdk/internal/util/random/RandomSupport.java index 402be6b5dfe..71c4c8fbbbb 100644 --- a/src/java.base/share/classes/jdk/internal/util/random/RandomSupport.java +++ b/src/java.base/share/classes/jdk/internal/util/random/RandomSupport.java @@ -725,11 +725,7 @@ public static float boundedNextFloat(RandomGenerator rng, float bound) { // The following decides which of two strategies initialSeed() will use. private static boolean secureRandomSeedRequested() { - @SuppressWarnings("removal") - String pp = java.security.AccessController.doPrivileged( - new sun.security.action.GetPropertyAction( - "java.util.secureRandomSeed")); - return (pp != null && pp.equalsIgnoreCase("true")); + return Boolean.getBoolean("java.util.secureRandomSeed"); } private static final boolean useSecureRandomSeed = secureRandomSeedRequested(); From fec0d1cf5b1e219db3f58c271939b0dbb291404e Mon Sep 17 00:00:00 2001 From: Nizar Benalla Date: Sat, 16 Nov 2024 20:27:26 +0000 Subject: [PATCH 038/311] 8343777: Add since checker tests to Internationalisation modules Reviewed-by: jlu, naoto --- .../jdk.charsets/JdkCharsetsCheckSince.java | 30 +++++++++++++++++++ .../JdkLocaledataCheckSince.java | 30 +++++++++++++++++++ 2 files changed, 60 insertions(+) create mode 100644 test/jdk/tools/sincechecker/modules/jdk.charsets/JdkCharsetsCheckSince.java create mode 100644 test/jdk/tools/sincechecker/modules/jdk.localedata/JdkLocaledataCheckSince.java diff --git a/test/jdk/tools/sincechecker/modules/jdk.charsets/JdkCharsetsCheckSince.java b/test/jdk/tools/sincechecker/modules/jdk.charsets/JdkCharsetsCheckSince.java new file mode 100644 index 00000000000..b9b47998ace --- /dev/null +++ b/test/jdk/tools/sincechecker/modules/jdk.charsets/JdkCharsetsCheckSince.java @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8343777 + * @summary Test for `@since` declaration in the module-info.java file of jdk.charsets + * @library /test/lib /test/jdk/tools/sincechecker + * @run main SinceChecker jdk.charsets + */ diff --git a/test/jdk/tools/sincechecker/modules/jdk.localedata/JdkLocaledataCheckSince.java b/test/jdk/tools/sincechecker/modules/jdk.localedata/JdkLocaledataCheckSince.java new file mode 100644 index 00000000000..209333b2541 --- /dev/null +++ b/test/jdk/tools/sincechecker/modules/jdk.localedata/JdkLocaledataCheckSince.java @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8343777 + * @summary Test for `@since` declaration in the module-info.java file of jdk.localedata + * @library /test/lib /test/jdk/tools/sincechecker + * @run main SinceChecker jdk.localedata + */ From aa10ec7c96bc50057e07fe2733079a1b3fa13a03 Mon Sep 17 00:00:00 2001 From: Prasanta Sadhukhan Date: Sun, 17 Nov 2024 08:52:48 +0000 Subject: [PATCH 039/311] 8343123: Nimbus: javax/swing/JInternalFrame/bug6726866.java does not have green undecorated window Reviewed-by: tr, dnguyen --- .../swing/plaf/nimbus/SynthPainterImpl.java | 23 +++++++++++++++---- .../swing/JInternalFrame/bug6726866.java | 3 +-- 2 files changed, 19 insertions(+), 7 deletions(-) diff --git a/src/java.desktop/share/classes/javax/swing/plaf/nimbus/SynthPainterImpl.java b/src/java.desktop/share/classes/javax/swing/plaf/nimbus/SynthPainterImpl.java index 9dfd422f6dd..96ef2541c7b 100644 --- a/src/java.desktop/share/classes/javax/swing/plaf/nimbus/SynthPainterImpl.java +++ b/src/java.desktop/share/classes/javax/swing/plaf/nimbus/SynthPainterImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -24,12 +24,21 @@ */ package javax.swing.plaf.nimbus; -import java.awt.*; +import java.awt.Color; +import java.awt.Component; +import java.awt.Graphics; +import java.awt.Graphics2D; import java.awt.geom.AffineTransform; import java.awt.geom.NoninvertibleTransformException; import java.awt.image.BufferedImage; -import java.util.*; -import javax.swing.*; +import javax.swing.JDesktopPane; +import javax.swing.JSlider; +import javax.swing.JSplitPane; +import javax.swing.JTabbedPane; +import javax.swing.Painter; +import javax.swing.SwingConstants; +import javax.swing.UIManager; +import javax.swing.plaf.UIResource; import javax.swing.plaf.synth.SynthContext; import javax.swing.plaf.synth.SynthPainter; import javax.swing.plaf.synth.SynthConstants; @@ -531,7 +540,11 @@ public void paintDesktopIconBorder(SynthContext context, public void paintDesktopPaneBackground(SynthContext context, Graphics g, int x, int y, int w, int h) { - paintBackground(context, g, x, y, w, h, null); + if (context.getComponent() instanceof JDesktopPane pane) { + if (pane.getBackground() instanceof UIResource) { + paintBackground(context, g, x, y, w, h, null); + } + } } /** diff --git a/test/jdk/javax/swing/JInternalFrame/bug6726866.java b/test/jdk/javax/swing/JInternalFrame/bug6726866.java index 88b890d7b2c..a8f267fedc2 100644 --- a/test/jdk/javax/swing/JInternalFrame/bug6726866.java +++ b/test/jdk/javax/swing/JInternalFrame/bug6726866.java @@ -23,7 +23,7 @@ /* * @test - * @bug 6726866 8186617 + * @bug 6726866 8186617 8343123 * @summary Repainting artifacts when resizing or dragging JInternalFrames in non-opaque toplevel * @library /java/awt/regtesthelpers @@ -34,7 +34,6 @@ import java.awt.Color; import java.awt.Window; -import javax.swing.JApplet; import javax.swing.JDesktopPane; import javax.swing.JFrame; import javax.swing.JInternalFrame; From 41a627b7890ab7fefef49e3bac3aad8403d0e82e Mon Sep 17 00:00:00 2001 From: Alexey Semenyuk Date: Sun, 17 Nov 2024 23:46:49 +0000 Subject: [PATCH 040/311] 8343876: Enhancements to jpackage test lib Reviewed-by: almatvee --- .../jdk/jpackage/test/AnnotationsTest.java | 408 ++++++++++++++ .../jdk/jpackage/test/Annotations.java | 50 +- .../helpers/jdk/jpackage/test/Comm.java | 39 ++ .../jdk/jpackage/test/LinuxHelper.java | 43 +- .../helpers/jdk/jpackage/test/Main.java | 42 +- .../helpers/jdk/jpackage/test/MethodCall.java | 236 +++++--- .../helpers/jdk/jpackage/test/TKit.java | 31 +- .../jdk/jpackage/test/TestBuilder.java | 215 ++------ .../jdk/jpackage/test/TestBuilderConfig.java | 62 +++ .../jdk/jpackage/test/TestInstance.java | 41 +- .../jdk/jpackage/test/TestMethodSupplier.java | 510 ++++++++++++++++++ .../tools/jpackage/share/InOutPathTest.java | 93 ++-- .../tools/jpackage/share/InstallDirTest.java | 29 +- 13 files changed, 1462 insertions(+), 337 deletions(-) create mode 100644 test/jdk/tools/jpackage/helpers-test/jdk/jpackage/test/AnnotationsTest.java create mode 100644 test/jdk/tools/jpackage/helpers/jdk/jpackage/test/Comm.java create mode 100644 test/jdk/tools/jpackage/helpers/jdk/jpackage/test/TestBuilderConfig.java create mode 100644 test/jdk/tools/jpackage/helpers/jdk/jpackage/test/TestMethodSupplier.java diff --git a/test/jdk/tools/jpackage/helpers-test/jdk/jpackage/test/AnnotationsTest.java b/test/jdk/tools/jpackage/helpers-test/jdk/jpackage/test/AnnotationsTest.java new file mode 100644 index 00000000000..2d23f49cdd7 --- /dev/null +++ b/test/jdk/tools/jpackage/helpers-test/jdk/jpackage/test/AnnotationsTest.java @@ -0,0 +1,408 @@ +/* + * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.jpackage.test; + +import static java.lang.StackWalker.Option.RETAIN_CLASS_REFERENCE; +import java.lang.reflect.Method; +import java.nio.file.Path; +import java.time.LocalDate; +import java.util.Arrays; +import java.util.Collection; +import java.util.HashSet; +import java.util.List; +import java.util.Optional; +import java.util.Set; +import static java.util.stream.Collectors.toMap; +import java.util.stream.Stream; +import jdk.internal.util.OperatingSystem; +import static jdk.internal.util.OperatingSystem.LINUX; +import jdk.jpackage.test.Annotations.Parameter; +import jdk.jpackage.test.Annotations.ParameterSupplier; +import jdk.jpackage.test.Annotations.Parameters; +import jdk.jpackage.test.Annotations.Test; +import static jdk.jpackage.test.Functional.ThrowingSupplier.toSupplier; + +/* + * @test + * @summary Test jpackage test library's annotation processor + * @library /test/jdk/tools/jpackage/helpers + * @build jdk.jpackage.test.* + * @run main/othervm/timeout=360 -Xmx512m jdk.jpackage.test.AnnotationsTest + */ +public class AnnotationsTest { + + public static void main(String... args) { + runTests(BasicTest.class, ParameterizedInstanceTest.class); + for (var os : OperatingSystem.values()) { + try { + TestBuilderConfig.setOperatingSystem(os); + TKit.log("Current operating system: " + os); + runTests(IfOSTest.class); + } finally { + TestBuilderConfig.setDefaults(); + } + } + } + + public static class BasicTest extends TestExecutionRecorder { + @Test + public void testNoArg() { + recordTestCase(); + } + + @Test + @Parameter("TRUE") + public int testNoArg(boolean v) { + recordTestCase(v); + return 0; + } + + @Test + @Parameter({}) + @Parameter("a") + @Parameter({"b", "c"}) + public void testVarArg(Path ... paths) { + recordTestCase((Object[]) paths); + } + + @Test + @Parameter({"12", "foo"}) + @Parameter({"-89", "bar", "more"}) + @Parameter({"-89", "bar", "more", "moore"}) + public void testVarArg2(int a, String b, String ... other) { + recordTestCase(a, b, other); + } + + @Test + @ParameterSupplier("dateSupplier") + @ParameterSupplier("jdk.jpackage.test.AnnotationsTest.dateSupplier") + public void testDates(LocalDate v) { + recordTestCase(v); + } + + public static Set getExpectedTestDescs() { + return Set.of( + "().testNoArg()", + "().testNoArg(true)", + "().testVarArg()", + "().testVarArg(a)", + "().testVarArg(b, c)", + "().testVarArg2(-89, bar, [more, moore](length=2))", + "().testVarArg2(-89, bar, [more](length=1))", + "().testVarArg2(12, foo, [](length=0))", + "().testDates(2018-05-05)", + "().testDates(2018-07-11)", + "().testDates(2034-05-05)", + "().testDates(2056-07-11)" + ); + } + + public static Collection dateSupplier() { + return List.of(new Object[][] { + { LocalDate.parse("2018-05-05") }, + { LocalDate.parse("2018-07-11") }, + }); + } + } + + public static class ParameterizedInstanceTest extends TestExecutionRecorder { + public ParameterizedInstanceTest(String... args) { + super((Object[]) args); + } + + public ParameterizedInstanceTest(int o) { + super(o); + } + + public ParameterizedInstanceTest(int a, Boolean[] b, String c, String ... other) { + super(a, b, c, other); + } + + @Test + public void testNoArgs() { + recordTestCase(); + } + + @Test + @ParameterSupplier("jdk.jpackage.test.AnnotationsTest.dateSupplier") + public void testDates(LocalDate v) { + recordTestCase(v); + } + + @Test + @Parameter("a") + public static void staticTest(String arg) { + staticRecorder.recordTestCase(arg); + } + + @Parameters + public static Collection input() { + return List.of(new Object[][] { + {}, + {55, new Boolean[]{false, true, false}, "foo", "bar"}, + {78}, + }); + } + + @Parameters + public static Collection input2() { + return List.of(new Object[][] { + {51, new boolean[]{true, true, true}, "foo"}, + {33}, + {55, null, null }, + {55, null, null, "1" }, + }); + } + + public static Set getExpectedTestDescs() { + return Set.of( + "().testNoArgs()", + "(33).testNoArgs()", + "(78).testNoArgs()", + "(55, [false, true, false](length=3), foo, [bar](length=1)).testNoArgs()", + "(51, [true, true, true](length=3), foo, [](length=0)).testNoArgs()", + "().testDates(2034-05-05)", + "().testDates(2056-07-11)", + "(33).testDates(2034-05-05)", + "(33).testDates(2056-07-11)", + "(51, [true, true, true](length=3), foo, [](length=0)).testDates(2034-05-05)", + "(51, [true, true, true](length=3), foo, [](length=0)).testDates(2056-07-11)", + "(55, [false, true, false](length=3), foo, [bar](length=1)).testDates(2034-05-05)", + "(55, [false, true, false](length=3), foo, [bar](length=1)).testDates(2056-07-11)", + "(78).testDates(2034-05-05)", + "(78).testDates(2056-07-11)", + "(55, null, null, [1](length=1)).testDates(2034-05-05)", + "(55, null, null, [1](length=1)).testDates(2056-07-11)", + "(55, null, null, [1](length=1)).testNoArgs()", + "(55, null, null, [](length=0)).testDates(2034-05-05)", + "(55, null, null, [](length=0)).testDates(2056-07-11)", + "(55, null, null, [](length=0)).testNoArgs()", + "().staticTest(a)" + ); + } + + private final static TestExecutionRecorder staticRecorder = new TestExecutionRecorder(ParameterizedInstanceTest.class); + } + + public static class IfOSTest extends TestExecutionRecorder { + public IfOSTest(int a, String b) { + super(a, b); + } + + @Test(ifOS = OperatingSystem.LINUX) + public void testNoArgs() { + recordTestCase(); + } + + @Test(ifNotOS = OperatingSystem.LINUX) + public void testNoArgs2() { + recordTestCase(); + } + + @Test + @Parameter(value = "foo", ifOS = OperatingSystem.LINUX) + @Parameter(value = {"foo", "bar"}, ifOS = { OperatingSystem.LINUX, OperatingSystem.MACOS }) + @Parameter(value = {}, ifNotOS = { OperatingSystem.WINDOWS }) + public void testVarArgs(String ... args) { + recordTestCase((Object[]) args); + } + + @Test + @ParameterSupplier(value = "jdk.jpackage.test.AnnotationsTest.dateSupplier", ifOS = OperatingSystem.WINDOWS) + public void testDates(LocalDate v) { + recordTestCase(v); + } + + @Parameters(ifOS = OperatingSystem.LINUX) + public static Collection input() { + return Set.of(new Object[][] { + {7, null}, + }); + } + + @Parameters(ifNotOS = {OperatingSystem.LINUX, OperatingSystem.MACOS}) + public static Collection input2() { + return Set.of(new Object[][] { + {10, "hello"}, + }); + } + + @Parameters(ifNotOS = OperatingSystem.LINUX) + public static Collection input3() { + return Set.of(new Object[][] { + {15, "bye"}, + }); + } + + public static Set getExpectedTestDescs() { + switch (TestBuilderConfig.getDefault().getOperatingSystem()) { + case LINUX -> { + return Set.of( + "(7, null).testNoArgs()", + "(7, null).testVarArgs()", + "(7, null).testVarArgs(foo)", + "(7, null).testVarArgs(foo, bar)" + ); + } + + case MACOS -> { + return Set.of( + "(15, bye).testNoArgs2()", + "(15, bye).testVarArgs()", + "(15, bye).testVarArgs(foo, bar)" + ); + } + + case WINDOWS -> { + return Set.of( + "(15, bye).testDates(2034-05-05)", + "(15, bye).testDates(2056-07-11)", + "(15, bye).testNoArgs2()", + "(10, hello).testDates(2034-05-05)", + "(10, hello).testDates(2056-07-11)", + "(10, hello).testNoArgs2()" + ); + } + + case AIX -> { + return Set.of( + ); + } + } + + throw new UnsupportedOperationException(); + } + } + + public static Collection dateSupplier() { + return List.of(new Object[][] { + { LocalDate.parse("2034-05-05") }, + { LocalDate.parse("2056-07-11") }, + }); + } + + private static void runTests(Class... tests) { + ACTUAL_TEST_DESCS.get().clear(); + + var expectedTestDescs = Stream.of(tests) + .map(AnnotationsTest::getExpectedTestDescs) + .flatMap(x -> x) + // Collect in the map to check for collisions for free + .collect(toMap(x -> x, x -> "")) + .keySet(); + + var args = Stream.of(tests).map(test -> { + return String.format("--jpt-run=%s", test.getName()); + }).toArray(String[]::new); + + try { + Main.main(args); + assertRecordedTestDescs(expectedTestDescs); + } catch (Throwable t) { + t.printStackTrace(System.err); + System.exit(1); + } + } + + private static Stream getExpectedTestDescs(Class type) { + return toSupplier(() -> { + var method = type.getMethod("getExpectedTestDescs"); + var testDescPefix = type.getName(); + return ((Set)method.invoke(null)).stream().map(desc -> { + return testDescPefix + desc; + }); + }).get(); + } + + private static void assertRecordedTestDescs(Set expectedTestDescs) { + var comm = Comm.compare(expectedTestDescs, ACTUAL_TEST_DESCS.get()); + if (!comm.unique1().isEmpty()) { + System.err.println("Missing test case signatures:"); + comm.unique1().stream().sorted().sequential().forEachOrdered(System.err::println); + System.err.println("<>"); + } + + if (!comm.unique2().isEmpty()) { + System.err.println("Unexpected test case signatures:"); + comm.unique2().stream().sorted().sequential().forEachOrdered(System.err::println); + System.err.println("<>"); + } + + if (!comm.unique2().isEmpty() || !comm.unique1().isEmpty()) { + // Don't use TKit asserts as this call is outside the test execution + throw new AssertionError("Test case signatures mismatched"); + } + } + + private static class TestExecutionRecorder { + protected TestExecutionRecorder(Object ... args) { + this.testClass = getClass(); + this.testDescBuilder = TestInstance.TestDesc.createBuilder().ctorArgs(args); + } + + TestExecutionRecorder(Class testClass) { + this.testClass = testClass; + this.testDescBuilder = TestInstance.TestDesc.createBuilder().ctorArgs(); + } + + protected void recordTestCase(Object ... args) { + testDescBuilder.methodArgs(args).method(getCurrentTestCase()); + var testCaseDescs = ACTUAL_TEST_DESCS.get(); + var testCaseDesc = testDescBuilder.get().testFullName(); + TKit.assertTrue(!testCaseDescs.contains(testCaseDesc), String.format( + "Check this test case is executed for the first time", + testCaseDesc)); + TKit.assertTrue(!executed, "Check this test case instance is not reused"); + executed = true; + testCaseDescs.add(testCaseDesc); + } + + private Method getCurrentTestCase() { + return StackWalker.getInstance(RETAIN_CLASS_REFERENCE).walk(frames -> { + return frames.map(frame -> { + var methodType = frame.getMethodType(); + var methodName = frame.getMethodName(); + var methodReturn = methodType.returnType(); + var methodParameters = methodType.parameterArray(); + return Stream.of(testClass.getDeclaredMethods()).filter(method -> { + return method.getName().equals(methodName) + && method.getReturnType().equals(methodReturn) + && Arrays.equals(method.getParameterTypes(), methodParameters) + && method.isAnnotationPresent(Test.class); + }).findFirst(); + }).dropWhile(Optional::isEmpty).map(Optional::get).findFirst(); + }).get(); + } + + private boolean executed; + private final TestInstance.TestDesc.Builder testDescBuilder; + private final Class testClass; + } + + private static final ThreadLocal> ACTUAL_TEST_DESCS = new ThreadLocal<>() { + @Override + protected Set initialValue() { + return new HashSet<>(); + } + }; +} diff --git a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/Annotations.java b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/Annotations.java index d29133ee3e1..ad1e77b4171 100644 --- a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/Annotations.java +++ b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/Annotations.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -27,6 +27,7 @@ import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; +import jdk.internal.util.OperatingSystem; public class Annotations { @@ -43,6 +44,14 @@ public class Annotations { @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) public @interface Test { + + OperatingSystem[] ifOS() default { + OperatingSystem.LINUX, + OperatingSystem.WINDOWS, + OperatingSystem.MACOS + }; + + OperatingSystem[] ifNotOS() default {}; } @Retention(RetentionPolicy.RUNTIME) @@ -51,6 +60,14 @@ public class Annotations { public @interface Parameter { String[] value(); + + OperatingSystem[] ifOS() default { + OperatingSystem.LINUX, + OperatingSystem.WINDOWS, + OperatingSystem.MACOS + }; + + OperatingSystem[] ifNotOS() default {}; } @Retention(RetentionPolicy.RUNTIME) @@ -60,8 +77,39 @@ public class Annotations { Parameter[] value(); } + @Retention(RetentionPolicy.RUNTIME) + @Target(ElementType.METHOD) + @Repeatable(ParameterSupplierGroup.class) + public @interface ParameterSupplier { + + String value(); + + OperatingSystem[] ifOS() default { + OperatingSystem.LINUX, + OperatingSystem.WINDOWS, + OperatingSystem.MACOS + }; + + OperatingSystem[] ifNotOS() default {}; + } + + @Retention(RetentionPolicy.RUNTIME) + @Target(ElementType.METHOD) + public @interface ParameterSupplierGroup { + + ParameterSupplier[] value(); + } + @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.METHOD) public @interface Parameters { + + OperatingSystem[] ifOS() default { + OperatingSystem.LINUX, + OperatingSystem.WINDOWS, + OperatingSystem.MACOS + }; + + OperatingSystem[] ifNotOS() default {}; } } diff --git a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/Comm.java b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/Comm.java new file mode 100644 index 00000000000..23798f326fe --- /dev/null +++ b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/Comm.java @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.jpackage.test; + +import java.util.HashSet; +import java.util.Set; + +record Comm(Set common, Set unique1, Set unique2) { + + static Comm compare(Set a, Set b) { + Set common = new HashSet<>(a); + common.retainAll(b); + Set unique1 = new HashSet<>(a); + unique1.removeAll(common); + Set unique2 = new HashSet<>(b); + unique2.removeAll(common); + return new Comm(common, unique1, unique2); + } +} diff --git a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/LinuxHelper.java b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/LinuxHelper.java index bf5ced09bc7..a96bab49355 100644 --- a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/LinuxHelper.java +++ b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/LinuxHelper.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -40,6 +40,7 @@ import java.util.regex.Pattern; import java.util.stream.Collectors; import java.util.stream.Stream; +import jdk.jpackage.internal.ApplicationLayout; import jdk.jpackage.internal.IOUtils; import jdk.jpackage.test.Functional.ThrowingConsumer; import jdk.jpackage.test.PackageTest.PackageHandlers; @@ -399,6 +400,15 @@ static void addBundleDesktopIntegrationVerifier(PackageTest test, private static void verifyDesktopFile(JPackageCommand cmd, Path desktopFile) throws IOException { TKit.trace(String.format("Check [%s] file BEGIN", desktopFile)); + + var launcherName = Stream.of(List.of(cmd.name()), cmd.addLauncherNames()).flatMap(List::stream).filter(name -> { + return getDesktopFile(cmd, name).equals(desktopFile); + }).findAny(); + if (!cmd.hasArgument("--app-image")) { + TKit.assertTrue(launcherName.isPresent(), + "Check the desktop file corresponds to one of app launchers"); + } + List lines = Files.readAllLines(desktopFile); TKit.assertEquals("[Desktop Entry]", lines.get(0), "Check file header"); @@ -428,7 +438,7 @@ private static void verifyDesktopFile(JPackageCommand cmd, Path desktopFile) "Check value of [%s] key", key)); } - // Verify value of `Exec` property in .desktop files are escaped if required + // Verify the value of `Exec` key is escaped if required String launcherPath = data.get("Exec"); if (Pattern.compile("\\s").matcher(launcherPath).find()) { TKit.assertTrue(launcherPath.startsWith("\"") @@ -437,10 +447,25 @@ private static void verifyDesktopFile(JPackageCommand cmd, Path desktopFile) launcherPath = launcherPath.substring(1, launcherPath.length() - 1); } - Stream.of(launcherPath, data.get("Icon")) - .map(Path::of) - .map(cmd::pathToUnpackedPackageFile) - .forEach(TKit::assertFileExists); + if (launcherName.isPresent()) { + TKit.assertEquals(launcherPath, cmd.pathToPackageFile( + cmd.appLauncherPath(launcherName.get())).toString(), + String.format( + "Check the value of [Exec] key references [%s] app launcher", + launcherName.get())); + } + + for (var e : List.>, Function>>of( + Map.entry(Map.entry("Exec", Optional.of(launcherPath)), ApplicationLayout::launchersDirectory), + Map.entry(Map.entry("Icon", Optional.empty()), ApplicationLayout::destktopIntegrationDirectory))) { + var path = e.getKey().getValue().or(() -> Optional.of(data.get( + e.getKey().getKey()))).map(Path::of).get(); + TKit.assertFileExists(cmd.pathToUnpackedPackageFile(path)); + Path expectedDir = cmd.pathToPackageFile(e.getValue().apply(cmd.appLayout())); + TKit.assertTrue(path.getParent().equals(expectedDir), String.format( + "Check the value of [%s] key references a file in [%s] folder", + e.getKey().getKey(), expectedDir)); + } TKit.trace(String.format("Check [%s] file END", desktopFile)); } @@ -725,10 +750,10 @@ private static Method initGetServiceUnitFileName() { private static Map archs; - private final static Pattern XDG_CMD_ICON_SIZE_PATTERN = Pattern.compile("\\s--size\\s+(\\d+)\\b"); + private static final Pattern XDG_CMD_ICON_SIZE_PATTERN = Pattern.compile("\\s--size\\s+(\\d+)\\b"); // Values grabbed from https://linux.die.net/man/1/xdg-icon-resource - private final static Set XDG_CMD_VALID_ICON_SIZES = Set.of(16, 22, 32, 48, 64, 128); + private static final Set XDG_CMD_VALID_ICON_SIZES = Set.of(16, 22, 32, 48, 64, 128); - private final static Method getServiceUnitFileName = initGetServiceUnitFileName(); + private static final Method getServiceUnitFileName = initGetServiceUnitFileName(); } diff --git a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/Main.java b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/Main.java index 37aca48ac17..5919d8361c4 100644 --- a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/Main.java +++ b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/Main.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,11 +23,17 @@ package jdk.jpackage.test; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.ArrayDeque; import java.util.ArrayList; +import java.util.Comparator; +import java.util.Deque; import java.util.List; import java.util.function.Function; import java.util.function.Predicate; -import java.util.stream.Collectors; +import static java.util.stream.Collectors.toCollection; +import java.util.stream.Stream; import static jdk.jpackage.test.TestBuilder.CMDLINE_ARG_PREFIX; @@ -36,7 +42,9 @@ public static void main(String args[]) throws Throwable { boolean listTests = false; List tests = new ArrayList<>(); try (TestBuilder testBuilder = new TestBuilder(tests::add)) { - for (var arg : args) { + Deque argsAsList = new ArrayDeque<>(List.of(args)); + while (!argsAsList.isEmpty()) { + var arg = argsAsList.pop(); TestBuilder.trace(String.format("Parsing [%s]...", arg)); if ((CMDLINE_ARG_PREFIX + "list").equals(arg)) { @@ -44,6 +52,29 @@ public static void main(String args[]) throws Throwable { continue; } + if (arg.startsWith("@")) { + // Command file + // @=args will read arguments from the "args" file, one argument per line + // @args will read arguments from the "args" file, splitting lines into arguments at whitespaces + arg = arg.substring(1); + var oneArgPerLine = arg.startsWith("="); + if (oneArgPerLine) { + arg = arg.substring(1); + } + + var newArgsStream = Files.readAllLines(Path.of(arg)).stream(); + if (!oneArgPerLine) { + newArgsStream.map(line -> { + return Stream.of(line.split("\\s+")); + }).flatMap(x -> x); + } + + var newArgs = newArgsStream.collect(toCollection(ArrayDeque::new)); + newArgs.addAll(argsAsList); + argsAsList = newArgs; + continue; + } + boolean success = false; try { testBuilder.processCmdLineArg(arg); @@ -62,12 +93,11 @@ public static void main(String args[]) throws Throwable { // Order tests by their full names to have stable test sequence. List orderedTests = tests.stream() - .sorted((a, b) -> a.fullName().compareTo(b.fullName())) - .collect(Collectors.toList()); + .sorted(Comparator.comparing(TestInstance::fullName)).toList(); if (listTests) { // Just list the tests - orderedTests.stream().forEach(test -> System.out.println(String.format( + orderedTests.forEach(test -> System.out.println(String.format( "%s; workDir=[%s]", test.fullName(), test.workDir()))); return; } diff --git a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/MethodCall.java b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/MethodCall.java index 2aaba054a9b..d5b8bd702c8 100644 --- a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/MethodCall.java +++ b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/MethodCall.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,34 +22,33 @@ */ package jdk.jpackage.test; +import java.lang.reflect.Array; import java.lang.reflect.Constructor; +import java.lang.reflect.Executable; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.util.Arrays; -import java.util.List; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; import java.util.Objects; import java.util.Optional; -import java.util.function.Supplier; -import java.util.stream.Collectors; +import java.util.function.Predicate; +import java.util.stream.IntStream; import java.util.stream.Stream; import jdk.jpackage.test.Functional.ThrowingConsumer; import jdk.jpackage.test.TestInstance.TestDesc; class MethodCall implements ThrowingConsumer { - MethodCall(Object[] instanceCtorArgs, Method method) { - this.ctorArgs = Optional.ofNullable(instanceCtorArgs).orElse( - DEFAULT_CTOR_ARGS); - this.method = method; - this.methodArgs = new Object[0]; - } + MethodCall(Object[] instanceCtorArgs, Method method, Object ... args) { + Objects.requireNonNull(instanceCtorArgs); + Objects.requireNonNull(method); - MethodCall(Object[] instanceCtorArgs, Method method, Object arg) { - this.ctorArgs = Optional.ofNullable(instanceCtorArgs).orElse( - DEFAULT_CTOR_ARGS); + this.ctorArgs = instanceCtorArgs; this.method = method; - this.methodArgs = new Object[]{arg}; + this.methodArgs = args; } TestDesc createDescription() { @@ -76,78 +75,195 @@ Object newInstance() throws NoSuchMethodException, InstantiationException, return null; } - Constructor ctor = findRequiredConstructor(method.getDeclaringClass(), - ctorArgs); - if (ctor.isVarArgs()) { - // Assume constructor doesn't have fixed, only variable parameters. - return ctor.newInstance(new Object[]{ctorArgs}); - } + var ctor = findMatchingConstructor(method.getDeclaringClass(), ctorArgs); - return ctor.newInstance(ctorArgs); + return ctor.newInstance(mapArgs(ctor, ctorArgs)); + } + + static Object[] mapArgs(Executable executable, final Object ... args) { + return mapPrimitiveTypeArgs(executable, mapVarArgs(executable, args)); } void checkRequiredConstructor() throws NoSuchMethodException { if ((method.getModifiers() & Modifier.STATIC) == 0) { - findRequiredConstructor(method.getDeclaringClass(), ctorArgs); + findMatchingConstructor(method.getDeclaringClass(), ctorArgs); } } - private static Constructor findVarArgConstructor(Class type) { - return Stream.of(type.getConstructors()).filter( - Constructor::isVarArgs).findFirst().orElse(null); - } - - private Constructor findRequiredConstructor(Class type, Object... ctorArgs) + private static Constructor findMatchingConstructor(Class type, Object... ctorArgs) throws NoSuchMethodException { - Supplier notFoundException = () -> { - return new NoSuchMethodException(String.format( + var ctors = filterMatchingExecutablesForParameterValues(Stream.of( + type.getConstructors()), ctorArgs).toList(); + + if (ctors.size() != 1) { + // No public constructors that can handle the given arguments. + throw new NoSuchMethodException(String.format( "No public contructor in %s for %s arguments", type, Arrays.deepToString(ctorArgs))); - }; - - if (Stream.of(ctorArgs).allMatch(Objects::nonNull)) { - // No `null` in constructor args, take easy path - try { - return type.getConstructor(Stream.of(ctorArgs).map( - Object::getClass).collect(Collectors.toList()).toArray( - Class[]::new)); - } catch (NoSuchMethodException ex) { - // Failed to find ctor that can take the given arguments. - Constructor varArgCtor = findVarArgConstructor(type); - if (varArgCtor != null) { - // There is one with variable number of arguments. Use it. - return varArgCtor; - } - throw notFoundException.get(); + } + + return ctors.get(0); + } + + @Override + public void accept(Object thiz) throws Throwable { + method.invoke(thiz, methodArgs); + } + + private static Object[] mapVarArgs(Executable executable, final Object ... args) { + if (executable.isVarArgs()) { + var paramTypes = executable.getParameterTypes(); + Class varArgParamType = paramTypes[paramTypes.length - 1]; + + Object[] newArgs; + if (paramTypes.length - args.length == 1) { + // Empty var args + + // "args" can be of type String[] if the "executable" is "foo(String ... str)" + newArgs = Arrays.copyOf(args, args.length + 1, Object[].class); + newArgs[newArgs.length - 1] = Array.newInstance(varArgParamType.componentType(), 0); + } else { + var varArgs = Arrays.copyOfRange(args, paramTypes.length - 1, + args.length, varArgParamType); + + // "args" can be of type String[] if the "executable" is "foo(String ... str)" + newArgs = Arrays.copyOfRange(args, 0, paramTypes.length, Object[].class); + newArgs[newArgs.length - 1] = varArgs; } + return newArgs; } - List ctors = Stream.of(type.getConstructors()) - .filter(ctor -> ctor.getParameterCount() == ctorArgs.length) - .collect(Collectors.toList()); + return args; + } - if (ctors.isEmpty()) { - // No public constructors that can handle the given arguments. - throw notFoundException.get(); + private static Object[] mapPrimitiveTypeArgs(Executable executable, final Object ... args) { + var paramTypes = executable.getParameterTypes(); + if (paramTypes.length != args.length) { + throw new IllegalArgumentException( + "The number of arguments must be equal to the number of parameters of the executable"); } - if (ctors.size() == 1) { - return ctors.iterator().next(); + if (IntStream.range(0, args.length).allMatch(idx -> { + return Optional.ofNullable(args[idx]).map(Object::getClass).map(paramTypes[idx]::isAssignableFrom).orElse(true); + })) { + return args; + } else { + final var newArgs = Arrays.copyOf(args, args.length, Object[].class); + for (var idx = 0; idx != args.length; ++idx) { + final var paramType = paramTypes[idx]; + final var argValue = args[idx]; + newArgs[idx] = Optional.ofNullable(argValue).map(Object::getClass).map(argType -> { + if(argType.isArray() && !paramType.isAssignableFrom(argType)) { + var length = Array.getLength(argValue); + var newArray = Array.newInstance(paramType.getComponentType(), length); + for (var arrayIdx = 0; arrayIdx != length; ++arrayIdx) { + Array.set(newArray, arrayIdx, Array.get(argValue, arrayIdx)); + } + return newArray; + } else { + return argValue; + } + }).orElse(argValue); + } + + return newArgs; } + } - // Revisit this tricky case when it will start bothering. - throw notFoundException.get(); + private static Stream filterMatchingExecutablesForParameterValues( + Stream executables, Object... args) { + return filterMatchingExecutablesForParameterTypes( + executables, + Stream.of(args) + .map(arg -> arg != null ? arg.getClass() : null) + .toArray(Class[]::new)); } - @Override - public void accept(Object thiz) throws Throwable { - method.invoke(thiz, methodArgs); + private static Stream filterMatchingExecutablesForParameterTypes( + Stream executables, Class... argTypes) { + return executables.filter(executable -> { + var parameterTypes = executable.getParameterTypes(); + + final int checkArgTypeCount; + if (parameterTypes.length <= argTypes.length) { + checkArgTypeCount = parameterTypes.length; + } else if (parameterTypes.length - argTypes.length == 1 && executable.isVarArgs()) { + // Empty optional arguments. + checkArgTypeCount = argTypes.length; + } else { + // Not enough mandatory arguments. + return false; + } + + var unmatched = IntStream.range(0, checkArgTypeCount).dropWhile(idx -> { + return new ParameterTypeMatcher(parameterTypes[idx]).test(argTypes[idx]); + }).toArray(); + + if (argTypes.length == parameterTypes.length && unmatched.length == 0) { + // Number of argument types equals to the number of parameters + // of the executable and all types match. + return true; + } + + if (executable.isVarArgs()) { + var varArgType = parameterTypes[parameterTypes.length - 1].componentType(); + return IntStream.of(unmatched).allMatch(idx -> { + return new ParameterTypeMatcher(varArgType).test(argTypes[idx]); + }); + } + + return false; + }); + } + + private static final class ParameterTypeMatcher implements Predicate> { + ParameterTypeMatcher(Class parameterType) { + Objects.requireNonNull(parameterType); + this.parameterType = NORM_TYPES.getOrDefault(parameterType, parameterType); + } + + @Override + public boolean test(Class paramaterValueType) { + if (paramaterValueType == null) { + return true; + } + + paramaterValueType = NORM_TYPES.getOrDefault(paramaterValueType, paramaterValueType); + return parameterType.isAssignableFrom(paramaterValueType); + } + + private final Class parameterType; } private final Object[] methodArgs; private final Method method; private final Object[] ctorArgs; - final static Object[] DEFAULT_CTOR_ARGS = new Object[0]; + private static final Map, Class> NORM_TYPES; + + static { + Map, Class> primitives = Map.of( + boolean.class, Boolean.class, + byte.class, Byte.class, + short.class, Short.class, + int.class, Integer.class, + long.class, Long.class, + float.class, Float.class, + double.class, Double.class); + + Map, Class> primitiveArrays = Map.of( + boolean[].class, Boolean[].class, + byte[].class, Byte[].class, + short[].class, Short[].class, + int[].class, Integer[].class, + long[].class, Long[].class, + float[].class, Float[].class, + double[].class, Double[].class); + + Map, Class> combined = new HashMap<>(primitives); + combined.putAll(primitiveArrays); + + NORM_TYPES = Collections.unmodifiableMap(combined); + } } diff --git a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/TKit.java b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/TKit.java index 28c58a4db3d..957449697a5 100644 --- a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/TKit.java +++ b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/TKit.java @@ -781,18 +781,18 @@ public void match(Set expected) { currentTest.notifyAssert(); var comm = Comm.compare(content, expected); - if (!comm.unique1.isEmpty() && !comm.unique2.isEmpty()) { + if (!comm.unique1().isEmpty() && !comm.unique2().isEmpty()) { error(String.format( "assertDirectoryContentEquals(%s): Some expected %s. Unexpected %s. Missing %s", - baseDir, format(comm.common), format(comm.unique1), format(comm.unique2))); - } else if (!comm.unique1.isEmpty()) { + baseDir, format(comm.common()), format(comm.unique1()), format(comm.unique2()))); + } else if (!comm.unique1().isEmpty()) { error(String.format( "assertDirectoryContentEquals(%s): Expected %s. Unexpected %s", - baseDir, format(comm.common), format(comm.unique1))); - } else if (!comm.unique2.isEmpty()) { + baseDir, format(comm.common()), format(comm.unique1()))); + } else if (!comm.unique2().isEmpty()) { error(String.format( "assertDirectoryContentEquals(%s): Some expected %s. Missing %s", - baseDir, format(comm.common), format(comm.unique2))); + baseDir, format(comm.common()), format(comm.unique2()))); } else { traceAssert(String.format( "assertDirectoryContentEquals(%s): Expected %s", @@ -808,10 +808,10 @@ public void contains(Set expected) { currentTest.notifyAssert(); var comm = Comm.compare(content, expected); - if (!comm.unique2.isEmpty()) { + if (!comm.unique2().isEmpty()) { error(String.format( "assertDirectoryContentContains(%s): Some expected %s. Missing %s", - baseDir, format(comm.common), format(comm.unique2))); + baseDir, format(comm.common()), format(comm.unique2()))); } else { traceAssert(String.format( "assertDirectoryContentContains(%s): Expected %s", @@ -838,21 +838,6 @@ private DirectoryContentVerifier(Path baseDir, Set contents) { this.content = contents; } - private static record Comm(Set common, Set unique1, Set unique2) { - static Comm compare(Set a, Set b) { - Set common = new HashSet<>(a); - common.retainAll(b); - - Set unique1 = new HashSet<>(a); - unique1.removeAll(common); - - Set unique2 = new HashSet<>(b); - unique2.removeAll(common); - - return new Comm(common, unique1, unique2); - } - } - private static String format(Set paths) { return Arrays.toString( paths.stream().sorted().map(Path::toString).toArray( diff --git a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/TestBuilder.java b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/TestBuilder.java index bb699ba3b9c..c2fc1789a25 100644 --- a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/TestBuilder.java +++ b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/TestBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,32 +23,28 @@ package jdk.jpackage.test; -import java.lang.reflect.Array; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; -import java.lang.reflect.Modifier; import java.util.ArrayList; -import java.util.Collection; +import java.util.Comparator; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Objects; import java.util.Optional; import java.util.Set; -import java.util.concurrent.atomic.AtomicInteger; import java.util.function.Consumer; -import java.util.function.Function; import java.util.function.UnaryOperator; import java.util.stream.Collectors; import java.util.stream.Stream; import jdk.jpackage.test.Annotations.AfterEach; import jdk.jpackage.test.Annotations.BeforeEach; -import jdk.jpackage.test.Annotations.Parameter; -import jdk.jpackage.test.Annotations.ParameterGroup; -import jdk.jpackage.test.Annotations.Parameters; import jdk.jpackage.test.Annotations.Test; import jdk.jpackage.test.Functional.ThrowingConsumer; +import static jdk.jpackage.test.Functional.ThrowingConsumer.toConsumer; import jdk.jpackage.test.Functional.ThrowingFunction; +import jdk.jpackage.test.TestMethodSupplier.InvalidAnnotationException; +import static jdk.jpackage.test.TestMethodSupplier.MethodQuery.fromQualifiedMethodName; final class TestBuilder implements AutoCloseable { @@ -58,6 +54,7 @@ public void close() throws Exception { } TestBuilder(Consumer testConsumer) { + this.testMethodSupplier = TestBuilderConfig.getDefault().createTestMethodSupplier(); argProcessors = Map.of( CMDLINE_ARG_PREFIX + "after-run", arg -> getJavaMethodsFromArg(arg).map( @@ -70,7 +67,7 @@ public void close() throws Exception { CMDLINE_ARG_PREFIX + "run", arg -> addTestGroup(getJavaMethodsFromArg(arg).map( ThrowingFunction.toFunction( - TestBuilder::toMethodCalls)).flatMap(s -> s).collect( + this::toMethodCalls)).flatMap(s -> s).collect( Collectors.toList())), CMDLINE_ARG_PREFIX + "exclude", @@ -219,23 +216,29 @@ private static Stream selectFrameMethods(Class type, Class annotationTyp .filter(m -> m.getParameterCount() == 0) .filter(m -> !m.isAnnotationPresent(Test.class)) .filter(m -> m.isAnnotationPresent(annotationType)) - .sorted((a, b) -> a.getName().compareTo(b.getName())); + .sorted(Comparator.comparing(Method::getName)); } - private static Stream cmdLineArgValueToMethodNames(String v) { + private Stream cmdLineArgValueToMethodNames(String v) { List result = new ArrayList<>(); String defaultClassName = null; for (String token : v.split(",")) { Class testSet = probeClass(token); if (testSet != null) { + if (testMethodSupplier.isTestClass(testSet)) { + toConsumer(testMethodSupplier::verifyTestClass).accept(testSet); + } + // Test set class specified. Pull in all public methods // from the class with @Test annotation removing name duplicates. // Overloads will be handled at the next phase of processing. defaultClassName = token; - Stream.of(testSet.getMethods()).filter( - m -> m.isAnnotationPresent(Test.class)).map( - Method::getName).distinct().forEach( - name -> result.add(String.join(".", token, name))); + result.addAll(Stream.of(testSet.getMethods()) + .filter(m -> m.isAnnotationPresent(Test.class)) + .filter(testMethodSupplier::isEnabled) + .map(Method::getName).distinct() + .map(name -> String.join(".", token, name)) + .toList()); continue; } @@ -246,7 +249,7 @@ private static Stream cmdLineArgValueToMethodNames(String v) { qualifiedMethodName = token; defaultClassName = token.substring(0, lastDotIdx); } else if (defaultClassName == null) { - throw new ParseException("Default class name not found in"); + throw new ParseException("Missing default class name in"); } else { qualifiedMethodName = String.join(".", defaultClassName, token); } @@ -255,155 +258,43 @@ private static Stream cmdLineArgValueToMethodNames(String v) { return result.stream(); } - private static boolean filterMethod(String expectedMethodName, Method method) { - if (!method.getName().equals(expectedMethodName)) { - return false; - } - switch (method.getParameterCount()) { - case 0: - return !isParametrized(method); - case 1: - return isParametrized(method); - } - return false; - } - - private static boolean isParametrized(Method method) { - return method.isAnnotationPresent(ParameterGroup.class) || method.isAnnotationPresent( - Parameter.class); - } - - private static List getJavaMethodFromString( - String qualifiedMethodName) { + private List getJavaMethodFromString(String qualifiedMethodName) { int lastDotIdx = qualifiedMethodName.lastIndexOf('.'); if (lastDotIdx == -1) { - throw new ParseException("Class name not found in"); - } - String className = qualifiedMethodName.substring(0, lastDotIdx); - String methodName = qualifiedMethodName.substring(lastDotIdx + 1); - Class methodClass; - try { - methodClass = Class.forName(className); - } catch (ClassNotFoundException ex) { - throw new ParseException(String.format("Class [%s] not found;", - className)); - } - // Get the list of all public methods as need to deal with overloads. - List methods = Stream.of(methodClass.getMethods()).filter( - (m) -> filterMethod(methodName, m)).collect(Collectors.toList()); - if (methods.isEmpty()) { - throw new ParseException(String.format( - "Method [%s] not found in [%s] class;", - methodName, className)); + throw new ParseException("Missing class name in"); } - trace(String.format("%s -> %s", qualifiedMethodName, methods)); - return methods; - } - - private static Stream getJavaMethodsFromArg(String argValue) { - return cmdLineArgValueToMethodNames(argValue).map( - ThrowingFunction.toFunction( - TestBuilder::getJavaMethodFromString)).flatMap( - List::stream).sequential(); - } - - private static Parameter[] getMethodParameters(Method method) { - if (method.isAnnotationPresent(ParameterGroup.class)) { - return ((ParameterGroup) method.getAnnotation(ParameterGroup.class)).value(); - } - - if (method.isAnnotationPresent(Parameter.class)) { - return new Parameter[]{(Parameter) method.getAnnotation( - Parameter.class)}; - } - - // Unexpected - return null; - } - - private static Stream toCtorArgs(Method method) throws - IllegalAccessException, InvocationTargetException { - Class type = method.getDeclaringClass(); - List paremetersProviders = Stream.of(type.getMethods()) - .filter(m -> m.getParameterCount() == 0) - .filter(m -> (m.getModifiers() & Modifier.STATIC) != 0) - .filter(m -> m.isAnnotationPresent(Parameters.class)) - .sorted() - .collect(Collectors.toList()); - if (paremetersProviders.isEmpty()) { - // Single instance using the default constructor. - return Stream.ofNullable(MethodCall.DEFAULT_CTOR_ARGS); - } - - // Pick the first method from the list. - Method paremetersProvider = paremetersProviders.iterator().next(); - if (paremetersProviders.size() > 1) { - trace(String.format( - "Found %d public static methods without arguments with %s annotation. Will use %s", - paremetersProviders.size(), Parameters.class, - paremetersProvider)); - paremetersProviders.stream().map(Method::toString).forEach( - TestBuilder::trace); + try { + return testMethodSupplier.findNullaryLikeMethods( + fromQualifiedMethodName(qualifiedMethodName)); + } catch (NoSuchMethodException ex) { + throw new ParseException(ex.getMessage() + ";", ex); } - - // Construct collection of arguments for test class instances. - return ((Collection) paremetersProvider.invoke(null)).stream(); } - private static Stream toMethodCalls(Method method) throws - IllegalAccessException, InvocationTargetException { - return toCtorArgs(method).map(v -> toMethodCalls(v, method)).flatMap( - s -> s).peek(methodCall -> { - // Make sure required constructor is accessible if the one is needed. - // Need to probe all methods as some of them might be static - // and some class members. - // Only class members require ctors. - try { - methodCall.checkRequiredConstructor(); - } catch (NoSuchMethodException ex) { - throw new ParseException(ex.getMessage() + "."); - } - }); + private Stream getJavaMethodsFromArg(String argValue) { + var methods = cmdLineArgValueToMethodNames(argValue) + .map(this::getJavaMethodFromString) + .flatMap(List::stream).toList(); + trace(String.format("%s -> %s", argValue, methods)); + return methods.stream(); } - private static Stream toMethodCalls(Object[] ctorArgs, Method method) { - if (!isParametrized(method)) { - return Stream.of(new MethodCall(ctorArgs, method)); - } - Parameter[] annotations = getMethodParameters(method); - if (annotations.length == 0) { - return Stream.of(new MethodCall(ctorArgs, method)); - } - return Stream.of(annotations).map((a) -> { - Class paramType = method.getParameterTypes()[0]; - final Object annotationValue; - if (!paramType.isArray()) { - annotationValue = fromString(a.value()[0], paramType); - } else { - Class paramComponentType = paramType.getComponentType(); - annotationValue = Array.newInstance(paramComponentType, a.value().length); - var idx = new AtomicInteger(-1); - Stream.of(a.value()).map(v -> fromString(v, paramComponentType)).sequential().forEach( - v -> Array.set(annotationValue, idx.incrementAndGet(), v)); + private Stream toMethodCalls(Method method) throws + IllegalAccessException, InvocationTargetException, InvalidAnnotationException { + return testMethodSupplier.mapToMethodCalls(method).peek(methodCall -> { + // Make sure required constructor is accessible if the one is needed. + // Need to probe all methods as some of them might be static + // and some class members. + // Only class members require ctors. + try { + methodCall.checkRequiredConstructor(); + } catch (NoSuchMethodException ex) { + throw new ParseException(ex.getMessage() + ".", ex); } - return new MethodCall(ctorArgs, method, annotationValue); }); } - private static Object fromString(String value, Class toType) { - if (toType.isEnum()) { - return Enum.valueOf(toType, value); - } - Function converter = conv.get(toType); - if (converter == null) { - throw new RuntimeException(String.format( - "Failed to find a conversion of [%s] string to %s type", - value, toType)); - } - return converter.apply(value); - } - // Wraps Method.invike() into ThrowingRunnable.run() private ThrowingConsumer wrap(Method method) { return (test) -> { @@ -427,6 +318,10 @@ private static class ParseException extends IllegalArgumentException { super(msg); } + ParseException(String msg, Exception ex) { + super(msg, ex); + } + void setContext(String badCmdLineArg) { this.badCmdLineArg = badCmdLineArg; } @@ -448,8 +343,9 @@ static void trace(String msg) { } } + private final TestMethodSupplier testMethodSupplier; private final Map> argProcessors; - private Consumer testConsumer; + private final Consumer testConsumer; private List testGroup; private List beforeActions; private List afterActions; @@ -458,14 +354,5 @@ static void trace(String msg) { private String spaceSubstitute; private boolean dryRun; - private final static Map> conv = Map.of( - boolean.class, Boolean::valueOf, - Boolean.class, Boolean::valueOf, - int.class, Integer::valueOf, - Integer.class, Integer::valueOf, - long.class, Long::valueOf, - Long.class, Long::valueOf, - String.class, String::valueOf); - - final static String CMDLINE_ARG_PREFIX = "--jpt-"; + static final String CMDLINE_ARG_PREFIX = "--jpt-"; } diff --git a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/TestBuilderConfig.java b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/TestBuilderConfig.java new file mode 100644 index 00000000000..baeaec32546 --- /dev/null +++ b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/TestBuilderConfig.java @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.jpackage.test; + +import java.util.Objects; +import jdk.internal.util.OperatingSystem; + +final class TestBuilderConfig { + TestBuilderConfig() { + } + + TestMethodSupplier createTestMethodSupplier() { + return new TestMethodSupplier(os); + } + + OperatingSystem getOperatingSystem() { + return os; + } + + static TestBuilderConfig getDefault() { + return DEFAULT.get(); + } + + static void setOperatingSystem(OperatingSystem os) { + Objects.requireNonNull(os); + DEFAULT.get().os = os; + } + + static void setDefaults() { + DEFAULT.set(new TestBuilderConfig()); + } + + private OperatingSystem os = OperatingSystem.current(); + + private static final ThreadLocal DEFAULT = new ThreadLocal<>() { + @Override + protected TestBuilderConfig initialValue() { + return new TestBuilderConfig(); + } + }; +} diff --git a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/TestInstance.java b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/TestInstance.java index 105c8f707cd..f619c9e222e 100644 --- a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/TestInstance.java +++ b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/TestInstance.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -32,8 +32,10 @@ import java.util.Collections; import java.util.HashSet; import java.util.List; +import java.util.Map; import java.util.Objects; import java.util.Set; +import java.util.function.Function; import java.util.function.Predicate; import java.util.function.Supplier; import java.util.stream.Collectors; @@ -50,7 +52,7 @@ private TestDesc() { String testFullName() { StringBuilder sb = new StringBuilder(); - sb.append(clazz.getSimpleName()); + sb.append(clazz.getName()); if (instanceArgs != null) { sb.append('(').append(instanceArgs).append(')'); } @@ -78,12 +80,12 @@ Builder method(Method v) { } Builder ctorArgs(Object... v) { - ctorArgs = ofNullable(v); + ctorArgs = Arrays.asList(v); return this; } Builder methodArgs(Object... v) { - methodArgs = ofNullable(v); + methodArgs = Arrays.asList(v); return this; } @@ -107,22 +109,18 @@ private static String formatArgs(List values) { } return values.stream().map(v -> { if (v != null && v.getClass().isArray()) { - return String.format("%s(length=%d)", - Arrays.deepToString((Object[]) v), - Array.getLength(v)); + String asString; + if (v.getClass().getComponentType().isPrimitive()) { + asString = PRIMITIVE_ARRAY_FORMATTERS.get(v.getClass()).apply(v); + } else { + asString = Arrays.deepToString((Object[]) v); + } + return String.format("%s(length=%d)", asString, Array.getLength(v)); } return String.format("%s", v); }).collect(Collectors.joining(", ")); } - private static List ofNullable(Object... values) { - List result = new ArrayList(); - for (var v: values) { - result.add(v); - } - return result; - } - private List ctorArgs; private List methodArgs; private Method method; @@ -331,7 +329,7 @@ public String toString() { private final boolean dryRun; private final Path workDir; - private final static Set KEEP_WORK_DIR = Functional.identity( + private static final Set KEEP_WORK_DIR = Functional.identity( () -> { final String propertyName = "keep-work-dir"; Set keepWorkDir = TKit.tokenizeConfigProperty( @@ -355,4 +353,15 @@ public String toString() { return Collections.unmodifiableSet(result); }).get(); + private static final Map, Function> PRIMITIVE_ARRAY_FORMATTERS = Map.of( + boolean[].class, v -> Arrays.toString((boolean[])v), + byte[].class, v -> Arrays.toString((byte[])v), + char[].class, v -> Arrays.toString((char[])v), + short[].class, v -> Arrays.toString((short[])v), + int[].class, v -> Arrays.toString((int[])v), + long[].class, v -> Arrays.toString((long[])v), + float[].class, v -> Arrays.toString((float[])v), + double[].class, v -> Arrays.toString((double[])v) + ); + } diff --git a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/TestMethodSupplier.java b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/TestMethodSupplier.java new file mode 100644 index 00000000000..83b1c19bd95 --- /dev/null +++ b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/TestMethodSupplier.java @@ -0,0 +1,510 @@ +/* + * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.jpackage.test; + +import java.lang.annotation.Annotation; +import java.lang.reflect.Executable; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.Comparator; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Objects; +import java.util.Set; +import java.util.function.Function; +import java.util.stream.IntStream; +import java.util.stream.Stream; +import jdk.internal.util.OperatingSystem; +import jdk.jpackage.test.Annotations.Parameter; +import jdk.jpackage.test.Annotations.ParameterGroup; +import jdk.jpackage.test.Annotations.ParameterSupplier; +import jdk.jpackage.test.Annotations.ParameterSupplierGroup; +import jdk.jpackage.test.Annotations.Parameters; +import jdk.jpackage.test.Annotations.Test; +import static jdk.jpackage.test.Functional.ThrowingFunction.toFunction; +import static jdk.jpackage.test.Functional.ThrowingSupplier.toSupplier; +import static jdk.jpackage.test.MethodCall.mapArgs; + +final class TestMethodSupplier { + + TestMethodSupplier(OperatingSystem os) { + Objects.requireNonNull(os); + this.os = os; + } + + record MethodQuery(String className, String methodName) { + + List lookup() throws ClassNotFoundException { + final Class methodClass = Class.forName(className); + + // Get the list of all public methods as need to deal with overloads. + return Stream.of(methodClass.getMethods()).filter(method -> { + return method.getName().equals(methodName); + }).toList(); + } + + static MethodQuery fromQualifiedMethodName(String qualifiedMethodName) { + int lastDotIdx = qualifiedMethodName.lastIndexOf('.'); + if (lastDotIdx == -1) { + throw new IllegalArgumentException("Class name not specified"); + } + + var className = qualifiedMethodName.substring(0, lastDotIdx); + var methodName = qualifiedMethodName.substring(lastDotIdx + 1); + + return new MethodQuery(className, methodName); + } + } + + List findNullaryLikeMethods(MethodQuery query) throws NoSuchMethodException { + List methods; + + try { + methods = query.lookup(); + } catch (ClassNotFoundException ex) { + throw new NoSuchMethodException( + String.format("Class [%s] not found", query.className())); + } + + if (methods.isEmpty()) { + throw new NoSuchMethodException(String.format( + "Public method [%s] not found in [%s] class", + query.methodName(), query.className())); + } + + methods = methods.stream().filter(method -> { + if (isParameterized(method) && isTest(method)) { + // Always accept test method with annotations producing arguments for its invocation. + return true; + } else { + return method.getParameterCount() == 0; + } + }).filter(this::isEnabled).toList(); + + if (methods.isEmpty()) { + throw new NoSuchMethodException(String.format( + "Suitable public method [%s] not found in [%s] class", + query.methodName(), query.className())); + } + + return methods; + } + + boolean isTestClass(Class type) { + var typeStatus = processedTypes.get(type); + if (typeStatus == null) { + typeStatus = Verifier.isTestClass(type) ? TypeStatus.TEST_CLASS : TypeStatus.NOT_TEST_CLASS; + processedTypes.put(type, typeStatus); + } + + return !TypeStatus.NOT_TEST_CLASS.equals(typeStatus); + } + + void verifyTestClass(Class type) throws InvalidAnnotationException { + var typeStatus = processedTypes.get(type); + if (typeStatus == null) { + // The "type" has not been verified yet. + try { + Verifier.verifyTestClass(type); + processedTypes.put(type, TypeStatus.VALID_TEST_CLASS); + return; + } catch (InvalidAnnotationException ex) { + processedTypes.put(type, TypeStatus.TEST_CLASS); + throw ex; + } + } + + switch (typeStatus) { + case NOT_TEST_CLASS -> Verifier.throwNotTestClassException(type); + case TEST_CLASS -> Verifier.verifyTestClass(type); + case VALID_TEST_CLASS -> {} + } + } + + boolean isEnabled(Method method) { + return Stream.of(Test.class, Parameters.class) + .filter(method::isAnnotationPresent) + .findFirst() + .map(method::getAnnotation) + .map(this::canRunOnTheOperatingSystem) + .orElse(true); + } + + Stream mapToMethodCalls(Method method) throws + IllegalAccessException, InvocationTargetException { + return toCtorArgs(method).map(v -> toMethodCalls(v, method)).flatMap(x -> x); + } + + private Stream toCtorArgs(Method method) throws + IllegalAccessException, InvocationTargetException { + + if ((method.getModifiers() & Modifier.STATIC) != 0) { + // Static method, no instance + return Stream.ofNullable(DEFAULT_CTOR_ARGS); + } + + final var type = method.getDeclaringClass(); + + final var paremeterSuppliers = filterParameterSuppliers(type) + .filter(m -> m.isAnnotationPresent(Parameters.class)) + .filter(this::isEnabled) + .sorted(Comparator.comparing(Method::getName)).toList(); + if (paremeterSuppliers.isEmpty()) { + // Single instance using the default constructor. + return Stream.ofNullable(DEFAULT_CTOR_ARGS); + } + + // Construct collection of arguments for test class instances. + return createArgs(paremeterSuppliers.toArray(Method[]::new)); + } + + private Stream toMethodCalls(Object[] ctorArgs, Method method) { + if (!isParameterized(method)) { + return Stream.of(new MethodCall(ctorArgs, method)); + } + + var fromParameter = Stream.of(getMethodParameters(method)).map(a -> { + return createArgsForAnnotation(method, a); + }).flatMap(List::stream); + + var fromParameterSupplier = Stream.of(getMethodParameterSuppliers(method)).map(a -> { + return toSupplier(() -> createArgsForAnnotation(method, a)).get(); + }).flatMap(List::stream); + + return Stream.concat(fromParameter, fromParameterSupplier).map(args -> { + return new MethodCall(ctorArgs, method, args); + }); + } + + private List createArgsForAnnotation(Executable exec, Parameter a) { + if (!canRunOnTheOperatingSystem(a)) { + return List.of(); + } + + final var annotationArgs = a.value(); + final var execParameterTypes = exec.getParameterTypes(); + + if (execParameterTypes.length > annotationArgs.length) { + if (execParameterTypes.length - annotationArgs.length == 1 && exec.isVarArgs()) { + } else { + throw new RuntimeException(String.format( + "Not enough annotation values %s for [%s]", + List.of(annotationArgs), exec)); + } + } + + final Class[] argTypes; + if (exec.isVarArgs()) { + List> argTypesBuilder = new ArrayList<>(); + var lastExecParameterTypeIdx = execParameterTypes.length - 1; + argTypesBuilder.addAll(List.of(execParameterTypes).subList(0, + lastExecParameterTypeIdx)); + argTypesBuilder.addAll(Collections.nCopies( + Integer.max(0, annotationArgs.length - lastExecParameterTypeIdx), + execParameterTypes[lastExecParameterTypeIdx].componentType())); + argTypes = argTypesBuilder.toArray(Class[]::new); + } else { + argTypes = execParameterTypes; + } + + if (argTypes.length < annotationArgs.length) { + throw new RuntimeException(String.format( + "Too many annotation values %s for [%s]", + List.of(annotationArgs), exec)); + } + + var args = mapArgs(exec, IntStream.range(0, argTypes.length).mapToObj(idx -> { + return fromString(annotationArgs[idx], argTypes[idx]); + }).toArray(Object[]::new)); + + return List.of(args); + } + + private List createArgsForAnnotation(Executable exec, + ParameterSupplier a) throws IllegalAccessException, + InvocationTargetException { + if (!canRunOnTheOperatingSystem(a)) { + return List.of(); + } + + final Class execClass = exec.getDeclaringClass(); + final var supplierFuncName = a.value(); + + final MethodQuery methodQuery; + if (!a.value().contains(".")) { + // No class name specified + methodQuery = new MethodQuery(execClass.getName(), a.value()); + } else { + methodQuery = MethodQuery.fromQualifiedMethodName(supplierFuncName); + } + + final Method supplierMethod; + try { + final var parameterSupplierCandidates = findNullaryLikeMethods(methodQuery); + final Function classForName = toFunction(Class::forName); + final var supplierMethodClass = classForName.apply(methodQuery.className()); + if (parameterSupplierCandidates.isEmpty()) { + throw new RuntimeException(String.format( + "No parameter suppliers in [%s] class", + supplierMethodClass.getName())); + } + + var allParameterSuppliers = filterParameterSuppliers(supplierMethodClass).toList(); + + supplierMethod = findNullaryLikeMethods(methodQuery) + .stream() + .filter(allParameterSuppliers::contains) + .findFirst().orElseThrow(() -> { + var msg = String.format( + "No suitable parameter supplier found for %s(%s) annotation", + a, supplierFuncName); + trace(String.format( + "%s. Parameter suppliers of %s class:", msg, + execClass.getName())); + IntStream.range(0, allParameterSuppliers.size()).mapToObj(idx -> { + return String.format(" [%d/%d] %s()", idx + 1, + allParameterSuppliers.size(), + allParameterSuppliers.get(idx).getName()); + }).forEachOrdered(TestMethodSupplier::trace); + + return new RuntimeException(msg); + }); + } catch (NoSuchMethodException ex) { + throw new RuntimeException(String.format( + "Method not found for %s(%s) annotation", a, supplierFuncName)); + } + + return createArgs(supplierMethod).map(args -> { + return mapArgs(exec, args); + }).toList(); + } + + private boolean canRunOnTheOperatingSystem(Annotation a) { + switch (a) { + case Test t -> { + return canRunOnTheOperatingSystem(os, t.ifOS(), t.ifNotOS()); + } + case Parameters t -> { + return canRunOnTheOperatingSystem(os, t.ifOS(), t.ifNotOS()); + } + case Parameter t -> { + return canRunOnTheOperatingSystem(os, t.ifOS(), t.ifNotOS()); + } + case ParameterSupplier t -> { + return canRunOnTheOperatingSystem(os, t.ifOS(), t.ifNotOS()); + } + default -> { + return true; + } + } + } + + private static boolean isParameterized(Method method) { + return Stream.of( + Parameter.class, ParameterGroup.class, + ParameterSupplier.class, ParameterSupplierGroup.class + ).anyMatch(method::isAnnotationPresent); + } + + private static boolean isTest(Method method) { + return method.isAnnotationPresent(Test.class); + } + + private static boolean canRunOnTheOperatingSystem(OperatingSystem value, + OperatingSystem[] include, OperatingSystem[] exclude) { + Set suppordOperatingSystems = new HashSet<>(); + suppordOperatingSystems.addAll(List.of(include)); + suppordOperatingSystems.removeAll(List.of(exclude)); + return suppordOperatingSystems.contains(value); + } + + private static Parameter[] getMethodParameters(Method method) { + if (method.isAnnotationPresent(ParameterGroup.class)) { + return ((ParameterGroup) method.getAnnotation(ParameterGroup.class)).value(); + } + + if (method.isAnnotationPresent(Parameter.class)) { + return new Parameter[]{(Parameter) method.getAnnotation(Parameter.class)}; + } + + return new Parameter[0]; + } + + private static ParameterSupplier[] getMethodParameterSuppliers(Method method) { + if (method.isAnnotationPresent(ParameterSupplierGroup.class)) { + return ((ParameterSupplierGroup) method.getAnnotation(ParameterSupplierGroup.class)).value(); + } + + if (method.isAnnotationPresent(ParameterSupplier.class)) { + return new ParameterSupplier[]{(ParameterSupplier) method.getAnnotation( + ParameterSupplier.class)}; + } + + return new ParameterSupplier[0]; + } + + private static Stream filterParameterSuppliers(Class type) { + return Stream.of(type.getMethods()) + .filter(m -> m.getParameterCount() == 0) + .filter(m -> (m.getModifiers() & Modifier.STATIC) != 0) + .sorted(Comparator.comparing(Method::getName)); + } + + private static Stream createArgs(Method ... parameterSuppliers) throws + IllegalAccessException, InvocationTargetException { + List args = new ArrayList<>(); + for (var parameterSupplier : parameterSuppliers) { + args.addAll((Collection) parameterSupplier.invoke(null)); + } + return args.stream(); + } + + private static Object fromString(String value, Class toType) { + if (toType.isEnum()) { + return Enum.valueOf(toType, value); + } + Function converter = FROM_STRING.get(toType); + if (converter == null) { + throw new RuntimeException(String.format( + "Failed to find a conversion of [%s] string to %s type", + value, toType.getName())); + } + return converter.apply(value); + } + + private static void trace(String msg) { + if (TKit.VERBOSE_TEST_SETUP) { + TKit.log(msg); + } + } + + static class InvalidAnnotationException extends Exception { + InvalidAnnotationException(String msg) { + super(msg); + } + } + + private static class Verifier { + static boolean isTestClass(Class type) { + for (var method : type.getDeclaredMethods()) { + if (isParameterized(method) || isTest(method)) { + return true; + } + } + return false; + } + + static void verifyTestClass(Class type) throws InvalidAnnotationException { + boolean withTestAnnotations = false; + for (var method : type.getDeclaredMethods()) { + if (!withTestAnnotations && (isParameterized(method) || isTest(method))) { + withTestAnnotations = true; + } + verifyAnnotationsCorrect(method); + } + + if (!withTestAnnotations) { + throwNotTestClassException(type); + } + } + + static void throwNotTestClassException(Class type) throws InvalidAnnotationException { + throw new InvalidAnnotationException(String.format( + "Type [%s] is not a test class", type.getName())); + } + + private static void verifyAnnotationsCorrect(Method method) throws + InvalidAnnotationException { + var parameterized = isParameterized(method); + if (parameterized && !isTest(method)) { + throw new InvalidAnnotationException(String.format( + "Missing %s annotation on [%s] method", Test.class.getName(), method)); + } + + var isPublic = Modifier.isPublic(method.getModifiers()); + + if (isTest(method) && !isPublic) { + throw new InvalidAnnotationException(String.format( + "Non-public method [%s] with %s annotation", + method, Test.class.getName())); + } + + if (method.isAnnotationPresent(Parameters.class) && !isPublic) { + throw new InvalidAnnotationException(String.format( + "Non-public method [%s] with %s annotation", + method, Test.class.getName())); + } + } + } + + private enum TypeStatus { + NOT_TEST_CLASS, + TEST_CLASS, + VALID_TEST_CLASS, + } + + private final OperatingSystem os; + private final Map, TypeStatus> processedTypes = new HashMap<>(); + + private static final Object[] DEFAULT_CTOR_ARGS = new Object[0]; + + private static final Map> FROM_STRING; + + static { + Map> primitives = Map.of( + boolean.class, Boolean::valueOf, + byte.class, Byte::valueOf, + short.class, Short::valueOf, + int.class, Integer::valueOf, + long.class, Long::valueOf, + float.class, Float::valueOf, + double.class, Double::valueOf); + + Map> boxed = Map.of( + Boolean.class, Boolean::valueOf, + Byte.class, Byte::valueOf, + Short.class, Short::valueOf, + Integer.class, Integer::valueOf, + Long.class, Long::valueOf, + Float.class, Float::valueOf, + Double.class, Double::valueOf); + + Map> other = Map.of( + String.class, String::valueOf, + Path.class, Path::of); + + Map> combined = new HashMap<>(primitives); + combined.putAll(other); + combined.putAll(boxed); + + FROM_STRING = Collections.unmodifiableMap(combined); + } +} diff --git a/test/jdk/tools/jpackage/share/InOutPathTest.java b/test/jdk/tools/jpackage/share/InOutPathTest.java index f8cb983bd16..15d96283ef4 100644 --- a/test/jdk/tools/jpackage/share/InOutPathTest.java +++ b/test/jdk/tools/jpackage/share/InOutPathTest.java @@ -29,12 +29,12 @@ import java.util.List; import java.util.Set; import java.util.function.Predicate; -import static java.util.stream.Collectors.toSet; import java.util.stream.Stream; +import jdk.internal.util.OperatingSystem; import jdk.jpackage.internal.AppImageFile; import jdk.jpackage.internal.ApplicationLayout; import jdk.jpackage.internal.PackageFile; -import jdk.jpackage.test.Annotations; +import jdk.jpackage.test.Annotations.Parameters; import jdk.jpackage.test.Annotations.Test; import jdk.jpackage.test.Functional.ThrowingConsumer; import jdk.jpackage.test.JPackageCommand; @@ -55,47 +55,51 @@ */ public final class InOutPathTest { - @Annotations.Parameters + @Parameters public static Collection input() { List data = new ArrayList<>(); - for (var packageTypes : List.of(PackageType.IMAGE.toString(), ALL_NATIVE_PACKAGE_TYPES)) { + for (var packageTypeAlias : PackageTypeAlias.values()) { data.addAll(List.of(new Object[][]{ - {packageTypes, wrap(InOutPathTest::outputDirInInputDir, "--dest in --input")}, - {packageTypes, wrap(InOutPathTest::outputDirSameAsInputDir, "--dest same as --input")}, - {packageTypes, wrap(InOutPathTest::tempDirInInputDir, "--temp in --input")}, - {packageTypes, wrap(cmd -> { + {packageTypeAlias, wrap(InOutPathTest::outputDirInInputDir, "--dest in --input")}, + {packageTypeAlias, wrap(InOutPathTest::outputDirSameAsInputDir, "--dest same as --input")}, + {packageTypeAlias, wrap(InOutPathTest::tempDirInInputDir, "--temp in --input")}, + {packageTypeAlias, wrap(cmd -> { outputDirInInputDir(cmd); tempDirInInputDir(cmd); }, "--dest and --temp in --input")}, })); - data.addAll(additionalContentInput(packageTypes, "--app-content")); + data.addAll(additionalContentInput(packageTypeAlias, "--app-content")); } - if (!TKit.isOSX()) { - data.addAll(List.of(new Object[][]{ - {PackageType.IMAGE.toString(), wrap(cmd -> { - additionalContent(cmd, "--app-content", cmd.outputBundle()); - }, "--app-content same as output bundle")}, - })); - } else { - var contentsFolder = "Contents/MacOS"; - data.addAll(List.of(new Object[][]{ - {PackageType.IMAGE.toString(), wrap(cmd -> { - additionalContent(cmd, "--app-content", cmd.outputBundle().resolve(contentsFolder)); - }, String.format("--app-content same as the \"%s\" folder in the output bundle", contentsFolder))}, - })); - } + return data; + } - if (TKit.isOSX()) { - data.addAll(additionalContentInput(PackageType.MAC_DMG.toString(), - "--mac-dmg-content")); - } + @Parameters(ifNotOS = OperatingSystem.MACOS) + public static Collection appContentInputOther() { + return List.of(new Object[][]{ + {PackageTypeAlias.IMAGE, wrap(cmd -> { + additionalContent(cmd, "--app-content", cmd.outputBundle()); + }, "--app-content same as output bundle")}, + }); + } - return data; + @Parameters(ifOS = OperatingSystem.MACOS) + public static Collection appContentInputOSX() { + var contentsFolder = "Contents/MacOS"; + return List.of(new Object[][]{ + {PackageTypeAlias.IMAGE, wrap(cmd -> { + additionalContent(cmd, "--app-content", cmd.outputBundle().resolve(contentsFolder)); + }, String.format("--app-content same as the \"%s\" folder in the output bundle", contentsFolder))}, + }); } - private static List additionalContentInput(String packageTypes, String argName) { + @Parameters(ifOS = OperatingSystem.MACOS) + public static Collection inputOSX() { + return List.of(additionalContentInput(PackageType.MAC_DMG, "--mac-dmg-content").toArray(Object[][]::new)); + } + + private static List additionalContentInput(Object packageTypes, String argName) { List data = new ArrayList<>(); data.addAll(List.of(new Object[][]{ @@ -127,13 +131,16 @@ private static List additionalContentInput(String packageTypes, String return data; } - public InOutPathTest(String packageTypes, Envelope configure) { - if (ALL_NATIVE_PACKAGE_TYPES.equals(packageTypes)) { - this.packageTypes = PackageType.NATIVE; - } else { - this.packageTypes = Stream.of(packageTypes.split(",")).map( - PackageType::valueOf).collect(toSet()); - } + public InOutPathTest(PackageTypeAlias packageTypeAlias, Envelope configure) { + this(packageTypeAlias.packageTypes, configure); + } + + public InOutPathTest(PackageType packageType, Envelope configure) { + this(Set.of(packageType), configure); + } + + public InOutPathTest(Set packageTypes, Envelope configure) { + this.packageTypes = packageTypes; this.configure = configure.value; } @@ -271,6 +278,18 @@ public String toString() { } } + private enum PackageTypeAlias { + IMAGE(Set.of(PackageType.IMAGE)), + NATIVE(PackageType.NATIVE), + ; + + PackageTypeAlias(Set packageTypes) { + this.packageTypes = packageTypes; + } + + private final Set packageTypes; + } + private final Set packageTypes; private final ThrowingConsumer configure; @@ -279,6 +298,4 @@ public String toString() { // For other platforms it doesn't matter. Keep it the same across // all platforms for simplicity. private static final Path JAR_PATH = Path.of("Resources/duke.jar"); - - private static final String ALL_NATIVE_PACKAGE_TYPES = "NATIVE"; } diff --git a/test/jdk/tools/jpackage/share/InstallDirTest.java b/test/jdk/tools/jpackage/share/InstallDirTest.java index 7047f35e87b..23539589bcc 100644 --- a/test/jdk/tools/jpackage/share/InstallDirTest.java +++ b/test/jdk/tools/jpackage/share/InstallDirTest.java @@ -22,13 +22,12 @@ */ import java.nio.file.Path; -import java.util.HashMap; -import java.util.Map; +import jdk.internal.util.OperatingSystem; import jdk.jpackage.test.TKit; import jdk.jpackage.test.PackageTest; import jdk.jpackage.test.PackageType; -import jdk.jpackage.test.Functional; import jdk.jpackage.test.Annotations.Parameter; +import jdk.jpackage.test.Annotations.Test; /** * Test --install-dir parameter. Output of the test should be @@ -76,28 +75,18 @@ */ public class InstallDirTest { - public static void testCommon() { - final Map INSTALL_DIRS = Functional.identity(() -> { - Map reply = new HashMap<>(); - reply.put(PackageType.WIN_MSI, Path.of("TestVendor\\InstallDirTest1234")); - reply.put(PackageType.WIN_EXE, reply.get(PackageType.WIN_MSI)); - - reply.put(PackageType.LINUX_DEB, Path.of("/opt/jpackage")); - reply.put(PackageType.LINUX_RPM, reply.get(PackageType.LINUX_DEB)); - - reply.put(PackageType.MAC_PKG, Path.of("/Applications/jpackage")); - reply.put(PackageType.MAC_DMG, reply.get(PackageType.MAC_PKG)); - - return reply; - }).get(); - + @Test + @Parameter(value = "TestVendor\\InstallDirTest1234", ifOS = OperatingSystem.WINDOWS) + @Parameter(value = "/opt/jpackage", ifOS = OperatingSystem.LINUX) + @Parameter(value = "/Applications/jpackage", ifOS = OperatingSystem.MACOS) + public static void testCommon(Path installDir) { new PackageTest().configureHelloApp() .addInitializer(cmd -> { - cmd.addArguments("--install-dir", INSTALL_DIRS.get( - cmd.packageType())); + cmd.addArguments("--install-dir", installDir); }).run(); } + @Test(ifOS = OperatingSystem.LINUX) @Parameter("/") @Parameter(".") @Parameter("foo") From e1c4b4977ec613efe4f51151433e242a256204ee Mon Sep 17 00:00:00 2001 From: Justin Lu Date: Mon, 18 Nov 2024 00:16:02 +0000 Subject: [PATCH 041/311] 8343237: Improve the copying of the available set of Currencies Reviewed-by: bpb --- src/java.base/share/classes/java/util/Currency.java | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/java.base/share/classes/java/util/Currency.java b/src/java.base/share/classes/java/util/Currency.java index b639855b3bf..789eefad5d5 100644 --- a/src/java.base/share/classes/java/util/Currency.java +++ b/src/java.base/share/classes/java/util/Currency.java @@ -486,10 +486,7 @@ public static Set getAvailableCurrencies() { } } } - - @SuppressWarnings("unchecked") - Set result = (Set) available.clone(); - return result; + return new HashSet<>(available); } /** From 80e37a96bbd4167bca44b11b9968949318ee1140 Mon Sep 17 00:00:00 2001 From: Gui Cao Date: Mon, 18 Nov 2024 00:48:24 +0000 Subject: [PATCH 042/311] 8344265: RISC-V: Remove unused function get_previous_sp_entry Reviewed-by: fyang, mli --- src/hotspot/cpu/riscv/stubRoutines_riscv.cpp | 11 ---- src/hotspot/cpu/riscv/stubRoutines_riscv.hpp | 53 -------------------- 2 files changed, 64 deletions(-) diff --git a/src/hotspot/cpu/riscv/stubRoutines_riscv.cpp b/src/hotspot/cpu/riscv/stubRoutines_riscv.cpp index 6d5492b86b3..28b797a639e 100644 --- a/src/hotspot/cpu/riscv/stubRoutines_riscv.cpp +++ b/src/hotspot/cpu/riscv/stubRoutines_riscv.cpp @@ -34,16 +34,6 @@ // Implementation of the platform-specific part of StubRoutines - for // a description of how to extend it, see the stubRoutines.hpp file. -address StubRoutines::riscv::_get_previous_sp_entry = nullptr; - -address StubRoutines::riscv::_f2i_fixup = nullptr; -address StubRoutines::riscv::_f2l_fixup = nullptr; -address StubRoutines::riscv::_d2i_fixup = nullptr; -address StubRoutines::riscv::_d2l_fixup = nullptr; -address StubRoutines::riscv::_float_sign_mask = nullptr; -address StubRoutines::riscv::_float_sign_flip = nullptr; -address StubRoutines::riscv::_double_sign_mask = nullptr; -address StubRoutines::riscv::_double_sign_flip = nullptr; address StubRoutines::riscv::_zero_blocks = nullptr; address StubRoutines::riscv::_compare_long_string_LL = nullptr; address StubRoutines::riscv::_compare_long_string_UU = nullptr; @@ -52,7 +42,6 @@ address StubRoutines::riscv::_compare_long_string_UL = nullptr; address StubRoutines::riscv::_string_indexof_linear_ll = nullptr; address StubRoutines::riscv::_string_indexof_linear_uu = nullptr; address StubRoutines::riscv::_string_indexof_linear_ul = nullptr; -address StubRoutines::riscv::_large_byte_array_inflate = nullptr; bool StubRoutines::riscv::_completed = false; diff --git a/src/hotspot/cpu/riscv/stubRoutines_riscv.hpp b/src/hotspot/cpu/riscv/stubRoutines_riscv.hpp index 3d1f4a61f00..a099d71475e 100644 --- a/src/hotspot/cpu/riscv/stubRoutines_riscv.hpp +++ b/src/hotspot/cpu/riscv/stubRoutines_riscv.hpp @@ -47,18 +47,6 @@ class riscv { friend class StubGenerator; private: - static address _get_previous_sp_entry; - - static address _f2i_fixup; - static address _f2l_fixup; - static address _d2i_fixup; - static address _d2l_fixup; - - static address _float_sign_mask; - static address _float_sign_flip; - static address _double_sign_mask; - static address _double_sign_flip; - static address _zero_blocks; static address _compare_long_string_LL; @@ -68,48 +56,11 @@ class riscv { static address _string_indexof_linear_ll; static address _string_indexof_linear_uu; static address _string_indexof_linear_ul; - static address _large_byte_array_inflate; static bool _completed; public: - static address get_previous_sp_entry() { - return _get_previous_sp_entry; - } - - static address f2i_fixup() { - return _f2i_fixup; - } - - static address f2l_fixup() { - return _f2l_fixup; - } - - static address d2i_fixup() { - return _d2i_fixup; - } - - static address d2l_fixup() { - return _d2l_fixup; - } - - static address float_sign_mask() { - return _float_sign_mask; - } - - static address float_sign_flip() { - return _float_sign_flip; - } - - static address double_sign_mask() { - return _double_sign_mask; - } - - static address double_sign_flip() { - return _double_sign_flip; - } - static address zero_blocks() { return _zero_blocks; } @@ -142,10 +93,6 @@ class riscv { return _string_indexof_linear_uu; } - static address large_byte_array_inflate() { - return _large_byte_array_inflate; - } - static bool complete() { return _completed; } From a47d9ba98a1498425970613415ecb830f805a3be Mon Sep 17 00:00:00 2001 From: SendaoYan Date: Mon, 18 Nov 2024 02:35:18 +0000 Subject: [PATCH 043/311] 8344349: Problemlist jdk/jfr/jvm/TestVirtualThreadExclusion.java before JDK-8344199 resolved Reviewed-by: lmesnik --- test/jdk/ProblemList-Xcomp.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/test/jdk/ProblemList-Xcomp.txt b/test/jdk/ProblemList-Xcomp.txt index 680806e6e31..1577bb6f7f1 100644 --- a/test/jdk/ProblemList-Xcomp.txt +++ b/test/jdk/ProblemList-Xcomp.txt @@ -30,3 +30,4 @@ java/lang/invoke/MethodHandles/CatchExceptionTest.java 8146623 generic-all java/lang/reflect/callerCache/ReflectionCallerCacheTest.java 8332028 generic-all com/sun/jdi/InterruptHangTest.java 8043571 generic-all +jdk/jfr/jvm/TestVirtualThreadExclusion.java 8344199 generic-all From 92b26317d444fc63c8b229dfabd2cddd838b9fe4 Mon Sep 17 00:00:00 2001 From: Sidraya Jayagond Date: Mon, 18 Nov 2024 06:51:11 +0000 Subject: [PATCH 044/311] 8327652: S390x: Implements SLP support Reviewed-by: amitkumar, lucy, mdoerr --- src/hotspot/cpu/s390/assembler_s390.hpp | 106 ++- .../cpu/s390/assembler_s390.inline.hpp | 49 +- .../cpu/s390/c2_MacroAssembler_s390.cpp | 6 + src/hotspot/cpu/s390/c2_globals_s390.hpp | 2 +- src/hotspot/cpu/s390/globals_s390.hpp | 5 + src/hotspot/cpu/s390/registerSaver_s390.hpp | 9 +- src/hotspot/cpu/s390/register_s390.cpp | 13 +- src/hotspot/cpu/s390/register_s390.hpp | 24 +- src/hotspot/cpu/s390/s390.ad | 866 +++++++++++++++++- src/hotspot/cpu/s390/sharedRuntime_s390.cpp | 89 +- src/hotspot/cpu/s390/vm_version_s390.cpp | 18 +- src/hotspot/cpu/s390/vmreg_s390.cpp | 10 + src/hotspot/cpu/s390/vmreg_s390.hpp | 16 +- src/hotspot/cpu/s390/vmreg_s390.inline.hpp | 12 +- src/hotspot/share/adlc/output_c.cpp | 3 + src/hotspot/share/opto/machnode.hpp | 8 + src/hotspot/share/opto/type.cpp | 2 +- 17 files changed, 1148 insertions(+), 90 deletions(-) diff --git a/src/hotspot/cpu/s390/assembler_s390.hpp b/src/hotspot/cpu/s390/assembler_s390.hpp index c98c100a068..60e347a2d92 100644 --- a/src/hotspot/cpu/s390/assembler_s390.hpp +++ b/src/hotspot/cpu/s390/assembler_s390.hpp @@ -1236,6 +1236,9 @@ class Assembler : public AbstractAssembler { // NOR #define VNO_ZOPC (unsigned long)(0xe7L << 40 | 0x6bL << 0) // V1 := !(V2 | V3), element size = 2**m + //NOT-XOR +#define VNX_ZOPC (unsigned long)(0xe7L << 40 | 0x6cL << 0) // V1 := !(V2 | V3), element size = 2**m + // OR #define VO_ZOPC (unsigned long)(0xe7L << 40 | 0x6aL << 0) // V1 := V2 | V3, element size = 2**m @@ -1287,6 +1290,13 @@ class Assembler : public AbstractAssembler { #define VSTRC_ZOPC (unsigned long)(0xe7L << 40 | 0x8aL << 0) // String range compare #define VISTR_ZOPC (unsigned long)(0xe7L << 40 | 0x5cL << 0) // Isolate String +#define VFA_ZOPC (unsigned long)(0xe7L << 40 | 0xE3L << 0) // V1 := V2 + V3, element size = 2**m +#define VFS_ZOPC (unsigned long)(0xe7L << 40 | 0xE2L << 0) // V1 := V2 - V3, element size = 2**m +#define VFM_ZOPC (unsigned long)(0xe7L << 40 | 0xE7L << 0) // V1 := V2 * V3, element size = 2**m +#define VFD_ZOPC (unsigned long)(0xe7L << 40 | 0xE5L << 0) // V1 := V2 / V3, element size = 2**m +#define VFSQ_ZOPC (unsigned long)(0xe7L << 40 | 0xCEL << 0) // V1 := sqrt of V2, element size = 2**m +#define VFLR_ZOPC (unsigned long)(0xe7L << 40 | 0xC5L << 0) // vector fp load rounded, element size = 2**m + //-------------------------------- //-- Miscellaneous Operations -- @@ -2322,22 +2332,22 @@ class Assembler : public AbstractAssembler { inline void z_xilf(Register r1, int64_t i2); // xor r1 = r1 ^ i2_imm32 ; or only for bits 32-63 // shift - inline void z_sla( Register r1, int64_t d2, Register b2=Z_R0); // shift left r1 = r1 << ((d2+b2)&0x3f) ; int32, only 31 bits shifted, sign preserved! - inline void z_slak(Register r1, Register r3, int64_t d2, Register b2=Z_R0); // shift left r1 = r3 << ((d2+b2)&0x3f) ; int32, only 31 bits shifted, sign preserved! - inline void z_slag(Register r1, Register r3, int64_t d2, Register b2=Z_R0); // shift left r1 = r3 << ((d2+b2)&0x3f) ; int64, only 63 bits shifted, sign preserved! - inline void z_sra( Register r1, int64_t d2, Register b2=Z_R0); // shift right r1 = r1 >> ((d2+b2)&0x3f) ; int32, sign extended - inline void z_srak(Register r1, Register r3, int64_t d2, Register b2=Z_R0); // shift right r1 = r3 >> ((d2+b2)&0x3f) ; int32, sign extended - inline void z_srag(Register r1, Register r3, int64_t d2, Register b2=Z_R0); // shift right r1 = r3 >> ((d2+b2)&0x3f) ; int64, sign extended - inline void z_sll( Register r1, int64_t d2, Register b2=Z_R0); // shift left r1 = r1 << ((d2+b2)&0x3f) ; int32, zeros added - inline void z_sllk(Register r1, Register r3, int64_t d2, Register b2=Z_R0); // shift left r1 = r3 << ((d2+b2)&0x3f) ; int32, zeros added - inline void z_sllg(Register r1, Register r3, int64_t d2, Register b2=Z_R0); // shift left r1 = r3 << ((d2+b2)&0x3f) ; int64, zeros added - inline void z_srl( Register r1, int64_t d2, Register b2=Z_R0); // shift right r1 = r1 >> ((d2+b2)&0x3f) ; int32, zero extended - inline void z_srlk(Register r1, Register r3, int64_t d2, Register b2=Z_R0); // shift right r1 = r3 >> ((d2+b2)&0x3f) ; int32, zero extended - inline void z_srlg(Register r1, Register r3, int64_t d2, Register b2=Z_R0); // shift right r1 = r3 >> ((d2+b2)&0x3f) ; int64, zero extended + inline void z_sla( Register r1, int64_t d2, Register b2 = Z_R0); // shift left r1 = r1 << ((d2+b2)&0x3f) ; int32, only 31 bits shifted, sign preserved! + inline void z_slak(Register r1, Register r3, int64_t d2, Register b2 = Z_R0); // shift left r1 = r3 << ((d2+b2)&0x3f) ; int32, only 31 bits shifted, sign preserved! + inline void z_slag(Register r1, Register r3, int64_t d2, Register b2 = Z_R0); // shift left r1 = r3 << ((d2+b2)&0x3f) ; int64, only 63 bits shifted, sign preserved! + inline void z_sra( Register r1, int64_t d2, Register b2 = Z_R0); // shift right r1 = r1 >> ((d2+b2)&0x3f) ; int32, sign extended + inline void z_srak(Register r1, Register r3, int64_t d2, Register b2 = Z_R0); // shift right r1 = r3 >> ((d2+b2)&0x3f) ; int32, sign extended + inline void z_srag(Register r1, Register r3, int64_t d2, Register b2 = Z_R0); // shift right r1 = r3 >> ((d2+b2)&0x3f) ; int64, sign extended + inline void z_sll( Register r1, int64_t d2, Register b2 = Z_R0); // shift left r1 = r1 << ((d2+b2)&0x3f) ; int32, zeros added + inline void z_sllk(Register r1, Register r3, int64_t d2, Register b2 = Z_R0); // shift left r1 = r3 << ((d2+b2)&0x3f) ; int32, zeros added + inline void z_sllg(Register r1, Register r3, int64_t d2, Register b2 = Z_R0); // shift left r1 = r3 << ((d2+b2)&0x3f) ; int64, zeros added + inline void z_srl( Register r1, int64_t d2, Register b2 = Z_R0); // shift right r1 = r1 >> ((d2+b2)&0x3f) ; int32, zero extended + inline void z_srlk(Register r1, Register r3, int64_t d2, Register b2 = Z_R0); // shift right r1 = r3 >> ((d2+b2)&0x3f) ; int32, zero extended + inline void z_srlg(Register r1, Register r3, int64_t d2, Register b2 = Z_R0); // shift right r1 = r3 >> ((d2+b2)&0x3f) ; int64, zero extended // rotate - inline void z_rll( Register r1, Register r3, int64_t d2, Register b2=Z_R0); // rot r1 = r3 << (d2+b2 & 0x3f) ; int32 -- z10 - inline void z_rllg(Register r1, Register r3, int64_t d2, Register b2=Z_R0); // rot r1 = r3 << (d2+b2 & 0x3f) ; int64 -- z10 + inline void z_rll( Register r1, Register r3, int64_t d2, Register b2 = Z_R0); // rot r1 = r3 << (d2+b2 & 0x3f) ; int32 -- z10 + inline void z_rllg(Register r1, Register r3, int64_t d2, Register b2 = Z_R0); // rot r1 = r3 << (d2+b2 & 0x3f) ; int64 -- z10 // rotate the AND/XOR/OR/insert inline void z_rnsbg( Register r1, Register r2, int64_t spos3, int64_t epos4, int64_t nrot5, bool test_only = false); // rotate then AND selected bits -- z196 @@ -2459,7 +2469,7 @@ class Assembler : public AbstractAssembler { inline void z_mvc(const Address& d, const Address& s, int64_t l); // move l bytes inline void z_mvc(int64_t d1, int64_t l, Register b1, int64_t d2, Register b2); // move l+1 bytes inline void z_mvcin(int64_t d1, int64_t l, Register b1, int64_t d2, Register b2); // move l+1 bytes - inline void z_mvcle(Register r1, Register r3, int64_t d2, Register b2=Z_R0); // move region of memory + inline void z_mvcle(Register r1, Register r3, int64_t d2, Register b2 = Z_R0); // move region of memory inline void z_stfle(int64_t d2, Register b2); // store facility list extended @@ -2491,6 +2501,7 @@ class Assembler : public AbstractAssembler { // Load (transfer from memory) inline void z_vlm( VectorRegister v1, VectorRegister v3, int64_t d2, Register b2); inline void z_vl( VectorRegister v1, int64_t d2, Register x2, Register b2); + inline void z_vl( VectorRegister v1, const Address& a); inline void z_vleb( VectorRegister v1, int64_t d2, Register x2, Register b2, int64_t m3); inline void z_vleh( VectorRegister v1, int64_t d2, Register x2, Register b2, int64_t m3); inline void z_vlef( VectorRegister v1, int64_t d2, Register x2, Register b2, int64_t m3); @@ -2529,10 +2540,10 @@ class Assembler : public AbstractAssembler { inline void z_vlgvg( Register r1, VectorRegister v3, int64_t d2, Register b2); inline void z_vlvg( VectorRegister v1, Register r3, int64_t d2, Register b2, int64_t m4); - inline void z_vlvgb( VectorRegister v1, Register r3, int64_t d2, Register b2); - inline void z_vlvgh( VectorRegister v1, Register r3, int64_t d2, Register b2); - inline void z_vlvgf( VectorRegister v1, Register r3, int64_t d2, Register b2); - inline void z_vlvgg( VectorRegister v1, Register r3, int64_t d2, Register b2); + inline void z_vlvgb( VectorRegister v1, Register r3, int64_t d2, Register b2 = Z_R0); + inline void z_vlvgh( VectorRegister v1, Register r3, int64_t d2, Register b2 = Z_R0); + inline void z_vlvgf( VectorRegister v1, Register r3, int64_t d2, Register b2 = Z_R0); + inline void z_vlvgg( VectorRegister v1, Register r3, int64_t d2, Register b2 = Z_R0); inline void z_vlvgp( VectorRegister v1, Register r2, Register r3); @@ -2619,6 +2630,7 @@ class Assembler : public AbstractAssembler { // Store inline void z_vstm( VectorRegister v1, VectorRegister v3, int64_t d2, Register b2); inline void z_vst( VectorRegister v1, int64_t d2, Register x2, Register b2); + inline void z_vst( VectorRegister v1, const Address& a); inline void z_vsteb( VectorRegister v1, int64_t d2, Register x2, Register b2, int64_t m3); inline void z_vsteh( VectorRegister v1, int64_t d2, Register x2, Register b2, int64_t m3); inline void z_vstef( VectorRegister v1, int64_t d2, Register x2, Register b2, int64_t m3); @@ -2679,13 +2691,16 @@ class Assembler : public AbstractAssembler { inline void z_vscbiq( VectorRegister v1, VectorRegister v2, VectorRegister v3); // MULTIPLY - inline void z_vml( VectorRegister v1, VectorRegister v2, VectorRegister v3, int64_t m4); - inline void z_vmh( VectorRegister v1, VectorRegister v2, VectorRegister v3, int64_t m4); - inline void z_vmlh( VectorRegister v1, VectorRegister v2, VectorRegister v3, int64_t m4); - inline void z_vme( VectorRegister v1, VectorRegister v2, VectorRegister v3, int64_t m4); - inline void z_vmle( VectorRegister v1, VectorRegister v2, VectorRegister v3, int64_t m4); - inline void z_vmo( VectorRegister v1, VectorRegister v2, VectorRegister v3, int64_t m4); - inline void z_vmlo( VectorRegister v1, VectorRegister v2, VectorRegister v3, int64_t m4); + inline void z_vml( VectorRegister v1, VectorRegister v2, VectorRegister v3, int64_t m4); + inline void z_vmlb( VectorRegister v1, VectorRegister v2, VectorRegister v3); + inline void z_vmlhw(VectorRegister v1, VectorRegister v2, VectorRegister v3); + inline void z_vmlf( VectorRegister v1, VectorRegister v2, VectorRegister v3); + inline void z_vmh( VectorRegister v1, VectorRegister v2, VectorRegister v3, int64_t m4); + inline void z_vmlh( VectorRegister v1, VectorRegister v2, VectorRegister v3, int64_t m4); + inline void z_vme( VectorRegister v1, VectorRegister v2, VectorRegister v3, int64_t m4); + inline void z_vmle( VectorRegister v1, VectorRegister v2, VectorRegister v3, int64_t m4); + inline void z_vmo( VectorRegister v1, VectorRegister v2, VectorRegister v3, int64_t m4); + inline void z_vmlo( VectorRegister v1, VectorRegister v2, VectorRegister v3, int64_t m4); // MULTIPLY & ADD inline void z_vmal( VectorRegister v1, VectorRegister v2, VectorRegister v3, VectorRegister v4, int64_t m5); @@ -2744,6 +2759,9 @@ class Assembler : public AbstractAssembler { // NOR inline void z_vno( VectorRegister v1, VectorRegister v2, VectorRegister v3); + //NOT-XOR + inline void z_vnx( VectorRegister v1, VectorRegister v2, VectorRegister v3); + // OR inline void z_vo( VectorRegister v1, VectorRegister v2, VectorRegister v3); @@ -2810,6 +2828,10 @@ class Assembler : public AbstractAssembler { inline void z_vctzf( VectorRegister v1, VectorRegister v2); inline void z_vctzg( VectorRegister v1, VectorRegister v2); inline void z_vpopct( VectorRegister v1, VectorRegister v2, int64_t m3); + inline void z_vpopctb(VectorRegister v1, VectorRegister v2); + inline void z_vpopcth(VectorRegister v1, VectorRegister v2); + inline void z_vpopctf(VectorRegister v1, VectorRegister v2); + inline void z_vpopctg(VectorRegister v1, VectorRegister v2); // Rotate/Shift inline void z_verllv( VectorRegister v1, VectorRegister v2, VectorRegister v3, int64_t m4); @@ -2898,9 +2920,39 @@ class Assembler : public AbstractAssembler { inline void z_vistrfs(VectorRegister v1, VectorRegister v2); - // Floatingpoint instructions + // Vector Floatingpoint instructions // ========================== + // Add + inline void z_vfa( VectorRegister v1, VectorRegister v2, VectorRegister v3, int64_t m4); + inline void z_vfasb(VectorRegister v1, VectorRegister v2, VectorRegister v3); + inline void z_vfadb(VectorRegister v1, VectorRegister v2, VectorRegister v3); + + //SUB + inline void z_vfs( VectorRegister v1, VectorRegister v2, VectorRegister v3, int64_t m4); + inline void z_vfssb(VectorRegister v1, VectorRegister v2, VectorRegister v3); + inline void z_vfsdb(VectorRegister v1, VectorRegister v2, VectorRegister v3); + + //MUL + inline void z_vfm( VectorRegister v1, VectorRegister v2, VectorRegister v3, int64_t m4); + inline void z_vfmsb(VectorRegister v1, VectorRegister v2, VectorRegister v3); + inline void z_vfmdb(VectorRegister v1, VectorRegister v2, VectorRegister v3); + + //DIV + inline void z_vfd( VectorRegister v1, VectorRegister v2, VectorRegister v3, int64_t m4); + inline void z_vfdsb(VectorRegister v1, VectorRegister v2, VectorRegister v3); + inline void z_vfddb(VectorRegister v1, VectorRegister v2, VectorRegister v3); + + //square root + inline void z_vfsq( VectorRegister v1, VectorRegister v2, int64_t m3); + inline void z_vfsqsb(VectorRegister v1, VectorRegister v2); + inline void z_vfsqdb(VectorRegister v1, VectorRegister v2); + + //vector fp load rounded + inline void z_vflr( VectorRegister v1, VectorRegister v2, int64_t m3, int64_t m5); + inline void z_vflrd( VectorRegister v1, VectorRegister v2, int64_t m5); + // Floatingpoint instructions + // ========================== // compare instructions inline void z_cebr(FloatRegister r1, FloatRegister r2); // compare (r1, r2) ; float inline void z_ceb(FloatRegister r1, int64_t d2, Register x2, Register b2); // compare (r1, *(d2_imm12+x2+b2)) ; float diff --git a/src/hotspot/cpu/s390/assembler_s390.inline.hpp b/src/hotspot/cpu/s390/assembler_s390.inline.hpp index 78ce87ddeb7..e9277b8bb6f 100644 --- a/src/hotspot/cpu/s390/assembler_s390.inline.hpp +++ b/src/hotspot/cpu/s390/assembler_s390.inline.hpp @@ -787,6 +787,7 @@ inline void Assembler::z_vleb( VectorRegister v1, int64_t d2, Register x2, Reg inline void Assembler::z_vleh( VectorRegister v1, int64_t d2, Register x2, Register b2, int64_t ix3){emit_48(VLEH_ZOPC | vreg(v1, 8) | rxmask_48(d2, x2, b2) | uimm4(ix3, 32, 48)); } inline void Assembler::z_vlef( VectorRegister v1, int64_t d2, Register x2, Register b2, int64_t ix3){emit_48(VLEF_ZOPC | vreg(v1, 8) | rxmask_48(d2, x2, b2) | uimm4(ix3, 32, 48)); } inline void Assembler::z_vleg( VectorRegister v1, int64_t d2, Register x2, Register b2, int64_t ix3){emit_48(VLEG_ZOPC | vreg(v1, 8) | rxmask_48(d2, x2, b2) | uimm4(ix3, 32, 48)); } +inline void Assembler::z_vl(VectorRegister v1, const Address& a) { z_vl(v1, a.disp(), a.indexOrR0(), a.baseOrR0()); } // Gather/Scatter inline void Assembler::z_vgef( VectorRegister v1, int64_t d2, VectorRegister vx2, Register b2, int64_t ix3) {emit_48(VGEF_ZOPC | vreg(v1, 8) | rvmask_48(d2, vx2, b2) | uimm4(ix3, 32, 48)); } @@ -820,7 +821,7 @@ inline void Assembler::z_vlgvh( Register r1, VectorRegister v3, int64_t d2, Reg inline void Assembler::z_vlgvf( Register r1, VectorRegister v3, int64_t d2, Register b2) {z_vlgv(r1, v3, d2, b2, VRET_FW); } // load FW from VR element (index d2(b2)) into GR (logical) inline void Assembler::z_vlgvg( Register r1, VectorRegister v3, int64_t d2, Register b2) {z_vlgv(r1, v3, d2, b2, VRET_DW); } // load DW from VR element (index d2(b2)) into GR. -inline void Assembler::z_vlvg( VectorRegister v1, Register r3, int64_t d2, Register b2, int64_t m4) {emit_48(VLVG_ZOPC | vreg(v1, 8) | reg(r3, 12, 48) | rsmask_48(d2, b2) | vesc_mask(m4, VRET_BYTE, VRET_DW, 32)); } +inline void Assembler::z_vlvg( VectorRegister v1, Register r3, int64_t d2, Register b2, int64_t m4) {emit_48(VLVG_ZOPC | vreg(v1, 8) | reg(r3, 12, 48) | rsmaskt_48(d2, b2) | vesc_mask(m4, VRET_BYTE, VRET_DW, 32)); } inline void Assembler::z_vlvgb( VectorRegister v1, Register r3, int64_t d2, Register b2) {z_vlvg(v1, r3, d2, b2, VRET_BYTE); } inline void Assembler::z_vlvgh( VectorRegister v1, Register r3, int64_t d2, Register b2) {z_vlvg(v1, r3, d2, b2, VRET_HW); } inline void Assembler::z_vlvgf( VectorRegister v1, Register r3, int64_t d2, Register b2) {z_vlvg(v1, r3, d2, b2, VRET_FW); } @@ -916,6 +917,7 @@ inline void Assembler::z_vsteh( VectorRegister v1, int64_t d2, Register x2, Reg inline void Assembler::z_vstef( VectorRegister v1, int64_t d2, Register x2, Register b2, int64_t ix3){emit_48(VSTEF_ZOPC | vreg(v1, 8) | rxmask_48(d2, x2, b2) | uimm4(ix3, 32, 48)); } inline void Assembler::z_vsteg( VectorRegister v1, int64_t d2, Register x2, Register b2, int64_t ix3){emit_48(VSTEG_ZOPC | vreg(v1, 8) | rxmask_48(d2, x2, b2) | uimm4(ix3, 32, 48)); } inline void Assembler::z_vstl( VectorRegister v1, Register r3, int64_t d2, Register b2) {emit_48(VSTL_ZOPC | vreg(v1, 8) | reg(r3, 12, 48) | rsmask_48(d2, b2)); } +inline void Assembler::z_vst(VectorRegister v1, const Address& a) { z_vst(v1, a.disp(), a.indexOrR0(), a.baseOrR0()); } // Misc inline void Assembler::z_vgm( VectorRegister v1, int64_t imm2, int64_t imm3, int64_t m4) {emit_48(VGM_ZOPC | vreg(v1, 8) | uimm8( imm2, 16, 48) | uimm8(imm3, 24, 48) | vesc_mask(m4, VRET_BYTE, VRET_DW, 32)); } @@ -973,6 +975,9 @@ inline void Assembler::z_vscbiq( VectorRegister v1, VectorRegister v2, VectorReg // MULTIPLY inline void Assembler::z_vml( VectorRegister v1, VectorRegister v2, VectorRegister v3, int64_t m4) {emit_48(VML_ZOPC | vreg(v1, 8) | vreg(v2, 12) | vreg(v3, 16) | vesc_mask(m4, VRET_BYTE, VRET_FW, 32)); } inline void Assembler::z_vmh( VectorRegister v1, VectorRegister v2, VectorRegister v3, int64_t m4) {emit_48(VMH_ZOPC | vreg(v1, 8) | vreg(v2, 12) | vreg(v3, 16) | vesc_mask(m4, VRET_BYTE, VRET_FW, 32)); } +inline void Assembler::z_vmlb( VectorRegister v1, VectorRegister v2, VectorRegister v3) {z_vml(v1, v2, v3, VRET_BYTE);} // vector element type 'B' +inline void Assembler::z_vmlhw( VectorRegister v1, VectorRegister v2, VectorRegister v3) {z_vml(v1, v2, v3, VRET_HW);} // vector element type 'H' +inline void Assembler::z_vmlf( VectorRegister v1, VectorRegister v2, VectorRegister v3) {z_vml(v1, v2, v3, VRET_FW);} // vector element type 'F' inline void Assembler::z_vmlh( VectorRegister v1, VectorRegister v2, VectorRegister v3, int64_t m4) {emit_48(VMLH_ZOPC | vreg(v1, 8) | vreg(v2, 12) | vreg(v3, 16) | vesc_mask(m4, VRET_BYTE, VRET_FW, 32)); } inline void Assembler::z_vme( VectorRegister v1, VectorRegister v2, VectorRegister v3, int64_t m4) {emit_48(VME_ZOPC | vreg(v1, 8) | vreg(v2, 12) | vreg(v3, 16) | vesc_mask(m4, VRET_BYTE, VRET_FW, 32)); } inline void Assembler::z_vmle( VectorRegister v1, VectorRegister v2, VectorRegister v3, int64_t m4) {emit_48(VMLE_ZOPC | vreg(v1, 8) | vreg(v2, 12) | vreg(v3, 16) | vesc_mask(m4, VRET_BYTE, VRET_FW, 32)); } @@ -1035,6 +1040,9 @@ inline void Assembler::z_vx( VectorRegister v1, VectorRegister v2, VectorReg // NOR inline void Assembler::z_vno( VectorRegister v1, VectorRegister v2, VectorRegister v3) {emit_48(VNO_ZOPC | vreg(v1, 8) | vreg(v2, 12) | vreg(v3, 16)); } +//NOT-XOR +inline void Assembler::z_vnx( VectorRegister v1, VectorRegister v2, VectorRegister v3) {emit_48(VNX_ZOPC | vreg(v1, 8) | vreg(v2, 12) | vreg(v3, 16)); } + // OR inline void Assembler::z_vo( VectorRegister v1, VectorRegister v2, VectorRegister v3) {emit_48(VO_ZOPC | vreg(v1, 8) | vreg(v2, 12) | vreg(v3, 16)); } @@ -1101,6 +1109,10 @@ inline void Assembler::z_vctzh( VectorRegister v1, VectorRegister v2) inline void Assembler::z_vctzf( VectorRegister v1, VectorRegister v2) {z_vctz(v1, v2, VRET_FW); } // vector element type 'F' inline void Assembler::z_vctzg( VectorRegister v1, VectorRegister v2) {z_vctz(v1, v2, VRET_DW); } // vector element type 'G' inline void Assembler::z_vpopct( VectorRegister v1, VectorRegister v2, int64_t m3) {emit_48(VPOPCT_ZOPC| vreg(v1, 8) | vreg(v2, 12) | vesc_mask(m3, VRET_BYTE, VRET_DW, 32)); } +inline void Assembler::z_vpopctb( VectorRegister v1, VectorRegister v2) {z_vpopct(v1, v2, VRET_BYTE); } +inline void Assembler::z_vpopcth( VectorRegister v1, VectorRegister v2) {z_vpopct(v1, v2, VRET_HW); } +inline void Assembler::z_vpopctf( VectorRegister v1, VectorRegister v2) {z_vpopct(v1, v2, VRET_FW); } +inline void Assembler::z_vpopctg( VectorRegister v1, VectorRegister v2) {z_vpopct(v1, v2, VRET_DW); } // Rotate/Shift inline void Assembler::z_verllv( VectorRegister v1, VectorRegister v2, VectorRegister v3, int64_t m4) {emit_48(VERLLV_ZOPC| vreg(v1, 8) | vreg(v2, 12) | vreg(v3, 16) | vesc_mask(m4, VRET_BYTE, VRET_DW, 32)); } @@ -1108,7 +1120,7 @@ inline void Assembler::z_verllvb(VectorRegister v1, VectorRegister v2, VectorReg inline void Assembler::z_verllvh(VectorRegister v1, VectorRegister v2, VectorRegister v3) {z_verllv(v1, v2, v3, VRET_HW); } // vector element type 'H' inline void Assembler::z_verllvf(VectorRegister v1, VectorRegister v2, VectorRegister v3) {z_verllv(v1, v2, v3, VRET_FW); } // vector element type 'F' inline void Assembler::z_verllvg(VectorRegister v1, VectorRegister v2, VectorRegister v3) {z_verllv(v1, v2, v3, VRET_DW); } // vector element type 'G' -inline void Assembler::z_verll( VectorRegister v1, VectorRegister v3, int64_t d2, Register b2, int64_t m4) {emit_48(VERLL_ZOPC | vreg(v1, 8) | vreg(v3, 12) | rsmask_48(d2, b2) | vesc_mask(m4, VRET_BYTE, VRET_DW, 32)); } +inline void Assembler::z_verll( VectorRegister v1, VectorRegister v3, int64_t d2, Register b2, int64_t m4) {emit_48(VERLL_ZOPC | vreg(v1, 8) | vreg(v3, 12) | rsmask_48(d2, b2) | vesc_mask(m4, VRET_BYTE, VRET_DW, 32)); } inline void Assembler::z_verllb( VectorRegister v1, VectorRegister v3, int64_t d2, Register b2) {z_verll(v1, v3, d2, b2, VRET_BYTE);}// vector element type 'B' inline void Assembler::z_verllh( VectorRegister v1, VectorRegister v3, int64_t d2, Register b2) {z_verll(v1, v3, d2, b2, VRET_HW);} // vector element type 'H' inline void Assembler::z_verllf( VectorRegister v1, VectorRegister v3, int64_t d2, Register b2) {z_verll(v1, v3, d2, b2, VRET_FW);} // vector element type 'F' @@ -1188,12 +1200,41 @@ inline void Assembler::z_vistrbs(VectorRegister v1, VectorRegister v2) inline void Assembler::z_vistrhs(VectorRegister v1, VectorRegister v2) {z_vistr(v1, v2, VRET_HW, VOPRC_CCSET); } inline void Assembler::z_vistrfs(VectorRegister v1, VectorRegister v2) {z_vistr(v1, v2, VRET_FW, VOPRC_CCSET); } +//------------------------------- +// Vector FLOAT INSTRUCTIONS +//------------------------------- +// ADD +inline void Assembler::z_vfa( VectorRegister v1, VectorRegister v2, VectorRegister v3, int64_t m4) {emit_48(VFA_ZOPC | vreg(v1, 8) | vreg(v2, 12) | vreg(v3, 16) | vesc_mask(m4, VRET_FW, VRET_QW, 32)); } +inline void Assembler::z_vfasb( VectorRegister v1, VectorRegister v2, VectorRegister v3) {z_vfa(v1, v2, v3, VRET_FW); } // vector element type 'F' +inline void Assembler::z_vfadb( VectorRegister v1, VectorRegister v2, VectorRegister v3) {z_vfa(v1, v2, v3, VRET_DW); } // vector element type 'G' + +// SUB +inline void Assembler::z_vfs( VectorRegister v1, VectorRegister v2, VectorRegister v3, int64_t m4) {emit_48(VFS_ZOPC | vreg(v1, 8) | vreg(v2, 12) | vreg(v3, 16) | vesc_mask(m4, VRET_FW, VRET_QW, 32)); } +inline void Assembler::z_vfssb( VectorRegister v1, VectorRegister v2, VectorRegister v3) {z_vfs(v1, v2, v3, VRET_FW); } // vector element type 'F' +inline void Assembler::z_vfsdb( VectorRegister v1, VectorRegister v2, VectorRegister v3) {z_vfs(v1, v2, v3, VRET_DW); } // vector element type 'G' + +// MUL +inline void Assembler::z_vfm( VectorRegister v1, VectorRegister v2, VectorRegister v3, int64_t m4) {emit_48(VFM_ZOPC | vreg(v1, 8) | vreg(v2, 12) | vreg(v3, 16) | vesc_mask(m4, VRET_FW, VRET_QW, 32)); } +inline void Assembler::z_vfmsb( VectorRegister v1, VectorRegister v2, VectorRegister v3) {z_vfm(v1, v2, v3, VRET_FW); } // vector element type 'F' +inline void Assembler::z_vfmdb( VectorRegister v1, VectorRegister v2, VectorRegister v3) {z_vfm(v1, v2, v3, VRET_DW); } // vector element type 'G' + +// DIV +inline void Assembler::z_vfd( VectorRegister v1, VectorRegister v2, VectorRegister v3, int64_t m4) {emit_48(VFD_ZOPC | vreg(v1, 8) | vreg(v2, 12) | vreg(v3, 16) | vesc_mask(m4, VRET_FW, VRET_QW, 32)); } +inline void Assembler::z_vfdsb( VectorRegister v1, VectorRegister v2, VectorRegister v3) {z_vfd(v1, v2, v3, VRET_FW); } // vector element type 'F' +inline void Assembler::z_vfddb( VectorRegister v1, VectorRegister v2, VectorRegister v3) {z_vfd(v1, v2, v3, VRET_DW); } // vector element type 'G' + +// square root +inline void Assembler::z_vfsq( VectorRegister v1, VectorRegister v2, int64_t m3) {emit_48(VFSQ_ZOPC | vreg(v1, 8) | vreg(v2, 12) | vesc_mask(m3, VRET_FW, VRET_QW, 32)); } +inline void Assembler::z_vfsqsb( VectorRegister v1, VectorRegister v2) {z_vfsq(v1, v2, VRET_FW); } +inline void Assembler::z_vfsqdb( VectorRegister v1, VectorRegister v2) {z_vfsq(v1, v2, VRET_DW); } + +// vector fp load rounded +inline void Assembler::z_vflr( VectorRegister v1, VectorRegister v2, int64_t m5, int64_t m3) {emit_48(VFLR_ZOPC | vreg(v1, 8) | vreg(v2, 12) | vesc_mask(m5, VRET_FW, 7, 24) | vesc_mask(m3, VRET_FW, VRET_QW, 32)); } +inline void Assembler::z_vflrd( VectorRegister v1, VectorRegister v2, int64_t m5) {z_vflr(v1, v2, m5, VRET_DW); } //------------------------------- // FLOAT INSTRUCTIONS //------------------------------- - -//---------------- // LOAD //---------------- inline void Assembler::z_ler( FloatRegister r1, FloatRegister r2) { emit_16( LER_ZOPC | fregt(r1,8,16) | freg(r2,12,16)); } diff --git a/src/hotspot/cpu/s390/c2_MacroAssembler_s390.cpp b/src/hotspot/cpu/s390/c2_MacroAssembler_s390.cpp index 378d5e4cfe1..c8393fe0e60 100644 --- a/src/hotspot/cpu/s390/c2_MacroAssembler_s390.cpp +++ b/src/hotspot/cpu/s390/c2_MacroAssembler_s390.cpp @@ -169,6 +169,7 @@ unsigned int C2_MacroAssembler::string_compress(Register result, Register src, R #endif clear_reg(Z_R0); // make sure register is properly initialized. +#if 0 if (VM_Version::has_VectorFacility()) { const int min_vcnt = 32; // Minimum #characters required to use vector instructions. // Otherwise just do nothing in vector mode. @@ -223,6 +224,7 @@ unsigned int C2_MacroAssembler::string_compress(Register result, Register src, R bind(VectorDone); } +#endif { const int min_cnt = 8; // Minimum #characters required to use unrolled loop. @@ -461,6 +463,7 @@ unsigned int C2_MacroAssembler::string_inflate(Register src, Register dst, Regis #endif clear_reg(Z_R0); // make sure register is properly initialized. +#if 0 if (VM_Version::has_VectorFacility()) { const int min_vcnt = 32; // Minimum #characters required to use vector instructions. // Otherwise just do nothing in vector mode. @@ -489,6 +492,7 @@ unsigned int C2_MacroAssembler::string_inflate(Register src, Register dst, Regis bind(VectorDone); } +#endif const int min_cnt = 8; // Minimum #characters required to use unrolled scalar loop. // Otherwise just do nothing in unrolled scalar mode. @@ -623,6 +627,7 @@ unsigned int C2_MacroAssembler::string_inflate_const(Register src, Register dst, bool restore_inputs = false; bool workreg_clear = false; +#if 0 if ((len >= 32) && VM_Version::has_VectorFacility()) { const int min_vcnt = 32; // Minimum #characters required to use vector instructions. // Otherwise just do nothing in vector mode. @@ -678,6 +683,7 @@ unsigned int C2_MacroAssembler::string_inflate_const(Register src, Register dst, src_off += min_vcnt; dst_off += min_vcnt*2; } +#endif if ((len-nprocessed) > 8) { const int min_cnt = 8; // Minimum #characters required to use unrolled scalar loop. diff --git a/src/hotspot/cpu/s390/c2_globals_s390.hpp b/src/hotspot/cpu/s390/c2_globals_s390.hpp index 0192cb716ba..1de38f100f6 100644 --- a/src/hotspot/cpu/s390/c2_globals_s390.hpp +++ b/src/hotspot/cpu/s390/c2_globals_s390.hpp @@ -60,7 +60,7 @@ define_pd_global(bool, UseCISCSpill, true); define_pd_global(bool, OptoBundling, false); define_pd_global(bool, OptoScheduling, false); define_pd_global(bool, OptoRegScheduling, false); -define_pd_global(bool, SuperWordLoopUnrollAnalysis, false); +define_pd_global(bool, SuperWordLoopUnrollAnalysis, true); // On s390x, we can clear the array with a single instruction, // so don't idealize it. define_pd_global(bool, IdealizeClearArrayNode, false); diff --git a/src/hotspot/cpu/s390/globals_s390.hpp b/src/hotspot/cpu/s390/globals_s390.hpp index fb5892ba62f..cf4be20397c 100644 --- a/src/hotspot/cpu/s390/globals_s390.hpp +++ b/src/hotspot/cpu/s390/globals_s390.hpp @@ -107,6 +107,11 @@ define_pd_global(intx, InitArrayShortSize, 1*BytesPerLong); /* Seems to pay off with 2 pages already. */ \ product(size_t, MVCLEThreshold, +2*(4*K), DIAGNOSTIC, \ "Threshold above which page-aligned MVCLE copy/init is used.") \ + /* special instructions */ \ + product(bool, SuperwordUseVX, false, \ + "Use Z15 Vector instructions for superword optimization.") \ + product(bool, UseSFPV, false, DIAGNOSTIC, \ + "Use SFPV Vector instructions for superword optimization.") \ \ product(bool, PreferLAoverADD, false, DIAGNOSTIC, \ "Use LA/LAY instructions over ADD instructions (z/Architecture).") \ diff --git a/src/hotspot/cpu/s390/registerSaver_s390.hpp b/src/hotspot/cpu/s390/registerSaver_s390.hpp index 97883685384..13674f1562d 100644 --- a/src/hotspot/cpu/s390/registerSaver_s390.hpp +++ b/src/hotspot/cpu/s390/registerSaver_s390.hpp @@ -47,10 +47,11 @@ class RegisterSaver { // Boolean flags to force only argument registers to be saved. static int live_reg_save_size(RegisterSet reg_set); - static int live_reg_frame_size(RegisterSet reg_set); + static int live_reg_frame_size(RegisterSet reg_set, bool save_vectors = false); + static int calculate_vregstosave_num(); // Specify the register that should be stored as the return pc in the current frame. - static OopMap* save_live_registers(MacroAssembler* masm, RegisterSet reg_set, Register return_pc = Z_R14); - static void restore_live_registers(MacroAssembler* masm, RegisterSet reg_set); + static OopMap* save_live_registers(MacroAssembler* masm, RegisterSet reg_set, Register return_pc = Z_R14, bool save_vectors = false); + static void restore_live_registers(MacroAssembler* masm, RegisterSet reg_set, bool save_vectors = false); // Generate the OopMap (again, regs where saved before). static OopMap* generate_oop_map(MacroAssembler* masm, RegisterSet reg_set); @@ -65,11 +66,13 @@ class RegisterSaver { int_reg = 0, float_reg = 1, excluded_reg = 2, // Not saved/restored. + v_reg = 3 } RegisterType; typedef enum { reg_size = 8, half_reg_size = reg_size / 2, + v_reg_size = 16 } RegisterConstants; // Remember type, number, and VMReg. diff --git a/src/hotspot/cpu/s390/register_s390.cpp b/src/hotspot/cpu/s390/register_s390.cpp index f055a1c0134..c0840add5d6 100644 --- a/src/hotspot/cpu/s390/register_s390.cpp +++ b/src/hotspot/cpu/s390/register_s390.cpp @@ -26,11 +26,6 @@ #include "precompiled.hpp" #include "register_s390.hpp" - -const int ConcreteRegisterImpl::max_gpr = Register::number_of_registers * 2; -const int ConcreteRegisterImpl::max_fpr = ConcreteRegisterImpl::max_gpr + - FloatRegister::number_of_registers * 2; - const char* Register::name() const { const char* names[number_of_registers] = { "Z_R0", "Z_R1", "Z_R2", "Z_R3", "Z_R4", "Z_R5", "Z_R6", "Z_R7", @@ -54,5 +49,11 @@ const char* VectorRegister::name() const { "Z_V16", "Z_V17", "Z_V18", "Z_V19", "Z_V20", "Z_V21", "Z_V22", "Z_V23", "Z_V24", "Z_V25", "Z_V26", "Z_V27", "Z_V28", "Z_V29", "Z_V30", "Z_V31" }; - return is_valid() ? names[encoding()] : "fnoreg"; + return is_valid() ? names[encoding()] : "vnoreg"; +} + +// Method to convert a FloatRegister to a VectorRegister (VectorRegister) +VectorRegister FloatRegister::to_vr() const { + if (*this == fnoreg) { return vnoreg; } + return as_VectorRegister(encoding()); } diff --git a/src/hotspot/cpu/s390/register_s390.hpp b/src/hotspot/cpu/s390/register_s390.hpp index 18af232e569..6fcba746cd3 100644 --- a/src/hotspot/cpu/s390/register_s390.hpp +++ b/src/hotspot/cpu/s390/register_s390.hpp @@ -64,6 +64,7 @@ class Register { public: enum { number_of_registers = 16, + max_slots_per_register = 2, number_of_arg_registers = 5 }; @@ -164,12 +165,13 @@ constexpr ConditionRegister Z_CR = as_ConditionRegister(0); //========================= // The implementation of float registers for the z/Architecture. - +class VectorRegister; class FloatRegister { int _encoding; public: enum { number_of_registers = 16, + max_slots_per_register = 2, number_of_arg_registers = 4 }; @@ -192,6 +194,8 @@ class FloatRegister { constexpr bool is_nonvolatile() const { return (8 <= _encoding && _encoding <= 15); } const char* name() const; + // convert to VR + VectorRegister to_vr() const; }; inline constexpr FloatRegister as_FloatRegister(int encoding) { @@ -285,6 +289,7 @@ class VectorRegister { public: enum { number_of_registers = 32, + max_slots_per_register = 4, number_of_arg_registers = 0 }; @@ -379,21 +384,20 @@ constexpr VectorRegister Z_V31 = as_VectorRegister(31); // Need to know the total number of registers of all sorts for SharedInfo. // Define a class that exports it. - class ConcreteRegisterImpl : public AbstractRegisterImpl { public: enum { - number_of_registers = - (Register::number_of_registers + - FloatRegister::number_of_registers) - * 2 // register halves - + 1 // condition code register + max_gpr = Register::number_of_registers * Register::max_slots_per_register, + max_fpr = max_gpr + FloatRegister::number_of_registers * FloatRegister::max_slots_per_register, + max_vr = max_fpr + VectorRegister::number_of_registers * VectorRegister::max_slots_per_register, + // A big enough number for C2: all the registers plus flags + // This number must be large enough to cover REG_COUNT (defined by c2) registers. + // There is no requirement that any ordering here matches any ordering c2 gives + // it's optoregs. + number_of_registers = max_vr + 1 // gpr/fpr/vr + flags }; - static const int max_gpr; - static const int max_fpr; }; - // Common register declarations used in assembler code. constexpr Register Z_EXC_OOP = Z_R2; constexpr Register Z_EXC_PC = Z_R3; diff --git a/src/hotspot/cpu/s390/s390.ad b/src/hotspot/cpu/s390/s390.ad index 63e150c9e9c..e1a98139992 100644 --- a/src/hotspot/cpu/s390/s390.ad +++ b/src/hotspot/cpu/s390/s390.ad @@ -97,8 +97,9 @@ register %{ // e.g. Z_R3_H, which is needed by the allocator, but is not used // for stores, loads, etc. - // Integer/Long Registers - // ---------------------------- +// ---------------------------- +// Integer/Long Registers +// ---------------------------- // z/Architecture has 16 64-bit integer registers. @@ -136,7 +137,9 @@ register %{ reg_def Z_R15 (NS, NS, Op_RegI, 15, Z_R15->as_VMReg()); // s SP reg_def Z_R15_H(NS, NS, Op_RegI, 99, Z_R15->as_VMReg()->next()); - // Float/Double Registers +// ---------------------------- +// Float/Double Registers +// ---------------------------- // The rules of ADL require that double registers be defined in pairs. // Each pair must be two 32-bit values, but not necessarily a pair of @@ -182,7 +185,169 @@ register %{ reg_def Z_F15 (SOC, SOE, Op_RegF, 15, Z_F15->as_VMReg()); reg_def Z_F15_H(SOC, SOE, Op_RegF, 99, Z_F15->as_VMReg()->next()); - +// ---------------------------- +// Vector Registers +// ---------------------------- + // 1st 16 VRs are aliases for the FPRs which are already defined above. + reg_def Z_VR0 ( SOC, SOC, Op_RegF, 0, VMRegImpl::Bad()); + reg_def Z_VR0_H ( SOC, SOC, Op_RegF, 0, VMRegImpl::Bad()); + reg_def Z_VR0_J ( SOC, SOC, Op_RegF, 0, VMRegImpl::Bad()); + reg_def Z_VR0_K ( SOC, SOC, Op_RegF, 0, VMRegImpl::Bad()); + + reg_def Z_VR1 ( SOC, SOC, Op_RegF, 1, VMRegImpl::Bad()); + reg_def Z_VR1_H ( SOC, SOC, Op_RegF, 1, VMRegImpl::Bad()); + reg_def Z_VR1_J ( SOC, SOC, Op_RegF, 1, VMRegImpl::Bad()); + reg_def Z_VR1_K ( SOC, SOC, Op_RegF, 1, VMRegImpl::Bad()); + + reg_def Z_VR2 ( SOC, SOC, Op_RegF, 2, VMRegImpl::Bad()); + reg_def Z_VR2_H ( SOC, SOC, Op_RegF, 2, VMRegImpl::Bad()); + reg_def Z_VR2_J ( SOC, SOC, Op_RegF, 2, VMRegImpl::Bad()); + reg_def Z_VR2_K ( SOC, SOC, Op_RegF, 2, VMRegImpl::Bad()); + + reg_def Z_VR3 ( SOC, SOC, Op_RegF, 3, VMRegImpl::Bad()); + reg_def Z_VR3_H ( SOC, SOC, Op_RegF, 3, VMRegImpl::Bad()); + reg_def Z_VR3_J ( SOC, SOC, Op_RegF, 3, VMRegImpl::Bad()); + reg_def Z_VR3_K ( SOC, SOC, Op_RegF, 3, VMRegImpl::Bad()); + + reg_def Z_VR4 ( SOC, SOC, Op_RegF, 4, VMRegImpl::Bad()); + reg_def Z_VR4_H ( SOC, SOC, Op_RegF, 4, VMRegImpl::Bad()); + reg_def Z_VR4_J ( SOC, SOC, Op_RegF, 4, VMRegImpl::Bad()); + reg_def Z_VR4_K ( SOC, SOC, Op_RegF, 4, VMRegImpl::Bad()); + + reg_def Z_VR5 ( SOC, SOC, Op_RegF, 5, VMRegImpl::Bad()); + reg_def Z_VR5_H ( SOC, SOC, Op_RegF, 5, VMRegImpl::Bad()); + reg_def Z_VR5_J ( SOC, SOC, Op_RegF, 5, VMRegImpl::Bad()); + reg_def Z_VR5_K ( SOC, SOC, Op_RegF, 5, VMRegImpl::Bad()); + + reg_def Z_VR6 ( SOC, SOC, Op_RegF, 6, VMRegImpl::Bad()); + reg_def Z_VR6_H ( SOC, SOC, Op_RegF, 6, VMRegImpl::Bad()); + reg_def Z_VR6_J ( SOC, SOC, Op_RegF, 6, VMRegImpl::Bad()); + reg_def Z_VR6_K ( SOC, SOC, Op_RegF, 6, VMRegImpl::Bad()); + + reg_def Z_VR7 ( SOC, SOC, Op_RegF, 7, VMRegImpl::Bad()); + reg_def Z_VR7_H ( SOC, SOC, Op_RegF, 7, VMRegImpl::Bad()); + reg_def Z_VR7_J ( SOC, SOC, Op_RegF, 7, VMRegImpl::Bad()); + reg_def Z_VR7_K ( SOC, SOC, Op_RegF, 7, VMRegImpl::Bad()); + + reg_def Z_VR8 ( SOC, SOC, Op_RegF, 8, VMRegImpl::Bad()); + reg_def Z_VR8_H ( SOC, SOC, Op_RegF, 8, VMRegImpl::Bad()); + reg_def Z_VR8_J ( SOC, SOC, Op_RegF, 8, VMRegImpl::Bad()); + reg_def Z_VR8_K ( SOC, SOC, Op_RegF, 8, VMRegImpl::Bad()); + + reg_def Z_VR9 ( SOC, SOC, Op_RegF, 9, VMRegImpl::Bad()); + reg_def Z_VR9_H ( SOC, SOC, Op_RegF, 9, VMRegImpl::Bad()); + reg_def Z_VR9_J ( SOC, SOC, Op_RegF, 9, VMRegImpl::Bad()); + reg_def Z_VR9_K ( SOC, SOC, Op_RegF, 9, VMRegImpl::Bad()); + + reg_def Z_VR10 ( SOC, SOC, Op_RegF, 10, VMRegImpl::Bad()); + reg_def Z_VR10_H ( SOC, SOC, Op_RegF, 10, VMRegImpl::Bad()); + reg_def Z_VR10_J ( SOC, SOC, Op_RegF, 10, VMRegImpl::Bad()); + reg_def Z_VR10_K ( SOC, SOC, Op_RegF, 10, VMRegImpl::Bad()); + + reg_def Z_VR11 ( SOC, SOC, Op_RegF, 11, VMRegImpl::Bad()); + reg_def Z_VR11_H ( SOC, SOC, Op_RegF, 11, VMRegImpl::Bad()); + reg_def Z_VR11_J ( SOC, SOC, Op_RegF, 11, VMRegImpl::Bad()); + reg_def Z_VR11_K ( SOC, SOC, Op_RegF, 11, VMRegImpl::Bad()); + + reg_def Z_VR12 ( SOC, SOC, Op_RegF, 12, VMRegImpl::Bad()); + reg_def Z_VR12_H ( SOC, SOC, Op_RegF, 12, VMRegImpl::Bad()); + reg_def Z_VR12_J ( SOC, SOC, Op_RegF, 12, VMRegImpl::Bad()); + reg_def Z_VR12_K ( SOC, SOC, Op_RegF, 12, VMRegImpl::Bad()); + + reg_def Z_VR13 ( SOC, SOC, Op_RegF, 13, VMRegImpl::Bad()); + reg_def Z_VR13_H ( SOC, SOC, Op_RegF, 13, VMRegImpl::Bad()); + reg_def Z_VR13_J ( SOC, SOC, Op_RegF, 13, VMRegImpl::Bad()); + reg_def Z_VR13_K ( SOC, SOC, Op_RegF, 13, VMRegImpl::Bad()); + + reg_def Z_VR14 ( SOC, SOC, Op_RegF, 14, VMRegImpl::Bad()); + reg_def Z_VR14_H ( SOC, SOC, Op_RegF, 14, VMRegImpl::Bad()); + reg_def Z_VR14_J ( SOC, SOC, Op_RegF, 14, VMRegImpl::Bad()); + reg_def Z_VR14_K ( SOC, SOC, Op_RegF, 14, VMRegImpl::Bad()); + + reg_def Z_VR15 ( SOC, SOC, Op_RegF, 15, VMRegImpl::Bad()); + reg_def Z_VR15_H ( SOC, SOC, Op_RegF, 15, VMRegImpl::Bad()); + reg_def Z_VR15_J ( SOC, SOC, Op_RegF, 15, VMRegImpl::Bad()); + reg_def Z_VR15_K ( SOC, SOC, Op_RegF, 15, VMRegImpl::Bad()); + + reg_def Z_VR16 ( SOC, SOC, Op_RegF, 16, Z_V16->as_VMReg() ); + reg_def Z_VR16_H ( SOC, SOC, Op_RegF, 16, Z_V16->as_VMReg()->next() ); + reg_def Z_VR16_J ( SOC, SOC, Op_RegF, 16, Z_V16->as_VMReg()->next(2) ); + reg_def Z_VR16_K ( SOC, SOC, Op_RegF, 16, Z_V16->as_VMReg()->next(3) ); + + reg_def Z_VR17 ( SOC, SOC, Op_RegF, 17, Z_V17->as_VMReg() ); + reg_def Z_VR17_H ( SOC, SOC, Op_RegF, 17, Z_V17->as_VMReg()->next() ); + reg_def Z_VR17_J ( SOC, SOC, Op_RegF, 17, Z_V17->as_VMReg()->next(2) ); + reg_def Z_VR17_K ( SOC, SOC, Op_RegF, 17, Z_V17->as_VMReg()->next(3) ); + + reg_def Z_VR18 ( SOC, SOC, Op_RegF, 18, Z_V18->as_VMReg() ); + reg_def Z_VR18_H ( SOC, SOC, Op_RegF, 18, Z_V18->as_VMReg()->next() ); + reg_def Z_VR18_J ( SOC, SOC, Op_RegF, 18, Z_V18->as_VMReg()->next(2) ); + reg_def Z_VR18_K ( SOC, SOC, Op_RegF, 18, Z_V18->as_VMReg()->next(3) ); + + reg_def Z_VR19 ( SOC, SOC, Op_RegF, 19, Z_V19->as_VMReg() ); + reg_def Z_VR19_H ( SOC, SOC, Op_RegF, 19, Z_V19->as_VMReg()->next() ); + reg_def Z_VR19_J ( SOC, SOC, Op_RegF, 19, Z_V19->as_VMReg()->next(2) ); + reg_def Z_VR19_K ( SOC, SOC, Op_RegF, 19, Z_V19->as_VMReg()->next(3) ); + + reg_def Z_VR20 ( SOC, SOC, Op_RegF, 20, Z_V20->as_VMReg() ); + reg_def Z_VR20_H ( SOC, SOC, Op_RegF, 20, Z_V20->as_VMReg()->next() ); + reg_def Z_VR20_J ( SOC, SOC, Op_RegF, 20, Z_V20->as_VMReg()->next(2) ); + reg_def Z_VR20_K ( SOC, SOC, Op_RegF, 20, Z_V20->as_VMReg()->next(3) ); + + reg_def Z_VR21 ( SOC, SOC, Op_RegF, 21, Z_V21->as_VMReg() ); + reg_def Z_VR21_H ( SOC, SOC, Op_RegF, 21, Z_V21->as_VMReg()->next() ); + reg_def Z_VR21_J ( SOC, SOC, Op_RegF, 21, Z_V21->as_VMReg()->next(2) ); + reg_def Z_VR21_K ( SOC, SOC, Op_RegF, 21, Z_V21->as_VMReg()->next(3) ); + + reg_def Z_VR22 ( SOC, SOC, Op_RegF, 22, Z_V22->as_VMReg() ); + reg_def Z_VR22_H ( SOC, SOC, Op_RegF, 22, Z_V22->as_VMReg()->next() ); + reg_def Z_VR22_J ( SOC, SOC, Op_RegF, 22, Z_V22->as_VMReg()->next(2) ); + reg_def Z_VR22_K ( SOC, SOC, Op_RegF, 22, Z_V22->as_VMReg()->next(3) ); + + reg_def Z_VR23 ( SOC, SOC, Op_RegF, 23, Z_V23->as_VMReg() ); + reg_def Z_VR23_H ( SOC, SOC, Op_RegF, 23, Z_V23->as_VMReg()->next() ); + reg_def Z_VR23_J ( SOC, SOC, Op_RegF, 23, Z_V23->as_VMReg()->next(2) ); + reg_def Z_VR23_K ( SOC, SOC, Op_RegF, 23, Z_V23->as_VMReg()->next(3) ); + + reg_def Z_VR24 ( SOC, SOC, Op_RegF, 24, Z_V24->as_VMReg() ); + reg_def Z_VR24_H ( SOC, SOC, Op_RegF, 24, Z_V24->as_VMReg()->next() ); + reg_def Z_VR24_J ( SOC, SOC, Op_RegF, 24, Z_V24->as_VMReg()->next(2) ); + reg_def Z_VR24_K ( SOC, SOC, Op_RegF, 24, Z_V24->as_VMReg()->next(3) ); + + reg_def Z_VR25 ( SOC, SOC, Op_RegF, 25, Z_V25->as_VMReg() ); + reg_def Z_VR25_H ( SOC, SOC, Op_RegF, 25, Z_V25->as_VMReg()->next() ); + reg_def Z_VR25_J ( SOC, SOC, Op_RegF, 25, Z_V25->as_VMReg()->next(2) ); + reg_def Z_VR25_K ( SOC, SOC, Op_RegF, 25, Z_V25->as_VMReg()->next(3) ); + + reg_def Z_VR26 ( SOC, SOC, Op_RegF, 26, Z_V26->as_VMReg() ); + reg_def Z_VR26_H ( SOC, SOC, Op_RegF, 26, Z_V26->as_VMReg()->next() ); + reg_def Z_VR26_J ( SOC, SOC, Op_RegF, 26, Z_V26->as_VMReg()->next(2) ); + reg_def Z_VR26_K ( SOC, SOC, Op_RegF, 26, Z_V26->as_VMReg()->next(3) ); + + reg_def Z_VR27 ( SOC, SOC, Op_RegF, 27, Z_V27->as_VMReg() ); + reg_def Z_VR27_H ( SOC, SOC, Op_RegF, 27, Z_V27->as_VMReg()->next() ); + reg_def Z_VR27_J ( SOC, SOC, Op_RegF, 27, Z_V27->as_VMReg()->next(2) ); + reg_def Z_VR27_K ( SOC, SOC, Op_RegF, 27, Z_V27->as_VMReg()->next(3) ); + + reg_def Z_VR28 ( SOC, SOC, Op_RegF, 28, Z_V28->as_VMReg() ); + reg_def Z_VR28_H ( SOC, SOC, Op_RegF, 28, Z_V28->as_VMReg()->next() ); + reg_def Z_VR28_J ( SOC, SOC, Op_RegF, 28, Z_V28->as_VMReg()->next(2) ); + reg_def Z_VR28_K ( SOC, SOC, Op_RegF, 28, Z_V28->as_VMReg()->next(3) ); + + reg_def Z_VR29 ( SOC, SOC, Op_RegF, 29, Z_V29->as_VMReg() ); + reg_def Z_VR29_H ( SOC, SOC, Op_RegF, 29, Z_V29->as_VMReg()->next() ); + reg_def Z_VR29_J ( SOC, SOC, Op_RegF, 29, Z_V29->as_VMReg()->next(2) ); + reg_def Z_VR29_K ( SOC, SOC, Op_RegF, 29, Z_V29->as_VMReg()->next(3) ); + + reg_def Z_VR30 ( SOC, SOC, Op_RegF, 30, Z_V30->as_VMReg() ); + reg_def Z_VR30_H ( SOC, SOC, Op_RegF, 30, Z_V30->as_VMReg()->next() ); + reg_def Z_VR30_J ( SOC, SOC, Op_RegF, 30, Z_V30->as_VMReg()->next(2) ); + reg_def Z_VR30_K ( SOC, SOC, Op_RegF, 30, Z_V30->as_VMReg()->next(3) ); + + reg_def Z_VR31 ( SOC, SOC, Op_RegF, 31, Z_V31->as_VMReg() ); + reg_def Z_VR31_H ( SOC, SOC, Op_RegF, 31, Z_V31->as_VMReg()->next() ); + reg_def Z_VR31_J ( SOC, SOC, Op_RegF, 31, Z_V31->as_VMReg()->next(2) ); + reg_def Z_VR31_K ( SOC, SOC, Op_RegF, 31, Z_V31->as_VMReg()->next(3) ); // Special Registers // Condition Codes Flag Registers @@ -194,7 +359,6 @@ register %{ reg_def Z_CR(SOC, SOC, Op_RegFlags, 0, Z_CR->as_VMReg()); // volatile - // Specify priority of register selection within phases of register // allocation. Highest priority is first. A useful heuristic is to // give registers a low priority when they are required by machine @@ -268,6 +432,41 @@ alloc_class chunk1( ); alloc_class chunk2( + Z_VR0, Z_VR0_H, Z_VR0_J, Z_VR0_K, + Z_VR1, Z_VR1_H, Z_VR1_J, Z_VR1_K, + Z_VR2, Z_VR2_H, Z_VR2_J, Z_VR2_K, + Z_VR3, Z_VR3_H, Z_VR3_J, Z_VR3_K, + Z_VR4, Z_VR4_H, Z_VR4_J, Z_VR4_K, + Z_VR5, Z_VR5_H, Z_VR5_J, Z_VR5_K, + Z_VR6, Z_VR6_H, Z_VR6_J, Z_VR6_K, + Z_VR7, Z_VR7_H, Z_VR7_J, Z_VR7_K, + Z_VR8, Z_VR8_H, Z_VR8_J, Z_VR8_K, + Z_VR9, Z_VR9_H, Z_VR9_J, Z_VR9_K, + Z_VR10, Z_VR10_H, Z_VR10_J, Z_VR10_K, + Z_VR11, Z_VR11_H, Z_VR11_J, Z_VR11_K, + Z_VR12, Z_VR12_H, Z_VR12_J, Z_VR12_K, + Z_VR13, Z_VR13_H, Z_VR13_J, Z_VR13_K, + Z_VR14, Z_VR14_H, Z_VR14_J, Z_VR14_K, + Z_VR15, Z_VR15_H, Z_VR15_J, Z_VR15_K, + Z_VR16, Z_VR16_H, Z_VR16_J, Z_VR16_K, + Z_VR17, Z_VR17_H, Z_VR17_J, Z_VR17_K, + Z_VR18, Z_VR18_H, Z_VR18_J, Z_VR18_K, + Z_VR19, Z_VR19_H, Z_VR19_J, Z_VR19_K, + Z_VR20, Z_VR20_H, Z_VR20_J, Z_VR20_K, + Z_VR21, Z_VR21_H, Z_VR21_J, Z_VR21_K, + Z_VR22, Z_VR22_H, Z_VR22_J, Z_VR22_K, + Z_VR23, Z_VR23_H, Z_VR23_J, Z_VR23_K, + Z_VR24, Z_VR24_H, Z_VR24_J, Z_VR24_K, + Z_VR25, Z_VR25_H, Z_VR25_J, Z_VR25_K, + Z_VR26, Z_VR26_H, Z_VR26_J, Z_VR26_K, + Z_VR27, Z_VR27_H, Z_VR27_J, Z_VR27_K, + Z_VR28, Z_VR28_H, Z_VR28_J, Z_VR28_K, + Z_VR29, Z_VR29_H, Z_VR29_J, Z_VR29_K, + Z_VR30, Z_VR30_H, Z_VR30_J, Z_VR30_K, + Z_VR31, Z_VR31_H, Z_VR31_J, Z_VR31_K +); + +alloc_class chunk3( Z_CR ); @@ -542,6 +741,27 @@ reg_class z_dbl_reg( ); reg_class z_rscratch1_dbl_reg(Z_F1,Z_F1_H); +reg_class z_v_reg( + // Attention: Only these ones are saved & restored at safepoint by RegisterSaver. + //1st 16 VRs overlaps with 1st 16 FPRs. + Z_VR16, Z_VR16_H, Z_VR16_J, Z_VR16_K, + Z_VR17, Z_VR17_H, Z_VR17_J, Z_VR17_K, + Z_VR18, Z_VR18_H, Z_VR18_J, Z_VR18_K, + Z_VR19, Z_VR19_H, Z_VR19_J, Z_VR19_K, + Z_VR20, Z_VR20_H, Z_VR20_J, Z_VR20_K, + Z_VR21, Z_VR21_H, Z_VR21_J, Z_VR21_K, + Z_VR22, Z_VR22_H, Z_VR22_J, Z_VR22_K, + Z_VR23, Z_VR23_H, Z_VR23_J, Z_VR23_K, + Z_VR24, Z_VR24_H, Z_VR24_J, Z_VR24_K, + Z_VR25, Z_VR25_H, Z_VR25_J, Z_VR25_K, + Z_VR26, Z_VR26_H, Z_VR26_J, Z_VR26_K, + Z_VR27, Z_VR27_H, Z_VR27_J, Z_VR27_K, + Z_VR28, Z_VR28_H, Z_VR28_J, Z_VR28_K, + Z_VR29, Z_VR29_H, Z_VR29_J, Z_VR29_K, + Z_VR30, Z_VR30_H, Z_VR30_J, Z_VR30_K, + Z_VR31, Z_VR31_H, Z_VR31_J, Z_VR31_K +); + %} //----------DEFINITION BLOCK--------------------------------------------------- @@ -953,8 +1173,8 @@ const Pipeline * MachEpilogNode::pipeline() const { //============================================================================= -// Figure out which register class each belongs in: rc_int, rc_float, rc_stack. -enum RC { rc_bad, rc_int, rc_float, rc_stack }; +// Figure out which register class each belongs in: rc_int, rc_float, rc_vector, rc_stack. +enum RC { rc_bad, rc_int, rc_float, rc_vector, rc_stack }; static enum RC rc_class(OptoReg::Name reg) { // Return the register class for the given register. The given register @@ -975,8 +1195,13 @@ static enum RC rc_class(OptoReg::Name reg) { return rc_float; } + // we have 128 vector register halves at index 64 + if (reg < 32+32+128) { + return rc_vector; + } + // Between float regs & stack are the flags regs. - assert(reg >= OptoReg::stack0(), "blow up if spilling flags"); + assert(OptoReg::is_stack(reg) || reg < 32+32+128, "blow up if spilling flags"); return rc_stack; } @@ -1035,7 +1260,7 @@ uint MachSpillCopyNode::implementation(C2_MacroAssembler *masm, PhaseRegAlloc *r "expected aligned-adjacent pairs"); // Generate spill code! - + int size = 0; if (src_lo == dst_lo && src_hi == dst_hi) { return 0; // Self copy, no move. } @@ -1049,6 +1274,37 @@ uint MachSpillCopyNode::implementation(C2_MacroAssembler *masm, PhaseRegAlloc *r const char *mnemo = nullptr; unsigned long opc = 0; + if (bottom_type()->isa_vect() != nullptr && ideal_reg() == Op_VecX) { + if (src_lo_rc == rc_stack && dst_lo_rc == rc_stack) { + if (masm != nullptr) { + __ z_mvc(Address(Z_SP, 0, dst_offset), Address(Z_SP, 0, src_offset), 16); + } + size += 6; + } else if (src_lo_rc == rc_vector && dst_lo_rc == rc_stack) { + VectorRegister Rsrc = as_VectorRegister(Matcher::_regEncode[src_lo]); + if (masm != nullptr) { + __ z_vst(Rsrc, Address(Z_SP, 0, dst_offset)); + } + size += 6; + } else if (src_lo_rc == rc_stack && dst_lo_rc == rc_vector) { + VectorRegister Rdst = as_VectorRegister(Matcher::_regEncode[dst_lo]); + if (masm != nullptr) { + __ z_vl(Rdst, Address(Z_SP, 0, src_offset)); + } + size += 6; + } else if (src_lo_rc == rc_vector && dst_lo_rc == rc_vector) { + VectorRegister Rsrc = as_VectorRegister(Matcher::_regEncode[src_lo]); + VectorRegister Rdst = as_VectorRegister(Matcher::_regEncode[dst_lo]); + if (masm != nullptr) { + __ z_vlr(Rdst, Rsrc); + } + size += 6; + } else { + ShouldNotReachHere(); + } + return size; + } + // Memory->Memory Spill. Use Z_R0 to hold the value. if (src_lo_rc == rc_stack && dst_lo_rc == rc_stack) { @@ -1283,7 +1539,7 @@ source_hpp %{ // // To keep related declarations/definitions/uses close together, // we switch between source %{ }% and source_hpp %{ }% freely as needed. - +#include "opto/convertnode.hpp" #include "oops/klass.inline.hpp" //-------------------------------------------------------------- @@ -1446,6 +1702,32 @@ bool Matcher::match_rule_supported(int opcode) { case Op_PopCountL: // PopCount supported by H/W from z/Architecture G5 (z196) on. return (UsePopCountInstruction && VM_Version::has_PopCount()); + case Op_AddVB: + case Op_AddVS: + case Op_AddVI: + case Op_AddVL: + case Op_AddVD: + case Op_SubVB: + case Op_SubVS: + case Op_SubVI: + case Op_SubVL: + case Op_SubVD: + case Op_MulVB: + case Op_MulVS: + case Op_MulVI: + case Op_MulVD: + case Op_DivVD: + case Op_SqrtVD: + case Op_RoundDoubleModeV: + return SuperwordUseVX; + case Op_AddVF: + case Op_SubVF: + case Op_MulVF: + case Op_DivVF: + case Op_SqrtVF: + //PopCountVI supported by z14 onwards. + case Op_PopCountVI: + return (SuperwordUseVX && UseSFPV); case Op_FmaF: case Op_FmaD: return UseFMA; @@ -1491,14 +1773,24 @@ OptoRegPair Matcher::vector_return_value(uint ideal_reg) { // Vector width in bytes. int Matcher::vector_width_in_bytes(BasicType bt) { - assert(MaxVectorSize == 8, ""); - return 8; + if (SuperwordUseVX) { + assert(MaxVectorSize == 16, ""); + return 16; + } else { + assert(MaxVectorSize == 8, ""); + return 8; + } } // Vector ideal reg. uint Matcher::vector_ideal_reg(int size) { - assert(MaxVectorSize == 8 && size == 8, ""); - return Op_RegL; + if (SuperwordUseVX) { + assert(MaxVectorSize == 16 && size == 16, ""); + return Op_VecX; + } else { + assert(MaxVectorSize == 8 && size == 8, ""); + return Op_RegL; + } } // Limits on vector size (number of elements) loaded into vector. @@ -2391,6 +2683,14 @@ ins_attrib ins_should_rematerialize(false); // Immediate Operands // Please note: // Formats are generated automatically for constants and base registers. +operand vecX() %{ + constraint(ALLOC_IN_RC(z_v_reg)); + match(VecX); + + format %{ %} + interface(REG_INTER); +%} + //---------------------------------------------- // SIGNED (shorter than INT) immediate operands @@ -10534,6 +10834,45 @@ instruct Repl4S_immm1(iRegL dst, immS_minus1 src) %{ ins_pipe(pipe_class_dummy); %} +instruct repl8S_reg_Ex(vecX dst, iRegI src) %{ + match(Set dst (Replicate src)); + predicate(n->as_Vector()->length() == 8 && + Matcher::vector_element_basic_type(n) == T_SHORT); + + size(12); + ins_encode %{ + __ z_vlvgh($dst$$VectorRegister, $src$$Register, 0); + __ z_vreph($dst$$VectorRegister, $dst$$VectorRegister, 0); + %} + ins_pipe(pipe_class_dummy); +%} + +instruct repl8S_immIminus1(vecX dst, immI_minus1 src) %{ + match(Set dst (Replicate src)); + predicate(n->as_Vector()->length() == 8 && + Matcher::vector_element_basic_type(n) == T_SHORT); + + format %{ "VONE $dst, $src \t// replicate8S" %} + size(6); + ins_encode %{ + __ z_vone($dst$$VectorRegister); + %} + ins_pipe(pipe_class_dummy); +%} + +instruct repl8S_immI0(vecX dst, immI_0 zero) %{ + match(Set dst (Replicate zero)); + predicate(n->as_Vector()->length() == 8 && + Matcher::vector_element_basic_type(n) == T_SHORT); + + format %{ "VZERO $dst, $zero \t// replicate8S" %} + size(6); + ins_encode %{ + __ z_vzero($dst$$VectorRegister); + %} + ins_pipe(pipe_class_dummy); +%} + // Exploit rotate_then_insert, if available. // Replicate scalar int to packed int values (8 Bytes). instruct Repl2I_reg_risbg(iRegL dst, iRegI src, flagsReg cr) %{ @@ -10586,7 +10925,44 @@ instruct Repl2I_immm1(iRegL dst, immI_minus1 src) %{ ins_pipe(pipe_class_dummy); %} -// +instruct repl4I_reg_Ex(vecX dst, iRegI src) %{ + match(Set dst (Replicate src)); + predicate(n->as_Vector()->length() == 4 && + Matcher::vector_element_basic_type(n) == T_INT); + + size(12); + ins_encode %{ + __ z_vlvgf($dst$$VectorRegister, $src$$Register, 0); + __ z_vrepf($dst$$VectorRegister, $dst$$VectorRegister, 0); + %} + ins_pipe(pipe_class_dummy); +%} + +instruct repl4I_immI0(vecX dst, immI_0 zero) %{ + match(Set dst (Replicate zero)); + predicate(n->as_Vector()->length() == 4 && + Matcher::vector_element_basic_type(n) == T_INT); + + format %{ "VZERO $dst, $zero \t// replicate4I" %} + size(6); + ins_encode %{ + __ z_vzero($dst$$VectorRegister); + %} + ins_pipe(pipe_class_dummy); +%} + +instruct repl4I_immIminus1(vecX dst, immI_minus1 src) %{ + match(Set dst (Replicate src)); + predicate(n->as_Vector()->length() == 4 && + Matcher::vector_element_basic_type(n) == T_INT); + + format %{ "VONE $dst, $dst, $dst \t// replicate4I" %} + size(6); + ins_encode %{ + __ z_vone($dst$$VectorRegister); + %} + ins_pipe(pipe_class_dummy); +%} instruct Repl2F_reg_indirect(iRegL dst, regF src, flagsReg cr) %{ match(Set dst (Replicate src)); @@ -10650,6 +11026,139 @@ instruct Repl2F_imm0(iRegL dst, immFp0 src) %{ ins_pipe(pipe_class_dummy); %} +instruct repl4F_reg_Ex(vecX dst, regF src) %{ + match(Set dst (Replicate src)); + predicate(n->as_Vector()->length() == 4 && + Matcher::vector_element_basic_type(n) == T_FLOAT); + + format %{ "VREP $dst, $src \t// replicate4F" %} + size(6); + + ins_encode %{ + __ z_vrepf($dst$$VectorRegister, $src$$FloatRegister->to_vr(), 0); + %} + ins_pipe(pipe_class_dummy); +%} + +instruct repl4F_immF0(vecX dst, immFp0 zero) %{ + match(Set dst (Replicate zero)); + predicate(n->as_Vector()->length() == 4 && + Matcher::vector_element_basic_type(n) == T_FLOAT); + + format %{ "VZERO $dst, $zero \t// replicate4F" %} + size(6); + ins_encode %{ + __ z_vzero($dst$$VectorRegister); + %} + ins_pipe(pipe_class_dummy); +%} + +instruct repl2D_reg_Ex(vecX dst, regD src) %{ + match(Set dst (Replicate src)); + predicate(n->as_Vector()->length() == 2 && + Matcher::vector_element_basic_type(n) == T_DOUBLE); + + format %{ "VREP $dst, $src \t// replicate2D" %} + size(6); + + ins_encode %{ + __ z_vrepg($dst$$VectorRegister, $src$$FloatRegister->to_vr(), 0); + %} + ins_pipe(pipe_class_dummy); +%} + +instruct repl2D_immD0(vecX dst, immDp0 zero) %{ + match(Set dst (Replicate zero)); + predicate(n->as_Vector()->length() == 2 && + Matcher::vector_element_basic_type(n) == T_DOUBLE); + + format %{ "VZERO $dst, $zero \t// replicate2D" %} + size(6); + ins_encode %{ + __ z_vzero($dst$$VectorRegister); + %} + ins_pipe(pipe_class_dummy); +%} + +instruct repl16B_reg_Ex(vecX dst, iRegI src) %{ + match(Set dst (Replicate src)); + predicate(n->as_Vector()->length() == 16 && + Matcher::vector_element_basic_type(n) == T_BYTE); + + size(12); + ins_encode %{ + __ z_vlvgb($dst$$VectorRegister, $src$$Register, 0); + __ z_vrepb($dst$$VectorRegister, $dst$$VectorRegister, 0); + %} + ins_pipe(pipe_class_dummy); +%} + +instruct repl16B_immIminus1(vecX dst, immI_minus1 src) %{ + match(Set dst (Replicate src)); + predicate(n->as_Vector()->length() == 16 && + Matcher::vector_element_basic_type(n) == T_BYTE); + + format %{ "VONE $dst, $src \t// replicate16B" %} + size(6); + ins_encode %{ + __ z_vone($dst$$VectorRegister); + %} + ins_pipe(pipe_class_dummy); +%} + +instruct repl16B_immI0(vecX dst, immI_0 zero) %{ + match(Set dst (Replicate zero)); + predicate(n->as_Vector()->length() == 16 && + Matcher::vector_element_basic_type(n) == T_BYTE); + + format %{ "VZERO $dst, $zero \t// replicate16B" %} + size(6); + ins_encode %{ + __ z_vzero($dst$$VectorRegister); + %} + ins_pipe(pipe_class_dummy); +%} + +instruct repl2L_reg_Ex(vecX dst, iRegL src) %{ + match(Set dst (Replicate src)); + predicate(n->as_Vector()->length() == 2 && + Matcher::vector_element_basic_type(n) == T_LONG); + + size(12); + ins_encode %{ + __ z_vlvgg($dst$$VectorRegister, $src$$Register, 0); + __ z_vrepg($dst$$VectorRegister, $dst$$VectorRegister, 0); + %} + ins_pipe(pipe_class_dummy); +%} + +instruct repl2L_immIminus1(vecX dst, immI_minus1 src) %{ + match(Set dst (Replicate src)); + predicate(n->as_Vector()->length() == 2 && + Matcher::vector_element_basic_type(n) == T_LONG); + + format %{ "VONE $dst, $src \t// replicate2L" %} + size(6); + ins_encode %{ + __ z_vone($dst$$VectorRegister); + %} + ins_pipe(pipe_class_dummy); +%} + +instruct repl2L_immI0(vecX dst, immI_0 zero) %{ + match(Set dst (Replicate zero)); + predicate(n->as_Vector()->length() == 2 && + Matcher::vector_element_basic_type(n) == T_LONG); + + format %{ "VZERO $dst, $zero \t// replicate16B" %} + size(6); + ins_encode %{ + __ z_vzero($dst$$VectorRegister); + %} + ins_pipe(pipe_class_dummy); +%} + + // Load/Store vector // Store Aligned Packed Byte register to memory (8 Bytes). @@ -10664,6 +11173,21 @@ instruct storeA8B(memory mem, iRegL src) %{ ins_pipe(pipe_class_dummy); %} +// Store Packed Byte long register to memory +instruct storeV16(memoryRX mem, vecX src) %{ + predicate(n->as_StoreVector()->memory_size() == 16); + match(Set mem (StoreVector mem src)); + ins_cost(MEMORY_REF_COST); + + format %{ "VST $mem, $src \t// store 16-byte Vector" %} + size(6); + ins_encode %{ + __ z_vst($src$$VectorRegister, + Address(reg_to_register_object($mem$$base), $mem$$index$$Register, $mem$$disp)); + %} + ins_pipe(pipe_class_dummy); +%} + instruct loadV8(iRegL dst, memory mem) %{ match(Set dst (LoadVector mem)); predicate(n->as_LoadVector()->memory_size() == 8); @@ -10675,6 +11199,21 @@ instruct loadV8(iRegL dst, memory mem) %{ ins_pipe(pipe_class_dummy); %} +// Load Aligned Packed Byte +instruct loadV16(vecX dst, memoryRX mem) %{ + predicate(n->as_LoadVector()->memory_size() == 16); + match(Set dst (LoadVector mem)); + ins_cost(MEMORY_REF_COST); + + format %{ "VL $dst, $mem \t// load 16-byte Vector" %} + size(6); + ins_encode %{ + __ z_vl($dst$$VectorRegister, + Address(reg_to_register_object($mem$$base), $mem$$index$$Register, $mem$$disp)); + %} + ins_pipe(pipe_class_dummy); +%} + // Reinterpret: only one vector size used instruct reinterpret(iRegL dst) %{ match(Set dst (VectorReinterpret dst)); @@ -10684,6 +11223,303 @@ instruct reinterpret(iRegL dst) %{ ins_pipe(pipe_class_dummy); %} +instruct reinterpretX(vecX dst) %{ + match(Set dst (VectorReinterpret dst)); + ins_cost(0); + format %{ "reinterpret $dst" %} + ins_encode( /*empty*/ ); + ins_pipe(pipe_class_dummy); +%} + +//----------Vector Arithmetic Instructions-------------------------------------- + +// Vector Addition Instructions + +instruct vadd16B_reg(vecX dst, vecX src1, vecX src2) %{ + match(Set dst (AddVB src1 src2)); + predicate(n->as_Vector()->length() == 16); + format %{ "VAB $dst,$src1,$src2\t// add packed16B" %} + size(6); + ins_encode %{ + __ z_vab($dst$$VectorRegister, $src1$$VectorRegister, $src2$$VectorRegister); + %} + ins_pipe(pipe_class_dummy); +%} + +instruct vadd8S_reg(vecX dst, vecX src1, vecX src2) %{ + match(Set dst (AddVS src1 src2)); + predicate(n->as_Vector()->length() == 8); + format %{ "VAH $dst,$src1,$src2\t// add packed8S" %} + size(6); + ins_encode %{ + __ z_vah($dst$$VectorRegister, $src1$$VectorRegister, $src2$$VectorRegister); + %} + ins_pipe(pipe_class_dummy); +%} + +instruct vadd4I_reg(vecX dst, vecX src1, vecX src2) %{ + match(Set dst (AddVI src1 src2)); + predicate(n->as_Vector()->length() == 4); + format %{ "VAF $dst,$src1,$src2\t// add packed4I" %} + size(6); + ins_encode %{ + __ z_vaf($dst$$VectorRegister, $src1$$VectorRegister, $src2$$VectorRegister); + %} + ins_pipe(pipe_class_dummy); +%} + +instruct vadd2L_reg(vecX dst, vecX src1, vecX src2) %{ + match(Set dst (AddVL src1 src2)); + predicate(n->as_Vector()->length() == 2); + format %{ "VAG $dst,$src1,$src2\t// add packed2L" %} + size(6); + ins_encode %{ + __ z_vag($dst$$VectorRegister, $src1$$VectorRegister, $src2$$VectorRegister); + %} + ins_pipe(pipe_class_dummy); +%} + +instruct vmul16B_reg(vecX dst, vecX src1, vecX src2) %{ + match(Set dst (MulVB src1 src2)); + predicate(n->as_Vector()->length() == 16); + format %{ "VMLB $dst,$src1,$src2\t// mul packed16B" %} + size(6); + ins_encode %{ + __ z_vmlb($dst$$VectorRegister, $src1$$VectorRegister, $src2$$VectorRegister); + %} + ins_pipe(pipe_class_dummy); +%} + +instruct vmul8S_reg(vecX dst, vecX src1, vecX src2) %{ + match(Set dst (MulVS src1 src2)); + predicate(n->as_Vector()->length() == 8); + format %{ "VMLHW $dst,$src1,$src2\t// mul packed8S" %} + size(6); + ins_encode %{ + __ z_vmlhw($dst$$VectorRegister, $src1$$VectorRegister, $src2$$VectorRegister); + %} + ins_pipe(pipe_class_dummy); +%} + +instruct vmul4I_reg(vecX dst, vecX src1, vecX src2) %{ + match(Set dst (MulVI src1 src2)); + predicate(n->as_Vector()->length() == 4); + format %{ "VMLF $dst,$src1,$src2\t// mul packed4I" %} + size(6); + ins_encode %{ + __ z_vmlf($dst$$VectorRegister, $src1$$VectorRegister, $src2$$VectorRegister); + %} + ins_pipe(pipe_class_dummy); +%} + +instruct vsub16B_reg(vecX dst, vecX src1, vecX src2) %{ + match(Set dst (SubVB src1 src2)); + predicate(n->as_Vector()->length() == 16); + format %{ "VSB $dst,$src1,$src2\t// sub packed16B" %} + size(6); + ins_encode %{ + __ z_vsb($dst$$VectorRegister, $src1$$VectorRegister, $src2$$VectorRegister); + %} + ins_pipe(pipe_class_dummy); +%} + +instruct vsub8S_reg(vecX dst, vecX src1, vecX src2) %{ + match(Set dst (SubVS src1 src2)); + predicate(n->as_Vector()->length() == 8); + format %{ "VSH $dst,$src1,$src2\t// sub packed8S" %} + size(6); + ins_encode %{ + __ z_vsh($dst$$VectorRegister, $src1$$VectorRegister, $src2$$VectorRegister); + %} + ins_pipe(pipe_class_dummy); +%} + +instruct vsub4I_reg(vecX dst, vecX src1, vecX src2) %{ + match(Set dst (SubVI src1 src2)); + predicate(n->as_Vector()->length() == 4); + format %{ "VSF $dst,$src1,$src2\t// sub packed4I" %} + size(6); + ins_encode %{ + __ z_vsf($dst$$VectorRegister, $src1$$VectorRegister, $src2$$VectorRegister); + %} + ins_pipe(pipe_class_dummy); +%} + +instruct vsub2L_reg(vecX dst, vecX src1, vecX src2) %{ + match(Set dst (SubVL src1 src2)); + predicate(n->as_Vector()->length() == 2); + format %{ "VSG $dst,$src1,$src2\t// sub packed2L" %} + size(6); + ins_encode %{ + __ z_vsg($dst$$VectorRegister, $src1$$VectorRegister, $src2$$VectorRegister); + %} + ins_pipe(pipe_class_dummy); +%} + +instruct vadd4F_reg(vecX dst, vecX src1, vecX src2) %{ + match(Set dst (AddVF src1 src2)); + predicate(n->as_Vector()->length() == 4); + format %{ "VFASB $dst,$src1,$src2\t// add packed4F" %} + size(6); + ins_encode %{ + __ z_vfasb($dst$$VectorRegister, $src1$$VectorRegister, $src2$$VectorRegister); + %} + ins_pipe(pipe_class_dummy); +%} + +instruct vadd2D_reg(vecX dst, vecX src1, vecX src2) %{ + match(Set dst (AddVD src1 src2)); + predicate(n->as_Vector()->length() == 2); + format %{ "VFADB $dst,$src1,$src2\t// add packed2D" %} + size(6); + ins_encode %{ + __ z_vfadb($dst$$VectorRegister, $src1$$VectorRegister, $src2$$VectorRegister); + %} + ins_pipe(pipe_class_dummy); +%} + +instruct vsub4F_reg(vecX dst, vecX src1, vecX src2) %{ + match(Set dst (SubVF src1 src2)); + predicate(n->as_Vector()->length() == 4); + format %{ "VFSSB $dst,$src1,$src2\t// sub packed4F" %} + size(6); + ins_encode %{ + __ z_vfssb($dst$$VectorRegister, $src1$$VectorRegister, $src2$$VectorRegister); + %} + ins_pipe(pipe_class_dummy); +%} + +instruct vsub2D_reg(vecX dst, vecX src1, vecX src2) %{ + match(Set dst (SubVD src1 src2)); + predicate(n->as_Vector()->length() == 2); + format %{ "VFSDB $dst,$src1,$src2\t// sub packed2D" %} + size(6); + ins_encode %{ + __ z_vfsdb($dst$$VectorRegister, $src1$$VectorRegister, $src2$$VectorRegister); + %} + ins_pipe(pipe_class_dummy); +%} + +instruct vmul4F_reg(vecX dst, vecX src1, vecX src2) %{ + match(Set dst (MulVF src1 src2)); + predicate(n->as_Vector()->length() == 4); + format %{ "VFMSB $dst,$src1,$src2\t// mul packed4F" %} + size(6); + ins_encode %{ + __ z_vfmsb($dst$$VectorRegister, $src1$$VectorRegister, $src2$$VectorRegister); + %} + ins_pipe(pipe_class_dummy); +%} + +instruct vmul2D_reg(vecX dst, vecX src1, vecX src2) %{ + match(Set dst (MulVD src1 src2)); + predicate(n->as_Vector()->length() == 2); + format %{ "VFMDB $dst,$src1,$src2\t// mul packed2D" %} + size(6); + ins_encode %{ + __ z_vfmdb($dst$$VectorRegister, $src1$$VectorRegister, $src2$$VectorRegister); + %} + ins_pipe(pipe_class_dummy); +%} + +instruct vdiv4F_reg(vecX dst, vecX src1, vecX src2) %{ + match(Set dst (DivVF src1 src2)); + predicate(n->as_Vector()->length() == 4); + format %{ "VFDSB $dst,$src1,$src2\t// div packed4F" %} + size(6); + ins_encode %{ + __ z_vfdsb($dst$$VectorRegister, $src1$$VectorRegister, $src2$$VectorRegister); + %} + ins_pipe(pipe_class_dummy); +%} + +instruct vdiv2D_reg(vecX dst, vecX src1, vecX src2) %{ + match(Set dst (DivVD src1 src2)); + predicate(n->as_Vector()->length() == 2); + format %{ "VFDDB $dst,$src1,$src2\t// div packed2D" %} + size(6); + ins_encode %{ + __ z_vfddb($dst$$VectorRegister, $src1$$VectorRegister, $src2$$VectorRegister); + %} + ins_pipe(pipe_class_dummy); +%} + +// Vector Square Root Instructions + +instruct vsqrt4F_reg(vecX dst, vecX src) %{ + match(Set dst (SqrtVF src)); + predicate(n->as_Vector()->length() == 4); + format %{ "VFSQSB $dst,$src\t// sqrt packed4F" %} + size(6); + ins_encode %{ + __ z_vfsqsb($dst$$VectorRegister, $src$$VectorRegister); + %} + ins_pipe(pipe_class_dummy); +%} + +instruct vsqrt2D_reg(vecX dst, vecX src) %{ + match(Set dst (SqrtVD src)); + predicate(n->as_Vector()->length() == 2); + format %{ "VFSQDB $dst,$src\t// sqrt packed2D" %} + size(6); + ins_encode %{ + __ z_vfsqdb($dst$$VectorRegister, $src$$VectorRegister); + %} + ins_pipe(pipe_class_dummy); +%} + +// Vector Population Count Instructions + +instruct vpopcnt_reg(vecX dst, vecX src) %{ + match(Set dst (PopCountVI src)); + format %{ "VPOPCT $dst,$src\t// pop count packed" %} + size(6); + ins_encode %{ + BasicType bt = Matcher::vector_element_basic_type(this); + switch (bt) { + case T_BYTE: + __ z_vpopctb($dst$$VectorRegister, $src$$VectorRegister); + break; + case T_SHORT: + __ z_vpopcth($dst$$VectorRegister, $src$$VectorRegister); + break; + case T_INT: + __ z_vpopctf($dst$$VectorRegister, $src$$VectorRegister); + break; + case T_LONG: + __ z_vpopctg($dst$$VectorRegister, $src$$VectorRegister); + break; + default: + ShouldNotReachHere(); + } + %} + ins_pipe(pipe_class_dummy); +%} + +// Vector Round Instructions +instruct vround2D_reg(vecX dst, vecX src, immI8 rmode) %{ + match(Set dst (RoundDoubleModeV src rmode)); + predicate(n->as_Vector()->length() == 2); + format %{ "RoundDoubleModeV $src,$rmode" %} + size(6); + ins_encode %{ + switch ($rmode$$constant) { + case RoundDoubleModeNode::rmode_rint: + __ z_vflrd($dst$$VectorRegister, $src$$VectorRegister, 0); + break; + case RoundDoubleModeNode::rmode_floor: + __ z_vflrd($dst$$VectorRegister, $src$$VectorRegister, 7); + break; + case RoundDoubleModeNode::rmode_ceil: + __ z_vflrd($dst$$VectorRegister, $src$$VectorRegister, 6); + break; + default: + ShouldNotReachHere(); + } + %} + ins_pipe(pipe_class_dummy); +%} + //----------POPULATION COUNT RULES-------------------------------------------- // Byte reverse diff --git a/src/hotspot/cpu/s390/sharedRuntime_s390.cpp b/src/hotspot/cpu/s390/sharedRuntime_s390.cpp index c60f6ef3295..1238f887b87 100644 --- a/src/hotspot/cpu/s390/sharedRuntime_s390.cpp +++ b/src/hotspot/cpu/s390/sharedRuntime_s390.cpp @@ -81,6 +81,9 @@ #define RegisterSaver_ExcludedFloatReg(regname) \ { RegisterSaver::excluded_reg, regname->encoding(), regname->as_VMReg() } +#define RegisterSaver_LiveVReg(regname) \ + { RegisterSaver::v_reg, regname->encoding(), regname->as_VMReg() } + static const RegisterSaver::LiveRegType RegisterSaver_LiveRegs[] = { // Live registers which get spilled to the stack. Register positions // in this array correspond directly to the stack layout. @@ -258,6 +261,26 @@ static const RegisterSaver::LiveRegType RegisterSaver_LiveVolatileRegs[] = { // RegisterSaver_ExcludedIntReg(Z_R15) // stack pointer }; +static const RegisterSaver::LiveRegType RegisterSaver_LiveVRegs[] = { + // live vector registers (optional, only these are used by C2): + RegisterSaver_LiveVReg( Z_V16 ), + RegisterSaver_LiveVReg( Z_V17 ), + RegisterSaver_LiveVReg( Z_V18 ), + RegisterSaver_LiveVReg( Z_V19 ), + RegisterSaver_LiveVReg( Z_V20 ), + RegisterSaver_LiveVReg( Z_V21 ), + RegisterSaver_LiveVReg( Z_V22 ), + RegisterSaver_LiveVReg( Z_V23 ), + RegisterSaver_LiveVReg( Z_V24 ), + RegisterSaver_LiveVReg( Z_V25 ), + RegisterSaver_LiveVReg( Z_V26 ), + RegisterSaver_LiveVReg( Z_V27 ), + RegisterSaver_LiveVReg( Z_V28 ), + RegisterSaver_LiveVReg( Z_V29 ), + RegisterSaver_LiveVReg( Z_V30 ), + RegisterSaver_LiveVReg( Z_V31 ) +}; + int RegisterSaver::live_reg_save_size(RegisterSet reg_set) { int reg_space = -1; switch (reg_set) { @@ -271,23 +294,28 @@ int RegisterSaver::live_reg_save_size(RegisterSet reg_set) { return (reg_space / sizeof(RegisterSaver::LiveRegType)) * reg_size; } +int RegisterSaver::calculate_vregstosave_num() { + return (sizeof(RegisterSaver_LiveVRegs) / sizeof(RegisterSaver::LiveRegType)); +} -int RegisterSaver::live_reg_frame_size(RegisterSet reg_set) { - return live_reg_save_size(reg_set) + frame::z_abi_160_size; +int RegisterSaver::live_reg_frame_size(RegisterSet reg_set, bool save_vectors) { + const int vregstosave_num = save_vectors ? calculate_vregstosave_num() : 0; + return live_reg_save_size(reg_set) + vregstosave_num * v_reg_size + frame::z_abi_160_size; } // return_pc: Specify the register that should be stored as the return pc in the current frame. -OopMap* RegisterSaver::save_live_registers(MacroAssembler* masm, RegisterSet reg_set, Register return_pc) { +OopMap* RegisterSaver::save_live_registers(MacroAssembler* masm, RegisterSet reg_set, Register return_pc, bool save_vectors) { // Record volatile registers as callee-save values in an OopMap so // their save locations will be propagated to the caller frame's // RegisterMap during StackFrameStream construction (needed for // deoptimization; see compiledVFrame::create_stack_value). // Calculate frame size. - const int frame_size_in_bytes = live_reg_frame_size(reg_set); + const int frame_size_in_bytes = live_reg_frame_size(reg_set, save_vectors); const int frame_size_in_slots = frame_size_in_bytes / sizeof(jint); - const int register_save_offset = frame_size_in_bytes - live_reg_save_size(reg_set); + const int vregstosave_num = save_vectors ? calculate_vregstosave_num() : 0; + const int register_save_offset = frame_size_in_bytes - (live_reg_save_size(reg_set) + vregstosave_num * v_reg_size); // OopMap frame size is in c2 stack slots (sizeof(jint)) not bytes or words. OopMap* map = new OopMap(frame_size_in_slots, 0); @@ -382,6 +410,23 @@ OopMap* RegisterSaver::save_live_registers(MacroAssembler* masm, RegisterSet reg assert(first != noreg, "Should spill at least one int reg."); __ z_stmg(first, last, first_offset, Z_SP); + for (int i = 0; i < vregstosave_num; i++, offset += v_reg_size) { + int reg_num = RegisterSaver_LiveVRegs[i].reg_num; + + __ z_vst(as_VectorRegister(reg_num), Address(Z_SP, offset)); + + map->set_callee_saved(VMRegImpl::stack2reg(offset>>2), + RegisterSaver_LiveVRegs[i].vmreg); + map->set_callee_saved(VMRegImpl::stack2reg((offset + half_reg_size ) >> 2), + RegisterSaver_LiveVRegs[i].vmreg->next()); + map->set_callee_saved(VMRegImpl::stack2reg((offset + (half_reg_size * 2)) >> 2), + RegisterSaver_LiveVRegs[i].vmreg->next(2)); + map->set_callee_saved(VMRegImpl::stack2reg((offset + (half_reg_size * 3)) >> 2), + RegisterSaver_LiveVRegs[i].vmreg->next(3)); + } + + assert(offset == frame_size_in_bytes, "consistency check"); + // And we're done. return map; } @@ -433,14 +478,18 @@ OopMap* RegisterSaver::generate_oop_map(MacroAssembler* masm, RegisterSet reg_se } offset += reg_size; } +#ifdef ASSERT + assert(offset == frame_size_in_bytes, "consistency check"); +#endif return map; } // Pop the current frame and restore all the registers that we saved. -void RegisterSaver::restore_live_registers(MacroAssembler* masm, RegisterSet reg_set) { +void RegisterSaver::restore_live_registers(MacroAssembler* masm, RegisterSet reg_set, bool save_vectors) { int offset; - const int register_save_offset = live_reg_frame_size(reg_set) - live_reg_save_size(reg_set); + const int vregstosave_num = save_vectors ? calculate_vregstosave_num() : 0; + const int register_save_offset = live_reg_frame_size(reg_set, save_vectors) - (live_reg_save_size(reg_set) + vregstosave_num * v_reg_size); Register first = noreg; Register last = noreg; @@ -517,6 +566,12 @@ void RegisterSaver::restore_live_registers(MacroAssembler* masm, RegisterSet reg assert(first != noreg, "Should spill at least one int reg."); __ z_lmg(first, last, first_offset, Z_SP); + for (int i = 0; i < vregstosave_num; i++, offset += v_reg_size) { + int reg_num = RegisterSaver_LiveVRegs[i].reg_num; + + __ z_vl(as_VectorRegister(reg_num), Address(Z_SP, offset)); + } + // Pop the frame. __ pop_frame(); @@ -527,14 +582,12 @@ void RegisterSaver::restore_live_registers(MacroAssembler* masm, RegisterSet reg // Pop the current frame and restore the registers that might be holding a result. void RegisterSaver::restore_result_registers(MacroAssembler* masm) { - int i; - int offset; const int regstosave_num = sizeof(RegisterSaver_LiveRegs) / sizeof(RegisterSaver::LiveRegType); const int register_save_offset = live_reg_frame_size(all_registers) - live_reg_save_size(all_registers); // Restore all result registers (ints and floats). - offset = register_save_offset; + int offset = register_save_offset; for (int i = 0; i < regstosave_num; i++, offset += reg_size) { int reg_num = RegisterSaver_LiveRegs[i].reg_num; int reg_type = RegisterSaver_LiveRegs[i].reg_type; @@ -557,6 +610,7 @@ void RegisterSaver::restore_result_registers(MacroAssembler* masm) { ShouldNotReachHere(); } } + assert(offset == live_reg_frame_size(all_registers), "consistency check"); } // --------------------------------------------------------------------------- @@ -980,8 +1034,8 @@ static void gen_special_dispatch(MacroAssembler *masm, // Is the size of a vector size (in bytes) bigger than a size saved by default? // 8 bytes registers are saved by default on z/Architecture. bool SharedRuntime::is_wide_vector(int size) { - // Note, MaxVectorSize == 8 on this platform. - assert(size <= 8, "%d bytes vectors are not supported", size); + // Note, MaxVectorSize == 8/16 on this platform. + assert(size <= (SuperwordUseVX ? 16 : 8), "%d bytes vectors are not supported", size); return size > 8; } @@ -2865,8 +2919,9 @@ SafepointBlob* SharedRuntime::generate_handler_blob(SharedStubId id, address cal __ z_lg(Z_R14, Address(Z_thread, JavaThread::saved_exception_pc_offset())); } + bool save_vectors = (poll_type == POLL_AT_VECTOR_LOOP); // Save registers, fpu state, and flags - map = RegisterSaver::save_live_registers(masm, RegisterSaver::all_registers); + map = RegisterSaver::save_live_registers(masm, RegisterSaver::all_registers, Z_R14, save_vectors); if (!cause_return) { // Keep a copy of the return pc to detect if it gets modified. @@ -2898,7 +2953,7 @@ SafepointBlob* SharedRuntime::generate_handler_blob(SharedStubId id, address cal // Pending exception case, used (sporadically) by // api/java_lang/Thread.State/index#ThreadState et al. - RegisterSaver::restore_live_registers(masm, RegisterSaver::all_registers); + RegisterSaver::restore_live_registers(masm, RegisterSaver::all_registers, save_vectors); // Jump to forward_exception_entry, with the issuing PC in Z_R14 // so it looks like the original nmethod called forward_exception_entry. @@ -2911,7 +2966,7 @@ SafepointBlob* SharedRuntime::generate_handler_blob(SharedStubId id, address cal if (!cause_return) { Label no_adjust; // If our stashed return pc was modified by the runtime we avoid touching it - const int offset_of_return_pc = _z_common_abi(return_pc) + RegisterSaver::live_reg_frame_size(RegisterSaver::all_registers); + const int offset_of_return_pc = _z_common_abi(return_pc) + RegisterSaver::live_reg_frame_size(RegisterSaver::all_registers, save_vectors); __ z_cg(Z_R6, offset_of_return_pc, Z_SP); __ z_brne(no_adjust); @@ -2924,7 +2979,7 @@ SafepointBlob* SharedRuntime::generate_handler_blob(SharedStubId id, address cal } // Normal exit, restore registers and exit. - RegisterSaver::restore_live_registers(masm, RegisterSaver::all_registers); + RegisterSaver::restore_live_registers(masm, RegisterSaver::all_registers, save_vectors); __ z_br(Z_R14); @@ -2932,7 +2987,7 @@ SafepointBlob* SharedRuntime::generate_handler_blob(SharedStubId id, address cal masm->flush(); // Fill-out other meta info - return SafepointBlob::create(&buffer, oop_maps, RegisterSaver::live_reg_frame_size(RegisterSaver::all_registers)/wordSize); + return SafepointBlob::create(&buffer, oop_maps, RegisterSaver::live_reg_frame_size(RegisterSaver::all_registers, save_vectors)/wordSize); } diff --git a/src/hotspot/cpu/s390/vm_version_s390.cpp b/src/hotspot/cpu/s390/vm_version_s390.cpp index 4b17ff4594c..8ab5affd309 100644 --- a/src/hotspot/cpu/s390/vm_version_s390.cpp +++ b/src/hotspot/cpu/s390/vm_version_s390.cpp @@ -97,7 +97,23 @@ void VM_Version::initialize() { intx cache_line_size = Dcache_lineSize(0); #ifdef COMPILER2 - MaxVectorSize = 8; + int model_ix = get_model_index(); + + if ( model_ix >= 7 ) { + if (FLAG_IS_DEFAULT(SuperwordUseVX)) { + FLAG_SET_ERGO(SuperwordUseVX, true); + } + if (model_ix > 7 && FLAG_IS_DEFAULT(UseSFPV) && SuperwordUseVX) { + FLAG_SET_ERGO(UseSFPV, true); + } else if (model_ix == 7 && UseSFPV) { + warning("UseSFPV specified, but needs at least Z14."); + FLAG_SET_DEFAULT(UseSFPV, false); + } + } else if (SuperwordUseVX) { + warning("SuperwordUseVX specified, but needs at least Z13."); + FLAG_SET_DEFAULT(SuperwordUseVX, false); + } + MaxVectorSize = SuperwordUseVX ? 16 : 8; #endif if (has_PrefetchRaw()) { diff --git a/src/hotspot/cpu/s390/vmreg_s390.cpp b/src/hotspot/cpu/s390/vmreg_s390.cpp index 239b68513b9..5bec8313a48 100644 --- a/src/hotspot/cpu/s390/vmreg_s390.cpp +++ b/src/hotspot/cpu/s390/vmreg_s390.cpp @@ -43,6 +43,16 @@ void VMRegImpl::set_regName() { regName[i++] = freg->name(); freg = freg->successor(); } + + VectorRegister vreg = ::as_VectorRegister(0); + for (; i < ConcreteRegisterImpl::max_vr;) { + regName[i++] = vreg->name(); + regName[i++] = vreg->name(); + regName[i++] = vreg->name(); + regName[i++] = vreg->name(); + vreg = vreg->successor(); + } + for (; i < ConcreteRegisterImpl::number_of_registers; i ++) { regName[i] = "NON-GPR-XMM"; } diff --git a/src/hotspot/cpu/s390/vmreg_s390.hpp b/src/hotspot/cpu/s390/vmreg_s390.hpp index 3dd1bd9a16c..eb601f693ab 100644 --- a/src/hotspot/cpu/s390/vmreg_s390.hpp +++ b/src/hotspot/cpu/s390/vmreg_s390.hpp @@ -35,14 +35,26 @@ inline bool is_FloatRegister() { value() < ConcreteRegisterImpl::max_fpr; } +inline bool is_VectorRegister() { + return value() >= ConcreteRegisterImpl::max_fpr && + value() < ConcreteRegisterImpl::max_vr; +} + inline Register as_Register() { assert(is_Register() && is_even(value()), "even-aligned GPR name"); - return ::as_Register(value() >> 1); + return ::as_Register(value() / Register::max_slots_per_register); } inline FloatRegister as_FloatRegister() { assert(is_FloatRegister() && is_even(value()), "must be"); - return ::as_FloatRegister((value() - ConcreteRegisterImpl::max_gpr) >> 1); + return ::as_FloatRegister((value() - ConcreteRegisterImpl::max_gpr) / + FloatRegister::max_slots_per_register); +} + +inline VectorRegister as_VectorRegister() { + assert(is_VectorRegister(), "must be"); + return ::as_VectorRegister((value() - ConcreteRegisterImpl::max_fpr) / + VectorRegister::max_slots_per_register); } inline bool is_concrete() { diff --git a/src/hotspot/cpu/s390/vmreg_s390.inline.hpp b/src/hotspot/cpu/s390/vmreg_s390.inline.hpp index 593a0d48045..b03a66b3086 100644 --- a/src/hotspot/cpu/s390/vmreg_s390.inline.hpp +++ b/src/hotspot/cpu/s390/vmreg_s390.inline.hpp @@ -27,15 +27,21 @@ #define CPU_S390_VMREG_S390_INLINE_HPP inline VMReg Register::as_VMReg() const { - return VMRegImpl::as_VMReg(encoding() << 1); + return VMRegImpl::as_VMReg(encoding() * Register::max_slots_per_register); } inline VMReg FloatRegister::as_VMReg() const { - return VMRegImpl::as_VMReg((encoding() << 1) + ConcreteRegisterImpl::max_gpr); + return VMRegImpl::as_VMReg((encoding() * FloatRegister::max_slots_per_register) + + ConcreteRegisterImpl::max_gpr); +} + +inline VMReg VectorRegister::as_VMReg() const { + return VMRegImpl::as_VMReg((encoding() * VectorRegister::max_slots_per_register) + + ConcreteRegisterImpl::max_fpr); } inline VMReg ConditionRegister::as_VMReg() const { - return VMRegImpl::as_VMReg((encoding() << 1) + ConcreteRegisterImpl::max_fpr); + return VMRegImpl::as_VMReg(encoding() + ConcreteRegisterImpl::max_vr); } #endif // CPU_S390_VMREG_S390_INLINE_HPP diff --git a/src/hotspot/share/adlc/output_c.cpp b/src/hotspot/share/adlc/output_c.cpp index 804e8f1a4e6..cc6ed278b49 100644 --- a/src/hotspot/share/adlc/output_c.cpp +++ b/src/hotspot/share/adlc/output_c.cpp @@ -2358,6 +2358,9 @@ class DefineEmitState { if (strcmp(rep_var,"$VectorRegister") == 0) return "as_VectorRegister"; if (strcmp(rep_var,"$VectorSRegister") == 0) return "as_VectorSRegister"; #endif +#if defined(S390) + if (strcmp(rep_var,"$VectorRegister") == 0) return "as_VectorRegister"; +#endif #if defined(AARCH64) if (strcmp(rep_var,"$PRegister") == 0) return "as_PRegister"; #endif diff --git a/src/hotspot/share/opto/machnode.hpp b/src/hotspot/share/opto/machnode.hpp index 6fcbabdab90..4ac91175f78 100644 --- a/src/hotspot/share/opto/machnode.hpp +++ b/src/hotspot/share/opto/machnode.hpp @@ -134,6 +134,14 @@ class MachOper : public ResourceObj { return ::as_VectorSRegister(reg(ra_, node, idx)); } #endif +#if defined(S390) + VectorRegister as_VectorRegister(PhaseRegAlloc *ra_, const Node *node) const { + return ::as_VectorRegister(reg(ra_, node)); + } + VectorRegister as_VectorRegister(PhaseRegAlloc *ra_, const Node *node, int idx) const { + return ::as_VectorRegister(reg(ra_, node, idx)); + } +#endif #if defined(AARCH64) PRegister as_PRegister(PhaseRegAlloc* ra_, const Node* node) const { return ::as_PRegister(reg(ra_, node)); diff --git a/src/hotspot/share/opto/type.cpp b/src/hotspot/share/opto/type.cpp index 70cd46c900d..407a4a20a9b 100644 --- a/src/hotspot/share/opto/type.cpp +++ b/src/hotspot/share/opto/type.cpp @@ -77,7 +77,7 @@ const Type::TypeInfo Type::_type_info[Type::lastype] = { { Bad, T_ILLEGAL, "vectora:", false, Op_VecA, relocInfo::none }, // VectorA. { Bad, T_ILLEGAL, "vectors:", false, 0, relocInfo::none }, // VectorS { Bad, T_ILLEGAL, "vectord:", false, Op_RegL, relocInfo::none }, // VectorD - { Bad, T_ILLEGAL, "vectorx:", false, 0, relocInfo::none }, // VectorX + { Bad, T_ILLEGAL, "vectorx:", false, Op_VecX, relocInfo::none }, // VectorX { Bad, T_ILLEGAL, "vectory:", false, 0, relocInfo::none }, // VectorY { Bad, T_ILLEGAL, "vectorz:", false, 0, relocInfo::none }, // VectorZ #else // all other From 543e355bd92d74bcb5a408ccefd8e2e0d9a0552f Mon Sep 17 00:00:00 2001 From: Matthias Baesken Date: Mon, 18 Nov 2024 07:42:58 +0000 Subject: [PATCH 045/311] 8344298: Test tools/sincechecker/modules/jdk.hotspot.agent/JdkHotspotAgentCheckSince.java fails on platforms without sa Reviewed-by: lucy --- .../modules/jdk.hotspot.agent/JdkHotspotAgentCheckSince.java | 1 + 1 file changed, 1 insertion(+) diff --git a/test/jdk/tools/sincechecker/modules/jdk.hotspot.agent/JdkHotspotAgentCheckSince.java b/test/jdk/tools/sincechecker/modules/jdk.hotspot.agent/JdkHotspotAgentCheckSince.java index 5f8b8162cd9..974550cc7b7 100644 --- a/test/jdk/tools/sincechecker/modules/jdk.hotspot.agent/JdkHotspotAgentCheckSince.java +++ b/test/jdk/tools/sincechecker/modules/jdk.hotspot.agent/JdkHotspotAgentCheckSince.java @@ -25,6 +25,7 @@ * @test * @bug 8343781 * @summary Test for `@since` in jdk.hotspot.agent module + * @requires vm.hasSA * @library /test/lib /test/jdk/tools/sincechecker * @run main SinceChecker jdk.hotspot.agent */ From b6c2122efb1c3a36d5fe7a425038333a87951cfc Mon Sep 17 00:00:00 2001 From: Prasanta Sadhukhan Date: Mon, 18 Nov 2024 08:11:52 +0000 Subject: [PATCH 046/311] 8316151: [macos14] ActionListenerCalledTwiceTest.java fails on macOS 14 Reviewed-by: tr --- test/jdk/ProblemList.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/test/jdk/ProblemList.txt b/test/jdk/ProblemList.txt index a87ab372da2..702a426df0a 100644 --- a/test/jdk/ProblemList.txt +++ b/test/jdk/ProblemList.txt @@ -707,7 +707,6 @@ javax/swing/JComboBox/TestComboBoxComponentRendering.java 8309734 linux-all # This test fails on macOS 14 javax/swing/plaf/synth/7158712/bug7158712.java 8324782 macosx-all -javax/swing/JMenuItem/ActionListenerCalledTwice/ActionListenerCalledTwiceTest.java 8316151 macosx-all ############################################################################ From 4a7ce1d7c1bd4b751063b98cf8bedcd27055760b Mon Sep 17 00:00:00 2001 From: Richard Reingruber Date: Mon, 18 Nov 2024 08:18:15 +0000 Subject: [PATCH 047/311] 8344205: [PPC]: failing assertion: sharedRuntime_ppc.cpp:1652: cookie not found Reviewed-by: mdoerr --- src/hotspot/cpu/ppc/sharedRuntime_ppc.cpp | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/hotspot/cpu/ppc/sharedRuntime_ppc.cpp b/src/hotspot/cpu/ppc/sharedRuntime_ppc.cpp index 84102ef41e8..aedded83623 100644 --- a/src/hotspot/cpu/ppc/sharedRuntime_ppc.cpp +++ b/src/hotspot/cpu/ppc/sharedRuntime_ppc.cpp @@ -1602,7 +1602,6 @@ static void fill_continuation_entry(MacroAssembler* masm, Register reg_cont_obj, #ifdef ASSERT __ load_const_optimized(tmp2, ContinuationEntry::cookie_value()); __ stw(tmp2, in_bytes(ContinuationEntry::cookie_offset()), R1_SP); - __ std(tmp2, _abi0(cr), R1_SP); #endif //ASSERT __ li(zero, 0); @@ -1646,10 +1645,6 @@ static void continuation_enter_cleanup(MacroAssembler* masm) { __ ld_ptr(tmp1, JavaThread::cont_entry_offset(), R16_thread); __ cmpd(CCR0, R1_SP, tmp1); __ asm_assert_eq(FILE_AND_LINE ": incorrect R1_SP"); - __ load_const_optimized(tmp1, ContinuationEntry::cookie_value()); - __ ld(tmp2, _abi0(cr), R1_SP); - __ cmpd(CCR0, tmp1, tmp2); - __ asm_assert_eq(FILE_AND_LINE ": cookie not found"); #endif __ ld_ptr(tmp1, ContinuationEntry::parent_cont_fastpath_offset(), R1_SP); From 6c2ae44c052bdabbfc2fd15e133b30849580b4a6 Mon Sep 17 00:00:00 2001 From: Tobias Holenstein Date: Mon, 18 Nov 2024 08:35:12 +0000 Subject: [PATCH 048/311] 8344204: IGV: Button to enable/disable cutting of long edges Reviewed-by: rcastanedalo, chagedorn --- .../HierarchicalCFGLayoutManager.java | 6 ++ .../HierarchicalClusterLayoutManager.java | 6 ++ .../HierarchicalLayoutManager.java | 5 +- .../HierarchicalStableLayoutManager.java | 28 ++++- .../LinearLayoutManager.java | 3 + .../sun/hotspot/igv/layout/LayoutManager.java | 2 + .../sun/hotspot/igv/view/DiagramScene.java | 15 ++- .../hotspot/igv/view/DiagramViewModel.java | 56 ++++------ .../hotspot/igv/view/EditorTopComponent.java | 7 +- .../igv/view/actions/CutEdgesAction.java | 97 ++++++++++++++++++ .../view/actions/HideDuplicatesAction.java | 57 ---------- .../com/sun/hotspot/igv/view/images/cut.png | Bin 0 -> 2330 bytes .../igv/view/images/hideDuplicates.png | Bin 618 -> 0 bytes 13 files changed, 176 insertions(+), 106 deletions(-) create mode 100644 src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/actions/CutEdgesAction.java delete mode 100644 src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/actions/HideDuplicatesAction.java create mode 100644 src/utils/IdealGraphVisualizer/View/src/main/resources/com/sun/hotspot/igv/view/images/cut.png delete mode 100644 src/utils/IdealGraphVisualizer/View/src/main/resources/com/sun/hotspot/igv/view/images/hideDuplicates.png diff --git a/src/utils/IdealGraphVisualizer/HierarchicalLayout/src/main/java/com/sun/hotspot/igv/hierarchicallayout/HierarchicalCFGLayoutManager.java b/src/utils/IdealGraphVisualizer/HierarchicalLayout/src/main/java/com/sun/hotspot/igv/hierarchicallayout/HierarchicalCFGLayoutManager.java index c712c2f935e..3d4e8f87b27 100644 --- a/src/utils/IdealGraphVisualizer/HierarchicalLayout/src/main/java/com/sun/hotspot/igv/hierarchicallayout/HierarchicalCFGLayoutManager.java +++ b/src/utils/IdealGraphVisualizer/HierarchicalLayout/src/main/java/com/sun/hotspot/igv/hierarchicallayout/HierarchicalCFGLayoutManager.java @@ -45,6 +45,12 @@ public HierarchicalCFGLayoutManager() { fontMetrics = canvas.getFontMetrics(font); } + @Override + public void setCutEdges(boolean enable) { + subManager.setCutEdges(enable); + manager.setCutEdges(enable); + } + public void setSubManager(LayoutManager manager) { this.subManager = manager; } diff --git a/src/utils/IdealGraphVisualizer/HierarchicalLayout/src/main/java/com/sun/hotspot/igv/hierarchicallayout/HierarchicalClusterLayoutManager.java b/src/utils/IdealGraphVisualizer/HierarchicalLayout/src/main/java/com/sun/hotspot/igv/hierarchicallayout/HierarchicalClusterLayoutManager.java index badfb0e036a..1d103585e58 100644 --- a/src/utils/IdealGraphVisualizer/HierarchicalLayout/src/main/java/com/sun/hotspot/igv/hierarchicallayout/HierarchicalClusterLayoutManager.java +++ b/src/utils/IdealGraphVisualizer/HierarchicalLayout/src/main/java/com/sun/hotspot/igv/hierarchicallayout/HierarchicalClusterLayoutManager.java @@ -43,6 +43,12 @@ public HierarchicalClusterLayoutManager(HierarchicalLayoutManager.Combine combin this.combine = combine; } + @Override + public void setCutEdges(boolean enable) { + subManager.setCutEdges(enable); + manager.setCutEdges(enable); + } + public void doLayout(LayoutGraph graph, Set importantLinks) { doLayout(graph); } diff --git a/src/utils/IdealGraphVisualizer/HierarchicalLayout/src/main/java/com/sun/hotspot/igv/hierarchicallayout/HierarchicalLayoutManager.java b/src/utils/IdealGraphVisualizer/HierarchicalLayout/src/main/java/com/sun/hotspot/igv/hierarchicallayout/HierarchicalLayoutManager.java index 0c9e5ccd480..996fd895577 100644 --- a/src/utils/IdealGraphVisualizer/HierarchicalLayout/src/main/java/com/sun/hotspot/igv/hierarchicallayout/HierarchicalLayoutManager.java +++ b/src/utils/IdealGraphVisualizer/HierarchicalLayout/src/main/java/com/sun/hotspot/igv/hierarchicallayout/HierarchicalLayoutManager.java @@ -136,8 +136,9 @@ public void setLayerOffset(int layerOffset) { this.layerOffset = layerOffset; } - public void setMaxLayerLength(int v) { - maxLayerLength = v; + @Override + public void setCutEdges(boolean enable) { + maxLayerLength = enable ? 10 : -1; } public void setMinLayerDifference(int v) { diff --git a/src/utils/IdealGraphVisualizer/HierarchicalLayout/src/main/java/com/sun/hotspot/igv/hierarchicallayout/HierarchicalStableLayoutManager.java b/src/utils/IdealGraphVisualizer/HierarchicalLayout/src/main/java/com/sun/hotspot/igv/hierarchicallayout/HierarchicalStableLayoutManager.java index 875ccb19022..2d76d15394c 100644 --- a/src/utils/IdealGraphVisualizer/HierarchicalLayout/src/main/java/com/sun/hotspot/igv/hierarchicallayout/HierarchicalStableLayoutManager.java +++ b/src/utils/IdealGraphVisualizer/HierarchicalLayout/src/main/java/com/sun/hotspot/igv/hierarchicallayout/HierarchicalStableLayoutManager.java @@ -38,8 +38,8 @@ public class HierarchicalStableLayoutManager { public static final int X_OFFSET = 8; public static final int LAYER_OFFSET = 8; // Algorithm global data structures - private HashSet currentVertices; - private HashSet currentLinks; + private Set currentVertices; + private Set currentLinks; private Set reversedLinks; private List nodes; private final HashMap vertexToLayoutNode; @@ -51,10 +51,19 @@ public class HierarchicalStableLayoutManager { private HashMap vertexToAction; private List vertexActions; private List linkActions; - private HashSet oldVertices; - private HashSet oldLinks; + private Set oldVertices; + private Set oldLinks; private boolean shouldRedrawLayout = true; private boolean shouldRemoveEmptyLayers = true; + private boolean cutEdges = false; + + public void doLayout(LayoutGraph layoutGraph) { + boolean oldShouldRedrawLayout = shouldRedrawLayout; + setShouldRedrawLayout(true); + updateLayout(layoutGraph.getVertices(), layoutGraph.getLinks()); + setShouldRedrawLayout(oldShouldRedrawLayout); + } + enum Action { ADD, @@ -90,6 +99,15 @@ public HierarchicalStableLayoutManager() { nodes = new ArrayList<>(); } + public void setCutEdges(boolean enable) { + cutEdges = enable; + manager.setCutEdges(enable); + } + + public boolean getCutEdges() { + return cutEdges; + } + private int calculateOptimalBoth(LayoutNode n) { if (n.preds.isEmpty() && n.succs.isEmpty()) { return n.x; @@ -396,7 +414,7 @@ public void setShouldRedrawLayout(boolean shouldRedrawLayout) { this.shouldRedrawLayout = shouldRedrawLayout; } - public void updateLayout(HashSet vertices, HashSet links) { + public void updateLayout(Set vertices, Set links) { currentVertices = vertices; currentLinks = links; reversedLinks = new HashSet<>(); diff --git a/src/utils/IdealGraphVisualizer/HierarchicalLayout/src/main/java/com/sun/hotspot/igv/hierarchicallayout/LinearLayoutManager.java b/src/utils/IdealGraphVisualizer/HierarchicalLayout/src/main/java/com/sun/hotspot/igv/hierarchicallayout/LinearLayoutManager.java index 32f56e69bf9..69d53ebc9fa 100644 --- a/src/utils/IdealGraphVisualizer/HierarchicalLayout/src/main/java/com/sun/hotspot/igv/hierarchicallayout/LinearLayoutManager.java +++ b/src/utils/IdealGraphVisualizer/HierarchicalLayout/src/main/java/com/sun/hotspot/igv/hierarchicallayout/LinearLayoutManager.java @@ -39,6 +39,9 @@ public LinearLayoutManager(Map vertexRank) { this.vertexRank = vertexRank; } + @Override + public void setCutEdges(boolean enable) {} + @Override public void doLayout(LayoutGraph graph) { doLayout(graph, new HashSet<>()); diff --git a/src/utils/IdealGraphVisualizer/Layout/src/main/java/com/sun/hotspot/igv/layout/LayoutManager.java b/src/utils/IdealGraphVisualizer/Layout/src/main/java/com/sun/hotspot/igv/layout/LayoutManager.java index 86a0d02e16b..a74ef280ebe 100644 --- a/src/utils/IdealGraphVisualizer/Layout/src/main/java/com/sun/hotspot/igv/layout/LayoutManager.java +++ b/src/utils/IdealGraphVisualizer/Layout/src/main/java/com/sun/hotspot/igv/layout/LayoutManager.java @@ -31,6 +31,8 @@ */ public interface LayoutManager { + void setCutEdges(boolean enable); + void doLayout(LayoutGraph graph); void doLayout(LayoutGraph graph, Set importantLinks); diff --git a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/DiagramScene.java b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/DiagramScene.java index f9c2e991d46..3f7fec74505 100644 --- a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/DiagramScene.java +++ b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/DiagramScene.java @@ -700,12 +700,19 @@ private boolean isVisible(Connection c) { } private void doStableSeaLayout(HashSet
visibleFigures, HashSet visibleConnections) { - hierarchicalStableLayoutManager.updateLayout(visibleFigures, visibleConnections); + boolean enable = model.getCutEdges(); + boolean previous = hierarchicalStableLayoutManager.getCutEdges(); + hierarchicalStableLayoutManager.setCutEdges(enable); + if (enable != previous) { + hierarchicalStableLayoutManager.doLayout(new LayoutGraph(visibleConnections, visibleFigures)); + } else { + hierarchicalStableLayoutManager.updateLayout(visibleFigures, visibleConnections); + } } private void doSeaLayout(HashSet
figures, HashSet edges) { HierarchicalLayoutManager manager = new HierarchicalLayoutManager(HierarchicalLayoutManager.Combine.SAME_OUTPUTS); - manager.setMaxLayerLength(10); + manager.setCutEdges(model.getCutEdges()); manager.doLayout(new LayoutGraph(edges, figures)); hierarchicalStableLayoutManager.setShouldRedrawLayout(true); } @@ -713,7 +720,7 @@ private void doSeaLayout(HashSet
figures, HashSet edges) { private void doClusteredLayout(HashSet edges) { HierarchicalClusterLayoutManager m = new HierarchicalClusterLayoutManager(HierarchicalLayoutManager.Combine.SAME_OUTPUTS); HierarchicalLayoutManager manager = new HierarchicalLayoutManager(HierarchicalLayoutManager.Combine.SAME_OUTPUTS); - manager.setMaxLayerLength(9); + manager.setCutEdges(model.getCutEdges()); manager.setMinLayerDifference(3); m.setManager(manager); m.setSubManager(new HierarchicalLayoutManager(HierarchicalLayoutManager.Combine.SAME_OUTPUTS)); @@ -724,7 +731,7 @@ private void doCFGLayout(HashSet
figures, HashSet edges) { Diagram diagram = getModel().getDiagram(); HierarchicalCFGLayoutManager m = new HierarchicalCFGLayoutManager(); HierarchicalLayoutManager manager = new HierarchicalLayoutManager(HierarchicalLayoutManager.Combine.SAME_OUTPUTS); - manager.setMaxLayerLength(9); + manager.setCutEdges(model.getCutEdges()); manager.setMinLayerDifference(1); manager.setLayoutSelfEdges(true); manager.setXOffset(25); diff --git a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/DiagramViewModel.java b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/DiagramViewModel.java index 6d7599e6d34..3081825025f 100644 --- a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/DiagramViewModel.java +++ b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/DiagramViewModel.java @@ -36,6 +36,7 @@ import com.sun.hotspot.igv.graph.MatcherSelector; import com.sun.hotspot.igv.settings.Settings; import com.sun.hotspot.igv.util.RangeSliderModel; +import com.sun.hotspot.igv.view.actions.CutEdgesAction; import com.sun.hotspot.igv.view.actions.GlobalSelectionAction; import java.awt.Color; import java.util.*; @@ -68,8 +69,8 @@ public class DiagramViewModel extends RangeSliderModel implements ChangedListene private boolean showCFG; private boolean showNodeHull; private boolean showEmptyBlocks; - private boolean hideDuplicates; private static boolean globalSelection = false; + private static boolean cutEdges = false; private final ChangedListener filterChainChangedListener = changedFilterChain -> { assert filterChain == changedFilterChain; @@ -80,6 +81,18 @@ public Group getGroup() { return group; } + public boolean getCutEdges() { + return cutEdges; + } + + public void setCutEdges(boolean enable, boolean fire) { + boolean prevEnable = cutEdges; + cutEdges = enable; + if (fire && prevEnable != enable) { + diagramChangedEvent.fire(); + } + } + public boolean getGlobalSelection() { return globalSelection; } @@ -154,25 +167,6 @@ public void setShowEmptyBlocks(boolean b) { diagramChangedEvent.fire(); } - public void setHideDuplicates(boolean hideDuplicates) { - this.hideDuplicates = hideDuplicates; - InputGraph currentGraph = getFirstGraph(); - if (hideDuplicates) { - // Back up to the unhidden equivalent graph - int index = graphs.indexOf(currentGraph); - while (graphs.get(index).getProperties().get("_isDuplicate") != null) { - index--; - } - currentGraph = graphs.get(index); - } - filterGraphs(); - selectGraph(currentGraph); - } - - public boolean getHideDuplicates() { - return hideDuplicates; - } - private void initGroup() { group.getChangedEvent().addListener(g -> { assert g == group; @@ -191,6 +185,7 @@ private void initGroup() { public DiagramViewModel(DiagramViewModel model) { super(model); globalSelection = false; + cutEdges = false; group = model.getGroup(); initGroup(); graphs = new ArrayList<>(model.graphs); @@ -205,12 +200,12 @@ public DiagramViewModel(DiagramViewModel model) { filtersOrder = provider.getAllFiltersOrdered(); globalSelection = GlobalSelectionAction.get(GlobalSelectionAction.class).isSelected(); + cutEdges = CutEdgesAction.get(CutEdgesAction.class).isSelected(); showCFG = model.getShowCFG(); showSea = model.getShowSea(); showBlocks = model.getShowBlocks(); showNodeHull = model.getShowNodeHull(); showEmptyBlocks = model.getShowEmptyBlocks(); - hideDuplicates = model.getHideDuplicates(); hiddenNodes = new HashSet<>(model.getHiddenNodes()); selectedNodes = new HashSet<>(); @@ -228,13 +223,13 @@ public DiagramViewModel(InputGraph graph) { filtersOrder = provider.getAllFiltersOrdered(); globalSelection = GlobalSelectionAction.get(GlobalSelectionAction.class).isSelected(); + cutEdges = CutEdgesAction.get(CutEdgesAction.class).isSelected(); showStableSea = Settings.get().getInt(Settings.DEFAULT_VIEW, Settings.DEFAULT_VIEW_DEFAULT) == Settings.DefaultView.STABLE_SEA_OF_NODES; showSea = Settings.get().getInt(Settings.DEFAULT_VIEW, Settings.DEFAULT_VIEW_DEFAULT) == Settings.DefaultView.SEA_OF_NODES; showBlocks = Settings.get().getInt(Settings.DEFAULT_VIEW, Settings.DEFAULT_VIEW_DEFAULT) == Settings.DefaultView.CLUSTERED_SEA_OF_NODES; showCFG = Settings.get().getInt(Settings.DEFAULT_VIEW, Settings.DEFAULT_VIEW_DEFAULT) == Settings.DefaultView.CONTROL_FLOW_GRAPH; showNodeHull = true; showEmptyBlocks = true; - hideDuplicates = false; hiddenNodes = new HashSet<>(); selectedNodes = new HashSet<>(); @@ -422,11 +417,8 @@ private void filterGraphs() { ArrayList result = new ArrayList<>(); List positions = new ArrayList<>(); for (InputGraph graph : group.getGraphs()) { - String duplicate = graph.getProperties().get("_isDuplicate"); - if (duplicate == null || !hideDuplicates) { - result.add(graph); - positions.add(graph.getName()); - } + result.add(graph); + positions.add(graph.getName()); } this.graphs = result; setPositions(positions); @@ -460,22 +452,12 @@ public InputGraph getSecondGraph() { public void selectGraph(InputGraph graph) { int index = graphs.indexOf(graph); - if (index == -1 && hideDuplicates) { - // A graph was selected that's currently hidden, so unhide and select it. - setHideDuplicates(false); - index = graphs.indexOf(graph); - } assert index != -1; setPositions(index, index); } public void selectDiffGraph(InputGraph graph) { int index = graphs.indexOf(graph); - if (index == -1 && hideDuplicates) { - // A graph was selected that's currently hidden, so unhide and select it. - setHideDuplicates(false); - index = graphs.indexOf(graph); - } assert index != -1; int firstIndex = getFirstPosition(); int secondIndex = getSecondPosition(); diff --git a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/EditorTopComponent.java b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/EditorTopComponent.java index e24ffa476a2..d69047c8c3e 100644 --- a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/EditorTopComponent.java +++ b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/EditorTopComponent.java @@ -210,7 +210,6 @@ public void mouseMoved(MouseEvent e) {} toolBar.addSeparator(); toolBar.add(new JToggleButton(new PredSuccAction(diagramViewModel.getShowNodeHull()))); toolBar.add(new JToggleButton(new ShowEmptyBlocksAction(cfgLayoutAction, diagramViewModel.getShowEmptyBlocks()))); - toolBar.add(new JToggleButton(new HideDuplicatesAction(diagramViewModel.getHideDuplicates()))); toolBar.addSeparator(); UndoAction undoAction = UndoAction.get(UndoAction.class); @@ -221,6 +220,11 @@ public void mouseMoved(MouseEvent e) {} toolBar.add(redoAction); toolBar.addSeparator(); + + JToggleButton cutEdgesButton = new JToggleButton(CutEdgesAction.get(CutEdgesAction.class)); + cutEdgesButton.setHideActionText(true); + toolBar.add(cutEdgesButton); + JToggleButton globalSelectionButton = new JToggleButton(GlobalSelectionAction.get(GlobalSelectionAction.class)); globalSelectionButton.setHideActionText(true); toolBar.add(globalSelectionButton); @@ -453,6 +457,7 @@ public TopComponent cloneComponent() { } etc.addSelectedNodes(selectedNodes, false); model.setGlobalSelection(GlobalSelectionAction.get(GlobalSelectionAction.class).isSelected(), false); + model.setCutEdges(CutEdgesAction.get(CutEdgesAction.class).isSelected(), false); etc.resetUndoRedo(); int currentZoomLevel = scene.getZoomPercentage(); diff --git a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/actions/CutEdgesAction.java b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/actions/CutEdgesAction.java new file mode 100644 index 00000000000..4467031bab9 --- /dev/null +++ b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/actions/CutEdgesAction.java @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ +package com.sun.hotspot.igv.view.actions; + +import com.sun.hotspot.igv.view.EditorTopComponent; +import javax.swing.AbstractAction; +import javax.swing.Action; +import javax.swing.ImageIcon; +import javax.swing.SwingUtilities; +import org.openide.awt.ActionID; +import org.openide.awt.ActionReference; +import org.openide.awt.ActionReferences; +import org.openide.awt.ActionRegistration; +import org.openide.util.HelpCtx; +import org.openide.util.ImageUtilities; +import org.openide.util.NbBundle; +import org.openide.util.actions.CallableSystemAction; + +@ActionID(category = "View", id = "com.sun.hotspot.igv.view.actions.CutEdgesAction") +@ActionRegistration(displayName = "#CTL_CutEdgesAction") +@ActionReferences({ + @ActionReference(path = "Menu/Options", position = 350), +}) +@NbBundle.Messages({ + "CTL_CutEdgesAction=Cut long edges", + "HINT_CutEdgesAction=Cut long edges" +}) +public final class CutEdgesAction extends CallableSystemAction { + + private boolean isSelected; + + public CutEdgesAction() { + putValue(AbstractAction.SMALL_ICON, new ImageIcon(ImageUtilities.loadImage(iconResource()))); + putValue(Action.SHORT_DESCRIPTION, getDescription()); + putValue(SELECTED_KEY, false); + isSelected = false; + } + + @Override + public String getName() { + return NbBundle.getMessage(CutEdgesAction.class, "CTL_CutEdgesAction"); + } + + @Override + public HelpCtx getHelpCtx() { + return HelpCtx.DEFAULT_HELP; + } + + @Override + public void performAction() { + isSelected = !isSelected; + putValue(SELECTED_KEY, isSelected); + EditorTopComponent editor = EditorTopComponent.getActive(); + if (editor != null) { + SwingUtilities.invokeLater(() -> editor.getModel().setCutEdges(isSelected, true)); + } + } + + public boolean isSelected() { + return isSelected; + } + + private String getDescription() { + return NbBundle.getMessage(CutEdgesAction.class, "HINT_CutEdgesAction"); + } + + @Override + protected boolean asynchronous() { + return false; + } + + @Override + public String iconResource() { + return "com/sun/hotspot/igv/view/images/cut.png"; + } +} diff --git a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/actions/HideDuplicatesAction.java b/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/actions/HideDuplicatesAction.java deleted file mode 100644 index 34dd615b459..00000000000 --- a/src/utils/IdealGraphVisualizer/View/src/main/java/com/sun/hotspot/igv/view/actions/HideDuplicatesAction.java +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright (c) 2014, 2023, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - * - */ -package com.sun.hotspot.igv.view.actions; - -import com.sun.hotspot.igv.view.EditorTopComponent; -import java.awt.event.ActionEvent; -import javax.swing.AbstractAction; -import javax.swing.Action; -import javax.swing.ImageIcon; -import org.openide.util.ImageUtilities; - -/** - * - * @author Tom Rodriguez - */ -public class HideDuplicatesAction extends AbstractAction { - - public HideDuplicatesAction(boolean selected) { - putValue(AbstractAction.SMALL_ICON, new ImageIcon(ImageUtilities.loadImage(iconResource()))); - putValue(Action.SELECTED_KEY, selected); - putValue(Action.SHORT_DESCRIPTION, "Hide graphs which are the same as the previous graph"); - } - - @Override - public void actionPerformed(ActionEvent ev) { - EditorTopComponent editor = EditorTopComponent.getActive(); - if (editor != null) { - boolean selected = (boolean)getValue(SELECTED_KEY); - editor.getModel().setHideDuplicates(selected); - } - } - - protected String iconResource() { - return "com/sun/hotspot/igv/view/images/hideDuplicates.png"; - } -} diff --git a/src/utils/IdealGraphVisualizer/View/src/main/resources/com/sun/hotspot/igv/view/images/cut.png b/src/utils/IdealGraphVisualizer/View/src/main/resources/com/sun/hotspot/igv/view/images/cut.png new file mode 100644 index 0000000000000000000000000000000000000000..67030403bb0cb819dadb88ba9afa08c7947d180f GIT binary patch literal 2330 zcmZ`(2~-nT6rB((yJ7$>Y9)piu}UTjD1;;xlOREXfGj~R$B;~9FeGU*NU$slMJia3 zs6}x>IH<=3tB6uswLNGB7o;wzrw6dE97Kf_Mckl&5`=(|%+G&$@80+R`+x4=Bnn;Z zU^~qgf*=QB5I+LUj`*Q=laaR ze9GipUtdg@9c-5<_+o~SD?ifuP|k9fwA42weesngizd&o`*wmLd`q-H_FPo$o2({T z26Sgn@z1+;DPn3-du?iPdAZfZ_WFU=f!g*xcIVs_6;}hwt{oa!(rXw zxusC+f$huE?{_1nm-Q%u~D_xm!^Vsan*-zsQyC=A8 zRR6Mn_nGbrbzgcM+V9cwZ-c0AMakBgZixl!(xTZ+lFcmXlFy?rZ?@^&TN!=%l67b8 zuK1lhZf~zY{Uo*VIzv^pnc0z*%skl7%WTQ$SzcP47Wxg*-svJac*C3tSYt&{44ABU_om;YHI)J(f|Cxo-n*w&=N-dcC$N$H&rckG+B zYM;*EijN%o{*=d)d)+sCd(&>_!&Wo~k>`KB+TKf8t9@UTe#`l_;pMf&%PAQSqV*dB zD_5Nj1xMJ6h=uZy5a?@QTSL}_iI4@bNMI-lB!~!R0{B9NY0w0t4MFP((}(OI37&%( zfF#h3TnB*LLSPteXJGHmMIp;UZWWjzo(7R%h>VL+B{Ee!Le(Xy@q7?l#{y;&f=S4_ zB!yDT(s3w81Pj=>8>Wzr5Nr*HA_k4{R2qalpGu?BC|p}InatM6uZGi@1JOb0HG#Hhd_VHl+t zpuk3Y@fQo%k^;pg%2G&_t2q>%mkg0hk`)+btTQyhN2X!JxOZfBHazxnOjt89n{EnY z25?nyZNYJUymq*@&IZE~aNnXren6z}<=8`;`=QtTv@foH)$Ou! zO5FR_Y`cMwTh6`h`wKh_O%~pj8KwLBpRA?N-&8XDtjpoOUA#z6!prIlnEI}N=7PFr z(V?ErlfsnWVawN-tGAttCBpiDMNk(J92C*T&Qj?hgqK+ROh^Yslm>~hypVStJdsD}B6{F( z@45WX|D1b1l(m+)1jgimi@=yDz^3RE&-dTQ@v1`*7^8u!zyffP{bdih0W5jGAN?T+ zj8VV~;Jg5G{4*$itjCTVNTu?)m=DSmZ}RKK~T0UjYXMI|r<) z?Lr{~yaRfHl}xF$2HX^~U7)r!JY1Y|-8H}k>c9Zd1WssRMw~wa*MLDFEBAZT{rx?s zQ>n**tDu6`JNg~E?p>GW)$Pz}4W-T=-`e^P3;}^)$K~9N6I=*JN3#p*^zFe!q6es3r6w|^ z(k}22xMQtt1jZZ!raA=OZL9+WjVNMvXQ#T+Y&L-qxDVX5)`o#G%fLL+#?B;O23CZ% zMHHR$%H{R=UnTM)a0O7nyyyF?|2)e7XPLTE{i}8U1vOa83($Vj#{d8T07*qoM6N<$ Ef*MH^#Q*>R From 475feb064bb6b9dfd34fc52762e3e0ab825254ec Mon Sep 17 00:00:00 2001 From: Magnus Ihse Bursie Date: Mon, 18 Nov 2024 09:23:50 +0000 Subject: [PATCH 049/311] 8344056: Use markdown format for man pages Reviewed-by: cstein, iris, dholmes --- make/common/modules/LauncherCommon.gmk | 10 - src/java.base/share/man/java.1 | 5409 ----------------- src/java.base/share/man/java.md | 4050 ++++++++++++ src/java.base/share/man/keytool.1 | 2991 --------- src/java.base/share/man/keytool.md | 2430 ++++++++ src/java.rmi/share/man/rmiregistry.1 | 100 - src/java.rmi/share/man/rmiregistry.md | 86 + src/java.scripting/share/man/jrunscript.1 | 166 - src/java.scripting/share/man/jrunscript.md | 141 + src/java.security.jgss/windows/man/kinit.md | 154 + src/java.security.jgss/windows/man/klist.md | 98 + src/java.security.jgss/windows/man/ktab.md | 134 + .../windows/man/jabswitch.md | 75 + .../windows/man/jaccessinspector.md | 249 + .../windows/man/jaccesswalker.md | 71 + src/jdk.compiler/share/man/javac.1 | 2372 -------- src/jdk.compiler/share/man/javac.md | 1952 ++++++ src/jdk.compiler/share/man/serialver.1 | 90 - src/jdk.compiler/share/man/serialver.md | 74 + src/jdk.hotspot.agent/share/man/jhsdb.1 | 218 - src/jdk.hotspot.agent/share/man/jhsdb.md | 186 + src/jdk.httpserver/share/man/jwebserver.1 | 193 - src/jdk.httpserver/share/man/jwebserver.md | 152 + src/jdk.jartool/share/man/jar.1 | 379 -- src/jdk.jartool/share/man/jar.md | 313 + src/jdk.jartool/share/man/jarsigner.1 | 1395 ----- src/jdk.jartool/share/man/jarsigner.md | 1089 ++++ src/jdk.javadoc/share/man/javadoc.1 | 1526 ----- src/jdk.javadoc/share/man/javadoc.md | 1214 ++++ src/jdk.jcmd/share/man/jcmd.1 | 1345 ---- src/jdk.jcmd/share/man/jcmd.md | 1032 ++++ src/jdk.jcmd/share/man/jinfo.1 | 103 - src/jdk.jcmd/share/man/jinfo.md | 88 + src/jdk.jcmd/share/man/jmap.1 | 106 - src/jdk.jcmd/share/man/jmap.md | 89 + src/jdk.jcmd/share/man/jps.1 | 235 - src/jdk.jcmd/share/man/jps.md | 189 + src/jdk.jcmd/share/man/jstack.1 | 89 - src/jdk.jcmd/share/man/jstack.md | 73 + src/jdk.jcmd/share/man/jstat.1 | 689 --- src/jdk.jcmd/share/man/jstat.md | 588 ++ src/jdk.jconsole/share/man/jconsole.1 | 104 - src/jdk.jconsole/share/man/jconsole.md | 86 + src/jdk.jdeps/share/man/javap.1 | 259 - src/jdk.jdeps/share/man/javap.md | 227 + src/jdk.jdeps/share/man/jdeprscan.1 | 271 - src/jdk.jdeps/share/man/jdeprscan.md | 217 + src/jdk.jdeps/share/man/jdeps.1 | 338 - src/jdk.jdeps/share/man/jdeps.md | 297 + src/jdk.jdeps/share/man/jnativescan.1 | 220 - src/jdk.jdeps/share/man/jnativescan.md | 175 + src/jdk.jdi/share/man/jdb.1 | 277 - src/jdk.jdi/share/man/jdb.md | 237 + src/jdk.jfr/share/man/jfr.1 | 438 -- src/jdk.jfr/share/man/jfr.md | 399 ++ src/jdk.jlink/share/man/jlink.1 | 409 -- src/jdk.jlink/share/man/jlink.md | 347 ++ src/jdk.jlink/share/man/jmod.1 | 423 -- src/jdk.jlink/share/man/jmod.md | 348 ++ src/jdk.jpackage/share/man/jpackage.1 | 834 --- src/jdk.jpackage/share/man/jpackage.md | 791 +++ src/jdk.jshell/share/man/jshell.1 | 1292 ---- src/jdk.jshell/share/man/jshell.md | 1042 ++++ src/jdk.jstatd/share/man/jstatd.1 | 219 - src/jdk.jstatd/share/man/jstatd.md | 180 + .../jdk/javadoc/tool/CheckManPageOptions.java | 23 +- 66 files changed, 18886 insertions(+), 22510 deletions(-) delete mode 100644 src/java.base/share/man/java.1 create mode 100644 src/java.base/share/man/java.md delete mode 100644 src/java.base/share/man/keytool.1 create mode 100644 src/java.base/share/man/keytool.md delete mode 100644 src/java.rmi/share/man/rmiregistry.1 create mode 100644 src/java.rmi/share/man/rmiregistry.md delete mode 100644 src/java.scripting/share/man/jrunscript.1 create mode 100644 src/java.scripting/share/man/jrunscript.md create mode 100644 src/java.security.jgss/windows/man/kinit.md create mode 100644 src/java.security.jgss/windows/man/klist.md create mode 100644 src/java.security.jgss/windows/man/ktab.md create mode 100644 src/jdk.accessibility/windows/man/jabswitch.md create mode 100644 src/jdk.accessibility/windows/man/jaccessinspector.md create mode 100644 src/jdk.accessibility/windows/man/jaccesswalker.md delete mode 100644 src/jdk.compiler/share/man/javac.1 create mode 100644 src/jdk.compiler/share/man/javac.md delete mode 100644 src/jdk.compiler/share/man/serialver.1 create mode 100644 src/jdk.compiler/share/man/serialver.md delete mode 100644 src/jdk.hotspot.agent/share/man/jhsdb.1 create mode 100644 src/jdk.hotspot.agent/share/man/jhsdb.md delete mode 100644 src/jdk.httpserver/share/man/jwebserver.1 create mode 100644 src/jdk.httpserver/share/man/jwebserver.md delete mode 100644 src/jdk.jartool/share/man/jar.1 create mode 100644 src/jdk.jartool/share/man/jar.md delete mode 100644 src/jdk.jartool/share/man/jarsigner.1 create mode 100644 src/jdk.jartool/share/man/jarsigner.md delete mode 100644 src/jdk.javadoc/share/man/javadoc.1 create mode 100644 src/jdk.javadoc/share/man/javadoc.md delete mode 100644 src/jdk.jcmd/share/man/jcmd.1 create mode 100644 src/jdk.jcmd/share/man/jcmd.md delete mode 100644 src/jdk.jcmd/share/man/jinfo.1 create mode 100644 src/jdk.jcmd/share/man/jinfo.md delete mode 100644 src/jdk.jcmd/share/man/jmap.1 create mode 100644 src/jdk.jcmd/share/man/jmap.md delete mode 100644 src/jdk.jcmd/share/man/jps.1 create mode 100644 src/jdk.jcmd/share/man/jps.md delete mode 100644 src/jdk.jcmd/share/man/jstack.1 create mode 100644 src/jdk.jcmd/share/man/jstack.md delete mode 100644 src/jdk.jcmd/share/man/jstat.1 create mode 100644 src/jdk.jcmd/share/man/jstat.md delete mode 100644 src/jdk.jconsole/share/man/jconsole.1 create mode 100644 src/jdk.jconsole/share/man/jconsole.md delete mode 100644 src/jdk.jdeps/share/man/javap.1 create mode 100644 src/jdk.jdeps/share/man/javap.md delete mode 100644 src/jdk.jdeps/share/man/jdeprscan.1 create mode 100644 src/jdk.jdeps/share/man/jdeprscan.md delete mode 100644 src/jdk.jdeps/share/man/jdeps.1 create mode 100644 src/jdk.jdeps/share/man/jdeps.md delete mode 100644 src/jdk.jdeps/share/man/jnativescan.1 create mode 100644 src/jdk.jdeps/share/man/jnativescan.md delete mode 100644 src/jdk.jdi/share/man/jdb.1 create mode 100644 src/jdk.jdi/share/man/jdb.md delete mode 100644 src/jdk.jfr/share/man/jfr.1 create mode 100644 src/jdk.jfr/share/man/jfr.md delete mode 100644 src/jdk.jlink/share/man/jlink.1 create mode 100644 src/jdk.jlink/share/man/jlink.md delete mode 100644 src/jdk.jlink/share/man/jmod.1 create mode 100644 src/jdk.jlink/share/man/jmod.md delete mode 100644 src/jdk.jpackage/share/man/jpackage.1 create mode 100644 src/jdk.jpackage/share/man/jpackage.md delete mode 100644 src/jdk.jshell/share/man/jshell.1 create mode 100644 src/jdk.jshell/share/man/jshell.md delete mode 100644 src/jdk.jstatd/share/man/jstatd.1 create mode 100644 src/jdk.jstatd/share/man/jstatd.md diff --git a/make/common/modules/LauncherCommon.gmk b/make/common/modules/LauncherCommon.gmk index aa721a683d7..b522df076f3 100644 --- a/make/common/modules/LauncherCommon.gmk +++ b/make/common/modules/LauncherCommon.gmk @@ -178,10 +178,8 @@ ifeq ($(call isTargetOsType, unix)+$(MAKEFILE_PREFIX), true+Launcher) # We assume all our man pages should reside in section 1. MAN_FILES_MD := $(wildcard $(addsuffix /*.md, $(call FindModuleManDirs, $(MODULE)))) - MAN_FILES_TROFF := $(wildcard $(addsuffix /*.1, $(call FindModuleManDirs, $(MODULE)))) ifneq ($(MAN_FILES_MD), ) - # If we got markdown files, ignore the troff files ifeq ($(ENABLE_PANDOC), false) $(info Warning: pandoc not found. Not generating man pages) else @@ -226,13 +224,5 @@ ifeq ($(call isTargetOsType, unix)+$(MAKEFILE_PREFIX), true+Launcher) TARGETS += $(BUILD_MAN_PAGES) endif - else - # No markdown man pages present - $(eval $(call SetupCopyFiles, COPY_MAN_PAGES, \ - DEST := $(SUPPORT_OUTPUTDIR)/modules_man/$(MODULE)/man1, \ - FILES := $(MAN_FILES_TROFF), \ - )) - - TARGETS += $(COPY_MAN_PAGES) endif endif diff --git a/src/java.base/share/man/java.1 b/src/java.base/share/man/java.1 deleted file mode 100644 index da7fb86099f..00000000000 --- a/src/java.base/share/man/java.1 +++ /dev/null @@ -1,5409 +0,0 @@ -.\" Copyright (c) 1994, 2024, Oracle and/or its affiliates. All rights reserved. -.\" DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -.\" -.\" This code is free software; you can redistribute it and/or modify it -.\" under the terms of the GNU General Public License version 2 only, as -.\" published by the Free Software Foundation. -.\" -.\" This code is distributed in the hope that it will be useful, but WITHOUT -.\" ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -.\" FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -.\" version 2 for more details (a copy is included in the LICENSE file that -.\" accompanied this code). -.\" -.\" You should have received a copy of the GNU General Public License version -.\" 2 along with this work; if not, write to the Free Software Foundation, -.\" Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -.\" -.\" Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -.\" or visit www.oracle.com if you need additional information or have any -.\" questions. -.\" -'\" t -.\" Automatically generated by Pandoc 2.19.2 -.\" -.\" Define V font for inline verbatim, using C font in formats -.\" that render this, and otherwise B font. -.ie "\f[CB]x\f[R]"x" \{\ -. ftr V B -. ftr VI BI -. ftr VB B -. ftr VBI BI -.\} -.el \{\ -. ftr V CR -. ftr VI CI -. ftr VB CB -. ftr VBI CBI -.\} -.TH "JAVA" "1" "2025" "JDK 24-ea" "JDK Commands" -.hy -.SH NAME -.PP -java - launch a Java application -.SH SYNOPSIS -.PP -To launch a class file: -.PP -\f[V]java\f[R] [\f[I]options\f[R]] \f[I]mainclass\f[R] [\f[I]args\f[R] -\&...] -.PP -To launch the main class in a JAR file: -.PP -\f[V]java\f[R] [\f[I]options\f[R]] \f[V]-jar\f[R] \f[I]jarfile\f[R] -[\f[I]args\f[R] ...] -.PP -To launch the main class in a module: -.PP -\f[V]java\f[R] [\f[I]options\f[R]] \f[V]-m\f[R] -\f[I]module\f[R][\f[V]/\f[R]\f[I]mainclass\f[R]] [\f[I]args\f[R] ...] -.PP -or -.PP -\f[V]java\f[R] [\f[I]options\f[R]] \f[V]--module\f[R] -\f[I]module\f[R][\f[V]/\f[R]\f[I]mainclass\f[R]] [\f[I]args\f[R] ...] -.PP -To launch a source-file program: -.PP -\f[V]java\f[R] [\f[I]options\f[R]] \f[I]source-file\f[R] [\f[I]args\f[R] -\&...] -.TP -\f[I]options\f[R] -Optional: Specifies command-line options separated by spaces. -See \f[B]Overview of Java Options\f[R] for a description of available -options. -.TP -\f[I]mainclass\f[R] -Specifies the name of the class to be launched. -Command-line entries following \f[V]classname\f[R] are the arguments for -the main method. -.TP -\f[V]-jar\f[R] \f[I]jarfile\f[R] -Executes a program encapsulated in a JAR file. -The \f[I]jarfile\f[R] argument is the name of a JAR file with a manifest -that contains a line in the form -\f[V]Main-Class:\f[R]\f[I]classname\f[R] that defines the class with the -\f[V]public static void main(String[] args)\f[R] method that serves as -your application\[aq]s starting point. -When you use \f[V]-jar\f[R], the specified JAR file is the source of all -user classes, and other class path settings are ignored. -If you\[aq]re using JAR files, then see \f[B]jar\f[R]. -.TP -\f[V]-m\f[R] or \f[V]--module\f[R] \f[I]module\f[R][\f[V]/\f[R]\f[I]mainclass\f[R]] -Executes the main class in a module specified by \f[I]mainclass\f[R] if -it is given, or, if it is not given, the value in the \f[I]module\f[R]. -In other words, \f[I]mainclass\f[R] can be used when it is not specified -by the module, or to override the value when it is specified. -.RS -.PP -See \f[B]Standard Options for Java\f[R]. -.RE -.TP -\f[I]source-file\f[R] -Only used to launch a source-file program. -Specifies the source file that contains the main class when using -source-file mode. -See \f[B]Using Source-File Mode to Launch Source-Code Programs\f[R] -.TP -\f[I]args\f[R] ... -Optional: Arguments following \f[I]mainclass\f[R], -\f[I]source-file\f[R], \f[V]-jar\f[R] \f[I]jarfile\f[R], and -\f[V]-m\f[R] or \f[V]--module\f[R] -\f[I]module\f[R]\f[V]/\f[R]\f[I]mainclass\f[R] are passed as arguments -to the main class. -.SH DESCRIPTION -.PP -The \f[V]java\f[R] command starts a Java application. -It does this by starting the Java Virtual Machine (JVM), loading the -specified class, and calling that class\[aq]s \f[V]main()\f[R] method. -The method must be declared \f[V]public\f[R] and \f[V]static\f[R], it -must not return any value, and it must accept a \f[V]String\f[R] array -as a parameter. -The method declaration has the following form: -.RS -.PP -\f[V]public static void main(String[] args)\f[R] -.RE -.PP -In source-file mode, the \f[V]java\f[R] command can launch a class -declared in a source file. -See \f[B]Using Source-File Mode to Launch Source-Code Programs\f[R] for -a description of using the source-file mode. -.RS -.PP -\f[B]Note:\f[R] You can use the \f[V]JDK_JAVA_OPTIONS\f[R] launcher -environment variable to prepend its content to the actual command line -of the \f[V]java\f[R] launcher. -See \f[B]Using the JDK_JAVA_OPTIONS Launcher Environment Variable\f[R]. -.RE -.PP -By default, the first argument that isn\[aq]t an option of the -\f[V]java\f[R] command is the fully qualified name of the class to be -called. -If \f[V]-jar\f[R] is specified, then its argument is the name of the JAR -file containing class and resource files for the application. -The startup class must be indicated by the \f[V]Main-Class\f[R] manifest -header in its manifest file. -.PP -Arguments after the class file name or the JAR file name are passed to -the \f[V]main()\f[R] method. -.SS \f[V]javaw\f[R] -.PP -\f[B]Windows:\f[R] The \f[V]javaw\f[R] command is identical to -\f[V]java\f[R], except that with \f[V]javaw\f[R] there\[aq]s no -associated console window. -Use \f[V]javaw\f[R] when you don\[aq]t want a command prompt window to -appear. -The \f[V]javaw\f[R] launcher will, however, display a dialog box with -error information if a launch fails. -.SH USING SOURCE-FILE MODE TO LAUNCH SOURCE-CODE PROGRAMS -.PP -To launch a class declared in a source file, run the \f[V]java\f[R] -launcher in source-file mode. -Entering source-file mode is determined by two items on the -\f[V]java\f[R] command line: -.IP \[bu] 2 -The first item on the command line that is not an option or part of an -option. -In other words, the item in the command line that would otherwise be the -main class name. -.IP \[bu] 2 -The \f[V]--source\f[R] \f[I]version\f[R] option, if present. -.PP -If the class identifies an existing file that has a \f[V].java\f[R] -extension, or if the \f[V]--source\f[R] option is specified, then -source-file mode is selected. -The source file is then compiled and run. -The \f[V]--source\f[R] option can be used to specify the source -\f[I]version\f[R] or \f[I]N\f[R] of the source code. -This determines the API that can be used. -When you set \f[V]--source\f[R] \f[I]N\f[R], you can only use the public -API that was defined in JDK \f[I]N\f[R]. -.RS -.PP -\f[B]Note:\f[R] The valid values of \f[I]N\f[R] change for each release, -with new values added and old values removed. -You\[aq]ll get an error message if you use a value of \f[I]N\f[R] that -is no longer supported. -The supported values of \f[I]N\f[R] are the current Java SE release -(\f[V]24\f[R]) and a limited number of previous releases, detailed in -the command-line help for \f[V]javac\f[R], under the \f[V]--source\f[R] -and \f[V]--release\f[R] options. -.RE -.PP -If the file does not have the \f[V].java\f[R] extension, the -\f[V]--source\f[R] option must be used to tell the \f[V]java\f[R] -command to use the source-file mode. -The \f[V]--source\f[R] option is used for cases when the source file is -a \[dq]script\[dq] to be executed and the name of the source file does -not follow the normal naming conventions for Java source files. -.PP -In source-file mode, the effect is as though the source file is compiled -into memory, and the first class found in the source file is executed. -Any arguments placed after the name of the source file in the original -command line are passed to the compiled class when it is executed. -.PP -For example, if a file were named \f[V]HelloWorld.java\f[R] and -contained a class named \f[V]HelloWorld\f[R], then the source-file mode -command to launch the class would be: -.RS -.PP -\f[V]java HelloWorld.java\f[R] -.RE -.PP -This use of source-file mode is informally equivalent to using the -following two commands: -.IP -.nf -\f[CB] -javac -d --source-path HelloWorld.java -java --class-path HelloWorld -\f[R] -.fi -.PP -where \f[V]\f[R] is computed -.PP -\f[B]In source-file mode, any additional command-line options are -processed as follows:\f[R] -.IP \[bu] 2 -The launcher scans the options specified before the source file for any -that are relevant in order to compile the source file. -.RS 2 -.PP -This includes: \f[V]--class-path\f[R], \f[V]--module-path\f[R], -\f[V]--add-exports\f[R], \f[V]--add-modules\f[R], -\f[V]--limit-modules\f[R], \f[V]--patch-module\f[R], -\f[V]--upgrade-module-path\f[R], and any variant forms of those options. -It also includes the new \f[V]--enable-preview\f[R] option, described in -JEP 12. -.RE -.IP \[bu] 2 -No provision is made to pass any additional options to the compiler, -such as \f[V]-processor\f[R] or \f[V]-Werror\f[R]. -.IP \[bu] 2 -Command-line argument files (\f[V]\[at]\f[R]-files) may be used in the -standard way. -Long lists of arguments for either the VM or the program being invoked -may be placed in files specified on the command-line by prefixing the -filename with an \f[V]\[at]\f[R] character. -.PP -\f[B]In source-file mode, compilation proceeds as follows:\f[R] -.IP \[bu] 2 -Any command-line options that are relevant to the compilation -environment are taken into account. -These include: -\f[V]--class-path\f[R]/\f[V]-classpath\f[R]/\f[V]-cp\f[R], -\f[V]--module-path\f[R]/\f[V]-p\f[R], \f[V]--add-exports\f[R], -\f[V]--add-modules\f[R], \f[V]--limit-modules\f[R], -\f[V]--patch-module\f[R], \f[V]--upgrade-module-path\f[R], -\f[V]--enable-preview\f[R]. -.IP \[bu] 2 -The root of the source tree, \f[V]\f[R] is computed from -the package of the class being launched. -For example, if \f[V]HelloWorld.java\f[R] declared its classes to be in -the \f[V]hello\f[R] package, then the file \f[V]HelloWorld.java\f[R] is -expected to reside in the directory \f[V]somedir/hello/\f[R]. -In this case, \f[V]somedir\f[R] is computed to be the root of the source -tree. -.IP \[bu] 2 -The root of the source tree serves as the source-path for compilation, -so that other source files found in that tree and are needed by -\f[V]HelloWorld\f[R] could be compiled. -.IP \[bu] 2 -Annotation processing is disabled, as if \f[V]-proc:none\f[R] is in -effect. -.IP \[bu] 2 -If a version is specified, via the \f[V]--source\f[R] option, the value -is used as the argument for an implicit \f[V]--release\f[R] option for -the compilation. -This sets both the source version accepted by compiler and the system -API that may be used by the code in the source file. -.IP \[bu] 2 -If \f[V]--enable-preview\f[R] is specified, the \f[V]--source N\f[R] -arguments can be omitted. -If the Java runtime version is \f[V]N\f[R], then \f[V]--release N\f[R] -is implied when compiling source files. -.IP \[bu] 2 -If a \f[V]module-info.java\f[R] file exists in the -\f[V]\f[R] directory, its module declaration is used to -define a named module that will contain all the classes compiled from -\f[V].java\f[R] files in the source tree. -If \f[V]module-info.java\f[R] does not exist, all the classes compiled -from source files will be compiled in the context of the unnamed module. -.IP \[bu] 2 -The source file that is launched should contain one or more top-level -classes, the first of which is taken as the class to be executed. -.IP \[bu] 2 -For the source file that is launched, the compiler does not enforce the -optional restriction defined at the end of JLS 7.6, that a type in a -named package should exist in a file whose name is composed from the -type name followed by the \f[V].java\f[R] extension. -.IP \[bu] 2 -If a source file contains errors, appropriate error messages are written -to the standard error stream, and the launcher exits with a non-zero -exit code. -.PP -\f[B]In source-file mode, execution proceeds as follows:\f[R] -.IP \[bu] 2 -The class to be executed is the first top-level class found in the -source file. -It must contain a declaration of an entry \f[V]main\f[R] method. -.IP \[bu] 2 -The compiled classes are loaded by a custom class loader, that delegates -to the application class loader. -This implies that classes appearing on the application class path cannot -refer to any classes declared in source files. -.IP \[bu] 2 -If a \f[V]module-info.java\f[R] file exists in the -\f[V]\f[R] directory, then all the classes compiled from -\f[V].java\f[R] files in the source tree will be in that module, which -will serve as the root module for the execution of the program. -If \f[V]module-info.java\f[R] does not exist, the compiled classes are -executed in the context of an unnamed module, as though -\f[V]--add-modules=ALL-DEFAULT\f[R] is in effect. -This is in addition to any other \f[V]--add-module\f[R] options that may -be have been specified on the command line. -.IP \[bu] 2 -Any arguments appearing after the name of the file on the command line -are passed to the main method in the obvious way. -.IP \[bu] 2 -It is an error if there is a class on the application class path whose -name is the same as that of the class to be executed. -.PP -See \f[B]JEP 458: Launch Multi-File Source-Code Programs\f[R] -[https://openjdk.org/jeps/458] for complete details. -.SH USING THE JDK_JAVA_OPTIONS LAUNCHER ENVIRONMENT VARIABLE -.PP -\f[V]JDK_JAVA_OPTIONS\f[R] prepends its content to the options parsed -from the command line. -The content of the \f[V]JDK_JAVA_OPTIONS\f[R] environment variable is a -list of arguments separated by white-space characters (as determined by -\f[V]isspace()\f[R]). -These are prepended to the command line arguments passed to -\f[V]java\f[R] launcher. -The encoding requirement for the environment variable is the same as the -\f[V]java\f[R] command line on the system. -\f[V]JDK_JAVA_OPTIONS\f[R] environment variable content is treated in -the same manner as that specified in the command line. -.PP -Single (\f[V]\[aq]\f[R]) or double (\f[V]\[dq]\f[R]) quotes can be used -to enclose arguments that contain whitespace characters. -All content between the open quote and the first matching close quote -are preserved by simply removing the pair of quotes. -In case a matching quote is not found, the launcher will abort with an -error message. -\f[V]\[at]\f[R]-files are supported as they are specified in the command -line. -However, as in \f[V]\[at]\f[R]-files, use of a wildcard is not -supported. -In order to mitigate potential misuse of \f[V]JDK_JAVA_OPTIONS\f[R] -behavior, options that specify the main class (such as \f[V]-jar\f[R]) -or cause the \f[V]java\f[R] launcher to exit without executing the main -class (such as \f[V]-h\f[R]) are disallowed in the environment variable. -If any of these options appear in the environment variable, the launcher -will abort with an error message. -When \f[V]JDK_JAVA_OPTIONS\f[R] is set, the launcher prints a message to -stderr as a reminder. -.PP -\f[B]Example:\f[R] -.IP -.nf -\f[CB] -$ export JDK_JAVA_OPTIONS=\[aq]-g \[at]file1 -Dprop=value \[at]file2 -Dws.prop=\[dq]white spaces\[dq]\[aq] -$ java -Xint \[at]file3 -\f[R] -.fi -.PP -is equivalent to the command line: -.IP -.nf -\f[CB] -java -g \[at]file1 -Dprop=value \[at]file2 -Dws.prop=\[dq]white spaces\[dq] -Xint \[at]file3 -\f[R] -.fi -.SH OVERVIEW OF JAVA OPTIONS -.PP -The \f[V]java\f[R] command supports a wide range of options in the -following categories: -.IP \[bu] 2 -\f[B]Standard Options for Java\f[R]: Options guaranteed to be supported -by all implementations of the Java Virtual Machine (JVM). -They\[aq]re used for common actions, such as checking the version of the -JRE, setting the class path, enabling verbose output, and so on. -.IP \[bu] 2 -\f[B]Extra Options for Java\f[R]: General purpose options that are -specific to the Java HotSpot Virtual Machine. -They aren\[aq]t guaranteed to be supported by all JVM implementations, -and are subject to change. -These options start with \f[V]-X\f[R]. -.PP -The advanced options aren\[aq]t recommended for casual use. -These are developer options used for tuning specific areas of the Java -HotSpot Virtual Machine operation that often have specific system -requirements and may require privileged access to system configuration -parameters. -Several examples of performance tuning are provided in \f[B]Performance -Tuning Examples\f[R]. -These options aren\[aq]t guaranteed to be supported by all JVM -implementations and are subject to change. -Advanced options start with \f[V]-XX\f[R]. -.IP \[bu] 2 -\f[B]Advanced Runtime Options for Java\f[R]: Control the runtime -behavior of the Java HotSpot VM. -.IP \[bu] 2 -\f[B]Advanced JIT Compiler Options for java\f[R]: Control the dynamic -just-in-time (JIT) compilation performed by the Java HotSpot VM. -.IP \[bu] 2 -\f[B]Advanced Serviceability Options for Java\f[R]: Enable gathering -system information and performing extensive debugging. -.IP \[bu] 2 -\f[B]Advanced Garbage Collection Options for Java\f[R]: Control how -garbage collection (GC) is performed by the Java HotSpot -.PP -Boolean options are used to either enable a feature that\[aq]s disabled -by default or disable a feature that\[aq]s enabled by default. -Such options don\[aq]t require a parameter. -Boolean \f[V]-XX\f[R] options are enabled using the plus sign -(\f[V]-XX:+\f[R]\f[I]OptionName\f[R]) and disabled using the minus sign -(\f[V]-XX:-\f[R]\f[I]OptionName\f[R]). -.PP -For options that require an argument, the argument may be separated from -the option name by a space, a colon (:), or an equal sign (=), or the -argument may directly follow the option (the exact syntax differs for -each option). -If you\[aq]re expected to specify the size in bytes, then you can use no -suffix, or use the suffix \f[V]k\f[R] or \f[V]K\f[R] for kilobytes (KB), -\f[V]m\f[R] or \f[V]M\f[R] for megabytes (MB), or \f[V]g\f[R] or -\f[V]G\f[R] for gigabytes (GB). -For example, to set the size to 8 GB, you can specify either -\f[V]8g\f[R], \f[V]8192m\f[R], \f[V]8388608k\f[R], or -\f[V]8589934592\f[R] as the argument. -If you are expected to specify the percentage, then use a number from 0 -to 1. -For example, specify \f[V]0.25\f[R] for 25%. -.PP -The following sections describe the options that are deprecated, -obsolete, and removed: -.IP \[bu] 2 -\f[B]Deprecated Java Options\f[R]: Accepted and acted upon --- a warning -is issued when they\[aq]re used. -.IP \[bu] 2 -\f[B]Obsolete Java Options\f[R]: Accepted but ignored --- a warning is -issued when they\[aq]re used. -.IP \[bu] 2 -\f[B]Removed Java Options\f[R]: Removed --- using them results in an -error. -.SH STANDARD OPTIONS FOR JAVA -.PP -These are the most commonly used options supported by all -implementations of the JVM. -.RS -.PP -\f[B]Note:\f[R] To specify an argument for a long option, you can use -either \f[V]--\f[R]\f[I]name\f[R]\f[V]=\f[R]\f[I]value\f[R] or -\f[V]--\f[R]\f[I]name\f[R] \f[I]value\f[R]. -.RE -.TP -\f[V]-agentlib:\f[R]\f[I]libname\f[R][\f[V]=\f[R]\f[I]options\f[R]] -Loads the specified native agent library. -After the library name, a comma-separated list of options specific to -the library can be used. -If the option \f[V]-agentlib:foo\f[R] is specified, then the JVM -attempts to load the library named \f[V]foo\f[R] using the platform -specific naming conventions and locations: -.RS -.IP \[bu] 2 -\f[B]Linux and other POSIX-like platforms:\f[R] The JVM attempts to load -the library named \f[V]libfoo.so\f[R] in the location specified by the -\f[V]LD_LIBRARY_PATH\f[R] system variable. -.IP \[bu] 2 -\f[B]macOS:\f[R] The JVM attempts to load the library named -\f[V]libfoo.dylib\f[R] in the location specified by the -\f[V]DYLD_LIBRARY_PATH\f[R] system variable. -.IP \[bu] 2 -\f[B]Windows:\f[R] The JVM attempts to load the library named -\f[V]foo.dll\f[R] in the location specified by the \f[V]PATH\f[R] system -variable. -.RS 2 -.PP -The following example shows how to load the Java Debug Wire Protocol -(JDWP) library and listen for the socket connection on port 8000, -suspending the JVM before the main class loads: -.RS -.PP -\f[V]-agentlib:jdwp=transport=dt_socket,server=y,address=8000\f[R] -.RE -.RE -.RE -.TP -\f[V]-agentpath:\f[R]\f[I]pathname\f[R][\f[V]=\f[R]\f[I]options\f[R]] -Loads the native agent library specified by the absolute path name. -This option is equivalent to \f[V]-agentlib\f[R] but uses the full path -and file name of the library. -.TP -\f[V]--class-path\f[R] \f[I]classpath\f[R], \f[V]-classpath\f[R] \f[I]classpath\f[R], or \f[V]-cp\f[R] \f[I]classpath\f[R] -Specifies a list of directories, JAR files, and ZIP archives to search -for class files. -.RS -.PP -On Windows, semicolons (\f[V];\f[R]) separate entities in this list; on -other platforms it is a colon (\f[V]:\f[R]). -.PP -Specifying \f[I]classpath\f[R] overrides any setting of the -\f[V]CLASSPATH\f[R] environment variable. -If the class path option isn\[aq]t used and \f[I]classpath\f[R] -isn\[aq]t set, then the user class path consists of the current -directory (.). -.PP -As a special convenience, a class path element that contains a base name -of an asterisk (*) is considered equivalent to specifying a list of all -the files in the directory with the extension \f[V].jar\f[R] or -\f[V].JAR\f[R] . -A Java program can\[aq]t tell the difference between the two -invocations. -For example, if the directory mydir contains \f[V]a.jar\f[R] and -\f[V]b.JAR\f[R], then the class path element mydir/* is expanded to -\f[V]A.jar:b.JAR\f[R], except that the order of JAR files is -unspecified. -All \f[V].jar\f[R] files in the specified directory, even hidden ones, -are included in the list. -A class path entry consisting of an asterisk (*) expands to a list of -all the jar files in the current directory. -The \f[V]CLASSPATH\f[R] environment variable, where defined, is -similarly expanded. -Any class path wildcard expansion that occurs before the Java VM is -started. -Java programs never see wildcards that aren\[aq]t expanded except by -querying the environment, such as by calling -\f[V]System.getenv(\[dq]CLASSPATH\[dq])\f[R]. -.RE -.TP -\f[V]--disable-\[at]files\f[R] -Can be used anywhere on the command line, including in an argument file, -to prevent further \f[V]\[at]filename\f[R] expansion. -This option stops expanding \f[V]\[at]\f[R]-argfiles after the option. -.TP -\f[V]--enable-preview\f[R] -Allows classes to depend on \f[B]preview features\f[R] -[https://docs.oracle.com/en/java/javase/12/language/index.html#JSLAN-GUID-5A82FE0E-0CA4-4F1F-B075-564874FE2823] -of the release. -.TP -\f[V]--enable-native-access\f[R] \f[I]module\f[R][\f[V],\f[R]\f[I]module\f[R]...] -Native access involves access to code or data outside the Java runtime. -This is generally unsafe and, if done incorrectly, might crash the JVM -or result in memory corruption. -Native access can occur as a result of calling a method that is either -\f[B]restricted\f[R] [https://openjdk.org/jeps/454#Safety], or -\f[V]native\f[R]. -This option allows code in the specified modules to perform native -access. -Native access occurring in a module that has not been explicitly enabled -is deemed \f[I]illegal\f[R]. -.RS -.PP -\f[I]module\f[R] can be a module name, or \f[V]ALL-UNNAMED\f[R] to -indicate code on the class path. -.RE -.TP --\f[V]--illegal-native-access=\f[R]\f[I]parameter\f[R] -This option specifies a mode for how illegal native access is handled: -.RS -.RS -.PP -\f[B]Note:\f[R] This option will be removed in a future release. -.RE -.IP \[bu] 2 -\f[V]allow\f[R]: This mode allows illegal native access in all modules, -without any warings. -.IP \[bu] 2 -\f[V]warn\f[R]: This mode is identical to \f[V]allow\f[R] except that a -warning message is issued for the first illegal native access found in a -module. -This mode is the default for the current JDK but will change in a future -release. -.IP \[bu] 2 -\f[V]deny\f[R]: This mode disables illegal native access. -That is, any illegal native access causes an -\f[V]IllegalCallerException\f[R]. -This mode will become the default in a future release. -.PP -To verify that your application is ready for a future version of the -JDK, run it with \f[V]--illegal-native-access=deny\f[R] along with any -necessary \f[V]--enable-native-access\f[R] options. -.RE -.TP -\f[V]--finalization=\f[R]\f[I]value\f[R] -Controls whether the JVM performs finalization of objects. -Valid values are \[dq]enabled\[dq] and \[dq]disabled\[dq]. -Finalization is enabled by default, so the value \[dq]enabled\[dq] does -nothing. -The value \[dq]disabled\[dq] disables finalization, so that no -finalizers are invoked. -.TP -\f[V]--module-path\f[R] \f[I]modulepath\f[R]... or \f[V]-p\f[R] \f[I]modulepath\f[R] -Specifies where to find application modules with a list of path -elements. -The elements of a module path can be a file path to a module or a -directory containing modules. -Each module is either a modular JAR or an exploded-module directory. -.RS -.PP -On Windows, semicolons (\f[V];\f[R]) separate path elements in this -list; on other platforms it is a colon (\f[V]:\f[R]). -.RE -.TP -\f[V]--upgrade-module-path\f[R] \f[I]modulepath\f[R]... -Specifies where to find module replacements of upgradeable modules in -the runtime image with a list of path elements. -The elements of a module path can be a file path to a module or a -directory containing modules. -Each module is either a modular JAR or an exploded-module directory. -.RS -.PP -On Windows, semicolons (\f[V];\f[R]) separate path elements in this -list; on other platforms it is a colon (\f[V]:\f[R]). -.RE -.TP -\f[V]--add-modules\f[R] \f[I]module\f[R][\f[V],\f[R]\f[I]module\f[R]...] -Specifies the root modules to resolve in addition to the initial module. -\f[I]module\f[R] can also be \f[V]ALL-DEFAULT\f[R], -\f[V]ALL-SYSTEM\f[R], and \f[V]ALL-MODULE-PATH\f[R]. -.TP -\f[V]--list-modules\f[R] -Lists the observable modules and then exits. -.TP -\f[V]-d\f[R] \f[I]module_name\f[R] or \f[V]--describe-module\f[R] \f[I]module_name\f[R] -Describes a specified module and then exits. -.TP -\f[V]--dry-run\f[R] -Creates the VM but doesn\[aq]t execute the main method. -This \f[V]--dry-run\f[R] option might be useful for validating the -command-line options such as the module system configuration. -.TP -\f[V]--validate-modules\f[R] -Validates all modules and exit. -This option is helpful for finding conflicts and other errors with -modules on the module path. -.TP -\f[V]-D\f[R]\f[I]property\f[R]\f[V]=\f[R]\f[I]value\f[R] -Sets a system property value. -The \f[I]property\f[R] variable is a string with no spaces that -represents the name of the property. -The \f[I]value\f[R] variable is a string that represents the value of -the property. -If \f[I]value\f[R] is a string with spaces, then enclose it in quotation -marks (for example \f[V]-Dfoo=\[dq]foo bar\[dq]\f[R]). -.TP -\f[V]-disableassertions\f[R][\f[V]:\f[R][\f[I]packagename\f[R]]...|\f[V]:\f[R]\f[I]classname\f[R]] or \f[V]-da\f[R][\f[V]:\f[R][\f[I]packagename\f[R]]...|\f[V]:\f[R]\f[I]classname\f[R]] -Disables assertions. -By default, assertions are disabled in all packages and classes. -With no arguments, \f[V]-disableassertions\f[R] (\f[V]-da\f[R]) disables -assertions in all packages and classes. -With the \f[I]packagename\f[R] argument ending in \f[V]...\f[R], the -switch disables assertions in the specified package and any subpackages. -If the argument is simply \f[V]...\f[R], then the switch disables -assertions in the unnamed package in the current working directory. -With the \f[I]classname\f[R] argument, the switch disables assertions in -the specified class. -.RS -.PP -The \f[V]-disableassertions\f[R] (\f[V]-da\f[R]) option applies to all -class loaders and to system classes (which don\[aq]t have a class -loader). -There\[aq]s one exception to this rule: If the option is provided with -no arguments, then it doesn\[aq]t apply to system classes. -This makes it easy to disable assertions in all classes except for -system classes. -The \f[V]-disablesystemassertions\f[R] option enables you to disable -assertions in all system classes. -To explicitly enable assertions in specific packages or classes, use the -\f[V]-enableassertions\f[R] (\f[V]-ea\f[R]) option. -Both options can be used at the same time. -For example, to run the \f[V]MyClass\f[R] application with assertions -enabled in the package \f[V]com.wombat.fruitbat\f[R] (and any -subpackages) but disabled in the class -\f[V]com.wombat.fruitbat.Brickbat\f[R], use the following command: -.RS -.PP -\f[V]java -ea:com.wombat.fruitbat... -da:com.wombat.fruitbat.Brickbat MyClass\f[R] -.RE -.RE -.TP -\f[V]-disablesystemassertions\f[R] or \f[V]-dsa\f[R] -Disables assertions in all system classes. -.TP -\f[V]-enableassertions\f[R][\f[V]:\f[R][\f[I]packagename\f[R]]...|\f[V]:\f[R]\f[I]classname\f[R]] or \f[V]-ea\f[R][\f[V]:\f[R][\f[I]packagename\f[R]]...|\f[V]:\f[R]\f[I]classname\f[R]] -Enables assertions. -By default, assertions are disabled in all packages and classes. -With no arguments, \f[V]-enableassertions\f[R] (\f[V]-ea\f[R]) enables -assertions in all packages and classes. -With the \f[I]packagename\f[R] argument ending in \f[V]...\f[R], the -switch enables assertions in the specified package and any subpackages. -If the argument is simply \f[V]...\f[R], then the switch enables -assertions in the unnamed package in the current working directory. -With the \f[I]classname\f[R] argument, the switch enables assertions in -the specified class. -.RS -.PP -The \f[V]-enableassertions\f[R] (\f[V]-ea\f[R]) option applies to all -class loaders and to system classes (which don\[aq]t have a class -loader). -There\[aq]s one exception to this rule: If the option is provided with -no arguments, then it doesn\[aq]t apply to system classes. -This makes it easy to enable assertions in all classes except for system -classes. -The \f[V]-enablesystemassertions\f[R] option provides a separate switch -to enable assertions in all system classes. -To explicitly disable assertions in specific packages or classes, use -the \f[V]-disableassertions\f[R] (\f[V]-da\f[R]) option. -If a single command contains multiple instances of these switches, then -they\[aq]re processed in order, before loading any classes. -For example, to run the \f[V]MyClass\f[R] application with assertions -enabled only in the package \f[V]com.wombat.fruitbat\f[R] (and any -subpackages) but disabled in the class -\f[V]com.wombat.fruitbat.Brickbat\f[R], use the following command: -.RS -.PP -\f[V]java -ea:com.wombat.fruitbat... -da:com.wombat.fruitbat.Brickbat MyClass\f[R] -.RE -.RE -.TP -\f[V]-enablesystemassertions\f[R] or \f[V]-esa\f[R] -Enables assertions in all system classes. -.TP -\f[V]-help\f[R], \f[V]-h\f[R], or \f[V]-?\f[R] -Prints the help message to the error stream. -.TP -\f[V]--help\f[R] -Prints the help message to the output stream. -.TP -\f[V]-javaagent:\f[R]\f[I]jarpath\f[R][\f[V]=\f[R]\f[I]options\f[R]] -Loads the specified Java programming language agent. -See \f[V]java.lang.instrument\f[R]. -.TP -\f[V]--show-version\f[R] -Prints the product version to the output stream and continues. -.TP -\f[V]-showversion\f[R] -Prints the product version to the error stream and continues. -.TP -\f[V]--show-module-resolution\f[R] -Shows module resolution output during startup. -.TP -\f[V]-splash:\f[R]\f[I]imagepath\f[R] -Shows the splash screen with the image specified by \f[I]imagepath\f[R]. -HiDPI scaled images are automatically supported and used if available. -The unscaled image file name, such as \f[V]image.ext\f[R], should always -be passed as the argument to the \f[V]-splash\f[R] option. -The most appropriate scaled image provided is picked up automatically. -.RS -.PP -For example, to show the \f[V]splash.gif\f[R] file from the -\f[V]images\f[R] directory when starting your application, use the -following option: -.RS -.PP -\f[V]-splash:images/splash.gif\f[R] -.RE -.PP -See the SplashScreen API documentation for more information. -.RE -.TP -\f[V]-verbose:class\f[R] -Displays information about each loaded class. -.TP -\f[V]-verbose:gc\f[R] -Displays information about each garbage collection (GC) event. -.TP -\f[V]-verbose:jni\f[R] -Displays information about the use of native methods and other Java -Native Interface (JNI) activity. -.TP -\f[V]-verbose:module\f[R] -Displays information about the modules in use. -.TP -\f[V]--version\f[R] -Prints product version to the output stream and exits. -.TP -\f[V]-version\f[R] -Prints product version to the error stream and exits. -.TP -\f[V]-X\f[R] -Prints the help on extra options to the error stream. -.TP -\f[V]--help-extra\f[R] -Prints the help on extra options to the output stream. -.TP -\f[V]\[at]\f[R]\f[I]argfile\f[R] -Specifies one or more argument files prefixed by \f[V]\[at]\f[R] used by -the \f[V]java\f[R] command. -It isn\[aq]t uncommon for the \f[V]java\f[R] command line to be very -long because of the \f[V].jar\f[R] files needed in the classpath. -The \f[V]\[at]\f[R]\f[I]argfile\f[R] option overcomes command-line -length limitations by enabling the launcher to expand the contents of -argument files after shell expansion, but before argument processing. -Contents in the argument files are expanded because otherwise, they -would be specified on the command line until the -\f[V]--disable-\[at]files\f[R] option was encountered. -.RS -.PP -The argument files can also contain the main class name and all options. -If an argument file contains all of the options required by the -\f[V]java\f[R] command, then the command line could simply be: -.RS -.PP -\f[V]java \[at]\f[R]\f[I]argfile\f[R] -.RE -.PP -See \f[B]java Command-Line Argument Files\f[R] for a description and -examples of using \f[V]\[at]\f[R]-argfiles. -.RE -.SH EXTRA OPTIONS FOR JAVA -.PP -The following \f[V]java\f[R] options are general purpose options that -are specific to the Java HotSpot Virtual Machine. -.TP -\f[V]-Xbatch\f[R] -Disables background compilation. -By default, the JVM compiles the method as a background task, running -the method in interpreter mode until the background compilation is -finished. -The \f[V]-Xbatch\f[R] flag disables background compilation so that -compilation of all methods proceeds as a foreground task until -completed. -This option is equivalent to \f[V]-XX:-BackgroundCompilation\f[R]. -.TP -\f[V]-Xbootclasspath/a:\f[R]\f[I]directories\f[R]|\f[I]zip\f[R]|\f[I]JAR-files\f[R] -Specifies a list of directories, JAR files, and ZIP archives to append -to the end of the default bootstrap class path. -.RS -.PP -On Windows, semicolons (\f[V];\f[R]) separate entities in this list; on -other platforms it is a colon (\f[V]:\f[R]). -.RE -.TP -\f[V]-Xcheck:jni\f[R] -Performs additional checks for Java Native Interface (JNI) functions. -.RS -.PP -The following checks are considered indicative of significant problems -with the native code, and the JVM terminates with an irrecoverable error -in such cases: -.IP \[bu] 2 -The thread doing the call is not attached to the JVM. -.IP \[bu] 2 -The thread doing the call is using the \f[V]JNIEnv\f[R] belonging to -another thread. -.IP \[bu] 2 -A parameter validation check fails: -.RS 2 -.IP \[bu] 2 -A \f[V]jfieldID\f[R], or \f[V]jmethodID\f[R], is detected as being -invalid. -For example: -.RS 2 -.IP \[bu] 2 -Of the wrong type -.IP \[bu] 2 -Associated with the wrong class -.RE -.IP \[bu] 2 -A parameter of the wrong type is detected. -.IP \[bu] 2 -An invalid parameter value is detected. -For example: -.RS 2 -.IP \[bu] 2 -NULL where not permitted -.IP \[bu] 2 -An out-of-bounds array index, or frame capacity -.IP \[bu] 2 -A non-UTF-8 string -.IP \[bu] 2 -An invalid JNI reference -.IP \[bu] 2 -An attempt to use a \f[V]ReleaseXXX\f[R] function on a parameter not -produced by the corresponding \f[V]GetXXX\f[R] function -.RE -.RE -.PP -The following checks only result in warnings being printed: -.IP \[bu] 2 -A JNI call was made without checking for a pending exception from a -previous JNI call, and the current call is not safe when an exception -may be pending. -.IP \[bu] 2 -A class descriptor is in decorated format (\f[V]Lname;\f[R]) when it -should not be. -.IP \[bu] 2 -A \f[V]NULL\f[R] parameter is allowed, but its use is questionable. -.IP \[bu] 2 -Calling other JNI functions in the scope of -\f[V]Get/ReleasePrimitiveArrayCritical\f[R] or -\f[V]Get/ReleaseStringCritical\f[R] -.PP -Expect a performance degradation when this option is used. -.RE -.TP -\f[V]-Xcomp\f[R] -Testing mode to exercise JIT compilers. -This option should not be used in production environments. -.TP -\f[V]-Xdebug\f[R] -Does nothing; deprecated for removal in a future release. -.TP -\f[V]-Xdiag\f[R] -Shows additional diagnostic messages. -.TP -\f[V]-Xint\f[R] -Runs the application in interpreted-only mode. -Compilation to native code is disabled, and all bytecode is executed by -the interpreter. -The performance benefits offered by the just-in-time (JIT) compiler -aren\[aq]t present in this mode. -.TP -\f[V]-Xinternalversion\f[R] -Displays more detailed JVM version information than the -\f[V]-version\f[R] option, and then exits. -.TP -\f[V]-Xlog:\f[R]\f[I]option\f[R] -Configure or enable logging with the Java Virtual Machine (JVM) unified -logging framework. -See \f[B]Enable Logging with the JVM Unified Logging Framework\f[R]. -.TP -\f[V]-Xmixed\f[R] -Executes all bytecode by the interpreter except for hot methods, which -are compiled to native code. -On by default. -Use \f[V]-Xint\f[R] to switch off. -.TP -\f[V]-Xmn\f[R] \f[I]size\f[R] -Sets the initial and maximum size (in bytes) of the heap for the young -generation (nursery) in the generational collectors. -Append the letter \f[V]k\f[R] or \f[V]K\f[R] to indicate kilobytes, -\f[V]m\f[R] or \f[V]M\f[R] to indicate megabytes, or \f[V]g\f[R] or -\f[V]G\f[R] to indicate gigabytes. -The young generation region of the heap is used for new objects. -GC is performed in this region more often than in other regions. -If the size for the young generation is too small, then a lot of minor -garbage collections are performed. -If the size is too large, then only full garbage collections are -performed, which can take a long time to complete. -It is recommended that you do not set the size for the young generation -for the G1 collector, and keep the size for the young generation greater -than 25% and less than 50% of the overall heap size for other -collectors. -The following examples show how to set the initial and maximum size of -young generation to 256 MB using various units: -.RS -.IP -.nf -\f[CB] --Xmn256m --Xmn262144k --Xmn268435456 -\f[R] -.fi -.PP -Instead of the \f[V]-Xmn\f[R] option to set both the initial and maximum -size of the heap for the young generation, you can use -\f[V]-XX:NewSize\f[R] to set the initial size and -\f[V]-XX:MaxNewSize\f[R] to set the maximum size. -.RE -.TP -\f[V]-Xms\f[R] \f[I]size\f[R] -Sets the minimum and the initial size (in bytes) of the heap. -This value must be a multiple of 1024 and greater than 1 MB. -Append the letter \f[V]k\f[R] or \f[V]K\f[R] to indicate kilobytes, -\f[V]m\f[R] or \f[V]M\f[R] to indicate megabytes, or \f[V]g\f[R] or -\f[V]G\f[R] to indicate gigabytes. -The following examples show how to set the size of allocated memory to 6 -MB using various units: -.RS -.IP -.nf -\f[CB] --Xms6291456 --Xms6144k --Xms6m -\f[R] -.fi -.PP -If you do not set this option, then the initial size will be set as the -sum of the sizes allocated for the old generation and the young -generation. -The initial size of the heap for the young generation can be set using -the \f[V]-Xmn\f[R] option or the \f[V]-XX:NewSize\f[R] option. -.PP -Note that the \f[V]-XX:InitialHeapSize\f[R] option can also be used to -set the initial heap size. -If it appears after \f[V]-Xms\f[R] on the command line, then the initial -heap size gets set to the value specified with -\f[V]-XX:InitialHeapSize\f[R]. -.RE -.TP -\f[V]-Xmx\f[R] \f[I]size\f[R] -Specifies the maximum size (in bytes) of the heap. -This value must be a multiple of 1024 and greater than 2 MB. -Append the letter \f[V]k\f[R] or \f[V]K\f[R] to indicate kilobytes, -\f[V]m\f[R] or \f[V]M\f[R] to indicate megabytes, or \f[V]g\f[R] or -\f[V]G\f[R] to indicate gigabytes. -The default value is chosen at runtime based on system configuration. -For server deployments, \f[V]-Xms\f[R] and \f[V]-Xmx\f[R] are often set -to the same value. -The following examples show how to set the maximum allowed size of -allocated memory to 80 MB using various units: -.RS -.IP -.nf -\f[CB] --Xmx83886080 --Xmx81920k --Xmx80m -\f[R] -.fi -.PP -The \f[V]-Xmx\f[R] option is equivalent to \f[V]-XX:MaxHeapSize\f[R]. -.RE -.TP -\f[V]-Xnoclassgc\f[R] -Disables garbage collection (GC) of classes. -This can save some GC time, which shortens interruptions during the -application run. -When you specify \f[V]-Xnoclassgc\f[R] at startup, the class objects in -the application are left untouched during GC and are always be -considered live. -This can result in more memory being permanently occupied which, if not -used carefully, throws an out-of-memory exception. -.TP -\f[V]-Xrs\f[R] -Reduces the use of operating system signals by the JVM. -Shutdown hooks enable the orderly shutdown of a Java application by -running user cleanup code (such as closing database connections) at -shutdown, even if the JVM terminates abruptly. -.RS -.IP \[bu] 2 -\f[B]Non-Windows:\f[R] -.RS 2 -.IP \[bu] 2 -The JVM catches signals to implement shutdown hooks for unexpected -termination. -The JVM uses \f[V]SIGHUP\f[R], \f[V]SIGINT\f[R], and \f[V]SIGTERM\f[R] -to initiate the running of shutdown hooks. -.IP \[bu] 2 -Applications embedding the JVM frequently need to trap signals such as -\f[V]SIGINT\f[R] or \f[V]SIGTERM\f[R], which can lead to interference -with the JVM signal handlers. -The \f[V]-Xrs\f[R] option is available to address this issue. -When \f[V]-Xrs\f[R] is used, the signal masks for \f[V]SIGINT\f[R], -\f[V]SIGTERM\f[R], \f[V]SIGHUP\f[R], and \f[V]SIGQUIT\f[R] aren\[aq]t -changed by the JVM, and signal handlers for these signals aren\[aq]t -installed. -.RE -.IP \[bu] 2 -\f[B]Windows:\f[R] -.RS 2 -.IP \[bu] 2 -The JVM watches for console control events to implement shutdown hooks -for unexpected termination. -Specifically, the JVM registers a console control handler that begins -shutdown-hook processing and returns \f[V]TRUE\f[R] for -\f[V]CTRL_C_EVENT\f[R], \f[V]CTRL_CLOSE_EVENT\f[R], -\f[V]CTRL_LOGOFF_EVENT\f[R], and \f[V]CTRL_SHUTDOWN_EVENT\f[R]. -.IP \[bu] 2 -The JVM uses a similar mechanism to implement the feature of dumping -thread stacks for debugging purposes. -The JVM uses \f[V]CTRL_BREAK_EVENT\f[R] to perform thread dumps. -.IP \[bu] 2 -If the JVM is run as a service (for example, as a servlet engine for a -web server), then it can receive \f[V]CTRL_LOGOFF_EVENT\f[R] but -shouldn\[aq]t initiate shutdown because the operating system doesn\[aq]t -actually terminate the process. -To avoid possible interference such as this, the \f[V]-Xrs\f[R] option -can be used. -When the \f[V]-Xrs\f[R] option is used, the JVM doesn\[aq]t install a -console control handler, implying that it doesn\[aq]t watch for or -process \f[V]CTRL_C_EVENT\f[R], \f[V]CTRL_CLOSE_EVENT\f[R], -\f[V]CTRL_LOGOFF_EVENT\f[R], or \f[V]CTRL_SHUTDOWN_EVENT\f[R]. -.RE -.PP -There are two consequences of specifying \f[V]-Xrs\f[R]: -.IP \[bu] 2 -\f[B]Non-Windows:\f[R] \f[V]SIGQUIT\f[R] thread dumps aren\[aq]t -available. -.IP \[bu] 2 -\f[B]Windows:\f[R] Ctrl + Break thread dumps aren\[aq]t available. -.PP -User code is responsible for causing shutdown hooks to run, for example, -by calling \f[V]System.exit()\f[R] when the JVM is to be terminated. -.RE -.TP -\f[V]-Xshare:\f[R]\f[I]mode\f[R] -Sets the class data sharing (CDS) mode. -.RS -.PP -Possible \f[I]mode\f[R] arguments for this option include the following: -.TP -\f[V]auto\f[R] -Use shared class data if possible (default). -.TP -\f[V]on\f[R] -Require using shared class data, otherwise fail. -.RS -.PP -\f[B]Note:\f[R] The \f[V]-Xshare:on\f[R] option is used for testing -purposes only. -It may cause the VM to unexpectedly exit during start-up when the CDS -archive cannot be used (for example, when certain VM parameters are -changed, or when a different JDK is used). -This option should not be used in production environments. -.RE -.TP -\f[V]off\f[R] -Do not attempt to use shared class data. -.RE -.TP -\f[V]-XshowSettings\f[R] -Shows all settings and then continues. -.TP -\f[V]-XshowSettings:\f[R]\f[I]category\f[R] -Shows settings and continues. -Possible \f[I]category\f[R] arguments for this option include the -following: -.RS -.TP -\f[V]all\f[R] -Shows all categories of settings in \f[B]verbose\f[R] detail. -.TP -\f[V]locale\f[R] -Shows settings related to locale. -.TP -\f[V]properties\f[R] -Shows settings related to system properties. -.TP -\f[V]security\f[R] -Shows all settings related to security. -.RS -.PP -sub-category arguments for \f[V]security\f[R] include the following: -.IP \[bu] 2 -\f[V]security:all\f[R] : shows all security settings -.IP \[bu] 2 -\f[V]security:properties\f[R] : shows security properties -.IP \[bu] 2 -\f[V]security:providers\f[R] : shows static security provider settings -.IP \[bu] 2 -\f[V]security:tls\f[R] : shows TLS related security settings -.RE -.TP -\f[V]vm\f[R] -Shows the settings of the JVM. -.TP -\f[V]system\f[R] -\f[B]Linux only:\f[R] Shows host system or container configuration and -continues. -.RE -.TP -\f[V]-Xss\f[R] \f[I]size\f[R] -Sets the thread stack size (in bytes). -Append the letter \f[V]k\f[R] or \f[V]K\f[R] to indicate KB, \f[V]m\f[R] -or \f[V]M\f[R] to indicate MB, or \f[V]g\f[R] or \f[V]G\f[R] to indicate -GB. -The actual size may be rounded up to a multiple of the system page size -as required by the operating system. -The default value depends on the platform. -For example: -.RS -.IP \[bu] 2 -Linux/x64: 1024 KB -.IP \[bu] 2 -Linux/Aarch64: 2048 KB -.IP \[bu] 2 -macOS/x64: 1024 KB -.IP \[bu] 2 -macOS/Aarch64: 2048 KB -.IP \[bu] 2 -Windows: The default value depends on virtual memory -.PP -The following examples set the thread stack size to 1024 KB in different -units: -.IP -.nf -\f[CB] --Xss1m --Xss1024k --Xss1048576 -\f[R] -.fi -.PP -This option is similar to \f[V]-XX:ThreadStackSize\f[R]. -.RE -.TP -\f[V]--add-reads\f[R] \f[I]module\f[R]\f[V]=\f[R]\f[I]target-module\f[R](\f[V],\f[R]\f[I]target-module\f[R])* -Updates \f[I]module\f[R] to read the \f[I]target-module\f[R], regardless -of the module declaration. -\f[I]target-module\f[R] can be \f[V]ALL-UNNAMED\f[R] to read all unnamed -modules. -.TP -\f[V]--add-exports\f[R] \f[I]module\f[R]\f[V]/\f[R]\f[I]package\f[R]\f[V]=\f[R]\f[I]target-module\f[R](\f[V],\f[R]\f[I]target-module\f[R])* -Updates \f[I]module\f[R] to export \f[I]package\f[R] to -\f[I]target-module\f[R], regardless of module declaration. -\f[I]target-module\f[R] can be \f[V]ALL-UNNAMED\f[R] to export to all -unnamed modules. -.TP -\f[V]--add-opens\f[R] \f[I]module\f[R]\f[V]/\f[R]\f[I]package\f[R]\f[V]=\f[R]\f[I]target-module\f[R](\f[V],\f[R]\f[I]target-module\f[R])* -Updates \f[I]module\f[R] to open \f[I]package\f[R] to -\f[I]target-module\f[R], regardless of module declaration. -.TP -\f[V]--limit-modules\f[R] \f[I]module\f[R][\f[V],\f[R]\f[I]module\f[R]...] -Specifies the limit of the universe of observable modules. -.TP -\f[V]--patch-module\f[R] \f[I]module\f[R]\f[V]=\f[R]\f[I]file\f[R](\f[V];\f[R]\f[I]file\f[R])* -Overrides or augments a module with classes and resources in JAR files -or directories. -.TP -\f[V]--source\f[R] \f[I]version\f[R] -Sets the version of the source in source-file mode. -.TP -\f[V]--sun-misc-unsafe-memory-access=\f[R] \f[I]value\f[R] -Allow or deny usage of unsupported API \f[V]sun.misc.Unsafe\f[R]. -\f[I]value\f[R] is one of: -.RS -.TP -\f[V]allow\f[R] -Allow use of the memory-access methods with no warnings at run time. -.TP -\f[V]warn\f[R] -Allow use of the memory-access methods, but issues a warning on the -first occasion that any memory-access method is used. -At most one warning is issued. -.TP -\f[V]debug\f[R] -Allow use of the memory-access methods, but issue a one-line warning and -a stack trace when any memory-access method is used. -.TP -\f[V]deny\f[R] -Disallow use of the memory-access methods by throwing an -\f[V]UnsupportedOperationException\f[R] on every usage. -.PP -The default value when the option is not specified is \f[V]allow\f[R]. -.RE -.SH EXTRA OPTIONS FOR MACOS -.PP -The following extra options are macOS specific. -.TP -\f[V]-XstartOnFirstThread\f[R] -Runs the \f[V]main()\f[R] method on the first (AppKit) thread. -.TP -\f[V]-Xdock:name=\f[R]\f[I]application_name\f[R] -Overrides the default application name displayed in dock. -.TP -\f[V]-Xdock:icon=\f[R]\f[I]path_to_icon_file\f[R] -Overrides the default icon displayed in dock. -.SH ADVANCED OPTIONS FOR JAVA -.PP -These \f[V]java\f[R] options can be used to enable other advanced -options. -.TP -\f[V]-XX:+UnlockDiagnosticVMOptions\f[R] -Unlocks the options intended for diagnosing the JVM. -By default, this option is disabled and diagnostic options aren\[aq]t -available. -.RS -.PP -Command line options that are enabled with the use of this option are -not supported. -If you encounter issues while using any of these options, it is very -likely that you will be required to reproduce the problem without using -any of these unsupported options before Oracle Support can assist with -an investigation. -It is also possible that any of these options may be removed or their -behavior changed without any warning. -.RE -.TP -\f[V]-XX:+UnlockExperimentalVMOptions\f[R] -Unlocks the options that provide experimental features in the JVM. -By default, this option is disabled and experimental features aren\[aq]t -available. -.SH ADVANCED RUNTIME OPTIONS FOR JAVA -.PP -These \f[V]java\f[R] options control the runtime behavior of the Java -HotSpot VM. -.TP -\f[V]-XX:ActiveProcessorCount=\f[R]\f[I]x\f[R] -Overrides the number of CPUs that the VM will use to calculate the size -of thread pools it will use for various operations such as Garbage -Collection and ForkJoinPool. -.RS -.PP -The VM normally determines the number of available processors from the -operating system. -This flag can be useful for partitioning CPU resources when running -multiple Java processes in docker containers. -This flag is honored even if \f[V]UseContainerSupport\f[R] is not -enabled. -See \f[V]-XX:-UseContainerSupport\f[R] for a description of enabling and -disabling container support. -.RE -.TP -\f[V]-XX:AllocateHeapAt=\f[R]\f[I]path\f[R] -Takes a path to the file system and uses memory mapping to allocate the -object heap on the memory device. -Using this option enables the HotSpot VM to allocate the Java object -heap on an alternative memory device, such as an NV-DIMM, specified by -the user. -.RS -.PP -Alternative memory devices that have the same semantics as DRAM, -including the semantics of atomic operations, can be used instead of -DRAM for the object heap without changing the existing application code. -All other memory structures (such as the code heap, metaspace, and -thread stacks) continue to reside in DRAM. -.PP -Some operating systems expose non-DRAM memory through the file system. -Memory-mapped files in these file systems bypass the page cache and -provide a direct mapping of virtual memory to the physical memory on the -device. -The existing heap related flags (such as \f[V]-Xmx\f[R] and -\f[V]-Xms\f[R]) and garbage-collection related flags continue to work as -before. -.RE -.TP -\f[V]-XX:-CompactStrings\f[R] -Disables the Compact Strings feature. -By default, this option is enabled. -When this option is enabled, Java Strings containing only single-byte -characters are internally represented and stored as -single-byte-per-character Strings using ISO-8859-1 / Latin-1 encoding. -This reduces, by 50%, the amount of space required for Strings -containing only single-byte characters. -For Java Strings containing at least one multibyte character: these are -represented and stored as 2 bytes per character using UTF-16 encoding. -Disabling the Compact Strings feature forces the use of UTF-16 encoding -as the internal representation for all Java Strings. -.RS -.PP -Cases where it may be beneficial to disable Compact Strings include the -following: -.IP \[bu] 2 -When it\[aq]s known that an application overwhelmingly will be -allocating multibyte character Strings -.IP \[bu] 2 -In the unexpected event where a performance regression is observed in -migrating from Java SE 8 to Java SE 9 and an analysis shows that Compact -Strings introduces the regression -.PP -In both of these scenarios, disabling Compact Strings makes sense. -.RE -.TP -\f[V]-XX:ErrorFile=\f[R]\f[I]filename\f[R] -Specifies the path and file name to which error data is written when an -irrecoverable error occurs. -By default, this file is created in the current working directory and -named \f[V]hs_err_pid\f[R]\f[I]pid\f[R]\f[V].log\f[R] where -\f[I]pid\f[R] is the identifier of the process that encountered the -error. -.RS -.PP -The following example shows how to set the default log file (note that -the identifier of the process is specified as \f[V]%p\f[R]): -.RS -.PP -\f[V]-XX:ErrorFile=./hs_err_pid%p.log\f[R] -.RE -.IP \[bu] 2 -\f[B]Non-Windows:\f[R] The following example shows how to set the error -log to \f[V]/var/log/java/java_error.log\f[R]: -.RS 2 -.RS -.PP -\f[V]-XX:ErrorFile=/var/log/java/java_error.log\f[R] -.RE -.RE -.IP \[bu] 2 -\f[B]Windows:\f[R] The following example shows how to set the error log -file to \f[V]C:/log/java/java_error.log\f[R]: -.RS 2 -.RS -.PP -\f[V]-XX:ErrorFile=C:/log/java/java_error.log\f[R] -.RE -.RE -.PP -If the file exists, and is writeable, then it will be overwritten. -Otherwise, if the file can\[aq]t be created in the specified directory -(due to insufficient space, permission problem, or another issue), then -the file is created in the temporary directory for the operating system: -.IP \[bu] 2 -\f[B]Non-Windows:\f[R] The temporary directory is \f[V]/tmp\f[R]. -.IP \[bu] 2 -\f[B]Windows:\f[R] The temporary directory is specified by the value of -the \f[V]TMP\f[R] environment variable; if that environment variable -isn\[aq]t defined, then the value of the \f[V]TEMP\f[R] environment -variable is used. -.RE -.TP -\f[V]-XX:+ExtensiveErrorReports\f[R] -Enables the reporting of more extensive error information in the -\f[V]ErrorFile\f[R]. -This option can be turned on in environments where maximal information -is desired - even if the resulting logs may be quite large and/or -contain information that might be considered sensitive. -The information can vary from release to release, and across different -platforms. -By default this option is disabled. -.TP -\f[V]-XX:FlightRecorderOptions=\f[R]\f[I]parameter\f[R]\f[V]=\f[R]\f[I]value\f[R] (or) \f[V]-XX:FlightRecorderOptions:\f[R]\f[I]parameter\f[R]\f[V]=\f[R]\f[I]value\f[R] -Sets the parameters that control the behavior of JFR. -Multiple parameters can be specified by separating them with a comma. -.RS -.PP -The following list contains the available JFR -\f[I]parameter\f[R]\f[V]=\f[R]\f[I]value\f[R] entries: -.TP -\f[V]globalbuffersize=\f[R]\f[I]size\f[R] -Specifies the total amount of primary memory used for data retention. -The default value is based on the value specified for -\f[V]memorysize\f[R]. -Change the \f[V]memorysize\f[R] parameter to alter the size of global -buffers. -.TP -\f[V]maxchunksize=\f[R]\f[I]size\f[R] -Specifies the maximum size (in bytes) of the data chunks in a recording. -Append \f[V]m\f[R] or \f[V]M\f[R] to specify the size in megabytes (MB), -or \f[V]g\f[R] or \f[V]G\f[R] to specify the size in gigabytes (GB). -By default, the maximum size of data chunks is set to 12 MB. -The minimum allowed is 1 MB. -.TP -\f[V]memorysize=\f[R]\f[I]size\f[R] -Determines how much buffer memory should be used, and sets the -\f[V]globalbuffersize\f[R] and \f[V]numglobalbuffers\f[R] parameters -based on the size specified. -Append \f[V]m\f[R] or \f[V]M\f[R] to specify the size in megabytes (MB), -or \f[V]g\f[R] or \f[V]G\f[R] to specify the size in gigabytes (GB). -By default, the memory size is set to 10 MB. -.TP -\f[V]numglobalbuffers\f[R] -Specifies the number of global buffers used. -The default value is based on the memory size specified. -Change the \f[V]memorysize\f[R] parameter to alter the number of global -buffers. -.TP -\f[V]old-object-queue-size=number-of-objects\f[R] -Maximum number of old objects to track. -By default, the number of objects is set to 256. -.TP -\f[V]preserve-repository=\f[R]{\f[V]true\f[R]|\f[V]false\f[R]} -Specifies whether files stored in the disk repository should be kept -after the JVM has exited. -If false, files are deleted. -By default, this parameter is disabled. -.TP -\f[V]repository=\f[R]\f[I]path\f[R] -Specifies the repository (a directory) for temporary disk storage. -By default, the system\[aq]s temporary directory is used. -.TP -\f[V]retransform=\f[R]{\f[V]true\f[R]|\f[V]false\f[R]} -Specifies whether event classes should be retransformed using JVMTI. -If false, instrumentation is added when event classes are loaded. -By default, this parameter is enabled. -.TP -\f[V]stackdepth=\f[R]\f[I]depth\f[R] -Stack depth for stack traces. -By default, the depth is set to 64 method calls. -The maximum is 2048. -Values greater than 64 could create significant overhead and reduce -performance. -.TP -\f[V]threadbuffersize=\f[R]\f[I]size\f[R] -Specifies the per-thread local buffer size (in bytes). -By default, the local buffer size is set to 8 kilobytes, with a minimum -value of 4 kilobytes. -Overriding this parameter could reduce performance and is not -recommended. -.RE -.TP -\f[V]-XX:LargePageSizeInBytes=\f[R]\f[I]size\f[R] -Sets the maximum large page size (in bytes) used by the JVM. -The \f[I]size\f[R] argument must be a valid page size supported by the -environment to have any effect. -Append the letter \f[V]k\f[R] or \f[V]K\f[R] to indicate kilobytes, -\f[V]m\f[R] or \f[V]M\f[R] to indicate megabytes, or \f[V]g\f[R] or -\f[V]G\f[R] to indicate gigabytes. -By default, the size is set to 0, meaning that the JVM will use the -default large page size for the environment as the maximum size for -large pages. -See \f[B]Large Pages\f[R]. -.RS -.PP -The following example describes how to set the large page size to 1 -gigabyte (GB): -.RS -.PP -\f[V]-XX:LargePageSizeInBytes=1g\f[R] -.RE -.RE -.TP -\f[V]-XX:MaxDirectMemorySize=\f[R]\f[I]size\f[R] -Sets the maximum total size (in bytes) of the \f[V]java.nio\f[R] -package, direct-buffer allocations. -Append the letter \f[V]k\f[R] or \f[V]K\f[R] to indicate kilobytes, -\f[V]m\f[R] or \f[V]M\f[R] to indicate megabytes, or \f[V]g\f[R] or -\f[V]G\f[R] to indicate gigabytes. -If not set, the flag is ignored and the JVM chooses the size for NIO -direct-buffer allocations automatically. -.RS -.PP -The following examples illustrate how to set the NIO size to 1024 KB in -different units: -.IP -.nf -\f[CB] --XX:MaxDirectMemorySize=1m --XX:MaxDirectMemorySize=1024k --XX:MaxDirectMemorySize=1048576 -\f[R] -.fi -.RE -.TP -\f[V]-XX:-MaxFDLimit\f[R] -Disables the attempt to set the soft limit for the number of open file -descriptors to the hard limit. -By default, this option is enabled on all platforms, but is ignored on -Windows. -The only time that you may need to disable this is on macOS, where its -use imposes a maximum of 10240, which is lower than the actual system -maximum. -.TP -\f[V]-XX:NativeMemoryTracking=\f[R]\f[I]mode\f[R] -Specifies the mode for tracking JVM native memory usage. -Possible \f[I]mode\f[R] arguments for this option include the following: -.RS -.TP -\f[V]off\f[R] -Instructs not to track JVM native memory usage. -This is the default behavior if you don\[aq]t specify the -\f[V]-XX:NativeMemoryTracking\f[R] option. -.TP -\f[V]summary\f[R] -Tracks memory usage only by JVM subsystems, such as Java heap, class, -code, and thread. -.TP -\f[V]detail\f[R] -In addition to tracking memory usage by JVM subsystems, track memory -usage by individual \f[V]CallSite\f[R], individual virtual memory region -and its committed regions. -.RE -.TP -\f[V]-XX:TrimNativeHeapInterval=\f[R]\f[I]millis\f[R] -Interval, in ms, at which the JVM will trim the native heap. -Lower values will reclaim memory more eagerly at the cost of higher -overhead. -A value of 0 (default) disables native heap trimming. -Native heap trimming is performed in a dedicated thread. -.RS -.PP -This option is only supported on Linux with GNU C Library (glibc). -.RE -.TP -\f[V]-XX:+NeverActAsServerClassMachine\f[R] -Enable the \[dq]Client VM emulation\[dq] mode which only uses the C1 JIT -compiler, a 32Mb CodeCache and the Serial GC. -The maximum amount of memory that the JVM may use (controlled by the -\f[V]-XX:MaxRAM=n\f[R] flag) is set to 1GB by default. -The string \[dq]emulated-client\[dq] is added to the JVM version string. -.RS -.PP -By default the flag is set to \f[V]true\f[R] only on Windows in 32-bit -mode and \f[V]false\f[R] in all other cases. -.PP -The \[dq]Client VM emulation\[dq] mode will not be enabled if any of the -following flags are used on the command line: -.IP -.nf -\f[CB] --XX:{+|-}TieredCompilation --XX:CompilationMode=mode --XX:TieredStopAtLevel=n --XX:{+|-}EnableJVMCI --XX:{+|-}UseJVMCICompiler -\f[R] -.fi -.RE -.TP -\f[V]-XX:ObjectAlignmentInBytes=\f[R]\f[I]alignment\f[R] -Sets the memory alignment of Java objects (in bytes). -By default, the value is set to 8 bytes. -The specified value should be a power of 2, and must be within the range -of 8 and 256 (inclusive). -This option makes it possible to use compressed pointers with large Java -heap sizes. -.RS -.PP -The heap size limit in bytes is calculated as: -.RS -.PP -\f[V]4GB * ObjectAlignmentInBytes\f[R] -.RE -.RS -.PP -\f[B]Note:\f[R] As the alignment value increases, the unused space -between objects also increases. -As a result, you may not realize any benefits from using compressed -pointers with large Java heap sizes. -.RE -.RE -.TP -\f[V]-XX:OnError=\f[R]\f[I]string\f[R] -Sets a custom command or a series of semicolon-separated commands to run -when an irrecoverable error occurs. -If the string contains spaces, then it must be enclosed in quotation -marks. -.RS -.IP \[bu] 2 -\f[B]Non-Windows:\f[R] The following example shows how the -\f[V]-XX:OnError\f[R] option can be used to run the \f[V]gcore\f[R] -command to create a core image, and start the \f[V]gdb\f[R] debugger to -attach to the process in case of an irrecoverable error (the -\f[V]%p\f[R] designates the current process identifier): -.RS 2 -.RS -.PP -\f[V]-XX:OnError=\[dq]gcore %p;gdb -p %p\[dq]\f[R] -.RE -.RE -.IP \[bu] 2 -\f[B]Windows:\f[R] The following example shows how the -\f[V]-XX:OnError\f[R] option can be used to run the -\f[V]userdump.exe\f[R] utility to obtain a crash dump in case of an -irrecoverable error (the \f[V]%p\f[R] designates the current process -identifier). -This example assumes that the path to the \f[V]userdump.exe\f[R] utility -is specified in the \f[V]PATH\f[R] environment variable: -.RS 2 -.RS -.PP -\f[V]-XX:OnError=\[dq]userdump.exe %p\[dq]\f[R] -.RE -.RE -.RE -.TP -\f[V]-XX:OnOutOfMemoryError=\f[R]\f[I]string\f[R] -Sets a custom command or a series of semicolon-separated commands to run -when an \f[V]OutOfMemoryError\f[R] exception is first thrown. -If the string contains spaces, then it must be enclosed in quotation -marks. -For an example of a command string, see the description of the -\f[V]-XX:OnError\f[R] option. -.TP -\f[V]-XX:+PrintCommandLineFlags\f[R] -Enables printing of ergonomically selected JVM flags that appeared on -the command line. -It can be useful to know the ergonomic values set by the JVM, such as -the heap space size and the selected garbage collector. -By default, this option is disabled and flags aren\[aq]t printed. -.TP -\f[V]-XX:+PreserveFramePointer\f[R] -Selects between using the RBP register as a general purpose register -(\f[V]-XX:-PreserveFramePointer\f[R]) and using the RBP register to hold -the frame pointer of the currently executing method -(\f[V]-XX:+PreserveFramePointer\f[R] . -If the frame pointer is available, then external profiling tools (for -example, Linux perf) can construct more accurate stack traces. -.TP -\f[V]-XX:+PrintNMTStatistics\f[R] -Enables printing of collected native memory tracking data at JVM exit -when native memory tracking is enabled (see -\f[V]-XX:NativeMemoryTracking\f[R]). -By default, this option is disabled and native memory tracking data -isn\[aq]t printed. -.TP -\f[V]-XX:SharedArchiveFile=\f[R]\f[I]path\f[R] -Specifies the path and name of the class data sharing (CDS) archive file -.RS -.PP -See \f[B]Application Class Data Sharing\f[R]. -.RE -.TP -\f[V]-XX:+VerifySharedSpaces\f[R] -If this option is specified, the JVM will load a CDS archive file only -if it passes an integrity check based on CRC32 checksums. -The purpose of this flag is to check for unintentional damage to CDS -archive files in transmission or storage. -To guarantee the security and proper operation of CDS, the user must -ensure that the CDS archive files used by Java applications cannot be -modified without proper authorization. -.TP -\f[V]-XX:SharedArchiveConfigFile=\f[R]\f[I]shared_config_file\f[R] -Specifies additional shared data added to the archive file. -.TP -\f[V]-XX:SharedClassListFile=\f[R]\f[I]file_name\f[R] -Specifies the text file that contains the names of the classes to store -in the class data sharing (CDS) archive. -This file contains the full name of one class per line, except slashes -(\f[V]/\f[R]) replace dots (\f[V].\f[R]). -For example, to specify the classes \f[V]java.lang.Object\f[R] and -\f[V]hello.Main\f[R], create a text file that contains the following two -lines: -.RS -.IP -.nf -\f[CB] -java/lang/Object -hello/Main -\f[R] -.fi -.PP -The classes that you specify in this text file should include the -classes that are commonly used by the application. -They may include any classes from the application, extension, or -bootstrap class paths. -.PP -See \f[B]Application Class Data Sharing\f[R]. -.RE -.TP -\f[V]-XX:+ShowCodeDetailsInExceptionMessages\f[R] -Enables printing of improved \f[V]NullPointerException\f[R] messages. -When an application throws a \f[V]NullPointerException\f[R], the option -enables the JVM to analyze the program\[aq]s bytecode instructions to -determine precisely which reference is \f[V]null\f[R], and describes the -source with a null-detail message. -The null-detail message is calculated and returned by -\f[V]NullPointerException.getMessage()\f[R], and will be printed as the -exception message along with the method, filename, and line number. -By default, this option is enabled. -.TP -\f[V]-XX:+ShowMessageBoxOnError\f[R] -Enables the display of a dialog box when the JVM experiences an -irrecoverable error. -This prevents the JVM from exiting and keeps the process active so that -you can attach a debugger to it to investigate the cause of the error. -By default, this option is disabled. -.TP -\f[V]-XX:StartFlightRecording:\f[R]\f[I]parameter\f[R]\f[V]=\f[R]\f[I]value\f[R] -Starts a JFR recording for the Java application. -This option is equivalent to the \f[V]JFR.start\f[R] diagnostic command -that starts a recording during runtime. -\f[V]-XX:StartFlightRecording:help\f[R] prints available options and -example command lines. -You can set the following \f[I]parameter\f[R]\f[V]=\f[R]\f[I]value\f[R] -entries when starting a JFR recording: -.RS -.TP -\f[V]delay=\f[R]\f[I]time\f[R] -Specifies the delay between the Java application launch time and the -start of the recording. -Append \f[V]s\f[R] to specify the time in seconds, \f[V]m\f[R] for -minutes, \f[V]h\f[R] for hours, or \f[V]d\f[R] for days (for example, -specifying \f[V]10m\f[R] means 10 minutes). -By default, there\[aq]s no delay, and this parameter is set to 0. -.TP -\f[V]disk=\f[R]{\f[V]true\f[R]|\f[V]false\f[R]} -Specifies whether to write data to disk while recording. -By default, this parameter is enabled. -.TP -\f[V]dumponexit=\f[R]{\f[V]true\f[R]|\f[V]false\f[R]} -Specifies if the running recording is dumped when the JVM shuts down. -If enabled and a \f[V]filename\f[R] is not entered, the recording is -written to a file in the directory where the process was started. -The file name is a system-generated name that contains the process ID, -recording ID, and current timestamp, similar to -\f[V]hotspot-pid-47496-id-1-2018_01_25_19_10_41.jfr\f[R]. -By default, this parameter is disabled. -.TP -\f[V]duration=\f[R]\f[I]time\f[R] -Specifies the duration of the recording. -Append \f[V]s\f[R] to specify the time in seconds, \f[V]m\f[R] for -minutes, \f[V]h\f[R] for hours, or \f[V]d\f[R] for days (for example, -specifying \f[V]5h\f[R] means 5 hours). -By default, the duration isn\[aq]t limited, and this parameter is set to -0. -.TP -\f[V]filename=\f[R]\f[I]path\f[R] -Specifies the path and name of the file to which the recording is -written when the recording is stopped, for example: -.RS -.IP \[bu] 2 -\f[V]recording.jfr\f[R] -.IP \[bu] 2 -\f[V]/home/user/recordings/recording.jfr\f[R] -.IP \[bu] 2 -\f[V]c:\[rs]recordings\[rs]recording.jfr\f[R] -.PP -If %p and/or %t is specified in the filename, it expands to the -JVM\[aq]s PID and the current timestamp, respectively. -The filename may also be a directory in which case, the filename is -generated from the PID and the current date in the specified directory. -.RE -.TP -\f[V]name=\f[R]\f[I]identifier\f[R] -Takes both the name and the identifier of a recording. -.TP -\f[V]maxage=\f[R]\f[I]time\f[R] -Specifies the maximum age of disk data to keep for the recording. -This parameter is valid only when the \f[V]disk\f[R] parameter is set to -\f[V]true\f[R]. -Append \f[V]s\f[R] to specify the time in seconds, \f[V]m\f[R] for -minutes, \f[V]h\f[R] for hours, or \f[V]d\f[R] for days (for example, -specifying \f[V]30s\f[R] means 30 seconds). -By default, the maximum age isn\[aq]t limited, and this parameter is set -to \f[V]0s\f[R]. -.TP -\f[V]maxsize=\f[R]\f[I]size\f[R] -Specifies the maximum size (in bytes) of disk data to keep for the -recording. -This parameter is valid only when the \f[V]disk\f[R] parameter is set to -\f[V]true\f[R]. -The value must not be less than the value for the \f[V]maxchunksize\f[R] -parameter set with \f[V]-XX:FlightRecorderOptions\f[R]. -Append \f[V]m\f[R] or \f[V]M\f[R] to specify the size in megabytes, or -\f[V]g\f[R] or \f[V]G\f[R] to specify the size in gigabytes. -By default, the maximum size of disk data isn\[aq]t limited, and this -parameter is set to \f[V]0\f[R]. -.TP -\f[V]path-to-gc-roots=\f[R]{\f[V]true\f[R]|\f[V]false\f[R]} -Specifies whether to collect the path to garbage collection (GC) roots -at the end of a recording. -By default, this parameter is disabled. -.RS -.PP -The path to GC roots is useful for finding memory leaks, but collecting -it is time-consuming. -Enable this option only when you start a recording for an application -that you suspect has a memory leak. -If the \f[V]settings\f[R] parameter is set to \f[V]profile\f[R], the -stack trace from where the potential leaking object was allocated is -included in the information collected. -.RE -.TP -\f[V]settings=\f[R]\f[I]path\f[R] -Specifies the path and name of the event settings file (of type JFC). -By default, the \f[V]default.jfc\f[R] file is used, which is located in -\f[V]JAVA_HOME/lib/jfr\f[R]. -This default settings file collects a predefined set of information with -low overhead, so it has minimal impact on performance and can be used -with recordings that run continuously. -.RS -.PP -A second settings file is also provided, profile.jfc, which provides -more data than the default configuration, but can have more overhead and -impact performance. -Use this configuration for short periods of time when more information -is needed. -.RE -.PP -You can specify values for multiple parameters by separating them with a -comma. -Event settings and .jfc options can be specified using the following -syntax: -.TP -\f[V]option=\f[R]\f[I]value\f[R] -Specifies the option value to modify. -To list available options, use the \f[V]JAVA_HOME\f[R]/bin/jfr tool. -.TP -\f[V]event-setting=\f[R]\f[I]value\f[R] -Specifies the event setting value to modify. -Use the form: \f[V]#=\f[R]. -To add a new event setting, prefix the event name with \[aq]+\[aq]. -.PP -You can specify values for multiple event settings and .jfc options by -separating them with a comma. -In case of a conflict between a parameter and a .jfc option, the -parameter will take precedence. -The whitespace delimiter can be omitted for timespan values, i.e. -20ms. -For more information about the settings syntax, see Javadoc of the -jdk.jfr package. -.PP -To only see warnings and errors from JFR during startup set --Xlog:jfr+startup=warning. -.RE -.TP -\f[V]-XX:ThreadStackSize=\f[R]\f[I]size\f[R] -Sets the Java thread stack size (in kilobytes). -Use of a scaling suffix, such as \f[V]k\f[R], results in the scaling of -the kilobytes value so that \f[V]-XX:ThreadStackSize=1k\f[R] sets the -Java thread stack size to 1024*1024 bytes or 1 megabyte. -The default value depends on the platform. -For example: -.RS -.IP \[bu] 2 -Linux/x64: 1024 KB -.IP \[bu] 2 -Linux/Aarch64: 2048 KB -.IP \[bu] 2 -macOS/x64: 1024 KB -.IP \[bu] 2 -macOS/Aarch64: 2048 KB -.IP \[bu] 2 -Windows: The default value depends on virtual memory -.PP -The following examples show how to set the thread stack size to 1 -megabyte in different units: -.IP -.nf -\f[CB] --XX:ThreadStackSize=1k --XX:ThreadStackSize=1024 -\f[R] -.fi -.PP -This option is similar to \f[V]-Xss\f[R]. -.RE -.TP -\f[V]-XX:-UseCompressedOops\f[R] -Disables the use of compressed pointers. -By default, this option is enabled, and compressed pointers are used. -This will automatically limit the maximum ergonomically determined Java -heap size to the maximum amount of memory that can be covered by -compressed pointers. -By default this range is 32 GB. -.RS -.PP -With compressed oops enabled, object references are represented as -32-bit offsets instead of 64-bit pointers, which typically increases -performance when running the application with Java heap sizes smaller -than the compressed oops pointer range. -This option works only for 64-bit JVMs. -.PP -It\[aq]s possible to use compressed pointers with Java heap sizes -greater than 32 GB. -See the \f[V]-XX:ObjectAlignmentInBytes\f[R] option. -.RE -.TP -\f[V]-XX:-UseContainerSupport\f[R] -\f[B]Linux only:\f[R] The VM now provides automatic container detection -support, which allows the VM to determine the amount of memory and -number of processors that are available to a Java process running in -docker containers. -It uses this information to allocate system resources. -The default for this flag is \f[V]true\f[R], and container support is -enabled by default. -It can be disabled with \f[V]-XX:-UseContainerSupport\f[R]. -.RS -.PP -Unified Logging is available to help to diagnose issues related to this -support. -.PP -Use \f[V]-Xlog:os+container=trace\f[R] for maximum logging of container -information. -See \f[B]Enable Logging with the JVM Unified Logging Framework\f[R] for -a description of using Unified Logging. -.RE -.TP -\f[V]-XX:+UseLargePages\f[R] -Enables the use of large page memory. -By default, this option is disabled and large page memory isn\[aq]t -used. -.RS -.PP -See \f[B]Large Pages\f[R]. -.RE -.TP -\f[V]-XX:+UseTransparentHugePages\f[R] -\f[B]Linux only:\f[R] Enables the use of large pages that can -dynamically grow or shrink. -This option is disabled by default. -You may encounter performance problems with transparent huge pages as -the OS moves other pages around to create huge pages; this option is -made available for experimentation. -.TP -\f[V]-XX:+AllowUserSignalHandlers\f[R] -\f[B]Non-Windows:\f[R] Enables installation of signal handlers by the -application. -By default, this option is disabled and the application isn\[aq]t -allowed to install signal handlers. -.TP -\f[V]-XX:VMOptionsFile=\f[R]\f[I]filename\f[R] -Allows user to specify VM options in a file, for example, -\f[V]java -XX:VMOptionsFile=/var/my_vm_options HelloWorld\f[R]. -.TP -\f[V]-XX:UseBranchProtection=\f[R]\f[I]mode\f[R] -\f[B]Linux AArch64 only:\f[R] Specifies the branch protection mode. -All options other than \f[V]none\f[R] require the VM to have been built -with branch protection enabled. -In addition, for full protection, any native libraries provided by -applications should be compiled with the same level of protection. -.RS -.PP -Possible \f[I]mode\f[R] arguments for this option include the following: -.TP -\f[V]none\f[R] -Do not use branch protection. -This is the default value. -.TP -\f[V]standard\f[R] -Enables all branch protection modes available on the current platform. -.TP -\f[V]pac-ret\f[R] -Enables protection against ROP based attacks. -(AArch64 8.3+ only) -.RE -.SH ADVANCED JIT COMPILER OPTIONS FOR JAVA -.PP -These \f[V]java\f[R] options control the dynamic just-in-time (JIT) -compilation performed by the Java HotSpot VM. -.TP -\f[V]-XX:AllocateInstancePrefetchLines=\f[R]\f[I]lines\f[R] -Sets the number of lines to prefetch ahead of the instance allocation -pointer. -By default, the number of lines to prefetch is set to 1: -.RS -.RS -.PP -\f[V]-XX:AllocateInstancePrefetchLines=1\f[R] -.RE -.RE -.TP -\f[V]-XX:AllocatePrefetchDistance=\f[R]\f[I]size\f[R] -Sets the size (in bytes) of the prefetch distance for object allocation. -Memory about to be written with the value of new objects is prefetched -up to this distance starting from the address of the last allocated -object. -Each Java thread has its own allocation point. -.RS -.PP -Negative values denote that prefetch distance is chosen based on the -platform. -Positive values are bytes to prefetch. -Append the letter \f[V]k\f[R] or \f[V]K\f[R] to indicate kilobytes, -\f[V]m\f[R] or \f[V]M\f[R] to indicate megabytes, or \f[V]g\f[R] or -\f[V]G\f[R] to indicate gigabytes. -The default value is set to -1. -.PP -The following example shows how to set the prefetch distance to 1024 -bytes: -.RS -.PP -\f[V]-XX:AllocatePrefetchDistance=1024\f[R] -.RE -.RE -.TP -\f[V]-XX:AllocatePrefetchInstr=\f[R]\f[I]instruction\f[R] -Sets the prefetch instruction to prefetch ahead of the allocation -pointer. -Possible values are from 0 to 3. -The actual instructions behind the values depend on the platform. -By default, the prefetch instruction is set to 0: -.RS -.RS -.PP -\f[V]-XX:AllocatePrefetchInstr=0\f[R] -.RE -.RE -.TP -\f[V]-XX:AllocatePrefetchLines=\f[R]\f[I]lines\f[R] -Sets the number of cache lines to load after the last object allocation -by using the prefetch instructions generated in compiled code. -The default value is 1 if the last allocated object was an instance, and -3 if it was an array. -.RS -.PP -The following example shows how to set the number of loaded cache lines -to 5: -.RS -.PP -\f[V]-XX:AllocatePrefetchLines=5\f[R] -.RE -.RE -.TP -\f[V]-XX:AllocatePrefetchStepSize=\f[R]\f[I]size\f[R] -Sets the step size (in bytes) for sequential prefetch instructions. -Append the letter \f[V]k\f[R] or \f[V]K\f[R] to indicate kilobytes, -\f[V]m\f[R] or \f[V]M\f[R] to indicate megabytes, \f[V]g\f[R] or -\f[V]G\f[R] to indicate gigabytes. -By default, the step size is set to 16 bytes: -.RS -.RS -.PP -\f[V]-XX:AllocatePrefetchStepSize=16\f[R] -.RE -.RE -.TP -\f[V]-XX:AllocatePrefetchStyle=\f[R]\f[I]style\f[R] -Sets the generated code style for prefetch instructions. -The \f[I]style\f[R] argument is an integer from 0 to 3: -.RS -.TP -\f[V]0\f[R] -Don\[aq]t generate prefetch instructions. -.TP -\f[V]1\f[R] -Execute prefetch instructions after each allocation. -This is the default setting. -.TP -\f[V]2\f[R] -Use the thread-local allocation block (TLAB) watermark pointer to -determine when prefetch instructions are executed. -.TP -\f[V]3\f[R] -Generate one prefetch instruction per cache line. -.RE -.TP -\f[V]-XX:+BackgroundCompilation\f[R] -Enables background compilation. -This option is enabled by default. -To disable background compilation, specify -\f[V]-XX:-BackgroundCompilation\f[R] (this is equivalent to specifying -\f[V]-Xbatch\f[R]). -.TP -\f[V]-XX:CICompilerCount=\f[R]\f[I]threads\f[R] -Sets the number of compiler threads to use for compilation. -By default, the number of compiler threads is selected automatically -depending on the number of CPUs and memory available for compiled code. -The following example shows how to set the number of threads to 2: -.RS -.RS -.PP -\f[V]-XX:CICompilerCount=2\f[R] -.RE -.RE -.TP -\f[V]-XX:+UseDynamicNumberOfCompilerThreads\f[R] -Dynamically create compiler thread up to the limit specified by -\f[V]-XX:CICompilerCount\f[R]. -This option is enabled by default. -.TP -\f[V]-XX:CompileCommand=\f[R]\f[I]command\f[R]\f[V],\f[R]\f[I]method\f[R][\f[V],\f[R]\f[I]option\f[R]] -Specifies a \f[I]command\f[R] to perform on a \f[I]method\f[R]. -For example, to exclude the \f[V]indexOf()\f[R] method of the -\f[V]String\f[R] class from being compiled, use the following: -.RS -.RS -.PP -\f[V]-XX:CompileCommand=exclude,java/lang/String.indexOf\f[R] -.RE -.PP -Note that the full class name is specified, including all packages and -subpackages separated by a slash (\f[V]/\f[R]). -For easier cut-and-paste operations, it\[aq]s also possible to use the -method name format produced by the \f[V]-XX:+PrintCompilation\f[R] and -\f[V]-XX:+LogCompilation\f[R] options: -.RS -.PP -\f[V]-XX:CompileCommand=exclude,java.lang.String::indexOf\f[R] -.RE -.PP -If the method is specified without the signature, then the command is -applied to all methods with the specified name. -However, you can also specify the signature of the method in the class -file format. -In this case, you should enclose the arguments in quotation marks, -because otherwise the shell treats the semicolon as a command end. -For example, if you want to exclude only the \f[V]indexOf(String)\f[R] -method of the \f[V]String\f[R] class from being compiled, use the -following: -.RS -.PP -\f[V]-XX:CompileCommand=\[dq]exclude,java/lang/String.indexOf,(Ljava/lang/String;)I\[dq]\f[R] -.RE -.PP -You can also use the asterisk (*) as a wildcard for class and method -names. -For example, to exclude all \f[V]indexOf()\f[R] methods in all classes -from being compiled, use the following: -.RS -.PP -\f[V]-XX:CompileCommand=exclude,*.indexOf\f[R] -.RE -.PP -The commas and periods are aliases for spaces, making it easier to pass -compiler commands through a shell. -You can pass arguments to \f[V]-XX:CompileCommand\f[R] using spaces as -separators by enclosing the argument in quotation marks: -.RS -.PP -\f[V]-XX:CompileCommand=\[dq]exclude java/lang/String indexOf\[dq]\f[R] -.RE -.PP -Note that after parsing the commands passed on the command line using -the \f[V]-XX:CompileCommand\f[R] options, the JIT compiler then reads -commands from the \f[V].hotspot_compiler\f[R] file. -You can add commands to this file or specify a different file using the -\f[V]-XX:CompileCommandFile\f[R] option. -.PP -To add several commands, either specify the \f[V]-XX:CompileCommand\f[R] -option multiple times, or separate each argument with the new line -separator (\f[V]\[rs]n\f[R]). -The following commands are available: -.TP -\f[V]break\f[R] -Sets a breakpoint when debugging the JVM to stop at the beginning of -compilation of the specified method. -.TP -\f[V]compileonly\f[R] -Excludes all methods from compilation except for the specified method. -As an alternative, you can use the \f[V]-XX:CompileOnly\f[R] option, -which lets you specify several methods. -.TP -\f[V]dontinline\f[R] -Prevents inlining of the specified method. -.TP -\f[V]exclude\f[R] -Excludes the specified method from compilation. -.TP -\f[V]help\f[R] -Prints a help message for the \f[V]-XX:CompileCommand\f[R] option. -.TP -\f[V]inline\f[R] -Attempts to inline the specified method. -.TP -\f[V]log\f[R] -Excludes compilation logging (with the \f[V]-XX:+LogCompilation\f[R] -option) for all methods except for the specified method. -By default, logging is performed for all compiled methods. -.TP -\f[V]option\f[R] -Passes a JIT compilation option to the specified method in place of the -last argument (\f[V]option\f[R]). -The compilation option is set at the end, after the method name. -For example, to enable the \f[V]BlockLayoutByFrequency\f[R] option for -the \f[V]append()\f[R] method of the \f[V]StringBuffer\f[R] class, use -the following: -.RS -.RS -.PP -\f[V]-XX:CompileCommand=option,java/lang/StringBuffer.append,BlockLayoutByFrequency\f[R] -.RE -.PP -You can specify multiple compilation options, separated by commas or -spaces. -.RE -.TP -\f[V]print\f[R] -Prints generated assembler code after compilation of the specified -method. -.TP -\f[V]quiet\f[R] -Instructs not to print the compile commands. -By default, the commands that you specify with the -\f[V]-XX:CompileCommand\f[R] option are printed; for example, if you -exclude from compilation the \f[V]indexOf()\f[R] method of the -\f[V]String\f[R] class, then the following is printed to standard -output: -.RS -.RS -.PP -\f[V]CompilerOracle: exclude java/lang/String.indexOf\f[R] -.RE -.PP -You can suppress this by specifying the -\f[V]-XX:CompileCommand=quiet\f[R] option before other -\f[V]-XX:CompileCommand\f[R] options. -.RE -.RE -.TP -\f[V]-XX:CompileCommandFile=\f[R]\f[I]filename\f[R] -Sets the file from which JIT compiler commands are read. -By default, the \f[V].hotspot_compiler\f[R] file is used to store -commands performed by the JIT compiler. -.RS -.PP -Each line in the command file represents a command, a class name, and a -method name for which the command is used. -For example, this line prints assembly code for the \f[V]toString()\f[R] -method of the \f[V]String\f[R] class: -.RS -.PP -\f[V]print java/lang/String toString\f[R] -.RE -.PP -If you\[aq]re using commands for the JIT compiler to perform on methods, -then see the \f[V]-XX:CompileCommand\f[R] option. -.RE -.TP -\f[V]-XX:CompilerDirectivesFile=\f[R]\f[I]file\f[R] -Adds directives from a file to the directives stack when a program -starts. -See \f[B]Compiler Control\f[R] -[https://docs.oracle.com/en/java/javase/12/vm/compiler-control1.html#GUID-94AD8194-786A-4F19-BFFF-278F8E237F3A]. -.RS -.PP -The \f[V]-XX:CompilerDirectivesFile\f[R] option has to be used together -with the \f[V]-XX:UnlockDiagnosticVMOptions\f[R] option that unlocks -diagnostic JVM options. -.RE -.TP -\f[V]-XX:+CompilerDirectivesPrint\f[R] -Prints the directives stack when the program starts or when a new -directive is added. -.RS -.PP -The \f[V]-XX:+CompilerDirectivesPrint\f[R] option has to be used -together with the \f[V]-XX:UnlockDiagnosticVMOptions\f[R] option that -unlocks diagnostic JVM options. -.RE -.TP -\f[V]-XX:CompileOnly=\f[R]\f[I]methods\f[R] -Sets the list of methods (separated by commas) to which compilation -should be restricted. -Only the specified methods are compiled. -.RS -.PP -\f[V]-XX:CompileOnly=method1,method2,...,methodN\f[R] is an alias for: -.IP -.nf -\f[CB] --XX:CompileCommand=compileonly,method1 --XX:CompileCommand=compileonly,method2 -\&... --XX:CompileCommand=compileonly,methodN -\f[R] -.fi -.RE -.TP -\f[V]-XX:CompileThresholdScaling=\f[R]\f[I]scale\f[R] -Provides unified control of first compilation. -This option controls when methods are first compiled for both the tiered -and the nontiered modes of operation. -The \f[V]CompileThresholdScaling\f[R] option has a floating point value -between 0 and +Inf and scales the thresholds corresponding to the -current mode of operation (both tiered and nontiered). -Setting \f[V]CompileThresholdScaling\f[R] to a value less than 1.0 -results in earlier compilation while values greater than 1.0 delay -compilation. -Setting \f[V]CompileThresholdScaling\f[R] to 0 is equivalent to -disabling compilation. -.TP -\f[V]-XX:+DoEscapeAnalysis\f[R] -Enables the use of escape analysis. -This option is enabled by default. -To disable the use of escape analysis, specify -\f[V]-XX:-DoEscapeAnalysis\f[R]. -.TP -\f[V]-XX:InitialCodeCacheSize=\f[R]\f[I]size\f[R] -Sets the initial code cache size (in bytes). -Append the letter \f[V]k\f[R] or \f[V]K\f[R] to indicate kilobytes, -\f[V]m\f[R] or \f[V]M\f[R] to indicate megabytes, or \f[V]g\f[R] or -\f[V]G\f[R] to indicate gigabytes. -The default value depends on the platform. -The initial code cache size shouldn\[aq]t be less than the system\[aq]s -minimal memory page size. -The following example shows how to set the initial code cache size to 32 -KB: -.RS -.RS -.PP -\f[V]-XX:InitialCodeCacheSize=32k\f[R] -.RE -.RE -.TP -\f[V]-XX:+Inline\f[R] -Enables method inlining. -This option is enabled by default to increase performance. -To disable method inlining, specify \f[V]-XX:-Inline\f[R]. -.TP -\f[V]-XX:InlineSmallCode=\f[R]\f[I]size\f[R] -Sets the maximum code size (in bytes) for already compiled methods that -may be inlined. -This flag only applies to the C2 compiler. -Append the letter \f[V]k\f[R] or \f[V]K\f[R] to indicate kilobytes, -\f[V]m\f[R] or \f[V]M\f[R] to indicate megabytes, or \f[V]g\f[R] or -\f[V]G\f[R] to indicate gigabytes. -The default value depends on the platform and on whether tiered -compilation is enabled. -In the following example it is set to 1000 bytes: -.RS -.RS -.PP -\f[V]-XX:InlineSmallCode=1000\f[R] -.RE -.RE -.TP -\f[V]-XX:+LogCompilation\f[R] -Enables logging of compilation activity to a file named -\f[V]hotspot.log\f[R] in the current working directory. -You can specify a different log file path and name using the -\f[V]-XX:LogFile\f[R] option. -.RS -.PP -By default, this option is disabled and compilation activity isn\[aq]t -logged. -The \f[V]-XX:+LogCompilation\f[R] option has to be used together with -the \f[V]-XX:UnlockDiagnosticVMOptions\f[R] option that unlocks -diagnostic JVM options. -.PP -You can enable verbose diagnostic output with a message printed to the -console every time a method is compiled by using the -\f[V]-XX:+PrintCompilation\f[R] option. -.RE -.TP -\f[V]-XX:FreqInlineSize=\f[R]\f[I]size\f[R] -Sets the maximum bytecode size (in bytes) of a hot method to be inlined. -This flag only applies to the C2 compiler. -Append the letter \f[V]k\f[R] or \f[V]K\f[R] to indicate kilobytes, -\f[V]m\f[R] or \f[V]M\f[R] to indicate megabytes, or \f[V]g\f[R] or -\f[V]G\f[R] to indicate gigabytes. -The default value depends on the platform. -In the following example it is set to 325 bytes: -.RS -.RS -.PP -\f[V]-XX:FreqInlineSize=325\f[R] -.RE -.RE -.TP -\f[V]-XX:MaxInlineSize=\f[R]\f[I]size\f[R] -Sets the maximum bytecode size (in bytes) of a cold method to be -inlined. -This flag only applies to the C2 compiler. -Append the letter \f[V]k\f[R] or \f[V]K\f[R] to indicate kilobytes, -\f[V]m\f[R] or \f[V]M\f[R] to indicate megabytes, or \f[V]g\f[R] or -\f[V]G\f[R] to indicate gigabytes. -By default, the maximum bytecode size is set to 35 bytes: -.RS -.RS -.PP -\f[V]-XX:MaxInlineSize=35\f[R] -.RE -.RE -.TP -\f[V]-XX:C1MaxInlineSize=\f[R]\f[I]size\f[R] -Sets the maximum bytecode size (in bytes) of a cold method to be -inlined. -This flag only applies to the C1 compiler. -Append the letter \f[V]k\f[R] or \f[V]K\f[R] to indicate kilobytes, -\f[V]m\f[R] or \f[V]M\f[R] to indicate megabytes, or \f[V]g\f[R] or -\f[V]G\f[R] to indicate gigabytes. -By default, the maximum bytecode size is set to 35 bytes: -.RS -.RS -.PP -\f[V]-XX:MaxInlineSize=35\f[R] -.RE -.RE -.TP -\f[V]-XX:MaxTrivialSize=\f[R]\f[I]size\f[R] -Sets the maximum bytecode size (in bytes) of a trivial method to be -inlined. -This flag only applies to the C2 compiler. -Append the letter \f[V]k\f[R] or \f[V]K\f[R] to indicate kilobytes, -\f[V]m\f[R] or \f[V]M\f[R] to indicate megabytes, or \f[V]g\f[R] or -\f[V]G\f[R] to indicate gigabytes. -By default, the maximum bytecode size of a trivial method is set to 6 -bytes: -.RS -.RS -.PP -\f[V]-XX:MaxTrivialSize=6\f[R] -.RE -.RE -.TP -\f[V]-XX:C1MaxTrivialSize=\f[R]\f[I]size\f[R] -Sets the maximum bytecode size (in bytes) of a trivial method to be -inlined. -This flag only applies to the C1 compiler. -Append the letter \f[V]k\f[R] or \f[V]K\f[R] to indicate kilobytes, -\f[V]m\f[R] or \f[V]M\f[R] to indicate megabytes, or \f[V]g\f[R] or -\f[V]G\f[R] to indicate gigabytes. -By default, the maximum bytecode size of a trivial method is set to 6 -bytes: -.RS -.RS -.PP -\f[V]-XX:MaxTrivialSize=6\f[R] -.RE -.RE -.TP -\f[V]-XX:MaxNodeLimit=\f[R]\f[I]nodes\f[R] -Sets the maximum number of nodes to be used during single method -compilation. -By default the value depends on the features enabled. -In the following example the maximum number of nodes is set to 100,000: -.RS -.RS -.PP -\f[V]-XX:MaxNodeLimit=100000\f[R] -.RE -.RE -.TP -\f[V]-XX:NonNMethodCodeHeapSize=\f[R]\f[I]size\f[R] -Sets the size in bytes of the code segment containing nonmethod code. -.RS -.PP -A nonmethod code segment containing nonmethod code, such as compiler -buffers and the bytecode interpreter. -This code type stays in the code cache forever. -This flag is used only if \f[V]-XX:SegmentedCodeCache\f[R] is enabled. -.RE -.TP -\f[V]-XX:NonProfiledCodeHeapSize=\f[R]\f[I]size\f[R] -Sets the size in bytes of the code segment containing nonprofiled -methods. -This flag is used only if \f[V]-XX:SegmentedCodeCache\f[R] is enabled. -.TP -\f[V]-XX:+OptimizeStringConcat\f[R] -Enables the optimization of \f[V]String\f[R] concatenation operations. -This option is enabled by default. -To disable the optimization of \f[V]String\f[R] concatenation -operations, specify \f[V]-XX:-OptimizeStringConcat\f[R]. -.TP -\f[V]-XX:+PrintAssembly\f[R] -Enables printing of assembly code for bytecoded and native methods by -using the external \f[V]hsdis-.so\f[R] or \f[V].dll\f[R] library. -For 64-bit VM on Windows, it\[aq]s \f[V]hsdis-amd64.dll\f[R]. -This lets you to see the generated code, which may help you to diagnose -performance issues. -.RS -.PP -By default, this option is disabled and assembly code isn\[aq]t printed. -The \f[V]-XX:+PrintAssembly\f[R] option has to be used together with the -\f[V]-XX:UnlockDiagnosticVMOptions\f[R] option that unlocks diagnostic -JVM options. -.RE -.TP -\f[V]-XX:ProfiledCodeHeapSize=\f[R]\f[I]size\f[R] -Sets the size in bytes of the code segment containing profiled methods. -This flag is used only if \f[V]-XX:SegmentedCodeCache\f[R] is enabled. -.TP -\f[V]-XX:+PrintCompilation\f[R] -Enables verbose diagnostic output from the JVM by printing a message to -the console every time a method is compiled. -This lets you to see which methods actually get compiled. -By default, this option is disabled and diagnostic output isn\[aq]t -printed. -.RS -.PP -You can also log compilation activity to a file by using the -\f[V]-XX:+LogCompilation\f[R] option. -.RE -.TP -\f[V]-XX:+PrintInlining\f[R] -Enables printing of inlining decisions. -This let\[aq]s you see which methods are getting inlined. -.RS -.PP -By default, this option is disabled and inlining information isn\[aq]t -printed. -The \f[V]-XX:+PrintInlining\f[R] option has to be used together with the -\f[V]-XX:+UnlockDiagnosticVMOptions\f[R] option that unlocks diagnostic -JVM options. -.RE -.TP -\f[V]-XX:ReservedCodeCacheSize=\f[R]\f[I]size\f[R] -Sets the maximum code cache size (in bytes) for JIT-compiled code. -Append the letter \f[V]k\f[R] or \f[V]K\f[R] to indicate kilobytes, -\f[V]m\f[R] or \f[V]M\f[R] to indicate megabytes, or \f[V]g\f[R] or -\f[V]G\f[R] to indicate gigabytes. -The default maximum code cache size is 240 MB; if you disable tiered -compilation with the option \f[V]-XX:-TieredCompilation\f[R], then the -default size is 48 MB. -This option has a limit of 2 GB; otherwise, an error is generated. -The maximum code cache size shouldn\[aq]t be less than the initial code -cache size; see the option \f[V]-XX:InitialCodeCacheSize\f[R]. -.TP -\f[V]-XX:+SegmentedCodeCache\f[R] -Enables segmentation of the code cache, without which the code cache -consists of one large segment. -With \f[V]-XX:+SegmentedCodeCache\f[R], separate segments will be used -for non-method, profiled method, and non-profiled method code. -The segments are not resized at runtime. -The advantages are better control of the memory footprint, reduced code -fragmentation, and better CPU iTLB (instruction translation lookaside -buffer) and instruction cache behavior due to improved locality. -.RS -.PP -The feature is enabled by default if tiered compilation is enabled -(\f[V]-XX:+TieredCompilation\f[R] ) and the reserved code cache size -(\f[V]-XX:ReservedCodeCacheSize\f[R]) is at least 240 MB. -.RE -.TP -\f[V]-XX:StartAggressiveSweepingAt=\f[R]\f[I]percent\f[R] -Forces stack scanning of active methods to aggressively remove unused -code when only the given percentage of the code cache is free. -The default value is 10%. -.TP -\f[V]-XX:-TieredCompilation\f[R] -Disables the use of tiered compilation. -By default, this option is enabled. -.TP -\f[V]-XX:UseSSE=\f[R]\f[I]version\f[R] -Enables the use of SSE instruction set of a specified version. -Is set by default to the highest supported version available (x86 only). -.TP -\f[V]-XX:UseAVX=\f[R]\f[I]version\f[R] -Enables the use of AVX instruction set of a specified version. -Is set by default to the highest supported version available (x86 only). -.TP -\f[V]-XX:+UseAES\f[R] -Enables hardware-based AES intrinsics for hardware that supports it. -This option is on by default on hardware that has the necessary -instructions. -The \f[V]-XX:+UseAES\f[R] is used in conjunction with -\f[V]UseAESIntrinsics\f[R]. -Flags that control intrinsics now require the option -\f[V]-XX:+UnlockDiagnosticVMOptions\f[R]. -.TP -\f[V]-XX:+UseAESIntrinsics\f[R] -Enables AES intrinsics. -Specifying \f[V]-XX:+UseAESIntrinsics\f[R] is equivalent to also -enabling \f[V]-XX:+UseAES\f[R]. -To disable hardware-based AES intrinsics, specify -\f[V]-XX:-UseAES -XX:-UseAESIntrinsics\f[R]. -For example, to enable hardware AES, use the following flags: -.RS -.RS -.PP -\f[V]-XX:+UseAES -XX:+UseAESIntrinsics\f[R] -.RE -.PP -Flags that control intrinsics now require the option -\f[V]-XX:+UnlockDiagnosticVMOptions\f[R]. -.RE -.TP -\f[V]-XX:+UseAESCTRIntrinsics\f[R] -Analogous to \f[V]-XX:+UseAESIntrinsics\f[R] enables AES/CTR intrinsics. -.TP -\f[V]-XX:+UseGHASHIntrinsics\f[R] -Controls the use of GHASH intrinsics. -Enabled by default on platforms that support the corresponding -instructions. -Flags that control intrinsics now require the option -\f[V]-XX:+UnlockDiagnosticVMOptions\f[R]. -.TP -\f[V]-XX:+UseChaCha20Intrinsics\f[R] -Enable ChaCha20 intrinsics. -This option is on by default for supported platforms. -To disable ChaCha20 intrinsics, specify -\f[V]-XX:-UseChaCha20Intrinsics\f[R]. -Flags that control intrinsics now require the option -\f[V]-XX:+UnlockDiagnosticVMOptions\f[R]. -.TP -\f[V]-XX:+UsePoly1305Intrinsics\f[R] -Enable Poly1305 intrinsics. -This option is on by default for supported platforms. -To disable Poly1305 intrinsics, specify -\f[V]-XX:-UsePoly1305Intrinsics\f[R]. -Flags that control intrinsics now require the option -\f[V]-XX:+UnlockDiagnosticVMOptions\f[R]. -.TP -\f[V]-XX:+UseBASE64Intrinsics\f[R] -Controls the use of accelerated BASE64 encoding routines for -\f[V]java.util.Base64\f[R]. -Enabled by default on platforms that support it. -Flags that control intrinsics now require the option -\f[V]-XX:+UnlockDiagnosticVMOptions\f[R]. -.TP -\f[V]-XX:+UseAdler32Intrinsics\f[R] -Controls the use of Adler32 checksum algorithm intrinsic for -\f[V]java.util.zip.Adler32\f[R]. -Enabled by default on platforms that support it. -Flags that control intrinsics now require the option -\f[V]-XX:+UnlockDiagnosticVMOptions\f[R]. -.TP -\f[V]-XX:+UseCRC32Intrinsics\f[R] -Controls the use of CRC32 intrinsics for \f[V]java.util.zip.CRC32\f[R]. -Enabled by default on platforms that support it. -Flags that control intrinsics now require the option -\f[V]-XX:+UnlockDiagnosticVMOptions\f[R]. -.TP -\f[V]-XX:+UseCRC32CIntrinsics\f[R] -Controls the use of CRC32C intrinsics for -\f[V]java.util.zip.CRC32C\f[R]. -Enabled by default on platforms that support it. -Flags that control intrinsics now require the option -\f[V]-XX:+UnlockDiagnosticVMOptions\f[R]. -.TP -\f[V]-XX:+UseSHA\f[R] -Enables hardware-based intrinsics for SHA crypto hash functions for some -hardware. -The \f[V]UseSHA\f[R] option is used in conjunction with the -\f[V]UseSHA1Intrinsics\f[R], \f[V]UseSHA256Intrinsics\f[R], and -\f[V]UseSHA512Intrinsics\f[R] options. -.RS -.PP -The \f[V]UseSHA\f[R] and \f[V]UseSHA*Intrinsics\f[R] flags are enabled -by default on machines that support the corresponding instructions. -.PP -This feature is applicable only when using the -\f[V]sun.security.provider.Sun\f[R] provider for SHA operations. -Flags that control intrinsics now require the option -\f[V]-XX:+UnlockDiagnosticVMOptions\f[R]. -.PP -To disable all hardware-based SHA intrinsics, specify the -\f[V]-XX:-UseSHA\f[R]. -To disable only a particular SHA intrinsic, use the appropriate -corresponding option. -For example: \f[V]-XX:-UseSHA256Intrinsics\f[R]. -.RE -.TP -\f[V]-XX:+UseSHA1Intrinsics\f[R] -Enables intrinsics for SHA-1 crypto hash function. -Flags that control intrinsics now require the option -\f[V]-XX:+UnlockDiagnosticVMOptions\f[R]. -.TP -\f[V]-XX:+UseSHA256Intrinsics\f[R] -Enables intrinsics for SHA-224 and SHA-256 crypto hash functions. -Flags that control intrinsics now require the option -\f[V]-XX:+UnlockDiagnosticVMOptions\f[R]. -.TP -\f[V]-XX:+UseSHA512Intrinsics\f[R] -Enables intrinsics for SHA-384 and SHA-512 crypto hash functions. -Flags that control intrinsics now require the option -\f[V]-XX:+UnlockDiagnosticVMOptions\f[R]. -.TP -\f[V]-XX:+UseMathExactIntrinsics\f[R] -Enables intrinsification of various \f[V]java.lang.Math.*Exact()\f[R] -functions. -Enabled by default. -Flags that control intrinsics now require the option -\f[V]-XX:+UnlockDiagnosticVMOptions\f[R]. -.TP -\f[V]-XX:+UseMultiplyToLenIntrinsic\f[R] -Enables intrinsification of \f[V]BigInteger.multiplyToLen()\f[R]. -Enabled by default on platforms that support it. -Flags that control intrinsics now require the option -\f[V]-XX:+UnlockDiagnosticVMOptions\f[R]. -.TP --XX:+UseSquareToLenIntrinsic -Enables intrinsification of \f[V]BigInteger.squareToLen()\f[R]. -Enabled by default on platforms that support it. -Flags that control intrinsics now require the option -\f[V]-XX:+UnlockDiagnosticVMOptions\f[R]. -.TP --XX:+UseMulAddIntrinsic -Enables intrinsification of \f[V]BigInteger.mulAdd()\f[R]. -Enabled by default on platforms that support it. -Flags that control intrinsics now require the option -\f[V]-XX:+UnlockDiagnosticVMOptions\f[R]. -.TP --XX:+UseMontgomeryMultiplyIntrinsic -Enables intrinsification of \f[V]BigInteger.montgomeryMultiply()\f[R]. -Enabled by default on platforms that support it. -Flags that control intrinsics now require the option -\f[V]-XX:+UnlockDiagnosticVMOptions\f[R]. -.TP --XX:+UseMontgomerySquareIntrinsic -Enables intrinsification of \f[V]BigInteger.montgomerySquare()\f[R]. -Enabled by default on platforms that support it. -Flags that control intrinsics now require the option -\f[V]-XX:+UnlockDiagnosticVMOptions\f[R]. -.TP -\f[V]-XX:+UseCMoveUnconditionally\f[R] -Generates CMove (scalar and vector) instructions regardless of -profitability analysis. -.TP -\f[V]-XX:+UseCodeCacheFlushing\f[R] -Enables flushing of the code cache before shutting down the compiler. -This option is enabled by default. -To disable flushing of the code cache before shutting down the compiler, -specify \f[V]-XX:-UseCodeCacheFlushing\f[R]. -.TP -\f[V]-XX:+UseCondCardMark\f[R] -Enables checking if the card is already marked before updating the card -table. -This option is disabled by default. -It should be used only on machines with multiple sockets, where it -increases the performance of Java applications that rely on concurrent -operations. -.TP -\f[V]-XX:+UseCountedLoopSafepoints\f[R] -Keeps safepoints in counted loops. -Its default value depends on whether the selected garbage collector -requires low latency safepoints. -.TP -\f[V]-XX:LoopStripMiningIter=\f[R]\f[I]number_of_iterations\f[R] -Controls the number of iterations in the inner strip mined loop. -Strip mining transforms counted loops into two level nested loops. -Safepoints are kept in the outer loop while the inner loop can execute -at full speed. -This option controls the maximum number of iterations in the inner loop. -The default value is 1,000. -.TP -\f[V]-XX:LoopStripMiningIterShortLoop=\f[R]\f[I]number_of_iterations\f[R] -Controls loop strip mining optimization. -Loops with the number of iterations less than specified will not have -safepoints in them. -Default value is 1/10th of \f[V]-XX:LoopStripMiningIter\f[R]. -.TP -\f[V]-XX:+UseFMA\f[R] -Enables hardware-based FMA intrinsics for hardware where FMA -instructions are available (such as, Intel and ARM64). -FMA intrinsics are generated for the -\f[V]java.lang.Math.fma(\f[R]\f[I]a\f[R]\f[V],\f[R] -\f[I]b\f[R]\f[V],\f[R] \f[I]c\f[R]\f[V])\f[R] methods that calculate the -value of \f[V](\f[R] \f[I]a\f[R] \f[V]*\f[R] \f[I]b\f[R] \f[V]+\f[R] -\f[I]c\f[R] \f[V])\f[R] expressions. -.TP -\f[V]-XX:+UseSuperWord\f[R] -Enables the transformation of scalar operations into superword -operations. -Superword is a vectorization optimization. -This option is enabled by default. -To disable the transformation of scalar operations into superword -operations, specify \f[V]-XX:-UseSuperWord\f[R]. -.SH ADVANCED SERVICEABILITY OPTIONS FOR JAVA -.PP -These \f[V]java\f[R] options provide the ability to gather system -information and perform extensive debugging. -.TP -\f[V]-XX:+DisableAttachMechanism\f[R] -Disables the mechanism that lets tools attach to the JVM. -By default, this option is disabled, meaning that the attach mechanism -is enabled and you can use diagnostics and troubleshooting tools such as -\f[V]jcmd\f[R], \f[V]jstack\f[R], \f[V]jmap\f[R], and \f[V]jinfo\f[R]. -.RS -.RS -.PP -\f[B]Note:\f[R] The tools such as \f[B]jcmd\f[R], \f[B]jinfo\f[R], -\f[B]jmap\f[R], and \f[B]jstack\f[R] shipped with the JDK aren\[aq]t -supported when using the tools from one JDK version to troubleshoot a -different JDK version. -.RE -.RE -.TP -\f[V]-XX:+DTraceAllocProbes\f[R] -\f[B]Linux and macOS:\f[R] Enable \f[V]dtrace\f[R] tool probes for -object allocation. -.TP -\f[V]-XX:+DTraceMethodProbes\f[R] -\f[B]Linux and macOS:\f[R] Enable \f[V]dtrace\f[R] tool probes for -method-entry and method-exit. -.TP -\f[V]-XX:+DTraceMonitorProbes\f[R] -\f[B]Linux and macOS:\f[R] Enable \f[V]dtrace\f[R] tool probes for -monitor events. -.TP -\f[V]-XX:+HeapDumpOnOutOfMemoryError\f[R] -Enables the dumping of the Java heap to a file in the current directory -by using the heap profiler (HPROF) when a -\f[V]java.lang.OutOfMemoryError\f[R] exception is thrown. -You can explicitly set the heap dump file path and name using the -\f[V]-XX:HeapDumpPath\f[R] option. -By default, this option is disabled and the heap isn\[aq]t dumped when -an \f[V]OutOfMemoryError\f[R] exception is thrown. -.TP -\f[V]-XX:HeapDumpPath=\f[R]\f[I]path\f[R] -Sets the path and file name for writing the heap dump provided by the -heap profiler (HPROF) when the \f[V]-XX:+HeapDumpOnOutOfMemoryError\f[R] -option is set. -By default, the file is created in the current working directory, and -it\[aq]s named \f[V]java_pid.hprof\f[R] where \f[V]\f[R] is -the identifier of the process that caused the error. -The following example shows how to set the default file explicitly -(\f[V]%p\f[R] represents the current process identifier): -.RS -.RS -.PP -\f[V]-XX:HeapDumpPath=./java_pid%p.hprof\f[R] -.RE -.IP \[bu] 2 -\f[B]Non-Windows:\f[R] The following example shows how to set the heap -dump file to \f[V]/var/log/java/java_heapdump.hprof\f[R]: -.RS 2 -.RS -.PP -\f[V]-XX:HeapDumpPath=/var/log/java/java_heapdump.hprof\f[R] -.RE -.RE -.IP \[bu] 2 -\f[B]Windows:\f[R] The following example shows how to set the heap dump -file to \f[V]C:/log/java/java_heapdump.log\f[R]: -.RS 2 -.RS -.PP -\f[V]-XX:HeapDumpPath=C:/log/java/java_heapdump.log\f[R] -.RE -.RE -.RE -.TP -\f[V]-XX:LogFile=\f[R]\f[I]path\f[R] -Sets the path and file name to where log data is written. -By default, the file is created in the current working directory, and -it\[aq]s named \f[V]hotspot.log\f[R]. -.RS -.IP \[bu] 2 -\f[B]Non-Windows:\f[R] The following example shows how to set the log -file to \f[V]/var/log/java/hotspot.log\f[R]: -.RS 2 -.RS -.PP -\f[V]-XX:LogFile=/var/log/java/hotspot.log\f[R] -.RE -.RE -.IP \[bu] 2 -\f[B]Windows:\f[R] The following example shows how to set the log file -to \f[V]C:/log/java/hotspot.log\f[R]: -.RS 2 -.RS -.PP -\f[V]-XX:LogFile=C:/log/java/hotspot.log\f[R] -.RE -.RE -.RE -.TP -\f[V]-XX:+PrintClassHistogram\f[R] -Enables printing of a class instance histogram after one of the -following events: -.RS -.IP \[bu] 2 -\f[B]Non-Windows:\f[R] \f[V]Control+\[rs]\f[R] (\f[V]SIGQUIT\f[R]) -.IP \[bu] 2 -\f[B]Windows:\f[R] \f[V]Control+C\f[R] (\f[V]SIGTERM\f[R]) -.PP -By default, this option is disabled. -.PP -Setting this option is equivalent to running the \f[V]jmap -histo\f[R] -command, or the \f[V]jcmd\f[R] \f[I]pid\f[R] -\f[V]GC.class_histogram\f[R] command, where \f[I]pid\f[R] is the current -Java process identifier. -.RE -.TP -\f[V]-XX:+PrintConcurrentLocks\f[R] -Enables printing of \f[V]java.util.concurrent\f[R] locks after one of -the following events: -.RS -.IP \[bu] 2 -\f[B]Non-Windows:\f[R] \f[V]Control+\[rs]\f[R] (\f[V]SIGQUIT\f[R]) -.IP \[bu] 2 -\f[B]Windows:\f[R] \f[V]Control+C\f[R] (\f[V]SIGTERM\f[R]) -.PP -By default, this option is disabled. -.PP -Setting this option is equivalent to running the \f[V]jstack -l\f[R] -command or the \f[V]jcmd\f[R] \f[I]pid\f[R] \f[V]Thread.print -l\f[R] -command, where \f[I]pid\f[R] is the current Java process identifier. -.RE -.TP -\f[V]-XX:+PrintFlagsRanges\f[R] -Prints the range specified and allows automatic testing of the values. -See \f[B]Validate Java Virtual Machine Flag Arguments\f[R]. -.TP -\f[V]-XX:+PerfDataSaveToFile\f[R] -If enabled, saves \f[B]jstat\f[R] binary data when the Java application -exits. -This binary data is saved in a file named -\f[V]hsperfdata_\f[R]\f[I]pid\f[R], where \f[I]pid\f[R] is the process -identifier of the Java application that you ran. -Use the \f[V]jstat\f[R] command to display the performance data -contained in this file as follows: -.RS -.RS -.PP -\f[V]jstat -class file:///\f[R]\f[I]path\f[R]\f[V]/hsperfdata_\f[R]\f[I]pid\f[R] -.RE -.RS -.PP -\f[V]jstat -gc file:///\f[R]\f[I]path\f[R]\f[V]/hsperfdata_\f[R]\f[I]pid\f[R] -.RE -.RE -.TP -\f[V]-XX:+UsePerfData\f[R] -Enables the \f[V]perfdata\f[R] feature. -This option is enabled by default to allow JVM monitoring and -performance testing. -Disabling it suppresses the creation of the \f[V]hsperfdata_userid\f[R] -directories. -To disable the \f[V]perfdata\f[R] feature, specify -\f[V]-XX:-UsePerfData\f[R]. -.SH ADVANCED GARBAGE COLLECTION OPTIONS FOR JAVA -.PP -These \f[V]java\f[R] options control how garbage collection (GC) is -performed by the Java HotSpot VM. -.TP -\f[V]-XX:+AggressiveHeap\f[R] -Enables Java heap optimization. -This sets various parameters to be optimal for long-running jobs with -intensive memory allocation, based on the configuration of the computer -(RAM and CPU). -By default, the option is disabled and the heap sizes are configured -less aggressively. -.TP -\f[V]-XX:+AlwaysPreTouch\f[R] -Requests the VM to touch every page on the Java heap after requesting it -from the operating system and before handing memory out to the -application. -By default, this option is disabled and all pages are committed as the -application uses the heap space. -.TP -\f[V]-XX:ConcGCThreads=\f[R]\f[I]threads\f[R] -Sets the number of threads used for concurrent GC. -Sets \f[I]\f[VI]threads\f[I]\f[R] to approximately 1/4 of the number of -parallel garbage collection threads. -The default value depends on the number of CPUs available to the JVM. -.RS -.PP -For example, to set the number of threads for concurrent GC to 2, -specify the following option: -.RS -.PP -\f[V]-XX:ConcGCThreads=2\f[R] -.RE -.RE -.TP -\f[V]-XX:+DisableExplicitGC\f[R] -Enables the option that disables processing of calls to the -\f[V]System.gc()\f[R] method. -This option is disabled by default, meaning that calls to -\f[V]System.gc()\f[R] are processed. -If processing of calls to \f[V]System.gc()\f[R] is disabled, then the -JVM still performs GC when necessary. -.TP -\f[V]-XX:+ExplicitGCInvokesConcurrent\f[R] -Enables invoking of concurrent GC by using the \f[V]System.gc()\f[R] -request. -This option is disabled by default and can be enabled only with the -\f[V]-XX:+UseG1GC\f[R] option. -.TP -\f[V]-XX:G1AdaptiveIHOPNumInitialSamples=\f[R]\f[I]number\f[R] -When \f[V]-XX:UseAdaptiveIHOP\f[R] is enabled, this option sets the -number of completed marking cycles used to gather samples until G1 -adaptively determines the optimum value of -\f[V]-XX:InitiatingHeapOccupancyPercent\f[R]. -Before, G1 uses the value of -\f[V]-XX:InitiatingHeapOccupancyPercent\f[R] directly for this purpose. -The default value is 3. -.TP -\f[V]-XX:G1HeapRegionSize=\f[R]\f[I]size\f[R] -Sets the size of the regions into which the Java heap is subdivided when -using the garbage-first (G1) collector. -The value is a power of 2 and can range from 1 MB to 32 MB. -The default region size is determined ergonomically based on the heap -size with a goal of approximately 2048 regions. -.RS -.PP -The following example sets the size of the subdivisions to 16 MB: -.RS -.PP -\f[V]-XX:G1HeapRegionSize=16m\f[R] -.RE -.RE -.TP -\f[V]-XX:G1HeapWastePercent=\f[R]\f[I]percent\f[R] -Sets the percentage of heap that you\[aq]re willing to waste. -The Java HotSpot VM doesn\[aq]t initiate the mixed garbage collection -cycle when the reclaimable percentage is less than the heap waste -percentage. -The default is 5 percent. -.TP -\f[V]-XX:G1MaxNewSizePercent=\f[R]\f[I]percent\f[R] -Sets the percentage of the heap size to use as the maximum for the young -generation size. -The default value is 60 percent of your Java heap. -.RS -.PP -This is an experimental flag. -This setting replaces the \f[V]-XX:DefaultMaxNewGenPercent\f[R] setting. -.RE -.TP -\f[V]-XX:G1MixedGCCountTarget=\f[R]\f[I]number\f[R] -Sets the target number of mixed garbage collections after a marking -cycle to collect old regions with at most -\f[V]G1MixedGCLIveThresholdPercent\f[R] live data. -The default is 8 mixed garbage collections. -The goal for mixed collections is to be within this target number. -.TP -\f[V]-XX:G1MixedGCLiveThresholdPercent=\f[R]\f[I]percent\f[R] -Sets the occupancy threshold for an old region to be included in a mixed -garbage collection cycle. -The default occupancy is 85 percent. -.RS -.PP -This is an experimental flag. -This setting replaces the -\f[V]-XX:G1OldCSetRegionLiveThresholdPercent\f[R] setting. -.RE -.TP -\f[V]-XX:G1NewSizePercent=\f[R]\f[I]percent\f[R] -Sets the percentage of the heap to use as the minimum for the young -generation size. -The default value is 5 percent of your Java heap. -.RS -.PP -This is an experimental flag. -This setting replaces the \f[V]-XX:DefaultMinNewGenPercent\f[R] setting. -.RE -.TP -\f[V]-XX:G1OldCSetRegionThresholdPercent=\f[R]\f[I]percent\f[R] -Sets an upper limit on the number of old regions to be collected during -a mixed garbage collection cycle. -The default is 10 percent of the Java heap. -.TP -\f[V]-XX:G1ReservePercent=\f[R]\f[I]percent\f[R] -Sets the percentage of the heap (0 to 50) that\[aq]s reserved as a false -ceiling to reduce the possibility of promotion failure for the G1 -collector. -When you increase or decrease the percentage, ensure that you adjust the -total Java heap by the same amount. -By default, this option is set to 10%. -.RS -.PP -The following example sets the reserved heap to 20%: -.RS -.PP -\f[V]-XX:G1ReservePercent=20\f[R] -.RE -.RE -.TP -\f[V]-XX:+G1UseAdaptiveIHOP\f[R] -Controls adaptive calculation of the old generation occupancy to start -background work preparing for an old generation collection. -If enabled, G1 uses \f[V]-XX:InitiatingHeapOccupancyPercent\f[R] for the -first few times as specified by the value of -\f[V]-XX:G1AdaptiveIHOPNumInitialSamples\f[R], and after that adaptively -calculates a new optimum value for the initiating occupancy -automatically. -Otherwise, the old generation collection process always starts at the -old generation occupancy determined by -\f[V]-XX:InitiatingHeapOccupancyPercent\f[R]. -.RS -.PP -The default is enabled. -.RE -.TP -\f[V]-XX:InitialHeapSize=\f[R]\f[I]size\f[R] -Sets the initial size (in bytes) of the memory allocation pool. -This value must be either 0, or a multiple of 1024 and greater than 1 -MB. -Append the letter \f[V]k\f[R] or \f[V]K\f[R] to indicate kilobytes, -\f[V]m\f[R] or \f[V]M\f[R] to indicate megabytes, or \f[V]g\f[R] or -\f[V]G\f[R] to indicate gigabytes. -The default value is selected at run time based on the system -configuration. -.RS -.PP -The following examples show how to set the size of allocated memory to 6 -MB using various units: -.IP -.nf -\f[CB] --XX:InitialHeapSize=6291456 --XX:InitialHeapSize=6144k --XX:InitialHeapSize=6m -\f[R] -.fi -.PP -If you set this option to 0, then the initial size is set as the sum of -the sizes allocated for the old generation and the young generation. -The size of the heap for the young generation can be set using the -\f[V]-XX:NewSize\f[R] option. -Note that the \f[V]-Xms\f[R] option sets both the minimum and the -initial heap size of the heap. -If \f[V]-Xms\f[R] appears after \f[V]-XX:InitialHeapSize\f[R] on the -command line, then the initial heap size gets set to the value specified -with \f[V]-Xms\f[R]. -.RE -.TP -\f[V]-XX:InitialRAMPercentage=\f[R]\f[I]percent\f[R] -Sets the initial amount of memory that the JVM will use for the Java -heap before applying ergonomics heuristics as a percentage of the -maximum amount determined as described in the \f[V]-XX:MaxRAM\f[R] -option. -The default value is 1.5625 percent. -.RS -.PP -The following example shows how to set the percentage of the initial -amount of memory used for the Java heap: -.RS -.PP -\f[V]-XX:InitialRAMPercentage=5\f[R] -.RE -.RE -.TP -\f[V]-XX:InitialSurvivorRatio=\f[R]\f[I]ratio\f[R] -Sets the initial survivor space ratio used by the throughput garbage -collector (which is enabled by the \f[V]-XX:+UseParallelGC\f[R] option). -Adaptive sizing is enabled by default with the throughput garbage -collector by using the \f[V]-XX:+UseParallelGC\f[R] option, and the -survivor space is resized according to the application behavior, -starting with the initial value. -If adaptive sizing is disabled (using the -\f[V]-XX:-UseAdaptiveSizePolicy\f[R] option), then the -\f[V]-XX:SurvivorRatio\f[R] option should be used to set the size of the -survivor space for the entire execution of the application. -.RS -.PP -The following formula can be used to calculate the initial size of -survivor space (S) based on the size of the young generation (Y), and -the initial survivor space ratio (R): -.RS -.PP -\f[V]S=Y/(R+2)\f[R] -.RE -.PP -The 2 in the equation denotes two survivor spaces. -The larger the value specified as the initial survivor space ratio, the -smaller the initial survivor space size. -.PP -By default, the initial survivor space ratio is set to 8. -If the default value for the young generation space size is used (2 MB), -then the initial size of the survivor space is 0.2 MB. -.PP -The following example shows how to set the initial survivor space ratio -to 4: -.RS -.PP -\f[V]-XX:InitialSurvivorRatio=4\f[R] -.RE -.RE -.TP -\f[V]-XX:InitiatingHeapOccupancyPercent=\f[R]\f[I]percent\f[R] -Sets the percentage of the old generation occupancy (0 to 100) at which -to start the first few concurrent marking cycles for the G1 garbage -collector. -.RS -.PP -By default, the initiating value is set to 45%. -A value of 0 implies nonstop concurrent GC cycles from the beginning -until G1 adaptively sets this value. -.PP -See also the \f[V]-XX:G1UseAdaptiveIHOP\f[R] and -\f[V]-XX:G1AdaptiveIHOPNumInitialSamples\f[R] options. -.PP -The following example shows how to set the initiating heap occupancy to -75%: -.RS -.PP -\f[V]-XX:InitiatingHeapOccupancyPercent=75\f[R] -.RE -.RE -.TP -\f[V]-XX:MaxGCPauseMillis=\f[R]\f[I]time\f[R] -Sets a target for the maximum GC pause time (in milliseconds). -This is a soft goal, and the JVM will make its best effort to achieve -it. -The specified value doesn\[aq]t adapt to your heap size. -By default, for G1 the maximum pause time target is 200 milliseconds. -The other generational collectors do not use a pause time goal by -default. -.RS -.PP -The following example shows how to set the maximum target pause time to -500 ms: -.RS -.PP -\f[V]-XX:MaxGCPauseMillis=500\f[R] -.RE -.RE -.TP -\f[V]-XX:MaxHeapSize=\f[R]\f[I]size\f[R] -Sets the maximum size (in byes) of the memory allocation pool. -This value must be a multiple of 1024 and greater than 2 MB. -Append the letter \f[V]k\f[R] or \f[V]K\f[R] to indicate kilobytes, -\f[V]m\f[R] or \f[V]M\f[R] to indicate megabytes, or \f[V]g\f[R] or -\f[V]G\f[R] to indicate gigabytes. -The default value is selected at run time based on the system -configuration. -For server deployments, the options \f[V]-XX:InitialHeapSize\f[R] and -\f[V]-XX:MaxHeapSize\f[R] are often set to the same value. -.RS -.PP -The following examples show how to set the maximum allowed size of -allocated memory to 80 MB using various units: -.IP -.nf -\f[CB] --XX:MaxHeapSize=83886080 --XX:MaxHeapSize=81920k --XX:MaxHeapSize=80m -\f[R] -.fi -.PP -The \f[V]-XX:MaxHeapSize\f[R] option is equivalent to \f[V]-Xmx\f[R]. -.RE -.TP -\f[V]-XX:MaxHeapFreeRatio=\f[R]\f[I]percent\f[R] -Sets the maximum allowed percentage of free heap space (0 to 100) after -a GC event. -If free heap space expands above this value, then the heap is shrunk. -By default, this value is set to 70%. -.RS -.PP -Minimize the Java heap size by lowering the values of the parameters -\f[V]MaxHeapFreeRatio\f[R] (default value is 70%) and -\f[V]MinHeapFreeRatio\f[R] (default value is 40%) with the command-line -options \f[V]-XX:MaxHeapFreeRatio\f[R] and -\f[V]-XX:MinHeapFreeRatio\f[R]. -Lowering \f[V]MaxHeapFreeRatio\f[R] to as low as 10% and -\f[V]MinHeapFreeRatio\f[R] to 5% has successfully reduced the heap size -without too much performance regression; however, results may vary -greatly depending on your application. -Try different values for these parameters until they\[aq]re as low as -possible yet still retain acceptable performance. -.RS -.PP -\f[V]-XX:MaxHeapFreeRatio=10 -XX:MinHeapFreeRatio=5\f[R] -.RE -.PP -Customers trying to keep the heap small should also add the option -\f[V]-XX:-ShrinkHeapInSteps\f[R]. -See \f[B]Performance Tuning Examples\f[R] for a description of using -this option to keep the Java heap small by reducing the dynamic -footprint for embedded applications. -.RE -.TP -\f[V]-XX:MaxMetaspaceSize=\f[R]\f[I]size\f[R] -Sets the maximum amount of native memory that can be allocated for class -metadata. -By default, the size isn\[aq]t limited. -The amount of metadata for an application depends on the application -itself, other running applications, and the amount of memory available -on the system. -.RS -.PP -The following example shows how to set the maximum class metadata size -to 256 MB: -.RS -.PP -\f[V]-XX:MaxMetaspaceSize=256m\f[R] -.RE -.RE -.TP -\f[V]-XX:MaxNewSize=\f[R]\f[I]size\f[R] -Sets the maximum size (in bytes) of the heap for the young generation -(nursery). -The default value is set ergonomically. -.TP -\f[V]-XX:MaxRAM=\f[R]\f[I]size\f[R] -Sets the maximum amount of memory that the JVM may use for the Java heap -before applying ergonomics heuristics. -The default value is the maximum amount of available memory to the JVM -process or 128 GB, whichever is lower. -.RS -.PP -The maximum amount of available memory to the JVM process is the minimum -of the machine\[aq]s physical memory and any constraints set by the -environment (e.g. -container). -.PP -Specifying this option disables automatic use of compressed oops if the -combined result of this and other options influencing the maximum amount -of memory is larger than the range of memory addressable by compressed -oops. -See \f[V]-XX:UseCompressedOops\f[R] for further information about -compressed oops. -.PP -The following example shows how to set the maximum amount of available -memory for sizing the Java heap to 2 GB: -.RS -.PP -\f[V]-XX:MaxRAM=2G\f[R] -.RE -.RE -.TP -\f[V]-XX:MaxRAMPercentage=\f[R]\f[I]percent\f[R] -Sets the maximum amount of memory that the JVM may use for the Java heap -before applying ergonomics heuristics as a percentage of the maximum -amount determined as described in the \f[V]-XX:MaxRAM\f[R] option. -The default value is 25 percent. -.RS -.PP -Specifying this option disables automatic use of compressed oops if the -combined result of this and other options influencing the maximum amount -of memory is larger than the range of memory addressable by compressed -oops. -See \f[V]-XX:UseCompressedOops\f[R] for further information about -compressed oops. -.PP -The following example shows how to set the percentage of the maximum -amount of memory used for the Java heap: -.RS -.PP -\f[V]-XX:MaxRAMPercentage=75\f[R] -.RE -.RE -.TP -\f[V]-XX:MinRAMPercentage=\f[R]\f[I]percent\f[R] -Sets the maximum amount of memory that the JVM may use for the Java heap -before applying ergonomics heuristics as a percentage of the maximum -amount determined as described in the \f[V]-XX:MaxRAM\f[R] option for -small heaps. -A small heap is a heap of approximately 125 MB. -The default value is 50 percent. -.RS -.PP -The following example shows how to set the percentage of the maximum -amount of memory used for the Java heap for small heaps: -.RS -.PP -\f[V]-XX:MinRAMPercentage=75\f[R] -.RE -.RE -.TP -\f[V]-XX:MaxTenuringThreshold=\f[R]\f[I]threshold\f[R] -Sets the maximum tenuring threshold for use in adaptive GC sizing. -The largest value is 15. -The default value is 15 for the parallel (throughput) collector. -.RS -.PP -The following example shows how to set the maximum tenuring threshold to -10: -.RS -.PP -\f[V]-XX:MaxTenuringThreshold=10\f[R] -.RE -.RE -.TP -\f[V]-XX:MetaspaceSize=\f[R]\f[I]size\f[R] -Sets the size of the allocated class metadata space that triggers a -garbage collection the first time it\[aq]s exceeded. -This threshold for a garbage collection is increased or decreased -depending on the amount of metadata used. -The default size depends on the platform. -.TP -\f[V]-XX:MinHeapFreeRatio=\f[R]\f[I]percent\f[R] -Sets the minimum allowed percentage of free heap space (0 to 100) after -a GC event. -If free heap space falls below this value, then the heap is expanded. -By default, this value is set to 40%. -.RS -.PP -Minimize Java heap size by lowering the values of the parameters -\f[V]MaxHeapFreeRatio\f[R] (default value is 70%) and -\f[V]MinHeapFreeRatio\f[R] (default value is 40%) with the command-line -options \f[V]-XX:MaxHeapFreeRatio\f[R] and -\f[V]-XX:MinHeapFreeRatio\f[R]. -Lowering \f[V]MaxHeapFreeRatio\f[R] to as low as 10% and -\f[V]MinHeapFreeRatio\f[R] to 5% has successfully reduced the heap size -without too much performance regression; however, results may vary -greatly depending on your application. -Try different values for these parameters until they\[aq]re as low as -possible, yet still retain acceptable performance. -.RS -.PP -\f[V]-XX:MaxHeapFreeRatio=10 -XX:MinHeapFreeRatio=5\f[R] -.RE -.PP -Customers trying to keep the heap small should also add the option -\f[V]-XX:-ShrinkHeapInSteps\f[R]. -See \f[B]Performance Tuning Examples\f[R] for a description of using -this option to keep the Java heap small by reducing the dynamic -footprint for embedded applications. -.RE -.TP -\f[V]-XX:MinHeapSize=\f[R]\f[I]size\f[R] -Sets the minimum size (in bytes) of the memory allocation pool. -This value must be either 0, or a multiple of 1024 and greater than 1 -MB. -Append the letter \f[V]k\f[R] or \f[V]K\f[R] to indicate kilobytes, -\f[V]m\f[R] or \f[V]M\f[R] to indicate megabytes, or \f[V]g\f[R] or -\f[V]G\f[R] to indicate gigabytes. -The default value is selected at run time based on the system -configuration. -.RS -.PP -The following examples show how to set the minimum size of allocated -memory to 6 MB using various units: -.IP -.nf -\f[CB] --XX:MinHeapSize=6291456 --XX:MinHeapSize=6144k --XX:MinHeapSize=6m -\f[R] -.fi -.PP -If you set this option to 0, then the minimum size is set to the same -value as the initial size. -.RE -.TP -\f[V]-XX:NewRatio=\f[R]\f[I]ratio\f[R] -Sets the ratio between young and old generation sizes. -By default, this option is set to 2. -The following example shows how to set the young-to-old ratio to 1: -.RS -.RS -.PP -\f[V]-XX:NewRatio=1\f[R] -.RE -.RE -.TP -\f[V]-XX:NewSize=\f[R]\f[I]size\f[R] -Sets the initial size (in bytes) of the heap for the young generation -(nursery). -Append the letter \f[V]k\f[R] or \f[V]K\f[R] to indicate kilobytes, -\f[V]m\f[R] or \f[V]M\f[R] to indicate megabytes, or \f[V]g\f[R] or -\f[V]G\f[R] to indicate gigabytes. -.RS -.PP -The young generation region of the heap is used for new objects. -GC is performed in this region more often than in other regions. -If the size for the young generation is too low, then a large number of -minor GCs are performed. -If the size is too high, then only full GCs are performed, which can -take a long time to complete. -It is recommended that you keep the size for the young generation -greater than 25% and less than 50% of the overall heap size. -.PP -The following examples show how to set the initial size of the young -generation to 256 MB using various units: -.IP -.nf -\f[CB] --XX:NewSize=256m --XX:NewSize=262144k --XX:NewSize=268435456 -\f[R] -.fi -.PP -The \f[V]-XX:NewSize\f[R] option is equivalent to \f[V]-Xmn\f[R]. -.RE -.TP -\f[V]-XX:ParallelGCThreads=\f[R]\f[I]threads\f[R] -Sets the number of the stop-the-world (STW) worker threads. -The default value depends on the number of CPUs available to the JVM and -the garbage collector selected. -.RS -.PP -For example, to set the number of threads for G1 GC to 2, specify the -following option: -.RS -.PP -\f[V]-XX:ParallelGCThreads=2\f[R] -.RE -.RE -.TP -\f[V]-XX:+ParallelRefProcEnabled\f[R] -Enables parallel reference processing. -By default, this option is disabled. -.TP -\f[V]-XX:+PrintAdaptiveSizePolicy\f[R] -Enables printing of information about adaptive-generation sizing. -By default, this option is disabled. -.TP -\f[V]-XX:SoftRefLRUPolicyMSPerMB=\f[R]\f[I]time\f[R] -Sets the amount of time (in milliseconds) a softly reachable object is -kept active on the heap after the last time it was referenced. -The default value is one second of lifetime per free megabyte in the -heap. -The \f[V]-XX:SoftRefLRUPolicyMSPerMB\f[R] option accepts integer values -representing milliseconds per one megabyte of the current heap size (for -Java HotSpot Client VM) or the maximum possible heap size (for Java -HotSpot Server VM). -This difference means that the Client VM tends to flush soft references -rather than grow the heap, whereas the Server VM tends to grow the heap -rather than flush soft references. -In the latter case, the value of the \f[V]-Xmx\f[R] option has a -significant effect on how quickly soft references are garbage collected. -.RS -.PP -The following example shows how to set the value to 2.5 seconds: -.PP -\f[V]-XX:SoftRefLRUPolicyMSPerMB=2500\f[R] -.RE -.TP -\f[V]-XX:-ShrinkHeapInSteps\f[R] -Incrementally reduces the Java heap to the target size, specified by the -option \f[V]-XX:MaxHeapFreeRatio\f[R]. -This option is enabled by default. -If disabled, then it immediately reduces the Java heap to the target -size instead of requiring multiple garbage collection cycles. -Disable this option if you want to minimize the Java heap size. -You will likely encounter performance degradation when this option is -disabled. -.RS -.PP -See \f[B]Performance Tuning Examples\f[R] for a description of using the -\f[V]MaxHeapFreeRatio\f[R] option to keep the Java heap small by -reducing the dynamic footprint for embedded applications. -.RE -.TP -\f[V]-XX:StringDeduplicationAgeThreshold=\f[R]\f[I]threshold\f[R] -Identifies \f[V]String\f[R] objects reaching the specified age that are -considered candidates for deduplication. -An object\[aq]s age is a measure of how many times it has survived -garbage collection. -This is sometimes referred to as tenuring. -.RS -.RS -.PP -\f[B]Note:\f[R] \f[V]String\f[R] objects that are promoted to an old -heap region before this age has been reached are always considered -candidates for deduplication. -The default value for this option is \f[V]3\f[R]. -See the \f[V]-XX:+UseStringDeduplication\f[R] option. -.RE -.RE -.TP -\f[V]-XX:SurvivorRatio=\f[R]\f[I]ratio\f[R] -Sets the ratio between eden space size and survivor space size. -By default, this option is set to 8. -The following example shows how to set the eden/survivor space ratio to -4: -.RS -.RS -.PP -\f[V]-XX:SurvivorRatio=4\f[R] -.RE -.RE -.TP -\f[V]-XX:TargetSurvivorRatio=\f[R]\f[I]percent\f[R] -Sets the desired percentage of survivor space (0 to 100) used after -young garbage collection. -By default, this option is set to 50%. -.RS -.PP -The following example shows how to set the target survivor space ratio -to 30%: -.RS -.PP -\f[V]-XX:TargetSurvivorRatio=30\f[R] -.RE -.RE -.TP -\f[V]-XX:TLABSize=\f[R]\f[I]size\f[R] -Sets the initial size (in bytes) of a thread-local allocation buffer -(TLAB). -Append the letter \f[V]k\f[R] or \f[V]K\f[R] to indicate kilobytes, -\f[V]m\f[R] or \f[V]M\f[R] to indicate megabytes, or \f[V]g\f[R] or -\f[V]G\f[R] to indicate gigabytes. -If this option is set to 0, then the JVM selects the initial size -automatically. -.RS -.PP -The following example shows how to set the initial TLAB size to 512 KB: -.RS -.PP -\f[V]-XX:TLABSize=512k\f[R] -.RE -.RE -.TP -\f[V]-XX:+UseAdaptiveSizePolicy\f[R] -Enables the use of adaptive generation sizing. -This option is enabled by default. -To disable adaptive generation sizing, specify -\f[V]-XX:-UseAdaptiveSizePolicy\f[R] and set the size of the memory -allocation pool explicitly. -See the \f[V]-XX:SurvivorRatio\f[R] option. -.TP -\f[V]-XX:+UseG1GC\f[R] -Enables the use of the garbage-first (G1) garbage collector. -It\[aq]s a server-style garbage collector, targeted for multiprocessor -machines with a large amount of RAM. -This option meets GC pause time goals with high probability, while -maintaining good throughput. -The G1 collector is recommended for applications requiring large heaps -(sizes of around 6 GB or larger) with limited GC latency requirements (a -stable and predictable pause time below 0.5 seconds). -By default, this option is enabled and G1 is used as the default garbage -collector. -.TP -\f[V]-XX:+UseGCOverheadLimit\f[R] -Enables the use of a policy that limits the proportion of time spent by -the JVM on GC before an \f[V]OutOfMemoryError\f[R] exception is thrown. -This option is enabled, by default, and the parallel GC will throw an -\f[V]OutOfMemoryError\f[R] if more than 98% of the total time is spent -on garbage collection and less than 2% of the heap is recovered. -When the heap is small, this feature can be used to prevent applications -from running for long periods of time with little or no progress. -To disable this option, specify the option -\f[V]-XX:-UseGCOverheadLimit\f[R]. -.TP -\f[V]-XX:+UseNUMA\f[R] -Enables performance optimization of an application on a machine with -nonuniform memory architecture (NUMA) by increasing the -application\[aq]s use of lower latency memory. -By default, this option is disabled and no optimization for NUMA is -made. -The option is available only when the parallel garbage collector is used -(\f[V]-XX:+UseParallelGC\f[R]). -.TP -\f[V]-XX:+UseParallelGC\f[R] -Enables the use of the parallel scavenge garbage collector (also known -as the throughput collector) to improve the performance of your -application by leveraging multiple processors. -.RS -.PP -By default, this option is disabled and the default collector is used. -.RE -.TP -\f[V]-XX:+UseSerialGC\f[R] -Enables the use of the serial garbage collector. -This is generally the best choice for small and simple applications that -don\[aq]t require any special functionality from garbage collection. -By default, this option is disabled and the default collector is used. -.TP -\f[V]-XX:+UseStringDeduplication\f[R] -Enables string deduplication. -By default, this option is disabled. -To use this option, you must enable the garbage-first (G1) garbage -collector. -.RS -.PP -String deduplication reduces the memory footprint of \f[V]String\f[R] -objects on the Java heap by taking advantage of the fact that many -\f[V]String\f[R] objects are identical. -Instead of each \f[V]String\f[R] object pointing to its own character -array, identical \f[V]String\f[R] objects can point to and share the -same character array. -.RE -.TP -\f[V]-XX:+UseTLAB\f[R] -Enables the use of thread-local allocation blocks (TLABs) in the young -generation space. -This option is enabled by default. -To disable the use of TLABs, specify the option \f[V]-XX:-UseTLAB\f[R]. -.TP -\f[V]-XX:+UseZGC\f[R] -Enables the use of the Z garbage collector (ZGC). -This is a low latency garbage collector, providing max pause times of a -few milliseconds, at some throughput cost. -Pause times are independent of what heap size is used. -Supports heap sizes from 8MB to 16TB. -.TP -\f[V]-XX:ZAllocationSpikeTolerance=\f[R]\f[I]factor\f[R] -Sets the allocation spike tolerance for ZGC. -By default, this option is set to 2.0. -This factor describes the level of allocation spikes to expect. -For example, using a factor of 3.0 means the current allocation rate can -be expected to triple at any time. -.TP -\f[V]-XX:ZCollectionInterval=\f[R]\f[I]seconds\f[R] -Sets the maximum interval (in seconds) between two GC cycles when using -ZGC. -By default, this option is set to 0 (disabled). -.TP -\f[V]-XX:ZFragmentationLimit=\f[R]\f[I]percent\f[R] -Sets the maximum acceptable heap fragmentation (in percent) for ZGC. -By default, this option is set to 25. -Using a lower value will cause the heap to be compacted more -aggressively, to reclaim more memory at the cost of using more CPU time. -.TP -\f[V]-XX:+ZProactive\f[R] -Enables proactive GC cycles when using ZGC. -By default, this option is enabled. -ZGC will start a proactive GC cycle if doing so is expected to have -minimal impact on the running application. -This is useful if the application is mostly idle or allocates very few -objects, but you still want to keep the heap size down and allow -reference processing to happen even when there are a lot of free space -on the heap. -.TP -\f[V]-XX:+ZUncommit\f[R] -Enables uncommitting of unused heap memory when using ZGC. -By default, this option is enabled. -Uncommitting unused heap memory will lower the memory footprint of the -JVM, and make that memory available for other processes to use. -.TP -\f[V]-XX:ZUncommitDelay=\f[R]\f[I]seconds\f[R] -Sets the amount of time (in seconds) that heap memory must have been -unused before being uncommitted. -By default, this option is set to 300 (5 minutes). -Committing and uncommitting memory are relatively expensive operations. -Using a lower value will cause heap memory to be uncommitted earlier, at -the risk of soon having to commit it again. -.SH DEPRECATED JAVA OPTIONS -.PP -These \f[V]java\f[R] options are deprecated and might be removed in a -future JDK release. -They\[aq]re still accepted and acted upon, but a warning is issued when -they\[aq]re used. -.TP -\f[V]-Xloggc:\f[R]\f[I]filename\f[R] -Sets the file to which verbose GC events information should be -redirected for logging. -The \f[V]-Xloggc\f[R] option overrides \f[V]-verbose:gc\f[R] if both are -given with the same java command. -\f[V]-Xloggc:\f[R]\f[I]filename\f[R] is replaced by -\f[V]-Xlog:gc:\f[R]\f[I]filename\f[R]. -See Enable Logging with the JVM Unified Logging Framework. -.RS -.PP -Example: -.PP -\f[V]-Xlog:gc:garbage-collection.log\f[R] -.RE -.TP -\f[V]-XX:+FlightRecorder\f[R] -Enables the use of Java Flight Recorder (JFR) during the runtime of the -application. -Since JDK 8u40 this option has not been required to use JFR. -.SH OBSOLETE JAVA OPTIONS -.PP -These \f[V]java\f[R] options are still accepted but ignored, and a -warning is issued when they\[aq]re used. -.TP -\f[V]--illegal-access=\f[R]\f[I]parameter\f[R] -Controlled \f[I]relaxed strong encapsulation\f[R], as defined in -\f[B]JEP 261\f[R] -[https://openjdk.org/jeps/261#Relaxed-strong-encapsulation]. -This option was deprecated in JDK 16 by \f[B]JEP 396\f[R] -[https://openjdk.org/jeps/396] and made obsolete in JDK 17 by \f[B]JEP -403\f[R] [https://openjdk.org/jeps/403]. -.TP -\f[V]-XX:RTMAbortRatio=\f[R]\f[I]abort_ratio\f[R] -Specifies the RTM abort ratio is specified as a percentage (%) of all -executed RTM transactions. -If a number of aborted transactions becomes greater than this ratio, -then the compiled code is deoptimized. -This ratio is used when the \f[V]-XX:+UseRTMDeopt\f[R] option is -enabled. -The default value of this option is 50. -This means that the compiled code is deoptimized if 50% of all -transactions are aborted. -.TP -\f[V]-XX:RTMRetryCount=\f[R]\f[I]number_of_retries\f[R] -Specifies the number of times that the RTM locking code is retried, when -it is aborted or busy, before falling back to the normal locking -mechanism. -The default value for this option is 5. -The \f[V]-XX:UseRTMLocking\f[R] option must be enabled. -.TP -\f[V]-XX:+UseRTMDeopt\f[R] -Autotunes RTM locking depending on the abort ratio. -This ratio is specified by the \f[V]-XX:RTMAbortRatio\f[R] option. -If the number of aborted transactions exceeds the abort ratio, then the -method containing the lock is deoptimized and recompiled with all locks -as normal locks. -This option is disabled by default. -The \f[V]-XX:+UseRTMLocking\f[R] option must be enabled. -.TP -\f[V]-XX:+UseRTMLocking\f[R] -Generates Restricted Transactional Memory (RTM) locking code for all -inflated locks, with the normal locking mechanism as the fallback -handler. -This option is disabled by default. -Options related to RTM are available only on x86 CPUs that support -Transactional Synchronization Extensions (TSX). -.RS -.PP -RTM is part of Intel\[aq]s TSX, which is an x86 instruction set -extension and facilitates the creation of multithreaded applications. -RTM introduces the new instructions \f[V]XBEGIN\f[R], \f[V]XABORT\f[R], -\f[V]XEND\f[R], and \f[V]XTEST\f[R]. -The \f[V]XBEGIN\f[R] and \f[V]XEND\f[R] instructions enclose a set of -instructions to run as a transaction. -If no conflict is found when running the transaction, then the memory -and register modifications are committed together at the \f[V]XEND\f[R] -instruction. -The \f[V]XABORT\f[R] instruction can be used to explicitly abort a -transaction and the \f[V]XTEST\f[R] instruction checks if a set of -instructions is being run in a transaction. -.PP -A lock on a transaction is inflated when another thread tries to access -the same transaction, thereby blocking the thread that didn\[aq]t -originally request access to the transaction. -RTM requires that a fallback set of operations be specified in case a -transaction aborts or fails. -An RTM lock is a lock that has been delegated to the TSX\[aq]s system. -.PP -RTM improves performance for highly contended locks with low conflict in -a critical region (which is code that must not be accessed by more than -one thread concurrently). -RTM also improves the performance of coarse-grain locking, which -typically doesn\[aq]t perform well in multithreaded applications. -(Coarse-grain locking is the strategy of holding locks for long periods -to minimize the overhead of taking and releasing locks, while -fine-grained locking is the strategy of trying to achieve maximum -parallelism by locking only when necessary and unlocking as soon as -possible.) -Also, for lightly contended locks that are used by different threads, -RTM can reduce false cache line sharing, also known as cache line -ping-pong. -This occurs when multiple threads from different processors are -accessing different resources, but the resources share the same cache -line. -As a result, the processors repeatedly invalidate the cache lines of -other processors, which forces them to read from main memory instead of -their cache. -.RE -.SH REMOVED JAVA OPTIONS -.PP -These \f[V]java\f[R] options have been removed in JDK 24 and using them -results in an error of: -.RS -.PP -\f[V]Unrecognized VM option\f[R] \f[I]option-name\f[R] -.RE -.TP -\f[V]-XX:InitialRAMFraction=\f[R]\f[I]ratio\f[R] -Sets the initial amount of memory that the JVM may use for the Java heap -before applying ergonomics heuristics as a ratio of the maximum amount -determined as described in the \f[V]-XX:MaxRAM\f[R] option. -The default value is 64. -.RS -.PP -Use the option \f[V]-XX:InitialRAMPercentage\f[R] instead. -.RE -.TP -\f[V]-XX:MaxRAMFraction=\f[R]\f[I]ratio\f[R] -Sets the maximum amount of memory that the JVM may use for the Java heap -before applying ergonomics heuristics as a fraction of the maximum -amount determined as described in the \f[V]-XX:MaxRAM\f[R] option. -The default value is 4. -.RS -.PP -Specifying this option disables automatic use of compressed oops if the -combined result of this and other options influencing the maximum amount -of memory is larger than the range of memory addressable by compressed -oops. -See \f[V]-XX:UseCompressedOops\f[R] for further information about -compressed oops. -.PP -Use the option \f[V]-XX:MaxRAMPercentage\f[R] instead. -.RE -.TP -\f[V]-XX:MinRAMFraction=\f[R]\f[I]ratio\f[R] -Sets the maximum amount of memory that the JVM may use for the Java heap -before applying ergonomics heuristics as a fraction of the maximum -amount determined as described in the \f[V]-XX:MaxRAM\f[R] option for -small heaps. -A small heap is a heap of approximately 125 MB. -The default value is 2. -.RS -.PP -Use the option \f[V]-XX:MinRAMPercentage\f[R] instead. -.RE -.TP -\f[V]-XX:+ScavengeBeforeFullGC\f[R] -Enables GC of the young generation before each full GC. -This option is enabled by default. -It is recommended that you \f[I]don\[aq]t\f[R] disable it, because -scavenging the young generation before a full GC can reduce the number -of objects reachable from the old generation space into the young -generation space. -To disable GC of the young generation before each full GC, specify the -option \f[V]-XX:-ScavengeBeforeFullGC\f[R]. -.TP -\f[V]-Xfuture\f[R] -Enables strict class-file format checks that enforce close conformance -to the class-file format specification. -Developers should use this flag when developing new code. -Stricter checks may become the default in future releases. -.RS -.PP -Use the option \f[V]-Xverify:all\f[R] instead. -.RE -.PP -For the lists and descriptions of options removed in previous releases -see the \f[I]Removed Java Options\f[R] section in: -.IP \[bu] 2 -\f[B]The \f[VB]java\f[B] Command, Release 23\f[R] -[https://docs.oracle.com/en/java/javase/23/docs/specs/man/java.html] -.IP \[bu] 2 -\f[B]The \f[VB]java\f[B] Command, Release 22\f[R] -[https://docs.oracle.com/en/java/javase/22/docs/specs/man/java.html] -.IP \[bu] 2 -\f[B]The \f[VB]java\f[B] Command, Release 21\f[R] -[https://docs.oracle.com/en/java/javase/21/docs/specs/man/java.html] -.IP \[bu] 2 -\f[B]The \f[VB]java\f[B] Command, Release 20\f[R] -[https://docs.oracle.com/en/java/javase/20/docs/specs/man/java.html] -.IP \[bu] 2 -\f[B]The \f[VB]java\f[B] Command, Release 19\f[R] -[https://docs.oracle.com/en/java/javase/19/docs/specs/man/java.html] -.IP \[bu] 2 -\f[B]The \f[VB]java\f[B] Command, Release 18\f[R] -[https://docs.oracle.com/en/java/javase/18/docs/specs/man/java.html] -.IP \[bu] 2 -\f[B]The \f[VB]java\f[B] Command, Release 17\f[R] -[https://docs.oracle.com/en/java/javase/17/docs/specs/man/java.html] -.IP \[bu] 2 -\f[B]The \f[VB]java\f[B] Command, Release 16\f[R] -[https://docs.oracle.com/en/java/javase/16/docs/specs/man/java.html] -.IP \[bu] 2 -\f[B]The \f[VB]java\f[B] Command, Release 15\f[R] -[https://docs.oracle.com/en/java/javase/15/docs/specs/man/java.html] -.IP \[bu] 2 -\f[B]The \f[VB]java\f[B] Command, Release 14\f[R] -[https://docs.oracle.com/en/java/javase/14/docs/specs/man/java.html] -.IP \[bu] 2 -\f[B]The \f[VB]java\f[B] Command, Release 13\f[R] -[https://docs.oracle.com/en/java/javase/13/docs/specs/man/java.html] -.IP \[bu] 2 -\f[B]Java Platform, Standard Edition Tools Reference, Release 12\f[R] -[https://docs.oracle.com/en/java/javase/12/tools/java.html#GUID-3B1CE181-CD30-4178-9602-230B800D4FAE] -.IP \[bu] 2 -\f[B]Java Platform, Standard Edition Tools Reference, Release 11\f[R] -[https://docs.oracle.com/en/java/javase/11/tools/java.html#GUID-741FC470-AA3E-494A-8D2B-1B1FE4A990D1] -.IP \[bu] 2 -\f[B]Java Platform, Standard Edition Tools Reference, Release 10\f[R] -[https://docs.oracle.com/javase/10/tools/java.htm#JSWOR624] -.IP \[bu] 2 -\f[B]Java Platform, Standard Edition Tools Reference, Release 9\f[R] -[https://docs.oracle.com/javase/9/tools/java.htm#JSWOR624] -.IP \[bu] 2 -\f[B]Java Platform, Standard Edition Tools Reference, Release 8 for -Oracle JDK on Windows\f[R] -[https://docs.oracle.com/javase/8/docs/technotes/tools/windows/java.html#BGBCIEFC] -.IP \[bu] 2 -\f[B]Java Platform, Standard Edition Tools Reference, Release 8 for -Oracle JDK on Solaris, Linux, and macOS\f[R] -[https://docs.oracle.com/javase/8/docs/technotes/tools/unix/java.html#BGBCIEFC] -.SH JAVA COMMAND-LINE ARGUMENT FILES -.PP -You can shorten or simplify the \f[V]java\f[R] command by using -\f[V]\[at]\f[R] argument files to specify one or more text files that -contain arguments, such as options and class names, which are passed to -the \f[V]java\f[R] command. -This let\[aq]s you to create \f[V]java\f[R] commands of any length on -any operating system. -.PP -In the command line, use the at sign (\f[V]\[at]\f[R]) prefix to -identify an argument file that contains \f[V]java\f[R] options and class -names. -When the \f[V]java\f[R] command encounters a file beginning with the at -sign (\f[V]\[at]\f[R]), it expands the contents of that file into an -argument list just as they would be specified on the command line. -.PP -The \f[V]java\f[R] launcher expands the argument file contents until it -encounters the \f[V]--disable-\[at]files\f[R] option. -You can use the \f[V]--disable-\[at]files\f[R] option anywhere on the -command line, including in an argument file, to stop \f[V]\[at]\f[R] -argument files expansion. -.PP -The following items describe the syntax of \f[V]java\f[R] argument -files: -.IP \[bu] 2 -The argument file must contain only ASCII characters or characters in -system default encoding that\[aq]s ASCII friendly, such as UTF-8. -.IP \[bu] 2 -The argument file size must not exceed MAXINT (2,147,483,647) bytes. -.IP \[bu] 2 -The launcher doesn\[aq]t expand wildcards that are present within an -argument file. -.IP \[bu] 2 -Use white space or new line characters to separate arguments included in -the file. -.IP \[bu] 2 -White space includes a white space character, \f[V]\[rs]t\f[R], -\f[V]\[rs]n\f[R], \f[V]\[rs]r\f[R], and \f[V]\[rs]f\f[R]. -.RS 2 -.PP -For example, it is possible to have a path with a space, such as -\f[V]c:\[rs]Program Files\f[R] that can be specified as either -\f[V]\[dq]c:\[rs]\[rs]Program Files\[dq]\f[R] or, to avoid an escape, -\f[V]c:\[rs]Program\[dq] \[dq]Files\f[R]. -.RE -.IP \[bu] 2 -Any option that contains spaces, such as a path component, must be -within quotation marks using quotation (\[aq]\[dq]\[aq]) characters in -its entirety. -.IP \[bu] 2 -A string within quotation marks may contain the characters -\f[V]\[rs]n\f[R], \f[V]\[rs]r\f[R], \f[V]\[rs]t\f[R], and -\f[V]\[rs]f\f[R]. -They are converted to their respective ASCII codes. -.IP \[bu] 2 -If a file name contains embedded spaces, then put the whole file name in -double quotation marks. -.IP \[bu] 2 -File names in an argument file are relative to the current directory, -not to the location of the argument file. -.IP \[bu] 2 -Use the number sign \f[V]#\f[R] in the argument file to identify -comments. -All characters following the \f[V]#\f[R] are ignored until the end of -line. -.IP \[bu] 2 -Additional at sign \f[V]\[at]\f[R] prefixes to \f[V]\[at]\f[R] prefixed -options act as an escape, (the first \f[V]\[at]\f[R] is removed and the -rest of the arguments are presented to the launcher literally). -.IP \[bu] 2 -Lines may be continued using the continuation character -(\f[V]\[rs]\f[R]) at the end-of-line. -The two lines are concatenated with the leading white spaces trimmed. -To prevent trimming the leading white spaces, a continuation character -(\f[V]\[rs]\f[R]) may be placed at the first column. -.IP \[bu] 2 -Because backslash (\[rs]) is an escape character, a backslash character -must be escaped with another backslash character. -.IP \[bu] 2 -Partial quote is allowed and is closed by an end-of-file. -.IP \[bu] 2 -An open quote stops at end-of-line unless \f[V]\[rs]\f[R] is the last -character, which then joins the next line by removing all leading white -space characters. -.IP \[bu] 2 -Wildcards (*) aren\[aq]t allowed in these lists (such as specifying -\f[V]*.java\f[R]). -.IP \[bu] 2 -Use of the at sign (\f[V]\[at]\f[R]) to recursively interpret files -isn\[aq]t supported. -.SS Example of Open or Partial Quotes in an Argument File -.PP -In the argument file, -.IP -.nf -\f[CB] --cp \[dq]lib/ -cool/ -app/ -jars -\f[R] -.fi -.PP -this is interpreted as: -.RS -.PP -\f[V]-cp lib/cool/app/jars\f[R] -.RE -.SS Example of a Backslash Character Escaped with Another Backslash Character in an Argument File -.PP -To output the following: -.RS -.PP -\f[V]-cp c:\[rs]Program Files (x86)\[rs]Java\[rs]jre\[rs]lib\[rs]ext;c:\[rs]Program Files\[rs]Java\[rs]jre9\[rs]lib\[rs]ext\f[R] -.RE -.PP -The backslash character must be specified in the argument file as: -.RS -.PP -\f[V]-cp \[dq]c:\[rs]\[rs]Program Files (x86)\[rs]\[rs]Java\[rs]\[rs]jre\[rs]\[rs]lib\[rs]\[rs]ext;c:\[rs]\[rs]Program Files\[rs]\[rs]Java\[rs]\[rs]jre9\[rs]\[rs]lib\[rs]\[rs]ext\[dq]\f[R] -.RE -.SS Example of an EOL Escape Used to Force Concatenation of Lines in an Argument File -.PP -In the argument file, -.IP -.nf -\f[CB] --cp \[dq]/lib/cool app/jars:\[rs] - /lib/another app/jars\[dq] -\f[R] -.fi -.PP -This is interpreted as: -.RS -.PP -\f[V]-cp /lib/cool app/jars:/lib/another app/jars\f[R] -.RE -.SS Example of Line Continuation with Leading Spaces in an Argument File -.PP -In the argument file, -.IP -.nf -\f[CB] --cp \[dq]/lib/cool\[rs] -\[rs]app/jars\[dq] -\f[R] -.fi -.PP -This is interpreted as: -.PP -\f[V]-cp /lib/cool app/jars\f[R] -.SS Examples of Using Single Argument File -.PP -You can use a single argument file, such as \f[V]myargumentfile\f[R] in -the following example, to hold all required \f[V]java\f[R] arguments: -.RS -.PP -\f[V]java \[at]myargumentfile\f[R] -.RE -.SS Examples of Using Argument Files with Paths -.PP -You can include relative paths in argument files; however, they\[aq]re -relative to the current working directory and not to the paths of the -argument files themselves. -In the following example, \f[V]path1/options\f[R] and -\f[V]path2/options\f[R] represent argument files with different paths. -Any relative paths that they contain are relative to the current working -directory and not to the argument files: -.RS -.PP -\f[V]java \[at]path1/options \[at]path2/classes\f[R] -.RE -.SH CODE HEAP STATE ANALYTICS -.SS Overview -.PP -There are occasions when having insight into the current state of the -JVM code heap would be helpful to answer questions such as: -.IP \[bu] 2 -Why was the JIT turned off and then on again and again? -.IP \[bu] 2 -Where has all the code heap space gone? -.IP \[bu] 2 -Why is the method sweeper not working effectively? -.PP -To provide this insight, a code heap state analytics feature has been -implemented that enables on-the-fly analysis of the code heap. -The analytics process is divided into two parts. -The first part examines the entire code heap and aggregates all -information that is believed to be useful or important. -The second part consists of several independent steps that print the -collected information with an emphasis on different aspects of the data. -Data collection and printing are done on an \[dq]on request\[dq] basis. -.SS Syntax -.PP -Requests for real-time, on-the-fly analysis can be issued with the -following command: -.RS -.PP -\f[V]jcmd\f[R] \f[I]pid\f[R] \f[V]Compiler.CodeHeap_Analytics\f[R] -[\f[I]function\f[R]] [\f[I]granularity\f[R]] -.RE -.PP -If you are only interested in how the code heap looks like after running -a sample workload, you can use the command line option: -.RS -.PP -\f[V]-Xlog:codecache=Trace\f[R] -.RE -.PP -To see the code heap state when a \[dq]CodeCache full\[dq] condition -exists, start the VM with the command line option: -.RS -.PP -\f[V]-Xlog:codecache=Debug\f[R] -.RE -.PP -See \f[B]CodeHeap State Analytics (OpenJDK)\f[R] -[https://bugs.openjdk.org/secure/attachment/75649/JVM_CodeHeap_StateAnalytics_V2.pdf] -for a detailed description of the code heap state analytics feature, the -supported functions, and the granularity options. -.SH ENABLE LOGGING WITH THE JVM UNIFIED LOGGING FRAMEWORK -.PP -You use the \f[V]-Xlog\f[R] option to configure or enable logging with -the Java Virtual Machine (JVM) unified logging framework. -.SS Synopsis -.RS -.PP -\f[V]-Xlog\f[R][\f[V]:\f[R][\f[I]what\f[R]][\f[V]:\f[R][\f[I]output\f[R]][\f[V]:\f[R][\f[I]decorators\f[R]][\f[V]:\f[R]\f[I]output-options\f[R][\f[V],\f[R]...]]]]] -.PP -\f[V]-Xlog:\f[R]\f[I]directive\f[R] -.RE -.TP -\f[I]what\f[R] -Specifies a combination of tags and levels of the form -\f[I]tag1\f[R][\f[V]+\f[R]\f[I]tag2\f[R]...][\f[V]*\f[R]][\f[V]=\f[R]\f[I]level\f[R]][\f[V],\f[R]...]. -Unless the wildcard (\f[V]*\f[R]) is specified, only log messages tagged -with exactly the tags specified are matched. -See \f[B]-Xlog Tags and Levels\f[R]. -.TP -\f[I]output\f[R] -Sets the type of output. -Omitting the \f[I]output\f[R] type defaults to \f[V]stdout\f[R]. -See \f[B]-Xlog Output\f[R]. -.TP -\f[I]decorators\f[R] -Configures the output to use a custom set of decorators. -Omitting \f[I]decorators\f[R] defaults to \f[V]uptime\f[R], -\f[V]level\f[R], and \f[V]tags\f[R]. -See \f[B]Decorations\f[R]. -.TP -\f[I]output-options\f[R] -Sets the \f[V]-Xlog\f[R] logging output options. -.TP -\f[I]directive\f[R] -A global option or subcommand: help, disable, async -.SS Description -.PP -The Java Virtual Machine (JVM) unified logging framework provides a -common logging system for all components of the JVM. -GC logging for the JVM has been changed to use the new logging -framework. -The mapping of old GC flags to the corresponding new Xlog configuration -is described in \f[B]Convert GC Logging Flags to Xlog\f[R]. -In addition, runtime logging has also been changed to use the JVM -unified logging framework. -The mapping of legacy runtime logging flags to the corresponding new -Xlog configuration is described in \f[B]Convert Runtime Logging Flags to -Xlog\f[R]. -.PP -The following provides quick reference to the \f[V]-Xlog\f[R] command -and syntax for options: -.TP -\f[V]-Xlog\f[R] -Enables JVM logging on an \f[V]info\f[R] level. -.TP -\f[V]-Xlog:help\f[R] -Prints \f[V]-Xlog\f[R] usage syntax and available tags, levels, and -decorators along with example command lines with explanations. -.TP -\f[V]-Xlog:disable\f[R] -Turns off all logging and clears all configuration of the logging -framework including the default configuration for warnings and errors. -.TP -\f[V]-Xlog\f[R][\f[V]:\f[R]\f[I]option\f[R]] -Applies multiple arguments in the order that they appear on the command -line. -Multiple \f[V]-Xlog\f[R] arguments for the same output override each -other in their given order. -.RS -.PP -The \f[I]option\f[R] is set as: -.RS -.PP -[\f[I]tag-selection\f[R]][\f[V]:\f[R][\f[I]output\f[R]][\f[V]:\f[R][\f[I]decorators\f[R]][\f[V]:\f[R]\f[I]output-options\f[R]]]] -.RE -.PP -Omitting the \f[I]tag-selection\f[R] defaults to a tag-set of -\f[V]all\f[R] and a level of \f[V]info\f[R]. -.RS -.PP -\f[I]tag\f[R][\f[V]+\f[R]...] -\f[V]all\f[R] -.RE -.PP -The \f[V]all\f[R] tag is a meta tag consisting of all tag-sets -available. -The asterisk \f[V]*\f[R] in a tag set definition denotes a wildcard tag -match. -Matching with a wildcard selects all tag sets that contain \f[I]at -least\f[R] the specified tags. -Without the wildcard, only exact matches of the specified tag sets are -selected. -.PP -\f[I]output-options\f[R] is -.RS -.PP -\f[V]filecount=\f[R]\f[I]file-count\f[R] \f[V]filesize=\f[R]\f[I]file -size with optional K, M or G suffix\f[R] -\f[V]foldmultilines=\f[R]\f[I]\f[R] -.RE -.PP -When \f[V]foldmultilines\f[R] is true, a log event that consists of -multiple lines will be folded into a single line by replacing newline -characters with the sequence \f[V]\[aq]\[rs]\[aq]\f[R] and -\f[V]\[aq]n\[aq]\f[R] in the output. -Existing single backslash characters will also be replaced with a -sequence of two backslashes so that the conversion can be reversed. -This option is safe to use with UTF-8 character encodings, but other -encodings may not work. -For example, it may incorrectly convert multi-byte sequences in Shift -JIS and BIG5. -.RE -.SS Default Configuration -.PP -When the \f[V]-Xlog\f[R] option and nothing else is specified on the -command line, the default configuration is used. -The default configuration logs all messages with a level that matches -either warning or error regardless of what tags the message is -associated with. -The default configuration is equivalent to entering the following on the -command line: -.RS -.PP -\f[V]-Xlog:all=warning:stdout:uptime,level,tags\f[R] -.RE -.SS Controlling Logging at Runtime -.PP -Logging can also be controlled at run time through Diagnostic Commands -(with the \f[B]jcmd\f[R] utility). -Everything that can be specified on the command line can also be -specified dynamically with the \f[V]VM.log\f[R] command. -As the diagnostic commands are automatically exposed as MBeans, you can -use JMX to change logging configuration at run time. -.SS -Xlog Tags and Levels -.PP -Each log message has a level and a tag set associated with it. -The level of the message corresponds to its details, and the tag set -corresponds to what the message contains or which JVM component it -involves (such as, \f[V]gc\f[R], \f[V]jit\f[R], or \f[V]os\f[R]). -Mapping GC flags to the Xlog configuration is described in \f[B]Convert -GC Logging Flags to Xlog\f[R]. -Mapping legacy runtime logging flags to the corresponding Xlog -configuration is described in \f[B]Convert Runtime Logging Flags to -Xlog\f[R]. -.PP -\f[B]Available log levels:\f[R] -.IP \[bu] 2 -\f[V]off\f[R] -.IP \[bu] 2 -\f[V]trace\f[R] -.IP \[bu] 2 -\f[V]debug\f[R] -.IP \[bu] 2 -\f[V]info\f[R] -.IP \[bu] 2 -\f[V]warning\f[R] -.IP \[bu] 2 -\f[V]error\f[R] -.PP -\f[B]Available log tags:\f[R] -.PP -There are literally dozens of log tags, which in the right combinations, -will enable a range of logging output. -The full set of available log tags can be seen using -\f[V]-Xlog:help\f[R]. -Specifying \f[V]all\f[R] instead of a tag combination matches all tag -combinations. -.SS -Xlog Output -.PP -The \f[V]-Xlog\f[R] option supports the following types of outputs: -.IP \[bu] 2 -\f[V]stdout\f[R] --- Sends output to stdout -.IP \[bu] 2 -\f[V]stderr\f[R] --- Sends output to stderr -.IP \[bu] 2 -\f[V]file=\f[R]\f[I]filename\f[R] --- Sends output to text file(s). -.PP -When using \f[V]file=\f[R]\f[I]filename\f[R], specifying \f[V]%p\f[R], -\f[V]%t\f[R] and/or \f[V]%hn\f[R] in the file name expands to the -JVM\[aq]s PID, startup timestamp and host name, respectively. -You can also configure text files to handle file rotation based on file -size and a number of files to rotate. -For example, to rotate the log file every 10 MB and keep 5 files in -rotation, specify the options \f[V]filesize=10M, filecount=5\f[R]. -The target size of the files isn\[aq]t guaranteed to be exact, it\[aq]s -just an approximate value. -Files are rotated by default with up to 5 rotated files of target size -20 MB, unless configured otherwise. -Specifying \f[V]filecount=0\f[R] means that the log file shouldn\[aq]t -be rotated. -There\[aq]s a possibility of the pre-existing log file getting -overwritten. -.SS -Xlog Output Mode -.PP -By default logging messages are output synchronously - each log message -is written to the designated output when the logging call is made. -But you can instead use asynchronous logging mode by specifying: -.TP -\f[V]-Xlog:async\f[R] -Write all logging asynchronously. -.PP -In asynchronous logging mode, log sites enqueue all logging messages to -an intermediate buffer and a standalone thread is responsible for -flushing them to the corresponding outputs. -The intermediate buffer is bounded and on buffer exhaustion the -enqueuing message is discarded. -Log entry write operations are guaranteed non-blocking. -.PP -The option \f[V]-XX:AsyncLogBufferSize=N\f[R] specifies the memory -budget in bytes for the intermediate buffer. -The default value should be big enough to cater for most cases. -Users can provide a custom value to trade memory overhead for log -accuracy if they need to. -.SS Decorations -.PP -Logging messages are decorated with information about the message. -You can configure each output to use a custom set of decorators. -The order of the output is always the same as listed in the table. -You can configure the decorations to be used at run time. -Decorations are prepended to the log message. -For example: -.IP -.nf -\f[CB] -[6.567s][info][gc,old] Old collection complete -\f[R] -.fi -.PP -Omitting \f[V]decorators\f[R] defaults to \f[V]uptime\f[R], -\f[V]level\f[R], and \f[V]tags\f[R]. -The \f[V]none\f[R] decorator is special and is used to turn off all -decorations. -.PP -\f[V]time\f[R] (\f[V]t\f[R]), \f[V]utctime\f[R] (\f[V]utc\f[R]), -\f[V]uptime\f[R] (\f[V]u\f[R]), \f[V]timemillis\f[R] (\f[V]tm\f[R]), -\f[V]uptimemillis\f[R] (\f[V]um\f[R]), \f[V]timenanos\f[R] -(\f[V]tn\f[R]), \f[V]uptimenanos\f[R] (\f[V]un\f[R]), \f[V]hostname\f[R] -(\f[V]hn\f[R]), \f[V]pid\f[R] (\f[V]p\f[R]), \f[V]tid\f[R] -(\f[V]ti\f[R]), \f[V]level\f[R] (\f[V]l\f[R]), \f[V]tags\f[R] -(\f[V]tg\f[R]) decorators can also be specified as \f[V]none\f[R] for no -decoration. -.PP -Logging Messages Decorations -.TS -tab(@); -lw(14.9n) lw(55.1n). -T{ -Decorations -T}@T{ -Description -T} -_ -T{ -\f[V]time\f[R] or \f[V]t\f[R] -T}@T{ -Current time and date in ISO-8601 format. -T} -T{ -\f[V]utctime\f[R] or \f[V]utc\f[R] -T}@T{ -Universal Time Coordinated or Coordinated Universal Time. -T} -T{ -\f[V]uptime\f[R] or \f[V]u\f[R] -T}@T{ -Time since the start of the JVM in seconds and milliseconds. -For example, 6.567s. -T} -T{ -\f[V]timemillis\f[R] or \f[V]tm\f[R] -T}@T{ -The same value as generated by \f[V]System.currentTimeMillis()\f[R] -T} -T{ -\f[V]uptimemillis\f[R] or \f[V]um\f[R] -T}@T{ -Milliseconds since the JVM started. -T} -T{ -\f[V]timenanos\f[R] or \f[V]tn\f[R] -T}@T{ -The same value generated by \f[V]System.nanoTime()\f[R]. -T} -T{ -\f[V]uptimenanos\f[R] or \f[V]un\f[R] -T}@T{ -Nanoseconds since the JVM started. -T} -T{ -\f[V]hostname\f[R] or \f[V]hn\f[R] -T}@T{ -The host name. -T} -T{ -\f[V]pid\f[R] or \f[V]p\f[R] -T}@T{ -The process identifier. -T} -T{ -\f[V]tid\f[R] or \f[V]ti\f[R] -T}@T{ -The thread identifier. -T} -T{ -\f[V]level\f[R] or \f[V]l\f[R] -T}@T{ -The level associated with the log message. -T} -T{ -\f[V]tags\f[R] or \f[V]tg\f[R] -T}@T{ -The tag-set associated with the log message. -T} -.TE -.SS Convert GC Logging Flags to Xlog -.PP -Legacy GC Logging Flags to Xlog Configuration Mapping -.TS -tab(@); -lw(22.4n) lw(16.5n) lw(31.2n). -T{ -Legacy Garbage Collection (GC) Flag -T}@T{ -Xlog Configuration -T}@T{ -Comment -T} -_ -T{ -\f[V]G1PrintHeapRegions\f[R] -T}@T{ -\f[V]-Xlog:gc+region=trace\f[R] -T}@T{ -Not Applicable -T} -T{ -\f[V]GCLogFileSize\f[R] -T}@T{ -No configuration available -T}@T{ -Log rotation is handled by the framework. -T} -T{ -\f[V]NumberOfGCLogFiles\f[R] -T}@T{ -Not Applicable -T}@T{ -Log rotation is handled by the framework. -T} -T{ -\f[V]PrintAdaptiveSizePolicy\f[R] -T}@T{ -\f[V]-Xlog:gc+ergo*=\f[R]\f[I]level\f[R] -T}@T{ -Use a \f[I]level\f[R] of \f[V]debug\f[R] for most of the information, or -a \f[I]level\f[R] of \f[V]trace\f[R] for all of what was logged for -\f[V]PrintAdaptiveSizePolicy\f[R]. -T} -T{ -\f[V]PrintGC\f[R] -T}@T{ -\f[V]-Xlog:gc\f[R] -T}@T{ -Not Applicable -T} -T{ -\f[V]PrintGCApplicationConcurrentTime\f[R] -T}@T{ -\f[V]-Xlog:safepoint\f[R] -T}@T{ -Note that \f[V]PrintGCApplicationConcurrentTime\f[R] and -\f[V]PrintGCApplicationStoppedTime\f[R] are logged on the same tag and -aren\[aq]t separated in the new logging. -T} -T{ -\f[V]PrintGCApplicationStoppedTime\f[R] -T}@T{ -\f[V]-Xlog:safepoint\f[R] -T}@T{ -Note that \f[V]PrintGCApplicationConcurrentTime\f[R] and -\f[V]PrintGCApplicationStoppedTime\f[R] are logged on the same tag and -not separated in the new logging. -T} -T{ -\f[V]PrintGCCause\f[R] -T}@T{ -Not Applicable -T}@T{ -GC cause is now always logged. -T} -T{ -\f[V]PrintGCDateStamps\f[R] -T}@T{ -Not Applicable -T}@T{ -Date stamps are logged by the framework. -T} -T{ -\f[V]PrintGCDetails\f[R] -T}@T{ -\f[V]-Xlog:gc*\f[R] -T}@T{ -Not Applicable -T} -T{ -\f[V]PrintGCID\f[R] -T}@T{ -Not Applicable -T}@T{ -GC ID is now always logged. -T} -T{ -\f[V]PrintGCTaskTimeStamps\f[R] -T}@T{ -\f[V]-Xlog:gc+task*=debug\f[R] -T}@T{ -Not Applicable -T} -T{ -\f[V]PrintGCTimeStamps\f[R] -T}@T{ -Not Applicable -T}@T{ -Time stamps are logged by the framework. -T} -T{ -\f[V]PrintHeapAtGC\f[R] -T}@T{ -\f[V]-Xlog:gc+heap=trace\f[R] -T}@T{ -Not Applicable -T} -T{ -\f[V]PrintReferenceGC\f[R] -T}@T{ -\f[V]-Xlog:gc+ref*=debug\f[R] -T}@T{ -Note that in the old logging, \f[V]PrintReferenceGC\f[R] had an effect -only if \f[V]PrintGCDetails\f[R] was also enabled. -T} -T{ -\f[V]PrintStringDeduplicationStatistics\f[R] -T}@T{ -\[ga]-Xlog:gc+stringdedup*=debug -T}@T{ -\[ga] Not Applicable -T} -T{ -\f[V]PrintTenuringDistribution\f[R] -T}@T{ -\f[V]-Xlog:gc+age*=\f[R]\f[I]level\f[R] -T}@T{ -Use a \f[I]level\f[R] of \f[V]debug\f[R] for the most relevant -information, or a \f[I]level\f[R] of \f[V]trace\f[R] for all of what was -logged for \f[V]PrintTenuringDistribution\f[R]. -T} -T{ -\f[V]UseGCLogFileRotation\f[R] -T}@T{ -Not Applicable -T}@T{ -What was logged for \f[V]PrintTenuringDistribution\f[R]. -T} -.TE -.SS Convert Runtime Logging Flags to Xlog -.PP -These legacy flags are no longer recognized and will cause an error if -used directly. -Use their unified logging equivalent instead. -.PP -Runtime Logging Flags to Xlog Configuration Mapping -.TS -tab(@); -lw(15.0n) lw(20.2n) lw(34.7n). -T{ -Legacy Runtime Flag -T}@T{ -Xlog Configuration -T}@T{ -Comment -T} -_ -T{ -\f[V]TraceExceptions\f[R] -T}@T{ -\f[V]-Xlog:exceptions=info\f[R] -T}@T{ -Not Applicable -T} -T{ -\f[V]TraceClassLoading\f[R] -T}@T{ -\f[V]-Xlog:class+load=\f[R]\f[I]level\f[R] -T}@T{ -Use \f[I]level\f[R]=\f[V]info\f[R] for regular information, or -\f[I]level\f[R]=\f[V]debug\f[R] for additional information. -In Unified Logging syntax, \f[V]-verbose:class\f[R] equals -\f[V]-Xlog:class+load=info,class+unload=info\f[R]. -T} -T{ -\f[V]TraceClassLoadingPreorder\f[R] -T}@T{ -\f[V]-Xlog:class+preorder=debug\f[R] -T}@T{ -Not Applicable -T} -T{ -\f[V]TraceClassUnloading\f[R] -T}@T{ -\f[V]-Xlog:class+unload=\f[R]\f[I]level\f[R] -T}@T{ -Use \f[I]level\f[R]=\f[V]info\f[R] for regular information, or -\f[I]level\f[R]=\f[V]trace\f[R] for additional information. -In Unified Logging syntax, \f[V]-verbose:class\f[R] equals -\f[V]-Xlog:class+load=info,class+unload=info\f[R]. -T} -T{ -\f[V]VerboseVerification\f[R] -T}@T{ -\f[V]-Xlog:verification=info\f[R] -T}@T{ -Not Applicable -T} -T{ -\f[V]TraceClassPaths\f[R] -T}@T{ -\f[V]-Xlog:class+path=info\f[R] -T}@T{ -Not Applicable -T} -T{ -\f[V]TraceClassResolution\f[R] -T}@T{ -\f[V]-Xlog:class+resolve=debug\f[R] -T}@T{ -Not Applicable -T} -T{ -\f[V]TraceClassInitialization\f[R] -T}@T{ -\f[V]-Xlog:class+init=info\f[R] -T}@T{ -Not Applicable -T} -T{ -\f[V]TraceLoaderConstraints\f[R] -T}@T{ -\f[V]-Xlog:class+loader+constraints=info\f[R] -T}@T{ -Not Applicable -T} -T{ -\f[V]TraceClassLoaderData\f[R] -T}@T{ -\f[V]-Xlog:class+loader+data=\f[R]\f[I]level\f[R] -T}@T{ -Use \f[I]level\f[R]=\f[V]debug\f[R] for regular information or -\f[I]level\f[R]=\f[V]trace\f[R] for additional information. -T} -T{ -\f[V]TraceSafepointCleanupTime\f[R] -T}@T{ -\f[V]-Xlog:safepoint+cleanup=info\f[R] -T}@T{ -Not Applicable -T} -T{ -\f[V]TraceSafepoint\f[R] -T}@T{ -\f[V]-Xlog:safepoint=debug\f[R] -T}@T{ -Not Applicable -T} -T{ -\f[V]TraceMonitorInflation\f[R] -T}@T{ -\f[V]-Xlog:monitorinflation=debug\f[R] -T}@T{ -Not Applicable -T} -T{ -\f[V]TraceRedefineClasses\f[R] -T}@T{ -\f[V]-Xlog:redefine+class*=\f[R]\f[I]level\f[R] -T}@T{ -\f[I]level\f[R]=\f[V]info\f[R], \f[V]debug\f[R], and \f[V]trace\f[R] -provide increasing amounts of information. -T} -.TE -.SS -Xlog Usage Examples -.PP -The following are \f[V]-Xlog\f[R] examples. -.TP -\f[V]-Xlog\f[R] -Logs all messages by using the \f[V]info\f[R] level to \f[V]stdout\f[R] -with \f[V]uptime\f[R], \f[V]levels\f[R], and \f[V]tags\f[R] decorations. -This is equivalent to using: -.RS -.RS -.PP -\f[V]-Xlog:all=info:stdout:uptime,levels,tags\f[R] -.RE -.RE -.TP -\f[V]-Xlog:gc\f[R] -Logs messages tagged with the \f[V]gc\f[R] tag using \f[V]info\f[R] -level to \f[V]stdout\f[R]. -The default configuration for all other messages at level -\f[V]warning\f[R] is in effect. -.TP -\f[V]-Xlog:gc,safepoint\f[R] -Logs messages tagged either with the \f[V]gc\f[R] or \f[V]safepoint\f[R] -tags, both using the \f[V]info\f[R] level, to \f[V]stdout\f[R], with -default decorations. -Messages tagged with both \f[V]gc\f[R] and \f[V]safepoint\f[R] won\[aq]t -be logged. -.TP -\f[V]-Xlog:gc+ref=debug\f[R] -Logs messages tagged with both \f[V]gc\f[R] and \f[V]ref\f[R] tags, -using the \f[V]debug\f[R] level to \f[V]stdout\f[R], with default -decorations. -Messages tagged only with one of the two tags won\[aq]t be logged. -.TP -\f[V]-Xlog:gc=debug:file=gc.txt:none\f[R] -Logs messages tagged with the \f[V]gc\f[R] tag using the \f[V]debug\f[R] -level to a file called \f[V]gc.txt\f[R] with no decorations. -The default configuration for all other messages at level -\f[V]warning\f[R] is still in effect. -.TP -\f[V]-Xlog:gc=trace:file=gctrace.txt:uptimemillis,pid:filecount=5,filesize=1024\f[R] -Logs messages tagged with the \f[V]gc\f[R] tag using the \f[V]trace\f[R] -level to a rotating file set with 5 files with size 1 MB with the base -name \f[V]gctrace.txt\f[R] and uses decorations \f[V]uptimemillis\f[R] -and \f[V]pid\f[R]. -.RS -.PP -The default configuration for all other messages at level -\f[V]warning\f[R] is still in effect. -.RE -.TP -\f[V]-Xlog:gc::uptime,tid\f[R] -Logs messages tagged with the \f[V]gc\f[R] tag using the default -\[aq]info\[aq] level to default the output \f[V]stdout\f[R] and uses -decorations \f[V]uptime\f[R] and \f[V]tid\f[R]. -The default configuration for all other messages at level -\f[V]warning\f[R] is still in effect. -.TP -\f[V]-Xlog:gc*=info,safepoint*=off\f[R] -Logs messages tagged with at least \f[V]gc\f[R] using the \f[V]info\f[R] -level, but turns off logging of messages tagged with -\f[V]safepoint\f[R]. -Messages tagged with both \f[V]gc\f[R] and \f[V]safepoint\f[R] won\[aq]t -be logged. -.TP -\f[V]-Xlog:disable -Xlog:safepoint=trace:safepointtrace.txt\f[R] -Turns off all logging, including warnings and errors, and then enables -messages tagged with \f[V]safepoint\f[R]using \f[V]trace\f[R]level to -the file \f[V]safepointtrace.txt\f[R]. -The default configuration doesn\[aq]t apply, because the command line -started with \f[V]-Xlog:disable\f[R]. -.SS Complex -Xlog Usage Examples -.PP -The following describes a few complex examples of using the -\f[V]-Xlog\f[R] option. -.TP -\f[V]-Xlog:gc+class*=debug\f[R] -Logs messages tagged with at least \f[V]gc\f[R] and \f[V]class\f[R] tags -using the \f[V]debug\f[R] level to \f[V]stdout\f[R]. -The default configuration for all other messages at the level -\f[V]warning\f[R] is still in effect -.TP -\f[V]-Xlog:gc+meta*=trace,class*=off:file=gcmetatrace.txt\f[R] -Logs messages tagged with at least the \f[V]gc\f[R] and \f[V]meta\f[R] -tags using the \f[V]trace\f[R] level to the file \f[V]metatrace.txt\f[R] -but turns off all messages tagged with \f[V]class\f[R]. -Messages tagged with \f[V]gc\f[R], \f[V]meta\f[R], and \f[V]class\f[R] -aren\[aq]t be logged as \f[V]class*\f[R] is set to off. -The default configuration for all other messages at level -\f[V]warning\f[R] is in effect except for those that include -\f[V]class\f[R]. -.TP -\f[V]-Xlog:gc+meta=trace\f[R] -Logs messages tagged with exactly the \f[V]gc\f[R] and \f[V]meta\f[R] -tags using the \f[V]trace\f[R] level to \f[V]stdout\f[R]. -The default configuration for all other messages at level -\f[V]warning\f[R] is still be in effect. -.TP -\f[V]-Xlog:gc+class+heap*=debug,meta*=warning,threads*=off\f[R] -Logs messages tagged with at least \f[V]gc\f[R], \f[V]class\f[R], and -\f[V]heap\f[R] tags using the \f[V]trace\f[R] level to \f[V]stdout\f[R] -but only log messages tagged with \f[V]meta\f[R] with level. -The default configuration for all other messages at the level -\f[V]warning\f[R] is in effect except for those that include -\f[V]threads\f[R]. -.SH VALIDATE JAVA VIRTUAL MACHINE FLAG ARGUMENTS -.PP -You use values provided to all Java Virtual Machine (JVM) command-line -flags for validation and, if the input value is invalid or out-of-range, -then an appropriate error message is displayed. -.PP -Whether they\[aq]re set ergonomically, in a command line, by an input -tool, or through the APIs (for example, classes contained in the package -\f[V]java.lang.management\f[R]) the values provided to all Java Virtual -Machine (JVM) command-line flags are validated. -Ergonomics are described in Java Platform, Standard Edition HotSpot -Virtual Machine Garbage Collection Tuning Guide. -.PP -Range and constraints are validated either when all flags have their -values set during JVM initialization or a flag\[aq]s value is changed -during runtime (for example using the \f[V]jcmd\f[R] tool). -The JVM is terminated if a value violates either the range or constraint -check and an appropriate error message is printed on the error stream. -.PP -For example, if a flag violates a range or a constraint check, then the -JVM exits with an error: -.IP -.nf -\f[CB] -java -XX:AllocatePrefetchStyle=5 -version -intx AllocatePrefetchStyle=5 is outside the allowed range [ 0 ... 3 ] -Improperly specified VM option \[aq]AllocatePrefetchStyle=5\[aq] -Error: Could not create the Java Virtual Machine. -Error: A fatal exception has occurred. Program will exit. -\f[R] -.fi -.PP -The flag \f[V]-XX:+PrintFlagsRanges\f[R] prints the range of all the -flags. -This flag allows automatic testing of the flags by the values provided -by the ranges. -For the flags that have the ranges specified, the type, name, and the -actual range is printed in the output. -.PP -For example, -.IP -.nf -\f[CB] -intx ThreadStackSize [ 0 ... 9007199254740987 ] {pd product} -\f[R] -.fi -.PP -For the flags that don\[aq]t have the range specified, the values -aren\[aq]t displayed in the print out. -For example: -.IP -.nf -\f[CB] -size_t NewSize [ ... ] {product} -\f[R] -.fi -.PP -This helps to identify the flags that need to be implemented. -The automatic testing framework can skip those flags that don\[aq]t have -values and aren\[aq]t implemented. -.SH LARGE PAGES -.PP -You use large pages, also known as huge pages, as memory pages that are -significantly larger than the standard memory page size (which varies -depending on the processor and operating system). -Large pages optimize processor Translation-Lookaside Buffers. -.PP -A Translation-Lookaside Buffer (TLB) is a page translation cache that -holds the most-recently used virtual-to-physical address translations. -A TLB is a scarce system resource. -A TLB miss can be costly because the processor must then read from the -hierarchical page table, which may require multiple memory accesses. -By using a larger memory page size, a single TLB entry can represent a -larger memory range. -This results in less pressure on a TLB, and memory-intensive -applications may have better performance. -.PP -However, using large pages can negatively affect system performance. -For example, when a large amount of memory is pinned by an application, -it may create a shortage of regular memory and cause excessive paging in -other applications and slow down the entire system. -Also, a system that has been up for a long time could produce excessive -fragmentation, which could make it impossible to reserve enough large -page memory. -When this happens, either the OS or JVM reverts to using regular pages. -.PP -Linux and Windows support large pages. -.SS Large Pages Support for Linux -.PP -Linux supports large pages since version 2.6. -To check if your environment supports large pages, try the following: -.IP -.nf -\f[CB] -# cat /proc/meminfo | grep Huge -HugePages_Total: 0 -HugePages_Free: 0 -\&... -Hugepagesize: 2048 kB -\f[R] -.fi -.PP -If the output contains items prefixed with \[dq]Huge\[dq], then your -system supports large pages. -The values may vary depending on environment. -The \f[V]Hugepagesize\f[R] field shows the default large page size in -your environment, and the other fields show details for large pages of -this size. -Newer kernels have support for multiple large page sizes. -To list the supported page sizes, run this: -.IP -.nf -\f[CB] -# ls /sys/kernel/mm/hugepages/ -hugepages-1048576kB hugepages-2048kB -\f[R] -.fi -.PP -The above environment supports 2 MB and 1 GB large pages, but they need -to be configured so that the JVM can use them. -When using large pages and not enabling transparent huge pages (option -\f[V]-XX:+UseTransparentHugePages\f[R]), the number of large pages must -be pre-allocated. -For example, to enable 8 GB of memory to be backed by 2 MB large pages, -login as \f[V]root\f[R] and run: -.RS -.PP -\f[V]# echo 4096 > /sys/kernel/mm/hugepages/hugepages-2048kB/nr_hugepages\f[R] -.RE -.PP -It is always recommended to check the value of \f[V]nr_hugepages\f[R] -after the request to make sure the kernel was able to allocate the -requested number of large pages. -.RS -.PP -\f[B]Note:\f[R] The values contained in \f[V]/proc\f[R] and -\f[V]/sys\f[R] reset after you reboot your system, so may want to set -them in an initialization script (for example, \f[V]rc.local\f[R] or -\f[V]sysctl.conf\f[R]). -.RE -.PP -If you configure the OS kernel parameters to enable use of large pages, -the Java processes may allocate large pages for the Java heap as well as -other internal areas, for example: -.IP \[bu] 2 -Code cache -.IP \[bu] 2 -Marking bitmaps -.PP -Consequently, if you configure the \f[V]nr_hugepages\f[R] parameter to -the size of the Java heap, then the JVM can still fail to allocate the -heap using large pages because other areas such as the code cache might -already have used some of the configured large pages. -.SS Large Pages Support for Windows -.PP -To use large pages support on Windows, the administrator must first -assign additional privileges to the user who is running the application: -.IP "1." 3 -Select \f[B]Control Panel\f[R], \f[B]Administrative Tools\f[R], and then -\f[B]Local Security Policy\f[R]. -.IP "2." 3 -Select \f[B]Local Policies\f[R] and then \f[B]User Rights -Assignment\f[R]. -.IP "3." 3 -Double-click \f[B]Lock pages in memory\f[R], then add users and/or -groups. -.IP "4." 3 -Reboot your system. -.PP -Note that these steps are required even if it\[aq]s the administrator -who\[aq]s running the application, because administrators by default -don\[aq]t have the privilege to lock pages in memory. -.SH APPLICATION CLASS DATA SHARING -.PP -Application Class Data Sharing (AppCDS) stores classes used by your -applications in an archive file. -Since these classes are stored in a format that can be loaded very -quickly (compared to classes stored in a JAR file), AppCDS can improve -the start-up time of your applications. -In addition, AppCDS can reduce the runtime memory footprint by sharing -parts of these classes across multiple processes. -.PP -Classes in the CDS archive are stored in an optimized format that\[aq]s -about 2 to 5 times larger than classes stored in JAR files or the JDK -runtime image. -Therefore, it\[aq]s a good idea to archive only those classes that are -actually used by your application. -These usually are just a small portion of all available classes. -For example, your application may use only a few APIs provided by a -large library. -.SS Using CDS Archives -.PP -By default, in most JDK distributions, unless \f[V]-Xshare:off\f[R] is -specified, the JVM starts up with a default CDS archive, which is -usually located in \f[V]JAVA_HOME/lib/server/classes.jsa\f[R] (or -\f[V]JAVA_HOME\[rs]bin\[rs]server\[rs]classes.jsa\f[R] on Windows). -This archive contains about 1300 core library classes that are used by -most applications. -.PP -To use CDS for the exact set of classes used by your application, you -can use the \f[V]-XX:SharedArchiveFile\f[R] option, which has the -general form: -.RS -.PP -\f[V]-XX:SharedArchiveFile=:\f[R] -.RE -.IP \[bu] 2 -The \f[V]\f[R] overrides the default CDS archive. -.IP \[bu] 2 -The \f[V]\f[R] provides additional classes that can be -loaded on top of those in the \f[V]\f[R]. -.IP \[bu] 2 -On Windows, the above path delimiter \f[V]:\f[R] should be replaced with -\f[V];\f[R] -.PP -(The names \[dq]static\[dq] and \[dq]dynamic\[dq] are used for -historical reasons. -The only significance is that the \[dq]static\[dq] archive is loaded -first and the \[dq]dynamic\[dq] archive is loaded second). -.PP -The JVM can use up to two archives. -To use only a single \f[V]\f[R], you can omit the -\f[V]\f[R] portion: -.RS -.PP -\f[V]-XX:SharedArchiveFile=\f[R] -.RE -.PP -For convenience, the \f[V]\f[R] records the location of -the \f[V]\f[R]. -Therefore, you can omit the \f[V]\f[R] by saying only: -.RS -.PP -\f[V]-XX:SharedArchiveFile=\f[R] -.RE -.SS Manually Creating CDS Archives -.PP -CDS archives can be created manually using several methods: -.IP \[bu] 2 -\f[V]-Xshare:dump\f[R] -.IP \[bu] 2 -\f[V]-XX:ArchiveClassesAtExit\f[R] -.IP \[bu] 2 -\f[V]jcmd VM.cds\f[R] -.PP -One common operation in all these methods is a \[dq]trial run\[dq], -where you run the application once to determine the classes that should -be stored in the archive. -.SS Creating a Static CDS Archive File with -Xshare:dump -.PP -The following steps create a static CDS archive file that contains all -the classes used by the \f[V]test.Hello\f[R] application. -.IP "1." 3 -Create a list of all classes used by the \f[V]test.Hello\f[R] -application. -The following command creates a file named \f[V]hello.classlist\f[R] -that contains a list of all classes used by this application: -.RS 4 -.RS -.PP -\f[V]java -Xshare:off -XX:DumpLoadedClassList=hello.classlist -cp hello.jar test.Hello\f[R] -.RE -.PP -The classpath specified by the \f[V]-cp\f[R] parameter must contain only -JAR files. -.RE -.IP "2." 3 -Create a static archive, named \f[V]hello.jsa\f[R], that contains all -the classes in \f[V]hello.classlist\f[R]: -.RS 4 -.RS -.PP -\f[V]java -Xshare:dump -XX:SharedArchiveFile=hello.jsa -XX:SharedClassListFile=hello.classlist -cp hello.jar\f[R] -.RE -.RE -.IP "3." 3 -Run the application \f[V]test.Hello\f[R] with the archive -\f[V]hello.jsa\f[R]: -.RS 4 -.RS -.PP -\f[V]java -XX:SharedArchiveFile=hello.jsa -cp hello.jar test.Hello\f[R] -.RE -.RE -.IP "4." 3 -\f[B]Optional\f[R] Verify that the \f[V]test.Hello\f[R] application is -using the class contained in the \f[V]hello.jsa\f[R] shared archive: -.RS 4 -.RS -.PP -\f[V]java -XX:SharedArchiveFile=hello.jsa -cp hello.jar -Xlog:class+load test.Hello\f[R] -.RE -.PP -The output of this command should contain the following text: -.RS -.PP -\f[V][info][class,load] test.Hello source: shared objects file\f[R] -.RE -.RE -.PP -By default, when the \f[V]-Xshare:dump\f[R] option is used, the JVM runs -in interpreter-only mode (as if the \f[V]-Xint\f[R] option were -specified). -This is required for generating deterministic output in the shared -archive file. -I.e., the exact same archive will be generated, bit-for-bit, every time -you dump it. -However, if deterministic output is not needed, and you have a large -classlist, you can explicitly add \f[V]-Xmixed\f[R] to the command-line -to enable the JIT compiler. -This will speed up the archive creation. -.SS Creating a Dynamic CDS Archive File with -XX:ArchiveClassesAtExit -.PP -Advantages of dynamic CDS archives are: -.IP \[bu] 2 -They usually use less disk space, since they don\[aq]t need to store the -classes that are already in the static archive. -.IP \[bu] 2 -They are created with one fewer step than the comparable static archive. -.PP -The following steps create a dynamic CDS archive file that contains the -classes that are used by the \f[V]test.Hello\f[R] application, excluding -those that are already in the default CDS archive. -.IP "1." 3 -Create a dynamic CDS archive, named \f[V]hello.jsa\f[R], that contains -all the classes in \f[V]hello.jar\f[R] loaded by the application -\f[V]test.Hello\f[R]: -.RS 4 -.RS -.PP -\f[V]java -XX:ArchiveClassesAtExit=hello.jsa -cp hello.jar Hello\f[R] -.RE -.RE -.IP "2." 3 -Run the application \f[V]test.Hello\f[R] with the shared archive -\f[V]hello.jsa\f[R]: -.RS 4 -.RS -.PP -\f[V]java -XX:SharedArchiveFile=hello.jsa -cp hello.jar test.Hello\f[R] -.RE -.RE -.IP "3." 3 -\f[B]Optional\f[R] Repeat step 4 of the previous section to verify that -the \f[V]test.Hello\f[R] application is using the class contained in the -\f[V]hello.jsa\f[R] shared archive. -.PP -It\[aq]s also possible to create a dynamic CDS archive with a -non-default static CDS archive. -E.g., -.RS -.PP -\f[V]java -XX:SharedArchiveFile=base.jsa -XX:ArchiveClassesAtExit=hello.jsa -cp hello.jar Hello\f[R] -.RE -.PP -To run the application using this dynamic CDS archive: -.RS -.PP -\f[V]java -XX:SharedArchiveFile=base.jsa:hello.jsa -cp hello.jar Hello\f[R] -.RE -.PP -(On Windows, the above path delimiter \f[V]:\f[R] should be replaced -with \f[V];\f[R]) -.PP -As mention above, the name of the static archive can be skipped: -.RS -.PP -\f[V]java -XX:SharedArchiveFile=hello.jsa -cp hello.jar Hello\f[R] -.RE -.SS Creating CDS Archive Files with jcmd -.PP -The previous two sections require you to modify the application\[aq]s -start-up script in order to create a CDS archive. -Sometimes this could be difficult, for example, if the application\[aq]s -class path is set up by complex routines. -.PP -The \f[V]jcmd VM.cds\f[R] command provides a less intrusive way for -creating a CDS archive by connecting to a running JVM process. -You can create either a static: -.RS -.PP -\f[V]jcmd VM.cds static_dump my_static_archive.jsa\f[R] -.RE -.PP -or a dynamic archive: -.RS -.PP -\f[V]jcmd VM.cds dynamic_dump my_dynamic_archive.jsa\f[R] -.RE -.PP -To use the resulting archive file in a subsequent run of the application -without modifying the application\[aq]s start-up script, you can use the -following technique: -.RS -.PP -\f[V]env JAVA_TOOL_OPTIONS=-XX:SharedArchiveFile=my_static_archive.jsa bash app_start.sh\f[R] -.RE -.PP -Note: to use \f[V]jcmd VM.cds dynamic_dump\f[R], the JVM process -identified by \f[V]\f[R] must be started with -\f[V]-XX:+RecordDynamicDumpInfo\f[R], which can also be passed to the -application start-up script with the same technique: -.RS -.PP -\f[V]env JAVA_TOOL_OPTIONS=-XX:+RecordDynamicDumpInfo bash app_start.sh\f[R] -.RE -.SS Creating Dynamic CDS Archive File with -XX:+AutoCreateSharedArchive -.PP -\f[V]-XX:+AutoCreateSharedArchive\f[R] is a more convenient way of -creating/using CDS archives. -Unlike the methods of manual CDS archive creation described in the -previous section, with \f[V]-XX:+AutoCreateSharedArchive\f[R], it\[aq]s -no longer necessary to have a separate trial run. -Instead, you can always run the application with the same command-line -and enjoy the benefits of CDS automatically. -.RS -.PP -\f[V]java -XX:+AutoCreateSharedArchive -XX:SharedArchiveFile=hello.jsa -cp hello.jar Hello\f[R] -.RE -.PP -If the specified archive file exists and was created by the same version -of the JDK, then it will be loaded as a dynamic archive; otherwise it is -ignored at VM startup. -.PP -At VM exit, if the specified archive file does not exist, it will be -created. -If it exists but was created with a different (but post JDK 19) version -of the JDK, then it will be replaced. -In both cases the archive will be ready to be loaded the next time the -JVM is launched with the same command line. -.PP -If the specified archive file exists but was created by a JDK version -prior to JDK 19, then it will be ignored: neither loaded at startup, nor -replaced at exit. -.PP -Developers should note that the contents of the CDS archive file are -specific to each build of the JDK. -Therefore, if you switch to a different JDK build, -\f[V]-XX:+AutoCreateSharedArchive\f[R] will automatically recreate the -archive to match the JDK. -If you intend to use this feature with an existing archive, you should -make sure that the archive is created by at least version 19 of the JDK. -.SS Restrictions on Class Path and Module Path -.IP \[bu] 2 -Neither the class path (\f[V]-classpath\f[R] and -\f[V]-Xbootclasspath/a\f[R]) nor the module path -(\f[V]--module-path\f[R]) can contain non-empty directories. -.IP \[bu] 2 -Only modular JAR files are supported in \f[V]--module-path\f[R]. -Exploded modules are not supported. -.IP \[bu] 2 -The class path used at archive creation time must be the same as (or a -prefix of) the class path used at run time. -(There\[aq]s no such requirement for the module path.) -.IP \[bu] 2 -The CDS archive cannot be loaded if any JAR files in the class path or -module path are modified after the archive is generated. -.IP \[bu] 2 -If any of the VM options \f[V]--upgrade-module-path\f[R], -\f[V]--patch-module\f[R] or \f[V]--limit-modules\f[R] are specified, CDS -is disabled. -This means that the JVM will execute without loading any CDS archives. -In addition, if you try to create a CDS archive with any of these 3 -options specified, the JVM will report an error. -.SH PERFORMANCE TUNING EXAMPLES -.PP -You can use the Java advanced runtime options to optimize the -performance of your applications. -.SS Tuning for Higher Throughput -.PP -Use the following commands and advanced options to achieve higher -throughput performance for your application: -.RS -.PP -\f[V]java -server -XX:+UseParallelGC -XX:+UseLargePages -Xmn10g -Xms26g -Xmx26g\f[R] -.RE -.SS Tuning for Lower Response Time -.PP -Use the following commands and advanced options to achieve lower -response times for your application: -.RS -.PP -\f[V]java -XX:+UseG1GC -XX:MaxGCPauseMillis=100\f[R] -.RE -.SS Keeping the Java Heap Small and Reducing the Dynamic Footprint of Embedded Applications -.PP -Use the following advanced runtime options to keep the Java heap small -and reduce the dynamic footprint of embedded applications: -.RS -.PP -\f[V]-XX:MaxHeapFreeRatio=10 -XX:MinHeapFreeRatio=5\f[R] -.RE -.RS -.PP -\f[B]Note:\f[R] The defaults for these two options are 70% and 40% -respectively. -Because performance sacrifices can occur when using these small -settings, you should optimize for a small footprint by reducing these -settings as much as possible without introducing unacceptable -performance degradation. -.RE -.SH EXIT STATUS -.PP -The following exit values are typically returned by the launcher when -the launcher is called with the wrong arguments, serious errors, or -exceptions thrown by the JVM. -However, a Java application may choose to return any value by using the -API call \f[V]System.exit(exitValue)\f[R]. -The values are: -.IP \[bu] 2 -\f[V]0\f[R]: Successful completion -.IP \[bu] 2 -\f[V]>0\f[R]: An error occurred diff --git a/src/java.base/share/man/java.md b/src/java.base/share/man/java.md new file mode 100644 index 00000000000..f79e55622cd --- /dev/null +++ b/src/java.base/share/man/java.md @@ -0,0 +1,4050 @@ +--- +# Copyright (c) 1994, 2024, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# This code is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 only, as +# published by the Free Software Foundation. +# +# This code is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# version 2 for more details (a copy is included in the LICENSE file that +# accompanied this code). +# +# You should have received a copy of the GNU General Public License version +# 2 along with this work; if not, write to the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +# or visit www.oracle.com if you need additional information or have any +# questions. +# + +title: 'JAVA(1) JDK @@VERSION_SHORT@@ | JDK Commands' +date: @@COPYRIGHT_YEAR@@ +lang: en +--- + +## Name + +java - launch a Java application + +## Synopsis + +To launch a class file: + +`java` \[*options*\] *mainclass* \[*args* ...\] + +To launch the main class in a JAR file: + +`java` \[*options*\] `-jar` *jarfile* \[*args* ...\] + +To launch the main class in a module: + +`java` \[*options*\] `-m` *module*\[`/`*mainclass*\] \[*args* ...\] + +or + +`java` \[*options*\] `--module` *module*\[`/`*mainclass*\] \[*args* ...\] + +To launch a source-file program: + +`java` \[*options*\] *source-file* \[*args* ...\] + +*options* +: Optional: Specifies command-line options separated by spaces. See [Overview + of Java Options] for a description of available + options. + +*mainclass* +: Specifies the name of the class to be launched. Command-line entries + following `classname` are the arguments for the main method. + +`-jar` *jarfile* +: Executes a program encapsulated in a JAR file. The *jarfile* argument is + the name of a JAR file with a manifest that contains a line in the form + `Main-Class:`*classname* that defines the class with the + `public static void main(String[] args)` method that serves as your + application's starting point. When you use `-jar`, the specified JAR file + is the source of all user classes, and other class path settings are + ignored. If you're using JAR files, then see [jar](jar.html). + +`-m` or `--module` *module*\[`/`*mainclass*\] +: Executes the main class in a module specified by *mainclass* if it is + given, or, if it is not given, the value in the *module*. In other words, + *mainclass* can be used when it is not specified by the module, or to + override the value when it is specified. + + See [Standard Options for Java]. + +*source-file* +: Only used to launch a source-file program. Specifies the source file + that contains the main class when using source-file mode. See [Using + Source-File Mode to Launch Source-Code Programs] + +*args* ... +: Optional: Arguments following *mainclass*, *source-file*, `-jar` *jarfile*, + and `-m` or `--module` *module*`/`*mainclass* are passed as arguments to + the main class. + +## Description + +The `java` command starts a Java application. It does this by starting the Java +Virtual Machine (JVM), loading the specified class, and calling that +class's `main()` method. The method must be declared `public` and `static`, it +must not return any value, and it must accept a `String` array as a parameter. +The method declaration has the following form: + +> `public static void main(String[] args)` + +In source-file mode, the `java` command can launch a class declared in a source +file. See [Using Source-File Mode to Launch Source-Code Programs] +for a description of using the source-file mode. + +> **Note:** You can use the `JDK_JAVA_OPTIONS` launcher environment variable to prepend its +content to the actual command line of the `java` launcher. See [Using the +JDK\_JAVA\_OPTIONS Launcher Environment Variable]. + +By default, the first argument that isn't an option of the `java` command is +the fully qualified name of the class to be called. If `-jar` is specified, +then its argument is the name of the JAR file containing class and resource +files for the application. The startup class must be indicated by the +`Main-Class` manifest header in its manifest file. + +Arguments after the class file name or the JAR file name are passed to the +`main()` method. + +### `javaw` + +**Windows:** The `javaw` command is identical to `java`, except that with +`javaw` there's no associated console window. Use `javaw` when you don't want a +command prompt window to appear. The `javaw` launcher will, however, display a +dialog box with error information if a launch fails. + +## Using Source-File Mode to Launch Source-Code Programs + +To launch a class declared in a source file, run the `java` launcher in +source-file mode. Entering source-file mode is determined by two items on the +`java` command line: + +- The first item on the command line that is not an option or part of an + option. In other words, the item in the command line that would otherwise + be the main class name. + +- The `--source` *version* option, if present. + +If the class identifies an existing file that has a `.java` extension, or if +the `--source` option is specified, then source-file mode is selected. The +source file is then compiled and run. The `--source` option can be used to +specify the source *version* or *N* of the source code. This determines the API +that can be used. When you set `--source` *N*, you can only use the public API +that was defined in JDK *N*. + +> **Note:** The valid values of *N* change for each release, with new values added and old +values removed. You'll get an error message if you use a value of *N* that is +no longer supported. +The supported values of *N* are the current Java SE release (`@@VERSION_SPECIFICATION@@`) +and a limited number of previous releases, detailed in the command-line help +for `javac`, under the `--source` and `--release` options. + +If the file does not have the `.java` extension, the `--source` option must be +used to tell the `java` command to use the source-file mode. The `--source` +option is used for cases when the source file is a "script" to be executed and +the name of the source file does not follow the normal naming conventions for +Java source files. + +In source-file mode, the effect is as though the source file is compiled into +memory, and the first class found in the source file is executed. Any arguments +placed after the name of the source file in the original command line are +passed to the compiled class when it is executed. + +For example, if a file were named `HelloWorld.java` and contained a class named +`HelloWorld`, then the source-file mode command to launch the class would be: + +> `java HelloWorld.java` + +This use of source-file mode is informally equivalent to using the following two +commands: + +``` +javac -d --source-path HelloWorld.java +java --class-path HelloWorld +``` + +where `` is computed + +**In source-file mode, any additional command-line options are processed as +follows:** + +- The launcher scans the options specified before the source file for any + that are relevant in order to compile the source file. + + This includes: `--class-path`, `--module-path`, `--add-exports`, + `--add-modules`, `--limit-modules`, `--patch-module`, + `--upgrade-module-path`, and any variant forms of those options. It also + includes the new `--enable-preview` option, described in JEP 12. + +- No provision is made to pass any additional options to the compiler, such + as `-processor` or `-Werror`. + +- Command-line argument files (`@`-files) may be used in the standard way. + Long lists of arguments for either the VM or the program being invoked may + be placed in files specified on the command-line by prefixing the filename + with an `@` character. + +**In source-file mode, compilation proceeds as follows:** + +- Any command-line options that are relevant to the compilation environment + are taken into account. These include: `--class-path`/`-classpath`/`-cp`, + `--module-path`/`-p`, `--add-exports`, `--add-modules`, `--limit-modules`, + `--patch-module`, `--upgrade-module-path`, `--enable-preview`. + +- The root of the source tree, `` is computed from the package + of the class being launched. For example, if `HelloWorld.java` declared its classes + to be in the `hello` package, then the file `HelloWorld.java` is expected + to reside in the directory `somedir/hello/`. In this case, `somedir` is + computed to be the root of the source tree. + +- The root of the source tree serves as the source-path for compilation, so that + other source files found in that tree and are needed by `HelloWorld` could be + compiled. + +- Annotation processing is disabled, as if `-proc:none` is in effect. + +- If a version is specified, via the `--source` option, the value is used as + the argument for an implicit `--release` option for the compilation. This + sets both the source version accepted by compiler and the system API that + may be used by the code in the source file. + +- If `--enable-preview` is specified, the `--source N` arguments can be omitted. + If the Java runtime version is `N`, then `--release N` is implied when + compiling source files. + +- If a `module-info.java` file exists in the `` directory, its + module declaration is used to define a named module that will contain all + the classes compiled from `.java` files in the source tree. If + `module-info.java` does not exist, all the classes compiled from source files + will be compiled in the context of the unnamed module. + +- The source file that is launched should contain one or more top-level classes, the first of + which is taken as the class to be executed. + +- For the source file that is launched, the compiler does not enforce the optional restriction defined at the end + of JLS 7.6, that a type in a named package should exist in a file whose + name is composed from the type name followed by the `.java` extension. + +- If a source file contains errors, appropriate error messages are written + to the standard error stream, and the launcher exits with a non-zero exit + code. + +**In source-file mode, execution proceeds as follows:** + +- The class to be executed is the first top-level class found in the source + file. It must contain a declaration of an entry `main` method. + +- The compiled classes are loaded by a custom class loader, that delegates to + the application class loader. This implies that classes appearing on the + application class path cannot refer to any classes declared in source files. + +- If a `module-info.java` file exists in the `` directory, then all + the classes compiled from `.java` files in the source tree will be in that + module, which will serve as the root module for the execution of the program. + If `module-info.java` does not exist, the compiled classes are executed in the + context of an unnamed module, as though `--add-modules=ALL-DEFAULT` is in effect. + This is in addition to any other `--add-module` options that may be have been + specified on the command line. + +- Any arguments appearing after the name of the file on the command line are + passed to the main method in the obvious way. + +- It is an error if there is a class on the application class path whose name + is the same as that of the class to be executed. + +See [JEP 458: Launch Multi-File Source-Code Programs]( +https://openjdk.org/jeps/458) for complete details. + +## Using the JDK\_JAVA\_OPTIONS Launcher Environment Variable + +`JDK_JAVA_OPTIONS` prepends its content to the options parsed from the command +line. The content of the `JDK_JAVA_OPTIONS` environment variable is a list of +arguments separated by white-space characters (as determined by `isspace()`). +These are prepended to the command line arguments passed to `java` launcher. +The encoding requirement for the environment variable is the same as the `java` +command line on the system. `JDK_JAVA_OPTIONS` environment variable content is +treated in the same manner as that specified in the command line. + +Single (`'`) or double (`"`) quotes can be used to enclose arguments that +contain whitespace characters. All content between the open quote and the +first matching close quote are preserved by simply removing the pair of quotes. +In case a matching quote is not found, the launcher will abort with an error +message. `@`-files are supported as they are specified in the command line. +However, as in `@`-files, use of a wildcard is not supported. In order to +mitigate potential misuse of `JDK_JAVA_OPTIONS` behavior, options that specify +the main class (such as `-jar`) or cause the `java` launcher to exit without +executing the main class (such as `-h`) are disallowed in the environment +variable. If any of these options appear in the environment variable, the +launcher will abort with an error message. When `JDK_JAVA_OPTIONS` is set, the +launcher prints a message to stderr as a reminder. + +**Example:** + +``` +$ export JDK_JAVA_OPTIONS='-g @file1 -Dprop=value @file2 -Dws.prop="white spaces"' +$ java -Xint @file3 +``` + +is equivalent to the command line: + +``` +java -g @file1 -Dprop=value @file2 -Dws.prop="white spaces" -Xint @file3 +``` + +## Overview of Java Options + +The `java` command supports a wide range of options in the following +categories: + +- [Standard Options for Java]\: Options guaranteed to be supported by all + implementations of the Java Virtual Machine (JVM). They're used for common + actions, such as checking the version of the JRE, setting the class path, + enabling verbose output, and so on. + +- [Extra Options for Java]\: General purpose options that are specific to the + Java HotSpot Virtual Machine. They aren't guaranteed to be supported by + all JVM implementations, and are subject to change. These options start + with `-X`. + +The advanced options aren't recommended for casual use. These are developer +options used for tuning specific areas of the Java HotSpot Virtual Machine +operation that often have specific system requirements and may require +privileged access to system configuration parameters. Several examples of +performance tuning are provided in [Performance Tuning Examples]. These +options aren't guaranteed to be supported by all JVM implementations and are +subject to change. Advanced options start with `-XX`. + +- [Advanced Runtime Options for Java]\: Control the runtime behavior of the + Java HotSpot VM. + +- [Advanced JIT Compiler Options for java]\: Control the dynamic just-in-time + (JIT) compilation performed by the Java HotSpot VM. + +- [Advanced Serviceability Options for Java]\: Enable gathering system + information and performing extensive debugging. + +- [Advanced Garbage Collection Options for Java]\: Control how garbage + collection (GC) is performed by the Java HotSpot + +Boolean options are used to either enable a feature that's disabled by default +or disable a feature that's enabled by default. Such options don't require a +parameter. Boolean `-XX` options are enabled using the plus sign +(`-XX:+`*OptionName*) and disabled using the minus sign (`-XX:-`*OptionName*). + +For options that require an argument, the argument may be separated from the +option name by a space, a colon (:), or an equal sign (=), or the argument may +directly follow the option (the exact syntax differs for each option). If +you're expected to specify the size in bytes, then you can use no suffix, or +use the suffix `k` or `K` for kilobytes (KB), `m` or `M` for megabytes (MB), or +`g` or `G` for gigabytes (GB). For example, to set the size to 8 GB, you can +specify either `8g`, `8192m`, `8388608k`, or `8589934592` as the argument. If +you are expected to specify the percentage, then use a number from 0 to 1. For +example, specify `0.25` for 25%. + +The following sections describe the options that are deprecated, obsolete, and +removed: + +- [Deprecated Java Options]\: Accepted and acted upon --- a warning is issued + when they're used. + +- [Obsolete Java Options]\: Accepted but ignored --- a warning is issued when + they're used. + +- [Removed Java Options]\: Removed --- using them results in an error. + +## Standard Options for Java + +These are the most commonly used options supported by all implementations of +the JVM. + +> **Note:** To specify an argument for a long option, you can use either +`--`*name*`=`*value* or `--`*name* *value*. + +`-agentlib:`*libname*\[`=`*options*\] +: Loads the specified native agent library. After the library name, a + comma-separated list of options specific to the library can be used. + If the option `-agentlib:foo` is specified, then the JVM attempts to + load the library named `foo` using the platform specific naming + conventions and locations: + + - **Linux and other POSIX-like platforms:** The JVM attempts to load + the library named `libfoo.so` in the location specified by the + `LD_LIBRARY_PATH` system variable. + + - **macOS:** The JVM attempts to load the library named `libfoo.dylib` + in the location specified by the `DYLD_LIBRARY_PATH` system variable. + + - **Windows:** The JVM attempts to load the library named `foo.dll` in + the location specified by the `PATH` system variable. + + The following example shows how to load the Java Debug Wire Protocol + (JDWP) library and listen for the socket connection on port 8000, + suspending the JVM before the main class loads: + + > `-agentlib:jdwp=transport=dt_socket,server=y,address=8000` + +`-agentpath:`*pathname*\[`=`*options*\] +: Loads the native agent library specified by the absolute path name. This + option is equivalent to `-agentlib` but uses the full path and file name of + the library. + +`--class-path` *classpath*, `-classpath` *classpath*, or `-cp` *classpath* +: Specifies a list of directories, JAR files, and ZIP archives to search + for class files. + + On Windows, semicolons (`;`) separate entities in this list; + on other platforms it is a colon (`:`). + + Specifying *classpath* overrides any setting of the `CLASSPATH` environment + variable. If the class path option isn't used and *classpath* isn't set, + then the user class path consists of the current directory (.). + + As a special convenience, a class path element that contains a base name of + an asterisk (\*) is considered equivalent to specifying a list of all the + files in the directory with the extension `.jar` or `.JAR` . A Java program + can't tell the difference between the two invocations. For example, if the + directory mydir contains `a.jar` and `b.JAR`, then the class path element + mydir/\* is expanded to `A.jar:b.JAR`, except that the order of JAR files + is unspecified. All `.jar` files in the specified directory, even hidden + ones, are included in the list. A class path entry consisting of an + asterisk (\*) expands to a list of all the jar files in the current + directory. The `CLASSPATH` environment variable, where defined, is + similarly expanded. Any class path wildcard expansion that occurs before + the Java VM is started. Java programs never see wildcards that aren't + expanded except by querying the environment, such as by calling + `System.getenv("CLASSPATH")`. + +`--disable-@files` +: Can be used anywhere on the command line, including in an argument file, to + prevent further `@filename` expansion. This option stops expanding + `@`-argfiles after the option. + +`--enable-preview` +: Allows classes to depend on [preview features](https://docs.oracle.com/en/java/javase/12/language/index.html#JSLAN-GUID-5A82FE0E-0CA4-4F1F-B075-564874FE2823) of the release. + +`--enable-native-access` *module*\[`,`*module*...\] +: Native access involves access to code or data outside the Java runtime. + This is generally unsafe and, if done incorrectly, might crash the JVM or result + in memory corruption. Native access can occur as a result of calling a method that + is either [restricted](https://openjdk.org/jeps/454#Safety), or `native`. + This option allows code in the specified modules to perform native access. + Native access occurring in a module that has not been explicitly enabled + is deemed *illegal*. + + *module* can be a module name, or `ALL-UNNAMED` to indicate code on the class path. + + +-`--illegal-native-access=`*parameter* +: This option specifies a mode for how illegal native access is handled: + + > **Note:** This option will be removed in a future release. + + - `allow`: This mode allows illegal native access in all modules, + without any warings. + + - `warn`: This mode is identical to `allow` except that a warning + message is issued for the first illegal native access found in a module. + This mode is the default for the current JDK but will change in a future + release. + + - `deny`: This mode disables illegal native access. That is, any illegal native + access causes an `IllegalCallerException`. This mode will become the default + in a future release. + + To verify that your application is ready for a future version of the JDK, + run it with `--illegal-native-access=deny` along with any necessary `--enable-native-access` + options. + +`--finalization=`*value* +: Controls whether the JVM performs finalization of objects. Valid values + are "enabled" and "disabled". Finalization is enabled by default, so the + value "enabled" does nothing. The value "disabled" disables finalization, + so that no finalizers are invoked. + +`--module-path` *modulepath*... or `-p` *modulepath* +: Specifies where to find application modules with a list of path elements. + The elements of a module path can be a file path to a module or a directory + containing modules. Each module is either a modular JAR or an + exploded-module directory. + + On Windows, semicolons (`;`) separate path elements in this list; + on other platforms it is a colon (`:`). + +`--upgrade-module-path` *modulepath*... +: Specifies where to find module replacements of upgradeable modules in the + runtime image with a list of path elements. + The elements of a module path can be a file path to a module or a directory + containing modules. Each module is either a modular JAR or an + exploded-module directory. + + On Windows, semicolons (`;`) separate path elements in this list; + on other platforms it is a colon (`:`). + +`--add-modules` *module*\[`,`*module*...\] +: Specifies the root modules to resolve in addition to the initial module. + *module* can also be `ALL-DEFAULT`, `ALL-SYSTEM`, and `ALL-MODULE-PATH`. + +`--list-modules` +: Lists the observable modules and then exits. + +`-d` *module\_name* or `--describe-module` *module\_name* +: Describes a specified module and then exits. + +`--dry-run` +: Creates the VM but doesn't execute the main method. This `--dry-run` option + might be useful for validating the command-line options such as the module + system configuration. + +`--validate-modules` +: Validates all modules and exit. This option is helpful for finding + conflicts and other errors with modules on the module path. + +`-D`*property*`=`*value* +: Sets a system property value. The *property* variable is a string with no + spaces that represents the name of the property. The *value* variable is a + string that represents the value of the property. If *value* is a string + with spaces, then enclose it in quotation marks (for example + `-Dfoo="foo bar"`). + +`-disableassertions`\[`:`\[*packagename*\]...\|`:`*classname*\] or `-da`\[`:`\[*packagename*\]...\|`:`*classname*\] +: Disables assertions. By default, assertions are disabled in all packages + and classes. With no arguments, `-disableassertions` (`-da`) disables + assertions in all packages and classes. With the *packagename* argument + ending in `...`, the switch disables assertions in the specified package + and any subpackages. If the argument is simply `...`, then the switch + disables assertions in the unnamed package in the current working + directory. With the *classname* argument, the switch disables assertions in + the specified class. + + The `-disableassertions` (`-da`) option applies to all class loaders and to + system classes (which don't have a class loader). There's one exception to + this rule: If the option is provided with no arguments, then it doesn't + apply to system classes. This makes it easy to disable assertions in all + classes except for system classes. The `-disablesystemassertions` option + enables you to disable assertions in all system classes. To explicitly + enable assertions in specific packages or classes, use the + `-enableassertions` (`-ea`) option. Both options can be used at the same + time. For example, to run the `MyClass` application with assertions enabled + in the package `com.wombat.fruitbat` (and any subpackages) but disabled in + the class `com.wombat.fruitbat.Brickbat`, use the following command: + + > `java -ea:com.wombat.fruitbat... -da:com.wombat.fruitbat.Brickbat + MyClass` + +`-disablesystemassertions` or `-dsa` +: Disables assertions in all system classes. + +`-enableassertions`\[`:`\[*packagename*\]...\|`:`*classname*\] or `-ea`\[`:`\[*packagename*\]...\|`:`*classname*\] +: Enables assertions. By default, assertions are disabled in all packages and + classes. With no arguments, `-enableassertions` (`-ea`) enables assertions + in all packages and classes. With the *packagename* argument ending in + `...`, the switch enables assertions in the specified package and any + subpackages. If the argument is simply `...`, then the switch enables + assertions in the unnamed package in the current working directory. With + the *classname* argument, the switch enables assertions in the specified + class. + + The `-enableassertions` (`-ea`) option applies to all class loaders and to + system classes (which don't have a class loader). There's one exception to + this rule: If the option is provided with no arguments, then it doesn't + apply to system classes. This makes it easy to enable assertions in all + classes except for system classes. The `-enablesystemassertions` option + provides a separate switch to enable assertions in all system classes. To + explicitly disable assertions in specific packages or classes, use the + `-disableassertions` (`-da`) option. If a single command contains multiple + instances of these switches, then they're processed in order, before + loading any classes. For example, to run the `MyClass` application with + assertions enabled only in the package `com.wombat.fruitbat` (and any + subpackages) but disabled in the class `com.wombat.fruitbat.Brickbat`, use + the following command: + + > `java -ea:com.wombat.fruitbat... -da:com.wombat.fruitbat.Brickbat + MyClass` + +`-enablesystemassertions` or `-esa` +: Enables assertions in all system classes. + +`-help`, `-h`, or `-?` +: Prints the help message to the error stream. + +`--help` +: Prints the help message to the output stream. + +`-javaagent:`*jarpath*\[`=`*options*\] +: Loads the specified Java programming language agent. See `java.lang.instrument`. + +`--show-version` +: Prints the product version to the output stream and continues. + +`-showversion` +: Prints the product version to the error stream and continues. + +`--show-module-resolution` +: Shows module resolution output during startup. + +`-splash:`*imagepath* +: Shows the splash screen with the image specified by *imagepath*. HiDPI + scaled images are automatically supported and used if available. The + unscaled image file name, such as `image.ext`, should always be passed as + the argument to the `-splash` option. The most appropriate scaled image + provided is picked up automatically. + + For example, to show the `splash.gif` file from the `images` directory when + starting your application, use the following option: + + > `-splash:images/splash.gif` + + See the SplashScreen API documentation for more information. + +`-verbose:class` +: Displays information about each loaded class. + +`-verbose:gc` +: Displays information about each garbage collection (GC) event. + +`-verbose:jni` +: Displays information about the use of native methods and other Java Native + Interface (JNI) activity. + +`-verbose:module` +: Displays information about the modules in use. + +`--version` +: Prints product version to the output stream and exits. + +`-version` +: Prints product version to the error stream and exits. + +`-X` +: Prints the help on extra options to the error stream. + +`--help-extra` +: Prints the help on extra options to the output stream. + +`@`*argfile* +: Specifies one or more argument files prefixed by `@` used by the `java` + command. It isn't uncommon for the `java` command line to be very long + because of the `.jar` files needed in the classpath. The `@`*argfile* + option overcomes command-line length limitations by enabling the launcher + to expand the contents of argument files after shell expansion, but before + argument processing. Contents in the argument files are expanded because + otherwise, they would be specified on the command line until the + `--disable-@files` option was encountered. + + The argument files can also contain the main class name and all options. If + an argument file contains all of the options required by the `java` + command, then the command line could simply be: + + > `java @`*argfile* + + See [java Command-Line Argument Files] for a description and examples of + using `@`-argfiles. + +## Extra Options for Java + +The following `java` options are general purpose options that are specific to +the Java HotSpot Virtual Machine. + +`-Xbatch` +: Disables background compilation. By default, the JVM compiles the method as + a background task, running the method in interpreter mode until the + background compilation is finished. The `-Xbatch` flag disables background + compilation so that compilation of all methods proceeds as a foreground + task until completed. This option is equivalent to + `-XX:-BackgroundCompilation`. + +`-Xbootclasspath/a:`*directories*\|*zip*\|*JAR-files* +: Specifies a list of directories, JAR files, and ZIP archives to append to + the end of the default bootstrap class path. + + On Windows, semicolons (`;`) separate entities in this list; + on other platforms it is a colon (`:`). + +`-Xcheck:jni` +: Performs additional checks for Java Native Interface (JNI) functions. + + The following checks are considered indicative of significant problems + with the native code, and the JVM terminates with an irrecoverable + error in such cases: + + - The thread doing the call is not attached to the JVM. + - The thread doing the call is using the `JNIEnv` belonging to another + thread. + - A parameter validation check fails: + - A `jfieldID`, or `jmethodID`, is detected as being invalid. For example: + - Of the wrong type + - Associated with the wrong class + - A parameter of the wrong type is detected. + - An invalid parameter value is detected. For example: + - NULL where not permitted + - An out-of-bounds array index, or frame capacity + - A non-UTF-8 string + - An invalid JNI reference + - An attempt to use a `ReleaseXXX` function on a parameter not + produced by the corresponding `GetXXX` function + + The following checks only result in warnings being printed: + + - A JNI call was made without checking for a pending exception from a + previous JNI call, and the current call is not safe when an exception + may be pending. + - A class descriptor is in decorated format (`Lname;`) when it should not be. + - A `NULL` parameter is allowed, but its use is questionable. + - Calling other JNI functions in the scope of `Get/ReleasePrimitiveArrayCritical` + or `Get/ReleaseStringCritical` + + Expect a performance degradation when this option is used. + +`-Xcomp` +: Testing mode to exercise JIT compilers. This option should not be used in production environments. + +`-Xdebug` +: Does nothing; deprecated for removal in a future release. + +`-Xdiag` +: Shows additional diagnostic messages. + +`-Xint` +: Runs the application in interpreted-only mode. Compilation to native code + is disabled, and all bytecode is executed by the interpreter. The + performance benefits offered by the just-in-time (JIT) compiler aren't + present in this mode. + +`-Xinternalversion` +: Displays more detailed JVM version information than the `-version` option, + and then exits. + +`-Xlog:`*option* +: Configure or enable logging with the Java Virtual Machine (JVM) unified + logging framework. See [Enable Logging with the JVM Unified Logging + Framework]. + +`-Xmixed` +: Executes all bytecode by the interpreter except for hot methods, which are + compiled to native code. On by default. Use `-Xint` to switch off. + +`-Xmn` *size* +: Sets the initial and maximum size (in bytes) of the heap for the young + generation (nursery) in the generational collectors. Append the letter + `k` or `K` to indicate kilobytes, `m` or `M` to indicate megabytes, or + `g` or `G` to indicate gigabytes. The young generation region of the heap + is used for new objects. GC is performed in this region more often than + in other regions. If the size for the young generation is too small, then + a lot of minor garbage collections are performed. If the size is too large, + then only full garbage collections are performed, which can take a long + time to complete. It is recommended that you do not set the size for the + young generation for the G1 collector, and keep the size for the young + generation greater than 25% and less than 50% of the overall heap size for + other collectors. + The following examples show how to set the initial and maximum size of + young generation to 256 MB using various units: + + ``` + -Xmn256m + -Xmn262144k + -Xmn268435456 + ``` + + Instead of the `-Xmn` option to set both the initial and maximum size of + the heap for the young generation, you can use `-XX:NewSize` to set the + initial size and `-XX:MaxNewSize` to set the maximum size. + +`-Xms` *size* +: Sets the minimum and the initial size (in bytes) of the heap. This value + must be a multiple of 1024 and greater than 1 MB. Append the letter `k` or + `K` to indicate kilobytes, `m` or `M` to indicate megabytes, or `g` or `G` + to indicate gigabytes. The following examples show how to set the size of + allocated memory to 6 MB using various units: + + ``` + -Xms6291456 + -Xms6144k + -Xms6m + ``` + + If you do not set this option, then the initial size will be set as the sum + of the sizes allocated for the old generation and the young generation. The + initial size of the heap for the young generation can be set using the + `-Xmn` option or the `-XX:NewSize` option. + + Note that the `-XX:InitialHeapSize` option can also be used to set the + initial heap size. If it appears after `-Xms` on the command line, then the + initial heap size gets set to the value specified with `-XX:InitialHeapSize`. + +`-Xmx` *size* +: Specifies the maximum size (in bytes) of the heap. This value + must be a multiple of 1024 and greater than 2 MB. Append the letter `k` or + `K` to indicate kilobytes, `m` or `M` to indicate megabytes, or `g` or `G` + to indicate gigabytes. The default value is chosen at runtime based on system + configuration. For server deployments, `-Xms` and `-Xmx` are often set to + the same value. The following examples show how to set the maximum allowed + size of allocated memory to 80 MB using various units: + + ``` + -Xmx83886080 + -Xmx81920k + -Xmx80m + ``` + + The `-Xmx` option is equivalent to `-XX:MaxHeapSize`. + +`-Xnoclassgc` +: Disables garbage collection (GC) of classes. This can save some GC time, + which shortens interruptions during the application run. When you specify + `-Xnoclassgc` at startup, the class objects in the application are left + untouched during GC and are always be considered live. This can result in + more memory being permanently occupied which, if not used carefully, throws + an out-of-memory exception. + +`-Xrs` +: Reduces the use of operating system signals by the JVM. Shutdown hooks + enable the orderly shutdown of a Java application by running user cleanup + code (such as closing database connections) at shutdown, even if the JVM + terminates abruptly. + + - **Non-Windows:** + + - The JVM catches signals to implement shutdown hooks for unexpected + termination. The JVM uses `SIGHUP`, `SIGINT`, and `SIGTERM` to + initiate the running of shutdown hooks. + + - Applications embedding the JVM frequently need to trap signals such + as `SIGINT` or `SIGTERM`, which can lead to interference with the + JVM signal handlers. The `-Xrs` option is available to address this + issue. When `-Xrs` is used, the signal masks for `SIGINT`, + `SIGTERM`, `SIGHUP`, and `SIGQUIT` aren't changed by the JVM, and + signal handlers for these signals aren't installed. + + - **Windows:** + + - The JVM watches for console control events to implement shutdown + hooks for unexpected termination. Specifically, the JVM registers a + console control handler that begins shutdown-hook processing and + returns `TRUE` for `CTRL_C_EVENT`, `CTRL_CLOSE_EVENT`, + `CTRL_LOGOFF_EVENT`, and `CTRL_SHUTDOWN_EVENT`. + + - The JVM uses a similar mechanism to implement the feature of + dumping thread stacks for debugging purposes. The JVM uses + `CTRL_BREAK_EVENT` to perform thread dumps. + + - If the JVM is run as a service (for example, as a servlet engine + for a web server), then it can receive `CTRL_LOGOFF_EVENT` but + shouldn't initiate shutdown because the operating system doesn't + actually terminate the process. To avoid possible interference such + as this, the `-Xrs` option can be used. When the `-Xrs` option is + used, the JVM doesn't install a console control handler, implying + that it doesn't watch for or process `CTRL_C_EVENT`, + `CTRL_CLOSE_EVENT`, `CTRL_LOGOFF_EVENT`, or `CTRL_SHUTDOWN_EVENT`. + + There are two consequences of specifying `-Xrs`: + + - **Non-Windows:** `SIGQUIT` thread dumps aren't + available. + + - **Windows:** Ctrl + Break thread dumps aren't available. + + User code is responsible for causing shutdown hooks to run, for example, by + calling `System.exit()` when the JVM is to be terminated. + +`-Xshare:`*mode* +: Sets the class data sharing (CDS) mode. + + Possible *mode* arguments for this option include the following: + + `auto` + : Use shared class data if possible (default). + + `on` + : Require using shared class data, otherwise fail. + + > **Note:** The `-Xshare:on` option is used for testing purposes only. + It may cause the VM to unexpectedly exit during start-up when the CDS + archive cannot be used (for example, when certain VM parameters are changed, + or when a different JDK is used). This option should not be used + in production environments. + + `off` + : Do not attempt to use shared class data. + +`-XshowSettings` +: Shows all settings and then continues. + +`-XshowSettings:`*category* +: Shows settings and continues. Possible *category* arguments for this option + include the following: + + `all` + : Shows all categories of settings in **verbose** detail. + + `locale` + : Shows settings related to locale. + + `properties` + : Shows settings related to system properties. + + `security` + : Shows all settings related to security. + + sub-category arguments for `security` include the following: + + * `security:all` : shows all security settings + * `security:properties` : shows security properties + * `security:providers` : shows static security provider settings + * `security:tls` : shows TLS related security settings + + `vm` + : Shows the settings of the JVM. + + `system` + : **Linux only:** Shows host system or container configuration and continues. + +`-Xss` *size* +: Sets the thread stack size (in bytes). Append the letter `k` or `K` to + indicate KB, `m` or `M` to indicate MB, or `g` or `G` to indicate GB. The + actual size may be rounded up to a multiple of the system page size as + required by the operating system. The default value depends on the + platform. For example: + + - Linux/x64: 1024 KB + + - Linux/Aarch64: 2048 KB + + - macOS/x64: 1024 KB + + - macOS/Aarch64: 2048 KB + + - Windows: The default value depends on virtual memory + + The following examples set the thread stack size to 1024 KB in different + units: + + ``` + -Xss1m + -Xss1024k + -Xss1048576 + ``` + + This option is similar to `-XX:ThreadStackSize`. + +`--add-reads` *module*`=`*target-module*(`,`*target-module*)\* +: Updates *module* to read the *target-module*, regardless of the module + declaration. *target-module* can be `ALL-UNNAMED` to read all unnamed + modules. + +`--add-exports` *module*`/`*package*`=`*target-module*(`,`*target-module*)\* +: Updates *module* to export *package* to *target-module*, regardless of + module declaration. *target-module* can be `ALL-UNNAMED` to export to all + unnamed modules. + +`--add-opens` *module*`/`*package*`=`*target-module*(`,`*target-module*)\* +: Updates *module* to open *package* to *target-module*, regardless of module + declaration. + +`--limit-modules` *module*\[`,`*module*...\] +: Specifies the limit of the universe of observable modules. + +`--patch-module` *module*`=`*file*(`;`*file*)\* +: Overrides or augments a module with classes and resources in JAR files or + directories. + +`--source` *version* +: Sets the version of the source in source-file mode. + + +`--sun-misc-unsafe-memory-access=` *value* +: Allow or deny usage of unsupported API `sun.misc.Unsafe`. *value* is one of: + + `allow` + : Allow use of the memory-access methods with no warnings at run time. + + `warn` + : Allow use of the memory-access methods, but issues a warning on the first + occasion that any memory-access method is used. At most one warning is + issued. + + `debug` + : Allow use of the memory-access methods, but issue a one-line warning and + a stack trace when any memory-access method is used. + + `deny` + : Disallow use of the memory-access methods by throwing an + `UnsupportedOperationException` on every usage. + + The default value when the option is not specified is `allow`. + + +## Extra Options for macOS + +The following extra options are macOS specific. + +`-XstartOnFirstThread` +: Runs the `main()` method on the first (AppKit) thread. + +`-Xdock:name=`*application\_name* +: Overrides the default application name displayed in dock. + +`-Xdock:icon=`*path\_to\_icon\_file* +: Overrides the default icon displayed in dock. + +## Advanced Options for Java + +These `java` options can be used to enable other advanced options. + +`-XX:+UnlockDiagnosticVMOptions` +: Unlocks the options intended for diagnosing the JVM. By default, this + option is disabled and diagnostic options aren't available. + + Command line options that are enabled with the use of this option are + not supported. If you encounter issues while using any of these + options, it is very likely that you will be required to reproduce the + problem without using any of these unsupported options before Oracle + Support can assist with an investigation. It is also possible that any + of these options may be removed or their behavior changed without any + warning. + +`-XX:+UnlockExperimentalVMOptions` +: Unlocks the options that provide experimental features in the JVM. + By default, this option is disabled and experimental features aren't available. + +## Advanced Runtime Options for Java + +These `java` options control the runtime behavior of the Java HotSpot VM. + +`-XX:ActiveProcessorCount=`*x* +: Overrides the number of CPUs that the VM will use to calculate the size of + thread pools it will use for various operations such as Garbage Collection + and ForkJoinPool. + + The VM normally determines the number of available processors from the + operating system. This flag can be useful for partitioning CPU resources + when running multiple Java processes in docker containers. This flag is + honored even if `UseContainerSupport` is not enabled. See + `-XX:-UseContainerSupport` for a description of enabling and disabling + container support. + +`-XX:AllocateHeapAt=`*path* +: Takes a path to the file system and uses memory mapping to allocate the + object heap on the memory device. Using this option enables the HotSpot VM + to allocate the Java object heap on an alternative memory device, such as + an NV-DIMM, specified by the user. + + Alternative memory devices that have the same semantics as DRAM, including + the semantics of atomic operations, can be used instead of DRAM for the + object heap without changing the existing application code. All other + memory structures (such as the code heap, metaspace, and thread stacks) + continue to reside in DRAM. + + Some operating systems expose non-DRAM memory through the file system. + Memory-mapped files in these file systems bypass the page cache and provide + a direct mapping of virtual memory to the physical memory on the device. + The existing heap related flags (such as `-Xmx` and `-Xms`) and + garbage-collection related flags continue to work as before. + +`-XX:-CompactStrings` +: Disables the Compact Strings feature. By default, this option is enabled. + When this option is enabled, Java Strings containing only single-byte + characters are internally represented and stored as + single-byte-per-character Strings using ISO-8859-1 / Latin-1 encoding. This + reduces, by 50%, the amount of space required for Strings containing only + single-byte characters. For Java Strings containing at least one multibyte + character: these are represented and stored as 2 bytes per character using + UTF-16 encoding. Disabling the Compact Strings feature forces the use of + UTF-16 encoding as the internal representation for all Java Strings. + + Cases where it may be beneficial to disable Compact Strings include the + following: + + - When it's known that an application overwhelmingly will be allocating + multibyte character Strings + + - In the unexpected event where a performance regression is observed in + migrating from Java SE 8 to Java SE 9 and an analysis shows that + Compact Strings introduces the regression + + In both of these scenarios, disabling Compact Strings makes sense. + +`-XX:ErrorFile=`*filename* +: Specifies the path and file name to which error data is written when an + irrecoverable error occurs. By default, this file is created in the current + working directory and named `hs_err_pid`*pid*`.log` where *pid* is the + identifier of the process that encountered the error. + + The following example shows how to set the default log file (note that the + identifier of the process is specified as `%p`): + + > `-XX:ErrorFile=./hs_err_pid%p.log` + + - **Non-Windows:** The following example shows how to + set the error log to `/var/log/java/java_error.log`: + + > `-XX:ErrorFile=/var/log/java/java_error.log` + + - **Windows:** The following example shows how to set the error log file + to `C:/log/java/java_error.log`: + + > `-XX:ErrorFile=C:/log/java/java_error.log` + + If the file exists, and is writeable, then it will be overwritten. + Otherwise, if the file can't be created in the specified directory (due to + insufficient space, permission problem, or another issue), then the file is + created in the temporary directory for the operating system: + + - **Non-Windows:** The temporary directory is `/tmp`. + + - **Windows:** The temporary directory is specified by the value of the + `TMP` environment variable; if that environment variable isn't defined, + then the value of the `TEMP` environment variable is used. + +`-XX:+ExtensiveErrorReports` +: Enables the reporting of more extensive error information in the `ErrorFile`. + This option can be turned on in environments where maximal information is + desired - even if the resulting logs may be quite large and/or contain + information that might be considered sensitive. The information can vary + from release to release, and across different platforms. By default this + option is disabled. + +`-XX:FlightRecorderOptions=`*parameter*`=`*value* (or) `-XX:FlightRecorderOptions:`*parameter*`=`*value* +: Sets the parameters that control the behavior of JFR. Multiple parameters can be specified + by separating them with a comma. + + The following list contains the available JFR *parameter*`=`*value* + entries: + + `globalbuffersize=`*size* + : Specifies the total amount of primary memory used for data retention. + The default value is based on the value specified for `memorysize`. + Change the `memorysize` parameter to alter the size of global buffers. + + `maxchunksize=`*size* + : Specifies the maximum size (in bytes) of the data chunks in a + recording. Append `m` or `M` to specify the size in megabytes (MB), or + `g` or `G` to specify the size in gigabytes (GB). By default, the + maximum size of data chunks is set to 12 MB. The minimum allowed is 1 + MB. + + `memorysize=`*size* + : Determines how much buffer memory should be used, and sets the + `globalbuffersize` and `numglobalbuffers` parameters based on the size + specified. Append `m` or `M` to specify the size in megabytes (MB), or + `g` or `G` to specify the size in gigabytes (GB). By default, the + memory size is set to 10 MB. + + `numglobalbuffers` + : Specifies the number of global buffers used. The default value is based + on the memory size specified. Change the `memorysize` parameter to + alter the number of global buffers. + + `old-object-queue-size=number-of-objects` + : Maximum number of old objects to track. By default, the number of + objects is set to 256. + + `preserve-repository=`{`true`\|`false`} + : Specifies whether files stored in the disk repository should be kept + after the JVM has exited. If false, files are deleted. By default, + this parameter is disabled. + + `repository=`*path* + : Specifies the repository (a directory) for temporary disk storage. By + default, the system's temporary directory is used. + + `retransform=`{`true`\|`false`} + : Specifies whether event classes should be retransformed using JVMTI. If + false, instrumentation is added when event classes are loaded. By + default, this parameter is enabled. + + `stackdepth=`*depth* + : Stack depth for stack traces. By default, the depth is set to 64 method + calls. The maximum is 2048. Values greater than 64 could create + significant overhead and reduce performance. + + `threadbuffersize=`*size* + : Specifies the per-thread local buffer size (in bytes). By default, the + local buffer size is set to 8 kilobytes, with a minimum value of + 4 kilobytes. Overriding this parameter + could reduce performance and is not recommended. + +`-XX:LargePageSizeInBytes=`*size* +: Sets the maximum large page size (in bytes) used by the JVM. The + *size* argument must be a valid page size supported by the environment + to have any effect. Append the letter `k` or `K` to indicate kilobytes, + `m` or `M` to indicate megabytes, or `g` or `G` to indicate gigabytes. + By default, the size is set to 0, meaning that the JVM will use the + default large page size for the environment as the maximum size for + large pages. See [Large Pages]. + + The following example describes how to set the large page size to 1 + gigabyte (GB): + + > `-XX:LargePageSizeInBytes=1g` + +`-XX:MaxDirectMemorySize=`*size* +: Sets the maximum total size (in bytes) of the `java.nio` package, + direct-buffer allocations. Append the letter `k` or `K` to indicate + kilobytes, `m` or `M` to indicate megabytes, or `g` or `G` to indicate + gigabytes. If not set, the flag is ignored and the JVM chooses the size + for NIO direct-buffer allocations automatically. + + The following examples illustrate how to set the NIO size to 1024 KB in + different units: + + ``` + -XX:MaxDirectMemorySize=1m + -XX:MaxDirectMemorySize=1024k + -XX:MaxDirectMemorySize=1048576 + ``` + +`-XX:-MaxFDLimit` +: Disables the attempt to set the soft limit for the number of open file + descriptors to the hard limit. By default, this option is enabled on all + platforms, but is ignored on Windows. The only time that you may need to + disable this is on macOS, where its use imposes a maximum of 10240, which + is lower than the actual system maximum. + +`-XX:NativeMemoryTracking=`*mode* +: Specifies the mode for tracking JVM native memory usage. Possible *mode* + arguments for this option include the following: + + `off` + : Instructs not to track JVM native memory usage. This is the default + behavior if you don't specify the `-XX:NativeMemoryTracking` option. + + `summary` + : Tracks memory usage only by JVM subsystems, such as Java heap, class, + code, and thread. + + `detail` + : In addition to tracking memory usage by JVM subsystems, track memory + usage by individual `CallSite`, individual virtual memory region and + its committed regions. + +`-XX:TrimNativeHeapInterval=`*millis* +: Interval, in ms, at which the JVM will trim the native heap. Lower values + will reclaim memory more eagerly at the cost of higher overhead. A value + of 0 (default) disables native heap trimming. + Native heap trimming is performed in a dedicated thread. + + This option is only supported on Linux with GNU C Library (glibc). + +`-XX:+NeverActAsServerClassMachine` +: Enable the "Client VM emulation" mode which only uses the C1 JIT compiler, + a 32Mb CodeCache and the Serial GC. The maximum amount of memory that the + JVM may use (controlled by the `-XX:MaxRAM=n` flag) is set to 1GB by default. + The string "emulated-client" is added to the JVM version string. + + By default the flag is set to `true` only on Windows in 32-bit mode and + `false` in all other cases. + + The "Client VM emulation" mode will not be enabled if any of the following + flags are used on the command line: + + ``` + -XX:{+|-}TieredCompilation + -XX:CompilationMode=mode + -XX:TieredStopAtLevel=n + -XX:{+|-}EnableJVMCI + -XX:{+|-}UseJVMCICompiler + ``` + +`-XX:ObjectAlignmentInBytes=`*alignment* +: Sets the memory alignment of Java objects (in bytes). By default, the value + is set to 8 bytes. The specified value should be a power of 2, and must be + within the range of 8 and 256 (inclusive). This option makes it possible to + use compressed pointers with large Java heap sizes. + + The heap size limit in bytes is calculated as: + + > `4GB * ObjectAlignmentInBytes` + + > **Note:** As the alignment value increases, the unused space between objects also + increases. As a result, you may not realize any benefits from using + compressed pointers with large Java heap sizes. + +`-XX:OnError=`*string* +: Sets a custom command or a series of semicolon-separated commands to run + when an irrecoverable error occurs. If the string contains spaces, then it + must be enclosed in quotation marks. + + - **Non-Windows:** The following example shows how + the `-XX:OnError` option can be used to run the `gcore` command to + create a core image, and start the `gdb` debugger to attach to the + process in case of an irrecoverable error (the `%p` designates the + current process identifier): + + > `-XX:OnError="gcore %p;gdb -p %p"` + + - **Windows:** The following example shows how the `-XX:OnError` option + can be used to run the `userdump.exe` utility to obtain a crash dump in + case of an irrecoverable error (the `%p` designates the current + process identifier). This example assumes that the path to the `userdump.exe` + utility is specified in the `PATH` environment variable: + + > `-XX:OnError="userdump.exe %p"` + +`-XX:OnOutOfMemoryError=`*string* +: Sets a custom command or a series of semicolon-separated commands to run + when an `OutOfMemoryError` exception is first thrown. If the string + contains spaces, then it must be enclosed in quotation marks. For an + example of a command string, see the description of the `-XX:OnError` + option. + +`-XX:+PrintCommandLineFlags` +: Enables printing of ergonomically selected JVM flags that appeared on the + command line. It can be useful to know the ergonomic values set by the JVM, + such as the heap space size and the selected garbage collector. By default, + this option is disabled and flags aren't printed. + +`-XX:+PreserveFramePointer` +: Selects between using the RBP register as a general purpose register + (`-XX:-PreserveFramePointer`) and using the RBP register to hold the frame + pointer of the currently executing method (`-XX:+PreserveFramePointer` . If + the frame pointer is available, then external profiling tools (for example, + Linux perf) can construct more accurate stack traces. + +`-XX:+PrintNMTStatistics` +: Enables printing of collected native memory tracking data at JVM exit when + native memory tracking is enabled (see `-XX:NativeMemoryTracking`). By + default, this option is disabled and native memory tracking data isn't + printed. + +`-XX:SharedArchiveFile=`*path* +: Specifies the path and name of the class data sharing (CDS) archive file + + See [Application Class Data Sharing]. + +`-XX:+VerifySharedSpaces` +: If this option is specified, the JVM will load a CDS archive file only if it + passes an integrity check based on CRC32 checksums. The purpose of this flag is + to check for unintentional damage to CDS archive files in transmission or storage. + To guarantee the security and proper operation of CDS, the user must + ensure that the CDS archive files used by Java applications cannot be modified without + proper authorization. + +`-XX:SharedArchiveConfigFile=`*shared\_config\_file* +: Specifies additional shared data added to the archive file. + +`-XX:SharedClassListFile=`*file\_name* +: Specifies the text file that contains the names of the classes to store in + the class data sharing (CDS) archive. This file contains the full name of + one class per line, except slashes (`/`) replace dots (`.`). For example, + to specify the classes `java.lang.Object` and `hello.Main`, create a text + file that contains the following two lines: + + ``` + java/lang/Object + hello/Main + ``` + + The classes that you specify in this text file should include the classes + that are commonly used by the application. They may include any classes + from the application, extension, or bootstrap class paths. + + See [Application Class Data Sharing]. + +`-XX:+ShowCodeDetailsInExceptionMessages` +: Enables printing of improved `NullPointerException` messages. When an application throws a + `NullPointerException`, the option enables the JVM to analyze the program's bytecode + instructions to determine precisely which reference is `null`, + and describes the source with a null-detail message. + The null-detail message is calculated and returned by `NullPointerException.getMessage()`, + and will be printed as the exception message along with + the method, filename, and line number. By default, this option is enabled. + +`-XX:+ShowMessageBoxOnError` +: Enables the display of a dialog box when the JVM experiences an + irrecoverable error. This prevents the JVM from exiting and keeps the + process active so that you can attach a debugger to it to investigate the + cause of the error. By default, this option is disabled. + +`-XX:StartFlightRecording:`*parameter*`=`*value* +: Starts a JFR recording for the Java application. This option is equivalent + to the `JFR.start` diagnostic command that starts a recording during + runtime. `-XX:StartFlightRecording:help` prints available options and + example command lines. You can set the following *parameter*`=`*value* + entries when starting a JFR recording: + + `delay=`*time* + : Specifies the delay between the Java application launch time and the + start of the recording. Append `s` to specify the time in seconds, `m` + for minutes, `h` for hours, or `d` for days (for example, specifying + `10m` means 10 minutes). By default, there's no delay, and this + parameter is set to 0. + + `disk=`{`true`\|`false`} + : Specifies whether to write data to disk while recording. By default, + this parameter is enabled. + + `dumponexit=`{`true`\|`false`} + : Specifies if the running recording is dumped when the JVM shuts down. + If enabled and a `filename` is not entered, the recording is written to + a file in the directory where the process was started. The file name is + a system-generated name that contains the process ID, recording ID, and + current timestamp, similar to + `hotspot-pid-47496-id-1-2018_01_25_19_10_41.jfr`. By default, this + parameter is disabled. + + `duration=`*time* + : Specifies the duration of the recording. Append `s` to specify the time + in seconds, `m` for minutes, `h` for hours, or `d` for days (for + example, specifying `5h` means 5 hours). By default, the duration isn't + limited, and this parameter is set to 0. + + `filename=`*path* + : Specifies the path and name of the file to which the recording is + written when the recording is stopped, for example: + + - `recording.jfr` + - `/home/user/recordings/recording.jfr` + - `c:\recordings\recording.jfr` + + If %p and/or %t is specified in the filename, it expands to the JVM's + PID and the current timestamp, respectively. The filename may also be + a directory in which case, the filename is generated from the PID + and the current date in the specified directory. + + `name=`*identifier* + : Takes both the name and the identifier of a recording. + + `maxage=`*time* + : Specifies the maximum age of disk data to keep for the recording. This + parameter is valid only when the `disk` parameter is set to `true`. + Append `s` to specify the time in seconds, `m` for minutes, `h` for + hours, or `d` for days (for example, specifying `30s` means 30 + seconds). By default, the maximum age isn't limited, and this parameter + is set to `0s`. + + `maxsize=`*size* + : Specifies the maximum size (in bytes) of disk data to keep for the + recording. This parameter is valid only when the `disk` parameter is + set to `true`. The value must not be less than the value for the + `maxchunksize` parameter set with `-XX:FlightRecorderOptions`. Append + `m` or `M` to specify the size in megabytes, or `g` or `G` to specify + the size in gigabytes. By default, the maximum size of disk data isn't + limited, and this parameter is set to `0`. + + `path-to-gc-roots=`{`true`\|`false`} + : Specifies whether to collect the path to garbage collection (GC) roots + at the end of a recording. By default, this parameter is disabled. + + The path to GC roots is useful for finding memory leaks, but collecting + it is time-consuming. Enable this option only when you start a + recording for an application that you suspect has a memory leak. If the + `settings` parameter is set to `profile`, the stack trace from where + the potential leaking object was allocated is included in the + information collected. + + `settings=`*path* + : Specifies the path and name of the event settings file (of type JFC). + By default, the `default.jfc` file is used, which is located in + `JAVA_HOME/lib/jfr`. This default settings file collects a predefined + set of information with low overhead, so it has minimal impact on + performance and can be used with recordings that run continuously. + + A second settings file is also provided, profile.jfc, which provides + more data than the default configuration, but can have more overhead + and impact performance. Use this configuration for short periods of + time when more information is needed. + + You can specify values for multiple parameters by separating them with a + comma. Event settings and .jfc options can be specified using the + following syntax: + + `option=`*value* + : Specifies the option value to modify. To list available options, use + the `JAVA_HOME`/bin/jfr tool. + + `event-setting=`*value* + : Specifies the event setting value to modify. Use the form: + `#=`. + To add a new event setting, prefix the event name with '+'. + + You can specify values for multiple event settings and .jfc options by + separating them with a comma. In case of a conflict between a parameter + and a .jfc option, the parameter will take precedence. The whitespace + delimiter can be omitted for timespan values, i.e. 20ms. For more + information about the settings syntax, see Javadoc of the jdk.jfr + package. + + To only see warnings and errors from JFR during startup set + -Xlog:jfr+startup=warning. + +`-XX:ThreadStackSize=`*size* +: Sets the Java thread stack size (in kilobytes). Use of a scaling suffix, + such as `k`, results in the scaling of the kilobytes value so that + `-XX:ThreadStackSize=1k` sets the Java thread stack size to 1024\*1024 + bytes or 1 megabyte. The default value depends on the platform. For example: + + - Linux/x64: 1024 KB + + - Linux/Aarch64: 2048 KB + + - macOS/x64: 1024 KB + + - macOS/Aarch64: 2048 KB + + - Windows: The default value depends on virtual memory + + The following examples show how to set the thread stack size to 1 megabyte + in different units: + + ``` + -XX:ThreadStackSize=1k + -XX:ThreadStackSize=1024 + ``` + + This option is similar to `-Xss`. + +`-XX:-UseCompressedOops` +: Disables the use of compressed pointers. By default, this option is + enabled, and compressed pointers are used. This will automatically limit + the maximum ergonomically determined Java heap size to the maximum amount + of memory that can be covered by compressed pointers. By default this range + is 32 GB. + + With compressed oops enabled, object references are represented + as 32-bit offsets instead of 64-bit pointers, which typically increases + performance when running the application with Java heap sizes smaller than + the compressed oops pointer range. This option works only for 64-bit JVMs. + + It's possible to use compressed pointers with Java heap sizes greater than + 32 GB. See the `-XX:ObjectAlignmentInBytes` option. + +`-XX:-UseContainerSupport` +: **Linux only:** The VM now provides automatic container detection support, which allows the + VM to determine the amount of memory and number of processors that are + available to a Java process running in docker containers. It uses this + information to allocate system resources. The default for this flag is `true`, + and container support is enabled by default. It can be disabled + with `-XX:-UseContainerSupport`. + + Unified Logging is available to help to diagnose issues related to this + support. + + Use `-Xlog:os+container=trace` for maximum logging of container + information. See [Enable Logging with the JVM Unified Logging Framework] + for a description of using Unified Logging. + +`-XX:+UseLargePages` +: Enables the use of large page memory. By default, this option is disabled + and large page memory isn't used. + + See [Large Pages]. + +`-XX:+UseTransparentHugePages` +: **Linux only:** Enables the use of large pages that can dynamically grow or + shrink. This option is disabled by default. You may encounter performance + problems with transparent huge pages as the OS moves other pages around to + create huge pages; this option is made available for experimentation. + +`-XX:+AllowUserSignalHandlers` +: **Non-Windows:** Enables installation of signal handlers by the application. By default, + this option is disabled and the application isn't allowed to install signal + handlers. + +`-XX:VMOptionsFile=`*filename* +: Allows user to specify VM options in a file, for example, + `java -XX:VMOptionsFile=/var/my_vm_options HelloWorld`. + +`-XX:UseBranchProtection=`*mode* +: **Linux AArch64 only:** Specifies the branch protection mode. + All options other than + `none` require the VM to have been built with branch protection + enabled. In addition, for full protection, any native libraries + provided by applications should be compiled with the same level + of protection. + + Possible *mode* arguments for this option include the following: + + `none` + : Do not use branch protection. This is the default value. + + `standard` + : Enables all branch protection modes available on the current platform. + + `pac-ret` + : Enables protection against ROP based attacks. (AArch64 8.3+ only) + +## Advanced JIT Compiler Options for java + +These `java` options control the dynamic just-in-time (JIT) compilation +performed by the Java HotSpot VM. + +`-XX:AllocateInstancePrefetchLines=`*lines* +: Sets the number of lines to prefetch ahead of the instance allocation + pointer. By default, the number of lines to prefetch is set to 1: + + > `-XX:AllocateInstancePrefetchLines=1` + + +`-XX:AllocatePrefetchDistance=`*size* +: Sets the size (in bytes) of the prefetch distance for object allocation. + Memory about to be written with the value of new objects is prefetched up + to this distance starting from the address of the last allocated object. + Each Java thread has its own allocation point. + + Negative values denote that prefetch distance is chosen based on the + platform. Positive values are bytes to prefetch. Append the letter `k` or + `K` to indicate kilobytes, `m` or `M` to indicate megabytes, or `g` or `G` + to indicate gigabytes. The default value is set to -1. + + The following example shows how to set the prefetch distance to 1024 bytes: + + > `-XX:AllocatePrefetchDistance=1024` + + +`-XX:AllocatePrefetchInstr=`*instruction* +: Sets the prefetch instruction to prefetch ahead of the allocation pointer. + Possible values are from 0 to 3. The actual instructions behind the values + depend on the platform. By default, the prefetch instruction is set to 0: + + > `-XX:AllocatePrefetchInstr=0` + + +`-XX:AllocatePrefetchLines=`*lines* +: Sets the number of cache lines to load after the last object allocation by + using the prefetch instructions generated in compiled code. The default + value is 1 if the last allocated object was an instance, and 3 if it was an + array. + + The following example shows how to set the number of loaded cache lines to + 5: + + > `-XX:AllocatePrefetchLines=5` + + +`-XX:AllocatePrefetchStepSize=`*size* +: Sets the step size (in bytes) for sequential prefetch instructions. Append + the letter `k` or `K` to indicate kilobytes, `m` or `M` to indicate + megabytes, `g` or `G` to indicate gigabytes. By default, the step size is + set to 16 bytes: + + > `-XX:AllocatePrefetchStepSize=16` + + +`-XX:AllocatePrefetchStyle=`*style* +: Sets the generated code style for prefetch instructions. The *style* + argument is an integer from 0 to 3: + + `0` + : Don't generate prefetch instructions. + + `1` + : Execute prefetch instructions after each allocation. This is the + default setting. + + `2` + : Use the thread-local allocation block (TLAB) watermark pointer to + determine when prefetch instructions are executed. + + `3` + : Generate one prefetch instruction per cache line. + + +`-XX:+BackgroundCompilation` +: Enables background compilation. This option is enabled by default. To + disable background compilation, specify `-XX:-BackgroundCompilation` (this + is equivalent to specifying `-Xbatch`). + +`-XX:CICompilerCount=`*threads* +: Sets the number of compiler threads to use for compilation. + By default, the number of compiler threads is selected automatically + depending on the number of CPUs and memory available for compiled code. + The following example shows how to set the number of threads to 2: + + > `-XX:CICompilerCount=2` + +`-XX:+UseDynamicNumberOfCompilerThreads` +: Dynamically create compiler thread up to the limit specified by `-XX:CICompilerCount`. + This option is enabled by default. + +`-XX:CompileCommand=`*command*`,`*method*\[`,`*option*\] +: Specifies a *command* to perform on a *method*. For example, to exclude the + `indexOf()` method of the `String` class from being compiled, use the + following: + + > `-XX:CompileCommand=exclude,java/lang/String.indexOf` + + Note that the full class name is specified, including all packages and + subpackages separated by a slash (`/`). For easier cut-and-paste + operations, it's also possible to use the method name format produced by + the `-XX:+PrintCompilation` and `-XX:+LogCompilation` options: + + > `-XX:CompileCommand=exclude,java.lang.String::indexOf` + + If the method is specified without the signature, then the command is + applied to all methods with the specified name. However, you can also + specify the signature of the method in the class file format. In this case, + you should enclose the arguments in quotation marks, because otherwise the + shell treats the semicolon as a command end. For example, if you want to + exclude only the `indexOf(String)` method of the `String` class from being + compiled, use the following: + + > `-XX:CompileCommand="exclude,java/lang/String.indexOf,(Ljava/lang/String;)I"` + + You can also use the asterisk (\*) as a wildcard for class and method + names. For example, to exclude all `indexOf()` methods in all classes from + being compiled, use the following: + + > `-XX:CompileCommand=exclude,*.indexOf` + + The commas and periods are aliases for spaces, making it easier to pass + compiler commands through a shell. You can pass arguments to + `-XX:CompileCommand` using spaces as separators by enclosing the argument + in quotation marks: + + > `-XX:CompileCommand="exclude java/lang/String indexOf"` + + Note that after parsing the commands passed on the command line using the + `-XX:CompileCommand` options, the JIT compiler then reads commands from the + `.hotspot_compiler` file. You can add commands to this file or specify a + different file using the `-XX:CompileCommandFile` option. + + To add several commands, either specify the `-XX:CompileCommand` option + multiple times, or separate each argument with the new line separator + (`\n`). The following commands are available: + + `break` + : Sets a breakpoint when debugging the JVM to stop at the beginning of + compilation of the specified method. + + `compileonly` + : Excludes all methods from compilation except for the specified method. + As an alternative, you can use the `-XX:CompileOnly` option, which lets + you specify several methods. + + `dontinline` + : Prevents inlining of the specified method. + + `exclude` + : Excludes the specified method from compilation. + + `help` + : Prints a help message for the `-XX:CompileCommand` option. + + `inline` + : Attempts to inline the specified method. + + `log` + : Excludes compilation logging (with the `-XX:+LogCompilation` option) + for all methods except for the specified method. By default, logging is + performed for all compiled methods. + + `option` + : Passes a JIT compilation option to the specified method in place of the + last argument (`option`). The compilation option is set at the end, + after the method name. For example, to enable the + `BlockLayoutByFrequency` option for the `append()` method of the + `StringBuffer` class, use the following: + + > `-XX:CompileCommand=option,java/lang/StringBuffer.append,BlockLayoutByFrequency` + + You can specify multiple compilation options, separated by commas or + spaces. + + `print` + : Prints generated assembler code after compilation of the specified + method. + + `quiet` + : Instructs not to print the compile commands. By default, the commands + that you specify with the `-XX:CompileCommand` option are printed; for + example, if you exclude from compilation the `indexOf()` method of the + `String` class, then the following is printed to standard output: + + > `CompilerOracle: exclude java/lang/String.indexOf` + + You can suppress this by specifying the `-XX:CompileCommand=quiet` + option before other `-XX:CompileCommand` options. + +`-XX:CompileCommandFile=`*filename* +: Sets the file from which JIT compiler commands are read. By default, the + `.hotspot_compiler` file is used to store commands performed by the JIT + compiler. + + Each line in the command file represents a command, a class name, and a + method name for which the command is used. For example, this line prints + assembly code for the `toString()` method of the `String` class: + + > `print java/lang/String toString` + + If you're using commands for the JIT compiler to perform on methods, then + see the `-XX:CompileCommand` option. + +`-XX:CompilerDirectivesFile=`*file* +: Adds directives from a file to the directives stack when a program starts. + See [Compiler Control](https://docs.oracle.com/en/java/javase/12/vm/compiler-control1.html#GUID-94AD8194-786A-4F19-BFFF-278F8E237F3A). + + The `-XX:CompilerDirectivesFile` option has to be used together with the + `-XX:UnlockDiagnosticVMOptions` option that unlocks diagnostic JVM options. + + +`-XX:+CompilerDirectivesPrint` +: Prints the directives stack when the program starts or when a new directive + is added. + + The `-XX:+CompilerDirectivesPrint` option has to be used together with the + `-XX:UnlockDiagnosticVMOptions` option that unlocks diagnostic JVM options. + +`-XX:CompileOnly=`*methods* +: Sets the list of methods (separated by commas) to which compilation should + be restricted. Only the specified methods are compiled. + + `-XX:CompileOnly=method1,method2,...,methodN` is an alias for: + ``` + -XX:CompileCommand=compileonly,method1 + -XX:CompileCommand=compileonly,method2 + ... + -XX:CompileCommand=compileonly,methodN + ``` + +`-XX:CompileThresholdScaling=`*scale* +: Provides unified control of first compilation. This option controls when + methods are first compiled for both the tiered and the nontiered modes of + operation. The `CompileThresholdScaling` option has a floating point value + between 0 and +Inf and scales the thresholds corresponding to the current + mode of operation (both tiered and nontiered). Setting + `CompileThresholdScaling` to a value less than 1.0 results in earlier + compilation while values greater than 1.0 delay compilation. Setting + `CompileThresholdScaling` to 0 is equivalent to disabling compilation. + +`-XX:+DoEscapeAnalysis` +: Enables the use of escape analysis. This option is enabled by default. To + disable the use of escape analysis, specify `-XX:-DoEscapeAnalysis`. + +`-XX:InitialCodeCacheSize=`*size* +: Sets the initial code cache size (in bytes). Append the letter `k` or `K` + to indicate kilobytes, `m` or `M` to indicate megabytes, or `g` or `G` to + indicate gigabytes. The default value depends on the platform. The initial code + cache size shouldn't be less than the system's minimal memory page size. + The following example shows how to set the initial code cache size to 32 + KB: + + > `-XX:InitialCodeCacheSize=32k` + +`-XX:+Inline` +: Enables method inlining. This option is enabled by default to increase + performance. To disable method inlining, specify `-XX:-Inline`. + +`-XX:InlineSmallCode=`*size* +: Sets the maximum code size (in bytes) for already compiled methods + that may be inlined. This flag only applies to the C2 compiler. + Append the letter `k` or `K` to indicate kilobytes, + `m` or `M` to indicate megabytes, or `g` or `G` to indicate gigabytes. + The default value depends on the platform and on whether tiered compilation + is enabled. In the following example it is set to 1000 bytes: + + > `-XX:InlineSmallCode=1000` + +`-XX:+LogCompilation` +: Enables logging of compilation activity to a file named `hotspot.log` in + the current working directory. You can specify a different log file path + and name using the `-XX:LogFile` option. + + By default, this option is disabled and compilation activity isn't logged. + The `-XX:+LogCompilation` option has to be used together with the + `-XX:UnlockDiagnosticVMOptions` option that unlocks diagnostic JVM options. + + You can enable verbose diagnostic output with a message printed to the + console every time a method is compiled by using the + `-XX:+PrintCompilation` option. + + +`-XX:FreqInlineSize=`*size* +: Sets the maximum bytecode size (in bytes) of a hot method to be inlined. + This flag only applies to the C2 compiler. Append + the letter `k` or `K` to indicate kilobytes, `m` or `M` to indicate + megabytes, or `g` or `G` to indicate gigabytes. The default value depends + on the platform. In the following example it is set to 325 bytes: + + > `-XX:FreqInlineSize=325` + + +`-XX:MaxInlineSize=`*size* +: Sets the maximum bytecode size (in bytes) of a cold method to be inlined. + This flag only applies to the C2 compiler. + Append the letter `k` or `K` to indicate kilobytes, `m` or `M` to indicate + megabytes, or `g` or `G` to indicate gigabytes. By default, the maximum + bytecode size is set to 35 bytes: + + > `-XX:MaxInlineSize=35` + +`-XX:C1MaxInlineSize=`*size* +: Sets the maximum bytecode size (in bytes) of a cold method to be inlined. + This flag only applies to the C1 compiler. + Append the letter `k` or `K` to indicate kilobytes, `m` or `M` to indicate + megabytes, or `g` or `G` to indicate gigabytes. By default, the maximum + bytecode size is set to 35 bytes: + + > `-XX:MaxInlineSize=35` + +`-XX:MaxTrivialSize=`*size* +: Sets the maximum bytecode size (in bytes) of a trivial method to be + inlined. This flag only applies to the C2 compiler. + Append the letter `k` or `K` to indicate kilobytes, `m` or `M` to + indicate megabytes, or `g` or `G` to indicate gigabytes. By default, the + maximum bytecode size of a trivial method is set to 6 bytes: + + > `-XX:MaxTrivialSize=6` + +`-XX:C1MaxTrivialSize=`*size* +: Sets the maximum bytecode size (in bytes) of a trivial method to be + inlined. This flag only applies to the C1 compiler. + Append the letter `k` or `K` to indicate kilobytes, `m` or `M` to + indicate megabytes, or `g` or `G` to indicate gigabytes. By default, the + maximum bytecode size of a trivial method is set to 6 bytes: + + > `-XX:MaxTrivialSize=6` + +`-XX:MaxNodeLimit=`*nodes* +: Sets the maximum number of nodes to be used during single method + compilation. By default the value depends on the features enabled. + In the following example the maximum number of nodes is set to 100,000: + + > `-XX:MaxNodeLimit=100000` + +`-XX:NonNMethodCodeHeapSize=`*size* +: Sets the size in bytes of the code segment containing nonmethod code. + + A nonmethod code segment containing nonmethod code, such as compiler + buffers and the bytecode interpreter. This code type stays in the code + cache forever. This flag is used only if `-XX:SegmentedCodeCache` is + enabled. + +`-XX:NonProfiledCodeHeapSize=`*size* +: Sets the size in bytes of the code segment containing nonprofiled methods. + This flag is used only if `-XX:SegmentedCodeCache` is enabled. + +`-XX:+OptimizeStringConcat` +: Enables the optimization of `String` concatenation operations. This option + is enabled by default. To disable the optimization of `String` + concatenation operations, specify `-XX:-OptimizeStringConcat`. + +`-XX:+PrintAssembly` +: Enables printing of assembly code for bytecoded and native methods by using + the external `hsdis-.so` or `.dll` library. For 64-bit VM on Windows, + it's `hsdis-amd64.dll`. This lets you to see the generated code, which may + help you to diagnose performance issues. + + By default, this option is disabled and assembly code isn't printed. The + `-XX:+PrintAssembly` option has to be used together with the + `-XX:UnlockDiagnosticVMOptions` option that unlocks diagnostic JVM options. + +`-XX:ProfiledCodeHeapSize=`*size* +: Sets the size in bytes of the code segment containing profiled methods. + This flag is used only if `-XX:SegmentedCodeCache` is enabled. + +`-XX:+PrintCompilation` +: Enables verbose diagnostic output from the JVM by printing a message to the + console every time a method is compiled. This lets you to see which methods + actually get compiled. By default, this option is disabled and diagnostic + output isn't printed. + + You can also log compilation activity to a file by using the + `-XX:+LogCompilation` option. + +`-XX:+PrintInlining` +: Enables printing of inlining decisions. This let's you see which methods + are getting inlined. + + By default, this option is disabled and inlining information isn't printed. + The `-XX:+PrintInlining` option has to be used together with the + `-XX:+UnlockDiagnosticVMOptions` option that unlocks diagnostic JVM + options. + +`-XX:ReservedCodeCacheSize=`*size* +: Sets the maximum code cache size (in bytes) for JIT-compiled code. Append + the letter `k` or `K` to indicate kilobytes, `m` or `M` to indicate + megabytes, or `g` or `G` to indicate gigabytes. The default maximum code + cache size is 240 MB; if you disable tiered compilation with the option + `-XX:-TieredCompilation`, then the default size is 48 MB. This option has a + limit of 2 GB; otherwise, an error is generated. The maximum code cache + size shouldn't be less than the initial code cache size; see the option + `-XX:InitialCodeCacheSize`. + +`-XX:+SegmentedCodeCache` +: Enables segmentation of the code cache, without which the code cache + consists of one large segment. With `-XX:+SegmentedCodeCache`, separate + segments will be used for non-method, profiled method, and non-profiled + method code. The segments are not resized at runtime. The advantages are + better control of the memory footprint, reduced code fragmentation, and + better CPU iTLB (instruction translation lookaside buffer) and instruction + cache behavior due to improved locality. + + The feature is enabled by default if tiered compilation is enabled + (`-XX:+TieredCompilation` ) and the reserved code cache size + (`-XX:ReservedCodeCacheSize`) is at least 240 MB. + +`-XX:StartAggressiveSweepingAt=`*percent* +: Forces stack scanning of active methods to aggressively remove unused code + when only the given percentage of the code cache is free. The default value + is 10%. + +`-XX:-TieredCompilation` +: Disables the use of tiered compilation. By default, this option is enabled. + +`-XX:UseSSE=`*version* +: Enables the use of SSE instruction set of a specified version. + Is set by default to the highest supported version available (x86 only). + +`-XX:UseAVX=`*version* +: Enables the use of AVX instruction set of a specified version. + Is set by default to the highest supported version available (x86 only). + +`-XX:+UseAES` +: Enables hardware-based AES intrinsics for hardware that supports it. + This option is on by default on hardware that has the necessary instructions. + The `-XX:+UseAES` is used in conjunction with `UseAESIntrinsics`. Flags + that control intrinsics now require the option `-XX:+UnlockDiagnosticVMOptions`. + +`-XX:+UseAESIntrinsics` +: Enables AES intrinsics. Specifying `-XX:+UseAESIntrinsics` is equivalent to + also enabling `-XX:+UseAES`. To disable hardware-based AES intrinsics, + specify `-XX:-UseAES -XX:-UseAESIntrinsics`. For example, to enable hardware + AES, use the following flags: + + > `-XX:+UseAES -XX:+UseAESIntrinsics` + + Flags that control intrinsics now require the option + `-XX:+UnlockDiagnosticVMOptions`. + +`-XX:+UseAESCTRIntrinsics` +: Analogous to `-XX:+UseAESIntrinsics` enables AES/CTR intrinsics. + +`-XX:+UseGHASHIntrinsics` +: Controls the use of GHASH intrinsics. Enabled by default on platforms that + support the corresponding instructions. + Flags that control intrinsics now require the option `-XX:+UnlockDiagnosticVMOptions`. + +`-XX:+UseChaCha20Intrinsics` +: Enable ChaCha20 intrinsics. This option is on by default for supported + platforms. To disable ChaCha20 intrinsics, specify + `-XX:-UseChaCha20Intrinsics`. Flags that control intrinsics now require + the option `-XX:+UnlockDiagnosticVMOptions`. + +`-XX:+UsePoly1305Intrinsics` +: Enable Poly1305 intrinsics. This option is on by default for supported + platforms. To disable Poly1305 intrinsics, specify + `-XX:-UsePoly1305Intrinsics`. Flags that control intrinsics now require + the option `-XX:+UnlockDiagnosticVMOptions`. + +`-XX:+UseBASE64Intrinsics` +: Controls the use of accelerated BASE64 encoding routines for `java.util.Base64`. + Enabled by default on platforms that support it. + Flags that control intrinsics now require the option `-XX:+UnlockDiagnosticVMOptions`. + +`-XX:+UseAdler32Intrinsics` +: Controls the use of Adler32 checksum algorithm intrinsic for `java.util.zip.Adler32`. + Enabled by default on platforms that support it. + Flags that control intrinsics now require the option `-XX:+UnlockDiagnosticVMOptions`. + +`-XX:+UseCRC32Intrinsics` +: Controls the use of CRC32 intrinsics for `java.util.zip.CRC32`. + Enabled by default on platforms that support it. + Flags that control intrinsics now require the option `-XX:+UnlockDiagnosticVMOptions`. + +`-XX:+UseCRC32CIntrinsics` +: Controls the use of CRC32C intrinsics for `java.util.zip.CRC32C`. + Enabled by default on platforms that support it. + Flags that control intrinsics now require the option `-XX:+UnlockDiagnosticVMOptions`. + +`-XX:+UseSHA` +: Enables hardware-based intrinsics for SHA crypto hash functions for some + hardware. The `UseSHA` option is used in conjunction with the + `UseSHA1Intrinsics`, `UseSHA256Intrinsics`, and `UseSHA512Intrinsics` + options. + + The `UseSHA` and `UseSHA*Intrinsics` flags are enabled by default on + machines that support the corresponding instructions. + + This feature is applicable only when using the `sun.security.provider.Sun` + provider for SHA operations. Flags that control intrinsics now require the + option `-XX:+UnlockDiagnosticVMOptions`. + + To disable all hardware-based SHA intrinsics, specify the `-XX:-UseSHA`. To + disable only a particular SHA intrinsic, use the appropriate corresponding + option. For example: `-XX:-UseSHA256Intrinsics`. + +`-XX:+UseSHA1Intrinsics` +: Enables intrinsics for SHA-1 crypto hash function. Flags that control + intrinsics now require the option `-XX:+UnlockDiagnosticVMOptions`. + +`-XX:+UseSHA256Intrinsics` +: Enables intrinsics for SHA-224 and SHA-256 crypto hash functions. Flags + that control intrinsics now require the option + `-XX:+UnlockDiagnosticVMOptions`. + +`-XX:+UseSHA512Intrinsics` +: Enables intrinsics for SHA-384 and SHA-512 crypto hash functions. Flags + that control intrinsics now require the option + `-XX:+UnlockDiagnosticVMOptions`. + +`-XX:+UseMathExactIntrinsics` +: Enables intrinsification of various `java.lang.Math.*Exact()` functions. + Enabled by default. + Flags that control intrinsics now require the option `-XX:+UnlockDiagnosticVMOptions`. + +`-XX:+UseMultiplyToLenIntrinsic` +: Enables intrinsification of `BigInteger.multiplyToLen()`. + Enabled by default on platforms that support it. + Flags that control intrinsics now require the option `-XX:+UnlockDiagnosticVMOptions`. + +-XX:+UseSquareToLenIntrinsic +: Enables intrinsification of `BigInteger.squareToLen()`. + Enabled by default on platforms that support it. + Flags that control intrinsics now require the option `-XX:+UnlockDiagnosticVMOptions`. + +-XX:+UseMulAddIntrinsic +: Enables intrinsification of `BigInteger.mulAdd()`. + Enabled by default on platforms that support it. + Flags that control intrinsics now require the option `-XX:+UnlockDiagnosticVMOptions`. + +-XX:+UseMontgomeryMultiplyIntrinsic +: Enables intrinsification of `BigInteger.montgomeryMultiply()`. + Enabled by default on platforms that support it. + Flags that control intrinsics now require the option `-XX:+UnlockDiagnosticVMOptions`. + +-XX:+UseMontgomerySquareIntrinsic +: Enables intrinsification of `BigInteger.montgomerySquare()`. + Enabled by default on platforms that support it. + Flags that control intrinsics now require the option `-XX:+UnlockDiagnosticVMOptions`. + +`-XX:+UseCMoveUnconditionally` +: Generates CMove (scalar and vector) instructions regardless of + profitability analysis. + +`-XX:+UseCodeCacheFlushing` +: Enables flushing of the code cache before shutting down the compiler. This + option is enabled by default. To disable flushing of the code cache before + shutting down the compiler, specify `-XX:-UseCodeCacheFlushing`. + +`-XX:+UseCondCardMark` +: Enables checking if the card is already marked before updating the card + table. This option is disabled by default. It should be used only on + machines with multiple sockets, where it increases the performance of Java + applications that rely on concurrent operations. + +`-XX:+UseCountedLoopSafepoints` +: Keeps safepoints in counted loops. Its default value depends on whether the + selected garbage collector requires low latency safepoints. + +`-XX:LoopStripMiningIter=`*number_of_iterations* +: Controls the number of iterations in the inner strip mined loop. Strip mining + transforms counted loops into two level nested loops. Safepoints are kept + in the outer loop while the inner loop can execute at full speed. This option + controls the maximum number of iterations in the inner loop. The default value + is 1,000. + +`-XX:LoopStripMiningIterShortLoop=`*number_of_iterations* +: Controls loop strip mining optimization. Loops with the number of iterations + less than specified will not have safepoints in them. Default value is + 1/10th of `-XX:LoopStripMiningIter`. + +`-XX:+UseFMA` +: Enables hardware-based FMA intrinsics for hardware where FMA instructions + are available (such as, Intel and ARM64). FMA intrinsics are + generated for the `java.lang.Math.fma(`*a*`,` *b*`,` *c*`)` methods that + calculate the value of `(` *a* `*` *b* `+` *c* `)` expressions. + +`-XX:+UseSuperWord` +: Enables the transformation of scalar operations into superword operations. + Superword is a vectorization optimization. This option is enabled by + default. To disable the transformation of scalar operations into superword + operations, specify `-XX:-UseSuperWord`. + +## Advanced Serviceability Options for Java + +These `java` options provide the ability to gather system information and +perform extensive debugging. + +`-XX:+DisableAttachMechanism` +: Disables the mechanism that lets tools attach to the JVM. By default, this + option is disabled, meaning that the attach mechanism is enabled and you + can use diagnostics and troubleshooting tools such as `jcmd`, `jstack`, + `jmap`, and `jinfo`. + + > **Note:** The tools such as [jcmd](jcmd.html), [jinfo](jinfo.html), + [jmap](jmap.html), and [jstack](jstack.html) shipped with the JDK aren't + supported when using the tools from one JDK version to troubleshoot a + different JDK version. + +`-XX:+DTraceAllocProbes` +: **Linux and macOS:** Enable `dtrace` tool probes for object allocation. + +`-XX:+DTraceMethodProbes` +: **Linux and macOS:** Enable `dtrace` tool probes for method-entry + and method-exit. + +`-XX:+DTraceMonitorProbes` +: **Linux and macOS:** Enable `dtrace` tool probes for monitor events. + +`-XX:+HeapDumpOnOutOfMemoryError` +: Enables the dumping of the Java heap to a file in the current directory by + using the heap profiler (HPROF) when a `java.lang.OutOfMemoryError` + exception is thrown. You can explicitly set the heap dump file path and + name using the `-XX:HeapDumpPath` option. By default, this option is + disabled and the heap isn't dumped when an `OutOfMemoryError` exception is + thrown. + +`-XX:HeapDumpPath=`*path* +: Sets the path and file name for writing the heap dump provided by the heap + profiler (HPROF) when the `-XX:+HeapDumpOnOutOfMemoryError` option is set. + By default, the file is created in the current working directory, and it's + named `java_pid.hprof` where `` is the identifier of the process + that caused the error. The following example shows how to set the default + file explicitly (`%p` represents the current process identifier): + + > `-XX:HeapDumpPath=./java_pid%p.hprof` + + - **Non-Windows:** The following example shows how to + set the heap dump file to `/var/log/java/java_heapdump.hprof`: + + > `-XX:HeapDumpPath=/var/log/java/java_heapdump.hprof` + + - **Windows:** The following example shows how to set the heap dump file + to `C:/log/java/java_heapdump.log`: + + > `-XX:HeapDumpPath=C:/log/java/java_heapdump.log` + +`-XX:LogFile=`*path* +: Sets the path and file name to where log data is written. By default, the + file is created in the current working directory, and it's named + `hotspot.log`. + + - **Non-Windows:** The following example shows how to + set the log file to `/var/log/java/hotspot.log`: + + > `-XX:LogFile=/var/log/java/hotspot.log` + + - **Windows:** The following example shows how to set the log file to + `C:/log/java/hotspot.log`: + + > `-XX:LogFile=C:/log/java/hotspot.log` + +`-XX:+PrintClassHistogram` +: Enables printing of a class instance histogram after one of the following + events: + + - **Non-Windows:** `Control+\` (`SIGQUIT`) + + - **Windows:** `Control+C` (`SIGTERM`) + + By default, this option is disabled. + + Setting this option is equivalent to running the `jmap -histo` command, or + the `jcmd` *pid* `GC.class_histogram` command, where *pid* is the current + Java process identifier. + +`-XX:+PrintConcurrentLocks` +: Enables printing of `java.util.concurrent` locks after one of the following + events: + + - **Non-Windows:** `Control+\` (`SIGQUIT`) + + - **Windows:** `Control+C` (`SIGTERM`) + + By default, this option is disabled. + + Setting this option is equivalent to running the `jstack -l` command or the + `jcmd` *pid* `Thread.print -l` command, where *pid* is the current Java + process identifier. + +`-XX:+PrintFlagsRanges` +: Prints the range specified and allows automatic testing of the values. See + [Validate Java Virtual Machine Flag + Arguments]. + +`-XX:+PerfDataSaveToFile` +: If enabled, saves [jstat](jstat.html) binary data when the Java application + exits. This binary data is saved in a file named `hsperfdata_`*pid*, where + *pid* is the process identifier of the Java application that you ran. Use + the `jstat` command to display the performance data contained in this file + as follows: + + > `jstat -class file:///`*path*`/hsperfdata_`*pid* + + > `jstat -gc file:///`*path*`/hsperfdata_`*pid* + +`-XX:+UsePerfData` +: Enables the `perfdata` feature. This option is enabled by default to allow + JVM monitoring and performance testing. Disabling it suppresses the + creation of the `hsperfdata_userid` directories. To disable the `perfdata` + feature, specify `-XX:-UsePerfData`. + +## Advanced Garbage Collection Options for Java + +These `java` options control how garbage collection (GC) is performed by the +Java HotSpot VM. + +`-XX:+AggressiveHeap` +: Enables Java heap optimization. This sets various parameters to be + optimal for long-running jobs with intensive memory allocation, based on + the configuration of the computer (RAM and CPU). By default, the option + is disabled and the heap sizes are configured less aggressively. + +`-XX:+AlwaysPreTouch` +: Requests the VM to touch every page on the Java heap after requesting it from + the operating system and before handing memory out to the application. + By default, this option is disabled and all pages are committed as the + application uses the heap space. + +`-XX:ConcGCThreads=`*threads* +: Sets the number of threads used for concurrent GC. Sets *`threads`* to + approximately 1/4 of the number of parallel garbage collection threads. The + default value depends on the number of CPUs available to the JVM. + + For example, to set the number of threads for concurrent GC to 2, specify + the following option: + + > `-XX:ConcGCThreads=2` + +`-XX:+DisableExplicitGC` +: Enables the option that disables processing of calls to the `System.gc()` + method. This option is disabled by default, meaning that calls to + `System.gc()` are processed. If processing of calls to `System.gc()` is + disabled, then the JVM still performs GC when necessary. + +`-XX:+ExplicitGCInvokesConcurrent` +: Enables invoking of concurrent GC by using the `System.gc()` request. This + option is disabled by default and can be enabled only with the `-XX:+UseG1GC` option. + +`-XX:G1AdaptiveIHOPNumInitialSamples=`*number* +: When `-XX:UseAdaptiveIHOP` is enabled, this option sets the number of + completed marking cycles used to gather samples until G1 adaptively + determines the optimum value of `-XX:InitiatingHeapOccupancyPercent`. Before, + G1 uses the value of `-XX:InitiatingHeapOccupancyPercent` directly for + this purpose. The default value is 3. + +`-XX:G1HeapRegionSize=`*size* +: Sets the size of the regions into which the Java heap is subdivided when + using the garbage-first (G1) collector. The value is a power of 2 and can + range from 1 MB to 32 MB. The default region size is determined + ergonomically based on the heap size with a goal of approximately 2048 + regions. + + The following example sets the size of the subdivisions to 16 MB: + + > `-XX:G1HeapRegionSize=16m` + +`-XX:G1HeapWastePercent=`*percent* +: Sets the percentage of heap that you're willing to waste. The Java HotSpot + VM doesn't initiate the mixed garbage collection cycle when the reclaimable + percentage is less than the heap waste percentage. The default is 5 + percent. + +`-XX:G1MaxNewSizePercent=`*percent* +: Sets the percentage of the heap size to use as the maximum for the young + generation size. The default value is 60 percent of your Java heap. + + This is an experimental flag. This setting replaces the + `-XX:DefaultMaxNewGenPercent` setting. + +`-XX:G1MixedGCCountTarget=`*number* +: Sets the target number of mixed garbage collections after a marking cycle + to collect old regions with at most `G1MixedGCLIveThresholdPercent` live + data. The default is 8 mixed garbage collections. The goal for mixed + collections is to be within this target number. + +`-XX:G1MixedGCLiveThresholdPercent=`*percent* +: Sets the occupancy threshold for an old region to be included in a mixed + garbage collection cycle. The default occupancy is 85 percent. + + This is an experimental flag. This setting replaces the + `-XX:G1OldCSetRegionLiveThresholdPercent` setting. + +`-XX:G1NewSizePercent=`*percent* +: Sets the percentage of the heap to use as the minimum for the young + generation size. The default value is 5 percent of your Java heap. + + This is an experimental flag. This setting replaces the + `-XX:DefaultMinNewGenPercent` setting. + +`-XX:G1OldCSetRegionThresholdPercent=`*percent* +: Sets an upper limit on the number of old regions to be collected during a + mixed garbage collection cycle. The default is 10 percent of the Java heap. + +`-XX:G1ReservePercent=`*percent* +: Sets the percentage of the heap (0 to 50) that's reserved as a false + ceiling to reduce the possibility of promotion failure for the G1 + collector. When you increase or decrease the percentage, ensure that you + adjust the total Java heap by the same amount. By default, this option is + set to 10%. + + The following example sets the reserved heap to 20%: + + > `-XX:G1ReservePercent=20` + +`-XX:+G1UseAdaptiveIHOP` +: Controls adaptive calculation of the old generation occupancy to start + background work preparing for an old generation collection. If enabled, + G1 uses `-XX:InitiatingHeapOccupancyPercent` for the first few times as + specified by the value of `-XX:G1AdaptiveIHOPNumInitialSamples`, and after + that adaptively calculates a new optimum value for the initiating + occupancy automatically. + Otherwise, the old generation collection process always starts at the + old generation occupancy determined by + `-XX:InitiatingHeapOccupancyPercent`. + + The default is enabled. + +`-XX:InitialHeapSize=`*size* +: Sets the initial size (in bytes) of the memory allocation pool. This value + must be either 0, or a multiple of 1024 and greater than 1 MB. Append the + letter `k` or `K` to indicate kilobytes, `m` or `M` to indicate megabytes, + or `g` or `G` to indicate gigabytes. The default value is selected at run + time based on the system configuration. + + The following examples show how to set the size of allocated memory to 6 MB + using various units: + + ``` + -XX:InitialHeapSize=6291456 + -XX:InitialHeapSize=6144k + -XX:InitialHeapSize=6m + ``` + + If you set this option to 0, then the initial size is set as the sum of the + sizes allocated for the old generation and the young generation. The size + of the heap for the young generation can be set using the `-XX:NewSize` + option. Note that the `-Xms` option sets both the minimum and the initial + heap size of the heap. If `-Xms` appears after `-XX:InitialHeapSize` on the + command line, then the initial heap size gets set to the value specified + with `-Xms`. + +`-XX:InitialRAMPercentage=`*percent* +: Sets the initial amount of memory that the JVM will use for the Java heap + before applying ergonomics heuristics as a percentage of the maximum amount + determined as described in the `-XX:MaxRAM` option. The default value is + 1.5625 percent. + + The following example shows how to set the percentage of the initial + amount of memory used for the Java heap: + + > `-XX:InitialRAMPercentage=5` + +`-XX:InitialSurvivorRatio=`*ratio* +: Sets the initial survivor space ratio used by the throughput garbage + collector (which is enabled by the `-XX:+UseParallelGC` option). Adaptive + sizing is enabled by default with the throughput garbage collector by + using the `-XX:+UseParallelGC` option, and the survivor space is resized + according to the application behavior, starting with the initial value. If + adaptive sizing is disabled (using the `-XX:-UseAdaptiveSizePolicy` + option), then the `-XX:SurvivorRatio` option should be used to set the size + of the survivor space for the entire execution of the application. + + The following formula can be used to calculate the initial size of survivor + space (S) based on the size of the young generation (Y), and the initial + survivor space ratio (R): + + > `S=Y/(R+2)` + + The 2 in the equation denotes two survivor spaces. The larger the value + specified as the initial survivor space ratio, the smaller the initial + survivor space size. + + By default, the initial survivor space ratio is set to 8. If the default + value for the young generation space size is used (2 MB), then the initial + size of the survivor space is 0.2 MB. + + The following example shows how to set the initial survivor space ratio to + 4: + + > `-XX:InitialSurvivorRatio=4` + +`-XX:InitiatingHeapOccupancyPercent=`*percent* +: Sets the percentage of the old generation occupancy (0 to 100) at which to + start the first few concurrent marking cycles for the G1 garbage collector. + + By default, the initiating value is set to 45%. A value of 0 implies + nonstop concurrent GC cycles from the beginning until G1 adaptively sets this + value. + + See also the `-XX:G1UseAdaptiveIHOP` and `-XX:G1AdaptiveIHOPNumInitialSamples` + options. + + The following example shows how to set the initiating heap occupancy to 75%: + + > `-XX:InitiatingHeapOccupancyPercent=75` + +`-XX:MaxGCPauseMillis=`*time* +: Sets a target for the maximum GC pause time (in milliseconds). This is a + soft goal, and the JVM will make its best effort to achieve it. The + specified value doesn't adapt to your heap size. By default, for G1 the + maximum pause time target is 200 milliseconds. The other generational + collectors do not use a pause time goal by default. + + The following example shows how to set the maximum target pause time to 500 + ms: + + > `-XX:MaxGCPauseMillis=500` + +`-XX:MaxHeapSize=`*size* +: Sets the maximum size (in byes) of the memory allocation pool. This value + must be a multiple of 1024 and greater than 2 MB. Append the letter `k` or + `K` to indicate kilobytes, `m` or `M` to indicate megabytes, or `g` or `G` + to indicate gigabytes. The default value is selected at run time based on + the system configuration. For server deployments, the options + `-XX:InitialHeapSize` and `-XX:MaxHeapSize` are often set to the same + value. + + The following examples show how to set the maximum allowed size of + allocated memory to 80 MB using various units: + + ``` + -XX:MaxHeapSize=83886080 + -XX:MaxHeapSize=81920k + -XX:MaxHeapSize=80m + ``` + + The `-XX:MaxHeapSize` option is equivalent to `-Xmx`. + +`-XX:MaxHeapFreeRatio=`*percent* +: Sets the maximum allowed percentage of free heap space (0 to 100) after a + GC event. If free heap space expands above this value, then the heap is + shrunk. By default, this value is set to 70%. + + Minimize the Java heap size by lowering the values of the parameters + `MaxHeapFreeRatio` (default value is 70%) and `MinHeapFreeRatio` (default + value is 40%) with the command-line options `-XX:MaxHeapFreeRatio` and + `-XX:MinHeapFreeRatio`. Lowering `MaxHeapFreeRatio` to as low as 10% and + `MinHeapFreeRatio` to 5% has successfully reduced the heap size without too + much performance regression; however, results may vary greatly depending on + your application. Try different values for these parameters until they're + as low as possible yet still retain acceptable performance. + + > `-XX:MaxHeapFreeRatio=10 -XX:MinHeapFreeRatio=5` + + Customers trying to keep the heap small should also add the option + `-XX:-ShrinkHeapInSteps`. See [Performance Tuning Examples] for a + description of using this option to keep the Java heap small by reducing + the dynamic footprint for embedded applications. + +`-XX:MaxMetaspaceSize=`*size* +: Sets the maximum amount of native memory that can be allocated for class + metadata. By default, the size isn't limited. The amount of metadata for an + application depends on the application itself, other running applications, + and the amount of memory available on the system. + + The following example shows how to set the maximum class metadata size to + 256 MB: + + > `-XX:MaxMetaspaceSize=256m` + +`-XX:MaxNewSize=`*size* +: Sets the maximum size (in bytes) of the heap for the young generation + (nursery). The default value is set ergonomically. + +`-XX:MaxRAM=`*size* +: Sets the maximum amount of memory that the JVM may use for the Java heap + before applying ergonomics heuristics. The default value is the maximum + amount of available memory to the JVM process or 128 GB, whichever is lower. + + The maximum amount of available memory to the JVM process is the minimum + of the machine's physical memory and any constraints set by the environment + (e.g. container). + + Specifying this option disables automatic use of compressed oops if + the combined result of this and other options influencing the maximum amount + of memory is larger than the range of memory addressable by compressed oops. + See `-XX:UseCompressedOops` for further information about compressed oops. + + The following example shows how to set the maximum amount of available + memory for sizing the Java heap to 2 GB: + + > `-XX:MaxRAM=2G` + +`-XX:MaxRAMPercentage=`*percent* +: Sets the maximum amount of memory that the JVM may use for the Java heap + before applying ergonomics heuristics as a percentage of the maximum amount + determined as described in the `-XX:MaxRAM` option. The default value is 25 + percent. + + Specifying this option disables automatic use of compressed oops if + the combined result of this and other options influencing the maximum amount + of memory is larger than the range of memory addressable by compressed oops. + See `-XX:UseCompressedOops` for further information about compressed oops. + + The following example shows how to set the percentage of the maximum amount + of memory used for the Java heap: + + > `-XX:MaxRAMPercentage=75` + +`-XX:MinRAMPercentage=`*percent* +: Sets the maximum amount of memory that the JVM may use for the Java heap + before applying ergonomics heuristics as a percentage of the maximum amount + determined as described in the `-XX:MaxRAM` option for small heaps. A small + heap is a heap of approximately 125 MB. The default value is 50 percent. + + The following example shows how to set the percentage of the maximum amount + of memory used for the Java heap for small heaps: + + > `-XX:MinRAMPercentage=75` + +`-XX:MaxTenuringThreshold=`*threshold* +: Sets the maximum tenuring threshold for use in adaptive GC sizing. The + largest value is 15. The default value is 15 for the parallel (throughput) + collector. + + The following example shows how to set the maximum tenuring threshold to + 10: + + > `-XX:MaxTenuringThreshold=10` + +`-XX:MetaspaceSize=`*size* +: Sets the size of the allocated class metadata space that triggers a garbage + collection the first time it's exceeded. This threshold for a garbage + collection is increased or decreased depending on the amount of metadata + used. The default size depends on the platform. + +`-XX:MinHeapFreeRatio=`*percent* +: Sets the minimum allowed percentage of free heap space (0 to 100) after a + GC event. If free heap space falls below this value, then the heap is + expanded. By default, this value is set to 40%. + + Minimize Java heap size by lowering the values of the parameters + `MaxHeapFreeRatio` (default value is 70%) and `MinHeapFreeRatio` (default + value is 40%) with the command-line options `-XX:MaxHeapFreeRatio` and + `-XX:MinHeapFreeRatio`. Lowering `MaxHeapFreeRatio` to as low as 10% and + `MinHeapFreeRatio` to 5% has successfully reduced the heap size without too + much performance regression; however, results may vary greatly depending on + your application. Try different values for these parameters until they're + as low as possible, yet still retain acceptable performance. + + > `-XX:MaxHeapFreeRatio=10 -XX:MinHeapFreeRatio=5` + + Customers trying to keep the heap small should also add the option + `-XX:-ShrinkHeapInSteps`. See [Performance Tuning Examples] for a + description of using this option to keep the Java heap small by reducing + the dynamic footprint for embedded applications. + +`-XX:MinHeapSize=`*size* +: Sets the minimum size (in bytes) of the memory allocation pool. This value + must be either 0, or a multiple of 1024 and greater than 1 MB. Append the + letter `k` or `K` to indicate kilobytes, `m` or `M` to indicate megabytes, + or `g` or `G` to indicate gigabytes. The default value is selected at run + time based on the system configuration. + + The following examples show how to set the minimum size of allocated memory + to 6 MB using various units: + + ``` + -XX:MinHeapSize=6291456 + -XX:MinHeapSize=6144k + -XX:MinHeapSize=6m + ``` + + If you set this option to 0, then the minimum size is set to the same value + as the initial size. + +`-XX:NewRatio=`*ratio* +: Sets the ratio between young and old generation sizes. By default, this + option is set to 2. The following example shows how to set the young-to-old + ratio to 1: + + > `-XX:NewRatio=1` + +`-XX:NewSize=`*size* +: Sets the initial size (in bytes) of the heap for the young generation + (nursery). Append the letter `k` or `K` to indicate kilobytes, `m` or `M` + to indicate megabytes, or `g` or `G` to indicate gigabytes. + + The young generation region of the heap is used for new objects. GC is + performed in this region more often than in other regions. If the size for + the young generation is too low, then a large number of minor GCs are + performed. If the size is too high, then only full GCs are performed, which + can take a long time to complete. It is recommended that you keep the size + for the young generation greater than 25% and less than 50% of the overall + heap size. + + The following examples show how to set the initial size of the young + generation to 256 MB using various units: + + ``` + -XX:NewSize=256m + -XX:NewSize=262144k + -XX:NewSize=268435456 + ``` + + The `-XX:NewSize` option is equivalent to `-Xmn`. + +`-XX:ParallelGCThreads=`*threads* +: Sets the number of the stop-the-world (STW) worker threads. The default value + depends on the number of CPUs available to the JVM and the garbage collector + selected. + + For example, to set the number of threads for G1 GC to 2, specify the + following option: + + > `-XX:ParallelGCThreads=2` + +`-XX:+ParallelRefProcEnabled` +: Enables parallel reference processing. By default, this option is disabled. + +`-XX:+PrintAdaptiveSizePolicy` +: Enables printing of information about adaptive-generation sizing. By + default, this option is disabled. + +`-XX:SoftRefLRUPolicyMSPerMB=`*time* +: Sets the amount of time (in milliseconds) a softly reachable object is + kept active on the heap after the last time it was referenced. The default + value is one second of lifetime per free megabyte in the heap. The + `-XX:SoftRefLRUPolicyMSPerMB` option accepts integer values representing + milliseconds per one megabyte of the current heap size (for Java HotSpot + Client VM) or the maximum possible heap size (for Java HotSpot Server VM). + This difference means that the Client VM tends to flush soft references + rather than grow the heap, whereas the Server VM tends to grow the heap + rather than flush soft references. In the latter case, the value of the + `-Xmx` option has a significant effect on how quickly soft references are + garbage collected. + + The following example shows how to set the value to 2.5 seconds: + + `-XX:SoftRefLRUPolicyMSPerMB=2500` + +`-XX:-ShrinkHeapInSteps` +: Incrementally reduces the Java heap to the target size, specified by the + option `-XX:MaxHeapFreeRatio`. This option is enabled by default. If + disabled, then it immediately reduces the Java heap to the target size + instead of requiring multiple garbage collection cycles. Disable this + option if you want to minimize the Java heap size. You will likely + encounter performance degradation when this option is disabled. + + See [Performance Tuning Examples] for a description of using the + `MaxHeapFreeRatio` option to keep the Java heap small by reducing the + dynamic footprint for embedded applications. + +`-XX:StringDeduplicationAgeThreshold=`*threshold* +: Identifies `String` objects reaching the specified age that are considered + candidates for deduplication. An object's age is a measure of how many + times it has survived garbage collection. This is sometimes referred to as + tenuring. + + > **Note:** `String` objects that are promoted to an old heap region before this age + has been reached are always considered candidates for deduplication. The + default value for this option is `3`. See the `-XX:+UseStringDeduplication` + option. + +`-XX:SurvivorRatio=`*ratio* +: Sets the ratio between eden space size and survivor space size. By default, + this option is set to 8. The following example shows how to set the + eden/survivor space ratio to 4: + + > `-XX:SurvivorRatio=4` + +`-XX:TargetSurvivorRatio=`*percent* +: Sets the desired percentage of survivor space (0 to 100) used after young + garbage collection. By default, this option is set to 50%. + + The following example shows how to set the target survivor space ratio to + 30%: + + > `-XX:TargetSurvivorRatio=30` + +`-XX:TLABSize=`*size* +: Sets the initial size (in bytes) of a thread-local allocation buffer + (TLAB). Append the letter `k` or `K` to indicate kilobytes, `m` or `M` to + indicate megabytes, or `g` or `G` to indicate gigabytes. If this option is + set to 0, then the JVM selects the initial size automatically. + + The following example shows how to set the initial TLAB size to 512 KB: + + > `-XX:TLABSize=512k` + +`-XX:+UseAdaptiveSizePolicy` +: Enables the use of adaptive generation sizing. This option is enabled by + default. To disable adaptive generation sizing, specify + `-XX:-UseAdaptiveSizePolicy` and set the size of the memory allocation pool + explicitly. See the `-XX:SurvivorRatio` option. + +`-XX:+UseG1GC` +: Enables the use of the garbage-first (G1) garbage collector. It's a + server-style garbage collector, targeted for multiprocessor machines with a + large amount of RAM. This option meets GC pause time goals with high + probability, while maintaining good throughput. The G1 collector is + recommended for applications requiring large heaps (sizes of around 6 GB or + larger) with limited GC latency requirements (a stable and predictable + pause time below 0.5 seconds). By default, this option is enabled and G1 is + used as the default garbage collector. + +`-XX:+UseGCOverheadLimit` +: Enables the use of a policy that limits the proportion of time spent by the + JVM on GC before an `OutOfMemoryError` exception is thrown. This option is + enabled, by default, and the parallel GC will throw an `OutOfMemoryError` + if more than 98% of the total time is spent on garbage collection and less + than 2% of the heap is recovered. When the heap is small, this feature can + be used to prevent applications from running for long periods of time with + little or no progress. To disable this option, specify the option + `-XX:-UseGCOverheadLimit`. + +`-XX:+UseNUMA` +: Enables performance optimization of an application on a machine with + nonuniform memory architecture (NUMA) by increasing the application's use + of lower latency memory. By default, this option is disabled and no + optimization for NUMA is made. The option is available only when the + parallel garbage collector is used (`-XX:+UseParallelGC`). + +`-XX:+UseParallelGC` +: Enables the use of the parallel scavenge garbage collector (also known as + the throughput collector) to improve the performance of your application by + leveraging multiple processors. + + By default, this option is disabled and the default collector is used. + +`-XX:+UseSerialGC` +: Enables the use of the serial garbage collector. This is generally the best + choice for small and simple applications that don't require any special + functionality from garbage collection. By default, this option is disabled + and the default collector is used. + +`-XX:+UseStringDeduplication` +: Enables string deduplication. By default, this option is disabled. To use + this option, you must enable the garbage-first (G1) garbage collector. + + String deduplication reduces the memory footprint of `String` objects on + the Java heap by taking advantage of the fact that many `String` objects + are identical. Instead of each `String` object pointing to its own + character array, identical `String` objects can point to and share the same + character array. + +`-XX:+UseTLAB` +: Enables the use of thread-local allocation blocks (TLABs) in the young + generation space. This option is enabled by default. To disable the use of + TLABs, specify the option `-XX:-UseTLAB`. + +`-XX:+UseZGC` +: Enables the use of the Z garbage collector (ZGC). This is a low latency + garbage collector, providing max pause times of a few milliseconds, at + some throughput cost. Pause times are independent of what heap size is + used. Supports heap sizes from 8MB to 16TB. + +`-XX:ZAllocationSpikeTolerance=`*factor* +: Sets the allocation spike tolerance for ZGC. By default, this option is + set to 2.0. This factor describes the level of allocation spikes to expect. + For example, using a factor of 3.0 means the current allocation rate can + be expected to triple at any time. + +`-XX:ZCollectionInterval=`*seconds* +: Sets the maximum interval (in seconds) between two GC cycles when using + ZGC. By default, this option is set to 0 (disabled). + +`-XX:ZFragmentationLimit=`*percent* +: Sets the maximum acceptable heap fragmentation (in percent) for ZGC. + By default, this option is set to 25. Using a lower value will cause the + heap to be compacted more aggressively, to reclaim more memory at the cost + of using more CPU time. + +`-XX:+ZProactive` +: Enables proactive GC cycles when using ZGC. By default, this option is + enabled. ZGC will start a proactive GC cycle if doing so is expected to + have minimal impact on the running application. This is useful if the + application is mostly idle or allocates very few objects, but you still + want to keep the heap size down and allow reference processing to happen + even when there are a lot of free space on the heap. + +`-XX:+ZUncommit` +: Enables uncommitting of unused heap memory when using ZGC. By default, + this option is enabled. Uncommitting unused heap memory will lower the + memory footprint of the JVM, and make that memory available for other + processes to use. + +`-XX:ZUncommitDelay=`*seconds* +: Sets the amount of time (in seconds) that heap memory must have been + unused before being uncommitted. By default, this option is set to 300 + (5 minutes). Committing and uncommitting memory are relatively + expensive operations. Using a lower value will cause heap memory to be + uncommitted earlier, at the risk of soon having to commit it again. + +## Deprecated Java Options + +These `java` options are deprecated and might be removed in a future JDK +release. They're still accepted and acted upon, but a warning is issued when +they're used. + +`-Xloggc:`*filename* +: Sets the file to which verbose GC events information should be redirected + for logging. The `-Xloggc` option overrides `-verbose:gc` if both are given + with the same java command. `-Xloggc:`*filename* is replaced by + `-Xlog:gc:`*filename*. See Enable Logging with the JVM Unified Logging + Framework. + + Example: + + `-Xlog:gc:garbage-collection.log` + +`-XX:+FlightRecorder` +: Enables the use of Java Flight Recorder (JFR) during the runtime of the + application. Since JDK 8u40 this option has not been required to use JFR. + +## Obsolete Java Options + +These `java` options are still accepted but ignored, and a warning is issued +when they're used. + +`--illegal-access=`*parameter* +: Controlled _relaxed strong encapsulation_, as defined in [JEP + 261](https://openjdk.org/jeps/261#Relaxed-strong-encapsulation). + This option was deprecated in JDK 16 by [JEP + 396](https://openjdk.org/jeps/396) and made obsolete in JDK 17 + by [JEP 403](https://openjdk.org/jeps/403). + +`-XX:RTMAbortRatio=`*abort\_ratio* +: Specifies the RTM abort ratio is specified as a percentage (%) of all + executed RTM transactions. If a number of aborted transactions becomes + greater than this ratio, then the compiled code is deoptimized. This ratio + is used when the `-XX:+UseRTMDeopt` option is enabled. The default value of + this option is 50. This means that the compiled code is deoptimized if 50% + of all transactions are aborted. + +`-XX:RTMRetryCount=`*number\_of\_retries* +: Specifies the number of times that the RTM locking code is retried, when it + is aborted or busy, before falling back to the normal locking mechanism. + The default value for this option is 5. The `-XX:UseRTMLocking` option must + be enabled. + +`-XX:+UseRTMDeopt` +: Autotunes RTM locking depending on the abort ratio. This ratio is specified + by the `-XX:RTMAbortRatio` option. If the number of aborted transactions + exceeds the abort ratio, then the method containing the lock is deoptimized + and recompiled with all locks as normal locks. This option is disabled by + default. The `-XX:+UseRTMLocking` option must be enabled. + +`-XX:+UseRTMLocking` +: Generates Restricted Transactional Memory (RTM) locking code for all + inflated locks, with the normal locking mechanism as the fallback handler. + This option is disabled by default. Options related to RTM are available + only on x86 CPUs that support Transactional Synchronization Extensions (TSX). + + RTM is part of Intel's TSX, which is an x86 instruction set extension and + facilitates the creation of multithreaded applications. RTM introduces the + new instructions `XBEGIN`, `XABORT`, `XEND`, and `XTEST`. The `XBEGIN` and + `XEND` instructions enclose a set of instructions to run as a transaction. + If no conflict is found when running the transaction, then the memory and + register modifications are committed together at the `XEND` instruction. + The `XABORT` instruction can be used to explicitly abort a transaction and + the `XTEST` instruction checks if a set of instructions is being run in a + transaction. + + A lock on a transaction is inflated when another thread tries to access the + same transaction, thereby blocking the thread that didn't originally + request access to the transaction. RTM requires that a fallback set of + operations be specified in case a transaction aborts or fails. An RTM lock + is a lock that has been delegated to the TSX's system. + + RTM improves performance for highly contended locks with low conflict in a + critical region (which is code that must not be accessed by more than one + thread concurrently). RTM also improves the performance of coarse-grain + locking, which typically doesn't perform well in multithreaded + applications. (Coarse-grain locking is the strategy of holding locks for + long periods to minimize the overhead of taking and releasing locks, while + fine-grained locking is the strategy of trying to achieve maximum + parallelism by locking only when necessary and unlocking as soon as + possible.) Also, for lightly contended locks that are used by different + threads, RTM can reduce false cache line sharing, also known as cache line + ping-pong. This occurs when multiple threads from different processors are + accessing different resources, but the resources share the same cache line. + As a result, the processors repeatedly invalidate the cache lines of other + processors, which forces them to read from main memory instead of their + cache. + +## Removed Java Options + +These `java` options have been removed in JDK @@VERSION_SPECIFICATION@@ and using them results in an error of: + +> `Unrecognized VM option` *option-name* + +`-XX:InitialRAMFraction=`*ratio* +: Sets the initial amount of memory that the JVM may use for the Java heap + before applying ergonomics heuristics as a ratio of the maximum amount + determined as described in the `-XX:MaxRAM` option. The default value is + 64. + + Use the option `-XX:InitialRAMPercentage` instead. + +`-XX:MaxRAMFraction=`*ratio* +: Sets the maximum amount of memory that the JVM may use for the Java heap + before applying ergonomics heuristics as a fraction of the maximum amount + determined as described in the `-XX:MaxRAM` option. The default value is 4. + + Specifying this option disables automatic use of compressed oops if + the combined result of this and other options influencing the maximum amount + of memory is larger than the range of memory addressable by compressed oops. + See `-XX:UseCompressedOops` for further information about compressed oops. + + Use the option `-XX:MaxRAMPercentage` instead. + +`-XX:MinRAMFraction=`*ratio* +: Sets the maximum amount of memory that the JVM may use for the Java heap + before applying ergonomics heuristics as a fraction of the maximum amount + determined as described in the `-XX:MaxRAM` option for small heaps. A small + heap is a heap of approximately 125 MB. The default value is 2. + + Use the option `-XX:MinRAMPercentage` instead. + +`-XX:+ScavengeBeforeFullGC` +: Enables GC of the young generation before each full GC. This option is + enabled by default. It is recommended that you *don't* disable it, because + scavenging the young generation before a full GC can reduce the number of + objects reachable from the old generation space into the young generation + space. To disable GC of the young generation before each full GC, specify + the option `-XX:-ScavengeBeforeFullGC`. + +`-Xfuture` +: Enables strict class-file format checks that enforce close conformance to + the class-file format specification. Developers should use this flag when + developing new code. Stricter checks may become the default in future + releases. + + Use the option `-Xverify:all` instead. + +For the lists and descriptions of options removed in previous releases see the *Removed Java Options* section in: + +- [The `java` Command, Release 23](https://docs.oracle.com/en/java/javase/23/docs/specs/man/java.html) + +- [The `java` Command, Release 22](https://docs.oracle.com/en/java/javase/22/docs/specs/man/java.html) + +- [The `java` Command, Release 21](https://docs.oracle.com/en/java/javase/21/docs/specs/man/java.html) + +- [The `java` Command, Release 20](https://docs.oracle.com/en/java/javase/20/docs/specs/man/java.html) + +- [The `java` Command, Release 19](https://docs.oracle.com/en/java/javase/19/docs/specs/man/java.html) + +- [The `java` Command, Release 18](https://docs.oracle.com/en/java/javase/18/docs/specs/man/java.html) + +- [The `java` Command, Release 17](https://docs.oracle.com/en/java/javase/17/docs/specs/man/java.html) + +- [The `java` Command, Release 16](https://docs.oracle.com/en/java/javase/16/docs/specs/man/java.html) + +- [The `java` Command, Release 15](https://docs.oracle.com/en/java/javase/15/docs/specs/man/java.html) + +- [The `java` Command, Release 14](https://docs.oracle.com/en/java/javase/14/docs/specs/man/java.html) + +- [The `java` Command, Release 13](https://docs.oracle.com/en/java/javase/13/docs/specs/man/java.html) + +- [Java Platform, Standard Edition Tools Reference, Release 12]( + https://docs.oracle.com/en/java/javase/12/tools/java.html#GUID-3B1CE181-CD30-4178-9602-230B800D4FAE) + +- [Java Platform, Standard Edition Tools Reference, Release 11]( + https://docs.oracle.com/en/java/javase/11/tools/java.html#GUID-741FC470-AA3E-494A-8D2B-1B1FE4A990D1) + +- [Java Platform, Standard Edition Tools Reference, Release 10]( + https://docs.oracle.com/javase/10/tools/java.htm#JSWOR624) + +- [Java Platform, Standard Edition Tools Reference, Release 9]( + https://docs.oracle.com/javase/9/tools/java.htm#JSWOR624) + +- [Java Platform, Standard Edition Tools Reference, Release 8 for Oracle JDK + on Windows]( + https://docs.oracle.com/javase/8/docs/technotes/tools/windows/java.html#BGBCIEFC) + +- [Java Platform, Standard Edition Tools Reference, Release 8 for Oracle JDK + on Solaris, Linux, and macOS]( + https://docs.oracle.com/javase/8/docs/technotes/tools/unix/java.html#BGBCIEFC) + +## java Command-Line Argument Files + +You can shorten or simplify the `java` command by using `@` argument files to +specify one or more text files that contain arguments, such as options and +class names, which are passed to the `java` command. This let's you to create +`java` commands of any length on any operating system. + +In the command line, use the at sign (`@`) prefix to identify an argument file +that contains `java` options and class names. When the `java` command +encounters a file beginning with the at sign (`@`), it expands the contents of +that file into an argument list just as they would be specified on the command +line. + +The `java` launcher expands the argument file contents until it encounters the +`--disable-@files` option. You can use the `--disable-@files` option anywhere +on the command line, including in an argument file, to stop `@` argument files +expansion. + +The following items describe the syntax of `java` argument files: + +- The argument file must contain only ASCII characters or characters in + system default encoding that's ASCII friendly, such as UTF-8. + +- The argument file size must not exceed MAXINT (2,147,483,647) bytes. + +- The launcher doesn't expand wildcards that are present within an argument + file. + +- Use white space or new line characters to separate arguments included in + the file. + +- White space includes a white space character, `\t`, `\n`, `\r`, and `\f`. + + For example, it is possible to have a path with a space, such as + `c:\Program Files` that can be specified as either `"c:\\Program Files"` or, + to avoid an escape, `c:\Program" "Files`. + +- Any option that contains spaces, such as a path component, must be within + quotation marks using quotation ('\"') characters in its entirety. + +- A string within quotation marks may contain the characters `\n`, `\r`, + `\t`, and `\f`. They are converted to their respective ASCII codes. + +- If a file name contains embedded spaces, then put the whole file name in + double quotation marks. + +- File names in an argument file are relative to the current directory, not + to the location of the argument file. + +- Use the number sign `#` in the argument file to identify comments. All + characters following the `#` are ignored until the end of line. + +- Additional at sign `@` prefixes to `@` prefixed options act as an escape, + (the first `@` is removed and the rest of the arguments are presented to + the launcher literally). + +- Lines may be continued using the continuation character (`\`) at the + end-of-line. The two lines are concatenated with the leading white spaces + trimmed. To prevent trimming the leading white spaces, a continuation + character (`\`) may be placed at the first column. + +- Because backslash (\\) is an escape character, a backslash character must + be escaped with another backslash character. + +- Partial quote is allowed and is closed by an end-of-file. + +- An open quote stops at end-of-line unless `\` is the last character, which + then joins the next line by removing all leading white space characters. + +- Wildcards (\*) aren't allowed in these lists (such as specifying `*.java`). + +- Use of the at sign (`@`) to recursively interpret files isn't supported. + +### Example of Open or Partial Quotes in an Argument File + +In the argument file, + +``` +-cp "lib/ +cool/ +app/ +jars +``` + +this is interpreted as: + +> `-cp lib/cool/app/jars` + +### Example of a Backslash Character Escaped with Another Backslash Character in an Argument File + +To output the following: + +> `-cp c:\Program Files (x86)\Java\jre\lib\ext;c:\Program + Files\Java\jre9\lib\ext` + +The backslash character must be specified in the argument file as: + +> `-cp "c:\\Program Files (x86)\\Java\\jre\\lib\\ext;c:\\Program + Files\\Java\\jre9\\lib\\ext"` + +### Example of an EOL Escape Used to Force Concatenation of Lines in an Argument File + +In the argument file, + +``` +-cp "/lib/cool app/jars:\ + /lib/another app/jars" +``` + +This is interpreted as: + +> `-cp /lib/cool app/jars:/lib/another app/jars` + +### Example of Line Continuation with Leading Spaces in an Argument File + +In the argument file, + +``` +-cp "/lib/cool\ +\app/jars" +``` + +This is interpreted as: + +`-cp /lib/cool app/jars` + +### Examples of Using Single Argument File + +You can use a single argument file, such as `myargumentfile` in the following +example, to hold all required `java` arguments: + +> `java @myargumentfile` + +### Examples of Using Argument Files with Paths + +You can include relative paths in argument files; however, they're relative to +the current working directory and not to the paths of the argument files +themselves. In the following example, `path1/options` and `path2/options` +represent argument files with different paths. Any relative paths that they +contain are relative to the current working directory and not to the argument +files: + +> `java @path1/options @path2/classes` + +## Code Heap State Analytics + +### Overview + +There are occasions when having insight into the current state of the JVM code +heap would be helpful to answer questions such as: + +- Why was the JIT turned off and then on again and again? + +- Where has all the code heap space gone? + +- Why is the method sweeper not working effectively? + +To provide this insight, a code heap state analytics feature has been +implemented that enables on-the-fly analysis of the code heap. The analytics +process is divided into two parts. The first part examines the entire code heap +and aggregates all information that is believed to be useful or important. The +second part consists of several independent steps that print the collected +information with an emphasis on different aspects of the data. Data collection +and printing are done on an "on request" basis. + +### Syntax + +Requests for real-time, on-the-fly analysis can be issued with the following +command: + +> `jcmd` *pid* `Compiler.CodeHeap_Analytics` \[*function*\] \[*granularity*\] + +If you are only interested in how the code heap looks like after running a +sample workload, you can use the command line option: + +> `-Xlog:codecache=Trace` + +To see the code heap state when a "CodeCache full" condition exists, start the +VM with the command line option: + +> `-Xlog:codecache=Debug` + +See [CodeHeap State Analytics (OpenJDK)]( +https://bugs.openjdk.org/secure/attachment/75649/JVM_CodeHeap_StateAnalytics_V2.pdf) +for a detailed description of the code heap state analytics feature, the +supported functions, and the granularity options. + +## Enable Logging with the JVM Unified Logging Framework + +You use the `-Xlog` option to configure or enable logging with the Java Virtual +Machine (JVM) unified logging framework. + +### Synopsis + +> `-Xlog`\[`:`\[*what*\]\[`:`\[*output*\]\[`:`\[*decorators*\]\[`:`*output-options*\[`,`...\]\]\]\]\] +> +> `-Xlog:`*directive* + +*what* +: Specifies a combination of tags and levels of the form + *tag1*\[`+`*tag2*...\]\[`*`\]\[`=`*level*\]\[`,`...\]. Unless the wildcard + (`*`) is specified, only log messages tagged with exactly the tags + specified are matched. See [-Xlog Tags and Levels]. + +*output* +: Sets the type of output. Omitting the *output* type defaults to `stdout`. + See [-Xlog Output]. + +*decorators* +: Configures the output to use a custom set of decorators. Omitting + *decorators* defaults to `uptime`, `level`, and `tags`. See + [Decorations]. + +*output-options* +: Sets the `-Xlog` logging output options. + +*directive* +: A global option or subcommand: help, disable, async + +### Description + +The Java Virtual Machine (JVM) unified logging framework provides a common +logging system for all components of the JVM. GC logging for the JVM has been +changed to use the new logging framework. The mapping of old GC flags to the +corresponding new Xlog configuration is described in [Convert GC Logging Flags +to Xlog]. In addition, runtime logging has also been changed to use the JVM +unified logging framework. The mapping of legacy runtime logging flags to the +corresponding new Xlog configuration is described in [Convert Runtime Logging +Flags to Xlog]. + +The following provides quick reference to the `-Xlog` command and syntax for +options: + +`-Xlog` +: Enables JVM logging on an `info` level. + +`-Xlog:help` +: Prints `-Xlog` usage syntax and available tags, levels, and decorators + along with example command lines with explanations. + +`-Xlog:disable` +: Turns off all logging and clears all configuration of the logging framework + including the default configuration for warnings and errors. + +`-Xlog`\[`:`*option*\] +: Applies multiple arguments in the order that they appear on the command + line. Multiple `-Xlog` arguments for the same output override each other in + their given order. + + The *option* is set as: + + > \[*tag-selection*\]\[`:`\[*output*\]\[`:`\[*decorators*\]\[`:`*output-options*\]\]\] + + Omitting the *tag-selection* defaults to a tag-set of `all` and a level of + `info`. + + > *tag*\[`+`...\] `all` + + The `all` tag is a meta tag consisting of all tag-sets available. The + asterisk `*` in a tag set definition denotes a wildcard tag match. Matching + with a wildcard selects all tag sets that contain *at least* the specified + tags. Without the wildcard, only exact matches of the specified tag sets + are selected. + + *output-options* is + + > `filecount=`*file-count* `filesize=`*file size with optional K, M or G + suffix* `foldmultilines=`** + + When `foldmultilines` is true, a log event that consists of + multiple lines will be folded into a single line by replacing newline characters + with the sequence `'\'` and `'n'` in the output. + Existing single backslash characters will also be replaced with a sequence of + two backslashes so that the conversion can be reversed. + This option is safe to use with UTF-8 character encodings, but other encodings may not work. + For example, it may incorrectly convert multi-byte sequences in Shift JIS and BIG5. + +### Default Configuration + +When the `-Xlog` option and nothing else is specified on the command line, the +default configuration is used. The default configuration logs all messages with +a level that matches either warning or error regardless of what tags the +message is associated with. The default configuration is equivalent to entering +the following on the command line: + +> `-Xlog:all=warning:stdout:uptime,level,tags` + +### Controlling Logging at Runtime + +Logging can also be controlled at run time through Diagnostic Commands (with +the [jcmd](jcmd.html) utility). Everything that can be specified on the command line can +also be specified dynamically with the `VM.log` command. As the diagnostic +commands are automatically exposed as MBeans, you can use JMX to change logging +configuration at run time. + +### -Xlog Tags and Levels + +Each log message has a level and a tag set associated with it. The level of +the message corresponds to its details, and the tag set corresponds to what +the message contains or which JVM component it involves (such as, `gc`, +`jit`, or `os`). Mapping GC flags to the Xlog configuration is described +in [Convert GC Logging Flags to Xlog]. Mapping legacy runtime logging flags to +the corresponding Xlog configuration is described in [Convert Runtime Logging +Flags to Xlog]. + +**Available log levels:** + +- `off` +- `trace` +- `debug` +- `info` +- `warning` +- `error` + +**Available log tags:** + +There are literally dozens of log tags, which in the right combinations, will enable +a range of logging output. The full set of available log tags can be seen using `-Xlog:help`. +Specifying `all` instead of a tag combination matches all tag combinations. + +### -Xlog Output + +The `-Xlog` option supports the following types of outputs: + +- `stdout` --- Sends output to stdout +- `stderr` --- Sends output to stderr +- `file=`*filename* --- Sends output to text file(s). + +When using `file=`*filename*, specifying `%p`, `%t` and/or `%hn` in the file name +expands to the JVM's PID, startup timestamp and host name, respectively. You can also +configure text files to handle file rotation based on file size and a number of +files to rotate. For example, to rotate the log file every 10 MB and keep 5 +files in rotation, specify the options `filesize=10M, filecount=5`. The target +size of the files isn't guaranteed to be exact, it's just an approximate value. +Files are rotated by default with up to 5 rotated files of target size 20 MB, +unless configured otherwise. Specifying `filecount=0` means that the log file +shouldn't be rotated. There's a possibility of the pre-existing log file +getting overwritten. + +### -Xlog Output Mode + +By default logging messages are output synchronously - each log message is written to +the designated output when the logging call is made. But you can instead use asynchronous +logging mode by specifying: + +`-Xlog:async` +: Write all logging asynchronously. + +In asynchronous logging mode, log sites enqueue all logging messages to an intermediate buffer +and a standalone thread is responsible for flushing them to the corresponding outputs. The +intermediate buffer is bounded and on buffer exhaustion the enqueuing message is discarded. +Log entry write operations are guaranteed non-blocking. + +The option `-XX:AsyncLogBufferSize=N` specifies the memory budget in bytes for the intermediate buffer. +The default value should be big enough to cater for most cases. Users can provide a custom value to +trade memory overhead for log accuracy if they need to. + +### Decorations + +Logging messages are decorated with information about the message. You can +configure each output to use a custom set of decorators. The order of the +output is always the same as listed in the table. You can configure the +decorations to be used at run time. Decorations are prepended to the log +message. For example: + +``` +[6.567s][info][gc,old] Old collection complete +``` + +Omitting `decorators` defaults to `uptime`, `level`, and `tags`. The `none` +decorator is special and is used to turn off all decorations. + +`time` (`t`), `utctime` (`utc`), `uptime` (`u`), `timemillis` (`tm`), +`uptimemillis` (`um`), `timenanos` (`tn`), `uptimenanos` (`un`), `hostname` +(`hn`), `pid` (`p`), `tid` (`ti`), `level` (`l`), `tags` (`tg`) decorators can +also be specified as `none` for no decoration. + +Table: Logging Messages Decorations + +--------------- -------------------------------------------------------------- +Decorations Description +--------------- -------------------------------------------------------------- +`time` or `t` Current time and date in ISO-8601 format. + +`utctime` Universal Time Coordinated or Coordinated Universal Time. +or `utc` + +`uptime` or `u` Time since the start of the JVM in seconds and milliseconds. + For example, 6.567s. + +`timemillis` The same value as generated by `System.currentTimeMillis()` +or `tm` + +`uptimemillis` Milliseconds since the JVM started. +or `um` + +`timenanos` The same value generated by `System.nanoTime()`. +or `tn` + +`uptimenanos` Nanoseconds since the JVM started. +or `un` + +`hostname` The host name. +or `hn` + +`pid` or `p` The process identifier. + +`tid` or `ti` The thread identifier. + +`level` or `l` The level associated with the log message. + +`tags` or `tg` The tag-set associated with the log message. +--------------- -------------------------------------------------------------- + +### Convert GC Logging Flags to Xlog + +Table: Legacy GC Logging Flags to Xlog Configuration Mapping + +------------------------------------ -------------------------- ---------------------------------------------------- +Legacy Garbage Collection (GC) Flag Xlog Configuration Comment +------------------------------------ -------------------------- ---------------------------------------------------- +`G1PrintHeapRegions` `-Xlog:gc+region=trace` Not Applicable + +`GCLogFileSize` No configuration Log rotation is handled by the framework. + available + +`NumberOfGCLogFiles` Not Applicable Log rotation is handled by the framework. + +`PrintAdaptiveSizePolicy` `-Xlog:gc+ergo*=`*level* Use a *level* of `debug` for most of the information, + or a *level* of `trace` for all of what was logged + for `PrintAdaptiveSizePolicy`. + +`PrintGC` `-Xlog:gc` Not Applicable + +`PrintGCApplicationConcurrentTime` `-Xlog:safepoint` Note that `PrintGCApplicationConcurrentTime` and + `PrintGCApplicationStoppedTime` are logged on the + same tag and aren't separated in the new logging. + +`PrintGCApplicationStoppedTime` `-Xlog:safepoint` Note that `PrintGCApplicationConcurrentTime` and + `PrintGCApplicationStoppedTime` are logged on the + same tag and not separated in the new logging. + +`PrintGCCause` Not Applicable GC cause is now always logged. + +`PrintGCDateStamps` Not Applicable Date stamps are logged by the framework. + +`PrintGCDetails` `-Xlog:gc*` Not Applicable + +`PrintGCID` Not Applicable GC ID is now always logged. + +`PrintGCTaskTimeStamps` `-Xlog:gc+task*=debug` Not Applicable + +`PrintGCTimeStamps` Not Applicable Time stamps are logged by the framework. + +`PrintHeapAtGC` `-Xlog:gc+heap=trace` Not Applicable + +`PrintReferenceGC` `-Xlog:gc+ref*=debug` Note that in the old logging, `PrintReferenceGC` had + an effect only if `PrintGCDetails` was also enabled. + +`PrintStringDeduplicationStatistics` `-Xlog:gc+stringdedup*=debug` Not Applicable + +`PrintTenuringDistribution` `-Xlog:gc+age*=`*level* Use a *level* of `debug` for the most relevant + information, or a *level* of `trace` for all of what + was logged for `PrintTenuringDistribution`. + +`UseGCLogFileRotation` Not Applicable What was logged for `PrintTenuringDistribution`. +------------------------------------ -------------------------- ---------------------------------------------------- + +### Convert Runtime Logging Flags to Xlog + +These legacy flags are no longer recognized and will cause an error if used directly. Use their unified logging equivalent +instead. + +Table: Runtime Logging Flags to Xlog Configuration Mapping + +--------------------------- ------------------------------------- ------------------------------------------------------------------ +Legacy Runtime Flag Xlog Configuration Comment +--------------------------- ------------------------------------- ------------------------------------------------------------------ +`TraceExceptions` `-Xlog:exceptions=info` Not Applicable + +`TraceClassLoading` `-Xlog:class+load=`*level* Use *level*=`info` for regular information, or *level*=`debug` + for additional information. In Unified Logging syntax, + `-verbose:class` equals `-Xlog:class+load=info,class+unload=info`. + +`TraceClassLoadingPreorder` `-Xlog:class+preorder=debug` Not Applicable + +`TraceClassUnloading` `-Xlog:class+unload=`*level* Use *level*=`info` for regular information, or *level*=`trace` + for additional information. In Unified Logging syntax, + `-verbose:class` equals `-Xlog:class+load=info,class+unload=info`. + +`VerboseVerification` `-Xlog:verification=info` Not Applicable + +`TraceClassPaths` `-Xlog:class+path=info` Not Applicable + +`TraceClassResolution` `-Xlog:class+resolve=debug` Not Applicable + +`TraceClassInitialization` `-Xlog:class+init=info` Not Applicable + +`TraceLoaderConstraints` `-Xlog:class+loader+constraints=info` Not Applicable + + +`TraceClassLoaderData` `-Xlog:class+loader+data=`*level* Use *level*=`debug` for regular information or *level*=`trace` for + additional information. + +`TraceSafepointCleanupTime` `-Xlog:safepoint+cleanup=info` Not Applicable + +`TraceSafepoint` `-Xlog:safepoint=debug` Not Applicable + +`TraceMonitorInflation` `-Xlog:monitorinflation=debug` Not Applicable + +`TraceRedefineClasses` `-Xlog:redefine+class*=`*level* *level*=`info`, `debug`, and `trace` provide increasing amounts + of information. +--------------------------- ------------------------------------- ------------------------------------------------------------------ + +### -Xlog Usage Examples + +The following are `-Xlog` examples. + +`-Xlog` +: Logs all messages by using the `info` level to `stdout` with `uptime`, + `levels`, and `tags` decorations. This is equivalent to using: + + > `-Xlog:all=info:stdout:uptime,levels,tags` + +`-Xlog:gc` +: Logs messages tagged with the `gc` tag using `info` level to `stdout`. The + default configuration for all other messages at level `warning` is in + effect. + +`-Xlog:gc,safepoint` +: Logs messages tagged either with the `gc` or `safepoint` tags, both using + the `info` level, to `stdout`, with default decorations. Messages tagged + with both `gc` and `safepoint` won't be logged. + +`-Xlog:gc+ref=debug` +: Logs messages tagged with both `gc` and `ref` tags, using the `debug` level + to `stdout`, with default decorations. Messages tagged only with one of the + two tags won't be logged. + +`-Xlog:gc=debug:file=gc.txt:none` +: Logs messages tagged with the `gc` tag using the `debug` level to a file + called `gc.txt` with no decorations. The default configuration for all + other messages at level `warning` is still in effect. + +`-Xlog:gc=trace:file=gctrace.txt:uptimemillis,pid:filecount=5,filesize=1024` +: Logs messages tagged with the `gc` tag using the `trace` level to a + rotating file set with 5 files with size 1 MB with the base name + `gctrace.txt` and uses decorations `uptimemillis` and `pid`. + + The default configuration for all other messages at level `warning` is + still in effect. + +`-Xlog:gc::uptime,tid` +: Logs messages tagged with the `gc` tag using the default 'info' level to + default the output `stdout` and uses decorations `uptime` and `tid`. The + default configuration for all other messages at level `warning` is still in + effect. + +`-Xlog:gc*=info,safepoint*=off` +: Logs messages tagged with at least `gc` using the `info` level, but turns + off logging of messages tagged with `safepoint`. Messages tagged with both + `gc` and `safepoint` won't be logged. + +`-Xlog:disable -Xlog:safepoint=trace:safepointtrace.txt` +: Turns off all logging, including warnings and errors, and then enables + messages tagged with `safepoint`using `trace`level to the file + `safepointtrace.txt`. The default configuration doesn't apply, because the + command line started with `-Xlog:disable`. + +### Complex -Xlog Usage Examples + +The following describes a few complex examples of using the `-Xlog` option. + +`-Xlog:gc+class*=debug` +: Logs messages tagged with at least `gc` and `class` tags using the `debug` + level to `stdout`. The default configuration for all other messages at the + level `warning` is still in effect + +`-Xlog:gc+meta*=trace,class*=off:file=gcmetatrace.txt` +: Logs messages tagged with at least the `gc` and `meta` tags using the + `trace` level to the file `metatrace.txt` but turns off all messages tagged + with `class`. Messages tagged with `gc`, `meta`, and `class` aren't be + logged as `class*` is set to off. The default configuration for all other + messages at level `warning` is in effect except for those that include + `class`. + +`-Xlog:gc+meta=trace` +: Logs messages tagged with exactly the `gc` and `meta` tags using the + `trace` level to `stdout`. The default configuration for all other messages + at level `warning` is still be in effect. + +`-Xlog:gc+class+heap*=debug,meta*=warning,threads*=off` +: Logs messages tagged with at least `gc`, `class`, and `heap` tags using the + `trace` level to `stdout` but only log messages tagged with `meta` with + level. The default configuration for all other messages at the level + `warning` is in effect except for those that include `threads`. + +## Validate Java Virtual Machine Flag Arguments + +You use values provided to all Java Virtual Machine (JVM) command-line flags +for validation and, if the input value is invalid or out-of-range, then an +appropriate error message is displayed. + +Whether they're set ergonomically, in a command line, by an input tool, or +through the APIs (for example, classes contained in the package +`java.lang.management`) the values provided to all Java Virtual Machine (JVM) +command-line flags are validated. Ergonomics are described in Java Platform, +Standard Edition HotSpot Virtual Machine Garbage Collection Tuning Guide. + +Range and constraints are validated either when all flags have their values set +during JVM initialization or a flag's value is changed during runtime (for +example using the `jcmd` tool). The JVM is terminated if a value violates +either the range or constraint check and an appropriate error message is +printed on the error stream. + +For example, if a flag violates a range or a constraint check, then the JVM +exits with an error: + +``` +java -XX:AllocatePrefetchStyle=5 -version +intx AllocatePrefetchStyle=5 is outside the allowed range [ 0 ... 3 ] +Improperly specified VM option 'AllocatePrefetchStyle=5' +Error: Could not create the Java Virtual Machine. +Error: A fatal exception has occurred. Program will exit. +``` + +The flag `-XX:+PrintFlagsRanges` prints the range of all the flags. This flag +allows automatic testing of the flags by the values provided by the ranges. For +the flags that have the ranges specified, the type, name, and the actual range +is printed in the output. + +For example, + +``` +intx ThreadStackSize [ 0 ... 9007199254740987 ] {pd product} +``` + +For the flags that don't have the range specified, the values aren't displayed +in the print out. For example: + +``` +size_t NewSize [ ... ] {product} +``` + +This helps to identify the flags that need to be implemented. The automatic +testing framework can skip those flags that don't have values and aren't +implemented. + +## Large Pages + +You use large pages, also known as huge pages, as memory pages that are +significantly larger than the standard memory page size (which varies depending +on the processor and operating system). Large pages optimize processor +Translation-Lookaside Buffers. + +A Translation-Lookaside Buffer (TLB) is a page translation cache that holds the +most-recently used virtual-to-physical address translations. A TLB is a scarce +system resource. A TLB miss can be costly because the processor must then read +from the hierarchical page table, which may require multiple memory accesses. +By using a larger memory page size, a single TLB entry can represent a larger +memory range. This results in less pressure on a TLB, and memory-intensive +applications may have better performance. + +However, using large pages can negatively affect system performance. For +example, when a large amount of memory is pinned by an application, it may +create a shortage of regular memory and cause excessive paging in other +applications and slow down the entire system. Also, a system that has been up +for a long time could produce excessive fragmentation, which could make it +impossible to reserve enough large page memory. When this happens, either the +OS or JVM reverts to using regular pages. + +Linux and Windows support large pages. + +### Large Pages Support for Linux + +Linux supports large pages since version 2.6. To check if your environment +supports large pages, try the following: + +``` +# cat /proc/meminfo | grep Huge +HugePages_Total: 0 +HugePages_Free: 0 +... +Hugepagesize: 2048 kB +``` + +If the output contains items prefixed with "Huge", then your system supports +large pages. The values may vary depending on environment. The `Hugepagesize` +field shows the default large page size in your environment, and the other +fields show details for large pages of this size. Newer kernels have support +for multiple large page sizes. To list the supported page sizes, run this: + +``` +# ls /sys/kernel/mm/hugepages/ +hugepages-1048576kB hugepages-2048kB +``` + +The above environment supports 2 MB and 1 GB large pages, but they need to be +configured so that the JVM can use them. When using large pages and not +enabling transparent huge pages (option `-XX:+UseTransparentHugePages`), the +number of large pages must be pre-allocated. For example, to enable 8 GB of +memory to be backed by 2 MB large pages, login as `root` and run: + +> `# echo 4096 > /sys/kernel/mm/hugepages/hugepages-2048kB/nr_hugepages` + +It is always recommended to check the value of `nr_hugepages` after the request +to make sure the kernel was able to allocate the requested number of large +pages. + +> **Note:** The values contained in `/proc` and `/sys` reset after you + reboot your system, so may want to set them in an initialization script + (for example, `rc.local` or `sysctl.conf`). + +If you configure the OS kernel parameters to enable use of large pages, the +Java processes may allocate large pages for the Java heap as well as other +internal areas, for example: + +* Code cache +* Marking bitmaps + +Consequently, if you configure the `nr_hugepages` parameter to the size of the +Java heap, then the JVM can still fail to allocate the heap using large pages +because other areas such as the code cache might already have used some of the +configured large pages. + +### Large Pages Support for Windows + +To use large pages support on Windows, the +administrator must first assign additional privileges to the user who is running +the application: + +1. Select **Control Panel**, **Administrative Tools**, and then **Local + Security Policy**. +2. Select **Local Policies** and then **User Rights Assignment**. +3. Double-click **Lock pages in memory**, then add users and/or groups. +4. Reboot your system. + +Note that these steps are required even if it's the administrator who's running +the application, because administrators by default don't have the privilege to +lock pages in memory. + +## Application Class Data Sharing + +Application Class Data Sharing (AppCDS) stores classes used +by your applications in an archive file. Since these classes are +stored in a format that can be loaded very quickly (compared +to classes stored in a JAR file), AppCDS can improve the start-up +time of your applications. In addition, AppCDS can reduce the runtime +memory footprint by sharing parts of these classes across multiple +processes. + +Classes in the CDS archive are stored in an optimized format that's +about 2 to 5 times larger than classes stored in JAR files or the JDK +runtime image. Therefore, it's a good idea to archive only those +classes that are actually used by your application. These usually +are just a small portion of all available classes. For example, your +application may use only a few APIs provided by a large library. + +### Using CDS Archives + +By default, in most JDK distributions, unless `-Xshare:off` is +specified, the JVM starts up with a default CDS archive, which +is usually located in `JAVA_HOME/lib/server/classes.jsa` (or +`JAVA_HOME\bin\server\classes.jsa` on Windows). This +archive contains about 1300 core library classes that are used +by most applications. + +To use CDS for the exact set of classes used by your application, +you can use the `-XX:SharedArchiveFile` option, which has the +general form: + +> `-XX:SharedArchiveFile=:` + +- The `` overrides the default CDS archive. +- The `` provides additional classes that can + be loaded on top of those in the ``. +- On Windows, the above path delimiter `:` should be replaced with `;` + +(The names "static" and "dynamic" are used for historical reasons. +The only significance is that the "static" archive is loaded first and +the "dynamic" archive is loaded second). + +The JVM can use up to two archives. To use only a single ``, +you can omit the `` portion: + +> `-XX:SharedArchiveFile=` + +For convenience, the `` records the location of the +``. Therefore, you can omit the `` by saying only: + +> `-XX:SharedArchiveFile=` + +### Manually Creating CDS Archives + +CDS archives can be created manually using several methods: + +- `-Xshare:dump` +- `-XX:ArchiveClassesAtExit` +- `jcmd VM.cds` + +One common operation in all these methods is a "trial run", where you run +the application once to determine the classes that should be stored +in the archive. + +#### Creating a Static CDS Archive File with -Xshare:dump + +The following steps create a static CDS archive file that contains all the classes +used by the `test.Hello` application. + +1. Create a list of all classes used by the `test.Hello` application. The + following command creates a file named `hello.classlist` that contains a + list of all classes used by this application: + + > `java -Xshare:off -XX:DumpLoadedClassList=hello.classlist -cp hello.jar test.Hello` + + The classpath specified by the `-cp` parameter must contain only + JAR files. + +2. Create a static archive, named `hello.jsa`, that contains all the classes + in `hello.classlist`: + + > `java -Xshare:dump -XX:SharedArchiveFile=hello.jsa -XX:SharedClassListFile=hello.classlist -cp hello.jar` + +3. Run the application `test.Hello` with the archive `hello.jsa`: + + > `java -XX:SharedArchiveFile=hello.jsa -cp hello.jar test.Hello` + +4. **Optional** Verify that the `test.Hello` application is using the class + contained in the `hello.jsa` shared archive: + + > `java -XX:SharedArchiveFile=hello.jsa -cp hello.jar -Xlog:class+load test.Hello` + + The output of this command should contain the following text: + + > `[info][class,load] test.Hello source: shared objects file` + +By default, when the `-Xshare:dump` option is used, the JVM runs in interpreter-only mode +(as if the `-Xint` option were specified). This is required for generating deterministic output +in the shared archive file. I.e., the exact same archive will be generated, bit-for-bit, every time +you dump it. However, if deterministic output is not needed, and you have a large classlist, you can +explicitly add `-Xmixed` to the command-line to enable the JIT compiler. This will speed up +the archive creation. + +#### Creating a Dynamic CDS Archive File with -XX:ArchiveClassesAtExit + +Advantages of dynamic CDS archives are: + +- They usually use less disk space, since they don't need to store the + classes that are already in the static archive. +- They are created with one fewer step than the comparable static archive. + +The following steps create a dynamic CDS archive file that contains the classes +that are used by the `test.Hello` application, excluding those that are already in +the default CDS archive. + +1. Create a dynamic CDS archive, named `hello.jsa`, that contains all the classes + in `hello.jar` loaded by the application `test.Hello`: + + > `java -XX:ArchiveClassesAtExit=hello.jsa -cp hello.jar Hello` + +2. Run the application `test.Hello` with the shared archive `hello.jsa`: + + > `java -XX:SharedArchiveFile=hello.jsa -cp hello.jar test.Hello` + +3. **Optional** Repeat step 4 of the previous section to verify that the `test.Hello` application is using the class + contained in the `hello.jsa` shared archive. + +It's also possible to create a dynamic CDS archive with a non-default static CDS archive. E.g., + +> `java -XX:SharedArchiveFile=base.jsa -XX:ArchiveClassesAtExit=hello.jsa -cp hello.jar Hello` + +To run the application using this dynamic CDS archive: + +> `java -XX:SharedArchiveFile=base.jsa:hello.jsa -cp hello.jar Hello` + +(On Windows, the above path delimiter `:` should be replaced with `;`) + +As mention above, the name of the static archive can be skipped: + +> `java -XX:SharedArchiveFile=hello.jsa -cp hello.jar Hello` + +#### Creating CDS Archive Files with jcmd + +The previous two sections require you to modify the application's start-up script +in order to create a CDS archive. Sometimes this could be difficult, for example, +if the application's class path is set up by complex routines. + +The `jcmd VM.cds` command provides a less intrusive way for creating a CDS +archive by connecting to a running JVM process. You can create either a +static: + +> `jcmd VM.cds static_dump my_static_archive.jsa` + +or a dynamic archive: + +> `jcmd VM.cds dynamic_dump my_dynamic_archive.jsa` + +To use the resulting archive file in a subsequent run of the application +without modifying the application's start-up script, you can use the +following technique: + +> `env JAVA_TOOL_OPTIONS=-XX:SharedArchiveFile=my_static_archive.jsa bash app_start.sh` + +Note: to use `jcmd VM.cds dynamic_dump`, the JVM process identified by `` +must be started with `-XX:+RecordDynamicDumpInfo`, which can also be passed to the +application start-up script with the same technique: + +> `env JAVA_TOOL_OPTIONS=-XX:+RecordDynamicDumpInfo bash app_start.sh` + + +### Creating Dynamic CDS Archive File with -XX:+AutoCreateSharedArchive + +`-XX:+AutoCreateSharedArchive` is a more convenient way of creating/using +CDS archives. Unlike the methods of manual CDS archive creation described +in the previous section, with `-XX:+AutoCreateSharedArchive`, it's no longer +necessary to have a separate trial run. Instead, you can always run the +application with the same command-line and enjoy the benefits of CDS automatically. + +> `java -XX:+AutoCreateSharedArchive -XX:SharedArchiveFile=hello.jsa -cp hello.jar Hello` + +If the specified archive file exists and was created by the same version of the JDK, +then it will be loaded as a dynamic archive; otherwise it is ignored at VM startup. + +At VM exit, if the specified archive file does not exist, it will be created. +If it exists but was created with a different (but post JDK 19) version of the JDK, +then it will be replaced. In both cases the archive will be ready to be loaded the +next time the JVM is launched with the same command line. + +If the specified archive file exists but was created by a JDK version prior +to JDK 19, then it will be ignored: neither loaded at startup, nor replaced at exit. + +Developers should note that the contents of the CDS archive file are specific +to each build of the JDK. Therefore, if you switch to a different JDK build, +`-XX:+AutoCreateSharedArchive` will automatically recreate the archive to +match the JDK. If you intend to use this feature with an existing +archive, you should make sure that the archive is created by at least version +19 of the JDK. + + +### Restrictions on Class Path and Module Path + +- Neither the class path (`-classpath` and `-Xbootclasspath/a`) + nor the module path (`--module-path`) can contain non-empty directories. + +- Only modular JAR files are supported in `--module-path`. Exploded + modules are not supported. + +- The class path used at archive creation time must be the same as + (or a prefix of) the class path used at run time. (There's no + such requirement for the module path.) + +- The CDS archive cannot be loaded if any JAR files in the class path or + module path are modified after the archive is generated. + +- If any of the VM options `--upgrade-module-path`, `--patch-module` or + `--limit-modules` are specified, CDS is disabled. This means that the + JVM will execute without loading any CDS archives. In addition, if + you try to create a CDS archive with any of these 3 options specified, + the JVM will report an error. + +## Performance Tuning Examples + +You can use the Java advanced runtime options to optimize the performance of +your applications. + +### Tuning for Higher Throughput + +Use the following commands and advanced options to achieve higher +throughput performance for your application: + +> `java -server -XX:+UseParallelGC -XX:+UseLargePages -Xmn10g -Xms26g -Xmx26g` + +### Tuning for Lower Response Time + +Use the following commands and advanced options to achieve lower +response times for your application: + +> `java -XX:+UseG1GC -XX:MaxGCPauseMillis=100` + +### Keeping the Java Heap Small and Reducing the Dynamic Footprint of Embedded Applications + +Use the following advanced runtime options to keep the Java heap small and +reduce the dynamic footprint of embedded applications: + +> `-XX:MaxHeapFreeRatio=10 -XX:MinHeapFreeRatio=5` + +> **Note:** The defaults for these two options are 70% and 40% respectively. Because +performance sacrifices can occur when using these small settings, you should +optimize for a small footprint by reducing these settings as much as possible +without introducing unacceptable performance degradation. + +## Exit Status + +The following exit values are typically returned by the launcher when the +launcher is called with the wrong arguments, serious errors, or exceptions +thrown by the JVM. However, a Java application may choose to return any value +by using the API call `System.exit(exitValue)`. The values are: + +- `0`: Successful completion + +- `>0`: An error occurred diff --git a/src/java.base/share/man/keytool.1 b/src/java.base/share/man/keytool.1 deleted file mode 100644 index 63a134eb932..00000000000 --- a/src/java.base/share/man/keytool.1 +++ /dev/null @@ -1,2991 +0,0 @@ -.\" Copyright (c) 1998, 2024, Oracle and/or its affiliates. All rights reserved. -.\" DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -.\" -.\" This code is free software; you can redistribute it and/or modify it -.\" under the terms of the GNU General Public License version 2 only, as -.\" published by the Free Software Foundation. -.\" -.\" This code is distributed in the hope that it will be useful, but WITHOUT -.\" ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -.\" FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -.\" version 2 for more details (a copy is included in the LICENSE file that -.\" accompanied this code). -.\" -.\" You should have received a copy of the GNU General Public License version -.\" 2 along with this work; if not, write to the Free Software Foundation, -.\" Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -.\" -.\" Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -.\" or visit www.oracle.com if you need additional information or have any -.\" questions. -.\" -'\" t -.\" Automatically generated by Pandoc 2.19.2 -.\" -.\" Define V font for inline verbatim, using C font in formats -.\" that render this, and otherwise B font. -.ie "\f[CB]x\f[R]"x" \{\ -. ftr V B -. ftr VI BI -. ftr VB B -. ftr VBI BI -.\} -.el \{\ -. ftr V CR -. ftr VI CI -. ftr VB CB -. ftr VBI CBI -.\} -.TH "KEYTOOL" "1" "2025" "JDK 24-ea" "JDK Commands" -.hy -.SH NAME -.PP -keytool - a key and certificate management utility -.SH SYNOPSIS -.PP -\f[V]keytool\f[R] [\f[I]commands\f[R]] -.TP -\f[I]commands\f[R] -Commands for \f[V]keytool\f[R] include the following: -.RS -.IP \[bu] 2 -\f[V]-certreq\f[R]: Generates a certificate request -.IP \[bu] 2 -\f[V]-changealias\f[R]: Changes an entry\[aq]s alias -.IP \[bu] 2 -\f[V]-delete\f[R]: Deletes an entry -.IP \[bu] 2 -\f[V]-exportcert\f[R]: Exports certificate -.IP \[bu] 2 -\f[V]-genkeypair\f[R]: Generates a key pair -.IP \[bu] 2 -\f[V]-genseckey\f[R]: Generates a secret key -.IP \[bu] 2 -\f[V]-gencert\f[R]: Generates a certificate from a certificate request -.IP \[bu] 2 -\f[V]-importcert\f[R]: Imports a certificate or a certificate chain -.IP \[bu] 2 -\f[V]-importpass\f[R]: Imports a password -.IP \[bu] 2 -\f[V]-importkeystore\f[R]: Imports one or all entries from another -keystore -.IP \[bu] 2 -\f[V]-keypasswd\f[R]: Changes the key password of an entry -.IP \[bu] 2 -\f[V]-list\f[R]: Lists entries in a keystore -.IP \[bu] 2 -\f[V]-printcert\f[R]: Prints the content of a certificate -.IP \[bu] 2 -\f[V]-printcertreq\f[R]: Prints the content of a certificate request -.IP \[bu] 2 -\f[V]-printcrl\f[R]: Prints the content of a Certificate Revocation List -(CRL) file -.IP \[bu] 2 -\f[V]-storepasswd\f[R]: Changes the store password of a keystore -.IP \[bu] 2 -\f[V]-showinfo\f[R]: Displays security-related information -.IP \[bu] 2 -\f[V]-version\f[R]: Prints the program version -.PP -See \f[B]Commands and Options\f[R] for a description of these commands -with their options. -.RE -.SH DESCRIPTION -.PP -The \f[V]keytool\f[R] command is a key and certificate management -utility. -It enables users to administer their own public/private key pairs and -associated certificates for use in self-authentication (where a user -authenticates themselves to other users and services) or data integrity -and authentication services, by using digital signatures. -The \f[V]keytool\f[R] command also enables users to cache the public -keys (in the form of certificates) of their communicating peers. -.PP -A certificate is a digitally signed statement from one entity (person, -company, and so on), which says that the public key (and some other -information) of some other entity has a particular value. -When data is digitally signed, the signature can be verified to check -the data integrity and authenticity. -Integrity means that the data hasn\[aq]t been modified or tampered with, -and authenticity means that the data comes from the individual who -claims to have created and signed it. -.PP -The \f[V]keytool\f[R] command also enables users to administer secret -keys and passphrases used in symmetric encryption and decryption (Data -Encryption Standard). -It can also display other security-related information. -.PP -The \f[V]keytool\f[R] command stores the keys and certificates in a -keystore. -.PP -The \f[V]keytool\f[R] command uses the -\f[V]jdk.certpath.disabledAlgorithms\f[R] and -\f[V]jdk.security.legacyAlgorithms\f[R] security properties to determine -which algorithms are considered a security risk. -It emits warnings when disabled or legacy algorithms are being used. -The \f[V]jdk.certpath.disabledAlgorithms\f[R] and -\f[V]jdk.security.legacyAlgorithms\f[R] security properties are defined -in the \f[V]java.security\f[R] file (located in the JDK\[aq]s -\f[V]$JAVA_HOME/conf/security\f[R] directory). -.SH COMMAND AND OPTION NOTES -.PP -The following notes apply to the descriptions in \f[B]Commands and -Options\f[R]: -.IP \[bu] 2 -All command and option names are preceded by a hyphen sign -(\f[V]-\f[R]). -.IP \[bu] 2 -Only one command can be provided. -.IP \[bu] 2 -Options for each command can be provided in any order. -.IP \[bu] 2 -There are two kinds of options, one is single-valued which should be -only provided once. -If a single-valued option is provided multiple times, the value of the -last one is used. -The other type is multi-valued, which can be provided multiple times and -all values are used. -The only multi-valued option currently supported is the \f[V]-ext\f[R] -option used to generate X.509v3 certificate extensions. -.IP \[bu] 2 -All items not italicized or in braces ({ }) or brackets ([ ]) are -required to appear as is. -.IP \[bu] 2 -Braces surrounding an option signify that a default value is used when -the option isn\[aq]t specified on the command line. -Braces are also used around the \f[V]-v\f[R], \f[V]-rfc\f[R], and -\f[V]-J\f[R] options, which have meaning only when they appear on the -command line. -They don\[aq]t have any default values. -.IP \[bu] 2 -Brackets surrounding an option signify that the user is prompted for the -values when the option isn\[aq]t specified on the command line. -For the \f[V]-keypass\f[R] option, if you don\[aq]t specify the option -on the command line, then the \f[V]keytool\f[R] command first attempts -to use the keystore password to recover the private/secret key. -If this attempt fails, then the \f[V]keytool\f[R] command prompts you -for the private/secret key password. -.IP \[bu] 2 -Items in italics (option values) represent the actual values that must -be supplied. -For example, here is the format of the \f[V]-printcert\f[R] command: -.RS 2 -.RS -.PP -\f[V]keytool -printcert\f[R] {\f[V]-file\f[R] \f[I]cert_file\f[R]} -{\f[V]-v\f[R]} -.RE -.PP -When you specify a \f[V]-printcert\f[R] command, replace -\f[I]cert_file\f[R] with the actual file name, as follows: -\f[V]keytool -printcert -file VScert.cer\f[R] -.RE -.IP \[bu] 2 -Option values must be enclosed in quotation marks when they contain a -blank (space). -.SH COMMANDS AND OPTIONS -.PP -The keytool commands and their options can be grouped by the tasks that -they perform. -.PP -\f[B]Commands for Creating or Adding Data to the Keystore\f[R]: -.IP \[bu] 2 -\f[V]-gencert\f[R] -.IP \[bu] 2 -\f[V]-genkeypair\f[R] -.IP \[bu] 2 -\f[V]-genseckey\f[R] -.IP \[bu] 2 -\f[V]-importcert\f[R] -.IP \[bu] 2 -\f[V]-importpass\f[R] -.PP -\f[B]Commands for Importing Contents from Another Keystore\f[R]: -.IP \[bu] 2 -\f[V]-importkeystore\f[R] -.PP -\f[B]Commands for Generating a Certificate Request\f[R]: -.IP \[bu] 2 -\f[V]-certreq\f[R] -.PP -\f[B]Commands for Exporting Data\f[R]: -.IP \[bu] 2 -\f[V]-exportcert\f[R] -.PP -\f[B]Commands for Displaying Data\f[R]: -.IP \[bu] 2 -\f[V]-list\f[R] -.IP \[bu] 2 -\f[V]-printcert\f[R] -.IP \[bu] 2 -\f[V]-printcertreq\f[R] -.IP \[bu] 2 -\f[V]-printcrl\f[R] -.PP -\f[B]Commands for Managing the Keystore\f[R]: -.IP \[bu] 2 -\f[V]-storepasswd\f[R] -.IP \[bu] 2 -\f[V]-keypasswd\f[R] -.IP \[bu] 2 -\f[V]-delete\f[R] -.IP \[bu] 2 -\f[V]-changealias\f[R] -.PP -\f[B]Commands for Displaying Security-related Information\f[R]: -.IP \[bu] 2 -\f[V]-showinfo\f[R] -.PP -\f[B]Commands for Displaying Program Version\f[R]: -.IP \[bu] 2 -\f[V]-version\f[R] -.SH COMMANDS FOR CREATING OR ADDING DATA TO THE KEYSTORE -.TP -\f[V]-gencert\f[R] -The following are the available options for the \f[V]-gencert\f[R] -command: -.RS -.IP \[bu] 2 -{\f[V]-rfc\f[R]}: Output in RFC (Request For Comment) style -.IP \[bu] 2 -{\f[V]-infile\f[R] \f[I]infile\f[R]}: Input file name -.IP \[bu] 2 -{\f[V]-outfile\f[R] \f[I]outfile\f[R]}: Output file name -.IP \[bu] 2 -{\f[V]-alias\f[R] \f[I]alias\f[R]}: Alias name of the entry to process -.IP \[bu] 2 -{\f[V]-sigalg\f[R] \f[I]sigalg\f[R]}: Signature algorithm name -.IP \[bu] 2 -{\f[V]-dname\f[R] \f[I]dname\f[R]}: Distinguished name -.IP \[bu] 2 -{\f[V]-startdate\f[R] \f[I]startdate\f[R]}: Certificate validity start -date and time -.IP \[bu] 2 -{\f[V]-ext\f[R] \f[I]ext\f[R]}*: X.509 extension -.IP \[bu] 2 -{\f[V]-validity\f[R] \f[I]days\f[R]}: Validity number of days -.IP \[bu] 2 -[\f[V]-keypass\f[R] \f[I]arg\f[R]]: Key password -.IP \[bu] 2 -{\f[V]-keystore\f[R] \f[I]keystore\f[R]}: Keystore name -.IP \[bu] 2 -[\f[V]-storepass\f[R] \f[I]arg\f[R]]: Keystore password -.IP \[bu] 2 -{\f[V]-storetype\f[R] \f[I]type\f[R]}: Keystore type -.IP \[bu] 2 -{\f[V]-providername\f[R] \f[I]name\f[R]}: Provider name -.IP \[bu] 2 -{\f[V]-addprovider\f[R] \f[I]name\f[R] [\f[V]-providerarg\f[R] -\f[I]arg\f[R]]}: Adds a security provider by name (such as SunPKCS11) -with an optional configure argument. -The value of the security provider is the name of a security provider -that is defined in a module. -.RS 2 -.PP -For example, -.RS -.PP -\f[V]keytool -addprovider SunPKCS11 -providerarg some.cfg ...\f[R] -.RE -.PP -\f[B]Note:\f[R] -.PP -For compatibility reasons, the SunPKCS11 provider can still be loaded -with \f[V]-providerclass sun.security.pkcs11.SunPKCS11\f[R] even if it -is now defined in a module. -This is the only module included in the JDK that needs a configuration, -and therefore the most widely used with the \f[V]-providerclass\f[R] -option. -For legacy security providers located on classpath and loaded by -reflection, \f[V]-providerclass\f[R] should still be used. -.RE -.IP \[bu] 2 -{\f[V]-providerclass\f[R] \f[I]class\f[R] [\f[V]-providerarg\f[R] -\f[I]arg\f[R]]}: Add security provider by fully qualified class name -with an optional configure argument. -.RS 2 -.PP -For example, if \f[V]MyProvider\f[R] is a legacy provider loaded via -reflection, -.RS -.PP -\f[V]keytool -providerclass com.example.MyProvider ...\f[R] -.RE -.RE -.IP \[bu] 2 -{\f[V]-providerpath\f[R] \f[I]list\f[R]}: Provider classpath -.IP \[bu] 2 -{\f[V]-v\f[R]}: Verbose output -.IP \[bu] 2 -{\f[V]-protected\f[R]}: Password provided through a protected mechanism -.PP -Use the \f[V]-gencert\f[R] command to generate a certificate as a -response to a certificate request file (which can be created by the -\f[V]keytool -certreq\f[R] command). -The command reads the request either from \f[I]infile\f[R] or, if -omitted, from the standard input, signs it by using the alias\[aq]s -private key, and outputs the X.509 certificate into either -\f[I]outfile\f[R] or, if omitted, to the standard output. -When \f[V]-rfc\f[R] is specified, the output format is Base64-encoded -PEM; otherwise, a binary DER is created. -.PP -The \f[V]-sigalg\f[R] value specifies the algorithm that should be used -to sign the certificate. -The \f[I]startdate\f[R] argument is the start time and date that the -certificate is valid. -The \f[I]days\f[R] argument tells the number of days for which the -certificate should be considered valid. -.PP -When \f[I]dname\f[R] is provided, it is used as the subject of the -generated certificate. -Otherwise, the one from the certificate request is used. -.PP -The \f[V]-ext\f[R] value shows what X.509 extensions will be embedded in -the certificate. -Read \f[B]Common Command Options\f[R] for the grammar of \f[V]-ext\f[R]. -.PP -The \f[V]-gencert\f[R] option enables you to create certificate chains. -The following example creates a certificate, \f[V]e1\f[R], that contains -three certificates in its certificate chain. -.PP -The following commands creates four key pairs named \f[V]ca\f[R], -\f[V]ca1\f[R], \f[V]ca2\f[R], and \f[V]e1\f[R]: -.IP -.nf -\f[CB] -keytool -alias ca -dname CN=CA -genkeypair -keyalg rsa -keytool -alias ca1 -dname CN=CA -genkeypair -keyalg rsa -keytool -alias ca2 -dname CN=CA -genkeypair -keyalg rsa -keytool -alias e1 -dname CN=E1 -genkeypair -keyalg rsa -\f[R] -.fi -.PP -The following two commands create a chain of signed certificates; -\f[V]ca\f[R] signs \f[V]ca1\f[R] and \f[V]ca1\f[R] signs \f[V]ca2\f[R], -all of which are self-issued: -.IP -.nf -\f[CB] -keytool -alias ca1 -certreq | - keytool -alias ca -gencert -ext san=dns:ca1 | - keytool -alias ca1 -importcert - -keytool -alias ca2 -certreq | - keytool -alias ca1 -gencert -ext san=dns:ca2 | - keytool -alias ca2 -importcert -\f[R] -.fi -.PP -The following command creates the certificate \f[V]e1\f[R] and stores it -in the \f[V]e1.cert\f[R] file, which is signed by \f[V]ca2\f[R]. -As a result, \f[V]e1\f[R] should contain \f[V]ca\f[R], \f[V]ca1\f[R], -and \f[V]ca2\f[R] in its certificate chain: -.RS -.PP -\f[V]keytool -alias e1 -certreq | keytool -alias ca2 -gencert > e1.cert\f[R] -.RE -.RE -.TP -\f[V]-genkeypair\f[R] -The following are the available options for the \f[V]-genkeypair\f[R] -command: -.RS -.IP \[bu] 2 -{\f[V]-alias\f[R] \f[I]alias\f[R]}: Alias name of the entry to process -.IP \[bu] 2 -\f[V]-keyalg\f[R] \f[I]alg\f[R]: Key algorithm name -.IP \[bu] 2 -{\f[V]-keysize\f[R] \f[I]size\f[R]}: Key bit size -.IP \[bu] 2 -{\f[V]-groupname\f[R] \f[I]name\f[R]}: Group name. -For example, an Elliptic Curve name. -.IP \[bu] 2 -{\f[V]-sigalg\f[R] \f[I]alg\f[R]}: Signature algorithm name -.IP \[bu] 2 -{\f[V]-signer\f[R] \f[I]alias\f[R]}: Signer alias -.IP \[bu] 2 -[\f[V]-signerkeypass\f[R] \f[I]arg\f[R]]: Signer key password -.IP \[bu] 2 -[\f[V]-dname\f[R] \f[I]name\f[R]]: Distinguished name -.IP \[bu] 2 -{\f[V]-startdate\f[R] \f[I]date\f[R]}: Certificate validity start date -and time -.IP \[bu] 2 -{\f[V]-ext\f[R] \f[I]value\f[R]}*: X.509 extension -.IP \[bu] 2 -{\f[V]-validity\f[R] \f[I]days\f[R]}: Validity number of days -.IP \[bu] 2 -[\f[V]-keypass\f[R] \f[I]arg\f[R]]: Key password -.IP \[bu] 2 -{\f[V]-keystore\f[R] \f[I]keystore\f[R]}: Keystore name -.IP \[bu] 2 -[\f[V]-storepass\f[R] \f[I]arg\f[R]]: Keystore password -.IP \[bu] 2 -{\f[V]-storetype\f[R] \f[I]type\f[R]}: Keystore type -.IP \[bu] 2 -{\f[V]-providername\f[R] \f[I]name\f[R]}: Provider name -.IP \[bu] 2 -{\f[V]-addprovider\f[R] \f[I]name\f[R] [\f[V]-providerarg\f[R] -\f[I]arg\f[R]]}: Add security provider by name (such as SunPKCS11) with -an optional configure argument. -.IP \[bu] 2 -{\f[V]-providerclass\f[R] \f[I]class\f[R] [\f[V]-providerarg\f[R] -\f[I]arg\f[R]] }: Add security provider by fully qualified class name -with an optional configure argument. -.IP \[bu] 2 -{\f[V]-providerpath\f[R] \f[I]list\f[R]}: Provider classpath -.IP \[bu] 2 -{\f[V]-v\f[R]}: Verbose output -.IP \[bu] 2 -{\f[V]-protected\f[R]}: Password provided through a protected mechanism -.PP -Use the \f[V]-genkeypair\f[R] command to generate a key pair (a public -key and associated private key). -When the \f[V]-signer\f[R] option is not specified, the public key is -wrapped in an X.509 v3 self-signed certificate and stored as a -single-element certificate chain. -When the \f[V]-signer\f[R] option is specified, a new certificate is -generated and signed by the designated signer and stored as a -multiple-element certificate chain (containing the generated certificate -itself, and the signer\[aq]s certificate chain). -The certificate chain and private key are stored in a new keystore entry -that is identified by its alias. -.PP -The \f[V]-keyalg\f[R] value specifies the algorithm to be used to -generate the key pair. -The \f[V]-keysize\f[R] value specifies the size of each key to be -generated. -The \f[V]-groupname\f[R] value specifies the named group (for example, -the standard or predefined name of an Elliptic Curve) of the key to be -generated. -.PP -When a \f[V]-keysize\f[R] value is provided, it will be used to -initialize a \f[V]KeyPairGenerator\f[R] object using the -\f[V]initialize(int keysize)\f[R] method. -When a \f[V]-groupname\f[R] value is provided, it will be used to -initialize a \f[V]KeyPairGenerator\f[R] object using the -\f[V]initialize(AlgorithmParameterSpec params)\f[R] method where -\f[V]params\f[R] is \f[V]new NamedParameterSpec(groupname)\f[R]. -.PP -Only one of \f[V]-groupname\f[R] and \f[V]-keysize\f[R] can be -specified. -If an algorithm has multiple named groups that have the same key size, -the \f[V]-groupname\f[R] option should usually be used. -In this case, if \f[V]-keysize\f[R] is specified, it\[aq]s up to the -security provider to determine which named group is chosen when -generating a key pair. -.PP -The \f[V]-sigalg\f[R] value specifies the algorithm that should be used -to sign the certificate. -This algorithm must be compatible with the \f[V]-keyalg\f[R] value. -.PP -The \f[V]-signer\f[R] value specifies the alias of a -\f[V]PrivateKeyEntry\f[R] for the signer that already exists in the -keystore. -This option is used to sign the certificate with the signer\[aq]s -private key. -This is especially useful for key agreement algorithms (i.e. -the \f[V]-keyalg\f[R] value is \f[V]XDH\f[R], \f[V]X25519\f[R], -\f[V]X448\f[R], or \f[V]DH\f[R]) as these keys cannot be used for -digital signatures, and therefore a self-signed certificate cannot be -created. -.PP -The \f[V]-signerkeypass\f[R] value specifies the password of the -signer\[aq]s private key. -It can be specified if the private key of the signer entry is protected -by a password different from the store password. -.PP -The \f[V]-dname\f[R] value specifies the X.500 Distinguished Name to be -associated with the value of \f[V]-alias\f[R]. -If the \f[V]-signer\f[R] option is not specified, the issuer and subject -fields of the self-signed certificate are populated with the specified -distinguished name. -If the \f[V]-signer\f[R] option is specified, the subject field of the -certificate is populated with the specified distinguished name and the -issuer field is populated with the subject field of the signer\[aq]s -certificate. -If a distinguished name is not provided at the command line, then the -user is prompted for one. -.PP -The value of \f[V]-keypass\f[R] is a password used to protect the -private key of the generated key pair. -If a password is not provided, then the user is prompted for it. -If you press the \f[B]Return\f[R] key at the prompt, then the key -password is set to the same password as the keystore password. -The \f[V]-keypass\f[R] value must have at least six characters. -.PP -The value of \f[V]-startdate\f[R] specifies the issue time of the -certificate, also known as the \[dq]Not Before\[dq] value of the X.509 -certificate\[aq]s Validity field. -.PP -The option value can be set in one of these two forms: -.PP -([\f[V]+-\f[R]]\f[I]nnn\f[R][\f[V]ymdHMS\f[R]])+ -.PP -[\f[I]yyyy\f[R]\f[V]/\f[R]\f[I]mm\f[R]\f[V]/\f[R]\f[I]dd\f[R]] -[\f[I]HH\f[R]\f[V]:\f[R]\f[I]MM\f[R]\f[V]:\f[R]\f[I]SS\f[R]] -.PP -With the first form, the issue time is shifted by the specified value -from the current time. -The value is a concatenation of a sequence of subvalues. -Inside each subvalue, the plus sign (+) means shift forward, and the -minus sign (-) means shift backward. -The time to be shifted is \f[I]nnn\f[R] units of years, months, days, -hours, minutes, or seconds (denoted by a single character of -\f[V]y\f[R], \f[V]m\f[R], \f[V]d\f[R], \f[V]H\f[R], \f[V]M\f[R], or -\f[V]S\f[R] respectively). -The exact value of the issue time is calculated by using the -\f[V]java.util.GregorianCalendar.add(int field, int amount)\f[R] method -on each subvalue, from left to right. -For example, the issue time can be specified by: -.IP -.nf -\f[CB] -Calendar c = new GregorianCalendar(); -c.add(Calendar.YEAR, -1); -c.add(Calendar.MONTH, 1); -c.add(Calendar.DATE, -1); -return c.getTime() -\f[R] -.fi -.PP -With the second form, the user sets the exact issue time in two parts, -year/month/day and hour:minute:second (using the local time zone). -The user can provide only one part, which means the other part is the -same as the current date (or time). -The user must provide the exact number of digits shown in the format -definition (padding with 0 when shorter). -When both date and time are provided, there is one (and only one) space -character between the two parts. -The hour should always be provided in 24-hour format. -.PP -When the option isn\[aq]t provided, the start date is the current time. -The option can only be provided one time. -.PP -The value of \f[I]date\f[R] specifies the number of days (starting at -the date specified by \f[V]-startdate\f[R], or the current date when -\f[V]-startdate\f[R] isn\[aq]t specified) for which the certificate -should be considered valid. -.RE -.TP -\f[V]-genseckey\f[R] -The following are the available options for the \f[V]-genseckey\f[R] -command: -.RS -.IP \[bu] 2 -{\f[V]-alias\f[R] \f[I]alias\f[R]}: Alias name of the entry to process -.IP \[bu] 2 -[\f[V]-keypass\f[R] \f[I]arg\f[R]]: Key password -.IP \[bu] 2 -\f[V]-keyalg\f[R] \f[I]alg\f[R]: Key algorithm name -.IP \[bu] 2 -{\f[V]-keysize\f[R] \f[I]size\f[R]}: Key bit size -.IP \[bu] 2 -{\f[V]-keystore\f[R] \f[I]keystore\f[R]}: Keystore name -.IP \[bu] 2 -[\f[V]-storepass\f[R] \f[I]arg\f[R]]: Keystore password -.IP \[bu] 2 -{\f[V]-storetype\f[R] \f[I]type\f[R]}: Keystore type -.IP \[bu] 2 -{\f[V]-providername\f[R] \f[I]name\f[R]}: Provider name -.IP \[bu] 2 -{\f[V]-addprovider\f[R] \f[I]name\f[R] [\f[V]-providerarg\f[R] -\f[I]arg\f[R]]}: Add security provider by name (such as SunPKCS11) with -an optional configure argument. -.IP \[bu] 2 -{\f[V]-providerclass\f[R] \f[I]class\f[R] [\f[V]-providerarg\f[R] -\f[I]arg\f[R]]}: Add security provider by fully qualified class name -with an optional configure argument. -.IP \[bu] 2 -{\f[V]-providerpath\f[R] \f[I]list\f[R]}: Provider classpath -.IP \[bu] 2 -{\f[V]-v\f[R]}: Verbose output -.IP \[bu] 2 -{\f[V]-protected\f[R]}: Password provided through a protected mechanism -.PP -Use the \f[V]-genseckey\f[R] command to generate a secret key and store -it in a new \f[V]KeyStore.SecretKeyEntry\f[R] identified by -\f[V]alias\f[R]. -.PP -The value of \f[V]-keyalg\f[R] specifies the algorithm to be used to -generate the secret key, and the value of \f[V]-keysize\f[R] specifies -the size of the key that is generated. -The \f[V]-keypass\f[R] value is a password that protects the secret key. -If a password is not provided, then the user is prompted for it. -If you press the \f[B]Return\f[R] key at the prompt, then the key -password is set to the same password that is used for the -\f[V]-keystore\f[R]. -The \f[V]-keypass\f[R] value must contain at least six characters. -.RE -.TP -\f[V]-importcert\f[R] -The following are the available options for the \f[V]-importcert\f[R] -command: -.RS -.IP \[bu] 2 -{\f[V]-noprompt\f[R]}: Do not prompt -.IP \[bu] 2 -{\f[V]-trustcacerts\f[R]}: Trust certificates from cacerts -.IP \[bu] 2 -{\f[V]-protected\f[R]}: Password is provided through protected mechanism -.IP \[bu] 2 -{\f[V]-alias\f[R] \f[I]alias\f[R]}: Alias name of the entry to process -.IP \[bu] 2 -{\f[V]-file\f[R] \f[I]file\f[R]}: Input file name -.IP \[bu] 2 -[\f[V]-keypass\f[R] \f[I]arg\f[R]]: Key password -.IP \[bu] 2 -{\f[V]-keystore\f[R] \f[I]keystore\f[R]}: Keystore name -.IP \[bu] 2 -{\f[V]-cacerts\f[R]}: Access the cacerts keystore -.IP \[bu] 2 -[\f[V]-storepass\f[R] \f[I]arg\f[R]]: Keystore password -.IP \[bu] 2 -{\f[V]-storetype\f[R] \f[I]type\f[R]}: Keystore type -.IP \[bu] 2 -{\f[V]-providername\f[R] \f[I]name\f[R]}: Provider name -.IP \[bu] 2 -{\f[V]-addprovider\f[R] \f[I]name\f[R] [\f[V]-providerarg\f[R] -\f[I]arg\f[R]]}: Add security provider by name (such as SunPKCS11) with -an optional configure argument. -.IP \[bu] 2 -{\f[V]-providerclass\f[R] \f[I]class\f[R] [\f[V]-providerarg\f[R] -\f[I]arg\f[R]]}: Add security provider by fully qualified class name -with an optional configure argument. -.IP \[bu] 2 -{\f[V]-providerpath\f[R] \f[I]list\f[R]}: Provider classpath -.IP \[bu] 2 -{\f[V]-v\f[R]}: Verbose output -.PP -Use the \f[V]-importcert\f[R] command to read the certificate or -certificate chain (where the latter is supplied in a PKCS#7 formatted -reply or in a sequence of X.509 certificates) from \f[V]-file\f[R] -\f[I]file\f[R], and store it in the \f[V]keystore\f[R] entry identified -by \f[V]-alias\f[R]. -If \f[V]-file\f[R] \f[I]file\f[R] is not specified, then the certificate -or certificate chain is read from \f[V]stdin\f[R]. -.PP -The \f[V]keytool\f[R] command can import X.509 v1, v2, and v3 -certificates, and PKCS#7 formatted certificate chains consisting of -certificates of that type. -The data to be imported must be provided either in binary encoding -format or in printable encoding format (also known as Base64 encoding) -as defined by the Internet RFC 1421 standard. -In the latter case, the encoding must be bounded at the beginning by a -string that starts with \f[V]-----BEGIN\f[R], and bounded at the end by -a string that starts with \f[V]-----END\f[R]. -.PP -You import a certificate for two reasons: To add it to the list of -trusted certificates, and to import a certificate reply received from a -certificate authority (CA) as the result of submitting a Certificate -Signing Request (CSR) to that CA. -See the \f[V]-certreq\f[R] command in \f[B]Commands for Generating a -Certificate Request\f[R]. -.PP -The type of import is indicated by the value of the \f[V]-alias\f[R] -option. -If the alias doesn\[aq]t point to a key entry, then the -\f[V]keytool\f[R] command assumes you are adding a trusted certificate -entry. -In this case, the alias shouldn\[aq]t already exist in the keystore. -If the alias does exist, then the \f[V]keytool\f[R] command outputs an -error because a trusted certificate already exists for that alias, and -doesn\[aq]t import the certificate. -If \f[V]-alias\f[R] points to a key entry, then the \f[V]keytool\f[R] -command assumes that you\[aq]re importing a certificate reply. -.RE -.TP -\f[V]-importpass\f[R] -The following are the available options for the \f[V]-importpass\f[R] -command: -.RS -.IP \[bu] 2 -{\f[V]-alias\f[R] \f[I]alias\f[R]}: Alias name of the entry to process -.IP \[bu] 2 -[\f[V]-keypass\f[R] \f[I]arg\f[R]]: Key password -.IP \[bu] 2 -{\f[V]-keyalg\f[R] \f[I]alg\f[R]}: Key algorithm name -.IP \[bu] 2 -{\f[V]-keysize\f[R] \f[I]size\f[R]}: Key bit size -.IP \[bu] 2 -{\f[V]-keystore\f[R] \f[I]keystore\f[R]}: Keystore name -.IP \[bu] 2 -[\f[V]-storepass\f[R] \f[I]arg\f[R]]: Keystore password -.IP \[bu] 2 -{\f[V]-storetype\f[R] \f[I]type\f[R]}: Keystore type -.IP \[bu] 2 -{\f[V]-providername\f[R] \f[I]name\f[R]}: Provider name -.IP \[bu] 2 -{\f[V]-addprovider\f[R] \f[I]name\f[R] [\f[V]-providerarg\f[R] -\f[I]arg\f[R]]}: Add security provider by name (such as SunPKCS11) with -an optional configure argument. -.IP \[bu] 2 -{\f[V]-providerclass\f[R] \f[I]class\f[R] [\f[V]-providerarg\f[R] -\f[I]arg\f[R]]}: Add security provider by fully qualified class name -with an optional configure argument. -.IP \[bu] 2 -{\f[V]-providerpath\f[R] \f[I]list\f[R]}: Provider classpath -.IP \[bu] 2 -{\f[V]-v\f[R]}: Verbose output -.IP \[bu] 2 -{\f[V]-protected\f[R]}: Password provided through a protected mechanism -.PP -Use the \f[V]-importpass\f[R] command to imports a passphrase and store -it in a new \f[V]KeyStore.SecretKeyEntry\f[R] identified by -\f[V]-alias\f[R]. -The passphrase may be supplied via the standard input stream; otherwise -the user is prompted for it. -The \f[V]-keypass\f[R] option provides a password to protect the -imported passphrase. -If a password is not provided, then the user is prompted for it. -If you press the \f[B]Return\f[R] key at the prompt, then the key -password is set to the same password as that used for the -\f[V]keystore\f[R]. -The \f[V]-keypass\f[R] value must contain at least six characters. -.RE -.SH COMMANDS FOR IMPORTING CONTENTS FROM ANOTHER KEYSTORE -.TP -\f[V]-importkeystore\f[R] -The following are the available options for the -\f[V]-importkeystore\f[R] command: -.RS -.IP \[bu] 2 -\f[V]-srckeystore\f[R] \f[I]keystore\f[R]: Source keystore name -.IP \[bu] 2 -{\f[V]-destkeystore\f[R] \f[I]keystore\f[R]}: Destination keystore name -.IP \[bu] 2 -{\f[V]-srcstoretype\f[R] \f[I]type\f[R]}: Source keystore type -.IP \[bu] 2 -{\f[V]-deststoretype\f[R] \f[I]type\f[R]}: Destination keystore type -.IP \[bu] 2 -[\f[V]-srcstorepass\f[R] \f[I]arg\f[R]]: Source keystore password -.IP \[bu] 2 -[\f[V]-deststorepass\f[R] \f[I]arg\f[R]]: Destination keystore password -.IP \[bu] 2 -{\f[V]-srcprotected\f[R]}: Source keystore password protected -.IP \[bu] 2 -{\f[V]-destprotected\f[R]}: Destination keystore password protected -.IP \[bu] 2 -{\f[V]-srcprovidername\f[R] \f[I]name\f[R]}: Source keystore provider -name -.IP \[bu] 2 -{\f[V]-destprovidername\f[R] \f[I]name\f[R]}: Destination keystore -provider name -.IP \[bu] 2 -{\f[V]-srcalias\f[R] \f[I]alias\f[R]}: Source alias -.IP \[bu] 2 -{\f[V]-destalias\f[R] \f[I]alias\f[R]}: Destination alias -.IP \[bu] 2 -[\f[V]-srckeypass\f[R] \f[I]arg\f[R]]: Source key password -.IP \[bu] 2 -[\f[V]-destkeypass\f[R] \f[I]arg\f[R]]: Destination key password -.IP \[bu] 2 -{\f[V]-noprompt\f[R]}: Do not prompt -.IP \[bu] 2 -{\f[V]-addprovider\f[R] \f[I]name\f[R] [\f[V]-providerarg\f[R] -\f[I]arg\f[R]]: Add security provider by name (such as SunPKCS11) with -an optional configure argument. -.IP \[bu] 2 -{\f[V]-providerclass\f[R] \f[I]class\f[R] [\f[V]-providerarg\f[R] -\f[I]arg\f[R]]}: Add security provider by fully qualified class name -with an optional configure argument -.IP \[bu] 2 -{\f[V]-providerpath\f[R] \f[I]list\f[R]}: Provider classpath -.IP \[bu] 2 -{\f[V]-v\f[R]}: Verbose output -.PP -\f[B]Note:\f[R] -.PP -This is the first line of all options: -.RS -.PP -\f[V]-srckeystore\f[R] \f[I]keystore\f[R] \f[V]-destkeystore\f[R] -\f[I]keystore\f[R] -.RE -.PP -Use the \f[V]-importkeystore\f[R] command to import a single entry or -all entries from a source keystore to a destination keystore. -.PP -\f[B]Note:\f[R] -.PP -If you do not specify \f[V]-destkeystore\f[R] when using the -\f[V]keytool -importkeystore\f[R] command, then the default keystore -used is \f[V]$HOME/.keystore\f[R]. -.PP -When the \f[V]-srcalias\f[R] option is provided, the command imports the -single entry identified by the alias to the destination keystore. -If a destination alias isn\[aq]t provided with \f[V]-destalias\f[R], -then \f[V]-srcalias\f[R] is used as the destination alias. -If the source entry is protected by a password, then -\f[V]-srckeypass\f[R] is used to recover the entry. -If \f[V]-srckeypass\f[R] isn\[aq]t provided, then the \f[V]keytool\f[R] -command attempts to use \f[V]-srcstorepass\f[R] to recover the entry. -If \f[V]-srcstorepass\f[R] is not provided or is incorrect, then the -user is prompted for a password. -The destination entry is protected with \f[V]-destkeypass\f[R]. -If \f[V]-destkeypass\f[R] isn\[aq]t provided, then the destination entry -is protected with the source entry password. -For example, most third-party tools require \f[V]storepass\f[R] and -\f[V]keypass\f[R] in a PKCS #12 keystore to be the same. -To create a PKCS#12 keystore for these tools, always specify a -\f[V]-destkeypass\f[R] that is the same as \f[V]-deststorepass\f[R]. -.PP -If the \f[V]-srcalias\f[R] option isn\[aq]t provided, then all entries -in the source keystore are imported into the destination keystore. -Each destination entry is stored under the alias from the source entry. -If the source entry is protected by a password, then -\f[V]-srcstorepass\f[R] is used to recover the entry. -If \f[V]-srcstorepass\f[R] is not provided or is incorrect, then the -user is prompted for a password. -If a source keystore entry type isn\[aq]t supported in the destination -keystore, or if an error occurs while storing an entry into the -destination keystore, then the user is prompted either to skip the entry -and continue or to quit. -The destination entry is protected with the source entry password. -.PP -If the destination alias already exists in the destination keystore, -then the user is prompted either to overwrite the entry or to create a -new entry under a different alias name. -.PP -If the \f[V]-noprompt\f[R] option is provided, then the user isn\[aq]t -prompted for a new destination alias. -Existing entries are overwritten with the destination alias name. -Entries that can\[aq]t be imported are skipped and a warning is -displayed. -.RE -.SH COMMANDS FOR GENERATING A CERTIFICATE REQUEST -.TP -\f[V]-certreq\f[R] -The following are the available options for the \f[V]-certreq\f[R] -command: -.RS -.IP \[bu] 2 -{\f[V]-alias\f[R] \f[I]alias\f[R]}: Alias name of the entry to process -.IP \[bu] 2 -{\f[V]-sigalg\f[R] \f[I]alg\f[R]}: Signature algorithm name -.IP \[bu] 2 -{\f[V]-file\f[R] \f[I]file\f[R]}: Output file name -.IP \[bu] 2 -[ \f[V]-keypass\f[R] \f[I]arg\f[R]]: Key password -.IP \[bu] 2 -{\f[V]-keystore\f[R] \f[I]keystore\f[R]}: Keystore name -.IP \[bu] 2 -{\f[V]-dname\f[R] \f[I]name\f[R]}: Distinguished name -.IP \[bu] 2 -{\f[V]-ext\f[R] \f[I]value\f[R]}: X.509 extension -.IP \[bu] 2 -[\f[V]-storepass\f[R] \f[I]arg\f[R]]: Keystore password -.IP \[bu] 2 -{\f[V]-storetype\f[R] \f[I]type\f[R]}: Keystore type -.IP \[bu] 2 -{\f[V]-providername\f[R] \f[I]name\f[R]}: Provider name -.IP \[bu] 2 -{\f[V]-addprovider\f[R] \f[I]name\f[R] [\f[V]-providerarg\f[R] -\f[I]arg\f[R]]}: Add security provider by name (such as SunPKCS11) with -an optional configure argument. -.IP \[bu] 2 -{\f[V]-providerclass\f[R] \f[I]class\f[R] [\f[V]-providerarg\f[R] -\f[I]arg\f[R]]}: Add security provider by fully qualified class name -with an optional configure argument. -.IP \[bu] 2 -{\f[V]-providerpath\f[R] \f[I]list\f[R]}: Provider classpath -.IP \[bu] 2 -{\f[V]-v\f[R]}: Verbose output -.IP \[bu] 2 -{\f[V]-protected\f[R]}: Password provided through a protected mechanism -.PP -Use the \f[V]-certreq\f[R] command to generate a Certificate Signing -Request (CSR) using the PKCS #10 format. -.PP -A CSR is intended to be sent to a CA. -The CA authenticates the certificate requestor (usually offline) and -returns a certificate or certificate chain to replace the existing -certificate chain (initially a self-signed certificate) in the keystore. -.PP -The private key associated with \f[I]alias\f[R] is used to create the -PKCS #10 certificate request. -To access the private key, the correct password must be provided. -If \f[V]-keypass\f[R] isn\[aq]t provided at the command line and is -different from the password used to protect the integrity of the -keystore, then the user is prompted for it. -If \f[V]-dname\f[R] is provided, then it is used as the subject in the -CSR. -Otherwise, the X.500 Distinguished Name associated with alias is used. -.PP -The \f[V]-sigalg\f[R] value specifies the algorithm that should be used -to sign the CSR. -.PP -The CSR is stored in the \f[V]-file\f[R] \f[I]file\f[R]. -If a file is not specified, then the CSR is output to \f[V]-stdout\f[R]. -.PP -Use the \f[V]-importcert\f[R] command to import the response from the -CA. -.RE -.SH COMMANDS FOR EXPORTING DATA -.TP -\f[V]-exportcert\f[R] -The following are the available options for the \f[V]-exportcert\f[R] -command: -.RS -.IP \[bu] 2 -{\f[V]-rfc\f[R]}: Output in RFC style -.IP \[bu] 2 -{\f[V]-alias\f[R] \f[I]alias\f[R]}: Alias name of the entry to process -.IP \[bu] 2 -{\f[V]-file\f[R] \f[I]file\f[R]}: Output file name -.IP \[bu] 2 -{\f[V]-keystore\f[R] \f[I]keystore\f[R]}: Keystore name -.IP \[bu] 2 -{\f[V]-cacerts\f[R]}: Access the cacerts keystore -.IP \[bu] 2 -[\f[V]-storepass\f[R] \f[I]arg\f[R]]: Keystore password -.IP \[bu] 2 -{\f[V]-storetype\f[R] \f[I]type\f[R]}: Keystore type -.IP \[bu] 2 -{\f[V]-providername\f[R] \f[I]name\f[R]}: Provider name -.IP \[bu] 2 -{\f[V]-addprovider\f[R] \f[I]name\f[R] [\f[V]-providerarg\f[R] -\f[I]arg\f[R]]}: Add security provider by name (such as SunPKCS11) with -an optional configure argument. -.IP \[bu] 2 -{\f[V]-providerclass\f[R] \f[I]class\f[R] [\f[V]-providerarg\f[R] -\f[I]arg\f[R]] }: Add security provider by fully qualified class name -with an optional configure argument. -.IP \[bu] 2 -{\f[V]-providerpath\f[R] \f[I]list\f[R]}: Provider classpath -.IP \[bu] 2 -{\f[V]-v\f[R]}: Verbose output -.IP \[bu] 2 -{\f[V]-protected\f[R]}: Password provided through a protected mechanism -.PP -Use the \f[V]-exportcert\f[R] command to read a certificate from the -keystore that is associated with \f[V]-alias\f[R] \f[I]alias\f[R] and -store it in the \f[V]-file\f[R] \f[I]file\f[R]. -When a file is not specified, the certificate is output to -\f[V]stdout\f[R]. -.PP -By default, the certificate is output in binary encoding. -If the \f[V]-rfc\f[R] option is specified, then the output in the -printable encoding format defined by the Internet RFC 1421 Certificate -Encoding Standard. -.PP -If \f[V]-alias\f[R] refers to a trusted certificate, then that -certificate is output. -Otherwise, \f[V]-alias\f[R] refers to a key entry with an associated -certificate chain. -In that case, the first certificate in the chain is returned. -This certificate authenticates the public key of the entity addressed by -\f[V]-alias\f[R]. -.RE -.SH COMMANDS FOR DISPLAYING DATA -.TP -\f[V]-list\f[R] -The following are the available options for the \f[V]-list\f[R] command: -.RS -.IP \[bu] 2 -{\f[V]-rfc\f[R]}: Output in RFC style -.IP \[bu] 2 -{\f[V]-alias\f[R] \f[I]alias\f[R]}: Alias name of the entry to process -.IP \[bu] 2 -{\f[V]-keystore\f[R] \f[I]keystore\f[R]}: Keystore name -.IP \[bu] 2 -{\f[V]-cacerts\f[R]}: Access the cacerts keystore -.IP \[bu] 2 -[\f[V]-storepass\f[R] \f[I]arg\f[R]]: Keystore password -.IP \[bu] 2 -{\f[V]-storetype\f[R] \f[I]type\f[R]}: Keystore type -.IP \[bu] 2 -{\f[V]-providername\f[R] \f[I]name\f[R]}: Provider name -.IP \[bu] 2 -{\f[V]-addprovider\f[R] \f[I]name\f[R] [\f[V]-providerarg\f[R] -\f[I]arg\f[R]]}: Add security provider by name (such as SunPKCS11) with -an optional configure argument. -.IP \[bu] 2 -{\f[V]-providerclass\f[R] \f[I]class\f[R] [\f[V]-providerarg\f[R] -\f[I]arg\f[R]] }: Add security provider by fully qualified class name -with an optional configure argument. -.IP \[bu] 2 -{\f[V]-providerpath\f[R] \f[I]list\f[R]}: Provider classpath -.IP \[bu] 2 -{\f[V]-v\f[R]}: Verbose output -.IP \[bu] 2 -{\f[V]-protected\f[R]}: Password provided through a protected mechanism -.PP -Use the \f[V]-list\f[R] command to print the contents of the keystore -entry identified by \f[V]-alias\f[R] to \f[V]stdout\f[R]. -If \f[V]-alias\f[R] \f[I]alias\f[R] is not specified, then the contents -of the entire keystore are printed. -.PP -By default, this command prints the SHA-256 fingerprint of a -certificate. -If the \f[V]-v\f[R] option is specified, then the certificate is printed -in human-readable format, with additional information such as the owner, -issuer, serial number, and any extensions. -If the \f[V]-rfc\f[R] option is specified, then the certificate contents -are printed by using the printable encoding format, as defined by the -Internet RFC 1421 Certificate Encoding Standard. -.PP -\f[B]Note:\f[R] -.PP -You can\[aq]t specify both \f[V]-v\f[R] and \f[V]-rfc\f[R] in the same -command. -Otherwise, an error is reported. -.RE -.TP -\f[V]-printcert\f[R] -The following are the available options for the \f[V]-printcert\f[R] -command: -.RS -.IP \[bu] 2 -{\f[V]-rfc\f[R]}: Output in RFC style -.IP \[bu] 2 -{\f[V]-file\f[R] \f[I]cert_file\f[R]}: Input file name -.IP \[bu] 2 -{\f[V]-sslserver\f[R] \f[I]server\f[R][\f[V]:\f[R]\f[I]port\f[R]]}:: -Secure Sockets Layer (SSL) server host and port -.IP \[bu] 2 -{\f[V]-jarfile\f[R] \f[I]JAR_file\f[R]}: Signed \f[V].jar\f[R] file -.IP \[bu] 2 -{\f[V]-keystore\f[R] \f[I]keystore\f[R]}: Keystore name -.IP \[bu] 2 -{\f[V]-trustcacerts\f[R]}: Trust certificates from cacerts -.IP \[bu] 2 -[\f[V]-storepass\f[R] \f[I]arg\f[R]]: Keystore password -.IP \[bu] 2 -{\f[V]-storetype\f[R] \f[I]type\f[R]}: Keystore type -.IP \[bu] 2 -{\f[V]-providername\f[R] \f[I]name\f[R]}: Provider name -.IP \[bu] 2 -{\f[V]-addprovider\f[R] \f[I]name\f[R] [\f[V]-providerarg\f[R] -\f[I]arg\f[R]]}: Add security provider by name (such as SunPKCS11) with -an optional configure argument. -.IP \[bu] 2 -{\f[V]-providerclass\f[R] \f[I]class\f[R] [\f[V]-providerarg\f[R] -\f[I]arg\f[R]]}: Add security provider by fully qualified class name -with an optional configure argument. -.IP \[bu] 2 -{\f[V]-providerpath\f[R] \f[I]list\f[R]}: Provider classpath -.IP \[bu] 2 -{\f[V]-protected\f[R]}: Password is provided through protected mechanism -.IP \[bu] 2 -{\f[V]-v\f[R]}: Verbose output -.PP -Use the \f[V]-printcert\f[R] command to read and print the certificate -from \f[V]-file\f[R] \f[I]cert_file\f[R], the SSL server located at -\f[V]-sslserver\f[R] \f[I]server\f[R][\f[V]:\f[R]\f[I]port\f[R]], or the -signed JAR file specified by \f[V]-jarfile\f[R] \f[I]JAR_file\f[R]. -It prints its contents in a human-readable format. -When a port is not specified, the standard HTTPS port 443 is assumed. -.PP -\f[B]Note:\f[R] -.PP -The \f[V]-sslserver\f[R] and \f[V]-file\f[R] options can\[aq]t be -provided in the same command. -Otherwise, an error is reported. -If you don\[aq]t specify either option, then the certificate is read -from \f[V]stdin\f[R]. -.PP -When\f[V]-rfc\f[R] is specified, the \f[V]keytool\f[R] command prints -the certificate in PEM mode as defined by the Internet RFC 1421 -Certificate Encoding standard. -.PP -If the certificate is read from a file or \f[V]stdin\f[R], then it might -be either binary encoded or in printable encoding format, as defined by -the RFC 1421 Certificate Encoding standard. -.PP -If the SSL server is behind a firewall, then the -\f[V]-J-Dhttps.proxyHost=proxyhost\f[R] and -\f[V]-J-Dhttps.proxyPort=proxyport\f[R] options can be specified on the -command line for proxy tunneling. -.PP -\f[B]Note:\f[R] -.PP -This command can be used independently of a keystore. -This command does not check for the weakness of a certificate\[aq]s -signature algorithm if it is a trusted certificate in the user keystore -(specified by \f[V]-keystore\f[R]) or in the \f[V]cacerts\f[R] keystore -(if \f[V]-trustcacerts\f[R] is specified). -.RE -.TP -\f[V]-printcertreq\f[R] -The following are the available options for the \f[V]-printcertreq\f[R] -command: -.RS -.IP \[bu] 2 -{\f[V]-file\f[R] \f[I]file\f[R]}: Input file name -.IP \[bu] 2 -{\f[V]-v\f[R]}: Verbose output -.PP -Use the \f[V]-printcertreq\f[R] command to print the contents of a PKCS -#10 format certificate request, which can be generated by the -\f[V]keytool -certreq\f[R] command. -The command reads the request from file. -If there is no file, then the request is read from the standard input. -.RE -.TP -\f[V]-printcrl\f[R] -The following are the available options for the \f[V]-printcrl\f[R] -command: -.RS -.IP \[bu] 2 -{\f[V]-file crl\f[R]}: Input file name -.IP \[bu] 2 -{\f[V]-keystore\f[R] \f[I]keystore\f[R]}: Keystore name -.IP \[bu] 2 -{\f[V]-trustcacerts\f[R]}: Trust certificates from cacerts -.IP \[bu] 2 -[\f[V]-storepass\f[R] \f[I]arg\f[R]]: Keystore password -.IP \[bu] 2 -{\f[V]-storetype\f[R] \f[I]type\f[R]}: Keystore type -.IP \[bu] 2 -{\f[V]-providername\f[R] \f[I]name\f[R]}: Provider name -.IP \[bu] 2 -{\f[V]-addprovider\f[R] \f[I]name\f[R] [\f[V]-providerarg\f[R] -\f[I]arg\f[R]]}: Add security provider by name (such as SunPKCS11) with -an optional configure argument. -.IP \[bu] 2 -{\f[V]-providerclass\f[R] \f[I]class\f[R] [\f[V]-providerarg\f[R] -\f[I]arg\f[R]]}: Add security provider by fully qualified class name -with an optional configure argument. -.IP \[bu] 2 -{\f[V]-providerpath\f[R] \f[I]list\f[R]}: Provider classpath -.IP \[bu] 2 -{\f[V]-protected\f[R]}: Password is provided through protected mechanism -.IP \[bu] 2 -{\f[V]-v\f[R]}: Verbose output -.PP -Use the \f[V]-printcrl\f[R] command to read the Certificate Revocation -List (CRL) from \f[V]-file crl\f[R] . -A CRL is a list of the digital certificates that were revoked by the CA -that issued them. -The CA generates the \f[V]crl\f[R] file. -.PP -\f[B]Note:\f[R] -.PP -This command can be used independently of a keystore. -This command attempts to verify the CRL using a certificate from the -user keystore (specified by \f[V]-keystore\f[R]) or the -\f[V]cacerts\f[R] keystore (if \f[V]-trustcacerts\f[R] is specified), -and will print out a warning if it cannot be verified. -.RE -.SH COMMANDS FOR MANAGING THE KEYSTORE -.TP -\f[V]-storepasswd\f[R] -The following are the available options for the \f[V]-storepasswd\f[R] -command: -.RS -.IP \[bu] 2 -[\f[V]-new\f[R] \f[I]arg\f[R]]: New password -.IP \[bu] 2 -{\f[V]-keystore\f[R] \f[I]keystore\f[R]}: Keystore name -.IP \[bu] 2 -{\f[V]-cacerts\f[R]}: Access the cacerts keystore -.IP \[bu] 2 -[\f[V]-storepass\f[R] \f[I]arg\f[R]]: Keystore password -.IP \[bu] 2 -{\f[V]-storetype\f[R] \f[I]type\f[R]}: Keystore type -.IP \[bu] 2 -{\f[V]-providername\f[R] \f[I]name\f[R]}: Provider name -.IP \[bu] 2 -{\f[V]-addprovider\f[R] \f[I]name\f[R] [\f[V]-providerarg\f[R] -\f[I]arg\f[R]]}: Add security provider by name (such as SunPKCS11) with -an optional configure argument. -.IP \[bu] 2 -{\f[V]-providerclass\f[R] \f[I]class\f[R] [\f[V]-providerarg\f[R] -\f[I]arg\f[R]]}: Add security provider by fully qualified class name -with an optional configure argument. -.IP \[bu] 2 -{\f[V]-providerpath\f[R] \f[I]list\f[R]}: Provider classpath -.IP \[bu] 2 -{\f[V]-v\f[R]}: Verbose output -.PP -Use the \f[V]-storepasswd\f[R] command to change the password used to -protect the integrity of the keystore contents. -The new password is set by \f[V]-new\f[R] \f[I]arg\f[R] and must contain -at least six characters. -.RE -.TP -\f[V]-keypasswd\f[R] -The following are the available options for the \f[V]-keypasswd\f[R] -command: -.RS -.IP \[bu] 2 -{\f[V]-alias\f[R] \f[I]alias\f[R]}: Alias name of the entry to process -.IP \[bu] 2 -[\f[V]-keypass\f[R] \f[I]old_keypass\f[R]]: Key password -.IP \[bu] 2 -[\f[V]-new\f[R] \f[I]new_keypass\f[R]]: New password -.IP \[bu] 2 -{\f[V]-keystore\f[R] \f[I]keystore\f[R]}: Keystore name -.IP \[bu] 2 -{\f[V]-storepass\f[R] \f[I]arg\f[R]}: Keystore password -.IP \[bu] 2 -{\f[V]-storetype\f[R] \f[I]type\f[R]}: Keystore type -.IP \[bu] 2 -{\f[V]-providername\f[R] \f[I]name\f[R]}: Provider name -.IP \[bu] 2 -{\f[V]-addprovider\f[R] \f[I]name\f[R] [\f[V]-providerarg\f[R] -\f[I]arg\f[R]]}: Add security provider by name (such as SunPKCS11) with -an optional configure argument. -.IP \[bu] 2 -{\f[V]-providerclass\f[R] \f[I]class\f[R] [\f[V]-providerarg\f[R] -\f[I]arg\f[R]]}: Add security provider by fully qualified class name -with an optional configure argument. -.IP \[bu] 2 -{\f[V]-providerpath\f[R] \f[I]list\f[R]}: Provider classpath -.IP \[bu] 2 -{\f[V]-v\f[R]}: Verbose output -.PP -Use the \f[V]-keypasswd\f[R] command to change the password (under which -private/secret keys identified by \f[V]-alias\f[R] are protected) from -\f[V]-keypass\f[R] \f[I]old_keypass\f[R] to \f[V]-new\f[R] -\f[I]new_keypass\f[R]. -The password value must contain at least six characters. -.PP -If the \f[V]-keypass\f[R] option isn\[aq]t provided at the command line -and the \f[V]-keypass\f[R] password is different from the keystore -password (\f[V]-storepass\f[R] \f[I]arg\f[R]), then the user is prompted -for it. -.PP -If the \f[V]-new\f[R] option isn\[aq]t provided at the command line, -then the user is prompted for it. -.RE -.TP -\f[V]-delete\f[R] -The following are the available options for the \f[V]-delete\f[R] -command: -.RS -.IP \[bu] 2 -[\f[V]-alias\f[R] \f[I]alias\f[R]]: Alias name of the entry to process -.IP \[bu] 2 -{\f[V]-keystore\f[R] \f[I]keystore\f[R]}: Keystore name -.IP \[bu] 2 -{\f[V]-cacerts\f[R]}: Access the cacerts keystore -.IP \[bu] 2 -[\f[V]-storepass\f[R] \f[I]arg\f[R]]: Keystore password -.IP \[bu] 2 -{\f[V]-storetype\f[R] \f[I]type\f[R]}: Keystore type -.IP \[bu] 2 -{\f[V]-providername\f[R] \f[I]name\f[R]}: Provider name -.IP \[bu] 2 -{\f[V]-addprovider\f[R] \f[I]name\f[R] [\f[V]-providerarg\f[R] -\f[I]arg\f[R]]}: Add security provider by name (such as SunPKCS11) with -an optional configure argument. -.IP \[bu] 2 -{\f[V]-providerclass\f[R] \f[I]class\f[R] [\f[V]-providerarg\f[R] -\f[I]arg\f[R]]}: Add security provider by fully qualified class name -with an optional configure argument. -.IP \[bu] 2 -{\f[V]-providerpath\f[R] \f[I]list\f[R]}: Provider classpath -.IP \[bu] 2 -{\f[V]-v\f[R]}: Verbose output -.IP \[bu] 2 -{\f[V]-protected\f[R]}: Password provided through a protected mechanism -.PP -Use the \f[V]-delete\f[R] command to delete the \f[V]-alias\f[R] -\f[I]alias\f[R] entry from the keystore. -When not provided at the command line, the user is prompted for the -\f[V]alias\f[R]. -.RE -.TP -\f[V]-changealias\f[R] -The following are the available options for the \f[V]-changealias\f[R] -command: -.RS -.IP \[bu] 2 -{\f[V]-alias\f[R] \f[I]alias\f[R]}: Alias name of the entry to process -.IP \[bu] 2 -[\f[V]-destalias\f[R] \f[I]alias\f[R]]: Destination alias -.IP \[bu] 2 -[\f[V]-keypass\f[R] \f[I]arg\f[R]]: Key password -.IP \[bu] 2 -{\f[V]-keystore\f[R] \f[I]keystore\f[R]}: Keystore name -.IP \[bu] 2 -{\f[V]-cacerts\f[R]}: Access the cacerts keystore -.IP \[bu] 2 -[\f[V]-storepass\f[R] \f[I]arg\f[R]]: Keystore password -.IP \[bu] 2 -{\f[V]-storetype\f[R] \f[I]type\f[R]}: Keystore type -.IP \[bu] 2 -{\f[V]-providername\f[R] \f[I]name\f[R]}: Provider name -.IP \[bu] 2 -{\f[V]-addprovider\f[R] \f[I]name\f[R] [\f[V]-providerarg\f[R] -\f[I]arg\f[R]]}: Add security provider by name (such as SunPKCS11) with -an optional configure argument. -.IP \[bu] 2 -{\f[V]-providerclass\f[R] \f[I]class\f[R] [\f[V]-providerarg\f[R] -\f[I]arg\f[R]]}: Add security provider by fully qualified class name -with an optional configure argument. -.IP \[bu] 2 -{\f[V]-providerpath\f[R] \f[I]list\f[R]}: Provider classpath -.IP \[bu] 2 -{\f[V]-v\f[R]}: Verbose output -.IP \[bu] 2 -{\f[V]-protected\f[R]}: Password provided through a protected mechanism -.PP -Use the \f[V]-changealias\f[R] command to move an existing keystore -entry from \f[V]-alias\f[R] \f[I]alias\f[R] to a new -\f[V]-destalias\f[R] \f[I]alias\f[R]. -If a destination alias is not provided, then the command prompts you for -one. -If the original entry is protected with an entry password, then the -password can be supplied with the \f[V]-keypass\f[R] option. -If a key password is not provided, then the \f[V]-storepass\f[R] (if -provided) is attempted first. -If the attempt fails, then the user is prompted for a password. -.RE -.SH COMMANDS FOR DISPLAYING SECURITY-RELATED INFORMATION -.TP -\f[V]-showinfo\f[R] -The following are the available options for the \f[V]-showinfo\f[R] -command: -.RS -.IP \[bu] 2 -{\f[V]-tls\f[R]}: Displays TLS configuration information -.IP \[bu] 2 -{\f[V]-v\f[R]}: Verbose output -.PP -Use the \f[V]-showinfo\f[R] command to display various security-related -information. -The \f[V]-tls\f[R] option displays TLS configurations, such as the list -of enabled protocols and cipher suites. -.RE -.SH COMMANDS FOR DISPLAYING PROGRAM VERSION -.PP -You can use \f[V]-version\f[R] to print the program version of -\f[V]keytool\f[R]. -.SH COMMANDS FOR DISPLAYING HELP INFORMATION -.PP -You can use \f[V]--help\f[R] to display a list of \f[V]keytool\f[R] -commands or to display help information about a specific -\f[V]keytool\f[R] command. -.IP \[bu] 2 -To display a list of \f[V]keytool\f[R] commands, enter: -.RS 2 -.RS -.PP -\f[V]keytool --help\f[R] -.RE -.RE -.IP \[bu] 2 -To display help information about a specific \f[V]keytool\f[R] command, -enter: -.RS 2 -.RS -.PP -\f[V]keytool - --help\f[R] -.RE -.RE -.SH COMMON COMMAND OPTIONS -.PP -The \f[V]-v\f[R] option can appear for all commands except -\f[V]--help\f[R]. -When the \f[V]-v\f[R] option appears, it signifies verbose mode, which -means that more information is provided in the output. -.PP -The \f[V]-J\f[R]\f[I]option\f[R] argument can appear for any command. -When the \f[V]-J\f[R]\f[I]option\f[R] is used, the specified -\f[I]option\f[R] string is passed directly to the Java interpreter. -This option doesn\[aq]t contain any spaces. -It\[aq]s useful for adjusting the execution environment or memory usage. -For a list of possible interpreter options, enter \f[V]java -h\f[R] or -\f[V]java -X\f[R] at the command line. -.PP -These options can appear for all commands operating on a keystore: -.TP -\f[V]-storetype\f[R] \f[I]storetype\f[R] -This qualifier specifies the type of keystore to be instantiated. -.TP -\f[V]-keystore\f[R] \f[I]keystore\f[R] -The keystore location. -.RS -.PP -If the JKS \f[V]storetype\f[R] is used and a keystore file doesn\[aq]t -yet exist, then certain \f[V]keytool\f[R] commands can result in a new -keystore file being created. -For example, if \f[V]keytool -genkeypair\f[R] is called and the -\f[V]-keystore\f[R] option isn\[aq]t specified, the default keystore -file named \f[V].keystore\f[R] is created in the user\[aq]s home -directory if it doesn\[aq]t already exist. -Similarly, if the \f[V]-keystore ks_file\f[R] option is specified but -\f[V]ks_file\f[R] doesn\[aq]t exist, then it is created. -For more information on the JKS \f[V]storetype\f[R], see the -\f[B]KeyStore Implementation\f[R] section in \f[B]KeyStore aliases\f[R]. -.PP -Note that the input stream from the \f[V]-keystore\f[R] option is passed -to the \f[V]KeyStore.load\f[R] method. -If \f[V]NONE\f[R] is specified as the URL, then a null stream is passed -to the \f[V]KeyStore.load\f[R] method. -\f[V]NONE\f[R] should be specified if the keystore isn\[aq]t file-based. -For example, when the keystore resides on a hardware token device. -.RE -.TP -\f[V]-cacerts\f[R] \f[I]cacerts\f[R] -Operates on the \f[I]cacerts\f[R] keystore . -This option is equivalent to \f[V]-keystore\f[R] -\f[I]path_to_cacerts\f[R] \f[V]-storetype\f[R] -\f[I]type_of_cacerts\f[R]. -An error is reported if the \f[V]-keystore\f[R] or \f[V]-storetype\f[R] -option is used with the \f[V]-cacerts\f[R] option. -.TP -\f[V]-storepass\f[R] [\f[V]:env\f[R] | \f[V]:file\f[R] ] \f[I]argument\f[R] -The password that is used to protect the integrity of the keystore. -.RS -.PP -If the modifier \f[V]env\f[R] or \f[V]file\f[R] isn\[aq]t specified, -then the password has the value \f[I]argument\f[R], which must contain -at least six characters. -Otherwise, the password is retrieved as follows: -.IP \[bu] 2 -\f[V]env\f[R]: Retrieve the password from the environment variable named -\f[I]argument\f[R]. -.IP \[bu] 2 -\f[V]file\f[R]: Retrieve the password from the file named -\f[I]argument\f[R]. -.PP -\f[B]Note:\f[R] All other options that require passwords, such as -\f[V]-keypass\f[R], \f[V]-srckeypass\f[R], \f[V]-destkeypass\f[R], -\f[V]-srcstorepass\f[R], and \f[V]-deststorepass\f[R], accept the -\f[V]env\f[R] and \f[V]file\f[R] modifiers. -Remember to separate the password option and the modifier with a colon -(:). -.PP -The password must be provided to all commands that access the keystore -contents. -For such commands, when the \f[V]-storepass\f[R] option isn\[aq]t -provided at the command line, the user is prompted for it. -.PP -When retrieving information from the keystore, the password is optional. -If a password is not specified, then the integrity of the retrieved -information can\[aq]t be verified and a warning is displayed. -.RE -.TP -\f[V]-providername\f[R] \f[I]name\f[R] -Used to identify a cryptographic service provider\[aq]s name when listed -in the security properties file. -.TP -\f[V]-addprovider\f[R] \f[I]name\f[R] -Used to add a security provider by name (such as SunPKCS11) . -.TP -\f[V]-providerclass\f[R] \f[I]class\f[R] -Used to specify the name of a cryptographic service provider\[aq]s -master class file when the service provider isn\[aq]t listed in the -security properties file. -.TP -\f[V]-providerpath\f[R] \f[I]list\f[R] -Used to specify the provider classpath. -.TP -\f[V]-providerarg\f[R] \f[I]arg\f[R] -Used with the \f[V]-addprovider\f[R] or \f[V]-providerclass\f[R] option -to represent an optional string input argument for the constructor of -\f[I]class\f[R] name. -.TP -\f[V]-protected=true\f[R]|\f[V]false\f[R] -Specify this value as \f[V]true\f[R] when a password must be specified -by way of a protected authentication path, such as a dedicated PIN -reader. -Because there are two keystores involved in the -\f[V]-importkeystore\f[R] command, the following two options, -\f[V]-srcprotected\f[R] and \f[V]-destprotected\f[R], are provided for -the source keystore and the destination keystore respectively. -.TP -\f[V]-ext\f[R] {\f[I]name\f[R]{\f[V]:critical\f[R]} {\f[V]=\f[R]\f[I]value\f[R]}} -Denotes an X.509 certificate extension. -The option can be used in \f[V]-genkeypair\f[R] and \f[V]-gencert\f[R] -to embed extensions into the generated certificate, or in -\f[V]-certreq\f[R] to show what extensions are requested in the -certificate request. -The option can appear multiple times. -The \f[I]name\f[R] argument can be a supported extension name (see -\f[B]Supported Named Extensions\f[R]) or an arbitrary OID number. -The \f[I]value\f[R] argument, when provided, denotes the argument for -the extension. -When \f[I]value\f[R] is omitted, the default value of the extension or -the extension itself requires no argument. -The \f[V]:critical\f[R] modifier, when provided, means the -extension\[aq]s \f[V]isCritical\f[R] attribute is \f[V]true\f[R]; -otherwise, it is \f[V]false\f[R]. -You can use \f[V]:c\f[R] in place of \f[V]:critical\f[R]. -.TP -\f[V]-conf\f[R] \f[I]file\f[R] -Specifies a pre-configured options file. -.SH PRE-CONFIGURED OPTIONS FILE -.PP -A pre-configured options file is a Java properties file that can be -specified with the \f[V]-conf\f[R] option. -Each property represents the default option(s) for a keytool command -using \[dq]keytool.\f[I]command_name\f[R]\[dq] as the property name. -A special property named \[dq]keytool.all\[dq] represents the default -option(s) applied to all commands. -A property value can include \f[V]${prop}\f[R] which will be expanded to -the system property associated with it. -If an option value includes white spaces inside, it should be surrounded -by quotation marks (\[dq] or \[aq]). -All property names must be in lower case. -.PP -When \f[V]keytool\f[R] is launched with a pre-configured options file, -the value for \[dq]keytool.all\[dq] (if it exists) is prepended to the -\f[V]keytool\f[R] command line first, with the value for the command -name (if it exists) comes next, and the existing options on the command -line at last. -For a single-valued option, this allows the property for a specific -command to override the \[dq]keytool.all\[dq] value, and the value -specified on the command line to override both. -For multiple-valued options, all of them will be used by -\f[V]keytool\f[R]. -.PP -For example, given the following file named \f[V]preconfig\f[R]: -.IP -.nf -\f[CB] - # A tiny pre-configured options file - keytool.all = -keystore ${user.home}/ks - keytool.list = -v - keytool.genkeypair = -keyalg rsa -\f[R] -.fi -.PP -\f[V]keytool -conf preconfig -list\f[R] is identical to -.RS -.PP -\f[V]keytool -keystore \[ti]/ks -v -list\f[R] -.RE -.PP -\f[V]keytool -conf preconfig -genkeypair -alias me\f[R] is identical to -.RS -.PP -\f[V]keytool -keystore \[ti]/ks -keyalg rsa -genkeypair -alias me\f[R] -.RE -.PP -\f[V]keytool -conf preconfig -genkeypair -alias you -keyalg ec\f[R] is -identical to -.RS -.PP -\f[V]keytool -keystore \[ti]/ks -keyalg rsa -genkeypair -alias you -keyalg ec\f[R] -.RE -.PP -which is equivalent to -.RS -.PP -\f[V]keytool -keystore \[ti]/ks -genkeypair -alias you -keyalg ec\f[R] -.RE -.PP -because \f[V]-keyalg\f[R] is a single-valued option and the \f[V]ec\f[R] -value specified on the command line overrides the preconfigured options -file. -.SH EXAMPLES OF OPTION VALUES -.PP -The following examples show the defaults for various option values: -.IP -.nf -\f[CB] --alias \[dq]mykey\[dq] - --keysize - 2048 (when using -genkeypair and -keyalg is \[dq]DSA\[dq]) - 3072 (when using -genkeypair and -keyalg is \[dq]RSA\[dq], \[dq]RSASSA-PSS\[dq], or \[dq]DH\[dq]) - 384 (when using -genkeypair and -keyalg is \[dq]EC\[dq]) - 56 (when using -genseckey and -keyalg is \[dq]DES\[dq]) - 168 (when using -genseckey and -keyalg is \[dq]DESede\[dq]) - --groupname - ed25519 (when using -genkeypair and -keyalg is \[dq]EdDSA\[dq], key size is 255) - x25519 (when using -genkeypair and -keyalg is \[dq]XDH\[dq], key size is 255) - --validity 90 - --keystore - --destkeystore - --storetype - --file - stdin (if reading) - stdout (if writing) - --protected false -\f[R] -.fi -.PP -When generating a certificate or a certificate request, the default -signature algorithm (\f[V]-sigalg\f[R] option) is derived from the -algorithm of the underlying private key to provide an appropriate level -of security strength as follows: -.PP -Default Signature Algorithms -.TS -tab(@); -l l l. -T{ -keyalg -T}@T{ -key size -T}@T{ -default sigalg -T} -_ -T{ -DSA -T}@T{ -any size -T}@T{ -SHA256withDSA -T} -T{ -RSA -T}@T{ -< 624 -T}@T{ -SHA256withRSA (key size is too small for using SHA-384) -T} -T{ -T}@T{ -<= 7680 -T}@T{ -SHA384withRSA -T} -T{ -T}@T{ -> 7680 -T}@T{ -SHA512withRSA -T} -T{ -EC -T}@T{ -< 512 -T}@T{ -SHA384withECDSA -T} -T{ -T}@T{ ->= 512 -T}@T{ -SHA512withECDSA -T} -T{ -RSASSA-PSS -T}@T{ -< 624 -T}@T{ -RSASSA-PSS (with SHA-256, key size is too small for -T} -T{ -T}@T{ -T}@T{ -using SHA-384) -T} -T{ -T}@T{ -<= 7680 -T}@T{ -RSASSA-PSS (with SHA-384) -T} -T{ -T}@T{ -> 7680 -T}@T{ -RSASSA-PSS (with SHA-512) -T} -T{ -EdDSA -T}@T{ -255 -T}@T{ -Ed25519 -T} -T{ -T}@T{ -448 -T}@T{ -Ed448 -T} -T{ -Ed25519 -T}@T{ -255 -T}@T{ -Ed25519 -T} -T{ -Ed448 -T}@T{ -448 -T}@T{ -Ed448 -T} -.TE -.IP \[bu] 2 -The key size, measured in bits, corresponds to the size of the private -key. -This size is determined by the value of the \f[V]-keysize\f[R] or -\f[V]-groupname\f[R] options or the value derived from a default -setting. -.IP \[bu] 2 -An RSASSA-PSS signature algorithm uses a \f[V]MessageDigest\f[R] -algorithm as its hash and MGF1 algorithms. -.IP \[bu] 2 -If neither a default \f[V]-keysize\f[R] or \f[V]-groupname\f[R] is -defined for an algorithm, the security provider will choose a default -setting. -.PP -\f[B]Note:\f[R] -.PP -To improve out of the box security, default keysize, groupname, and -signature algorithm names are periodically updated to stronger values -with each release of the JDK. -If interoperability with older releases of the JDK is important, make -sure that the defaults are supported by those releases. -Alternatively, you can use the \f[V]-keysize\f[R], \f[V]-groupname\f[R], -or \f[V]-sigalg\f[R] options to override the default values at your own -risk. -.SH SUPPORTED NAMED EXTENSIONS -.PP -The \f[V]keytool\f[R] command supports these named extensions. -The names aren\[aq]t case-sensitive. -.TP -\f[V]BC\f[R] or \f[V]BasicConstraints\f[R] -Values: -.RS -.PP -The full form is -\f[V]ca:\f[R]{\f[V]true\f[R]|\f[V]false\f[R]}[\f[V],pathlen:\f[R]\f[I]len\f[R]] -or \f[I]len\f[R], which is short for -\f[V]ca:true,pathlen:\f[R]\f[I]len\f[R]. -.PP -When \f[I]len\f[R] is omitted, the resulting value is \f[V]ca:true\f[R]. -.RE -.TP -\f[V]KU\f[R] or \f[V]KeyUsage\f[R] -Values: -.RS -.PP -\f[I]usage\f[R](\f[V],\f[R] \f[I]usage\f[R])* -.PP -\f[I]usage\f[R] can be one of the following: -.IP \[bu] 2 -\f[V]digitalSignature\f[R] -.IP \[bu] 2 -\f[V]nonRepudiation\f[R] (\f[V]contentCommitment\f[R]) -.IP \[bu] 2 -\f[V]keyEncipherment\f[R] -.IP \[bu] 2 -\f[V]dataEncipherment\f[R] -.IP \[bu] 2 -\f[V]keyAgreement\f[R] -.IP \[bu] 2 -\f[V]keyCertSign\f[R] -.IP \[bu] 2 -\f[V]cRLSign\f[R] -.IP \[bu] 2 -\f[V]encipherOnly\f[R] -.IP \[bu] 2 -\f[V]decipherOnly\f[R] -.PP -Provided there is no ambiguity, the \f[I]usage\f[R] argument can be -abbreviated with the first few letters (such as \f[V]dig\f[R] for -\f[V]digitalSignature\f[R]) or in camel-case style (such as \f[V]dS\f[R] -for \f[V]digitalSignature\f[R] or \f[V]cRLS\f[R] for \f[V]cRLSign\f[R]). -The \f[I]usage\f[R] values are case-sensitive. -.RE -.TP -\f[V]EKU\f[R] or \f[V]ExtendedKeyUsage\f[R] -Values: -.RS -.PP -\f[I]usage\f[R](\f[V],\f[R] \f[I]usage\f[R])* -.PP -\f[I]usage\f[R] can be one of the following: -.IP \[bu] 2 -\f[V]anyExtendedKeyUsage\f[R] -.IP \[bu] 2 -\f[V]serverAuth\f[R] -.IP \[bu] 2 -\f[V]clientAuth\f[R] -.IP \[bu] 2 -\f[V]codeSigning\f[R] -.IP \[bu] 2 -\f[V]emailProtection\f[R] -.IP \[bu] 2 -\f[V]timeStamping\f[R] -.IP \[bu] 2 -\f[V]OCSPSigning\f[R] -.IP \[bu] 2 -Any OID string -.PP -Provided there is no ambiguity, the \f[I]usage\f[R] argument can be -abbreviated with the first few letters or in camel-case style. -The \f[I]usage\f[R] values are case-sensitive. -.RE -.TP -\f[V]SAN\f[R] or \f[V]SubjectAlternativeName\f[R] -Values: -.RS -.PP -\f[I]type\f[R]\f[V]:\f[R]\f[I]value\f[R](\f[V],\f[R] -\f[I]type\f[R]\f[V]:\f[R]\f[I]value\f[R])* -.PP -\f[I]type\f[R] can be one of the following: -.IP \[bu] 2 -\f[V]EMAIL\f[R] -.IP \[bu] 2 -\f[V]URI\f[R] -.IP \[bu] 2 -\f[V]DNS\f[R] -.IP \[bu] 2 -\f[V]IP\f[R] -.IP \[bu] 2 -\f[V]OID\f[R] -.PP -The \f[I]value\f[R] argument is the string format value for the -\f[I]type\f[R]. -.RE -.TP -\f[V]IAN\f[R] or \f[V]IssuerAlternativeName\f[R] -Values: -.RS -.PP -Same as \f[V]SAN\f[R] or \f[V]SubjectAlternativeName\f[R]. -.RE -.TP -\f[V]SIA\f[R] or \f[V]SubjectInfoAccess\f[R] -Values: -.RS -.PP -\f[I]method\f[R]\f[V]:\f[R]\f[I]location-type\f[R]\f[V]:\f[R]\f[I]location-value\f[R](\f[V],\f[R] -\f[I]method\f[R]\f[V]:\f[R]\f[I]location-type\f[R]\f[V]:\f[R]\f[I]location-value\f[R])* -.PP -\f[I]method\f[R] can be one of the following: -.IP \[bu] 2 -\f[V]timeStamping\f[R] -.IP \[bu] 2 -\f[V]caRepository\f[R] -.IP \[bu] 2 -Any OID -.PP -The \f[I]location-type\f[R] and \f[I]location-value\f[R] arguments can -be any \f[I]type\f[R]\f[V]:\f[R]\f[I]value\f[R] supported by the -\f[V]SubjectAlternativeName\f[R] extension. -.RE -.TP -\f[V]AIA\f[R] or \f[V]AuthorityInfoAccess\f[R] -Values: -.RS -.PP -Same as \f[V]SIA\f[R] or \f[V]SubjectInfoAccess\f[R]. -.PP -The \f[I]method\f[R] argument can be one of the following: -.IP \[bu] 2 -\f[V]ocsp\f[R] -.IP \[bu] 2 -\f[V]caIssuers\f[R] -.IP \[bu] 2 -Any OID -.RE -.PP -When \f[I]name\f[R] is OID, the value is the hexadecimal dumped Definite -Encoding Rules (DER) encoding of the \f[V]extnValue\f[R] for the -extension excluding the OCTET STRING type and length bytes. -Other than standard hexadecimal numbers (0-9, a-f, A-F), any extra -characters are ignored in the HEX string. -Therefore, both 01:02:03:04 and 01020304 are accepted as identical -values. -When there is no value, the extension has an empty value field. -.PP -A special name \f[V]honored\f[R], used only in \f[V]-gencert\f[R], -denotes how the extensions included in the certificate request should be -honored. -The value for this name is a comma-separated list of \f[V]all\f[R] (all -requested extensions are honored), -\f[I]name\f[R]{\f[V]:\f[R][\f[V]critical\f[R]|\f[V]non-critical\f[R]]} -(the named extension is honored, but it uses a different -\f[V]isCritical\f[R] attribute), and \f[V]-name\f[R] (used with -\f[V]all\f[R], denotes an exception). -Requested extensions aren\[aq]t honored by default. -.PP -If, besides the\f[V]-ext honored\f[R] option, another named or OID -\f[V]-ext\f[R] option is provided, this extension is added to those -already honored. -However, if this name (or OID) also appears in the honored value, then -its value and criticality override that in the request. -If an extension of the same type is provided multiple times through -either a name or an OID, only the last extension is used. -.PP -The \f[V]subjectKeyIdentifier\f[R] extension is always created. -For non-self-signed certificates, the \f[V]authorityKeyIdentifier\f[R] -is created. -.PP -\f[B]CAUTION:\f[R] -.PP -Users should be aware that some combinations of extensions (and other -certificate fields) may not conform to the Internet standard. -See \f[B]Certificate Conformance Warning\f[R]. -.SH EXAMPLES OF TASKS IN CREATING A KEYSTORE -.PP -The following examples describe the sequence actions in creating a -keystore for managing public/private key pairs and certificates from -trusted entities. -.IP \[bu] 2 -\f[B]Generating the Key Pair\f[R] -.IP \[bu] 2 -\f[B]Requesting a Signed Certificate from a CA\f[R] -.IP \[bu] 2 -\f[B]Importing a Certificate for the CA\f[R] -.IP \[bu] 2 -\f[B]Importing the Certificate Reply from the CA\f[R] -.IP \[bu] 2 -\f[B]Exporting a Certificate That Authenticates the Public Key\f[R] -.IP \[bu] 2 -\f[B]Importing the Keystore\f[R] -.IP \[bu] 2 -\f[B]Generating Certificates for an SSL Server\f[R] -.SH GENERATING THE KEY PAIR -.PP -Create a keystore and then generate the key pair. -.PP -You can enter the command as a single line such as the following: -.RS -.PP -\f[V]keytool -genkeypair -dname \[dq]cn=myname, ou=mygroup, o=mycompany, c=mycountry\[dq] -alias business -keyalg rsa -keypass\f[R] -\f[I]password\f[R] -\f[V]-keystore /working/mykeystore -storepass password -validity 180\f[R] -.RE -.PP -The command creates the keystore named \f[V]mykeystore\f[R] in the -working directory (provided it doesn\[aq]t already exist), and assigns -it the password specified by \f[V]-keypass\f[R]. -It generates a public/private key pair for the entity whose -distinguished name is \f[V]myname\f[R], \f[V]mygroup\f[R], -\f[V]mycompany\f[R], and a two-letter country code of -\f[V]mycountry\f[R]. -It uses the RSA key generation algorithm to create the keys; both are -3072 bits. -.PP -The command uses the default SHA384withRSA signature algorithm to create -a self-signed certificate that includes the public key and the -distinguished name information. -The certificate is valid for 180 days, and is associated with the -private key in a keystore entry referred to by -\f[V]-alias business\f[R]. -The private key is assigned the password specified by -\f[V]-keypass\f[R]. -.PP -The command is significantly shorter when the option defaults are -accepted. -In this case, only \f[V]-keyalg\f[R] is required, and the defaults are -used for unspecified options that have default values. -You are prompted for any required values. -You could have the following: -.RS -.PP -\f[V]keytool -genkeypair -keyalg rsa\f[R] -.RE -.PP -In this case, a keystore entry with the alias \f[V]mykey\f[R] is -created, with a newly generated key pair and a certificate that is valid -for 90 days. -This entry is placed in your home directory in a keystore named -\f[V].keystore\f[R] . -\f[V].keystore\f[R] is created if it doesn\[aq]t already exist. -You are prompted for the distinguished name information, the keystore -password, and the private key password. -.PP -\f[B]Note:\f[R] -.PP -The rest of the examples assume that you responded to the prompts with -values equal to those specified in the first \f[V]-genkeypair\f[R] -command. -For example, a distinguished name of -\f[V]cn=\f[R]\f[I]myname\f[R]\f[V], ou=\f[R]\f[I]mygroup\f[R]\f[V], o=\f[R]\f[I]mycompany\f[R]\f[V], c=\f[R]\f[I]mycountry\f[R]). -.SH REQUESTING A SIGNED CERTIFICATE FROM A CA -.PP -\f[B]Note:\f[R] -.PP -Generating the key pair created a self-signed certificate; however, a -certificate is more likely to be trusted by others when it is signed by -a CA. -.PP -To get a CA signature, complete the following process: -.IP "1." 3 -Generate a CSR: -.RS 4 -.RS -.PP -\f[V]keytool -certreq -file myname.csr\f[R] -.RE -.PP -This creates a CSR for the entity identified by the default alias -\f[V]mykey\f[R] and puts the request in the file named -\f[V]myname.csr\f[R]. -.RE -.IP "2." 3 -Submit \f[V]myname.csr\f[R] to a CA, such as DigiCert. -.PP -The CA authenticates you, the requestor (usually offline), and returns a -certificate, signed by them, authenticating your public key. -In some cases, the CA returns a chain of certificates, each one -authenticating the public key of the signer of the previous certificate -in the chain. -.SH IMPORTING A CERTIFICATE FOR THE CA -.PP -To import a certificate for the CA, complete the following process: -.IP "1." 3 -Before you import the certificate reply from a CA, you need one or more -trusted certificates either in your keystore or in the \f[V]cacerts\f[R] -keystore file. -See \f[V]-importcert\f[R] in \f[B]Commands\f[R]. -.RS 4 -.IP \[bu] 2 -If the certificate reply is a certificate chain, then you need the top -certificate of the chain. -The root CA certificate that authenticates the public key of the CA. -.IP \[bu] 2 -If the certificate reply is a single certificate, then you need a -certificate for the issuing CA (the one that signed it). -If that certificate isn\[aq]t self-signed, then you need a certificate -for its signer, and so on, up to a self-signed root CA certificate. -.PP -The \f[V]cacerts\f[R] keystore ships with a set of root certificates -issued by the CAs of \f[B]the Oracle Java Root Certificate program\f[R] -[http://www.oracle.com/technetwork/java/javase/javasecarootcertsprogram-1876540.html]. -If you request a signed certificate from a CA, and a certificate -authenticating that CA\[aq]s public key hasn\[aq]t been added to -\f[V]cacerts\f[R], then you must import a certificate from that CA as a -trusted certificate. -.PP -A certificate from a CA is usually self-signed or signed by another CA. -If it is signed by another CA, you need a certificate that authenticates -that CA\[aq]s public key. -.PP -For example, you have obtained a \f[I]X\f[R]\f[V].cer\f[R] file from a -company that is a CA and the file is supposed to be a self-signed -certificate that authenticates that CA\[aq]s public key. -Before you import it as a trusted certificate, you should ensure that -the certificate is valid by: -.IP "1." 3 -Viewing it with the \f[V]keytool -printcert\f[R] command or the -\f[V]keytool -importcert\f[R] command without using the -\f[V]-noprompt\f[R] option. -Make sure that the displayed certificate fingerprints match the expected -fingerprints. -.IP "2." 3 -Calling the person who sent the certificate, and comparing the -fingerprints that you see with the ones that they show or that a secure -public key repository shows. -.PP -Only when the fingerprints are equal is it assured that the certificate -wasn\[aq]t replaced in transit with somebody else\[aq]s certificate -(such as an attacker\[aq]s certificate). -If such an attack takes place, and you didn\[aq]t check the certificate -before you imported it, then you would be trusting anything that the -attacker signed. -.RE -.IP "2." 3 -Replace the self-signed certificate with a certificate chain, where each -certificate in the chain authenticates the public key of the signer of -the previous certificate in the chain, up to a root CA. -.RS 4 -.PP -If you trust that the certificate is valid, then you can add it to your -keystore by entering the following command: -.RS -.PP -\f[V]keytool -importcert -alias\f[R] \f[I]alias\f[R] -\f[V]-file *X*\f[R].cer\[ga] -.RE -.PP -This command creates a trusted certificate entry in the keystore from -the data in the CA certificate file and assigns the values of the -\f[I]alias\f[R] to the entry. -.RE -.SH IMPORTING THE CERTIFICATE REPLY FROM THE CA -.PP -After you import a certificate that authenticates the public key of the -CA that you submitted your certificate signing request to (or there is -already such a certificate in the \f[V]cacerts\f[R] file), you can -import the certificate reply and replace your self-signed certificate -with a certificate chain. -.PP -The certificate chain is one of the following: -.IP \[bu] 2 -Returned by the CA when the CA reply is a chain. -.IP \[bu] 2 -Constructed when the CA reply is a single certificate. -This certificate chain is constructed by using the certificate reply and -trusted certificates available either in the keystore where you import -the reply or in the \f[V]cacerts\f[R] keystore file. -.PP -For example, if you sent your certificate signing request to DigiCert, -then you can import their reply by entering the following command: -.PP -\f[B]Note:\f[R] -.PP -In this example, the returned certificate is named -\f[V]DCmyname.cer\f[R]. -.RS -.PP -\f[V]keytool -importcert -trustcacerts -file DCmyname.cer\f[R] -.RE -.SH EXPORTING A CERTIFICATE THAT AUTHENTICATES THE PUBLIC KEY -.PP -\f[B]Note:\f[R] -.PP -If you used the \f[V]jarsigner\f[R] command to sign a Java Archive (JAR) -file, then clients that use the file will want to authenticate your -signature. -.PP -One way that clients can authenticate you is by importing your public -key certificate into their keystore as a trusted entry. -You can then export the certificate and supply it to your clients. -.PP -For example: -.IP "1." 3 -Copy your certificate to a file named \f[V]myname.cer\f[R] by entering -the following command: -.RS 4 -.PP -\f[B]Note:\f[R] -.PP -In this example, the entry has an alias of \f[V]mykey\f[R]. -.RS -.PP -\f[V]keytool -exportcert -alias mykey -file myname.cer\f[R] -.RE -.RE -.IP "2." 3 -With the certificate and the signed JAR file, a client can use the -\f[V]jarsigner\f[R] command to authenticate your signature. -.SH IMPORTING THE KEYSTORE -.PP -Use the \f[V]importkeystore\f[R] command to import an entire keystore -into another keystore. -This imports all entries from the source keystore, including keys and -certificates, to the destination keystore with a single command. -You can use this command to import entries from a different type of -keystore. -During the import, all new entries in the destination keystore will have -the same alias names and protection passwords (for secret keys and -private keys). -If the \f[V]keytool\f[R] command can\[aq]t recover the private keys or -secret keys from the source keystore, then it prompts you for a -password. -If it detects alias duplication, then it asks you for a new alias, and -you can specify a new alias or simply allow the \f[V]keytool\f[R] -command to overwrite the existing one. -.PP -For example, import entries from a typical JKS type keystore -\f[V]key.jks\f[R] into a PKCS #11 type hardware-based keystore, by -entering the following command: -.RS -.PP -\f[V]keytool -importkeystore -srckeystore key.jks -destkeystore NONE -srcstoretype JKS -deststoretype PKCS11 -srcstorepass\f[R] -\f[I]password\f[R] \f[V]-deststorepass\f[R] \f[I]password\f[R] -.RE -.PP -The \f[V]importkeystore\f[R] command can also be used to import a single -entry from a source keystore to a destination keystore. -In this case, besides the options you used in the previous example, you -need to specify the alias you want to import. -With the \f[V]-srcalias\f[R] option specified, you can also specify the -destination alias name, protection password for a secret or private key, -and the destination protection password you want as follows: -.RS -.PP -\f[V]keytool -importkeystore -srckeystore key.jks -destkeystore NONE -srcstoretype JKS -deststoretype PKCS11 -srcstorepass\f[R] -\f[I]password\f[R] \f[V]-deststorepass\f[R] \f[I]password\f[R] -\f[V]-srcalias myprivatekey -destalias myoldprivatekey -srckeypass\f[R] -\f[I]password\f[R] \f[V]-destkeypass\f[R] \f[I]password\f[R] -\f[V]-noprompt\f[R] -.RE -.SH GENERATING CERTIFICATES FOR AN SSL SERVER -.PP -The following are \f[V]keytool\f[R] commands used to generate key pairs -and certificates for three entities: -.IP \[bu] 2 -Root CA (\f[V]root\f[R]) -.IP \[bu] 2 -Intermediate CA (\f[V]ca\f[R]) -.IP \[bu] 2 -SSL server (\f[V]server\f[R]) -.PP -Ensure that you store all the certificates in the same keystore. -.IP -.nf -\f[CB] -keytool -genkeypair -keystore root.jks -alias root -ext bc:c -keyalg rsa -keytool -genkeypair -keystore ca.jks -alias ca -ext bc:c -keyalg rsa -keytool -genkeypair -keystore server.jks -alias server -keyalg rsa - -keytool -keystore root.jks -alias root -exportcert -rfc > root.pem - -keytool -storepass password -keystore ca.jks -certreq -alias ca | - keytool -storepass password -keystore root.jks - -gencert -alias root -ext BC=0 -rfc > ca.pem -keytool -keystore ca.jks -importcert -alias ca -file ca.pem - -keytool -storepass password -keystore server.jks -certreq -alias server | - keytool -storepass password -keystore ca.jks -gencert -alias ca - -ext ku:c=dig,kE -rfc > server.pem -cat root.pem ca.pem server.pem | - keytool -keystore server.jks -importcert -alias server -\f[R] -.fi -.SH TERMS -.TP -Keystore -A keystore is a storage facility for cryptographic keys and -certificates. -.TP -Keystore entries -Keystores can have different types of entries. -The two most applicable entry types for the \f[V]keytool\f[R] command -include the following: -.RS -.PP -Key entries: Each entry holds very sensitive cryptographic key -information, which is stored in a protected format to prevent -unauthorized access. -Typically, a key stored in this type of entry is a secret key, or a -private key accompanied by the certificate chain for the corresponding -public key. -See \f[B]Certificate Chains\f[R]. -The \f[V]keytool\f[R] command can handle both types of entries, while -the \f[V]jarsigner\f[R] tool only handles the latter type of entry, that -is private keys and their associated certificate chains. -.PP -Trusted certificate entries: Each entry contains a single public key -certificate that belongs to another party. -The entry is called a trusted certificate because the keystore owner -trusts that the public key in the certificate belongs to the identity -identified by the subject (owner) of the certificate. -The issuer of the certificate vouches for this, by signing the -certificate. -.RE -.TP -Keystore aliases -All keystore entries (key and trusted certificate entries) are accessed -by way of unique aliases. -.RS -.PP -An alias is specified when you add an entity to the keystore with the -\f[V]-genseckey\f[R] command to generate a secret key, the -\f[V]-genkeypair\f[R] command to generate a key pair (public and private -key), or the \f[V]-importcert\f[R] command to add a certificate or -certificate chain to the list of trusted certificates. -Subsequent \f[V]keytool\f[R] commands must use this same alias to refer -to the entity. -.PP -For example, you can use the alias \f[V]duke\f[R] to generate a new -public/private key pair and wrap the public key into a self-signed -certificate with the following command. -See \f[B]Certificate Chains\f[R]. -.RS -.PP -\f[V]keytool -genkeypair -alias duke -keyalg rsa -keypass\f[R] -\f[I]passwd\f[R] -.RE -.PP -This example specifies an initial \f[I]passwd\f[R] required by -subsequent commands to access the private key associated with the alias -\f[V]duke\f[R]. -If you later want to change Duke\[aq]s private key password, use a -command such as the following: -.RS -.PP -\f[V]keytool -keypasswd -alias duke -keypass\f[R] \f[I]passwd\f[R] -\f[V]-new\f[R] \f[I]newpasswd\f[R] -.RE -.PP -This changes the initial \f[I]passwd\f[R] to \f[I]newpasswd\f[R]. -A password shouldn\[aq]t be specified on a command line or in a script -unless it is for testing purposes, or you are on a secure system. -If you don\[aq]t specify a required password option on a command line, -then you are prompted for it. -.RE -.TP -Keystore implementation -The \f[V]KeyStore\f[R] class provided in the \f[V]java.security\f[R] -package supplies well-defined interfaces to access and modify the -information in a keystore. -It is possible for there to be multiple different concrete -implementations, where each implementation is that for a particular type -of keystore. -.RS -.PP -Currently, two command-line tools (\f[V]keytool\f[R] and -\f[V]jarsigner\f[R]) make use of keystore implementations. -Because the \f[V]KeyStore\f[R] class is \f[V]public\f[R], users can -write additional security applications that use it. -.PP -In JDK 9 and later, the default keystore implementation is -\f[V]PKCS12\f[R]. -This is a cross platform keystore based on the RSA PKCS12 Personal -Information Exchange Syntax Standard. -This standard is primarily meant for storing or transporting a -user\[aq]s private keys, certificates, and miscellaneous secrets. -There is another built-in implementation, provided by Oracle. -It implements the keystore as a file with a proprietary keystore type -(format) named \f[V]JKS\f[R]. -It protects each private key with its individual password, and also -protects the integrity of the entire keystore with a (possibly -different) password. -.PP -Keystore implementations are provider-based. -More specifically, the application interfaces supplied by -\f[V]KeyStore\f[R] are implemented in terms of a Service Provider -Interface (SPI). -That is, there is a corresponding abstract \f[V]KeystoreSpi\f[R] class, -also in the \f[V]java.security package\f[R], which defines the Service -Provider Interface methods that providers must implement. -The term \f[I]provider\f[R] refers to a package or a set of packages -that supply a concrete implementation of a subset of services that can -be accessed by the Java Security API. -To provide a keystore implementation, clients must implement a provider -and supply a \f[V]KeystoreSpi\f[R] subclass implementation, as described -in Steps to Implement and Integrate a Provider. -.PP -Applications can choose different types of keystore implementations from -different providers, using the \f[V]getInstance\f[R] factory method -supplied in the \f[V]KeyStore\f[R] class. -A keystore type defines the storage and data format of the keystore -information, and the algorithms used to protect private/secret keys in -the keystore and the integrity of the keystore. -Keystore implementations of different types aren\[aq]t compatible. -.PP -The \f[V]keytool\f[R] command works on any file-based keystore -implementation. -It treats the keystore location that is passed to it at the command line -as a file name and converts it to a \f[V]FileInputStream\f[R], from -which it loads the keystore information.)The \f[V]jarsigner\f[R] -commands can read a keystore from any location that can be specified -with a URL. -.PP -For \f[V]keytool\f[R] and \f[V]jarsigner\f[R], you can specify a -keystore type at the command line, with the \f[V]-storetype\f[R] option. -.PP -If you don\[aq]t explicitly specify a keystore type, then the tools -choose a keystore implementation based on the value of the -\f[V]keystore.type\f[R] property specified in the security properties -file. -The security properties file is called \f[V]java.security\f[R], and -resides in the security properties directory: -.IP \[bu] 2 -\f[B]Linux and macOS:\f[R] \f[V]java.home/lib/security\f[R] -.IP \[bu] 2 -\f[B]Windows:\f[R] \f[V]java.home\[rs]lib\[rs]security\f[R] -.PP -Each tool gets the \f[V]keystore.type\f[R] value and then examines all -the currently installed providers until it finds one that implements a -keystores of that type. -It then uses the keystore implementation from that provider.The -\f[V]KeyStore\f[R] class defines a static method named -\f[V]getDefaultType\f[R] that lets applications retrieve the value of -the \f[V]keystore.type\f[R] property. -The following line of code creates an instance of the default keystore -type as specified in the \f[V]keystore.type\f[R] property: -.RS -.PP -\f[V]KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());\f[R] -.RE -.PP -The default keystore type is \f[V]pkcs12\f[R], which is a cross-platform -keystore based on the RSA PKCS12 Personal Information Exchange Syntax -Standard. -This is specified by the following line in the security properties file: -.RS -.PP -\f[V]keystore.type=pkcs12\f[R] -.RE -.PP -To have the tools utilize a keystore implementation other than the -default, you can change that line to specify a different keystore type. -For example, if you want to use the Oracle\[aq]s \f[V]jks\f[R] keystore -implementation, then change the line to the following: -.RS -.PP -\f[V]keystore.type=jks\f[R] -.RE -.PP -\f[B]Note:\f[R] -.PP -Case doesn\[aq]t matter in keystore type designations. -For example, \f[V]JKS\f[R] would be considered the same as -\f[V]jks\f[R]. -.RE -.TP -Certificate -A certificate (or public-key certificate) is a digitally signed -statement from one entity (the issuer), saying that the public key and -some other information of another entity (the subject) has some specific -value. -The following terms are related to certificates: -.RS -.IP \[bu] 2 -Public Keys: These are numbers associated with a particular entity, and -are intended to be known to everyone who needs to have trusted -interactions with that entity. -Public keys are used to verify signatures. -.IP \[bu] 2 -Digitally Signed: If some data is digitally signed, then it is stored -with the identity of an entity and a signature that proves that entity -knows about the data. -The data is rendered unforgeable by signing with the entity\[aq]s -private key. -.IP \[bu] 2 -Identity: A known way of addressing an entity. -In some systems, the identity is the public key, and in others it can be -anything from an Oracle Solaris UID to an email address to an X.509 -distinguished name. -.IP \[bu] 2 -Signature: A signature is computed over some data using the private key -of an entity. -The signer, which in the case of a certificate is also known as the -issuer. -.IP \[bu] 2 -Private Keys: These are numbers, each of which is supposed to be known -only to the particular entity whose private key it is (that is, it is -supposed to be kept secret). -Private and public keys exist in pairs in all public key cryptography -systems (also referred to as public key crypto systems). -In a typical public key crypto system, such as DSA, a private key -corresponds to exactly one public key. -Private keys are used to compute signatures. -.IP \[bu] 2 -Entity: An entity is a person, organization, program, computer, -business, bank, or something else you are trusting to some degree. -.PP -Public key cryptography requires access to users\[aq] public keys. -In a large-scale networked environment, it is impossible to guarantee -that prior relationships between communicating entities were established -or that a trusted repository exists with all used public keys. -Certificates were invented as a solution to this public key distribution -problem. -Now a Certification Authority (CA) can act as a trusted third party. -CAs are entities such as businesses that are trusted to sign (issue) -certificates for other entities. -It is assumed that CAs only create valid and reliable certificates -because they are bound by legal agreements. -There are many public Certification Authorities, such as DigiCert, -Comodo, Entrust, and so on. -.PP -You can also run your own Certification Authority using products such as -Microsoft Certificate Server or the Entrust CA product for your -organization. -With the \f[V]keytool\f[R] command, it is possible to display, import, -and export certificates. -It is also possible to generate self-signed certificates. -.PP -The \f[V]keytool\f[R] command currently handles X.509 certificates. -.RE -.TP -X.509 Certificates -The X.509 standard defines what information can go into a certificate -and describes how to write it down (the data format). -All the data in a certificate is encoded with two related standards -called ASN.1/DER. -Abstract Syntax Notation 1 describes data. -The Definite Encoding Rules describe a single way to store and transfer -that data. -.RS -.PP -All X.509 certificates have the following data, in addition to the -signature: -.IP \[bu] 2 -Version: This identifies which version of the X.509 standard applies to -this certificate, which affects what information can be specified in it. -Thus far, three versions are defined. -The \f[V]keytool\f[R] command can import and export v1, v2, and v3 -certificates. -It generates v3 certificates. -.RS 2 -.IP \[bu] 2 -X.509 Version 1 has been available since 1988, is widely deployed, and -is the most generic. -.IP \[bu] 2 -X.509 Version 2 introduced the concept of subject and issuer unique -identifiers to handle the possibility of reuse of subject or issuer -names over time. -Most certificate profile documents strongly recommend that names not be -reused and that certificates shouldn\[aq]t make use of unique -identifiers. -Version 2 certificates aren\[aq]t widely used. -.IP \[bu] 2 -X.509 Version 3 is the most recent (1996) and supports the notion of -extensions where anyone can define an extension and include it in the -certificate. -Some common extensions are: KeyUsage (limits the use of the keys to -particular purposes such as \f[V]signing-only\f[R]) and AlternativeNames -(allows other identities to also be associated with this public key, for -example. -DNS names, email addresses, IP addresses). -Extensions can be marked critical to indicate that the extension should -be checked and enforced or used. -For example, if a certificate has the KeyUsage extension marked critical -and set to \f[V]keyCertSign\f[R], then when this certificate is -presented during SSL communication, it should be rejected because the -certificate extension indicates that the associated private key should -only be used for signing certificates and not for SSL use. -.RE -.IP \[bu] 2 -Serial number: The entity that created the certificate is responsible -for assigning it a serial number to distinguish it from other -certificates it issues. -This information is used in numerous ways. -For example, when a certificate is revoked its serial number is placed -in a Certificate Revocation List (CRL). -.IP \[bu] 2 -Signature algorithm identifier: This identifies the algorithm used by -the CA to sign the certificate. -.IP \[bu] 2 -Issuer name: The X.500 Distinguished Name of the entity that signed the -certificate. -This is typically a CA. -Using this certificate implies trusting the entity that signed this -certificate. -In some cases, such as root or top-level CA certificates, the issuer -signs its own certificate. -.IP \[bu] 2 -Validity period: Each certificate is valid only for a limited amount of -time. -This period is described by a start date and time and an end date and -time, and can be as short as a few seconds or almost as long as a -century. -The validity period chosen depends on a number of factors, such as the -strength of the private key used to sign the certificate, or the amount -one is willing to pay for a certificate. -This is the expected period that entities can rely on the public value, -when the associated private key has not been compromised. -.IP \[bu] 2 -Subject name: The name of the entity whose public key the certificate -identifies. -This name uses the X.500 standard, so it is intended to be unique across -the Internet. -This is the X.500 Distinguished Name (DN) of the entity. -For example, -.RS 2 -.RS -.PP -\f[V]CN=Java Duke, OU=Java Software Division, O=Oracle Corporation, C=US\f[R] -.RE -.PP -These refer to the subject\[aq]s common name (CN), organizational unit -(OU), organization (O), and country (C). -.RE -.IP \[bu] 2 -Subject public key information: This is the public key of the entity -being named with an algorithm identifier that specifies which public key -crypto system this key belongs to and any associated key parameters. -.RE -.TP -Certificate Chains -The \f[V]keytool\f[R] command can create and manage keystore key entries -that each contain a private key and an associated certificate chain. -The first certificate in the chain contains the public key that -corresponds to the private key. -.RS -.PP -When keys are first generated, the chain usually starts off containing a -single element, a self-signed certificate. -See -genkeypair in \f[B]Commands\f[R]. -A self-signed certificate is one for which the issuer (signer) is the -same as the subject. -The subject is the entity whose public key is being authenticated by the -certificate. -When the \f[V]-genkeypair\f[R] command is called to generate a new -public/private key pair, it also wraps the public key into a self-signed -certificate (unless the \f[V]-signer\f[R] option is specified). -.PP -Later, after a Certificate Signing Request (CSR) was generated with the -\f[V]-certreq\f[R] command and sent to a Certification Authority (CA), -the response from the CA is imported with \f[V]-importcert\f[R], and the -self-signed certificate is replaced by a chain of certificates. -At the bottom of the chain is the certificate (reply) issued by the CA -authenticating the subject\[aq]s public key. -The next certificate in the chain is one that authenticates the CA\[aq]s -public key. -.PP -In many cases, this is a self-signed certificate, which is a certificate -from the CA authenticating its own public key, and the last certificate -in the chain. -In other cases, the CA might return a chain of certificates. -In this case, the bottom certificate in the chain is the same (a -certificate signed by the CA, authenticating the public key of the key -entry), but the second certificate in the chain is a certificate signed -by a different CA that authenticates the public key of the CA you sent -the CSR to. -The next certificate in the chain is a certificate that authenticates -the second CA\[aq]s key, and so on, until a self-signed root certificate -is reached. -Each certificate in the chain (after the first) authenticates the public -key of the signer of the previous certificate in the chain. -.PP -Many CAs only return the issued certificate, with no supporting chain, -especially when there is a flat hierarchy (no intermediates CAs). -In this case, the certificate chain must be established from trusted -certificate information already stored in the keystore. -.PP -A different reply format (defined by the PKCS #7 standard) includes the -supporting certificate chain in addition to the issued certificate. -Both reply formats can be handled by the \f[V]keytool\f[R] command. -.PP -The top-level (root) CA certificate is self-signed. -However, the trust into the root\[aq]s public key doesn\[aq]t come from -the root certificate itself, but from other sources such as a newspaper. -This is because anybody could generate a self-signed certificate with -the distinguished name of, for example, the DigiCert root CA. -The root CA public key is widely known. -The only reason it is stored in a certificate is because this is the -format understood by most tools, so the certificate in this case is only -used as a vehicle to transport the root CA\[aq]s public key. -Before you add the root CA certificate to your keystore, you should view -it with the \f[V]-printcert\f[R] option and compare the displayed -fingerprint with the well-known fingerprint obtained from a newspaper, -the root CA\[aq]s Web page, and so on. -.RE -.TP -cacerts Certificates File -A certificates file named \f[V]cacerts\f[R] resides in the security -properties directory: -.RS -.IP \[bu] 2 -\f[B]Linux and macOS:\f[R] \f[I]JAVA_HOME\f[R]\f[V]/lib/security\f[R] -.IP \[bu] 2 -\f[B]Windows:\f[R] \f[I]JAVA_HOME\f[R]\f[V]\[rs]lib\[rs]security\f[R] -.PP -The \f[V]cacerts\f[R] file represents a system-wide keystore with CA -certificates. -System administrators can configure and manage that file with the -\f[V]keytool\f[R] command by specifying \f[V]jks\f[R] as the keystore -type. -The \f[V]cacerts\f[R] keystore file ships with a default set of root CA -certificates. -For Linux, macOS, and Windows, you can list the default certificates -with the following command: -.RS -.PP -\f[V]keytool -list -cacerts\f[R] -.RE -.PP -The initial password of the \f[V]cacerts\f[R] keystore file is -\f[V]changeit\f[R]. -System administrators should change that password and the default access -permission of that file upon installing the SDK. -.PP -\f[B]Note:\f[R] -.PP -It is important to verify your \f[V]cacerts\f[R] file. -Because you trust the CAs in the \f[V]cacerts\f[R] file as entities for -signing and issuing certificates to other entities, you must manage the -\f[V]cacerts\f[R] file carefully. -The \f[V]cacerts\f[R] file should contain only certificates of the CAs -you trust. -It is your responsibility to verify the trusted root CA certificates -bundled in the \f[V]cacerts\f[R] file and make your own trust decisions. -.PP -To remove an untrusted CA certificate from the \f[V]cacerts\f[R] file, -use the \f[V]-delete\f[R] option of the \f[V]keytool\f[R] command. -You can find the \f[V]cacerts\f[R] file in the JDK\[aq]s -\f[V]$JAVA_HOME/lib/security\f[R] directory. -Contact your system administrator if you don\[aq]t have permission to -edit this file. -.RE -.TP -Internet RFC 1421 Certificate Encoding Standard -Certificates are often stored using the printable encoding format -defined by the Internet RFC 1421 standard, instead of their binary -encoding. -This certificate format, also known as Base64 encoding, makes it easy to -export certificates to other applications by email or through some other -mechanism. -.RS -.PP -Certificates read by the \f[V]-importcert\f[R] and \f[V]-printcert\f[R] -commands can be in either this format or binary encoded. -The \f[V]-exportcert\f[R] command by default outputs a certificate in -binary encoding, but will instead output a certificate in the printable -encoding format, when the \f[V]-rfc\f[R] option is specified. -.PP -The \f[V]-list\f[R] command by default prints the SHA-256 fingerprint of -a certificate. -If the \f[V]-v\f[R] option is specified, then the certificate is printed -in human-readable format. -If the \f[V]-rfc\f[R] option is specified, then the certificate is -output in the printable encoding format. -.PP -In its printable encoding format, the encoded certificate is bounded at -the beginning and end by the following text: -.IP -.nf -\f[CB] ------BEGIN CERTIFICATE----- - -encoded certificate goes here. - ------END CERTIFICATE----- -\f[R] -.fi -.RE -.TP -X.500 Distinguished Names -X.500 Distinguished Names are used to identify entities, such as those -that are named by the \f[V]subject\f[R] and \f[V]issuer\f[R] (signer) -fields of X.509 certificates. -The \f[V]keytool\f[R] command supports the following subparts: -.RS -.IP \[bu] 2 -commonName: The common name of a person such as Susan Jones. -.IP \[bu] 2 -organizationUnit: The small organization (such as department or -division) name. -For example, Purchasing. -.IP \[bu] 2 -localityName: The locality (city) name, for example, Palo Alto. -.IP \[bu] 2 -stateName: State or province name, for example, California. -.IP \[bu] 2 -country: Two-letter country code, for example, CH. -.PP -When you supply a distinguished name string as the value of a -\f[V]-dname\f[R] option, such as for the \f[V]-genkeypair\f[R] command, -the string must be in the following format: -.RS -.PP -\f[V]CN=cName, OU=orgUnit, O=org, L=city, S=state, C=countryCode\f[R] -.RE -.PP -All the following items represent actual values and the previous -keywords are abbreviations for the following: -.IP -.nf -\f[CB] -CN=commonName -OU=organizationUnit -O=organizationName -L=localityName -S=stateName -C=country -\f[R] -.fi -.PP -A sample distinguished name string is: -.RS -.PP -\f[V]CN=Mark Smith, OU=Java, O=Oracle, L=Cupertino, S=California, C=US\f[R] -.RE -.PP -A sample command using such a string is: -.RS -.PP -\f[V]keytool -genkeypair -dname \[dq]CN=Mark Smith, OU=Java, O=Oracle, L=Cupertino, S=California, C=US\[dq] -alias mark -keyalg rsa\f[R] -.RE -.PP -Case doesn\[aq]t matter for the keyword abbreviations. -For example, CN, cn, and Cn are all treated the same. -.PP -Order matters; each subcomponent must appear in the designated order. -However, it isn\[aq]t necessary to have all the subcomponents. -You can use a subset, for example: -.RS -.PP -\f[V]CN=Smith, OU=Java, O=Oracle, C=US\f[R] -.RE -.PP -If a distinguished name string value contains a comma, then the comma -must be escaped by a backslash (\[rs]) character when you specify the -string on a command line, as in: -.RS -.PP -\f[V]cn=Jack, ou=Java\[rs], Product Development, o=Oracle, c=US\f[R] -.RE -.PP -It is never necessary to specify a distinguished name string on a -command line. -When the distinguished name is needed for a command, but not supplied on -the command line, the user is prompted for each of the subcomponents. -In this case, a comma doesn\[aq]t need to be escaped by a backslash -(\[rs]). -.RE -.SH WARNINGS -.SH IMPORTING TRUSTED CERTIFICATES WARNING -.PP -\f[B]Important\f[R]: Be sure to check a certificate very carefully -before importing it as a trusted certificate. -.PP -\f[B]Windows Example:\f[R] -.PP -View the certificate first with the \f[V]-printcert\f[R] command or the -\f[V]-importcert\f[R] command without the \f[V]-noprompt\f[R] option. -Ensure that the displayed certificate fingerprints match the expected -ones. -For example, suppose someone sends or emails you a certificate that you -put it in a file named \f[V]\[rs]tmp\[rs]cert\f[R]. -Before you consider adding the certificate to your list of trusted -certificates, you can execute a \f[V]-printcert\f[R] command to view its -fingerprints, as follows: -.IP -.nf -\f[CB] - keytool -printcert -file \[rs]tmp\[rs]cert - Owner: CN=ll, OU=ll, O=ll, L=ll, S=ll, C=ll - Issuer: CN=ll, OU=ll, O=ll, L=ll, S=ll, C=ll - Serial Number: 59092b34 - Valid from: Thu Jun 24 18:01:13 PDT 2016 until: Wed Jun 23 17:01:13 PST 2016 - Certificate Fingerprints: - - SHA-1: 20:B6:17:FA:EF:E5:55:8A:D0:71:1F:E8:D6:9D:C0:37:13:0E:5E:FE - SHA-256: 90:7B:70:0A:EA:DC:16:79:92:99:41:FF:8A:FE:EB:90: - 17:75:E0:90:B2:24:4D:3A:2A:16:A6:E4:11:0F:67:A4 -\f[R] -.fi -.PP -\f[B]Linux Example:\f[R] -.PP -View the certificate first with the \f[V]-printcert\f[R] command or the -\f[V]-importcert\f[R] command without the \f[V]-noprompt\f[R] option. -Ensure that the displayed certificate fingerprints match the expected -ones. -For example, suppose someone sends or emails you a certificate that you -put it in a file named \f[V]/tmp/cert\f[R]. -Before you consider adding the certificate to your list of trusted -certificates, you can execute a \f[V]-printcert\f[R] command to view its -fingerprints, as follows: -.IP -.nf -\f[CB] - keytool -printcert -file /tmp/cert - Owner: CN=ll, OU=ll, O=ll, L=ll, S=ll, C=ll - Issuer: CN=ll, OU=ll, O=ll, L=ll, S=ll, C=ll - Serial Number: 59092b34 - Valid from: Thu Jun 24 18:01:13 PDT 2016 until: Wed Jun 23 17:01:13 PST 2016 - Certificate Fingerprints: - - SHA-1: 20:B6:17:FA:EF:E5:55:8A:D0:71:1F:E8:D6:9D:C0:37:13:0E:5E:FE - SHA-256: 90:7B:70:0A:EA:DC:16:79:92:99:41:FF:8A:FE:EB:90: - 17:75:E0:90:B2:24:4D:3A:2A:16:A6:E4:11:0F:67:A4 -\f[R] -.fi -.PP -Then call or otherwise contact the person who sent the certificate and -compare the fingerprints that you see with the ones that they show. -Only when the fingerprints are equal is it guaranteed that the -certificate wasn\[aq]t replaced in transit with somebody else\[aq]s -certificate such as an attacker\[aq]s certificate. -If such an attack took place, and you didn\[aq]t check the certificate -before you imported it, then you would be trusting anything the attacker -signed, for example, a JAR file with malicious class files inside. -.PP -\f[B]Note:\f[R] -.PP -It isn\[aq]t required that you execute a \f[V]-printcert\f[R] command -before importing a certificate. -This is because before you add a certificate to the list of trusted -certificates in the keystore, the \f[V]-importcert\f[R] command prints -out the certificate information and prompts you to verify it. -You can then stop the import operation. -However, you can do this only when you call the \f[V]-importcert\f[R] -command without the \f[V]-noprompt\f[R] option. -If the \f[V]-noprompt\f[R] option is specified, then there is no -interaction with the user. -.SH PASSWORDS WARNING -.PP -Most commands that operate on a keystore require the store password. -Some commands require a private/secret key password. -Passwords can be specified on the command line in the -\f[V]-storepass\f[R] and \f[V]-keypass\f[R] options. -However, a password shouldn\[aq]t be specified on a command line or in a -script unless it is for testing, or you are on a secure system. -When you don\[aq]t specify a required password option on a command line, -you are prompted for it. -.SH CERTIFICATE CONFORMANCE WARNING -.PP -\f[B]Internet X.509 Public Key Infrastructure Certificate and -Certificate Revocation List (CRL) Profile\f[R] -[https://tools.ietf.org/rfc/rfc5280.txt] defined a profile on conforming -X.509 certificates, which includes what values and value combinations -are valid for certificate fields and extensions. -.PP -The \f[V]keytool\f[R] command doesn\[aq]t enforce all of these rules so -it can generate certificates that don\[aq]t conform to the standard, -such as self-signed certificates that would be used for internal testing -purposes. -Certificates that don\[aq]t conform to the standard might be rejected by -the JDK or other applications. -Users should ensure that they provide the correct options for -\f[V]-dname\f[R], \f[V]-ext\f[R], and so on. -.SH IMPORT A NEW TRUSTED CERTIFICATE -.PP -Before you add the certificate to the keystore, the \f[V]keytool\f[R] -command verifies it by attempting to construct a chain of trust from -that certificate to a self-signed certificate (belonging to a root CA), -using trusted certificates that are already available in the keystore. -.PP -If the \f[V]-trustcacerts\f[R] option was specified, then additional -certificates are considered for the chain of trust, namely the -certificates in a file named \f[V]cacerts\f[R]. -.PP -If the \f[V]keytool\f[R] command fails to establish a trust path from -the certificate to be imported up to a self-signed certificate (either -from the keystore or the \f[V]cacerts\f[R] file), then the certificate -information is printed, and the user is prompted to verify it by -comparing the displayed certificate fingerprints with the fingerprints -obtained from some other (trusted) source of information, which might be -the certificate owner. -Be very careful to ensure the certificate is valid before importing it -as a trusted certificate. -The user then has the option of stopping the import operation. -If the \f[V]-noprompt\f[R] option is specified, then there is no -interaction with the user. -.SH IMPORT A CERTIFICATE REPLY -.PP -When you import a certificate reply, the certificate reply is validated -with trusted certificates from the keystore, and optionally, the -certificates configured in the \f[V]cacerts\f[R] keystore file when the -\f[V]-trustcacerts\f[R] option is specified. -.PP -The methods of determining whether the certificate reply is trusted are -as follows: -.IP \[bu] 2 -If the reply is a single X.509 certificate, then the \f[V]keytool\f[R] -command attempts to establish a trust chain, starting at the certificate -reply and ending at a self-signed certificate (belonging to a root CA). -The certificate reply and the hierarchy of certificates is used to -authenticate the certificate reply from the new certificate chain of -aliases. -If a trust chain can\[aq]t be established, then the certificate reply -isn\[aq]t imported. -In this case, the \f[V]keytool\f[R] command doesn\[aq]t print the -certificate and prompt the user to verify it, because it is very -difficult for a user to determine the authenticity of the certificate -reply. -.IP \[bu] 2 -If the reply is a PKCS #7 formatted certificate chain or a sequence of -X.509 certificates, then the chain is ordered with the user certificate -first followed by zero or more CA certificates. -If the chain ends with a self-signed root CA certificate and -the\f[V]-trustcacerts\f[R] option was specified, the \f[V]keytool\f[R] -command attempts to match it with any of the trusted certificates in the -keystore or the \f[V]cacerts\f[R] keystore file. -If the chain doesn\[aq]t end with a self-signed root CA certificate and -the \f[V]-trustcacerts\f[R] option was specified, the \f[V]keytool\f[R] -command tries to find one from the trusted certificates in the keystore -or the \f[V]cacerts\f[R] keystore file and add it to the end of the -chain. -If the certificate isn\[aq]t found and the \f[V]-noprompt\f[R] option -isn\[aq]t specified, the information of the last certificate in the -chain is printed, and the user is prompted to verify it. -.PP -If the public key in the certificate reply matches the user\[aq]s public -key already stored with \f[V]alias\f[R], then the old certificate chain -is replaced with the new certificate chain in the reply. -The old chain can only be replaced with a valid \f[V]keypass\f[R], and -so the password used to protect the private key of the entry is -supplied. -If no password is provided, and the private key password is different -from the keystore password, the user is prompted for it. -.PP -This command was named \f[V]-import\f[R] in earlier releases. -This old name is still supported in this release. -The new name, \f[V]-importcert\f[R], is preferred. diff --git a/src/java.base/share/man/keytool.md b/src/java.base/share/man/keytool.md new file mode 100644 index 00000000000..22b2877a3e7 --- /dev/null +++ b/src/java.base/share/man/keytool.md @@ -0,0 +1,2430 @@ +--- +# Copyright (c) 1998, 2024, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# This code is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 only, as +# published by the Free Software Foundation. +# +# This code is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# version 2 for more details (a copy is included in the LICENSE file that +# accompanied this code). +# +# You should have received a copy of the GNU General Public License version +# 2 along with this work; if not, write to the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +# or visit www.oracle.com if you need additional information or have any +# questions. +# + +title: 'KEYTOOL(1) JDK @@VERSION_SHORT@@ | JDK Commands' +date: @@COPYRIGHT_YEAR@@ +lang: en +--- + +## Name + +keytool - a key and certificate management utility + +## Synopsis + +`keytool` \[*commands*\] + +*commands* +: Commands for `keytool` include the following: + + - `-certreq`: Generates a certificate request + + - `-changealias`: Changes an entry's alias + + - `-delete`: Deletes an entry + + - `-exportcert`: Exports certificate + + - `-genkeypair`: Generates a key pair + + - `-genseckey`: Generates a secret key + + - `-gencert`: Generates a certificate from a certificate request + + - `-importcert`: Imports a certificate or a certificate chain + + - `-importpass`: Imports a password + + - `-importkeystore`: Imports one or all entries from another keystore + + - `-keypasswd`: Changes the key password of an entry + + - `-list`: Lists entries in a keystore + + - `-printcert`: Prints the content of a certificate + + - `-printcertreq`: Prints the content of a certificate request + + - `-printcrl`: Prints the content of a Certificate Revocation List (CRL) + file + + - `-storepasswd`: Changes the store password of a keystore + + - `-showinfo`: Displays security-related information + + - `-version`: Prints the program version + + See [Commands and Options] for a description of these commands with their + options. + +## Description + +The `keytool` command is a key and certificate management utility. It enables +users to administer their own public/private key pairs and associated +certificates for use in self-authentication (where a user authenticates +themselves to other users and services) or data integrity and authentication +services, by using digital signatures. The `keytool` command also enables users +to cache the public keys (in the form of certificates) of their communicating +peers. + +A certificate is a digitally signed statement from one entity (person, company, +and so on), which says that the public key (and some other information) of some +other entity has a particular value. When data is digitally signed, the +signature can be verified to check the data integrity and authenticity. +Integrity means that the data hasn't been modified or tampered with, and +authenticity means that the data comes from the individual who claims to have +created and signed it. + +The `keytool` command also enables users to administer secret keys and +passphrases used in symmetric encryption and decryption (Data Encryption +Standard). It can also display other security-related information. + +The `keytool` command stores the keys and certificates in a keystore. + +The `keytool` command uses the `jdk.certpath.disabledAlgorithms` and +`jdk.security.legacyAlgorithms` security properties to determine which +algorithms are considered a security risk. It emits warnings when +disabled or legacy algorithms are being used. +The `jdk.certpath.disabledAlgorithms` and `jdk.security.legacyAlgorithms` +security properties are defined in the `java.security` file (located in +the JDK's `$JAVA_HOME/conf/security` directory). + +## Command and Option Notes + +The following notes apply to the descriptions in [Commands and Options]\: + +- All command and option names are preceded by a hyphen sign (`-`). + +- Only one command can be provided. + +- Options for each command can be provided in any order. + +- There are two kinds of options, one is single-valued which should be + only provided once. If a single-valued option is provided multiple times, + the value of the last one is used. The other type is multi-valued, + which can be provided multiple times and all values are used. + The only multi-valued option currently supported is the `-ext` option used + to generate X.509v3 certificate extensions. + +- All items not italicized or in braces ({ }) or brackets (\[ \]) are + required to appear as is. + +- Braces surrounding an option signify that a default value is used when the + option isn't specified on the command line. Braces are also used around the + `-v`, `-rfc`, and `-J` options, which have meaning only when they appear on + the command line. They don't have any default values. + +- Brackets surrounding an option signify that the user is prompted for the + values when the option isn't specified on the command line. For the + `-keypass` option, if you don't specify the option on the command line, + then the `keytool` command first attempts to use the keystore password to + recover the private/secret key. If this attempt fails, then the `keytool` + command prompts you for the private/secret key password. + +- Items in italics (option values) represent the actual values that must be + supplied. For example, here is the format of the `-printcert` command: + + > `keytool -printcert` {`-file` *cert\_file*} {`-v`} + + When you specify a `-printcert` command, replace *cert\_file* with the + actual file name, as follows: `keytool -printcert -file VScert.cer` + +- Option values must be enclosed in quotation marks when they contain a blank + (space). + +## Commands and Options + +The keytool commands and their options can be grouped by the tasks that they +perform. + +[Commands for Creating or Adding Data to the Keystore]\: + +- `-gencert` + +- `-genkeypair` + +- `-genseckey` + +- `-importcert` + +- `-importpass` + +[Commands for Importing Contents from Another Keystore]\: + +- `-importkeystore` + +[Commands for Generating a Certificate Request]\: + +- `-certreq` + +[Commands for Exporting Data]\: + +- `-exportcert` + +[Commands for Displaying Data]\: + +- `-list` + +- `-printcert` + +- `-printcertreq` + +- `-printcrl` + +[Commands for Managing the Keystore]\: + +- `-storepasswd` + +- `-keypasswd` + +- `-delete` + +- `-changealias` + +[Commands for Displaying Security-related Information]\: + +- `-showinfo` + +[Commands for Displaying Program Version]\: + +- `-version` + +## Commands for Creating or Adding Data to the Keystore + +`-gencert` +: The following are the available options for the `-gencert` command: + + - {`-rfc`}: Output in RFC (Request For Comment) style + + - {`-infile` *infile*}: Input file name + + - {`-outfile` *outfile*}: Output file name + + - {`-alias` *alias*}: Alias name of the entry to process + + - {`-sigalg` *sigalg*}: Signature algorithm name + + - {`-dname` *dname*}: Distinguished name + + - {`-startdate` *startdate*}: Certificate validity start date and time + + - {`-ext` *ext*}\*: X.509 extension + + - {`-validity` *days*}: Validity number of days + + - \[`-keypass` *arg*\]: Key password + + - {`-keystore` *keystore*}: Keystore name + + - \[`-storepass` *arg*\]: Keystore password + + - {`-storetype` *type*}: Keystore type + + - {`-providername` *name*}: Provider name + + - {`-addprovider` *name* \[`-providerarg` *arg*\]}: Adds a security + provider by name (such as SunPKCS11) with an optional configure + argument. The value of the security provider is the name of a security + provider that is defined in a module. + + For example, + + > `keytool -addprovider SunPKCS11 -providerarg some.cfg ...` + + **Note:** + + For compatibility reasons, the SunPKCS11 provider can still be loaded + with `-providerclass sun.security.pkcs11.SunPKCS11` even if it is now + defined in a module. This is the only module included in the JDK that + needs a configuration, and therefore the most widely used with the + `-providerclass` option. For legacy security providers located on + classpath and loaded by reflection, `-providerclass` should still be + used. + + - {`-providerclass` *class* \[`-providerarg` *arg*\]}: Add security + provider by fully qualified class name with an optional configure + argument. + + For example, if `MyProvider` is a legacy provider loaded via + reflection, + + > `keytool -providerclass com.example.MyProvider ...` + + - {`-providerpath` *list*}: Provider classpath + + - {`-v`}: Verbose output + + - {`-protected`}: Password provided through a protected mechanism + + Use the `-gencert` command to generate a certificate as a response to a + certificate request file (which can be created by the `keytool -certreq` + command). The command reads the request either from *infile* or, if + omitted, from the standard input, signs it by using the alias's private + key, and outputs the X.509 certificate into either *outfile* or, if + omitted, to the standard output. When `-rfc` is specified, the output + format is Base64-encoded PEM; otherwise, a binary DER is created. + + The `-sigalg` value specifies the algorithm that should be used to sign the + certificate. The *startdate* argument is the start time and date that the + certificate is valid. The *days* argument tells the number of days for + which the certificate should be considered valid. + + When *dname* is provided, it is used as the subject of the generated + certificate. Otherwise, the one from the certificate request is used. + + The `-ext` value shows what X.509 extensions will be embedded in the + certificate. Read [Common Command Options] for the grammar of `-ext`. + + The `-gencert` option enables you to create certificate chains. The + following example creates a certificate, `e1`, that contains three + certificates in its certificate chain. + + The following commands creates four key pairs named `ca`, `ca1`, `ca2`, and + `e1`: + + ``` + keytool -alias ca -dname CN=CA -genkeypair -keyalg rsa + keytool -alias ca1 -dname CN=CA -genkeypair -keyalg rsa + keytool -alias ca2 -dname CN=CA -genkeypair -keyalg rsa + keytool -alias e1 -dname CN=E1 -genkeypair -keyalg rsa + ``` + + The following two commands create a chain of signed certificates; `ca` + signs `ca1` and `ca1` signs `ca2`, all of which are self-issued: + + ``` + keytool -alias ca1 -certreq | + keytool -alias ca -gencert -ext san=dns:ca1 | + keytool -alias ca1 -importcert + + keytool -alias ca2 -certreq | + keytool -alias ca1 -gencert -ext san=dns:ca2 | + keytool -alias ca2 -importcert + ``` + + The following command creates the certificate `e1` and stores it in the + `e1.cert` file, which is signed by `ca2`. As a result, `e1` should contain + `ca`, `ca1`, and `ca2` in its certificate chain: + + > `keytool -alias e1 -certreq | keytool -alias ca2 -gencert > e1.cert` + +`-genkeypair` +: The following are the available options for the `-genkeypair` command: + + - {`-alias` *alias*}: Alias name of the entry to process + + - `-keyalg` *alg*: Key algorithm name + + - {`-keysize` *size*}: Key bit size + + - {`-groupname` *name*}: Group name. For example, an Elliptic Curve name. + + - {`-sigalg` *alg*}: Signature algorithm name + + - {`-signer` *alias*}: Signer alias + + - \[`-signerkeypass` *arg*\]: Signer key password + + - \[`-dname` *name*\]: Distinguished name + + - {`-startdate` *date*}: Certificate validity start date and time + + - {`-ext` *value*}\*: X.509 extension + + - {`-validity` *days*}: Validity number of days + + - \[`-keypass` *arg*\]: Key password + + - {`-keystore` *keystore*}: Keystore name + + - \[`-storepass` *arg*\]: Keystore password + + - {`-storetype` *type*}: Keystore type + + - {`-providername` *name*}: Provider name + + - {`-addprovider` *name* \[`-providerarg` *arg*\]}: Add security provider + by name (such as SunPKCS11) with an optional configure argument. + + - {`-providerclass` *class* \[`-providerarg` *arg*\] }: Add security + provider by fully qualified class name with an optional configure + argument. + + - {`-providerpath` *list*}: Provider classpath + + - {`-v`}: Verbose output + + - {`-protected`}: Password provided through a protected mechanism + + Use the `-genkeypair` command to generate a key pair (a public key and + associated private key). When the `-signer` option is not specified, + the public key is wrapped in an X.509 v3 self-signed certificate and + stored as a single-element certificate chain. When the `-signer` + option is specified, a new certificate is generated and signed by + the designated signer and stored as a multiple-element certificate + chain (containing the generated certificate itself, and the signer's + certificate chain). The certificate chain and private key are stored + in a new keystore entry that is identified by its alias. + + The `-keyalg` value specifies the algorithm to be used to generate the key + pair. The `-keysize` value specifies the size of each key to be generated. + The `-groupname` value specifies the named group (for example, the standard + or predefined name of an Elliptic Curve) of the key to be generated. + + When a `-keysize` value is provided, it will be used to initialize a + `KeyPairGenerator` object using the `initialize(int keysize)` + method. When a `-groupname` value is provided, it will be used to + initialize a `KeyPairGenerator` object using the + `initialize(AlgorithmParameterSpec params)` method where `params` + is `new NamedParameterSpec(groupname)`. + + Only one of `-groupname` and `-keysize` can be specified. If an algorithm + has multiple named groups that have the same key size, the `-groupname` + option should usually be used. In this case, if `-keysize` is specified, + it's up to the security provider to determine which named group is chosen + when generating a key pair. + + The `-sigalg` value specifies the algorithm that should be used + to sign the certificate. This algorithm must be compatible with + the `-keyalg` value. + + The `-signer` value specifies the alias of a `PrivateKeyEntry` for the + signer that already exists in the keystore. This option is used to + sign the certificate with the signer's private key. This is especially + useful for key agreement algorithms (i.e. the `-keyalg` value is `XDH`, + `X25519`, `X448`, or `DH`) as these keys cannot be used for digital + signatures, and therefore a self-signed certificate cannot be created. + + The `-signerkeypass` value specifies the password of the signer's private + key. It can be specified if the private key of the signer entry is + protected by a password different from the store password. + + The `-dname` value specifies the X.500 Distinguished Name to be associated + with the value of `-alias`. If the `-signer` option is not specified, the + issuer and subject fields of the self-signed certificate are populated + with the specified distinguished name. If the `-signer` option is + specified, the subject field of the certificate is populated with the + specified distinguished name and the issuer field is populated with the + subject field of the signer's certificate. If a distinguished name is not + provided at the command line, then the user is prompted for one. + + The value of `-keypass` is a password used to protect the private key of + the generated key pair. If a password is not provided, then the user is + prompted for it. If you press the **Return** key at the prompt, then the + key password is set to the same password as the keystore password. The + `-keypass` value must have at least six characters. + + The value of `-startdate` specifies the issue time of the certificate, also + known as the "Not Before" value of the X.509 certificate's Validity field. + + The option value can be set in one of these two forms: + + (\[`+-`\]*nnn*\[`ymdHMS`\])+ + + \[*yyyy*`/`*mm*`/`*dd*\] \[*HH*`:`*MM*`:`*SS*\] + + With the first form, the issue time is shifted by the specified value from + the current time. The value is a concatenation of a sequence of subvalues. + Inside each subvalue, the plus sign (+) means shift forward, and the minus + sign (-) means shift backward. The time to be shifted is *nnn* units of + years, months, days, hours, minutes, or seconds (denoted by a single + character of `y`, `m`, `d`, `H`, `M`, or `S` respectively). The exact value + of the issue time is calculated by using the + `java.util.GregorianCalendar.add(int field, int amount)` method on each + subvalue, from left to right. For example, the issue time can be specified + by: + + ``` + Calendar c = new GregorianCalendar(); + c.add(Calendar.YEAR, -1); + c.add(Calendar.MONTH, 1); + c.add(Calendar.DATE, -1); + return c.getTime() + ``` + + With the second form, the user sets the exact issue time in two parts, + year/month/day and hour:minute:second (using the local time zone). The user + can provide only one part, which means the other part is the same as the + current date (or time). The user must provide the exact number of digits + shown in the format definition (padding with 0 when shorter). When both + date and time are provided, there is one (and only one) space character + between the two parts. The hour should always be provided in 24-hour + format. + + When the option isn't provided, the start date is the current time. The + option can only be provided one time. + + The value of *date* specifies the number of days (starting at the date + specified by `-startdate`, or the current date when `-startdate` isn't + specified) for which the certificate should be considered valid. + +`-genseckey` +: The following are the available options for the `-genseckey` command: + + - {`-alias` *alias*}: Alias name of the entry to process + + - \[`-keypass` *arg*\]: Key password + + - `-keyalg` *alg*: Key algorithm name + + - {`-keysize` *size*}: Key bit size + + - {`-keystore` *keystore*}: Keystore name + + - \[`-storepass` *arg*\]: Keystore password + + - {`-storetype` *type*}: Keystore type + + - {`-providername` *name*}: Provider name + + - {`-addprovider` *name* \[`-providerarg` *arg*\]}: Add security provider + by name (such as SunPKCS11) with an optional configure argument. + + - {`-providerclass` *class* \[`-providerarg` *arg*\]}: Add security + provider by fully qualified class name with an optional configure + argument. + + - {`-providerpath` *list*}: Provider classpath + + - {`-v`}: Verbose output + + - {`-protected`}: Password provided through a protected mechanism + + Use the `-genseckey` command to generate a secret key and store it in a new + `KeyStore.SecretKeyEntry` identified by `alias`. + + The value of `-keyalg` specifies the algorithm to be used to generate the + secret key, and the value of `-keysize` specifies the size of the key that + is generated. The `-keypass` value is a password that protects the secret + key. If a password is not provided, then the user is prompted for it. If + you press the **Return** key at the prompt, then the key password is set to + the same password that is used for the `-keystore`. The `-keypass` value + must contain at least six characters. + +`-importcert` +: The following are the available options for the `-importcert` command: + + - {`-noprompt`}: Do not prompt + + - {`-trustcacerts`}: Trust certificates from cacerts + + - {`-protected`}: Password is provided through protected mechanism + + - {`-alias` *alias*}: Alias name of the entry to process + + - {`-file` *file*}: Input file name + + - \[`-keypass` *arg*\]: Key password + + - {`-keystore` *keystore*}: Keystore name + + - {`-cacerts`}: Access the cacerts keystore + + - \[`-storepass` *arg*\]: Keystore password + + - {`-storetype` *type*}: Keystore type + + - {`-providername` *name*}: Provider name + + - {`-addprovider` *name* \[`-providerarg` *arg*\]}: Add security provider + by name (such as SunPKCS11) with an optional configure argument. + + - {`-providerclass` *class* \[`-providerarg` *arg*\]}: Add security + provider by fully qualified class name with an optional configure + argument. + + - {`-providerpath` *list*}: Provider classpath + + - {`-v`}: Verbose output + + Use the `-importcert` command to read the certificate or certificate chain + (where the latter is supplied in a PKCS\#7 formatted reply or in a sequence + of X.509 certificates) from `-file` *file*, and store it in the `keystore` + entry identified by `-alias`. If `-file` *file* is not specified, then the + certificate or certificate chain is read from `stdin`. + + The `keytool` command can import X.509 v1, v2, and v3 certificates, and + PKCS\#7 formatted certificate chains consisting of certificates of that + type. The data to be imported must be provided either in binary encoding + format or in printable encoding format (also known as Base64 encoding) as + defined by the Internet RFC 1421 standard. In the latter case, the encoding + must be bounded at the beginning by a string that starts with `-----BEGIN`, + and bounded at the end by a string that starts with `-----END`. + + You import a certificate for two reasons: To add it to the list of trusted + certificates, and to import a certificate reply received from a certificate + authority (CA) as the result of submitting a Certificate Signing Request + (CSR) to that CA. See the `-certreq` command in [Commands for Generating a + Certificate Request]. + + The type of import is indicated by the value of the `-alias` option. If the + alias doesn't point to a key entry, then the `keytool` command assumes you + are adding a trusted certificate entry. In this case, the alias shouldn't + already exist in the keystore. If the alias does exist, then the `keytool` + command outputs an error because a trusted certificate already exists for + that alias, and doesn't import the certificate. If `-alias` points to a key + entry, then the `keytool` command assumes that you're importing a + certificate reply. + +`-importpass` +: The following are the available options for the `-importpass` command: + + - {`-alias` *alias*}: Alias name of the entry to process + + - \[`-keypass` *arg*\]: Key password + + - {`-keyalg` *alg*}: Key algorithm name + + - {`-keysize` *size*}: Key bit size + + - {`-keystore` *keystore*}: Keystore name + + - \[`-storepass` *arg*\]: Keystore password + + - {`-storetype` *type*}: Keystore type + + - {`-providername` *name*}: Provider name + + - {`-addprovider` *name* \[`-providerarg` *arg*\]}: Add security provider + by name (such as SunPKCS11) with an optional configure argument. + + - {`-providerclass` *class* \[`-providerarg` *arg*\]}: Add security + provider by fully qualified class name with an optional configure + argument. + + - {`-providerpath` *list*}: Provider classpath + + - {`-v`}: Verbose output + + - {`-protected`}: Password provided through a protected mechanism + + Use the `-importpass` command to imports a passphrase and store it in a new + `KeyStore.SecretKeyEntry` identified by `-alias`. The passphrase may be + supplied via the standard input stream; otherwise the user is prompted for + it. The `-keypass` option provides a password to protect the imported + passphrase. If a password is not provided, then the user is prompted for + it. If you press the **Return** key at the prompt, then the key password is + set to the same password as that used for the `keystore`. The `-keypass` + value must contain at least six characters. + +## Commands for Importing Contents from Another Keystore + +`-importkeystore` +: The following are the available options for the `-importkeystore` command: + + - `-srckeystore` *keystore*: Source keystore name + + - {`-destkeystore` *keystore*}: Destination keystore name + + - {`-srcstoretype` *type*}: Source keystore type + + - {`-deststoretype` *type*}: Destination keystore type + + - \[`-srcstorepass` *arg*\]: Source keystore password + + - \[`-deststorepass` *arg*\]: Destination keystore password + + - {`-srcprotected`}: Source keystore password protected + + - {`-destprotected`}: Destination keystore password protected + + - {`-srcprovidername` *name*}: Source keystore provider name + + - {`-destprovidername` *name*}: Destination keystore provider name + + - {`-srcalias` *alias*}: Source alias + + - {`-destalias` *alias*}: Destination alias + + - \[`-srckeypass` *arg*\]: Source key password + + - \[`-destkeypass` *arg*\]: Destination key password + + - {`-noprompt`}: Do not prompt + + - {`-addprovider` *name* \[`-providerarg` *arg*\]: Add security provider + by name (such as SunPKCS11) with an optional configure argument. + + - {`-providerclass` *class* \[`-providerarg` *arg*\]}: Add security + provider by fully qualified class name with an optional configure + argument + + - {`-providerpath` *list*}: Provider classpath + + - {`-v`}: Verbose output + + **Note:** + + This is the first line of all options: + + > `-srckeystore` *keystore* `-destkeystore` *keystore* + + Use the `-importkeystore` command to import a single entry or all entries + from a source keystore to a destination keystore. + + **Note:** + + If you do not specify `-destkeystore` when using the + `keytool -importkeystore` command, then the default keystore used is + `$HOME/.keystore`. + + When the `-srcalias` option is provided, the command imports the single + entry identified by the alias to the destination keystore. If a destination + alias isn't provided with `-destalias`, then `-srcalias` is used as the + destination alias. If the source entry is protected by a password, then + `-srckeypass` is used to recover the entry. If `-srckeypass` isn't + provided, then the `keytool` command attempts to use `-srcstorepass` to + recover the entry. If `-srcstorepass` is not provided or is incorrect, then + the user is prompted for a password. The destination entry is protected + with `-destkeypass`. If `-destkeypass` isn't provided, then the destination + entry is protected with the source entry password. For example, most + third-party tools require `storepass` and `keypass` in a PKCS \#12 keystore + to be the same. To create a PKCS\#12 keystore for these tools, always + specify a `-destkeypass` that is the same as `-deststorepass`. + + If the `-srcalias` option isn't provided, then all entries in the source + keystore are imported into the destination keystore. Each destination entry + is stored under the alias from the source entry. If the source entry is + protected by a password, then `-srcstorepass` is used to recover the entry. + If `-srcstorepass` is not provided or is incorrect, then the user is + prompted for a password. If a source keystore entry type isn't supported in + the destination keystore, or if an error occurs while storing an entry into + the destination keystore, then the user is prompted either to skip the + entry and continue or to quit. The destination entry is protected with the + source entry password. + + If the destination alias already exists in the destination keystore, then + the user is prompted either to overwrite the entry or to create a new entry + under a different alias name. + + If the `-noprompt` option is provided, then the user isn't prompted for a + new destination alias. Existing entries are overwritten with the + destination alias name. Entries that can't be imported are skipped and a + warning is displayed. + +## Commands for Generating a Certificate Request + +`-certreq` +: The following are the available options for the `-certreq` command: + + - {`-alias` *alias*}: Alias name of the entry to process + + - {`-sigalg` *alg*}: Signature algorithm name + + - {`-file` *file*}: Output file name + + - \[ `-keypass` *arg*\]: Key password + + - {`-keystore` *keystore*}: Keystore name + + - {`-dname` *name*}: Distinguished name + + - {`-ext` *value*}: X.509 extension + + - \[`-storepass` *arg*\]: Keystore password + + - {`-storetype` *type*}: Keystore type + + - {`-providername` *name*}: Provider name + + - {`-addprovider` *name* \[`-providerarg` *arg*\]}: Add security provider + by name (such as SunPKCS11) with an optional configure argument. + + - {`-providerclass` *class* \[`-providerarg` *arg*\]}: Add security + provider by fully qualified class name with an optional configure + argument. + + - {`-providerpath` *list*}: Provider classpath + + - {`-v`}: Verbose output + + - {`-protected`}: Password provided through a protected mechanism + + Use the `-certreq` command to generate a Certificate Signing Request (CSR) + using the PKCS \#10 format. + + A CSR is intended to be sent to a CA. The CA authenticates the certificate + requestor (usually offline) and returns a certificate or certificate chain + to replace the existing certificate chain (initially a self-signed + certificate) in the keystore. + + The private key associated with *alias* is used to create the PKCS \#10 + certificate request. To access the private key, the correct password must + be provided. If `-keypass` isn't provided at the command line and is + different from the password used to protect the integrity of the keystore, + then the user is prompted for it. If `-dname` is provided, then it is used + as the subject in the CSR. Otherwise, the X.500 Distinguished Name + associated with alias is used. + + The `-sigalg` value specifies the algorithm that should be used to sign the + CSR. + + The CSR is stored in the `-file` *file*. If a file is not specified, then + the CSR is output to `-stdout`. + + Use the `-importcert` command to import the response from the CA. + +## Commands for Exporting Data + +`-exportcert` +: The following are the available options for the `-exportcert` command: + + - {`-rfc`}: Output in RFC style + + - {`-alias` *alias*}: Alias name of the entry to process + + - {`-file` *file*}: Output file name + + - {`-keystore` *keystore*}: Keystore name + + - {`-cacerts`}: Access the cacerts keystore + + - \[`-storepass` *arg*\]: Keystore password + + - {`-storetype` *type*}: Keystore type + + - {`-providername` *name*}: Provider name + + - {`-addprovider` *name* \[`-providerarg` *arg*\]}: Add security provider + by name (such as SunPKCS11) with an optional configure argument. + + - {`-providerclass` *class* \[`-providerarg` *arg*\] }: Add security + provider by fully qualified class name with an optional configure + argument. + + - {`-providerpath` *list*}: Provider classpath + + - {`-v`}: Verbose output + + - {`-protected`}: Password provided through a protected mechanism + + Use the `-exportcert` command to read a certificate from the keystore that + is associated with `-alias` *alias* and store it in the `-file` *file*. + When a file is not specified, the certificate is output to `stdout`. + + By default, the certificate is output in binary encoding. If the `-rfc` + option is specified, then the output in the printable encoding format + defined by the Internet RFC 1421 Certificate Encoding Standard. + + If `-alias` refers to a trusted certificate, then that certificate is + output. Otherwise, `-alias` refers to a key entry with an associated + certificate chain. In that case, the first certificate in the chain is + returned. This certificate authenticates the public key of the entity + addressed by `-alias`. + +## Commands for Displaying Data + +`-list` +: The following are the available options for the `-list` command: + + - {`-rfc`}: Output in RFC style + + - {`-alias` *alias*}: Alias name of the entry to process + + - {`-keystore` *keystore*}: Keystore name + + - {`-cacerts`}: Access the cacerts keystore + + - \[`-storepass` *arg*\]: Keystore password + + - {`-storetype` *type*}: Keystore type + + - {`-providername` *name*}: Provider name + + - {`-addprovider` *name* \[`-providerarg` *arg*\]}: Add security provider + by name (such as SunPKCS11) with an optional configure argument. + + - {`-providerclass` *class* \[`-providerarg` *arg*\] }: Add security + provider by fully qualified class name with an optional configure + argument. + + - {`-providerpath` *list*}: Provider classpath + + - {`-v`}: Verbose output + + - {`-protected`}: Password provided through a protected mechanism + + Use the `-list` command to print the contents of the keystore entry + identified by `-alias` to `stdout`. If `-alias` *alias* is not specified, + then the contents of the entire keystore are printed. + + By default, this command prints the SHA-256 fingerprint of a certificate. + If the `-v` option is specified, then the certificate is printed in + human-readable format, with additional information such as the owner, + issuer, serial number, and any extensions. If the `-rfc` option is + specified, then the certificate contents are printed by using the printable + encoding format, as defined by the Internet RFC 1421 Certificate Encoding + Standard. + + **Note:** + + You can't specify both `-v` and `-rfc` in the same command. Otherwise, an + error is reported. + +`-printcert` +: The following are the available options for the `-printcert` command: + + - {`-rfc`}: Output in RFC style + + - {`-file` *cert\_file*}: Input file name + + - {`-sslserver` *server*\[`:`*port*\]}:: Secure Sockets Layer (SSL) + server host and port + + - {`-jarfile` *JAR\_file*}: Signed `.jar` file + + - {`-keystore` *keystore*}: Keystore name + + - {`-trustcacerts`}: Trust certificates from cacerts + + - \[`-storepass` *arg*\]: Keystore password + + - {`-storetype` *type*}: Keystore type + + - {`-providername` *name*}: Provider name + + - {`-addprovider` *name* \[`-providerarg` *arg*\]}: Add security provider + by name (such as SunPKCS11) with an optional configure argument. + + - {`-providerclass` *class* \[`-providerarg` *arg*\]}: Add security + provider by fully qualified class name with an optional configure + argument. + + - {`-providerpath` *list*}: Provider classpath + + - {`-protected`}: Password is provided through protected mechanism + + - {`-v`}: Verbose output + + Use the `-printcert` command to read and print the certificate from `-file` + *cert\_file*, the SSL server located at `-sslserver` *server*\[`:`*port*\], + or the signed JAR file specified by `-jarfile` *JAR\_file*. It prints its + contents in a human-readable format. When a port is not specified, the + standard HTTPS port 443 is assumed. + + **Note:** + + The `-sslserver` and `-file` options can't be provided in the same command. + Otherwise, an error is reported. If you don't specify either option, then + the certificate is read from `stdin`. + + When`-rfc` is specified, the `keytool` command prints the certificate in + PEM mode as defined by the Internet RFC 1421 Certificate Encoding standard. + + If the certificate is read from a file or `stdin`, then it might be either + binary encoded or in printable encoding format, as defined by the RFC 1421 + Certificate Encoding standard. + + If the SSL server is behind a firewall, then the + `-J-Dhttps.proxyHost=proxyhost` and `-J-Dhttps.proxyPort=proxyport` options + can be specified on the command line for proxy tunneling. + + **Note:** + + This command can be used independently of a keystore. This command does not + check for the weakness of a certificate's signature algorithm if it is a + trusted certificate in the user keystore (specified by `-keystore`) or in + the `cacerts` keystore (if `-trustcacerts` is specified). + +`-printcertreq` +: The following are the available options for the `-printcertreq` command: + + - {`-file` *file*}: Input file name + + - {`-v`}: Verbose output + + Use the `-printcertreq` command to print the contents of a PKCS \#10 format + certificate request, which can be generated by the `keytool -certreq` + command. The command reads the request from file. If there is no file, then + the request is read from the standard input. + +`-printcrl` +: The following are the available options for the `-printcrl` command: + + - {`-file crl`}: Input file name + + - {`-keystore` *keystore*}: Keystore name + + - {`-trustcacerts`}: Trust certificates from cacerts + + - \[`-storepass` *arg*\]: Keystore password + + - {`-storetype` *type*}: Keystore type + + - {`-providername` *name*}: Provider name + + - {`-addprovider` *name* \[`-providerarg` *arg*\]}: Add security provider + by name (such as SunPKCS11) with an optional configure argument. + + - {`-providerclass` *class* \[`-providerarg` *arg*\]}: Add security + provider by fully qualified class name with an optional configure + argument. + + - {`-providerpath` *list*}: Provider classpath + + - {`-protected`}: Password is provided through protected mechanism + + - {`-v`}: Verbose output + + Use the `-printcrl` command to read the Certificate Revocation List (CRL) + from `-file crl` . A CRL is a list of the digital certificates that were + revoked by the CA that issued them. The CA generates the `crl` file. + + **Note:** + + This command can be used independently of a keystore. This command attempts + to verify the CRL using a certificate from the user keystore (specified by + `-keystore`) or the `cacerts` keystore (if `-trustcacerts` is specified), and + will print out a warning if it cannot be verified. + +## Commands for Managing the Keystore + +`-storepasswd` +: The following are the available options for the `-storepasswd` command: + + - \[`-new` *arg*\]: New password + + - {`-keystore` *keystore*}: Keystore name + + - {`-cacerts`}: Access the cacerts keystore + + - \[`-storepass` *arg*\]: Keystore password + + - {`-storetype` *type*}: Keystore type + + - {`-providername` *name*}: Provider name + + - {`-addprovider` *name* \[`-providerarg` *arg*\]}: Add security provider + by name (such as SunPKCS11) with an optional configure argument. + + - {`-providerclass` *class* \[`-providerarg` *arg*\]}: Add security + provider by fully qualified class name with an optional configure + argument. + + - {`-providerpath` *list*}: Provider classpath + + - {`-v`}: Verbose output + + Use the `-storepasswd` command to change the password used to protect the + integrity of the keystore contents. The new password is set by `-new` *arg* + and must contain at least six characters. + +`-keypasswd` +: The following are the available options for the `-keypasswd` command: + + - {`-alias` *alias*}: Alias name of the entry to process + + - \[`-keypass` *old\_keypass*\]: Key password + + - \[`-new` *new\_keypass*\]: New password + + - {`-keystore` *keystore*}: Keystore name + + - {`-storepass` *arg*}: Keystore password + + - {`-storetype` *type*}: Keystore type + + - {`-providername` *name*}: Provider name + + - {`-addprovider` *name* \[`-providerarg` *arg*\]}: Add security provider + by name (such as SunPKCS11) with an optional configure argument. + + - {`-providerclass` *class* \[`-providerarg` *arg*\]}: Add security + provider by fully qualified class name with an optional configure + argument. + + - {`-providerpath` *list*}: Provider classpath + + - {`-v`}: Verbose output + + Use the `-keypasswd` command to change the password (under which + private/secret keys identified by `-alias` are protected) from `-keypass` + *old\_keypass* to `-new` *new\_keypass*. The password value must contain at + least six characters. + + If the `-keypass` option isn't provided at the command line and the + `-keypass` password is different from the keystore password (`-storepass` + *arg*), then the user is prompted for it. + + If the `-new` option isn't provided at the command line, then the user is + prompted for it. + +`-delete` +: The following are the available options for the `-delete` command: + + - \[`-alias` *alias*\]: Alias name of the entry to process + + - {`-keystore` *keystore*}: Keystore name + + - {`-cacerts`}: Access the cacerts keystore + + - \[`-storepass` *arg*\]: Keystore password + + - {`-storetype` *type*}: Keystore type + + - {`-providername` *name*}: Provider name + + - {`-addprovider` *name* \[`-providerarg` *arg*\]}: Add security provider + by name (such as SunPKCS11) with an optional configure argument. + + - {`-providerclass` *class* \[`-providerarg` *arg*\]}: Add security + provider by fully qualified class name with an optional configure + argument. + + - {`-providerpath` *list*}: Provider classpath + + - {`-v`}: Verbose output + + - {`-protected`}: Password provided through a protected mechanism + + Use the `-delete` command to delete the `-alias` *alias* entry from the + keystore. When not provided at the command line, the user is prompted for + the `alias`. + +`-changealias` +: The following are the available options for the `-changealias` command: + + - {`-alias` *alias*}: Alias name of the entry to process + + - \[`-destalias` *alias*\]: Destination alias + + - \[`-keypass` *arg*\]: Key password + + - {`-keystore` *keystore*}: Keystore name + + - {`-cacerts`}: Access the cacerts keystore + + - \[`-storepass` *arg*\]: Keystore password + + - {`-storetype` *type*}: Keystore type + + - {`-providername` *name*}: Provider name + + - {`-addprovider` *name* \[`-providerarg` *arg*\]}: Add security provider + by name (such as SunPKCS11) with an optional configure argument. + + - {`-providerclass` *class* \[`-providerarg` *arg*\]}: Add security + provider by fully qualified class name with an optional configure + argument. + + - {`-providerpath` *list*}: Provider classpath + + - {`-v`}: Verbose output + + - {`-protected`}: Password provided through a protected mechanism + + Use the `-changealias` command to move an existing keystore entry from + `-alias` *alias* to a new `-destalias` *alias*. If a destination alias is + not provided, then the command prompts you for one. If the original entry + is protected with an entry password, then the password can be supplied with + the `-keypass` option. If a key password is not provided, then the + `-storepass` (if provided) is attempted first. If the attempt fails, then + the user is prompted for a password. + +## Commands for Displaying Security-related Information + +`-showinfo` +: The following are the available options for the `-showinfo` command: + + - {`-tls`}: Displays TLS configuration information + + - {`-v`}: Verbose output + + Use the `-showinfo` command to display various security-related + information. The `-tls` option displays TLS configurations, such as + the list of enabled protocols and cipher suites. + +## Commands for Displaying Program Version + +You can use `-version` to print the program version of `keytool`. + +## Commands for Displaying Help Information + +You can use `--help` to display a list of `keytool` commands or to display help +information about a specific `keytool` command. + +- To display a list of `keytool` commands, enter: + + > `keytool --help` + +- To display help information about a specific `keytool` command, enter: + + > `keytool - --help` + +## Common Command Options + +The `-v` option can appear for all commands except `--help`. When the `-v` +option appears, it signifies verbose mode, which means that more information is +provided in the output. + +The `-J`*option* argument can appear for any command. When the `-J`*option* is +used, the specified *option* string is passed directly to the Java interpreter. +This option doesn't contain any spaces. It's useful for adjusting the execution +environment or memory usage. For a list of possible interpreter options, enter +`java -h` or `java -X` at the command line. + +These options can appear for all commands operating on a keystore: + +`-storetype` *storetype* +: This qualifier specifies the type of keystore to be instantiated. + +`-keystore` *keystore* +: The keystore location. + + If the JKS `storetype` is used and a keystore file doesn't yet exist, then + certain `keytool` commands can result in a new keystore file being created. + For example, if `keytool -genkeypair` is called and the `-keystore` option + isn't specified, the default keystore file named `.keystore` is created in + the user's home directory if it doesn't already exist. Similarly, if the + `-keystore ks_file` option is specified but `ks_file` doesn't exist, then + it is created. For more information on the JKS `storetype`, see the + **KeyStore Implementation** section in **KeyStore aliases**. + + Note that the input stream from the `-keystore` option is passed to the + `KeyStore.load` method. If `NONE` is specified as the URL, then a null + stream is passed to the `KeyStore.load` method. `NONE` should be specified + if the keystore isn't file-based. For example, when the keystore resides on + a hardware token device. + +`-cacerts` *cacerts* +: Operates on the *cacerts* keystore . This option is equivalent to + `-keystore` *path\_to\_cacerts* `-storetype` *type\_of\_cacerts*. An error + is reported if the `-keystore` or `-storetype` option is used with the + `-cacerts` option. + +`-storepass` \[`:env` \| `:file` \] *argument* +: The password that is used to protect the integrity of the keystore. + + If the modifier `env` or `file` isn't specified, then the password has the + value *argument*, which must contain at least six characters. Otherwise, + the password is retrieved as follows: + + - `env`: Retrieve the password from the environment variable named + *argument*. + + - `file`: Retrieve the password from the file named *argument*. + + **Note:** All other options that require passwords, such as `-keypass`, + `-srckeypass`, `-destkeypass`, `-srcstorepass`, and `-deststorepass`, + accept the `env` and `file` modifiers. Remember to separate the password + option and the modifier with a colon (:). + + The password must be provided to all commands that access the keystore + contents. For such commands, when the `-storepass` option isn't provided at + the command line, the user is prompted for it. + + When retrieving information from the keystore, the password is optional. If + a password is not specified, then the integrity of the retrieved + information can't be verified and a warning is displayed. + +`-providername` *name* +: Used to identify a cryptographic service provider's name when listed in the + security properties file. + +`-addprovider` *name* +: Used to add a security provider by name (such as SunPKCS11) . + +`-providerclass` *class* +: Used to specify the name of a cryptographic service provider's master class + file when the service provider isn't listed in the security properties + file. + +`-providerpath` *list* +: Used to specify the provider classpath. + +`-providerarg` *arg* +: Used with the `-addprovider` or `-providerclass` option to represent an + optional string input argument for the constructor of *class* name. + +`-protected=true`\|`false` +: Specify this value as `true` when a password must be specified by way of a + protected authentication path, such as a dedicated PIN reader. Because + there are two keystores involved in the `-importkeystore` command, the + following two options, `-srcprotected` and `-destprotected`, are provided + for the source keystore and the destination keystore respectively. + +`-ext` {*name*{`:critical`} {`=`*value*}} +: Denotes an X.509 certificate extension. The option can be used in + `-genkeypair` and `-gencert` to embed extensions into the generated + certificate, or in `-certreq` to show what extensions are requested in the + certificate request. The option can appear multiple times. The *name* + argument can be a supported extension name (see [Supported Named + Extensions]) or an arbitrary OID number. The *value* argument, when + provided, denotes the argument for the extension. When *value* is omitted, + the default value of the extension or the extension itself requires no + argument. The `:critical` modifier, when provided, means the extension's + `isCritical` attribute is `true`; otherwise, it is `false`. You can use + `:c` in place of `:critical`. + +`-conf` *file* +: Specifies a pre-configured options file. + +## Pre-configured options file + +A pre-configured options file is a Java properties file that can be specified +with the `-conf` option. Each property represents the default option(s) for +a keytool command using "keytool.*command_name*" as the property name. A +special property named "keytool.all" represents the default option(s) applied +to all commands. A property value can include `${prop}` which will be expanded +to the system property associated with it. If an option value includes white +spaces inside, it should be surrounded by quotation marks (" or '). All +property names must be in lower case. + +When `keytool` is launched with a pre-configured options file, the value for +"keytool.all" (if it exists) is prepended to the `keytool` command line first, +with the value for the command name (if it exists) comes next, and the existing +options on the command line at last. For a single-valued option, this allows +the property for a specific command to override the "keytool.all" value, +and the value specified on the command line to override both. For +multiple-valued options, all of them will be used by `keytool`. + +For example, given the following file named `preconfig`: +``` + # A tiny pre-configured options file + keytool.all = -keystore ${user.home}/ks + keytool.list = -v + keytool.genkeypair = -keyalg rsa +``` + +`keytool -conf preconfig -list` is identical to + +> `keytool -keystore ~/ks -v -list` + +`keytool -conf preconfig -genkeypair -alias me` is identical to + +> `keytool -keystore ~/ks -keyalg rsa -genkeypair -alias me` + +`keytool -conf preconfig -genkeypair -alias you -keyalg ec` is identical to + +> `keytool -keystore ~/ks -keyalg rsa -genkeypair -alias you -keyalg ec` + +which is equivalent to + +> `keytool -keystore ~/ks -genkeypair -alias you -keyalg ec` + +because `-keyalg` is a single-valued option and the `ec` value specified +on the command line overrides the preconfigured options file. + +## Examples of Option Values + +The following examples show the defaults for various option values: + +``` +-alias "mykey" + +-keysize + 2048 (when using -genkeypair and -keyalg is "DSA") + 3072 (when using -genkeypair and -keyalg is "RSA", "RSASSA-PSS", or "DH") + 384 (when using -genkeypair and -keyalg is "EC") + 56 (when using -genseckey and -keyalg is "DES") + 168 (when using -genseckey and -keyalg is "DESede") + +-groupname + ed25519 (when using -genkeypair and -keyalg is "EdDSA", key size is 255) + x25519 (when using -genkeypair and -keyalg is "XDH", key size is 255) + +-validity 90 + +-keystore + +-destkeystore + +-storetype + +-file + stdin (if reading) + stdout (if writing) + +-protected false +``` + +When generating a certificate or a certificate request, the default signature +algorithm (`-sigalg` option) is derived from the algorithm of the underlying +private key to provide an appropriate level of security strength as follows: + +Table: Default Signature Algorithms + +keyalg key size default sigalg +------- -------- -------------- +DSA any size SHA256withDSA +RSA \< 624 SHA256withRSA (key size is too small for using SHA-384) + \<= 7680 SHA384withRSA + \> 7680 SHA512withRSA +EC \< 512 SHA384withECDSA + \>= 512 SHA512withECDSA +RSASSA-PSS \< 624 RSASSA-PSS (with SHA-256, key size is too small for + using SHA-384) + \<= 7680 RSASSA-PSS (with SHA-384) + \> 7680 RSASSA-PSS (with SHA-512) +EdDSA 255 Ed25519 + 448 Ed448 +Ed25519 255 Ed25519 +Ed448 448 Ed448 +------- -------- -------------- + +* The key size, measured in bits, corresponds to the size of the private key. +This size is determined by the value of the `-keysize` or `-groupname` options +or the value derived from a default setting. + +* An RSASSA-PSS signature algorithm uses a `MessageDigest` +algorithm as its hash and MGF1 algorithms. + +* If neither a default `-keysize` or `-groupname` is defined for an algorithm, +the security provider will choose a default setting. + +**Note:** + +To improve out of the box security, default keysize, groupname, and signature +algorithm names are periodically updated to stronger values with each release +of the JDK. If interoperability with older releases of the JDK is important, +make sure that the defaults are supported by those releases. Alternatively, +you can use the `-keysize`, `-groupname`, or `-sigalg` options to override +the default values at your own risk. + +## Supported Named Extensions + +The `keytool` command supports these named extensions. The names aren't +case-sensitive. + +`BC` or `BasicConstraints` +: Values: + + The full form is `ca:`{`true`\|`false`}\[`,pathlen:`*len*\] or *len*, which + is short for `ca:true,pathlen:`*len*. + + When *len* is omitted, the resulting value is `ca:true`. + +`KU` or `KeyUsage` +: Values: + + *usage*(`,` *usage*)\* + + *usage* can be one of the following: + + - `digitalSignature` + + - `nonRepudiation` (`contentCommitment`) + + - `keyEncipherment` + + - `dataEncipherment` + + - `keyAgreement` + + - `keyCertSign` + + - `cRLSign` + + - `encipherOnly` + + - `decipherOnly` + + Provided there is no ambiguity, the *usage* argument can be abbreviated + with the first few letters (such as `dig` for `digitalSignature`) or in + camel-case style (such as `dS` for `digitalSignature` or `cRLS` for + `cRLSign`). The *usage* values are case-sensitive. + +`EKU` or `ExtendedKeyUsage` +: Values: + + *usage*(`,` *usage*)\* + + *usage* can be one of the following: + + - `anyExtendedKeyUsage` + + - `serverAuth` + + - `clientAuth` + + - `codeSigning` + + - `emailProtection` + + - `timeStamping` + + - `OCSPSigning` + + - Any OID string + + Provided there is no ambiguity, the *usage* argument can be abbreviated + with the first few letters or in camel-case style. The *usage* values are + case-sensitive. + +`SAN` or `SubjectAlternativeName` +: Values: + + *type*`:`*value*(`,` *type*`:`*value*)\* + + *type* can be one of the following: + + - `EMAIL` + + - `URI` + + - `DNS` + + - `IP` + + - `OID` + + The *value* argument is the string format value for the *type*. + +`IAN` or `IssuerAlternativeName` +: Values: + + Same as `SAN` or `SubjectAlternativeName`. + +`SIA` or `SubjectInfoAccess` +: Values: + + *method*`:`*location-type*`:`*location-value*(`,` + *method*`:`*location-type*`:`*location-value*)\* + + *method* can be one of the following: + + - `timeStamping` + + - `caRepository` + + - Any OID + + The *location-type* and *location-value* arguments can be any + *type*`:`*value* supported by the `SubjectAlternativeName` extension. + +`AIA` or `AuthorityInfoAccess` +: Values: + + Same as `SIA` or `SubjectInfoAccess`. + + The *method* argument can be one of the following: + + - `ocsp` + + - `caIssuers` + + - Any OID + +When *name* is OID, the value is the hexadecimal dumped Definite Encoding Rules +(DER) encoding of the `extnValue` for the extension excluding the OCTET STRING +type and length bytes. Other than standard hexadecimal numbers (0-9, a-f, A-F), +any extra characters are ignored in the HEX string. Therefore, both 01:02:03:04 +and 01020304 are accepted as identical values. When there is no value, the +extension has an empty value field. + +A special name `honored`, used only in `-gencert`, denotes how the extensions +included in the certificate request should be honored. The value for this name +is a comma-separated list of `all` (all requested extensions are honored), +*name*{`:`\[`critical`\|`non-critical`\]} (the named extension is honored, but +it uses a different `isCritical` attribute), and `-name` (used with `all`, +denotes an exception). Requested extensions aren't honored by default. + +If, besides the`-ext honored` option, another named or OID `-ext` option is +provided, this extension is added to those already honored. However, if this +name (or OID) also appears in the honored value, then its value and criticality +override that in the request. If an extension of the same type is provided +multiple times through either a name or an OID, only the last extension is +used. + +The `subjectKeyIdentifier` extension is always created. For non-self-signed +certificates, the `authorityKeyIdentifier` is created. + +**CAUTION:** + +Users should be aware that some combinations of extensions (and other +certificate fields) may not conform to the Internet standard. See [Certificate +Conformance Warning]. + +## Examples of Tasks in Creating a keystore + +The following examples describe the sequence actions in creating a keystore for +managing public/private key pairs and certificates from trusted entities. + +- [Generating the Key Pair] + +- [Requesting a Signed Certificate from a CA] + +- [Importing a Certificate for the CA] + +- [Importing the Certificate Reply from the CA] + +- [Exporting a Certificate That Authenticates the Public Key] + +- [Importing the Keystore] + +- [Generating Certificates for an SSL Server] + +## Generating the Key Pair + +Create a keystore and then generate the key pair. + +You can enter the command as a single line such as the following: + +> `keytool -genkeypair -dname "cn=myname, ou=mygroup, o=mycompany, + c=mycountry" -alias business -keyalg rsa -keypass` *password* `-keystore + /working/mykeystore -storepass password -validity 180` + +The command creates the keystore named `mykeystore` in the working directory +(provided it doesn't already exist), and assigns it the password specified by +`-keypass`. It generates a public/private key pair for the entity whose +distinguished name is `myname`, `mygroup`, `mycompany`, and a two-letter +country code of `mycountry`. It uses the RSA key generation algorithm +to create the keys; both are 3072 bits. + +The command uses the default SHA384withRSA signature algorithm to create a +self-signed certificate that includes the public key and the distinguished name +information. The certificate is valid for 180 days, and is associated with the +private key in a keystore entry referred to by `-alias business`. The private +key is assigned the password specified by `-keypass`. + +The command is significantly shorter when the option defaults are accepted. In +this case, only `-keyalg` is required, and the defaults are used for unspecified +options that have default values. You are prompted for any required values. You +could have the following: + +> `keytool -genkeypair -keyalg rsa` + +In this case, a keystore entry with the alias `mykey` is created, with a newly +generated key pair and a certificate that is valid for 90 days. This entry is +placed in your home directory in a keystore named `.keystore` . `.keystore` is +created if it doesn't already exist. You are prompted for the distinguished +name information, the keystore password, and the private key password. + +**Note:** + +The rest of the examples assume that you responded to the prompts with values +equal to those specified in the first `-genkeypair` command. For example, a +distinguished name of +`cn=`*myname*`, ou=`*mygroup*`, o=`*mycompany*`, c=`*mycountry*). + +## Requesting a Signed Certificate from a CA + +**Note:** + +Generating the key pair created a self-signed certificate; however, a +certificate is more likely to be trusted by others when it is signed by a CA. + +To get a CA signature, complete the following process: + +1. Generate a CSR: + + > `keytool -certreq -file myname.csr` + + This creates a CSR for the entity identified by the default alias `mykey` + and puts the request in the file named `myname.csr`. + +2. Submit `myname.csr` to a CA, such as DigiCert. + +The CA authenticates you, the requestor (usually offline), and returns a +certificate, signed by them, authenticating your public key. In some cases, the +CA returns a chain of certificates, each one authenticating the public key of +the signer of the previous certificate in the chain. + +## Importing a Certificate for the CA + +To import a certificate for the CA, complete the following process: + +1. Before you import the certificate reply from a CA, you need one or more + trusted certificates either in your keystore or in the `cacerts` keystore + file. See `-importcert` in **Commands**. + + - If the certificate reply is a certificate chain, then you need the top + certificate of the chain. The root CA certificate that authenticates + the public key of the CA. + + - If the certificate reply is a single certificate, then you need a + certificate for the issuing CA (the one that signed it). If that + certificate isn't self-signed, then you need a certificate for its + signer, and so on, up to a self-signed root CA certificate. + + The `cacerts` keystore ships with a set of root certificates issued by the + CAs of [the Oracle Java Root Certificate program]( + http://www.oracle.com/technetwork/java/javase/javasecarootcertsprogram-1876540.html). + If you request a signed certificate from a CA, and a certificate + authenticating that CA's public key hasn't been added to `cacerts`, then + you must import a certificate from that CA as a trusted certificate. + + A certificate from a CA is usually self-signed or signed by another CA. If + it is signed by another CA, you need a certificate that authenticates that + CA's public key. + + For example, you have obtained a *X*`.cer` file from a company that is a CA + and the file is supposed to be a self-signed certificate that authenticates + that CA's public key. Before you import it as a trusted certificate, you + should ensure that the certificate is valid by: + + 1. Viewing it with the `keytool -printcert` command or the + `keytool -importcert` command without using the `-noprompt` option. + Make sure that the displayed certificate fingerprints match the + expected fingerprints. + + 2. Calling the person who sent the certificate, and comparing the + fingerprints that you see with the ones that they show or that a secure + public key repository shows. + + Only when the fingerprints are equal is it assured that the certificate + wasn't replaced in transit with somebody else's certificate (such as an + attacker's certificate). If such an attack takes place, and you didn't + check the certificate before you imported it, then you would be trusting + anything that the attacker signed. + +2. Replace the self-signed certificate with a certificate chain, where each + certificate in the chain authenticates the public key of the signer of the + previous certificate in the chain, up to a root CA. + + If you trust that the certificate is valid, then you can add it to your + keystore by entering the following command: + + > `keytool -importcert -alias` *alias* `-file *X*`.cer` + + This command creates a trusted certificate entry in the keystore from the + data in the CA certificate file and assigns the values of the *alias* to + the entry. + +## Importing the Certificate Reply from the CA + +After you import a certificate that authenticates the public key of the CA that +you submitted your certificate signing request to (or there is already such a +certificate in the `cacerts` file), you can import the certificate reply and +replace your self-signed certificate with a certificate chain. + +The certificate chain is one of the following: + +- Returned by the CA when the CA reply is a chain. + +- Constructed when the CA reply is a single certificate. This certificate + chain is constructed by using the certificate reply and trusted + certificates available either in the keystore where you import the reply or + in the `cacerts` keystore file. + +For example, if you sent your certificate signing request to DigiCert, then you +can import their reply by entering the following command: + +**Note:** + +In this example, the returned certificate is named `DCmyname.cer`. + +> `keytool -importcert -trustcacerts -file DCmyname.cer` + +## Exporting a Certificate That Authenticates the Public Key + +**Note:** + +If you used the `jarsigner` command to sign a Java Archive (JAR) file, then +clients that use the file will want to authenticate your signature. + +One way that clients can authenticate you is by importing your public key +certificate into their keystore as a trusted entry. You can then export the +certificate and supply it to your clients. + +For example: + +1. Copy your certificate to a file named `myname.cer` by entering the + following command: + + **Note:** + + In this example, the entry has an alias of `mykey`. + + > `keytool -exportcert -alias mykey -file myname.cer` + +2. With the certificate and the signed JAR file, a client can use the + `jarsigner` command to authenticate your signature. + +## Importing the Keystore + +Use the `importkeystore` command to import an entire keystore into another +keystore. This imports all entries from the source keystore, including keys and +certificates, to the destination keystore with a single command. You can use +this command to import entries from a different type of keystore. During the +import, all new entries in the destination keystore will have the same alias +names and protection passwords (for secret keys and private keys). If the +`keytool` command can't recover the private keys or secret keys from the source +keystore, then it prompts you for a password. If it detects alias duplication, +then it asks you for a new alias, and you can specify a new alias or simply +allow the `keytool` command to overwrite the existing one. + +For example, import entries from a typical JKS type keystore `key.jks` into a +PKCS \#11 type hardware-based keystore, by entering the following command: + +> `keytool -importkeystore -srckeystore key.jks -destkeystore NONE + -srcstoretype JKS -deststoretype PKCS11 -srcstorepass` *password* + `-deststorepass` *password* + +The `importkeystore` command can also be used to import a single entry from a +source keystore to a destination keystore. In this case, besides the options +you used in the previous example, you need to specify the alias you want to +import. With the `-srcalias` option specified, you can also specify the +destination alias name, protection password for a secret or private key, and +the destination protection password you want as follows: + +> `keytool -importkeystore -srckeystore key.jks -destkeystore NONE + -srcstoretype JKS -deststoretype PKCS11 -srcstorepass` *password* + `-deststorepass` *password* `-srcalias myprivatekey -destalias + myoldprivatekey -srckeypass` *password* `-destkeypass` *password* + `-noprompt` + +## Generating Certificates for an SSL Server + +The following are `keytool` commands used to generate key pairs and +certificates for three entities: + +- Root CA (`root`) + +- Intermediate CA (`ca`) + +- SSL server (`server`) + +Ensure that you store all the certificates in the same keystore. + +``` +keytool -genkeypair -keystore root.jks -alias root -ext bc:c -keyalg rsa +keytool -genkeypair -keystore ca.jks -alias ca -ext bc:c -keyalg rsa +keytool -genkeypair -keystore server.jks -alias server -keyalg rsa + +keytool -keystore root.jks -alias root -exportcert -rfc > root.pem + +keytool -storepass password -keystore ca.jks -certreq -alias ca | + keytool -storepass password -keystore root.jks + -gencert -alias root -ext BC=0 -rfc > ca.pem +keytool -keystore ca.jks -importcert -alias ca -file ca.pem + +keytool -storepass password -keystore server.jks -certreq -alias server | + keytool -storepass password -keystore ca.jks -gencert -alias ca + -ext ku:c=dig,kE -rfc > server.pem +cat root.pem ca.pem server.pem | + keytool -keystore server.jks -importcert -alias server + +``` + +## Terms + +Keystore +: A keystore is a storage facility for cryptographic keys and certificates. + +Keystore entries +: Keystores can have different types of entries. The two most applicable + entry types for the `keytool` command include the following: + + Key entries: Each entry holds very sensitive cryptographic key information, + which is stored in a protected format to prevent unauthorized access. + Typically, a key stored in this type of entry is a secret key, or a private + key accompanied by the certificate chain for the corresponding public key. + See **Certificate Chains**. The `keytool` command can handle both types of + entries, while the `jarsigner` tool only handles the latter type of entry, + that is private keys and their associated certificate chains. + + Trusted certificate entries: Each entry contains a single public key + certificate that belongs to another party. The entry is called a trusted + certificate because the keystore owner trusts that the public key in the + certificate belongs to the identity identified by the subject (owner) of + the certificate. The issuer of the certificate vouches for this, by signing + the certificate. + +Keystore aliases +: All keystore entries (key and trusted certificate entries) are accessed by + way of unique aliases. + + An alias is specified when you add an entity to the keystore with the + `-genseckey` command to generate a secret key, the `-genkeypair` command to + generate a key pair (public and private key), or the `-importcert` command + to add a certificate or certificate chain to the list of trusted + certificates. Subsequent `keytool` commands must use this same alias to + refer to the entity. + + For example, you can use the alias `duke` to generate a new public/private + key pair and wrap the public key into a self-signed certificate with the + following command. See **Certificate Chains**. + + > `keytool -genkeypair -alias duke -keyalg rsa -keypass` *passwd* + + This example specifies an initial *passwd* required by subsequent commands + to access the private key associated with the alias `duke`. If you later + want to change Duke's private key password, use a command such as the + following: + + > `keytool -keypasswd -alias duke -keypass` *passwd* `-new` *newpasswd* + + This changes the initial *passwd* to *newpasswd*. A password shouldn't be + specified on a command line or in a script unless it is for testing + purposes, or you are on a secure system. If you don't specify a required + password option on a command line, then you are prompted for it. + +Keystore implementation +: The `KeyStore` class provided in the `java.security` package supplies + well-defined interfaces to access and modify the information in a keystore. + It is possible for there to be multiple different concrete implementations, + where each implementation is that for a particular type of keystore. + + Currently, two command-line tools (`keytool` and `jarsigner`) make use of + keystore implementations. Because the `KeyStore` class is `public`, users + can write additional security applications that use it. + + In JDK 9 and later, the default keystore implementation is `PKCS12`. This + is a cross platform keystore based on the RSA PKCS12 Personal Information + Exchange Syntax Standard. This standard is primarily meant for storing or + transporting a user's private keys, certificates, and miscellaneous + secrets. There is another built-in implementation, provided by Oracle. It + implements the keystore as a file with a proprietary keystore type (format) + named `JKS`. It protects each private key with its individual password, and + also protects the integrity of the entire keystore with a (possibly + different) password. + + Keystore implementations are provider-based. More specifically, the + application interfaces supplied by `KeyStore` are implemented in terms of a + Service Provider Interface (SPI). That is, there is a corresponding + abstract `KeystoreSpi` class, also in the `java.security package`, which + defines the Service Provider Interface methods that providers must + implement. The term *provider* refers to a package or a set of packages + that supply a concrete implementation of a subset of services that can be + accessed by the Java Security API. To provide a keystore implementation, + clients must implement a provider and supply a `KeystoreSpi` subclass + implementation, as described in Steps to Implement and Integrate a + Provider. + + Applications can choose different types of keystore implementations from + different providers, using the `getInstance` factory method supplied in the + `KeyStore` class. A keystore type defines the storage and data format of + the keystore information, and the algorithms used to protect private/secret + keys in the keystore and the integrity of the keystore. Keystore + implementations of different types aren't compatible. + + The `keytool` command works on any file-based keystore implementation. It + treats the keystore location that is passed to it at the command line as a + file name and converts it to a `FileInputStream`, from which it loads the + keystore information.)The `jarsigner` commands can read a keystore from any + location that can be specified with a URL. + + For `keytool` and `jarsigner`, you can specify a keystore type at the + command line, with the `-storetype` option. + + If you don't explicitly specify a keystore type, then the tools choose a + keystore implementation based on the value of the `keystore.type` property + specified in the security properties file. The security properties file is + called `java.security`, and resides in the security properties directory: + + - **Linux and macOS:** `java.home/lib/security` + + - **Windows:** `java.home\lib\security` + + Each tool gets the `keystore.type` value and then examines all the + currently installed providers until it finds one that implements a + keystores of that type. It then uses the keystore implementation from that + provider.The `KeyStore` class defines a static method named + `getDefaultType` that lets applications retrieve the value of the + `keystore.type` property. The following line of code creates an instance of + the default keystore type as specified in the `keystore.type` property: + + > `KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());` + + The default keystore type is `pkcs12`, which is a cross-platform keystore + based on the RSA PKCS12 Personal Information Exchange Syntax Standard. This + is specified by the following line in the security properties file: + + > `keystore.type=pkcs12` + + To have the tools utilize a keystore implementation other than the default, + you can change that line to specify a different keystore type. For example, + if you want to use the Oracle's `jks` keystore implementation, then change + the line to the following: + + > `keystore.type=jks` + + **Note:** + + Case doesn't matter in keystore type designations. For example, `JKS` would + be considered the same as `jks`. + +Certificate +: A certificate (or public-key certificate) is a digitally signed statement + from one entity (the issuer), saying that the public key and some other + information of another entity (the subject) has some specific value. The + following terms are related to certificates: + + - Public Keys: These are numbers associated with a particular entity, and + are intended to be known to everyone who needs to have trusted + interactions with that entity. Public keys are used to verify + signatures. + + - Digitally Signed: If some data is digitally signed, then it is stored + with the identity of an entity and a signature that proves that entity + knows about the data. The data is rendered unforgeable by signing with + the entity's private key. + + - Identity: A known way of addressing an entity. In some systems, the + identity is the public key, and in others it can be anything from an + Oracle Solaris UID to an email address to an X.509 distinguished name. + + - Signature: A signature is computed over some data using the private key + of an entity. The signer, which in the case of a certificate is also + known as the issuer. + + - Private Keys: These are numbers, each of which is supposed to be known + only to the particular entity whose private key it is (that is, it is + supposed to be kept secret). Private and public keys exist in pairs in + all public key cryptography systems (also referred to as public key + crypto systems). In a typical public key crypto system, such as DSA, a + private key corresponds to exactly one public key. Private keys are + used to compute signatures. + + - Entity: An entity is a person, organization, program, computer, + business, bank, or something else you are trusting to some degree. + + Public key cryptography requires access to users' public keys. In a + large-scale networked environment, it is impossible to guarantee that prior + relationships between communicating entities were established or that a + trusted repository exists with all used public keys. Certificates were + invented as a solution to this public key distribution problem. Now a + Certification Authority (CA) can act as a trusted third party. CAs are + entities such as businesses that are trusted to sign (issue) certificates + for other entities. It is assumed that CAs only create valid and reliable + certificates because they are bound by legal agreements. There are many + public Certification Authorities, such as DigiCert, Comodo, Entrust, and so + on. + + You can also run your own Certification Authority using products such as + Microsoft Certificate Server or the Entrust CA product for your + organization. With the `keytool` command, it is possible to display, + import, and export certificates. It is also possible to generate + self-signed certificates. + + The `keytool` command currently handles X.509 certificates. + +X.509 Certificates +: The X.509 standard defines what information can go into a certificate and + describes how to write it down (the data format). All the data in a + certificate is encoded with two related standards called ASN.1/DER. + Abstract Syntax Notation 1 describes data. The Definite Encoding Rules + describe a single way to store and transfer that data. + + All X.509 certificates have the following data, in addition to the + signature: + + - Version: This identifies which version of the X.509 standard applies to + this certificate, which affects what information can be specified in + it. Thus far, three versions are defined. The `keytool` command can + import and export v1, v2, and v3 certificates. It generates v3 + certificates. + + - X.509 Version 1 has been available since 1988, is widely deployed, + and is the most generic. + + - X.509 Version 2 introduced the concept of subject and issuer unique + identifiers to handle the possibility of reuse of subject or issuer + names over time. Most certificate profile documents strongly + recommend that names not be reused and that certificates shouldn't + make use of unique identifiers. Version 2 certificates aren't + widely used. + + - X.509 Version 3 is the most recent (1996) and supports the notion + of extensions where anyone can define an extension and include it + in the certificate. Some common extensions are: KeyUsage (limits + the use of the keys to particular purposes such as `signing-only`) + and AlternativeNames (allows other identities to also be associated + with this public key, for example. DNS names, email addresses, IP + addresses). Extensions can be marked critical to indicate that the + extension should be checked and enforced or used. For example, if a + certificate has the KeyUsage extension marked critical and set to + `keyCertSign`, then when this certificate is presented during SSL + communication, it should be rejected because the certificate + extension indicates that the associated private key should only be + used for signing certificates and not for SSL use. + + - Serial number: The entity that created the certificate is responsible + for assigning it a serial number to distinguish it from other + certificates it issues. This information is used in numerous ways. For + example, when a certificate is revoked its serial number is placed in a + Certificate Revocation List (CRL). + + - Signature algorithm identifier: This identifies the algorithm used by + the CA to sign the certificate. + + - Issuer name: The X.500 Distinguished Name of the entity that signed the + certificate. This is typically a CA. Using this certificate implies + trusting the entity that signed this certificate. In some cases, such + as root or top-level CA certificates, the issuer signs its own + certificate. + + - Validity period: Each certificate is valid only for a limited amount of + time. This period is described by a start date and time and an end date + and time, and can be as short as a few seconds or almost as long as a + century. The validity period chosen depends on a number of factors, + such as the strength of the private key used to sign the certificate, + or the amount one is willing to pay for a certificate. This is the + expected period that entities can rely on the public value, when the + associated private key has not been compromised. + + - Subject name: The name of the entity whose public key the certificate + identifies. This name uses the X.500 standard, so it is intended to be + unique across the Internet. This is the X.500 Distinguished Name (DN) + of the entity. For example, + + > `CN=Java Duke, OU=Java Software Division, O=Oracle Corporation, + C=US` + + These refer to the subject's common name (CN), organizational unit + (OU), organization (O), and country (C). + + - Subject public key information: This is the public key of the entity + being named with an algorithm identifier that specifies which public + key crypto system this key belongs to and any associated key + parameters. + +Certificate Chains +: The `keytool` command can create and manage keystore key entries that each + contain a private key and an associated certificate chain. The first + certificate in the chain contains the public key that corresponds to the + private key. + + When keys are first generated, the chain usually starts off containing a single + element, a self-signed certificate. See -genkeypair in **Commands**. A + self-signed certificate is one for which the issuer (signer) is the same as + the subject. The subject is the entity whose public key is being + authenticated by the certificate. When the `-genkeypair` command is called + to generate a new public/private key pair, it also wraps the public key + into a self-signed certificate (unless the `-signer` option is specified). + + Later, after a Certificate Signing Request (CSR) was generated with the + `-certreq` command and sent to a Certification Authority (CA), the response + from the CA is imported with `-importcert`, and the self-signed certificate + is replaced by a chain of certificates. At the bottom of the chain is the + certificate (reply) issued by the CA authenticating the subject's public + key. The next certificate in the chain is one that authenticates the CA's + public key. + + In many cases, this is a self-signed certificate, which is a certificate + from the CA authenticating its own public key, and the last certificate in + the chain. In other cases, the CA might return a chain of certificates. In + this case, the bottom certificate in the chain is the same (a certificate + signed by the CA, authenticating the public key of the key entry), but the + second certificate in the chain is a certificate signed by a different CA + that authenticates the public key of the CA you sent the CSR to. The next + certificate in the chain is a certificate that authenticates the second + CA's key, and so on, until a self-signed root certificate is reached. Each + certificate in the chain (after the first) authenticates the public key of + the signer of the previous certificate in the chain. + + Many CAs only return the issued certificate, with no supporting chain, + especially when there is a flat hierarchy (no intermediates CAs). In this + case, the certificate chain must be established from trusted certificate + information already stored in the keystore. + + A different reply format (defined by the PKCS \#7 standard) includes the + supporting certificate chain in addition to the issued certificate. Both + reply formats can be handled by the `keytool` command. + + The top-level (root) CA certificate is self-signed. However, the trust into + the root's public key doesn't come from the root certificate itself, but + from other sources such as a newspaper. This is because anybody could + generate a self-signed certificate with the distinguished name of, for + example, the DigiCert root CA. The root CA public key is widely known. The + only reason it is stored in a certificate is because this is the format + understood by most tools, so the certificate in this case is only used as a + vehicle to transport the root CA's public key. Before you add the root CA + certificate to your keystore, you should view it with the `-printcert` + option and compare the displayed fingerprint with the well-known + fingerprint obtained from a newspaper, the root CA's Web page, and so on. + +cacerts Certificates File +: A certificates file named `cacerts` resides in the security properties + directory: + + - **Linux and macOS:** *JAVA\_HOME*`/lib/security` + + - **Windows:** *JAVA\_HOME*`\lib\security` + + The `cacerts` file represents a system-wide keystore with CA certificates. + System administrators can configure and manage that file with the `keytool` + command by specifying `jks` as the keystore type. The `cacerts` keystore + file ships with a default set of root CA certificates. For Linux, macOS, and + Windows, you can list the default certificates with the following command: + + > `keytool -list -cacerts` + + The initial password of the `cacerts` keystore file is `changeit`. System + administrators should change that password and the default access + permission of that file upon installing the SDK. + + **Note:** + + It is important to verify your `cacerts` file. Because you trust the CAs in + the `cacerts` file as entities for signing and issuing certificates to + other entities, you must manage the `cacerts` file carefully. The `cacerts` + file should contain only certificates of the CAs you trust. It is your + responsibility to verify the trusted root CA certificates bundled in the + `cacerts` file and make your own trust decisions. + + To remove an untrusted CA certificate from the `cacerts` file, use the + `-delete` option of the `keytool` command. You can find the `cacerts` file + in the JDK's `$JAVA_HOME/lib/security` directory. Contact your system + administrator if you don't have permission to edit this file. + +Internet RFC 1421 Certificate Encoding Standard +: Certificates are often stored using the printable encoding format defined + by the Internet RFC 1421 standard, instead of their binary encoding. This + certificate format, also known as Base64 encoding, makes it easy to export + certificates to other applications by email or through some other + mechanism. + + Certificates read by the `-importcert` and `-printcert` commands can be in + either this format or binary encoded. The `-exportcert` command by default + outputs a certificate in binary encoding, but will instead output a + certificate in the printable encoding format, when the `-rfc` option is + specified. + + The `-list` command by default prints the SHA-256 fingerprint of a + certificate. If the `-v` option is specified, then the certificate is + printed in human-readable format. If the `-rfc` option is specified, then + the certificate is output in the printable encoding format. + + In its printable encoding format, the encoded certificate is bounded at the + beginning and end by the following text: + + ``` + -----BEGIN CERTIFICATE----- + + encoded certificate goes here. + + -----END CERTIFICATE----- + ``` + +X.500 Distinguished Names +: X.500 Distinguished Names are used to identify entities, such as those that + are named by the `subject` and `issuer` (signer) fields of X.509 + certificates. The `keytool` command supports the following subparts: + + - commonName: The common name of a person such as Susan Jones. + + - organizationUnit: The small organization (such as department or + division) name. For example, Purchasing. + + - localityName: The locality (city) name, for example, Palo Alto. + + - stateName: State or province name, for example, California. + + - country: Two-letter country code, for example, CH. + + When you supply a distinguished name string as the value of a `-dname` + option, such as for the `-genkeypair` command, the string must be in the + following format: + + > `CN=cName, OU=orgUnit, O=org, L=city, S=state, C=countryCode` + + All the following items represent actual values and the previous keywords + are abbreviations for the following: + + ``` + CN=commonName + OU=organizationUnit + O=organizationName + L=localityName + S=stateName + C=country + ``` + + A sample distinguished name string is: + + > `CN=Mark Smith, OU=Java, O=Oracle, L=Cupertino, S=California, C=US` + + A sample command using such a string is: + + > `keytool -genkeypair -dname "CN=Mark Smith, OU=Java, O=Oracle, + L=Cupertino, S=California, C=US" -alias mark -keyalg rsa` + + Case doesn't matter for the keyword abbreviations. For example, CN, cn, and + Cn are all treated the same. + + Order matters; each subcomponent must appear in the designated order. + However, it isn't necessary to have all the subcomponents. You can use a + subset, for example: + + > `CN=Smith, OU=Java, O=Oracle, C=US` + + If a distinguished name string value contains a comma, then the comma must + be escaped by a backslash (\\) character when you specify the string on a + command line, as in: + + > `cn=Jack, ou=Java\, Product Development, o=Oracle, c=US` + + It is never necessary to specify a distinguished name string on a command + line. When the distinguished name is needed for a command, but not supplied + on the command line, the user is prompted for each of the subcomponents. In + this case, a comma doesn't need to be escaped by a backslash (\\). + +## Warnings + +## Importing Trusted Certificates Warning + +**Important**: Be sure to check a certificate very carefully before importing +it as a trusted certificate. + +**Windows Example:** + +View the certificate first with the `-printcert` command or the `-importcert` +command without the `-noprompt` option. Ensure that the displayed certificate +fingerprints match the expected ones. For example, suppose someone sends or +emails you a certificate that you put it in a file named `\tmp\cert`. Before +you consider adding the certificate to your list of trusted certificates, you +can execute a `-printcert` command to view its fingerprints, as follows: + +``` + keytool -printcert -file \tmp\cert + Owner: CN=ll, OU=ll, O=ll, L=ll, S=ll, C=ll + Issuer: CN=ll, OU=ll, O=ll, L=ll, S=ll, C=ll + Serial Number: 59092b34 + Valid from: Thu Jun 24 18:01:13 PDT 2016 until: Wed Jun 23 17:01:13 PST 2016 + Certificate Fingerprints: + + SHA-1: 20:B6:17:FA:EF:E5:55:8A:D0:71:1F:E8:D6:9D:C0:37:13:0E:5E:FE + SHA-256: 90:7B:70:0A:EA:DC:16:79:92:99:41:FF:8A:FE:EB:90: + 17:75:E0:90:B2:24:4D:3A:2A:16:A6:E4:11:0F:67:A4 +``` + +**Linux Example:** + +View the certificate first with the `-printcert` command or the `-importcert` +command without the `-noprompt` option. Ensure that the displayed certificate +fingerprints match the expected ones. For example, suppose someone sends or +emails you a certificate that you put it in a file named `/tmp/cert`. Before +you consider adding the certificate to your list of trusted certificates, you +can execute a `-printcert` command to view its fingerprints, as follows: + +``` + keytool -printcert -file /tmp/cert + Owner: CN=ll, OU=ll, O=ll, L=ll, S=ll, C=ll + Issuer: CN=ll, OU=ll, O=ll, L=ll, S=ll, C=ll + Serial Number: 59092b34 + Valid from: Thu Jun 24 18:01:13 PDT 2016 until: Wed Jun 23 17:01:13 PST 2016 + Certificate Fingerprints: + + SHA-1: 20:B6:17:FA:EF:E5:55:8A:D0:71:1F:E8:D6:9D:C0:37:13:0E:5E:FE + SHA-256: 90:7B:70:0A:EA:DC:16:79:92:99:41:FF:8A:FE:EB:90: + 17:75:E0:90:B2:24:4D:3A:2A:16:A6:E4:11:0F:67:A4 +``` + +Then call or otherwise contact the person who sent the certificate and compare +the fingerprints that you see with the ones that they show. Only when the +fingerprints are equal is it guaranteed that the certificate wasn't replaced in +transit with somebody else's certificate such as an attacker's certificate. If +such an attack took place, and you didn't check the certificate before you +imported it, then you would be trusting anything the attacker signed, for +example, a JAR file with malicious class files inside. + +**Note:** + +It isn't required that you execute a `-printcert` command before importing a +certificate. This is because before you add a certificate to the list of +trusted certificates in the keystore, the `-importcert` command prints out the +certificate information and prompts you to verify it. You can then stop the +import operation. However, you can do this only when you call the `-importcert` +command without the `-noprompt` option. If the `-noprompt` option is specified, +then there is no interaction with the user. + +## Passwords Warning + +Most commands that operate on a keystore require the store password. Some +commands require a private/secret key password. Passwords can be specified on +the command line in the `-storepass` and `-keypass` options. However, a +password shouldn't be specified on a command line or in a script unless it is +for testing, or you are on a secure system. When you don't specify a required +password option on a command line, you are prompted for it. + +## Certificate Conformance Warning + +[Internet X.509 Public Key Infrastructure Certificate and Certificate +Revocation List (CRL) Profile](https://tools.ietf.org/rfc/rfc5280.txt) defined +a profile on conforming X.509 certificates, which includes what values and +value combinations are valid for certificate fields and extensions. + +The `keytool` command doesn't enforce all of these rules so it can generate +certificates that don't conform to the standard, such as self-signed +certificates that would be used for internal testing purposes. Certificates +that don't conform to the standard might be rejected by the JDK or other +applications. Users should ensure that they provide the correct options for +`-dname`, `-ext`, and so on. + +## Import a New Trusted Certificate + +Before you add the certificate to the keystore, the `keytool` command verifies +it by attempting to construct a chain of trust from that certificate to a +self-signed certificate (belonging to a root CA), using trusted certificates +that are already available in the keystore. + +If the `-trustcacerts` option was specified, then additional certificates are +considered for the chain of trust, namely the certificates in a file named +`cacerts`. + +If the `keytool` command fails to establish a trust path from the certificate +to be imported up to a self-signed certificate (either from the keystore or the +`cacerts` file), then the certificate information is printed, and the user is +prompted to verify it by comparing the displayed certificate fingerprints with +the fingerprints obtained from some other (trusted) source of information, +which might be the certificate owner. Be very careful to ensure the certificate +is valid before importing it as a trusted certificate. The user then has the +option of stopping the import operation. If the `-noprompt` option is +specified, then there is no interaction with the user. + +## Import a Certificate Reply + +When you import a certificate reply, the certificate reply is validated with +trusted certificates from the keystore, and optionally, the certificates +configured in the `cacerts` keystore file when the `-trustcacerts` option is +specified. + +The methods of determining whether the certificate reply is trusted are as +follows: + +- If the reply is a single X.509 certificate, then the `keytool` command + attempts to establish a trust chain, starting at the certificate reply and + ending at a self-signed certificate (belonging to a root CA). The + certificate reply and the hierarchy of certificates is used to authenticate + the certificate reply from the new certificate chain of aliases. If a trust + chain can't be established, then the certificate reply isn't imported. In + this case, the `keytool` command doesn't print the certificate and prompt + the user to verify it, because it is very difficult for a user to determine + the authenticity of the certificate reply. + +- If the reply is a PKCS \#7 formatted certificate chain or a sequence of + X.509 certificates, then the chain is ordered with the user certificate + first followed by zero or more CA certificates. If the chain ends with a + self-signed root CA certificate and the`-trustcacerts` option was + specified, the `keytool` command attempts to match it with any of the + trusted certificates in the keystore or the `cacerts` keystore file. If the + chain doesn't end with a self-signed root CA certificate and the + `-trustcacerts` option was specified, the `keytool` command tries to find + one from the trusted certificates in the keystore or the `cacerts` keystore + file and add it to the end of the chain. If the certificate isn't found and + the `-noprompt` option isn't specified, the information of the last + certificate in the chain is printed, and the user is prompted to verify it. + +If the public key in the certificate reply matches the user's public key +already stored with `alias`, then the old certificate chain is replaced with +the new certificate chain in the reply. The old chain can only be replaced with +a valid `keypass`, and so the password used to protect the private key of the +entry is supplied. If no password is provided, and the private key password is +different from the keystore password, the user is prompted for it. + +This command was named `-import` in earlier releases. This old name is still +supported in this release. The new name, `-importcert`, is preferred. diff --git a/src/java.rmi/share/man/rmiregistry.1 b/src/java.rmi/share/man/rmiregistry.1 deleted file mode 100644 index c168e1482a6..00000000000 --- a/src/java.rmi/share/man/rmiregistry.1 +++ /dev/null @@ -1,100 +0,0 @@ -.\" Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved. -.\" DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -.\" -.\" This code is free software; you can redistribute it and/or modify it -.\" under the terms of the GNU General Public License version 2 only, as -.\" published by the Free Software Foundation. -.\" -.\" This code is distributed in the hope that it will be useful, but WITHOUT -.\" ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -.\" FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -.\" version 2 for more details (a copy is included in the LICENSE file that -.\" accompanied this code). -.\" -.\" You should have received a copy of the GNU General Public License version -.\" 2 along with this work; if not, write to the Free Software Foundation, -.\" Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -.\" -.\" Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -.\" or visit www.oracle.com if you need additional information or have any -.\" questions. -.\" -.\" Automatically generated by Pandoc 2.19.2 -.\" -.\" Define V font for inline verbatim, using C font in formats -.\" that render this, and otherwise B font. -.ie "\f[CB]x\f[R]"x" \{\ -. ftr V B -. ftr VI BI -. ftr VB B -. ftr VBI BI -.\} -.el \{\ -. ftr V CR -. ftr VI CI -. ftr VB CB -. ftr VBI CBI -.\} -.TH "RMIREGISTRY" "1" "2025" "JDK 24-ea" "JDK Commands" -.hy -.SH NAME -.PP -rmiregistry - create and start a remote object registry on the specified -port on the current host -.SH SYNOPSIS -.PP -\f[V]rmiregistry\f[R] [\f[I]options\f[R]] [\f[I]port\f[R]] -.TP -\f[I]options\f[R] -This represents the option for the \f[V]rmiregistry\f[R] command. -See \f[B]Options\f[R] -.TP -\f[I]port\f[R] -The number of a port on the current host at which to start the remote -object registry. -.SH DESCRIPTION -.PP -The \f[V]rmiregistry\f[R] command creates and starts a remote object -registry on the specified port on the current host. -If the port is omitted, then the registry is started on port 1099. -The \f[V]rmiregistry\f[R] command produces no output and is typically -run in the background, for example: -.RS -.PP -\f[V]rmiregistry &\f[R] -.RE -.PP -A remote object registry is a bootstrap naming service that\[aq]s used -by RMI servers on the same host to bind remote objects to names. -Clients on local and remote hosts can then look up remote objects and -make remote method invocations. -.PP -The registry is typically used to locate the first remote object on -which an application needs to call methods. -That object then provides application-specific support for finding other -objects. -.PP -The methods of the \f[V]java.rmi.registry.LocateRegistry\f[R] class are -used to get a registry operating on the local host or local host and -port. -.PP -The URL-based methods of the \f[V]java.rmi.Naming\f[R] class operate on -a registry and can be used to: -.IP \[bu] 2 -Bind the specified name to a remote object -.IP \[bu] 2 -Return an array of the names bound in the registry -.IP \[bu] 2 -Return a reference, a stub, for the remote object associated with the -specified name -.IP \[bu] 2 -Rebind the specified name to a new remote object -.IP \[bu] 2 -Destroy the binding for the specified name that\[aq]s associated with a -remote object -.SH OPTIONS -.TP -\f[V]-J\f[R]\f[I]option\f[R] -Used with any Java option to pass the \f[I]option\f[R] following the -\f[V]-J\f[R] (no spaces between the \f[V]-J\f[R] and the option) to the -Java interpreter. diff --git a/src/java.rmi/share/man/rmiregistry.md b/src/java.rmi/share/man/rmiregistry.md new file mode 100644 index 00000000000..48c426cfbdc --- /dev/null +++ b/src/java.rmi/share/man/rmiregistry.md @@ -0,0 +1,86 @@ +--- +# Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# This code is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 only, as +# published by the Free Software Foundation. +# +# This code is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# version 2 for more details (a copy is included in the LICENSE file that +# accompanied this code). +# +# You should have received a copy of the GNU General Public License version +# 2 along with this work; if not, write to the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +# or visit www.oracle.com if you need additional information or have any +# questions. +# + +title: 'RMIREGISTRY(1) JDK @@VERSION_SHORT@@ | JDK Commands' +date: @@COPYRIGHT_YEAR@@ +lang: en +--- + +## Name + +rmiregistry - create and start a remote object registry on the specified port +on the current host + +## Synopsis + +`rmiregistry` \[*options*\] \[*port*\] + +*options* +: This represents the option for the `rmiregistry` command. See + [Options] + +*port* +: The number of a port on the current host at which to start the remote + object registry. + +## Description + +The `rmiregistry` command creates and starts a remote object registry on the +specified port on the current host. If the port is omitted, then the registry +is started on port 1099. The `rmiregistry` command produces no output and is +typically run in the background, for example: + +> `rmiregistry &` + +A remote object registry is a bootstrap naming service that's used by RMI +servers on the same host to bind remote objects to names. Clients on local and +remote hosts can then look up remote objects and make remote method +invocations. + +The registry is typically used to locate the first remote object on which an +application needs to call methods. That object then provides +application-specific support for finding other objects. + +The methods of the `java.rmi.registry.LocateRegistry` class are used to get a +registry operating on the local host or local host and port. + +The URL-based methods of the `java.rmi.Naming` class operate on a registry and +can be used to: + +- Bind the specified name to a remote object + +- Return an array of the names bound in the registry + +- Return a reference, a stub, for the remote object associated with the + specified name + +- Rebind the specified name to a new remote object + +- Destroy the binding for the specified name that's associated with a remote + object + +## Options + +`-J`*option* +: Used with any Java option to pass the *option* following the `-J` (no + spaces between the `-J` and the option) to the Java interpreter. diff --git a/src/java.scripting/share/man/jrunscript.1 b/src/java.scripting/share/man/jrunscript.1 deleted file mode 100644 index 491c3cb3be3..00000000000 --- a/src/java.scripting/share/man/jrunscript.1 +++ /dev/null @@ -1,166 +0,0 @@ -.\" Copyright (c) 2006, 2024, Oracle and/or its affiliates. All rights reserved. -.\" DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -.\" -.\" This code is free software; you can redistribute it and/or modify it -.\" under the terms of the GNU General Public License version 2 only, as -.\" published by the Free Software Foundation. -.\" -.\" This code is distributed in the hope that it will be useful, but WITHOUT -.\" ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -.\" FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -.\" version 2 for more details (a copy is included in the LICENSE file that -.\" accompanied this code). -.\" -.\" You should have received a copy of the GNU General Public License version -.\" 2 along with this work; if not, write to the Free Software Foundation, -.\" Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -.\" -.\" Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -.\" or visit www.oracle.com if you need additional information or have any -.\" questions. -.\" -.\" Automatically generated by Pandoc 2.19.2 -.\" -.\" Define V font for inline verbatim, using C font in formats -.\" that render this, and otherwise B font. -.ie "\f[CB]x\f[R]"x" \{\ -. ftr V B -. ftr VI BI -. ftr VB B -. ftr VBI BI -.\} -.el \{\ -. ftr V CR -. ftr VI CI -. ftr VB CB -. ftr VBI CBI -.\} -.TH "JRUNSCRIPT" "1" "2025" "JDK 24-ea" "JDK Commands" -.hy -.SH NAME -.PP -jrunscript - run a command-line script shell that supports interactive -and batch modes -.SH SYNOPSIS -.PP -\f[B]Note:\f[R] -.PP -This tool is \f[B]experimental\f[R] and unsupported. -It is deprecated and will be removed in a future release. -.PP -\f[V]jrunscript\f[R] [\f[I]options\f[R]] [\f[I]arguments\f[R]] -.TP -\f[I]options\f[R] -This represents the \f[V]jrunscript\f[R] command-line options that can -be used. -See \f[B]Options for the jrunscript Command\f[R]. -.TP -\f[I]arguments\f[R] -Arguments, when used, follow immediately after options or the command -name. -See \f[B]Arguments\f[R]. -.SH DESCRIPTION -.PP -The \f[V]jrunscript\f[R] command is a language-independent command-line -script shell. -The \f[V]jrunscript\f[R] command supports both an interactive -(read-eval-print) mode and a batch (\f[V]-f\f[R] option) mode of script -execution. -By default, JavaScript is the language used, but the \f[V]-l\f[R] option -can be used to specify a different language. -By using Java to scripting language communication, the -\f[V]jrunscript\f[R] command supports an exploratory programming style. -.PP -If JavaScript is used, then before it evaluates a user defined script, -the \f[V]jrunscript\f[R] command initializes certain built-in functions -and objects, which are documented in the API Specification for -\f[V]jrunscript\f[R] JavaScript built-in functions. -.SH OPTIONS FOR THE JRUNSCRIPT COMMAND -.TP -\f[V]-cp\f[R] \f[I]path\f[R] or \f[V]-classpath\f[R] \f[I]path\f[R] -Indicates where any class files are that the script needs to access. -.TP -\f[V]-D\f[R]\f[I]name\f[R]\f[V]=\f[R]\f[I]value\f[R] -Sets a Java system property. -.TP -\f[V]-J\f[R]\f[I]flag\f[R] -Passes \f[I]flag\f[R] directly to the Java Virtual Machine where the -\f[V]jrunscript\f[R] command is running. -.TP -\f[V]-l\f[R] \f[I]language\f[R] -Uses the specified scripting language. -By default, JavaScript is used. -To use other scripting languages, you must specify the corresponding -script engine\[aq]s JAR file with the \f[V]-cp\f[R] or -\f[V]-classpath\f[R] option. -.TP -\f[V]-e\f[R] \f[I]script\f[R] -Evaluates the specified script. -This option can be used to run one-line scripts that are specified -completely on the command line. -.TP -\f[V]-encoding\f[R] \f[I]encoding\f[R] -Specifies the character encoding used to read script files. -.TP -\f[V]-f\f[R] \f[I]script-file\f[R] -Evaluates the specified script file (batch mode). -.TP -\f[V]-f -\f[R] -Enters interactive mode to read and evaluate a script from standard -input. -.TP -\f[V]-help\f[R] or \f[V]-?\f[R] -Displays a help message and exits. -.TP -\f[V]-q\f[R] -Lists all script engines available and exits. -.SH ARGUMENTS -.PP -If arguments are present and if no \f[V]-e\f[R] or \f[V]-f\f[R] option -is used, then the first argument is the script file and the rest of the -arguments, if any, are passed as script arguments. -If arguments and the \f[V]-e\f[R] or the \f[V]-f\f[R] option are used, -then all arguments are passed as script arguments. -If arguments \f[V]-e\f[R] and \f[V]-f\f[R] are missing, then the -interactive mode is used. -.SH EXAMPLE OF EXECUTING INLINE SCRIPTS -.RS -.PP -\f[V]jrunscript -e \[dq]print(\[aq]hello world\[aq])\[dq]\f[R] -.RE -.RS -.PP -\f[V]jrunscript -e \[dq]cat(\[aq]http://www.example.com\[aq])\[dq]\f[R] -.RE -.SH EXAMPLE OF USING SPECIFIED LANGUAGE AND EVALUATE THE SCRIPT FILE -.RS -.PP -\f[V]jrunscript -l js -f test.js\f[R] -.RE -.SH EXAMPLE OF INTERACTIVE MODE -.IP -.nf -\f[CB] -jrunscript -js> print(\[aq]Hello World\[rs]n\[aq]); -Hello World -js> 34 + 55 -89.0 -js> t = new java.lang.Thread(function() { print(\[aq]Hello World\[rs]n\[aq]); }) -Thread[Thread-0,5,main] -js> t.start() -js> Hello World - -js> -\f[R] -.fi -.SH RUN SCRIPT FILE WITH SCRIPT ARGUMENTS -.PP -In this example, the \f[V]test.js\f[R] file is the script file. -The \f[V]arg1\f[R], \f[V]arg2\f[R], and \f[V]arg3\f[R] arguments are -passed to the script. -The script can access these arguments with an arguments array. -.RS -.PP -\f[V]jrunscript test.js arg1 arg2 arg3\f[R] -.RE diff --git a/src/java.scripting/share/man/jrunscript.md b/src/java.scripting/share/man/jrunscript.md new file mode 100644 index 00000000000..85ace0c32ee --- /dev/null +++ b/src/java.scripting/share/man/jrunscript.md @@ -0,0 +1,141 @@ +--- +# Copyright (c) 2006, 2024, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# This code is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 only, as +# published by the Free Software Foundation. +# +# This code is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# version 2 for more details (a copy is included in the LICENSE file that +# accompanied this code). +# +# You should have received a copy of the GNU General Public License version +# 2 along with this work; if not, write to the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +# or visit www.oracle.com if you need additional information or have any +# questions. +# + +title: 'JRUNSCRIPT(1) JDK @@VERSION_SHORT@@ | JDK Commands' +date: @@COPYRIGHT_YEAR@@ +lang: en +--- + +## Name + +jrunscript - run a command-line script shell that supports interactive and +batch modes + +## Synopsis + +**Note:** + +This tool is **experimental** and unsupported. It is deprecated and will be +removed in a future release. + +`jrunscript` \[*options*\] \[*arguments*\] + +*options* +: This represents the `jrunscript` command-line options that can be used. See + [Options for the jrunscript Command]. + +*arguments* +: Arguments, when used, follow immediately after options or the command name. + See [Arguments]. + +## Description + +The `jrunscript` command is a language-independent command-line script shell. +The `jrunscript` command supports both an interactive (read-eval-print) mode +and a batch (`-f` option) mode of script execution. By default, JavaScript is +the language used, but the `-l` option can be used to specify a different +language. By using Java to scripting language communication, the `jrunscript` +command supports an exploratory programming style. + +If JavaScript is used, then before it evaluates a user defined script, the +`jrunscript` command initializes certain built-in functions and objects, which +are documented in the API Specification for `jrunscript` JavaScript built-in +functions. + +## Options for the jrunscript Command + +`-cp` *path* or `-classpath` *path* +: Indicates where any class files are that the script needs to access. + +`-D`*name*`=`*value* +: Sets a Java system property. + +`-J`*flag* +: Passes *flag* directly to the Java Virtual Machine where the `jrunscript` + command is running. + +`-l` *language* +: Uses the specified scripting language. By default, JavaScript is used. To + use other scripting languages, you must specify the corresponding script + engine's JAR file with the `-cp` or `-classpath` option. + +`-e` *script* +: Evaluates the specified script. This option can be used to run one-line + scripts that are specified completely on the command line. + +`-encoding` *encoding* +: Specifies the character encoding used to read script files. + +`-f` *script-file* +: Evaluates the specified script file (batch mode). + +`-f -` +: Enters interactive mode to read and evaluate a script from standard input. + +`-help` or `-?` +: Displays a help message and exits. + +`-q` +: Lists all script engines available and exits. + +## Arguments + +If arguments are present and if no `-e` or `-f` option is used, then the first +argument is the script file and the rest of the arguments, if any, are passed +as script arguments. If arguments and the `-e` or the `-f` option are used, +then all arguments are passed as script arguments. If arguments `-e` and `-f` +are missing, then the interactive mode is used. + +## Example of Executing Inline Scripts + +> `jrunscript -e "print('hello world')"` + +> `jrunscript -e "cat('http://www.example.com')"` + +## Example of Using Specified Language and Evaluate the Script File + +> `jrunscript -l js -f test.js` + +## Example of Interactive Mode + +``` +jrunscript +js> print('Hello World\n'); +Hello World +js> 34 + 55 +89.0 +js> t = new java.lang.Thread(function() { print('Hello World\n'); }) +Thread[Thread-0,5,main] +js> t.start() +js> Hello World + +js> +``` + +## Run Script File with Script Arguments + +In this example, the `test.js` file is the script file. The `arg1`, `arg2`, and +`arg3` arguments are passed to the script. The script can access these +arguments with an arguments array. + +> `jrunscript test.js arg1 arg2 arg3` diff --git a/src/java.security.jgss/windows/man/kinit.md b/src/java.security.jgss/windows/man/kinit.md new file mode 100644 index 00000000000..03605667ae9 --- /dev/null +++ b/src/java.security.jgss/windows/man/kinit.md @@ -0,0 +1,154 @@ +--- +# Copyright (c) 2005, 2019, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# This code is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 only, as +# published by the Free Software Foundation. +# +# This code is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# version 2 for more details (a copy is included in the LICENSE file that +# accompanied this code). +# +# You should have received a copy of the GNU General Public License version +# 2 along with this work; if not, write to the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +# or visit www.oracle.com if you need additional information or have any +# questions. +# + +title: 'KINIT(1) JDK @@VERSION_SHORT@@ | JDK Commands' +date: @@COPYRIGHT_YEAR@@ +lang: en +--- + +## Name + +kinit - obtain and cache Kerberos ticket-granting tickets + +## Synopsis + +Initial ticket request: + +`kinit` \[`-A`\] \[`-f`\] \[`-p`\] \[`-c` *cache\_name*\] \[`-l` *lifetime*\] +\[`-r` *renewable\_time*\] \[\[`-k` \[`-t` *keytab\_file\_name*\]\] +\[*principal*\] \[*password*\] + +Renew a ticket: + +`kinit` `-R` \[`-c` *cache\_name*\] \[*principal*\] + +## Description + +This tool is similar in functionality to the `kinit` tool that is commonly +found in other Kerberos implementations, such as SEAM and MIT Reference +implementations. The user must be registered as a principal with the Key +Distribution Center (KDC) prior to running `kinit`. + +By default, on Windows, a cache file named *USER\_HOME*`\krb5cc_`*USER\_NAME* +is generated. + +The identifier *USER\_HOME* is obtained from the `java.lang.System` property +`user.home`. *USER\_NAME* is obtained from the `java.lang.System` property +`user.name`. If *USER\_HOME* is null, the cache file is stored in the current +directory from which the program is running. *USER\_NAME* is the operating +system's login user name. This user name could be different than the user's +principal name. For example, on Windows, the cache file could be +`C:\Windows\Users\duke\krb5cc_duke`, in which `duke` is the *USER\_NAME* and +`C:\Windows\Users\duke` is the *USER\_HOME*. + +By default, the keytab name is retrieved from the Kerberos configuration file. +If the keytab name isn't specified in the Kerberos configuration file, the +kinit tool assumes that the name is *USER\_HOME*`\krb5.keytab` + +If you don't specify the password using the *password* option on the command +line, the `kinit` tool prompts you for the password. + +**Note:** + +The `password` option is provided only for testing purposes. Don't specify your +password in a script or provide your password on the command line. Doing so +will compromise your password. + +## Commands + +You can specify one of the following commands. After the command, specify the +options for it. + +`-A` +: Doesn't include addresses. + +`-f` +: Issues a forwardable ticket. + +`-p` +: Issues a proxiable ticket. + +`-c` *cache\_name* +: The cache name (for example, `FILE:D:\temp\mykrb5cc`). + +`-l` *lifetime* +: Sets the lifetime of a ticket. The value can be one of "h:m[:s]", + "NdNhNmNs", and "N". See the [MIT krb5 Time Duration definition]( + http://web.mit.edu/kerberos/krb5-1.17/doc/basic/date_format.html#duration) + for more information. + +`-r` *renewable\_time* +: Sets the total lifetime that a ticket can be renewed. + +`-R` +: Renews a ticket. + +`-k` +: Uses keytab + +`-t` *keytab\_filename* +: The keytab name (for example, `D:\winnt\profiles\duke\krb5.keytab`). + +*principal* +: The principal name (for example, `duke@example.com`). + +*password* +: The *principal*'s Kerberos password. **Don't specify this on the command + line or in a script.** + +Run `kinit -help` to display the instructions above. + +## Examples + +Requests credentials valid for authentication from the current client host, for +the default services, storing the credentials cache in the default location +(`C:\Windows\Users\duke\krb5cc_duke`): + +> `kinit duke@example.com` + +Requests proxiable credentials for a different principal and store these +credentials in a specified file cache: + +> `kinit -l 1h -r 10h duke@example.com` + +Requests a TGT for the specified principal that will expire in 1 hour but +is renewable for up to 10 hours. Users must renew a ticket before it has +expired. The renewed ticket can be renewed repeatedly within 10 hours +from its initial request. + +> `kinit -R duke@example.com` + +Renews an existing renewable TGT for the specified principal. + +> `kinit -p -c FILE:C:\Windows\Users\duke\credentials\krb5cc_cafebeef + cafebeef@example.com` + +Requests proxiable and forwardable credentials for a different principal and +stores these credentials in a specified file cache: + +> `kinit -f -p -c FILE:C:\Windows\Users\duke\credentials\krb5cc_cafebeef + cafebeef@example.com` + +Displays the help menu for the `kinit` tool: + +> `kinit -help` diff --git a/src/java.security.jgss/windows/man/klist.md b/src/java.security.jgss/windows/man/klist.md new file mode 100644 index 00000000000..be9e26abe0f --- /dev/null +++ b/src/java.security.jgss/windows/man/klist.md @@ -0,0 +1,98 @@ +--- +# Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# This code is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 only, as +# published by the Free Software Foundation. +# +# This code is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# version 2 for more details (a copy is included in the LICENSE file that +# accompanied this code). +# +# You should have received a copy of the GNU General Public License version +# 2 along with this work; if not, write to the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +# or visit www.oracle.com if you need additional information or have any +# questions. +# + +title: 'KLIST(1) JDK @@VERSION_SHORT@@ | JDK Commands' +date: @@COPYRIGHT_YEAR@@ +lang: en +--- + +## Name + +klist - display the entries in the local credentials cache and key table + +## Synopsis + +`klist` \[`-c` \[`-f`\] \[`-e`\] \[`-a` \[`-n`\]\]\] \[`-k` \[`-t`\] \[`-K`\]\] +\[*name*\] \[`-help`\] + +## Description + +The `klist` tool displays the entries in the local credentials cache and key +table. After you modify the credentials cache with the `kinit` tool or modify +the keytab with the `ktab` tool, the only way to verify the changes is to view +the contents of the credentials cache or keytab using the `klist` tool. The +`klist` tool doesn't change the Kerberos database. + +## Commands + +`-c` +: Specifies that the credential cache is to be listed. + + The following are the options for credential cache entries: + + `-f` + : Show credential flags. + + `-e` + : Show the encryption type. + + `-a` + : Show addresses. + + `-n` + : If the `-a` option is specified, don't reverse resolve addresses. + +`-k` +: Specifies that key tab is to be listed. + + List the keytab entries. The following are the options for keytab entries: + + `-t` + : Show keytab entry timestamps. + + `-K` + : Show keytab entry DES keys. + + `-e` + : Shows keytab entry key type. + +*name* +: Specifies the credential cache name or the keytab name. File-based cache or + keytab's prefix is `FILE:`. If the name isn't specified, the `klist` tool + uses default values for the cache name and keytab. The `kinit` + documentation lists these default values. + +`-help` +: Displays instructions. + +## Examples + +List entries in the keytable specified including keytab entry timestamps and +DES keys: + +> `klist -k -t -K FILE:\temp\mykrb5cc` + +List entries in the credentials cache specified including credentials flag and +address list: + +> `klist -c -f FILE:\temp\mykrb5cc` diff --git a/src/java.security.jgss/windows/man/ktab.md b/src/java.security.jgss/windows/man/ktab.md new file mode 100644 index 00000000000..ac8a6d4a0ec --- /dev/null +++ b/src/java.security.jgss/windows/man/ktab.md @@ -0,0 +1,134 @@ +--- +# Copyright (c) 2005, 2022, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# This code is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 only, as +# published by the Free Software Foundation. +# +# This code is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# version 2 for more details (a copy is included in the LICENSE file that +# accompanied this code). +# +# You should have received a copy of the GNU General Public License version +# 2 along with this work; if not, write to the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +# or visit www.oracle.com if you need additional information or have any +# questions. +# + +title: 'KTAB(1) JDK @@VERSION_SHORT@@ | JDK Commands' +date: @@COPYRIGHT_YEAR@@ +lang: en +--- + +## Name + +ktab - manage the principal names and service keys stored in a local key +table + +## Synopsis + +`ktab` \[*commands*\] \[*options*\] + +\[*commands*\] \[*options*\] +: Lists the keytab name and entries, adds new key entries to the keytab, + deletes existing key entries, and displays instructions. See [Commands and + Options]. + +## Description + +The `ktab` enables the user to manage the principal names and service keys +stored in a local key table. Principal and key pairs listed in the keytab +enable services running on a host to authenticate themselves to the Key +Distribution Center (KDC). + +Before configuring a server to use Kerberos, you must set up a keytab on the +host running the server. Note that any updates made to the keytab using the +`ktab` tool don't affect the Kerberos database. + +A *keytab* is a host's copy of its own keylist, which is analogous to a user's +password. An application server that needs to authenticate itself to the Key +Distribution Center (KDC) must have a keytab which contains its own principal +and key. If you change the keys in the keytab, you must also make the +corresponding changes to the Kerberos database. The `ktab` tool enables you to +list, add, update or delete principal names and key pairs in the key table. +None of these operations affect the Kerberos database. + +## Security Alert + +Don't specify your password on the command line. Doing so can be a security +risk. For example, an attacker could discover your password while running the +UNIX `ps` command. + +Just as it is important for users to protect their passwords, it is equally +important for hosts to protect their keytabs. You should always store keytab +files on the local disk and make them readable only by root. You should never +send a keytab file over a network in the clear. + +## Commands and Options + +`-l` \[`-e`\] \[`-t`\] +: Lists the keytab name and entries. When `-e` is specified, the encryption + type for each entry is displayed. When `-t` is specified, the timestamp for + each entry is displayed. + +`-a` *principal\_name* \[*password*\] \[`-n` *kvno*\] \[`-s` *salt* \| `-f`\] \[`-append`\] +: Adds new key entries to the keytab for the given principal name with an + optional *password*. If a *kvno* is specified, new keys' Key Version + Numbers equal to the value, otherwise, automatically incrementing the Key + Version Numbers. If *salt* is specified, it will be used instead of the + default salt. If `-f` is specified, the KDC will be contacted to + fetch the salt. If `-append` is specified, new keys are appended to the + keytab, otherwise, old keys for the same principal are removed. + + No changes are made to the Kerberos database. **Don't specify the password + on the command line or in a script.** This tool will prompt for a password + if it isn't specified. + +`-d` *principal\_name* \[`-f`\] \[`-e` *etype*\] \[*kvno* \| `all`\| `old`\] +: Deletes key entries from the keytab for the specified principal. No changes + are made to the Kerberos database. + + - If *kvno* is specified, the tool deletes keys whose Key Version Numbers + match kvno. If `all` is specified, delete all keys. + + - If `old` is specified, the tool deletes all keys except those with the + highest *kvno*. The default action is `all`. + + - If *etype* is specified, the tool only deletes keys of this encryption + type. *etype* should be specified as the numeric value *etype* defined + in RFC 3961, section 8. A prompt to confirm the deletion is displayed + unless `-f` is specified. + + When *etype* is provided, only the entry matching this encryption type is + deleted. Otherwise, all entries are deleted. + +`-help` +: Displays instructions. + +## Common Options + +This option can be used with the `-l`, `-a` or `-d` commands. + +`-k` *keytab name* +: Specifies the keytab name and path with the `FILE:` prefix. + +## Examples + +- Lists all the entries in the default keytable + + > `ktab -l` + +- Adds a new principal to the key table (note that you will be prompted for + your password) + + > `ktab -a duke@example.com` + +- Deletes a principal from the key table + + > `ktab -d duke@example.com` diff --git a/src/jdk.accessibility/windows/man/jabswitch.md b/src/jdk.accessibility/windows/man/jabswitch.md new file mode 100644 index 00000000000..8dfdd6f2737 --- /dev/null +++ b/src/jdk.accessibility/windows/man/jabswitch.md @@ -0,0 +1,75 @@ +--- +# Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# This code is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 only, as +# published by the Free Software Foundation. +# +# This code is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# version 2 for more details (a copy is included in the LICENSE file that +# accompanied this code). +# +# You should have received a copy of the GNU General Public License version +# 2 along with this work; if not, write to the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +# or visit www.oracle.com if you need additional information or have any +# questions. +# + +title: 'JABSWITCH(1) JDK @@VERSION_SHORT@@ | JDK Commands' +date: @@COPYRIGHT_YEAR@@ +lang: en +--- + +## Name + +jabswitch - enable or disable the Java Access Bridge + +## Synopsis + +`jabswitch` \[ -enable|/enable | -disable|/disable | -version|/version | -?|/? \] + +## Options + +`-enable` +or +`/enable` +: Enables the Java Access Bridge + +`-disable` +or +`/disable` +: Disables the Java Access Bridge + +`-version` +or +`/version` +: Displays version information for the `jabswitch` command. + +`-?` +or +`/?` +: Displays usage information for the `jabswitch` command. + +## Description + +The `jabswitch` command is a utility program that enables the +Java Access Bridge to be loaded by the JDK on Windows platforms. +The Java Access Bridge is used by Assistive Technologies +to interact with Java Accessibility APIs of the Java SE platform. +To have any effect, the assistive technology must support the Java Access Bridge. + +This command creates or updates a file named `.accessibility.properties`, +in the user's home directory. When selecting the `-enable` option, the file +is populated with the information needed to load the Java Access Bridge. +This file is then read and used in accordance with the specification of the +Java SE +[`java.awt.Toolkit.getDefaultToolkit()`](../../api/java.desktop/java/awt/Toolkit.html#getDefaultToolkit()) +API, on initialization. + +Note: This command is only provided with JDK for Windows. diff --git a/src/jdk.accessibility/windows/man/jaccessinspector.md b/src/jdk.accessibility/windows/man/jaccessinspector.md new file mode 100644 index 00000000000..17f44cef358 --- /dev/null +++ b/src/jdk.accessibility/windows/man/jaccessinspector.md @@ -0,0 +1,249 @@ +--- +# Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# This code is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 only, as +# published by the Free Software Foundation. +# +# This code is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# version 2 for more details (a copy is included in the LICENSE file that +# accompanied this code). +# +# You should have received a copy of the GNU General Public License version +# 2 along with this work; if not, write to the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +# or visit www.oracle.com if you need additional information or have any +# questions. +# + +title: 'JACCESSINSPECTOR(1) JDK @@VERSION_SHORT@@ | JDK Commands' +date: @@COPYRIGHT_YEAR@@ +lang: en +--- + +## Name + +jaccessinspector - examine accessible information about the objects in the +Java Virtual Machine using the Java Accessibility Utilities API + +## Description + +The `jaccessinspector` tool lets you select different methods for examining the +object accessibility information: + +- When events occur such as a change of focus, mouse movement, property + change, menu selection, and the display of a popup menu + +- When you press the F1 key when the mouse is over an object, or F2 when the + mouse is over a window + +After an object has been selected for examination, the `jaccessinspector` tool +displays the results of calling Java Accessibility API methods on that object. + +## Running the jaccessinspector Tool + +To use the `jaccessinspector` tool, launch the `jaccessinspector` tool after +launching a Java application. To launch `jaccessinspector`, run the following +command: + +**Note:** + +`JAVA_HOME` is an environment variable and should be set to the path of the JDK +or JRE, such as `c:\Program Files\Java\jdk-10`. + +> `%JAVA_HOME%\bin\jaccessinspector.exe` + +You now have two windows open: The Java application window and the +`jaccessinspector` window. The `jaccessinspector` window contains five menus: + +- [File Menu] + +- [UpdateSettings Menu] + +- [JavaEvents Menu] + +- [AccessibilityEvents Menu] + +- [Options Menu] + +The items in **UpdateSettings**, **JavaEvents**, and **AccessibilityEvents** +menus let you query Java applications in a variety of ways. + +## File Menu + +This section describes the **File** menu items. + +AccessBridge DLL Loaded +: Enables and disables AccessBridge DLL Loaded. + +Exit +: Exits from the tool. + +## UpdateSettings Menu + +This section describes the **UpdateSettings** menu items. + +Update from Mouse +: Determines the x- and y-coordinates of the mouse (assuming the + `jaccessinspector` tool window is topmost) when the mouse has stopped + moving, and then queries the Java application for the accessible object + underneath the mouse, dumping the output into the `jaccessinspector` + window. + +Update with F2 (Mouse HWND) +: Determines the x- and y-coordinates of the mouse (assuming the + `jaccessinspector` tool window is topmost), and then queries the Java + application for the accessible object of the HWND underneath the mouse, + dumping the output into the `jaccessinspector` window. + +Update with F1 (Mouse Point) +: Determines the x- and y-coordinates of the mouse (assuming the + `jaccessinspector` tool window is topmost), and then queries the Java + application for the accessible object underneath the cursor, dumping the + output into the `jaccessinspector` window. + +## JavaEvents Menu + +This section describes the **JavaEvents** menu items. + +Track Mouse Events +: Registers with the Java application all Java Mouse Entered events, and upon + receiving one, queries the object that was entered by the cursor and dumps + the output into the `jaccessinspector` window. + + **Note:** If the mouse is moved quickly, then there may be some delay + before the displayed information is updated. + +Track Focus Events +: Registers with the Java application all Java Focus Gained events, and upon + receiving an event, queries the object that received the focus and dumps + the output into the `jaccessinspector` window. + +Track Caret Events +: Register with the Java application all Java Caret Update events, and upon + receiving an event, queries the object in which the caret was updated, and + dumps the output into the `jaccessinspector` window. + + **Note:** Because objects that contain carets are almost by definition + objects that are rich text objects, this won't seem as responsive as the + other event tracking options. In real use, one would make fewer + accessibility calls in Caret Update situations (for example, just get the + new letter, word, sentence at the caret location), which would be + significantly faster. + +Track Menu Selected \| Deselected \| Cancelled Events +: Registers with the Java application all Menu events, and upon receiving an + event, queries the object in which the caret was updated, and dumps the + output into the `jaccessinspector` window. + +Track Popup Visible \| Invisible \| Cancelled Events +: Registers with the Java application all Popup Menu events, and upon + receiving an event, queries the object in which the caret was updated, and + dumps the output into the `jaccessinspector` window. + +Track Shutdown Events +: Registers with the Java application to receive a Property Changed event + when a Java application terminates. + +## AccessibilityEvents Menu + +This section describes the **AccessibilityEvents** menu items. + +**Note:** The items listed in the **AccessibilityEvents** menu are the most +important for testing applications, especially for assistive technology +applications. + +Track Name Property Events +: Registers with the Java application all Java Property Changed events + specifically on accessible objects in which the Name property has changed, + and upon receiving an event, dumps the output into the scrolling window, + along with information about the property that changed. + +Track Description Property Events +: Register with the Java application for all Java Property Changed events + specifically on accessible objects in which the Description property has + changed, and upon receiving an event, dumps the output into the + `jaccessinspector` window, along with information about the property that + changed. + +Track State Property Events +: Register with the Java application all Java Property Changed events + specifically on accessible objects in which the State property has changed, + and upon receiving an event, dumps the output into the `jaccessinspector` + window, along with information about the property that changed. + +Track Value Property Events +: Register with the Java application all Java Property Changed events + specifically on accessible objects in which the Value property has changed, + and upon receiving an event, dumps the output into the scrolling window, + along with information about the property that changed. + +Track Selection Property Events +: Register with the Java application all Java Property Changed events + specifically on accessible objects in which the Selection property has + changed, and upon receiving an event, dumps the output into the + `jaccessinspector` window, along with information about the property that + changed. + +Track Text Property Events +: Register with the Java application all Java Property Changed events + specifically on accessible objects in which the Text property has changed, + and upon receiving one event, dump the output into the `jaccessinspector` + window, along with information about the property that changed. + +Track Caret Property Events +: Register with the Java application all Java Property Changed events + specifically on accessible objects in which the Caret property has changed, + and upon receiving an event, dumps the output into the `jaccessinspector` + window, along with information about the property that changed. + +Track VisibleData Property Events +: Register with the Java application all Java Property Changed events + specifically on accessible objects in which the VisibleData property has + changed, and upon receiving an event, dumps the output into the + `jaccessinspector` window, along with information about the property that + changed. + +Track Child Property Events +: Register with the Java application all Java Property Changed events + specifically on accessible objects in which the Child property has changed, + and upon receiving an event, dumps the output into the `jaccessinspector` + window, along with information about the property that changed. + +Track Active Descendent Property Events +: Register with the Java application all Java Property Changed events + specifically on accessible objects in which the Active Descendent property + has changed, and upon receiving an event, dumps the output into the + `jaccessinspector` window, along with information about the property that + changed. + +Track Table Model Change Property Events +: Register with the Java application all Property Changed events specifically + on accessible objects in which the Table Model Change property has changed, + and upon receiving an event, dumps the output into the `jaccessinspector` + window, along with information about the property that changed. + +## Options Menu + +This section describes the **Options** menu items. + +Monitor the same events as JAWS +: Enables monitoring of only the events also monitored by JAWS. + +Monitor All Events +: Enables monitoring of all events in the `jaccessinspector` window. + +Reset All Events +: Resets the selected Options to the default settings. + +Go To Message +: Opens the **Go To Message** dialog that lets you display a logged message + by entering its message number. + +Clear Message History +: Clears the history of logged messages from the `jaccessinspector` window. diff --git a/src/jdk.accessibility/windows/man/jaccesswalker.md b/src/jdk.accessibility/windows/man/jaccesswalker.md new file mode 100644 index 00000000000..f688ae57aee --- /dev/null +++ b/src/jdk.accessibility/windows/man/jaccesswalker.md @@ -0,0 +1,71 @@ +--- +# Copyright (c) 2017, 2018, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# This code is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 only, as +# published by the Free Software Foundation. +# +# This code is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# version 2 for more details (a copy is included in the LICENSE file that +# accompanied this code). +# +# You should have received a copy of the GNU General Public License version +# 2 along with this work; if not, write to the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +# or visit www.oracle.com if you need additional information or have any +# questions. +# + +title: 'JACCESSWALKER(1) JDK @@VERSION_SHORT@@ | JDK Commands' +date: @@COPYRIGHT_YEAR@@ +lang: en +--- + +## Name + +jaccesswalker - navigate through the component trees in a particular Java +Virtual Machine and present the hierarchy in a tree view + +## Description + +You select a node in the tree, and from the **Panels** menu, you select +**Accessibility API Panel**. The `jaccesswalker` tool shows you the +accessibility information for the object in the window. + +## Running the jaccesswalker Tool + +To use `jaccesswalker`, launch the `jaccesswalker` tool after launching a Java +application. For example, to launch `jaccesswalker`, enter the following +command: + +**Note:** + +`JAVA_HOME` is an environment variable and should be set to the path of the JDK +or JRE, such as, `c:\Program Files\Java\jdk-10`. + +> `%JAVA_HOME%\bin\jaccesswalker.exe` + +You now have two windows open: The Java application window, and the window for +the `jaccesswalker` tool. There are two tasks that you can do with +`jaccesswalker` . You can build a tree view of the Java applications' GUI +hierarchy, and you can query the Java Accessibility API information of a +particular element in the GUI hierarchy. + +## Building the GUI Hierarchy + +From the **File** menu, select **Refresh Tree** menu. The `jaccesswalker` tool +builds a list of the top-level windows belonging to Java applications. The tool +then recursively queries the elements in those windows, and builds a tree of +all of the GUI components in all of the Java applications in all of the JVMs +running in the system. + +## Examining a GUI Component + +After a GUI tree is built, you can view detailed accessibility information +about an individual GUI component by selecting it in the tree, then selecting +**Panels**, and then **Display Accessibility Information**. diff --git a/src/jdk.compiler/share/man/javac.1 b/src/jdk.compiler/share/man/javac.1 deleted file mode 100644 index ebee0369238..00000000000 --- a/src/jdk.compiler/share/man/javac.1 +++ /dev/null @@ -1,2372 +0,0 @@ -.\" Copyright (c) 1994, 2023, Oracle and/or its affiliates. All rights reserved. -.\" DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -.\" -.\" This code is free software; you can redistribute it and/or modify it -.\" under the terms of the GNU General Public License version 2 only, as -.\" published by the Free Software Foundation. -.\" -.\" This code is distributed in the hope that it will be useful, but WITHOUT -.\" ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -.\" FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -.\" version 2 for more details (a copy is included in the LICENSE file that -.\" accompanied this code). -.\" -.\" You should have received a copy of the GNU General Public License version -.\" 2 along with this work; if not, write to the Free Software Foundation, -.\" Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -.\" -.\" Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -.\" or visit www.oracle.com if you need additional information or have any -.\" questions. -.\" -.\" Automatically generated by Pandoc 2.19.2 -.\" -.\" Define V font for inline verbatim, using C font in formats -.\" that render this, and otherwise B font. -.ie "\f[CB]x\f[R]"x" \{\ -. ftr V B -. ftr VI BI -. ftr VB B -. ftr VBI BI -.\} -.el \{\ -. ftr V CR -. ftr VI CI -. ftr VB CB -. ftr VBI CBI -.\} -.TH "JAVAC" "1" "2025" "JDK 24-ea" "JDK Commands" -.hy -.SH NAME -.PP -javac - read Java declarations and compile them into class files -.SH SYNOPSIS -.PP -\f[V]javac\f[R] [\f[I]options\f[R]] -[\f[I]sourcefiles-or-classnames\f[R]] -.TP -\f[I]options\f[R] -Command-line options. -.TP -\f[I]sourcefiles-or-classnames\f[R] -Source files to be compiled (for example, \f[V]Shape.java\f[R]) or the -names of previously compiled classes to be processed for annotations -(for example, \f[V]geometry.MyShape\f[R]). -.SH DESCRIPTION -.PP -The \f[V]javac\f[R] command reads \f[I]source files\f[R] that contain -module, package and type declarations written in the Java programming -language, and compiles them into \f[I]class files\f[R] that run on the -Java Virtual Machine. -.PP -The \f[V]javac\f[R] command can also \f[B]process annotations\f[R] in -Java source files and classes. -.PP -Source files must have a file name extension of \f[V].java\f[R]. -Class files have a file name extension of \f[V].class\f[R]. -Both source and class files normally have file names that identify the -contents. -For example, a class called \f[V]Shape\f[R] would be declared in a -source file called \f[V]Shape.java\f[R], and compiled into a class file -called \f[V]Shape.class\f[R]. -.PP -There are two ways to specify source files to \f[V]javac\f[R]: -.IP \[bu] 2 -For a small number of source files, you can list their file names on the -command line. -.IP \[bu] 2 -For a large number of source files, you can use the -\f[B]\f[VB]\[at]\f[B]\f[BI]filename\f[B]\f[R] option on the command line -to specify an \f[I]argument file\f[R] that lists their file names. -See \f[B]Standard Options\f[R] for a description of the option and -\f[B]Command-Line Argument Files\f[R] for a description of -\f[V]javac\f[R] argument files. -.PP -The order of source files specified on the command line or in an -argument file is not important. -\f[V]javac\f[R] will compile the files together, as a group, and will -automatically resolve any dependencies between the declarations in the -various source files. -.PP -\f[V]javac\f[R] expects that source files are arranged in one or more -directory hierarchies on the file system, described in \f[B]Arrangement -of Source Code\f[R]. -.PP -To compile a source file, \f[V]javac\f[R] needs to find the declaration -of every class or interface that is used, extended, or implemented by -the code in the source file. -This lets \f[V]javac\f[R] check that the code has the right to access -those classes and interfaces. -Rather than specifying the source files of those classes and interfaces -explicitly, you can use command-line options to tell \f[V]javac\f[R] -where to search for their source files. -If you have compiled those source files previously, you can use options -to tell \f[V]javac\f[R] where to search for the corresponding class -files. -The options, which all have names ending in \[dq]path\[dq], are -described in \f[B]Standard Options\f[R], and further described in -\f[B]Configuring a Compilation\f[R] and \f[B]Searching for Module, -Package and Type Declarations\f[R]. -.PP -By default, \f[V]javac\f[R] compiles each source file to a class file in -the same directory as the source file. -However, it is recommended to specify a separate destination directory -with the \f[B]\f[VB]-d\f[B]\f[R] option. -.PP -Command-line \f[B]options\f[R] and \f[B]environment variables\f[R] also -control how \f[V]javac\f[R] performs various tasks: -.IP \[bu] 2 -Compiling code to run on earlier releases of the JDK. -.IP \[bu] 2 -Compiling code to run under a debugger. -.IP \[bu] 2 -Checking for stylistic issues in Java source code. -.IP \[bu] 2 -Checking for problems in \f[V]javadoc\f[R] comments -(\f[V]/** ... */\f[R]). -.IP \[bu] 2 -Processing annotations in source files and class files. -.IP \[bu] 2 -Upgrading and patching modules in the compile-time environment. -.PP -\f[V]javac\f[R] supports \f[B]Compiling for Earlier Releases Of The -Platform\f[R] and can also be invoked from Java code using one of a -number of \f[B]APIs\f[R] -.SH OPTIONS -.PP -\f[V]javac\f[R] provides \f[B]standard options\f[R], and \f[B]extra -options\f[R] that are either non-standard or are for advanced use. -.PP -Some options take one or more arguments. -If an argument contains spaces or other whitespace characters, the value -should be quoted according to the conventions of the environment being -used to invoke javac. -If the option begins with a single dash (\f[V]-\f[R]) the argument -should either directly follow the option name, or should be separated -with a colon (\f[V]:\f[R]) or whitespace, depending on the option. -If the option begins with a double dash (\f[V]--\f[R]), the argument may -be separated either by whitespace or by an equals (\f[V]=\f[R]) -character with no additional whitespace. -For example, -.IP -.nf -\f[CB] --Aname=\[dq]J. Duke\[dq] --proc:only --d myDirectory ---module-version 3 ---module-version=3 -\f[R] -.fi -.PP -In the following lists of options, an argument of \f[I]path\f[R] -represents a search path, composed of a list of file system locations -separated by the platform path separator character, (semicolon -\f[V];\f[R] on Windows, or colon \f[V]:\f[R] on other systems.) -Depending on the option, the file system locations may be directories, -JAR files or JMOD files. -.SS Standard Options -.TP -\f[V]\[at]\f[R]\f[I]filename\f[R] -Reads options and file names from a file. -To shorten or simplify the \f[V]javac\f[R] command, you can specify one -or more files that contain arguments to the \f[V]javac\f[R] command -(except \f[B]\f[VB]-J\f[B]\f[R] options). -This lets you to create \f[V]javac\f[R] commands of any length on any -operating system. -See \f[B]Command-Line Argument Files\f[R]. -.TP -\f[V]-A\f[R]\f[I]key\f[R][\f[V]=\f[R]\f[I]value\f[R]] -Specifies options to pass to annotation processors. -These options are not interpreted by \f[V]javac\f[R] directly, but are -made available for use by individual processors. -The \f[I]key\f[R] value should be one or more identifiers separated by a -dot (\f[V].\f[R]). -.TP -\f[V]--add-modules\f[R] \f[I]module\f[R]\f[V],\f[R]\f[I]module\f[R] -Specifies root modules to resolve in addition to the initial modules, or -all modules on the module path if \f[I]module\f[R] is -\f[V]ALL-MODULE-PATH\f[R]. -.TP -\f[V]--boot-class-path\f[R] \f[I]path\f[R] or \f[V]-bootclasspath\f[R] \f[I]path\f[R] -Overrides the location of the bootstrap class files. -.RS -.PP -\f[B]Note:\f[R] This can only be used when compiling for releases prior -to JDK 9. -As applicable, see the descriptions in \f[B]\f[VB]--release\f[B]\f[R], -\f[B]\f[VB]-source\f[B]\f[R], or \f[B]\f[VB]-target\f[B]\f[R] for -details. -For JDK 9 or later, see \f[B]\f[VB]--system\f[B]\f[R]. -.RE -.TP -\f[V]--class-path\f[R] \f[I]path\f[R], \f[V]-classpath\f[R] \f[I]path\f[R], or \f[V]-cp\f[R] \f[I]path\f[R] -Specifies where to find user class files and annotation processors. -This class path overrides the user class path in the \f[V]CLASSPATH\f[R] -environment variable. -.RS -.IP \[bu] 2 -If \f[V]--class-path\f[R], \f[V]-classpath\f[R], or \f[V]-cp\f[R] are -not specified, then the user class path is the value of the -\f[V]CLASSPATH\f[R] environment variable, if that is set, or else the -current directory. -.IP \[bu] 2 -If not compiling code for modules, if the -\f[B]\f[VB]--source-path\f[B]\f[R] or -sourcepath\[ga] option is not -specified, then the user class path is also searched for source files. -.IP \[bu] 2 -If the \f[B]\f[VB]-processorpath\f[B]\f[R] option is not specified, then -the class path is also searched for annotation processors. -.RE -.TP -\f[V]-d\f[R] \f[I]directory\f[R] -Sets the destination directory (or \f[I]class output directory\f[R]) for -class files. -If a class is part of a package, then \f[V]javac\f[R] puts the class -file in a subdirectory that reflects the module name (if appropriate) -and package name. -The directory, and any necessary subdirectories, will be created if they -do not already exist. -.RS -.PP -If the \f[V]-d\f[R] option is not specified, then \f[V]javac\f[R] puts -each class file in the same directory as the source file from which it -was generated. -.PP -Except when compiling code for multiple modules, the contents of the -class output directory will be organized in a package hierarchy. -When compiling code for multiple modules, the contents of the output -directory will be organized in a module hierarchy, with the contents of -each module in a separate subdirectory, each organized as a package -hierarchy. -.PP -\f[B]Note:\f[R] When compiling code for one or more modules, the class -output directory will automatically be checked when searching for -previously compiled classes. -When not compiling for modules, for backwards compatibility, the -directory is \f[I]not\f[R] automatically checked for previously compiled -classes, and so it is recommended to specify the class output directory -as one of the locations on the user class path, using the -\f[V]--class-path\f[R] option or one of its alternate forms. -.RE -.TP -\f[V]-deprecation\f[R] -Shows a description of each use or override of a deprecated member or -class. -Without the \f[V]-deprecation\f[R] option, \f[V]javac\f[R] shows a -summary of the source files that use or override deprecated members or -classes. -The \f[V]-deprecation\f[R] option is shorthand for -\f[V]-Xlint:deprecation\f[R]. -.TP -\f[V]--enable-preview\f[R] -Enables preview language features. -Used in conjunction with either \f[B]\f[VB]-source\f[B]\f[R] or -\f[B]\f[VB]--release\f[B]\f[R]. -.TP -\f[V]-encoding\f[R] \f[I]encoding\f[R] -Specifies character encoding used by source files, such as EUC-JP and -UTF-8. -If the \f[V]-encoding\f[R] option is not specified, then the platform -default converter is used. -.TP -\f[V]-endorseddirs\f[R] \f[I]directories\f[R] -Overrides the location of the endorsed standards path. -.RS -.PP -\f[B]Note:\f[R] This can only be used when compiling for releases prior -to JDK 9. -As applicable, see the descriptions in \f[B]\f[VB]--release\f[B]\f[R], -\f[B]\f[VB]-source\f[B]\f[R], or \f[B]\f[VB]-target\f[B]\f[R] for -details. -.RE -.TP -\f[V]-extdirs\f[R] \f[I]directories\f[R] -Overrides the location of the installed extensions. -\f[V]directories\f[R] is a list of directories, separated by the -platform path separator (\f[V];\f[R] on Windows, and \f[V]:\f[R] -otherwise). -Each JAR file in the specified directories is searched for class files. -All JAR files found become part of the class path. -.RS -.PP -If you are compiling for a release of the platform that supports the -Extension Mechanism, then this option specifies the directories that -contain the extension classes. -See [Compiling for Other Releases of the Platform]. -.PP -\f[B]Note:\f[R] This can only be used when compiling for releases prior -to JDK 9. -As applicable, see the descriptions in \f[B]\f[VB]--release\f[B]\f[R], -\f[B]\f[VB]-source\f[B]\f[R], or \f[B]\f[VB]-target\f[B]\f[R] for -details. -.RE -.TP -\f[V]-g\f[R] -Generates all debugging information, including local variables. -By default, only line number and source file information is generated. -.TP -\f[V]-g:\f[R][\f[V]lines\f[R], \f[V]vars\f[R], \f[V]source\f[R]] -Generates only the kinds of debugging information specified by the -comma-separated list of keywords. -Valid keywords are: -.RS -.TP -\f[V]lines\f[R] -Line number debugging information. -.TP -\f[V]vars\f[R] -Local variable debugging information. -.TP -\f[V]source\f[R] -Source file debugging information. -.RE -.TP -\f[V]-g:none\f[R] -Does not generate debugging information. -.TP -\f[V]-h\f[R] \f[I]directory\f[R] -Specifies where to place generated native header files. -.RS -.PP -When you specify this option, a native header file is generated for each -class that contains native methods or that has one or more constants -annotated with the \f[B]\f[VB]java.lang.annotation.Native\f[B]\f[R] -annotation. -If the class is part of a package, then the compiler puts the native -header file in a subdirectory that reflects the module name (if -appropriate) and package name. -The directory, and any necessary subdirectories, will be created if they -do not already exist. -.RE -.TP -\f[V]--help\f[R], \f[V]-help\f[R] or \f[V]-?\f[R] -Prints a synopsis of the standard options. -.TP -\f[V]--help-extra\f[R] or \f[V]-X\f[R] -Prints a synopsis of the set of extra options. -.TP -\f[V]--help-lint\f[R] -Prints the supported keys for the \f[V]-Xlint\f[R] option. -.TP -\f[V]-implicit:\f[R][\f[V]none\f[R], \f[V]class\f[R]] -Specifies whether or not to generate class files for implicitly -referenced files: -.RS -.IP \[bu] 2 -\f[V]-implicit:class\f[R] --- Automatically generates class files. -.IP \[bu] 2 -\f[V]-implicit:none\f[R] --- Suppresses class file generation. -.PP -If this option is not specified, then the default automatically -generates class files. -In this case, the compiler issues a warning if any class files are -generated when also doing annotation processing. -The warning is not issued when the \f[V]-implicit\f[R] option is -explicitly set. -See \f[B]Searching for Module, Package and Type Declarations\f[R]. -.RE -.TP -\f[V]-J\f[R]\f[I]option\f[R] -Passes \f[I]option\f[R] to the runtime system, where \f[I]option\f[R] is -one of the Java options described on \f[B]java\f[R] command. -For example, \f[V]-J-Xms48m\f[R] sets the startup memory to 48 MB. -.RS -.PP -\f[B]Note:\f[R] The \f[V]CLASSPATH\f[R] environment variable, -\f[V]-classpath\f[R] option, \f[V]-bootclasspath\f[R] option, and -\f[V]-extdirs\f[R] option do not specify the classes used to run -\f[V]javac\f[R]. -Trying to customize the compiler implementation with these options and -variables is risky and often does not accomplish what you want. -If you must customize the compiler implementation, then use the -\f[V]-J\f[R] option to pass options through to the underlying Java -launcher. -.RE -.TP -\f[V]--limit-modules\f[R] \f[I]module\f[R]\f[V],\f[R]\f[I]module\f[R]* -Limits the universe of observable modules. -.TP -\f[V]--module\f[R] \f[I]module-name\f[R] (\f[V],\f[R]\f[I]module-name\f[R])* or \f[V]-m\f[R] \f[I]module-name\f[R] (\f[V],\f[R]\f[I]module-name\f[R])* -Compiles those source files in the named modules that are newer than the -corresponding files in the output directory. -.TP -\f[V]--module-path\f[R] \f[I]path\f[R] or \f[V]-p\f[R] \f[I]path\f[R] -Specifies where to find application modules. -.TP -\f[V]--module-source-path\f[R] \f[I]module-source-path\f[R] -Specifies where to find source files when compiling code in multiple -modules. -See [Compilation Modes] and \f[B]The Module Source Path Option\f[R]. -.TP -\f[V]--module-version\f[R] \f[I]version\f[R] -Specifies the version of modules that are being compiled. -.TP -\f[V]-nowarn\f[R] -Disables warning messages. -This option operates the same as the \f[V]-Xlint:none\f[R] option. -.TP -\f[V]-parameters\f[R] -Generates metadata for reflection on method parameters. -Stores formal parameter names of constructors and methods in the -generated class file so that the method -\f[V]java.lang.reflect.Executable.getParameters\f[R] from the Reflection -API can retrieve them. -.TP -\f[V]-proc:\f[R][\f[V]none\f[R], \f[V]only\f[R], \f[V]full\f[R]] -Controls whether annotation processing and compilation are done. -\f[V]-proc:none\f[R] means that compilation takes place without -annotation processing. -\f[V]-proc:only\f[R] means that only annotation processing is done, -without any subsequent compilation. -If this option is not used, or \f[V]-proc:full\f[R] is specified, -annotation processing and compilation are done. -.TP -\f[V]-processor\f[R] \f[I]class1\f[R][\f[V],\f[R]\f[I]class2\f[R]\f[V],\f[R]\f[I]class3\f[R]...] -Names of the annotation processors to run. -This bypasses the default discovery process. -.TP -\f[V]--processor-module-path\f[R] \f[I]path\f[R] -Specifies the module path used for finding annotation processors. -.TP -\f[V]--processor-path\f[R] \f[I]path\f[R] or \f[V]-processorpath\f[R] \f[I]path\f[R] -Specifies where to find annotation processors. -If this option is not used, then the class path is searched for -processors. -.TP -\f[V]-profile\f[R] \f[I]profile\f[R] -Checks that the API used is available in the specified profile. -This option is deprecated and may be removed in a future release. -.RS -.PP -\f[B]Note:\f[R] This can only be used when compiling for releases prior -to JDK 9. -As applicable, see the descriptions in \f[B]\f[VB]--release\f[B]\f[R], -\f[B]\f[VB]-source\f[B]\f[R], or \f[B]\f[VB]-target\f[B]\f[R] for -details. -.RE -.TP -\f[V]--release\f[R] \f[I]release\f[R] -Compiles source code according to the rules of the Java programming -language for the specified Java SE release, generating class files which -target that release. -Source code is compiled against the combined Java SE and JDK API for the -specified release. -.RS -.PP -The supported values of \f[I]release\f[R] are the current Java SE -release and a limited number of previous releases, detailed in the -command-line help. -.PP -For the current release, the Java SE API consists of the -\f[V]java.*\f[R], \f[V]javax.*\f[R], and \f[V]org.*\f[R] packages that -are exported by the Java SE modules in the release; the JDK API consists -of the \f[V]com.*\f[R] and \f[V]jdk.*\f[R] packages that are exported by -the JDK modules in the release, plus the \f[V]javax.*\f[R] packages that -are exported by standard, but non-Java SE, modules in the release. -.PP -For previous releases, the Java SE API and the JDK API are as defined in -that release. -.PP -\f[B]Note:\f[R] When using \f[V]--release\f[R], you cannot also use the -\f[B]\f[VB]--source\f[B]\f[R]/\f[V]-source\f[R] or -\f[B]\f[VB]--target\f[B]\f[R]/\f[V]-target\f[R] options. -.PP -\f[B]Note:\f[R] When using \f[V]--release\f[R] to specify a release that -supports the Java Platform Module System, the \f[V]--add-exports\f[R] -option cannot be used to enlarge the set of packages exported by the -Java SE, JDK, and standard modules in the specified release. -.RE -.TP -\f[V]-s\f[R] \f[I]directory\f[R] -Specifies the directory used to place the generated source files. -If a class is part of a package, then the compiler puts the source file -in a subdirectory that reflects the module name (if appropriate) and -package name. -The directory, and any necessary subdirectories, will be created if they -do not already exist. -.RS -.PP -Except when compiling code for multiple modules, the contents of the -source output directory will be organized in a package hierarchy. -When compiling code for multiple modules, the contents of the source -output directory will be organized in a module hierarchy, with the -contents of each module in a separate subdirectory, each organized as a -package hierarchy. -.RE -.TP -\f[V]--source\f[R] \f[I]release\f[R] or \f[V]-source\f[R] \f[I]release\f[R] -Compiles source code according to the rules of the Java programming -language for the specified Java SE release. -The supported values of \f[I]release\f[R] are the current Java SE -release and a limited number of previous releases, detailed in the -command-line help. -.RS -.PP -If the option is not specified, the default is to compile source code -according to the rules of the Java programming language for the current -Java SE release. -.RE -.TP -\f[V]--source-path\f[R] \f[I]path\f[R] or \f[V]-sourcepath\f[R] \f[I]path\f[R] -Specifies where to find source files. -Except when compiling multiple modules together, this is the source code -path used to search for class or interface definitions. -.RS -.PP -\f[B]Note:\f[R] Classes found through the class path might be recompiled -when their source files are also found. -See \f[B]Searching for Module, Package and Type Declarations\f[R]. -.RE -.TP -\f[V]--system\f[R] \f[I]jdk\f[R] | \f[V]none\f[R] -Overrides the location of system modules. -.TP -\f[V]--target\f[R] \f[I]release\f[R] or \f[V]-target\f[R] \f[I]release\f[R] -Generates \f[V]class\f[R] files suitable for the specified Java SE -release. -The supported values of \f[I]release\f[R] are the current Java SE -release and a limited number of previous releases, detailed in the -command-line help. -.RS -.PP -\f[B]Note:\f[R] The target release must be equal to or higher than the -source release. -(See \f[B]\f[VB]--source\f[B]\f[R].) -.RE -.TP -\f[V]--upgrade-module-path\f[R] \f[I]path\f[R] -Overrides the location of upgradeable modules. -.TP -\f[V]-verbose\f[R] -Outputs messages about what the compiler is doing. -Messages include information about each class loaded and each source -file compiled. -.TP -\f[V]--version\f[R] or \f[V]-version\f[R] -Prints version information. -.TP -\f[V]-Werror\f[R] -Terminates compilation when warnings occur. -.SS Extra Options -.TP -\f[V]--add-exports\f[R] \f[I]module\f[R]\f[V]/\f[R]\f[I]package\f[R]\f[V]=\f[R]\f[I]other-module\f[R](\f[V],\f[R]\f[I]other-module\f[R])* -Specifies a package to be considered as exported from its defining -module to additional modules or to all unnamed modules when the value of -\f[I]other-module\f[R] is \f[V]ALL-UNNAMED\f[R]. -.TP -\f[V]--add-reads\f[R] \f[I]module\f[R]\f[V]=\f[R]\f[I]other-module\f[R](\f[V],\f[R]\f[I]other-module\f[R])* -Specifies additional modules to be considered as required by a given -module. -.TP -\f[V]--default-module-for-created-files\f[R] \f[I]module-name\f[R] -Specifies the fallback target module for files created by annotation -processors, if none is specified or inferred. -.TP -\f[V]--disable-line-doc-comments\f[R] -Disables support for documentation comments with lines beginning ///. -.TP -\f[V]-Djava.endorsed.dirs=\f[R]\f[I]dirs\f[R] -Overrides the location of the endorsed standards path. -.RS -.PP -\f[B]Note:\f[R] This can only be used when compiling for releases prior -to JDK 9. -As applicable, see the descriptions in \f[B]\f[VB]--release\f[B]\f[R], -\f[B]\f[VB]-source\f[B]\f[R], or \f[B]\f[VB]-target\f[B]\f[R] for -details. -.RE -.TP -\f[V]-Djava.ext.dirs=\f[R]\f[I]dirs\f[R] -Overrides the location of installed extensions. -.RS -.PP -\f[B]Note:\f[R] This can only be used when compiling for releases prior -to JDK 9. -As applicable, see the descriptions in \f[B]\f[VB]--release\f[B]\f[R], -\f[B]\f[VB]-source\f[B]\f[R], or \f[B]\f[VB]-target\f[B]\f[R] for -details. -.RE -.TP -\f[V]--patch-module\f[R] \f[I]module\f[R]\f[V]=\f[R]\f[I]path\f[R] -Overrides or augments a module with classes and resources in JAR files -or directories. -.TP -\f[V]-Xbootclasspath:\f[R]\f[I]path\f[R] -Overrides the location of the bootstrap class files. -.RS -.PP -\f[B]Note:\f[R] This can only be used when compiling for releases prior -to JDK 9. -As applicable, see the descriptions in \f[B]\f[VB]--release\f[B]\f[R], -\f[B]\f[VB]-source\f[B]\f[R], or \f[B]\f[VB]-target\f[B]\f[R] for -details. -.RE -.TP -\f[V]-Xbootclasspath/a:\f[R]\f[I]path\f[R] -Adds a suffix to the bootstrap class path. -.RS -.PP -\f[B]Note:\f[R] This can only be used when compiling for releases prior -to JDK 9. -As applicable, see the descriptions in \f[B]\f[VB]--release\f[B]\f[R], -\f[B]\f[VB]-source\f[B]\f[R], or \f[B]\f[VB]-target\f[B]\f[R] for -details. -.RE -.TP -\f[V]-Xbootclasspath/p:\f[R]\f[I]path\f[R] -Adds a prefix to the bootstrap class path. -.RS -.PP -\f[B]Note:\f[R] This can only be used when compiling for releases prior -to JDK 9. -As applicable, see the descriptions in \f[B]\f[VB]--release\f[B]\f[R], -\f[B]\f[VB]-source\f[B]\f[R], or \f[B]\f[VB]-target\f[B]\f[R] for -details. -.RE -.TP -\f[V]-Xdiags:\f[R][\f[V]compact\f[R], \f[V]verbose\f[R]] -Selects a diagnostic mode. -.TP -\f[V]-Xdoclint\f[R] -Enables recommended checks for problems in documentation comments. -.TP -\f[V]-Xdoclint:\f[R](\f[V]all\f[R]|\f[V]none\f[R]|[\f[V]-\f[R]]\f[I]group\f[R])[\f[V]/\f[R]\f[I]access\f[R]] -Enables or disables specific groups of checks in documentation comments. -.RS -.PP -\f[I]group\f[R] can have one of the following values: -\f[V]accessibility\f[R], \f[V]html\f[R], \f[V]missing\f[R], -\f[V]reference\f[R], \f[V]syntax\f[R]. -.PP -The variable \f[I]access\f[R] specifies the minimum visibility level of -classes and members that the \f[V]-Xdoclint\f[R] option checks. -It can have one of the following values (in order of most to least -visible): \f[V]public\f[R], \f[V]protected\f[R], \f[V]package\f[R], -\f[V]private\f[R]. -.PP -The default \f[I]access\f[R] level is \f[V]private\f[R]. -.PP -When prefixed by \f[V]doclint:\f[R], the \f[I]group\f[R] names and -\f[V]all\f[R] can be used with \f[V]\[at]SuppressWarnings\f[R] to -suppress warnings about documentation comments in parts of the code -being compiled. -.PP -For more information about these groups of checks, see the -\f[B]DocLint\f[R] section of the \f[V]javadoc\f[R] command -documentation. -The \f[V]-Xdoclint\f[R] option is disabled by default in the -\f[V]javac\f[R] command. -.PP -For example, the following option checks classes and members (with all -groups of checks) that have the access level of protected and higher -(which includes protected and public): -.RS -.PP -\f[V]-Xdoclint:all/protected\f[R] -.RE -.PP -The following option enables all groups of checks for all access levels, -except it will not check for HTML errors for classes and members that -have the access level of package and higher (which includes package, -protected and public): -.RS -.PP -\f[V]-Xdoclint:all,-html/package\f[R] -.RE -.RE -.TP -\f[V]-Xdoclint/package:\f[R][\f[V]-\f[R]]\f[I]packages\f[R](\f[V],\f[R][\f[V]-\f[R]]\f[I]package\f[R])* -Enables or disables checks in specific packages. -Each \f[I]package\f[R] is either the qualified name of a package or a -package name prefix followed by \f[V].*\f[R], which expands to all -sub-packages of the given package. -Each \f[I]package\f[R] can be prefixed with a hyphen (\f[V]-\f[R]) to -disable checks for a specified package or packages. -.RS -.PP -For more information, see the \f[B]DocLint\f[R] section of the -\f[V]javadoc\f[R] command documentation. -.RE -.TP -\f[V]-Xlint\f[R] -Enables all recommended warnings. -In this release, enabling all available warnings is recommended. -.TP -\f[V]-Xlint:\f[R][\f[V]-\f[R]]\f[I]key\f[R](\f[V],\f[R][\f[V]-\f[R]]\f[I]key\f[R])* -Supplies warnings to enable or disable, separated by comma. -Precede a key by a hyphen (\f[V]-\f[R]) to disable the specified -warning. -.RS -.PP -Supported values for \f[I]key\f[R] are: -.IP \[bu] 2 -\f[V]all\f[R]: Enables all warnings. -.IP \[bu] 2 -\f[V]auxiliaryclass\f[R]: Warns about an auxiliary class that is hidden -in a source file, and is used from other files. -.IP \[bu] 2 -\f[V]cast\f[R]: Warns about the use of unnecessary casts. -.IP \[bu] 2 -\f[V]classfile\f[R]: Warns about the issues related to classfile -contents. -.IP \[bu] 2 -\f[V]dangling-doc-comments\f[R]: Warns about extra or misplaced -documentation comments near the beginning of a declaration. -.IP \[bu] 2 -\f[V]deprecation\f[R]: Warns about the use of deprecated items. -.IP \[bu] 2 -\f[V]dep-ann\f[R]: Warns about the items marked as deprecated in -\f[V]javadoc\f[R] but without the \f[V]\[at]Deprecated\f[R] annotation. -.IP \[bu] 2 -\f[V]divzero\f[R]: Warns about the division by the constant integer 0. -.IP \[bu] 2 -\f[V]empty\f[R]: Warns about an empty statement after \f[V]if\f[R]. -.IP \[bu] 2 -\f[V]exports\f[R]: Warns about the issues regarding module exports. -.IP \[bu] 2 -\f[V]fallthrough\f[R]: Warns about the falling through from one case of -a switch statement to the next. -.IP \[bu] 2 -\f[V]finally\f[R]: Warns about \f[V]finally\f[R] clauses that do not -terminate normally. -.IP \[bu] 2 -\f[V]incubating\f[R]: Warns about the use of incubating modules. -.IP \[bu] 2 -\f[V]lossy-conversions\f[R]: Warns about possible lossy conversions in -compound assignment. -.IP \[bu] 2 -\f[V]missing-explicit-ctor\f[R]: Warns about missing explicit -constructors in public and protected classes in exported packages. -.IP \[bu] 2 -\f[V]module\f[R]: Warns about the module system-related issues. -.IP \[bu] 2 -\f[V]opens\f[R]: Warns about the issues related to module opens. -.IP \[bu] 2 -\f[V]options\f[R]: Warns about the issues relating to use of command -line options. -.IP \[bu] 2 -\f[V]output-file-clash\f[R]: Warns if any output file is overwritten -during compilation. -This can occur, for example, on case-insensitive filesystems. -.IP \[bu] 2 -\f[V]overloads\f[R]: Warns about the issues related to method overloads. -.IP \[bu] 2 -\f[V]overrides\f[R]: Warns about the issues related to method overrides. -.IP \[bu] 2 -\f[V]path\f[R]: Warns about the invalid path elements on the command -line. -.IP \[bu] 2 -\f[V]preview\f[R]: Warns about the use of preview language features. -.IP \[bu] 2 -\f[V]processing\f[R]: Warns about the issues related to annotation -processing. -.IP \[bu] 2 -\f[V]rawtypes\f[R]: Warns about the use of raw types. -.IP \[bu] 2 -\f[V]removal\f[R]: Warns about the use of an API that has been marked -for removal. -.IP \[bu] 2 -\f[V]restricted\f[R]: Warns about the use of restricted methods. -.IP \[bu] 2 -\f[V]requires-automatic\f[R]: Warns developers about the use of -automatic modules in requires clauses. -.IP \[bu] 2 -\f[V]requires-transitive-automatic\f[R]: Warns about automatic modules -in requires transitive. -.IP \[bu] 2 -\f[V]serial\f[R]: Warns about the serializable classes that do not -provide a serial version ID. -Also warns about access to non-public members from a serializable -element. -.IP \[bu] 2 -\f[V]static\f[R]: Warns about the accessing a static member using an -instance. -.IP \[bu] 2 -\f[V]strictfp\f[R]: Warns about unnecessary use of the -\f[V]strictfp\f[R] modifier. -.IP \[bu] 2 -\f[V]synchronization\f[R]: Warns about synchronization attempts on -instances of value-based classes. -.IP \[bu] 2 -\f[V]text-blocks\f[R]: Warns about inconsistent white space characters -in text block indentation. -.IP \[bu] 2 -\f[V]this-escape\f[R]: Warns about constructors leaking \f[V]this\f[R] -prior to subclass initialization. -.IP \[bu] 2 -\f[V]try\f[R]: Warns about the issues relating to the use of try blocks -(that is, try-with-resources). -.IP \[bu] 2 -\f[V]unchecked\f[R]: Warns about the unchecked operations. -.IP \[bu] 2 -\f[V]varargs\f[R]: Warns about the potentially unsafe \f[V]vararg\f[R] -methods. -.IP \[bu] 2 -\f[V]none\f[R]: Disables all warnings. -.PP -With the exception of \f[V]all\f[R] and \f[V]none\f[R], the keys can be -used with the \f[V]\[at]SuppressWarnings\f[R] annotation to suppress -warnings in a part of the source code being compiled. -.PP -See \f[B]Examples of Using -Xlint keys\f[R]. -.RE -.TP -\f[V]-Xmaxerrs\f[R] \f[I]number\f[R] -Sets the maximum number of errors to print. -.TP -\f[V]-Xmaxwarns\f[R] \f[I]number\f[R] -Sets the maximum number of warnings to print. -.TP -\f[V]-Xpkginfo:\f[R][\f[V]always\f[R], \f[V]legacy\f[R], \f[V]nonempty\f[R]] -Specifies when and how the \f[V]javac\f[R] command generates -\f[V]package-info.class\f[R] files from \f[V]package-info.java\f[R] -files using one of the following options: -.RS -.TP -\f[V]always\f[R] -Generates a \f[V]package-info.class\f[R] file for every -\f[V]package-info.java\f[R] file. -This option may be useful if you use a build system such as Ant, which -checks that each \f[V].java\f[R] file has a corresponding -\f[V].class\f[R] file. -.TP -\f[V]legacy\f[R] -Generates a \f[V]package-info.class\f[R] file only if -\f[V]package-info.java\f[R] contains annotations. -This option does not generate a \f[V]package-info.class\f[R] file if -\f[V]package-info.java\f[R] contains only comments. -.RS -.PP -\f[B]Note:\f[R] A \f[V]package-info.class\f[R] file might be generated -but be empty if all the annotations in the \f[V]package-info.java\f[R] -file have \f[V]RetentionPolicy.SOURCE\f[R]. -.RE -.TP -\f[V]nonempty\f[R] -Generates a \f[V]package-info.class\f[R] file only if -\f[V]package-info.java\f[R] contains annotations with -\f[V]RetentionPolicy.CLASS\f[R] or \f[V]RetentionPolicy.RUNTIME\f[R]. -.RE -.TP -\f[V]-Xplugin:\f[R]\f[I]name\f[R] \f[I]args\f[R] -Specifies the name and optional arguments for a plug-in to be run. -If \f[I]args\f[R] are provided, \f[I]name\f[R] and \f[I]args\f[R] should -be quoted or otherwise escape the whitespace characters between the name -and all the arguments. -For details on the API for a plugin, see the API documentation for -\f[B]jdk.compiler/com.sun.source.util.Plugin\f[R]. -.TP -\f[V]-Xprefer:\f[R][\f[V]source\f[R], \f[V]newer\f[R]] -Specifies which file to read when both a source file and class file are -found for an implicitly compiled class using one of the following -options. -See \f[B]Searching for Module, Package and Type Declarations\f[R]. -.RS -.IP \[bu] 2 -\f[V]-Xprefer:newer\f[R]: Reads the newer of the source or class files -for a type (default). -.IP \[bu] 2 -\f[V]-Xprefer:source\f[R] : Reads the source file. -Use \f[V]-Xprefer:source\f[R] when you want to be sure that any -annotation processors can access annotations declared with a retention -policy of \f[V]SOURCE\f[R]. -.RE -.TP -\f[V]-Xprint\f[R] -Prints a textual representation of specified types for debugging -purposes. -This does not perform annotation processing or compilation. -The format of the output could change. -.TP -\f[V]-XprintProcessorInfo\f[R] -Prints information about which annotations a processor is asked to -process. -.TP -\f[V]-XprintRounds\f[R] -Prints information about initial and subsequent annotation processing -rounds. -.TP -\f[V]-Xstdout\f[R] \f[I]filename\f[R] -Sends compiler messages to the named file. -By default, compiler messages go to \f[V]System.err\f[R]. -.SH ENVIRONMENT VARIABLES -.SS CLASSPATH -.PP -If the \f[B]\f[VB]--class-path\f[B]\f[R] option or any of its alternate -forms are not specified, the class path will default to the value of the -\f[V]CLASSPATH\f[R] environment variable if it is set. -However, it is recommended that this environment variable should -\f[I]not\f[R] be set, and that the \f[V]--class-path\f[R] option should -be used to provide an explicit value for the class path when one is -required. -.SS JDK_JAVAC_OPTIONS -.PP -The content of the \f[V]JDK_JAVAC_OPTIONS\f[R] environment variable, -separated by white-spaces ( ) or white-space characters -(\f[V]\[rs]n\f[R], \f[V]\[rs]t\f[R], \f[V]\[rs]r\f[R], or -\f[V]\[rs]f\f[R]) is prepended to the command line arguments passed to -\f[V]javac\f[R] as a list of arguments. -.PP -The encoding requirement for the environment variable is the same as the -\f[V]javac\f[R] command line on the system. -\f[V]JDK_JAVAC_OPTIONS\f[R] environment variable content is treated in -the same manner as that specified in the command line. -.PP -Single quotes (\f[V]\[aq]\f[R]) or double quotes (\f[V]\[dq]\f[R]) can -be used to enclose arguments that contain whitespace characters. -All content between the open quote and the first matching close quote -are preserved by simply removing the pair of quotes. -In case a matching quote is not found, the launcher will abort with an -error message. -\f[V]\[at]\f[R]\f[I]files\f[R] are supported as they are specified in -the command line. -However, as in \f[V]\[at]\f[R]\f[I]files\f[R], use of a wildcard is not -supported. -.PP -\f[B]Examples of quoting arguments containing white spaces:\f[R] -.RS -.PP -\f[V]export JDK_JAVAC_OPTIONS=\[aq]\[at]\[dq]C:\[rs]white spaces\[rs]argfile\[dq]\[aq]\f[R] -.RE -.RS -.PP -\f[V]export JDK_JAVAC_OPTIONS=\[aq]\[dq]\[at]C:\[rs]white spaces\[rs]argfile\[dq]\[aq]\f[R] -.RE -.RS -.PP -\f[V]export JDK_JAVAC_OPTIONS=\[aq]\[at]C:\[rs]\[dq]white spaces\[dq]\[rs]argfile\[aq]\f[R] -.RE -.SH COMMAND-LINE ARGUMENT FILES -.PP -An argument file can include command-line options and source file names -in any combination. -The arguments within a file can be separated by spaces or new line -characters. -If a file name contains embedded spaces, then put the whole file name in -double quotation marks. -.PP -File names within an argument file are relative to the current -directory, not to the location of the argument file. -Wildcards (\f[V]*\f[R]) are not allowed in these lists (such as for -specifying \f[V]*.java\f[R]). -Use of the at sign (\f[V]\[at]\f[R]) to recursively interpret files is -not supported. -The \f[V]-J\f[R] options are not supported because they\[aq]re passed to -the launcher, which does not support argument files. -.PP -When executing the \f[V]javac\f[R] command, pass in the path and name of -each argument file with the at sign (\f[V]\[at]\f[R]) leading character. -When the \f[V]javac\f[R] command encounters an argument beginning with -the at sign (\f[V]\[at]\f[R]), it expands the contents of that file into -the argument list. -.SS Examples of Using javac \[at]filename -.TP -Single Argument File -You could use a single argument file named \f[V]argfile\f[R] to hold all -\f[V]javac\f[R] arguments: -.RS -.RS -.PP -\f[V]javac \[at]argfile\f[R] -.RE -.PP -This argument file could contain the contents of both files shown in the -following \f[B]Two Argument Files\f[R] example. -.RE -.TP -Two Argument Files -You can create two argument files: one for the \f[V]javac\f[R] options -and the other for the source file names. -Note that the following lists have no line-continuation characters. -.RS -.PP -Create a file named \f[V]options\f[R] that contains the following: -.PP -\f[B]Linux and macOS:\f[R] -.IP -.nf -\f[CB] --d classes --g --sourcepath /java/pubs/ws/1.3/src/share/classes -\f[R] -.fi -.PP -\f[B]Windows:\f[R] -.IP -.nf -\f[CB] --d classes --g --sourcepath C:\[rs]java\[rs]pubs\[rs]ws\[rs]1.3\[rs]src\[rs]share\[rs]classes -\f[R] -.fi -.PP -Create a file named \f[V]sources\f[R] that contains the following: -.IP -.nf -\f[CB] -MyClass1.java -MyClass2.java -MyClass3.java -\f[R] -.fi -.PP -Then, run the \f[V]javac\f[R] command as follows: -.RS -.PP -\f[V]javac \[at]options \[at]sources\f[R] -.RE -.RE -.TP -Argument Files with Paths -The argument files can have paths, but any file names inside the files -are relative to the current working directory (not \f[V]path1\f[R] or -\f[V]path2\f[R]): -.RS -.RS -.PP -\f[V]javac \[at]path1/options \[at]path2/sources\f[R] -.RE -.RE -.SH ARRANGEMENT OF SOURCE CODE -.PP -In the Java language, classes and interfaces can be organized into -packages, and packages can be organized into modules. -\f[V]javac\f[R] expects that the physical arrangement of source files in -directories of the file system will mirror the organization of classes -into packages, and packages into modules. -.PP -It is a widely adopted convention that module names and package names -begin with a lower-case letter, and that class names begin with an -upper-case letter. -.SS Arrangement of Source Code for a Package -.PP -When classes and interfaces are organized into a package, the package is -represented as a directory, and any subpackages are represented as -subdirectories. -.PP -For example: -.IP \[bu] 2 -The package \f[V]p\f[R] is represented as a directory called -\f[V]p\f[R]. -.IP \[bu] 2 -The package \f[V]p.q\f[R] -- that is, the subpackage \f[V]q\f[R] of -package \f[V]p\f[R] -- is represented as the subdirectory \f[V]q\f[R] of -directory \f[V]p\f[R]. -The directory tree representing package \f[V]p.q\f[R] is therefore -\f[V]p\[rs]q\f[R] on Windows, and \f[V]p/q\f[R] on other systems. -.IP \[bu] 2 -The package \f[V]p.q.r\f[R] is represented as the directory tree -\f[V]p\[rs]q\[rs]r\f[R] (on Windows) or \f[V]p/q/r\f[R] (on other -systems). -.PP -Within a directory or subdirectory, \f[V].java\f[R] files represent -classes and interfaces in the corresponding package or subpackage. -.PP -For example: -.IP \[bu] 2 -The class \f[V]X\f[R] declared in package \f[V]p\f[R] is represented by -the file \f[V]X.java\f[R] in the \f[V]p\f[R] directory. -.IP \[bu] 2 -The class \f[V]Y\f[R] declared in package \f[V]p.q\f[R] is represented -by the file \f[V]Y.java\f[R] in the \f[V]q\f[R] subdirectory of -directory \f[V]p\f[R]. -.IP \[bu] 2 -The class \f[V]Z\f[R] declared in package \f[V]p.q.r\f[R] is represented -by the file \f[V]Z.java\f[R] in the \f[V]r\f[R] subdirectory of -\f[V]p\[rs]q\f[R] (on Windows) or \f[V]p/q\f[R] (on other systems). -.PP -In some situations, it is convenient to split the code into separate -directories, each structured as described above, and the aggregate list -of directories specified to \f[V]javac\f[R]. -.SS Arrangement of Source Code for a Module -.PP -In the Java language, a module is a set of packages designed for reuse. -In addition to \f[V].java\f[R] files for classes and interfaces, each -module has a source file called \f[V]module-info.java\f[R] which: -.IP "1." 3 -declares the module\[aq]s name; -.IP "2." 3 -lists the packages exported by the module (to allow reuse by other -modules); -.IP "3." 3 -lists other modules required by the module (to reuse their exported -packages). -.PP -When packages are organized into a module, the module is represented by -one or more directories representing the packages in the module, one of -which contains the \f[V]module-info.java\f[R] file. -It may be convenient, but it is not required, to use a single directory, -named after the module, to contain the \f[V]module-info.java\f[R] file -alongside the directory tree which represents the packages in the module -(i.e., the \f[I]package hierarchy\f[R] described above). -The exact arrangement of source code for a module is typically dictated -by the conventions adopted by a development environment (IDE) or build -system. -.PP -For example: -.IP \[bu] 2 -The module \f[V]a.b.c\f[R] may be represented by the directory -\f[V]a.b.c\f[R], on all systems. -.IP \[bu] 2 -The module\[aq]s declaration is represented by the file -\f[V]module-info.java\f[R] in the \f[V]a.b.c\f[R] directory. -.IP \[bu] 2 -If the module contains package \f[V]p.q.r\f[R], then the \f[V]a.b.c\f[R] -directory contains the directory tree \f[V]p\[rs]q\[rs]r\f[R] (on -Windows) or \f[V]p/q/r\f[R] (on other systems). -.PP -The development environment may prescribe some directory hierarchy -between the directory named for the module and the source files to be -read by \f[V]javac\f[R]. -.PP -For example: -.IP \[bu] 2 -The module \f[V]a.b.c\f[R] may be represented by the directory -\f[V]a.b.c\f[R] -.IP \[bu] 2 -The module\[aq]s declaration and the module\[aq]s packages may be in -some subdirectory of \f[V]a.b.c\f[R], such as -\f[V]src\[rs]main\[rs]java\f[R] (on Windows) or \f[V]src/main/java\f[R] -(on other systems). -.SH CONFIGURING A COMPILATION -.PP -This section describes how to configure \f[V]javac\f[R] to perform a -basic compilation. -.PP -See \f[B]Configuring the Module System\f[R] for additional details for -use when compiling for a release of the platform that supports modules. -.SS Source Files -.IP \[bu] 2 -Specify the source files to be compiled on the command line. -.PP -If there are no compilation errors, the corresponding class files will -be placed in the \f[B]output directory\f[R]. -.PP -Some systems may limit the amount you can put on a command line; to work -around those limits, you can use \f[B]argument files\f[R]. -.PP -When compiling code for modules, you can also specify source files -indirectly, by using the \f[B]\f[VB]--module\f[B]\f[R] or \f[V]-m\f[R] -option. -.SS Output Directory -.IP \[bu] 2 -Use the \f[B]\f[VB]-d\f[B]\f[R] option to specify an output directory in -which to put the compiled class files. -.PP -This will normally be organized in a \f[B]package hierarchy\f[R], unless -you are compiling source code from multiple modules, in which case it -will be organized as a \f[B]module hierarchy\f[R]. -.PP -When the compilation has been completed, if you are compiling one or -more modules, you can place the output directory on the module path for -the Java \f[B]launcher\f[R]; otherwise, you can place the place the -output directory on the class path for the Java launcher. -.SS Precompiled Code -.PP -The code to be compiled may refer to libraries beyond what is provided -by the platform. -If so, you must place these libraries on the class path or module path. -If the library code is not in a module, place it on the class path; if -it is in a module, place it on the module path. -.IP \[bu] 2 -Use the \f[B]\f[VB]--class-path\f[B]\f[R] option to specify libraries to -be placed on the class path. -Locations on the class path should be organized in a \f[B]package -hierarchy\f[R]. -You can also use alternate forms of the option: \f[V]-classpath\f[R] or -\f[V]-cp\f[R]. -.IP \[bu] 2 -Use the \f[B]\f[VB]--module-path\f[B]\f[R] option to specify libraries -to be placed on the module path. -Locations on the module path should either be modules or directories of -modules. -You can also use an alternate form of the option: \f[V]-p\f[R]. -.RS 2 -.PP -See \f[B]Configuring the Module System\f[R] for details on how to modify -the default configuration of library modules. -.RE -.PP -\f[B]Note\f[R]: the options for the class path and module path are not -mutually exclusive, although it is not common to specify the class path -when compiling code for one or more modules. -.SS Additional Source Files -.PP -The code to be compiled may refer to types in additional source files -that are not specified on the command line. -If so, you must put those source files on either the source path or -module path. -You can only specify one of these options: if you are not compiling code -for a module, or if you are only compiling code for a single module, use -the source path; if you are compiling code for multiple modules, use the -module source path. -.IP \[bu] 2 -Use the \f[B]\f[VB]--source-path\f[B]\f[R] option to specify the -locations of additional source files that may be read by javac. -Locations on the source path should be organized in a \f[B]package -hierarchy\f[R]. -You can also use an alternate form of the option: \f[V]-sourcepath\f[R]. -.IP \[bu] 2 -Use the \f[B]\f[VB]--module-source-path\f[B]\f[R] option one or more -times to specify the location of additional source files in different -modules that may be read by javac, or when compiling source files in -multiple modules. -You can either specify the locations for each module -\f[B]individually\f[R], or you can organize the source files so that you -can specify the locations all \f[B]together\f[R]. -For more details, see \f[B]The Module Source Path Option\f[R]. -.PP -If you want to be able to refer to types in additional source files but -do not want them to be compiled, use the \f[B]\f[VB]-implicit\f[B]\f[R] -option. -.PP -\f[B]Note\f[R]: if you are compiling code for multiple modules, you must -always specify a module source path, and all source files specified on -the command line must be in one of the directories on the module source -path, or in a subdirectory thereof. -.SS Example of Compiling Multiple Source Files -.PP -This example compiles the \f[V]Aloha.java\f[R], \f[V]GutenTag.java\f[R], -\f[V]Hello.java\f[R], and \f[V]Hi.java\f[R] source files in the -\f[V]greetings\f[R] package. -.PP -\f[B]Linux and macOS:\f[R] -.IP -.nf -\f[CB] -% javac greetings/*.java -% ls greetings -Aloha.class GutenTag.class Hello.class Hi.class -Aloha.java GutenTag.java Hello.java Hi.java -\f[R] -.fi -.PP -\f[B]Windows:\f[R] -.IP -.nf -\f[CB] -C:\[rs]>javac greetings\[rs]*.java -C:\[rs]>dir greetings -Aloha.class GutenTag.class Hello.class Hi.class -Aloha.java GutenTag.java Hello.java Hi.java -\f[R] -.fi -.SS Example of Specifying a User Class Path -.PP -After changing one of the source files in the previous example, -recompile it: -.PP -\f[B]Linux and macOS:\f[R] -.IP -.nf -\f[CB] -pwd -/examples -javac greetings/Hi.java -\f[R] -.fi -.PP -\f[B]Windows:\f[R] -.IP -.nf -\f[CB] -C:\[rs]>cd -\[rs]examples -C:\[rs]>javac greetings\[rs]Hi.java -\f[R] -.fi -.PP -Because \f[V]greetings.Hi\f[R] refers to other classes in the -\f[V]greetings\f[R] package, the compiler needs to find these other -classes. -The previous example works because the default user class path is the -directory that contains the package directory. -If you want to recompile this file without concern for which directory -you are in, then add the examples directory to the user class path by -setting \f[V]CLASSPATH\f[R]. -This example uses the \f[V]-classpath\f[R] option. -.PP -\f[B]Linux and macOS:\f[R] -.RS -.PP -\f[V]javac -classpath /examples /examples/greetings/Hi.java\f[R] -.RE -.PP -\f[B]Windows:\f[R] -.RS -.PP -\f[V]C:\[rs]>javac -classpath \[rs]examples \[rs]examples\[rs]greetings\[rs]Hi.java\f[R] -.RE -.PP -If you change \f[V]greetings.Hi\f[R] to use a banner utility, then that -utility also needs to be accessible through the user class path. -.PP -\f[B]Linux and macOS:\f[R] -.IP -.nf -\f[CB] -javac -classpath /examples:/lib/Banners.jar \[rs] - /examples/greetings/Hi.java -\f[R] -.fi -.PP -\f[B]Windows:\f[R] -.IP -.nf -\f[CB] -C:\[rs]>javac -classpath \[rs]examples;\[rs]lib\[rs]Banners.jar \[ha] - \[rs]examples\[rs]greetings\[rs]Hi.java -\f[R] -.fi -.PP -To execute a class in the \f[V]greetings\f[R] package, the program needs -access to the \f[V]greetings\f[R] package, and to the classes that the -\f[V]greetings\f[R] classes use. -.PP -\f[B]Linux and macOS:\f[R] -.RS -.PP -\f[V]java -classpath /examples:/lib/Banners.jar greetings.Hi\f[R] -.RE -.PP -\f[B]Windows:\f[R] -.RS -.PP -\f[V]C:\[rs]>java -classpath \[rs]examples;\[rs]lib\[rs]Banners.jar greetings.Hi\f[R] -.RE -.SH CONFIGURING THE MODULE SYSTEM -.PP -If you want to include additional modules in your compilation, use the -\f[B]\f[VB]--add-modules\f[B]\f[R] option. -This may be necessary when you are compiling code that is not in a -module, or which is in an automatic module, and the code refers to API -in the additional modules. -.PP -If you want to restrict the set of modules in your compilation, use the -\f[B]\f[VB]--limit-modules\f[B]\f[R] option. -This may be useful if you want to ensure that the code you are compiling -is capable of running on a system with a limited set of modules -installed. -.PP -If you want to break encapsulation and specify that additional packages -should be considered as exported from a module, use the -\f[B]\f[VB]--add-exports\f[B]\f[R] option. -This may be useful when performing white-box testing; relying on access -to internal API in production code is strongly discouraged. -.PP -If you want to specify that additional packages should be considered as -required by a module, use the \f[B]\f[VB]--add-reads\f[B]\f[R] option. -This may be useful when performing white-box testing; relying on access -to internal API in production code is strongly discouraged. -.PP -You can patch additional content into any module using the -\f[B]\f[VB]--patch-module\f[B]\f[R] option. -See [Patching a Module] for more details. -.SH SEARCHING FOR MODULE, PACKAGE AND TYPE DECLARATIONS -.PP -To compile a source file, the compiler often needs information about a -module or type, but the declaration is not in the source files specified -on the command line. -.PP -\f[V]javac\f[R] needs type information for every class or interface -used, extended, or implemented in the source file. -This includes classes and interfaces not explicitly mentioned in the -source file, but that provide information through inheritance. -.PP -For example, when you create a subclass of \f[V]java.awt.Window\f[R], -you are also using the ancestor classes of \f[V]Window\f[R]: -\f[V]java.awt.Container\f[R], \f[V]java.awt.Component\f[R], and -\f[V]java.lang.Object\f[R]. -.PP -When compiling code for a module, the compiler also needs to have -available the declaration of that module. -.PP -A successful search may produce a class file, a source file, or both. -If both are found, then you can use the \f[B]\f[VB]-Xprefer\f[B]\f[R] -option to instruct the compiler which to use. -.PP -If a search finds and uses a source file, then by default -\f[V]javac\f[R] compiles that source file. -This behavior can be altered with \f[B]\f[VB]-implicit\f[B]\f[R]. -.PP -The compiler might not discover the need for some type information until -after annotation processing completes. -When the type information is found in a source file and no -\f[B]\f[VB]-implicit\f[B]\f[R] option is specified, the compiler gives a -warning that the file is being compiled without being subject to -annotation processing. -To disable the warning, either specify the file on the command line (so -that it will be subject to annotation processing) or use the -\f[B]\f[VB]-implicit\f[B]\f[R] option to specify whether or not class -files should be generated for such source files. -.PP -The way that \f[V]javac\f[R] locates the declarations of those types -depends on whether the reference exists within code for a module or not. -.SS Searching Package Oriented Paths -.PP -When searching for a source or class file on a path composed of package -oriented locations, \f[V]javac\f[R] will check each location on the path -in turn for the possible presence of the file. -The first occurrence of a particular file shadows (hides) any subsequent -occurrences of like-named files. -This shadowing does not affect any search for any files with a different -name. -This can be convenient when searching for source files, which may be -grouped in different locations, such as shared code, platform-specific -code and generated code. -It can also be useful when injecting alternate versions of a class file -into a package, to debugging or other instrumentation reasons. -But, it can also be dangerous, such as when putting incompatible -different versions of a library on the class path. -.SS Searching Module Oriented Paths -.PP -Prior to scanning any module paths for any package or type declarations, -\f[V]javac\f[R] will lazily scan the following paths and locations to -determine the modules that will be used in the compilation. -.IP \[bu] 2 -The module source path (see the -\f[B]\f[VB]--module-source-path\f[B]\f[R] option) -.IP \[bu] 2 -The path for upgradeable modules (see the -\f[B]\f[VB]--upgrade-module-path\f[B]\f[R] option) -.IP \[bu] 2 -The system modules (see the \f[B]\f[VB]--system\f[B]\f[R] option) -.IP \[bu] 2 -The user module path ( see the \f[B]\f[VB]--module-path\f[B]\f[R] -option) -.PP -For any module, the first occurrence of the module during the scan -completely shadows (hides) any subsequent appearance of a like-named -module. -While locating the modules, \f[V]javac\f[R] is able to determine the -packages exported by the module and to associate with each module a -package oriented path for the contents of the module. -For any previously compiled module, this path will typically be a single -entry for either a directory or a file that provides an internal -directory-like hierarchy, such as a JAR file. -Thus, when searching for a type that is in a package that is known to be -exported by a module, \f[V]javac\f[R] can locate the declaration -directly and efficiently. -.SS Searching for the Declaration of a Module -.PP -If the module has been previously compiled, the module declaration is -located in a file named \f[V]module-info.class\f[R] in the root of the -package hierarchy for the content of the module. -.PP -If the module is one of those currently being compiled, the module -declaration will be either the file named \f[V]module-info.class\f[R] in -the root of the package hierarchy for the module in the class output -directory, or the file named \f[V]module-info.java\f[R] in one of the -locations on the source path or one the module source path for the -module. -.SS Searching for the Declaration of a Type When the Reference is not in a Module -.PP -When searching for a type that is referenced in code that is not in a -module, \f[V]javac\f[R] will look in the following places: -.IP \[bu] 2 -The platform classes (or the types in exported packages of the platform -modules) (This is for compiled class files only.) -.IP \[bu] 2 -Types in exported packages of any modules on the module path, if -applicable. -(This is for compiled class files only.) -.IP \[bu] 2 -Types in packages on the class path and/or source path: -.RS 2 -.IP \[bu] 2 -If both are specified, \f[V]javac\f[R] looks for compiled class files on -the class path and for source files on the source path. -.IP \[bu] 2 -If the class path is specified, but not source path, \f[V]javac\f[R] -looks for both compiled class files and source files on the class path. -.IP \[bu] 2 -If the class path is not specified, it defaults to the current -directory. -.RE -.PP -When looking for a type on the class path and/or source path, if both a -compiled class file and a source file are found, the most recently -modified file will be used by default. -If the source file is newer, it will be compiled and will may override -any previously compiled version of the file. -You can use the \f[B]\f[VB]-Xprefer\f[B]\f[R] option to override the -default behavior. -.SS Searching for the Declaration of a Type When the Reference is in a Module -.PP -When searching for a type that is referenced in code in a module, -\f[V]javac\f[R] will examine the declaration of the enclosing module to -determine if the type is in a package that is exported from another -module that is readable by the enclosing module. -If so, \f[V]javac\f[R] will simply and directly go to the definition of -that module to find the definition of the required type. -Unless the module is another of the modules being compiled, -\f[V]javac\f[R] will only look for compiled class files files. -In other words, \f[V]javac\f[R] will not look for source files in -platform modules or modules on the module path. -.PP -If the type being referenced is not in some other readable module, -\f[V]javac\f[R] will examine the module being compiled to try and find -the declaration of the type. -\f[V]javac\f[R] will look for the declaration of the type as follows: -.IP \[bu] 2 -Source files specified on the command line or on the source path or -module source path. -.IP \[bu] 2 -Previously compiled files in the output directory. -.SH DIRECTORY HIERARCHIES -.PP -\f[V]javac\f[R] generally assumes that source files and compiled class -files will be organized in a file system directory hierarchy or in a -type of file that supports in an internal directory hierarchy, such as a -JAR file. -Three different kinds of hierarchy are supported: a \f[I]package -hierarchy\f[R], a \f[I]module hierarchy\f[R], and a \f[I]module source -hierarchy\f[R]. -.PP -While \f[V]javac\f[R] is fairly relaxed about the organization of source -code, beyond the expectation that source will be organized in one or -package hierarchies, and can generally accommodate organizations -prescribed by development environments and build tools, Java tools in -general, and \f[V]javac\f[R] and the Java launcher in particular, are -more stringent regarding the organization of compiled class files, and -will be organized in package hierarchies or module hierarchies, as -appropriate. -.PP -The location of these hierarchies are specified to \f[V]javac\f[R] with -command-line options, whose names typically end in \[dq]path\[dq], like -\f[B]\f[VB]--source-path\f[B]\f[R] or \f[B]\f[VB]--class-path\f[B]\f[R]. -Also as a general rule, path options whose name includes the word -\f[V]module\f[R], like \f[B]\f[VB]--module-path\f[B]\f[R], are used to -specify module hierarchies, although some module-related path options -allow a package hierarchy to be specified on a per-module basis. -All other path options are used to specify package hierarchies. -.SS Package Hierarchy -.PP -In a package hierarchy, directories and subdirectories are used to -represent the component parts of the package name, with the source file -or compiled class file for a type being stored as a file with an -extension of \f[V].java\f[R] or \f[V].class\f[R] in the most nested -directory. -.PP -For example, in a package hierarchy, the source file for a class -\f[V]com.example.MyClass\f[R] will be stored in the file -\f[I]com/example/MyClass.java\f[R] -.SS Module Hierarchy -.PP -In a module hierarchy, the first level of directories are named for the -modules in the hierarchy; within each of those directories the contents -of the module are organized in package hierarchies. -.PP -For example, in a module hierarchy, the compiled class file for a type -called \f[V]com.example.MyClass\f[R] in a module called -\f[V]my.library\f[R] will be stored in -\f[I]my.library/com/example/MyClass.class\f[R]. -.PP -The various output directories used by \f[V]javac\f[R] (the class output -directory, the source output directory, and native header output -directory) will all be organized in a module hierarchy when multiple -modules are being compiled. -.SS Module Source Hierarchy -.PP -Although the source for each individual module should always be -organized in a package hierarchy, it may be convenient to group those -hierarchies into a module source hierarchy. -This is similar to a module hierarchy, except that there may be -intervening directories between the directory for the module and the -directory that is the root of the package hierarchy for the source code -of the module. -.PP -For example, in a module source hierarchy, the source file for a type -called \f[V]com.example.MyClass\f[R] in a module called -\f[V]my.library\f[R] may be stored in a file such as -\f[I]my.library/src/main/java/com/example/MyClass.java\f[R]. -.SH THE MODULE SOURCE PATH OPTION -.PP -The \f[B]\f[VB]--module-source-path\f[B]\f[R] option has two forms: a -\f[I]module-specific form\f[R], in which a package path is given for -each module containing code to be compiled, and a -\f[I]module-pattern\f[R] form, in which the source path for each module -is specified by a pattern. -The module-specific form is generally simpler to use when only a small -number of modules are involved; the module-pattern form may be more -convenient when the number of modules is large and the modules are -organized in a regular manner that can be described by a pattern. -.PP -Multiple instances of the \f[V]--module-source-path\f[R] option may be -given, each one using either the module-pattern form or the -module-specific form, subject to the following limitations: -.IP \[bu] 2 -the module-pattern form may be used at most once -.IP \[bu] 2 -the module-specific form may be used at most once for any given module -.PP -If the module-specific form is used for any module, the associated -search path overrides any path that might otherwise have been inferred -from the module-pattern form. -.SS Module-specific form -.PP -The module-specific form allows an explicit search path to be given for -any specific module. -This form is: -.IP \[bu] 2 -\f[V]--module-source-path\f[R] -\f[I]module-name\f[R]\f[V]=\f[R]\f[I]file-path\f[R] -(\f[I]path-separator\f[R] \f[I]file-path\f[R])* -.PP -The path separator character is \f[V];\f[R] on Windows, and \f[V]:\f[R] -otherwise. -.PP -\f[B]Note:\f[R] this is similar to the form used for the -\f[B]\f[VB]--patch-module\f[B]\f[R] option. -.SS Module-pattern form -.PP -The module-pattern form allows a concise specification of the module -source path for any number of modules organized in regular manner. -.IP \[bu] 2 -\f[V]--module-source-path\f[R] \f[I]pattern\f[R] -.PP -The pattern is defined by the following rules, which are applied in -order: -.IP \[bu] 2 -The argument is considered to be a series of segments separated by the -path separator character (\f[V];\f[R] on Windows, and \f[V]:\f[R] -otherwise). -.IP \[bu] 2 -Each segment containing curly braces of the form -.RS 2 -.IP -.nf -\f[CB] -string1{alt1 ( ,alt2 )* } string2 -\f[R] -.fi -.PP -is considered to be replaced by a series of segments formed by -\[dq]expanding\[dq] the braces: -.IP -.nf -\f[CB] -string1 alt1 string2 -string1 alt2 string2 -and so on... -\f[R] -.fi -.PP -The braces may be nested. -.PP -This rule is applied for all such usages of braces. -.RE -.IP \[bu] 2 -Each segment must have at most one asterisk (\f[V]*\f[R]). -If a segment does not contain an asterisk, it is considered to be as -though the file separator character and an asterisk are appended. -.RS 2 -.PP -For any module \f[I]M\f[R], the source path for that module is formed -from the series of segments obtained by substituting the module name -\f[I]M\f[R] for the asterisk in each segment. -.PP -\f[B]Note\f[R]: in this context, the asterisk is just used as a special -marker, to denote the position in the path of the module name. -It should not be confused with the use of \f[V]*\f[R] as a file name -wildcard character, as found on most operating systems. -.RE -.SH PATCHING MODULES -.PP -javac allows any content, whether in source or compiled form, to be -patched into any module using the \f[B]\f[VB]--patch-module\f[B]\f[R] -option. -You may want to do this to compile alternative implementations of a -class to be patched at runtime into a JVM, or to inject additional -classes into the module, such as when testing. -.PP -The form of the option is: -.IP \[bu] 2 -\f[V]--patch-module\f[R] -\f[I]module-name\f[R]\f[V]=\f[R]\f[I]file-path\f[R] -(\f[I]path-separator\f[R] \f[I]file-path\f[R] )* -.PP -The path separator character is \f[V];\f[R] on Windows, and \f[V]:\f[R] -otherwise. -The paths given for the module must specify the root of a package -hierarchy for the contents of the module -.PP -The option may be given at most once for any given module. -Any content on the path will hide any like-named content later in the -path and in the patched module. -.PP -When patching source code into more than one module, the -\f[B]\f[VB]--module-source-path\f[B]\f[R] must also be used, so that the -output directory is organized in a module hierarchy, and capable of -holding the compiled class files for the modules being compiled. -.SH ANNOTATION PROCESSING -.PP -The \f[V]javac\f[R] command provides direct support for annotation -processing. -.PP -The API for annotation processors is defined in the -\f[V]javax.annotation.processing\f[R] and \f[V]javax.lang.model\f[R] -packages and subpackages. -.SS How Annotation Processing Works -.PP -Unless annotation processing is disabled with the -\f[B]\f[VB]-proc:none\f[B]\f[R] option, the compiler searches for any -annotation processors that are available. -The search path can be specified with the -\f[B]\f[VB]-processorpath\f[B]\f[R] option. -If no path is specified, then the user class path is used. -Processors are located by means of service provider-configuration files -named \f[V]META-INF/services/javax.annotation.processing.Processor\f[R] -on the search path. -Such files should contain the names of any annotation processors to be -used, listed one per line. -Alternatively, processors can be specified explicitly, using the -\f[B]\f[VB]-processor\f[B]\f[R] option. -.PP -After scanning the source files and classes on the command line to -determine what annotations are present, the compiler queries the -processors to determine what annotations they process. -When a match is found, the processor is called. -A processor can claim the annotations it processes, in which case no -further attempt is made to find any processors for those annotations. -After all of the annotations are claimed, the compiler does not search -for additional processors. -.PP -If any processors generate new source files, then another round of -annotation processing occurs: Any newly generated source files are -scanned, and the annotations processed as before. -Any processors called on previous rounds are also called on all -subsequent rounds. -This continues until no new source files are generated. -.PP -After a round occurs where no new source files are generated, the -annotation processors are called one last time, to give them a chance to -complete any remaining work. -Finally, unless the \f[B]\f[VB]-proc:only\f[B]\f[R] option is used, the -compiler compiles the original and all generated source files. -.PP -If you use an annotation processor that generates additional source -files to be included in the compilation, you can specify a default -module to be used for the newly generated files, for use when a module -declaration is not also generated. -In this case, use the -\f[B]\f[VB]--default-module-for-created-files\f[B]\f[R] option. -.SS Compilation Environment and Runtime Environment. -.PP -The declarations in source files and previously compiled class files are -analyzed by \f[V]javac\f[R] in a \f[I]compilation environment\f[R] that -is distinct from the \f[I]runtime environment\f[R] used to execute -\f[V]javac\f[R] itself. -Although there is a deliberate similarity between many \f[V]javac\f[R] -options and like-named options for the Java \f[B]launcher\f[R], such as -\f[V]--class-path\f[R], \f[V]--module-path\f[R] and so on, it is -important to understand that in general the \f[V]javac\f[R] options just -affect the environment in which the source files are compiled, and do -not affect the operation of \f[V]javac\f[R] itself. -.PP -The distinction between the compilation environment and runtime -environment is significant when it comes to using annotation processors. -Although annotations processors process elements (declarations) that -exist in the compilation environment, the annotation processor itself is -executed in the runtime environment. -If an annotation processor has dependencies on libraries that are not in -modules, the libraries can be placed, along with the annotation -processor itself, on the processor path. -(See the \f[B]\f[VB]--processor-path\f[B]\f[R] option.) -If the annotation processor and its dependencies are in modules, you -should use the processor module path instead. -(See the \f[B]\f[VB]--processor-module-path\f[B]\f[R] option.) -When those are insufficient, it may be necessary to provide further -configuration of the runtime environment. -This can be done in two ways: -.IP "1." 3 -If \f[V]javac\f[R] is invoked from the command line, options can be -passed to the underlying runtime by prefixing the option with -\f[B]\f[VB]-J\f[B]\f[R]. -.IP "2." 3 -You can start an instance of a Java Virtual Machine directly and use -command line options and API to configure an environment in which -\f[V]javac\f[R] can be invoked via one of its \f[B]APIs\f[R]. -.SH COMPILING FOR EARLIER RELEASES OF THE PLATFORM -.PP -\f[V]javac\f[R] can compile code that is to be used on other releases of -the platform, using either the \f[B]\f[VB]--release\f[B]\f[R] option, or -the \f[B]\f[VB]--source\f[B]\f[R]/\f[V]-source\f[R] and -\f[B]\f[VB]--target\f[B]\f[R]/\f[V]-target\f[R] options, together with -additional options to specify the platform classes. -.PP -Depending on the desired platform release, there are some restrictions -on some of the options that can be used. -.IP \[bu] 2 -When compiling for JDK 8 and earlier releases, you cannot use any option -that is intended for use with the module system. -This includes all of the following options: -.RS 2 -.IP \[bu] 2 -\f[B]\f[VB]--module-source-path\f[B]\f[R], -\f[B]\f[VB]--upgrade-module-path\f[B]\f[R], -\f[B]\f[VB]--system\f[B]\f[R], \f[B]\f[VB]--module-path\f[B]\f[R], -\f[B]\f[VB]--add-modules\f[B]\f[R], \f[B]\f[VB]--add-exports\f[B]\f[R], -\f[V]--add-opens\f[R], \f[B]\f[VB]--add-reads\f[B]\f[R], -\f[B]\f[VB]--limit-modules\f[B]\f[R], -\f[B]\f[VB]--patch-module\f[B]\f[R] -.PP -If you use the \f[V]--source\f[R]/\f[V]-source\f[R] or -\f[V]--target\f[R]/\f[V]-target\f[R] options, you should also set the -appropriate platform classes using the boot class path family of -options. -.RE -.IP \[bu] 2 -When compiling for JDK 9 and later releases, you cannot use any option -that is intended to configure the boot class path. -This includes all of the following options: -.RS 2 -.IP \[bu] 2 -\f[B]\f[VB]-Xbootclasspath/p:\f[B]\f[R], -\f[B]\f[VB]-Xbootclasspath\f[B]\f[R], -\f[B]\f[VB]-Xbootclasspath/a:\f[B]\f[R], -\f[B]\f[VB]-endorseddirs\f[B]\f[R], -\f[B]\f[VB]-Djava.endorsed.dirs\f[B]\f[R], -\f[B]\f[VB]-extdirs\f[B]\f[R], \f[B]\f[VB]-Djava.ext.dirs\f[B]\f[R], -\f[B]\f[VB]-profile\f[B]\f[R] -.PP -If you use the \f[V]--source\f[R]/\f[V]-source\f[R] or -\f[V]--target\f[R]/\f[V]-target\f[R] options, you should also set the -appropriate platform classes using the \f[V]--system\f[R] option to give -the location of an appropriate installed release of JDK. -.RE -.PP -When using the \f[V]--release\f[R] option, only the supported documented -API for that release may be used; you cannot use any options to break -encapsulation to access any internal classes. -.SH APIS -.PP -The \f[V]javac\f[R] compiler can be invoked using an API in three -different ways: -.TP -The \f[B]Java Compiler API\f[R] -This provides the most flexible way to invoke the compiler, including -the ability to compile source files provided in memory buffers or other -non-standard file systems. -.TP -The \f[B]ToolProvider API\f[R] -A \f[V]ToolProvider\f[R] for \f[V]javac\f[R] can be obtained by calling -\f[V]ToolProvider.findFirst(\[dq]javac\[dq])\f[R]. -This returns an object with the equivalent functionality of the -command-line tool. -.RS -.PP -\f[B]Note\f[R]: This API should not be confused with the like-named API -in the \f[B]\f[VB]javax.tools\f[B]\f[R] package. -.RE -.TP -The \f[V]javac\f[R] \f[B]Legacy API\f[R] -This API is retained for backward compatibility only. -All new code should use either the Java Compiler API or the ToolProvider -API. -.PP -\f[B]Note:\f[R] All other classes and methods found in a package with -names that start with \f[V]com.sun.tools.javac\f[R] (subpackages of -\f[V]com.sun.tools.javac\f[R]) are strictly internal and subject to -change at any time. -.SH EXAMPLES OF USING -XLINT KEYS -.TP -\f[V]cast\f[R] -Warns about unnecessary and redundant casts, for example: -.RS -.RS -.PP -\f[V]String s = (String) \[dq]Hello!\[dq]\f[R] -.RE -.RE -.TP -\f[V]classfile\f[R] -Warns about issues related to class file contents. -.TP -\f[V]deprecation\f[R] -Warns about the use of deprecated items. -For example: -.RS -.IP -.nf -\f[CB] -java.util.Date myDate = new java.util.Date(); -int currentDay = myDate.getDay(); -\f[R] -.fi -.PP -The method \f[V]java.util.Date.getDay\f[R] has been deprecated since JDK -1.1. -.RE -.TP -\f[V]dep-ann\f[R] -Warns about items that are documented with the \f[V]\[at]deprecated\f[R] -Javadoc comment, but do not have the \f[V]\[at]Deprecated\f[R] -annotation, for example: -.RS -.IP -.nf -\f[CB] -/** - * \[at]deprecated As of Java SE 7, replaced by {\[at]link #newMethod()} - */ -public static void deprecatedMethod() { } -public static void newMethod() { } -\f[R] -.fi -.RE -.TP -\f[V]divzero\f[R] -Warns about division by the constant integer 0, for example: -.RS -.RS -.PP -\f[V]int divideByZero = 42 / 0;\f[R] -.RE -.RE -.TP -\f[V]empty\f[R] -Warns about empty statements after \f[V]if\f[R]statements, for example: -.RS -.IP -.nf -\f[CB] -class E { - void m() { - if (true) ; - } -} -\f[R] -.fi -.RE -.TP -\f[V]fallthrough\f[R] -Checks the switch blocks for fall-through cases and provides a warning -message for any that are found. -Fall-through cases are cases in a switch block, other than the last case -in the block, whose code does not include a \f[V]break\f[R] statement, -allowing code execution to fall through from that case to the next case. -For example, the code following the case 1 label in this switch block -does not end with a \f[V]break\f[R] statement: -.RS -.IP -.nf -\f[CB] -switch (x) { -case 1: - System.out.println(\[dq]1\[dq]); - // No break statement here. -case 2: - System.out.println(\[dq]2\[dq]); -} -\f[R] -.fi -.PP -If the \f[V]-Xlint:fallthrough\f[R] option was used when compiling this -code, then the compiler emits a warning about possible fall-through into -case, with the line number of the case in question. -.RE -.TP -\f[V]finally\f[R] -Warns about \f[V]finally\f[R] clauses that cannot be completed normally, -for example: -.RS -.IP -.nf -\f[CB] -public static int m() { - try { - throw new NullPointerException(); - } catch (NullPointerException(); { - System.err.println(\[dq]Caught NullPointerException.\[dq]); - return 1; - } finally { - return 0; - } - } -\f[R] -.fi -.PP -The compiler generates a warning for the \f[V]finally\f[R] block in this -example. -When the \f[V]int\f[R] method is called, it returns a value of 0. -A \f[V]finally\f[R] block executes when the \f[V]try\f[R] block exits. -In this example, when control is transferred to the \f[V]catch\f[R] -block, the \f[V]int\f[R] method exits. -However, the \f[V]finally\f[R] block must execute, so it\[aq]s executed, -even though control was transferred outside the method. -.RE -.TP -\f[V]options\f[R] -Warns about issues that related to the use of command-line options. -See \f[B]Compiling for Earlier Releases of the Platform\f[R]. -.TP -\f[V]overrides\f[R] -Warns about issues related to method overrides. -For example, consider the following two classes: -.RS -.IP -.nf -\f[CB] -public class ClassWithVarargsMethod { - void varargsMethod(String... s) { } -} - -public class ClassWithOverridingMethod extends ClassWithVarargsMethod { - \[at]Override - void varargsMethod(String[] s) { } -} -\f[R] -.fi -.PP -The compiler generates a warning similar to the following:. -.IP -.nf -\f[CB] -warning: [override] varargsMethod(String[]) in ClassWithOverridingMethod -overrides varargsMethod(String...) in ClassWithVarargsMethod; overriding -method is missing \[aq]...\[aq] -\f[R] -.fi -.PP -When the compiler encounters a \f[V]varargs\f[R] method, it translates -the \f[V]varargs\f[R] formal parameter into an array. -In the method \f[V]ClassWithVarargsMethod.varargsMethod\f[R], the -compiler translates the \f[V]varargs\f[R] formal parameter -\f[V]String... s\f[R] to the formal parameter \f[V]String[] s\f[R], an -array that matches the formal parameter of the method -\f[V]ClassWithOverridingMethod.varargsMethod\f[R]. -Consequently, this example compiles. -.RE -.TP -\f[V]path\f[R] -Warns about invalid path elements and nonexistent path directories on -the command line (with regard to the class path, the source path, and -other paths). -Such warnings cannot be suppressed with the -\f[V]\[at]SuppressWarnings\f[R] annotation. -For example: -.RS -.IP \[bu] 2 -\f[B]Linux and macOS:\f[R] -\f[V]javac -Xlint:path -classpath /nonexistentpath Example.java\f[R] -.IP \[bu] 2 -\f[B]Windows:\f[R] -\f[V]javac -Xlint:path -classpath C:\[rs]nonexistentpath Example.java\f[R] -.RE -.TP -\f[V]processing\f[R] -Warns about issues related to annotation processing. -The compiler generates this warning when you have a class that has an -annotation, and you use an annotation processor that cannot handle that -type of annotation. -For example, the following is a simple annotation processor: -.RS -.PP -\f[B]Source file AnnoProc.java\f[R]: -.IP -.nf -\f[CB] -import java.util.*; -import javax.annotation.processing.*; -import javax.lang.model.*; -import javax.lang.model.element.*; - -\[at]SupportedAnnotationTypes(\[dq]NotAnno\[dq]) -public class AnnoProc extends AbstractProcessor { - public boolean process(Set elems, RoundEnvironment renv){ - return true; - } - - public SourceVersion getSupportedSourceVersion() { - return SourceVersion.latest(); - } -} -\f[R] -.fi -.PP -\f[B]Source file AnnosWithoutProcessors.java\f[R]: -.IP -.nf -\f[CB] -\[at]interface Anno { } - -\[at]Anno -class AnnosWithoutProcessors { } -\f[R] -.fi -.PP -The following commands compile the annotation processor -\f[V]AnnoProc\f[R], then run this annotation processor against the -source file \f[V]AnnosWithoutProcessors.java\f[R]: -.IP -.nf -\f[CB] -javac AnnoProc.java -javac -cp . -Xlint:processing -processor AnnoProc -proc:only AnnosWithoutProcessors.java -\f[R] -.fi -.PP -When the compiler runs the annotation processor against the source file -\f[V]AnnosWithoutProcessors.java\f[R], it generates the following -warning: -.IP -.nf -\f[CB] -warning: [processing] No processor claimed any of these annotations: Anno -\f[R] -.fi -.PP -To resolve this issue, you can rename the annotation defined and used in -the class \f[V]AnnosWithoutProcessors\f[R] from \f[V]Anno\f[R] to -\f[V]NotAnno\f[R]. -.RE -.TP -\f[V]rawtypes\f[R] -Warns about unchecked operations on raw types. -The following statement generates a \f[V]rawtypes\f[R] warning: -.RS -.RS -.PP -\f[V]void countElements(List l) { ... }\f[R] -.RE -.PP -The following example does not generate a \f[V]rawtypes\f[R] warning: -.RS -.PP -\f[V]void countElements(List l) { ... }\f[R] -.RE -.PP -\f[V]List\f[R] is a raw type. -However, \f[V]List\f[R] is an unbounded wildcard parameterized type. -Because \f[V]List\f[R] is a parameterized interface, always specify its -type argument. -In this example, the \f[V]List\f[R] formal argument is specified with an -unbounded wildcard (\f[V]?\f[R]) as its formal type parameter, which -means that the \f[V]countElements\f[R] method can accept any -instantiation of the \f[V]List\f[R] interface. -.RE -.TP -\f[V]serial\f[R] -Warns about missing \f[V]serialVersionUID\f[R] definitions on -serializable classes. -For example: -.RS -.IP -.nf -\f[CB] -public class PersistentTime implements Serializable -{ - private Date time; - - public PersistentTime() { - time = Calendar.getInstance().getTime(); - } - - public Date getTime() { - return time; - } -} -\f[R] -.fi -.PP -The compiler generates the following warning: -.IP -.nf -\f[CB] -warning: [serial] serializable class PersistentTime has no definition of -serialVersionUID -\f[R] -.fi -.PP -If a serializable class does not explicitly declare a field named -\f[V]serialVersionUID\f[R], then the serialization runtime environment -calculates a default \f[V]serialVersionUID\f[R] value for that class -based on various aspects of the class, as described in the Java Object -Serialization Specification. -However, it\[aq]s strongly recommended that all serializable classes -explicitly declare \f[V]serialVersionUID\f[R] values because the default -process of computing \f[V]serialVersionUID\f[R] values is highly -sensitive to class details that can vary depending on compiler -implementations. -As a result, this might cause an unexpected -\f[V]InvalidClassExceptions\f[R] during deserialization. -To guarantee a consistent \f[V]serialVersionUID\f[R] value across -different Java compiler implementations, a serializable class must -declare an explicit \f[V]serialVersionUID\f[R] value. -.RE -.TP -\f[V]static\f[R] -Warns about issues relating to the use of static variables, for example: -.RS -.IP -.nf -\f[CB] -class XLintStatic { - static void m1() { } - void m2() { this.m1(); } -} -\f[R] -.fi -.PP -The compiler generates the following warning: -.IP -.nf -\f[CB] -warning: [static] static method should be qualified by type name, -XLintStatic, instead of by an expression -\f[R] -.fi -.PP -To resolve this issue, you can call the \f[V]static\f[R] method -\f[V]m1\f[R] as follows: -.RS -.PP -\f[V]XLintStatic.m1();\f[R] -.RE -.PP -Alternately, you can remove the \f[V]static\f[R] keyword from the -declaration of the method \f[V]m1\f[R]. -.RE -.TP -\f[V]this-escape\f[R] -Warns about constructors leaking \f[V]this\f[R] prior to subclass -initialization. -For example, this class: -.RS -.IP -.nf -\f[CB] -public class MyClass { - public MyClass() { - System.out.println(this.hashCode()); - } -} -\f[R] -.fi -.PP -generates the following warning: -.IP -.nf -\f[CB] -MyClass.java:3: warning: [this-escape] possible \[aq]this\[aq] escape - before subclass is fully initialized - System.out.println(this.hashCode()); - \[ha] -\f[R] -.fi -.PP -A \[aq]this\[aq] escape warning is generated when a constructor does -something that might result in a subclass method being invoked before -the constructor returns. -In such cases the subclass method would be operating on an incompletely -initialized instance. -In the above example, a subclass of \f[V]MyClass\f[R] that overrides -\f[V]hashCode()\f[R] to incorporate its own fields would likely produce -an incorrect result when invoked as shown. -.PP -Warnings are only generated if a subclass could exist that is outside of -the current module (or package, if no module) being compiled. -So, for example, constructors in final and non-public classes do not -generate warnings. -.RE -.TP -\f[V]try\f[R] -Warns about issues relating to the use of \f[V]try\f[R] blocks, -including try-with-resources statements. -For example, a warning is generated for the following statement because -the resource \f[V]ac\f[R] declared in the \f[V]try\f[R] block is not -used: -.RS -.IP -.nf -\f[CB] -try ( AutoCloseable ac = getResource() ) { // do nothing} -\f[R] -.fi -.RE -.TP -\f[V]unchecked\f[R] -Gives more detail for unchecked conversion warnings that are mandated by -the Java Language Specification, for example: -.RS -.IP -.nf -\f[CB] -List l = new ArrayList(); -List ls = l; // unchecked warning -\f[R] -.fi -.PP -During type erasure, the types \f[V]ArrayList\f[R] and -\f[V]List\f[R] become \f[V]ArrayList\f[R] and \f[V]List\f[R], -respectively. -.PP -The \f[V]ls\f[R] command has the parameterized type -\f[V]List\f[R]. -When the \f[V]List\f[R] referenced by \f[V]l\f[R] is assigned to -\f[V]ls\f[R], the compiler generates an unchecked warning. -At compile time, the compiler and JVM cannot determine whether -\f[V]l\f[R] refers to a \f[V]List\f[R] type. -In this case, \f[V]l\f[R] does not refer to a \f[V]List\f[R] -type. -As a result, heap pollution occurs. -.PP -A heap pollution situation occurs when the \f[V]List\f[R] object -\f[V]l\f[R], whose static type is \f[V]List\f[R], is assigned to -another \f[V]List\f[R] object, \f[V]ls\f[R], that has a different static -type, \f[V]List\f[R]. -However, the compiler still allows this assignment. -It must allow this assignment to preserve backward compatibility with -releases of Java SE that do not support generics. -Because of type erasure, \f[V]List\f[R] and -\f[V]List\f[R] both become \f[V]List\f[R]. -Consequently, the compiler allows the assignment of the object -\f[V]l\f[R], which has a raw type of \f[V]List\f[R], to the object -\f[V]ls\f[R]. -.RE -.TP -\f[V]varargs\f[R] -Warns about unsafe use of variable arguments (\f[V]varargs\f[R]) -methods, in particular, those that contain non-reifiable arguments, for -example: -.RS -.IP -.nf -\f[CB] -public class ArrayBuilder { - public static void addToList (List listArg, T... elements) { - for (T x : elements) { - listArg.add(x); - } - } -} -\f[R] -.fi -.PP -A non-reifiable type is a type whose type information is not fully -available at runtime. -.PP -The compiler generates the following warning for the definition of the -method \f[V]ArrayBuilder.addToList\f[R]: -.IP -.nf -\f[CB] -warning: [varargs] Possible heap pollution from parameterized vararg type T -\f[R] -.fi -.PP -When the compiler encounters a varargs method, it translates the -\f[V]varargs\f[R] formal parameter into an array. -However, the Java programming language does not permit the creation of -arrays of parameterized types. -In the method \f[V]ArrayBuilder.addToList\f[R], the compiler translates -the \f[V]varargs\f[R] formal parameter \f[V]T...\f[R] elements to the -formal parameter \f[V]T[]\f[R] elements, an array. -However, because of type erasure, the compiler converts the -\f[V]varargs\f[R] formal parameter to \f[V]Object[]\f[R] elements. -Consequently, there\[aq]s a possibility of heap pollution. -.RE diff --git a/src/jdk.compiler/share/man/javac.md b/src/jdk.compiler/share/man/javac.md new file mode 100644 index 00000000000..b41a395f386 --- /dev/null +++ b/src/jdk.compiler/share/man/javac.md @@ -0,0 +1,1952 @@ +--- +# Copyright (c) 1994, 2023, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# This code is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 only, as +# published by the Free Software Foundation. +# +# This code is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# version 2 for more details (a copy is included in the LICENSE file that +# accompanied this code). +# +# You should have received a copy of the GNU General Public License version +# 2 along with this work; if not, write to the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +# or visit www.oracle.com if you need additional information or have any +# questions. +# + +title: 'JAVAC(1) JDK @@VERSION_SHORT@@ | JDK Commands' +date: @@COPYRIGHT_YEAR@@ +lang: en +--- + +## Name + +javac - read Java declarations and compile them into class files + +## Synopsis + +`javac` \[*options*\] \[*sourcefiles-or-classnames*\] + +*options* +: Command-line options. + +*sourcefiles-or-classnames* +: Source files to be compiled (for example, `Shape.java`) or + the names of previously compiled classes to be processed for annotations + (for example, `geometry.MyShape`). + +## Description + +The `javac` command reads _source files_ that contain module, package and type +declarations written in the Java programming language, and compiles them into _class files_ +that run on the Java Virtual Machine. + +The `javac` command can also [process annotations](#annotation-processing) +in Java source files and classes. + +Source files must have a file name extension of `.java`. +Class files have a file name extension of `.class`. +Both source and class files normally have file names that identify the contents. +For example, a class called `Shape` would be declared in a source file +called `Shape.java`, and compiled into a class file called `Shape.class`. + +There are two ways to specify source files to `javac`: + +- For a small number of source files, you can list their file names on + the command line. + +- For a large number of source files, you can use the [`@`*filename*](#option-at) + option on the command line to specify an _argument file_ that lists + their file names. See [Standard Options] for a description of the + option and [Command-Line Argument Files] for a description of + `javac` argument files. + +The order of source files specified on the command line or in an +argument file is not important. `javac` will compile the files together, +as a group, and will automatically resolve any dependencies between +the declarations in the various source files. + +`javac` expects that source files are arranged in one or more directory +hierarchies on the file system, described in [Arrangement of Source +Code]. + +To compile a source file, `javac` needs to find the declaration of +every class or interface that is used, extended, or implemented by the +code in the source file. This lets `javac` check that the code has the +right to access those classes and interfaces. Rather than specifying +the source files of those classes and interfaces explicitly, you can +use command-line options to tell `javac` where to search for their +source files. If you have compiled those source files previously, you +can use options to tell `javac` where to search for the corresponding +class files. The options, which all have names ending in "path", are +described in [Standard Options], and further described in +[Configuring a Compilation] and [Searching for Module, Package and Type Declarations]. + +By default, `javac` compiles each source file to a class file in the +same directory as the source file. However, it is recommended to +specify a separate destination directory with the [`-d`](#option-d) option. + +Command-line [options] and [environment variables] also control how +`javac` performs various tasks: + +- Compiling code to run on earlier releases of the JDK. +- Compiling code to run under a debugger. +- Checking for stylistic issues in Java source code. +- Checking for problems in `javadoc` comments (`/** ... */`). +- Processing annotations in source files and class files. +- Upgrading and patching modules in the compile-time environment. + +`javac` supports [Compiling for Earlier Releases Of The Platform] +and can also be invoked from Java code using one of a number of [APIs] + +## Options + +`javac` provides [standard options], and [extra options] that are either +non-standard or are for advanced use. + +Some options take one or more arguments. +If an argument contains spaces or other whitespace characters, +the value should be quoted according to the conventions of the +environment being used to invoke javac. +If the option begins with a single dash (`-`) the argument should +either directly follow the option name, or should be separated with a +colon (`:`) or whitespace, depending on the option. If the option begins with +a double dash (`--`), the argument may be separated either by whitespace +or by an equals (`=`) character with no additional whitespace. +For example, + + -Aname="J. Duke" + -proc:only + -d myDirectory + --module-version 3 + --module-version=3 + +In the following lists of options, an argument of *path* represents +a search path, composed of a list of file system locations separated +by the platform path separator character, (semicolon `;` on Windows, +or colon `:` on other systems.) Depending on the option, the +file system locations may be directories, JAR files or JMOD files. + +### Standard Options + +`@`*filename* +: Reads options and file names from a file. To shorten or simplify the + `javac` command, you can specify one or more files that contain arguments + to the `javac` command (except [`-J`](#option-J) options). This lets you to create + `javac` commands of any length on any operating system. + See [Command-Line Argument Files]. + +`-A`*key*\[`=`*value*\] +: Specifies options to pass to annotation processors. These options are not + interpreted by `javac` directly, but are made available for use by + individual processors. The *key* value should be one or more identifiers + separated by a dot (`.`). + +`--add-modules` *module*`,`*module* +: Specifies root modules to resolve in addition to the initial modules, or + all modules on the module path if *module* is `ALL-MODULE-PATH`. + +`--boot-class-path` *path* or `-bootclasspath` *path* +: Overrides the location of the bootstrap class files. + + **Note:** This can only be used when compiling for releases prior to JDK 9. + As applicable, see the descriptions in [`--release`](#option-release), [`-source`](#option-source), or + [`-target`](#option-target) for details. For JDK 9 or later, see [`--system`](#option-system). + +`--class-path` *path*, `-classpath` *path*, or `-cp` *path* +: Specifies where to find user class files and annotation processors. This + class path overrides the user class path in the `CLASSPATH` environment + variable. + + - If `--class-path`, `-classpath`, or `-cp` are not specified, then the + user class path is the value of the `CLASSPATH` environment variable, + if that is set, or else the current directory. + + - If not compiling code for modules, if the [`--source-path`](#option-source-path) or -sourcepath` + option is not specified, then the user class path is also searched for source files. + + - If the [`-processorpath`](#option-processor-path) option is not specified, then the class path is + also searched for annotation processors. + +`-d` *directory* +: Sets the destination directory (or _class output directory_) for class files. + If a class is part of a package, then `javac` puts the class file in a + subdirectory that reflects the module name (if appropriate) and package name. + The directory, and any necessary subdirectories, will be created if they + do not already exist. + + If the `-d` option is not specified, then `javac` puts each class file in + the same directory as the source file from which it was generated. + + Except when compiling code for multiple modules, the contents of the + class output directory will be organized in a package hierarchy. + When compiling code for multiple modules, the contents of the output + directory will be organized in a module hierarchy, with the contents of each + module in a separate subdirectory, each organized as a package + hierarchy. + + **Note:** + When compiling code for one or more modules, the class output directory will + automatically be checked when searching for previously compiled classes. + When not compiling for modules, for backwards compatibility, + the directory is _not_ automatically checked for previously compiled classes, + and so it is recommended to specify the class output directory as one + of the locations on the user class path, using the `--class-path` option or one of + its alternate forms. + +`-deprecation` +: Shows a description of each use or override of a deprecated member or + class. Without the `-deprecation` option, `javac` shows a summary of the + source files that use or override deprecated members or classes. The + `-deprecation` option is shorthand for `-Xlint:deprecation`. + +`--enable-preview` +: Enables preview language features. Used in conjunction with either + [`-source`](#option-source) or [`--release`](#option-release). + +`-encoding` *encoding* +: Specifies character encoding used by source files, such as EUC-JP and + UTF-8. If the `-encoding` option is not specified, then the platform default + converter is used. + +`-endorseddirs` *directories* +: Overrides the location of the endorsed standards path. + + **Note:** This can only be used when compiling for releases prior to JDK 9. + As applicable, see the descriptions in [`--release`](#option-release), [`-source`](#option-source), or + [`-target`](#option-target) for details. + +`-extdirs` *directories* +: Overrides the location of the installed extensions. + `directories` is a list of directories, separated by the platform path separator + (`;` on Windows, and `:` otherwise). + Each JAR file in the specified directories is searched for class files. + All JAR files found become part of the class path. + + If you are compiling for a release of the platform that supports the + Extension Mechanism, then this option specifies the directories that + contain the extension classes. + See [Compiling for Other Releases of the Platform]. + + **Note:** This can only be used when compiling for releases prior to JDK 9. + As applicable, see the descriptions in [`--release`](#option-release), [`-source`](#option-source), or + [`-target`](#option-target) for details. + +`-g` +: Generates all debugging information, including local variables. By default, + only line number and source file information is generated. + +`-g:`\[`lines`, `vars`, `source`\] +: Generates only the kinds of debugging information specified by the + comma-separated list of keywords. Valid keywords are: + + `lines` + : Line number debugging information. + + `vars` + : Local variable debugging information. + + `source` + : Source file debugging information. + +`-g:none` +: Does not generate debugging information. + +`-h` *directory* +: Specifies where to place generated native header files. + + When you specify this option, a native header file is generated for each + class that contains native methods or that has one or more constants + annotated with the [`java.lang.annotation.Native`]( + ../../api/java.base/java/lang/annotation/Native.html) + annotation. If the class is part of a package, then the compiler puts the + native header file in a subdirectory that reflects the module name + (if appropriate) and package name. + The directory, and any necessary subdirectories, will be created if they + do not already exist. + +`--help`, `-help` or `-?` +: Prints a synopsis of the standard options. + +`--help-extra` or `-X` +: Prints a synopsis of the set of extra options. + +`--help-lint` +: Prints the supported keys for the `-Xlint` option. + +`-implicit:`\[`none`, `class`\] +: Specifies whether or not to generate class files for implicitly referenced + files: + + - `-implicit:class` --- Automatically generates class files. + + - `-implicit:none` --- Suppresses class file generation. + + If this option is not specified, then the default automatically generates + class files. In this case, the compiler issues a warning if any class files + are generated when also doing annotation processing. The warning is not + issued when the `-implicit` option is explicitly set. + See [Searching for Module, Package and Type Declarations]. + +`-J`*option* +: Passes *option* to the runtime system, where *option* is one of the Java + options described on [java](java.html) command. For example, `-J-Xms48m` + sets the startup memory to 48 MB. + + **Note:** The `CLASSPATH` environment variable, `-classpath` option, `-bootclasspath` + option, and `-extdirs` option do not specify the classes used to run + `javac`. Trying to customize the compiler implementation with these options + and variables is risky and often does not accomplish what you want. If you + must customize the compiler implementation, then use the `-J` option to + pass options through to the underlying Java launcher. + +`--limit-modules` *module*`,`*module*\* +: Limits the universe of observable modules. + +`--module` *module-name* (`,`*module-name*)* or `-m` *module-name* (`,`*module-name*)* +: Compiles those source files in the named modules that are newer + than the corresponding files in the output directory. + +`--module-path` *path* or `-p` *path* +: Specifies where to find application modules. + +`--module-source-path` *module-source-path* +: Specifies where to find source files when compiling code + in multiple modules. See [The Module Source Path Option]. + +`--module-version` *version* +: Specifies the version of modules that are being compiled. + +`-nowarn` +: Disables warning messages. This option operates the same as the + `-Xlint:none` option. + +`-parameters` +: Generates metadata for reflection on method parameters. Stores formal + parameter names of constructors and methods in the generated class file so + that the method `java.lang.reflect.Executable.getParameters` from the + Reflection API can retrieve them. + +`-proc:`\[`none`, `only`, `full`\] +: Controls whether annotation processing and compilation are done. + `-proc:none` means that compilation takes place without annotation + processing. `-proc:only` means that only annotation processing is done, + without any subsequent compilation. If this option is not used, or + `-proc:full` is specified, annotation processing and compilation are done. + +`-processor` *class1*\[`,`*class2*`,`*class3*...\] +: Names of the annotation processors to run. This bypasses the default + discovery process. + +`--processor-module-path` *path* +: Specifies the module path used for finding annotation processors. + +`--processor-path` *path* or `-processorpath` *path* +: Specifies where to find annotation processors. If this option is not used, + then the class path is searched for processors. + +`-profile` *profile* +: Checks that the API used is available in the specified profile. + This option is deprecated and may be removed in a future release. + + **Note:** This can only be used when compiling for releases prior to JDK 9. + As applicable, see the descriptions in [`--release`](#option-release), [`-source`](#option-source), + or [`-target`](#option-target) for details. + +`--release` *release* +: Compiles source code according to the rules of the Java programming language + for the specified Java SE release, generating class files which target + that release. + Source code is compiled against the combined Java SE and JDK API for the + specified release. + + The supported values of *release* are the current Java SE release and a + limited number of previous releases, detailed in the command-line help. + + For the current release, the Java SE API consists of the `java.*`, + `javax.*`, and `org.*` packages that are exported by the Java SE modules in + the release; the JDK API consists of the `com.*` and `jdk.*` packages that + are exported by the JDK modules in the release, plus the `javax.*` packages + that are exported by standard, but non-Java SE, modules in the release. + + For previous releases, the Java SE API and the JDK API are as defined in + that release. + + **Note:** When using `--release`, you cannot also use the [`--source`](#option-source)/`-source` or + [`--target`](#option-target)/`-target` options. + + **Note:** When using `--release` to specify a release that supports the Java + Platform Module System, the `--add-exports` option cannot be used to + enlarge the set of packages exported by the Java SE, JDK, and standard + modules in the specified release. + +`-s` *directory* +: Specifies the directory used to place the generated source files. If a + class is part of a package, then the compiler puts the source file in a + subdirectory that reflects the module name (if appropriate) and package name. + The directory, and any necessary subdirectories, will be created if they + do not already exist. + + Except when compiling code for multiple modules, the contents of the + source output directory will be organized in a package hierarchy. + When compiling code for multiple modules, the contents of the source output directory will be + organized in a module hierarchy, with the contents of each + module in a separate subdirectory, each organized as a package + hierarchy. + +`--source` *release* or `-source` *release* +: Compiles source code according to the rules of the Java programming language + for the specified Java SE release. + The supported values of *release* are the current Java SE release and a + limited number of previous releases, detailed in the command-line help. + + If the option is not specified, the default is to compile source code + according to the rules of the Java programming language for the current + Java SE release. + +`--source-path` *path* or `-sourcepath` *path* +: Specifies where to find source files. + Except when compiling multiple modules together, this is the source code path + used to search for class or interface definitions. + + **Note:** Classes found through the class path might be recompiled when their source + files are also found. See [Searching for Module, Package and Type Declarations]. + +`--system` *jdk* \| `none` +: Overrides the location of system modules. + +`--target` *release* or `-target` *release* +: Generates `class` files suitable for the specified Java SE release. + The supported values of *release* are the current Java SE release and a + limited number of previous releases, detailed in the command-line help. + + **Note:** The target release must be equal to or higher than the source release. + (See [`--source`](#option-source).) + +`--upgrade-module-path` *path* +: Overrides the location of upgradeable modules. + +`-verbose` +: Outputs messages about what the compiler is doing. Messages include + information about each class loaded and each source file compiled. + +`--version` or `-version` +: Prints version information. + +`-Werror` +: Terminates compilation when warnings occur. + +### Extra Options + +`--add-exports` *module*`/`*package*`=`*other-module*(`,`*other-module*)\* +: Specifies a package to be considered as exported from its defining module + to additional modules or to all unnamed modules when the value of + *other-module* is `ALL-UNNAMED`. + +`--add-reads` *module*`=`*other-module*(`,`*other-module*)\* +: Specifies additional modules to be considered as required by a given + module. + +`--default-module-for-created-files` *module-name* +: Specifies the fallback target module for files created by annotation + processors, if none is specified or inferred. + +`--disable-line-doc-comments` +: Disables support for documentation comments with lines beginning ///. + +`-Djava.endorsed.dirs=`*dirs* +: Overrides the location of the endorsed standards path. + + **Note:** This can only be used when compiling for releases prior to JDK 9. + As applicable, see the descriptions in [`--release`](#option-release), [`-source`](#option-source), + or [`-target`](#option-target) for details. + +`-Djava.ext.dirs=`*dirs* +: Overrides the location of installed extensions. + + **Note:** This can only be used when compiling for releases prior to JDK 9. + As applicable, see the descriptions in [`--release`](#option-release), [`-source`](#option-source), + or [`-target`](#option-target) for details. + +`--patch-module` *module*`=`*path* +: Overrides or augments a module with classes and resources in JAR files or + directories. + +`-Xbootclasspath:`*path* +: Overrides the location of the bootstrap class files. + + **Note:** This can only be used when compiling for releases prior to JDK 9. + As applicable, see the descriptions in [`--release`](#option-release), [`-source`](#option-source), + or [`-target`](#option-target) for details. + +`-Xbootclasspath/a:`*path* +: Adds a suffix to the bootstrap class path. + + **Note:** This can only be used when compiling for releases prior to JDK 9. + As applicable, see the descriptions in [`--release`](#option-release), [`-source`](#option-source), + or [`-target`](#option-target) for details. + +`-Xbootclasspath/p:`*path* +: Adds a prefix to the bootstrap class path. + + **Note:** This can only be used when compiling for releases prior to JDK 9. + As applicable, see the descriptions in [`--release`](#option-release), [`-source`](#option-source), + or [`-target`](#option-target) for details. + +`-Xdiags:`\[`compact`, `verbose`\] +: Selects a diagnostic mode. + +`-Xdoclint` +: Enables recommended checks for problems in documentation comments. + +`-Xdoclint:`(`all`|`none`|\[`-`\]*group*)\[`/`*access*\] +: Enables or disables specific groups of checks in documentation comments. + + *group* can have one of the following values: + `accessibility`, `html`, `missing`, `reference`, `syntax`. + + The variable *access* specifies the minimum visibility level of classes and + members that the `-Xdoclint` option checks. It can have one of the + following values (in order of most to least visible): + `public`, `protected`, `package`, `private`. + + The default *access* level is `private`. + + When prefixed by `doclint:`, the *group* names and `all` can be used with `@SuppressWarnings` + to suppress warnings about documentation comments in parts of the code being compiled. + + For more information about these groups of checks, see the [DocLint](javadoc.html#doclint) + section of the `javadoc` command documentation. + The `-Xdoclint` option is disabled by default in the `javac` command. + + For example, the following option checks classes and members (with all + groups of checks) that have the access level of protected and higher (which + includes protected and public): + + > `-Xdoclint:all/protected` + + The following option enables all groups of checks for all access levels, + except it will not check for HTML errors for classes and members that have the + access level of package and higher (which includes package, protected and + public): + + > `-Xdoclint:all,-html/package` + +`-Xdoclint/package:`\[`-`\]*packages*(`,`\[`-`\]*package*)\* +: Enables or disables checks in specific packages. Each *package* is either + the qualified name of a package or a package name prefix followed by `.*`, + which expands to all sub-packages of the given package. Each *package* can + be prefixed with a hyphen (`-`) to disable checks for a specified package + or packages. + + For more information, see the [DocLint](javadoc.html#doclint) + section of the `javadoc` command documentation. + +`-Xlint` +: Enables all recommended warnings. In this release, enabling all available + warnings is recommended. + +`-Xlint:`\[`-`\]*key*(`,`\[`-`\]*key*)\* +: Supplies warnings to enable or disable, separated by comma. Precede a key + by a hyphen (`-`) to disable the specified warning. + + Supported values for *key* are: + + - `all`: Enables all warnings. + + - `auxiliaryclass`: Warns about an auxiliary class that is hidden in a + source file, and is used from other files. + + - `cast`: Warns about the use of unnecessary casts. + + - `classfile`: Warns about the issues related to classfile contents. + + - `dangling-doc-comments`: Warns about extra or misplaced documentation + comments near the beginning of a declaration. + + - `deprecation`: Warns about the use of deprecated items. + + - `dep-ann`: Warns about the items marked as deprecated in `javadoc` but + without the `@Deprecated` annotation. + + - `divzero`: Warns about the division by the constant integer 0. + + - `empty`: Warns about an empty statement after `if`. + + - `exports`: Warns about the issues regarding module exports. + + - `fallthrough`: Warns about the falling through from one case of a + switch statement to the next. + + - `finally`: Warns about `finally` clauses that do not terminate normally. + + - `incubating`: Warns about the use of incubating modules. + + - `lossy-conversions`: Warns about possible lossy conversions + in compound assignment. + + - `missing-explicit-ctor`: Warns about missing explicit constructors in + public and protected classes in exported packages. + + - `module`: Warns about the module system-related issues. + + - `opens`: Warns about the issues related to module opens. + + - `options`: Warns about the issues relating to use of command line + options. + + - `output-file-clash`: Warns if any output file is overwritten during compilation. + This can occur, for example, on case-insensitive filesystems. + + - `overloads`: Warns about the issues related to method overloads. + + - `overrides`: Warns about the issues related to method overrides. + + - `path`: Warns about the invalid path elements on the command line. + + - `preview`: Warns about the use of preview language features. + + - `processing`: Warns about the issues related to annotation processing. + + - `rawtypes`: Warns about the use of raw types. + + - `removal`: Warns about the use of an API that has been marked for + removal. + + - `restricted`: Warns about the use of restricted methods. + + - `requires-automatic`: Warns developers about the use of automatic + modules in requires clauses. + + - `requires-transitive-automatic`: Warns about automatic modules in + requires transitive. + + - `serial`: Warns about the serializable classes that do not provide a + serial version ID. Also warns about access to non-public members from a + serializable element. + + - `static`: Warns about the accessing a static member using an instance. + + - `strictfp`: Warns about unnecessary use of the `strictfp` modifier. + + - `synchronization`: Warns about synchronization attempts on instances + of value-based classes. + + - `text-blocks`: Warns about inconsistent white space characters in text + block indentation. + + - `this-escape`: Warns about constructors leaking `this` prior to subclass initialization. + + - `try`: Warns about the issues relating to the use of try blocks (that + is, try-with-resources). + + - `unchecked`: Warns about the unchecked operations. + + - `varargs`: Warns about the potentially unsafe `vararg` methods. + + - `none`: Disables all warnings. + + With the exception of `all` and `none`, the keys can be used with + the `@SuppressWarnings` annotation to suppress warnings in a part + of the source code being compiled. + + See [Examples of Using -Xlint keys]. + +`-Xmaxerrs` *number* +: Sets the maximum number of errors to print. + +`-Xmaxwarns` *number* +: Sets the maximum number of warnings to print. + +`-Xpkginfo:`\[`always`, `legacy`, `nonempty`\] +: Specifies when and how the `javac` command generates `package-info.class` + files from `package-info.java` files using one of the following options: + + `always` + : Generates a `package-info.class` file for every `package-info.java` + file. This option may be useful if you use a build system such as Ant, + which checks that each `.java` file has a corresponding `.class` file. + + `legacy` + : Generates a `package-info.class` file only if `package-info.java` + contains annotations. This option does not generate a + `package-info.class` file if `package-info.java` contains only + comments. + + **Note:** A `package-info.class` file might be generated but be empty if all the + annotations in the `package-info.java` file have + `RetentionPolicy.SOURCE`. + + `nonempty` + : Generates a `package-info.class` file only if `package-info.java` + contains annotations with `RetentionPolicy.CLASS` or + `RetentionPolicy.RUNTIME`. + +`-Xplugin:`*name* *args* +: Specifies the name and optional arguments for a plug-in to be run. + If *args* are provided, *name* and *args* should be quoted or otherwise + escape the whitespace characters between the name and all the arguments. + For details on the API for a plugin, see the API documentation for + [jdk.compiler/com.sun.source.util.Plugin](../../api/jdk.compiler/com/sun/source/util/Plugin.html). + +`-Xprefer:`\[`source`, `newer`\] +: Specifies which file to read when both a source file and class file are + found for an implicitly compiled class using one of the following options. + See [Searching for Module, Package and Type Declarations]. + + - `-Xprefer:newer`: Reads the newer of the source or class files for a + type (default). + + - `-Xprefer:source` : Reads the source file. Use `-Xprefer:source` when + you want to be sure that any annotation processors can access + annotations declared with a retention policy of `SOURCE`. + +`-Xprint` +: Prints a textual representation of specified types for debugging purposes. + This does not perform annotation processing or compilation. The format of + the output could change. + +`-XprintProcessorInfo` +: Prints information about which annotations a processor is asked to process. + +`-XprintRounds` +: Prints information about initial and subsequent annotation processing + rounds. + +`-Xstdout` *filename* +: Sends compiler messages to the named file. By default, compiler messages go + to `System.err`. + +## Environment Variables + +### CLASSPATH + +If the [`--class-path`](#option-class-path) option or any of its alternate forms are not specified, +the class path will default to the value of the `CLASSPATH` environment +variable if it is set. +However, it is recommended that this environment variable should _not_ be set, +and that the `--class-path` option should be used to provide an explicit +value for the class path when one is required. + +### JDK\_JAVAC\_OPTIONS + +The content of the `JDK_JAVAC_OPTIONS` environment variable, separated by +white-spaces ( ) or white-space characters (`\n`, `\t`, `\r`, or `\f`) is +prepended to the command line arguments passed to `javac` as a list of +arguments. + +The encoding requirement for the environment variable is the same as the +`javac` command line on the system. `JDK_JAVAC_OPTIONS` environment variable +content is treated in the same manner as that specified in the command line. + +Single quotes (`'`) or double quotes (`"`) can be used to enclose arguments +that contain whitespace characters. All content between the open quote and the +first matching close quote are preserved by simply removing the pair of quotes. +In case a matching quote is not found, the launcher will abort with an error +message. `@`*files* are supported as they are specified in the command line. +However, as in `@`*files*, use of a wildcard is not supported. + +**Examples of quoting arguments containing white spaces:** + +> `export JDK_JAVAC_OPTIONS='@"C:\white spaces\argfile"'` + +> `export JDK_JAVAC_OPTIONS='"@C:\white spaces\argfile"'` + +> `export JDK_JAVAC_OPTIONS='@C:\"white spaces"\argfile'` + +## Command-Line Argument Files + +An argument file can include command-line options and source file names in any +combination. The arguments within a file can be separated by spaces or new line +characters. If a file name contains embedded spaces, then put the whole file +name in double quotation marks. + +File names within an argument file are relative to the current directory, not +to the location of the argument file. Wildcards (`*`) are not allowed in these +lists (such as for specifying `*.java`). Use of the at sign (`@`) to +recursively interpret files is not supported. The `-J` options are not supported +because they're passed to the launcher, which does not support argument files. + +When executing the `javac` command, pass in the path and name of each argument +file with the at sign (`@`) leading character. When the `javac` command +encounters an argument beginning with the at sign (`@`), it expands the +contents of that file into the argument list. + + +### Examples of Using javac @filename + +Single Argument File +: You could use a single argument file named `argfile` to hold all `javac` + arguments: + + > `javac @argfile` + + This argument file could contain the contents of both files shown in the + following **Two Argument Files** example. + +Two Argument Files +: You can create two argument files: one for the `javac` options and the + other for the source file names. Note that the following lists have no + line-continuation characters. + + Create a file named `options` that contains the following: + + **Linux and macOS:** + + ``` + -d classes + -g + -sourcepath /java/pubs/ws/1.3/src/share/classes + ``` + + **Windows:** + + ``` + -d classes + -g + -sourcepath C:\java\pubs\ws\1.3\src\share\classes + ``` + + Create a file named `sources` that contains the following: + + ``` + MyClass1.java + MyClass2.java + MyClass3.java + ``` + + Then, run the `javac` command as follows: + + > `javac @options @sources` + +Argument Files with Paths +: The argument files can have paths, but any file names inside the files are + relative to the current working directory (not `path1` or `path2`): + + > `javac @path1/options @path2/sources` + +## Arrangement of Source Code + +In the Java language, classes and interfaces can be organized into +packages, and packages can be organized into modules. `javac` expects +that the physical arrangement of source files in directories of the +file system will mirror the organization of classes into packages, and +packages into modules. + +It is a widely adopted convention that module names and package names +begin with a lower-case letter, and that class names begin with an +upper-case letter. + +### Arrangement of Source Code for a Package + +When classes and interfaces are organized into a package, the package +is represented as a directory, and any subpackages are represented as +subdirectories. + +For example: + +- The package `p` is represented as a directory called `p`. + +- The package `p.q` -- that is, the subpackage `q` of package `p` -- + is represented as the subdirectory `q` of directory `p`. The + directory tree representing package `p.q` is therefore `p\q` + on Windows, and `p/q` on other systems. + +- The package `p.q.r` is represented as the directory tree `p\q\r` + (on Windows) or `p/q/r` (on other systems). + +Within a directory or subdirectory, `.java` files represent classes +and interfaces in the corresponding package or subpackage. + +For example: + +- The class `X` declared in package `p` is represented by the file + `X.java` in the `p` directory. + +- The class `Y` declared in package `p.q` is represented by the file + `Y.java` in the `q` subdirectory of directory `p`. + +- The class `Z` declared in package `p.q.r` is represented by the file + `Z.java` in the `r` subdirectory of `p\q` (on Windows) or `p/q` + (on other systems). + +In some situations, it is convenient to split the code into +separate directories, each structured as described above, and +the aggregate list of directories specified to `javac`. + +### Arrangement of Source Code for a Module + +In the Java language, a module is a set of packages designed for +reuse. In addition to `.java` files for classes and interfaces, each +module has a source file called `module-info.java` which: + +1. declares the module's name; + +2. lists the packages exported by the module (to allow reuse by other + modules); + +3. lists other modules required by the module (to reuse their exported + packages). + +When packages are organized into a module, the module is represented +by one or more directories representing the packages in the module, +one of which contains the `module-info.java` file. It may be convenient, +but it is not required, to use a single directory, named after the module, +to contain the `module-info.java` file alongside the directory tree which +represents the packages in the module (i.e., the _package hierarchy_ +described above). The exact arrangement of source code for a module +is typically dictated by the conventions adopted by a development +environment (IDE) or build system. + +For example: + +- The module `a.b.c` may be represented by the directory `a.b.c`, on all + systems. + +- The module's declaration is represented by the file + `module-info.java` in the `a.b.c` directory. + +- If the module contains package `p.q.r`, then the `a.b.c` directory + contains the directory tree `p\q\r` (on Windows) or `p/q/r` + (on other systems). + +The development environment may prescribe some directory hierarchy +between the directory named for the module and the source files to +be read by `javac`. + +For example: + +- The module `a.b.c` may be represented by the directory `a.b.c` + +- The module's declaration and the module's packages may be in + some subdirectory of `a.b.c`, such as `src\main\java` (on Windows) + or `src/main/java` (on other systems). + + +## Configuring a Compilation + +This section describes how to configure `javac` to perform a basic compilation. + +See [Configuring the Module System] for additional details for use when compiling +for a release of the platform that supports modules. + +### Source Files + +* Specify the source files to be compiled on the command line. + +If there are no compilation errors, the corresponding class files will +be placed in the [output directory]. + +Some systems may limit the amount you can put on a command line; +to work around those limits, you can use [argument files](#command-line-argument-files). + +When compiling code for modules, you can also specify source files indirectly, +by using the [`--module`](#option-module) or `-m` option. + +### Output Directory + +* Use the [`-d`](#option-d) option to specify an output directory in which to put the compiled class files. + +This will normally be organized in a [package hierarchy](#package-hierarchy), +unless you are compiling source code from multiple modules, in which case it will be +organized as a [module hierarchy](#module-hierarchy). + +When the compilation has been completed, if you are compiling one or more modules, +you can place the output directory on the module path for the Java [launcher](java.html); +otherwise, you can place the place the output directory on the class path +for the Java launcher. + +### Precompiled Code + +The code to be compiled may refer to libraries beyond what is provided by the platform. +If so, you must place these libraries on the class path or module path. +If the library code is not in a module, place it on the class path; +if it is in a module, place it on the module path. + +* Use the [`--class-path`](#option-class-path) option to specify libraries to be placed on the class path. + Locations on the class path should be organized in a [package hierarchy](#package-hierarchy). + You can also use alternate forms of the option: `-classpath` or `-cp`. + +* Use the [`--module-path`](#option-module-path) option to specify libraries to be placed on the module path. + Locations on the module path should either be modules or directories of modules. + You can also use an alternate form of the option: `-p`. + + See [Configuring the Module System] for details on how to modify the default + configuration of library modules. + +**Note**: the options for the class path and module path are not mutually +exclusive, although it is not common to specify the class path when compiling +code for one or more modules. + +### Additional Source Files + +The code to be compiled may refer to types in additional source files that are not +specified on the command line. +If so, you must put those source files on either the source path or module path. +You can only specify one of these options: if you are not compiling code for a module, +or if you are only compiling code for a single module, use the source path; +if you are compiling code for multiple modules, use the module source path. + +* Use the [`--source-path`](#option-source-path) option to specify the locations of additional source + files that may be read by javac. + Locations on the source path should be organized in a [package hierarchy](#package-hierarchy). + You can also use an alternate form of the option: `-sourcepath`. + +* Use the [`--module-source-path`](#option-module-source-path) option one or more times to specify the location + of additional source files in different modules that may be read by javac, + or when compiling source files in multiple modules. + You can either specify the locations for each module [individually](#module-specific-form), + or you can organize the source files so that you can specify the locations all + [together](#module-pattern-form). For more details, see [The Module Source Path Option]. + +If you want to be able to refer to types in additional source files but do not +want them to be compiled, use the [`-implicit`](#option-implicit) option. + +**Note**: if you are compiling code for multiple modules, you must always specify +a module source path, and all source files specified on the command line must be +in one of the directories on the module source path, or in a subdirectory thereof. + + +### Example of Compiling Multiple Source Files + +This example compiles the `Aloha.java`, `GutenTag.java`, `Hello.java`, and +`Hi.java` source files in the `greetings` package. + +**Linux and macOS:** + +``` +% javac greetings/*.java +% ls greetings +Aloha.class GutenTag.class Hello.class Hi.class +Aloha.java GutenTag.java Hello.java Hi.java +``` + +**Windows:** + +``` +C:\>javac greetings\*.java +C:\>dir greetings +Aloha.class GutenTag.class Hello.class Hi.class +Aloha.java GutenTag.java Hello.java Hi.java +``` + +### Example of Specifying a User Class Path + +After changing one of the source files in the previous example, recompile it: + +**Linux and macOS:** + +``` +pwd +/examples +javac greetings/Hi.java +``` + +**Windows:** + +``` +C:\>cd +\examples +C:\>javac greetings\Hi.java +``` + +Because `greetings.Hi` refers to other classes in the `greetings` package, the +compiler needs to find these other classes. The previous example works because +the default user class path is the directory that contains the package +directory. If you want to recompile this file without concern for which +directory you are in, then add the examples directory to the user class path by +setting `CLASSPATH`. This example uses the `-classpath` option. + +**Linux and macOS:** + +> `javac -classpath /examples /examples/greetings/Hi.java` + +**Windows:** + +> `C:\>javac -classpath \examples \examples\greetings\Hi.java` + +If you change `greetings.Hi` to use a banner utility, then that utility also +needs to be accessible through the user class path. + +**Linux and macOS:** + +``` +javac -classpath /examples:/lib/Banners.jar \ + /examples/greetings/Hi.java +``` + +**Windows:** + +``` +C:\>javac -classpath \examples;\lib\Banners.jar ^ + \examples\greetings\Hi.java +``` + +To execute a class in the `greetings` package, the program needs access to the +`greetings` package, and to the classes that the `greetings` classes use. + +**Linux and macOS:** + +> `java -classpath /examples:/lib/Banners.jar greetings.Hi` + +**Windows:** + +> `C:\>java -classpath \examples;\lib\Banners.jar greetings.Hi` + +## Configuring the Module System + +If you want to include additional modules in your compilation, use the +[`--add-modules`](#option-add-modules) option. +This may be necessary when you are compiling code that is not in a module, +or which is in an automatic module, and the code refers to API in the additional +modules. + +If you want to restrict the set of modules in your compilation, use the +[`--limit-modules`](#option-limit-modules) option. +This may be useful if you want to ensure that the code you are compiling +is capable of running on a system with a limited set of modules installed. + +If you want to break encapsulation and specify that additional packages +should be considered as exported from a module, use the [`--add-exports`](#option-add-exports) option. +This may be useful when performing white-box testing; relying on access +to internal API in production code is strongly discouraged. + +If you want to specify that additional packages +should be considered as required by a module, use the [`--add-reads`](#option-add-reads) option. +This may be useful when performing white-box testing; relying on access +to internal API in production code is strongly discouraged. + +You can patch additional content into any module using the +[`--patch-module`](#option-patch-module) option. See [Patching a Module] for more details. + +## Searching for Module, Package and Type Declarations + +To compile a source file, the compiler often needs information about a module +or type, but the declaration is not in the source files specified on the command +line. + +`javac` needs type information for every class or interface used, +extended, or implemented in the source file. This includes classes and +interfaces not explicitly mentioned in the source file, but that provide +information through inheritance. + +For example, when you create a subclass of `java.awt.Window`, you are also +using the ancestor classes of `Window`: `java.awt.Container`, +`java.awt.Component`, and `java.lang.Object`. + +When compiling code for a module, the compiler also needs to have available +the declaration of that module. + +A successful search may produce a class file, a source file, or both. If +both are found, then you can use the [`-Xprefer`](#option-Xprefer) option to instruct the compiler +which to use. + +If a search finds and uses a source file, then by default `javac` +compiles that source file. This behavior can be altered with +[`-implicit`](#option-implicit). + +The compiler might not discover the need for some type information until after +annotation processing completes. When the type information is found in a source +file and no [`-implicit`](#option-implicit) option is specified, the compiler gives a warning that +the file is being compiled without being subject to annotation processing. To +disable the warning, either specify the file on the command line (so that it +will be subject to annotation processing) or use the [`-implicit`](#option-implicit) option to +specify whether or not class files should be generated for such source files. + +The way that `javac` locates the declarations of those types +depends on whether the reference exists within code for a module or not. + +### Searching Package Oriented Paths + +When searching for a source or class file on a path composed of package oriented +locations, `javac` will check each location on the path in turn for the +possible presence of the file. The first occurrence of a particular file +shadows (hides) any subsequent occurrences of like-named files. This shadowing +does not affect any search for any files with a different name. This can be +convenient when searching for source files, which may be grouped in different +locations, such as shared code, platform-specific code and generated code. +It can also be useful when injecting alternate versions of a class file into +a package, to debugging or other instrumentation reasons. But, it can also +be dangerous, such as when putting incompatible different versions of a library +on the class path. + +### Searching Module Oriented Paths + +Prior to scanning any module paths for any package or type declarations, +`javac` will lazily scan the following paths and locations to determine +the modules that will be used in the compilation. + +* The module source path (see the [`--module-source-path`](#option-module-source-path) option) +* The path for upgradeable modules (see the [`--upgrade-module-path`](#option-upgrade-module-path) option) +* The system modules (see the [`--system`](#option-system) option) +* The user module path ( see the [`--module-path`](#option-module-path) option) + +For any module, the first occurrence of the module during the scan completely +shadows (hides) any subsequent appearance of a like-named module. While locating +the modules, `javac` is able to determine the packages exported by the module +and to associate with each module a package oriented path for the contents of +the module. For any previously compiled module, this path will typically be a +single entry for either a directory or a file that provides an internal +directory-like hierarchy, such as a JAR file. Thus, when searching for a type +that is in a package that is known to be exported by a module, `javac` can +locate the declaration directly and efficiently. + +### Searching for the Declaration of a Module + +If the module has been previously compiled, the module declaration is +located in a file named `module-info.class` in the root of the package hierarchy +for the content of the module. + +If the module is one of those currently being compiled, the module declaration +will be either the file named `module-info.class` in the root of the +package hierarchy for the module in the class output directory, or the +file named `module-info.java` in one of the locations on the source path +or one the module source path for the module. + +### Searching for the Declaration of a Type When the Reference is not in a Module + +When searching for a type that is referenced in code that is not in a module, +`javac` will look in the following places: + +* The platform classes (or the types in exported packages of the platform modules) + (This is for compiled class files only.) + +* Types in exported packages of any modules on the module path, if applicable. + (This is for compiled class files only.) + +* Types in packages on the class path and/or source path: + + * If both are specified, `javac` looks for compiled class files on the class path + and for source files on the source path. + + * If the class path is specified, but not source path, `javac` looks for both + compiled class files and source files on the class path. + + * If the class path is not specified, it defaults to the current directory. + +When looking for a type on the class path and/or source path, if both a compiled +class file and a source file are found, the most recently modified file will +be used by default. +If the source file is newer, it will be compiled and will may override any +previously compiled version of the file. You can use the [`-Xprefer`](#option-Xprefer) option +to override the default behavior. + +### Searching for the Declaration of a Type When the Reference is in a Module + +When searching for a type that is referenced in code in a module, +`javac` will examine the declaration of the enclosing module to determine +if the type is in a package that is exported from another module that is +readable by the enclosing module. +If so, `javac` will simply and directly go to the definition of that module +to find the definition of the required type. +Unless the module is another of the modules being compiled, `javac` will +only look for compiled class files files. In other words, `javac` will +not look for source files in platform modules or modules on the module path. + +If the type being referenced is not in some other readable module, +`javac` will examine the module being compiled to try and find the +declaration of the type. +`javac` will look for the declaration of the type as follows: + +* Source files specified on the command line or on the source path or + module source path. + +* Previously compiled files in the output directory. + + +## Directory Hierarchies + +`javac` generally assumes that source files and compiled class files will be +organized in a file system directory hierarchy or in a type of file that +supports in an internal directory hierarchy, such as a JAR file. +Three different kinds of hierarchy are supported: a _package hierarchy_, +a _module hierarchy_, and a _module source hierarchy_. + +While `javac` is fairly relaxed about the organization of source code, +beyond the expectation that source will be organized in one or package +hierarchies, and can generally accommodate organizations prescribed by +development environments and build tools, Java tools in general, +and `javac` and the Java launcher in particular, are more stringent +regarding the organization of compiled class files, and will be +organized in package hierarchies or module hierarchies, as appropriate. + +The location of these hierarchies are specified to `javac` with command-line +options, whose names typically end in "path", like [`--source-path`](#option-source-path) or +[`--class-path`](#option-class-path). Also as a general rule, path options whose name includes the +word `module`, like [`--module-path`](#option-module-path), are used to specify module hierarchies, +although some module-related path options allow a package hierarchy to be +specified on a per-module basis. All other path options are used to specify +package hierarchies. + +### Package Hierarchy + +In a package hierarchy, directories and subdirectories are used +to represent the component parts of the package name, with the source +file or compiled class file for a type being stored as a file with an +extension of `.java` or `.class` in the most nested directory. + +For example, in a package hierarchy, the source file for a class +`com.example.MyClass` will be stored in the file _com/example/MyClass.java_ + +### Module Hierarchy + +In a module hierarchy, the first level of directories are named +for the modules in the hierarchy; within each of those directories +the contents of the module are organized in package hierarchies. + +For example, in a module hierarchy, the compiled class file for a type called +`com.example.MyClass` in a module called `my.library` will be stored in +_my.library/com/example/MyClass.class_. + +The various output directories used by `javac` (the class output directory, +the source output directory, and native header output directory) +will all be organized in a module hierarchy when multiple modules are being compiled. + +### Module Source Hierarchy + +Although the source for each individual module should always be +organized in a package hierarchy, it may be convenient to group +those hierarchies into a module source hierarchy. This is similar +to a module hierarchy, except that there may be intervening directories +between the directory for the module and the directory that is +the root of the package hierarchy for the source code of the module. + +For example, in a module source hierarchy, the source file for a type called +`com.example.MyClass` in a module called `my.library` may be stored in a +file such as +_my.library/src/main/java/com/example/MyClass.java_. + +## The Module Source Path Option + +The [`--module-source-path`](#option-module-source-path) option has two forms: a _module-specific form_, +in which a package path is given for each module containing code to be compiled, +and a _module-pattern_ form, in which the source path for each module is specified +by a pattern. +The module-specific form is generally simpler to use when only a small number of +modules are involved; the module-pattern form may be more convenient when the +number of modules is large and the modules are organized in a regular manner that +can be described by a pattern. + +Multiple instances of the `--module-source-path` option may be given, each one +using either the module-pattern form or the module-specific form, subject to the +following limitations: + +* the module-pattern form may be used at most once +* the module-specific form may be used at most once for any given module + +If the module-specific form is used for any module, the associated search path +overrides any path that might otherwise have been inferred from the module-pattern form. + +### Module-specific form + +The module-specific form allows an explicit search path to be given for any specific module. +This form is: + +* `--module-source-path` *module-name*`=`*file-path* (*path-separator* *file-path*)* + +The path separator character is `;` on Windows, and `:` otherwise. + +**Note:** this is similar to the form used for the [`--patch-module`](#option-patch-module) option. + +### Module-pattern form + +The module-pattern form allows a concise specification of the module source path +for any number of modules organized in regular manner. + +* `--module-source-path` *pattern* + +The pattern is defined by the following rules, which are applied in order: + +* The argument is considered to be a series of segments separated by the path + separator character (`;` on Windows, and `:` otherwise). + +* Each segment containing curly braces of the form + + string1{alt1 ( ,alt2 )* } string2 + + is considered to be replaced by a series of segments formed by "expanding" the braces: + + string1 alt1 string2 + string1 alt2 string2 + and so on... + + The braces may be nested. + + This rule is applied for all such usages of braces. + + * Each segment must have at most one asterisk (`*`). + If a segment does not contain an asterisk, it is considered to be as though the + file separator character and an asterisk are appended. + + For any module _M_, the source path for that module is formed from the series + of segments obtained by substituting the module name _M_ for the asterisk in + each segment. + + **Note**: in this context, the asterisk is just used as a special marker, to + denote the position in the path of the module name. It should not be confused + with the use of `*` as a file name wildcard character, as found on most + operating systems. + +## Patching Modules + +javac allows any content, whether in source or compiled form, to be patched +into any module using the [`--patch-module`](#option-patch-module) option. +You may want to do this to compile alternative implementations of a class +to be patched at runtime into a JVM, or to inject additional classes into +the module, such as when testing. + +The form of the option is: + +* `--patch-module` *module-name*`=`*file-path* (*path-separator* *file-path* )* + +The path separator character is `;` on Windows, and `:` otherwise. +The paths given for the module must specify the root of a +package hierarchy for the contents of the module + +The option may be given at most once for any given module. +Any content on the path will hide any like-named content later in the path +and in the patched module. + +When patching source code into more than one module, the [`--module-source-path`](#option-module-source-path) +must also be used, so that the output directory is organized in a module hierarchy, +and capable of holding the compiled class files for the modules being compiled. + +## Annotation Processing + +The `javac` command provides direct support for annotation processing. + +The API for annotation processors is defined in the +`javax.annotation.processing` and `javax.lang.model` packages and subpackages. + +### How Annotation Processing Works + +Unless annotation processing is disabled with the [`-proc:none`](#option-proc) option, the +compiler searches for any annotation processors that are available. The search +path can be specified with the [`-processorpath`](#option-processor-path) option. If no path is +specified, then the user class path is used. Processors are located by means of +service provider-configuration files named +`META-INF/services/javax.annotation.processing.Processor` on the search path. +Such files should contain the names of any annotation processors to be used, +listed one per line. Alternatively, processors can be specified explicitly, +using the [`-processor`](#option-processor) option. + +After scanning the source files and classes on the command line to determine +what annotations are present, the compiler queries the processors to determine +what annotations they process. When a match is found, the processor is called. +A processor can claim the annotations it processes, in which case no further +attempt is made to find any processors for those annotations. After all of the +annotations are claimed, the compiler does not search for additional +processors. + +If any processors generate new source files, then another round of annotation +processing occurs: Any newly generated source files are scanned, and the +annotations processed as before. Any processors called on previous rounds are +also called on all subsequent rounds. This continues until no new source files +are generated. + +After a round occurs where no new source files are generated, the annotation +processors are called one last time, to give them a chance to complete any +remaining work. Finally, unless the [`-proc:only`](#option-proc) option is used, the compiler +compiles the original and all generated source files. + +If you use an annotation processor that generates additional source +files to be included in the compilation, you can specify a default +module to be used for the newly generated files, for use when a +module declaration is not also generated. In this case, use the +[`--default-module-for-created-files`](#option-default-module-for-created-files) option. + +### Compilation Environment and Runtime Environment. + +The declarations in source files and previously compiled class files are analyzed +by `javac` in a _compilation environment_ that is distinct from the +_runtime environment_ used to execute `javac` itself. Although there is a +deliberate similarity between many `javac` options and like-named options for the +Java [launcher](java.html), such as `--class-path`, `--module-path` and so +on, it is important to understand that in general the `javac` options just affect +the environment in which the source files are compiled, and do not affect +the operation of `javac` itself. + +The distinction between the compilation environment and runtime environment +is significant when it comes to using annotation processors. +Although annotations processors process elements (declarations) that exist +in the compilation environment, the annotation processor itself is executed +in the runtime environment. If an annotation processor has dependencies on +libraries that are not in modules, the libraries can be placed, along with the +annotation processor itself, on the processor path. +(See the [`--processor-path`](#option-processor-path) option.) +If the annotation processor and its dependencies are in modules, you should +use the processor module path instead. +(See the [`--processor-module-path`](#option-processor-module-path) option.) +When those are insufficient, it may be necessary to provide further +configuration of the runtime environment. This can be done in two ways: + +1. If `javac` is invoked from the command line, options can be passed to the + underlying runtime by prefixing the option with [`-J`](#option-J). + +2. You can start an instance of a Java Virtual Machine directly and use + command line options and API to configure an environment in which + `javac` can be invoked via one of its [APIs]. + +## Compiling for Earlier Releases of the Platform + +`javac` can compile code that is to be used on other releases of the platform, +using either the [`--release`](#option-release) option, or the [`--source`](#option-source)/`-source` and +[`--target`](#option-target)/`-target` options, together with additional options to specify the +platform classes. + +Depending on the desired platform release, there are some restrictions on some +of the options that can be used. + +* When compiling for JDK 8 and earlier releases, you cannot use any option + that is intended for use with the module system. + This includes all of the following options: + + * [`--module-source-path`](#option-module-source-path), + [`--upgrade-module-path`](#option-upgrade-module-path), + [`--system`](#option-system), + [`--module-path`](#option-module-path), + [`--add-modules`](#option-add-modules), + [`--add-exports`](#option-add-exports), + `--add-opens`, + [`--add-reads`](#option-add-reads), + [`--limit-modules`](#option-limit-modules), + [`--patch-module`](#option-patch-module) + + If you use the `--source`/`-source` or `--target`/`-target` options, + you should also set the appropriate platform classes using the + boot class path family of options. + +* When compiling for JDK 9 and later releases, you cannot use any option + that is intended to configure the boot class path. + This includes all of the following options: + + * [`-Xbootclasspath/p:`](#option-Xbootclasspath-p), + [`-Xbootclasspath`](#option-Xbootclasspath), + [`-Xbootclasspath/a:`](#option-Xbootclasspath-a), + [`-endorseddirs`](#option-endorseddirs), + [`-Djava.endorsed.dirs`](#option-Djava.endorsed.dirs), + [`-extdirs`](#option-extdirs), + [`-Djava.ext.dirs`](#option-Djava.ext.dirs), + [`-profile`](#option-profile) + + If you use the `--source`/`-source` or `--target`/`-target` options, + you should also set the appropriate platform classes using the `--system` + option to give the location of an appropriate installed release of JDK. + +When using the `--release` option, only the supported documented API for that +release may be used; you cannot use any options to break encapsulation to +access any internal classes. + +## APIs + +The `javac` compiler can be invoked using an API in three different ways: + +The [Java Compiler API](../../api/java.compiler/javax/tools/JavaCompiler.html) +: This provides the most flexible way to invoke the compiler, + including the ability to compile source files provided in + memory buffers or other non-standard file systems. + +The [ToolProvider API](../../api/java.base/java/util/spi/ToolProvider.html) +: A `ToolProvider` for `javac` can be obtained by calling + `ToolProvider.findFirst("javac")`. This returns an object + with the equivalent functionality of the command-line tool. + + **Note**: This API should not be confused with the like-named + API in the [`javax.tools`](../../api/java.compiler/javax/tools/ToolProvider.html) + package. + +The `javac` [Legacy API](../../api/jdk.compiler/com/sun/tools/javac/Main.html) +: This API is retained for backward compatibility only. + All new code should use either the Java Compiler API or the ToolProvider API. + +**Note:** All other classes and methods found in a package with names that start with +`com.sun.tools.javac` (subpackages of `com.sun.tools.javac`) are strictly +internal and subject to change at any time. + +## Examples of Using -Xlint keys + +`cast` +: Warns about unnecessary and redundant casts, for example: + + > `String s = (String) "Hello!"` + +`classfile` +: Warns about issues related to class file contents. + +`deprecation` +: Warns about the use of deprecated items. For example: + + ``` + java.util.Date myDate = new java.util.Date(); + int currentDay = myDate.getDay(); + ``` + + The method `java.util.Date.getDay` has been deprecated since JDK 1.1. + +`dep-ann` +: Warns about items that are documented with the `@deprecated` Javadoc + comment, but do not have the `@Deprecated` annotation, for example: + + ``` + /** + * @deprecated As of Java SE 7, replaced by {@link #newMethod()} + */ + public static void deprecatedMethod() { } + public static void newMethod() { } + ``` + +`divzero` +: Warns about division by the constant integer 0, for example: + + > `int divideByZero = 42 / 0;` + +`empty` +: Warns about empty statements after `if`statements, for example: + + ``` + class E { + void m() { + if (true) ; + } + } + ``` + +`fallthrough` +: Checks the switch blocks for fall-through cases and provides a warning + message for any that are found. Fall-through cases are cases in a switch + block, other than the last case in the block, whose code does not include a + `break` statement, allowing code execution to fall through from that case to + the next case. For example, the code following the case 1 label in this + switch block does not end with a `break` statement: + + ``` + switch (x) { + case 1: + System.out.println("1"); + // No break statement here. + case 2: + System.out.println("2"); + } + ``` + + If the `-Xlint:fallthrough` option was used when compiling this code, then + the compiler emits a warning about possible fall-through into case, with + the line number of the case in question. + +`finally` +: Warns about `finally` clauses that cannot be completed normally, for + example: + + ``` + public static int m() { + try { + throw new NullPointerException(); + } catch (NullPointerException(); { + System.err.println("Caught NullPointerException."); + return 1; + } finally { + return 0; + } + } + ``` + + The compiler generates a warning for the `finally` block in this example. + When the `int` method is called, it returns a value of 0. A `finally` block + executes when the `try` block exits. In this example, when control is + transferred to the `catch` block, the `int` method exits. However, the + `finally` block must execute, so it's executed, even though control was + transferred outside the method. + +`options` +: Warns about issues that related to the use of command-line options. See + [Compiling for Earlier Releases of the Platform]. + +`overrides` +: Warns about issues related to method overrides. For example, consider the + following two classes: + + ``` + public class ClassWithVarargsMethod { + void varargsMethod(String... s) { } + } + + public class ClassWithOverridingMethod extends ClassWithVarargsMethod { + @Override + void varargsMethod(String[] s) { } + } + ``` + + The compiler generates a warning similar to the following:. + + ``` + warning: [override] varargsMethod(String[]) in ClassWithOverridingMethod + overrides varargsMethod(String...) in ClassWithVarargsMethod; overriding + method is missing '...' + ``` + + When the compiler encounters a `varargs` method, it translates the + `varargs` formal parameter into an array. In the method + `ClassWithVarargsMethod.varargsMethod`, the compiler translates the + `varargs` formal parameter `String... s` to the formal parameter + `String[] s`, an array that matches the formal parameter of the method + `ClassWithOverridingMethod.varargsMethod`. Consequently, this example + compiles. + +`path` +: Warns about invalid path elements and nonexistent path directories on the + command line (with regard to the class path, the source path, and other + paths). Such warnings cannot be suppressed with the `@SuppressWarnings` + annotation. For example: + + - **Linux and macOS:** + `javac -Xlint:path -classpath /nonexistentpath Example.java` + + - **Windows:** + `javac -Xlint:path -classpath C:\nonexistentpath Example.java` + +`processing` +: Warns about issues related to annotation processing. The compiler generates + this warning when you have a class that has an annotation, and you use an + annotation processor that cannot handle that type of annotation. For example, + the following is a simple annotation processor: + + **Source file AnnoProc.java**: + + ``` + import java.util.*; + import javax.annotation.processing.*; + import javax.lang.model.*; + import javax.lang.model.element.*; + + @SupportedAnnotationTypes("NotAnno") + public class AnnoProc extends AbstractProcessor { + public boolean process(Set elems, RoundEnvironment renv){ + return true; + } + + public SourceVersion getSupportedSourceVersion() { + return SourceVersion.latest(); + } + } + ``` + + **Source file AnnosWithoutProcessors.java**: + + ``` + @interface Anno { } + + @Anno + class AnnosWithoutProcessors { } + ``` + + The following commands compile the annotation processor `AnnoProc`, then + run this annotation processor against the source file + `AnnosWithoutProcessors.java`: + + ``` + javac AnnoProc.java + javac -cp . -Xlint:processing -processor AnnoProc -proc:only AnnosWithoutProcessors.java + ``` + + When the compiler runs the annotation processor against the source file + `AnnosWithoutProcessors.java`, it generates the following warning: + + ``` + warning: [processing] No processor claimed any of these annotations: Anno + ``` + + To resolve this issue, you can rename the annotation defined and used in + the class `AnnosWithoutProcessors` from `Anno` to `NotAnno`. + +`rawtypes` +: Warns about unchecked operations on raw types. The following statement + generates a `rawtypes` warning: + + > `void countElements(List l) { ... }` + + The following example does not generate a `rawtypes` warning: + + > `void countElements(List l) { ... }` + + `List` is a raw type. However, `List` is an unbounded wildcard + parameterized type. Because `List` is a parameterized interface, always + specify its type argument. In this example, the `List` formal argument is + specified with an unbounded wildcard (`?`) as its formal type parameter, + which means that the `countElements` method can accept any instantiation of + the `List` interface. + +`serial` +: Warns about missing `serialVersionUID` definitions on serializable classes. + For example: + + ``` + public class PersistentTime implements Serializable + { + private Date time; + + public PersistentTime() { + time = Calendar.getInstance().getTime(); + } + + public Date getTime() { + return time; + } + } + ``` + + The compiler generates the following warning: + + ``` + warning: [serial] serializable class PersistentTime has no definition of + serialVersionUID + ``` + + If a serializable class does not explicitly declare a field named + `serialVersionUID`, then the serialization runtime environment calculates a + default `serialVersionUID` value for that class based on various aspects of + the class, as described in the Java Object Serialization Specification. + However, it's strongly recommended that all serializable classes explicitly + declare `serialVersionUID` values because the default process of computing + `serialVersionUID` values is highly sensitive to class details that can + vary depending on compiler implementations. As a result, this might cause + an unexpected `InvalidClassExceptions` during deserialization. To guarantee + a consistent `serialVersionUID` value across different Java compiler + implementations, a serializable class must declare an explicit + `serialVersionUID` value. + +`static` +: Warns about issues relating to the use of static variables, for example: + + ``` + class XLintStatic { + static void m1() { } + void m2() { this.m1(); } + } + ``` + + The compiler generates the following warning: + + ``` + warning: [static] static method should be qualified by type name, + XLintStatic, instead of by an expression + ``` + + To resolve this issue, you can call the `static` method `m1` as follows: + + > `XLintStatic.m1();` + + Alternately, you can remove the `static` keyword from the declaration of + the method `m1`. + +`this-escape` +: Warns about constructors leaking + `this` prior to subclass initialization. + For example, this class: + + ``` + public class MyClass { + public MyClass() { + System.out.println(this.hashCode()); + } + } + ``` + + generates the following warning: + + ``` + MyClass.java:3: warning: [this-escape] possible 'this' escape + before subclass is fully initialized + System.out.println(this.hashCode()); + ^ + ``` + + A 'this' escape warning is generated when a constructor does something + that might result in a subclass method being invoked before the + constructor returns. + In such cases the subclass method would be operating on an incompletely + initialized instance. + In the above example, a subclass of `MyClass` that overrides + `hashCode()` to incorporate its own fields would likely produce + an incorrect result when invoked as shown. + + Warnings are only generated if a subclass could exist that is outside + of the current module (or package, if no module) being compiled. + So, for example, constructors in final and non-public classes do not + generate warnings. + +`try` +: Warns about issues relating to the use of `try` blocks, including + try-with-resources statements. For example, a warning is generated for the + following statement because the resource `ac` declared in the `try` block + is not used: + + ``` + try ( AutoCloseable ac = getResource() ) { // do nothing} + ``` + +`unchecked` +: Gives more detail for unchecked conversion warnings that are mandated by + the Java Language Specification, for example: + + ``` + List l = new ArrayList(); + List ls = l; // unchecked warning + ``` + + During type erasure, the types `ArrayList` and `List` + become `ArrayList` and `List`, respectively. + + The `ls` command has the parameterized type `List`. When the `List` + referenced by `l` is assigned to `ls`, the compiler generates an unchecked + warning. At compile time, the compiler and JVM cannot determine whether `l` + refers to a `List` type. In this case, `l` does not refer to a + `List` type. As a result, heap pollution occurs. + + A heap pollution situation occurs when the `List` object `l`, whose static + type is `List`, is assigned to another `List` object, `ls`, that + has a different static type, `List`. However, the compiler still + allows this assignment. It must allow this assignment to preserve backward + compatibility with releases of Java SE that do not support generics. Because + of type erasure, `List` and `List` both become `List`. + Consequently, the compiler allows the assignment of the object `l`, which + has a raw type of `List`, to the object `ls`. + +`varargs` +: Warns about unsafe use of variable arguments (`varargs`) methods, in + particular, those that contain non-reifiable arguments, for example: + + ``` + public class ArrayBuilder { + public static void addToList (List listArg, T... elements) { + for (T x : elements) { + listArg.add(x); + } + } + } + ``` + + A non-reifiable type is a type whose type information is not fully available + at runtime. + + The compiler generates the following warning for the definition of the + method `ArrayBuilder.addToList`: + + ``` + warning: [varargs] Possible heap pollution from parameterized vararg type T + ``` + + When the compiler encounters a varargs method, it translates the `varargs` + formal parameter into an array. However, the Java programming language + does not permit the creation of arrays of parameterized types. In the method + `ArrayBuilder.addToList`, the compiler translates the `varargs` formal + parameter `T...` elements to the formal parameter `T[]` elements, an array. + However, because of type erasure, the compiler converts the `varargs` + formal parameter to `Object[]` elements. Consequently, there's a + possibility of heap pollution. diff --git a/src/jdk.compiler/share/man/serialver.1 b/src/jdk.compiler/share/man/serialver.1 deleted file mode 100644 index bad14872ee6..00000000000 --- a/src/jdk.compiler/share/man/serialver.1 +++ /dev/null @@ -1,90 +0,0 @@ -.\" Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved. -.\" DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -.\" -.\" This code is free software; you can redistribute it and/or modify it -.\" under the terms of the GNU General Public License version 2 only, as -.\" published by the Free Software Foundation. -.\" -.\" This code is distributed in the hope that it will be useful, but WITHOUT -.\" ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -.\" FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -.\" version 2 for more details (a copy is included in the LICENSE file that -.\" accompanied this code). -.\" -.\" You should have received a copy of the GNU General Public License version -.\" 2 along with this work; if not, write to the Free Software Foundation, -.\" Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -.\" -.\" Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -.\" or visit www.oracle.com if you need additional information or have any -.\" questions. -.\" -.\" Automatically generated by Pandoc 2.19.2 -.\" -.\" Define V font for inline verbatim, using C font in formats -.\" that render this, and otherwise B font. -.ie "\f[CB]x\f[R]"x" \{\ -. ftr V B -. ftr VI BI -. ftr VB B -. ftr VBI BI -.\} -.el \{\ -. ftr V CR -. ftr VI CI -. ftr VB CB -. ftr VBI CBI -.\} -.TH "SERIALVER" "1" "2025" "JDK 24-ea" "JDK Commands" -.hy -.SH NAME -.PP -serialver - return the \f[V]serialVersionUID\f[R] for one or more -classes in a form suitable for copying into an evolving class -.SH SYNOPSIS -.PP -\f[V]serialver\f[R] [\f[I]options\f[R]] [\f[I]classnames\f[R]] -.TP -\f[I]options\f[R] -This represents the command-line options for the \f[V]serialver\f[R] -command. -See \f[B]Options for serialver\f[R]. -.TP -\f[I]classnames\f[R] -The classes for which \f[V]serialVersionUID\f[R] is to be returned. -.SH DESCRIPTION -.PP -The \f[V]serialver\f[R] command returns the \f[V]serialVersionUID\f[R] -for one or more classes in a form suitable for copying into an evolving -class. -When called with no arguments, the \f[V]serialver\f[R] command prints a -usage line. -.SH OPTIONS FOR SERIALVER -.TP -\f[V]-classpath\f[R] \f[I]path-files\f[R] -Sets the search path for application classes and resources. -Separate classes and resources with a colon (:). -.TP -\f[V]-J\f[R]\f[I]option\f[R] -Passes the specified \f[I]option\f[R] to the Java Virtual Machine, where -\f[I]option\f[R] is one of the options described on the reference page -for the Java application launcher. -For example, \f[V]-J-Xms48m\f[R] sets the startup memory to 48 MB. -.SH NOTES -.PP -The \f[V]serialver\f[R] command loads and initializes the specified -classes in its virtual machine, and by default, it doesn\[aq]t set a -security manager. -If the \f[V]serialver\f[R] command is to be run with untrusted classes, -then a security manager can be set with the following option: -.RS -.PP -\f[V]-J-Djava.security.manager\f[R] -.RE -.PP -When necessary, a security policy can be specified with the following -option: -.RS -.PP -\f[V]-J-Djava.security.policy=\f[R]\f[I]policy_file\f[R] -.RE diff --git a/src/jdk.compiler/share/man/serialver.md b/src/jdk.compiler/share/man/serialver.md new file mode 100644 index 00000000000..5838f1c61a9 --- /dev/null +++ b/src/jdk.compiler/share/man/serialver.md @@ -0,0 +1,74 @@ +--- +# Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# This code is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 only, as +# published by the Free Software Foundation. +# +# This code is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# version 2 for more details (a copy is included in the LICENSE file that +# accompanied this code). +# +# You should have received a copy of the GNU General Public License version +# 2 along with this work; if not, write to the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +# or visit www.oracle.com if you need additional information or have any +# questions. +# + +title: 'SERIALVER(1) JDK @@VERSION_SHORT@@ | JDK Commands' +date: @@COPYRIGHT_YEAR@@ +lang: en +--- + +## Name + +serialver - return the `serialVersionUID` for one or more classes in a form +suitable for copying into an evolving class + +## Synopsis + +`serialver` \[*options*\] \[*classnames*\] + +*options* +: This represents the command-line options for the `serialver` command. See + [Options for serialver]. + +*classnames* +: The classes for which `serialVersionUID` is to be returned. + +## Description + +The `serialver` command returns the `serialVersionUID` for one or more classes +in a form suitable for copying into an evolving class. When called with no +arguments, the `serialver` command prints a usage line. + +## Options for serialver + +`-classpath` *path-files* +: Sets the search path for application classes and resources. Separate + classes and resources with a colon (:). + +`-J`*option* +: Passes the specified *option* to the Java Virtual Machine, where *option* + is one of the options described on the reference page for the Java + application launcher. For example, `-J-Xms48m` sets the startup memory to + 48 MB. + +## Notes + +The `serialver` command loads and initializes the specified classes in its +virtual machine, and by default, it doesn't set a security manager. If the +`serialver` command is to be run with untrusted classes, then a security +manager can be set with the following option: + +> `-J-Djava.security.manager` + +When necessary, a security policy can be specified with the following option: + +> `-J-Djava.security.policy=`*policy\_file* diff --git a/src/jdk.hotspot.agent/share/man/jhsdb.1 b/src/jdk.hotspot.agent/share/man/jhsdb.1 deleted file mode 100644 index 93cc1fedb15..00000000000 --- a/src/jdk.hotspot.agent/share/man/jhsdb.1 +++ /dev/null @@ -1,218 +0,0 @@ -.\" Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved. -.\" DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -.\" -.\" This code is free software; you can redistribute it and/or modify it -.\" under the terms of the GNU General Public License version 2 only, as -.\" published by the Free Software Foundation. -.\" -.\" This code is distributed in the hope that it will be useful, but WITHOUT -.\" ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -.\" FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -.\" version 2 for more details (a copy is included in the LICENSE file that -.\" accompanied this code). -.\" -.\" You should have received a copy of the GNU General Public License version -.\" 2 along with this work; if not, write to the Free Software Foundation, -.\" Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -.\" -.\" Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -.\" or visit www.oracle.com if you need additional information or have any -.\" questions. -.\" -.\" Automatically generated by Pandoc 2.19.2 -.\" -.\" Define V font for inline verbatim, using C font in formats -.\" that render this, and otherwise B font. -.ie "\f[CB]x\f[R]"x" \{\ -. ftr V B -. ftr VI BI -. ftr VB B -. ftr VBI BI -.\} -.el \{\ -. ftr V CR -. ftr VI CI -. ftr VB CB -. ftr VBI CBI -.\} -.TH "JHSDB" "1" "2025" "JDK 24-ea" "JDK Commands" -.hy -.SH NAME -.PP -jhsdb - attach to a Java process or launch a postmortem debugger to -analyze the content of a core dump from a crashed Java Virtual Machine -(JVM) -.SH SYNOPSIS -.PP -\f[B]WARNING:\f[R] The \f[V]debugd\f[R] subcommand and -\f[V]--connect\f[R] options are deprecated. -They will be removed in a future release. -.PP -\f[V]jhsdb\f[R] \f[V]clhsdb\f[R] [\f[V]--pid\f[R] \f[I]pid\f[R] | -\f[V]--exe\f[R] \f[I]executable\f[R] \f[V]--core\f[R] -\f[I]coredump\f[R]] -.PP -\f[V]jhsdb\f[R] \f[V]hsdb\f[R] [\f[V]--pid\f[R] \f[I]pid\f[R] | -\f[V]--exe\f[R] \f[I]executable\f[R] \f[V]--core\f[R] -\f[I]coredump\f[R]] -.PP -\f[V]jhsdb\f[R] \f[V]debugd\f[R] (\f[V]--pid\f[R] \f[I]pid\f[R] | -\f[V]--exe\f[R] \f[I]executable\f[R] \f[V]--core\f[R] -\f[I]coredump\f[R]) [\f[I]options\f[R]] -.PP -\f[V]jhsdb\f[R] \f[V]jstack\f[R] (\f[V]--pid\f[R] \f[I]pid\f[R] | -\f[V]--exe\f[R] \f[I]executable\f[R] \f[V]--core\f[R] \f[I]coredump\f[R] -| \f[V]--connect\f[R] \f[I][server-id\[at]]debugd-host\f[R]) -[\f[I]options\f[R]] -.PP -\f[V]jhsdb\f[R] \f[V]jmap\f[R] (\f[V]--pid\f[R] \f[I]pid\f[R] | -\f[V]--exe\f[R] \f[I]executable\f[R] \f[V]--core\f[R] \f[I]coredump\f[R] -| \f[V]--connect\f[R] \f[I][server-id\[at]]debugd-host\f[R]) -[\f[I]options\f[R]] -.PP -\f[V]jhsdb\f[R] \f[V]jinfo\f[R] (\f[V]--pid\f[R] \f[I]pid\f[R] | -\f[V]--exe\f[R] \f[I]executable\f[R] \f[V]--core\f[R] \f[I]coredump\f[R] -| \f[V]--connect\f[R] \f[I][server-id\[at]]debugd-host\f[R]) -[\f[I]options\f[R]] -.PP -\f[V]jhsdb\f[R] \f[V]jsnap\f[R] (\f[V]--pid\f[R] \f[I]pid\f[R] | -\f[V]--exe\f[R] \f[I]executable\f[R] \f[V]--core\f[R] \f[I]coredump\f[R] -| \f[V]--connect\f[R] \f[I][server-id\[at]]debugd-host\f[R]) -[\f[I]options\f[R]] -.TP -\f[I]pid\f[R] -The process ID to which the \f[V]jhsdb\f[R] tool should attach. -The process must be a Java process. -To get a list of Java processes running on a machine, use the -\f[V]ps\f[R] command or, if the JVM processes are not running in a -separate docker instance, the \f[B]jps\f[R] command. -.TP -\f[I]executable\f[R] -The Java executable file from which the core dump was produced. -.TP -\f[I]coredump\f[R] -The core file to which the \f[V]jhsdb\f[R] tool should attach. -.TP -\f[I][server-id\[at]]debugd-host\f[R] -An optional server ID and the address of the remote debug server -(debugd). -.TP -\f[I]options\f[R] -The command-line options for a \f[V]jhsdb\f[R] mode. -See \f[B]Options for the debugd Mode\f[R], \f[B]Options for the jstack -Mode\f[R], \f[B]Options for the jmap Mode\f[R], \f[B]Options for the -jinfo Mode\f[R], and \f[B]Options for the jsnap Mode\f[R]. -.PP -\f[B]Note:\f[R] -.PP -Either the \f[I]pid\f[R] or the pair of \f[I]executable\f[R] and -\f[I]core\f[R] files or the \f[I][server-id\[at]]debugd-host\f[R] must -be provided for \f[V]debugd\f[R], \f[V]jstack\f[R], \f[V]jmap\f[R], -\f[V]jinfo\f[R] and \f[V]jsnap\f[R] modes. -.SH DESCRIPTION -.PP -You can use the \f[V]jhsdb\f[R] tool to attach to a Java process or to -launch a postmortem debugger to analyze the content of a core-dump from -a crashed Java Virtual Machine (JVM). -This command is experimental and unsupported. -.PP -\f[B]Note:\f[R] -.PP -Attaching the \f[V]jhsdb\f[R] tool to a live process will cause the -process to hang and the process will probably crash when the debugger -detaches. -.PP -The \f[V]jhsdb\f[R] tool can be launched in any one of the following -modes: -.TP -\f[V]jhsdb clhsdb\f[R] -Starts the interactive command-line debugger. -.TP -\f[V]jhsdb hsdb\f[R] -Starts the interactive GUI debugger. -.TP -\f[V]jhsdb debugd\f[R] -Starts the remote debug server. -.TP -\f[V]jhsdb jstack\f[R] -Prints stack and locks information. -.TP -\f[V]jhsdb jmap\f[R] -Prints heap information. -.TP -\f[V]jhsdb jinfo\f[R] -Prints basic JVM information. -.TP -\f[V]jhsdb jsnap\f[R] -Prints performance counter information. -.TP -\f[V]jhsdb\f[R] \f[I]command\f[R] \f[V]--help\f[R] -Displays the options available for the \f[I]command\f[R]. -.SH OPTIONS FOR THE DEBUGD MODE -.TP -\f[V]--serverid\f[R] \f[I]server-id\f[R] -An optional unique ID for this debug server. -This is required if multiple debug servers are run on the same machine. -.TP -\f[V]--rmiport\f[R] \f[I]port\f[R] -Sets the port number to which the RMI connector is bound. -If not specified a random available port is used. -.TP -\f[V]--registryport\f[R] \f[I]port\f[R] -Sets the RMI registry port. -This option overrides the system property -\[aq]sun.jvm.hotspot.rmi.port\[aq]. -If not specified, the system property is used. -If the system property is not set, the default port 1099 is used. -.TP -\f[V]--hostname\f[R] \f[I]hostname\f[R] -Sets the hostname the RMI connector is bound. -The value could be a hostname or an IPv4/IPv6 address. -This option overrides the system property -\[aq]java.rmi.server.hostname\[aq]. -If not specified, the system property is used. -If the system property is not set, a system hostname is used. -.SH OPTIONS FOR THE JINFO MODE -.TP -\f[V]--flags\f[R] -Prints the VM flags. -.TP -\f[V]--sysprops\f[R] -Prints the Java system properties. -.TP -no option -Prints the VM flags and the Java system properties. -.SH OPTIONS FOR THE JMAP MODE -.TP -no option -Prints the same information as Solaris \f[V]pmap\f[R]. -.TP -\f[V]--heap\f[R] -Prints the \f[V]java\f[R] heap summary. -.TP -\f[V]--binaryheap\f[R] -Dumps the \f[V]java\f[R] heap in \f[V]hprof\f[R] binary format. -.TP -\f[V]--dumpfile\f[R] \f[I]name\f[R] -The name of the dumpfile. -.TP -\f[V]--histo\f[R] -Prints the histogram of \f[V]java\f[R] object heap. -.TP -\f[V]--clstats\f[R] -Prints the class loader statistics. -.TP -\f[V]--finalizerinfo\f[R] -Prints the information on objects awaiting finalization. -.SH OPTIONS FOR THE JSTACK MODE -.TP -\f[V]--locks\f[R] -Prints the \f[V]java.util.concurrent\f[R] locks information. -.TP -\f[V]--mixed\f[R] -Attempts to print both \f[V]java\f[R] and native frames if the platform -allows it. -.SH OPTIONS FOR THE JSNAP MODE -.TP -\f[V]--all\f[R] -Prints all performance counters. diff --git a/src/jdk.hotspot.agent/share/man/jhsdb.md b/src/jdk.hotspot.agent/share/man/jhsdb.md new file mode 100644 index 00000000000..4c6be775ece --- /dev/null +++ b/src/jdk.hotspot.agent/share/man/jhsdb.md @@ -0,0 +1,186 @@ +--- +# Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# This code is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 only, as +# published by the Free Software Foundation. +# +# This code is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# version 2 for more details (a copy is included in the LICENSE file that +# accompanied this code). +# +# You should have received a copy of the GNU General Public License version +# 2 along with this work; if not, write to the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +# or visit www.oracle.com if you need additional information or have any +# questions. +# + +title: 'JHSDB(1) JDK @@VERSION_SHORT@@ | JDK Commands' +date: @@COPYRIGHT_YEAR@@ +lang: en +--- + +## Name + +jhsdb - attach to a Java process or launch a postmortem debugger to analyze +the content of a core dump from a crashed Java Virtual Machine (JVM) + +## Synopsis + + **WARNING:** The `debugd` subcommand and `--connect` options are deprecated. They will be removed in a future release. + +`jhsdb` `clhsdb` \[`--pid` *pid* \| `--exe` *executable* `--core` *coredump*\] + +`jhsdb` `hsdb` \[`--pid` *pid* \| `--exe` *executable* `--core` *coredump*\] + +`jhsdb` `debugd` (`--pid` *pid* \| `--exe` *executable* `--core` *coredump*) +\[*options*\] + +`jhsdb` `jstack` (`--pid` *pid* \| `--exe` *executable* `--core` *coredump* \| +`--connect` *\[server-id@\]debugd-host*) \[*options*\] + +`jhsdb` `jmap` (`--pid` *pid* \| `--exe` *executable* `--core` *coredump* \| +`--connect` *\[server-id@\]debugd-host*) \[*options*\] + +`jhsdb` `jinfo` (`--pid` *pid* \| `--exe` *executable* `--core` *coredump* \| +`--connect` *\[server-id@\]debugd-host*) \[*options*\] + +`jhsdb` `jsnap` (`--pid` *pid* \| `--exe` *executable* `--core` *coredump* \| +`--connect` *\[server-id@\]debugd-host*) \[*options*\] + +*pid* +: The process ID to which the `jhsdb` tool should attach. The process must be + a Java process. To get a list of Java processes running on a machine, use + the `ps` command or, if the JVM processes are not running in a separate + docker instance, the [jps](jps.html) command. + +*executable* +: The Java executable file from which the core dump was produced. + +*coredump* +: The core file to which the `jhsdb` tool should attach. + +*\[server-id@\]debugd-host* +: An optional server ID and the address of the remote debug server (debugd). + +*options* +: The command-line options for a `jhsdb` mode. See [Options for the debugd Mode], + [Options for the jstack Mode], [Options for the jmap Mode], + [Options for the jinfo Mode], and [Options for the jsnap Mode]. + +**Note:** + +Either the *pid* or the pair of *executable* and *core* files or +the *\[server-id@\]debugd-host* must be provided for `debugd`, `jstack`, `jmap`, +`jinfo` and `jsnap` modes. + +## Description + +You can use the `jhsdb` tool to attach to a Java process or to launch a +postmortem debugger to analyze the content of a core-dump from a crashed Java +Virtual Machine (JVM). This command is experimental and unsupported. + +**Note:** + +Attaching the `jhsdb` tool to a live process will cause the process to hang and +the process will probably crash when the debugger detaches. + +The `jhsdb` tool can be launched in any one of the following modes: + +`jhsdb clhsdb` +: Starts the interactive command-line debugger. + +`jhsdb hsdb` +: Starts the interactive GUI debugger. + +`jhsdb debugd` +: Starts the remote debug server. + +`jhsdb jstack` +: Prints stack and locks information. + +`jhsdb jmap` +: Prints heap information. + +`jhsdb jinfo` +: Prints basic JVM information. + +`jhsdb jsnap` +: Prints performance counter information. + +`jhsdb` *command* `--help` +: Displays the options available for the *command*. + +## Options for the debugd Mode + +`--serverid` *server-id* +: An optional unique ID for this debug server. This is required if multiple + debug servers are run on the same machine. + +`--rmiport` *port* +: Sets the port number to which the RMI connector is bound. If not specified + a random available port is used. + +`--registryport` *port* +: Sets the RMI registry port. This option overrides the system property + 'sun.jvm.hotspot.rmi.port'. If not specified, the system property is used. + If the system property is not set, the default port 1099 is used. + +`--hostname` *hostname* +: Sets the hostname the RMI connector is bound. The value could be a hostname + or an IPv4/IPv6 address. This option overrides the system property + 'java.rmi.server.hostname'. If not specified, the system property is used. + If the system property is not set, a system hostname is used. + +## Options for the jinfo Mode + +`--flags` +: Prints the VM flags. + +`--sysprops` +: Prints the Java system properties. + +no option +: Prints the VM flags and the Java system properties. + +## Options for the jmap Mode + +no option +: Prints the same information as Solaris `pmap`. + +`--heap` +: Prints the `java` heap summary. + +`--binaryheap` +: Dumps the `java` heap in `hprof` binary format. + +`--dumpfile` *name* +: The name of the dumpfile. + +`--histo` +: Prints the histogram of `java` object heap. + +`--clstats` +: Prints the class loader statistics. + +`--finalizerinfo` +: Prints the information on objects awaiting finalization. + +## Options for the jstack Mode + +`--locks` +: Prints the `java.util.concurrent` locks information. + +`--mixed` +: Attempts to print both `java` and native frames if the platform allows it. + +## Options for the jsnap Mode + +`--all` +: Prints all performance counters. diff --git a/src/jdk.httpserver/share/man/jwebserver.1 b/src/jdk.httpserver/share/man/jwebserver.1 deleted file mode 100644 index 4fbaf9dd09d..00000000000 --- a/src/jdk.httpserver/share/man/jwebserver.1 +++ /dev/null @@ -1,193 +0,0 @@ -.\" Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. -.\" DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -.\" -.\" This code is free software; you can redistribute it and/or modify it -.\" under the terms of the GNU General Public License version 2 only, as -.\" published by the Free Software Foundation. -.\" -.\" This code is distributed in the hope that it will be useful, but WITHOUT -.\" ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -.\" FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -.\" version 2 for more details (a copy is included in the LICENSE file that -.\" accompanied this code). -.\" -.\" You should have received a copy of the GNU General Public License version -.\" 2 along with this work; if not, write to the Free Software Foundation, -.\" Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -.\" -.\" Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -.\" or visit www.oracle.com if you need additional information or have any -.\" questions. -.\" -.\" Automatically generated by Pandoc 2.19.2 -.\" -.\" Define V font for inline verbatim, using C font in formats -.\" that render this, and otherwise B font. -.ie "\f[CB]x\f[R]"x" \{\ -. ftr V B -. ftr VI BI -. ftr VB B -. ftr VBI BI -.\} -.el \{\ -. ftr V CR -. ftr VI CI -. ftr VB CB -. ftr VBI CBI -.\} -.TH "JWEBSERVER" "1" "2025" "JDK 24-ea" "JDK Commands" -.hy -.SH NAME -.PP -jwebserver - launch the Java Simple Web Server -.SH SYNOPSIS -.PP -\f[V]jwebserver\f[R] [\f[I]options\f[R]] -.TP -\f[I]options\f[R] -Command-line options. -For a detailed description of the options, see \f[B]Options\f[R]. -.SH DESCRIPTION -.PP -The \f[V]jwebserver\f[R] tool provides a minimal HTTP server, designed -to be used for prototyping, testing, and debugging. -It serves a single directory hierarchy, and only serves static files. -Only HTTP/1.1 is supported; HTTP/2 and HTTPS are not supported. -.PP -Only idempotent HEAD and GET requests are served. -Any other requests receive a \f[V]501 - Not Implemented\f[R] or a -\f[V]405 - Not Allowed\f[R] response. -GET requests are mapped to the directory being served, as follows: -.IP \[bu] 2 -If the requested resource is a file, its content is served. -.IP \[bu] 2 -If the requested resource is a directory that contains an index file, -the content of the index file is served. -.IP \[bu] 2 -Otherwise, the names of all files and subdirectories of the directory -are listed. -Symbolic links and hidden files are not listed or served. -.PP -MIME types are configured automatically, using the built-in table. -For example, \f[V].html\f[R] files are served as \f[V]text/html\f[R] and -\f[V].java\f[R] files are served as \f[V]text/plain\f[R]. -.PP -\f[V]jwebserver\f[R] is located in the jdk.httpserver module, and can -alternatively be started with \f[V]java -m jdk.httpserver\f[R]. -It is based on the web server implementation in the -\f[V]com.sun.net.httpserver\f[R] package. -The \f[V]com.sun.net.httpserver.SimpleFileServer\f[R] class provides a -programmatic way to retrieve the server and its components for reuse and -extension. -.SH USAGE -.IP -.nf -\f[CB] -jwebserver [-b bind address] [-p port] [-d directory] - [-o none|info|verbose] [-h to show options] - [-version to show version information] -\f[R] -.fi -.SH OPTIONS -.TP -\f[V]-h\f[R] or \f[V]-?\f[R] or \f[V]--help\f[R] -Prints the help message and exits. -.TP -\f[V]-b\f[R] \f[I]addr\f[R] or \f[V]--bind-address\f[R] \f[I]addr\f[R] -Specifies the address to bind to. -Default: 127.0.0.1 or ::1 (loopback). -For all interfaces use \f[V]-b 0.0.0.0\f[R] or \f[V]-b ::\f[R]. -.TP -\f[V]-d\f[R] \f[I]dir\f[R] or \f[V]--directory\f[R] \f[I]dir\f[R] -Specifies the directory to serve. -Default: current directory. -.TP -\f[V]-o\f[R] \f[I]level\f[R] or \f[V]--output\f[R] \f[I]level\f[R] -Specifies the output format. -\f[V]none\f[R] | \f[V]info\f[R] | \f[V]verbose\f[R]. -Default: \f[V]info\f[R]. -.TP -\f[V]-p\f[R] \f[I]port\f[R] or \f[V]--port\f[R] \f[I]port\f[R] -Specifies the port to listen on. -Default: 8000. -.TP -\f[V]-version\f[R] or \f[V]--version\f[R] -Prints the version information and exits. -.PP -To stop the server, press \f[V]Ctrl + C\f[R]. -.SH STARTING THE SERVER -.PP -The following command starts the Simple Web Server: -.IP -.nf -\f[CB] -$ jwebserver -\f[R] -.fi -.PP -If startup is successful, the server prints a message to -\f[V]System.out\f[R] listing the local address and the absolute path of -the directory being served. -For example: -.IP -.nf -\f[CB] -$ jwebserver -Binding to loopback by default. For all interfaces use \[dq]-b 0.0.0.0\[dq] or \[dq]-b ::\[dq]. -Serving /cwd and subdirectories on 127.0.0.1 port 8000 -URL http://127.0.0.1:8000/ -\f[R] -.fi -.SH CONFIGURATION -.PP -By default, the server runs in the foreground and binds to the loopback -address and port 8000. -This can be changed with the \f[V]-b\f[R] and \f[V]-p\f[R] options. -For example, to bind the Simple Web Server to all interfaces, use: -.IP -.nf -\f[CB] -$ jwebserver -b 0.0.0.0 -Serving /cwd and subdirectories on 0.0.0.0 (all interfaces) port 8000 -URL http://123.456.7.891:8000/ -\f[R] -.fi -.PP -Note that this makes the web server accessible to all hosts on the -network. -\f[I]Do not do this unless you are sure the server cannot leak any -sensitive information.\f[R] -.PP -As another example, use the following command to run on port 9000: -.IP -.nf -\f[CB] -$ jwebserver -p 9000 -\f[R] -.fi -.PP -By default, the files of the current directory are served. -A different directory can be specified with the \f[V]-d\f[R] option. -.PP -By default, every request is logged on the console. -The output looks like this: -.IP -.nf -\f[CB] -127.0.0.1 - - [10/Feb/2021:14:34:11 +0000] \[dq]GET /some/subdirectory/ HTTP/1.1\[dq] 200 - -\f[R] -.fi -.PP -Logging output can be changed with the \f[V]-o\f[R] option. -The default setting is \f[V]info\f[R]. -The \f[V]verbose\f[R] setting additionally includes the request and -response headers as well as the absolute path of the requested resource. -.SH STOPPING THE SERVER -.PP -Once started successfully, the server runs until it is stopped. -On Unix platforms, the server can be stopped by sending it a -\f[V]SIGINT\f[R] signal (\f[V]Ctrl+C\f[R] in a terminal window). -.SH HELP OPTION -.PP -The \f[V]-h\f[R] option displays a help message describing the usage and -the options of the \f[V]jwebserver\f[R]. diff --git a/src/jdk.httpserver/share/man/jwebserver.md b/src/jdk.httpserver/share/man/jwebserver.md new file mode 100644 index 00000000000..352e982654d --- /dev/null +++ b/src/jdk.httpserver/share/man/jwebserver.md @@ -0,0 +1,152 @@ +--- +# Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# This code is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 only, as +# published by the Free Software Foundation. +# +# This code is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# version 2 for more details (a copy is included in the LICENSE file that +# accompanied this code). +# +# You should have received a copy of the GNU General Public License version +# 2 along with this work; if not, write to the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +# or visit www.oracle.com if you need additional information or have any +# questions. +# + +title: 'JWEBSERVER(1) JDK @@VERSION_SHORT@@ | JDK Commands' +date: @@COPYRIGHT_YEAR@@ +lang: en +--- + +## Name + +jwebserver - launch the Java Simple Web Server + +## Synopsis + +`jwebserver` \[*options*\] + +*options* +: Command-line options. For a detailed description of the options, see [Options]. + +## Description +The `jwebserver` tool provides a minimal HTTP server, designed to be used +for prototyping, testing, and debugging. It serves a single directory hierarchy, +and only serves static files. Only HTTP/1.1 is supported; +HTTP/2 and HTTPS are not supported. + +Only idempotent HEAD and GET requests are served. Any other requests receive +a `501 - Not Implemented` or a `405 - Not Allowed` response. GET requests are +mapped to the directory being served, as follows: + +* If the requested resource is a file, its content is served. +* If the requested resource is a directory that contains an index file, +the content of the index file is served. +* Otherwise, the names of all files and subdirectories of the directory are +listed. Symbolic links and hidden files are not listed or served. + +MIME types are configured automatically, using the built-in table. For example, +`.html` files are served as `text/html` and `.java` files are served as +`text/plain`. + +`jwebserver` is located in the jdk.httpserver module, and can alternatively +be started with `java -m jdk.httpserver`. It is based on the web server +implementation in the `com.sun.net.httpserver` package. +The `com.sun.net.httpserver.SimpleFileServer` class provides a programmatic +way to retrieve the server and its components for reuse and extension. + +## Usage +``` +jwebserver [-b bind address] [-p port] [-d directory] + [-o none|info|verbose] [-h to show options] + [-version to show version information] +``` + +## Options + +`-h` or `-?` or `--help` +: Prints the help message and exits. + +`-b` *addr* or `--bind-address` *addr* +: Specifies the address to bind to. + Default: 127.0.0.1 or ::1 (loopback). + For all interfaces use `-b 0.0.0.0` or `-b ::`. + +`-d` *dir* or `--directory` *dir* +: Specifies the directory to serve. + Default: current directory. + +`-o` *level* or `--output` *level* +: Specifies the output format. `none` | `info` | `verbose`. + Default: `info`. + +`-p` *port* or `--port` *port* +: Specifies the port to listen on. + Default: 8000. + +`-version` or `--version` +: Prints the version information and exits. + +To stop the server, press `Ctrl + C`. + +## Starting the Server +The following command starts the Simple Web Server: +``` +$ jwebserver +``` +If startup is successful, the server prints a message to `System.out` +listing the local address and the absolute path of the directory being +served. For example: +``` +$ jwebserver +Binding to loopback by default. For all interfaces use "-b 0.0.0.0" or "-b ::". +Serving /cwd and subdirectories on 127.0.0.1 port 8000 +URL http://127.0.0.1:8000/ +``` + +## Configuration +By default, the server runs in the foreground and binds to the loopback +address and port 8000. This can be changed with the `-b` and `-p` options. +For example, to bind the Simple Web Server to all interfaces, use: +``` +$ jwebserver -b 0.0.0.0 +Serving /cwd and subdirectories on 0.0.0.0 (all interfaces) port 8000 +URL http://123.456.7.891:8000/ +``` +Note that this makes the web server accessible to all hosts on the network. +*Do not do this unless you are sure the server cannot leak any sensitive +information.* + +As another example, use the following command to run on port 9000: +``` +$ jwebserver -p 9000 +``` + +By default, the files of the current directory are served. A different +directory can be specified with the `-d` option. + +By default, every request is logged on the console. The output looks like +this: +``` +127.0.0.1 - - [10/Feb/2021:14:34:11 +0000] "GET /some/subdirectory/ HTTP/1.1" 200 - +``` +Logging output can be changed with the `-o` option. The default setting is +`info`. The `verbose` setting additionally includes the request and response +headers as well as the absolute path of the requested resource. + +## Stopping the Server +Once started successfully, the server runs until it is stopped. On Unix +platforms, the server can be stopped by sending it a `SIGINT` signal +(`Ctrl+C` in a terminal window). + +## Help Option +The `-h` option displays a help message describing the usage and the options +of the `jwebserver`. diff --git a/src/jdk.jartool/share/man/jar.1 b/src/jdk.jartool/share/man/jar.1 deleted file mode 100644 index a88653753ee..00000000000 --- a/src/jdk.jartool/share/man/jar.1 +++ /dev/null @@ -1,379 +0,0 @@ -.\" Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. -.\" DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -.\" -.\" This code is free software; you can redistribute it and/or modify it -.\" under the terms of the GNU General Public License version 2 only, as -.\" published by the Free Software Foundation. -.\" -.\" This code is distributed in the hope that it will be useful, but WITHOUT -.\" ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -.\" FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -.\" version 2 for more details (a copy is included in the LICENSE file that -.\" accompanied this code). -.\" -.\" You should have received a copy of the GNU General Public License version -.\" 2 along with this work; if not, write to the Free Software Foundation, -.\" Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -.\" -.\" Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -.\" or visit www.oracle.com if you need additional information or have any -.\" questions. -.\" -.\" Automatically generated by Pandoc 2.19.2 -.\" -.\" Define V font for inline verbatim, using C font in formats -.\" that render this, and otherwise B font. -.ie "\f[CB]x\f[R]"x" \{\ -. ftr V B -. ftr VI BI -. ftr VB B -. ftr VBI BI -.\} -.el \{\ -. ftr V CR -. ftr VI CI -. ftr VB CB -. ftr VBI CBI -.\} -.TH "JAR" "1" "2025" "JDK 24-ea" "JDK Commands" -.hy -.SH NAME -.PP -jar - create an archive for classes and resources, and manipulate or -restore individual classes or resources from an archive -.SH SYNOPSIS -.PP -\f[V]jar\f[R] [\f[I]OPTION\f[R] ...] -[ [\f[V]--release\f[R] \f[I]VERSION\f[R]] [\f[V]-C\f[R] \f[I]dir\f[R]] -\f[I]files\f[R]] ... -.SH DESCRIPTION -.PP -The \f[V]jar\f[R] command is a general-purpose archiving and compression -tool, based on the ZIP and ZLIB compression formats. -Initially, the \f[V]jar\f[R] command was designed to package Java -applets (not supported since JDK 11) or applications; however, beginning -with JDK 9, users can use the \f[V]jar\f[R] command to create modular -JARs. -For transportation and deployment, it\[aq]s usually more convenient to -package modules as modular JARs. -.PP -The syntax for the \f[V]jar\f[R] command resembles the syntax for the -\f[V]tar\f[R] command. -It has several main operation modes, defined by one of the mandatory -operation arguments. -Other arguments are either options that modify the behavior of the -operation or are required to perform the operation. -.PP -When modules or the components of an application (files, images and -sounds) are combined into a single archive, they can be downloaded by a -Java agent (such as a browser) in a single HTTP transaction, rather than -requiring a new connection for each piece. -This dramatically improves download times. -The \f[V]jar\f[R] command also compresses files, which further improves -download time. -The \f[V]jar\f[R] command also enables individual entries in a file to -be signed so that their origin can be authenticated. -A JAR file can be used as a class path entry, whether or not it\[aq]s -compressed. -.PP -An archive becomes a modular JAR when you include a module descriptor, -\f[V]module-info.class\f[R], in the root of the given directories or in -the root of the \f[V].jar\f[R] archive. -The following operations described in \f[B]Operation Modifiers Valid -Only in Create and Update Modes\f[R] are valid only when creating or -updating a modular jar or updating an existing non-modular jar: -.IP \[bu] 2 -\f[V]--module-version\f[R] -.IP \[bu] 2 -\f[V]--hash-modules\f[R] -.IP \[bu] 2 -\f[V]--module-path\f[R] -.PP -\f[B]Note:\f[R] -.PP -All mandatory or optional arguments for long options are also mandatory -or optional for any corresponding short options. -.SH MAIN OPERATION MODES -.PP -When using the \f[V]jar\f[R] command, you must specify the operation for -it to perform. -You specify the operation mode for the \f[V]jar\f[R] command by -including the appropriate operation arguments described in this section. -You can mix an operation argument with other one-letter options. -Generally the operation argument is the first argument specified on the -command line. -.TP -\f[V]-c\f[R] or \f[V]--create\f[R] -Creates the archive. -.TP -\f[V]-i\f[R] \f[I]FILE\f[R] or \f[V]--generate-index=\f[R]\f[I]FILE\f[R] -Generates index information for the specified JAR file. -This option is deprecated and may be removed in a future release. -.TP -\f[V]-t\f[R] or \f[V]--list\f[R] -Lists the table of contents for the archive. -.TP -\f[V]-u\f[R] or \f[V]--update\f[R] -Updates an existing JAR file. -.TP -\f[V]-x\f[R] or \f[V]--extract\f[R] -Extracts the named (or all) files from the archive. -If a file with the same name appears more than once in the archive, each -copy will be extracted, with later copies overwriting (replacing) -earlier copies unless -k is specified. -.TP -\f[V]-d\f[R] or \f[V]--describe-module\f[R] -Prints the module descriptor or automatic module name. -.SH OPERATION MODIFIERS VALID IN ANY MODE -.PP -You can use the following options to customize the actions of any -operation mode included in the \f[V]jar\f[R] command. -.TP -\f[V]-C\f[R] \f[I]DIR\f[R] -When used with the create operation mode, changes the specified -directory and includes the \f[I]files\f[R] specified at the end of the -command line. -.RS -.PP -\f[V]jar\f[R] [\f[I]OPTION\f[R] ...] -[ [\f[V]--release\f[R] \f[I]VERSION\f[R]] [\f[V]-C\f[R] \f[I]dir\f[R]] -\f[I]files\f[R]] -.PP -When used with the extract operation mode, specifies the destination -directory where the JAR file will be extracted. -Unlike with the create operation mode, this option can be specified only -once with the extract operation mode. -.RE -.TP -\f[V]-f\f[R] \f[I]FILE\f[R] or \f[V]--file=\f[R]\f[I]FILE\f[R] -Specifies the archive file name. -.TP -\f[V]--release\f[R] \f[I]VERSION\f[R] -Creates a multirelease JAR file. -Places all files specified after the option into a versioned directory -of the JAR file named -\f[V]META-INF/versions/\f[R]\f[I]VERSION\f[R]\f[V]/\f[R], where -\f[I]VERSION\f[R] must be must be a positive integer whose value is 9 or -greater. -.RS -.PP -At run time, where more than one version of a class exists in the JAR, -the JDK will use the first one it finds, searching initially in the -directory tree whose \f[I]VERSION\f[R] number matches the JDK\[aq]s -major version number. -It will then look in directories with successively lower -\f[I]VERSION\f[R] numbers, and finally look in the root of the JAR. -.RE -.TP -\f[V]-v\f[R] or \f[V]--verbose\f[R] -Sends or prints verbose output to standard output. -.SH OPERATION MODIFIERS VALID ONLY IN CREATE AND UPDATE MODES -.PP -You can use the following options to customize the actions of the create -and the update main operation modes: -.TP -\f[V]-e\f[R] \f[I]CLASSNAME\f[R] or \f[V]--main-class=\f[R]\f[I]CLASSNAME\f[R] -Specifies the application entry point for standalone applications -bundled into a modular or executable modular JAR file. -.TP -\f[V]-m\f[R] \f[I]FILE\f[R] or \f[V]--manifest=\f[R]\f[I]FILE\f[R] -Includes the manifest information from the given manifest file. -.TP -\f[V]-M\f[R] or \f[V]--no-manifest\f[R] -Doesn\[aq]t create a manifest file for the entries. -.TP -\f[V]--module-version=\f[R]\f[I]VERSION\f[R] -Specifies the module version, when creating or updating a modular JAR -file, or updating a non-modular JAR file. -.TP -\f[V]--hash-modules=\f[R]\f[I]PATTERN\f[R] -Computes and records the hashes of modules matched by the given pattern -and that depend upon directly or indirectly on a modular JAR file being -created or a non-modular JAR file being updated. -.TP -\f[V]-p\f[R] or \f[V]--module-path\f[R] -Specifies the location of module dependence for generating the hash. -.TP -\f[V]\[at]\f[R]\f[I]file\f[R] -Reads \f[V]jar\f[R] options and file names from a text file as if they -were supplied on the command line -.SH OPERATION MODIFIERS VALID ONLY IN CREATE, UPDATE, AND GENERATE-INDEX MODES -.PP -You can use the following options to customize the actions of the create -(\f[V]-c\f[R] or \f[V]--create\f[R]) the update (\f[V]-u\f[R] or -\f[V]--update\f[R] ) and the generate-index (\f[V]-i\f[R] or -\f[V]--generate-index=\f[R]\f[I]FILE\f[R]) main operation modes: -.TP -\f[V]-0\f[R] or \f[V]--no-compress\f[R] -Stores without using ZIP compression. -.TP -\f[V]--date=\f[R]\f[I]TIMESTAMP\f[R] -The timestamp in ISO-8601 extended offset date-time with optional -time-zone format, to use for the timestamp of the entries, e.g. -\[dq]2022-02-12T12:30:00-05:00\[dq]. -.SH OPERATION MODIFIERS VALID ONLY IN EXTRACT MODE -.TP -\f[V]--dir\f[R] \f[I]DIR\f[R] -Directory into which the JAR file will be extracted. -.TP -\f[V]-k\f[R] or \f[V]--keep-old-files\f[R] -Do not overwrite existing files. -If a Jar file entry with the same name exists in the target directory, -the existing file will not be overwritten. -As a result, if a file appears more than once in an archive, later -copies will not overwrite earlier copies. -Also note that some file system can be case insensitive. -.SH OTHER OPTIONS -.PP -The following options are recognized by the \f[V]jar\f[R] command and -not used with operation modes: -.TP -\f[V]-h\f[R] or \f[V]--help\f[R][\f[V]:compat\f[R]] -Displays the command-line help for the \f[V]jar\f[R] command or -optionally the compatibility help. -.TP -\f[V]--help-extra\f[R] -Displays help on extra options. -.TP -\f[V]--version\f[R] -Prints the program version. -.SH EXAMPLES OF JAR COMMAND SYNTAX -.IP \[bu] 2 -Create an archive, \f[V]classes.jar\f[R], that contains two class files, -\f[V]Foo.class\f[R] and \f[V]Bar.class\f[R]. -.RS 2 -.RS -.PP -\f[V]jar --create --file classes.jar Foo.class Bar.class\f[R] -.RE -.RE -.IP \[bu] 2 -Create an archive, \f[V]classes.jar\f[R], that contains two class files, -\f[V]Foo.class\f[R] and \f[V]Bar.class\f[R] setting the last modified -date and time to \f[V]2021 Jan 6 12:36:00\f[R]. -.RS 2 -.RS -.PP -\f[V]jar --create --date=\[dq]2021-01-06T14:36:00+02:00\[dq] --file=classes.jar Foo.class Bar.class\f[R] -.RE -.RE -.IP \[bu] 2 -Create an archive, \f[V]classes.jar\f[R], by using an existing manifest, -\f[V]mymanifest\f[R], that contains all of the files in the directory -\f[V]foo/\f[R]. -.RS 2 -.RS -.PP -\f[V]jar --create --file classes.jar --manifest mymanifest -C foo/\f[R] -.RE -.RE -.IP \[bu] 2 -Create a modular JAR archive,\f[V]foo.jar\f[R], where the module -descriptor is located in \f[V]classes/module-info.class\f[R]. -.RS 2 -.RS -.PP -\f[V]jar --create --file foo.jar --main-class com.foo.Main --module-version 1.0 -C foo/classes resources\f[R] -.RE -.RE -.IP \[bu] 2 -Update an existing non-modular JAR, \f[V]foo.jar\f[R], to a modular JAR -file. -.RS 2 -.RS -.PP -\f[V]jar --update --file foo.jar --main-class com.foo.Main --module-version 1.0 -C foo/module-info.class\f[R] -.RE -.RE -.IP \[bu] 2 -Create a versioned or multi-release JAR, \f[V]foo.jar\f[R], that places -the files in the \f[V]classes\f[R] directory at the root of the JAR, and -the files in the \f[V]classes-10\f[R] directory in the -\f[V]META-INF/versions/10\f[R] directory of the JAR. -.RS 2 -.PP -In this example, the \f[V]classes/com/foo\f[R] directory contains two -classes, \f[V]com.foo.Hello\f[R] (the entry point class) and -\f[V]com.foo.NameProvider\f[R], both compiled for JDK 8. -The \f[V]classes-10/com/foo\f[R] directory contains a different version -of the \f[V]com.foo.NameProvider\f[R] class, this one containing JDK 10 -specific code and compiled for JDK 10. -.PP -Given this setup, create a multirelease JAR file \f[V]foo.jar\f[R] by -running the following command from the directory containing the -directories \f[V]classes\f[R] and \f[V]classes-10\f[R] . -.RS -.PP -\f[V]jar --create --file foo.jar --main-class com.foo.Hello -C classes . --release 10 -C classes-10 .\f[R] -.RE -.PP -The JAR file \f[V]foo.jar\f[R] now contains: -.IP -.nf -\f[CB] -% jar -tf foo.jar - -META-INF/ -META-INF/MANIFEST.MF -com/ -com/foo/ -com/foo/Hello.class -com/foo/NameProvider.class -META-INF/versions/10/com/ -META-INF/versions/10/com/foo/ -META-INF/versions/10/com/foo/NameProvider.class -\f[R] -.fi -.PP -As well as other information, the file \f[V]META-INF/MANIFEST.MF\f[R], -will contain the following lines to indicate that this is a multirelease -JAR file with an entry point of \f[V]com.foo.Hello\f[R]. -.IP -.nf -\f[CB] -\&... -Main-Class: com.foo.Hello -Multi-Release: true -\f[R] -.fi -.PP -Assuming that the \f[V]com.foo.Hello\f[R] class calls a method on the -\f[V]com.foo.NameProvider\f[R] class, running the program using JDK 10 -will ensure that the \f[V]com.foo.NameProvider\f[R] class is the one in -\f[V]META-INF/versions/10/com/foo/\f[R]. -Running the program using JDK 8 will ensure that the -\f[V]com.foo.NameProvider\f[R] class is the one at the root of the JAR, -in \f[V]com/foo\f[R]. -.RE -.IP \[bu] 2 -Create an archive, \f[V]my.jar\f[R], by reading options and lists of -class files from the file \f[V]classes.list\f[R]. -.RS 2 -.PP -\f[B]Note:\f[R] -.PP -To shorten or simplify the \f[V]jar\f[R] command, you can provide an arg -file that lists the files to include in the JAR file and pass it to the -\f[V]jar\f[R] command with the at sign (\f[V]\[at]\f[R]) as a prefix. -.RS -.PP -\f[V]jar --create --file my.jar \[at]classes.list\f[R] -.RE -.PP -If one or more entries in the arg file cannot be found then the jar -command fails without creating the JAR file. -.RE -.IP \[bu] 2 -Extract the JAR file \f[V]foo.jar\f[R] to \f[V]/tmp/bar/\f[R] directory: -.RS 2 -.RS -.PP -\f[V]jar -xf foo.jar -C /tmp/bar/\f[R] -.RE -.PP -Alternatively, you can also do: -.RS -.PP -\f[V]jar --extract --file foo.jar --dir /tmp/bar/\f[R] -.RE -.RE diff --git a/src/jdk.jartool/share/man/jar.md b/src/jdk.jartool/share/man/jar.md new file mode 100644 index 00000000000..709786fe89b --- /dev/null +++ b/src/jdk.jartool/share/man/jar.md @@ -0,0 +1,313 @@ +--- +# Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# This code is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 only, as +# published by the Free Software Foundation. +# +# This code is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# version 2 for more details (a copy is included in the LICENSE file that +# accompanied this code). +# +# You should have received a copy of the GNU General Public License version +# 2 along with this work; if not, write to the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +# or visit www.oracle.com if you need additional information or have any +# questions. +# + +title: 'JAR(1) JDK @@VERSION_SHORT@@ | JDK Commands' +date: @@COPYRIGHT_YEAR@@ +lang: en +--- + +## Name + +jar - create an archive for classes and resources, and manipulate or restore +individual classes or resources from an archive + +## Synopsis + +`jar` \[*OPTION* ...\] \[ \[`--release` *VERSION*\] \[`-C` *dir*\] *files*\] +... + +## Description + +The `jar` command is a general-purpose archiving and compression tool, based on +the ZIP and ZLIB compression formats. Initially, the `jar` command was designed +to package Java applets (not supported since JDK 11) or applications; however, +beginning with JDK 9, users can use the `jar` command to create modular JARs. +For transportation and deployment, it's usually more convenient to package +modules as modular JARs. + +The syntax for the `jar` command resembles the syntax for the `tar` command. It +has several main operation modes, defined by one of the mandatory operation +arguments. Other arguments are either options that modify the behavior of the +operation or are required to perform the operation. + +When modules or the components of an application (files, images and sounds) are +combined into a single archive, they can be downloaded by a Java agent (such as +a browser) in a single HTTP transaction, rather than requiring a new connection +for each piece. This dramatically improves download times. The `jar` command +also compresses files, which further improves download time. The `jar` command +also enables individual entries in a file to be signed so that their origin can +be authenticated. A JAR file can be used as a class path entry, whether or not +it's compressed. + +An archive becomes a modular JAR when you include a module descriptor, +`module-info.class`, in the root of the given directories or in the root of +the `.jar` archive. The following operations described in [Operation Modifiers +Valid Only in Create and Update Modes] are valid only when creating or +updating a modular jar or updating an existing non-modular jar: + +- `--module-version` + +- `--hash-modules` + +- `--module-path` + +**Note:** + +All mandatory or optional arguments for long options are also mandatory or +optional for any corresponding short options. + +## Main Operation Modes + +When using the `jar` command, you must specify the operation for it to perform. +You specify the operation mode for the `jar` command by including the +appropriate operation arguments described in this section. You can mix an +operation argument with other one-letter options. Generally the operation +argument is the first argument specified on the command line. + +`-c` or `--create` +: Creates the archive. + +`-i` *FILE* or `--generate-index=`*FILE* +: Generates index information for the specified JAR file. This option is deprecated + and may be removed in a future release. + +`-t` or `--list` +: Lists the table of contents for the archive. + +`-u` or `--update` +: Updates an existing JAR file. + +`-x` or `--extract` +: Extracts the named (or all) files from the archive. + If a file with the same name appears more than once in + the archive, each copy will be extracted, with later copies + overwriting (replacing) earlier copies unless -k is specified. + +`-d` or `--describe-module` +: Prints the module descriptor or automatic module name. + +## Operation Modifiers Valid in Any Mode + +You can use the following options to customize the actions of any operation +mode included in the `jar` command. + +`-C` *DIR* +: When used with the create operation mode, changes the specified directory + and includes the *files* specified at the end of the command line. + + `jar` \[*OPTION* ...\] \[ \[`--release` *VERSION*\] \[`-C` *dir*\] + *files*\] + + When used with the extract operation mode, specifies the destination directory + where the JAR file will be extracted. Unlike with the create operation mode, + this option can be specified only once with the extract operation mode. + +`-f` *FILE* or `--file=`*FILE* +: Specifies the archive file name. + +`--release` *VERSION* +: Creates a multirelease JAR file. Places all files specified after the + option into a versioned directory of the JAR file named + `META-INF/versions/`*VERSION*`/`, where *VERSION* must be must be a + positive integer whose value is 9 or greater. + + At run time, where more than one version of a class exists in the JAR, the + JDK will use the first one it finds, searching initially in the directory + tree whose *VERSION* number matches the JDK's major version number. It will + then look in directories with successively lower *VERSION* numbers, and + finally look in the root of the JAR. + +`-v` or `--verbose` +: Sends or prints verbose output to standard output. + +## Operation Modifiers Valid Only in Create and Update Modes + +You can use the following options to customize the actions of the create and +the update main operation modes: + +`-e` *CLASSNAME* or `--main-class=`*CLASSNAME* +: Specifies the application entry point for standalone applications bundled + into a modular or executable modular JAR file. + +`-m` *FILE* or `--manifest=`*FILE* +: Includes the manifest information from the given manifest file. + +`-M` or `--no-manifest` +: Doesn't create a manifest file for the entries. + +`--module-version=`*VERSION* +: Specifies the module version, when creating or updating a modular JAR file, + or updating a non-modular JAR file. + +`--hash-modules=`*PATTERN* +: Computes and records the hashes of modules matched by the given pattern and + that depend upon directly or indirectly on a modular JAR file being created + or a non-modular JAR file being updated. + +`-p` or `--module-path` +: Specifies the location of module dependence for generating the hash. + +`@`*file* +: Reads `jar` options and file names from a text file as if they were supplied +on the command line + +## Operation Modifiers Valid Only in Create, Update, and Generate-index Modes + +You can use the following options to customize the actions of the create (`-c` +or `--create`) the update (`-u` or `--update` ) and the generate-index (`-i` or +`--generate-index=`*FILE*) main operation modes: + +`-0` or `--no-compress` +: Stores without using ZIP compression. + +`--date=`*TIMESTAMP* +: The timestamp in ISO-8601 extended offset date-time with optional time-zone + format, to use for the timestamp of the entries, + e.g. "2022-02-12T12:30:00-05:00". + +## Operation Modifiers Valid Only in Extract Mode + +`--dir` *DIR* +: Directory into which the JAR file will be extracted. + +`-k` or `--keep-old-files` +: Do not overwrite existing files. + If a Jar file entry with the same name exists in the target directory, the + existing file will not be overwritten. + As a result, if a file appears more than once in an archive, later copies will not overwrite + earlier copies. + Also note that some file system can be case insensitive. + +## Other Options + +The following options are recognized by the `jar` command and not used with +operation modes: + +`-h` or `--help`\[`:compat`\] +: Displays the command-line help for the `jar` command or optionally the + compatibility help. + +`--help-extra` +: Displays help on extra options. + +`--version` +: Prints the program version. + +## Examples of jar Command Syntax + +- Create an archive, `classes.jar`, that contains two class files, + `Foo.class` and `Bar.class`. + + > `jar --create --file classes.jar Foo.class Bar.class` + +- Create an archive, `classes.jar`, that contains two class files, + `Foo.class` and `Bar.class` setting the last modified date and time to `2021 Jan 6 12:36:00`. + + > `jar --create --date="2021-01-06T14:36:00+02:00" --file=classes.jar Foo.class Bar.class` + +- Create an archive, `classes.jar`, by using an existing manifest, + `mymanifest`, that contains all of the files in the directory `foo/`. + + > `jar --create --file classes.jar --manifest mymanifest -C foo/` + +- Create a modular JAR archive,`foo.jar`, where the module descriptor is + located in `classes/module-info.class`. + + > `jar --create --file foo.jar --main-class com.foo.Main + --module-version 1.0 -C foo/classes resources` + +- Update an existing non-modular JAR, `foo.jar`, to a modular JAR file. + + > `jar --update --file foo.jar --main-class com.foo.Main + --module-version 1.0 -C foo/module-info.class` + +- Create a versioned or multi-release JAR, `foo.jar`, that places the files + in the `classes` directory at the root of the JAR, and the files in the + `classes-10` directory in the `META-INF/versions/10` directory of the JAR. + + In this example, the `classes/com/foo` directory contains two classes, + `com.foo.Hello` (the entry point class) and `com.foo.NameProvider`, both + compiled for JDK 8. The `classes-10/com/foo` directory contains a different + version of the `com.foo.NameProvider` class, this one containing JDK 10 + specific code and compiled for JDK 10. + + Given this setup, create a multirelease JAR file `foo.jar` by running the + following command from the directory containing the directories `classes` + and `classes-10` . + + > `jar --create --file foo.jar --main-class com.foo.Hello -C classes . + --release 10 -C classes-10 .` + + The JAR file `foo.jar` now contains: + + ``` + % jar -tf foo.jar + + META-INF/ + META-INF/MANIFEST.MF + com/ + com/foo/ + com/foo/Hello.class + com/foo/NameProvider.class + META-INF/versions/10/com/ + META-INF/versions/10/com/foo/ + META-INF/versions/10/com/foo/NameProvider.class + ``` + + As well as other information, the file `META-INF/MANIFEST.MF`, will contain + the following lines to indicate that this is a multirelease JAR file with + an entry point of `com.foo.Hello`. + + ``` + ... + Main-Class: com.foo.Hello + Multi-Release: true + ``` + + Assuming that the `com.foo.Hello` class calls a method on the + `com.foo.NameProvider` class, running the program using JDK 10 will ensure + that the `com.foo.NameProvider` class is the one in + `META-INF/versions/10/com/foo/`. Running the program using JDK 8 will + ensure that the `com.foo.NameProvider` class is the one at the root of the + JAR, in `com/foo`. + +- Create an archive, `my.jar`, by reading options and lists of class files + from the file `classes.list`. + + **Note:** + + To shorten or simplify the `jar` command, you can provide an arg file that lists + the files to include in the JAR file and pass it to the `jar` command with the at sign (`@`) + as a prefix. + + > `jar --create --file my.jar @classes.list` + + If one or more entries in the arg file cannot be found then the jar command fails without creating the JAR file. + +- Extract the JAR file `foo.jar` to `/tmp/bar/` directory: + + > `jar -xf foo.jar -C /tmp/bar/` + + Alternatively, you can also do: + + > `jar --extract --file foo.jar --dir /tmp/bar/` diff --git a/src/jdk.jartool/share/man/jarsigner.1 b/src/jdk.jartool/share/man/jarsigner.1 deleted file mode 100644 index d085efcfcd0..00000000000 --- a/src/jdk.jartool/share/man/jarsigner.1 +++ /dev/null @@ -1,1395 +0,0 @@ -.\" Copyright (c) 1998, 2023, Oracle and/or its affiliates. All rights reserved. -.\" DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -.\" -.\" This code is free software; you can redistribute it and/or modify it -.\" under the terms of the GNU General Public License version 2 only, as -.\" published by the Free Software Foundation. -.\" -.\" This code is distributed in the hope that it will be useful, but WITHOUT -.\" ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -.\" FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -.\" version 2 for more details (a copy is included in the LICENSE file that -.\" accompanied this code). -.\" -.\" You should have received a copy of the GNU General Public License version -.\" 2 along with this work; if not, write to the Free Software Foundation, -.\" Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -.\" -.\" Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -.\" or visit www.oracle.com if you need additional information or have any -.\" questions. -.\" -'\" t -.\" Automatically generated by Pandoc 2.19.2 -.\" -.\" Define V font for inline verbatim, using C font in formats -.\" that render this, and otherwise B font. -.ie "\f[CB]x\f[R]"x" \{\ -. ftr V B -. ftr VI BI -. ftr VB B -. ftr VBI BI -.\} -.el \{\ -. ftr V CR -. ftr VI CI -. ftr VB CB -. ftr VBI CBI -.\} -.TH "JARSIGNER" "1" "2025" "JDK 24-ea" "JDK Commands" -.hy -.SH NAME -.PP -jarsigner - sign and verify Java Archive (JAR) files -.SH SYNOPSIS -.PP -\f[V]jarsigner\f[R] [\f[I]options\f[R]] \f[I]jar-file\f[R] -\f[I]alias\f[R] -.PP -\f[V]jarsigner\f[R] \f[V]-verify\f[R] [\f[I]options\f[R]] -\f[I]jar-file\f[R] [\f[I]alias\f[R] ...] -.PP -\f[V]jarsigner\f[R] \f[V]-version\f[R] -.TP -\f[I]options\f[R] -The command-line options. -See \f[B]Options for jarsigner\f[R]. -.TP -\f[V]-verify\f[R] -The \f[V]-verify\f[R] option can take zero or more keystore alias names -after the JAR file name. -When the \f[V]-verify\f[R] option is specified, the \f[V]jarsigner\f[R] -command checks that the certificate used to verify each signed entry in -the JAR file matches one of the keystore aliases. -The aliases are defined in the keystore specified by \f[V]-keystore\f[R] -or the default keystore. -.RS -.PP -If you also specify the \f[V]-strict\f[R] option, and the -\f[V]jarsigner\f[R] command detects severe warnings, the message, -\[dq]jar verified, with signer errors\[dq] is displayed. -.RE -.TP -\f[I]jar-file\f[R] -The JAR file to be signed. -.RS -.PP -If you also specified the \f[V]-strict\f[R] option, and the -\f[V]jarsigner\f[R] command detected severe warnings, the message, -\[dq]jar signed, with signer errors\[dq] is displayed. -.RE -.TP -\f[I]alias\f[R] -The aliases are defined in the keystore specified by \f[V]-keystore\f[R] -or the default keystore. -.TP -\f[V]-version\f[R] -The \f[V]-version\f[R] option prints the program version of -\f[V]jarsigner\f[R]. -.SH DESCRIPTION -.PP -The \f[V]jarsigner\f[R] tool has two purposes: -.IP \[bu] 2 -To sign Java Archive (JAR) files. -.IP \[bu] 2 -To verify the signatures and integrity of signed JAR files. -.PP -The JAR feature enables the packaging of class files, images, sounds, -and other digital data in a single file for faster and easier -distribution. -A tool named \f[V]jar\f[R] enables developers to produce JAR files. -(Technically, any ZIP file can also be considered a JAR file, although -when created by the \f[V]jar\f[R] command or processed by the -\f[V]jarsigner\f[R] command, JAR files also contain a -\f[V]META-INF/MANIFEST.MF\f[R] file.) -.PP -A digital signature is a string of bits that is computed from some data -(the data being signed) and the private key of an entity (a person, -company, and so on). -Similar to a handwritten signature, a digital signature has many useful -characteristics: -.IP \[bu] 2 -Its authenticity can be verified by a computation that uses the public -key corresponding to the private key used to generate the signature. -.IP \[bu] 2 -It can\[aq]t be forged, assuming the private key is kept secret. -.IP \[bu] 2 -It is a function of the data signed and thus can\[aq]t be claimed to be -the signature for other data as well. -.IP \[bu] 2 -The signed data can\[aq]t be changed. -If the data is changed, then the signature can\[aq]t be verified as -authentic. -.PP -To generate an entity\[aq]s signature for a file, the entity must first -have a public/private key pair associated with it and one or more -certificates that authenticate its public key. -A certificate is a digitally signed statement from one entity that says -that the public key of another entity has a particular value. -.PP -The \f[V]jarsigner\f[R] command uses key and certificate information -from a keystore to generate digital signatures for JAR files. -A keystore is a database of private keys and their associated X.509 -certificate chains that authenticate the corresponding public keys. -The \f[V]keytool\f[R] command is used to create and administer -keystores. -.PP -The \f[V]jarsigner\f[R] command uses an entity\[aq]s private key to -generate a signature. -The signed JAR file contains, among other things, a copy of the -certificate from the keystore for the public key corresponding to the -private key used to sign the file. -The \f[V]jarsigner\f[R] command can verify the digital signature of the -signed JAR file using the certificate inside it (in its signature block -file). -.PP -The \f[V]jarsigner\f[R] command can generate signatures that include a -time stamp that enables a systems or deployer to check whether the JAR -file was signed while the signing certificate was still valid. -.PP -In addition, APIs allow applications to obtain the timestamp -information. -.PP -At this time, the \f[V]jarsigner\f[R] command can only sign JAR files -created by the \f[V]jar\f[R] command or zip files. -JAR files are the same as zip files, except they also have a -\f[V]META-INF/MANIFEST.MF\f[R] file. -A \f[V]META-INF/MANIFEST.MF\f[R] file is created when the -\f[V]jarsigner\f[R] command signs a zip file. -.PP -The default \f[V]jarsigner\f[R] command behavior is to sign a JAR or zip -file. -Use the \f[V]-verify\f[R] option to verify a signed JAR file. -.PP -The \f[V]jarsigner\f[R] command also attempts to validate the -signer\[aq]s certificate after signing or verifying. -During validation, it checks the revocation status of each certificate -in the signer\[aq]s certificate chain when the \f[V]-revCheck\f[R] -option is specified. -If there is a validation error or any other problem, the command -generates warning messages. -If you specify the \f[V]-strict\f[R] option, then the command treats -severe warnings as errors. -See \f[B]Errors and Warnings\f[R]. -.SH KEYSTORE ALIASES -.PP -All keystore entities are accessed with unique aliases. -.PP -When you use the \f[V]jarsigner\f[R] command to sign a JAR file, you -must specify the alias for the keystore entry that contains the private -key needed to generate the signature. -If no output file is specified, it overwrites the original JAR file with -the signed JAR file. -.PP -Keystores are protected with a password, so the store password must be -specified. -You are prompted for it when you don\[aq]t specify it on the command -line. -Similarly, private keys are protected in a keystore with a password, so -the private key\[aq]s password must be specified, and you are prompted -for the password when you don\[aq]t specify it on the command line and -it isn\[aq]t the same as the store password. -.SH KEYSTORE LOCATION -.PP -The \f[V]jarsigner\f[R] command has a \f[V]-keystore\f[R] option for -specifying the URL of the keystore to be used. -The keystore is by default stored in a file named \f[V].keystore\f[R] in -the user\[aq]s home directory, as determined by the \f[V]user.home\f[R] -system property. -.PP -\f[B]Linux and macOS:\f[R] \f[V]user.home\f[R] defaults to the -user\[aq]s home directory. -.PP -The input stream from the \f[V]-keystore\f[R] option is passed to the -\f[V]KeyStore.load\f[R] method. -If \f[V]NONE\f[R] is specified as the URL, then a null stream is passed -to the \f[V]KeyStore.load\f[R] method. -\f[V]NONE\f[R] should be specified when the \f[V]KeyStore\f[R] class -isn\[aq]t file based, for example, when it resides on a hardware token -device. -.SH KEYSTORE IMPLEMENTATION -.PP -The \f[V]KeyStore\f[R] class provided in the \f[V]java.security\f[R] -package supplies a number of well-defined interfaces to access and -modify the information in a keystore. -You can have multiple different concrete implementations, where each -implementation is for a particular type of keystore. -.PP -Currently, there are two command-line tools that use keystore -implementations (\f[V]keytool\f[R] and \f[V]jarsigner\f[R]). -.PP -The default keystore implementation is \f[V]PKCS12\f[R]. -This is a cross platform keystore based on the RSA PKCS12 Personal -Information Exchange Syntax Standard. -This standard is primarily meant for storing or transporting a -user\[aq]s private keys, certificates, and miscellaneous secrets. -There is another built-in implementation, provided by Oracle. -It implements the keystore as a file with a proprietary keystore type -(format) named \f[V]JKS\f[R]. -It protects each private key with its individual password, and also -protects the integrity of the entire keystore with a (possibly -different) password. -.PP -Keystore implementations are provider-based, which means the application -interfaces supplied by the \f[V]KeyStore\f[R] class are implemented in -terms of a Service Provider Interface (SPI). -There is a corresponding abstract \f[V]KeystoreSpi\f[R] class, also in -the \f[V]java.security package\f[R], that defines the Service Provider -Interface methods that providers must implement. -The term provider refers to a package or a set of packages that supply a -concrete implementation of a subset of services that can be accessed by -the Java Security API. -To provide a keystore implementation, clients must implement a provider -and supply a \f[V]KeystoreSpi\f[R] subclass implementation, as described -in \f[B]How to Implement a Provider in the Java Cryptography -Architecture\f[R] -[https://www.oracle.com/pls/topic/lookup?ctx=en/java/javase&id=security_guide_implement_provider_jca]. -.PP -Applications can choose different types of keystore implementations from -different providers, with the \f[V]getInstance\f[R] factory method in -the \f[V]KeyStore\f[R] class. -A keystore type defines the storage and data format of the keystore -information and the algorithms used to protect private keys in the -keystore and the integrity of the keystore itself. -Keystore implementations of different types aren\[aq]t compatible. -.PP -The \f[V]jarsigner\f[R] commands can read file-based keystores from any -location that can be specified using a URL. -In addition, these commands can read non-file-based keystores such as -those provided by MSCAPI on Windows and PKCS11 on all platforms. -.PP -For the \f[V]jarsigner\f[R] and \f[V]keytool\f[R] commands, you can -specify a keystore type at the command line with the -\f[V]-storetype\f[R] option. -.PP -If you don\[aq]t explicitly specify a keystore type, then the tools -choose a keystore implementation based on the value of the -\f[V]keystore.type\f[R] property specified in the security properties -file. -The security properties file is called \f[V]java.security\f[R], and it -resides in the JDK security properties directory, -\f[V]java.home/conf/security\f[R]. -.PP -Each tool gets the \f[V]keystore.type\f[R] value and then examines all -the installed providers until it finds one that implements keystores of -that type. -It then uses the keystore implementation from that provider. -.PP -The \f[V]KeyStore\f[R] class defines a static method named -\f[V]getDefaultType\f[R] that lets applications retrieve the value of -the \f[V]keystore.type\f[R] property. -The following line of code creates an instance of the default keystore -type as specified in the \f[V]keystore.type\f[R] property: -.RS -.PP -\f[V]KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());\f[R] -.RE -.PP -The default keystore type is \f[V]pkcs12\f[R], which is a cross platform -keystore based on the RSA PKCS12 Personal Information Exchange Syntax -Standard. -This is specified by the following line in the security properties file: -.RS -.PP -\f[V]keystore.type=pkcs12\f[R] -.RE -.PP -Case doesn\[aq]t matter in keystore type designations. -For example, \f[V]JKS\f[R] is the same as \f[V]jks\f[R]. -.PP -To have the tools utilize a keystore implementation other than the -default, you can change that line to specify a different keystore type. -For example, if you want to use the Oracle\[aq]s \f[V]jks\f[R] keystore -implementation, then change the line to the following: -.RS -.PP -\f[V]keystore.type=jks\f[R] -.RE -.SH SUPPORTED ALGORITHMS -.PP -By default, the \f[V]jarsigner\f[R] command signs a JAR file using one -of the following algorithms and block file extensions depending on the -type and size of the private key: -.PP -Default Signature Algorithms and Block File Extensions -.TS -tab(@); -l l l l. -T{ -keyalg -T}@T{ -key size -T}@T{ -default sigalg -T}@T{ -block file extension -T} -_ -T{ -DSA -T}@T{ -any size -T}@T{ -SHA256withDSA -T}@T{ -\&.DSA -T} -T{ -RSA -T}@T{ -< 624 -T}@T{ -SHA256withRSA -T}@T{ -\&.RSA -T} -T{ -T}@T{ -<= 7680 -T}@T{ -SHA384withRSA -T}@T{ -T} -T{ -T}@T{ -> 7680 -T}@T{ -SHA512withRSA -T}@T{ -T} -T{ -EC -T}@T{ -< 512 -T}@T{ -SHA384withECDSA -T}@T{ -\&.EC -T} -T{ -T}@T{ ->= 512 -T}@T{ -SHA512withECDSA -T}@T{ -T} -T{ -RSASSA-PSS -T}@T{ -< 624 -T}@T{ -RSASSA-PSS (with SHA-256) -T}@T{ -\&.RSA -T} -T{ -T}@T{ -<= 7680 -T}@T{ -RSASSA-PSS (with SHA-384) -T}@T{ -T} -T{ -T}@T{ -> 7680 -T}@T{ -RSASSA-PSS (with SHA-512) -T}@T{ -T} -T{ -EdDSA -T}@T{ -255 -T}@T{ -Ed25519 -T}@T{ -\&.EC -T} -T{ -T}@T{ -448 -T}@T{ -Ed448 -T}@T{ -T} -.TE -.IP \[bu] 2 -If an RSASSA-PSS key is encoded with parameters, then jarsigner will use -the same parameters in the signature. -Otherwise, jarsigner will use parameters that are determined by the size -of the key as specified in the table above. -For example, an 3072-bit RSASSA-PSS key will use RSASSA-PSS as the -signature algorithm and SHA-384 as the hash and MGF1 algorithms. -.IP \[bu] 2 -If a key algorithm is not listed in this table, the \f[V].DSA\f[R] -extension is used when signing a JAR file. -.PP -These default signature algorithms can be overridden by using the -\f[V]-sigalg\f[R] option. -.PP -The \f[V]jarsigner\f[R] command uses the -\f[V]jdk.jar.disabledAlgorithms\f[R] and -\f[V]jdk.security.legacyAlgorithms\f[R] security properties to determine -which algorithms are considered a security risk. -If the JAR file was signed with any algorithms that are disabled, it -will be treated as an unsigned JAR file. -If the JAR file was signed with any legacy algorithms, it will be -treated as signed with an informational warning to inform users that the -legacy algorithm will be disabled in a future update. -For detailed verification output, include -\f[V]-J-Djava.security.debug=jar\f[R]. -The \f[V]jdk.jar.disabledAlgorithms\f[R] and -\f[V]jdk.security.legacyAlgorithms\f[R] security properties are defined -in the \f[V]java.security\f[R] file (located in the JDK\[aq]s -\f[V]$JAVA_HOME/conf/security\f[R] directory). -.PP -\f[B]Note:\f[R] -.PP -In order to improve out of the box security, default key size and -signature algorithm names are periodically updated to stronger values -with each release of the JDK. -If interoperability with older releases of the JDK is important, please -make sure the defaults are supported by those releases, or alternatively -use the \f[V]-sigalg\f[R] option to override the default values at your -own risk. -.SH THE SIGNED JAR FILE -.PP -When the \f[V]jarsigner\f[R] command is used to sign a JAR file, the -output signed JAR file is exactly the same as the input JAR file, except -that it has two additional files placed in the META-INF directory: -.IP \[bu] 2 -A signature file with an \f[V].SF\f[R] extension -.IP \[bu] 2 -A signature block file with a \f[V].DSA\f[R], \f[V].RSA\f[R], or -\f[V].EC\f[R] extension -.PP -The base file names for these two files come from the value of the -\f[V]-sigfile\f[R] option. -For example, when the option is \f[V]-sigfile MKSIGN\f[R], the files are -named \f[V]MKSIGN.SF\f[R] and \f[V]MKSIGN.RSA\f[R]. -In this document, we assume the signer always uses an RSA key. -.PP -If no \f[V]-sigfile\f[R] option appears on the command line, then the -base file name for the \f[V].SF\f[R] and the signature block files is -the first 8 characters of the alias name specified on the command line, -all converted to uppercase. -If the alias name has fewer than 8 characters, then the full alias name -is used. -If the alias name contains any characters that aren\[aq]t allowed in a -signature file name, then each such character is converted to an -underscore (_) character in forming the file name. -Valid characters include letters, digits, underscores, and hyphens. -.SH SIGNATURE FILE -.PP -A signature file (\f[V].SF\f[R] file) looks similar to the manifest file -that is always included in a JAR file when the \f[V]jarsigner\f[R] -command is used to sign the file. -For each source file included in the JAR file, the \f[V].SF\f[R] file -has two lines, such as in the manifest file, that list the following: -.IP \[bu] 2 -File name -.IP \[bu] 2 -Name of the digest algorithm (SHA) -.IP \[bu] 2 -SHA digest value -.PP -\f[B]Note:\f[R] -.PP -The name of the digest algorithm (SHA) and the SHA digest value are on -the same line. -.PP -In the manifest file, the SHA digest value for each source file is the -digest (hash) of the binary data in the source file. -In the \f[V].SF\f[R] file, the digest value for a specified source file -is the hash of the two lines in the manifest file for the source file. -.PP -The signature file, by default, includes a header with a hash of the -whole manifest file. -The header also contains a hash of the manifest header. -The presence of the header enables verification optimization. -See \f[B]JAR File Verification\f[R]. -.SH SIGNATURE BLOCK FILE -.PP -The \f[V].SF\f[R] file is signed and the signature is placed in the -signature block file. -This file also contains, encoded inside it, the certificate or -certificate chain from the keystore that authenticates the public key -corresponding to the private key used for signing. -The file has the extension \f[V].DSA\f[R], \f[V].RSA\f[R], or -\f[V].EC\f[R], depending on the key algorithm used. -See the table in \f[B]Supported Algorithms\f[R]. -.SH SIGNATURE TIME STAMP -.PP -The \f[V]jarsigner\f[R] command used with the following options -generates and stores a signature time stamp when signing a JAR file: -.IP \[bu] 2 -\f[V]-tsa\f[R] \f[I]url\f[R] -.IP \[bu] 2 -\f[V]-tsacert\f[R] \f[I]alias\f[R] -.IP \[bu] 2 -\f[V]-tsapolicyid\f[R] \f[I]policyid\f[R] -.IP \[bu] 2 -\f[V]-tsadigestalg\f[R] \f[I]algorithm\f[R] -.PP -See \f[B]Options for jarsigner\f[R]. -.SH JAR FILE VERIFICATION -.PP -A successful JAR file verification occurs when the signatures are valid, -and none of the files that were in the JAR file when the signatures were -generated have changed since then. -JAR file verification involves the following steps: -.IP "1." 3 -Verify the signature of the \f[V].SF\f[R] file. -.RS 4 -.PP -The verification ensures that the signature stored in each signature -block file was generated using the private key corresponding to the -public key whose certificate (or certificate chain) also appears in the -signature block file. -It also ensures that the signature is a valid signature of the -corresponding signature (\f[V].SF\f[R]) file, and thus the \f[V].SF\f[R] -file wasn\[aq]t tampered with. -.RE -.IP "2." 3 -Verify the digest listed in each entry in the \f[V].SF\f[R] file with -each corresponding section in the manifest. -.RS 4 -.PP -The \f[V].SF\f[R] file by default includes a header that contains a hash -of the entire manifest file. -When the header is present, the verification can check to see whether or -not the hash in the header matches the hash of the manifest file. -If there is a match, then verification proceeds to the next step. -.PP -If there is no match, then a less optimized verification is required to -ensure that the hash in each source file information section in the -\f[V].SF\f[R] file equals the hash of its corresponding section in the -manifest file. -See Signature File. -.PP -One reason the hash of the manifest file that is stored in the -\f[V].SF\f[R] file header might not equal the hash of the current -manifest file is that it might contain sections for newly added files -after the file was signed. -For example, suppose one or more files were added to the signed JAR file -(using the \f[V]jar\f[R] tool) that already contains a signature and a -\f[V].SF\f[R] file. -If the JAR file is signed again by a different signer, then the manifest -file is changed (sections are added to it for the new files by the -\f[V]jarsigner\f[R] tool) and a new \f[V].SF\f[R] file is created, but -the original \f[V].SF\f[R] file is unchanged. -A verification is still considered successful if none of the files that -were in the JAR file when the original signature was generated have been -changed since then. -This is because the hashes in the non-header sections of the -\f[V].SF\f[R] file equal the hashes of the corresponding sections in the -manifest file. -.RE -.IP "3." 3 -Read each file in the JAR file that has an entry in the \f[V].SF\f[R] -file. -While reading, compute the file\[aq]s digest and compare the result with -the digest for this file in the manifest section. -The digests should be the same or verification fails. -.RS 4 -.PP -If any serious verification failures occur during the verification -process, then the process is stopped and a security exception is thrown. -The \f[V]jarsigner\f[R] command catches and displays the exception. -.RE -.IP "4." 3 -Check for disabled algorithm usage. -See \f[B]Supported Algorithms\f[R]. -.PP -\f[B]Note:\f[R] -.PP -You should read any addition warnings (or errors if you specified the -\f[V]-strict\f[R] option), as well as the content of the certificate (by -specifying the \f[V]-verbose\f[R] and \f[V]-certs\f[R] options) to -determine if the signature can be trusted. -.SH MULTIPLE SIGNATURES FOR A JAR FILE -.PP -A JAR file can be signed by multiple people by running the -\f[V]jarsigner\f[R] command on the file multiple times and specifying -the alias for a different person each time, as follows: -.IP -.nf -\f[CB] -jarsigner myBundle.jar susan -jarsigner myBundle.jar kevin -\f[R] -.fi -.PP -When a JAR file is signed multiple times, there are multiple -\f[V].SF\f[R] and signature block files in the resulting JAR file, one -pair for each signature. -In the previous example, the output JAR file includes files with the -following names: -.IP -.nf -\f[CB] -SUSAN.SF -SUSAN.RSA -KEVIN.SF -KEVIN.RSA -\f[R] -.fi -.SH OPTIONS FOR JARSIGNER -.PP -The following sections describe the options for the \f[V]jarsigner\f[R]. -Be aware of the following standards: -.IP \[bu] 2 -All option names are preceded by a hyphen sign (-). -.IP \[bu] 2 -The options can be provided in any order. -.IP \[bu] 2 -Items that are in italics or underlined (option values) represent the -actual values that must be supplied. -.IP \[bu] 2 -The \f[V]-storepass\f[R], \f[V]-keypass\f[R], \f[V]-sigfile\f[R], -\f[V]-sigalg\f[R], \f[V]-digestalg\f[R], \f[V]-signedjar\f[R], and -TSA-related options are only relevant when signing a JAR file; they -aren\[aq]t relevant when verifying a signed JAR file. -The \f[V]-keystore\f[R] option is relevant for signing and verifying a -JAR file. -In addition, aliases are specified when signing and verifying a JAR -file. -.TP -\f[V]-keystore\f[R] \f[I]url\f[R] -Specifies the URL that tells the keystore location. -This defaults to the file \f[V].keystore\f[R] in the user\[aq]s home -directory, as determined by the \f[V]user.home\f[R] system property. -.RS -.PP -A keystore is required when signing. -You must explicitly specify a keystore when the default keystore -doesn\[aq]t exist or if you want to use one other than the default. -.PP -A keystore isn\[aq]t required when verifying, but if one is specified or -the default exists and the \f[V]-verbose\f[R] option was also specified, -then additional information is output regarding whether or not any of -the certificates used to verify the JAR file are contained in that -keystore. -.PP -The \f[V]-keystore\f[R] argument can be a file name and path -specification rather than a URL, in which case it is treated the same as -a file: URL, for example, the following are equivalent: -.IP \[bu] 2 -\f[V]-keystore\f[R] \f[I]filePathAndName\f[R] -.IP \[bu] 2 -\f[V]-keystore file:\f[R]\f[I]filePathAndName\f[R] -.PP -If the Sun PKCS #11 provider was configured in the -\f[V]java.security\f[R] security properties file (located in the -JDK\[aq]s \f[V]$JAVA_HOME/conf/security\f[R] directory), then the -\f[V]keytool\f[R] and \f[V]jarsigner\f[R] tools can operate on the PKCS -#11 token by specifying these options: -.RS -.PP -\f[V]-keystore NONE -storetype PKCS11\f[R] -.RE -.PP -For example, the following command lists the contents of the configured -PKCS#11 token: -.RS -.PP -\f[V]keytool -keystore NONE -storetype PKCS11 -list\f[R] -.RE -.RE -.TP -\f[V]-storepass\f[R] [\f[V]:env\f[R] | \f[V]:file\f[R]] \f[I]argument\f[R] -Specifies the password that is required to access the keystore. -This is only needed when signing (not verifying) a JAR file. -In that case, if a \f[V]-storepass\f[R] option isn\[aq]t provided at the -command line, then the user is prompted for the password. -.RS -.PP -If the modifier \f[V]env\f[R] or \f[V]file\f[R] isn\[aq]t specified, -then the password has the value \f[V]argument\f[R]. -Otherwise, the password is retrieved as follows: -.IP \[bu] 2 -\f[V]env\f[R]: Retrieve the password from the environment variable named -\f[I]argument\f[R]. -.IP \[bu] 2 -\f[V]file\f[R]: Retrieve the password from the file named -\f[I]argument\f[R]. -.PP -\f[B]Note:\f[R] -.PP -The password shouldn\[aq]t be specified on the command line or in a -script unless it is for testing purposes, or you are on a secure system. -.RE -.TP -\f[V]-storetype\f[R] \f[I]storetype\f[R] -Specifies the type of keystore to be instantiated. -The default keystore type is the one that is specified as the value of -the \f[V]keystore.type\f[R] property in the security properties file, -which is returned by the static \f[V]getDefaultType\f[R] method in -\f[V]java.security.KeyStore\f[R]. -.RS -.PP -The PIN for a PKCS #11 token can also be specified with the -\f[V]-storepass\f[R] option. -If none is specified, then the \f[V]keytool\f[R] and \f[V]jarsigner\f[R] -commands prompt for the token PIN. -If the token has a protected authentication path (such as a dedicated -PIN-pad or a biometric reader), then the \f[V]-protected\f[R] option -must be specified and no password options can be specified. -.RE -.TP -\f[V]-keypass\f[R] [\f[V]:env\f[R] | \f[V]:file\f[R]] \f[I]argument\f[R] \f[V]-certchain\f[R] \f[I]file\f[R] -Specifies the password used to protect the private key of the keystore -entry addressed by the alias specified on the command line. -The password is required when using \f[V]jarsigner\f[R] to sign a JAR -file. -If no password is provided on the command line, and the required -password is different from the store password, then the user is prompted -for it. -.RS -.PP -If the modifier \f[V]env\f[R] or \f[V]file\f[R] isn\[aq]t specified, -then the password has the value \f[V]argument\f[R]. -Otherwise, the password is retrieved as follows: -.IP \[bu] 2 -\f[V]env\f[R]: Retrieve the password from the environment variable named -\f[I]argument\f[R]. -.IP \[bu] 2 -\f[V]file\f[R]: Retrieve the password from the file named -\f[I]argument\f[R]. -.PP -\f[B]Note:\f[R] -.PP -The password shouldn\[aq]t be specified on the command line or in a -script unless it is for testing purposes, or you are on a secure system. -.RE -.TP -\f[V]-certchain\f[R] \f[I]file\f[R] -Specifies the certificate chain to be used when the certificate chain -associated with the private key of the keystore entry that is addressed -by the alias specified on the command line isn\[aq]t complete. -This can happen when the keystore is located on a hardware token where -there isn\[aq]t enough capacity to hold a complete certificate chain. -The file can be a sequence of concatenated X.509 certificates, or a -single PKCS#7 formatted data block, either in binary encoding format or -in printable encoding format (also known as Base64 encoding) as defined -by \f[B]Internet RFC 1421 Certificate Encoding Standard\f[R] -[http://tools.ietf.org/html/rfc1421]. -.TP -\f[V]-sigfile\f[R] \f[I]file\f[R] -Specifies the base file name to be used for the generated \f[V].SF\f[R] -and signature block files. -For example, if file is \f[V]DUKESIGN\f[R], then the generated -\f[V].SF\f[R] and signature block files are named \f[V]DUKESIGN.SF\f[R] -and \f[V]DUKESIGN.RSA\f[R], and placed in the \f[V]META-INF\f[R] -directory of the signed JAR file. -.RS -.PP -The characters in the file must come from the set \f[V]a-zA-Z0-9_-\f[R]. -Only letters, numbers, underscore, and hyphen characters are allowed. -All lowercase characters are converted to uppercase for the -\f[V].SF\f[R] and signature block file names. -.PP -If no \f[V]-sigfile\f[R] option appears on the command line, then the -base file name for the \f[V].SF\f[R] and signature block files is the -first 8 characters of the alias name specified on the command line, all -converted to upper case. -If the alias name has fewer than 8 characters, then the full alias name -is used. -If the alias name contains any characters that aren\[aq]t valid in a -signature file name, then each such character is converted to an -underscore (_) character to form the file name. -.RE -.TP -\f[V]-signedjar\f[R] \f[I]file\f[R] -Specifies the name of signed JAR file. -.TP -\f[V]-digestalg\f[R] \f[I]algorithm\f[R] -Specifies the name of the message digest algorithm to use when digesting -the entries of a JAR file. -.RS -.PP -For a list of standard message digest algorithm names, see the Java -Security Standard Algorithm Names Specification. -.PP -If this option isn\[aq]t specified, then \f[V]SHA-384\f[R] is used. -There must either be a statically installed provider supplying an -implementation of the specified algorithm or the user must specify one -with the \f[V]-addprovider\f[R] or \f[V]-providerClass\f[R] options; -otherwise, the command will not succeed. -.RE -.TP -\f[V]-sigalg\f[R] \f[I]algorithm\f[R] -Specifies the name of the signature algorithm to use to sign the JAR -file. -.RS -.PP -This algorithm must be compatible with the private key used to sign the -JAR file. -If this option isn\[aq]t specified, then use a default algorithm -matching the private key as described in the \f[B]Supported -Algorithms\f[R] section. -There must either be a statically installed provider supplying an -implementation of the specified algorithm or you must specify one with -the \f[V]-addprovider\f[R] or \f[V]-providerClass\f[R] option; -otherwise, the command doesn\[aq]t succeed. -.PP -For a list of standard signature algorithm names, see the Java Security -Standard Algorithm Names Specification. -.RE -.TP -\f[V]-verify\f[R] -Verifies a signed JAR file. -.TP -\f[V]-verbose\f[R][\f[V]:\f[R]\f[I]suboptions\f[R]] -When the \f[V]-verbose\f[R] option appears on the command line, it -indicates that the \f[V]jarsigner\f[R] use the verbose mode when signing -or verifying with the suboptions determining how much information is -shown. -This causes the , which causes \f[V]jarsigner\f[R] to output extra -information about the progress of the JAR signing or verification. -The \f[I]suboptions\f[R] can be \f[V]all\f[R], \f[V]grouped\f[R], or -\f[V]summary\f[R]. -.RS -.PP -If the \f[V]-certs\f[R] option is also specified, then the default mode -(or suboption \f[V]all\f[R]) displays each entry as it is being -processed, and after that, the certificate information for each signer -of the JAR file. -.PP -If the \f[V]-certs\f[R] and the \f[V]-verbose:grouped\f[R] suboptions -are specified, then entries with the same signer info are grouped and -displayed together with their certificate information. -.PP -If \f[V]-certs\f[R] and the \f[V]-verbose:summary\f[R] suboptions are -specified, then entries with the same signer information are grouped and -displayed together with their certificate information. -.PP -Details about each entry are summarized and displayed as \f[I]one entry -(and more)\f[R]. -See \f[B]Example of Verifying a Signed JAR File\f[R] and \f[B]Example of -Verification with Certificate Information\f[R]. -.RE -.TP -\f[V]-certs\f[R] -If the \f[V]-certs\f[R] option appears on the command line with the -\f[V]-verify\f[R] and \f[V]-verbose\f[R] options, then the output -includes certificate information for each signer of the JAR file. -This information includes the name of the type of certificate (stored in -the signature block file) that certifies the signer\[aq]s public key, -and if the certificate is an X.509 certificate (an instance of the -\f[V]java.security.cert.X509Certificate\f[R]), then the distinguished -name of the signer. -.RS -.PP -The keystore is also examined. -If no keystore value is specified on the command line, then the default -keystore file (if any) is checked. -If the public key certificate for a signer matches an entry in the -keystore, then the alias name for the keystore entry for that signer is -displayed in parentheses. -.RE -.TP -\f[V]-revCheck\f[R] -This option enables revocation checking of certificates when signing or -verifying a JAR file. -The \f[V]jarsigner\f[R] command attempts to make network connections to -fetch OCSP responses and CRLs if the \f[V]-revCheck\f[R] option is -specified on the command line. -Note that revocation checks are not enabled unless this option is -specified. -.TP -\f[V]-tsa\f[R] \f[I]url\f[R] -If \f[V]-tsa http://example.tsa.url\f[R] appears on the command line -when signing a JAR file then a time stamp is generated for the -signature. -The URL, \f[V]http://example.tsa.url\f[R], identifies the location of -the Time Stamping Authority (TSA) and overrides any URL found with the -\f[V]-tsacert\f[R] option. -The \f[V]-tsa\f[R] option doesn\[aq]t require the TSA public key -certificate to be present in the keystore. -.RS -.PP -To generate the time stamp, \f[V]jarsigner\f[R] communicates with the -TSA with the Time-Stamp Protocol (TSP) defined in RFC 3161. -When successful, the time stamp token returned by the TSA is stored with -the signature in the signature block file. -.RE -.TP -\f[V]-tsacert\f[R] \f[I]alias\f[R] -When \f[V]-tsacert\f[R] \f[I]alias\f[R] appears on the command line when -signing a JAR file, a time stamp is generated for the signature. -The alias identifies the TSA public key certificate in the keystore that -is in effect. -The entry\[aq]s certificate is examined for a Subject Information Access -extension that contains a URL identifying the location of the TSA. -.RS -.PP -The TSA public key certificate must be present in the keystore when -using the \f[V]-tsacert\f[R] option. -.RE -.TP -\f[V]-tsapolicyid\f[R] \f[I]policyid\f[R] -Specifies the object identifier (OID) that identifies the policy ID to -be sent to the TSA server. -If this option isn\[aq]t specified, no policy ID is sent and the TSA -server will choose a default policy ID. -.RS -.PP -Object identifiers are defined by X.696, which is an ITU -Telecommunication Standardization Sector (ITU-T) standard. -These identifiers are typically period-separated sets of non-negative -digits like \f[V]1.2.3.4\f[R], for example. -.RE -.TP -\f[V]-tsadigestalg\f[R] \f[I]algorithm\f[R] -Specifies the message digest algorithm that is used to generate the -message imprint to be sent to the TSA server. -If this option isn\[aq]t specified, SHA-384 will be used. -.RS -.PP -See \f[B]Supported Algorithms\f[R]. -.PP -For a list of standard message digest algorithm names, see the Java -Security Standard Algorithm Names Specification. -.RE -.TP -\f[V]-internalsf\f[R] -In the past, the signature block file generated when a JAR file was -signed included a complete encoded copy of the \f[V].SF\f[R] file -(signature file) also generated. -This behavior has been changed. -To reduce the overall size of the output JAR file, the signature block -file by default doesn\[aq]t contain a copy of the \f[V].SF\f[R] file -anymore. -If \f[V]-internalsf\f[R] appears on the command line, then the old -behavior is utilized. -This option is useful for testing. -In practice, don\[aq]t use the \f[V]-internalsf\f[R] option because it -incurs higher overhead. -.TP -\f[V]-sectionsonly\f[R] -If the \f[V]-sectionsonly\f[R] option appears on the command line, then -the \f[V].SF\f[R] file (signature file) generated when a JAR file is -signed doesn\[aq]t include a header that contains a hash of the whole -manifest file. -It contains only the information and hashes related to each individual -source file included in the JAR file. -See Signature File. -.RS -.PP -By default, this header is added, as an optimization. -When the header is present, whenever the JAR file is verified, the -verification can first check to see whether the hash in the header -matches the hash of the whole manifest file. -When there is a match, verification proceeds to the next step. -When there is no match, it is necessary to do a less optimized -verification that the hash in each source file information section in -the \f[V].SF\f[R] file equals the hash of its corresponding section in -the manifest file. -See \f[B]JAR File Verification\f[R]. -.PP -The \f[V]-sectionsonly\f[R] option is primarily used for testing. -It shouldn\[aq]t be used other than for testing because using it incurs -higher overhead. -.RE -.TP -\f[V]-protected\f[R] -Values can be either \f[V]true\f[R] or \f[V]false\f[R]. -Specify \f[V]true\f[R] when a password must be specified through a -protected authentication path such as a dedicated PIN reader. -.TP -\f[V]-providerName\f[R] \f[I]providerName\f[R] -If more than one provider was configured in the \f[V]java.security\f[R] -security properties file, then you can use the \f[V]-providerName\f[R] -option to target a specific provider instance. -The argument to this option is the name of the provider. -.RS -.PP -For the Oracle PKCS #11 provider, \f[I]providerName\f[R] is of the form -\f[V]SunPKCS11-\f[R]\f[I]TokenName\f[R], where \f[I]TokenName\f[R] is -the name suffix that the provider instance has been configured with, as -detailed in the configuration attributes table. -For example, the following command lists the contents of the -\f[V]PKCS #11\f[R] keystore provider instance with name suffix -\f[V]SmartCard\f[R]: -.RS -.PP -\f[V]jarsigner -keystore NONE -storetype PKCS11 -providerName SunPKCS11-SmartCard -list\f[R] -.RE -.RE -.TP -\f[V]-addprovider\f[R] \f[I]name\f[R] [\f[V]-providerArg\f[R] \f[I]arg\f[R]] -Adds a security provider by name (such as SunPKCS11) and an optional -configure argument. -The value of the security provider is the name of a security provider -that is defined in a module. -.RS -.PP -Used with the \f[V]-providerArg ConfigFilePath\f[R] option, the -\f[V]keytool\f[R] and \f[V]jarsigner\f[R] tools install the provider -dynamically and use \f[V]ConfigFilePath\f[R] for the path to the token -configuration file. -The following example shows a command to list a \f[V]PKCS #11\f[R] -keystore when the Oracle PKCS #11 provider wasn\[aq]t configured in the -security properties file. -.RS -.PP -\f[V]jarsigner -keystore NONE -storetype PKCS11 -addprovider SunPKCS11 -providerArg /mydir1/mydir2/token.config\f[R] -.RE -.RE -.TP -\f[V]-providerClass\f[R] \f[I]provider-class-name\f[R] [\f[V]-providerArg\f[R] \f[I]arg\f[R]] -Used to specify the name of cryptographic service provider\[aq]s master -class file when the service provider isn\[aq]t listed in the -\f[V]java.security\f[R] security properties file. -Adds a security provider by fully-qualified class name and an optional -configure argument. -.RS -.PP -\f[B]Note:\f[R] -.PP -The preferred way to load PKCS11 is by using modules. -See \f[V]-addprovider\f[R]. -.RE -.TP -\f[V]-providerPath\f[R] \f[I]classpath\f[R] -Used to specify the classpath for providers specified by the -\f[V]-providerClass\f[R] option. -Multiple paths should be separated by the system-dependent -path-separator character. -.TP -\f[V]-J\f[R]\f[I]javaoption\f[R] -Passes through the specified \f[I]javaoption\f[R] string directly to the -Java interpreter. -The \f[V]jarsigner\f[R] command is a wrapper around the interpreter. -This option shouldn\[aq]t contain any spaces. -It is useful for adjusting the execution environment or memory usage. -For a list of possible interpreter options, type \f[V]java -h\f[R] or -\f[V]java -X\f[R] at the command line. -.TP -\f[V]-strict\f[R] -During the signing or verifying process, the command may issue warning -messages. -If you specify this option, the exit code of the tool reflects the -severe warning messages that this command found. -See \f[B]Errors and Warnings\f[R]. -.TP -\f[V]-conf\f[R] \f[I]url\f[R] -Specifies a pre-configured options file. -Read the \f[B]keytool documentation\f[R] for details. -The property keys supported are \[dq]jarsigner.all\[dq] for all actions, -\[dq]jarsigner.sign\[dq] for signing, and \[dq]jarsigner.verify\[dq] for -verification. -\f[V]jarsigner\f[R] arguments including the JAR file name and alias -name(s) cannot be set in this file. -.TP -\f[V]-version\f[R] -Prints the program version. -.SH ERRORS AND WARNINGS -.PP -During the signing or verifying process, the \f[V]jarsigner\f[R] command -may issue various errors or warnings. -.PP -If there is a failure, the \f[V]jarsigner\f[R] command exits with code -1. -If there is no failure, but there are one or more severe warnings, the -\f[V]jarsigner\f[R] command exits with code 0 when the \f[V]-strict\f[R] -option is \f[B]not\f[R] specified, or exits with the OR-value of the -warning codes when the \f[V]-strict\f[R] is specified. -If there is only informational warnings or no warning at all, the -command always exits with code 0. -.PP -For example, if a certificate used to sign an entry is expired and has a -KeyUsage extension that doesn\[aq]t allow it to sign a file, the -\f[V]jarsigner\f[R] command exits with code 12 (=4+8) when the -\f[V]-strict\f[R] option is specified. -.PP -\f[B]Note:\f[R] Exit codes are reused because only the values from 0 to -255 are legal on Linux and macOS. -.PP -The following sections describes the names, codes, and descriptions of -the errors and warnings that the \f[V]jarsigner\f[R] command can issue. -.SH FAILURE -.PP -Reasons why the \f[V]jarsigner\f[R] command fails include (but -aren\[aq]t limited to) a command line parsing error, the inability to -find a keypair to sign the JAR file, or the verification of a signed JAR -fails. -.TP -failure -Code 1. -The signing or verifying fails. -.SH SEVERE WARNINGS -.PP -\f[B]Note:\f[R] -.PP -Severe warnings are reported as errors if you specify the -\f[V]-strict\f[R] option. -.PP -Reasons why the \f[V]jarsigner\f[R] command issues a severe warning -include the certificate used to sign the JAR file has an error or the -signed JAR file has other problems. -.TP -hasExpiredCert -Code 4. -This JAR contains entries whose signer certificate has expired. -.TP -hasExpiredTsaCert -Code 4. -The timestamp has expired. -.TP -notYetValidCert -Code 4. -This JAR contains entries whose signer certificate isn\[aq]t yet valid. -.TP -chainNotValidated -Code 4. -This JAR contains entries whose certificate chain isn\[aq]t validated. -.TP -tsaChainNotValidated -Code 64. -The timestamp is invalid. -.TP -signerSelfSigned -Code 4. -This JAR contains entries whose signer certificate is self signed. -.TP -disabledAlg -Code 4. -An algorithm used is considered a security risk and is disabled. -.TP -badKeyUsage -Code 8. -This JAR contains entries whose signer certificate\[aq]s KeyUsage -extension doesn\[aq]t allow code signing. -.TP -badExtendedKeyUsage -Code 8. -This JAR contains entries whose signer certificate\[aq]s -ExtendedKeyUsage extension doesn\[aq]t allow code signing. -.TP -badNetscapeCertType -Code 8. -This JAR contains entries whose signer certificate\[aq]s -NetscapeCertType extension doesn\[aq]t allow code signing. -.TP -hasUnsignedEntry -Code 16. -This JAR contains unsigned entries which haven\[aq]t been -integrity-checked. -.TP -notSignedByAlias -Code 32. -This JAR contains signed entries which aren\[aq]t signed by the -specified alias(es). -.TP -aliasNotInStore -Code 32. -This JAR contains signed entries that aren\[aq]t signed by alias in this -keystore. -.TP -tsaChainNotValidated -Code 64. -This JAR contains entries whose TSA certificate chain is invalid. -.SH INFORMATIONAL WARNINGS -.PP -Informational warnings include those that aren\[aq]t errors but regarded -as bad practice. -They don\[aq]t have a code. -.TP -extraAttributesDetected -The POSIX file permissions and/or symlink attributes are detected during -signing or verifying a JAR file. -The \f[V]jarsigner\f[R] tool preserves these attributes in the newly -signed file but warns that these attributes are unsigned and not -protected by the signature. -.TP -hasExpiringCert -This JAR contains entries whose signer certificate expires within six -months. -.TP -hasExpiringTsaCert -The timestamp will expire within one year on \f[V]YYYY-MM-DD\f[R]. -.TP -legacyAlg -An algorithm used is considered a security risk but not disabled. -.TP -noTimestamp -This JAR contains signatures that doesn\[aq]t include a timestamp. -Without a timestamp, users may not be able to validate this JAR file -after the signer certificate\[aq]s expiration date -(\f[V]YYYY-MM-DD\f[R]) or after any future revocation date. -.SH EXAMPLE OF SIGNING A JAR FILE -.PP -Use the following command to sign \f[V]bundle.jar\f[R] with the private -key of a user whose keystore alias is \f[V]jane\f[R] in a keystore named -\f[V]mystore\f[R] in the \f[V]working\f[R] directory and name the signed -JAR file \f[V]sbundle.jar\f[R]: -.RS -.PP -\f[V]jarsigner -keystore /working/mystore -storepass\f[R] -\f[I]keystore_password\f[R] \f[V]-keypass\f[R] -\f[I]private_key_password\f[R] -\f[V]-signedjar sbundle.jar bundle.jar jane\f[R] -.RE -.PP -There is no \f[V]-sigfile\f[R] specified in the previous command so the -generated \f[V].SF\f[R] and signature block files to be placed in the -signed JAR file have default names based on the alias name. -They are named \f[V]JANE.SF\f[R] and \f[V]JANE.RSA\f[R]. -.PP -If you want to be prompted for the store password and the private key -password, then you could shorten the previous command to the following: -.RS -.PP -\f[V]jarsigner -keystore /working/mystore -signedjar sbundle.jar bundle.jar jane\f[R] -.RE -.PP -If the \f[V]keystore\f[R] is the default \f[V]keystore\f[R] -(\f[V].keystore\f[R] in your home directory), then you don\[aq]t need to -specify a \f[V]keystore\f[R], as follows: -.RS -.PP -\f[V]jarsigner -signedjar sbundle.jar bundle.jar jane\f[R] -.RE -.PP -If you want the signed JAR file to overwrite the input JAR file -(\f[V]bundle.jar\f[R]), then you don\[aq]t need to specify a -\f[V]-signedjar\f[R] option, as follows: -.RS -.PP -\f[V]jarsigner bundle.jar jane\f[R] -.RE -.SH EXAMPLE OF VERIFYING A SIGNED JAR FILE -.PP -To verify a signed JAR file to ensure that the signature is valid and -the JAR file wasn\[aq]t been tampered with, use a command such as the -following: -.RS -.PP -\f[V]jarsigner -verify ButtonDemo.jar\f[R] -.RE -.PP -When the verification is successful, \f[V]jar verified\f[R] is -displayed. -Otherwise, an error message is displayed. -You can get more information when you use the \f[V]-verbose\f[R] option. -A sample use of \f[V]jarsigner\f[R] with the \f[V]-verbose\f[R] option -follows: -.IP -.nf -\f[CB] -jarsigner -verify -verbose ButtonDemo.jar - -s 866 Tue Sep 12 20:08:48 EDT 2017 META-INF/MANIFEST.MF - 825 Tue Sep 12 20:08:48 EDT 2017 META-INF/ORACLE_C.SF - 7475 Tue Sep 12 20:08:48 EDT 2017 META-INF/ORACLE_C.RSA - 0 Tue Sep 12 20:07:54 EDT 2017 META-INF/ - 0 Tue Sep 12 20:07:16 EDT 2017 components/ - 0 Tue Sep 12 20:07:16 EDT 2017 components/images/ -sm 523 Tue Sep 12 20:07:16 EDT 2017 components/ButtonDemo$1.class -sm 3440 Tue Sep 12 20:07:16 EDT 2017 components/ButtonDemo.class -sm 2346 Tue Sep 12 20:07:16 EDT 2017 components/ButtonDemo.jnlp -sm 172 Tue Sep 12 20:07:16 EDT 2017 components/images/left.gif -sm 235 Tue Sep 12 20:07:16 EDT 2017 components/images/middle.gif -sm 172 Tue Sep 12 20:07:16 EDT 2017 components/images/right.gif - - s = signature was verified - m = entry is listed in manifest - k = at least one certificate was found in keystore - -- Signed by \[dq]CN=\[dq]Oracle America, Inc.\[dq], OU=Software Engineering, O=\[dq]Oracle America, Inc.\[dq], L=Redwood City, ST=California, C=US\[dq] - Digest algorithm: SHA-256 - Signature algorithm: SHA256withRSA, 2048-bit key - Timestamped by \[dq]CN=Symantec Time Stamping Services Signer - G4, O=Symantec Corporation, C=US\[dq] on Tue Sep 12 20:08:49 UTC 2017 - Timestamp digest algorithm: SHA-1 - Timestamp signature algorithm: SHA1withRSA, 2048-bit key - -jar verified. - -The signer certificate expired on 2018-02-01. However, the JAR will be valid until the timestamp expires on 2020-12-29. -\f[R] -.fi -.SH EXAMPLE OF VERIFICATION WITH CERTIFICATE INFORMATION -.PP -If you specify the \f[V]-certs\f[R] option with the \f[V]-verify\f[R] -and \f[V]-verbose\f[R] options, then the output includes certificate -information for each signer of the JAR file. -The information includes the certificate type, the signer distinguished -name information (when it is an X.509 certificate), and in parentheses, -the keystore alias for the signer when the public key certificate in the -JAR file matches the one in a keystore entry, for example: -.IP -.nf -\f[CB] -jarsigner -keystore $JAVA_HOME/lib/security/cacerts -verify -verbose -certs ButtonDemo.jar - -s k 866 Tue Sep 12 20:08:48 EDT 2017 META-INF/MANIFEST.MF - - >>> Signer - X.509, CN=\[dq]Oracle America, Inc.\[dq], OU=Software Engineering, O=\[dq]Oracle America, Inc.\[dq], L=Redwood City, ST=California, C=US - [certificate is valid from 2017-01-30, 7:00 PM to 2018-02-01, 6:59 PM] - X.509, CN=Symantec Class 3 SHA256 Code Signing CA, OU=Symantec Trust Network, O=Symantec Corporation, C=US - [certificate is valid from 2013-12-09, 7:00 PM to 2023-12-09, 6:59 PM] - X.509, CN=VeriSign Class 3 Public Primary Certification Authority - G5, OU=\[dq](c) 2006 VeriSign, Inc. - For authorized use only\[dq], OU=VeriSign Trust Network, O=\[dq]VeriSign, Inc.\[dq], C=US (verisignclass3g5ca [jdk]) - [trusted certificate] - >>> TSA - X.509, CN=Symantec Time Stamping Services Signer - G4, O=Symantec Corporation, C=US - [certificate is valid from 2012-10-17, 8:00 PM to 2020-12-29, 6:59 PM] - X.509, CN=Symantec Time Stamping Services CA - G2, O=Symantec Corporation, C=US - [certificate is valid from 2012-12-20, 7:00 PM to 2020-12-30, 6:59 PM] - - 825 Tue Sep 12 20:08:48 EDT 2017 META-INF/ORACLE_C.SF - 7475 Tue Sep 12 20:08:48 EDT 2017 META-INF/ORACLE_C.RSA - 0 Tue Sep 12 20:07:54 EDT 2017 META-INF/ - 0 Tue Sep 12 20:07:16 EDT 2017 components/ - 0 Tue Sep 12 20:07:16 EDT 2017 components/images/ -smk 523 Tue Sep 12 20:07:16 EDT 2017 components/ButtonDemo$1.class - - [entry was signed on 2017-09-12, 4:08 PM] - >>> Signer - X.509, CN=\[dq]Oracle America, Inc.\[dq], OU=Software Engineering, O=\[dq]Oracle America, Inc.\[dq], L=Redwood City, ST=California, C=US - [certificate is valid from 2017-01-30, 7:00 PM to 2018-02-01, 6:59 PM] - X.509, CN=Symantec Class 3 SHA256 Code Signing CA, OU=Symantec Trust Network, O=Symantec Corporation, C=US - [certificate is valid from 2013-12-09, 7:00 PM to 2023-12-09, 6:59 PM] - X.509, CN=VeriSign Class 3 Public Primary Certification Authority - G5, OU=\[dq](c) 2006 VeriSign, Inc. - For authorized use only\[dq], OU=VeriSign Trust Network, O=\[dq]VeriSign, Inc.\[dq], C=US (verisignclass3g5ca [jdk]) - [trusted certificate] - >>> TSA - X.509, CN=Symantec Time Stamping Services Signer - G4, O=Symantec Corporation, C=US - [certificate is valid from 2012-10-17, 8:00 PM to 2020-12-29, 6:59 PM] - X.509, CN=Symantec Time Stamping Services CA - G2, O=Symantec Corporation, C=US - [certificate is valid from 2012-12-20, 7:00 PM to 2020-12-30, 6:59 PM] - -smk 3440 Tue Sep 12 20:07:16 EDT 2017 components/ButtonDemo.class -\&... -smk 2346 Tue Sep 12 20:07:16 EDT 2017 components/ButtonDemo.jnlp -\&... -smk 172 Tue Sep 12 20:07:16 EDT 2017 components/images/left.gif -\&... -smk 235 Tue Sep 12 20:07:16 EDT 2017 components/images/middle.gif -\&... -smk 172 Tue Sep 12 20:07:16 EDT 2017 components/images/right.gif -\&... - - s = signature was verified - m = entry is listed in manifest - k = at least one certificate was found in keystore - -- Signed by \[dq]CN=\[dq]Oracle America, Inc.\[dq], OU=Software Engineering, O=\[dq]Oracle America, Inc.\[dq], L=Redwood City, ST=California, C=US\[dq] - Digest algorithm: SHA-256 - Signature algorithm: SHA256withRSA, 2048-bit key - Timestamped by \[dq]CN=Symantec Time Stamping Services Signer - G4, O=Symantec Corporation, C=US\[dq] on Tue Sep 12 20:08:49 UTC 2017 - Timestamp digest algorithm: SHA-1 - Timestamp signature algorithm: SHA1withRSA, 2048-bit key - -jar verified. - -The signer certificate expired on 2018-02-01. However, the JAR will be valid until the timestamp expires on 2020-12-29. -\f[R] -.fi -.PP -If the certificate for a signer isn\[aq]t an X.509 certificate, then -there is no distinguished name information. -In that case, just the certificate type and the alias are shown. -For example, if the certificate is a PGP certificate, and the alias is -\f[V]bob\f[R], then you would get: \f[V]PGP, (bob)\f[R]. diff --git a/src/jdk.jartool/share/man/jarsigner.md b/src/jdk.jartool/share/man/jarsigner.md new file mode 100644 index 00000000000..9542c0fda60 --- /dev/null +++ b/src/jdk.jartool/share/man/jarsigner.md @@ -0,0 +1,1089 @@ +--- +# Copyright (c) 1998, 2024, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# This code is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 only, as +# published by the Free Software Foundation. +# +# This code is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# version 2 for more details (a copy is included in the LICENSE file that +# accompanied this code). +# +# You should have received a copy of the GNU General Public License version +# 2 along with this work; if not, write to the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +# or visit www.oracle.com if you need additional information or have any +# questions. +# + +title: 'JARSIGNER(1) JDK @@VERSION_SHORT@@ | JDK Commands' +date: @@COPYRIGHT_YEAR@@ +lang: en +--- + +## Name + +jarsigner - sign and verify Java Archive (JAR) files + +## Synopsis + +`jarsigner` \[*options*\] *jar-file* *alias* + +`jarsigner` `-verify` \[*options*\] *jar-file* \[*alias* ...\] + +`jarsigner` `-version` + +*options* +: The command-line options. See [Options for jarsigner]. + +`-verify` +: The `-verify` option can take zero or more keystore alias names after the + JAR file name. When the `-verify` option is specified, the `jarsigner` + command checks that the certificate used to verify each signed entry in the + JAR file matches one of the keystore aliases. The aliases are defined in + the keystore specified by `-keystore` or the default keystore. + + If you also specify the `-strict` option, and the `jarsigner` command + detects severe warnings, the message, "jar verified, with signer errors" is + displayed. + +*jar-file* +: The JAR file to be signed. + + If you also specified the `-strict` option, and the `jarsigner` command + detected severe warnings, the message, "jar signed, with signer errors" is + displayed. + +*alias* +: The aliases are defined in the keystore specified by `-keystore` or the + default keystore. + +`-version` +: The `-version` option prints the program version of `jarsigner`. + +## Description + +The `jarsigner` tool has two purposes: + +- To sign Java Archive (JAR) files. + +- To verify the signatures and integrity of signed JAR files. + +The JAR feature enables the packaging of class files, images, sounds, and other +digital data in a single file for faster and easier distribution. A tool named +`jar` enables developers to produce JAR files. (Technically, any ZIP file can +also be considered a JAR file, although when created by the `jar` command or +processed by the `jarsigner` command, JAR files also contain a +`META-INF/MANIFEST.MF` file.) + +A digital signature is a string of bits that is computed from some data (the +data being signed) and the private key of an entity (a person, company, and so +on). Similar to a handwritten signature, a digital signature has many useful +characteristics: + +- Its authenticity can be verified by a computation that uses the public key + corresponding to the private key used to generate the signature. + +- It can't be forged, assuming the private key is kept secret. + +- It is a function of the data signed and thus can't be claimed to be the + signature for other data as well. + +- The signed data can't be changed. If the data is changed, then the + signature can't be verified as authentic. + +To generate an entity's signature for a file, the entity must first have a +public/private key pair associated with it and one or more certificates that +authenticate its public key. A certificate is a digitally signed statement from +one entity that says that the public key of another entity has a particular +value. + +The `jarsigner` command uses key and certificate information from a keystore to +generate digital signatures for JAR files. A keystore is a database of private +keys and their associated X.509 certificate chains that authenticate the +corresponding public keys. The `keytool` command is used to create and +administer keystores. + +The `jarsigner` command uses an entity's private key to generate a signature. +The signed JAR file contains, among other things, a copy of the certificate +from the keystore for the public key corresponding to the private key used to +sign the file. The `jarsigner` command can verify the digital signature of the +signed JAR file using the certificate inside it (in its signature block file). + +The `jarsigner` command can generate signatures that include a time stamp that +enables a systems or deployer to check whether the JAR file was signed while +the signing certificate was still valid. + +In addition, APIs allow applications to obtain the timestamp information. + +At this time, the `jarsigner` command can only sign JAR files created by the +`jar` command or zip files. JAR files are the same as zip files, except they +also have a `META-INF/MANIFEST.MF` file. A `META-INF/MANIFEST.MF` file is +created when the `jarsigner` command signs a zip file. + +The default `jarsigner` command behavior is to sign a JAR or zip file. Use the +`-verify` option to verify a signed JAR file. + +The `jarsigner` command also attempts to validate the signer's certificate +after signing or verifying. During validation, it checks the revocation +status of each certificate in the signer's certificate chain when the +`-revCheck` option is specified. If there is a validation error or any other +problem, the command generates warning messages. If you specify the `-strict` +option, then the command treats severe warnings as errors. See [Errors and +Warnings]. + +## Keystore Aliases + +All keystore entities are accessed with unique aliases. + +When you use the `jarsigner` command to sign a JAR file, you must specify the +alias for the keystore entry that contains the private key needed to generate +the signature. If no output file is specified, it overwrites the original JAR +file with the signed JAR file. + +Keystores are protected with a password, so the store password must be +specified. You are prompted for it when you don't specify it on the command +line. Similarly, private keys are protected in a keystore with a password, so +the private key's password must be specified, and you are prompted for the +password when you don't specify it on the command line and it isn't the same as +the store password. + +## Keystore Location + +The `jarsigner` command has a `-keystore` option for specifying the URL of the +keystore to be used. The keystore is by default stored in a file named +`.keystore` in the user's home directory, as determined by the `user.home` +system property. + +**Linux and macOS:** `user.home` defaults to the user's home +directory. + +The input stream from the `-keystore` option is passed to the `KeyStore.load` +method. If `NONE` is specified as the URL, then a null stream is passed to the +`KeyStore.load` method. `NONE` should be specified when the `KeyStore` class +isn't file based, for example, when it resides on a hardware token device. + +## Keystore Implementation + +The `KeyStore` class provided in the `java.security` package supplies a number +of well-defined interfaces to access and modify the information in a keystore. +You can have multiple different concrete implementations, where each +implementation is for a particular type of keystore. + +Currently, there are two command-line tools that use keystore implementations +(`keytool` and `jarsigner`). + +The default keystore implementation is `PKCS12`. This is a cross platform +keystore based on the RSA PKCS12 Personal Information Exchange Syntax Standard. +This standard is primarily meant for storing or transporting a user's private +keys, certificates, and miscellaneous secrets. There is another built-in +implementation, provided by Oracle. It implements the keystore as a file with a +proprietary keystore type (format) named `JKS`. It protects each private key +with its individual password, and also protects the integrity of the entire +keystore with a (possibly different) password. + +Keystore implementations are provider-based, which means the application +interfaces supplied by the `KeyStore` class are implemented in terms of a +Service Provider Interface (SPI). There is a corresponding abstract +`KeystoreSpi` class, also in the `java.security package`, that defines the +Service Provider Interface methods that providers must implement. The term +provider refers to a package or a set of packages that supply a concrete +implementation of a subset of services that can be accessed by the Java +Security API. To provide a keystore implementation, clients must implement a +provider and supply a `KeystoreSpi` subclass implementation, as described in +[How to Implement a Provider in the Java Cryptography Architecture]( +https://www.oracle.com/pls/topic/lookup?ctx=en/java/javase&id=security_guide_implement_provider_jca). + +Applications can choose different types of keystore implementations from +different providers, with the `getInstance` factory method in the `KeyStore` +class. A keystore type defines the storage and data format of the keystore +information and the algorithms used to protect private keys in the keystore and +the integrity of the keystore itself. Keystore implementations of different +types aren't compatible. + +The `jarsigner` commands can read file-based keystores from any location that +can be specified using a URL. In addition, these commands can read +non-file-based keystores such as those provided by MSCAPI on Windows and PKCS11 +on all platforms. + +For the `jarsigner` and `keytool` commands, you can specify a keystore type at +the command line with the `-storetype` option. + +If you don't explicitly specify a keystore type, then the tools choose a +keystore implementation based on the value of the `keystore.type` property +specified in the security properties file. The security properties file is +called `java.security`, and it resides in the JDK security properties +directory, `java.home/conf/security`. + +Each tool gets the `keystore.type` value and then examines all the installed +providers until it finds one that implements keystores of that type. It then +uses the keystore implementation from that provider. + +The `KeyStore` class defines a static method named `getDefaultType` that lets +applications retrieve the value of the `keystore.type` property. The following +line of code creates an instance of the default keystore type as specified in +the `keystore.type` property: + +> `KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());` + +The default keystore type is `pkcs12`, which is a cross platform keystore based +on the RSA PKCS12 Personal Information Exchange Syntax Standard. This is +specified by the following line in the security properties file: + +> `keystore.type=pkcs12` + +Case doesn't matter in keystore type designations. For example, `JKS` is the +same as `jks`. + +To have the tools utilize a keystore implementation other than the default, you +can change that line to specify a different keystore type. For example, if you +want to use the Oracle's `jks` keystore implementation, then change the line to +the following: + +> `keystore.type=jks` + +## Supported Algorithms + +By default, the `jarsigner` command signs a JAR file using one of the following +algorithms and block file extensions depending on the type and size of +the private key: + +Table: Default Signature Algorithms and Block File Extensions + +keyalg key size default sigalg block file extension +------- -------- -------------- -------------------- +DSA any size SHA256withDSA .DSA +RSA \< 624 SHA256withRSA .RSA + \<= 7680 SHA384withRSA + \> 7680 SHA512withRSA +EC \< 512 SHA384withECDSA .EC + \>= 512 SHA512withECDSA +RSASSA-PSS \< 624 RSASSA-PSS (with SHA-256) .RSA + \<= 7680 RSASSA-PSS (with SHA-384) + \> 7680 RSASSA-PSS (with SHA-512) +EdDSA 255 Ed25519 .EC + 448 Ed448 +------- -------- -------------- ------ + +* If an RSASSA-PSS key is encoded with parameters, then jarsigner will use the +same parameters in the signature. Otherwise, jarsigner will use parameters that +are determined by the size of the key as specified in the table above. +For example, an 3072-bit RSASSA-PSS key will use RSASSA-PSS as the signature +algorithm and SHA-384 as the hash and MGF1 algorithms. + +* If a key algorithm is not listed in this table, the `.DSA` extension +is used when signing a JAR file. + +These default signature algorithms can be overridden by using the `-sigalg` +option. + +The `jarsigner` command uses the `jdk.jar.disabledAlgorithms` and +`jdk.security.legacyAlgorithms` security properties to determine which +algorithms are considered a security risk. If the JAR file was signed +with any algorithms that are disabled, it will be treated as an unsigned JAR +file. If the JAR file was signed with any legacy algorithms, it will be treated +as signed with an informational warning to inform users that the legacy +algorithm will be disabled in a future update. +For detailed verification output, include `-J-Djava.security.debug=jar`. +The `jdk.jar.disabledAlgorithms` and `jdk.security.legacyAlgorithms` +security properties are defined in the `java.security` file (located in +the JDK's `$JAVA_HOME/conf/security` directory). + +**Note:** + +In order to improve out of the box security, default key size and signature +algorithm names are periodically updated to stronger values with each release +of the JDK. If interoperability with older releases of the JDK is important, +please make sure the defaults are supported by those releases, or alternatively +use the `-sigalg` option to override the default values at your own risk. + +## The Signed JAR File + +When the `jarsigner` command is used to sign a JAR file, the output signed JAR +file is exactly the same as the input JAR file, except that it has two +additional files placed in the META-INF directory: + +- A signature file with an `.SF` extension + +- A signature block file with a `.DSA`, `.RSA`, or `.EC` extension + +The base file names for these two files come from the value of the `-sigfile` +option. For example, when the option is `-sigfile MKSIGN`, the files are named +`MKSIGN.SF` and `MKSIGN.RSA`. In this document, we assume the signer always +uses an RSA key. + +If no `-sigfile` option appears on the command line, then the base file name +for the `.SF` and the signature block files is the first 8 characters of the alias name +specified on the command line, all converted to uppercase. If the alias name +has fewer than 8 characters, then the full alias name is used. If the alias +name contains any characters that aren't allowed in a signature file name, then +each such character is converted to an underscore (\_) character in forming the +file name. Valid characters include letters, digits, underscores, and hyphens. + +## Signature File + +A signature file (`.SF` file) looks similar to the manifest file that is always +included in a JAR file when the `jarsigner` command is used to sign the file. +For each source file included in the JAR file, the `.SF` file has two lines, +such as in the manifest file, that list the following: + +- File name + +- Name of the digest algorithm (SHA) + +- SHA digest value + +**Note:** + +The name of the digest algorithm (SHA) and the SHA digest value are on the same +line. + +In the manifest file, the SHA digest value for each source file is the digest +(hash) of the binary data in the source file. In the `.SF` file, the digest +value for a specified source file is the hash of the two lines in the manifest +file for the source file. + +The signature file, by default, includes a header with a hash of the whole +manifest file. The header also contains a hash of the manifest header. The +presence of the header enables verification optimization. See [JAR File +Verification]. + +## Signature Block File + +The `.SF` file is signed and the signature is placed in the signature block +file. This file also contains, encoded inside it, the certificate or +certificate chain from the keystore that authenticates the public key +corresponding to the private key used for signing. The file has the extension +`.DSA`, `.RSA`, or `.EC`, depending on the key algorithm used. See the table +in [Supported Algorithms]. + +## Signature Time Stamp + +The `jarsigner` command used with the following options generates and stores a +signature time stamp when signing a JAR file: + +- `-tsa` *url* + +- `-tsacert` *alias* + +- `-tsapolicyid` *policyid* + +- `-tsadigestalg` *algorithm* + +See [Options for jarsigner]. + +## JAR File Verification + +A successful JAR file verification occurs when the signatures are valid, and +none of the files that were in the JAR file when the signatures were generated +have changed since then. JAR file verification involves the following steps: + +1. Verify the signature of the `.SF` file. + + The verification ensures that the signature stored in each signature block + file was generated using the private key corresponding to the + public key whose certificate (or certificate chain) also appears in the + signature block file. It also ensures that the signature is a valid signature of the + corresponding signature (`.SF`) file, and thus the `.SF` file wasn't + tampered with. + +2. Verify the digest listed in each entry in the `.SF` file with each + corresponding section in the manifest. + + The `.SF` file by default includes a header that contains a hash of the + entire manifest file. When the header is present, the verification can + check to see whether or not the hash in the header matches the hash of the + manifest file. If there is a match, then verification proceeds to the next + step. + + If there is no match, then a less optimized verification is required to + ensure that the hash in each source file information section in the `.SF` + file equals the hash of its corresponding section in the manifest file. See + Signature File. + + One reason the hash of the manifest file that is stored in the `.SF` file + header might not equal the hash of the current manifest file is that it + might contain sections for newly added files after the file was signed. For + example, suppose one or more files were added to the signed JAR file (using + the `jar` tool) that already contains a signature and a `.SF` file. If the + JAR file is signed again by a different signer, then the manifest file is + changed (sections are added to it for the new files by the `jarsigner` tool) + and a new `.SF` file is created, but the original `.SF` file is unchanged. A + verification is still considered successful if none of the files that were + in the JAR file when the original signature was generated have been changed + since then. This is because the hashes in the non-header sections of the + `.SF` file equal the hashes of the corresponding sections in the manifest + file. + +3. Read each file in the JAR file that has an entry in the `.SF` file. While + reading, compute the file's digest and compare the result with the digest + for this file in the manifest section. The digests should be the same or + verification fails. + + If any serious verification failures occur during the verification process, + then the process is stopped and a security exception is thrown. The + `jarsigner` command catches and displays the exception. + +4. Check for disabled algorithm usage. See [Supported Algorithms]. + +**Note:** + +You should read any addition warnings (or errors if you specified the `-strict` +option), as well as the content of the certificate (by specifying the +`-verbose` and `-certs` options) to determine if the signature can be trusted. + +## Multiple Signatures for a JAR File + +A JAR file can be signed by multiple people by running the `jarsigner` command +on the file multiple times and specifying the alias for a different person each +time, as follows: + +``` +jarsigner myBundle.jar susan +jarsigner myBundle.jar kevin +``` + +When a JAR file is signed multiple times, there are multiple `.SF` and signature +block files in the resulting JAR file, one pair for each signature. In the previous +example, the output JAR file includes files with the following names: + +``` +SUSAN.SF +SUSAN.RSA +KEVIN.SF +KEVIN.RSA +``` + +## Options for jarsigner + +The following sections describe the options for the `jarsigner`. Be aware of +the following standards: + +- All option names are preceded by a hyphen sign (-). + +- The options can be provided in any order. + +- Items that are in italics or underlined (option values) represent the + actual values that must be supplied. + +- The `-storepass`, `-keypass`, `-sigfile`, `-sigalg`, `-digestalg`, + `-signedjar`, and TSA-related options are only relevant when signing a JAR + file; they aren't relevant when verifying a signed JAR file. The + `-keystore` option is relevant for signing and verifying a JAR file. In + addition, aliases are specified when signing and verifying a JAR file. + +`-keystore` *url* +: Specifies the URL that tells the keystore location. This defaults to the + file `.keystore` in the user's home directory, as determined by the + `user.home` system property. + + A keystore is required when signing. You must explicitly specify a keystore + when the default keystore doesn't exist or if you want to use one other + than the default. + + A keystore isn't required when verifying, but if one is specified or the + default exists and the `-verbose` option was also specified, then + additional information is output regarding whether or not any of the + certificates used to verify the JAR file are contained in that keystore. + + The `-keystore` argument can be a file name and path specification rather + than a URL, in which case it is treated the same as a file: URL, for + example, the following are equivalent: + + - `-keystore` *filePathAndName* + + - `-keystore file:`*filePathAndName* + + If the Sun PKCS \#11 provider was configured in the `java.security` + security properties file (located in the JDK's `$JAVA_HOME/conf/security` + directory), then the `keytool` and `jarsigner` tools can operate on the + PKCS \#11 token by specifying these options: + + > `-keystore NONE -storetype PKCS11` + + For example, the following command lists the contents of the configured + PKCS\#11 token: + + > `keytool -keystore NONE -storetype PKCS11 -list` + +`-storepass` \[`:env` \| `:file`\] *argument* +: Specifies the password that is required to access the keystore. This is + only needed when signing (not verifying) a JAR file. In that case, if a + `-storepass` option isn't provided at the command line, then the user is + prompted for the password. + + If the modifier `env` or `file` isn't specified, then the password has the + value `argument`. Otherwise, the password is retrieved as follows: + + - `env`: Retrieve the password from the environment variable named + *argument*. + + - `file`: Retrieve the password from the file named *argument*. + + **Note:** + + The password shouldn't be specified on the command line or in a script + unless it is for testing purposes, or you are on a secure system. + +`-storetype` *storetype* +: Specifies the type of keystore to be instantiated. The default keystore + type is the one that is specified as the value of the `keystore.type` + property in the security properties file, which is returned by the static + `getDefaultType` method in `java.security.KeyStore`. + + The PIN for a PKCS \#11 token can also be specified with the `-storepass` + option. If none is specified, then the `keytool` and `jarsigner` commands + prompt for the token PIN. If the token has a protected authentication path + (such as a dedicated PIN-pad or a biometric reader), then the `-protected` + option must be specified and no password options can be specified. + +`-keypass` \[`:env` \| `:file`\] *argument* `-certchain` *file* +: Specifies the password used to protect the private key of the keystore + entry addressed by the alias specified on the command line. The password is + required when using `jarsigner` to sign a JAR file. If no password is + provided on the command line, and the required password is different from + the store password, then the user is prompted for it. + + If the modifier `env` or `file` isn't specified, then the password has the + value `argument`. Otherwise, the password is retrieved as follows: + + - `env`: Retrieve the password from the environment variable named + *argument*. + + - `file`: Retrieve the password from the file named *argument*. + + **Note:** + + The password shouldn't be specified on the command line or in a script + unless it is for testing purposes, or you are on a secure system. + +`-certchain` *file* +: Specifies the certificate chain to be used when the certificate chain + associated with the private key of the keystore entry that is addressed by + the alias specified on the command line isn't complete. This can happen + when the keystore is located on a hardware token where there isn't enough + capacity to hold a complete certificate chain. The file can be a sequence + of concatenated X.509 certificates, or a single PKCS\#7 formatted data + block, either in binary encoding format or in printable encoding format + (also known as Base64 encoding) as defined by [Internet RFC 1421 + Certificate Encoding Standard](http://tools.ietf.org/html/rfc1421). + +`-sigfile` *file* +: Specifies the base file name to be used for the generated `.SF` and signature block + files. For example, if file is `DUKESIGN`, then the generated `.SF` and + signature block files are named `DUKESIGN.SF` and `DUKESIGN.RSA`, and placed in the + `META-INF` directory of the signed JAR file. + + The characters in the file must come from the set `a-zA-Z0-9_-`. Only + letters, numbers, underscore, and hyphen characters are allowed. All + lowercase characters are converted to uppercase for the `.SF` and signature block + file names. + + If no `-sigfile` option appears on the command line, then the base file + name for the `.SF` and signature block files is the first 8 characters of the alias + name specified on the command line, all converted to upper case. If the + alias name has fewer than 8 characters, then the full alias name is used. + If the alias name contains any characters that aren't valid in a signature + file name, then each such character is converted to an underscore (\_) + character to form the file name. + +`-signedjar` *file* +: Specifies the name of signed JAR file. + +`-digestalg` *algorithm* +: Specifies the name of the message digest algorithm to use when digesting + the entries of a JAR file. + + For a list of standard message digest algorithm names, see the Java Security + Standard Algorithm Names Specification. + + If this option isn't specified, then `SHA-384` is used. There must either be + a statically installed provider supplying an implementation of the + specified algorithm or the user must specify one with the `-addprovider` or + `-providerClass` options; otherwise, the command will not succeed. + +`-sigalg` *algorithm* +: Specifies the name of the signature algorithm to use to sign the JAR file. + + This algorithm must be compatible with the private key used to sign the + JAR file. If this option isn't specified, then use a default algorithm + matching the private key as described in the [Supported Algorithms] + section. There must either be a statically installed provider supplying an + implementation of the specified algorithm or you must specify one with the + `-addprovider` or `-providerClass` option; otherwise, the command doesn't + succeed. + + For a list of standard signature algorithm names, see the Java Security + Standard Algorithm Names Specification. + +`-verify` +: Verifies a signed JAR file. + +`-verbose`\[`:`*suboptions*\] +: When the `-verbose` option appears on the command line, it indicates that + the `jarsigner` use the verbose mode when signing or verifying with the + suboptions determining how much information is shown. This causes the , + which causes `jarsigner` to output extra information about the progress of + the JAR signing or verification. The *suboptions* can be `all`, `grouped`, + or `summary`. + + If the `-certs` option is also specified, then the default mode (or + suboption `all`) displays each entry as it is being processed, and after + that, the certificate information for each signer of the JAR file. + + If the `-certs` and the `-verbose:grouped` suboptions are specified, then + entries with the same signer info are grouped and displayed together with + their certificate information. + + If `-certs` and the `-verbose:summary` suboptions are specified, then + entries with the same signer information are grouped and displayed together + with their certificate information. + + Details about each entry are summarized and displayed as *one entry (and + more)*. See [Example of Verifying a Signed JAR File] and [Example of + Verification with Certificate Information]. + +`-certs` +: If the `-certs` option appears on the command line with the `-verify` and + `-verbose` options, then the output includes certificate information for + each signer of the JAR file. This information includes the name of the type + of certificate (stored in the signature block file) that certifies the signer's + public key, and if the certificate is an X.509 certificate (an instance of + the `java.security.cert.X509Certificate`), then the distinguished name of + the signer. + + The keystore is also examined. If no keystore value is specified on the + command line, then the default keystore file (if any) is checked. If the + public key certificate for a signer matches an entry in the keystore, then + the alias name for the keystore entry for that signer is displayed in + parentheses. + +`-revCheck` +: This option enables revocation checking of certificates when signing or + verifying a JAR file. The `jarsigner` command attempts to make network + connections to fetch OCSP responses and CRLs if the `-revCheck` option + is specified on the command line. Note that revocation checks are not + enabled unless this option is specified. + +`-tsa` *url* +: If `-tsa http://example.tsa.url` appears on the command line when signing a + JAR file then a time stamp is generated for the signature. The URL, + `http://example.tsa.url`, identifies the location of the Time Stamping + Authority (TSA) and overrides any URL found with the `-tsacert` option. The + `-tsa` option doesn't require the TSA public key certificate to be present + in the keystore. + + To generate the time stamp, `jarsigner` communicates with the TSA with the + Time-Stamp Protocol (TSP) defined in RFC 3161. When successful, the time + stamp token returned by the TSA is stored with the signature in the + signature block file. + +`-tsacert` *alias* +: When `-tsacert` *alias* appears on the command line when signing a JAR + file, a time stamp is generated for the signature. The alias identifies the + TSA public key certificate in the keystore that is in effect. The entry's + certificate is examined for a Subject Information Access extension that + contains a URL identifying the location of the TSA. + + The TSA public key certificate must be present in the keystore when using + the `-tsacert` option. + +`-tsapolicyid` *policyid* +: Specifies the object identifier (OID) that identifies the policy ID to be + sent to the TSA server. If this option isn't specified, no policy ID is + sent and the TSA server will choose a default policy ID. + + Object identifiers are defined by X.696, which is an ITU Telecommunication + Standardization Sector (ITU-T) standard. These identifiers are typically + period-separated sets of non-negative digits like `1.2.3.4`, for example. + +`-tsadigestalg` *algorithm* +: Specifies the message digest algorithm that is used to generate the message + imprint to be sent to the TSA server. If this option isn't specified, + SHA-384 will be used. + + See [Supported Algorithms]. + + For a list of standard message digest algorithm names, see the Java Security + Standard Algorithm Names Specification. + +`-internalsf` +: In the past, the signature block file generated when a JAR file + was signed included a complete encoded copy of the `.SF` file (signature + file) also generated. This behavior has been changed. To reduce the overall + size of the output JAR file, the signature block file by default doesn't contain a + copy of the `.SF` file anymore. If `-internalsf` appears on the command + line, then the old behavior is utilized. This option is useful for testing. + In practice, don't use the `-internalsf` option because it incurs higher + overhead. + +`-sectionsonly` +: If the `-sectionsonly` option appears on the command line, then the `.SF` + file (signature file) generated when a JAR file is signed doesn't include a + header that contains a hash of the whole manifest file. It contains only + the information and hashes related to each individual source file included + in the JAR file. See Signature File. + + By default, this header is added, as an optimization. When the header is + present, whenever the JAR file is verified, the verification can first + check to see whether the hash in the header matches the hash of the whole + manifest file. When there is a match, verification proceeds to the next + step. When there is no match, it is necessary to do a less optimized + verification that the hash in each source file information section in the + `.SF` file equals the hash of its corresponding section in the manifest + file. See [JAR File Verification]. + + The `-sectionsonly` option is primarily used for testing. It shouldn't be + used other than for testing because using it incurs higher overhead. + +`-protected` +: Values can be either `true` or `false`. Specify `true` when a password must + be specified through a protected authentication path such as a dedicated + PIN reader. + +`-providerName` *providerName* +: If more than one provider was configured in the `java.security` security + properties file, then you can use the `-providerName` option to target a + specific provider instance. The argument to this option is the name of the + provider. + + For the Oracle PKCS \#11 provider, *providerName* is of the form + `SunPKCS11-`*TokenName*, where *TokenName* is the name suffix that the + provider instance has been configured with, as detailed in the + configuration attributes table. For example, the following command lists + the contents of the `PKCS #11` keystore provider instance with name suffix + `SmartCard`: + + > `jarsigner -keystore NONE -storetype PKCS11 -providerName + SunPKCS11-SmartCard -list` + +`-addprovider` *name* \[`-providerArg` *arg*\] +: Adds a security provider by name (such as SunPKCS11) and an optional + configure argument. The value of the security provider is the name of a + security provider that is defined in a module. + + Used with the `-providerArg ConfigFilePath` option, the `keytool` and + `jarsigner` tools install the provider dynamically and use `ConfigFilePath` + for the path to the token configuration file. The following example shows a + command to list a `PKCS #11` keystore when the Oracle PKCS \#11 provider + wasn't configured in the security properties file. + + > `jarsigner -keystore NONE -storetype PKCS11 -addprovider SunPKCS11 + -providerArg /mydir1/mydir2/token.config` + +`-providerClass` *provider-class-name* \[`-providerArg` *arg*\] +: Used to specify the name of cryptographic service provider's master class + file when the service provider isn't listed in the `java.security` security + properties file. Adds a security provider by fully-qualified class name and + an optional configure argument. + + **Note:** + + The preferred way to load PKCS11 is by using modules. See `-addprovider`. + +`-providerPath` *classpath* +: Used to specify the classpath for providers specified by the `-providerClass` + option. Multiple paths should be separated by the system-dependent + path-separator character. + +`-J`*javaoption* +: Passes through the specified *javaoption* string directly to the Java + interpreter. The `jarsigner` command is a wrapper around the interpreter. + This option shouldn't contain any spaces. It is useful for adjusting the + execution environment or memory usage. For a list of possible interpreter + options, type `java -h` or `java -X` at the command line. + +`-strict` +: During the signing or verifying process, the command may issue warning + messages. If you specify this option, the exit code of the tool reflects + the severe warning messages that this command found. See [Errors and + Warnings]. + +`-conf` *url* +: Specifies a pre-configured options file. Read the + [keytool documentation](keytool.html#pre-configured-options-file) for + details. The property keys supported are "jarsigner.all" for all actions, + "jarsigner.sign" for signing, and "jarsigner.verify" for verification. + `jarsigner` arguments including the JAR file name and alias name(s) cannot + be set in this file. + +`-version` +: Prints the program version. + +## Errors and Warnings + +During the signing or verifying process, the `jarsigner` command may issue +various errors or warnings. + +If there is a failure, the `jarsigner` command exits with code 1. If there is +no failure, but there are one or more severe warnings, the `jarsigner` command +exits with code 0 when the `-strict` option is **not** specified, or exits with +the OR-value of the warning codes when the `-strict` is specified. If there is +only informational warnings or no warning at all, the command always exits with +code 0. + +For example, if a certificate used to sign an entry is expired and has a +KeyUsage extension that doesn't allow it to sign a file, the `jarsigner` +command exits with code 12 (=4+8) when the `-strict` option is specified. + +**Note:** Exit codes are reused because only the values from 0 to 255 are legal +on Linux and macOS. + +The following sections describes the names, codes, and descriptions of the +errors and warnings that the `jarsigner` command can issue. + +## Failure + +Reasons why the `jarsigner` command fails include (but aren't limited to) a +command line parsing error, the inability to find a keypair to sign the JAR +file, or the verification of a signed JAR fails. + +failure +: Code 1. The signing or verifying fails. + +## Severe Warnings + +**Note:** + +Severe warnings are reported as errors if you specify the `-strict` option. + +Reasons why the `jarsigner` command issues a severe warning include the +certificate used to sign the JAR file has an error or the signed JAR file has +other problems. + +hasExpiredCert +: Code 4. This JAR contains entries whose signer certificate has expired. + +hasExpiredTsaCert +: Code 4. The timestamp has expired. + +notYetValidCert +: Code 4. This JAR contains entries whose signer certificate isn't yet valid. + +chainNotValidated +: Code 4. This JAR contains entries whose certificate chain isn't validated. + +tsaChainNotValidated +: Code 64. The timestamp is invalid. + +signerSelfSigned +: Code 4. This JAR contains entries whose signer certificate is self signed. + +disabledAlg +: Code 4. An algorithm used is considered a security risk and is disabled. + +badKeyUsage +: Code 8. This JAR contains entries whose signer certificate's KeyUsage + extension doesn't allow code signing. + +badExtendedKeyUsage +: Code 8. This JAR contains entries whose signer certificate's + ExtendedKeyUsage extension doesn't allow code signing. + +badNetscapeCertType +: Code 8. This JAR contains entries whose signer certificate's + NetscapeCertType extension doesn't allow code signing. + +hasUnsignedEntry +: Code 16. This JAR contains unsigned entries which haven't been + integrity-checked. + +notSignedByAlias +: Code 32. This JAR contains signed entries which aren't signed by the + specified alias(es). + +aliasNotInStore +: Code 32. This JAR contains signed entries that aren't signed by alias in + this keystore. + +tsaChainNotValidated +: Code 64. This JAR contains entries whose TSA certificate chain is invalid. + +## Informational Warnings + +Informational warnings include those that aren't errors but regarded as bad +practice. They don't have a code. + +extraAttributesDetected +: The POSIX file permissions and/or symlink attributes are detected during + signing or verifying a JAR file. The `jarsigner` tool preserves these + attributes in the newly signed file but warns that these attributes are + unsigned and not protected by the signature. + +hasExpiringCert +: This JAR contains entries whose signer certificate expires within six + months. + +hasExpiringTsaCert +: The timestamp will expire within one year on `YYYY-MM-DD`. + +hasNonexistentEntries +: This JAR contains signed entries for files that do not exist. + +legacyAlg +: An algorithm used is considered a security risk but not disabled. + +noTimestamp +: This JAR contains signatures that doesn't include a timestamp. Without a + timestamp, users may not be able to validate this JAR file after the signer + certificate's expiration date (`YYYY-MM-DD`) or after any future revocation + date. + +## Example of Signing a JAR File + +Use the following command to sign `bundle.jar` with the private key of a user +whose keystore alias is `jane` in a keystore named `mystore` in the `working` +directory and name the signed JAR file `sbundle.jar`: + +> `jarsigner -keystore /working/mystore -storepass` *keystore\_password* + `-keypass` *private\_key\_password* `-signedjar sbundle.jar bundle.jar + jane` + +There is no `-sigfile` specified in the previous command so the generated `.SF` +and signature block files to be placed in the signed JAR file have default names based +on the alias name. They are named `JANE.SF` and `JANE.RSA`. + +If you want to be prompted for the store password and the private key password, +then you could shorten the previous command to the following: + +> `jarsigner -keystore /working/mystore -signedjar sbundle.jar bundle.jar + jane` + +If the `keystore` is the default `keystore` (`.keystore` in your home +directory), then you don't need to specify a `keystore`, as follows: + +> `jarsigner -signedjar sbundle.jar bundle.jar jane` + +If you want the signed JAR file to overwrite the input JAR file (`bundle.jar`), +then you don't need to specify a `-signedjar` option, as follows: + +> `jarsigner bundle.jar jane` + +## Example of Verifying a Signed JAR File + +To verify a signed JAR file to ensure that the signature is valid and the JAR +file wasn't been tampered with, use a command such as the following: + +> `jarsigner -verify ButtonDemo.jar` + +When the verification is successful, `jar verified` is displayed. Otherwise, an +error message is displayed. You can get more information when you use the +`-verbose` option. A sample use of `jarsigner` with the `-verbose` option +follows: + +``` +jarsigner -verify -verbose ButtonDemo.jar + +s 866 Tue Sep 12 20:08:48 EDT 2017 META-INF/MANIFEST.MF + 825 Tue Sep 12 20:08:48 EDT 2017 META-INF/ORACLE_C.SF + 7475 Tue Sep 12 20:08:48 EDT 2017 META-INF/ORACLE_C.RSA + 0 Tue Sep 12 20:07:54 EDT 2017 META-INF/ + 0 Tue Sep 12 20:07:16 EDT 2017 components/ + 0 Tue Sep 12 20:07:16 EDT 2017 components/images/ +sm 523 Tue Sep 12 20:07:16 EDT 2017 components/ButtonDemo$1.class +sm 3440 Tue Sep 12 20:07:16 EDT 2017 components/ButtonDemo.class +sm 2346 Tue Sep 12 20:07:16 EDT 2017 components/ButtonDemo.jnlp +sm 172 Tue Sep 12 20:07:16 EDT 2017 components/images/left.gif +sm 235 Tue Sep 12 20:07:16 EDT 2017 components/images/middle.gif +sm 172 Tue Sep 12 20:07:16 EDT 2017 components/images/right.gif + + s = signature was verified + m = entry is listed in manifest + k = at least one certificate was found in keystore + +- Signed by "CN="Oracle America, Inc.", OU=Software Engineering, O="Oracle America, Inc.", L=Redwood City, ST=California, C=US" + Digest algorithm: SHA-256 + Signature algorithm: SHA256withRSA, 2048-bit key + Timestamped by "CN=Symantec Time Stamping Services Signer - G4, O=Symantec Corporation, C=US" on Tue Sep 12 20:08:49 UTC 2017 + Timestamp digest algorithm: SHA-1 + Timestamp signature algorithm: SHA1withRSA, 2048-bit key + +jar verified. + +The signer certificate expired on 2018-02-01. However, the JAR will be valid until the timestamp expires on 2020-12-29. +``` + +## Example of Verification with Certificate Information + +If you specify the `-certs` option with the `-verify` and `-verbose` options, +then the output includes certificate information for each signer of the JAR +file. The information includes the certificate type, the signer distinguished +name information (when it is an X.509 certificate), and in parentheses, the +keystore alias for the signer when the public key certificate in the JAR file +matches the one in a keystore entry, for example: + +``` +jarsigner -keystore $JAVA_HOME/lib/security/cacerts -verify -verbose -certs ButtonDemo.jar + +s k 866 Tue Sep 12 20:08:48 EDT 2017 META-INF/MANIFEST.MF + + >>> Signer + X.509, CN="Oracle America, Inc.", OU=Software Engineering, O="Oracle America, Inc.", L=Redwood City, ST=California, C=US + [certificate is valid from 2017-01-30, 7:00 PM to 2018-02-01, 6:59 PM] + X.509, CN=Symantec Class 3 SHA256 Code Signing CA, OU=Symantec Trust Network, O=Symantec Corporation, C=US + [certificate is valid from 2013-12-09, 7:00 PM to 2023-12-09, 6:59 PM] + X.509, CN=VeriSign Class 3 Public Primary Certification Authority - G5, OU="(c) 2006 VeriSign, Inc. - For authorized use only", OU=VeriSign Trust Network, O="VeriSign, Inc.", C=US (verisignclass3g5ca [jdk]) + [trusted certificate] + >>> TSA + X.509, CN=Symantec Time Stamping Services Signer - G4, O=Symantec Corporation, C=US + [certificate is valid from 2012-10-17, 8:00 PM to 2020-12-29, 6:59 PM] + X.509, CN=Symantec Time Stamping Services CA - G2, O=Symantec Corporation, C=US + [certificate is valid from 2012-12-20, 7:00 PM to 2020-12-30, 6:59 PM] + + 825 Tue Sep 12 20:08:48 EDT 2017 META-INF/ORACLE_C.SF + 7475 Tue Sep 12 20:08:48 EDT 2017 META-INF/ORACLE_C.RSA + 0 Tue Sep 12 20:07:54 EDT 2017 META-INF/ + 0 Tue Sep 12 20:07:16 EDT 2017 components/ + 0 Tue Sep 12 20:07:16 EDT 2017 components/images/ +smk 523 Tue Sep 12 20:07:16 EDT 2017 components/ButtonDemo$1.class + + [entry was signed on 2017-09-12, 4:08 PM] + >>> Signer + X.509, CN="Oracle America, Inc.", OU=Software Engineering, O="Oracle America, Inc.", L=Redwood City, ST=California, C=US + [certificate is valid from 2017-01-30, 7:00 PM to 2018-02-01, 6:59 PM] + X.509, CN=Symantec Class 3 SHA256 Code Signing CA, OU=Symantec Trust Network, O=Symantec Corporation, C=US + [certificate is valid from 2013-12-09, 7:00 PM to 2023-12-09, 6:59 PM] + X.509, CN=VeriSign Class 3 Public Primary Certification Authority - G5, OU="(c) 2006 VeriSign, Inc. - For authorized use only", OU=VeriSign Trust Network, O="VeriSign, Inc.", C=US (verisignclass3g5ca [jdk]) + [trusted certificate] + >>> TSA + X.509, CN=Symantec Time Stamping Services Signer - G4, O=Symantec Corporation, C=US + [certificate is valid from 2012-10-17, 8:00 PM to 2020-12-29, 6:59 PM] + X.509, CN=Symantec Time Stamping Services CA - G2, O=Symantec Corporation, C=US + [certificate is valid from 2012-12-20, 7:00 PM to 2020-12-30, 6:59 PM] + +smk 3440 Tue Sep 12 20:07:16 EDT 2017 components/ButtonDemo.class +... +smk 2346 Tue Sep 12 20:07:16 EDT 2017 components/ButtonDemo.jnlp +... +smk 172 Tue Sep 12 20:07:16 EDT 2017 components/images/left.gif +... +smk 235 Tue Sep 12 20:07:16 EDT 2017 components/images/middle.gif +... +smk 172 Tue Sep 12 20:07:16 EDT 2017 components/images/right.gif +... + + s = signature was verified + m = entry is listed in manifest + k = at least one certificate was found in keystore + +- Signed by "CN="Oracle America, Inc.", OU=Software Engineering, O="Oracle America, Inc.", L=Redwood City, ST=California, C=US" + Digest algorithm: SHA-256 + Signature algorithm: SHA256withRSA, 2048-bit key + Timestamped by "CN=Symantec Time Stamping Services Signer - G4, O=Symantec Corporation, C=US" on Tue Sep 12 20:08:49 UTC 2017 + Timestamp digest algorithm: SHA-1 + Timestamp signature algorithm: SHA1withRSA, 2048-bit key + +jar verified. + +The signer certificate expired on 2018-02-01. However, the JAR will be valid until the timestamp expires on 2020-12-29. +``` + +If the certificate for a signer isn't an X.509 certificate, then there is no +distinguished name information. In that case, just the certificate type and the +alias are shown. For example, if the certificate is a PGP certificate, and the +alias is `bob`, then you would get: `PGP, (bob)`. diff --git a/src/jdk.javadoc/share/man/javadoc.1 b/src/jdk.javadoc/share/man/javadoc.1 deleted file mode 100644 index 4e256a7ce38..00000000000 --- a/src/jdk.javadoc/share/man/javadoc.1 +++ /dev/null @@ -1,1526 +0,0 @@ -.\" Copyright (c) 1994, 2024, Oracle and/or its affiliates. All rights reserved. -.\" DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -.\" -.\" This code is free software; you can redistribute it and/or modify it -.\" under the terms of the GNU General Public License version 2 only, as -.\" published by the Free Software Foundation. -.\" -.\" This code is distributed in the hope that it will be useful, but WITHOUT -.\" ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -.\" FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -.\" version 2 for more details (a copy is included in the LICENSE file that -.\" accompanied this code). -.\" -.\" You should have received a copy of the GNU General Public License version -.\" 2 along with this work; if not, write to the Free Software Foundation, -.\" Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -.\" -.\" Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -.\" or visit www.oracle.com if you need additional information or have any -.\" questions. -.\" -.\" Automatically generated by Pandoc 2.19.2 -.\" -.\" Define V font for inline verbatim, using C font in formats -.\" that render this, and otherwise B font. -.ie "\f[CB]x\f[R]"x" \{\ -. ftr V B -. ftr VI BI -. ftr VB B -. ftr VBI BI -.\} -.el \{\ -. ftr V CR -. ftr VI CI -. ftr VB CB -. ftr VBI CBI -.\} -.TH "JAVADOC" "1" "2025" "JDK 24-ea" "JDK Commands" -.hy -.SH NAME -.PP -javadoc - generate HTML pages of API documentation from Java source -files -.SH SYNOPSIS -.PP -\f[V]javadoc\f[R] [\f[I]options\f[R]] [\f[I]packagenames\f[R]] -[\f[I]sourcefiles\f[R]] [\f[V]\[at]\f[R]\f[I]files\f[R]] -.TP -\f[I]options\f[R] -Specifies command-line options, separated by spaces. -See \f[B]Standard \f[VB]javadoc\f[B] Options\f[R], \f[B]Extra -\f[VB]javadoc\f[B] Options\f[R], \f[B]Standard Options for the Standard -Doclet\f[R], and \f[B]Extra Options for the Standard Doclet\f[R]. -.TP -\f[I]packagenames\f[R] -Specifies names of packages that you want to document, separated by -spaces, for example \f[V]java.lang java.lang.reflect java.awt\f[R]. -If you want to also document the subpackages, then use the -\f[V]-subpackages\f[R] option to specify the packages. -.RS -.PP -By default, \f[V]javadoc\f[R] looks for the specified packages in the -current directory and subdirectories. -Use the \f[V]-sourcepath\f[R] option to specify the list of directories -where to look for packages. -.RE -.TP -\f[I]sourcefiles\f[R] -Specifies names of Java source files that you want to document, -separated by spaces, for example -\f[V]Class.java Object.java Button.java\f[R]. -By default, \f[V]javadoc\f[R] looks for the specified classes in the -current directory. -However, you can specify the full path to the class file and use -wildcard characters, for example -\f[V]/home/src/java/awt/Graphics*.java\f[R]. -You can also specify the path relative to the current directory. -.TP -\f[V]\[at]\f[R]\f[I]files\f[R] -Specifies names of files that contain a list of \f[V]javadoc\f[R] tool -options, package names, and source file names in any order. -.SH DESCRIPTION -.PP -The \f[V]javadoc\f[R] tool parses the declarations and documentation -comments in a set of Java source files and produces corresponding HTML -pages that describe (by default) the public and protected classes, -nested and implicitly declared classes (but not anonymous inner -classes), interfaces, constructors, methods, and fields. -You can use the \f[V]javadoc\f[R] tool to generate the API documentation -or the implementation documentation for a set of source files. -.PP -You can run the \f[V]javadoc\f[R] tool on entire packages, individual -source files, or both. -When documenting entire packages, you can use the \f[V]-subpackages\f[R] -option either to recursively traverse a directory and its -subdirectories, or to pass in an explicit list of package names. -When you document individual source files, pass in a list of Java source -file names. -.SS Documentation Comments -.PP -The \f[V]javadoc\f[R] tool uses the documentation comment, if any, that -immediately precedes the beginning of the declaration, whether that is -an annotation, modifier, or the name being declared. -If there are multiple documentation comments before the declaration, -only the last one (closest to the declaration) will be used. -If there are any documentation comments after the beginning of the -declaration, they will be ignored. -To check for any extra or misplaced documentation comments, compile your -source code with the \f[V]javac\f[R] option \f[V]-Xlint\f[R], or more -specifically, \f[V]-Xlint:dangling-doc-comments\f[R]. -Within a source file, you may suppress any warnings generated by these -options by using -\f[V]\[at]SuppressWarnings(\[dq]dangling-doc-comments\[dq])\f[R] on a -suitable enclosing declaration. -.SS Conformance -.PP -The standard doclet does not validate the content of documentation -comments for conformance, nor does it attempt to correct any errors in -documentation comments. -Anyone running javadoc is advised to be aware of the problems that may -arise when generating non-conformant output or output containing -executable content, such as JavaScript. -The standard doclet does provide the \f[B]DocLint\f[R] feature to help -developers detect common problems in documentation comments; but it is -also recommended to check the generated output with any appropriate -conformance and other checking tools. -.PP -For more details on the conformance requirements for HTML5 documents, -see \f[B]Conformance requirements for authors\f[R] -[https://html.spec.whatwg.org/multipage/introduction.html#conformance-requirements-for-authors] -in the HTML5 Specification. -For more details on security issues related to web pages, see the -\f[B]Open Web Application Security Project (OWASP)\f[R] -[https://www.owasp.org] page. -.SH OPTIONS -.PP -\f[V]javadoc\f[R] supports command-line options for both the main -\f[V]javadoc\f[R] tool and the currently selected doclet. -The standard doclet is used if no other doclet is specified. -.PP -GNU-style options (that is, those beginning with \f[V]--\f[R]) can use -an equal sign (\f[V]=\f[R]) instead of whitespace characters to separate -the name of an option from its value. -.SS Standard \f[V]javadoc\f[R] Options -.PP -The following core \f[V]javadoc\f[R] options are equivalent to -corresponding \f[V]javac\f[R] options. -See \f[I]Standard Options\f[R] in \f[B]javac\f[R] for the detailed -descriptions of using these options: -.IP \[bu] 2 -\f[V]--add-modules\f[R] -.IP \[bu] 2 -\f[V]-bootclasspath\f[R] -.IP \[bu] 2 -\f[V]--class-path\f[R], \f[V]-classpath\f[R], or \f[V]-cp\f[R] -.IP \[bu] 2 -\f[V]--disable-line-doc-comments\f[R] -.IP \[bu] 2 -\f[V]--enable-preview\f[R] -.IP \[bu] 2 -\f[V]-encoding\f[R] -.IP \[bu] 2 -\f[V]-extdirs\f[R] -.IP \[bu] 2 -\f[V]--limit-modules\f[R] -.IP \[bu] 2 -\f[V]--module\f[R] -.IP \[bu] 2 -\f[V]--module-path\f[R] or \f[V]-p\f[R] -.IP \[bu] 2 -\f[V]--module-source-path\f[R] -.IP \[bu] 2 -\f[V]--release\f[R] -.IP \[bu] 2 -\f[V]--source\f[R] or \f[V]-source\f[R] -.IP \[bu] 2 -\f[V]--source-path\f[R] or \f[V]-sourcepath\f[R] -.IP \[bu] 2 -\f[V]--system\f[R] -.IP \[bu] 2 -\f[V]--upgrade-module-path\f[R] -.PP -The following options are the core \f[V]javadoc\f[R] options that are -not equivalent to a corresponding \f[V]javac\f[R] option: -.TP -\f[V]-breakiterator\f[R] -Computes the first sentence of the description in a documentation -comment using an instance of \f[V]java.text.BreakIterator\f[R] to detect -\f[I]sentence breaks\f[R]. -The rules that are used depend on the \f[B]current locale\f[R]: for -example, for English, a sentence break occurs after a period, question -mark, or exclamation point followed by a space when the next word starts -with a capital letter. -(This is meant to handle most abbreviations, such as \[dq]The serial no. -is valid\[dq], but will not handle \[dq]Mr. -Smith\[dq].) -.RS -.PP -The option is enabled by default if the language of the current locale -is not English. -If the language of the current locale is English, and the -\f[V]-breakiterator\f[R] option is not given, a simple default algorithm -is used, which just looks for a period followed by a space. -.PP -In a traditional \f[V]/**...*/\f[R] comment, the search for the end of -the first sentence is terminated by an HTML block tag, such as -\f[V]

\f[R], \f[V]

\f[R], or the tag for a heading.
-.PP
-In a Markdown \f[V]///\f[R] comment, the search for the end of the first
-sentence skips over any characters enclosed in code spans and links, and
-is terminated by the end of the initial block, as indicated by a blank
-line or the beginning of the next block, such as a list, thematic break,
-or an HTML block.
-.PP
-The first sentence of the description in a documentation comment is used
-in summary tables, index pages, and other situations where a short
-summary is required.
-For more explicit control in any individual documentation comment,
-enclose the contents of the first sentence in a
-\f[V]{\[at]summary ...}\f[R] tag, or when applicable, in a
-\f[V]{\[at]return ...}\f[R] tag.
-.RE
-.TP
-\f[V]-doclet\f[R] \f[I]class\f[R]
-Generates output by using an alternate doclet.
-Use the fully qualified name.
-This doclet defines the content and formats the output.
-If the \f[V]-doclet\f[R] option isn\[aq]t used, then the
-\f[V]javadoc\f[R] tool uses the standard doclet for generating the
-default HTML format.
-This class must implement the \f[V]jdk.javadoc.doclet.Doclet\f[R]
-interface.
-The path to this class is defined by the \f[V]-docletpath\f[R] option.
-.TP
-\f[V]-docletpath\f[R] \f[I]path\f[R]
-Specifies where to find doclet class files (specified with the
-\f[V]-doclet\f[R] option) and any JAR files it depends on.
-If the starting class file is in a JAR file, then this option specifies
-the path to that JAR file.
-You can specify an absolute path or a path relative to the current
-directory.
-If \f[V]path\f[R] contains multiple paths or JAR files, then they should
-be separated with a colon (\f[V]:\f[R]) on Linux and macOS, and a
-semicolon (\f[V];\f[R]) on Windows.
-This option isn\[aq]t necessary when the \f[V]doclet\f[R] starting class
-is already in the search path.
-.TP
-\f[V]-exclude\f[R] \f[I]pkglist\f[R]
-Unconditionally, excludes the specified packages and their subpackages
-from the list formed by \f[V]-subpackages\f[R].
-It excludes those packages even when they would otherwise be included by
-some earlier or later \f[V]-subpackages\f[R] option.
-.RS
-.PP
-The following example would include \f[V]java.io\f[R],
-\f[V]java.util\f[R], and \f[V]java.math\f[R] (among others), but would
-exclude packages rooted at \f[V]java.net\f[R] and \f[V]java.lang\f[R].
-Notice that these examples exclude \f[V]java.lang.ref\f[R], which is a
-subpackage of \f[V]java.lang\f[R].
-Arguments are separated by colons on all operating systems.
-.IP \[bu] 2
-\f[B]Linux and macOS:\f[R]
-.RS 2
-.IP
-.nf
-\f[CB]
-javadoc -sourcepath /home/user/src -subpackages java -exclude java.net:java.lang
-\f[R]
-.fi
-.RE
-.IP \[bu] 2
-\f[B]Windows:\f[R]
-.RS 2
-.IP
-.nf
-\f[CB]
-javadoc -sourcepath \[rs]user\[rs]src -subpackages java -exclude java.net:java.lang
-\f[R]
-.fi
-.RE
-.RE
-.TP
-\f[V]--expand-requires\f[R] (\f[V]transitive\f[R]|\f[V]all\f[R])
-Instructs the javadoc tool to expand the set of modules to be
-documented.
-By default, only the modules given explicitly on the command line are
-documented.
-Supports the following values:
-.RS
-.IP \[bu] 2
-\f[V]transitive\f[R]: additionally includes all the required transitive
-dependencies of those modules.
-.IP \[bu] 2
-\f[V]all\f[R]: includes all dependencies.
-.RE
-.TP
-\f[V]--help\f[R], \f[V]-help\f[R], \f[V]-h\f[R], or \f[V]-?\f[R]
-Prints a synopsis of the standard options.
-.TP
-\f[V]--help-extra\f[R] or \f[V]-X\f[R]
-Prints a synopsis of the set of extra options.
-.TP
-\f[V]-J\f[R]\f[I]flag\f[R]
-Passes \f[I]flag\f[R] directly to the Java Runtime Environment (JRE)
-that runs the \f[V]javadoc\f[R] tool.
-For example, if you must ensure that the system sets aside 32 MB of
-memory in which to process the generated documentation, then you would
-call the \f[V]-Xmx\f[R] option as follows:
-\f[V]javadoc -J-Xmx32m -J-Xms32m com.mypackage\f[R].
-Be aware that \f[V]-Xms\f[R] is optional because it only sets the size
-of initial memory, which is useful when you know the minimum amount of
-memory required.
-.RS
-.PP
-There is no space between the \f[V]J\f[R] and the \f[V]flag\f[R].
-.PP
-Use the \f[V]-version\f[R] option to report the version of the JRE being
-used to run the \f[V]javadoc\f[R] tool.
-.IP
-.nf
-\f[CB]
-javadoc -J-version
-java version \[dq]17\[dq] 2021-09-14 LTS
-Java(TM) SE Runtime Environment (build 17+35-LTS-2724)
-Java HotSpot(TM) 64-Bit Server VM (build 17+35-LTS-2724, mixed mode, sharing)
-\f[R]
-.fi
-.RE
-.TP
-\f[V]-locale\f[R] \f[I]name\f[R]
-Specifies the locale that the \f[V]javadoc\f[R] tool uses when it
-generates documentation.
-The argument is the name of the locale, as described in
-\f[V]java.util.Locale\f[R] documentation, such as \f[V]en_US\f[R]
-(English, United States) or \f[V]en_US_WIN\f[R] (Windows variant).
-.RS
-.PP
-Specifying a locale causes the \f[V]javadoc\f[R] tool to choose the
-resource files of that locale for messages such as strings in the
-navigation bar, headings for lists and tables, help file contents,
-comments in the \f[V]stylesheet.css\f[R] file, and so on.
-It also specifies the sorting order for lists sorted alphabetically, and
-the sentence separator to determine the end of the first sentence.
-The \f[V]-locale\f[R] option doesn\[aq]t determine the locale of the
-documentation comment text specified in the source files of the
-documented classes.
-.RE
-.TP
-\f[V]-package\f[R]
-Shows only package, protected, and public classes and members.
-.TP
-\f[V]-private\f[R]
-Shows all classes and members.
-.TP
-\f[V]-protected\f[R]
-Shows only protected and public classes and members.
-This is the default.
-.TP
-\f[V]-public\f[R]
-Shows only the public classes and members.
-.TP
-\f[V]-quiet\f[R]
-Shuts off messages so that only the warnings and errors appear to make
-them easier to view.
-It also suppresses the \f[V]version\f[R] string.
-.TP
-\f[V]--show-members\f[R] \f[I]value\f[R]
-Specifies which members (fields, methods, or constructors) are
-documented, where \f[I]value\f[R] can be any of the following:
-.RS
-.IP \[bu] 2
-\f[V]public\f[R] --- shows only public members
-.IP \[bu] 2
-\f[V]protected\f[R] --- shows public and protected members; this is the
-default
-.IP \[bu] 2
-\f[V]package\f[R] --- shows public, protected, and package members
-.IP \[bu] 2
-\f[V]private\f[R] --- shows all members
-.RE
-.TP
-\f[V]--show-module-contents\f[R] \f[I]value\f[R]
-Specifies the documentation granularity of module declarations, where
-\f[I]value\f[R] can be \f[V]api\f[R] or \f[V]all\f[R].
-.TP
-\f[V]--show-packages\f[R] \f[I]value\f[R]
-Specifies which module packages are documented, where \f[I]value\f[R]
-can be \f[V]exported\f[R] or \f[V]all\f[R] packages.
-.TP
-\f[V]--show-types\f[R] \f[I]value\f[R]
-Specifies which types (classes, interfaces, etc.)
-are documented, where \f[I]value\f[R] can be any of the following:
-.RS
-.IP \[bu] 2
-\f[V]public\f[R] --- shows only public types
-.IP \[bu] 2
-\f[V]protected\f[R] --- shows public and protected types; this is the
-default
-.IP \[bu] 2
-\f[V]package\f[R] --- shows public, protected, and package types
-.IP \[bu] 2
-\f[V]private\f[R] --- shows all types
-.RE
-.TP
-\f[V]-subpackages\f[R] \f[I]subpkglist\f[R]
-Generates documentation from source files in the specified packages and
-recursively in their subpackages.
-This option is useful when adding new subpackages to the source code
-because they are automatically included.
-Each package argument is any top-level subpackage (such as
-\f[V]java\f[R]) or fully qualified package (such as
-\f[V]javax.swing\f[R]) that doesn\[aq]t need to contain source files.
-Arguments are separated by colons on all operating systems.
-Wild cards aren\[aq]t allowed.
-Use \f[V]-sourcepath\f[R] to specify where to find the packages.
-This option doesn\[aq]t process source files that are in the source tree
-but don\[aq]t belong to the packages.
-.RS
-.PP
-For example, the following commands generates documentation for packages
-named \f[V]java\f[R] and \f[V]javax.swing\f[R] and all of their
-subpackages.
-.IP \[bu] 2
-\f[B]Linux and macOS:\f[R]
-.RS 2
-.IP
-.nf
-\f[CB]
-javadoc -d docs -sourcepath /home/user/src -subpackages java:javax.swing
-\f[R]
-.fi
-.RE
-.IP \[bu] 2
-\f[B]Windows:\f[R]
-.RS 2
-.IP
-.nf
-\f[CB]
-javadoc -d docs -sourcepath \[rs]user\[rs]src -subpackages java:javax.swing
-\f[R]
-.fi
-.RE
-.RE
-.TP
-\f[V]-verbose\f[R]
-Provides more detailed messages while the \f[V]javadoc\f[R] tool runs.
-Without the \f[V]-verbose\f[R] option, messages appear for loading the
-source files, generating the documentation (one message per source
-file), and sorting.
-The \f[V]-verbose\f[R] option causes the printing of additional messages
-that specify the number of milliseconds to parse each Java source file.
-.TP
-\f[V]--version\f[R]
-Prints version information.
-.TP
-\f[V]-Werror\f[R]
-Reports an error if any warnings occur.
-.PP
-Note that if a Java source file contains an implicitly declared class,
-then that class and its public, protected, and package members will be
-documented regardless of the options such as \f[V]--show-types\f[R],
-\f[V]--show-members\f[R], \f[V]-private\f[R], \f[V]-protected\f[R],
-\f[V]-package\f[R], and \f[V]-public\f[R].
-If \f[V]--show-members\f[R] is specified with value \f[V]private\f[R] or
-if \f[V]-private\f[R] is used then all private members of an implicitly
-declared class will be documented too.
-.SS Extra \f[V]javadoc\f[R] Options
-.PP
-\f[I]Note:\f[R] The additional options for \f[V]javadoc\f[R] are subject
-to change without notice.
-.PP
-The following additional \f[V]javadoc\f[R] options are equivalent to
-corresponding \f[V]javac\f[R] options.
-See \f[I]Extra Options\f[R] in \f[B]javac\f[R] for the detailed
-descriptions of using these options:
-.IP \[bu] 2
-\f[V]--add-exports\f[R]
-.IP \[bu] 2
-\f[V]--add-reads\f[R]
-.IP \[bu] 2
-\f[V]--patch-module\f[R]
-.IP \[bu] 2
-\f[V]-Xmaxerrs\f[R]
-.IP \[bu] 2
-\f[V]-Xmaxwarns\f[R]
-.SS Standard Options for the Standard Doclet
-.PP
-The following options are provided by the standard doclet.
-.TP
-\f[V]--add-script\f[R] \f[I]file\f[R]
-Adds \f[I]file\f[R] as an additional JavaScript file to the generated
-documentation.
-This option can be used one or more times to specify additional script
-files.
-.RS
-.PP
-Command-line example:
-.RS
-.PP
-\f[V]javadoc --add-script first_script.js --add-script second_script.js pkg_foo\f[R]
-.RE
-.RE
-.TP
-\f[V]--add-stylesheet\f[R] \f[I]file\f[R]
-Adds \f[I]file\f[R] as an additional stylesheet file to the generated
-documentation.
-This option can be used one or more times to specify additional
-stylesheets included in the documentation.
-.RS
-.PP
-Command-line example:
-.IP
-.nf
-\f[CB]
-javadoc --add-stylesheet new_stylesheet_1.css --add-stylesheet new_stylesheet_2.css pkg_foo
-\f[R]
-.fi
-.RE
-.TP
-\f[V]--allow-script-in-comments\f[R]
-Allow JavaScript in documentation comments, and options whose value is
-\f[I]html-code\f[R].
-.TP
-\f[V]-author\f[R]
-Includes the text of any \f[V]author\f[R] tags in the generated
-documentation.
-.TP
-\f[V]-bottom\f[R] \f[I]html-code\f[R]
-Specifies the text to be placed at the bottom of each generated page.
-The text can contain HTML tags and white space, but when it does, the
-text must be enclosed in quotation marks.
-Use escape characters for any internal quotation marks within text.
-.TP
-\f[V]-charset\f[R] \f[I]name\f[R]
-Specifies the HTML character set for this document.
-The name should be a preferred MIME name as specified in the \f[B]IANA
-Registry, Character Sets\f[R]
-[http://www.iana.org/assignments/character-sets].
-.RS
-.PP
-For example:
-.IP
-.nf
-\f[CB]
-javadoc -charset \[dq]iso-8859-1\[dq] mypackage
-\f[R]
-.fi
-.PP
-This command inserts the following line, containing a
-\f[B]\f[VB]meta\f[B] element\f[R]
-[https://html.spec.whatwg.org/multipage/semantics.html#the-meta-element]
-in the head of every generated page:
-.IP
-.nf
-\f[CB]
-
-\f[R]
-.fi
-.RE
-.TP
-\f[V]-d\f[R] \f[I]directory\f[R]
-Specifies the destination directory where the \f[V]javadoc\f[R] tool
-saves the generated HTML files.
-If you omit the \f[V]-d\f[R] option, then the files are saved to the
-current directory.
-The \f[V]directory\f[R] value can be absolute or relative to the current
-working directory.
-The destination directory is automatically created when the
-\f[V]javadoc\f[R] tool runs.
-.RS
-.IP \[bu] 2
-\f[B]Linux and macOS:\f[R] For example, the following command generates
-the documentation for the package \f[V]com.mypackage\f[R] and saves the
-results in the \f[V]/user/doc/\f[R] directory:
-.RS 2
-.IP
-.nf
-\f[CB]
-javadoc -d /user/doc/ com.mypackage
-\f[R]
-.fi
-.RE
-.IP \[bu] 2
-\f[B]Windows:\f[R] For example, the following command generates the
-documentation for the package \f[V]com.mypackage\f[R] and saves the
-results in the \f[V]\[rs]user\[rs]doc\[rs]\f[R] directory:
-.RS 2
-.IP
-.nf
-\f[CB]
-javadoc -d \[rs]user\[rs]doc\[rs] com.mypackage
-\f[R]
-.fi
-.RE
-.RE
-.TP
-\f[V]-docencoding\f[R] \f[I]name\f[R]
-Specifies the encoding of the generated HTML files.
-The name should be a preferred MIME name as specified in the \f[B]IANA
-Registry, Character Sets\f[R]
-[http://www.iana.org/assignments/character-sets].
-.RS
-.PP
-Three options are available for use in a \f[V]javadoc\f[R] encoding
-command.
-The \f[V]-encoding\f[R] option is used for encoding the files read by
-the \f[V]javadoc\f[R] tool, while the \f[V]-docencoding\f[R] and
-\f[V]-charset\f[R] options are used for encoding the files written by
-the tool.
-Of the three available options, at most, only the input and an output
-encoding option are used in a single encoding command.
-If you specify both input and output encoding options in a command, they
-must be the same value.
-If you specify neither output option, it defaults to the input encoding.
-.PP
-For example:
-.IP
-.nf
-\f[CB]
-javadoc -docencoding \[dq]iso-8859-1\[dq] mypackage
-\f[R]
-.fi
-.RE
-.TP
-\f[V]-docfilessubdirs\f[R]
-Enables deep copying of \f[V]doc-files\f[R] directories.
-Subdirectories and all contents are recursively copied to the
-destination.
-For example, the directory \f[V]doc-files/example/images\f[R] and all of
-its contents are copied.
-Use the \f[B]\f[VB]-excludedocfilessubdir\f[B]\f[R] option to restrict
-the subdirectories to be copied.
-.TP
-\f[V]-doctitle\f[R] \f[I]html-code\f[R]
-Specifies the title to place near the top of the overview summary file.
-The text specified in the \f[V]title\f[R] tag is placed as a centered,
-level-one heading directly beneath the navigation bar.
-The \f[V]title\f[R] tag can contain HTML tags and white space, but when
-it does, you must enclose the title in quotation marks.
-Additional quotation marks within the \f[V]title\f[R] tag must be
-escaped.
-For example,
-\f[V]javadoc -doctitle \[dq]My Library
v1.0\[dq] com.mypackage\f[R]. -.TP -\f[V]-excludedocfilessubdir\f[R] \f[I]name1\f[R]\f[V],\f[R]\f[I]name2...\f[R] -Excludes any subdirectories with the given names when recursively -copying \f[V]doc-files\f[R] subdirectories. -See \f[B]\f[VB]-docfilessubdirs\f[B]\f[R]. -For historical reasons, \f[V]:\f[R] can be used anywhere in the argument -as a separator instead of \f[V],\f[R]. -.TP -\f[V]-footer\f[R] \f[I]html-code\f[R] -This option is no longer supported and reports a warning. -.TP -\f[V]-group\f[R] \f[I]name\f[R] \f[I]p1\f[R]\f[V],\f[R]\f[I]p2...\f[R] -Group the specified packages together in the Overview page. -For historical reasons, \f[V]:\f[R] can be used as a separator anywhere -in the argument instead of \f[V],\f[R]. -.TP -\f[V]-header\f[R] \f[I]html-code\f[R] -Specifies the header text to be placed at the top of each output file. -The header is placed to the right of the navigation bar. -The \f[V]header\f[R] can contain HTML tags and white space, but when it -does, the \f[V]header\f[R] must be enclosed in quotation marks. -Use escape characters for internal quotation marks within a header. -For example, -\f[V]javadoc -header \[dq]My Library
v1.0\[dq] com.mypackage\f[R]. -.TP -\f[V]-helpfile\f[R] \f[I]filename\f[R] -Specifies a file containing the text that will be displayed when the -\f[B]HELP\f[R] link in the navigation bar is clicked. -If this option is not given, the \f[V]javadoc\f[R] tool creates a -default page that will be used. -.TP -\f[V]-html5\f[R] -This option is a no-op and is just retained for backwards compatibility. -.TP -\f[V]--javafx\f[R] or \f[V]-javafx\f[R] -Enables JavaFX functionality. -This option is enabled by default if the JavaFX library classes are -detected on the module path. -.TP -\f[V]-keywords\f[R] -Adds HTML keyword \f[V]\f[R] tags to the generated file for each -class. -These tags can help search engines that look for \f[V]\f[R] tags -find the pages. -Most search engines that search the entire Internet don\[aq]t look at -\f[V]\f[R] tags, because pages can misuse them. -Search engines offered by companies that confine their searches to their -own website can benefit by looking at \f[V]\f[R] tags. -The \f[V]\f[R] tags include the fully qualified name of the class -and the unqualified names of the fields and methods. -Constructors aren\[aq]t included because they are identical to the class -name. -For example, the page for the class \f[V]String\f[R] includes these -keywords: -.RS -.IP -.nf -\f[CB] - - - - -\f[R] -.fi -.RE -.TP -\f[V]-link\f[R] \f[I]url\f[R] -Creates links to existing \f[V]javadoc\f[R] generated documentation of -externally referenced classes. -The \f[I]url\f[R] argument is the absolute or relative URL of the -directory that contains the external \f[V]javadoc\f[R] generated -documentation. -You can specify multiple \f[V]-link\f[R] options in a specified -\f[V]javadoc\f[R] tool run to link to multiple documents. -.RS -.PP -Either a \f[V]package-list\f[R] or an \f[V]element-list\f[R] file must -be in this \f[I]url\f[R] directory (otherwise, use the -\f[V]-linkoffline\f[R] option). -.PP -\f[I]Note:\f[R] The \f[V]package-list\f[R] and \f[V]element-list\f[R] -files are generated by the \f[V]javadoc\f[R] tool when generating the -API documentation and should not be modified by the user. -.PP -When you use the \f[V]javadoc\f[R] tool to document packages, it uses -the \f[V]package-list\f[R] file to determine the packages declared in an -API. -When you generate API documents for modules, the \f[V]javadoc\f[R] tool -uses the \f[V]element-list\f[R] file to determine the modules and -packages declared in an API. -.PP -The \f[V]javadoc\f[R] tool reads the names from the appropriate list -file and then links to the packages or modules at that URL. -.PP -When the \f[V]javadoc\f[R] tool runs, the \f[I]url\f[R] value is copied -into the \f[V]\f[R] links that are created. -Therefore, \f[I]url\f[R] must be the URL to the directory and not to a -file. -.PP -You can use an absolute link for \f[I]url\f[R] to enable your documents -to link to a document on any web site, or you can use a relative link to -link only to a relative location. -If you use a relative link, then the value you pass in should be the -relative path from the destination directory (specified with the -\f[V]-d\f[R] option) to the directory containing the packages being -linked to. -When you specify an absolute link, you usually use an HTTP link. -However, if you want to link to a file system that has no web server, -then you can use a file link. -Use a file link only when everyone who wants to access the generated -documentation shares the same file system. -In all cases, and on all operating systems, use a slash as the -separator, whether the URL is absolute or relative, and -\f[V]https:\f[R], \f[V]http:\f[R], or \f[V]file:\f[R] as specified in -the \f[B]RFC 1738: Uniform Resource Locators (URL)\f[R] -[https://www.rfc-editor.org/info/rfc1738]. -.IP -.nf -\f[CB] --link https://///.../ --link http://///.../ --link file://///.../ --link //.../ -\f[R] -.fi -.RE -.TP -\f[V]--link-modularity-mismatch\f[R] (\f[V]warn\f[R]|\f[V]info\f[R]) -Specifies whether external documentation with wrong modularity (e.g. -non-modular documentation for a modular library, or the reverse case) -should be reported as a warning (\f[V]warn\f[R]) or just a message -(\f[V]info\f[R]). -The default behavior is to report a warning. -.TP -\f[V]-linkoffline\f[R] \f[I]url1\f[R] \f[I]url2\f[R] -This option is a variation of the \f[V]-link\f[R] option. -They both create links to \f[V]javadoc\f[R] generated documentation for -externally referenced classes. -You can specify multiple \f[V]-linkoffline\f[R] options in a specified -\f[V]javadoc\f[R] tool run. -.RS -.PP -Use the \f[V]-linkoffline\f[R] option when: -.IP \[bu] 2 -Linking to a document on the web that the \f[V]javadoc\f[R] tool -can\[aq]t access through a web connection -.IP \[bu] 2 -The \f[V]package-list\f[R] or \f[V]element-list\f[R] file of the -external document either isn\[aq]t accessible or doesn\[aq]t exist at -the URL location, but does exist at a different location and can be -specified by either the \f[V]package-list\f[R] or \f[V]element-list\f[R] -file (typically local). -.PP -\f[I]Note:\f[R] The \f[V]package-list\f[R] and \f[V]element-list\f[R] -files are generated by the \f[V]javadoc\f[R] tool when generating the -API documentation and should not be modified by the user. -.PP -If \f[I]url1\f[R] is accessible only on the World Wide Web, then the -\f[V]-linkoffline\f[R] option removes the constraint that the -\f[V]javadoc\f[R] tool must have a web connection to generate -documentation. -.PP -Another use of the \f[V]-linkoffline\f[R] option is as a work-around to -update documents. -After you have run the \f[V]javadoc\f[R] tool on a full set of packages -or modules, you can run the \f[V]javadoc\f[R] tool again on a smaller -set of changed packages or modules, so that the updated files can be -inserted back into the original set. -.PP -For example, the \f[V]-linkoffline\f[R] option takes two arguments. -The first is for the string to be embedded in the \f[V]\f[R] -links, and the second tells the \f[V]javadoc\f[R] tool where to find -either the \f[V]package-list\f[R] or \f[V]element-list\f[R] file. -.PP -The \f[I]url1\f[R] or \f[I]url2\f[R] value is the absolute or relative -URL of the directory that contains the external \f[V]javadoc\f[R] -generated documentation that you want to link to. -When relative, the value should be the relative path from the -destination directory (specified with the \f[V]-d\f[R] option) to the -root of the packages being linked to. -See \f[I]url\f[R] in the \f[V]-link\f[R] option. -.RE -.TP -\f[V]--link-platform-properties\f[R] \f[I]url\f[R] -Specifies a properties file used to configure links to platform -documentation. -.RS -.PP -The \f[I]url\f[R] argument is expected to point to a properties file -containing one or more entries with the following format, where -\f[V]\f[R] is the platform version as passed to the -\f[V]--release\f[R] or \f[V]--source\f[R] option and \f[V]\f[R] is -the base URL of the corresponding platform API documentation: -.IP -.nf -\f[CB] -doclet.platform.docs.= -\f[R] -.fi -.PP -For instance, a properties file containing URLs for releases 15 to 17 -might contain the following lines: -.IP -.nf -\f[CB] -doclet.platform.docs.15=https://example.com/api/15/ -doclet.platform.docs.16=https://example.com/api/16/ -doclet.platform.docs.17=https://example.com/api/17/ -\f[R] -.fi -.PP -If the properties file does not contain an entry for a particular -release no platform links are generated. -.RE -.TP -\f[V]-linksource\f[R] -Creates an HTML version of each source file (with line numbers) and adds -links to them from the standard HTML documentation. -Links are created for classes, interfaces, constructors, methods, and -fields whose declarations are in a source file. -Otherwise, links aren\[aq]t created, such as for default constructors -and generated classes. -.RS -.PP -This option exposes all private implementation details in the included -source files, including private classes, private fields, and the bodies -of private methods, regardless of the \f[V]-public\f[R], -\f[V]-package\f[R], \f[V]-protected\f[R], and \f[V]-private\f[R] -options. -Unless you also use the \f[V]-private\f[R] option, not all private -classes or interfaces are accessible through links. -.PP -Each link appears on the name of the identifier in its declaration. -For example, the link to the source code of the \f[V]Button\f[R] class -would be on the word \f[V]Button\f[R]: -.IP -.nf -\f[CB] -public class Button extends Component implements Accessible -\f[R] -.fi -.PP -The link to the source code of the \f[V]getLabel\f[R] method in the -\f[V]Button\f[R] class is on the word \f[V]getLabel\f[R]: -.IP -.nf -\f[CB] -public String getLabel() -\f[R] -.fi -.RE -.TP -\f[V]--main-stylesheet\f[R] \f[I]file\f[R] or \f[V]-stylesheetfile\f[R] \f[I]file\f[R] -Specifies the path of an alternate stylesheet file that contains the -definitions for the CSS styles used in the generated documentation. -This option lets you override the default. -If you do not specify the option, the \f[V]javadoc\f[R] tool will create -and use a default stylesheet. -The file name can be any name and isn\[aq]t restricted to -\f[V]stylesheet.css\f[R]. -The \f[V]--main-stylesheet\f[R] option is the preferred form. -.RS -.PP -Command-line example: -.IP -.nf -\f[CB] -javadoc --main-stylesheet main_stylesheet.css pkg_foo -\f[R] -.fi -.RE -.TP -\f[V]-nocomment\f[R] -Suppresses the entire comment body, including the main description and -all tags, and generate only declarations. -This option lets you reuse source files that were originally intended -for a different purpose so that you can produce skeleton HTML -documentation during the early stages of a new project. -.TP -\f[V]-nodeprecated\f[R] -Prevents the generation of any deprecated API in the documentation. -This does what the \f[V]-nodeprecatedlist\f[R] option does, and it -doesn\[aq]t generate any deprecated API throughout the rest of the -documentation. -This is useful when writing code when you don\[aq]t want to be -distracted by the deprecated code. -.TP -\f[V]-nodeprecatedlist\f[R] -Prevents the generation of the file that contains the list of deprecated -APIs (\f[V]deprecated-list.html\f[R]) and the link in the navigation bar -to that page. -The \f[V]javadoc\f[R] tool continues to generate the deprecated API -throughout the rest of the document. -This is useful when your source code contains no deprecated APIs, and -you want to make the navigation bar cleaner. -.TP -\f[V]--no-fonts\f[R] -Prevents inclusion of font files in the generated documentation. -This can be useful if the documentation uses a custom stylesheet which -does not use the default fonts. -.TP -\f[V]-nohelp\f[R] -Omits the \f[B]HELP\f[R] link in the navigation bar at the top of each -generated page. -.TP -\f[V]-noindex\f[R] -Omits the index from the generated documents. -The index is produced by default. -.TP -\f[V]-nonavbar\f[R] -Prevents the generation of the navigation bar and header. -The \f[V]-nonavbar\f[R] option has no effect on the \f[V]-bottom\f[R] -option. -The \f[V]-nonavbar\f[R] option is useful when you are interested only in -the content and have no need for navigation, such as when you are -converting the files to PostScript or PDF for printing only. -.TP -\f[V]--no-platform-links\f[R] -Prevents the generation of links to platform documentation. -These links are generated by default. -.TP -\f[V]-noqualifier\f[R] \f[I]name1\f[R]\f[V],\f[R]\f[I]name2...\f[R] -Excludes the list of qualifiers from the output. -The package name is removed from places where class or interface names -appear. -For historical reasons, \f[V]:\f[R] can be used anywhere in the argument -as a separator instead of \f[V],\f[R]. -.RS -.PP -The following example omits all package qualifiers: -\f[V]-noqualifier all\f[R]. -.PP -The following example omits \f[V]java.lang\f[R] and \f[V]java.io\f[R] -package qualifiers: \f[V]-noqualifier java.lang:java.io\f[R]. -.PP -The following example omits package qualifiers starting with -\f[V]java\f[R] and \f[V]com.sun\f[R] subpackages, but not -\f[V]javax: -noqualifier java.*:com.sun.*\f[R]. -.PP -Where a package qualifier would appear due to the previous behavior, the -name can be suitably shortened. -This rule is in effect whether or not the \f[V]-noqualifier\f[R] option -is used. -.RE -.TP -\f[V]-nosince\f[R] -Omits from the generated documentation the \f[V]Since\f[R] sections -derived from any \f[V]since\f[R] tags. -.TP -\f[V]-notimestamp\f[R] -Suppresses the time stamp, which is hidden in an HTML comment in the -generated HTML near the top of each page. -The \f[V]-notimestamp\f[R] option is useful when you want to run the -\f[V]javadoc\f[R] tool on two source bases and compare them, because it -prevents time stamps from causing a difference (which would otherwise be -a difference on every page). -The time stamp includes the \f[V]javadoc\f[R] tool release number. -.TP -\f[V]-notree\f[R] -Omits the class and interface hierarchy pages from the generated -documents. -These are the pages you reach using the \f[B]TREE\f[R] link in the -navigation bar. -The hierarchy is produced by default. -.TP -\f[V]--override-methods\f[R] (\f[V]detail\f[R]|\f[V]summary\f[R]) -Documents overridden methods in the detail or summary sections. -The default is \f[V]detail\f[R]. -.TP -\f[V]-overview\f[R] \f[I]filename\f[R] -Specifies that the \f[V]javadoc\f[R] tool should retrieve the content -for the overview documentation from the file specified by -\f[I]filename\f[R] and place it on the Overview page -(\f[V]overview-summary.html\f[R]). -If the \f[I]filename\f[R] is a relative path, it is evaluated relative -to the current working directory. -.RS -.PP -The file may be an HTML file, with a filename ending in \f[V].html\f[R], -or a Markdown file, with a filename ending in \f[V].md\f[R]. -If the file is an HTML file, the content for the overview documentation -is taken from the \f[V]
\f[R] element in the file, if one is -present, or from the \f[V]\f[R] element is there is no -\f[V]
\f[R] element. -If the file is a Markdown file, the entire content of the file is used. -.PP -The title on the overview page is set by \f[V]-doctitle\f[R]. -.PP -\f[I]Note:\f[R] older versions of the \f[V]javadoc\f[R] tool assumed -that any use of this option was for an HTML file, and allowed any -extension for the \f[I]filename\f[R]. -.RE -.TP -\f[V]-serialwarn\f[R] -Reports compile-time warnings for missing \f[V]\[at]serial\f[R] tags. -By default, Javadoc reports no serial warnings. -Use this option to display the serial warnings, which helps to properly -document default serializable fields and \f[V]writeExternal\f[R] -methods. -.TP -\f[V]--since\f[R] \f[I]release\f[R](\f[V],\f[R]\f[I]release\f[R])* -Generates documentation for APIs that were added or newly deprecated in -the specified \f[I]release\f[R]s. -.RS -.PP -If the \f[V]\[at]since\f[R] tag in the \f[V]javadoc\f[R] comment of an -element in the documented source code matches a \f[I]release\f[R] passed -as the option argument, information about the element and the release it -was added in is included in a \[dq]New API\[dq] page. -.PP -If the \[dq]Deprecated API\[dq] page is generated and the -\f[V]since\f[R] element of the \f[V]java.lang.Deprecated\f[R] annotation -of a documented element matches a \f[I]release\f[R] in the option -arguments, information about the release the element was deprecated in -is added to the \[dq]Deprecated API\[dq] page. -.PP -Releases are compared using case-sensitive string comparison. -.RE -.TP -\f[V]--since-label\f[R] \f[I]text\f[R] -Specifies the \f[I]text\f[R] to use in the heading of the \[dq]New -API\[dq] page. -This may contain information about the releases covered in the page, -e.g. -\[dq]New API in release 2.0\[dq], or \[dq]New API since release 1\[dq]. -.TP -\f[V]--snippet-path\f[R] \f[I]snippetpathlist\f[R] -Specifies the search paths for finding files for external snippets. -The \f[I]snippetpathlist\f[R] can contain multiple paths by separating -them with the platform path separator (\f[V];\f[R] on Windows; -\f[V]:\f[R] on other platforms.) -The standard doclet first searches the \f[V]snippet-files\f[R] -subdirectory in the package containing the snippet, and then searches -all the directories in the given list. -.TP -\f[V]-sourcetab\f[R] \f[I]tab-length\f[R] -Specifies the number of spaces each tab uses in the source. -.TP -\f[V]--spec-base-url\f[R] \f[I]url\f[R] -Specifies the base URL for relative URLs in \f[V]\[at]spec\f[R] tags, to -be used when generating links to any external specifications. -It can either be an absolute URL, or a relative URL, in which case it is -evaluated relative to the base directory of the generated output files. -The default value is equivalent to \f[V]{\[at]docRoot}/../specs\f[R]. -.TP -\f[V]-splitindex\f[R] -Splits the index file into multiple files, alphabetically, one file per -letter, plus a file for any index entries that start with -non-alphabetical symbols. -.TP -\f[V]-tag\f[R] \f[I]name\f[R]:\f[I]locations\f[R]:\f[I]header\f[R] -Specifies a custom tag with a single argument. -For the \f[V]javadoc\f[R] tool to spell-check tag names, it is important -to include a \f[V]-tag\f[R] option for every custom tag that is present -in the source code, disabling (with \f[V]X\f[R]) those that aren\[aq]t -being output in the current run. -The colon (\f[V]:\f[R]) is always the separator. -To include a colon in the tag name, escape it with a backward slash -(\f[V]\[rs]\f[R]). -The \f[V]-tag\f[R] option outputs the tag heading, \f[I]header\f[R], in -bold, followed on the next line by the text from its single argument. -Similar to any block tag, the argument text can contain inline tags, -which are also interpreted. -The output is similar to standard one-argument tags, such as the -\f[V]\[at]return\f[R] and \f[V]\[at]author\f[R] tags. -Omitting a \f[I]header\f[R] value causes the \f[I]name\f[R] to be the -heading. -\f[I]locations\f[R] is a list of characters specifying the kinds of -declarations in which the tag may be used. -The following characters may be used, in either uppercase or lowercase: -.RS -.IP \[bu] 2 -\f[V]A\f[R]: all declarations -.IP \[bu] 2 -\f[V]C\f[R]: constructors -.IP \[bu] 2 -\f[V]F\f[R]: fields -.IP \[bu] 2 -\f[V]M\f[R]: methods -.IP \[bu] 2 -\f[V]O\f[R]: the overview page and other documentation files in -\f[V]doc-files\f[R] subdirectories -.IP \[bu] 2 -\f[V]P\f[R]: packages -.IP \[bu] 2 -\f[V]S\f[R]: modules -.IP \[bu] 2 -\f[V]T\f[R]: types (classes and interfaces) -.IP \[bu] 2 -\f[V]X\f[R]: nowhere: the tag is disabled, and will be ignored -.PP -The order in which tags are given on the command line will be used as -the order in which the tags appear in the generated output. -You can include standard tags in the order given on the command line by -using the \f[V]-tag\f[R] option with no \f[I]locations\f[R] or -\f[I]header\f[R]. -.RE -.TP -\f[V]-taglet\f[R] \f[I]class\f[R] -Specifies the fully qualified name of the taglet used in generating the -documentation for that tag. -Use the fully qualified name for the \f[I]class\f[R] value. -This taglet also defines the number of text arguments that the custom -tag has. -The taglet accepts those arguments, processes them, and generates the -output. -.RS -.PP -Taglets are useful for block or inline tags. -They can have any number of arguments and implement custom behavior, -such as making text bold, formatting bullets, writing out the text to a -file, or starting other processes. -Taglets can only determine where a tag should appear and in what form. -All other decisions are made by the doclet. -A taglet can\[aq]t do things such as remove a class name from the list -of included classes. -However, it can execute side effects, such as printing the tag\[aq]s -text to a file or triggering another process. -Use the \f[V]-tagletpath\f[R] option to specify the path to the taglet. -The following example inserts the To Do taglet after Parameters and -ahead of Throws in the generated pages. -.IP -.nf -\f[CB] --taglet com.sun.tools.doclets.ToDoTaglet --tagletpath /home/taglets --tag return --tag param --tag todo --tag throws --tag see -\f[R] -.fi -.PP -Alternately, you can use the \f[V]-taglet\f[R] option in place of its -\f[V]-tag\f[R] option, but that might be difficult to read. -.RE -.TP -\f[V]-tagletpath\f[R] \f[I]tagletpathlist\f[R] -Specifies the search paths for finding taglet class files. -The \f[I]tagletpathlist\f[R] can contain multiple paths by separating -them with the platform path separator (\f[V];\f[R] on Windows; -\f[V]:\f[R] on other platforms.) -The \f[V]javadoc\f[R] tool searches all subdirectories of the specified -paths. -.TP -\f[V]-top\f[R] \f[I]html-code\f[R] -Specifies the text to be placed at the top of each output file. -.TP -\f[V]-use\f[R] -Creates class and package usage pages. -Includes one Use page for each documented class and package. -The page describes what packages, classes, methods, constructors, and -fields use any API of the specified class or package. -Given class C, things that use class C would include subclasses of C, -fields declared as C, methods that return C, and methods and -constructors with parameters of type C. -For example, you can look at the Use page for the \f[V]String\f[R] type. -Because the \f[V]getName\f[R] method in the \f[V]java.awt.Font\f[R] -class returns type \f[V]String\f[R], the \f[V]getName\f[R] method uses -\f[V]String\f[R] and so the \f[V]getName\f[R] method appears on the Use -page for \f[V]String\f[R]. -This documents only uses of the API, not the implementation. -When a method uses \f[V]String\f[R] in its implementation, but -doesn\[aq]t take a string as an argument or return a string, that -isn\[aq]t considered a use of \f[V]String\f[R]. -To access the generated Use page, go to the class or package and click -the \f[B]USE\f[R] link in the navigation bar. -.TP -\f[V]-version\f[R] -Includes the text of any \f[V]version\f[R] tags in the generated -documentation. -This text is omitted by default. -Note: To find out what version of the \f[V]javadoc\f[R] tool you are -using, use the \f[V]--version\f[R] option (with two hyphens). -.TP -\f[V]-windowtitle\f[R] \f[I]title\f[R] -Specifies the title to be placed in the HTML \f[V]\f[R] tag. -The text specified in the \f[V]title\f[R] tag appears in the window -title and in any browser bookmarks (favorite places) that someone -creates for this page. -This title should not contain any HTML tags because a browser will not -interpret them correctly. -Use escape characters on any internal quotation marks within the -\f[V]title\f[R] tag. -If the \f[V]-windowtitle\f[R] option is omitted, then the -\f[V]javadoc\f[R] tool uses the value of the \f[V]-doctitle\f[R] option -for the \f[V]-windowtitle\f[R] option. -For example, -\f[V]javadoc -windowtitle \[dq]My Library\[dq] com.mypackage\f[R]. -.SS Extra Options for the Standard Doclet -.PP -The following are additional options provided by the standard doclet and -are subject to change without notice. -Additional options are less commonly used or are otherwise regarded as -advanced. -.TP -\f[V]--date\f[R] \f[I]date-and-time\f[R] -Specifies the value to be used to timestamp the generated pages, in -\f[B]ISO 8601\f[R] -[https://www.iso.org/iso-8601-date-and-time-format.html] format. -The specified value must be within 10 years of the current date and -time. -It is an error to specify both \f[V]-notimestamp\f[R] and -\f[V]--date\f[R]. -Using a specific value means the generated documentation can be part of -a \f[B]reproducible build\f[R] [https://reproducible-builds.org/]. -If the option is not given, the default value is the current date and -time. -For example: -.RS -.IP -.nf -\f[CB] -javadoc --date 2022-02-01T17:41:59-08:00 mypackage -\f[R] -.fi -.RE -.TP -\f[V]--legal-notices\f[R] (\f[V]default\f[R]|\f[V]none\f[R]|\f[I]directory\f[R]) -Specifies the location from which to copy legal files to the generated -documentation. -If the option is not specified or is used with the value -\f[V]default\f[R], the files are copied from the default location. -If the argument is used with value \f[V]none\f[R], no files are copied. -Every other argument is interpreted as directory from which to copy the -legal files. -.TP -\f[V]--no-frames\f[R] -This option is no longer supported and reports a warning. -.TP -\f[V]-Xdoclint\f[R] -Enables recommended checks for problems in documentation comments. -.RS -.PP -By default, the \f[V]-Xdoclint\f[R] option is enabled. -Disable it with the option \f[V]-Xdoclint:none\f[R]. -.PP -For more details, see \f[B]DocLint\f[R]. -.RE -.TP -\f[V]-Xdoclint:\f[R]\f[I]flag\f[R],\f[I]flag\f[R],... -Enables or disables specific checks for different kinds of issues in -documentation comments. -.RS -.PP -Each \f[I]flag\f[R] can be one of \f[V]all\f[R], \f[V]none\f[R], or -\f[V][-]\f[R]\f[I]group\f[R] where \f[I]group\f[R] has one of the -following values: \f[V]accessibility\f[R], \f[V]html\f[R], -\f[V]missing\f[R], \f[V]reference\f[R], \f[V]syntax\f[R]. -For more details on these values, see \f[B]DocLint Groups\f[R]. -.PP -When specifying two or more flags, you can either use a single -\f[V]-Xdoclint:...\f[R] option, listing all the desired flags, or you -can use multiple options giving one or more flag in each option. -For example, use either of the following commands to check for the HTML, -syntax, and accessibility issues in the file \f[V]MyFile.java\f[R]. -.IP -.nf -\f[CB] -javadoc -Xdoclint:html -Xdoclint:syntax -Xdoclint:accessibility MyFile.java -javadoc -Xdoclint:html,syntax,accessibility MyFile.java -\f[R] -.fi -.PP -The following examples illustrate how to change what DocLint reports: -.IP \[bu] 2 -\f[V]-Xdoclint:none\f[R] --- disables all checks -.IP \[bu] 2 -\f[V]-Xdoclint:\f[R]\f[I]group\f[R] --- enables \f[I]group\f[R] checks -.IP \[bu] 2 -\f[V]-Xdoclint:all\f[R] --- enables all groups of checks -.IP \[bu] 2 -\f[V]-Xdoclint:all,-\f[R]\f[I]group\f[R] --- enables all checks except -\f[I]group\f[R] checks -.PP -For more details, see \f[B]DocLint\f[R]. -.RE -.TP -\f[V]-Xdoclint/package:\f[R][\f[V]-\f[R]]\f[I]packages\f[R] -Enables or disables checks in specific packages. -\f[I]packages\f[R] is a comma separated list of package specifiers. -A package specifier is either a qualified name of a package or a package -name prefix followed by \f[V]*\f[R], which expands to all subpackages of -the given package. -Prefix the package specifier with \f[V]-\f[R] to disable checks for the -specified packages. -.RS -.PP -For more details, see \f[B]DocLint\f[R]. -.RE -.TP -\f[V]-Xdocrootparent\f[R] \f[I]url\f[R] -Replaces all \f[V]\[at]docRoot\f[R] items followed by \f[V]/..\f[R] in -documentation comments with \f[I]url\f[R]. -.SH DOCLINT -.PP -DocLint provides the ability to check for possible problems in -documentation comments. -Problems may be reported as warnings or errors, depending on their -severity. -For example, a missing comment may be bad style that deserves a warning, -but a link to an unknown Java declaration is more serious and deserves -an error. -Problems are organized into \f[B]groups\f[R], and options can be used to -enable or disable messages in one or more groups. -Within the source code, messages in one or more groups can be -\f[B]suppressed\f[R] by using \f[V]\[at]SuppressWarnings\f[R] -annotations. -.PP -When invoked from \f[V]javadoc\f[R], by default DocLint checks all -comments that are used in the generated documentation. -It thus relies on other command-line options to determine which -declarations, and which corresponding documentation comments will be -included. -\f[I]Note:\f[R] this may mean that even comments on some private members -of serializable classes will also be checked, if the members need to be -documented in the generated \f[V]Serialized Forms\f[R] page. -.PP -In contrast, when DocLint is invoked from \f[V]javac\f[R], DocLint -solely relies on the various \f[V]-Xdoclint...\f[R] options to determine -which documentation comments to check. -.PP -DocLint doesn\[aq]t attempt to fix invalid input, it just reports it. -.PP -\f[I]Note:\f[R] DocLint doesn\[aq]t guarantee the completeness of these -checks. -In particular, it isn\[aq]t a full HTML compliance checker. -The goal is to just report common errors in a convenient manner. -.SS Groups -.PP -The checks performed by DocLint are organized into groups. -The warnings and errors in each group can be enabled or disabled with -command-line options, or suppressed with \f[V]\[at]SuppressWarnings\f[R] -annotations. -.PP -The groups are as follows: -.IP \[bu] 2 -\f[V]accessibility\f[R] --- Checks for issues related to accessibility. -For example, no \f[V]alt\f[R] attribute specified in an \f[V]<img>\f[R] -element, or no caption or summary attributes specified in a -\f[V]<table>\f[R] element. -.RS 2 -.PP -Issues are reported as errors if a downstream validation tool might be -expected to report an error in the files generated by \f[V]javadoc\f[R]. -.PP -For reference, see the \f[B]Web Content Accessibility Guidelines\f[R] -[https://www.w3.org/WAI/standards-guidelines/wcag/]. -.RE -.IP \[bu] 2 -\f[V]html\f[R] --- Detects common high-level HTML issues. -For example, putting block elements inside inline elements, or not -closing elements that require an end tag. -.RS 2 -.PP -Issues are reported as errors if a downstream validation tool might be -expected to report an error in the files generated by \f[V]javadoc\f[R]. -.PP -For reference, see the \f[B]HTML Living Standard\f[R] -[https://html.spec.whatwg.org/multipage/]. -.RE -.IP \[bu] 2 -\f[V]missing\f[R] --- Checks for missing documentation comments or tags. -For example, a missing comment on a class declaration, or a missing -\f[V]\[at]param\f[R] or \f[V]\[at]return\f[R] tag in the comment for a -method declaration. -.RS 2 -.PP -Issues related to missing items are typically reported as warnings -because they are unlikely to be reported as errors by downstream -validation tools that may be used to check the output generated by -\f[V]javadoc\f[R]. -.RE -.IP \[bu] 2 -\f[V]reference\f[R] --- Checks for issues relating to the references to -Java API elements from documentation comment tags. -For example, the reference in \f[V]\[at]see\f[R] or -\f[V]{\[at]link ...}\f[R] cannot be found, or a bad name is given for -\f[V]\[at]param\f[R] or \f[V]\[at]throws\f[R]. -.RS 2 -.PP -Issues are typically reported as errors because while the issue may not -cause problems in the generated files, the author has likely made a -mistake that will lead to incorrect or unexpected documentation. -.RE -.IP \[bu] 2 -\f[V]syntax\f[R] --- Checks for low-level syntactic issues in -documentation comments. -For example, unescaped angle brackets (\f[V]<\f[R] and \f[V]>\f[R]) and -ampersands (\f[V]&\f[R]) and invalid documentation comment tags. -.RS 2 -.PP -Issues are typically reported as errors because the issues may lead to -incorrect or unexpected documentation. -.RE -.SS Suppressing Messages -.PP -DocLint checks for and recognizes two strings that may be present in the -arguments for an \f[V]\[at]SuppressWarnings\f[R] annotation. -.IP \[bu] 2 -\f[V]doclint\f[R] -.IP \[bu] 2 -\f[V]doclint:\f[R]\f[I]LIST\f[R] -.PP -where \f[I]LIST\f[R] is a comma-separated list of one or more of -\f[V]accessibility\f[R], \f[V]html\f[R], \f[V]missing\f[R], -\f[V]reference\f[R], \f[V]syntax\f[R]. -.PP -The names in \f[I]LIST\f[R] are the same \f[B]group\f[R] names supported -by the command-line \f[V]-Xdoclint\f[R] option for \f[V]javac\f[R] and -\f[V]javadoc\f[R]. -(This is the same convention honored by the \f[V]javac\f[R] -\f[V]-Xlint\f[R] option and the corresponding names supported by -\f[V]\[at]SuppressWarnings\f[R].) -.PP -The names in \f[I]LIST\f[R] can equivalently be specified in separate -arguments of the annotation. -For example, the following are equivalent: -.IP \[bu] 2 -\f[V]\[at]SuppressWarnings(\[dq]doclint:accessibility,missing\[dq])\f[R] -.IP \[bu] 2 -\f[V]\[at]SuppressWarnings(\[dq]doclint:accessibility\[dq], \[dq]doclint:missing\[dq])\f[R] -.PP -When DocLint detects an issue in a documentation comment, it checks for -the presence of \f[V]\[at]SuppressWarnings\f[R] on the associated -declaration and on all lexically enclosing declarations. -The issue will be ignored if any such annotation is found containing the -simple string \f[V]doclint\f[R] or the longer form -\f[V]doclint:LIST\f[R] where \f[I]LIST\f[R] contains the name of the -group for the issue. -.PP -\f[I]Note:\f[R] as with other uses of \f[V]\[at]SuppressWarnings\f[R], -using the annotation on a module or package declaration only affects -that declaration; it does not affect the contents of the module or -package in other source files. -.PP -All messages related to an issue are suppressed by the presence of an -appropriate \f[V]\[at]SuppressWarnings\f[R] annotation: this includes -errors as well as warnings. -.PP -\f[I]Note:\f[R] It is only possible to \f[I]suppress\f[R] messages. -If an annotation of \f[V]\[at]SuppressWarnings(\[dq]doclint\[dq])\f[R] -is given on a top-level declaration, all DocLint messages for that -declaration and any enclosed declarations will be suppressed; it is not -possible to selectively re-enable messages for issues in enclosed -declarations. -.SS Comparison with downstream validation tools -.PP -DocLint is a utility built into \f[V]javac\f[R] and \f[V]javadoc\f[R] -that checks the content of documentation comments, as found in source -files. -In contrast, downstream validation tools can be used to validate the -output generated from those documentation comments by \f[V]javadoc\f[R] -and the standard doclet. -.PP -Although there is some overlap in functionality, the two mechanisms are -different and each has its own strengths and weaknesses. -.IP \[bu] 2 -Downstream validation tools can check the end result of any generated -documentation, as it will be seen by the end user. -This includes content from all sources, including documentation -comments, the standard doclet itself, user-provided taglets, and content -supplied via command-line options. -Because such tools are analyzing complete HTML pages, they can do more -complete checks than can DocLint. -However, when a problem is found in the generated pages, it can be -harder to track down exactly where in the build pipeline the problem -needs to be fixed. -.IP \[bu] 2 -DocLint checks the content of documentation comments, in source files. -This makes it very easy to identify the exact position of any issues -that may be found. -DocLint can also detect some semantic errors in documentation comments -that downstream tools cannot detect, such as missing comments, using an -\f[V]\[at]return\f[R] tag in a method returning \f[V]void\f[R], or an -\f[V]\[at]param\f[R] tag describing a non-existent parameter. -But by its nature, DocLint cannot report on problems such as missing -links, or errors in user-provided custom taglets, or problems in the -standard doclet itself. -It also cannot reliably detect errors in documentation comments at the -boundaries between content in a documentation comment and content -generated by a custom taglet. diff --git a/src/jdk.javadoc/share/man/javadoc.md b/src/jdk.javadoc/share/man/javadoc.md new file mode 100644 index 00000000000..6a1a92e7d16 --- /dev/null +++ b/src/jdk.javadoc/share/man/javadoc.md @@ -0,0 +1,1214 @@ +--- +# Copyright (c) 1994, 2024, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# This code is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 only, as +# published by the Free Software Foundation. +# +# This code is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# version 2 for more details (a copy is included in the LICENSE file that +# accompanied this code). +# +# You should have received a copy of the GNU General Public License version +# 2 along with this work; if not, write to the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +# or visit www.oracle.com if you need additional information or have any +# questions. +# + +title: 'JAVADOC(1) JDK @@VERSION_SHORT@@ | JDK Commands' +date: @@COPYRIGHT_YEAR@@ +lang: en +--- + +## Name + +javadoc - generate HTML pages of API documentation from Java source files + +## Synopsis + +`javadoc` \[*options*\] \[*packagenames*\] \[*sourcefiles*\] \[`@`*files*\] + +*options* +: Specifies command-line options, separated by spaces. See [Standard `javadoc` + Options], [Extra `javadoc` Options], [Standard Options for the Standard Doclet], + and [Extra Options for the Standard Doclet]. + +*packagenames* +: Specifies names of packages that you want to document, separated by spaces, + for example `java.lang java.lang.reflect java.awt`. If you want to also + document the subpackages, then use the `-subpackages` option to specify the + packages. + + By default, `javadoc` looks for the specified packages in the current + directory and subdirectories. Use the `-sourcepath` option to specify the + list of directories where to look for packages. + +*sourcefiles* +: Specifies names of Java source files that you want to document, separated + by spaces, for example `Class.java Object.java Button.java`. By default, + `javadoc` looks for the specified classes in the current directory. + However, you can specify the full path to the class file and use wildcard + characters, for example `/home/src/java/awt/Graphics*.java`. You can also + specify the path relative to the current directory. + +`@`*files* +: Specifies names of files that contain a list of `javadoc` tool options, + package names, and source file names in any order. + +## Description + +The `javadoc` tool parses the declarations and documentation comments in a set +of Java source files and processes them using a pluggable back-end called a +[_doclet_][doclet]. + +The [_standard doclet_][standard-doclet] is the one that is used by default, +and can produce corresponding HTML pages that describe the public and protected +classes, nested and implicitly declared classes (but not anonymous inner classes), +interfaces, constructors, methods, and fields. The standard doclet interprets +the content of documentation comments according to the +[JavaDoc Documentation Comment Specification for the Standard Doclet][doc-comment-spec]. +Custom tags in documentation comments are supported by means of [taglets][taglet]. + +You can use the `javadoc` tool and the standard doclet to generate the API +documentation or the implementation documentation for a set of source files. + +You can run the `javadoc` tool on entire packages, individual source files, or +both. When documenting entire packages, you can use the `-subpackages` option +either to recursively traverse a directory and its subdirectories, or to pass +in an explicit list of package names. When you document individual source +files, pass in a list of Java source file names. + +### Documentation Comments + +The `javadoc` tool uses the documentation comment, if any, that immediately +precedes the beginning of the declaration, whether that is an annotation, +modifier, or the name being declared. If there are multiple documentation +comments before the declaration, only the last one (closest to the declaration) +will be used. If there are any documentation comments after the beginning of +the declaration, they will be ignored. To check for any extra or misplaced +documentation comments, compile your source code with the `javac` option +`-Xlint`, or more specifically, `-Xlint:dangling-doc-comments`. Within a +source file, you may suppress any warnings generated by these options +by using `@SuppressWarnings("dangling-doc-comments")` on a suitable enclosing +declaration. + +[doc-comment-spec]: ../javadoc/doc-comment-spec.html +[doclet]: ../../api/jdk.javadoc/jdk/javadoc/doclet/Doclet.html +[standard-doclet]: ../../api/jdk.javadoc/jdk/javadoc/doclet/StandardDoclet.html +[taglet]: ../../api/jdk.javadoc/jdk/javadoc/doclet/Taglet.html + +### Conformance + +The standard doclet does not validate the content of documentation comments for +conformance, nor does it attempt to correct any errors in documentation +comments. Anyone running javadoc is advised to be aware of the problems that +may arise when generating non-conformant output or output containing executable +content, such as JavaScript. The standard doclet does provide the [DocLint](#doclint) +feature to help developers detect common problems in documentation comments; +but it is also recommended to check the generated output with any appropriate +conformance and other checking tools. + +For more details on the conformance requirements for HTML5 documents, see +[Conformance requirements for authors]( +https://html.spec.whatwg.org/multipage/introduction.html#conformance-requirements-for-authors) +in the HTML5 Specification. For more details on security issues related to web +pages, see the [Open Web Application Security Project (OWASP)]( +https://www.owasp.org) page. + +## Options + +`javadoc` supports command-line options for both the main `javadoc` tool +and the currently selected doclet. The standard doclet is used if no other +doclet is specified. + +GNU-style options (that is, those beginning with `--`) can use an equal sign +(`=`) instead of whitespace characters to separate the name of an option from +its value. + +### Standard `javadoc` Options + +The following core `javadoc` options are equivalent to corresponding `javac` +options. See *Standard Options* in [javac](javac.html) for the detailed +descriptions of using these options: + +* <span id="option-add-modules">`--add-modules`</span> +* <span id="option-bootclasspath">`-bootclasspath`</span> +* <span id="option-class-path">`--class-path`, `-classpath`, or `-cp`</span> +* <span id="option-disable-line-doc-comments">`--disable-line-doc-comments`</span> +* <span id="option-enable-preview">`--enable-preview`</span> +* <span id="option-encoding">`-encoding`</span> +* <span id="option-extdirs">`-extdirs`</span> +* <span id="option-limit-modules">`--limit-modules`</span> +* <span id="option-module">`--module`</span> +* <span id="option-module-path">`--module-path` or `-p`</span> +* <span id="option-module-source-path">`--module-source-path`</span> +* <span id="option-release">`--release`</span> +* <span id="option-source">`--source` or `-source`</span> +* <span id="option-source-path">`--source-path` or `-sourcepath`</span> +* <span id="option-system">`--system`</span> +* <span id="option-upgrade-module-path">`--upgrade-module-path`</span> + +The following options are the core `javadoc` options that are not equivalent to +a corresponding `javac` option: + +<span id="option-breakiterator">`-breakiterator`</span> +: Computes the first sentence of the description in a documentation comment + using an instance of `java.text.BreakIterator` to detect _sentence breaks_. + The rules that are used depend on the [current locale](#option-locale): + for example, for English, a sentence break occurs after a period, question mark, + or exclamation point followed by a space when the next word starts with a + capital letter. (This is meant to handle most abbreviations, such as + "The serial no. is valid", but will not handle "Mr. Smith".) + + The option is enabled by default if the language of the current locale is + not English. If the language of the current locale is English, and the + `-breakiterator` option is not given, a simple default algorithm is used, + which just looks for a period followed by a space. + + In a traditional `/**...*/` comment, the search for the end of the first + sentence is terminated by an HTML block tag, such as `<p>`, `<pre>`, or + the tag for a heading. + + In a Markdown `///` comment, the search for the end of the first sentence + skips over any characters enclosed in code spans and links, and is + terminated by the end of the initial block, as indicated by a + blank line or the beginning of the next block, such as a list, thematic break, + or an HTML block. + + The first sentence of the description in a documentation comment is used in + summary tables, index pages, and other situations where a short summary is + required. For more explicit control in any individual documentation comment, + enclose the contents of the first sentence in a `{@summary ...}` tag, or + when applicable, in a `{@return ...}` tag. + +<span id="option-doclet">`-doclet` *class*</span> +: Generates output by using an alternate doclet. Use the fully qualified + name. This doclet defines the content and formats the output. If the + `-doclet` option isn't used, then the `javadoc` tool uses the standard + doclet for generating the default HTML format. This class must implement + the `jdk.javadoc.doclet.Doclet` interface. The path to this class is + defined by the `-docletpath` option. + +<span id="option-docletpath">`-docletpath` *path*</span> +: Specifies where to find doclet class files (specified with the `-doclet` + option) and any JAR files it depends on. If the starting class file is in a + JAR file, then this option specifies the path to that JAR file. You can + specify an absolute path or a path relative to the current directory. If + `path` contains multiple paths or JAR files, then they should be + separated with a colon (`:`) on Linux and macOS, and a semicolon (`;`) on + Windows. This option isn't necessary when the `doclet` starting class is + already in the search path. + +<span id="option-exclude">`-exclude` *pkglist*</span> +: Unconditionally, excludes the specified packages and their subpackages from + the list formed by `-subpackages`. It excludes those packages even when + they would otherwise be included by some earlier or later `-subpackages` + option. + + The following example would include `java.io`, `java.util`, and `java.math` + (among others), but would exclude packages rooted at `java.net` and + `java.lang`. Notice that these examples exclude `java.lang.ref`, which is a + subpackage of `java.lang`. Arguments are separated by colons on all + operating systems. + + - **Linux and macOS:** + + ``` + javadoc -sourcepath /home/user/src -subpackages java -exclude java.net:java.lang + ``` + + - **Windows:** + + ``` + javadoc -sourcepath \user\src -subpackages java -exclude java.net:java.lang + ``` + +<span id="option-expand-requires">`--expand-requires` (`transitive`|`all`)</span> +: Instructs the javadoc tool to expand the set of modules to be documented. + By default, only the modules given explicitly on the command line are + documented. Supports the following values: + + - `transitive`: additionally includes all the required transitive + dependencies of those modules. + + - `all`: includes all dependencies. + +<span id="option-help">`--help`, `-help`, `-h`, or `-?`</span> +: Prints a synopsis of the standard options. + +<span id="option-help-extra">`--help-extra` or `-X`</span> +: Prints a synopsis of the set of extra options. + +<span id="option-J">`-J`*flag*</span> +: Passes *flag* directly to the Java Runtime Environment (JRE) that runs the + `javadoc` tool. For example, if you must ensure that the system sets aside + 32 MB of memory in which to process the generated documentation, then you + would call the `-Xmx` option as follows: + `javadoc -J-Xmx32m -J-Xms32m com.mypackage`. Be aware that `-Xms` is + optional because it only sets the size of initial memory, which is useful + when you know the minimum amount of memory required. + + There is no space between the `J` and the `flag`. + + Use the `-version` option to report the version of the JRE being used to + run the `javadoc` tool. + + ``` + javadoc -J-version + java version "17" 2021-09-14 LTS + Java(TM) SE Runtime Environment (build 17+35-LTS-2724) + Java HotSpot(TM) 64-Bit Server VM (build 17+35-LTS-2724, mixed mode, sharing) + ``` + +<span id="option-locale">`-locale` *name*</span> +: Specifies the locale that the `javadoc` tool uses when it generates + documentation. The argument is the name of the locale, as described in + `java.util.Locale` documentation, such as `en_US` (English, United States) + or `en_US_WIN` (Windows variant). + + Specifying a locale causes the `javadoc` tool to choose the resource files + of that locale for messages such as strings in the navigation bar, headings + for lists and tables, help file contents, comments in the `stylesheet.css` + file, and so on. It also specifies the sorting order for lists sorted + alphabetically, and the sentence separator to determine the end of the + first sentence. The `-locale` option doesn't determine the locale of the + documentation comment text specified in the source files of the documented + classes. + +<span id="option-package">`-package`</span> +: Shows only package, protected, and public classes and members. + +<span id="option-private">`-private`</span> +: Shows all classes and members. + +<span id="option-protected">`-protected`</span> +: Shows only protected and public classes and members. This is the default. + +<span id="option-public">`-public`</span> +: Shows only the public classes and members. + +<span id="option-quiet">`-quiet`</span> +: Shuts off messages so that only the warnings and errors appear to make them + easier to view. It also suppresses the `version` string. + +<span id="option-show-members">`--show-members` *value*</span> +: Specifies which members (fields, methods, or constructors) are documented, + where *value* can be any of the following: + + * `public` --- shows only public members + * `protected` --- shows public and protected members; this is the default + * `package` --- shows public, protected, and package members + * `private` --- shows all members + +<span id="option-show-module-contents">`--show-module-contents` *value*</span> +: Specifies the documentation granularity of module declarations, where + *value* can be `api` or `all`. + +<span id="option-show-packages">`--show-packages` *value*</span> +: Specifies which module packages are documented, where *value* can be + `exported` or `all` packages. + +<span id="option-show-types">`--show-types` *value*</span> +: Specifies which types (classes, interfaces, etc.) are documented, where + *value* can be any of the following: + + * `public` --- shows only public types + * `protected` --- shows public and protected types; this is the default + * `package` --- shows public, protected, and package types + * `private` --- shows all types + +<span id="option-subpackages">`-subpackages` *subpkglist*</span> +: Generates documentation from source files in the specified packages and + recursively in their subpackages. This option is useful when adding new + subpackages to the source code because they are automatically included. + Each package argument is any top-level subpackage (such as `java`) or fully + qualified package (such as `javax.swing`) that doesn't need to contain + source files. Arguments are separated by colons on all operating systems. + Wild cards aren't allowed. Use `-sourcepath` to specify where to find the + packages. This option doesn't process source files that are in the source + tree but don't belong to the packages. + + For example, the following commands generates documentation for packages + named `java` and `javax.swing` and all of their subpackages. + + - **Linux and macOS:** + + ``` + javadoc -d docs -sourcepath /home/user/src -subpackages java:javax.swing + ``` + + - **Windows:** + + ``` + javadoc -d docs -sourcepath \user\src -subpackages java:javax.swing + ``` + +<span id="option-verbose">`-verbose`</span> +: Provides more detailed messages while the `javadoc` tool runs. Without the + `-verbose` option, messages appear for loading the source files, generating + the documentation (one message per source file), and sorting. The + `-verbose` option causes the printing of additional messages that specify + the number of milliseconds to parse each Java source file. + +<span id="option--version">`--version`</span> +: Prints version information. + +<span id="option-Werror">`-Werror`</span> +: Reports an error if any warnings occur. + +Note that if a Java source file contains an implicitly declared class, then +that class and its public, protected, and package members will be documented +regardless of the options such as `--show-types`, `--show-members`, `-private`, +`-protected`, `-package`, and `-public`. If `--show-members` is specified with +value `private` or if `-private` is used then all private members of an +implicitly declared class will be documented too. + +### Extra `javadoc` Options + +_Note:_ The additional options for `javadoc` are subject to change without +notice. + +The following additional `javadoc` options are equivalent to corresponding +`javac` options. See *Extra Options* in [javac](javac.html) for the detailed +descriptions of using these options: + +* <span id="option-add-exports">`--add-exports`</span> +* <span id="option-add-reads">`--add-reads`</span> +* <span id="option-patch-module">`--patch-module`</span> +* <span id="option-Xmaxerrs">`-Xmaxerrs`</span> +* <span id="option-Xmaxwarns">`-Xmaxwarns`</span> + +### Standard Options for the Standard Doclet + +The following options are provided by the standard doclet. + +<span id="option-add-script">`--add-script` *file*</span> +: Adds *file* as an additional JavaScript file to the generated documentation. + This option can be used one or more times to specify additional script + files. + + Command-line example: + + > `javadoc --add-script first_script.js --add-script + second_script.js pkg_foo` + +<span id="option-add-stylesheet">`--add-stylesheet` *file*</span> +: Adds *file* as an additional stylesheet file to the generated documentation. + This option can be used one or more times to specify additional stylesheets + included in the documentation. + + Command-line example: + + ``` + javadoc --add-stylesheet new_stylesheet_1.css --add-stylesheet new_stylesheet_2.css pkg_foo + ``` + +<span id="option-allow-script-in-comments">`--allow-script-in-comments`</span> +: Allow JavaScript in documentation comments, and options whose value is + _html-code_. + +<span id="option-author">`-author`</span> +: Includes the text of any `author` tags in the generated documentation. + +<span id="option-bottom">`-bottom` *html-code*</span> +: Specifies the text to be placed at the bottom of each generated page. + The text can contain HTML tags and white space, but when it does, the text + must be enclosed in quotation marks. Use escape characters for any internal + quotation marks within text. + +<span id="option-charset">`-charset` *name*</span> +: Specifies the HTML character set for this document. The name should be a + preferred MIME name as specified in the [IANA Registry, Character Sets]( + http://www.iana.org/assignments/character-sets). + + For example: + + ``` + javadoc -charset "iso-8859-1" mypackage + ``` + + This command inserts the following line, containing a + [`meta` element](https://html.spec.whatwg.org/multipage/semantics.html#the-meta-element) + in the head of every generated page: + + ``` + <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"> + ``` + +<span id="option-d">`-d` *directory*</span> +: Specifies the destination directory where the `javadoc` tool saves the + generated HTML files. If you omit the `-d` option, then the files are saved + to the current directory. The `directory` value can be absolute or relative + to the current working directory. The destination directory is + automatically created when the `javadoc` tool runs. + + - **Linux and macOS:** For example, the following command + generates the documentation for the package `com.mypackage` and saves + the results in the `/user/doc/` directory: + + ``` + javadoc -d /user/doc/ com.mypackage + ``` + + - **Windows:** For example, the following command generates the + documentation for the package `com.mypackage` and saves the results in + the `\user\doc\` directory: + + ``` + javadoc -d \user\doc\ com.mypackage + ``` + +<span id="option-docencoding">`-docencoding` *name*</span> +: Specifies the encoding of the generated HTML files. The name should be a + preferred MIME name as specified in the [IANA Registry, Character Sets]( + http://www.iana.org/assignments/character-sets). + + Three options are available for use in a `javadoc` encoding command. The + `-encoding` option is used for encoding the files read by the `javadoc` + tool, while the `-docencoding` and `-charset` options are used for encoding + the files written by the tool. Of the three available options, at most, + only the input and an output encoding option are used in a single encoding + command. If you specify both input and output encoding options in a + command, they must be the same value. If you specify neither output option, + it defaults to the input encoding. + + For example: + + ``` + javadoc -docencoding "iso-8859-1" mypackage + ``` + +<span id="option-docfilessubdirs">`-docfilessubdirs`</span> +: Enables deep copying of `doc-files` directories. Subdirectories and all + contents are recursively copied to the destination. For example, the + directory `doc-files/example/images` and all of its contents are copied. + Use the [`-excludedocfilessubdir`](#option-excludedocfilessubdir) option to + restrict the subdirectories to be copied. + +<span id="option-doctitle">`-doctitle` *html-code*</span> +: Specifies the title to place near the top of the overview summary file. The + text specified in the `title` tag is placed as a centered, level-one + heading directly beneath the navigation bar. The `title` tag can + contain HTML tags and white space, but when it does, you must enclose the + title in quotation marks. Additional quotation marks within the `title` tag + must be escaped. For example, + `javadoc -doctitle "<b>My Library</b><br>v1.0" com.mypackage`. + +<span id="option-excludedocfilessubdir">`-excludedocfilessubdir` *name1*`,`*name2...*</span> +: Excludes any subdirectories with the given names + when recursively copying `doc-files` subdirectories. + See [`-docfilessubdirs`](#option-docfilessubdirs). + For historical reasons, `:` can be used anywhere in the argument as a + separator instead of `,`. + +<span id="option-footer">`-footer` *html-code*</span> +: This option is no longer supported and reports a warning. + +<span id="option-group">`-group` *name* *p1*`,`*p2...*</span> +: Group the specified packages together in the Overview page. + For historical reasons, `:` can be used as a separator anywhere in the + argument instead of `,`. + +<span id="option-header">`-header` *html-code*</span> +: Specifies the header text to be placed at the top of each output file. The + header is placed to the right of the navigation bar. The `header` can + contain HTML tags and white space, but when it does, the `header` must be + enclosed in quotation marks. Use escape characters for internal quotation + marks within a header. For example, + `javadoc -header "<b>My Library</b><br>v1.0" com.mypackage`. + +<span id="option-helpfile">`-helpfile` *filename*</span> +: Specifies a file containing the text that will be displayed when the + **HELP** link in the navigation bar is clicked. If this option is not given, + the `javadoc` tool creates a default page that will be used. + +<span id="option-html5">`-html5`</span> +: This option is a no-op and is just retained for backwards compatibility. + +<span id="option-javafx">`--javafx` or `-javafx`</span> +: Enables JavaFX functionality. This option is enabled by default if the + JavaFX library classes are detected on the module path. + +<span id="option-keywords">`-keywords`</span> +: Adds HTML keyword `<meta>` tags to the generated file for each class. These + tags can help search engines that look for `<meta>` tags find the pages. + Most search engines that search the entire Internet don't look at `<meta>` + tags, because pages can misuse them. Search engines offered by companies + that confine their searches to their own website can benefit by looking at + `<meta>` tags. The `<meta>` tags include the fully qualified name of the + class and the unqualified names of the fields and methods. Constructors + aren't included because they are identical to the class name. For example, + the page for the class `String` includes these keywords: + + ``` + <meta name="keywords" content="java.lang.String class"> + <meta name="keywords" content="CASE_INSENSITIVE_ORDER"> + <meta name="keywords" content="length()"> + <meta name="keywords" content="isEmpty()"> + ``` + +<span id="option-link">`-link` *url*</span> +: Creates links to existing `javadoc` generated documentation of externally + referenced classes. The *url* argument is the absolute or relative URL of + the directory that contains the external `javadoc` generated documentation. + You can specify multiple `-link` options in a specified `javadoc` tool run + to link to multiple documents. + + Either a `package-list` or an `element-list` file must be in this *url* + directory (otherwise, use the `-linkoffline` option). + + _Note:_ The `package-list` and `element-list` files are generated by the + `javadoc` tool when generating the API documentation and should not be + modified by the user. + + When you use the `javadoc` tool to document packages, it uses the + `package-list` file to determine the packages declared in an API. When you + generate API documents for modules, the `javadoc` tool uses the + `element-list` file to determine the modules and packages declared in an + API. + + The `javadoc` tool reads the names from the appropriate list file and then + links to the packages or modules at that URL. + + When the `javadoc` tool runs, the *url* value is copied into the `<a href>` + links that are created. Therefore, *url* must be the URL to the directory + and not to a file. + + You can use an absolute link for *url* to enable your documents to link to + a document on any web site, or you can use a relative link to link only to + a relative location. If you use a relative link, then the value you pass in + should be the relative path from the destination directory (specified with + the `-d` option) to the directory containing the packages being linked to. + When you specify an absolute link, you usually use an HTTP link. However, + if you want to link to a file system that has no web server, then you can + use a file link. Use a file link only when everyone who wants to access the + generated documentation shares the same file system. In all cases, and on + all operating systems, use a slash as the separator, whether the URL is + absolute or relative, and `https:`, `http:`, or `file:` as specified in the + [RFC 1738: Uniform Resource Locators (URL)](https://www.rfc-editor.org/info/rfc1738). + + ``` + -link https://<host>/<directory>/<directory>/.../<name> + -link http://<host>/<directory>/<directory>/.../<name> + -link file://<host>/<directory>/<directory>/.../<name> + -link <directory>/<directory>/.../<name> + ``` + +<span id="option-link-modularity-mismatch">`--link-modularity-mismatch` (`warn`|`info`)</span> +: Specifies whether external documentation with wrong modularity (e.g. + non-modular documentation for a modular library, or the reverse case) + should be reported as a warning (`warn`) or just a message (`info`). + The default behavior is to report a warning. + +<span id="option-linkoffline">`-linkoffline` *url1* *url2*</span> +: This option is a variation of the `-link` option. They both create links to + `javadoc` generated documentation for externally referenced classes. You + can specify multiple `-linkoffline` options in a specified `javadoc` tool + run. + + Use the `-linkoffline` option when: + + - Linking to a document on the web that the `javadoc` tool can't access + through a web connection + + - The `package-list` or `element-list` file of the external document + either isn't accessible or doesn't exist at the URL location, but does + exist at a different location and can be specified by either the + `package-list` or `element-list` file (typically local). + + _Note:_ The `package-list` and `element-list` files are generated by the + `javadoc` tool when generating the API documentation and should not be + modified by the user. + + If *url1* is accessible only on the World Wide Web, then the `-linkoffline` + option removes the constraint that the `javadoc` tool must have a web + connection to generate documentation. + + Another use of the `-linkoffline` option is as a work-around to update + documents. After you have run the `javadoc` tool on a full set of packages + or modules, you can run the `javadoc` tool again on a smaller set of + changed packages or modules, so that the updated files can be inserted back + into the original set. + + For example, the `-linkoffline` option takes two arguments. The first is + for the string to be embedded in the `<a href>` links, and the second tells + the `javadoc` tool where to find either the `package-list` or + `element-list` file. + + The *url1* or *url2* value is the absolute or relative URL of the directory + that contains the external `javadoc` generated documentation that you want + to link to. When relative, the value should be the relative path from the + destination directory (specified with the `-d` option) to the root of the + packages being linked to. See *url* in the `-link` option. + +<span id="option-link-platform-properties">`--link-platform-properties` *url*</span> +: Specifies a properties file used to configure links to platform + documentation. + + The *url* argument is expected to point to a properties file containing + one or more entries with the following format, where `<version>` is the + platform version as passed to the `--release` or `--source` option and + `<url>` is the base URL of the corresponding platform API documentation: + + ``` + doclet.platform.docs.<version>=<url> + ``` + + For instance, a properties file containing URLs for releases 15 to 17 might + contain the following lines: + + ``` + doclet.platform.docs.15=https://example.com/api/15/ + doclet.platform.docs.16=https://example.com/api/16/ + doclet.platform.docs.17=https://example.com/api/17/ + ``` + + If the properties file does not contain an entry for a particular release + no platform links are generated. + +<span id="option-linksource">`-linksource`</span> +: Creates an HTML version of each source file (with line numbers) and adds + links to them from the standard HTML documentation. Links are created for + classes, interfaces, constructors, methods, and fields whose declarations + are in a source file. Otherwise, links aren't created, such as for default + constructors and generated classes. + + This option exposes all private implementation details in the included + source files, including private classes, private fields, and the bodies of + private methods, regardless of the `-public`, `-package`, `-protected`, and + `-private` options. Unless you also use the `-private` option, not all + private classes or interfaces are accessible through links. + + Each link appears on the name of the identifier in its declaration. For + example, the link to the source code of the `Button` class would be on the + word `Button`: + + ``` + public class Button extends Component implements Accessible + ``` + + The link to the source code of the `getLabel` method in the `Button` class + is on the word `getLabel`: + + ``` + public String getLabel() + ``` + +<span id="option-main-stylesheet">`--main-stylesheet` *file* or `-stylesheetfile` *file*</span> +: Specifies the path of an alternate stylesheet file that contains the + definitions for the CSS styles used in the generated documentation. This + option lets you override the default. If you do not specify the option, the + `javadoc` tool will create and use a default stylesheet. The file name can + be any name and isn't restricted to `stylesheet.css`. The + `--main-stylesheet` option is the preferred form. + + Command-line example: + + ``` + javadoc --main-stylesheet main_stylesheet.css pkg_foo + ``` + +<span id="option-nocomment">`-nocomment`</span> +: Suppresses the entire comment body, including the main description and all + tags, and generate only declarations. This option lets you reuse source + files that were originally intended for a different purpose so that you can + produce skeleton HTML documentation during the early stages of a new + project. + +<span id="option-nodeprecated">`-nodeprecated`</span> +: Prevents the generation of any deprecated API in the documentation. This + does what the `-nodeprecatedlist` option does, and it doesn't generate any + deprecated API throughout the rest of the documentation. This is useful + when writing code when you don't want to be distracted by the deprecated + code. + +<span id="option-nodeprecatedlist">`-nodeprecatedlist`</span> +: Prevents the generation of the file that contains the list of deprecated + APIs (`deprecated-list.html`) and the link in the navigation bar to that + page. The `javadoc` tool continues to generate the deprecated API + throughout the rest of the document. This is useful when your source code + contains no deprecated APIs, and you want to make the navigation bar + cleaner. + +<span id="option-no-fonts">`--no-fonts`</span> +: Prevents inclusion of font files in the generated documentation. This can + be useful if the documentation uses a custom stylesheet which does not + use the default fonts. + +<span id="option-nohelp">`-nohelp`</span> +: Omits the **HELP** link in the navigation bar at the top of each + generated page. + +<span id="option-noindex">`-noindex`</span> +: Omits the index from the generated documents. The index is produced by + default. + +<span id="option-nonavbar">`-nonavbar`</span> +: Prevents the generation of the navigation bar and header. The `-nonavbar` + option has no effect on the `-bottom` option. The `-nonavbar` option is + useful when you are interested only in the content and have no need for + navigation, such as when you are converting the files to PostScript or PDF + for printing only. + +<span id="option-no-platform-links">`--no-platform-links`</span> +: Prevents the generation of links to platform documentation. + These links are generated by default. + +<span id="option-noqualifier">`-noqualifier` *name1*`,`*name2...*</span> +: Excludes the list of qualifiers from the output. The package name is + removed from places where class or interface names appear. + For historical reasons, `:` can be used anywhere in the argument as a + separator instead of `,`. + + The following example omits all package qualifiers: `-noqualifier all`. + + The following example omits `java.lang` and `java.io` package qualifiers: + `-noqualifier java.lang:java.io`. + + The following example omits package qualifiers starting with `java` and + `com.sun` subpackages, but not `javax: -noqualifier java.*:com.sun.*`. + + Where a package qualifier would appear due to the previous behavior, the + name can be suitably shortened. This rule is in effect whether or not the + `-noqualifier` option is used. + +<span id="option-nosince">`-nosince`</span> +: Omits from the generated documentation the `Since` sections derived from + any `since` tags. + +<span id="option-notimestamp">`-notimestamp`</span> +: Suppresses the time stamp, which is hidden in an HTML comment in the + generated HTML near the top of each page. The `-notimestamp` option is + useful when you want to run the `javadoc` tool on two source bases and + compare them, because it prevents time stamps from causing a difference + (which would otherwise be a difference on every page). The time stamp + includes the `javadoc` tool release number. + +<span id="option-notree">`-notree`</span> +: Omits the class and interface hierarchy pages from the generated documents. + These are the pages you reach using the **TREE** link in the navigation bar. + The hierarchy is produced by default. + +<span id="option-override-methods">`--override-methods` (`detail`|`summary`)</span> +: Documents overridden methods in the detail or summary sections. + The default is `detail`. + +<span id="option-overview">`-overview` *filename*</span> +: Specifies that the `javadoc` tool should retrieve the content for the overview + documentation from the file specified by *filename* and place it on + the Overview page (`overview-summary.html`). If the *filename* is a relative + path, it is evaluated relative to the current working directory. + + The file may be an HTML file, with a filename ending in `.html`, + or a Markdown file, with a filename ending in `.md`. + If the file is an HTML file, the content for the overview documentation + is taken from the `<main>` element in the file, if one is present, or from + the `<body>` element is there is no `<main>` element. If the file is + a Markdown file, the entire content of the file is used. + + The title on the overview page is set by `-doctitle`. + + _Note:_ older versions of the `javadoc` tool assumed that any use of this + option was for an HTML file, and allowed any extension for the *filename*. + +<span id="option-serialwarn">`-serialwarn`</span> +: Reports compile-time warnings for missing `@serial` tags. By default, + Javadoc reports no serial warnings. Use this option to display the serial + warnings, which helps to properly document default serializable fields and + `writeExternal` methods. + +<span id="option-since">`--since` *release*(`,`*release*)*</span> +: Generates documentation for APIs that were added or newly deprecated in the + specified *release*s. + + If the `@since` tag in the `javadoc` comment of an element in the documented + source code matches a *release* passed as the option argument, information + about the element and the release it was added in is included in a "New API" + page. + + If the "Deprecated API" page is generated and the `since` element of the + `java.lang.Deprecated` annotation of a documented element matches a *release* + in the option arguments, information about the release the element was + deprecated in is added to the "Deprecated API" page. + + Releases are compared using case-sensitive string comparison. + +<span id="option-since-label">`--since-label` *text*</span> +: Specifies the *text* to use in the heading of the "New API" page. This may + contain information about the releases covered in the page, e.g. + "New API in release 2.0", or "New API since release 1". + +<span id="option-snippet-path">`--snippet-path` *snippetpathlist*</span> +: Specifies the search paths for finding files for external snippets. + The *snippetpathlist* can contain multiple paths by separating them with the + platform path separator (`;` on Windows; `:` on other platforms.) + The standard doclet first searches the `snippet-files` subdirectory in the + package containing the snippet, and then searches all the directories in the + given list. + +<span id="option-sourcetab">`-sourcetab` *tab-length*</span> +: Specifies the number of spaces each tab uses in the source. + +<span id="option-spec-base-url">`--spec-base-url` *url*</span> +: Specifies the base URL for relative URLs in `@spec` tags, to be used when + generating links to any external specifications. It can either be an + absolute URL, or a relative URL, in which case it is evaluated relative + to the base directory of the generated output files. The default value is + equivalent to `{@docRoot}/../specs`. + +<span id="option-splitindex">`-splitindex`</span> +: Splits the index file into multiple files, alphabetically, one file per + letter, plus a file for any index entries that start with non-alphabetical + symbols. + +<span id="option-tag">`-tag` *name*:*locations*:*header*</span> +: Specifies a custom tag with a single argument. For the `javadoc` tool to + spell-check tag names, it is important to include a `-tag` option for every + custom tag that is present in the source code, disabling (with `X`) those + that aren't being output in the current run. The colon (`:`) is always the + separator. To include a colon in the tag name, escape it with a backward + slash (`\`). The `-tag` option outputs the tag heading, *header*, in bold, + followed on the next line by the text from its single argument. Similar to + any block tag, the argument text can contain inline tags, which are also + interpreted. The output is similar to standard one-argument tags, such as + the `@return` and `@author` tags. Omitting a *header* value causes the + *name* to be the heading. *locations* is a list of characters specifying + the kinds of declarations in which the tag may be used. The following + characters may be used, in either uppercase or lowercase: + + * `A`: all declarations + * `C`: constructors + * `F`: fields + * `M`: methods + * `O`: the overview page and other documentation files in `doc-files` subdirectories + * `P`: packages + * `S`: modules + * `T`: types (classes and interfaces) + * `X`: nowhere: the tag is disabled, and will be ignored + + The order in which tags are given on the command line will be used + as the order in which the tags appear in the generated output. + You can include standard tags in the order given on the command line + by using the `-tag` option with no *locations* or *header*. + +<span id="option-taglet">`-taglet` *class*</span> +: Specifies the fully qualified name of the taglet used in generating the + documentation for that tag. Use the fully qualified name for the *class* + value. This taglet also defines the number of text arguments that the + custom tag has. The taglet accepts those arguments, processes them, and + generates the output. + + Taglets are useful for block or inline tags. They can have any number of + arguments and implement custom behavior, such as making text bold, + formatting bullets, writing out the text to a file, or starting other + processes. Taglets can only determine where a tag should appear and in what + form. All other decisions are made by the doclet. A taglet can't do things + such as remove a class name from the list of included classes. However, it + can execute side effects, such as printing the tag's text to a file or + triggering another process. Use the `-tagletpath` option to specify the + path to the taglet. The following example inserts the To Do taglet after + Parameters and ahead of Throws in the generated pages. + + ``` + -taglet com.sun.tools.doclets.ToDoTaglet + -tagletpath /home/taglets + -tag return + -tag param + -tag todo + -tag throws + -tag see + ``` + + Alternately, you can use the `-taglet` option in place of its `-tag` + option, but that might be difficult to read. + +<span id="option-tagletpath">`-tagletpath` *tagletpathlist*</span> +: Specifies the search paths for finding taglet class files. + The *tagletpathlist* can contain multiple paths by separating them with the + platform path separator (`;` on Windows; `:` on other platforms.) + The `javadoc` tool searches all subdirectories of the specified paths. + +<span id="option-top">`-top` *html-code*</span> +: Specifies the text to be placed at the top of each output file. + +<span id="option-use">`-use`</span> +: Creates class and package usage pages. Includes one Use page for each + documented class and package. The page describes what packages, classes, + methods, constructors, and fields use any API of the specified class or + package. Given class C, things that use class C would include subclasses of + C, fields declared as C, methods that return C, and methods and + constructors with parameters of type C. For example, you can look at the + Use page for the `String` type. Because the `getName` method in the + `java.awt.Font` class returns type `String`, the `getName` method uses + `String` and so the `getName` method appears on the Use page for `String`. + This documents only uses of the API, not the implementation. When a method + uses `String` in its implementation, but doesn't take a string as an + argument or return a string, that isn't considered a use of `String`. To + access the generated Use page, go to the class or package and click the + **USE** link in the navigation bar. + +<span id="option-version">`-version`</span> +: Includes the text of any `version` tags in the generated documentation. + This text is omitted by default. + Note: To find out what version of the `javadoc` tool you are using, use + the `--version` option (with two hyphens). + +<span id="option-windowtitle">`-windowtitle` *title*</span> +: Specifies the title to be placed in the HTML `<title>` tag. The text + specified in the `title` tag appears in the window title and in any browser + bookmarks (favorite places) that someone creates for this page. This title + should not contain any HTML tags because a browser will not interpret them + correctly. Use escape characters on any internal quotation marks within the + `title` tag. If the `-windowtitle` option is omitted, then the `javadoc` + tool uses the value of the `-doctitle` option for the `-windowtitle` + option. For example, `javadoc -windowtitle "My Library" com.mypackage`. + +### Extra Options for the Standard Doclet + +The following are additional options provided by the standard doclet and are +subject to change without notice. Additional options are less commonly +used or are otherwise regarded as advanced. + +<span id="option-date">`--date` *date-and-time*</span> +: Specifies the value to be used to timestamp the generated pages, in + [ISO 8601][] format. The specified value must be within 10 years of the + current date and time. It is an error to specify both `-notimestamp` + and `--date`. Using a specific value means the generated documentation + can be part of a [reproducible build][]. If the option is not given, the + default value is the current date and time. For example: + + ``` + javadoc --date 2022-02-01T17:41:59-08:00 mypackage + ``` + +<span id="option-legal-notices">`--legal-notices` (`default`|`none`|*directory*)</span> +: Specifies the location from which to copy legal files to the generated + documentation. If the option is not specified or is used with the value + `default`, the files are copied from the default location. + If the argument is used with value `none`, no files are copied. Every + other argument is interpreted as directory from which to copy the legal + files. + +<span id="option-no-frames">`--no-frames`</span> +: This option is no longer supported and reports a warning. + +<span id="option-Xdoclint">`-Xdoclint`</span> +: Enables recommended checks for problems in documentation comments. + + By default, the `-Xdoclint` option is enabled. Disable it with the option + `-Xdoclint:none`. + + For more details, see [DocLint](#doclint). + +<span id="option-Xdoclint-flags">`-Xdoclint:`*flag*,*flag*,...</span> +: Enables or disables specific checks for different kinds of issues in + documentation comments. + + Each *flag* can be one of `all`, `none`, or `[-]`*group* where + *group* has one of the following values: + `accessibility`, `html`, `missing`, `reference`, `syntax`. + For more details on these values, see [DocLint Groups](#groups). + + When specifying two or more flags, you can either use a single `-Xdoclint:...` + option, listing all the desired flags, or you can use multiple options + giving one or more flag in each option. For example, use either of the + following commands to check for the HTML, syntax, and accessibility issues + in the file `MyFile.java`. + + ``` + javadoc -Xdoclint:html -Xdoclint:syntax -Xdoclint:accessibility MyFile.java + javadoc -Xdoclint:html,syntax,accessibility MyFile.java + ``` + + The following examples illustrate how to change what DocLint reports: + + * `-Xdoclint:none` --- disables all checks + * `-Xdoclint:`*group* --- enables *group* checks + * `-Xdoclint:all` --- enables all groups of checks + * `-Xdoclint:all,-`*group* --- enables all checks except *group* checks + + For more details, see [DocLint](#doclint). + +<span id="option-Xdoclint-package">`-Xdoclint/package:`\[`-`\]*packages*</span> +: Enables or disables checks in specific packages. *packages* is a comma + separated list of package specifiers. A package specifier is either a + qualified name of a package or a package name prefix followed by `*`, which + expands to all subpackages of the given package. Prefix the package + specifier with `-` to disable checks for the specified packages. + + For more details, see [DocLint](#doclint). + +<span id="option-Xdocrootparent">`-Xdocrootparent` *url*</span> +: Replaces all `@docRoot` items followed by `/..` in documentation comments + with *url*. + +[ISO 8601]: https://www.iso.org/iso-8601-date-and-time-format.html +[reproducible build]: https://reproducible-builds.org/ + +## DocLint + +DocLint provides the ability to check for possible problems in documentation +comments. Problems may be reported as warnings or errors, depending on their +severity. For example, a missing comment may be bad style that deserves a +warning, but a link to an unknown Java declaration is more serious and deserves +an error. Problems are organized into [groups](#groups), and options can be +used to enable or disable messages in one or more groups. Within the source +code, messages in one or more groups can be [suppressed](#suppressing-messages) +by using `@SuppressWarnings` annotations. + +When invoked from `javadoc`, by default DocLint checks all comments that are +used in the generated documentation. It thus relies on other command-line +options to determine which declarations, and which corresponding documentation +comments will be included. _Note:_ this may mean that even comments on some +private members of serializable classes will also be checked, if the members +need to be documented in the generated `Serialized Forms` page. + +In contrast, when DocLint is invoked from `javac`, DocLint solely relies on the +various `-Xdoclint...` options to determine which documentation comments to +check. + +DocLint doesn't attempt to fix invalid input, it just reports it. + +_Note:_ DocLint doesn't guarantee the completeness of these checks. +In particular, it isn't a full HTML compliance checker. The goal is to just +report common errors in a convenient manner. + +### Groups + +The checks performed by DocLint are organized into groups. The warnings and +errors in each group can be enabled or disabled with command-line options, or +suppressed with `@SuppressWarnings` annotations. + +The groups are as follows: + +* `accessibility` --- Checks for issues related to accessibility.<br> + For example, no `alt` attribute specified in an `<img>` element, + or no caption or summary attributes specified in a `<table>` element. + + Issues are reported as errors if a downstream validation tool might + be expected to report an error in the files generated by `javadoc`. + + For reference, see the [Web Content Accessibility Guidelines][]. + + +* `html` --- Detects common high-level HTML issues.<br> + For example, putting block elements inside inline elements, or not closing + elements that require an end tag. + + Issues are reported as errors if a downstream validation tool might + be expected to report an error in the files generated by `javadoc`. + + For reference, see the [HTML Living Standard][]. + + +* `missing` --- Checks for missing documentation comments or tags.<br> + For example, a missing comment on a class declaration, or a missing `@param` + or `@return` tag in the comment for a method declaration. + + Issues related to missing items are typically reported as warnings because + they are unlikely to be reported as errors by downstream validation tools + that may be used to check the output generated by `javadoc`. + + +* `reference` --- Checks for issues relating to the references to Java API + elements from documentation comment tags.<br> + For example, the reference in `@see` or `{@link ...}` cannot be found, + or a bad name is given for `@param` or `@throws`. + + Issues are typically reported as errors because while the issue may not cause + problems in the generated files, the author has likely made a mistake that + will lead to incorrect or unexpected documentation. + + +* `syntax` --- Checks for low-level syntactic issues in documentation comments.<br> + For example, unescaped angle brackets (`<` and `>`) and ampersands (`&`) + and invalid documentation comment tags.<br> + + Issues are typically reported as errors because the issues may + lead to incorrect or unexpected documentation. + +[HTML Living Standard]: https://html.spec.whatwg.org/multipage/ +[Web Content Accessibility Guidelines]: https://www.w3.org/WAI/standards-guidelines/wcag/ + + +### Suppressing Messages + +DocLint checks for and recognizes two strings that may be present in the +arguments for an `@SuppressWarnings` annotation. + +* `doclint` +* `doclint:`_LIST_ + +where _LIST_ is a comma-separated list of one or more of +`accessibility`, `html`, `missing`, `reference`, `syntax`. + +The names in _LIST_ are the same [group](#groups) names supported by the +command-line `-Xdoclint` option for `javac` and `javadoc`. (This is the same +convention honored by the `javac` `-Xlint` option and the corresponding names +supported by `@SuppressWarnings`.) + +The names in _LIST_ can equivalently be specified in separate arguments of +the annotation. For example, the following are equivalent: + +* `@SuppressWarnings("doclint:accessibility,missing")` +* `@SuppressWarnings("doclint:accessibility", "doclint:missing")` + +When DocLint detects an issue in a documentation comment, it checks for the +presence of `@SuppressWarnings` on the associated declaration and on all +lexically enclosing declarations. The issue will be ignored if any such +annotation is found containing the simple string `doclint` or the longer form +`doclint:LIST` where _LIST_ contains the name of the group for the issue. + +_Note:_ as with other uses of `@SuppressWarnings`, using the annotation on a +module or package declaration only affects that declaration; it does not affect +the contents of the module or package in other source files. + +All messages related to an issue are suppressed by the presence of an +appropriate `@SuppressWarnings` annotation: this includes errors as well as +warnings. + +_Note:_ It is only possible to *suppress* messages. +If an annotation of `@SuppressWarnings("doclint")` is given on a top-level +declaration, all DocLint messages for that declaration and any enclosed +declarations will be suppressed; it is not possible to selectively re-enable +messages for issues in enclosed declarations. + + +### Comparison with downstream validation tools + +DocLint is a utility built into `javac` and `javadoc` that checks the content +of documentation comments, as found in source files. In contrast, downstream +validation tools can be used to validate the output generated from those +documentation comments by `javadoc` and the standard doclet. + +Although there is some overlap in functionality, the two mechanisms are +different and each has its own strengths and weaknesses. + +* Downstream validation tools can check the end result of any generated + documentation, as it will be seen by the end user. + This includes content from all sources, including documentation comments, + the standard doclet itself, user-provided taglets, and content supplied + via command-line options. Because such tools are analyzing complete HTML + pages, they can do more complete checks than can DocLint. + However, when a problem is found in the generated pages, it can be harder to + track down exactly where in the build pipeline the problem needs to be fixed. + + +* DocLint checks the content of documentation comments, in source files. + This makes it very easy to identify the exact position of any issues that + may be found. DocLint can also detect some semantic errors in + documentation comments that downstream tools cannot detect, + such as missing comments, using an `@return` tag in a method returning `void`, + or an `@param` tag describing a non-existent parameter. + But by its nature, DocLint cannot report on problems such as + missing links, or errors in user-provided custom taglets, or + problems in the standard doclet itself. It also cannot reliably + detect errors in documentation comments at the boundaries + between content in a documentation comment and content generated + by a custom taglet. diff --git a/src/jdk.jcmd/share/man/jcmd.1 b/src/jdk.jcmd/share/man/jcmd.1 deleted file mode 100644 index 495b629089d..00000000000 --- a/src/jdk.jcmd/share/man/jcmd.1 +++ /dev/null @@ -1,1345 +0,0 @@ -.\" Copyright (c) 2012, 2024, Oracle and/or its affiliates. All rights reserved. -.\" DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -.\" -.\" This code is free software; you can redistribute it and/or modify it -.\" under the terms of the GNU General Public License version 2 only, as -.\" published by the Free Software Foundation. -.\" -.\" This code is distributed in the hope that it will be useful, but WITHOUT -.\" ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -.\" FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -.\" version 2 for more details (a copy is included in the LICENSE file that -.\" accompanied this code). -.\" -.\" You should have received a copy of the GNU General Public License version -.\" 2 along with this work; if not, write to the Free Software Foundation, -.\" Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -.\" -.\" Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -.\" or visit www.oracle.com if you need additional information or have any -.\" questions. -.\" -.\" Automatically generated by Pandoc 2.19.2 -.\" -.\" Define V font for inline verbatim, using C font in formats -.\" that render this, and otherwise B font. -.ie "\f[CB]x\f[R]"x" \{\ -. ftr V B -. ftr VI BI -. ftr VB B -. ftr VBI BI -.\} -.el \{\ -. ftr V CR -. ftr VI CI -. ftr VB CB -. ftr VBI CBI -.\} -.TH "JCMD" "1" "2025" "JDK 24-ea" "JDK Commands" -.hy -.SH NAME -.PP -jcmd - send diagnostic command requests to a running Java Virtual -Machine (JVM) -.SH SYNOPSIS -.PP -\f[V]jcmd\f[R] [\f[I]pid\f[R] | \f[I]main-class\f[R]] -\f[I]command\f[R]... -| \f[V]PerfCounter.print\f[R] | \f[V]-f\f[R] \f[I]filename\f[R] -.PP -\f[V]jcmd\f[R] [\f[V]-l\f[R]] -.PP -\f[V]jcmd\f[R] \f[V]-h\f[R] -.TP -\f[I]pid\f[R] -When used, the \f[V]jcmd\f[R] utility sends the diagnostic command -request to the process ID for the Java process. -.TP -\f[I]main-class\f[R] -When used, the \f[V]jcmd\f[R] utility sends the diagnostic command -request to all Java processes with the specified name of the main class. -.TP -\f[I]command\f[R] -The \f[V]command\f[R] must be a valid \f[V]jcmd\f[R] command for the -selected JVM. -The list of available commands for \f[V]jcmd\f[R] is obtained by running -the \f[V]help\f[R] command (\f[V]jcmd\f[R] \f[I]pid\f[R] \f[V]help\f[R]) -where \f[I]pid\f[R] is the process ID for the running Java process. -.TP -\f[V]Perfcounter.print\f[R] -Prints the performance counters exposed by the specified Java process. -.TP -\f[V]-f\f[R] \f[I]filename\f[R] -Reads and executes commands from a specified file, \f[I]filename\f[R]. -.TP -\f[V]-l\f[R] -Displays the list of Java Virtual Machine process identifiers that are -not running in a separate docker process along with the main class and -command-line arguments that were used to launch the process. -If the JVM is in a docker process, you must use tools such as -\f[V]ps\f[R] to look up the PID. -.RS -.PP -\f[B]Note:\f[R] -.PP -Using \f[V]jcmd\f[R] without arguments is the same as using -\f[V]jcmd -l\f[R]. -.RE -.TP -\f[V]-h\f[R] -Displays the \f[V]jcmd\f[R] utility\[aq]s command-line help. -.SH DESCRIPTION -.PP -The \f[V]jcmd\f[R] utility is used to send diagnostic command requests -to the JVM. -It must be used on the same machine on which the JVM is running, and -have the same effective user and group identifiers that were used to -launch the JVM. -Each diagnostic command has its own set of options and arguments. -To display the description, syntax, and a list of available options and -arguments for a diagnostic command, use the name of the command as the -argument. -For example: -.RS -.PP -\f[V]jcmd\f[R] \f[I]pid\f[R] \f[V]help\f[R] \f[I]command\f[R] -.RE -.PP -If arguments contain spaces, then you must surround them with single or -double quotation marks (\f[V]\[aq]\f[R] or \f[V]\[dq]\f[R]). -In addition, you must escape single or double quotation marks with a -backslash (\f[V]\[rs]\f[R]) to prevent the operating system shell from -processing quotation marks. -Alternatively, you can surround these arguments with single quotation -marks and then with double quotation marks (or with double quotation -marks and then with single quotation marks). -.PP -If you specify the process identifier (\f[I]pid\f[R]) or the main class -(\f[I]main-class\f[R]) as the first argument, then the \f[V]jcmd\f[R] -utility sends the diagnostic command request to the Java process with -the specified identifier or to all Java processes with the specified -name of the main class. -You can also send the diagnostic command request to all available Java -processes by specifying \f[V]0\f[R] as the process identifier. -.SH COMMANDS FOR JCMD -.PP -The \f[I]command\f[R] must be a valid \f[V]jcmd\f[R] diagnostic command -for the selected JVM. -The list of available commands for \f[V]jcmd\f[R] is obtained by running -the \f[V]help\f[R] command (\f[V]jcmd\f[R] \f[I]pid\f[R] \f[V]help\f[R]) -where \f[I]pid\f[R] is the process ID for a running Java process. -If the \f[I]pid\f[R] is \f[V]0\f[R], commands will be sent to all Java -processes. -The main class argument will be used to match, either partially or -fully, the class used to start Java. -If no options are given, it lists the running Java process identifiers -that are not in separate docker processes along with the main class and -command-line arguments that were used to launch the process (the same as -using \f[V]-l\f[R]). -.PP -\f[V]jcmd\f[R] \f[I]commands\f[R] may take options and arguments. -\f[I]Options\f[R] are specified using either \f[I]key\f[R] or -\f[I]key\f[R]\f[V]=\f[R]\f[I]value\f[R] syntax. -\f[I]Arguments\f[R] are given as just a value, never name=value. -.PP -The following commands are available: -.TP -\f[V]help\f[R] [\f[I]options\f[R]] [\f[I]arguments\f[R]] -For more information about a specific command. -.RS -.PP -\f[I]arguments\f[R]: -.IP \[bu] 2 -\f[I]command name\f[R]: The name of the command for which we want help -(STRING, no default value) -.PP -\f[B]Note:\f[R] -.PP -The following \f[I]options\f[R] must be specified using either -\f[I]key\f[R] or \f[I]key\f[R]\f[V]=\f[R]\f[I]value\f[R] syntax. -.PP -\f[I]options\f[R]: -.IP \[bu] 2 -\f[V]-all\f[R]: (Optional) Show help for all commands (BOOLEAN, false) . -.RE -.TP -\f[V]Compiler.CodeHeap_Analytics\f[R] [\f[I]function\f[R]] [\f[I]granularity\f[R]] -Print CodeHeap analytics -.RS -.PP -Impact: Low: Depends on code heap size and content. -Holds CodeCache_lock during analysis step, usually sub-second duration. -.PP -\f[I]arguments\f[R]: -.IP \[bu] 2 -\f[I]function\f[R]: (Optional) Function to be performed (aggregate, -UsedSpace, FreeSpace, MethodCount, MethodSpace, MethodAge, MethodNames, -discard (STRING, all) -.IP \[bu] 2 -\f[I]granularity\f[R]: (Optional) Detail level - smaller value -> more -detail (INT, 4096) -.RE -.TP -\f[V]Compiler.codecache\f[R] -Prints code cache layout and bounds. -.RS -.PP -Impact: Low -.RE -.TP -\f[V]Compiler.codelist\f[R] -Prints all compiled methods in code cache that are alive. -.RS -.PP -Impact: Medium -.RE -.TP -\f[V]Compiler.directives_add\f[R] \f[I]arguments\f[R] -Adds compiler directives from a file. -.RS -.PP -Impact: Low -.PP -\f[I]arguments\f[R]: -.IP \[bu] 2 -\f[I]filename\f[R]: The name of the directives file (STRING, no default -value) -.RE -.TP -\f[V]Compiler.directives_clear\f[R] -Remove all compiler directives. -.RS -.PP -Impact: Low -.RE -.TP -\f[V]Compiler.directives_print\f[R] -Prints all active compiler directives. -.RS -.PP -Impact: Low -.RE -.TP -\f[V]Compiler.directives_remove\f[R] -Remove latest added compiler directive. -.RS -.PP -Impact: Low -.RE -.TP -\f[V]Compiler.memory\f[R] [\f[I]options\f[R]] -Print compilation footprint -.RS -.PP -Impact: Medium: Pause time depends on number of compiled methods -.PP -\f[B]Note:\f[R] -.PP -The \f[I]options\f[R] must be specified using either \f[I]key\f[R] or -\f[I]key\f[R]\f[V]=\f[R]\f[I]value\f[R] syntax. -.PP -\f[I]options\f[R]: -.IP \[bu] 2 -\f[V]-H\f[R]: (Optional) Human readable format (BOOLEAN, false) -.IP \[bu] 2 -\f[V]-s\f[R]: (Optional) Minimum memory size (MEMORY SIZE, 0) -.RE -.TP -\f[V]Compiler.perfmap\f[R] [\f[I]arguments\f[R]] (Linux only) -Write map file for Linux perf tool. -.RS -.PP -Impact: Low -.PP -\f[I]arguments\f[R]: -.IP \[bu] 2 -\f[I]filename\f[R]: (Optional) The name of the map file. -If %p is specified in the filename, it is expanded to the JVM\[aq]s PID. -(FILE, \[dq]/tmp/perf-%p.map\[dq]) -.RE -.TP -\f[V]Compiler.queue\f[R] -Prints methods queued for compilation. -.RS -.PP -Impact: Low -.RE -.TP -\f[V]GC.class_histogram\f[R] [\f[I]options\f[R]] -Provides statistics about the Java heap usage. -.RS -.PP -Impact: High --- depends on Java heap size and content. -.PP -\f[B]Note:\f[R] -.PP -The \f[I]options\f[R] must be specified using either \f[I]key\f[R] or -\f[I]key\f[R]\f[V]=\f[R]\f[I]value\f[R] syntax. -.PP -\f[I]options\f[R]: -.IP \[bu] 2 -\f[V]-all\f[R]: (Optional) Inspects all objects, including unreachable -objects (BOOLEAN, false) -.IP \[bu] 2 -\f[V]-parallel\f[R]: (Optional) Number of parallel threads to use for -heap inspection. -0 (the default) means let the VM determine the number of threads to use. -1 means use one thread (disable parallelism). -For any other value the VM will try to use the specified number of -threads, but might use fewer. -(INT, 0) -.RE -.TP -\f[V]GC.finalizer_info\f[R] -Provides information about the Java finalization queue. -.RS -.PP -Impact: Medium -.RE -.TP -\f[V]GC.heap_dump\f[R] [\f[I]options\f[R]] \f[I]filename\f[R] -Generates a HPROF format dump of the Java heap. -.RS -.PP -Impact: High --- depends on the Java heap size and content. -Request a full GC unless the \f[V]-all\f[R] option is specified. -.PP -\f[B]Note:\f[R] -.PP -The following \f[I]options\f[R] must be specified using either -\f[I]key\f[R] or \f[I]key\f[R]\f[V]=\f[R]\f[I]value\f[R] syntax. -.PP -\f[I]options\f[R]: -.IP \[bu] 2 -\f[V]-all\f[R]: (Optional) Dump all objects, including unreachable -objects (BOOLEAN, false) -.IP \[bu] 2 -\f[V]-gz\f[R]: (Optional) If specified, the heap dump is written in -gzipped format using the given compression level. -1 (recommended) is the fastest, 9 the strongest compression. -(INT, 1) -.IP \[bu] 2 -\f[V]-overwrite\f[R]: (Optional) If specified, the dump file will be -overwritten if it exists (BOOLEAN, false) -.IP \[bu] 2 -\f[V]-parallel\f[R]: (Optional) Number of parallel threads to use for -heap dump. -The VM will try to use the specified number of threads, but might use -fewer. -(INT, 1) -.PP -\f[I]arguments\f[R]: -.IP \[bu] 2 -\f[I]filename\f[R]: The name of the dump file. -If %p is specified in the filename, it is expanded to the JVM\[aq]s PID. -(FILE, no default value) -.RE -.TP -\f[V]GC.heap_info\f[R] -Provides generic Java heap information. -.RS -.PP -Impact: Medium -.RE -.TP -\f[V]GC.run\f[R] -Calls \f[V]java.lang.System.gc()\f[R]. -.RS -.PP -Impact: Medium --- depends on the Java heap size and content. -.RE -.TP -\f[V]GC.run_finalization\f[R] -Calls \f[V]java.lang.System.runFinalization()\f[R]. -.RS -.PP -Impact: Medium --- depends on the Java content. -.RE -.TP -\f[V]JFR.check\f[R] [\f[I]options\f[R]] -Show information about a running flight recording -.RS -.PP -Impact: Low -.PP -\f[B]Note:\f[R] -.PP -The \f[I]options\f[R] must be specified using either \f[I]key\f[R] or -\f[I]key\f[R]\f[V]=\f[R]\f[I]value\f[R] syntax. -If no parameters are entered, information for all active recordings is -shown. -.PP -\f[I]options\f[R]: -.IP \[bu] 2 -\f[V]name\f[R]: (Optional) Name of the flight recording. -(STRING, no default value) -.IP \[bu] 2 -\f[V]verbose\f[R]: (Optional) Flag for printing the event settings for -the recording (BOOLEAN, false) -.RE -.TP -\f[V]JFR.configure\f[R] [\f[I]options\f[R]] -Set the parameters for a flight recording -.RS -.PP -Impact: Low -.PP -\f[B]Note:\f[R] -.PP -The \f[I]options\f[R] must be specified using either \f[I]key\f[R] or -\f[I]key\f[R]\f[V]=\f[R]\f[I]value\f[R] syntax. -If no parameters are entered, the current settings are displayed. -.PP -\f[I]options\f[R]: -.IP \[bu] 2 -\f[V]dumppath\f[R]: (Optional) Path to the location where a recording -file is written in case the VM runs into a critical error, such as a -system crash. -(STRING, The default location is the current directory) -.IP \[bu] 2 -\f[V]globalbuffercount\f[R]: (Optional) Number of global buffers. -This option is a legacy option: change the \f[V]memorysize\f[R] -parameter to alter the number of global buffers. -This value cannot be changed once JFR has been initialized. -(STRING, default determined by the value for \f[V]memorysize\f[R]) -.IP \[bu] 2 -\f[V]globalbuffersize\f[R]: (Optional) Size of the global buffers, in -bytes. -This option is a legacy option: change the \f[V]memorysize\f[R] -parameter to alter the size of the global buffers. -This value cannot be changed once JFR has been initialized. -(STRING, default determined by the value for \f[V]memorysize\f[R]) -.IP \[bu] 2 -\f[V]maxchunksize\f[R]: (Optional) Maximum size of an individual data -chunk in bytes if one of the following suffixes is not used: \[aq]m\[aq] -or \[aq]M\[aq] for megabytes OR \[aq]g\[aq] or \[aq]G\[aq] for -gigabytes. -This value cannot be changed once JFR has been initialized. -(STRING, 12M) -.IP \[bu] 2 -\f[V]memorysize\f[R]: (Optional) Overall memory size, in bytes if one of -the following suffixes is not used: \[aq]m\[aq] or \[aq]M\[aq] for -megabytes OR \[aq]g\[aq] or \[aq]G\[aq] for gigabytes. -This value cannot be changed once JFR has been initialized. -(STRING, 10M) -.IP \[bu] 2 -\f[V]repositorypath\f[R]: (Optional) Path to the location where -recordings are stored until they are written to a permanent file. -(STRING, The default location is the temporary directory for the -operating system. -On Linux operating systems, the temporary directory is \f[V]/tmp\f[R]. -On Windwows, the temporary directory is specified by the \f[V]TMP\f[R] -environment variable.) -.IP \[bu] 2 -\f[V]preserve-repository=\f[R]{\f[V]true\f[R]|\f[V]false\f[R]} : -Specifies whether files stored in the disk repository should be kept -after the JVM has exited. -If false, files are deleted. -By default, this parameter is disabled. -.IP \[bu] 2 -\f[V]stackdepth\f[R]: (Optional) Stack depth for stack traces. -Setting this value greater than the default of 64 may cause a -performance degradation. -This value cannot be changed once JFR has been initialized. -(LONG, 64) -.IP \[bu] 2 -\f[V]thread_buffer_size\f[R]: (Optional) Local buffer size for each -thread in bytes if one of the following suffixes is not used: -\[aq]k\[aq] or \[aq]K\[aq] for kilobytes or \[aq]m\[aq] or \[aq]M\[aq] -for megabytes. -Overriding this parameter could reduce performance and is not -recommended. -This value cannot be changed once JFR has been initialized. -(STRING, 8k) -.IP \[bu] 2 -\f[V]samplethreads\f[R]: (Optional) Flag for activating thread sampling. -(BOOLEAN, true) -.RE -.TP -\f[V]JFR.dump\f[R] [\f[I]options\f[R]] -Write data to a file while a flight recording is running -.RS -.PP -Impact: Low -.PP -\f[B]Note:\f[R] -.PP -The \f[I]options\f[R] must be specified using either \f[I]key\f[R] or -\f[I]key\f[R]\f[V]=\f[R]\f[I]value\f[R] syntax. -No options are required. -The recording continues to run after the data is written. -.PP -\f[I]options\f[R]: -.IP \[bu] 2 -\f[V]begin\f[R]: (Optional) Specify the time from which recording data -will be included in the dump file. -The format is specified as local time. -(STRING, no default value) -.IP \[bu] 2 -\f[V]end\f[R]: (Optional) Specify the time to which recording data will -be included in the dump file. -The format is specified as local time. -(STRING, no default value) -.RS 2 -.PP -\f[B]Note:\f[R] For both \f[V]begin\f[R] and \f[V]end\f[R], the time -must be in a format that can be read by -java.time.LocalTime::parse(STRING), -java.time.LocalDateTime::parse(STRING) or -java.time.Instant::parse(STRING). -For example, \[dq]13:20:15\[dq], \[dq]2020-03-17T09:00:00\[dq] or -\[dq]2020-03-17T09:00:00Z\[dq]. -.PP -\f[B]Note:\f[R] \f[V]begin\f[R] and \f[V]end\f[R] times correspond to -the timestamps found within the recorded information in the flight -recording data. -.PP -Another option is to use a time relative to the current time that is -specified by a negative integer followed by \[dq]s\[dq], \[dq]m\[dq] or -\[dq]h\[dq]. -For example, \[dq]-12h\[dq], \[dq]-15m\[dq] or \[dq]-30s\[dq] -.RE -.IP \[bu] 2 -\f[V]filename\f[R]: (Optional) Name of the file to which the flight -recording data is dumped. -If no filename is given, a filename is generated from the PID and the -current date. -The filename may also be a directory in which case, the filename is -generated from the PID and the current date in the specified directory. -If %p and/or %t is specified in the filename, it expands to the -JVM\[aq]s PID and the current timestamp, respectively. -(FILE, no default value) -.IP \[bu] 2 -\f[V]maxage\f[R]: (Optional) Length of time for dumping the flight -recording data to a file. -(INTEGER followed by \[aq]s\[aq] for seconds \[aq]m\[aq] for minutes or -\[aq]h\[aq] for hours, no default value) -.IP \[bu] 2 -\f[V]maxsize\f[R]: (Optional) Maximum size for the amount of data to -dump from a flight recording in bytes if one of the following suffixes -is not used: \[aq]m\[aq] or \[aq]M\[aq] for megabytes OR \[aq]g\[aq] or -\[aq]G\[aq] for gigabytes. -(STRING, no default value) -.IP \[bu] 2 -\f[V]name\f[R]: (Optional) Name of the recording. -If no name is given, data from all recordings is dumped. -(STRING, no default value) -.IP \[bu] 2 -\f[V]path-to-gc-roots\f[R]: (Optional) Flag for saving the path to -garbage collection (GC) roots at the time the recording data is dumped. -The path information is useful for finding memory leaks but collecting -it can cause the application to pause for a short period of time. -Turn on this flag only when you have an application that you suspect has -a memory leak. -(BOOLEAN, false) -.RE -.TP -\f[V]JFR.start\f[R] [\f[I]options\f[R]] -Start a flight recording -.RS -.PP -Impact: Low -.PP -\f[B]Note:\f[R] -.PP -The \f[I]options\f[R] must be specified using either \f[I]key\f[R] or -\f[I]key\f[R]\f[V]=\f[R]\f[I]value\f[R] syntax. -If no parameters are entered, then a recording is started with default -values. -.PP -\f[I]options\f[R]: -.IP \[bu] 2 -\f[V]delay\f[R]: (Optional) Length of time to wait before starting to -record (INTEGER followed by \[aq]s\[aq] for seconds \[aq]m\[aq] for -minutes or \[aq]h\[aq] for hours, 0s) -.IP \[bu] 2 -\f[V]disk\f[R]: (Optional) Flag for also writing the data to disk while -recording (BOOLEAN, true) -.IP \[bu] 2 -\f[V]dumponexit\f[R]: (Optional) Flag for writing the recording to disk -when the Java Virtual Machine (JVM) shuts down. -If set to \[aq]true\[aq] and no value is given for \f[V]filename\f[R], -the recording is written to a file in the directory where the process -was started. -The file name is a system-generated name that contains the process ID, -the recording ID and the current time stamp. -(For example: \f[V]id-1-2019_12_12_10_41.jfr\f[R]) (BOOLEAN, false) -.IP \[bu] 2 -\f[V]duration\f[R]: (Optional) Length of time to record. -Note that \f[V]0s\f[R] means forever (INTEGER followed by \[aq]s\[aq] -for seconds \[aq]m\[aq] for minutes or \[aq]h\[aq] for hours, 0s) -.IP \[bu] 2 -\f[V]filename\f[R]: (Optional) Name of the file to which the flight -recording data is written when the recording is stopped. -If no filename is given, a filename is generated from the PID and the -current date and is placed in the directory where the process was -started. -The filename may also be a directory in which case, the filename is -generated from the PID and the current date in the specified directory. -If %p and/or %t is specified in the filename, it expands to the -JVM\[aq]s PID and the current timestamp, respectively. -(FILE, no default value) -.IP \[bu] 2 -\f[V]maxage\f[R]: (Optional) Maximum time to keep the recorded data on -disk. -This parameter is valid only when the \f[V]disk\f[R] parameter is set to -\f[V]true\f[R]. -Note \f[V]0s\f[R] means forever. -(INTEGER followed by \[aq]s\[aq] for seconds \[aq]m\[aq] for minutes or -\[aq]h\[aq] for hours, 0s) -.IP \[bu] 2 -\f[V]maxsize\f[R]: (Optional) Maximum size of the data to keep on disk -in bytes if one of the following suffixes is not used: \[aq]m\[aq] or -\[aq]M\[aq] for megabytes OR \[aq]g\[aq] or \[aq]G\[aq] for gigabytes. -This parameter is valid only when the \f[V]disk\f[R] parameter is set to -\[aq]true\[aq]. -The value must not be less than the value for the \f[V]maxchunksize\f[R] -parameter set with the \f[V]JFR.configure\f[R] command. -(STRING, 0 (no maximum size)) -.IP \[bu] 2 -\f[V]name\f[R]: (Optional) Name of the recording. -If no name is provided, a name is generated. -Make note of the generated name that is shown in the response to the -command so that you can use it with other commands. -(STRING, system-generated default name) -.IP \[bu] 2 -\f[V]path-to-gc-roots\f[R]: (Optional) Flag for saving the path to -garbage collection (GC) roots at the end of a recording. -The path information is useful for finding memory leaks but collecting -it is time consuming. -Turn on this flag only when you have an application that you suspect has -a memory leak. -If the \f[V]settings\f[R] parameter is set to \[aq]profile\[aq], then -the information collected includes the stack trace from where the -potential leaking object was allocated. -(BOOLEAN, false) -.IP \[bu] 2 -\f[V]settings\f[R]: (Optional) Name of the settings file that identifies -which events to record. -To specify more than one file, separate the names with a comma -(\[aq],\[aq]). -Include the path if the file is not in \f[V]JAVA-HOME\f[R]/lib/jfr. -The following profiles are included with the JDK in the -\f[V]JAVA-HOME\f[R]/lib/jfr directory: \[aq]default.jfc\[aq]: collects a -predefined set of information with low overhead, so it has minimal -impact on performance and can be used with recordings that run -continuously; \[aq]profile.jfc\[aq]: Provides more data than the -\[aq]default.jfc\[aq] profile, but with more overhead and impact on -performance. -Use this configuration for short periods of time when more information -is needed. -Use \f[V]none\f[R] to start a recording without a predefined -configuration file. -(STRING, \f[V]JAVA-HOME\f[R]/lib/jfr/default.jfc) -.PP -Event settings and .jfc options can be specified using the following -syntax: -.IP \[bu] 2 -\f[V]option\f[R]: (Optional) Specifies the option value to modify. -To list available options, use the \f[V]JAVA_HOME\f[R]/bin/jfr tool. -.IP \[bu] 2 -\f[V]event-setting\f[R]: (Optional) Specifies the event setting value to -modify. -Use the form: \f[V]<event-name>#<setting-name>=<value>\f[R] To add a new -event setting, prefix the event name with \[aq]+\[aq]. -.PP -You can specify values for multiple event settings and .jfc options by -separating them with a whitespace. -In case of a conflict between a parameter and a .jfc option, the -parameter will take precedence. -The whitespace delimiter can be omitted for timespan values, i.e. -20ms. -For more information about the settings syntax, see Javadoc of the -jdk.jfr package. -.RE -.TP -\f[V]JFR.stop\f[R] [\f[I]options\f[R]] -Stop a flight recording -.RS -.PP -Impact: Low -.PP -\f[B]Note:\f[R] -.PP -The \f[I]options\f[R] must be specified using either \f[I]key\f[R] or -\f[I]key\f[R]\f[V]=\f[R]\f[I]value\f[R] syntax. -If no parameters are entered, then no recording is stopped. -.PP -\f[I]options\f[R]: -.IP \[bu] 2 -\f[V]filename\f[R]: (Optional) Name of the file to which the recording -is written when the recording is stopped. -If %p and/or %t is specified in the filename, it expands to the -JVM\[aq]s PID and the current timestamp, respectively. -If no path is provided, the data from the recording is discarded. -(FILE, no default value) -.IP \[bu] 2 -\f[V]name\f[R]: (Optional) Name of the recording (STRING, no default -value) -.RE -.TP -\f[V]JFR.view\f[R] [\f[I]options\f[R]] -Display event data in predefined views. -.RS -.PP -Impact: Medium -.PP -\f[B]Note:\f[R] -.PP -The \f[I]options\f[R] must be specified using either \f[I]key\f[R] or -\f[I]key\f[R]\f[V]=\f[R]\f[I]value\f[R] syntax. -If no parameters are entered, then a list of available views are -displayed. -.PP -\f[I]options\f[R]: -.IP \[bu] 2 -\f[V]cell-height\f[R]: (Optional) Maximum number of rows in a table -cell. -(INT, default value depends on the view) -.IP \[bu] 2 -\f[V]maxage\f[R]: (Optional) Length of time for the view to span. -(INT followed by \[aq]s\[aq] for seconds \[aq]m\[aq] for minutes or -\[aq]h\[aq] for hours, default value is 10m) -.IP \[bu] 2 -\f[V]maxsize\f[R]: (Optional) Maximum size for the view to span in bytes -if one of the following suffixes is not used: \[aq]m\[aq] or \[aq]M\[aq] -for megabytes OR \[aq]g\[aq] or \[aq]G\[aq] for gigabytes. -(STRING, default value is 32MB) -.IP \[bu] 2 -\f[V]truncate\f[R]: (Optional) Maximum number of rows in a table cell. -(INT, default value depends on the view) -.IP \[bu] 2 -\f[V]verbose\f[R]: (Optional) Displays the query that makes up the view. -(BOOLEAN, default value is false) -.IP \[bu] 2 -\f[V]width\f[R]: (Optional) The width of the view in characters. -(INT, default value depends on the view) -.PP -\f[I]arguments\f[R]: -.IP \[bu] 2 -\f[V]view\f[R]: Name of the view or event type to display. -Use \f[V]help JFR.view\f[R] to see a list of available views. -(STRING, no default value) -.PP -The view parameter can be an event type name. -Use \f[V]JFR.view types\f[R] to see a list. -To display all views, use \f[V]JFR.view all-views\f[R]. -To display all events, use \f[V]JFR.view all-events\f[R]. -.RE -.TP -\f[V]JVMTI.agent_load\f[R] [\f[I]arguments\f[R]] -Loads JVMTI native agent. -.RS -.PP -Impact: Low -.PP -\f[I]arguments\f[R]: -.IP \[bu] 2 -\f[I]library path\f[R]: Absolute path of the JVMTI agent to load. -(STRING, no default value) -.IP \[bu] 2 -\f[I]agent option\f[R]: (Optional) Option string to pass the agent. -(STRING, no default value) -.RE -.TP -\f[V]JVMTI.data_dump\f[R] -Signal the JVM to do a data-dump request for JVMTI. -.RS -.PP -Impact: High -.RE -.TP -\f[V]ManagementAgent.start\f[R] [\f[I]options\f[R]] -Starts remote management agent. -.RS -.PP -Impact: Low --- no impact -.PP -\f[B]Note:\f[R] -.PP -The following \f[I]options\f[R] must be specified using either -\f[I]key\f[R] or \f[I]key\f[R]\f[V]=\f[R]\f[I]value\f[R] syntax. -.PP -\f[I]options\f[R]: -.IP \[bu] 2 -\f[V]config.file\f[R]: (Optional) Sets -\f[V]com.sun.management.config.file\f[R] (STRING, no default value) -.IP \[bu] 2 -\f[V]jmxremote.host\f[R]: (Optional) Sets -\f[V]com.sun.management.jmxremote.host\f[R] (STRING, no default value) -.IP \[bu] 2 -\f[V]jmxremote.port\f[R]: (Optional) Sets -\f[V]com.sun.management.jmxremote.port\f[R] (STRING, no default value) -.IP \[bu] 2 -\f[V]jmxremote.rmi.port\f[R]: (Optional) Sets -\f[V]com.sun.management.jmxremote.rmi.port\f[R] (STRING, no default -value) -.IP \[bu] 2 -\f[V]jmxremote.ssl\f[R]: (Optional) Sets -\f[V]com.sun.management.jmxremote.ssl\f[R] (STRING, no default value) -.IP \[bu] 2 -\f[V]jmxremote.registry.ssl\f[R]: (Optional) Sets -\f[V]com.sun.management.jmxremote.registry.ssl\f[R] (STRING, no default -value) -.IP \[bu] 2 -\f[V]jmxremote.authenticate\f[R]: (Optional) Sets -\f[V]com.sun.management.jmxremote.authenticate\f[R] (STRING, no default -value) -.IP \[bu] 2 -jmxremote.password.file: (Optional) Sets -\f[V]com.sun.management.jmxremote.password.file\f[R] (STRING, no default -value) -.IP \[bu] 2 -\f[V]jmxremote.access.file\f[R]: (Optional) Sets -\f[V]com.sun.management.jmxremote.acce ss.file\f[R] (STRING, no default -value) -.IP \[bu] 2 -\f[V]jmxremote.login.config\f[R]: (Optional) Sets -\f[V]com.sun.management.jmxremote.log in.config\f[R] (STRING, no default -value) -.IP \[bu] 2 -\f[V]jmxremote.ssl.enabled.cipher.suites\f[R]: (Optional) Sets -\f[V]com.sun.management\f[R]. -.IP \[bu] 2 -\f[V]jmxremote.ssl.enabled.cipher.suite\f[R]: (STRING, no default value) -.IP \[bu] 2 -\f[V]jmxremote.ssl.enabled.protocols\f[R]: (Optional) Sets -\f[V]com.sun.management.jmxr emote.ssl.enabled.protocols\f[R] (STRING, -no default value) -.IP \[bu] 2 -\f[V]jmxremote.ssl.need.client.auth\f[R]: (Optional) Sets -\f[V]com.sun.management.jmxre mote.need.client.auth\f[R] (STRING, no -default value) -.IP \[bu] 2 -\f[V]jmxremote.ssl.config.file\f[R]: (Optional) Sets -\f[V]com.sun.management.jmxremote. ssl_config_file\f[R] (STRING, no -default value) -.IP \[bu] 2 -\f[V]jmxremote.autodiscovery\f[R]: (Optional) Sets -\f[V]com.sun.management.jmxremote.au todiscovery\f[R] (STRING, no -default value) -.IP \[bu] 2 -\f[V]jdp.port\f[R]: (Optional) Sets -\f[V]com.sun.management.jdp.port\f[R] (INT, no default value) -.IP \[bu] 2 -\f[V]jdp.address\f[R]: (Optional) Sets -\f[V]com.sun.management.jdp.address\f[R] (STRING, no default value) -.IP \[bu] 2 -\f[V]jdp.source_addr\f[R]: (Optional) Sets -\f[V]com.sun.management.jdp.source_addr\f[R] (STRING, no default value) -.IP \[bu] 2 -\f[V]jdp.ttl\f[R]: (Optional) Sets \f[V]com.sun.management.jdp.ttl\f[R] -(INT, no default value) -.IP \[bu] 2 -\f[V]jdp.pause\f[R]: (Optional) Sets -\f[V]com.sun.management.jdp.pause\f[R] (INT, no default value) -.IP \[bu] 2 -\f[V]jdp.name\f[R]: (Optional) Sets -\f[V]com.sun.management.jdp.name\f[R] (STRING, no default value) -.RE -.TP -\f[V]ManagementAgent.start_local\f[R] -Starts the local management agent. -.RS -.PP -Impact: Low --- no impact -.RE -.TP -\f[V]ManagementAgent.status\f[R] -Print the management agent status. -.RS -.PP -Impact: Low --- no impact -.RE -.TP -\f[V]ManagementAgent.stop\f[R] -Stops the remote management agent. -.RS -.PP -Impact: Low --- no impact -.RE -.TP -\f[V]System.dump_map\f[R] [\f[I]options\f[R]] (Linux only) -Dumps an annotated process memory map to an output file. -.RS -.PP -Impact: Low -.PP -\f[B]Note:\f[R] -.PP -The following \f[I]options\f[R] must be specified using either -\f[I]key\f[R] or \f[I]key\f[R]\f[V]=\f[R]\f[I]value\f[R] syntax. -.PP -\f[I]options\f[R]: -.IP \[bu] 2 -\f[V]-H\f[R]: (Optional) Human readable format (BOOLEAN, false) -.IP \[bu] 2 -\f[V]-F\f[R]: (Optional) File path. -If %p is specified in the filename, it is expanded to the JVM\[aq]s PID. -(FILE, \[dq]vm_memory_map_%p.txt\[dq]) -.RE -.TP -\f[V]System.map\f[R] [\f[I]options\f[R]] (Linux only) -Prints an annotated process memory map of the VM process. -.RS -.PP -Impact: Low -.PP -\f[B]Note:\f[R] -.PP -The following \f[I]options\f[R] must be specified using either -\f[I]key\f[R] or \f[I]key\f[R]\f[V]=\f[R]\f[I]value\f[R] syntax. -.PP -\f[I]options\f[R]: -.IP \[bu] 2 -\f[V]-H\f[R]: (Optional) Human readable format (BOOLEAN, false) -.RE -.TP -\f[V]System.native_heap_info\f[R] (Linux only) -Attempts to output information regarding native heap usage through -malloc_info(3). -If unsuccessful outputs \[dq]Error: \[dq] and a reason. -.RS -.PP -Impact: Low -.RE -.TP -\f[V]System.trim_native_heap\f[R] (Linux only) -Attempts to free up memory by trimming the C-heap. -.RS -.PP -Impact: Low -.RE -.TP -\f[V]Thread.dump_to_file\f[R] [\f[I]options\f[R]] \f[I]filepath\f[R] -Dump threads, with stack traces, to a file in plain text or JSON format. -.RS -.PP -Impact: Medium: Depends on the number of threads. -.PP -\f[B]Note:\f[R] -.PP -The following \f[I]options\f[R] must be specified using either -\f[I]key\f[R] or \f[I]key\f[R]\f[V]=\f[R]\f[I]value\f[R] syntax. -.PP -\f[I]options\f[R]: -.IP \[bu] 2 -\f[V]-overwrite\f[R]: (Optional) May overwrite existing file (BOOLEAN, -false) -.IP \[bu] 2 -\f[V]-format\f[R]: (Optional) Output format (\[dq]plain\[dq] or -\[dq]json\[dq]) (STRING, plain) -.PP -\f[I]arguments\f[R]: -.IP \[bu] 2 -\f[I]filepath\f[R]: The file path to the output file. -If %p is specified in the filename, it is expanded to the JVM\[aq]s PID. -(FILE, no default value) -.RE -.TP -\f[V]Thread.print\f[R] [\f[I]options\f[R]] -Prints all threads with stacktraces. -.RS -.PP -Impact: Medium --- depends on the number of threads. -.PP -\f[B]Note:\f[R] -.PP -The following \f[I]options\f[R] must be specified using either -\f[I]key\f[R] or \f[I]key\f[R]\f[V]=\f[R]\f[I]value\f[R] syntax. -.PP -\f[I]options\f[R]: -.IP \[bu] 2 -\f[V]-e\f[R]: (Optional) Print extended thread information (BOOLEAN, -false) -.IP \[bu] 2 -\f[V]-l\f[R]: (Optional) Prints \f[V]java.util.concurrent\f[R] locks -(BOOLEAN, false) -.RE -.TP -\f[V]VM.cds\f[R] [\f[I]arguments\f[R]] -Dump a static or dynamic shared archive that includes all currently -loaded classes. -.RS -.PP -Impact: Medium --- pause time depends on number of loaded classes -.PP -\f[I]arguments\f[R]: -.IP \[bu] 2 -\f[I]subcmd\f[R]: must be either \f[V]static_dump\f[R] or -\f[V]dynamic_dump\f[R] (STRING, no default value) -.IP \[bu] 2 -\f[I]filename\f[R]: (Optional) Name of the shared archive to be dumped. -If %p is specified in the filename, it is expanded to the JVM\[aq]s PID. -(FILE, \[dq]java_pid%p_<subcmd>.jsa\[dq]) -.PP -If \f[V]dynamic_dump\f[R] is specified, the target JVM must be started -with the JVM option \f[V]-XX:+RecordDynamicDumpInfo\f[R]. -.RE -.TP -\f[V]VM.class_hierarchy\f[R] [\f[I]options\f[R]] [\f[I]arguments\f[R]] -Print a list of all loaded classes, indented to show the class -hierarchy. -The name of each class is followed by the ClassLoaderData* of its -ClassLoader, or \[dq]null\[dq] if it is loaded by the bootstrap class -loader. -.RS -.PP -Impact: Medium --- depends on the number of loaded classes. -.PP -\f[B]Note:\f[R] -.PP -The following \f[I]options\f[R] must be specified using either -\f[I]key\f[R] or \f[I]key\f[R]\f[V]=\f[R]\f[I]value\f[R] syntax. -.PP -\f[I]options\f[R]: -.IP \[bu] 2 -\f[V]-i\f[R]: (Optional) Inherited interfaces should be printed. -(BOOLEAN, false) -.IP \[bu] 2 -\f[V]-s\f[R]: (Optional) If a classname is specified, print its -subclasses in addition to its superclasses. -Without this option only the superclasses will be printed. -(BOOLEAN, false) -.PP -\f[I]arguments\f[R]: -.IP \[bu] 2 -\f[I]classname\f[R]: (Optional) The name of the class whose hierarchy -should be printed. -If not specified, all class hierarchies are printed. -(STRING, no default value) -.RE -.TP -\f[V]VM.classes\f[R] [\f[I]options\f[R]] -Print all loaded classes -.RS -.PP -Impact: Medium: Depends on number of loaded classes. -.PP -The following \f[I]options\f[R] must be specified using either -\f[I]key\f[R] or \f[I]key\f[R]\f[V]=\f[R]\f[I]value\f[R] syntax. -.PP -\f[I]options\f[R]: -.IP \[bu] 2 -\f[V]-verbose\f[R]: (Optional) Dump the detailed content of a Java -class. -Some classes are annotated with flags: \f[V]F\f[R] = has, or inherits, a -non-empty finalize method, \f[V]f\f[R] = has final method, \f[V]W\f[R] = -methods rewritten, \f[V]C\f[R] = marked with \f[V]\[at]Contended\f[R] -annotation, \f[V]R\f[R] = has been redefined, \f[V]S\f[R] = is shared -class (BOOLEAN, false) -.RE -.TP -\f[V]VM.classloader_stats\f[R] -Print statistics about all ClassLoaders. -.RS -.PP -Impact: Low -.RE -.TP -\f[V]VM.classloaders\f[R] [\f[I]options\f[R]] -Prints classloader hierarchy. -.RS -.PP -Impact: Medium --- Depends on number of class loaders and classes -loaded. -.PP -The following \f[I]options\f[R] must be specified using either -\f[I]key\f[R] or \f[I]key\f[R]\f[V]=\f[R]\f[I]value\f[R] syntax. -.PP -\f[I]options\f[R]: -.IP \[bu] 2 -\f[V]show-classes\f[R]: (Optional) Print loaded classes. -(BOOLEAN, false) -.IP \[bu] 2 -\f[V]verbose\f[R]: (Optional) Print detailed information. -(BOOLEAN, false) -.IP \[bu] 2 -\f[V]fold\f[R]: (Optional) Show loaders of the same name and class as -one. -(BOOLEAN, true) -.RE -.TP -\f[V]VM.command_line\f[R] -Print the command line used to start this VM instance. -.RS -.PP -Impact: Low -.RE -.TP -\f[V]VM.dynlibs\f[R] -Print loaded dynamic libraries. -.RS -.PP -Impact: Low -.RE -.TP -\f[V]VM.events\f[R] [\f[I]options\f[R]] -Print VM event logs -.RS -.PP -Impact: Low --- Depends on event log size. -.PP -\f[I]options\f[R]: -.PP -\f[B]Note:\f[R] -.PP -The following \f[I]options\f[R] must be specified using either -\f[I]key\f[R] or \f[I]key\f[R]\f[V]=\f[R]\f[I]value\f[R] syntax. -.IP \[bu] 2 -\f[V]log\f[R]: (Optional) Name of log to be printed. -If omitted, all logs are printed. -(STRING, no default value) -.IP \[bu] 2 -\f[V]max\f[R]: (Optional) Maximum number of events to be printed (newest -first). -If omitted, all events are printed. -(STRING, no default value) -.RE -.TP -\f[V]VM.flags\f[R] [\f[I]options\f[R]] -Print the VM flag options and their current values. -.RS -.PP -Impact: Low -.PP -\f[B]Note:\f[R] -.PP -The following \f[I]options\f[R] must be specified using either -\f[I]key\f[R] or \f[I]key\f[R]\f[V]=\f[R]\f[I]value\f[R] syntax. -.PP -\f[I]options\f[R]: -.IP \[bu] 2 -\f[V]-all\f[R]: (Optional) Prints all flags supported by the VM -(BOOLEAN, false). -.RE -.TP -\f[V]VM.info\f[R] -Print information about the JVM environment and status. -.RS -.PP -Impact: Low -.RE -.TP -\f[V]VM.log\f[R] [\f[I]options\f[R]] -Lists current log configuration, enables/disables/configures a log -output, or rotates all logs. -.RS -.PP -Impact: Low -.PP -\f[I]options\f[R]: -.PP -\f[B]Note:\f[R] -.PP -The following \f[I]options\f[R] must be specified using either -\f[I]key\f[R] or \f[I]key\f[R]\f[V]=\f[R]\f[I]value\f[R] syntax. -.IP \[bu] 2 -\f[V]output\f[R]: (Optional) The name or index (#) of output to -configure. -(STRING, no default value) -.IP \[bu] 2 -\f[V]output_options\f[R]: (Optional) Options for the output. -(STRING, no default value) -.IP \[bu] 2 -\f[V]what\f[R]: (Optional) Configures what tags to log. -(STRING, no default value ) -.IP \[bu] 2 -\f[V]decorators\f[R]: (Optional) Configures which decorators to use. -Use \[aq]none\[aq] or an empty value to remove all. -(STRING, no default value) -.IP \[bu] 2 -\f[V]disable\f[R]: (Optional) Turns off all logging and clears the log -configuration. -(BOOLEAN, no default value) -.IP \[bu] 2 -\f[V]list\f[R]: (Optional) Lists current log configuration. -(BOOLEAN, no default value) -.IP \[bu] 2 -\f[V]rotate\f[R]: (Optional) Rotates all logs. -(BOOLEAN, no default value) -.RE -.TP -\f[V]VM.metaspace\f[R] [\f[I]options\f[R]] -Prints the statistics for the metaspace -.RS -.PP -Impact: Medium --- Depends on number of classes loaded. -.PP -\f[B]Note:\f[R] -.PP -The following \f[I]options\f[R] must be specified using either -\f[I]key\f[R] or \f[I]key\f[R]\f[V]=\f[R]\f[I]value\f[R] syntax. -.PP -\f[I]options\f[R]: -.IP \[bu] 2 -\f[V]basic\f[R]: (Optional) Prints a basic summary (does not need a -safepoint). -(BOOLEAN, false) -.IP \[bu] 2 -\f[V]show-loaders\f[R]: (Optional) Shows usage by class loader. -(BOOLEAN, false) -.IP \[bu] 2 -\f[V]show-classes\f[R]: (Optional) If show-loaders is set, shows loaded -classes for each loader. -(BOOLEAN, false) -.IP \[bu] 2 -\f[V]by-chunktype\f[R]: (Optional) Break down numbers by chunk type. -(BOOLEAN, false) -.IP \[bu] 2 -\f[V]by-spacetype\f[R]: (Optional) Break down numbers by loader type. -(BOOLEAN, false) -.IP \[bu] 2 -\f[V]vslist\f[R]: (Optional) Shows details about the underlying virtual -space. -(BOOLEAN, false) -.IP \[bu] 2 -\f[V]chunkfreelist\f[R]: (Optional) Shows details about global chunk -free lists (ChunkManager). -(BOOLEAN, false) -.IP \[bu] 2 -\f[V]scale\f[R]: (Optional) Memory usage in which to scale. -Valid values are: 1, KB, MB or GB (fixed scale) or \[dq]dynamic\[dq] for -a dynamically chosen scale. -(STRING, dynamic) -.RE -.TP -\f[V]VM.native_memory\f[R] [\f[I]options\f[R]] -Print native memory usage -.RS -.PP -Impact: Medium -.PP -\f[B]Note:\f[R] -.PP -The following \f[I]options\f[R] must be specified using either -\f[I]key\f[R] or \f[I]key\f[R]\f[V]=\f[R]\f[I]value\f[R] syntax. -.PP -\f[I]options\f[R]: -.IP \[bu] 2 -\f[V]summary\f[R]: (Optional) Requests runtime to report current memory -summary, which includes total reserved and committed memory, along with -memory usage summary by each subsystem. -(BOOLEAN, false) -.IP \[bu] 2 -\f[V]detail\f[R]: (Optional) Requests runtime to report memory -allocation >= 1K by each callsite. -(BOOLEAN, false) -.IP \[bu] 2 -\f[V]baseline\f[R]: (Optional) Requests runtime to baseline current -memory usage, so it can be compared against in later time. -(BOOLEAN, false) -.IP \[bu] 2 -\f[V]summary.diff\f[R]: (Optional) Requests runtime to report memory -summary comparison against previous baseline. -(BOOLEAN, false) -.IP \[bu] 2 -\f[V]detail.diff\f[R]: (Optional) Requests runtime to report memory -detail comparison against previous baseline, which shows the memory -allocation activities at different callsites. -(BOOLEAN, false) -.IP \[bu] 2 -\f[V]statistics\f[R]: (Optional) Prints tracker statistics for tuning -purpose. -(BOOLEAN, false) -.IP \[bu] 2 -\f[V]scale\f[R]: (Optional) Memory usage in which scale, KB, MB or GB -(STRING, KB) -.RE -.TP -\f[V]VM.set_flag\f[R] [\f[I]arguments\f[R]] -Sets VM flag option using the provided value. -.RS -.PP -Impact: Low -.PP -\f[I]arguments\f[R]: -.IP \[bu] 2 -\f[I]flag name\f[R]: The name of the flag that you want to set (STRING, -no default value) -.IP \[bu] 2 -\f[I]string value\f[R]: (Optional) The value that you want to set -(STRING, no default value) -.RE -.TP -\f[V]VM.stringtable\f[R] [\f[I]options\f[R]] -Dump string table. -.RS -.PP -Impact: Medium --- depends on the Java content. -.PP -\f[B]Note:\f[R] -.PP -The following \f[I]options\f[R] must be specified using either -\f[I]key\f[R] or \f[I]key\f[R]\f[V]=\f[R]\f[I]value\f[R] syntax. -.PP -\f[I]options\f[R]: -.IP \[bu] 2 -\f[V]-verbose\f[R]: (Optional) Dumps the content of each string in the -table (BOOLEAN, false) -.RE -.TP -\f[V]VM.symboltable\f[R] [\f[I]options\f[R]] -Dump symbol table. -.RS -.PP -Impact: Medium --- depends on the Java content. -.PP -\f[B]Note:\f[R] -.PP -The following \f[I]options\f[R] must be specified using either -\f[I]key\f[R] or \f[I]key\f[R]\f[V]=\f[R]\f[I]value\f[R] syntax). -.PP -\f[I]options\f[R]: -.IP \[bu] 2 -\f[V]-verbose\f[R]: (Optional) Dumps the content of each symbol in the -table (BOOLEAN, false) -.RE -.TP -\f[V]VM.system_properties\f[R] -Print system properties. -.RS -.PP -Impact: Low -.RE -.TP -\f[V]VM.systemdictionary\f[R] -Prints the statistics for dictionary hashtable sizes and bucket length. -.RS -.PP -Impact: Medium -.PP -\f[B]Note:\f[R] -.PP -The following \f[I]options\f[R] must be specified using either -\f[I]key\f[R] or \f[I]key\f[R]\f[V]=\f[R]\f[I]value\f[R] syntax. -.PP -\f[I]options\f[R]: -.IP \[bu] 2 -\f[V]verbose\f[R]: (Optional) Dump the content of each dictionary entry -for all class loaders (BOOLEAN, false) . -.RE -.TP -\f[V]VM.uptime\f[R] [\f[I]options\f[R]] -Print VM uptime. -.RS -.PP -Impact: Low -.PP -\f[B]Note:\f[R] -.PP -The following \f[I]options\f[R] must be specified using either -\f[I]key\f[R] or \f[I]key\f[R]\f[V]=\f[R]\f[I]value\f[R] syntax. -.PP -\f[I]options\f[R]: -.IP \[bu] 2 -\f[V]-date\f[R]: (Optional) Adds a prefix with the current date -(BOOLEAN, false) -.RE -.TP -\f[V]VM.version\f[R] -Print JVM version information. -.RS -.PP -Impact: Low -.RE diff --git a/src/jdk.jcmd/share/man/jcmd.md b/src/jdk.jcmd/share/man/jcmd.md new file mode 100644 index 00000000000..448dfdd3051 --- /dev/null +++ b/src/jdk.jcmd/share/man/jcmd.md @@ -0,0 +1,1032 @@ +--- +# Copyright (c) 2012, 2024, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# This code is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 only, as +# published by the Free Software Foundation. +# +# This code is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# version 2 for more details (a copy is included in the LICENSE file that +# accompanied this code). +# +# You should have received a copy of the GNU General Public License version +# 2 along with this work; if not, write to the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +# or visit www.oracle.com if you need additional information or have any +# questions. +# + +title: 'JCMD(1) JDK @@VERSION_SHORT@@ | JDK Commands' +date: @@COPYRIGHT_YEAR@@ +lang: en +--- + +## Name + +jcmd - send diagnostic command requests to a running Java Virtual Machine +(JVM) + +## Synopsis + +`jcmd` \[*pid* \| *main-class*\] *command*... \| `PerfCounter.print` \| `-f` +*filename* + +`jcmd` \[`-l`\] + +`jcmd` `-h` + +*pid* +: When used, the `jcmd` utility sends the diagnostic command request to the + process ID for the Java process. + +*main-class* +: When used, the `jcmd` utility sends the diagnostic command request to all + Java processes with the specified name of the main class. + +*command* +: The `command` must be a valid `jcmd` command for the selected JVM. The list + of available commands for `jcmd` is obtained by running the `help` command + (`jcmd` *pid* `help`) where *pid* is the process ID for the running Java + process. + +`Perfcounter.print` +: Prints the performance counters exposed by the specified Java process. + +`-f` *filename* +: Reads and executes commands from a specified file, *filename*. + +`-l` +: Displays the list of Java Virtual Machine process identifiers that are not + running in a separate docker process along with the main class and + command-line arguments that were used to launch the process. If the JVM is + in a docker process, you must use tools such as `ps` to look up the PID. + + **Note:** + + Using `jcmd` without arguments is the same as using `jcmd -l`. + +`-h` +: Displays the `jcmd` utility's command-line help. + +## Description + +The `jcmd` utility is used to send diagnostic command requests to the JVM. It +must be used on the same machine on which the JVM is running, and have the same +effective user and group identifiers that were used to launch the JVM. Each +diagnostic command has its own set of options and arguments. To display the description, +syntax, and a list of available options and arguments for a diagnostic command, use the +name of the command as the argument. For example: + +> `jcmd` *pid* `help` *command* + +If arguments contain spaces, then you must surround them with single or double +quotation marks (`'` or `"`). In addition, you must escape single or double +quotation marks with a backslash (`\`) to prevent the operating system shell +from processing quotation marks. Alternatively, you can surround these +arguments with single quotation marks and then with double quotation marks (or +with double quotation marks and then with single quotation marks). + +If you specify the process identifier (*pid*) or the main class (*main-class*) +as the first argument, then the `jcmd` utility sends the diagnostic command +request to the Java process with the specified identifier or to all Java +processes with the specified name of the main class. You can also send the +diagnostic command request to all available Java processes by specifying `0` as +the process identifier. + +## Commands for jcmd + +The *command* must be a valid `jcmd` diagnostic command for the selected JVM. +The list of available commands for `jcmd` is obtained by running the `help` +command (`jcmd` *pid* `help`) where *pid* is the process ID for a running Java +process. If the *pid* is `0`, commands will be sent to all Java processes. The +main class argument will be used to match, either partially or fully, the class +used to start Java. If no options are given, it lists the running Java process +identifiers that are not in separate docker processes along with the main class +and command-line arguments that were used to launch the process (the same as +using `-l`). + +`jcmd` *commands* may take options and arguments. *Options* are specified using +either *key* or *key*`=`*value* syntax. *Arguments* are given as just a value, +never name=value. + + +The following commands are available: + +`help` \[*options*\] \[*arguments*\] +: For more information about a specific command. + + *arguments*: + + - *command name*: The name of the command for which we want help (STRING, + no default value) + + **Note:** + + The following *options* must be specified using either *key* or + *key*`=`*value* syntax. + + *options*: + + - `-all`: (Optional) Show help for all commands (BOOLEAN, false) . + +`Compiler.CodeHeap_Analytics` \[*function*\] \[*granularity*\] +: Print CodeHeap analytics + + Impact: Low: Depends on code heap size and content. Holds CodeCache_lock during analysis step, usually sub-second duration. + + *arguments*: + + - *function*: (Optional) Function to be performed (aggregate, UsedSpace, FreeSpace, MethodCount, MethodSpace, MethodAge, MethodNames, discard (STRING, all) + + - *granularity*: (Optional) Detail level - smaller value -> more detail (INT, 4096) + +`Compiler.codecache` +: Prints code cache layout and bounds. + + Impact: Low + +`Compiler.codelist` +: Prints all compiled methods in code cache that are alive. + + Impact: Medium + +`Compiler.directives_add` *arguments* +: Adds compiler directives from a file. + + Impact: Low + + *arguments*: + + - *filename*: The name of the directives file (STRING, no default value) + +`Compiler.directives_clear` +: Remove all compiler directives. + + Impact: Low + +`Compiler.directives_print` +: Prints all active compiler directives. + + Impact: Low + +`Compiler.directives_remove` +: Remove latest added compiler directive. + + Impact: Low + +`Compiler.memory` \[*options*\] +: Print compilation footprint + + Impact: Medium: Pause time depends on number of compiled methods + + **Note:** + + The *options* must be specified using either *key* or *key*`=`*value* + syntax. + + *options*: + + - `-H`: (Optional) Human readable format (BOOLEAN, false) + - `-s`: (Optional) Minimum memory size (MEMORY SIZE, 0) + +`Compiler.perfmap` \[*arguments*\] (Linux only) +: Write map file for Linux perf tool. + + Impact: Low + + *arguments*: + + - *filename*: (Optional) The name of the map file. If %p is specified in the filename, it is expanded to the JVM's PID. (FILE, "/tmp/perf-%p.map") + +`Compiler.queue` +: Prints methods queued for compilation. + + Impact: Low + +`GC.class_histogram` \[*options*\] +: Provides statistics about the Java heap usage. + + Impact: High --- depends on Java heap size and content. + + **Note:** + + The *options* must be specified using either *key* or *key*`=`*value* + syntax. + + *options*: + + - `-all`: (Optional) Inspects all objects, including unreachable objects + (BOOLEAN, false) + - `-parallel`: (Optional) Number of parallel threads to use for heap inspection. + 0 (the default) means let the VM determine the number of threads to use. + 1 means use one thread (disable parallelism). For any other value the VM will + try to use the specified number of threads, but might use fewer. (INT, 0) + +`GC.finalizer_info` +: Provides information about the Java finalization queue. + + Impact: Medium + +`GC.heap_dump` \[*options*\] *filename* +: Generates a HPROF format dump of the Java heap. + + Impact: High --- depends on the Java heap size and content. Request a full + GC unless the `-all` option is specified. + + **Note:** + + The following *options* must be specified using either *key* or + *key*`=`*value* syntax. + + *options*: + + - `-all`: (Optional) Dump all objects, including unreachable objects + (BOOLEAN, false) + - `-gz`: (Optional) If specified, the heap dump is written in gzipped format + using the given compression level. 1 (recommended) is the fastest, 9 the + strongest compression. (INT, 1) + - `-overwrite`: (Optional) If specified, the dump file will be overwritten if + it exists (BOOLEAN, false) + - `-parallel`: (Optional) Number of parallel threads to use for heap dump. The VM will try to use the specified number of threads, but might use fewer. (INT, 1) + + *arguments*: + + - *filename*: The name of the dump file. If %p is specified in the filename, it is expanded to the JVM's PID. (FILE, no default value) + +`GC.heap_info` +: Provides generic Java heap information. + + Impact: Medium + +`GC.run` +: Calls `java.lang.System.gc()`. + + Impact: Medium --- depends on the Java heap size and content. + +`GC.run_finalization` +: Calls `java.lang.System.runFinalization()`. + + Impact: Medium --- depends on the Java content. + +`JFR.check` \[*options*\] +: Show information about a running flight recording + + Impact: Low + + **Note:** + + The *options* must be specified using either *key* or *key*`=`*value* + syntax. If no parameters are entered, information for all active recordings is shown. + + *options*: + + - `name`: (Optional) Name of the flight recording. (STRING, no default value) + + - `verbose`: (Optional) Flag for printing the event settings for the recording + (BOOLEAN, false) + +`JFR.configure` \[*options*\] +: Set the parameters for a flight recording + + Impact: Low + + **Note:** + + The *options* must be specified using either *key* or *key*`=`*value* + syntax. If no parameters are entered, the current settings are displayed. + + *options*: + + - `dumppath`: (Optional) Path to the location where a recording file is written + in case the VM runs into a critical error, such as a system + crash. (STRING, The default location is the current directory) + + - `globalbuffercount`: (Optional) Number of global buffers. This option is + a legacy option: change the `memorysize` parameter to alter the number of + global buffers. This value cannot be changed once JFR has been initialized. + (STRING, default determined by the value for `memorysize`) + + - `globalbuffersize`: (Optional) Size of the global buffers, in bytes. This + option is a legacy option: change the `memorysize` parameter to alter + the size of the global buffers. This value cannot be changed once JFR + has been initialized. (STRING, default determined by the value for `memorysize`) + + - `maxchunksize`: (Optional) Maximum size of an individual data chunk in bytes + if one of the following suffixes is not used: 'm' or 'M' for megabytes OR + 'g' or 'G' for gigabytes. This value cannot be changed once JFR has been + initialized. (STRING, 12M) + + - `memorysize`: (Optional) Overall memory size, in bytes if one of the following + suffixes is not used: 'm' or 'M' for megabytes OR 'g' or 'G' for gigabytes. + This value cannot be changed once JFR has been initialized. (STRING, 10M) + + - `repositorypath`: (Optional) Path to the location where recordings are stored + until they are written to a permanent file. (STRING, The default location is + the temporary directory for the operating system. On Linux operating systems, + the temporary directory is `/tmp`. On Windwows, the temporary directory is + specified by the `TMP` environment variable.) + + - `preserve-repository=`{`true`\|`false`} : Specifies whether files stored in + the disk repository should be kept after the JVM has exited. If false, files + are deleted. By default, this parameter is disabled. + + - `stackdepth`: (Optional) Stack depth for stack traces. Setting this value + greater than the default of 64 may cause a performance degradation. + This value cannot be changed once JFR has been initialized. (LONG, 64) + + - `thread_buffer_size`: (Optional) Local buffer size for each thread in bytes if one + of the following suffixes is not used: 'k' or 'K' for kilobytes or 'm' or 'M' + for megabytes. Overriding this parameter could reduce performance and is + not recommended. This value cannot be changed once JFR has been initialized. + (STRING, 8k) + + - `samplethreads`: (Optional) Flag for activating thread sampling. (BOOLEAN, true) + +`JFR.dump` \[*options*\] +: Write data to a file while a flight recording is running + + Impact: Low + + **Note:** + + The *options* must be specified using either *key* or *key*`=`*value* syntax. + No options are required. The recording continues to run after the data is written. + + *options*: + + - `begin`: (Optional) Specify the time from which recording data will be included + in the dump file. The format is specified as local time. (STRING, no default value) + + - `end`: (Optional) Specify the time to which recording data will be included in the + dump file. The format is specified as local time. (STRING, no default value) + + **Note:** For both `begin` and `end`, the time must be in a format that can be read + by java.time.LocalTime::parse(STRING), java.time.LocalDateTime::parse(STRING) + or java.time.Instant::parse(STRING). For example, "13:20:15", "2020-03-17T09:00:00" + or "2020-03-17T09:00:00Z". + + **Note:** `begin` and `end` times correspond to the timestamps found within the recorded + information in the flight recording data. + + Another option is to use a time relative to the current time that is specified + by a negative integer followed by "s", "m" or "h". For example, "-12h", "-15m" or "-30s" + + - `filename`: (Optional) Name of the file to which the flight recording data + is dumped. If no filename is given, a filename is generated from the PID and + the current date. The filename may also be a directory in which case, the filename + is generated from the PID and the current date in the specified directory. + If %p and/or %t is specified in the filename, it expands to the JVM's PID and + the current timestamp, respectively. + (FILE, no default value) + + - `maxage`: (Optional) Length of time for dumping the flight recording data + to a file. (INTEGER followed by 's' for seconds 'm' for minutes or 'h' for hours, + no default value) + + - `maxsize`: (Optional) Maximum size for the amount of data to dump from a flight + recording in bytes if one of the following suffixes is not used: 'm' or 'M' for megabytes + OR 'g' or 'G' for gigabytes. (STRING, no default value) + + - `name`: (Optional) Name of the recording. If no name is given, data + from all recordings is dumped. (STRING, no default value) + + - `path-to-gc-roots`: (Optional) Flag for saving the path to garbage collection (GC) + roots at the time the recording data is dumped. The path information is useful for + finding memory leaks but collecting it can cause the application to pause for + a short period of time. Turn on this flag only when you have an application + that you suspect has a memory leak. (BOOLEAN, false) + +`JFR.start` \[*options*\] +: Start a flight recording + + Impact: Low + + **Note:** + + The *options* must be specified using either *key* or *key*`=`*value* + syntax. If no parameters are entered, then a recording is started with default values. + + *options*: + + - `delay`: (Optional) Length of time to wait before starting to record + (INTEGER followed by 's' for seconds 'm' for minutes or 'h' for hours, 0s) + + - `disk`: (Optional) Flag for also writing the data to disk while recording + (BOOLEAN, true) + + - `dumponexit`: (Optional) Flag for writing the recording to disk when the + Java Virtual Machine (JVM) shuts down. If set to 'true' and no value is given + for `filename`, the recording is written to a file in the directory where + the process was started. The file name is a system-generated name that + contains the process ID, the recording ID and the current time stamp. + (For example: `id-1-2019_12_12_10_41.jfr`) (BOOLEAN, false) + + - `duration`: (Optional) Length of time to record. Note that `0s` means forever + (INTEGER followed by 's' for seconds 'm' for minutes or 'h' for hours, 0s) + + - `filename`: (Optional) Name of the file to which the flight recording data + is written when the recording is stopped. If no filename is given, a filename + is generated from the PID and the current date and is placed in the directory + where the process was started. The filename may also be a directory in which case, + the filename is generated from the PID and the current date in the specified directory. + If %p and/or %t is specified in the filename, it expands to the JVM's PID + and the current timestamp, respectively. + (FILE, no default value) + + - `maxage`: (Optional) Maximum time to keep the recorded data on disk. This + parameter is valid only when the `disk` parameter is set to `true`. Note + `0s` means forever. (INTEGER followed by 's' for seconds 'm' + for minutes or 'h' for hours, 0s) + + - `maxsize`: (Optional) Maximum size of the data to keep on disk in bytes if one + of the following suffixes is not used: 'm' or 'M' for megabytes OR 'g' or 'G' for gigabytes. + This parameter is valid only when the `disk` parameter is set to 'true'. The value must + not be less than the value for the `maxchunksize` parameter set with the `JFR.configure` command. + (STRING, 0 (no maximum size)) + + - `name`: (Optional) Name of the recording. If no name is provided, a name is generated. + Make note of the generated name that is shown in the response to the command so that + you can use it with other commands. (STRING, system-generated default name) + + - `path-to-gc-roots`: (Optional) Flag for saving the path to garbage collection (GC) + roots at the end of a recording. The path information is useful for finding memory leaks + but collecting it is time consuming. Turn on this flag only when you + have an application that you suspect has a memory leak. If the `settings` parameter + is set to 'profile', then the information collected includes the stack trace + from where the potential leaking object was allocated. (BOOLEAN, false) + + - `settings`: (Optional) Name of the settings file that identifies which events to record. + To specify more than one file, separate the names with a comma (','). Include the path + if the file is not in `JAVA-HOME`/lib/jfr. The following profiles are included with + the JDK in the `JAVA-HOME`/lib/jfr directory: 'default.jfc': collects a predefined set + of information with low overhead, so it has minimal impact on performance and can be + used with recordings that run continuously; 'profile.jfc': Provides more data than the + 'default.jfc' profile, but with more overhead and impact on performance. Use this + configuration for short periods of time when more information is needed. Use `none` to + start a recording without a predefined configuration file. + (STRING, `JAVA-HOME`/lib/jfr/default.jfc) + + Event settings and .jfc options can be specified using the following syntax: + + - `option`: (Optional) Specifies the option value to modify. To list available + options, use the `JAVA_HOME`/bin/jfr tool. + + - `event-setting`: (Optional) Specifies the event setting value to modify. Use the form: + `<event-name>#<setting-name>=<value>` + To add a new event setting, prefix the event name with '+'. + + You can specify values for multiple event settings and .jfc options by + separating them with a whitespace. In case of a conflict between a parameter + and a .jfc option, the parameter will take precedence. The whitespace + delimiter can be omitted for timespan values, i.e. 20ms. For more + information about the settings syntax, see Javadoc of the jdk.jfr + package. + +`JFR.stop` \[*options*\] +: Stop a flight recording + + Impact: Low + + **Note:** + + The *options* must be specified using either *key* or *key*`=`*value* + syntax. If no parameters are entered, then no recording is stopped. + + *options*: + + - `filename`: (Optional) Name of the file to which the recording is + written when the recording is stopped. If %p and/or %t is specified + in the filename, it expands to the JVM's PID and the current + timestamp, respectively. If no path is provided, the data from the + recording is discarded. (FILE, no default value) + + - `name`: (Optional) Name of the recording (STRING, no default value) + + +`JFR.view` \[*options*\] +: Display event data in predefined views. + + Impact: Medium + + **Note:** + + The *options* must be specified using either *key* or *key*`=`*value* + syntax. If no parameters are entered, then a list of available views + are displayed. + + *options*: + + - `cell-height`: (Optional) Maximum number of rows in a table cell. + (INT, default value depends on the view) + + - `maxage`: (Optional) Length of time for the view to span. + (INT followed by 's' for seconds 'm' for minutes or 'h' for hours, + default value is 10m) + + - `maxsize`: (Optional) Maximum size for the view to span in bytes if one + of the following suffixes is not used: 'm' or 'M' for megabytes OR + 'g' or 'G' for gigabytes. (STRING, default value is 32MB) + + - `truncate`: (Optional) Maximum number of rows in a table cell. + (INT, default value depends on the view) + + - `verbose`: (Optional) Displays the query that makes up the view. + (BOOLEAN, default value is false) + + - `width`: (Optional) The width of the view in characters. (INT, + default value depends on the view) + + *arguments*: + + - `view`: Name of the view or event type to display. Use `help JFR.view` + to see a list of available views. (STRING, no default value) + + The view parameter can be an event type name. Use `JFR.view types` to see + a list. To display all views, use `JFR.view all-views`. To display all + events, use `JFR.view all-events`. + +`JVMTI.agent_load` \[*arguments*\] +: Loads JVMTI native agent. + + Impact: Low + + *arguments*: + + - *library path*: Absolute path of the JVMTI agent to load. (STRING, no + default value) + + - *agent option*: (Optional) Option string to pass the agent. (STRING, no + default value) + +`JVMTI.data_dump` +: Signal the JVM to do a data-dump request for JVMTI. + + Impact: High + +`ManagementAgent.start` \[*options*\] +: Starts remote management agent. + + Impact: Low --- no impact + + **Note:** + + The following *options* must be specified using either *key* or + *key*`=`*value* syntax. + + *options*: + + - `config.file`: (Optional) Sets `com.sun.management.config.file` + (STRING, no default value) + + - `jmxremote.host`: (Optional) Sets `com.sun.management.jmxremote.host` + (STRING, no default value) + + - `jmxremote.port`: (Optional) Sets `com.sun.management.jmxremote.port` + (STRING, no default value) + + - `jmxremote.rmi.port`: (Optional) Sets + `com.sun.management.jmxremote.rmi.port` (STRING, no default value) + + - `jmxremote.ssl`: (Optional) Sets `com.sun.management.jmxremote.ssl` + (STRING, no default value) + + - `jmxremote.registry.ssl`: (Optional) Sets + `com.sun.management.jmxremote.registry.ssl` (STRING, no default value) + + - `jmxremote.authenticate`: (Optional) Sets + `com.sun.management.jmxremote.authenticate` (STRING, no default value) + + - jmxremote.password.file: (Optional) Sets + `com.sun.management.jmxremote.password.file` (STRING, no default value) + + - `jmxremote.access.file`: (Optional) Sets + `com.sun.management.jmxremote.acce ss.file` (STRING, no default value) + + - `jmxremote.login.config`: (Optional) Sets + `com.sun.management.jmxremote.log in.config` (STRING, no default value) + + - `jmxremote.ssl.enabled.cipher.suites`: (Optional) Sets + `com.sun.management`. + + - `jmxremote.ssl.enabled.cipher.suite`: (STRING, no default value) + + - `jmxremote.ssl.enabled.protocols`: (Optional) Sets + `com.sun.management.jmxr emote.ssl.enabled.protocols` (STRING, no + default value) + + - `jmxremote.ssl.need.client.auth`: (Optional) Sets + `com.sun.management.jmxre mote.need.client.auth` (STRING, no default + value) + + - `jmxremote.ssl.config.file`: (Optional) Sets + `com.sun.management.jmxremote. ssl_config_file` (STRING, no default + value) + + - `jmxremote.autodiscovery`: (Optional) Sets + `com.sun.management.jmxremote.au todiscovery` (STRING, no default + value) + + - `jdp.port`: (Optional) Sets `com.sun.management.jdp.port` (INT, no + default value) + + - `jdp.address`: (Optional) Sets `com.sun.management.jdp.address` + (STRING, no default value) + + - `jdp.source_addr`: (Optional) Sets `com.sun.management.jdp.source_addr` + (STRING, no default value) + + - `jdp.ttl`: (Optional) Sets `com.sun.management.jdp.ttl` (INT, no + default value) + + - `jdp.pause`: (Optional) Sets `com.sun.management.jdp.pause` (INT, no + default value) + + - `jdp.name`: (Optional) Sets `com.sun.management.jdp.name` (STRING, no + default value) + +`ManagementAgent.start_local` +: Starts the local management agent. + + Impact: Low --- no impact + +`ManagementAgent.status` +: Print the management agent status. + + Impact: Low --- no impact + +`ManagementAgent.stop` +: Stops the remote management agent. + + Impact: Low --- no impact + +`System.dump_map` \[*options*\] (Linux only) +: Dumps an annotated process memory map to an output file. + + Impact: Low + + **Note:** + + The following *options* must be specified using either *key* or + *key*`=`*value* syntax. + + *options*: + + - `-H`: (Optional) Human readable format (BOOLEAN, false) + - `-F`: (Optional) File path. If %p is specified in the filename, it is expanded to the JVM's PID. (FILE, "vm_memory_map_%p.txt") + +`System.map` \[*options*\] (Linux only) +: Prints an annotated process memory map of the VM process. + + Impact: Low + + **Note:** + + The following *options* must be specified using either *key* or + *key*`=`*value* syntax. + + *options*: + + - `-H`: (Optional) Human readable format (BOOLEAN, false) + +`System.native_heap_info` (Linux only) +: Attempts to output information regarding native heap usage through malloc_info(3). If unsuccessful outputs "Error: " and a reason. + + Impact: Low + +`System.trim_native_heap` (Linux only) +: Attempts to free up memory by trimming the C-heap. + + Impact: Low + +`Thread.dump_to_file` \[*options*\] *filepath* +: Dump threads, with stack traces, to a file in plain text or JSON format. + + Impact: Medium: Depends on the number of threads. + + **Note:** + + The following *options* must be specified using either *key* or + *key*`=`*value* syntax. + + *options*: + + - `-overwrite`: (Optional) May overwrite existing file (BOOLEAN, false) + - `-format`: (Optional) Output format ("plain" or "json") (STRING, plain) + + *arguments*: + + - *filepath*: The file path to the output file. If %p is specified in the filename, it is expanded to the JVM's PID. (FILE, no default value) + +`Thread.print` \[*options*\] +: Prints all threads with stacktraces. + + Impact: Medium --- depends on the number of threads. + + **Note:** + + The following *options* must be specified using either *key* or + *key*`=`*value* syntax. + + *options*: + + - `-e`: (Optional) Print extended thread information (BOOLEAN, false) + - `-l`: (Optional) Prints `java.util.concurrent` locks (BOOLEAN, false) + +`VM.cds` \[*arguments*\] +: Dump a static or dynamic shared archive that includes all currently loaded classes. + + Impact: Medium --- pause time depends on number of loaded classes + + *arguments*: + + - *subcmd*: must be either `static_dump` or `dynamic_dump` (STRING, no default value) + - *filename*: (Optional) Name of the shared archive to be dumped. If %p is specified in the filename, it is expanded to the JVM's PID. (FILE, "java_pid%p_\<subcmd\>.jsa") + + If `dynamic_dump` is specified, the target JVM must be started with the JVM option + `-XX:+RecordDynamicDumpInfo`. + +`VM.class_hierarchy` \[*options*\] \[*arguments*\] +: Print a list of all loaded classes, indented to show the class hierarchy. + The name of each class is followed by the ClassLoaderData\* of its + ClassLoader, or "null" if it is loaded by the bootstrap class loader. + + Impact: Medium --- depends on the number of loaded classes. + + **Note:** + + The following *options* must be specified using either *key* or + *key*`=`*value* syntax. + + *options*: + + - `-i`: (Optional) Inherited interfaces should be printed. (BOOLEAN, + false) + + - `-s`: (Optional) If a classname is specified, print its subclasses + in addition to its superclasses. Without this option only the + superclasses will be printed. (BOOLEAN, false) + + *arguments*: + + - *classname*: (Optional) The name of the class whose hierarchy should be + printed. If not specified, all class hierarchies are printed. (STRING, + no default value) + +`VM.classes` \[*options*\] +: Print all loaded classes + + Impact: Medium: Depends on number of loaded classes. + + The following *options* must be specified using either *key* or + *key*`=`*value* syntax. + + *options*: + + - `-verbose`: (Optional) Dump the detailed content of a Java class. + Some classes are annotated with flags: `F` = has, or inherits, a non-empty finalize method, + `f` = has final method, `W` = methods rewritten, `C` = marked with `@Contended` annotation, + `R` = has been redefined, `S` = is shared class (BOOLEAN, false) + +`VM.classloader_stats` +: Print statistics about all ClassLoaders. + + Impact: Low + +`VM.classloaders` \[*options*\] +: Prints classloader hierarchy. + + Impact: Medium --- Depends on number of class loaders and classes loaded. + + The following *options* must be specified using either *key* or + *key*`=`*value* syntax. + + *options*: + + - `show-classes`: (Optional) Print loaded classes. (BOOLEAN, false) + - `verbose`: (Optional) Print detailed information. (BOOLEAN, false) + - `fold`: (Optional) Show loaders of the same name and class as one. (BOOLEAN, true) + +`VM.command_line` +: Print the command line used to start this VM instance. + + Impact: Low + +`VM.dynlibs` +: Print loaded dynamic libraries. + + Impact: Low + +`VM.events` \[*options*\] +: Print VM event logs + + Impact: Low --- Depends on event log size. + + *options*: + + **Note:** + + The following *options* must be specified using either *key* or + *key*`=`*value* syntax. + + - `log`: (Optional) Name of log to be printed. + If omitted, all logs are printed. (STRING, no default value) + - `max`: (Optional) Maximum number of events to be printed (newest first). + If omitted, all events are printed. (STRING, no default value) + +`VM.flags` \[*options*\] +: Print the VM flag options and their current values. + + Impact: Low + + **Note:** + + The following *options* must be specified using either *key* or + *key*`=`*value* syntax. + + *options*: + + - `-all`: (Optional) Prints all flags supported by the VM (BOOLEAN, + false). + +`VM.info` +: Print information about the JVM environment and status. + + Impact: Low + +`VM.log` \[*options*\] +: Lists current log configuration, enables/disables/configures a log output, + or rotates all logs. + + Impact: Low + + *options*: + + **Note:** + + The following *options* must be specified using either *key* or + *key*`=`*value* syntax. + + - `output`: (Optional) The name or index (\#) of output to configure. + (STRING, no default value) + + - `output_options`: (Optional) Options for the output. (STRING, no + default value) + + - `what`: (Optional) Configures what tags to log. (STRING, no default + value ) + + - `decorators`: (Optional) Configures which decorators to use. Use 'none' + or an empty value to remove all. (STRING, no default value) + + - `disable`: (Optional) Turns off all logging and clears the log + configuration. (BOOLEAN, no default value) + + - `list`: (Optional) Lists current log configuration. (BOOLEAN, no + default value) + + - `rotate`: (Optional) Rotates all logs. (BOOLEAN, no default value) + +`VM.metaspace` \[*options*\] +: Prints the statistics for the metaspace + + Impact: Medium --- Depends on number of classes loaded. + + **Note:** + + The following *options* must be specified using either *key* or + *key*`=`*value* syntax. + + *options*: + + - `basic`: (Optional) Prints a basic summary (does not need a safepoint). (BOOLEAN, false) + - `show-loaders`: (Optional) Shows usage by class loader. (BOOLEAN, false) + - `show-classes`: (Optional) If show-loaders is set, shows loaded classes for each loader. (BOOLEAN, false) + - `by-chunktype`: (Optional) Break down numbers by chunk type. (BOOLEAN, false) + - `by-spacetype`: (Optional) Break down numbers by loader type. (BOOLEAN, false) + - `vslist`: (Optional) Shows details about the underlying virtual space. (BOOLEAN, false) + - `chunkfreelist`: (Optional) Shows details about global chunk free lists (ChunkManager). (BOOLEAN, false) + - `scale`: (Optional) Memory usage in which to scale. Valid values are: 1, KB, MB + or GB (fixed scale) or "dynamic" for a dynamically chosen scale. (STRING, dynamic) + +`VM.native_memory` \[*options*\] +: Print native memory usage + + Impact: Medium + + **Note:** + + The following *options* must be specified using either *key* or + *key*`=`*value* syntax. + + *options*: + + - `summary`: (Optional) Requests runtime to report current memory + summary, which includes total reserved and committed memory, along with + memory usage summary by each subsystem. (BOOLEAN, false) + + - `detail`: (Optional) Requests runtime to report memory allocation >= + 1K by each callsite. (BOOLEAN, false) + + - `baseline`: (Optional) Requests runtime to baseline current memory + usage, so it can be compared against in later time. (BOOLEAN, false) + + - `summary.diff`: (Optional) Requests runtime to report memory summary + comparison against previous baseline. (BOOLEAN, false) + + - `detail.diff`: (Optional) Requests runtime to report memory detail + comparison against previous baseline, which shows the memory allocation + activities at different callsites. (BOOLEAN, false) + + - `statistics`: (Optional) Prints tracker statistics for tuning purpose. + (BOOLEAN, false) + + - `scale`: (Optional) Memory usage in which scale, KB, MB or GB (STRING, + KB) + +`VM.set_flag` \[*arguments*\] +: Sets VM flag option using the provided value. + + Impact: Low + + *arguments*: + + - *flag name*: The name of the flag that you want to set (STRING, no + default value) + + - *string value*: (Optional) The value that you want to set (STRING, no + default value) + +`VM.stringtable` \[*options*\] +: Dump string table. + + Impact: Medium --- depends on the Java content. + + **Note:** + + The following *options* must be specified using either *key* or + *key*`=`*value* syntax. + + *options*: + + - `-verbose`: (Optional) Dumps the content of each string in the table + (BOOLEAN, false) + +`VM.symboltable` \[*options*\] +: Dump symbol table. + + Impact: Medium --- depends on the Java content. + + **Note:** + + The following *options* must be specified using either *key* or + *key*`=`*value* syntax). + + *options*: + + - `-verbose`: (Optional) Dumps the content of each symbol in the table + (BOOLEAN, false) + +`VM.system_properties` +: Print system properties. + + Impact: Low + +`VM.systemdictionary` +: Prints the statistics for dictionary hashtable sizes and bucket length. + + Impact: Medium + + **Note:** + + The following *options* must be specified using either *key* or + *key*`=`*value* syntax. + + *options*: + + - `verbose`: (Optional) Dump the content of each dictionary entry for all + class loaders (BOOLEAN, false) . + +`VM.uptime` \[*options*\] +: Print VM uptime. + + Impact: Low + + **Note:** + + The following *options* must be specified using either *key* or + *key*`=`*value* syntax. + + *options*: + + - `-date`: (Optional) Adds a prefix with the current date (BOOLEAN, + false) + +`VM.version` +: Print JVM version information. + + Impact: Low diff --git a/src/jdk.jcmd/share/man/jinfo.1 b/src/jdk.jcmd/share/man/jinfo.1 deleted file mode 100644 index 49d8a852633..00000000000 --- a/src/jdk.jcmd/share/man/jinfo.1 +++ /dev/null @@ -1,103 +0,0 @@ -.\" Copyright (c) 2004, 2018, Oracle and/or its affiliates. All rights reserved. -.\" DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -.\" -.\" This code is free software; you can redistribute it and/or modify it -.\" under the terms of the GNU General Public License version 2 only, as -.\" published by the Free Software Foundation. -.\" -.\" This code is distributed in the hope that it will be useful, but WITHOUT -.\" ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -.\" FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -.\" version 2 for more details (a copy is included in the LICENSE file that -.\" accompanied this code). -.\" -.\" You should have received a copy of the GNU General Public License version -.\" 2 along with this work; if not, write to the Free Software Foundation, -.\" Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -.\" -.\" Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -.\" or visit www.oracle.com if you need additional information or have any -.\" questions. -.\" -.\" Automatically generated by Pandoc 2.19.2 -.\" -.\" Define V font for inline verbatim, using C font in formats -.\" that render this, and otherwise B font. -.ie "\f[CB]x\f[R]"x" \{\ -. ftr V B -. ftr VI BI -. ftr VB B -. ftr VBI BI -.\} -.el \{\ -. ftr V CR -. ftr VI CI -. ftr VB CB -. ftr VBI CBI -.\} -.TH "JINFO" "1" "2025" "JDK 24-ea" "JDK Commands" -.hy -.SH NAME -.PP -jinfo - generate Java configuration information for a specified Java -process -.SH SYNOPSIS -.PP -\f[B]Note:\f[R] This command is experimental and unsupported. -.PP -\f[V]jinfo\f[R] [\f[I]option\f[R]] \f[I]pid\f[R] -.TP -\f[I]option\f[R] -This represents the \f[V]jinfo\f[R] command-line options. -See \f[B]Options for the jinfo Command\f[R]. -.TP -\f[I]pid\f[R] -The process ID for which the configuration information is to be printed. -The process must be a Java process. -To get a list of Java processes running on a machine, use either the -\f[V]ps\f[R] command or, if the JVM processes are not running in a -separate docker instance, the \f[B]jps\f[R] command. -.SH DESCRIPTION -.PP -The \f[V]jinfo\f[R] command prints Java configuration information for a -specified Java process. -The configuration information includes Java system properties and JVM -command-line flags. -If the specified process is running on a 64-bit JVM, then you might need -to specify the \f[V]-J-d64\f[R] option, for example: -.RS -.PP -\f[V]jinfo -J-d64 -sysprops\f[R] \f[I]pid\f[R] -.RE -.PP -This command is unsupported and might not be available in future -releases of the JDK. -In Windows Systems where \f[V]dbgeng.dll\f[R] is not present, the -Debugging Tools for Windows must be installed to have these tools work. -The \f[V]PATH\f[R] environment variable should contain the location of -the \f[V]jvm.dll\f[R] that\[aq]s used by the target process or the -location from which the core dump file was produced. -.SH OPTIONS FOR THE JINFO COMMAND -.PP -\f[B]Note:\f[R] -.PP -If none of the following options are used, both the command-line flags -and the system property name-value pairs are printed. -.TP -\f[V]-flag\f[R] \f[I]name\f[R] -Prints the name and value of the specified command-line flag. -.TP -\f[V]-flag\f[R] [\f[V]+\f[R]|\f[V]-\f[R]]\f[I]name\f[R] -Enables or disables the specified Boolean command-line flag. -.TP -\f[V]-flag\f[R] \f[I]name\f[R]\f[V]=\f[R]\f[I]value\f[R] -Sets the specified command-line flag to the specified value. -.TP -\f[V]-flags\f[R] -Prints command-line flags passed to the JVM. -.TP -\f[V]-sysprops\f[R] -Prints Java system properties as name-value pairs. -.TP -\f[V]-h\f[R] or \f[V]-help\f[R] -Prints a help message. diff --git a/src/jdk.jcmd/share/man/jinfo.md b/src/jdk.jcmd/share/man/jinfo.md new file mode 100644 index 00000000000..5e8603e0e08 --- /dev/null +++ b/src/jdk.jcmd/share/man/jinfo.md @@ -0,0 +1,88 @@ +--- +# Copyright (c) 2004, 2018, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# This code is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 only, as +# published by the Free Software Foundation. +# +# This code is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# version 2 for more details (a copy is included in the LICENSE file that +# accompanied this code). +# +# You should have received a copy of the GNU General Public License version +# 2 along with this work; if not, write to the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +# or visit www.oracle.com if you need additional information or have any +# questions. +# + +title: 'JINFO(1) JDK @@VERSION_SHORT@@ | JDK Commands' +date: @@COPYRIGHT_YEAR@@ +lang: en +--- + +## Name + +jinfo - generate Java configuration information for a specified Java process + +## Synopsis + +**Note:** This command is experimental and unsupported. + +`jinfo` \[*option*\] *pid* + +*option* +: This represents the `jinfo` command-line options. See [Options for the + jinfo Command]. + +*pid* +: The process ID for which the configuration information is to be printed. + The process must be a Java process. To get a list of Java processes running + on a machine, use either the `ps` command or, if the JVM processes are not + running in a separate docker instance, the [jps](jps.html) command. + +## Description + +The `jinfo` command prints Java configuration information for a specified Java +process. The configuration information includes Java system properties and JVM +command-line flags. If the specified process is running on a 64-bit JVM, then +you might need to specify the `-J-d64` option, for example: + +> `jinfo -J-d64 -sysprops` *pid* + +This command is unsupported and might not be available in future releases of +the JDK. In Windows Systems where `dbgeng.dll` is not present, the Debugging +Tools for Windows must be installed to have these tools work. The `PATH` +environment variable should contain the location of the `jvm.dll` that's used +by the target process or the location from which the core dump file was +produced. + +## Options for the jinfo Command + +**Note:** + +If none of the following options are used, both the command-line flags and the +system property name-value pairs are printed. + +`-flag` *name* +: Prints the name and value of the specified command-line flag. + +`-flag` \[`+`\|`-`\]*name* +: Enables or disables the specified Boolean command-line flag. + +`-flag` *name*`=`*value* +: Sets the specified command-line flag to the specified value. + +`-flags` +: Prints command-line flags passed to the JVM. + +`-sysprops` +: Prints Java system properties as name-value pairs. + +`-h` or `-help` +: Prints a help message. diff --git a/src/jdk.jcmd/share/man/jmap.1 b/src/jdk.jcmd/share/man/jmap.1 deleted file mode 100644 index 42831aa68ac..00000000000 --- a/src/jdk.jcmd/share/man/jmap.1 +++ /dev/null @@ -1,106 +0,0 @@ -.\" Copyright (c) 2004, 2018, Oracle and/or its affiliates. All rights reserved. -.\" DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -.\" -.\" This code is free software; you can redistribute it and/or modify it -.\" under the terms of the GNU General Public License version 2 only, as -.\" published by the Free Software Foundation. -.\" -.\" This code is distributed in the hope that it will be useful, but WITHOUT -.\" ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -.\" FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -.\" version 2 for more details (a copy is included in the LICENSE file that -.\" accompanied this code). -.\" -.\" You should have received a copy of the GNU General Public License version -.\" 2 along with this work; if not, write to the Free Software Foundation, -.\" Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -.\" -.\" Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -.\" or visit www.oracle.com if you need additional information or have any -.\" questions. -.\" -.\" Automatically generated by Pandoc 2.19.2 -.\" -.\" Define V font for inline verbatim, using C font in formats -.\" that render this, and otherwise B font. -.ie "\f[CB]x\f[R]"x" \{\ -. ftr V B -. ftr VI BI -. ftr VB B -. ftr VBI BI -.\} -.el \{\ -. ftr V CR -. ftr VI CI -. ftr VB CB -. ftr VBI CBI -.\} -.TH "JMAP" "1" "2025" "JDK 24-ea" "JDK Commands" -.hy -.SH NAME -.PP -jmap - print details of a specified process -.SH SYNOPSIS -.PP -\f[B]Note:\f[R] This command is experimental and unsupported. -.PP -\f[V]jmap\f[R] [\f[I]options\f[R]] \f[I]pid\f[R] -.TP -\f[I]options\f[R] -This represents the \f[V]jmap\f[R] command-line options. -See \f[B]Options for the jmap Command\f[R]. -.TP -\f[I]pid\f[R] -The process ID for which the information specified by the -\f[I]options\f[R] is to be printed. -The process must be a Java process. -To get a list of Java processes running on a machine, use either the -\f[V]ps\f[R] command or, if the JVM processes are not running in a -separate docker instance, the \f[B]jps\f[R] command. -.SH DESCRIPTION -.PP -The \f[V]jmap\f[R] command prints details of a specified running -process. -.PP -\f[B]Note:\f[R] -.PP -This command is unsupported and might not be available in future -releases of the JDK. -On Windows Systems where the \f[V]dbgeng.dll\f[R] file isn\[aq]t -present, the Debugging Tools for Windows must be installed to make these -tools work. -The \f[V]PATH\f[R] environment variable should contain the location of -the \f[V]jvm.dll\f[R] file that\[aq]s used by the target process or the -location from which the core dump file was produced. -.SH OPTIONS FOR THE JMAP COMMAND -.TP -\f[V]-clstats\f[R] \f[I]pid\f[R] -Connects to a running process and prints class loader statistics of Java -heap. -.TP -\f[V]-finalizerinfo\f[R] \f[I]pid\f[R] -Connects to a running process and prints information on objects awaiting -finalization. -.TP -\f[V]-histo\f[R][\f[V]:live\f[R]] \f[I]pid\f[R] -Connects to a running process and prints a histogram of the Java object -heap. -If the \f[V]live\f[R] suboption is specified, it then counts only live -objects. -.TP -\f[V]-dump:\f[R]\f[I]dump_options\f[R] \f[I]pid\f[R] -Connects to a running process and dumps the Java heap. -The \f[I]dump_options\f[R] include: -.RS -.IP \[bu] 2 -\f[V]live\f[R] --- When specified, dumps only the live objects; if not -specified, then dumps all objects in the heap. -.IP \[bu] 2 -\f[V]format=b\f[R] --- Dumps the Java heap in \f[V]hprof\f[R] binary -format -.IP \[bu] 2 -\f[V]file=\f[R]\f[I]filename\f[R] --- Dumps the heap to -\f[I]filename\f[R] -.PP -Example: \f[V]jmap -dump:live,format=b,file=heap.bin\f[R] \f[I]pid\f[R] -.RE diff --git a/src/jdk.jcmd/share/man/jmap.md b/src/jdk.jcmd/share/man/jmap.md new file mode 100644 index 00000000000..1f986f97fab --- /dev/null +++ b/src/jdk.jcmd/share/man/jmap.md @@ -0,0 +1,89 @@ +--- +# Copyright (c) 2004, 2018, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# This code is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 only, as +# published by the Free Software Foundation. +# +# This code is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# version 2 for more details (a copy is included in the LICENSE file that +# accompanied this code). +# +# You should have received a copy of the GNU General Public License version +# 2 along with this work; if not, write to the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +# or visit www.oracle.com if you need additional information or have any +# questions. +# + +title: 'JMAP(1) JDK @@VERSION_SHORT@@ | JDK Commands' +date: @@COPYRIGHT_YEAR@@ +lang: en +--- + +## Name + +jmap - print details of a specified process + +## Synopsis + +**Note:** This command is experimental and unsupported. + +`jmap` \[*options*\] *pid* + +*options* +: This represents the `jmap` command-line options. See [Options for the jmap + Command]. + +*pid* +: The process ID for which the information specified by the *options* is to + be printed. The process must be a Java process. To get a list of Java + processes running on a machine, use either the `ps` command or, if the JVM + processes are not running in a separate docker instance, the + [jps](jps.html) command. + +## Description + +The `jmap` command prints details of a specified running process. + +**Note:** + +This command is unsupported and might not be available in future releases of +the JDK. On Windows Systems where the `dbgeng.dll` file isn't present, the +Debugging Tools for Windows must be installed to make these tools work. The +`PATH` environment variable should contain the location of the `jvm.dll` file +that's used by the target process or the location from which the core dump file +was produced. + +## Options for the jmap Command + +`-clstats` *pid* +: Connects to a running process and prints class loader statistics of Java + heap. + +`-finalizerinfo` *pid* +: Connects to a running process and prints information on objects awaiting + finalization. + +`-histo`\[`:live`\] *pid* +: Connects to a running process and prints a histogram of the Java object + heap. If the `live` suboption is specified, it then counts only live + objects. + +`-dump:`*dump\_options* *pid* +: Connects to a running process and dumps the Java heap. The *dump\_options* + include: + + - `live` --- When specified, dumps only the live objects; if not + specified, then dumps all objects in the heap. + + - `format=b` --- Dumps the Java heap in `hprof` binary format + + - `file=`*filename* --- Dumps the heap to *filename* + + Example: `jmap -dump:live,format=b,file=heap.bin` *pid* diff --git a/src/jdk.jcmd/share/man/jps.1 b/src/jdk.jcmd/share/man/jps.1 deleted file mode 100644 index cbc69872b60..00000000000 --- a/src/jdk.jcmd/share/man/jps.1 +++ /dev/null @@ -1,235 +0,0 @@ -.\" Copyright (c) 2004, 2018, Oracle and/or its affiliates. All rights reserved. -.\" DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -.\" -.\" This code is free software; you can redistribute it and/or modify it -.\" under the terms of the GNU General Public License version 2 only, as -.\" published by the Free Software Foundation. -.\" -.\" This code is distributed in the hope that it will be useful, but WITHOUT -.\" ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -.\" FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -.\" version 2 for more details (a copy is included in the LICENSE file that -.\" accompanied this code). -.\" -.\" You should have received a copy of the GNU General Public License version -.\" 2 along with this work; if not, write to the Free Software Foundation, -.\" Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -.\" -.\" Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -.\" or visit www.oracle.com if you need additional information or have any -.\" questions. -.\" -.\" Automatically generated by Pandoc 2.19.2 -.\" -.\" Define V font for inline verbatim, using C font in formats -.\" that render this, and otherwise B font. -.ie "\f[CB]x\f[R]"x" \{\ -. ftr V B -. ftr VI BI -. ftr VB B -. ftr VBI BI -.\} -.el \{\ -. ftr V CR -. ftr VI CI -. ftr VB CB -. ftr VBI CBI -.\} -.TH "JPS" "1" "2025" "JDK 24-ea" "JDK Commands" -.hy -.SH NAME -.PP -jps - list the instrumented JVMs on the target system -.SH SYNOPSIS -.PP -\f[B]Note:\f[R] This command is experimental and unsupported. -.PP -\f[V]jps\f[R] [\f[V]-q\f[R]] [\f[V]-mlvV\f[R]] [\f[I]hostid\f[R]] -.PP -\f[V]jps\f[R] [\f[V]-help\f[R]] -.SH OPTIONS -.TP -\f[V]-q\f[R] -Suppresses the output of the class name, JAR file name, and arguments -passed to the \f[V]main\f[R] method, producing a list of only local JVM -identifiers. -.TP -\f[V]-mlvV\f[R] -You can specify any combination of these options. -.RS -.IP \[bu] 2 -\f[V]-m\f[R] displays the arguments passed to the \f[V]main\f[R] method. -The output may be \f[V]null\f[R] for embedded JVMs. -.IP \[bu] 2 -\f[V]-l\f[R] displays the full package name for the application\[aq]s -\f[V]main\f[R] class or the full path name to the application\[aq]s JAR -file. -.IP \[bu] 2 -\f[V]-v\f[R] displays the arguments passed to the JVM. -.IP \[bu] 2 -\f[V]-V\f[R] suppresses the output of the class name, JAR file name, and -arguments passed to the \f[V]main\f[R] method, producing a list of only -local JVM identifiers. -.RE -.TP -\f[I]hostid\f[R] -The identifier of the host for which the process report should be -generated. -The \f[V]hostid\f[R] can include optional components that indicate the -communications protocol, port number, and other implementation specific -data. -See \f[B]Host Identifier\f[R]. -.TP -\f[V]-help\f[R] -Displays the help message for the \f[V]jps\f[R] command. -.SH DESCRIPTION -.PP -The \f[V]jps\f[R] command lists the instrumented Java HotSpot VMs on the -target system. -The command is limited to reporting information on JVMs for which it has -the access permissions. -.PP -If the \f[V]jps\f[R] command is run without specifying a -\f[V]hostid\f[R], then it searches for instrumented JVMs on the local -host. -If started with a \f[V]hostid\f[R], then it searches for JVMs on the -indicated host, using the specified protocol and port. -A \f[V]jstatd\f[R] process is assumed to be running on the target host. -.PP -The \f[V]jps\f[R] command reports the local JVM identifier, or -\f[V]lvmid\f[R], for each instrumented JVM found on the target system. -The \f[V]lvmid\f[R] is typically, but not necessarily, the operating -system\[aq]s process identifier for the JVM process. -With no options, the \f[V]jps\f[R] command lists each Java -application\[aq]s \f[V]lvmid\f[R] followed by the short form of the -application\[aq]s class name or jar file name. -The short form of the class name or JAR file name omits the class\[aq]s -package information or the JAR files path information. -.PP -The \f[V]jps\f[R] command uses the Java launcher to find the class name -and arguments passed to the main method. -If the target JVM is started with a custom launcher, then the class or -JAR file name, and the arguments to the \f[V]main\f[R] method aren\[aq]t -available. -In this case, the \f[V]jps\f[R] command outputs the string -\f[V]Unknown\f[R] for the class name, or JAR file name, and for the -arguments to the \f[V]main\f[R] method. -.PP -The list of JVMs produced by the \f[V]jps\f[R] command can be limited by -the permissions granted to the principal running the command. -The command lists only the JVMs for which the principal has access -rights as determined by operating system-specific access control -mechanisms. -.SH HOST IDENTIFIER -.PP -The host identifier, or \f[V]hostid\f[R], is a string that indicates the -target system. -The syntax of the \f[V]hostid\f[R] string corresponds to the syntax of a -URI: -.RS -.PP -[\f[I]protocol\f[R]\f[V]:\f[R]][[\f[V]//\f[R]]\f[I]hostname\f[R]][\f[V]:\f[R]\f[I]port\f[R]][\f[V]/\f[R]\f[I]servername\f[R]] -.RE -.TP -\f[I]protocol\f[R] -The communications protocol. -If the \f[I]protocol\f[R] is omitted and a \f[I]hostname\f[R] isn\[aq]t -specified, then the default protocol is a platform-specific, optimized, -local protocol. -If the protocol is omitted and a host name is specified, then the -default protocol is \f[V]rmi\f[R]. -.TP -\f[I]hostname\f[R] -A host name or IP address that indicates the target host. -If you omit the \f[I]hostname\f[R] parameter, then the target host is -the local host. -.TP -\f[I]port\f[R] -The default port for communicating with the remote server. -If the \f[I]hostname\f[R] parameter is omitted or the \f[I]protocol\f[R] -parameter specifies an optimized, local protocol, then the -\f[I]port\f[R] parameter is ignored. -Otherwise, treatment of the \f[I]port\f[R] parameter is -implementation-specific. -For the default \f[V]rmi\f[R] protocol, the \f[I]port\f[R] parameter -indicates the port number for the \f[V]rmiregistry\f[R] on the remote -host. -If the \f[I]port\f[R] parameter is omitted, and the \f[I]protocol\f[R] -parameter indicates \f[V]rmi\f[R], then the default -\f[V]rmiregistry\f[R] port (\f[V]1099\f[R]) is used. -.TP -\f[I]servername\f[R] -The treatment of this parameter depends on the implementation. -For the optimized, local protocol, this field is ignored. -For the \f[V]rmi\f[R] protocol, this parameter is a string that -represents the name of the RMI remote object on the remote host. -See the \f[B]jstatd\f[R] command \f[V]-n\f[R] option. -.SH OUTPUT FORMAT OF THE JPS COMMAND -.PP -The output of the \f[V]jps\f[R] command has the following pattern: -.RS -.PP -\f[I]lvmid\f[R] [ [ \f[I]classname\f[R] | \f[I]JARfilename\f[R] | -\f[V]\[dq]Unknown\[dq]\f[R]] [ \f[I]arg\f[R]* ] [ \f[I]jvmarg\f[R]* ] ] -.RE -.PP -All output tokens are separated by white space. -An \f[V]arg\f[R] value that includes embedded white space introduces -ambiguity when attempting to map arguments to their actual positional -parameters. -.PP -\f[B]Note:\f[R] -.PP -It\[aq]s recommended that you don\[aq]t write scripts to parse -\f[V]jps\f[R] output because the format might change in future releases. -If you write scripts that parse \f[V]jps\f[R] output, then expect to -modify them for future releases of this tool. -.SH EXAMPLES -.PP -This section provides examples of the \f[V]jps\f[R] command. -.PP -List the instrumented JVMs on the local host: -.IP -.nf -\f[CB] -jps -18027 Java2Demo.JAR -18032 jps -18005 jstat -\f[R] -.fi -.PP -The following example lists the instrumented JVMs on a remote host. -This example assumes that the \f[V]jstat\f[R] server and either the its -internal RMI registry or a separate external \f[V]rmiregistry\f[R] -process are running on the remote host on the default port (port -\f[V]1099\f[R]). -It also assumes that the local host has appropriate permissions to -access the remote host. -This example includes the \f[V]-l\f[R] option to output the long form of -the class names or JAR file names. -.IP -.nf -\f[CB] -jps -l remote.domain -3002 /opt/jdk1.7.0/demo/jfc/Java2D/Java2Demo.JAR -2857 sun.tools.jstatd.jstatd -\f[R] -.fi -.PP -The following example lists the instrumented JVMs on a remote host with -a nondefault port for the RMI registry. -This example assumes that the \f[V]jstatd\f[R] server, with an internal -RMI registry bound to port \f[V]2002\f[R], is running on the remote -host. -This example also uses the \f[V]-m\f[R] option to include the arguments -passed to the \f[V]main\f[R] method of each of the listed Java -applications. -.IP -.nf -\f[CB] -jps -m remote.domain:2002 -3002 /opt/jdk1.7.0/demo/jfc/Java2D/Java2Demo.JAR -3102 sun.tools.jstatd.jstatd -p 2002 -\f[R] -.fi diff --git a/src/jdk.jcmd/share/man/jps.md b/src/jdk.jcmd/share/man/jps.md new file mode 100644 index 00000000000..be3994c411e --- /dev/null +++ b/src/jdk.jcmd/share/man/jps.md @@ -0,0 +1,189 @@ +--- +# Copyright (c) 2004, 2018, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# This code is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 only, as +# published by the Free Software Foundation. +# +# This code is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# version 2 for more details (a copy is included in the LICENSE file that +# accompanied this code). +# +# You should have received a copy of the GNU General Public License version +# 2 along with this work; if not, write to the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +# or visit www.oracle.com if you need additional information or have any +# questions. +# + +title: 'JPS(1) JDK @@VERSION_SHORT@@ | JDK Commands' +date: @@COPYRIGHT_YEAR@@ +lang: en +--- + +## Name + +jps - list the instrumented JVMs on the target system + +## Synopsis + +**Note:** This command is experimental and unsupported. + +`jps` \[`-q`\] \[`-mlvV`\] \[*hostid*\] + +`jps` \[`-help`\] + +## Options + +`-q` +: Suppresses the output of the class name, JAR file name, and arguments + passed to the `main` method, producing a list of only local JVM + identifiers. + +`-mlvV` +: You can specify any combination of these options. + + - `-m` displays the arguments passed to the `main` method. The output may + be `null` for embedded JVMs. + + - `-l` displays the full package name for the application's `main` class + or the full path name to the application's JAR file. + + - `-v` displays the arguments passed to the JVM. + + - `-V` suppresses the output of the class name, JAR file name, and + arguments passed to the `main` method, producing a list of only local + JVM identifiers. + +*hostid* +: The identifier of the host for which the process report should be + generated. The `hostid` can include optional components that indicate the + communications protocol, port number, and other implementation specific + data. See [Host Identifier]. + +`-help` +: Displays the help message for the `jps` command. + +## Description + +The `jps` command lists the instrumented Java HotSpot VMs on the target system. +The command is limited to reporting information on JVMs for which it has the +access permissions. + +If the `jps` command is run without specifying a `hostid`, then it searches for +instrumented JVMs on the local host. If started with a `hostid`, then it +searches for JVMs on the indicated host, using the specified protocol and port. +A `jstatd` process is assumed to be running on the target host. + +The `jps` command reports the local JVM identifier, or `lvmid`, for each +instrumented JVM found on the target system. The `lvmid` is typically, but not +necessarily, the operating system's process identifier for the JVM process. +With no options, the `jps` command lists each Java application's `lvmid` +followed by the short form of the application's class name or jar file name. +The short form of the class name or JAR file name omits the class's package +information or the JAR files path information. + +The `jps` command uses the Java launcher to find the class name and arguments +passed to the main method. If the target JVM is started with a custom launcher, +then the class or JAR file name, and the arguments to the `main` method aren't +available. In this case, the `jps` command outputs the string `Unknown` for the +class name, or JAR file name, and for the arguments to the `main` method. + +The list of JVMs produced by the `jps` command can be limited by the +permissions granted to the principal running the command. The command lists +only the JVMs for which the principal has access rights as determined by +operating system-specific access control mechanisms. + +## Host Identifier + +The host identifier, or `hostid`, is a string that indicates the target system. +The syntax of the `hostid` string corresponds to the syntax of a URI: + +> \[*protocol*`:`\]\[\[`//`\]*hostname*\]\[`:`*port*\]\[`/`*servername*\] + +*protocol* +: The communications protocol. If the *protocol* is omitted and a *hostname* + isn't specified, then the default protocol is a platform-specific, + optimized, local protocol. If the protocol is omitted and a host name is + specified, then the default protocol is `rmi`. + +*hostname* +: A host name or IP address that indicates the target host. If you omit the + *hostname* parameter, then the target host is the local host. + +*port* +: The default port for communicating with the remote server. If the + *hostname* parameter is omitted or the *protocol* parameter specifies an + optimized, local protocol, then the *port* parameter is ignored. Otherwise, + treatment of the *port* parameter is implementation-specific. For the + default `rmi` protocol, the *port* parameter indicates the port number for + the `rmiregistry` on the remote host. If the *port* parameter is omitted, + and the *protocol* parameter indicates `rmi`, then the default + `rmiregistry` port (`1099`) is used. + +*servername* +: The treatment of this parameter depends on the implementation. For the + optimized, local protocol, this field is ignored. For the `rmi` protocol, + this parameter is a string that represents the name of the RMI remote + object on the remote host. See the [jstatd](jstatd.html) command `-n` + option. + +## Output Format of the jps Command + +The output of the `jps` command has the following pattern: + +> *lvmid* \[ \[ *classname* \| *JARfilename* \| `"Unknown"`\] \[ *arg*\* \] + \[ *jvmarg*\* \] \] + +All output tokens are separated by white space. An `arg` value that includes +embedded white space introduces ambiguity when attempting to map arguments to +their actual positional parameters. + +**Note:** + +It's recommended that you don't write scripts to parse `jps` output because the +format might change in future releases. If you write scripts that parse `jps` +output, then expect to modify them for future releases of this tool. + +## Examples + +This section provides examples of the `jps` command. + +List the instrumented JVMs on the local host: + +``` +jps +18027 Java2Demo.JAR +18032 jps +18005 jstat +``` + +The following example lists the instrumented JVMs on a remote host. This +example assumes that the `jstat` server and either the its internal RMI +registry or a separate external `rmiregistry` process are running on the remote +host on the default port (port `1099`). It also assumes that the local host has +appropriate permissions to access the remote host. This example includes the +`-l` option to output the long form of the class names or JAR file names. + +``` +jps -l remote.domain +3002 /opt/jdk1.7.0/demo/jfc/Java2D/Java2Demo.JAR +2857 sun.tools.jstatd.jstatd +``` + +The following example lists the instrumented JVMs on a remote host with a +nondefault port for the RMI registry. This example assumes that the `jstatd` +server, with an internal RMI registry bound to port `2002`, is running on the +remote host. This example also uses the `-m` option to include the arguments +passed to the `main` method of each of the listed Java applications. + +``` +jps -m remote.domain:2002 +3002 /opt/jdk1.7.0/demo/jfc/Java2D/Java2Demo.JAR +3102 sun.tools.jstatd.jstatd -p 2002 +``` diff --git a/src/jdk.jcmd/share/man/jstack.1 b/src/jdk.jcmd/share/man/jstack.1 deleted file mode 100644 index 933db5fc80d..00000000000 --- a/src/jdk.jcmd/share/man/jstack.1 +++ /dev/null @@ -1,89 +0,0 @@ -.\" Copyright (c) 2004, 2018, Oracle and/or its affiliates. All rights reserved. -.\" DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -.\" -.\" This code is free software; you can redistribute it and/or modify it -.\" under the terms of the GNU General Public License version 2 only, as -.\" published by the Free Software Foundation. -.\" -.\" This code is distributed in the hope that it will be useful, but WITHOUT -.\" ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -.\" FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -.\" version 2 for more details (a copy is included in the LICENSE file that -.\" accompanied this code). -.\" -.\" You should have received a copy of the GNU General Public License version -.\" 2 along with this work; if not, write to the Free Software Foundation, -.\" Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -.\" -.\" Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -.\" or visit www.oracle.com if you need additional information or have any -.\" questions. -.\" -.\" Automatically generated by Pandoc 2.19.2 -.\" -.\" Define V font for inline verbatim, using C font in formats -.\" that render this, and otherwise B font. -.ie "\f[CB]x\f[R]"x" \{\ -. ftr V B -. ftr VI BI -. ftr VB B -. ftr VBI BI -.\} -.el \{\ -. ftr V CR -. ftr VI CI -. ftr VB CB -. ftr VBI CBI -.\} -.TH "JSTACK" "1" "2025" "JDK 24-ea" "JDK Commands" -.hy -.SH NAME -.PP -jstack - print Java stack traces of Java threads for a specified Java -process -.SH SYNOPSIS -.PP -\f[B]Note:\f[R] This command is experimental and unsupported. -.PP -\f[V]jstack\f[R] [\f[I]options\f[R]] \f[I]pid\f[R] -.TP -\f[I]options\f[R] -This represents the \f[V]jstack\f[R] command-line options. -See \f[B]Options for the jstack Command\f[R]. -.TP -\f[I]pid\f[R] -The process ID for which the stack trace is printed. -The process must be a Java process. -To get a list of Java processes running on a machine, use either the -\f[V]ps\f[R] command or, if the JVM processes are not running in a -separate docker instance, the \f[B]jps\f[R] command. -.SH DESCRIPTION -.PP -The \f[V]jstack\f[R] command prints Java stack traces of Java threads -for a specified Java process. -For each Java frame, the full class name, method name, byte code index -(BCI), and line number, when available, are printed. -C++ mangled names aren\[aq]t demangled. -To demangle C++ names, the output of this command can be piped to -\f[V]c++filt\f[R]. -When the specified process is running on a 64-bit JVM, you might need to -specify the \f[V]-J-d64\f[R] option, for example: -\f[V]jstack -J-d64\f[R] \f[I]pid\f[R]. -.PP -\f[B]Note:\f[R] -.PP -This command is unsupported and might not be available in future -releases of the JDK. -In Windows Systems where the \f[V]dbgeng.dll\f[R] file isn\[aq]t -present, the Debugging Tools for Windows must be installed so that these -tools work. -The \f[V]PATH\f[R] environment variable needs to contain the location of -the \f[V]jvm.dll\f[R] that is used by the target process, or the -location from which the core dump file was produced. -.SH OPTIONS FOR THE JSTACK COMMAND -.TP -\f[V]-l\f[R] -The long listing option prints additional information about locks. -.TP -\f[V]-h\f[R] or \f[V]-help\f[R] -Prints a help message. diff --git a/src/jdk.jcmd/share/man/jstack.md b/src/jdk.jcmd/share/man/jstack.md new file mode 100644 index 00000000000..84df235a70e --- /dev/null +++ b/src/jdk.jcmd/share/man/jstack.md @@ -0,0 +1,73 @@ +--- +# Copyright (c) 2004, 2018, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# This code is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 only, as +# published by the Free Software Foundation. +# +# This code is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# version 2 for more details (a copy is included in the LICENSE file that +# accompanied this code). +# +# You should have received a copy of the GNU General Public License version +# 2 along with this work; if not, write to the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +# or visit www.oracle.com if you need additional information or have any +# questions. +# + +title: 'JSTACK(1) JDK @@VERSION_SHORT@@ | JDK Commands' +date: @@COPYRIGHT_YEAR@@ +lang: en +--- + +## Name + +jstack - print Java stack traces of Java threads for a specified Java process + +## Synopsis + +**Note:** This command is experimental and unsupported. + +`jstack` \[*options*\] *pid* + +*options* +: This represents the `jstack` command-line options. See [Options for the + jstack Command]. + +*pid* +: The process ID for which the stack trace is printed. The process must be a + Java process. To get a list of Java processes running on a machine, use + either the `ps` command or, if the JVM processes are not running in a + separate docker instance, the [jps](jps.html) command. + +## Description + +The `jstack` command prints Java stack traces of Java threads for a specified +Java process. For each Java frame, the full class name, method name, byte code +index (BCI), and line number, when available, are printed. C++ mangled names +aren't demangled. To demangle C++ names, the output of this command can be +piped to `c++filt`. When the specified process is running on a 64-bit JVM, you +might need to specify the `-J-d64` option, for example: `jstack -J-d64` *pid*. + +**Note:** + +This command is unsupported and might not be available in future releases of +the JDK. In Windows Systems where the `dbgeng.dll` file isn't present, the +Debugging Tools for Windows must be installed so that these tools work. The +`PATH` environment variable needs to contain the location of the `jvm.dll` that +is used by the target process, or the location from which the core dump file +was produced. + +## Options for the jstack Command + +`-l` +: The long listing option prints additional information about locks. + +`-h` or `-help` +: Prints a help message. diff --git a/src/jdk.jcmd/share/man/jstat.1 b/src/jdk.jcmd/share/man/jstat.1 deleted file mode 100644 index 22e111a812b..00000000000 --- a/src/jdk.jcmd/share/man/jstat.1 +++ /dev/null @@ -1,689 +0,0 @@ -.\" Copyright (c) 2004, 2023, Oracle and/or its affiliates. All rights reserved. -.\" DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -.\" -.\" This code is free software; you can redistribute it and/or modify it -.\" under the terms of the GNU General Public License version 2 only, as -.\" published by the Free Software Foundation. -.\" -.\" This code is distributed in the hope that it will be useful, but WITHOUT -.\" ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -.\" FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -.\" version 2 for more details (a copy is included in the LICENSE file that -.\" accompanied this code). -.\" -.\" You should have received a copy of the GNU General Public License version -.\" 2 along with this work; if not, write to the Free Software Foundation, -.\" Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -.\" -.\" Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -.\" or visit www.oracle.com if you need additional information or have any -.\" questions. -.\" -.\" Automatically generated by Pandoc 2.19.2 -.\" -.\" Define V font for inline verbatim, using C font in formats -.\" that render this, and otherwise B font. -.ie "\f[CB]x\f[R]"x" \{\ -. ftr V B -. ftr VI BI -. ftr VB B -. ftr VBI BI -.\} -.el \{\ -. ftr V CR -. ftr VI CI -. ftr VB CB -. ftr VBI CBI -.\} -.TH "JSTAT" "1" "2025" "JDK 24-ea" "JDK Commands" -.hy -.SH NAME -.PP -jstat - monitor JVM statistics -.SH SYNOPSIS -.PP -\f[B]Note:\f[R] This command is experimental and unsupported. -.PP -\f[V]jstat\f[R] \f[I]generalOptions\f[R] -.PP -\f[V]jstat\f[R] \f[I]outputOptions\f[R] [\f[V]-t\f[R]] [\f[V]-h\f[R] -\f[I]lines\f[R]] \f[I]vmid\f[R] [\f[I]interval\f[R] [\f[I]count\f[R]]] -.TP -\f[I]generalOptions\f[R] -A single general command-line option. -See \f[B]General Options\f[R]. -.TP -\f[I]outputOptions\f[R] -An option reported by the \f[V]-options\f[R] option. -One or more output options that consist of a single -\f[V]statOption\f[R], plus any of the \f[V]-t\f[R], \f[V]-h\f[R], and -\f[V]-J\f[R] options. -See \f[B]Output Options for the jstat Command\f[R]. -.TP -\f[V]-t\f[R] -Displays a time-stamp column as the first column of output. -The time stamp is the time since the start time of the target JVM. -.TP -\f[V]-h\f[R] \f[I]n\f[R] -Displays a column header every \f[I]n\f[R] samples (output rows), where -\f[I]n\f[R] is a positive integer. -The default value is \f[V]0\f[R], which displays the column header of -the first row of data. -.TP -\f[I]vmid\f[R] -A virtual machine identifier, which is a string that indicates the -target JVM. -See \f[B]Virtual Machine Identifier\f[R]. -.TP -\f[I]interval\f[R] -The sampling interval in the specified units, seconds (s) or -milliseconds (ms). -Default units are milliseconds. -This must be a positive integer. -When specified, the \f[V]jstat\f[R] command produces its output at each -interval. -.TP -\f[I]count\f[R] -The number of samples to display. -The default value is infinity, which causes the \f[V]jstat\f[R] command -to display statistics until the target JVM terminates or the -\f[V]jstat\f[R] command is terminated. -This value must be a positive integer. -.SH DESCRIPTION -.PP -The \f[V]jstat\f[R] command displays performance statistics for an -instrumented Java HotSpot VM. -The target JVM is identified by its virtual machine identifier, or -\f[V]vmid\f[R] option. -.PP -The \f[V]jstat\f[R] command supports two types of options, general -options and output options. -General options cause the \f[V]jstat\f[R] command to display simple -usage and version information. -Output options determine the content and format of the statistical -output. -.PP -All options and their functionality are subject to change or removal in -future releases. -.SH GENERAL OPTIONS -.PP -If you specify one of the general options, then you can\[aq]t specify -any other option or parameter. -.TP -\f[V]-help\f[R] -Displays a help message. -.TP -\f[V]-options\f[R] -Displays a list of static options. -See \f[B]Output Options for the jstat Command\f[R]. -.SH OUTPUT OPTIONS FOR THE JSTAT COMMAND -.PP -If you don\[aq]t specify a general option, then you can specify output -options. -Output options determine the content and format of the \f[V]jstat\f[R] -command\[aq]s output, and consist of a single \f[V]statOption\f[R], plus -any of the other output options (\f[V]-h\f[R], \f[V]-t\f[R], and -\f[V]-J\f[R]). -The \f[V]statOption\f[R] must come first. -.PP -Output is formatted as a table, with columns that are separated by -spaces. -A header row with titles describes the columns. -Use the \f[V]-h\f[R] option to set the frequency at which the header is -displayed. -Column header names are consistent among the different options. -In general, if two options provide a column with the same name, then the -data source for the two columns is the same. -.PP -Use the \f[V]-t\f[R] option to display a time-stamp column, labeled -Timestamp as the first column of output. -The Timestamp column contains the elapsed time, in seconds, since the -target JVM started. -The resolution of the time stamp is dependent on various factors and is -subject to variation due to delayed thread scheduling on heavily loaded -systems. -.PP -Use the interval and count parameters to determine how frequently and -how many times, respectively, the \f[V]jstat\f[R] command displays its -output. -.PP -\f[B]Note:\f[R] -.PP -Don\[aq]t write scripts to parse the \f[V]jstat\f[R] command\[aq]s -output because the format might change in future releases. -If you write scripts that parse the \f[V]jstat\f[R] command output, then -expect to modify them for future releases of this tool. -.TP -\f[V]-statOption\f[R] -Determines the statistics information that the \f[V]jstat\f[R] command -displays. -The following lists the available options. -Use the \f[V]-options\f[R] general option to display the list of options -for a particular platform installation. -See \f[B]Stat Options and Output\f[R]. -.RS -.PP -\f[V]class\f[R]: Displays statistics about the behavior of the class -loader. -.PP -\f[V]compiler\f[R]: Displays statistics about the behavior of the Java -HotSpot VM Just-in-Time compiler. -.PP -\f[V]gc\f[R]: Displays statistics about the behavior of the garbage -collected heap. -.PP -\f[V]gccapacity\f[R]: Displays statistics about the capacities of the -generations and their corresponding spaces. -.PP -\f[V]gccause\f[R]: Displays a summary about garbage collection -statistics (same as \f[V]-gcutil\f[R]), with the cause of the last and -current (when applicable) garbage collection events. -.PP -\f[V]gcnew\f[R]: Displays statistics about the behavior of the new -generation. -.PP -\f[V]gcnewcapacity\f[R]: Displays statistics about the sizes of the new -generations and their corresponding spaces. -.PP -\f[V]gcold\f[R]: Displays statistics about the behavior of the old -generation and metaspace statistics. -.PP -\f[V]gcoldcapacity\f[R]: Displays statistics about the sizes of the old -generation. -.PP -\f[V]gcmetacapacity\f[R]: Displays statistics about the sizes of the -metaspace. -.PP -\f[V]gcutil\f[R]: Displays a summary about garbage collection -statistics. -.PP -\f[V]printcompilation\f[R]: Displays Java HotSpot VM compilation method -statistics. -.RE -.TP -\f[V]-J\f[R]\f[I]javaOption\f[R] -Passes \f[I]javaOption\f[R] to the Java application launcher. -For example, \f[V]-J-Xms48m\f[R] sets the startup memory to 48 MB. -For a complete list of options, see \f[B]java\f[R]. -.SH STAT OPTIONS AND OUTPUT -.PP -The following information summarizes the columns that the -\f[V]jstat\f[R] command outputs for each \f[I]statOption\f[R]. -.TP -\f[V]-class\f[R] \f[I]option\f[R] -Class loader statistics. -.RS -.PP -\f[V]Loaded\f[R]: Number of classes loaded. -.PP -\f[V]Bytes\f[R]: Number of KB loaded. -.PP -\f[V]Unloaded\f[R]: Number of classes unloaded. -.PP -\f[V]Bytes\f[R]: Number of KB unloaded. -.PP -\f[V]Time\f[R]: Time spent performing class loading and unloading -operations. -.RE -.TP -\f[V]-compiler\f[R] \f[I]option\f[R] -Java HotSpot VM Just-in-Time compiler statistics. -.RS -.PP -\f[V]Compiled\f[R]: Number of compilation tasks performed. -.PP -\f[V]Failed\f[R]: Number of compilations tasks failed. -.PP -\f[V]Invalid\f[R]: Number of compilation tasks that were invalidated. -.PP -\f[V]Time\f[R]: Time spent performing compilation tasks. -.PP -\f[V]FailedType\f[R]: Compile type of the last failed compilation. -.PP -\f[V]FailedMethod\f[R]: Class name and method of the last failed -compilation. -.RE -.TP -\f[V]-gc\f[R] \f[I]option\f[R] -Garbage collected heap statistics. -.RS -.PP -\f[V]S0C\f[R]: Current survivor space 0 capacity (KB). -.PP -\f[V]S1C\f[R]: Current survivor space 1 capacity (KB). -.PP -\f[V]S0U\f[R]: Survivor space 0 utilization (KB). -.PP -\f[V]S1U\f[R]: Survivor space 1 utilization (KB). -.PP -\f[V]EC\f[R]: Current eden space capacity (KB). -.PP -\f[V]EU\f[R]: Eden space utilization (KB). -.PP -\f[V]OC\f[R]: Current old space capacity (KB). -.PP -\f[V]OU\f[R]: Old space utilization (KB). -.PP -\f[V]MC\f[R]: Metaspace Committed Size (KB). -.PP -\f[V]MU\f[R]: Metaspace utilization (KB). -.PP -\f[V]CCSC\f[R]: Compressed class committed size (KB). -.PP -\f[V]CCSU\f[R]: Compressed class space used (KB). -.PP -\f[V]YGC\f[R]: Number of young generation garbage collection (GC) -events. -.PP -\f[V]YGCT\f[R]: Young generation garbage collection time. -.PP -\f[V]FGC\f[R]: Number of full GC events. -.PP -\f[V]FGCT\f[R]: Full garbage collection time. -.PP -\f[V]GCT\f[R]: Total garbage collection time. -.RE -.TP -\f[V]-gccapacity\f[R] \f[I]option\f[R] -Memory pool generation and space capacities. -.RS -.PP -\f[V]NGCMN\f[R]: Minimum new generation capacity (KB). -.PP -\f[V]NGCMX\f[R]: Maximum new generation capacity (KB). -.PP -\f[V]NGC\f[R]: Current new generation capacity (KB). -.PP -\f[V]S0C\f[R]: Current survivor space 0 capacity (KB). -.PP -\f[V]S1C\f[R]: Current survivor space 1 capacity (KB). -.PP -\f[V]EC\f[R]: Current eden space capacity (KB). -.PP -\f[V]OGCMN\f[R]: Minimum old generation capacity (KB). -.PP -\f[V]OGCMX\f[R]: Maximum old generation capacity (KB). -.PP -\f[V]OGC\f[R]: Current old generation capacity (KB). -.PP -\f[V]OC\f[R]: Current old space capacity (KB). -.PP -\f[V]MCMN\f[R]: Minimum metaspace capacity (KB). -.PP -\f[V]MCMX\f[R]: Maximum metaspace capacity (KB). -.PP -\f[V]MC\f[R]: Metaspace Committed Size (KB). -.PP -\f[V]CCSMN\f[R]: Compressed class space minimum capacity (KB). -.PP -\f[V]CCSMX\f[R]: Compressed class space maximum capacity (KB). -.PP -\f[V]CCSC\f[R]: Compressed class committed size (KB). -.PP -\f[V]YGC\f[R]: Number of young generation GC events. -.PP -\f[V]FGC\f[R]: Number of full GC events. -.RE -.TP -\f[V]-gccause\f[R] \f[I]option\f[R] -This option displays the same summary of garbage collection statistics -as the \f[V]-gcutil\f[R] option, but includes the causes of the last -garbage collection event and (when applicable), the current garbage -collection event. -In addition to the columns listed for \f[V]-gcutil\f[R], this option -adds the following columns: -.RS -.PP -\f[V]LGCC\f[R]: Cause of last garbage collection -.PP -\f[V]GCC\f[R]: Cause of current garbage collection -.RE -.TP -\f[V]-gcnew\f[R] \f[I]option\f[R] -New generation statistics. -.RS -.PP -\f[V]S0C\f[R]: Current survivor space 0 capacity (KB). -.PP -\f[V]S1C\f[R]: Current survivor space 1 capacity (KB). -.PP -\f[V]S0U\f[R]: Survivor space 0 utilization (KB). -.PP -\f[V]S1U\f[R]: Survivor space 1 utilization (KB). -.PP -\f[V]TT\f[R]: Tenuring threshold. -.PP -\f[V]MTT\f[R]: Maximum tenuring threshold. -.PP -\f[V]DSS\f[R]: Desired survivor size (KB). -.PP -\f[V]EC\f[R]: Current eden space capacity (KB). -.PP -\f[V]EU\f[R]: Eden space utilization (KB). -.PP -\f[V]YGC\f[R]: Number of young generation GC events. -.PP -\f[V]YGCT\f[R]: Young generation garbage collection time. -.RE -.TP -\f[V]-gcnewcapacity\f[R] \f[I]option\f[R] -New generation space size statistics. -.RS -.PP -\f[V]NGCMN\f[R]: Minimum new generation capacity (KB). -.PP -\f[V]NGCMX\f[R]: Maximum new generation capacity (KB). -.PP -\f[V]NGC\f[R]: Current new generation capacity (KB). -.PP -\f[V]S0CMX\f[R]: Maximum survivor space 0 capacity (KB). -.PP -\f[V]S0C\f[R]: Current survivor space 0 capacity (KB). -.PP -\f[V]S1CMX\f[R]: Maximum survivor space 1 capacity (KB). -.PP -\f[V]S1C\f[R]: Current survivor space 1 capacity (KB). -.PP -\f[V]ECMX\f[R]: Maximum eden space capacity (KB). -.PP -\f[V]EC\f[R]: Current eden space capacity (KB). -.PP -\f[V]YGC\f[R]: Number of young generation GC events. -.PP -\f[V]FGC\f[R]: Number of full GC events. -.RE -.TP -\f[V]-gcold\f[R] \f[I]option\f[R] -Old generation size statistics. -.RS -.PP -\f[V]MC\f[R]: Metaspace Committed Size (KB). -.PP -\f[V]MU\f[R]: Metaspace utilization (KB). -.PP -\f[V]CCSC\f[R]: Compressed class committed size (KB). -.PP -\f[V]CCSU\f[R]: Compressed class space used (KB). -.PP -\f[V]OC\f[R]: Current old space capacity (KB). -.PP -\f[V]OU\f[R]: Old space utilization (KB). -.PP -\f[V]YGC\f[R]: Number of young generation GC events. -.PP -\f[V]FGC\f[R]: Number of full GC events. -.PP -\f[V]FGCT\f[R]: Full garbage collection time. -.PP -\f[V]GCT\f[R]: Total garbage collection time. -.RE -.TP -\f[V]-gcoldcapacity\f[R] \f[I]option\f[R] -Old generation statistics. -.RS -.PP -\f[V]OGCMN\f[R]: Minimum old generation capacity (KB). -.PP -\f[V]OGCMX\f[R]: Maximum old generation capacity (KB). -.PP -\f[V]OGC\f[R]: Current old generation capacity (KB). -.PP -\f[V]OC\f[R]: Current old space capacity (KB). -.PP -\f[V]YGC\f[R]: Number of young generation GC events. -.PP -\f[V]FGC\f[R]: Number of full GC events. -.PP -\f[V]FGCT\f[R]: Full garbage collection time. -.PP -\f[V]GCT\f[R]: Total garbage collection time. -.RE -.TP -\f[V]-gcmetacapacity\f[R] \f[I]option\f[R] -Metaspace size statistics. -.RS -.PP -\f[V]MCMN\f[R]: Minimum metaspace capacity (KB). -.PP -\f[V]MCMX\f[R]: Maximum metaspace capacity (KB). -.PP -\f[V]MC\f[R]: Metaspace Committed Size (KB). -.PP -\f[V]CCSMN\f[R]: Compressed class space minimum capacity (KB). -.PP -\f[V]CCSMX\f[R]: Compressed class space maximum capacity (KB). -.PP -\f[V]YGC\f[R]: Number of young generation GC events. -.PP -\f[V]FGC\f[R]: Number of full GC events. -.PP -\f[V]FGCT\f[R]: Full garbage collection time. -.PP -\f[V]GCT\f[R]: Total garbage collection time. -.RE -.TP -\f[V]-gcutil\f[R] \f[I]option\f[R] -Summary of garbage collection statistics. -.RS -.PP -\f[V]S0\f[R]: Survivor space 0 utilization as a percentage of the -space\[aq]s current capacity. -.PP -\f[V]S1\f[R]: Survivor space 1 utilization as a percentage of the -space\[aq]s current capacity. -.PP -\f[V]E\f[R]: Eden space utilization as a percentage of the space\[aq]s -current capacity. -.PP -\f[V]O\f[R]: Old space utilization as a percentage of the space\[aq]s -current capacity. -.PP -\f[V]M\f[R]: Metaspace utilization as a percentage of the space\[aq]s -current capacity. -.PP -\f[V]CCS\f[R]: Compressed class space utilization as a percentage. -.PP -\f[V]YGC\f[R]: Number of young generation GC events. -.PP -\f[V]YGCT\f[R]: Young generation garbage collection time. -.PP -\f[V]FGC\f[R]: Number of full GC events. -.PP -\f[V]FGCT\f[R]: Full garbage collection time. -.PP -\f[V]GCT\f[R]: Total garbage collection time. -.RE -.TP -\f[V]-printcompilation\f[R] \f[I]option\f[R] -Java HotSpot VM compiler method statistics. -.RS -.PP -\f[V]Compiled\f[R]: Number of compilation tasks performed by the most -recently compiled method. -.PP -\f[V]Size\f[R]: Number of bytes of byte code of the most recently -compiled method. -.PP -\f[V]Type\f[R]: Compilation type of the most recently compiled method. -.PP -\f[V]Method\f[R]: Class name and method name identifying the most -recently compiled method. -Class name uses a slash (/) instead of a dot (.) -as a name space separator. -The method name is the method within the specified class. -The format for these two fields is consistent with the HotSpot -\f[V]-XX:+PrintCompilation\f[R] option. -.RE -.SH VIRTUAL MACHINE IDENTIFIER -.PP -The syntax of the \f[V]vmid\f[R] string corresponds to the syntax of a -URI: -.RS -.PP -[\f[I]protocol\f[R]\f[V]:\f[R]][\f[V]//\f[R]]\f[I]lvmid\f[R][\f[V]\[at]\f[R]\f[I]hostname\f[R][\f[V]:\f[R]\f[I]port\f[R]][\f[V]/\f[R]\f[I]servername\f[R]] -.RE -.PP -The syntax of the \f[V]vmid\f[R] string corresponds to the syntax of a -URI. -The \f[V]vmid\f[R] string can vary from a simple integer that represents -a local JVM to a more complex construction that specifies a -communications protocol, port number, and other implementation-specific -values. -.TP -\f[I]protocol\f[R] -The communications protocol. -If the \f[I]protocol\f[R] value is omitted and a host name isn\[aq]t -specified, then the default protocol is a platform-specific optimized -local protocol. -If the \f[I]protocol\f[R] value is omitted and a host name is specified, -then the default protocol is \f[V]rmi\f[R]. -.TP -\f[I]lvmid\f[R] -The local virtual machine identifier for the target JVM. -The \f[I]lvmid\f[R] is a platform-specific value that uniquely -identifies a JVM on a system. -The \f[I]lvmid\f[R] is the only required component of a virtual machine -identifier. -The \f[I]lvmid\f[R] is typically, but not necessarily, the operating -system\[aq]s process identifier for the target JVM process. -You can use the \f[V]jps\f[R] command to determine the \f[I]lvmid\f[R] -provided the JVM processes is not running in a separate docker instance. -You can also determine the \f[I]lvmid\f[R] on Linux and macOS platforms -with the \f[V]ps\f[R] command, and on Windows with the Windows Task -Manager. -.TP -\f[I]hostname\f[R] -A host name or IP address that indicates the target host. -If the \f[I]hostname\f[R] value is omitted, then the target host is the -local host. -.TP -\f[I]port\f[R] -The default port for communicating with the remote server. -If the \f[I]hostname\f[R] value is omitted or the \f[I]protocol\f[R] -value specifies an optimized, local protocol, then the \f[I]port\f[R] -value is ignored. -Otherwise, treatment of the \f[I]port\f[R] parameter is -implementation-specific. -For the default \f[V]rmi\f[R] protocol, the port value indicates the -port number for the \f[V]rmiregistry\f[R] on the remote host. -If the \f[I]port\f[R] value is omitted and the \f[I]protocol\f[R] value -indicates \f[V]rmi\f[R], then the default rmiregistry port (1099) is -used. -.TP -\f[I]servername\f[R] -The treatment of the \f[I]servername\f[R] parameter depends on -implementation. -For the optimized local protocol, this field is ignored. -For the \f[V]rmi\f[R] protocol, it represents the name of the RMI remote -object on the remote host. -.SH EXAMPLES -.PP -This section presents some examples of monitoring a local JVM with an -\f[I]lvmid\f[R] of 21891. -.SH THE GCUTIL OPTION -.PP -This example attaches to lvmid 21891 and takes 7 samples at 250 -millisecond intervals and displays the output as specified by the -\f[V]-gcutil\f[R] option. -.PP -The output of this example shows that a young generation collection -occurred between the third and fourth sample. -The collection took 0.078 seconds and promoted objects from the eden -space (E) to the old space (O), resulting in an increase of old space -utilization from 66.80% to 68.19%. -Before the collection, the survivor space was 97.02% utilized, but after -this collection it\[aq]s 91.03% utilized. -.IP -.nf -\f[CB] -jstat -gcutil 21891 250 7 - S0 S1 E O M CCS YGC YGCT FGC FGCT GCT - 0.00 97.02 70.31 66.80 95.52 89.14 7 0.300 0 0.000 0.300 - 0.00 97.02 86.23 66.80 95.52 89.14 7 0.300 0 0.000 0.300 - 0.00 97.02 96.53 66.80 95.52 89.14 7 0.300 0 0.000 0.300 - 91.03 0.00 1.98 68.19 95.89 91.24 8 0.378 0 0.000 0.378 - 91.03 0.00 15.82 68.19 95.89 91.24 8 0.378 0 0.000 0.378 - 91.03 0.00 17.80 68.19 95.89 91.24 8 0.378 0 0.000 0.378 - 91.03 0.00 17.80 68.19 95.89 91.24 8 0.378 0 0.000 0.378 -\f[R] -.fi -.SH REPEAT THE COLUMN HEADER STRING -.PP -This example attaches to lvmid 21891 and takes samples at 250 -millisecond intervals and displays the output as specified by -\f[V]-gcnew\f[R] option. -In addition, it uses the \f[V]-h3\f[R] option to output the column -header after every 3 lines of data. -.PP -In addition to showing the repeating header string, this example shows -that between the second and third samples, a young GC occurred. -Its duration was 0.001 seconds. -The collection found enough active data that the survivor space 0 -utilization (S0U) would have exceeded the desired survivor size (DSS). -As a result, objects were promoted to the old generation (not visible in -this output), and the tenuring threshold (TT) was lowered from 31 to 2. -.PP -Another collection occurs between the fifth and sixth samples. -This collection found very few survivors and returned the tenuring -threshold to 31. -.IP -.nf -\f[CB] -jstat -gcnew -h3 21891 250 - S0C S1C S0U S1U TT MTT DSS EC EU YGC YGCT - 64.0 64.0 0.0 31.7 31 31 32.0 512.0 178.6 249 0.203 - 64.0 64.0 0.0 31.7 31 31 32.0 512.0 355.5 249 0.203 - 64.0 64.0 35.4 0.0 2 31 32.0 512.0 21.9 250 0.204 - S0C S1C S0U S1U TT MTT DSS EC EU YGC YGCT - 64.0 64.0 35.4 0.0 2 31 32.0 512.0 245.9 250 0.204 - 64.0 64.0 35.4 0.0 2 31 32.0 512.0 421.1 250 0.204 - 64.0 64.0 0.0 19.0 31 31 32.0 512.0 84.4 251 0.204 - S0C S1C S0U S1U TT MTT DSS EC EU YGC YGCT - 64.0 64.0 0.0 19.0 31 31 32.0 512.0 306.7 251 0.204 -\f[R] -.fi -.SH INCLUDE A TIME STAMP FOR EACH SAMPLE -.PP -This example attaches to lvmid 21891 and takes 3 samples at 250 -millisecond intervals. -The \f[V]-t\f[R] option is used to generate a time stamp for each sample -in the first column. -.PP -The Timestamp column reports the elapsed time in seconds since the start -of the target JVM. -In addition, the \f[V]-gcoldcapacity\f[R] output shows the old -generation capacity (OGC) and the old space capacity (OC) increasing as -the heap expands to meet allocation or promotion demands. -The old generation capacity (OGC) has grown from 11,696 KB to 13,820 KB -after the eighty-first full garbage collection (FGC). -The maximum capacity of the generation (and space) is 60,544 KB (OGCMX), -so it still has room to expand. -.IP -.nf -\f[CB] -Timestamp OGCMN OGCMX OGC OC YGC FGC FGCT GCT - 150.1 1408.0 60544.0 11696.0 11696.0 194 80 2.874 3.799 - 150.4 1408.0 60544.0 13820.0 13820.0 194 81 2.938 3.863 - 150.7 1408.0 60544.0 13820.0 13820.0 194 81 2.938 3.863 -\f[R] -.fi -.SH MONITOR INSTRUMENTATION FOR A REMOTE JVM -.PP -This example attaches to lvmid 40496 on the system named -\f[V]remote.domain\f[R] using the \f[V]-gcutil\f[R] option, with samples -taken every second indefinitely. -.PP -The lvmid is combined with the name of the remote host to construct a -vmid of \f[V]40496\[at]remote.domain\f[R]. -This vmid results in the use of the \f[V]rmi\f[R] protocol to -communicate to the default \f[V]jstatd\f[R] server on the remote host. -The \f[V]jstatd\f[R] server is located using the \f[V]rmiregistry\f[R] -command on \f[V]remote.domain\f[R] that\[aq]s bound to the default port -of the \f[V]rmiregistry\f[R] command (port 1099). -.IP -.nf -\f[CB] -jstat -gcutil 40496\[at]remote.domain 1000 -\&... output omitted -\f[R] -.fi diff --git a/src/jdk.jcmd/share/man/jstat.md b/src/jdk.jcmd/share/man/jstat.md new file mode 100644 index 00000000000..795fc9caa40 --- /dev/null +++ b/src/jdk.jcmd/share/man/jstat.md @@ -0,0 +1,588 @@ +--- +# Copyright (c) 2004, 2023, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# This code is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 only, as +# published by the Free Software Foundation. +# +# This code is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# version 2 for more details (a copy is included in the LICENSE file that +# accompanied this code). +# +# You should have received a copy of the GNU General Public License version +# 2 along with this work; if not, write to the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +# or visit www.oracle.com if you need additional information or have any +# questions. +# + +title: 'JSTAT(1) JDK @@VERSION_SHORT@@ | JDK Commands' +date: @@COPYRIGHT_YEAR@@ +lang: en +--- + +## Name + +jstat - monitor JVM statistics + +## Synopsis + +**Note:** This command is experimental and unsupported. + +`jstat` *generalOptions* + +`jstat` *outputOptions* \[`-t`\] \[`-h` *lines*\] *vmid* \[*interval* +\[*count*\]\] + +*generalOptions* +: A single general command-line option. See [General Options]. + +*outputOptions* +: An option reported by the `-options` option. One or more output options + that consist of a single `statOption`, plus any of the `-t`, `-h`, and `-J` + options. See [Output Options for the jstat Command]. + +`-t` +: Displays a time-stamp column as the first column of output. The time stamp + is the time since the start time of the target JVM. + +`-h` *n* +: Displays a column header every *n* samples (output rows), where *n* is a + positive integer. The default value is `0`, which displays the column + header of the first row of data. + +*vmid* +: A virtual machine identifier, which is a string that indicates the target + JVM. See [Virtual Machine Identifier]. + +*interval* +: The sampling interval in the specified units, seconds (s) or milliseconds + (ms). Default units are milliseconds. This must be a positive integer. When + specified, the `jstat` command produces its output at each interval. + +*count* +: The number of samples to display. The default value is infinity, which + causes the `jstat` command to display statistics until the target JVM + terminates or the `jstat` command is terminated. This value must be a + positive integer. + +## Description + +The `jstat` command displays performance statistics for an instrumented Java +HotSpot VM. The target JVM is identified by its virtual machine identifier, or +`vmid` option. + +The `jstat` command supports two types of options, general options and output +options. General options cause the `jstat` command to display simple usage and +version information. Output options determine the content and format of the +statistical output. + +All options and their functionality are subject to change or removal in future +releases. + +## General Options + +If you specify one of the general options, then you can't specify any other +option or parameter. + +`-help` +: Displays a help message. + +`-options` +: Displays a list of static options. See [Output Options for the jstat + Command]. + +## Output Options for the jstat Command + +If you don't specify a general option, then you can specify output options. +Output options determine the content and format of the `jstat` command's +output, and consist of a single `statOption`, plus any of the other output +options (`-h`, `-t`, and `-J`). The `statOption` must come first. + +Output is formatted as a table, with columns that are separated by spaces. A +header row with titles describes the columns. Use the `-h` option to set the +frequency at which the header is displayed. Column header names are consistent +among the different options. In general, if two options provide a column with +the same name, then the data source for the two columns is the same. + +Use the `-t` option to display a time-stamp column, labeled Timestamp as the +first column of output. The Timestamp column contains the elapsed time, in +seconds, since the target JVM started. The resolution of the time stamp is +dependent on various factors and is subject to variation due to delayed thread +scheduling on heavily loaded systems. + +Use the interval and count parameters to determine how frequently and how many +times, respectively, the `jstat` command displays its output. + +**Note:** + +Don't write scripts to parse the `jstat` command's output because the format +might change in future releases. If you write scripts that parse the `jstat` +command output, then expect to modify them for future releases of this tool. + +`-statOption` +: Determines the statistics information that the `jstat` command displays. + The following lists the available options. Use the `-options` general + option to display the list of options for a particular platform + installation. See [Stat Options and Output]. + + `class`: Displays statistics about the behavior of the class loader. + + `compiler`: Displays statistics about the behavior of the Java HotSpot VM + Just-in-Time compiler. + + `gc`: Displays statistics about the behavior of the garbage collected heap. + + `gccapacity`: Displays statistics about the capacities of the generations + and their corresponding spaces. + + `gccause`: Displays a summary about garbage collection statistics (same as + `-gcutil`), with the cause of the last and current (when applicable) + garbage collection events. + + `gcnew`: Displays statistics about the behavior of the new generation. + + `gcnewcapacity`: Displays statistics about the sizes of the new generations + and their corresponding spaces. + + `gcold`: Displays statistics about the behavior of the old generation and + metaspace statistics. + + `gcoldcapacity`: Displays statistics about the sizes of the old generation. + + `gcmetacapacity`: Displays statistics about the sizes of the metaspace. + + `gcutil`: Displays a summary about garbage collection statistics. + + `printcompilation`: Displays Java HotSpot VM compilation method statistics. + +`-J`*javaOption* +: Passes *javaOption* to the Java application launcher. For example, + `-J-Xms48m` sets the startup memory to 48 MB. For a complete list of + options, see [java](java.html). + +## Stat Options and Output + +The following information summarizes the columns that the `jstat` command +outputs for each *statOption*. + +`-class` *option* +: Class loader statistics. + + `Loaded`: Number of classes loaded. + + `Bytes`: Number of KB loaded. + + `Unloaded`: Number of classes unloaded. + + `Bytes`: Number of KB unloaded. + + `Time`: Time spent performing class loading and unloading operations. + +`-compiler` *option* +: Java HotSpot VM Just-in-Time compiler statistics. + + `Compiled`: Number of compilation tasks performed. + + `Failed`: Number of compilations tasks failed. + + `Invalid`: Number of compilation tasks that were invalidated. + + `Time`: Time spent performing compilation tasks. + + `FailedType`: Compile type of the last failed compilation. + + `FailedMethod`: Class name and method of the last failed compilation. + +`-gc` *option* +: Garbage collected heap statistics. + + `S0C`: Current survivor space 0 capacity (KB). + + `S1C`: Current survivor space 1 capacity (KB). + + `S0U`: Survivor space 0 utilization (KB). + + `S1U`: Survivor space 1 utilization (KB). + + `EC`: Current eden space capacity (KB). + + `EU`: Eden space utilization (KB). + + `OC`: Current old space capacity (KB). + + `OU`: Old space utilization (KB). + + `MC`: Metaspace Committed Size (KB). + + `MU`: Metaspace utilization (KB). + + `CCSC`: Compressed class committed size (KB). + + `CCSU`: Compressed class space used (KB). + + `YGC`: Number of young generation garbage collection (GC) events. + + `YGCT`: Young generation garbage collection time. + + `FGC`: Number of full GC events. + + `FGCT`: Full garbage collection time. + + `GCT`: Total garbage collection time. + +`-gccapacity` *option* +: Memory pool generation and space capacities. + + `NGCMN`: Minimum new generation capacity (KB). + + `NGCMX`: Maximum new generation capacity (KB). + + `NGC`: Current new generation capacity (KB). + + `S0C`: Current survivor space 0 capacity (KB). + + `S1C`: Current survivor space 1 capacity (KB). + + `EC`: Current eden space capacity (KB). + + `OGCMN`: Minimum old generation capacity (KB). + + `OGCMX`: Maximum old generation capacity (KB). + + `OGC`: Current old generation capacity (KB). + + `OC`: Current old space capacity (KB). + + `MCMN`: Minimum metaspace capacity (KB). + + `MCMX`: Maximum metaspace capacity (KB). + + `MC`: Metaspace Committed Size (KB). + + `CCSMN`: Compressed class space minimum capacity (KB). + + `CCSMX`: Compressed class space maximum capacity (KB). + + `CCSC`: Compressed class committed size (KB). + + `YGC`: Number of young generation GC events. + + `FGC`: Number of full GC events. + +`-gccause` *option* +: This option displays the same summary of garbage collection statistics as + the `-gcutil` option, but includes the causes of the last garbage + collection event and (when applicable), the current garbage collection + event. In addition to the columns listed for `-gcutil`, this option adds + the following columns: + + `LGCC`: Cause of last garbage collection + + `GCC`: Cause of current garbage collection + +`-gcnew` *option* +: New generation statistics. + + `S0C`: Current survivor space 0 capacity (KB). + + `S1C`: Current survivor space 1 capacity (KB). + + `S0U`: Survivor space 0 utilization (KB). + + `S1U`: Survivor space 1 utilization (KB). + + `TT`: Tenuring threshold. + + `MTT`: Maximum tenuring threshold. + + `DSS`: Desired survivor size (KB). + + `EC`: Current eden space capacity (KB). + + `EU`: Eden space utilization (KB). + + `YGC`: Number of young generation GC events. + + `YGCT`: Young generation garbage collection time. + +`-gcnewcapacity` *option* +: New generation space size statistics. + + `NGCMN`: Minimum new generation capacity (KB). + + `NGCMX`: Maximum new generation capacity (KB). + + `NGC`: Current new generation capacity (KB). + + `S0CMX`: Maximum survivor space 0 capacity (KB). + + `S0C`: Current survivor space 0 capacity (KB). + + `S1CMX`: Maximum survivor space 1 capacity (KB). + + `S1C`: Current survivor space 1 capacity (KB). + + `ECMX`: Maximum eden space capacity (KB). + + `EC`: Current eden space capacity (KB). + + `YGC`: Number of young generation GC events. + + `FGC`: Number of full GC events. + +`-gcold` *option* +: Old generation size statistics. + + `MC`: Metaspace Committed Size (KB). + + `MU`: Metaspace utilization (KB). + + `CCSC`: Compressed class committed size (KB). + + `CCSU`: Compressed class space used (KB). + + `OC`: Current old space capacity (KB). + + `OU`: Old space utilization (KB). + + `YGC`: Number of young generation GC events. + + `FGC`: Number of full GC events. + + `FGCT`: Full garbage collection time. + + `GCT`: Total garbage collection time. + +`-gcoldcapacity` *option* +: Old generation statistics. + + `OGCMN`: Minimum old generation capacity (KB). + + `OGCMX`: Maximum old generation capacity (KB). + + `OGC`: Current old generation capacity (KB). + + `OC`: Current old space capacity (KB). + + `YGC`: Number of young generation GC events. + + `FGC`: Number of full GC events. + + `FGCT`: Full garbage collection time. + + `GCT`: Total garbage collection time. + +`-gcmetacapacity` *option* +: Metaspace size statistics. + + `MCMN`: Minimum metaspace capacity (KB). + + `MCMX`: Maximum metaspace capacity (KB). + + `MC`: Metaspace Committed Size (KB). + + `CCSMN`: Compressed class space minimum capacity (KB). + + `CCSMX`: Compressed class space maximum capacity (KB). + + `YGC`: Number of young generation GC events. + + `FGC`: Number of full GC events. + + `FGCT`: Full garbage collection time. + + `GCT`: Total garbage collection time. + +`-gcutil` *option* +: Summary of garbage collection statistics. + + `S0`: Survivor space 0 utilization as a percentage of the space's current + capacity. + + `S1`: Survivor space 1 utilization as a percentage of the space's current + capacity. + + `E`: Eden space utilization as a percentage of the space's current + capacity. + + `O`: Old space utilization as a percentage of the space's current capacity. + + `M`: Metaspace utilization as a percentage of the space's current capacity. + + `CCS`: Compressed class space utilization as a percentage. + + `YGC`: Number of young generation GC events. + + `YGCT`: Young generation garbage collection time. + + `FGC`: Number of full GC events. + + `FGCT`: Full garbage collection time. + + `GCT`: Total garbage collection time. + +`-printcompilation` *option* +: Java HotSpot VM compiler method statistics. + + `Compiled`: Number of compilation tasks performed by the most recently + compiled method. + + `Size`: Number of bytes of byte code of the most recently compiled method. + + `Type`: Compilation type of the most recently compiled method. + + `Method`: Class name and method name identifying the most recently compiled + method. Class name uses a slash (/) instead of a dot (.) as a name space + separator. The method name is the method within the specified class. The + format for these two fields is consistent with the HotSpot + `-XX:+PrintCompilation` option. + +## Virtual Machine Identifier + +The syntax of the `vmid` string corresponds to the syntax of a URI: + +> \[*protocol*`:`\]\[`//`\]*lvmid*\[`@`*hostname*\[`:`*port*\]\[`/`*servername*\] + +The syntax of the `vmid` string corresponds to the syntax of a URI. The `vmid` +string can vary from a simple integer that represents a local JVM to a more +complex construction that specifies a communications protocol, port number, and +other implementation-specific values. + +*protocol* +: The communications protocol. If the *protocol* value is omitted and a host + name isn't specified, then the default protocol is a platform-specific + optimized local protocol. If the *protocol* value is omitted and a host + name is specified, then the default protocol is `rmi`. + +*lvmid* +: The local virtual machine identifier for the target JVM. The *lvmid* is a + platform-specific value that uniquely identifies a JVM on a system. The + *lvmid* is the only required component of a virtual machine identifier. The + *lvmid* is typically, but not necessarily, the operating system's process + identifier for the target JVM process. You can use the `jps` command to + determine the *lvmid* provided the JVM processes is not running in a + separate docker instance. You can also determine the *lvmid* on Linux and + macOS platforms with the `ps` command, and on Windows with the Windows Task + Manager. + +*hostname* +: A host name or IP address that indicates the target host. If the *hostname* + value is omitted, then the target host is the local host. + +*port* +: The default port for communicating with the remote server. If the + *hostname* value is omitted or the *protocol* value specifies an optimized, + local protocol, then the *port* value is ignored. Otherwise, treatment of + the *port* parameter is implementation-specific. For the default `rmi` + protocol, the port value indicates the port number for the `rmiregistry` on + the remote host. If the *port* value is omitted and the *protocol* value + indicates `rmi`, then the default rmiregistry port (1099) is used. + +*servername* +: The treatment of the *servername* parameter depends on implementation. For + the optimized local protocol, this field is ignored. For the `rmi` + protocol, it represents the name of the RMI remote object on the remote + host. + +## Examples + +This section presents some examples of monitoring a local JVM with an *lvmid* +of 21891. + +## The gcutil Option + +This example attaches to lvmid 21891 and takes 7 samples at 250 millisecond +intervals and displays the output as specified by the `-gcutil` option. + +The output of this example shows that a young generation collection occurred +between the third and fourth sample. The collection took 0.078 seconds and +promoted objects from the eden space (E) to the old space (O), resulting in an +increase of old space utilization from 66.80% to 68.19%. Before the collection, +the survivor space was 97.02% utilized, but after this collection it's 91.03% +utilized. + +``` +jstat -gcutil 21891 250 7 + S0 S1 E O M CCS YGC YGCT FGC FGCT GCT + 0.00 97.02 70.31 66.80 95.52 89.14 7 0.300 0 0.000 0.300 + 0.00 97.02 86.23 66.80 95.52 89.14 7 0.300 0 0.000 0.300 + 0.00 97.02 96.53 66.80 95.52 89.14 7 0.300 0 0.000 0.300 + 91.03 0.00 1.98 68.19 95.89 91.24 8 0.378 0 0.000 0.378 + 91.03 0.00 15.82 68.19 95.89 91.24 8 0.378 0 0.000 0.378 + 91.03 0.00 17.80 68.19 95.89 91.24 8 0.378 0 0.000 0.378 + 91.03 0.00 17.80 68.19 95.89 91.24 8 0.378 0 0.000 0.378 +``` + +## Repeat the Column Header String + +This example attaches to lvmid 21891 and takes samples at 250 millisecond +intervals and displays the output as specified by `-gcnew` option. In addition, +it uses the `-h3` option to output the column header after every 3 lines of +data. + +In addition to showing the repeating header string, this example shows that +between the second and third samples, a young GC occurred. Its duration was +0.001 seconds. The collection found enough active data that the survivor space +0 utilization (S0U) would have exceeded the desired survivor size (DSS). As a +result, objects were promoted to the old generation (not visible in this +output), and the tenuring threshold (TT) was lowered from 31 to 2. + +Another collection occurs between the fifth and sixth samples. This collection +found very few survivors and returned the tenuring threshold to 31. + +``` +jstat -gcnew -h3 21891 250 + S0C S1C S0U S1U TT MTT DSS EC EU YGC YGCT + 64.0 64.0 0.0 31.7 31 31 32.0 512.0 178.6 249 0.203 + 64.0 64.0 0.0 31.7 31 31 32.0 512.0 355.5 249 0.203 + 64.0 64.0 35.4 0.0 2 31 32.0 512.0 21.9 250 0.204 + S0C S1C S0U S1U TT MTT DSS EC EU YGC YGCT + 64.0 64.0 35.4 0.0 2 31 32.0 512.0 245.9 250 0.204 + 64.0 64.0 35.4 0.0 2 31 32.0 512.0 421.1 250 0.204 + 64.0 64.0 0.0 19.0 31 31 32.0 512.0 84.4 251 0.204 + S0C S1C S0U S1U TT MTT DSS EC EU YGC YGCT + 64.0 64.0 0.0 19.0 31 31 32.0 512.0 306.7 251 0.204 +``` + +## Include a Time Stamp for Each Sample + +This example attaches to lvmid 21891 and takes 3 samples at 250 millisecond +intervals. The `-t` option is used to generate a time stamp for each sample in +the first column. + +The Timestamp column reports the elapsed time in seconds since the start of the +target JVM. In addition, the `-gcoldcapacity` output shows the old generation +capacity (OGC) and the old space capacity (OC) increasing as the heap expands +to meet allocation or promotion demands. The old generation capacity (OGC) has +grown from 11,696 KB to 13,820 KB after the eighty-first full garbage +collection (FGC). The maximum capacity of the generation (and space) is 60,544 +KB (OGCMX), so it still has room to expand. + +``` +Timestamp OGCMN OGCMX OGC OC YGC FGC FGCT GCT + 150.1 1408.0 60544.0 11696.0 11696.0 194 80 2.874 3.799 + 150.4 1408.0 60544.0 13820.0 13820.0 194 81 2.938 3.863 + 150.7 1408.0 60544.0 13820.0 13820.0 194 81 2.938 3.863 +``` + +## Monitor Instrumentation for a Remote JVM + +This example attaches to lvmid 40496 on the system named `remote.domain` using +the `-gcutil` option, with samples taken every second indefinitely. + +The lvmid is combined with the name of the remote host to construct a vmid of +`40496@remote.domain`. This vmid results in the use of the `rmi` protocol to +communicate to the default `jstatd` server on the remote host. The `jstatd` +server is located using the `rmiregistry` command on `remote.domain` that's +bound to the default port of the `rmiregistry` command (port 1099). + +``` +jstat -gcutil 40496@remote.domain 1000 +... output omitted +``` diff --git a/src/jdk.jconsole/share/man/jconsole.1 b/src/jdk.jconsole/share/man/jconsole.1 deleted file mode 100644 index ec70040acf4..00000000000 --- a/src/jdk.jconsole/share/man/jconsole.1 +++ /dev/null @@ -1,104 +0,0 @@ -.\" Copyright (c) 2004, 2018, Oracle and/or its affiliates. All rights reserved. -.\" DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -.\" -.\" This code is free software; you can redistribute it and/or modify it -.\" under the terms of the GNU General Public License version 2 only, as -.\" published by the Free Software Foundation. -.\" -.\" This code is distributed in the hope that it will be useful, but WITHOUT -.\" ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -.\" FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -.\" version 2 for more details (a copy is included in the LICENSE file that -.\" accompanied this code). -.\" -.\" You should have received a copy of the GNU General Public License version -.\" 2 along with this work; if not, write to the Free Software Foundation, -.\" Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -.\" -.\" Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -.\" or visit www.oracle.com if you need additional information or have any -.\" questions. -.\" -.\" Automatically generated by Pandoc 2.19.2 -.\" -.\" Define V font for inline verbatim, using C font in formats -.\" that render this, and otherwise B font. -.ie "\f[CB]x\f[R]"x" \{\ -. ftr V B -. ftr VI BI -. ftr VB B -. ftr VBI BI -.\} -.el \{\ -. ftr V CR -. ftr VI CI -. ftr VB CB -. ftr VBI CBI -.\} -.TH "JCONSOLE" "1" "2025" "JDK 24-ea" "JDK Commands" -.hy -.SH NAME -.PP -jconsole - start a graphical console to monitor and manage Java -applications -.SH SYNOPSIS -.PP -\f[V]jconsole\f[R] [\f[V]-interval=\f[R]\f[I]n\f[R]] [\f[V]-notile\f[R]] -[\f[V]-plugin\f[R] \f[I]path\f[R]] [\f[V]-version\f[R]] -[\f[I]connection\f[R] ... -] [\f[V]-J\f[R]\f[I]input_arguments\f[R]] -.PP -\f[V]jconsole\f[R] \f[V]-help\f[R] -.SH OPTIONS -.TP -\f[V]-interval\f[R] -Sets the update interval to \f[V]n\f[R] seconds (default is 4 seconds). -.TP -\f[V]-notile\f[R] -Doesn\[aq]t tile the windows for two or more connections. -.TP -\f[V]-pluginpath\f[R] \f[I]path\f[R] -Specifies the path that \f[V]jconsole\f[R] uses to look up plug-ins. -The plug-in \f[I]path\f[R] should contain a provider-configuration file -named \f[V]META-INF/services/com.sun.tools.jconsole.JConsolePlugin\f[R] -that contains one line for each plug-in. -The line specifies the fully qualified class name of the class -implementing the \f[V]com.sun.tools.jconsole.JConsolePlugin\f[R] class. -.TP -\f[V]-version\f[R] -Prints the program version. -.TP -\f[I]connection\f[R] = \f[I]pid\f[R] | \f[I]host\f[R]\f[V]:\f[R]\f[I]port\f[R] | \f[I]jmxURL\f[R] -A connection is described by either \f[I]pid\f[R], -\f[I]host\f[R]\f[V]:\f[R]\f[I]port\f[R] or \f[I]jmxURL\f[R]. -.RS -.IP \[bu] 2 -The \f[I]pid\f[R] value is the process ID of a target process. -The JVM must be running with the same user ID as the user ID running the -\f[V]jconsole\f[R] command. -.IP \[bu] 2 -The \f[I]host\f[R]\f[V]:\f[R]\f[I]port\f[R] values are the name of the -host system on which the JVM is running, and the port number specified -by the system property \f[V]com.sun.management.jmxremote.port\f[R] when -the JVM was started. -.IP \[bu] 2 -The \f[I]jmxUrl\f[R] value is the address of the JMX agent to be -connected to as described in JMXServiceURL. -.RE -.TP -\f[V]-J\f[R]\f[I]input_arguments\f[R] -Passes \f[I]input_arguments\f[R] to the JVM on which the -\f[V]jconsole\f[R] command is run. -.TP -\f[V]-help\f[R] or \f[V]--help\f[R] -Displays the help message for the command. -.SH DESCRIPTION -.PP -The \f[V]jconsole\f[R] command starts a graphical console tool that lets -you monitor and manage Java applications and virtual machines on a local -or remote machine. -.PP -On Windows, the \f[V]jconsole\f[R] command doesn\[aq]t associate with a -console window. -It does, however, display a dialog box with error information when the -\f[V]jconsole\f[R] command fails. diff --git a/src/jdk.jconsole/share/man/jconsole.md b/src/jdk.jconsole/share/man/jconsole.md new file mode 100644 index 00000000000..59c84a0431a --- /dev/null +++ b/src/jdk.jconsole/share/man/jconsole.md @@ -0,0 +1,86 @@ +--- +# Copyright (c) 2004, 2018, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# This code is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 only, as +# published by the Free Software Foundation. +# +# This code is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# version 2 for more details (a copy is included in the LICENSE file that +# accompanied this code). +# +# You should have received a copy of the GNU General Public License version +# 2 along with this work; if not, write to the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +# or visit www.oracle.com if you need additional information or have any +# questions. +# + +title: 'JCONSOLE(1) JDK @@VERSION_SHORT@@ | JDK Commands' +date: @@COPYRIGHT_YEAR@@ +lang: en +--- + +## Name + +jconsole - start a graphical console to monitor and manage Java applications + +## Synopsis + +`jconsole` \[`-interval=`*n*\] \[`-notile`\] \[`-plugin` *path*\] +\[`-version`\] \[*connection* ... \] \[`-J`*input\_arguments*\] + +`jconsole` `-help` + +## Options + +`-interval` +: Sets the update interval to `n` seconds (default is 4 seconds). + +`-notile` +: Doesn't tile the windows for two or more connections. + +`-pluginpath` *path* +: Specifies the path that `jconsole` uses to look up plug-ins. The plug-in + *path* should contain a provider-configuration file named + `META-INF/services/com.sun.tools.jconsole.JConsolePlugin` that contains one + line for each plug-in. The line specifies the fully qualified class name of + the class implementing the `com.sun.tools.jconsole.JConsolePlugin` class. + +`-version` +: Prints the program version. + +*connection* = *pid* \| *host*`:`*port* \| *jmxURL* +: A connection is described by either *pid*, *host*`:`*port* or *jmxURL*. + + - The *pid* value is the process ID of a target process. The JVM must be + running with the same user ID as the user ID running the `jconsole` + command. + + - The *host*`:`*port* values are the name of the host system on which the + JVM is running, and the port number specified by the system property + `com.sun.management.jmxremote.port` when the JVM was started. + + - The *jmxUrl* value is the address of the JMX agent to be connected to + as described in JMXServiceURL. + +`-J`*input\_arguments* +: Passes *input\_arguments* to the JVM on which the `jconsole` command is + run. + +`-help` or `--help` +: Displays the help message for the command. + +## Description + +The `jconsole` command starts a graphical console tool that lets you monitor +and manage Java applications and virtual machines on a local or remote machine. + +On Windows, the `jconsole` command doesn't associate with a console window. It +does, however, display a dialog box with error information when the `jconsole` +command fails. diff --git a/src/jdk.jdeps/share/man/javap.1 b/src/jdk.jdeps/share/man/javap.1 deleted file mode 100644 index 27b0a29d0ba..00000000000 --- a/src/jdk.jdeps/share/man/javap.1 +++ /dev/null @@ -1,259 +0,0 @@ -.\" Copyright (c) 1994, 2020, Oracle and/or its affiliates. All rights reserved. -.\" DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -.\" -.\" This code is free software; you can redistribute it and/or modify it -.\" under the terms of the GNU General Public License version 2 only, as -.\" published by the Free Software Foundation. -.\" -.\" This code is distributed in the hope that it will be useful, but WITHOUT -.\" ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -.\" FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -.\" version 2 for more details (a copy is included in the LICENSE file that -.\" accompanied this code). -.\" -.\" You should have received a copy of the GNU General Public License version -.\" 2 along with this work; if not, write to the Free Software Foundation, -.\" Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -.\" -.\" Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -.\" or visit www.oracle.com if you need additional information or have any -.\" questions. -.\" -.\" Automatically generated by Pandoc 2.19.2 -.\" -.\" Define V font for inline verbatim, using C font in formats -.\" that render this, and otherwise B font. -.ie "\f[CB]x\f[R]"x" \{\ -. ftr V B -. ftr VI BI -. ftr VB B -. ftr VBI BI -.\} -.el \{\ -. ftr V CR -. ftr VI CI -. ftr VB CB -. ftr VBI CBI -.\} -.TH "JAVAP" "1" "2025" "JDK 24-ea" "JDK Commands" -.hy -.SH NAME -.PP -javap - disassemble one or more class files -.SH SYNOPSIS -.PP -\f[V]javap\f[R] [\f[I]options\f[R]] \f[I]classes\f[R]... -.TP -\f[I]options\f[R] -Specifies the command-line options. -See \f[B]Options for javap\f[R]. -.TP -\f[I]classes\f[R] -Specifies one or more classes separated by spaces to be processed for -annotations. -You can specify a class that can be found in the class path by its file -name, URL, or by its fully qualified class name. -.RS -.PP -Examples: -.RS -.PP -\f[V]path/to/MyClass.class\f[R] -.RE -.RS -.PP -\f[V]jar:file:///path/to/MyJar.jar!/mypkg/MyClass.class\f[R] -.RE -.RS -.PP -\f[V]java.lang.Object\f[R] -.RE -.RE -.SH DESCRIPTION -.PP -The \f[V]javap\f[R] command disassembles one or more class files. -The output depends on the options used. -When no options are used, the \f[V]javap\f[R] command prints the -protected and public fields, and methods of the classes passed to it. -.PP -The \f[V]javap\f[R] command isn\[aq]t multirelease JAR aware. -Using the class path form of the command results in viewing the base -entry in all JAR files, multirelease or not. -Using the URL form, you can use the URL form of an argument to specify a -specific version of a class to be disassembled. -.PP -The \f[V]javap\f[R] command prints its output to \f[V]stdout\f[R]. -.PP -\f[B]Note:\f[R] -.PP -In tools that support \f[V]--\f[R] style options, the GNU-style options -can use the equal sign (\f[V]=\f[R]) instead of a white space to -separate the name of an option from its value. -.SH OPTIONS FOR JAVAP -.TP -\f[V]--help\f[R], \f[V]-help\f[R] , \f[V]-h\f[R], or \f[V]-?\f[R] -Prints a help message for the \f[V]javap\f[R] command. -.TP -\f[V]-version\f[R] -Prints release information. -.TP -\f[V]-verbose\f[R] or \f[V]-v\f[R] -Prints additional information about the selected class. -.TP -\f[V]-l\f[R] -Prints line and local variable tables. -.TP -\f[V]-public\f[R] -Shows only public classes and members. -.TP -\f[V]-protected\f[R] -Shows only protected and public classes and members. -.TP -\f[V]-package\f[R] -Shows package/protected/public classes and members (default). -.TP -\f[V]-private\f[R] or \f[V]-p\f[R] -Shows all classes and members. -.TP -\f[V]-c\f[R] -Prints disassembled code, for example, the instructions that comprise -the Java bytecodes, for each of the methods in the class. -.TP -\f[V]-s\f[R] -Prints internal type signatures. -.TP -\f[V]-sysinfo\f[R] -Shows system information (path, size, date, SHA-256 hash) of the class -being processed. -.TP -\f[V]-verify\f[R] -Prints additional class verification info. -.TP -\f[V]-constants\f[R] -Shows \f[V]static final\f[R] constants. -.TP -\f[V]--module\f[R] \f[I]module\f[R] or \f[V]-m\f[R] \f[I]module\f[R] -Specifies the module containing classes to be disassembled. -.TP -\f[V]--module-path\f[R] \f[I]path\f[R] -Specifies where to find application modules. -.TP -\f[V]--system\f[R] \f[I]jdk\f[R] -Specifies where to find system modules. -.TP -\f[V]--class-path\f[R] \f[I]path\f[R], \f[V]-classpath\f[R] \f[I]path\f[R], or \f[V]-cp\f[R] \f[I]path\f[R] -Specifies the path that the \f[V]javap\f[R] command uses to find user -class files. -It overrides the default or the \f[V]CLASSPATH\f[R] environment variable -when it\[aq]s set. -.TP -\f[V]-bootclasspath\f[R] \f[I]path\f[R] -Overrides the location of bootstrap class files. -.TP -\f[V]--multi-release\f[R] \f[I]version\f[R] -Specifies the version to select in multi-release JAR files. -.TP -\f[V]-J\f[R]\f[I]option\f[R] -Passes the specified option to the JVM. -For example: -.RS -.IP -.nf -\f[CB] -javap -J-version - -javap -J-Djava.security.manager -J-Djava.security.policy=MyPolicy MyClassName -\f[R] -.fi -.PP -See \f[I]Overview of Java Options\f[R] in \f[B]java\f[R]. -.RE -.SH JAVAP EXAMPLE -.PP -Compile the following \f[V]HelloWorldFrame\f[R] class: -.IP -.nf -\f[CB] -import java.awt.Graphics; - -import javax.swing.JFrame; -import javax.swing.JPanel; - -public class HelloWorldFrame extends JFrame { - - String message = \[dq]Hello World!\[dq]; - - public HelloWorldFrame(){ - setContentPane(new JPanel(){ - \[at]Override - protected void paintComponent(Graphics g) { - g.drawString(message, 15, 30); - } - }); - setSize(100, 100); - } - public static void main(String[] args) { - HelloWorldFrame frame = new HelloWorldFrame(); - frame.setVisible(true); - - } - -} -\f[R] -.fi -.PP -The output from the \f[V]javap HelloWorldFrame.class\f[R] command yields -the following: -.IP -.nf -\f[CB] -Compiled from \[dq]HelloWorldFrame.java\[dq] -public class HelloWorldFrame extends javax.swing.JFrame { - java.lang.String message; - public HelloWorldFrame(); - public static void main(java.lang.String[]); -} -\f[R] -.fi -.PP -The output from the \f[V]javap -c HelloWorldFrame.class\f[R] command -yields the following: -.IP -.nf -\f[CB] -Compiled from \[dq]HelloWorldFrame.java\[dq] -public class HelloWorldFrame extends javax.swing.JFrame { - java.lang.String message; - - public HelloWorldFrame(); - Code: - 0: aload_0 - 1: invokespecial #1 // Method javax/swing/JFrame.\[dq]<init>\[dq]:()V - 4: aload_0 - 5: ldc #2 // String Hello World! - 7: putfield #3 // Field message:Ljava/lang/String; - 10: aload_0 - 11: new #4 // class HelloWorldFrame$1 - 14: dup - 15: aload_0 - 16: invokespecial #5 // Method HelloWorldFrame$1.\[dq]<init>\[dq]:(LHelloWorldFrame;)V - 19: invokevirtual #6 // Method setContentPane:(Ljava/awt/Container;)V - 22: aload_0 - 23: bipush 100 - 25: bipush 100 - 27: invokevirtual #7 // Method setSize:(II)V - 30: return - - public static void main(java.lang.String[]); - Code: - 0: new #8 // class HelloWorldFrame - 3: dup - 4: invokespecial #9 // Method \[dq]<init>\[dq]:()V - 7: astore_1 - 8: aload_1 - 9: iconst_1 - 10: invokevirtual #10 // Method setVisible:(Z)V - 13: return -} -\f[R] -.fi diff --git a/src/jdk.jdeps/share/man/javap.md b/src/jdk.jdeps/share/man/javap.md new file mode 100644 index 00000000000..814db56b3ba --- /dev/null +++ b/src/jdk.jdeps/share/man/javap.md @@ -0,0 +1,227 @@ +--- +# Copyright (c) 1994, 2020, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# This code is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 only, as +# published by the Free Software Foundation. +# +# This code is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# version 2 for more details (a copy is included in the LICENSE file that +# accompanied this code). +# +# You should have received a copy of the GNU General Public License version +# 2 along with this work; if not, write to the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +# or visit www.oracle.com if you need additional information or have any +# questions. +# + +title: 'JAVAP(1) JDK @@VERSION_SHORT@@ | JDK Commands' +date: @@COPYRIGHT_YEAR@@ +lang: en +--- + +## Name + +javap - disassemble one or more class files + +## Synopsis + +`javap` \[*options*\] *classes*... + +*options* +: Specifies the command-line options. See [Options for javap]. + +*classes* +: Specifies one or more classes separated by spaces to be processed for + annotations. You can specify a class that can be found in the class path by + its file name, URL, or by its fully qualified class name. + + Examples: + + > `path/to/MyClass.class` + + > `jar:file:///path/to/MyJar.jar!/mypkg/MyClass.class` + + > `java.lang.Object` + +## Description + +The `javap` command disassembles one or more class files. The output depends on +the options used. When no options are used, the `javap` command prints the +protected and public fields, and methods of the classes passed to it. + +The `javap` command isn't multirelease JAR aware. Using the class path form of +the command results in viewing the base entry in all JAR files, multirelease or +not. Using the URL form, you can use the URL form of an argument to specify a +specific version of a class to be disassembled. + +The `javap` command prints its output to `stdout`. + +**Note:** + +In tools that support `--` style options, the GNU-style options can use the +equal sign (`=`) instead of a white space to separate the name of an option +from its value. + +## Options for javap + +`--help`, `-help` , `-h`, or `-?` +: Prints a help message for the `javap` command. + +`-version` +: Prints release information. + +`-verbose` or `-v` +: Prints additional information about the selected class. + +`-l` +: Prints line and local variable tables. + +`-public` +: Shows only public classes and members. + +`-protected` +: Shows only protected and public classes and members. + +`-package` +: Shows package/protected/public classes and members (default). + +`-private` or `-p` +: Shows all classes and members. + +`-c` +: Prints disassembled code, for example, the instructions that comprise the + Java bytecodes, for each of the methods in the class. + +`-s` +: Prints internal type signatures. + +`-sysinfo` +: Shows system information (path, size, date, SHA-256 hash) of the class being + processed. + +`-verify` +: Prints additional class verification info. + +`-constants` +: Shows `static final` constants. + +`--module` *module* or `-m` *module* +: Specifies the module containing classes to be disassembled. + +`--module-path` *path* +: Specifies where to find application modules. + +`--system` *jdk* +: Specifies where to find system modules. + +`--class-path` *path*, `-classpath` *path*, or `-cp` *path* +: Specifies the path that the `javap` command uses to find user class files. + It overrides the default or the `CLASSPATH` environment variable when it's + set. + +`-bootclasspath` *path* +: Overrides the location of bootstrap class files. + +`--multi-release` *version* +: Specifies the version to select in multi-release JAR files. + +`-J`*option* +: Passes the specified option to the JVM. For example: + + ``` + javap -J-version + + javap -J-Djava.security.manager -J-Djava.security.policy=MyPolicy MyClassName + ``` + + See *Overview of Java Options* in [java](java.html). + +## javap Example + +Compile the following `HelloWorldFrame` class: + +``` +import java.awt.Graphics; + +import javax.swing.JFrame; +import javax.swing.JPanel; + +public class HelloWorldFrame extends JFrame { + + String message = "Hello World!"; + + public HelloWorldFrame(){ + setContentPane(new JPanel(){ + @Override + protected void paintComponent(Graphics g) { + g.drawString(message, 15, 30); + } + }); + setSize(100, 100); + } + public static void main(String[] args) { + HelloWorldFrame frame = new HelloWorldFrame(); + frame.setVisible(true); + + } + +} +``` + +The output from the `javap HelloWorldFrame.class` command yields the following: + +``` +Compiled from "HelloWorldFrame.java" +public class HelloWorldFrame extends javax.swing.JFrame { + java.lang.String message; + public HelloWorldFrame(); + public static void main(java.lang.String[]); +} +``` + +The output from the `javap -c HelloWorldFrame.class` command yields the +following: + +``` +Compiled from "HelloWorldFrame.java" +public class HelloWorldFrame extends javax.swing.JFrame { + java.lang.String message; + + public HelloWorldFrame(); + Code: + 0: aload_0 + 1: invokespecial #1 // Method javax/swing/JFrame."<init>":()V + 4: aload_0 + 5: ldc #2 // String Hello World! + 7: putfield #3 // Field message:Ljava/lang/String; + 10: aload_0 + 11: new #4 // class HelloWorldFrame$1 + 14: dup + 15: aload_0 + 16: invokespecial #5 // Method HelloWorldFrame$1."<init>":(LHelloWorldFrame;)V + 19: invokevirtual #6 // Method setContentPane:(Ljava/awt/Container;)V + 22: aload_0 + 23: bipush 100 + 25: bipush 100 + 27: invokevirtual #7 // Method setSize:(II)V + 30: return + + public static void main(java.lang.String[]); + Code: + 0: new #8 // class HelloWorldFrame + 3: dup + 4: invokespecial #9 // Method "<init>":()V + 7: astore_1 + 8: aload_1 + 9: iconst_1 + 10: invokevirtual #10 // Method setVisible:(Z)V + 13: return +} +``` diff --git a/src/jdk.jdeps/share/man/jdeprscan.1 b/src/jdk.jdeps/share/man/jdeprscan.1 deleted file mode 100644 index fc13f05c449..00000000000 --- a/src/jdk.jdeps/share/man/jdeprscan.1 +++ /dev/null @@ -1,271 +0,0 @@ -.\" Copyright (c) 2017, 2023, Oracle and/or its affiliates. All rights reserved. -.\" DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -.\" -.\" This code is free software; you can redistribute it and/or modify it -.\" under the terms of the GNU General Public License version 2 only, as -.\" published by the Free Software Foundation. -.\" -.\" This code is distributed in the hope that it will be useful, but WITHOUT -.\" ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -.\" FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -.\" version 2 for more details (a copy is included in the LICENSE file that -.\" accompanied this code). -.\" -.\" You should have received a copy of the GNU General Public License version -.\" 2 along with this work; if not, write to the Free Software Foundation, -.\" Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -.\" -.\" Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -.\" or visit www.oracle.com if you need additional information or have any -.\" questions. -.\" -.\" Automatically generated by Pandoc 2.19.2 -.\" -.\" Define V font for inline verbatim, using C font in formats -.\" that render this, and otherwise B font. -.ie "\f[CB]x\f[R]"x" \{\ -. ftr V B -. ftr VI BI -. ftr VB B -. ftr VBI BI -.\} -.el \{\ -. ftr V CR -. ftr VI CI -. ftr VB CB -. ftr VBI CBI -.\} -.TH "JDEPRSCAN" "1" "2025" "JDK 24-ea" "JDK Commands" -.hy -.SH NAME -.PP -jdeprscan - static analysis tool that scans a jar file (or some other -aggregation of class files) for uses of deprecated API elements -.SH SYNOPSIS -.PP -\f[V]jdeprscan\f[R] [\f[I]options\f[R]] -{\f[I]dir\f[R]|\f[I]jar\f[R]|\f[I]class\f[R]} -.TP -\f[I]options\f[R] -See \f[B]Options for the jdeprscan Command\f[R] -.TP -\f[I]dir\f[R]|\f[I]jar\f[R]|\f[I]class\f[R] -\f[V]jdeprscan\f[R] command scans each argument for usages of deprecated -APIs. -The arguments can be a: -.RS -.IP \[bu] 2 -\f[I]dir\f[R]: Directory -.IP \[bu] 2 -\f[I]jar\f[R]: JAR file -.IP \[bu] 2 -\f[I]class\f[R]: Class name or class file -.PP -The class name should use a dot (\f[V].\f[R]) as a separator. -For example: -.PP -\f[V]java.lang.Thread\f[R] -.PP -For nested classes, the dollar sign \f[V]$\f[R] separator character -should be used. -For example: -.PP -\f[V]java.lang.Thread$State\f[R] -.PP -A class file can also be named. -For example: -.PP -\f[V]build/classes/java/lang/Thread$State.class\f[R] -.RE -.SH DESCRIPTION -.PP -The \f[V]jdeprscan\f[R] tool is a static analysis tool provided by the -JDK that scans a JAR file or some other aggregation of class files for -uses of deprecated API elements. -The deprecated APIs identified by the \f[V]jdeprscan\f[R] tool are only -those that are defined by Java SE. -Deprecated APIs defined by third-party libraries aren\[aq]t reported. -.PP -To scan a JAR file or a set of class files, you must first ensure that -all of the classes that the scanned classes depend upon are present in -the class path. -Set the class path using the \f[V]--class-path\f[R] option described in -\f[B]Options for the jdeprscan Command\f[R]. -Typically, you would use the same class path as the one that you use -when invoking your application. -.PP -If the \f[V]jdeprscan\f[R] can\[aq]t find all the dependent classes, it -will generate an error message for each class that\[aq]s missing. -These error messages are typically of the form: -.RS -.PP -\f[V]error: cannot find class ...\f[R] -.RE -.PP -If these errors occur, then you must adjust the class path so that it -includes all dependent classes. -.SH OPTIONS FOR THE JDEPRSCAN COMMAND -.PP -The following options are available: -.TP -\f[V]--class-path\f[R] \f[I]path\f[R] -Provides a search path for resolution of dependent classes. -.RS -.PP -\f[I]path\f[R] can be a search path that consists of one or more -directories separated by the system-specific path separator. -For example: -.IP \[bu] 2 -\f[B]Linux and macOS:\f[R] -.RS 2 -.RS -.PP -\f[V]--class-path /some/directory:/another/different/dir\f[R] -.RE -.RE -.PP -\f[B]Note:\f[R] -.PP -On Windows, use a semicolon (\f[V];\f[R]) as the separator instead of a -colon (\f[V]:\f[R]). -.IP \[bu] 2 -\f[B]Windows:\f[R] -.RS 2 -.RS -.PP -\f[V]--class-path \[rs]some\[rs]directory;\[rs]another\[rs]different\[rs]dir\f[R] -.RE -.RE -.RE -.TP -\f[V]--for-removal\f[R] -Limits scanning or listing to APIs that are deprecated for removal. -Can\[aq]t be used with a release value of 6, 7, or 8. -.TP -\f[V]--full-version\f[R] -Prints out the full version string of the tool. -.TP -\f[V]--help\f[R] or \f[V]-h\f[R] -Prints out a full help message. -.TP -\f[V]--list\f[R] or \f[V]-l\f[R] -Prints the set of deprecated APIs. -No scanning is done, so no directory, jar, or class arguments should be -provided. -.TP -\f[V]--release\f[R] \f[V]6\f[R]|\f[V]7\f[R]|\f[V]8\f[R]|\f[V]9\f[R] -Specifies the Java SE release that provides the set of deprecated APIs -for scanning. -.TP -\f[V]--verbose\f[R] or \f[V]-v\f[R] -Enables additional message output during processing. -.TP -\f[V]--version\f[R] -Prints out the abbreviated version string of the tool. -.SH EXAMPLE OF JDEPRSCAN OUTPUT -.PP -The JAR file for this library will be named something similar to -\f[V]commons-math3-3.6.1.jar\f[R]. -To scan this JAR file for the use of deprecated APIs, run the following -command: -.RS -.PP -\f[V]jdeprscan commons-math3-3.6.1.jar\f[R] -.RE -.PP -This command produces several lines of output. -For example, one line of output might be: -.IP -.nf -\f[CB] -class org/apache/commons/math3/util/MathUtils uses deprecated method java/lang/Double::<init>(D)V -\f[R] -.fi -.PP -\f[B]Note:\f[R] -.PP -The class name is specified using the slash-separated binary name as -described in JVMS 4.2.1. -This is the form used internally in class files. -.PP -The deprecated API it uses is a method on the \f[V]java.lang.Double\f[R] -class. -.PP -The name of the deprecated method is \f[V]<init>\f[R], which is a -special name that means that the method is actually a constructor. -Another special name is \f[V]<clinit>\f[R], which indicates a class -static initializer. -.PP -Other methods are listed just by their method name. -Following the method name is the argument list and return type: -.RS -.PP -\f[V](D)V\f[R] -.RE -.PP -This indicates that it takes just one double value (a primitive) and -returns void. -The argument and return types can become cryptic. -For example, another line of output might be: -.IP -.nf -\f[CB] -class org/apache/commons/math3/util/Precision uses deprecated method java/math/BigDecimal::setScale(II)Ljava/math/BigDecimal; -\f[R] -.fi -.PP -In this line of output, the deprecated method is on class -\f[V]java.math.BigDecimal\f[R], and the method is \f[V]setScale()\f[R]. -In this case, the \f[V](II)\f[R] means that it takes two \f[V]int\f[R] -arguments. -The \f[V]Ljava/math/BigDecimal;\f[R] after the parentheses means that it -returns a reference to \f[V]java.math.BigDecimal\f[R]. -.SH JDEPRSCAN ANALYSIS CAN BE VERSION-SPECIFIC -.PP -You can use \f[V]jdeprscan\f[R] relative to the previous three JDK -releases. -For example, if you are running JDK 9, then you can check against JDK 8, -7, and 6. -.PP -As an example, look at this code snippet: -.IP -.nf -\f[CB] -public class Deprecations { - SecurityManager sm = new RMISecurityManager(); // deprecated in 8 - Boolean b2 = new Boolean(true); // deprecated in 9 -} -\f[R] -.fi -.PP -The complete class compiles without warnings in JDK 7. -.PP -If you run \f[V]jdeprscan\f[R] on a system with JDK 9, then you see: -.IP -.nf -\f[CB] -$ jdeprscan --class-path classes --release 7 example.Deprecations -(no output) -\f[R] -.fi -.PP -Run \f[V]jdeprscan\f[R] with a release value of 8: -.IP -.nf -\f[CB] -$ jdeprscan --class-path classes --release 8 example.Deprecations -class example/Deprecations uses type java/rmi/RMISecurityManager deprecated -class example/Deprecations uses method in type java/rmi/RMISecurityManager deprecated -\f[R] -.fi -.PP -Run \f[V]jdeprscan\f[R] on JDK 9: -.IP -.nf -\f[CB] -$ jdeprscan --class-path classes example.Deprecations -class example/Deprecations uses type java/rmi/RMISecurityManager deprecated -class example/Deprecations uses method in type java/rmi/RMISecurityManager deprecated -class example/Deprecations uses method java/lang/Boolean <init> (Z)V deprecated -\f[R] -.fi diff --git a/src/jdk.jdeps/share/man/jdeprscan.md b/src/jdk.jdeps/share/man/jdeprscan.md new file mode 100644 index 00000000000..8f76b29aee3 --- /dev/null +++ b/src/jdk.jdeps/share/man/jdeprscan.md @@ -0,0 +1,217 @@ +--- +# Copyright (c) 2017, 2023, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# This code is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 only, as +# published by the Free Software Foundation. +# +# This code is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# version 2 for more details (a copy is included in the LICENSE file that +# accompanied this code). +# +# You should have received a copy of the GNU General Public License version +# 2 along with this work; if not, write to the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +# or visit www.oracle.com if you need additional information or have any +# questions. +# + +title: 'JDEPRSCAN(1) JDK @@VERSION_SHORT@@ | JDK Commands' +date: @@COPYRIGHT_YEAR@@ +lang: en +--- + +## Name + +jdeprscan - static analysis tool that scans a jar file (or some other +aggregation of class files) for uses of deprecated API elements + +## Synopsis + +`jdeprscan` \[*options*\] {*dir*\|*jar*\|*class*} + +*options* +: See [Options for the jdeprscan Command] + +*dir*\|*jar*\|*class* +: `jdeprscan` command scans each argument for usages of deprecated APIs. The + arguments can be a: + + - *dir*: Directory + + - *jar*: JAR file + + - *class*: Class name or class file + + The class name should use a dot (`.`) as a separator. For example: + + `java.lang.Thread` + + For nested classes, the dollar sign `$` separator character should be used. + For example: + + `java.lang.Thread$State` + + A class file can also be named. For example: + + `build/classes/java/lang/Thread$State.class` + +## Description + +The `jdeprscan` tool is a static analysis tool provided by the JDK that scans a +JAR file or some other aggregation of class files for uses of deprecated API +elements. The deprecated APIs identified by the `jdeprscan` tool are only those +that are defined by Java SE. Deprecated APIs defined by third-party libraries +aren't reported. + +To scan a JAR file or a set of class files, you must first ensure that all of +the classes that the scanned classes depend upon are present in the class +path. Set the class path using the `--class-path` option described in [Options +for the jdeprscan Command]. Typically, you would use the same class path as +the one that you use when invoking your application. + +If the `jdeprscan` can't find all the dependent classes, it will generate an +error message for each class that's missing. These error messages are typically +of the form: + +> `error: cannot find class ...` + +If these errors occur, then you must adjust the class path so that it includes +all dependent classes. + +## Options for the jdeprscan Command + +The following options are available: + +`--class-path` *path* +: Provides a search path for resolution of dependent classes. + + *path* can be a search path that consists of one or more directories + separated by the system-specific path separator. For example: + + - **Linux and macOS:** + + > `--class-path /some/directory:/another/different/dir` + + **Note:** + + On Windows, use a semicolon (`;`) as the separator instead of a colon + (`:`). + + - **Windows:** + + > `--class-path \some\directory;\another\different\dir` + +`--for-removal` +: Limits scanning or listing to APIs that are deprecated for removal. Can't + be used with a release value of 6, 7, or 8. + +`--full-version` +: Prints out the full version string of the tool. + +`--help` or `-h` +: Prints out a full help message. + +`--list` or `-l` +: Prints the set of deprecated APIs. No scanning is done, so no directory, + jar, or class arguments should be provided. + +`--release` `6`\|`7`\|`8`\|`9` +: Specifies the Java SE release that provides the set of deprecated APIs for + scanning. + +`--verbose` or `-v` +: Enables additional message output during processing. + +`--version` +: Prints out the abbreviated version string of the tool. + +## Example of jdeprscan Output + +The JAR file for this library will be named something similar to +`commons-math3-3.6.1.jar`. To scan this JAR file for the use of deprecated +APIs, run the following command: + +> `jdeprscan commons-math3-3.6.1.jar` + +This command produces several lines of output. For example, one line of output +might be: + +``` +class org/apache/commons/math3/util/MathUtils uses deprecated method java/lang/Double::<init>(D)V +``` + +**Note:** + +The class name is specified using the slash-separated binary name as described +in JVMS 4.2.1. This is the form used internally in class files. + +The deprecated API it uses is a method on the `java.lang.Double` class. + +The name of the deprecated method is `<init>`, which is a special name that +means that the method is actually a constructor. Another special name is +`<clinit>`, which indicates a class static initializer. + +Other methods are listed just by their method name. Following the method name +is the argument list and return type: + +> `(D)V` + +This indicates that it takes just one double value (a primitive) and returns +void. The argument and return types can become cryptic. For example, another +line of output might be: + +``` +class org/apache/commons/math3/util/Precision uses deprecated method java/math/BigDecimal::setScale(II)Ljava/math/BigDecimal; +``` + +In this line of output, the deprecated method is on class +`java.math.BigDecimal`, and the method is `setScale()`. In this case, the +`(II)` means that it takes two `int` arguments. The `Ljava/math/BigDecimal;` +after the parentheses means that it returns a reference to +`java.math.BigDecimal`. + +## jdeprscan Analysis Can Be Version-Specific + +You can use `jdeprscan` relative to the previous three JDK releases. For +example, if you are running JDK 9, then you can check against JDK 8, 7, and 6. + +As an example, look at this code snippet: + +``` +public class Deprecations { + SecurityManager sm = new RMISecurityManager(); // deprecated in 8 + Boolean b2 = new Boolean(true); // deprecated in 9 +} +``` + +The complete class compiles without warnings in JDK 7. + +If you run `jdeprscan` on a system with JDK 9, then you see: + +``` +$ jdeprscan --class-path classes --release 7 example.Deprecations +(no output) +``` + +Run `jdeprscan` with a release value of 8: + +``` +$ jdeprscan --class-path classes --release 8 example.Deprecations +class example/Deprecations uses type java/rmi/RMISecurityManager deprecated +class example/Deprecations uses method in type java/rmi/RMISecurityManager deprecated +``` + +Run `jdeprscan` on JDK 9: + +``` +$ jdeprscan --class-path classes example.Deprecations +class example/Deprecations uses type java/rmi/RMISecurityManager deprecated +class example/Deprecations uses method in type java/rmi/RMISecurityManager deprecated +class example/Deprecations uses method java/lang/Boolean <init> (Z)V deprecated +``` diff --git a/src/jdk.jdeps/share/man/jdeps.1 b/src/jdk.jdeps/share/man/jdeps.1 deleted file mode 100644 index d3dde37e3b9..00000000000 --- a/src/jdk.jdeps/share/man/jdeps.1 +++ /dev/null @@ -1,338 +0,0 @@ -.\" Copyright (c) 2013, 2023, Oracle and/or its affiliates. All rights reserved. -.\" DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -.\" -.\" This code is free software; you can redistribute it and/or modify it -.\" under the terms of the GNU General Public License version 2 only, as -.\" published by the Free Software Foundation. -.\" -.\" This code is distributed in the hope that it will be useful, but WITHOUT -.\" ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -.\" FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -.\" version 2 for more details (a copy is included in the LICENSE file that -.\" accompanied this code). -.\" -.\" You should have received a copy of the GNU General Public License version -.\" 2 along with this work; if not, write to the Free Software Foundation, -.\" Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -.\" -.\" Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -.\" or visit www.oracle.com if you need additional information or have any -.\" questions. -.\" -.\" Automatically generated by Pandoc 2.19.2 -.\" -.\" Define V font for inline verbatim, using C font in formats -.\" that render this, and otherwise B font. -.ie "\f[CB]x\f[R]"x" \{\ -. ftr V B -. ftr VI BI -. ftr VB B -. ftr VBI BI -.\} -.el \{\ -. ftr V CR -. ftr VI CI -. ftr VB CB -. ftr VBI CBI -.\} -.TH "JDEPS" "1" "2025" "JDK 24-ea" "JDK Commands" -.hy -.SH NAME -.PP -jdeps - launch the Java class dependency analyzer -.SH SYNOPSIS -.PP -\f[V]jdeps\f[R] [\f[I]options\f[R]] \f[I]path\f[R] ... -.TP -\f[I]options\f[R] -Command-line options. -For detailed descriptions of the options that can be used, see -.RS -.IP \[bu] 2 -\f[B]Possible Options\f[R] -.IP \[bu] 2 -\f[B]Module Dependence Analysis Options\f[R] -.IP \[bu] 2 -\f[B]Options to Filter Dependences\f[R] -.IP \[bu] 2 -\f[B]Options to Filter Classes to be Analyzed\f[R] -.RE -.TP -\f[I]path\f[R] -A pathname to the \f[V].class\f[R] file, directory, or JAR file to -analyze. -.SH DESCRIPTION -.PP -The \f[V]jdeps\f[R] command shows the package-level or class-level -dependencies of Java class files. -The input class can be a path name to a \f[V].class\f[R] file, a -directory, a JAR file, or it can be a fully qualified class name to -analyze all class files. -The options determine the output. -By default, the \f[V]jdeps\f[R] command writes the dependencies to the -system output. -The command can generate the dependencies in DOT language (see the -\f[V]-dotoutput\f[R] option). -.SH POSSIBLE OPTIONS -.TP -\f[V]-?\f[R] or \f[V]-h\f[R] or \f[V]--help\f[R] -Prints the help message. -.TP -\f[V]-dotoutput\f[R] \f[I]dir\f[R] or \f[V]--dot-output\f[R] \f[I]dir\f[R] -Specifies the destination directory for DOT file output. -If this option is specified, then the \f[V]jdeps\f[R]command generates -one \f[V].dot\f[R] file for each analyzed archive named -\f[V]archive-file-name.dot\f[R] that lists the dependencies, and also a -summary file named \f[V]summary.dot\f[R] that lists the dependencies -among the archive files. -.TP -\f[V]-s\f[R] or \f[V]-summary\f[R] -Prints a dependency summary only. -.TP -\f[V]-v\f[R] or \f[V]-verbose\f[R] -Prints all class-level dependencies. -This is equivalent to -.RS -.RS -.PP -\f[V]-verbose:class -filter:none\f[R] -.RE -.RE -.TP -\f[V]-verbose:package\f[R] -Prints package-level dependencies excluding, by default, dependences -within the same package. -.TP -\f[V]-verbose:class\f[R] -Prints class-level dependencies excluding, by default, dependencies -within the same archive. -.TP -\f[V]-apionly\f[R] or \f[V]--api-only\f[R] -Restricts the analysis to APIs, for example, dependences from the -signature of \f[V]public\f[R] and \f[V]protected\f[R] members of public -classes including field type, method parameter types, returned type, and -checked exception types. -.TP -\f[V]-jdkinternals\f[R] or \f[V]--jdk-internals\f[R] -Finds class-level dependences in the JDK internal APIs. -By default, this option analyzes all classes specified in the -\f[V]--classpath\f[R] option and input files unless you specified the -\f[V]-include\f[R] option. -You can\[aq]t use this option with the \f[V]-p\f[R], \f[V]-e\f[R], and -\f[V]-s\f[R] options. -.RS -.PP -\f[B]Warning\f[R]: The JDK internal APIs are inaccessible. -.RE -.TP -\f[V]-cp\f[R] \f[I]path\f[R], \f[V]-classpath\f[R] \f[I]path\f[R], or \f[V]--class-path\f[R] \f[I]path\f[R] -Specifies where to find class files. -.TP -\f[V]--module-path\f[R] \f[I]module-path\f[R] -Specifies the module path. -.TP -\f[V]--upgrade-module-path\f[R] \f[I]module-path\f[R] -Specifies the upgrade module path. -.TP -\f[V]--system\f[R] \f[I]java-home\f[R] -Specifies an alternate system module path. -.TP -\f[V]--add-modules\f[R] \f[I]module-name\f[R][\f[V],\f[R] \f[I]module-name\f[R]...] -Adds modules to the root set for analysis. -.TP -\f[V]--multi-release\f[R] \f[I]version\f[R] -Specifies the version when processing multi-release JAR files. -\f[I]version\f[R] should be an integer >=9 or base. -.TP -\f[V]-q\f[R] or \f[V]-quiet\f[R] -Doesn\[aq]t show missing dependencies from -\f[V]-generate-module-info\f[R] output. -.TP -\f[V]-version\f[R] or \f[V]--version\f[R] -Prints version information. -.SH MODULE DEPENDENCE ANALYSIS OPTIONS -.TP -\f[V]-m\f[R] \f[I]module-name\f[R] or \f[V]--module\f[R] \f[I]module-name\f[R] -Specifies the root module for analysis. -.TP -\f[V]--generate-module-info\f[R] \f[I]dir\f[R] -Generates \f[V]module-info.java\f[R] under the specified directory. -The specified JAR files will be analyzed. -This option cannot be used with \f[V]--dot-output\f[R] or -\f[V]--class-path\f[R] options. -Use the \f[V]--generate-open-module\f[R] option for open modules. -.TP -\f[V]--generate-open-module\f[R] \f[I]dir\f[R] -Generates \f[V]module-info.java\f[R] for the specified JAR files under -the specified directory as open modules. -This option cannot be used with the \f[V]--dot-output\f[R] or -\f[V]--class-path\f[R] options. -.TP -\f[V]--check\f[R] \f[I]module-name\f[R] [\f[V],\f[R] \f[I]module-name\f[R]...] -Analyzes the dependence of the specified modules. -It prints the module descriptor, the resulting module dependences after -analysis and the graph after transition reduction. -It also identifies any unused qualified exports. -.TP -\f[V]--list-deps\f[R] -Lists the module dependences and also the package names of JDK internal -APIs (if referenced). -This option transitively analyzes libraries on class path and module -path if referenced. -Use \f[V]--no-recursive\f[R] option for non-transitive dependency -analysis. -.TP -\f[V]--list-reduced-deps\f[R] -Same as \f[V]--list-deps\f[R] without listing the implied reads edges -from the module graph. -If module M1 reads M2, and M2 requires transitive on M3, then M1 reading -M3 is implied and is not shown in the graph. -.TP -\f[V]--print-module-deps\f[R] -Same as \f[V]--list-reduced-deps\f[R] with printing a comma-separated -list of module dependences. -The output can be used by \f[V]jlink --add-modules\f[R] to create a -custom image that contains those modules and their transitive -dependences. -.TP -\f[V]--ignore-missing-deps\f[R] -Ignore missing dependences. -.SH OPTIONS TO FILTER DEPENDENCES -.TP -\f[V]-p\f[R] \f[I]pkg_name\f[R], \f[V]-package\f[R] \f[I]pkg_name\f[R], or \f[V]--package\f[R] \f[I]pkg_name\f[R] -Finds dependences matching the specified package name. -You can specify this option multiple times for different packages. -The \f[V]-p\f[R] and \f[V]-e\f[R] options are mutually exclusive. -.TP -\f[V]-e\f[R] \f[I]regex\f[R], \f[V]-regex\f[R] \f[I]regex\f[R], or \f[V]--regex\f[R] \f[I]regex\f[R] -Finds dependences matching the specified pattern. -The \f[V]-p\f[R] and \f[V]-e\f[R] options are mutually exclusive. -.TP -\f[V]--require\f[R] \f[I]module-name\f[R] -Finds dependences matching the given module name (may be given multiple -times). -The \f[V]--package\f[R], \f[V]--regex\f[R], and \f[V]--require\f[R] -options are mutually exclusive. -.TP -\f[V]-f\f[R] \f[I]regex\f[R] or \f[V]-filter\f[R] \f[I]regex\f[R] -Filters dependences matching the given pattern. -If give multiple times, the last one will be selected. -.TP -\f[V]-filter:package\f[R] -Filters dependences within the same package. -This is the default. -.TP -\f[V]-filter:archive\f[R] -Filters dependences within the same archive. -.TP -\f[V]-filter:module\f[R] -Filters dependences within the same module. -.TP -\f[V]-filter:none\f[R] -No \f[V]-filter:package\f[R] and \f[V]-filter:archive\f[R] filtering. -Filtering specified via the \f[V]-filter\f[R] option still applies. -.TP -\f[V]--missing-deps\f[R] -Finds missing dependences. -This option cannot be used with \f[V]-p\f[R], \f[V]-e\f[R] and -\f[V]-s\f[R] options. -.SH OPTIONS TO FILTER CLASSES TO BE ANALYZED -.TP -\f[V]-include\f[R] \f[I]regex\f[R] -Restricts analysis to the classes matching pattern. -This option filters the list of classes to be analyzed. -It can be used together with \f[V]-p\f[R] and \f[V]-e\f[R], which apply -the pattern to the dependencies. -.TP -\f[V]-R\f[R] or \f[V]--recursive\f[R] -Recursively traverses all run-time dependences. -The \f[V]-R\f[R] option implies \f[V]-filter:none\f[R]. -If \f[V]-p\f[R], \f[V]-e\f[R], or \f[V]-f\f[R] options are specified, -only the matching dependences are analyzed. -.TP -\f[V]--no-recursive\f[R] -Do not recursively traverse dependences. -.TP -\f[V]-I\f[R] or \f[V]--inverse\f[R] -Analyzes the dependences per other given options and then finds all -artifacts that directly and indirectly depend on the matching nodes. -This is equivalent to the inverse of the compile-time view analysis and -the print dependency summary. -This option must be used with the \f[V]--require\f[R], -\f[V]--package\f[R], or \f[V]--regex\f[R] options. -.TP -\f[V]--compile-time\f[R] -Analyzes the compile-time view of transitive dependencies, such as the -compile-time view of the \f[V]-R\f[R] option. -Analyzes the dependences per other specified options. -If a dependency is found from a directory, a JAR file or a module, all -classes in that containing archive are analyzed. -.SH EXAMPLE OF ANALYZING DEPENDENCIES -.PP -The following example demonstrates analyzing the dependencies of the -\f[V]Notepad.jar\f[R] file. -.PP -\f[B]Linux and macOS:\f[R] -.IP -.nf -\f[CB] -$ jdeps demo/jfc/Notepad/Notepad.jar -Notepad.jar -> java.base -Notepad.jar -> java.desktop -Notepad.jar -> java.logging - <unnamed> (Notepad.jar) - -> java.awt - -> java.awt.event - -> java.beans - -> java.io - -> java.lang - -> java.net - -> java.util - -> java.util.logging - -> javax.swing - -> javax.swing.border - -> javax.swing.event - -> javax.swing.text - -> javax.swing.tree - -> javax.swing.undo -\f[R] -.fi -.PP -\f[B]Windows:\f[R] -.IP -.nf -\f[CB] -C:\[rs]Java\[rs]jdk1.9.0>jdeps demo\[rs]jfc\[rs]Notepad\[rs]Notepad.jar -Notepad.jar -> java.base -Notepad.jar -> java.desktop -Notepad.jar -> java.logging - <unnamed> (Notepad.jar) - -> java.awt - -> java.awt.event - -> java.beans - -> java.io - -> java.lang - -> java.net - -> java.util - -> java.util.logging - -> javax.swing - -> javax.swing.border - -> javax.swing.event - -> javax.swing.text - -> javax.swing.tree - -> javax.swing.undo -\f[R] -.fi -.SH EXAMPLE USING THE --INVERSE OPTION -.IP -.nf -\f[CB] - $ jdeps --inverse --require java.xml.bind -Inverse transitive dependences on [java.xml.bind] -java.xml.bind <- java.se.ee -java.xml.bind <- jdk.xml.ws -java.xml.bind <- java.xml.ws <- java.se.ee -java.xml.bind <- java.xml.ws <- jdk.xml.ws -java.xml.bind <- jdk.xml.bind <- jdk.xml.ws -\f[R] -.fi diff --git a/src/jdk.jdeps/share/man/jdeps.md b/src/jdk.jdeps/share/man/jdeps.md new file mode 100644 index 00000000000..cb936bf3e01 --- /dev/null +++ b/src/jdk.jdeps/share/man/jdeps.md @@ -0,0 +1,297 @@ +--- +# Copyright (c) 2013, 2023, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# This code is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 only, as +# published by the Free Software Foundation. +# +# This code is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# version 2 for more details (a copy is included in the LICENSE file that +# accompanied this code). +# +# You should have received a copy of the GNU General Public License version +# 2 along with this work; if not, write to the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +# or visit www.oracle.com if you need additional information or have any +# questions. +# + +title: 'JDEPS(1) JDK @@VERSION_SHORT@@ | JDK Commands' +date: @@COPYRIGHT_YEAR@@ +lang: en +--- + +## Name + +jdeps - launch the Java class dependency analyzer + +## Synopsis + +`jdeps` \[*options*\] *path* ... + +*options* +: Command-line options. For detailed descriptions of the options that can be + used, see + + - [Possible Options] + + - [Module Dependence Analysis Options] + + - [Options to Filter Dependences] + + - [Options to Filter Classes to be Analyzed] + +*path* +: A pathname to the `.class` file, directory, or JAR file to analyze. + +## Description + +The `jdeps` command shows the package-level or class-level dependencies of Java +class files. The input class can be a path name to a `.class` file, a +directory, a JAR file, or it can be a fully qualified class name to analyze all +class files. The options determine the output. By default, the `jdeps` command +writes the dependencies to the system output. The command can generate the +dependencies in DOT language (see the `-dotoutput` option). + +## Possible Options + +`-?` or `-h` or `--help` +: Prints the help message. + +`-dotoutput` *dir* or `--dot-output` *dir* +: Specifies the destination directory for DOT file output. If this option is + specified, then the `jdeps`command generates one `.dot` file for each + analyzed archive named `archive-file-name.dot` that lists the dependencies, + and also a summary file named `summary.dot` that lists the dependencies + among the archive files. + +`-s` or `-summary` +: Prints a dependency summary only. + +`-v` or `-verbose` +: Prints all class-level dependencies. This is equivalent to + + > `-verbose:class -filter:none` + +`-verbose:package` +: Prints package-level dependencies excluding, by default, dependences within + the same package. + +`-verbose:class` +: Prints class-level dependencies excluding, by default, dependencies within + the same archive. + +`-apionly` or `--api-only` +: Restricts the analysis to APIs, for example, dependences from the signature + of `public` and `protected` members of public classes including field type, + method parameter types, returned type, and checked exception types. + +`-jdkinternals` or `--jdk-internals` +: Finds class-level dependences in the JDK internal APIs. By default, this + option analyzes all classes specified in the `--classpath` option and input + files unless you specified the `-include` option. You can't use this option + with the `-p`, `-e`, and `-s` options. + + **Warning**: The JDK internal APIs are inaccessible. + +`-cp` *path*, `-classpath` *path*, or `--class-path` *path* +: Specifies where to find class files. + +`--module-path` *module-path* +: Specifies the module path. + +`--upgrade-module-path` *module-path* +: Specifies the upgrade module path. + +`--system` *java-home* +: Specifies an alternate system module path. + +`--add-modules` *module-name*\[`,` *module-name*...\] +: Adds modules to the root set for analysis. + +`--multi-release` *version* +: Specifies the version when processing multi-release JAR files. *version* + should be an integer \>=9 or base. + +`-q` or `-quiet` +: Doesn't show missing dependencies from `-generate-module-info` output. + +`-version` or `--version` +: Prints version information. + +## Module Dependence Analysis Options + +`-m` *module-name* or `--module` *module-name* +: Specifies the root module for analysis. + +`--generate-module-info` *dir* +: Generates `module-info.java` under the specified directory. The specified + JAR files will be analyzed. This option cannot be used with `--dot-output` + or `--class-path` options. Use the `--generate-open-module` option for open + modules. + +`--generate-open-module` *dir* +: Generates `module-info.java` for the specified JAR files under the + specified directory as open modules. This option cannot be used with the + `--dot-output` or `--class-path` options. + +`--check` *module-name* \[`,` *module-name*...\] +: Analyzes the dependence of the specified modules. It prints the module + descriptor, the resulting module dependences after analysis and the graph + after transition reduction. It also identifies any unused qualified + exports. + +`--list-deps` +: Lists the module dependences and also the package names of JDK internal + APIs (if referenced). This option transitively analyzes libraries on + class path and module path if referenced. Use `--no-recursive` option for + non-transitive dependency analysis. + +`--list-reduced-deps` +: Same as `--list-deps` without listing the implied reads edges from the + module graph. If module M1 reads M2, and M2 requires transitive on M3, then + M1 reading M3 is implied and is not shown in the graph. + +`--print-module-deps` +: Same as `--list-reduced-deps` with printing a comma-separated list of + module dependences. The output can be used by `jlink --add-modules` to + create a custom image that contains those modules and their transitive + dependences. + +`--ignore-missing-deps` +: Ignore missing dependences. + +## Options to Filter Dependences + +`-p` *pkg\_name*, `-package` *pkg\_name*, or `--package` *pkg\_name* +: Finds dependences matching the specified package name. You can specify this + option multiple times for different packages. The `-p` and `-e` options are + mutually exclusive. + +`-e` *regex*, `-regex` *regex*, or `--regex` *regex* +: Finds dependences matching the specified pattern. The `-p` and `-e` options + are mutually exclusive. + +`--require` *module-name* +: Finds dependences matching the given module name (may be given multiple + times). The `--package`, `--regex`, and `--require` options are mutually + exclusive. + +`-f` *regex* or `-filter` *regex* +: Filters dependences matching the given pattern. If give multiple times, the + last one will be selected. + +`-filter:package` +: Filters dependences within the same package. This is the default. + +`-filter:archive` +: Filters dependences within the same archive. + +`-filter:module` +: Filters dependences within the same module. + +`-filter:none` +: No `-filter:package` and `-filter:archive` filtering. Filtering specified + via the `-filter` option still applies. + +`--missing-deps` +: Finds missing dependences. This option cannot be used with `-p`, `-e` and + `-s` options. + +## Options to Filter Classes to be Analyzed + +`-include` *regex* +: Restricts analysis to the classes matching pattern. This option filters the + list of classes to be analyzed. It can be used together with `-p` and `-e`, + which apply the pattern to the dependencies. + +`-R` or `--recursive` +: Recursively traverses all run-time dependences. The `-R` option implies + `-filter:none`. If `-p`, `-e`, or `-f` options are specified, only the + matching dependences are analyzed. + +`--no-recursive` +: Do not recursively traverse dependences. + +`-I` or `--inverse` +: Analyzes the dependences per other given options and then finds all + artifacts that directly and indirectly depend on the matching nodes. This + is equivalent to the inverse of the compile-time view analysis and the + print dependency summary. This option must be used with the `--require`, + `--package`, or `--regex` options. + +`--compile-time` +: Analyzes the compile-time view of transitive dependencies, such as the + compile-time view of the `-R` option. Analyzes the dependences per other + specified options. If a dependency is found from a directory, a JAR file or + a module, all classes in that containing archive are analyzed. + +## Example of Analyzing Dependencies + +The following example demonstrates analyzing the dependencies of the +`Notepad.jar` file. + +**Linux and macOS:** + +``` +$ jdeps demo/jfc/Notepad/Notepad.jar +Notepad.jar -> java.base +Notepad.jar -> java.desktop +Notepad.jar -> java.logging + <unnamed> (Notepad.jar) + -> java.awt + -> java.awt.event + -> java.beans + -> java.io + -> java.lang + -> java.net + -> java.util + -> java.util.logging + -> javax.swing + -> javax.swing.border + -> javax.swing.event + -> javax.swing.text + -> javax.swing.tree + -> javax.swing.undo +``` + +**Windows:** + +``` +C:\Java\jdk1.9.0>jdeps demo\jfc\Notepad\Notepad.jar +Notepad.jar -> java.base +Notepad.jar -> java.desktop +Notepad.jar -> java.logging + <unnamed> (Notepad.jar) + -> java.awt + -> java.awt.event + -> java.beans + -> java.io + -> java.lang + -> java.net + -> java.util + -> java.util.logging + -> javax.swing + -> javax.swing.border + -> javax.swing.event + -> javax.swing.text + -> javax.swing.tree + -> javax.swing.undo +``` + +## Example Using the --inverse Option + +``` + $ jdeps --inverse --require java.xml.bind +Inverse transitive dependences on [java.xml.bind] +java.xml.bind <- java.se.ee +java.xml.bind <- jdk.xml.ws +java.xml.bind <- java.xml.ws <- java.se.ee +java.xml.bind <- java.xml.ws <- jdk.xml.ws +java.xml.bind <- jdk.xml.bind <- jdk.xml.ws +``` diff --git a/src/jdk.jdeps/share/man/jnativescan.1 b/src/jdk.jdeps/share/man/jnativescan.1 deleted file mode 100644 index ff7f18277f2..00000000000 --- a/src/jdk.jdeps/share/man/jnativescan.1 +++ /dev/null @@ -1,220 +0,0 @@ -.\" Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. -.\" DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -.\" -.\" This code is free software; you can redistribute it and/or modify it -.\" under the terms of the GNU General Public License version 2 only, as -.\" published by the Free Software Foundation. -.\" -.\" This code is distributed in the hope that it will be useful, but WITHOUT -.\" ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -.\" FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -.\" version 2 for more details (a copy is included in the LICENSE file that -.\" accompanied this code). -.\" -.\" You should have received a copy of the GNU General Public License version -.\" 2 along with this work; if not, write to the Free Software Foundation, -.\" Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -.\" -.\" Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -.\" or visit www.oracle.com if you need additional information or have any -.\" questions. -.\" -.\" Automatically generated by Pandoc 2.19.2 -.\" -.\" Define V font for inline verbatim, using C font in formats -.\" that render this, and otherwise B font. -.ie "\f[CB]x\f[R]"x" \{\ -. ftr V B -. ftr VI BI -. ftr VB B -. ftr VBI BI -.\} -.el \{\ -. ftr V CR -. ftr VI CI -. ftr VB CB -. ftr VBI CBI -.\} -.TH "JNATIVESCAN" "1" "2025" "JDK 24-ea" "JDK Commands" -.hy -.SH NAME -.PP -jnativescan - static analysis tool that scans one or more jar files for -uses of native functionalities, such as restricted method calls or -\f[V]native\f[R] method declarations. -.SH SYNOPSIS -.PP -\f[V]jnativescan\f[R] [\f[I]options\f[R]] -.TP -\f[I]options\f[R] -See \f[B]Options for the jnativescan Command\f[R] -.SH DESCRIPTION -.PP -The \f[V]jnative\f[R] tool is a static analysis tool provided by the JDK -that scans a JAR file for uses of native functionalities, such as -restricted method calls or \f[V]native\f[R] method declarations. -.PP -\f[V]jnativescan\f[R] accepts a runtime class path and module path -configuration, as well as a set of root modules, and a target release. -It scans the jars on the class and module paths, and reports uses of -native functionalities either in a tree like structure, which also -identifies that calling classes and methods, or as a list of module -names when the \f[V]--print-native-access\f[R] flag is specified. -.SH OPTIONS FOR THE JNATIVESCAN COMMAND -.PP -The following options are available: -.TP -\f[V]--class-path\f[R] \f[I]path\f[R] -Used to specify a list of paths pointing to jar files to be scanned. -.PP -All jar files specified through this list will be scanned. -If a jar file contains a \f[V]Class-Path\f[R] attribute in its manifest, -jar files listed there will be scanned as well. -Jar files listed in the \f[V]Class-Path\f[R] manifest attribute that can -not be found are ignored. -All the jar files found are treated as if they belonged to the unnamed -module. -.TP -\f[V]--module-path\f[R] \f[I]path\f[R] -Used to specify a list of paths pointing to jar files or directories -containing jar files, that the tool can use to find modules that need to -be scanned. -The list of jar files that will be scanned depends on the -\f[V]--add-modules\f[R] option. -.RS -.PP -For both the \f[V]--class-path\f[R] and \f[V]--module-path\f[R] options, -\f[I]path\f[R] should be a search path that consists of one or more jar -files, separated by the system-specific path separator. -For example: -.IP \[bu] 2 -\f[B]Linux and macOS:\f[R] -.RS 2 -.RS -.PP -\f[V]--class-path /some/foo.jar:/another/different/bar.jar\f[R] -.RE -.RE -.PP -\f[B]Note:\f[R] -.PP -On Windows, use a semicolon (\f[V];\f[R]) as the separator instead of a -colon (\f[V]:\f[R]). -.IP \[bu] 2 -\f[B]Windows:\f[R] -.RS 2 -.RS -.PP -\f[V]--class-path C:\[rs]some\[rs]foo.jar;C:\[rs]another\[rs]different\[rs]bar.jar\f[R] -.RE -.RE -.RE -.TP -\f[V]--add-modules\f[R] \f[I]module[,module...]\f[R] -Used to specify a comma-separated list of module names that indicate the -root modules to scan. -All the root modules will be scanned, as well as any modules that they -depend on. -This includes dependencies on service implementations specified through -the \f[V]uses\f[R] directive in a module\[aq]s \f[V]module-info\f[R] -file. -All modules found on the module path that provide an implementation of -such a service will be scanned as well. -.TP -\f[V]--release\f[R] \f[I]version\f[R] -Used to specify the Java SE release that specifies the set of restricted -methods to scan for. -For multi-release jar files, this option also indicates the version of -class file that should be loaded from the jar. -This option should be set to the version of the runtime under which the -application is eventually intended to be run. -If this flag is omitted, the version of \f[V]jnativescan\f[R] is used as -release version, which is the same as the version of the JDK that the -tool belongs to. -.TP -\f[V]--print-native-access\f[R] -Print a comma-separated list of module names that use native -functionalities, instead of the default tree structure. -.TP -\f[V]--help\f[R] or \f[V]-h\f[R] -Prints out a full help message. -.TP -\f[V]--version\f[R] -Prints out the abbreviated version string of the tool. -.SH EXAMPLE OF \f[V]jnativescan\f[R] USE -.PP -\f[V]jnativescan\f[R] accepts a runtime configuration in the form of a -class path, module path, set of root modules, and a target release -version. -For the class path, the tool will scan all jar files, including those -found recursively through the \f[V]Class-Path\f[R] manifest attribute. -For the module path, the tool scans all root modules specified through -\f[V]--add-modules\f[R], and any (transitive) dependence of the root -modules, including any modules that contain service implementations that -are used by a scanned module. -.PP -By default, the tool prints out which jars, classes, and methods use -native functionalities, in a tree-like structure. -The following is an example output: -.IP -.nf -\f[CB] -$ jnativescan --class-path app.jar -app.jar (ALL-UNNAMED): - foo.Main: - foo.Main::main(String[])void references restricted methods: - java.lang.foreign.MemorySegment::reinterpret(long)MemorySegment - foo.Main::nativeMethod()void is a native method declaration -\f[R] -.fi -.PP -\f[V]app.jar (ALL-UNNAMED)\f[R] is the path to the jar file, with the -module name in parentheses behind it. -Since in this case the jar file appears on the class path, -\f[V]ALL-UNNAMED\f[R] is printed to indicate the unnamed module. -The second line of the output, \f[V]foo.Main\f[R], indicates that -methods using native functionalities were found in the -\f[V]foo.Main\f[R] class. -The next line: -.IP -.nf -\f[CB] - foo.Main::main(String[])void references restricted methods: -\f[R] -.fi -.PP -Indicates that the \f[V]main(String[])\f[R] method in the -\f[V]foo.Main\f[R] class references a restricted method, which is listed -on the following line as: -.IP -.nf -\f[CB] - java.lang.foreign.MemorySegment::reinterpret(long)MemorySegment -\f[R] -.fi -.PP -Lastly, the text: -.IP -.nf -\f[CB] - foo.Main::nativeMethod()void is a native method declaration -\f[R] -.fi -.PP -Indicates that the \f[V]foo.Main\f[R] class contains a declaration of a -\f[V]native\f[R] method named \f[V]nativeMethod\f[R]. -.PP -If we add \f[V]--print-native-access\f[R] to the example command line, -we instead get a list of the names of modules that contain accesses to -native functionalities: -.IP -.nf -\f[CB] -$ jnativescan --class-path app.jar --print-native-access -ALL-UNNAMED -\f[R] -.fi -.PP -In this case the output consists of just \f[V]ALL-UNNAMED\f[R], which -indicates a jar file on the class path, that is, in the unnamed module, -contains an access to native functionalities. diff --git a/src/jdk.jdeps/share/man/jnativescan.md b/src/jdk.jdeps/share/man/jnativescan.md new file mode 100644 index 00000000000..73c2429fc89 --- /dev/null +++ b/src/jdk.jdeps/share/man/jnativescan.md @@ -0,0 +1,175 @@ +--- +# Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# This code is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 only, as +# published by the Free Software Foundation. +# +# This code is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# version 2 for more details (a copy is included in the LICENSE file that +# accompanied this code). +# +# You should have received a copy of the GNU General Public License version +# 2 along with this work; if not, write to the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +# or visit www.oracle.com if you need additional information or have any +# questions. +# + +title: 'JNATIVESCAN(1) JDK @@VERSION_SHORT@@ | JDK Commands' +date: @@COPYRIGHT_YEAR@@ +lang: en +--- + +## Name + +jnativescan - static analysis tool that scans one or more jar files for uses of +native functionalities, such as restricted method calls or `native` method declarations. + +## Synopsis + +`jnativescan` \[*options*\] + +*options* +: See [Options for the jnativescan Command] + +## Description + +The `jnative` tool is a static analysis tool provided by the JDK that scans a +JAR file for uses of native functionalities, such as restricted method calls +or `native` method declarations. + +`jnativescan` accepts a runtime class path and module path configuration, as +well as a set of root modules, and a target release. It scans the jars on the +class and module paths, and reports uses of native functionalities either in a tree +like structure, which also identifies that calling classes and methods, or as a list +of module names when the `--print-native-access` flag is specified. + +## Options for the jnativescan Command + +The following options are available: + +`--class-path` *path* +: Used to specify a list of paths pointing to jar files to be scanned. + +All jar files specified through this list will be scanned. If a jar file +contains a `Class-Path` attribute in its manifest, jar files listed there +will be scanned as well. Jar files listed in the `Class-Path` manifest +attribute that can not be found are ignored. All the jar files found are +treated as if they belonged to the unnamed module. + +`--module-path` *path* +: Used to specify a list of paths pointing to jar files or directories +containing jar files, that the tool can use to find modules that need +to be scanned. The list of jar files that will be scanned depends on the +`--add-modules` option. + + For both the `--class-path` and `--module-path` options, *path* should + be a search path that consists of one or more jar files, separated by + the system-specific path separator. For example: + + - **Linux and macOS:** + + > `--class-path /some/foo.jar:/another/different/bar.jar` + + **Note:** + + On Windows, use a semicolon (`;`) as the separator instead of a colon + (`:`). + + - **Windows:** + + > `--class-path C:\some\foo.jar;C:\another\different\bar.jar` + +`--add-modules` *module[,module...]* +: Used to specify a comma-separated list of module names that indicate +the root modules to scan. All the root modules will be scanned, +as well as any modules that they depend on. This includes dependencies on +service implementations specified through the `uses` directive in a module's +`module-info` file. All modules found on the module path that provide an +implementation of such a service will be scanned as well. + +`--release` *version* +: Used to specify the Java SE release that specifies the set of restricted +methods to scan for. For multi-release jar files, this option also indicates +the version of class file that should be loaded from the jar. This option +should be set to the version of the runtime under which the application is +eventually intended to be run. If this flag is omitted, the version of +`jnativescan` is used as release version, which is the same as the version of +the JDK that the tool belongs to. + +`--print-native-access` +: Print a comma-separated list of module names that use native functionalities, +instead of the default tree structure. + +`--help` or `-h` +: Prints out a full help message. + +`--version` +: Prints out the abbreviated version string of the tool. + +## Example of `jnativescan` use + +`jnativescan` accepts a runtime configuration in the form of a class path, module +path, set of root modules, and a target release version. For the class path, the +tool will scan all jar files, including those found recursively through the +`Class-Path` manifest attribute. For the module path, the tool scans all root +modules specified through `--add-modules`, and any (transitive) dependence of +the root modules, including any modules that contain service implementations that +are used by a scanned module. + +By default, the tool prints out which jars, classes, and methods use native +functionalities, in a tree-like structure. The following is an example output: + +``` +$ jnativescan --class-path app.jar +app.jar (ALL-UNNAMED): + foo.Main: + foo.Main::main(String[])void references restricted methods: + java.lang.foreign.MemorySegment::reinterpret(long)MemorySegment + foo.Main::nativeMethod()void is a native method declaration +``` + +`app.jar (ALL-UNNAMED)` is the path to the jar file, with the module name in +parentheses behind it. Since in this case the jar file appears on the class +path, `ALL-UNNAMED` is printed to indicate the unnamed module. The second line +of the output, `foo.Main`, indicates that methods using native functionalities +were found in the `foo.Main` class. The next line: + +``` + foo.Main::main(String[])void references restricted methods: +``` + +Indicates that the `main(String[])` method in the `foo.Main` class references +a restricted method, which is listed on the following line as: + +``` + java.lang.foreign.MemorySegment::reinterpret(long)MemorySegment +``` + +Lastly, the text: + +``` + foo.Main::nativeMethod()void is a native method declaration +``` + +Indicates that the `foo.Main` class contains a declaration of a `native` +method named `nativeMethod`. + +If we add `--print-native-access` to the example command line, we instead +get a list of the names of modules that contain accesses to native +functionalities: + +``` +$ jnativescan --class-path app.jar --print-native-access +ALL-UNNAMED +``` + +In this case the output consists of just `ALL-UNNAMED`, which indicates +a jar file on the class path, that is, in the unnamed module, contains an access +to native functionalities. diff --git a/src/jdk.jdi/share/man/jdb.1 b/src/jdk.jdi/share/man/jdb.1 deleted file mode 100644 index 88097ffeae4..00000000000 --- a/src/jdk.jdi/share/man/jdb.1 +++ /dev/null @@ -1,277 +0,0 @@ -.\" Copyright (c) 1995, 2023, Oracle and/or its affiliates. All rights reserved. -.\" DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -.\" -.\" This code is free software; you can redistribute it and/or modify it -.\" under the terms of the GNU General Public License version 2 only, as -.\" published by the Free Software Foundation. -.\" -.\" This code is distributed in the hope that it will be useful, but WITHOUT -.\" ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -.\" FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -.\" version 2 for more details (a copy is included in the LICENSE file that -.\" accompanied this code). -.\" -.\" You should have received a copy of the GNU General Public License version -.\" 2 along with this work; if not, write to the Free Software Foundation, -.\" Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -.\" -.\" Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -.\" or visit www.oracle.com if you need additional information or have any -.\" questions. -.\" -.\" Automatically generated by Pandoc 2.19.2 -.\" -.\" Define V font for inline verbatim, using C font in formats -.\" that render this, and otherwise B font. -.ie "\f[CB]x\f[R]"x" \{\ -. ftr V B -. ftr VI BI -. ftr VB B -. ftr VBI BI -.\} -.el \{\ -. ftr V CR -. ftr VI CI -. ftr VB CB -. ftr VBI CBI -.\} -.TH "JDB" "1" "2025" "JDK 24-ea" "JDK Commands" -.hy -.SH NAME -.PP -jdb - find and fix bugs in Java platform programs -.SH SYNOPSIS -.PP -\f[V]jdb\f[R] [\f[I]options\f[R]] [\f[I]classname\f[R]] -[\f[I]arguments\f[R]] -.TP -\f[I]options\f[R] -This represents the \f[V]jdb\f[R] command-line options. -See \f[B]Options for the jdb command\f[R]. -.TP -\f[I]classname\f[R] -This represents the name of the main class to debug. -.TP -\f[I]arguments\f[R] -This represents the arguments that are passed to the \f[V]main()\f[R] -method of the class. -.SH DESCRIPTION -.PP -The Java Debugger (JDB) is a simple command-line debugger for Java -classes. -The \f[V]jdb\f[R] command and its options call the JDB. -The \f[V]jdb\f[R] command demonstrates the Java Platform Debugger -Architecture and provides inspection and debugging of a local or remote -JVM. -.SH START A JDB SESSION -.PP -There are many ways to start a JDB session. -The most frequently used way is to have the JDB launch a new JVM with -the main class of the application to be debugged. -Do this by substituting the \f[V]jdb\f[R] command for the \f[V]java\f[R] -command in the command line. -For example, if your application\[aq]s main class is \f[V]MyClass\f[R], -then use the following command to debug it under the JDB: -.RS -.PP -\f[V]jdb MyClass\f[R] -.RE -.PP -When started this way, the \f[V]jdb\f[R] command calls a second JVM with -the specified parameters, loads the specified class, and stops the JVM -before executing that class\[aq]s first instruction. -.PP -Another way to use the \f[V]jdb\f[R] command is by attaching it to a JVM -that\[aq]s already running. -Syntax for starting a JVM to which the \f[V]jdb\f[R] command attaches -when the JVM is running is as follows. -This loads in-process debugging libraries and specifies the kind of -connection to be made. -.RS -.PP -\f[V]java -agentlib:jdwp=transport=dt_socket,server=y,suspend=n MyClass\f[R] -.RE -.PP -You can then attach the \f[V]jdb\f[R] command to the JVM with the -following command: -.RS -.PP -\f[V]jdb -attach 8000\f[R] -.RE -.PP -8000 is the address of the running JVM. -.PP -The \f[V]MyClass\f[R] argument isn\[aq]t specified in the \f[V]jdb\f[R] -command line in this case because the \f[V]jdb\f[R] command is -connecting to an existing JVM instead of launching a new JVM. -.PP -There are many other ways to connect the debugger to a JVM, and all of -them are supported by the \f[V]jdb\f[R] command. -The Java Platform Debugger Architecture has additional documentation on -these connection options. -.SH BREAKPOINTS -.PP -Breakpoints can be set in the JDB at line numbers or at the first -instruction of a method, for example: -.IP \[bu] 2 -The command \f[V]stop at MyClass:22\f[R] sets a breakpoint at the first -instruction for line 22 of the source file containing \f[V]MyClass\f[R]. -.IP \[bu] 2 -The command \f[V]stop in java.lang.String.length\f[R] sets a breakpoint -at the beginning of the method \f[V]java.lang.String.length\f[R]. -.IP \[bu] 2 -The command \f[V]stop in MyClass.<clinit>\f[R] uses \f[V]<clinit>\f[R] -to identify the static initialization code for \f[V]MyClass\f[R]. -.PP -When a method is overloaded, you must also specify its argument types so -that the proper method can be selected for a breakpoint. -For example, \f[V]MyClass.myMethod(int,java.lang.String)\f[R] or -\f[V]MyClass.myMethod()\f[R]. -.PP -The \f[V]clear\f[R] command removes breakpoints using the following -syntax: \f[V]clear MyClass:45\f[R]. -Using the \f[V]clear\f[R] or \f[V]stop\f[R] command with no argument -displays a list of all breakpoints currently set. -The \f[V]cont\f[R] command continues execution. -.SH STEPPING -.PP -The \f[V]step\f[R] command advances execution to the next line whether -it\[aq]s in the current stack frame or a called method. -The \f[V]next\f[R] command advances execution to the next line in the -current stack frame. -.SH EXCEPTIONS -.PP -When an exception occurs for which there isn\[aq]t a \f[V]catch\f[R] -statement anywhere in the throwing thread\[aq]s call stack, the JVM -typically prints an exception trace and exits. -When running under the JDB, however, control returns to the JDB at the -offending throw. -You can then use the \f[V]jdb\f[R] command to diagnose the cause of the -exception. -.PP -Use the \f[V]catch\f[R] command to cause the debugged application to -stop at other thrown exceptions, for example: -\f[V]catch java.io.FileNotFoundException\f[R] or \f[V]catch\f[R] -\f[V]mypackage.BigTroubleException\f[R]. -Any exception that\[aq]s an instance of the specified class or subclass -stops the application at the point where the exception is thrown. -.PP -The \f[V]ignore\f[R] command negates the effect of an earlier -\f[V]catch\f[R] command. -The \f[V]ignore\f[R] command doesn\[aq]t cause the debugged JVM to -ignore specific exceptions, but only to ignore the debugger. -.SH OPTIONS FOR THE JDB COMMAND -.PP -When you use the \f[V]jdb\f[R] command instead of the \f[V]java\f[R] -command on the command line, the \f[V]jdb\f[R] command accepts many of -the same options as the \f[V]java\f[R] command. -.PP -The following options are accepted by the \f[V]jdb\f[R] command: -.TP -\f[V]-help\f[R] -Displays a help message. -.TP -\f[V]-sourcepath\f[R] \f[I]dir1\f[R]\f[V]:\f[R]\f[I]dir2\f[R]\f[V]:\f[R]... -Uses the specified path to search for source files in the specified -path. -If this option is not specified, then use the default path of dot -(\f[V].\f[R]). -.TP -\f[V]-attach\f[R] \f[I]address\f[R] -Attaches the debugger to a running JVM with the default connection -mechanism. -.TP -\f[V]-listen\f[R] \f[I]address\f[R] -Waits for a running JVM to connect to the specified address with a -standard connector. -.TP -\f[V]-listenany\f[R] -Waits for a running JVM to connect at any available address using a -standard connector. -.TP -\f[V]-launch\f[R] -Starts the debugged application immediately upon startup of the -\f[V]jdb\f[R] command. -The \f[V]-launch\f[R] option removes the need for the \f[V]run\f[R] -command. -The debugged application is launched and then stopped just before the -initial application class is loaded. -At that point, you can set any necessary breakpoints and use the -\f[V]cont\f[R] command to continue execution. -.TP -\f[V]-listconnectors\f[R] -Lists the connectors available in this JVM. -.TP -\f[V]-connect\f[R] \f[I]connector-name\f[R]\f[V]:\f[R]\f[I]name1\f[R]\f[V]=\f[R]\f[I]value1\f[R].... -Connects to the target JVM with the named connector and listed argument -values. -.TP -\f[V]-dbgtrace\f[R] [\f[I]flags\f[R]] -Prints information for debugging the \f[V]jdb\f[R] command. -.TP -\f[V]-tclient\f[R] -Runs the application in the Java HotSpot VM client. -.TP -\f[V]-trackallthreads\f[R] -Track all threads as they are created, including virtual threads. -See \f[B]Working With Virtual Threads\f[R] below. -.TP -\f[V]-tserver\f[R] -Runs the application in the Java HotSpot VM server. -.TP -\f[V]-J\f[R]\f[I]option\f[R] -Passes \f[I]option\f[R] to the JDB JVM, where option is one of the -options described on the reference page for the Java application -launcher. -For example, \f[V]-J-Xms48m\f[R] sets the startup memory to 48 MB. -See \f[I]Overview of Java Options\f[R] in \f[B]java\f[R]. -.PP -The following options are forwarded to the debuggee process: -.TP -\f[V]-R\f[R]\f[I]option\f[R] -Passes \f[I]option\f[R] to the debuggee JVM, where option is one of the -options described on the reference page for the Java application -launcher. -For example, \f[V]-R-Xms48m\f[R] sets the startup memory to 48 MB. -See \f[I]Overview of Java Options\f[R] in \f[B]java\f[R]. -.TP -\f[V]-v\f[R] or \f[V]-verbose\f[R][\f[V]:\f[R]\f[I]class\f[R]|\f[V]gc\f[R]|\f[V]jni\f[R]] -Turns on the verbose mode. -.TP -\f[V]-D\f[R]\f[I]name\f[R]\f[V]=\f[R]\f[I]value\f[R] -Sets a system property. -.TP -\f[V]-classpath\f[R] \f[I]dir\f[R] -Lists directories separated by colons in which to look for classes. -.TP -\f[V]-X\f[R] \f[I]option\f[R] -A nonstandard target JVM option. -.PP -Other options are supported to provide alternate mechanisms for -connecting the debugger to the JVM that it\[aq]s to debug. -.SH WORKING WITH VIRTUAL THREADS -.PP -Often virtual theads are created in such large numbers and frequency -that they can overwhelm a debugger. -For this reason by default JDB does not keep track of virtual threads as -they are created. -It will only keep track of virtual threads that an event has arrived on, -such as a breakpoint event. -The \f[V]-trackallthreads\f[R] option can be used to make JDB track all -virtual threads as they are created. -.PP -When JDB first connects, it requests a list of all known threads from -the Debug Agent. -By default the debug agent does not return any virtual threads in this -list, once again because the list could be so large that it overwhelms -the debugger. -The Debug Agent has an \f[V]includevirtualthreads\f[R] option that can -be enabled to change this behavior so all known virtual threads will be -included in the list. -The JDB \f[V]-trackallthreads\f[R] option will cause JDB to -automatically enable the Debug Agent\[aq]s -\f[V]includevirtualthreads\f[R] option when JDB launches an application -to debug. -However, keep in mind that the Debug Agent may not know about any -virtual threads that were created before JDB attached to the debugged -application. diff --git a/src/jdk.jdi/share/man/jdb.md b/src/jdk.jdi/share/man/jdb.md new file mode 100644 index 00000000000..e163cbf5e23 --- /dev/null +++ b/src/jdk.jdi/share/man/jdb.md @@ -0,0 +1,237 @@ +--- +# Copyright (c) 1995, 2023, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# This code is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 only, as +# published by the Free Software Foundation. +# +# This code is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# version 2 for more details (a copy is included in the LICENSE file that +# accompanied this code). +# +# You should have received a copy of the GNU General Public License version +# 2 along with this work; if not, write to the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +# or visit www.oracle.com if you need additional information or have any +# questions. +# + +title: 'JDB(1) JDK @@VERSION_SHORT@@ | JDK Commands' +date: @@COPYRIGHT_YEAR@@ +lang: en +--- + +## Name + +jdb - find and fix bugs in Java platform programs + +## Synopsis + +`jdb` \[*options*\] \[*classname*\] \[*arguments*\] + +*options* +: This represents the `jdb` command-line options. See [Options for the jdb + command]. + +*classname* +: This represents the name of the main class to debug. + +*arguments* +: This represents the arguments that are passed to the `main()` method of the + class. + +## Description + +The Java Debugger (JDB) is a simple command-line debugger for Java classes. The +`jdb` command and its options call the JDB. The `jdb` command demonstrates the +Java Platform Debugger Architecture and provides inspection and debugging of a +local or remote JVM. + +## Start a JDB Session + +There are many ways to start a JDB session. The most frequently used way is to +have the JDB launch a new JVM with the main class of the application to be +debugged. Do this by substituting the `jdb` command for the `java` command in +the command line. For example, if your application's main class is `MyClass`, +then use the following command to debug it under the JDB: + +> `jdb MyClass` + +When started this way, the `jdb` command calls a second JVM with the specified +parameters, loads the specified class, and stops the JVM before executing that +class's first instruction. + +Another way to use the `jdb` command is by attaching it to a JVM that's already +running. Syntax for starting a JVM to which the `jdb` command attaches when the +JVM is running is as follows. This loads in-process debugging libraries and +specifies the kind of connection to be made. + +> `java -agentlib:jdwp=transport=dt_socket,server=y,suspend=n MyClass` + +You can then attach the `jdb` command to the JVM with the following command: + +> `jdb -attach 8000` + +8000 is the address of the running JVM. + +The `MyClass` argument isn't specified in the `jdb` command line in this case +because the `jdb` command is connecting to an existing JVM instead of launching +a new JVM. + +There are many other ways to connect the debugger to a JVM, and all of them are +supported by the `jdb` command. The Java Platform Debugger Architecture has +additional documentation on these connection options. + +## Breakpoints + +Breakpoints can be set in the JDB at line numbers or at the first instruction +of a method, for example: + +- The command `stop at MyClass:22` sets a breakpoint at the first instruction + for line 22 of the source file containing `MyClass`. + +- The command `stop in java.lang.String.length` sets a breakpoint at the + beginning of the method `java.lang.String.length`. + +- The command `stop in MyClass.<clinit>` uses `<clinit>` to identify the + static initialization code for `MyClass`. + +When a method is overloaded, you must also specify its argument types so that +the proper method can be selected for a breakpoint. For example, +`MyClass.myMethod(int,java.lang.String)` or `MyClass.myMethod()`. + +The `clear` command removes breakpoints using the following syntax: +`clear MyClass:45`. Using the `clear` or `stop` command with no argument +displays a list of all breakpoints currently set. The `cont` command continues +execution. + +## Stepping + +The `step` command advances execution to the next line whether it's in the +current stack frame or a called method. The `next` command advances execution +to the next line in the current stack frame. + +## Exceptions + +When an exception occurs for which there isn't a `catch` statement anywhere in +the throwing thread's call stack, the JVM typically prints an exception trace +and exits. When running under the JDB, however, control returns to the JDB at +the offending throw. You can then use the `jdb` command to diagnose the cause +of the exception. + +Use the `catch` command to cause the debugged application to stop at other +thrown exceptions, for example: `catch java.io.FileNotFoundException` or +`catch` `mypackage.BigTroubleException`. Any exception that's an instance of +the specified class or subclass stops the application at the point where the +exception is thrown. + +The `ignore` command negates the effect of an earlier `catch` command. The +`ignore` command doesn't cause the debugged JVM to ignore specific exceptions, +but only to ignore the debugger. + +## Options for the jdb command + +When you use the `jdb` command instead of the `java` command on the command +line, the `jdb` command accepts many of the same options as the `java` +command. + +The following options are accepted by the `jdb` command: + +`-help` +: Displays a help message. + +`-sourcepath` *dir1*`:`*dir2*`:`... +: Uses the specified path to search for source files in the specified path. + If this option is not specified, then use the default path of dot (`.`). + +`-attach` *address* +: Attaches the debugger to a running JVM with the default connection + mechanism. + +`-listen` *address* +: Waits for a running JVM to connect to the specified address with a standard + connector. + +`-listenany` +: Waits for a running JVM to connect at any available address using a + standard connector. + +`-launch` +: Starts the debugged application immediately upon startup of the `jdb` + command. The `-launch` option removes the need for the `run` command. The + debugged application is launched and then stopped just before the initial + application class is loaded. At that point, you can set any necessary + breakpoints and use the `cont` command to continue execution. + +`-listconnectors` +: Lists the connectors available in this JVM. + +`-connect` *connector-name*`:`*name1*`=`*value1*.... +: Connects to the target JVM with the named connector and listed argument + values. + +`-dbgtrace` \[*flags*\] +: Prints information for debugging the `jdb` command. + +`-tclient` +: Runs the application in the Java HotSpot VM client. + +`-trackallthreads` +: Track all threads as they are created, including virtual threads. + See [Working With Virtual Threads](#working-with-virtual-threads) below. + +`-tserver` +: Runs the application in the Java HotSpot VM server. + +`-J`*option* +: Passes *option* to the JDB JVM, where option is one of the options described on + the reference page for the Java application launcher. For example, + `-J-Xms48m` sets the startup memory to 48 MB. See *Overview of Java + Options* in [java](java.html). + +The following options are forwarded to the debuggee process: + +`-R`*option* +: Passes *option* to the debuggee JVM, where option is one of the options described on + the reference page for the Java application launcher. For example, + `-R-Xms48m` sets the startup memory to 48 MB. See *Overview of Java + Options* in [java](java.html). + +`-v` or `-verbose`\[`:`*class*\|`gc`\|`jni`\] +: Turns on the verbose mode. + +`-D`*name*`=`*value* +: Sets a system property. + +`-classpath` *dir* +: Lists directories separated by colons in which to look for classes. + +`-X` *option* +: A nonstandard target JVM option. + +Other options are supported to provide alternate mechanisms for connecting the +debugger to the JVM that it's to debug. + +## Working With Virtual Threads + +Often virtual theads are created in such large numbers and frequency that they +can overwhelm a debugger. For this reason by default JDB does not keep track +of virtual threads as they are created. It will only keep track of virtual +threads that an event has arrived on, such as a breakpoint event. The +`-trackallthreads` option can be used to make JDB track all virtual threads +as they are created. + +When JDB first connects, it requests a list of all known threads from the Debug Agent. +By default the debug agent does not return any virtual threads in this list, once +again because the list could be so large that it overwhelms the debugger. The +Debug Agent has an `includevirtualthreads` option that can be enabled to change +this behavior so all known virtual threads will be included in the list. The +JDB `-trackallthreads` option will cause JDB to automatically enable the Debug Agent's +`includevirtualthreads` option when JDB launches an application to debug. However, keep in mind +that the Debug Agent may not know about any virtual threads that were created +before JDB attached to the debugged application. diff --git a/src/jdk.jfr/share/man/jfr.1 b/src/jdk.jfr/share/man/jfr.1 deleted file mode 100644 index 71a487f558e..00000000000 --- a/src/jdk.jfr/share/man/jfr.1 +++ /dev/null @@ -1,438 +0,0 @@ -.\" Copyright (c) 2019, 2023, Oracle and/or its affiliates. All rights reserved. -.\" DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -.\" -.\" This code is free software; you can redistribute it and/or modify it -.\" under the terms of the GNU General Public License version 2 only, as -.\" published by the Free Software Foundation. -.\" -.\" This code is distributed in the hope that it will be useful, but WITHOUT -.\" ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -.\" FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -.\" version 2 for more details (a copy is included in the LICENSE file that -.\" accompanied this code). -.\" -.\" You should have received a copy of the GNU General Public License version -.\" 2 along with this work; if not, write to the Free Software Foundation, -.\" Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -.\" -.\" Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -.\" or visit www.oracle.com if you need additional information or have any -.\" questions. -.\" -.\" Automatically generated by Pandoc 2.19.2 -.\" -.\" Define V font for inline verbatim, using C font in formats -.\" that render this, and otherwise B font. -.ie "\f[CB]x\f[R]"x" \{\ -. ftr V B -. ftr VI BI -. ftr VB B -. ftr VBI BI -.\} -.el \{\ -. ftr V CR -. ftr VI CI -. ftr VB CB -. ftr VBI CBI -.\} -.TH "JFR" "1" "2025" "JDK 24-ea" "JDK Commands" -.hy -.SH NAME -.PP -jfr - print and manipulate Flight Recorder files -.SH SYNOPSIS -.PP -To print the contents of a flight recording to standard out: -.PP -\f[V]jfr\f[R] \f[V]print\f[R] [\f[I]options\f[R]] \f[I]file\f[R] -.PP -To display aggregated event data on standard out: -.PP -\f[V]jfr\f[R] \f[V]view\f[R] [\f[I]options\f[R]] \f[I]file\f[R] -.PP -To configure a .jfc settings file: -.PP -\f[V]jfr\f[R] \f[V]configure\f[R] [\f[I]options\f[R]] -.PP -To print metadata information about flight recording events: -.PP -\f[V]jfr\f[R] \f[V]metadata\f[R] [\f[I]file\f[R]] -.PP -To view the summary statistics for a flight recording file: -.PP -\f[V]jfr\f[R] \f[V]summary\f[R] \f[I]file\f[R] -.PP -To remove events from a flight recording file: -.PP -\f[V]jfr\f[R] \f[V]scrub\f[R] [\f[I]options\f[R]] \f[I]file\f[R] -.PP -To assemble chunk files into a flight recording file: -.PP -\f[V]jfr\f[R] \f[V]assemble\f[R] \f[I]repository\f[R] \f[I]file\f[R] -.PP -To disassemble a flight recording file into chunk files: -.PP -\f[V]jfr\f[R] \f[V]disassmble\f[R] [\f[I]options\f[R]] \f[I]file\f[R] -.TP -\f[I]options\f[R] -Optional: Specifies command-line options separated by spaces. -See the individual subcomponent sections for descriptions of the -available options. -.TP -\f[I]file\f[R] -Specifies the name of the target flight recording file (\f[V].jfr\f[R]). -.TP -\f[I]repository\f[R] -Specifies the location of the chunk files which are to be assembled into -a flight recording. -.SH DESCRIPTION -.PP -The \f[V]jfr\f[R] command provides a tool for interacting with flight -recorder files (\f[V].jfr\f[R]). -The main function is to filter, summarize and output flight recording -files into human readable format. -There is also support for scrubbing, merging and splitting recording -files. -.PP -Flight recording files are created and saved as binary formatted files. -Having a tool that can extract the contents from a flight recording and -manipulate the contents and translate them into human readable format -helps developers to debug performance issues with Java applications. -.SS Subcommands -.PP -The \f[V]jfr\f[R] command has several subcommands: -.IP \[bu] 2 -\f[V]print\f[R] -.IP \[bu] 2 -\f[V]view\f[R] -.IP \[bu] 2 -\f[V]configure\f[R] -.IP \[bu] 2 -\f[V]metadata\f[R] -.IP \[bu] 2 -\f[V]summary\f[R] -.IP \[bu] 2 -\f[V]scrub\f[R] -.IP \[bu] 2 -\f[V]assemble\f[R] -.IP \[bu] 2 -\f[V]disassemble\f[R] -.SS \f[V]jfr print\f[R] subcommand -.PP -Use \f[V]jfr print\f[R] to print the contents of a flight recording file -to standard out. -.PP -The syntax is: -.PP -\f[V]jfr print\f[R] [\f[V]--xml\f[R]|\f[V]--json\f[R]] -[\f[V]--categories\f[R] <\f[I]filters\f[R]>] [\f[V]--events\f[R] -<\f[I]filters\f[R]>] [\f[V]--stack-depth\f[R] <\f[I]depth\f[R]>] -<\f[I]file\f[R]> -.PP -where: -.TP -\f[V]--xml\f[R] -Print the recording in XML format. -.TP -\f[V]--json\f[R] -Print the recording in JSON format. -.TP -\f[V]--categories\f[R] <\f[I]filters\f[R]> -Select events matching a category name. -The filter is a comma-separated list of names, simple and/or qualified, -and/or quoted glob patterns. -.TP -\f[V]--events\f[R] <\f[I]filters\f[R]> -Select events matching an event name. -The filter is a comma-separated list of names, simple and/or qualified, -and/or quoted glob patterns. -.TP -\f[V]--stack-depth\f[R] <\f[I]depth\f[R]> -Number of frames in stack traces, by default 5. -.TP -<\f[I]file\f[R]> -Location of the recording file (\f[V].jfr\f[R]) -.PP -The default format for printing the contents of the flight recording -file is human readable form unless either \f[V]xml\f[R] or -\f[V]json\f[R] is specified. -These options provide machine-readable output that can be further parsed -or processed by user created scripts. -.PP -Use \f[V]jfr --help print\f[R] to see example usage of filters. -.PP -To reduce the amount of data displayed, it is possible to filter out -events or categories of events. -The filter operates on the symbolic name of an event, set by using the -\f[V]\[at]Name\f[R] annotation, or the category name, set by using the -\f[V]\[at]Category\f[R] annotation. -If multiple filters are used, events from both filters will be included. -If no filter is used, all the events will be printed. -If a combination of a category filter and event filter is used, the -selected events will be the union of the two filters. -.PP -For example, to show all GC events and the CPULoad event, the following -command could be used: -.PP -\f[V]jfr print --categories GC --events CPULoad recording.jfr\f[R] -.PP -Event values are formatted according to the content types that are being -used. -For example, a field with the \f[V]jdk.jfr.Percentage\f[R] annotation -that has the value 0.52 is formatted as 52%. -.PP -Stack traces are by default truncated to 5 frames, but the number can be -increased/decreased using the \f[V]--stack-depth\f[R] command-line -option. -.SS \f[V]jfr view\f[R] subcommand -.PP -Use \f[V]jfr view\f[R] to aggregate and display event data on standard -out. -.PP -The syntax is: -.PP -\f[V]jfr view\f[R] [\f[V]--verbose\f[R]] [\f[V]--width\f[R] -<\f[I]integer\f[R]>] [\f[V]--truncate\f[R] <\f[I]mode\f[R]>] -[\f[V]--cell-height\f[R] <\f[I]integer\f[R]>] <\f[I]view\f[R]> -<\f[I]file\f[R]> -.PP -where: -.TP -\f[V]--verbose\f[R] -Displays the query that makes up the view. -.TP -\f[V]--width\f[R] <\f[I]integer\f[R]> -The width of the view in characters. -Default value depends on the view. -.TP -\f[V]--truncate\f[R] <\f[I]mode\f[R]> -How to truncate content that exceeds space in a table cell. -Mode can be \[aq]beginning\[aq] or \[aq]end\[aq]. -Default value is \[aq]end\[aq]. -.TP -\f[V]--cell-height\f[R] <\f[I]integer\f[R]> -Maximum number of rows in a table cell. -Default value depends on the view. -.TP -<\f[I]view\f[R]> -Name of the view or event type to display. -Use \f[V]jfr --help view\f[R] to see a list of available views. -.TP -<\f[I]file\f[R]> -Location of the recording file (.jfr) -.PP -The <\f[I]view\f[R]> parameter can be an event type name. -Use the \f[V]jfr view types <file>\f[R] to see a list. -To display all views, use \f[V]jfr view all-views <file>\f[R]. -To display all events, use \f[V]jfr view all-events <file>\f[R]. -.SS \f[V]jfr configure\f[R] subcommand -.PP -Use \f[V]jfr configure\f[R] to configure a .jfc settings file. -.PP -The syntax is: -.PP -\f[V]jfr configure\f[R] [--interactive] [--verbose] [--input ] [--output -] [option=value]* [event-setting=value]* -.TP -\f[V]--interactive\f[R] -Interactive mode where the configuration is determined by a set of -questions. -.TP -\f[V]--verbose\f[R] -Displays the modified settings. -.TP -\f[V]--input\f[R] <\f[I]files\f[R]> -A comma-separated list of .jfc files from which the new configuration is -based. -If no file is specified, the default file in the JDK is used -(default.jfc). -If \[aq]none\[aq] is specified, the new configuration starts empty. -.TP -\f[V]--output\f[R] <\f[I]file\f[R]> -The filename of the generated output file. -If not specified, the filename custom.jfc will be used. -.TP -\f[I]option=value\f[R] -The option value to modify. -To see available options, use \f[V]jfr help configure\f[R] -.TP -\f[I]event-setting=value\f[R] -The event setting value to modify. -Use the form: -<\f[I]event-name\f[R]>#<\f[I]setting-name\f[R]>=<\f[I]value\f[R]> To add -a new event setting, prefix the event name with \[aq]+\[aq]. -.PP -The whitespace delimiter can be omitted for timespan values, i.e. -20ms. -For more information about the settings syntax, see Javadoc of the -jdk.jfr package. -.SS \f[V]jfr metadata\f[R] subcommand -.PP -Use \f[V]jfr metadata\f[R] to display information about events, such as -event names, categories and field layout within a flight recording file. -.PP -The syntax is: -.PP -\f[V]jfr metadata\f[R] [--categories ] [--events ] [] -.TP -\f[V]--categories\f[R] <\f[I]filter\f[R]> -Select events matching a category name. -The filter is a comma-separated list of names, simple and/or qualified, -and/or quoted glob patterns. -.TP -\f[V]--events\f[R] <\f[I]filter\f[R]> -Select events matching an event name. -The filter is a comma-separated list of names, simple and/or qualified, -and/or quoted glob patterns. -.TP -<\f[I]file\f[R]> -Location of the recording file (.jfr) -.PP -If the parameter is omitted, metadata from the JDK where the -\[aq]jfr\[aq] tool is located will be used. -.SS \f[V]jfr summary\f[R] subcommand -.PP -Use \f[V]jfr summary\f[R] to print statistics for a recording. -For example, a summary can illustrate the number of recorded events and -how much disk space they used. -This is useful for troubleshooting and understanding the impact of event -settings. -.PP -The syntax is: -.PP -\f[V]jfr summary\f[R] <\f[I]file\f[R]> -.PP -where: -.TP -<\f[I]file\f[R]> -Location of the flight recording file (\f[V].jfr\f[R]) -.SS \f[V]jfr scrub\f[R] subcommand -.PP -Use \f[V]jfr scrub\f[R] to remove sensitive contents from a file or to -reduce its size. -.PP -The syntax is: -.PP -\f[V]jfr scrub\f[R] [--include-events <\f[I]filter\f[R]>] -[--exclude-events <\f[I]filter\f[R]>] [--include-categories -<\f[I]filter\f[R]>] [--exclude-categories <\f[I]filter\f[R]>] -[--include-threads <\f[I]filter\f[R]>] [--exclude-threads -<\f[I]filter\f[R]>] <\f[I]input-file\f[R]> [<\f[I]output-file\f[R]>] -.TP -\f[V]--include-events\f[R] <\f[I]filter\f[R]> -Select events matching an event name. -.TP -\f[V]--exclude-events\f[R] <\f[I]filter\f[R]> -Exclude events matching an event name. -.TP -\f[V]--include-categories\f[R] <\f[I]filter\f[R]> -Select events matching a category name. -.TP -\f[V]--exclude-categories\f[R] <\f[I]filter\f[R]> -Exclude events matching a category name. -.TP -\f[V]--include-threads\f[R] <\f[I]filter\f[R]> -Select events matching a thread name. -.TP -\f[V]--exclude-threads\f[R] <\f[I]filter\f[R]> -Exclude events matching a thread name. -.TP -<\f[I]input-file\f[R]> -The input file to read events from. -.TP -<\f[I]output-file\f[R]> -The output file to write filter events to. -If no file is specified, it will be written to the same path as the -input file, but with \[dq]-scrubbed\[dq] appended to the filename. -.PP -The filter is a comma-separated list of names, simple and/or qualified, -and/or quoted glob patterns. -If multiple filters are used, they are applied in the specified order. -.SS \f[V]jfr assemble\f[R] subcommand -.PP -Use jfr \f[V]assemble\f[R] to assemble chunk files into a recording -file. -.PP -The syntax is: -.PP -\f[V]jfr assemble\f[R] <\f[I]repository\f[R]> <\f[I]file\f[R]> -.PP -where: -.TP -<\f[I]repository\f[R]> -Directory where the repository containing chunk files is located. -.TP -<\f[I]file\f[R]> -Location of the flight recording file (\f[V].jfr\f[R]). -.PP -Flight recording information is written in chunks. -A chunk contains all of the information necessary for parsing. -A chunk typically contains events useful for troubleshooting. -If a JVM should crash, these chunks can be recovered and used to create -a flight recording file using this \f[V]jfr assemble\f[R] command. -These chunk files are concatenated in chronological order and chunk -files that are not finished (.part) are excluded. -.SS \f[V]jfr disassemble\f[R] subcommand -.PP -Use \f[V]jfr disassemble\f[R] to decompose a flight recording file into -its chunk file pieces. -.PP -The syntax is: -.PP -\f[V]jfr disassemble\f[R] [\f[V]--max-chunks\f[R] <\f[I]chunks\f[R]>] -[\f[V]--output\f[R] <\f[I]directory\f[R]>] <\f[I]file\f[R]> -.PP -where: -.TP -\f[V]--output\f[R] <\f[I]directory\f[R]> -The location to write the disassembled file, by default the current -directory -.TP -\f[V]--max-chunks\f[R] <\f[I]chunks\f[R]> -Maximum number of chunks per file, by default 5. -The chunk size varies, but is typically around 15 MB. -.TP -\f[V]--max-size\f[R] <\f[I]size\f[R]> -Maximum number of bytes per file. -.TP -<\f[I]file\f[R]> -Location of the flight recording file (\f[V].jfr\f[R]) -.PP -This function can be useful for repairing a broken file by removing the -faulty chunk. -It can also be used to reduce the size of a file that is too large to -transfer. -The resulting chunk files are named \f[V]myfile_1.jfr\f[R], -\f[V]myfile_2.jfr\f[R], etc. -If needed, the resulting file names will be padded with zeros to -preserve chronological order. -For example, the chunk file name is \f[V]myfile_001.jfr\f[R] if the -recording consists of more than 100 chunks. -.SS jfr version and help subcommands -.PP -Use \f[V]jfr --version\f[R] or \f[V]jfr version\f[R] to view the version -string information for this jfr command. -.PP -To get help on any of the jfr subcommands, use: -.PP -\f[V]jfr <--help|help>\f[R] [\f[I]subcommand\f[R]] -.PP -where: -.PP -[\f[I]subcommand\f[R]] is any of: -.IP \[bu] 2 -\f[V]print\f[R] -.IP \[bu] 2 -\f[V]view\f[R] -.IP \[bu] 2 -\f[V]configure\f[R] -.IP \[bu] 2 -\f[V]metadata\f[R] -.IP \[bu] 2 -\f[V]summary\f[R] -.IP \[bu] 2 -\f[V]scrub\f[R] -.IP \[bu] 2 -\f[V]assemble\f[R] -.IP \[bu] 2 -\f[V]disassemble\f[R] diff --git a/src/jdk.jfr/share/man/jfr.md b/src/jdk.jfr/share/man/jfr.md new file mode 100644 index 00000000000..f942b97dd99 --- /dev/null +++ b/src/jdk.jfr/share/man/jfr.md @@ -0,0 +1,399 @@ +--- +# Copyright (c) 2019, 2023, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# This code is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 only, as +# published by the Free Software Foundation. +# +# This code is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# version 2 for more details (a copy is included in the LICENSE file that +# accompanied this code). +# +# You should have received a copy of the GNU General Public License version +# 2 along with this work; if not, write to the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +# or visit www.oracle.com if you need additional information or have any +# questions. +# + +title: 'JFR(1) JDK @@VERSION_SHORT@@ | JDK Commands' +date: @@COPYRIGHT_YEAR@@ +lang: en +--- + +## Name + +jfr - print and manipulate Flight Recorder files + +## Synopsis + +To print the contents of a flight recording to standard out: + +`jfr` `print` \[*options*\] *file* + +To display aggregated event data on standard out: + +`jfr` `view` \[*options*\] *file* + +To configure a .jfc settings file: + +`jfr` `configure` \[*options*\] + +To print metadata information about flight recording events: + +`jfr` `metadata` \[*file*\] + +To view the summary statistics for a flight recording file: + +`jfr` `summary` *file* + +To remove events from a flight recording file: + +`jfr` `scrub` \[*options*\] *file* + +To assemble chunk files into a flight recording file: + +`jfr` `assemble` *repository* *file* + +To disassemble a flight recording file into chunk files: + +`jfr` `disassmble` \[*options*\] *file* + +*options* +: Optional: Specifies command-line options separated by spaces. See the +individual subcomponent sections for descriptions of the available options. + +*file* +: Specifies the name of the target flight recording file (`.jfr`). + +*repository* +: Specifies the location of the chunk files which are to be assembled into +a flight recording. + +## Description + +The `jfr` command provides a tool for interacting with flight recorder files +(`.jfr`). The main function is to filter, summarize and output flight +recording files into human readable format. There is also support for scrubbing, +merging and splitting recording files. + +Flight recording files are created and saved as binary formatted files. Having +a tool that can extract the contents from a flight recording and manipulate the +contents and translate them into human readable format helps developers to debug +performance issues with Java applications. + +### Subcommands + +The `jfr` command has several subcommands: + +- `print` +- `view` +- `configure` +- `metadata` +- `summary` +- `scrub` +- `assemble` +- `disassemble` + +#### `jfr print` subcommand + +Use `jfr print` to print the contents of a flight recording file to standard out. + +The syntax is: + +`jfr print` \[`--xml`|`--json`\] + \[`--categories` <*filters*>\] + \[`--events` <*filters*>\] + \[`--stack-depth` <*depth*>\] + <*file*> + +where: + +<a id="print-option-xml">`--xml`</a> +: Print the recording in XML format. + +<a id="print-option-json">`--json`</a> +: Print the recording in JSON format. + +<a id="print-option-categories">`--categories` <*filters*></a> +: Select events matching a category name. +The filter is a comma-separated list of names, +simple and/or qualified, and/or quoted glob patterns. + +<a id="print-option-events">`--events` <*filters*></a> +: Select events matching an event name. +The filter is a comma-separated list of names, +simple and/or qualified, and/or quoted glob patterns. + +<a id="print-option-stack-depth">`--stack-depth` <*depth*></a> +: Number of frames in stack traces, by default 5. + +<a id="print-option-file"><*file*></a> +: Location of the recording file (`.jfr`) + +The default format for printing the contents of the flight recording file is human +readable form unless either `xml` or `json` is specified. These options provide +machine-readable output that can be further parsed or processed by user created scripts. + +Use `jfr --help print` to see example usage of filters. + +To reduce the amount of data displayed, it is possible to filter out events or +categories of events. The filter operates on the symbolic name of an event, +set by using the `@Name` annotation, or the category name, set by using +the `@Category` annotation. If multiple filters are used, events from both +filters will be included. If no filter is used, all the events will be printed. +If a combination of a category filter and event filter is used, the selected events +will be the union of the two filters. + +For example, to show all GC events and the CPULoad event, the following command could be used: + +`jfr print --categories GC --events CPULoad recording.jfr` + +Event values are formatted according to the content types that are being used. +For example, a field with the `jdk.jfr.Percentage` annotation that has the value 0.52 +is formatted as 52%. + +Stack traces are by default truncated to 5 frames, but the number can be +increased/decreased using the `--stack-depth` command-line option. + +#### `jfr view` subcommand + +Use `jfr view` to aggregate and display event data on standard out. + +The syntax is: + + `jfr view` \[`--verbose`\] + \[`--width` <*integer*>\] + \[`--truncate` <*mode*>\] + \[`--cell-height` <*integer*>\] + <*view*> + <*file*> + +where: + +<a id="view-option-verbose">`--verbose`</a> +: Displays the query that makes up the view. + +<a id="view-option-width">`--width` <*integer*></a> +: The width of the view in characters. Default value depends on the view. + +<a id="view-option-truncate">`--truncate` <*mode*></a> +: How to truncate content that exceeds space in a table cell. +Mode can be 'beginning' or 'end'. Default value is 'end'. + +<a id="view-option-cell-height">`--cell-height` <*integer*></a> +: Maximum number of rows in a table cell. Default value depends on the view. + +<a id="view-option-view"><*view*></a> +: Name of the view or event type to display. Use `jfr --help view` to see a +list of available views. + +<a id="view-option-file"><*file*></a> +: Location of the recording file (.jfr) + +The <*view*> parameter can be an event type name. Use the `jfr view types <file>` +to see a list. To display all views, use `jfr view all-views <file>`. To display +all events, use `jfr view all-events <file>`. + +#### `jfr configure` subcommand + +Use `jfr configure` to configure a .jfc settings file. + +The syntax is: + + `jfr configure` \[--interactive\] \[--verbose\] + \[--input <files>\] [--output <file>\] + \[option=value\]* \[event-setting=value\]* + +<a id="configure-option-interactive">`--interactive`</a> +: Interactive mode where the configuration is determined by a set of questions. + +<a id="configure-option-verbose">`--verbose`</a> +: Displays the modified settings. + +<a id="configure-option-input">`--input` <*files*></a> +: A comma-separated list of .jfc files from which the new configuration is +based. If no file is specified, the default file in the JDK is used +(default.jfc). If 'none' is specified, the new configuration starts empty. + +<a id="configure-option-output">`--output` <*file*></a> +: The filename of the generated output file. If not specified, the filename +custom.jfc will be used. + +<a id="configure-option-value">*option=value*</a> +: The option value to modify. To see available options, +use `jfr help configure` + +<a id="configure-option-event-setting">*event-setting=value*</a> +: The event setting value to modify. Use the form: + <*event-name*>#<*setting-name*>=<*value*> +To add a new event setting, prefix the event name with '+'. + +The whitespace delimiter can be omitted for timespan values, i.e. 20ms. For +more information about the settings syntax, see Javadoc of the jdk.jfr package. + +#### `jfr metadata` subcommand + +Use `jfr metadata` to display information about events, such as event +names, categories and field layout within a flight recording file. + +The syntax is: + +`jfr metadata` \[--categories <filter>\] + \[--events <filter>\] + \[<file>\] + +<a id="metadata-option-categories">`--categories` <*filter*></a> +: Select events matching a category name. The filter is a comma-separated +list of names, simple and/or qualified, and/or quoted glob patterns. + +<a id="metadata-option-events">`--events` <*filter*></a> +: Select events matching an event name. The filter is a comma-separated +list of names, simple and/or qualified, and/or quoted glob patterns. + +<a id="metadata-option-file"><*file*></a> +: Location of the recording file (.jfr) + +If the <file> parameter is omitted, metadata from the JDK where +the 'jfr' tool is located will be used. + +#### `jfr summary` subcommand + +Use `jfr summary` to print statistics for a recording. For example, a summary can +illustrate the number of recorded events and how much disk space they used. This +is useful for troubleshooting and understanding the impact of event settings. + +The syntax is: + +`jfr summary` <*file*> + +where: + +<a id="summary-option-file"><*file*></a> +: Location of the flight recording file (`.jfr`) + +#### `jfr scrub` subcommand + +Use `jfr scrub` to remove sensitive contents from a file or to reduce its size. + +The syntax is: + +`jfr scrub` \[--include-events <*filter*>\] + \[--exclude-events <*filter*>\] + \[--include-categories <*filter*>\] + \[--exclude-categories <*filter*>\] + \[--include-threads <*filter*>\] + \[--exclude-threads <*filter*>\] + <*input-file*> + \[<*output-file*>\] + +<a id="scrub-option-include-events">`--include-events` <*filter*></a> +: Select events matching an event name. + +<a id="scrub-option-exclude-events">`--exclude-events` <*filter*></a> +: Exclude events matching an event name. + +<a id="scrub-option-include-categories">`--include-categories` <*filter*></a> +: Select events matching a category name. + +<a id="scrub-option-exclude-categories">`--exclude-categories` <*filter*></a> +: Exclude events matching a category name. + +<a id="scrub-option-include-threads">`--include-threads` <*filter*></a> +: Select events matching a thread name. + +<a id="scrub-option-exclude-threads">`--exclude-threads` <*filter*></a> +: Exclude events matching a thread name. + +<a id="scrub-option-input-file"><*input-file*></a> +: The input file to read events from. + +<a id="scrub-option-output-file"><*output-file*></a> +: The output file to write filter events to. If no file is specified, +it will be written to the same path as the input file, but with +"-scrubbed" appended to the filename. + +The filter is a comma-separated list of names, simple and/or qualified, +and/or quoted glob patterns. If multiple filters are used, they +are applied in the specified order. + +#### `jfr assemble` subcommand + +Use jfr `assemble` to assemble chunk files into a recording file. + +The syntax is: + +`jfr assemble` <*repository*> + <*file*> + +where: + +<a id="assemble-option-repository"><*repository*></a> +: Directory where the repository containing chunk files is located. + +<a id="assemble-option-file"><*file*></a> +: Location of the flight recording file (`.jfr`). + +Flight recording information is written in chunks. A chunk contains all of the information +necessary for parsing. A chunk typically contains events useful for troubleshooting. +If a JVM should crash, these chunks can be recovered and used to create a flight +recording file using this `jfr assemble` command. These chunk files are concatenated in +chronological order and chunk files that are not finished (.part) are excluded. + +#### `jfr disassemble` subcommand + +Use `jfr disassemble` to decompose a flight recording file into its chunk file pieces. + +The syntax is: + +`jfr disassemble` \[`--max-chunks` <*chunks*>\] + \[`--output` <*directory*>\] + <*file*> + +where: + +<a id="disassemble-option-output">`--output` <*directory*></a> +: The location to write the disassembled file, +by default the current directory + +<a id="disassemble-option-max-chunks">`--max-chunks` <*chunks*></a> +: Maximum number of chunks per file, by default 5. +The chunk size varies, but is typically around 15 MB. + +<a id="disassemble-option-max-size">`--max-size` <*size*></a> +: Maximum number of bytes per file. + +<a id="disassemble-option-file"><*file*></a> +: Location of the flight recording file (`.jfr`) + +This function can be useful for repairing a broken file by removing the faulty chunk. +It can also be used to reduce the size of a file that is too large to transfer. +The resulting chunk files are named `myfile_1.jfr`, `myfile_2.jfr`, etc. If needed, the +resulting file names will be padded with zeros to preserve chronological order. For example, +the chunk file name is `myfile_001.jfr` if the recording consists of more than 100 chunks. + +#### jfr version and help subcommands + +Use `jfr --version` or `jfr version` to view the version string information for this jfr command. + +To get help on any of the jfr subcommands, use: + +`jfr <--help|help>` \[*subcommand*\] + +where: + +\[*subcommand*\] is any of: + +- `print` +- `view` +- `configure` +- `metadata` +- `summary` +- `scrub` +- `assemble` +- `disassemble` diff --git a/src/jdk.jlink/share/man/jlink.1 b/src/jdk.jlink/share/man/jlink.1 deleted file mode 100644 index 5cadc153a37..00000000000 --- a/src/jdk.jlink/share/man/jlink.1 +++ /dev/null @@ -1,409 +0,0 @@ -.\" Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved. -.\" DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -.\" -.\" This code is free software; you can redistribute it and/or modify it -.\" under the terms of the GNU General Public License version 2 only, as -.\" published by the Free Software Foundation. -.\" -.\" This code is distributed in the hope that it will be useful, but WITHOUT -.\" ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -.\" FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -.\" version 2 for more details (a copy is included in the LICENSE file that -.\" accompanied this code). -.\" -.\" You should have received a copy of the GNU General Public License version -.\" 2 along with this work; if not, write to the Free Software Foundation, -.\" Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -.\" -.\" Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -.\" or visit www.oracle.com if you need additional information or have any -.\" questions. -.\" -.\" Automatically generated by Pandoc 2.19.2 -.\" -.\" Define V font for inline verbatim, using C font in formats -.\" that render this, and otherwise B font. -.ie "\f[CB]x\f[R]"x" \{\ -. ftr V B -. ftr VI BI -. ftr VB B -. ftr VBI BI -.\} -.el \{\ -. ftr V CR -. ftr VI CI -. ftr VB CB -. ftr VBI CBI -.\} -.TH "JLINK" "1" "2025" "JDK 24-ea" "JDK Commands" -.hy -.SH NAME -.PP -jlink - assemble and optimize a set of modules and their dependencies -into a custom runtime image -.SH SYNOPSIS -.PP -\f[V]jlink\f[R] [\f[I]options\f[R]] \f[V]--module-path\f[R] -\f[I]modulepath\f[R] \f[V]--add-modules\f[R] -\f[I]module\f[R][,\f[I]module\f[R]...] -.TP -\f[I]options\f[R] -Command-line options separated by spaces. -See \f[B]jlink Options\f[R]. -.TP -\f[I]modulepath\f[R] -The path where the \f[V]jlink\f[R] tool discovers observable modules. -These modules can be modular JAR files, JMOD files, or exploded modules. -.TP -\f[I]module\f[R] -The names of the modules to add to the runtime image. -The \f[V]jlink\f[R] tool adds these modules and their transitive -dependencies. -.SH DESCRIPTION -.PP -The \f[V]jlink\f[R] tool links a set of modules, along with their -transitive dependences, to create a custom runtime image. -.PP -\f[B]Note:\f[R] -.PP -Developers are responsible for updating their custom runtime images. -.SH JLINK OPTIONS -.TP -\f[V]--add-modules\f[R] \f[I]mod\f[R][\f[V],\f[R]\f[I]mod\f[R]...] -Adds the named modules, \f[I]mod\f[R], to the default set of root -modules. -The default set of root modules is empty. -.TP -\f[V]--bind-services\f[R] -Link service provider modules and their dependencies. -.TP -\f[V]-c ={0|1|2}\f[R] or \f[V]--compress={0|1|2}\f[R] -Enable compression of resources: -.RS -.IP \[bu] 2 -\f[V]0\f[R]: No compression -.IP \[bu] 2 -\f[V]1\f[R]: Constant string sharing -.IP \[bu] 2 -\f[V]2\f[R]: ZIP -.RE -.TP -\f[V]--disable-plugin\f[R] \f[I]pluginname\f[R] -Disables the specified plug-in. -See \f[B]jlink Plug-ins\f[R] for the list of supported plug-ins. -.TP -\f[V]--endian\f[R] {\f[V]little\f[R]|\f[V]big\f[R]} -Specifies the byte order of the generated image. -The default value is the format of your system\[aq]s architecture. -.TP -\f[V]-h\f[R] or \f[V]--help\f[R] -Prints the help message. -.TP -\f[V]--ignore-signing-information\f[R] -Suppresses a fatal error when signed modular JARs are linked in the -runtime image. -The signature-related files of the signed modular JARs aren\[aq]t copied -to the runtime image. -.TP -\f[V]--launcher\f[R] \f[I]command\f[R]\f[V]=\f[R]\f[I]module\f[R] or \f[V]--launcher\f[R] \f[I]command\f[R]\f[V]=\f[R]\f[I]module\f[R]\f[V]/\f[R]\f[I]main\f[R] -Specifies the launcher command name for the module or the command name -for the module and main class (the module and the main class names are -separated by a slash (\f[V]/\f[R])). -.TP -\f[V]--limit-modules\f[R] \f[I]mod\f[R][\f[V],\f[R]\f[I]mod\f[R]...] -Limits the universe of observable modules to those in the transitive -closure of the named modules, \f[V]mod\f[R], plus the main module, if -any, plus any further modules specified in the \f[V]--add-modules\f[R] -option. -.TP -\f[V]--list-plugins\f[R] -Lists available plug-ins, which you can access through command-line -options; see \f[B]jlink Plug-ins\f[R]. -.TP -\f[V]-p\f[R] or \f[V]--module-path\f[R] \f[I]modulepath\f[R] -Specifies the module path. -.RS -.PP -If this option is not specified, then the default module path is -\f[V]$JAVA_HOME/jmods\f[R]. -This directory contains the \f[V]java.base\f[R] module and the other -standard and JDK modules. -If this option is specified but the \f[V]java.base\f[R] module cannot be -resolved from it, then the \f[V]jlink\f[R] command appends -\f[V]$JAVA_HOME/jmods\f[R] to the module path. -.RE -.TP -\f[V]--no-header-files\f[R] -Excludes header files. -.TP -\f[V]--no-man-pages\f[R] -Excludes man pages. -.TP -\f[V]--output\f[R] \f[I]path\f[R] -Specifies the location of the generated runtime image. -.TP -\f[V]--save-opts\f[R] \f[I]filename\f[R] -Saves \f[V]jlink\f[R] options in the specified file. -.TP -\f[V]--suggest-providers\f[R] [\f[I]name\f[R]\f[V],\f[R] ...] -Suggest providers that implement the given service types from the module -path. -.TP -\f[V]--version\f[R] -Prints version information. -.TP -\f[V]\[at]\f[R]\f[I]filename\f[R] -Reads options from the specified file. -.RS -.PP -An options file is a text file that contains the options and values that -you would typically enter in a command prompt. -Options may appear on one line or on several lines. -You may not specify environment variables for path names. -You may comment out lines by prefixing a hash symbol (\f[V]#\f[R]) to -the beginning of the line. -.PP -The following is an example of an options file for the \f[V]jlink\f[R] -command: -.IP -.nf -\f[CB] -#Wed Dec 07 00:40:19 EST 2016 ---module-path mlib ---add-modules com.greetings ---output greetingsapp -\f[R] -.fi -.RE -.SH JLINK PLUG-INS -.PP -\f[B]Note:\f[R] -.PP -Plug-ins not listed in this section aren\[aq]t supported and are subject -to change. -.PP -For plug-in options that require a \f[I]pattern-list\f[R], the value is -a comma-separated list of elements, with each element using one the -following forms: -.IP \[bu] 2 -\f[I]glob-pattern\f[R] -.IP \[bu] 2 -\f[V]glob:\f[R]\f[I]glob-pattern\f[R] -.IP \[bu] 2 -\f[V]regex:\f[R]\f[I]regex-pattern\f[R] -.IP \[bu] 2 -\f[V]\[at]\f[R]\f[I]filename\f[R] -.RS 2 -.IP \[bu] 2 -\f[I]filename\f[R] is the name of a file that contains patterns to be -used, one pattern per line. -.RE -.PP -For a complete list of all available plug-ins, run the command -\f[V]jlink --list-plugins\f[R]. -.SS Plugin \f[V]compress\f[R] -.TP -Options -\f[V]--compress=\f[R]{\f[V]0\f[R]|\f[V]1\f[R]|\f[V]2\f[R]}[\f[V]:filter=\f[R]\f[I]pattern-list\f[R]] -.TP -Description -Compresses all resources in the output image. -.RS -.IP \[bu] 2 -Level 0: No compression -.IP \[bu] 2 -Level 1: Constant string sharing -.IP \[bu] 2 -Level 2: ZIP -.PP -An optional \f[I]pattern-list\f[R] filter can be specified to list the -pattern of files to include. -.RE -.SS Plugin \f[V]include-locales\f[R] -.TP -Options -\f[V]--include-locales=\f[R]\f[I]langtag\f[R][\f[V],\f[R]\f[I]langtag\f[R]]* -.TP -Description -Includes the list of locales where \f[I]langtag\f[R] is a BCP 47 -language tag. -This option supports locale matching as defined in RFC 4647. -Ensure that you add the module jdk.localedata when using this option. -.RS -.PP -Example: -.RS -.PP -\f[V]--add-modules jdk.localedata --include-locales=en,ja,*-IN\f[R] -.RE -.RE -.SS Plugin \f[V]order-resources\f[R] -.TP -Options -\f[V]--order-resources=\f[R]\f[I]pattern-list\f[R] -.TP -Description -Orders the specified paths in priority order. -If \f[V]\[at]\f[R]\f[I]filename\f[R] is specified, then each line in -\f[I]pattern-list\f[R] must be an exact match for the paths to be -ordered. -.RS -.PP -Example: -.RS -.PP -\f[V]--order-resources=/module-info.class,\[at]classlist,/java.base/java/lang/\f[R] -.RE -.RE -.SS Plugin \f[V]strip-debug\f[R] -.TP -Options -\f[V]--strip-debug\f[R] -.TP -Description -Strips debug information from the output image. -.SS Plugin \f[V]generate-cds-archive\f[R] -.TP -Options -\f[V]--generate-cds-archive\f[R] -.TP -Description -Generate CDS archive if the runtime image supports the CDS feature. -.SH JLINK EXAMPLES -.PP -The following command creates a runtime image in the directory -\f[V]greetingsapp\f[R]. -This command links the module \f[V]com.greetings\f[R], whose module -definition is contained in the directory \f[V]mlib\f[R]. -.IP -.nf -\f[CB] -jlink --module-path mlib --add-modules com.greetings --output greetingsapp -\f[R] -.fi -.PP -The following command lists the modules in the runtime image -\f[V]greetingsapp\f[R]: -.IP -.nf -\f[CB] -greetingsapp/bin/java --list-modules -com.greetings -java.base\[at]11 -java.logging\[at]11 -org.astro\[at]1.0 -\f[R] -.fi -.PP -The following command creates a runtime image in the directory -compressedrt that\[aq]s stripped of debug symbols, uses compression to -reduce space, and includes French language locale information: -.IP -.nf -\f[CB] -jlink --add-modules jdk.localedata --strip-debug --compress=2 --include-locales=fr --output compressedrt -\f[R] -.fi -.PP -The following example compares the size of the runtime image -\f[V]compressedrt\f[R] with \f[V]fr_rt\f[R], which isn\[aq]t stripped of -debug symbols and doesn\[aq]t use compression: -.IP -.nf -\f[CB] -jlink --add-modules jdk.localedata --include-locales=fr --output fr_rt - -du -sh ./compressedrt ./fr_rt -23M ./compressedrt -36M ./fr_rt -\f[R] -.fi -.PP -The following example lists the providers that implement -\f[V]java.security.Provider\f[R]: -.IP -.nf -\f[CB] -jlink --suggest-providers java.security.Provider - -Suggested providers: - java.naming provides java.security.Provider used by java.base - java.security.jgss provides java.security.Provider used by java.base - java.security.sasl provides java.security.Provider used by java.base - java.smartcardio provides java.security.Provider used by java.base - java.xml.crypto provides java.security.Provider used by java.base - jdk.crypto.cryptoki provides java.security.Provider used by java.base - jdk.crypto.ec provides java.security.Provider used by java.base - jdk.crypto.mscapi provides java.security.Provider used by java.base - jdk.security.jgss provides java.security.Provider used by java.base -\f[R] -.fi -.PP -The following example creates a custom runtime image named -\f[V]mybuild\f[R] that includes only \f[V]java.naming\f[R] and -\f[V]jdk.crypto.cryptoki\f[R] and their dependencies but no other -providers. -Note that these dependencies must exist in the module path: -.IP -.nf -\f[CB] -jlink --add-modules java.naming,jdk.crypto.cryptoki --output mybuild -\f[R] -.fi -.PP -The following command is similar to the one that creates a runtime image -named \f[V]greetingsapp\f[R], except that it will link the modules -resolved from root modules with service binding; see the -\f[B]\f[VB]Configuration.resolveAndBind\f[B]\f[R] method. -.IP -.nf -\f[CB] -jlink --module-path mlib --add-modules com.greetings --output greetingsapp --bind-services -\f[R] -.fi -.PP -The following command lists the modules in the runtime image -greetingsapp created by this command: -.IP -.nf -\f[CB] -greetingsapp/bin/java --list-modules -com.greetings -java.base\[at]11 -java.compiler\[at]11 -java.datatransfer\[at]11 -java.desktop\[at]11 -java.logging\[at]11 -java.management\[at]11 -java.management.rmi\[at]11 -java.naming\[at]11 -java.prefs\[at]11 -java.rmi\[at]11 -java.security.jgss\[at]11 -java.security.sasl\[at]11 -java.smartcardio\[at]11 -java.xml\[at]11 -java.xml.crypto\[at]11 -jdk.accessibility\[at]11 -jdk.charsets\[at]11 -jdk.compiler\[at]11 -jdk.crypto.cryptoki\[at]11 -jdk.crypto.ec\[at]11 -jdk.crypto.mscapi\[at]11 -jdk.internal.opt\[at]11 -jdk.jartool\[at]11 -jdk.javadoc\[at]11 -jdk.jdeps\[at]11 -jdk.jfr\[at]11 -jdk.jlink\[at]11 -jdk.localedata\[at]11 -jdk.management\[at]11 -jdk.management.jfr\[at]11 -jdk.naming.dns\[at]11 -jdk.naming.rmi\[at]11 -jdk.security.auth\[at]11 -jdk.security.jgss\[at]11 -jdk.zipfs\[at]11 -org.astro\[at]1.0 -\f[R] -.fi diff --git a/src/jdk.jlink/share/man/jlink.md b/src/jdk.jlink/share/man/jlink.md new file mode 100644 index 00000000000..8c344a692cb --- /dev/null +++ b/src/jdk.jlink/share/man/jlink.md @@ -0,0 +1,347 @@ +--- +# Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# This code is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 only, as +# published by the Free Software Foundation. +# +# This code is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# version 2 for more details (a copy is included in the LICENSE file that +# accompanied this code). +# +# You should have received a copy of the GNU General Public License version +# 2 along with this work; if not, write to the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +# or visit www.oracle.com if you need additional information or have any +# questions. +# + +title: 'JLINK(1) JDK @@VERSION_SHORT@@ | JDK Commands' +date: @@COPYRIGHT_YEAR@@ +lang: en +--- + +## Name + +jlink - assemble and optimize a set of modules and their dependencies into a +custom runtime image + +## Synopsis + +`jlink` \[*options*\] `--module-path` *modulepath* `--add-modules` *module*\[,*module*...\] + +*options* +: Command-line options separated by spaces. See [jlink Options]. + +*modulepath* +: The path where the `jlink` tool discovers observable modules. These modules + can be modular JAR files, JMOD files, or exploded modules. + +*module* +: The names of the modules to add to the runtime image. The `jlink` tool adds + these modules and their transitive dependencies. + +## Description + +The `jlink` tool links a set of modules, along with their transitive +dependences, to create a custom runtime image. + +**Note:** + +Developers are responsible for updating their custom runtime images. + +## jlink Options + +`--add-modules` *mod*\[`,`*mod*...\] +: Adds the named modules, *mod*, to the default set of root modules. The + default set of root modules is empty. + +`--bind-services` +: Link service provider modules and their dependencies. + +`-c ={0|1|2}` or `--compress={0|1|2}` +: Enable compression of resources: + + - `0`: No compression + - `1`: Constant string sharing + - `2`: ZIP + +`--disable-plugin` *pluginname* +: Disables the specified plug-in. See [jlink Plug-ins] for the list of + supported plug-ins. + +`--endian` {`little`\|`big`} +: Specifies the byte order of the generated image. The default value is the + format of your system's architecture. + +`-h` or `--help` +: Prints the help message. + +`--ignore-signing-information` +: Suppresses a fatal error when signed modular JARs are linked in the runtime + image. The signature-related files of the signed modular JARs aren't copied + to the runtime image. + +`--launcher` *command*`=`*module* or `--launcher` *command*`=`*module*`/`*main* +: Specifies the launcher command name for the module or the command name for + the module and main class (the module and the main class names are + separated by a slash (`/`)). + +`--limit-modules` *mod*\[`,`*mod*...\] +: Limits the universe of observable modules to those in the transitive + closure of the named modules, `mod`, plus the main module, if any, plus any + further modules specified in the `--add-modules` option. + +`--list-plugins` +: Lists available plug-ins, which you can access through command-line + options; see [jlink Plug-ins]. + +`-p` or `--module-path` *modulepath* +: Specifies the module path. + + If this option is not specified, then the default module path is + `$JAVA_HOME/jmods`. This directory contains the `java.base` module and the + other standard and JDK modules. If this option is specified but the + `java.base` module cannot be resolved from it, then the `jlink` command + appends `$JAVA_HOME/jmods` to the module path. + +`--no-header-files` +: Excludes header files. + +`--no-man-pages` +: Excludes man pages. + +`--output` *path* +: Specifies the location of the generated runtime image. + +`--save-opts` *filename* +: Saves `jlink` options in the specified file. + +`--suggest-providers` \[*name*`,` ...\] +: Suggest providers that implement the given service types from the module + path. + +`--version` +: Prints version information. + +`@`*filename* +: Reads options from the specified file. + + An options file is a text file that contains the options and values that + you would typically enter in a command prompt. Options may appear on one + line or on several lines. You may not specify environment variables for + path names. You may comment out lines by prefixing a hash symbol (`#`) to + the beginning of the line. + + The following is an example of an options file for the `jlink` command: + + ``` + #Wed Dec 07 00:40:19 EST 2016 + --module-path mlib + --add-modules com.greetings + --output greetingsapp + ``` + +## jlink Plug-ins + +**Note:** + +Plug-ins not listed in this section aren't supported and are subject to change. + +For plug-in options that require a *pattern-list*, the value is a +comma-separated list of elements, with each element using one the following +forms: + +- *glob-pattern* +- `glob:`*glob-pattern* +- `regex:`*regex-pattern* +- `@`*filename* + - *filename* is the name of a file that contains patterns to be used, one + pattern per line. + +For a complete list of all available plug-ins, run the command +`jlink --list-plugins`. + +### Plugin `compress` + +Options +: `--compress=`{`0`\|`1`\|`2`}\[`:filter=`*pattern-list*\] + +Description +: Compresses all resources in the output image. + + - Level 0: No compression + - Level 1: Constant string sharing + - Level 2: ZIP + + An optional *pattern-list* filter can be specified to list the pattern of + files to include. + +### Plugin `include-locales` + +Options +: `--include-locales=`*langtag*\[`,`*langtag*\]\* + +Description +: Includes the list of locales where *langtag* is a BCP 47 language tag. + This option supports locale matching as defined in RFC 4647. Ensure that + you add the module jdk.localedata when using this option. + + Example: + + > `--add-modules jdk.localedata --include-locales=en,ja,*-IN` + +### Plugin `order-resources` + +Options +: `--order-resources=`*pattern-list* + +Description +: Orders the specified paths in priority order. If `@`*filename* is + specified, then each line in *pattern-list* must be an exact match for the + paths to be ordered. + + Example: + + > `--order-resources=/module-info.class,@classlist,/java.base/java/lang/` + +### Plugin `strip-debug` + +Options +: `--strip-debug` + +Description +: Strips debug information from the output image. + +### Plugin `generate-cds-archive` + +Options +: `--generate-cds-archive` + +Description +: Generate CDS archive if the runtime image supports the CDS feature. + +## jlink Examples + +The following command creates a runtime image in the directory `greetingsapp`. +This command links the module `com.greetings`, whose module definition is +contained in the directory `mlib`. + +``` +jlink --module-path mlib --add-modules com.greetings --output greetingsapp +``` + +The following command lists the modules in the runtime image `greetingsapp`: + +``` +greetingsapp/bin/java --list-modules +com.greetings +java.base@11 +java.logging@11 +org.astro@1.0 +``` + +The following command creates a runtime image in the directory compressedrt +that's stripped of debug symbols, uses compression to reduce space, and +includes French language locale information: + +``` +jlink --add-modules jdk.localedata --strip-debug --compress=2 --include-locales=fr --output compressedrt +``` + +The following example compares the size of the runtime image `compressedrt` +with `fr_rt`, which isn't stripped of debug symbols and doesn't use +compression: + +``` +jlink --add-modules jdk.localedata --include-locales=fr --output fr_rt + +du -sh ./compressedrt ./fr_rt +23M ./compressedrt +36M ./fr_rt +``` + +The following example lists the providers that implement +`java.security.Provider`: + +``` +jlink --suggest-providers java.security.Provider + +Suggested providers: + java.naming provides java.security.Provider used by java.base + java.security.jgss provides java.security.Provider used by java.base + java.security.sasl provides java.security.Provider used by java.base + java.smartcardio provides java.security.Provider used by java.base + java.xml.crypto provides java.security.Provider used by java.base + jdk.crypto.cryptoki provides java.security.Provider used by java.base + jdk.crypto.ec provides java.security.Provider used by java.base + jdk.crypto.mscapi provides java.security.Provider used by java.base + jdk.security.jgss provides java.security.Provider used by java.base +``` + +The following example creates a custom runtime image named `mybuild` that +includes only `java.naming` and `jdk.crypto.cryptoki` and their dependencies but no +other providers. Note that these dependencies must exist in the module path: + +``` +jlink --add-modules java.naming,jdk.crypto.cryptoki --output mybuild +``` + +The following command is similar to the one that creates a runtime image named +`greetingsapp`, except that it will link the modules resolved from root modules +with service binding; see the [`Configuration.resolveAndBind`]( +../../api/java.base/java/lang/module/Configuration.html#resolveAndBind(java.lang.module.ModuleFinder,java.util.List,java.lang.module.ModuleFinder,java.util.Collection)) +method. + +``` +jlink --module-path mlib --add-modules com.greetings --output greetingsapp --bind-services +``` + +The following command lists the modules in the runtime image greetingsapp +created by this command: + +``` +greetingsapp/bin/java --list-modules +com.greetings +java.base@11 +java.compiler@11 +java.datatransfer@11 +java.desktop@11 +java.logging@11 +java.management@11 +java.management.rmi@11 +java.naming@11 +java.prefs@11 +java.rmi@11 +java.security.jgss@11 +java.security.sasl@11 +java.smartcardio@11 +java.xml@11 +java.xml.crypto@11 +jdk.accessibility@11 +jdk.charsets@11 +jdk.compiler@11 +jdk.crypto.cryptoki@11 +jdk.crypto.ec@11 +jdk.crypto.mscapi@11 +jdk.internal.opt@11 +jdk.jartool@11 +jdk.javadoc@11 +jdk.jdeps@11 +jdk.jfr@11 +jdk.jlink@11 +jdk.localedata@11 +jdk.management@11 +jdk.management.jfr@11 +jdk.naming.dns@11 +jdk.naming.rmi@11 +jdk.security.auth@11 +jdk.security.jgss@11 +jdk.zipfs@11 +org.astro@1.0 +``` diff --git a/src/jdk.jlink/share/man/jmod.1 b/src/jdk.jlink/share/man/jmod.1 deleted file mode 100644 index 4475505e524..00000000000 --- a/src/jdk.jlink/share/man/jmod.1 +++ /dev/null @@ -1,423 +0,0 @@ -.\" Copyright (c) 2017, 2023, Oracle and/or its affiliates. All rights reserved. -.\" DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -.\" -.\" This code is free software; you can redistribute it and/or modify it -.\" under the terms of the GNU General Public License version 2 only, as -.\" published by the Free Software Foundation. -.\" -.\" This code is distributed in the hope that it will be useful, but WITHOUT -.\" ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -.\" FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -.\" version 2 for more details (a copy is included in the LICENSE file that -.\" accompanied this code). -.\" -.\" You should have received a copy of the GNU General Public License version -.\" 2 along with this work; if not, write to the Free Software Foundation, -.\" Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -.\" -.\" Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -.\" or visit www.oracle.com if you need additional information or have any -.\" questions. -.\" -.\" Automatically generated by Pandoc 2.19.2 -.\" -.\" Define V font for inline verbatim, using C font in formats -.\" that render this, and otherwise B font. -.ie "\f[CB]x\f[R]"x" \{\ -. ftr V B -. ftr VI BI -. ftr VB B -. ftr VBI BI -.\} -.el \{\ -. ftr V CR -. ftr VI CI -. ftr VB CB -. ftr VBI CBI -.\} -.TH "JMOD" "1" "2025" "JDK 24-ea" "JDK Commands" -.hy -.SH NAME -.PP -jmod - create JMOD files and list the content of existing JMOD files -.SH SYNOPSIS -.PP -\f[V]jmod\f[R] -(\f[V]create\f[R]|\f[V]extract\f[R]|\f[V]list\f[R]|\f[V]describe\f[R]|\f[V]hash\f[R]) -[\f[I]options\f[R]] \f[I]jmod-file\f[R] -.PP -Includes the following: -.PP -\f[B]Main operation modes\f[R] -.TP -\f[V]create\f[R] -Creates a new JMOD archive file. -.TP -\f[V]extract\f[R] -Extracts all the files from the JMOD archive file. -.TP -\f[V]list\f[R] -Prints the names of all the entries. -.TP -\f[V]describe\f[R] -Prints the module details. -.TP -\f[V]hash\f[R] -Determines leaf modules and records the hashes of the dependencies that -directly and indirectly require them. -.PP -\f[B]Options\f[R] -.TP -\f[I]options\f[R] -See \f[B]Options for jmod\f[R]. -.PP -\f[B]Required\f[R] -.TP -\f[I]jmod-file\f[R] -Specifies the name of the JMOD file to create or from which to retrieve -information. -.SH DESCRIPTION -.PP -\f[B]Note:\f[R] For most development tasks, including deploying modules -on the module path or publishing them to a Maven repository, continue to -package modules in modular JAR files. -The \f[V]jmod\f[R] tool is intended for modules that have native -libraries or other configuration files or for modules that you intend to -link, with the \f[B]jlink\f[R] tool, to a runtime image. -.PP -The JMOD file format lets you aggregate files other than -\f[V].class\f[R] files, metadata, and resources. -This format is transportable but not executable, which means that you -can use it during compile time or link time but not at run time. -.PP -Many \f[V]jmod\f[R] options involve specifying a path whose contents are -copied into the resulting JMOD files. -These options copy all the contents of the specified path, including -subdirectories and their contents, but exclude files whose names match -the pattern specified by the \f[V]--exclude\f[R] option. -.PP -With the \f[V]--hash-modules\f[R] option or the \f[V]jmod hash\f[R] -command, you can, in each module\[aq]s descriptor, record hashes of the -content of the modules that are allowed to depend upon it, thus -\[dq]tying\[dq] together these modules. -This enables a package to be exported to one or more specifically-named -modules and to no others through qualified exports. -The runtime verifies if the recorded hash of a module matches the one -resolved at run time; if not, the runtime returns an error. -.SH OPTIONS FOR JMOD -.TP -\f[V]--class-path\f[R] \f[I]path\f[R] -Specifies the location of application JAR files or a directory -containing classes to copy into the resulting JMOD file. -.TP -\f[V]--cmds\f[R] \f[I]path\f[R] -Specifies the location of native commands to copy into the resulting -JMOD file. -.TP -\f[V]--compress\f[R] \f[I]compress\f[R] -Specifies the compression to use in creating the JMOD file. -The accepted values are \f[V]zip-[0-9]\f[R], where \f[V]zip-0\f[R] -provides no compression, and \f[V]zip-9\f[R] provides the best -compression. -Default is \f[V]zip-6\f[R]. -.TP -\f[V]--config\f[R] \f[I]path\f[R] -Specifies the location of user-editable configuration files to copy into -the resulting JMOD file. -.TP -\f[V]--date\f[R]\f[I]TIMESTAMP\f[R] -The timestamp in ISO-8601 extended offset date-time with optional -time-zone format, to use for the timestamp of the entries, e.g. -\[dq]2022-02-12T12:30:00-05:00\[dq]. -.TP -\f[V]--dir\f[R] \f[I]path\f[R] -Specifies the location where \f[V]jmod\f[R] puts extracted files from -the specified JMOD archive. -.TP -\f[V]--dry-run\f[R] -Performs a dry run of hash mode. -It identifies leaf modules and their required modules without recording -any hash values. -.TP -\f[V]--exclude\f[R] \f[I]pattern-list\f[R] -Excludes files matching the supplied comma-separated pattern list, each -element using one the following forms: -.RS -.IP \[bu] 2 -\f[I]glob-pattern\f[R] -.IP \[bu] 2 -\f[V]glob:\f[R]\f[I]glob-pattern\f[R] -.IP \[bu] 2 -\f[V]regex:\f[R]\f[I]regex-pattern\f[R] -.PP -See the \f[B]\f[VB]FileSystem.getPathMatcher\f[B]\f[R] method for the -syntax of \f[I]glob-pattern\f[R]. -See the \f[B]\f[VB]Pattern\f[B]\f[R] class for the syntax of -\f[I]regex-pattern\f[R], which represents a regular expression. -.RE -.TP -\f[V]--hash-modules\f[R] \f[I]regex-pattern\f[R] -Determines the leaf modules and records the hashes of the dependencies -directly and indirectly requiring them, based on the module graph of the -modules matching the given \f[I]regex-pattern\f[R]. -The hashes are recorded in the JMOD archive file being created, or a -JMOD archive or modular JAR on the module path specified by the -\f[V]jmod hash\f[R] command. -.TP -\f[V]--header-files\f[R] \f[I]path\f[R] -Specifies the location of header files to copy into the resulting JMOD -file. -.TP -\f[V]--help\f[R] or \f[V]-h\f[R] -Prints a usage message. -.TP -\f[V]--help-extra\f[R] -Prints help for extra options. -.TP -\f[V]--legal-notices\f[R] \f[I]path\f[R] -Specifies the location of legal notices to copy into the resulting JMOD -file. -.TP -\f[V]--libs\f[R] \f[I]path\f[R] -Specifies location of native libraries to copy into the resulting JMOD -file. -.TP -\f[V]--main-class\f[R] \f[I]class-name\f[R] -Specifies main class to record in the module-info.class file. -.TP -\f[V]--man-pages\f[R] \f[I]path\f[R] -Specifies the location of man pages to copy into the resulting JMOD -file. -.TP -\f[V]--module-version\f[R] \f[I]module-version\f[R] -Specifies the module version to record in the module-info.class file. -.TP -\f[V]--module-path\f[R] \f[I]path\f[R] or \f[V]-p\f[R] \f[I]path\f[R] -Specifies the module path. -This option is required if you also specify \f[V]--hash-modules\f[R]. -.TP -\f[V]--target-platform\f[R] \f[I]platform\f[R] -Specifies the target platform. -.TP -\f[V]--version\f[R] -Prints version information of the \f[V]jmod\f[R] tool. -.TP -\f[V]\[at]\f[R]\f[I]filename\f[R] -Reads options from the specified file. -.RS -.PP -An options file is a text file that contains the options and values that -you would ordinarily enter in a command prompt. -Options may appear on one line or on several lines. -You may not specify environment variables for path names. -You may comment out lines by prefixinga hash symbol (\f[V]#\f[R]) to the -beginning of the line. -.PP -The following is an example of an options file for the \f[V]jmod\f[R] -command: -.IP -.nf -\f[CB] -#Wed Dec 07 00:40:19 EST 2016 -create --class-path mods/com.greetings --module-path mlib - --cmds commands --config configfiles --header-files src/h - --libs lib --main-class com.greetings.Main - --man-pages man --module-version 1.0 - --os-arch \[dq]x86_x64\[dq] --os-name \[dq]macOS\[dq] - --os-version \[dq]10.10.5\[dq] greetingsmod -\f[R] -.fi -.RE -.SH EXTRA OPTIONS FOR JMOD -.PP -In addition to the options described in \f[B]Options for jmod\f[R], the -following are extra options that can be used with the command. -.TP -\f[V]--do-not-resolve-by-default\f[R] -Exclude from the default root set of modules -.TP -\f[V]--warn-if-resolved\f[R] -Hint for a tool to issue a warning if the module is resolved. -One of deprecated, deprecated-for-removal, or incubating. -.SH JMOD CREATE EXAMPLE -.PP -The following is an example of creating a JMOD file: -.IP -.nf -\f[CB] -jmod create --class-path mods/com.greetings --cmds commands - --config configfiles --header-files src/h --libs lib - --main-class com.greetings.Main --man-pages man --module-version 1.0 - --os-arch \[dq]x86_x64\[dq] --os-name \[dq]macOS\[dq] - --os-version \[dq]10.10.5\[dq] greetingsmod -\f[R] -.fi -.PP -Create a JMOD file specifying the date for the entries as -\f[V]2022 March 15 00:00:00\f[R]: -.IP -.nf -\f[CB] -jmod create --class-path build/foo/classes --date 2022-03-15T00:00:00Z - jmods/foo1.jmod -\f[R] -.fi -.SH JMOD HASH EXAMPLE -.PP -The following example demonstrates what happens when you try to link a -leaf module (in this example, \f[V]ma\f[R]) with a required module -(\f[V]mb\f[R]), and the hash value recorded in the required module -doesn\[aq]t match that of the leaf module. -.IP "1." 3 -Create and compile the following \f[V].java\f[R] files: -.RS 4 -.IP \[bu] 2 -\f[V]jmodhashex/src/ma/module-info.java\f[R] -.RS 2 -.IP -.nf -\f[CB] -module ma { - requires mb; -} -\f[R] -.fi -.RE -.IP \[bu] 2 -\f[V]jmodhashex/src/mb/module-info.java\f[R] -.RS 2 -.IP -.nf -\f[CB] -module mb { -} -\f[R] -.fi -.RE -.IP \[bu] 2 -\f[V]jmodhashex2/src/ma/module-info.java\f[R] -.RS 2 -.IP -.nf -\f[CB] -module ma { - requires mb; -} -\f[R] -.fi -.RE -.IP \[bu] 2 -\f[V]jmodhashex2/src/mb/module-info.java\f[R] -.RS 2 -.IP -.nf -\f[CB] -module mb { -} -\f[R] -.fi -.RE -.RE -.IP "2." 3 -Create a JMOD archive for each module. -Create the directories \f[V]jmodhashex/jmods\f[R] and -\f[V]jmodhashex2/jmods\f[R], and then run the following commands from -the \f[V]jmodhashex\f[R] directory, then from the \f[V]jmodhashex2\f[R] -directory: -.RS 4 -.IP \[bu] 2 -\f[V]jmod create --class-path mods/ma jmods/ma.jmod\f[R] -.IP \[bu] 2 -\f[V]jmod create --class-path mods/mb jmods/mb.jmod\f[R] -.RE -.IP "3." 3 -Optionally preview the \f[V]jmod hash\f[R] command. -Run the following command from the \f[V]jmodhashex\f[R] directory: -.RS 4 -.PP -\f[V]jmod hash --dry-run -module-path jmods --hash-modules .*\f[R] -.PP -The command prints the following: -.IP -.nf -\f[CB] -Dry run: -mb - hashes ma SHA-256 07667d5032004b37b42ec2bb81b46df380cf29e66962a16481ace2e71e74073a -\f[R] -.fi -.PP -This indicates that the \f[V]jmod hash\f[R] command (without the -\f[V]--dry-run\f[R] option) will record the hash value of the leaf -module \f[V]ma\f[R] in the module \f[V]mb\f[R]. -.RE -.IP "4." 3 -Record hash values in the JMOD archive files contained in the -\f[V]jmodhashex\f[R] directory. -Run the following command from the \f[V]jmodhashex\f[R] directory: -.RS 4 -.RS -.PP -\f[V]jmod hash --module-path jmods --hash-modules .*\f[R] -.RE -.PP -The command prints the following: -.RS -.PP -\f[V]Hashes are recorded in module mb\f[R] -.RE -.RE -.IP "5." 3 -Print information about each JMOD archive contained in the -\f[V]jmodhashex\f[R] directory. -Run the highlighted commands from the \f[V]jmodhashex\f[R] directory: -.RS 4 -.IP -.nf -\f[CB] -jmod describe jmods/ma.jmod - -ma - requires mandated java.base - requires mb - -jmod describe jmods/mb.jmod - -mb - requires mandated java.base - hashes ma SHA-256 07667d5032004b37b42ec2bb81b46df380cf29e66962a16481ace2e71e74073a -\f[R] -.fi -.RE -.IP "6." 3 -Attempt to create a runtime image that contains the module \f[V]ma\f[R] -from the directory \f[V]jmodhashex2\f[R] but the module \f[V]mb\f[R] -from the directory \f[V]jmodhashex\f[R]. -Run the following command from the \f[V]jmodhashex2\f[R] directory: -.RS 4 -.IP \[bu] 2 -\f[B]Linux and macOS:\f[R] -.RS 2 -.RS -.PP -\f[V]jlink --module-path $JAVA_HOME/jmods:jmods/ma.jmod:../jmodhashex/jmods/mb.jmod --add-modules ma --output ma-app\f[R] -.RE -.RE -.IP \[bu] 2 -\f[B]Windows:\f[R] -.RS 2 -.RS -.PP -\f[V]jlink --module-path %JAVA_HOME%/jmods;jmods/ma.jmod;../jmodhashex/jmods/mb.jmod --add-modules ma --output ma-app\f[R] -.RE -.RE -.PP -The command prints an error message similar to the following: -.IP -.nf -\f[CB] -Error: Hash of ma (a2d77889b0cb067df02a3abc39b01ac1151966157a68dc4241562c60499150d2) differs to -expected hash (07667d5032004b37b42ec2bb81b46df380cf29e66962a16481ace2e71e74073a) recorded in mb -\f[R] -.fi -.RE diff --git a/src/jdk.jlink/share/man/jmod.md b/src/jdk.jlink/share/man/jmod.md new file mode 100644 index 00000000000..273001b6a9a --- /dev/null +++ b/src/jdk.jlink/share/man/jmod.md @@ -0,0 +1,348 @@ +--- +# Copyright (c) 2017, 2023, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# This code is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 only, as +# published by the Free Software Foundation. +# +# This code is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# version 2 for more details (a copy is included in the LICENSE file that +# accompanied this code). +# +# You should have received a copy of the GNU General Public License version +# 2 along with this work; if not, write to the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +# or visit www.oracle.com if you need additional information or have any +# questions. +# + +title: 'JMOD(1) JDK @@VERSION_SHORT@@ | JDK Commands' +date: @@COPYRIGHT_YEAR@@ +lang: en +--- + +## Name + +jmod - create JMOD files and list the content of existing JMOD files + +## Synopsis + +`jmod` (`create`\|`extract`\|`list`\|`describe`\|`hash`) \[*options*\] +*jmod-file* + +Includes the following: + +**Main operation modes** + +`create` +: Creates a new JMOD archive file. + +`extract` +: Extracts all the files from the JMOD archive file. + +`list` +: Prints the names of all the entries. + +`describe` +: Prints the module details. + +`hash` +: Determines leaf modules and records the hashes of the dependencies that + directly and indirectly require them. + +**Options** + +*options* +: See [Options for jmod]. + +**Required** + +*jmod-file* +: Specifies the name of the JMOD file to create or from which to retrieve + information. + +## Description + +**Note:** For most development tasks, including deploying modules on the module +path or publishing them to a Maven repository, continue to package modules in +modular JAR files. The `jmod` tool is intended for modules that have native +libraries or other configuration files or for modules that you intend to link, +with the [jlink](jlink.html) tool, to a runtime image. + +The JMOD file format lets you aggregate files other than `.class` files, +metadata, and resources. This format is transportable but not executable, which +means that you can use it during compile time or link time but not at run time. + +Many `jmod` options involve specifying a path whose contents are copied into +the resulting JMOD files. These options copy all the contents of the specified +path, including subdirectories and their contents, but exclude files whose +names match the pattern specified by the `--exclude` option. + +With the `--hash-modules` option or the `jmod hash` command, you can, in each +module's descriptor, record hashes of the content of the modules that are +allowed to depend upon it, thus "tying" together these modules. This enables a +package to be exported to one or more specifically-named modules and to no +others through qualified exports. The runtime verifies if the recorded hash of +a module matches the one resolved at run time; if not, the runtime returns an +error. + +## Options for jmod + +`--class-path` *path* +: Specifies the location of application JAR files or a directory containing + classes to copy into the resulting JMOD file. + +`--cmds` *path* +: Specifies the location of native commands to copy into the resulting JMOD + file. + +`--compress` *compress* +: Specifies the compression to use in creating the JMOD file. + The accepted values are `zip-[0-9]`, where `zip-0` provides no + compression, and `zip-9` provides the best compression. Default is `zip-6`. + +`--config` *path* +: Specifies the location of user-editable configuration files to copy into + the resulting JMOD file. + +`--date `*TIMESTAMP* +: The timestamp in ISO-8601 extended offset date-time with optional time-zone +format, to use for the timestamp of the entries, +e.g. "2022-02-12T12:30:00-05:00". + +`--dir` *path* +: Specifies the location where `jmod` puts extracted files from the specified + JMOD archive. + +`--dry-run` +: Performs a dry run of hash mode. It identifies leaf modules and their + required modules without recording any hash values. + +`--exclude` *pattern-list* +: Excludes files matching the supplied comma-separated pattern list, each + element using one the following forms: + + - *glob-pattern* + + - `glob:`*glob-pattern* + + - `regex:`*regex-pattern* + + See the [`FileSystem.getPathMatcher`]( + ../../api/java.base/java/nio/file/FileSystem.html#getPathMatcher(java.lang.String)) + method for the syntax of *glob-pattern*. See the [`Pattern`]( + ../../api/java.base/java/util/regex/Pattern.html) + class for the syntax of *regex-pattern*, which represents a regular + expression. + +`--hash-modules` *regex-pattern* +: Determines the leaf modules and records the hashes of the dependencies + directly and indirectly requiring them, based on the module graph of the + modules matching the given *regex-pattern*. The hashes are recorded in the + JMOD archive file being created, or a JMOD archive or modular JAR on the + module path specified by the `jmod hash` command. + +`--header-files` *path* +: Specifies the location of header files to copy into the resulting JMOD + file. + +`--help` or `-h` +: Prints a usage message. + +`--help-extra` +: Prints help for extra options. + +`--legal-notices` *path* +: Specifies the location of legal notices to copy into the resulting JMOD + file. + +`--libs` *path* +: Specifies location of native libraries to copy into the resulting JMOD + file. + +`--main-class` *class-name* +: Specifies main class to record in the module-info.class file. + +`--man-pages` *path* +: Specifies the location of man pages to copy into the resulting JMOD file. + +`--module-version` *module-version* +: Specifies the module version to record in the module-info.class file. + +`--module-path` *path* or `-p` *path* +: Specifies the module path. This option is required if you also specify + `--hash-modules`. + +`--target-platform` *platform* +: Specifies the target platform. + +`--version` +: Prints version information of the `jmod` tool. + +`@`*filename* +: Reads options from the specified file. + + An options file is a text file that contains the options and values that + you would ordinarily enter in a command prompt. Options may appear on one + line or on several lines. You may not specify environment variables for + path names. You may comment out lines by prefixinga hash symbol (`#`) to + the beginning of the line. + + The following is an example of an options file for the `jmod` command: + + ``` + #Wed Dec 07 00:40:19 EST 2016 + create --class-path mods/com.greetings --module-path mlib + --cmds commands --config configfiles --header-files src/h + --libs lib --main-class com.greetings.Main + --man-pages man --module-version 1.0 + --os-arch "x86_x64" --os-name "macOS" + --os-version "10.10.5" greetingsmod + ``` + +## Extra Options for jmod + +In addition to the options described in [Options for jmod], the following are +extra options that can be used with the command. + +`--do-not-resolve-by-default` +: Exclude from the default root set of modules + +`--warn-if-resolved` +: Hint for a tool to issue a warning if the module is resolved. One of + deprecated, deprecated-for-removal, or incubating. + +## jmod Create Example + +The following is an example of creating a JMOD file: + +``` +jmod create --class-path mods/com.greetings --cmds commands + --config configfiles --header-files src/h --libs lib + --main-class com.greetings.Main --man-pages man --module-version 1.0 + --os-arch "x86_x64" --os-name "macOS" + --os-version "10.10.5" greetingsmod +``` +Create a JMOD file specifying the date for the entries as `2022 March 15 00:00:00`: + +``` +jmod create --class-path build/foo/classes --date 2022-03-15T00:00:00Z + jmods/foo1.jmod +``` +## jmod Hash Example + +The following example demonstrates what happens when you try to link a leaf +module (in this example, `ma`) with a required module (`mb`), and the hash +value recorded in the required module doesn't match that of the leaf module. + +1. Create and compile the following `.java` files: + + - `jmodhashex/src/ma/module-info.java` + + ``` + module ma { + requires mb; + } + ``` + + - `jmodhashex/src/mb/module-info.java` + + ``` + module mb { + } + ``` + + - `jmodhashex2/src/ma/module-info.java` + + ``` + module ma { + requires mb; + } + ``` + + - `jmodhashex2/src/mb/module-info.java` + + ``` + module mb { + } + ``` + +2. Create a JMOD archive for each module. Create the directories + `jmodhashex/jmods` and `jmodhashex2/jmods`, and then run the following + commands from the `jmodhashex` directory, then from the `jmodhashex2` + directory: + + - `jmod create --class-path mods/ma jmods/ma.jmod` + + - `jmod create --class-path mods/mb jmods/mb.jmod` + +3. Optionally preview the `jmod hash` command. Run the following command from + the `jmodhashex` directory: + + `jmod hash --dry-run -module-path jmods --hash-modules .*` + + The command prints the following: + + ``` + Dry run: + mb + hashes ma SHA-256 07667d5032004b37b42ec2bb81b46df380cf29e66962a16481ace2e71e74073a + ``` + + This indicates that the `jmod hash` command (without the `--dry-run` + option) will record the hash value of the leaf module `ma` in the module + `mb`. + +4. Record hash values in the JMOD archive files contained in the `jmodhashex` + directory. Run the following command from the `jmodhashex` directory: + + > `jmod hash --module-path jmods --hash-modules .*` + + The command prints the following: + + > `Hashes are recorded in module mb` + +5. Print information about each JMOD archive contained in the `jmodhashex` + directory. Run the highlighted commands from the `jmodhashex` directory: + + ``` + jmod describe jmods/ma.jmod + + ma + requires mandated java.base + requires mb + + jmod describe jmods/mb.jmod + + mb + requires mandated java.base + hashes ma SHA-256 07667d5032004b37b42ec2bb81b46df380cf29e66962a16481ace2e71e74073a + ``` + +6. Attempt to create a runtime image that contains the module `ma` from the + directory `jmodhashex2` but the module `mb` from the directory + `jmodhashex`. Run the following command from the `jmodhashex2` directory: + + - **Linux and macOS:** + + > `jlink --module-path + $JAVA_HOME/jmods:jmods/ma.jmod:../jmodhashex/jmods/mb.jmod + --add-modules ma --output ma-app` + + - **Windows:** + + > `jlink --module-path + %JAVA_HOME%/jmods;jmods/ma.jmod;../jmodhashex/jmods/mb.jmod + --add-modules ma --output ma-app` + + The command prints an error message similar to the following: + + ``` + Error: Hash of ma (a2d77889b0cb067df02a3abc39b01ac1151966157a68dc4241562c60499150d2) differs to + expected hash (07667d5032004b37b42ec2bb81b46df380cf29e66962a16481ace2e71e74073a) recorded in mb + ``` diff --git a/src/jdk.jpackage/share/man/jpackage.1 b/src/jdk.jpackage/share/man/jpackage.1 deleted file mode 100644 index 09d340ec033..00000000000 --- a/src/jdk.jpackage/share/man/jpackage.1 +++ /dev/null @@ -1,834 +0,0 @@ -.\" Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. -.\" DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -.\" -.\" This code is free software; you can redistribute it and/or modify it -.\" under the terms of the GNU General Public License version 2 only, as -.\" published by the Free Software Foundation. -.\" -.\" This code is distributed in the hope that it will be useful, but WITHOUT -.\" ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -.\" FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -.\" version 2 for more details (a copy is included in the LICENSE file that -.\" accompanied this code). -.\" -.\" You should have received a copy of the GNU General Public License version -.\" 2 along with this work; if not, write to the Free Software Foundation, -.\" Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -.\" -.\" Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -.\" or visit www.oracle.com if you need additional information or have any -.\" questions. -.\" -.\" Automatically generated by Pandoc 2.19.2 -.\" -.\" Define V font for inline verbatim, using C font in formats -.\" that render this, and otherwise B font. -.ie "\f[CB]x\f[R]"x" \{\ -. ftr V B -. ftr VI BI -. ftr VB B -. ftr VBI BI -.\} -.el \{\ -. ftr V CR -. ftr VI CI -. ftr VB CB -. ftr VBI CBI -.\} -.TH "JPACKAGE" "1" "2025" "JDK 24-ea" "JDK Commands" -.hy -.SH NAME -.PP -jpackage - tool for packaging self-contained Java applications. -.SH SYNOPSIS -.PP -\f[V]jpackage\f[R] [\f[I]options\f[R]] -.TP -\f[I]options\f[R] -Command-line options separated by spaces. -See \f[B]jpackage Options\f[R]. -.SH DESCRIPTION -.PP -The \f[V]jpackage\f[R] tool will take as input a Java application and a -Java run-time image, and produce a Java application image that includes -all the necessary dependencies. -It will be able to produce a native package in a platform-specific -format, such as an exe on Windows or a dmg on macOS. -Each format must be built on the platform it runs on, there is no -cross-platform support. -The tool will have options that allow packaged applications to be -customized in various ways. -.SH JPACKAGE OPTIONS -.SS Generic Options: -.TP -\f[V]\[at]\f[R]\f[I]filename\f[R] -Read options from a file. -.RS -.PP -This option can be used multiple times. -.RE -.TP -\f[V]--type\f[R] or \f[V]-t\f[R] \f[I]type\f[R] -The type of package to create -.RS -.PP -Valid values are: {\[dq]app-image\[dq], \[dq]exe\[dq], \[dq]msi\[dq], -\[dq]rpm\[dq], \[dq]deb\[dq], \[dq]pkg\[dq], \[dq]dmg\[dq]} -.PP -If this option is not specified a platform dependent default type will -be created. -.RE -.TP -\f[V]--app-version\f[R] \f[I]version\f[R] -Version of the application and/or package -.TP -\f[V]--copyright\f[R] \f[I]copyright\f[R] -Copyright for the application -.TP -\f[V]--description\f[R] \f[I]description\f[R] -Description of the application -.TP -\f[V]--help\f[R] or \f[V]-h\f[R] -Print the usage text with a list and description of each valid option -for the current platform to the output stream, and exit. -.TP -\f[V]--icon\f[R] \f[I]path\f[R] -Path of the icon of the application package -.RS -.PP -(absolute path or relative to the current directory) -.RE -.TP -\f[V]--name\f[R] or \f[V]-n\f[R] \f[I]name\f[R] -Name of the application and/or package -.TP -\f[V]--dest\f[R] or \f[V]-d\f[R] \f[I]destination\f[R] -Path where generated output file is placed -.RS -.PP -(absolute path or relative to the current directory). -.PP -Defaults to the current working directory. -.RE -.TP -\f[V]--resource-dir\f[R] \f[I]path\f[R] -Path to override jpackage resources -.RS -.PP -(absolute path or relative to the current directory) -.PP -Icons, template files, and other resources of jpackage can be -over-ridden by adding replacement resources to this directory. -.RE -.TP -\f[V]--temp\f[R] \f[I]directory\f[R] -Path of a new or empty directory used to create temporary files -.RS -.PP -(absolute path or relative to the current directory) -.PP -If specified, the temp dir will not be removed upon the task completion -and must be removed manually. -.PP -If not specified, a temporary directory will be created and removed upon -the task completion. -.RE -.TP -\f[V]--vendor\f[R] \f[I]vendor\f[R] -Vendor of the application -.TP -\f[V]--verbose\f[R] -Enables verbose output. -.TP -\f[V]--version\f[R] -Print the product version to the output stream and exit. -.SS Options for creating the runtime image: -.TP -\f[V]--add-modules\f[R] \f[I]module-name\f[R] [\f[V],\f[R]\f[I]module-name\f[R]...] -A comma (\[dq],\[dq]) separated list of modules to add -.RS -.PP -This module list, along with the main module (if specified) will be -passed to jlink as the --add-module argument. -If not specified, either just the main module (if --module is -specified), or the default set of modules (if --main-jar is specified) -are used. -.PP -This option can be used multiple times. -.RE -.TP -\f[V]--module-path\f[R] or \f[V]-p\f[R] \f[I]module-path\f[R] [\f[V],\f[R]\f[I]module-path\f[R]...] -A File.pathSeparator separated list of paths -.RS -.PP -Each path is either a directory of modules or the path to a modular jar, -and is absolute or relative to the current directory. -.PP -This option can be used multiple times. -.RE -.TP -\f[V]--jlink-options\f[R] \f[I]options\f[R] -A space separated list of options to pass to jlink -.RS -.PP -If not specified, defaults to \[dq]--strip-native-commands --strip-debug ---no-man-pages --no-header-files\[dq] -.PP -This option can be used multiple times. -.RE -.TP -\f[V]--runtime-image\f[R] \f[I]directory\f[R] -Path of the predefined runtime image that will be copied into the -application image -.RS -.PP -(absolute path or relative to the current directory) -.PP -If --runtime-image is not specified, jpackage will run jlink to create -the runtime image using options specified by --jlink-options. -.RE -.SS Options for creating the application image: -.TP -\f[V]--input\f[R] or \f[V]-i\f[R] \f[I]directory\f[R] -Path of the input directory that contains the files to be packaged -.RS -.PP -(absolute path or relative to the current directory) -.PP -All files in the input directory will be packaged into the application -image. -.RE -.TP -\f[V]--app-content\f[R] \f[I]additional-content\f[R] [\f[V],\f[R]\f[I]additional-content\f[R]...] -A comma separated list of paths to files and/or directories to add to -the application payload. -.RS -.PP -This option can be used more than once. -.RE -.SS Options for creating the application launcher(s): -.TP -\f[V]--add-launcher\f[R] \f[I]name\f[R]=\f[I]path\f[R] -Name of launcher, and a path to a Properties file that contains a list -of key, value pairs -.RS -.PP -(absolute path or relative to the current directory) -.PP -The keys \[dq]module\[dq], \[dq]main-jar\[dq], \[dq]main-class\[dq], -\[dq]description\[dq], \[dq]arguments\[dq], \[dq]java-options\[dq], -\[dq]icon\[dq], \[dq]launcher-as-service\[dq], \[dq]win-console\[dq], -\[dq]win-shortcut\[dq], \[dq]win-menu\[dq], and \[dq]linux-shortcut\[dq] -can be used. -.PP -These options are added to, or used to overwrite, the original command -line options to build an additional alternative launcher. -The main application launcher will be built from the command line -options. -Additional alternative launchers can be built using this option, and -this option can be used multiple times to build multiple additional -launchers. -.RE -.TP -\f[V]--arguments\f[R] \f[I]arguments\f[R] -Command line arguments to pass to the main class if no command line -arguments are given to the launcher -.RS -.PP -This option can be used multiple times. -.RE -.TP -\f[V]--java-options\f[R] \f[I]options\f[R] -Options to pass to the Java runtime -.RS -.PP -This option can be used multiple times. -.RE -.TP -\f[V]--main-class\f[R] \f[I]class-name\f[R] -Qualified name of the application main class to execute -.RS -.PP -This option can only be used if --main-jar is specified. -.RE -.TP -\f[V]--main-jar\f[R] \f[I]main-jar\f[R] -The main JAR of the application; containing the main class (specified as -a path relative to the input path) -.RS -.PP -Either --module or --main-jar option can be specified but not both. -.RE -.TP -\f[V]--module\f[R] or \f[V]-m\f[R] \f[I]module-name\f[R][/\f[I]main-class\f[R]] -The main module (and optionally main class) of the application -.RS -.PP -This module must be located on the module path. -.PP -When this option is specified, the main module will be linked in the -Java runtime image. -Either --module or --main-jar option can be specified but not both. -.RE -.SS Platform dependent options for creating the application launcher: -.SS Windows platform options (available only when running on Windows): -.TP -\f[V]--win-console\f[R] -Creates a console launcher for the application, should be specified for -application which requires console interactions -.SS macOS platform options (available only when running on macOS): -.TP -\f[V]--mac-package-identifier\f[R] \f[I]identifier\f[R] -An identifier that uniquely identifies the application for macOS -.RS -.PP -Defaults to the main class name. -.PP -May only use alphanumeric (A-Z,a-z,0-9), hyphen (-), and period (.) -characters. -.RE -.TP -\f[V]--mac-package-name\f[R] \f[I]name\f[R] -Name of the application as it appears in the Menu Bar -.RS -.PP -This can be different from the application name. -.PP -This name must be less than 16 characters long and be suitable for -displaying in the menu bar and the application Info window. -Defaults to the application name. -.RE -.TP -\f[V]--mac-package-signing-prefix\f[R] \f[I]prefix\f[R] -When signing the application package, this value is prefixed to all -components that need to be signed that don\[aq]t have an existing -package identifier. -.TP -\f[V]--mac-sign\f[R] -Request that the package or the predefined application image be signed. -.TP -\f[V]--mac-signing-keychain\f[R] \f[I]keychain-name\f[R] -Name of the keychain to search for the signing identity -.RS -.PP -If not specified, the standard keychains are used. -.RE -.TP -\f[V]--mac-signing-key-user-name\f[R] \f[I]name\f[R] -Team or user name portion in Apple signing identities -.TP -\f[V]--mac-app-store\f[R] -Indicates that the jpackage output is intended for the Mac App Store. -.TP -\f[V]--mac-entitlements\f[R] \f[I]path\f[R] -Path to file containing entitlements to use when signing executables and -libraries in the bundle -.TP -\f[V]--mac-app-category\f[R] \f[I]category\f[R] -String used to construct LSApplicationCategoryType in application plist -.RS -.PP -The default value is \[dq]utilities\[dq]. -.RE -.SS Options for creating the application package: -.TP -\f[V]--about-url\f[R] \f[I]url\f[R] -URL of the application\[aq]s home page -.TP -\f[V]--app-image\f[R] \f[I]directory\f[R] -Location of the predefined application image that is used to build an -installable package (on all platforms) or to be signed (on macOS) -.RS -.PP -(absolute path or relative to the current directory) -.RE -.TP -\f[V]--file-associations\f[R] \f[I]path\f[R] -Path to a Properties file that contains list of key, value pairs -.RS -.PP -(absolute path or relative to the current directory) -.PP -The keys \[dq]extension\[dq], \[dq]mime-type\[dq], \[dq]icon\[dq], and -\[dq]description\[dq] can be used to describe the association. -.PP -This option can be used multiple times. -.RE -.TP -\f[V]--install-dir\f[R] \f[I]path\f[R] -Absolute path of the installation directory of the application (on macOS -or linux), or relative sub-path of the installation directory such as -\[dq]Program Files\[dq] or \[dq]AppData\[dq] (on Windows) -.TP -\f[V]--license-file\f[R] \f[I]path\f[R] -Path to the license file -.RS -.PP -(absolute path or relative to the current directory) -.RE -.TP -\f[V]--runtime-image\f[R] \f[I]path\f[R] -Path of the predefined runtime image to install -.RS -.PP -(absolute path or relative to the current directory) -.PP -Option is required when creating a runtime installer. -.RE -.TP -\f[V]--launcher-as-service\f[R] -Request to create an installer that will register the main application -launcher as a background service-type application. -.SS Platform dependent options for creating the application package: -.SS Windows platform options (available only when running on Windows): -.TP -\f[V]--win-dir-chooser\f[R] -Adds a dialog to enable the user to choose a directory in which the -product is installed. -.TP -\f[V]--win-help-url\f[R] \f[I]url\f[R] -URL where user can obtain further information or technical support -.TP -\f[V]--win-menu\f[R] -Request to add a Start Menu shortcut for this application -.TP -\f[V]--win-menu-group\f[R] \f[I]menu-group-name\f[R] -Start Menu group this application is placed in -.TP -\f[V]--win-per-user-install\f[R] -Request to perform an install on a per-user basis -.TP -\f[V]--win-shortcut\f[R] -Request to create a desktop shortcut for this application -.TP -\f[V]--win-shortcut-prompt\f[R] -Adds a dialog to enable the user to choose if shortcuts will be created -by installer -.TP -\f[V]--win-update-url\f[R] \f[I]url\f[R] -URL of available application update information -.TP -\f[V]--win-upgrade-uuid\f[R] \f[I]id\f[R] -UUID associated with upgrades for this package -.SS Linux platform options (available only when running on Linux): -.TP -\f[V]--linux-package-name\f[R] \f[I]name\f[R] -Name for Linux package -.RS -.PP -Defaults to the application name. -.RE -.TP -\f[V]--linux-deb-maintainer\f[R] \f[I]email-address\f[R] -Maintainer for .deb bundle -.TP -\f[V]--linux-menu-group\f[R] \f[I]menu-group-name\f[R] -Menu group this application is placed in -.TP -\f[V]--linux-package-deps\f[R] -Required packages or capabilities for the application -.TP -\f[V]--linux-rpm-license-type\f[R] \f[I]type\f[R] -Type of the license (\[dq]License: \f[I]value\f[R]\[dq] of the RPM -\&.spec) -.TP -\f[V]--linux-app-release\f[R] \f[I]release\f[R] -Release value of the RPM <name>.spec file or Debian revision value of -the DEB control file -.TP -\f[V]--linux-app-category\f[R] \f[I]category-value\f[R] -Group value of the RPM /.spec file or Section value of DEB control file -.TP -\f[V]--linux-shortcut\f[R] -Creates a shortcut for the application. -.SS macOS platform options (available only when running on macOS): -.TP -\f[V]--mac-dmg-content\f[R] \f[I]additional-content\f[R] [\f[V],\f[R]\f[I]additional-content\f[R]...] -Include all the referenced content in the dmg. -.RS -.PP -This option can be used more than once. -.RE -.SH JPACKAGE EXAMPLES -.IP -.nf -\f[CB] -Generate an application package suitable for the host system: -\f[R] -.fi -.IP -.nf -\f[CB] -For a modular application: - jpackage -n name -p modulePath -m moduleName/className -For a non-modular application: - jpackage -i inputDir -n name \[rs] - --main-class className --main-jar myJar.jar -From a pre-built application image: - jpackage -n name --app-image appImageDir -\f[R] -.fi -.IP -.nf -\f[CB] -Generate an application image: -\f[R] -.fi -.IP -.nf -\f[CB] -For a modular application: - jpackage --type app-image -n name -p modulePath \[rs] - -m moduleName/className -For a non-modular application: - jpackage --type app-image -i inputDir -n name \[rs] - --main-class className --main-jar myJar.jar -To provide your own options to jlink, run jlink separately: - jlink --output appRuntimeImage -p modulePath \[rs] - --add-modules moduleName \[rs] - --no-header-files [<additional jlink options>...] - jpackage --type app-image -n name \[rs] - -m moduleName/className --runtime-image appRuntimeImage -\f[R] -.fi -.IP -.nf -\f[CB] -Generate a Java runtime package: -\f[R] -.fi -.IP -.nf -\f[CB] -jpackage -n name --runtime-image <runtime-image> -\f[R] -.fi -.IP -.nf -\f[CB] -Sign the predefined application image (on macOS): -\f[R] -.fi -.IP -.nf -\f[CB] -jpackage --type app-image --app-image <app-image> \[rs] - --mac-sign [<additional signing options>...] - -Note: the only additional options that are permitted in this mode are: - the set of additional mac signing options and --verbose -\f[R] -.fi -.SH JPACKAGE RESOURCE DIRECTORY -.PP -Icons, template files, and other resources of jpackage can be -over-ridden by adding replacement resources to this directory. -jpackage will lookup files by specific names in the resource directory. -.SS Resource directory files considered only when running on Linux: -.TP -\f[V]<launcher-name>.png\f[R] -Application launcher icon -.RS -.PP -Default resource is \f[I]JavaApp.png\f[R] -.RE -.TP -\f[V]<launcher-name>.desktop\f[R] -A desktop file to be used with \f[V]xdg-desktop-menu\f[R] command -.RS -.PP -Considered with application launchers registered for file associations -and/or have an icon -.PP -Default resource is \f[I]template.desktop\f[R] -.RE -.SS Resource directory files considered only when building Linux DEB/RPM installer: -.TP -\f[V]<package-name>-<launcher-name>.service\f[R] -systemd unit file for application launcher registered as a background -service-type application -.RS -.PP -Default resource is \f[I]unit-template.service\f[R] -.RE -.SS Resource directory files considered only when building Linux RPM installer: -.TP -\f[V]<package-name>.spec\f[R] -RPM spec file -.RS -.PP -Default resource is \f[I]template.spec\f[R] -.RE -.SS Resource directory files considered only when building Linux DEB installer: -.TP -\f[V]control\f[R] -Control file -.RS -.PP -Default resource is \f[I]template.control\f[R] -.RE -.TP -\f[V]copyright\f[R] -Copyright file -.RS -.PP -Default resource is \f[I]template.copyright\f[R] -.RE -.TP -\f[V]preinstall\f[R] -Pre-install shell script -.RS -.PP -Default resource is \f[I]template.preinstall\f[R] -.RE -.TP -\f[V]prerm\f[R] -Pre-remove shell script -.RS -.PP -Default resource is \f[I]template.prerm\f[R] -.RE -.TP -\f[V]postinstall\f[R] -Post-install shell script -.RS -.PP -Default resource is \f[I]template.postinstall\f[R] -.RE -.TP -\f[V]postrm\f[R] -Post-remove shell script -.RS -.PP -Default resource is \f[I]template.postrm\f[R] -.RE -.SS Resource directory files considered only when running on Windows: -.TP -\f[V]<launcher-name>.ico\f[R] -Application launcher icon -.RS -.PP -Default resource is \f[I]JavaApp.ico\f[R] -.RE -.TP -\f[V]<launcher-name>.properties\f[R] -Properties file for application launcher executable -.RS -.PP -Default resource is \f[I]WinLauncher.template\f[R] -.RE -.SS Resource directory files considered only when building Windows MSI/EXE installer: -.TP -\f[V]<application-name>-post-image.wsf\f[R] -A Windows Script File (WSF) to run after building application image -.TP -\f[V]main.wxs\f[R] -Main WiX project file -.RS -.PP -Default resource is \f[I]main.wxs\f[R] -.RE -.TP -\f[V]overrides.wxi\f[R] -Overrides WiX project file -.RS -.PP -Default resource is \f[I]overrides.wxi\f[R] -.RE -.TP -\f[V]service-installer.exe\f[R] -Service installer executable -.RS -.PP -Considered if some application launchers are registered as background -service-type applications -.RE -.TP -\f[V]<launcher-name>-service-install.wxi\f[R] -Service installer WiX project file -.RS -.PP -Considered if some application launchers are registered as background -service-type applications -.PP -Default resource is \f[I]service-install.wxi\f[R] -.RE -.TP -\f[V]<launcher-name>-service-config.wxi\f[R] -Service installer WiX project file -.RS -.PP -Considered if some application launchers are registered as background -service-type applications -.PP -Default resource is \f[I]service-config.wxi\f[R] -.RE -.TP -\f[V]InstallDirNotEmptyDlg.wxs\f[R] -WiX project file for installer UI dialog checking installation directory -doesn\[aq]t exist or is empty -.RS -.PP -Default resource is \f[I]InstallDirNotEmptyDlg.wxs\f[R] -.RE -.TP -\f[V]ShortcutPromptDlg.wxs\f[R] -WiX project file for installer UI dialog configuring shortcuts -.RS -.PP -Default resource is \f[I]ShortcutPromptDlg.wxs\f[R] -.RE -.TP -\f[V]bundle.wxf\f[R] -WiX project file with the hierarchy of components of application image -.TP -\f[V]ui.wxf\f[R] -WiX project file for installer UI -.SS Resource directory files considered only when building Windows EXE installer: -.TP -\f[V]WinInstaller.properties\f[R] -Properties file for the installer executable -.RS -.PP -Default resource is \f[I]WinInstaller.template\f[R] -.RE -.TP -\f[V]<package-name>-post-msi.wsf\f[R] -A Windows Script File (WSF) to run after building embedded MSI installer -for EXE installer -.SS Resource directory files considered only when running on macOS: -.TP -\f[V]<launcher-name>.icns\f[R] -Application launcher icon -.RS -.PP -Default resource is \f[I]JavaApp.icns\f[R] -.RE -.TP -\f[V]Info.plist\f[R] -Application property list file -.RS -.PP -Default resource is \f[I]Info-lite.plist.template\f[R] -.RE -.TP -\f[V]Runtime-Info.plist\f[R] -Java Runtime property list file -.RS -.PP -Default resource is \f[I]Runtime-Info.plist.template\f[R] -.RE -.TP -\f[V]<application-name>.entitlements\f[R] -Signing entitlements property list file -.RS -.PP -Default resource is \f[I]sandbox.plist\f[R] -.RE -.SS Resource directory files considered only when building macOS PKG/DMG installer: -.TP -\f[V]<package-name>-post-image.sh\f[R] -Shell script to run after building application image -.SS Resource directory files considered only when building macOS PKG installer: -.TP -\f[V]uninstaller\f[R] -Uninstaller shell script -.RS -.PP -Considered if some application launchers are registered as background -service-type applications -.PP -Default resource is \f[I]uninstall.command.template\f[R] -.RE -.TP -\f[V]preinstall\f[R] -Pre-install shell script -.RS -.PP -Default resource is \f[I]preinstall.template\f[R] -.RE -.TP -\f[V]postinstall\f[R] -Post-install shell script -.RS -.PP -Default resource is \f[I]postinstall.template\f[R] -.RE -.TP -\f[V]services-preinstall\f[R] -Pre-install shell script for services package -.RS -.PP -Considered if some application launchers are registered as background -service-type applications -.PP -Default resource is \f[I]services-preinstall.template\f[R] -.RE -.TP -\f[V]services-postinstall\f[R] -Post-install shell script for services package -.RS -.PP -Considered if some application launchers are registered as background -service-type applications -.PP -Default resource is \f[I]services-postinstall.template\f[R] -.RE -.TP -\f[V]<package-name>-background.png\f[R] -Background image -.RS -.PP -Default resource is \f[I]background_pkg.png\f[R] -.RE -.TP -\f[V]<package-name>-background-darkAqua.png\f[R] -Dark background image -.RS -.PP -Default resource is \f[I]background_pkg.png\f[R] -.RE -.TP -\f[V]product-def.plist\f[R] -Package property list file -.RS -.PP -Default resource is \f[I]product-def.plist\f[R] -.RE -.TP -\f[V]<package-name>-<launcher-name>.plist\f[R] -launchd property list file for application launcher registered as a -background service-type application -.RS -.PP -Default resource is \f[I]launchd.plist.template\f[R] -.RE -.SS Resource directory files considered only when building macOS DMG installer: -.TP -\f[V]<package-name>-dmg-setup.scpt\f[R] -Setup AppleScript script -.RS -.PP -Default resource is \f[I]DMGsetup.scpt\f[R] -.RE -.TP -\f[V]<package-name>-license.plist\f[R] -License property list file -.RS -.PP -Default resource is \f[I]lic_template.plist\f[R] -.RE -.TP -\f[V]<package-name>-background.tiff\f[R] -Background image -.RS -.PP -Default resource is \f[I]background_dmg.tiff\f[R] -.RE -.TP -\f[V]<package-name>-volume.icns\f[R] -Volume icon -.RS -.PP -Default resource is \f[I]JavaApp.icns\f[R] -.RE diff --git a/src/jdk.jpackage/share/man/jpackage.md b/src/jdk.jpackage/share/man/jpackage.md new file mode 100644 index 00000000000..228c0b13259 --- /dev/null +++ b/src/jdk.jpackage/share/man/jpackage.md @@ -0,0 +1,791 @@ +--- +# Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# This code is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 only, as +# published by the Free Software Foundation. +# +# This code is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# version 2 for more details (a copy is included in the LICENSE file that +# accompanied this code). +# +# You should have received a copy of the GNU General Public License version +# 2 along with this work; if not, write to the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +# or visit www.oracle.com if you need additional information or have any +# questions. +# + +title: 'JPACKAGE(1) JDK @@VERSION_SHORT@@ | JDK Commands' +date: @@COPYRIGHT_YEAR@@ +lang: en +--- + +## Name + +jpackage - tool for packaging self-contained Java applications. + +## Synopsis + +`jpackage` \[*options*\] + + +*options* +: Command-line options separated by spaces. See [jpackage Options]. + +## Description + +The `jpackage` tool will take as input a Java application and a Java run-time image, and produce a Java application image that includes all the necessary dependencies. It will be able to produce a native package in a platform-specific format, such as an exe on Windows or a dmg on macOS. Each format must be built on the platform it runs on, there is no cross-platform support. The tool will have options that allow packaged applications to be customized in various ways. + + +## jpackage Options + +### Generic Options: + +`@`*filename* + +: Read options from a file. + + This option can be used multiple times. + +<a id="option-type">`--type` or `-t` *type*</a> +: The type of package to create + + Valid values are: {"app-image", "exe", "msi", "rpm", "deb", "pkg", "dmg"} + + If this option is not specified a platform dependent + default type will be created. + +<a id="option-app-version">`--app-version` *version*</a> + +: Version of the application and/or package + +<a id="option-copyright">`--copyright` *copyright*</a> + +: Copyright for the application + +<a id="option-description">`--description` *description*</a> + +: Description of the application + +<a id="option-help">`--help` or `-h`</a> + +: Print the usage text with a list and description of each valid + option for the current platform to the output stream, and exit. + +<a id="option-icon">`--icon` *path*</a> + +: Path of the icon of the application package + + (absolute path or relative to the current directory) + +<a id="option-name">`--name` or `-n` *name*</a> + +: Name of the application and/or package + +<a id="option-dest">`--dest` or `-d` *destination*</a> + +: Path where generated output file is placed + + (absolute path or relative to the current directory). + + Defaults to the current working directory. + +<a id="option-resource-dir">`--resource-dir` *path*</a> + +: Path to override jpackage resources + + (absolute path or relative to the current directory) + + Icons, template files, and other resources of jpackage can be + over-ridden by adding replacement resources to this directory. + +<a id="option-temp">`--temp` *directory*</a> + +: Path of a new or empty directory used to create temporary files + + (absolute path or relative to the current directory) + + If specified, the temp dir will not be removed upon the task + completion and must be removed manually. + + If not specified, a temporary directory will be created and + removed upon the task completion. + +<a id="option-vendor">`--vendor` *vendor*</a> + +: Vendor of the application + +<a id="option-verbose">`--verbose`</a> + +: Enables verbose output. + +<a id="option-version">`--version`</a> + +: Print the product version to the output stream and exit. + +### Options for creating the runtime image: + + +<a id="option-add-modules">`--add-modules` *module-name* \[`,`*module-name*...\]</a> + +: A comma (",") separated list of modules to add + + This module list, along with the main module (if specified) + will be passed to jlink as the --add-module argument. + If not specified, either just the main module (if --module is + specified), or the default set of modules (if --main-jar is + specified) are used. + + This option can be used multiple times. + +<a id="option-module-path">`--module-path` or `-p` *module-path* \[`,`*module-path*...\]</a> + +: A File.pathSeparator separated list of paths + + Each path is either a directory of modules or the path to a + modular jar, and is absolute or relative to the current directory. + + This option can be used multiple times. + +<a id="option-jlink-options">`--jlink-options` *options*</a> + +: A space separated list of options to pass to jlink + + If not specified, defaults to "--strip-native-commands + --strip-debug --no-man-pages --no-header-files" + + This option can be used multiple times. + +<a id="option-runtime-image">`--runtime-image` *directory*</a> + +: Path of the predefined runtime image that will be copied into + the application image + + (absolute path or relative to the current directory) + + If --runtime-image is not specified, jpackage will run jlink to + create the runtime image using options specified by --jlink-options. + +### Options for creating the application image: + +<a id="option-input">`--input` or `-i` *directory*</a> + +: Path of the input directory that contains the files to be packaged + + (absolute path or relative to the current directory) + + All files in the input directory will be packaged into the + application image. + +<a id="option-app-content">`--app-content` *additional-content* \[`,`*additional-content*...\]</a> + +: A comma separated list of paths to files and/or directories + to add to the application payload. + + This option can be used more than once. + +### Options for creating the application launcher(s): + + +<a id="option-add-launcher">`--add-launcher` *name*=*path*</a> + +: Name of launcher, and a path to a Properties file that contains + a list of key, value pairs + + (absolute path or relative to the current directory) + + The keys "module", "main-jar", "main-class", "description", + "arguments", "java-options", "icon", "launcher-as-service", + "win-console", "win-shortcut", "win-menu", and "linux-shortcut" + can be used. + + These options are added to, or used to overwrite, the original + command line options to build an additional alternative launcher. + The main application launcher will be built from the command line + options. Additional alternative launchers can be built using + this option, and this option can be used multiple times to + build multiple additional launchers. + +<a id="option-arguments">`--arguments` *arguments*</a> + +: Command line arguments to pass to the main class if no command + line arguments are given to the launcher + + This option can be used multiple times. + +<a id="option-java-options">`--java-options` *options*</a> + +: Options to pass to the Java runtime + + This option can be used multiple times. + +<a id="option-main-class">`--main-class` *class-name*</a> + +: Qualified name of the application main class to execute + + This option can only be used if --main-jar is specified. + +<a id="option-main-jar">`--main-jar` *main-jar*</a> + +: The main JAR of the application; containing the main class + (specified as a path relative to the input path) + + Either --module or --main-jar option can be specified but not + both. + +<a id="option-module">`--module` or `-m` *module-name*[/*main-class*]</a> + +: The main module (and optionally main class) of the application + + This module must be located on the module path. + + When this option is specified, the main module will be linked + in the Java runtime image. Either --module or --main-jar + option can be specified but not both. + + +### Platform dependent options for creating the application launcher: + + +#### Windows platform options (available only when running on Windows): + +<a id="option-win-console">`--win-console`</a> + +: Creates a console launcher for the application, should be + specified for application which requires console interactions + +#### macOS platform options (available only when running on macOS): + +<a id="option-mac-package-identifier">`--mac-package-identifier` *identifier*</a> + +: An identifier that uniquely identifies the application for macOS + + Defaults to the main class name. + + May only use alphanumeric (A-Z,a-z,0-9), hyphen (-), + and period (.) characters. + +<a id="option-mac-package-name">`--mac-package-name` *name*</a> + +: Name of the application as it appears in the Menu Bar + + This can be different from the application name. + + This name must be less than 16 characters long and be suitable for + displaying in the menu bar and the application Info window. + Defaults to the application name. + +<a id="option-mac-package-signing-prefix">`--mac-package-signing-prefix` *prefix*</a> + +: When signing the application package, this value is prefixed to all + components that need to be signed that don't have + an existing package identifier. + +<a id="option-mac-sign">`--mac-sign`</a> + +: Request that the package or the predefined application image be signed. + +<a id="option-mac-signing-keychain">`--mac-signing-keychain` *keychain-name*</a> + +: Name of the keychain to search for the signing identity + + If not specified, the standard keychains are used. + +<a id="option-mac-signing-key-user-name">`--mac-signing-key-user-name` *name*</a> + +: Team or user name portion in Apple signing identities + +<a id="option-mac-app-store">`--mac-app-store`</a> + +: Indicates that the jpackage output is intended for the Mac App Store. + +<a id="option-mac-entitlements">`--mac-entitlements` *path*</a> + +: Path to file containing entitlements to use when signing executables and libraries in the bundle + +<a id="option-mac-app-category">`--mac-app-category` *category*</a> + +: String used to construct LSApplicationCategoryType in application plist + + The default value is "utilities". + +### Options for creating the application package: + +<a id="option-about-url">`--about-url` *url*</a> + +: URL of the application's home page + +<a id="option-app-image">`--app-image` *directory*</a> + +: Location of the predefined application image that is used to build an installable package + (on all platforms) or to be signed (on macOS) + + (absolute path or relative to the current directory) + +<a id="option-file-associations">`--file-associations` *path*</a> + +: Path to a Properties file that contains list of key, value pairs + + (absolute path or relative to the current directory) + + The keys "extension", "mime-type", "icon", and "description" + can be used to describe the association. + + This option can be used multiple times. + +<a id="option-install-dir">`--install-dir` *path*</a> + +: Absolute path of the installation directory of the application (on macOS + or linux), or relative sub-path of the installation directory + such as "Program Files" or "AppData" (on Windows) + +<a id="option-license-file">`--license-file` *path*</a> + +: Path to the license file + + (absolute path or relative to the current directory) + +<a id="option-application-package-runtime-image">`--runtime-image` *path*</a> + +: Path of the predefined runtime image to install + + (absolute path or relative to the current directory) + + Option is required when creating a runtime installer. + +<a id="option-launcher-as-service">`--launcher-as-service`</a> + +: Request to create an installer that will register the main + application launcher as a background service-type application. + + +### Platform dependent options for creating the application package: + + +#### Windows platform options (available only when running on Windows): + +<a id="option-win-dir-chooser">`--win-dir-chooser`</a> + +: Adds a dialog to enable the user to choose a directory in which + the product is installed. + +<a id="option-win-help-url">`--win-help-url` *url*</a> + +: URL where user can obtain further information or technical support + +<a id="option-win-menu">`--win-menu`</a> + +: Request to add a Start Menu shortcut for this application + +<a id="option-win-menu-group">`--win-menu-group` *menu-group-name*</a> + +: Start Menu group this application is placed in + +<a id="option-win-per-user-install">`--win-per-user-install`</a> + +: Request to perform an install on a per-user basis + +<a id="option-win-shortcut">`--win-shortcut`</a> + +: Request to create a desktop shortcut for this application + +<a id="option-win-shortcut-prompt">`--win-shortcut-prompt`</a> + +: Adds a dialog to enable the user to choose if shortcuts will be created by installer + +<a id="option-win-update-url">`--win-update-url` *url*</a> + +: URL of available application update information + +<a id="option-win-upgrade-uuid">`--win-upgrade-uuid` *id*</a> + +: UUID associated with upgrades for this package + +#### Linux platform options (available only when running on Linux): + +<a id="option-linux-package-name">`--linux-package-name` *name*</a> + +: Name for Linux package + + Defaults to the application name. + +<a id="option-linux-deb-maintainer">`--linux-deb-maintainer` *email-address*</a> + +: Maintainer for .deb bundle + +<a id="option-linux-menu-group">`--linux-menu-group` *menu-group-name*</a> + +: Menu group this application is placed in + +<a id="option-linux-package-deps">`--linux-package-deps`</a> + +: Required packages or capabilities for the application + +<a id="option-linux-rpm-license-type">`--linux-rpm-license-type` *type*</a> + +: Type of the license ("License: *value*" of the RPM .spec) + +<a id="option-linux-app-release">`--linux-app-release` *release*</a> + +: Release value of the RPM \<name\>.spec file or + Debian revision value of the DEB control file + +<a id="option-linux-app-category">`--linux-app-category` *category-value*</a> + +: Group value of the RPM /<name/>.spec file or + Section value of DEB control file + +<a id="option-linux-shortcut">`--linux-shortcut`</a> + +: Creates a shortcut for the application. + +#### macOS platform options (available only when running on macOS): + +<a id="option-mac-dmg-content">`--mac-dmg-content` *additional-content* \[`,`*additional-content*...\]</a> + +: Include all the referenced content in the dmg. + + This option can be used more than once. + +## jpackage Examples + +``` +Generate an application package suitable for the host system: +``` + For a modular application: + jpackage -n name -p modulePath -m moduleName/className + For a non-modular application: + jpackage -i inputDir -n name \ + --main-class className --main-jar myJar.jar + From a pre-built application image: + jpackage -n name --app-image appImageDir + +``` +Generate an application image: +``` + For a modular application: + jpackage --type app-image -n name -p modulePath \ + -m moduleName/className + For a non-modular application: + jpackage --type app-image -i inputDir -n name \ + --main-class className --main-jar myJar.jar + To provide your own options to jlink, run jlink separately: + jlink --output appRuntimeImage -p modulePath \ + --add-modules moduleName \ + --no-header-files [<additional jlink options>...] + jpackage --type app-image -n name \ + -m moduleName/className --runtime-image appRuntimeImage + +``` +Generate a Java runtime package: +``` + jpackage -n name --runtime-image <runtime-image> + +``` +Sign the predefined application image (on macOS): +``` + jpackage --type app-image --app-image <app-image> \ + --mac-sign [<additional signing options>...] + + Note: the only additional options that are permitted in this mode are: + the set of additional mac signing options and --verbose + + +## jpackage resource directory + +Icons, template files, and other resources of jpackage can be over-ridden by +adding replacement resources to this directory. +jpackage will lookup files by specific names in the resource directory. + + +### Resource directory files considered only when running on Linux: + +`<launcher-name>.png` + +: Application launcher icon + + Default resource is *JavaApp.png* + +`<launcher-name>.desktop` + +: A desktop file to be used with `xdg-desktop-menu` command + + Considered with application launchers registered for file associations and/or have an icon + + Default resource is *template.desktop* + + +#### Resource directory files considered only when building Linux DEB/RPM installer: + +`<package-name>-<launcher-name>.service` + +: systemd unit file for application launcher registered as a background service-type application + + Default resource is *unit-template.service* + + +#### Resource directory files considered only when building Linux RPM installer: + +`<package-name>.spec` + +: RPM spec file + + Default resource is *template.spec* + + +#### Resource directory files considered only when building Linux DEB installer: + +`control` + +: Control file + + Default resource is *template.control* + +`copyright` + +: Copyright file + + Default resource is *template.copyright* + +`preinstall` + +: Pre-install shell script + + Default resource is *template.preinstall* + +`prerm` + +: Pre-remove shell script + + Default resource is *template.prerm* + +`postinstall` + +: Post-install shell script + + Default resource is *template.postinstall* + +`postrm` + +: Post-remove shell script + + Default resource is *template.postrm* + + +### Resource directory files considered only when running on Windows: + +`<launcher-name>.ico` + +: Application launcher icon + + Default resource is *JavaApp.ico* + +`<launcher-name>.properties` + +: Properties file for application launcher executable + + Default resource is *WinLauncher.template* + + +#### Resource directory files considered only when building Windows MSI/EXE installer: + +`<application-name>-post-image.wsf` + +: A Windows Script File (WSF) to run after building application image + +`main.wxs` + +: Main WiX project file + + Default resource is *main.wxs* + +`overrides.wxi` + +: Overrides WiX project file + + Default resource is *overrides.wxi* + +`service-installer.exe` + +: Service installer executable + + Considered if some application launchers are registered as background service-type applications + +`<launcher-name>-service-install.wxi` + +: Service installer WiX project file + + Considered if some application launchers are registered as background service-type applications + + Default resource is *service-install.wxi* + +`<launcher-name>-service-config.wxi` + +: Service installer WiX project file + + Considered if some application launchers are registered as background service-type applications + + Default resource is *service-config.wxi* + +`InstallDirNotEmptyDlg.wxs` + +: WiX project file for installer UI dialog checking installation directory doesn't exist or is empty + + Default resource is *InstallDirNotEmptyDlg.wxs* + +`ShortcutPromptDlg.wxs` + +: WiX project file for installer UI dialog configuring shortcuts + + Default resource is *ShortcutPromptDlg.wxs* + +`bundle.wxf` + +: WiX project file with the hierarchy of components of application image + +`ui.wxf` + +: WiX project file for installer UI + + +#### Resource directory files considered only when building Windows EXE installer: + +`WinInstaller.properties` + +: Properties file for the installer executable + + Default resource is *WinInstaller.template* + +`<package-name>-post-msi.wsf` + +: A Windows Script File (WSF) to run after building embedded MSI installer for EXE installer + + +### Resource directory files considered only when running on macOS: + +`<launcher-name>.icns` + +: Application launcher icon + + Default resource is *JavaApp.icns* + +`Info.plist` + +: Application property list file + + Default resource is *Info-lite.plist.template* + +`Runtime-Info.plist` + +: Java Runtime property list file + + Default resource is *Runtime-Info.plist.template* + +`<application-name>.entitlements` + +: Signing entitlements property list file + + Default resource is *sandbox.plist* + + +#### Resource directory files considered only when building macOS PKG/DMG installer: + +`<package-name>-post-image.sh` + +: Shell script to run after building application image + + +#### Resource directory files considered only when building macOS PKG installer: + +`uninstaller` + +: Uninstaller shell script + + Considered if some application launchers are registered as background service-type applications + + Default resource is *uninstall.command.template* + +`preinstall` + +: Pre-install shell script + + Default resource is *preinstall.template* + +`postinstall` + +: Post-install shell script + + Default resource is *postinstall.template* + +`services-preinstall` + +: Pre-install shell script for services package + + Considered if some application launchers are registered as background service-type applications + + Default resource is *services-preinstall.template* + +`services-postinstall` + +: Post-install shell script for services package + + Considered if some application launchers are registered as background service-type applications + + Default resource is *services-postinstall.template* + +`<package-name>-background.png` + +: Background image + + Default resource is *background_pkg.png* + +`<package-name>-background-darkAqua.png` + +: Dark background image + + Default resource is *background_pkg.png* + +`product-def.plist` + +: Package property list file + + Default resource is *product-def.plist* + +`<package-name>-<launcher-name>.plist` + +: launchd property list file for application launcher registered as a background service-type application + + Default resource is *launchd.plist.template* + + +#### Resource directory files considered only when building macOS DMG installer: + +`<package-name>-dmg-setup.scpt` + +: Setup AppleScript script + + Default resource is *DMGsetup.scpt* + +`<package-name>-license.plist` + +: License property list file + + Default resource is *lic_template.plist* + +`<package-name>-background.tiff` + +: Background image + + Default resource is *background_dmg.tiff* + +`<package-name>-volume.icns` + +: Volume icon + + Default resource is *JavaApp.icns* diff --git a/src/jdk.jshell/share/man/jshell.1 b/src/jdk.jshell/share/man/jshell.1 deleted file mode 100644 index 6f478e57442..00000000000 --- a/src/jdk.jshell/share/man/jshell.1 +++ /dev/null @@ -1,1292 +0,0 @@ -.\" Copyright (c) 2017, 2023, Oracle and/or its affiliates. All rights reserved. -.\" DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -.\" -.\" This code is free software; you can redistribute it and/or modify it -.\" under the terms of the GNU General Public License version 2 only, as -.\" published by the Free Software Foundation. -.\" -.\" This code is distributed in the hope that it will be useful, but WITHOUT -.\" ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -.\" FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -.\" version 2 for more details (a copy is included in the LICENSE file that -.\" accompanied this code). -.\" -.\" You should have received a copy of the GNU General Public License version -.\" 2 along with this work; if not, write to the Free Software Foundation, -.\" Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -.\" -.\" Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -.\" or visit www.oracle.com if you need additional information or have any -.\" questions. -.\" -'\" t -.\" Automatically generated by Pandoc 2.19.2 -.\" -.\" Define V font for inline verbatim, using C font in formats -.\" that render this, and otherwise B font. -.ie "\f[CB]x\f[R]"x" \{\ -. ftr V B -. ftr VI BI -. ftr VB B -. ftr VBI BI -.\} -.el \{\ -. ftr V CR -. ftr VI CI -. ftr VB CB -. ftr VBI CBI -.\} -.TH "JSHELL" "1" "2025" "JDK 24-ea" "JDK Commands" -.hy -.SH NAME -.PP -jshell - interactively evaluate declarations, statements, and -expressions of the Java programming language in a read-eval-print loop -(REPL) -.SH SYNOPSIS -.PP -\f[V]jshell\f[R] [\f[I]options\f[R]] [\f[I]load-files\f[R]] -.TP -\f[I]options\f[R] -Command-line options, separated by spaces. -See \f[B]Options for jshell\f[R]. -.TP -\f[I]load-files\f[R] -One or more scripts to run when the tool is started. -Scripts can contain any valid code snippets or JShell commands. -.RS -.PP -The script can be a local file or one of following predefined scripts: -.TP -\f[V]DEFAULT\f[R] -Loads the default entries, which are commonly used as imports. -.TP -\f[V]JAVASE\f[R] -Imports all Java SE packages. -.TP -\f[V]PRINTING\f[R] -Defines \f[V]print\f[R], \f[V]println\f[R], and \f[V]printf\f[R] as -\f[V]jshell\f[R] methods for use within the tool. -.TP -\f[V]TOOLING\f[R] -Defines \f[V]javac\f[R], \f[V]jar\f[R], and other methods for running -JDK tools via their command-line interface within the \f[V]jshell\f[R] -tool. -.PP -For more than one script, use a space to separate the names. -Scripts are run in the order in which they\[aq]re entered on the command -line. -Command-line scripts are run after startup scripts. -To run a script after JShell is started, use the \f[V]/open\f[R] -command. -.PP -To accept input from standard input and suppress the interactive I/O, -enter a hyphen (-) for \f[I]load-files\f[R]. -This option enables the use of the \f[V]jshell\f[R] tool in pipe chains. -.RE -.SH DESCRIPTION -.PP -JShell provides a way to interactively evaluate declarations, -statements, and expressions of the Java programming language, making it -easier to learn the language, explore unfamiliar code and APIs, and -prototype complex code. -Java statements, variable definitions, method definitions, class -definitions, import statements, and expressions are accepted. -The bits of code entered are called snippets. -.PP -As snippets are entered, they\[aq]re evaluated, and feedback is -provided. -Feedback varies from the results and explanations of actions to nothing, -depending on the snippet entered and the feedback mode chosen. -Errors are described regardless of the feedback mode. -Start with the verbose mode to get the most feedback while learning the -tool. -.PP -Command-line options are available for configuring the initial -environment when JShell is started. -Within JShell, commands are available for modifying the environment as -needed. -.PP -Existing snippets can be loaded from a file to initialize a JShell -session, or at any time within a session. -Snippets can be modified within the session to try out different -variations and make corrections. -To keep snippets for later use, save them to a file. -.SH OPTIONS FOR JSHELL -.TP -\f[V]--add-exports\f[R] \f[I]module\f[R]/\f[I]package\f[R] -Specifies a package to be considered as exported from its defining -module. -.TP -\f[V]--add-modules\f[R] \f[I]module\f[R][\f[V],\f[R]\f[I]module\f[R]...] -Specifies the root modules to resolve in addition to the initial module. -.TP -\f[V]-C\f[R]\f[I]flag\f[R] -passes \f[I]flag\f[R] to the Java compiler inside JShell. -For example, \f[V]-C-Xlint\f[R] enables all the recommended lint -warnings, and \f[V]-C--release=<N>\f[R] compiles for Java SE N, as if ---release N was specified. -.TP -\f[V]--class-path\f[R] \f[I]path\f[R] -Specifies the directories and archives that are searched to locate class -files. -This option overrides the path in the \f[V]CLASSPATH\f[R] environment -variable. -If the environment variable isn\[aq]t set and this option isn\[aq]t -used, then the current directory is searched. -For Linux and macOS, use a colon (:) to separate items in the path. -For Windows, use a semicolon (;) to separate items. -.TP -\f[V]--enable-preview\f[R] -Allows code to depend on the preview features of this release. -.TP -\f[V]--execution\f[R] \f[I]specification\f[R] -Specifies an alternate execution engine, where \f[I]specification\f[R] -is an ExecutionControl spec. -See the documentation of the package jdk.jshell.spi for the syntax of -the spec. -.TP -\f[V]--feedback\f[R] \f[I]mode\f[R] -Sets the initial level of feedback provided in response to what\[aq]s -entered. -The initial level can be overridden within a session by using the -\f[V]/set feedback\f[R] \f[I]mode\f[R] command. -The default is \f[V]normal\f[R]. -.RS -.PP -The following values are valid for \f[I]mode\f[R]: -.TP -\f[V]verbose\f[R] -Provides detailed feedback for entries. -Additional information about the action performed is displayed after the -result of the action. -The next prompt is separated from the feedback by a blank line. -.TP -\f[V]normal\f[R] -Provides an average amount of feedback. -The next prompt is separated from the feedback by a blank line. -.TP -\f[V]concise\f[R] -Provides minimal feedback. -The next prompt immediately follows the code snippet or feedback. -.TP -\f[V]silent\f[R] -Provides no feedback. -The next prompt immediately follows the code snippet. -.TP -\f[I]custom\f[R] -Provides custom feedback based on how the mode is defined. -Custom feedback modes are created within JShell by using the -\f[V]/set mode\f[R] command. -.RE -.TP -\f[V]--help\f[R] or \f[V]-h\f[R] or \f[V]-?\f[R] -Prints a summary of standard options and exits the tool. -.TP -\f[V]--help-extra\f[R] or \f[V]-X\f[R] -Prints a summary of nonstandard options and exits the tool. -Nonstandard options are subject to change without notice. -.TP -\f[V]-J\f[R]\f[I]flag\f[R] -passes \f[I]flag\f[R] to the runtime system, but has no effect on the -execution of code snippets. -To specify flags that affect the execution of code snippets, use -\f[V]-R\f[R]\f[I]flag\f[R]. -Alternatively, use \f[V]-J\f[R]\f[I]flag\f[R] with -\f[V]--execution local\f[R]. -.TP -\f[V]--module-path\f[R] \f[I]modulepath\f[R] -Specifies where to find application modules. -For Linux and macOS, use a colon (:) to separate items in the path. -For Windows, use a semicolon (;) to separate items. -.TP -\f[V]--no-startup\f[R] -Prevents startup scripts from running when JShell starts. -Use this option to run only the scripts entered on the command line when -JShell is started, or to start JShell without any preloaded information -if no scripts are entered. -This option can\[aq]t be used if the \f[V]--startup\f[R] option is used. -.TP -\f[V]-q\f[R] -Sets the feedback mode to \f[V]concise\f[R], which is the same as -entering \f[V]--feedback concise\f[R]. -.TP -\f[V]-R\f[R]\f[I]flag\f[R] -passes \f[I]flag\f[R] to the runtime system only when code snippets are -executed. -For example, \f[V]-R-Dfoo=bar\f[R] means that execution of the snippet -\f[V]System.getProperty(\[dq]foo\[dq])\f[R] will return -\f[V]\[dq]bar\[dq]\f[R]. -.TP -\f[V]-s\f[R] -Sets the feedback mode to \f[V]silent\f[R], which is the same as -entering \f[V]--feedback silent\f[R]. -.TP -\f[V]--show-version\f[R] -Prints version information and enters the tool. -.TP -\f[V]--startup\f[R] \f[I]file\f[R] -Overrides the default startup script for this session. -The script can contain any valid code snippets or commands. -.RS -.PP -The script can be a local file or one of the following predefined -scripts: -.TP -\f[V]DEFAULT\f[R] -Loads the default entries, which are commonly used as imports. -.TP -\f[V]JAVASE\f[R] -Imports all Java SE packages. -.TP -\f[V]PRINTING\f[R] -Defines \f[V]print\f[R], \f[V]println\f[R], and \f[V]printf\f[R] as -\f[V]jshell\f[R] methods for use within the tool. -.TP -\f[V]TOOLING\f[R] -Defines \f[V]javac\f[R], \f[V]jar\f[R], and other methods for running -JDK tools via their command-line interface within the \f[V]jshell\f[R] -tool. -.PP -For more than one script, provide a separate instance of this option for -each script. -Startup scripts are run when JShell is first started and when the -session is restarted with the \f[V]/reset\f[R], \f[V]/reload\f[R], or -\f[V]/env\f[R] command. -Startup scripts are run in the order in which they\[aq]re entered on the -command line. -.PP -This option can\[aq]t be used if the \f[V]--no-startup\f[R] option is -used. -.RE -.TP -\f[V]-v\f[R] -Sets the feedback mode to \f[V]verbose\f[R], which is the same as -entering \f[V]--feedback verbose\f[R]. -.TP -\f[V]--version\f[R] -Prints version information and exits the tool. -.SH JSHELL COMMANDS -.PP -Within the \f[V]jshell\f[R] tool, commands are used to modify the -environment and manage code snippets. -.TP -\f[V]/drop\f[R] {\f[I]name\f[R]|\f[I]id\f[R]|\f[I]startID\f[R]\f[V]-\f[R]\f[I]endID\f[R]} [{\f[I]name\f[R]|\f[I]id\f[R]|\f[I]startID\f[R]\f[V]-\f[R]\f[I]endID\f[R]}...] -Drops snippets identified by name, ID, or ID range, making them -inactive. -For a range of IDs, provide the starting ID and ending ID separated with -a hyphen. -To provide a list, separate the items in the list with a space. -Use the \f[V]/list\f[R] command to see the IDs of code snippets. -.TP -\f[V]/edit\f[R] [\f[I]option\f[R]] -Opens an editor. -If no option is entered, then the editor opens with the active snippets. -.RS -.PP -The following options are valid: -.TP -{\f[I]name\f[R]|\f[I]id\f[R]|\f[I]startID\f[R]\f[V]-\f[R]\f[I]endID\f[R]} [{\f[I]name\f[R]|\f[I]id\f[R]|\f[I]startID\f[R]\f[V]-\f[R]\f[I]endID\f[R]}...] -Opens the editor with the snippets identified by name, ID, or ID range. -For a range of IDs, provide the starting ID and ending ID separated with -a hyphen. -To provide a list, separate the items in the list with a space. -Use the \f[V]/list\f[R] command to see the IDs of code snippets. -.TP -\f[V]-all\f[R] -Opens the editor with all snippets, including startup snippets and -snippets that failed, were overwritten, or were dropped. -.TP -\f[V]-start\f[R] -Opens the editor with startup snippets that were evaluated when JShell -was started. -.PP -To exit edit mode, close the editor window, or respond to the prompt -provided if the \f[V]-wait\f[R] option was used when the editor was set. -.PP -Use the \f[V]/set editor\f[R] command to specify the editor to use. -If no editor is set, then the following environment variables are -checked in order: \f[V]JSHELLEDITOR\f[R], \f[V]VISUAL\f[R], and -\f[V]EDITOR\f[R]. -If no editor is set in JShell and none of the editor environment -variables is set, then a simple default editor is used. -.RE -.TP -\f[V]/env\f[R] [\f[I]options\f[R]] -Displays the environment settings, or updates the environment settings -and restarts the session. -If no option is entered, then the current environment settings are -displayed. -If one or more options are entered, then the session is restarted as -follows: -.RS -.IP \[bu] 2 -Updates the environment settings with the provided options. -.IP \[bu] 2 -Resets the execution state. -.IP \[bu] 2 -Runs the startup scripts. -.IP \[bu] 2 -Silently replays the history in the order entered. -The history includes all valid snippets or \f[V]/drop\f[R] commands -entered at the \f[V]jshell\f[R] prompt, in scripts entered on the -command line, or scripts entered with the \f[V]/open\f[R] command. -.PP -Environment settings entered on the command line or provided with a -previous \f[V]/reset\f[R], \f[V]/env\f[R], or \f[V]/reload\f[R] command -are maintained unless an \f[I]option\f[R] is entered that overwrites the -setting. -.PP -The following options are valid: -.TP -\f[V]--add-modules\f[R] \f[I]module\f[R][\f[V],\f[R]\f[I]module\f[R]...] -Specifies the root modules to resolve in addition to the initial module. -.TP -\f[V]--add-exports\f[R] \f[I]source-module\f[R]\f[V]/\f[R]\f[I]package\f[R]\f[V]=\f[R]\f[I]target-module\f[R][\f[V],\f[R]\f[I]target-module\f[R]]* -Adds an export of \f[I]package\f[R] from \f[I]source-module\f[R] to -\f[I]target-module\f[R]. -.TP -\f[V]--class-path\f[R] \f[I]path\f[R] -Specifies the directories and archives that are searched to locate class -files. -This option overrides the path in the \f[V]CLASSPATH\f[R] environment -variable. -If the environment variable isn\[aq]t set and this option isn\[aq]t -used, then the current directory is searched. -For Linux and macOS, use a colon (\f[V]:\f[R]) to separate items in the -path. -For Windows, use a semicolon (\f[V];\f[R]) to separate items. -.TP -\f[V]--module-path\f[R] \f[I]modulepath\f[R] -Specifies where to find application modules. -For Linux and macOS, use a colon (\f[V]:\f[R]) to separate items in the -path. -For Windows, use a semicolon (\f[V];\f[R]) to separate items. -.RE -.TP -\f[V]/exit\f[R] [\f[I]integer-expression-snippet\f[R]] -Exits the tool. -If no snippet is entered, the exit status is zero. -If a snippet is entered and the result of the snippet is an integer, the -result is used as the exit status. -If an error occurs, or the result of the snippet is not an integer, an -error is displayed and the tool remains active. -.TP -\f[V]/history\f[R] -Displays what was entered in this session. -.TP -\f[V]/help\f[R] [\f[I]command\f[R]|\f[I]subject\f[R]] -Displays information about commands and subjects. -If no options are entered, then a summary of information for all -commands and a list of available subjects are displayed. -If a valid command is provided, then expanded information for that -command is displayed. -If a valid subject is entered, then information about that subject is -displayed. -.RS -.PP -The following values for \f[I]subject\f[R] are valid: -.TP -\f[V]context\f[R] -Describes the options that are available for configuring the -environment. -.TP -\f[V]intro\f[R] -Provides an introduction to the tool. -.TP -\f[V]shortcuts\f[R] -Describes keystrokes for completing commands and snippets. -See \f[B]Input Shortcuts\f[R]. -.RE -.TP -\f[V]/imports\f[R] -Displays the current active imports, including those from the startup -scripts and scripts that were entered on the command line when JShell -was started. -.TP -\f[V]/list\f[R] [\f[I]option\f[R]] -Displays a list of snippets and their IDs. -If no option is entered, then all active snippets are displayed, but -startup snippets aren\[aq]t. -.RS -.PP -The following options are valid: -.TP -{\f[I]name\f[R]|\f[I]id\f[R]|\f[I]startID\f[R]\f[V]-\f[R]\f[I]endID\f[R]} [{\f[I]name\f[R]|\f[I]id\f[R]|\f[I]startID\f[R]\f[V]-\f[R]\f[I]endID\f[R]}...] -Displays the snippets identified by name, ID, or ID range. -For a range of IDs, provide the starting ID and ending ID separated with -a hyphen. -To provide a list, separate the items in the list with a space. -.TP -\f[V]-all\f[R] -Displays all snippets, including startup snippets and snippets that -failed, were overwritten, or were dropped. -IDs that begin with \f[V]s\f[R] are startup snippets. -IDs that begin with \f[V]e\f[R] are snippets that failed. -.TP -\f[V]-start\f[R] -Displays startup snippets that were evaluated when JShell was started. -.RE -.TP -\f[V]/methods\f[R] [\f[I]option\f[R]] -Displays information about the methods that were entered. -If no option is entered, then the name, parameter types, and return type -of all active methods are displayed. -.RS -.PP -The following options are valid: -.TP -{\f[I]name\f[R]|\f[I]id\f[R]|\f[I]startID\f[R]\f[V]-\f[R]\f[I]endID\f[R]} [{\f[I]name\f[R]|\f[I]id\f[R]|\f[I]startID\f[R]\f[V]-\f[R]\f[I]endID\f[R]}...] -Displays information for methods identified by name, ID, or ID range. -For a range of IDs, provide the starting ID and ending ID separated with -a hyphen. -To provide a list, separate the items in the list with a space. -Use the \f[V]/list\f[R] command to see the IDs of code snippets. -.TP -\f[V]-all\f[R] -Displays information for all methods, including those added when JShell -was started, and methods that failed, were overwritten, or were dropped. -.TP -\f[V]-start\f[R] -Displays information for startup methods that were added when JShell was -started. -.RE -.TP -\f[V]/open\f[R] \f[I]file\f[R] -Opens the script specified and reads the snippets into the tool. -The script can be a local file or one of the following predefined -scripts: -.RS -.TP -\f[V]DEFAULT\f[R] -Loads the default entries, which are commonly used as imports. -.TP -\f[V]JAVASE\f[R] -Imports all Java SE packages. -.TP -\f[V]PRINTING\f[R] -Defines \f[V]print\f[R], \f[V]println\f[R], and \f[V]printf\f[R] as -\f[V]jshell\f[R] methods for use within the tool. -.TP -\f[V]TOOLING\f[R] -Defines \f[V]javac\f[R], \f[V]jar\f[R], and other methods for running -JDK tools via their command-line interface within the \f[V]jshell\f[R] -tool. -.RE -.TP -\f[V]/reload\f[R] [\f[I]options\f[R]] -Restarts the session as follows: -.RS -.IP \[bu] 2 -Updates the environment settings with the provided options, if any. -.IP \[bu] 2 -Resets the execution state. -.IP \[bu] 2 -Runs the startup scripts. -.IP \[bu] 2 -Replays the history in the order entered. -The history includes all valid snippets or \f[V]/drop\f[R] commands -entered at the \f[V]jshell\f[R] prompt, in scripts entered on the -command line, or scripts entered with the \f[V]/open\f[R] command. -.PP -Environment settings entered on the command line or provided with a -previous \f[V]/reset\f[R], \f[V]/env\f[R], or \f[V]/reload\f[R] command -are maintained unless an \f[I]option\f[R] is entered that overwrites the -setting. -.PP -The following options are valid: -.TP -\f[V]--add-modules\f[R] \f[I]module\f[R][\f[V],\f[R]\f[I]module\f[R]...] -Specifies the root modules to resolve in addition to the initial module. -.TP -\f[V]--add-exports\f[R] \f[I]source-module\f[R]\f[V]/\f[R]\f[I]package\f[R]\f[V]=\f[R]\f[I]target-module\f[R][\f[V],\f[R]\f[I]target-module\f[R]]* -Adds an export of \f[I]package\f[R] from \f[I]source-module\f[R] to -\f[I]target-module\f[R]. -.TP -\f[V]--class-path\f[R] \f[I]path\f[R] -Specifies the directories and archives that are searched to locate class -files. -This option overrides the path in the \f[V]CLASSPATH\f[R] environment -variable. -If the environment variable isn\[aq]t set and this option isn\[aq]t -used, then the current directory is searched. -For Linux and macOS, use a colon (\f[V]:\f[R]) to separate items in the -path. -For Windows, use a semicolon (\f[V];\f[R]) to separate items. -.TP -\f[V]--module-path\f[R] \f[I]modulepath\f[R] -Specifies where to find application modules. -For Linux and macOS, use a colon (\f[V]:\f[R]) to separate items in the -path. -For Windows, use a semicolon (\f[V];\f[R]) to separate items. -.TP -\f[V]-quiet\f[R] -Replays the valid history without displaying it. -Errors are displayed. -.TP -\f[V]-restore\f[R] -Resets the environment to the state at the start of the previous run of -the tool or to the last time a \f[V]/reset\f[R], \f[V]/reload\f[R], or -\f[V]/env\f[R] command was executed in the previous run. -The valid history since that point is replayed. -Use this option to restore a previous JShell session. -.RE -.TP -\f[V]/reset\f[R] [\f[I]options\f[R]] -Discards all entered snippets and restarts the session as follows: -.RS -.IP \[bu] 2 -Updates the environment settings with the provided options, if any. -.IP \[bu] 2 -Resets the execution state. -.IP \[bu] 2 -Runs the startup scripts. -.PP -History is not replayed. -All code that was entered is lost. -.PP -Environment settings entered on the command line or provided with a -previous \f[V]/reset\f[R], \f[V]/env\f[R], or \f[V]/reload\f[R] command -are maintained unless an \f[I]option\f[R] is entered that overwrites the -setting. -.PP -The following options are valid: -.TP -\f[V]--add-modules\f[R] \f[I]module\f[R][\f[V],\f[R]\f[I]module\f[R]...] -Specifies the root modules to resolve in addition to the initial module. -.TP -\f[V]--add-exports\f[R] \f[I]source-module\f[R]\f[V]/\f[R]\f[I]package\f[R]\f[V]=\f[R]\f[I]target-module\f[R][\f[V],\f[R]\f[I]target-module\f[R]]* -Adds an export of \f[I]package\f[R] from \f[I]source-module\f[R] to -\f[I]target-module\f[R]. -.TP -\f[V]--class-path\f[R] \f[I]path\f[R] -Specifies the directories and archives that are searched to locate class -files. -This option overrides the path in the \f[V]CLASSPATH\f[R] environment -variable. -If the environment variable isn\[aq]t set and this option isn\[aq]t -used, then the current directory is searched. -For Linux and macOS, use a colon (\f[V]:\f[R]) to separate items in the -path. -For Windows, use a semicolon (\f[V];\f[R]) to separate items. -.TP -\f[V]--module-path\f[R] \f[I]modulepath\f[R] -Specifies where to find application modules. -For Linux and macOS, use a colon (\f[V]:\f[R]) to separate items in the -path. -For Windows, use a semicolon (\f[V];\f[R]) to separate items. -.RE -.TP -\f[V]/save\f[R] [\f[I]options\f[R]] \f[I]file\f[R] -Saves snippets and commands to the file specified. -If no options are entered, then active snippets are saved. -.RS -.PP -The following options are valid: -.TP -{\f[I]name\f[R]|\f[I]id\f[R]|\f[I]startID\f[R]\f[V]-\f[R]\f[I]endID\f[R]} [{\f[I]name\f[R]|\f[I]id\f[R]|\f[I]startID\f[R]\f[V]-\f[R]\f[I]endID\f[R]}...] -Saves the snippets and commands identified by name, ID, or ID range. -For a range of IDs, provide the starting ID and ending ID separated with -a hyphen. -To provide a list, separate the items in the list with a space. -Use the \f[V]/list\f[R] command to see the IDs of the code snippets. -.TP -\f[V]-all\f[R] -Saves all snippets, including startup snippets and snippets that were -overwritten or failed. -.TP -\f[V]-history\f[R] -Saves the sequential history of all commands and snippets entered in the -current session. -.TP -\f[V]-start\f[R] -Saves the current startup settings. -If no startup scripts were provided, then an empty file is saved. -.RE -.TP -\f[V]/set\f[R] [\f[I]setting\f[R]] -Sets configuration information, including the external editor, startup -settings, and feedback mode. -This command is also used to create a custom feedback mode with -customized prompt, format, and truncation values. -If no setting is entered, then the current setting for the editor, -startup settings, and feedback mode are displayed. -.RS -.PP -The following values are valid for \f[V]setting\f[R]: -.TP -\f[V]editor\f[R] [\f[I]options\f[R]] [\f[I]command\f[R]] -Sets the command used to start an external editor when the -\f[V]/edit\f[R] command is entered. -The command can include command arguments separated by spaces. -If no command or options are entered, then the current setting is -displayed. -.RS -.PP -The following options are valid: -.TP -\f[V]-default\f[R] -Sets the editor to the default editor provided with JShell. -This option can\[aq]t be used if a command for starting an editor is -entered. -.TP -\f[V]-delete\f[R] -Sets the editor to the one in effect when the session started. -If used with the \f[V]-retain\f[R] option, then the retained editor -setting is deleted and the editor is set to the first of the following -environment variables found: \f[V]JSHELLEDITOR\f[R], \f[V]VISUAL\f[R], -or \f[V]EDITOR\f[R]. -If none of the editor environment variables are set, then this option -sets the editor to the default editor. -.RS -.PP -This option can\[aq]t be used if a command for starting an editor is -entered. -.RE -.TP -\f[V]-retain\f[R] -Saves the editor setting across sessions. -If no other option or a command is entered, then the current setting is -saved. -.TP -\f[V]-wait\f[R] -Prompts the user to indicate when editing is complete. -Otherwise control returns to JShell when the editor exits. -Use this option if the editor being used exits immediately, for example, -when an edit window already exists. -This option is valid only when a command for starting an editor is -entered. -.RE -.TP -\f[V]feedback\f[R] [\f[I]mode\f[R]] -Sets the feedback mode used to respond to input. -If no mode is entered, then the current mode is displayed. -.RS -.PP -The following modes are valid: \f[V]concise\f[R], \f[V]normal\f[R], -\f[V]silent\f[R], \f[V]verbose\f[R], and any custom mode created with -the \f[V]/set mode\f[R] command. -.RE -.TP -\f[V]format\f[R] \f[I]mode\f[R] \f[I]field\f[R] \f[V]\[dq]\f[R]\f[I]format-string\f[R]\f[V]\[dq]\f[R] \f[I]selector\f[R] -Sets the format of the feedback provided in response to input. -If no mode is entered, then the current formats for all fields for all -feedback modes are displayed. -If only a mode is entered, then the current formats for that mode are -displayed. -If only a mode and field are entered, then the current formats for that -field are displayed. -.RS -.PP -To define a format, the following arguments are required: -.TP -\f[I]mode\f[R] -Specifies a feedback mode to which the response format is applied. -Only custom modes created with the \f[V]/set mode\f[R] command can be -modified. -.TP -\f[I]field\f[R] -Specifies a context-specific field to which the response format is -applied. -The fields are described in the online help, which is accessed from -JShell using the \f[V]/help /set format\f[R] command. -.TP -\f[V]\[dq]\f[R]\f[I]format-string\f[R]\f[V]\[dq]\f[R] -Specifies the string to use as the response format for the specified -field and selector. -The structure of the format string is described in the online help, -which is accessed from JShell using the \f[V]/help /set format\f[R] -command. -.TP -\f[I]selector\f[R] -Specifies the context in which the response format is applied. -The selectors are described in the online help, which is accessed from -JShell using the \f[V]/help /set format\f[R] command. -.RE -.TP -\f[V]mode\f[R] [\f[I]mode-name\f[R]] [\f[I]existing-mode\f[R]] [\f[I]options\f[R]] -Creates a custom feedback mode with the mode name provided. -If no mode name is entered, then the settings for all modes are -displayed, which includes the mode, prompt, format, and truncation -settings. -If the name of an existing mode is provided, then the settings from the -existing mode are copied to the mode being created. -.RS -.PP -The following options are valid: -.TP -\f[V]-command\f[R]|\f[V]-quiet\f[R] -Specifies the level of feedback displayed for commands when using the -mode. -This option is required when creating a feedback mode. -Use \f[V]-command\f[R] to show information and verification feedback for -commands. -Use \f[V]-quiet\f[R] to show only essential feedback for commands, such -as error messages. -.TP -\f[V]-delete\f[R] -Deletes the named feedback mode for this session. -The name of the mode to delete is required. -To permanently delete a retained mode, use the \f[V]-retain\f[R] option -with this option. -Predefined modes can\[aq]t be deleted. -.TP -\f[V]-retain\f[R] -Saves the named feedback mode across sessions. -The name of the mode to retain is required. -.PP -Configure the new feedback mode using the \f[V]/set prompt\f[R], -\f[V]/set format\f[R], and \f[V]/set truncation\f[R] commands. -.PP -To start using the new mode, use the \f[V]/set feedback\f[R] command. -.RE -.TP -\f[V]prompt\f[R] \f[I]mode\f[R] \f[V]\[dq]\f[R]\f[I]prompt-string\f[R]\f[V]\[dq]\f[R] \f[V]\[dq]\f[R]\f[I]continuation-prompt-string\f[R]\f[V]\[dq]\f[R] -Sets the prompts for input within JShell. -If no mode is entered, then the current prompts for all feedback modes -are displayed. -If only a mode is entered, then the current prompts for that mode are -displayed. -.RS -.PP -To define a prompt, the following arguments are required: -.TP -\f[I]mode\f[R] -Specifies the feedback mode to which the prompts are applied. -Only custom modes created with the \f[V]/set mode\f[R] command can be -modified. -.TP -\f[V]\[dq]\f[R]\f[I]prompt-string\f[R]\f[V]\[dq]\f[R] -Specifies the string to use as the prompt for the first line of input. -.TP -\f[V]\[dq]\f[R]\f[I]continuation-prompt-string\f[R]\f[V]\[dq]\f[R] -Specifies the string to use as the prompt for the additional input lines -needed to complete a snippet. -.RE -.TP -\f[V]start\f[R] [\f[V]-retain\f[R]] [\f[I]file\f[R] [\f[I]file\f[R]...]|\f[I]option\f[R]] -Sets the names of the startup scripts used when the next -\f[V]/reset\f[R], \f[V]/reload\f[R], or \f[V]/env\f[R] command is -entered. -If more than one script is entered, then the scripts are run in the -order entered. -If no scripts or options are entered, then the current startup settings -are displayed. -.RS -.PP -The scripts can be local files or one of the following predefined -scripts: -.TP -\f[V]DEFAULT\f[R] -Loads the default entries, which are commonly used as imports. -.TP -\f[V]JAVASE\f[R] -Imports all Java SE packages. -.TP -\f[V]PRINTING\f[R] -Defines \f[V]print\f[R], \f[V]println\f[R], and \f[V]printf\f[R] as -\f[V]jshell\f[R] methods for use within the tool. -.TP -\f[V]TOOLING\f[R] -Defines \f[V]javac\f[R], \f[V]jar\f[R], and other methods for running -JDK tools via their command-line interface within the \f[V]jshell\f[R] -tool. -.PP -The following options are valid: -.TP -\f[V]-default\f[R] -Sets the startup settings to the default settings. -.TP -\f[V]-none\f[R] -Specifies that no startup settings are used. -.PP -Use the \f[V]-retain\f[R] option to save the start setting across -sessions. -.RE -.TP -\f[V]truncation\f[R] \f[I]mode\f[R] \f[I]length\f[R] \f[I]selector\f[R] -Sets the maximum length of a displayed value. -If no mode is entered, then the current truncation values for all -feedback modes are displayed. -If only a mode is entered, then the current truncation values for that -mode are displayed. -.RS -.PP -To define truncation values, the following arguments are required: -.TP -\f[I]mode\f[R] -Specifies the feedback mode to which the truncation value is applied. -Only custom modes created with the \f[V]/set mode\f[R] command can be -modified. -.TP -\f[I]length\f[R] -Specifies the unsigned integer to use as the maximum length for the -specified selector. -.TP -\f[I]selector\f[R] -Specifies the context in which the truncation value is applied. -The selectors are described in the online help, which is accessed from -JShell using the \f[V]/help /set truncation\f[R] command. -.RE -.RE -.TP -\f[V]/types\f[R] [\f[I]option\f[R]] -Displays classes, interfaces, and enums that were entered. -If no option is entered, then all current active classes, interfaces, -and enums are displayed. -.RS -.PP -The following options are valid: -.TP -{\f[I]name\f[R]|\f[I]id\f[R]|\f[I]startID\f[R]\f[V]-\f[R]\f[I]endID\f[R]} [{\f[I]name\f[R]|\f[I]id\f[R]|\f[I]startID\f[R]\f[V]-\f[R]\f[I]endID\f[R]}...] -Displays information for classes, interfaces, and enums identified by -name, ID, or ID range. -For a range of IDs, provide the starting ID and ending ID separated with -a hyphen. -To provide a list, separate the items in the list with a space. -Use the \f[V]/list\f[R] command to see the IDs of the code snippets. -.TP -\f[V]-all\f[R] -Displays information for all classes, interfaces, and enums, including -those added when JShell was started, and classes, interfaces, and enums -that failed, were overwritten, or were dropped. -.TP -\f[V]-start\f[R] -Displays information for startup classes, interfaces, and enums that -were added when JShell was started. -.RE -.TP -\f[V]/vars\f[R] [\f[I]option\f[R]] -Displays the name, type, and value of variables that were entered. -If no option is entered, then all current active variables are -displayed. -.RS -.PP -The following options are valid: -.TP -{\f[I]name\f[R]|\f[I]id\f[R]|\f[I]startID\f[R]\f[V]-\f[R]\f[I]endID\f[R]} [{\f[I]name\f[R]|\f[I]id\f[R]|\f[I]startID\f[R]\f[V]-\f[R]\f[I]endID\f[R]}...] -Displays information for variables identified by name, ID, or ID range. -For a range of IDs, provide the starting ID and ending ID separated with -a hyphen. -To provide a list, separate the items in the list with a space. -Use the \f[V]/list\f[R] command to see the IDs of the code snippets. -.TP -\f[V]-all\f[R] -Displays information for all variables, including those added when -JShell was started, and variables that failed, were overwritten, or were -dropped. -.TP -\f[V]-start\f[R] -Displays information for startup variables that were added when JShell -was started. -.RE -.TP -\f[V]/?\f[R] -Same as the \f[V]/help\f[R] command. -.TP -\f[V]/!\f[R] -Reruns the last snippet. -.TP -\f[V]/\f[R]{\f[I]name\f[R]|\f[I]id\f[R]|\f[I]startID\f[R]\f[V]-\f[R]\f[I]endID\f[R]} [{\f[I]name\f[R]|\f[I]id\f[R]|\f[I]startID\f[R]\f[V]-\f[R]\f[I]endID\f[R]}...] -Reruns the snippets identified by ID, range of IDs, or name. -For a range of IDs, provide the starting ID and ending ID separated with -a hyphen. -To provide a list, separate the items in the list with a space. -The first item in the list must be an ID or ID range. -Use the \f[V]/list\f[R] command to see the IDs of the code snippets. -.TP -\f[V]/-\f[R]\f[I]n\f[R] -Reruns the -\f[I]n\f[R]th previous snippet. -For example, if 15 code snippets were entered, then \f[V]/-4\f[R] runs -the 11th snippet. -Commands aren\[aq]t included in the count. -.SH INPUT SHORTCUTS -.PP -The following shortcuts are available for entering commands and snippets -in JShell. -.SS Tab completion -.TP -\f[B]<tab>\f[R] -When entering snippets, commands, subcommands, command arguments, or -command options, use the Tab key to automatically complete the item. -If the item can\[aq]t be determined from what was entered, then possible -options are provided. -.RS -.PP -When entering a method call, use the Tab key after the method call\[aq]s -opening parenthesis to see the parameters for the method. -If the method has more than one signature, then all signatures are -displayed. -Pressing the Tab key a second time displays the description of the -method and the parameters for the first signature. -Continue pressing the Tab key for a description of any additional -signatures. -.RE -.TP -\f[B]Shift+<Tab> V\f[R] -After entering a complete expression, use this key sequence to convert -the expression to a variable declaration of a type determined by the -type of the expression. -.TP -\f[B]Shift+<Tab> M\f[R] -After entering a complete expression or statement, use this key sequence -to convert the expression or statement to a method declaration. -If an expression is entered, the return type is based on the type of the -expression. -.TP -\f[B]Shift+<Tab> I\f[R] -When an identifier is entered that can\[aq]t be resolved, use this key -sequence to show possible imports that resolve the identifier based on -the content of the specified class path. -.SS Command abbreviations -.PP -An abbreviation of a command is accepted if the abbreviation uniquely -identifies a command. -For example, \f[V]/l\f[R] is recognized as the \f[V]/list\f[R] command. -However, \f[V]/s\f[R] isn\[aq]t a valid abbreviation because it -can\[aq]t be determined if the \f[V]/set\f[R] or \f[V]/save\f[R] command -is meant. -Use \f[V]/se\f[R] for the \f[V]/set\f[R] command or \f[V]/sa\f[R] for -the \f[V]/save\f[R] command. -.PP -Abbreviations are also accepted for subcommands, command arguments, and -command options. -For example, use \f[V]/m -a\f[R] to display all methods. -.SS History navigation -.PP -A history of what was entered is maintained across sessions. -Use the up and down arrows to scroll through commands and snippets from -the current and past sessions. -Use the Ctrl key with the up and down arrows to skip all but the first -line of multiline snippets. -.SS History search -.PP -Use the Ctrl+R key combination to search the history for the string -entered. -The prompt changes to show the string and the match. -Ctrl+R searches backwards from the current location in the history -through earlier entries. -Ctrl+S searches forward from the current location in the history though -later entries. -.SH INPUT EDITING -.PP -The editing capabilities of JShell are similar to that of other common -shells. -Keyboard keys and key combinations provide line editing shortcuts. -The Ctrl key and Meta key are used in key combinations. -If your keyboard doesn\[aq]t have a Meta key, then the Alt key is often -mapped to provide Meta key functionality. -.PP -Line Editing Shortcuts -.TS -tab(@); -l l. -T{ -Key or Key Combination -T}@T{ -Action -T} -_ -T{ -Return -T}@T{ -Enter the current line. -T} -T{ -Left arrow -T}@T{ -Move the cursor to the left one character. -T} -T{ -Right arrow Move -T}@T{ -the cursor to the right one character. -T} -T{ -Ctrl+A -T}@T{ -Move the cursor to the beginning of the line. -T} -T{ -Ctrl+E -T}@T{ -Move the cursor to the end of the line. -T} -T{ -Meta+B -T}@T{ -Move the cursor to the left one word. -T} -T{ -Meta+F -T}@T{ -Move the cursor to the right one word. -T} -T{ -Delete -T}@T{ -Delete the character under the cursor. -T} -T{ -Backspace -T}@T{ -Delete the character before the cursor. -T} -T{ -Ctrl+K -T}@T{ -Delete the text from the cursor to the end of the line. -T} -T{ -Meta+D -T}@T{ -Delete the text from the cursor to the end of the word. -T} -T{ -Ctrl+W -T}@T{ -Delete the text from the cursor to the previous white space. -T} -T{ -Ctrl+Y -T}@T{ -Paste the most recently deleted text into the line. -T} -T{ -Meta+Y -T}@T{ -After Ctrl+Y, press to cycle through the previously deleted text. -T} -.TE -.SH EXAMPLE OF STARTING AND STOPPING A JSHELL SESSION -.PP -JShell is provided with the JDK. -To start a session, enter \f[V]jshell\f[R] on the command line. -A welcome message is printed, and a prompt for entering commands and -snippets is provided. -.IP -.nf -\f[CB] -% jshell -| Welcome to JShell -- Version 9 -| For an introduction type: /help intro - -jshell> -\f[R] -.fi -.PP -To see which snippets were automatically loaded when JShell started, use -the \f[V]/list -start\f[R] command. -The default startup snippets are import statements for common packages. -The ID for each snippet begins with the letter \f[I]s\f[R], which -indicates it\[aq]s a startup snippet. -.IP -.nf -\f[CB] -jshell> /list -start - - s1 : import java.io.*; - s2 : import java.math.*; - s3 : import java.net.*; - s4 : import java.nio.file.*; - s5 : import java.util.*; - s6 : import java.util.concurrent.*; - s7 : import java.util.function.*; - s8 : import java.util.prefs.*; - s9 : import java.util.regex.*; - s10 : import java.util.stream.*; - -jshell> -\f[R] -.fi -.PP -To end the session, use the \f[V]/exit\f[R] command. -.IP -.nf -\f[CB] -jshell> /exit -| Goodbye - -% -\f[R] -.fi -.SH EXAMPLE OF ENTERING SNIPPETS -.PP -Snippets are Java statements, variable definitions, method definitions, -class definitions, import statements, and expressions. -Terminating semicolons are automatically added to the end of a completed -snippet if they\[aq]re missing. -.PP -The following example shows two variables and a method being defined, -and the method being run. -Note that a scratch variable is automatically created to hold the result -because no variable was provided. -.IP -.nf -\f[CB] -jshell> int a=4 -a ==> 4 - -jshell> int b=8 -b ==> 8 - -jshell> int square(int i1) { - ...> return i1 * i1; - ...> } -| created method square(int) - -jshell> square(b) -$5 ==> 64 -\f[R] -.fi -.SH EXAMPLE OF CHANGING SNIPPETS -.PP -Change the definition of a variable, method, or class by entering it -again. -.PP -The following examples shows a method being defined and the method run: -.IP -.nf -\f[CB] -jshell> String grade(int testScore) { - ...> if (testScore >= 90) { - ...> return \[dq]Pass\[dq]; - ...> } - ...> return \[dq]Fail\[dq]; - ...> } -| created method grade(int) - -jshell> grade(88) -$3 ==> \[dq]Fail\[dq] -\f[R] -.fi -.PP -To change the method \f[V]grade\f[R] to allow more students to pass, -enter the method definition again and change the pass score to -\f[V]80\f[R]. -Use the up arrow key to retrieve the previous entries to avoid having to -reenter them and make the change in the \f[V]if\f[R] statement. -The following example shows the new definition and reruns the method to -show the new result: -.IP -.nf -\f[CB] -jshell> String grade(int testScore) { - ...> if (testScore >= 80) { - ...> return \[dq]Pass\[dq]; - ...> } - ...> return \[dq]Fail\[dq]; - ...> } -| modified method grade(int) - -jshell> grade(88) -$5 ==> \[dq]Pass\[dq] -\f[R] -.fi -.PP -For snippets that are more than a few lines long, or to make more than a -few changes, use the \f[V]/edit\f[R] command to open the snippet in an -editor. -After the changes are complete, close the edit window to return control -to the JShell session. -The following example shows the command and the feedback provided when -the edit window is closed. -The \f[V]/list\f[R] command is used to show that the pass score was -changed to \f[V]85\f[R]. -.IP -.nf -\f[CB] -jshell> /edit grade -| modified method grade(int) -jshell> /list grade - - 6 : String grade(int testScore) { - if (testScore >= 85) { - return \[dq]Pass\[dq]; - } - return \[dq]Fail\[dq]; - } -\f[R] -.fi -.SH EXAMPLE OF CREATING A CUSTOM FEEDBACK MODE -.PP -The feedback mode determines the prompt that\[aq]s displayed, the -feedback messages that are provided as snippets are entered, and the -maximum length of a displayed value. -Predefined feedback modes are provided. -Commands for creating custom feedback modes are also provided. -.PP -Use the \f[V]/set mode\f[R] command to create a new feedback mode. -In the following example, the new mode \f[V]mymode\f[R], is based on the -predefined feedback mode, \f[V]normal\f[R], and verifying command -feedback is displayed: -.IP -.nf -\f[CB] -jshell> /set mode mymode normal -command -| Created new feedback mode: mymode -\f[R] -.fi -.PP -Because the new mode is based on the \f[V]normal\f[R] mode, the prompts -are the same. -The following example shows how to see what prompts are used and then -changes the prompts to custom strings. -The first string represents the standard JShell prompt. -The second string represents the prompt for additional lines in -multiline snippets. -.IP -.nf -\f[CB] -jshell> /set prompt mymode -| /set prompt mymode \[dq]\[rs]njshell> \[dq] \[dq] ...> \[dq] - -jshell> /set prompt mymode \[dq]\[rs]nprompt$ \[dq] \[dq] continue$ \[dq] -\f[R] -.fi -.PP -The maximum length of a displayed value is controlled by the truncation -setting. -Different types of values can have different lengths. -The following example sets an overall truncation value of 72, and a -truncation value of 500 for variable value expressions: -.IP -.nf -\f[CB] -jshell> /set truncation mymode 72 - -jshell> /set truncation mymode 500 varvalue -\f[R] -.fi -.PP -The feedback displayed after snippets are entered is controlled by the -format setting and is based on the type of snippet entered and the -action taken for that snippet. -In the predefined mode \f[V]normal\f[R], the string \f[V]created\f[R] is -displayed when a method is created. -The following example shows how to change that string to -\f[V]defined\f[R]: -.IP -.nf -\f[CB] -jshell> /set format mymode action \[dq]defined\[dq] added-primary -\f[R] -.fi -.PP -Use the \f[V]/set feedback\f[R] command to start using the feedback mode -that was just created. -The following example shows the custom mode in use: -.IP -.nf -\f[CB] -jshell> /set feedback mymode -| Feedback mode: mymode - -prompt$ int square (int num1){ - continue$ return num1*num1; - continue$ } -| defined method square(int) - -prompt$ -\f[R] -.fi diff --git a/src/jdk.jshell/share/man/jshell.md b/src/jdk.jshell/share/man/jshell.md new file mode 100644 index 00000000000..b9f9fe577cf --- /dev/null +++ b/src/jdk.jshell/share/man/jshell.md @@ -0,0 +1,1042 @@ +--- +# Copyright (c) 2017, 2023, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# This code is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 only, as +# published by the Free Software Foundation. +# +# This code is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# version 2 for more details (a copy is included in the LICENSE file that +# accompanied this code). +# +# You should have received a copy of the GNU General Public License version +# 2 along with this work; if not, write to the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +# or visit www.oracle.com if you need additional information or have any +# questions. +# + +title: 'JSHELL(1) JDK @@VERSION_SHORT@@ | JDK Commands' +date: @@COPYRIGHT_YEAR@@ +lang: en +--- + +## Name + +jshell - interactively evaluate declarations, statements, and expressions of +the Java programming language in a read-eval-print loop (REPL) + +## Synopsis + +`jshell` \[*options*\] \[*load-files*\] + +*options* +: Command-line options, separated by spaces. See [Options for jshell]. + +*load-files* +: One or more scripts to run when the tool is started. Scripts can contain + any valid code snippets or JShell commands. + + The script can be a local file or one of following predefined scripts: + + `DEFAULT` + : Loads the default entries, which are commonly used as imports. + + `JAVASE` + : Imports all Java SE packages. + + `PRINTING` + : Defines `print`, `println`, and `printf` as `jshell` methods for use + within the tool. + + `TOOLING` + : Defines `javac`, `jar`, and other methods for running JDK tools via + their command-line interface within the `jshell` tool. + + For more than one script, use a space to separate the names. Scripts are + run in the order in which they're entered on the command line. Command-line + scripts are run after startup scripts. To run a script after JShell is + started, use the `/open` command. + + To accept input from standard input and suppress the interactive I/O, enter + a hyphen (-) for *load-files*. This option enables the use of the `jshell` + tool in pipe chains. + +## Description + +JShell provides a way to interactively evaluate declarations, statements, and +expressions of the Java programming language, making it easier to learn the +language, explore unfamiliar code and APIs, and prototype complex code. Java +statements, variable definitions, method definitions, class definitions, import +statements, and expressions are accepted. The bits of code entered are called +snippets. + +As snippets are entered, they're evaluated, and feedback is provided. Feedback +varies from the results and explanations of actions to nothing, depending on +the snippet entered and the feedback mode chosen. Errors are described +regardless of the feedback mode. Start with the verbose mode to get the most +feedback while learning the tool. + +Command-line options are available for configuring the initial environment when +JShell is started. Within JShell, commands are available for modifying the +environment as needed. + +Existing snippets can be loaded from a file to initialize a JShell session, or +at any time within a session. Snippets can be modified within the session to +try out different variations and make corrections. To keep snippets for later +use, save them to a file. + +## Options for jshell + +`--add-exports` *module*/*package* +: Specifies a package to be considered as exported from its defining module. + +`--add-modules` *module*\[`,`*module*...\] +: Specifies the root modules to resolve in addition to the initial module. + +`-C`*flag* +: passes *flag* to the Java compiler inside JShell. For example, `-C-Xlint` + enables all the recommended lint warnings, and `-C--release=<N>` compiles + for Java SE N, as if --release N was specified. + +`--class-path` *path* +: Specifies the directories and archives that are searched to locate class + files. This option overrides the path in the `CLASSPATH` environment + variable. If the environment variable isn't set and this option isn't used, + then the current directory is searched. For Linux and macOS, use a colon + (:) to separate items in the path. For Windows, use a semicolon (;) to + separate items. + +`--enable-preview` +: Allows code to depend on the preview features of this release. + +`--execution` *specification* +: Specifies an alternate execution engine, where *specification* is an + ExecutionControl spec. See the documentation of the package jdk.jshell.spi + for the syntax of the spec. + +`--feedback` *mode* +: Sets the initial level of feedback provided in response to what's entered. + The initial level can be overridden within a session by using the + `/set feedback` *mode* command. The default is `normal`. + + The following values are valid for *mode*: + + `verbose` + : Provides detailed feedback for entries. Additional information about + the action performed is displayed after the result of the action. The + next prompt is separated from the feedback by a blank line. + + `normal` + : Provides an average amount of feedback. The next prompt is separated + from the feedback by a blank line. + + `concise` + : Provides minimal feedback. The next prompt immediately follows the code + snippet or feedback. + + `silent` + : Provides no feedback. The next prompt immediately follows the code + snippet. + + *custom* + : Provides custom feedback based on how the mode is defined. Custom + feedback modes are created within JShell by using the `/set mode` + command. + +`--help` or `-h` or `-?` +: Prints a summary of standard options and exits the tool. + +`--help-extra` or `-X` +: Prints a summary of nonstandard options and exits the tool. Nonstandard + options are subject to change without notice. + +`-J`*flag* +: passes *flag* to the runtime system, but has no effect on the execution of + code snippets. To specify flags that affect the execution of code snippets, + use `-R`*flag*. Alternatively, use `-J`*flag* with `--execution local`. + +`--module-path` *modulepath* +: Specifies where to find application modules. For Linux and macOS, use a + colon (:) to separate items in the path. For Windows, use a semicolon (;) + to separate items. + +`--no-startup` +: Prevents startup scripts from running when JShell starts. Use this option + to run only the scripts entered on the command line when JShell is started, + or to start JShell without any preloaded information if no scripts are + entered. This option can't be used if the `--startup` option is used. + +`-q` +: Sets the feedback mode to `concise`, which is the same as entering + `--feedback concise`. + +`-R`*flag* +: passes *flag* to the runtime system only when code snippets are executed. + For example, `-R-Dfoo=bar` means that execution of the snippet + `System.getProperty("foo")` will return `"bar"`. + +`-s` +: Sets the feedback mode to `silent`, which is the same as entering + `--feedback silent`. + +`--show-version` +: Prints version information and enters the tool. + +`--startup` *file* +: Overrides the default startup script for this session. The script can + contain any valid code snippets or commands. + + The script can be a local file or one of the following predefined scripts: + + `DEFAULT` + : Loads the default entries, which are commonly used as imports. + + `JAVASE` + : Imports all Java SE packages. + + `PRINTING` + : Defines `print`, `println`, and `printf` as `jshell` methods for use + within the tool. + + `TOOLING` + : Defines `javac`, `jar`, and other methods for running JDK tools via + their command-line interface within the `jshell` tool. + + For more than one script, provide a separate instance of this option for + each script. Startup scripts are run when JShell is first started and when + the session is restarted with the `/reset`, `/reload`, or `/env` command. + Startup scripts are run in the order in which they're entered on the + command line. + + This option can't be used if the `--no-startup` option is used. + +`-v` +: Sets the feedback mode to `verbose`, which is the same as entering + `--feedback verbose`. + +`--version` +: Prints version information and exits the tool. + +## jshell Commands + +Within the `jshell` tool, commands are used to modify the environment and +manage code snippets. + +`/drop` {*name*\|*id*\|*startID*`-`*endID*} \[{*name*\|*id*\|*startID*`-`*endID*}...\] +: Drops snippets identified by name, ID, or ID range, making them inactive. + For a range of IDs, provide the starting ID and ending ID separated with a + hyphen. To provide a list, separate the items in the list with a space. Use + the `/list` command to see the IDs of code snippets. + +`/edit` \[*option*\] +: Opens an editor. If no option is entered, then the editor opens with the + active snippets. + + The following options are valid: + + {*name*\|*id*\|*startID*`-`*endID*} \[{*name*\|*id*\|*startID*`-`*endID*}...\] + : Opens the editor with the snippets identified by name, ID, or ID range. + For a range of IDs, provide the starting ID and ending ID separated + with a hyphen. To provide a list, separate the items in the list with a + space. Use the `/list` command to see the IDs of code snippets. + + `-all` + : Opens the editor with all snippets, including startup snippets and + snippets that failed, were overwritten, or were dropped. + + `-start` + : Opens the editor with startup snippets that were evaluated when JShell + was started. + + To exit edit mode, close the editor window, or respond to the prompt + provided if the `-wait` option was used when the editor was set. + + Use the `/set editor` command to specify the editor to use. If no editor is + set, then the following environment variables are checked in order: + `JSHELLEDITOR`, `VISUAL`, and `EDITOR`. If no editor is set in JShell and + none of the editor environment variables is set, then a simple default + editor is used. + +`/env` \[*options*\] +: Displays the environment settings, or updates the environment settings and + restarts the session. If no option is entered, then the current environment + settings are displayed. If one or more options are entered, then the + session is restarted as follows: + + - Updates the environment settings with the provided options. + + - Resets the execution state. + + - Runs the startup scripts. + + - Silently replays the history in the order entered. The history includes + all valid snippets or `/drop` commands entered at the `jshell` prompt, + in scripts entered on the command line, or scripts entered with the + `/open` command. + + Environment settings entered on the command line or provided with a + previous `/reset`, `/env`, or `/reload` command are maintained unless an + *option* is entered that overwrites the setting. + + The following options are valid: + + `--add-modules` *module*\[`,`*module*...\] + : Specifies the root modules to resolve in addition to the initial + module. + + `--add-exports` *source-module*`/`*package*`=`*target-module*\[`,`*target-module*\]\* + : Adds an export of *package* from *source-module* to *target-module*. + + `--class-path` *path* + : Specifies the directories and archives that are searched to locate + class files. This option overrides the path in the `CLASSPATH` + environment variable. If the environment variable isn't set and this + option isn't used, then the current directory is searched. For Linux + and macOS, use a colon (`:`) to separate items in the path. For Windows, + use a semicolon (`;`) to separate items. + + `--module-path` *modulepath* + : Specifies where to find application modules. For Linux and macOS, use + a colon (`:`) to separate items in the path. For Windows, use a + semicolon (`;`) to separate items. + +`/exit` \[*integer-expression-snippet*\] +: Exits the tool. If no snippet is entered, the exit status is zero. If a + snippet is entered and the result of the snippet is an integer, the result + is used as the exit status. If an error occurs, or the result of the + snippet is not an integer, an error is displayed and the tool remains + active. + +`/history` +: Displays what was entered in this session. + +`/help` \[*command*\|*subject*\] +: Displays information about commands and subjects. If no options are + entered, then a summary of information for all commands and a list of + available subjects are displayed. If a valid command is provided, then + expanded information for that command is displayed. If a valid subject is + entered, then information about that subject is displayed. + + The following values for *subject* are valid: + + `context` + : Describes the options that are available for configuring the + environment. + + `intro` + : Provides an introduction to the tool. + + `shortcuts` + : Describes keystrokes for completing commands and snippets. See [Input + Shortcuts]. + +`/imports` +: Displays the current active imports, including those from the startup + scripts and scripts that were entered on the command line when JShell was + started. + +`/list` \[*option*\] +: Displays a list of snippets and their IDs. If no option is entered, then + all active snippets are displayed, but startup snippets aren't. + + The following options are valid: + + {*name*\|*id*\|*startID*`-`*endID*} \[{*name*\|*id*\|*startID*`-`*endID*}...\] + : Displays the snippets identified by name, ID, or ID range. For a range + of IDs, provide the starting ID and ending ID separated with a hyphen. + To provide a list, separate the items in the list with a space. + + `-all` + : Displays all snippets, including startup snippets and snippets that + failed, were overwritten, or were dropped. IDs that begin with `s` are + startup snippets. IDs that begin with `e` are snippets that failed. + + `-start` + : Displays startup snippets that were evaluated when JShell was started. + +`/methods` \[*option*\] +: Displays information about the methods that were entered. If no option is + entered, then the name, parameter types, and return type of all active + methods are displayed. + + The following options are valid: + + {*name*\|*id*\|*startID*`-`*endID*} \[{*name*\|*id*\|*startID*`-`*endID*}...\] + : Displays information for methods identified by name, ID, or ID range. + For a range of IDs, provide the starting ID and ending ID separated + with a hyphen. To provide a list, separate the items in the list with a + space. Use the `/list` command to see the IDs of code snippets. + + `-all` + : Displays information for all methods, including those added when JShell + was started, and methods that failed, were overwritten, or were + dropped. + + `-start` + : Displays information for startup methods that were added when JShell + was started. + +`/open` *file* +: Opens the script specified and reads the snippets into the tool. The script + can be a local file or one of the following predefined scripts: + + `DEFAULT` + : Loads the default entries, which are commonly used as imports. + + `JAVASE` + : Imports all Java SE packages. + + `PRINTING` + : Defines `print`, `println`, and `printf` as `jshell` methods for use + within the tool. + + `TOOLING` + : Defines `javac`, `jar`, and other methods for running JDK tools via + their command-line interface within the `jshell` tool. + +`/reload` \[*options*\] +: Restarts the session as follows: + + - Updates the environment settings with the provided options, if any. + + - Resets the execution state. + + - Runs the startup scripts. + + - Replays the history in the order entered. The history includes all + valid snippets or `/drop` commands entered at the `jshell` prompt, in + scripts entered on the command line, or scripts entered with the + `/open` command. + + Environment settings entered on the command line or provided with a + previous `/reset`, `/env`, or `/reload` command are maintained unless an + *option* is entered that overwrites the setting. + + The following options are valid: + + `--add-modules` *module*\[`,`*module*...\] + : Specifies the root modules to resolve in addition to the initial + module. + + `--add-exports` *source-module*`/`*package*`=`*target-module*\[`,`*target-module*\]\* + : Adds an export of *package* from *source-module* to *target-module*. + + `--class-path` *path* + : Specifies the directories and archives that are searched to locate + class files. This option overrides the path in the `CLASSPATH` + environment variable. If the environment variable isn't set and this + option isn't used, then the current directory is searched. For Linux + and macOS, use a colon (`:`) to separate items in the path. For + Windows, use a semicolon (`;`) to separate items. + + `--module-path` *modulepath* + : Specifies where to find application modules. For Linux and macOS, use + a colon (`:`) to separate items in the path. For Windows, use a + semicolon (`;`) to separate items. + + `-quiet` + : Replays the valid history without displaying it. Errors are displayed. + + `-restore` + : Resets the environment to the state at the start of the previous run of + the tool or to the last time a `/reset`, `/reload`, or `/env` command + was executed in the previous run. The valid history since that point is + replayed. Use this option to restore a previous JShell session. + +`/reset` \[*options*\] +: Discards all entered snippets and restarts the session as follows: + + - Updates the environment settings with the provided options, if any. + + - Resets the execution state. + + - Runs the startup scripts. + + History is not replayed. All code that was entered is lost. + + Environment settings entered on the command line or provided with a + previous `/reset`, `/env`, or `/reload` command are maintained unless an + *option* is entered that overwrites the setting. + + The following options are valid: + + `--add-modules` *module*\[`,`*module*...\] + : Specifies the root modules to resolve in addition to the initial + module. + + `--add-exports` *source-module*`/`*package*`=`*target-module*\[`,`*target-module*\]\* + : Adds an export of *package* from *source-module* to *target-module*. + + `--class-path` *path* + : Specifies the directories and archives that are searched to locate + class files. This option overrides the path in the `CLASSPATH` + environment variable. If the environment variable isn't set and this + option isn't used, then the current directory is searched. For Linux + and macOS, use a colon (`:`) to separate items in the path. For + Windows, use a semicolon (`;`) to separate items. + + `--module-path` *modulepath* + : Specifies where to find application modules. For Linux and macOS, use + a colon (`:`) to separate items in the path. For Windows, use a + semicolon (`;`) to separate items. + +`/save` \[*options*\] *file* +: Saves snippets and commands to the file specified. If no options are + entered, then active snippets are saved. + + The following options are valid: + + {*name*\|*id*\|*startID*`-`*endID*} \[{*name*\|*id*\|*startID*`-`*endID*}...\] + : Saves the snippets and commands identified by name, ID, or ID range. + For a range of IDs, provide the starting ID and ending ID separated + with a hyphen. To provide a list, separate the items in the list with a + space. Use the `/list` command to see the IDs of the code snippets. + + `-all` + : Saves all snippets, including startup snippets and snippets that were + overwritten or failed. + + `-history` + : Saves the sequential history of all commands and snippets entered in + the current session. + + `-start` + : Saves the current startup settings. If no startup scripts were + provided, then an empty file is saved. + +`/set` \[*setting*\] +: Sets configuration information, including the external editor, startup + settings, and feedback mode. This command is also used to create a custom + feedback mode with customized prompt, format, and truncation values. If no + setting is entered, then the current setting for the editor, startup + settings, and feedback mode are displayed. + + The following values are valid for `setting`: + + `editor` \[*options*\] \[*command*\] + : Sets the command used to start an external editor when the `/edit` + command is entered. The command can include command arguments separated + by spaces. If no command or options are entered, then the current + setting is displayed. + + The following options are valid: + + `-default` + : Sets the editor to the default editor provided with JShell. This + option can't be used if a command for starting an editor is + entered. + + `-delete` + : Sets the editor to the one in effect when the session started. If + used with the `-retain` option, then the retained editor setting is + deleted and the editor is set to the first of the following + environment variables found: `JSHELLEDITOR`, `VISUAL`, or `EDITOR`. + If none of the editor environment variables are set, then this + option sets the editor to the default editor. + + This option can't be used if a command for starting an editor is + entered. + + `-retain` + : Saves the editor setting across sessions. If no other option or a + command is entered, then the current setting is saved. + + `-wait` + : Prompts the user to indicate when editing is complete. Otherwise + control returns to JShell when the editor exits. Use this option if + the editor being used exits immediately, for example, when an edit + window already exists. This option is valid only when a command for + starting an editor is entered. + + `feedback` \[*mode*\] + : Sets the feedback mode used to respond to input. If no mode is entered, + then the current mode is displayed. + + The following modes are valid: `concise`, `normal`, `silent`, + `verbose`, and any custom mode created with the `/set mode` command. + + `format` *mode* *field* `"`*format-string*`"` *selector* + : Sets the format of the feedback provided in response to input. If no + mode is entered, then the current formats for all fields for all + feedback modes are displayed. If only a mode is entered, then the + current formats for that mode are displayed. If only a mode and field + are entered, then the current formats for that field are displayed. + + To define a format, the following arguments are required: + + *mode* + : Specifies a feedback mode to which the response format is applied. + Only custom modes created with the `/set mode` command can be + modified. + + *field* + : Specifies a context-specific field to which the response format is + applied. The fields are described in the online help, which is + accessed from JShell using the `/help /set format` command. + + `"`*format-string*`"` + : Specifies the string to use as the response format for the + specified field and selector. The structure of the format string is + described in the online help, which is accessed from JShell using + the `/help /set format` command. + + *selector* + : Specifies the context in which the response format is applied. The + selectors are described in the online help, which is accessed from + JShell using the `/help /set format` command. + + `mode` \[*mode-name*\] \[*existing-mode*\] \[*options*\] + : Creates a custom feedback mode with the mode name provided. If no mode + name is entered, then the settings for all modes are displayed, which + includes the mode, prompt, format, and truncation settings. If the name + of an existing mode is provided, then the settings from the existing + mode are copied to the mode being created. + + The following options are valid: + + `-command`\|`-quiet` + : Specifies the level of feedback displayed for commands when using + the mode. This option is required when creating a feedback mode. + Use `-command` to show information and verification feedback for + commands. Use `-quiet` to show only essential feedback for + commands, such as error messages. + + `-delete` + : Deletes the named feedback mode for this session. The name of the + mode to delete is required. To permanently delete a retained mode, + use the `-retain` option with this option. Predefined modes can't + be deleted. + + `-retain` + : Saves the named feedback mode across sessions. The name of the mode + to retain is required. + + Configure the new feedback mode using the `/set prompt`, `/set format`, + and `/set truncation` commands. + + To start using the new mode, use the `/set feedback` command. + + `prompt` *mode* `"`*prompt-string*`"` `"`*continuation-prompt-string*`"` + : Sets the prompts for input within JShell. If no mode is entered, then + the current prompts for all feedback modes are displayed. If only a + mode is entered, then the current prompts for that mode are displayed. + + To define a prompt, the following arguments are required: + + *mode* + : Specifies the feedback mode to which the prompts are applied. Only + custom modes created with the `/set mode` command can be modified. + + `"`*prompt-string*`"` + : Specifies the string to use as the prompt for the first line of + input. + + `"`*continuation-prompt-string*`"` + : Specifies the string to use as the prompt for the additional input + lines needed to complete a snippet. + + `start` \[`-retain`\] \[*file* \[*file*...\]\|*option*\] + : Sets the names of the startup scripts used when the next `/reset`, + `/reload`, or `/env` command is entered. If more than one script is + entered, then the scripts are run in the order entered. If no scripts + or options are entered, then the current startup settings are + displayed. + + The scripts can be local files or one of the following predefined + scripts: + + `DEFAULT` + : Loads the default entries, which are commonly used as imports. + + `JAVASE` + : Imports all Java SE packages. + + `PRINTING` + : Defines `print`, `println`, and `printf` as `jshell` methods for + use within the tool. + + `TOOLING` + : Defines `javac`, `jar`, and other methods for running JDK tools via + their command-line interface within the `jshell` tool. + + The following options are valid: + + `-default` + : Sets the startup settings to the default settings. + + `-none` + : Specifies that no startup settings are used. + + Use the `-retain` option to save the start setting across sessions. + + `truncation` *mode* *length* *selector* + : Sets the maximum length of a displayed value. If no mode is entered, + then the current truncation values for all feedback modes are + displayed. If only a mode is entered, then the current truncation + values for that mode are displayed. + + To define truncation values, the following arguments are required: + + *mode* + : Specifies the feedback mode to which the truncation value is + applied. Only custom modes created with the `/set mode` command can + be modified. + + *length* + : Specifies the unsigned integer to use as the maximum length for the + specified selector. + + *selector* + : Specifies the context in which the truncation value is applied. The + selectors are described in the online help, which is accessed from + JShell using the `/help /set truncation` command. + +`/types` \[*option*\] +: Displays classes, interfaces, and enums that were entered. If no option is + entered, then all current active classes, interfaces, and enums are + displayed. + + The following options are valid: + + {*name*\|*id*\|*startID*`-`*endID*} \[{*name*\|*id*\|*startID*`-`*endID*}...\] + : Displays information for classes, interfaces, and enums identified by + name, ID, or ID range. For a range of IDs, provide the starting ID and + ending ID separated with a hyphen. To provide a list, separate the + items in the list with a space. Use the `/list` command to see the IDs + of the code snippets. + + `-all` + : Displays information for all classes, interfaces, and enums, including + those added when JShell was started, and classes, interfaces, and enums + that failed, were overwritten, or were dropped. + + `-start` + : Displays information for startup classes, interfaces, and enums that + were added when JShell was started. + +`/vars` \[*option*\] +: Displays the name, type, and value of variables that were entered. If no + option is entered, then all current active variables are displayed. + + The following options are valid: + + {*name*\|*id*\|*startID*`-`*endID*} \[{*name*\|*id*\|*startID*`-`*endID*}...\] + : Displays information for variables identified by name, ID, or ID range. + For a range of IDs, provide the starting ID and ending ID separated + with a hyphen. To provide a list, separate the items in the list with a + space. Use the `/list` command to see the IDs of the code snippets. + + `-all` + : Displays information for all variables, including those added when + JShell was started, and variables that failed, were overwritten, or + were dropped. + + `-start` + : Displays information for startup variables that were added when JShell + was started. + +`/?` +: Same as the `/help` command. + +`/!` +: Reruns the last snippet. + +`/`{*name*\|*id*\|*startID*`-`*endID*} \[{*name*\|*id*\|*startID*`-`*endID*}...\] +: Reruns the snippets identified by ID, range of IDs, or name. For a range of + IDs, provide the starting ID and ending ID separated with a hyphen. To + provide a list, separate the items in the list with a space. The first item + in the list must be an ID or ID range. Use the `/list` command to see the + IDs of the code snippets. + +`/-`*n* +: Reruns the -*n*th previous snippet. For example, if 15 code snippets were + entered, then `/-4` runs the 11th snippet. Commands aren't included in the + count. + +## Input Shortcuts + +The following shortcuts are available for entering commands and snippets in +JShell. + +### Tab completion + +**\<tab\>** +: When entering snippets, commands, subcommands, command arguments, or + command options, use the Tab key to automatically complete the item. If the + item can't be determined from what was entered, then possible options are + provided. + + When entering a method call, use the Tab key after the method call's + opening parenthesis to see the parameters for the method. If the method has + more than one signature, then all signatures are displayed. Pressing the + Tab key a second time displays the description of the method and the + parameters for the first signature. Continue pressing the Tab key for a + description of any additional signatures. + +**Shift+\<Tab\> V** +: After entering a complete expression, use this key sequence to convert the + expression to a variable declaration of a type determined by the type of + the expression. + +**Shift+\<Tab\> M** +: After entering a complete expression or statement, use this key sequence to + convert the expression or statement to a method declaration. If an + expression is entered, the return type is based on the type of the + expression. + +**Shift+\<Tab\> I** +: When an identifier is entered that can't be resolved, use this key sequence + to show possible imports that resolve the identifier based on the content + of the specified class path. + +### Command abbreviations + +An abbreviation of a command is accepted if the abbreviation uniquely +identifies a command. For example, `/l` is recognized as the `/list` command. +However, `/s` isn't a valid abbreviation because it can't be determined if the +`/set` or `/save` command is meant. Use `/se` for the `/set` command or `/sa` +for the `/save` command. + +Abbreviations are also accepted for subcommands, command arguments, and command +options. For example, use `/m -a` to display all methods. + +### History navigation + +A history of what was entered is maintained across sessions. Use the up and +down arrows to scroll through commands and snippets from the current and past +sessions. Use the Ctrl key with the up and down arrows to skip all but the +first line of multiline snippets. + +### History search + +Use the Ctrl+R key combination to search the history for the string entered. +The prompt changes to show the string and the match. Ctrl+R searches backwards +from the current location in the history through earlier entries. Ctrl+S +searches forward from the current location in the history though later entries. + +## Input Editing + +The editing capabilities of JShell are similar to that of other common shells. +Keyboard keys and key combinations provide line editing shortcuts. The Ctrl key +and Meta key are used in key combinations. If your keyboard doesn't have a Meta +key, then the Alt key is often mapped to provide Meta key functionality. + +Table: Line Editing Shortcuts + +Key or Key Combination Action +----------------------- ------- +Return Enter the current line. +Left arrow Move the cursor to the left one character. +Right arrow Move the cursor to the right one character. +Ctrl+A Move the cursor to the beginning of the line. +Ctrl+E Move the cursor to the end of the line. +Meta+B Move the cursor to the left one word. +Meta+F Move the cursor to the right one word. +Delete Delete the character under the cursor. +Backspace Delete the character before the cursor. +Ctrl+K Delete the text from the cursor to the end of the line. +Meta+D Delete the text from the cursor to the end of the word. +Ctrl+W Delete the text from the cursor to the previous white space. +Ctrl+Y Paste the most recently deleted text into the line. +Meta+Y After Ctrl+Y, press to cycle through the previously deleted text. +----------------------- ------- + +## Example of Starting and Stopping a JShell Session + +JShell is provided with the JDK. To start a session, enter `jshell` on the +command line. A welcome message is printed, and a prompt for entering commands +and snippets is provided. + +``` +% jshell +| Welcome to JShell -- Version 9 +| For an introduction type: /help intro + +jshell> +``` + +To see which snippets were automatically loaded when JShell started, use the +`/list -start` command. The default startup snippets are import statements for +common packages. The ID for each snippet begins with the letter *s*, which +indicates it's a startup snippet. + +``` +jshell> /list -start + + s1 : import java.io.*; + s2 : import java.math.*; + s3 : import java.net.*; + s4 : import java.nio.file.*; + s5 : import java.util.*; + s6 : import java.util.concurrent.*; + s7 : import java.util.function.*; + s8 : import java.util.prefs.*; + s9 : import java.util.regex.*; + s10 : import java.util.stream.*; + +jshell> +``` + +To end the session, use the `/exit` command. + +``` +jshell> /exit +| Goodbye + +% +``` + +## Example of Entering Snippets + +Snippets are Java statements, variable definitions, method definitions, class +definitions, import statements, and expressions. Terminating semicolons are +automatically added to the end of a completed snippet if they're missing. + +The following example shows two variables and a method being defined, and the +method being run. Note that a scratch variable is automatically created to hold +the result because no variable was provided. + +``` +jshell> int a=4 +a ==> 4 + +jshell> int b=8 +b ==> 8 + +jshell> int square(int i1) { + ...> return i1 * i1; + ...> } +| created method square(int) + +jshell> square(b) +$5 ==> 64 +``` + +## Example of Changing Snippets + +Change the definition of a variable, method, or class by entering it again. + +The following examples shows a method being defined and the method run: + +``` +jshell> String grade(int testScore) { + ...> if (testScore >= 90) { + ...> return "Pass"; + ...> } + ...> return "Fail"; + ...> } +| created method grade(int) + +jshell> grade(88) +$3 ==> "Fail" +``` + +To change the method `grade` to allow more students to pass, enter the method +definition again and change the pass score to `80`. Use the up arrow key to +retrieve the previous entries to avoid having to reenter them and make the +change in the `if` statement. The following example shows the new definition +and reruns the method to show the new result: + +``` +jshell> String grade(int testScore) { + ...> if (testScore >= 80) { + ...> return "Pass"; + ...> } + ...> return "Fail"; + ...> } +| modified method grade(int) + +jshell> grade(88) +$5 ==> "Pass" +``` + +For snippets that are more than a few lines long, or to make more than a few +changes, use the `/edit` command to open the snippet in an editor. After the +changes are complete, close the edit window to return control to the JShell +session. The following example shows the command and the feedback provided when +the edit window is closed. The `/list` command is used to show that the pass +score was changed to `85`. + +``` +jshell> /edit grade +| modified method grade(int) +jshell> /list grade + + 6 : String grade(int testScore) { + if (testScore >= 85) { + return "Pass"; + } + return "Fail"; + } +``` + +## Example of Creating a Custom Feedback Mode + +The feedback mode determines the prompt that's displayed, the feedback messages +that are provided as snippets are entered, and the maximum length of a +displayed value. Predefined feedback modes are provided. Commands for creating +custom feedback modes are also provided. + +Use the `/set mode` command to create a new feedback mode. In the following +example, the new mode `mymode`, is based on the predefined feedback mode, +`normal`, and verifying command feedback is displayed: + +``` +jshell> /set mode mymode normal -command +| Created new feedback mode: mymode +``` + +Because the new mode is based on the `normal` mode, the prompts are the same. +The following example shows how to see what prompts are used and then changes +the prompts to custom strings. The first string represents the standard JShell +prompt. The second string represents the prompt for additional lines in +multiline snippets. + +``` +jshell> /set prompt mymode +| /set prompt mymode "\njshell> " " ...> " + +jshell> /set prompt mymode "\nprompt$ " " continue$ " +``` + +The maximum length of a displayed value is controlled by the truncation +setting. Different types of values can have different lengths. The following +example sets an overall truncation value of 72, and a truncation value of 500 +for variable value expressions: + +``` +jshell> /set truncation mymode 72 + +jshell> /set truncation mymode 500 varvalue +``` + +The feedback displayed after snippets are entered is controlled by the format +setting and is based on the type of snippet entered and the action taken for +that snippet. In the predefined mode `normal`, the string `created` is +displayed when a method is created. The following example shows how to change +that string to `defined`: + +``` +jshell> /set format mymode action "defined" added-primary +``` + +Use the `/set feedback` command to start using the feedback mode that was just +created. The following example shows the custom mode in use: + +``` +jshell> /set feedback mymode +| Feedback mode: mymode + +prompt$ int square (int num1){ + continue$ return num1*num1; + continue$ } +| defined method square(int) + +prompt$ +``` diff --git a/src/jdk.jstatd/share/man/jstatd.1 b/src/jdk.jstatd/share/man/jstatd.1 deleted file mode 100644 index f5d2f347b45..00000000000 --- a/src/jdk.jstatd/share/man/jstatd.1 +++ /dev/null @@ -1,219 +0,0 @@ -.\" Copyright (c) 2004, 2024, Oracle and/or its affiliates. All rights reserved. -.\" DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -.\" -.\" This code is free software; you can redistribute it and/or modify it -.\" under the terms of the GNU General Public License version 2 only, as -.\" published by the Free Software Foundation. -.\" -.\" This code is distributed in the hope that it will be useful, but WITHOUT -.\" ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -.\" FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -.\" version 2 for more details (a copy is included in the LICENSE file that -.\" accompanied this code). -.\" -.\" You should have received a copy of the GNU General Public License version -.\" 2 along with this work; if not, write to the Free Software Foundation, -.\" Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -.\" -.\" Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA -.\" or visit www.oracle.com if you need additional information or have any -.\" questions. -.\" -.\" Automatically generated by Pandoc 2.19.2 -.\" -.\" Define V font for inline verbatim, using C font in formats -.\" that render this, and otherwise B font. -.ie "\f[CB]x\f[R]"x" \{\ -. ftr V B -. ftr VI BI -. ftr VB B -. ftr VBI BI -.\} -.el \{\ -. ftr V CR -. ftr VI CI -. ftr VB CB -. ftr VBI CBI -.\} -.TH "JSTATD" "1" "2025" "JDK 24-ea" "JDK Commands" -.hy -.SH NAME -.PP -jstatd - monitor the creation and termination of instrumented Java -HotSpot VMs -.SH SYNOPSIS -.PP -\f[B]WARNING:\f[R] This command is experimental, unsupported, and -deprecated. -It will be removed in a future release. -.PP -\f[V]jstatd\f[R] [\f[I]options\f[R]] -.TP -\f[I]options\f[R] -This represents the \f[V]jstatd\f[R] command-line options. -See \f[B]Options for the jstatd Command\f[R]. -.SH DESCRIPTION -.PP -The \f[V]jstatd\f[R] command is an RMI server application that monitors -for the creation and termination of instrumented Java HotSpot VMs and -provides an interface to enable remote monitoring tools, \f[V]jstat\f[R] -and \f[V]jps\f[R], to attach to JVMs that are running on the local host -and collect information about the JVM process. -.PP -The \f[V]jstatd\f[R] server requires an RMI registry on the local host. -The \f[V]jstatd\f[R] server attempts to attach to the RMI registry on -the default port, or on the port you specify with the \f[V]-p\f[R] -\f[V]port\f[R] option. -If an RMI registry is not found, then one is created within the -\f[V]jstatd\f[R] application that\[aq]s bound to the port that\[aq]s -indicated by the \f[V]-p\f[R] \f[V]port\f[R] option or to the default -RMI registry port when the \f[V]-p\f[R] \f[V]port\f[R] option is -omitted. -You can stop the creation of an internal RMI registry by specifying the -\f[V]-nr\f[R] option. -.SH OPTIONS FOR THE JSTATD COMMAND -.TP -\f[V]-nr\f[R] -This option does not attempt to create an internal RMI registry within -the \f[V]jstatd\f[R] process when an existing RMI registry isn\[aq]t -found. -.TP -\f[V]-p\f[R] \f[I]port\f[R] -This option sets the port number where the RMI registry is expected to -be found, or when not found, created if the \f[V]-nr\f[R] option -isn\[aq]t specified. -.TP -\f[V]-r\f[R] \f[I]rmiport\f[R] -This option sets the port number to which the RMI connector is bound. -If not specified a random available port is used. -.TP -\f[V]-n\f[R] \f[I]rminame\f[R] -This option sets the name to which the remote RMI object is bound in the -RMI registry. -The default name is \f[V]JStatRemoteHost\f[R]. -If multiple \f[V]jstatd\f[R] servers are started on the same host, then -the name of the exported RMI object for each server can be made unique -by specifying this option. -However, doing so requires that the unique server name be included in -the monitoring client\[aq]s \f[V]hostid\f[R] and \f[V]vmid\f[R] strings. -.TP -\f[V]-J\f[R]\f[I]option\f[R] -This option passes a Java \f[V]option\f[R] to the JVM, where the option -is one of those described on the reference page for the Java application -launcher. -For example, \f[V]-J-Xms48m\f[R] sets the startup memory to 48 MB. -See \f[B]java\f[R]. -.SH SECURITY -.PP -The \f[V]jstatd\f[R] server can monitor only JVMs for which it has the -appropriate native access permissions. -Therefore, the \f[V]jstatd\f[R] process must be running with the same -user credentials as the target JVMs. -Some user credentials, such as the root user in Linux and macOS -operating systems, have permission to access the instrumentation -exported by any JVM on the system. -A \f[V]jstatd\f[R] process running with such credentials can monitor any -JVM on the system, but introduces additional security concerns. -.PP -The \f[V]jstatd\f[R] server doesn\[aq]t provide any authentication of -remote clients. -Therefore, running a \f[V]jstatd\f[R] server process exposes the -instrumentation export by all JVMs for which the \f[V]jstatd\f[R] -process has access permissions to any user on the network. -This exposure might be undesirable in your environment, and therefore, -local security policies should be considered before you start the -\f[V]jstatd\f[R] process, particularly in production environments or on -networks that aren\[aq]t secure. -.PP -For security purposes, the \f[V]jstatd\f[R] server uses an RMI -ObjectInputFilter to allow only essential classes to be deserialized. -.PP -If your security concerns can\[aq]t be addressed, then the safest action -is to not run the \f[V]jstatd\f[R] server and use the \f[V]jstat\f[R] -and \f[V]jps\f[R] tools locally. -However, when using \f[V]jps\f[R] to get a list of instrumented JVMs, -the list will not include any JVMs running in docker containers. -.SH REMOTE INTERFACE -.PP -The interface exported by the \f[V]jstatd\f[R] process is proprietary -and guaranteed to change. -Users and developers are discouraged from writing to this interface. -.SH EXAMPLES -.PP -The following are examples of the \f[V]jstatd\f[R] command. -The \f[V]jstatd\f[R] scripts automatically start the server in the -background. -.SH INTERNAL RMI REGISTRY -.PP -This example shows how to start a \f[V]jstatd\f[R] session with an -internal RMI registry. -This example assumes that no other server is bound to the default RMI -registry port (port \f[V]1099\f[R]). -.RS -.PP -\f[V]jstatd\f[R] -.RE -.SH EXTERNAL RMI REGISTRY -.PP -This example starts a \f[V]jstatd\f[R] session with an external RMI -registry. -.IP -.nf -\f[CB] -rmiregistry& -jstatd -\f[R] -.fi -.PP -This example starts a \f[V]jstatd\f[R] session with an external RMI -registry server on port \f[V]2020\f[R]. -.IP -.nf -\f[CB] -jrmiregistry 2020& -jstatd -p 2020 -\f[R] -.fi -.PP -This example starts a \f[V]jstatd\f[R] session with an external RMI -registry server on port \f[V]2020\f[R] and JMX connector bound to port -\f[V]2021\f[R]. -.IP -.nf -\f[CB] -jrmiregistry 2020& -jstatd -p 2020 -r 2021 -\f[R] -.fi -.PP -This example starts a \f[V]jstatd\f[R] session with an external RMI -registry on port 2020 that\[aq]s bound to -\f[V]AlternateJstatdServerName\f[R]. -.IP -.nf -\f[CB] -rmiregistry 2020& -jstatd -p 2020 -n AlternateJstatdServerName -\f[R] -.fi -.SH STOP THE CREATION OF AN IN-PROCESS RMI REGISTRY -.PP -This example starts a \f[V]jstatd\f[R] session that doesn\[aq]t create -an RMI registry when one isn\[aq]t found. -This example assumes an RMI registry is already running. -If an RMI registry isn\[aq]t running, then an error message is -displayed. -.RS -.PP -\f[V]jstatd -nr\f[R] -.RE -.SH ENABLE RMI LOGGING -.PP -This example starts a \f[V]jstatd\f[R] session with RMI logging -capabilities enabled. -This technique is useful as a troubleshooting aid or for monitoring -server activities. -.RS -.PP -\f[V]jstatd -J-Djava.rmi.server.logCalls=true\f[R] -.RE diff --git a/src/jdk.jstatd/share/man/jstatd.md b/src/jdk.jstatd/share/man/jstatd.md new file mode 100644 index 00000000000..d068fddeb01 --- /dev/null +++ b/src/jdk.jstatd/share/man/jstatd.md @@ -0,0 +1,180 @@ +--- +# Copyright (c) 2004, 2024, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# This code is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 only, as +# published by the Free Software Foundation. +# +# This code is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# version 2 for more details (a copy is included in the LICENSE file that +# accompanied this code). +# +# You should have received a copy of the GNU General Public License version +# 2 along with this work; if not, write to the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +# or visit www.oracle.com if you need additional information or have any +# questions. +# + +title: 'JSTATD(1) JDK @@VERSION_SHORT@@ | JDK Commands' +date: @@COPYRIGHT_YEAR@@ +lang: en +--- + +## Name + +jstatd - monitor the creation and termination of instrumented Java HotSpot VMs + +## Synopsis + +**WARNING:** This command is experimental, unsupported, and deprecated. It will be removed in a future release. + +`jstatd` \[*options*\] + +*options* +: This represents the `jstatd` command-line options. See [Options for the + jstatd Command]. + +## Description + +The `jstatd` command is an RMI server application that monitors for the +creation and termination of instrumented Java HotSpot VMs and provides an +interface to enable remote monitoring tools, `jstat` and `jps`, to attach to +JVMs that are running on the local host and collect information about the JVM +process. + +The `jstatd` server requires an RMI registry on the local host. The `jstatd` +server attempts to attach to the RMI registry on the default port, or on the +port you specify with the `-p` `port` option. If an RMI registry is not found, +then one is created within the `jstatd` application that's bound to the port +that's indicated by the `-p` `port` option or to the default RMI registry port +when the `-p` `port` option is omitted. You can stop the creation of an +internal RMI registry by specifying the `-nr` option. + +## Options for the jstatd Command + +`-nr` +: This option does not attempt to create an internal RMI registry within the + `jstatd` process when an existing RMI registry isn't found. + +`-p` *port* +: This option sets the port number where the RMI registry is expected to be + found, or when not found, created if the `-nr` option isn't specified. + +`-r` *rmiport* +: This option sets the port number to which the RMI connector is bound. If + not specified a random available port is used. + +`-n` *rminame* +: This option sets the name to which the remote RMI object is bound in the + RMI registry. The default name is `JStatRemoteHost`. If multiple `jstatd` + servers are started on the same host, then the name of the exported RMI + object for each server can be made unique by specifying this option. + However, doing so requires that the unique server name be included in the + monitoring client's `hostid` and `vmid` strings. + +`-J`*option* +: This option passes a Java `option` to the JVM, where the option is one of + those described on the reference page for the Java application launcher. + For example, `-J-Xms48m` sets the startup memory to 48 MB. See + [java](java.html). + +## Security + +The `jstatd` server can monitor only JVMs for which it has the appropriate +native access permissions. Therefore, the `jstatd` process must be running with +the same user credentials as the target JVMs. Some user credentials, such as +the root user in Linux and macOS operating systems, have +permission to access the instrumentation exported by any JVM on the system. A +`jstatd` process running with such credentials can monitor any JVM on the +system, but introduces additional security concerns. + +The `jstatd` server doesn't provide any authentication of remote clients. +Therefore, running a `jstatd` server process exposes the instrumentation export +by all JVMs for which the `jstatd` process has access permissions to any user +on the network. This exposure might be undesirable in your environment, and +therefore, local security policies should be considered before you start the +`jstatd` process, particularly in production environments or on networks that +aren't secure. + +For security purposes, the `jstatd` server uses an RMI ObjectInputFilter to allow +only essential classes to be deserialized. + +If your security concerns can't be addressed, +then the safest action is to not run the `jstatd` server and use the `jstat` +and `jps` tools locally. However, when using `jps` to get a list of +instrumented JVMs, the list will not include any JVMs running in docker +containers. + +## Remote Interface + +The interface exported by the `jstatd` process is proprietary and guaranteed to +change. Users and developers are discouraged from writing to this interface. + +## Examples + +The following are examples of the `jstatd` command. The `jstatd` scripts +automatically start the server in the background. + +## Internal RMI Registry + +This example shows how to start a `jstatd` session with an internal RMI +registry. This example assumes that no other server is bound to the default RMI +registry port (port `1099`). + +> `jstatd` + +## External RMI Registry + +This example starts a `jstatd` session with an external RMI registry. + +``` +rmiregistry& +jstatd +``` + +This example starts a `jstatd` session with an external RMI registry server on +port `2020`. + +``` +jrmiregistry 2020& +jstatd -p 2020 +``` + +This example starts a `jstatd` session with an external RMI registry server on +port `2020` and JMX connector bound to port `2021`. + +``` +jrmiregistry 2020& +jstatd -p 2020 -r 2021 +``` + +This example starts a `jstatd` session with an external RMI registry on port +2020 that's bound to `AlternateJstatdServerName`. + +``` +rmiregistry 2020& +jstatd -p 2020 -n AlternateJstatdServerName +``` + +## Stop the Creation of an In-Process RMI Registry + +This example starts a `jstatd` session that doesn't create an RMI registry when +one isn't found. This example assumes an RMI registry is already running. If an +RMI registry isn't running, then an error message is displayed. + +> `jstatd -nr` + +## Enable RMI Logging + +This example starts a `jstatd` session with RMI logging capabilities enabled. +This technique is useful as a troubleshooting aid or for monitoring server +activities. + +> `jstatd + -J-Djava.rmi.server.logCalls=true` diff --git a/test/langtools/jdk/javadoc/tool/CheckManPageOptions.java b/test/langtools/jdk/javadoc/tool/CheckManPageOptions.java index 2e2d0d0f84d..41bff3906d4 100644 --- a/test/langtools/jdk/javadoc/tool/CheckManPageOptions.java +++ b/test/langtools/jdk/javadoc/tool/CheckManPageOptions.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -138,7 +138,7 @@ String toSimpleList(Collection<String> items) { } Path findDefaultFile() { - return findRootDir().resolve("src/jdk.javadoc/share/man/javadoc.1"); + return findRootDir().resolve("src/jdk.javadoc/share/man/javadoc.md"); } Path findRootDir() { @@ -264,29 +264,32 @@ List<String> parseMarkdown(String page) { var list = new ArrayList<String>(); // In the Markdown man page, options are defined in one of two forms: // 1. options delegated to javac appear in lines of the form - // - `-... + // * <span id="...">`-...</span> // 2. options implemented by the tool or doclet appear in lines of the form - // `-...` + // <span id="...">`-...</span> - Pattern p1 = Pattern.compile("\\R- `-.*"); - Pattern p2 = Pattern.compile("\\R`-.*"); + Pattern p1 = Pattern.compile("\\R* <span id=\"[^\"]+\">`-.*</span>"); + Pattern p2 = Pattern.compile("\\R<span id=\"[^\"]+\">`-.*</span>"); Pattern outer = Pattern.compile("(" + p1.pattern() + "|" + p2.pattern() + ")"); Matcher outerMatcher = outer.matcher(page); // In the defining areas, option names are represented as follows: - // `OPTION` - // where OPTION is the shortest string not containing whitespace or colon - Pattern inner = Pattern.compile("\\s`([^:`]+)"); + // `OPTION` or `OPTION` + // where OPTION is the shortest string not containing whitespace or colon, + // and in which all '-' characters are escaped with a single backslash. + Pattern inner = Pattern.compile("[>\\s]`(-[^ :]+?)(:|`)"); while (outerMatcher.find()) { String lines = outerMatcher.group(); - out.println("found:" + lines + "\n"); + out.println("found:" + lines); Matcher innerMatcher = inner.matcher(lines); while (innerMatcher.find()) { String option = innerMatcher.group(1); + out.println(" found option:" + option); list.add(option); } + out.println(); } return list; From 00ff6a38ce28f94f866f4c120a04e9b0ffb7bda5 Mon Sep 17 00:00:00 2001 From: Kevin Walls <kevinw@openjdk.org> Date: Mon, 18 Nov 2024 09:24:11 +0000 Subject: [PATCH 050/311] 8344105: Remove SecurityManager and related calls from jdk.attach and jdk.hotspot.agent Reviewed-by: amenkov, cjplummer --- .../sun/tools/attach/AttachProviderImpl.java | 5 +---- .../sun/tools/attach/AttachProviderImpl.java | 5 +---- .../sun/tools/attach/AttachProviderImpl.java | 5 +---- .../sun/tools/attach/spi/AttachProvider.java | 5 ----- .../tools/attach/HotSpotAttachProvider.java | 13 +------------ .../tools/attach/HotSpotVirtualMachine.java | 12 ++---------- .../sun/tools/attach/AttachProviderImpl.java | 4 +--- .../sun/jvm/hotspot/SALauncherLoader.java | 19 +------------------ .../hotspot/tools/jcore/ByteCodeRewriter.java | 19 ++----------------- 9 files changed, 10 insertions(+), 77 deletions(-) diff --git a/src/jdk.attach/aix/classes/sun/tools/attach/AttachProviderImpl.java b/src/jdk.attach/aix/classes/sun/tools/attach/AttachProviderImpl.java index 2f6fc4d4df2..a7912e3234d 100644 --- a/src/jdk.attach/aix/classes/sun/tools/attach/AttachProviderImpl.java +++ b/src/jdk.attach/aix/classes/sun/tools/attach/AttachProviderImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2024, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2013 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -52,8 +52,6 @@ public String type() { public VirtualMachine attachVirtualMachine(String vmid) throws AttachNotSupportedException, IOException { - checkAttachPermission(); - // AttachNotSupportedException will be thrown if the target VM can be determined // to be not attachable. testAttachable(vmid); @@ -72,7 +70,6 @@ public VirtualMachine attachVirtualMachine(VirtualMachineDescriptor vmd) // implementation which only returns a list of attachable VMs. if (vmd instanceof HotSpotVirtualMachineDescriptor) { assert ((HotSpotVirtualMachineDescriptor)vmd).isAttachable(); - checkAttachPermission(); return new VirtualMachineImpl(this, vmd.id()); } else { return attachVirtualMachine(vmd.id()); diff --git a/src/jdk.attach/linux/classes/sun/tools/attach/AttachProviderImpl.java b/src/jdk.attach/linux/classes/sun/tools/attach/AttachProviderImpl.java index fd89af02511..156590885bf 100644 --- a/src/jdk.attach/linux/classes/sun/tools/attach/AttachProviderImpl.java +++ b/src/jdk.attach/linux/classes/sun/tools/attach/AttachProviderImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -49,8 +49,6 @@ public String type() { public VirtualMachine attachVirtualMachine(String vmid) throws AttachNotSupportedException, IOException { - checkAttachPermission(); - // AttachNotSupportedException will be thrown if the target VM can be determined // to be not attachable. testAttachable(vmid); @@ -69,7 +67,6 @@ public VirtualMachine attachVirtualMachine(VirtualMachineDescriptor vmd) // implementation which only returns a list of attachable VMs. if (vmd instanceof HotSpotVirtualMachineDescriptor) { assert ((HotSpotVirtualMachineDescriptor)vmd).isAttachable(); - checkAttachPermission(); return new VirtualMachineImpl(this, vmd.id()); } else { return attachVirtualMachine(vmd.id()); diff --git a/src/jdk.attach/macosx/classes/sun/tools/attach/AttachProviderImpl.java b/src/jdk.attach/macosx/classes/sun/tools/attach/AttachProviderImpl.java index d44684f81af..d57fd7961ab 100644 --- a/src/jdk.attach/macosx/classes/sun/tools/attach/AttachProviderImpl.java +++ b/src/jdk.attach/macosx/classes/sun/tools/attach/AttachProviderImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -49,8 +49,6 @@ public String type() { public VirtualMachine attachVirtualMachine(String vmid) throws AttachNotSupportedException, IOException { - checkAttachPermission(); - // AttachNotSupportedException will be thrown if the target VM can be determined // to be not attachable. testAttachable(vmid); @@ -69,7 +67,6 @@ public VirtualMachine attachVirtualMachine(VirtualMachineDescriptor vmd) // implementation which only returns a list of attachable VMs. if (vmd instanceof HotSpotVirtualMachineDescriptor) { assert ((HotSpotVirtualMachineDescriptor)vmd).isAttachable(); - checkAttachPermission(); return new VirtualMachineImpl(this, vmd.id()); } else { return attachVirtualMachine(vmd.id()); diff --git a/src/jdk.attach/share/classes/com/sun/tools/attach/spi/AttachProvider.java b/src/jdk.attach/share/classes/com/sun/tools/attach/spi/AttachProvider.java index da3f61e49ce..6446473d9d6 100644 --- a/src/jdk.attach/share/classes/com/sun/tools/attach/spi/AttachProvider.java +++ b/src/jdk.attach/share/classes/com/sun/tools/attach/spi/AttachProvider.java @@ -32,7 +32,6 @@ import java.util.List; import com.sun.tools.attach.VirtualMachine; import com.sun.tools.attach.VirtualMachineDescriptor; -import com.sun.tools.attach.AttachPermission; import com.sun.tools.attach.AttachNotSupportedException; import java.util.ServiceLoader; @@ -84,10 +83,6 @@ public abstract class AttachProvider { * Initializes a new instance of this class. */ protected AttachProvider() { - @SuppressWarnings("removal") - SecurityManager sm = System.getSecurityManager(); - if (sm != null) - sm.checkPermission(new AttachPermission("createAttachProvider")); } /** diff --git a/src/jdk.attach/share/classes/sun/tools/attach/HotSpotAttachProvider.java b/src/jdk.attach/share/classes/sun/tools/attach/HotSpotAttachProvider.java index c73a15db921..f833ee1afb3 100644 --- a/src/jdk.attach/share/classes/sun/tools/attach/HotSpotAttachProvider.java +++ b/src/jdk.attach/share/classes/sun/tools/attach/HotSpotAttachProvider.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,7 +25,6 @@ package sun.tools.attach; import com.sun.tools.attach.VirtualMachineDescriptor; -import com.sun.tools.attach.AttachPermission; import com.sun.tools.attach.AttachNotSupportedException; import com.sun.tools.attach.spi.AttachProvider; @@ -47,16 +46,6 @@ public abstract class HotSpotAttachProvider extends AttachProvider { public HotSpotAttachProvider() { } - public void checkAttachPermission() { - @SuppressWarnings("removal") - SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - sm.checkPermission( - new AttachPermission("attachVirtualMachine") - ); - } - } - /* * This listVirtualMachines implementation is based on jvmstat. Can override * this in platform implementations when there is a more efficient mechanism diff --git a/src/jdk.attach/share/classes/sun/tools/attach/HotSpotVirtualMachine.java b/src/jdk.attach/share/classes/sun/tools/attach/HotSpotVirtualMachine.java index 10d23f33535..ace00100aab 100644 --- a/src/jdk.attach/share/classes/sun/tools/attach/HotSpotVirtualMachine.java +++ b/src/jdk.attach/share/classes/sun/tools/attach/HotSpotVirtualMachine.java @@ -37,7 +37,6 @@ import java.io.InputStream; import java.io.IOException; import java.io.InputStreamReader; -import java.security.AccessController; import java.security.PrivilegedAction; import java.util.Properties; import java.util.stream.Collectors; @@ -54,8 +53,7 @@ public abstract class HotSpotVirtualMachine extends VirtualMachine { @SuppressWarnings("removal") private static long pid() { - PrivilegedAction<ProcessHandle> pa = () -> ProcessHandle.current(); - return AccessController.doPrivileged(pa).pid(); + return ProcessHandle.current().pid(); } private static final boolean ALLOW_ATTACH_SELF; @@ -361,12 +359,7 @@ protected int detectVersion() throws IOException { */ protected boolean isAPIv2Enabled() { // if "jdk.attach.compat" property is set, only v1 is enabled. - try { - String value = System.getProperty("jdk.attach.compat"); - return !("true".equalsIgnoreCase(value)); - } catch (SecurityException se) { - } - return true; + return !Boolean.getBoolean("jdk.attach.compat"); } /* @@ -563,7 +556,6 @@ long attachTimeout() { String s = System.getProperty("sun.tools.attach.attachTimeout"); attachTimeout = Long.parseLong(s); - } catch (SecurityException se) { } catch (NumberFormatException ne) { } if (attachTimeout <= 0) { diff --git a/src/jdk.attach/windows/classes/sun/tools/attach/AttachProviderImpl.java b/src/jdk.attach/windows/classes/sun/tools/attach/AttachProviderImpl.java index 503d9592370..f4826a81366 100644 --- a/src/jdk.attach/windows/classes/sun/tools/attach/AttachProviderImpl.java +++ b/src/jdk.attach/windows/classes/sun/tools/attach/AttachProviderImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -51,8 +51,6 @@ public String type() { public VirtualMachine attachVirtualMachine(String vmid) throws AttachNotSupportedException, IOException { - checkAttachPermission(); - // AttachNotSupportedException will be thrown if the target VM can be determined // to be not attachable. testAttachable(vmid); diff --git a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/SALauncherLoader.java b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/SALauncherLoader.java index 6579ac26cfc..a67f0b00077 100644 --- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/SALauncherLoader.java +++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/SALauncherLoader.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -76,14 +76,6 @@ public SALauncherLoader(ClassLoader parent) { */ public synchronized Class loadClass(String name, boolean resolve) throws ClassNotFoundException { - int i = name.lastIndexOf('.'); - if (i != -1) { - @SuppressWarnings("removal") - SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - sm.checkPackageAccess(name.substring(0, i)); - } - } Class clazz = findLoadedClass(name); if (clazz != null) return clazz; @@ -104,15 +96,6 @@ public synchronized Class loadClass(String name, boolean resolve) } } - /** - * allow any classes loaded from classpath to exit the VM. - */ - protected PermissionCollection getPermissions(CodeSource codesource) { - PermissionCollection perms = super.getPermissions(codesource); - perms.add(new RuntimePermission("exitVM")); - return perms; - } - //-- Internals only below this point private String[] libpaths; diff --git a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/tools/jcore/ByteCodeRewriter.java b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/tools/jcore/ByteCodeRewriter.java index 2ed2106c02d..95fa363c324 100644 --- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/tools/jcore/ByteCodeRewriter.java +++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/tools/jcore/ByteCodeRewriter.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -24,9 +24,6 @@ package sun.jvm.hotspot.tools.jcore; -import java.security.AccessController; -import java.security.PrivilegedAction; - import sun.jvm.hotspot.interpreter.Bytecodes; import sun.jvm.hotspot.oops.ConstantPool; import sun.jvm.hotspot.oops.ConstantPoolCache; @@ -44,19 +41,7 @@ public class ByteCodeRewriter private Bytes bytes; private static final int jintSize = 4; - public static final boolean DEBUG; - - static { - @SuppressWarnings("removal") - String debug = AccessController.doPrivileged( - new PrivilegedAction<>() { - public String run() { - return System.getProperty("sun.jvm.hotspot.tools.jcore.ByteCodeRewriter.DEBUG"); - } - } - ); - DEBUG = (debug != null ? debug.equalsIgnoreCase("true") : false); - } + public static final boolean DEBUG = Boolean.getBoolean("sun.jvm.hotspot.tools.jcore.ByteCodeRewriter.DEBUG"); protected void debugMessage(String message) { From b9c6ce900b512adfcaccd2341be3eb0003a28b87 Mon Sep 17 00:00:00 2001 From: Tobias Holenstein <tholenstein@openjdk.org> Date: Mon, 18 Nov 2024 09:36:08 +0000 Subject: [PATCH 051/311] 8344122: IGV: Extend c2 IdealGraphPrinter to send subgraphs to IGV Reviewed-by: chagedorn, epeter, rcastanedalo --- src/hotspot/share/opto/compile.cpp | 26 ++++++++--- src/hotspot/share/opto/compile.hpp | 4 +- src/hotspot/share/opto/idealGraphPrinter.cpp | 48 +++++++++++++++----- src/hotspot/share/opto/idealGraphPrinter.hpp | 15 ++++-- src/hotspot/share/opto/node.cpp | 11 +++++ src/hotspot/share/opto/parse2.cpp | 2 +- 6 files changed, 82 insertions(+), 24 deletions(-) diff --git a/src/hotspot/share/opto/compile.cpp b/src/hotspot/share/opto/compile.cpp index 1b148db20e0..7e4760e2cd6 100644 --- a/src/hotspot/share/opto/compile.cpp +++ b/src/hotspot/share/opto/compile.cpp @@ -5162,7 +5162,7 @@ void Compile::print_method(CompilerPhaseType cpt, int level, Node* n) { const char* name = ss.as_string(); if (should_print_igv(level)) { - _igv_printer->print_method(name, level); + _igv_printer->print_graph(name); } if (should_print_phase(cpt)) { print_ideal_ir(CompilerPhaseTypeHelper::to_name(cpt)); @@ -5204,6 +5204,15 @@ bool Compile::should_print_phase(CompilerPhaseType cpt) { return false; } +#ifndef PRODUCT +void Compile::init_igv() { + if (_igv_printer == nullptr) { + _igv_printer = IdealGraphPrinter::printer(); + _igv_printer->set_compile(this); + } +} +#endif + bool Compile::should_print_igv(const int level) { #ifndef PRODUCT if (PrintIdealGraphLevel < 0) { // disabled by the user @@ -5211,9 +5220,8 @@ bool Compile::should_print_igv(const int level) { } bool need = directive()->IGVPrintLevelOption >= level; - if (need && !_igv_printer) { - _igv_printer = IdealGraphPrinter::printer(); - _igv_printer->set_compile(this); + if (need) { + Compile::init_igv(); } return need; #else @@ -5281,17 +5289,23 @@ void Compile::igv_print_method_to_file(const char* phase_name, bool append) { _debug_file_printer->update_compiled_method(C->method()); } tty->print_cr("Method %s to %s", append ? "appended" : "printed", file_name); - _debug_file_printer->print(phase_name, (Node*)C->root()); + _debug_file_printer->print_graph(phase_name); } void Compile::igv_print_method_to_network(const char* phase_name) { + ResourceMark rm; + GrowableArray<const Node*> empty_list; + igv_print_graph_to_network(phase_name, (Node*) C->root(), empty_list); +} + +void Compile::igv_print_graph_to_network(const char* name, Node* node, GrowableArray<const Node*>& visible_nodes) { if (_debug_network_printer == nullptr) { _debug_network_printer = new IdealGraphPrinter(C); } else { _debug_network_printer->update_compiled_method(C->method()); } tty->print_cr("Method printed over network stream to IGV"); - _debug_network_printer->print(phase_name, (Node*)C->root()); + _debug_network_printer->print(name, C->root(), visible_nodes); } #endif diff --git a/src/hotspot/share/opto/compile.hpp b/src/hotspot/share/opto/compile.hpp index 6285d4a5548..7c251bd4bd9 100644 --- a/src/hotspot/share/opto/compile.hpp +++ b/src/hotspot/share/opto/compile.hpp @@ -711,14 +711,16 @@ class Compile : public Phase { void print_method(CompilerPhaseType cpt, int level, Node* n = nullptr); #ifndef PRODUCT + void init_igv(); void dump_igv(const char* graph_name, int level = 3) { if (should_print_igv(level)) { - _igv_printer->print_method(graph_name, level); + _igv_printer->print_graph(graph_name); } } void igv_print_method_to_file(const char* phase_name = "Debug", bool append = false); void igv_print_method_to_network(const char* phase_name = "Debug"); + void igv_print_graph_to_network(const char* name, Node* node, GrowableArray<const Node*>& visible_nodes); static IdealGraphPrinter* debug_file_printer() { return _debug_file_printer; } static IdealGraphPrinter* debug_network_printer() { return _debug_network_printer; } #endif diff --git a/src/hotspot/share/opto/idealGraphPrinter.cpp b/src/hotspot/share/opto/idealGraphPrinter.cpp index 40aec858205..ec9233935e7 100644 --- a/src/hotspot/share/opto/idealGraphPrinter.cpp +++ b/src/hotspot/share/opto/idealGraphPrinter.cpp @@ -53,6 +53,7 @@ const char *IdealGraphPrinter::COMPILATION_OSR_PROPERTY = "osr"; const char *IdealGraphPrinter::METHOD_NAME_PROPERTY = "name"; const char *IdealGraphPrinter::METHOD_IS_PUBLIC_PROPERTY = "public"; const char *IdealGraphPrinter::METHOD_IS_STATIC_PROPERTY = "static"; +const char *IdealGraphPrinter::FALSE_VALUE = "false"; const char *IdealGraphPrinter::TRUE_VALUE = "true"; const char *IdealGraphPrinter::NODE_NAME_PROPERTY = "name"; const char *IdealGraphPrinter::EDGE_NAME_PROPERTY = "name"; @@ -68,6 +69,12 @@ const char *IdealGraphPrinter::BYTECODES_ELEMENT = "bytecodes"; const char *IdealGraphPrinter::METHOD_BCI_PROPERTY = "bci"; const char *IdealGraphPrinter::METHOD_SHORT_NAME_PROPERTY = "shortName"; const char *IdealGraphPrinter::CONTROL_FLOW_ELEMENT = "controlFlow"; +const char *IdealGraphPrinter::GRAPH_STATES_ELEMENT = "graphStates"; +const char *IdealGraphPrinter::STATE_ELEMENT = "state"; +const char *IdealGraphPrinter::DIFFERENCE_ELEMENT = "difference"; +const char *IdealGraphPrinter::DIFFERENCE_VALUE_PROPERTY = "value"; +const char *IdealGraphPrinter::VISIBLE_NODES_ELEMENT = "visibleNodes"; +const char *IdealGraphPrinter::ALL_PROPERTY = "all"; const char *IdealGraphPrinter::BLOCK_NAME_PROPERTY = "name"; const char *IdealGraphPrinter::BLOCK_DOMINATOR_PROPERTY = "dom"; const char *IdealGraphPrinter::BLOCK_ELEMENT = "block"; @@ -349,7 +356,7 @@ void IdealGraphPrinter::set_traverse_outs(bool b) { _traverse_outs = b; } -void IdealGraphPrinter::visit_node(Node *n, bool edges, VectorSet* temp_set) { +void IdealGraphPrinter::visit_node(Node* n, bool edges) { if (edges) { @@ -775,7 +782,7 @@ Node* IdealGraphPrinter::get_load_node(const Node* node) { return load; } -void IdealGraphPrinter::walk_nodes(Node* start, bool edges, VectorSet* temp_set) { +void IdealGraphPrinter::walk_nodes(Node* start, bool edges) { VectorSet visited; GrowableArray<Node *> nodeStack(Thread::current()->resource_area(), 0, 0, nullptr); nodeStack.push(start); @@ -796,7 +803,7 @@ void IdealGraphPrinter::walk_nodes(Node* start, bool edges, VectorSet* temp_set) continue; } - visit_node(n, edges, temp_set); + visit_node(n, edges); if (_traverse_outs) { for (DUIterator i = n->outs(); n->has_out(i); i++) { @@ -812,14 +819,14 @@ void IdealGraphPrinter::walk_nodes(Node* start, bool edges, VectorSet* temp_set) } } -void IdealGraphPrinter::print_method(const char *name, int level) { - if (C->should_print_igv(level)) { - print(name, (Node *) C->root()); - } +void IdealGraphPrinter::print_graph(const char* name) { + ResourceMark rm; + GrowableArray<const Node*> empty_list; + print(name, (Node*) C->root(), empty_list); } // Print current ideal graph -void IdealGraphPrinter::print(const char *name, Node *node) { +void IdealGraphPrinter::print(const char* name, Node* node, GrowableArray<const Node*>& visible_nodes) { if (!_current_method || !_should_send_method || node == nullptr) return; @@ -830,8 +837,6 @@ void IdealGraphPrinter::print(const char *name, Node *node) { print_attr(GRAPH_NAME_PROPERTY, (const char *)name); end_head(); - VectorSet temp_set; - head(NODES_ELEMENT); if (C->cfg() != nullptr) { // Compute the maximum estimated frequency in the current graph. @@ -843,11 +848,11 @@ void IdealGraphPrinter::print(const char *name, Node *node) { } } } - walk_nodes(node, false, &temp_set); + walk_nodes(node, false); tail(NODES_ELEMENT); head(EDGES_ELEMENT); - walk_nodes(node, true, &temp_set); + walk_nodes(node, true); tail(EDGES_ELEMENT); if (C->cfg() != nullptr) { head(CONTROL_FLOW_ELEMENT); @@ -877,6 +882,25 @@ void IdealGraphPrinter::print(const char *name, Node *node) { } tail(CONTROL_FLOW_ELEMENT); } + if (visible_nodes.is_nonempty()) { + head(GRAPH_STATES_ELEMENT); + head(STATE_ELEMENT); + begin_elem(DIFFERENCE_ELEMENT); + print_attr(DIFFERENCE_VALUE_PROPERTY, "0"); + end_elem(); + + begin_head(VISIBLE_NODES_ELEMENT); + print_attr(ALL_PROPERTY, FALSE_VALUE); + end_head(); + for (int i = 0; i < visible_nodes.length(); ++i) { + begin_elem(NODE_ELEMENT); + print_attr(NODE_ID_PROPERTY, visible_nodes.at(i)->_igv_idx); + end_elem(); + } + tail(VISIBLE_NODES_ELEMENT); + tail(STATE_ELEMENT); + tail(GRAPH_STATES_ELEMENT); + } tail(GRAPH_ELEMENT); _xml->flush(); } diff --git a/src/hotspot/share/opto/idealGraphPrinter.hpp b/src/hotspot/share/opto/idealGraphPrinter.hpp index a06f2396f63..b6794667911 100644 --- a/src/hotspot/share/opto/idealGraphPrinter.hpp +++ b/src/hotspot/share/opto/idealGraphPrinter.hpp @@ -59,6 +59,12 @@ class IdealGraphPrinter : public CHeapObj<mtCompiler> { static const char *CONTROL_FLOW_ELEMENT; static const char *REMOVE_EDGE_ELEMENT; static const char *REMOVE_NODE_ELEMENT; + static const char *GRAPH_STATES_ELEMENT; + static const char *STATE_ELEMENT; + static const char *DIFFERENCE_ELEMENT; + static const char *DIFFERENCE_VALUE_PROPERTY; + static const char *VISIBLE_NODES_ELEMENT; + static const char *ALL_PROPERTY; static const char *COMPILATION_ID_PROPERTY; static const char *COMPILATION_OSR_PROPERTY; static const char *METHOD_NAME_PROPERTY; @@ -69,6 +75,7 @@ class IdealGraphPrinter : public CHeapObj<mtCompiler> { static const char *SUCCESSOR_ELEMENT; static const char *METHOD_IS_PUBLIC_PROPERTY; static const char *METHOD_IS_STATIC_PROPERTY; + static const char *FALSE_VALUE; static const char *TRUE_VALUE; static const char *NODE_NAME_PROPERTY; static const char *EDGE_NAME_PROPERTY; @@ -101,13 +108,13 @@ class IdealGraphPrinter : public CHeapObj<mtCompiler> { void print_method(ciMethod* method, int bci, InlineTree* tree); void print_inline_tree(InlineTree* tree); - void visit_node(Node* n, bool edges, VectorSet* temp_set); + void visit_node(Node* n, bool edges); void print_bci_and_line_number(JVMState* caller); void print_field(const Node* node); ciField* get_field(const Node* node); ciField* find_source_field_of_array_access(const Node* node, uint& depth); static Node* get_load_node(const Node* node); - void walk_nodes(Node *start, bool edges, VectorSet* temp_set); + void walk_nodes(Node* start, bool edges); void begin_elem(const char *s); void end_elem(); void begin_head(const char *s); @@ -137,8 +144,8 @@ class IdealGraphPrinter : public CHeapObj<mtCompiler> { void print_inlining(); void begin_method(); void end_method(); - void print_method(const char *name, int level = 0); - void print(const char *name, Node *root); + void print_graph(const char* name); + void print(const char* name, Node* root, GrowableArray<const Node*>& hidden_nodes); void set_compile(Compile* compile) {C = compile; } void update_compiled_method(ciMethod* current_method); }; diff --git a/src/hotspot/share/opto/node.cpp b/src/hotspot/share/opto/node.cpp index 3f82c472163..cf371bb3fff 100644 --- a/src/hotspot/share/opto/node.cpp +++ b/src/hotspot/share/opto/node.cpp @@ -1830,6 +1830,8 @@ class PrintBFS { bool _print_blocks = false; bool _print_old = false; bool _dump_only = false; + bool _print_igv = false; + void print_options_help(bool print_examples); bool parse_options(); @@ -2047,6 +2049,11 @@ void PrintBFS::print() { const Node* n = _print_list.at(i); print_node(n); } + if (_print_igv) { + Compile* C = Compile::current(); + C->init_igv(); + C->igv_print_graph_to_network("PrintBFS", (Node*) C->root(), _print_list); + } } else { _output->print_cr("No nodes to print."); } @@ -2089,6 +2096,7 @@ void PrintBFS::print_options_help(bool print_examples) { _output->print_cr(" @: print old nodes - before matching (if available)"); _output->print_cr(" B: print scheduling blocks (if available)"); _output->print_cr(" $: dump only, no header, no other columns"); + _output->print_cr(" !: show nodes on IGV (sent over network stream)"); _output->print_cr(""); _output->print_cr("recursively follow edges to nodes with permitted visit types,"); _output->print_cr("on the boundary additionally display nodes allowed in boundary types"); @@ -2202,6 +2210,9 @@ bool PrintBFS::parse_options() { case '$': _dump_only = true; break; + case '!': + _print_igv = true; + break; case 'h': print_options_help(false); return false; diff --git a/src/hotspot/share/opto/parse2.cpp b/src/hotspot/share/opto/parse2.cpp index f7b17361913..73cf9234808 100644 --- a/src/hotspot/share/opto/parse2.cpp +++ b/src/hotspot/share/opto/parse2.cpp @@ -2836,7 +2836,7 @@ void Parse::do_one_bytecode() { jio_snprintf(buffer, sizeof(buffer), "Bytecode %d: %s", bci(), Bytecodes::name(bc())); bool old = printer->traverse_outs(); printer->set_traverse_outs(true); - printer->print_method(buffer, perBytecode); + printer->print_graph(buffer); printer->set_traverse_outs(old); } #endif From ea8f28980ca19bfa74c39ed5a6708ce094b6119f Mon Sep 17 00:00:00 2001 From: Jan Lahoda <jlahoda@openjdk.org> Date: Mon, 18 Nov 2024 10:38:45 +0000 Subject: [PATCH 052/311] 8344271: Comparison build fails due to difference in doc summary Reviewed-by: hannesw --- .../doclets/formats/html/ModuleWriter.java | 28 +++++++++---------- 1 file changed, 13 insertions(+), 15 deletions(-) diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ModuleWriter.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ModuleWriter.java index 30de66b46a6..793f619035a 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ModuleWriter.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ModuleWriter.java @@ -41,6 +41,7 @@ import com.sun.source.doctree.DeprecatedTree; import com.sun.source.doctree.DocTree; +import java.util.function.Predicate; import java.util.stream.Collectors; import jdk.javadoc.doclet.DocletEnvironment.ModuleMode; @@ -591,14 +592,10 @@ protected void addPackagesSummary(Content summariesList) { .anyMatch(rd -> rd.isTransitive() && javaBase.equals(rd.getDependency())); if (hasRequiresTransitiveJavaBase) { - Map<ModuleElement, SortedSet<PackageElement>> filteredIndirectPackages = - indirectPackages.entrySet() - .stream() - .filter(e -> !e.getKey().equals(javaBase)) - .collect(Collectors.toMap(e -> e.getKey(), e -> e.getValue())); String aepText = resources.getText("doclet.Indirect_Exports_Summary"); var aepTable = getTable2(Text.of(aepText), indirectPackagesHeader); - addIndirectPackages(aepTable, filteredIndirectPackages); + addIndirectPackages(aepTable, indirectPackages, + m -> !m.equals(javaBase)); section.add(aepTable); //add the preview box: section.add(HtmlTree.BR()); @@ -614,30 +611,26 @@ protected void addPackagesSummary(Content summariesList) { section.add(previewDiv); //add the Indirect Exports - filteredIndirectPackages = - indirectPackages.entrySet() - .stream() - .filter(e -> e.getKey().equals(javaBase)) - .collect(Collectors.toMap(e -> e.getKey(), e -> e.getValue())); String aepPreviewText = resources.getText("doclet.Indirect_Exports_Summary"); ContentBuilder tableCaption = new ContentBuilder( Text.of(aepPreviewText), HtmlTree.SUP(links.createLink(previewRequiresTransitiveId, contents.previewMark))); var aepPreviewTable = getTable2(tableCaption, indirectPackagesHeader); - addIndirectPackages(aepPreviewTable, filteredIndirectPackages); + addIndirectPackages(aepPreviewTable, indirectPackages, + m -> m.equals(javaBase)); section.add(aepPreviewTable); } else { String aepText = resources.getText("doclet.Indirect_Exports_Summary"); var aepTable = getTable2(Text.of(aepText), indirectPackagesHeader); - addIndirectPackages(aepTable, indirectPackages); + addIndirectPackages(aepTable, indirectPackages, _ -> true); section.add(aepTable); } } if (display(indirectOpenPackages)) { String aopText = resources.getText("doclet.Indirect_Opens_Summary"); var aopTable = getTable2(Text.of(aopText), indirectPackagesHeader); - addIndirectPackages(aopTable, indirectOpenPackages); + addIndirectPackages(aopTable, indirectOpenPackages, _ -> true); section.add(aopTable); } summariesList.add(HtmlTree.LI(section)); @@ -768,9 +761,14 @@ private Content getPackageExportOpensTo(Set<ModuleElement> modules) { * @param table the table to which the content rows will be added * @param ip indirect packages to be added */ - public void addIndirectPackages(Table<?> table, Map<ModuleElement, SortedSet<PackageElement>> ip) { + public void addIndirectPackages(Table<?> table, + Map<ModuleElement, SortedSet<PackageElement>> ip, + Predicate<ModuleElement> acceptModule) { for (Map.Entry<ModuleElement, SortedSet<PackageElement>> entry : ip.entrySet()) { ModuleElement m = entry.getKey(); + if (!acceptModule.test(m)) { + continue; + } SortedSet<PackageElement> pkgList = entry.getValue(); Content moduleLinkContent = getModuleLink(m, Text.of(m.getQualifiedName())); Content list = new ContentBuilder(); From 5fc432226746c8a71290857240a388bf0101f3c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ant=C3=B3n=20Seoane=20Ampudia?= <anton.seoane-ampudia.8277@student.uu.se> Date: Mon, 18 Nov 2024 10:40:33 +0000 Subject: [PATCH 053/311] 8288298: Resolve multiline message parsing ambiguities in UL Reviewed-by: jsjolen, rcastanedalo, dholmes --- .../share/logging/logFileStreamOutput.cpp | 36 +++++++++++++++---- .../runtime/logging/FoldMultilinesTest.java | 4 +-- 2 files changed, 31 insertions(+), 9 deletions(-) diff --git a/src/hotspot/share/logging/logFileStreamOutput.cpp b/src/hotspot/share/logging/logFileStreamOutput.cpp index 76e67a45de2..dc34a9b8b14 100644 --- a/src/hotspot/share/logging/logFileStreamOutput.cpp +++ b/src/hotspot/share/logging/logFileStreamOutput.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -30,6 +30,7 @@ #include "logging/logMessageBuffer.hpp" #include "memory/allocation.inline.hpp" #include "utilities/defaultStream.hpp" +#include <string.h> const char* const LogFileStreamOutput::FoldMultilinesOptionKey = "foldmultilines"; @@ -119,14 +120,35 @@ int LogFileStreamOutput::write_internal(const LogDecorations& decorations, const int written = 0; const bool use_decorations = !_decorators.is_empty(); - if (use_decorations) { - WRITE_LOG_WITH_RESULT_CHECK(write_decorations(decorations), written); - WRITE_LOG_WITH_RESULT_CHECK(jio_fprintf(_stream, " "), written); - } - if (!_fold_multilines) { - WRITE_LOG_WITH_RESULT_CHECK(jio_fprintf(_stream, "%s\n", msg), written); + const char* base = msg; + int decorator_padding = 0; + if (use_decorations) { + WRITE_LOG_WITH_RESULT_CHECK(write_decorations(decorations), decorator_padding); + WRITE_LOG_WITH_RESULT_CHECK(jio_fprintf(_stream, " "), written); + } + written += decorator_padding; + + // Search for newlines in the string and repeatedly print the substrings that end + // with each newline. + const char* next = strstr(msg, "\n"); + while (next != nullptr) { // We have some newlines to print + int to_print = next - base; + WRITE_LOG_WITH_RESULT_CHECK(jio_fprintf(_stream, "%.*s\n", to_print, base), written); + if (use_decorations) { + WRITE_LOG_WITH_RESULT_CHECK(jio_fprintf(_stream, "[%*c] ", decorator_padding - 2, ' '), written); // Substracting 2 because decorator_padding includes the brackets + } + base = next + 1; + next = strstr(base, "\n"); + } + + // Print the end of the message + WRITE_LOG_WITH_RESULT_CHECK(jio_fprintf(_stream, "%s\n", base), written); } else { + if (use_decorations) { + WRITE_LOG_WITH_RESULT_CHECK(write_decorations(decorations), written); + WRITE_LOG_WITH_RESULT_CHECK(jio_fprintf(_stream, " "), written); + } char *dupstr = os::strdup_check_oom(msg, mtLogging); char *cur = dupstr; char *next; diff --git a/test/hotspot/jtreg/runtime/logging/FoldMultilinesTest.java b/test/hotspot/jtreg/runtime/logging/FoldMultilinesTest.java index 8df835245c8..e9a7bbc6496 100644 --- a/test/hotspot/jtreg/runtime/logging/FoldMultilinesTest.java +++ b/test/hotspot/jtreg/runtime/logging/FoldMultilinesTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2024, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2021 NTT DATA. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -41,7 +41,7 @@ public class FoldMultilinesTest { private static String XLOG_BASE = "-Xlog:exceptions=info:"; private static String EXCEPTION_MESSAGE = "line 1\nline 2\\nstring"; private static String FOLDED_EXCEPTION_MESSAGE = "line 1\\nline 2\\\\nstring"; - private static Pattern NEWLINE_LOG_PATTERN = Pattern.compile("line 1\\Rline 2\\\\nstring", Pattern.MULTILINE); + private static Pattern NEWLINE_LOG_PATTERN = Pattern.compile("line 1\\R\\[\\s+\\] line 2\\\\nstring", Pattern.MULTILINE); private static String getLog(String out, OutputAnalyzer output) throws Exception { return switch (out) { From b8b70c8b4efd97ae6a57a880b03a4bf26d79acc4 Mon Sep 17 00:00:00 2001 From: Amit Kumar <amitkumar@openjdk.org> Date: Mon, 18 Nov 2024 10:40:52 +0000 Subject: [PATCH 054/311] 8344379: [s390x] build failure due to missing change from JDK-8339466 Reviewed-by: lucy, shade --- src/hotspot/cpu/s390/sharedRuntime_s390.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hotspot/cpu/s390/sharedRuntime_s390.cpp b/src/hotspot/cpu/s390/sharedRuntime_s390.cpp index 1238f887b87..1844b0deb1c 100644 --- a/src/hotspot/cpu/s390/sharedRuntime_s390.cpp +++ b/src/hotspot/cpu/s390/sharedRuntime_s390.cpp @@ -2919,7 +2919,7 @@ SafepointBlob* SharedRuntime::generate_handler_blob(SharedStubId id, address cal __ z_lg(Z_R14, Address(Z_thread, JavaThread::saved_exception_pc_offset())); } - bool save_vectors = (poll_type == POLL_AT_VECTOR_LOOP); + bool save_vectors = (id == SharedStubId::polling_page_vectors_safepoint_handler_id); // Save registers, fpu state, and flags map = RegisterSaver::save_live_registers(masm, RegisterSaver::all_registers, Z_R14, save_vectors); From 5eb0733f5f4652751214dac5af51c1812e0925e6 Mon Sep 17 00:00:00 2001 From: Magnus Ihse Bursie <ihse@openjdk.org> Date: Mon, 18 Nov 2024 11:31:08 +0000 Subject: [PATCH 055/311] 8344383: Include ZipArchive and JarArchive directly Reviewed-by: shade --- make/ZipSecurity.gmk | 4 ++-- make/ZipSource.gmk | 4 ++-- make/test/BuildMicrobenchmark.gmk | 1 + 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/make/ZipSecurity.gmk b/make/ZipSecurity.gmk index 373ba13ecc6..08f9caadd9a 100644 --- a/make/ZipSecurity.gmk +++ b/make/ZipSecurity.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2014, 2023, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2014, 2024, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -27,7 +27,7 @@ default: all include $(SPEC) include MakeBase.gmk -include JavaCompilation.gmk +include ZipArchive.gmk ################################################################################ # diff --git a/make/ZipSource.gmk b/make/ZipSource.gmk index 341af7e9847..c1df6af7583 100644 --- a/make/ZipSource.gmk +++ b/make/ZipSource.gmk @@ -1,5 +1,5 @@ # -# Copyright (c) 2014, 2022, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2014, 2024, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -27,8 +27,8 @@ default: all include $(SPEC) include MakeBase.gmk -include JavaCompilation.gmk include Modules.gmk +include ZipArchive.gmk SRC_ZIP_WORK_DIR := $(SUPPORT_OUTPUTDIR)/src $(if $(filter $(TOPDIR)/%, $(SUPPORT_OUTPUTDIR)), $(eval SRC_ZIP_BASE := $(TOPDIR)), $(eval SRC_ZIP_BASE := $(SUPPORT_OUTPUTDIR))) diff --git a/make/test/BuildMicrobenchmark.gmk b/make/test/BuildMicrobenchmark.gmk index 1b2eb40b252..0a4c2d9a48d 100644 --- a/make/test/BuildMicrobenchmark.gmk +++ b/make/test/BuildMicrobenchmark.gmk @@ -30,6 +30,7 @@ include $(SPEC) include MakeBase.gmk include CopyFiles.gmk +include JarArchive.gmk include JavaCompilation.gmk include TestFilesCompilation.gmk From dfddbcaab886b9baa731cd748bb7f547e1903b64 Mon Sep 17 00:00:00 2001 From: Coleen Phillimore <coleenp@openjdk.org> Date: Mon, 18 Nov 2024 12:48:40 +0000 Subject: [PATCH 056/311] 8341916: Remove ProtectionDomain related hotspot code and tests Reviewed-by: dholmes, iklam, jrose --- .../share/cds/aotConstantPoolResolver.cpp | 4 +- .../share/cds/aotLinkedClassBulkLoader.cpp | 2 +- src/hotspot/share/cds/classListParser.cpp | 6 +- src/hotspot/share/cds/heapShared.cpp | 2 +- src/hotspot/share/ci/ciEnv.cpp | 7 +- src/hotspot/share/ci/ciReplay.cpp | 20 +- .../share/classfile/classFileParser.cpp | 2 - src/hotspot/share/classfile/dictionary.cpp | 297 ++---------------- src/hotspot/share/classfile/dictionary.hpp | 62 +--- src/hotspot/share/classfile/javaClasses.cpp | 55 +--- src/hotspot/share/classfile/javaClasses.hpp | 26 -- .../share/classfile/protectionDomainCache.cpp | 228 -------------- .../share/classfile/protectionDomainCache.hpp | 74 ----- .../share/classfile/systemDictionary.cpp | 113 ++----- .../share/classfile/systemDictionary.hpp | 47 +-- .../share/classfile/verificationType.cpp | 8 +- src/hotspot/share/classfile/verifier.cpp | 6 +- src/hotspot/share/classfile/vmClassMacros.hpp | 3 - src/hotspot/share/classfile/vmSymbols.hpp | 11 - src/hotspot/share/include/jvm.h | 6 - .../share/interpreter/linkResolver.cpp | 1 - src/hotspot/share/jvmci/jvmciCompilerToVM.cpp | 13 +- src/hotspot/share/jvmci/jvmciEnv.cpp | 5 +- src/hotspot/share/jvmci/jvmciRuntime.cpp | 4 +- .../share/logging/logDiagnosticCommand.hpp | 3 +- src/hotspot/share/logging/logTag.hpp | 1 - src/hotspot/share/oops/constantPool.cpp | 7 +- src/hotspot/share/oops/method.cpp | 3 +- src/hotspot/share/prims/jni.cpp | 12 +- src/hotspot/share/prims/jvm.cpp | 97 +----- src/hotspot/share/prims/jvm_misc.hpp | 4 +- src/hotspot/share/prims/whitebox.cpp | 6 - src/hotspot/share/runtime/deoptimization.cpp | 2 +- src/hotspot/share/runtime/serviceThread.cpp | 14 - src/hotspot/share/runtime/signature.cpp | 21 +- src/hotspot/share/runtime/signature.hpp | 15 +- src/hotspot/share/runtime/threads.cpp | 2 +- src/hotspot/share/runtime/vframe.cpp | 3 +- .../share/services/diagnosticCommand.cpp | 8 +- src/hotspot/share/services/management.cpp | 1 - src/hotspot/share/utilities/exceptions.cpp | 44 ++- src/hotspot/share/utilities/exceptions.hpp | 22 +- test/hotspot/jtreg/ProblemList.txt | 3 - .../Dictionary/CleanProtectionDomain.java | 101 ------ .../Dictionary/ProtectionDomainCacheTest.java | 115 ------- .../ProtectionDomainVerificationTest.java | 81 ----- .../dcmd/vm/DictionaryStatsTest.java | 14 +- test/lib/jdk/test/whitebox/WhiteBox.java | 3 - 48 files changed, 169 insertions(+), 1415 deletions(-) delete mode 100644 src/hotspot/share/classfile/protectionDomainCache.cpp delete mode 100644 src/hotspot/share/classfile/protectionDomainCache.hpp delete mode 100644 test/hotspot/jtreg/runtime/Dictionary/CleanProtectionDomain.java delete mode 100644 test/hotspot/jtreg/runtime/Dictionary/ProtectionDomainCacheTest.java delete mode 100644 test/hotspot/jtreg/runtime/logging/ProtectionDomainVerificationTest.java diff --git a/src/hotspot/share/cds/aotConstantPoolResolver.cpp b/src/hotspot/share/cds/aotConstantPoolResolver.cpp index cc500557c8d..584be7085ce 100644 --- a/src/hotspot/share/cds/aotConstantPoolResolver.cpp +++ b/src/hotspot/share/cds/aotConstantPoolResolver.cpp @@ -170,9 +170,7 @@ void AOTConstantPoolResolver::dumptime_resolve_constants(InstanceKlass* ik, TRAP Klass* AOTConstantPoolResolver::find_loaded_class(Thread* current, oop class_loader, Symbol* name) { HandleMark hm(current); Handle h_loader(current, class_loader); - Klass* k = SystemDictionary::find_instance_or_array_klass(current, name, - h_loader, - Handle()); + Klass* k = SystemDictionary::find_instance_or_array_klass(current, name, h_loader); if (k != nullptr) { return k; } diff --git a/src/hotspot/share/cds/aotLinkedClassBulkLoader.cpp b/src/hotspot/share/cds/aotLinkedClassBulkLoader.cpp index d823db9e8d7..9bab6042436 100644 --- a/src/hotspot/share/cds/aotLinkedClassBulkLoader.cpp +++ b/src/hotspot/share/cds/aotLinkedClassBulkLoader.cpp @@ -306,7 +306,7 @@ void AOTLinkedClassBulkLoader::load_hidden_class(ClassLoaderData* loader_data, I // use any special ClassLoaderData. Handle loader(THREAD, loader_data->class_loader()); ResourceMark rm(THREAD); - assert(SystemDictionary::resolve_or_null(ik->name(), loader, pd, THREAD) == nullptr, + assert(SystemDictionary::resolve_or_null(ik->name(), loader, THREAD) == nullptr, "hidden classes cannot be accessible by name: %s", ik->external_name()); if (HAS_PENDING_EXCEPTION) { CLEAR_PENDING_EXCEPTION; diff --git a/src/hotspot/share/cds/classListParser.cpp b/src/hotspot/share/cds/classListParser.cpp index 57d14229795..47925f578ea 100644 --- a/src/hotspot/share/cds/classListParser.cpp +++ b/src/hotspot/share/cds/classListParser.cpp @@ -612,8 +612,7 @@ void ClassListParser::resolve_indy_impl(Symbol* class_name_symbol, TRAPS) { // resolve the CP entry for the invokedynamic instruction, which may result in // generation of LambdaForm classes. Handle class_loader(THREAD, SystemDictionary::java_system_loader()); - Handle protection_domain; - Klass* klass = SystemDictionary::resolve_or_fail(class_name_symbol, class_loader, protection_domain, true, CHECK); + Klass* klass = SystemDictionary::resolve_or_fail(class_name_symbol, class_loader, true, CHECK); if (klass->is_instance_klass()) { InstanceKlass* ik = InstanceKlass::cast(klass); MetaspaceShared::try_link_class(THREAD, ik); @@ -781,8 +780,7 @@ InstanceKlass* ClassListParser::lookup_interface_for_current_class(Symbol* inter InstanceKlass* ClassListParser::find_builtin_class_helper(JavaThread* current, Symbol* class_name_symbol, oop class_loader_oop) { Handle class_loader(current, class_loader_oop); - Handle protection_domain; - return SystemDictionary::find_instance_klass(current, class_name_symbol, class_loader, protection_domain); + return SystemDictionary::find_instance_klass(current, class_name_symbol, class_loader); } InstanceKlass* ClassListParser::find_builtin_class(JavaThread* current, const char* class_name) { diff --git a/src/hotspot/share/cds/heapShared.cpp b/src/hotspot/share/cds/heapShared.cpp index 3a7ba936bb0..d2ab109cc72 100644 --- a/src/hotspot/share/cds/heapShared.cpp +++ b/src/hotspot/share/cds/heapShared.cpp @@ -2436,7 +2436,7 @@ void HeapShared::print_stats() { bool HeapShared::is_archived_boot_layer_available(JavaThread* current) { TempNewSymbol klass_name = SymbolTable::new_symbol(ARCHIVED_BOOT_LAYER_CLASS); - InstanceKlass* k = SystemDictionary::find_instance_klass(current, klass_name, Handle(), Handle()); + InstanceKlass* k = SystemDictionary::find_instance_klass(current, klass_name, Handle()); if (k == nullptr) { return false; } else { diff --git a/src/hotspot/share/ci/ciEnv.cpp b/src/hotspot/share/ci/ciEnv.cpp index 6bf8f44553d..eb7d1eaf64d 100644 --- a/src/hotspot/share/ci/ciEnv.cpp +++ b/src/hotspot/share/ci/ciEnv.cpp @@ -462,14 +462,12 @@ ciKlass* ciEnv::get_klass_by_name_impl(ciKlass* accessing_klass, } Handle loader; - Handle domain; if (accessing_klass != nullptr) { loader = Handle(current, accessing_klass->loader()); - domain = Handle(current, accessing_klass->protection_domain()); } Klass* found_klass = require_local ? - SystemDictionary::find_instance_or_array_klass(current, sym, loader, domain) : + SystemDictionary::find_instance_or_array_klass(current, sym, loader) : SystemDictionary::find_constrained_instance_or_array_klass(current, sym, loader); // If we fail to find an array klass, look again for its element type. @@ -1611,8 +1609,7 @@ void ciEnv::dump_replay_data_helper(outputStream* out) { GrowableArray<ciMetadata*>* objects = _factory->get_ci_metadata(); out->print_cr("# %d ciObject found", objects->length()); - // The very first entry is the InstanceKlass of the root method of the current compilation in order to get the right - // protection domain to load subsequent classes during replay compilation. + // The very first entry is the InstanceKlass of the root method of the current compilation. ciInstanceKlass::dump_replay_instanceKlass(out, task()->method()->method_holder()); for (int i = 0; i < objects->length(); i++) { diff --git a/src/hotspot/share/ci/ciReplay.cpp b/src/hotspot/share/ci/ciReplay.cpp index fd29e0cf857..c4127263df1 100644 --- a/src/hotspot/share/ci/ciReplay.cpp +++ b/src/hotspot/share/ci/ciReplay.cpp @@ -114,8 +114,6 @@ class CompileReplay : public StackObj { private: FILE* _stream; Thread* _thread; - Handle _protection_domain; - bool _protection_domain_initialized; Handle _loader; int _version; @@ -144,8 +142,6 @@ class CompileReplay : public StackObj { CompileReplay(const char* filename, TRAPS) { _thread = THREAD; _loader = Handle(_thread, SystemDictionary::java_system_loader()); - _protection_domain = Handle(); - _protection_domain_initialized = false; _stream = os::fopen(filename, "rt"); if (_stream == nullptr) { @@ -558,7 +554,7 @@ class CompileReplay : public StackObj { if (_iklass != nullptr) { k = (Klass*)_iklass->find_klass(ciSymbol::make(klass_name->as_C_string()))->constant_encoding(); } else { - k = SystemDictionary::resolve_or_fail(klass_name, _loader, _protection_domain, true, THREAD); + k = SystemDictionary::resolve_or_fail(klass_name, _loader, true, THREAD); } if (HAS_PENDING_EXCEPTION) { oop throwable = PENDING_EXCEPTION; @@ -579,7 +575,7 @@ class CompileReplay : public StackObj { // Lookup a klass Klass* resolve_klass(const char* klass, TRAPS) { Symbol* klass_name = SymbolTable::new_symbol(klass); - return SystemDictionary::resolve_or_fail(klass_name, _loader, _protection_domain, true, THREAD); + return SystemDictionary::resolve_or_fail(klass_name, _loader, true, THREAD); } // Parse the standard tuple of <klass> <name> <signature> @@ -896,18 +892,6 @@ class CompileReplay : public StackObj { // just load the referenced class Klass* k = parse_klass(CHECK); - if (_version >= 1) { - if (!_protection_domain_initialized && k != nullptr) { - assert(_protection_domain() == nullptr, "must be uninitialized"); - // The first entry is the holder class of the method for which a replay compilation is requested. - // Use the same protection domain to load all subsequent classes in order to resolve all classes - // in signatures of inlinees. This ensures that inlining can be done as stated in the replay file. - _protection_domain = Handle(_thread, k->protection_domain()); - } - - _protection_domain_initialized = true; - } - if (k == nullptr) { return; } diff --git a/src/hotspot/share/classfile/classFileParser.cpp b/src/hotspot/share/classfile/classFileParser.cpp index f108835c9c6..12e7cf1ae9d 100644 --- a/src/hotspot/share/classfile/classFileParser.cpp +++ b/src/hotspot/share/classfile/classFileParser.cpp @@ -822,7 +822,6 @@ void ClassFileParser::parse_interfaces(const ClassFileStream* const stream, interf = SystemDictionary::resolve_super_or_fail(_class_name, unresolved_klass, Handle(THREAD, _loader_data->class_loader()), - _protection_domain, false, CHECK); } @@ -5691,7 +5690,6 @@ void ClassFileParser::post_process_parsed_stream(const ClassFileStream* const st SystemDictionary::resolve_super_or_fail(_class_name, super_class_name, loader, - _protection_domain, true, CHECK); } diff --git a/src/hotspot/share/classfile/dictionary.cpp b/src/hotspot/share/classfile/dictionary.cpp index eecfc9e88a0..73d58ac3687 100644 --- a/src/hotspot/share/classfile/dictionary.cpp +++ b/src/hotspot/share/classfile/dictionary.cpp @@ -26,26 +26,14 @@ #include "cds/cdsConfig.hpp" #include "classfile/classLoaderData.inline.hpp" #include "classfile/dictionary.hpp" -#include "classfile/javaClasses.hpp" -#include "classfile/protectionDomainCache.hpp" -#include "classfile/systemDictionary.hpp" -#include "classfile/vmSymbols.hpp" #include "logging/log.hpp" #include "logging/logStream.hpp" #include "memory/iterator.hpp" #include "memory/metaspaceClosure.hpp" #include "memory/resourceArea.hpp" -#include "memory/universe.hpp" -#include "oops/klass.inline.hpp" -#include "oops/method.hpp" -#include "oops/oop.inline.hpp" -#include "oops/oopHandle.inline.hpp" -#include "runtime/handles.inline.hpp" -#include "runtime/javaCalls.hpp" -#include "runtime/mutexLocker.hpp" -#include "runtime/safepointVerifiers.hpp" +#include "oops/instanceKlass.hpp" #include "utilities/concurrentHashTable.inline.hpp" -#include "utilities/growableArray.hpp" +#include "utilities/ostream.hpp" #include "utilities/tableStatistics.hpp" // 2^24 is max size, like StringTable. @@ -69,7 +57,7 @@ Dictionary::~Dictionary() { } uintx Dictionary::Config::get_hash(Value const& value, bool* is_dead) { - return value->instance_klass()->name()->identity_hash(); + return value->name()->identity_hash(); } void* Dictionary::Config::allocate_node(void* context, size_t size, Value const& value) { @@ -77,26 +65,9 @@ void* Dictionary::Config::allocate_node(void* context, size_t size, Value const& } void Dictionary::Config::free_node(void* context, void* memory, Value const& value) { - delete value; // Call DictionaryEntry destructor FreeHeap(memory); } -DictionaryEntry::DictionaryEntry(InstanceKlass* klass) : _instance_klass(klass) { - release_set_package_access_cache(nullptr); -} - -DictionaryEntry::~DictionaryEntry() { - // avoid recursion when deleting linked list - // package_access_cache is accessed during a safepoint. - // This doesn't require a lock because nothing is reading this - // entry anymore. The ClassLoader is dead. - while (package_access_cache_acquire() != nullptr) { - ProtectionDomainEntry* to_delete = package_access_cache_acquire(); - release_set_package_access_cache(to_delete->next_acquire()); - delete to_delete; - } -} - const int _resize_load_trigger = 5; // load factor that will trigger the resize int Dictionary::table_size() const { @@ -108,86 +79,10 @@ bool Dictionary::check_if_needs_resize() { !_table->is_max_size_reached()); } -bool DictionaryEntry::has_package_access_been_granted(Handle protection_domain) { - return protection_domain() == nullptr || !java_lang_System::allow_security_manager() - ? true - : is_in_package_access_cache(protection_domain()); -} - -// Reading the package_access_cache on each DictionaryEntry is lock free and cannot safepoint. -// Adding and deleting entries is under the SystemDictionary_lock -// Deleting unloaded entries on ClassLoaderData for dictionaries that are not unloaded -// is a three step process: -// moving the entries to a separate list, handshake to wait for -// readers to complete (see NSV here), and then actually deleting the entries. -// Deleting entries is done by the ServiceThread when triggered by class unloading. - -bool DictionaryEntry::is_in_package_access_cache(oop protection_domain) const { - assert(Thread::current()->is_Java_thread() || SafepointSynchronize::is_at_safepoint(), - "can only be called by a JavaThread or at safepoint"); - // This cannot safepoint while reading the protection domain set. - NoSafepointVerifier nsv; -#ifdef ASSERT - if (protection_domain == instance_klass()->protection_domain()) { - // Ensure this doesn't show up in the package_access_cache (invariant) - bool in_package_access_cache = false; - for (ProtectionDomainEntry* current = package_access_cache_acquire(); - current != nullptr; - current = current->next_acquire()) { - if (current->object_no_keepalive() == protection_domain) { - in_package_access_cache = true; - break; - } - } - if (in_package_access_cache) { - assert(false, "A klass's protection domain should not show up " - "in its sys. dict. PD set"); - } - } -#endif /* ASSERT */ - - if (protection_domain == instance_klass()->protection_domain()) { - // Succeeds trivially - return true; - } - - for (ProtectionDomainEntry* current = package_access_cache_acquire(); - current != nullptr; - current = current->next_acquire()) { - if (current->object_no_keepalive() == protection_domain) { - return true; - } - } - return false; -} - -void DictionaryEntry::add_to_package_access_cache(ClassLoaderData* loader_data, Handle protection_domain) { - assert_lock_strong(SystemDictionary_lock); - if (!is_in_package_access_cache(protection_domain())) { - WeakHandle obj = ProtectionDomainCacheTable::add_if_absent(protection_domain); - // Additions and deletions hold the SystemDictionary_lock, readers are lock-free - ProtectionDomainEntry* new_head = new ProtectionDomainEntry(obj, _package_access_cache); - release_set_package_access_cache(new_head); - } - LogTarget(Trace, protectiondomain) lt; - if (lt.is_enabled()) { - ResourceMark rm; - LogStream ls(lt); - ls.print("adding protection domain that can access class %s", instance_klass()->name()->as_C_string()); - ls.print(" class loader: "); - loader_data->class_loader()->print_value_on(&ls); - ls.print(" protection domain: "); - protection_domain->print_value_on(&ls); - ls.print(" "); - print_count(&ls); - ls.cr(); - } -} - // Just the classes from defining class loaders void Dictionary::classes_do(void f(InstanceKlass*)) { - auto doit = [&] (DictionaryEntry** value) { - InstanceKlass* k = (*value)->instance_klass(); + auto doit = [&] (InstanceKlass** value) { + InstanceKlass* k = (*value); if (loader_data() == k->class_loader_data()) { f(k); } @@ -199,8 +94,8 @@ void Dictionary::classes_do(void f(InstanceKlass*)) { // All classes, and their class loaders, including initiating class loaders void Dictionary::all_entries_do(KlassClosure* closure) { - auto all_doit = [&] (DictionaryEntry** value) { - InstanceKlass* k = (*value)->instance_klass(); + auto all_doit = [&] (InstanceKlass** value) { + InstanceKlass* k = (*value); closure->do_klass(k); return true; }; @@ -212,9 +107,8 @@ void Dictionary::all_entries_do(KlassClosure* closure) { void Dictionary::classes_do(MetaspaceClosure* it) { assert(CDSConfig::is_dumping_archive(), "sanity"); - auto push = [&] (DictionaryEntry** value) { - InstanceKlass** k = (*value)->instance_klass_addr(); - it->push(k); + auto push = [&] (InstanceKlass** value) { + it->push(value); return true; }; _table->do_scan(Thread::current(), push); @@ -228,26 +122,25 @@ class DictionaryLookup : StackObj { uintx get_hash() const { return _name->identity_hash(); } - bool equals(DictionaryEntry** value) { - DictionaryEntry *entry = *value; - return (entry->instance_klass()->name() == _name); + bool equals(InstanceKlass** value) { + InstanceKlass* entry = *value; + return (entry->name() == _name); } - bool is_dead(DictionaryEntry** value) { + bool is_dead(InstanceKlass** value) { return false; } }; // Add a loaded class to the dictionary. void Dictionary::add_klass(JavaThread* current, Symbol* class_name, - InstanceKlass* obj) { + InstanceKlass* klass) { assert_locked_or_safepoint(SystemDictionary_lock); // doesn't matter now - assert(obj != nullptr, "adding nullptr obj"); - assert(obj->name() == class_name, "sanity check on name"); + assert(klass != nullptr, "adding nullptr obj"); + assert(klass->name() == class_name, "sanity check on name"); - DictionaryEntry* entry = new DictionaryEntry(obj); DictionaryLookup lookup(class_name); bool needs_rehashing, clean_hint; - bool created = _table->insert(current, lookup, entry, &needs_rehashing, &clean_hint); + bool created = _table->insert(current, lookup, klass, &needs_rehashing, &clean_hint); assert(created, "should be because we have a lock"); assert (!needs_rehashing, "should never need rehashing"); assert(!clean_hint, "no class should be unloaded"); @@ -277,11 +170,10 @@ void Dictionary::add_klass(JavaThread* current, Symbol* class_name, // Callers should be aware that an entry could be added just after // the table is read here, so the caller will not see the new entry. // The entry may be accessed by the VM thread in verification. -DictionaryEntry* Dictionary::get_entry(Thread* current, - Symbol* class_name) { +InstanceKlass* Dictionary::find_class(Thread* current, Symbol* class_name) { DictionaryLookup lookup(class_name); - DictionaryEntry* result = nullptr; - auto get = [&] (DictionaryEntry** value) { + InstanceKlass* result = nullptr; + auto get = [&] (InstanceKlass** value) { // function called if value is found so is never null result = (*value); }; @@ -291,137 +183,6 @@ DictionaryEntry* Dictionary::get_entry(Thread* current, return result; } -// If SecurityManager is allowed, return the class ONLY IF the protection_domain has been -// granted access to this class by a previous call to Dictionary::check_package_access() -InstanceKlass* Dictionary::find(Thread* current, Symbol* name, - Handle protection_domain) { - NoSafepointVerifier nsv; - - DictionaryEntry* entry = get_entry(current, name); - if (entry != nullptr && entry->has_package_access_been_granted(protection_domain)) { - return entry->instance_klass(); - } else { - return nullptr; - } -} - -InstanceKlass* Dictionary::find_class(Thread* current, - Symbol* name) { - assert_locked_or_safepoint(SystemDictionary_lock); - DictionaryEntry* entry = get_entry(current, name); - return (entry != nullptr) ? entry->instance_klass() : nullptr; -} - -void Dictionary::add_to_package_access_cache(JavaThread* current, - InstanceKlass* klass, - Handle protection_domain) { - assert(java_lang_System::allow_security_manager(), "only needed if security manager allowed"); - Symbol* klass_name = klass->name(); - DictionaryEntry* entry = get_entry(current, klass_name); - - assert(entry != nullptr,"entry must be present, we just created it"); - assert(protection_domain() != nullptr, - "real protection domain should be present"); - - entry->add_to_package_access_cache(loader_data(), protection_domain); - -#ifdef ASSERT - assert(loader_data() != ClassLoaderData::the_null_class_loader_data(), "doesn't make sense"); -#endif - - assert(entry->is_in_package_access_cache(protection_domain()), - "now protection domain should be present"); -} - -inline bool Dictionary::is_in_package_access_cache(JavaThread* current, - Symbol* name, - Handle protection_domain) { - DictionaryEntry* entry = get_entry(current, name); - return entry->has_package_access_been_granted(protection_domain); -} - -void Dictionary::check_package_access(InstanceKlass* klass, - Handle class_loader, - Handle protection_domain, - TRAPS) { - - assert(class_loader() != nullptr, "Should not call this"); - assert(protection_domain() != nullptr, "Should not call this"); -} - -// During class loading we may have cached a protection domain that has -// since been unreferenced, so this entry should be cleared. -void Dictionary::remove_from_package_access_cache(GrowableArray<ProtectionDomainEntry*>* delete_list) { - assert(Thread::current()->is_Java_thread(), "only called by JavaThread"); - assert_lock_strong(SystemDictionary_lock); - assert(!loader_data()->has_class_mirror_holder(), "cld should have a ClassLoader holder not a Class holder"); - - if (loader_data()->is_the_null_class_loader_data()) { - // Classes in the boot loader are not loaded with protection domains - return; - } - - auto clean_entries = [&] (DictionaryEntry** value) { - DictionaryEntry* probe = *value; - Klass* e = probe->instance_klass(); - - ProtectionDomainEntry* current = probe->package_access_cache_acquire(); - ProtectionDomainEntry* prev = nullptr; - while (current != nullptr) { - if (current->object_no_keepalive() == nullptr) { - LogTarget(Debug, protectiondomain) lt; - if (lt.is_enabled()) { - ResourceMark rm; - // Print out trace information - LogStream ls(lt); - ls.print_cr("PD in set is not alive:"); - ls.print("class loader: "); _loader_data->class_loader()->print_value_on(&ls); - ls.print(" loading: "); probe->instance_klass()->print_value_on(&ls); - ls.cr(); - } - if (probe->package_access_cache_acquire() == current) { - probe->release_set_package_access_cache(current->next_acquire()); - } else { - assert(prev != nullptr, "should be set by alive entry"); - prev->release_set_next(current->next_acquire()); - } - // Mark current for deletion but in the meantime it can still be - // traversed. - delete_list->push(current); - current = current->next_acquire(); - } else { - prev = current; - current = current->next_acquire(); - } - } - return true; - }; - - _table->do_scan(Thread::current(), clean_entries); -} - -void DictionaryEntry::verify_package_access_cache() { - assert(SafepointSynchronize::is_at_safepoint(), "must only be called as safepoint"); - for (ProtectionDomainEntry* current = package_access_cache_acquire(); // accessed at a safepoint - current != nullptr; - current = current->next_acquire()) { - guarantee(oopDesc::is_oop_or_null(current->object_no_keepalive()), "Invalid oop"); - } -} - -void DictionaryEntry::print_count(outputStream *st) { - assert_locked_or_safepoint(SystemDictionary_lock); - int count = 0; - for (ProtectionDomainEntry* current = package_access_cache_acquire(); - current != nullptr; - current = current->next_acquire()) { - count++; - } - st->print("pd set count = #%d", count); -} - -// ---------------------------------------------------------------------------- - void Dictionary::print_size(outputStream* st) const { st->print_cr("Java dictionary (table_size=%d, classes=%d)", table_size(), _number_of_entries); @@ -435,9 +196,8 @@ void Dictionary::print_on(outputStream* st) const { print_size(st); st->print_cr("^ indicates that initiating loader is different from defining loader"); - auto printer = [&] (DictionaryEntry** entry) { - DictionaryEntry* probe = *entry; - Klass* e = probe->instance_klass(); + auto printer = [&] (InstanceKlass** entry) { + InstanceKlass* e = *entry; bool is_defining_class = (_loader_data == e->class_loader_data()); st->print(" %s%s", is_defining_class ? " " : "^", e->external_name()); @@ -448,7 +208,6 @@ void Dictionary::print_on(outputStream* st) const { st->print(", "); cld->print_value_on(st); st->print(", "); - probe->print_count(st); } st->cr(); return true; @@ -462,14 +221,6 @@ void Dictionary::print_on(outputStream* st) const { tty->cr(); } -void DictionaryEntry::verify() { - Klass* e = instance_klass(); - guarantee(e->is_instance_klass(), - "Verify of dictionary failed"); - e->verify(); - verify_package_access_cache(); -} - void Dictionary::verify() { guarantee(_number_of_entries >= 0, "Verify of dictionary failed"); @@ -480,7 +231,7 @@ void Dictionary::verify() { (cld->is_the_null_class_loader_data() || cld->class_loader_no_keepalive()->is_instance()), "checking type of class_loader"); - auto verifier = [&] (DictionaryEntry** val) { + auto verifier = [&] (InstanceKlass** val) { (*val)->verify(); return true; }; @@ -490,7 +241,7 @@ void Dictionary::verify() { void Dictionary::print_table_statistics(outputStream* st, const char* table_name) { static TableStatistics ts; - auto sz = [&] (DictionaryEntry** val) { + auto sz = [&] (InstanceKlass** val) { return sizeof(**val); }; ts = _table->statistics_get(Thread::current(), sz, ts); diff --git a/src/hotspot/share/classfile/dictionary.hpp b/src/hotspot/share/classfile/dictionary.hpp index fc2747e916a..3f7f381b466 100644 --- a/src/hotspot/share/classfile/dictionary.hpp +++ b/src/hotspot/share/classfile/dictionary.hpp @@ -25,27 +25,21 @@ #ifndef SHARE_CLASSFILE_DICTIONARY_HPP #define SHARE_CLASSFILE_DICTIONARY_HPP -#include "oops/instanceKlass.hpp" -#include "oops/oop.hpp" -#include "oops/oopHandle.hpp" #include "utilities/concurrentHashTable.hpp" -#include "utilities/ostream.hpp" -class DictionaryEntry; -class ProtectionDomainEntry; -template <typename T> class GrowableArray; +class ClassLoaderData; +class InstanceKlass; +class outputStream; //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ // The data structure for the class loader data dictionaries. -class DictionaryEntry; - class Dictionary : public CHeapObj<mtClass> { int _number_of_entries; class Config { public: - using Value = DictionaryEntry*; + using Value = InstanceKlass*; static uintx get_hash(Value const& value, bool* is_dead); static void* allocate_node(void* context, size_t size, Value const& value); static void free_node(void* context, void* memory, Value const& value); @@ -57,7 +51,6 @@ class Dictionary : public CHeapObj<mtClass> { ClassLoaderData* _loader_data; // backpointer to owning loader ClassLoaderData* loader_data() const { return _loader_data; } - DictionaryEntry* get_entry(Thread* current, Symbol* name); bool check_if_needs_resize(); int table_size() const; @@ -73,58 +66,11 @@ class Dictionary : public CHeapObj<mtClass> { void all_entries_do(KlassClosure* closure); void classes_do(MetaspaceClosure* it); - void remove_from_package_access_cache(GrowableArray<ProtectionDomainEntry*>* delete_list); - - InstanceKlass* find(Thread* current, Symbol* name, Handle protection_domain); - - // May make Java upcalls to ClassLoader.checkPackageAccess() when a SecurityManager - // is installed. - void check_package_access(InstanceKlass* klass, - Handle class_loader, - Handle protection_domain, - TRAPS); - void print_table_statistics(outputStream* st, const char* table_name); void print_on(outputStream* st) const; void print_size(outputStream* st) const; void verify(); - - private: - bool is_in_package_access_cache(JavaThread* current, Symbol* name, - Handle protection_domain); - void add_to_package_access_cache(JavaThread* current, InstanceKlass* klass, - Handle protection_domain); -}; - -class DictionaryEntry : public CHeapObj<mtClass> { - private: - InstanceKlass* _instance_klass; - - // A cache of the ProtectionDomains that have been granted - // access to the package of _instance_klass by Java up-calls to - // ClassLoader.checkPackageAccess(). See Dictionary::check_package_access(). - // - // We use a cache to avoid repeat Java up-calls that can be expensive. - ProtectionDomainEntry* volatile _package_access_cache; - - public: - DictionaryEntry(InstanceKlass* instance_klass); - ~DictionaryEntry(); - - bool is_in_package_access_cache(oop protection_domain) const; - void add_to_package_access_cache(ClassLoaderData* loader_data, Handle protection_domain); - inline bool has_package_access_been_granted(Handle protection_domain); - void verify_package_access_cache(); - - InstanceKlass* instance_klass() const { return _instance_klass; } - InstanceKlass** instance_klass_addr() { return &_instance_klass; } - - ProtectionDomainEntry* package_access_cache_acquire() const { return Atomic::load_acquire(&_package_access_cache); } - void release_set_package_access_cache(ProtectionDomainEntry* entry) { Atomic::release_store(&_package_access_cache, entry); } - - void print_count(outputStream *st); - void verify(); }; #endif // SHARE_CLASSFILE_DICTIONARY_HPP diff --git a/src/hotspot/share/classfile/javaClasses.cpp b/src/hotspot/share/classfile/javaClasses.cpp index 12d3ef79cd0..2e8f6541418 100644 --- a/src/hotspot/share/classfile/javaClasses.cpp +++ b/src/hotspot/share/classfile/javaClasses.cpp @@ -1646,7 +1646,7 @@ JFR_ONLY(int java_lang_Thread::_jfr_epoch_offset;) #define THREAD_FIELDS_DO(macro) \ macro(_holder_offset, k, "holder", thread_fieldholder_signature, false); \ macro(_name_offset, k, vmSymbols::name_name(), string_signature, false); \ - macro(_contextClassLoader_offset, k, vmSymbols::contextClassLoader_name(), classloader_signature, false); \ + macro(_contextClassLoader_offset, k, "contextClassLoader", classloader_signature, false); \ macro(_eetop_offset, k, "eetop", long_signature, false); \ macro(_interrupted_offset, k, "interrupted", bool_signature, false); \ macro(_interruptLock_offset, k, "interruptLock", object_signature, false); \ @@ -4721,47 +4721,6 @@ DependencyContext java_lang_invoke_MethodHandleNatives_CallSiteContext::vmdepend return dep_ctx; } -// Support for java_security_AccessControlContext - -int java_security_AccessControlContext::_context_offset; -int java_security_AccessControlContext::_privilegedContext_offset; -int java_security_AccessControlContext::_isPrivileged_offset; -int java_security_AccessControlContext::_isAuthorized_offset; - -#define ACCESSCONTROLCONTEXT_FIELDS_DO(macro) \ - macro(_context_offset, k, "context", protectiondomain_signature, false); \ - macro(_privilegedContext_offset, k, "privilegedContext", accesscontrolcontext_signature, false); \ - macro(_isPrivileged_offset, k, "isPrivileged", bool_signature, false); \ - macro(_isAuthorized_offset, k, "isAuthorized", bool_signature, false) - -void java_security_AccessControlContext::compute_offsets() { - assert(_isPrivileged_offset == 0, "offsets should be initialized only once"); - InstanceKlass* k = vmClasses::AccessControlContext_klass(); - ACCESSCONTROLCONTEXT_FIELDS_DO(FIELD_COMPUTE_OFFSET); -} - -#if INCLUDE_CDS -void java_security_AccessControlContext::serialize_offsets(SerializeClosure* f) { - ACCESSCONTROLCONTEXT_FIELDS_DO(FIELD_SERIALIZE_OFFSET); -} -#endif - -oop java_security_AccessControlContext::create(objArrayHandle context, bool isPrivileged, Handle privileged_context, TRAPS) { - assert(_isPrivileged_offset != 0, "offsets should have been initialized"); - assert(_isAuthorized_offset != 0, "offsets should have been initialized"); - // Ensure klass is initialized - vmClasses::AccessControlContext_klass()->initialize(CHECK_NULL); - // Allocate result - oop result = vmClasses::AccessControlContext_klass()->allocate_instance(CHECK_NULL); - // Fill in values - result->obj_field_put(_context_offset, context()); - result->obj_field_put(_privilegedContext_offset, privileged_context()); - result->bool_field_put(_isPrivileged_offset, isPrivileged); - result->bool_field_put(_isAuthorized_offset, true); - return result; -} - - // Support for java_lang_ClassLoader int java_lang_ClassLoader::_loader_data_offset; @@ -4898,17 +4857,6 @@ void java_lang_System::compute_offsets() { SYSTEM_FIELDS_DO(FIELD_COMPUTE_OFFSET); } -// This field tells us that a security manager can never be installed so we -// can completely skip populating the ProtectionDomainCacheTable. -bool java_lang_System::allow_security_manager() { - return false; -} - -// This field tells us that a security manager is installed. -bool java_lang_System::has_security_manager() { - return false; -} - #if INCLUDE_CDS void java_lang_System::serialize_offsets(SerializeClosure* f) { SYSTEM_FIELDS_DO(FIELD_SERIALIZE_OFFSET); @@ -5423,7 +5371,6 @@ void java_lang_InternalError::serialize_offsets(SerializeClosure* f) { f(java_lang_invoke_CallSite) \ f(java_lang_invoke_ConstantCallSite) \ f(java_lang_invoke_MethodHandleNatives_CallSiteContext) \ - f(java_security_AccessControlContext) \ f(java_lang_reflect_AccessibleObject) \ f(java_lang_reflect_Method) \ f(java_lang_reflect_Constructor) \ diff --git a/src/hotspot/share/classfile/javaClasses.hpp b/src/hotspot/share/classfile/javaClasses.hpp index dcb94878aed..843c8012d2d 100644 --- a/src/hotspot/share/classfile/javaClasses.hpp +++ b/src/hotspot/share/classfile/javaClasses.hpp @@ -1480,27 +1480,6 @@ class java_lang_invoke_MethodHandleNatives_CallSiteContext : AllStatic { static bool is_instance(oop obj); }; -// Interface to java.security.AccessControlContext objects - -class java_security_AccessControlContext: AllStatic { - private: - // Note that for this class the layout changed between JDK1.2 and JDK1.3, - // so we compute the offsets at startup rather than hard-wiring them. - static int _context_offset; - static int _privilegedContext_offset; - static int _isPrivileged_offset; - static int _isAuthorized_offset; - - static void compute_offsets(); - public: - static void serialize_offsets(SerializeClosure* f) NOT_CDS_RETURN; - static oop create(objArrayHandle context, bool isPrivileged, Handle privileged_context, TRAPS); - - // Debugging/initialization - friend class JavaClasses; -}; - - // Interface to java.lang.ClassLoader objects #define CLASSLOADER_INJECTED_FIELDS(macro) \ @@ -1557,16 +1536,11 @@ class java_lang_System : AllStatic { static int _static_in_offset; static int _static_out_offset; static int _static_err_offset; - static int _static_security_offset; - static int _static_allow_security_offset; - static int _static_never_offset; public: static int in_offset() { CHECK_INIT(_static_in_offset); } static int out_offset() { CHECK_INIT(_static_out_offset); } static int err_offset() { CHECK_INIT(_static_err_offset); } - static bool allow_security_manager(); - static bool has_security_manager(); static void compute_offsets(); static void serialize_offsets(SerializeClosure* f) NOT_CDS_RETURN; diff --git a/src/hotspot/share/classfile/protectionDomainCache.cpp b/src/hotspot/share/classfile/protectionDomainCache.cpp deleted file mode 100644 index d6c83253ee7..00000000000 --- a/src/hotspot/share/classfile/protectionDomainCache.cpp +++ /dev/null @@ -1,228 +0,0 @@ -/* - * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - * - */ - -#include "precompiled.hpp" -#include "classfile/classLoaderDataGraph.hpp" -#include "classfile/dictionary.hpp" -#include "classfile/javaClasses.hpp" -#include "classfile/protectionDomainCache.hpp" -#include "logging/log.hpp" -#include "logging/logStream.hpp" -#include "memory/iterator.hpp" -#include "memory/resourceArea.hpp" -#include "memory/universe.hpp" -#include "oops/oop.inline.hpp" -#include "oops/weakHandle.inline.hpp" -#include "runtime/atomic.hpp" -#include "runtime/mutexLocker.hpp" -#include "utilities/growableArray.hpp" -#include "utilities/resourceHash.hpp" - -unsigned int ProtectionDomainCacheTable::compute_hash(const WeakHandle& protection_domain) { - // The protection domain in the hash computation is passed from a Handle so cannot resolve to null. - assert(protection_domain.peek() != nullptr, "Must be live"); - return (unsigned int)(protection_domain.resolve()->identity_hash()); -} - -bool ProtectionDomainCacheTable::equals(const WeakHandle& protection_domain1, const WeakHandle& protection_domain2) { - return protection_domain1.peek() == protection_domain2.peek(); -} - -// WeakHandle is both the key and the value. We need it as the key to compare the oops that each point to -// for equality. We need it as the value to return the one that already exists to link in the DictionaryEntry. -using InternalProtectionDomainCacheTable = ResourceHashtable<WeakHandle, WeakHandle, 1009, AnyObj::C_HEAP, mtClass, - ProtectionDomainCacheTable::compute_hash, - ProtectionDomainCacheTable::equals>; -static InternalProtectionDomainCacheTable* _pd_cache_table; - -bool ProtectionDomainCacheTable::_dead_entries = false; -int ProtectionDomainCacheTable::_total_oops_removed = 0; - -void ProtectionDomainCacheTable::initialize(){ - _pd_cache_table = new (mtClass) InternalProtectionDomainCacheTable(); -} -void ProtectionDomainCacheTable::trigger_cleanup() { - MutexLocker ml(Service_lock, Mutex::_no_safepoint_check_flag); - _dead_entries = true; - Service_lock->notify_all(); -} - -class CleanProtectionDomainEntries : public CLDClosure { - GrowableArray<ProtectionDomainEntry*>* _delete_list; - public: - CleanProtectionDomainEntries(GrowableArray<ProtectionDomainEntry*>* delete_list) : - _delete_list(delete_list) {} - - void do_cld(ClassLoaderData* data) { - Dictionary* dictionary = data->dictionary(); - if (dictionary != nullptr) { - dictionary->remove_from_package_access_cache(_delete_list); - } - } -}; - -static GrowableArray<ProtectionDomainEntry*>* _delete_list = nullptr; - -class HandshakeForPD : public HandshakeClosure { - public: - HandshakeForPD() : HandshakeClosure("HandshakeForPD") {} - - void do_thread(Thread* thread) { - log_trace(protectiondomain)("HandshakeForPD::do_thread: thread=" - INTPTR_FORMAT, p2i(thread)); - } -}; - -static void purge_deleted_entries() { - // If there are any deleted entries, Handshake-all then they'll be - // safe to remove since traversing the package_access_cache list does not stop for - // safepoints and only JavaThreads will read the package_access_cache. - // This is actually quite rare because the protection domain is generally associated - // with the caller class and class loader, which if still alive will keep this - // protection domain entry alive. - if (_delete_list->length() >= 10) { - HandshakeForPD hs_pd; - Handshake::execute(&hs_pd); - - for (int i = _delete_list->length() - 1; i >= 0; i--) { - ProtectionDomainEntry* entry = _delete_list->at(i); - _delete_list->remove_at(i); - delete entry; - } - assert(_delete_list->length() == 0, "should be cleared"); - } -} - -void ProtectionDomainCacheTable::unlink() { - // DictionaryEntry::_package_access_cache should be null also, so nothing to do. - assert(java_lang_System::allow_security_manager(), "should not be called otherwise"); - - // Create a list for holding deleted entries - if (_delete_list == nullptr) { - _delete_list = new (mtClass) - GrowableArray<ProtectionDomainEntry*>(20, mtClass); - } - - { - // First clean cached pd lists in loaded CLDs - // It's unlikely, but some loaded classes in a dictionary might - // point to a protection_domain that has been unloaded. - // DictionaryEntry::_package_access_cache points at entries in the ProtectionDomainCacheTable. - MutexLocker ml(ClassLoaderDataGraph_lock); - MutexLocker mldict(SystemDictionary_lock); // need both. - CleanProtectionDomainEntries clean(_delete_list); - ClassLoaderDataGraph::loaded_cld_do(&clean); - } - - // Purge any deleted entries outside of the SystemDictionary_lock. - purge_deleted_entries(); - - // Reacquire the lock to remove entries from the hashtable. - MutexLocker ml(SystemDictionary_lock); - - struct Deleter { - int _oops_removed; - Deleter() : _oops_removed(0) {} - - bool do_entry(WeakHandle& key, WeakHandle& value) { - oop pd = value.peek(); - if (value.peek() == nullptr) { - _oops_removed++; - LogTarget(Debug, protectiondomain, table) lt; - if (lt.is_enabled()) { - LogStream ls(lt); - ls.print_cr("protection domain unlinked %d", _oops_removed); - } - value.release(Universe::vm_weak()); - return true; - } else { - return false; - } - } - }; - - Deleter deleter; - _pd_cache_table->unlink(&deleter); - - _total_oops_removed += deleter._oops_removed; - _dead_entries = false; -} - -void ProtectionDomainCacheTable::print_on(outputStream* st) { - assert_locked_or_safepoint(SystemDictionary_lock); - auto printer = [&] (WeakHandle& key, WeakHandle& value) { - st->print_cr(" protection_domain: " PTR_FORMAT, p2i(value.peek())); - }; - st->print_cr("Protection domain cache table (table_size=%d, protection domains=%d)", - _pd_cache_table->table_size(), _pd_cache_table->number_of_entries()); - _pd_cache_table->iterate_all(printer); -} - -void ProtectionDomainCacheTable::verify() { - auto verifier = [&] (WeakHandle& key, WeakHandle& value) { - guarantee(value.peek() == nullptr || oopDesc::is_oop(value.peek()), "must be an oop"); - }; - _pd_cache_table->iterate_all(verifier); -} - -// The object_no_keepalive() call peeks at the phantomly reachable oop without -// keeping it alive. This is used for traversing DictionaryEntry::_package_access_cache. -oop ProtectionDomainEntry::object_no_keepalive() { - return _object.peek(); -} - -WeakHandle ProtectionDomainCacheTable::add_if_absent(Handle protection_domain) { - assert_locked_or_safepoint(SystemDictionary_lock); - WeakHandle w(Universe::vm_weak(), protection_domain); - bool created; - WeakHandle* wk = _pd_cache_table->put_if_absent(w, w, &created); - if (!created) { - // delete the one created since we already had it in the table - w.release(Universe::vm_weak()); - } else { - LogTarget(Debug, protectiondomain, table) lt; - if (lt.is_enabled()) { - LogStream ls(lt); - ls.print("protection domain added "); - protection_domain->print_value_on(&ls); - ls.cr(); - } - } - // Keep entry alive - (void)wk->resolve(); - return *wk; -} - -void ProtectionDomainCacheTable::print_table_statistics(outputStream* st) { - auto size = [&] (WeakHandle& key, WeakHandle& value) { - // The only storage is in OopStorage for an oop - return sizeof(oop); - }; - TableStatistics ts = _pd_cache_table->statistics_calculate(size); - ts.print(st, "ProtectionDomainCacheTable"); -} - -int ProtectionDomainCacheTable::number_of_entries() { - return _pd_cache_table->number_of_entries(); -} diff --git a/src/hotspot/share/classfile/protectionDomainCache.hpp b/src/hotspot/share/classfile/protectionDomainCache.hpp deleted file mode 100644 index 8ba69d9ab66..00000000000 --- a/src/hotspot/share/classfile/protectionDomainCache.hpp +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - * - */ - -#ifndef SHARE_CLASSFILE_PROTECTIONDOMAINCACHE_HPP -#define SHARE_CLASSFILE_PROTECTIONDOMAINCACHE_HPP - -#include "oops/oop.hpp" -#include "oops/weakHandle.hpp" -#include "runtime/atomic.hpp" - -// The ProtectionDomainCacheTable maps all java.security.ProtectionDomain objects that are -// registered by DictionaryEntry::add_to_package_access_cache() to a unique WeakHandle. -// The amount of different protection domains used is typically magnitudes smaller -// than the number of system dictionary entries (loaded classes). -class ProtectionDomainCacheTable : public AllStatic { - - static bool _dead_entries; - static int _total_oops_removed; - -public: - static void initialize(); - static unsigned int compute_hash(const WeakHandle& protection_domain); - static bool equals(const WeakHandle& protection_domain1, const WeakHandle& protection_domain2); - - static WeakHandle add_if_absent(Handle protection_domain); - static void unlink(); - - static void print_on(outputStream* st); - static void verify(); - - static bool has_work() { return _dead_entries; } - static void trigger_cleanup(); - - static int removed_entries_count() { return _total_oops_removed; }; - static int number_of_entries(); - static void print_table_statistics(outputStream* st); -}; - - -// This describes the linked list protection domain for each DictionaryEntry in its package_access_cache. -class ProtectionDomainEntry :public CHeapObj<mtClass> { - WeakHandle _object; - ProtectionDomainEntry* volatile _next; - public: - - ProtectionDomainEntry(WeakHandle obj, - ProtectionDomainEntry* head) : _object(obj), _next(head) {} - - ProtectionDomainEntry* next_acquire() { return Atomic::load_acquire(&_next); } - void release_set_next(ProtectionDomainEntry* entry) { Atomic::release_store(&_next, entry); } - oop object_no_keepalive(); -}; -#endif // SHARE_CLASSFILE_PROTECTIONDOMAINCACHE_HPP diff --git a/src/hotspot/share/classfile/systemDictionary.cpp b/src/hotspot/share/classfile/systemDictionary.cpp index b9b341c4dab..0cd9886bd01 100644 --- a/src/hotspot/share/classfile/systemDictionary.cpp +++ b/src/hotspot/share/classfile/systemDictionary.cpp @@ -38,7 +38,6 @@ #include "classfile/loaderConstraints.hpp" #include "classfile/packageEntry.hpp" #include "classfile/placeholders.hpp" -#include "classfile/protectionDomainCache.hpp" #include "classfile/resolutionErrors.hpp" #include "classfile/stringTable.hpp" #include "classfile/symbolTable.hpp" @@ -331,9 +330,9 @@ static void handle_resolution_exception(Symbol* class_name, bool throw_error, TR // Forwards to resolve_or_null -Klass* SystemDictionary::resolve_or_fail(Symbol* class_name, Handle class_loader, Handle protection_domain, +Klass* SystemDictionary::resolve_or_fail(Symbol* class_name, Handle class_loader, bool throw_error, TRAPS) { - Klass* klass = resolve_or_null(class_name, class_loader, protection_domain, THREAD); + Klass* klass = resolve_or_null(class_name, class_loader, THREAD); // Check for pending exception or null klass, and throw exception if (HAS_PENDING_EXCEPTION || klass == nullptr) { handle_resolution_exception(class_name, throw_error, CHECK_NULL); @@ -343,9 +342,9 @@ Klass* SystemDictionary::resolve_or_fail(Symbol* class_name, Handle class_loader // Forwards to resolve_array_class_or_null or resolve_instance_class_or_null -Klass* SystemDictionary::resolve_or_null(Symbol* class_name, Handle class_loader, Handle protection_domain, TRAPS) { +Klass* SystemDictionary::resolve_or_null(Symbol* class_name, Handle class_loader, TRAPS) { if (Signature::is_array(class_name)) { - return resolve_array_class_or_null(class_name, class_loader, protection_domain, THREAD); + return resolve_array_class_or_null(class_name, class_loader, THREAD); } else { assert(class_name != nullptr && !Signature::is_array(class_name), "must be"); if (Signature::has_envelope(class_name)) { @@ -353,9 +352,9 @@ Klass* SystemDictionary::resolve_or_null(Symbol* class_name, Handle class_loader // Ignore wrapping L and ;. TempNewSymbol name = SymbolTable::new_symbol(class_name->as_C_string() + 1, class_name->utf8_length() - 2); - return resolve_instance_class_or_null(name, class_loader, protection_domain, THREAD); + return resolve_instance_class_or_null(name, class_loader, THREAD); } else { - return resolve_instance_class_or_null(class_name, class_loader, protection_domain, THREAD); + return resolve_instance_class_or_null(class_name, class_loader, THREAD); } } } @@ -364,7 +363,6 @@ Klass* SystemDictionary::resolve_or_null(Symbol* class_name, Handle class_loader Klass* SystemDictionary::resolve_array_class_or_null(Symbol* class_name, Handle class_loader, - Handle protection_domain, TRAPS) { assert(Signature::is_array(class_name), "must be array"); ResourceMark rm(THREAD); @@ -376,7 +374,6 @@ Klass* SystemDictionary::resolve_array_class_or_null(Symbol* class_name, Symbol* obj_class = ss.as_symbol(); k = SystemDictionary::resolve_instance_class_or_null(obj_class, class_loader, - protection_domain, CHECK_NULL); if (k != nullptr) { k = k->array_klass(ndims, CHECK_NULL); @@ -422,7 +419,6 @@ static inline void log_circularity_error(Symbol* name, PlaceholderEntry* probe) InstanceKlass* SystemDictionary::resolve_with_circularity_detection(Symbol* class_name, Symbol* next_name, Handle class_loader, - Handle protection_domain, bool is_superclass, TRAPS) { @@ -487,7 +483,6 @@ InstanceKlass* SystemDictionary::resolve_with_circularity_detection(Symbol* clas InstanceKlass* superk = SystemDictionary::resolve_instance_class_or_null(next_name, class_loader, - protection_domain, THREAD); // Clean up placeholder entry. @@ -514,7 +509,7 @@ InstanceKlass* SystemDictionary::resolve_with_circularity_detection(Symbol* clas static void handle_parallel_super_load(Symbol* name, Symbol* superclassname, Handle class_loader, - Handle protection_domain, TRAPS) { + TRAPS) { // The result superk is not used; resolve_with_circularity_detection is called for circularity check only. // This passes true to is_superclass even though it might not be the super class in order to perform the @@ -522,7 +517,6 @@ static void handle_parallel_super_load(Symbol* name, Klass* superk = SystemDictionary::resolve_with_circularity_detection(name, superclassname, class_loader, - protection_domain, true, CHECK); } @@ -588,7 +582,6 @@ void SystemDictionary::post_class_load_event(EventClassLoad* event, const Instan // This can return null, an exception or an InstanceKlass. InstanceKlass* SystemDictionary::resolve_instance_class_or_null(Symbol* name, Handle class_loader, - Handle protection_domain, TRAPS) { // name must be in the form of "java/lang/Object" -- cannot be "Ljava/lang/Object;" DEBUG_ONLY(ResourceMark rm(THREAD)); @@ -602,12 +595,8 @@ InstanceKlass* SystemDictionary::resolve_instance_class_or_null(Symbol* name, ClassLoaderData* loader_data = register_loader(class_loader); Dictionary* dictionary = loader_data->dictionary(); - // Do lookup to see if class already exists and the protection domain - // has the right access. - // This call uses find which checks protection domain already matches - // All subsequent calls use find_class, and set loaded_class so that - // before we return a result, we call out to java to check for valid protection domain. - InstanceKlass* probe = dictionary->find(THREAD, name, protection_domain); + // Do lookup to see if class already exists. + InstanceKlass* probe = dictionary->find_class(THREAD, name); if (probe != nullptr) return probe; // Non-bootstrap class loaders will call out to class loader and @@ -653,7 +642,6 @@ InstanceKlass* SystemDictionary::resolve_instance_class_or_null(Symbol* name, if (circularity_detection_in_progress) { handle_parallel_super_load(name, superclassname, class_loader, - protection_domain, CHECK_NULL); } @@ -738,12 +726,6 @@ InstanceKlass* SystemDictionary::resolve_instance_class_or_null(Symbol* name, // Make sure we have the right class in the dictionary DEBUG_ONLY(verify_dictionary_entry(name, loaded_class)); - if (protection_domain() != nullptr) { - // A SecurityManager (if installed) may prevent this protection_domain from accessing loaded_class - // by throwing a SecurityException. - dictionary->check_package_access(loaded_class, class_loader, protection_domain, CHECK_NULL); - } - return loaded_class; } @@ -761,8 +743,7 @@ InstanceKlass* SystemDictionary::resolve_instance_class_or_null(Symbol* name, InstanceKlass* SystemDictionary::find_instance_klass(Thread* current, Symbol* class_name, - Handle class_loader, - Handle protection_domain) { + Handle class_loader) { ClassLoaderData* loader_data = ClassLoaderData::class_loader_data_or_null(class_loader()); if (loader_data == nullptr) { @@ -772,15 +753,14 @@ InstanceKlass* SystemDictionary::find_instance_klass(Thread* current, } Dictionary* dictionary = loader_data->dictionary(); - return dictionary->find(current, class_name, protection_domain); + return dictionary->find_class(current, class_name); } // Look for a loaded instance or array klass by name. Do not do any loading. // return null in case of error. Klass* SystemDictionary::find_instance_or_array_klass(Thread* current, Symbol* class_name, - Handle class_loader, - Handle protection_domain) { + Handle class_loader) { Klass* k = nullptr; assert(class_name != nullptr, "class name must be non nullptr"); @@ -794,13 +774,13 @@ Klass* SystemDictionary::find_instance_or_array_klass(Thread* current, if (t != T_OBJECT) { k = Universe::typeArrayKlass(t); } else { - k = SystemDictionary::find_instance_klass(current, ss.as_symbol(), class_loader, protection_domain); + k = SystemDictionary::find_instance_klass(current, ss.as_symbol(), class_loader); } if (k != nullptr) { k = k->array_klass_or_null(ndims); } } else { - k = find_instance_klass(current, class_name, class_loader, protection_domain); + k = find_instance_klass(current, class_name, class_loader); } return k; } @@ -1044,8 +1024,7 @@ bool SystemDictionary::is_shared_class_visible_impl(Symbol* class_name, } bool SystemDictionary::check_shared_class_super_type(InstanceKlass* klass, InstanceKlass* super_type, - Handle class_loader, Handle protection_domain, - bool is_superclass, TRAPS) { + Handle class_loader, bool is_superclass, TRAPS) { assert(super_type->is_shared(), "must be"); // Quick check if the super type has been already loaded. @@ -1055,14 +1034,14 @@ bool SystemDictionary::check_shared_class_super_type(InstanceKlass* klass, Insta if (!super_type->is_shared_unregistered_class() && super_type->class_loader_data() != nullptr) { // Check if the superclass is loaded by the current class_loader Symbol* name = super_type->name(); - InstanceKlass* check = find_instance_klass(THREAD, name, class_loader, protection_domain); + InstanceKlass* check = find_instance_klass(THREAD, name, class_loader); if (check == super_type) { return true; } } Klass *found = resolve_with_circularity_detection(klass->name(), super_type->name(), - class_loader, protection_domain, is_superclass, CHECK_false); + class_loader, is_superclass, CHECK_false); if (found == super_type) { return true; } else { @@ -1072,8 +1051,7 @@ bool SystemDictionary::check_shared_class_super_type(InstanceKlass* klass, Insta } } -bool SystemDictionary::check_shared_class_super_types(InstanceKlass* ik, Handle class_loader, - Handle protection_domain, TRAPS) { +bool SystemDictionary::check_shared_class_super_types(InstanceKlass* ik, Handle class_loader, TRAPS) { // Check the superclass and interfaces. They must be the same // as in dump time, because the layout of <ik> depends on // the specific layout of ik->super() and ik->local_interfaces(). @@ -1083,7 +1061,7 @@ bool SystemDictionary::check_shared_class_super_types(InstanceKlass* ik, Handle if (ik->super() != nullptr) { bool check_super = check_shared_class_super_type(ik, InstanceKlass::cast(ik->super()), - class_loader, protection_domain, true, + class_loader, true, CHECK_false); if (!check_super) { return false; @@ -1093,7 +1071,7 @@ bool SystemDictionary::check_shared_class_super_types(InstanceKlass* ik, Handle Array<InstanceKlass*>* interfaces = ik->local_interfaces(); int num_interfaces = interfaces->length(); for (int index = 0; index < num_interfaces; index++) { - bool check_interface = check_shared_class_super_type(ik, interfaces->at(index), class_loader, protection_domain, false, + bool check_interface = check_shared_class_super_type(ik, interfaces->at(index), class_loader, false, CHECK_false); if (!check_interface) { return false; @@ -1111,7 +1089,7 @@ InstanceKlass* SystemDictionary::load_shared_lambda_proxy_class(InstanceKlass* i InstanceKlass* shared_nest_host = SystemDictionaryShared::get_shared_nest_host(ik); assert(shared_nest_host->is_shared(), "nest host must be in CDS archive"); Symbol* cn = shared_nest_host->name(); - Klass *s = resolve_or_fail(cn, class_loader, protection_domain, true, CHECK_NULL); + Klass *s = resolve_or_fail(cn, class_loader, true, CHECK_NULL); if (s != shared_nest_host) { // The dynamically resolved nest_host is not the same as the one we used during dump time, // so we cannot use ik. @@ -1151,7 +1129,7 @@ InstanceKlass* SystemDictionary::load_shared_class(InstanceKlass* ik, return nullptr; } - bool check = check_shared_class_super_types(ik, class_loader, protection_domain, CHECK_NULL); + bool check = check_shared_class_super_types(ik, class_loader, CHECK_NULL); if (!check) { ik->set_shared_loading_failed(); return nullptr; @@ -1579,17 +1557,6 @@ bool SystemDictionary::do_unloading(GCTimer* gc_timer) { if (unloading_occurred) { SymbolTable::trigger_cleanup(); - if (java_lang_System::allow_security_manager()) { - // Oops referenced by the protection domain cache table may get unreachable independently - // of the class loader (eg. cached protection domain oops). So we need to - // explicitly unlink them here. - // All protection domain oops are linked to the caller class, so if nothing - // unloads, this is not needed. - ProtectionDomainCacheTable::trigger_cleanup(); - } else { - assert(ProtectionDomainCacheTable::number_of_entries() == 0, "should be empty"); - } - ConditionalMutexLocker ml(ClassInitError_lock, is_concurrent); InstanceKlass::clean_initialization_error_table(); } @@ -1627,7 +1594,6 @@ void SystemDictionary::initialize(TRAPS) { ResolutionErrorTable::initialize(); LoaderConstraintTable::initialize(); PlaceholderTable::initialize(); - ProtectionDomainCacheTable::initialize(); #if INCLUDE_CDS SystemDictionaryShared::initialize(); #endif @@ -1744,10 +1710,7 @@ Klass* SystemDictionary::find_constrained_instance_or_array_klass( Thread* current, Symbol* class_name, Handle class_loader) { // First see if it has been loaded directly. - // Force the protection domain to be null. (This removes protection checks.) - Handle no_protection_domain; - Klass* klass = find_instance_or_array_klass(current, class_name, class_loader, - no_protection_domain); + Klass* klass = find_instance_or_array_klass(current, class_name, class_loader); if (klass != nullptr) return klass; @@ -2195,21 +2158,18 @@ static bool is_always_visible_class(oop mirror) { // N.B. Code in reflection should use this entry point. Handle SystemDictionary::find_java_mirror_for_type(Symbol* signature, Klass* accessing_klass, - Handle class_loader, - Handle protection_domain, SignatureStream::FailureMode failure_mode, TRAPS) { - assert(accessing_klass == nullptr || (class_loader.is_null() && protection_domain.is_null()), - "one or the other, or perhaps neither"); + + Handle class_loader; // What we have here must be a valid field descriptor, // and all valid field descriptors are supported. // Produce the same java.lang.Class that reflection reports. if (accessing_klass != nullptr) { class_loader = Handle(THREAD, accessing_klass->class_loader()); - protection_domain = Handle(THREAD, accessing_klass->protection_domain()); } - ResolvingSignatureStream ss(signature, class_loader, protection_domain, false); + ResolvingSignatureStream ss(signature, class_loader, false); oop mirror_oop = ss.as_java_mirror(failure_mode, CHECK_NH); if (mirror_oop == nullptr) { return Handle(); // report failure this way @@ -2250,10 +2210,9 @@ Handle SystemDictionary::find_method_handle_type(Symbol* signature, return Handle(); // do not attempt from within compiler, unless it was cached } - Handle class_loader, protection_domain; + Handle class_loader; if (accessing_klass != nullptr) { class_loader = Handle(THREAD, accessing_klass->class_loader()); - protection_domain = Handle(THREAD, accessing_klass->protection_domain()); } bool can_be_cached = true; int npts = ArgumentCount(signature).size(); @@ -2265,8 +2224,7 @@ Handle SystemDictionary::find_method_handle_type(Symbol* signature, oop mirror = nullptr; if (can_be_cached) { // Use neutral class loader to lookup candidate classes to be placed in the cache. - mirror = ss.as_java_mirror(Handle(), Handle(), - SignatureStream::ReturnNull, CHECK_(empty)); + mirror = ss.as_java_mirror(Handle(), SignatureStream::ReturnNull, CHECK_(empty)); if (mirror == nullptr || (ss.is_reference() && !is_always_visible_class(mirror))) { // Fall back to accessing_klass context. can_be_cached = false; @@ -2274,8 +2232,7 @@ Handle SystemDictionary::find_method_handle_type(Symbol* signature, } if (!can_be_cached) { // Resolve, throwing a real error if it doesn't work. - mirror = ss.as_java_mirror(class_loader, protection_domain, - SignatureStream::NCDFError, CHECK_(empty)); + mirror = ss.as_java_mirror(class_loader, SignatureStream::NCDFError, CHECK_(empty)); } assert(mirror != nullptr, "%s", ss.as_symbol()->as_C_string()); if (ss.at_return_type()) @@ -2328,12 +2285,11 @@ Handle SystemDictionary::find_field_handle_type(Symbol* signature, ResourceMark rm(THREAD); SignatureStream ss(signature, /*is_method=*/ false); if (!ss.is_done()) { - Handle class_loader, protection_domain; + Handle class_loader; if (accessing_klass != nullptr) { class_loader = Handle(THREAD, accessing_klass->class_loader()); - protection_domain = Handle(THREAD, accessing_klass->protection_domain()); } - oop mirror = ss.as_java_mirror(class_loader, protection_domain, SignatureStream::NCDFError, CHECK_(empty)); + oop mirror = ss.as_java_mirror(class_loader, SignatureStream::NCDFError, CHECK_(empty)); ss.next(); if (ss.is_done()) { return Handle(THREAD, mirror); @@ -2471,9 +2427,6 @@ void SystemDictionary::print_on(outputStream *st) { // loader constraints - print under SD_lock LoaderConstraintTable::print_on(st); st->cr(); - - ProtectionDomainCacheTable::print_on(st); - st->cr(); } void SystemDictionary::print() { print_on(tty); } @@ -2487,9 +2440,6 @@ void SystemDictionary::verify() { // Verify constraint table LoaderConstraintTable::verify(); - - // Verify protection domain table - ProtectionDomainCacheTable::verify(); } void SystemDictionary::dump(outputStream *st, bool verbose) { @@ -2500,7 +2450,6 @@ void SystemDictionary::dump(outputStream *st, bool verbose) { CDS_ONLY(SystemDictionaryShared::print_table_statistics(st)); ClassLoaderDataGraph::print_table_statistics(st); LoaderConstraintTable::print_table_statistics(st); - ProtectionDomainCacheTable::print_table_statistics(st); } } diff --git a/src/hotspot/share/classfile/systemDictionary.hpp b/src/hotspot/share/classfile/systemDictionary.hpp index 9f5f34ee773..5883b76b64b 100644 --- a/src/hotspot/share/classfile/systemDictionary.hpp +++ b/src/hotspot/share/classfile/systemDictionary.hpp @@ -33,12 +33,12 @@ // The dictionary in each ClassLoaderData stores all loaded classes, either // initiatied by its class loader or defined by its class loader: // -// class loader -> ClassLoaderData -> [class, protection domain set] +// class loader -> ClassLoaderData -> Loaded and initiated loaded classes // // Classes are loaded lazily. The default VM class loader is // represented as null. -// The underlying data structure is an open hash table (Dictionary) per +// The underlying data structure is a concurrent hash table (Dictionary) per // ClassLoaderData with a fixed number of buckets. During loading the // class loader object is locked, (for the VM loader a private lock object is used). // The global SystemDictionary_lock is held for all additions into the ClassLoaderData @@ -49,9 +49,7 @@ // a side data structure, and is used to detect ClassCircularityErrors. // // When class loading is finished, a new entry is added to the dictionary -// of the class loader and the placeholder is removed. Note that the protection -// domain field of the dictionary entry has not yet been filled in when -// the "real" dictionary entry is created. +// of the class loader and the placeholder is removed. // // Clients of this class who are interested in finding if a class has // been completely loaded -- not classes in the process of being loaded -- @@ -91,24 +89,23 @@ class SystemDictionary : AllStatic { // throw_error flag. For most uses the throw_error argument should be set // to true. - static Klass* resolve_or_fail(Symbol* class_name, Handle class_loader, Handle protection_domain, bool throw_error, TRAPS); + static Klass* resolve_or_fail(Symbol* class_name, Handle class_loader, bool throw_error, TRAPS); // Convenient call for null loader and protection domain. static Klass* resolve_or_fail(Symbol* class_name, bool throw_error, TRAPS) { - return resolve_or_fail(class_name, Handle(), Handle(), throw_error, THREAD); + return resolve_or_fail(class_name, Handle(), throw_error, THREAD); } // Returns a class with a given class name and class loader. // Loads the class if needed. If not found null is returned. - static Klass* resolve_or_null(Symbol* class_name, Handle class_loader, Handle protection_domain, TRAPS); + static Klass* resolve_or_null(Symbol* class_name, Handle class_loader, TRAPS); // Version with null loader and protection domain static Klass* resolve_or_null(Symbol* class_name, TRAPS) { - return resolve_or_null(class_name, Handle(), Handle(), THREAD); + return resolve_or_null(class_name, Handle(), THREAD); } static InstanceKlass* resolve_with_circularity_detection(Symbol* class_name, Symbol* next_name, Handle class_loader, - Handle protection_domain, bool is_superclass, TRAPS); @@ -117,9 +114,8 @@ class SystemDictionary : AllStatic { // "class_name" is the class whose super class or interface is being resolved. static InstanceKlass* resolve_super_or_fail(Symbol* class_name, Symbol* super_name, Handle class_loader, - Handle protection_domain, bool is_superclass, TRAPS) { - return resolve_with_circularity_detection(class_name, super_name, class_loader, protection_domain, - is_superclass, THREAD); + bool is_superclass, TRAPS) { + return resolve_with_circularity_detection(class_name, super_name, class_loader, is_superclass, THREAD); } private: @@ -152,14 +148,13 @@ class SystemDictionary : AllStatic { // Lookup an already loaded class. If not found null is returned. static InstanceKlass* find_instance_klass(Thread* current, Symbol* class_name, - Handle class_loader, Handle protection_domain); + Handle class_loader); // Lookup an already loaded instance or array class. // Do not make any queries to class loaders; consult only the cache. // If not found null is returned. static Klass* find_instance_or_array_klass(Thread* current, Symbol* class_name, - Handle class_loader, - Handle protection_domain); + Handle class_loader); // Lookup an instance or array class that has already been loaded // either into the given class loader, or else into another class @@ -246,21 +241,10 @@ class SystemDictionary : AllStatic { static void restore_archived_method_handle_intrinsics() NOT_CDS_RETURN; // compute java_mirror (java.lang.Class instance) for a type ("I", "[[B", "LFoo;", etc.) - // Either the accessing_klass or the CL/PD can be non-null, but not both. static Handle find_java_mirror_for_type(Symbol* signature, Klass* accessing_klass, - Handle class_loader, - Handle protection_domain, SignatureStream::FailureMode failure_mode, TRAPS); - static Handle find_java_mirror_for_type(Symbol* signature, - Klass* accessing_klass, - SignatureStream::FailureMode failure_mode, - TRAPS) { - // callee will fill in CL/PD from AK, if they are needed - return find_java_mirror_for_type(signature, accessing_klass, Handle(), Handle(), - failure_mode, THREAD); - } // find a java.lang.invoke.MethodType object for a given signature // (asks Java to compute it if necessary, except in a compiler thread) @@ -309,10 +293,10 @@ class SystemDictionary : AllStatic { // Basic loading operations static InstanceKlass* resolve_instance_class_or_null(Symbol* class_name, Handle class_loader, - Handle protection_domain, TRAPS); + TRAPS); static Klass* resolve_array_class_or_null(Symbol* class_name, Handle class_loader, - Handle protection_domain, TRAPS); + TRAPS); static void define_instance_class(InstanceKlass* k, Handle class_loader, TRAPS); static InstanceKlass* find_or_define_helper(Symbol* class_name, Handle class_loader, @@ -334,10 +318,9 @@ class SystemDictionary : AllStatic { PackageEntry* pkg_entry, Handle class_loader); static bool check_shared_class_super_type(InstanceKlass* klass, InstanceKlass* super, - Handle class_loader, Handle protection_domain, + Handle class_loader, bool is_superclass, TRAPS); - static bool check_shared_class_super_types(InstanceKlass* ik, Handle class_loader, - Handle protection_domain, TRAPS); + static bool check_shared_class_super_types(InstanceKlass* ik, Handle class_loader, TRAPS); // Second part of load_shared_class static void load_shared_class_misc(InstanceKlass* ik, ClassLoaderData* loader_data) NOT_CDS_RETURN; static void restore_archived_method_handle_intrinsics_impl(TRAPS) NOT_CDS_RETURN; diff --git a/src/hotspot/share/classfile/verificationType.cpp b/src/hotspot/share/classfile/verificationType.cpp index bd66cf43b5c..ddeee499814 100644 --- a/src/hotspot/share/classfile/verificationType.cpp +++ b/src/hotspot/share/classfile/verificationType.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -57,8 +57,7 @@ bool VerificationType::resolve_and_check_assignability(InstanceKlass* klass, Sym this_class = klass; } else { this_class = SystemDictionary::resolve_or_fail( - name, Handle(THREAD, klass->class_loader()), - Handle(THREAD, klass->protection_domain()), true, CHECK_false); + name, Handle(THREAD, klass->class_loader()), true, CHECK_false); if (log_is_enabled(Debug, class, resolve)) { Verifier::trace_class_resolution(this_class, klass); } @@ -79,8 +78,7 @@ bool VerificationType::resolve_and_check_assignability(InstanceKlass* klass, Sym from_class = klass; } else { from_class = SystemDictionary::resolve_or_fail( - from_name, Handle(THREAD, klass->class_loader()), - Handle(THREAD, klass->protection_domain()), true, CHECK_false); + from_name, Handle(THREAD, klass->class_loader()), true, CHECK_false); if (log_is_enabled(Debug, class, resolve)) { Verifier::trace_class_resolution(from_class, klass); } diff --git a/src/hotspot/share/classfile/verifier.cpp b/src/hotspot/share/classfile/verifier.cpp index e8dc8bcfdc9..ef3caff6476 100644 --- a/src/hotspot/share/classfile/verifier.cpp +++ b/src/hotspot/share/classfile/verifier.cpp @@ -2092,15 +2092,13 @@ void ClassVerifier::class_format_error(const char* msg, ...) { Klass* ClassVerifier::load_class(Symbol* name, TRAPS) { HandleMark hm(THREAD); - // Get current loader and protection domain first. + // Get current loader first. oop loader = current_class()->class_loader(); - oop protection_domain = current_class()->protection_domain(); assert(name_in_supers(name, current_class()), "name should be a super class"); Klass* kls = SystemDictionary::resolve_or_fail( - name, Handle(THREAD, loader), Handle(THREAD, protection_domain), - true, THREAD); + name, Handle(THREAD, loader), true, THREAD); if (kls != nullptr) { if (log_is_enabled(Debug, class, resolve)) { diff --git a/src/hotspot/share/classfile/vmClassMacros.hpp b/src/hotspot/share/classfile/vmClassMacros.hpp index 46d601d17dd..395034d4a21 100644 --- a/src/hotspot/share/classfile/vmClassMacros.hpp +++ b/src/hotspot/share/classfile/vmClassMacros.hpp @@ -60,10 +60,7 @@ do_klass(Error_klass, java_lang_Error ) \ do_klass(Exception_klass, java_lang_Exception ) \ do_klass(RuntimeException_klass, java_lang_RuntimeException ) \ - do_klass(SecurityManager_klass, java_lang_SecurityManager ) \ do_klass(ProtectionDomain_klass, java_security_ProtectionDomain ) \ - do_klass(AccessControlContext_klass, java_security_AccessControlContext ) \ - do_klass(AccessController_klass, java_security_AccessController ) \ do_klass(SecureClassLoader_klass, java_security_SecureClassLoader ) \ do_klass(ClassNotFoundException_klass, java_lang_ClassNotFoundException ) \ do_klass(Record_klass, java_lang_Record ) \ diff --git a/src/hotspot/share/classfile/vmSymbols.hpp b/src/hotspot/share/classfile/vmSymbols.hpp index 0728e156f82..ca451572de7 100644 --- a/src/hotspot/share/classfile/vmSymbols.hpp +++ b/src/hotspot/share/classfile/vmSymbols.hpp @@ -118,12 +118,8 @@ class SerializeClosure; template(java_lang_reflect_RecordComponent, "java/lang/reflect/RecordComponent") \ template(java_lang_StringBuffer, "java/lang/StringBuffer") \ template(java_lang_StringBuilder, "java/lang/StringBuilder") \ - template(java_lang_SecurityManager, "java/lang/SecurityManager") \ template(java_lang_ScopedValue, "java/lang/ScopedValue") \ template(java_lang_ScopedValue_Carrier, "java/lang/ScopedValue$Carrier") \ - template(java_security_AccessControlContext, "java/security/AccessControlContext") \ - template(java_security_AccessController, "java/security/AccessController") \ - template(executePrivileged_name, "executePrivileged") \ template(java_security_CodeSource, "java/security/CodeSource") \ template(java_security_ProtectionDomain, "java/security/ProtectionDomain") \ template(java_security_SecureClassLoader, "java/security/SecureClassLoader") \ @@ -440,9 +436,6 @@ class SerializeClosure; template(getCause_name, "getCause") \ template(initCause_name, "initCause") \ template(getProperty_name, "getProperty") \ - template(context_name, "context") \ - template(contextClassLoader_name, "contextClassLoader") \ - template(getClassContext_name, "getClassContext") \ template(wait_name, "wait0") \ template(forName_name, "forName") \ template(forName0_name, "forName0") \ @@ -490,7 +483,6 @@ class SerializeClosure; template(input_stream_void_signature, "(Ljava/io/InputStream;)V") \ template(input_stream_signature, "Ljava/io/InputStream;") \ template(print_stream_signature, "Ljava/io/PrintStream;") \ - template(security_manager_signature, "Ljava/lang/SecurityManager;") \ template(defineOrCheckPackage_name, "defineOrCheckPackage") \ template(defineOrCheckPackage_signature, "(Ljava/lang/String;Ljava/util/jar/Manifest;Ljava/net/URL;)Ljava/lang/Package;") \ template(getProtectionDomain_name, "getProtectionDomain") \ @@ -604,9 +596,6 @@ class SerializeClosure; template(void_string_signature, "()Ljava/lang/String;") \ template(object_array_object_signature, "([Ljava/lang/Object;)Ljava/lang/Object;") \ template(object_object_array_object_signature, "(Ljava/lang/Object;[Ljava/lang/Object;)Ljava/lang/Object;")\ - template(protectiondomain_signature, "[Ljava/security/ProtectionDomain;") \ - template(accesscontrolcontext_signature, "Ljava/security/AccessControlContext;") \ - template(class_protectiondomain_signature, "(Ljava/lang/Class;Ljava/security/ProtectionDomain;)V") \ template(thread_signature, "Ljava/lang/Thread;") \ template(thread_fieldholder_signature, "Ljava/lang/Thread$FieldHolder;") \ template(threadgroup_signature, "Ljava/lang/ThreadGroup;") \ diff --git a/src/hotspot/share/include/jvm.h b/src/hotspot/share/include/jvm.h index e50d758335c..bc46a2cf852 100644 --- a/src/hotspot/share/include/jvm.h +++ b/src/hotspot/share/include/jvm.h @@ -326,12 +326,6 @@ JVM_GetNextThreadIdOffset(JNIEnv *env, jclass threadClass); JNIEXPORT void JNICALL JVM_RegisterContinuationMethods(JNIEnv *env, jclass cls); -/* - * java.lang.SecurityManager - */ -JNIEXPORT jobjectArray JNICALL -JVM_GetClassContext(JNIEnv *env); - /* * java.lang.Package */ diff --git a/src/hotspot/share/interpreter/linkResolver.cpp b/src/hotspot/share/interpreter/linkResolver.cpp index 92d95b43e40..6300b660092 100644 --- a/src/hotspot/share/interpreter/linkResolver.cpp +++ b/src/hotspot/share/interpreter/linkResolver.cpp @@ -496,7 +496,6 @@ Method* LinkResolver::lookup_polymorphic_method(const LinkInfo& link_info, Klass* natives = vmClasses::MethodHandleNatives_klass(); if (natives == nullptr || InstanceKlass::cast(natives)->is_not_initialized()) { SystemDictionary::resolve_or_fail(vmSymbols::java_lang_invoke_MethodHandleNatives(), - Handle(), Handle(), true, CHECK_NULL); diff --git a/src/hotspot/share/jvmci/jvmciCompilerToVM.cpp b/src/hotspot/share/jvmci/jvmciCompilerToVM.cpp index 3599df18544..aa8ce28b7c5 100644 --- a/src/hotspot/share/jvmci/jvmciCompilerToVM.cpp +++ b/src/hotspot/share/jvmci/jvmciCompilerToVM.cpp @@ -613,10 +613,8 @@ C2V_VMENTRY_NULL(jobject, lookupType, (JNIEnv* env, jobject, jstring jname, ARGU JVMCIKlassHandle resolved_klass(THREAD); Klass* accessing_klass = UNPACK_PAIR(Klass, accessing_klass); Handle class_loader; - Handle protection_domain; if (accessing_klass != nullptr) { class_loader = Handle(THREAD, accessing_klass->class_loader()); - protection_domain = Handle(THREAD, accessing_klass->protection_domain()); } else { switch (accessing_klass_loader) { case 0: break; // class_loader is already null, the boot loader @@ -629,23 +627,21 @@ C2V_VMENTRY_NULL(jobject, lookupType, (JNIEnv* env, jobject, jstring jname, ARGU } if (resolve) { - resolved_klass = SystemDictionary::resolve_or_fail(class_name, class_loader, protection_domain, true, CHECK_NULL); + resolved_klass = SystemDictionary::resolve_or_fail(class_name, class_loader, true, CHECK_NULL); } else { if (Signature::has_envelope(class_name)) { // This is a name from a signature. Strip off the trimmings. // Call recursive to keep scope of strippedsym. TempNewSymbol strippedsym = Signature::strip_envelope(class_name); resolved_klass = SystemDictionary::find_instance_klass(THREAD, strippedsym, - class_loader, - protection_domain); + class_loader); } else if (Signature::is_array(class_name)) { SignatureStream ss(class_name, false); int ndim = ss.skip_array_prefix(); if (ss.type() == T_OBJECT) { Symbol* strippedsym = ss.as_symbol(); resolved_klass = SystemDictionary::find_instance_klass(THREAD, strippedsym, - class_loader, - protection_domain); + class_loader); if (!resolved_klass.is_null()) { resolved_klass = resolved_klass->array_klass(ndim, CHECK_NULL); } @@ -654,8 +650,7 @@ C2V_VMENTRY_NULL(jobject, lookupType, (JNIEnv* env, jobject, jstring jname, ARGU } } else { resolved_klass = SystemDictionary::find_instance_klass(THREAD, class_name, - class_loader, - protection_domain); + class_loader); } } JVMCIObject result = JVMCIENV->get_jvmci_type(resolved_klass, JVMCI_CHECK_NULL); diff --git a/src/hotspot/share/jvmci/jvmciEnv.cpp b/src/hotspot/share/jvmci/jvmciEnv.cpp index 129a88ac4d7..c930910dd44 100644 --- a/src/hotspot/share/jvmci/jvmciEnv.cpp +++ b/src/hotspot/share/jvmci/jvmciEnv.cpp @@ -941,9 +941,8 @@ void JVMCIEnv::fthrow_error(const char* file, int line, const char* format, ...) va_end(ap); JavaThread* THREAD = JavaThread::current(); if (is_hotspot()) { - Handle h_loader = Handle(); - Handle h_protection_domain = Handle(); - Exceptions::_throw_msg(THREAD, file, line, vmSymbols::jdk_vm_ci_common_JVMCIError(), msg, h_loader, h_protection_domain); + Handle h_loader; + Exceptions::_throw_msg(THREAD, file, line, vmSymbols::jdk_vm_ci_common_JVMCIError(), msg, h_loader ); } else { JNIAccessMark jni(this, THREAD); jni()->ThrowNew(JNIJVMCI::JVMCIError::clazz(), msg); diff --git a/src/hotspot/share/jvmci/jvmciRuntime.cpp b/src/hotspot/share/jvmci/jvmciRuntime.cpp index 8241fc2498c..ac972e97b1b 100644 --- a/src/hotspot/share/jvmci/jvmciRuntime.cpp +++ b/src/hotspot/share/jvmci/jvmciRuntime.cpp @@ -1678,14 +1678,12 @@ Klass* JVMCIRuntime::get_klass_by_name_impl(Klass*& accessing_klass, } Handle loader; - Handle domain; if (accessing_klass != nullptr) { loader = Handle(THREAD, accessing_klass->class_loader()); - domain = Handle(THREAD, accessing_klass->protection_domain()); } Klass* found_klass = require_local ? - SystemDictionary::find_instance_or_array_klass(THREAD, sym, loader, domain) : + SystemDictionary::find_instance_or_array_klass(THREAD, sym, loader) : SystemDictionary::find_constrained_instance_or_array_klass(THREAD, sym, loader); // If we fail to find an array klass, look again for its element type. diff --git a/src/hotspot/share/logging/logDiagnosticCommand.hpp b/src/hotspot/share/logging/logDiagnosticCommand.hpp index 089bcdc48af..e63509bea9e 100644 --- a/src/hotspot/share/logging/logDiagnosticCommand.hpp +++ b/src/hotspot/share/logging/logDiagnosticCommand.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -59,7 +59,6 @@ class LogDiagnosticCommand : public DCmdWithParser { return "Lists current log configuration, enables/disables/configures a log output, or rotates all logs."; } - // Used by SecurityManager. This DCMD requires ManagementPermission = control. static const JavaPermission permission() { JavaPermission p = {"java.lang.management.ManagementPermission", "control", nullptr}; return p; diff --git a/src/hotspot/share/logging/logTag.hpp b/src/hotspot/share/logging/logTag.hpp index d9563e41ce7..15ac30d09ab 100644 --- a/src/hotspot/share/logging/logTag.hpp +++ b/src/hotspot/share/logging/logTag.hpp @@ -161,7 +161,6 @@ class outputStream; LOG_TAG(preorder) /* Trace all classes loaded in order referenced (not loaded) */ \ LOG_TAG(preview) /* Trace loading of preview feature types */ \ LOG_TAG(promotion) \ - LOG_TAG(protectiondomain) /* "Trace protection domain verification" */ \ LOG_TAG(ptrqueue) \ LOG_TAG(purge) \ LOG_TAG(record) \ diff --git a/src/hotspot/share/oops/constantPool.cpp b/src/hotspot/share/oops/constantPool.cpp index a435d6e5fd3..73cc16bc122 100644 --- a/src/hotspot/share/oops/constantPool.cpp +++ b/src/hotspot/share/oops/constantPool.cpp @@ -680,13 +680,12 @@ Klass* ConstantPool::klass_at_impl(const constantPoolHandle& this_cp, int cp_ind Handle mirror_handle; Symbol* name = this_cp->symbol_at(name_index); Handle loader (THREAD, this_cp->pool_holder()->class_loader()); - Handle protection_domain (THREAD, this_cp->pool_holder()->protection_domain()); Klass* k; { // Turn off the single stepping while doing class resolution JvmtiHideSingleStepping jhss(javaThread); - k = SystemDictionary::resolve_or_fail(name, loader, protection_domain, true, THREAD); + k = SystemDictionary::resolve_or_fail(name, loader, true, THREAD); } // JvmtiHideSingleStepping jhss(javaThread); if (!HAS_PENDING_EXCEPTION) { @@ -756,10 +755,8 @@ Klass* ConstantPool::klass_at_if_loaded(const constantPoolHandle& this_cp, int w HandleMark hm(current); Symbol* name = this_cp->symbol_at(name_index); oop loader = this_cp->pool_holder()->class_loader(); - oop protection_domain = this_cp->pool_holder()->protection_domain(); - Handle h_prot (current, protection_domain); Handle h_loader (current, loader); - Klass* k = SystemDictionary::find_instance_klass(current, name, h_loader, h_prot); + Klass* k = SystemDictionary::find_instance_klass(current, name, h_loader); // Avoid constant pool verification at a safepoint, as it takes the Module_lock. if (k != nullptr && current->is_Java_thread()) { diff --git a/src/hotspot/share/oops/method.cpp b/src/hotspot/share/oops/method.cpp index 917c93304c1..af10efc0f00 100644 --- a/src/hotspot/share/oops/method.cpp +++ b/src/hotspot/share/oops/method.cpp @@ -927,8 +927,7 @@ bool Method::is_klass_loaded_by_klass_index(int klass_index) const { Thread *thread = Thread::current(); Symbol* klass_name = constants()->klass_name_at(klass_index); Handle loader(thread, method_holder()->class_loader()); - Handle prot (thread, method_holder()->protection_domain()); - return SystemDictionary::find_instance_klass(thread, klass_name, loader, prot) != nullptr; + return SystemDictionary::find_instance_klass(thread, klass_name, loader) != nullptr; } else { return true; } diff --git a/src/hotspot/share/prims/jni.cpp b/src/hotspot/share/prims/jni.cpp index b27448dd39a..7bea3441fa5 100644 --- a/src/hotspot/share/prims/jni.cpp +++ b/src/hotspot/share/prims/jni.cpp @@ -321,8 +321,6 @@ JNI_ENTRY(jclass, jni_FindClass(JNIEnv *env, const char *name)) SystemDictionary::class_name_symbol(name, vmSymbols::java_lang_NoClassDefFoundError(), CHECK_NULL); - //%note jni_3 - Handle protection_domain; // Find calling class Klass* k = thread->security_get_caller_class(0); // default to the system loader when no context @@ -344,15 +342,13 @@ JNI_ENTRY(jclass, jni_FindClass(JNIEnv *env, const char *name)) if (mirror != nullptr) { Klass* fromClass = java_lang_Class::as_Klass(mirror); loader = Handle(THREAD, fromClass->class_loader()); - protection_domain = Handle(THREAD, fromClass->protection_domain()); } } else { loader = Handle(THREAD, k->class_loader()); } } - result = find_class_from_class_loader(env, class_name, true, loader, - protection_domain, true, thread); + result = find_class_from_class_loader(env, class_name, true, loader, true, thread); if (log_is_enabled(Debug, class, resolve) && result != nullptr) { trace_class_resolution(java_lang_Class::as_Klass(JNIHandles::resolve_non_null(result))); @@ -537,8 +533,7 @@ JNI_ENTRY(jint, jni_ThrowNew(JNIEnv *env, jclass clazz, const char *message)) InstanceKlass* k = InstanceKlass::cast(java_lang_Class::as_Klass(JNIHandles::resolve_non_null(clazz))); Symbol* name = k->name(); Handle class_loader (THREAD, k->class_loader()); - Handle protection_domain (THREAD, k->protection_domain()); - THROW_MSG_LOADER_(name, (char *)message, class_loader, protection_domain, JNI_OK); + THROW_MSG_LOADER_(name, (char *)message, class_loader, JNI_OK); ShouldNotReachHere(); return 0; // Mute compiler. JNI_END @@ -2929,10 +2924,9 @@ static jfieldID bufferCapacityField = nullptr; static jclass lookupOne(JNIEnv* env, const char* name, TRAPS) { Handle loader; // null (bootstrap) loader - Handle protection_domain; // null protection domain TempNewSymbol sym = SymbolTable::new_symbol(name); - jclass result = find_class_from_class_loader(env, sym, true, loader, protection_domain, true, CHECK_NULL); + jclass result = find_class_from_class_loader(env, sym, true, loader, true, CHECK_NULL); if (log_is_enabled(Debug, class, resolve) && result != nullptr) { trace_class_resolution(java_lang_Class::as_Klass(JNIHandles::resolve_non_null(result))); diff --git a/src/hotspot/share/prims/jvm.cpp b/src/hotspot/share/prims/jvm.cpp index 3288f2eefe4..b8e7f9c1ea2 100644 --- a/src/hotspot/share/prims/jvm.cpp +++ b/src/hotspot/share/prims/jvm.cpp @@ -151,29 +151,22 @@ and thus can only support use of handles passed in. */ -static void trace_class_resolution_impl(Klass* to_class, TRAPS) { +extern void trace_class_resolution(Klass* to_class) { ResourceMark rm; int line_number = -1; const char * source_file = nullptr; const char * trace = "explicit"; InstanceKlass* caller = nullptr; - JavaThread* jthread = THREAD; + JavaThread* jthread = JavaThread::current(); if (jthread->has_last_Java_frame()) { vframeStream vfst(jthread); - // scan up the stack skipping ClassLoader, AccessController and PrivilegedAction frames - TempNewSymbol access_controller = SymbolTable::new_symbol("java/security/AccessController"); - Klass* access_controller_klass = SystemDictionary::resolve_or_fail(access_controller, false, CHECK); - TempNewSymbol privileged_action = SymbolTable::new_symbol("java/security/PrivilegedAction"); - Klass* privileged_action_klass = SystemDictionary::resolve_or_fail(privileged_action, false, CHECK); - + // Scan up the stack skipping ClassLoader frames. Method* last_caller = nullptr; while (!vfst.at_end()) { Method* m = vfst.method(); - if (!vfst.method()->method_holder()->is_subclass_of(vmClasses::ClassLoader_klass())&& - !vfst.method()->method_holder()->is_subclass_of(access_controller_klass) && - !vfst.method()->method_holder()->is_subclass_of(privileged_action_klass)) { + if (!vfst.method()->method_holder()->is_subclass_of(vmClasses::ClassLoader_klass())) { break; } last_caller = m; @@ -232,14 +225,6 @@ static void trace_class_resolution_impl(Klass* to_class, TRAPS) { } } -void trace_class_resolution(Klass* to_class) { - EXCEPTION_MARK; - trace_class_resolution_impl(to_class, THREAD); - if (HAS_PENDING_EXCEPTION) { - CLEAR_PENDING_EXCEPTION; - } -} - // java.lang.System ////////////////////////////////////////////////////////////////////// @@ -833,20 +818,10 @@ JVM_ENTRY(jclass, JVM_FindClassFromCaller(JNIEnv* env, const char* name, oop loader_oop = JNIHandles::resolve(loader); oop from_class = JNIHandles::resolve(caller); - oop protection_domain = nullptr; - // If loader is null, shouldn't call ClassLoader.checkPackageAccess; otherwise get - // NPE. Put it in another way, the bootstrap class loader has all permission and - // thus no checkPackageAccess equivalence in the VM class loader. - // The caller is also passed as null by the java code if there is no security - // manager to avoid the performance cost of getting the calling class. - if (from_class != nullptr && loader_oop != nullptr) { - protection_domain = java_lang_Class::as_Klass(from_class)->protection_domain(); - } - Handle h_loader(THREAD, loader_oop); - Handle h_prot(THREAD, protection_domain); + jclass result = find_class_from_class_loader(env, h_name, init, h_loader, - h_prot, false, THREAD); + false, THREAD); if (log_is_enabled(Debug, class, resolve) && result != nullptr) { trace_class_resolution(java_lang_Class::as_Klass(JNIHandles::resolve_non_null(result))); @@ -865,15 +840,11 @@ JVM_ENTRY(jclass, JVM_FindClassFromClass(JNIEnv *env, const char *name, ? (Klass*)nullptr : java_lang_Class::as_Klass(from_class_oop); oop class_loader = nullptr; - oop protection_domain = nullptr; if (from_class != nullptr) { class_loader = from_class->class_loader(); - protection_domain = from_class->protection_domain(); } Handle h_loader(THREAD, class_loader); - Handle h_prot (THREAD, protection_domain); - jclass result = find_class_from_class_loader(env, h_name, init, h_loader, - h_prot, true, thread); + jclass result = find_class_from_class_loader(env, h_name, init, h_loader, true, thread); if (log_is_enabled(Debug, class, resolve) && result != nullptr) { // this function is generally only used for class loading during verification. @@ -1121,9 +1092,7 @@ JVM_ENTRY(jclass, JVM_FindLoadedClass(JNIEnv *env, jobject loader, jstring name) // The Java level wrapper will perform the necessary security check allowing // us to pass the null as the initiating class loader. Handle h_loader(THREAD, JNIHandles::resolve(loader)); - Klass* k = SystemDictionary::find_instance_or_array_klass(THREAD, klass_name, - h_loader, - Handle()); + Klass* k = SystemDictionary::find_instance_or_array_klass(THREAD, klass_name, h_loader); #if INCLUDE_CDS if (k == nullptr) { // If the class is not already loaded, try to see if it's in the shared @@ -3069,45 +3038,6 @@ JVM_ENTRY(void, JVM_SetScopedValueCache(JNIEnv* env, jclass threadClass, thread->set_scopedValueCache(objs); JVM_END -// java.lang.SecurityManager /////////////////////////////////////////////////////////////////////// - -JVM_ENTRY(jobjectArray, JVM_GetClassContext(JNIEnv *env)) - ResourceMark rm(THREAD); - JvmtiVMObjectAllocEventCollector oam; - vframeStream vfst(thread); - - if (vmClasses::reflect_CallerSensitive_klass() != nullptr) { - // This must only be called from SecurityManager.getClassContext - Method* m = vfst.method(); - if (!(m->method_holder() == vmClasses::SecurityManager_klass() && - m->name() == vmSymbols::getClassContext_name() && - m->signature() == vmSymbols::void_class_array_signature())) { - THROW_MSG_NULL(vmSymbols::java_lang_InternalError(), "JVM_GetClassContext must only be called from SecurityManager.getClassContext"); - } - } - - // Collect method holders - GrowableArray<Klass*>* klass_array = new GrowableArray<Klass*>(); - for (; !vfst.at_end(); vfst.security_next()) { - Method* m = vfst.method(); - // Native frames are not returned - if (!m->is_ignored_by_security_stack_walk() && !m->is_native()) { - Klass* holder = m->method_holder(); - assert(holder->is_klass(), "just checking"); - klass_array->append(holder); - } - } - - // Create result array of type [Ljava/lang/Class; - objArrayOop result = oopFactory::new_objArray(vmClasses::Class_klass(), klass_array->length(), CHECK_NULL); - // Fill in mirrors corresponding to method holders - for (int i = 0; i < klass_array->length(); i++) { - result->obj_at_put(i, klass_array->at(i)->java_mirror()); - } - - return (jobjectArray) JNIHandles::make_local(THREAD, result); -JVM_END - // java.lang.Package //////////////////////////////////////////////////////////////// @@ -3421,15 +3351,8 @@ JNIEXPORT void JNICALL JVM_RawMonitorExit(void *mon) { // Shared JNI/JVM entry points ////////////////////////////////////////////////////////////// jclass find_class_from_class_loader(JNIEnv* env, Symbol* name, jboolean init, - Handle loader, Handle protection_domain, - jboolean throwError, TRAPS) { - // Security Note: - // The Java level wrapper will perform the necessary security check allowing - // us to pass the null as the initiating class loader. The VM is responsible for - // the checkPackageAccess relative to the initiating class loader via the - // protection_domain. The protection_domain is passed as null by the java code - // if there is no security manager in 3-arg Class.forName(). - Klass* klass = SystemDictionary::resolve_or_fail(name, loader, protection_domain, throwError != 0, CHECK_NULL); + Handle loader, jboolean throwError, TRAPS) { + Klass* klass = SystemDictionary::resolve_or_fail(name, loader, throwError != 0, CHECK_NULL); // Check if we should initialize the class if (init && klass->is_instance_klass()) { diff --git a/src/hotspot/share/prims/jvm_misc.hpp b/src/hotspot/share/prims/jvm_misc.hpp index 28b39631bf4..18c8e3b6ad5 100644 --- a/src/hotspot/share/prims/jvm_misc.hpp +++ b/src/hotspot/share/prims/jvm_misc.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -31,7 +31,7 @@ // Useful entry points shared by JNI and JVM interface. // We do not allow real JNI or JVM entry point to call each other. -jclass find_class_from_class_loader(JNIEnv* env, Symbol* name, jboolean init, Handle loader, Handle protection_domain, jboolean throwError, TRAPS); +jclass find_class_from_class_loader(JNIEnv* env, Symbol* name, jboolean init, Handle loader, jboolean throwError, TRAPS); void trace_class_resolution(Klass* to_class); diff --git a/src/hotspot/share/prims/whitebox.cpp b/src/hotspot/share/prims/whitebox.cpp index d4b5e293c09..a8607bb2efd 100644 --- a/src/hotspot/share/prims/whitebox.cpp +++ b/src/hotspot/share/prims/whitebox.cpp @@ -35,7 +35,6 @@ #include "classfile/classPrinter.hpp" #include "classfile/javaClasses.inline.hpp" #include "classfile/modules.hpp" -#include "classfile/protectionDomainCache.hpp" #include "classfile/stringTable.hpp" #include "classfile/symbolTable.hpp" #include "classfile/systemDictionary.hpp" @@ -2536,10 +2535,6 @@ WB_ENTRY(jlong, WB_ResolvedMethodItemsCount(JNIEnv* env, jobject o)) return (jlong) ResolvedMethodTable::items_count(); WB_END -WB_ENTRY(jint, WB_ProtectionDomainRemovedCount(JNIEnv* env, jobject o)) - return (jint) ProtectionDomainCacheTable::removed_entries_count(); -WB_END - WB_ENTRY(jint, WB_GetKlassMetadataSize(JNIEnv* env, jobject wb, jclass mirror)) Klass* k = java_lang_Class::as_Klass(JNIHandles::resolve(mirror)); // Return size in bytes. @@ -2966,7 +2961,6 @@ static JNINativeMethod methods[] = { {CC"printOsInfo", CC"()V", (void*)&WB_PrintOsInfo }, {CC"disableElfSectionCache", CC"()V", (void*)&WB_DisableElfSectionCache }, {CC"resolvedMethodItemsCount", CC"()J", (void*)&WB_ResolvedMethodItemsCount }, - {CC"protectionDomainRemovedCount", CC"()I", (void*)&WB_ProtectionDomainRemovedCount }, {CC"getKlassMetadataSize", CC"(Ljava/lang/Class;)I",(void*)&WB_GetKlassMetadataSize}, {CC"createMetaspaceTestContext", CC"(JJ)J", (void*)&WB_CreateMetaspaceTestContext}, diff --git a/src/hotspot/share/runtime/deoptimization.cpp b/src/hotspot/share/runtime/deoptimization.cpp index 9992d42622f..10fd83750d4 100644 --- a/src/hotspot/share/runtime/deoptimization.cpp +++ b/src/hotspot/share/runtime/deoptimization.cpp @@ -1065,7 +1065,7 @@ class BoxCacheBase : public CHeapObj<mtCompiler> { static InstanceKlass* find_cache_klass(Thread* thread, Symbol* klass_name) { ResourceMark rm(thread); char* klass_name_str = klass_name->as_C_string(); - InstanceKlass* ik = SystemDictionary::find_instance_klass(thread, klass_name, Handle(), Handle()); + InstanceKlass* ik = SystemDictionary::find_instance_klass(thread, klass_name, Handle()); guarantee(ik != nullptr, "%s must be loaded", klass_name_str); if (!ik->is_in_error_state()) { guarantee(ik->is_initialized(), "%s must be initialized", klass_name_str); diff --git a/src/hotspot/share/runtime/serviceThread.cpp b/src/hotspot/share/runtime/serviceThread.cpp index f5653ccd5f4..f4bffc72ef3 100644 --- a/src/hotspot/share/runtime/serviceThread.cpp +++ b/src/hotspot/share/runtime/serviceThread.cpp @@ -25,11 +25,8 @@ #include "precompiled.hpp" #include "classfile/classLoaderDataGraph.inline.hpp" #include "classfile/javaClasses.hpp" -#include "classfile/protectionDomainCache.hpp" #include "classfile/stringTable.hpp" #include "classfile/symbolTable.hpp" -#include "classfile/systemDictionary.hpp" -#include "classfile/vmClasses.hpp" #include "gc/shared/oopStorage.hpp" #include "gc/shared/oopStorageSet.hpp" #include "interpreter/oopMapCache.hpp" @@ -40,15 +37,10 @@ #include "prims/resolvedMethodTable.hpp" #include "runtime/handles.inline.hpp" #include "runtime/interfaceSupport.inline.hpp" -#include "runtime/java.hpp" -#include "runtime/javaCalls.hpp" -#include "runtime/jniHandles.hpp" #include "runtime/lightweightSynchronizer.hpp" #include "runtime/mutexLocker.hpp" #include "runtime/os.hpp" #include "runtime/serviceThread.hpp" -#include "services/diagnosticArgument.hpp" -#include "services/diagnosticFramework.hpp" #include "services/finalizerService.hpp" #include "services/gcNotifier.hpp" #include "services/lowMemoryDetector.hpp" @@ -88,7 +80,6 @@ void ServiceThread::service_thread_entry(JavaThread* jt, TRAPS) { bool finalizerservice_work = false; bool resolved_method_table_work = false; bool thread_id_table_work = false; - bool protection_domain_table_work = false; bool oopstorage_work = false; JvmtiDeferredEvent jvmti_event; bool oop_handles_to_release = false; @@ -118,7 +109,6 @@ void ServiceThread::service_thread_entry(JavaThread* jt, TRAPS) { (finalizerservice_work = FinalizerService::has_work()) | (resolved_method_table_work = ResolvedMethodTable::has_work()) | (thread_id_table_work = ThreadIdTable::has_work()) | - (protection_domain_table_work = ProtectionDomainCacheTable::has_work()) | (oopstorage_work = OopStorage::has_cleanup_work_and_reset()) | (oop_handles_to_release = JavaThread::has_oop_handles_to_release()) | (cldg_cleanup_work = ClassLoaderDataGraph::should_clean_metaspaces_and_reset()) | @@ -163,10 +153,6 @@ void ServiceThread::service_thread_entry(JavaThread* jt, TRAPS) { ThreadIdTable::do_concurrent_work(jt); } - if (protection_domain_table_work) { - ProtectionDomainCacheTable::unlink(); - } - if (oopstorage_work) { cleanup_oopstorages(); } diff --git a/src/hotspot/share/runtime/signature.cpp b/src/hotspot/share/runtime/signature.cpp index 081bdd2e0d3..2dfb8d81037 100644 --- a/src/hotspot/share/runtime/signature.cpp +++ b/src/hotspot/share/runtime/signature.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -501,8 +501,7 @@ Symbol* SignatureStream::find_symbol() { return name; } -Klass* SignatureStream::as_klass(Handle class_loader, Handle protection_domain, - FailureMode failure_mode, TRAPS) { +Klass* SignatureStream::as_klass(Handle class_loader, FailureMode failure_mode, TRAPS) { if (!is_reference()) { return nullptr; } @@ -511,11 +510,11 @@ Klass* SignatureStream::as_klass(Handle class_loader, Handle protection_domain, if (failure_mode == ReturnNull) { // Note: SD::resolve_or_null returns null for most failure modes, // but not all. Circularity errors, invalid PDs, etc., throw. - k = SystemDictionary::resolve_or_null(name, class_loader, protection_domain, CHECK_NULL); + k = SystemDictionary::resolve_or_null(name, class_loader, CHECK_NULL); } else if (failure_mode == CachedOrNull) { NoSafepointVerifier nsv; // no loading, now, we mean it! assert(!HAS_PENDING_EXCEPTION, ""); - k = SystemDictionary::find_instance_klass(THREAD, name, class_loader, protection_domain); + k = SystemDictionary::find_instance_klass(THREAD, name, class_loader); // SD::find does not trigger loading, so there should be no throws // Still, bad things can happen, so we CHECK_NULL and ask callers // to do likewise. @@ -525,18 +524,17 @@ Klass* SignatureStream::as_klass(Handle class_loader, Handle protection_domain, // The test here allows for an additional mode CNFException // if callers need to request the reflective error instead. bool throw_error = (failure_mode == NCDFError); - k = SystemDictionary::resolve_or_fail(name, class_loader, protection_domain, throw_error, CHECK_NULL); + k = SystemDictionary::resolve_or_fail(name, class_loader, throw_error, CHECK_NULL); } return k; } -oop SignatureStream::as_java_mirror(Handle class_loader, Handle protection_domain, - FailureMode failure_mode, TRAPS) { +oop SignatureStream::as_java_mirror(Handle class_loader, FailureMode failure_mode, TRAPS) { if (!is_reference()) { return Universe::java_mirror(type()); } - Klass* klass = as_klass(class_loader, protection_domain, failure_mode, CHECK_NULL); + Klass* klass = as_klass(class_loader, failure_mode, CHECK_NULL); if (klass == nullptr) { return nullptr; } @@ -551,10 +549,8 @@ void SignatureStream::skip_to_return_type() { ResolvingSignatureStream::ResolvingSignatureStream(Symbol* signature, Handle class_loader, - Handle protection_domain, bool is_method) - : SignatureStream(signature, is_method), - _class_loader(class_loader), _protection_domain(protection_domain) + : SignatureStream(signature, is_method), _class_loader(class_loader) { initialize_load_origin(nullptr); } @@ -576,7 +572,6 @@ void ResolvingSignatureStream::cache_handles() { assert(_load_origin != nullptr, ""); JavaThread* current = JavaThread::current(); _class_loader = Handle(current, _load_origin->class_loader()); - _protection_domain = Handle(current, _load_origin->protection_domain()); } #ifdef ASSERT diff --git a/src/hotspot/share/runtime/signature.hpp b/src/hotspot/share/runtime/signature.hpp index 25de9c0a1f0..ef18b0f03d3 100644 --- a/src/hotspot/share/runtime/signature.hpp +++ b/src/hotspot/share/runtime/signature.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2021, Azul Systems, Inc. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -562,8 +562,8 @@ class SignatureStream : public StackObj { // free-standing lookups (bring your own CL/PD pair) enum FailureMode { ReturnNull, NCDFError, CachedOrNull }; - Klass* as_klass(Handle class_loader, Handle protection_domain, FailureMode failure_mode, TRAPS); - oop as_java_mirror(Handle class_loader, Handle protection_domain, FailureMode failure_mode, TRAPS); + Klass* as_klass(Handle class_loader, FailureMode failure_mode, TRAPS); + oop as_java_mirror(Handle class_loader, FailureMode failure_mode, TRAPS); }; // Specialized SignatureStream: used for invoking SystemDictionary to either find @@ -573,7 +573,6 @@ class ResolvingSignatureStream : public SignatureStream { Klass* _load_origin; bool _handles_cached; Handle _class_loader; // cached when needed - Handle _protection_domain; // cached when needed void initialize_load_origin(Klass* load_origin) { _load_origin = load_origin; @@ -589,20 +588,18 @@ class ResolvingSignatureStream : public SignatureStream { public: ResolvingSignatureStream(Symbol* signature, Klass* load_origin, bool is_method = true); - ResolvingSignatureStream(Symbol* signature, Handle class_loader, Handle protection_domain, bool is_method = true); + ResolvingSignatureStream(Symbol* signature, Handle class_loader, bool is_method = true); ResolvingSignatureStream(const Method* method); Klass* as_klass(FailureMode failure_mode, TRAPS) { need_handles(); - return SignatureStream::as_klass(_class_loader, _protection_domain, - failure_mode, THREAD); + return SignatureStream::as_klass(_class_loader, failure_mode, THREAD); } oop as_java_mirror(FailureMode failure_mode, TRAPS) { if (is_reference()) { need_handles(); } - return SignatureStream::as_java_mirror(_class_loader, _protection_domain, - failure_mode, THREAD); + return SignatureStream::as_java_mirror(_class_loader, failure_mode, THREAD); } }; diff --git a/src/hotspot/share/runtime/threads.cpp b/src/hotspot/share/runtime/threads.cpp index 41ac7bc6627..f6b7b7956e2 100644 --- a/src/hotspot/share/runtime/threads.cpp +++ b/src/hotspot/share/runtime/threads.cpp @@ -385,7 +385,7 @@ void Threads::initialize_java_lang_classes(JavaThread* main_thread, TRAPS) { // Some values are actually configure-time constants but some can be set via the jlink tool and // so must be read dynamically. We treat them all the same. InstanceKlass* ik = SystemDictionary::find_instance_klass(THREAD, vmSymbols::java_lang_VersionProps(), - Handle(), Handle()); + Handle()); { ResourceMark rm(main_thread); JDK_Version::set_java_version(get_java_version_info(ik, vmSymbols::java_version_name())); diff --git a/src/hotspot/share/runtime/vframe.cpp b/src/hotspot/share/runtime/vframe.cpp index 41a46c86a70..fbf82c69673 100644 --- a/src/hotspot/share/runtime/vframe.cpp +++ b/src/hotspot/share/runtime/vframe.cpp @@ -532,8 +532,7 @@ vframeStream::vframeStream(oop continuation, Handle continuation_scope) // Step back n frames, skip any pseudo frames in between. -// This function is used in Class.forName, Class.newInstance, Method.Invoke, -// AccessController.doPrivileged. +// This function is used in Class.forName, Class.newInstance, and Method.Invoke. void vframeStreamCommon::security_get_caller_frame(int depth) { assert(depth >= 0, "invalid depth: %d", depth); for (int n = 0; !at_end(); security_next()) { diff --git a/src/hotspot/share/services/diagnosticCommand.cpp b/src/hotspot/share/services/diagnosticCommand.cpp index ac711520065..240f3604cc1 100644 --- a/src/hotspot/share/services/diagnosticCommand.cpp +++ b/src/hotspot/share/services/diagnosticCommand.cpp @@ -695,7 +695,7 @@ void JMXStartRemoteDCmd::execute(DCmdSource source, TRAPS) { loadAgentModule(CHECK); Handle loader = Handle(THREAD, SystemDictionary::java_system_loader()); - Klass* k = SystemDictionary::resolve_or_fail(vmSymbols::jdk_internal_agent_Agent(), loader, Handle(), true, CHECK); + Klass* k = SystemDictionary::resolve_or_fail(vmSymbols::jdk_internal_agent_Agent(), loader, true, CHECK); JavaValue result(T_VOID); @@ -768,7 +768,7 @@ void JMXStartLocalDCmd::execute(DCmdSource source, TRAPS) { loadAgentModule(CHECK); Handle loader = Handle(THREAD, SystemDictionary::java_system_loader()); - Klass* k = SystemDictionary::resolve_or_fail(vmSymbols::jdk_internal_agent_Agent(), loader, Handle(), true, CHECK); + Klass* k = SystemDictionary::resolve_or_fail(vmSymbols::jdk_internal_agent_Agent(), loader, true, CHECK); JavaValue result(T_VOID); JavaCalls::call_static(&result, k, vmSymbols::startLocalAgent_name(), vmSymbols::void_method_signature(), CHECK); @@ -785,7 +785,7 @@ void JMXStopRemoteDCmd::execute(DCmdSource source, TRAPS) { loadAgentModule(CHECK); Handle loader = Handle(THREAD, SystemDictionary::java_system_loader()); - Klass* k = SystemDictionary::resolve_or_fail(vmSymbols::jdk_internal_agent_Agent(), loader, Handle(), true, CHECK); + Klass* k = SystemDictionary::resolve_or_fail(vmSymbols::jdk_internal_agent_Agent(), loader, true, CHECK); JavaValue result(T_VOID); JavaCalls::call_static(&result, k, vmSymbols::stopRemoteAgent_name(), vmSymbols::void_method_signature(), CHECK); @@ -806,7 +806,7 @@ void JMXStatusDCmd::execute(DCmdSource source, TRAPS) { loadAgentModule(CHECK); Handle loader = Handle(THREAD, SystemDictionary::java_system_loader()); - Klass* k = SystemDictionary::resolve_or_fail(vmSymbols::jdk_internal_agent_Agent(), loader, Handle(), true, CHECK); + Klass* k = SystemDictionary::resolve_or_fail(vmSymbols::jdk_internal_agent_Agent(), loader, true, CHECK); JavaValue result(T_OBJECT); JavaCalls::call_static(&result, k, vmSymbols::getAgentStatus_name(), vmSymbols::void_string_signature(), CHECK); diff --git a/src/hotspot/share/services/management.cpp b/src/hotspot/share/services/management.cpp index ac7e1daf397..7729fb08808 100644 --- a/src/hotspot/share/services/management.cpp +++ b/src/hotspot/share/services/management.cpp @@ -160,7 +160,6 @@ void Management::initialize(TRAPS) { Handle loader = Handle(THREAD, SystemDictionary::java_system_loader()); Klass* k = SystemDictionary::resolve_or_null(vmSymbols::jdk_internal_agent_Agent(), loader, - Handle(), THREAD); if (k == nullptr) { vm_exit_during_initialization("Management agent initialization failure: " diff --git a/src/hotspot/share/utilities/exceptions.cpp b/src/hotspot/share/utilities/exceptions.cpp index 10405a06048..0f87f76a2e8 100644 --- a/src/hotspot/share/utilities/exceptions.cpp +++ b/src/hotspot/share/utilities/exceptions.cpp @@ -188,30 +188,30 @@ void Exceptions::_throw(JavaThread* thread, const char* file, int line, Handle h void Exceptions::_throw_msg(JavaThread* thread, const char* file, int line, Symbol* name, const char* message, - Handle h_loader, Handle h_protection_domain) { + Handle h_loader) { // Check for special boot-strapping/compiler-thread handling if (special_exception(thread, file, line, Handle(), name, message)) return; // Create and throw exception Handle h_cause(thread, nullptr); - Handle h_exception = new_exception(thread, name, message, h_cause, h_loader, h_protection_domain); + Handle h_exception = new_exception(thread, name, message, h_cause, h_loader); _throw(thread, file, line, h_exception, message); } void Exceptions::_throw_msg_cause(JavaThread* thread, const char* file, int line, Symbol* name, const char* message, Handle h_cause, - Handle h_loader, Handle h_protection_domain) { + Handle h_loader) { // Check for special boot-strapping/compiler-thread handling if (special_exception(thread, file, line, Handle(), name, message)) return; // Create and throw exception and init cause - Handle h_exception = new_exception(thread, name, message, h_cause, h_loader, h_protection_domain); + Handle h_exception = new_exception(thread, name, message, h_cause, h_loader); _throw(thread, file, line, h_exception, message); } void Exceptions::_throw_cause(JavaThread* thread, const char* file, int line, Symbol* name, Handle h_cause, - Handle h_loader, Handle h_protection_domain) { + Handle h_loader) { // Check for special boot-strapping/compiler-thread handling if (special_exception(thread, file, line, Handle(), name)) return; // Create and throw exception - Handle h_exception = new_exception(thread, name, h_cause, h_loader, h_protection_domain); + Handle h_exception = new_exception(thread, name, h_cause, h_loader); _throw(thread, file, line, h_exception, nullptr); } @@ -229,13 +229,13 @@ void Exceptions::_throw_args(JavaThread* thread, const char* file, int line, Sym // Methods for default parameters. // NOTE: These must be here (and not in the header file) because of include circularities. void Exceptions::_throw_msg_cause(JavaThread* thread, const char* file, int line, Symbol* name, const char* message, Handle h_cause) { - _throw_msg_cause(thread, file, line, name, message, h_cause, Handle(thread, nullptr), Handle(thread, nullptr)); + _throw_msg_cause(thread, file, line, name, message, h_cause, Handle()); } void Exceptions::_throw_msg(JavaThread* thread, const char* file, int line, Symbol* name, const char* message) { - _throw_msg(thread, file, line, name, message, Handle(thread, nullptr), Handle(thread, nullptr)); + _throw_msg(thread, file, line, name, message, Handle()); } void Exceptions::_throw_cause(JavaThread* thread, const char* file, int line, Symbol* name, Handle h_cause) { - _throw_cause(thread, file, line, name, h_cause, Handle(thread, nullptr), Handle(thread, nullptr)); + _throw_cause(thread, file, line, name, h_cause, Handle()); } @@ -297,7 +297,7 @@ void Exceptions::fthrow(JavaThread* thread, const char* file, int line, Symbol* // and returns a Handle Handle Exceptions::new_exception(JavaThread* thread, Symbol* name, Symbol* signature, JavaCallArguments *args, - Handle h_loader, Handle h_protection_domain) { + Handle h_loader) { assert(Universe::is_fully_initialized(), "cannot be called during initialization"); assert(!thread->has_pending_exception(), "already has exception"); @@ -305,7 +305,7 @@ Handle Exceptions::new_exception(JavaThread* thread, Symbol* name, Handle h_exception; // Resolve exception klass, and check for pending exception below. - Klass* klass = SystemDictionary::resolve_or_fail(name, h_loader, h_protection_domain, true, thread); + Klass* klass = SystemDictionary::resolve_or_fail(name, h_loader, true, thread); if (!thread->has_pending_exception()) { assert(klass != nullptr, "klass must exist"); @@ -329,8 +329,8 @@ Handle Exceptions::new_exception(JavaThread* thread, Symbol* name, Handle Exceptions::new_exception(JavaThread* thread, Symbol* name, Symbol* signature, JavaCallArguments *args, Handle h_cause, - Handle h_loader, Handle h_protection_domain) { - Handle h_exception = new_exception(thread, name, signature, args, h_loader, h_protection_domain); + Handle h_loader) { + Handle h_exception = new_exception(thread, name, signature, args, h_loader); // Future: object initializer should take a cause argument if (h_cause.not_null()) { @@ -359,7 +359,7 @@ Handle Exceptions::new_exception(JavaThread* thread, Symbol* name, // creating a new exception Handle Exceptions::new_exception(JavaThread* thread, Symbol* name, Handle h_cause, - Handle h_loader, Handle h_protection_domain, + Handle h_loader, ExceptionMsgToUtf8Mode to_utf8_safe) { JavaCallArguments args; Symbol* signature = nullptr; @@ -369,14 +369,14 @@ Handle Exceptions::new_exception(JavaThread* thread, Symbol* name, signature = vmSymbols::throwable_void_signature(); args.push_oop(h_cause); } - return new_exception(thread, name, signature, &args, h_loader, h_protection_domain); + return new_exception(thread, name, signature, &args, h_loader); } // Convenience method. Calls either the <init>() or <init>(String) method when // creating a new exception Handle Exceptions::new_exception(JavaThread* thread, Symbol* name, const char* message, Handle h_cause, - Handle h_loader, Handle h_protection_domain, + Handle h_loader, ExceptionMsgToUtf8Mode to_utf8_safe) { JavaCallArguments args; Symbol* signature = nullptr; @@ -413,11 +413,10 @@ Handle Exceptions::new_exception(JavaThread* thread, Symbol* name, args.push_oop(msg); signature = vmSymbols::string_void_signature(); } - return new_exception(thread, name, signature, &args, h_cause, h_loader, h_protection_domain); + return new_exception(thread, name, signature, &args, h_cause, h_loader); } -// Another convenience method that creates handles for null class loaders and -// protection domains and null causes. +// Another convenience method that creates handles for null class loaders and null causes. // If the last parameter 'to_utf8_mode' is safe_to_utf8, // it means we can safely ignore the encoding scheme of the message string and // convert it directly to a java UTF8 string. Otherwise, we need to take the @@ -428,11 +427,10 @@ Handle Exceptions::new_exception(JavaThread* thread, Symbol* name, const char* message, ExceptionMsgToUtf8Mode to_utf8_safe) { - Handle h_loader(thread, nullptr); - Handle h_prot(thread, nullptr); - Handle h_cause(thread, nullptr); + Handle h_loader; + Handle h_cause; return Exceptions::new_exception(thread, name, message, h_cause, h_loader, - h_prot, to_utf8_safe); + to_utf8_safe); } // invokedynamic uses wrap_dynamic_exception for: diff --git a/src/hotspot/share/utilities/exceptions.hpp b/src/hotspot/share/utilities/exceptions.hpp index 33eba68d6d9..0dca7971ef9 100644 --- a/src/hotspot/share/utilities/exceptions.hpp +++ b/src/hotspot/share/utilities/exceptions.hpp @@ -128,15 +128,15 @@ class Exceptions { static void _throw_msg(JavaThread* thread, const char* file, int line, Symbol* name, const char* message); static void _throw_msg(JavaThread* thread, const char* file, int line, Symbol* name, const char* message, - Handle loader, Handle protection_domain); + Handle loader); static void _throw_msg_cause(JavaThread* thread, const char* file, int line, Symbol* name, const char* message, Handle h_cause); static void _throw_msg_cause(JavaThread* thread, const char* file, int line, Symbol* name, const char* message, Handle h_cause, - Handle h_loader, Handle h_protection_domain); + Handle h_loader); static void _throw_cause(JavaThread* thread, const char* file, int line, Symbol* name, Handle h_cause); static void _throw_cause(JavaThread* thread, const char* file, int line, Symbol* name, Handle h_cause, - Handle h_loader, Handle h_protection_domain); + Handle h_loader); static void _throw_args(JavaThread* thread, const char* file, int line, Symbol* name, Symbol* signature, @@ -150,21 +150,21 @@ class Exceptions { // Create and initialize a new exception static Handle new_exception(JavaThread* thread, Symbol* name, Symbol* signature, JavaCallArguments* args, - Handle loader, Handle protection_domain); + Handle loader); static Handle new_exception(JavaThread* thread, Symbol* name, Symbol* signature, JavaCallArguments* args, Handle cause, - Handle loader, Handle protection_domain); + Handle loader); static Handle new_exception(JavaThread* thread, Symbol* name, Handle cause, - Handle loader, Handle protection_domain, + Handle loader, ExceptionMsgToUtf8Mode to_utf8_safe = safe_to_utf8); static Handle new_exception(JavaThread* thread, Symbol* name, const char* message, Handle cause, - Handle loader, Handle protection_domain, + Handle loader, ExceptionMsgToUtf8Mode to_utf8_safe = safe_to_utf8); static Handle new_exception(JavaThread* thread, Symbol* name, @@ -268,8 +268,8 @@ class Exceptions { #define THROW_CAUSE(name, cause) \ { Exceptions::_throw_cause(THREAD_AND_LOCATION, name, cause); return; } -#define THROW_MSG_LOADER(name, message, loader, protection_domain) \ - { Exceptions::_throw_msg(THREAD_AND_LOCATION, name, message, loader, protection_domain); return; } +#define THROW_MSG_LOADER(name, message, loader) \ + { Exceptions::_throw_msg(THREAD_AND_LOCATION, name, message, loader); return; } #define THROW_ARG(name, signature, args) \ { Exceptions::_throw_args(THREAD_AND_LOCATION, name, signature, args); return; } @@ -286,8 +286,8 @@ class Exceptions { #define THROW_MSG_(name, message, result) \ { Exceptions::_throw_msg(THREAD_AND_LOCATION, name, message); return result; } -#define THROW_MSG_LOADER_(name, message, loader, protection_domain, result) \ - { Exceptions::_throw_msg(THREAD_AND_LOCATION, name, message, loader, protection_domain); return result; } +#define THROW_MSG_LOADER_(name, message, loader, result) \ + { Exceptions::_throw_msg(THREAD_AND_LOCATION, name, message, loader); return result; } #define THROW_ARG_(name, signature, args, result) \ { Exceptions::_throw_args(THREAD_AND_LOCATION, name, signature, args); return result; } diff --git a/test/hotspot/jtreg/ProblemList.txt b/test/hotspot/jtreg/ProblemList.txt index ba1851708b2..d3de1f871e8 100644 --- a/test/hotspot/jtreg/ProblemList.txt +++ b/test/hotspot/jtreg/ProblemList.txt @@ -113,9 +113,6 @@ runtime/ErrorHandling/CreateCoredumpOnCrash.java 8267433 macosx-x64 runtime/StackGuardPages/TestStackGuardPagesNative.java 8303612 linux-all runtime/ErrorHandling/MachCodeFramesInErrorFile.java 8313315 linux-ppc64le runtime/cds/appcds/customLoader/HelloCustom_JFR.java 8241075 linux-all,windows-x64 -runtime/Dictionary/CleanProtectionDomain.java 8341916 generic-all -runtime/Dictionary/ProtectionDomainCacheTest.java 8341916 generic-all -runtime/logging/ProtectionDomainVerificationTest.java 8341916 generic-all runtime/NMT/VirtualAllocCommitMerge.java 8309698 linux-s390x # Fails with +UseCompactObjectHeaders on aarch64 diff --git a/test/hotspot/jtreg/runtime/Dictionary/CleanProtectionDomain.java b/test/hotspot/jtreg/runtime/Dictionary/CleanProtectionDomain.java deleted file mode 100644 index 4e4a9329f5d..00000000000 --- a/test/hotspot/jtreg/runtime/Dictionary/CleanProtectionDomain.java +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -/* - * @test - * @summary Verifies the creation and cleaup of entries in the Protection Domain Table - * @requires vm.flagless - * @library /test/lib - * @modules java.base/jdk.internal.misc - * @build jdk.test.whitebox.WhiteBox - * @run driver jdk.test.lib.helpers.ClassFileInstaller jdk.test.whitebox.WhiteBox - * @run driver CleanProtectionDomain - */ - -import java.security.ProtectionDomain; -import jdk.test.lib.compiler.InMemoryJavaCompiler; -import jdk.internal.misc.Unsafe; -import static jdk.test.lib.Asserts.*; -import jdk.test.lib.process.OutputAnalyzer; -import jdk.test.lib.process.ProcessTools; -import jdk.test.whitebox.WhiteBox; - -public class CleanProtectionDomain { - - public static void main(String args[]) throws Exception { - ProcessBuilder pb = ProcessTools.createLimitedTestJavaProcessBuilder( - "-Xlog:protectiondomain+table=debug", - "--add-exports=java.base/jdk.internal.misc=ALL-UNNAMED", - "-XX:+UnlockDiagnosticVMOptions", - "-XX:+WhiteBoxAPI", - "-Xbootclasspath/a:.", - "-Djava.security.manager=allow", - Test.class.getName()); - OutputAnalyzer output = new OutputAnalyzer(pb.start()); - output.shouldContain("protection domain added"); - output.shouldContain("protection domain unlinked"); - output.shouldHaveExitValue(0); - } - - static class Test { - public static void test() throws Exception { - TestClassLoader classloader = new TestClassLoader(); - ProtectionDomain pd = new ProtectionDomain(null, null); - byte klassbuf[] = InMemoryJavaCompiler.compile("TestClass", "class TestClass { }"); - Class<?> klass = classloader.defineClass("TestClass", klassbuf, pd); - } - - public static void main(String[] args) throws Exception { - WhiteBox wb = WhiteBox.getWhiteBox(); - int removedCountOrig = wb.protectionDomainRemovedCount(); - int removedCount; - - test(); - - // Wait until ServiceThread cleans ProtectionDomain table. - // When the TestClassLoader is unloaded by GC, at least one - // ProtectionDomainCacheEntry will be eligible for removal. - int cnt = 0; - while (true) { - if (cnt++ % 30 == 0) { - System.gc(); - } - removedCount = wb.protectionDomainRemovedCount(); - if (removedCountOrig != removedCount) { - break; - } - Thread.sleep(100); - } - } - - private static class TestClassLoader extends ClassLoader { - public TestClassLoader() { - super(); - } - - public Class<?> defineClass(String name, byte[] bytes, ProtectionDomain pd) { - return defineClass(name, bytes, 0, bytes.length, pd); - } - } - } -} diff --git a/test/hotspot/jtreg/runtime/Dictionary/ProtectionDomainCacheTest.java b/test/hotspot/jtreg/runtime/Dictionary/ProtectionDomainCacheTest.java deleted file mode 100644 index 423fba7d221..00000000000 --- a/test/hotspot/jtreg/runtime/Dictionary/ProtectionDomainCacheTest.java +++ /dev/null @@ -1,115 +0,0 @@ -/* - * Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -/* - * @test - * @bug 8151486 8218266 - * @summary Call Class.forName() on the system classloader from a class loaded - * from a custom classloader, using the current class's protection domain. - * @requires vm.flagless - * @library /test/lib - * @modules java.base/jdk.internal.misc - * @build jdk.test.lib.Utils - * jdk.test.lib.util.JarUtils - * @build ClassForName ProtectionDomainCacheTest - * @run driver ProtectionDomainCacheTest - */ - -import java.net.URL; -import java.net.URLClassLoader; -import java.nio.file.FileSystems; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.util.List; -import jdk.test.lib.Utils; -import jdk.test.lib.util.JarUtils; -import java.io.File; - -import jdk.test.lib.process.OutputAnalyzer; -import jdk.test.lib.process.ProcessTools; - -/* - * Create .jar, load ClassForName from .jar using a URLClassLoader - */ -public class ProtectionDomainCacheTest { - static class Test { - private static final long TIMEOUT = (long)(5000.0 * Utils.TIMEOUT_FACTOR); - private static final String TESTCLASSES = System.getProperty("test.classes", "."); - private static final String CLASSFILENAME = "ClassForName.class"; - - // Use a new classloader to load the ClassForName class. - public static void loadAndRun(Path jarFilePath) - throws Exception { - ClassLoader classLoader = new URLClassLoader( - new URL[]{jarFilePath.toUri().toURL()}) { - @Override public String toString() { return "LeakedClassLoader"; } - }; - - Class<?> loadClass = Class.forName("ClassForName", true, classLoader); - loadClass.newInstance(); - - System.out.println("returning : " + classLoader); - } - - public static void main(final String[] args) throws Exception { - // Create a temporary .jar file containing ClassForName.class - Path testClassesDir = Paths.get(TESTCLASSES); - Path jarFilePath = Files.createTempFile("cfn", ".jar"); - JarUtils.createJarFile(jarFilePath, testClassesDir, CLASSFILENAME); - jarFilePath.toFile().deleteOnExit(); - - // Remove the ClassForName.class file that jtreg built, to make sure - // we're loading from the tmp .jar - Path classFile = FileSystems.getDefault().getPath(TESTCLASSES, - CLASSFILENAME); - Files.delete(classFile); - - for (int i = 0; i < 20; i++) { - loadAndRun(jarFilePath); - } - - // Give the GC a chance to unload protection domains - for (int i = 0; i < 100; i++) { - System.gc(); - } - System.out.println("All Classloaders and protection domain cache entries successfully unloaded"); - } - } - - public static void main(String args[]) throws Exception { - ProcessBuilder pb = ProcessTools.createLimitedTestJavaProcessBuilder( - "-Djava.security.policy==" + System.getProperty("test.src") + File.separator + "test.policy", - "-Dtest.classes=" + System.getProperty("test.classes", "."), - "-XX:+UnlockDiagnosticVMOptions", - "-XX:VerifySubSet=dictionary", - "-XX:+VerifyAfterGC", - "-Xlog:gc+verify,protectiondomain=trace", - "-Djava.security.manager", - Test.class.getName()); - OutputAnalyzer output = new OutputAnalyzer(pb.start()); - output.shouldContain("PD in set is not alive"); - output.shouldContain("HandshakeForPD::do_thread"); - output.shouldHaveExitValue(0); - } -} diff --git a/test/hotspot/jtreg/runtime/logging/ProtectionDomainVerificationTest.java b/test/hotspot/jtreg/runtime/logging/ProtectionDomainVerificationTest.java deleted file mode 100644 index e8e5c881125..00000000000 --- a/test/hotspot/jtreg/runtime/logging/ProtectionDomainVerificationTest.java +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright (c) 2016, 2024, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -/* - * @test ProtectionDomainVerificationTest - * @bug 8149064 - * @requires vm.flagless - * @modules java.base/jdk.internal.misc - * @library /test/lib - * @run driver ProtectionDomainVerificationTest - */ - -import jdk.test.lib.process.OutputAnalyzer; -import jdk.test.lib.Platform; -import jdk.test.lib.process.ProcessTools; - -public class ProtectionDomainVerificationTest { - - public static void main(String... args) throws Exception { - - // -Xlog:protectiondomain=trace - ProcessBuilder pb = ProcessTools.createLimitedTestJavaProcessBuilder("-Xlog:protectiondomain=trace", - "-Xmx128m", - "-Djava.security.manager=allow", - Hello.class.getName(), "security_manager"); - new OutputAnalyzer(pb.start()) - .shouldHaveExitValue(0) - .shouldContain("[protectiondomain] Checking package access") - .shouldContain("[protectiondomain] adding protection domain that can access class"); - - // -Xlog:protectiondomain=debug - pb = ProcessTools.createLimitedTestJavaProcessBuilder("-Xlog:protectiondomain=debug", - "-Xmx128m", - "-Djava.security.manager=allow", - Hello.class.getName(), "security_manager"); - new OutputAnalyzer(pb.start()) - .shouldHaveExitValue(0) - .shouldContain("[protectiondomain] Checking package access") - .shouldNotContain("[protectiondomain] adding protection domain that can access class"); - - // -Xlog:protectiondomain=debug - pb = ProcessTools.createLimitedTestJavaProcessBuilder("-Xlog:protectiondomain=trace", - "-Xmx128m", - "-Djava.security.manager=disallow", - Hello.class.getName()); - new OutputAnalyzer(pb.start()) - .shouldHaveExitValue(0) - .shouldNotContain("[protectiondomain] Checking package access") - .shouldNotContain("pd set count = #"); - } - - public static class Hello { - public static void main(String[] args) { - if (args.length == 1) { - // Need a security manager to trigger logging. - System.setSecurityManager(new SecurityManager()); - } - System.out.print("Hello!"); - } - } -} diff --git a/test/hotspot/jtreg/serviceability/dcmd/vm/DictionaryStatsTest.java b/test/hotspot/jtreg/serviceability/dcmd/vm/DictionaryStatsTest.java index 29223efb8ee..50b6b53233e 100644 --- a/test/hotspot/jtreg/serviceability/dcmd/vm/DictionaryStatsTest.java +++ b/test/hotspot/jtreg/serviceability/dcmd/vm/DictionaryStatsTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -67,14 +67,6 @@ public class DictionaryStatsTest { // Variance of bucket size : 0.281 // Std. dev. of bucket size: 0.530 // Maximum bucket size : 2 - // ProtectionDomainCacheTable statistics: - // Number of buckets : 1009 = 8072 bytes, each 8 - // Number of entries : 0 = 0 bytes, each 0 - // Total footprint : = 8072 bytes - // Average bucket size : 0.000 - // Variance of bucket size : 0.000 - // Std. dev. of bucket size: 0.000 - // Maximum bucket size : 0 public void run(CommandExecutor executor) throws ClassNotFoundException { @@ -99,10 +91,6 @@ public void run(CommandExecutor executor) throws ClassNotFoundException { output.shouldContain("Std. dev. of bucket size"); output.shouldContain("Maximum bucket size"); output.shouldMatch("LoaderConstraintTable statistics:"); - // Would be nice to run this with "-Djava.security.manager=allow" - // so the numbers aren't 0 (running make with VM_OPTIONS allowing - // security manager does get 12 entries in this table.) - output.shouldMatch("ProtectionDomainCacheTable statistics:"); // what is this? Reference.reachabilityFence(named_cl); diff --git a/test/lib/jdk/test/whitebox/WhiteBox.java b/test/lib/jdk/test/whitebox/WhiteBox.java index 0db7c46c6cf..2e723d91267 100644 --- a/test/lib/jdk/test/whitebox/WhiteBox.java +++ b/test/lib/jdk/test/whitebox/WhiteBox.java @@ -776,9 +776,6 @@ public native int validateCgroup(String procCgroups, // Resolved Method Table public native long resolvedMethodItemsCount(); - // Protection Domain Table - public native int protectionDomainRemovedCount(); - public native int getKlassMetadataSize(Class<?> c); // ThreadSMR GC safety check for threadObj From d52d13648612546ef4458579aff6daf965586a03 Mon Sep 17 00:00:00 2001 From: Daniel Fuchs <dfuchs@openjdk.org> Date: Mon, 18 Nov 2024 15:17:40 +0000 Subject: [PATCH 057/311] 8344221: Remove calls to SecurityManager and and doPrivileged in java.net.IDN, java.net.URL, java.net.URLConnection, sun.net.util.URLUtil, and java.net.URLStreamHandlerProvider after JEP 486 integration Reviewed-by: alanb, rriggs --- src/java.base/share/classes/java/net/IDN.java | 13 +- src/java.base/share/classes/java/net/URL.java | 121 +++--------------- .../share/classes/java/net/URLConnection.java | 59 +++------ .../net/spi/URLStreamHandlerProvider.java | 10 -- .../share/classes/sun/net/util/URLUtil.java | 6 +- 5 files changed, 37 insertions(+), 172 deletions(-) diff --git a/src/java.base/share/classes/java/net/IDN.java b/src/java.base/share/classes/java/net/IDN.java index 5e01ab6532d..6f11643264f 100644 --- a/src/java.base/share/classes/java/net/IDN.java +++ b/src/java.base/share/classes/java/net/IDN.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,8 +26,6 @@ import java.io.InputStream; import java.io.IOException; -import java.security.AccessController; -import java.security.PrivilegedAction; import jdk.internal.icu.impl.Punycode; import jdk.internal.icu.text.StringPrep; @@ -248,14 +246,7 @@ public static String toUnicode(String input) { StringPrep stringPrep = null; try { final String IDN_PROFILE = "/sun/net/idn/uidna.spp"; - @SuppressWarnings("removal") - InputStream stream = System.getSecurityManager() != null - ? AccessController.doPrivileged(new PrivilegedAction<>() { - public InputStream run() { - return StringPrep.class.getResourceAsStream(IDN_PROFILE); - }}) - : StringPrep.class.getResourceAsStream(IDN_PROFILE); - + InputStream stream = StringPrep.class.getResourceAsStream(IDN_PROFILE); stringPrep = new StringPrep(stream); stream.close(); } catch (IOException e) { diff --git a/src/java.base/share/classes/java/net/URL.java b/src/java.base/share/classes/java/net/URL.java index 418651bc7c2..be4daa28f33 100644 --- a/src/java.base/share/classes/java/net/URL.java +++ b/src/java.base/share/classes/java/net/URL.java @@ -30,8 +30,6 @@ import java.io.InputStream; import java.net.spi.URLStreamHandlerProvider; import java.nio.file.Path; -import java.security.AccessController; -import java.security.PrivilegedAction; import java.util.Hashtable; import java.io.InvalidObjectException; import java.io.ObjectStreamException; @@ -39,8 +37,6 @@ import java.io.ObjectInputStream.GetField; import java.util.Iterator; import java.util.Locale; -import java.util.NoSuchElementException; -import java.util.ServiceConfigurationError; import java.util.ServiceLoader; import jdk.internal.access.JavaNetURLAccess; @@ -48,8 +44,6 @@ import jdk.internal.misc.ThreadTracker; import jdk.internal.misc.VM; import sun.net.util.IPAddressUtil; -import sun.security.util.SecurityConstants; -import sun.security.action.GetPropertyAction; /** * Class {@code URL} represents a Uniform Resource @@ -485,14 +479,6 @@ public URL(String protocol, String host, String file) @Deprecated(since = "20") public URL(String protocol, String host, int port, String file, URLStreamHandler handler) throws MalformedURLException { - if (handler != null) { - @SuppressWarnings("removal") - SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - // check for permission to specify a handler - checkSpecifyHandler(sm); - } - } protocol = lowerCaseProtocol(protocol); this.protocol = protocol; @@ -683,15 +669,6 @@ public URL(URL context, String spec, URLStreamHandler handler) boolean aRef=false; boolean isRelative = false; - // Check for permission to specify a handler - if (handler != null) { - @SuppressWarnings("removal") - SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - checkSpecifyHandler(sm); - } - } - try { limit = spec.length(); while ((limit > 0) && (spec.charAt(limit - 1) <= ' ')) { @@ -912,13 +889,6 @@ private boolean isValidProtocol(String protocol) { return true; } - /* - * Checks for permission to specify a stream handler. - */ - private void checkSpecifyHandler(@SuppressWarnings("removal") SecurityManager sm) { - sm.checkPermission(SecurityConstants.SPECIFY_HANDLER_PERMISSION); - } - /** * Sets the specified 8 fields of the URL. This is not a public method so * that only URLStreamHandlers can modify URL fields. URLs are otherwise @@ -956,9 +926,8 @@ void set(String protocol, String host, int port, /** * Returns the address of the host represented by this URL. - * A {@link SecurityException} or an {@link UnknownHostException} - * while getting the host address will result in this method returning - * {@code null} + * An {@link UnknownHostException} while getting the host address + * will result in this method returning {@code null}. * * @return an {@link InetAddress} representing the host */ @@ -972,7 +941,7 @@ synchronized InetAddress getHostAddress() { } try { hostAddress = InetAddress.getByName(host); - } catch (UnknownHostException | SecurityException ex) { + } catch (UnknownHostException e) { return null; } return hostAddress; @@ -1271,16 +1240,6 @@ public URLConnection openConnection(Proxy proxy) // Create a copy of Proxy as a security measure Proxy p = proxy == Proxy.NO_PROXY ? Proxy.NO_PROXY : sun.net.ApplicationProxy.create(proxy); - @SuppressWarnings("removal") - SecurityManager sm = System.getSecurityManager(); - if (p.type() != Proxy.Type.DIRECT && sm != null) { - InetSocketAddress epoint = (InetSocketAddress) p.address(); - if (epoint.isUnresolved()) - sm.checkConnect(epoint.getHostName(), epoint.getPort()); - else - sm.checkConnect(epoint.getAddress().getHostAddress(), - epoint.getPort()); - } return handler.openConnection(this, p); } @@ -1358,11 +1317,6 @@ public static void setURLStreamHandlerFactory(URLStreamHandlerFactory fac) { if (factory != null) { throw new Error("factory already defined"); } - @SuppressWarnings("removal") - SecurityManager security = System.getSecurityManager(); - if (security != null) { - security.checkSetFactory(); - } handlers.clear(); // safe publication of URLStreamHandlerFactory with volatile write @@ -1398,8 +1352,7 @@ public URLStreamHandler createURLStreamHandler(String protocol) { } private static URLStreamHandler lookupViaProperty(String protocol) { - String packagePrefixList = - GetPropertyAction.privilegedGetProperty(protocolPathProp); + String packagePrefixList = System.getProperty(protocolPathProp); if (packagePrefixList == null || packagePrefixList.isEmpty()) { // not set return null; @@ -1435,47 +1388,6 @@ private static URLStreamHandler lookupViaProperty(String protocol) { return handler; } - private static Iterator<URLStreamHandlerProvider> providers() { - return new Iterator<>() { - - final ClassLoader cl = ClassLoader.getSystemClassLoader(); - final ServiceLoader<URLStreamHandlerProvider> sl = - ServiceLoader.load(URLStreamHandlerProvider.class, cl); - final Iterator<URLStreamHandlerProvider> i = sl.iterator(); - - URLStreamHandlerProvider next = null; - - private boolean getNext() { - while (next == null) { - try { - if (!i.hasNext()) - return false; - next = i.next(); - } catch (ServiceConfigurationError sce) { - if (sce.getCause() instanceof SecurityException) { - // Ignore security exceptions - continue; - } - throw sce; - } - } - return true; - } - - public boolean hasNext() { - return getNext(); - } - - public URLStreamHandlerProvider next() { - if (!getNext()) - throw new NoSuchElementException(); - URLStreamHandlerProvider n = next; - next = null; - return n; - } - }; - } - private static class ThreadTrackHolder { static final ThreadTracker TRACKER = new ThreadTracker(); } @@ -1488,26 +1400,23 @@ private static void endLookup(Object key) { ThreadTrackHolder.TRACKER.end(key); } - @SuppressWarnings("removal") private static URLStreamHandler lookupViaProviders(final String protocol) { Object key = tryBeginLookup(); if (key == null) { throw new Error("Circular loading of URL stream handler providers detected"); } try { - return AccessController.doPrivileged( - new PrivilegedAction<>() { - public URLStreamHandler run() { - Iterator<URLStreamHandlerProvider> itr = providers(); - while (itr.hasNext()) { - URLStreamHandlerProvider f = itr.next(); - URLStreamHandler h = f.createURLStreamHandler(protocol); - if (h != null) - return h; - } - return null; - } - }); + final ClassLoader cl = ClassLoader.getSystemClassLoader(); + final ServiceLoader<URLStreamHandlerProvider> sl = + ServiceLoader.load(URLStreamHandlerProvider.class, cl); + final Iterator<URLStreamHandlerProvider> itr = sl.iterator(); + while (itr.hasNext()) { + URLStreamHandlerProvider f = itr.next(); + URLStreamHandler h = f.createURLStreamHandler(protocol); + if (h != null) + return h; + } + return null; } finally { endLookup(key); } diff --git a/src/java.base/share/classes/java/net/URLConnection.java b/src/java.base/share/classes/java/net/URLConnection.java index 168e4df29df..209b84de200 100644 --- a/src/java.base/share/classes/java/net/URLConnection.java +++ b/src/java.base/share/classes/java/net/URLConnection.java @@ -28,7 +28,6 @@ import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; -import java.security.PrivilegedAction; import java.util.Hashtable; import java.util.concurrent.ConcurrentHashMap; import java.util.Date; @@ -42,10 +41,8 @@ import java.util.Map; import java.util.List; import java.security.Permission; -import java.security.AccessController; import sun.security.util.SecurityConstants; import sun.net.www.MessageHeader; -import sun.security.action.GetPropertyAction; /** * The abstract class {@code URLConnection} is the superclass @@ -328,9 +325,6 @@ public String getContentTypeFor(String fileName) { * @since 1.2 */ public static void setFileNameMap(FileNameMap map) { - @SuppressWarnings("removal") - SecurityManager sm = System.getSecurityManager(); - if (sm != null) sm.checkSetFactory(); fileNameMap = map; } @@ -1285,11 +1279,6 @@ public static synchronized void setContentHandlerFactory(ContentHandlerFactory f if (factory != null) { throw new Error("factory already defined"); } - @SuppressWarnings("removal") - SecurityManager security = System.getSecurityManager(); - if (security != null) { - security.checkSetFactory(); - } factory = fac; } @@ -1401,35 +1390,22 @@ private ContentHandler lookupContentHandlerClassFor(String contentType) { @SuppressWarnings("removal") private ContentHandler lookupContentHandlerViaProvider(String contentType) { - return AccessController.doPrivileged( - new PrivilegedAction<>() { - @Override - public ContentHandler run() { - ClassLoader cl = ClassLoader.getSystemClassLoader(); - ServiceLoader<ContentHandlerFactory> sl = - ServiceLoader.load(ContentHandlerFactory.class, cl); - - Iterator<ContentHandlerFactory> iterator = sl.iterator(); - - ContentHandler handler = null; - while (iterator.hasNext()) { - ContentHandlerFactory f; - try { - f = iterator.next(); - } catch (ServiceConfigurationError e) { - if (e.getCause() instanceof SecurityException) { - continue; - } - throw e; - } - handler = f.createContentHandler(contentType); - if (handler != null) { - break; - } - } - return handler; - } - }); + + ClassLoader cl = ClassLoader.getSystemClassLoader(); + ServiceLoader<ContentHandlerFactory> sl = + ServiceLoader.load(ContentHandlerFactory.class, cl); + + Iterator<ContentHandlerFactory> iterator = sl.iterator(); + + ContentHandler handler = null; + while (iterator.hasNext()) { + ContentHandlerFactory f = iterator.next(); + handler = f.createContentHandler(contentType); + if (handler != null) { + break; + } + } + return handler; } /** @@ -1465,8 +1441,7 @@ private String typeToPackageName(String contentType) { * is always the last one on the returned package list. */ private String getContentHandlerPkgPrefixes() { - String packagePrefixList = - GetPropertyAction.privilegedGetProperty(contentPathProp, ""); + String packagePrefixList = System.getProperty(contentPathProp, ""); if (packagePrefixList != "") { packagePrefixList += "|"; diff --git a/src/java.base/share/classes/java/net/spi/URLStreamHandlerProvider.java b/src/java.base/share/classes/java/net/spi/URLStreamHandlerProvider.java index 202f3e654fa..05733f7287d 100644 --- a/src/java.base/share/classes/java/net/spi/URLStreamHandlerProvider.java +++ b/src/java.base/share/classes/java/net/spi/URLStreamHandlerProvider.java @@ -49,19 +49,9 @@ public abstract class URLStreamHandlerProvider implements URLStreamHandlerFactory { - private static Void checkPermission() { - @SuppressWarnings("removal") - SecurityManager sm = System.getSecurityManager(); - if (sm != null) - sm.checkPermission(new RuntimePermission("setFactory")); - return null; - } - private URLStreamHandlerProvider(Void ignore) { } - /** * Initializes a new URL stream handler provider. */ protected URLStreamHandlerProvider() { - this(checkPermission()); } } diff --git a/src/java.base/share/classes/sun/net/util/URLUtil.java b/src/java.base/share/classes/sun/net/util/URLUtil.java index 9eb04ce4151..055742baf2f 100644 --- a/src/java.base/share/classes/sun/net/util/URLUtil.java +++ b/src/java.base/share/classes/sun/net/util/URLUtil.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -38,12 +38,12 @@ public class URLUtil { /** * Returns a string form of the url suitable for use as a key in HashMap/Sets. * - * The string form should be behave in the same manner as the URL when + * The string form should behave in the same manner as the URL when * compared for equality in a HashMap/Set, except that no nameservice * lookup is done on the hostname (only string comparison), and the fragment * is not considered. * - * @see java.net.URLStreamHandler.sameFile(java.net.URL) + * @see java.net.URL#sameFile(java.net.URL) */ public static String urlNoFragString(URL url) { StringBuilder strForm = new StringBuilder(); From 9b0ab92b16f682e65e9847e8127b6ce09fc5759c Mon Sep 17 00:00:00 2001 From: Roger Riggs <rriggs@openjdk.org> Date: Mon, 18 Nov 2024 16:17:07 +0000 Subject: [PATCH 058/311] 8344034: Remove security manager dependency in Serialization Reviewed-by: mullan, alanb --- .../classes/java/io/ObjectInputFilter.java | 20 +- .../classes/java/io/ObjectInputStream.java | 126 ++------- .../classes/java/io/ObjectOutputStream.java | 85 ++---- .../classes/java/io/ObjectStreamClass.java | 242 ++++-------------- .../classes/java/io/ObjectStreamField.java | 13 +- .../SerializationMisdeclarationChecker.java | 26 +- .../reflect/CallerSensitive/CheckCSMs.java | 3 +- 7 files changed, 101 insertions(+), 414 deletions(-) diff --git a/src/java.base/share/classes/java/io/ObjectInputFilter.java b/src/java.base/share/classes/java/io/ObjectInputFilter.java index 9a04e1f58e3..9232111de07 100644 --- a/src/java.base/share/classes/java/io/ObjectInputFilter.java +++ b/src/java.base/share/classes/java/io/ObjectInputFilter.java @@ -29,8 +29,6 @@ import jdk.internal.util.StaticProperty; import java.lang.reflect.InvocationTargetException; -import java.security.AccessController; -import java.security.PrivilegedAction; import java.security.Security; import java.util.ArrayList; import java.util.List; @@ -630,17 +628,13 @@ final class Config { configLog = System.getLogger("java.io.serialization"); // Get the values of the system properties, if they are defined - @SuppressWarnings("removal") String factoryClassName = StaticProperty.jdkSerialFilterFactory() != null ? StaticProperty.jdkSerialFilterFactory() - : AccessController.doPrivileged((PrivilegedAction<String>) () -> - Security.getProperty(SERIAL_FILTER_FACTORY_PROPNAME)); + : Security.getProperty(SERIAL_FILTER_FACTORY_PROPNAME); - @SuppressWarnings("removal") String filterString = StaticProperty.jdkSerialFilter() != null ? StaticProperty.jdkSerialFilter() - : AccessController.doPrivileged((PrivilegedAction<String>) () -> - Security.getProperty(SERIAL_FILTER_PROPNAME)); + : Security.getProperty(SERIAL_FILTER_PROPNAME); // Initialize the static filter if the jdk.serialFilter is present String filterMessage = null; @@ -734,11 +728,6 @@ public static ObjectInputFilter getSerialFilter() { */ public static void setSerialFilter(ObjectInputFilter filter) { Objects.requireNonNull(filter, "filter"); - @SuppressWarnings("removal") - SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - sm.checkPermission(ObjectStreamConstants.SERIAL_FILTER_PERMISSION); - } if (invalidFilterMessage != null) { throw new IllegalStateException(invalidFilterMessage); } @@ -831,11 +820,6 @@ static BinaryOperator<ObjectInputFilter> getSerialFilterFactorySingleton() { */ public static void setSerialFilterFactory(BinaryOperator<ObjectInputFilter> filterFactory) { Objects.requireNonNull(filterFactory, "filterFactory"); - @SuppressWarnings("removal") - SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - sm.checkPermission(ObjectStreamConstants.SERIAL_FILTER_PERMISSION); - } if (filterFactoryNoReplace.getAndSet(true)) { final String msg = serialFilterFactory != null ? "Cannot replace filter factory: " + serialFilterFactory.getClass().getName() diff --git a/src/java.base/share/classes/java/io/ObjectInputStream.java b/src/java.base/share/classes/java/io/ObjectInputStream.java index 60d8cadf6a3..31d0aecf831 100644 --- a/src/java.base/share/classes/java/io/ObjectInputStream.java +++ b/src/java.base/share/classes/java/io/ObjectInputStream.java @@ -34,13 +34,7 @@ import java.lang.reflect.Modifier; import java.lang.reflect.Proxy; import java.nio.charset.StandardCharsets; -import java.security.AccessControlContext; -import java.security.AccessController; -import java.security.PrivilegedAction; -import java.security.PrivilegedActionException; -import java.security.PrivilegedExceptionAction; import java.util.Arrays; -import java.util.Map; import java.util.Objects; import jdk.internal.access.JavaLangAccess; @@ -49,8 +43,6 @@ import jdk.internal.misc.Unsafe; import jdk.internal.util.ByteArray; import sun.reflect.misc.ReflectUtil; -import sun.security.action.GetBooleanAction; -import sun.security.action.GetIntegerAction; /** * An ObjectInputStream deserializes primitive data and objects previously @@ -278,8 +270,8 @@ protected Boolean computeValue(Class<?> type) { * have been read. * See {@link #setObjectInputFilter(ObjectInputFilter)} */ - static final boolean SET_FILTER_AFTER_READ = GetBooleanAction - .privilegedGetProperty("jdk.serialSetFilterAfterRead"); + static final boolean SET_FILTER_AFTER_READ = + Boolean.getBoolean("jdk.serialSetFilterAfterRead"); /** * Property to control {@link GetField#get(String, Object)} conversion of @@ -287,8 +279,8 @@ protected Boolean computeValue(Class<?> type) { * {@link GetField#get(String, Object)} returns null otherwise * throwing {@link ClassNotFoundException}. */ - private static final boolean GETFIELD_CNFE_RETURNS_NULL = GetBooleanAction - .privilegedGetProperty("jdk.serialGetFieldCnfeReturnsNull"); + private static final boolean GETFIELD_CNFE_RETURNS_NULL = + Boolean.getBoolean("jdk.serialGetFieldCnfeReturnsNull"); /** * Property to override the implementation limit on the number @@ -296,8 +288,8 @@ protected Boolean computeValue(Class<?> type) { * The maximum number of interfaces allowed for a proxy is limited to 65535 by * {@link java.lang.reflect.Proxy#newProxyInstance(ClassLoader, Class[], InvocationHandler)}. */ - static final int PROXY_INTERFACE_LIMIT = Math.clamp(GetIntegerAction - .privilegedGetProperty("jdk.serialProxyInterfaceLimit", 65535), 0, 65535); + static final int PROXY_INTERFACE_LIMIT = + Math.clamp(Integer.getInteger("jdk.serialProxyInterfaceLimit", 65535), 0, 65535); } /* @@ -386,7 +378,6 @@ private static class Logging { */ @SuppressWarnings("this-escape") public ObjectInputStream(InputStream in) throws IOException { - verifySubclass(); bin = new BlockDataInputStream(in); handles = new HandleTable(10); vlist = new ValidationList(); @@ -416,11 +407,6 @@ public ObjectInputStream(InputStream in) throws IOException { * fails due to invalid serial filter or serial filter factory properties. */ protected ObjectInputStream() throws IOException { - @SuppressWarnings("removal") - SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - sm.checkPermission(SUBCLASS_IMPLEMENTATION_PERMISSION); - } bin = null; handles = null; vlist = null; @@ -907,13 +893,6 @@ protected boolean enableResolveObject(boolean enable) { if (enable == enableResolve) { return enable; } - if (enable) { - @SuppressWarnings("removal") - SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - sm.checkPermission(SUBSTITUTION_PERMISSION); - } - } enableResolve = enable; return !enableResolve; } @@ -1309,11 +1288,6 @@ public final ObjectInputFilter getObjectInputFilter() { * @since 9 */ public final void setObjectInputFilter(ObjectInputFilter filter) { - @SuppressWarnings("removal") - SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - sm.checkPermission(ObjectStreamConstants.SERIAL_FILTER_PERMISSION); - } if (totalObjectRefs > 0 && !Caches.SET_FILTER_AFTER_READ) { throw new IllegalStateException( "filter can not be set after an object has been read"); @@ -1571,58 +1545,29 @@ public abstract boolean get(String name, boolean val) public abstract Object get(String name, Object val) throws IOException, ClassNotFoundException; } - /** - * Verifies that this (possibly subclass) instance can be constructed - * without violating security constraints: the subclass must not override - * security-sensitive non-final methods, or else the - * "enableSubclassImplementation" SerializablePermission is checked. - */ - private void verifySubclass() { - Class<?> cl = getClass(); - if (cl == ObjectInputStream.class) { - return; - } - @SuppressWarnings("removal") - SecurityManager sm = System.getSecurityManager(); - if (sm == null) { - return; - } - boolean result = Caches.subclassAudits.get(cl); - if (!result) { - sm.checkPermission(SUBCLASS_IMPLEMENTATION_PERMISSION); - } - } - /** * Performs reflective checks on given subclass to verify that it doesn't * override security-sensitive non-final methods. Returns TRUE if subclass * is "safe", FALSE otherwise. */ - @SuppressWarnings("removal") private static Boolean auditSubclass(Class<?> subcl) { - return AccessController.doPrivileged( - new PrivilegedAction<Boolean>() { - public Boolean run() { - for (Class<?> cl = subcl; - cl != ObjectInputStream.class; - cl = cl.getSuperclass()) - { - try { - cl.getDeclaredMethod( - "readUnshared", (Class[]) null); - return Boolean.FALSE; - } catch (NoSuchMethodException ex) { - } - try { - cl.getDeclaredMethod("readFields", (Class[]) null); - return Boolean.FALSE; - } catch (NoSuchMethodException ex) { - } - } - return Boolean.TRUE; - } + for (Class<?> cl = subcl; + cl != ObjectInputStream.class; + cl = cl.getSuperclass()) + { + try { + cl.getDeclaredMethod( + "readUnshared", (Class[]) null); + return Boolean.FALSE; + } catch (NoSuchMethodException ex) { } - ); + try { + cl.getDeclaredMethod("readFields", (Class[]) null); + return Boolean.FALSE; + } catch (NoSuchMethodException ex) { + } + } + return Boolean.TRUE; } /** @@ -2702,16 +2647,11 @@ private static class Callback { final ObjectInputValidation obj; final int priority; Callback next; - @SuppressWarnings("removal") - final AccessControlContext acc; - Callback(ObjectInputValidation obj, int priority, Callback next, - @SuppressWarnings("removal") AccessControlContext acc) - { + Callback(ObjectInputValidation obj, int priority, Callback next) { this.obj = obj; this.priority = priority; this.next = next; - this.acc = acc; } } @@ -2740,12 +2680,10 @@ void register(ObjectInputValidation obj, int priority) prev = cur; cur = cur.next; } - @SuppressWarnings("removal") - AccessControlContext acc = AccessController.getContext(); if (prev != null) { - prev.next = new Callback(obj, priority, cur, acc); + prev.next = new Callback(obj, priority, cur); } else { - list = new Callback(obj, priority, list, acc); + list = new Callback(obj, priority, list); } } @@ -2756,23 +2694,15 @@ void register(ObjectInputValidation obj, int priority) * throws an InvalidObjectException, the callback process is terminated * and the exception propagated upwards. */ - @SuppressWarnings("removal") void doCallbacks() throws InvalidObjectException { try { while (list != null) { - AccessController.doPrivileged( - new PrivilegedExceptionAction<Void>() - { - public Void run() throws InvalidObjectException { - list.obj.validateObject(); - return null; - } - }, list.acc); + list.obj.validateObject(); list = list.next; } - } catch (PrivilegedActionException ex) { + } catch (InvalidObjectException ex) { list = null; - throw (InvalidObjectException) ex.getException(); + throw ex; } } diff --git a/src/java.base/share/classes/java/io/ObjectOutputStream.java b/src/java.base/share/classes/java/io/ObjectOutputStream.java index 429c91ab673..5225c673705 100644 --- a/src/java.base/share/classes/java/io/ObjectOutputStream.java +++ b/src/java.base/share/classes/java/io/ObjectOutputStream.java @@ -26,8 +26,6 @@ package java.io; -import java.security.AccessController; -import java.security.PrivilegedAction; import java.util.ArrayList; import java.util.Arrays; import java.util.List; @@ -224,11 +222,8 @@ protected Boolean computeValue(Class<?> type) { * value of "sun.io.serialization.extendedDebugInfo" property, * as true or false for extended information about exception's place */ - @SuppressWarnings("removal") private static final boolean extendedDebugInfo = - java.security.AccessController.doPrivileged( - new sun.security.action.GetBooleanAction( - "sun.io.serialization.extendedDebugInfo")).booleanValue(); + Boolean.getBoolean("sun.io.serialization.extendedDebugInfo"); /** * Creates an ObjectOutputStream that writes to the specified OutputStream. @@ -247,7 +242,6 @@ protected Boolean computeValue(Class<?> type) { */ @SuppressWarnings("this-escape") public ObjectOutputStream(OutputStream out) throws IOException { - verifySubclass(); bout = new BlockDataOutputStream(out); handles = new HandleTable(10, (float) 3.00); subs = new ReplaceTable(10, (float) 3.00); @@ -269,11 +263,6 @@ public ObjectOutputStream(OutputStream out) throws IOException { * @throws IOException if an I/O error occurs while creating this stream */ protected ObjectOutputStream() throws IOException { - @SuppressWarnings("removal") - SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - sm.checkPermission(SUBCLASS_IMPLEMENTATION_PERMISSION); - } bout = null; handles = null; subs = null; @@ -595,13 +584,6 @@ protected boolean enableReplaceObject(boolean enable) { if (enable == enableReplace) { return enable; } - if (enable) { - @SuppressWarnings("removal") - SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - sm.checkPermission(SUBSTITUTION_PERMISSION); - } - } enableReplace = enable; return !enableReplace; } @@ -625,8 +607,8 @@ protected void writeStreamHeader() throws IOException { * stream. Subclasses of ObjectOutputStream may override this method to * customize the way in which class descriptors are written to the * serialization stream. The corresponding method in ObjectInputStream, - * {@link ObjectInputStream#readClassDescriptor readClassDescriptor}, should then be overridden to - * reconstitute the class descriptor from its custom stream representation. + * {@link ObjectInputStream#readClassDescriptor readClassDescriptor}, should then be + * overridden to reconstitute the class descriptor from its custom stream representation. * By default, this method writes class descriptors according to the format * defined in the <a href="{@docRoot}/../specs/serialization/index.html"> * <cite>Java Object Serialization Specification</cite></a>. @@ -1022,58 +1004,29 @@ void writeTypeString(String str) throws IOException { } } - /** - * Verifies that this (possibly subclass) instance can be constructed - * without violating security constraints: the subclass must not override - * security-sensitive non-final methods, or else the - * "enableSubclassImplementation" SerializablePermission is checked. - */ - private void verifySubclass() { - Class<?> cl = getClass(); - if (cl == ObjectOutputStream.class) { - return; - } - @SuppressWarnings("removal") - SecurityManager sm = System.getSecurityManager(); - if (sm == null) { - return; - } - boolean result = Caches.subclassAudits.get(cl); - if (!result) { - sm.checkPermission(SUBCLASS_IMPLEMENTATION_PERMISSION); - } - } - /** * Performs reflective checks on given subclass to verify that it doesn't * override security-sensitive non-final methods. Returns TRUE if subclass * is "safe", FALSE otherwise. */ - @SuppressWarnings("removal") private static Boolean auditSubclass(Class<?> subcl) { - return AccessController.doPrivileged( - new PrivilegedAction<>() { - public Boolean run() { - for (Class<?> cl = subcl; - cl != ObjectOutputStream.class; - cl = cl.getSuperclass()) - { - try { - cl.getDeclaredMethod( - "writeUnshared", new Class<?>[] { Object.class }); - return Boolean.FALSE; - } catch (NoSuchMethodException ex) { - } - try { - cl.getDeclaredMethod("putFields", (Class<?>[]) null); - return Boolean.FALSE; - } catch (NoSuchMethodException ex) { - } - } - return Boolean.TRUE; - } + for (Class<?> cl = subcl; + cl != ObjectOutputStream.class; + cl = cl.getSuperclass()) + { + try { + cl.getDeclaredMethod( + "writeUnshared", new Class<?>[] { Object.class }); + return Boolean.FALSE; + } catch (NoSuchMethodException ex) { } - ); + try { + cl.getDeclaredMethod("putFields", (Class<?>[]) null); + return Boolean.FALSE; + } catch (NoSuchMethodException ex) { + } + } + return Boolean.TRUE; } /** diff --git a/src/java.base/share/classes/java/io/ObjectStreamClass.java b/src/java.base/share/classes/java/io/ObjectStreamClass.java index 73bb162e843..4fb9847a4e8 100644 --- a/src/java.base/share/classes/java/io/ObjectStreamClass.java +++ b/src/java.base/share/classes/java/io/ObjectStreamClass.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -32,21 +32,12 @@ import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.RecordComponent; -import java.lang.reflect.UndeclaredThrowableException; import java.lang.reflect.Member; import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.lang.reflect.Proxy; -import java.security.AccessControlContext; -import java.security.AccessController; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; -import java.security.PermissionCollection; -import java.security.Permissions; -import java.security.PrivilegedAction; -import java.security.PrivilegedActionException; -import java.security.PrivilegedExceptionAction; -import java.security.ProtectionDomain; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; @@ -58,13 +49,8 @@ import jdk.internal.event.SerializationMisdeclarationEvent; import jdk.internal.misc.Unsafe; -import jdk.internal.reflect.CallerSensitive; -import jdk.internal.reflect.Reflection; import jdk.internal.reflect.ReflectionFactory; -import jdk.internal.access.SharedSecrets; -import jdk.internal.access.JavaSecurityAccess; import jdk.internal.util.ByteArray; -import sun.reflect.misc.ReflectUtil; /** * Serialization's descriptor for classes. It contains the name and @@ -98,12 +84,6 @@ public final class ObjectStreamClass implements Serializable { private static final ObjectStreamField[] serialPersistentFields = NO_FIELDS; - /** reflection factory for obtaining serialization constructors */ - @SuppressWarnings("removal") - private static final ReflectionFactory reflFactory = - AccessController.doPrivileged( - new ReflectionFactory.GetReflectionFactoryAction()); - private static class Caches { /** cache mapping local classes -> descriptors */ static final ClassCache<ObjectStreamClass> localDescs = @@ -206,8 +186,6 @@ InvalidClassException newInvalidClassException() { /** session-cache of record deserialization constructor * (in de-serialized OSC only), or null */ private MethodHandle deserializationCtr; - /** protection domains that need to be checked when calling the constructor */ - private ProtectionDomain[] domains; /** class-defined writeObject method, or null if none */ private Method writeObjectMethod; @@ -280,20 +258,13 @@ public String getName() { * * @return the SUID of the class described by this descriptor */ - @SuppressWarnings("removal") public long getSerialVersionUID() { // REMIND: synchronize instead of relying on volatile? if (suid == null) { if (isRecord) return 0L; - suid = AccessController.doPrivileged( - new PrivilegedAction<Long>() { - public Long run() { - return computeDefaultSUID(cl); - } - } - ); + suid = computeDefaultSUID(cl); } return suid.longValue(); } @@ -304,19 +275,11 @@ public Long run() { * * @return the {@code Class} instance that this descriptor represents */ - @SuppressWarnings("removal") - @CallerSensitive public Class<?> forClass() { if (cl == null) { return null; } requireInitialized(); - if (System.getSecurityManager() != null) { - Class<?> caller = Reflection.getCallerClass(); - if (ReflectUtil.needsPackageAccessCheck(caller.getClassLoader(), cl.getClassLoader())) { - ReflectUtil.checkPackageAccess(cl); - } - } return cl; } @@ -369,7 +332,6 @@ static ObjectStreamClass lookup(Class<?> cl, boolean all) { /** * Creates local class descriptor representing given class. */ - @SuppressWarnings("removal") private ObjectStreamClass(final Class<?> cl) { this.cl = cl; name = cl.getName(); @@ -384,53 +346,44 @@ private ObjectStreamClass(final Class<?> cl) { localDesc = this; if (serializable) { - AccessController.doPrivileged(new PrivilegedAction<>() { - public Void run() { - if (isEnum) { - suid = 0L; - fields = NO_FIELDS; - return null; - } - if (cl.isArray()) { - fields = NO_FIELDS; - return null; - } - - suid = getDeclaredSUID(cl); - try { - fields = getSerialFields(cl); - computeFieldOffsets(); - } catch (InvalidClassException e) { - serializeEx = deserializeEx = + if (isEnum) { + suid = 0L; + fields = NO_FIELDS; + } else if (cl.isArray()) { + fields = NO_FIELDS; + } else { + suid = getDeclaredSUID(cl); + try { + fields = getSerialFields(cl); + computeFieldOffsets(); + } catch (InvalidClassException e) { + serializeEx = deserializeEx = new ExceptionInfo(e.classname, e.getMessage()); - fields = NO_FIELDS; - } + fields = NO_FIELDS; + } - if (isRecord) { - canonicalCtr = canonicalRecordCtr(cl); - deserializationCtrs = new DeserializationConstructorsCache(); - } else if (externalizable) { - cons = getExternalizableConstructor(cl); - } else { - cons = getSerializableConstructor(cl); - writeObjectMethod = getPrivateMethod(cl, "writeObject", - new Class<?>[] { ObjectOutputStream.class }, + if (isRecord) { + canonicalCtr = canonicalRecordCtr(cl); + deserializationCtrs = new DeserializationConstructorsCache(); + } else if (externalizable) { + cons = getExternalizableConstructor(cl); + } else { + cons = getSerializableConstructor(cl); + writeObjectMethod = getPrivateMethod(cl, "writeObject", + new Class<?>[]{ObjectOutputStream.class}, Void.TYPE); - readObjectMethod = getPrivateMethod(cl, "readObject", - new Class<?>[] { ObjectInputStream.class }, + readObjectMethod = getPrivateMethod(cl, "readObject", + new Class<?>[]{ObjectInputStream.class}, Void.TYPE); - readObjectNoDataMethod = getPrivateMethod( + readObjectNoDataMethod = getPrivateMethod( cl, "readObjectNoData", null, Void.TYPE); - hasWriteObjectData = (writeObjectMethod != null); - } - domains = getProtectionDomains(cons, cl); - writeReplaceMethod = getInheritableMethod( + hasWriteObjectData = (writeObjectMethod != null); + } + writeReplaceMethod = getInheritableMethod( cl, "writeReplace", null, Object.class); - readResolveMethod = getInheritableMethod( + readResolveMethod = getInheritableMethod( cl, "readResolve", null, Object.class); - return null; - } - }); + } } else { suid = 0L; fields = NO_FIELDS; @@ -474,66 +427,6 @@ public Void run() { ObjectStreamClass() { } - /** - * Creates a PermissionDomain that grants no permission. - */ - private ProtectionDomain noPermissionsDomain() { - PermissionCollection perms = new Permissions(); - perms.setReadOnly(); - return new ProtectionDomain(null, perms); - } - - /** - * Aggregate the ProtectionDomains of all the classes that separate - * a concrete class {@code cl} from its ancestor's class declaring - * a constructor {@code cons}. - * - * If {@code cl} is defined by the boot loader, or the constructor - * {@code cons} is declared by {@code cl}, or if there is no security - * manager, then this method does nothing and {@code null} is returned. - * - * @param cons A constructor declared by {@code cl} or one of its - * ancestors. - * @param cl A concrete class, which is either the class declaring - * the constructor {@code cons}, or a serializable subclass - * of that class. - * @return An array of ProtectionDomain representing the set of - * ProtectionDomain that separate the concrete class {@code cl} - * from its ancestor's declaring {@code cons}, or {@code null}. - */ - @SuppressWarnings("removal") - private ProtectionDomain[] getProtectionDomains(Constructor<?> cons, - Class<?> cl) { - ProtectionDomain[] domains = null; - if (cons != null && cl.getClassLoader() != null - && System.getSecurityManager() != null) { - Class<?> cls = cl; - Class<?> fnscl = cons.getDeclaringClass(); - Set<ProtectionDomain> pds = null; - while (cls != fnscl) { - ProtectionDomain pd = cls.getProtectionDomain(); - if (pd != null) { - if (pds == null) pds = new HashSet<>(); - pds.add(pd); - } - cls = cls.getSuperclass(); - if (cls == null) { - // that's not supposed to happen - // make a ProtectionDomain with no permission. - // should we throw instead? - if (pds == null) pds = new HashSet<>(); - else pds.clear(); - pds.add(noPermissionsDomain()); - break; - } - } - if (pds != null) { - domains = pds.toArray(new ProtectionDomain[0]); - } - } - return domains; - } - /** * Initializes class descriptor representing a proxy class. */ @@ -564,7 +457,6 @@ void initProxy(Class<?> cl, writeReplaceMethod = localDesc.writeReplaceMethod; readResolveMethod = localDesc.readResolveMethod; deserializeEx = localDesc.deserializeEx; - domains = localDesc.domains; cons = localDesc.cons; } fieldRefl = getReflector(fields, localDesc); @@ -656,7 +548,6 @@ void initNonProxy(ObjectStreamClass model, if (deserializeEx == null) { deserializeEx = localDesc.deserializeEx; } - domains = localDesc.domains; assert cl.isRecord() ? localDesc.cons == null : true; cons = localDesc.cons; } @@ -1013,7 +904,6 @@ boolean hasReadResolveMethod() { * class is non-serializable or if the appropriate no-arg constructor is * inaccessible/unavailable. */ - @SuppressWarnings("removal") Object newInstance() throws InstantiationException, InvocationTargetException, UnsupportedOperationException @@ -1021,35 +911,7 @@ Object newInstance() requireInitialized(); if (cons != null) { try { - if (domains == null || domains.length == 0) { - return cons.newInstance(); - } else { - JavaSecurityAccess jsa = SharedSecrets.getJavaSecurityAccess(); - PrivilegedAction<?> pea = () -> { - try { - return cons.newInstance(); - } catch (InstantiationException - | InvocationTargetException - | IllegalAccessException x) { - throw new UndeclaredThrowableException(x); - } - }; // Can't use PrivilegedExceptionAction with jsa - try { - return jsa.doIntersectionPrivilege(pea, - AccessController.getContext(), - new AccessControlContext(domains)); - } catch (UndeclaredThrowableException x) { - Throwable cause = x.getCause(); - if (cause instanceof InstantiationException ie) - throw ie; - if (cause instanceof InvocationTargetException ite) - throw ite; - if (cause instanceof IllegalAccessException iae) - throw iae; - // not supposed to happen - throw x; - } - } + return cons.newInstance(); } catch (IllegalAccessException ex) { // should not occur, as access checks have been suppressed throw new InternalError(ex); @@ -1454,7 +1316,7 @@ private static Constructor<?> getExternalizableConstructor(Class<?> cl) { * returned constructor (if any). */ private static Constructor<?> getSerializableConstructor(Class<?> cl) { - return reflFactory.newConstructorForSerialization(cl); + return ReflectionFactory.getReflectionFactory().newConstructorForSerialization(cl); } /** @@ -1462,22 +1324,18 @@ private static Constructor<?> getSerializableConstructor(Class<?> cl) { * the not found ( which should never happen for correctly generated record * classes ). */ - @SuppressWarnings("removal") private static MethodHandle canonicalRecordCtr(Class<?> cls) { assert cls.isRecord() : "Expected record, got: " + cls; - PrivilegedAction<MethodHandle> pa = () -> { - Class<?>[] paramTypes = Arrays.stream(cls.getRecordComponents()) - .map(RecordComponent::getType) - .toArray(Class<?>[]::new); - try { - Constructor<?> ctr = cls.getDeclaredConstructor(paramTypes); - ctr.setAccessible(true); - return MethodHandles.lookup().unreflectConstructor(ctr); - } catch (IllegalAccessException | NoSuchMethodException e) { - return null; - } - }; - return AccessController.doPrivileged(pa); + Class<?>[] paramTypes = Arrays.stream(cls.getRecordComponents()) + .map(RecordComponent::getType) + .toArray(Class<?>[]::new); + try { + Constructor<?> ctr = cls.getDeclaredConstructor(paramTypes); + ctr.setAccessible(true); + return MethodHandles.lookup().unreflectConstructor(ctr); + } catch (IllegalAccessException | NoSuchMethodException e) { + return null; + } } /** @@ -2358,7 +2216,6 @@ static final class RecordSupport { * and return * {@code Object} */ - @SuppressWarnings("removal") static MethodHandle deserializationCtr(ObjectStreamClass desc) { // check the cached value 1st MethodHandle mh = desc.deserializationCtr; @@ -2367,14 +2224,7 @@ static MethodHandle deserializationCtr(ObjectStreamClass desc) { if (mh != null) return desc.deserializationCtr = mh; // retrieve record components - RecordComponent[] recordComponents; - try { - Class<?> cls = desc.forClass(); - PrivilegedExceptionAction<RecordComponent[]> pa = cls::getRecordComponents; - recordComponents = AccessController.doPrivileged(pa); - } catch (PrivilegedActionException e) { - throw new InternalError(e.getCause()); - } + RecordComponent[] recordComponents = desc.forClass().getRecordComponents(); // retrieve the canonical constructor // (T1, T2, ..., Tn):TR diff --git a/src/java.base/share/classes/java/io/ObjectStreamField.java b/src/java.base/share/classes/java/io/ObjectStreamField.java index 75c955440c1..465c29c101c 100644 --- a/src/java.base/share/classes/java/io/ObjectStreamField.java +++ b/src/java.base/share/classes/java/io/ObjectStreamField.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,9 +26,6 @@ package java.io; import java.lang.reflect.Field; -import jdk.internal.reflect.CallerSensitive; -import jdk.internal.reflect.Reflection; -import sun.reflect.misc.ReflectUtil; /** * A description of a Serializable field from a Serializable class. An array @@ -161,15 +158,7 @@ public String getName() { * @return a {@code Class} object representing the type of the * serializable field */ - @SuppressWarnings("removal") - @CallerSensitive public Class<?> getType() { - if (System.getSecurityManager() != null) { - Class<?> caller = Reflection.getCallerClass(); - if (ReflectUtil.needsPackageAccessCheck(caller.getClassLoader(), type.getClassLoader())) { - ReflectUtil.checkPackageAccess(type); - } - } return type; } diff --git a/src/java.base/share/classes/java/io/SerializationMisdeclarationChecker.java b/src/java.base/share/classes/java/io/SerializationMisdeclarationChecker.java index 5eae83e80f7..5a9a6f02ab4 100644 --- a/src/java.base/share/classes/java/io/SerializationMisdeclarationChecker.java +++ b/src/java.base/share/classes/java/io/SerializationMisdeclarationChecker.java @@ -29,8 +29,6 @@ import java.lang.reflect.Member; import java.lang.reflect.Method; import java.lang.reflect.Proxy; -import java.security.AccessController; -import java.security.PrivilegedAction; import java.util.Arrays; import static jdk.internal.event.SerializationMisdeclarationEvent.*; @@ -75,7 +73,7 @@ static void checkMisdeclarations(Class<?> cl) { } private static void checkSerialVersionUID(Class<?> cl) { - Field f = privilegedDeclaredField(cl, SUID_NAME); + Field f = declaredField(cl, SUID_NAME); if (f == null) { if (isOrdinaryClass(cl)) { commitEvent(cl, SUID_NAME + " should be declared explicitly" + @@ -101,7 +99,7 @@ private static void checkSerialVersionUID(Class<?> cl) { } private static void checkSerialPersistentFields(Class<?> cl) { - Field f = privilegedDeclaredField(cl, SERIAL_PERSISTENT_FIELDS_NAME); + Field f = declaredField(cl, SERIAL_PERSISTENT_FIELDS_NAME); if (f == null) { return; } @@ -142,7 +140,7 @@ private static void checkSerialPersistentFields(Class<?> cl) { private static void checkPrivateMethod(Class<?> cl, String name, Class<?>[] paramTypes, Class<?> retType) { - for (Method m : privilegedDeclaredMethods(cl)) { + for (Method m : cl.getDeclaredMethods()) { if (m.getName().equals(name)) { checkPrivateMethod(cl, m, paramTypes, retType); } @@ -173,7 +171,7 @@ private static void checkPrivateMethod(Class<?> cl, private static void checkAccessibleMethod(Class<?> cl, String name, Class<?>[] paramTypes, Class<?> retType) { for (Class<?> superCl = cl; superCl != null; superCl = superCl.getSuperclass()) { - for (Method m : privilegedDeclaredMethods(superCl)) { + for (Method m : superCl.getDeclaredMethods()) { if (m.getName().equals(name)) { checkAccessibleMethod(cl, superCl, m, paramTypes, retType); } @@ -236,14 +234,6 @@ private static boolean isStatic(Member m) { return (m.getModifiers() & STATIC) != 0; } - @SuppressWarnings("removal") - private static Field privilegedDeclaredField(Class<?> cl, String name) { - if (System.getSecurityManager() == null) { - return declaredField(cl, name); - } - return AccessController.doPrivileged((PrivilegedAction<Field>) () -> - declaredField(cl, name)); - } private static Field declaredField(Class<?> cl, String name) { try { @@ -253,14 +243,6 @@ private static Field declaredField(Class<?> cl, String name) { return null; } - @SuppressWarnings("removal") - private static Method[] privilegedDeclaredMethods(Class<?> cl) { - if (System.getSecurityManager() == null) { - return cl.getDeclaredMethods(); - } - return AccessController.doPrivileged( - (PrivilegedAction<Method[]>) cl::getDeclaredMethods); - } private static Object objectFromStatic(Field f) { try { diff --git a/test/jdk/jdk/internal/reflect/CallerSensitive/CheckCSMs.java b/test/jdk/jdk/internal/reflect/CallerSensitive/CheckCSMs.java index ee4d2021b87..6b63ce122a3 100644 --- a/test/jdk/jdk/internal/reflect/CallerSensitive/CheckCSMs.java +++ b/test/jdk/jdk/internal/reflect/CallerSensitive/CheckCSMs.java @@ -70,8 +70,7 @@ public class CheckCSMs { // The goal is to remove this list of Non-final instance @CS methods // over time. Do not add any new one to this list. private static final Set<String> KNOWN_NON_FINAL_CSMS = - Set.of("java/io/ObjectStreamField#getType ()Ljava/lang/Class;", - "java/lang/Runtime#load (Ljava/lang/String;)V", + Set.of("java/lang/Runtime#load (Ljava/lang/String;)V", "java/lang/Runtime#loadLibrary (Ljava/lang/String;)V", "javax/sql/rowset/serial/SerialJavaObject#getFields ()[Ljava/lang/reflect/Field;" ); From 162d66adacf71e500c85382a155c7449a4f9ba55 Mon Sep 17 00:00:00 2001 From: Ramkumar Sunderbabu <rsunderbabu@openjdk.org> Date: Mon, 18 Nov 2024 16:17:30 +0000 Subject: [PATCH 059/311] 8318668: java/lang/management/MemoryMXBean/CollectionUsageThreshold.java fails with Xcomp Reviewed-by: kevinw, lmesnik --- .../management/MemoryMXBean/CollectionUsageThreshold.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/jdk/java/lang/management/MemoryMXBean/CollectionUsageThreshold.java b/test/jdk/java/lang/management/MemoryMXBean/CollectionUsageThreshold.java index fd148d37785..33f18a4e533 100644 --- a/test/jdk/java/lang/management/MemoryMXBean/CollectionUsageThreshold.java +++ b/test/jdk/java/lang/management/MemoryMXBean/CollectionUsageThreshold.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -33,7 +33,7 @@ * @library /test/lib * @modules jdk.management * @build CollectionUsageThreshold MemoryUtil RunUtil - * @requires vm.opt.ExplicitGCInvokesConcurrent == "false" | vm.opt.ExplicitGCInvokesConcurrent == "null" + * @requires (vm.opt.ExplicitGCInvokesConcurrent == "false" | vm.opt.ExplicitGCInvokesConcurrent == "null") & vm.compMode != "Xcomp" * @build jdk.test.whitebox.WhiteBox * @run driver jdk.test.lib.helpers.ClassFileInstaller jdk.test.whitebox.WhiteBox * @run main/othervm/timeout=300 -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xbootclasspath/a:. CollectionUsageThreshold From 207832952be3e57faf3db9303d492faa391d507c Mon Sep 17 00:00:00 2001 From: Per Minborg <pminborg@openjdk.org> Date: Mon, 18 Nov 2024 16:20:06 +0000 Subject: [PATCH 060/311] 8344134: Use static property in SystemLookup Reviewed-by: alanb, rriggs --- .../share/classes/jdk/internal/foreign/SystemLookup.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/java.base/share/classes/jdk/internal/foreign/SystemLookup.java b/src/java.base/share/classes/jdk/internal/foreign/SystemLookup.java index 7194813aff7..8adf51ef6fd 100644 --- a/src/java.base/share/classes/jdk/internal/foreign/SystemLookup.java +++ b/src/java.base/share/classes/jdk/internal/foreign/SystemLookup.java @@ -35,6 +35,7 @@ import jdk.internal.loader.NativeLibrary; import jdk.internal.loader.RawNativeLibraries; import jdk.internal.util.OperatingSystem; +import jdk.internal.util.StaticProperty; import static java.lang.foreign.ValueLayout.ADDRESS; @@ -125,7 +126,7 @@ private static SymbolLookup libLookup(Function<RawNativeLibraries, NativeLibrary * Returns the path of the given library name from JDK */ private static Path jdkLibraryPath(String name) { - Path javahome = Path.of(System.getProperty("java.home")); + Path javahome = Path.of(StaticProperty.javaHome()); String lib = OperatingSystem.isWindows() ? "bin" : "lib"; String libname = System.mapLibraryName(name); return javahome.resolve(lib).resolve(libname); From 3e78ff16d3c986784113799c76c71941cbb16836 Mon Sep 17 00:00:00 2001 From: Kevin Driver <kdriver@openjdk.org> Date: Mon, 18 Nov 2024 16:41:57 +0000 Subject: [PATCH 061/311] 8320743: AEAD ciphers throw undocumented exceptions on overflow Reviewed-by: ascarpino --- .../com/sun/crypto/provider/ChaCha20Cipher.java | 10 +++++----- .../com/sun/crypto/provider/GaloisCounterMode.java | 4 ++-- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/java.base/share/classes/com/sun/crypto/provider/ChaCha20Cipher.java b/src/java.base/share/classes/com/sun/crypto/provider/ChaCha20Cipher.java index fc39b4ed634..3f63dee72d6 100644 --- a/src/java.base/share/classes/com/sun/crypto/provider/ChaCha20Cipher.java +++ b/src/java.base/share/classes/com/sun/crypto/provider/ChaCha20Cipher.java @@ -245,7 +245,7 @@ protected AlgorithmParameters engineGetParameters() { params.init((new DerValue( DerValue.tag_OctetString, nonceData).toByteArray())); } catch (NoSuchAlgorithmException | IOException exc) { - throw new RuntimeException(exc); + throw new ProviderException(exc); } } @@ -353,7 +353,7 @@ protected void engineInit(int opmode, Key key, break; default: // Should never happen - throw new RuntimeException("ChaCha20 in unsupported mode"); + throw new ProviderException("ChaCha20 in unsupported mode"); } init(opmode, key, newNonce); } @@ -426,7 +426,7 @@ protected void engineInit(int opmode, Key key, } break; default: - throw new RuntimeException("Invalid mode: " + mode); + throw new ProviderException("Invalid mode: " + mode); } // Continue with initialization @@ -730,7 +730,7 @@ protected byte[] engineDoFinal(byte[] in, int inOfs, int inLen) try { engine.doFinal(in, inOfs, inLen, output, 0); } catch (ShortBufferException | KeyException exc) { - throw new RuntimeException(exc); + throw new ProviderException(exc); } finally { // Reset the cipher's state to post-init values. resetStartState(); @@ -767,7 +767,7 @@ protected int engineDoFinal(byte[] in, int inOfs, int inLen, byte[] out, try { bytesUpdated = engine.doFinal(in, inOfs, inLen, out, outOfs); } catch (KeyException ke) { - throw new RuntimeException(ke); + throw new ProviderException(ke); } finally { // Reset the cipher's state to post-init values. resetStartState(); diff --git a/src/java.base/share/classes/com/sun/crypto/provider/GaloisCounterMode.java b/src/java.base/share/classes/com/sun/crypto/provider/GaloisCounterMode.java index 478593dfac1..4f6495b8916 100644 --- a/src/java.base/share/classes/com/sun/crypto/provider/GaloisCounterMode.java +++ b/src/java.base/share/classes/com/sun/crypto/provider/GaloisCounterMode.java @@ -241,7 +241,7 @@ protected AlgorithmParameters engineGetParameters() { params.init(spec); return params; } catch (NoSuchAlgorithmException | InvalidParameterSpecException e) { - throw new RuntimeException(e); + throw new ProviderException(e); } } @@ -781,7 +781,7 @@ int implGCMCrypt(ByteBuffer src, ByteBuffer dst) { int mergeBlock(byte[] buffer, int bufOfs, int bufLen, byte[] in, int inOfs, int inLen, byte[] block) { if (bufLen > blockSize) { - throw new RuntimeException("mergeBlock called on an ibuffer " + + throw new ProviderException("mergeBlock called on an ibuffer " + "too big: " + bufLen + " bytes"); } From d76b5b888e15b507631068f508e261cab75c841e Mon Sep 17 00:00:00 2001 From: Viktor Klang <vklang@openjdk.org> Date: Mon, 18 Nov 2024 17:31:03 +0000 Subject: [PATCH 062/311] 8344253: Test java/util/Spliterator/SpliteratorTraversingAndSplittingTest.java failed Reviewed-by: alanb --- .../classes/java/util/concurrent/ConcurrentSkipListMap.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListMap.java b/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListMap.java index 2460bf79a83..6a60a2397ce 100644 --- a/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListMap.java +++ b/src/java.base/share/classes/java/util/concurrent/ConcurrentSkipListMap.java @@ -3165,7 +3165,7 @@ public KeySpliterator<K,V> trySplit() { current = n; Index<K,V> r = q.down; row = (s.right != null) ? s : s.down; - est -= est >>> 2; + est >>>= 1; return new KeySpliterator<K,V>(cmp, r, e, sk, est); } } @@ -3255,7 +3255,7 @@ public ValueSpliterator<K,V> trySplit() { current = n; Index<K,V> r = q.down; row = (s.right != null) ? s : s.down; - est -= est >>> 2; + est >>>= 1; return new ValueSpliterator<K,V>(cmp, r, e, sk, est); } } @@ -3341,7 +3341,7 @@ public EntrySpliterator<K,V> trySplit() { current = n; Index<K,V> r = q.down; row = (s.right != null) ? s : s.down; - est -= est >>> 2; + est >>>= 1; return new EntrySpliterator<K,V>(cmp, r, e, sk, est); } } From c4e7dc7ff24809ced7bc3363fc3b462108b992dd Mon Sep 17 00:00:00 2001 From: Aleksey Shipilev <shade@openjdk.org> Date: Mon, 18 Nov 2024 18:08:20 +0000 Subject: [PATCH 063/311] 8344389: 32-bit builds fail at CDS build time after JDK-8331497 Reviewed-by: iklam --- src/hotspot/share/cds/archiveBuilder.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hotspot/share/cds/archiveBuilder.cpp b/src/hotspot/share/cds/archiveBuilder.cpp index da4319955ea..36a17813d32 100644 --- a/src/hotspot/share/cds/archiveBuilder.cpp +++ b/src/hotspot/share/cds/archiveBuilder.cpp @@ -897,7 +897,7 @@ void ArchiveBuilder::make_klasses_shareable() { assert(HeapShared::is_archivable_hidden_klass(ik), "sanity"); } else { // Legacy CDS support for lambda proxies - assert(HeapShared::is_lambda_proxy_klass(ik), "sanity"); + CDS_JAVA_HEAP_ONLY(assert(HeapShared::is_lambda_proxy_klass(ik), "sanity");) } } else if (ik->is_shared_boot_class()) { type = "boot"; From c59adf68d9ac49b41fb778041e3949a8057e8d7f Mon Sep 17 00:00:00 2001 From: Naoto Sato <naoto@openjdk.org> Date: Mon, 18 Nov 2024 18:22:18 +0000 Subject: [PATCH 064/311] 8344330: Remove AccessController.doPrivileged() from jdk.charsets module Reviewed-by: lancea, bpb, rriggs, jlu --- .../share/classes/sun/nio/cs/ext/SJIS_0213.java | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) diff --git a/src/jdk.charsets/share/classes/sun/nio/cs/ext/SJIS_0213.java b/src/jdk.charsets/share/classes/sun/nio/cs/ext/SJIS_0213.java index 1ac70f2d2e3..5853d01bdfc 100644 --- a/src/jdk.charsets/share/classes/sun/nio/cs/ext/SJIS_0213.java +++ b/src/jdk.charsets/share/classes/sun/nio/cs/ext/SJIS_0213.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -31,10 +31,6 @@ import java.nio.charset.CharsetEncoder; import java.nio.charset.CharsetDecoder; import java.nio.charset.CoderResult; -import java.security.AccessController; -import java.security.PrivilegedAction; -import java.util.Arrays; -import sun.nio.cs.CharsetMapping; import sun.nio.cs.*; /* @@ -77,13 +73,8 @@ public CharsetEncoder newEncoder() { } private static class Holder { - @SuppressWarnings("removal") - static final CharsetMapping mapping = AccessController.doPrivileged( - new PrivilegedAction<CharsetMapping>() { - public CharsetMapping run() { - return CharsetMapping.get(SJIS_0213.class.getResourceAsStream("sjis0213.dat")); - } - }); + static final CharsetMapping mapping = + CharsetMapping.get(SJIS_0213.class.getResourceAsStream("sjis0213.dat")); } protected static class Decoder extends CharsetDecoder { From e9e4200a6aaacc11442f0298525e2531bf08240e Mon Sep 17 00:00:00 2001 From: Naman Nigam <namannigam12@gmail.com> Date: Mon, 18 Nov 2024 18:30:24 +0000 Subject: [PATCH 065/311] 8343125: Correct the documentation for TreeMap's getFloorEntry and getCeilingEntry Reviewed-by: liach, acobbs --- src/java.base/share/classes/java/util/TreeMap.java | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/src/java.base/share/classes/java/util/TreeMap.java b/src/java.base/share/classes/java/util/TreeMap.java index 0e544573f01..79aec5c1456 100644 --- a/src/java.base/share/classes/java/util/TreeMap.java +++ b/src/java.base/share/classes/java/util/TreeMap.java @@ -420,10 +420,9 @@ else if (cmp > 0) } /** - * Gets the entry corresponding to the specified key; if no such entry - * exists, returns the entry for the least key greater than the specified - * key; if no such entry exists (i.e., the greatest key in the Tree is less - * than the specified key), returns {@code null}. + * Returns the entry for the least key greater than or equal to the specified key; + * if no such entry exists (i.e. the specified key is greater than any key in the tree, + * or the tree is empty), returns {@code null}. */ final Entry<K,V> getCeilingEntry(K key) { Entry<K,V> p = root; @@ -453,10 +452,9 @@ final Entry<K,V> getCeilingEntry(K key) { } /** - * Gets the entry corresponding to the specified key; if no such entry - * exists, returns the entry for the greatest key less than the specified - * key; if no such entry exists (i.e., the least key in the Tree is greater - * than the specified key), returns {@code null}. + * Returns the entry for the greatest key less than or equal to the specified key; + * if no such entry exists (i.e. the specified key is less than any key in the tree, + * or the tree is empty), returns {@code null}. */ final Entry<K,V> getFloorEntry(K key) { Entry<K,V> p = root; From 26494063237ab50b1a86847da1b3ce3c44d55409 Mon Sep 17 00:00:00 2001 From: Aleksey Shipilev <shade@openjdk.org> Date: Mon, 18 Nov 2024 18:38:56 +0000 Subject: [PATCH 066/311] 8344352: 32-bit builds crash after JDK-8305895 Reviewed-by: rkennke, coleenp --- src/hotspot/share/runtime/arguments.cpp | 1 - src/hotspot/share/runtime/threads.cpp | 3 +++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/hotspot/share/runtime/arguments.cpp b/src/hotspot/share/runtime/arguments.cpp index 175a85e33fb..0b16a634489 100644 --- a/src/hotspot/share/runtime/arguments.cpp +++ b/src/hotspot/share/runtime/arguments.cpp @@ -3678,7 +3678,6 @@ jint Arguments::parse(const JavaVMInitArgs* initial_cmd_args) { if (UseCompactObjectHeaders && !UseCompressedClassPointers) { FLAG_SET_DEFAULT(UseCompressedClassPointers, true); } - ObjLayout::initialize(); #endif return JNI_OK; diff --git a/src/hotspot/share/runtime/threads.cpp b/src/hotspot/share/runtime/threads.cpp index f6b7b7956e2..73f2e87f5c7 100644 --- a/src/hotspot/share/runtime/threads.cpp +++ b/src/hotspot/share/runtime/threads.cpp @@ -497,6 +497,9 @@ jint Threads::create_vm(JavaVMInitArgs* args, bool* canTryAgain) { // Timing (must come after argument parsing) TraceTime timer("Create VM", TRACETIME_LOG(Info, startuptime)); + // Initialize object layout after parsing the args + ObjLayout::initialize(); + // Initialize the os module after parsing the args jint os_init_2_result = os::init_2(); if (os_init_2_result != JNI_OK) return os_init_2_result; From 922b12f30c4cfd6b504d66daf37fb30c7fb1bfe7 Mon Sep 17 00:00:00 2001 From: Brian Burkhalter <bpb@openjdk.org> Date: Mon, 18 Nov 2024 19:17:14 +0000 Subject: [PATCH 067/311] 8344078: Remove security manager dependency in java.nio Reviewed-by: alanb, rriggs --- .../sun/nio/ch/DefaultSelectorProvider.java | 14 +-- .../sun/nio/ch/DefaultSelectorProvider.java | 12 +- .../sun/nio/fs/LinuxDosFileAttributeView.java | 6 +- .../sun/nio/ch/DefaultSelectorProvider.java | 10 +- .../sun/nio/fs/BsdFileAttributeViews.java | 3 - .../classes/sun/nio/fs/BsdFileSystem.java | 4 +- .../spi/AsynchronousChannelProvider.java | 37 ++----- .../nio/channels/spi/SelectorProvider.java | 33 ++---- .../classes/java/nio/charset/Charset.java | 103 ++++++------------ .../classes/java/nio/file/CopyMoveHelper.java | 18 +-- .../classes/java/nio/file/FileSystems.java | 14 +-- .../java/nio/file/FileTreeIterator.java | 4 +- .../classes/java/nio/file/FileTreeWalker.java | 29 +---- .../share/classes/java/nio/file/Files.java | 60 +++------- .../classes/java/nio/file/TempFileHelper.java | 11 +- .../java/nio/file/spi/FileSystemProvider.java | 11 +- .../nio/ch/AsynchronousChannelGroupImpl.java | 57 ++-------- .../AsynchronousServerSocketChannelImpl.java | 10 +- .../nio/ch/AsynchronousSocketChannelImpl.java | 12 +- .../classes/sun/nio/ch/CompletedFuture.java | 6 +- .../share/classes/sun/nio/ch/Invoker.java | 22 +--- .../share/classes/sun/nio/ch/Net.java | 58 ++-------- .../classes/sun/nio/ch/PendingFuture.java | 2 +- .../share/classes/sun/nio/ch/Reflect.java | 19 +--- .../sun/nio/ch/ServerSocketAdaptor.java | 15 +-- .../sun/nio/ch/ServerSocketChannelImpl.java | 26 +---- .../ch/SimpleAsynchronousFileChannelImpl.java | 2 - .../classes/sun/nio/ch/SocketAdaptor.java | 19 +--- .../classes/sun/nio/ch/SocketChannelImpl.java | 26 +---- .../share/classes/sun/nio/ch/ThreadPool.java | 34 ++---- .../classes/sun/nio/ch/UnixDomainSockets.java | 26 +---- .../share/classes/sun/nio/ch/Util.java | 81 ++++++-------- .../classes/sun/nio/cs/CharsetMapping.java | 10 +- .../classes/sun/nio/fs/AbstractPoller.java | 26 ++--- .../AbstractUserDefinedFileAttributeView.java | 20 +--- .../sun/nio/fs/PollingWatchService.java | 43 +------- .../classes/sun/nio/ch/InheritedChannel.java | 17 --- ...ixAsynchronousServerSocketChannelImpl.java | 58 ++-------- .../ch/UnixAsynchronousSocketChannelImpl.java | 11 +- .../sun/nio/ch/UnixDomainSocketsUtil.java | 18 +-- .../sun/nio/fs/MimeTypesFileTypeDetector.java | 24 ++-- .../sun/nio/fs/UnixChannelFactory.java | 24 +--- .../sun/nio/fs/UnixFileAttributeViews.java | 28 +---- .../classes/sun/nio/fs/UnixFileStore.java | 12 +- .../classes/sun/nio/fs/UnixFileSystem.java | 66 +---------- .../sun/nio/fs/UnixFileSystemProvider.java | 58 ---------- .../unix/classes/sun/nio/fs/UnixPath.java | 32 +----- .../sun/nio/fs/UnixSecureDirectoryStream.java | 79 +------------- .../unix/classes/sun/nio/fs/UnixUriUtils.java | 5 +- .../fs/UnixUserDefinedFileAttributeView.java | 22 +--- .../sun/nio/fs/UnixUserPrincipals.java | 7 +- .../sun/nio/ch/DefaultSelectorProvider.java | 12 +- .../windows/classes/sun/nio/ch/PipeImpl.java | 28 ++--- .../sun/nio/ch/UnixDomainSocketsUtil.java | 26 ++--- ...wsAsynchronousServerSocketChannelImpl.java | 35 +----- .../WindowsAsynchronousSocketChannelImpl.java | 31 +----- .../nio/fs/WindowsAclFileAttributeView.java | 27 +---- .../sun/nio/fs/WindowsChannelFactory.java | 25 +---- .../sun/nio/fs/WindowsFileAttributeViews.java | 10 +- .../classes/sun/nio/fs/WindowsFileCopy.java | 21 ---- .../classes/sun/nio/fs/WindowsFileSystem.java | 34 +----- .../sun/nio/fs/WindowsFileSystemProvider.java | 53 +-------- .../sun/nio/fs/WindowsLinkSupport.java | 10 +- .../classes/sun/nio/fs/WindowsPath.java | 64 +---------- .../classes/sun/nio/fs/WindowsUriSupport.java | 5 +- .../WindowsUserDefinedFileAttributeView.java | 32 ++---- .../sun/nio/fs/WindowsUserPrincipals.java | 8 +- 67 files changed, 285 insertions(+), 1480 deletions(-) diff --git a/src/java.base/aix/classes/sun/nio/ch/DefaultSelectorProvider.java b/src/java.base/aix/classes/sun/nio/ch/DefaultSelectorProvider.java index 86d3ade19de..9438b67039b 100644 --- a/src/java.base/aix/classes/sun/nio/ch/DefaultSelectorProvider.java +++ b/src/java.base/aix/classes/sun/nio/ch/DefaultSelectorProvider.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,20 +25,12 @@ package sun.nio.ch; -import java.security.AccessController; -import java.security.PrivilegedAction; - /** * Creates this platform's default SelectorProvider */ -@SuppressWarnings("removal") public class DefaultSelectorProvider { - private static final SelectorProviderImpl INSTANCE; - static { - PrivilegedAction<SelectorProviderImpl> pa = PollSelectorProvider::new; - INSTANCE = AccessController.doPrivileged(pa); - } + private static final SelectorProviderImpl INSTANCE = new PollSelectorProvider(); /** * Prevent instantiation. @@ -51,4 +43,4 @@ private DefaultSelectorProvider() { } public static SelectorProviderImpl get() { return INSTANCE; } -} \ No newline at end of file +} diff --git a/src/java.base/linux/classes/sun/nio/ch/DefaultSelectorProvider.java b/src/java.base/linux/classes/sun/nio/ch/DefaultSelectorProvider.java index fa925f54546..36e517f093a 100644 --- a/src/java.base/linux/classes/sun/nio/ch/DefaultSelectorProvider.java +++ b/src/java.base/linux/classes/sun/nio/ch/DefaultSelectorProvider.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,20 +25,12 @@ package sun.nio.ch; -import java.security.AccessController; -import java.security.PrivilegedAction; - /** * Creates this platform's default SelectorProvider */ -@SuppressWarnings("removal") public class DefaultSelectorProvider { - private static final SelectorProviderImpl INSTANCE; - static { - PrivilegedAction<SelectorProviderImpl> pa = EPollSelectorProvider::new; - INSTANCE = AccessController.doPrivileged(pa); - } + private static final SelectorProviderImpl INSTANCE = new EPollSelectorProvider(); /** * Prevent instantiation. diff --git a/src/java.base/linux/classes/sun/nio/fs/LinuxDosFileAttributeView.java b/src/java.base/linux/classes/sun/nio/fs/LinuxDosFileAttributeView.java index 49b24a42b89..4cbd51ab49d 100644 --- a/src/java.base/linux/classes/sun/nio/fs/LinuxDosFileAttributeView.java +++ b/src/java.base/linux/classes/sun/nio/fs/LinuxDosFileAttributeView.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -115,8 +115,6 @@ public Map<String,Object> readAttributes(String[] attributes) @Override public DosFileAttributes readAttributes() throws IOException { - file.checkRead(); - int fd = -1; try { fd = file.openForAttributeAccess(followLinks); @@ -249,8 +247,6 @@ private int getDosAttribute(int fd) throws UnixException { * Updates the value of the user.DOSATTRIB extended attribute */ private void updateDosAttribute(int flag, boolean enable) throws IOException { - file.checkWrite(); - int fd = -1; try { fd = file.openForAttributeAccess(followLinks); diff --git a/src/java.base/macosx/classes/sun/nio/ch/DefaultSelectorProvider.java b/src/java.base/macosx/classes/sun/nio/ch/DefaultSelectorProvider.java index a010b1706d4..202d070c493 100644 --- a/src/java.base/macosx/classes/sun/nio/ch/DefaultSelectorProvider.java +++ b/src/java.base/macosx/classes/sun/nio/ch/DefaultSelectorProvider.java @@ -25,20 +25,12 @@ package sun.nio.ch; -import java.security.AccessController; -import java.security.PrivilegedAction; - /** * Creates this platform's default SelectorProvider */ -@SuppressWarnings("removal") public class DefaultSelectorProvider { - private static final SelectorProviderImpl INSTANCE; - static { - PrivilegedAction<SelectorProviderImpl> pa = KQueueSelectorProvider::new; - INSTANCE = AccessController.doPrivileged(pa); - } + private static final SelectorProviderImpl INSTANCE = new KQueueSelectorProvider(); /** * Prevent instantiation. diff --git a/src/java.base/macosx/classes/sun/nio/fs/BsdFileAttributeViews.java b/src/java.base/macosx/classes/sun/nio/fs/BsdFileAttributeViews.java index cac81af84dc..d39131a6de2 100644 --- a/src/java.base/macosx/classes/sun/nio/fs/BsdFileAttributeViews.java +++ b/src/java.base/macosx/classes/sun/nio/fs/BsdFileAttributeViews.java @@ -50,9 +50,6 @@ private static void setTimes(UnixPath path, FileTime lastModifiedTime, return; } - // permission check - path.checkWrite(); - // use a file descriptor if possible to avoid a race due to accessing // a path more than once as the file at that path could change. // if path is a symlink, then the open should fail with ELOOP and diff --git a/src/java.base/macosx/classes/sun/nio/fs/BsdFileSystem.java b/src/java.base/macosx/classes/sun/nio/fs/BsdFileSystem.java index 3b99a456288..69a5d775b0b 100644 --- a/src/java.base/macosx/classes/sun/nio/fs/BsdFileSystem.java +++ b/src/java.base/macosx/classes/sun/nio/fs/BsdFileSystem.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -28,13 +28,11 @@ import java.io.IOException; import java.nio.file.FileStore; import java.nio.file.WatchService; -import java.security.AccessController; import java.util.ArrayList; import java.util.Collections; import java.util.HashSet; import java.util.Set; import sun.nio.ch.IOStatus; -import sun.security.action.GetPropertyAction; import static sun.nio.fs.UnixConstants.*; import static sun.nio.fs.UnixNativeDispatcher.chown; diff --git a/src/java.base/share/classes/java/nio/channels/spi/AsynchronousChannelProvider.java b/src/java.base/share/classes/java/nio/channels/spi/AsynchronousChannelProvider.java index e35e0ee687f..1d9e32c31d3 100644 --- a/src/java.base/share/classes/java/nio/channels/spi/AsynchronousChannelProvider.java +++ b/src/java.base/share/classes/java/nio/channels/spi/AsynchronousChannelProvider.java @@ -31,8 +31,6 @@ import java.util.ServiceLoader; import java.util.ServiceConfigurationError; import java.util.concurrent.*; -import java.security.AccessController; -import java.security.PrivilegedAction; /** * Service-provider class for asynchronous channels. @@ -62,20 +60,15 @@ protected AsynchronousChannelProvider() { private static class ProviderHolder { static final AsynchronousChannelProvider provider = load(); - @SuppressWarnings("removal") private static AsynchronousChannelProvider load() { - return AccessController - .doPrivileged(new PrivilegedAction<>() { - public AsynchronousChannelProvider run() { - AsynchronousChannelProvider p; - p = loadProviderFromProperty(); - if (p != null) - return p; - p = loadProviderAsService(); - if (p != null) - return p; - return sun.nio.ch.DefaultAsynchronousChannelProvider.create(); - }}); + AsynchronousChannelProvider p; + p = loadProviderFromProperty(); + if (p != null) + return p; + p = loadProviderAsService(); + if (p != null) + return p; + return sun.nio.ch.DefaultAsynchronousChannelProvider.create(); } private static AsynchronousChannelProvider loadProviderFromProperty() { @@ -87,7 +80,7 @@ private static AsynchronousChannelProvider loadProviderFromProperty() { Object tmp = Class.forName(cn, true, ClassLoader.getSystemClassLoader()).newInstance(); return (AsynchronousChannelProvider)tmp; - } catch (ClassNotFoundException | SecurityException | + } catch (ClassNotFoundException | InstantiationException | IllegalAccessException x) { throw new ServiceConfigurationError(null, x); } @@ -98,17 +91,7 @@ private static AsynchronousChannelProvider loadProviderAsService() { ServiceLoader.load(AsynchronousChannelProvider.class, ClassLoader.getSystemClassLoader()); Iterator<AsynchronousChannelProvider> i = sl.iterator(); - for (;;) { - try { - return (i.hasNext()) ? i.next() : null; - } catch (ServiceConfigurationError sce) { - if (sce.getCause() instanceof SecurityException) { - // Ignore the security exception, try the next provider - continue; - } - throw sce; - } - } + return sl.findFirst().orElse(null); } } diff --git a/src/java.base/share/classes/java/nio/channels/spi/SelectorProvider.java b/src/java.base/share/classes/java/nio/channels/spi/SelectorProvider.java index bfb23d048f6..f07f45620d8 100644 --- a/src/java.base/share/classes/java/nio/channels/spi/SelectorProvider.java +++ b/src/java.base/share/classes/java/nio/channels/spi/SelectorProvider.java @@ -33,8 +33,6 @@ import java.nio.channels.Pipe; import java.nio.channels.ServerSocketChannel; import java.nio.channels.SocketChannel; -import java.security.AccessController; -import java.security.PrivilegedAction; import java.util.Iterator; import java.util.Objects; import java.util.ServiceLoader; @@ -81,17 +79,13 @@ protected SelectorProvider() { private static class Holder { static final SelectorProvider INSTANCE = provider(); - @SuppressWarnings("removal") static SelectorProvider provider() { - PrivilegedAction<SelectorProvider> pa = () -> { - SelectorProvider sp; - if ((sp = loadProviderFromProperty()) != null) - return sp; - if ((sp = loadProviderAsService()) != null) - return sp; - return sun.nio.ch.DefaultSelectorProvider.get(); - }; - return AccessController.doPrivileged(pa); + SelectorProvider sp; + if ((sp = loadProviderFromProperty()) != null) + return sp; + if ((sp = loadProviderAsService()) != null) + return sp; + return sun.nio.ch.DefaultSelectorProvider.get(); } private static SelectorProvider loadProviderFromProperty() { @@ -105,8 +99,7 @@ private static SelectorProvider loadProviderFromProperty() { NoSuchMethodException | IllegalAccessException | InvocationTargetException | - InstantiationException | - SecurityException x) { + InstantiationException x) { throw new ServiceConfigurationError(null, x); } } @@ -116,17 +109,7 @@ private static SelectorProvider loadProviderAsService() { ServiceLoader.load(SelectorProvider.class, ClassLoader.getSystemClassLoader()); Iterator<SelectorProvider> i = sl.iterator(); - for (;;) { - try { - return i.hasNext() ? i.next() : null; - } catch (ServiceConfigurationError sce) { - if (sce.getCause() instanceof SecurityException) { - // Ignore the security exception, try the next provider - continue; - } - throw sce; - } - } + return sl.findFirst().orElse(null); } } diff --git a/src/java.base/share/classes/java/nio/charset/Charset.java b/src/java.base/share/classes/java/nio/charset/Charset.java index 35c7e5b1cd5..4766c907d55 100644 --- a/src/java.base/share/classes/java/nio/charset/Charset.java +++ b/src/java.base/share/classes/java/nio/charset/Charset.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -34,15 +34,12 @@ import java.nio.ByteBuffer; import java.nio.CharBuffer; import java.nio.charset.spi.CharsetProvider; -import java.security.AccessController; -import java.security.PrivilegedAction; import java.util.Arrays; import java.util.Collections; import java.util.Iterator; import java.util.Locale; import java.util.Map; import java.util.NoSuchElementException; -import java.util.ServiceConfigurationError; import java.util.ServiceLoader; import java.util.Set; import java.util.SortedMap; @@ -346,9 +343,7 @@ private static void cache(String charsetName, Charset cs) { cache1 = new Object[] { charsetName, cs }; } - // Creates an iterator that walks over the available providers, ignoring - // those whose lookup or instantiation causes a security exception to be - // thrown. Should be invoked with full privileges. + // Creates an iterator that walks over the available providers // private static Iterator<CharsetProvider> providers() { return new Iterator<>() { @@ -360,17 +355,9 @@ private static Iterator<CharsetProvider> providers() { private boolean getNext() { while (next == null) { - try { - if (!i.hasNext()) - return false; - next = i.next(); - } catch (ServiceConfigurationError sce) { - if (sce.getCause() instanceof SecurityException) { - // Ignore security exceptions - continue; - } - throw sce; - } + if (!i.hasNext()) + return false; + next = i.next(); } return true; } @@ -406,7 +393,6 @@ private static void endLookup(Object key) { ThreadTrackHolder.TRACKER.end(key); } - @SuppressWarnings("removal") private static Charset lookupViaProviders(final String charsetName) { // The runtime startup sequence looks up standard charsets as a @@ -426,20 +412,13 @@ private static Charset lookupViaProviders(final String charsetName) { return null; } try { - return AccessController.doPrivileged( - new PrivilegedAction<>() { - public Charset run() { - for (Iterator<CharsetProvider> i = providers(); - i.hasNext();) { - CharsetProvider cp = i.next(); - Charset cs = cp.charsetForName(charsetName); - if (cs != null) - return cs; - } - return null; - } - }); - + for (Iterator<CharsetProvider> i = providers(); i.hasNext();) { + CharsetProvider cp = i.next(); + Charset cs = cp.charsetForName(charsetName); + if (cs != null) + return cs; + } + return null; } finally { endLookup(key); } @@ -449,22 +428,18 @@ public Charset run() { private static class ExtendedProviderHolder { static final CharsetProvider[] extendedProviders = extendedProviders(); // returns ExtendedProvider, if installed - @SuppressWarnings("removal") private static CharsetProvider[] extendedProviders() { - return AccessController.doPrivileged(new PrivilegedAction<>() { - public CharsetProvider[] run() { - CharsetProvider[] cps = new CharsetProvider[1]; - int n = 0; - ServiceLoader<CharsetProvider> sl = - ServiceLoader.loadInstalled(CharsetProvider.class); - for (CharsetProvider cp : sl) { - if (n + 1 > cps.length) { - cps = Arrays.copyOf(cps, cps.length << 1); - } - cps[n++] = cp; - } - return n == cps.length ? cps : Arrays.copyOf(cps, n); - }}); + CharsetProvider[] cps = new CharsetProvider[1]; + int n = 0; + ServiceLoader<CharsetProvider> sl = + ServiceLoader.loadInstalled(CharsetProvider.class); + for (CharsetProvider cp : sl) { + if (n + 1 > cps.length) { + cps = Arrays.copyOf(cps, cps.length << 1); + } + cps[n++] = cp; + } + return n == cps.length ? cps : Arrays.copyOf(cps, n); } } @@ -628,26 +603,20 @@ private static void put(Iterator<Charset> i, Map<String,Charset> m) { * @return An immutable, case-insensitive map from canonical charset names * to charset objects */ - @SuppressWarnings("removal") public static SortedMap<String,Charset> availableCharsets() { - return AccessController.doPrivileged( - new PrivilegedAction<>() { - public SortedMap<String,Charset> run() { - TreeMap<String,Charset> m = - new TreeMap<>( - String.CASE_INSENSITIVE_ORDER); - put(standardProvider.charsets(), m); - CharsetProvider[] ecps = ExtendedProviderHolder.extendedProviders; - for (CharsetProvider ecp :ecps) { - put(ecp.charsets(), m); - } - for (Iterator<CharsetProvider> i = providers(); i.hasNext();) { - CharsetProvider cp = i.next(); - put(cp.charsets(), m); - } - return Collections.unmodifiableSortedMap(m); - } - }); + TreeMap<String,Charset> m = + new TreeMap<>( + String.CASE_INSENSITIVE_ORDER); + put(standardProvider.charsets(), m); + CharsetProvider[] ecps = ExtendedProviderHolder.extendedProviders; + for (CharsetProvider ecp :ecps) { + put(ecp.charsets(), m); + } + for (Iterator<CharsetProvider> i = providers(); i.hasNext();) { + CharsetProvider cp = i.next(); + put(cp.charsets(), m); + } + return Collections.unmodifiableSortedMap(m); } private @Stable static Charset defaultCharset; diff --git a/src/java.base/share/classes/java/nio/file/CopyMoveHelper.java b/src/java.base/share/classes/java/nio/file/CopyMoveHelper.java index 24a89456661..357e200e930 100644 --- a/src/java.base/share/classes/java/nio/file/CopyMoveHelper.java +++ b/src/java.base/share/classes/java/nio/file/CopyMoveHelper.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -116,13 +116,9 @@ static void copyToForeignTarget(Path source, Path target, // attributes of source file BasicFileAttributes sourceAttrs = null; if (sourcePosixView != null) { - try { - sourceAttrs = Files.readAttributes(source, - PosixFileAttributes.class, - linkOptions); - } catch (SecurityException ignored) { - // okay to continue if RuntimePermission("accessUserInformation") not granted - } + sourceAttrs = Files.readAttributes(source, + PosixFileAttributes.class, + linkOptions); } if (sourceAttrs == null) sourceAttrs = Files.readAttributes(source, @@ -173,11 +169,7 @@ else if (Files.exists(target)) if (sourceAttrs instanceof PosixFileAttributes sourcePosixAttrs && targetView instanceof PosixFileAttributeView targetPosixView) { - try { - targetPosixView.setPermissions(sourcePosixAttrs.permissions()); - } catch (SecurityException ignored) { - // okay to continue if RuntimePermission("accessUserInformation") not granted - } + targetPosixView.setPermissions(sourcePosixAttrs.permissions()); } } catch (Throwable x) { // rollback diff --git a/src/java.base/share/classes/java/nio/file/FileSystems.java b/src/java.base/share/classes/java/nio/file/FileSystems.java index ddf1033c7ee..ab0538a1d41 100644 --- a/src/java.base/share/classes/java/nio/file/FileSystems.java +++ b/src/java.base/share/classes/java/nio/file/FileSystems.java @@ -25,12 +25,10 @@ package java.nio.file; -import java.nio.file.spi.FileSystemProvider; -import java.net.URI; import java.io.IOException; -import java.security.AccessController; -import java.security.PrivilegedAction; import java.lang.reflect.Constructor; +import java.net.URI; +import java.nio.file.spi.FileSystemProvider; import java.util.Collections; import java.util.Map; import java.util.ServiceConfigurationError; @@ -96,13 +94,7 @@ private static class DefaultFileSystemHolder { // returns default file system private static FileSystem defaultFileSystem() { // load default provider - @SuppressWarnings("removal") - FileSystemProvider provider = AccessController - .doPrivileged(new PrivilegedAction<>() { - public FileSystemProvider run() { - return getDefaultProvider(); - } - }); + FileSystemProvider provider = getDefaultProvider(); // return file system return provider.getFileSystem(URI.create("file:///")); diff --git a/src/java.base/share/classes/java/nio/file/FileTreeIterator.java b/src/java.base/share/classes/java/nio/file/FileTreeIterator.java index 2901d1d9884..0f8c646dc5e 100644 --- a/src/java.base/share/classes/java/nio/file/FileTreeIterator.java +++ b/src/java.base/share/classes/java/nio/file/FileTreeIterator.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2023, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -58,8 +58,6 @@ class FileTreeIterator implements Iterator<Event>, Closeable { * if {@code maxDepth} is negative * @throws IOException * if an I/O errors occurs opening the starting file - * @throws SecurityException - * if the security manager denies access to the starting file * @throws NullPointerException * if {@code start} or {@code options} is {@code null} or * the options array contains a {@code null} element diff --git a/src/java.base/share/classes/java/nio/file/FileTreeWalker.java b/src/java.base/share/classes/java/nio/file/FileTreeWalker.java index 02f5c7de773..e5f01ea87d7 100644 --- a/src/java.base/share/classes/java/nio/file/FileTreeWalker.java +++ b/src/java.base/share/classes/java/nio/file/FileTreeWalker.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -198,16 +198,12 @@ IOException ioeException() { * the walk is following sym links is not. The {@code canUseCached} * argument determines whether this method can use cached attributes. */ - @SuppressWarnings("removal") private BasicFileAttributes getAttributes(Path file, boolean canUseCached) throws IOException { // if attributes are cached then use them if possible - if (canUseCached && - (file instanceof BasicFileAttributesHolder) && - (System.getSecurityManager() == null)) - { - BasicFileAttributes cached = ((BasicFileAttributesHolder)file).get(); + if (canUseCached && (file instanceof BasicFileAttributesHolder bfah)) { + BasicFileAttributes cached = bfah.get(); if (cached != null && (!followLinks || !cached.isSymbolicLink())) { return cached; } @@ -250,7 +246,7 @@ private boolean wouldLoop(Path dir, Object key) { // cycle detected return true; } - } catch (IOException | SecurityException x) { + } catch (IOException e) { // ignore } } @@ -262,25 +258,16 @@ private boolean wouldLoop(Path dir, Object key) { * Visits the given file, returning the {@code Event} corresponding to that * visit. * - * The {@code ignoreSecurityException} parameter determines whether - * any SecurityException should be ignored or not. If a SecurityException - * is thrown, and is ignored, then this method returns {@code null} to - * mean that there is no event corresponding to a visit to the file. - * * The {@code canUseCached} parameter determines whether cached attributes * for the file can be used or not. */ - private Event visit(Path entry, boolean ignoreSecurityException, boolean canUseCached) { + private Event visit(Path entry, boolean canUseCached) { // need the file attributes BasicFileAttributes attrs; try { attrs = getAttributes(entry, canUseCached); } catch (IOException ioe) { return new Event(EventType.ENTRY, entry, ioe); - } catch (SecurityException se) { - if (ignoreSecurityException) - return null; - throw se; } // at maximum depth or file is not a directory @@ -301,10 +288,6 @@ private Event visit(Path entry, boolean ignoreSecurityException, boolean canUseC stream = Files.newDirectoryStream(entry); } catch (IOException ioe) { return new Event(EventType.ENTRY, entry, ioe); - } catch (SecurityException se) { - if (ignoreSecurityException) - return null; - throw se; } // push a directory node to the stack and return an event @@ -321,7 +304,6 @@ Event walk(Path file) { throw new IllegalStateException("Closed"); Event ev = visit(file, - false, // ignoreSecurityException false); // canUseCached assert ev != null; return ev; @@ -372,7 +354,6 @@ Event next() { // visit the entry ev = visit(entry, - true, // ignoreSecurityException true); // canUseCached } while (ev == null); diff --git a/src/java.base/share/classes/java/nio/file/Files.java b/src/java.base/share/classes/java/nio/file/Files.java index 9599193d5d7..5dd8d219ba9 100644 --- a/src/java.base/share/classes/java/nio/file/Files.java +++ b/src/java.base/share/classes/java/nio/file/Files.java @@ -58,8 +58,6 @@ import java.nio.file.attribute.UserPrincipal; import java.nio.file.spi.FileSystemProvider; import java.nio.file.spi.FileTypeDetector; -import java.security.AccessController; -import java.security.PrivilegedAction; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; @@ -696,14 +694,8 @@ public static Path createDirectories(Path dir, FileAttribute<?>... attrs) } catch (IOException x) { // parent may not exist or other reason } - SecurityException se = null; - Path absDir = dir; - try { - absDir = dir.toAbsolutePath(); - } catch (SecurityException x) { - // don't have permission to get absolute path - se = x; - } + Path absDir = dir.toAbsolutePath(); + // find a descendant that exists Path parent = absDir.getParent(); while (parent != null) { @@ -717,12 +709,8 @@ public static Path createDirectories(Path dir, FileAttribute<?>... attrs) } if (parent == null) { // unable to find existing parent - if (se == null) { - throw new FileSystemException(absDir.toString(), null, - "Unable to determine if root directory exists"); - } else { - throw se; - } + throw new FileSystemException(absDir.toString(), null, + "Unable to determine if root directory exists"); } // create directories @@ -1525,29 +1513,19 @@ private static class FileTypeDetectors{ loadInstalledDetectors(); // creates the default file type detector - @SuppressWarnings("removal") private static FileTypeDetector createDefaultFileTypeDetector() { - return AccessController - .doPrivileged(new PrivilegedAction<>() { - @Override public FileTypeDetector run() { - return sun.nio.fs.DefaultFileTypeDetector.create(); - }}); + return sun.nio.fs.DefaultFileTypeDetector.create(); } // loads all installed file type detectors - @SuppressWarnings("removal") private static List<FileTypeDetector> loadInstalledDetectors() { - return AccessController - .doPrivileged(new PrivilegedAction<>() { - @Override public List<FileTypeDetector> run() { - List<FileTypeDetector> list = new ArrayList<>(); - ServiceLoader<FileTypeDetector> loader = ServiceLoader - .load(FileTypeDetector.class, ClassLoader.getSystemClassLoader()); - for (FileTypeDetector detector: loader) { - list.add(detector); - } - return list; - }}); + List<FileTypeDetector> list = new ArrayList<>(); + ServiceLoader<FileTypeDetector> loader = ServiceLoader + .load(FileTypeDetector.class, ClassLoader.getSystemClassLoader()); + for (FileTypeDetector detector: loader) { + list.add(detector); + } + return list; } } @@ -2863,26 +2841,16 @@ public static long copy(InputStream in, Path target, CopyOption... options) } // attempt to delete an existing file - SecurityException se = null; if (replaceExisting) { - try { - deleteIfExists(target); - } catch (SecurityException x) { - se = x; - } + deleteIfExists(target); } - // attempt to create target file. If it fails with - // FileAlreadyExistsException then it may be because the security - // manager prevented us from deleting the file, in which case we just - // throw the SecurityException. + // attempt to create target file. OutputStream ostream; try { ostream = newOutputStream(target, StandardOpenOption.CREATE_NEW, StandardOpenOption.WRITE); } catch (FileAlreadyExistsException x) { - if (se != null) - throw se; // someone else won the race and created the file throw x; } diff --git a/src/java.base/share/classes/java/nio/file/TempFileHelper.java b/src/java.base/share/classes/java/nio/file/TempFileHelper.java index 0d7a8cab849..e5ba85fcf36 100644 --- a/src/java.base/share/classes/java/nio/file/TempFileHelper.java +++ b/src/java.base/share/classes/java/nio/file/TempFileHelper.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -117,16 +117,12 @@ private static Path create(Path dir, } // loop generating random names until file or directory can be created - @SuppressWarnings("removal") - SecurityManager sm = System.getSecurityManager(); for (;;) { Path f; try { f = generatePath(prefix, suffix, dir); } catch (InvalidPathException e) { // don't reveal temporary directory location - if (sm != null) - throw new IllegalArgumentException("Invalid prefix or suffix"); throw e; } try { @@ -135,11 +131,6 @@ private static Path create(Path dir, } else { return Files.createFile(f, attrs); } - } catch (SecurityException e) { - // don't reveal temporary directory location - if (dir == tmpdir && sm != null) - throw new SecurityException("Unable to create temporary file or directory"); - throw e; } catch (FileAlreadyExistsException e) { // ignore } diff --git a/src/java.base/share/classes/java/nio/file/spi/FileSystemProvider.java b/src/java.base/share/classes/java/nio/file/spi/FileSystemProvider.java index 0f91e9b5f89..14e5ce90c2c 100644 --- a/src/java.base/share/classes/java/nio/file/spi/FileSystemProvider.java +++ b/src/java.base/share/classes/java/nio/file/spi/FileSystemProvider.java @@ -45,7 +45,6 @@ import java.nio.file.FileSystems; import java.nio.file.Files; import java.nio.file.LinkOption; -import java.nio.file.LinkPermission; import java.nio.file.NoSuchFileException; import java.nio.file.NotDirectoryException; import java.nio.file.NotLinkException; @@ -68,8 +67,6 @@ import java.util.ServiceLoader; import java.util.Set; import java.util.concurrent.ExecutorService; -import java.security.AccessController; -import java.security.PrivilegedAction; import sun.nio.ch.FileChannelImpl; @@ -185,13 +182,7 @@ public static List<FileSystemProvider> installedProviders() { } loadingProviders = true; - @SuppressWarnings("removal") - List<FileSystemProvider> list = AccessController - .doPrivileged(new PrivilegedAction<>() { - @Override - public List<FileSystemProvider> run() { - return loadInstalledProviders(); - }}); + List<FileSystemProvider> list = loadInstalledProviders(); // insert the default provider at the start of the list list.add(0, defaultProvider); diff --git a/src/java.base/share/classes/sun/nio/ch/AsynchronousChannelGroupImpl.java b/src/java.base/share/classes/sun/nio/ch/AsynchronousChannelGroupImpl.java index 0c15c1a6439..0b70a954e4c 100644 --- a/src/java.base/share/classes/sun/nio/ch/AsynchronousChannelGroupImpl.java +++ b/src/java.base/share/classes/sun/nio/ch/AsynchronousChannelGroupImpl.java @@ -34,10 +34,6 @@ import java.util.concurrent.*; import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicBoolean; -import java.security.PrivilegedAction; -import java.security.AccessController; -import java.security.AccessControlContext; -import sun.security.action.GetIntegerAction; /** * Base implementation of AsynchronousChannelGroup @@ -48,9 +44,8 @@ abstract class AsynchronousChannelGroupImpl { // number of internal threads handling I/O events when using an unbounded // thread pool. Internal threads do not dispatch to completion handlers. - @SuppressWarnings("removal") - private static final int internalThreadCount = AccessController.doPrivileged( - new GetIntegerAction("sun.nio.ch.internalThreadPoolSize", 1)); + private static final int internalThreadCount = + Integer.getInteger("sun.nio.ch.internalThreadPoolSize", 1); // associated thread pool private final ThreadPool pool; @@ -115,17 +110,10 @@ public void run() { }; } - @SuppressWarnings("removal") private void startInternalThread(final Runnable task) { - AccessController.doPrivileged(new PrivilegedAction<>() { - @Override - public Void run() { - // internal threads should not be visible to application so - // cannot use user-supplied thread factory - ThreadPool.defaultThreadFactory().newThread(task).start(); - return null; - } - }); + // internal threads should not be visible to application so + // cannot use user-supplied thread factory + ThreadPool.defaultThreadFactory().newThread(task).start(); } protected final void startThreads(Runnable task) { @@ -247,18 +235,9 @@ abstract Object attachForeignChannel(Channel channel, FileDescriptor fdo) */ abstract void shutdownHandlerTasks(); - @SuppressWarnings("removal") private void shutdownExecutors() { - AccessController.doPrivileged( - new PrivilegedAction<>() { - public Void run() { - pool.executor().shutdown(); - timeoutExecutor.shutdown(); - return null; - } - }, - null, - new RuntimePermission("modifyThread")); + pool.executor().shutdown(); + timeoutExecutor.shutdown(); } @Override @@ -320,28 +299,6 @@ public final boolean awaitTermination(long timeout, TimeUnit unit) */ @Override public final void execute(Runnable task) { - @SuppressWarnings("removal") - SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - // when a security manager is installed then the user's task - // must be run with the current calling context - @SuppressWarnings("removal") - final AccessControlContext acc = AccessController.getContext(); - final Runnable delegate = task; - task = new Runnable() { - @SuppressWarnings("removal") - @Override - public void run() { - AccessController.doPrivileged(new PrivilegedAction<>() { - @Override - public Void run() { - delegate.run(); - return null; - } - }, acc); - } - }; - } executeOnPooledThread(task); } } diff --git a/src/java.base/share/classes/sun/nio/ch/AsynchronousServerSocketChannelImpl.java b/src/java.base/share/classes/sun/nio/ch/AsynchronousServerSocketChannelImpl.java index cdc3a883734..0e6ca6c3dcd 100644 --- a/src/java.base/share/classes/sun/nio/ch/AsynchronousServerSocketChannelImpl.java +++ b/src/java.base/share/classes/sun/nio/ch/AsynchronousServerSocketChannelImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -150,10 +150,6 @@ public final AsynchronousServerSocketChannel bind(SocketAddress local, int backl { InetSocketAddress isa = (local == null) ? new InetSocketAddress(0) : Net.checkAddress(local); - @SuppressWarnings("removal") - SecurityManager sm = System.getSecurityManager(); - if (sm != null) - sm.checkListen(isa.getPort()); try { begin(); @@ -175,7 +171,7 @@ public final AsynchronousServerSocketChannel bind(SocketAddress local, int backl public final SocketAddress getLocalAddress() throws IOException { if (!isOpen()) throw new ClosedChannelException(); - return Net.getRevealedLocalAddress(localAddress); + return localAddress; } @Override @@ -257,7 +253,7 @@ public final String toString() { if (localAddress == null) { sb.append("unbound"); } else { - sb.append(Net.getRevealedLocalAddressAsString(localAddress)); + sb.append(localAddress.toString()); } } sb.append(']'); diff --git a/src/java.base/share/classes/sun/nio/ch/AsynchronousSocketChannelImpl.java b/src/java.base/share/classes/sun/nio/ch/AsynchronousSocketChannelImpl.java index 9c07dc47cd2..e08a873d73d 100644 --- a/src/java.base/share/classes/sun/nio/ch/AsynchronousSocketChannelImpl.java +++ b/src/java.base/share/classes/sun/nio/ch/AsynchronousSocketChannelImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -428,11 +428,6 @@ public final AsynchronousSocketChannel bind(SocketAddress local) throw new AlreadyBoundException(); InetSocketAddress isa = (local == null) ? new InetSocketAddress(0) : Net.checkAddress(local); - @SuppressWarnings("removal") - SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - sm.checkListen(isa.getPort()); - } NetHooks.beforeTcpBind(fd, isa.getAddress(), isa.getPort()); Net.bind(fd, isa.getAddress(), isa.getPort()); localAddress = Net.localAddress(fd); @@ -447,7 +442,7 @@ public final AsynchronousSocketChannel bind(SocketAddress local) public final SocketAddress getLocalAddress() throws IOException { if (!isOpen()) throw new ClosedChannelException(); - return Net.getRevealedLocalAddress(localAddress); + return localAddress; } @Override @@ -591,8 +586,7 @@ public final String toString() { } if (localAddress != null) { sb.append(" local="); - sb.append( - Net.getRevealedLocalAddressAsString(localAddress)); + sb.append(localAddress.toString()); } if (remoteAddress != null) { sb.append(" remote="); diff --git a/src/java.base/share/classes/sun/nio/ch/CompletedFuture.java b/src/java.base/share/classes/sun/nio/ch/CompletedFuture.java index 60f5f1056bc..e008dd9357b 100644 --- a/src/java.base/share/classes/sun/nio/ch/CompletedFuture.java +++ b/src/java.base/share/classes/sun/nio/ch/CompletedFuture.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -49,8 +49,8 @@ static <V> CompletedFuture<V> withResult(V result) { } static <V> CompletedFuture<V> withFailure(Throwable exc) { - // exception must be IOException or SecurityException - if (!(exc instanceof IOException) && !(exc instanceof SecurityException)) + // exception must be IOException + if (!(exc instanceof IOException)) exc = new IOException(exc); return new CompletedFuture<V>(null, exc); } diff --git a/src/java.base/share/classes/sun/nio/ch/Invoker.java b/src/java.base/share/classes/sun/nio/ch/Invoker.java index 475669a2b82..4c9d604a342 100644 --- a/src/java.base/share/classes/sun/nio/ch/Invoker.java +++ b/src/java.base/share/classes/sun/nio/ch/Invoker.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -27,8 +27,6 @@ import java.nio.channels.*; import java.util.concurrent.*; -import java.security.AccessController; -import sun.security.action.GetIntegerAction; import jdk.internal.misc.InnocuousThread; /** @@ -41,9 +39,8 @@ private Invoker() { } // maximum number of completion handlers that may be invoked on the current // thread before it re-directs invocations to the thread pool. This helps // avoid stack overflow and lessens the risk of starvation. - @SuppressWarnings("removal") - private static final int maxHandlerInvokeCount = AccessController.doPrivileged( - new GetIntegerAction("sun.nio.ch.maxCompletionHandlersOnStack", 16)); + private static final int maxHandlerInvokeCount = + Integer.getInteger("sun.nio.ch.maxCompletionHandlersOnStack", 16); // Per-thread object with reference to channel group and a counter for // the number of completion handlers invoked. This should be reset to 0 @@ -115,7 +112,6 @@ static boolean mayInvokeDirect(GroupAndInvokeCount myGroupAndInvokeCount, * Invoke handler without checking the thread identity or number of handlers * on the thread stack. */ - @SuppressWarnings("removal") static <V,A> void invokeUnchecked(CompletionHandler<V,? super A> handler, A attachment, V value, @@ -129,18 +125,6 @@ static <V,A> void invokeUnchecked(CompletionHandler<V,? super A> handler, // clear interrupt Thread.interrupted(); - - // clear thread locals when in default thread pool - if (System.getSecurityManager() != null) { - Thread me = Thread.currentThread(); - if (me instanceof InnocuousThread) { - GroupAndInvokeCount thisGroupAndInvokeCount = myGroupAndInvokeCount.get(); - ((InnocuousThread)me).eraseThreadLocals(); - if (thisGroupAndInvokeCount != null) { - myGroupAndInvokeCount.set(thisGroupAndInvokeCount); - } - } - } } /** diff --git a/src/java.base/share/classes/sun/nio/ch/Net.java b/src/java.base/share/classes/sun/nio/ch/Net.java index 49814ae6bf2..03dcf04a50f 100644 --- a/src/java.base/share/classes/sun/nio/ch/Net.java +++ b/src/java.base/share/classes/sun/nio/ch/Net.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -45,14 +45,11 @@ import java.nio.channels.NotYetConnectedException; import java.nio.channels.UnresolvedAddressException; import java.nio.channels.UnsupportedAddressTypeException; -import java.security.AccessController; -import java.security.PrivilegedAction; import java.util.Enumeration; import java.util.Objects; import sun.net.ext.ExtendedSocketOptions; import sun.net.util.IPAddressUtil; -import sun.security.action.GetPropertyAction; public class Net { private Net() { } @@ -215,34 +212,6 @@ static void translateException(Exception x) translateException(x, false); } - /** - * Returns the local address after performing a SecurityManager#checkConnect. - */ - static InetSocketAddress getRevealedLocalAddress(SocketAddress sa) { - InetSocketAddress isa = (InetSocketAddress) sa; - @SuppressWarnings("removal") - SecurityManager sm = System.getSecurityManager(); - if (isa != null && sm != null) { - try { - sm.checkConnect(isa.getAddress().getHostAddress(), -1); - } catch (SecurityException e) { - // Return loopback address only if security check fails - isa = getLoopbackAddress(isa.getPort()); - } - } - return isa; - } - - @SuppressWarnings("removal") - static String getRevealedLocalAddressAsString(SocketAddress sa) { - InetSocketAddress isa = (InetSocketAddress) sa; - if (System.getSecurityManager() == null) { - return isa.toString(); - } else { - return getLoopbackAddress(isa.getPort()).toString(); - } - } - private static InetSocketAddress getLoopbackAddress(int port) { return new InetSocketAddress(InetAddress.getLoopbackAddress(), port); } @@ -302,20 +271,15 @@ static InetAddress anyLocalAddress(ProtocolFamily family) { * Returns any IPv4 address of the given network interface, or * null if the interface does not have any IPv4 addresses. */ - @SuppressWarnings("removal") static Inet4Address anyInet4Address(final NetworkInterface interf) { - return AccessController.doPrivileged(new PrivilegedAction<Inet4Address>() { - public Inet4Address run() { - Enumeration<InetAddress> addrs = interf.getInetAddresses(); - while (addrs.hasMoreElements()) { - InetAddress addr = addrs.nextElement(); - if (addr instanceof Inet4Address inet4Address) { - return inet4Address; - } - } - return null; + Enumeration<InetAddress> addrs = interf.getInetAddresses(); + while (addrs.hasMoreElements()) { + InetAddress addr = addrs.nextElement(); + if (addr instanceof Inet4Address inet4Address) { + return inet4Address; } - }); + } + return null; } /** @@ -500,8 +464,7 @@ static Object getSocketOption(FileDescriptor fd, ProtocolFamily family, SocketOp } private static boolean isFastTcpLoopbackRequested() { - String loopbackProp = GetPropertyAction - .privilegedGetProperty("jdk.net.useFastTcpLoopback", "false"); + String loopbackProp = System.getProperty("jdk.net.useFastTcpLoopback", "false"); return loopbackProp.isEmpty() || Boolean.parseBoolean(loopbackProp); } @@ -827,8 +790,7 @@ static native int blockOrUnblock6(boolean block, FileDescriptor fd, byte[] group static { int availLevel = isExclusiveBindAvailable(); if (availLevel >= 0) { - String exclBindProp = GetPropertyAction - .privilegedGetProperty("sun.net.useExclusiveBind"); + String exclBindProp = System.getProperty("sun.net.useExclusiveBind"); if (exclBindProp != null) { EXCLUSIVE_BIND = exclBindProp.isEmpty() || Boolean.parseBoolean(exclBindProp); } else { diff --git a/src/java.base/share/classes/sun/nio/ch/PendingFuture.java b/src/java.base/share/classes/sun/nio/ch/PendingFuture.java index b2b3baceb62..67b526d8466 100644 --- a/src/java.base/share/classes/sun/nio/ch/PendingFuture.java +++ b/src/java.base/share/classes/sun/nio/ch/PendingFuture.java @@ -145,7 +145,7 @@ void setResult(V res) { * Sets the result, or a no-op if the result or exception is already set. */ void setFailure(Throwable x) { - if (!(x instanceof IOException) && !(x instanceof SecurityException)) + if (!(x instanceof IOException)) x = new IOException(x); synchronized (this) { if (haveResult) diff --git a/src/java.base/share/classes/sun/nio/ch/Reflect.java b/src/java.base/share/classes/sun/nio/ch/Reflect.java index 8090e0f0cc5..d1e564cce97 100644 --- a/src/java.base/share/classes/sun/nio/ch/Reflect.java +++ b/src/java.base/share/classes/sun/nio/ch/Reflect.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -27,8 +27,6 @@ import java.io.*; import java.lang.reflect.*; -import java.security.AccessController; -import java.security.PrivilegedAction; class Reflect { // package-private @@ -43,22 +41,13 @@ private static class ReflectionError extends Error { } } - @SuppressWarnings("removal") - private static void setAccessible(final AccessibleObject ao) { - AccessController.doPrivileged(new PrivilegedAction<Void>() { - public Void run() { - ao.setAccessible(true); - return null; - }}); - } - static Constructor<?> lookupConstructor(String className, Class<?>[] paramTypes) { try { Class<?> cl = Class.forName(className); Constructor<?> c = cl.getDeclaredConstructor(paramTypes); - setAccessible(c); + c.setAccessible(true); return c; } catch (ClassNotFoundException | NoSuchMethodException x) { throw new ReflectionError(x); @@ -82,7 +71,7 @@ static Method lookupMethod(String className, try { Class<?> cl = Class.forName(className); Method m = cl.getDeclaredMethod(methodName, paramTypes); - setAccessible(m); + m.setAccessible(true); return m; } catch (ClassNotFoundException | NoSuchMethodException x) { throw new ReflectionError(x); @@ -115,7 +104,7 @@ static Field lookupField(String className, String fieldName) { try { Class<?> cl = Class.forName(className); Field f = cl.getDeclaredField(fieldName); - setAccessible(f); + f.setAccessible(true); return f; } catch (ClassNotFoundException | NoSuchFieldException x) { throw new ReflectionError(x); diff --git a/src/java.base/share/classes/sun/nio/ch/ServerSocketAdaptor.java b/src/java.base/share/classes/sun/nio/ch/ServerSocketAdaptor.java index 1720801fbe9..3e1583693cc 100644 --- a/src/java.base/share/classes/sun/nio/ch/ServerSocketAdaptor.java +++ b/src/java.base/share/classes/sun/nio/ch/ServerSocketAdaptor.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -37,9 +37,6 @@ import java.nio.channels.IllegalBlockingModeException; import java.nio.channels.ServerSocketChannel; import java.nio.channels.SocketChannel; -import java.security.AccessController; -import java.security.PrivilegedActionException; -import java.security.PrivilegedExceptionAction; import java.util.Set; import static java.util.concurrent.TimeUnit.MILLISECONDS; @@ -61,14 +58,8 @@ class ServerSocketAdaptor // package-private // Timeout "option" value for accepts private volatile int timeout; - @SuppressWarnings("removal") static ServerSocket create(ServerSocketChannelImpl ssc) { - PrivilegedExceptionAction<ServerSocket> pa = () -> new ServerSocketAdaptor(ssc); - try { - return AccessController.doPrivileged(pa); - } catch (PrivilegedActionException pae) { - throw new InternalError("Should not reach here", pae); - } + return new ServerSocketAdaptor(ssc); } private ServerSocketAdaptor(ServerSocketChannelImpl ssc) { @@ -98,7 +89,7 @@ public InetAddress getInetAddress() { if (local == null) { return null; } else { - return Net.getRevealedLocalAddress(local).getAddress(); + return ((InetSocketAddress)local).getAddress(); } } diff --git a/src/java.base/share/classes/sun/nio/ch/ServerSocketChannelImpl.java b/src/java.base/share/classes/sun/nio/ch/ServerSocketChannelImpl.java index 0bd72bacf0b..f266b762b8b 100644 --- a/src/java.base/share/classes/sun/nio/ch/ServerSocketChannelImpl.java +++ b/src/java.base/share/classes/sun/nio/ch/ServerSocketChannelImpl.java @@ -202,11 +202,7 @@ public ServerSocket socket() { public SocketAddress getLocalAddress() throws IOException { synchronized (stateLock) { ensureOpen(); - if (isUnixSocket()) { - return UnixDomainSockets.getRevealedLocalAddress(localAddress); - } else { - return Net.getRevealedLocalAddress(localAddress); - } + return localAddress; } } @@ -305,7 +301,6 @@ public ServerSocketChannel bind(SocketAddress local, int backlog) throws IOExcep } private SocketAddress unixBind(SocketAddress local, int backlog) throws IOException { - UnixDomainSockets.checkPermission(); if (local == null) { // Attempt up to 10 times to find an unused name in temp directory. // If local address supplied then bind called only once @@ -336,10 +331,6 @@ private SocketAddress netBind(SocketAddress local, int backlog) throws IOExcepti } else { isa = Net.checkAddress(local, family); } - @SuppressWarnings("removal") - SecurityManager sm = System.getSecurityManager(); - if (sm != null) - sm.checkListen(isa.getPort()); NetHooks.beforeTcpBind(fd, isa.getAddress(), isa.getPort()); Net.bind(family, fd, isa.getAddress(), isa.getPort()); Net.listen(fd, backlog < 1 ? 50 : backlog); @@ -423,7 +414,6 @@ private int implAccept(FileDescriptor fd, FileDescriptor newfd, SocketAddress[] throws IOException { if (isUnixSocket()) { - UnixDomainSockets.checkPermission(); String[] pa = new String[1]; int n = UnixDomainSockets.accept(fd, newfd, pa); if (n > 0) @@ -495,16 +485,6 @@ private SocketChannel finishAccept(FileDescriptor newfd, SocketAddress sa) try { // newly accepted socket is initially in blocking mode IOUtil.configureBlocking(newfd, true); - - // check permitted to accept connections from the remote address - if (isNetSocket()) { - @SuppressWarnings("removal") - SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - InetSocketAddress isa = (InetSocketAddress) sa; - sm.checkAccept(isa.getAddress().getHostAddress(), isa.getPort()); - } - } return new SocketChannelImpl(provider(), family, newfd, sa); } catch (Exception e) { nd.close(newfd); @@ -749,9 +729,7 @@ public String toString() { if (addr == null) { sb.append("unbound"); } else if (isUnixSocket()) { - sb.append(UnixDomainSockets.getRevealedLocalAddressAsString(addr)); - } else { - sb.append(Net.getRevealedLocalAddressAsString(addr)); + sb.append(addr); } } } diff --git a/src/java.base/share/classes/sun/nio/ch/SimpleAsynchronousFileChannelImpl.java b/src/java.base/share/classes/sun/nio/ch/SimpleAsynchronousFileChannelImpl.java index 5f3f91e7aff..440c254601d 100644 --- a/src/java.base/share/classes/sun/nio/ch/SimpleAsynchronousFileChannelImpl.java +++ b/src/java.base/share/classes/sun/nio/ch/SimpleAsynchronousFileChannelImpl.java @@ -30,8 +30,6 @@ import java.nio.channels.*; import java.util.concurrent.*; import java.nio.ByteBuffer; -import java.security.AccessController; -import java.security.PrivilegedAction; import java.io.FileDescriptor; import java.io.IOException; diff --git a/src/java.base/share/classes/sun/nio/ch/SocketAdaptor.java b/src/java.base/share/classes/sun/nio/ch/SocketAdaptor.java index 076f817d5ce..cbcfd79378c 100644 --- a/src/java.base/share/classes/sun/nio/ch/SocketAdaptor.java +++ b/src/java.base/share/classes/sun/nio/ch/SocketAdaptor.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -36,9 +36,6 @@ import java.net.SocketOption; import java.net.StandardSocketOptions; import java.nio.channels.SocketChannel; -import java.security.AccessController; -import java.security.PrivilegedActionException; -import java.security.PrivilegedExceptionAction; import java.util.Set; import static java.util.concurrent.TimeUnit.MILLISECONDS; @@ -63,16 +60,10 @@ private SocketAdaptor(SocketChannelImpl sc) throws SocketException { this.sc = sc; } - @SuppressWarnings("removal") static Socket create(SocketChannelImpl sc) { try { - if (System.getSecurityManager() == null) { - return new SocketAdaptor(sc); - } else { - PrivilegedExceptionAction<Socket> pa = () -> new SocketAdaptor(sc); - return AccessController.doPrivileged(pa); - } - } catch (SocketException | PrivilegedActionException e) { + return new SocketAdaptor(sc); + } catch (SocketException e) { throw new InternalError(e); } } @@ -132,7 +123,7 @@ public InetAddress getLocalAddress() { if (sc.isOpen()) { InetSocketAddress local = localAddress(); if (local != null) { - return Net.getRevealedLocalAddress(local).getAddress(); + return local.getAddress(); } } return new InetSocketAddress(0).getAddress(); @@ -165,7 +156,7 @@ public SocketAddress getRemoteSocketAddress() { @Override public SocketAddress getLocalSocketAddress() { - return Net.getRevealedLocalAddress(sc.localAddress()); + return sc.localAddress(); } @Override diff --git a/src/java.base/share/classes/sun/nio/ch/SocketChannelImpl.java b/src/java.base/share/classes/sun/nio/ch/SocketChannelImpl.java index ebbf55acd97..893bd17ceed 100644 --- a/src/java.base/share/classes/sun/nio/ch/SocketChannelImpl.java +++ b/src/java.base/share/classes/sun/nio/ch/SocketChannelImpl.java @@ -243,11 +243,7 @@ public Socket socket() { public SocketAddress getLocalAddress() throws IOException { synchronized (stateLock) { ensureOpen(); - if (isUnixSocket()) { - return UnixDomainSockets.getRevealedLocalAddress(localAddress); - } else { - return Net.getRevealedLocalAddress(localAddress); - } + return localAddress; } } @@ -811,7 +807,6 @@ public SocketChannel bind(SocketAddress local) throws IOException { } private SocketAddress unixBind(SocketAddress local) throws IOException { - UnixDomainSockets.checkPermission(); if (local == null) { return UnixDomainSockets.unnamed(); } else { @@ -833,11 +828,6 @@ private SocketAddress netBind(SocketAddress local) throws IOException { } else { isa = Net.checkAddress(local, family); } - @SuppressWarnings("removal") - SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - sm.checkListen(isa.getPort()); - } NetHooks.beforeTcpBind(fd, isa.getAddress(), isa.getPort()); Net.bind(family, fd, isa.getAddress(), isa.getPort()); return Net.localAddress(fd); @@ -923,15 +913,9 @@ private void endConnect(boolean blocking, boolean completed) */ private SocketAddress checkRemote(SocketAddress sa) { if (isUnixSocket()) { - UnixDomainSockets.checkPermission(); return UnixDomainSockets.checkAddress(sa); } else { InetSocketAddress isa = Net.checkAddress(sa, family); - @SuppressWarnings("removal") - SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - sm.checkConnect(isa.getAddress().getHostAddress(), isa.getPort()); - } InetAddress address = isa.getAddress(); if (address.isAnyLocalAddress()) { int port = isa.getPort(); @@ -1617,15 +1601,11 @@ public String toString() { SocketAddress addr = localAddress(); if (addr != null) { sb.append(" local="); - if (isUnixSocket()) { - sb.append(UnixDomainSockets.getRevealedLocalAddressAsString(addr)); - } else { - sb.append(Net.getRevealedLocalAddressAsString(addr)); - } + sb.append(addr); } if (remoteAddress() != null) { sb.append(" remote="); - sb.append(remoteAddress().toString()); + sb.append(remoteAddress()); } } } diff --git a/src/java.base/share/classes/sun/nio/ch/ThreadPool.java b/src/java.base/share/classes/sun/nio/ch/ThreadPool.java index f5a17361eba..b3157008fcb 100644 --- a/src/java.base/share/classes/sun/nio/ch/ThreadPool.java +++ b/src/java.base/share/classes/sun/nio/ch/ThreadPool.java @@ -26,10 +26,6 @@ package sun.nio.ch; import java.util.concurrent.*; -import java.security.AccessController; -import java.security.PrivilegedAction; -import sun.security.action.GetPropertyAction; -import sun.security.action.GetIntegerAction; import jdk.internal.misc.InnocuousThread; /** @@ -72,24 +68,12 @@ int poolSize() { return poolSize; } - @SuppressWarnings("removal") static ThreadFactory defaultThreadFactory() { - if (System.getSecurityManager() == null) { - return (Runnable r) -> { - Thread t = new Thread(r); - t.setDaemon(true); - return t; - }; - } else { - return (Runnable r) -> { - PrivilegedAction<Thread> action = () -> { - Thread t = InnocuousThread.newThread(r); - t.setDaemon(true); - return t; - }; - return AccessController.doPrivileged(action); - }; - } + return (Runnable r) -> { + Thread t = new Thread(r); + t.setDaemon(true); + return t; + }; } private static class DefaultThreadPoolHolder { @@ -148,9 +132,7 @@ public static ThreadPool wrap(ExecutorService executor, int initialSize) { } private static int getDefaultThreadPoolInitialSize() { - @SuppressWarnings("removal") - String propValue = AccessController.doPrivileged(new - GetPropertyAction(DEFAULT_THREAD_POOL_INITIAL_SIZE)); + String propValue = System.getProperty(DEFAULT_THREAD_POOL_INITIAL_SIZE); if (propValue != null) { try { return Integer.parseInt(propValue); @@ -163,9 +145,7 @@ private static int getDefaultThreadPoolInitialSize() { } private static ThreadFactory getDefaultThreadPoolThreadFactory() { - @SuppressWarnings("removal") - String propValue = AccessController.doPrivileged(new - GetPropertyAction(DEFAULT_THREAD_POOL_THREAD_FACTORY)); + String propValue = System.getProperty(DEFAULT_THREAD_POOL_THREAD_FACTORY); if (propValue != null) { try { @SuppressWarnings("deprecation") diff --git a/src/java.base/share/classes/sun/nio/ch/UnixDomainSockets.java b/src/java.base/share/classes/sun/nio/ch/UnixDomainSockets.java index 251e79c6ecc..128694cb52d 100644 --- a/src/java.base/share/classes/sun/nio/ch/UnixDomainSockets.java +++ b/src/java.base/share/classes/sun/nio/ch/UnixDomainSockets.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -59,25 +59,6 @@ static boolean isSupported() { return supported; } - static void checkPermission() { - @SuppressWarnings("removal") - SecurityManager sm = System.getSecurityManager(); - if (sm != null) - sm.checkPermission(accessUnixDomainSocket); - } - - static UnixDomainSocketAddress getRevealedLocalAddress(SocketAddress sa) { - UnixDomainSocketAddress addr = (UnixDomainSocketAddress) sa; - try { - checkPermission(); - // Security check passed - } catch (SecurityException e) { - // Return unnamed address only if security check fails - addr = unnamed(); - } - return addr; - } - static UnixDomainSocketAddress localAddress(FileDescriptor fd) throws IOException { String path = new String(localAddress0(fd), UnixDomainSocketsUtil.getCharset()); return UnixDomainSocketAddress.of(path); @@ -85,11 +66,6 @@ static UnixDomainSocketAddress localAddress(FileDescriptor fd) throws IOExceptio private static native byte[] localAddress0(FileDescriptor fd) throws IOException; - @SuppressWarnings("removal") - static String getRevealedLocalAddressAsString(SocketAddress sa) { - return (System.getSecurityManager() != null) ? sa.toString() : ""; - } - static UnixDomainSocketAddress checkAddress(SocketAddress sa) { if (sa == null) throw new NullPointerException(); diff --git a/src/java.base/share/classes/sun/nio/ch/Util.java b/src/java.base/share/classes/sun/nio/ch/Util.java index bf9fc0c0f7c..cf411008e43 100644 --- a/src/java.base/share/classes/sun/nio/ch/Util.java +++ b/src/java.base/share/classes/sun/nio/ch/Util.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -32,15 +32,12 @@ import java.lang.reflect.InvocationTargetException; import java.nio.ByteBuffer; import java.nio.MappedByteBuffer; -import java.security.AccessController; -import java.security.PrivilegedAction; import java.util.Collection; import java.util.Iterator; import java.util.Set; import jdk.internal.misc.TerminatingThreadLocal; import jdk.internal.misc.Unsafe; -import sun.security.action.GetPropertyAction; public class Util { @@ -75,7 +72,7 @@ protected void threadTerminated(BufferCache cache) { // will never be null * for potential future-proofing. */ private static long getMaxCachedBufferSize() { - String s = GetPropertyAction.privilegedGetProperty("jdk.nio.maxCachedBufferSize"); + String s = System.getProperty("jdk.nio.maxCachedBufferSize"); if (s != null) { try { long m = Long.parseLong(s); @@ -406,28 +403,23 @@ static int pageSize() { private static volatile Constructor<?> directByteBufferConstructor; - @SuppressWarnings("removal") private static void initDBBConstructor() { - AccessController.doPrivileged(new PrivilegedAction<Void>() { - public Void run() { - try { - Class<?> cl = Class.forName("java.nio.DirectByteBuffer"); - Constructor<?> ctor = cl.getDeclaredConstructor( - new Class<?>[] { int.class, - long.class, - FileDescriptor.class, - Runnable.class, - boolean.class, MemorySegment.class}); - ctor.setAccessible(true); - directByteBufferConstructor = ctor; - } catch (ClassNotFoundException | - NoSuchMethodException | - IllegalArgumentException | - ClassCastException x) { - throw new InternalError(x); - } - return null; - }}); + try { + Class<?> cl = Class.forName("java.nio.DirectByteBuffer"); + Constructor<?> ctor = cl.getDeclaredConstructor( + new Class<?>[] { int.class, + long.class, + FileDescriptor.class, + Runnable.class, + boolean.class, MemorySegment.class }); + ctor.setAccessible(true); + directByteBufferConstructor = ctor; + } catch (ClassNotFoundException | + NoSuchMethodException | + IllegalArgumentException | + ClassCastException x) { + throw new InternalError(x); + } } static MappedByteBuffer newMappedByteBuffer(int size, long addr, @@ -455,28 +447,23 @@ static MappedByteBuffer newMappedByteBuffer(int size, long addr, private static volatile Constructor<?> directByteBufferRConstructor; - @SuppressWarnings("removal") private static void initDBBRConstructor() { - AccessController.doPrivileged(new PrivilegedAction<Void>() { - public Void run() { - try { - Class<?> cl = Class.forName("java.nio.DirectByteBufferR"); - Constructor<?> ctor = cl.getDeclaredConstructor( - new Class<?>[] { int.class, - long.class, - FileDescriptor.class, - Runnable.class, - boolean.class, MemorySegment.class }); - ctor.setAccessible(true); - directByteBufferRConstructor = ctor; - } catch (ClassNotFoundException | - NoSuchMethodException | - IllegalArgumentException | - ClassCastException x) { - throw new InternalError(x); - } - return null; - }}); + try { + Class<?> cl = Class.forName("java.nio.DirectByteBufferR"); + Constructor<?> ctor = cl.getDeclaredConstructor( + new Class<?>[] { int.class, + long.class, + FileDescriptor.class, + Runnable.class, + boolean.class, MemorySegment.class }); + ctor.setAccessible(true); + directByteBufferRConstructor = ctor; + } catch (ClassNotFoundException | + NoSuchMethodException | + IllegalArgumentException | + ClassCastException x) { + throw new InternalError(x); + } } static MappedByteBuffer newMappedByteBufferR(int size, long addr, diff --git a/src/java.base/share/classes/sun/nio/cs/CharsetMapping.java b/src/java.base/share/classes/sun/nio/cs/CharsetMapping.java index d3e4e907805..eeafe87eb96 100644 --- a/src/java.base/share/classes/sun/nio/cs/CharsetMapping.java +++ b/src/java.base/share/classes/sun/nio/cs/CharsetMapping.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -28,7 +28,6 @@ import java.io.InputStream; import java.io.IOException; import java.util.*; -import java.security.*; public class CharsetMapping { public static final char UNMAPPABLE_DECODING = '\uFFFD'; @@ -129,13 +128,8 @@ public int encodeComposite(Entry comp) { } // init the CharsetMapping object from the .dat binary file - @SuppressWarnings("removal") public static CharsetMapping get(final InputStream is) { - return AccessController.doPrivileged(new PrivilegedAction<>() { - public CharsetMapping run() { - return new CharsetMapping().load(is); - } - }); + return new CharsetMapping().load(is); } public static class Entry { diff --git a/src/java.base/share/classes/sun/nio/fs/AbstractPoller.java b/src/java.base/share/classes/sun/nio/fs/AbstractPoller.java index d2cd7217942..e2ac950f01d 100644 --- a/src/java.base/share/classes/sun/nio/fs/AbstractPoller.java +++ b/src/java.base/share/classes/sun/nio/fs/AbstractPoller.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,8 +26,6 @@ package sun.nio.fs; import java.nio.file.*; -import java.security.AccessController; -import java.security.PrivilegedAction; import java.io.IOException; import java.util.*; @@ -54,22 +52,14 @@ protected AbstractPoller() { /** * Starts the poller thread */ - @SuppressWarnings("removal") public void start() { - final Runnable thisRunnable = this; - AccessController.doPrivileged(new PrivilegedAction<>() { - @Override - public Object run() { - Thread thr = new Thread(null, - thisRunnable, - "FileSystemWatchService", - 0, - false); - thr.setDaemon(true); - thr.start(); - return null; - } - }); + Thread thr = new Thread(null, + this, + "FileSystemWatchService", + 0, + false); + thr.setDaemon(true); + thr.start(); } /** diff --git a/src/java.base/share/classes/sun/nio/fs/AbstractUserDefinedFileAttributeView.java b/src/java.base/share/classes/sun/nio/fs/AbstractUserDefinedFileAttributeView.java index c01cec55dfe..14c809d9f3f 100644 --- a/src/java.base/share/classes/sun/nio/fs/AbstractUserDefinedFileAttributeView.java +++ b/src/java.base/share/classes/sun/nio/fs/AbstractUserDefinedFileAttributeView.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,9 +25,9 @@ package sun.nio.fs; +import java.io.IOException; import java.nio.ByteBuffer; import java.nio.file.attribute.UserDefinedFileAttributeView; -import java.io.IOException; import java.util.*; /** @@ -39,22 +39,6 @@ abstract class AbstractUserDefinedFileAttributeView { protected AbstractUserDefinedFileAttributeView() { } - protected void checkAccess(String file, - boolean checkRead, - boolean checkWrite) - { - assert checkRead || checkWrite; - @SuppressWarnings("removal") - SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - if (checkRead) - sm.checkRead(file); - if (checkWrite) - sm.checkWrite(file); - sm.checkPermission(new RuntimePermission("accessUserDefinedAttributes")); - } - } - @Override public final String name() { return "user"; diff --git a/src/java.base/share/classes/sun/nio/fs/PollingWatchService.java b/src/java.base/share/classes/sun/nio/fs/PollingWatchService.java index 91b5471145c..0284156ca3b 100644 --- a/src/java.base/share/classes/sun/nio/fs/PollingWatchService.java +++ b/src/java.base/share/classes/sun/nio/fs/PollingWatchService.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -36,10 +36,6 @@ import java.nio.file.WatchKey; import java.nio.file.attribute.BasicFileAttributes; import java.nio.file.attribute.FileTime; -import java.security.AccessController; -import java.security.PrivilegedAction; -import java.security.PrivilegedExceptionAction; -import java.security.PrivilegedActionException; import java.io.IOException; import java.util.HashMap; import java.util.HashSet; @@ -86,7 +82,6 @@ public Thread newThread(Runnable r) { /** * Register the given file with this watch service */ - @SuppressWarnings("removal") @Override WatchKey register(final Path path, WatchEvent.Kind<?>[] events, @@ -133,30 +128,9 @@ WatchKey register(final Path path, if (!isOpen()) throw new ClosedWatchServiceException(); - // registration is done in privileged block as it requires the - // attributes of the entries in the directory. - try { - return AccessController.doPrivileged( - new PrivilegedExceptionAction<PollingWatchKey>() { - @Override - public PollingWatchKey run() throws IOException { - return doPrivilegedRegister(path, eventSet); - } - }); - } catch (PrivilegedActionException pae) { - Throwable cause = pae.getCause(); - if (cause instanceof IOException ioe) - throw ioe; - throw new AssertionError(pae); - } - } + // registers directory returning a new key if not already registered or + // existing key if already registered - // registers directory returning a new key if not already registered or - // existing key if already registered - private PollingWatchKey doPrivilegedRegister(Path path, - Set<? extends WatchEvent.Kind<?>> events) - throws IOException - { // check file is a directory and get its file key if possible BasicFileAttributes attrs = Files.readAttributes(path, BasicFileAttributes.class); if (!attrs.isDirectory()) { @@ -183,13 +157,12 @@ private PollingWatchKey doPrivilegedRegister(Path path, watchKey.disable(); } } - watchKey.enable(events); + watchKey.enable(eventSet); return watchKey; } } - @SuppressWarnings("removal") @Override void implClose() throws IOException { synchronized (map) { @@ -200,13 +173,7 @@ void implClose() throws IOException { } map.clear(); } - AccessController.doPrivileged(new PrivilegedAction<Void>() { - @Override - public Void run() { - scheduledExecutor.shutdown(); - return null; - } - }); + scheduledExecutor.shutdown(); } /** diff --git a/src/java.base/unix/classes/sun/nio/ch/InheritedChannel.java b/src/java.base/unix/classes/sun/nio/ch/InheritedChannel.java index 868e859da29..d0cab80c664 100644 --- a/src/java.base/unix/classes/sun/nio/ch/InheritedChannel.java +++ b/src/java.base/unix/classes/sun/nio/ch/InheritedChannel.java @@ -149,18 +149,6 @@ protected void implCloseSelectableChannel() throws IOException { } } - /* - * If there's a SecurityManager then check for the appropriate - * RuntimePermission. - */ - private static void checkAccess() { - @SuppressWarnings("removal") - SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - sm.checkPermission(new RuntimePermission("inheritedChannel")); - } - } - /* * If standard inherited channel is connected to a socket then return a Channel * of the appropriate type based standard input. @@ -252,11 +240,6 @@ public static synchronized Channel getChannel() throws IOException { haveChannel = true; } - // if there is a channel then do the security check before - // returning it. - if (channel != null) { - checkAccess(); - } return channel; } diff --git a/src/java.base/unix/classes/sun/nio/ch/UnixAsynchronousServerSocketChannelImpl.java b/src/java.base/unix/classes/sun/nio/ch/UnixAsynchronousServerSocketChannelImpl.java index d8e6ed1a21a..e98756c7e64 100644 --- a/src/java.base/unix/classes/sun/nio/ch/UnixAsynchronousServerSocketChannelImpl.java +++ b/src/java.base/unix/classes/sun/nio/ch/UnixAsynchronousServerSocketChannelImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -31,9 +31,6 @@ import java.io.FileDescriptor; import java.net.InetSocketAddress; import java.util.concurrent.atomic.AtomicBoolean; -import java.security.AccessControlContext; -import java.security.AccessController; -import java.security.PrivilegedAction; /** * Unix implementation of AsynchronousServerSocketChannel @@ -64,11 +61,6 @@ private void enableAccept() { private Object acceptAttachment; private PendingFuture<AsynchronousSocketChannel,Object> acceptFuture; - // context for permission check when security manager set - @SuppressWarnings("removal") - private AccessControlContext acceptAcc; - - UnixAsynchronousServerSocketChannelImpl(Port port) throws IOException { @@ -165,9 +157,9 @@ public void onEvent(int events, boolean mayInvokeDirect) { AsynchronousSocketChannel child = null; if (exc == null) { try { - child = finishAccept(newfd, isaa[0], acceptAcc); + child = finishAccept(newfd, isaa[0]); } catch (Throwable x) { - if (!(x instanceof IOException) && !(x instanceof SecurityException)) + if (!(x instanceof IOException)) x = new IOException(x); exc = x; } @@ -198,14 +190,12 @@ public void onEvent(int events, boolean mayInvokeDirect) { /** * Completes the accept by creating the AsynchronousSocketChannel for * the given file descriptor and remote address. If this method completes - * with an IOException or SecurityException then the channel/file descriptor + * with an IOException then the channel/file descriptor * will be closed. */ - @SuppressWarnings("removal") private AsynchronousSocketChannel finishAccept(FileDescriptor newfd, - final InetSocketAddress remote, - AccessControlContext acc) - throws IOException, SecurityException + final InetSocketAddress remote) + throws IOException { AsynchronousSocketChannel ch = null; try { @@ -215,38 +205,9 @@ private AsynchronousSocketChannel finishAccept(FileDescriptor newfd, throw x; } - // permission check must always be in initiator's context - try { - if (acc != null) { - AccessController.doPrivileged(new PrivilegedAction<>() { - public Void run() { - SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - sm.checkAccept(remote.getAddress().getHostAddress(), - remote.getPort()); - } - return null; - } - }, acc); - } else { - SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - sm.checkAccept(remote.getAddress().getHostAddress(), - remote.getPort()); - } - } - } catch (SecurityException x) { - try { - ch.close(); - } catch (Throwable suppressed) { - x.addSuppressed(suppressed); - } - throw x; - } return ch; } - @SuppressWarnings("removal") @Override Future<AsynchronousSocketChannel> implAccept(Object att, CompletionHandler<AsynchronousSocketChannel,Object> handler) @@ -283,9 +244,6 @@ Future<AsynchronousSocketChannel> implAccept(Object att, int n = Net.accept(this.fd, newfd, isaa); if (n == IOStatus.UNAVAILABLE) { - // need calling context when there is security manager as - // permission check may be done in a different thread without - // any application call frames on the stack PendingFuture<AsynchronousSocketChannel,Object> result = null; synchronized (updateLock) { if (handler == null) { @@ -296,8 +254,6 @@ Future<AsynchronousSocketChannel> implAccept(Object att, this.acceptHandler = handler; this.acceptAttachment = att; } - this.acceptAcc = (System.getSecurityManager() == null) ? - null : AccessController.getContext(); this.acceptPending = true; } @@ -318,7 +274,7 @@ Future<AsynchronousSocketChannel> implAccept(Object att, if (exc == null) { // connection accepted immediately try { - child = finishAccept(newfd, isaa[0], null); + child = finishAccept(newfd, isaa[0]); } catch (Throwable x) { exc = x; } diff --git a/src/java.base/unix/classes/sun/nio/ch/UnixAsynchronousSocketChannelImpl.java b/src/java.base/unix/classes/sun/nio/ch/UnixAsynchronousSocketChannelImpl.java index 49960b7ed21..b9c099ef92f 100644 --- a/src/java.base/unix/classes/sun/nio/ch/UnixAsynchronousSocketChannelImpl.java +++ b/src/java.base/unix/classes/sun/nio/ch/UnixAsynchronousSocketChannelImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -35,7 +35,6 @@ import sun.net.ConnectionResetException; import sun.net.NetHooks; import sun.net.util.SocketExceptions; -import sun.security.action.GetPropertyAction; /** * Unix implementation of AsynchronousSocketChannel @@ -49,7 +48,7 @@ private static enum OpType { CONNECT, READ, WRITE }; private static final boolean disableSynchronousRead; static { - String propValue = GetPropertyAction.privilegedGetProperty( + String propValue = System.getProperty( "sun.nio.ch.disableSynchronousRead", "false"); disableSynchronousRead = propValue.isEmpty() ? true : Boolean.parseBoolean(propValue); @@ -309,12 +308,6 @@ <A> Future<Void> implConnect(SocketAddress remote, InetSocketAddress isa = Net.checkAddress(remote); - // permission check - @SuppressWarnings("removal") - SecurityManager sm = System.getSecurityManager(); - if (sm != null) - sm.checkConnect(isa.getAddress().getHostAddress(), isa.getPort()); - // check and set state boolean notifyBeforeTcpConnect; synchronized (stateLock) { diff --git a/src/java.base/unix/classes/sun/nio/ch/UnixDomainSocketsUtil.java b/src/java.base/unix/classes/sun/nio/ch/UnixDomainSocketsUtil.java index b28bf9d093c..f3f6499871e 100644 --- a/src/java.base/unix/classes/sun/nio/ch/UnixDomainSocketsUtil.java +++ b/src/java.base/unix/classes/sun/nio/ch/UnixDomainSocketsUtil.java @@ -26,8 +26,6 @@ package sun.nio.ch; import java.nio.charset.Charset; -import java.security.AccessController; -import java.security.PrivilegedAction; import sun.net.NetProperties; import jdk.internal.util.StaticProperty; @@ -51,16 +49,12 @@ static Charset getCharset() { * 2. ${jdk.net.unixdomain.tmpdir} if set as net property * 3. ${java.io.tmpdir} system property */ - @SuppressWarnings("removal") static String getTempDir() { - PrivilegedAction<String> action = () -> { - String s = NetProperties.get("jdk.net.unixdomain.tmpdir"); - if (s != null && s.length() > 0) { - return s; - } else { - return StaticProperty.javaIoTmpDir(); - } - }; - return AccessController.doPrivileged(action); + String s = NetProperties.get("jdk.net.unixdomain.tmpdir"); + if (s != null && s.length() > 0) { + return s; + } else { + return StaticProperty.javaIoTmpDir(); + } } } diff --git a/src/java.base/unix/classes/sun/nio/fs/MimeTypesFileTypeDetector.java b/src/java.base/unix/classes/sun/nio/fs/MimeTypesFileTypeDetector.java index e68158c2569..67abe634ab1 100644 --- a/src/java.base/unix/classes/sun/nio/fs/MimeTypesFileTypeDetector.java +++ b/src/java.base/unix/classes/sun/nio/fs/MimeTypesFileTypeDetector.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -29,8 +29,6 @@ import java.nio.charset.Charset; import java.nio.file.Files; import java.nio.file.Path; -import java.security.AccessController; -import java.security.PrivilegedAction; import java.util.Collections; import java.util.HashMap; import java.util.List; @@ -93,19 +91,13 @@ private void loadMimeTypes() { if (!loaded) { synchronized (this) { if (!loaded) { - @SuppressWarnings("removal") - List<String> lines = AccessController.doPrivileged( - new PrivilegedAction<>() { - @Override - public List<String> run() { - try { - return Files.readAllLines(mimeTypesFile, - Charset.defaultCharset()); - } catch (IOException ignore) { - return Collections.emptyList(); - } - } - }); + List<String> lines; + try { + lines = Files.readAllLines(mimeTypesFile, + Charset.defaultCharset()); + } catch (IOException ignore) { + lines = Collections.emptyList(); + } mimeTypeMap = HashMap.newHashMap(lines.size()); String entry = ""; diff --git a/src/java.base/unix/classes/sun/nio/fs/UnixChannelFactory.java b/src/java.base/unix/classes/sun/nio/fs/UnixChannelFactory.java index 8e5bf38882c..dec13180f2f 100644 --- a/src/java.base/unix/classes/sun/nio/fs/UnixChannelFactory.java +++ b/src/java.base/unix/classes/sun/nio/fs/UnixChannelFactory.java @@ -25,9 +25,9 @@ package sun.nio.fs; +import java.io.FileDescriptor; import java.nio.file.*; import java.nio.channels.*; -import java.io.FileDescriptor; import java.util.Set; import jdk.internal.access.SharedSecrets; @@ -108,7 +108,6 @@ static Flags toFlags(Set<? extends OpenOption> options) { */ static FileChannel newFileChannel(int dfd, UnixPath path, - String pathForPermissionCheck, Set<? extends OpenOption> options, int mode) throws UnixException @@ -130,7 +129,7 @@ static FileChannel newFileChannel(int dfd, if (flags.append && flags.truncateExisting) throw new IllegalArgumentException("APPEND + TRUNCATE_EXISTING not allowed"); - FileDescriptor fdObj = open(dfd, path, pathForPermissionCheck, flags, mode); + FileDescriptor fdObj = open(dfd, path, flags, mode); return FileChannelImpl.open(fdObj, path.toString(), flags.read, flags.write, (flags.sync || flags.dsync), flags.direct, null); } @@ -143,7 +142,7 @@ static FileChannel newFileChannel(UnixPath path, int mode) throws UnixException { - return newFileChannel(-1, path, null, options, mode); + return newFileChannel(-1, path, options, mode); } /** @@ -167,7 +166,7 @@ static AsynchronousFileChannel newAsynchronousFileChannel(UnixPath path, throw new UnsupportedOperationException("APPEND not allowed"); // for now use simple implementation - FileDescriptor fdObj = open(-1, path, null, flags, mode); + FileDescriptor fdObj = open(-1, path, flags, mode); return SimpleAsynchronousFileChannelImpl.open(fdObj, path.toString(), flags.read, flags.write, pool); } @@ -177,7 +176,6 @@ static AsynchronousFileChannel newAsynchronousFileChannel(UnixPath path, */ protected static FileDescriptor open(int dfd, UnixPath path, - String pathForPermissionCheck, Flags flags, int mode) throws UnixException @@ -236,20 +234,6 @@ protected static FileDescriptor open(int dfd, if (flags.direct) oflags |= O_DIRECT; - // permission check before we open the file - @SuppressWarnings("removal") - SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - if (pathForPermissionCheck == null) - pathForPermissionCheck = path.getPathForPermissionCheck(); - if (flags.read) - sm.checkRead(pathForPermissionCheck); - if (flags.write) - sm.checkWrite(pathForPermissionCheck); - if (flags.deleteOnClose) - sm.checkDelete(pathForPermissionCheck); - } - int fd; try { if (dfd >= 0) { diff --git a/src/java.base/unix/classes/sun/nio/fs/UnixFileAttributeViews.java b/src/java.base/unix/classes/sun/nio/fs/UnixFileAttributeViews.java index 4ba1d2b8774..aadef1ea50f 100644 --- a/src/java.base/unix/classes/sun/nio/fs/UnixFileAttributeViews.java +++ b/src/java.base/unix/classes/sun/nio/fs/UnixFileAttributeViews.java @@ -25,11 +25,11 @@ package sun.nio.fs; +import java.io.IOException; import java.nio.file.*; import java.nio.file.attribute.*; import java.util.*; import java.util.concurrent.TimeUnit; -import java.io.IOException; import static sun.nio.fs.UnixConstants.*; import static sun.nio.fs.UnixNativeDispatcher.*; @@ -47,7 +47,6 @@ static class Basic extends AbstractBasicFileAttributeView { @Override public BasicFileAttributes readAttributes() throws IOException { - file.checkRead(); try { UnixFileAttributes attrs = UnixFileAttributes.get(file, followLinks); @@ -69,9 +68,6 @@ public void setTimes(FileTime lastModifiedTime, return; } - // permission check - file.checkWrite(); - // use a file descriptor if possible to avoid a race due to // accessing a path more than once as the file at that path could // change. @@ -156,24 +152,6 @@ static class Posix extends Basic implements PosixFileAttributeView { super(file, followLinks); } - final void checkReadExtended() { - @SuppressWarnings("removal") - SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - file.checkRead(); - sm.checkPermission(new RuntimePermission("accessUserInformation")); - } - } - - final void checkWriteExtended() { - @SuppressWarnings("removal") - SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - file.checkWrite(); - sm.checkPermission(new RuntimePermission("accessUserInformation")); - } - } - @Override public String name() { return "posix"; @@ -228,7 +206,6 @@ public Map<String,Object> readAttributes(String[] requested) @Override public UnixFileAttributes readAttributes() throws IOException { - checkReadExtended(); try { return UnixFileAttributes.get(file, followLinks); } catch (UnixException x) { @@ -239,8 +216,6 @@ public UnixFileAttributes readAttributes() throws IOException { // chmod final void setMode(int mode) throws IOException { - checkWriteExtended(); - if (followLinks) { try { chmod(file, mode); @@ -283,7 +258,6 @@ final void setMode(int mode) throws IOException { // chown final void setOwners(int uid, int gid) throws IOException { - checkWriteExtended(); try { if (followLinks) { chown(file, uid, gid); diff --git a/src/java.base/unix/classes/sun/nio/fs/UnixFileStore.java b/src/java.base/unix/classes/sun/nio/fs/UnixFileStore.java index 6704a588d10..4311cd6c646 100644 --- a/src/java.base/unix/classes/sun/nio/fs/UnixFileStore.java +++ b/src/java.base/unix/classes/sun/nio/fs/UnixFileStore.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -34,8 +34,6 @@ import java.nio.channels.*; import java.util.*; import java.io.IOException; -import java.security.AccessController; -import java.security.PrivilegedAction; /** * Base implementation of FileStore for Unix/like implementations. @@ -269,17 +267,11 @@ enum FeatureStatus { /** * Returns status to indicate if file system supports a given feature */ - @SuppressWarnings("removal") FeatureStatus checkIfFeaturePresent(String feature) { if (props == null) { synchronized (loadLock) { if (props == null) { - props = AccessController.doPrivileged( - new PrivilegedAction<>() { - @Override - public Properties run() { - return loadProperties(); - }}); + props = loadProperties(); } } } diff --git a/src/java.base/unix/classes/sun/nio/fs/UnixFileSystem.java b/src/java.base/unix/classes/sun/nio/fs/UnixFileSystem.java index 56a7624e436..51ed4211fff 100644 --- a/src/java.base/unix/classes/sun/nio/fs/UnixFileSystem.java +++ b/src/java.base/unix/classes/sun/nio/fs/UnixFileSystem.java @@ -34,7 +34,6 @@ import java.nio.file.FileSystem; import java.nio.file.FileSystemException; import java.nio.file.LinkOption; -import java.nio.file.LinkPermission; import java.nio.file.Path; import java.nio.file.PathMatcher; import java.nio.file.StandardCopyOption; @@ -54,7 +53,6 @@ import java.util.regex.Pattern; import sun.nio.ch.DirectBuffer; import sun.nio.ch.IOStatus; -import sun.security.action.GetPropertyAction; import static sun.nio.fs.UnixConstants.*; import static sun.nio.fs.UnixNativeDispatcher.*; @@ -87,8 +85,7 @@ abstract class UnixFileSystem // if process-wide chdir is allowed or default directory is not the // process working directory then paths must be resolved against the // default directory. - String propValue = GetPropertyAction - .privilegedGetProperty("sun.nio.fs.chdirAllowed", "false"); + String propValue = System.getProperty("sun.nio.fs.chdirAllowed", "false"); boolean chdirAllowed = propValue.isEmpty() ? true : Boolean.parseBoolean(propValue); if (chdirAllowed) { this.needToResolveAgainstDefaultDirectory = true; @@ -179,20 +176,7 @@ void copyNonPosixAttributes(int sfd, int tfd) { */ @Override public final Iterable<Path> getRootDirectories() { - final List<Path> allowedList = List.of(rootDirectory); - return new Iterable<>() { - public Iterator<Path> iterator() { - try { - @SuppressWarnings("removal") - SecurityManager sm = System.getSecurityManager(); - if (sm != null) - sm.checkRead(rootDirectory.toString()); - return allowedList.iterator(); - } catch (SecurityException x) { - return Collections.emptyIterator(); //disallowed - } - } - }; + return List.of(rootDirectory); } /** @@ -228,16 +212,6 @@ private FileStore readNext() { if (entry.isIgnored()) continue; - // check permission to read mount point - @SuppressWarnings("removal") - SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - try { - sm.checkRead(Util.toString(entry.dir())); - } catch (SecurityException x) { - continue; - } - } try { return getFileStore(entry); } catch (IOException ignore) { @@ -275,20 +249,7 @@ public void remove() { @Override public final Iterable<FileStore> getFileStores() { - @SuppressWarnings("removal") - SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - try { - sm.checkPermission(new RuntimePermission("getFileStoreAttributes")); - } catch (SecurityException se) { - return Collections.emptyList(); - } - } - return new Iterable<>() { - public Iterator<FileStore> iterator() { - return new FileStoreIterator(); - } - }; + return FileStoreIterator::new; } @Override @@ -845,14 +806,6 @@ static void ensureEmptyDir(UnixPath dir) throws IOException { void move(UnixPath source, UnixPath target, CopyOption... options) throws IOException { - // permission check - @SuppressWarnings("removal") - SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - source.checkWrite(); - target.checkWrite(); - } - // translate options into flags Flags flags = Flags.fromMoveOptions(options); @@ -988,14 +941,6 @@ void copy(final UnixPath source, final UnixPath target, CopyOption... options) throws IOException { - // permission checks - @SuppressWarnings("removal") - SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - source.checkRead(); - target.checkWrite(); - } - // translate options into flags final Flags flags = Flags.fromCopyOptions(options); @@ -1009,11 +954,6 @@ void copy(final UnixPath source, x.rethrowAsIOException(source); } - // if source file is symbolic link then we must check LinkPermission - if (sm != null && sourceAttrs.isSymbolicLink()) { - sm.checkPermission(new LinkPermission("symbolic")); - } - // ensure source can be copied if (!sourceAttrs.isSymbolicLink() || flags.followLinks) { // the access(2) system call always follows links so it diff --git a/src/java.base/unix/classes/sun/nio/fs/UnixFileSystemProvider.java b/src/java.base/unix/classes/sun/nio/fs/UnixFileSystemProvider.java index 7b3bca3acac..ed846354ea0 100644 --- a/src/java.base/unix/classes/sun/nio/fs/UnixFileSystemProvider.java +++ b/src/java.base/unix/classes/sun/nio/fs/UnixFileSystemProvider.java @@ -40,7 +40,6 @@ import java.nio.file.FileSystem; import java.nio.file.FileSystemAlreadyExistsException; import java.nio.file.LinkOption; -import java.nio.file.LinkPermission; import java.nio.file.NotDirectoryException; import java.nio.file.NotLinkException; import java.nio.file.OpenOption; @@ -59,7 +58,6 @@ import jdk.internal.util.StaticProperty; import sun.nio.ch.ThreadPool; -import sun.security.util.SecurityConstants; import static sun.nio.fs.UnixNativeDispatcher.*; import static sun.nio.fs.UnixConstants.*; @@ -171,7 +169,6 @@ public <A extends BasicFileAttributes> A readAttributesIfExists(Path path, { if (type == BasicFileAttributes.class && Util.followLinks(options)) { UnixPath file = UnixPath.toUnixPath(path); - file.checkRead(); try { @SuppressWarnings("unchecked") A attrs = (A) UnixFileAttributes.getIfExists(file); @@ -250,7 +247,6 @@ public SeekableByteChannel newByteChannel(Path obj, @Override boolean implDelete(Path obj, boolean failIfNotExists) throws IOException { UnixPath file = UnixPath.toUnixPath(obj); - file.checkDelete(); // need file attributes to know if file is directory UnixFileAttributes attrs = null; @@ -317,20 +313,12 @@ public void checkAccess(Path obj, AccessMode... modes) throws IOException { int mode = 0; if (e || r) { - file.checkRead(); mode |= (r) ? R_OK : F_OK; } if (w) { - file.checkWrite(); mode |= W_OK; } if (x) { - @SuppressWarnings("removal") - SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - // not cached - sm.checkExec(file.getPathForPermissionCheck()); - } mode |= X_OK; } int errno = access(file, mode); @@ -341,26 +329,18 @@ public void checkAccess(Path obj, AccessMode... modes) throws IOException { @Override public boolean isReadable(Path path) { UnixPath file = UnixPath.toUnixPath(path); - file.checkRead(); return access(file, R_OK) == 0; } @Override public boolean isWritable(Path path) { UnixPath file = UnixPath.toUnixPath(path); - file.checkWrite(); return access(file, W_OK) == 0; } @Override public boolean isExecutable(Path path) { UnixPath file = UnixPath.toUnixPath(path); - @SuppressWarnings("removal") - SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - // not cached - sm.checkExec(file.getPathForPermissionCheck()); - } return access(file, X_OK) == 0; } @@ -374,10 +354,6 @@ public boolean isSameFile(Path obj1, Path obj2) throws IOException { if (!(obj2 instanceof UnixPath file2)) return false; - // check security manager access to both files - file1.checkRead(); - file2.checkRead(); - UnixFileAttributes attrs1; UnixFileAttributes attrs2; try { @@ -398,7 +374,6 @@ public boolean isSameFile(Path obj1, Path obj2) throws IOException { @Override public boolean isHidden(Path obj) { UnixPath file = UnixPath.toUnixPath(obj); - file.checkRead(); UnixPath name = file.getFileName(); if (name == null) return false; @@ -421,12 +396,6 @@ public boolean isHidden(Path obj) { @Override public FileStore getFileStore(Path obj) throws IOException { UnixPath file = UnixPath.toUnixPath(obj); - @SuppressWarnings("removal") - SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - sm.checkPermission(new RuntimePermission("getFileStoreAttributes")); - file.checkRead(); - } return getFileStore(file); } @@ -435,7 +404,6 @@ public void createDirectory(Path obj, FileAttribute<?>... attrs) throws IOException { UnixPath dir = UnixPath.toUnixPath(obj); - dir.checkWrite(); int mode = UnixFileModeAttribute.toUnixMode(UnixFileModeAttribute.ALL_PERMISSIONS, attrs); try { @@ -453,7 +421,6 @@ public DirectoryStream<Path> newDirectoryStream(Path obj, DirectoryStream.Filter throws IOException { UnixPath dir = UnixPath.toUnixPath(obj); - dir.checkRead(); if (filter == null) throw new NullPointerException(); @@ -506,14 +473,6 @@ public void createSymbolicLink(Path obj1, Path obj2, FileAttribute<?>... attrs) " not supported when creating symbolic link"); } - // permission check - @SuppressWarnings("removal") - SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - sm.checkPermission(new LinkPermission("symbolic")); - link.checkWrite(); - } - // create link try { symlink(target.asByteArray(), link); @@ -527,14 +486,6 @@ public void createLink(Path obj1, Path obj2) throws IOException { UnixPath link = UnixPath.toUnixPath(obj1); UnixPath existing = UnixPath.toUnixPath(obj2); - // permission check - @SuppressWarnings("removal") - SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - sm.checkPermission(new LinkPermission("hard")); - link.checkWrite(); - existing.checkWrite(); - } try { link(existing, link); } catch (UnixException x) { @@ -545,14 +496,6 @@ public void createLink(Path obj1, Path obj2) throws IOException { @Override public Path readSymbolicLink(Path obj1) throws IOException { UnixPath link = UnixPath.toUnixPath(obj1); - // permission check - @SuppressWarnings("removal") - SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - FilePermission perm = new FilePermission(link.getPathForPermissionCheck(), - SecurityConstants.FILE_READLINK_ACTION); - sm.checkPermission(perm); - } try { byte[] target = readlink(link); return new UnixPath(link.getFileSystem(), target); @@ -568,7 +511,6 @@ public Path readSymbolicLink(Path obj1) throws IOException { public boolean exists(Path path, LinkOption... options) { if (Util.followLinks(options)) { UnixPath file = UnixPath.toUnixPath(path); - file.checkRead(); return access(file, F_OK) == 0; } else { return super.exists(path, options); diff --git a/src/java.base/unix/classes/sun/nio/fs/UnixPath.java b/src/java.base/unix/classes/sun/nio/fs/UnixPath.java index 7898acdc452..e2f52e701cb 100644 --- a/src/java.base/unix/classes/sun/nio/fs/UnixPath.java +++ b/src/java.base/unix/classes/sun/nio/fs/UnixPath.java @@ -833,47 +833,18 @@ int openForAttributeAccess(boolean followLinks) throws UnixException { return open(this, flags, 0); } - void checkRead() { - @SuppressWarnings("removal") - SecurityManager sm = System.getSecurityManager(); - if (sm != null) - sm.checkRead(getPathForPermissionCheck()); - } - - void checkWrite() { - @SuppressWarnings("removal") - SecurityManager sm = System.getSecurityManager(); - if (sm != null) - sm.checkWrite(getPathForPermissionCheck()); - } - - void checkDelete() { - @SuppressWarnings("removal") - SecurityManager sm = System.getSecurityManager(); - if (sm != null) - sm.checkDelete(getPathForPermissionCheck()); - } - @Override public UnixPath toAbsolutePath() { if (isAbsolute()) { return this; } - // The path is relative so need to resolve against default directory, - // taking care not to reveal the user.dir - @SuppressWarnings("removal") - SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - sm.checkPropertyAccess("user.dir"); - } + // The path is relative so need to resolve against default directory return new UnixPath(getFileSystem(), resolve(getFileSystem().defaultDirectory(), path)); } @Override public Path toRealPath(LinkOption... options) throws IOException { - checkRead(); - UnixPath absolute = toAbsolutePath(); // if resolving links then use realpath @@ -1022,7 +993,6 @@ public WatchKey register(WatchService watcher, throw new NullPointerException(); if (!(watcher instanceof AbstractWatchService)) throw new ProviderMismatchException(); - checkRead(); return ((AbstractWatchService)watcher).register(this, events, modifiers); } } diff --git a/src/java.base/unix/classes/sun/nio/fs/UnixSecureDirectoryStream.java b/src/java.base/unix/classes/sun/nio/fs/UnixSecureDirectoryStream.java index 9497ca3644e..ce04f49a9e2 100644 --- a/src/java.base/unix/classes/sun/nio/fs/UnixSecureDirectoryStream.java +++ b/src/java.base/unix/classes/sun/nio/fs/UnixSecureDirectoryStream.java @@ -25,12 +25,12 @@ package sun.nio.fs; +import java.io.IOException; +import java.nio.channels.SeekableByteChannel; import java.nio.file.*; import java.nio.file.attribute.*; -import java.nio.channels.SeekableByteChannel; import java.util.*; import java.util.concurrent.TimeUnit; -import java.io.IOException; import static sun.nio.fs.UnixNativeDispatcher.*; import static sun.nio.fs.UnixConstants.*; @@ -93,13 +93,6 @@ public SecureDirectoryStream<Path> newDirectoryStream(Path obj, UnixPath child = ds.directory().resolve(file); boolean followLinks = Util.followLinks(options); - // permission check using name resolved against original path of directory - @SuppressWarnings("removal") - SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - child.checkRead(); - } - ds.readLock().lock(); try { if (!ds.isOpen()) @@ -146,15 +139,12 @@ public SeekableByteChannel newByteChannel(Path obj, int mode = UnixFileModeAttribute .toUnixMode(UnixFileModeAttribute.ALL_READWRITE, attrs); - // path for permission check - String pathToCheck = ds.directory().resolve(file).getPathForPermissionCheck(); - ds.readLock().lock(); try { if (!ds.isOpen()) throw new ClosedDirectoryStreamException(); try { - return UnixChannelFactory.newFileChannel(dfd, file, pathToCheck, options, mode); + return UnixChannelFactory.newFileChannel(dfd, file, options, mode); } catch (UnixException x) { x.rethrowAsIOException(file); return null; // keep compiler happy @@ -173,13 +163,6 @@ private void implDelete(Path obj, boolean haveFlags, int flags) { UnixPath file = getName(obj); - // permission check using name resolved against original path of directory - @SuppressWarnings("removal") - SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - ds.directory().resolve(file).checkDelete(); - } - ds.readLock().lock(); try { if (!ds.isOpen()) @@ -239,14 +222,6 @@ public void move(Path fromObj, SecureDirectoryStream<Path> dir, Path toObj) throw new ProviderMismatchException(); UnixSecureDirectoryStream that = (UnixSecureDirectoryStream)dir; - // permission check - @SuppressWarnings("removal") - SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - this.ds.directory().resolve(from).checkWrite(); - that.ds.directory().resolve(to).checkWrite(); - } - // lock ordering doesn't matter this.ds.readLock().lock(); try { @@ -337,18 +312,6 @@ int open() throws IOException { } } - private void checkWriteAccess() { - @SuppressWarnings("removal") - SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - if (file == null) { - ds.directory().checkWrite(); - } else { - ds.directory().resolve(file).checkWrite(); - } - } - } - @Override public String name() { return "basic"; @@ -361,15 +324,6 @@ public BasicFileAttributes readAttributes() throws IOException { if (!ds.isOpen()) throw new ClosedDirectoryStreamException(); - @SuppressWarnings("removal") - SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - if (file == null) { - ds.directory().checkRead(); - } else { - ds.directory().resolve(file).checkRead(); - } - } try { UnixFileAttributes attrs = (file == null) ? UnixFileAttributes.get(dfd) : @@ -392,8 +346,6 @@ public void setTimes(FileTime lastModifiedTime, FileTime createTime) // ignore throws IOException { - checkWriteAccess(); - ds.readLock().lock(); try { if (!ds.isOpen()) @@ -441,15 +393,6 @@ private class PosixFileAttributeViewImpl super(file, followLinks); } - private void checkWriteAndUserAccess() { - @SuppressWarnings("removal") - SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - super.checkWriteAccess(); - sm.checkPermission(new RuntimePermission("accessUserInformation")); - } - } - @Override public String name() { return "posix"; @@ -457,16 +400,6 @@ public String name() { @Override public PosixFileAttributes readAttributes() throws IOException { - @SuppressWarnings("removal") - SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - if (file == null) - ds.directory().checkRead(); - else - ds.directory().resolve(file).checkRead(); - sm.checkPermission(new RuntimePermission("accessUserInformation")); - } - ds.readLock().lock(); try { if (!ds.isOpen()) @@ -490,9 +423,6 @@ public PosixFileAttributes readAttributes() throws IOException { public void setPermissions(Set<PosixFilePermission> perms) throws IOException { - // permission check - checkWriteAndUserAccess(); - ds.readLock().lock(); try { if (!ds.isOpen()) @@ -513,9 +443,6 @@ public void setPermissions(Set<PosixFilePermission> perms) } private void setOwners(int uid, int gid) throws IOException { - // permission check - checkWriteAndUserAccess(); - ds.readLock().lock(); try { if (!ds.isOpen()) diff --git a/src/java.base/unix/classes/sun/nio/fs/UnixUriUtils.java b/src/java.base/unix/classes/sun/nio/fs/UnixUriUtils.java index 2cbc4c377a2..269e8b8f1fd 100644 --- a/src/java.base/unix/classes/sun/nio/fs/UnixUriUtils.java +++ b/src/java.base/unix/classes/sun/nio/fs/UnixUriUtils.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -121,12 +121,11 @@ static URI toUri(UnixPath up) { // trailing slash if directory if (sb.charAt(sb.length()-1) != '/') { try { - up.checkRead(); UnixFileAttributes attrs = UnixFileAttributes.getIfExists(up); if (attrs != null && ((attrs.mode() & UnixConstants.S_IFMT) == UnixConstants.S_IFDIR)) sb.append('/'); - } catch (UnixException | SecurityException ignore) { } + } catch (UnixException ignore) { } } try { diff --git a/src/java.base/unix/classes/sun/nio/fs/UnixUserDefinedFileAttributeView.java b/src/java.base/unix/classes/sun/nio/fs/UnixUserDefinedFileAttributeView.java index e814dde3229..5b8d50dabf2 100644 --- a/src/java.base/unix/classes/sun/nio/fs/UnixUserDefinedFileAttributeView.java +++ b/src/java.base/unix/classes/sun/nio/fs/UnixUserDefinedFileAttributeView.java @@ -25,9 +25,9 @@ package sun.nio.fs; +import java.io.IOException; import java.nio.file.*; import java.nio.ByteBuffer; -import java.io.IOException; import java.util.*; import jdk.internal.access.JavaNioAccess; @@ -114,12 +114,8 @@ private static List<String> list(int fd, int bufSize) throws UnixException { } } - @SuppressWarnings("removal") @Override public List<String> list() throws IOException { - if (System.getSecurityManager() != null) - checkAccess(file.getPathForPermissionCheck(), true, false); - int fd = -1; try { fd = file.openForAttributeAccess(followLinks); @@ -141,12 +137,8 @@ public List<String> list() throws IOException { } } - @SuppressWarnings("removal") @Override public int size(String name) throws IOException { - if (System.getSecurityManager() != null) - checkAccess(file.getPathForPermissionCheck(), true, false); - int fd = -1; try { fd = file.openForAttributeAccess(followLinks); @@ -165,12 +157,8 @@ public int size(String name) throws IOException { } } - @SuppressWarnings("removal") @Override public int read(String name, ByteBuffer dst) throws IOException { - if (System.getSecurityManager() != null) - checkAccess(file.getPathForPermissionCheck(), true, false); - if (dst.isReadOnly()) throw new IllegalArgumentException("Read-only buffer"); int pos = dst.position(); @@ -230,12 +218,8 @@ private int read(String name, long address, int rem) throws IOException { } } - @SuppressWarnings("removal") @Override public int write(String name, ByteBuffer src) throws IOException { - if (System.getSecurityManager() != null) - checkAccess(file.getPathForPermissionCheck(), false, true); - int pos = src.position(); int lim = src.limit(); assert (pos <= lim); @@ -293,12 +277,8 @@ private void write(String name, long address, int rem) throws IOException { } } - @SuppressWarnings("removal") @Override public void delete(String name) throws IOException { - if (System.getSecurityManager() != null) - checkAccess(file.getPathForPermissionCheck(), false, true); - int fd = -1; try { fd = file.openForAttributeAccess(followLinks); diff --git a/src/java.base/unix/classes/sun/nio/fs/UnixUserPrincipals.java b/src/java.base/unix/classes/sun/nio/fs/UnixUserPrincipals.java index 26da60fe2f8..f50dea108b0 100644 --- a/src/java.base/unix/classes/sun/nio/fs/UnixUserPrincipals.java +++ b/src/java.base/unix/classes/sun/nio/fs/UnixUserPrincipals.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -132,11 +132,6 @@ public static Group fromGid(int gid) { private static int lookupName(String name, boolean isGroup) throws IOException { - @SuppressWarnings("removal") - SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - sm.checkPermission(new RuntimePermission("lookupUserInformation")); - } int id; try { id = (isGroup) ? getgrnam(name) : getpwnam(name); diff --git a/src/java.base/windows/classes/sun/nio/ch/DefaultSelectorProvider.java b/src/java.base/windows/classes/sun/nio/ch/DefaultSelectorProvider.java index 0133d82986f..1da43697eaf 100644 --- a/src/java.base/windows/classes/sun/nio/ch/DefaultSelectorProvider.java +++ b/src/java.base/windows/classes/sun/nio/ch/DefaultSelectorProvider.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,20 +25,12 @@ package sun.nio.ch; -import java.security.AccessController; -import java.security.PrivilegedAction; - /** * Creates this platform's default SelectorProvider */ -@SuppressWarnings("removal") public class DefaultSelectorProvider { - private static final SelectorProviderImpl INSTANCE; - static { - PrivilegedAction<SelectorProviderImpl> pa = WEPollSelectorProvider::new; - INSTANCE = AccessController.doPrivileged(pa); - } + private static final SelectorProviderImpl INSTANCE = new WEPollSelectorProvider(); /** * Prevent instantiation. diff --git a/src/java.base/windows/classes/sun/nio/ch/PipeImpl.java b/src/java.base/windows/classes/sun/nio/ch/PipeImpl.java index 67a344a663d..7e138a5cc11 100644 --- a/src/java.base/windows/classes/sun/nio/ch/PipeImpl.java +++ b/src/java.base/windows/classes/sun/nio/ch/PipeImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -39,9 +39,6 @@ import java.nio.file.Files; import java.nio.file.Path; import java.nio.channels.spi.*; -import java.security.AccessController; -import java.security.PrivilegedExceptionAction; -import java.security.PrivilegedActionException; import java.security.SecureRandom; import java.util.Random; @@ -64,10 +61,7 @@ class PipeImpl private final SourceChannelImpl source; private final SinkChannelImpl sink; - private static class Initializer - implements PrivilegedExceptionAction<Void> - { - + private static class Initializer { private final SelectorProvider sp; private final boolean preferUnixDomain; private IOException ioe; @@ -79,8 +73,7 @@ private Initializer(SelectorProvider sp, boolean preferUnixDomain) { this.preferUnixDomain = preferUnixDomain; } - @Override - public Void run() throws IOException { + public void init() throws IOException { LoopbackConnector connector = new LoopbackConnector(); connector.run(); if (ioe instanceof ClosedByInterruptException) { @@ -101,8 +94,6 @@ public void interrupt() {} if (ioe != null) throw new IOException("Unable to establish loopback connection", ioe); - - return null; } private class LoopbackConnector implements Runnable { @@ -190,17 +181,12 @@ public void run() { * * @param buffering if false set TCP_NODELAY on TCP sockets */ - @SuppressWarnings("removal") PipeImpl(SelectorProvider sp, boolean preferAfUnix, boolean buffering) throws IOException { Initializer initializer = new Initializer(sp, preferAfUnix); - try { - AccessController.doPrivileged(initializer); - SinkChannelImpl sink = initializer.sink; - if (sink.isNetSocket() && !buffering) { - sink.setOption(StandardSocketOptions.TCP_NODELAY, true); - } - } catch (PrivilegedActionException pae) { - throw (IOException) pae.getCause(); + initializer.init(); + SinkChannelImpl sink = initializer.sink; + if (sink.isNetSocket() && !buffering) { + sink.setOption(StandardSocketOptions.TCP_NODELAY, true); } this.source = initializer.source; this.sink = initializer.sink; diff --git a/src/java.base/windows/classes/sun/nio/ch/UnixDomainSocketsUtil.java b/src/java.base/windows/classes/sun/nio/ch/UnixDomainSocketsUtil.java index fd51e4540fd..43d790e5411 100644 --- a/src/java.base/windows/classes/sun/nio/ch/UnixDomainSocketsUtil.java +++ b/src/java.base/windows/classes/sun/nio/ch/UnixDomainSocketsUtil.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -27,8 +27,6 @@ import java.nio.charset.Charset; import java.nio.charset.StandardCharsets; -import java.security.AccessController; -import java.security.PrivilegedAction; import sun.net.NetProperties; import jdk.internal.util.StaticProperty; @@ -50,20 +48,16 @@ static Charset getCharset() { * 3. %TEMP% * 4. ${java.io.tmpdir} */ - @SuppressWarnings("removal") static String getTempDir() { - PrivilegedAction<String> action = () -> { - String s = NetProperties.get("jdk.net.unixdomain.tmpdir"); - if (s != null) { - return s; - } - String temp = System.getenv("TEMP"); - if (temp != null) { - return temp; - } - return StaticProperty.javaIoTmpDir(); - }; - return AccessController.doPrivileged(action); + String s = NetProperties.get("jdk.net.unixdomain.tmpdir"); + if (s != null) { + return s; + } + String temp = System.getenv("TEMP"); + if (temp != null) { + return temp; + } + return StaticProperty.javaIoTmpDir(); } } diff --git a/src/java.base/windows/classes/sun/nio/ch/WindowsAsynchronousServerSocketChannelImpl.java b/src/java.base/windows/classes/sun/nio/ch/WindowsAsynchronousServerSocketChannelImpl.java index 53c2219368c..9f84a5089fa 100644 --- a/src/java.base/windows/classes/sun/nio/ch/WindowsAsynchronousServerSocketChannelImpl.java +++ b/src/java.base/windows/classes/sun/nio/ch/WindowsAsynchronousServerSocketChannelImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -30,9 +30,6 @@ import java.util.concurrent.Future; import java.util.concurrent.atomic.AtomicBoolean; import java.io.IOException; -import java.security.AccessControlContext; -import java.security.AccessController; -import java.security.PrivilegedAction; import jdk.internal.misc.Unsafe; /** @@ -115,16 +112,12 @@ public AsynchronousChannelGroupImpl group() { */ private class AcceptTask implements Runnable, Iocp.ResultHandler { private final WindowsAsynchronousSocketChannelImpl channel; - @SuppressWarnings("removal") - private final AccessControlContext acc; private final PendingFuture<AsynchronousSocketChannel,Object> result; AcceptTask(WindowsAsynchronousSocketChannelImpl channel, - @SuppressWarnings("removal") AccessControlContext acc, PendingFuture<AsynchronousSocketChannel,Object> result) { this.channel = channel; - this.acc = acc; this.result = result; } @@ -139,7 +132,6 @@ void closeChildChannel() { } // caller must have acquired read lock for the listener and child channel. - @SuppressWarnings("removal") void finishAccept() throws IOException { /** * Set local/remote addresses. This is currently very inefficient @@ -151,18 +143,6 @@ void finishAccept() throws IOException { InetSocketAddress local = Net.localAddress(channel.fd); final InetSocketAddress remote = Net.remoteAddress(channel.fd); channel.setConnected(local, remote); - - // permission check (in context of initiating thread) - if (acc != null) { - AccessController.doPrivileged(new PrivilegedAction<Void>() { - public Void run() { - SecurityManager sm = System.getSecurityManager(); - sm.checkAccept(remote.getAddress().getHostAddress(), - remote.getPort()); - return null; - } - }, acc); - } } /** @@ -207,7 +187,7 @@ public void run() { closeChildChannel(); if (x instanceof ClosedChannelException) x = new AsynchronousCloseException(); - if (!(x instanceof IOException) && !(x instanceof SecurityException)) + if (!(x instanceof IOException)) x = new IOException(x); enableAccept(); result.setFailure(x); @@ -259,7 +239,7 @@ public void completed(int bytesTransferred, boolean canInvokeDirect) { closeChildChannel(); if (x instanceof ClosedChannelException) x = new AsynchronousCloseException(); - if (!(x instanceof IOException) && !(x instanceof SecurityException)) + if (!(x instanceof IOException)) x = new IOException(x); result.setFailure(x); } @@ -328,16 +308,9 @@ Future<AsynchronousSocketChannel> implAccept(Object attachment, return null; } - // need calling context when there is security manager as - // permission check may be done in a different thread without - // any application call frames on the stack - @SuppressWarnings("removal") - AccessControlContext acc = (System.getSecurityManager() == null) ? - null : AccessController.getContext(); - PendingFuture<AsynchronousSocketChannel,Object> result = new PendingFuture<AsynchronousSocketChannel,Object>(this, handler, attachment); - AcceptTask task = new AcceptTask(ch, acc, result); + AcceptTask task = new AcceptTask(ch, result); result.setContext(task); // check and set flag to prevent concurrent accepting diff --git a/src/java.base/windows/classes/sun/nio/ch/WindowsAsynchronousSocketChannelImpl.java b/src/java.base/windows/classes/sun/nio/ch/WindowsAsynchronousSocketChannelImpl.java index 20fdfc46ae3..9f3916bad8c 100644 --- a/src/java.base/windows/classes/sun/nio/ch/WindowsAsynchronousSocketChannelImpl.java +++ b/src/java.base/windows/classes/sun/nio/ch/WindowsAsynchronousSocketChannelImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -31,9 +31,6 @@ import java.net.*; import java.util.concurrent.*; import java.io.IOException; -import java.security.AccessController; -import java.security.PrivilegedActionException; -import java.security.PrivilegedExceptionAction; import jdk.internal.misc.Unsafe; import sun.net.util.SocketExceptions; @@ -308,20 +305,6 @@ public void failed(int error, IOException x) { } } - @SuppressWarnings("removal") - private void doPrivilegedBind(final SocketAddress sa) throws IOException { - try { - AccessController.doPrivileged(new PrivilegedExceptionAction<Void>() { - public Void run() throws IOException { - bind(sa); - return null; - } - }); - } catch (PrivilegedActionException e) { - throw (IOException) e.getException(); - } - } - @Override <A> Future<Void> implConnect(SocketAddress remote, A attachment, @@ -337,12 +320,6 @@ <A> Future<Void> implConnect(SocketAddress remote, InetSocketAddress isa = Net.checkAddress(remote); - // permission check - @SuppressWarnings("removal") - SecurityManager sm = System.getSecurityManager(); - if (sm != null) - sm.checkConnect(isa.getAddress().getHostAddress(), isa.getPort()); - // check and update state // ConnectEx requires the socket to be bound to a local address IOException bindException = null; @@ -354,11 +331,7 @@ <A> Future<Void> implConnect(SocketAddress remote, if (localAddress == null) { try { SocketAddress any = new InetSocketAddress(0); - if (sm == null) { - bind(any); - } else { - doPrivilegedBind(any); - } + bind(any); } catch (IOException x) { bindException = x; } diff --git a/src/java.base/windows/classes/sun/nio/fs/WindowsAclFileAttributeView.java b/src/java.base/windows/classes/sun/nio/fs/WindowsAclFileAttributeView.java index d22c7aaba86..99898549dc8 100644 --- a/src/java.base/windows/classes/sun/nio/fs/WindowsAclFileAttributeView.java +++ b/src/java.base/windows/classes/sun/nio/fs/WindowsAclFileAttributeView.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -61,22 +61,6 @@ class WindowsAclFileAttributeView this.followLinks = followLinks; } - // permission check - private void checkAccess(WindowsPath file, - boolean checkRead, - boolean checkWrite) - { - @SuppressWarnings("removal") - SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - if (checkRead) - sm.checkRead(file.getPathForPermissionCheck()); - if (checkWrite) - sm.checkWrite(file.getPathForPermissionCheck()); - sm.checkPermission(new RuntimePermission("accessUserInformation")); - } - } - // invokes GetFileSecurity to get requested security information static NativeBuffer getFileSecurity(String path, int request) throws IOException @@ -114,8 +98,6 @@ static NativeBuffer getFileSecurity(String path, int request) public UserPrincipal getOwner() throws IOException { - checkAccess(file, true, false); - // GetFileSecurity does not follow links so when following links we // need the final target String path = WindowsLinkSupport.getFinalPath(file, followLinks); @@ -135,8 +117,6 @@ public UserPrincipal getOwner() public List<AclEntry> getAcl() throws IOException { - checkAccess(file, true, false); - // GetFileSecurity does not follow links so when following links we // need the final target String path = WindowsLinkSupport.getFinalPath(file, followLinks); @@ -158,9 +138,6 @@ public void setOwner(UserPrincipal obj) throw new ProviderMismatchException(); WindowsUserPrincipals.User owner = (WindowsUserPrincipals.User)obj; - // permission check - checkAccess(file, false, true); - // SetFileSecurity does not follow links so when following links we // need the final target String path = WindowsLinkSupport.getFinalPath(file, followLinks); @@ -199,8 +176,6 @@ public void setOwner(UserPrincipal obj) @Override public void setAcl(List<AclEntry> acl) throws IOException { - checkAccess(file, false, true); - // SetFileSecurity does not follow links so when following links we // need the final target String path = WindowsLinkSupport.getFinalPath(file, followLinks); diff --git a/src/java.base/windows/classes/sun/nio/fs/WindowsChannelFactory.java b/src/java.base/windows/classes/sun/nio/fs/WindowsChannelFactory.java index 59db82d3fab..75d68f938c1 100644 --- a/src/java.base/windows/classes/sun/nio/fs/WindowsChannelFactory.java +++ b/src/java.base/windows/classes/sun/nio/fs/WindowsChannelFactory.java @@ -139,11 +139,8 @@ static Flags toFlags(Set<? extends OpenOption> options) { * * @param pathForWindows * The path of the file to open/create - * @param pathToCheck - * The path used for permission checks (if security manager) */ static FileChannel newFileChannel(String pathForWindows, - String pathToCheck, Set<? extends OpenOption> options, long pSecurityDescriptor) throws WindowsException @@ -165,7 +162,7 @@ static FileChannel newFileChannel(String pathForWindows, if (flags.append && flags.truncateExisting) throw new IllegalArgumentException("APPEND + TRUNCATE_EXISTING not allowed"); - FileDescriptor fdObj = open(pathForWindows, pathToCheck, flags, pSecurityDescriptor); + FileDescriptor fdObj = open(pathForWindows, flags, pSecurityDescriptor); return FileChannelImpl.open(fdObj, pathForWindows, flags.read, flags.write, (flags.sync || flags.dsync), flags.direct, null); } @@ -175,13 +172,10 @@ static FileChannel newFileChannel(String pathForWindows, * * @param pathForWindows * The path of the file to open/create - * @param pathToCheck - * The path used for permission checks (if security manager) * @param pool * The thread pool that the channel is associated with */ static AsynchronousFileChannel newAsynchronousFileChannel(String pathForWindows, - String pathToCheck, Set<? extends OpenOption> options, long pSecurityDescriptor, ThreadPool pool) @@ -204,7 +198,7 @@ static AsynchronousFileChannel newAsynchronousFileChannel(String pathForWindows, // open file for overlapped I/O FileDescriptor fdObj; try { - fdObj = open(pathForWindows, pathToCheck, flags, pSecurityDescriptor); + fdObj = open(pathForWindows, flags, pSecurityDescriptor); } catch (WindowsException x) { x.rethrowAsIOException(pathForWindows); return null; @@ -226,7 +220,6 @@ static AsynchronousFileChannel newAsynchronousFileChannel(String pathForWindows, * encapsulating the handle to the open file. */ private static FileDescriptor open(String pathForWindows, - String pathToCheck, Flags flags, long pSecurityDescriptor) throws WindowsException @@ -291,20 +284,6 @@ private static FileDescriptor open(String pathForWindows, dwFlagsAndAttributes |= FILE_FLAG_OPEN_REPARSE_POINT; } - // permission check - if (pathToCheck != null) { - @SuppressWarnings("removal") - SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - if (flags.read) - sm.checkRead(pathToCheck); - if (flags.write) - sm.checkWrite(pathToCheck); - if (flags.deleteOnClose) - sm.checkDelete(pathToCheck); - } - } - // open file long handle = CreateFile(pathForWindows, dwDesiredAccess, diff --git a/src/java.base/windows/classes/sun/nio/fs/WindowsFileAttributeViews.java b/src/java.base/windows/classes/sun/nio/fs/WindowsFileAttributeViews.java index 2db3c912d39..9a6c0cf3764 100644 --- a/src/java.base/windows/classes/sun/nio/fs/WindowsFileAttributeViews.java +++ b/src/java.base/windows/classes/sun/nio/fs/WindowsFileAttributeViews.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -46,7 +46,6 @@ private static class Basic extends AbstractBasicFileAttributeView { @Override public WindowsFileAttributes readAttributes() throws IOException { - file.checkRead(); try { return WindowsFileAttributes.get(file, followLinks); } catch (WindowsException x) { @@ -110,7 +109,7 @@ void setFileTimes(long createTime, // retry succeeded x = null; } - } catch (SecurityException | WindowsException | IOException ignore) { + } catch (WindowsException | IOException ignore) { // ignore exceptions to let original exception be thrown } } @@ -134,9 +133,6 @@ public void setTimes(FileTime lastModifiedTime, return; } - // permission check - file.checkWrite(); - // update times long t1 = (createTime == null) ? -1L : WindowsFileAttributes.toWindowsTime(createTime); @@ -219,8 +215,6 @@ public Map<String,Object> readAttributes(String[] attributes) private void updateAttributes(int flag, boolean enable) throws IOException { - file.checkWrite(); - // GetFileAttributes & SetFileAttributes do not follow links so when // following links we need the final target String path = WindowsLinkSupport.getFinalPath(file, followLinks); diff --git a/src/java.base/windows/classes/sun/nio/fs/WindowsFileCopy.java b/src/java.base/windows/classes/sun/nio/fs/WindowsFileCopy.java index 8ad69662822..16bb2898a8d 100644 --- a/src/java.base/windows/classes/sun/nio/fs/WindowsFileCopy.java +++ b/src/java.base/windows/classes/sun/nio/fs/WindowsFileCopy.java @@ -84,15 +84,6 @@ static void copy(final WindowsPath source, throw new UnsupportedOperationException("Unsupported copy option: " + option); } - // check permissions. If the source file is a symbolic link then - // later we must also check LinkPermission - @SuppressWarnings("removal") - SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - source.checkRead(); - target.checkWrite(); - } - // get attributes of source file // attempt to get attributes of target file // if both files are the same there is nothing to do @@ -144,11 +135,6 @@ static void copy(final WindowsPath source, CloseHandle(sourceHandle); } - // if source file is a symbolic link then we must check for LinkPermission - if (sm != null && sourceAttrs.isSymbolicLink()) { - sm.checkPermission(new LinkPermission("symbolic")); - } - // if source is a Unix domain socket, we don't want to copy it for various // reasons including consistency with Unix if (sourceAttrs.isUnixDomainSocket()) { @@ -308,13 +294,6 @@ static void move(WindowsPath source, WindowsPath target, CopyOption... options) throw new UnsupportedOperationException("Unsupported option: " + option); } - @SuppressWarnings("removal") - SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - source.checkWrite(); - target.checkWrite(); - } - final String sourcePath = asWin32Path(source); final String targetPath = asWin32Path(target); diff --git a/src/java.base/windows/classes/sun/nio/fs/WindowsFileSystem.java b/src/java.base/windows/classes/sun/nio/fs/WindowsFileSystem.java index f2cded1b372..2788c0cf304 100644 --- a/src/java.base/windows/classes/sun/nio/fs/WindowsFileSystem.java +++ b/src/java.base/windows/classes/sun/nio/fs/WindowsFileSystem.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -101,23 +101,14 @@ public Iterable<Path> getRootDirectories() { throw new AssertionError(x.getMessage()); } - // iterate over roots, ignoring those that the security manager denies + // iterate over roots ArrayList<Path> result = new ArrayList<>(); - @SuppressWarnings("removal") - SecurityManager sm = System.getSecurityManager(); for (int i = 0; i <= 25; i++) { // 0->A, 1->B, 2->C... if ((drives & (1 << i)) != 0) { StringBuilder sb = new StringBuilder(3); sb.append((char)('A' + i)); sb.append(":\\"); String root = sb.toString(); - if (sm != null) { - try { - sm.checkRead(root); - } catch (SecurityException x) { - continue; - } - } result.add(WindowsPath.createFromNormalizedPath(this, root)); } } @@ -141,12 +132,6 @@ private FileStore readNext() { if (!roots.hasNext()) return null; WindowsPath root = (WindowsPath)roots.next(); - // ignore if security manager denies access - try { - root.checkRead(); - } catch (SecurityException x) { - continue; - } try { FileStore fs = WindowsFileStore.create(root.toString(), true); if (fs != null) @@ -186,20 +171,7 @@ public void remove() { @Override public Iterable<FileStore> getFileStores() { - @SuppressWarnings("removal") - SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - try { - sm.checkPermission(new RuntimePermission("getFileStoreAttributes")); - } catch (SecurityException se) { - return Collections.emptyList(); - } - } - return new Iterable<FileStore>() { - public Iterator<FileStore> iterator() { - return new FileStoreIterator(); - } - }; + return FileStoreIterator::new; } // supported views diff --git a/src/java.base/windows/classes/sun/nio/fs/WindowsFileSystemProvider.java b/src/java.base/windows/classes/sun/nio/fs/WindowsFileSystemProvider.java index d76ad8b6f8e..7c280d87f62 100644 --- a/src/java.base/windows/classes/sun/nio/fs/WindowsFileSystemProvider.java +++ b/src/java.base/windows/classes/sun/nio/fs/WindowsFileSystemProvider.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -112,7 +112,6 @@ public FileChannel newFileChannel(Path path, try { return WindowsChannelFactory .newFileChannel(file.getPathForWin32Calls(), - file.getPathForPermissionCheck(), options, sd.address()); } catch (WindowsException x) { @@ -142,7 +141,6 @@ public AsynchronousFileChannel newAsynchronousFileChannel(Path path, try { return WindowsChannelFactory .newAsynchronousFileChannel(file.getPathForWin32Calls(), - file.getPathForPermissionCheck(), options, sd.address(), pool); @@ -227,7 +225,6 @@ public SeekableByteChannel newByteChannel(Path obj, try { return WindowsChannelFactory .newFileChannel(file.getPathForWin32Calls(), - file.getPathForPermissionCheck(), options, sd.address()); } catch (WindowsException x) { @@ -241,7 +238,6 @@ public SeekableByteChannel newByteChannel(Path obj, @Override boolean implDelete(Path obj, boolean failIfNotExists) throws IOException { WindowsPath file = WindowsPath.toWindowsPath(obj); - file.checkDelete(); WindowsFileAttributes attrs = null; try { @@ -324,7 +320,6 @@ private void checkReadAccess(WindowsPath file) throws IOException { Set<OpenOption> opts = Collections.emptySet(); FileChannel fc = WindowsChannelFactory .newFileChannel(file.getPathForWin32Calls(), - file.getPathForPermissionCheck(), opts, 0L); fc.close(); @@ -371,7 +366,6 @@ public void checkAccess(Path obj, AccessMode... modes) throws IOException { // check file exists only if (!(r || w || x)) { - file.checkRead(); try { WindowsFileAttributes.get(file, true); return; @@ -389,18 +383,12 @@ public void checkAccess(Path obj, AccessMode... modes) throws IOException { int mask = 0; if (r) { - file.checkRead(); mask |= FILE_READ_DATA; } if (w) { - file.checkWrite(); mask |= FILE_WRITE_DATA; } if (x) { - @SuppressWarnings("removal") - SecurityManager sm = System.getSecurityManager(); - if (sm != null) - sm.checkExec(file.getPathForPermissionCheck()); mask |= FILE_EXECUTE; } @@ -440,10 +428,6 @@ public boolean isSameFile(Path obj1, Path obj2) throws IOException { return false; WindowsPath file2 = (WindowsPath)obj2; - // check security manager access to both files - file1.checkRead(); - file2.checkRead(); - // open both files and see if they are the same long h1 = 0L; try { @@ -483,7 +467,6 @@ public boolean isSameFile(Path obj1, Path obj2) throws IOException { @Override public boolean isHidden(Path obj) throws IOException { WindowsPath file = WindowsPath.toWindowsPath(obj); - file.checkRead(); WindowsFileAttributes attrs = null; try { attrs = WindowsFileAttributes.get(file, true); @@ -496,12 +479,6 @@ public boolean isHidden(Path obj) throws IOException { @Override public FileStore getFileStore(Path obj) throws IOException { WindowsPath file = WindowsPath.toWindowsPath(obj); - @SuppressWarnings("removal") - SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - sm.checkPermission(new RuntimePermission("getFileStoreAttributes")); - file.checkRead(); - } return WindowsFileStore.create(file); } @@ -511,7 +488,6 @@ public void createDirectory(Path obj, FileAttribute<?>... attrs) throws IOException { WindowsPath dir = WindowsPath.toWindowsPath(obj); - dir.checkWrite(); WindowsSecurityDescriptor sd = WindowsSecurityDescriptor.fromAttribute(attrs); try { CreateDirectory(dir.getPathForWin32Calls(), sd.address()); @@ -535,7 +511,6 @@ public DirectoryStream<Path> newDirectoryStream(Path obj, DirectoryStream.Filter throws IOException { WindowsPath dir = WindowsPath.toWindowsPath(obj); - dir.checkRead(); if (filter == null) throw new NullPointerException(); return new WindowsDirectoryStream(dir, filter); @@ -555,14 +530,6 @@ public void createSymbolicLink(Path obj1, Path obj2, FileAttribute<?>... attrs) "not supported when creating symbolic link"); } - // permission check - @SuppressWarnings("removal") - SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - sm.checkPermission(new LinkPermission("symbolic")); - link.checkWrite(); - } - /** * Throw I/O exception for the drive-relative case because Windows * creates a link with the resolved target for this case. @@ -611,15 +578,6 @@ public void createLink(Path obj1, Path obj2) throws IOException { WindowsPath link = WindowsPath.toWindowsPath(obj1); WindowsPath existing = WindowsPath.toWindowsPath(obj2); - // permission check - @SuppressWarnings("removal") - SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - sm.checkPermission(new LinkPermission("hard")); - link.checkWrite(); - existing.checkWrite(); - } - // create hard link try { CreateHardLink(link.getPathForWin32Calls(), @@ -634,15 +592,6 @@ public Path readSymbolicLink(Path obj1) throws IOException { WindowsPath link = WindowsPath.toWindowsPath(obj1); WindowsFileSystem fs = link.getFileSystem(); - // permission check - @SuppressWarnings("removal") - SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - FilePermission perm = new FilePermission(link.getPathForPermissionCheck(), - SecurityConstants.FILE_READLINK_ACTION); - sm.checkPermission(perm); - } - String target = WindowsLinkSupport.readLink(link); return WindowsPath.createFromNormalizedPath(fs, target); } diff --git a/src/java.base/windows/classes/sun/nio/fs/WindowsLinkSupport.java b/src/java.base/windows/classes/sun/nio/fs/WindowsLinkSupport.java index 4ccd1d702bd..6ada2337cbb 100644 --- a/src/java.base/windows/classes/sun/nio/fs/WindowsLinkSupport.java +++ b/src/java.base/windows/classes/sun/nio/fs/WindowsLinkSupport.java @@ -28,8 +28,6 @@ import java.nio.file.*; import java.io.IOException; import java.io.IOError; -import java.security.AccessController; -import java.security.PrivilegedAction; import jdk.internal.misc.Unsafe; import static sun.nio.fs.WindowsNativeDispatcher.*; @@ -120,7 +118,6 @@ static String getFinalPath(WindowsPath input) throws IOException { * Returns the final path of a given path as a String. This should be used * prior to calling Win32 system calls that do not follow links. */ - @SuppressWarnings("removal") static String getFinalPath(WindowsPath input, boolean followLinks) throws IOException { @@ -164,12 +161,7 @@ static String getFinalPath(WindowsPath input, boolean followLinks) if (parent == null) { // no parent so use parent of absolute path final WindowsPath t = target; - target = AccessController - .doPrivileged(new PrivilegedAction<WindowsPath>() { - @Override - public WindowsPath run() { - return t.toAbsolutePath(); - }}); + target = t.toAbsolutePath(); parent = target.getParent(); } target = parent.resolve(link); diff --git a/src/java.base/windows/classes/sun/nio/fs/WindowsPath.java b/src/java.base/windows/classes/sun/nio/fs/WindowsPath.java index c3dc204bb9d..a085adefd68 100644 --- a/src/java.base/windows/classes/sun/nio/fs/WindowsPath.java +++ b/src/java.base/windows/classes/sun/nio/fs/WindowsPath.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -166,11 +166,6 @@ String getPathForExceptionMessage() { return path; } - // use this path for permission checks - String getPathForPermissionCheck() { - return path; - } - // use this path for Win32 calls // This method will prefix long paths with \\?\ or \\?\UNC as required. String getPathForWin32Calls() throws WindowsException { @@ -890,30 +885,6 @@ private long openSocketForReadAttributeAccess() } } - void checkRead() { - @SuppressWarnings("removal") - SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - sm.checkRead(getPathForPermissionCheck()); - } - } - - void checkWrite() { - @SuppressWarnings("removal") - SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - sm.checkWrite(getPathForPermissionCheck()); - } - } - - void checkDelete() { - @SuppressWarnings("removal") - SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - sm.checkDelete(getPathForPermissionCheck()); - } - } - @Override public URI toUri() { return WindowsUriSupport.toUri(this); @@ -924,13 +895,6 @@ public WindowsPath toAbsolutePath() { if (isAbsolute()) return this; - // permission check as per spec - @SuppressWarnings("removal") - SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - sm.checkPropertyAccess("user.dir"); - } - try { return createFromNormalizedPath(getFileSystem(), getAbsolutePath()); } catch (WindowsException x) { @@ -940,7 +904,6 @@ public WindowsPath toAbsolutePath() { @Override public WindowsPath toRealPath(LinkOption... options) throws IOException { - checkRead(); String rp = WindowsLinkSupport.getRealPath(this, Util.followLinks(options)); return createFromNormalizedPath(getFileSystem(), rp); } @@ -956,31 +919,6 @@ public WatchKey register(WatchService watcher, if (!(watcher instanceof WindowsWatchService)) throw new ProviderMismatchException(); - // When a security manager is set then we need to make a defensive - // copy of the modifiers and check for the Windows specific FILE_TREE - // modifier. When the modifier is present then check that permission - // has been granted recursively. - @SuppressWarnings("removal") - SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - boolean watchSubtree = false; - final int ml = modifiers.length; - if (ml > 0) { - modifiers = Arrays.copyOf(modifiers, ml); - int i=0; - while (i < ml) { - if (ExtendedOptions.FILE_TREE.matches(modifiers[i++])) { - watchSubtree = true; - break; - } - } - } - String s = getPathForPermissionCheck(); - sm.checkRead(s); - if (watchSubtree) - sm.checkRead(s + "\\-"); - } - return ((WindowsWatchService)watcher).register(this, events, modifiers); } } diff --git a/src/java.base/windows/classes/sun/nio/fs/WindowsUriSupport.java b/src/java.base/windows/classes/sun/nio/fs/WindowsUriSupport.java index a4d4c2ff316..3d22d1122bd 100644 --- a/src/java.base/windows/classes/sun/nio/fs/WindowsUriSupport.java +++ b/src/java.base/windows/classes/sun/nio/fs/WindowsUriSupport.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -104,9 +104,8 @@ static URI toUri(WindowsPath path) { boolean addSlash = false; if (!s.endsWith("\\")) { try { - path.checkRead(); addSlash = WindowsFileAttributes.get(path, true).isDirectory(); - } catch (SecurityException | WindowsException x) { + } catch (WindowsException x) { } } diff --git a/src/java.base/windows/classes/sun/nio/fs/WindowsUserDefinedFileAttributeView.java b/src/java.base/windows/classes/sun/nio/fs/WindowsUserDefinedFileAttributeView.java index a96596af3cd..b488602a0f2 100644 --- a/src/java.base/windows/classes/sun/nio/fs/WindowsUserDefinedFileAttributeView.java +++ b/src/java.base/windows/classes/sun/nio/fs/WindowsUserDefinedFileAttributeView.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -100,19 +100,13 @@ private List<String> listUsingStreamEnumeration() throws IOException { return Collections.unmodifiableList(list); } - @SuppressWarnings("removal") @Override public List<String> list() throws IOException { - if (System.getSecurityManager() != null) - checkAccess(file.getPathForPermissionCheck(), true, false); return listUsingStreamEnumeration(); } - @SuppressWarnings("removal") @Override public int size(String name) throws IOException { - if (System.getSecurityManager() != null) - checkAccess(file.getPathForPermissionCheck(), true, false); // wrap with channel FileChannel fc = null; @@ -122,9 +116,9 @@ public int size(String name) throws IOException { if (!followLinks) opts.add(WindowsChannelFactory.OPEN_REPARSE_POINT); fc = WindowsChannelFactory - .newFileChannel(join(file, name), null, opts, 0L); + .newFileChannel(join(file, name), opts, 0L); } catch (WindowsException x) { - x.rethrowAsIOException(join(file.getPathForPermissionCheck(), name)); + x.rethrowAsIOException(join(file.getPathForExceptionMessage(), name)); } try { long size = fc.size(); @@ -136,12 +130,8 @@ public int size(String name) throws IOException { } } - @SuppressWarnings("removal") @Override public int read(String name, ByteBuffer dst) throws IOException { - if (System.getSecurityManager() != null) - checkAccess(file.getPathForPermissionCheck(), true, false); - // wrap with channel FileChannel fc = null; try { @@ -150,9 +140,9 @@ public int read(String name, ByteBuffer dst) throws IOException { if (!followLinks) opts.add(WindowsChannelFactory.OPEN_REPARSE_POINT); fc = WindowsChannelFactory - .newFileChannel(join(file, name), null, opts, 0L); + .newFileChannel(join(file, name), opts, 0L); } catch (WindowsException x) { - x.rethrowAsIOException(join(file.getPathForPermissionCheck(), name)); + x.rethrowAsIOException(join(file.getPathForExceptionMessage(), name)); } // read to EOF (nothing we can do if I/O error occurs) @@ -172,12 +162,8 @@ public int read(String name, ByteBuffer dst) throws IOException { } } - @SuppressWarnings("removal") @Override public int write(String name, ByteBuffer src) throws IOException { - if (System.getSecurityManager() != null) - checkAccess(file.getPathForPermissionCheck(), false, true); - /** * Creating a named stream will cause the unnamed stream to be created * if it doesn't already exist. To avoid this we open the unnamed stream @@ -210,9 +196,9 @@ public int write(String name, ByteBuffer src) throws IOException { FileChannel named = null; try { named = WindowsChannelFactory - .newFileChannel(join(file, name), null, opts, 0L); + .newFileChannel(join(file, name), opts, 0L); } catch (WindowsException x) { - x.rethrowAsIOException(join(file.getPathForPermissionCheck(), name)); + x.rethrowAsIOException(join(file.getPathForExceptionMessage(), name)); } // write value (nothing we can do if I/O error occurs) try { @@ -229,12 +215,8 @@ public int write(String name, ByteBuffer src) throws IOException { } } - @SuppressWarnings("removal") @Override public void delete(String name) throws IOException { - if (System.getSecurityManager() != null) - checkAccess(file.getPathForPermissionCheck(), false, true); - String path = WindowsLinkSupport.getFinalPath(file, followLinks); String toDelete = join(path, name); try { diff --git a/src/java.base/windows/classes/sun/nio/fs/WindowsUserPrincipals.java b/src/java.base/windows/classes/sun/nio/fs/WindowsUserPrincipals.java index cdb66296a63..336bbe22cfb 100644 --- a/src/java.base/windows/classes/sun/nio/fs/WindowsUserPrincipals.java +++ b/src/java.base/windows/classes/sun/nio/fs/WindowsUserPrincipals.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -131,12 +131,6 @@ static UserPrincipal fromSid(long sidAddress) throws IOException { } static UserPrincipal lookup(String name) throws IOException { - @SuppressWarnings("removal") - SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - sm.checkPermission(new RuntimePermission("lookupUserInformation")); - } - // invoke LookupAccountName to get buffer size needed for SID int size; try { From 70eb95f8488aa39c22ee404c1a4756ecf5db7af6 Mon Sep 17 00:00:00 2001 From: Kevin Walls <kevinw@openjdk.org> Date: Mon, 18 Nov 2024 19:18:22 +0000 Subject: [PATCH 068/311] 8344187: Remove SecurityManager and related calls from java.instrument Reviewed-by: alanb, amenkov --- .../lang/instrument/ClassFileTransformer.java | 2 - .../sun/instrument/InstrumentationImpl.java | 38 +++---------------- 2 files changed, 6 insertions(+), 34 deletions(-) diff --git a/src/java.instrument/share/classes/java/lang/instrument/ClassFileTransformer.java b/src/java.instrument/share/classes/java/lang/instrument/ClassFileTransformer.java index ee2037fac5b..7091847a599 100644 --- a/src/java.instrument/share/classes/java/lang/instrument/ClassFileTransformer.java +++ b/src/java.instrument/share/classes/java/lang/instrument/ClassFileTransformer.java @@ -25,8 +25,6 @@ package java.lang.instrument; -import java.security.AccessController; -import java.security.PrivilegedAction; import java.security.ProtectionDomain; /* diff --git a/src/java.instrument/share/classes/sun/instrument/InstrumentationImpl.java b/src/java.instrument/share/classes/sun/instrument/InstrumentationImpl.java index 3aeddd1c90d..bd54b89aee6 100644 --- a/src/java.instrument/share/classes/sun/instrument/InstrumentationImpl.java +++ b/src/java.instrument/share/classes/sun/instrument/InstrumentationImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -36,7 +36,6 @@ import java.nio.file.Path; import java.nio.file.InvalidPathException; import java.net.URL; -import java.security.AccessController; import java.security.CodeSource; import java.security.PrivilegedAction; import java.security.ProtectionDomain; @@ -68,9 +67,7 @@ public class InstrumentationImpl implements Instrumentation { private static final String TRACE_USAGE_PROP_NAME = "jdk.instrument.traceUsage"; private static final boolean TRACE_USAGE; static { - PrivilegedAction<String> pa = () -> System.getProperty(TRACE_USAGE_PROP_NAME); - @SuppressWarnings("removal") - String s = AccessController.doPrivileged(pa); + String s = System.getProperty(TRACE_USAGE_PROP_NAME); TRACE_USAGE = (s != null) && (s.isEmpty() || Boolean.parseBoolean(s)); } @@ -100,9 +97,7 @@ public class InstrumentationImpl implements Instrumentation { String source = jarFile(nativeAgent); try { Path path = Path.of(source); - PrivilegedAction<Path> pa = path::toAbsolutePath; - @SuppressWarnings("removal") - Path absolutePath = AccessController.doPrivileged(pa); + Path absolutePath = path.toAbsolutePath(); source = absolutePath.toString(); } catch (InvalidPathException e) { // use original path @@ -482,18 +477,6 @@ private TransformerManager findTransformerManager(ClassFileTransformer transform * Internals */ - - // Enable or disable Java programming language access checks on a - // reflected object (for example, a method) - @SuppressWarnings("removal") - private static void setAccessible(final AccessibleObject ao, final boolean accessible) { - AccessController.doPrivileged(new PrivilegedAction<Object>() { - public Object run() { - ao.setAccessible(accessible); - return null; - }}); - } - // Attempt to load and start an agent private void loadClassAndStartAgent( String classname, @@ -553,7 +536,7 @@ public Object run() { !javaAgentClass.getModule().isNamed()) { // If the java agent class is in an unnamed module, the java agent class can be non-public. // Suppress access check upon the invocation of the premain/agentmain method. - setAccessible(m, true); + m.setAccessible(true); } // invoke the 1 or 2-arg method @@ -665,9 +648,7 @@ private void trace(String methodName) { * Returns the possibly-bnull code source of the given class. */ private static URL codeSource(Class<?> clazz) { - PrivilegedAction<ProtectionDomain> pa = clazz::getProtectionDomain; - @SuppressWarnings("removal") - CodeSource cs = AccessController.doPrivileged(pa).getCodeSource(); + CodeSource cs = clazz.getProtectionDomain().getCodeSource(); return (cs != null) ? cs.getLocation() : null; } @@ -675,13 +656,6 @@ private static URL codeSource(Class<?> clazz) { * Holder for StackWalker object. */ private static class HolderStackWalker { - static final StackWalker walker; - static { - PrivilegedAction<StackWalker> pa = () -> - StackWalker.getInstance(StackWalker.Option.RETAIN_CLASS_REFERENCE); - @SuppressWarnings("removal") - StackWalker w = AccessController.doPrivileged(pa); - walker = w; - } + static final StackWalker walker = StackWalker.getInstance(StackWalker.Option.RETAIN_CLASS_REFERENCE); } } From 92271af6358d38a49b02fb02020f9459c55fca26 Mon Sep 17 00:00:00 2001 From: Harshitha Onkar <honkar@openjdk.org> Date: Mon, 18 Nov 2024 19:19:51 +0000 Subject: [PATCH 069/311] 8344058: Remove doPrivileged calls from macos platform sources in the java.desktop module Reviewed-by: prr, aivanov --- .../macosx/classes/apple/laf/JRSUIUtils.java | 6 +- .../classes/com/apple/eio/FileManager.java | 10 +- .../classes/com/apple/laf/AquaFileView.java | 10 +- .../com/apple/laf/AquaImageFactory.java | 16 +-- .../com/apple/laf/AquaLookAndFeel.java | 18 +--- .../classes/com/apple/laf/AquaMenuBarUI.java | 13 +-- .../com/apple/laf/AquaNativeResources.java | 10 +- .../com/apple/laf/AquaUtilControlSize.java | 6 +- .../classes/com/apple/laf/AquaUtils.java | 31 ++---- .../classes/com/apple/laf/ScreenMenu.java | 10 +- .../classes/sun/awt/PlatformGraphicsInfo.java | 7 +- .../macosx/classes/sun/font/CFontManager.java | 26 ++--- .../macosx/classes/sun/java2d/MacOSFlags.java | 99 +++++++++---------- .../sun/java2d/metal/MTLGraphicsConfig.java | 9 +- .../sun/java2d/metal/MTLRenderQueue.java | 6 +- .../classes/sun/lwawt/LWComponentPeer.java | 45 +++------ .../macosx/classes/sun/lwawt/LWToolkit.java | 35 +++---- .../sun/lwawt/macosx/CAccessibility.java | 10 +- .../lwawt/macosx/CDragSourceContextPeer.java | 3 +- .../classes/sun/lwawt/macosx/CFileDialog.java | 10 +- .../sun/lwawt/macosx/CPlatformWindow.java | 6 +- .../classes/sun/lwawt/macosx/CPrinterJob.java | 12 +-- .../classes/sun/lwawt/macosx/CTrayIcon.java | 7 +- .../classes/sun/lwawt/macosx/LWCToolkit.java | 58 ++++------- 24 files changed, 142 insertions(+), 321 deletions(-) diff --git a/src/java.desktop/macosx/classes/apple/laf/JRSUIUtils.java b/src/java.desktop/macosx/classes/apple/laf/JRSUIUtils.java index bed22b8d4ee..d6c051c17ab 100644 --- a/src/java.desktop/macosx/classes/apple/laf/JRSUIUtils.java +++ b/src/java.desktop/macosx/classes/apple/laf/JRSUIUtils.java @@ -25,12 +25,9 @@ package apple.laf; -import java.security.AccessController; - import apple.laf.JRSUIConstants.Hit; import apple.laf.JRSUIConstants.ScrollBarPart; import com.apple.laf.AquaImageFactory.NineSliceMetrics; -import sun.security.action.GetPropertyAction; public final class JRSUIUtils { @@ -69,8 +66,7 @@ static boolean currentMacOSXVersionMatchesGivenVersionRange( final int majorVersion, final int minorVersion, final boolean inclusive, final boolean matchBelow, final boolean matchAbove) { // split the "x.y.z" version number - @SuppressWarnings("removal") - String osVersion = AccessController.doPrivileged(new GetPropertyAction("os.version")); + String osVersion = System.getProperty("os.version"); String[] fragments = osVersion.split("\\."); if (fragments.length < 2) return false; diff --git a/src/java.desktop/macosx/classes/com/apple/eio/FileManager.java b/src/java.desktop/macosx/classes/com/apple/eio/FileManager.java index 1a77ddd7600..5449e3ff9e2 100644 --- a/src/java.desktop/macosx/classes/com/apple/eio/FileManager.java +++ b/src/java.desktop/macosx/classes/com/apple/eio/FileManager.java @@ -58,15 +58,9 @@ public class FileManager { loadOSXLibrary(); } - @SuppressWarnings({"removal", "restricted"}) + @SuppressWarnings("restricted") private static void loadOSXLibrary() { - java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction<Void>() { - public Void run() { - System.loadLibrary("osx"); - return null; - } - }); + System.loadLibrary("osx"); } /** diff --git a/src/java.desktop/macosx/classes/com/apple/laf/AquaFileView.java b/src/java.desktop/macosx/classes/com/apple/laf/AquaFileView.java index 34e5b7c9b7c..32b43dba295 100644 --- a/src/java.desktop/macosx/classes/com/apple/laf/AquaFileView.java +++ b/src/java.desktop/macosx/classes/com/apple/laf/AquaFileView.java @@ -65,15 +65,9 @@ class AquaFileView extends FileView { loadOSXUILibrary(); } - @SuppressWarnings({"removal", "restricted"}) + @SuppressWarnings("restricted") private static void loadOSXUILibrary() { - java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction<Void>() { - public Void run() { - System.loadLibrary("osxui"); - return null; - } - }); + System.loadLibrary("osxui"); } // TODO: Un-comment this out when the native version exists diff --git a/src/java.desktop/macosx/classes/com/apple/laf/AquaImageFactory.java b/src/java.desktop/macosx/classes/com/apple/laf/AquaImageFactory.java index 2fddf6483a5..9cf3b920f91 100644 --- a/src/java.desktop/macosx/classes/com/apple/laf/AquaImageFactory.java +++ b/src/java.desktop/macosx/classes/com/apple/laf/AquaImageFactory.java @@ -27,11 +27,11 @@ import java.awt.*; import java.awt.image.BufferedImage; -import java.security.PrivilegedAction; import javax.swing.*; import javax.swing.plaf.*; +import com.apple.eawt.Application; import sun.lwawt.macosx.LWCToolkit; import apple.laf.JRSUIConstants.AlignmentHorizontal; import apple.laf.JRSUIConstants.AlignmentVertical; @@ -82,22 +82,12 @@ public static IconUIResource getLockImageIcon() { return getAppIconCompositedOn(lockIcon); } - @SuppressWarnings("removal") static Image getGenericJavaIcon() { - return java.security.AccessController.doPrivileged(new PrivilegedAction<Image>() { - public Image run() { - return com.apple.eawt.Application.getApplication().getDockIconImage(); - } - }); + return Application.getApplication().getDockIconImage(); } - @SuppressWarnings("removal") static String getPathToThisApplication() { - return java.security.AccessController.doPrivileged(new PrivilegedAction<String>() { - public String run() { - return FileManager.getPathToApplicationBundle(); - } - }); + return FileManager.getPathToApplicationBundle(); } static IconUIResource getAppIconCompositedOn(final SystemIcon systemIcon) { diff --git a/src/java.desktop/macosx/classes/com/apple/laf/AquaLookAndFeel.java b/src/java.desktop/macosx/classes/com/apple/laf/AquaLookAndFeel.java index 9748f900827..34a39525a74 100644 --- a/src/java.desktop/macosx/classes/com/apple/laf/AquaLookAndFeel.java +++ b/src/java.desktop/macosx/classes/com/apple/laf/AquaLookAndFeel.java @@ -154,22 +154,10 @@ public boolean isSupportedLookAndFeel() { * @see #uninitialize * @see UIManager#setLookAndFeel */ - @SuppressWarnings({"removal", "restricted"}) + @SuppressWarnings("restricted") public void initialize() { - java.security.AccessController.doPrivileged(new PrivilegedAction<Void>() { - public Void run() { - System.loadLibrary("osxui"); - return null; - } - }); - - java.security.AccessController.doPrivileged(new PrivilegedAction<Void>(){ - @Override - public Void run() { - JRSUIControl.initJRSUI(); - return null; - } - }); + System.loadLibrary("osxui"); + JRSUIControl.initJRSUI(); super.initialize(); final ScreenPopupFactory spf = new ScreenPopupFactory(); diff --git a/src/java.desktop/macosx/classes/com/apple/laf/AquaMenuBarUI.java b/src/java.desktop/macosx/classes/com/apple/laf/AquaMenuBarUI.java index f252e310750..1c9ad2c929d 100644 --- a/src/java.desktop/macosx/classes/com/apple/laf/AquaMenuBarUI.java +++ b/src/java.desktop/macosx/classes/com/apple/laf/AquaMenuBarUI.java @@ -29,7 +29,6 @@ import java.awt.Dimension; import java.awt.Graphics; import java.awt.MenuBar; -import java.security.AccessController; import javax.swing.JComponent; import javax.swing.JFrame; @@ -38,18 +37,13 @@ import javax.swing.plaf.basic.BasicMenuBarUI; import sun.lwawt.macosx.LWCToolkit; -import sun.security.action.GetBooleanAction; // MenuBar implementation for Mac L&F -@SuppressWarnings({"removal", "restricted"}) +@SuppressWarnings("restricted") public class AquaMenuBarUI extends BasicMenuBarUI implements ScreenMenuBarProvider { static { - java.security.AccessController.doPrivileged( - (java.security.PrivilegedAction<Void>) () -> { - System.loadLibrary("osxui"); - return null; - }); + System.loadLibrary("osxui"); } // Utilities @@ -151,7 +145,6 @@ public static final boolean isScreenMenuBar(final JMenuBar c) { public static boolean getScreenMenuBarProperty() { // Do not allow AWT to set the screen menu bar if it's embedded in another UI toolkit if (LWCToolkit.isEmbedded()) return false; - return AccessController.doPrivileged(new GetBooleanAction( - AquaLookAndFeel.sPropertyPrefix + "useScreenMenuBar")); + return Boolean.getBoolean(AquaLookAndFeel.sPropertyPrefix + "useScreenMenuBar"); } } diff --git a/src/java.desktop/macosx/classes/com/apple/laf/AquaNativeResources.java b/src/java.desktop/macosx/classes/com/apple/laf/AquaNativeResources.java index a8abf1a6cd8..ee813fc7104 100644 --- a/src/java.desktop/macosx/classes/com/apple/laf/AquaNativeResources.java +++ b/src/java.desktop/macosx/classes/com/apple/laf/AquaNativeResources.java @@ -32,16 +32,10 @@ import com.apple.laf.AquaUtils.RecyclableSingleton; -@SuppressWarnings({"removal", "restricted"}) +@SuppressWarnings("restricted") public class AquaNativeResources { static { - java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction<Void>() { - public Void run() { - System.loadLibrary("osxui"); - return null; - } - }); + System.loadLibrary("osxui"); } // TODO: removing CColorPaint for now diff --git a/src/java.desktop/macosx/classes/com/apple/laf/AquaUtilControlSize.java b/src/java.desktop/macosx/classes/com/apple/laf/AquaUtilControlSize.java index 0bd1ce9609d..51b02a7f5d4 100644 --- a/src/java.desktop/macosx/classes/com/apple/laf/AquaUtilControlSize.java +++ b/src/java.desktop/macosx/classes/com/apple/laf/AquaUtilControlSize.java @@ -27,7 +27,6 @@ import java.awt.*; import java.beans.*; -import java.security.AccessController; import javax.swing.*; import javax.swing.border.Border; @@ -38,7 +37,6 @@ import com.apple.laf.AquaUtils.RecyclableSingleton; import com.apple.laf.AquaUtils.RecyclableSingletonFromDefaultConstructor; -import sun.security.action.GetPropertyAction; public class AquaUtilControlSize { protected static final String CLIENT_PROPERTY_KEY = "JComponent.sizeVariant"; @@ -72,9 +70,7 @@ private static JRSUIConstants.Size getSizeFromString(final String name) { } private static Size getDefaultSize() { - @SuppressWarnings("removal") - final String sizeProperty = AccessController.doPrivileged( - new GetPropertyAction(SYSTEM_PROPERTY_KEY)); + final String sizeProperty = System.getProperty(SYSTEM_PROPERTY_KEY); final JRSUIConstants.Size size = getSizeFromString(sizeProperty); if (size != null) return size; return JRSUIConstants.Size.REGULAR; diff --git a/src/java.desktop/macosx/classes/com/apple/laf/AquaUtils.java b/src/java.desktop/macosx/classes/com/apple/laf/AquaUtils.java index 712f597f9ef..d40d50b1b5c 100644 --- a/src/java.desktop/macosx/classes/com/apple/laf/AquaUtils.java +++ b/src/java.desktop/macosx/classes/com/apple/laf/AquaUtils.java @@ -29,8 +29,6 @@ import java.awt.image.*; import java.lang.ref.SoftReference; import java.lang.reflect.Method; -import java.security.AccessController; -import java.security.PrivilegedAction; import java.util.*; import javax.swing.*; @@ -41,7 +39,6 @@ import sun.lwawt.macosx.CPlatformWindow; import sun.reflect.misc.ReflectUtil; -import sun.security.action.GetPropertyAction; import sun.swing.SwingUtilities2; import com.apple.laf.AquaImageFactory.SlicedImageControl; @@ -205,9 +202,7 @@ V get(final K key) { private static final RecyclableSingleton<Boolean> enableAnimations = new RecyclableSingleton<Boolean>() { @Override protected Boolean getInstance() { - @SuppressWarnings("removal") - final String sizeProperty = (String) AccessController.doPrivileged((PrivilegedAction<?>)new GetPropertyAction( - ANIMATIONS_PROPERTY)); + final String sizeProperty = System.getProperty(ANIMATIONS_PROPERTY); return !"false".equals(sizeProperty); // should be true by default } }; @@ -332,25 +327,17 @@ public void paintBorder(final Component c, final Graphics g, final int x, final } } - @SuppressWarnings("removal") private static final RecyclableSingleton<Method> getJComponentGetFlagMethod = new RecyclableSingleton<Method>() { @Override protected Method getInstance() { - return AccessController.doPrivileged( - new PrivilegedAction<Method>() { - @Override - public Method run() { - try { - final Method method = JComponent.class.getDeclaredMethod( - "getFlag", new Class<?>[] { int.class }); - method.setAccessible(true); - return method; - } catch (final Throwable ignored) { - return null; - } - } - } - ); + try { + final Method method = JComponent.class.getDeclaredMethod( + "getFlag", new Class<?>[]{int.class}); + method.setAccessible(true); + return method; + } catch (final Throwable ignored) { + return null; + } } }; diff --git a/src/java.desktop/macosx/classes/com/apple/laf/ScreenMenu.java b/src/java.desktop/macosx/classes/com/apple/laf/ScreenMenu.java index d8d0928c55f..ef4e4c5707a 100644 --- a/src/java.desktop/macosx/classes/com/apple/laf/ScreenMenu.java +++ b/src/java.desktop/macosx/classes/com/apple/laf/ScreenMenu.java @@ -45,15 +45,9 @@ final class ScreenMenu extends Menu loadAWTLibrary(); } - @SuppressWarnings({"removal", "restricted"}) + @SuppressWarnings("restricted") private static void loadAWTLibrary() { - java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction<Void>() { - public Void run() { - System.loadLibrary("awt"); - return null; - } - }); + System.loadLibrary("awt"); } // screen menu stuff diff --git a/src/java.desktop/macosx/classes/sun/awt/PlatformGraphicsInfo.java b/src/java.desktop/macosx/classes/sun/awt/PlatformGraphicsInfo.java index 6af002fc04f..571bc5c5479 100644 --- a/src/java.desktop/macosx/classes/sun/awt/PlatformGraphicsInfo.java +++ b/src/java.desktop/macosx/classes/sun/awt/PlatformGraphicsInfo.java @@ -27,17 +27,12 @@ import java.awt.GraphicsEnvironment; import java.awt.Toolkit; -import java.security.AccessController; -import java.security.PrivilegedAction; -@SuppressWarnings({"removal", "restricted"}) +@SuppressWarnings({"restricted"}) public class PlatformGraphicsInfo { static { - AccessController.doPrivileged((PrivilegedAction<Void>) () -> { System.loadLibrary("awt"); - return null; - }); } public static GraphicsEnvironment createGE() { diff --git a/src/java.desktop/macosx/classes/sun/font/CFontManager.java b/src/java.desktop/macosx/classes/sun/font/CFontManager.java index baab3257153..f9455a6d102 100644 --- a/src/java.desktop/macosx/classes/sun/font/CFontManager.java +++ b/src/java.desktop/macosx/classes/sun/font/CFontManager.java @@ -27,8 +27,6 @@ import java.awt.*; import java.io.File; -import java.security.AccessController; -import java.security.PrivilegedAction; import java.util.ArrayList; import java.util.HashMap; import java.util.Hashtable; @@ -147,10 +145,7 @@ protected void addNativeFontFamilyNames(TreeMap<String, String> familyNames, Loc protected void registerFontsInDir(final String dirName, boolean useJavaRasterizer, int fontRank, boolean defer, boolean resolveSymLinks) { - @SuppressWarnings("removal") - String[] files = AccessController.doPrivileged((PrivilegedAction<String[]>) () -> { - return new File(dirName).list(getTrueTypeFilter()); - }); + String[] files = new File(dirName).list(getTrueTypeFilter()); if (files == null) { return; @@ -205,24 +200,17 @@ void registerItalicDerived() { Object waitForFontsToBeLoaded = new Object(); private boolean loadedAllFonts = false; - @SuppressWarnings("removal") + public void loadFonts() { synchronized(waitForFontsToBeLoaded) { super.loadFonts(); - java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction<Object>() { - public Object run() { - if (!loadedAllFonts) { - loadNativeFonts(); - registerItalicDerived(); - loadedAllFonts = true; - } - return null; - } - } - ); + if (!loadedAllFonts) { + loadNativeFonts(); + registerItalicDerived(); + loadedAllFonts = true; + } String defaultFont = "Lucida Grande"; String defaultFallback = "Lucida Grande"; diff --git a/src/java.desktop/macosx/classes/sun/java2d/MacOSFlags.java b/src/java.desktop/macosx/classes/sun/java2d/MacOSFlags.java index 37b573a339b..033b9ad8362 100644 --- a/src/java.desktop/macosx/classes/sun/java2d/MacOSFlags.java +++ b/src/java.desktop/macosx/classes/sun/java2d/MacOSFlags.java @@ -25,7 +25,6 @@ package sun.java2d; -import java.security.PrivilegedAction; import sun.java2d.metal.MTLGraphicsConfig; import sun.java2d.opengl.CGLGraphicsConfig; @@ -83,59 +82,53 @@ private static boolean isBooleanPropTrueVerbose(String p) { return false; } - @SuppressWarnings("removal") private static void initJavaFlags() { - java.security.AccessController.doPrivileged( - (PrivilegedAction<Object>) () -> { - PropertyState oglState = getBooleanProp("sun.java2d.opengl", PropertyState.UNSPECIFIED); - PropertyState metalState = getBooleanProp("sun.java2d.metal", PropertyState.UNSPECIFIED); - - // Handle invalid combinations to use the default rendering pipeline - // The default rendering pipeline is Metal - if ((oglState == PropertyState.UNSPECIFIED && metalState == PropertyState.UNSPECIFIED) || - (oglState == PropertyState.DISABLED && metalState == PropertyState.DISABLED) || - (oglState == PropertyState.ENABLED && metalState == PropertyState.ENABLED)) { - metalState = PropertyState.ENABLED; // Enable default pipeline - oglState = PropertyState.DISABLED; // Disable non-default pipeline - } - - if (metalState == PropertyState.UNSPECIFIED) { - if (oglState == PropertyState.DISABLED) { - oglEnabled = false; - metalEnabled = true; - } else { - oglEnabled = true; - metalEnabled = false; - } - } else if (metalState == PropertyState.ENABLED) { - oglEnabled = false; - metalEnabled = true; - } else if (metalState == PropertyState.DISABLED) { - oglEnabled = true; - metalEnabled = false; - } - - oglVerbose = isBooleanPropTrueVerbose("sun.java2d.opengl"); - metalVerbose = isBooleanPropTrueVerbose("sun.java2d.metal"); - - if (oglEnabled && !metalEnabled) { - // Check whether OGL is available - if (!CGLGraphicsConfig.isCGLAvailable()) { - if (oglVerbose) { - System.out.println("Could not enable OpenGL pipeline (CGL not available)"); - } - oglEnabled = false; - metalEnabled = true; - } - } - - // At this point one of the rendering pipeline must be enabled. - if (!metalEnabled && !oglEnabled) { - throw new InternalError("Error - unable to initialize any rendering pipeline."); - } - - return null; - }); + PropertyState oglState = getBooleanProp("sun.java2d.opengl", PropertyState.UNSPECIFIED); + PropertyState metalState = getBooleanProp("sun.java2d.metal", PropertyState.UNSPECIFIED); + + // Handle invalid combinations to use the default rendering pipeline + // The default rendering pipeline is Metal + if ((oglState == PropertyState.UNSPECIFIED && metalState == PropertyState.UNSPECIFIED) || + (oglState == PropertyState.DISABLED && metalState == PropertyState.DISABLED) || + (oglState == PropertyState.ENABLED && metalState == PropertyState.ENABLED)) { + metalState = PropertyState.ENABLED; // Enable default pipeline + oglState = PropertyState.DISABLED; // Disable non-default pipeline + } + + if (metalState == PropertyState.UNSPECIFIED) { + if (oglState == PropertyState.DISABLED) { + oglEnabled = false; + metalEnabled = true; + } else { + oglEnabled = true; + metalEnabled = false; + } + } else if (metalState == PropertyState.ENABLED) { + oglEnabled = false; + metalEnabled = true; + } else if (metalState == PropertyState.DISABLED) { + oglEnabled = true; + metalEnabled = false; + } + + oglVerbose = isBooleanPropTrueVerbose("sun.java2d.opengl"); + metalVerbose = isBooleanPropTrueVerbose("sun.java2d.metal"); + + if (oglEnabled && !metalEnabled) { + // Check whether OGL is available + if (!CGLGraphicsConfig.isCGLAvailable()) { + if (oglVerbose) { + System.out.println("Could not enable OpenGL pipeline (CGL not available)"); + } + oglEnabled = false; + metalEnabled = true; + } + } + + // At this point one of the rendering pipeline must be enabled. + if (!metalEnabled && !oglEnabled) { + throw new InternalError("Error - unable to initialize any rendering pipeline."); + } } public static boolean isMetalEnabled() { diff --git a/src/java.desktop/macosx/classes/sun/java2d/metal/MTLGraphicsConfig.java b/src/java.desktop/macosx/classes/sun/java2d/metal/MTLGraphicsConfig.java index 2b70c39146b..f3867ce88c1 100644 --- a/src/java.desktop/macosx/classes/sun/java2d/metal/MTLGraphicsConfig.java +++ b/src/java.desktop/macosx/classes/sun/java2d/metal/MTLGraphicsConfig.java @@ -58,8 +58,6 @@ import java.awt.image.VolatileImage; import java.awt.image.WritableRaster; import java.io.File; -import java.security.AccessController; -import java.security.PrivilegedAction; import static sun.java2d.metal.MTLContext.MTLContextCaps.CAPS_EXT_GRAD_SHADER; import static sun.java2d.pipe.hw.AccelSurface.TEXTURE; @@ -73,11 +71,10 @@ public final class MTLGraphicsConfig extends CGraphicsConfig { private static ImageCapabilities imageCaps = new MTLImageCaps(); - @SuppressWarnings("removal") - private static final String mtlShadersLib = AccessController.doPrivileged( - (PrivilegedAction<String>) () -> + + private static final String mtlShadersLib = System.getProperty("java.home", "") + File.separator + - "lib" + File.separator + "shaders.metallib"); + "lib" + File.separator + "shaders.metallib"; private BufferCapabilities bufferCaps; diff --git a/src/java.desktop/macosx/classes/sun/java2d/metal/MTLRenderQueue.java b/src/java.desktop/macosx/classes/sun/java2d/metal/MTLRenderQueue.java index 57b412f5b13..7970aa919f1 100644 --- a/src/java.desktop/macosx/classes/sun/java2d/metal/MTLRenderQueue.java +++ b/src/java.desktop/macosx/classes/sun/java2d/metal/MTLRenderQueue.java @@ -29,9 +29,6 @@ import sun.java2d.pipe.RenderBuffer; import sun.java2d.pipe.RenderQueue; -import java.security.AccessController; -import java.security.PrivilegedAction; - import static sun.java2d.pipe.BufferedOpCodes.DISPOSE_CONFIG; import static sun.java2d.pipe.BufferedOpCodes.SYNC; @@ -46,13 +43,12 @@ public class MTLRenderQueue extends RenderQueue { private static MTLRenderQueue theInstance; private final QueueFlusher flusher; - @SuppressWarnings("removal") private MTLRenderQueue() { /* * The thread must be a member of a thread group * which will not get GCed before VM exit. */ - flusher = AccessController.doPrivileged((PrivilegedAction<QueueFlusher>) QueueFlusher::new); + flusher = new QueueFlusher(); } /** diff --git a/src/java.desktop/macosx/classes/sun/lwawt/LWComponentPeer.java b/src/java.desktop/macosx/classes/sun/lwawt/LWComponentPeer.java index f37e4ad7425..b487b14fd79 100644 --- a/src/java.desktop/macosx/classes/sun/lwawt/LWComponentPeer.java +++ b/src/java.desktop/macosx/classes/sun/lwawt/LWComponentPeer.java @@ -58,8 +58,6 @@ import java.awt.peer.ContainerPeer; import java.awt.peer.KeyboardFocusManagerPeer; import java.lang.reflect.Field; -import java.security.AccessController; -import java.security.PrivilegedAction; import java.util.concurrent.atomic.AtomicBoolean; import javax.swing.JComponent; @@ -260,37 +258,26 @@ public void addDirtyRegion(final JComponent c, final int x, final int y, final i * This method must be called under Toolkit.getDefaultToolkit() lock * and followed by setToolkitAWTEventListener() */ - @SuppressWarnings("removal") protected final AWTEventListener getToolkitAWTEventListener() { - return AccessController.doPrivileged(new PrivilegedAction<AWTEventListener>() { - public AWTEventListener run() { - Toolkit toolkit = Toolkit.getDefaultToolkit(); - try { - Field field = Toolkit.class.getDeclaredField("eventListener"); - field.setAccessible(true); - return (AWTEventListener) field.get(toolkit); - } catch (Exception e) { - throw new InternalError(e.toString()); - } - } - }); + Toolkit toolkit = Toolkit.getDefaultToolkit(); + try { + Field field = Toolkit.class.getDeclaredField("eventListener"); + field.setAccessible(true); + return (AWTEventListener) field.get(toolkit); + } catch (Exception e) { + throw new InternalError(e.toString()); + } } - @SuppressWarnings("removal") protected final void setToolkitAWTEventListener(final AWTEventListener listener) { - AccessController.doPrivileged(new PrivilegedAction<Void>() { - public Void run() { - Toolkit toolkit = Toolkit.getDefaultToolkit(); - try { - Field field = Toolkit.class.getDeclaredField("eventListener"); - field.setAccessible(true); - field.set(toolkit, listener); - } catch (Exception e) { - throw new InternalError(e.toString()); - } - return null; - } - }); + Toolkit toolkit = Toolkit.getDefaultToolkit(); + try { + Field field = Toolkit.class.getDeclaredField("eventListener"); + field.setAccessible(true); + field.set(toolkit, listener); + } catch (Exception e) { + throw new InternalError(e.toString()); + } } /** diff --git a/src/java.desktop/macosx/classes/sun/lwawt/LWToolkit.java b/src/java.desktop/macosx/classes/sun/lwawt/LWToolkit.java index 6f38e62c46d..9a08fae9f4e 100644 --- a/src/java.desktop/macosx/classes/sun/lwawt/LWToolkit.java +++ b/src/java.desktop/macosx/classes/sun/lwawt/LWToolkit.java @@ -31,7 +31,6 @@ import java.awt.dnd.DropTarget; import java.awt.image.*; import java.awt.peer.*; -import java.security.*; import java.util.*; import sun.awt.*; @@ -69,27 +68,23 @@ protected LWToolkit() { * This method waits for the toolkit to be completely initialized * and returns before the message pump is started. */ - @SuppressWarnings("removal") protected final void init() { AWTAutoShutdown.notifyToolkitThreadBusy(); - AccessController.doPrivileged((PrivilegedAction<Void>) () -> { - Runnable shutdownRunnable = () -> { - shutdown(); - waitForRunState(STATE_CLEANUP); - }; - Thread shutdown = new Thread( - ThreadGroupUtils.getRootThreadGroup(), shutdownRunnable, - "AWT-Shutdown", 0, false); - shutdown.setContextClassLoader(null); - Runtime.getRuntime().addShutdownHook(shutdown); - String name = "AWT-LW"; - Thread toolkitThread = new Thread( - ThreadGroupUtils.getRootThreadGroup(), this, name, 0, false); - toolkitThread.setDaemon(true); - toolkitThread.setPriority(Thread.NORM_PRIORITY + 1); - toolkitThread.start(); - return null; - }); + Runnable shutdownRunnable = () -> { + shutdown(); + waitForRunState(STATE_CLEANUP); + }; + Thread shutdown = new Thread( + ThreadGroupUtils.getRootThreadGroup(), shutdownRunnable, + "AWT-Shutdown", 0, false); + shutdown.setContextClassLoader(null); + Runtime.getRuntime().addShutdownHook(shutdown); + String name = "AWT-LW"; + Thread toolkitThread = new Thread( + ThreadGroupUtils.getRootThreadGroup(), this, name, 0, false); + toolkitThread.setDaemon(true); + toolkitThread.setPriority(Thread.NORM_PRIORITY + 1); + toolkitThread.start(); waitForRunState(STATE_MESSAGELOOP); } diff --git a/src/java.desktop/macosx/classes/sun/lwawt/macosx/CAccessibility.java b/src/java.desktop/macosx/classes/sun/lwawt/macosx/CAccessibility.java index 436ab6138fa..417750507aa 100644 --- a/src/java.desktop/macosx/classes/sun/lwawt/macosx/CAccessibility.java +++ b/src/java.desktop/macosx/classes/sun/lwawt/macosx/CAccessibility.java @@ -77,16 +77,10 @@ class CAccessibility implements PropertyChangeListener { loadAWTLibrary(); } - @SuppressWarnings({"removal", "restricted"}) + @SuppressWarnings("restricted") private static void loadAWTLibrary() { // Need to load the native library for this code. - java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction<Void>() { - public Void run() { - System.loadLibrary("awt"); - return null; - } - }); + System.loadLibrary("awt"); } static CAccessibility sAccessibility; diff --git a/src/java.desktop/macosx/classes/sun/lwawt/macosx/CDragSourceContextPeer.java b/src/java.desktop/macosx/classes/sun/lwawt/macosx/CDragSourceContextPeer.java index dbf595a55e1..c36cdd27f3f 100644 --- a/src/java.desktop/macosx/classes/sun/lwawt/macosx/CDragSourceContextPeer.java +++ b/src/java.desktop/macosx/classes/sun/lwawt/macosx/CDragSourceContextPeer.java @@ -59,8 +59,7 @@ public final class CDragSourceContextPeer extends SunDragSourceContextPeer { private static double fMaxImageSize = 128.0; static { - @SuppressWarnings("removal") - String propValue = java.security.AccessController.doPrivileged(new sun.security.action.GetPropertyAction("apple.awt.dnd.defaultDragImageSize")); + String propValue = System.getProperty("apple.awt.dnd.defaultDragImageSize"); if (propValue != null) { try { double value = Double.parseDouble(propValue); diff --git a/src/java.desktop/macosx/classes/sun/lwawt/macosx/CFileDialog.java b/src/java.desktop/macosx/classes/sun/lwawt/macosx/CFileDialog.java index 169aea8127e..090a90554f0 100644 --- a/src/java.desktop/macosx/classes/sun/lwawt/macosx/CFileDialog.java +++ b/src/java.desktop/macosx/classes/sun/lwawt/macosx/CFileDialog.java @@ -51,12 +51,10 @@ import java.awt.peer.FileDialogPeer; import java.io.File; import java.io.FilenameFilter; -import java.security.AccessController; import java.util.List; import sun.awt.AWTAccessor; import sun.java2d.pipe.Region; -import sun.security.action.GetBooleanAction; class CFileDialog implements FileDialogPeer { @@ -65,12 +63,8 @@ private class Task implements Runnable { @Override public void run() { try { - @SuppressWarnings("removal") - boolean navigateApps = !AccessController.doPrivileged( - new GetBooleanAction("apple.awt.use-file-dialog-packages")); - @SuppressWarnings("removal") - boolean chooseDirectories = AccessController.doPrivileged( - new GetBooleanAction("apple.awt.fileDialogForDirectories")); + boolean navigateApps = !Boolean.getBoolean("apple.awt.use-file-dialog-packages"); + boolean chooseDirectories = Boolean.getBoolean("apple.awt.fileDialogForDirectories"); int dialogMode = target.getMode(); String title = target.getTitle(); diff --git a/src/java.desktop/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java b/src/java.desktop/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java index 1bf77f5ee69..3af1b4bcdda 100644 --- a/src/java.desktop/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java +++ b/src/java.desktop/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java @@ -46,7 +46,6 @@ import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.lang.reflect.InvocationTargetException; -import java.security.AccessController; import java.util.ArrayList; import java.util.Arrays; import java.util.Comparator; @@ -70,7 +69,6 @@ import sun.lwawt.LWWindowPeer; import sun.lwawt.LWWindowPeer.PeerType; import sun.lwawt.PlatformWindow; -import sun.security.action.GetPropertyAction; import sun.util.logging.PlatformLogger; public class CPlatformWindow extends CFRetainedResource implements PlatformWindow { @@ -131,9 +129,7 @@ private static native void nativeSetNSWindowStandardFrame(long nsWindowPtr, // This system property is named as jdk.* because it is not specific to AWT // and it is also used in JavaFX - @SuppressWarnings("removal") - public static final String MAC_OS_TABBED_WINDOW = AccessController.doPrivileged( - new GetPropertyAction("jdk.allowMacOSTabbedWindows")); + public static final String MAC_OS_TABBED_WINDOW = System.getProperty("jdk.allowMacOSTabbedWindows"); // Yeah, I know. But it's easier to deal with ints from JNI static final int MODELESS = 0; diff --git a/src/java.desktop/macosx/classes/sun/lwawt/macosx/CPrinterJob.java b/src/java.desktop/macosx/classes/sun/lwawt/macosx/CPrinterJob.java index 416a3ee002b..cbb39e24c1a 100644 --- a/src/java.desktop/macosx/classes/sun/lwawt/macosx/CPrinterJob.java +++ b/src/java.desktop/macosx/classes/sun/lwawt/macosx/CPrinterJob.java @@ -31,8 +31,6 @@ import java.awt.image.BufferedImage; import java.awt.print.*; import java.net.URI; -import java.security.AccessController; -import java.security.PrivilegedAction; import java.util.concurrent.atomic.AtomicReference; import javax.print.*; @@ -284,7 +282,6 @@ private String getDestinationFile() { return destinationAttr; } - @SuppressWarnings("removal") @Override public void print(PrintRequestAttributeSet attributes) throws PrinterException { // NOTE: Some of this code is copied from RasterPrinterJob. @@ -344,14 +341,7 @@ public void print(PrintRequestAttributeSet attributes) throws PrinterException { onEventThread = true; - printingLoop = AccessController.doPrivileged(new PrivilegedAction<SecondaryLoop>() { - @Override - public SecondaryLoop run() { - return Toolkit.getDefaultToolkit() - .getSystemEventQueue() - .createSecondaryLoop(); - } - }); + printingLoop = Toolkit.getDefaultToolkit().getSystemEventQueue().createSecondaryLoop(); try { // Fire off the print rendering loop on the AppKit thread, and don't have diff --git a/src/java.desktop/macosx/classes/sun/lwawt/macosx/CTrayIcon.java b/src/java.desktop/macosx/classes/sun/lwawt/macosx/CTrayIcon.java index 7d35f859a7a..4ca923c75b6 100644 --- a/src/java.desktop/macosx/classes/sun/lwawt/macosx/CTrayIcon.java +++ b/src/java.desktop/macosx/classes/sun/lwawt/macosx/CTrayIcon.java @@ -45,8 +45,6 @@ import java.awt.image.BufferedImage; import java.awt.image.ImageObserver; import java.awt.peer.TrayIconPeer; -import java.security.AccessController; -import java.security.PrivilegedAction; import javax.swing.Icon; import javax.swing.UIManager; @@ -71,10 +69,7 @@ public class CTrayIcon extends CFRetainedResource implements TrayIconPeer { // events between MOUSE_PRESSED and MOUSE_RELEASED for particular button private static int mouseClickButtons = 0; - @SuppressWarnings("removal") - private static final boolean useTemplateImages = AccessController.doPrivileged((PrivilegedAction<Boolean>) - () -> Boolean.getBoolean("apple.awt.enableTemplateImages") - ); + private static final boolean useTemplateImages = Boolean.getBoolean("apple.awt.enableTemplateImages"); CTrayIcon(TrayIcon target) { super(0, true); diff --git a/src/java.desktop/macosx/classes/sun/lwawt/macosx/LWCToolkit.java b/src/java.desktop/macosx/classes/sun/lwawt/macosx/LWCToolkit.java index 9a9be0e65c7..d3ffcfc7730 100644 --- a/src/java.desktop/macosx/classes/sun/lwawt/macosx/LWCToolkit.java +++ b/src/java.desktop/macosx/classes/sun/lwawt/macosx/LWCToolkit.java @@ -87,8 +87,6 @@ import java.lang.reflect.UndeclaredThrowableException; import java.net.MalformedURLException; import java.net.URL; -import java.security.AccessController; -import java.security.PrivilegedAction; import java.util.HashMap; import java.util.Locale; import java.util.Map; @@ -146,24 +144,14 @@ public final class LWCToolkit extends LWToolkit { static { System.err.flush(); - @SuppressWarnings({"removal", "restricted"}) - ResourceBundle platformResources = java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction<ResourceBundle>() { - @Override - public ResourceBundle run() { - ResourceBundle platformResources = null; - try { - platformResources = ResourceBundle.getBundle("sun.awt.resources.awtosx"); - } catch (MissingResourceException e) { - // No resource file; defaults will be used. - } - - System.loadLibrary("awt"); - System.loadLibrary("fontmanager"); - - return platformResources; - } - }); + ResourceBundle platformResources = null; + try { + platformResources = ResourceBundle.getBundle("sun.awt.resources.awtosx"); + } catch (MissingResourceException e) { + // No resource file; defaults will be used. + } + + loadLibrary(); if (!GraphicsEnvironment.isHeadless() && !PlatformGraphicsInfo.isInAquaSession()) @@ -178,32 +166,28 @@ public ResourceBundle run() { } } + @SuppressWarnings("restricted") + private static void loadLibrary() { + System.loadLibrary("awt"); + System.loadLibrary("fontmanager"); + } + /* * If true we operate in normal mode and nested runloop is executed in JavaRunLoopMode * If false we operate in singleThreaded FX/AWT interop mode and nested loop uses NSDefaultRunLoopMode */ - @SuppressWarnings("removal") private static final boolean inAWT - = AccessController.doPrivileged(new PrivilegedAction<Boolean>() { - @Override - public Boolean run() { - return !Boolean.parseBoolean( + = !Boolean.parseBoolean( System.getProperty("javafx.embed.singleThread", "false")); - } - }); - @SuppressWarnings("removal") public LWCToolkit() { final String extraButtons = "sun.awt.enableExtraMouseButtons"; - AccessController.doPrivileged((PrivilegedAction<Void>) () -> { areExtraMouseButtonsEnabled = Boolean.parseBoolean(System.getProperty(extraButtons, "true")); //set system property if not yet assigned - System.setProperty(extraButtons, ""+areExtraMouseButtonsEnabled); + System.setProperty(extraButtons, "" + areExtraMouseButtonsEnabled); initAppkit(ThreadGroupUtils.getRootThreadGroup(), GraphicsEnvironment.isHeadless()); - return null; - }); } /* @@ -254,13 +238,9 @@ public static Color getAppleColor(int color) { } // This is only called from native code. - @SuppressWarnings("removal") static void systemColorsChanged() { EventQueue.invokeLater(() -> { - AccessController.doPrivileged( (PrivilegedAction<Object>) () -> { AWTAccessor.getSystemColorAccessor().updateSystemColors(); - return null; - }); }); } @@ -592,13 +572,9 @@ public boolean isAlwaysOnTopSupported() { private static final String APPKIT_THREAD_NAME = "AppKit Thread"; // Intended to be called from the LWCToolkit.m only. - @SuppressWarnings("removal") private static void installToolkitThreadInJava() { Thread.currentThread().setName(APPKIT_THREAD_NAME); - AccessController.doPrivileged((PrivilegedAction<Void>) () -> { - Thread.currentThread().setContextClassLoader(null); - return null; - }); + Thread.currentThread().setContextClassLoader(null); } @Override From de6e013e0e713136ee3117a9805a542ecf521a55 Mon Sep 17 00:00:00 2001 From: Sean Mullan <mullan@openjdk.org> Date: Mon, 18 Nov 2024 19:35:42 +0000 Subject: [PATCH 070/311] 8344310: Remove Security Manager dependencies from javax.crypto and com.sun.crypto packages Reviewed-by: jpai, ascarpino --- .../sun/crypto/provider/DHKeyAgreement.java | 10 ++---- .../com/sun/crypto/provider/JceKeyStore.java | 12 ++----- .../provider/SealedObjectForKeyProtector.java | 21 +++--------- .../com/sun/crypto/provider/SunJCE.java | 18 ++-------- .../javax/crypto/JceSecurity.java.template | 33 +++++-------------- .../javax/crypto/JceSecurityManager.java | 14 ++------ .../javax/crypto/ProviderVerifier.java | 22 ++++--------- 7 files changed, 29 insertions(+), 101 deletions(-) diff --git a/src/java.base/share/classes/com/sun/crypto/provider/DHKeyAgreement.java b/src/java.base/share/classes/com/sun/crypto/provider/DHKeyAgreement.java index 5eebf98acc3..e13eec42905 100644 --- a/src/java.base/share/classes/com/sun/crypto/provider/DHKeyAgreement.java +++ b/src/java.base/share/classes/com/sun/crypto/provider/DHKeyAgreement.java @@ -56,14 +56,8 @@ public final class DHKeyAgreement private static class AllowKDF { - private static final boolean VALUE = getValue(); - - @SuppressWarnings("removal") - private static boolean getValue() { - return AccessController.doPrivileged( - (PrivilegedAction<Boolean>) - () -> Boolean.getBoolean("jdk.crypto.KeyAgreement.legacyKDF")); - } + private static final boolean VALUE = + Boolean.getBoolean("jdk.crypto.KeyAgreement.legacyKDF"); } /** diff --git a/src/java.base/share/classes/com/sun/crypto/provider/JceKeyStore.java b/src/java.base/share/classes/com/sun/crypto/provider/JceKeyStore.java index ab8f2d7097b..3a8f19fa2fb 100644 --- a/src/java.base/share/classes/com/sun/crypto/provider/JceKeyStore.java +++ b/src/java.base/share/classes/com/sun/crypto/provider/JceKeyStore.java @@ -30,14 +30,12 @@ import java.io.*; import java.util.*; -import java.security.AccessController; import java.security.DigestInputStream; import java.security.DigestOutputStream; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.security.Key; import java.security.PrivateKey; -import java.security.PrivilegedAction; import java.security.KeyStoreSpi; import java.security.KeyStoreException; import java.security.UnrecoverableKeyException; @@ -835,15 +833,9 @@ public void engineLoad(InputStream stream, char[] password) // read the sealed key try { ois = new ObjectInputStream(dis); - final ObjectInputStream ois2 = ois; // Set a deserialization checker - @SuppressWarnings("removal") - var dummy = AccessController.doPrivileged( - (PrivilegedAction<Void>)() -> { - ois2.setObjectInputFilter( - new DeserializationChecker(fullLength)); - return null; - }); + ois.setObjectInputFilter( + new DeserializationChecker(fullLength)); entry.sealedKey = (SealedObject)ois.readObject(); entry.maxLength = fullLength; // NOTE: don't close ois here since we are still diff --git a/src/java.base/share/classes/com/sun/crypto/provider/SealedObjectForKeyProtector.java b/src/java.base/share/classes/com/sun/crypto/provider/SealedObjectForKeyProtector.java index 01330678083..b5f5bc89f23 100644 --- a/src/java.base/share/classes/com/sun/crypto/provider/SealedObjectForKeyProtector.java +++ b/src/java.base/share/classes/com/sun/crypto/provider/SealedObjectForKeyProtector.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -73,18 +73,13 @@ AlgorithmParameters getParameters() { return params; } - @SuppressWarnings("removal") final Key getKey(Cipher c, int maxLength) throws IOException, ClassNotFoundException, IllegalBlockSizeException, BadPaddingException { try (ObjectInputStream ois = SharedSecrets.getJavaxCryptoSealedObjectAccess() .getExtObjectInputStream(this, c)) { - AccessController.doPrivileged( - (PrivilegedAction<Void>) () -> { - ois.setObjectInputFilter(new DeserializationChecker(maxLength)); - return null; - }); + ois.setObjectInputFilter(new DeserializationChecker(maxLength)); try { @SuppressWarnings("unchecked") Key t = (Key) ois.readObject(); @@ -113,16 +108,8 @@ private static class DeserializationChecker implements ObjectInputFilter { private static final ObjectInputFilter OWN_FILTER; static { - @SuppressWarnings("removal") - String prop = AccessController.doPrivileged( - (PrivilegedAction<String>) () -> { - String tmp = System.getProperty(KEY_SERIAL_FILTER); - if (tmp != null) { - return tmp; - } else { - return Security.getProperty(KEY_SERIAL_FILTER); - } - }); + String prop = System.getProperty( + KEY_SERIAL_FILTER, Security.getProperty(KEY_SERIAL_FILTER)); OWN_FILTER = prop == null ? null : ObjectInputFilter.Config.createFilter(prop); diff --git a/src/java.base/share/classes/com/sun/crypto/provider/SunJCE.java b/src/java.base/share/classes/com/sun/crypto/provider/SunJCE.java index c0766077ba9..6e3efe8c285 100644 --- a/src/java.base/share/classes/com/sun/crypto/provider/SunJCE.java +++ b/src/java.base/share/classes/com/sun/crypto/provider/SunJCE.java @@ -25,10 +25,8 @@ package com.sun.crypto.provider; -import java.security.AccessController; import java.security.Provider; import java.security.SecureRandom; -import java.security.PrivilegedAction; import java.util.HashMap; import java.util.List; import static sun.security.util.SecurityConstants.PROVIDER_VER; @@ -121,24 +119,12 @@ private void psA(String type, String algo, String cn, attrs)); } - @SuppressWarnings("removal") public SunJCE() { /* We are the "SunJCE" provider */ super("SunJCE", PROVIDER_VER, info); - // if there is no security manager installed, put directly into - // the provider - if (System.getSecurityManager() == null) { - putEntries(); - } else { - AccessController.doPrivileged(new PrivilegedAction<Void>() { - @Override - public Void run() { - putEntries(); - return null; - } - }); - } + putEntries(); + if (instance == null) { instance = this; } diff --git a/src/java.base/share/classes/javax/crypto/JceSecurity.java.template b/src/java.base/share/classes/javax/crypto/JceSecurity.java.template index cd5069d89dd..8b64b452b11 100644 --- a/src/java.base/share/classes/javax/crypto/JceSecurity.java.template +++ b/src/java.base/share/classes/javax/crypto/JceSecurity.java.template @@ -76,7 +76,6 @@ import sun.security.util.Debug; * @since 1.4 */ -@SuppressWarnings("removal") final class JceSecurity { private static final Debug debug = Debug.getInstance("jca"); @@ -109,15 +108,7 @@ final class JceSecurity { static { try { - AccessController.doPrivileged( - new PrivilegedExceptionAction<> () { - @Override - public Void run() throws Exception { - setupJurisdictionPolicies(); - return null; - } - } - ); + setupJurisdictionPolicies(); isRestricted = defaultPolicy.implies( CryptoAllPermission.INSTANCE) ? false : true; @@ -285,20 +276,14 @@ final class JceSecurity { synchronized (codeBaseCacheRef) { URL url = codeBaseCacheRef.get(clazz); if (url == null) { - url = AccessController.doPrivileged( - new PrivilegedAction<>() { - @Override - public URL run() { - ProtectionDomain pd = clazz.getProtectionDomain(); - if (pd != null) { - CodeSource cs = pd.getCodeSource(); - if (cs != null) { - return cs.getLocation(); - } - } - return NULL_URL; - } - }); + url = NULL_URL; + ProtectionDomain pd = clazz.getProtectionDomain(); + if (pd != null) { + CodeSource cs = pd.getCodeSource(); + if (cs != null) { + url = cs.getLocation(); + } + } codeBaseCacheRef.put(clazz, url); } return (url == NULL_URL) ? null : url; diff --git a/src/java.base/share/classes/javax/crypto/JceSecurityManager.java b/src/java.base/share/classes/javax/crypto/JceSecurityManager.java index b178c8bfb02..6e4d39bb88f 100644 --- a/src/java.base/share/classes/javax/crypto/JceSecurityManager.java +++ b/src/java.base/share/classes/javax/crypto/JceSecurityManager.java @@ -65,18 +65,10 @@ final class JceSecurityManager { exemptPolicy = JceSecurity.getExemptPolicy(); allPerm = CryptoAllPermission.INSTANCE; - PrivilegedAction<JceSecurityManager> paSM = JceSecurityManager::new; - @SuppressWarnings("removal") - JceSecurityManager dummySecurityManager = - AccessController.doPrivileged(paSM); - INSTANCE = dummySecurityManager; + INSTANCE = new JceSecurityManager(); - PrivilegedAction<StackWalker> paWalker = - () -> StackWalker.getInstance(Set.of(Option.DROP_METHOD_INFO, Option.RETAIN_CLASS_REFERENCE)); - @SuppressWarnings("removal") - StackWalker dummyWalker = AccessController.doPrivileged(paWalker); - - WALKER = dummyWalker; + WALKER = StackWalker.getInstance( + Set.of(Option.DROP_METHOD_INFO, Option.RETAIN_CLASS_REFERENCE)); } private JceSecurityManager() { diff --git a/src/java.base/share/classes/javax/crypto/ProviderVerifier.java b/src/java.base/share/classes/javax/crypto/ProviderVerifier.java index cbfd02c32f4..37d16dff568 100644 --- a/src/java.base/share/classes/javax/crypto/ProviderVerifier.java +++ b/src/java.base/share/classes/javax/crypto/ProviderVerifier.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -100,20 +100,12 @@ void verify() throws IOException { // Get a link to the Jarfile to search. try { - @SuppressWarnings("removal") - var tmp = AccessController.doPrivileged( - (PrivilegedExceptionAction<JarFile>) () -> { - JarURLConnection conn = - (JarURLConnection) url.openConnection(); - // You could do some caching here as - // an optimization. - conn.setUseCaches(false); - return conn.getJarFile(); - }); - jf = tmp; - } catch (java.security.PrivilegedActionException pae) { - throw new SecurityException("Cannot load " + url, - pae.getCause()); + JarURLConnection conn = (JarURLConnection) url.openConnection(); + // You could do some caching here as an optimization. + conn.setUseCaches(false); + jf = conn.getJarFile(); + } catch (IOException ioe) { + throw new SecurityException("Cannot load " + url, ioe); } if (jf != null) { From f636674889f925d4feb9a8d2be811e66f9b3a0ac Mon Sep 17 00:00:00 2001 From: Patricio Chilano Mateo <pchilanomate@openjdk.org> Date: Mon, 18 Nov 2024 20:48:09 +0000 Subject: [PATCH 071/311] 8344247: Move objectWaiter field to VirtualThread instance Reviewed-by: dholmes, coleenp --- src/hotspot/share/classfile/javaClasses.cpp | 19 +++++++++++++++ src/hotspot/share/classfile/javaClasses.hpp | 10 ++++++++ .../share/classfile/javaClasses.inline.hpp | 8 +++++++ .../share/classfile/javaClassesImpl.hpp | 1 + src/hotspot/share/oops/stackChunkOop.hpp | 6 ----- .../share/oops/stackChunkOop.inline.hpp | 19 --------------- src/hotspot/share/prims/jvmtiEnvBase.cpp | 23 ++++--------------- .../share/runtime/continuationFreezeThaw.cpp | 6 ++--- .../share/runtime/continuationJavaClasses.cpp | 1 - .../share/runtime/continuationJavaClasses.hpp | 5 ---- .../continuationJavaClasses.inline.hpp | 8 ------- src/hotspot/share/runtime/objectMonitor.cpp | 23 +++++++------------ 12 files changed, 53 insertions(+), 76 deletions(-) diff --git a/src/hotspot/share/classfile/javaClasses.cpp b/src/hotspot/share/classfile/javaClasses.cpp index 2e8f6541418..c8f6276cb01 100644 --- a/src/hotspot/share/classfile/javaClasses.cpp +++ b/src/hotspot/share/classfile/javaClasses.cpp @@ -2052,6 +2052,7 @@ int java_lang_VirtualThread::_next_offset; int java_lang_VirtualThread::_onWaitingList_offset; int java_lang_VirtualThread::_notified_offset; int java_lang_VirtualThread::_timeout_offset; +int java_lang_VirtualThread::_objectWaiter_offset; #define VTHREAD_FIELDS_DO(macro) \ macro(static_vthread_scope_offset, k, "VTHREAD_SCOPE", continuationscope_signature, true); \ @@ -2067,6 +2068,7 @@ int java_lang_VirtualThread::_timeout_offset; void java_lang_VirtualThread::compute_offsets() { InstanceKlass* k = vmClasses::VirtualThread_klass(); VTHREAD_FIELDS_DO(FIELD_COMPUTE_OFFSET); + VTHREAD_INJECTED_FIELDS(INJECTED_FIELD_COMPUTE_OFFSET); } bool java_lang_VirtualThread::is_instance(oop obj) { @@ -2182,6 +2184,22 @@ JavaThreadStatus java_lang_VirtualThread::map_state_to_thread_status(int state) return status; } +ObjectMonitor* java_lang_VirtualThread::current_pending_monitor(oop vthread) { + ObjectWaiter* waiter = objectWaiter(vthread); + if (waiter != nullptr && waiter->at_monitorenter()) { + return waiter->monitor(); + } + return nullptr; +} + +ObjectMonitor* java_lang_VirtualThread::current_waiting_monitor(oop vthread) { + ObjectWaiter* waiter = objectWaiter(vthread); + if (waiter != nullptr && waiter->is_wait()) { + return waiter->monitor(); + } + return nullptr; +} + bool java_lang_VirtualThread::is_preempted(oop vthread) { oop continuation = java_lang_VirtualThread::continuation(vthread); assert(continuation != nullptr, "vthread with no continuation"); @@ -2192,6 +2210,7 @@ bool java_lang_VirtualThread::is_preempted(oop vthread) { #if INCLUDE_CDS void java_lang_VirtualThread::serialize_offsets(SerializeClosure* f) { VTHREAD_FIELDS_DO(FIELD_SERIALIZE_OFFSET); + VTHREAD_INJECTED_FIELDS(INJECTED_FIELD_SERIALIZE_OFFSET); } #endif diff --git a/src/hotspot/share/classfile/javaClasses.hpp b/src/hotspot/share/classfile/javaClasses.hpp index 843c8012d2d..0d0fa5954b1 100644 --- a/src/hotspot/share/classfile/javaClasses.hpp +++ b/src/hotspot/share/classfile/javaClasses.hpp @@ -38,6 +38,8 @@ class JvmtiThreadState; class RecordComponent; class SerializeClosure; +class ObjectWaiter; +class ObjectMonitor; #define CHECK_INIT(offset) assert(offset != 0, "should be initialized"); return offset; @@ -537,6 +539,8 @@ class java_lang_ThreadGroup : AllStatic { // Interface to java.lang.VirtualThread objects +#define VTHREAD_INJECTED_FIELDS(macro) \ + macro(java_lang_VirtualThread, objectWaiter, intptr_signature, false) class java_lang_VirtualThread : AllStatic { private: @@ -549,6 +553,7 @@ class java_lang_VirtualThread : AllStatic { static int _notified_offset; static int _recheckInterval_offset; static int _timeout_offset; + static int _objectWaiter_offset; JFR_ONLY(static int _jfr_epoch_offset;) public: enum { @@ -600,6 +605,11 @@ class java_lang_VirtualThread : AllStatic { static void set_notified(oop vthread, jboolean value); static bool is_preempted(oop vthread); static JavaThreadStatus map_state_to_thread_status(int state); + + static inline ObjectWaiter* objectWaiter(oop vthread); + static inline void set_objectWaiter(oop vthread, ObjectWaiter* waiter); + static ObjectMonitor* current_pending_monitor(oop vthread); + static ObjectMonitor* current_waiting_monitor(oop vthread); }; diff --git a/src/hotspot/share/classfile/javaClasses.inline.hpp b/src/hotspot/share/classfile/javaClasses.inline.hpp index 0476f0185ca..f27f1feba6d 100644 --- a/src/hotspot/share/classfile/javaClasses.inline.hpp +++ b/src/hotspot/share/classfile/javaClasses.inline.hpp @@ -220,6 +220,14 @@ inline oop java_lang_VirtualThread::vthread_scope() { return base->obj_field(static_vthread_scope_offset); } +inline ObjectWaiter* java_lang_VirtualThread::objectWaiter(oop vthread) { + return (ObjectWaiter*)vthread->address_field(_objectWaiter_offset); +} + +inline void java_lang_VirtualThread::set_objectWaiter(oop vthread, ObjectWaiter* value) { + vthread->address_field_put(_objectWaiter_offset, (address)value); +} + #if INCLUDE_JFR inline u2 java_lang_Thread::jfr_epoch(oop ref) { return ref->short_field(_jfr_epoch_offset); diff --git a/src/hotspot/share/classfile/javaClassesImpl.hpp b/src/hotspot/share/classfile/javaClassesImpl.hpp index 618189aa0f1..235334a388b 100644 --- a/src/hotspot/share/classfile/javaClassesImpl.hpp +++ b/src/hotspot/share/classfile/javaClassesImpl.hpp @@ -40,6 +40,7 @@ STACKFRAMEINFO_INJECTED_FIELDS(macro) \ MODULE_INJECTED_FIELDS(macro) \ THREAD_INJECTED_FIELDS(macro) \ + VTHREAD_INJECTED_FIELDS(macro) \ INTERNALERROR_INJECTED_FIELDS(macro) \ STACKCHUNK_INJECTED_FIELDS(macro) diff --git a/src/hotspot/share/oops/stackChunkOop.hpp b/src/hotspot/share/oops/stackChunkOop.hpp index 38f26d091f0..57ab6316c2a 100644 --- a/src/hotspot/share/oops/stackChunkOop.hpp +++ b/src/hotspot/share/oops/stackChunkOop.hpp @@ -98,12 +98,6 @@ class stackChunkOopDesc : public instanceOopDesc { inline uint8_t lockstack_size() const; inline void set_lockstack_size(uint8_t value); - inline ObjectWaiter* object_waiter() const; - inline void set_object_waiter(ObjectWaiter* obj_waiter); - - inline ObjectMonitor* current_pending_monitor() const; - inline ObjectMonitor* current_waiting_monitor() const; - inline oop cont() const; template<typename P> inline oop cont() const; diff --git a/src/hotspot/share/oops/stackChunkOop.inline.hpp b/src/hotspot/share/oops/stackChunkOop.inline.hpp index d647904bf5b..4b2c160cd81 100644 --- a/src/hotspot/share/oops/stackChunkOop.inline.hpp +++ b/src/hotspot/share/oops/stackChunkOop.inline.hpp @@ -92,9 +92,6 @@ inline void stackChunkOopDesc::set_max_thawing_size(int value) { inline uint8_t stackChunkOopDesc::lockstack_size() const { return jdk_internal_vm_StackChunk::lockStackSize(as_oop()); } inline void stackChunkOopDesc::set_lockstack_size(uint8_t value) { jdk_internal_vm_StackChunk::set_lockStackSize(this, value); } -inline ObjectWaiter* stackChunkOopDesc::object_waiter() const { return (ObjectWaiter*)jdk_internal_vm_StackChunk::objectWaiter(as_oop()); } -inline void stackChunkOopDesc::set_object_waiter(ObjectWaiter* obj) { jdk_internal_vm_StackChunk::set_objectWaiter(this, (address)obj); } - inline oop stackChunkOopDesc::cont() const { return jdk_internal_vm_StackChunk::cont(as_oop()); } inline void stackChunkOopDesc::set_cont(oop value) { jdk_internal_vm_StackChunk::set_cont(this, value); } template<typename P> @@ -171,22 +168,6 @@ inline void stackChunkOopDesc::set_preempted(bool value) { set_flag(FLAG_PREEMPTED, value); } -inline ObjectMonitor* stackChunkOopDesc::current_pending_monitor() const { - ObjectWaiter* waiter = object_waiter(); - if (waiter != nullptr && waiter->at_monitorenter()) { - return waiter->monitor(); - } - return nullptr; -} - -inline ObjectMonitor* stackChunkOopDesc::current_waiting_monitor() const { - ObjectWaiter* waiter = object_waiter(); - if (waiter != nullptr && waiter->is_wait()) { - return waiter->monitor(); - } - return nullptr; -} - inline bool stackChunkOopDesc::has_lockstack() const { return is_flag(FLAG_HAS_LOCKSTACK); } inline void stackChunkOopDesc::set_has_lockstack(bool value) { set_flag(FLAG_HAS_LOCKSTACK, value); } diff --git a/src/hotspot/share/prims/jvmtiEnvBase.cpp b/src/hotspot/share/prims/jvmtiEnvBase.cpp index 422bbced802..debfc77c32c 100644 --- a/src/hotspot/share/prims/jvmtiEnvBase.cpp +++ b/src/hotspot/share/prims/jvmtiEnvBase.cpp @@ -1080,12 +1080,7 @@ JvmtiEnvBase::get_locked_objects_in_frame(JavaThread* calling_thread, JavaThread ObjectMonitor *mon = target->current_waiting_monitor(); if (mon != nullptr) wait_obj = mon->object(); } else { - assert(vthread != nullptr, "no vthread oop"); - oop cont = java_lang_VirtualThread::continuation(vthread); - assert(cont != nullptr, "vthread with no continuation"); - stackChunkOop chunk = jdk_internal_vm_Continuation::tail(cont); - assert(chunk != nullptr, "unmounted vthread should have a chunk"); - ObjectMonitor *mon = chunk->current_waiting_monitor(); + ObjectMonitor *mon = java_lang_VirtualThread::current_waiting_monitor(vthread); if (mon != nullptr) wait_obj = mon->object(); } } @@ -1099,12 +1094,7 @@ JvmtiEnvBase::get_locked_objects_in_frame(JavaThread* calling_thread, JavaThread ObjectMonitor *mon = target->current_pending_monitor(); if (mon != nullptr) pending_obj = mon->object(); } else { - assert(vthread != nullptr, "no vthread oop"); - oop cont = java_lang_VirtualThread::continuation(vthread); - assert(cont != nullptr, "vthread with no continuation"); - stackChunkOop chunk = jdk_internal_vm_Continuation::tail(cont); - assert(chunk != nullptr, "unmounted vthread should have a chunk"); - ObjectMonitor *mon = chunk->current_pending_monitor(); + ObjectMonitor *mon = java_lang_VirtualThread::current_pending_monitor(vthread); if (mon != nullptr) pending_obj = mon->object(); } } @@ -2569,12 +2559,9 @@ GetCurrentContendedMonitorClosure::do_thread(Thread *target) { void GetCurrentContendedMonitorClosure::do_vthread(Handle target_h) { if (_target_jt == nullptr) { - oop cont = java_lang_VirtualThread::continuation(target_h()); - assert(cont != nullptr, "vthread with no continuation"); - stackChunkOop chunk = jdk_internal_vm_Continuation::tail(cont); - assert(chunk != nullptr, "unmounted vthread should have a chunk"); - if (chunk->current_pending_monitor() != nullptr) { - *_owned_monitor_ptr = JNIHandles::make_local(_calling_thread, chunk->current_pending_monitor()->object()); + ObjectMonitor *mon = java_lang_VirtualThread::current_pending_monitor(target_h()); + if (mon != nullptr) { + *_owned_monitor_ptr = JNIHandles::make_local(_calling_thread, mon->object()); } _result = JVMTI_ERROR_NONE; // target virtual thread is unmounted return; diff --git a/src/hotspot/share/runtime/continuationFreezeThaw.cpp b/src/hotspot/share/runtime/continuationFreezeThaw.cpp index be4fef5255c..18beb10f0b4 100644 --- a/src/hotspot/share/runtime/continuationFreezeThaw.cpp +++ b/src/hotspot/share/runtime/continuationFreezeThaw.cpp @@ -1524,7 +1524,6 @@ stackChunkOop Freeze<ConfigT>::allocate_chunk(size_t stack_size, int argsize_md) assert(chunk->flags() == 0, ""); assert(chunk->is_gc_mode() == false, ""); assert(chunk->lockstack_size() == 0, ""); - assert(chunk->object_waiter() == nullptr, ""); // fields are uninitialized chunk->set_parent_access<IS_DEST_UNINITIALIZED>(_cont.last_nonempty_chunk()); @@ -2214,11 +2213,10 @@ NOINLINE intptr_t* Thaw<ConfigT>::thaw_slow(stackChunkOop chunk, Continuation::t _preempted_case = chunk->preempted(); if (_preempted_case) { - if (chunk->object_waiter() != nullptr) { + ObjectWaiter* waiter = java_lang_VirtualThread::objectWaiter(_thread->vthread()); + if (waiter != nullptr) { // Mounted again after preemption. Resume the pending monitor operation, // which will be either a monitorenter or Object.wait() call. - assert(chunk->current_pending_monitor() != nullptr || chunk->current_waiting_monitor() != nullptr, ""); - ObjectWaiter* waiter = chunk->object_waiter(); ObjectMonitor* mon = waiter->monitor(); preempt_kind = waiter->is_wait() ? Continuation::freeze_on_wait : Continuation::freeze_on_monitorenter; diff --git a/src/hotspot/share/runtime/continuationJavaClasses.cpp b/src/hotspot/share/runtime/continuationJavaClasses.cpp index 5ab96f9cf4f..e76a151f481 100644 --- a/src/hotspot/share/runtime/continuationJavaClasses.cpp +++ b/src/hotspot/share/runtime/continuationJavaClasses.cpp @@ -88,7 +88,6 @@ int jdk_internal_vm_StackChunk::_bottom_offset; int jdk_internal_vm_StackChunk::_flags_offset; int jdk_internal_vm_StackChunk::_maxThawingSize_offset; int jdk_internal_vm_StackChunk::_lockStackSize_offset; -int jdk_internal_vm_StackChunk::_objectWaiter_offset; int jdk_internal_vm_StackChunk::_cont_offset; #define STACKCHUNK_FIELDS_DO(macro) \ diff --git a/src/hotspot/share/runtime/continuationJavaClasses.hpp b/src/hotspot/share/runtime/continuationJavaClasses.hpp index d100ef17871..f9cd53ff9f0 100644 --- a/src/hotspot/share/runtime/continuationJavaClasses.hpp +++ b/src/hotspot/share/runtime/continuationJavaClasses.hpp @@ -76,7 +76,6 @@ class jdk_internal_vm_Continuation: AllStatic { macro(jdk_internal_vm_StackChunk, pc, intptr_signature, false) \ macro(jdk_internal_vm_StackChunk, maxThawingSize, int_signature, false) \ macro(jdk_internal_vm_StackChunk, lockStackSize, byte_signature, false) \ - macro(jdk_internal_vm_StackChunk, objectWaiter, intptr_signature, false) \ class jdk_internal_vm_StackChunk: AllStatic { friend class JavaClasses; @@ -89,7 +88,6 @@ class jdk_internal_vm_StackChunk: AllStatic { static int _flags_offset; static int _maxThawingSize_offset; static int _lockStackSize_offset; - static int _objectWaiter_offset; static int _cont_offset; @@ -131,9 +129,6 @@ class jdk_internal_vm_StackChunk: AllStatic { static inline uint8_t lockStackSize(oop chunk); static inline void set_lockStackSize(oop chunk, uint8_t value); - static inline address objectWaiter(oop chunk); - static inline void set_objectWaiter(oop chunk, address mon); - // cont oop's processing is essential for the chunk's GC protocol static inline oop cont(oop chunk); template<typename P> diff --git a/src/hotspot/share/runtime/continuationJavaClasses.inline.hpp b/src/hotspot/share/runtime/continuationJavaClasses.inline.hpp index b4400c59c68..0e8bf2d6563 100644 --- a/src/hotspot/share/runtime/continuationJavaClasses.inline.hpp +++ b/src/hotspot/share/runtime/continuationJavaClasses.inline.hpp @@ -194,12 +194,4 @@ inline void jdk_internal_vm_StackChunk::set_lockStackSize(oop chunk, uint8_t val Atomic::store(chunk->field_addr<uint8_t>(_lockStackSize_offset), value); } -inline address jdk_internal_vm_StackChunk::objectWaiter(oop chunk) { - return chunk->address_field(_objectWaiter_offset); -} - -inline void jdk_internal_vm_StackChunk::set_objectWaiter(oop chunk, address value) { - chunk->address_field_put(_objectWaiter_offset, value); -} - #endif // SHARE_RUNTIME_CONTINUATIONJAVACLASSES_INLINE_HPP diff --git a/src/hotspot/share/runtime/objectMonitor.cpp b/src/hotspot/share/runtime/objectMonitor.cpp index 7d1998ca849..82473489f68 100644 --- a/src/hotspot/share/runtime/objectMonitor.cpp +++ b/src/hotspot/share/runtime/objectMonitor.cpp @@ -1134,11 +1134,9 @@ bool ObjectMonitor::VThreadMonitorEnter(JavaThread* current, ObjectWaiter* waite java_lang_VirtualThread::set_state(vthread, java_lang_VirtualThread::BLOCKING); // We didn't succeed in acquiring the monitor so increment _contentions and - // save ObjectWaiter* in the chunk since we will need it when resuming execution. + // save ObjectWaiter* in the vthread since we will need it when resuming execution. add_to_contentions(1); - oop cont = java_lang_VirtualThread::continuation(vthread); - stackChunkOop chunk = jdk_internal_vm_Continuation::tail(cont); - chunk->set_object_waiter(node); + java_lang_VirtualThread::set_objectWaiter(vthread, node); return false; } @@ -1202,11 +1200,8 @@ void ObjectMonitor::VThreadEpilog(JavaThread* current, ObjectWaiter* node) { UnlinkAfterAcquire(current, node); delete node; - // Remove the ObjectWaiter* from the stackChunk. - oop vthread = current->vthread(); - oop cont = java_lang_VirtualThread::continuation(vthread); - stackChunkOop chunk = jdk_internal_vm_Continuation::tail(cont); - chunk->set_object_waiter(nullptr); + // Clear the ObjectWaiter* from the vthread. + java_lang_VirtualThread::set_objectWaiter(current->vthread(), nullptr); if (JvmtiExport::should_post_monitor_contended_entered()) { // We are going to call thaw again after this and finish the VMTS @@ -2030,10 +2025,8 @@ void ObjectMonitor::VThreadWait(JavaThread* current, jlong millis) { java_lang_VirtualThread::set_state(vthread, millis == 0 ? java_lang_VirtualThread::WAITING : java_lang_VirtualThread::TIMED_WAITING); java_lang_VirtualThread::set_timeout(vthread, millis); - // Save the ObjectWaiter* in the chunk since we will need it when resuming execution. - oop cont = java_lang_VirtualThread::continuation(vthread); - stackChunkOop chunk = jdk_internal_vm_Continuation::tail(cont); - chunk->set_object_waiter(node); + // Save the ObjectWaiter* in the vthread since we will need it when resuming execution. + java_lang_VirtualThread::set_objectWaiter(vthread, node); } bool ObjectMonitor::VThreadWaitReenter(JavaThread* current, ObjectWaiter* node, ContinuationWrapper& cont) { @@ -2079,8 +2072,8 @@ bool ObjectMonitor::VThreadWaitReenter(JavaThread* current, ObjectWaiter* node, } delete node; - stackChunkOop chunk = cont.tail(); - chunk->set_object_waiter(nullptr); + // Clear the ObjectWaiter* from the vthread. + java_lang_VirtualThread::set_objectWaiter(current->vthread(), nullptr); return true; } } else { From 8d43e0d664aca03f3e8f66812c184a85847fc105 Mon Sep 17 00:00:00 2001 From: Justin Lu <jlu@openjdk.org> Date: Mon, 18 Nov 2024 21:27:24 +0000 Subject: [PATCH 072/311] 8344331: SM cleanup in java.scripting Reviewed-by: naoto, lancea --- .../share/classes/javax/script/ScriptEngineManager.java | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/java.scripting/share/classes/javax/script/ScriptEngineManager.java b/src/java.scripting/share/classes/javax/script/ScriptEngineManager.java index 88f70fc5131..da4d761a853 100644 --- a/src/java.scripting/share/classes/javax/script/ScriptEngineManager.java +++ b/src/java.scripting/share/classes/javax/script/ScriptEngineManager.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,7 +25,6 @@ package javax.script; import java.util.*; -import java.security.*; import java.util.ServiceLoader; import java.util.ServiceConfigurationError; import java.util.function.Function; @@ -87,10 +86,7 @@ private ServiceLoader<ScriptEngineFactory> getServiceLoader(final ClassLoader lo private void initEngines(final ClassLoader loader) { Iterator<ScriptEngineFactory> itr; try { - @SuppressWarnings("removal") - var sl = AccessController.doPrivileged( - (PrivilegedAction<ServiceLoader<ScriptEngineFactory>>)() -> getServiceLoader(loader)); - itr = sl.iterator(); + itr = getServiceLoader(loader).iterator(); } catch (ServiceConfigurationError err) { reportException("Can't find ScriptEngineFactory providers: ", err); // do not throw any exception here. user may want to From 5cb0d438231383d491b2fcca455d09af7f2ee016 Mon Sep 17 00:00:00 2001 From: Christian Stein <cstein@openjdk.org> Date: Mon, 18 Nov 2024 21:49:36 +0000 Subject: [PATCH 073/311] 8293040: Argfile documentation for java launcher tool is confusing regarding usage of wildcards Reviewed-by: liach --- src/java.base/share/man/java.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/java.base/share/man/java.md b/src/java.base/share/man/java.md index f79e55622cd..5f1f9d8ef45 100644 --- a/src/java.base/share/man/java.md +++ b/src/java.base/share/man/java.md @@ -3073,7 +3073,9 @@ The following items describe the syntax of `java` argument files: - The argument file size must not exceed MAXINT (2,147,483,647) bytes. - The launcher doesn't expand wildcards that are present within an argument - file. + file. That means, an asterisk `*` is passed on as-is to the starting VM. + For example `*.java` stays `*.java` and is not expanded to `Foo.java`, + `Bar.java`, etc. like on some command line shell. - Use white space or new line characters to separate arguments included in the file. From dd8636908c6a604a9b191d7dcce8490fa8e3eb4d Mon Sep 17 00:00:00 2001 From: Alex Menkov <amenkov@openjdk.org> Date: Tue, 19 Nov 2024 00:08:06 +0000 Subject: [PATCH 074/311] 8344262: Win32AttachOperationRequest objects are created by using global new Reviewed-by: jwaters, dholmes --- src/hotspot/os/windows/attachListener_windows.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hotspot/os/windows/attachListener_windows.cpp b/src/hotspot/os/windows/attachListener_windows.cpp index 5a34639a1cf..fa45c98ced2 100644 --- a/src/hotspot/os/windows/attachListener_windows.cpp +++ b/src/hotspot/os/windows/attachListener_windows.cpp @@ -161,7 +161,7 @@ class Win32AttachOperation: public AttachOperation { // Win32AttachOperationRequest is an element of AttachOperation request list. -class Win32AttachOperationRequest { +class Win32AttachOperationRequest: public CHeapObj<mtServiceability> { private: AttachAPIVersion _ver; char _name[AttachOperation::name_length_max + 1]; From 37298844c9504fbafb08c593cb6eec70184e308b Mon Sep 17 00:00:00 2001 From: Fei Yang <fyang@openjdk.org> Date: Tue, 19 Nov 2024 01:49:33 +0000 Subject: [PATCH 075/311] 8344371: RISC-V: compiler/intrinsics/chacha/TestChaCha20.java fails after JDK-8343555 Reviewed-by: mli --- test/hotspot/jtreg/compiler/intrinsics/chacha/TestChaCha20.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/hotspot/jtreg/compiler/intrinsics/chacha/TestChaCha20.java b/test/hotspot/jtreg/compiler/intrinsics/chacha/TestChaCha20.java index 448d594b6aa..d2f287e8bcc 100644 --- a/test/hotspot/jtreg/compiler/intrinsics/chacha/TestChaCha20.java +++ b/test/hotspot/jtreg/compiler/intrinsics/chacha/TestChaCha20.java @@ -104,7 +104,7 @@ public static void main(String... args) throws Exception { // Riscv64 intrinsics require the vector instructions if (containsFuzzy(cpuFeatures, "rvv")) { System.out.println("Setting up vector worker"); - configs.add(List.of("-XX:+UseRVV")); + configs.add(List.of()); } } else { // We only have ChaCha20 intrinsics on x64, aarch64 and riscv64 From 9e92a9e2bab04b79626b88a7dd017dd0def04d7a Mon Sep 17 00:00:00 2001 From: Prasanta Sadhukhan <psadhukhan@openjdk.org> Date: Tue, 19 Nov 2024 03:11:31 +0000 Subject: [PATCH 076/311] 8344059: Remove doPrivileged calls from windows platform sources in the java.desktop module Reviewed-by: kcr, prr --- .../plaf/windows/AnimationController.java | 6 +- .../plaf/windows/WindowsLookAndFeel.java | 9 +- .../sun/java/swing/plaf/windows/XPStyle.java | 8 +- .../classes/sun/awt/PlatformGraphicsInfo.java | 10 +- .../classes/sun/awt/Win32FontManager.java | 98 +++++++---------- .../classes/sun/awt/Win32GraphicsDevice.java | 4 +- .../awt/shell/Win32ShellFolderManager2.java | 65 ++++------- .../awt/windows/TranslucentWindowPainter.java | 14 +-- .../sun/awt/windows/WEmbeddedFrame.java | 16 +-- .../sun/awt/windows/WFileDialogPeer.java | 22 ++-- .../classes/sun/awt/windows/WFramePeer.java | 7 +- .../sun/awt/windows/WMenuItemPeer.java | 26 ++--- .../sun/awt/windows/WPathGraphics.java | 7 +- .../classes/sun/awt/windows/WToolkit.java | 62 ++++------- .../java2d/d3d/D3DScreenUpdateManager.java | 46 ++++---- .../sun/java2d/windows/WindowsFlags.java | 102 ++++++++---------- .../sun/print/PrintServiceLookupProvider.java | 41 +++---- 17 files changed, 188 insertions(+), 355 deletions(-) diff --git a/src/java.desktop/windows/classes/com/sun/java/swing/plaf/windows/AnimationController.java b/src/java.desktop/windows/classes/com/sun/java/swing/plaf/windows/AnimationController.java index b50a5ad583e..a8fdbaf7a50 100644 --- a/src/java.desktop/windows/classes/com/sun/java/swing/plaf/windows/AnimationController.java +++ b/src/java.desktop/windows/classes/com/sun/java/swing/plaf/windows/AnimationController.java @@ -25,9 +25,6 @@ package com.sun.java.swing.plaf.windows; -import java.security.AccessController; -import sun.security.action.GetBooleanAction; - import java.util.*; import java.beans.PropertyChangeListener; import java.beans.PropertyChangeEvent; @@ -67,9 +64,8 @@ */ class AnimationController implements ActionListener, PropertyChangeListener { - @SuppressWarnings("removal") private static final boolean VISTA_ANIMATION_DISABLED = - AccessController.doPrivileged(new GetBooleanAction("swing.disablevistaanimation")); + Boolean.getBoolean("swing.disablevistaanimation"); private static final Object ANIMATION_CONTROLLER_KEY = diff --git a/src/java.desktop/windows/classes/com/sun/java/swing/plaf/windows/WindowsLookAndFeel.java b/src/java.desktop/windows/classes/com/sun/java/swing/plaf/windows/WindowsLookAndFeel.java index aa97b0d0741..72ad51535ff 100644 --- a/src/java.desktop/windows/classes/com/sun/java/swing/plaf/windows/WindowsLookAndFeel.java +++ b/src/java.desktop/windows/classes/com/sun/java/swing/plaf/windows/WindowsLookAndFeel.java @@ -58,7 +58,6 @@ import java.awt.image.ImageFilter; import java.awt.image.ImageProducer; import java.awt.image.RGBImageFilter; -import java.security.AccessController; import javax.swing.AbstractAction; import javax.swing.Action; @@ -90,7 +89,6 @@ import sun.awt.SunToolkit; import sun.awt.shell.ShellFolder; import sun.font.FontUtilities; -import sun.security.action.GetPropertyAction; import sun.swing.DefaultLayoutStyle; import sun.swing.ImageIconUIResource; import sun.swing.MnemonicHandler; @@ -184,9 +182,7 @@ public void initialize() { // performance and compatibility issues, so allow this feature // to be switched off either at runtime or programmatically // - @SuppressWarnings("removal") - String systemFonts = java.security.AccessController.doPrivileged( - new GetPropertyAction("swing.useSystemFontSettings")); + String systemFonts = System.getProperty("swing.useSystemFontSettings"); useSystemFontSettings = systemFonts == null || Boolean.parseBoolean(systemFonts); if (useSystemFontSettings) { @@ -596,8 +592,7 @@ protected void initComponentDefaults(UIDefaults table) if (!(this instanceof WindowsClassicLookAndFeel) && (OSInfo.getOSType() == OSInfo.OSType.WINDOWS && OSInfo.getWindowsVersion().compareTo(OSInfo.WINDOWS_XP) >= 0)) { - @SuppressWarnings("removal") - String prop = AccessController.doPrivileged(new GetPropertyAction("swing.noxp")); + String prop = System.getProperty("swing.noxp"); if (prop == null) { // These desktop properties are not used directly, but are needed to diff --git a/src/java.desktop/windows/classes/com/sun/java/swing/plaf/windows/XPStyle.java b/src/java.desktop/windows/classes/com/sun/java/swing/plaf/windows/XPStyle.java index 5723d4274af..bba5f8dc31e 100644 --- a/src/java.desktop/windows/classes/com/sun/java/swing/plaf/windows/XPStyle.java +++ b/src/java.desktop/windows/classes/com/sun/java/swing/plaf/windows/XPStyle.java @@ -55,7 +55,6 @@ import java.awt.image.BufferedImage; import java.awt.image.DataBufferInt; import java.awt.image.WritableRaster; -import java.security.AccessController; import java.util.HashMap; import javax.swing.AbstractButton; @@ -79,7 +78,6 @@ import sun.awt.image.SunWritableRaster; import sun.awt.windows.ThemeReader; -import sun.security.action.GetPropertyAction; import sun.swing.CachedPainter; import static com.sun.java.swing.plaf.windows.TMSchema.Part; @@ -124,7 +122,6 @@ static synchronized void invalidateStyle() { * @return the singleton instance of this class or null if XP styles * are not active or if this is not Windows XP */ - @SuppressWarnings("removal") static synchronized XPStyle getXP() { if (themeActive == null) { Toolkit toolkit = Toolkit.getDefaultToolkit(); @@ -134,9 +131,8 @@ static synchronized XPStyle getXP() { themeActive = Boolean.FALSE; } if (themeActive.booleanValue()) { - GetPropertyAction propertyAction = - new GetPropertyAction("swing.noxp"); - if (AccessController.doPrivileged(propertyAction) == null && + String propertyAction = System.getProperty("swing.noxp"); + if (propertyAction == null && ThemeReader.isThemed() && !(UIManager.getLookAndFeel() instanceof WindowsClassicLookAndFeel)) { diff --git a/src/java.desktop/windows/classes/sun/awt/PlatformGraphicsInfo.java b/src/java.desktop/windows/classes/sun/awt/PlatformGraphicsInfo.java index 6d14a72400c..642f98b0df2 100644 --- a/src/java.desktop/windows/classes/sun/awt/PlatformGraphicsInfo.java +++ b/src/java.desktop/windows/classes/sun/awt/PlatformGraphicsInfo.java @@ -39,15 +39,9 @@ public class PlatformGraphicsInfo { hasDisplays = hasDisplays0(); } - @SuppressWarnings({"removal", "restricted"}) + @SuppressWarnings("restricted") private static void loadAWTLibrary() { - java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction<Void>() { - public Void run() { - System.loadLibrary("awt"); - return null; - } - }); + System.loadLibrary("awt"); } private static native boolean hasDisplays0(); diff --git a/src/java.desktop/windows/classes/sun/awt/Win32FontManager.java b/src/java.desktop/windows/classes/sun/awt/Win32FontManager.java index 1d5f76f9960..52042a600f9 100644 --- a/src/java.desktop/windows/classes/sun/awt/Win32FontManager.java +++ b/src/java.desktop/windows/classes/sun/awt/Win32FontManager.java @@ -29,13 +29,12 @@ import java.awt.FontFormatException; import java.awt.GraphicsEnvironment; import java.io.File; -import java.security.AccessController; -import java.security.PrivilegedAction; import java.util.ArrayList; import java.util.HashMap; import java.util.Locale; import java.util.NoSuchElementException; import java.util.StringTokenizer; +import java.util.function.Supplier; import sun.awt.windows.WFontConfiguration; import sun.font.FontManager; @@ -47,24 +46,21 @@ */ public final class Win32FontManager extends SunFontManager { - @SuppressWarnings("removal") private static final TrueTypeFont eudcFont = - AccessController.doPrivileged(new PrivilegedAction<TrueTypeFont>() { - public TrueTypeFont run() { - String eudcFile = getEUDCFontFile(); - if (eudcFile != null) { - try { - /* Must use Java rasteriser since GDI doesn't - * enumerate (allow direct use) of EUDC fonts. - */ - return new TrueTypeFont(eudcFile, null, 0, - true, false); - } catch (FontFormatException e) { - } + ((Supplier<TrueTypeFont>) () -> { + String eudcFile = getEUDCFontFile(); + if (eudcFile != null) { + try { + /* Must use Java rasteriser since GDI doesn't + * enumerate (allow direct use) of EUDC fonts. + */ + return new TrueTypeFont(eudcFile, null, 0, + true, false); + } catch (FontFormatException e) { } - return null; } - }); + return null; + }).get(); /* Used on Windows to obtain from the windows registry the name * of a file containing the system EUFC font. If running in one of @@ -78,20 +74,14 @@ public TrueTypeFont getEUDCFont() { return eudcFont; } - @SuppressWarnings("removal") public Win32FontManager() { super(); - AccessController.doPrivileged(new PrivilegedAction<Object>() { - public Object run() { - - /* Register the JRE fonts so that the native platform can - * access them. This is used only on Windows so that when - * printing the printer driver can access the fonts. - */ - registerJREFontsWithPlatform(jreFontDirName); - return null; - } - }); + + /* Register the JRE fonts so that the native platform can + * access them. This is used only on Windows so that when + * printing the printer driver can access the fonts. + */ + registerJREFontsWithPlatform(jreFontDirName); } /** @@ -213,21 +203,15 @@ protected String[] getDefaultPlatformFont() { info[1] = "c:\\windows\\fonts"; final String[] dirs = getPlatformFontDirs(true); if (dirs.length > 1) { - @SuppressWarnings("removal") - String dir = (String) - AccessController.doPrivileged(new PrivilegedAction<Object>() { - public Object run() { - for (int i=0; i<dirs.length; i++) { - String path = - dirs[i] + File.separator + "arial.ttf"; - File file = new File(path); - if (file.exists()) { - return dirs[i]; - } - } - return null; - } - }); + String dir = null; + for (int i=0; i<dirs.length; i++) { + String path = dirs[i] + File.separator + "arial.ttf"; + File file = new File(path); + if (file.exists()) { + dir = dirs[i]; + break; + } + } if (dir != null) { info[1] = dir; } @@ -248,7 +232,6 @@ protected void registerJREFontsWithPlatform(String pathName) { fontsForPrinting = pathName; } - @SuppressWarnings("removal") public static void registerJREFontsForPrinting() { final String pathName; synchronized (Win32GraphicsEnvironment.class) { @@ -259,22 +242,15 @@ public static void registerJREFontsForPrinting() { pathName = fontsForPrinting; fontsForPrinting = null; } - java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction<Object>() { - public Object run() { - File f1 = new File(pathName); - String[] ls = f1.list(SunFontManager.getInstance(). - getTrueTypeFilter()); - if (ls == null) { - return null; - } - for (int i=0; i <ls.length; i++ ) { - File fontFile = new File(f1, ls[i]); - registerFontWithPlatform(fontFile.getAbsolutePath()); - } - return null; - } - }); + File f1 = new File(pathName); + String[] ls = f1.list(SunFontManager.getInstance(). + getTrueTypeFilter()); + if (ls != null) { + for (int i=0; i <ls.length; i++ ) { + File fontFile = new File(f1, ls[i]); + registerFontWithPlatform(fontFile.getAbsolutePath()); + } + } } private static native void registerFontWithPlatform(String fontName); diff --git a/src/java.desktop/windows/classes/sun/awt/Win32GraphicsDevice.java b/src/java.desktop/windows/classes/sun/awt/Win32GraphicsDevice.java index 13de92384e4..f32b25626bb 100644 --- a/src/java.desktop/windows/classes/sun/awt/Win32GraphicsDevice.java +++ b/src/java.desktop/windows/classes/sun/awt/Win32GraphicsDevice.java @@ -100,9 +100,7 @@ public class Win32GraphicsDevice extends GraphicsDevice implements // is run as an NT service. To prevent the loading of ddraw.dll // completely, sun.awt.nopixfmt should be set as well. Apps which use // OpenGL w/ Java probably don't want to set this. - @SuppressWarnings("removal") - String nopixfmt = java.security.AccessController.doPrivileged( - new sun.security.action.GetPropertyAction("sun.awt.nopixfmt")); + String nopixfmt = System.getProperty("sun.awt.nopixfmt"); pfDisabled = (nopixfmt != null); initIDs(); } diff --git a/src/java.desktop/windows/classes/sun/awt/shell/Win32ShellFolderManager2.java b/src/java.desktop/windows/classes/sun/awt/shell/Win32ShellFolderManager2.java index 20df99eb7d6..810b25b55fd 100644 --- a/src/java.desktop/windows/classes/sun/awt/shell/Win32ShellFolderManager2.java +++ b/src/java.desktop/windows/classes/sun/awt/shell/Win32ShellFolderManager2.java @@ -31,8 +31,6 @@ import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; -import java.security.AccessController; -import java.security.PrivilegedAction; import java.util.ArrayList; import java.util.Arrays; import java.util.List; @@ -478,12 +476,7 @@ public boolean isComputerNode(final File dir) { if (dir != null && dir == getDrives()) { return true; } else { - @SuppressWarnings("removal") - String path = AccessController.doPrivileged(new PrivilegedAction<String>() { - public String run() { - return dir.getAbsolutePath(); - } - }); + String path = dir.getAbsolutePath(); return (path.startsWith("\\\\") && path.indexOf("\\", 2) < 0); //Network path } @@ -572,25 +565,17 @@ protected Invoker createInvoker() { private static class ComInvoker extends ThreadPoolExecutor implements ThreadFactory, ShellFolder.Invoker { private static Thread comThread; - @SuppressWarnings("removal") private ComInvoker() { super(1, 1, 0, TimeUnit.DAYS, new LinkedBlockingQueue<>()); allowCoreThreadTimeOut(false); setThreadFactory(this); - final Runnable shutdownHook = () -> AccessController.doPrivileged((PrivilegedAction<Void>) () -> { - shutdownNow(); - return null; - }); - AccessController.doPrivileged((PrivilegedAction<Void>) () -> { - Thread t = new Thread( - ThreadGroupUtils.getRootThreadGroup(), shutdownHook, - "ShellFolder", 0, false); - Runtime.getRuntime().addShutdownHook(t); - return null; - }); + final Runnable shutdownHook = () -> shutdownNow(); + Thread t = new Thread( + ThreadGroupUtils.getRootThreadGroup(), shutdownHook, + "ShellFolder", 0, false); + Runtime.getRuntime().addShutdownHook(t); } - @SuppressWarnings("removal") public synchronized Thread newThread(final Runnable task) { final Runnable comRun = new Runnable() { public void run() { @@ -602,27 +587,22 @@ public void run() { } } }; - comThread = AccessController.doPrivileged((PrivilegedAction<Thread>) () -> { - String name = "Swing-Shell"; - /* The thread must be a member of a thread group - * which will not get GCed before VM exit. - * Make its parent the top-level thread group. - */ - Thread thread = new Thread( - ThreadGroupUtils.getRootThreadGroup(), comRun, name, - 0, false); - thread.setDaemon(true); - /* This is important, since this thread running at lower priority - leads to memory consumption when listDrives() function is called - repeatedly. - */ - thread.setPriority(Thread.MAX_PRIORITY); - return thread; - }); + /* The thread must be a member of a thread group + * which will not get GCed before VM exit. + * Make its parent the top-level thread group. + */ + comThread = new Thread( + ThreadGroupUtils.getRootThreadGroup(), comRun, "Swing-Shell", + 0, false); + comThread.setDaemon(true); + /* This is important, since this thread running at lower priority + leads to memory consumption when listDrives() function is called + repeatedly. + */ + comThread.setPriority(Thread.MAX_PRIORITY); return comThread; } - @SuppressWarnings("removal") public <T> T invoke(Callable<T> task) throws Exception { if (Thread.currentThread() == comThread) { // if it's already called from the COM @@ -640,13 +620,8 @@ public <T> T invoke(Callable<T> task) throws Exception { try { return future.get(); } catch (InterruptedException e) { - AccessController.doPrivileged(new PrivilegedAction<Void>() { - public Void run() { - future.cancel(true); + future.cancel(true); - return null; - } - }); throw e; } catch (ExecutionException e) { diff --git a/src/java.desktop/windows/classes/sun/awt/windows/TranslucentWindowPainter.java b/src/java.desktop/windows/classes/sun/awt/windows/TranslucentWindowPainter.java index 56cea268d28..b31685294ba 100644 --- a/src/java.desktop/windows/classes/sun/awt/windows/TranslucentWindowPainter.java +++ b/src/java.desktop/windows/classes/sun/awt/windows/TranslucentWindowPainter.java @@ -35,7 +35,6 @@ import java.awt.image.BufferedImage; import java.awt.image.DataBufferInt; import java.awt.image.VolatileImage; -import java.security.AccessController; import sun.awt.image.BufImgSurfaceData; import sun.java2d.DestSurfaceProvider; import sun.java2d.InvalidPipeException; @@ -45,7 +44,6 @@ import sun.java2d.pipe.BufferedContext; import sun.java2d.pipe.hw.AccelGraphicsConfig; import sun.java2d.pipe.hw.AccelSurface; -import sun.security.action.GetPropertyAction; import static java.awt.image.VolatileImage.*; import static sun.java2d.pipe.hw.AccelSurface.*; @@ -66,14 +64,10 @@ abstract class TranslucentWindowPainter { protected WWindowPeer peer; // REMIND: we probably would want to remove this later - @SuppressWarnings("removal") - private static final boolean forceOpt = - Boolean.parseBoolean(AccessController.doPrivileged( - new GetPropertyAction("sun.java2d.twp.forceopt", "false"))); - @SuppressWarnings("removal") - private static final boolean forceSW = - Boolean.parseBoolean(AccessController.doPrivileged( - new GetPropertyAction("sun.java2d.twp.forcesw", "false"))); + private static final boolean forceOpt = + Boolean.getBoolean("sun.java2d.twp.forceopt"); + private static final boolean forceSW = + Boolean.getBoolean("sun.java2d.twp.forcesw"); /** * Creates an instance of the painter for particular peer. diff --git a/src/java.desktop/windows/classes/sun/awt/windows/WEmbeddedFrame.java b/src/java.desktop/windows/classes/sun/awt/windows/WEmbeddedFrame.java index 0ffc973408a..a6294e05ba9 100644 --- a/src/java.desktop/windows/classes/sun/awt/windows/WEmbeddedFrame.java +++ b/src/java.desktop/windows/classes/sun/awt/windows/WEmbeddedFrame.java @@ -32,11 +32,8 @@ import java.awt.image.*; import sun.awt.image.ByteInterleavedRaster; -import sun.security.action.GetPropertyAction; import java.awt.peer.FramePeer; -import java.security.PrivilegedAction; -import java.security.AccessController; @SuppressWarnings("serial") // JDK-implementation class public class WEmbeddedFrame extends EmbeddedFrame { @@ -60,9 +57,7 @@ public class WEmbeddedFrame extends EmbeddedFrame { */ private boolean isEmbeddedInIE = false; - @SuppressWarnings("removal") - private static String printScale = AccessController.doPrivileged( - new GetPropertyAction("sun.java2d.print.pluginscalefactor")); + private static String printScale = System.getProperty("sun.java2d.print.pluginscalefactor"); public WEmbeddedFrame() { this((long)0); @@ -181,7 +176,6 @@ void print(long hdc) { } } - @SuppressWarnings("removal") protected static int getPrintScaleFactor() { // check if value is already cached if (pScale != 0) @@ -189,13 +183,7 @@ protected static int getPrintScaleFactor() { if (printScale == null) { // if no system property is specified, // check for environment setting - printScale = AccessController.doPrivileged( - new PrivilegedAction<String>() { - public String run() { - return System.getenv("JAVA2D_PLUGIN_PRINT_SCALE"); - } - } - ); + printScale = System.getenv("JAVA2D_PLUGIN_PRINT_SCALE"); } int default_printDC_scale = 4; int scale = default_printDC_scale; diff --git a/src/java.desktop/windows/classes/sun/awt/windows/WFileDialogPeer.java b/src/java.desktop/windows/classes/sun/awt/windows/WFileDialogPeer.java index 7502b667250..60f3726249e 100644 --- a/src/java.desktop/windows/classes/sun/awt/windows/WFileDialogPeer.java +++ b/src/java.desktop/windows/classes/sun/awt/windows/WFileDialogPeer.java @@ -30,8 +30,6 @@ import java.awt.peer.*; import java.io.File; import java.io.FilenameFilter; -import java.security.AccessController; -import java.security.PrivilegedAction; import java.util.ResourceBundle; import java.util.MissingResourceException; import java.util.Vector; @@ -197,19 +195,13 @@ public void run() { //This whole static block is a part of 4152317 fix static { - @SuppressWarnings("removal") - String filterString = AccessController.doPrivileged( - new PrivilegedAction<String>() { - @Override - public String run() { - try { - ResourceBundle rb = ResourceBundle.getBundle("sun.awt.windows.awtLocalization"); - return rb.getString("allFiles"); - } catch (MissingResourceException e) { - return "All Files"; - } - } - }); + String filterString; + try { + ResourceBundle rb = ResourceBundle.getBundle("sun.awt.windows.awtLocalization"); + filterString = rb.getString("allFiles"); + } catch (MissingResourceException e) { + filterString = "All Files"; + } setFilterString(filterString); } diff --git a/src/java.desktop/windows/classes/sun/awt/windows/WFramePeer.java b/src/java.desktop/windows/classes/sun/awt/windows/WFramePeer.java index a5612b08dc4..9b74f7359fb 100644 --- a/src/java.desktop/windows/classes/sun/awt/windows/WFramePeer.java +++ b/src/java.desktop/windows/classes/sun/awt/windows/WFramePeer.java @@ -32,11 +32,9 @@ import java.awt.MenuBar; import java.awt.Rectangle; import java.awt.peer.FramePeer; -import java.security.AccessController; import sun.awt.AWTAccessor; import sun.awt.im.InputMethodManager; -import sun.security.action.GetPropertyAction; import static sun.java2d.SunGraphicsEnvironment.getGCDeviceBounds; import static sun.java2d.SunGraphicsEnvironment.toDeviceSpaceAbs; @@ -80,11 +78,8 @@ public void toFront() { private native void setMaximizedBounds(int x, int y, int w, int h); private native void clearMaximizedBounds(); - @SuppressWarnings("removal") private static final boolean keepOnMinimize = "true".equals( - AccessController.doPrivileged( - new GetPropertyAction( - "sun.awt.keepWorkingSetOnMinimize"))); + System.getProperty("sun.awt.keepWorkingSetOnMinimize")); @Override public final void setMaximizedBounds(Rectangle b) { diff --git a/src/java.desktop/windows/classes/sun/awt/windows/WMenuItemPeer.java b/src/java.desktop/windows/classes/sun/awt/windows/WMenuItemPeer.java index 344a8e7dbc8..3a736e5c519 100644 --- a/src/java.desktop/windows/classes/sun/awt/windows/WMenuItemPeer.java +++ b/src/java.desktop/windows/classes/sun/awt/windows/WMenuItemPeer.java @@ -29,11 +29,8 @@ import java.awt.*; import java.awt.peer.*; import java.awt.event.ActionEvent; -import java.security.AccessController; -import java.security.PrivilegedAction; import sun.util.logging.PlatformLogger; -@SuppressWarnings("removal") class WMenuItemPeer extends WObjectPeer implements MenuItemPeer { private static final PlatformLogger log = PlatformLogger.getLogger("sun.awt.WMenuItemPeer"); @@ -146,20 +143,15 @@ public void run() { private static Font defaultMenuFont; static { - defaultMenuFont = AccessController.doPrivileged( - new PrivilegedAction <Font> () { - public Font run() { - try { - ResourceBundle rb = ResourceBundle.getBundle("sun.awt.windows.awtLocalization"); - return Font.decode(rb.getString("menuFont")); - } catch (MissingResourceException e) { - if (log.isLoggable(PlatformLogger.Level.FINE)) { - log.fine("WMenuItemPeer: " + e.getMessage()+". Using default MenuItem font.", e); - } - return new Font("SanSerif", Font.PLAIN, 11); - } - } - }); + try { + ResourceBundle rb = ResourceBundle.getBundle("sun.awt.windows.awtLocalization"); + defaultMenuFont = Font.decode(rb.getString("menuFont")); + } catch (MissingResourceException e) { + if (log.isLoggable(PlatformLogger.Level.FINE)) { + log.fine("WMenuItemPeer: " + e.getMessage()+". Using default MenuItem font.", e); + } + defaultMenuFont = new Font("SanSerif", Font.PLAIN, 11); + } } static Font getDefaultFont() { diff --git a/src/java.desktop/windows/classes/sun/awt/windows/WPathGraphics.java b/src/java.desktop/windows/classes/sun/awt/windows/WPathGraphics.java index 84ae7e8f418..aef078b950f 100644 --- a/src/java.desktop/windows/classes/sun/awt/windows/WPathGraphics.java +++ b/src/java.desktop/windows/classes/sun/awt/windows/WPathGraphics.java @@ -95,11 +95,8 @@ final class WPathGraphics extends PathGraphics { private static boolean useGDITextLayout = true; private static boolean preferGDITextLayout = false; static { - @SuppressWarnings("removal") - String textLayoutStr = - java.security.AccessController.doPrivileged( - new sun.security.action.GetPropertyAction( - "sun.java2d.print.enableGDITextLayout")); + String textLayoutStr = System.getProperty( + "sun.java2d.print.enableGDITextLayout"); if (textLayoutStr != null) { useGDITextLayout = Boolean.getBoolean(textLayoutStr); diff --git a/src/java.desktop/windows/classes/sun/awt/windows/WToolkit.java b/src/java.desktop/windows/classes/sun/awt/windows/WToolkit.java index ad643ccbd3d..f2fbfa9b77d 100644 --- a/src/java.desktop/windows/classes/sun/awt/windows/WToolkit.java +++ b/src/java.desktop/windows/classes/sun/awt/windows/WToolkit.java @@ -112,8 +112,6 @@ import java.awt.peer.WindowPeer; import java.beans.PropertyChangeListener; import java.lang.ref.WeakReference; -import java.security.AccessController; -import java.security.PrivilegedAction; import java.util.Hashtable; import java.util.Locale; import java.util.Map; @@ -168,17 +166,11 @@ public final class WToolkit extends SunToolkit implements Runnable { */ private static native void initIDs(); private static boolean loaded = false; - @SuppressWarnings({"removal", "restricted"}) + + @SuppressWarnings("restricted") public static void loadLibraries() { if (!loaded) { - java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction<Void>() { - @Override - public Void run() { - System.loadLibrary("awt"); - return null; - } - }); + System.loadLibrary("awt"); loaded = true; } } @@ -208,7 +200,6 @@ public void dispose() { private static native boolean startToolkitThread(Runnable thread, ThreadGroup rootThreadGroup); - @SuppressWarnings("removal") public WToolkit() { // Startup toolkit threads if (PerformanceLogger.loggingEnabled()) { @@ -225,16 +216,12 @@ public WToolkit() { AWTAutoShutdown.notifyToolkitThreadBusy(); // Find a root TG and attach toolkit thread to it - ThreadGroup rootTG = AccessController.doPrivileged( - (PrivilegedAction<ThreadGroup>) ThreadGroupUtils::getRootThreadGroup); + ThreadGroup rootTG = ThreadGroupUtils.getRootThreadGroup(); if (!startToolkitThread(this, rootTG)) { final String name = "AWT-Windows"; - AccessController.doPrivileged((PrivilegedAction<Void>) () -> { - Thread toolkitThread = new Thread(rootTG, this, name, 0, false); - toolkitThread.setDaemon(true); - toolkitThread.start(); - return null; - }); + Thread toolkitThread = new Thread(rootTG, this, name, 0, false); + toolkitThread.setDaemon(true); + toolkitThread.start(); } try { @@ -251,36 +238,25 @@ public WToolkit() { // by the native system though. setDynamicLayout(true); final String extraButtons = "sun.awt.enableExtraMouseButtons"; - AccessController.doPrivileged((PrivilegedAction<Void>) () -> { - areExtraMouseButtonsEnabled = - Boolean.parseBoolean(System.getProperty(extraButtons, "true")); - //set system property if not yet assigned - System.setProperty(extraButtons, ""+areExtraMouseButtonsEnabled); - return null; - }); + areExtraMouseButtonsEnabled = + Boolean.parseBoolean(System.getProperty(extraButtons, "true")); + //set system property if not yet assigned + System.setProperty(extraButtons, ""+areExtraMouseButtonsEnabled); setExtraMouseButtonsEnabledNative(areExtraMouseButtonsEnabled); } - @SuppressWarnings("removal") private void registerShutdownHook() { - AccessController.doPrivileged((PrivilegedAction<Void>) () -> { - Thread shutdown = new Thread( - ThreadGroupUtils.getRootThreadGroup(), this::shutdown, - "ToolkitShutdown", 0, false); - shutdown.setContextClassLoader(null); - Runtime.getRuntime().addShutdownHook(shutdown); - return null; - }); - } + Thread shutdown = new Thread( + ThreadGroupUtils.getRootThreadGroup(), this::shutdown, + "ToolkitShutdown", 0, false); + shutdown.setContextClassLoader(null); + Runtime.getRuntime().addShutdownHook(shutdown); + } - @SuppressWarnings("removal") @Override public void run() { - AccessController.doPrivileged((PrivilegedAction<Void>) () -> { - Thread.currentThread().setContextClassLoader(null); - Thread.currentThread().setPriority(Thread.NORM_PRIORITY + 1); - return null; - }); + Thread.currentThread().setContextClassLoader(null); + Thread.currentThread().setPriority(Thread.NORM_PRIORITY + 1); boolean startPump = init(); diff --git a/src/java.desktop/windows/classes/sun/java2d/d3d/D3DScreenUpdateManager.java b/src/java.desktop/windows/classes/sun/java2d/d3d/D3DScreenUpdateManager.java index 7ad09a5e750..fd9112e08f1 100644 --- a/src/java.desktop/windows/classes/sun/java2d/d3d/D3DScreenUpdateManager.java +++ b/src/java.desktop/windows/classes/sun/java2d/d3d/D3DScreenUpdateManager.java @@ -32,8 +32,6 @@ import java.awt.Graphics2D; import java.awt.Rectangle; import java.awt.Window; -import java.security.AccessController; -import java.security.PrivilegedAction; import java.util.ArrayList; import java.util.HashMap; @@ -91,25 +89,21 @@ public class D3DScreenUpdateManager extends ScreenUpdateManager */ private HashMap<D3DWindowSurfaceData, GDIWindowSurfaceData> gdiSurfaces; - @SuppressWarnings("removal") public D3DScreenUpdateManager() { done = false; - AccessController.doPrivileged((PrivilegedAction<Void>) () -> { - Runnable shutdownRunnable = () -> { - done = true; - wakeUpUpdateThread(); - }; - Thread shutdown = new Thread( - ThreadGroupUtils.getRootThreadGroup(), shutdownRunnable, - "ScreenUpdater", 0, false); - shutdown.setContextClassLoader(null); - try { - Runtime.getRuntime().addShutdownHook(shutdown); - } catch (Exception e) { - done = true; - } - return null; - }); + Runnable shutdownRunnable = () -> { + done = true; + wakeUpUpdateThread(); + }; + Thread shutdown = new Thread( + ThreadGroupUtils.getRootThreadGroup(), shutdownRunnable, + "ScreenUpdater", 0, false); + shutdown.setContextClassLoader(null); + try { + Runtime.getRuntime().addShutdownHook(shutdown); + } catch (Exception e) { + done = true; + } } /** @@ -345,19 +339,15 @@ private void removeGdiSurface(final D3DWindowSurfaceData d3dw) { * If the update thread hasn't yet been created, it will be; * otherwise it is awaken */ - @SuppressWarnings("removal") private synchronized void startUpdateThread() { if (screenUpdater == null) { - screenUpdater = AccessController.doPrivileged((PrivilegedAction<Thread>) () -> { - String name = "D3D Screen Updater"; - Thread t = new Thread( + String name = "D3D Screen Updater"; + screenUpdater = new Thread( ThreadGroupUtils.getRootThreadGroup(), this, name, 0, false); - // REMIND: should it be higher? - t.setPriority(Thread.NORM_PRIORITY + 2); - t.setDaemon(true); - return t; - }); + // REMIND: should it be higher? + screenUpdater.setPriority(Thread.NORM_PRIORITY + 2); + screenUpdater.setDaemon(true); screenUpdater.start(); } else { wakeUpUpdateThread(); diff --git a/src/java.desktop/windows/classes/sun/java2d/windows/WindowsFlags.java b/src/java.desktop/windows/classes/sun/java2d/windows/WindowsFlags.java index 3c18de432bb..da13c6b49fc 100644 --- a/src/java.desktop/windows/classes/sun/java2d/windows/WindowsFlags.java +++ b/src/java.desktop/windows/classes/sun/java2d/windows/WindowsFlags.java @@ -176,65 +176,57 @@ private static boolean getPropertySet(String p) { return (propString != null) ? true : false; } - @SuppressWarnings("removal") private static void initJavaFlags() { - java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction<Object>() - { - public Object run() { - magPresent = getBooleanProp( - "javax.accessibility.screen_magnifier_present", false); - boolean ddEnabled = - !getBooleanProp("sun.java2d.noddraw", magPresent); - boolean ddOffscreenEnabled = - getBooleanProp("sun.java2d.ddoffscreen", ddEnabled); - d3dEnabled = getBooleanProp("sun.java2d.d3d", - ddEnabled && ddOffscreenEnabled); - d3dOnScreenEnabled = - getBooleanProp("sun.java2d.d3d.onscreen", d3dEnabled); - oglEnabled = getBooleanProp("sun.java2d.opengl", false); - if (oglEnabled) { - oglVerbose = isBooleanPropTrueVerbose("sun.java2d.opengl"); - if (WGLGraphicsConfig.isWGLAvailable()) { - d3dEnabled = false; - } else { - if (oglVerbose) { - System.out.println( - "Could not enable OpenGL pipeline " + - "(WGL not available)"); - } - oglEnabled = false; - } - } - gdiBlitEnabled = getBooleanProp("sun.java2d.gdiBlit", true); - d3dSet = getPropertySet("sun.java2d.d3d"); - if (d3dSet) { - d3dVerbose = isBooleanPropTrueVerbose("sun.java2d.d3d"); - } - offscreenSharingEnabled = - getBooleanProp("sun.java2d.offscreenSharing", false); - String dpiOverride = System.getProperty("sun.java2d.dpiaware"); - if (dpiOverride != null) { - setHighDPIAware = dpiOverride.equalsIgnoreCase("true"); - } else { - String sunLauncherProperty = - System.getProperty("sun.java.launcher", "unknown"); - setHighDPIAware = - sunLauncherProperty.equalsIgnoreCase("SUN_STANDARD"); - } - /* - // Output info based on some non-default flags: - if (offscreenSharingEnabled) { + magPresent = getBooleanProp( + "javax.accessibility.screen_magnifier_present", false); + boolean ddEnabled = + !getBooleanProp("sun.java2d.noddraw", magPresent); + boolean ddOffscreenEnabled = + getBooleanProp("sun.java2d.ddoffscreen", ddEnabled); + d3dEnabled = getBooleanProp("sun.java2d.d3d", + ddEnabled && ddOffscreenEnabled); + d3dOnScreenEnabled = + getBooleanProp("sun.java2d.d3d.onscreen", d3dEnabled); + oglEnabled = getBooleanProp("sun.java2d.opengl", false); + if (oglEnabled) { + oglVerbose = isBooleanPropTrueVerbose("sun.java2d.opengl"); + if (WGLGraphicsConfig.isWGLAvailable()) { + d3dEnabled = false; + } else { + if (oglVerbose) { System.out.println( - "Warning: offscreenSharing has been enabled. " + - "The use of this capability will change in future " + - "releases and applications that depend on it " + - "may not work correctly"); + "Could not enable OpenGL pipeline " + + "(WGL not available)"); } - */ - return null; + oglEnabled = false; } - }); + } + gdiBlitEnabled = getBooleanProp("sun.java2d.gdiBlit", true); + d3dSet = getPropertySet("sun.java2d.d3d"); + if (d3dSet) { + d3dVerbose = isBooleanPropTrueVerbose("sun.java2d.d3d"); + } + offscreenSharingEnabled = + getBooleanProp("sun.java2d.offscreenSharing", false); + String dpiOverride = System.getProperty("sun.java2d.dpiaware"); + if (dpiOverride != null) { + setHighDPIAware = dpiOverride.equalsIgnoreCase("true"); + } else { + String sunLauncherProperty = + System.getProperty("sun.java.launcher", "unknown"); + setHighDPIAware = + sunLauncherProperty.equalsIgnoreCase("SUN_STANDARD"); + } + /* + // Output info based on some non-default flags: + if (offscreenSharingEnabled) { + System.out.println( + "Warning: offscreenSharing has been enabled. " + + "The use of this capability will change in future " + + "releases and applications that depend on it " + + "may not work correctly"); + } + */ /* System.out.println("WindowsFlags (Java):"); System.out.println(" ddEnabled: " + ddEnabled + "\n" + diff --git a/src/java.desktop/windows/classes/sun/print/PrintServiceLookupProvider.java b/src/java.desktop/windows/classes/sun/print/PrintServiceLookupProvider.java index 9079e7c2bfe..44173fb2abf 100644 --- a/src/java.desktop/windows/classes/sun/print/PrintServiceLookupProvider.java +++ b/src/java.desktop/windows/classes/sun/print/PrintServiceLookupProvider.java @@ -25,8 +25,6 @@ package sun.print; -import java.security.AccessController; -import java.security.PrivilegedAction; import java.util.ArrayList; import javax.print.DocFlavor; @@ -54,15 +52,9 @@ public class PrintServiceLookupProvider extends PrintServiceLookup { loadAWTLibrary(); } - @SuppressWarnings({"removal", "restricted"}) + @SuppressWarnings("restricted") private static void loadAWTLibrary() { - java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction<Void>() { - public Void run() { - System.loadLibrary("awt"); - return null; - } - }); + System.loadLibrary("awt"); } /* The singleton win32 print lookup service. @@ -85,31 +77,26 @@ public static PrintServiceLookupProvider getWin32PrintLUS() { return win32PrintLUS; } - @SuppressWarnings("removal") public PrintServiceLookupProvider() { if (win32PrintLUS == null) { win32PrintLUS = this; // start the local printer listener thread - AccessController.doPrivileged((PrivilegedAction<Thread>) () -> { - Thread thr = new Thread(ThreadGroupUtils.getRootThreadGroup(), - new PrinterChangeListener(), - "PrinterListener", 0, false); - thr.setContextClassLoader(null); - thr.setDaemon(true); - return thr; - }).start(); + Thread thr = new Thread(ThreadGroupUtils.getRootThreadGroup(), + new PrinterChangeListener(), + "PrinterListener", 0, false); + thr.setContextClassLoader(null); + thr.setDaemon(true); + thr.start(); // start the remote printer listener thread - AccessController.doPrivileged((PrivilegedAction<Thread>) () -> { - Thread thr = new Thread(ThreadGroupUtils.getRootThreadGroup(), - new RemotePrinterChangeListener(), - "RemotePrinterListener", 0, false); - thr.setContextClassLoader(null); - thr.setDaemon(true); - return thr; - }).start(); + Thread thr1 = new Thread(ThreadGroupUtils.getRootThreadGroup(), + new RemotePrinterChangeListener(), + "RemotePrinterListener", 0, false); + thr1.setContextClassLoader(null); + thr1.setDaemon(true); + thr1.start(); } /* else condition ought to never happen! */ } From d85dd77edf18c6efd3a7438c0595cd729af2f863 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eirik=20Bj=C3=B8rsn=C3=B8s?= <eirbjo@openjdk.org> Date: Tue, 19 Nov 2024 05:43:22 +0000 Subject: [PATCH 077/311] 8344365: SecurityManager cleanups in java.sql and java.sql.rowset modules Reviewed-by: rriggs, bchristi --- .../com/sun/rowset/CachedRowSetImpl.java | 20 +-- .../rowset/internal/CachedRowSetWriter.java | 4 +- .../javax/sql/rowset/RowSetProvider.java | 63 ++------ .../javax/sql/rowset/serial/SQLInputImpl.java | 4 +- .../sql/rowset/serial/SerialJavaObject.java | 17 -- .../javax/sql/rowset/spi/SyncFactory.java | 88 ++-------- .../share/classes/java/sql/DriverManager.java | 97 +++-------- test/jdk/java/sql/testng/util/TestPolicy.java | 150 ------------------ .../reflect/CallerSensitive/CheckCSMs.java | 8 +- 9 files changed, 54 insertions(+), 397 deletions(-) delete mode 100644 test/jdk/java/sql/testng/util/TestPolicy.java diff --git a/src/java.sql.rowset/share/classes/com/sun/rowset/CachedRowSetImpl.java b/src/java.sql.rowset/share/classes/com/sun/rowset/CachedRowSetImpl.java index 736431df313..f5bf8df6a4a 100644 --- a/src/java.sql.rowset/share/classes/com/sun/rowset/CachedRowSetImpl.java +++ b/src/java.sql.rowset/share/classes/com/sun/rowset/CachedRowSetImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -31,16 +31,12 @@ import java.math.*; import java.util.*; import java.text.*; -import java.security.AccessController; -import java.security.PrivilegedActionException; -import java.security.PrivilegedExceptionAction; import javax.sql.rowset.*; import javax.sql.rowset.spi.*; import javax.sql.rowset.serial.*; import com.sun.rowset.internal.*; import com.sun.rowset.providers.*; -import sun.reflect.misc.ReflectUtil; import static java.nio.charset.StandardCharsets.US_ASCII; @@ -357,7 +353,6 @@ public class CachedRowSetImpl extends BaseRowSet implements RowSet, RowSetIntern * <P> * @throws SQLException if an error occurs */ - @SuppressWarnings("removal") public CachedRowSetImpl() throws SQLException { try { @@ -367,16 +362,7 @@ public CachedRowSetImpl() throws SQLException { } // set the Reader, this maybe overridden latter - try { - provider = AccessController.doPrivileged(new PrivilegedExceptionAction<>() { - @Override - public SyncProvider run() throws SyncFactoryException { - return SyncFactory.getInstance(DEFAULT_SYNC_PROVIDER); - } - }, null, new RuntimePermission("accessClassInPackage.com.sun.rowset.providers")); - } catch (PrivilegedActionException pae) { - throw (SyncFactoryException) pae.getException(); - } + provider = SyncFactory.getInstance(DEFAULT_SYNC_PROVIDER); if (!(provider instanceof RIOptimisticProvider)) { throw new SQLException(resBundle.handleGetObject("cachedrowsetimpl.invalidp").toString()); @@ -2976,7 +2962,6 @@ public Object getObject(int columnIndex) throws SQLException { // create new instance of the class SQLData obj = null; try { - ReflectUtil.checkPackageAccess(c); @SuppressWarnings("deprecation") Object tmp = c.newInstance(); obj = (SQLData) tmp; @@ -5726,7 +5711,6 @@ public Object getObject(int columnIndex, // create new instance of the class SQLData obj = null; try { - ReflectUtil.checkPackageAccess(c); @SuppressWarnings("deprecation") Object tmp = c.newInstance(); obj = (SQLData) tmp; diff --git a/src/java.sql.rowset/share/classes/com/sun/rowset/internal/CachedRowSetWriter.java b/src/java.sql.rowset/share/classes/com/sun/rowset/internal/CachedRowSetWriter.java index 6e4d3671651..56f0d30c6df 100644 --- a/src/java.sql.rowset/share/classes/com/sun/rowset/internal/CachedRowSetWriter.java +++ b/src/java.sql.rowset/share/classes/com/sun/rowset/internal/CachedRowSetWriter.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -29,7 +29,6 @@ import javax.sql.*; import java.util.*; import java.io.*; -import sun.reflect.misc.ReflectUtil; import com.sun.rowset.*; import java.text.MessageFormat; @@ -575,7 +574,6 @@ private boolean updateOriginalRow(CachedRowSet crs) // create new instance of the class SQLData obj = null; try { - ReflectUtil.checkPackageAccess(c); @SuppressWarnings("deprecation") Object tmp = c.newInstance(); obj = (SQLData)tmp; diff --git a/src/java.sql.rowset/share/classes/javax/sql/rowset/RowSetProvider.java b/src/java.sql.rowset/share/classes/javax/sql/rowset/RowSetProvider.java index f69ece6e469..37558222d9c 100644 --- a/src/java.sql.rowset/share/classes/javax/sql/rowset/RowSetProvider.java +++ b/src/java.sql.rowset/share/classes/javax/sql/rowset/RowSetProvider.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,13 +25,9 @@ package javax.sql.rowset; -import java.security.AccessController; -import java.security.PrivilegedAction; import java.sql.SQLException; -import java.util.PropertyPermission; import java.util.ServiceConfigurationError; import java.util.ServiceLoader; -import sun.reflect.misc.ReflectUtil; /** * A factory API that enables applications to obtain a @@ -68,7 +64,7 @@ public class RowSetProvider { static { // Check to see if the debug property is set - String val = getSystemProperty(ROWSET_DEBUG_PROPERTY); + String val = System.getProperty(ROWSET_DEBUG_PROPERTY); // Allow simply setting the prop to turn on debug debug = val != null && !"false".equals(val); } @@ -128,7 +124,8 @@ public static RowSetFactory newFactory() String factoryClassName = null; try { trace("Checking for Rowset System Property..."); - factoryClassName = getSystemProperty(ROWSET_FACTORY_NAME); + + factoryClassName = System.getProperty(ROWSET_FACTORY_NAME); if (factoryClassName != null) { trace("Found system property, value=" + factoryClassName); if (factoryClassName.equals(ROWSET_FACTORY_IMPL)) { @@ -193,11 +190,6 @@ public static RowSetFactory newFactory(String factoryClassName, ClassLoader cl) if(factoryClassName == null) { throw new SQLException("Error: factoryClassName cannot be null"); } - try { - ReflectUtil.checkPackageAccess(factoryClassName); - } catch (@SuppressWarnings("removal") java.security.AccessControlException e) { - throw new SQLException("Access Exception",e); - } try { // getFactoryClass takes care of adding the read edge if @@ -225,22 +217,14 @@ public static RowSetFactory newFactory(String factoryClassName, ClassLoader cl) * @return The ClassLoader to use. * */ - @SuppressWarnings("removal") - private static ClassLoader getContextClassLoader() throws SecurityException { - return AccessController.doPrivileged(new PrivilegedAction<ClassLoader>() { - - public ClassLoader run() { - ClassLoader cl = null; - - cl = Thread.currentThread().getContextClassLoader(); + private static ClassLoader getContextClassLoader() { + ClassLoader cl = Thread.currentThread().getContextClassLoader(); - if (cl == null) { - cl = ClassLoader.getSystemClassLoader(); - } + if (cl == null) { + cl = ClassLoader.getSystemClassLoader(); + } - return cl; - } - }); + return cl; } /** @@ -276,7 +260,6 @@ private static Class<?> getFactoryClass(String factoryClassName, ClassLoader cl, } } - ReflectUtil.checkPackageAccess(factoryClass); return factoryClass; } @@ -302,32 +285,6 @@ private static RowSetFactory loadViaServiceLoader() throws SQLException { } - /** - * Returns the requested System Property. If a {@code SecurityException} - * occurs, just return NULL - * @param propName - System property to retrieve - * @return The System property value or NULL if the property does not exist - * or a {@code SecurityException} occurs. - */ - @SuppressWarnings("removal") - private static String getSystemProperty(final String propName) { - String property = null; - try { - property = AccessController.doPrivileged(new PrivilegedAction<String>() { - - public String run() { - return System.getProperty(propName); - } - }, null, new PropertyPermission(propName, "read")); - } catch (SecurityException se) { - trace("error getting " + propName + ": "+ se); - if (debug) { - se.printStackTrace(); - } - } - return property; - } - /** * Debug routine which will output tracing if the System Property * -Djavax.sql.rowset.RowSetFactory.debug is set diff --git a/src/java.sql.rowset/share/classes/javax/sql/rowset/serial/SQLInputImpl.java b/src/java.sql.rowset/share/classes/javax/sql/rowset/serial/SQLInputImpl.java index 421d4943763..d2daa565baa 100644 --- a/src/java.sql.rowset/share/classes/javax/sql/rowset/serial/SQLInputImpl.java +++ b/src/java.sql.rowset/share/classes/javax/sql/rowset/serial/SQLInputImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -27,7 +27,6 @@ import java.sql.*; import java.util.Arrays; import java.util.Map; -import sun.reflect.misc.ReflectUtil; /** * An input stream used for custom mapping user-defined types (UDTs). @@ -477,7 +476,6 @@ public Object readObject() throws SQLException { // create new instance of the class SQLData obj = null; try { - ReflectUtil.checkPackageAccess(c); @SuppressWarnings("deprecation") Object tmp = c.newInstance(); obj = (SQLData)tmp; diff --git a/src/java.sql.rowset/share/classes/javax/sql/rowset/serial/SerialJavaObject.java b/src/java.sql.rowset/share/classes/javax/sql/rowset/serial/SerialJavaObject.java index 00284c5ce51..154c95bc1c4 100644 --- a/src/java.sql.rowset/share/classes/javax/sql/rowset/serial/SerialJavaObject.java +++ b/src/java.sql.rowset/share/classes/javax/sql/rowset/serial/SerialJavaObject.java @@ -30,9 +30,6 @@ import java.util.Arrays; import java.util.Vector; import javax.sql.rowset.RowSetWarning; -import jdk.internal.reflect.CallerSensitive; -import jdk.internal.reflect.Reflection; -import sun.reflect.misc.ReflectUtil; /** * A serializable mapping in the Java programming language of an SQL @@ -125,23 +122,9 @@ public Object getObject() throws SerialException { * the serialized object * @see Class#getFields */ - @CallerSensitive public Field[] getFields() throws SerialException { if (fields != null) { Class<?> c = this.obj.getClass(); - @SuppressWarnings("removal") - SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - /* - * Check if the caller is allowed to access the specified class's package. - * If access is denied, throw a SecurityException. - */ - Class<?> caller = Reflection.getCallerClass(); - if (ReflectUtil.needsPackageAccessCheck(caller.getClassLoader(), - c.getClassLoader())) { - ReflectUtil.checkPackageAccess(c); - } - } return c.getFields(); } else { throw new SerialException("SerialJavaObject does not contain" + diff --git a/src/java.sql.rowset/share/classes/javax/sql/rowset/spi/SyncFactory.java b/src/java.sql.rowset/share/classes/javax/sql/rowset/spi/SyncFactory.java index 90dea7760fb..9cc7a5b2da8 100644 --- a/src/java.sql.rowset/share/classes/javax/sql/rowset/spi/SyncFactory.java +++ b/src/java.sql.rowset/share/classes/javax/sql/rowset/spi/SyncFactory.java @@ -35,13 +35,8 @@ import java.io.InputStream; import java.io.IOException; import java.io.FileNotFoundException; -import java.security.AccessController; -import java.security.PrivilegedAction; -import java.security.PrivilegedActionException; -import java.security.PrivilegedExceptionAction; import javax.naming.*; -import sun.reflect.misc.ReflectUtil; /** * The Service Provider Interface (SPI) mechanism that generates <code>SyncProvider</code> @@ -236,11 +231,6 @@ private SyncFactory() { */ private static String ROWSET_PROPERTIES = "rowset.properties"; - /** - * Permission required to invoke setJNDIContext and setLogger - */ - private static final SQLPermission SET_SYNCFACTORY_PERMISSION = - new SQLPermission("setSyncFactory"); /** * The initial JNDI context where <code>SyncProvider</code> implementations can * be stored and from which they can be invoked. @@ -355,17 +345,7 @@ private static synchronized void initMapIfNecessary() throws SyncFactoryExceptio /* * Dependent on application */ - String strRowsetProperties; - try { - strRowsetProperties = AccessController.doPrivileged(new PrivilegedAction<String>() { - public String run() { - return System.getProperty("rowset.properties"); - } - }, null, new PropertyPermission("rowset.properties", "read")); - } catch (Exception ex) { - System.out.println("errorget rowset.properties: " + ex); - strRowsetProperties = null; - }; + String strRowsetProperties = System.getProperty("rowset.properties"); if (strRowsetProperties != null) { // Load user's implementation of SyncProvider @@ -385,25 +365,17 @@ public String run() { "rowset.properties"; try { - AccessController.doPrivileged((PrivilegedExceptionAction<Void>) () -> { - InputStream in = SyncFactory.class.getModule().getResourceAsStream(ROWSET_PROPERTIES); - if (in == null) { - throw new SyncFactoryException("Resource " + ROWSET_PROPERTIES + " not found"); - } - try (in) { - properties.load(in); - } - return null; - }); - } catch (PrivilegedActionException ex) { - Throwable e = ex.getException(); - if (e instanceof SyncFactoryException) { - throw (SyncFactoryException) e; - } else { - SyncFactoryException sfe = new SyncFactoryException(); - sfe.initCause(ex.getException()); - throw sfe; + InputStream in = SyncFactory.class.getModule().getResourceAsStream(ROWSET_PROPERTIES); + if (in == null) { + throw new SyncFactoryException("Resource " + ROWSET_PROPERTIES + " not found"); } + try (in) { + properties.load(in); + } + } catch (IOException e) { + SyncFactoryException sfe = new SyncFactoryException(); + sfe.initCause(e); + throw sfe; } parseProperties(properties); @@ -421,17 +393,7 @@ public String run() { * load additional properties from -D command line */ properties.clear(); - String providerImpls; - try { - providerImpls = AccessController.doPrivileged(new PrivilegedAction<String>() { - public String run() { - return System.getProperty(ROWSET_SYNC_PROVIDER); - } - }, null, new PropertyPermission(ROWSET_SYNC_PROVIDER, "read")); - } catch (Exception ex) { - providerImpls = null; - } - + String providerImpls = System.getProperty(ROWSET_SYNC_PROVIDER); if (providerImpls != null) { int i = 0; if (providerImpls.indexOf(colon) > 0) { @@ -563,14 +525,6 @@ public static SyncProvider getInstance(String providerID) return new com.sun.rowset.providers.RIOptimisticProvider(); } - try { - ReflectUtil.checkPackageAccess(providerID); - } catch (@SuppressWarnings("removal") java.security.AccessControlException e) { - SyncFactoryException sfe = new SyncFactoryException(); - sfe.initCause(e); - throw sfe; - } - // Attempt to invoke classname from registered SyncProvider list Class<?> c = null; try { @@ -626,12 +580,6 @@ public static Enumeration<SyncProvider> getRegisteredProviders() */ public static void setLogger(Logger logger) { - @SuppressWarnings("removal") - SecurityManager sec = System.getSecurityManager(); - if (sec != null) { - sec.checkPermission(SET_SYNCFACTORY_PERMISSION); - } - if(logger == null){ throw new NullPointerException("You must provide a Logger"); } @@ -652,12 +600,6 @@ public static void setLogger(Logger logger) { */ public static void setLogger(Logger logger, Level level) { // singleton - @SuppressWarnings("removal") - SecurityManager sec = System.getSecurityManager(); - if (sec != null) { - sec.checkPermission(SET_SYNCFACTORY_PERMISSION); - } - if(logger == null){ throw new NullPointerException("You must provide a Logger"); } @@ -692,11 +634,7 @@ public static Logger getLogger() throws SyncFactoryException { */ public static synchronized void setJNDIContext(javax.naming.Context ctx) throws SyncFactoryException { - @SuppressWarnings("removal") - SecurityManager sec = System.getSecurityManager(); - if (sec != null) { - sec.checkPermission(SET_SYNCFACTORY_PERMISSION); - } + if (ctx == null) { throw new SyncFactoryException("Invalid JNDI context supplied"); } diff --git a/src/java.sql/share/classes/java/sql/DriverManager.java b/src/java.sql/share/classes/java/sql/DriverManager.java index 918d0692a1a..7620a11e6fd 100644 --- a/src/java.sql/share/classes/java/sql/DriverManager.java +++ b/src/java.sql/share/classes/java/sql/DriverManager.java @@ -31,8 +31,6 @@ import java.util.Iterator; import java.util.List; import java.util.ServiceLoader; -import java.security.AccessController; -import java.security.PrivilegedAction; import java.util.concurrent.CopyOnWriteArrayList; import java.util.stream.Stream; @@ -98,22 +96,6 @@ public class DriverManager { /* Prevent the DriverManager class from being instantiated. */ private DriverManager(){} - /** - * The {@code SQLPermission} constant that allows the - * setting of the logging stream. - * @since 1.3 - */ - static final SQLPermission SET_LOG_PERMISSION = - new SQLPermission("setLog"); - - /** - * The {@code SQLPermission} constant that allows the - * un-register a registered JDBC driver. - * @since 1.8 - */ - static final SQLPermission DEREGISTER_DRIVER_PERMISSION = - new SQLPermission("deregisterDriver"); - //--------------------------JDBC 2.0----------------------------- /** @@ -140,14 +122,8 @@ public static java.io.PrintWriter getLogWriter() { * @since 1.2 */ public static void setLogWriter(java.io.PrintWriter out) { - - @SuppressWarnings("removal") - SecurityManager sec = System.getSecurityManager(); - if (sec != null) { - sec.checkPermission(SET_LOG_PERMISSION); - } - logStream = null; - logWriter = out; + logStream = null; + logWriter = out; } @@ -367,12 +343,6 @@ public static void deregisterDriver(Driver driver) throws SQLException { return; } - @SuppressWarnings("removal") - SecurityManager sec = System.getSecurityManager(); - if (sec != null) { - sec.checkPermission(DEREGISTER_DRIVER_PERMISSION); - } - println("DriverManager.deregisterDriver: " + driver); DriverInfo aDriver = new DriverInfo(driver, null); @@ -477,13 +447,6 @@ public static int getLoginTimeout() { */ @Deprecated(since="1.2") public static void setLogStream(java.io.PrintStream out) { - - @SuppressWarnings("removal") - SecurityManager sec = System.getSecurityManager(); - if (sec != null) { - sec.checkPermission(SET_LOG_PERMISSION); - } - logStream = out; if ( out != null ) logWriter = new java.io.PrintWriter(out); @@ -549,7 +512,6 @@ private static boolean isDriverAllowed(Driver driver, ClassLoader classLoader) { * Load the initial JDBC drivers by checking the System property * jdbc.drivers and then use the {@code ServiceLoader} mechanism */ - @SuppressWarnings("removal") private static void ensureDriversInitialized() { if (driversInitialized) { return; @@ -561,11 +523,7 @@ private static void ensureDriversInitialized() { } String drivers; try { - drivers = AccessController.doPrivileged(new PrivilegedAction<String>() { - public String run() { - return System.getProperty(JDBC_DRIVERS_PROPERTY); - } - }); + drivers = System.getProperty(JDBC_DRIVERS_PROPERTY); } catch (Exception ex) { drivers = null; } @@ -574,34 +532,29 @@ public String run() { // exposed as a java.sql.Driver.class service. // ServiceLoader.load() replaces the sun.misc.Providers() - AccessController.doPrivileged(new PrivilegedAction<Void>() { - public Void run() { - - ServiceLoader<Driver> loadedDrivers = ServiceLoader.load(Driver.class); - Iterator<Driver> driversIterator = loadedDrivers.iterator(); - - /* Load these drivers, so that they can be instantiated. - * It may be the case that the driver class may not be there - * i.e. there may be a packaged driver with the service class - * as implementation of java.sql.Driver but the actual class - * may be missing. In that case a java.util.ServiceConfigurationError - * will be thrown at runtime by the VM trying to locate - * and load the service. - * - * Adding a try catch block to catch those runtime errors - * if driver not available in classpath but it's - * packaged as service and that service is there in classpath. - */ - try { - while (driversIterator.hasNext()) { - driversIterator.next(); - } - } catch (Throwable t) { - // Do nothing - } - return null; + + ServiceLoader<Driver> loadedDrivers = ServiceLoader.load(Driver.class); + Iterator<Driver> driversIterator = loadedDrivers.iterator(); + + /* Load these drivers, so that they can be instantiated. + * It may be the case that the driver class may not be there + * i.e. there may be a packaged driver with the service class + * as implementation of java.sql.Driver but the actual class + * may be missing. In that case a java.util.ServiceConfigurationError + * will be thrown at runtime by the VM trying to locate + * and load the service. + * + * Adding a try catch block to catch those runtime errors + * if driver not available in classpath but it's + * packaged as service and that service is there in classpath. + */ + try { + while (driversIterator.hasNext()) { + driversIterator.next(); } - }); + } catch (Throwable t) { + // Do nothing + } println("DriverManager.initialize: jdbc.drivers = " + drivers); diff --git a/test/jdk/java/sql/testng/util/TestPolicy.java b/test/jdk/java/sql/testng/util/TestPolicy.java deleted file mode 100644 index 013dfad563c..00000000000 --- a/test/jdk/java/sql/testng/util/TestPolicy.java +++ /dev/null @@ -1,150 +0,0 @@ -/* - * Copyright (c) 2014, 2021, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package util; - -import java.io.FilePermission; -import java.lang.reflect.ReflectPermission; -import java.security.AllPermission; -import java.security.CodeSource; -import java.security.Permission; -import java.security.PermissionCollection; -import java.security.Permissions; -import java.security.Policy; -import java.security.ProtectionDomain; -import java.security.SecurityPermission; -import java.sql.SQLPermission; -import java.util.Enumeration; -import java.util.PropertyPermission; -import java.util.StringJoiner; -import java.util.logging.LoggingPermission; - -/* - * Simple Policy class that supports the required Permissions to validate the - * JDBC concrete classes - */ -public class TestPolicy extends Policy { - static final Policy DEFAULT_POLICY = Policy.getPolicy(); - - final PermissionCollection permissions = new Permissions(); - - /** - * Constructor which sets the minimum permissions allowing testNG to work - * with a SecurityManager - */ - public TestPolicy() { - setMinimalPermissions(); - } - - /* - * Constructor which determines which permissions are defined for this - * Policy used by the JDBC tests Possible values are: all (ALLPermissions), - * setLog (SQLPemission("setLog"), deregisterDriver - * (SQLPermission("deregisterDriver") (SQLPermission("deregisterDriver"), - * setSyncFactory(SQLPermission(setSyncFactory), and also - * LoggerPermission("control", null) when setting a Level - * - * @param policy Permissions to set - */ - public TestPolicy(String policy) { - - switch (policy) { - case "all": - permissions.add(new AllPermission()); - break; - case "setLog": - setMinimalPermissions(); - permissions.add(new SQLPermission("setLog")); - break; - case "deregisterDriver": - setMinimalPermissions(); - permissions.add(new SQLPermission("deregisterDriver")); - break; - case "setSyncFactory": - setMinimalPermissions(); - permissions.add(new SQLPermission("setSyncFactory")); - break; - case "setSyncFactoryLogger": - setMinimalPermissions(); - permissions.add(new SQLPermission("setSyncFactory")); - permissions.add(new LoggingPermission("control", null)); - break; - default: - setMinimalPermissions(); - } - } - - /* - * Defines the minimal permissions required by testNG when running these - * tests - */ - private void setMinimalPermissions() { - permissions.add(new SecurityPermission("getPolicy")); - permissions.add(new SecurityPermission("setPolicy")); - permissions.add(new RuntimePermission("getClassLoader")); - permissions.add(new RuntimePermission("setSecurityManager")); - permissions.add(new RuntimePermission("createSecurityManager")); - permissions.add(new PropertyPermission("line.separator", "read")); - permissions.add(new PropertyPermission("fileStringBuffer", "read")); - permissions.add(new PropertyPermission("dataproviderthreadcount", "read")); - permissions.add(new PropertyPermission("java.io.tmpdir", "read")); - permissions.add(new PropertyPermission("testng.show.stack.frames", - "read")); - permissions.add(new PropertyPermission("testng.thread.affinity", "read")); - permissions.add(new PropertyPermission("testng.memory.friendly", "read")); - permissions.add(new PropertyPermission("testng.mode.dryrun", "read")); - permissions.add(new PropertyPermission("testng.report.xml.name", "read")); - permissions.add(new PropertyPermission("testng.timezone", "read")); - permissions.add(new ReflectPermission("suppressAccessChecks")); - permissions.add(new FilePermission("<<ALL FILES>>", - "read, write, delete")); - } - - /* - * Overloaded methods from the Policy class - */ - @Override - public String toString() { - StringJoiner sj = new StringJoiner("\n", "policy: ", ""); - Enumeration<Permission> perms = permissions.elements(); - while (perms.hasMoreElements()) { - sj.add(perms.nextElement().toString()); - } - return sj.toString(); - - } - - @Override - public PermissionCollection getPermissions(ProtectionDomain domain) { - return permissions; - } - - @Override - public PermissionCollection getPermissions(CodeSource codesource) { - return permissions; - } - - @Override - public boolean implies(ProtectionDomain domain, Permission perm) { - return permissions.implies(perm) || DEFAULT_POLICY.implies(domain, perm); - } -} diff --git a/test/jdk/jdk/internal/reflect/CallerSensitive/CheckCSMs.java b/test/jdk/jdk/internal/reflect/CallerSensitive/CheckCSMs.java index 6b63ce122a3..83841fe104b 100644 --- a/test/jdk/jdk/internal/reflect/CallerSensitive/CheckCSMs.java +++ b/test/jdk/jdk/internal/reflect/CallerSensitive/CheckCSMs.java @@ -71,16 +71,12 @@ public class CheckCSMs { // over time. Do not add any new one to this list. private static final Set<String> KNOWN_NON_FINAL_CSMS = Set.of("java/lang/Runtime#load (Ljava/lang/String;)V", - "java/lang/Runtime#loadLibrary (Ljava/lang/String;)V", - "javax/sql/rowset/serial/SerialJavaObject#getFields ()[Ljava/lang/reflect/Field;" + "java/lang/Runtime#loadLibrary (Ljava/lang/String;)V" ); // These non-static non-final methods must not have @CallerSensitiveAdapter // methods that takes an additional caller class parameter. - private static Set<String> UNSUPPORTED_VIRTUAL_METHODS = - Set.of("java/io/ObjectStreamField#getType (Ljava/lang/Class;)Ljava/lang/Class;", - "javax/sql/rowset/serial/SerialJavaObject#getFields (Ljava/lang/Class;)[Ljava/lang/reflect/Field;" - ); + private static Set<String> UNSUPPORTED_VIRTUAL_METHODS = Set.of(); public static void main(String[] args) throws Exception { if (args.length > 0 && args[0].equals("--list")) { From b12c5b4d18d9bd53e44e515ac1fac548ceeb3dc6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eirik=20Bj=C3=B8rsn=C3=B8s?= <eirbjo@openjdk.org> Date: Tue, 19 Nov 2024 05:44:30 +0000 Subject: [PATCH 078/311] 8344218: Remove calls to SecurityManager and and doPrivileged in java.net.NetworkInterface after JEP 486 integration Reviewed-by: dfuchs --- .../classes/java/net/NetworkInterface.java | 94 +++++-------------- 1 file changed, 21 insertions(+), 73 deletions(-) diff --git a/src/java.base/share/classes/java/net/NetworkInterface.java b/src/java.base/share/classes/java/net/NetworkInterface.java index 1c5edd1c23f..29a07d9b76d 100644 --- a/src/java.base/share/classes/java/net/NetworkInterface.java +++ b/src/java.base/share/classes/java/net/NetworkInterface.java @@ -27,6 +27,7 @@ import java.util.Arrays; import java.util.Enumeration; +import java.util.List; import java.util.NoSuchElementException; import java.util.Objects; import java.util.Spliterator; @@ -79,9 +80,9 @@ public final class NetworkInterface { private String name; private String displayName; private int index; - private InetAddress addrs[]; - private InterfaceAddress bindings[]; - private NetworkInterface childs[]; + private InetAddress[] addrs; + private InterfaceAddress[] bindings; + private NetworkInterface[] childs; private NetworkInterface parent = null; private boolean virtual = false; private static final NetworkInterface defaultInterface; @@ -118,87 +119,46 @@ public String getName() { } /** - * Get an Enumeration with all, or a subset, of the InetAddresses bound to - * this network interface. + * Get an Enumeration of the InetAddresses bound to this network interface. * * @implNote - * The returned enumeration contains all, or a subset, of the InetAddresses that were - * bound to the interface at the time the {@linkplain #getNetworkInterfaces() + * The returned enumeration contains the InetAddresses that were bound to + * the interface at the time the {@linkplain #getNetworkInterfaces() * interface configuration was read} * - * @return an Enumeration object with all, or a subset, of the InetAddresses - * bound to this network interface + * @return an Enumeration object with the InetAddresses bound to this + * network interface * @see #inetAddresses() */ public Enumeration<InetAddress> getInetAddresses() { - return enumerationFromArray(getCheckedInetAddresses()); + return enumerationFromArray(addrs); } /** - * Get a Stream of all, or a subset, of the InetAddresses bound to this - * network interface. + * Get a Stream of the InetAddresses bound to this network interface. * * @implNote - * The stream contains all, or a subset, of the InetAddresses that were - * bound to the interface at the time the {@linkplain #getNetworkInterfaces() + * The stream contains the InetAddresses that were bound to the + * interface at the time the {@linkplain #getNetworkInterfaces() * interface configuration was read} * - * @return a Stream object with all, or a subset, of the InetAddresses - * bound to this network interface + * @return a Stream object with the InetAddresses bound to this network interface * @since 9 */ public Stream<InetAddress> inetAddresses() { - return streamFromArray(getCheckedInetAddresses()); - } - - private InetAddress[] getCheckedInetAddresses() { - InetAddress[] local_addrs = new InetAddress[addrs.length]; - boolean trusted = true; - - @SuppressWarnings("removal") - SecurityManager sec = System.getSecurityManager(); - if (sec != null) { - try { - sec.checkPermission(new NetPermission("getNetworkInformation")); - } catch (SecurityException e) { - trusted = false; - } - } - int i = 0; - for (int j = 0; j < addrs.length; j++) { - try { - if (!trusted) { - sec.checkConnect(addrs[j].getHostAddress(), -1); - } - local_addrs[i++] = addrs[j]; - } catch (SecurityException e) { } - } - return Arrays.copyOf(local_addrs, i); + return streamFromArray(addrs); } /** - * Get a List of all, or a subset, of the {@code InterfaceAddresses} - * of this network interface. + * Get a List of the {@code InterfaceAddresses} of this network interface. + * + * @return a {@code List} object with the InterfaceAddress of this + * network interface * - * @return a {@code List} object with all, or a subset, of the - * InterfaceAddress of this network interface * @since 1.6 */ - public java.util.List<InterfaceAddress> getInterfaceAddresses() { - java.util.List<InterfaceAddress> lst = new java.util.ArrayList<>(1); - if (bindings != null) { - @SuppressWarnings("removal") - SecurityManager sec = System.getSecurityManager(); - for (int j=0; j<bindings.length; j++) { - try { - if (sec != null) { - sec.checkConnect(bindings[j].getAddress().getHostAddress(), -1); - } - lst.add(bindings[j]); - } catch (SecurityException e) { } - } - } - return lst; + public List<InterfaceAddress> getInterfaceAddresses() { + return bindings == null ? List.of() : List.of(bindings); } /** @@ -556,18 +516,6 @@ public boolean supportsMulticast() throws SocketException { * @since 1.6 */ public byte[] getHardwareAddress() throws SocketException { - @SuppressWarnings("removal") - SecurityManager sec = System.getSecurityManager(); - if (sec != null) { - try { - sec.checkPermission(new NetPermission("getNetworkInformation")); - } catch (SecurityException e) { - if (!getInetAddresses().hasMoreElements()) { - // don't have connect permission to any local address - return null; - } - } - } if (isLoopback0(name, index)) { return null; } From 499186be0fa70dba4b008cdafb72aba6addb2965 Mon Sep 17 00:00:00 2001 From: Prasanta Sadhukhan <psadhukhan@openjdk.org> Date: Tue, 19 Nov 2024 06:37:49 +0000 Subject: [PATCH 079/311] 8343902: javax/swing/plaf/nimbus/8041642/bug8041642.java fails in ubuntu22.04 Reviewed-by: azvegint --- .../swing/plaf/nimbus/8041642/bug8041642.java | 29 +++++++++++++++---- 1 file changed, 23 insertions(+), 6 deletions(-) diff --git a/test/jdk/javax/swing/plaf/nimbus/8041642/bug8041642.java b/test/jdk/javax/swing/plaf/nimbus/8041642/bug8041642.java index 9eeaa0e1b9e..7779a4d6bd4 100644 --- a/test/jdk/javax/swing/plaf/nimbus/8041642/bug8041642.java +++ b/test/jdk/javax/swing/plaf/nimbus/8041642/bug8041642.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,11 +26,21 @@ * @key headful * @bug 8041642 8079450 8140237 * @summary Incorrect paint of JProgressBar in Nimbus LF - * @author Semyon Sadetsky */ -import javax.swing.*; -import java.awt.*; +import java.io.File; +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Graphics; +import java.awt.Point; +import java.awt.Rectangle; +import java.awt.Robot; +import java.awt.image.BufferedImage; +import javax.imageio.ImageIO; +import javax.swing.JFrame; +import javax.swing.JProgressBar; +import javax.swing.SwingUtilities; +import javax.swing.UIManager; public class bug8041642 { @@ -50,7 +60,8 @@ public void run() { } }); final Robot robot = new Robot(); - robot.delay(300); + robot.waitForIdle(); + robot.delay(1000); SwingUtilities.invokeAndWait(new Runnable() { @Override public void run() { @@ -58,9 +69,15 @@ public void run() { } }); Color color = robot.getPixelColor(point.x + 1, point.y + 7); - System.out.println(color); + System.out.println("point " + point + " color " + color); if (color.getGreen() < 150 || color.getBlue() > 30 || color.getRed() > 200) { + Rectangle bounds = frame.getBounds(); + BufferedImage img = new BufferedImage(bounds.width, bounds.height, BufferedImage.TYPE_INT_ARGB); + Graphics g = img.getGraphics(); + frame.paint(g); + g.dispose(); + ImageIO.write(img, "png", new File("bug8041642.png")); throw new RuntimeException("Bar padding color should be green"); } From 76a55c3cb6e5177442f355ae1036db4fbf8e54af Mon Sep 17 00:00:00 2001 From: Aleksey Shipilev <shade@openjdk.org> Date: Tue, 19 Nov 2024 08:45:02 +0000 Subject: [PATCH 080/311] 8341334: CDS: Parallel relocation Reviewed-by: iklam, adinn, stuefe --- src/hotspot/share/cds/archiveUtils.cpp | 185 ++++++++++++++++++++++ src/hotspot/share/cds/archiveUtils.hpp | 93 +++++++++++ src/hotspot/share/cds/cds_globals.hpp | 5 +- src/hotspot/share/cds/filemap.cpp | 36 ++++- src/hotspot/share/cds/metaspaceShared.cpp | 6 + src/hotspot/share/runtime/java.cpp | 5 + 6 files changed, 327 insertions(+), 3 deletions(-) diff --git a/src/hotspot/share/cds/archiveUtils.cpp b/src/hotspot/share/cds/archiveUtils.cpp index 4d717879e0f..3c778cbb523 100644 --- a/src/hotspot/share/cds/archiveUtils.cpp +++ b/src/hotspot/share/cds/archiveUtils.cpp @@ -399,3 +399,188 @@ size_t HeapRootSegments::segment_offset(size_t seg_idx) { return _base_offset + seg_idx * _max_size_in_bytes; } +ArchiveWorkers ArchiveWorkers::_workers; + +ArchiveWorkers::ArchiveWorkers() : + _start_semaphore(0), + _end_semaphore(0), + _num_workers(0), + _started_workers(0), + _waiting_workers(0), + _running_workers(0), + _state(NOT_READY), + _task(nullptr) { +} + +void ArchiveWorkers::initialize() { + assert(Atomic::load(&_state) == NOT_READY, "Should be"); + + Atomic::store(&_num_workers, max_workers()); + Atomic::store(&_state, READY); + + // Kick off pool startup by creating a single worker. + start_worker_if_needed(); +} + +int ArchiveWorkers::max_workers() { + // The pool is used for short-lived bursty tasks. We do not want to spend + // too much time creating and waking up threads unnecessarily. Plus, we do + // not want to overwhelm large machines. This is why we want to be very + // conservative about the number of workers actually needed. + return MAX2(0, log2i_graceful(os::active_processor_count())); +} + +bool ArchiveWorkers::is_parallel() { + return _num_workers > 0; +} + +void ArchiveWorkers::shutdown() { + while (true) { + State state = Atomic::load(&_state); + if (state == SHUTDOWN) { + // Already shut down. + return; + } + if (Atomic::cmpxchg(&_state, state, SHUTDOWN, memory_order_relaxed) == state) { + if (is_parallel()) { + // Execute a shutdown task and block until all workers respond. + run_task(&_shutdown_task); + } + } + } +} + +void ArchiveWorkers::start_worker_if_needed() { + while (true) { + int cur = Atomic::load(&_started_workers); + if (cur >= _num_workers) { + return; + } + if (Atomic::cmpxchg(&_started_workers, cur, cur + 1, memory_order_relaxed) == cur) { + new ArchiveWorkerThread(this); + return; + } + } +} + +void ArchiveWorkers::signal_worker_if_needed() { + while (true) { + int cur = Atomic::load(&_waiting_workers); + if (cur == 0) { + return; + } + if (Atomic::cmpxchg(&_waiting_workers, cur, cur - 1, memory_order_relaxed) == cur) { + _start_semaphore.signal(1); + return; + } + } +} + +void ArchiveWorkers::run_task(ArchiveWorkerTask* task) { + assert((Atomic::load(&_state) == READY) || + ((Atomic::load(&_state) == SHUTDOWN) && (task == &_shutdown_task)), + "Should be in correct state"); + assert(Atomic::load(&_task) == nullptr, "Should not have running tasks"); + + if (is_parallel()) { + run_task_multi(task); + } else { + run_task_single(task); + } +} + +void ArchiveWorkers::run_task_single(ArchiveWorkerTask* task) { + // Single thread needs no chunking. + task->configure_max_chunks(1); + + // Execute the task ourselves, as there are no workers. + task->work(0, 1); +} + +void ArchiveWorkers::run_task_multi(ArchiveWorkerTask* task) { + // Multiple threads can work with multiple chunks. + task->configure_max_chunks(_num_workers * CHUNKS_PER_WORKER); + + // Set up the run and publish the task. + Atomic::store(&_waiting_workers, _num_workers); + Atomic::store(&_running_workers, _num_workers); + Atomic::release_store(&_task, task); + + // Kick off pool wakeup by signaling a single worker, and proceed + // immediately to executing the task locally. + signal_worker_if_needed(); + + // Execute the task ourselves, while workers are catching up. + // This allows us to hide parts of task handoff latency. + task->run(); + + // Done executing task locally, wait for any remaining workers to complete, + // and then do the final housekeeping. + _end_semaphore.wait(); + Atomic::store(&_task, (ArchiveWorkerTask *) nullptr); + OrderAccess::fence(); + + assert(Atomic::load(&_waiting_workers) == 0, "All workers were signaled"); + assert(Atomic::load(&_running_workers) == 0, "No workers are running"); +} + +void ArchiveWorkerTask::run() { + while (true) { + int chunk = Atomic::load(&_chunk); + if (chunk >= _max_chunks) { + return; + } + if (Atomic::cmpxchg(&_chunk, chunk, chunk + 1, memory_order_relaxed) == chunk) { + assert(0 <= chunk && chunk < _max_chunks, "Sanity"); + work(chunk, _max_chunks); + } + } +} + +void ArchiveWorkerTask::configure_max_chunks(int max_chunks) { + if (_max_chunks == 0) { + _max_chunks = max_chunks; + } +} + +bool ArchiveWorkers::run_as_worker() { + assert(is_parallel(), "Should be in parallel mode"); + _start_semaphore.wait(); + + // Avalanche wakeups: each worker signals two others. + signal_worker_if_needed(); + signal_worker_if_needed(); + + ArchiveWorkerTask* task = Atomic::load_acquire(&_task); + task->run(); + + // All work done in threads should be visible to caller. + OrderAccess::fence(); + + // Signal the pool the tasks are complete, if this is the last worker. + if (Atomic::sub(&_running_workers, 1, memory_order_relaxed) == 0) { + _end_semaphore.signal(); + } + + // Continue if task was not a termination task. + return (task != &_shutdown_task); +} + +ArchiveWorkerThread::ArchiveWorkerThread(ArchiveWorkers* pool) : NamedThread(), _pool(pool) { + set_name("ArchiveWorkerThread"); + os::create_thread(this, os::os_thread); + os::start_thread(this); +} + +void ArchiveWorkerThread::run() { + // Avalanche thread startup: each starting worker starts two others. + _pool->start_worker_if_needed(); + _pool->start_worker_if_needed(); + + // Set ourselves up. + os::set_priority(this, NearMaxPriority); + + while (_pool->run_as_worker()) { + // Work until terminated. + } +} diff --git a/src/hotspot/share/cds/archiveUtils.hpp b/src/hotspot/share/cds/archiveUtils.hpp index 606f5137e9d..128fdc4d33a 100644 --- a/src/hotspot/share/cds/archiveUtils.hpp +++ b/src/hotspot/share/cds/archiveUtils.hpp @@ -33,6 +33,8 @@ #include "utilities/bitMap.hpp" #include "utilities/exceptions.hpp" #include "utilities/macros.hpp" +#include "runtime/nonJavaThread.hpp" +#include "runtime/semaphore.hpp" class BootstrapInfo; class ReservedSpace; @@ -319,4 +321,95 @@ class HeapRootSegments { HeapRootSegments& operator=(const HeapRootSegments&) = default; }; +class ArchiveWorkers; + +// A task to be worked on by worker threads +class ArchiveWorkerTask : public CHeapObj<mtInternal> { + friend class ArchiveWorkers; + friend class ArchiveWorkerShutdownTask; +private: + const char* _name; + int _max_chunks; + volatile int _chunk; + + void run(); + + void configure_max_chunks(int max_chunks); + +public: + ArchiveWorkerTask(const char* name) : + _name(name), _max_chunks(0), _chunk(0) {} + const char* name() const { return _name; } + virtual void work(int chunk, int max_chunks) = 0; +}; + +class ArchiveWorkerThread : public NamedThread { + friend class ArchiveWorkers; +private: + ArchiveWorkers* const _pool; + +public: + ArchiveWorkerThread(ArchiveWorkers* pool); + const char* type_name() const override { return "Archive Worker Thread"; } + void run() override; +}; + +class ArchiveWorkerShutdownTask : public ArchiveWorkerTask { +public: + ArchiveWorkerShutdownTask() : ArchiveWorkerTask("Archive Worker Shutdown") { + // This task always have only one chunk. + configure_max_chunks(1); + } + void work(int chunk, int max_chunks) override { + // Do nothing. + } +}; + +// Special worker pool for archive workers. The goal for this pool is to +// startup fast, distribute spiky workloads efficiently, and being able to +// shutdown after use. This makes the implementation quite different from +// the normal GC worker pool. +class ArchiveWorkers { + friend class ArchiveWorkerThread; +private: + // Target number of chunks per worker. This should be large enough to even + // out work imbalance, and small enough to keep bookkeeping overheads low. + static constexpr int CHUNKS_PER_WORKER = 4; + static int max_workers(); + + // Global shared instance. Can be uninitialized, can be shut down. + static ArchiveWorkers _workers; + + ArchiveWorkerShutdownTask _shutdown_task; + Semaphore _start_semaphore; + Semaphore _end_semaphore; + + int _num_workers; + int _started_workers; + int _waiting_workers; + int _running_workers; + + typedef enum { NOT_READY, READY, SHUTDOWN } State; + volatile State _state; + + ArchiveWorkerTask* _task; + + bool run_as_worker(); + void start_worker_if_needed(); + void signal_worker_if_needed(); + + void run_task_single(ArchiveWorkerTask* task); + void run_task_multi(ArchiveWorkerTask* task); + + bool is_parallel(); + + ArchiveWorkers(); + +public: + static ArchiveWorkers* workers() { return &_workers; } + void initialize(); + void shutdown(); + void run_task(ArchiveWorkerTask* task); +}; + #endif // SHARE_CDS_ARCHIVEUTILS_HPP diff --git a/src/hotspot/share/cds/cds_globals.hpp b/src/hotspot/share/cds/cds_globals.hpp index 38f5d8f46a6..811740cfbcb 100644 --- a/src/hotspot/share/cds/cds_globals.hpp +++ b/src/hotspot/share/cds/cds_globals.hpp @@ -117,7 +117,10 @@ product(bool, AOTClassLinking, false, \ "Load/link all archived classes for the boot/platform/app " \ "loaders before application main") \ - + \ + product(bool, AOTCacheParallelRelocation, true, DIAGNOSTIC, \ + "Use parallel relocation code to speed up startup.") \ + \ // end of CDS_FLAGS DECLARE_FLAGS(CDS_FLAGS) diff --git a/src/hotspot/share/cds/filemap.cpp b/src/hotspot/share/cds/filemap.cpp index 00d8fba4411..d33710a65a3 100644 --- a/src/hotspot/share/cds/filemap.cpp +++ b/src/hotspot/share/cds/filemap.cpp @@ -1972,6 +1972,32 @@ char* FileMapInfo::map_bitmap_region() { return bitmap_base; } +class SharedDataRelocationTask : public ArchiveWorkerTask { +private: + BitMapView* const _rw_bm; + BitMapView* const _ro_bm; + SharedDataRelocator* const _rw_reloc; + SharedDataRelocator* const _ro_reloc; + +public: + SharedDataRelocationTask(BitMapView* rw_bm, BitMapView* ro_bm, SharedDataRelocator* rw_reloc, SharedDataRelocator* ro_reloc) : + ArchiveWorkerTask("Shared Data Relocation"), + _rw_bm(rw_bm), _ro_bm(ro_bm), _rw_reloc(rw_reloc), _ro_reloc(ro_reloc) {} + + void work(int chunk, int max_chunks) override { + work_on(chunk, max_chunks, _rw_bm, _rw_reloc); + work_on(chunk, max_chunks, _ro_bm, _ro_reloc); + } + + void work_on(int chunk, int max_chunks, BitMapView* bm, SharedDataRelocator* reloc) { + BitMap::idx_t size = bm->size(); + BitMap::idx_t start = MIN2(size, size * chunk / max_chunks); + BitMap::idx_t end = MIN2(size, size * (chunk + 1) / max_chunks); + assert(end > start, "Sanity: no empty slices"); + bm->iterate(reloc, start, end); + } +}; + // This is called when we cannot map the archive at the requested[ base address (usually 0x800000000). // We relocate all pointers in the 2 core regions (ro, rw). bool FileMapInfo::relocate_pointers_in_core_regions(intx addr_delta) { @@ -2010,8 +2036,14 @@ bool FileMapInfo::relocate_pointers_in_core_regions(intx addr_delta) { valid_new_base, valid_new_end, addr_delta); SharedDataRelocator ro_patcher((address*)ro_patch_base + header()->ro_ptrmap_start_pos(), (address*)ro_patch_end, valid_old_base, valid_old_end, valid_new_base, valid_new_end, addr_delta); - rw_ptrmap.iterate(&rw_patcher); - ro_ptrmap.iterate(&ro_patcher); + + if (AOTCacheParallelRelocation) { + SharedDataRelocationTask task(&rw_ptrmap, &ro_ptrmap, &rw_patcher, &ro_patcher); + ArchiveWorkers::workers()->run_task(&task); + } else { + rw_ptrmap.iterate(&rw_patcher); + ro_ptrmap.iterate(&ro_patcher); + } // The MetaspaceShared::bm region will be unmapped in MetaspaceShared::initialize_shared_spaces(). diff --git a/src/hotspot/share/cds/metaspaceShared.cpp b/src/hotspot/share/cds/metaspaceShared.cpp index b2f5f420365..a8c10e38577 100644 --- a/src/hotspot/share/cds/metaspaceShared.cpp +++ b/src/hotspot/share/cds/metaspaceShared.cpp @@ -1088,6 +1088,9 @@ void MetaspaceShared::initialize_runtime_shared_and_meta_spaces() { assert(CDSConfig::is_using_archive(), "Must be called when UseSharedSpaces is enabled"); MapArchiveResult result = MAP_ARCHIVE_OTHER_FAILURE; + // We are about to open the archives. Initialize workers now. + ArchiveWorkers::workers()->initialize(); + FileMapInfo* static_mapinfo = open_static_archive(); FileMapInfo* dynamic_mapinfo = nullptr; @@ -1679,6 +1682,9 @@ void MetaspaceShared::initialize_shared_spaces() { dynamic_mapinfo->unmap_region(MetaspaceShared::bm); } + // Archive was fully read. Workers are no longer needed. + ArchiveWorkers::workers()->shutdown(); + LogStreamHandle(Info, cds) lsh; if (lsh.is_enabled()) { lsh.print("Using AOT-linked classes: %s (static archive: %s aot-linked classes", diff --git a/src/hotspot/share/runtime/java.cpp b/src/hotspot/share/runtime/java.cpp index c9c7ae8e4c3..d2338cd74d0 100644 --- a/src/hotspot/share/runtime/java.cpp +++ b/src/hotspot/share/runtime/java.cpp @@ -441,6 +441,11 @@ void before_exit(JavaThread* thread, bool halt) { #if INCLUDE_CDS ClassListWriter::write_resolved_constants(); + + // Initiate Archive Workers shutdown. These workers are likely already + // shut down, but we need to make sure they really are. Otherwise, workers + // would fail hard on broken semaphores. + ArchiveWorkers::workers()->shutdown(); #endif // Hang forever on exit if we're reporting an error. From 8bd080bcc9ae3eb368e4bcd5fd0f52408dd9050c Mon Sep 17 00:00:00 2001 From: Jan Lahoda <jlahoda@openjdk.org> Date: Tue, 19 Nov 2024 09:13:37 +0000 Subject: [PATCH 081/311] 8341901: Using 'var' keyword switch pattern matching causes compiler error Reviewed-by: vromero, abimpoudis --- .../com/sun/tools/javac/comp/Attr.java | 2 +- .../com/sun/tools/javac/tree/TreeMaker.java | 10 +- .../patterns/BindingPatternVarTypeModel.java | 94 ++++++++++++++++++- 3 files changed, 102 insertions(+), 4 deletions(-) diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java index f565cff0788..62c12334629 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java @@ -4198,6 +4198,7 @@ public void visitBindingPattern(JCBindingPattern tree) { if (chk.checkUnique(tree.var.pos(), v, env.info.scope)) { chk.checkTransparentVar(tree.var.pos(), v, env.info.scope); } + chk.validate(tree.var.vartype, env, true); if (tree.var.isImplicitlyTyped()) { setSyntheticVariableType(tree.var, type == Type.noType ? syms.errType : type); @@ -4207,7 +4208,6 @@ public void visitBindingPattern(JCBindingPattern tree) { annotate.queueScanTreeAndTypeAnnotate(tree.var.vartype, env, v, tree.var.pos()); } annotate.flush(); - chk.validate(tree.var.vartype, env, true); result = tree.type; if (v.isUnnamedVariable()) { matchBindings = MatchBindingsComputer.EMPTY; diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/TreeMaker.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/TreeMaker.java index 218099ac662..0d0852cb91b 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/TreeMaker.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/tree/TreeMaker.java @@ -738,12 +738,18 @@ public JCFieldAccess Select(JCExpression base, Symbol sym) { } /** Create a qualified identifier from a symbol, adding enough qualifications - * to make the reference unique. + * to make the reference unique. The types in the AST nodes will be erased. */ public JCExpression QualIdent(Symbol sym) { - return isUnqualifiable(sym) + JCExpression result = isUnqualifiable(sym) ? Ident(sym) : Select(QualIdent(sym.owner), sym); + + if (sym.kind == TYP) { + result.setType(types.erasure(sym.type)); + } + + return result; } /** Create an identifier that refers to the variable declared in given variable diff --git a/test/langtools/tools/javac/patterns/BindingPatternVarTypeModel.java b/test/langtools/tools/javac/patterns/BindingPatternVarTypeModel.java index 8327580a086..e63cbeb2008 100644 --- a/test/langtools/tools/javac/patterns/BindingPatternVarTypeModel.java +++ b/test/langtools/tools/javac/patterns/BindingPatternVarTypeModel.java @@ -23,18 +23,28 @@ /* * @test - * @bug 8332725 + * @bug 8332725 8341901 * @summary Verify the AST model works correctly for binding patterns with var */ import com.sun.source.tree.BindingPatternTree; import com.sun.source.tree.CompilationUnitTree; +import com.sun.source.tree.IdentifierTree; +import com.sun.source.tree.MemberSelectTree; import com.sun.source.tree.Tree; +import com.sun.source.tree.VariableTree; import com.sun.source.util.JavacTask; +import com.sun.source.util.TreePathScanner; import com.sun.source.util.TreeScanner; +import com.sun.source.util.Trees; import java.net.URI; import java.util.List; import java.util.concurrent.atomic.AtomicBoolean; +import javax.lang.model.type.DeclaredType; +import javax.lang.model.type.TypeKind; +import javax.lang.model.type.TypeMirror; +import javax.tools.Diagnostic; +import javax.tools.DiagnosticListener; import javax.tools.JavaCompiler; import javax.tools.JavaFileObject; import javax.tools.SimpleJavaFileObject; @@ -45,6 +55,7 @@ public class BindingPatternVarTypeModel { public static void main(String... args) throws Exception { new BindingPatternVarTypeModel().run(); + new BindingPatternVarTypeModel().runVarParameterized(); } private void run() throws Exception { @@ -86,4 +97,85 @@ public Void visitBindingPattern(BindingPatternTree node, Void p) { throw new AssertionError("Didn't find the binding pattern!"); } } + + private void runVarParameterized() throws Exception { + JavaFileObject input = + SimpleJavaFileObject.forSource(URI.create("mem:///Test.java"), + """ + package test; + public class Test { + record R(N.I i) {} + int test(Object o) { + Test.N.I checkType0 = null; + var checkType1 = checkType0; + return switch (o) { + case R(var checkType2) -> 0; + default -> 0; + }; + } + static class N<T> { + interface I {} + } + } + """); + DiagnosticListener<JavaFileObject> noErrors = d -> { + if (d.getKind() == Diagnostic.Kind.ERROR) { + throw new IllegalStateException(d.toString()); + } + }; + JavacTask task = + (JavacTask) compiler.getTask(null, null, noErrors, null, null, List.of(input)); + CompilationUnitTree cut = task.parse().iterator().next(); + Trees trees = Trees.instance(task); + + task.analyze(); + + new TreePathScanner<Void, Void>() { + private boolean checkAttributes; + @Override + public Void visitVariable(VariableTree node, Void p) { + boolean prevCheckAttributes = checkAttributes; + try { + checkAttributes |= + node.getName().toString().startsWith("checkType"); + return super.visitVariable(node, p); + } finally { + checkAttributes = prevCheckAttributes; + } + } + + @Override + public Void visitIdentifier(IdentifierTree node, Void p) { + checkType(); + return super.visitIdentifier(node, p); + } + + @Override + public Void visitMemberSelect(MemberSelectTree node, Void p) { + checkType(); + return super.visitMemberSelect(node, p); + } + + private void checkType() { + if (!checkAttributes) { + return ; + } + + TypeMirror type = trees.getTypeMirror(getCurrentPath()); + + if (type.getKind() == TypeKind.PACKAGE) { + return ; //OK + } + if (type.getKind() != TypeKind.DECLARED) { + throw new AssertionError("Expected a declared type, but got: " + + type.getKind()); + } + + if (!((DeclaredType) type).getTypeArguments().isEmpty()) { + throw new AssertionError("Unexpected type arguments: " + + ((DeclaredType) type).getTypeArguments()); + } + } + }.scan(cut, null); + } } From 9d60300feea12d353fcd6c806b196ace2df02d05 Mon Sep 17 00:00:00 2001 From: Tobias Hartmann <thartmann@openjdk.org> Date: Tue, 19 Nov 2024 10:01:49 +0000 Subject: [PATCH 082/311] 8344199: Incorrect excluded field value set by getEventWriter intrinsic Co-authored-by: Patricio Chilano Mateo <pchilanomate@openjdk.org> Reviewed-by: syan, mgronlun --- src/hotspot/share/opto/library_call.cpp | 14 ++++++++++---- test/jdk/ProblemList-Xcomp.txt | 1 - 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/src/hotspot/share/opto/library_call.cpp b/src/hotspot/share/opto/library_call.cpp index 226fddce29b..39bac0bc14f 100644 --- a/src/hotspot/share/opto/library_call.cpp +++ b/src/hotspot/share/opto/library_call.cpp @@ -3257,7 +3257,10 @@ bool LibraryCallKit::inline_native_getEventWriter() { set_all_memory(input_memory_state); Node* input_io_state = i_o(); - Node* excluded_mask = _gvn.intcon(32768); + // The most significant bit of the u2 is used to denote thread exclusion + Node* excluded_shift = _gvn.intcon(15); + Node* excluded_mask = _gvn.intcon(1 << 15); + // The epoch generation is the range [1-32767] Node* epoch_mask = _gvn.intcon(32767); // TLS @@ -3411,7 +3414,7 @@ bool LibraryCallKit::inline_native_getEventWriter() { record_for_igvn(vthread_compare_io); PhiNode* tid = new PhiNode(vthread_compare_rgn, TypeLong::LONG); record_for_igvn(tid); - PhiNode* exclusion = new PhiNode(vthread_compare_rgn, TypeInt::BOOL); + PhiNode* exclusion = new PhiNode(vthread_compare_rgn, TypeInt::CHAR); record_for_igvn(exclusion); PhiNode* pinVirtualThread = new PhiNode(vthread_compare_rgn, TypeInt::BOOL); record_for_igvn(pinVirtualThread); @@ -3476,7 +3479,8 @@ bool LibraryCallKit::inline_native_getEventWriter() { store_to_memory(tid_is_not_equal, event_writer_pin_field, _gvn.transform(pinVirtualThread), T_BOOLEAN, MemNode::unordered); // Store the exclusion state to the event writer. - store_to_memory(tid_is_not_equal, event_writer_excluded_field, _gvn.transform(exclusion), T_BOOLEAN, MemNode::unordered); + Node* excluded_bool = _gvn.transform(new URShiftINode(_gvn.transform(exclusion), excluded_shift)); + store_to_memory(tid_is_not_equal, event_writer_excluded_field, excluded_bool, T_BOOLEAN, MemNode::unordered); // Store the tid to the event writer. store_to_memory(tid_is_not_equal, event_writer_tid_field, tid, T_LONG, MemNode::unordered); @@ -3543,7 +3547,9 @@ void LibraryCallKit::extend_setCurrentThread(Node* jt, Node* thread) { Node* input_memory_state = reset_memory(); set_all_memory(input_memory_state); - Node* excluded_mask = _gvn.intcon(32768); + // The most significant bit of the u2 is used to denote thread exclusion + Node* excluded_mask = _gvn.intcon(1 << 15); + // The epoch generation is the range [1-32767] Node* epoch_mask = _gvn.intcon(32767); Node* const carrierThread = generate_current_thread(jt); diff --git a/test/jdk/ProblemList-Xcomp.txt b/test/jdk/ProblemList-Xcomp.txt index 1577bb6f7f1..680806e6e31 100644 --- a/test/jdk/ProblemList-Xcomp.txt +++ b/test/jdk/ProblemList-Xcomp.txt @@ -30,4 +30,3 @@ java/lang/invoke/MethodHandles/CatchExceptionTest.java 8146623 generic-all java/lang/reflect/callerCache/ReflectionCallerCacheTest.java 8332028 generic-all com/sun/jdi/InterruptHangTest.java 8043571 generic-all -jdk/jfr/jvm/TestVirtualThreadExclusion.java 8344199 generic-all From 7540fa2147ff8fc9c652ef13548f72f27e2809a8 Mon Sep 17 00:00:00 2001 From: Amit Kumar <amitkumar@openjdk.org> Date: Tue, 19 Nov 2024 10:16:22 +0000 Subject: [PATCH 083/311] 8343884: [s390x] Disallow OptoScheduling Reviewed-by: lucy --- src/hotspot/cpu/s390/vm_version_s390.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/hotspot/cpu/s390/vm_version_s390.cpp b/src/hotspot/cpu/s390/vm_version_s390.cpp index 8ab5affd309..ee3f97f26ef 100644 --- a/src/hotspot/cpu/s390/vm_version_s390.cpp +++ b/src/hotspot/cpu/s390/vm_version_s390.cpp @@ -320,6 +320,12 @@ void VM_Version::initialize() { if (FLAG_IS_DEFAULT(UseUnalignedAccesses)) { FLAG_SET_DEFAULT(UseUnalignedAccesses, true); } + + // The OptoScheduling information is not maintained in s390.ad. + if (OptoScheduling) { + warning("OptoScheduling is not supported on this CPU."); + FLAG_SET_DEFAULT(OptoScheduling, false); + } } From 0d66689177b880035e4047399e3e64f461713562 Mon Sep 17 00:00:00 2001 From: Fei Yang <fyang@openjdk.org> Date: Tue, 19 Nov 2024 10:20:58 +0000 Subject: [PATCH 084/311] 8344393: RISC-V: Remove option UseRVVForBigIntegerShiftIntrinsics Reviewed-by: mli, fjiang --- src/hotspot/cpu/riscv/globals_riscv.hpp | 2 -- src/hotspot/cpu/riscv/stubGenerator_riscv.cpp | 2 +- src/hotspot/cpu/riscv/vm_version_riscv.cpp | 1 - .../ci/hotspot/riscv64/RISCV64HotSpotJVMCIBackendFactory.java | 3 --- .../jdk/vm/ci/hotspot/riscv64/RISCV64HotSpotVMConfig.java | 1 - .../share/classes/jdk/vm/ci/riscv64/RISCV64.java | 3 +-- 6 files changed, 2 insertions(+), 10 deletions(-) diff --git a/src/hotspot/cpu/riscv/globals_riscv.hpp b/src/hotspot/cpu/riscv/globals_riscv.hpp index cc3c3b4a63c..ffbb7c58911 100644 --- a/src/hotspot/cpu/riscv/globals_riscv.hpp +++ b/src/hotspot/cpu/riscv/globals_riscv.hpp @@ -117,8 +117,6 @@ define_pd_global(intx, InlineSmallCode, 1000); product(bool, UseZvfh, false, DIAGNOSTIC, "Use Zvfh instructions") \ product(bool, UseZvkn, false, EXPERIMENTAL, \ "Use Zvkn group extension, Zvkned, Zvknhb, Zvkb, Zvkt") \ - product(bool, UseRVVForBigIntegerShiftIntrinsics, true, \ - "Use RVV instructions for left/right shift of BigInteger") \ product(bool, UseCtxFencei, false, EXPERIMENTAL, \ "Use PR_RISCV_CTX_SW_FENCEI_ON to avoid explicit icache flush") diff --git a/src/hotspot/cpu/riscv/stubGenerator_riscv.cpp b/src/hotspot/cpu/riscv/stubGenerator_riscv.cpp index e4ae4f3cfd1..795e6882c6a 100644 --- a/src/hotspot/cpu/riscv/stubGenerator_riscv.cpp +++ b/src/hotspot/cpu/riscv/stubGenerator_riscv.cpp @@ -6502,7 +6502,7 @@ static const int64_t right_3_bits = right_n_bits(3); StubRoutines::_poly1305_processBlocks = generate_poly1305_processBlocks(); } - if (UseRVVForBigIntegerShiftIntrinsics) { + if (UseRVV) { StubRoutines::_bigIntegerLeftShiftWorker = generate_bigIntegerLeftShift(); StubRoutines::_bigIntegerRightShiftWorker = generate_bigIntegerRightShift(); } diff --git a/src/hotspot/cpu/riscv/vm_version_riscv.cpp b/src/hotspot/cpu/riscv/vm_version_riscv.cpp index 6e8ee1ab7e0..dddded795fa 100644 --- a/src/hotspot/cpu/riscv/vm_version_riscv.cpp +++ b/src/hotspot/cpu/riscv/vm_version_riscv.cpp @@ -233,7 +233,6 @@ void VM_Version::c2_initialize() { if (!UseRVV) { FLAG_SET_DEFAULT(MaxVectorSize, 0); - FLAG_SET_DEFAULT(UseRVVForBigIntegerShiftIntrinsics, false); } else { if (!FLAG_IS_DEFAULT(MaxVectorSize) && MaxVectorSize != _initial_vector_length) { warning("Current system does not support RVV vector length for MaxVectorSize %d. Set MaxVectorSize to %d", diff --git a/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/riscv64/RISCV64HotSpotJVMCIBackendFactory.java b/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/riscv64/RISCV64HotSpotJVMCIBackendFactory.java index f6d365f193b..9e7d7679cab 100644 --- a/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/riscv64/RISCV64HotSpotJVMCIBackendFactory.java +++ b/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/riscv64/RISCV64HotSpotJVMCIBackendFactory.java @@ -76,9 +76,6 @@ private static EnumSet<RISCV64.Flag> computeFlags(RISCV64HotSpotVMConfig config) if (config.useZbb) { flags.add(RISCV64.Flag.UseZbb); } - if (config.useRVVForBigIntegerShiftIntrinsics) { - flags.add(RISCV64.Flag.UseRVVForBigIntegerShiftIntrinsics); - } return flags; } diff --git a/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/riscv64/RISCV64HotSpotVMConfig.java b/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/riscv64/RISCV64HotSpotVMConfig.java index 5af1a4b7796..7f19efc4566 100644 --- a/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/riscv64/RISCV64HotSpotVMConfig.java +++ b/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/riscv64/RISCV64HotSpotVMConfig.java @@ -50,7 +50,6 @@ class RISCV64HotSpotVMConfig extends HotSpotVMConfigAccess { final boolean useRVC = getFlag("UseRVC", Boolean.class); final boolean useZba = getFlag("UseZba", Boolean.class); final boolean useZbb = getFlag("UseZbb", Boolean.class); - final boolean useRVVForBigIntegerShiftIntrinsics = getFlag("UseRVVForBigIntegerShiftIntrinsics", Boolean.class); final long vmVersionFeatures = getFieldValue("Abstract_VM_Version::_features", Long.class, "uint64_t"); } diff --git a/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/riscv64/RISCV64.java b/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/riscv64/RISCV64.java index 91d7b79aad4..2da9d51cca2 100644 --- a/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/riscv64/RISCV64.java +++ b/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/riscv64/RISCV64.java @@ -170,8 +170,7 @@ public enum Flag { UseRVV, UseRVC, UseZba, - UseZbb, - UseRVVForBigIntegerShiftIntrinsics + UseZbb } private final EnumSet<Flag> flags; From 235973615fbad7073df67167ab1cb4d40b6f1ab5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eirik=20Bj=C3=B8rsn=C3=B8s?= <eirbjo@openjdk.org> Date: Tue, 19 Nov 2024 12:04:37 +0000 Subject: [PATCH 085/311] 8344534: Remove leftover import of java.security.AccessControlContext in JavaLangAccess Reviewed-by: alanb --- .../share/classes/jdk/internal/access/JavaLangAccess.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/java.base/share/classes/jdk/internal/access/JavaLangAccess.java b/src/java.base/share/classes/jdk/internal/access/JavaLangAccess.java index 80f4dfdf2aa..62ce8020d80 100644 --- a/src/java.base/share/classes/jdk/internal/access/JavaLangAccess.java +++ b/src/java.base/share/classes/jdk/internal/access/JavaLangAccess.java @@ -38,7 +38,6 @@ import java.net.URI; import java.nio.charset.CharacterCodingException; import java.nio.charset.Charset; -import java.security.AccessControlContext; import java.security.ProtectionDomain; import java.util.List; import java.util.Map; From cc8bd63741ce5745c144bf21b737c287d9b53817 Mon Sep 17 00:00:00 2001 From: Matthias Baesken <mbaesken@openjdk.org> Date: Tue, 19 Nov 2024 13:44:11 +0000 Subject: [PATCH 086/311] 8344036: Tests tools/jlink/runtimeImage fail on AIX after JDK-8311302 Reviewed-by: sgehwolf --- test/jdk/tools/jlink/runtimeImage/AddOptionsTest.java | 2 +- .../tools/jlink/runtimeImage/BasicJlinkMissingJavaBase.java | 2 +- test/jdk/tools/jlink/runtimeImage/BasicJlinkTest.java | 2 +- test/jdk/tools/jlink/runtimeImage/CustomModuleJlinkTest.java | 2 +- test/jdk/tools/jlink/runtimeImage/GenerateJLIClassesTest.java | 2 +- test/jdk/tools/jlink/runtimeImage/JavaSEReproducibleTest.java | 2 +- .../tools/jlink/runtimeImage/KeepPackagedModulesFailTest.java | 2 +- test/jdk/tools/jlink/runtimeImage/ModifiedFilesExitTest.java | 2 +- .../jdk/tools/jlink/runtimeImage/ModifiedFilesWarningTest.java | 2 +- test/jdk/tools/jlink/runtimeImage/MultiHopTest.java | 2 +- .../runtimeImage/PackagedModulesVsRuntimeImageLinkTest.java | 3 ++- .../tools/jlink/runtimeImage/PatchedJDKModuleJlinkTest.java | 2 +- test/jdk/tools/jlink/runtimeImage/SystemModulesTest.java | 2 +- test/jdk/tools/jlink/runtimeImage/SystemModulesTest2.java | 2 +- 14 files changed, 15 insertions(+), 14 deletions(-) diff --git a/test/jdk/tools/jlink/runtimeImage/AddOptionsTest.java b/test/jdk/tools/jlink/runtimeImage/AddOptionsTest.java index 1ffe1240d07..827f7da624d 100644 --- a/test/jdk/tools/jlink/runtimeImage/AddOptionsTest.java +++ b/test/jdk/tools/jlink/runtimeImage/AddOptionsTest.java @@ -40,7 +40,7 @@ * jdk.jlink/jdk.tools.jimage * @build tests.* jdk.test.lib.process.OutputAnalyzer * jdk.test.lib.process.ProcessTools - * @run main/othervm -Xmx1g AddOptionsTest + * @run main/othervm -Xmx1400m AddOptionsTest */ public class AddOptionsTest extends AbstractLinkableRuntimeTest { diff --git a/test/jdk/tools/jlink/runtimeImage/BasicJlinkMissingJavaBase.java b/test/jdk/tools/jlink/runtimeImage/BasicJlinkMissingJavaBase.java index b0d2a2d66f5..ebf5b060665 100644 --- a/test/jdk/tools/jlink/runtimeImage/BasicJlinkMissingJavaBase.java +++ b/test/jdk/tools/jlink/runtimeImage/BasicJlinkMissingJavaBase.java @@ -41,7 +41,7 @@ * jdk.jlink/jdk.tools.jimage * @build tests.* jdk.test.lib.process.OutputAnalyzer * jdk.test.lib.process.ProcessTools - * @run main/othervm -Xmx1g BasicJlinkMissingJavaBase + * @run main/othervm -Xmx1400m BasicJlinkMissingJavaBase */ public class BasicJlinkMissingJavaBase extends AbstractLinkableRuntimeTest { diff --git a/test/jdk/tools/jlink/runtimeImage/BasicJlinkTest.java b/test/jdk/tools/jlink/runtimeImage/BasicJlinkTest.java index b97ebff9b49..8cbd74e5ed1 100644 --- a/test/jdk/tools/jlink/runtimeImage/BasicJlinkTest.java +++ b/test/jdk/tools/jlink/runtimeImage/BasicJlinkTest.java @@ -39,7 +39,7 @@ * jdk.jlink/jdk.tools.jimage * @build tests.* jdk.test.lib.process.OutputAnalyzer * jdk.test.lib.process.ProcessTools - * @run main/othervm -Xmx1g BasicJlinkTest false + * @run main/othervm -Xmx1400m BasicJlinkTest false */ public class BasicJlinkTest extends AbstractLinkableRuntimeTest { diff --git a/test/jdk/tools/jlink/runtimeImage/CustomModuleJlinkTest.java b/test/jdk/tools/jlink/runtimeImage/CustomModuleJlinkTest.java index 369bccfecfc..d6c237a173b 100644 --- a/test/jdk/tools/jlink/runtimeImage/CustomModuleJlinkTest.java +++ b/test/jdk/tools/jlink/runtimeImage/CustomModuleJlinkTest.java @@ -39,7 +39,7 @@ * jdk.jlink/jdk.tools.jimage * @build tests.* jdk.test.lib.process.OutputAnalyzer * jdk.test.lib.process.ProcessTools - * @run main/othervm -Xmx1g CustomModuleJlinkTest + * @run main/othervm -Xmx1400m CustomModuleJlinkTest */ public class CustomModuleJlinkTest extends AbstractLinkableRuntimeTest { diff --git a/test/jdk/tools/jlink/runtimeImage/GenerateJLIClassesTest.java b/test/jdk/tools/jlink/runtimeImage/GenerateJLIClassesTest.java index 533a8db30d0..e59d18bd6f0 100644 --- a/test/jdk/tools/jlink/runtimeImage/GenerateJLIClassesTest.java +++ b/test/jdk/tools/jlink/runtimeImage/GenerateJLIClassesTest.java @@ -39,7 +39,7 @@ * jdk.jlink/jdk.tools.jimage * @build tests.* jdk.test.lib.process.OutputAnalyzer * jdk.test.lib.process.ProcessTools - * @run main/othervm -Xmx1g GenerateJLIClassesTest + * @run main/othervm -Xmx1400m GenerateJLIClassesTest */ public class GenerateJLIClassesTest extends AbstractLinkableRuntimeTest { diff --git a/test/jdk/tools/jlink/runtimeImage/JavaSEReproducibleTest.java b/test/jdk/tools/jlink/runtimeImage/JavaSEReproducibleTest.java index d923358aed9..a376d075ecd 100644 --- a/test/jdk/tools/jlink/runtimeImage/JavaSEReproducibleTest.java +++ b/test/jdk/tools/jlink/runtimeImage/JavaSEReproducibleTest.java @@ -40,7 +40,7 @@ * jdk.jlink/jdk.tools.jimage * @build tests.* jdk.test.lib.process.OutputAnalyzer * jdk.test.lib.process.ProcessTools - * @run main/othervm -Xmx1g JavaSEReproducibleTest + * @run main/othervm -Xmx1400m JavaSEReproducibleTest */ public class JavaSEReproducibleTest extends AbstractLinkableRuntimeTest { diff --git a/test/jdk/tools/jlink/runtimeImage/KeepPackagedModulesFailTest.java b/test/jdk/tools/jlink/runtimeImage/KeepPackagedModulesFailTest.java index 8094579ecd5..6fdaf5a9824 100644 --- a/test/jdk/tools/jlink/runtimeImage/KeepPackagedModulesFailTest.java +++ b/test/jdk/tools/jlink/runtimeImage/KeepPackagedModulesFailTest.java @@ -41,7 +41,7 @@ * jdk.jlink/jdk.tools.jimage * @build tests.* jdk.test.lib.process.OutputAnalyzer * jdk.test.lib.process.ProcessTools - * @run main/othervm -Xmx1g KeepPackagedModulesFailTest + * @run main/othervm -Xmx1400m KeepPackagedModulesFailTest */ public class KeepPackagedModulesFailTest extends AbstractLinkableRuntimeTest { diff --git a/test/jdk/tools/jlink/runtimeImage/ModifiedFilesExitTest.java b/test/jdk/tools/jlink/runtimeImage/ModifiedFilesExitTest.java index 709494b6256..90abe14c214 100644 --- a/test/jdk/tools/jlink/runtimeImage/ModifiedFilesExitTest.java +++ b/test/jdk/tools/jlink/runtimeImage/ModifiedFilesExitTest.java @@ -40,7 +40,7 @@ * jdk.jlink/jdk.tools.jimage * @build tests.* jdk.test.lib.process.OutputAnalyzer * jdk.test.lib.process.ProcessTools - * @run main/othervm -Xmx1g ModifiedFilesExitTest + * @run main/othervm -Xmx1400m ModifiedFilesExitTest */ public class ModifiedFilesExitTest extends ModifiedFilesTest { diff --git a/test/jdk/tools/jlink/runtimeImage/ModifiedFilesWarningTest.java b/test/jdk/tools/jlink/runtimeImage/ModifiedFilesWarningTest.java index f52691dd859..935d80dee4f 100644 --- a/test/jdk/tools/jlink/runtimeImage/ModifiedFilesWarningTest.java +++ b/test/jdk/tools/jlink/runtimeImage/ModifiedFilesWarningTest.java @@ -39,7 +39,7 @@ * jdk.jlink/jdk.tools.jimage * @build tests.* jdk.test.lib.process.OutputAnalyzer * jdk.test.lib.process.ProcessTools - * @run main/othervm -Xmx1g ModifiedFilesWarningTest + * @run main/othervm -Xmx1400m ModifiedFilesWarningTest */ public class ModifiedFilesWarningTest extends ModifiedFilesTest { diff --git a/test/jdk/tools/jlink/runtimeImage/MultiHopTest.java b/test/jdk/tools/jlink/runtimeImage/MultiHopTest.java index 88f91f238bd..0e2cabe7425 100644 --- a/test/jdk/tools/jlink/runtimeImage/MultiHopTest.java +++ b/test/jdk/tools/jlink/runtimeImage/MultiHopTest.java @@ -40,7 +40,7 @@ * jdk.jlink/jdk.tools.jimage * @build tests.* jdk.test.lib.process.OutputAnalyzer * jdk.test.lib.process.ProcessTools - * @run main/othervm -Xmx1g MultiHopTest + * @run main/othervm -Xmx1400m MultiHopTest */ public class MultiHopTest extends AbstractLinkableRuntimeTest { diff --git a/test/jdk/tools/jlink/runtimeImage/PackagedModulesVsRuntimeImageLinkTest.java b/test/jdk/tools/jlink/runtimeImage/PackagedModulesVsRuntimeImageLinkTest.java index 9910be5f919..d276e80702b 100644 --- a/test/jdk/tools/jlink/runtimeImage/PackagedModulesVsRuntimeImageLinkTest.java +++ b/test/jdk/tools/jlink/runtimeImage/PackagedModulesVsRuntimeImageLinkTest.java @@ -49,7 +49,7 @@ * jdk.jlink/jdk.tools.jimage * @build tests.* jdk.test.lib.process.OutputAnalyzer * jdk.test.lib.process.ProcessTools - * @run main/othervm -Xmx1g PackagedModulesVsRuntimeImageLinkTest + * @run main/othervm/timeout=1200 -Xmx1400m PackagedModulesVsRuntimeImageLinkTest */ public class PackagedModulesVsRuntimeImageLinkTest extends AbstractLinkableRuntimeTest { @@ -76,6 +76,7 @@ void runTest(Helper helper, boolean isLinkableRuntime) throws Exception { .output(helper.createNewImageDir("java-se-jmodfull")) .addMods("java.se").call().assertSuccess(); + System.out.println("Now comparing jmod-less and jmod-full) images"); compareRecursively(javaSEruntimeLink, javaSEJmodFull); } diff --git a/test/jdk/tools/jlink/runtimeImage/PatchedJDKModuleJlinkTest.java b/test/jdk/tools/jlink/runtimeImage/PatchedJDKModuleJlinkTest.java index 3baa824e049..f83c4c698f1 100644 --- a/test/jdk/tools/jlink/runtimeImage/PatchedJDKModuleJlinkTest.java +++ b/test/jdk/tools/jlink/runtimeImage/PatchedJDKModuleJlinkTest.java @@ -42,7 +42,7 @@ * jdk.jlink/jdk.tools.jimage * @build tests.* jdk.test.lib.process.OutputAnalyzer * jdk.test.lib.process.ProcessTools - * @run main/othervm -Xmx1g PatchedJDKModuleJlinkTest + * @run main/othervm -Xmx1400m PatchedJDKModuleJlinkTest */ public class PatchedJDKModuleJlinkTest extends AbstractLinkableRuntimeTest { diff --git a/test/jdk/tools/jlink/runtimeImage/SystemModulesTest.java b/test/jdk/tools/jlink/runtimeImage/SystemModulesTest.java index fac8cac112d..d0a6234eec0 100644 --- a/test/jdk/tools/jlink/runtimeImage/SystemModulesTest.java +++ b/test/jdk/tools/jlink/runtimeImage/SystemModulesTest.java @@ -41,7 +41,7 @@ * jdk.jlink/jdk.tools.jimage * @build tests.* jdk.test.lib.process.OutputAnalyzer * jdk.test.lib.process.ProcessTools - * @run main/othervm -Xmx1g SystemModulesTest + * @run main/othervm -Xmx1400m SystemModulesTest */ public class SystemModulesTest extends AbstractLinkableRuntimeTest { diff --git a/test/jdk/tools/jlink/runtimeImage/SystemModulesTest2.java b/test/jdk/tools/jlink/runtimeImage/SystemModulesTest2.java index 6be4ad7321c..ee22a55f3a7 100644 --- a/test/jdk/tools/jlink/runtimeImage/SystemModulesTest2.java +++ b/test/jdk/tools/jlink/runtimeImage/SystemModulesTest2.java @@ -42,7 +42,7 @@ * jdk.jlink/jdk.tools.jimage * @build tests.* jdk.test.lib.process.OutputAnalyzer * jdk.test.lib.process.ProcessTools - * @run main/othervm -Xmx1g SystemModulesTest2 + * @run main/othervm -Xmx1400m SystemModulesTest2 */ public class SystemModulesTest2 extends AbstractLinkableRuntimeTest { From 41436bb0e81ddf08fea189d9e1d020fb0ce8979b Mon Sep 17 00:00:00 2001 From: Alexey Semenyuk <asemenyuk@openjdk.org> Date: Tue, 19 Nov 2024 13:52:31 +0000 Subject: [PATCH 087/311] 8336087: Doccheck: the jpackage command page doesn't show the correct command-line options Reviewed-by: almatvee --- src/jdk.jpackage/share/man/jpackage.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/jdk.jpackage/share/man/jpackage.md b/src/jdk.jpackage/share/man/jpackage.md index 228c0b13259..21f07db0bb8 100644 --- a/src/jdk.jpackage/share/man/jpackage.md +++ b/src/jdk.jpackage/share/man/jpackage.md @@ -438,7 +438,7 @@ The `jpackage` tool will take as input a Java application and a Java run-time im <a id="option-linux-app-category">`--linux-app-category` *category-value*</a> -: Group value of the RPM /<name/>.spec file or +: Group value of the RPM \<name\>.spec file or Section value of DEB control file <a id="option-linux-shortcut">`--linux-shortcut`</a> From 0714114fe3e0ac01657053164c61cbb702c0f9a0 Mon Sep 17 00:00:00 2001 From: Alexey Semenyuk <asemenyuk@openjdk.org> Date: Tue, 19 Nov 2024 13:53:45 +0000 Subject: [PATCH 088/311] 8344322: Improve capabilities of jpackage test lib to validate error output of jpackage Reviewed-by: almatvee --- .../jpackage/test/CannedFormattedString.java | 53 +++++++++++++ .../jdk/jpackage/test/JPackageCommand.java | 24 ++++++ .../jpackage/test/JPackageStringBundle.java | 67 ++++++++++++++++ .../helpers/jdk/jpackage/test/TKit.java | 34 ++++++++- test/jdk/tools/jpackage/share/ErrorTest.java | 76 ++++++++++--------- 5 files changed, 217 insertions(+), 37 deletions(-) create mode 100644 test/jdk/tools/jpackage/helpers/jdk/jpackage/test/CannedFormattedString.java create mode 100644 test/jdk/tools/jpackage/helpers/jdk/jpackage/test/JPackageStringBundle.java diff --git a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/CannedFormattedString.java b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/CannedFormattedString.java new file mode 100644 index 00000000000..8b28049b7b1 --- /dev/null +++ b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/CannedFormattedString.java @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.jpackage.test; + +import java.util.List; +import java.util.function.BiFunction; + +public final class CannedFormattedString { + + CannedFormattedString(BiFunction<String, Object[], String> formatter, + String key, Object[] args) { + this.formatter = formatter; + this.key = key; + this.args = args; + } + + public String getValue() { + return formatter.apply(key, args); + } + + @Override + public String toString() { + if (args.length == 0) { + return String.format("%s", key); + } else { + return String.format("%s+%s", key, List.of(args)); + } + } + + private final BiFunction<String, Object[], String> formatter; + private final String key; + private final Object[] args; +} diff --git a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/JPackageCommand.java b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/JPackageCommand.java index 9b25c9058d1..49eeb25a00e 100644 --- a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/JPackageCommand.java +++ b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/JPackageCommand.java @@ -78,6 +78,7 @@ public JPackageCommand(JPackageCommand cmd) { prerequisiteActions = new Actions(cmd.prerequisiteActions); verifyActions = new Actions(cmd.verifyActions); appLayoutAsserts = cmd.appLayoutAsserts; + outputValidator = cmd.outputValidator; executeInDirectory = cmd.executeInDirectory; } @@ -739,6 +740,24 @@ public JPackageCommand ignoreDefaultVerbose(boolean v) { return this; } + public JPackageCommand validateOutput(TKit.TextStreamVerifier validator) { + return JPackageCommand.this.validateOutput(validator::apply); + } + + public JPackageCommand validateOutput(Consumer<Stream<String>> validator) { + if (validator != null) { + saveConsoleOutput(true); + outputValidator = validator; + } else { + outputValidator = null; + } + return this; + } + + public JPackageCommand validateOutput(CannedFormattedString str) { + return JPackageCommand.this.validateOutput(TKit.assertTextStream(str.getValue())); + } + public boolean isWithToolProvider() { return Optional.ofNullable(withToolProvider).orElse( defaultWithToolProvider); @@ -817,6 +836,10 @@ public Executor.Result execute(int expectedExitCode) { .createExecutor() .execute(expectedExitCode); + if (outputValidator != null) { + outputValidator.accept(result.getOutput().stream()); + } + if (result.exitCode == 0) { executeVerifyActions(); } @@ -1187,6 +1210,7 @@ public void run() { private final Actions verifyActions; private Path executeInDirectory; private Set<AppLayoutAssert> appLayoutAsserts = Set.of(AppLayoutAssert.values()); + private Consumer<Stream<String>> outputValidator; private static boolean defaultWithToolProvider; private static final Map<String, PackageType> PACKAGE_TYPES = Functional.identity( diff --git a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/JPackageStringBundle.java b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/JPackageStringBundle.java new file mode 100644 index 00000000000..565822d4504 --- /dev/null +++ b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/JPackageStringBundle.java @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.jpackage.test; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.text.MessageFormat; + +public enum JPackageStringBundle { + + MAIN("jdk.jpackage.internal.I18N"), + ; + + JPackageStringBundle(String i18nClassName) { + try { + i18nClass = Class.forName(i18nClassName); + + i18nClass_getString = i18nClass.getDeclaredMethod("getString", String.class); + i18nClass_getString.setAccessible(true); + } catch (ClassNotFoundException|NoSuchMethodException ex) { + throw Functional.rethrowUnchecked(ex); + } + } + + /** + * Return a string value of the given key from jpackage resources. + */ + private String getString(String key) { + try { + return (String)i18nClass_getString.invoke(i18nClass, key); + } catch (IllegalAccessException|InvocationTargetException ex) { + throw Functional.rethrowUnchecked(ex); + } + } + + private String getFormattedString(String key, Object[] args) { + return MessageFormat.format(getString(key), args); + } + + public CannedFormattedString cannedFormattedString(String key, String ... args) { + return new CannedFormattedString(this::getFormattedString, key, args); + } + + private final Class<?> i18nClass; + private final Method i18nClass_getString; +} diff --git a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/TKit.java b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/TKit.java index 957449697a5..8f91d581ef1 100644 --- a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/TKit.java +++ b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/TKit.java @@ -946,6 +946,16 @@ public TextStreamVerifier negate() { return this; } + public TextStreamVerifier andThen(Consumer<? super Stream<String>> anotherVerifier) { + this.anotherVerifier = anotherVerifier; + return this; + } + + public TextStreamVerifier andThen(TextStreamVerifier anotherVerifier) { + this.anotherVerifier = anotherVerifier::apply; + return this; + } + public TextStreamVerifier orElseThrow(RuntimeException v) { return orElseThrow(() -> v); } @@ -956,9 +966,22 @@ public TextStreamVerifier orElseThrow(Supplier<RuntimeException> v) { } public void apply(Stream<String> lines) { - String matchedStr = lines.filter(line -> predicate.test(line, value)).findFirst().orElse( - null); - String labelStr = Optional.ofNullable(label).orElse("output"); + final String matchedStr; + + lines = lines.dropWhile(line -> !predicate.test(line, value)); + if (anotherVerifier == null) { + matchedStr = lines.findFirst().orElse(null); + } else { + var tail = lines.toList(); + if (tail.isEmpty()) { + matchedStr = null; + } else { + matchedStr = tail.get(0); + } + lines = tail.stream().skip(1); + } + + final String labelStr = Optional.ofNullable(label).orElse("output"); if (negate) { String msg = String.format( "Check %s doesn't contain [%s] string", labelStr, value); @@ -982,12 +1005,17 @@ public void apply(Stream<String> lines) { } } } + + if (anotherVerifier != null) { + anotherVerifier.accept(lines); + } } private BiPredicate<String, String> predicate; private String label; private boolean negate; private Supplier<RuntimeException> createException; + private Consumer<? super Stream<String>> anotherVerifier; private final String value; } diff --git a/test/jdk/tools/jpackage/share/ErrorTest.java b/test/jdk/tools/jpackage/share/ErrorTest.java index f012eac1ced..ed7338a76dd 100644 --- a/test/jdk/tools/jpackage/share/ErrorTest.java +++ b/test/jdk/tools/jpackage/share/ErrorTest.java @@ -24,9 +24,13 @@ import java.util.Collection; import java.util.List; -import jdk.jpackage.test.Annotations.Parameters; +import java.util.Optional; +import java.util.stream.Stream; +import jdk.jpackage.test.Annotations.ParameterSupplier; import jdk.jpackage.test.Annotations.Test; +import jdk.jpackage.test.CannedFormattedString; import jdk.jpackage.test.JPackageCommand; +import jdk.jpackage.test.JPackageStringBundle; import jdk.jpackage.test.TKit; /* @@ -53,81 +57,85 @@ public final class ErrorTest { - private final String expectedError; - private final JPackageCommand cmd; - - @Parameters public static Collection input() { return List.of(new Object[][]{ // non-existent arg {"Hello", new String[]{"--no-such-argument"}, null, - "Invalid Option: [--no-such-argument]"}, + JPackageStringBundle.MAIN.cannedFormattedString("ERR_InvalidOption", "--no-such-argument")}, // no main jar {"Hello", null, new String[]{"--main-jar"}, - "--main-jar or --module"}, + JPackageStringBundle.MAIN.cannedFormattedString("ERR_NoEntryPoint")}, // no main-class {"Hello", null, new String[]{"--main-class"}, - "main class was not specified"}, + JPackageStringBundle.MAIN.cannedFormattedString("error.no-main-class-with-main-jar", "hello.jar"), + JPackageStringBundle.MAIN.cannedFormattedString("error.no-main-class-with-main-jar.advice", "hello.jar")}, // non-existent main jar {"Hello", new String[]{"--main-jar", "non-existent.jar"}, null, - "main jar does not exist"}, + JPackageStringBundle.MAIN.cannedFormattedString("error.main-jar-does-not-exist", "non-existent.jar")}, // non-existent runtime {"Hello", new String[]{"--runtime-image", "non-existent.runtime"}, null, - "does not exist"}, + JPackageStringBundle.MAIN.cannedFormattedString("message.runtime-image-dir-does-not-exist", "runtime-image", "non-existent.runtime")}, // non-existent resource-dir {"Hello", new String[]{"--resource-dir", "non-existent.dir"}, null, - "does not exist"}, + JPackageStringBundle.MAIN.cannedFormattedString("message.resource-dir-does-not-exist", "resource-dir", "non-existent.dir")}, // invalid type {"Hello", new String[]{"--type", "invalid-type"}, null, - "Invalid or unsupported type: [invalid-type]"}, + JPackageStringBundle.MAIN.cannedFormattedString("ERR_InvalidInstallerType", "invalid-type")}, // no --input {"Hello", null, new String[]{"--input"}, - "Missing argument: --input"}, + JPackageStringBundle.MAIN.cannedFormattedString("ERR_MissingArgument", "--input")}, // no --module-path {"com.other/com.other.Hello", null, new String[]{"--module-path"}, - "Missing argument: --runtime-image or --module-path"}, + JPackageStringBundle.MAIN.cannedFormattedString("ERR_MissingArgument", "--runtime-image or --module-path")}, }); } - public ErrorTest(String javaAppDesc, String[] jpackageArgs, - String[] removeArgs, - String expectedError) { - this.expectedError = expectedError; + @Test + @ParameterSupplier("input") + public static void test(String javaAppDesc, String[] jpackageArgs, + String[] removeArgs, CannedFormattedString... expectedErrors) { + // Init default jpackage test command line. + var cmd = JPackageCommand.helloAppImage(javaAppDesc) + // Disable default logic adding `--verbose` option + // to jpackage command line. + // It will affect jpackage error messages if the command line is malformed. + .ignoreDefaultVerbose(true) + // Ignore external runtime as it will interfer + // with jpackage arguments in this test. + .ignoreDefaultRuntime(true); - cmd = JPackageCommand.helloAppImage(javaAppDesc) - .saveConsoleOutput(true).dumpOutput(true); - if (jpackageArgs != null) { - cmd.addArguments(jpackageArgs); - } if (removeArgs != null) { - for (String arg : removeArgs) { - cmd.removeArgumentWithValue(arg); - } - } - } + // Add arguments if requested. + Optional.ofNullable(jpackageArgs).ifPresent(cmd::addArguments); - @Test - public void test() { - List<String> output = cmd.execute(1).getOutput(); - TKit.assertNotNull(output, "output is null"); - TKit.assertTextStream(expectedError).apply(output.stream()); - } + // Remove arguments if requested. + Optional.ofNullable(removeArgs).map(List::of).ifPresent( + args -> args.forEach(cmd::removeArgumentWithValue)); + + // Configure jpackage output verifier to look up the list of provided + // errors in the order they specified. + cmd.validateOutput(Stream.of(expectedErrors) + .map(CannedFormattedString::getValue) + .map(TKit::assertTextStream) + .reduce(TKit.TextStreamVerifier::andThen).get()); + cmd.execute(1); + } } From a28e4d839c9220655d78116be89c3c26b3d17a0e Mon Sep 17 00:00:00 2001 From: Alexey Semenyuk <asemenyuk@openjdk.org> Date: Tue, 19 Nov 2024 13:54:02 +0000 Subject: [PATCH 089/311] 8342299: Document that jpackage includes (possibly old) VC Redistributable MSVCP140.dll from JDK Reviewed-by: almatvee --- src/jdk.jpackage/share/man/jpackage.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/jdk.jpackage/share/man/jpackage.md b/src/jdk.jpackage/share/man/jpackage.md index 21f07db0bb8..9d7a3003c24 100644 --- a/src/jdk.jpackage/share/man/jpackage.md +++ b/src/jdk.jpackage/share/man/jpackage.md @@ -497,6 +497,14 @@ Sign the predefined application image (on macOS): the set of additional mac signing options and --verbose +## jpackage and jlink + +jpackage will use jlink to create Java Runtime unless the `--runtime-image` option is used. +The created Java Runtime image on Windows will include MS runtime libraries bundled with the JDK. +If MS runtime libraries of a different version are needed for the application, the user will need +to add/replace those themselves. + + ## jpackage resource directory Icons, template files, and other resources of jpackage can be over-ridden by From fea5f2b1458cdd53f437e59caaffaa6e22fb59a7 Mon Sep 17 00:00:00 2001 From: Alexey Semenyuk <asemenyuk@openjdk.org> Date: Tue, 19 Nov 2024 13:54:57 +0000 Subject: [PATCH 090/311] 8344415: Restruct jpackage utility classes Reviewed-by: almatvee --- .../jpackage/internal/DesktopIntegration.java | 10 +- .../internal/LinuxAppImageBuilder.java | 5 +- .../internal/LinuxPackageBundler.java | 5 +- .../internal/MacBaseInstallerBundler.java | 11 +- .../jdk/jpackage/internal/MacDmgBundler.java | 11 +- .../internal/MacLaunchersAsServices.java | 5 +- .../jdk/jpackage/internal/MacPkgBundler.java | 8 +- .../internal/AbstractAppImageBuilder.java | 10 +- .../jpackage/internal/AbstractBundler.java | 5 +- .../jdk/jpackage/internal/AppImageFile.java | 5 +- .../jdk/jpackage/internal/IOUtils.java | 294 +----------------- .../jdk/jpackage/internal/PathGroup.java | 5 +- .../internal/StandardBundlerParam.java | 5 +- .../jdk/jpackage/internal/util/FileUtils.java | 155 +++++++++ .../jdk/jpackage/internal/util/PathUtils.java | 54 ++++ .../internal/util/PrettyPrintHandler.java | 89 ++++++ .../internal/util/SkipDocumentHandler.java | 48 +++ .../jpackage/internal/util/XmlConsumer.java | 34 ++ .../jdk/jpackage/internal/util/XmlUtils.java | 103 ++++++ .../internal/util/function/ExceptionBox.java | 50 +++ .../util/function/ThrowingBiConsumer.java | 42 +++ .../util/function/ThrowingBiFunction.java | 43 +++ .../util/function/ThrowingConsumer.java | 42 +++ .../util/function/ThrowingFunction.java | 42 +++ .../util/function/ThrowingRunnable.java | 40 +++ .../util/function/ThrowingSupplier.java | 42 +++ .../util/function/ThrowingUnaryOperator.java | 43 +++ .../jdk/jpackage/internal/WinExeBundler.java | 5 +- .../jdk/jpackage/internal/WinMsiBundler.java | 5 +- .../internal/WixAppImageFragmentBuilder.java | 11 +- .../jpackage/internal/WixFragmentBuilder.java | 5 +- .../internal/WixLauncherAsService.java | 7 +- .../jdk/jpackage/internal/WixPipeline.java | 3 +- .../jpackage/internal/WixSourceConverter.java | 3 +- .../jdk/jpackage/internal/WixTool.java | 3 +- .../internal/WixUiFragmentBuilder.java | 4 +- test/jdk/tools/jpackage/TEST.properties | 2 + .../jdk/jpackage/test/AnnotationsTest.java | 2 +- .../jdk/jpackage/test/TKitTest.java | 6 +- .../jdk/jpackage/test/AdditionalLauncher.java | 45 +-- .../helpers/jdk/jpackage/test/Executor.java | 4 +- .../jdk/jpackage/test/FileAssociations.java | 10 +- .../helpers/jdk/jpackage/test/Functional.java | 102 ------ .../helpers/jdk/jpackage/test/HelloApp.java | 6 +- .../jdk/jpackage/test/JPackageCommand.java | 12 +- .../test/LauncherAsServiceVerifier.java | 12 +- .../jpackage/test/LauncherIconVerifier.java | 9 +- .../jdk/jpackage/test/LinuxHelper.java | 6 +- .../helpers/jdk/jpackage/test/MacHelper.java | 8 +- .../helpers/jdk/jpackage/test/MethodCall.java | 2 +- .../jdk/jpackage/test/PackageTest.java | 14 +- .../jdk/jpackage/test/PackageType.java | 17 +- .../helpers/jdk/jpackage/test/TKit.java | 8 +- .../jdk/jpackage/test/TestBuilder.java | 6 +- .../jdk/jpackage/test/TestInstance.java | 9 +- .../jdk/jpackage/test/TestMethodSupplier.java | 4 +- .../jdk/jpackage/test/WindowsHelper.java | 2 +- .../tools/jpackage/linux/AppAboutUrlTest.java | 2 +- .../tools/jpackage/share/AppContentTest.java | 8 +- test/jdk/tools/jpackage/share/BasicTest.java | 2 +- test/jdk/tools/jpackage/share/IconTest.java | 8 +- .../tools/jpackage/share/InOutPathTest.java | 2 +- .../tools/jpackage/share/MainClassTest.java | 2 +- .../tools/jpackage/share/PerUserCfgTest.java | 2 +- .../share/RuntimeImageSymbolicLinksTest.java | 9 - .../jpackage/windows/WinLongVersionTest.java | 7 +- .../tools/jpackage/windows/WinScriptTest.java | 5 +- 67 files changed, 1014 insertions(+), 571 deletions(-) create mode 100644 src/jdk.jpackage/share/classes/jdk/jpackage/internal/util/FileUtils.java create mode 100644 src/jdk.jpackage/share/classes/jdk/jpackage/internal/util/PathUtils.java create mode 100644 src/jdk.jpackage/share/classes/jdk/jpackage/internal/util/PrettyPrintHandler.java create mode 100644 src/jdk.jpackage/share/classes/jdk/jpackage/internal/util/SkipDocumentHandler.java create mode 100644 src/jdk.jpackage/share/classes/jdk/jpackage/internal/util/XmlConsumer.java create mode 100644 src/jdk.jpackage/share/classes/jdk/jpackage/internal/util/XmlUtils.java create mode 100644 src/jdk.jpackage/share/classes/jdk/jpackage/internal/util/function/ExceptionBox.java create mode 100644 src/jdk.jpackage/share/classes/jdk/jpackage/internal/util/function/ThrowingBiConsumer.java create mode 100644 src/jdk.jpackage/share/classes/jdk/jpackage/internal/util/function/ThrowingBiFunction.java create mode 100644 src/jdk.jpackage/share/classes/jdk/jpackage/internal/util/function/ThrowingConsumer.java create mode 100644 src/jdk.jpackage/share/classes/jdk/jpackage/internal/util/function/ThrowingFunction.java create mode 100644 src/jdk.jpackage/share/classes/jdk/jpackage/internal/util/function/ThrowingRunnable.java create mode 100644 src/jdk.jpackage/share/classes/jdk/jpackage/internal/util/function/ThrowingSupplier.java create mode 100644 src/jdk.jpackage/share/classes/jdk/jpackage/internal/util/function/ThrowingUnaryOperator.java diff --git a/src/jdk.jpackage/linux/classes/jdk/jpackage/internal/DesktopIntegration.java b/src/jdk.jpackage/linux/classes/jdk/jpackage/internal/DesktopIntegration.java index 6a5b200f8f3..a9cf2682cd7 100644 --- a/src/jdk.jpackage/linux/classes/jdk/jpackage/internal/DesktopIntegration.java +++ b/src/jdk.jpackage/linux/classes/jdk/jpackage/internal/DesktopIntegration.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -54,6 +54,8 @@ import static jdk.jpackage.internal.StandardBundlerParam.ICON; import static jdk.jpackage.internal.StandardBundlerParam.PREDEFINED_APP_IMAGE; import static jdk.jpackage.internal.StandardBundlerParam.SHORTCUT_HINT; +import jdk.jpackage.internal.util.PathUtils; +import jdk.jpackage.internal.util.XmlUtils; /** * Helper to create files for desktop integration. @@ -119,7 +121,7 @@ private DesktopIntegration(PlatformPackage thePackage, if (withDesktopFile) { desktopFile = new DesktopFile(desktopFileName); iconFile = new DesktopFile(escapedAppFileName - + IOUtils.getSuffix(Path.of(DEFAULT_ICON))); + + PathUtils.getSuffix(Path.of(DEFAULT_ICON))); if (curIconResource == null) { // Create default icon. @@ -420,7 +422,7 @@ private void appendFileAssociation(XMLStreamWriter xml, } private void createFileAssociationsMimeInfoFile() throws IOException { - IOUtils.createXml(mimeInfoFile.srcPath(), xml -> { + XmlUtils.createXml(mimeInfoFile.srcPath(), xml -> { xml.writeStartElement("mime-info"); xml.writeDefaultNamespace( "http://www.freedesktop.org/standards/shared-mime-info"); @@ -451,7 +453,7 @@ private void addFileAssociationIconFiles(ShellCommands shellCommands) // Create icon name for mime type from mime type. DesktopFile faIconFile = new DesktopFile(mimeType.replace( - File.separatorChar, '-') + IOUtils.getSuffix( + File.separatorChar, '-') + PathUtils.getSuffix( assoc.data.iconPath)); IOUtils.copyFile(assoc.data.iconPath, diff --git a/src/jdk.jpackage/linux/classes/jdk/jpackage/internal/LinuxAppImageBuilder.java b/src/jdk.jpackage/linux/classes/jdk/jpackage/internal/LinuxAppImageBuilder.java index 7291d56218a..ab97e327003 100644 --- a/src/jdk.jpackage/linux/classes/jdk/jpackage/internal/LinuxAppImageBuilder.java +++ b/src/jdk.jpackage/linux/classes/jdk/jpackage/internal/LinuxAppImageBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -35,6 +35,7 @@ import static jdk.jpackage.internal.StandardBundlerParam.APP_NAME; import static jdk.jpackage.internal.StandardBundlerParam.ICON; import static jdk.jpackage.internal.StandardBundlerParam.ADD_LAUNCHERS; +import jdk.jpackage.internal.util.PathUtils; public class LinuxAppImageBuilder extends AbstractAppImageBuilder { @@ -127,7 +128,7 @@ private void createLauncherForEntryPoint(Map<String, ? super Object> params, mainParams); if (iconResource != null) { Path iconTarget = appLayout.destktopIntegrationDirectory().resolve( - APP_NAME.fetchFrom(params) + IOUtils.getSuffix(Path.of( + APP_NAME.fetchFrom(params) + PathUtils.getSuffix(Path.of( DEFAULT_ICON))); iconResource.saveToFile(iconTarget); } diff --git a/src/jdk.jpackage/linux/classes/jdk/jpackage/internal/LinuxPackageBundler.java b/src/jdk.jpackage/linux/classes/jdk/jpackage/internal/LinuxPackageBundler.java index b510ed41411..5d160d4128c 100644 --- a/src/jdk.jpackage/linux/classes/jdk/jpackage/internal/LinuxPackageBundler.java +++ b/src/jdk.jpackage/linux/classes/jdk/jpackage/internal/LinuxPackageBundler.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -44,6 +44,7 @@ import static jdk.jpackage.internal.StandardBundlerParam.VENDOR; import static jdk.jpackage.internal.StandardBundlerParam.DESCRIPTION; import static jdk.jpackage.internal.StandardBundlerParam.INSTALL_DIR; +import jdk.jpackage.internal.util.FileUtils; abstract class LinuxPackageBundler extends AbstractBundler { @@ -144,7 +145,7 @@ public final Path execute(Map<String, ? super Object> params, // Application image is a newly created directory tree. // Move it. srcAppLayout.move(thePackage.sourceApplicationLayout()); - IOUtils.deleteRecursive(srcAppImageRoot); + FileUtils.deleteRecursive(srcAppImageRoot); } } diff --git a/src/jdk.jpackage/macosx/classes/jdk/jpackage/internal/MacBaseInstallerBundler.java b/src/jdk.jpackage/macosx/classes/jdk/jpackage/internal/MacBaseInstallerBundler.java index 8d9db0a0077..69ecce068e7 100644 --- a/src/jdk.jpackage/macosx/classes/jdk/jpackage/internal/MacBaseInstallerBundler.java +++ b/src/jdk.jpackage/macosx/classes/jdk/jpackage/internal/MacBaseInstallerBundler.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,25 +25,20 @@ package jdk.jpackage.internal; -import java.io.ByteArrayOutputStream; import java.io.IOException; -import java.io.PrintStream; import java.nio.file.Files; import java.nio.file.LinkOption; import java.nio.file.Path; import java.text.MessageFormat; -import java.util.ArrayList; -import java.util.List; import java.util.Map; import java.util.Optional; -import java.util.regex.Matcher; -import java.util.regex.Pattern; import static jdk.jpackage.internal.StandardBundlerParam.APP_NAME; import static jdk.jpackage.internal.StandardBundlerParam.INSTALLER_NAME; import static jdk.jpackage.internal.StandardBundlerParam.INSTALL_DIR; import static jdk.jpackage.internal.StandardBundlerParam.PREDEFINED_APP_IMAGE; import static jdk.jpackage.internal.StandardBundlerParam.VERSION; import static jdk.jpackage.internal.StandardBundlerParam.SIGN_BUNDLE; +import jdk.jpackage.internal.util.FileUtils; public abstract class MacBaseInstallerBundler extends AbstractBundler { @@ -187,7 +182,7 @@ protected Path prepareAppBundle(Map<String, ? super Object> params) StandardBundlerParam.getPredefinedAppImage(params); if (predefinedImage != null) { appDir = appImageRoot.resolve(APP_NAME.fetchFrom(params) + ".app"); - IOUtils.copyRecursive(predefinedImage, appDir, + FileUtils.copyRecursive(predefinedImage, appDir, LinkOption.NOFOLLOW_LINKS); // Create PackageFile if predefined app image is not signed diff --git a/src/jdk.jpackage/macosx/classes/jdk/jpackage/internal/MacDmgBundler.java b/src/jdk.jpackage/macosx/classes/jdk/jpackage/internal/MacDmgBundler.java index 7d100832dba..3de8ef5ee2b 100644 --- a/src/jdk.jpackage/macosx/classes/jdk/jpackage/internal/MacDmgBundler.java +++ b/src/jdk.jpackage/macosx/classes/jdk/jpackage/internal/MacDmgBundler.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -48,6 +48,7 @@ import static jdk.jpackage.internal.StandardBundlerParam.TEMP_ROOT; import static jdk.jpackage.internal.StandardBundlerParam.VERBOSE; import static jdk.jpackage.internal.StandardBundlerParam.DMG_CONTENT; +import jdk.jpackage.internal.util.FileUtils; public class MacDmgBundler extends MacBaseInstallerBundler { @@ -294,7 +295,7 @@ private Path buildDMG( Map<String, ? super Object> params, MAC_CF_BUNDLE_IDENTIFIER.fetchFrom(params)); Path dest = root.resolve("Contents/Home"); - IOUtils.copyRecursive(source, dest); + FileUtils.copyRecursive(source, dest); srcFolder = newRoot; } @@ -319,7 +320,7 @@ private Path buildDMG( Map<String, ? super Object> params, List <String> dmgContent = DMG_CONTENT.fetchFrom(params); for (String content : dmgContent) { Path path = Path.of(content); - IOUtils.copyRecursive(path, srcFolder.resolve(path.getFileName())); + FileUtils.copyRecursive(path, srcFolder.resolve(path.getFileName())); } // create temp image ProcessBuilder pb = new ProcessBuilder( @@ -381,9 +382,9 @@ private Path buildDMG( Map<String, ? super Object> params, Path destPath = mountedRoot .resolve(srcFolder.getFileName()); Files.createDirectory(destPath); - IOUtils.copyRecursive(srcFolder, destPath); + FileUtils.copyRecursive(srcFolder, destPath); } else { - IOUtils.copyRecursive(srcFolder, mountedRoot); + FileUtils.copyRecursive(srcFolder, mountedRoot); } } diff --git a/src/jdk.jpackage/macosx/classes/jdk/jpackage/internal/MacLaunchersAsServices.java b/src/jdk.jpackage/macosx/classes/jdk/jpackage/internal/MacLaunchersAsServices.java index b0ee96e2ee3..4f069921f45 100644 --- a/src/jdk.jpackage/macosx/classes/jdk/jpackage/internal/MacLaunchersAsServices.java +++ b/src/jdk.jpackage/macosx/classes/jdk/jpackage/internal/MacLaunchersAsServices.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -33,6 +33,7 @@ import static jdk.jpackage.internal.MacAppImageBuilder.MAC_CF_BUNDLE_IDENTIFIER; import static jdk.jpackage.internal.OverridableResource.createResource; import static jdk.jpackage.internal.StandardBundlerParam.APP_NAME; +import jdk.jpackage.internal.util.PathUtils; /** * Helper to install launchers as services using "launchd". @@ -95,7 +96,7 @@ private static class Launcher extends UnixLauncherAsService { // It is recommended to set value of "label" property in launchd // .plist file equal to the name of this .plist file without the suffix. - String label = IOUtils.replaceSuffix(plistFilename.getFileName(), "").toString(); + String label = PathUtils.replaceSuffix(plistFilename.getFileName(), "").toString(); getResource() .setPublicName(plistFilename) diff --git a/src/jdk.jpackage/macosx/classes/jdk/jpackage/internal/MacPkgBundler.java b/src/jdk.jpackage/macosx/classes/jdk/jpackage/internal/MacPkgBundler.java index 6ac84975451..a4345ecf764 100644 --- a/src/jdk.jpackage/macosx/classes/jdk/jpackage/internal/MacPkgBundler.java +++ b/src/jdk.jpackage/macosx/classes/jdk/jpackage/internal/MacPkgBundler.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -62,6 +62,8 @@ import static jdk.jpackage.internal.MacAppImageBuilder.MAC_CF_BUNDLE_IDENTIFIER; import static jdk.jpackage.internal.OverridableResource.createResource; import static jdk.jpackage.internal.StandardBundlerParam.RESOURCE_DIR; +import jdk.jpackage.internal.util.FileUtils; +import jdk.jpackage.internal.util.XmlUtils; public class MacPkgBundler extends MacBaseInstallerBundler { @@ -267,7 +269,7 @@ private void prepareDistributionXMLFile(Map<String, ? super Object> params) Log.verbose(MessageFormat.format(I18N.getString( "message.preparing-distribution-dist"), f.toAbsolutePath().toString())); - IOUtils.createXml(f, xml -> { + XmlUtils.createXml(f, xml -> { xml.writeStartElement("installer-gui-script"); xml.writeAttribute("minSpecVersion", "1"); @@ -452,7 +454,7 @@ private String getRoot(Map<String, ? super Object> params, source = appLocation; dest = newRoot.resolve(appLocation.getFileName()); } - IOUtils.copyRecursive(source, dest); + FileUtils.copyRecursive(source, dest); return newRoot.toString(); } diff --git a/src/jdk.jpackage/share/classes/jdk/jpackage/internal/AbstractAppImageBuilder.java b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/AbstractAppImageBuilder.java index b507cc955bd..b523e43f5aa 100644 --- a/src/jdk.jpackage/share/classes/jdk/jpackage/internal/AbstractAppImageBuilder.java +++ b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/AbstractAppImageBuilder.java @@ -32,8 +32,6 @@ import java.util.ArrayList; import java.util.Map; import java.util.List; -import java.util.Objects; -import java.util.stream.Stream; import static jdk.jpackage.internal.OverridableResource.createResource; import static jdk.jpackage.internal.StandardBundlerParam.APP_NAME; import static jdk.jpackage.internal.StandardBundlerParam.ICON; @@ -42,6 +40,8 @@ import static jdk.jpackage.internal.StandardBundlerParam.OUTPUT_DIR; import static jdk.jpackage.internal.StandardBundlerParam.TEMP_ROOT; import jdk.jpackage.internal.resources.ResourceLocator; +import jdk.jpackage.internal.util.FileUtils; +import jdk.jpackage.internal.util.PathUtils; /* * AbstractAppImageBuilder @@ -92,7 +92,7 @@ protected void copyApplication(Map<String, ? super Object> params) } } - IOUtils.copyRecursive(inputPath, + FileUtils.copyRecursive(inputPath, appLayout.appDirectory().toAbsolutePath(), excludes); } @@ -100,7 +100,7 @@ protected void copyApplication(Map<String, ? super Object> params) List<String> items = APP_CONTENT.fetchFrom(params); for (String item : items) { - IOUtils.copyRecursive(Path.of(item), + FileUtils.copyRecursive(Path.of(item), appLayout.contentDirectory().resolve(Path.of(item).getFileName())); } } @@ -115,7 +115,7 @@ public static OverridableResource createIconResource(String defaultIconName, } final String resourcePublicName = APP_NAME.fetchFrom(params) - + IOUtils.getSuffix(Path.of(defaultIconName)); + + PathUtils.getSuffix(Path.of(defaultIconName)); IconType iconType = getLauncherIconType(params); if (iconType == IconType.NoIcon) { diff --git a/src/jdk.jpackage/share/classes/jdk/jpackage/internal/AbstractBundler.java b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/AbstractBundler.java index b615176fd15..e28a444a045 100644 --- a/src/jdk.jpackage/share/classes/jdk/jpackage/internal/AbstractBundler.java +++ b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/AbstractBundler.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -28,6 +28,7 @@ import java.io.IOException; import java.nio.file.Path; import java.util.Map; +import jdk.jpackage.internal.util.FileUtils; /** @@ -55,7 +56,7 @@ public String toString() { @Override public void cleanup(Map<String, ? super Object> params) { try { - IOUtils.deleteRecursive( + FileUtils.deleteRecursive( StandardBundlerParam.TEMP_ROOT.fetchFrom(params)); } catch (IOException e) { Log.verbose(e.getMessage()); diff --git a/src/jdk.jpackage/share/classes/jdk/jpackage/internal/AppImageFile.java b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/AppImageFile.java index 31228a8f5a3..256d292350a 100644 --- a/src/jdk.jpackage/share/classes/jdk/jpackage/internal/AppImageFile.java +++ b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/AppImageFile.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -59,6 +59,7 @@ import static jdk.jpackage.internal.StandardBundlerParam.MENU_HINT; import static jdk.jpackage.internal.StandardBundlerParam.SIGN_BUNDLE; import static jdk.jpackage.internal.StandardBundlerParam.APP_STORE; +import jdk.jpackage.internal.util.XmlUtils; public final class AppImageFile { @@ -247,7 +248,7 @@ private static void save(Path appImageDir, addLauncherInfoSave = appImage.getAddLaunchers(); } - IOUtils.createXml(getPathInAppImage(appImageDir), xml -> { + XmlUtils.createXml(getPathInAppImage(appImageDir), xml -> { xml.writeStartElement("jpackage-state"); xml.writeAttribute("version", getVersion()); xml.writeAttribute("platform", getPlatform()); diff --git a/src/jdk.jpackage/share/classes/jdk/jpackage/internal/IOUtils.java b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/IOUtils.java index 573109a004b..534786ada13 100644 --- a/src/jdk.jpackage/share/classes/jdk/jpackage/internal/IOUtils.java +++ b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/IOUtils.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,41 +25,15 @@ package jdk.jpackage.internal; -import jdk.internal.util.OperatingSystem; - import java.io.BufferedReader; import java.io.InputStreamReader; import java.io.IOException; import java.io.PrintStream; -import java.io.Writer; -import java.lang.reflect.InvocationHandler; -import java.lang.reflect.Method; -import java.lang.reflect.Proxy; -import java.nio.file.FileVisitResult; import java.nio.file.Files; -import java.nio.file.CopyOption; import java.nio.file.Path; -import java.nio.file.SimpleFileVisitor; import java.nio.file.StandardCopyOption; -import java.nio.file.attribute.BasicFileAttributes; import java.util.ArrayList; -import java.util.Collection; -import java.util.HashMap; import java.util.List; -import java.util.Map; -import java.util.Optional; -import java.util.concurrent.atomic.AtomicReference; -import javax.xml.parsers.DocumentBuilder; -import javax.xml.parsers.DocumentBuilderFactory; -import javax.xml.parsers.ParserConfigurationException; -import javax.xml.stream.XMLOutputFactory; -import javax.xml.stream.XMLStreamException; -import javax.xml.stream.XMLStreamWriter; -import javax.xml.transform.Result; -import javax.xml.transform.Source; -import javax.xml.transform.TransformerException; -import javax.xml.transform.TransformerFactory; -import javax.xml.transform.stax.StAXResult; /** * IOUtils @@ -68,107 +42,6 @@ */ public class IOUtils { - public static void deleteRecursive(Path directory) throws IOException { - final AtomicReference<IOException> exception = new AtomicReference<>(); - - if (!Files.exists(directory)) { - return; - } - - Files.walkFileTree(directory, new SimpleFileVisitor<Path>() { - @Override - public FileVisitResult visitFile(Path file, - BasicFileAttributes attr) throws IOException { - if (OperatingSystem.isWindows()) { - Files.setAttribute(file, "dos:readonly", false); - } - try { - Files.delete(file); - } catch (IOException ex) { - exception.compareAndSet(null, ex); - } - return FileVisitResult.CONTINUE; - } - - @Override - public FileVisitResult preVisitDirectory(Path dir, - BasicFileAttributes attr) throws IOException { - if (OperatingSystem.isWindows()) { - Files.setAttribute(dir, "dos:readonly", false); - } - return FileVisitResult.CONTINUE; - } - - @Override - public FileVisitResult postVisitDirectory(Path dir, IOException e) - throws IOException { - try { - Files.delete(dir); - } catch (IOException ex) { - exception.compareAndSet(null, ex); - } - return FileVisitResult.CONTINUE; - } - }); - if (exception.get() != null) { - throw exception.get(); - } - } - - public static void copyRecursive(Path src, Path dest, CopyOption... options) - throws IOException { - copyRecursive(src, dest, List.of(), options); - } - - public static void copyRecursive(Path src, Path dest, - final List<Path> excludes, CopyOption... options) - throws IOException { - - List<CopyAction> copyActions = new ArrayList<>(); - - Files.walkFileTree(src, new SimpleFileVisitor<Path>() { - @Override - public FileVisitResult preVisitDirectory(final Path dir, - final BasicFileAttributes attrs) { - if (isPathMatch(dir, excludes)) { - return FileVisitResult.SKIP_SUBTREE; - } else { - copyActions.add(new CopyAction(null, dest.resolve(src. - relativize(dir)))); - return FileVisitResult.CONTINUE; - } - } - - @Override - public FileVisitResult visitFile(final Path file, - final BasicFileAttributes attrs) { - if (!isPathMatch(file, excludes)) { - copyActions.add(new CopyAction(file, dest.resolve(src. - relativize(file)))); - } - return FileVisitResult.CONTINUE; - } - }); - - for (var copyAction : copyActions) { - copyAction.apply(options); - } - } - - private static record CopyAction(Path src, Path dest) { - void apply(CopyOption... options) throws IOException { - if (src == null) { - Files.createDirectories(dest); - } else { - Files.copy(src, dest, options); - } - } - } - - private static boolean isPathMatch(Path what, List<Path> paths) { - return paths.stream().anyMatch(what::endsWith); - } - public static void copyFile(Path sourceFile, Path destFile) throws IOException { Files.createDirectories(getParent(destFile)); @@ -314,90 +187,6 @@ static void writableOutputDir(Path outdir) throws PackagerException { } } - public static Path replaceSuffix(Path path, String suffix) { - Path parent = path.getParent(); - String filename = getFileName(path).toString().replaceAll("\\.[^.]*$", "") - + Optional.ofNullable(suffix).orElse(""); - return parent != null ? parent.resolve(filename) : Path.of(filename); - } - - public static Path addSuffix(Path path, String suffix) { - Path parent = path.getParent(); - String filename = getFileName(path).toString() + suffix; - return parent != null ? parent.resolve(filename) : Path.of(filename); - } - - public static String getSuffix(Path path) { - String filename = replaceSuffix(getFileName(path), null).toString(); - return getFileName(path).toString().substring(filename.length()); - } - - @FunctionalInterface - public static interface XmlConsumer { - void accept(XMLStreamWriter xml) throws IOException, XMLStreamException; - } - - public static void createXml(Path dstFile, XmlConsumer xmlConsumer) throws - IOException { - XMLOutputFactory xmlFactory = XMLOutputFactory.newInstance(); - Files.createDirectories(getParent(dstFile)); - try (Writer w = Files.newBufferedWriter(dstFile)) { - // Wrap with pretty print proxy - XMLStreamWriter xml = (XMLStreamWriter) Proxy.newProxyInstance( - XMLStreamWriter.class.getClassLoader(), new Class<?>[]{ - XMLStreamWriter.class}, new PrettyPrintHandler( - xmlFactory.createXMLStreamWriter(w))); - - xml.writeStartDocument(); - xmlConsumer.accept(xml); - xml.writeEndDocument(); - xml.flush(); - xml.close(); - } catch (XMLStreamException ex) { - throw new IOException(ex); - } catch (IOException ex) { - throw ex; - } - } - - public static void mergeXmls(XMLStreamWriter xml, Collection<Source> sources) - throws XMLStreamException, IOException { - xml = (XMLStreamWriter) Proxy.newProxyInstance( - XMLStreamWriter.class.getClassLoader(), new Class<?>[]{ - XMLStreamWriter.class}, new SkipDocumentHandler(xml)); - - try { - TransformerFactory tf = TransformerFactory.newInstance(); - Result result = new StAXResult(xml); - for (var src : sources) { - tf.newTransformer().transform(src, result); - } - } catch (TransformerException ex) { - // Should never happen - throw new RuntimeException(ex); - } - } - - public static DocumentBuilderFactory initDocumentBuilderFactory() { - DocumentBuilderFactory dbf = DocumentBuilderFactory.newDefaultInstance(); - try { - dbf.setFeature( - "http://apache.org/xml/features/nonvalidating/load-external-dtd", - false); - } catch (ParserConfigurationException ex) { - throw new IllegalStateException(ex); - } - return dbf; - } - - public static DocumentBuilder initDocumentBuilder() { - try { - return initDocumentBuilderFactory().newDocumentBuilder(); - } catch (ParserConfigurationException ex) { - throw new IllegalStateException(ex); - } - } - public static Path getParent(Path p) { Path parent = p.getParent(); if (parent == null) { @@ -430,85 +219,4 @@ public static long getPID(Process p) { return -1; } } - - private static class PrettyPrintHandler implements InvocationHandler { - - PrettyPrintHandler(XMLStreamWriter target) { - this.target = target; - } - - @Override - public Object invoke(Object proxy, Method method, Object[] args) throws - Throwable { - switch (method.getName()) { - case "writeStartElement": - // update state of parent node - if (depth > 0) { - hasChildElement.put(depth - 1, true); - } - // reset state of current node - hasChildElement.put(depth, false); - // indent for current depth - target.writeCharacters(EOL); - target.writeCharacters(repeat(depth, INDENT)); - depth++; - break; - case "writeEndElement": - depth--; - if (hasChildElement.get(depth) == true) { - target.writeCharacters(EOL); - target.writeCharacters(repeat(depth, INDENT)); - } - break; - case "writeProcessingInstruction": - case "writeEmptyElement": - // update state of parent node - if (depth > 0) { - hasChildElement.put(depth - 1, true); - } - // indent for current depth - target.writeCharacters(EOL); - target.writeCharacters(repeat(depth, INDENT)); - break; - default: - break; - } - method.invoke(target, args); - return null; - } - - private static String repeat(int d, String s) { - StringBuilder sb = new StringBuilder(); - while (d-- > 0) { - sb.append(s); - } - return sb.toString(); - } - - private final XMLStreamWriter target; - private int depth = 0; - private final Map<Integer, Boolean> hasChildElement = new HashMap<>(); - private static final String INDENT = " "; - private static final String EOL = "\n"; - } - - private static class SkipDocumentHandler implements InvocationHandler { - - SkipDocumentHandler(XMLStreamWriter target) { - this.target = target; - } - - @Override - public Object invoke(Object proxy, Method method, Object[] args) throws - Throwable { - switch (method.getName()) { - case "writeStartDocument", "writeEndDocument" -> { - } - default -> method.invoke(target, args); - } - return null; - } - - private final XMLStreamWriter target; - } } diff --git a/src/jdk.jpackage/share/classes/jdk/jpackage/internal/PathGroup.java b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/PathGroup.java index 24fb394e100..296164551a1 100644 --- a/src/jdk.jpackage/share/classes/jdk/jpackage/internal/PathGroup.java +++ b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/PathGroup.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -35,6 +35,7 @@ import java.util.function.BiFunction; import java.util.stream.Collectors; import java.util.stream.Stream; +import jdk.jpackage.internal.util.FileUtils; /** @@ -232,7 +233,7 @@ public void createDirectory(Path dir) throws IOException { for (var entry: entries) { Path srcFile = entry.getKey(); if (Files.isDirectory(srcFile)) { - IOUtils.deleteRecursive(srcFile); + FileUtils.deleteRecursive(srcFile); } } } diff --git a/src/jdk.jpackage/share/classes/jdk/jpackage/internal/StandardBundlerParam.java b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/StandardBundlerParam.java index 718f186c954..0209eea584a 100644 --- a/src/jdk.jpackage/share/classes/jdk/jpackage/internal/StandardBundlerParam.java +++ b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/StandardBundlerParam.java @@ -44,6 +44,7 @@ import java.util.function.BiFunction; import java.util.function.Function; import java.util.stream.Stream; +import jdk.jpackage.internal.util.FileUtils; /** * StandardBundlerParam @@ -604,7 +605,7 @@ static void copyPredefinedRuntimeImage(Map<String, ? super Object> params, // copy whole runtime, need to skip jmods and src.zip final List<Path> excludes = Arrays.asList(Path.of("jmods"), Path.of("src.zip")); - IOUtils.copyRecursive(topImage, appLayout.runtimeHomeDirectory(), + FileUtils.copyRecursive(topImage, appLayout.runtimeHomeDirectory(), excludes, LinkOption.NOFOLLOW_LINKS); // if module-path given - copy modules to appDir/mods @@ -616,7 +617,7 @@ static void copyPredefinedRuntimeImage(Map<String, ? super Object> params, for (Path mp : modulePath) { if (!defaultModulePath.contains(mp)) { Files.createDirectories(dest); - IOUtils.copyRecursive(mp, dest); + FileUtils.copyRecursive(mp, dest); } } } diff --git a/src/jdk.jpackage/share/classes/jdk/jpackage/internal/util/FileUtils.java b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/util/FileUtils.java new file mode 100644 index 00000000000..71b8c3d6ddc --- /dev/null +++ b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/util/FileUtils.java @@ -0,0 +1,155 @@ +/* + * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.jpackage.internal.util; + +import java.io.IOException; +import java.nio.file.CopyOption; +import java.nio.file.FileVisitResult; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.SimpleFileVisitor; +import java.nio.file.attribute.BasicFileAttributes; +import java.util.ArrayList; +import java.util.List; +import jdk.internal.util.OperatingSystem; +import jdk.jpackage.internal.util.function.ExceptionBox; +import jdk.jpackage.internal.util.function.ThrowingConsumer; + +public final class FileUtils { + + public static void deleteRecursive(Path directory) throws IOException { + if (!Files.exists(directory)) { + return; + } + + var callback = new RecursiveDeleter(); + + Files.walkFileTree(directory, callback); + + if (callback.ex != null) { + throw callback.ex; + } + } + + public static void copyRecursive(Path src, Path dest, CopyOption... options) + throws IOException { + copyRecursive(src, dest, List.of(), options); + } + + public static void copyRecursive(Path src, Path dest, + final List<Path> excludes, CopyOption... options) + throws IOException { + + List<CopyAction> copyActions = new ArrayList<>(); + + Files.walkFileTree(src, new SimpleFileVisitor<Path>() { + @Override + public FileVisitResult preVisitDirectory(final Path dir, + final BasicFileAttributes attrs) { + if (isPathMatch(dir, excludes)) { + return FileVisitResult.SKIP_SUBTREE; + } else { + copyActions.add(new CopyAction(null, dest.resolve(src. + relativize(dir)))); + return FileVisitResult.CONTINUE; + } + } + + @Override + public FileVisitResult visitFile(final Path file, + final BasicFileAttributes attrs) { + if (!isPathMatch(file, excludes)) { + copyActions.add(new CopyAction(file, dest.resolve(src. + relativize(file)))); + } + return FileVisitResult.CONTINUE; + } + }); + + for (var copyAction : copyActions) { + copyAction.apply(options); + } + } + + private static boolean isPathMatch(Path what, List<Path> paths) { + return paths.stream().anyMatch(what::endsWith); + } + + private static record CopyAction(Path src, Path dest) { + + void apply(CopyOption... options) throws IOException { + if (src == null) { + Files.createDirectories(dest); + } else { + Files.copy(src, dest, options); + } + } + } + + private static class RecursiveDeleter extends SimpleFileVisitor<Path> { + + @Override + public FileVisitResult visitFile(Path file, + BasicFileAttributes attr) throws IOException { + adjustAttributes(file); + runActionOnPath(Files::delete, file); + return FileVisitResult.CONTINUE; + } + + @Override + public FileVisitResult preVisitDirectory(Path dir, + BasicFileAttributes attr) throws IOException { + adjustAttributes(dir); + return FileVisitResult.CONTINUE; + } + + @Override + public FileVisitResult postVisitDirectory(Path dir, IOException e) + throws IOException { + runActionOnPath(Files::delete, dir); + return FileVisitResult.CONTINUE; + } + + private static void adjustAttributes(Path path) throws IOException { + if (OperatingSystem.isWindows()) { + Files.setAttribute(path, "dos:readonly", false); + } + } + + private void runActionOnPath(ThrowingConsumer<Path> action, Path path) { + try { + action.accept(path); + } catch (IOException ex) { + if (this.ex == null) { + this.ex = ex; + } + } catch (Throwable t) { + throw ExceptionBox.rethrowUnchecked(t); + } + } + + private IOException ex; + } +} diff --git a/src/jdk.jpackage/share/classes/jdk/jpackage/internal/util/PathUtils.java b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/util/PathUtils.java new file mode 100644 index 00000000000..267062a2031 --- /dev/null +++ b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/util/PathUtils.java @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.jpackage.internal.util; + +import java.nio.file.Path; +import java.util.Optional; +import jdk.jpackage.internal.IOUtils; + +public final class PathUtils { + + public static String getSuffix(Path path) { + String filename = replaceSuffix(IOUtils.getFileName(path), null).toString(); + return IOUtils.getFileName(path).toString().substring(filename.length()); + } + + public static Path addSuffix(Path path, String suffix) { + Path parent = path.getParent(); + String filename = IOUtils.getFileName(path).toString() + suffix; + return parent != null ? parent.resolve(filename) : Path.of(filename); + } + + public static Path replaceSuffix(Path path, String suffix) { + Path parent = path.getParent(); + String filename = IOUtils.getFileName(path).toString().replaceAll("\\.[^.]*$", + "") + Optional.ofNullable(suffix).orElse(""); + return parent != null ? parent.resolve(filename) : Path.of(filename); + } + + public static Path resolveNullablePath(Path base, Path path) { + return Optional.ofNullable(path).map(base::resolve).orElse(null); + } +} diff --git a/src/jdk.jpackage/share/classes/jdk/jpackage/internal/util/PrettyPrintHandler.java b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/util/PrettyPrintHandler.java new file mode 100644 index 00000000000..ffd5b764103 --- /dev/null +++ b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/util/PrettyPrintHandler.java @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.jpackage.internal.util; + +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.Method; +import java.util.HashMap; +import java.util.Map; +import javax.xml.stream.XMLStreamWriter; + +final class PrettyPrintHandler implements InvocationHandler { + + public PrettyPrintHandler(XMLStreamWriter target) { + this.target = target; + } + + @Override + public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { + switch (method.getName()) { + case "writeStartElement": + // update state of parent node + if (depth > 0) { + hasChildElement.put(depth - 1, true); + } + // reset state of current node + hasChildElement.put(depth, false); + // indent for current depth + target.writeCharacters(EOL); + target.writeCharacters(repeat(depth, INDENT)); + depth++; + break; + case "writeEndElement": + depth--; + if (hasChildElement.get(depth) == true) { + target.writeCharacters(EOL); + target.writeCharacters(repeat(depth, INDENT)); + } + break; + case "writeProcessingInstruction": + case "writeEmptyElement": + // update state of parent node + if (depth > 0) { + hasChildElement.put(depth - 1, true); + } + // indent for current depth + target.writeCharacters(EOL); + target.writeCharacters(repeat(depth, INDENT)); + break; + default: + break; + } + method.invoke(target, args); + return null; + } + + private static String repeat(int d, String s) { + StringBuilder sb = new StringBuilder(); + while (d-- > 0) { + sb.append(s); + } + return sb.toString(); + } + + private final XMLStreamWriter target; + private int depth = 0; + private final Map<Integer, Boolean> hasChildElement = new HashMap<>(); + private static final String INDENT = " "; + private static final String EOL = "\n"; +} diff --git a/src/jdk.jpackage/share/classes/jdk/jpackage/internal/util/SkipDocumentHandler.java b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/util/SkipDocumentHandler.java new file mode 100644 index 00000000000..283dac451a2 --- /dev/null +++ b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/util/SkipDocumentHandler.java @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.jpackage.internal.util; + +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.Method; +import javax.xml.stream.XMLStreamWriter; + +final class SkipDocumentHandler implements InvocationHandler { + + public SkipDocumentHandler(XMLStreamWriter target) { + this.target = target; + } + + @Override + public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { + switch (method.getName()) { + case "writeStartDocument", "writeEndDocument" -> { + } + default -> method.invoke(target, args); + } + return null; + } + + private final XMLStreamWriter target; +} diff --git a/src/jdk.jpackage/share/classes/jdk/jpackage/internal/util/XmlConsumer.java b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/util/XmlConsumer.java new file mode 100644 index 00000000000..429be6aba05 --- /dev/null +++ b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/util/XmlConsumer.java @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.jpackage.internal.util; + +import java.io.IOException; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamWriter; + +@FunctionalInterface +public interface XmlConsumer { + + void accept(XMLStreamWriter xml) throws IOException, XMLStreamException; + +} diff --git a/src/jdk.jpackage/share/classes/jdk/jpackage/internal/util/XmlUtils.java b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/util/XmlUtils.java new file mode 100644 index 00000000000..8012384b679 --- /dev/null +++ b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/util/XmlUtils.java @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.jpackage.internal.util; + +import java.io.IOException; +import java.io.Writer; +import java.lang.reflect.Proxy; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.Collection; +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.stream.XMLOutputFactory; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamWriter; +import javax.xml.transform.Result; +import javax.xml.transform.Source; +import javax.xml.transform.TransformerException; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.stax.StAXResult; +import jdk.jpackage.internal.IOUtils; + + +public final class XmlUtils { + + public static void createXml(Path dstFile, XmlConsumer xmlConsumer) throws + IOException { + XMLOutputFactory xmlFactory = XMLOutputFactory.newInstance(); + Files.createDirectories(IOUtils.getParent(dstFile)); + try (Writer w = Files.newBufferedWriter(dstFile)) { + // Wrap with pretty print proxy + XMLStreamWriter xml = (XMLStreamWriter) Proxy.newProxyInstance(XMLStreamWriter.class.getClassLoader(), + new Class<?>[]{XMLStreamWriter.class}, + new PrettyPrintHandler(xmlFactory.createXMLStreamWriter(w))); + xml.writeStartDocument(); + xmlConsumer.accept(xml); + xml.writeEndDocument(); + xml.flush(); + xml.close(); + } catch (XMLStreamException ex) { + throw new IOException(ex); + } catch (IOException ex) { + throw ex; + } + } + + public static void mergeXmls(XMLStreamWriter xml, Collection<Source> sources) + throws XMLStreamException, IOException { + xml = (XMLStreamWriter) Proxy.newProxyInstance(XMLStreamWriter.class.getClassLoader(), + new Class<?>[]{XMLStreamWriter.class}, + new SkipDocumentHandler(xml)); + try { + TransformerFactory tf = TransformerFactory.newInstance(); + Result result = new StAXResult(xml); + for (Source src : sources) { + tf.newTransformer().transform(src, result); + } + } catch (TransformerException ex) { + // Should never happen + throw new RuntimeException(ex); + } + } + + public static DocumentBuilder initDocumentBuilder() { + try { + return initDocumentBuilderFactory().newDocumentBuilder(); + } catch (ParserConfigurationException ex) { + throw new IllegalStateException(ex); + } + } + + public static DocumentBuilderFactory initDocumentBuilderFactory() { + DocumentBuilderFactory dbf = DocumentBuilderFactory.newDefaultInstance(); + try { + dbf.setFeature("http://apache.org/xml/features/nonvalidating/load-external-dtd", + false); + } catch (ParserConfigurationException ex) { + throw new IllegalStateException(ex); + } + return dbf; + } +} diff --git a/src/jdk.jpackage/share/classes/jdk/jpackage/internal/util/function/ExceptionBox.java b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/util/function/ExceptionBox.java new file mode 100644 index 00000000000..55f2964445f --- /dev/null +++ b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/util/function/ExceptionBox.java @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.jpackage.internal.util.function; + +import java.lang.reflect.InvocationTargetException; + +public class ExceptionBox extends RuntimeException { + + private static final long serialVersionUID = 1L; + + public static RuntimeException rethrowUnchecked(Throwable throwable) { + if (throwable instanceof RuntimeException err) { + throw err; + } + + if (throwable instanceof Error err) { + throw err; + } + + if (throwable instanceof InvocationTargetException err) { + throw rethrowUnchecked(err.getCause()); + } + + throw new ExceptionBox(throwable); + } + + private ExceptionBox(Throwable throwable) { + super(throwable); + } +} diff --git a/src/jdk.jpackage/share/classes/jdk/jpackage/internal/util/function/ThrowingBiConsumer.java b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/util/function/ThrowingBiConsumer.java new file mode 100644 index 00000000000..e5b7704a92e --- /dev/null +++ b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/util/function/ThrowingBiConsumer.java @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.jpackage.internal.util.function; + +import java.util.function.BiConsumer; + +@FunctionalInterface +public interface ThrowingBiConsumer<T, U> { + + void accept(T t, U u) throws Throwable; + + public static <T, U> BiConsumer<T, U> toBiConsumer( + ThrowingBiConsumer<T, U> v) { + return (t, u) -> { + try { + v.accept(t, u); + } catch (Throwable ex) { + throw ExceptionBox.rethrowUnchecked(ex); + } + }; + } +} diff --git a/src/jdk.jpackage/share/classes/jdk/jpackage/internal/util/function/ThrowingBiFunction.java b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/util/function/ThrowingBiFunction.java new file mode 100644 index 00000000000..a8119f25bdb --- /dev/null +++ b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/util/function/ThrowingBiFunction.java @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.jpackage.internal.util.function; + +import java.util.function.BiFunction; + +@FunctionalInterface +public interface ThrowingBiFunction<T, U, R> { + + R apply(T t, U u) throws Throwable; + + public static <T, U, R> BiFunction<T, U, R> toBiFunction( + ThrowingBiFunction<T, U, R> v) { + return (t, u) -> { + try { + return v.apply(t, u); + } catch (Throwable ex) { + throw ExceptionBox.rethrowUnchecked(ex); + } + }; + } + +} diff --git a/src/jdk.jpackage/share/classes/jdk/jpackage/internal/util/function/ThrowingConsumer.java b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/util/function/ThrowingConsumer.java new file mode 100644 index 00000000000..5ca33c22d92 --- /dev/null +++ b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/util/function/ThrowingConsumer.java @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.jpackage.internal.util.function; + +import java.util.function.Consumer; + +@FunctionalInterface +public interface ThrowingConsumer<T> { + + void accept(T t) throws Throwable; + + public static <T> Consumer<T> toConsumer(ThrowingConsumer<T> v) { + return o -> { + try { + v.accept(o); + } catch (Throwable ex) { + throw ExceptionBox.rethrowUnchecked(ex); + } + }; + } + +} diff --git a/src/jdk.jpackage/share/classes/jdk/jpackage/internal/util/function/ThrowingFunction.java b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/util/function/ThrowingFunction.java new file mode 100644 index 00000000000..db6b1d26005 --- /dev/null +++ b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/util/function/ThrowingFunction.java @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.jpackage.internal.util.function; + +import java.util.function.Function; + +@FunctionalInterface +public interface ThrowingFunction<T, R> { + + R apply(T t) throws Throwable; + + public static <T, R> Function<T, R> toFunction(ThrowingFunction<T, R> v) { + return t -> { + try { + return v.apply(t); + } catch (Throwable ex) { + throw ExceptionBox.rethrowUnchecked(ex); + } + }; + } + +} diff --git a/src/jdk.jpackage/share/classes/jdk/jpackage/internal/util/function/ThrowingRunnable.java b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/util/function/ThrowingRunnable.java new file mode 100644 index 00000000000..7f3fcda536c --- /dev/null +++ b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/util/function/ThrowingRunnable.java @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.jpackage.internal.util.function; + +@FunctionalInterface +public interface ThrowingRunnable { + + void run() throws Throwable; + + public static Runnable toRunnable(ThrowingRunnable v) { + return () -> { + try { + v.run(); + } catch (Throwable ex) { + throw ExceptionBox.rethrowUnchecked(ex); + } + }; + } + +} diff --git a/src/jdk.jpackage/share/classes/jdk/jpackage/internal/util/function/ThrowingSupplier.java b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/util/function/ThrowingSupplier.java new file mode 100644 index 00000000000..2f5ef135875 --- /dev/null +++ b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/util/function/ThrowingSupplier.java @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.jpackage.internal.util.function; + +import java.util.function.Supplier; + +@FunctionalInterface +public interface ThrowingSupplier<T> { + + T get() throws Throwable; + + public static <T> Supplier<T> toSupplier(ThrowingSupplier<T> v) { + return () -> { + try { + return v.get(); + } catch (Throwable ex) { + throw ExceptionBox.rethrowUnchecked(ex); + } + }; + } + +} diff --git a/src/jdk.jpackage/share/classes/jdk/jpackage/internal/util/function/ThrowingUnaryOperator.java b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/util/function/ThrowingUnaryOperator.java new file mode 100644 index 00000000000..27a3e2f30f5 --- /dev/null +++ b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/util/function/ThrowingUnaryOperator.java @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.jpackage.internal.util.function; + +import java.util.function.UnaryOperator; + +@FunctionalInterface +public interface ThrowingUnaryOperator<T> { + + T apply(T t) throws Throwable; + + public static <T> UnaryOperator<T> toUnaryOperator( + ThrowingUnaryOperator<T> v) { + return t -> { + try { + return v.apply(t); + } catch (Throwable ex) { + throw ExceptionBox.rethrowUnchecked(ex); + } + }; + } + +} diff --git a/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/WinExeBundler.java b/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/WinExeBundler.java index fa81b4278b0..cc2e9298e99 100644 --- a/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/WinExeBundler.java +++ b/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/WinExeBundler.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -30,6 +30,7 @@ import java.nio.file.Path; import java.text.MessageFormat; import java.util.Map; +import jdk.jpackage.internal.util.PathUtils; @SuppressWarnings("restricted") public class WinExeBundler extends AbstractBundler { @@ -127,7 +128,7 @@ private Path buildEXE(Map<String, ? super Object> params, Path msi, outdir.toAbsolutePath().toString())); // Copy template msi wrapper next to msi file - final Path exePath = IOUtils.replaceSuffix(msi, ".exe"); + final Path exePath = PathUtils.replaceSuffix(msi, ".exe"); try (InputStream is = OverridableResource.readDefault(EXE_WRAPPER_NAME)) { Files.copy(is, exePath); } diff --git a/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/WinMsiBundler.java b/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/WinMsiBundler.java index c0ae65b3b0b..f6b0fb4be20 100644 --- a/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/WinMsiBundler.java +++ b/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/WinMsiBundler.java @@ -36,7 +36,6 @@ import java.nio.file.PathMatcher; import java.text.MessageFormat; import java.util.ArrayList; -import java.util.Arrays; import java.util.Collections; import java.util.HashMap; import java.util.LinkedHashSet; @@ -67,7 +66,7 @@ import static jdk.jpackage.internal.StandardBundlerParam.TEMP_ROOT; import static jdk.jpackage.internal.StandardBundlerParam.VENDOR; import static jdk.jpackage.internal.StandardBundlerParam.VERSION; -import jdk.jpackage.internal.WixToolset.WixToolsetType; +import jdk.jpackage.internal.util.FileUtils; import org.w3c.dom.Document; import org.w3c.dom.NodeList; import org.xml.sax.SAXException; @@ -367,7 +366,7 @@ private void prepareProto(Map<String, ? super Object> params) if (appImage != null) { appDir = MSI_IMAGE_DIR.fetchFrom(params).resolve(appName); // copy everything from appImage dir into appDir/name - IOUtils.copyRecursive(appImage, appDir); + FileUtils.copyRecursive(appImage, appDir); } else { appDir = appImageBundler.execute(params, MSI_IMAGE_DIR.fetchFrom( params)); diff --git a/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/WixAppImageFragmentBuilder.java b/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/WixAppImageFragmentBuilder.java index 5bc20c1413c..a5d9a5de141 100644 --- a/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/WixAppImageFragmentBuilder.java +++ b/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/WixAppImageFragmentBuilder.java @@ -42,7 +42,6 @@ import java.util.Optional; import java.util.Set; import java.util.UUID; -import java.util.function.Function; import java.util.function.Predicate; import java.util.function.Supplier; import java.util.stream.Collectors; @@ -56,7 +55,7 @@ import javax.xml.xpath.XPathExpressionException; import javax.xml.xpath.XPathFactory; import jdk.jpackage.internal.AppImageFile.LauncherInfo; -import jdk.jpackage.internal.IOUtils.XmlConsumer; +import jdk.jpackage.internal.util.XmlConsumer; import static jdk.jpackage.internal.StandardBundlerParam.APP_NAME; import static jdk.jpackage.internal.StandardBundlerParam.INSTALL_DIR; import static jdk.jpackage.internal.StandardBundlerParam.VENDOR; @@ -65,6 +64,8 @@ import static jdk.jpackage.internal.WinMsiBundler.SERVICE_INSTALLER; import static jdk.jpackage.internal.WinMsiBundler.WIN_APP_IMAGE; import jdk.jpackage.internal.WixToolset.WixToolsetType; +import jdk.jpackage.internal.util.PathUtils; +import jdk.jpackage.internal.util.XmlUtils; import org.w3c.dom.NodeList; /** @@ -202,7 +203,7 @@ private void normalizeFileAssociation(FileAssociation fa) { } private static Path addExeSuffixToPath(Path path) { - return IOUtils.addSuffix(path, ".exe"); + return PathUtils.addSuffix(path, ".exe"); } private Path getInstalledFaIcoPath(FileAssociation fa) { @@ -524,7 +525,7 @@ private String addShortcutComponent(XMLStreamWriter xml, Path launcherPath, throw throwInvalidPathException(launcherPath); } - String launcherBasename = IOUtils.replaceSuffix( + String launcherBasename = PathUtils.replaceSuffix( IOUtils.getFileName(launcherPath), "").toString(); Path shortcutPath = folder.getPath(this).resolve(launcherBasename); @@ -774,7 +775,7 @@ private List<String> addServiceConfigs(XMLStreamWriter xml) throws } try { - var buffer = new DOMResult(IOUtils.initDocumentBuilder().newDocument()); + var buffer = new DOMResult(XmlUtils.initDocumentBuilder().newDocument()); var bufferWriter = XMLOutputFactory.newInstance().createXMLStreamWriter( buffer); diff --git a/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/WixFragmentBuilder.java b/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/WixFragmentBuilder.java index 0276cc96e65..f0a5840eb6f 100644 --- a/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/WixFragmentBuilder.java +++ b/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/WixFragmentBuilder.java @@ -37,13 +37,14 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; import javax.xml.stream.XMLStreamWriter; -import jdk.jpackage.internal.IOUtils.XmlConsumer; +import jdk.jpackage.internal.util.XmlConsumer; import jdk.jpackage.internal.OverridableResource.Source; import static jdk.jpackage.internal.StandardBundlerParam.CONFIG_ROOT; import jdk.internal.util.Architecture; import static jdk.jpackage.internal.OverridableResource.createResource; import jdk.jpackage.internal.WixSourceConverter.ResourceGroup; import jdk.jpackage.internal.WixToolset.WixToolsetType; +import jdk.jpackage.internal.util.XmlUtils; /** * Creates WiX fragment. @@ -159,7 +160,7 @@ final protected void addResource(OverridableResource resource, String saveAsName } private void createWixSource(Path file, XmlConsumer xmlConsumer) throws IOException { - IOUtils.createXml(file, xml -> { + XmlUtils.createXml(file, xml -> { xml.writeStartElement("Wix"); for (var ns : getWixNamespaces().entrySet()) { switch (ns.getKey()) { diff --git a/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/WixLauncherAsService.java b/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/WixLauncherAsService.java index 9b737c8e1a4..ffd5e35b15c 100644 --- a/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/WixLauncherAsService.java +++ b/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/WixLauncherAsService.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -39,6 +39,7 @@ import javax.xml.xpath.XPathExpressionException; import javax.xml.xpath.XPathFactory; import static jdk.jpackage.internal.OverridableResource.createResource; +import jdk.jpackage.internal.util.XmlUtils; import org.w3c.dom.Document; import org.w3c.dom.Node; import org.w3c.dom.NodeList; @@ -95,7 +96,7 @@ private void writeResource(OverridableResource resource, XMLStreamWriter xml) resource.saveToStream(buffer); try { - Document doc = IOUtils.initDocumentBuilder().parse( + Document doc = XmlUtils.initDocumentBuilder().parse( new ByteArrayInputStream(buffer.toByteArray())); XPath xPath = XPathFactory.newInstance().newXPath(); @@ -109,7 +110,7 @@ private void writeResource(OverridableResource resource, XMLStreamWriter xml) sources.add(new DOMSource(n)); } - IOUtils.mergeXmls(xml, sources); + XmlUtils.mergeXmls(xml, sources); } catch (SAXException ex) { throw new IOException(ex); diff --git a/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/WixPipeline.java b/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/WixPipeline.java index 835247ed1de..5b626c8a565 100644 --- a/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/WixPipeline.java +++ b/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/WixPipeline.java @@ -36,6 +36,7 @@ import java.util.function.Function; import java.util.stream.Collectors; import java.util.stream.Stream; +import jdk.jpackage.internal.util.PathUtils; /** * WiX pipeline. Compiles and links WiX sources. @@ -180,7 +181,7 @@ private void buildMsiWix3(Path msi) throws IOException { } private Path compileWix3(WixSource wixSource) throws IOException { - Path wixObj = wixObjDir.toAbsolutePath().resolve(IOUtils.replaceSuffix( + Path wixObj = wixObjDir.toAbsolutePath().resolve(PathUtils.replaceSuffix( IOUtils.getFileName(wixSource.source), ".wixobj")); List<String> cmdline = new ArrayList<>(List.of( diff --git a/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/WixSourceConverter.java b/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/WixSourceConverter.java index 7786d64a786..86ef70442dc 100644 --- a/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/WixSourceConverter.java +++ b/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/WixSourceConverter.java @@ -52,6 +52,7 @@ import javax.xml.transform.stax.StAXResult; import javax.xml.transform.stream.StreamSource; import jdk.jpackage.internal.WixToolset.WixToolsetType; +import jdk.jpackage.internal.util.XmlUtils; import org.w3c.dom.Document; import org.xml.sax.SAXException; @@ -98,7 +99,7 @@ Status appyTo(OverridableResource resource, Path resourceSaveAsFile) throws IOEx Document inputXmlDom; try { - inputXmlDom = IOUtils.initDocumentBuilder().parse(new ByteArrayInputStream(buf)); + inputXmlDom = XmlUtils.initDocumentBuilder().parse(new ByteArrayInputStream(buf)); } catch (SAXException ex) { // Malformed XML, don't run converter, save as is. resource.saveToFile(resourceSaveAsFile); diff --git a/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/WixTool.java b/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/WixTool.java index f16b28edf24..ee98327b032 100644 --- a/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/WixTool.java +++ b/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/WixTool.java @@ -41,6 +41,7 @@ import java.util.stream.Collectors; import java.util.stream.Stream; import jdk.jpackage.internal.WixToolset.WixToolsetType; +import jdk.jpackage.internal.util.PathUtils; /** * WiX tool. @@ -51,7 +52,7 @@ public enum WixTool { Wix4("wix", DottedVersion.lazy("4.0.4")); WixTool(String commandName, DottedVersion minimalVersion) { - this.toolFileName = IOUtils.addSuffix(Path.of(commandName), ".exe"); + this.toolFileName = PathUtils.addSuffix(Path.of(commandName), ".exe"); this.minimalVersion = minimalVersion; } diff --git a/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/WixUiFragmentBuilder.java b/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/WixUiFragmentBuilder.java index 4f39a65e3b6..5eb23fc58c4 100644 --- a/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/WixUiFragmentBuilder.java +++ b/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/WixUiFragmentBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -39,7 +39,7 @@ import java.util.stream.Stream; import javax.xml.stream.XMLStreamException; import javax.xml.stream.XMLStreamWriter; -import jdk.jpackage.internal.IOUtils.XmlConsumer; +import jdk.jpackage.internal.util.XmlConsumer; import static jdk.jpackage.internal.OverridableResource.createResource; import static jdk.jpackage.internal.StandardBundlerParam.LICENSE_FILE; import jdk.jpackage.internal.WixAppImageFragmentBuilder.ShortcutsFolder; diff --git a/test/jdk/tools/jpackage/TEST.properties b/test/jdk/tools/jpackage/TEST.properties index e01036f0ed3..a34532d6695 100644 --- a/test/jdk/tools/jpackage/TEST.properties +++ b/test/jdk/tools/jpackage/TEST.properties @@ -12,4 +12,6 @@ maxOutputSize=2000000 exclusiveAccess.dirs=share windows modules=jdk.jpackage/jdk.jpackage.internal:+open \ + jdk.jpackage/jdk.jpackage.internal.util \ + jdk.jpackage/jdk.jpackage.internal.util.function \ java.base/jdk.internal.util diff --git a/test/jdk/tools/jpackage/helpers-test/jdk/jpackage/test/AnnotationsTest.java b/test/jdk/tools/jpackage/helpers-test/jdk/jpackage/test/AnnotationsTest.java index 2d23f49cdd7..230b14fd1ea 100644 --- a/test/jdk/tools/jpackage/helpers-test/jdk/jpackage/test/AnnotationsTest.java +++ b/test/jdk/tools/jpackage/helpers-test/jdk/jpackage/test/AnnotationsTest.java @@ -40,7 +40,7 @@ import jdk.jpackage.test.Annotations.ParameterSupplier; import jdk.jpackage.test.Annotations.Parameters; import jdk.jpackage.test.Annotations.Test; -import static jdk.jpackage.test.Functional.ThrowingSupplier.toSupplier; +import static jdk.jpackage.internal.util.function.ThrowingSupplier.toSupplier; /* * @test diff --git a/test/jdk/tools/jpackage/helpers-test/jdk/jpackage/test/TKitTest.java b/test/jdk/tools/jpackage/helpers-test/jdk/jpackage/test/TKitTest.java index 3f55c3c50ae..98a7d873190 100644 --- a/test/jdk/tools/jpackage/helpers-test/jdk/jpackage/test/TKitTest.java +++ b/test/jdk/tools/jpackage/helpers-test/jdk/jpackage/test/TKitTest.java @@ -37,9 +37,9 @@ import java.util.stream.Stream; import jdk.jpackage.test.Annotations.Parameters; import jdk.jpackage.test.Annotations.Test; -import jdk.jpackage.test.Functional.ThrowingRunnable; -import static jdk.jpackage.test.Functional.ThrowingRunnable.toRunnable; -import static jdk.jpackage.test.Functional.ThrowingSupplier.toSupplier; +import jdk.jpackage.internal.util.function.ThrowingRunnable; +import static jdk.jpackage.internal.util.function.ThrowingRunnable.toRunnable; +import static jdk.jpackage.internal.util.function.ThrowingSupplier.toSupplier; public class TKitTest { diff --git a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/AdditionalLauncher.java b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/AdditionalLauncher.java index 6c388ac77ff..70b0e160d24 100644 --- a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/AdditionalLauncher.java +++ b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/AdditionalLauncher.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -37,8 +37,9 @@ import java.util.regex.Pattern; import java.util.stream.Collectors; import java.util.stream.Stream; -import jdk.jpackage.test.Functional.ThrowingBiConsumer; -import static jdk.jpackage.test.Functional.ThrowingFunction.toFunction; +import static jdk.jpackage.internal.util.function.ExceptionBox.rethrowUnchecked; +import jdk.jpackage.internal.util.function.ThrowingBiConsumer; +import static jdk.jpackage.internal.util.function.ThrowingFunction.toFunction; public class AdditionalLauncher { @@ -48,12 +49,12 @@ public AdditionalLauncher(String name) { setPersistenceHandler(null); } - final public AdditionalLauncher setDefaultArguments(String... v) { + public final AdditionalLauncher setDefaultArguments(String... v) { defaultArguments = new ArrayList<>(List.of(v)); return this; } - final public AdditionalLauncher addDefaultArguments(String... v) { + public final AdditionalLauncher addDefaultArguments(String... v) { if (defaultArguments == null) { return setDefaultArguments(v); } @@ -62,12 +63,12 @@ final public AdditionalLauncher addDefaultArguments(String... v) { return this; } - final public AdditionalLauncher setJavaOptions(String... v) { + public final AdditionalLauncher setJavaOptions(String... v) { javaOptions = new ArrayList<>(List.of(v)); return this; } - final public AdditionalLauncher addJavaOptions(String... v) { + public final AdditionalLauncher addJavaOptions(String... v) { if (javaOptions == null) { return setJavaOptions(v); } @@ -76,27 +77,27 @@ final public AdditionalLauncher addJavaOptions(String... v) { return this; } - final public AdditionalLauncher setVerifyUninstalled(boolean value) { + public final AdditionalLauncher setVerifyUninstalled(boolean value) { verifyUninstalled = value; return this; } - final public AdditionalLauncher setLauncherAsService() { + public final AdditionalLauncher setLauncherAsService() { return addRawProperties(LAUNCHER_AS_SERVICE); } - final public AdditionalLauncher addRawProperties( + public final AdditionalLauncher addRawProperties( Map.Entry<String, String>... v) { return addRawProperties(List.of(v)); } - final public AdditionalLauncher addRawProperties( + public final AdditionalLauncher addRawProperties( Collection<Map.Entry<String, String>> v) { rawProperties.addAll(v); return this; } - final public String getRawPropertyValue( + public final String getRawPropertyValue( String key, Supplier<String> getDefault) { return rawProperties.stream() .filter(item -> item.getKey().equals(key)) @@ -108,13 +109,13 @@ private String getDesciption(JPackageCommand cmd) { "--description", unused -> cmd.name())); } - final public AdditionalLauncher setShortcuts(boolean menu, boolean shortcut) { + public final AdditionalLauncher setShortcuts(boolean menu, boolean shortcut) { withMenuShortcut = menu; withShortcut = shortcut; return this; } - final public AdditionalLauncher setIcon(Path iconPath) { + public final AdditionalLauncher setIcon(Path iconPath) { if (iconPath == NO_ICON) { throw new IllegalArgumentException(); } @@ -123,12 +124,12 @@ final public AdditionalLauncher setIcon(Path iconPath) { return this; } - final public AdditionalLauncher setNoIcon() { + public final AdditionalLauncher setNoIcon() { icon = NO_ICON; return this; } - final public AdditionalLauncher setPersistenceHandler( + public final AdditionalLauncher setPersistenceHandler( ThrowingBiConsumer<Path, List<Map.Entry<String, String>>> handler) { if (handler != null) { createFileHandler = ThrowingBiConsumer.toBiConsumer(handler); @@ -138,12 +139,12 @@ final public AdditionalLauncher setPersistenceHandler( return this; } - final public void applyTo(JPackageCommand cmd) { + public final void applyTo(JPackageCommand cmd) { cmd.addPrerequisiteAction(this::initialize); cmd.addVerifyAction(this::verify); } - final public void applyTo(PackageTest test) { + public final void applyTo(PackageTest test) { test.addInitializer(this::initialize); test.addInstallVerifier(this::verify); if (verifyUninstalled) { @@ -151,7 +152,7 @@ final public void applyTo(PackageTest test) { } } - final public void verifyRemovedInUpgrade(PackageTest test) { + public final void verifyRemovedInUpgrade(PackageTest test) { test.addInstallVerifier(this::verifyUninstalled); } @@ -189,7 +190,7 @@ private void initialize(JPackageCommand cmd) { propsFile = TKit.createTempFile(propsFile); TKit.deleteIfExists(propsFile); } catch (IOException ex) { - Functional.rethrowUnchecked(ex); + rethrowUnchecked(ex); } } @@ -446,7 +447,7 @@ private static String resolveVariables(JPackageCommand cmd, String str) { private Boolean withMenuShortcut; private Boolean withShortcut; - private final static Path NO_ICON = Path.of(""); - private final static Map.Entry<String, String> LAUNCHER_AS_SERVICE = Map.entry( + private static final Path NO_ICON = Path.of(""); + private static final Map.Entry<String, String> LAUNCHER_AS_SERVICE = Map.entry( "launcher-as-service", "true"); } diff --git a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/Executor.java b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/Executor.java index 72ebb64a142..f182f4f7f7d 100644 --- a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/Executor.java +++ b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/Executor.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -42,7 +42,7 @@ import java.util.spi.ToolProvider; import java.util.stream.Collectors; import java.util.stream.Stream; -import jdk.jpackage.test.Functional.ThrowingSupplier; +import jdk.jpackage.internal.util.function.ThrowingSupplier; public final class Executor extends CommandArguments<Executor> { diff --git a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/FileAssociations.java b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/FileAssociations.java index 49085197828..091a2206b17 100644 --- a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/FileAssociations.java +++ b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/FileAssociations.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -32,10 +32,10 @@ import java.util.Map; import java.util.Objects; import java.util.Optional; -import jdk.jpackage.internal.IOUtils; +import jdk.jpackage.internal.util.PathUtils; -final public class FileAssociations { +public final class FileAssociations { public FileAssociations(String faSuffixName) { suffixName = faSuffixName; setFilename("fa"); @@ -79,7 +79,7 @@ Path getLinuxIconFileName() { if (icon == null) { return null; } - return Path.of(getMime().replace('/', '-') + IOUtils.getSuffix(icon)); + return Path.of(getMime().replace('/', '-') + PathUtils.getSuffix(icon)); } Path getPropertiesFile() { @@ -243,7 +243,7 @@ public static enum InvocationType { } private Path file; - final private String suffixName; + private final String suffixName; private String description; private Path icon; private Collection<TestRun> testRuns; diff --git a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/Functional.java b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/Functional.java index a57caa92cb2..a974670b8e4 100644 --- a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/Functional.java +++ b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/Functional.java @@ -31,84 +31,6 @@ public class Functional { - @FunctionalInterface - public interface ThrowingConsumer<T> { - void accept(T t) throws Throwable; - - public static <T> Consumer<T> toConsumer(ThrowingConsumer<T> v) { - return o -> { - try { - v.accept(o); - } catch (Throwable ex) { - rethrowUnchecked(ex); - } - }; - } - } - - @FunctionalInterface - public interface ThrowingBiConsumer<T, U> { - void accept(T t, U u) throws Throwable; - - public static <T, U> BiConsumer<T, U> toBiConsumer(ThrowingBiConsumer<T, U> v) { - return (t, u) -> { - try { - v.accept(t, u); - } catch (Throwable ex) { - rethrowUnchecked(ex); - } - }; - } - } - - @FunctionalInterface - public interface ThrowingSupplier<T> { - T get() throws Throwable; - - public static <T> Supplier<T> toSupplier(ThrowingSupplier<T> v) { - return () -> { - try { - return v.get(); - } catch (Throwable ex) { - rethrowUnchecked(ex); - } - // Unreachable - return null; - }; - } - } - - @FunctionalInterface - public interface ThrowingFunction<T, R> { - R apply(T t) throws Throwable; - - public static <T, R> Function<T, R> toFunction(ThrowingFunction<T, R> v) { - return (t) -> { - try { - return v.apply(t); - } catch (Throwable ex) { - rethrowUnchecked(ex); - } - // Unreachable - return null; - }; - } - } - - @FunctionalInterface - public interface ThrowingRunnable { - void run() throws Throwable; - - public static Runnable toRunnable(ThrowingRunnable v) { - return () -> { - try { - v.run(); - } catch (Throwable ex) { - rethrowUnchecked(ex); - } - }; - } - } public static <T> Supplier<T> identity(Supplier<T> v) { return v; @@ -141,28 +63,4 @@ public static <T> Predicate<T> identity(Predicate<T> v) { public static <T> Predicate<T> identityPredicate(Predicate<T> v) { return v; } - - public static class ExceptionBox extends RuntimeException { - public ExceptionBox(Throwable throwable) { - super(throwable); - } - } - - @SuppressWarnings("unchecked") - public static RuntimeException rethrowUnchecked(Throwable throwable) throws - ExceptionBox { - if (throwable instanceof RuntimeException err) { - throw err; - } - - if (throwable instanceof Error err) { - throw err; - } - - if (throwable instanceof InvocationTargetException err) { - throw rethrowUnchecked(err.getCause()); - } - - throw new ExceptionBox(throwable); - } } diff --git a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/HelloApp.java b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/HelloApp.java index bc722e7acd9..bc35912bcbb 100644 --- a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/HelloApp.java +++ b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/HelloApp.java @@ -40,9 +40,9 @@ import java.util.stream.Collectors; import java.util.zip.ZipEntry; import java.util.zip.ZipFile; -import jdk.jpackage.test.Functional.ThrowingConsumer; -import jdk.jpackage.test.Functional.ThrowingFunction; -import jdk.jpackage.test.Functional.ThrowingSupplier; +import jdk.jpackage.internal.util.function.ThrowingConsumer; +import jdk.jpackage.internal.util.function.ThrowingFunction; +import jdk.jpackage.internal.util.function.ThrowingSupplier; public final class HelloApp { diff --git a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/JPackageCommand.java b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/JPackageCommand.java index 49eeb25a00e..4239d8a87c8 100644 --- a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/JPackageCommand.java +++ b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/JPackageCommand.java @@ -45,15 +45,15 @@ import java.util.regex.Pattern; import java.util.stream.Collectors; import java.util.stream.Stream; -import jdk.jpackage.internal.IOUtils; import jdk.jpackage.internal.AppImageFile; import jdk.jpackage.internal.ApplicationLayout; import jdk.jpackage.internal.PackageFile; +import jdk.jpackage.internal.util.XmlUtils; import static jdk.jpackage.test.AdditionalLauncher.forEachAdditionalLauncher; -import jdk.jpackage.test.Functional.ThrowingConsumer; -import jdk.jpackage.test.Functional.ThrowingFunction; -import jdk.jpackage.test.Functional.ThrowingRunnable; -import jdk.jpackage.test.Functional.ThrowingSupplier; +import jdk.jpackage.internal.util.function.ThrowingConsumer; +import jdk.jpackage.internal.util.function.ThrowingFunction; +import jdk.jpackage.internal.util.function.ThrowingRunnable; +import jdk.jpackage.internal.util.function.ThrowingSupplier; /** * jpackage command line with prerequisite actions. Prerequisite actions can be @@ -315,7 +315,7 @@ public void createJPackageXMLFile(String mainLauncher, String mainClass) "Error: --app-image expected"); })); - IOUtils.createXml(jpackageXMLFile, xml -> { + XmlUtils.createXml(jpackageXMLFile, xml -> { xml.writeStartElement("jpackage-state"); xml.writeAttribute("version", AppImageFile.getVersion()); xml.writeAttribute("platform", AppImageFile.getPlatform()); diff --git a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/LauncherAsServiceVerifier.java b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/LauncherAsServiceVerifier.java index 026da0df0eb..d73029ab153 100644 --- a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/LauncherAsServiceVerifier.java +++ b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/LauncherAsServiceVerifier.java @@ -35,8 +35,10 @@ import java.util.regex.Pattern; import java.util.stream.Collectors; import java.util.stream.Stream; -import jdk.jpackage.internal.IOUtils; -import static jdk.jpackage.test.Functional.ThrowingConsumer.toConsumer; +import jdk.jpackage.internal.util.PathUtils; +import jdk.jpackage.internal.util.function.ThrowingBiConsumer; +import static jdk.jpackage.internal.util.function.ThrowingConsumer.toConsumer; +import jdk.jpackage.internal.util.function.ThrowingRunnable; import static jdk.jpackage.test.PackageType.LINUX; import static jdk.jpackage.test.PackageType.MAC_PKG; import static jdk.jpackage.test.PackageType.WINDOWS; @@ -187,7 +189,7 @@ static List<String> getLaunchersAsServices(JPackageCommand cmd) { } AdditionalLauncher.forEachAdditionalLauncher(cmd, - Functional.ThrowingBiConsumer.toBiConsumer( + ThrowingBiConsumer.toBiConsumer( (launcherName, propFilePath) -> { if (Files.readAllLines(propFilePath).stream().anyMatch( line -> { @@ -335,14 +337,14 @@ private static void verifyMacDaemonPlistFile(JPackageCommand cmd, TKit.assertEquals(installedLauncherPath.toString(), args.get(0), "Check path to launcher in 'ProgramArguments' property in the property file"); - var expectedLabel = IOUtils.replaceSuffix(servicePlistFile.getFileName(), "").toString(); + var expectedLabel = PathUtils.replaceSuffix(servicePlistFile.getFileName(), "").toString(); TKit.assertEquals(expectedLabel, servicePlist.queryValue("Label"), "Check value of 'Label' property in the property file"); } private static void delayInstallVerify() { // Sleep a bit to let system launch the service - Functional.ThrowingRunnable.toRunnable(() -> Thread.sleep(5 * 1000)).run(); + ThrowingRunnable.toRunnable(() -> Thread.sleep(5 * 1000)).run(); } private Path appOutputFilePathInitialize() { diff --git a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/LauncherIconVerifier.java b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/LauncherIconVerifier.java index 2de2e002a94..39e483f1fee 100644 --- a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/LauncherIconVerifier.java +++ b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/LauncherIconVerifier.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -31,6 +31,7 @@ import java.nio.file.Path; import java.util.Optional; import javax.imageio.ImageIO; +import static jdk.jpackage.internal.util.function.ExceptionBox.rethrowUnchecked; public final class LauncherIconVerifier { public LauncherIconVerifier() { @@ -176,7 +177,7 @@ private WinIconVerifier() { iconSwapWrapper.setAccessible(true); } catch (ClassNotFoundException | NoSuchMethodException | SecurityException ex) { - throw Functional.rethrowUnchecked(ex); + throw rethrowUnchecked(ex); } } @@ -254,14 +255,14 @@ private void setIcon(Path iconPath, Path launcherPath) { } } } catch (IllegalAccessException | InvocationTargetException ex) { - throw Functional.rethrowUnchecked(ex); + throw rethrowUnchecked(ex); } } finally { launcherPath.toFile().setWritable(false, true); } } - final static WinIconVerifier instance = new WinIconVerifier(); + static final WinIconVerifier instance = new WinIconVerifier(); private final Class executableRebranderClass; private final Method lockResource; diff --git a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/LinuxHelper.java b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/LinuxHelper.java index a96bab49355..35baff3d5db 100644 --- a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/LinuxHelper.java +++ b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/LinuxHelper.java @@ -41,8 +41,8 @@ import java.util.stream.Collectors; import java.util.stream.Stream; import jdk.jpackage.internal.ApplicationLayout; -import jdk.jpackage.internal.IOUtils; -import jdk.jpackage.test.Functional.ThrowingConsumer; +import jdk.jpackage.internal.util.PathUtils; +import jdk.jpackage.internal.util.function.ThrowingConsumer; import jdk.jpackage.test.PackageTest.PackageHandlers; @@ -578,7 +578,7 @@ private static String queryMimeTypeDefaultHandler(String mimeType) { private static void verifyIconInScriptlet(Scriptlet scriptletType, List<String> scriptletBody, Path iconPathInPackage) { - final String dashMime = IOUtils.replaceSuffix( + final String dashMime = PathUtils.replaceSuffix( iconPathInPackage.getFileName(), null).toString(); final String xdgCmdName = "xdg-icon-resource"; diff --git a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/MacHelper.java b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/MacHelper.java index 63afb6cf9f7..9cadd419ca1 100644 --- a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/MacHelper.java +++ b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/MacHelper.java @@ -43,11 +43,11 @@ import javax.xml.xpath.XPath; import javax.xml.xpath.XPathConstants; import javax.xml.xpath.XPathFactory; -import jdk.jpackage.internal.IOUtils; -import jdk.jpackage.test.Functional.ThrowingConsumer; -import jdk.jpackage.test.Functional.ThrowingSupplier; +import jdk.jpackage.internal.util.function.ThrowingConsumer; +import jdk.jpackage.internal.util.function.ThrowingSupplier; import jdk.jpackage.test.PackageTest.PackageHandlers; import jdk.jpackage.internal.RetryExecutor; +import jdk.jpackage.internal.util.PathUtils; import org.xml.sax.SAXException; import org.w3c.dom.NodeList; @@ -212,7 +212,7 @@ static PackageHandlers createPkgPackageHandlers() { // Unpack all ".pkg" files from $dataDir folder in $unpackDir folder try (var dataListing = Files.list(dataDir)) { dataListing.filter(file -> { - return ".pkg".equals(IOUtils.getSuffix(file.getFileName())); + return ".pkg".equals(PathUtils.getSuffix(file.getFileName())); }).forEach(ThrowingConsumer.toConsumer(pkgDir -> { // Installation root of the package is stored in // /pkg-info@install-location attribute in $pkgDir/PackageInfo xml file diff --git a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/MethodCall.java b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/MethodCall.java index d5b8bd702c8..51a8ade8a1d 100644 --- a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/MethodCall.java +++ b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/MethodCall.java @@ -37,7 +37,7 @@ import java.util.function.Predicate; import java.util.stream.IntStream; import java.util.stream.Stream; -import jdk.jpackage.test.Functional.ThrowingConsumer; +import jdk.jpackage.internal.util.function.ThrowingConsumer; import jdk.jpackage.test.TestInstance.TestDesc; class MethodCall implements ThrowingConsumer { diff --git a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/PackageTest.java b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/PackageTest.java index 6f486425e73..7c6aab29fee 100644 --- a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/PackageTest.java +++ b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/PackageTest.java @@ -46,13 +46,13 @@ import java.util.stream.Stream; import java.util.stream.StreamSupport; import jdk.jpackage.internal.ApplicationLayout; -import jdk.jpackage.test.Functional.ThrowingBiConsumer; -import static jdk.jpackage.test.Functional.ThrowingBiConsumer.toBiConsumer; -import jdk.jpackage.test.Functional.ThrowingConsumer; -import static jdk.jpackage.test.Functional.ThrowingConsumer.toConsumer; -import jdk.jpackage.test.Functional.ThrowingRunnable; -import static jdk.jpackage.test.Functional.ThrowingSupplier.toSupplier; -import static jdk.jpackage.test.Functional.rethrowUnchecked; +import jdk.jpackage.internal.util.function.ThrowingBiConsumer; +import static jdk.jpackage.internal.util.function.ThrowingBiConsumer.toBiConsumer; +import jdk.jpackage.internal.util.function.ThrowingConsumer; +import static jdk.jpackage.internal.util.function.ThrowingConsumer.toConsumer; +import jdk.jpackage.internal.util.function.ThrowingRunnable; +import static jdk.jpackage.internal.util.function.ThrowingSupplier.toSupplier; +import static jdk.jpackage.internal.util.function.ExceptionBox.rethrowUnchecked; import static jdk.jpackage.test.PackageType.LINUX; import static jdk.jpackage.test.PackageType.LINUX_DEB; import static jdk.jpackage.test.PackageType.LINUX_RPM; diff --git a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/PackageType.java b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/PackageType.java index 71637ef7134..8aa7d005adb 100644 --- a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/PackageType.java +++ b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/PackageType.java @@ -32,6 +32,7 @@ import java.util.stream.Collectors; import java.util.stream.Stream; import jdk.jpackage.internal.Log; +import static jdk.jpackage.internal.util.function.ExceptionBox.rethrowUnchecked; /** * jpackage type traits. @@ -103,7 +104,7 @@ private static boolean isBundlerSupportedImpl(String bundlerClass) { } catch (ClassNotFoundException | IllegalAccessException ex) { } catch (InstantiationException | NoSuchMethodException | InvocationTargetException ex) { - Functional.rethrowUnchecked(ex); + rethrowUnchecked(ex); } return false; } @@ -127,7 +128,7 @@ private static boolean isBundlerSupported(String bundlerClass) { thread.run(); thread.join(); } catch (InterruptedException ex) { - Functional.rethrowUnchecked(ex); + rethrowUnchecked(ex); } return reply.get(); } @@ -136,15 +137,15 @@ private static boolean isBundlerSupported(String bundlerClass) { private final String suffix; private final boolean supported; - public final static Set<PackageType> LINUX = Set.of(LINUX_DEB, LINUX_RPM); - public final static Set<PackageType> WINDOWS = Set.of(WIN_EXE, WIN_MSI); - public final static Set<PackageType> MAC = Set.of(MAC_PKG, MAC_DMG); - public final static Set<PackageType> NATIVE = Stream.concat( + public static final Set<PackageType> LINUX = Set.of(LINUX_DEB, LINUX_RPM); + public static final Set<PackageType> WINDOWS = Set.of(WIN_EXE, WIN_MSI); + public static final Set<PackageType> MAC = Set.of(MAC_PKG, MAC_DMG); + public static final Set<PackageType> NATIVE = Stream.concat( Stream.concat(LINUX.stream(), WINDOWS.stream()), MAC.stream()).collect(Collectors.toUnmodifiableSet()); - private final static class Inner { - private final static Set<String> DISABLED_PACKAGERS = Optional.ofNullable( + private static final class Inner { + private static final Set<String> DISABLED_PACKAGERS = Optional.ofNullable( TKit.tokenizeConfigProperty("disabledPackagers")).orElse( TKit.isLinuxAPT() ? Set.of("rpm") : Collections.emptySet()); } diff --git a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/TKit.java b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/TKit.java index 8f91d581ef1..b5859564568 100644 --- a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/TKit.java +++ b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/TKit.java @@ -61,10 +61,10 @@ import static java.util.stream.Collectors.toSet; import java.util.stream.Stream; import jdk.internal.util.OperatingSystem; -import jdk.jpackage.test.Functional.ExceptionBox; -import jdk.jpackage.test.Functional.ThrowingConsumer; -import jdk.jpackage.test.Functional.ThrowingRunnable; -import jdk.jpackage.test.Functional.ThrowingSupplier; +import jdk.jpackage.internal.util.function.ExceptionBox; +import jdk.jpackage.internal.util.function.ThrowingConsumer; +import jdk.jpackage.internal.util.function.ThrowingRunnable; +import jdk.jpackage.internal.util.function.ThrowingSupplier; public final class TKit { diff --git a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/TestBuilder.java b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/TestBuilder.java index c2fc1789a25..23fd5dd52a5 100644 --- a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/TestBuilder.java +++ b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/TestBuilder.java @@ -40,9 +40,9 @@ import jdk.jpackage.test.Annotations.AfterEach; import jdk.jpackage.test.Annotations.BeforeEach; import jdk.jpackage.test.Annotations.Test; -import jdk.jpackage.test.Functional.ThrowingConsumer; -import static jdk.jpackage.test.Functional.ThrowingConsumer.toConsumer; -import jdk.jpackage.test.Functional.ThrowingFunction; +import jdk.jpackage.internal.util.function.ThrowingConsumer; +import static jdk.jpackage.internal.util.function.ThrowingConsumer.toConsumer; +import jdk.jpackage.internal.util.function.ThrowingFunction; import jdk.jpackage.test.TestMethodSupplier.InvalidAnnotationException; import static jdk.jpackage.test.TestMethodSupplier.MethodQuery.fromQualifiedMethodName; diff --git a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/TestInstance.java b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/TestInstance.java index f619c9e222e..871ddc24277 100644 --- a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/TestInstance.java +++ b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/TestInstance.java @@ -40,9 +40,10 @@ import java.util.function.Supplier; import java.util.stream.Collectors; import java.util.stream.Stream; -import jdk.jpackage.test.Functional.ThrowingConsumer; -import jdk.jpackage.test.Functional.ThrowingFunction; -import jdk.jpackage.test.Functional.ThrowingRunnable; +import jdk.jpackage.internal.util.function.ThrowingConsumer; +import jdk.jpackage.internal.util.function.ThrowingFunction; +import jdk.jpackage.internal.util.function.ThrowingRunnable; +import jdk.jpackage.internal.util.function.ThrowingSupplier; final class TestInstance implements ThrowingRunnable { @@ -258,7 +259,7 @@ private static Class enclosingMainMethodClass() { StackTraceElement st[] = Thread.currentThread().getStackTrace(); for (StackTraceElement ste : st) { if ("main".equals(ste.getMethodName())) { - return Functional.ThrowingSupplier.toSupplier(() -> Class.forName( + return ThrowingSupplier.toSupplier(() -> Class.forName( ste.getClassName())).get(); } } diff --git a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/TestMethodSupplier.java b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/TestMethodSupplier.java index 83b1c19bd95..0d701d0ec6f 100644 --- a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/TestMethodSupplier.java +++ b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/TestMethodSupplier.java @@ -49,8 +49,8 @@ import jdk.jpackage.test.Annotations.ParameterSupplierGroup; import jdk.jpackage.test.Annotations.Parameters; import jdk.jpackage.test.Annotations.Test; -import static jdk.jpackage.test.Functional.ThrowingFunction.toFunction; -import static jdk.jpackage.test.Functional.ThrowingSupplier.toSupplier; +import static jdk.jpackage.internal.util.function.ThrowingFunction.toFunction; +import static jdk.jpackage.internal.util.function.ThrowingSupplier.toSupplier; import static jdk.jpackage.test.MethodCall.mapArgs; final class TestMethodSupplier { diff --git a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/WindowsHelper.java b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/WindowsHelper.java index 1976a5cf72c..42ea9e3e9a7 100644 --- a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/WindowsHelper.java +++ b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/WindowsHelper.java @@ -36,7 +36,7 @@ import java.util.regex.Pattern; import java.util.stream.Collectors; import java.util.stream.Stream; -import jdk.jpackage.test.Functional.ThrowingRunnable; +import jdk.jpackage.internal.util.function.ThrowingRunnable; import jdk.jpackage.test.PackageTest.PackageHandlers; public class WindowsHelper { diff --git a/test/jdk/tools/jpackage/linux/AppAboutUrlTest.java b/test/jdk/tools/jpackage/linux/AppAboutUrlTest.java index 0d8f0ec4805..aef46e29725 100644 --- a/test/jdk/tools/jpackage/linux/AppAboutUrlTest.java +++ b/test/jdk/tools/jpackage/linux/AppAboutUrlTest.java @@ -22,7 +22,7 @@ */ import jdk.jpackage.test.Annotations.Test; -import jdk.jpackage.test.Functional.ThrowingConsumer; +import jdk.jpackage.internal.util.function.ThrowingConsumer; import jdk.jpackage.test.JPackageCommand; import jdk.jpackage.test.PackageTest; import jdk.jpackage.test.PackageType; diff --git a/test/jdk/tools/jpackage/share/AppContentTest.java b/test/jdk/tools/jpackage/share/AppContentTest.java index e056070a5fc..d33960092ee 100644 --- a/test/jdk/tools/jpackage/share/AppContentTest.java +++ b/test/jdk/tools/jpackage/share/AppContentTest.java @@ -33,8 +33,8 @@ import java.util.List; import static java.util.stream.Collectors.joining; import java.util.stream.Stream; -import jdk.jpackage.internal.IOUtils; -import jdk.jpackage.test.Functional.ThrowingFunction; +import jdk.jpackage.internal.util.FileUtils; +import jdk.jpackage.internal.util.function.ThrowingFunction; import jdk.jpackage.test.JPackageCommand; @@ -65,7 +65,7 @@ public class AppContentTest { // In particular, random files should be placed in "Contents/Resources" folder // otherwise "codesign" will fail to sign. // Need to prepare arguments for `--app-content` accordingly. - private final static boolean copyInResources = TKit.isOSX(); + private static final boolean copyInResources = TKit.isOSX(); private final List<String> testPathArgs; @@ -148,7 +148,7 @@ private static Path copyAppContentPath(Path appContentPath) throws IOException { var srcPath = TKit.TEST_SRC_ROOT.resolve(appContentPath); var dstPath = appContentArg.resolve(srcPath.getFileName()); Files.createDirectories(dstPath.getParent()); - IOUtils.copyRecursive(srcPath, dstPath); + FileUtils.copyRecursive(srcPath, dstPath); return appContentArg; } diff --git a/test/jdk/tools/jpackage/share/BasicTest.java b/test/jdk/tools/jpackage/share/BasicTest.java index 61668b9e878..c6e4e930155 100644 --- a/test/jdk/tools/jpackage/share/BasicTest.java +++ b/test/jdk/tools/jpackage/share/BasicTest.java @@ -41,7 +41,7 @@ import jdk.jpackage.test.JavaTool; import jdk.jpackage.test.Annotations.Test; import jdk.jpackage.test.Annotations.Parameter; -import jdk.jpackage.test.Functional.ThrowingConsumer; +import jdk.jpackage.internal.util.function.ThrowingConsumer; import static jdk.jpackage.test.RunnablePackageTest.Action.CREATE_AND_UNPACK; /* diff --git a/test/jdk/tools/jpackage/share/IconTest.java b/test/jdk/tools/jpackage/share/IconTest.java index 2d6469f5f2e..d5edbc93245 100644 --- a/test/jdk/tools/jpackage/share/IconTest.java +++ b/test/jdk/tools/jpackage/share/IconTest.java @@ -41,8 +41,8 @@ import jdk.jpackage.test.Executor; import jdk.jpackage.test.LinuxHelper; import jdk.jpackage.test.AdditionalLauncher; -import jdk.jpackage.test.Functional.ThrowingConsumer; -import jdk.jpackage.test.Functional.ThrowingBiConsumer; +import jdk.jpackage.internal.util.function.ThrowingConsumer; +import jdk.jpackage.internal.util.function.ThrowingBiConsumer; import jdk.jpackage.test.Annotations.Parameters; import jdk.jpackage.test.Annotations.Test; @@ -428,7 +428,7 @@ private enum Launcher { private final Path cmdlineIcon; private final Path resourceDirIcon; - private final static Set<Launcher> PRIMARY = Set.of(Main, Additional); + private static final Set<Launcher> PRIMARY = Set.of(Main, Additional); } private final boolean appImage; @@ -440,7 +440,7 @@ private static Path iconPath(String name) { + TKit.ICON_SUFFIX)); } - private final static Path[] ICONS = Stream.of("icon", "icon2", "icon3", + private static final Path[] ICONS = Stream.of("icon", "icon2", "icon3", "icon4") .map(IconTest::iconPath) .collect(Collectors.toList()).toArray(Path[]::new); diff --git a/test/jdk/tools/jpackage/share/InOutPathTest.java b/test/jdk/tools/jpackage/share/InOutPathTest.java index 15d96283ef4..b2579133148 100644 --- a/test/jdk/tools/jpackage/share/InOutPathTest.java +++ b/test/jdk/tools/jpackage/share/InOutPathTest.java @@ -36,7 +36,7 @@ import jdk.jpackage.internal.PackageFile; import jdk.jpackage.test.Annotations.Parameters; import jdk.jpackage.test.Annotations.Test; -import jdk.jpackage.test.Functional.ThrowingConsumer; +import jdk.jpackage.internal.util.function.ThrowingConsumer; import jdk.jpackage.test.JPackageCommand; import jdk.jpackage.test.JPackageCommand.AppLayoutAssert; import jdk.jpackage.test.PackageTest; diff --git a/test/jdk/tools/jpackage/share/MainClassTest.java b/test/jdk/tools/jpackage/share/MainClassTest.java index d9188e8f18f..a031bbc2788 100644 --- a/test/jdk/tools/jpackage/share/MainClassTest.java +++ b/test/jdk/tools/jpackage/share/MainClassTest.java @@ -44,7 +44,7 @@ import jdk.jpackage.test.Annotations.Parameters; import jdk.jpackage.test.Annotations.Test; import jdk.jpackage.test.CfgFile; -import jdk.jpackage.test.Functional.ThrowingConsumer; +import jdk.jpackage.internal.util.function.ThrowingConsumer; diff --git a/test/jdk/tools/jpackage/share/PerUserCfgTest.java b/test/jdk/tools/jpackage/share/PerUserCfgTest.java index 0fff7eb3a2d..2e62aa5c5d6 100644 --- a/test/jdk/tools/jpackage/share/PerUserCfgTest.java +++ b/test/jdk/tools/jpackage/share/PerUserCfgTest.java @@ -29,7 +29,7 @@ import jdk.jpackage.test.AdditionalLauncher; import jdk.jpackage.test.PackageTest; import jdk.jpackage.test.Annotations.Test; -import jdk.jpackage.test.Functional.ThrowingConsumer; +import jdk.jpackage.internal.util.function.ThrowingConsumer; import jdk.jpackage.test.HelloApp; import jdk.jpackage.test.JPackageCommand; import jdk.jpackage.test.LinuxHelper; diff --git a/test/jdk/tools/jpackage/share/RuntimeImageSymbolicLinksTest.java b/test/jdk/tools/jpackage/share/RuntimeImageSymbolicLinksTest.java index 0e48df630af..649ac0a3695 100644 --- a/test/jdk/tools/jpackage/share/RuntimeImageSymbolicLinksTest.java +++ b/test/jdk/tools/jpackage/share/RuntimeImageSymbolicLinksTest.java @@ -21,20 +21,11 @@ * questions. */ -import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; -import java.util.HashSet; -import java.util.Optional; -import java.util.Set; -import java.util.stream.Collectors; import jdk.jpackage.internal.ApplicationLayout; import jdk.jpackage.test.TKit; -import jdk.jpackage.test.PackageTest; -import jdk.jpackage.test.PackageType; -import jdk.jpackage.test.Functional; import jdk.jpackage.test.Annotations.Test; -import jdk.jpackage.test.Annotations.Parameter; import jdk.jpackage.test.JPackageCommand; import jdk.jpackage.test.JavaTool; import jdk.jpackage.test.Executor; diff --git a/test/jdk/tools/jpackage/windows/WinLongVersionTest.java b/test/jdk/tools/jpackage/windows/WinLongVersionTest.java index 0d52da65630..7a915b5c123 100644 --- a/test/jdk/tools/jpackage/windows/WinLongVersionTest.java +++ b/test/jdk/tools/jpackage/windows/WinLongVersionTest.java @@ -24,7 +24,6 @@ import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; -import java.util.Set; import java.util.UUID; import java.util.function.Supplier; import javax.xml.transform.Result; @@ -36,7 +35,7 @@ import javax.xml.xpath.XPath; import javax.xml.xpath.XPathConstants; import javax.xml.xpath.XPathFactory; -import jdk.jpackage.internal.IOUtils; +import jdk.jpackage.internal.util.XmlUtils; import jdk.jpackage.test.Annotations.Test; import jdk.jpackage.test.Executor; import jdk.jpackage.test.PackageTest; @@ -148,7 +147,7 @@ public static void test() throws IOException { Path scriptPath = resourceDir.resolve(String.format( "%s-post-msi.wsf", cmd.name())); - IOUtils.createXml(scriptPath, xml -> { + XmlUtils.createXml(scriptPath, xml -> { xml.writeStartElement("job"); xml.writeAttribute("id", "main"); xml.writeStartElement("script"); @@ -194,7 +193,7 @@ public static void testNoUpgradeTable() throws IOException { cmd.setFakeRuntime(); // Create package without Upgrade table - Document doc = IOUtils.initDocumentBuilder().parse( + Document doc = XmlUtils.initDocumentBuilder().parse( Files.newInputStream(TKit.SRC_ROOT.resolve( "windows/classes/jdk/jpackage/internal/resources/main.wxs"))); XPath xPath = XPathFactory.newInstance().newXPath(); diff --git a/test/jdk/tools/jpackage/windows/WinScriptTest.java b/test/jdk/tools/jpackage/windows/WinScriptTest.java index 296da482bb0..98b4922826d 100644 --- a/test/jdk/tools/jpackage/windows/WinScriptTest.java +++ b/test/jdk/tools/jpackage/windows/WinScriptTest.java @@ -24,8 +24,7 @@ import java.io.IOException; import java.nio.file.Path; import java.util.List; -import java.util.ArrayList; -import jdk.jpackage.internal.IOUtils; +import jdk.jpackage.internal.util.XmlUtils; import jdk.jpackage.test.TKit; import jdk.jpackage.test.PackageTest; import jdk.jpackage.test.PackageType; @@ -147,7 +146,7 @@ void assertJPackageOutput(List<String> output) { } void createScript(JPackageCommand cmd) throws IOException { - IOUtils.createXml(Path.of(cmd.getArgumentValue("--resource-dir"), + XmlUtils.createXml(Path.of(cmd.getArgumentValue("--resource-dir"), String.format("%s-%s.wsf", cmd.name(), scriptSuffixName)), xml -> { xml.writeStartElement("job"); xml.writeAttribute("id", "main"); From 1717946c1b6494a4a44622027ac1dd175fcb9563 Mon Sep 17 00:00:00 2001 From: Ivan Walulya <iwalulya@openjdk.org> Date: Tue, 19 Nov 2024 14:31:40 +0000 Subject: [PATCH 091/311] 8344302: G1: Refactor G1CMTask::do_marking_step to use smaller wrapper methods Reviewed-by: tschatzl, ayang --- src/hotspot/share/gc/g1/g1ConcurrentMark.cpp | 431 ++++++++++--------- src/hotspot/share/gc/g1/g1ConcurrentMark.hpp | 15 + 2 files changed, 237 insertions(+), 209 deletions(-) diff --git a/src/hotspot/share/gc/g1/g1ConcurrentMark.cpp b/src/hotspot/share/gc/g1/g1ConcurrentMark.cpp index 52d26418af6..d0879e9967c 100644 --- a/src/hotspot/share/gc/g1/g1ConcurrentMark.cpp +++ b/src/hotspot/share/gc/g1/g1ConcurrentMark.cpp @@ -2483,6 +2483,214 @@ bool G1ConcurrentMark::try_stealing(uint worker_id, G1TaskQueueEntry& task_entry return _task_queues->steal(worker_id, task_entry); } +void G1CMTask::process_current_region(G1CMBitMapClosure& bitmap_closure) { + if (has_aborted() || _curr_region == nullptr) { + return; + } + + // This means that we're already holding on to a region. + assert(_finger != nullptr, "if region is not null, then the finger " + "should not be null either"); + + // We might have restarted this task after an evacuation pause + // which might have evacuated the region we're holding on to + // underneath our feet. Let's read its limit again to make sure + // that we do not iterate over a region of the heap that + // contains garbage (update_region_limit() will also move + // _finger to the start of the region if it is found empty). + update_region_limit(); + // We will start from _finger not from the start of the region, + // as we might be restarting this task after aborting half-way + // through scanning this region. In this case, _finger points to + // the address where we last found a marked object. If this is a + // fresh region, _finger points to start(). + MemRegion mr = MemRegion(_finger, _region_limit); + + assert(!_curr_region->is_humongous() || mr.start() == _curr_region->bottom(), + "humongous regions should go around loop once only"); + + // Some special cases: + // If the memory region is empty, we can just give up the region. + // If the current region is humongous then we only need to check + // the bitmap for the bit associated with the start of the object, + // scan the object if it's live, and give up the region. + // Otherwise, let's iterate over the bitmap of the part of the region + // that is left. + // If the iteration is successful, give up the region. + if (mr.is_empty()) { + giveup_current_region(); + abort_marking_if_regular_check_fail(); + } else if (_curr_region->is_humongous() && mr.start() == _curr_region->bottom()) { + if (_mark_bitmap->is_marked(mr.start())) { + // The object is marked - apply the closure + bitmap_closure.do_addr(mr.start()); + } + // Even if this task aborted while scanning the humongous object + // we can (and should) give up the current region. + giveup_current_region(); + abort_marking_if_regular_check_fail(); + } else if (_mark_bitmap->iterate(&bitmap_closure, mr)) { + giveup_current_region(); + abort_marking_if_regular_check_fail(); + } else { + assert(has_aborted(), "currently the only way to do so"); + // The only way to abort the bitmap iteration is to return + // false from the do_bit() method. However, inside the + // do_bit() method we move the _finger to point to the + // object currently being looked at. So, if we bail out, we + // have definitely set _finger to something non-null. + assert(_finger != nullptr, "invariant"); + + // Region iteration was actually aborted. So now _finger + // points to the address of the object we last scanned. If we + // leave it there, when we restart this task, we will rescan + // the object. It is easy to avoid this. We move the finger by + // enough to point to the next possible object header. + assert(_finger < _region_limit, "invariant"); + HeapWord* const new_finger = _finger + cast_to_oop(_finger)->size(); + if (new_finger >= _region_limit) { + giveup_current_region(); + } else { + move_finger_to(new_finger); + } + } +} + +void G1CMTask::claim_new_region() { + // Read the note on the claim_region() method on why it might + // return null with potentially more regions available for + // claiming and why we have to check out_of_regions() to determine + // whether we're done or not. + while (!has_aborted() && _curr_region == nullptr && !_cm->out_of_regions()) { + // We are going to try to claim a new region. We should have + // given up on the previous one. + // Separated the asserts so that we know which one fires. + assert(_curr_region == nullptr, "invariant"); + assert(_finger == nullptr, "invariant"); + assert(_region_limit == nullptr, "invariant"); + G1HeapRegion* claimed_region = _cm->claim_region(_worker_id); + if (claimed_region != nullptr) { + // Yes, we managed to claim one + setup_for_region(claimed_region); + assert(_curr_region == claimed_region, "invariant"); + } + // It is important to call the regular clock here. It might take + // a while to claim a region if, for example, we hit a large + // block of empty regions. So we need to call the regular clock + // method once round the loop to make sure it's called + // frequently enough. + abort_marking_if_regular_check_fail(); + } +} + +void G1CMTask::attempt_stealing() { + // We cannot check whether the global stack is empty, since other + // tasks might be pushing objects to it concurrently. + assert(_cm->out_of_regions() && _task_queue->size() == 0, + "only way to reach here"); + while (!has_aborted()) { + G1TaskQueueEntry entry; + if (_cm->try_stealing(_worker_id, entry)) { + scan_task_entry(entry); + + // And since we're towards the end, let's totally drain the + // local queue and global stack. + drain_local_queue(false); + drain_global_stack(false); + } else { + break; + } + } +} + +void G1CMTask::attempt_termination(bool is_serial) { + // We cannot check whether the global stack is empty, since other + // tasks might be concurrently pushing objects on it. + // Separated the asserts so that we know which one fires. + assert(_cm->out_of_regions(), "only way to reach here"); + assert(_task_queue->size() == 0, "only way to reach here"); + double termination_start_time_ms = os::elapsedTime() * 1000.0; + + // The G1CMTask class also extends the TerminatorTerminator class, + // hence its should_exit_termination() method will also decide + // whether to exit the termination protocol or not. + bool finished = (is_serial || + _cm->terminator()->offer_termination(this)); + _termination_time_ms += (os::elapsedTime() * 1000.0 - termination_start_time_ms); + + if (finished) { + // We're all done. + + // We can now guarantee that the global stack is empty, since + // all other tasks have finished. We separated the guarantees so + // that, if a condition is false, we can immediately find out + // which one. + guarantee(_cm->out_of_regions(), "only way to reach here"); + guarantee(_cm->mark_stack_empty(), "only way to reach here"); + guarantee(_task_queue->size() == 0, "only way to reach here"); + guarantee(!_cm->has_overflown(), "only way to reach here"); + guarantee(!has_aborted(), "should never happen if termination has completed"); + } else { + // Apparently there's more work to do. Let's abort this task. We + // will restart it and hopefully we can find more things to do. + set_has_aborted(); + } +} + +void G1CMTask::handle_abort(bool is_serial, double elapsed_time_ms) { + if (_has_timed_out) { + double diff_ms = elapsed_time_ms - _time_target_ms; + // Keep statistics of how well we did with respect to hitting + // our target only if we actually timed out (if we aborted for + // other reasons, then the results might get skewed). + _marking_step_diff_ms.add(diff_ms); + } + + if (!_cm->has_overflown()) { + return; + } + + // This is the interesting one. We aborted because a global + // overflow was raised. This means we have to restart the + // marking phase and start iterating over regions. However, in + // order to do this we have to make sure that all tasks stop + // what they are doing and re-initialize in a safe manner. We + // will achieve this with the use of two barrier sync points. + if (!is_serial) { + // We only need to enter the sync barrier if being called + // from a parallel context + _cm->enter_first_sync_barrier(_worker_id); + + // When we exit this sync barrier we know that all tasks have + // stopped doing marking work. So, it's now safe to + // re-initialize our data structures. + } + + clear_region_fields(); + flush_mark_stats_cache(); + + if (!is_serial) { + // If we're executing the concurrent phase of marking, reset the marking + // state; otherwise the marking state is reset after reference processing, + // during the remark pause. + // If we reset here as a result of an overflow during the remark we will + // see assertion failures from any subsequent set_concurrency_and_phase() + // calls. + if (_cm->concurrent() && _worker_id == 0) { + // Worker 0 is responsible for clearing the global data structures because + // of an overflow. During STW we should not clear the overflow flag (in + // G1ConcurrentMark::reset_marking_state()) since we rely on it being true when we exit + // method to abort the pause and restart concurrent marking. + _cm->reset_marking_for_restart(); + + log_info(gc, marking)("Concurrent Mark reset for overflow"); + } + + // ...and enter the second barrier. + _cm->enter_second_sync_barrier(_worker_id); + } +} + /***************************************************************************** The do_marking_step(time_target_ms, ...) method is the building @@ -2653,123 +2861,27 @@ void G1CMTask::do_marking_step(double time_target_ms, drain_global_stack(true); do { - if (!has_aborted() && _curr_region != nullptr) { - // This means that we're already holding on to a region. - assert(_finger != nullptr, "if region is not null, then the finger " - "should not be null either"); - - // We might have restarted this task after an evacuation pause - // which might have evacuated the region we're holding on to - // underneath our feet. Let's read its limit again to make sure - // that we do not iterate over a region of the heap that - // contains garbage (update_region_limit() will also move - // _finger to the start of the region if it is found empty). - update_region_limit(); - // We will start from _finger not from the start of the region, - // as we might be restarting this task after aborting half-way - // through scanning this region. In this case, _finger points to - // the address where we last found a marked object. If this is a - // fresh region, _finger points to start(). - MemRegion mr = MemRegion(_finger, _region_limit); - - assert(!_curr_region->is_humongous() || mr.start() == _curr_region->bottom(), - "humongous regions should go around loop once only"); - - // Some special cases: - // If the memory region is empty, we can just give up the region. - // If the current region is humongous then we only need to check - // the bitmap for the bit associated with the start of the object, - // scan the object if it's live, and give up the region. - // Otherwise, let's iterate over the bitmap of the part of the region - // that is left. - // If the iteration is successful, give up the region. - if (mr.is_empty()) { - giveup_current_region(); - abort_marking_if_regular_check_fail(); - } else if (_curr_region->is_humongous() && mr.start() == _curr_region->bottom()) { - if (_mark_bitmap->is_marked(mr.start())) { - // The object is marked - apply the closure - bitmap_closure.do_addr(mr.start()); - } - // Even if this task aborted while scanning the humongous object - // we can (and should) give up the current region. - giveup_current_region(); - abort_marking_if_regular_check_fail(); - } else if (_mark_bitmap->iterate(&bitmap_closure, mr)) { - giveup_current_region(); - abort_marking_if_regular_check_fail(); - } else { - assert(has_aborted(), "currently the only way to do so"); - // The only way to abort the bitmap iteration is to return - // false from the do_bit() method. However, inside the - // do_bit() method we move the _finger to point to the - // object currently being looked at. So, if we bail out, we - // have definitely set _finger to something non-null. - assert(_finger != nullptr, "invariant"); - - // Region iteration was actually aborted. So now _finger - // points to the address of the object we last scanned. If we - // leave it there, when we restart this task, we will rescan - // the object. It is easy to avoid this. We move the finger by - // enough to point to the next possible object header. - assert(_finger < _region_limit, "invariant"); - HeapWord* const new_finger = _finger + cast_to_oop(_finger)->size(); - // Check if bitmap iteration was aborted while scanning the last object - if (new_finger >= _region_limit) { - giveup_current_region(); - } else { - move_finger_to(new_finger); - } - } - } + process_current_region(bitmap_closure); // At this point we have either completed iterating over the // region we were holding on to, or we have aborted. // We then partially drain the local queue and the global stack. - // (Do we really need this?) drain_local_queue(true); drain_global_stack(true); - // Read the note on the claim_region() method on why it might - // return null with potentially more regions available for - // claiming and why we have to check out_of_regions() to determine - // whether we're done or not. - while (!has_aborted() && _curr_region == nullptr && !_cm->out_of_regions()) { - // We are going to try to claim a new region. We should have - // given up on the previous one. - // Separated the asserts so that we know which one fires. - assert(_curr_region == nullptr, "invariant"); - assert(_finger == nullptr, "invariant"); - assert(_region_limit == nullptr, "invariant"); - G1HeapRegion* claimed_region = _cm->claim_region(_worker_id); - if (claimed_region != nullptr) { - // Yes, we managed to claim one - setup_for_region(claimed_region); - assert(_curr_region == claimed_region, "invariant"); - } - // It is important to call the regular clock here. It might take - // a while to claim a region if, for example, we hit a large - // block of empty regions. So we need to call the regular clock - // method once round the loop to make sure it's called - // frequently enough. - abort_marking_if_regular_check_fail(); - } + claim_new_region(); - if (!has_aborted() && _curr_region == nullptr) { - assert(_cm->out_of_regions(), - "at this point we should be out of regions"); - } + assert(has_aborted() || _curr_region != nullptr || _cm->out_of_regions(), + "at this point we should be out of regions"); } while ( _curr_region != nullptr && !has_aborted()); - if (!has_aborted()) { - // We cannot check whether the global stack is empty, since other - // tasks might be pushing objects to it concurrently. - assert(_cm->out_of_regions(), - "at this point we should be out of regions"); - // Try to reduce the number of available SATB buffers so that - // remark has less work to do. - drain_satb_buffers(); - } + // We cannot check whether the global stack is empty, since other + // tasks might be pushing objects to it concurrently. + assert(has_aborted() || _cm->out_of_regions(), + "at this point we should be out of regions"); + // Try to reduce the number of available SATB buffers so that + // remark has less work to do. + drain_satb_buffers(); // Since we've done everything else, we can now totally drain the // local queue and global stack. @@ -2780,60 +2892,13 @@ void G1CMTask::do_marking_step(double time_target_ms, if (do_stealing && !has_aborted()) { // We have not aborted. This means that we have finished all that // we could. Let's try to do some stealing... - - // We cannot check whether the global stack is empty, since other - // tasks might be pushing objects to it concurrently. - assert(_cm->out_of_regions() && _task_queue->size() == 0, - "only way to reach here"); - while (!has_aborted()) { - G1TaskQueueEntry entry; - if (_cm->try_stealing(_worker_id, entry)) { - scan_task_entry(entry); - - // And since we're towards the end, let's totally drain the - // local queue and global stack. - drain_local_queue(false); - drain_global_stack(false); - } else { - break; - } - } + attempt_stealing(); } // We still haven't aborted. Now, let's try to get into the // termination protocol. if (do_termination && !has_aborted()) { - // We cannot check whether the global stack is empty, since other - // tasks might be concurrently pushing objects on it. - // Separated the asserts so that we know which one fires. - assert(_cm->out_of_regions(), "only way to reach here"); - assert(_task_queue->size() == 0, "only way to reach here"); - double termination_start_time_ms = os::elapsedTime() * 1000.0; - - // The G1CMTask class also extends the TerminatorTerminator class, - // hence its should_exit_termination() method will also decide - // whether to exit the termination protocol or not. - bool finished = (is_serial || - _cm->terminator()->offer_termination(this)); - _termination_time_ms += (os::elapsedTime() * 1000.0 - termination_start_time_ms); - - if (finished) { - // We're all done. - - // We can now guarantee that the global stack is empty, since - // all other tasks have finished. We separated the guarantees so - // that, if a condition is false, we can immediately find out - // which one. - guarantee(_cm->out_of_regions(), "only way to reach here"); - guarantee(_cm->mark_stack_empty(), "only way to reach here"); - guarantee(_task_queue->size() == 0, "only way to reach here"); - guarantee(!_cm->has_overflown(), "only way to reach here"); - guarantee(!has_aborted(), "should never happen if termination has completed"); - } else { - // Apparently there's more work to do. Let's abort this task. It - // will restart it and we can hopefully find more things to do. - set_has_aborted(); - } + attempt_termination(is_serial); } // Mainly for debugging purposes to make sure that a pointer to the @@ -2847,59 +2912,7 @@ void G1CMTask::do_marking_step(double time_target_ms, if (has_aborted()) { // The task was aborted for some reason. - if (_has_timed_out) { - double diff_ms = elapsed_time_ms - _time_target_ms; - // Keep statistics of how well we did with respect to hitting - // our target only if we actually timed out (if we aborted for - // other reasons, then the results might get skewed). - _marking_step_diff_ms.add(diff_ms); - } - - if (_cm->has_overflown()) { - // This is the interesting one. We aborted because a global - // overflow was raised. This means we have to restart the - // marking phase and start iterating over regions. However, in - // order to do this we have to make sure that all tasks stop - // what they are doing and re-initialize in a safe manner. We - // will achieve this with the use of two barrier sync points. - - if (!is_serial) { - // We only need to enter the sync barrier if being called - // from a parallel context - _cm->enter_first_sync_barrier(_worker_id); - - // When we exit this sync barrier we know that all tasks have - // stopped doing marking work. So, it's now safe to - // re-initialize our data structures. - } - - clear_region_fields(); - flush_mark_stats_cache(); - - if (!is_serial) { - // If we're executing the concurrent phase of marking, reset the marking - // state; otherwise the marking state is reset after reference processing, - // during the remark pause. - // If we reset here as a result of an overflow during the remark we will - // see assertion failures from any subsequent set_concurrency_and_phase() - // calls. - if (_cm->concurrent() && _worker_id == 0) { - // Worker 0 is responsible for clearing the global data structures because - // of an overflow. During STW we should not clear the overflow flag (in - // G1ConcurrentMark::reset_marking_state()) since we rely on it being true when we exit - // method to abort the pause and restart concurrent marking. - _cm->reset_marking_for_restart(); - - log_info(gc, marking)("Concurrent Mark reset for overflow"); - } - - // ...and enter the second barrier. - _cm->enter_second_sync_barrier(_worker_id); - } - // At this point, if we're during the concurrent phase of - // marking, everything has been re-initialized and we're - // ready to restart. - } + handle_abort(is_serial, elapsed_time_ms); } } diff --git a/src/hotspot/share/gc/g1/g1ConcurrentMark.hpp b/src/hotspot/share/gc/g1/g1ConcurrentMark.hpp index b197afc65ee..fed624df851 100644 --- a/src/hotspot/share/gc/g1/g1ConcurrentMark.hpp +++ b/src/hotspot/share/gc/g1/g1ConcurrentMark.hpp @@ -810,6 +810,21 @@ class G1CMTask : public TerminatorTerminator { // Makes the limit of the region up-to-date void update_region_limit(); + // Handles the processing of the current region. + void process_current_region(G1CMBitMapClosure& bitmap_closure); + + // Claims a new region if available. + void claim_new_region(); + + // Attempts to steal work from other tasks. + void attempt_stealing(); + + // Handles the termination protocol. + void attempt_termination(bool is_serial); + + // Handles the has_aborted scenario. + void handle_abort(bool is_serial, double elapsed_time_ms); + // Called when either the words scanned or the refs visited limit // has been reached void reached_limit(); From 59fcfae63090f6659a94a9e3dd0705739ec1b074 Mon Sep 17 00:00:00 2001 From: SendaoYan <syan@openjdk.org> Date: Tue, 19 Nov 2024 15:17:34 +0000 Subject: [PATCH 092/311] 8343129: Disable unstable check of ThreadsListHandle.sanity_vm ThreadList values Reviewed-by: dholmes --- .../gtest/runtime/test_ThreadsListHandle.cpp | 30 ++++++++++++------- 1 file changed, 20 insertions(+), 10 deletions(-) diff --git a/test/hotspot/gtest/runtime/test_ThreadsListHandle.cpp b/test/hotspot/gtest/runtime/test_ThreadsListHandle.cpp index 5caa19fae95..81d36670c9a 100644 --- a/test/hotspot/gtest/runtime/test_ThreadsListHandle.cpp +++ b/test/hotspot/gtest/runtime/test_ThreadsListHandle.cpp @@ -171,8 +171,10 @@ TEST_VM(ThreadsListHandle, sanity) { // Verify the current thread refers to tlh2: EXPECT_EQ(ThreadsListHandleTest::get_Thread_threads_hazard_ptr(thr), tlh2.list()) << "thr->_threads_hazard_ptr must match tlh2.list()"; - EXPECT_EQ(tlh1.list(), tlh2.list()) - << "tlh1.list() must match tlh2.list()"; + // Disable unstable check of ThreadsListHandle.sanity_vm ThreadList values, + // until the root cause of test failure(JDK-8315141) has been fixed + // EXPECT_EQ(tlh1.list(), tlh2.list()) + // << "tlh1.list() must match tlh2.list()"; EXPECT_EQ(ThreadsListHandleTest::get_Thread_threads_list_ptr(thr), list_ptr2) << "thr->_threads_list_ptr must match list_ptr2"; EXPECT_NE(list_ptr1, list_ptr2) @@ -291,8 +293,10 @@ TEST_VM(ThreadsListHandle, sanity) { // Verify the current thread refers to tlh2: EXPECT_EQ(ThreadsListHandleTest::get_Thread_threads_hazard_ptr(thr), tlh2.list()) << "thr->_threads_hazard_ptr must match tlh2.list()"; - EXPECT_EQ(tlh1.list(), tlh2.list()) - << "tlh1.list() must match tlh2.list()"; + // Disable unstable check of ThreadsListHandle.sanity_vm ThreadList values, + // until the root cause of test failure(JDK-8315141) has been fixed + // EXPECT_EQ(tlh1.list(), tlh2.list()) + // << "tlh1.list() must match tlh2.list()"; EXPECT_EQ(ThreadsListHandleTest::get_Thread_threads_list_ptr(thr), list_ptr2) << "thr->_threads_list_ptr must match list_ptr2"; EXPECT_NE(list_ptr1, list_ptr2) @@ -339,8 +343,10 @@ TEST_VM(ThreadsListHandle, sanity) { // Verify the current thread refers to tlh3: EXPECT_EQ(ThreadsListHandleTest::get_Thread_threads_hazard_ptr(thr), tlh3.list()) << "thr->_threads_hazard_ptr must match tlh3.list()"; - EXPECT_EQ(tlh1.list(), tlh3.list()) - << "tlh1.list() must match tlh3.list()"; + // Disable unstable check of ThreadsListHandle.sanity_vm ThreadList values, + // until the root cause of test failure(JDK-8315141) has been fixed + // EXPECT_EQ(tlh1.list(), tlh3.list()) + // << "tlh1.list() must match tlh3.list()"; EXPECT_EQ(ThreadsListHandleTest::get_Thread_threads_list_ptr(thr), list_ptr3) << "thr->_threads_list_ptr must match list_ptr3"; EXPECT_NE(list_ptr1, list_ptr3) @@ -523,8 +529,10 @@ TEST_VM(ThreadsListHandle, sanity) { // Verify the current thread refers to tlh2a: EXPECT_EQ(ThreadsListHandleTest::get_Thread_threads_hazard_ptr(thr), tlh2a.list()) << "thr->_threads_hazard_ptr must match tlh2a.list()"; - EXPECT_EQ(tlh1.list(), tlh2a.list()) - << "tlh1.list() must match tlh2a.list()"; + // Disable unstable check of ThreadsListHandle.sanity_vm ThreadList values, + // until the root cause of test failure(JDK-8315141) has been fixed + // EXPECT_EQ(tlh1.list(), tlh2a.list()) + // << "tlh1.list() must match tlh2a.list()"; EXPECT_EQ(ThreadsListHandleTest::get_Thread_threads_list_ptr(thr), list_ptr2a) << "thr->_threads_list_ptr must match list_ptr2a"; EXPECT_NE(list_ptr1, list_ptr2a) @@ -601,8 +609,10 @@ TEST_VM(ThreadsListHandle, sanity) { // Verify the current thread refers to tlh2b: EXPECT_EQ(ThreadsListHandleTest::get_Thread_threads_hazard_ptr(thr), tlh2b.list()) << "thr->_threads_hazard_ptr must match tlh2b.list()"; - EXPECT_EQ(tlh1.list(), tlh2b.list()) - << "tlh1.list() must match tlh2b.list()"; + // Disable unstable check of ThreadsListHandle.sanity_vm ThreadList values, + // until the root cause of test failure(JDK-8315141) has been fixed + // EXPECT_EQ(tlh1.list(), tlh2b.list()) + // << "tlh1.list() must match tlh2b.list()"; EXPECT_EQ(ThreadsListHandleTest::get_Thread_threads_list_ptr(thr), list_ptr2b) << "thr->_threads_list_ptr must match list_ptr2b"; EXPECT_NE(list_ptr1, list_ptr2b) From ded01e4316a46d4c4a74d494db61d03f8591fd67 Mon Sep 17 00:00:00 2001 From: Roger Riggs <rriggs@openjdk.org> Date: Tue, 19 Nov 2024 15:21:02 +0000 Subject: [PATCH 093/311] 8344327: SM cleanup in jdk.unsupported ReflectionFactory Reviewed-by: liach, mullan, alanb --- .../sun/reflect/ReflectionFactory.java | 34 ++----------------- 1 file changed, 3 insertions(+), 31 deletions(-) diff --git a/src/jdk.unsupported/share/classes/sun/reflect/ReflectionFactory.java b/src/jdk.unsupported/share/classes/sun/reflect/ReflectionFactory.java index f6f9b3976fc..b6c538c507f 100644 --- a/src/jdk.unsupported/share/classes/sun/reflect/ReflectionFactory.java +++ b/src/jdk.unsupported/share/classes/sun/reflect/ReflectionFactory.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -29,60 +29,32 @@ import java.lang.invoke.MethodHandle; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; -import java.security.AccessController; -import java.security.Permission; -import java.security.PrivilegedAction; /** * ReflectionFactory supports custom serialization. * Its methods support the creation of uninitialized objects, invoking serialization * private methods for readObject, writeObject, readResolve, and writeReplace. - * <p> - * ReflectionFactory access is restricted, if a security manager is active, - * unless the permission {@code RuntimePermission("reflectionFactoryAccess")} - * is granted. */ public class ReflectionFactory { private static final ReflectionFactory soleInstance = new ReflectionFactory(); - @SuppressWarnings("removal") - private static final jdk.internal.reflect.ReflectionFactory delegate = AccessController.doPrivileged( - new PrivilegedAction<jdk.internal.reflect.ReflectionFactory>() { - public jdk.internal.reflect.ReflectionFactory run() { - return jdk.internal.reflect.ReflectionFactory.getReflectionFactory(); - } - }); + private static final jdk.internal.reflect.ReflectionFactory delegate = + jdk.internal.reflect.ReflectionFactory.getReflectionFactory(); private ReflectionFactory() {} - private static final Permission REFLECTION_FACTORY_ACCESS_PERM - = new RuntimePermission("reflectionFactoryAccess"); - /** * Provides the caller with the capability to instantiate reflective * objects. * - * <p> First, if there is a security manager, its {@code checkPermission} - * method is called with a {@link java.lang.RuntimePermission} with target - * {@code "reflectionFactoryAccess"}. This may result in a security - * exception. - * * <p> The returned {@code ReflectionFactory} object should be carefully * guarded by the caller, since it can be used to read and write private * data and invoke private methods, as well as to load unverified bytecodes. * It must never be passed to untrusted code. * * @return the ReflectionFactory - * @throws SecurityException if a security manager exists and its - * {@code checkPermission} method doesn't allow access to - * the RuntimePermission "reflectionFactoryAccess". */ public static ReflectionFactory getReflectionFactory() { - @SuppressWarnings("removal") - SecurityManager security = System.getSecurityManager(); - if (security != null) { - security.checkPermission(REFLECTION_FACTORY_ACCESS_PERM); - } return soleInstance; } From dc940ec8afcd3cd12ed3785d547f4cd602f65c15 Mon Sep 17 00:00:00 2001 From: Hamlin Li <mli@openjdk.org> Date: Tue, 19 Nov 2024 15:59:30 +0000 Subject: [PATCH 094/311] 8344387: RISC-V: C2: Improve encoding of LoadNKlass for compact headers Reviewed-by: fyang, luhenry --- src/hotspot/cpu/riscv/c2_MacroAssembler_riscv.cpp | 10 ---------- src/hotspot/cpu/riscv/c2_MacroAssembler_riscv.hpp | 2 -- src/hotspot/cpu/riscv/riscv.ad | 8 ++++++-- 3 files changed, 6 insertions(+), 14 deletions(-) diff --git a/src/hotspot/cpu/riscv/c2_MacroAssembler_riscv.cpp b/src/hotspot/cpu/riscv/c2_MacroAssembler_riscv.cpp index 7b0316e208f..bf553b35770 100644 --- a/src/hotspot/cpu/riscv/c2_MacroAssembler_riscv.cpp +++ b/src/hotspot/cpu/riscv/c2_MacroAssembler_riscv.cpp @@ -3124,13 +3124,3 @@ void C2_MacroAssembler::extract_fp_v(FloatRegister dst, VectorRegister src, Basi vfmv_f_s(dst, tmp); } } - -void C2_MacroAssembler::load_narrow_klass_compact_c2(Register dst, Address src) { - // The incoming address is pointing into obj-start + klass_offset_in_bytes. We need to extract - // obj-start, so that we can load from the object's mark-word instead. Usually the address - // comes as obj-start in obj and klass_offset_in_bytes in disp. - assert(UseCompactObjectHeaders, "must"); - int offset = oopDesc::mark_offset_in_bytes() - oopDesc::klass_offset_in_bytes(); - ld(dst, Address(src.base(), src.offset() + offset)); - srli(dst, dst, markWord::klass_shift); -} diff --git a/src/hotspot/cpu/riscv/c2_MacroAssembler_riscv.hpp b/src/hotspot/cpu/riscv/c2_MacroAssembler_riscv.hpp index 8f9d9cd2ccd..8736294e72c 100644 --- a/src/hotspot/cpu/riscv/c2_MacroAssembler_riscv.hpp +++ b/src/hotspot/cpu/riscv/c2_MacroAssembler_riscv.hpp @@ -281,6 +281,4 @@ void extract_v(Register dst, VectorRegister src, BasicType bt, int idx, VectorRegister tmp); void extract_fp_v(FloatRegister dst, VectorRegister src, BasicType bt, int idx, VectorRegister tmp); - void load_narrow_klass_compact_c2(Register dst, Address src); - #endif // CPU_RISCV_C2_MACROASSEMBLER_RISCV_HPP diff --git a/src/hotspot/cpu/riscv/riscv.ad b/src/hotspot/cpu/riscv/riscv.ad index b944cc5b4b9..ae8565e1bcf 100644 --- a/src/hotspot/cpu/riscv/riscv.ad +++ b/src/hotspot/cpu/riscv/riscv.ad @@ -4814,10 +4814,14 @@ instruct loadNKlassCompactHeaders(iRegNNoSp dst, memory mem) match(Set dst (LoadNKlass mem)); ins_cost(LOAD_COST); - format %{ "load_narrow_klass_compact $dst, $mem\t# compressed class ptr, #@loadNKlassCompactHeaders" %} + format %{ + "lwu $dst, $mem\t# compressed klass ptr, shifted\n\t" + "srli $dst, $dst, markWord::klass_shift_at_offset" + %} ins_encode %{ - __ load_narrow_klass_compact_c2(as_Register($dst$$reg), Address(as_Register($mem$$base), $mem$$disp)); + __ lwu(as_Register($dst$$reg), Address(as_Register($mem$$base), $mem$$disp)); + __ srli(as_Register($dst$$reg), as_Register($dst$$reg), (unsigned) markWord::klass_shift_at_offset); %} ins_pipe(iload_reg_mem); From d4cd27e875ba7d44b0c614d48888340990b94169 Mon Sep 17 00:00:00 2001 From: Coleen Phillimore <coleenp@openjdk.org> Date: Tue, 19 Nov 2024 16:13:11 +0000 Subject: [PATCH 095/311] 8344445: MethodCounters don't need a vptr Reviewed-by: kbarrett, dlong --- src/hotspot/share/oops/metadata.hpp | 5 ++--- src/hotspot/share/oops/methodCounters.cpp | 5 ++--- src/hotspot/share/oops/methodCounters.hpp | 18 ++++++++---------- 3 files changed, 12 insertions(+), 16 deletions(-) diff --git a/src/hotspot/share/oops/metadata.hpp b/src/hotspot/share/oops/metadata.hpp index f5aee34c80d..ff18cef60a7 100644 --- a/src/hotspot/share/oops/metadata.hpp +++ b/src/hotspot/share/oops/metadata.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -44,11 +44,10 @@ class Metadata : public MetaspaceObj { virtual bool is_method() const { return false; } virtual bool is_methodData() const { return false; } virtual bool is_constantPool() const { return false; } - virtual bool is_methodCounters() const { return false; } virtual int size() const = 0; virtual MetaspaceObj::Type type() const = 0; virtual const char* internal_name() const = 0; - virtual void metaspace_pointers_do(MetaspaceClosure* iter) {} + virtual void metaspace_pointers_do(MetaspaceClosure* iter) = 0; void print() const; void print_value() const; diff --git a/src/hotspot/share/oops/methodCounters.cpp b/src/hotspot/share/oops/methodCounters.cpp index 00096c5012c..93fd7e65c6b 100644 --- a/src/hotspot/share/oops/methodCounters.cpp +++ b/src/hotspot/share/oops/methodCounters.cpp @@ -50,12 +50,12 @@ MethodCounters::MethodCounters(const methodHandle& mh) : MethodCounters* MethodCounters::allocate_no_exception(const methodHandle& mh) { ClassLoaderData* loader_data = mh->method_holder()->class_loader_data(); - return new(loader_data, method_counters_size(), MetaspaceObj::MethodCountersType) MethodCounters(mh); + return new(loader_data, size(), MetaspaceObj::MethodCountersType) MethodCounters(mh); } MethodCounters* MethodCounters::allocate_with_exception(const methodHandle& mh, TRAPS) { ClassLoaderData* loader_data = mh->method_holder()->class_loader_data(); - return new(loader_data, method_counters_size(), MetaspaceObj::MethodCountersType, THREAD) MethodCounters(mh); + return new(loader_data, size(), MetaspaceObj::MethodCountersType, THREAD) MethodCounters(mh); } void MethodCounters::clear_counters() { @@ -70,7 +70,6 @@ void MethodCounters::clear_counters() { } void MethodCounters::print_value_on(outputStream* st) const { - assert(is_methodCounters(), "must be methodCounters"); st->print("method counters"); print_address_on(st); } diff --git a/src/hotspot/share/oops/methodCounters.hpp b/src/hotspot/share/oops/methodCounters.hpp index 80cfb159b50..bdf033a46a8 100644 --- a/src/hotspot/share/oops/methodCounters.hpp +++ b/src/hotspot/share/oops/methodCounters.hpp @@ -30,7 +30,7 @@ #include "interpreter/invocationCounter.hpp" #include "utilities/align.hpp" -class MethodCounters : public Metadata { +class MethodCounters : public MetaspaceObj { friend class VMStructs; friend class JVMCIVMStructs; private: @@ -52,19 +52,18 @@ class MethodCounters : public Metadata { MethodCounters(const methodHandle& mh); public: - virtual bool is_methodCounters() const { return true; } - static MethodCounters* allocate_no_exception(const methodHandle& mh); static MethodCounters* allocate_with_exception(const methodHandle& mh, TRAPS); + DEBUG_ONLY(bool on_stack() { return false; }) void deallocate_contents(ClassLoaderData* loader_data) {} - static int method_counters_size() { + void metaspace_pointers_do(MetaspaceClosure* it) { return; } + + static int size() { return align_up((int)sizeof(MethodCounters), wordSize) / wordSize; } - virtual int size() const { - return method_counters_size(); - } + MetaspaceObj::Type type() const { return MethodCountersType; } void clear_counters(); @@ -128,8 +127,7 @@ class MethodCounters : public Metadata { return byte_offset_of(MethodCounters, _backedge_mask); } - virtual const char* internal_name() const { return "{method counters}"; } - virtual void print_value_on(outputStream* st) const; - + const char* internal_name() const { return "{method counters}"; } + void print_value_on(outputStream* st) const; }; #endif // SHARE_OOPS_METHODCOUNTERS_HPP From 48223f7b9c6fbaf4e6751a5b41ea9e9046a48f91 Mon Sep 17 00:00:00 2001 From: Alan Bateman <alanb@openjdk.org> Date: Tue, 19 Nov 2024 16:37:43 +0000 Subject: [PATCH 096/311] 8344143: Test jdk/java/lang/Thread/virtual/stress/GetStackTraceALotWhenPinned.java timed out on macosx-x64 Reviewed-by: pchilanomate --- .../stress/GetStackTraceALotWhenBlocking.java | 18 +++++++++++++----- .../stress/GetStackTraceALotWhenPinned.java | 17 +++++++++++------ 2 files changed, 24 insertions(+), 11 deletions(-) diff --git a/test/jdk/java/lang/Thread/virtual/stress/GetStackTraceALotWhenBlocking.java b/test/jdk/java/lang/Thread/virtual/stress/GetStackTraceALotWhenBlocking.java index 5e15ea083e4..b68496bc7db 100644 --- a/test/jdk/java/lang/Thread/virtual/stress/GetStackTraceALotWhenBlocking.java +++ b/test/jdk/java/lang/Thread/virtual/stress/GetStackTraceALotWhenBlocking.java @@ -28,7 +28,7 @@ * @requires vm.debug != true * @modules jdk.management * @library /test/lib - * @run main/othervm GetStackTraceALotWhenBlocking 500000 + * @run main/othervm/timeout=300 GetStackTraceALotWhenBlocking 100000 */ /* @@ -68,16 +68,24 @@ public static void main(String[] args) throws Exception { var thread1 = Thread.ofVirtual().start(task); var thread2 = Thread.ofVirtual().start(task); + long lastTime = System.nanoTime(); try { for (int i = 1; i <= iterations; i++) { - if ((i % 10_000) == 0) { - System.out.format("%s => %d of %d%n", Instant.now(), i, iterations); - } - thread1.getStackTrace(); pause(); thread2.getStackTrace(); pause(); + + long currentTime = System.nanoTime(); + if (i == iterations || ((currentTime - lastTime) > 1_000_000_000L)) { + System.out.format("%s => %d of %d%n", Instant.now(), i, iterations); + lastTime = currentTime; + } + + if (Thread.currentThread().isInterrupted()) { + // fail quickly if interrupted by jtreg + throw new RuntimeException("interrupted"); + } } } finally { done.set(true); diff --git a/test/jdk/java/lang/Thread/virtual/stress/GetStackTraceALotWhenPinned.java b/test/jdk/java/lang/Thread/virtual/stress/GetStackTraceALotWhenPinned.java index 260446a1e3d..9d9d3eddce1 100644 --- a/test/jdk/java/lang/Thread/virtual/stress/GetStackTraceALotWhenPinned.java +++ b/test/jdk/java/lang/Thread/virtual/stress/GetStackTraceALotWhenPinned.java @@ -28,7 +28,7 @@ * @requires vm.debug != true * @modules jdk.management * @library /test/lib - * @run main/othervm --enable-native-access=ALL-UNNAMED GetStackTraceALotWhenPinned 500000 + * @run main/othervm/timeout=300 --enable-native-access=ALL-UNNAMED GetStackTraceALotWhenPinned 100000 */ /* @@ -36,7 +36,7 @@ * @requires vm.debug == true * @modules jdk.management * @library /test/lib - * @run main/othervm/timeout=300 --enable-native-access=ALL-UNNAMED GetStackTraceALotWhenPinned 200000 + * @run main/othervm/timeout=300 --enable-native-access=ALL-UNNAMED GetStackTraceALotWhenPinned 50000 */ import java.time.Instant; @@ -78,7 +78,7 @@ public static void main(String[] args) throws Exception { } }); - long lastTimestamp = System.currentTimeMillis(); + long lastTime = System.nanoTime(); for (int i = 1; i <= iterations; i++) { // wait for virtual thread to arrive barrier.await(); @@ -86,10 +86,15 @@ public static void main(String[] args) throws Exception { thread.getStackTrace(); LockSupport.unpark(thread); - long currentTime = System.currentTimeMillis(); - if (i == iterations || ((currentTime - lastTimestamp) > 500)) { + long currentTime = System.nanoTime(); + if (i == iterations || ((currentTime - lastTime) > 1_000_000_000L)) { System.out.format("%s => %d of %d%n", Instant.now(), i, iterations); - lastTimestamp = currentTime; + lastTime = currentTime; + } + + if (Thread.currentThread().isInterrupted()) { + // fail quickly if interrupted by jtreg + throw new RuntimeException("interrupted"); } } } From 7f672eb266b76a9310dcf108f72adf2469e63dee Mon Sep 17 00:00:00 2001 From: Alexey Semenyuk <asemenyuk@openjdk.org> Date: Tue, 19 Nov 2024 16:56:11 +0000 Subject: [PATCH 097/311] 8344550: Compilation error of jpackage test JPackageStringBundle.java source Reviewed-by: rriggs --- .../helpers/jdk/jpackage/test/JPackageStringBundle.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/JPackageStringBundle.java b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/JPackageStringBundle.java index 565822d4504..4757f54fdfd 100644 --- a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/JPackageStringBundle.java +++ b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/JPackageStringBundle.java @@ -26,6 +26,7 @@ import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.text.MessageFormat; +import static jdk.jpackage.internal.util.function.ExceptionBox.rethrowUnchecked; public enum JPackageStringBundle { @@ -39,7 +40,7 @@ public enum JPackageStringBundle { i18nClass_getString = i18nClass.getDeclaredMethod("getString", String.class); i18nClass_getString.setAccessible(true); } catch (ClassNotFoundException|NoSuchMethodException ex) { - throw Functional.rethrowUnchecked(ex); + throw rethrowUnchecked(ex); } } @@ -50,7 +51,7 @@ private String getString(String key) { try { return (String)i18nClass_getString.invoke(i18nClass, key); } catch (IllegalAccessException|InvocationTargetException ex) { - throw Functional.rethrowUnchecked(ex); + throw rethrowUnchecked(ex); } } From 78602be1fe6803503d4382cc9797ec70ee49eba6 Mon Sep 17 00:00:00 2001 From: Andrey Turbanov <aturbanov@openjdk.org> Date: Tue, 19 Nov 2024 16:59:06 +0000 Subject: [PATCH 098/311] 8344024: Unnecessary Hashtable usage in RSAPSSSignature.DIGEST_LENGTHS Reviewed-by: valeriep --- .../sun/security/rsa/RSAPSSSignature.java | 32 +++++++++---------- 1 file changed, 15 insertions(+), 17 deletions(-) diff --git a/src/java.base/share/classes/sun/security/rsa/RSAPSSSignature.java b/src/java.base/share/classes/sun/security/rsa/RSAPSSSignature.java index f15b058014a..6ccb3823e0a 100644 --- a/src/java.base/share/classes/sun/security/rsa/RSAPSSSignature.java +++ b/src/java.base/share/classes/sun/security/rsa/RSAPSSSignature.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -35,7 +35,7 @@ import java.security.interfaces.*; import java.util.Arrays; -import java.util.Hashtable; +import java.util.Map; import sun.security.util.*; import sun.security.jca.JCAUtil; @@ -81,21 +81,19 @@ private boolean isDigestEqual(String stdAlg, String givenAlg) { private static final byte[] EIGHT_BYTES_OF_ZEROS = new byte[8]; - private static final Hashtable<KnownOIDs, Integer> DIGEST_LENGTHS = - new Hashtable<>(); - static { - DIGEST_LENGTHS.put(KnownOIDs.SHA_1, 20); - DIGEST_LENGTHS.put(KnownOIDs.SHA_224, 28); - DIGEST_LENGTHS.put(KnownOIDs.SHA_256, 32); - DIGEST_LENGTHS.put(KnownOIDs.SHA_384, 48); - DIGEST_LENGTHS.put(KnownOIDs.SHA_512, 64); - DIGEST_LENGTHS.put(KnownOIDs.SHA_512$224, 28); - DIGEST_LENGTHS.put(KnownOIDs.SHA_512$256, 32); - DIGEST_LENGTHS.put(KnownOIDs.SHA3_224, 28); - DIGEST_LENGTHS.put(KnownOIDs.SHA3_256, 32); - DIGEST_LENGTHS.put(KnownOIDs.SHA3_384, 48); - DIGEST_LENGTHS.put(KnownOIDs.SHA3_512, 64); - } + private static final Map<KnownOIDs, Integer> DIGEST_LENGTHS = Map.ofEntries( + Map.entry(KnownOIDs.SHA_1, 20), + Map.entry(KnownOIDs.SHA_224, 28), + Map.entry(KnownOIDs.SHA_256, 32), + Map.entry(KnownOIDs.SHA_384, 48), + Map.entry(KnownOIDs.SHA_512, 64), + Map.entry(KnownOIDs.SHA_512$224, 28), + Map.entry(KnownOIDs.SHA_512$256, 32), + Map.entry(KnownOIDs.SHA3_224, 28), + Map.entry(KnownOIDs.SHA3_256, 32), + Map.entry(KnownOIDs.SHA3_384, 48), + Map.entry(KnownOIDs.SHA3_512, 64) + ); // message digest implementation we use for hashing the data private MessageDigest md; From 47ebf8d868b2e15b943a227ad3cf2ee12eed10f6 Mon Sep 17 00:00:00 2001 From: "naveen.n.narayanan" <“naveen.n.narayanan@oracle.com”> Date: Tue, 19 Nov 2024 17:15:24 +0000 Subject: [PATCH 099/311] 8342098: Write a test to compare the images Reviewed-by: aivanov, abhiscxk --- .../awt/Robot/ScreenCaptureRobotTest.java | 166 ++++++++++++++++++ 1 file changed, 166 insertions(+) create mode 100644 test/jdk/java/awt/Robot/ScreenCaptureRobotTest.java diff --git a/test/jdk/java/awt/Robot/ScreenCaptureRobotTest.java b/test/jdk/java/awt/Robot/ScreenCaptureRobotTest.java new file mode 100644 index 00000000000..944636ebf2a --- /dev/null +++ b/test/jdk/java/awt/Robot/ScreenCaptureRobotTest.java @@ -0,0 +1,166 @@ +/* + * Copyright (c) 2000, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.awt.BorderLayout; +import java.awt.Canvas; +import java.awt.Color; +import java.awt.Dimension; +import java.awt.EventQueue; +import java.awt.Font; +import java.awt.Frame; +import java.awt.Graphics; +import java.awt.GraphicsEnvironment; +import java.awt.Point; +import java.awt.Rectangle; +import java.awt.Robot; +import java.awt.image.BufferedImage; +import java.io.File; +import java.io.IOException; +import javax.imageio.ImageIO; + +/* + * @test + * @key headful + * @bug 8342098 + * @summary Verify that the image captured from the screen using a Robot + * and the source image are same. + * @run main/othervm -Dsun.java2d.uiScale=1 ScreenCaptureRobotTest + */ +public class ScreenCaptureRobotTest { + + private static final int IMAGE_WIDTH = 200; + private static final int IMAGE_HEIGHT = 100; + private static final int OFFSET = 10; + + private static Frame frame; + private static Canvas canvas; + + private static BufferedImage realImage; + + private static volatile Point point; + + public static void main(String[] args) throws Exception { + try { + EventQueue.invokeAndWait(ScreenCaptureRobotTest::initializeGUI); + doTest(); + } finally { + EventQueue.invokeAndWait(ScreenCaptureRobotTest::disposeFrame); + } + } + + private static void initializeGUI() { + frame = new Frame("ScreenCaptureRobotTest Frame"); + realImage = GraphicsEnvironment.getLocalGraphicsEnvironment() + .getDefaultScreenDevice() + .getDefaultConfiguration() + .createCompatibleImage(IMAGE_WIDTH, IMAGE_HEIGHT); + + Graphics g = realImage.createGraphics(); + g.setColor(Color.YELLOW); + g.fillRect(0, 0, IMAGE_WIDTH, IMAGE_HEIGHT); + g.setColor(Color.RED); + g.setFont(new Font(Font.SANS_SERIF, Font.BOLD, 20)); + g.drawString("Capture This", 10, 40); + g.dispose(); + + canvas = new ImageCanvas(); + canvas.setBackground(Color.YELLOW); + canvas.setPreferredSize(new Dimension(IMAGE_WIDTH + (OFFSET * 2), + IMAGE_HEIGHT + (OFFSET * 2))); + frame.setLayout(new BorderLayout()); + frame.add(canvas); + frame.pack(); + frame.setLocationRelativeTo(null); + frame.setVisible(true); + } + + private static void doTest() throws Exception { + Robot robot = new Robot(); + robot.waitForIdle(); + robot.delay(500); + + EventQueue.invokeAndWait(() -> point = canvas.getLocationOnScreen()); + + Rectangle rect = new Rectangle(point.x + OFFSET, point.y + OFFSET, + IMAGE_WIDTH, IMAGE_HEIGHT); + + BufferedImage capturedImage = robot.createScreenCapture(rect); + + if (!compareImages(capturedImage, realImage)) { + String errorMessage = "FAIL : Captured Image is different from " + + "the real image"; + saveImage(capturedImage, "CapturedImage.png"); + saveImage(realImage, "RealImage.png"); + throw new RuntimeException(errorMessage); + } + } + + private static boolean compareImages(BufferedImage capturedImg, + BufferedImage realImg) { + int capturedPixel; + int realPixel; + int imgWidth = capturedImg.getWidth(); + int imgHeight = capturedImg.getHeight(); + + if (imgWidth != IMAGE_WIDTH || imgHeight != IMAGE_HEIGHT) { + System.out.println("Captured and real images are different in size"); + return false; + } + + for (int i = 0; i < imgWidth; i++) { + for (int j = 0; j < imgHeight; j++) { + capturedPixel = capturedImg.getRGB(i, j); + realPixel = realImg.getRGB(i, j); + if (capturedPixel != realPixel) { + System.out.println("Captured pixel (" + + Integer.toHexString(capturedPixel) + ") at " + + "(" + i + ", " + j + ") is not equal to real pixel (" + + Integer.toHexString(realPixel) + ")"); + return false; + } + } + } + return true; + } + + private static class ImageCanvas extends Canvas { + @Override + public void paint(Graphics g) { + g.drawImage(realImage, OFFSET, OFFSET, this); + } + } + + private static void saveImage(BufferedImage image, String fileName) { + try { + ImageIO.write(image, "png", new File(fileName)); + } catch (IOException ignored) { + System.err.println(ignored.getMessage()); + } + } + + private static void disposeFrame() { + if (frame != null) { + frame.dispose(); + } + } +} From 02ec8ca2d6ccbabc6740b60be8fe1f8b2110f0ca Mon Sep 17 00:00:00 2001 From: Alexey Ivanov <aivanov@openjdk.org> Date: Tue, 19 Nov 2024 17:15:46 +0000 Subject: [PATCH 100/311] 8342508: Use latch in BasicMenuUI/bug4983388.java instead of delay Reviewed-by: azvegint, abhiscxk, serb --- .../basic/BasicMenuUI/4983388/bug4983388.java | 57 +++++++++++-------- 1 file changed, 33 insertions(+), 24 deletions(-) diff --git a/test/jdk/javax/swing/plaf/basic/BasicMenuUI/4983388/bug4983388.java b/test/jdk/javax/swing/plaf/basic/BasicMenuUI/4983388/bug4983388.java index 18f78d88f52..e495c929891 100644 --- a/test/jdk/javax/swing/plaf/basic/BasicMenuUI/4983388/bug4983388.java +++ b/test/jdk/javax/swing/plaf/basic/BasicMenuUI/4983388/bug4983388.java @@ -26,28 +26,41 @@ * @key headful * @bug 4983388 8015600 * @summary shortcuts on menus do not work on JDS - * @author Oleg Mokhovikov * @library ../../../../regtesthelpers * @build Util * @run main bug4983388 */ -import java.awt.*; -import javax.swing.*; -import javax.swing.event.MenuListener; -import javax.swing.event.MenuEvent; +import java.awt.Robot; import java.awt.event.KeyEvent; +import java.util.concurrent.CountDownLatch; + +import javax.swing.JFrame; +import javax.swing.JMenu; +import javax.swing.JMenuBar; +import javax.swing.SwingUtilities; +import javax.swing.UIManager; +import javax.swing.UnsupportedLookAndFeelException; +import javax.swing.event.MenuEvent; +import javax.swing.event.MenuListener; + +import static java.util.concurrent.TimeUnit.SECONDS; public class bug4983388 { - static volatile boolean bMenuSelected = false; static JFrame frame; + private static final CountDownLatch menuSelected = new CountDownLatch(1); + private static class TestMenuListener implements MenuListener { + @Override public void menuCanceled(MenuEvent e) {} + @Override public void menuDeselected(MenuEvent e) {} + + @Override public void menuSelected(MenuEvent e) { System.out.println("menuSelected"); - bMenuSelected = true; + menuSelected.countDown(); } } @@ -56,28 +69,24 @@ private static void createAndShowGUI() { JMenu menu = new JMenu("File"); menu.setMnemonic('F'); menuBar.add(menu); - frame = new JFrame(); + menu.addMenuListener(new TestMenuListener()); + + frame = new JFrame("bug4983388"); frame.setJMenuBar(menuBar); frame.setLocationRelativeTo(null); - frame.pack(); + frame.setSize(250, 100); frame.setVisible(true); - MenuListener listener = new TestMenuListener(); - menu.addMenuListener(listener); } public static void main(String[] args) throws Exception { - try { UIManager.setLookAndFeel("com.sun.java.swing.plaf.gtk.GTKLookAndFeel"); } catch (UnsupportedLookAndFeelException | ClassNotFoundException ex) { - System.err.println("GTKLookAndFeel is not supported on this platform. Using defailt LaF for this platform."); + System.err.println("GTKLookAndFeel is not supported on this platform. " + + "Using default LaF for this platform."); } - SwingUtilities.invokeAndWait(new Runnable() { - public void run() { - createAndShowGUI(); - } - }); + SwingUtilities.invokeAndWait(bug4983388::createAndShowGUI); Robot robot = new Robot(); robot.setAutoDelay(50); @@ -85,13 +94,13 @@ public void run() { robot.delay(500); Util.hitMnemonics(robot, KeyEvent.VK_F); - robot.waitForIdle(); - robot.delay(500); - - SwingUtilities.invokeAndWait(() -> frame.dispose()); - if (!bMenuSelected) { - throw new RuntimeException("shortcuts on menus do not work"); + try { + if (!menuSelected.await(1, SECONDS)) { + throw new RuntimeException("shortcuts on menus do not work"); + } + } finally { + SwingUtilities.invokeAndWait(frame::dispose); } } } From 087a07b5ededc6381d3d12cad045d3522434709e Mon Sep 17 00:00:00 2001 From: Archie Cobbs <acobbs@openjdk.org> Date: Tue, 19 Nov 2024 17:43:48 +0000 Subject: [PATCH 101/311] 8343479: Remove unnecessary @SuppressWarnings annotations (hotspot) Reviewed-by: chagedorn, epeter --- .../share/classes/jdk/vm/ci/hotspot/HotSpotJVMCIRuntime.java | 3 --- .../jdk/vm/ci/hotspot/IndirectHotSpotObjectConstantImpl.java | 3 +-- .../share/classes/jdk/vm/ci/meta/AnnotationData.java | 4 +--- 3 files changed, 2 insertions(+), 8 deletions(-) diff --git a/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotJVMCIRuntime.java b/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotJVMCIRuntime.java index 3fd92f8dee5..616b5a23f64 100644 --- a/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotJVMCIRuntime.java +++ b/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/HotSpotJVMCIRuntime.java @@ -959,7 +959,6 @@ public Map<Class<? extends Architecture>, JVMCIBackend> getJVMCIBackends() { return Collections.unmodifiableMap(backends); } - @SuppressWarnings("try") @VMEntryPoint private HotSpotCompilationRequestResult compileMethod(HotSpotResolvedJavaMethod method, int entryBCI, long compileState, int id) { HotSpotCompilationRequest request = new HotSpotCompilationRequest(method, entryBCI, compileState, id); @@ -981,13 +980,11 @@ private HotSpotCompilationRequestResult compileMethod(HotSpotResolvedJavaMethod return hsResult; } - @SuppressWarnings("try") @VMEntryPoint private boolean isGCSupported(int gcIdentifier) { return getCompiler().isGCSupported(gcIdentifier); } - @SuppressWarnings("try") @VMEntryPoint private boolean isIntrinsicSupported(int intrinsicIdentifier) { return getCompiler().isIntrinsicSupported(intrinsicIdentifier); diff --git a/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/IndirectHotSpotObjectConstantImpl.java b/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/IndirectHotSpotObjectConstantImpl.java index fe268e90476..2b8f717840e 100644 --- a/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/IndirectHotSpotObjectConstantImpl.java +++ b/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/hotspot/IndirectHotSpotObjectConstantImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -70,7 +70,6 @@ private static class Audit { */ private Object rawAudit; - @SuppressWarnings("serial") @VMEntryPoint private IndirectHotSpotObjectConstantImpl(long objectHandle, boolean compressed, boolean skipRegister) { super(compressed); diff --git a/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/AnnotationData.java b/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/AnnotationData.java index 17b6b714ba4..76edb8c83a7 100644 --- a/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/AnnotationData.java +++ b/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/AnnotationData.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -69,7 +69,6 @@ public final class AnnotationData { * @throws NullPointerException if any of the above parameters is null or any entry in * {@code elements} is null */ - @SuppressWarnings({"rawtypes", "unchecked"}) public AnnotationData(JavaType type, Map.Entry<String, Object>[] elements) { this.type = Objects.requireNonNull(type); for (Map.Entry<String, Object> e : elements) { @@ -125,7 +124,6 @@ public JavaType getAnnotationType() { * there was an error parsing or creating the element value */ // @formatter:on - @SuppressWarnings("unchecked") public <V> V get(String name, Class<V> elementType) { Object val = elements.get(name); if (val == null) { From bb7a8403ba1b32b2d97c0bd3ec78dac1832f5289 Mon Sep 17 00:00:00 2001 From: Renjith Kannath Pariyangad <rkannathpari@openjdk.org> Date: Tue, 19 Nov 2024 18:19:28 +0000 Subject: [PATCH 102/311] 8342541: Exclude List/KeyEventsTest/KeyEventsTest.java from running on macOS Reviewed-by: aivanov, prr --- .../awt/List/KeyEventsTest/KeyEventsTest.java | 30 ++++++++----------- 1 file changed, 12 insertions(+), 18 deletions(-) diff --git a/test/jdk/java/awt/List/KeyEventsTest/KeyEventsTest.java b/test/jdk/java/awt/List/KeyEventsTest/KeyEventsTest.java index 16fbccdafd1..919ea72a494 100644 --- a/test/jdk/java/awt/List/KeyEventsTest/KeyEventsTest.java +++ b/test/jdk/java/awt/List/KeyEventsTest/KeyEventsTest.java @@ -21,17 +21,6 @@ * questions. */ -/* - @test - @key headful - @bug 6190768 6190778 - @summary Tests that triggering events on AWT list by pressing CTRL + HOME, - CTRL + END, PG-UP, PG-DOWN similar Motif behavior - @library /test/lib - @build jdk.test.lib.Platform - @run main KeyEventsTest -*/ - import java.awt.BorderLayout; import java.awt.EventQueue; import java.awt.KeyboardFocusManager; @@ -50,6 +39,17 @@ import jdk.test.lib.Platform; +/* + * @test + * @key headful + * @bug 6190768 6190778 + * @requires os.family != "mac" + * @summary Tests that triggering events on AWT list by pressing CTRL + HOME, + * CTRL + END, PG-UP, PG-DOWN similar Motif behavior + * @library /test/lib + * @build jdk.test.lib.Platform + * @run main KeyEventsTest + */ public class KeyEventsTest { TestState currentState; final Object LOCK = new Object(); @@ -261,13 +261,7 @@ private void test(TestState currentState) throws Exception { private void doTest() throws Exception { - boolean isWin = false; - if (Platform.isWindows()) { - isWin = true; - } else if (Platform.isOSX()) { - System.out.println("Not for OS X"); - return; - } + boolean isWin = Platform.isWindows(); System.out.println("multiple? selectedMoved? ?scrollMoved keyID? template? action?"); test(new TestState(false, false, false, KeyEvent.VK_PAGE_UP, isWin?false:false)); From 93e889b48cb6eb6872201a28ee19d8fd17c5d821 Mon Sep 17 00:00:00 2001 From: Larry Cable <larry.cable@oracle.com> Date: Tue, 19 Nov 2024 18:45:45 +0000 Subject: [PATCH 103/311] 8342449: reimplement: JDK-8327114 Attach in Linux may have wrong behavior when pid == ns_pid Reviewed-by: kevinw --- .../sun/tools/attach/VirtualMachineImpl.java | 203 +++++++++--------- 1 file changed, 104 insertions(+), 99 deletions(-) diff --git a/src/jdk.attach/linux/classes/sun/tools/attach/VirtualMachineImpl.java b/src/jdk.attach/linux/classes/sun/tools/attach/VirtualMachineImpl.java index 35ce808c187..69cd4dcdb99 100644 --- a/src/jdk.attach/linux/classes/sun/tools/attach/VirtualMachineImpl.java +++ b/src/jdk.attach/linux/classes/sun/tools/attach/VirtualMachineImpl.java @@ -34,7 +34,8 @@ import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; -import java.util.Optional; + +import java.util.regex.Pattern; import static java.nio.charset.StandardCharsets.UTF_8; @@ -51,26 +52,9 @@ public class VirtualMachineImpl extends HotSpotVirtualMachine { private static final Path TMPDIR = Path.of("/tmp"); private static final Path PROC = Path.of("/proc"); - private static final Path NS_MNT = Path.of("ns/mnt"); - private static final Path NS_PID = Path.of("ns/pid"); - private static final Path SELF = PROC.resolve("self"); private static final Path STATUS = Path.of("status"); private static final Path ROOT_TMP = Path.of("root/tmp"); - private static final Optional<Path> SELF_MNT_NS; - - static { - Path nsPath = null; - - try { - nsPath = Files.readSymbolicLink(SELF.resolve(NS_MNT)); - } catch (IOException _) { - // do nothing - } finally { - SELF_MNT_NS = Optional.ofNullable(nsPath); - } - } - String socket_path; /** @@ -97,13 +81,16 @@ public class VirtualMachineImpl extends HotSpotVirtualMachine { if (!socket_file.exists()) { // Keep canonical version of File, to delete, in case target process ends and /proc link has gone: File f = createAttachFile(pid, ns_pid).getCanonicalFile(); + + boolean timedout = false; + try { - sendQuitTo(pid); + checkCatchesAndSendQuitTo(pid, false); // give the target VM time to start the attach mechanism final int delay_step = 100; final long timeout = attachTimeout(); - long time_spend = 0; + long time_spent = 0; long delay = 0; do { // Increase timeout on each attempt to reduce polling @@ -112,18 +99,19 @@ public class VirtualMachineImpl extends HotSpotVirtualMachine { Thread.sleep(delay); } catch (InterruptedException x) { } - time_spend += delay; - if (time_spend > timeout/2 && !socket_file.exists()) { + timedout = (time_spent += delay) > timeout; + + if (time_spent > timeout/2 && !socket_file.exists()) { // Send QUIT again to give target VM the last chance to react - sendQuitTo(pid); + checkCatchesAndSendQuitTo(pid, !timedout); } - } while (time_spend <= timeout && !socket_file.exists()); + } while (!timedout && !socket_file.exists()); + if (!socket_file.exists()) { throw new AttachNotSupportedException( String.format("Unable to open socket file %s: " + "target process %d doesn't respond within %dms " + - "or HotSpot VM not loaded", socket_path, pid, - time_spend)); + "or HotSpot VM not loaded", socket_path, pid, time_spent)); } } finally { f.delete(); @@ -257,79 +245,32 @@ private File createAttachFile(long pid, long ns_pid) throws AttachNotSupportedEx } private String findTargetProcessTmpDirectory(long pid, long ns_pid) throws AttachNotSupportedException, IOException { - // We need to handle at least 4 different cases: - // 1. Caller and target processes share PID namespace and root filesystem (host to host or container to - // container with both /tmp mounted between containers). - // 2. Caller and target processes share PID namespace and root filesystem but the target process has elevated - // privileges (host to host). - // 3. Caller and target processes share PID namespace but NOT root filesystem (container to container). - // 4. Caller and target processes share neither PID namespace nor root filesystem (host to container). - - Optional<ProcessHandle> target = ProcessHandle.of(pid); - Optional<ProcessHandle> ph = target; - long nsPid = ns_pid; - Optional<Path> prevPidNS = Optional.empty(); - - while (ph.isPresent()) { - final var curPid = ph.get().pid(); - final var procPidPath = PROC.resolve(Long.toString(curPid)); - Optional<Path> targetMountNS = Optional.empty(); - - try { - // attempt to read the target's mnt ns id - targetMountNS = Optional.ofNullable(Files.readSymbolicLink(procPidPath.resolve(NS_MNT))); - } catch (IOException _) { - // if we fail to read the target's mnt ns id then we either don't have access or it no longer exists! - if (!Files.exists(procPidPath)) { - throw new IOException(String.format("unable to attach, %s non-existent! process: %d terminated", procPidPath, pid)); - } - // the process still exists, but we don't have privileges to read its procfs - } - - final var sameMountNS = SELF_MNT_NS.isPresent() && SELF_MNT_NS.equals(targetMountNS); - - if (sameMountNS) { - return TMPDIR.toString(); // we share TMPDIR in common! - } else { - // we could not read the target's mnt ns - final var procPidRootTmp = procPidPath.resolve(ROOT_TMP); - if (Files.isReadable(procPidRootTmp)) { - return procPidRootTmp.toString(); // not in the same mnt ns but tmp is accessible via /proc - } - } - - // let's attempt to obtain the pid ns, best efforts to avoid crossing pid ns boundaries (as with a container) - Optional<Path> curPidNS = Optional.empty(); - - try { - // attempt to read the target's pid ns id - curPidNS = Optional.ofNullable(Files.readSymbolicLink(procPidPath.resolve(NS_PID))); - } catch (IOException _) { - // if we fail to read the target's pid ns id then we either don't have access or it no longer exists! - if (!Files.exists(procPidPath)) { - throw new IOException(String.format("unable to attach, %s non-existent! process: %d terminated", procPidPath, pid)); - } - // the process still exists, but we don't have privileges to read its procfs - } - - // recurse "up" the process hierarchy if appropriate. PID 1 cannot have a parent in the same namespace - final var havePidNSes = prevPidNS.isPresent() && curPidNS.isPresent(); - final var ppid = ph.get().parent(); - - if (ppid.isPresent() && (havePidNSes && curPidNS.equals(prevPidNS)) || (!havePidNSes && nsPid > 1)) { - ph = ppid; - nsPid = getNamespacePid(ph.get().pid()); // get the ns pid of the parent - prevPidNS = curPidNS; - } else { - ph = Optional.empty(); - } - } - - if (target.orElseThrow(AttachNotSupportedException::new).isAlive()) { - return TMPDIR.toString(); // fallback... - } else { - throw new IOException(String.format("unable to attach, process: %d terminated", pid)); - } + final var procPidRoot = PROC.resolve(Long.toString(pid)).resolve(ROOT_TMP); + + /* We need to handle at least 4 different cases: + * 1. Caller and target processes share PID namespace and root filesystem (host to host or container to + * container with both /tmp mounted between containers). + * 2. Caller and target processes share PID namespace and root filesystem but the target process has elevated + * privileges (host to host). + * 3. Caller and target processes share PID namespace but NOT root filesystem (container to container). + * 4. Caller and target processes share neither PID namespace nor root filesystem (host to container) + * + * if target is elevated, we cant use /proc/<pid>/... so we have to fallback to /tmp, but that may not be shared + * with the target/attachee process, we can try, except in the case where the ns_pid also exists in this pid ns + * which is ambiguous, if we share /tmp with the intended target, the attach will succeed, if we do not, + * then we will potentially attempt to attach to some arbitrary process with the same pid (in this pid ns) + * as that of the intended target (in its * pid ns). + * + * so in that case we should prehaps throw - or risk sending SIGQUIT to some arbitrary process... which could kill it + * + * however we can also check the target pid's signal masks to see if it catches SIGQUIT and only do so if in + * fact it does ... this reduces the risk of killing an innocent process in the current ns as opposed to + * attaching to the actual target JVM ... c.f: checkCatchesAndSendQuitTo() below. + * + * note that if pid == ns_pid we are in a shared pid ns with the target and may (potentially) share /tmp + */ + + return (Files.isWritable(procPidRoot) ? procPidRoot : TMPDIR).toString(); } /* @@ -378,6 +319,70 @@ private long getNamespacePid(long pid) throws AttachNotSupportedException, IOExc } } + private static final String FIELD = "field"; + private static final String MASK = "mask"; + + private static final Pattern SIGNAL_MASK_PATTERN = Pattern.compile("(?<" + FIELD + ">Sig\\p{Alpha}{3}):\\s+(?<" + MASK + ">\\p{XDigit}{16}).*"); + + private static final long SIGQUIT = 0b100; // mask bit for SIGQUIT + + private static boolean checkCatchesAndSendQuitTo(int pid, boolean throwIfNotReady) throws AttachNotSupportedException, IOException { + var quitIgn = false; + var quitBlk = false; + var quitCgt = false; + + final var procPid = PROC.resolve(Integer.toString(pid)); + + var readBlk = false; + var readIgn = false; + var readCgt = false; + + + if (!Files.exists(procPid)) throw new IOException("non existent JVM pid: " + pid); + + for (var line : Files.readAllLines(procPid.resolve("status"))) { + + if (!line.startsWith("Sig")) continue; // to speed things up ... avoids the matcher/RE invocation... + + final var m = SIGNAL_MASK_PATTERN.matcher(line); + + if (!m.matches()) continue; + + var sigmask = m.group(MASK); + final var slen = sigmask.length(); + + sigmask = sigmask.substring(slen / 2 , slen); // only really interested in the non r/t signals ... + + final var sigquit = (Long.valueOf(sigmask, 16) & SIGQUIT) != 0L; + + switch (m.group(FIELD)) { + case "SigBlk": { quitBlk = sigquit; readBlk = true; break; } + case "SigIgn": { quitIgn = sigquit; readIgn = true; break; } + case "SigCgt": { quitCgt = sigquit; readCgt = true; break; } + } + + if (readBlk && readIgn && readCgt) break; + } + + final boolean okToSendQuit = (!quitIgn && quitCgt); // ignore blocked as it may be temporary ... + + if (okToSendQuit) { + sendQuitTo(pid); + } else if (throwIfNotReady) { + final var cmdline = Files.lines(procPid.resolve("cmdline")).findFirst(); + + var cmd = "null"; // default + + if (cmdline.isPresent()) { + cmd = cmdline.get(); + cmd = cmd.substring(0, cmd.length() - 1); // remove trailing \0 + } + + throw new AttachNotSupportedException("pid: " + pid + " cmd: '" + cmd + "' state is not ready to participate in attach handshake!"); + } + + return okToSendQuit; + } //-- native methods From 0b1f57105d5af72b2cd47fa5c9a2b4e2961318cd Mon Sep 17 00:00:00 2001 From: Chris Plummer <cjplummer@openjdk.org> Date: Tue, 19 Nov 2024 18:58:00 +0000 Subject: [PATCH 104/311] 8253440: serviceability/sa/TestJhsdbJstackLineNumbers.java failed with "Didn't find enough line numbers" Reviewed-by: kevinw, lmesnik --- .../sa/TestJhsdbJstackLineNumbers.java | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/test/hotspot/jtreg/serviceability/sa/TestJhsdbJstackLineNumbers.java b/test/hotspot/jtreg/serviceability/sa/TestJhsdbJstackLineNumbers.java index 5d9c3982fb6..87e664ef308 100644 --- a/test/hotspot/jtreg/serviceability/sa/TestJhsdbJstackLineNumbers.java +++ b/test/hotspot/jtreg/serviceability/sa/TestJhsdbJstackLineNumbers.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -35,6 +35,7 @@ /** * @test + * @bug 8214226 8243500 * @requires vm.hasSA * @requires os.arch=="amd64" | os.arch=="x86_64" * @requires os.family=="windows" | os.family == "linux" | os.family == "mac" @@ -53,7 +54,7 @@ * * The test works by spawning a process that sits in a 10 line loop in the busywork() method, * all while the main test does repeated jstacks on the process. The expectation is - * that at least 5 of the lines in the busywork() loop will eventually show up in at + * that at least 4 of the lines in the busywork() loop will eventually show up in at * least one of the jstack runs. */ @@ -94,8 +95,11 @@ public static void main(String... args) { public class TestJhsdbJstackLineNumbers { // This is the number of lines in the busywork main loop static final int TOTAL_BUSYWORK_LOOP_LINES = 10; - // The minimum number of lines that we must at some point see in the jstack output - static final int MIN_BUSYWORK_LOOP_LINES = 5; + // The minimum number of lines that we must see at some point in the jstack output. + // There's always a chance we could see fewer, but the chances are so low that + // it is unlikely to ever happen. We can always decrease the odds by lowering + // the required number of lines or increasing the number of jstack runs. + static final int MIN_BUSYWORK_LOOP_LINES = 4; static final int MAX_NUMBER_OF_JSTACK_RUNS = 25; From 6a5256ec042e16a2157475e86e7859b345a91bd0 Mon Sep 17 00:00:00 2001 From: Stuart Marks <smarks@openjdk.org> Date: Tue, 19 Nov 2024 18:58:23 +0000 Subject: [PATCH 105/311] 8344149: Remove usage of Security Manager from java.rmi Reviewed-by: rriggs, kevinw, aefimov --- .../classes/java/rmi/MarshalledObject.java | 16 +-- .../classes/java/rmi/server/LogStream.java | 10 +- .../share/classes/java/rmi/server/ObjID.java | 8 +- .../java/rmi/server/RMIClassLoader.java | 14 +- .../java/rmi/server/RMISocketFactory.java | 10 -- .../classes/sun/rmi/log/ReliableLog.java | 22 +-- .../sun/rmi/registry/RegistryImpl.java | 2 - .../share/classes/sun/rmi/runtime/Log.java | 44 ++---- .../sun/rmi/runtime/NewThreadAction.java | 56 +++----- .../classes/sun/rmi/runtime/RuntimeUtil.java | 50 +------ .../sun/rmi/server/MarshalInputStream.java | 10 +- .../sun/rmi/server/MarshalOutputStream.java | 11 +- .../classes/sun/rmi/server/UnicastRef.java | 8 +- .../sun/rmi/server/UnicastServerRef.java | 41 ++---- .../share/classes/sun/rmi/server/Util.java | 27 +--- .../sun/rmi/transport/DGCAckHandler.java | 12 +- .../classes/sun/rmi/transport/DGCClient.java | 70 ++-------- .../classes/sun/rmi/transport/DGCImpl.java | 98 ++++---------- .../sun/rmi/transport/DGCImpl_Stub.java | 4 +- .../share/classes/sun/rmi/transport/GC.java | 30 ++--- .../sun/rmi/transport/ObjectTable.java | 20 +-- .../sun/rmi/transport/StreamRemoteCall.java | 10 +- .../classes/sun/rmi/transport/Target.java | 33 +---- .../classes/sun/rmi/transport/Transport.java | 50 +------ .../sun/rmi/transport/tcp/TCPChannel.java | 84 ++---------- .../sun/rmi/transport/tcp/TCPEndpoint.java | 22 +-- .../sun/rmi/transport/tcp/TCPTransport.java | 127 ++---------------- 27 files changed, 173 insertions(+), 716 deletions(-) diff --git a/src/java.rmi/share/classes/java/rmi/MarshalledObject.java b/src/java.rmi/share/classes/java/rmi/MarshalledObject.java index 148cc97ef94..acf402db4d9 100644 --- a/src/java.rmi/share/classes/java/rmi/MarshalledObject.java +++ b/src/java.rmi/share/classes/java/rmi/MarshalledObject.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -35,8 +35,6 @@ import java.io.ObjectStreamConstants; import java.io.OutputStream; import java.io.Serializable; -import java.security.AccessController; -import java.security.PrivilegedAction; import sun.rmi.server.MarshalInputStream; import sun.rmi.server.MarshalOutputStream; @@ -317,7 +315,6 @@ private static class MarshalledObjectInputStream * <code>null</code>, then all annotations will be * <code>null</code>. */ - @SuppressWarnings("removal") MarshalledObjectInputStream(InputStream objIn, InputStream locIn, ObjectInputFilter filter) throws IOException @@ -325,13 +322,10 @@ private static class MarshalledObjectInputStream super(objIn); this.locIn = (locIn == null ? null : new ObjectInputStream(locIn)); if (filter != null) { - AccessController.doPrivileged((PrivilegedAction<Void>) () -> { - MarshalledObjectInputStream.this.setObjectInputFilter(filter); - if (MarshalledObjectInputStream.this.locIn != null) { - MarshalledObjectInputStream.this.locIn.setObjectInputFilter(filter); - } - return null; - }); + MarshalledObjectInputStream.this.setObjectInputFilter(filter); + if (MarshalledObjectInputStream.this.locIn != null) { + MarshalledObjectInputStream.this.locIn.setObjectInputFilter(filter); + } } } diff --git a/src/java.rmi/share/classes/java/rmi/server/LogStream.java b/src/java.rmi/share/classes/java/rmi/server/LogStream.java index ca554569d3b..8ac26770263 100644 --- a/src/java.rmi/share/classes/java/rmi/server/LogStream.java +++ b/src/java.rmi/share/classes/java/rmi/server/LogStream.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -120,14 +120,6 @@ public static synchronized PrintStream getDefaultStream() { */ @Deprecated public static synchronized void setDefaultStream(PrintStream newDefault) { - @SuppressWarnings("removal") - SecurityManager sm = System.getSecurityManager(); - - if (sm != null) { - sm.checkPermission( - new java.util.logging.LoggingPermission("control", null)); - } - defaultStream = newDefault; } diff --git a/src/java.rmi/share/classes/java/rmi/server/ObjID.java b/src/java.rmi/share/classes/java/rmi/server/ObjID.java index ae3a61277ec..894ee317d28 100644 --- a/src/java.rmi/share/classes/java/rmi/server/ObjID.java +++ b/src/java.rmi/share/classes/java/rmi/server/ObjID.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -30,8 +30,6 @@ import java.io.ObjectInput; import java.io.ObjectOutput; import java.io.Serializable; -import java.security.AccessController; -import java.security.PrivilegedAction; import java.security.SecureRandom; import java.util.concurrent.atomic.AtomicLong; @@ -242,9 +240,7 @@ public String toString() { } private static boolean useRandomIDs() { - @SuppressWarnings("removal") - String value = AccessController.doPrivileged( - (PrivilegedAction<String>) () -> System.getProperty("java.rmi.server.randomIDs")); + String value = System.getProperty("java.rmi.server.randomIDs"); return value == null ? true : Boolean.parseBoolean(value); } } diff --git a/src/java.rmi/share/classes/java/rmi/server/RMIClassLoader.java b/src/java.rmi/share/classes/java/rmi/server/RMIClassLoader.java index 6736c33f0a0..004ea27e30a 100644 --- a/src/java.rmi/share/classes/java/rmi/server/RMIClassLoader.java +++ b/src/java.rmi/share/classes/java/rmi/server/RMIClassLoader.java @@ -27,8 +27,6 @@ import java.net.MalformedURLException; import java.net.URL; -import java.security.AccessController; -import java.security.PrivilegedAction; import java.util.Iterator; import java.util.ServiceLoader; @@ -112,12 +110,7 @@ public class RMIClassLoader { newDefaultProviderInstance(); /** provider instance */ - @SuppressWarnings("removal") - private static final RMIClassLoaderSpi provider = - AccessController.doPrivileged( - new PrivilegedAction<RMIClassLoaderSpi>() { - public RMIClassLoaderSpi run() { return initializeProvider(); } - }); + private static final RMIClassLoaderSpi provider = initializeProvider(); /* * Disallow anyone from creating one of these. @@ -538,11 +531,6 @@ public static String getClassAnnotation(Class<?> cl) { * @since 1.4 */ public static RMIClassLoaderSpi getDefaultProviderInstance() { - @SuppressWarnings("removal") - SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - sm.checkPermission(new RuntimePermission("setFactory")); - } return defaultProvider; } diff --git a/src/java.rmi/share/classes/java/rmi/server/RMISocketFactory.java b/src/java.rmi/share/classes/java/rmi/server/RMISocketFactory.java index fedc4b22d9b..a7fc07f3d4b 100644 --- a/src/java.rmi/share/classes/java/rmi/server/RMISocketFactory.java +++ b/src/java.rmi/share/classes/java/rmi/server/RMISocketFactory.java @@ -131,11 +131,6 @@ public static synchronized void setSocketFactory(RMISocketFactory fac) if (factory != null) { throw new SocketException("factory already defined"); } - @SuppressWarnings("removal") - SecurityManager security = System.getSecurityManager(); - if (security != null) { - security.checkSetFactory(); - } factory = fac; } @@ -181,11 +176,6 @@ public static synchronized RMISocketFactory getDefaultSocketFactory() { */ public static synchronized void setFailureHandler(RMIFailureHandler fh) { - @SuppressWarnings("removal") - SecurityManager security = System.getSecurityManager(); - if (security != null) { - security.checkSetFactory(); - } handler = fh; } diff --git a/src/java.rmi/share/classes/sun/rmi/log/ReliableLog.java b/src/java.rmi/share/classes/sun/rmi/log/ReliableLog.java index 293e2ccdec3..ce2aa84d312 100644 --- a/src/java.rmi/share/classes/sun/rmi/log/ReliableLog.java +++ b/src/java.rmi/share/classes/sun/rmi/log/ReliableLog.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -27,9 +27,6 @@ import java.io.*; import java.lang.reflect.Constructor; -import java.rmi.server.RMIClassLoader; -import java.security.AccessController; -import java.security.PrivilegedAction; /** * This class is a simple implementation of a reliable Log. The @@ -132,15 +129,13 @@ public class ReliableLog { * if an exception occurs during invocation of the handler's * snapshot method or if other IOException occurs. */ - @SuppressWarnings("removal") public ReliableLog(String dirPath, LogHandler handler, boolean pad) throws IOException { super(); - this.Debug = AccessController.doPrivileged( - (PrivilegedAction<Boolean>) () -> Boolean.getBoolean("sun.rmi.log.debug")); + this.Debug = Boolean.getBoolean("sun.rmi.log.debug"); dir = new File(dirPath); if (!(dir.exists() && dir.isDirectory())) { // create directory @@ -331,19 +326,10 @@ public synchronized void update(Object value, boolean forceToDisk) private static Constructor<? extends LogFile> getLogClassConstructor() { - @SuppressWarnings("removal") - String logClassName = AccessController.doPrivileged( - (PrivilegedAction<String>) () -> System.getProperty("sun.rmi.log.class")); + String logClassName = System.getProperty("sun.rmi.log.class"); if (logClassName != null) { try { - @SuppressWarnings("removal") - ClassLoader loader = - AccessController.doPrivileged( - new PrivilegedAction<ClassLoader>() { - public ClassLoader run() { - return ClassLoader.getSystemClassLoader(); - } - }); + ClassLoader loader = ClassLoader.getSystemClassLoader(); Class<? extends LogFile> cl = loader.loadClass(logClassName).asSubclass(LogFile.class); return cl.getConstructor(String.class, String.class); diff --git a/src/java.rmi/share/classes/sun/rmi/registry/RegistryImpl.java b/src/java.rmi/share/classes/sun/rmi/registry/RegistryImpl.java index 91bb92d9833..406e16b6376 100644 --- a/src/java.rmi/share/classes/sun/rmi/registry/RegistryImpl.java +++ b/src/java.rmi/share/classes/sun/rmi/registry/RegistryImpl.java @@ -263,7 +263,6 @@ public String[] list() * Check that the caller has access to perform indicated operation. * The client must be on same the same host as this server. */ - @SuppressWarnings("removal") public static void checkAccess(String op) throws AccessException { try { @@ -370,7 +369,6 @@ private static URL[] pathToURLs(String path) { * {@link ObjectInputFilter.Status#REJECTED} if rejected, * otherwise {@link ObjectInputFilter.Status#UNDECIDED} */ - @SuppressWarnings("removal") private static ObjectInputFilter.Status registryFilter(ObjectInputFilter.FilterInfo filterInfo) { if (registryFilter != null) { ObjectInputFilter.Status status = registryFilter.checkInput(filterInfo); diff --git a/src/java.rmi/share/classes/sun/rmi/runtime/Log.java b/src/java.rmi/share/classes/sun/rmi/runtime/Log.java index 849b35688d1..78154bb21c8 100644 --- a/src/java.rmi/share/classes/sun/rmi/runtime/Log.java +++ b/src/java.rmi/share/classes/sun/rmi/runtime/Log.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -30,7 +30,6 @@ import java.io.OutputStream; import java.lang.StackWalker.StackFrame; import java.rmi.server.LogStream; -import java.security.PrivilegedAction; import java.util.Set; import java.util.logging.Handler; import java.util.logging.SimpleFormatter; @@ -69,9 +68,7 @@ public abstract class Log { /* selects log implementation */ private static final LogFactory logFactory; static { - @SuppressWarnings("removal") - boolean useOld = java.security.AccessController.doPrivileged( - (PrivilegedAction<Boolean>) () -> Boolean.getBoolean("sun.rmi.log.useOld")); + boolean useOld = Boolean.getBoolean("sun.rmi.log.useOld"); /* set factory to select the logging facility to use */ logFactory = (useOld ? (LogFactory) new LogStreamLogFactory() : @@ -177,17 +174,12 @@ public Log createLog(final String loggerName, String oldLogName, private static class LoggerLog extends Log { /* alternate console handler for RMI loggers */ - @SuppressWarnings("removal") - private static final Handler alternateConsole = - java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction<Handler>() { - public Handler run() { - InternalStreamHandler alternate = - new InternalStreamHandler(System.err); - alternate.setLevel(Level.ALL); - return alternate; - } - }); + private static final Handler alternateConsole; + static { + var alternate = new InternalStreamHandler(System.err); + alternate.setLevel(Level.ALL); + alternateConsole = alternate; + } /** handler to which messages are copied */ private InternalStreamHandler copyHandler = null; @@ -199,22 +191,14 @@ public Handler run() { private LoggerPrintStream loggerSandwich; /** creates a Log which will delegate to the given logger */ - @SuppressWarnings("removal") private LoggerLog(final Logger logger, final Level level) { this.logger = logger; - if (level != null){ - java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction<Void>() { - public Void run() { - if (!logger.isLoggable(level)) { - logger.setLevel(level); - } - logger.addHandler(alternateConsole); - return null; - } - } - ); + if (level != null) { + if (!logger.isLoggable(level)) { + logger.setLevel(level); + } + logger.addHandler(alternateConsole); } } @@ -247,8 +231,6 @@ public String toString() { /** * Set the output stream associated with the RMI server call * logger. - * - * Calling code needs LoggingPermission "control". */ public synchronized void setOutputStream(OutputStream out) { if (out != null) { diff --git a/src/java.rmi/share/classes/sun/rmi/runtime/NewThreadAction.java b/src/java.rmi/share/classes/sun/rmi/runtime/NewThreadAction.java index aebd200afe6..f9be382d0fc 100644 --- a/src/java.rmi/share/classes/sun/rmi/runtime/NewThreadAction.java +++ b/src/java.rmi/share/classes/sun/rmi/runtime/NewThreadAction.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,13 +25,11 @@ package sun.rmi.runtime; -import java.security.AccessController; -import java.security.PrivilegedAction; -import sun.security.util.SecurityConstants; - /** - * A PrivilegedAction for creating a new thread conveniently with an - * AccessController.doPrivileged construct. + * A utility class for creating threads. The constructors take a + * variety of parameters to configure the thread. The run() method + * creates and sets up the thread and returns it, but does not + * start it. * * All constructors allow the choice of the Runnable for the new * thread to execute, the name of the new thread (which will be @@ -48,34 +46,27 @@ * * @author Peter Jones **/ -public final class NewThreadAction implements PrivilegedAction<Thread> { +public final class NewThreadAction { /** cached reference to the system (root) thread group */ - @SuppressWarnings("removal") - static final ThreadGroup systemThreadGroup = - AccessController.doPrivileged(new PrivilegedAction<ThreadGroup>() { - public ThreadGroup run() { - ThreadGroup group = Thread.currentThread().getThreadGroup(); - ThreadGroup parent; - while ((parent = group.getParent()) != null) { - group = parent; - } - return group; - } - }); + static final ThreadGroup systemThreadGroup; + static { + ThreadGroup group = Thread.currentThread().getThreadGroup(); + ThreadGroup parent; + while ((parent = group.getParent()) != null) { + group = parent; + } + systemThreadGroup = group; + } + /** - * special child of the system thread group for running tasks that - * may execute user code, so that the security policy for threads in - * the system thread group will not apply + * Special child of the system thread group for running tasks that + * may execute user code. The need for a separate thread group may + * be a vestige of it having had a different security policy from + * the system thread group, so this might no longer be necessary. */ - @SuppressWarnings("removal") - static final ThreadGroup userThreadGroup = - AccessController.doPrivileged(new PrivilegedAction<ThreadGroup>() { - public ThreadGroup run() { - return new ThreadGroup(systemThreadGroup, "RMI Runtime"); - } - }); + static final ThreadGroup userThreadGroup = new ThreadGroup(systemThreadGroup, "RMI Runtime"); private final ThreadGroup group; private final Runnable runnable; @@ -128,11 +119,6 @@ public NewThreadAction(Runnable runnable, String name, boolean daemon, } public Thread run() { - @SuppressWarnings("removal") - SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - sm.checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION); - } Thread t = new Thread(group, runnable, "RMI " + name); t.setContextClassLoader(ClassLoader.getSystemClassLoader()); t.setDaemon(daemon); diff --git a/src/java.rmi/share/classes/sun/rmi/runtime/RuntimeUtil.java b/src/java.rmi/share/classes/sun/rmi/runtime/RuntimeUtil.java index b45bbe5f3a3..4be706e57bb 100644 --- a/src/java.rmi/share/classes/sun/rmi/runtime/RuntimeUtil.java +++ b/src/java.rmi/share/classes/sun/rmi/runtime/RuntimeUtil.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,9 +25,6 @@ package sun.rmi.runtime; -import java.security.AccessController; -import java.security.Permission; -import java.security.PrivilegedAction; import java.util.concurrent.ScheduledThreadPoolExecutor; import java.util.concurrent.ThreadFactory; import java.util.concurrent.atomic.AtomicInteger; @@ -37,10 +34,7 @@ * RMI runtime implementation utilities. * * There is a single instance of this class, which can be obtained - * with a GetInstanceAction. Getting the instance requires - * RuntimePermission("sun.rmi.runtime.RuntimeUtil.getInstance") - * because the public methods of this class expose security-sensitive - * capabilities. + * with a getInstance() call. * * @author Peter Jones **/ @@ -51,14 +45,8 @@ public final class RuntimeUtil { Log.getLog("sun.rmi.runtime", null, false); /** number of scheduler threads */ - @SuppressWarnings("removal") private static final int schedulerThreads = // default 1 - AccessController.doPrivileged((PrivilegedAction<Integer>) () -> - Integer.getInteger("sun.rmi.runtime.schedulerThreads", 1)); - - /** permission required to get instance */ - private static final Permission GET_INSTANCE_PERMISSION = - new RuntimePermission("sun.rmi.runtime.RuntimeUtil.getInstance"); + Integer.getInteger("sun.rmi.runtime.schedulerThreads", 1); /** the singleton instance of this class */ private static final RuntimeUtil instance = new RuntimeUtil(); @@ -71,13 +59,11 @@ private RuntimeUtil() { schedulerThreads, new ThreadFactory() { private final AtomicInteger count = new AtomicInteger(); - @SuppressWarnings("removal") public Thread newThread(Runnable runnable) { try { - return AccessController.doPrivileged( - new NewThreadAction(runnable, - "Scheduler(" + count.getAndIncrement() + ")", - true)); + return new NewThreadAction(runnable, + "Scheduler(" + count.getAndIncrement() + ")", + true).run(); } catch (Throwable t) { runtimeLog.log(Level.WARNING, "scheduler thread factory throws", t); @@ -94,29 +80,7 @@ public Thread newThread(Runnable runnable) { // stpe.allowCoreThreadTimeOut(true); } - /** - * A PrivilegedAction for getting the RuntimeUtil instance. - **/ - public static class GetInstanceAction - implements PrivilegedAction<RuntimeUtil> - { - /** - * Creates an action that returns the RuntimeUtil instance. - **/ - public GetInstanceAction() { - } - - public RuntimeUtil run() { - return getInstance(); - } - } - - private static RuntimeUtil getInstance() { - @SuppressWarnings("removal") - SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - sm.checkPermission(GET_INSTANCE_PERMISSION); - } + public static RuntimeUtil getInstance() { return instance; } diff --git a/src/java.rmi/share/classes/sun/rmi/server/MarshalInputStream.java b/src/java.rmi/share/classes/sun/rmi/server/MarshalInputStream.java index 5574da072eb..30b6c47ed3d 100644 --- a/src/java.rmi/share/classes/sun/rmi/server/MarshalInputStream.java +++ b/src/java.rmi/share/classes/sun/rmi/server/MarshalInputStream.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -34,7 +34,6 @@ import java.security.AccessControlException; import java.security.Permission; import java.rmi.server.RMIClassLoader; -import java.security.PrivilegedAction; /** * MarshalInputStream is an extension of ObjectInputStream. When resolving @@ -62,12 +61,9 @@ public class MarshalInputStream extends ObjectInputStream { * The value is only false when the property is present * and is equal to "false". */ - @SuppressWarnings("removal") private static final boolean useCodebaseOnlyProperty = - ! java.security.AccessController.doPrivileged( - (PrivilegedAction<String>) () -> System.getProperty( - "java.rmi.server.useCodebaseOnly", "true")) - .equalsIgnoreCase("false"); + ! System.getProperty("java.rmi.server.useCodebaseOnly", "true") + .equalsIgnoreCase("false"); /** table to hold sun classes to which access is explicitly permitted */ protected static Map<String, Class<?>> permittedSunClasses diff --git a/src/java.rmi/share/classes/sun/rmi/server/MarshalOutputStream.java b/src/java.rmi/share/classes/sun/rmi/server/MarshalOutputStream.java index 26dae06c2d7..81bf7bf42e7 100644 --- a/src/java.rmi/share/classes/sun/rmi/server/MarshalOutputStream.java +++ b/src/java.rmi/share/classes/sun/rmi/server/MarshalOutputStream.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -58,19 +58,12 @@ public MarshalOutputStream(OutputStream out) throws IOException { /** * Creates a marshal output stream with the given protocol version. */ - @SuppressWarnings("removal") public MarshalOutputStream(OutputStream out, int protocolVersion) throws IOException { super(out); this.useProtocolVersion(protocolVersion); - java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction<Void>() { - public Void run() { - enableReplaceObject(true); - return null; - } - }); + enableReplaceObject(true); } /** diff --git a/src/java.rmi/share/classes/sun/rmi/server/UnicastRef.java b/src/java.rmi/share/classes/sun/rmi/server/UnicastRef.java index 0e41b5615b5..39ff8ce8f20 100644 --- a/src/java.rmi/share/classes/sun/rmi/server/UnicastRef.java +++ b/src/java.rmi/share/classes/sun/rmi/server/UnicastRef.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -38,8 +38,6 @@ import java.rmi.server.RemoteCall; import java.rmi.server.RemoteObject; import java.rmi.server.RemoteRef; -import java.security.AccessController; -import java.security.PrivilegedAction; import jdk.internal.access.SharedSecrets; import sun.rmi.runtime.Log; @@ -64,11 +62,9 @@ public class UnicastRef implements RemoteRef { /** * Client-side call log. */ - @SuppressWarnings("removal") public static final Log clientCallLog = Log.getLog("sun.rmi.client.call", "RMI", - AccessController.doPrivileged((PrivilegedAction<Boolean>) () -> - Boolean.getBoolean("sun.rmi.client.logCalls"))); + Boolean.getBoolean("sun.rmi.client.logCalls")); private static final long serialVersionUID = 8258372400816541186L; @SuppressWarnings("serial") // Type of field is not Serializable diff --git a/src/java.rmi/share/classes/sun/rmi/server/UnicastServerRef.java b/src/java.rmi/share/classes/sun/rmi/server/UnicastServerRef.java index 7c5b8f911f7..6263bf6d599 100644 --- a/src/java.rmi/share/classes/sun/rmi/server/UnicastServerRef.java +++ b/src/java.rmi/share/classes/sun/rmi/server/UnicastServerRef.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -48,14 +48,11 @@ import java.rmi.server.ServerRef; import java.rmi.server.Skeleton; import java.rmi.server.SkeletonNotFoundException; -import java.security.AccessController; -import java.security.PrivilegedAction; import java.util.Collections; import java.util.Date; import java.util.HashMap; import java.util.Map; import java.util.WeakHashMap; -import java.util.concurrent.atomic.AtomicInteger; import sun.rmi.runtime.Log; import sun.rmi.transport.LiveRef; import sun.rmi.transport.StreamRemoteCall; @@ -80,9 +77,7 @@ public class UnicastServerRef extends UnicastRef implements ServerRef, Dispatcher { /** value of server call log property */ - @SuppressWarnings("removal") - public static final boolean logCalls = AccessController.doPrivileged( - (PrivilegedAction<Boolean>) () -> Boolean.getBoolean("java.rmi.server.logCalls")); + public static final boolean logCalls = Boolean.getBoolean("java.rmi.server.logCalls"); /** server call log */ public static final Log callLog = @@ -92,10 +87,8 @@ public class UnicastServerRef extends UnicastRef private static final long serialVersionUID = -7384275867073752268L; /** flag to enable writing exceptions to System.err */ - @SuppressWarnings("removal") private static final boolean wantExceptionLog = - AccessController.doPrivileged((PrivilegedAction<Boolean>) () -> - Boolean.getBoolean("sun.rmi.server.exceptionTrace")); + Boolean.getBoolean("sun.rmi.server.exceptionTrace"); private boolean forceStubUse = false; @@ -103,10 +96,8 @@ public class UnicastServerRef extends UnicastRef * flag to remove server-side stack traces before marshalling * exceptions thrown by remote invocations to this VM */ - @SuppressWarnings("removal") private static final boolean suppressStackTraces = - AccessController.doPrivileged((PrivilegedAction<Boolean>) () -> - Boolean.getBoolean("sun.rmi.server.suppressStackTraces")); + Boolean.getBoolean("sun.rmi.server.suppressStackTraces"); /** * skeleton to dispatch remote calls through, for 1.1 stub protocol @@ -413,18 +404,10 @@ public void dispatch(Remote obj, RemoteCall call) throws IOException { * Sets a filter for invocation arguments, if a filter has been set. * Called by dispatch before the arguments are read. */ - @SuppressWarnings("removal") protected void unmarshalCustomCallData(ObjectInput in) throws IOException, ClassNotFoundException { - if (filter != null && - in instanceof ObjectInputStream) { - // Set the filter on the stream - ObjectInputStream ois = (ObjectInputStream) in; - - AccessController.doPrivileged((PrivilegedAction<Void>)() -> { - ois.setObjectInputFilter(filter); - return null; - }); + if (filter != null && in instanceof ObjectInputStream ois) { + ois.setObjectInputFilter(filter); } } @@ -576,7 +559,6 @@ private static class HashToMethod_Maps { HashToMethod_Maps() {} - @SuppressWarnings("removal") protected Map<Long,Method> computeValue(Class<?> remoteClass) { Map<Long,Method> map = new HashMap<>(); for (Class<?> cl = remoteClass; @@ -586,20 +568,13 @@ protected Map<Long,Method> computeValue(Class<?> remoteClass) { for (Class<?> intf : cl.getInterfaces()) { if (Remote.class.isAssignableFrom(intf)) { for (Method method : intf.getMethods()) { - final Method m = method; /* * Set this Method object to override language * access checks so that the dispatcher can invoke * methods from non-public remote interfaces. */ - AccessController.doPrivileged( - new PrivilegedAction<Void>() { - public Void run() { - m.setAccessible(true); - return null; - } - }); - map.put(Util.computeMethodHash(m), m); + method.setAccessible(true); + map.put(Util.computeMethodHash(method), method); } } } diff --git a/src/java.rmi/share/classes/sun/rmi/server/Util.java b/src/java.rmi/share/classes/sun/rmi/server/Util.java index 2c1cfe52ffe..8b9896bf2a9 100644 --- a/src/java.rmi/share/classes/sun/rmi/server/Util.java +++ b/src/java.rmi/share/classes/sun/rmi/server/Util.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -35,28 +35,20 @@ import java.rmi.Remote; import java.rmi.RemoteException; import java.rmi.StubNotFoundException; -import java.rmi.registry.Registry; import java.rmi.server.LogStream; -import java.rmi.server.ObjID; -import java.rmi.server.RMIClientSocketFactory; import java.rmi.server.RemoteObjectInvocationHandler; import java.rmi.server.RemoteRef; import java.rmi.server.RemoteStub; import java.rmi.server.Skeleton; import java.rmi.server.SkeletonNotFoundException; -import java.security.AccessController; import java.security.MessageDigest; import java.security.DigestOutputStream; import java.security.NoSuchAlgorithmException; -import java.security.PrivilegedAction; import java.util.ArrayList; import java.util.Collections; import java.util.Map; import java.util.WeakHashMap; -import sun.rmi.registry.RegistryImpl; import sun.rmi.runtime.Log; -import sun.rmi.transport.LiveRef; -import sun.rmi.transport.tcp.TCPEndpoint; /** * A utility class with static methods for creating stubs/proxies and @@ -66,20 +58,15 @@ public final class Util { /** "server" package log level */ - @SuppressWarnings("removal") - static final int logLevel = LogStream.parseLevel( - AccessController.doPrivileged( - (PrivilegedAction<String>) () -> System.getProperty("sun.rmi.server.logLevel"))); + static final int logLevel = LogStream.parseLevel(System.getProperty("sun.rmi.server.logLevel")); /** server reference log */ public static final Log serverRefLog = Log.getLog("sun.rmi.server.ref", "transport", Util.logLevel); /** cached value of property java.rmi.server.ignoreStubClasses */ - @SuppressWarnings("removal") private static final boolean ignoreStubClasses = - AccessController.doPrivileged( - (PrivilegedAction<Boolean>) () -> Boolean.getBoolean("java.rmi.server.ignoreStubClasses")); + Boolean.getBoolean("java.rmi.server.ignoreStubClasses"); /** cache of impl classes that have no corresponding stub class */ private static final Map<Class<?>, Void> withoutStubs = @@ -120,7 +107,6 @@ private Util() { * @throws StubNotFoundException if problem locating/creating stub or * creating the dynamic proxy instance **/ - @SuppressWarnings("removal") public static Remote createProxy(Class<?> implClass, RemoteRef clientRef, boolean forceStubUse) @@ -150,12 +136,7 @@ public static Remote createProxy(Class<?> implClass, /* REMIND: private remote interfaces? */ try { - return AccessController.doPrivileged(new PrivilegedAction<Remote>() { - public Remote run() { - return (Remote) Proxy.newProxyInstance(loader, - interfaces, - handler); - }}); + return (Remote) Proxy.newProxyInstance(loader, interfaces, handler); } catch (IllegalArgumentException e) { throw new StubNotFoundException("unable to create proxy", e); } diff --git a/src/java.rmi/share/classes/sun/rmi/transport/DGCAckHandler.java b/src/java.rmi/share/classes/sun/rmi/transport/DGCAckHandler.java index d02b500f2a3..4004a23fff7 100644 --- a/src/java.rmi/share/classes/sun/rmi/transport/DGCAckHandler.java +++ b/src/java.rmi/share/classes/sun/rmi/transport/DGCAckHandler.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,8 +26,6 @@ package sun.rmi.transport; import java.rmi.server.UID; -import java.security.AccessController; -import java.security.PrivilegedAction; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; @@ -64,16 +62,12 @@ public class DGCAckHandler { /** timeout for holding references without receiving an acknowledgment */ - @SuppressWarnings("removal") private static final long dgcAckTimeout = // default 5 minutes - AccessController.doPrivileged((PrivilegedAction<Long>) () -> - Long.getLong("sun.rmi.dgc.ackTimeout", 300000)); + Long.getLong("sun.rmi.dgc.ackTimeout", 300000); /** thread pool for scheduling delayed tasks */ - @SuppressWarnings("removal") private static final ScheduledExecutorService scheduler = - AccessController.doPrivileged( - new RuntimeUtil.GetInstanceAction()).getScheduler(); + RuntimeUtil.getInstance().getScheduler(); /** table mapping ack ID to handler */ private static final Map<UID,DGCAckHandler> idTable = diff --git a/src/java.rmi/share/classes/sun/rmi/transport/DGCClient.java b/src/java.rmi/share/classes/sun/rmi/transport/DGCClient.java index 7185f46201f..6bf0248f529 100644 --- a/src/java.rmi/share/classes/sun/rmi/transport/DGCClient.java +++ b/src/java.rmi/share/classes/sun/rmi/transport/DGCClient.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -27,17 +27,13 @@ import java.io.InvalidClassException; import java.lang.ref.PhantomReference; import java.lang.ref.ReferenceQueue; -import java.net.SocketPermission; import java.rmi.UnmarshalException; -import java.security.AccessController; -import java.security.PrivilegedAction; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; -import java.rmi.ConnectException; import java.rmi.RemoteException; import java.rmi.dgc.DGC; import java.rmi.dgc.Lease; @@ -49,10 +45,6 @@ import sun.rmi.server.UnicastRef; import sun.rmi.server.Util; -import java.security.AccessControlContext; -import java.security.Permissions; -import java.security.ProtectionDomain; - /** * DGCClient implements the client-side of the RMI distributed garbage * collection system. @@ -91,22 +83,16 @@ final class DGCClient { private static VMID vmid = new VMID(); /** lease duration to request (usually ignored by server) */ - @SuppressWarnings("removal") private static final long leaseValue = // default 10 minutes - AccessController.doPrivileged((PrivilegedAction<Long>) () -> - Long.getLong("java.rmi.dgc.leaseValue", 600000)); + Long.getLong("java.rmi.dgc.leaseValue", 600000); /** maximum interval between retries of failed clean calls */ - @SuppressWarnings("removal") private static final long cleanInterval = // default 3 minutes - AccessController.doPrivileged((PrivilegedAction<Long>) () -> - Long.getLong("sun.rmi.dgc.cleanInterval", 180000)); + Long.getLong("sun.rmi.dgc.cleanInterval", 180000); /** maximum interval between complete garbage collections of local heap */ - @SuppressWarnings("removal") private static final long gcInterval = // default 1 hour - AccessController.doPrivileged((PrivilegedAction<Long>) () -> - Long.getLong("sun.rmi.dgc.client.gcInterval", 3600000)); + Long.getLong("sun.rmi.dgc.client.gcInterval", 3600000); /** minimum retry count for dirty calls that fail */ private static final int dirtyFailureRetries = 5; @@ -120,21 +106,6 @@ final class DGCClient { /** ObjID for server-side DGC object */ private static final ObjID dgcID = new ObjID(ObjID.DGC_ID); - /** - * An AccessControlContext with only socket permissions, - * suitable for an RMIClientSocketFactory. - */ - @SuppressWarnings("removal") - private static final AccessControlContext SOCKET_ACC = createSocketAcc(); - - @SuppressWarnings("removal") - private static AccessControlContext createSocketAcc() { - Permissions perms = new Permissions(); - perms.add(new SocketPermission("*", "connect,resolve")); - ProtectionDomain[] pd = { new ProtectionDomain(null, perms) }; - return new AccessControlContext(pd); - } - /* * Disallow anyone from creating one of these. */ @@ -256,7 +227,6 @@ public static EndpointEntry lookup(Endpoint ep) { } } - @SuppressWarnings("removal") private EndpointEntry(final Endpoint endpoint) { this.endpoint = endpoint; try { @@ -266,9 +236,9 @@ private EndpointEntry(final Endpoint endpoint) { } catch (RemoteException e) { throw new Error("internal error creating DGC stub"); } - renewCleanThread = AccessController.doPrivileged( + renewCleanThread = new NewThreadAction(new RenewCleanThread(), - "RenewClean-" + endpoint, true)); + "RenewClean-" + endpoint, true).run(); renewCleanThread.start(); } @@ -496,20 +466,13 @@ private void makeDirtyCall(Set<RefEntry> refEntries, long sequenceNum) { * * This method must ONLY be called while synchronized on this entry. */ - @SuppressWarnings("removal") private void setRenewTime(long newRenewTime) { assert Thread.holdsLock(this); if (newRenewTime < renewTime) { renewTime = newRenewTime; if (interruptible) { - AccessController.doPrivileged( - new PrivilegedAction<Void>() { - public Void run() { - renewCleanThread.interrupt(); - return null; - } - }); + renewCleanThread.interrupt(); } } else { renewTime = newRenewTime; @@ -522,7 +485,6 @@ public Void run() { */ private class RenewCleanThread implements Runnable { - @SuppressWarnings("removal") public void run() { do { long timeToWait; @@ -601,19 +563,13 @@ public void run() { } } - boolean needRenewal_ = needRenewal; - Set<RefEntry> refsToDirty_ = refsToDirty; - long sequenceNum_ = sequenceNum; - AccessController.doPrivileged((PrivilegedAction<Void>)() -> { - if (needRenewal_) { - makeDirtyCall(refsToDirty_, sequenceNum_); - } + if (needRenewal) { + makeDirtyCall(refsToDirty, sequenceNum); + } - if (!pendingCleans.isEmpty()) { - makeCleanCalls(); - } - return null; - }, SOCKET_ACC); + if (!pendingCleans.isEmpty()) { + makeCleanCalls(); + } } while (!removed || !pendingCleans.isEmpty()); } } diff --git a/src/java.rmi/share/classes/sun/rmi/transport/DGCImpl.java b/src/java.rmi/share/classes/sun/rmi/transport/DGCImpl.java index ba73610b441..08c2eda4045 100644 --- a/src/java.rmi/share/classes/sun/rmi/transport/DGCImpl.java +++ b/src/java.rmi/share/classes/sun/rmi/transport/DGCImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,7 +25,6 @@ package sun.rmi.transport; import java.io.ObjectInputFilter; -import java.net.SocketPermission; import java.rmi.Remote; import java.rmi.RemoteException; import java.rmi.dgc.DGC; @@ -36,11 +35,6 @@ import java.rmi.server.RemoteServer; import java.rmi.server.ServerNotActiveException; import java.rmi.server.UID; -import java.security.AccessControlContext; -import java.security.AccessController; -import java.security.Permissions; -import java.security.PrivilegedAction; -import java.security.ProtectionDomain; import java.security.Security; import java.util.ArrayList; import java.util.HashSet; @@ -68,28 +62,20 @@ final class DGCImpl implements DGC { /* dgc system log */ - @SuppressWarnings("removal") static final Log dgcLog = Log.getLog("sun.rmi.dgc", "dgc", - LogStream.parseLevel(AccessController.doPrivileged( - (PrivilegedAction<String>) () -> System.getProperty("sun.rmi.dgc.logLevel")))); + LogStream.parseLevel(System.getProperty("sun.rmi.dgc.logLevel"))); /** lease duration to grant to clients */ - @SuppressWarnings("removal") private static final long leaseValue = // default 10 minutes - AccessController.doPrivileged( - (PrivilegedAction<Long>) () -> Long.getLong("java.rmi.dgc.leaseValue", 600000)); + Long.getLong("java.rmi.dgc.leaseValue", 600000); /** lease check interval; default is half of lease grant duration */ - @SuppressWarnings("removal") private static final long leaseCheckInterval = - AccessController.doPrivileged( - (PrivilegedAction<Long>) () -> Long.getLong("sun.rmi.dgc.checkInterval", leaseValue / 2)); + Long.getLong("sun.rmi.dgc.checkInterval", leaseValue / 2); /** thread pool for scheduling delayed tasks */ - @SuppressWarnings("removal") private static final ScheduledExecutorService scheduler = - AccessController.doPrivileged( - new RuntimeUtil.GetInstanceAction()).getScheduler(); + RuntimeUtil.getInstance().getScheduler(); /** remote implementation of DGC interface for this VM */ private static DGCImpl dgc; @@ -124,9 +110,7 @@ static DGCImpl getDGCImpl() { * The dgcFilter created from the value of the {@code "sun.rmi.transport.dgcFilter"} * property. */ - @SuppressWarnings("removal") - private static final ObjectInputFilter dgcFilter = - AccessController.doPrivileged((PrivilegedAction<ObjectInputFilter>)DGCImpl::initDgcFilter); + private static final ObjectInputFilter dgcFilter = initDgcFilter(); /** * Initialize the dgcFilter from the security properties or system property; if any @@ -323,59 +307,35 @@ private void checkLeases() { exportSingleton(); } - @SuppressWarnings("removal") private static void exportSingleton() { /* * "Export" the singleton DGCImpl in a context isolated from * the arbitrary current thread context. */ - AccessController.doPrivileged(new PrivilegedAction<Void>() { - public Void run() { - ClassLoader savedCcl = - Thread.currentThread().getContextClassLoader(); - try { - Thread.currentThread().setContextClassLoader( - ClassLoader.getSystemClassLoader()); - - /* - * Put remote collector object in table by hand to prevent - * listen on port. (UnicastServerRef.exportObject would - * cause transport to listen.) - */ - try { - dgc = new DGCImpl(); - ObjID dgcID = new ObjID(ObjID.DGC_ID); - LiveRef ref = new LiveRef(dgcID, 0); - UnicastServerRef disp = new UnicastServerRef(ref, - DGCImpl::checkInput); - Remote stub = - Util.createProxy(DGCImpl.class, - new UnicastRef(ref), true); - disp.setSkeleton(dgc); - - Permissions perms = new Permissions(); - perms.add(new SocketPermission("*", "accept,resolve")); - ProtectionDomain[] pd = { new ProtectionDomain(null, perms) }; - AccessControlContext acceptAcc = new AccessControlContext(pd); - - Target target = AccessController.doPrivileged( - new PrivilegedAction<Target>() { - public Target run() { - return new Target(dgc, disp, stub, dgcID, true); - } - }, acceptAcc); - - ObjectTable.putTarget(target); - } catch (RemoteException e) { - throw new Error( - "exception initializing server-side DGC", e); - } - } finally { - Thread.currentThread().setContextClassLoader(savedCcl); - } - return null; + ClassLoader savedCcl = Thread.currentThread().getContextClassLoader(); + try { + Thread.currentThread().setContextClassLoader(ClassLoader.getSystemClassLoader()); + + /* + * Put remote collector object in table by hand to prevent + * listen on port. (UnicastServerRef.exportObject would + * cause transport to listen.) + */ + try { + dgc = new DGCImpl(); + ObjID dgcID = new ObjID(ObjID.DGC_ID); + LiveRef ref = new LiveRef(dgcID, 0); + UnicastServerRef disp = new UnicastServerRef(ref, DGCImpl::checkInput); + Remote stub = Util.createProxy(DGCImpl.class, new UnicastRef(ref), true); + disp.setSkeleton(dgc); + Target target = new Target(dgc, disp, stub, dgcID, true); + ObjectTable.putTarget(target); + } catch (RemoteException e) { + throw new Error("exception initializing server-side DGC", e); } - }); + } finally { + Thread.currentThread().setContextClassLoader(savedCcl); + } } /** diff --git a/src/java.rmi/share/classes/sun/rmi/transport/DGCImpl_Stub.java b/src/java.rmi/share/classes/sun/rmi/transport/DGCImpl_Stub.java index 99880f3b3b0..c16ee9870b2 100644 --- a/src/java.rmi/share/classes/sun/rmi/transport/DGCImpl_Stub.java +++ b/src/java.rmi/share/classes/sun/rmi/transport/DGCImpl_Stub.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -33,8 +33,6 @@ import java.rmi.dgc.Lease; import java.rmi.dgc.VMID; import java.rmi.server.UID; -import java.security.AccessController; -import java.security.PrivilegedAction; import java.util.ArrayList; /** diff --git a/src/java.rmi/share/classes/sun/rmi/transport/GC.java b/src/java.rmi/share/classes/sun/rmi/transport/GC.java index 4bd50511dd4..9c76a98b955 100644 --- a/src/java.rmi/share/classes/sun/rmi/transport/GC.java +++ b/src/java.rmi/share/classes/sun/rmi/transport/GC.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,8 +25,6 @@ package sun.rmi.transport; -import java.security.AccessController; -import java.security.PrivilegedAction; import java.util.SortedSet; import java.util.TreeSet; import jdk.internal.misc.InnocuousThread; @@ -39,7 +37,7 @@ * @since 1.2 */ -@SuppressWarnings({"removal", "restricted"}) +@SuppressWarnings("restricted") class GC { private GC() { } /* To prevent instantiation */ @@ -85,11 +83,7 @@ private static class LatencyLock extends Object { }; public static native long maxObjectInspectionAge(); static { - AccessController.doPrivileged(new PrivilegedAction<Void>() { - public Void run() { - System.loadLibrary("rmi"); - return null; - }}); + System.loadLibrary("rmi"); } private static class Daemon implements Runnable { @@ -134,18 +128,12 @@ public void run() { /* Create a new daemon thread */ public static void create() { - PrivilegedAction<Void> pa = new PrivilegedAction<Void>() { - public Void run() { - Thread t = InnocuousThread.newSystemThread("RMI GC Daemon", - new Daemon()); - assert t.getContextClassLoader() == null; - t.setDaemon(true); - t.setPriority(Thread.MIN_PRIORITY + 1); - t.start(); - GC.daemon = t; - return null; - }}; - AccessController.doPrivileged(pa); + Thread t = InnocuousThread.newSystemThread("RMI GC Daemon", new Daemon()); + assert t.getContextClassLoader() == null; + t.setDaemon(true); + t.setPriority(Thread.MIN_PRIORITY + 1); + t.start(); + GC.daemon = t; } } diff --git a/src/java.rmi/share/classes/sun/rmi/transport/ObjectTable.java b/src/java.rmi/share/classes/sun/rmi/transport/ObjectTable.java index d01256f5533..dd1fcaddeab 100644 --- a/src/java.rmi/share/classes/sun/rmi/transport/ObjectTable.java +++ b/src/java.rmi/share/classes/sun/rmi/transport/ObjectTable.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -30,8 +30,6 @@ import java.rmi.dgc.VMID; import java.rmi.server.ExportException; import java.rmi.server.ObjID; -import java.security.AccessController; -import java.security.PrivilegedAction; import java.util.HashMap; import java.util.Map; import sun.rmi.runtime.Log; @@ -48,10 +46,8 @@ public final class ObjectTable { /** maximum interval between complete garbage collections of local heap */ - @SuppressWarnings("removal") private static final long gcInterval = // default 1 hour - AccessController.doPrivileged((PrivilegedAction<Long>) () -> - Long.getLong("sun.rmi.dgc.server.gcInterval", 3600000)); + Long.getLong("sun.rmi.dgc.server.gcInterval", 3600000); /** * lock guarding objTable and implTable. @@ -270,14 +266,12 @@ static void unreferenced(ObjID id, long sequenceNum, VMID vmid, * thread operates, the reaper thread also serves as the non-daemon * VM keep-alive thread; a new reaper thread is created if necessary. */ - @SuppressWarnings("removal") static void incrementKeepAliveCount() { synchronized (keepAliveLock) { keepAliveCount++; if (reaper == null) { - reaper = AccessController.doPrivileged( - new NewThreadAction(new Reaper(), "Reaper", false)); + reaper = new NewThreadAction(new Reaper(), "Reaper", false).run(); reaper.start(); } @@ -307,19 +301,13 @@ static void incrementKeepAliveCount() { * reaper thread is terminated to cease keeping the VM alive (and * because there are no more non-permanent remote objects to reap). */ - @SuppressWarnings("removal") static void decrementKeepAliveCount() { synchronized (keepAliveLock) { keepAliveCount--; if (keepAliveCount == 0) { if (!(reaper != null)) { throw new AssertionError(); } - AccessController.doPrivileged(new PrivilegedAction<Void>() { - public Void run() { - reaper.interrupt(); - return null; - } - }); + reaper.interrupt(); reaper = null; /* diff --git a/src/java.rmi/share/classes/sun/rmi/transport/StreamRemoteCall.java b/src/java.rmi/share/classes/sun/rmi/transport/StreamRemoteCall.java index 8df144d086d..0cff2c33ce9 100644 --- a/src/java.rmi/share/classes/sun/rmi/transport/StreamRemoteCall.java +++ b/src/java.rmi/share/classes/sun/rmi/transport/StreamRemoteCall.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -37,8 +37,6 @@ import java.rmi.UnmarshalException; import java.rmi.server.ObjID; import java.rmi.server.RemoteCall; -import java.security.AccessController; -import java.security.PrivilegedAction; import sun.rmi.runtime.Log; import sun.rmi.server.UnicastRef; @@ -139,17 +137,13 @@ public void setObjectInputFilter(ObjectInputFilter filter) { * Get the InputStream the stub/skeleton should get results/arguments * from. */ - @SuppressWarnings("removal") public ObjectInput getInputStream() throws IOException { if (in == null) { Transport.transportLog.log(Log.VERBOSE, "getting input stream"); in = new ConnectionInputStream(conn.getInputStream()); if (filter != null) { - AccessController.doPrivileged((PrivilegedAction<Void>) () -> { - in.setObjectInputFilter(filter); - return null; - }); + in.setObjectInputFilter(filter); } } return in; diff --git a/src/java.rmi/share/classes/sun/rmi/transport/Target.java b/src/java.rmi/share/classes/sun/rmi/transport/Target.java index c0d79bb38e2..3ea404698f2 100644 --- a/src/java.rmi/share/classes/sun/rmi/transport/Target.java +++ b/src/java.rmi/share/classes/sun/rmi/transport/Target.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -29,9 +29,6 @@ import java.rmi.dgc.VMID; import java.rmi.server.ObjID; import java.rmi.server.Unreferenced; -import java.security.AccessControlContext; -import java.security.AccessController; -import java.security.PrivilegedAction; import java.util.*; import sun.rmi.runtime.Log; import sun.rmi.runtime.NewThreadAction; @@ -58,9 +55,6 @@ public final class Target { /** table that maps client endpoints to sequence numbers */ private final Hashtable<VMID, SequenceEntry> sequenceTable = new Hashtable<>(5); - /** access control context in which target was created */ - @SuppressWarnings("removal") - private final AccessControlContext acc; /** context class loader in which target was created */ private final ClassLoader ccl; /** number of pending/executing calls */ @@ -86,7 +80,6 @@ public final class Target { * collection. Permanent objects do not keep a server from * exiting. */ - @SuppressWarnings("removal") public Target(Remote impl, Dispatcher disp, Remote stub, ObjID id, boolean permanent) { @@ -94,7 +87,6 @@ public Target(Remote impl, Dispatcher disp, Remote stub, ObjID id, this.disp = disp; this.stub = stub; this.id = id; - this.acc = AccessController.getContext(); /* * Fix for 4149366: so that downloaded parameter types unmarshalled @@ -177,11 +169,6 @@ Dispatcher getDispatcher() { return disp; } - @SuppressWarnings("removal") - AccessControlContext getAccessControlContext() { - return acc; - } - ClassLoader getContextClassLoader() { return ccl; } @@ -307,7 +294,6 @@ synchronized void unreferenced(long sequenceNum, VMID vmid, boolean strong) /** * Remove endpoint from the reference set. */ - @SuppressWarnings("removal") private synchronized void refSetRemove(VMID vmid) { // remove notification request DGCImpl.getDGCImpl().unregisterTarget(vmid, this); @@ -325,17 +311,12 @@ private synchronized void refSetRemove(VMID vmid) { * invoke its unreferenced callback in a separate thread. */ Remote obj = getImpl(); - if (obj instanceof Unreferenced) { - final Unreferenced unrefObj = (Unreferenced) obj; - AccessController.doPrivileged( - new NewThreadAction(() -> { - Thread.currentThread().setContextClassLoader(ccl); - AccessController.doPrivileged((PrivilegedAction<Void>) () -> { - unrefObj.unreferenced(); - return null; - }, acc); - }, "Unreferenced-" + nextThreadNum++, false, true)).start(); - // REMIND: access to nextThreadNum not synchronized; you care? + if (obj instanceof Unreferenced unrefObj) { + new NewThreadAction(() -> { + Thread.currentThread().setContextClassLoader(ccl); + unrefObj.unreferenced(); + }, "Unreferenced-" + nextThreadNum++, false, true).run().start(); + // REMIND: access to nextThreadNum not synchronized; you care? } unpinImpl(); diff --git a/src/java.rmi/share/classes/sun/rmi/transport/Transport.java b/src/java.rmi/share/classes/sun/rmi/transport/Transport.java index 4589f913dd3..b6174517180 100644 --- a/src/java.rmi/share/classes/sun/rmi/transport/Transport.java +++ b/src/java.rmi/share/classes/sun/rmi/transport/Transport.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -36,11 +36,6 @@ import java.rmi.server.RemoteCall; import java.rmi.server.RemoteServer; import java.rmi.server.ServerNotActiveException; -import java.security.AccessControlContext; -import java.security.AccessController; -import java.security.Permissions; -import java.security.PrivilegedAction; -import java.security.ProtectionDomain; import sun.rmi.runtime.Log; import sun.rmi.server.Dispatcher; import sun.rmi.server.UnicastServerRef; @@ -51,15 +46,14 @@ * * @author Ann Wollrath */ -@SuppressWarnings({"removal","deprecation"}) +@SuppressWarnings({"deprecation"}) public abstract class Transport { /** "transport" package log level */ static final int logLevel = LogStream.parseLevel(getLogLevel()); private static String getLogLevel() { - return java.security.AccessController.doPrivileged( - (PrivilegedAction<String>) () -> System.getProperty("sun.rmi.transport.logLevel")); + return System.getProperty("sun.rmi.transport.logLevel"); } /* transport package log */ @@ -72,15 +66,6 @@ private static String getLogLevel() { /** ObjID for DGCImpl */ private static final ObjID dgcID = new ObjID(ObjID.DGC_ID); - /** AccessControlContext for setting context ClassLoader */ - private static final AccessControlContext SETCCL_ACC; - static { - Permissions perms = new Permissions(); - perms.add(new RuntimePermission("setContextClassLoader")); - ProtectionDomain[] pd = { new ProtectionDomain(null, perms) }; - SETCCL_ACC = new AccessControlContext(pd); - } - /** * Returns a <I>Channel</I> that generates connections to the * endpoint <I>ep</I>. A Channel is an object that creates and @@ -121,22 +106,11 @@ static Transport currentTransport() { return currentTransport.get(); } - /** - * Verify that the current access control context has permission to accept - * the connection being dispatched by the current thread. The current - * access control context is passed as a parameter to avoid the overhead of - * an additional call to AccessController.getContext. - */ - protected abstract void checkAcceptPermission(AccessControlContext acc); - /** * Sets the context class loader for the current thread. */ private static void setContextClassLoader(ClassLoader ccl) { - AccessController.doPrivileged((PrivilegedAction<Void>)() -> { - Thread.currentThread().setContextClassLoader(ccl); - return null; - }, SETCCL_ACC); + Thread.currentThread().setContextClassLoader(ccl); } /** @@ -183,27 +157,13 @@ public boolean serviceCall(final RemoteCall call) { /* call the dispatcher */ transportLog.log(Log.VERBOSE, "call dispatcher"); - final AccessControlContext acc = - target.getAccessControlContext(); ClassLoader ccl = target.getContextClassLoader(); - ClassLoader savedCcl = Thread.currentThread().getContextClassLoader(); try { if (ccl != savedCcl) setContextClassLoader(ccl); currentTransport.set(this); - try { - java.security.AccessController.doPrivileged( - new java.security.PrivilegedExceptionAction<Void>() { - public Void run() throws IOException { - checkAcceptPermission(acc); - disp.dispatch(impl, call); - return null; - } - }, acc); - } catch (java.security.PrivilegedActionException pae) { - throw (IOException) pae.getException(); - } + disp.dispatch(impl, call); } finally { if (ccl != savedCcl) setContextClassLoader(savedCcl); currentTransport.set(null); diff --git a/src/java.rmi/share/classes/sun/rmi/transport/tcp/TCPChannel.java b/src/java.rmi/share/classes/sun/rmi/transport/tcp/TCPChannel.java index 013fc1606af..91ef41d3e49 100644 --- a/src/java.rmi/share/classes/sun/rmi/transport/tcp/TCPChannel.java +++ b/src/java.rmi/share/classes/sun/rmi/transport/tcp/TCPChannel.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -27,18 +27,12 @@ import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; -import java.lang.ref.Reference; -import java.lang.ref.SoftReference; import java.net.Socket; import java.rmi.ConnectIOException; import java.rmi.RemoteException; -import java.security.AccessControlContext; -import java.security.AccessController; -import java.security.PrivilegedAction; import java.util.ArrayList; import java.util.List; import java.util.ListIterator; -import java.util.WeakHashMap; import java.util.concurrent.Future; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; @@ -70,42 +64,21 @@ public class TCPChannel implements Channel { /** connection acceptor (should be in TCPTransport) */ private ConnectionAcceptor acceptor; - /** most recently authorized AccessControlContext */ - @SuppressWarnings("removal") - private AccessControlContext okContext; - - /** cache of authorized AccessControlContexts */ - @SuppressWarnings("removal") - private WeakHashMap<AccessControlContext, - Reference<AccessControlContext>> authcache; - - /** the SecurityManager which authorized okContext and authcache */ - @SuppressWarnings("removal") - private SecurityManager cacheSecurityManager = null; - /** client-side connection idle usage timeout */ - @SuppressWarnings("removal") private static final long idleTimeout = // default 15 seconds - AccessController.doPrivileged((PrivilegedAction<Long>) () -> - Long.getLong("sun.rmi.transport.connectionTimeout", 15000)); + Long.getLong("sun.rmi.transport.connectionTimeout", 15000); /** client-side connection handshake read timeout */ - @SuppressWarnings("removal") private static final int handshakeTimeout = // default 1 minute - AccessController.doPrivileged((PrivilegedAction<Integer>) () -> - Integer.getInteger("sun.rmi.transport.tcp.handshakeTimeout", 60000)); + Integer.getInteger("sun.rmi.transport.tcp.handshakeTimeout", 60000); /** client-side connection response read timeout (after handshake) */ - @SuppressWarnings("removal") private static final int responseTimeout = // default infinity - AccessController.doPrivileged((PrivilegedAction<Integer>) () -> - Integer.getInteger("sun.rmi.transport.tcp.responseTimeout", 0)); + Integer.getInteger("sun.rmi.transport.tcp.responseTimeout", 0); /** thread pool for scheduling delayed tasks */ - @SuppressWarnings("removal") private static final ScheduledExecutorService scheduler = - AccessController.doPrivileged( - new RuntimeUtil.GetInstanceAction()).getScheduler(); + RuntimeUtil.getInstance().getScheduler(); /** * Create channel for endpoint. @@ -122,41 +95,6 @@ public Endpoint getEndpoint() { return ep; } - /** - * Checks if the current caller has sufficient privilege to make - * a connection to the remote endpoint. - * @exception SecurityException if caller is not allowed to use this - * Channel. - */ - @SuppressWarnings("removal") - private void checkConnectPermission() throws SecurityException { - SecurityManager security = System.getSecurityManager(); - if (security == null) - return; - - if (security != cacheSecurityManager) { - // The security manager changed: flush the cache - okContext = null; - authcache = new WeakHashMap<AccessControlContext, - Reference<AccessControlContext>>(); - cacheSecurityManager = security; - } - - AccessControlContext ctx = AccessController.getContext(); - - // If ctx is the same context as last time, or if it - // appears in the cache, bypass the checkConnect. - if (okContext == null || - !(okContext.equals(ctx) || authcache.containsKey(ctx))) - { - security.checkConnect(ep.getHost(), ep.getPort()); - authcache.put(ctx, new SoftReference<AccessControlContext>(ctx)); - // A WeakHashMap is transformed into a SoftHashSet by making - // each value softly refer to its own key (Peter's idea). - } - okContext = ctx; - } - /** * Supplies a connection to the endpoint of the address space * for which this is a channel. The returned connection may @@ -175,10 +113,6 @@ public Connection newConnection() throws RemoteException { int elementPos = freeList.size()-1; if (elementPos >= 0) { - // If there is a security manager, make sure - // the caller is allowed to connect to the - // requested endpoint. - checkConnectPermission(); conn = freeList.get(elementPos); freeList.remove(elementPos); } @@ -467,11 +401,9 @@ public ConnectionAcceptor(TCPTransport transport) { * Start a new thread to accept connections. */ public void startNewAcceptor() { - @SuppressWarnings("removal") - Thread t = AccessController.doPrivileged( - new NewThreadAction(ConnectionAcceptor.this, - "TCPChannel Accept-" + ++ threadNum, - true)); + Thread t = new NewThreadAction(ConnectionAcceptor.this, + "TCPChannel Accept-" + ++ threadNum, + true).run(); t.start(); } diff --git a/src/java.rmi/share/classes/sun/rmi/transport/tcp/TCPEndpoint.java b/src/java.rmi/share/classes/sun/rmi/transport/tcp/TCPEndpoint.java index b2c0f189845..4eb1a35a95e 100644 --- a/src/java.rmi/share/classes/sun/rmi/transport/tcp/TCPEndpoint.java +++ b/src/java.rmi/share/classes/sun/rmi/transport/tcp/TCPEndpoint.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -38,8 +38,6 @@ import java.rmi.server.RMIClientSocketFactory; import java.rmi.server.RMIServerSocketFactory; import java.rmi.server.RMISocketFactory; -import java.security.AccessController; -import java.security.PrivilegedAction; import java.util.Collection; import java.util.HashMap; import java.util.HashSet; @@ -79,27 +77,19 @@ public class TCPEndpoint implements Endpoint { /** true if real local host name is known yet */ private static boolean localHostKnown; - // this should be a *private* method since it is privileged - @SuppressWarnings("removal") private static int getInt(String name, int def) { - return AccessController.doPrivileged( - (PrivilegedAction<Integer>) () -> Integer.getInteger(name, def)); + return Integer.getInteger(name, def); } - // this should be a *private* method since it is privileged - @SuppressWarnings("removal") private static boolean getBoolean(String name) { - return AccessController.doPrivileged( - (PrivilegedAction<Boolean>) () -> Boolean.getBoolean(name)); + return Boolean.getBoolean(name); } /** * Returns the value of the java.rmi.server.hostname property. */ - @SuppressWarnings("removal") private static String getHostnameProperty() { - return AccessController.doPrivileged( - (PrivilegedAction<String>) () -> System.getProperty("java.rmi.server.hostname")); + return System.getProperty("java.rmi.server.hostname"); } /** @@ -762,9 +752,7 @@ static String attemptFQDN(InetAddress localAddr) private void getFQDN() { /* FQDN finder will run in RMI threadgroup. */ - @SuppressWarnings("removal") - Thread t = AccessController.doPrivileged( - new NewThreadAction(FQDN.this, "FQDN Finder", true)); + Thread t = new NewThreadAction(FQDN.this, "FQDN Finder", true).run(); t.start(); } diff --git a/src/java.rmi/share/classes/sun/rmi/transport/tcp/TCPTransport.java b/src/java.rmi/share/classes/sun/rmi/transport/tcp/TCPTransport.java index dba0f9f8f60..9695fcac274 100644 --- a/src/java.rmi/share/classes/sun/rmi/transport/tcp/TCPTransport.java +++ b/src/java.rmi/share/classes/sun/rmi/transport/tcp/TCPTransport.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,7 +25,6 @@ package sun.rmi.transport.tcp; import java.lang.ref.Reference; -import java.lang.ref.SoftReference; import java.lang.ref.WeakReference; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.UndeclaredThrowableException; @@ -47,11 +46,6 @@ import java.rmi.server.RemoteCall; import java.rmi.server.ServerNotActiveException; import java.rmi.server.UID; -import java.security.AccessControlContext; -import java.security.AccessController; -import java.security.Permissions; -import java.security.PrivilegedAction; -import java.security.ProtectionDomain; import java.util.ArrayList; import java.util.LinkedList; import java.util.List; @@ -67,7 +61,6 @@ import java.util.concurrent.atomic.AtomicInteger; import sun.rmi.runtime.Log; import sun.rmi.runtime.NewThreadAction; -import sun.rmi.transport.Channel; import sun.rmi.transport.Connection; import sun.rmi.transport.DGCAckHandler; import sun.rmi.transport.Endpoint; @@ -87,23 +80,16 @@ public class TCPTransport extends Transport { /* tcp package log */ - @SuppressWarnings("removal") static final Log tcpLog = Log.getLog("sun.rmi.transport.tcp", "tcp", - LogStream.parseLevel(AccessController.doPrivileged( - (PrivilegedAction<String>) () -> System.getProperty("sun.rmi.transport.tcp.logLevel")))); + LogStream.parseLevel(System.getProperty("sun.rmi.transport.tcp.logLevel"))); /** maximum number of connection handler threads */ - @SuppressWarnings("removal") private static final int maxConnectionThreads = // default no limit - AccessController.doPrivileged((PrivilegedAction<Integer>) () -> - Integer.getInteger("sun.rmi.transport.tcp.maxConnectionThreads", - Integer.MAX_VALUE)); + Integer.getInteger("sun.rmi.transport.tcp.maxConnectionThreads", Integer.MAX_VALUE); /** keep alive time for idle connection handler threads */ - @SuppressWarnings("removal") private static final long threadKeepAliveTime = // default 1 minute - AccessController.doPrivileged((PrivilegedAction<Long>) () -> - Long.getLong("sun.rmi.transport.tcp.threadKeepAliveTime", 60000)); + Long.getLong("sun.rmi.transport.tcp.threadKeepAliveTime", 60000); /** thread pool for connection handlers */ private static final ExecutorService connectionThreadPool = @@ -111,10 +97,9 @@ public class TCPTransport extends Transport { threadKeepAliveTime, TimeUnit.MILLISECONDS, new SynchronousQueue<Runnable>(), new ThreadFactory() { - @SuppressWarnings("removal") public Thread newThread(Runnable runnable) { - return AccessController.doPrivileged(new NewThreadAction( - runnable, "TCP Connection(idle)", true, true)); + return new NewThreadAction( + runnable, "TCP Connection(idle)", true, true).run(); } }); @@ -125,17 +110,6 @@ public Thread newThread(Runnable runnable) { private static final ThreadLocal<ConnectionHandler> threadConnectionHandler = new ThreadLocal<>(); - /** an AccessControlContext with no permissions */ - @SuppressWarnings("removal") - private static final AccessControlContext NOPERMS_ACC = createNopermsAcc(); - - @SuppressWarnings("removal") - private static AccessControlContext createNopermsAcc() { - Permissions perms = new Permissions(); - ProtectionDomain[] pd = { new ProtectionDomain(null, perms) }; - return new AccessControlContext(pd); - } - /** endpoints for this transport */ private final LinkedList<TCPEndpoint> epList; /** number of objects exported on this transport */ @@ -149,16 +123,15 @@ private static AccessControlContext createNopermsAcc() { static final RMISocketFactory defaultSocketFactory = RMISocketFactory.getDefaultSocketFactory(); - /** number of milliseconds in accepted-connection timeout. + /** + * Number of milliseconds in accepted-connection timeout. * Warning: this should be greater than 15 seconds (the client-side * timeout), and defaults to 2 hours. * The maximum representable value is slightly more than 24 days * and 20 hours. */ - @SuppressWarnings("removal") private static final int connectionReadTimeout = // default 2 hours - AccessController.doPrivileged((PrivilegedAction<Integer>) () -> - Integer.getInteger("sun.rmi.transport.tcp.readTimeout", 2 * 3600 * 1000)); + Integer.getInteger("sun.rmi.transport.tcp.readTimeout", 2 * 3600 * 1000); /** * Constructs a TCPTransport. @@ -302,24 +275,6 @@ private void decrementExportCount() { } } - /** - * Verify that the current access control context has permission to - * accept the connection being dispatched by the current thread. - */ - protected void checkAcceptPermission(@SuppressWarnings("removal") AccessControlContext acc) { - @SuppressWarnings("removal") - SecurityManager sm = System.getSecurityManager(); - if (sm == null) { - return; - } - ConnectionHandler h = threadConnectionHandler.get(); - if (h == null) { - throw new Error( - "checkAcceptPermission not in ConnectionHandler thread"); - } - h.checkAcceptPermission(sm, acc); - } - private TCPEndpoint getEndpoint() { synchronized (epList) { return epList.getLast(); @@ -327,7 +282,8 @@ private TCPEndpoint getEndpoint() { } /** - * Listen on transport's endpoint. + * Listen on transport's endpoint. Do nothing if a server socket + * and listening thread already exist. */ private void listen() throws RemoteException { assert Thread.holdsLock(this); @@ -347,24 +303,14 @@ private void listen() throws RemoteException { * "port in use" will cause export to hang if an * RMIFailureHandler is not installed. */ - @SuppressWarnings("removal") - Thread t = AccessController.doPrivileged( - new NewThreadAction(new AcceptLoop(server), - "TCP Accept-" + port, true)); + Thread t = new NewThreadAction(new AcceptLoop(server), + "TCP Accept-" + port, true).run(); t.start(); } catch (java.net.BindException e) { throw new ExportException("Port already in use: " + port, e); } catch (IOException e) { throw new ExportException("Listen failed on port: " + port, e); } - - } else { - // otherwise verify security access to existing server socket - @SuppressWarnings("removal") - SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - sm.checkListen(port); - } } } @@ -656,17 +602,6 @@ private class ConnectionHandler implements Runnable { * make this once-reviled tactic again socially acceptable) */ private static final int POST = 0x504f5354; - /** most recently accept-authorized AccessControlContext */ - @SuppressWarnings("removal") - private AccessControlContext okContext; - /** cache of accept-authorized AccessControlContexts */ - @SuppressWarnings("removal") - private Map<AccessControlContext, - Reference<AccessControlContext>> authCache; - /** security manager which authorized contexts in authCache */ - @SuppressWarnings("removal") - private SecurityManager cacheSecurityManager = null; - private Socket socket; private String remoteHost; @@ -679,37 +614,6 @@ String getClientHost() { return remoteHost; } - /** - * Verify that the given AccessControlContext has permission to - * accept this connection. - */ - @SuppressWarnings("removal") - void checkAcceptPermission(SecurityManager sm, - AccessControlContext acc) - { - /* - * Note: no need to synchronize on cache-related fields, since this - * method only gets called from the ConnectionHandler's thread. - */ - if (sm != cacheSecurityManager) { - okContext = null; - authCache = new WeakHashMap<AccessControlContext, - Reference<AccessControlContext>>(); - cacheSecurityManager = sm; - } - if (acc.equals(okContext) || authCache.containsKey(acc)) { - return; - } - InetAddress addr = socket.getInetAddress(); - String host = (addr != null) ? addr.getHostAddress() : "*"; - - sm.checkAccept(host, socket.getPort()); - - authCache.put(acc, new SoftReference<AccessControlContext>(acc)); - okContext = acc; - } - - @SuppressWarnings("removal") public void run() { Thread t = Thread.currentThread(); String name = t.getName(); @@ -717,10 +621,7 @@ public void run() { t.setName("RMI TCP Connection(" + connectionCount.incrementAndGet() + ")-" + remoteHost); - AccessController.doPrivileged((PrivilegedAction<Void>)() -> { - run0(); - return null; - }, NOPERMS_ACC); + run0(); } finally { t.setName(name); } From 3328b4ecf225f95edfce6ab848dcfb62ddc1aaff Mon Sep 17 00:00:00 2001 From: Sonia Zaldana Calles <szaldana@openjdk.org> Date: Tue, 19 Nov 2024 19:13:09 +0000 Subject: [PATCH 106/311] 8343700: ceil_log2 should not loop endlessly Reviewed-by: shade, kbarrett, aph, stuefe --- src/hotspot/share/classfile/dictionary.cpp | 2 +- src/hotspot/share/utilities/powerOfTwo.hpp | 9 ++-- .../gtest/utilities/test_powerOfTwo.cpp | 43 ++++++++++++++++++- 3 files changed, 47 insertions(+), 7 deletions(-) diff --git a/src/hotspot/share/classfile/dictionary.cpp b/src/hotspot/share/classfile/dictionary.cpp index 73d58ac3687..92f362860eb 100644 --- a/src/hotspot/share/classfile/dictionary.cpp +++ b/src/hotspot/share/classfile/dictionary.cpp @@ -44,7 +44,7 @@ const size_t REHASH_LEN = 100; Dictionary::Dictionary(ClassLoaderData* loader_data, size_t table_size) : _number_of_entries(0), _loader_data(loader_data) { - size_t start_size_log_2 = MAX2(ceil_log2(table_size), (size_t)2); // 2 is minimum size even though some dictionaries only have one entry + size_t start_size_log_2 = MAX2(ceil_log2(table_size), 2); // 2 is minimum size even though some dictionaries only have one entry size_t current_size = ((size_t)1) << start_size_log_2; log_info(class, loader, data)("Dictionary start size: " SIZE_FORMAT " (" SIZE_FORMAT ")", current_size, start_size_log_2); diff --git a/src/hotspot/share/utilities/powerOfTwo.hpp b/src/hotspot/share/utilities/powerOfTwo.hpp index 786977a347f..6c1e413f403 100644 --- a/src/hotspot/share/utilities/powerOfTwo.hpp +++ b/src/hotspot/share/utilities/powerOfTwo.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -122,10 +122,9 @@ inline T next_power_of_2(T value) { // Find log2 value greater than this input template <typename T, ENABLE_IF(std::is_integral<T>::value)> -inline T ceil_log2(T value) { - T ret; - for (ret = 1; ((T)1 << ret) < value; ++ret); - return ret; +inline int ceil_log2(T value) { + assert(value > 0, "Invalid value"); + return log2i_graceful(value - 1) + 1; } // Return the largest power of two that is a submultiple of the given value. diff --git a/test/hotspot/gtest/utilities/test_powerOfTwo.cpp b/test/hotspot/gtest/utilities/test_powerOfTwo.cpp index 4d16e13ab31..fc4080bcefd 100644 --- a/test/hotspot/gtest/utilities/test_powerOfTwo.cpp +++ b/test/hotspot/gtest/utilities/test_powerOfTwo.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -305,3 +305,44 @@ TEST(power_of_2, log2i) { check_log2i_variants_for((uint)0); check_log2i_variants_for((jlong)0); } + +template <typename T> void test_ceil_log2() { + EXPECT_EQ(ceil_log2(T(1)), 0) << "value = " << T(1); + EXPECT_EQ(ceil_log2(T(2)), 1) << "value = " << T(2); + EXPECT_EQ(ceil_log2(T(3)), 2) << "value = " << T(3); + EXPECT_EQ(ceil_log2(T(4)), 2) << "value = " << T(4); + EXPECT_EQ(ceil_log2(T(5)), 3) << "value = " << T(5); + EXPECT_EQ(ceil_log2(T(6)), 3) << "value = " << T(6); + EXPECT_EQ(ceil_log2(T(7)), 3) << "value = " << T(7); + EXPECT_EQ(ceil_log2(T(8)), 3) << "value = " << T(8); + EXPECT_EQ(ceil_log2(T(9)), 4) << "value = " << T(9); + EXPECT_EQ(ceil_log2(T(10)), 4) << "value = " << T(10); + + // Test max values + if (std::is_unsigned<T>::value) { + EXPECT_EQ(ceil_log2(std::numeric_limits<T>::max()), + (int)(sizeof(T) * 8)) << "value = " << std::numeric_limits<T>::max(); + } else { + EXPECT_EQ(ceil_log2(std::numeric_limits<T>::max()), + (int)(sizeof(T) * 8 - 1)) << "value = " << std::numeric_limits<T>::max(); + } +} + +TEST(power_of_2, ceil_log2) { + test_ceil_log2<int8_t>(); + test_ceil_log2<int16_t>(); + test_ceil_log2<int32_t>(); + test_ceil_log2<int64_t>(); + test_ceil_log2<uint8_t>(); + test_ceil_log2<uint16_t>(); + test_ceil_log2<uint32_t>(); + test_ceil_log2<uint64_t>(); +} + +#ifdef ASSERT +TEST_VM_ASSERT_MSG(power_of_2, ceil_log2_invalid, + ".*Invalid value") { + ceil_log2(0); +} + +#endif // ASSERT From 69c9f2566ea36fa3317d762d4498637489c70c45 Mon Sep 17 00:00:00 2001 From: Phil Race <prr@openjdk.org> Date: Tue, 19 Nov 2024 19:35:28 +0000 Subject: [PATCH 107/311] 8344061: Remove doPrivileged calls from shared implementation code in the java.desktop module : part 2 Reviewed-by: aivanov --- .../classes/sun/awt/AWTAutoShutdown.java | 18 +- .../share/classes/sun/awt/AppContext.java | 192 ++---- .../classes/sun/awt/CausedFocusEvent.java | 19 +- .../share/classes/sun/awt/DebugSettings.java | 13 +- .../classes/sun/awt/FontConfiguration.java | 37 +- .../share/classes/sun/awt/FontDescriptor.java | 5 +- .../classes/sun/awt/NativeLibLoader.java | 10 +- .../sun/awt/datatransfer/DataTransferer.java | 83 +-- .../awt/datatransfer/TransferableProxy.java | 20 +- .../awt/im/ExecutableInputMethodManager.java | 31 +- .../classes/sun/awt/im/InputContext.java | 26 +- .../sun/awt/im/InputMethodContext.java | 5 +- .../classes/sun/font/CreatedFontTracker.java | 30 +- .../share/classes/sun/font/FileFont.java | 99 +-- .../sun/font/FontManagerNativeLibrary.java | 47 +- .../share/classes/sun/font/FontUtilities.java | 104 ++-- .../share/classes/sun/font/StrikeCache.java | 50 +- .../classes/sun/font/SunFontManager.java | 572 ++++++++---------- .../classes/sun/font/SunLayoutEngine.java | 7 +- .../share/classes/sun/font/TrueTypeFont.java | 22 +- .../share/classes/sun/font/Type1Font.java | 47 +- 21 files changed, 521 insertions(+), 916 deletions(-) diff --git a/src/java.desktop/share/classes/sun/awt/AWTAutoShutdown.java b/src/java.desktop/share/classes/sun/awt/AWTAutoShutdown.java index bb7fb64f7f1..e944d19e1c1 100644 --- a/src/java.desktop/share/classes/sun/awt/AWTAutoShutdown.java +++ b/src/java.desktop/share/classes/sun/awt/AWTAutoShutdown.java @@ -26,8 +26,6 @@ package sun.awt; import java.awt.AWTEvent; -import java.security.AccessController; -import java.security.PrivilegedAction; import java.util.HashSet; import java.util.IdentityHashMap; import java.util.Map; @@ -333,17 +331,13 @@ static AWTEvent getShutdownEvent() { * Creates and starts a new blocker thread. Doesn't return until * the new blocker thread starts. */ - @SuppressWarnings("removal") private void activateBlockerThread() { - AccessController.doPrivileged((PrivilegedAction<Thread>) () -> { - String name = "AWT-Shutdown"; - Thread thread = new Thread( - ThreadGroupUtils.getRootThreadGroup(), this, name, 0, false); - thread.setContextClassLoader(null); - thread.setDaemon(false); - blockerThread = thread; - return thread; - }).start(); + String name = "AWT-Shutdown"; + Thread thread = new Thread(ThreadGroupUtils.getRootThreadGroup(), this, name, 0, false); + thread.setContextClassLoader(null); + thread.setDaemon(false); + blockerThread = thread; + thread.start(); try { /* Wait for the blocker thread to start. */ mainLock.wait(); diff --git a/src/java.desktop/share/classes/sun/awt/AppContext.java b/src/java.desktop/share/classes/sun/awt/AppContext.java index fa098af556d..48482dfc39a 100644 --- a/src/java.desktop/share/classes/sun/awt/AppContext.java +++ b/src/java.desktop/share/classes/sun/awt/AppContext.java @@ -32,8 +32,6 @@ import java.awt.Toolkit; import java.awt.GraphicsEnvironment; import java.awt.event.InvocationEvent; -import java.security.AccessController; -import java.security.PrivilegedAction; import java.util.Collections; import java.util.HashMap; import java.util.IdentityHashMap; @@ -229,20 +227,13 @@ public boolean isDisposed() { * @see sun.awt.SunToolkit * @since 1.2 */ - @SuppressWarnings("removal") AppContext(ThreadGroup threadGroup) { numAppContexts.incrementAndGet(); this.threadGroup = threadGroup; threadGroup2appContext.put(threadGroup, this); - this.contextClassLoader = - AccessController.doPrivileged(new PrivilegedAction<ClassLoader>() { - public ClassLoader run() { - return Thread.currentThread().getContextClassLoader(); - } - }); - + this.contextClassLoader = Thread.currentThread().getContextClassLoader(); // Initialize push/pop lock and its condition to be used by all the // EventQueues within this AppContext Lock eventQueuePushPopLock = new ReentrantLock(); @@ -254,26 +245,19 @@ public ClassLoader run() { private static final ThreadLocal<AppContext> threadAppContext = new ThreadLocal<AppContext>(); - @SuppressWarnings("removal") private static void initMainAppContext() { // On the main Thread, we get the ThreadGroup, make a corresponding // AppContext, and instantiate the Java EventQueue. This way, legacy // code is unaffected by the move to multiple AppContext ability. - AccessController.doPrivileged(new PrivilegedAction<Void>() { - public Void run() { - ThreadGroup currentThreadGroup = - Thread.currentThread().getThreadGroup(); - ThreadGroup parentThreadGroup = currentThreadGroup.getParent(); - while (parentThreadGroup != null) { - // Find the root ThreadGroup to construct our main AppContext - currentThreadGroup = parentThreadGroup; - parentThreadGroup = currentThreadGroup.getParent(); - } + ThreadGroup currentThreadGroup = Thread.currentThread().getThreadGroup(); + ThreadGroup parentThreadGroup = currentThreadGroup.getParent(); + while (parentThreadGroup != null) { + // Find the root ThreadGroup to construct our main AppContext + currentThreadGroup = parentThreadGroup; + parentThreadGroup = currentThreadGroup.getParent(); + } - mainAppContext = SunToolkit.createNewAppContext(currentThreadGroup); - return null; - } - }); + mainAppContext = SunToolkit.createNewAppContext(currentThreadGroup); } /** @@ -284,7 +268,6 @@ public Void run() { * @see java.lang.ThreadGroup * @since 1.2 */ - @SuppressWarnings("removal") public static AppContext getAppContext() { // we are standalone app, return the main app context if (numAppContexts.get() == 1 && mainAppContext != null) { @@ -294,69 +277,53 @@ public static AppContext getAppContext() { AppContext appContext = threadAppContext.get(); if (null == appContext) { - appContext = AccessController.doPrivileged(new PrivilegedAction<AppContext>() - { - public AppContext run() { - // Get the current ThreadGroup, and look for it and its - // parents in the hash from ThreadGroup to AppContext -- - // it should be found, because we use createNewContext() - // when new AppContext objects are created. - ThreadGroup currentThreadGroup = Thread.currentThread().getThreadGroup(); - ThreadGroup threadGroup = currentThreadGroup; - - // Special case: we implicitly create the main app context - // if no contexts have been created yet. This covers standalone apps - // and excludes applets because by the time applet starts - // a number of contexts have already been created by the plugin. - synchronized (getAppContextLock) { - if (numAppContexts.get() == 0) { - if (System.getProperty("javaplugin.version") == null && - System.getProperty("javawebstart.version") == null) { - initMainAppContext(); - } else if (System.getProperty("javafx.version") != null && - threadGroup.getParent() != null) { - // Swing inside JavaFX case - SunToolkit.createNewAppContext(); - } - } + // Get the current ThreadGroup, and look for it and its + // parents in the hash from ThreadGroup to AppContext -- + // it should be found, because we use createNewContext() + // when new AppContext objects are created. + ThreadGroup currentThreadGroup = Thread.currentThread().getThreadGroup(); + ThreadGroup threadGroup = currentThreadGroup; + + // Special case: we implicitly create the main app context + // if no contexts have been created yet. This covers standalone apps + // and excludes applets because by the time applet starts + // a number of contexts have already been created by the plugin. + synchronized (getAppContextLock) { + if (numAppContexts.get() == 0) { + if (System.getProperty("javaplugin.version") == null && + System.getProperty("javawebstart.version") == null) { + initMainAppContext(); + } else if (System.getProperty("javafx.version") != null && + threadGroup.getParent() != null) { + // Swing inside JavaFX case + SunToolkit.createNewAppContext(); } + } + } - AppContext context = threadGroup2appContext.get(threadGroup); - while (context == null) { - threadGroup = threadGroup.getParent(); - if (threadGroup == null) { - // We've got up to the root thread group and did not find an AppContext - // Try to get it from the security manager - SecurityManager securityManager = System.getSecurityManager(); - if (securityManager != null) { - ThreadGroup smThreadGroup = securityManager.getThreadGroup(); - if (smThreadGroup != null) { - /* - * If we get this far then it's likely that - * the ThreadGroup does not actually belong - * to the applet, so do not cache it. - */ - return threadGroup2appContext.get(smThreadGroup); - } - } - return null; - } - context = threadGroup2appContext.get(threadGroup); - } + AppContext context = threadGroup2appContext.get(threadGroup); + while (context == null) { + threadGroup = threadGroup.getParent(); + if (threadGroup == null) { + // We've got up to the root thread group and did not find an AppContext + // We have nowhere else to look, and this is not supposed to happen. + // return null from this whole method. + return null; + } + context = threadGroup2appContext.get(threadGroup); + } - // In case we did anything in the above while loop, we add - // all the intermediate ThreadGroups to threadGroup2appContext - // so we won't spin again. - for (ThreadGroup tg = currentThreadGroup; tg != threadGroup; tg = tg.getParent()) { - threadGroup2appContext.put(tg, context); - } + // In case we did anything in the above while loop, we add + // all the intermediate ThreadGroups to threadGroup2appContext + // so we won't spin again. + for (ThreadGroup tg = currentThreadGroup; tg != threadGroup; tg = tg.getParent()) { + threadGroup2appContext.put(tg, context); + } - // Now we're done, so we cache the latest key/value pair. - threadAppContext.set(context); + // Now we're done, so we cache the latest key/value pair. + threadAppContext.set(context); - return context; - } - }); + appContext = context; } return appContext; @@ -395,7 +362,7 @@ public static boolean isMainContext(AppContext ctx) { * contained within this AppContext * @since 1.2 */ - @SuppressWarnings({"deprecation", "removal"}) + @SuppressWarnings("deprecation") public void dispose() throws IllegalThreadStateException { System.err.println( """ @@ -439,19 +406,13 @@ public void run() { log.finer("exception occurred while disposing app context", t); } } - AccessController.doPrivileged(new PrivilegedAction<Void>() { - public Void run() { - if (!GraphicsEnvironment.isHeadless() && SystemTray.isSupported()) - { - SystemTray systemTray = SystemTray.getSystemTray(); - TrayIcon[] trayIconsToDispose = systemTray.getTrayIcons(); - for (TrayIcon ti : trayIconsToDispose) { - systemTray.remove(ti); - } - } - return null; - } - }); + if (!GraphicsEnvironment.isHeadless() && SystemTray.isSupported()) { + SystemTray systemTray = SystemTray.getSystemTray(); + TrayIcon[] trayIconsToDispose = systemTray.getTrayIcons(); + for (TrayIcon ti : trayIconsToDispose) { + systemTray.remove(ti); + } + } // Alert PropertyChangeListeners that the GUI has been disposed. if (changeSupport != null) { changeSupport.firePropertyChange(GUI_DISPOSED, false, true); @@ -546,25 +507,6 @@ public void run() { } } - static final class CreateThreadAction implements PrivilegedAction<Thread> { - private final AppContext appContext; - private final Runnable runnable; - - CreateThreadAction(AppContext ac, Runnable r) { - appContext = ac; - runnable = r; - } - - public Thread run() { - Thread t = new Thread(appContext.getThreadGroup(), - runnable, "AppContext Disposer", 0, false); - t.setContextClassLoader(appContext.getContextClassLoader()); - t.setPriority(Thread.NORM_PRIORITY + 1); - t.setDaemon(true); - return t; - } - } - static void stopEventDispatchThreads() { for (AppContext appContext: getAppContexts()) { if (appContext.isDisposed()) { @@ -576,9 +518,11 @@ static void stopEventDispatchThreads() { if (appContext != AppContext.getAppContext()) { // Create a thread that belongs to the thread group associated // with the AppContext and invokes EventQueue.postEvent. - PrivilegedAction<Thread> action = new CreateThreadAction(appContext, r); - @SuppressWarnings("removal") - Thread thread = AccessController.doPrivileged(action); + Thread thread = new Thread(appContext.getThreadGroup(), + r, "AppContext Disposer", 0, false); + thread.setContextClassLoader(appContext.getContextClassLoader()); + thread.setPriority(Thread.NORM_PRIORITY + 1); + thread.setDaemon(true); thread.start(); } else { r.run(); @@ -806,14 +750,8 @@ public synchronized PropertyChangeListener[] getPropertyChangeListeners( // Set up JavaAWTAccess in SharedSecrets static { SharedSecrets.setJavaAWTAccess(new JavaAWTAccess() { - @SuppressWarnings("removal") private boolean hasRootThreadGroup(final AppContext ecx) { - return AccessController.doPrivileged(new PrivilegedAction<Boolean>() { - @Override - public Boolean run() { - return ecx.threadGroup.getParent() == null; - } - }); + return ecx.threadGroup.getParent() == null; } /** diff --git a/src/java.desktop/share/classes/sun/awt/CausedFocusEvent.java b/src/java.desktop/share/classes/sun/awt/CausedFocusEvent.java index a19e4f394e1..2527eda11f6 100644 --- a/src/java.desktop/share/classes/sun/awt/CausedFocusEvent.java +++ b/src/java.desktop/share/classes/sun/awt/CausedFocusEvent.java @@ -30,8 +30,6 @@ import java.io.ObjectStreamException; import java.io.Serial; import java.lang.reflect.Field; -import java.security.AccessController; -import java.security.PrivilegedAction; /** * This class exists for deserialization compatibility only. @@ -72,7 +70,6 @@ private CausedFocusEvent(Component source, int id, boolean temporary, throw new IllegalStateException(); } - @SuppressWarnings("removal") @Serial Object readResolve() throws ObjectStreamException { FocusEvent.Cause newCause; @@ -119,17 +116,11 @@ Object readResolve() throws ObjectStreamException { focusEvent.setSource(null); try { final Field consumedField = FocusEvent.class.getField("consumed"); - AccessController.doPrivileged(new PrivilegedAction<Object>() { - @Override - public Object run() { - consumedField.setAccessible(true); - try { - consumedField.set(focusEvent, consumed); - } catch (IllegalAccessException e) { - } - return null; - } - }); + consumedField.setAccessible(true); + try { + consumedField.set(focusEvent, consumed); + } catch (IllegalAccessException e) { + } } catch (NoSuchFieldException e) { } diff --git a/src/java.desktop/share/classes/sun/awt/DebugSettings.java b/src/java.desktop/share/classes/sun/awt/DebugSettings.java index 9d89b6519b7..b95ac44ba54 100644 --- a/src/java.desktop/share/classes/sun/awt/DebugSettings.java +++ b/src/java.desktop/share/classes/sun/awt/DebugSettings.java @@ -108,18 +108,11 @@ public static DebugSettings getInstance() { * Load debug properties from file, then override * with any command line specified properties */ - @SuppressWarnings("removal") private synchronized void loadProperties() { // setup initial properties - java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction<Void>() { - public Void run() { - loadDefaultProperties(); - loadFileProperties(); - loadSystemProperties(); - return null; - } - }); + loadDefaultProperties(); + loadFileProperties(); + loadSystemProperties(); // echo the initial property settings to stdout if (log.isLoggable(PlatformLogger.Level.FINE)) { diff --git a/src/java.desktop/share/classes/sun/awt/FontConfiguration.java b/src/java.desktop/share/classes/sun/awt/FontConfiguration.java index 9fffa09ed6c..0054382e8f6 100644 --- a/src/java.desktop/share/classes/sun/awt/FontConfiguration.java +++ b/src/java.desktop/share/classes/sun/awt/FontConfiguration.java @@ -35,8 +35,6 @@ import java.io.OutputStream; import java.nio.charset.Charset; import java.nio.charset.CharsetEncoder; -import java.security.AccessController; -import java.security.PrivilegedAction; import java.util.Arrays; import java.util.HashMap; import java.util.HashSet; @@ -120,7 +118,7 @@ public FontConfiguration(SunFontManager fm, this.preferPropFonts = preferPropFonts; /* fontConfig should be initialised by default constructor, and * its data tables can be shared, since readFontConfigFile doesn't - * update any other state. Also avoid a doPrivileged block. + * update any other state. */ initFontConfig(); } @@ -156,20 +154,8 @@ public boolean fontFilesArePresent() { short fontNameID = compFontNameIDs[0][0][0]; short fileNameID = getComponentFileID(fontNameID); final String fileName = mapFileName(getComponentFileName(fileNameID)); - @SuppressWarnings("removal") - Boolean exists = java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction<Boolean>() { - public Boolean run() { - try { - File f = new File(fileName); - return Boolean.valueOf(f.exists()); - } - catch (Exception e) { - return Boolean.FALSE; - } - } - }); - return exists.booleanValue(); + File f = new File(fileName); + return f.exists(); } private void findFontConfigFile() { @@ -960,18 +946,11 @@ private CharsetEncoder getFontCharsetEncoder(final String charsetName, !charsetName.startsWith("sun.font.")) { fc = Charset.forName(charsetName); } else { - @SuppressWarnings("removal") - Class<?> fcc = AccessController.doPrivileged(new PrivilegedAction<Class<?>>() { - public Class<?> run() { - try { - return Class.forName(charsetName, true, - ClassLoader.getSystemClassLoader()); - } catch (ClassNotFoundException e) { - } - return null; - } - }); - + Class<?> fcc = null; + try { + fcc = Class.forName(charsetName, true, ClassLoader.getSystemClassLoader()); + } catch (ClassNotFoundException e) { + } if (fcc != null) { try { fc = (Charset) fcc.getDeclaredConstructor().newInstance(); diff --git a/src/java.desktop/share/classes/sun/awt/FontDescriptor.java b/src/java.desktop/share/classes/sun/awt/FontDescriptor.java index 046ecce16da..4a16cd8d811 100644 --- a/src/java.desktop/share/classes/sun/awt/FontDescriptor.java +++ b/src/java.desktop/share/classes/sun/awt/FontDescriptor.java @@ -120,10 +120,7 @@ public boolean useUnicode() { } static boolean isLE; static { - @SuppressWarnings("removal") - String enc = java.security.AccessController.doPrivileged( - new sun.security.action.GetPropertyAction("sun.io.unicode.encoding", - "UnicodeBig")); + String enc = System.getProperty("sun.io.unicode.encoding", "UnicodeBig"); isLE = !"UnicodeBig".equals(enc); } } diff --git a/src/java.desktop/share/classes/sun/awt/NativeLibLoader.java b/src/java.desktop/share/classes/sun/awt/NativeLibLoader.java index 868ebdf3699..4bb49ae0b10 100644 --- a/src/java.desktop/share/classes/sun/awt/NativeLibLoader.java +++ b/src/java.desktop/share/classes/sun/awt/NativeLibLoader.java @@ -52,14 +52,8 @@ class NativeLibLoader { * For now, we know it's done by the implementation, and we assume * that the name of the library is "awt". -br. */ - @SuppressWarnings({"removal", "restricted"}) + @SuppressWarnings("restricted") static void loadLibraries() { - java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction<Void>() { - public Void run() { - System.loadLibrary("awt"); - return null; - } - }); + System.loadLibrary("awt"); } } diff --git a/src/java.desktop/share/classes/sun/awt/datatransfer/DataTransferer.java b/src/java.desktop/share/classes/sun/awt/datatransfer/DataTransferer.java index 23520de9eea..5014bb78ead 100644 --- a/src/java.desktop/share/classes/sun/awt/datatransfer/DataTransferer.java +++ b/src/java.desktop/share/classes/sun/awt/datatransfer/DataTransferer.java @@ -62,10 +62,6 @@ import java.nio.charset.CharsetEncoder; import java.nio.charset.IllegalCharsetNameException; import java.nio.charset.UnsupportedCharsetException; -import java.security.AccessController; -import java.security.PrivilegedAction; -import java.security.PrivilegedActionException; -import java.security.PrivilegedExceptionAction; import java.security.ProtectionDomain; import java.util.AbstractMap; import java.util.ArrayList; @@ -985,7 +981,6 @@ private static byte[] convertObjectToBytes(Object object) throws IOException { @SuppressWarnings("removal") private String removeSuspectedData(DataFlavor flavor, final Transferable contents, final String str) - throws IOException { if (null == System.getSecurityManager() || !flavor.isMimeTypeEqual("text/uri-list")) @@ -994,34 +989,25 @@ private String removeSuspectedData(DataFlavor flavor, final Transferable content } final ProtectionDomain userProtectionDomain = getUserProtectionDomain(contents); + StringBuilder allowedFiles = new StringBuilder(str.length()); + String [] uriArray = str.split("(\\s)+"); - try { - return AccessController.doPrivileged((PrivilegedExceptionAction<String>) () -> { - - StringBuilder allowedFiles = new StringBuilder(str.length()); - String [] uriArray = str.split("(\\s)+"); - - for (String fileName : uriArray) + for (String fileName : uriArray) + { + File file = new File(fileName); + if (file.exists() && + !(isFileInWebstartedCache(file) || + isForbiddenToRead(file, userProtectionDomain))) + { + if (0 != allowedFiles.length()) { - File file = new File(fileName); - if (file.exists() && - !(isFileInWebstartedCache(file) || - isForbiddenToRead(file, userProtectionDomain))) - { - if (0 != allowedFiles.length()) - { - allowedFiles.append("\\r\\n"); - } - - allowedFiles.append(fileName); - } + allowedFiles.append("\\r\\n"); } - return allowedFiles.toString(); - }); - } catch (PrivilegedActionException pae) { - throw new IOException(pae.getMessage(), pae); + allowedFiles.append(fileName); + } } + return allowedFiles.toString(); } private static ProtectionDomain getUserProtectionDomain(Transferable contents) { @@ -1047,25 +1033,19 @@ private boolean isForbiddenToRead (File file, ProtectionDomain protectionDomain) @SuppressWarnings("removal") private ArrayList<String> castToFiles(final List<?> files, final ProtectionDomain userProtectionDomain) throws IOException { - try { - return AccessController.doPrivileged((PrivilegedExceptionAction<ArrayList<String>>) () -> { - ArrayList<String> fileList = new ArrayList<>(); - for (Object fileObject : files) - { - File file = castToFile(fileObject); - if (file != null && - (null == System.getSecurityManager() || - !(isFileInWebstartedCache(file) || - isForbiddenToRead(file, userProtectionDomain)))) - { - fileList.add(file.getCanonicalPath()); - } - } - return fileList; - }); - } catch (PrivilegedActionException pae) { - throw new IOException(pae.getMessage()); + ArrayList<String> fileList = new ArrayList<>(); + for (Object fileObject : files) + { + File file = castToFile(fileObject); + if (file != null && + (null == System.getSecurityManager() || + !(isFileInWebstartedCache(file) || + isForbiddenToRead(file, userProtectionDomain)))) + { + fileList.add(file.getCanonicalPath()); + } } + return fileList; } // It is important do not use user's successors @@ -1419,7 +1399,6 @@ public Object translateStream(InputStream str, DataFlavor flavor, * and also arbitrary Objects which have a constructor which takes an * instance of the Class as its sole parameter. */ - @SuppressWarnings("removal") private Object constructFlavoredObject(Object arg, DataFlavor flavor, Class<?> clazz) throws IOException @@ -1429,15 +1408,7 @@ private Object constructFlavoredObject(Object arg, DataFlavor flavor, if (clazz.equals(dfrc)) { return arg; // simple case } else { - Constructor<?>[] constructors; - - try { - constructors = AccessController.doPrivileged( - (PrivilegedAction<Constructor<?>[]>) dfrc::getConstructors); - } catch (SecurityException se) { - throw new IOException(se.getMessage()); - } - + Constructor<?>[] constructors = dfrc.getConstructors(); Constructor<?> constructor = Stream.of(constructors) .filter(c -> Modifier.isPublic(c.getModifiers())) .filter(c -> { diff --git a/src/java.desktop/share/classes/sun/awt/datatransfer/TransferableProxy.java b/src/java.desktop/share/classes/sun/awt/datatransfer/TransferableProxy.java index cf8660fa8fa..fffb3f98a3e 100644 --- a/src/java.desktop/share/classes/sun/awt/datatransfer/TransferableProxy.java +++ b/src/java.desktop/share/classes/sun/awt/datatransfer/TransferableProxy.java @@ -38,8 +38,6 @@ import java.io.OutputStream; import java.lang.reflect.Modifier; import java.lang.reflect.Proxy; -import java.security.AccessController; -import java.security.PrivilegedAction; import java.util.HashMap; import java.util.HashSet; import java.util.Map; @@ -111,28 +109,14 @@ final class ClassLoaderObjectOutputStream extends ObjectOutputStream { } protected void annotateClass(final Class<?> cl) throws IOException { - @SuppressWarnings("removal") - ClassLoader classLoader = AccessController.doPrivileged( - new PrivilegedAction<ClassLoader>() { - public ClassLoader run() { - return cl.getClassLoader(); - } - }); - + ClassLoader classLoader = cl.getClassLoader(); Set<String> s = new HashSet<String>(1); s.add(cl.getName()); map.put(s, classLoader); } protected void annotateProxyClass(final Class<?> cl) throws IOException { - @SuppressWarnings("removal") - ClassLoader classLoader = AccessController.doPrivileged( - new PrivilegedAction<ClassLoader>() { - public ClassLoader run() { - return cl.getClassLoader(); - } - }); - + ClassLoader classLoader = cl.getClassLoader(); Class<?>[] interfaces = cl.getInterfaces(); Set<String> s = new HashSet<String>(interfaces.length); for (int i = 0; i < interfaces.length; i++) { diff --git a/src/java.desktop/share/classes/sun/awt/im/ExecutableInputMethodManager.java b/src/java.desktop/share/classes/sun/awt/im/ExecutableInputMethodManager.java index 3696d53945b..b937fb139a3 100644 --- a/src/java.desktop/share/classes/sun/awt/im/ExecutableInputMethodManager.java +++ b/src/java.desktop/share/classes/sun/awt/im/ExecutableInputMethodManager.java @@ -41,10 +41,6 @@ import java.awt.event.InvocationEvent; import java.awt.im.spi.InputMethodDescriptor; import java.lang.reflect.InvocationTargetException; -import java.security.AccessController; -import java.security.PrivilegedAction; -import java.security.PrivilegedActionException; -import java.security.PrivilegedExceptionAction; import java.util.Hashtable; import java.util.Iterator; import java.util.Locale; @@ -252,24 +248,14 @@ private synchronized void waitForChangeRequest() { * initializes the input method locator list for all * installed input method descriptors. */ - @SuppressWarnings("removal") private void initializeInputMethodLocatorList() { synchronized (javaInputMethodLocatorList) { javaInputMethodLocatorList.clear(); - try { - AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() { - public Object run() { - for (InputMethodDescriptor descriptor : - ServiceLoader.load(InputMethodDescriptor.class, - ClassLoader.getSystemClassLoader())) { - ClassLoader cl = descriptor.getClass().getClassLoader(); - javaInputMethodLocatorList.add(new InputMethodLocator(descriptor, cl, null)); - } - return null; - } - }); - } catch (PrivilegedActionException e) { - e.printStackTrace(); + for (InputMethodDescriptor descriptor : + ServiceLoader.load(InputMethodDescriptor.class, + ClassLoader.getSystemClassLoader())) { + ClassLoader cl = descriptor.getClass().getClassLoader(); + javaInputMethodLocatorList.add(new InputMethodLocator(descriptor, cl, null)); } javaInputMethodCount = javaInputMethodLocatorList.size(); } @@ -594,13 +580,8 @@ private void writePreferredInputMethod(String path, String descriptorName) { } } - @SuppressWarnings("removal") private Preferences getUserRoot() { - return AccessController.doPrivileged(new PrivilegedAction<Preferences>() { - public Preferences run() { - return Preferences.userRoot(); - } - }); + return Preferences.userRoot(); } private Locale getAdvertisedLocale(InputMethodLocator locator, Locale locale) { diff --git a/src/java.desktop/share/classes/sun/awt/im/InputContext.java b/src/java.desktop/share/classes/sun/awt/im/InputContext.java index 6d3dc248abf..00703eb44c3 100644 --- a/src/java.desktop/share/classes/sun/awt/im/InputContext.java +++ b/src/java.desktop/share/classes/sun/awt/im/InputContext.java @@ -44,8 +44,6 @@ import java.awt.im.InputMethodRequests; import java.awt.im.spi.InputMethod; import java.lang.Character.Subset; -import java.security.AccessController; -import java.security.PrivilegedAction; import java.text.MessageFormat; import java.util.Collection; import java.util.HashMap; @@ -1036,22 +1034,16 @@ public void windowDeactivated(WindowEvent e) {} /** * Initializes the input method selection key definition in preference trees */ - @SuppressWarnings("removal") private void initializeInputMethodSelectionKey() { - AccessController.doPrivileged(new PrivilegedAction<Object>() { - public Object run() { - // Look in user's tree - Preferences root = Preferences.userRoot(); - inputMethodSelectionKey = getInputMethodSelectionKeyStroke(root); - - if (inputMethodSelectionKey == null) { - // Look in system's tree - root = Preferences.systemRoot(); - inputMethodSelectionKey = getInputMethodSelectionKeyStroke(root); - } - return null; - } - }); + // Look in user's tree + Preferences root = Preferences.userRoot(); + inputMethodSelectionKey = getInputMethodSelectionKeyStroke(root); + + if (inputMethodSelectionKey == null) { + // Look in system's tree + root = Preferences.systemRoot(); + inputMethodSelectionKey = getInputMethodSelectionKeyStroke(root); + } } private AWTKeyStroke getInputMethodSelectionKeyStroke(Preferences root) { diff --git a/src/java.desktop/share/classes/sun/awt/im/InputMethodContext.java b/src/java.desktop/share/classes/sun/awt/im/InputMethodContext.java index 96d53178783..a0f9baa3112 100644 --- a/src/java.desktop/share/classes/sun/awt/im/InputMethodContext.java +++ b/src/java.desktop/share/classes/sun/awt/im/InputMethodContext.java @@ -37,7 +37,6 @@ import java.awt.font.TextHitInfo; import java.awt.im.InputMethodRequests; import java.awt.im.spi.InputMethod; -import java.security.AccessController; import java.text.AttributedCharacterIterator; import java.text.AttributedCharacterIterator.Attribute; import java.text.AttributedString; @@ -72,9 +71,7 @@ public class InputMethodContext static { // check whether we should use below-the-spot input // get property from command line - @SuppressWarnings("removal") - String inputStyle = AccessController.doPrivileged - (new GetPropertyAction("java.awt.im.style", null)); + String inputStyle = System.getProperty("java.awt.im.style"); // get property from awt.properties file if (inputStyle == null) { inputStyle = Toolkit.getProperty("java.awt.im.style", null); diff --git a/src/java.desktop/share/classes/sun/font/CreatedFontTracker.java b/src/java.desktop/share/classes/sun/font/CreatedFontTracker.java index 61f48e8d098..a144f14f4a9 100644 --- a/src/java.desktop/share/classes/sun/font/CreatedFontTracker.java +++ b/src/java.desktop/share/classes/sun/font/CreatedFontTracker.java @@ -27,8 +27,6 @@ import java.io.File; import java.io.OutputStream; -import java.security.AccessController; -import java.security.PrivilegedAction; import java.util.HashMap; import java.util.Map; import java.util.concurrent.Semaphore; @@ -112,25 +110,21 @@ private static class TempFileDeletionHook { private static HashMap<File, OutputStream> files = new HashMap<>(); private static Thread t = null; - @SuppressWarnings("removal") static void init() { if (t == null) { // Add a shutdown hook to remove the temp file. - AccessController.doPrivileged((PrivilegedAction<Void>) () -> { - /* The thread must be a member of a thread group - * which will not get GCed before VM exit. - * Make its parent the top-level thread group. - */ - ThreadGroup rootTG = ThreadGroupUtils.getRootThreadGroup(); - t = new Thread(rootTG, TempFileDeletionHook::runHooks, - "TempFontFileDeleter", 0, false); - /* Set context class loader to null in order to avoid - * keeping a strong reference to an application classloader. - */ - t.setContextClassLoader(null); - Runtime.getRuntime().addShutdownHook(t); - return null; - }); + /* The thread must be a member of a thread group + * which will not get GCed before VM exit. + * Make its parent the top-level thread group. + */ + ThreadGroup rootTG = ThreadGroupUtils.getRootThreadGroup(); + t = new Thread(rootTG, TempFileDeletionHook::runHooks, + "TempFontFileDeleter", 0, false); + /* Set context class loader to null in order to avoid + * keeping a strong reference to an application classloader. + */ + t.setContextClassLoader(null); + Runtime.getRuntime().addShutdownHook(t); } } diff --git a/src/java.desktop/share/classes/sun/font/FileFont.java b/src/java.desktop/share/classes/sun/font/FileFont.java index da5874518fa..47c6ea181f4 100644 --- a/src/java.desktop/share/classes/sun/font/FileFont.java +++ b/src/java.desktop/share/classes/sun/font/FileFont.java @@ -35,11 +35,7 @@ import sun.java2d.Disposer; import sun.java2d.DisposerRecord; -import java.io.IOException; import java.util.List; -import java.security.AccessController; -import java.security.PrivilegedActionException; -import java.security.PrivilegedExceptionAction; public abstract class FileFont extends PhysicalFont { @@ -252,84 +248,35 @@ private CreatedFontFileDisposerRecord(File file, int cnt, this.tracker = tracker; } - @SuppressWarnings("removal") public void dispose() { - java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction<Object>() { - public Object run() { - synchronized (fontFile) { - count--; - if (count > 0) { - return null; - } - } - if (fontFile != null) { - try { - if (tracker != null) { - tracker.subBytes((int)fontFile.length()); - } - /* REMIND: is it possible that the file is - * still open? It will be closed when the - * font2D is disposed but could this code - * execute first? If so the file would not - * be deleted on MS-windows. - */ - fontFile.delete(); - /* remove from delete on exit hook list : */ - // FIXME: still need to be refactored - SunFontManager.getInstance().tmpFontFiles.remove(fontFile); - } catch (Exception e) { - } - } - return null; + synchronized (fontFile) { + count--; + if (count > 0) { + return; + } + } + if (fontFile != null) { + try { + if (tracker != null) { + tracker.subBytes((int)fontFile.length()); } - }); + /* REMIND: is it possible that the file is + * still open? It will be closed when the + * font2D is disposed but could this code + * execute first? If so the file would not + * be deleted on MS-windows. + */ + fontFile.delete(); + /* remove from delete on exit hook list : */ + // FIXME: still need to be refactored + SunFontManager.getInstance().tmpFontFiles.remove(fontFile); + } catch (Exception e) { + } + } } } - @SuppressWarnings("removal") protected String getPublicFileName() { - SecurityManager sm = System.getSecurityManager(); - if (sm == null) { return platName; - } - boolean canReadProperty = true; - - try { - sm.checkPropertyAccess("java.io.tmpdir"); - } catch (SecurityException e) { - canReadProperty = false; - } - - if (canReadProperty) { - return platName; - } - - final File f = new File(platName); - - Boolean isTmpFile = Boolean.FALSE; - try { - isTmpFile = AccessController.doPrivileged( - new PrivilegedExceptionAction<Boolean>() { - public Boolean run() { - File tmp = new File(System.getProperty("java.io.tmpdir")); - try { - String tpath = tmp.getCanonicalPath(); - String fpath = f.getCanonicalPath(); - - return (fpath == null) || fpath.startsWith(tpath); - } catch (IOException e) { - return Boolean.TRUE; - } - } - } - ); - } catch (PrivilegedActionException e) { - // unable to verify whether value of java.io.tempdir will be - // exposed, so return only a name of the font file. - isTmpFile = Boolean.TRUE; - } - - return isTmpFile ? "temp file" : platName; } } diff --git a/src/java.desktop/share/classes/sun/font/FontManagerNativeLibrary.java b/src/java.desktop/share/classes/sun/font/FontManagerNativeLibrary.java index 9439f6ed857..51997571e75 100644 --- a/src/java.desktop/share/classes/sun/font/FontManagerNativeLibrary.java +++ b/src/java.desktop/share/classes/sun/font/FontManagerNativeLibrary.java @@ -27,39 +27,32 @@ import sun.awt.OSInfo; -@SuppressWarnings({"removal", "restricted"}) +@SuppressWarnings("restricted") public class FontManagerNativeLibrary { static { - java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction<Object>() { - public Object run() { - /* REMIND do we really have to load awt here? */ - System.loadLibrary("awt"); - if (OSInfo.getOSType() == OSInfo.OSType.WINDOWS) { - /* Ideally fontmanager library should not depend on - particular implementation of the font scaler. - However, freetype scaler is basically small wrapper on - top of freetype library (that is used in binary form). + /* REMIND do we really have to load awt here? */ + System.loadLibrary("awt"); + if (OSInfo.getOSType() == OSInfo.OSType.WINDOWS) { + /* Ideally fontmanager library should not depend on + particular implementation of the font scaler. + However, freetype scaler is basically small wrapper on + top of freetype library (that is used in binary form). - This wrapper is compiled into fontmanager and this make - fontmanger library depending on freetype library. + This wrapper is compiled into fontmanager and this make + fontmanger library depending on freetype library. - On Windows DLL's in the JRE's BIN directory cannot be - found by windows DLL loading as that directory is not - on the Windows PATH. + On Windows DLL's in the JRE's BIN directory cannot be + found by windows DLL loading as that directory is not + on the Windows PATH. - To avoid link error we have to load freetype explicitly - before we load fontmanager. + To avoid link error we have to load freetype explicitly + before we load fontmanager. - NB: consider moving freetype wrapper part to separate - shared library in order to avoid dependency. */ - System.loadLibrary("freetype"); - } - System.loadLibrary("fontmanager"); - - return null; - } - }); + NB: consider moving freetype wrapper part to separate + shared library in order to avoid dependency. */ + System.loadLibrary("freetype"); + } + System.loadLibrary("fontmanager"); } /* diff --git a/src/java.desktop/share/classes/sun/font/FontUtilities.java b/src/java.desktop/share/classes/sun/font/FontUtilities.java index bdccf99d1ed..30ec4f3db81 100644 --- a/src/java.desktop/share/classes/sun/font/FontUtilities.java +++ b/src/java.desktop/share/classes/sun/font/FontUtilities.java @@ -28,9 +28,7 @@ import java.awt.Font; import java.lang.ref.SoftReference; import java.util.concurrent.ConcurrentHashMap; -import java.security.AccessController; -import java.security.PrivilegedAction; import javax.swing.plaf.FontUIResource; import sun.awt.OSInfo; @@ -59,65 +57,57 @@ public final class FontUtilities { initStatic(); } - @SuppressWarnings("removal") + @SuppressWarnings("deprecation") // PlatformLogger.setLevel is deprecated. private static void initStatic() { - AccessController.doPrivileged(new PrivilegedAction<Object>() { - @SuppressWarnings("deprecation") // PlatformLogger.setLevel is deprecated. - @Override - public Object run() { - - isLinux = OSInfo.getOSType() == OSInfo.OSType.LINUX; - - isMacOSX = OSInfo.getOSType() == OSInfo.OSType.MACOSX; - if (isMacOSX) { - // os.version has values like 10.13.6, 10.14.6 - // If it is not positively recognised as 10.13 or less, - // assume it means 10.14 or some later version. - isMacOSX14 = true; - String version = System.getProperty("os.version", ""); - if (version.startsWith("10.")) { - version = version.substring(3); - int periodIndex = version.indexOf('.'); - if (periodIndex != -1) { - version = version.substring(0, periodIndex); - } - try { - int v = Integer.parseInt(version); - isMacOSX14 = (v >= 14); - } catch (NumberFormatException e) { - } - } - } - /* If set to "jdk", use the JDK's scaler rather than - * the platform one. This may be a no-op on platforms where - * JDK has been configured so that it always relies on the - * platform scaler. The principal case where it has an - * effect is that on Windows, 2D will never use GDI. - */ - String scalerStr = System.getProperty("sun.java2d.font.scaler"); - if (scalerStr != null) { - useJDKScaler = "jdk".equals(scalerStr); - } else { - useJDKScaler = false; + + isLinux = OSInfo.getOSType() == OSInfo.OSType.LINUX; + + isMacOSX = OSInfo.getOSType() == OSInfo.OSType.MACOSX; + if (isMacOSX) { + // os.version has values like 10.13.6, 10.14.6 + // If it is not positively recognised as 10.13 or less, + // assume it means 10.14 or some later version. + isMacOSX14 = true; + String version = System.getProperty("os.version", ""); + if (version.startsWith("10.")) { + version = version.substring(3); + int periodIndex = version.indexOf('.'); + if (periodIndex != -1) { + version = version.substring(0, periodIndex); } - isWindows = OSInfo.getOSType() == OSInfo.OSType.WINDOWS; - String debugLevel = - System.getProperty("sun.java2d.debugfonts"); - - if (debugLevel != null && !debugLevel.equals("false")) { - debugFonts = true; - logger = PlatformLogger.getLogger("sun.java2d"); - if (debugLevel.equals("warning")) { - logger.setLevel(PlatformLogger.Level.WARNING); - } else if (debugLevel.equals("severe")) { - logger.setLevel(PlatformLogger.Level.SEVERE); - } - logging = logger.isEnabled(); + try { + int v = Integer.parseInt(version); + isMacOSX14 = (v >= 14); + } catch (NumberFormatException e) { } - - return null; + } + } + /* If set to "jdk", use the JDK's scaler rather than + * the platform one. This may be a no-op on platforms where + * JDK has been configured so that it always relies on the + * platform scaler. The principal case where it has an + * effect is that on Windows, 2D will never use GDI. + */ + String scalerStr = System.getProperty("sun.java2d.font.scaler"); + if (scalerStr != null) { + useJDKScaler = "jdk".equals(scalerStr); + } else { + useJDKScaler = false; + } + isWindows = OSInfo.getOSType() == OSInfo.OSType.WINDOWS; + String debugLevel = + System.getProperty("sun.java2d.debugfonts"); + + if (debugLevel != null && !debugLevel.equals("false")) { + debugFonts = true; + logger = PlatformLogger.getLogger("sun.java2d"); + if (debugLevel.equals("warning")) { + logger.setLevel(PlatformLogger.Level.WARNING); + } else if (debugLevel.equals("severe")) { + logger.setLevel(PlatformLogger.Level.SEVERE); } - }); + logging = logger.isEnabled(); + } } /** diff --git a/src/java.desktop/share/classes/sun/font/StrikeCache.java b/src/java.desktop/share/classes/sun/font/StrikeCache.java index ea1369b4383..c0859c4c0af 100644 --- a/src/java.desktop/share/classes/sun/font/StrikeCache.java +++ b/src/java.desktop/share/classes/sun/font/StrikeCache.java @@ -263,7 +263,6 @@ static final byte getPixelByte(MemorySegment pixelData, long index) { initStatic(); } - @SuppressWarnings("removal") private static void initStatic() { if (nativeAddressSize < 4) { @@ -271,37 +270,28 @@ private static void initStatic() { nativeAddressSize); } - java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction<Object>() { - public Object run() { - - /* Allow a client to override the reference type used to - * cache strikes. The default is "soft" which hints to keep - * the strikes around. This property allows the client to - * override this to "weak" which hint to the GC to free - * memory more aggressively. - */ - String refType = - System.getProperty("sun.java2d.font.reftype", "soft"); - cacheRefTypeWeak = refType.equals("weak"); - - String minStrikesStr = - System.getProperty("sun.java2d.font.minstrikes"); - if (minStrikesStr != null) { - try { - MINSTRIKES = Integer.parseInt(minStrikesStr); - if (MINSTRIKES <= 0) { - MINSTRIKES = 1; - } - } catch (NumberFormatException e) { - } + /* Allow a client to override the reference type used to + * cache strikes. The default is "soft" which hints to keep + * the strikes around. This property allows the client to + * override this to "weak" which hint to the GC to free + * memory more aggressively. + */ + String refType = System.getProperty("sun.java2d.font.reftype", "soft"); + cacheRefTypeWeak = refType.equals("weak"); + + String minStrikesStr = + System.getProperty("sun.java2d.font.minstrikes"); + if (minStrikesStr != null) { + try { + MINSTRIKES = Integer.parseInt(minStrikesStr); + if (MINSTRIKES <= 0) { + MINSTRIKES = 1; } - - recentStrikes = new FontStrike[MINSTRIKES]; - - return null; + } catch (NumberFormatException e) { } - }); + } + + recentStrikes = new FontStrike[MINSTRIKES]; } diff --git a/src/java.desktop/share/classes/sun/font/SunFontManager.java b/src/java.desktop/share/classes/sun/font/SunFontManager.java index 3aec139b56d..06dc4a90820 100644 --- a/src/java.desktop/share/classes/sun/font/SunFontManager.java +++ b/src/java.desktop/share/classes/sun/font/SunFontManager.java @@ -33,8 +33,6 @@ import java.io.FilenameFilter; import java.io.IOException; import java.io.InputStreamReader; -import java.security.AccessController; -import java.security.PrivilegedAction; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; @@ -262,30 +260,24 @@ public FilenameFilter getType1Filter() { initStatic(); } - @SuppressWarnings("removal") private static void initStatic() { - AccessController.doPrivileged(new PrivilegedAction<Void>() { - public Void run() { - FontManagerNativeLibrary.load(); - - // JNI throws an exception if a class/method/field is not found, - // so there's no need to do anything explicit here. - initIDs(); - - switch (StrikeCache.nativeAddressSize) { - case 8: longAddresses = true; break; - case 4: longAddresses = false; break; - default: throw new RuntimeException("Unexpected address size"); - } + FontManagerNativeLibrary.load(); - noType1Font = "true".equals(System.getProperty("sun.java2d.noType1Font")); - jreLibDirName = System.getProperty("java.home","") + File.separator + "lib"; - jreFontDirName = jreLibDirName + File.separator + "fonts"; + // JNI throws an exception if a class/method/field is not found, + // so there's no need to do anything explicit here. + initIDs(); - maxSoftRefCnt = Integer.getInteger("sun.java2d.font.maxSoftRefs", 10); - return null; - } - }); + switch (StrikeCache.nativeAddressSize) { + case 8: longAddresses = true; break; + case 4: longAddresses = false; break; + default: throw new RuntimeException("Unexpected address size"); + } + + noType1Font = "true".equals(System.getProperty("sun.java2d.noType1Font")); + jreLibDirName = System.getProperty("java.home","") + File.separator + "lib"; + jreFontDirName = jreLibDirName + File.separator + "fonts"; + + maxSoftRefCnt = Integer.getInteger("sun.java2d.font.maxSoftRefs", 10); } /** @@ -304,150 +296,142 @@ public TrueTypeFont getEUDCFont() { /* Initialise ptrs used by JNI methods */ private static native void initIDs(); - @SuppressWarnings("removal") protected SunFontManager() { - AccessController.doPrivileged(new PrivilegedAction<Void>() { - public Void run() { - File badFontFile = - new File(jreFontDirName + File.separator + "badfonts.txt"); - if (badFontFile.exists()) { - badFonts = new ArrayList<>(); - try (FileInputStream fis = new FileInputStream(badFontFile); - BufferedReader br = new BufferedReader(new InputStreamReader(fis))) { - while (true) { - String name = br.readLine(); - if (name == null) { - break; - } else { - if (FontUtilities.debugFonts()) { - FontUtilities.logWarning("read bad font: " + name); - } - badFonts.add(name); - } + File badFontFile = + new File(jreFontDirName + File.separator + "badfonts.txt"); + if (badFontFile.exists()) { + badFonts = new ArrayList<>(); + try (FileInputStream fis = new FileInputStream(badFontFile); + BufferedReader br = new BufferedReader(new InputStreamReader(fis))) { + while (true) { + String name = br.readLine(); + if (name == null) { + break; + } else { + if (FontUtilities.debugFonts()) { + FontUtilities.logWarning("read bad font: " + name); } - } catch (IOException e) { + badFonts.add(name); } } + } catch (IOException e) { + } + } - /* Here we get the fonts in jre/lib/fonts and register - * them so they are always available and preferred over - * other fonts. This needs to be registered before the - * composite fonts as otherwise some native font that - * corresponds may be found as we don't have a way to - * handle two fonts of the same name, so the JRE one - * must be the first one registered. Pass "true" to - * registerFonts method as on-screen these JRE fonts - * always go through the JDK rasteriser. - */ - if (FontUtilities.isLinux) { - /* Linux font configuration uses these fonts */ - registerFontDir(jreFontDirName); - } - registerFontsInDir(jreFontDirName, true, Font2D.JRE_RANK, - true, false); - - /* Create the font configuration and get any font path - * that might be specified. - */ - fontConfig = createFontConfiguration(); - - String[] fontInfo = getDefaultPlatformFont(); - defaultFontName = fontInfo[0]; - if (defaultFontName == null && FontUtilities.debugFonts()) { - FontUtilities.logWarning("defaultFontName is null"); - } - defaultFontFileName = fontInfo[1]; - - String extraFontPath = fontConfig.getExtraFontPath(); - - /* In prior releases the debugging font path replaced - * all normally located font directories except for the - * JRE fonts dir. This directory is still always located - * and placed at the head of the path but as an - * augmentation to the previous behaviour the - * changes below allow you to additionally append to - * the font path by starting with append: or prepend by - * starting with a prepend: sign. Eg: to append - * -Dsun.java2d.fontpath=append:/usr/local/myfonts - * and to prepend - * -Dsun.java2d.fontpath=prepend:/usr/local/myfonts Disp - * - * If there is an appendedfontpath it in the font - * configuration it is used instead of searching the - * system for dirs. - * The behaviour of append and prepend is then similar - * to the normal case. ie it goes after what - * you prepend and * before what you append. If the - * sun.java2d.fontpath property is used, but it - * neither the append or prepend syntaxes is used then - * as except for the JRE dir the path is replaced and it - * is up to you to make sure that all the right - * directories are located. This is platform and - * locale-specific so its almost impossible to get - * right, so it should be used with caution. - */ - boolean prependToPath = false; - boolean appendToPath = false; - String dbgFontPath = System.getProperty("sun.java2d.fontpath"); - - if (dbgFontPath != null) { - if (dbgFontPath.startsWith("prepend:")) { - prependToPath = true; - dbgFontPath = - dbgFontPath.substring("prepend:".length()); - } else if (dbgFontPath.startsWith("append:")) { - appendToPath = true; - dbgFontPath = - dbgFontPath.substring("append:".length()); - } - } + /* Here we get the fonts in jre/lib/fonts and register + * them so they are always available and preferred over + * other fonts. This needs to be registered before the + * composite fonts as otherwise some native font that + * corresponds may be found as we don't have a way to + * handle two fonts of the same name, so the JRE one + * must be the first one registered. Pass "true" to + * registerFonts method as on-screen these JRE fonts + * always go through the JDK rasteriser. + */ + if (FontUtilities.isLinux) { + /* Linux font configuration uses these fonts */ + registerFontDir(jreFontDirName); + } + registerFontsInDir(jreFontDirName, true, Font2D.JRE_RANK, + true, false); - if (FontUtilities.debugFonts()) { - FontUtilities.logInfo("JRE font directory: " + jreFontDirName); - FontUtilities.logInfo("Extra font path: " + extraFontPath); - FontUtilities.logInfo("Debug font path: " + dbgFontPath); - } + /* Create the font configuration and get any font path + * that might be specified. + */ + fontConfig = createFontConfiguration(); + + String[] fontInfo = getDefaultPlatformFont(); + defaultFontName = fontInfo[0]; + if (defaultFontName == null && FontUtilities.debugFonts()) { + FontUtilities.logWarning("defaultFontName is null"); + } + defaultFontFileName = fontInfo[1]; + + String extraFontPath = fontConfig.getExtraFontPath(); + + /* In prior releases the debugging font path replaced + * all normally located font directories except for the + * JRE fonts dir. This directory is still always located + * and placed at the head of the path but as an + * augmentation to the previous behaviour the + * changes below allow you to additionally append to + * the font path by starting with append: or prepend by + * starting with a prepend: sign. Eg: to append + * -Dsun.java2d.fontpath=append:/usr/local/myfonts + * and to prepend + * -Dsun.java2d.fontpath=prepend:/usr/local/myfonts Disp + * + * If there is an appendedfontpath it in the font + * configuration it is used instead of searching the + * system for dirs. + * The behaviour of append and prepend is then similar + * to the normal case. ie it goes after what + * you prepend and * before what you append. If the + * sun.java2d.fontpath property is used, but it + * neither the append or prepend syntaxes is used then + * as except for the JRE dir the path is replaced and it + * is up to you to make sure that all the right + * directories are located. This is platform and + * locale-specific so its almost impossible to get + * right, so it should be used with caution. + */ + boolean prependToPath = false; + boolean appendToPath = false; + String dbgFontPath = System.getProperty("sun.java2d.fontpath"); - if (dbgFontPath != null) { - /* In debugging mode we register all the paths - * Caution: this is a very expensive call on Solaris:- - */ - fontPath = getPlatformFontPath(noType1Font); + if (dbgFontPath != null) { + if (dbgFontPath.startsWith("prepend:")) { + prependToPath = true; + dbgFontPath = + dbgFontPath.substring("prepend:".length()); + } else if (dbgFontPath.startsWith("append:")) { + appendToPath = true; + dbgFontPath = + dbgFontPath.substring("append:".length()); + } + } - if (extraFontPath != null) { - fontPath = extraFontPath + File.pathSeparator + fontPath; - } - if (appendToPath) { - fontPath += File.pathSeparator + dbgFontPath; - } else if (prependToPath) { - fontPath = dbgFontPath + File.pathSeparator + fontPath; - } else { - fontPath = dbgFontPath; - } - registerFontDirs(fontPath); - } else if (extraFontPath != null) { - /* If the font configuration contains an - * "appendedfontpath" entry, it is interpreted as a - * set of locations that should always be registered. - * It may be additional to locations normally found - * for that place, or it may be locations that need - * to have all their paths registered to locate all - * the needed platform names. - * This is typically when the same .TTF file is - * referenced from multiple font.dir files and all - * of these must be read to find all the native - * (XLFD) names for the font, so that X11 font APIs - * can be used for as many code points as possible. - */ - registerFontDirs(extraFontPath); - } + if (FontUtilities.debugFonts()) { + FontUtilities.logInfo("JRE font directory: " + jreFontDirName); + FontUtilities.logInfo("Extra font path: " + extraFontPath); + FontUtilities.logInfo("Debug font path: " + dbgFontPath); + } - initCompositeFonts(fontConfig, null); + if (dbgFontPath != null) { + /* In debugging mode we register all the paths + * Caution: this is a very expensive call on Solaris:- + */ + fontPath = getPlatformFontPath(noType1Font); - return null; + if (extraFontPath != null) { + fontPath = extraFontPath + File.pathSeparator + fontPath; } - }); + if (appendToPath) { + fontPath += File.pathSeparator + dbgFontPath; + } else if (prependToPath) { + fontPath = dbgFontPath + File.pathSeparator + fontPath; + } else { + fontPath = dbgFontPath; + } + registerFontDirs(fontPath); + } else if (extraFontPath != null) { + /* If the font configuration contains an + * "appendedfontpath" entry, it is interpreted as a + * set of locations that should always be registered. + * It may be additional to locations normally found + * for that place, or it may be locations that need + * to have all their paths registered to locate all + * the needed platform names. + * This is typically when the same .TTF file is + * referenced from multiple font.dir files and all + * of these must be read to find all the native + * (XLFD) names for the font, so that X11 font APIs + * can be used for as many code points as possible. + */ + registerFontDirs(extraFontPath); + } + initCompositeFonts(fontConfig, null); } public Font2DHandle getNewComposite(String family, int style, @@ -1095,7 +1079,6 @@ private static String dotStyleStr(int num) { private boolean haveCheckedUnreferencedFontFiles; - @SuppressWarnings("removal") private String[] getFontFilesFromPath(boolean noType1) { final FilenameFilter filter; if (noType1) { @@ -1103,34 +1086,30 @@ private String[] getFontFilesFromPath(boolean noType1) { } else { filter = new TTorT1Filter(); } - return AccessController.doPrivileged(new PrivilegedAction<String[]>() { - public String[] run() { - if (pathDirs.length == 1) { - File dir = new File(pathDirs[0]); - String[] files = dir.list(filter); - if (files == null) { - return new String[0]; - } - for (int f=0; f<files.length; f++) { - files[f] = files[f].toLowerCase(); - } - return files; - } else { - ArrayList<String> fileList = new ArrayList<>(); - for (int i = 0; i< pathDirs.length; i++) { - File dir = new File(pathDirs[i]); - String[] files = dir.list(filter); - if (files == null) { - continue; - } - for (int f = 0; f < files.length ; f++) { - fileList.add(files[f].toLowerCase()); - } - } - return fileList.toArray(STR_ARRAY); + if (pathDirs.length == 1) { + File dir = new File(pathDirs[0]); + String[] files = dir.list(filter); + if (files == null) { + return new String[0]; + } + for (int f=0; f<files.length; f++) { + files[f] = files[f].toLowerCase(); + } + return files; + } else { + ArrayList<String> fileList = new ArrayList<>(); + for (int i = 0; i< pathDirs.length; i++) { + File dir = new File(pathDirs[i]); + String[] files = dir.list(filter); + if (files == null) { + continue; + } + for (int f = 0; f < files.length ; f++) { + fileList.add(files[f].toLowerCase()); } } - }); + return fileList.toArray(STR_ARRAY); + } } /* This is needed since some windows registry names don't match @@ -1430,7 +1409,6 @@ public HashMap<String, FamilyDescription> populateHardcodedFileNameMap() { return new HashMap<>(0); } - @SuppressWarnings("removal") Font2D findFontFromPlatformMap(String lcName, int style) { HashMap<String, FamilyDescription> platformFontMap = SunFontManager.platformFontMap; if (platformFontMap == null) { @@ -1524,20 +1502,16 @@ Font2D findFontFromPlatformMap(String lcName, int style) { final String[] files = { plainFile, boldFile, italicFile, boldItalicFile } ; - failure = AccessController.doPrivileged(new PrivilegedAction<Boolean>() { - public Boolean run() { - for (int i=0; i<files.length; i++) { - if (files[i] == null) { - continue; - } - File f = new File(files[i]); - if (!f.exists()) { - return Boolean.TRUE; - } - } - return Boolean.FALSE; + for (int i=0; i<files.length; i++) { + if (files[i] == null) { + continue; + } + File f = new File(files[i]); + if (!f.exists()) { + failure = true; + break; } - }); + } if (failure) { if (FontUtilities.isLogging()) { @@ -1724,21 +1698,11 @@ private String getPathName(final String s) { } else if (pathDirs.length==1) { return pathDirs[0] + File.separator + s; } else { - @SuppressWarnings("removal") - String path = AccessController.doPrivileged( - new PrivilegedAction<String>() { - public String run() { - for (int p = 0; p < pathDirs.length; p++) { - File f = new File(pathDirs[p] +File.separator+ s); - if (f.exists()) { - return f.getAbsolutePath(); - } - } - return null; - } - }); - if (path != null) { - return path; + for (int p = 0; p < pathDirs.length; p++) { + f = new File(pathDirs[p] + File.separator + s); + if (f.exists()) { + return f.getAbsolutePath(); + } } } return s; // shouldn't happen, but harmless @@ -2181,7 +2145,6 @@ private static boolean fontSupportsEncoding(Font font, String encoding) { private int createdFontCount = 0; - @SuppressWarnings("removal") public Font2D[] createFont2D(File fontFile, int fontFormat, boolean all, boolean isCopy, CreatedFontTracker tracker) throws FontFormatException { @@ -2229,15 +2192,10 @@ public Font2D[] createFont2D(File fontFile, int fontFormat, boolean all, } } catch (FontFormatException e) { if (isCopy) { - AccessController.doPrivileged(new PrivilegedAction<Void>() { - public Void run() { - if (_tracker != null) { - _tracker.subBytes((int)fFile.length()); - } - fFile.delete(); - return null; - } - }); + if (_tracker != null) { + _tracker.subBytes((int)fFile.length()); + } + fFile.delete(); } throw(e); } @@ -2253,39 +2211,31 @@ public Void run() { if (fileCloser == null) { final Runnable fileCloserRunnable = new Runnable() { public void run() { - AccessController.doPrivileged(new PrivilegedAction<Void>() { - public Void run() { - for (int i = 0;i < CHANNELPOOLSIZE; i++) { - if (fontFileCache[i] != null) { - try { - fontFileCache[i].close(); - } catch (Exception e) { - } - } + for (int i = 0;i < CHANNELPOOLSIZE; i++) { + if (fontFileCache[i] != null) { + try { + fontFileCache[i].close(); + } catch (Exception e) { } - if (tmpFontFiles != null) { - File[] files = new File[tmpFontFiles.size()]; - files = tmpFontFiles.toArray(files); - for (int f=0; f<files.length;f++) { - try { - files[f].delete(); - } catch (Exception e) { - } - } + } + } + if (tmpFontFiles != null) { + File[] files = new File[tmpFontFiles.size()]; + files = tmpFontFiles.toArray(files); + for (int f=0; f<files.length;f++) { + try { + files[f].delete(); + } catch (Exception e) { } - return null; } - }); + } } }; - AccessController.doPrivileged((PrivilegedAction<Void>) () -> { - ThreadGroup rootTG = ThreadGroupUtils.getRootThreadGroup(); - fileCloser = new Thread(rootTG, fileCloserRunnable, - "FileCloser", 0, false); - fileCloser.setContextClassLoader(null); - Runtime.getRuntime().addShutdownHook(fileCloser); - return null; - }); + ThreadGroup rootTG = ThreadGroupUtils.getRootThreadGroup(); + fileCloser = new Thread(rootTG, fileCloserRunnable, + "FileCloser", 0, false); + fileCloser.setContextClassLoader(null); + Runtime.getRuntime().addShutdownHook(fileCloser); } } } @@ -2930,7 +2880,6 @@ public String getPlatformFontPath(boolean noType1Font) { return fontPath; } - @SuppressWarnings("removal") protected void loadFonts() { if (discoveredAllFonts) { return; @@ -2943,28 +2892,23 @@ protected void loadFonts() { } initialiseDeferredFonts(); - AccessController.doPrivileged(new PrivilegedAction<Void>() { - public Void run() { - if (fontPath == null) { - fontPath = getPlatformFontPath(noType1Font); - registerFontDirs(fontPath); - } - if (fontPath != null) { - // this will find all fonts including those already - // registered. But we have checks in place to prevent - // double registration. - if (! gotFontsFromPlatform()) { - registerFontsOnPath(fontPath, false, - Font2D.UNKNOWN_RANK, - false, true); - loadedAllFontFiles = true; - } - } - registerOtherFontFiles(registeredFontFiles); - discoveredAllFonts = true; - return null; + if (fontPath == null) { + fontPath = getPlatformFontPath(noType1Font); + registerFontDirs(fontPath); + } + if (fontPath != null) { + // this will find all fonts including those already + // registered. But we have checks in place to prevent + // double registration. + if (! gotFontsFromPlatform()) { + registerFontsOnPath(fontPath, false, + Font2D.UNKNOWN_RANK, + false, true); + loadedAllFontFiles = true; } - }); + } + registerOtherFontFiles(registeredFontFiles); + discoveredAllFonts = true; } } @@ -3048,7 +2992,6 @@ public synchronized String getDefaultFontFaceName() { return defaultFontName; } - @SuppressWarnings("removal") public void loadFontFiles() { loadFonts(); if (loadedAllFontFiles) { @@ -3060,23 +3003,18 @@ public void loadFontFiles() { Thread.dumpStack(); FontUtilities.logInfo("loadAllFontFiles() called"); } - AccessController.doPrivileged(new PrivilegedAction<Void>() { - public Void run() { - if (fontPath == null) { - fontPath = getPlatformFontPath(noType1Font); - } - if (fontPath != null) { - // this will find all fonts including those already - // registered. But we have checks in place to prevent - // double registration. - registerFontsOnPath(fontPath, false, - Font2D.UNKNOWN_RANK, - false, true); - } - loadedAllFontFiles = true; - return null; - } - }); + if (fontPath == null) { + fontPath = getPlatformFontPath(noType1Font); + } + if (fontPath != null) { + // this will find all fonts including those already + // registered. But we have checks in place to prevent + // double registration. + registerFontsOnPath(fontPath, false, + Font2D.UNKNOWN_RANK, + false, true); + } + loadedAllFontFiles = true; } } @@ -3402,16 +3340,9 @@ public String[] getInstalledFontFamilyNames(Locale requestedLocale) { // Provides an aperture to add native font family names to the map protected void addNativeFontFamilyNames(TreeMap<String, String> familyNames, Locale requestedLocale) { } - @SuppressWarnings("removal") public void register1dot0Fonts() { - AccessController.doPrivileged(new PrivilegedAction<Void>() { - public Void run() { - String type1Dir = "/usr/openwin/lib/X11/fonts/Type1"; - registerFontsInDir(type1Dir, true, Font2D.TYPE1_RANK, - false, false); - return null; - } - }); + String type1Dir = "/usr/openwin/lib/X11/fonts/Type1"; + registerFontsInDir(type1Dir, true, Font2D.TYPE1_RANK, false, false); } /* Really we need only the JRE fonts family names, but there's little @@ -3442,33 +3373,28 @@ protected void getJREFontFamilyNames(TreeMap<String,String> familyNames, * on windows and uses that if set. */ private static Locale systemLocale = null; - @SuppressWarnings("removal") private static Locale getSystemStartupLocale() { if (systemLocale == null) { - systemLocale = AccessController.doPrivileged(new PrivilegedAction<Locale>() { - public Locale run() { - /* On windows the system locale may be different than the - * user locale. This is an unsupported configuration, but - * in that case we want to return a dummy locale that will - * never cause a match in the usage of this API. This is - * important because Windows documents that the family - * names of fonts are enumerated using the language of - * the system locale. BY returning a dummy locale in that - * case we do not use the platform API which would not - * return us the names we want. - */ - String fileEncoding = System.getProperty("file.encoding", ""); - String sysEncoding = System.getProperty("sun.jnu.encoding"); - if (sysEncoding != null && !sysEncoding.equals(fileEncoding)) { - return Locale.ROOT; - } - - String language = System.getProperty("user.language", "en"); - String country = System.getProperty("user.country",""); - String variant = System.getProperty("user.variant",""); - return Locale.of(language, country, variant); - } - }); + /* On windows the system locale may be different than the + * user locale. This is an unsupported configuration, but + * in that case we want to return a dummy locale that will + * never cause a match in the usage of this API. This is + * important because Windows documents that the family + * names of fonts are enumerated using the language of + * the system locale. BY returning a dummy locale in that + * case we do not use the platform API which would not + * return us the names we want. + */ + String fileEncoding = System.getProperty("file.encoding", ""); + String sysEncoding = System.getProperty("sun.jnu.encoding"); + if (sysEncoding != null && !sysEncoding.equals(fileEncoding)) { + systemLocale = Locale.ROOT; + } else { + String language = System.getProperty("user.language", "en"); + String country = System.getProperty("user.country",""); + String variant = System.getProperty("user.variant",""); + systemLocale = Locale.of(language, country, variant); + } } return systemLocale; } diff --git a/src/java.desktop/share/classes/sun/font/SunLayoutEngine.java b/src/java.desktop/share/classes/sun/font/SunLayoutEngine.java index c291e45b558..f1d6de7d4bc 100644 --- a/src/java.desktop/share/classes/sun/font/SunLayoutEngine.java +++ b/src/java.desktop/share/classes/sun/font/SunLayoutEngine.java @@ -37,8 +37,6 @@ import java.awt.geom.Point2D; import java.lang.foreign.MemorySegment; import java.lang.ref.SoftReference; -import java.security.AccessController; -import java.security.PrivilegedAction; import java.util.concurrent.ConcurrentHashMap; import java.util.WeakHashMap; @@ -167,10 +165,7 @@ private long getFacePtr(Font2D font2D) { static boolean useFFM = true; static { - @SuppressWarnings("removal") - String prop = AccessController.doPrivileged( - (PrivilegedAction<String>) () -> - System.getProperty("sun.font.layout.ffm", "true")); + String prop = System.getProperty("sun.font.layout.ffm", "true"); useFFM = "true".equals(prop); } diff --git a/src/java.desktop/share/classes/sun/font/TrueTypeFont.java b/src/java.desktop/share/classes/sun/font/TrueTypeFont.java index 3895ec6ca82..a44a013b749 100644 --- a/src/java.desktop/share/classes/sun/font/TrueTypeFont.java +++ b/src/java.desktop/share/classes/sun/font/TrueTypeFont.java @@ -38,9 +38,6 @@ import java.nio.ShortBuffer; import java.nio.channels.ClosedChannelException; import java.nio.channels.FileChannel; -import java.security.AccessController; -import java.security.PrivilegedActionException; -import java.security.PrivilegedExceptionAction; import java.util.HashMap; import java.util.HashSet; import java.util.Locale; @@ -246,13 +243,7 @@ private synchronized FileChannel open(boolean usePool) FontUtilities.logInfo("open TTF: " + platName); } try { - @SuppressWarnings("removal") - RandomAccessFile raf = AccessController.doPrivileged( - new PrivilegedExceptionAction<RandomAccessFile>() { - public RandomAccessFile run() throws FileNotFoundException { - return new RandomAccessFile(platName, "r"); - } - }); + RandomAccessFile raf = new RandomAccessFile(platName, "r"); disposerRecord.channel = raf.getChannel(); fileSize = (int)disposerRecord.channel.size(); if (usePool) { @@ -261,13 +252,6 @@ public RandomAccessFile run() throws FileNotFoundException { ((SunFontManager) fm).addToPool(this); } } - } catch (PrivilegedActionException e) { - close(); - Throwable reason = e.getCause(); - if (reason == null) { - reason = e; - } - throw new FontFormatException(reason.toString()); } catch (ClosedChannelException e) { /* NIO I/O is interruptible, recurse to retry operation. * The call to channel.size() above can throw this exception. @@ -664,7 +648,6 @@ && getDirectoryEntry(hheaTag) == null) { }; private static String defaultCodePage = null; - @SuppressWarnings("removal") static String getCodePage() { if (defaultCodePage != null) { @@ -672,8 +655,7 @@ static String getCodePage() { } if (FontUtilities.isWindows) { - defaultCodePage = - AccessController.doPrivileged(new GetPropertyAction("file.encoding")); + defaultCodePage = System.getProperty("file.encoding"); } else { if (languages.length != codePages.length) { throw new InternalError("wrong code pages array length"); diff --git a/src/java.desktop/share/classes/sun/font/Type1Font.java b/src/java.desktop/share/classes/sun/font/Type1Font.java index cc36c193de0..67f83cce643 100644 --- a/src/java.desktop/share/classes/sun/font/Type1Font.java +++ b/src/java.desktop/share/classes/sun/font/Type1Font.java @@ -83,18 +83,10 @@ private static class T1DisposerRecord implements DisposerRecord { fileName = name; } - @SuppressWarnings("removal") public synchronized void dispose() { - java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction<Object>() { - public Object run() { - - if (fileName != null) { - (new java.io.File(fileName)).delete(); - } - return null; - } - }); + if (fileName != null) { + (new java.io.File(fileName)).delete(); + } } } @@ -191,18 +183,11 @@ private synchronized ByteBuffer getBuffer() throws FontFormatException { FontUtilities.logInfo("open Type 1 font: " + platName); } try { - @SuppressWarnings("removal") - RandomAccessFile raf = (RandomAccessFile) - java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction<Object>() { - public Object run() { - try { - return new RandomAccessFile(platName, "r"); - } catch (FileNotFoundException ffne) { - } - return null; - } - }); + RandomAccessFile raf = null; + try { + raf = new RandomAccessFile(platName, "r"); + } catch (FileNotFoundException ffne) { + } FileChannel fc = raf.getChannel(); fileSize = (int)fc.size(); bbuf = ByteBuffer.allocate(fileSize); @@ -227,7 +212,6 @@ protected void close() { } /* called from native code to read file into a direct byte buffer */ - @SuppressWarnings("removal") void readFile(ByteBuffer buffer) { RandomAccessFile raf = null; FileChannel fc; @@ -235,17 +219,10 @@ void readFile(ByteBuffer buffer) { FontUtilities.logInfo("open Type 1 font: " + platName); } try { - raf = (RandomAccessFile) - java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction<Object>() { - public Object run() { - try { - return new RandomAccessFile(platName, "r"); - } catch (FileNotFoundException fnfe) { - } - return null; - } - }); + try { + raf = new RandomAccessFile(platName, "r"); + } catch (FileNotFoundException fnfe) { + } fc = raf.getChannel(); while (buffer.remaining() > 0 && fc.read(buffer) != -1) {} } catch (ClosedChannelException e) { From cd45ba32f026ba3827d18836cab37a73f59346ed Mon Sep 17 00:00:00 2001 From: Xiaolong Peng <xpeng@openjdk.org> Date: Tue, 19 Nov 2024 20:18:54 +0000 Subject: [PATCH 108/311] 8342041: Test gc/shenandoah/oom/TestClassLoaderLeak.java slow on Windows after JDK-8340490 Reviewed-by: shade, wkemper --- src/hotspot/share/gc/shenandoah/shenandoahPacer.cpp | 10 +++++----- .../jtreg/gc/shenandoah/oom/TestClassLoaderLeak.java | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/hotspot/share/gc/shenandoah/shenandoahPacer.cpp b/src/hotspot/share/gc/shenandoah/shenandoahPacer.cpp index 8d10b7cbfcf..e7d5a2e00c5 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahPacer.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahPacer.cpp @@ -253,9 +253,9 @@ void ShenandoahPacer::pace_for_alloc(size_t words) { return; } - jlong const max_delay = ShenandoahPacingMaxDelay * NANOSECS_PER_MILLISEC; - jlong const start_time = os::elapsed_counter(); - while (!claimed && (os::elapsed_counter() - start_time) < max_delay) { + jlong const start_time = os::javaTimeNanos(); + jlong const deadline = start_time + (ShenandoahPacingMaxDelay * NANOSECS_PER_MILLISEC); + while (!claimed && os::javaTimeNanos() < deadline) { // We could instead assist GC, but this would suffice for now. wait(1); claimed = claim_for_alloc<false>(words); @@ -267,7 +267,7 @@ void ShenandoahPacer::pace_for_alloc(size_t words) { claimed = claim_for_alloc<true>(words); assert(claimed, "Should always succeed"); } - ShenandoahThreadLocalData::add_paced_time(current, (double)(os::elapsed_counter() - start_time) / NANOSECS_PER_SEC); + ShenandoahThreadLocalData::add_paced_time(current, (double)(os::javaTimeNanos() - start_time) / NANOSECS_PER_SEC); } void ShenandoahPacer::wait(size_t time_ms) { @@ -276,7 +276,7 @@ void ShenandoahPacer::wait(size_t time_ms) { assert(time_ms > 0, "Should not call this with zero argument, as it would stall until notify"); assert(time_ms <= LONG_MAX, "Sanity"); MonitorLocker locker(_wait_monitor); - _wait_monitor->wait((long)time_ms); + _wait_monitor->wait(time_ms); } void ShenandoahPacer::notify_waiters() { diff --git a/test/hotspot/jtreg/gc/shenandoah/oom/TestClassLoaderLeak.java b/test/hotspot/jtreg/gc/shenandoah/oom/TestClassLoaderLeak.java index 00e32a4136e..1a3d07bf80d 100644 --- a/test/hotspot/jtreg/gc/shenandoah/oom/TestClassLoaderLeak.java +++ b/test/hotspot/jtreg/gc/shenandoah/oom/TestClassLoaderLeak.java @@ -27,7 +27,7 @@ * @summary Test OOME in due to classloader leak * @requires vm.gc.Shenandoah * @library /test/lib - * @run driver/timeout=600 TestClassLoaderLeak + * @run driver TestClassLoaderLeak */ import java.util.*; From aac1f9af01b15aac0c6ca923b49f5577ee8ce104 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Laurent=20Bourg=C3=A8s?= <lbourges@openjdk.org> Date: Tue, 19 Nov 2024 20:28:58 +0000 Subject: [PATCH 109/311] 8341793: Fix ExceptionOccurred in jdk.accessibility Reviewed-by: prr, avu --- .../AccessBridgeJavaEntryPoints.cpp | 142 ++++-------------- 1 file changed, 30 insertions(+), 112 deletions(-) diff --git a/src/jdk.accessibility/windows/native/libjavaaccessbridge/AccessBridgeJavaEntryPoints.cpp b/src/jdk.accessibility/windows/native/libjavaaccessbridge/AccessBridgeJavaEntryPoints.cpp index 6f4231b70b9..8610617f7eb 100644 --- a/src/jdk.accessibility/windows/native/libjavaaccessbridge/AccessBridgeJavaEntryPoints.cpp +++ b/src/jdk.accessibility/windows/native/libjavaaccessbridge/AccessBridgeJavaEntryPoints.cpp @@ -74,36 +74,36 @@ AccessBridgeJavaEntryPoints::~AccessBridgeJavaEntryPoints() { return FALSE; \ } -#define EXCEPTION_CHECK(situationDescription, returnVal) \ - if (exception = jniEnv->ExceptionOccurred()) { \ - PrintDebugString("[ERROR]: *** Exception occured while doing: %s; returning %d", situationDescription, returnVal); \ - jniEnv->ExceptionDescribe(); \ - jniEnv->ExceptionClear(); \ - return (returnVal); \ - } - -#define EXCEPTION_CHECK_WITH_RELEASE(situationDescription, returnVal, js, stringBytes) \ - if (exception = jniEnv->ExceptionOccurred()) { \ - PrintDebugString("[ERROR]: *** Exception occured while doing: %s - call to GetStringLength; returning %d", situationDescription, returnVal); \ - jniEnv->ExceptionDescribe(); \ - jniEnv->ExceptionClear(); \ - jniEnv->ReleaseStringChars(js, stringBytes); \ - return (returnVal); \ - } \ - jniEnv->ReleaseStringChars(js, stringBytes); \ - if (exception = jniEnv->ExceptionOccurred()) { \ - PrintDebugString("[ERROR]: *** Exception occured while doing: %s - call to ReleaseStringChars; returning %d", situationDescription, returnVal); \ - jniEnv->ExceptionDescribe(); \ - jniEnv->ExceptionClear(); \ - return (returnVal); \ - } - -#define EXCEPTION_CHECK_VOID(situationDescription) \ - if (exception = jniEnv->ExceptionOccurred()) { \ +#define EXCEPTION_CHECK(situationDescription, returnVal) \ + if (jniEnv->ExceptionCheck()) { \ + PrintDebugString("[ERROR]: *** Exception occured while doing: %s; returning %d", situationDescription, returnVal); \ + jniEnv->ExceptionDescribe(); \ + jniEnv->ExceptionClear(); \ + return (returnVal); \ + } + +#define EXCEPTION_CHECK_WITH_RELEASE(situationDescription, returnVal, js, stringBytes) \ + if (jniEnv->ExceptionCheck()) { \ + PrintDebugString("[ERROR]: *** Exception occured while doing: %s - call to GetStringLength; returning %d", situationDescription, returnVal); \ + jniEnv->ExceptionDescribe(); \ + jniEnv->ExceptionClear(); \ + jniEnv->ReleaseStringChars(js, stringBytes); \ + return (returnVal); \ + } \ + jniEnv->ReleaseStringChars(js, stringBytes); \ + if (jniEnv->ExceptionCheck()) { \ + PrintDebugString("[ERROR]: *** Exception occured while doing: %s - call to ReleaseStringChars; returning %d", situationDescription, returnVal); \ + jniEnv->ExceptionDescribe(); \ + jniEnv->ExceptionClear(); \ + return (returnVal); \ + } + +#define EXCEPTION_CHECK_VOID(situationDescription) \ + if (jniEnv->ExceptionCheck()) { \ PrintDebugString("[ERROR]: *** Exception occured while doing: %s", situationDescription); \ - jniEnv->ExceptionDescribe(); \ - jniEnv->ExceptionClear(); \ - return; \ + jniEnv->ExceptionDescribe(); \ + jniEnv->ExceptionClear(); \ + return; \ } /** @@ -890,7 +890,6 @@ AccessBridgeJavaEntryPoints::BuildJavaEntryPoints() { */ BOOL AccessBridgeJavaEntryPoints::isJavaWindow(jint window) { - jthrowable exception; BOOL returnVal; PrintDebugString("[INFO]: Calling AccessBridgeJavaEntryPoints::isJavaWindow(%X):", window); @@ -913,7 +912,6 @@ AccessBridgeJavaEntryPoints::isJavaWindow(jint window) { */ BOOL AccessBridgeJavaEntryPoints::isSameObject(jobject obj1, jobject obj2) { - jthrowable exception; BOOL returnVal; PrintDebugString("[INFO]: In AccessBridgeJavaEntryPoints::isSameObject(%p %p):", obj1, obj2); @@ -935,7 +933,6 @@ jobject AccessBridgeJavaEntryPoints::getAccessibleContextFromHWND(jint window) { jobject returnedAccessibleContext; jobject globalRef; - jthrowable exception; PrintDebugString("[INFO]: In AccessBridgeJavaEntryPoints::getAccessibleContextFromHWND(%X):", window); @@ -961,7 +958,6 @@ AccessBridgeJavaEntryPoints::getAccessibleContextFromHWND(jint window) { */ HWND AccessBridgeJavaEntryPoints::getHWNDFromAccessibleContext(jobject accessibleContext) { - jthrowable exception; HWND rHWND; PrintDebugString("[INFO]: In AccessBridgeJavaEntryPoints::getHWNDFromAccessibleContext(%X):", @@ -987,7 +983,6 @@ AccessBridgeJavaEntryPoints::getHWNDFromAccessibleContext(jobject accessibleCont */ BOOL AccessBridgeJavaEntryPoints::setTextContents(const jobject accessibleContext, const wchar_t *text) { - jthrowable exception; BOOL result = FALSE; PrintDebugString("[INFO]: In AccessBridgeJavaEntryPoints::setTextContents(%p, %ls):", @@ -1024,7 +1019,6 @@ AccessBridgeJavaEntryPoints::setTextContents(const jobject accessibleContext, co */ jobject AccessBridgeJavaEntryPoints::getParentWithRole(const jobject accessibleContext, const wchar_t *role) { - jthrowable exception; jobject rAccessibleContext; PrintDebugString("[INFO]: In AccessBridgeJavaEntryPoints::getParentWithRole(%p):", @@ -1062,7 +1056,6 @@ AccessBridgeJavaEntryPoints::getParentWithRole(const jobject accessibleContext, */ jobject AccessBridgeJavaEntryPoints::getTopLevelObject(const jobject accessibleContext) { - jthrowable exception; jobject rAccessibleContext; PrintDebugString("[INFO]: In AccessBridgeJavaEntryPoints::getTopLevelObject(%p):", @@ -1093,7 +1086,6 @@ AccessBridgeJavaEntryPoints::getTopLevelObject(const jobject accessibleContext) */ jobject AccessBridgeJavaEntryPoints::getParentWithRoleElseRoot(const jobject accessibleContext, const wchar_t *role) { - jthrowable exception; jobject rAccessibleContext; PrintDebugString("[INFO]: In AccessBridgeJavaEntryPoints::getParentWithRoleElseRoot(%p):", @@ -1131,7 +1123,6 @@ AccessBridgeJavaEntryPoints::getParentWithRoleElseRoot(const jobject accessibleC */ jint AccessBridgeJavaEntryPoints::getObjectDepth(const jobject accessibleContext) { - jthrowable exception; jint rResult; PrintDebugString("[INFO]: In AccessBridgeJavaEntryPoints::getObjectDepth(%p):", @@ -1158,7 +1149,6 @@ AccessBridgeJavaEntryPoints::getObjectDepth(const jobject accessibleContext) { */ jobject AccessBridgeJavaEntryPoints::getActiveDescendent(const jobject accessibleContext) { - jthrowable exception; jobject rAccessibleContext; PrintDebugString("[INFO]: In AccessBridgeJavaEntryPoints::getActiveDescendent(%p):", @@ -1215,7 +1205,6 @@ AccessBridgeJavaEntryPoints::getVirtualAccessibleName ( jstring js = NULL; const wchar_t * stringBytes = NULL; - jthrowable exception = NULL; jsize length = 0; PrintDebugString("[INFO]: getVirtualAccessibleName called."); if (getVirtualAccessibleNameFromContextMethod != (jmethodID) 0) @@ -1266,7 +1255,6 @@ AccessBridgeJavaEntryPoints::getVirtualAccessibleName ( BOOL AccessBridgeJavaEntryPoints::requestFocus(const jobject accessibleContext) { - jthrowable exception; BOOL result = FALSE; PrintDebugString("[INFO]: In AccessBridgeJavaEntryPoints::requestFocus(%p):", @@ -1294,7 +1282,6 @@ AccessBridgeJavaEntryPoints::requestFocus(const jobject accessibleContext) { BOOL AccessBridgeJavaEntryPoints::selectTextRange(const jobject accessibleContext, int startIndex, int endIndex) { - jthrowable exception; BOOL result = FALSE; PrintDebugString("[INFO]: In AccessBridgeJavaEntryPoints::selectTextRange(%p start = %d end = %d):", @@ -1362,7 +1349,6 @@ AccessBridgeJavaEntryPoints::getTextAttributesInRange(const jobject accessibleCo jstring js; const wchar_t *stringBytes; - jthrowable exception; jsize length; BOOL result = FALSE; @@ -1429,7 +1415,6 @@ AccessBridgeJavaEntryPoints::getTextAttributesInRange(const jobject accessibleCo int AccessBridgeJavaEntryPoints::getVisibleChildrenCount(const jobject accessibleContext) { - jthrowable exception; PrintDebugString("[INFO]: ##### AccessBridgeJavaEntryPoints::getVisibleChildrenCount(%p)", accessibleContext); @@ -1455,8 +1440,6 @@ BOOL AccessBridgeJavaEntryPoints::getVisibleChildren(const jobject accessibleCon const int nStartIndex, /* OUT */ VisibleChildrenInfo *visibleChildrenInfo) { - jthrowable exception; - PrintDebugString("[INFO]: ##### AccessBridgeJavaEntryPoints::getVisibleChildren(%p, startIndex = %d)", accessibleContext, nStartIndex); @@ -1500,7 +1483,6 @@ BOOL AccessBridgeJavaEntryPoints::getVisibleChildren(const jobject accessibleCon BOOL AccessBridgeJavaEntryPoints::setCaretPosition(const jobject accessibleContext, int position) { - jthrowable exception; BOOL result = FALSE; PrintDebugString("[INFO]: In AccessBridgeJavaEntryPoints::setCaretPostion(%p position = %d):", @@ -1531,7 +1513,6 @@ BOOL AccessBridgeJavaEntryPoints::getVersionInfo(AccessBridgeVersionInfo *info) { jstring js; const wchar_t *stringBytes; - jthrowable exception; jsize length; PrintDebugString("[INFO]: Calling AccessBridgeJavaEntryPoints::getVersionInfo():"); @@ -1601,7 +1582,6 @@ AccessBridgeJavaEntryPoints::getVersionInfo(AccessBridgeVersionInfo *info) { BOOL AccessBridgeJavaEntryPoints::verifyAccessibleText(jobject obj) { JavaVM *vm; BOOL retval; - jthrowable exception; PrintDebugString("[INFO]: Calling AccessBridgeJavaEntryPoints::verifyAccessibleText"); @@ -1653,7 +1633,6 @@ jobject AccessBridgeJavaEntryPoints::getAccessibleContextAt(jint x, jint y, jobject accessibleContext) { jobject returnedAccessibleContext; jobject globalRef; - jthrowable exception; PrintDebugString("[INFO]: Calling AccessBridgeJavaEntryPoints::getAccessibleContextAt(%d, %d, %p):", x, y, accessibleContext); @@ -1688,7 +1667,6 @@ jobject AccessBridgeJavaEntryPoints::getAccessibleContextWithFocus() { jobject returnedAccessibleContext; jobject globalRef; - jthrowable exception; PrintDebugString("[INFO]: Calling AccessBridgeJavaEntryPoints::getAccessibleContextWithFocus()"); @@ -1724,7 +1702,6 @@ AccessBridgeJavaEntryPoints::getAccessibleContextInfo(jobject accessibleContext, jstring js; const wchar_t *stringBytes; jobject returnedJobject; - jthrowable exception; jsize length; PrintDebugString("[INFO]: ##### Calling AccessBridgeJavaEntryPoints::getAccessibleContextInfo(%p):", accessibleContext); @@ -2156,7 +2133,6 @@ jobject AccessBridgeJavaEntryPoints::getAccessibleChildFromContext(jobject accessibleContext, jint childIndex) { jobject returnedAccessibleContext; jobject globalRef; - jthrowable exception; PrintDebugString("[INFO]: Calling AccessBridgeJavaEntryPoints::getAccessibleChildContext(%p, %d):", accessibleContext, childIndex); @@ -2188,7 +2164,6 @@ AccessBridgeJavaEntryPoints::getAccessibleParentFromContext(jobject accessibleCo { jobject returnedAccessibleContext; jobject globalRef; - jthrowable exception; PrintDebugString("[INFO]: Calling AccessBridgeJavaEntryPoints::getAccessibleParentFromContext(%p):", accessibleContext); @@ -2217,8 +2192,6 @@ BOOL AccessBridgeJavaEntryPoints::getAccessibleTableInfo(jobject accessibleContext, AccessibleTableInfo *tableInfo) { - jthrowable exception; - PrintDebugString("[INFO]: ##### Calling AccessBridgeJavaEntryPoints::getAccessibleTableInfo(%p):", accessibleContext); @@ -2292,8 +2265,6 @@ BOOL AccessBridgeJavaEntryPoints::getAccessibleTableCellInfo(jobject accessibleTable, jint row, jint column, AccessibleTableCellInfo *tableCellInfo) { - jthrowable exception; - PrintDebugString("[INFO]: ##### Calling AccessBridgeJavaEntryPoints::getAccessibleTableCellInfo(%p): row=%d, column=%d", accessibleTable, row, column); @@ -2373,8 +2344,6 @@ AccessBridgeJavaEntryPoints::getAccessibleTableCellInfo(jobject accessibleTable, BOOL AccessBridgeJavaEntryPoints::getAccessibleTableRowHeader(jobject acParent, AccessibleTableInfo *tableInfo) { - jthrowable exception; - PrintDebugString("[INFO]: ##### Calling AccessBridgeJavaEntryPoints::getAccessibleTableRowHeader(%p):", acParent); @@ -2428,7 +2397,6 @@ AccessBridgeJavaEntryPoints::getAccessibleTableRowHeader(jobject acParent, Acces BOOL AccessBridgeJavaEntryPoints::getAccessibleTableColumnHeader(jobject acParent, AccessibleTableInfo *tableInfo) { - jthrowable exception; PrintDebugString("[INFO]: ##### Calling AccessBridgeJavaEntryPoints::getAccessibleTableColumnHeader(%p):", acParent); @@ -2485,7 +2453,6 @@ AccessBridgeJavaEntryPoints::getAccessibleTableRowDescription(jobject acParent, jobject returnedAccessibleContext; jobject globalRef; - jthrowable exception; PrintDebugString("[INFO]: ##### Calling AccessBridgeJavaEntryPoints::getAccessibleTableRowDescription(%p):", acParent); @@ -2513,7 +2480,6 @@ AccessBridgeJavaEntryPoints::getAccessibleTableColumnDescription(jobject acParen jobject returnedAccessibleContext; jobject globalRef; - jthrowable exception; PrintDebugString("[INFO]: ##### Calling AccessBridgeJavaEntryPoints::getAccessibleTableColumnDescription(%p):", acParent); @@ -2540,7 +2506,6 @@ AccessBridgeJavaEntryPoints::getAccessibleTableColumnDescription(jobject acParen jint AccessBridgeJavaEntryPoints::getAccessibleTableRowSelectionCount(jobject accessibleTable) { - jthrowable exception; jint count; PrintDebugString("[INFO]: ##### AccessBridgeJavaEntryPoints::getAccessibleTableRowSelectionCount(%p)", @@ -2565,7 +2530,6 @@ AccessBridgeJavaEntryPoints::getAccessibleTableRowSelectionCount(jobject accessi BOOL AccessBridgeJavaEntryPoints::isAccessibleTableRowSelected(jobject accessibleTable, jint row) { - jthrowable exception; BOOL result; PrintDebugString("[INFO]: ##### AccessBridgeJavaEntryPoints::isAccessibleTableRowSelected(%p, %d)", @@ -2591,7 +2555,6 @@ BOOL AccessBridgeJavaEntryPoints::getAccessibleTableRowSelections(jobject accessibleTable, jint count, jint *selections) { - jthrowable exception; PrintDebugString("[INFO]: ##### AccessBridgeJavaEntryPoints::getAccessibleTableRowSelections(%p, %d %p)", accessibleTable, count, selections); @@ -2618,7 +2581,6 @@ AccessBridgeJavaEntryPoints::getAccessibleTableRowSelections(jobject accessibleT jint AccessBridgeJavaEntryPoints::getAccessibleTableColumnSelectionCount(jobject accessibleTable) { - jthrowable exception; jint count; PrintDebugString("[INFO]: ##### AccessBridgeJavaEntryPoints::getAccessibleTableColumnSelectionCount(%p)", @@ -2643,7 +2605,6 @@ AccessBridgeJavaEntryPoints::getAccessibleTableColumnSelectionCount(jobject acce BOOL AccessBridgeJavaEntryPoints::isAccessibleTableColumnSelected(jobject accessibleTable, jint column) { - jthrowable exception; BOOL result; PrintDebugString("[INFO]: ##### AccessBridgeJavaEntryPoints::isAccessibleTableColumnSelected(%p, %d)", @@ -2668,7 +2629,6 @@ AccessBridgeJavaEntryPoints::isAccessibleTableColumnSelected(jobject accessibleT BOOL AccessBridgeJavaEntryPoints::getAccessibleTableColumnSelections(jobject accessibleTable, jint count, jint *selections) { - jthrowable exception; PrintDebugString("[INFO]: ##### AccessBridgeJavaEntryPoints::getAccessibleTableColumnSelections(%p, %d, %p)", accessibleTable, count, selections); @@ -2694,7 +2654,6 @@ AccessBridgeJavaEntryPoints::getAccessibleTableColumnSelections(jobject accessib jint AccessBridgeJavaEntryPoints::getAccessibleTableRow(jobject accessibleTable, jint index) { - jthrowable exception; jint result; PrintDebugString("[INFO]: ##### AccessBridgeJavaEntryPoints::getAccessibleTableRow(%p, index=%d)", @@ -2718,7 +2677,6 @@ AccessBridgeJavaEntryPoints::getAccessibleTableRow(jobject accessibleTable, jint jint AccessBridgeJavaEntryPoints::getAccessibleTableColumn(jobject accessibleTable, jint index) { - jthrowable exception; jint result; PrintDebugString("[INFO]: ##### AccessBridgeJavaEntryPoints::getAccessibleTableColumn(%p, index=%d)", @@ -2742,7 +2700,6 @@ AccessBridgeJavaEntryPoints::getAccessibleTableColumn(jobject accessibleTable, j jint AccessBridgeJavaEntryPoints::getAccessibleTableIndex(jobject accessibleTable, jint row, jint column) { - jthrowable exception; jint result; PrintDebugString("[INFO]: ##### AccessBridgeJavaEntryPoints::getAccessibleTableIndex(%p, row=%d, col=%d)", @@ -2773,7 +2730,6 @@ BOOL AccessBridgeJavaEntryPoints::getAccessibleRelationSet(jobject accessibleContext, AccessibleRelationSetInfo *relationSet) { - jthrowable exception; const wchar_t *stringBytes; jsize length; @@ -2853,7 +2809,6 @@ BOOL AccessBridgeJavaEntryPoints::getAccessibleHypertext(jobject accessibleContext, AccessibleHypertextInfo *hypertext) { - jthrowable exception; const wchar_t *stringBytes; jsize length; @@ -2953,7 +2908,6 @@ BOOL AccessBridgeJavaEntryPoints::activateAccessibleHyperlink(jobject accessibleContext, jobject accessibleHyperlink) { - jthrowable exception; BOOL returnVal; PrintDebugString("[INFO]: Calling AccessBridgeJavaEntryPoints::activateAccessibleHyperlink(%p, %p):", @@ -2983,7 +2937,6 @@ AccessBridgeJavaEntryPoints::getAccessibleHypertextExt(const jobject accessibleC const jint nStartIndex, /* OUT */ AccessibleHypertextInfo *hypertext) { - jthrowable exception; const wchar_t *stringBytes; jsize length; PrintDebugString("[INFO]: ##### AccessBridgeJavaEntryPoints::getAccessibleHypertextExt(%p, %p, startIndex = %d)", @@ -3084,8 +3037,6 @@ AccessBridgeJavaEntryPoints::getAccessibleHypertextExt(const jobject accessibleC jint AccessBridgeJavaEntryPoints::getAccessibleHyperlinkCount(const jobject accessibleContext) { - jthrowable exception; - PrintDebugString("[INFO]: ##### AccessBridgeJavaEntryPoints::getAccessibleHyperlinkCount(%X)", accessibleContext); @@ -3106,8 +3057,6 @@ jint AccessBridgeJavaEntryPoints::getAccessibleHyperlinkCount(const jobject acce jint AccessBridgeJavaEntryPoints::getAccessibleHypertextLinkIndex(const jobject hypertext, const jint nIndex) { - jthrowable exception; - PrintDebugString("[INFO]: ##### AccessBridgeJavaEntryPoints::getAccessibleHypertextLinkIndex(%p, index = %d)", hypertext, nIndex); @@ -3129,7 +3078,6 @@ BOOL AccessBridgeJavaEntryPoints::getAccessibleHyperlink(jobject hypertext, const jint index, /* OUT */ AccessibleHyperlinkInfo *info) { - jthrowable exception; const wchar_t *stringBytes; jsize length; @@ -3202,8 +3150,6 @@ BOOL AccessBridgeJavaEntryPoints::getAccessibleHyperlink(jobject hypertext, BOOL AccessBridgeJavaEntryPoints::getAccessibleKeyBindings(jobject accessibleContext, AccessibleKeyBindings *keyBindings) { - jthrowable exception; - PrintDebugString("[INFO]: ##### AccessBridgeJavaEntryPoints::getAccessibleKeyBindings(%p, %p)", accessibleContext, keyBindings); @@ -3249,7 +3195,6 @@ BOOL AccessBridgeJavaEntryPoints::getAccessibleKeyBindings(jobject accessibleCon BOOL AccessBridgeJavaEntryPoints::getAccessibleIcons(jobject accessibleContext, AccessibleIcons *icons) { - jthrowable exception; const wchar_t *stringBytes; jsize length; @@ -3328,7 +3273,6 @@ BOOL AccessBridgeJavaEntryPoints::getAccessibleIcons(jobject accessibleContext, BOOL AccessBridgeJavaEntryPoints::getAccessibleActions(jobject accessibleContext, AccessibleActions *actions) { - jthrowable exception; const wchar_t *stringBytes; jsize length; @@ -3388,7 +3332,6 @@ BOOL AccessBridgeJavaEntryPoints::doAccessibleActions(jobject accessibleContext, AccessibleActionsToDo *actionsToDo, jint *failure) { - jthrowable exception; BOOL returnVal; PrintDebugString("[INFO]: Calling AccessBridgeJavaEntryPoints::doAccessibleActions(%p, #actions %d %s):", @@ -3436,7 +3379,6 @@ BOOL AccessBridgeJavaEntryPoints::getAccessibleTextInfo(jobject accessibleContext, AccessibleTextInfo *textInfo, jint x, jint y) { - jthrowable exception; // Verify the Java VM still exists and AccessibleContext is // an instance of AccessibleText @@ -3495,7 +3437,6 @@ AccessBridgeJavaEntryPoints::getAccessibleTextItems(jobject accessibleContext, AccessibleTextItemsInfo *textItems, jint index) { jstring js; const wchar_t *stringBytes; - jthrowable exception; jsize length; PrintDebugString("[INFO]: Calling AccessBridgeJavaEntryPoints::getAccessibleTextItems(%p):", accessibleContext); @@ -3607,7 +3548,6 @@ AccessBridgeJavaEntryPoints::getAccessibleTextSelectionInfo(jobject accessibleCo AccessibleTextSelectionInfo *selectionInfo) { jstring js; const wchar_t *stringBytes; - jthrowable exception; jsize length; PrintDebugString("[INFO]: Calling AccessBridgeJavaEntryPoints::getAccessibleTextSelectionInfo(%p):", @@ -3680,7 +3620,6 @@ AccessBridgeJavaEntryPoints::getAccessibleTextAttributes(jobject accessibleConte jstring js; const wchar_t *stringBytes; jobject AttributeSet; - jthrowable exception; jsize length; PrintDebugString("[INFO]: Calling AccessBridgeJavaEntryPoints::getAccessibleTextAttributes(%p):", accessibleContext); @@ -4174,8 +4113,6 @@ AccessBridgeJavaEntryPoints::getAccessibleTextAttributes(jobject accessibleConte BOOL AccessBridgeJavaEntryPoints::getAccessibleTextRect(jobject accessibleContext, AccessibleTextRectInfo *rectInfo, jint index) { - jthrowable exception; - PrintDebugString("[INFO]: Calling AccessBridgeJavaEntryPoints::getAccessibleTextRect(%p), index = %d", accessibleContext, index); @@ -4244,8 +4181,6 @@ AccessBridgeJavaEntryPoints::getAccessibleTextRect(jobject accessibleContext, Ac BOOL AccessBridgeJavaEntryPoints::getCaretLocation(jobject accessibleContext, AccessibleTextRectInfo *rectInfo, jint index) { - jthrowable exception; - PrintDebugString("[INFO]: Calling AccessBridgeJavaEntryPoints::getCaretLocation(%p), index = %d", accessibleContext, index); @@ -4311,8 +4246,6 @@ AccessBridgeJavaEntryPoints::getCaretLocation(jobject accessibleContext, Accessi BOOL AccessBridgeJavaEntryPoints::getAccessibleTextLineBounds(jobject accessibleContext, jint index, jint *startIndex, jint *endIndex) { - jthrowable exception; - PrintDebugString("[INFO]: Calling AccessBridgeJavaEntryPoints::getAccessibleTextLineBounds(%p):", accessibleContext); // Verify the Java VM still exists and AccessibleContext is @@ -4353,7 +4286,6 @@ AccessBridgeJavaEntryPoints::getAccessibleTextRange(jobject accessibleContext, jint start, jint end, wchar_t *text, short len) { jstring js; const wchar_t *stringBytes; - jthrowable exception; jsize length; PrintDebugString("[INFO]: Calling AccessBridgeJavaEntryPoints::getAccessibleTextRange(%p, %d, %d, *text, %d):", accessibleContext, start, end, len); @@ -4412,7 +4344,6 @@ BOOL AccessBridgeJavaEntryPoints::getCurrentAccessibleValueFromContext(jobject accessibleContext, wchar_t *value, short len) { jstring js; const wchar_t *stringBytes; - jthrowable exception; jsize length; PrintDebugString("[INFO]: Calling AccessBridgeJavaEntryPoints::getCurrentAccessibleValueFromContext(%p):", accessibleContext); @@ -4453,7 +4384,6 @@ BOOL AccessBridgeJavaEntryPoints::getMaximumAccessibleValueFromContext(jobject accessibleContext, wchar_t *value, short len) { jstring js; const wchar_t *stringBytes; - jthrowable exception; jsize length; PrintDebugString("[INFO]: Calling AccessBridgeJavaEntryPoints::getMaximumAccessibleValueFromContext(%p):", accessibleContext); @@ -4494,7 +4424,6 @@ BOOL AccessBridgeJavaEntryPoints::getMinimumAccessibleValueFromContext(jobject accessibleContext, wchar_t *value, short len) { jstring js; const wchar_t *stringBytes; - jthrowable exception; jsize length; PrintDebugString("[INFO]: Calling AccessBridgeJavaEntryPoints::getMinimumAccessibleValueFromContext(%p):", accessibleContext); @@ -4536,7 +4465,6 @@ AccessBridgeJavaEntryPoints::getMinimumAccessibleValueFromContext(jobject access void AccessBridgeJavaEntryPoints::addAccessibleSelectionFromContext(jobject accessibleContext, int i) { - jthrowable exception; PrintDebugString("[INFO]: Calling AccessBridgeJavaEntryPoints::addAccessibleSelectionFromContext(%p):", accessibleContext); @@ -4554,7 +4482,6 @@ AccessBridgeJavaEntryPoints::addAccessibleSelectionFromContext(jobject accessibl void AccessBridgeJavaEntryPoints::clearAccessibleSelectionFromContext(jobject accessibleContext) { - jthrowable exception; PrintDebugString("[INFO]: Calling AccessBridgeJavaEntryPoints::clearAccessibleSelectionFromContext(%p):", accessibleContext); @@ -4574,7 +4501,6 @@ jobject AccessBridgeJavaEntryPoints::getAccessibleSelectionFromContext(jobject accessibleContext, int i) { jobject returnedAccessibleContext; jobject globalRef; - jthrowable exception; PrintDebugString("[INFO]: Calling AccessBridgeJavaEntryPoints::getAccessibleSelectionFromContext(%p):", accessibleContext); @@ -4600,7 +4526,6 @@ AccessBridgeJavaEntryPoints::getAccessibleSelectionFromContext(jobject accessibl int AccessBridgeJavaEntryPoints::getAccessibleSelectionCountFromContext(jobject accessibleContext) { int count; - jthrowable exception; PrintDebugString("[INFO]: Calling AccessBridgeJavaEntryPoints::getAccessibleSelectionCountFromContext(%p):", accessibleContext); @@ -4621,7 +4546,6 @@ AccessBridgeJavaEntryPoints::getAccessibleSelectionCountFromContext(jobject acce BOOL AccessBridgeJavaEntryPoints::isAccessibleChildSelectedFromContext(jobject accessibleContext, int i) { jboolean result; - jthrowable exception; PrintDebugString("[INFO]: Calling AccessBridgeJavaEntryPoints::isAccessibleChildSelectedFromContext(%p):", accessibleContext); @@ -4644,7 +4568,6 @@ AccessBridgeJavaEntryPoints::isAccessibleChildSelectedFromContext(jobject access void AccessBridgeJavaEntryPoints::removeAccessibleSelectionFromContext(jobject accessibleContext, int i) { - jthrowable exception; PrintDebugString("[INFO]: Calling AccessBridgeJavaEntryPoints::removeAccessibleSelectionFromContext(%p):", accessibleContext); @@ -4662,7 +4585,6 @@ AccessBridgeJavaEntryPoints::removeAccessibleSelectionFromContext(jobject access void AccessBridgeJavaEntryPoints::selectAllAccessibleSelectionFromContext(jobject accessibleContext) { - jthrowable exception; PrintDebugString("[INFO]: Calling AccessBridgeJavaEntryPoints::selectAllAccessibleSelectionFromContext(%p):", accessibleContext); @@ -4683,7 +4605,6 @@ AccessBridgeJavaEntryPoints::selectAllAccessibleSelectionFromContext(jobject acc BOOL AccessBridgeJavaEntryPoints::addJavaEventNotification(jlong type) { - jthrowable exception; PrintDebugString("[INFO]: in AccessBridgeJavaEntryPoints::addJavaEventNotification(%016I64X);", type); @@ -4701,7 +4622,6 @@ AccessBridgeJavaEntryPoints::addJavaEventNotification(jlong type) { BOOL AccessBridgeJavaEntryPoints::removeJavaEventNotification(jlong type) { - jthrowable exception; PrintDebugString("[INFO]: in AccessBridgeJavaEntryPoints::removeJavaEventNotification(%016I64X):", type); @@ -4719,7 +4639,6 @@ AccessBridgeJavaEntryPoints::removeJavaEventNotification(jlong type) { BOOL AccessBridgeJavaEntryPoints::addAccessibilityEventNotification(jlong type) { - jthrowable exception; PrintDebugString("[INFO]: in AccessBridgeJavaEntryPoints::addAccessibilityEventNotification(%016I64X);", type); @@ -4739,7 +4658,6 @@ AccessBridgeJavaEntryPoints::addAccessibilityEventNotification(jlong type) { BOOL AccessBridgeJavaEntryPoints::removeAccessibilityEventNotification(jlong type) { - jthrowable exception; PrintDebugString("[INFO]: in AccessBridgeJavaEntryPoints::removeAccessibilityEventNotification(%016I64X):", type); @@ -4753,4 +4671,4 @@ AccessBridgeJavaEntryPoints::removeAccessibilityEventNotification(jlong type) { return FALSE; } return TRUE; -} +} \ No newline at end of file From f6f73ce70da0bea31b93a397da7f7912d1642c09 Mon Sep 17 00:00:00 2001 From: Brian Burkhalter <bpb@openjdk.org> Date: Tue, 19 Nov 2024 20:30:02 +0000 Subject: [PATCH 110/311] 8344446: Remove security manager dependency from module jdk.sctp Reviewed-by: mullan, alanb --- .../sun/nio/ch/sctp/SctpChannelImpl.java | 24 ++-------- .../sun/nio/ch/sctp/SctpMultiChannelImpl.java | 27 +---------- .../unix/classes/sun/nio/ch/sctp/SctpNet.java | 45 +++---------------- .../nio/ch/sctp/SctpServerChannelImpl.java | 18 +------- 4 files changed, 11 insertions(+), 103 deletions(-) diff --git a/src/jdk.sctp/unix/classes/sun/nio/ch/sctp/SctpChannelImpl.java b/src/jdk.sctp/unix/classes/sun/nio/ch/sctp/SctpChannelImpl.java index 2e12e67c6c7..2a676e55a90 100644 --- a/src/jdk.sctp/unix/classes/sun/nio/ch/sctp/SctpChannelImpl.java +++ b/src/jdk.sctp/unix/classes/sun/nio/ch/sctp/SctpChannelImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -30,8 +30,6 @@ import java.net.InetSocketAddress; import java.io.FileDescriptor; import java.io.IOException; -import java.security.AccessController; -import java.security.PrivilegedAction; import java.util.Collections; import java.util.Set; import java.util.HashSet; @@ -194,11 +192,6 @@ public SctpChannel bind(SocketAddress local) throws IOException { SctpNet.throwAlreadyBoundException(); InetSocketAddress isa = (local == null) ? new InetSocketAddress(0) : Net.checkAddress(local); - @SuppressWarnings("removal") - SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - sm.checkListen(isa.getPort()); - } Net.bind(fd, isa.getAddress(), isa.getPort()); InetSocketAddress boundIsa = Net.localAddress(fd); port = boundIsa.getPort(); @@ -364,11 +357,6 @@ public boolean connect(SocketAddress endpoint) throws IOException { synchronized (sendLock) { ensureOpenAndUnconnected(); InetSocketAddress isa = Net.checkAddress(endpoint); - @SuppressWarnings("removal") - SecurityManager sm = System.getSecurityManager(); - if (sm != null) - sm.checkConnect(isa.getAddress().getHostAddress(), - isa.getPort()); synchronized (blockingLock()) { int n = 0; try { @@ -1094,16 +1082,10 @@ static native int send0(int fd, long address, int length, loadSctpLibrary(); } - @SuppressWarnings({"removal", "restricted"}) + @SuppressWarnings("restricted") private static void loadSctpLibrary() { IOUtil.load(); /* loads nio & net native libraries */ - AccessController.doPrivileged( - new PrivilegedAction<>() { - public Void run() { - System.loadLibrary("sctp"); - return null; - } - }); + System.loadLibrary("sctp"); initIDs(); } } diff --git a/src/jdk.sctp/unix/classes/sun/nio/ch/sctp/SctpMultiChannelImpl.java b/src/jdk.sctp/unix/classes/sun/nio/ch/sctp/SctpMultiChannelImpl.java index b1b721c9976..4a3f18e6b08 100644 --- a/src/jdk.sctp/unix/classes/sun/nio/ch/sctp/SctpMultiChannelImpl.java +++ b/src/jdk.sctp/unix/classes/sun/nio/ch/sctp/SctpMultiChannelImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -149,10 +149,6 @@ public SctpMultiChannel bind(SocketAddress local, int backlog) InetSocketAddress isa = (local == null) ? new InetSocketAddress(0) : Net.checkAddress(local); - @SuppressWarnings("removal") - SecurityManager sm = System.getSecurityManager(); - if (sm != null) - sm.checkListen(isa.getPort()); Net.bind(fd, isa.getAddress(), isa.getPort()); InetSocketAddress boundIsa = Net.localAddress(fd); @@ -508,21 +504,6 @@ public <T> MessageInfo receive(ByteBuffer buffer, resultContainer.getMessageInfo(); info.setAssociation(lookupAssociation(info. associationID())); - @SuppressWarnings("removal") - SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - InetSocketAddress isa = (InetSocketAddress)info.address(); - if (!addressMap.containsKey(isa)) { - /* must be a new association */ - try { - sm.checkAccept(isa.getAddress().getHostAddress(), - isa.getPort()); - } catch (SecurityException se) { - buffer.clear(); - throw se; - } - } - } assert info.association() != null; return info; @@ -805,12 +786,6 @@ public int send(ByteBuffer buffer, MessageInfo messageInfo) checkStreamNumber(association, messageInfo.streamNumber()); assocId = association.associationID(); - } else { /* must be new association */ - @SuppressWarnings("removal") - SecurityManager sm = System.getSecurityManager(); - if (sm != null) - sm.checkConnect(addr.getAddress().getHostAddress(), - addr.getPort()); } } else { throw new AssertionError( diff --git a/src/jdk.sctp/unix/classes/sun/nio/ch/sctp/SctpNet.java b/src/jdk.sctp/unix/classes/sun/nio/ch/sctp/SctpNet.java index decf964c6cb..a12049cbcf0 100644 --- a/src/jdk.sctp/unix/classes/sun/nio/ch/sctp/SctpNet.java +++ b/src/jdk.sctp/unix/classes/sun/nio/ch/sctp/SctpNet.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -32,8 +32,6 @@ import java.nio.channels.AlreadyBoundException; import java.util.Set; import java.util.HashSet; -import java.security.AccessController; -import java.security.PrivilegedAction; import sun.net.util.IPAddressUtil; import sun.nio.ch.IOUtil; import sun.nio.ch.Net; @@ -91,41 +89,14 @@ static Set<SocketAddress> getLocalAddresses(int fd) SocketAddress[] saa = getLocalAddresses0(fd); if (saa != null) { - set = getRevealedLocalAddressSet(saa); + set = new HashSet<>(saa.length); + for (SocketAddress sa : saa) + set.add(sa); } return set; } - private static Set<SocketAddress> getRevealedLocalAddressSet( - SocketAddress[] saa) - { - @SuppressWarnings("removal") - SecurityManager sm = System.getSecurityManager(); - Set<SocketAddress> set = new HashSet<>(saa.length); - for (SocketAddress sa : saa) { - set.add(getRevealedLocalAddress(sa, sm)); - } - return set; - } - - private static SocketAddress getRevealedLocalAddress(SocketAddress sa, - @SuppressWarnings("removal") SecurityManager sm) - { - if (sm == null || sa == null) - return sa; - InetSocketAddress ia = (InetSocketAddress)sa; - try{ - sm.checkConnect(ia.getAddress().getHostAddress(), -1); - // Security check passed - } catch (SecurityException e) { - // Return loopback address - return new InetSocketAddress(InetAddress.getLoopbackAddress(), - ia.getPort()); - } - return sa; - } - static Set<SocketAddress> getRemoteAddresses(int fd, int assocId) throws IOException { Set<SocketAddress> set = null; @@ -336,13 +307,7 @@ static native void setInitMsgOption0(int fd, int arg1, int arg2) @SuppressWarnings({"removal", "restricted"}) private static void loadSctpLibrary() { IOUtil.load(); // loads nio & net native libraries - java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction<Void>() { - public Void run() { - System.loadLibrary("sctp"); - return null; - } - }); + System.loadLibrary("sctp"); init(); } } diff --git a/src/jdk.sctp/unix/classes/sun/nio/ch/sctp/SctpServerChannelImpl.java b/src/jdk.sctp/unix/classes/sun/nio/ch/sctp/SctpServerChannelImpl.java index 0f710a4c670..4b2be742c6d 100644 --- a/src/jdk.sctp/unix/classes/sun/nio/ch/sctp/SctpServerChannelImpl.java +++ b/src/jdk.sctp/unix/classes/sun/nio/ch/sctp/SctpServerChannelImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -109,10 +109,6 @@ public SctpServerChannel bind(SocketAddress local, int backlog) InetSocketAddress isa = (local == null) ? new InetSocketAddress(0) : Net.checkAddress(local); - @SuppressWarnings("removal") - SecurityManager sm = System.getSecurityManager(); - if (sm != null) - sm.checkListen(isa.getPort()); Net.bind(fd, isa.getAddress(), isa.getPort()); InetSocketAddress boundIsa = Net.localAddress(fd); @@ -217,7 +213,6 @@ public SctpChannel accept() throws IOException { throw new ClosedChannelException(); if (!isBound()) throw new NotYetBoundException(); - SctpChannel sc = null; int n = 0; FileDescriptor newfd = new FileDescriptor(); @@ -244,16 +239,7 @@ public SctpChannel accept() throws IOException { return null; IOUtil.configureBlocking(newfd, true); - InetSocketAddress isa = isaa[0]; - sc = new SctpChannelImpl(provider(), newfd); - - @SuppressWarnings("removal") - SecurityManager sm = System.getSecurityManager(); - if (sm != null) - sm.checkAccept(isa.getAddress().getHostAddress(), - isa.getPort()); - - return sc; + return new SctpChannelImpl(provider(), newfd); } } From 81e43114eca5199a0d816c02f50ecb6bc370135b Mon Sep 17 00:00:00 2001 From: Brian Burkhalter <bpb@openjdk.org> Date: Tue, 19 Nov 2024 20:30:22 +0000 Subject: [PATCH 111/311] 8344077: Remove security manager dependency in java.io Reviewed-by: rriggs, alanb, naoto, lancea --- .../share/classes/java/io/Console.java | 29 ++-- src/java.base/share/classes/java/io/File.java | 138 +----------------- .../classes/java/io/FileInputStream.java | 18 +-- .../classes/java/io/FileOutputStream.java | 19 +-- .../share/classes/java/io/FilePermission.java | 38 ++--- .../classes/java/io/RandomAccessFile.java | 8 - .../java/io/SerializablePermission.java | 3 +- .../unix/classes/java/io/UnixFileSystem.java | 19 +-- .../classes/java/io/WinNTFileSystem.java | 42 +----- 9 files changed, 41 insertions(+), 273 deletions(-) diff --git a/src/java.base/share/classes/java/io/Console.java b/src/java.base/share/classes/java/io/Console.java index d8ba0439d47..3881b2380ad 100644 --- a/src/java.base/share/classes/java/io/Console.java +++ b/src/java.base/share/classes/java/io/Console.java @@ -25,8 +25,6 @@ package java.io; -import java.security.AccessController; -import java.security.PrivilegedAction; import java.util.*; import java.nio.charset.Charset; import jdk.internal.access.JavaIOAccess; @@ -659,9 +657,8 @@ public Console console() { }); } - @SuppressWarnings("removal") private static Console instantiateConsole() { - Console c; + Console c = null; try { /* @@ -673,25 +670,19 @@ private static Console instantiateConsole() { * If no providers are available, or instantiation failed, java.base built-in * Console implementation is used. */ - c = AccessController.doPrivileged(new PrivilegedAction<Console>() { - public Console run() { - var consModName = System.getProperty("jdk.console", - JdkConsoleProvider.DEFAULT_PROVIDER_MODULE_NAME); + var consModName = System.getProperty("jdk.console", + JdkConsoleProvider.DEFAULT_PROVIDER_MODULE_NAME); - for (var jcp : ServiceLoader.load(ModuleLayer.boot(), JdkConsoleProvider.class)) { - if (consModName.equals(jcp.getClass().getModule().getName())) { - var jc = jcp.console(istty, CHARSET); - if (jc != null) { - return new ProxyingConsole(jc); - } - break; - } + for (var jcp : ServiceLoader.load(ModuleLayer.boot(), JdkConsoleProvider.class)) { + if (consModName.equals(jcp.getClass().getModule().getName())) { + var jc = jcp.console(istty, CHARSET); + if (jc != null) { + c = new ProxyingConsole(jc); } - return null; + break; } - }); + } } catch (ServiceConfigurationError _) { - c = null; } // If not found, default to built-in Console diff --git a/src/java.base/share/classes/java/io/File.java b/src/java.base/share/classes/java/io/File.java index b8eda9dcf83..3cfeb7ffdee 100644 --- a/src/java.base/share/classes/java/io/File.java +++ b/src/java.base/share/classes/java/io/File.java @@ -751,11 +751,6 @@ public URI toURI() { * application; {@code false} otherwise */ public boolean canRead() { - @SuppressWarnings("removal") - SecurityManager security = System.getSecurityManager(); - if (security != null) { - security.checkRead(path); - } if (isInvalid()) { return false; } @@ -775,11 +770,6 @@ public boolean canRead() { * {@code false} otherwise. */ public boolean canWrite() { - @SuppressWarnings("removal") - SecurityManager security = System.getSecurityManager(); - if (security != null) { - security.checkWrite(path); - } if (isInvalid()) { return false; } @@ -794,11 +784,6 @@ public boolean canWrite() { * by this abstract pathname exists; {@code false} otherwise */ public boolean exists() { - @SuppressWarnings("removal") - SecurityManager security = System.getSecurityManager(); - if (security != null) { - security.checkRead(path); - } if (isInvalid()) { return false; } @@ -820,11 +805,6 @@ public boolean exists() { * {@code false} otherwise */ public boolean isDirectory() { - @SuppressWarnings("removal") - SecurityManager security = System.getSecurityManager(); - if (security != null) { - security.checkRead(path); - } if (isInvalid()) { return false; } @@ -848,11 +828,6 @@ public boolean isDirectory() { * {@code false} otherwise */ public boolean isFile() { - @SuppressWarnings("removal") - SecurityManager security = System.getSecurityManager(); - if (security != null) { - security.checkRead(path); - } if (isInvalid()) { return false; } @@ -881,11 +856,6 @@ public boolean isFile() { * @since 1.2 */ public boolean isHidden() { - @SuppressWarnings("removal") - SecurityManager security = System.getSecurityManager(); - if (security != null) { - security.checkRead(path); - } if (isInvalid()) { return false; } @@ -920,11 +890,6 @@ public boolean isHidden() { * epoch */ public long lastModified() { - @SuppressWarnings("removal") - SecurityManager security = System.getSecurityManager(); - if (security != null) { - security.checkRead(path); - } if (isInvalid()) { return 0L; } @@ -947,11 +912,6 @@ public long lastModified() { * denoting system-dependent entities such as devices or pipes. */ public long length() { - @SuppressWarnings("removal") - SecurityManager security = System.getSecurityManager(); - if (security != null) { - security.checkRead(path); - } if (isInvalid()) { return 0L; } @@ -983,9 +943,6 @@ public long length() { * @since 1.2 */ public boolean createNewFile() throws IOException { - @SuppressWarnings("removal") - SecurityManager security = System.getSecurityManager(); - if (security != null) security.checkWrite(path); if (isInvalid()) { throw new IOException("Invalid file path"); } @@ -1007,11 +964,6 @@ public boolean createNewFile() throws IOException { * successfully deleted; {@code false} otherwise */ public boolean delete() { - @SuppressWarnings("removal") - SecurityManager security = System.getSecurityManager(); - if (security != null) { - security.checkDelete(path); - } if (isInvalid()) { return false; } @@ -1043,11 +995,6 @@ public boolean delete() { * @since 1.2 */ public void deleteOnExit() { - @SuppressWarnings("removal") - SecurityManager security = System.getSecurityManager(); - if (security != null) { - security.checkDelete(path); - } if (isInvalid()) { return; } @@ -1097,11 +1044,6 @@ public String[] list() { * I/O error occurs. */ private final String[] normalizedList() { - @SuppressWarnings("removal") - SecurityManager security = System.getSecurityManager(); - if (security != null) { - security.checkRead(path); - } if (isInvalid()) { return null; } @@ -1275,11 +1217,6 @@ public File[] listFiles(FileFilter filter) { * created; {@code false} otherwise */ public boolean mkdir() { - @SuppressWarnings("removal") - SecurityManager security = System.getSecurityManager(); - if (security != null) { - security.checkWrite(path); - } if (isInvalid()) { return false; } @@ -1345,12 +1282,6 @@ public boolean renameTo(File dest) { if (dest == null) { throw new NullPointerException(); } - @SuppressWarnings("removal") - SecurityManager security = System.getSecurityManager(); - if (security != null) { - security.checkWrite(path); - security.checkWrite(dest.path); - } if (this.isInvalid() || dest.isInvalid()) { return false; } @@ -1380,11 +1311,6 @@ public boolean renameTo(File dest) { */ public boolean setLastModified(long time) { if (time < 0) throw new IllegalArgumentException("Negative time"); - @SuppressWarnings("removal") - SecurityManager security = System.getSecurityManager(); - if (security != null) { - security.checkWrite(path); - } if (isInvalid()) { return false; } @@ -1406,11 +1332,6 @@ public boolean setLastModified(long time) { * @since 1.2 */ public boolean setReadOnly() { - @SuppressWarnings("removal") - SecurityManager security = System.getSecurityManager(); - if (security != null) { - security.checkWrite(path); - } if (isInvalid()) { return false; } @@ -1445,11 +1366,6 @@ public boolean setReadOnly() { * @since 1.6 */ public boolean setWritable(boolean writable, boolean ownerOnly) { - @SuppressWarnings("removal") - SecurityManager security = System.getSecurityManager(); - if (security != null) { - security.checkWrite(path); - } if (isInvalid()) { return false; } @@ -1517,11 +1433,6 @@ public boolean setWritable(boolean writable) { * @since 1.6 */ public boolean setReadable(boolean readable, boolean ownerOnly) { - @SuppressWarnings("removal") - SecurityManager security = System.getSecurityManager(); - if (security != null) { - security.checkWrite(path); - } if (isInvalid()) { return false; } @@ -1595,11 +1506,6 @@ public boolean setReadable(boolean readable) { * @since 1.6 */ public boolean setExecutable(boolean executable, boolean ownerOnly) { - @SuppressWarnings("removal") - SecurityManager security = System.getSecurityManager(); - if (security != null) { - security.checkWrite(path); - } if (isInvalid()) { return false; } @@ -1652,11 +1558,6 @@ public boolean setExecutable(boolean executable) { * @since 1.6 */ public boolean canExecute() { - @SuppressWarnings("removal") - SecurityManager security = System.getSecurityManager(); - if (security != null) { - security.checkExec(path); - } if (isInvalid()) { return false; } @@ -1726,12 +1627,6 @@ public static File[] listRoots() { * @see FileStore#getTotalSpace */ public long getTotalSpace() { - @SuppressWarnings("removal") - SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - sm.checkPermission(new RuntimePermission("getFileSystemAttributes")); - sm.checkRead(path); - } if (isInvalid()) { return 0L; } @@ -1764,12 +1659,6 @@ public long getTotalSpace() { * @see FileStore#getUnallocatedSpace */ public long getFreeSpace() { - @SuppressWarnings("removal") - SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - sm.checkPermission(new RuntimePermission("getFileSystemAttributes")); - sm.checkRead(path); - } if (isInvalid()) { return 0L; } @@ -1805,12 +1694,6 @@ public long getFreeSpace() { * @see FileStore#getUsableSpace */ public long getUsableSpace() { - @SuppressWarnings("removal") - SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - sm.checkPermission(new RuntimePermission("getFileSystemAttributes")); - sm.checkRead(path); - } if (isInvalid()) { return 0L; } @@ -1840,7 +1723,6 @@ private static int shortenSubName(int subNameLength, int excess, } return subNameLength; } - @SuppressWarnings("removal") static File generateFile(String prefix, String suffix, File dir) throws IOException { @@ -1897,11 +1779,8 @@ static File generateFile(String prefix, String suffix, File dir) File f = new File(dir, name); if (!name.equals(f.getName()) || f.isInvalid()) { - if (System.getSecurityManager() != null) - throw new IOException("Unable to create temporary file"); - else - throw new IOException("Unable to create temporary file, " - + name); + throw new IOException("Unable to create temporary file, " + + name); } return f; } @@ -1998,22 +1877,9 @@ public static File createTempFile(String prefix, String suffix, File tmpdir = (directory != null) ? directory : TempDirectory.location(); - @SuppressWarnings("removal") - SecurityManager sm = System.getSecurityManager(); File f; do { f = TempDirectory.generateFile(prefix, suffix, tmpdir); - - if (sm != null) { - try { - sm.checkWrite(f.getPath()); - } catch (SecurityException se) { - // don't reveal temporary directory location - if (directory == null) - throw new SecurityException("Unable to create temporary file"); - throw se; - } - } } while (FS.hasBooleanAttributes(f, FileSystem.BA_EXISTS)); if (!FS.createFileExclusively(f.getPath())) diff --git a/src/java.base/share/classes/java/io/FileInputStream.java b/src/java.base/share/classes/java/io/FileInputStream.java index e429faec09b..ab312fc8c5b 100644 --- a/src/java.base/share/classes/java/io/FileInputStream.java +++ b/src/java.base/share/classes/java/io/FileInputStream.java @@ -130,22 +130,13 @@ public FileInputStream(String name) throws FileNotFoundException { */ @SuppressWarnings("this-escape") public FileInputStream(File file) throws FileNotFoundException { - String name = (file != null ? file.getPath() : null); - @SuppressWarnings("removal") - SecurityManager security = System.getSecurityManager(); - if (security != null) { - security.checkRead(name); - } - if (name == null) { - throw new NullPointerException(); - } if (file.isInvalid()) { throw new FileNotFoundException("Invalid file path"); } + path = file.getPath(); fd = new FileDescriptor(); fd.attach(this); - path = name; - open(name); + open(path); FileCleanable.register(fd); // open set the fd, register the cleanup } @@ -166,14 +157,9 @@ public FileInputStream(File file) throws FileNotFoundException { */ @SuppressWarnings("this-escape") public FileInputStream(FileDescriptor fdObj) { - @SuppressWarnings("removal") - SecurityManager security = System.getSecurityManager(); if (fdObj == null) { throw new NullPointerException(); } - if (security != null) { - security.checkRead(fdObj); - } fd = fdObj; path = null; diff --git a/src/java.base/share/classes/java/io/FileOutputStream.java b/src/java.base/share/classes/java/io/FileOutputStream.java index 557bea0c3fc..6c5a30ea432 100644 --- a/src/java.base/share/classes/java/io/FileOutputStream.java +++ b/src/java.base/share/classes/java/io/FileOutputStream.java @@ -199,23 +199,15 @@ public FileOutputStream(File file) throws FileNotFoundException { public FileOutputStream(File file, boolean append) throws FileNotFoundException { - String name = (file != null ? file.getPath() : null); - @SuppressWarnings("removal") - SecurityManager security = System.getSecurityManager(); - if (security != null) { - security.checkWrite(name); - } - if (name == null) { - throw new NullPointerException(); - } if (file.isInvalid()) { throw new FileNotFoundException("Invalid file path"); } + this.path = file.getPath(); + this.fd = new FileDescriptor(); fd.attach(this); - this.path = name; - open(name, append); + open(this.path, append); FileCleanable.register(fd); // open sets the fd, register the cleanup } @@ -236,14 +228,9 @@ public FileOutputStream(File file, boolean append) */ @SuppressWarnings("this-escape") public FileOutputStream(FileDescriptor fdObj) { - @SuppressWarnings("removal") - SecurityManager security = System.getSecurityManager(); if (fdObj == null) { throw new NullPointerException(); } - if (security != null) { - security.checkWrite(fdObj); - } this.fd = fdObj; this.path = null; diff --git a/src/java.base/share/classes/java/io/FilePermission.java b/src/java.base/share/classes/java/io/FilePermission.java index b11e0dd25be..30fa3978638 100644 --- a/src/java.base/share/classes/java/io/FilePermission.java +++ b/src/java.base/share/classes/java/io/FilePermission.java @@ -26,7 +26,8 @@ package java.io; import java.nio.file.*; -import java.security.*; +import java.security.Permission; +import java.security.PermissionCollection; import java.util.Enumeration; import java.util.Objects; import java.util.StringJoiner; @@ -36,7 +37,6 @@ import jdk.internal.access.JavaIOFilePermissionAccess; import jdk.internal.access.SharedSecrets; import sun.nio.fs.DefaultFileSystemProvider; -import sun.security.action.GetPropertyAction; import sun.security.util.FilePermCompat; import sun.security.util.SecurityConstants; @@ -181,8 +181,7 @@ public final class FilePermission extends Permission implements Serializable { private static final java.nio.file.FileSystem builtInFS = DefaultFileSystemProvider.theFileSystem(); - private static final Path here = builtInFS.getPath( - GetPropertyAction.privilegedGetProperty("user.dir")); + private static final Path here = builtInFS.getPath(jdk.internal.util.StaticProperty.userDir()); private static final Path EMPTY_PATH = builtInFS.getPath(""); private static final Path DASH_PATH = builtInFS.getPath("-"); @@ -361,25 +360,20 @@ private void init(int mask) { } // store only the canonical cpath if possible - cpath = AccessController.doPrivileged(new PrivilegedAction<>() { - public String run() { - try { - String path = cpath; - if (cpath.endsWith("*")) { - // call getCanonicalPath with a path with wildcard character - // replaced to avoid calling it with paths that are - // intended to match all entries in a directory - path = path.substring(0, path.length() - 1) + "-"; - path = new File(path).getCanonicalPath(); - return path.substring(0, path.length() - 1) + "*"; - } else { - return new File(path).getCanonicalPath(); - } - } catch (IOException ioe) { - return cpath; - } + try { + String path = cpath; + if (cpath.endsWith("*")) { + // call getCanonicalPath with a path with wildcard character + // replaced to avoid calling it with paths that are + // intended to match all entries in a directory + path = path.substring(0, path.length() - 1) + "-"; + path = new File(path).getCanonicalPath(); + cpath = path.substring(0, path.length() - 1) + "*"; + } else { + cpath = new File(path).getCanonicalPath(); } - }); + } catch (IOException ignore) { + } int len = cpath.length(); char last = ((len > 0) ? cpath.charAt(len - 1) : 0); diff --git a/src/java.base/share/classes/java/io/RandomAccessFile.java b/src/java.base/share/classes/java/io/RandomAccessFile.java index 1487764ac44..c09f87afcdc 100644 --- a/src/java.base/share/classes/java/io/RandomAccessFile.java +++ b/src/java.base/share/classes/java/io/RandomAccessFile.java @@ -245,14 +245,6 @@ else if (mode.startsWith("rw")) { + "\" must be one of " + "\"r\", \"rw\", \"rws\"," + " or \"rwd\""); - @SuppressWarnings("removal") - SecurityManager security = System.getSecurityManager(); - if (security != null) { - security.checkRead(name); - if (rw) { - security.checkWrite(name); - } - } if (name == null) { throw new NullPointerException(); } diff --git a/src/java.base/share/classes/java/io/SerializablePermission.java b/src/java.base/share/classes/java/io/SerializablePermission.java index 1e617e173a7..48be2eabf1f 100644 --- a/src/java.base/share/classes/java/io/SerializablePermission.java +++ b/src/java.base/share/classes/java/io/SerializablePermission.java @@ -25,7 +25,7 @@ package java.io; -import java.security.*; +import java.security.BasicPermission; import java.util.Enumeration; import java.util.Hashtable; import java.util.StringTokenizer; @@ -44,7 +44,6 @@ * @see java.security.Permission * @see java.security.Permissions * @see java.security.PermissionCollection - * @see java.lang.SecurityManager * * @author Joe Fialli * @since 1.2 diff --git a/src/java.base/unix/classes/java/io/UnixFileSystem.java b/src/java.base/unix/classes/java/io/UnixFileSystem.java index 18afb729c01..ea2ca28fe86 100644 --- a/src/java.base/unix/classes/java/io/UnixFileSystem.java +++ b/src/java.base/unix/classes/java/io/UnixFileSystem.java @@ -27,7 +27,6 @@ import java.util.Properties; import jdk.internal.util.StaticProperty; -import sun.security.action.GetPropertyAction; final class UnixFileSystem extends FileSystem { @@ -36,7 +35,7 @@ final class UnixFileSystem extends FileSystem { private final String userDir; UnixFileSystem() { - Properties props = GetPropertyAction.privilegedGetProperties(); + Properties props = System.getProperties(); slash = props.getProperty("file.separator").charAt(0); colon = props.getProperty("path.separator").charAt(0); userDir = StaticProperty.userDir(); @@ -150,11 +149,6 @@ public boolean isInvalid(File f) { @Override public String resolve(File f) { if (isAbsolute(f)) return f.getPath(); - @SuppressWarnings("removal") - SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - sm.checkPropertyAccess("user.dir"); - } return resolve(userDir, f.getPath()); } @@ -259,16 +253,7 @@ public boolean setReadOnly(File f) { @Override public File[] listRoots() { - try { - @SuppressWarnings("removal") - SecurityManager security = System.getSecurityManager(); - if (security != null) { - security.checkRead("/"); - } - return new File[] { new File("/") }; - } catch (SecurityException x) { - return new File[0]; - } + return new File[] { new File("/") }; } /* -- Disk usage -- */ diff --git a/src/java.base/windows/classes/java/io/WinNTFileSystem.java b/src/java.base/windows/classes/java/io/WinNTFileSystem.java index 10e02b4ba72..af6531edd01 100644 --- a/src/java.base/windows/classes/java/io/WinNTFileSystem.java +++ b/src/java.base/windows/classes/java/io/WinNTFileSystem.java @@ -30,7 +30,6 @@ import java.util.BitSet; import java.util.Locale; import java.util.Properties; -import sun.security.action.GetPropertyAction; /** * Unicode-aware FileSystem for Windows NT/2000. @@ -53,7 +52,7 @@ final class WinNTFileSystem extends FileSystem { // only if the property is set, ignoring case, to the string "false". private static final boolean ENABLE_ADS; static { - String enableADS = GetPropertyAction.privilegedGetProperty("jdk.io.File.enableADS"); + String enableADS = System.getProperty("jdk.io.File.enableADS"); if (enableADS != null) { ENABLE_ADS = !enableADS.equalsIgnoreCase(Boolean.FALSE.toString()); } else { @@ -81,7 +80,7 @@ private static String stripLongOrUNCPrefix(String path) { } WinNTFileSystem() { - Properties props = GetPropertyAction.privilegedGetProperties(); + Properties props = System.getProperties(); slash = props.getProperty("file.separator").charAt(0); semicolon = props.getProperty("path.separator").charAt(0); altSlash = (this.slash == '\\') ? '/' : '\\'; @@ -394,15 +393,15 @@ public String resolve(File f) { if (pl == 3) return path; /* Absolute local */ if (pl == 0) - return getUserPath() + slashify(path); /* Completely relative */ + return userDir + slashify(path); /* Completely relative */ if (pl == 1) { /* Drive-relative */ - String up = getUserPath(); + String up = userDir; String ud = getDrive(up); if (ud != null) return ud + path; return up + path; /* User dir is a UNC path */ } if (pl == 2) { /* Directory-relative */ - String up = getUserPath(); + String up = userDir; String ud = getDrive(up); if ((ud != null) && path.startsWith(ud)) return up + slashify(path.substring(2)); @@ -413,14 +412,6 @@ public String resolve(File f) { drive other than the current drive, insist that the caller have read permission on the result */ String p = drive + (':' + dir + slashify(path.substring(2))); - @SuppressWarnings("removal") - SecurityManager security = System.getSecurityManager(); - try { - if (security != null) security.checkRead(p); - } catch (SecurityException x) { - /* Don't disclose the drive's directory in the exception */ - throw new SecurityException("Cannot resolve path " + path); - } return p; } return drive + ":" + slashify(path.substring(2)); /* fake it */ @@ -428,17 +419,6 @@ public String resolve(File f) { throw new InternalError("Unresolvable path: " + path); } - private String getUserPath() { - /* For both compatibility and security, - we must look this up every time */ - @SuppressWarnings("removal") - SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - sm.checkPropertyAccess("user.dir"); - } - return userDir; - } - private String getDrive(String path) { int pl = prefixLength(path); return (pl == 3) ? path.substring(0, 2) : null; @@ -595,22 +575,10 @@ public File[] listRoots() { .valueOf(new long[] {listRoots0()}) .stream() .mapToObj(i -> new File((char)('A' + i) + ":" + slash)) - .filter(f -> access(f.getPath())) .toArray(File[]::new); } private static native int listRoots0(); - private boolean access(String path) { - try { - @SuppressWarnings("removal") - SecurityManager security = System.getSecurityManager(); - if (security != null) security.checkRead(path); - return true; - } catch (SecurityException x) { - return false; - } - } - /* -- Disk usage -- */ @Override From acdbf83325296511e6d27cc696911d81f99b8063 Mon Sep 17 00:00:00 2001 From: Calvin Cheung <ccheung@openjdk.org> Date: Tue, 19 Nov 2024 23:37:34 +0000 Subject: [PATCH 112/311] 8341553: Remove UseCompactObjectHeaders extra CDS archives Reviewed-by: erikj, iklam, coleenp --- make/conf/jib-profiles.js | 1 + .../cds/TestDefaultArchiveLoading.java | 31 +++++++++++++++++-- 2 files changed, 30 insertions(+), 2 deletions(-) diff --git a/make/conf/jib-profiles.js b/make/conf/jib-profiles.js index a28d85c146f..25cf15c5f3b 100644 --- a/make/conf/jib-profiles.js +++ b/make/conf/jib-profiles.js @@ -253,6 +253,7 @@ var getJibProfilesCommon = function (input, data) { configure_args: concat( "--with-exclude-translations=es,fr,it,ko,pt_BR,sv,ca,tr,cs,sk,ja_JP_A,ja_JP_HA,ja_JP_HI,ja_JP_I,zh_TW,zh_HK", "--disable-jvm-feature-shenandoahgc", + "--disable-cds-archive-coh", versionArgs(input, common)) }; diff --git a/test/hotspot/jtreg/runtime/cds/TestDefaultArchiveLoading.java b/test/hotspot/jtreg/runtime/cds/TestDefaultArchiveLoading.java index 590f22feed7..192f7ca42a8 100644 --- a/test/hotspot/jtreg/runtime/cds/TestDefaultArchiveLoading.java +++ b/test/hotspot/jtreg/runtime/cds/TestDefaultArchiveLoading.java @@ -66,12 +66,32 @@ * @run driver TestDefaultArchiveLoading coops_coh */ +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; import jdk.test.lib.Platform; import jdk.test.lib.process.OutputAnalyzer; import jdk.test.lib.process.ProcessTools; + import jtreg.SkippedException; public class TestDefaultArchiveLoading { + + private static String archiveName(String archiveSuffix) { + return "classes" + archiveSuffix + ".jsa"; + } + + private static Path archivePath(String archiveSuffix) { + return Paths.get(System.getProperty("java.home"), "lib", + "server", archiveName(archiveSuffix)); + } + + private static boolean isCOHArchiveAvailable(char coops, char coh, + String archiveSuffix) throws Exception { + Path archive= archivePath(archiveSuffix); + return Files.exists(archive); + } + public static void main(String[] args) throws Exception { if (args.length != 1) { @@ -90,6 +110,10 @@ public static void main(String[] args) throws Exception { coops = '-'; coh = '+'; archiveSuffix = "_nocoops_coh"; + if (!isCOHArchiveAvailable(coops, coh, archiveSuffix)) { + throw new SkippedException("Skipping test due to " + + archivePath(archiveSuffix).toString() + " not available"); + } break; case "coops_nocoh": coops = '+'; @@ -99,6 +123,10 @@ public static void main(String[] args) throws Exception { case "coops_coh": coh = coops = '+'; archiveSuffix = "_coh"; + if (!isCOHArchiveAvailable(coops, coh, archiveSuffix)) { + throw new SkippedException("Skipping test due to " + + archivePath(archiveSuffix).toString() + " not available"); + } break; default: throw new RuntimeException("Invalid argument " + args[0]); } @@ -114,7 +142,6 @@ public static void main(String[] args) throws Exception { OutputAnalyzer output = new OutputAnalyzer(pb.start()); output.shouldHaveExitValue(0); - output.shouldContain("classes" + archiveSuffix + ".jsa"); - + output.shouldContain(archiveName(archiveSuffix)); } } From f525290000bf8583617047aaeb894bf90332d2e9 Mon Sep 17 00:00:00 2001 From: Joe Darcy <darcy@openjdk.org> Date: Wed, 20 Nov 2024 00:06:24 +0000 Subject: [PATCH 113/311] 8341935: javac states that -proc:full is the default but the default as of 23 is -proc:none Reviewed-by: jlahoda --- src/jdk.compiler/share/man/javac.md | 47 ++++++++++++++++++++--------- 1 file changed, 33 insertions(+), 14 deletions(-) diff --git a/src/jdk.compiler/share/man/javac.md b/src/jdk.compiler/share/man/javac.md index b41a395f386..7761cde2b58 100644 --- a/src/jdk.compiler/share/man/javac.md +++ b/src/jdk.compiler/share/man/javac.md @@ -1,5 +1,5 @@ --- -# Copyright (c) 1994, 2023, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1994, 2024, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -336,10 +336,18 @@ file system locations may be directories, JAR files or JMOD files. <a id="option-proc">`-proc:`\[`none`, `only`, `full`\]</a> : Controls whether annotation processing and compilation are done. - `-proc:none` means that compilation takes place without annotation - processing. `-proc:only` means that only annotation processing is done, - without any subsequent compilation. If this option is not used, or - `-proc:full` is specified, annotation processing and compilation are done. + + - `-proc:none` means that compilation takes place without annotation + processing + + - `-proc:only` means that only annotation processing is done, + without any subsequent compilation. + + - `-proc:full` means annotation processing and compilation are done. + + If this option is not used, annotation processing and compilation + are done if at least one other option is used to explicitly + configure annotation processing. <a id="option-processor">`-processor` *class1*\[`,`*class2*`,`*class3*...\]</a> : Names of the annotation processors to run. This bypasses the default @@ -1427,15 +1435,26 @@ The API for annotation processors is defined in the ### How Annotation Processing Works -Unless annotation processing is disabled with the [`-proc:none`](#option-proc) option, the -compiler searches for any annotation processors that are available. The search -path can be specified with the [`-processorpath`](#option-processor-path) option. If no path is -specified, then the user class path is used. Processors are located by means of -service provider-configuration files named -`META-INF/services/javax.annotation.processing.Processor` on the search path. -Such files should contain the names of any annotation processors to be used, -listed one per line. Alternatively, processors can be specified explicitly, -using the [`-processor`](#option-processor) option. +Annotation processing is requested by using an option to configure +annotation processing, such as [`-processor`](#option-processor), +[`--processor-path`](#option-processor-path), +[`--processor-module-path`](#option-processor-module-path) or by +explicitly enabling processing with the [`-proc:full`](#option-proc) +or [`-proc:only`](#option-proc) options. Annotation processing is +disabled using the [`-proc:none`](#option-proc) option. + +If annotation processing is requested, the compiler searches for any +annotation processors that are available. + +The search path can be specified with the +[`-processorpath`](#option-processor-path) option. If no path is +specified, then the user class path is used. Processors are located by +means of service provider-configuration files named +`META-INF/services/javax.annotation.processing.Processor` on the +search path. Such files should contain the names of any +annotationation processors to be used, listed one per +line. Alternatively, processors can be specified explicitly, using the +[`-processor`](#option-processor) option. After scanning the source files and classes on the command line to determine what annotations are present, the compiler queries the processors to determine From bc7eabd7e4c499fc1b1f37b958c7384078b69bce Mon Sep 17 00:00:00 2001 From: Guoxiong Li <gli@openjdk.org> Date: Wed, 20 Nov 2024 01:09:05 +0000 Subject: [PATCH 114/311] 8344350: Add '.gdbinit' and '.lldbinit' to file '.gitignore' Reviewed-by: ihse, erikj --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index d0736707b80..b57addfccc9 100644 --- a/.gitignore +++ b/.gitignore @@ -20,3 +20,5 @@ NashornProfile.txt /.settings/ /compile_commands.json /.cache +/.gdbinit +/.lldbinit From 4ddd3dec2d0b232d48646ca89b16591b3026aa5c Mon Sep 17 00:00:00 2001 From: SendaoYan <syan@openjdk.org> Date: Wed, 20 Nov 2024 01:36:56 +0000 Subject: [PATCH 115/311] 8344356: Aarch64: implement -XX:+VerifyActivationFrameSize Reviewed-by: aph --- src/hotspot/cpu/aarch64/interp_masm_aarch64.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/hotspot/cpu/aarch64/interp_masm_aarch64.cpp b/src/hotspot/cpu/aarch64/interp_masm_aarch64.cpp index b892489af70..836caa86cb0 100644 --- a/src/hotspot/cpu/aarch64/interp_masm_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/interp_masm_aarch64.cpp @@ -393,7 +393,13 @@ void InterpreterMacroAssembler::dispatch_base(TosState state, bool verifyoop, bool generate_poll) { if (VerifyActivationFrameSize) { - Unimplemented(); + Label L; + sub(rscratch2, rfp, esp); + int min_frame_size = (frame::link_offset - frame::interpreter_frame_initial_sp_offset) * wordSize; + subs(rscratch2, rscratch2, min_frame_size); + br(Assembler::GE, L); + stop("broken stack frame"); + bind(L); } if (verifyoop) { interp_verify_oop(r0, state); From 8a1f9f0a324e30b5da53d58434ac1b39569fc523 Mon Sep 17 00:00:00 2001 From: Archie Cobbs <acobbs@openjdk.org> Date: Wed, 20 Nov 2024 01:57:03 +0000 Subject: [PATCH 116/311] 8343476: Remove unnecessary @SuppressWarnings annotations (client) Reviewed-by: prr --- src/demo/share/jfc/SampleTree/SampleTree.java | 3 +-- src/demo/share/jfc/TableExample/TableExample3.java | 3 +-- src/demo/share/jfc/TableExample/TableExample4.java | 4 +--- .../classes/com/apple/laf/AquaComboBoxButton.java | 3 +-- .../classes/com/apple/laf/AquaComboBoxPopup.java | 3 +-- .../classes/com/apple/laf/AquaComboBoxUI.java | 14 +------------- .../classes/com/apple/laf/AquaFileChooserUI.java | 5 +---- .../macosx/classes/com/apple/laf/AquaFileView.java | 3 +-- .../classes/com/apple/laf/AquaTabbedPaneUI.java | 3 +-- .../classes/com/apple/laf/AquaTextFieldSearch.java | 4 +--- .../macosx/classes/sun/lwawt/LWListPeer.java | 3 +-- .../macosx/classes/sun/lwawt/LWWindowPeer.java | 3 +-- .../classes/sun/lwawt/macosx/CPlatformWindow.java | 1 - .../plugins/tiff/TIFFOldJPEGDecompressor.java | 3 +-- .../java/swing/plaf/motif/MotifFileChooserUI.java | 10 +--------- .../swing/plaf/motif/MotifInternalFrameUI.java | 4 +--- .../java/swing/plaf/motif/MotifOptionPaneUI.java | 3 +-- .../com/sun/media/sound/JavaSoundAudioClip.java | 4 ++-- .../classes/java/awt/AWTEventMulticaster.java | 4 +--- .../share/classes/java/awt/Component.java | 4 +--- .../share/classes/java/awt/Container.java | 7 +------ .../java/awt/DefaultKeyboardFocusManager.java | 3 +-- .../share/classes/java/awt/EventQueue.java | 4 ++-- .../share/classes/java/awt/MediaTracker.java | 3 +-- .../share/classes/java/awt/SequencedEvent.java | 1 - .../share/classes/java/awt/SplashScreen.java | 2 +- .../classes/java/awt/WaitDispatchSupport.java | 1 - .../share/classes/java/awt/Window.java | 2 -- .../share/classes/java/awt/dnd/DragSource.java | 1 - .../share/classes/java/awt/event/FocusEvent.java | 3 +-- .../share/classes/java/beans/Beans.java | 2 +- .../BeanContextChildComponentProxy.java | 1 - .../beancontext/BeanContextContainerProxy.java | 1 - .../BeanContextServiceProviderBeanInfo.java | 1 - .../classes/javax/swing/DefaultFocusManager.java | 3 +-- .../share/classes/javax/swing/JColorChooser.java | 3 +-- .../share/classes/javax/swing/JComponent.java | 2 +- .../share/classes/javax/swing/JLayer.java | 3 +-- .../share/classes/javax/swing/KeyStroke.java | 3 +-- .../share/classes/javax/swing/Spring.java | 3 +-- .../share/classes/javax/swing/SpringLayout.java | 3 +-- .../share/classes/javax/swing/Timer.java | 1 - .../share/classes/javax/swing/UIManager.java | 1 - .../colorchooser/ColorChooserComponentFactory.java | 3 +-- .../javax/swing/filechooser/FileSystemView.java | 1 - .../share/classes/javax/swing/plaf/LayerUI.java | 7 +------ .../javax/swing/plaf/basic/BasicCheckBoxUI.java | 3 +-- .../swing/plaf/basic/BasicComboBoxEditor.java | 3 +-- .../javax/swing/plaf/basic/BasicComboBoxUI.java | 6 +----- .../javax/swing/plaf/basic/BasicFileChooserUI.java | 3 +-- .../javax/swing/plaf/basic/BasicListUI.java | 8 +------- .../javax/swing/plaf/basic/BasicOptionPaneUI.java | 1 - .../swing/plaf/basic/BasicSplitPaneDivider.java | 1 - .../javax/swing/plaf/basic/BasicSplitPaneUI.java | 3 +-- .../javax/swing/plaf/basic/BasicTextAreaUI.java | 3 +-- .../javax/swing/plaf/basic/BasicTextFieldUI.java | 3 +-- .../javax/swing/plaf/basic/BasicTextPaneUI.java | 3 +-- .../javax/swing/plaf/basic/BasicToolBarUI.java | 5 +---- .../classes/javax/swing/plaf/basic/ComboPopup.java | 3 +-- .../javax/swing/plaf/metal/DefaultMetalTheme.java | 3 +-- .../javax/swing/plaf/metal/MetalButtonUI.java | 3 +-- .../javax/swing/plaf/metal/MetalCheckBoxUI.java | 3 +-- .../swing/plaf/metal/MetalComboBoxEditor.java | 3 +-- .../javax/swing/plaf/metal/MetalFileChooserUI.java | 4 +--- .../javax/swing/plaf/metal/MetalProgressBarUI.java | 3 +-- .../javax/swing/plaf/metal/MetalRadioButtonUI.java | 3 +-- .../javax/swing/plaf/metal/MetalRootPaneUI.java | 3 +-- .../javax/swing/plaf/metal/MetalScrollPaneUI.java | 3 +-- .../javax/swing/plaf/metal/MetalSeparatorUI.java | 3 +-- .../javax/swing/plaf/metal/MetalSliderUI.java | 3 +-- .../javax/swing/plaf/metal/MetalSplitPaneUI.java | 3 +-- .../javax/swing/plaf/metal/MetalTabbedPaneUI.java | 3 +-- .../javax/swing/plaf/metal/MetalTextFieldUI.java | 3 +-- .../swing/plaf/metal/MetalToggleButtonUI.java | 3 +-- .../javax/swing/plaf/metal/MetalToolTipUI.java | 3 +-- .../classes/javax/swing/plaf/metal/MetalUtils.java | 4 +--- .../javax/swing/plaf/multi/MultiLookAndFeel.java | 3 +-- .../javax/swing/plaf/synth/SynthDesktopIconUI.java | 3 +-- .../javax/swing/plaf/synth/SynthScrollBarUI.java | 4 +--- .../javax/swing/plaf/synth/SynthSplitPaneUI.java | 3 +-- .../javax/swing/plaf/synth/SynthTextAreaUI.java | 3 +-- .../javax/swing/plaf/synth/SynthTextFieldUI.java | 3 +-- .../javax/swing/plaf/synth/SynthTextPaneUI.java | 3 +-- .../javax/swing/plaf/synth/SynthTreeUI.java | 3 +-- .../javax/swing/text/DefaultStyledDocument.java | 3 +-- .../classes/javax/swing/text/JTextComponent.java | 2 -- .../javax/swing/text/SimpleAttributeSet.java | 3 +-- .../classes/javax/swing/text/StyledEditorKit.java | 3 +-- .../classes/javax/swing/text/WrappedPlainView.java | 4 +--- .../classes/javax/swing/text/html/FormView.java | 6 +----- .../javax/swing/tree/AbstractLayoutCache.java | 3 +-- .../javax/swing/tree/DefaultTreeCellEditor.java | 3 +-- .../share/classes/sun/awt/AWTAutoShutdown.java | 3 +-- .../share/classes/sun/awt/AppContext.java | 3 +-- .../share/classes/sun/awt/CausedFocusEvent.java | 3 +-- .../sun/awt/KeyboardFocusManagerPeerImpl.java | 3 +-- .../share/classes/sun/awt/LightweightFrame.java | 3 +-- .../share/classes/sun/awt/SunToolkit.java | 4 +--- .../share/classes/sun/java2d/Disposer.java | 3 +-- .../sun/java2d/marlin/DMarlinRenderingEngine.java | 3 +-- .../share/classes/sun/print/ServiceDialog.java | 3 +-- .../share/classes/sun/swing/FilePane.java | 5 +---- .../share/classes/sun/swing/JLightweightFrame.java | 4 ++-- .../classes/sun/swing/LightweightContent.java | 4 +--- .../share/classes/sun/swing/PrintingStatus.java | 3 +-- .../swing/plaf/synth/SynthFileChooserUIImpl.java | 3 +-- .../sun/swing/text/TextComponentPrintable.java | 1 - 107 files changed, 95 insertions(+), 252 deletions(-) diff --git a/src/demo/share/jfc/SampleTree/SampleTree.java b/src/demo/share/jfc/SampleTree/SampleTree.java index 90588e6ec3a..8ff33828791 100644 --- a/src/demo/share/jfc/SampleTree/SampleTree.java +++ b/src/demo/share/jfc/SampleTree/SampleTree.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -142,7 +142,6 @@ public SampleTree() { /** Constructs a JPanel containing check boxes for the different * options that tree supports. */ - @SuppressWarnings("serial") private JPanel constructOptionsPanel() { JCheckBox aCheckbox; JPanel retPanel = new JPanel(false); diff --git a/src/demo/share/jfc/TableExample/TableExample3.java b/src/demo/share/jfc/TableExample/TableExample3.java index 9f3c11f4448..a5344f8802a 100644 --- a/src/demo/share/jfc/TableExample/TableExample3.java +++ b/src/demo/share/jfc/TableExample/TableExample3.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -97,7 +97,6 @@ public void windowClosing(WindowEvent e) { }; // Create a model of the data. - @SuppressWarnings("serial") TableModel dataModel = new AbstractTableModel() { // These methods always need to be implemented. diff --git a/src/demo/share/jfc/TableExample/TableExample4.java b/src/demo/share/jfc/TableExample/TableExample4.java index 4d81a3d8cf3..b429c9ec9de 100644 --- a/src/demo/share/jfc/TableExample/TableExample4.java +++ b/src/demo/share/jfc/TableExample/TableExample4.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -99,7 +99,6 @@ public void windowClosing(WindowEvent e) { }; // Create a model of the data. - @SuppressWarnings("serial") TableModel dataModel = new AbstractTableModel() { // These methods always need to be implemented. @@ -180,7 +179,6 @@ public void setValueAt(Object aValue, int row, int column) { // Show the values in the "Favorite Number" column in different colors. TableColumn numbersColumn = tableView.getColumn("Favorite Number"); - @SuppressWarnings("serial") DefaultTableCellRenderer numberColumnRenderer = new DefaultTableCellRenderer() { diff --git a/src/java.desktop/macosx/classes/com/apple/laf/AquaComboBoxButton.java b/src/java.desktop/macosx/classes/com/apple/laf/AquaComboBoxButton.java index b79cc98be9d..a9eab801b0d 100644 --- a/src/java.desktop/macosx/classes/com/apple/laf/AquaComboBoxButton.java +++ b/src/java.desktop/macosx/classes/com/apple/laf/AquaComboBoxButton.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -63,7 +63,6 @@ class AquaComboBoxButton extends JButton { boolean isPopDown; boolean isSquare; - @SuppressWarnings("serial") // anonymous class protected AquaComboBoxButton(final AquaComboBoxUI ui, final JComboBox<Object> comboBox, final CellRendererPane rendererPane, diff --git a/src/java.desktop/macosx/classes/com/apple/laf/AquaComboBoxPopup.java b/src/java.desktop/macosx/classes/com/apple/laf/AquaComboBoxPopup.java index 981a00d5588..dc29d0b5ae8 100644 --- a/src/java.desktop/macosx/classes/com/apple/laf/AquaComboBoxPopup.java +++ b/src/java.desktop/macosx/classes/com/apple/laf/AquaComboBoxPopup.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -161,7 +161,6 @@ public void show() { } @Override - @SuppressWarnings("serial") // anonymous class protected JList<Object> createList() { return new JList<Object>(comboBox.getModel()) { @Override diff --git a/src/java.desktop/macosx/classes/com/apple/laf/AquaComboBoxUI.java b/src/java.desktop/macosx/classes/com/apple/laf/AquaComboBoxUI.java index b9b60994085..130c30aa9e1 100644 --- a/src/java.desktop/macosx/classes/com/apple/laf/AquaComboBoxUI.java +++ b/src/java.desktop/macosx/classes/com/apple/laf/AquaComboBoxUI.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -230,7 +230,6 @@ private void editorTextChanged() { @SuppressWarnings("serial") // Superclass is not serializable across versions class AquaCustomComboTextField extends JTextField { - @SuppressWarnings("serial") // anonymous class public AquaCustomComboTextField() { final InputMap inputMap = getInputMap(); inputMap.put(KeyStroke.getKeyStroke("DOWN"), highlightNextAction); @@ -350,7 +349,6 @@ public void actionPerformed(final ActionEvent e) { /** * Highlight _but do not select_ the next item in the list. */ - @SuppressWarnings("serial") // anonymous class private Action highlightNextAction = new ComboBoxAction() { @Override public void performComboBoxAction(AquaComboBoxUI ui) { @@ -367,7 +365,6 @@ public void performComboBoxAction(AquaComboBoxUI ui) { /** * Highlight _but do not select_ the previous item in the list. */ - @SuppressWarnings("serial") // anonymous class private Action highlightPreviousAction = new ComboBoxAction() { @Override void performComboBoxAction(final AquaComboBoxUI ui) { @@ -380,7 +377,6 @@ void performComboBoxAction(final AquaComboBoxUI ui) { } }; - @SuppressWarnings("serial") // anonymous class private Action highlightFirstAction = new ComboBoxAction() { @Override void performComboBoxAction(final AquaComboBoxUI ui) { @@ -389,7 +385,6 @@ void performComboBoxAction(final AquaComboBoxUI ui) { } }; - @SuppressWarnings("serial") // anonymous class private Action highlightLastAction = new ComboBoxAction() { @Override void performComboBoxAction(final AquaComboBoxUI ui) { @@ -399,7 +394,6 @@ void performComboBoxAction(final AquaComboBoxUI ui) { } }; - @SuppressWarnings("serial") // anonymous class private Action highlightPageUpAction = new ComboBoxAction() { @Override void performComboBoxAction(final AquaComboBoxUI ui) { @@ -420,7 +414,6 @@ void performComboBoxAction(final AquaComboBoxUI ui) { } }; - @SuppressWarnings("serial") // anonymous class private Action highlightPageDownAction = new ComboBoxAction() { @Override void performComboBoxAction(final AquaComboBoxUI ui) { @@ -560,7 +553,6 @@ protected static void triggerSelectionEvent(final JComboBox<?> comboBox, final A // This is somewhat messy. The difference here from BasicComboBoxUI.EnterAction is that // arrow up or down does not automatically select the - @SuppressWarnings("serial") // anonymous class private final Action triggerSelectionAction = new AbstractAction() { public void actionPerformed(final ActionEvent e) { triggerSelectionEvent((JComboBox)e.getSource(), e); @@ -572,7 +564,6 @@ public boolean isEnabled() { } }; - @SuppressWarnings("serial") // anonymous class private static final Action toggleSelectionAction = new AbstractAction() { public void actionPerformed(final ActionEvent e) { final JComboBox<?> comboBox = (JComboBox<?>) e.getSource(); @@ -591,7 +582,6 @@ public void actionPerformed(final ActionEvent e) { } }; - @SuppressWarnings("serial") // anonymous class private final Action hideAction = new AbstractAction() { @Override public void actionPerformed(final ActionEvent e) { @@ -606,7 +596,6 @@ public boolean isEnabled() { } }; - @SuppressWarnings("serial") // anonymous class private final Action openPopupOrHighlightLast = new ComboBoxAction() { @Override void performComboBoxAction(final AquaComboBoxUI ui) { @@ -617,7 +606,6 @@ void performComboBoxAction(final AquaComboBoxUI ui) { } }; - @SuppressWarnings("serial") // anonymous class private final Action openPopupOrHighlightFirst = new ComboBoxAction() { @Override void performComboBoxAction(final AquaComboBoxUI ui) { diff --git a/src/java.desktop/macosx/classes/com/apple/laf/AquaFileChooserUI.java b/src/java.desktop/macosx/classes/com/apple/laf/AquaFileChooserUI.java index e4b112cc297..bdb440bf4d2 100644 --- a/src/java.desktop/macosx/classes/com/apple/laf/AquaFileChooserUI.java +++ b/src/java.desktop/macosx/classes/com/apple/laf/AquaFileChooserUI.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -1240,7 +1240,6 @@ public Dimension getMaximumSize(final JComponent c) { return new Dimension(Integer.MAX_VALUE, Integer.MAX_VALUE); } - @SuppressWarnings("serial") // anonymous class protected ListCellRenderer<File> createDirectoryComboBoxRenderer(final JFileChooser fc) { return new AquaComboBoxRendererInternal<File>(directoryComboBox) { public Component getListCellRendererComponent(final JList<? extends File> list, @@ -1356,7 +1355,6 @@ public File getElementAt(final int index) { // // Renderer for Types ComboBox // - @SuppressWarnings("serial") // anonymous class protected ListCellRenderer<FileFilter> createFilterComboBoxRenderer() { return new AquaComboBoxRendererInternal<FileFilter>(filterComboBox) { public Component getListCellRendererComponent(final JList<? extends FileFilter> list, @@ -1611,7 +1609,6 @@ public void installComponents(final JFileChooser fc) { tPanel.add(labelArea); // separator line - @SuppressWarnings("serial") // anonymous class final JSeparator sep = new JSeparator(){ public Dimension getPreferredSize() { return new Dimension(((JComponent)getParent()).getWidth(), 3); diff --git a/src/java.desktop/macosx/classes/com/apple/laf/AquaFileView.java b/src/java.desktop/macosx/classes/com/apple/laf/AquaFileView.java index 32b43dba295..653cf49cb55 100644 --- a/src/java.desktop/macosx/classes/com/apple/laf/AquaFileView.java +++ b/src/java.desktop/macosx/classes/com/apple/laf/AquaFileView.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -39,7 +39,6 @@ import static java.nio.charset.StandardCharsets.UTF_8; -@SuppressWarnings("serial") // JDK implementation class class AquaFileView extends FileView { private static final boolean DEBUG = false; diff --git a/src/java.desktop/macosx/classes/com/apple/laf/AquaTabbedPaneUI.java b/src/java.desktop/macosx/classes/com/apple/laf/AquaTabbedPaneUI.java index e00722bc293..1a10e30a6c6 100644 --- a/src/java.desktop/macosx/classes/com/apple/laf/AquaTabbedPaneUI.java +++ b/src/java.desktop/macosx/classes/com/apple/laf/AquaTabbedPaneUI.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -1020,7 +1020,6 @@ JMenuItem createMenuItem(final int i) { if (component == null) { menuItem = new JMenuItem(tabPane.getTitleAt(i), tabPane.getIconAt(i)); } else { - @SuppressWarnings("serial") // anonymous class JMenuItem tmp = new JMenuItem() { public void paintComponent(final Graphics g) { super.paintComponent(g); diff --git a/src/java.desktop/macosx/classes/com/apple/laf/AquaTextFieldSearch.java b/src/java.desktop/macosx/classes/com/apple/laf/AquaTextFieldSearch.java index 99349b6c6b3..a6be82d9ac3 100644 --- a/src/java.desktop/macosx/classes/com/apple/laf/AquaTextFieldSearch.java +++ b/src/java.desktop/macosx/classes/com/apple/laf/AquaTextFieldSearch.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -249,7 +249,6 @@ static void updatePromptLabelOnEDT(final JLabel label, final JTextComponent text label.setText(promptText); } - @SuppressWarnings("serial") // anonymous class inside protected static JButton getCancelButton(final JTextComponent c) { final JButton b = createButton(c, getCancelIcon()); b.setName("cancel"); @@ -326,7 +325,6 @@ public Insets getBorderInsets(final Component c) { } protected boolean doingLayout; - @SuppressWarnings("serial") // anonymous class inside protected LayoutManager getCustomLayout() { // unfortunately, the default behavior of BorderLayout, which accommodates for margins // is not what we want, so we "turn off margins" for layout for layout out our buttons diff --git a/src/java.desktop/macosx/classes/sun/lwawt/LWListPeer.java b/src/java.desktop/macosx/classes/sun/lwawt/LWListPeer.java index a9081ae3c36..905a66b3212 100644 --- a/src/java.desktop/macosx/classes/sun/lwawt/LWListPeer.java +++ b/src/java.desktop/macosx/classes/sun/lwawt/LWListPeer.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -254,7 +254,6 @@ public void setSkipStateChangedEvent(boolean skipStateChangedEvent) { } @Override - @SuppressWarnings("unchecked") public void valueChanged(final ListSelectionEvent e) { if (!e.getValueIsAdjusting() && !isSkipStateChangedEvent()) { final JList<?> source = (JList<?>) e.getSource(); diff --git a/src/java.desktop/macosx/classes/sun/lwawt/LWWindowPeer.java b/src/java.desktop/macosx/classes/sun/lwawt/LWWindowPeer.java index 4ec8d87fee3..13b6372a3c8 100644 --- a/src/java.desktop/macosx/classes/sun/lwawt/LWWindowPeer.java +++ b/src/java.desktop/macosx/classes/sun/lwawt/LWWindowPeer.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -1353,7 +1353,6 @@ public void emulateActivation(boolean activate) { changeFocusedWindow(activate, null); } - @SuppressWarnings("deprecation") private boolean isOneOfOwnersOf(LWWindowPeer peer) { Window owner = (peer != null ? peer.getTarget().getOwner() : null); while (owner != null) { diff --git a/src/java.desktop/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java b/src/java.desktop/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java index 3af1b4bcdda..0596ad2379e 100644 --- a/src/java.desktop/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java +++ b/src/java.desktop/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java @@ -268,7 +268,6 @@ public void applyProperty(final CPlatformWindow c, final Object value) { } } }) { - @SuppressWarnings("deprecation") public CPlatformWindow convertJComponentToTarget(final JRootPane p) { Component root = SwingUtilities.getRoot(p); final ComponentAccessor acc = AWTAccessor.getComponentAccessor(); diff --git a/src/java.desktop/share/classes/com/sun/imageio/plugins/tiff/TIFFOldJPEGDecompressor.java b/src/java.desktop/share/classes/com/sun/imageio/plugins/tiff/TIFFOldJPEGDecompressor.java index 5ad3db345e2..bc787f9127c 100644 --- a/src/java.desktop/share/classes/com/sun/imageio/plugins/tiff/TIFFOldJPEGDecompressor.java +++ b/src/java.desktop/share/classes/com/sun/imageio/plugins/tiff/TIFFOldJPEGDecompressor.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -610,7 +610,6 @@ public void decodeRaw(byte[] b, JPEGReader.read(0, JPEGParam); } - @SuppressWarnings("removal") protected void finalize() throws Throwable { super.finalize(); JPEGReader.dispose(); diff --git a/src/java.desktop/share/classes/com/sun/java/swing/plaf/motif/MotifFileChooserUI.java b/src/java.desktop/share/classes/com/sun/java/swing/plaf/motif/MotifFileChooserUI.java index a6d2f5bbb0e..0f1ecd0dc1e 100644 --- a/src/java.desktop/share/classes/com/sun/java/swing/plaf/motif/MotifFileChooserUI.java +++ b/src/java.desktop/share/classes/com/sun/java/swing/plaf/motif/MotifFileChooserUI.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -281,7 +281,6 @@ public void installComponents(JFileChooser fc) { fc.setLayout(new BorderLayout(10, 10)); fc.setAlignmentX(JComponent.CENTER_ALIGNMENT); - @SuppressWarnings("serial") // anonymous class JPanel interior = new JPanel() { public Insets getInsets() { return insets; @@ -305,7 +304,6 @@ public Insets getInsets() { curDirName = currentDirectory.getPath(); } - @SuppressWarnings("serial") // anonymous class JTextField tmp1 = new JTextField(curDirName, 35) { public Dimension getMaximumSize() { Dimension d = super.getMaximumSize(); @@ -341,7 +339,6 @@ public Dimension getMaximumSize() { align(l); leftPanel.add(l); - @SuppressWarnings("serial") // anonymous class JComboBox<FileFilter> tmp2 = new JComboBox<FileFilter>() { public Dimension getMaximumSize() { Dimension d = super.getMaximumSize(); @@ -419,7 +416,6 @@ public Dimension getMaximumSize() { align(fileNameLabel); interior.add(fileNameLabel); - @SuppressWarnings("serial") // anonymous class JTextField tmp3 = new JTextField(35) { public Dimension getMaximumSize() { Dimension d = super.getMaximumSize(); @@ -444,7 +440,6 @@ public Dimension getMaximumSize() { buttonPanel.setLayout(new BoxLayout(buttonPanel, BoxLayout.LINE_AXIS)); buttonPanel.add(Box.createGlue()); - @SuppressWarnings("serial") // anonymous class JButton tmp4 = new JButton(getApproveButtonText(fc)) { public Dimension getMaximumSize() { return new Dimension(MAX_SIZE.width, this.getPreferredSize().height); @@ -460,7 +455,6 @@ public Dimension getMaximumSize() { buttonPanel.add(approveButton); buttonPanel.add(Box.createGlue()); - @SuppressWarnings("serial") // anonymous class JButton updateButton = new JButton(updateButtonText) { public Dimension getMaximumSize() { return new Dimension(MAX_SIZE.width, this.getPreferredSize().height); @@ -475,7 +469,6 @@ public Dimension getMaximumSize() { buttonPanel.add(updateButton); buttonPanel.add(Box.createGlue()); - @SuppressWarnings("serial") // anonymous class JButton cancelButton = new JButton(cancelButtonText) { public Dimension getMaximumSize() { return new Dimension(MAX_SIZE.width, this.getPreferredSize().height); @@ -490,7 +483,6 @@ public Dimension getMaximumSize() { buttonPanel.add(cancelButton); buttonPanel.add(Box.createGlue()); - @SuppressWarnings("serial") // anonymous class JButton helpButton = new JButton(helpButtonText) { public Dimension getMaximumSize() { return new Dimension(MAX_SIZE.width, this.getPreferredSize().height); diff --git a/src/java.desktop/share/classes/com/sun/java/swing/plaf/motif/MotifInternalFrameUI.java b/src/java.desktop/share/classes/com/sun/java/swing/plaf/motif/MotifInternalFrameUI.java index cba71847fa4..1179df181ab 100644 --- a/src/java.desktop/share/classes/com/sun/java/swing/plaf/motif/MotifInternalFrameUI.java +++ b/src/java.desktop/share/classes/com/sun/java/swing/plaf/motif/MotifInternalFrameUI.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -132,7 +132,6 @@ protected void uninstallKeyboardActions(){ } } - @SuppressWarnings("serial") // anonymous class protected void setupMenuOpenKey(){ super.setupMenuOpenKey(); ActionMap map = SwingUtilities.getUIActionMap(frame); @@ -152,7 +151,6 @@ public boolean isEnabled(){ } } - @SuppressWarnings("serial") // anonymous class protected void setupMenuCloseKey(){ ActionMap map = SwingUtilities.getUIActionMap(frame); if (map != null) { diff --git a/src/java.desktop/share/classes/com/sun/java/swing/plaf/motif/MotifOptionPaneUI.java b/src/java.desktop/share/classes/com/sun/java/swing/plaf/motif/MotifOptionPaneUI.java index a9c40aa71af..e68d7e2d8bf 100644 --- a/src/java.desktop/share/classes/com/sun/java/swing/plaf/motif/MotifOptionPaneUI.java +++ b/src/java.desktop/share/classes/com/sun/java/swing/plaf/motif/MotifOptionPaneUI.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -72,7 +72,6 @@ public Dimension getMinimumOptionPaneSize() { return null; } - @SuppressWarnings("serial") // anonymous class protected Container createSeparator() { return new JPanel() { diff --git a/src/java.desktop/share/classes/com/sun/media/sound/JavaSoundAudioClip.java b/src/java.desktop/share/classes/com/sun/media/sound/JavaSoundAudioClip.java index affec1aace1..00862ea9022 100644 --- a/src/java.desktop/share/classes/com/sun/media/sound/JavaSoundAudioClip.java +++ b/src/java.desktop/share/classes/com/sun/media/sound/JavaSoundAudioClip.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -57,7 +57,7 @@ * @author Arthur van Hoff, Kara Kytle, Jan Borgersen * @author Florian Bomers */ -@SuppressWarnings({"deprecation", "removal"}) +@SuppressWarnings("removal") public final class JavaSoundAudioClip implements AudioClip, MetaEventListener, LineListener { private long lastPlayCall = 0; diff --git a/src/java.desktop/share/classes/java/awt/AWTEventMulticaster.java b/src/java.desktop/share/classes/java/awt/AWTEventMulticaster.java index 56084ec8f90..592482823db 100644 --- a/src/java.desktop/share/classes/java/awt/AWTEventMulticaster.java +++ b/src/java.desktop/share/classes/java/awt/AWTEventMulticaster.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -625,7 +625,6 @@ public static WindowListener add(WindowListener a, WindowListener b) { * @return the resulting listener * @since 1.4 */ - @SuppressWarnings("overloads") public static WindowStateListener add(WindowStateListener a, WindowStateListener b) { return (WindowStateListener)addInternal(a, b); @@ -828,7 +827,6 @@ public static WindowListener remove(WindowListener l, WindowListener oldl) { * @return the resulting listener * @since 1.4 */ - @SuppressWarnings("overloads") public static WindowStateListener remove(WindowStateListener l, WindowStateListener oldl) { return (WindowStateListener) removeInternal(l, oldl); diff --git a/src/java.desktop/share/classes/java/awt/Component.java b/src/java.desktop/share/classes/java/awt/Component.java index a1f8461c802..71618eea95b 100644 --- a/src/java.desktop/share/classes/java/awt/Component.java +++ b/src/java.desktop/share/classes/java/awt/Component.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1995, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1995, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -7415,7 +7415,6 @@ final void setFocusTraversalKeys_NoIDCheck(int id, Set<? extends AWTKeyStroke> k } final Set<AWTKeyStroke> getFocusTraversalKeys_NoIDCheck(int id) { // Okay to return Set directly because it is an unmodifiable view - @SuppressWarnings("unchecked") Set<AWTKeyStroke> keystrokes = (focusTraversalKeys != null) ? focusTraversalKeys[id] : null; @@ -8362,7 +8361,6 @@ public void add(PopupMenu popup) { * @see #add(PopupMenu) * @since 1.1 */ - @SuppressWarnings("unchecked") public void remove(MenuComponent popup) { synchronized (getTreeLock()) { if (popups == null) { diff --git a/src/java.desktop/share/classes/java/awt/Container.java b/src/java.desktop/share/classes/java/awt/Container.java index 2eb2c923de0..63bd7467d91 100644 --- a/src/java.desktop/share/classes/java/awt/Container.java +++ b/src/java.desktop/share/classes/java/awt/Container.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1995, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1995, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -814,7 +814,6 @@ public void setComponentZOrder(Component comp, int index) { * to new heavyweight parent. * @since 1.5 */ - @SuppressWarnings("deprecation") private void reparentTraverse(ContainerPeer parentPeer, Container child) { checkTreeLock(); @@ -838,7 +837,6 @@ private void reparentTraverse(ContainerPeer parentPeer, Container child) { * Container must be heavyweight. * @since 1.5 */ - @SuppressWarnings("deprecation") private void reparentChild(Component comp) { checkTreeLock(); if (comp == null) { @@ -4203,7 +4201,6 @@ final void recursiveApplyCurrentShape(int fromZorder, int toZorder) { } } - @SuppressWarnings("deprecation") private void recursiveShowHeavyweightChildren() { if (!hasHeavyweightDescendants() || !isVisible()) { return; @@ -4225,7 +4222,6 @@ private void recursiveShowHeavyweightChildren() { } } - @SuppressWarnings("deprecation") private void recursiveHideHeavyweightChildren() { if (!hasHeavyweightDescendants()) { return; @@ -4247,7 +4243,6 @@ private void recursiveHideHeavyweightChildren() { } } - @SuppressWarnings("deprecation") private void recursiveRelocateHeavyweightChildren(Point origin) { for (int index = 0; index < getComponentCount(); index++) { Component comp = getComponent(index); diff --git a/src/java.desktop/share/classes/java/awt/DefaultKeyboardFocusManager.java b/src/java.desktop/share/classes/java/awt/DefaultKeyboardFocusManager.java index 3c57ec3a8d9..8ee336548d2 100644 --- a/src/java.desktop/share/classes/java/awt/DefaultKeyboardFocusManager.java +++ b/src/java.desktop/share/classes/java/awt/DefaultKeyboardFocusManager.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -1087,7 +1087,6 @@ void clearMarkers() { } } - @SuppressWarnings("deprecation") private boolean preDispatchKeyEvent(KeyEvent ke) { if (((AWTEvent) ke).isPosted) { Component focusOwner = getFocusOwner(); diff --git a/src/java.desktop/share/classes/java/awt/EventQueue.java b/src/java.desktop/share/classes/java/awt/EventQueue.java index 57a9a6cf567..f79ff285a79 100644 --- a/src/java.desktop/share/classes/java/awt/EventQueue.java +++ b/src/java.desktop/share/classes/java/awt/EventQueue.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -1058,7 +1058,7 @@ final boolean isDispatchThreadImpl() { } } - @SuppressWarnings({"deprecation", "removal"}) + @SuppressWarnings("removal") final void initDispatchThread() { pushPopLock.lock(); try { diff --git a/src/java.desktop/share/classes/java/awt/MediaTracker.java b/src/java.desktop/share/classes/java/awt/MediaTracker.java index 2435dd0ba33..408d68ffe14 100644 --- a/src/java.desktop/share/classes/java/awt/MediaTracker.java +++ b/src/java.desktop/share/classes/java/awt/MediaTracker.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1995, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1995, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -927,7 +927,6 @@ void setStatus(int flag) { * The entry of the list of {@code Images} that is being tracked by the * {@code MediaTracker}. */ -@SuppressWarnings("serial") // MediaEntry does not have a no-arg ctor class ImageMediaEntry extends MediaEntry implements ImageObserver, java.io.Serializable { @SuppressWarnings("serial") // Not statically typed as Serializable diff --git a/src/java.desktop/share/classes/java/awt/SequencedEvent.java b/src/java.desktop/share/classes/java/awt/SequencedEvent.java index a671814a57b..e04757e195f 100644 --- a/src/java.desktop/share/classes/java/awt/SequencedEvent.java +++ b/src/java.desktop/share/classes/java/awt/SequencedEvent.java @@ -43,7 +43,6 @@ * * @author David Mendenhall */ -@SuppressWarnings("removal") class SequencedEvent extends AWTEvent implements ActiveEvent { /** diff --git a/src/java.desktop/share/classes/java/awt/SplashScreen.java b/src/java.desktop/share/classes/java/awt/SplashScreen.java index 7f522026b8a..737c1a5c080 100644 --- a/src/java.desktop/share/classes/java/awt/SplashScreen.java +++ b/src/java.desktop/share/classes/java/awt/SplashScreen.java @@ -121,7 +121,7 @@ public final class SplashScreen { * @return the {@link SplashScreen} instance, or {@code null} if there is * none or it has already been closed */ - @SuppressWarnings({"removal", "restricted"}) + @SuppressWarnings("restricted") public static SplashScreen getSplashScreen() { synchronized (SplashScreen.class) { if (GraphicsEnvironment.isHeadless()) { diff --git a/src/java.desktop/share/classes/java/awt/WaitDispatchSupport.java b/src/java.desktop/share/classes/java/awt/WaitDispatchSupport.java index 2968c9ad3ef..50a66e997f9 100644 --- a/src/java.desktop/share/classes/java/awt/WaitDispatchSupport.java +++ b/src/java.desktop/share/classes/java/awt/WaitDispatchSupport.java @@ -161,7 +161,6 @@ public WaitDispatchSupport(EventDispatchThread dispatchThread, /** * {@inheritDoc} */ - @SuppressWarnings("removal") @Override public boolean enter() { if (log.isLoggable(PlatformLogger.Level.FINE)) { diff --git a/src/java.desktop/share/classes/java/awt/Window.java b/src/java.desktop/share/classes/java/awt/Window.java index 1a5395431ab..9b855739443 100644 --- a/src/java.desktop/share/classes/java/awt/Window.java +++ b/src/java.desktop/share/classes/java/awt/Window.java @@ -798,7 +798,6 @@ public void removeNotify() { * @see Component#isDisplayable * @see #setMinimumSize */ - @SuppressWarnings("deprecation") public void pack() { Container parent = this.parent; if (parent != null && parent.peer == null) { @@ -3604,7 +3603,6 @@ public float getOpacity() { * * @since 1.7 */ - @SuppressWarnings("deprecation") public void setOpacity(float opacity) { synchronized (getTreeLock()) { if (opacity < 0.0f || opacity > 1.0f) { diff --git a/src/java.desktop/share/classes/java/awt/dnd/DragSource.java b/src/java.desktop/share/classes/java/awt/dnd/DragSource.java index 8477bc6376d..b5da544c46d 100644 --- a/src/java.desktop/share/classes/java/awt/dnd/DragSource.java +++ b/src/java.desktop/share/classes/java/awt/dnd/DragSource.java @@ -905,7 +905,6 @@ private void readObject(ObjectInputStream s) * @since 1.5 */ public static int getDragThreshold() { - @SuppressWarnings("removal") int ts = Integer.getInteger("awt.dnd.drag.threshold", 0); if (ts > 0) { return ts; diff --git a/src/java.desktop/share/classes/java/awt/event/FocusEvent.java b/src/java.desktop/share/classes/java/awt/event/FocusEvent.java index 4fb9043e5b7..27da2e8b4bb 100644 --- a/src/java.desktop/share/classes/java/awt/event/FocusEvent.java +++ b/src/java.desktop/share/classes/java/awt/event/FocusEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -391,7 +391,6 @@ public final Cause getCause() { * @since 9 */ @Serial - @SuppressWarnings("serial") Object readResolve() throws ObjectStreamException { if (cause != null) { return this; diff --git a/src/java.desktop/share/classes/java/beans/Beans.java b/src/java.desktop/share/classes/java/beans/Beans.java index 247f6982471..e35a751a42e 100644 --- a/src/java.desktop/share/classes/java/beans/Beans.java +++ b/src/java.desktop/share/classes/java/beans/Beans.java @@ -105,7 +105,7 @@ public static Object instantiate(ClassLoader cls, String beanName) throws IOExce * @deprecated this method will be removed when java.beans.beancontext is removed */ @Deprecated(since = "23", forRemoval = true) - @SuppressWarnings({"deprecation", "removal"}) + @SuppressWarnings("removal") public static Object instantiate(ClassLoader cls, String beanName, BeanContext beanContext) throws IOException, ClassNotFoundException { diff --git a/src/java.desktop/share/classes/java/beans/beancontext/BeanContextChildComponentProxy.java b/src/java.desktop/share/classes/java/beans/beancontext/BeanContextChildComponentProxy.java index 91d22ecce3b..9f79d1c27a9 100644 --- a/src/java.desktop/share/classes/java/beans/beancontext/BeanContextChildComponentProxy.java +++ b/src/java.desktop/share/classes/java/beans/beancontext/BeanContextChildComponentProxy.java @@ -41,7 +41,6 @@ * @see java.beans.beancontext.BeanContextSupport */ -@SuppressWarnings("removal") @Deprecated(since = "23", forRemoval = true) public interface BeanContextChildComponentProxy { diff --git a/src/java.desktop/share/classes/java/beans/beancontext/BeanContextContainerProxy.java b/src/java.desktop/share/classes/java/beans/beancontext/BeanContextContainerProxy.java index 3c6e0656c50..4fe6758b21f 100644 --- a/src/java.desktop/share/classes/java/beans/beancontext/BeanContextContainerProxy.java +++ b/src/java.desktop/share/classes/java/beans/beancontext/BeanContextContainerProxy.java @@ -40,7 +40,6 @@ * @see java.beans.beancontext.BeanContextSupport */ -@SuppressWarnings("removal") @Deprecated(since = "23", forRemoval = true) public interface BeanContextContainerProxy { diff --git a/src/java.desktop/share/classes/java/beans/beancontext/BeanContextServiceProviderBeanInfo.java b/src/java.desktop/share/classes/java/beans/beancontext/BeanContextServiceProviderBeanInfo.java index 11fe3fff730..60c80edee35 100644 --- a/src/java.desktop/share/classes/java/beans/beancontext/BeanContextServiceProviderBeanInfo.java +++ b/src/java.desktop/share/classes/java/beans/beancontext/BeanContextServiceProviderBeanInfo.java @@ -35,7 +35,6 @@ * services. */ -@SuppressWarnings("removal") @Deprecated(since = "23", forRemoval = true) public interface BeanContextServiceProviderBeanInfo extends BeanInfo { diff --git a/src/java.desktop/share/classes/javax/swing/DefaultFocusManager.java b/src/java.desktop/share/classes/javax/swing/DefaultFocusManager.java index 4413721097d..47cca584452 100644 --- a/src/java.desktop/share/classes/javax/swing/DefaultFocusManager.java +++ b/src/java.desktop/share/classes/javax/swing/DefaultFocusManager.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -47,7 +47,6 @@ * @author David Mendenhall * @since 1.2 */ -@SuppressWarnings("serial") // Obsolete class public class DefaultFocusManager extends FocusManager { final FocusTraversalPolicy gluePolicy = diff --git a/src/java.desktop/share/classes/javax/swing/JColorChooser.java b/src/java.desktop/share/classes/javax/swing/JColorChooser.java index 62c4fe8b083..89291be5f04 100644 --- a/src/java.desktop/share/classes/javax/swing/JColorChooser.java +++ b/src/java.desktop/share/classes/javax/swing/JColorChooser.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -714,7 +714,6 @@ public void actionPerformed(ActionEvent e) { cancelButton.getAccessibleContext().setAccessibleDescription(cancelString); // The following few lines are used to register esc to close the dialog - @SuppressWarnings("serial") // anonymous class Action cancelKeyAction = new AbstractAction() { public void actionPerformed(ActionEvent e) { ((AbstractButton)e.getSource()).fireActionPerformed(e); diff --git a/src/java.desktop/share/classes/javax/swing/JComponent.java b/src/java.desktop/share/classes/javax/swing/JComponent.java index 352fefeaacb..92f3f01ab3e 100644 --- a/src/java.desktop/share/classes/javax/swing/JComponent.java +++ b/src/java.desktop/share/classes/javax/swing/JComponent.java @@ -2949,7 +2949,7 @@ protected void processKeyEvent(KeyEvent e) { * * @since 1.3 */ - @SuppressWarnings({"deprecation", "removal"}) + @SuppressWarnings("deprecation") protected boolean processKeyBinding(KeyStroke ks, KeyEvent e, int condition, boolean pressed) { InputMap map = getInputMap(condition, false); diff --git a/src/java.desktop/share/classes/javax/swing/JLayer.java b/src/java.desktop/share/classes/javax/swing/JLayer.java index b08b140933f..7ce28b2b723 100644 --- a/src/java.desktop/share/classes/javax/swing/JLayer.java +++ b/src/java.desktop/share/classes/javax/swing/JLayer.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -735,7 +735,6 @@ public void doLayout() { * * @return the AccessibleContext associated with this {@code JLayer}. */ - @SuppressWarnings("serial") // anonymous class public AccessibleContext getAccessibleContext() { if (accessibleContext == null) { accessibleContext = new AccessibleJComponent() { diff --git a/src/java.desktop/share/classes/javax/swing/KeyStroke.java b/src/java.desktop/share/classes/javax/swing/KeyStroke.java index dcd87c74535..054d1ad72bb 100644 --- a/src/java.desktop/share/classes/javax/swing/KeyStroke.java +++ b/src/java.desktop/share/classes/javax/swing/KeyStroke.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -66,7 +66,6 @@ * @author David Mendenhall * @since 1.2 */ -@SuppressWarnings("serial") // Same-version serialization only public class KeyStroke extends AWTKeyStroke { /** diff --git a/src/java.desktop/share/classes/javax/swing/Spring.java b/src/java.desktop/share/classes/javax/swing/Spring.java index 751eef76435..cf4504f51f9 100644 --- a/src/java.desktop/share/classes/javax/swing/Spring.java +++ b/src/java.desktop/share/classes/javax/swing/Spring.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -127,7 +127,6 @@ * @author Philip Milne * @since 1.4 */ -@SuppressWarnings("serial") // Same-version serialization only public abstract class Spring { /** diff --git a/src/java.desktop/share/classes/javax/swing/SpringLayout.java b/src/java.desktop/share/classes/javax/swing/SpringLayout.java index 27641690e22..76050d31ce3 100644 --- a/src/java.desktop/share/classes/javax/swing/SpringLayout.java +++ b/src/java.desktop/share/classes/javax/swing/SpringLayout.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -184,7 +184,6 @@ * @author Joe Winchester * @since 1.4 */ -@SuppressWarnings("serial") // Same-version serialization only public class SpringLayout implements LayoutManager2 { private Map<Component, Constraints> componentConstraints = new HashMap<Component, Constraints>(); diff --git a/src/java.desktop/share/classes/javax/swing/Timer.java b/src/java.desktop/share/classes/javax/swing/Timer.java index 3801eb0a072..46051d92df1 100644 --- a/src/java.desktop/share/classes/javax/swing/Timer.java +++ b/src/java.desktop/share/classes/javax/swing/Timer.java @@ -597,7 +597,6 @@ Lock getLock() { return lock; } - @SuppressWarnings("removal") @Serial private void readObject(ObjectInputStream in) throws ClassNotFoundException, IOException diff --git a/src/java.desktop/share/classes/javax/swing/UIManager.java b/src/java.desktop/share/classes/javax/swing/UIManager.java index 4c55e0c5149..752b37a5238 100644 --- a/src/java.desktop/share/classes/javax/swing/UIManager.java +++ b/src/java.desktop/share/classes/javax/swing/UIManager.java @@ -1261,7 +1261,6 @@ public static PropertyChangeListener[] getPropertyChangeListeners() { } } - @SuppressWarnings("removal") private static Properties loadSwingProperties() { /* Don't bother checking for Swing properties if untrusted, as diff --git a/src/java.desktop/share/classes/javax/swing/colorchooser/ColorChooserComponentFactory.java b/src/java.desktop/share/classes/javax/swing/colorchooser/ColorChooserComponentFactory.java index eb3920857a6..f1d012ad178 100644 --- a/src/java.desktop/share/classes/javax/swing/colorchooser/ColorChooserComponentFactory.java +++ b/src/java.desktop/share/classes/javax/swing/colorchooser/ColorChooserComponentFactory.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -43,7 +43,6 @@ * * @author Steve Wilson */ -@SuppressWarnings("serial") // Same-version serialization only public class ColorChooserComponentFactory { private ColorChooserComponentFactory() { } // can't instantiate diff --git a/src/java.desktop/share/classes/javax/swing/filechooser/FileSystemView.java b/src/java.desktop/share/classes/javax/swing/filechooser/FileSystemView.java index fb89f725cd0..6e9f9f26b37 100644 --- a/src/java.desktop/share/classes/javax/swing/filechooser/FileSystemView.java +++ b/src/java.desktop/share/classes/javax/swing/filechooser/FileSystemView.java @@ -934,7 +934,6 @@ public File createFileObject(String path) { return super.createFileObject(path); } - @SuppressWarnings("serial") // anonymous class protected File createFileSystemRoot(File f) { // Problem: Removable drives on Windows return false on f.exists() // Workaround: Override exists() to always return true. diff --git a/src/java.desktop/share/classes/javax/swing/plaf/LayerUI.java b/src/java.desktop/share/classes/javax/swing/plaf/LayerUI.java index 61fad895c38..00b7cfc0e5d 100644 --- a/src/java.desktop/share/classes/javax/swing/plaf/LayerUI.java +++ b/src/java.desktop/share/classes/javax/swing/plaf/LayerUI.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -615,7 +615,6 @@ public void applyPropertyChange(PropertyChangeEvent evt, JLayer<? extends V> l) * baseline */ public int getBaseline(JComponent c, int width, int height) { - @SuppressWarnings("unchecked") JLayer<?> l = (JLayer) c; if (l.getView() != null) { return l.getView().getBaseline(width, height); @@ -633,7 +632,6 @@ public int getBaseline(JComponent c, int width, int height) { * size changes */ public Component.BaselineResizeBehavior getBaselineResizeBehavior(JComponent c) { - @SuppressWarnings("unchecked") JLayer<?> l = (JLayer) c; if (l.getView() != null) { return l.getView().getBaselineResizeBehavior(); @@ -666,7 +664,6 @@ public void doLayout(JLayer<? extends V> l) { * @return preferred size for the passed {@code JLayer} */ public Dimension getPreferredSize(JComponent c) { - @SuppressWarnings("unchecked") JLayer<?> l = (JLayer) c; Component view = l.getView(); if (view != null) { @@ -684,7 +681,6 @@ public Dimension getPreferredSize(JComponent c) { * @return minimal size for the passed {@code JLayer} */ public Dimension getMinimumSize(JComponent c) { - @SuppressWarnings("unchecked") JLayer<?> l = (JLayer) c; Component view = l.getView(); if (view != null) { @@ -702,7 +698,6 @@ public Dimension getMinimumSize(JComponent c) { * @return maximum size for the passed {@code JLayer} */ public Dimension getMaximumSize(JComponent c) { - @SuppressWarnings("unchecked") JLayer<?> l = (JLayer) c; Component view = l.getView(); if (view != null) { diff --git a/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicCheckBoxUI.java b/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicCheckBoxUI.java index a1bd07282c1..24af28c94c0 100644 --- a/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicCheckBoxUI.java +++ b/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicCheckBoxUI.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -49,7 +49,6 @@ * * @author Jeff Dinkins */ -@SuppressWarnings("serial") // Same-version serialization only public class BasicCheckBoxUI extends BasicRadioButtonUI { private static final Object BASIC_CHECK_BOX_UI_KEY = new Object(); diff --git a/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicComboBoxEditor.java b/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicComboBoxEditor.java index 0e5eab8285b..b2a8c58eb2e 100644 --- a/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicComboBoxEditor.java +++ b/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicComboBoxEditor.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -173,7 +173,6 @@ public void setBorder(Border b) { * has been added to the <code>java.beans</code> package. * Please see {@link java.beans.XMLEncoder}. */ - @SuppressWarnings("serial") // Same-version serialization only public static class UIResource extends BasicComboBoxEditor implements javax.swing.plaf.UIResource { /** diff --git a/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicComboBoxUI.java b/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicComboBoxUI.java index 6be306d5572..2d1a458e0d7 100644 --- a/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicComboBoxUI.java +++ b/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicComboBoxUI.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -1792,12 +1792,9 @@ public void propertyChange(PropertyChangeEvent e) { comboBox.revalidate(); } } else { - @SuppressWarnings("unchecked") JComboBox<?> comboBox = (JComboBox)e.getSource(); if ( propertyName == "model" ) { - @SuppressWarnings("unchecked") ComboBoxModel<?> newModel = (ComboBoxModel)e.getNewValue(); - @SuppressWarnings("unchecked") ComboBoxModel<?> oldModel = (ComboBoxModel)e.getOldValue(); if ( oldModel != null && listDataListener != null ) { @@ -2012,7 +2009,6 @@ public Dimension minimumLayoutSize(Container parent) { } public void layoutContainer(Container parent) { - @SuppressWarnings("unchecked") JComboBox<?> cb = (JComboBox)parent; int width = cb.getWidth(); int height = cb.getHeight(); diff --git a/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicFileChooserUI.java b/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicFileChooserUI.java index 57bd6664e1a..bdce05ae866 100644 --- a/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicFileChooserUI.java +++ b/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicFileChooserUI.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -696,7 +696,6 @@ public void valueChanged(ListSelectionEvent evt) { if(!evt.getValueIsAdjusting()) { JFileChooser chooser = getFileChooser(); FileSystemView fsv = chooser.getFileSystemView(); - @SuppressWarnings("unchecked") JList<?> list = (JList)evt.getSource(); int fsm = chooser.getFileSelectionMode(); diff --git a/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicListUI.java b/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicListUI.java index 53eb25a76d7..0a4aa03dce9 100644 --- a/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicListUI.java +++ b/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicListUI.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -1579,7 +1579,6 @@ private Handler getHandler() { * @see #installKeyboardActions * @see #installUI */ - @SuppressWarnings("serial") // Same-version serialization only public class MouseInputHandler implements MouseInputListener { /** @@ -1703,7 +1702,6 @@ protected FocusListener createFocusListener() { * @see #getCellBounds * @see #installUI */ - @SuppressWarnings("serial") // Same-version serialization only public class ListSelectionHandler implements ListSelectionListener { /** @@ -1769,7 +1767,6 @@ private void redrawList() { * @see #createListDataListener * @see #installUI */ - @SuppressWarnings("serial") // Same-version serialization only public class ListDataHandler implements ListDataListener { /** @@ -1842,7 +1839,6 @@ protected ListDataListener createListDataListener() { * @see #createPropertyChangeListener * @see #installUI */ - @SuppressWarnings("serial") // Same-version serialization only public class PropertyChangeHandler implements PropertyChangeListener { /** @@ -2653,9 +2649,7 @@ public void propertyChange(PropertyChangeEvent e) { * listDataListener from the old model and add it to the new one. */ if (propertyName == "model") { - @SuppressWarnings("unchecked") ListModel<?> oldModel = (ListModel)e.getOldValue(); - @SuppressWarnings("unchecked") ListModel<?> newModel = (ListModel)e.getNewValue(); if (oldModel != null) { oldModel.removeListDataListener(listDataListener); diff --git a/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicOptionPaneUI.java b/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicOptionPaneUI.java index 82547a4e036..2e61967031c 100644 --- a/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicOptionPaneUI.java +++ b/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicOptionPaneUI.java @@ -482,7 +482,6 @@ protected void addMessageComponents(Container container, if (nl >= 0) { // break up newlines if (nl == 0) { - @SuppressWarnings("serial") // anonymous class JPanel breakPanel = new JPanel() { public Dimension getPreferredSize() { Font f = getFont(); diff --git a/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicSplitPaneDivider.java b/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicSplitPaneDivider.java index 119e12276c7..cd59bf8433b 100644 --- a/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicSplitPaneDivider.java +++ b/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicSplitPaneDivider.java @@ -746,7 +746,6 @@ public void mouseExited(MouseEvent e) { * has been added to the <code>java.beans</code> package. * Please see {@link java.beans.XMLEncoder}. */ - @SuppressWarnings("serial") // Same-version serialization only protected class DragController { /** diff --git a/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicSplitPaneUI.java b/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicSplitPaneUI.java index 31d20ab7b93..5ff68f78d38 100644 --- a/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicSplitPaneUI.java +++ b/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicSplitPaneUI.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -899,7 +899,6 @@ public BasicSplitPaneDivider getDivider() { * * @return the default non continuous layout divider */ - @SuppressWarnings("serial") // anonymous class protected Component createDefaultNonContinuousLayoutDivider() { return new Canvas() { public void paint(Graphics g) { diff --git a/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicTextAreaUI.java b/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicTextAreaUI.java index 2f5f86f872a..1d7128b7ac9 100644 --- a/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicTextAreaUI.java +++ b/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicTextAreaUI.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -49,7 +49,6 @@ * * @author Timothy Prinzing */ -@SuppressWarnings("serial") // Same-version serialization only public class BasicTextAreaUI extends BasicTextUI { /** diff --git a/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicTextFieldUI.java b/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicTextFieldUI.java index f3795336207..35c1d0e30b5 100644 --- a/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicTextFieldUI.java +++ b/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicTextFieldUI.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -51,7 +51,6 @@ * * @author Timothy Prinzing */ -@SuppressWarnings("serial") // Same-version serialization only public class BasicTextFieldUI extends BasicTextUI { /** diff --git a/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicTextPaneUI.java b/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicTextPaneUI.java index a76308dbec6..bf1587f826c 100644 --- a/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicTextPaneUI.java +++ b/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicTextPaneUI.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -47,7 +47,6 @@ * * @author Timothy Prinzing */ -@SuppressWarnings("serial") // Same-version serialization only public class BasicTextPaneUI extends BasicEditorPaneUI { /** diff --git a/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicToolBarUI.java b/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicToolBarUI.java index e0e1a2e5ed6..41ab6137976 100644 --- a/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicToolBarUI.java +++ b/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicToolBarUI.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -554,13 +554,11 @@ private Border createNonRolloverToggleBorder() { @Deprecated(since = "17", forRemoval = true) protected JFrame createFloatingFrame(JToolBar toolbar) { Window window = SwingUtilities.getWindowAncestor(toolbar); - @SuppressWarnings("serial") // anonymous class JFrame frame = new JFrame(toolbar.getName(), (window != null) ? window.getGraphicsConfiguration() : null) { // Override createRootPane() to automatically resize // the frame when contents change protected JRootPane createRootPane() { - @SuppressWarnings("serial") // anonymous class JRootPane rootPane = new JRootPane() { private boolean packing = false; @@ -606,7 +604,6 @@ public ToolBarDialog(Dialog owner, String title, boolean modal) { // Override createRootPane() to automatically resize // the frame when contents change protected JRootPane createRootPane() { - @SuppressWarnings("serial") // anonymous class JRootPane rootPane = new JRootPane() { private boolean packing = false; diff --git a/src/java.desktop/share/classes/javax/swing/plaf/basic/ComboPopup.java b/src/java.desktop/share/classes/javax/swing/plaf/basic/ComboPopup.java index 122db235334..71865b4f19f 100644 --- a/src/java.desktop/share/classes/javax/swing/plaf/basic/ComboPopup.java +++ b/src/java.desktop/share/classes/javax/swing/plaf/basic/ComboPopup.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -46,7 +46,6 @@ * * @author Tom Santos */ -@SuppressWarnings("serial") // Same-version serialization only public interface ComboPopup { /** * Shows the popup diff --git a/src/java.desktop/share/classes/javax/swing/plaf/metal/DefaultMetalTheme.java b/src/java.desktop/share/classes/javax/swing/plaf/metal/DefaultMetalTheme.java index 3b9c79a8a9a..8ee862fb0b3 100644 --- a/src/java.desktop/share/classes/javax/swing/plaf/metal/DefaultMetalTheme.java +++ b/src/java.desktop/share/classes/javax/swing/plaf/metal/DefaultMetalTheme.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -87,7 +87,6 @@ * * @author Steve Wilson */ -@SuppressWarnings("serial") // Same-version serialization only public class DefaultMetalTheme extends MetalTheme { /** * Whether or not fonts should be plain. This is only used if diff --git a/src/java.desktop/share/classes/javax/swing/plaf/metal/MetalButtonUI.java b/src/java.desktop/share/classes/javax/swing/plaf/metal/MetalButtonUI.java index 2a0b1928fb7..0bbbab7b45f 100644 --- a/src/java.desktop/share/classes/javax/swing/plaf/metal/MetalButtonUI.java +++ b/src/java.desktop/share/classes/javax/swing/plaf/metal/MetalButtonUI.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -50,7 +50,6 @@ * * @author Tom Santos */ -@SuppressWarnings("serial") // Same-version serialization only public class MetalButtonUI extends BasicButtonUI { // NOTE: These are not really needed, but at this point we can't pull diff --git a/src/java.desktop/share/classes/javax/swing/plaf/metal/MetalCheckBoxUI.java b/src/java.desktop/share/classes/javax/swing/plaf/metal/MetalCheckBoxUI.java index 0470d15718a..558f1987e4d 100644 --- a/src/java.desktop/share/classes/javax/swing/plaf/metal/MetalCheckBoxUI.java +++ b/src/java.desktop/share/classes/javax/swing/plaf/metal/MetalCheckBoxUI.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -51,7 +51,6 @@ * @author Michael C. Albers * */ -@SuppressWarnings("serial") // Same-version serialization only public class MetalCheckBoxUI extends MetalRadioButtonUI { // NOTE: MetalCheckBoxUI inherits from MetalRadioButtonUI instead diff --git a/src/java.desktop/share/classes/javax/swing/plaf/metal/MetalComboBoxEditor.java b/src/java.desktop/share/classes/javax/swing/plaf/metal/MetalComboBoxEditor.java index 6765e034452..bac9a821a75 100644 --- a/src/java.desktop/share/classes/javax/swing/plaf/metal/MetalComboBoxEditor.java +++ b/src/java.desktop/share/classes/javax/swing/plaf/metal/MetalComboBoxEditor.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -135,7 +135,6 @@ public Insets getBorderInsets(Component c, Insets insets) { * has been added to the <code>java.beans</code> package. * Please see {@link java.beans.XMLEncoder}. */ - @SuppressWarnings("serial") // Same-version serialization only public static class UIResource extends MetalComboBoxEditor implements javax.swing.plaf.UIResource { /** diff --git a/src/java.desktop/share/classes/javax/swing/plaf/metal/MetalFileChooserUI.java b/src/java.desktop/share/classes/javax/swing/plaf/metal/MetalFileChooserUI.java index 23803dafde9..a7b8718ca8d 100644 --- a/src/java.desktop/share/classes/javax/swing/plaf/metal/MetalFileChooserUI.java +++ b/src/java.desktop/share/classes/javax/swing/plaf/metal/MetalFileChooserUI.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -238,7 +238,6 @@ public void installComponents(JFileChooser fc) { topPanel.add(lookInLabel, BorderLayout.BEFORE_LINE_BEGINS); // CurrentDir ComboBox - @SuppressWarnings("serial") // anonymous class JComboBox<Object> tmp1 = new JComboBox<Object>() { public Dimension getPreferredSize() { Dimension d = super.getPreferredSize(); @@ -381,7 +380,6 @@ public void propertyChange(PropertyChangeEvent e) { populateFileNameLabel(); fileNamePanel.add(fileNameLabel); - @SuppressWarnings("serial") // anonymous class JTextField tmp2 = new JTextField(35) { public Dimension getMaximumSize() { return new Dimension(Short.MAX_VALUE, super.getPreferredSize().height); diff --git a/src/java.desktop/share/classes/javax/swing/plaf/metal/MetalProgressBarUI.java b/src/java.desktop/share/classes/javax/swing/plaf/metal/MetalProgressBarUI.java index 5f316cbb209..b5dddfc1274 100644 --- a/src/java.desktop/share/classes/javax/swing/plaf/metal/MetalProgressBarUI.java +++ b/src/java.desktop/share/classes/javax/swing/plaf/metal/MetalProgressBarUI.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -44,7 +44,6 @@ * * @author Michael C. Albers */ -@SuppressWarnings("serial") // Same-version serialization only public class MetalProgressBarUI extends BasicProgressBarUI { private Rectangle innards; diff --git a/src/java.desktop/share/classes/javax/swing/plaf/metal/MetalRadioButtonUI.java b/src/java.desktop/share/classes/javax/swing/plaf/metal/MetalRadioButtonUI.java index 8bd1f9acc0a..712046737eb 100644 --- a/src/java.desktop/share/classes/javax/swing/plaf/metal/MetalRadioButtonUI.java +++ b/src/java.desktop/share/classes/javax/swing/plaf/metal/MetalRadioButtonUI.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -53,7 +53,6 @@ * @author Michael C. Albers (Metal modifications) * @author Jeff Dinkins (original BasicRadioButtonCode) */ -@SuppressWarnings("serial") // Same-version serialization only public class MetalRadioButtonUI extends BasicRadioButtonUI { private static final Object METAL_RADIO_BUTTON_UI_KEY = new Object(); diff --git a/src/java.desktop/share/classes/javax/swing/plaf/metal/MetalRootPaneUI.java b/src/java.desktop/share/classes/javax/swing/plaf/metal/MetalRootPaneUI.java index 81ea2fe28ee..b243c5ca472 100644 --- a/src/java.desktop/share/classes/javax/swing/plaf/metal/MetalRootPaneUI.java +++ b/src/java.desktop/share/classes/javax/swing/plaf/metal/MetalRootPaneUI.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -77,7 +77,6 @@ * @author Terry Kellerman * @since 1.4 */ -@SuppressWarnings("serial") // Same-version serialization only public class MetalRootPaneUI extends BasicRootPaneUI { /** diff --git a/src/java.desktop/share/classes/javax/swing/plaf/metal/MetalScrollPaneUI.java b/src/java.desktop/share/classes/javax/swing/plaf/metal/MetalScrollPaneUI.java index e90d8657ae5..e94edc28b65 100644 --- a/src/java.desktop/share/classes/javax/swing/plaf/metal/MetalScrollPaneUI.java +++ b/src/java.desktop/share/classes/javax/swing/plaf/metal/MetalScrollPaneUI.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -50,7 +50,6 @@ * * @author Steve Wilson */ -@SuppressWarnings("serial") // Same-version serialization only public class MetalScrollPaneUI extends BasicScrollPaneUI { diff --git a/src/java.desktop/share/classes/javax/swing/plaf/metal/MetalSeparatorUI.java b/src/java.desktop/share/classes/javax/swing/plaf/metal/MetalSeparatorUI.java index 9140577b895..fe8a45aa979 100644 --- a/src/java.desktop/share/classes/javax/swing/plaf/metal/MetalSeparatorUI.java +++ b/src/java.desktop/share/classes/javax/swing/plaf/metal/MetalSeparatorUI.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -50,7 +50,6 @@ * * @author Jeff Shapiro */ -@SuppressWarnings("serial") // Same-version serialization only public class MetalSeparatorUI extends BasicSeparatorUI { /** diff --git a/src/java.desktop/share/classes/javax/swing/plaf/metal/MetalSliderUI.java b/src/java.desktop/share/classes/javax/swing/plaf/metal/MetalSliderUI.java index 03133596822..c31ee81c729 100644 --- a/src/java.desktop/share/classes/javax/swing/plaf/metal/MetalSliderUI.java +++ b/src/java.desktop/share/classes/javax/swing/plaf/metal/MetalSliderUI.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -50,7 +50,6 @@ * * @author Tom Santos */ -@SuppressWarnings("serial") // Same-version serialization only public class MetalSliderUI extends BasicSliderUI { /** diff --git a/src/java.desktop/share/classes/javax/swing/plaf/metal/MetalSplitPaneUI.java b/src/java.desktop/share/classes/javax/swing/plaf/metal/MetalSplitPaneUI.java index ee888771ff2..aba58db389b 100644 --- a/src/java.desktop/share/classes/javax/swing/plaf/metal/MetalSplitPaneUI.java +++ b/src/java.desktop/share/classes/javax/swing/plaf/metal/MetalSplitPaneUI.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -43,7 +43,6 @@ * * @author Steve Wilson */ -@SuppressWarnings("serial") // Same-version serialization only public class MetalSplitPaneUI extends BasicSplitPaneUI { /** diff --git a/src/java.desktop/share/classes/javax/swing/plaf/metal/MetalTabbedPaneUI.java b/src/java.desktop/share/classes/javax/swing/plaf/metal/MetalTabbedPaneUI.java index d73ef0d6613..8f9229d4cbd 100644 --- a/src/java.desktop/share/classes/javax/swing/plaf/metal/MetalTabbedPaneUI.java +++ b/src/java.desktop/share/classes/javax/swing/plaf/metal/MetalTabbedPaneUI.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -47,7 +47,6 @@ * * @author Tom Santos */ -@SuppressWarnings("serial") // Same-version serialization only public class MetalTabbedPaneUI extends BasicTabbedPaneUI { /** diff --git a/src/java.desktop/share/classes/javax/swing/plaf/metal/MetalTextFieldUI.java b/src/java.desktop/share/classes/javax/swing/plaf/metal/MetalTextFieldUI.java index 9a59f99fdce..e7bbc0baf69 100644 --- a/src/java.desktop/share/classes/javax/swing/plaf/metal/MetalTextFieldUI.java +++ b/src/java.desktop/share/classes/javax/swing/plaf/metal/MetalTextFieldUI.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -47,7 +47,6 @@ * * @author Steve Wilson */ -@SuppressWarnings("serial") // Same-version serialization only public class MetalTextFieldUI extends BasicTextFieldUI { /** diff --git a/src/java.desktop/share/classes/javax/swing/plaf/metal/MetalToggleButtonUI.java b/src/java.desktop/share/classes/javax/swing/plaf/metal/MetalToggleButtonUI.java index 325f30f7e0a..088a54ba6b2 100644 --- a/src/java.desktop/share/classes/javax/swing/plaf/metal/MetalToggleButtonUI.java +++ b/src/java.desktop/share/classes/javax/swing/plaf/metal/MetalToggleButtonUI.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -55,7 +55,6 @@ * * @author Tom Santos */ -@SuppressWarnings("serial") // Same-version serialization only public class MetalToggleButtonUI extends BasicToggleButtonUI { private static final Object METAL_TOGGLE_BUTTON_UI_KEY = new Object(); diff --git a/src/java.desktop/share/classes/javax/swing/plaf/metal/MetalToolTipUI.java b/src/java.desktop/share/classes/javax/swing/plaf/metal/MetalToolTipUI.java index 6cf5314b4a0..258a37b8dbb 100644 --- a/src/java.desktop/share/classes/javax/swing/plaf/metal/MetalToolTipUI.java +++ b/src/java.desktop/share/classes/javax/swing/plaf/metal/MetalToolTipUI.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -49,7 +49,6 @@ * * @author Steve Wilson */ -@SuppressWarnings("serial") // Same-version serialization only public class MetalToolTipUI extends BasicToolTipUI { static MetalToolTipUI sharedInstance = new MetalToolTipUI(); diff --git a/src/java.desktop/share/classes/javax/swing/plaf/metal/MetalUtils.java b/src/java.desktop/share/classes/javax/swing/plaf/metal/MetalUtils.java index 5ed2cd9b5ce..79902886848 100644 --- a/src/java.desktop/share/classes/javax/swing/plaf/metal/MetalUtils.java +++ b/src/java.desktop/share/classes/javax/swing/plaf/metal/MetalUtils.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -210,7 +210,6 @@ static int getInt(Object key, int defaultValue) { */ static boolean drawGradient(Component c, Graphics g, String key, int x, int y, int w, int h, boolean vertical) { - @SuppressWarnings("unchecked") java.util.List<?> gradient = (java.util.List)UIManager.get(key); if (gradient == null || !(g instanceof Graphics2D)) { return false; @@ -275,7 +274,6 @@ public void paint(Component c, Graphics2D g, protected void paintToImage(Component c, Image image, Graphics g, int w, int h, Object[] args) { Graphics2D g2 = (Graphics2D)g; - @SuppressWarnings("unchecked") java.util.List<?> gradient = (java.util.List)args[0]; boolean isVertical = ((Boolean)args[1]).booleanValue(); // Render to the VolatileImage diff --git a/src/java.desktop/share/classes/javax/swing/plaf/multi/MultiLookAndFeel.java b/src/java.desktop/share/classes/javax/swing/plaf/multi/MultiLookAndFeel.java index 3862a5ab871..a2d3edd659d 100644 --- a/src/java.desktop/share/classes/javax/swing/plaf/multi/MultiLookAndFeel.java +++ b/src/java.desktop/share/classes/javax/swing/plaf/multi/MultiLookAndFeel.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -56,7 +56,6 @@ * * @author Willie Walker */ -@SuppressWarnings("serial") // Same-version serialization only public class MultiLookAndFeel extends LookAndFeel { /** diff --git a/src/java.desktop/share/classes/javax/swing/plaf/synth/SynthDesktopIconUI.java b/src/java.desktop/share/classes/javax/swing/plaf/synth/SynthDesktopIconUI.java index 0b82788032e..23e6e8ec4a3 100644 --- a/src/java.desktop/share/classes/javax/swing/plaf/synth/SynthDesktopIconUI.java +++ b/src/java.desktop/share/classes/javax/swing/plaf/synth/SynthDesktopIconUI.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -76,7 +76,6 @@ public static ComponentUI createUI(JComponent c) { @Override protected void installComponents() { if (UIManager.getBoolean("InternalFrame.useTaskBar")) { - @SuppressWarnings("serial") // anonymous class JToggleButton tmp = new JToggleButton(frame.getTitle(), frame.getFrameIcon()) { @Override public String getToolTipText() { return getText(); diff --git a/src/java.desktop/share/classes/javax/swing/plaf/synth/SynthScrollBarUI.java b/src/java.desktop/share/classes/javax/swing/plaf/synth/SynthScrollBarUI.java index 52ab14a359f..f8bf123ca89 100644 --- a/src/java.desktop/share/classes/javax/swing/plaf/synth/SynthScrollBarUI.java +++ b/src/java.desktop/share/classes/javax/swing/plaf/synth/SynthScrollBarUI.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -376,7 +376,6 @@ protected Dimension getMinimumThumbSize() { */ @Override protected JButton createDecreaseButton(int orientation) { - @SuppressWarnings("serial") // anonymous class SynthArrowButton synthArrowButton = new SynthArrowButton(orientation) { @Override public boolean contains(int x, int y) { @@ -406,7 +405,6 @@ public boolean contains(int x, int y) { */ @Override protected JButton createIncreaseButton(int orientation) { - @SuppressWarnings("serial") // anonymous class SynthArrowButton synthArrowButton = new SynthArrowButton(orientation) { @Override public boolean contains(int x, int y) { diff --git a/src/java.desktop/share/classes/javax/swing/plaf/synth/SynthSplitPaneUI.java b/src/java.desktop/share/classes/javax/swing/plaf/synth/SynthSplitPaneUI.java index 49a9689409f..4ac76dec282 100644 --- a/src/java.desktop/share/classes/javax/swing/plaf/synth/SynthSplitPaneUI.java +++ b/src/java.desktop/share/classes/javax/swing/plaf/synth/SynthSplitPaneUI.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -277,7 +277,6 @@ private void setDividerDraggingColor(Graphics g, int loc) { * {@inheritDoc} */ @Override - @SuppressWarnings("serial") // anonymous class protected Component createDefaultNonContinuousLayoutDivider() { return new Canvas() { public void paint(Graphics g) { diff --git a/src/java.desktop/share/classes/javax/swing/plaf/synth/SynthTextAreaUI.java b/src/java.desktop/share/classes/javax/swing/plaf/synth/SynthTextAreaUI.java index 3d4c41d9677..956a4ee2fcc 100644 --- a/src/java.desktop/share/classes/javax/swing/plaf/synth/SynthTextAreaUI.java +++ b/src/java.desktop/share/classes/javax/swing/plaf/synth/SynthTextAreaUI.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -51,7 +51,6 @@ * @author Shannon Hickey * @since 1.7 */ -@SuppressWarnings("serial") // Same-version serialization only public class SynthTextAreaUI extends BasicTextAreaUI implements SynthUI { private Handler handler = new Handler(); private SynthStyle style; diff --git a/src/java.desktop/share/classes/javax/swing/plaf/synth/SynthTextFieldUI.java b/src/java.desktop/share/classes/javax/swing/plaf/synth/SynthTextFieldUI.java index 61fd591d9af..02ab78d14e8 100644 --- a/src/java.desktop/share/classes/javax/swing/plaf/synth/SynthTextFieldUI.java +++ b/src/java.desktop/share/classes/javax/swing/plaf/synth/SynthTextFieldUI.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -50,7 +50,6 @@ * @author Shannon Hickey * @since 1.7 */ -@SuppressWarnings("serial") // Same-version serialization only public class SynthTextFieldUI extends BasicTextFieldUI implements SynthUI { private Handler handler = new Handler(); private SynthStyle style; diff --git a/src/java.desktop/share/classes/javax/swing/plaf/synth/SynthTextPaneUI.java b/src/java.desktop/share/classes/javax/swing/plaf/synth/SynthTextPaneUI.java index 4aa5567aa26..c966b979e32 100644 --- a/src/java.desktop/share/classes/javax/swing/plaf/synth/SynthTextPaneUI.java +++ b/src/java.desktop/share/classes/javax/swing/plaf/synth/SynthTextPaneUI.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -47,7 +47,6 @@ * @author Shannon Hickey * @since 1.7 */ -@SuppressWarnings("serial") // Same-version serialization only public class SynthTextPaneUI extends SynthEditorPaneUI { /** diff --git a/src/java.desktop/share/classes/javax/swing/plaf/synth/SynthTreeUI.java b/src/java.desktop/share/classes/javax/swing/plaf/synth/SynthTreeUI.java index f9d0d6eb1fa..0e9caf3ebd8 100644 --- a/src/java.desktop/share/classes/javax/swing/plaf/synth/SynthTreeUI.java +++ b/src/java.desktop/share/classes/javax/swing/plaf/synth/SynthTreeUI.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -771,7 +771,6 @@ public SynthTreeCellEditor(JTree tree, @Override protected TreeCellEditor createTreeCellEditor() { - @SuppressWarnings("serial") // anonymous class JTextField tf = new JTextField() { @Override public String getName() { diff --git a/src/java.desktop/share/classes/javax/swing/text/DefaultStyledDocument.java b/src/java.desktop/share/classes/javax/swing/text/DefaultStyledDocument.java index 60ca2d72634..757eccfcd53 100644 --- a/src/java.desktop/share/classes/javax/swing/text/DefaultStyledDocument.java +++ b/src/java.desktop/share/classes/javax/swing/text/DefaultStyledDocument.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -1182,7 +1182,6 @@ public String getName() { * has been added to the <code>java.beans</code> package. * Please see {@link java.beans.XMLEncoder}. */ - @SuppressWarnings("serial") // Same-version serialization only public static class ElementSpec { /** diff --git a/src/java.desktop/share/classes/javax/swing/text/JTextComponent.java b/src/java.desktop/share/classes/javax/swing/text/JTextComponent.java index ce36a5d5a1f..03e04d1c1a7 100644 --- a/src/java.desktop/share/classes/javax/swing/text/JTextComponent.java +++ b/src/java.desktop/share/classes/javax/swing/text/JTextComponent.java @@ -1127,7 +1127,6 @@ private static HashMap<String,Keymap> getKeymapTable() { * has been added to the <code>java.beans</code> package. * Please see {@link java.beans.XMLEncoder}. */ - @SuppressWarnings("serial") // Same-version serialization only public static class KeyBinding { /** @@ -3951,7 +3950,6 @@ public String toString() { * Maps from class name to Boolean indicating if * <code>processInputMethodEvent</code> has been overridden. */ - @SuppressWarnings("removal") private static Cache<Class<?>,Boolean> METHOD_OVERRIDDEN = new Cache<Class<?>,Boolean>(Cache.Kind.WEAK, Cache.Kind.STRONG) { /** diff --git a/src/java.desktop/share/classes/javax/swing/text/SimpleAttributeSet.java b/src/java.desktop/share/classes/javax/swing/text/SimpleAttributeSet.java index 30a47c02a1f..ad6afb14092 100644 --- a/src/java.desktop/share/classes/javax/swing/text/SimpleAttributeSet.java +++ b/src/java.desktop/share/classes/javax/swing/text/SimpleAttributeSet.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -48,7 +48,6 @@ * * @author Tim Prinzing */ -@SuppressWarnings("serial") // Same-version serialization only public class SimpleAttributeSet implements MutableAttributeSet, Serializable, Cloneable { /** diff --git a/src/java.desktop/share/classes/javax/swing/text/StyledEditorKit.java b/src/java.desktop/share/classes/javax/swing/text/StyledEditorKit.java index e2630c93623..636196de69c 100644 --- a/src/java.desktop/share/classes/javax/swing/text/StyledEditorKit.java +++ b/src/java.desktop/share/classes/javax/swing/text/StyledEditorKit.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -171,7 +171,6 @@ public Object clone() { /** * Creates the AttributeSet used for the selection. */ - @SuppressWarnings("serial") // anonymous class private void createInputAttributes() { inputAttributes = new SimpleAttributeSet() { public AttributeSet getResolveParent() { diff --git a/src/java.desktop/share/classes/javax/swing/text/WrappedPlainView.java b/src/java.desktop/share/classes/javax/swing/text/WrappedPlainView.java index 8d6980eaaea..0bceae3acee 100644 --- a/src/java.desktop/share/classes/javax/swing/text/WrappedPlainView.java +++ b/src/java.desktop/share/classes/javax/swing/text/WrappedPlainView.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -352,7 +352,6 @@ protected final Segment getLineBuffer() { * @param p1 the ending document location to use * @return the break position */ - @SuppressWarnings("deprecation") protected int calculateBreakPosition(int p0, int p1) { int p; Segment segment = SegmentCache.getSharedSegment(); @@ -798,7 +797,6 @@ public Shape modelToView(int pos, Shape a, Position.Bias b) * given point in the view * @see View#viewToModel */ - @SuppressWarnings("deprecation") public int viewToModel(float fx, float fy, Shape a, Position.Bias[] bias) { // PENDING(prinz) implement bias properly bias[0] = Position.Bias.Forward; diff --git a/src/java.desktop/share/classes/javax/swing/text/html/FormView.java b/src/java.desktop/share/classes/javax/swing/text/html/FormView.java index 8af4f9e2f1e..47f10e1abb2 100644 --- a/src/java.desktop/share/classes/javax/swing/text/html/FormView.java +++ b/src/java.desktop/share/classes/javax/swing/text/html/FormView.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -382,7 +382,6 @@ private void removeStaleListenerForModel(Object model) { // BasicListUI$Handler. // For JComboBox, there are 2 stale ListDataListeners, which are // BasicListUI$Handler and BasicComboBoxUI$Handler. - @SuppressWarnings("unchecked") AbstractListModel<?> listModel = (AbstractListModel) model; String listenerClass1 = "javax.swing.plaf.basic.BasicListUI$Handler"; @@ -850,7 +849,6 @@ private void loadSelectData(AttributeSet attr, StringBuilder buffer) { } } } else if (m instanceof ComboBoxModel) { - @SuppressWarnings("unchecked") ComboBoxModel<?> model = (ComboBoxModel)m; Option option = (Option)model.getSelectedItem(); if (option != null) { @@ -962,7 +960,6 @@ void resetForm() { } catch (BadLocationException e) { } } else if (m instanceof OptionListModel) { - @SuppressWarnings("unchecked") OptionListModel<?> model = (OptionListModel) m; int size = model.getSize(); for (int i = 0; i < size; i++) { @@ -975,7 +972,6 @@ void resetForm() { } } } else if (m instanceof OptionComboBoxModel) { - @SuppressWarnings("unchecked") OptionComboBoxModel<?> model = (OptionComboBoxModel) m; Option option = model.getInitialSelection(); if (option != null) { diff --git a/src/java.desktop/share/classes/javax/swing/tree/AbstractLayoutCache.java b/src/java.desktop/share/classes/javax/swing/tree/AbstractLayoutCache.java index d3435231e7f..97383785dca 100644 --- a/src/java.desktop/share/classes/javax/swing/tree/AbstractLayoutCache.java +++ b/src/java.desktop/share/classes/javax/swing/tree/AbstractLayoutCache.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -41,7 +41,6 @@ * * @author Scott Violet */ -@SuppressWarnings("serial") // Same-version serialization only public abstract class AbstractLayoutCache implements RowMapper { /** Object responsible for getting the size of a node. */ protected NodeDimensions nodeDimensions; diff --git a/src/java.desktop/share/classes/javax/swing/tree/DefaultTreeCellEditor.java b/src/java.desktop/share/classes/javax/swing/tree/DefaultTreeCellEditor.java index 2397f51f7a6..4662c95c01f 100644 --- a/src/java.desktop/share/classes/javax/swing/tree/DefaultTreeCellEditor.java +++ b/src/java.desktop/share/classes/javax/swing/tree/DefaultTreeCellEditor.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -537,7 +537,6 @@ protected Container createContainer() { */ protected TreeCellEditor createTreeCellEditor() { Border aBorder = UIManager.getBorder("Tree.editorBorder"); - @SuppressWarnings("serial") // Safe: outer class is non-serializable DefaultCellEditor editor = new DefaultCellEditor (new DefaultTextField(aBorder)) { public boolean shouldSelectCell(EventObject event) { diff --git a/src/java.desktop/share/classes/sun/awt/AWTAutoShutdown.java b/src/java.desktop/share/classes/sun/awt/AWTAutoShutdown.java index e944d19e1c1..5a81de507db 100644 --- a/src/java.desktop/share/classes/sun/awt/AWTAutoShutdown.java +++ b/src/java.desktop/share/classes/sun/awt/AWTAutoShutdown.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -321,7 +321,6 @@ public void run() { } } - @SuppressWarnings("serial") static AWTEvent getShutdownEvent() { return new AWTEvent(getInstance(), 0) { }; diff --git a/src/java.desktop/share/classes/sun/awt/AppContext.java b/src/java.desktop/share/classes/sun/awt/AppContext.java index 48482dfc39a..a35d89f6a0c 100644 --- a/src/java.desktop/share/classes/sun/awt/AppContext.java +++ b/src/java.desktop/share/classes/sun/awt/AppContext.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -362,7 +362,6 @@ public static boolean isMainContext(AppContext ctx) { * contained within this AppContext * @since 1.2 */ - @SuppressWarnings("deprecation") public void dispose() throws IllegalThreadStateException { System.err.println( """ diff --git a/src/java.desktop/share/classes/sun/awt/CausedFocusEvent.java b/src/java.desktop/share/classes/sun/awt/CausedFocusEvent.java index 2527eda11f6..a6293d4efea 100644 --- a/src/java.desktop/share/classes/sun/awt/CausedFocusEvent.java +++ b/src/java.desktop/share/classes/sun/awt/CausedFocusEvent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -59,7 +59,6 @@ private enum Cause { RETARGETED } - @SuppressWarnings("serial") private static final Component dummy = new Component(){}; private final Cause cause; diff --git a/src/java.desktop/share/classes/sun/awt/KeyboardFocusManagerPeerImpl.java b/src/java.desktop/share/classes/sun/awt/KeyboardFocusManagerPeerImpl.java index 86b957398f7..ef50d883ee5 100644 --- a/src/java.desktop/share/classes/sun/awt/KeyboardFocusManagerPeerImpl.java +++ b/src/java.desktop/share/classes/sun/awt/KeyboardFocusManagerPeerImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -104,7 +104,6 @@ public static boolean shouldFocusOnClick(Component component) { /* * Posts proper lost/gain focus events to the event queue. */ - @SuppressWarnings("deprecation") public static boolean deliverFocus(Component lightweightChild, Component target, boolean temporary, diff --git a/src/java.desktop/share/classes/sun/awt/LightweightFrame.java b/src/java.desktop/share/classes/sun/awt/LightweightFrame.java index cd1cdf3ebd5..205b8034b7e 100644 --- a/src/java.desktop/share/classes/sun/awt/LightweightFrame.java +++ b/src/java.desktop/share/classes/sun/awt/LightweightFrame.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -88,7 +88,6 @@ public LightweightFrame() { @Override public final void toFront() {} @Override public final void toBack() {} - @SuppressWarnings("deprecation") @Override public void addNotify() { synchronized (getTreeLock()) { if (!isDisplayable()) { diff --git a/src/java.desktop/share/classes/sun/awt/SunToolkit.java b/src/java.desktop/share/classes/sun/awt/SunToolkit.java index 355ee995c8c..5c4ebda8715 100644 --- a/src/java.desktop/share/classes/sun/awt/SunToolkit.java +++ b/src/java.desktop/share/classes/sun/awt/SunToolkit.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -525,7 +525,6 @@ public static void executeOnEventHandlerThread(Object target, * Fixed 5064013: the InvocationEvent time should be equals * the time of the ActionEvent */ - @SuppressWarnings("serial") public static void executeOnEventHandlerThread(Object target, Runnable runnable, final long when) { @@ -1569,7 +1568,6 @@ private boolean isEQEmpty() { * Should return {@code true} if more processing is * necessary, {@code false} otherwise. */ - @SuppressWarnings("serial") private final boolean waitForIdle(final long end) { if (timeout(end) <= 0) { return false; diff --git a/src/java.desktop/share/classes/sun/java2d/Disposer.java b/src/java.desktop/share/classes/sun/java2d/Disposer.java index 5a80a616045..5692b490278 100644 --- a/src/java.desktop/share/classes/sun/java2d/Disposer.java +++ b/src/java.desktop/share/classes/sun/java2d/Disposer.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -241,7 +241,6 @@ public static void pollRemove() { * so will clutter the records hashmap and no one will be cleaning up * the reference queue. */ - @SuppressWarnings("unchecked") public static void addReference(Reference<Object> ref, DisposerRecord rec) { records.put(ref, rec); } diff --git a/src/java.desktop/share/classes/sun/java2d/marlin/DMarlinRenderingEngine.java b/src/java.desktop/share/classes/sun/java2d/marlin/DMarlinRenderingEngine.java index a42e474e764..b29cc84c127 100644 --- a/src/java.desktop/share/classes/sun/java2d/marlin/DMarlinRenderingEngine.java +++ b/src/java.desktop/share/classes/sun/java2d/marlin/DMarlinRenderingEngine.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -1300,7 +1300,6 @@ private static void logSettings(final String reClass) { * Get the RendererContext instance dedicated to the current thread * @return RendererContext instance */ - @SuppressWarnings({"unchecked"}) static RendererContext getRendererContext() { final RendererContext rdrCtx = RDR_CTX_PROVIDER.acquire(); if (DO_MONITORS) { diff --git a/src/java.desktop/share/classes/sun/print/ServiceDialog.java b/src/java.desktop/share/classes/sun/print/ServiceDialog.java index 6f2bdecb809..983be70bdbb 100644 --- a/src/java.desktop/share/classes/sun/print/ServiceDialog.java +++ b/src/java.desktop/share/classes/sun/print/ServiceDialog.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -296,7 +296,6 @@ public void windowClosing(WindowEvent event) { * Performs Cancel when Esc key is pressed. */ private void handleEscKey(JButton btnCancel) { - @SuppressWarnings("serial") // anonymous class Action cancelKeyAction = new AbstractAction() { public void actionPerformed(ActionEvent e) { dispose(CANCEL); diff --git a/src/java.desktop/share/classes/sun/swing/FilePane.java b/src/java.desktop/share/classes/sun/swing/FilePane.java index e97dcb3b881..395cf058b7d 100644 --- a/src/java.desktop/share/classes/sun/swing/FilePane.java +++ b/src/java.desktop/share/classes/sun/swing/FilePane.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -659,7 +659,6 @@ public JPanel createList() { JPanel p = new JPanel(new BorderLayout()); final JFileChooser fileChooser = getFileChooser(); - @SuppressWarnings("serial") // anonymous class final JList<Object> list = new JList<Object>() { public int getNextMatch(String prefix, int startIndex, Position.Bias bias) { ListModel<?> model = getModel(); @@ -1262,7 +1261,6 @@ public JPanel createDetailsView() { JPanel p = new JPanel(new BorderLayout()); - @SuppressWarnings("serial") // anonymous class final JTable detailsTable = new JTable(getDetailsTableModel()) { // Handle Escape key events here protected boolean processKeyBinding(KeyStroke ks, KeyEvent e, int condition, boolean pressed) { @@ -1575,7 +1573,6 @@ private void applyEdit() { protected Action newFolderAction; - @SuppressWarnings("serial") // anonymous class inside public Action getNewFolderAction() { if (!readOnly && newFolderAction == null) { newFolderAction = new AbstractAction(newFolderActionLabelText) { diff --git a/src/java.desktop/share/classes/sun/swing/JLightweightFrame.java b/src/java.desktop/share/classes/sun/swing/JLightweightFrame.java index cfc5ceef6c3..d83b940a0bd 100644 --- a/src/java.desktop/share/classes/sun/swing/JLightweightFrame.java +++ b/src/java.desktop/share/classes/sun/swing/JLightweightFrame.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -331,7 +331,7 @@ private void notifyImageUpdated(int x, int y, int width, int height) { content.imageUpdated(x, y, width, height); } - @SuppressWarnings({"removal","serial"}) // anonymous class inside + @SuppressWarnings("removal") private void initInterior() { contentPane = new JPanel() { @Override diff --git a/src/java.desktop/share/classes/sun/swing/LightweightContent.java b/src/java.desktop/share/classes/sun/swing/LightweightContent.java index eb283908e81..f67e3ad7fcf 100644 --- a/src/java.desktop/share/classes/sun/swing/LightweightContent.java +++ b/src/java.desktop/share/classes/sun/swing/LightweightContent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -161,7 +161,6 @@ default public void imageBufferReset(int[] data, * @param scaleY the y coordinate scale factor of the pixel buffer * @since 9 */ - @SuppressWarnings("deprecation") default public void imageBufferReset(int[] data, int x, int y, int width, int height, @@ -178,7 +177,6 @@ default public void imageBufferReset(int[] data, * default implementations in order to allow a client application to run * with any JDK version without breaking backward compatibility. */ - @SuppressWarnings("deprecation") default public void imageBufferReset(int[] data, int x, int y, int width, int height, diff --git a/src/java.desktop/share/classes/sun/swing/PrintingStatus.java b/src/java.desktop/share/classes/sun/swing/PrintingStatus.java index 1f7358a2881..b2fbed5222e 100644 --- a/src/java.desktop/share/classes/sun/swing/PrintingStatus.java +++ b/src/java.desktop/share/classes/sun/swing/PrintingStatus.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -62,7 +62,6 @@ public class PrintingStatus { private final AtomicBoolean isAborted = new AtomicBoolean(false); // the action that will abort printing - @SuppressWarnings("serial") // anonymous class private final Action abortAction = new AbstractAction() { public void actionPerformed(ActionEvent ae) { if (!isAborted.get()) { diff --git a/src/java.desktop/share/classes/sun/swing/plaf/synth/SynthFileChooserUIImpl.java b/src/java.desktop/share/classes/sun/swing/plaf/synth/SynthFileChooserUIImpl.java index 81789bcfdcf..c225ddc9ff6 100644 --- a/src/java.desktop/share/classes/sun/swing/plaf/synth/SynthFileChooserUIImpl.java +++ b/src/java.desktop/share/classes/sun/swing/plaf/synth/SynthFileChooserUIImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -188,7 +188,6 @@ protected void installDefaults(JFileChooser fc) { readOnly = UIManager.getBoolean("FileChooser.readOnly"); } - @SuppressWarnings("serial") // anonymous classes inside public void installComponents(JFileChooser fc) { super.installComponents(fc); diff --git a/src/java.desktop/share/classes/sun/swing/text/TextComponentPrintable.java b/src/java.desktop/share/classes/sun/swing/text/TextComponentPrintable.java index 28d57b02b63..f93c1673aca 100644 --- a/src/java.desktop/share/classes/sun/swing/text/TextComponentPrintable.java +++ b/src/java.desktop/share/classes/sun/swing/text/TextComponentPrintable.java @@ -332,7 +332,6 @@ public JTextComponent call() throws Exception { } } - @SuppressWarnings("serial") // anonymous class inside private JTextComponent createPrintShellOnEDT(final JTextComponent textComponent) { assert SwingUtilities.isEventDispatchThread(); From 189fc8ddeffb4dd595ccd8ad3ca53a0ed4cee91f Mon Sep 17 00:00:00 2001 From: Amit Kumar <amitkumar@openjdk.org> Date: Wed, 20 Nov 2024 08:25:37 +0000 Subject: [PATCH 117/311] 8344381: [s390x] Test failures with error: Register type is not known Reviewed-by: mdoerr, lucy --- .../gc/shared/barrierSetAssembler_s390.cpp | 34 ++++++++++++++----- 1 file changed, 26 insertions(+), 8 deletions(-) diff --git a/src/hotspot/cpu/s390/gc/shared/barrierSetAssembler_s390.cpp b/src/hotspot/cpu/s390/gc/shared/barrierSetAssembler_s390.cpp index d826b4a06f3..8ead8e8ff38 100644 --- a/src/hotspot/cpu/s390/gc/shared/barrierSetAssembler_s390.cpp +++ b/src/hotspot/cpu/s390/gc/shared/barrierSetAssembler_s390.cpp @@ -218,10 +218,10 @@ SaveLiveRegisters::SaveLiveRegisters(MacroAssembler *masm, BarrierStubC2 *stub) const int register_save_size = iterate_over_register_mask(ACTION_COUNT_ONLY) * BytesPerWord; - _frame_size = align_up(register_save_size, frame::alignment_in_bytes) + frame::z_abi_160_size; // FIXME: this could be restricted to argument only + _frame_size = align_up(register_save_size, frame::alignment_in_bytes) + frame::z_abi_160_size; __ save_return_pc(); - __ push_frame(_frame_size, Z_R14); // FIXME: check if Z_R1_scaratch can do a job here; + __ push_frame(_frame_size, Z_R14); __ z_lg(Z_R14, _z_common_abi(return_pc) + _frame_size, Z_SP); @@ -240,6 +240,7 @@ int SaveLiveRegisters::iterate_over_register_mask(IterationAction action, int of int reg_save_index = 0; RegMaskIterator live_regs_iterator(_reg_mask); + // Going to preserve the volatile registers which can be used by Register Allocator. while(live_regs_iterator.has_next()) { const OptoReg::Name opto_reg = live_regs_iterator.next(); @@ -251,8 +252,11 @@ int SaveLiveRegisters::iterate_over_register_mask(IterationAction action, int of const VMReg vm_reg = OptoReg::as_VMReg(opto_reg); if (vm_reg->is_Register()) { Register std_reg = vm_reg->as_Register(); - - if (std_reg->encoding() >= Z_R2->encoding() && std_reg->encoding() <= Z_R15->encoding()) { + // Z_R0 and Z_R1 will not be allocated by the register allocator, see s390.ad (Integer Register Classes) + // Z_R6 to Z_R15 are saved registers, except Z_R14 (see Z-Abi) + if (std_reg->encoding() == Z_R14->encoding() || + (std_reg->encoding() >= Z_R2->encoding() && + std_reg->encoding() <= Z_R5->encoding())) { reg_save_index++; if (action == ACTION_SAVE) { @@ -265,8 +269,10 @@ int SaveLiveRegisters::iterate_over_register_mask(IterationAction action, int of } } else if (vm_reg->is_FloatRegister()) { FloatRegister fp_reg = vm_reg->as_FloatRegister(); - if (fp_reg->encoding() >= Z_F0->encoding() && fp_reg->encoding() <= Z_F15->encoding() - && fp_reg->encoding() != Z_F1->encoding()) { + // Z_R1 will not be allocated by the register allocator, see s390.ad (Float Register Classes) + if (fp_reg->encoding() >= Z_F0->encoding() && + fp_reg->encoding() <= Z_F7->encoding() && + fp_reg->encoding() != Z_F1->encoding()) { reg_save_index++; if (action == ACTION_SAVE) { @@ -277,8 +283,20 @@ int SaveLiveRegisters::iterate_over_register_mask(IterationAction action, int of assert(action == ACTION_COUNT_ONLY, "Sanity"); } } - } else if (false /* vm_reg->is_VectorRegister() */){ - fatal("Vector register support is not there yet!"); + } else if (vm_reg->is_VectorRegister()) { + VectorRegister vs_reg = vm_reg->as_VectorRegister(); + // Z_V0 to Z_V15 will not be allocated by the register allocator, see s390.ad (reg class z_v_reg) + if (vs_reg->encoding() >= Z_V16->encoding() && + vs_reg->encoding() <= Z_V31->encoding()) { + reg_save_index += 2; + if (action == ACTION_SAVE) { + __ z_vst(vs_reg, Address(Z_SP, offset - reg_save_index * BytesPerWord)); + } else if (action == ACTION_RESTORE) { + __ z_vl(vs_reg, Address(Z_SP, offset - reg_save_index * BytesPerWord)); + } else { + assert(action == ACTION_COUNT_ONLY, "Sanity"); + } + } } else { fatal("Register type is not known"); } From 587f2b4b4dd73733a6ee247200371f8a8d0299c1 Mon Sep 17 00:00:00 2001 From: Hamlin Li <mli@openjdk.org> Date: Wed, 20 Nov 2024 08:49:35 +0000 Subject: [PATCH 118/311] 8343827: RISC-V: set AlignVector as false if applicable to enable SLP Reviewed-by: fyang, luhenry --- src/hotspot/cpu/riscv/vm_version_riscv.cpp | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/hotspot/cpu/riscv/vm_version_riscv.cpp b/src/hotspot/cpu/riscv/vm_version_riscv.cpp index dddded795fa..3b8d8119a8e 100644 --- a/src/hotspot/cpu/riscv/vm_version_riscv.cpp +++ b/src/hotspot/cpu/riscv/vm_version_riscv.cpp @@ -150,11 +150,12 @@ void VM_Version::common_initialize() { } if (FLAG_IS_DEFAULT(AvoidUnalignedAccesses)) { - if (unaligned_access.value() != MISALIGNED_FAST) { - FLAG_SET_DEFAULT(AvoidUnalignedAccesses, true); - } else { - FLAG_SET_DEFAULT(AvoidUnalignedAccesses, false); - } + FLAG_SET_DEFAULT(AvoidUnalignedAccesses, + unaligned_access.value() != MISALIGNED_FAST); + } + + if (FLAG_IS_DEFAULT(AlignVector)) { + FLAG_SET_DEFAULT(AlignVector, AvoidUnalignedAccesses); } // See JDK-8026049 From 5b12a87dcb47b5783f179534e2de43d5a920a489 Mon Sep 17 00:00:00 2001 From: Prasanta Sadhukhan <psadhukhan@openjdk.org> Date: Wed, 20 Nov 2024 09:11:12 +0000 Subject: [PATCH 119/311] 8344060: Remove doPrivileged calls from shared implementation code in the java.desktop module : part 1 Reviewed-by: aivanov, prr --- .../share/classes/sun/awt/SunToolkit.java | 47 +++------ .../classes/sun/awt/image/ImageDecoder.java | 9 +- .../classes/sun/awt/image/ImageFetcher.java | 30 +++--- .../classes/sun/awt/image/ImageWatched.java | 36 +------ .../classes/sun/awt/image/ImagingLib.java | 24 ++--- .../sun/awt/image/JPEGImageDecoder.java | 10 +- .../sun/awt/image/NativeLibLoader.java | 10 +- .../sun/awt/image/VSyncedBSManager.java | 5 +- .../sun/awt/util/PerformanceLogger.java | 33 +++---- .../share/classes/sun/java2d/Disposer.java | 32 ++---- .../sun/java2d/SunGraphicsEnvironment.java | 10 +- .../classes/sun/java2d/SurfaceDataProxy.java | 11 +-- .../classes/sun/java2d/cmm/CMSManager.java | 11 +-- .../classes/sun/java2d/cmm/lcms/LCMS.java | 18 ++-- .../sun/java2d/loops/GraphicsPrimitive.java | 40 +++----- .../java2d/marlin/DMarlinRenderingEngine.java | 8 +- .../sun/java2d/marlin/MarlinProperties.java | 18 +--- .../sun/java2d/marlin/RendererStats.java | 30 +++--- .../sun/java2d/opengl/OGLRenderQueue.java | 5 +- .../sun/java2d/opengl/OGLSurfaceData.java | 20 +--- .../sun/java2d/pipe/RenderingEngine.java | 16 +-- .../share/classes/sun/print/PSPrinterJob.java | 97 ++++++------------- .../classes/sun/print/RasterPrinterJob.java | 61 ++---------- .../classes/sun/print/ServiceDialog.java | 39 ++------ .../classes/sun/swing/JLightweightFrame.java | 15 +-- .../classes/sun/swing/SwingUtilities2.java | 8 +- 26 files changed, 166 insertions(+), 477 deletions(-) diff --git a/src/java.desktop/share/classes/sun/awt/SunToolkit.java b/src/java.desktop/share/classes/sun/awt/SunToolkit.java index 5c4ebda8715..1dc6c2f3920 100644 --- a/src/java.desktop/share/classes/sun/awt/SunToolkit.java +++ b/src/java.desktop/share/classes/sun/awt/SunToolkit.java @@ -79,7 +79,6 @@ import java.io.InputStream; import java.lang.reflect.InvocationTargetException; import java.net.URL; -import java.security.AccessController; import java.util.ArrayList; import java.util.Collections; import java.util.Locale; @@ -100,8 +99,6 @@ import sun.awt.image.URLImageSource; import sun.font.FontDesignMetrics; import sun.net.util.URLUtil; -import sun.security.action.GetBooleanAction; -import sun.security.action.GetPropertyAction; import sun.util.logging.PlatformLogger; import static java.awt.RenderingHints.KEY_TEXT_ANTIALIASING; @@ -122,14 +119,12 @@ public abstract class SunToolkit extends Toolkit initStatic(); } - @SuppressWarnings("removal") private static void initStatic() { - if (AccessController.doPrivileged(new GetBooleanAction("sun.awt.nativedebug"))) { + if (Boolean.getBoolean("sun.awt.nativedebug")) { DebugSettings.init(); } touchKeyboardAutoShowIsEnabled = Boolean.parseBoolean( - GetPropertyAction.privilegedGetProperty( - "awt.touchKeyboardAutoShowIsEnabled", "true")); + System.getProperty("awt.touchKeyboardAutoShowIsEnabled", "true")); } /** @@ -231,9 +226,8 @@ public abstract KeyboardFocusManagerPeer getKeyboardFocusManagerPeer() * } */ - @SuppressWarnings("removal") private static final ReentrantLock AWT_LOCK = new ReentrantLock( - AccessController.doPrivileged(new GetBooleanAction("awt.lock.fair"))); + Boolean.getBoolean("awt.lock.fair")); private static final Condition AWT_LOCK_COND = AWT_LOCK.newCondition(); public static final void awtLock() { @@ -672,18 +666,16 @@ private void disableBackgroundEraseImpl(Component component) { * Returns the value of "sun.awt.noerasebackground" property. Default * value is {@code false}. */ - @SuppressWarnings("removal") public static boolean getSunAwtNoerasebackground() { - return AccessController.doPrivileged(new GetBooleanAction("sun.awt.noerasebackground")); + return Boolean.getBoolean("sun.awt.noerasebackground"); } /** * Returns the value of "sun.awt.erasebackgroundonresize" property. Default * value is {@code false}. */ - @SuppressWarnings("removal") public static boolean getSunAwtErasebackgroundonresize() { - return AccessController.doPrivileged(new GetBooleanAction("sun.awt.erasebackgroundonresize")); + return Boolean.getBoolean("sun.awt.erasebackgroundonresize"); } @@ -1157,15 +1149,12 @@ public boolean enableInputMethodsForTextComponent() { /** * Returns the locale in which the runtime was started. */ - @SuppressWarnings("removal") public static Locale getStartupLocale() { if (startupLocale == null) { String language, region, country, variant; - language = AccessController.doPrivileged( - new GetPropertyAction("user.language", "en")); + language = System.getProperty("user.language", "en"); // for compatibility, check for old user.region property - region = AccessController.doPrivileged( - new GetPropertyAction("user.region")); + region = System.getProperty("user.region"); if (region != null) { // region can be of form country, country_variant, or _variant int i = region.indexOf('_'); @@ -1177,10 +1166,8 @@ public static Locale getStartupLocale() { variant = ""; } } else { - country = AccessController.doPrivileged( - new GetPropertyAction("user.country", "")); - variant = AccessController.doPrivileged( - new GetPropertyAction("user.variant", "")); + country = System.getProperty("user.country", ""); + variant = System.getProperty("user.variant", ""); } startupLocale = Locale.of(language, country, variant); } @@ -1201,9 +1188,7 @@ public Locale getDefaultKeyboardLocale() { * @return {@code true}, if XEmbed is needed, {@code false} otherwise */ public static boolean needsXEmbed() { - @SuppressWarnings("removal") - String noxembed = AccessController. - doPrivileged(new GetPropertyAction("sun.awt.noxembed", "false")); + String noxembed = System.getProperty("sun.awt.noxembed", "false"); if ("true".equals(noxembed)) { return false; } @@ -1235,9 +1220,8 @@ protected boolean needsXEmbedImpl() { * developer. If true, Toolkit should return an * XEmbed-server-enabled CanvasPeer instead of the ordinary CanvasPeer. */ - @SuppressWarnings("removal") protected final boolean isXEmbedServerRequested() { - return AccessController.doPrivileged(new GetBooleanAction("sun.awt.xembedserver")); + return Boolean.getBoolean("sun.awt.xembedserver"); } /** @@ -1756,16 +1740,13 @@ private static RenderingHints getDesktopAAHintsByName(String hintname) { * to be inapplicable in that case. In that headless case although * this method will return "true" the toolkit will return a null map. */ - @SuppressWarnings("removal") private static boolean useSystemAAFontSettings() { if (!checkedSystemAAFontSettings) { useSystemAAFontSettings = true; /* initially set this true */ String systemAAFonts = null; Toolkit tk = Toolkit.getDefaultToolkit(); if (tk instanceof SunToolkit) { - systemAAFonts = - AccessController.doPrivileged( - new GetPropertyAction("awt.useSystemAAFontSettings")); + systemAAFonts = System.getProperty("awt.useSystemAAFontSettings"); } if (systemAAFonts != null) { useSystemAAFontSettings = Boolean.parseBoolean(systemAAFonts); @@ -1859,11 +1840,9 @@ public static Window getContainingWindow(Component comp) { * Returns the value of "sun.awt.disableMixing" property. Default * value is {@code false}. */ - @SuppressWarnings("removal") public static synchronized boolean getSunAwtDisableMixing() { if (sunAwtDisableMixing == null) { - sunAwtDisableMixing = AccessController.doPrivileged( - new GetBooleanAction("sun.awt.disableMixing")); + sunAwtDisableMixing = Boolean.getBoolean("sun.awt.disableMixing"); } return sunAwtDisableMixing.booleanValue(); } diff --git a/src/java.desktop/share/classes/sun/awt/image/ImageDecoder.java b/src/java.desktop/share/classes/sun/awt/image/ImageDecoder.java index d09cfd9b2d8..c3691773f6e 100644 --- a/src/java.desktop/share/classes/sun/awt/image/ImageDecoder.java +++ b/src/java.desktop/share/classes/sun/awt/image/ImageDecoder.java @@ -159,18 +159,11 @@ protected int imageComplete(int status, boolean done) { public abstract void produceImage() throws IOException, ImageFormatException; - @SuppressWarnings("removal") public void abort() { aborted = true; source.doneDecoding(this); close(); - java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction<Object>() { - public Object run() { - feeder.interrupt(); - return null; - } - }); + feeder.interrupt(); } public synchronized void close() { diff --git a/src/java.desktop/share/classes/sun/awt/image/ImageFetcher.java b/src/java.desktop/share/classes/sun/awt/image/ImageFetcher.java index e527dbfcb3f..88e830a2bf5 100644 --- a/src/java.desktop/share/classes/sun/awt/image/ImageFetcher.java +++ b/src/java.desktop/share/classes/sun/awt/image/ImageFetcher.java @@ -276,7 +276,6 @@ private static void stoppingAnimation(Thread me) { /** * Create and start ImageFetcher threads in the appropriate ThreadGroup. */ - @SuppressWarnings("removal") private static void createFetchers(final FetcherInfo info) { // We need to instantiate a new ImageFetcher thread. // First, figure out which ThreadGroup we'll put the @@ -310,25 +309,18 @@ private static void createFetchers(final FetcherInfo info) { } final ThreadGroup fetcherGroup = fetcherThreadGroup; - java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction<Object>() { - public Object run() { - for (int i = 0; i < info.fetchers.length; i++) { - if (info.fetchers[i] == null) { - ImageFetcher f = new ImageFetcher(fetcherGroup, i); - try { - f.start(); - info.fetchers[i] = f; - info.numFetchers++; - break; - } catch (Error e) { - } - } - } - return null; + for (int i = 0; i < info.fetchers.length; i++) { + if (info.fetchers[i] == null) { + ImageFetcher f = new ImageFetcher(fetcherGroup, i); + try { + f.start(); + info.fetchers[i] = f; + info.numFetchers++; + break; + } catch (Error e) { } - }); - return; + } + } } } diff --git a/src/java.desktop/share/classes/sun/awt/image/ImageWatched.java b/src/java.desktop/share/classes/sun/awt/image/ImageWatched.java index 0a1dd47fb55..c3198ac704b 100644 --- a/src/java.desktop/share/classes/sun/awt/image/ImageWatched.java +++ b/src/java.desktop/share/classes/sun/awt/image/ImageWatched.java @@ -29,10 +29,6 @@ import java.awt.Image; import java.awt.image.ImageObserver; -import java.security.AccessControlContext; -import java.security.AccessController; -import java.security.PrivilegedAction; - public abstract class ImageWatched { public static Link endlink = new Link(); @@ -89,28 +85,16 @@ public boolean newInfo(Image img, int info, } } - static class AccWeakReference<T> extends WeakReference<T> { - - @SuppressWarnings("removal") - private final AccessControlContext acc; - - @SuppressWarnings("removal") - AccWeakReference(T ref) { - super(ref); - acc = AccessController.getContext(); - } - } - /* * Standard Link implementation to manage a Weak Reference * to an ImageObserver. */ public static class WeakLink extends Link { - private final AccWeakReference<ImageObserver> myref; + private final WeakReference<ImageObserver> myref; private Link next; public WeakLink(ImageObserver obs, Link next) { - myref = new AccWeakReference<ImageObserver>(obs); + myref = new WeakReference<ImageObserver>(obs); this.next = next; } @@ -136,20 +120,6 @@ public Link removeWatcher(ImageObserver iw) { return this; } - @SuppressWarnings("removal") - private static boolean update(ImageObserver iw, AccessControlContext acc, - Image img, int info, - int x, int y, int w, int h) { - - if (acc != null || System.getSecurityManager() != null) { - return AccessController.doPrivileged( - (PrivilegedAction<Boolean>) () -> { - return iw.imageUpdate(img, info, x, y, w, h); - }, acc); - } - return false; - } - public boolean newInfo(Image img, int info, int x, int y, int w, int h) { @@ -159,7 +129,7 @@ public boolean newInfo(Image img, int info, if (myiw == null) { // My referent is null so we must prune in a second pass. ret = true; - } else if (update(myiw, myref.acc, img, info, x, y, w, h) == false) { + } else if (myiw.imageUpdate(img, info, x, y, w, h) == false) { // My referent has lost interest so clear it and ask // for a pruning pass to remove it later. myref.clear(); diff --git a/src/java.desktop/share/classes/sun/awt/image/ImagingLib.java b/src/java.desktop/share/classes/sun/awt/image/ImagingLib.java index a98e6fc81fb..d37afcb7a8b 100644 --- a/src/java.desktop/share/classes/sun/awt/image/ImagingLib.java +++ b/src/java.desktop/share/classes/sun/awt/image/ImagingLib.java @@ -37,8 +37,6 @@ import java.awt.image.RasterOp; import java.awt.image.Raster; import java.awt.image.WritableRaster; -import java.security.AccessController; -import java.security.PrivilegedAction; /** * This class provides a hook to access platform-specific @@ -51,7 +49,7 @@ * (in which case our java code will be executed) or may throw * an exception. */ -@SuppressWarnings({"removal", "restricted"}) +@SuppressWarnings("restricted") public class ImagingLib { static boolean useLib = true; @@ -90,20 +88,14 @@ public static native int lookupByteRaster(Raster src, Raster dst, static { - PrivilegedAction<Boolean> doMlibInitialization = - new PrivilegedAction<Boolean>() { - public Boolean run() { - try { - System.loadLibrary("mlib_image"); - } catch (UnsatisfiedLinkError e) { - return Boolean.FALSE; - } - boolean success = init(); - return Boolean.valueOf(success); - } - }; + boolean success = false; + try { + System.loadLibrary("mlib_image"); + success = init(); + } catch (UnsatisfiedLinkError e) { + } - useLib = AccessController.doPrivileged(doMlibInitialization); + useLib = success; // // Cache the class references of the operations we know about diff --git a/src/java.desktop/share/classes/sun/awt/image/JPEGImageDecoder.java b/src/java.desktop/share/classes/sun/awt/image/JPEGImageDecoder.java index b976a716ded..eb1023bd694 100644 --- a/src/java.desktop/share/classes/sun/awt/image/JPEGImageDecoder.java +++ b/src/java.desktop/share/classes/sun/awt/image/JPEGImageDecoder.java @@ -42,7 +42,7 @@ * * @author Jim Graham */ -@SuppressWarnings({"removal", "restricted"}) +@SuppressWarnings("restricted") public class JPEGImageDecoder extends ImageDecoder { private static ColorModel RGBcolormodel; private static ColorModel ARGBcolormodel; @@ -54,13 +54,7 @@ public class JPEGImageDecoder extends ImageDecoder { private ColorModel colormodel; static { - java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction<Void>() { - public Void run() { - System.loadLibrary("javajpeg"); - return null; - } - }); + System.loadLibrary("javajpeg"); initIDs(InputStreamClass); RGBcolormodel = new DirectColorModel(24, 0xff0000, 0xff00, 0xff); ARGBcolormodel = ColorModel.getRGBdefault(); diff --git a/src/java.desktop/share/classes/sun/awt/image/NativeLibLoader.java b/src/java.desktop/share/classes/sun/awt/image/NativeLibLoader.java index e1fe5658e63..d971bf6e40d 100644 --- a/src/java.desktop/share/classes/sun/awt/image/NativeLibLoader.java +++ b/src/java.desktop/share/classes/sun/awt/image/NativeLibLoader.java @@ -52,14 +52,8 @@ class NativeLibLoader { * For now, we know it's done by the implementation, and we assume * that the name of the library is "awt". -br. */ - @SuppressWarnings({"removal", "restricted"}) + @SuppressWarnings("restricted") static void loadLibraries() { - java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction<Void>() { - public Void run() { - System.loadLibrary("awt"); - return null; - } - }); + System.loadLibrary("awt"); } } diff --git a/src/java.desktop/share/classes/sun/awt/image/VSyncedBSManager.java b/src/java.desktop/share/classes/sun/awt/image/VSyncedBSManager.java index 8bb34dd6279..88403ca06a3 100644 --- a/src/java.desktop/share/classes/sun/awt/image/VSyncedBSManager.java +++ b/src/java.desktop/share/classes/sun/awt/image/VSyncedBSManager.java @@ -35,11 +35,8 @@ public abstract class VSyncedBSManager { private static VSyncedBSManager theInstance; - @SuppressWarnings("removal") private static final boolean vSyncLimit = - Boolean.parseBoolean(java.security.AccessController.doPrivileged( - new sun.security.action.GetPropertyAction( - "sun.java2d.vsynclimit", "true"))); + Boolean.parseBoolean(System.getProperty("sun.java2d.vsynclimit", "true")); private static VSyncedBSManager getInstance(boolean create) { if (theInstance == null && create) { diff --git a/src/java.desktop/share/classes/sun/awt/util/PerformanceLogger.java b/src/java.desktop/share/classes/sun/awt/util/PerformanceLogger.java index fa4a1450bb4..303b57626d6 100644 --- a/src/java.desktop/share/classes/sun/awt/util/PerformanceLogger.java +++ b/src/java.desktop/share/classes/sun/awt/util/PerformanceLogger.java @@ -72,7 +72,6 @@ * exist once those APIs are in place. * @author Chet Haase */ -@SuppressWarnings("removal") public class PerformanceLogger { // Timing values of global interest @@ -87,16 +86,12 @@ public class PerformanceLogger { private static long baseTime; static { - String perfLoggingProp = - java.security.AccessController.doPrivileged( - new sun.security.action.GetPropertyAction("sun.perflog")); + String perfLoggingProp = System.getProperty("sun.perflog"); if (perfLoggingProp != null) { perfLoggingOn = true; // Check if we should use nanoTime - String perfNanoProp = - java.security.AccessController.doPrivileged( - new sun.security.action.GetPropertyAction("sun.perflog.nano")); + String perfNanoProp = System.getProperty("sun.perflog.nano"); if (perfNanoProp != null) { useNanoTime = true; } @@ -107,21 +102,15 @@ public class PerformanceLogger { } if (logFileName != null) { if (logWriter == null) { - java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction<Void>() { - public Void run() { - try { - File logFile = new File(logFileName); - logFile.createNewFile(); - logWriter = new FileWriter(logFile); - } catch (Exception e) { - System.out.println(e + ": Creating logfile " + - logFileName + - ". Log to console"); - } - return null; - } - }); + try { + File logFile = new File(logFileName); + logFile.createNewFile(); + logWriter = new FileWriter(logFile); + } catch (Exception e) { + System.out.println(e + ": Creating logfile " + + logFileName + + ". Log to console"); + } } } if (logWriter == null) { diff --git a/src/java.desktop/share/classes/sun/java2d/Disposer.java b/src/java.desktop/share/classes/sun/java2d/Disposer.java index 5692b490278..9929238c099 100644 --- a/src/java.desktop/share/classes/sun/java2d/Disposer.java +++ b/src/java.desktop/share/classes/sun/java2d/Disposer.java @@ -31,8 +31,6 @@ import java.lang.ref.ReferenceQueue; import java.lang.ref.PhantomReference; import java.lang.ref.WeakReference; -import java.security.AccessController; -import java.security.PrivilegedAction; import java.util.Hashtable; import java.util.concurrent.ConcurrentLinkedDeque; @@ -50,7 +48,7 @@ * * @see DisposerRecord */ -@SuppressWarnings({"removal", "restricted"}) +@SuppressWarnings("restricted") public class Disposer implements Runnable { private static final ReferenceQueue<Object> queue = new ReferenceQueue<>(); private static final Hashtable<java.lang.ref.Reference<Object>, DisposerRecord> records = @@ -62,16 +60,9 @@ public class Disposer implements Runnable { public static int refType = PHANTOM; static { - java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction<Void>() { - public Void run() { - System.loadLibrary("awt"); - return null; - } - }); + System.loadLibrary("awt"); initIDs(); - String type = java.security.AccessController.doPrivileged( - new sun.security.action.GetPropertyAction("sun.java2d.reftype")); + String type = System.getProperty("sun.java2d.reftype"); if (type != null) { if (type.equals("weak")) { refType = WEAK; @@ -82,16 +73,13 @@ public Void run() { } } disposerInstance = new Disposer(); - AccessController.doPrivileged((PrivilegedAction<Void>) () -> { - String name = "Java2D Disposer"; - ThreadGroup rootTG = ThreadGroupUtils.getRootThreadGroup(); - Thread t = new Thread(rootTG, disposerInstance, name, 0, false); - t.setContextClassLoader(null); - t.setDaemon(true); - t.setPriority(Thread.MAX_PRIORITY); - t.start(); - return null; - }); + String name = "Java2D Disposer"; + ThreadGroup rootTG = ThreadGroupUtils.getRootThreadGroup(); + Thread t = new Thread(rootTG, disposerInstance, name, 0, false); + t.setContextClassLoader(null); + t.setDaemon(true); + t.setPriority(Thread.MAX_PRIORITY); + t.start(); } /** diff --git a/src/java.desktop/share/classes/sun/java2d/SunGraphicsEnvironment.java b/src/java.desktop/share/classes/sun/java2d/SunGraphicsEnvironment.java index 4335b1c9fbf..5cd8f11ecdb 100644 --- a/src/java.desktop/share/classes/sun/java2d/SunGraphicsEnvironment.java +++ b/src/java.desktop/share/classes/sun/java2d/SunGraphicsEnvironment.java @@ -40,7 +40,6 @@ import java.awt.geom.AffineTransform; import java.awt.image.BufferedImage; import java.awt.peer.ComponentPeer; -import java.security.AccessController; import java.util.Locale; import java.util.TreeMap; @@ -50,7 +49,6 @@ import sun.font.FontManagerFactory; import sun.font.FontManagerForSGE; import sun.java2d.pipe.Region; -import sun.security.action.GetPropertyAction; /** * This is an implementation of a GraphicsEnvironment object for the @@ -65,10 +63,8 @@ public abstract class SunGraphicsEnvironment extends GraphicsEnvironment /** Establish the default font to be used by SG2D. */ private final Font defaultFont = new Font(Font.DIALOG, Font.PLAIN, 12); - @SuppressWarnings("removal") private static final boolean uiScaleEnabled - = "true".equals(AccessController.doPrivileged( - new GetPropertyAction("sun.java2d.uiScale.enabled", "true"))); + = "true".equals(System.getProperty("sun.java2d.uiScale.enabled", "true")); private static final double debugScale = uiScaleEnabled ? getScaleFactor("sun.java2d.uiScale") : -1; @@ -293,9 +289,7 @@ public static double getDebugScale() { public static double getScaleFactor(String propertyName) { - @SuppressWarnings("removal") - String scaleFactor = AccessController.doPrivileged( - new GetPropertyAction(propertyName, "-1")); + String scaleFactor = System.getProperty(propertyName, "-1"); if (scaleFactor == null || scaleFactor.equals("-1")) { return -1; diff --git a/src/java.desktop/share/classes/sun/java2d/SurfaceDataProxy.java b/src/java.desktop/share/classes/sun/java2d/SurfaceDataProxy.java index 4c1e8256552..ba4d6caf44c 100644 --- a/src/java.desktop/share/classes/sun/java2d/SurfaceDataProxy.java +++ b/src/java.desktop/share/classes/sun/java2d/SurfaceDataProxy.java @@ -38,9 +38,6 @@ import sun.java2d.loops.BlitBg; import sun.awt.image.SurfaceManager; -import java.security.AccessController; -import sun.security.action.GetPropertyAction; - /** * The proxy class encapsulates the logic for managing alternate * SurfaceData representations of a primary SurfaceData. @@ -70,18 +67,14 @@ public abstract class SurfaceDataProxy static { cachingAllowed = true; - @SuppressWarnings("removal") - String manimg = AccessController.doPrivileged( - new GetPropertyAction("sun.java2d.managedimages")); + String manimg = System.getProperty("sun.java2d.managedimages"); if ("false".equals(manimg)) { cachingAllowed = false; System.out.println("Disabling managed images"); } defaultThreshold = 1; - @SuppressWarnings("removal") - String num = AccessController.doPrivileged( - new GetPropertyAction("sun.java2d.accthreshold")); + String num = System.getProperty("sun.java2d.accthreshold"); if (num != null) { try { int parsed = Integer.parseInt(num); diff --git a/src/java.desktop/share/classes/sun/java2d/cmm/CMSManager.java b/src/java.desktop/share/classes/sun/java2d/cmm/CMSManager.java index 99e167ba672..8aba1056616 100644 --- a/src/java.desktop/share/classes/sun/java2d/cmm/CMSManager.java +++ b/src/java.desktop/share/classes/sun/java2d/cmm/CMSManager.java @@ -27,9 +27,6 @@ import java.awt.color.CMMException; import java.awt.color.ICC_Profile; -import java.security.AccessController; - -import sun.security.action.GetPropertyAction; public final class CMSManager { @@ -45,9 +42,7 @@ private static synchronized PCMM createModule() { return cmmImpl; } - GetPropertyAction gpa = new GetPropertyAction("sun.java2d.cmm"); - @SuppressWarnings("removal") - String cmmProviderClass = AccessController.doPrivileged(gpa); + String cmmProviderClass = System.getProperty("sun.java2d.cmm"); CMMServiceProvider provider = null; if (cmmProviderClass != null) { try { @@ -67,9 +62,7 @@ private static synchronized PCMM createModule() { "No CM module found"); } - gpa = new GetPropertyAction("sun.java2d.cmm.trace"); - @SuppressWarnings("removal") - String cmmTrace = AccessController.doPrivileged(gpa); + String cmmTrace = System.getProperty("sun.java2d.cmm.trace"); if (cmmTrace != null) { cmmImpl = new CMMTracer(cmmImpl); } diff --git a/src/java.desktop/share/classes/sun/java2d/cmm/lcms/LCMS.java b/src/java.desktop/share/classes/sun/java2d/cmm/lcms/LCMS.java index 2fe86b3500c..3a7db37329e 100644 --- a/src/java.desktop/share/classes/sun/java2d/cmm/lcms/LCMS.java +++ b/src/java.desktop/share/classes/sun/java2d/cmm/lcms/LCMS.java @@ -143,23 +143,17 @@ private LCMS() {} private static LCMS theLcms = null; - @SuppressWarnings({"removal", "restricted"}) + @SuppressWarnings("restricted") static synchronized PCMM getModule() { if (theLcms != null) { return theLcms; } - java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction<Object>() { - public Object run() { - /* We need to load awt here because of usage trace and - * disposer frameworks - */ - System.loadLibrary("awt"); - System.loadLibrary("lcms"); - return null; - } - }); + /* We need to load awt here because of usage trace and + * disposer frameworks + */ + System.loadLibrary("awt"); + System.loadLibrary("lcms"); theLcms = new LCMS(); diff --git a/src/java.desktop/share/classes/sun/java2d/loops/GraphicsPrimitive.java b/src/java.desktop/share/classes/sun/java2d/loops/GraphicsPrimitive.java index ade97ee007f..8fd97626f04 100644 --- a/src/java.desktop/share/classes/sun/java2d/loops/GraphicsPrimitive.java +++ b/src/java.desktop/share/classes/sun/java2d/loops/GraphicsPrimitive.java @@ -36,8 +36,6 @@ import java.io.FileOutputStream; import java.io.PrintStream; import java.lang.reflect.Field; -import java.security.AccessController; -import java.security.PrivilegedAction; import java.util.HashMap; import java.util.Map; import java.util.StringTokenizer; @@ -46,7 +44,6 @@ import sun.awt.util.ThreadGroupUtils; import sun.java2d.SurfaceData; import sun.java2d.pipe.Region; -import sun.security.action.GetPropertyAction; /** * defines interface for primitives which can be placed into @@ -336,9 +333,7 @@ protected GraphicsPrimitive makePrimitive(SurfaceType srctype, public static final int TRACECOUNTS = 4; static { - GetPropertyAction gpa = new GetPropertyAction("sun.java2d.trace"); - @SuppressWarnings("removal") - String trace = AccessController.doPrivileged(gpa); + String trace = System.getProperty("sun.java2d.trace"); if (trace != null) { boolean verbose = false; int traceflags = 0; @@ -401,17 +396,12 @@ public static boolean tracingEnabled() { private static PrintStream getTraceOutputFile() { if (traceout == null) { if (tracefile != null) { - @SuppressWarnings("removal") - FileOutputStream o = AccessController.doPrivileged( - new PrivilegedAction<FileOutputStream>() { - public FileOutputStream run() { - try { - return new FileOutputStream(tracefile); - } catch (FileNotFoundException e) { - return null; - } - } - }); + FileOutputStream o; + try { + o = new FileOutputStream(tracefile); + } catch (FileNotFoundException e) { + o = null; + } if (o != null) { traceout = new PrintStream(o); } else { @@ -425,17 +415,13 @@ public FileOutputStream run() { } public static class TraceReporter implements Runnable { - @SuppressWarnings("removal") public static void setShutdownHook() { - AccessController.doPrivileged((PrivilegedAction<Void>) () -> { - TraceReporter t = new TraceReporter(); - Thread thread = new Thread( - ThreadGroupUtils.getRootThreadGroup(), t, - "TraceReporter", 0, false); - thread.setContextClassLoader(null); - Runtime.getRuntime().addShutdownHook(thread); - return null; - }); + TraceReporter t = new TraceReporter(); + Thread thread = new Thread( + ThreadGroupUtils.getRootThreadGroup(), t, + "TraceReporter", 0, false); + thread.setContextClassLoader(null); + Runtime.getRuntime().addShutdownHook(thread); } public void run() { diff --git a/src/java.desktop/share/classes/sun/java2d/marlin/DMarlinRenderingEngine.java b/src/java.desktop/share/classes/sun/java2d/marlin/DMarlinRenderingEngine.java index b29cc84c127..66eb9334e86 100644 --- a/src/java.desktop/share/classes/sun/java2d/marlin/DMarlinRenderingEngine.java +++ b/src/java.desktop/share/classes/sun/java2d/marlin/DMarlinRenderingEngine.java @@ -30,7 +30,6 @@ import java.awt.geom.AffineTransform; import java.awt.geom.Path2D; import java.awt.geom.PathIterator; -import java.security.AccessController; import java.util.Arrays; import sun.awt.geom.PathConsumer2D; import static sun.java2d.marlin.MarlinUtils.logInfo; @@ -40,7 +39,6 @@ import sun.java2d.pipe.AATileGenerator; import sun.java2d.pipe.Region; import sun.java2d.pipe.RenderingEngine; -import sun.security.action.GetPropertyAction; /** * Marlin RendererEngine implementation (derived from Pisces) @@ -1119,10 +1117,8 @@ public float getMinimumAAPenSize() { USE_THREAD_LOCAL = MarlinProperties.isUseThreadLocal(); // Soft reference by default: - @SuppressWarnings("removal") - final String refType = AccessController.doPrivileged( - new GetPropertyAction("sun.java2d.renderer.useRef", - "soft")); + final String refType = System.getProperty("sun.java2d.renderer.useRef", + "soft"); switch (refType) { default: case "soft": diff --git a/src/java.desktop/share/classes/sun/java2d/marlin/MarlinProperties.java b/src/java.desktop/share/classes/sun/java2d/marlin/MarlinProperties.java index ef919eba400..65122cae2a3 100644 --- a/src/java.desktop/share/classes/sun/java2d/marlin/MarlinProperties.java +++ b/src/java.desktop/share/classes/sun/java2d/marlin/MarlinProperties.java @@ -25,9 +25,7 @@ package sun.java2d.marlin; -import java.security.AccessController; import static sun.java2d.marlin.MarlinUtils.logInfo; -import sun.security.action.GetPropertyAction; public final class MarlinProperties { @@ -288,24 +286,18 @@ public static float getQuadDecD2() { } // system property utilities - @SuppressWarnings("removal") static String getString(final String key, final String def) { - return AccessController.doPrivileged( - new GetPropertyAction(key, def)); + return System.getProperty(key, def); } - @SuppressWarnings("removal") static boolean getBoolean(final String key, final String def) { - return Boolean.parseBoolean(AccessController.doPrivileged( - new GetPropertyAction(key, def))); + return Boolean.parseBoolean(System.getProperty(key, def)); } static int getInteger(final String key, final int def, final int min, final int max) { - @SuppressWarnings("removal") - final String property = AccessController.doPrivileged( - new GetPropertyAction(key)); + final String property = System.getProperty(key); int value = def; if (property != null) { @@ -334,9 +326,7 @@ public static double getDouble(final String key, final double def, final double min, final double max) { double value = def; - @SuppressWarnings("removal") - final String property = AccessController.doPrivileged( - new GetPropertyAction(key)); + final String property = System.getProperty(key); if (property != null) { try { diff --git a/src/java.desktop/share/classes/sun/java2d/marlin/RendererStats.java b/src/java.desktop/share/classes/sun/java2d/marlin/RendererStats.java index 5517ce93f99..131f63afa65 100644 --- a/src/java.desktop/share/classes/sun/java2d/marlin/RendererStats.java +++ b/src/java.desktop/share/classes/sun/java2d/marlin/RendererStats.java @@ -25,8 +25,6 @@ package sun.java2d.marlin; -import java.security.AccessController; -import java.security.PrivilegedAction; import java.util.Timer; import java.util.TimerTask; import java.util.concurrent.ConcurrentLinkedQueue; @@ -357,11 +355,8 @@ static void dumpStats() { private final ConcurrentLinkedQueue<RendererStats> allStats = new ConcurrentLinkedQueue<>(); - @SuppressWarnings("removal") private RendererStatsHolder() { - AccessController.doPrivileged( - (PrivilegedAction<Void>) () -> { - final Thread hook = new Thread( + final Thread hook = new Thread( MarlinUtils.getRootThreadGroup(), new Runnable() { @Override @@ -371,21 +366,18 @@ public void run() { }, "MarlinStatsHook" ); - hook.setContextClassLoader(null); - Runtime.getRuntime().addShutdownHook(hook); + hook.setContextClassLoader(null); + Runtime.getRuntime().addShutdownHook(hook); - if (USE_DUMP_THREAD) { - final Timer statTimer = new Timer("RendererStats"); - statTimer.scheduleAtFixedRate(new TimerTask() { - @Override - public void run() { - dump(); - } - }, DUMP_INTERVAL, DUMP_INTERVAL); + if (USE_DUMP_THREAD) { + final Timer statTimer = new Timer("RendererStats"); + statTimer.scheduleAtFixedRate(new TimerTask() { + @Override + public void run() { + dump(); } - return null; - } - ); + }, DUMP_INTERVAL, DUMP_INTERVAL); + } } void add(final Object parent, final RendererStats stats) { diff --git a/src/java.desktop/share/classes/sun/java2d/opengl/OGLRenderQueue.java b/src/java.desktop/share/classes/sun/java2d/opengl/OGLRenderQueue.java index 4b89aca5c85..8427bcd1a4f 100644 --- a/src/java.desktop/share/classes/sun/java2d/opengl/OGLRenderQueue.java +++ b/src/java.desktop/share/classes/sun/java2d/opengl/OGLRenderQueue.java @@ -30,8 +30,6 @@ import sun.java2d.pipe.RenderQueue; import static sun.java2d.pipe.BufferedOpCodes.*; -import java.security.AccessController; -import java.security.PrivilegedAction; /** * OGL-specific implementation of RenderQueue. This class provides a @@ -44,13 +42,12 @@ public class OGLRenderQueue extends RenderQueue { private static OGLRenderQueue theInstance; private final QueueFlusher flusher; - @SuppressWarnings("removal") private OGLRenderQueue() { /* * The thread must be a member of a thread group * which will not get GCed before VM exit. */ - flusher = AccessController.doPrivileged((PrivilegedAction<QueueFlusher>) QueueFlusher::new); + flusher = new QueueFlusher(); } /** diff --git a/src/java.desktop/share/classes/sun/java2d/opengl/OGLSurfaceData.java b/src/java.desktop/share/classes/sun/java2d/opengl/OGLSurfaceData.java index 2f27515c204..501399c35a9 100644 --- a/src/java.desktop/share/classes/sun/java2d/opengl/OGLSurfaceData.java +++ b/src/java.desktop/share/classes/sun/java2d/opengl/OGLSurfaceData.java @@ -178,31 +178,19 @@ protected native boolean initFBObject(long pData, static { if (!GraphicsEnvironment.isHeadless()) { // fbobject currently enabled by default; use "false" to disable - @SuppressWarnings("removal") - String fbo = java.security.AccessController.doPrivileged( - new sun.security.action.GetPropertyAction( - "sun.java2d.opengl.fbobject")); + String fbo = System.getProperty("sun.java2d.opengl.fbobject"); isFBObjectEnabled = !"false".equals(fbo); // lcdshader currently enabled by default; use "false" to disable - @SuppressWarnings("removal") - String lcd = java.security.AccessController.doPrivileged( - new sun.security.action.GetPropertyAction( - "sun.java2d.opengl.lcdshader")); + String lcd = System.getProperty("sun.java2d.opengl.lcdshader"); isLCDShaderEnabled = !"false".equals(lcd); // biopshader currently enabled by default; use "false" to disable - @SuppressWarnings("removal") - String biop = java.security.AccessController.doPrivileged( - new sun.security.action.GetPropertyAction( - "sun.java2d.opengl.biopshader")); + String biop = System.getProperty("sun.java2d.opengl.biopshader"); isBIOpShaderEnabled = !"false".equals(biop); // gradshader currently enabled by default; use "false" to disable - @SuppressWarnings("removal") - String grad = java.security.AccessController.doPrivileged( - new sun.security.action.GetPropertyAction( - "sun.java2d.opengl.gradshader")); + String grad = System.getProperty("sun.java2d.opengl.gradshader"); isGradShaderEnabled = !"false".equals(grad); OGLRenderQueue rq = OGLRenderQueue.getInstance(); diff --git a/src/java.desktop/share/classes/sun/java2d/pipe/RenderingEngine.java b/src/java.desktop/share/classes/sun/java2d/pipe/RenderingEngine.java index e33eabd06b3..e6a5be7ca3b 100644 --- a/src/java.desktop/share/classes/sun/java2d/pipe/RenderingEngine.java +++ b/src/java.desktop/share/classes/sun/java2d/pipe/RenderingEngine.java @@ -30,9 +30,6 @@ import java.awt.geom.PathIterator; import java.awt.geom.AffineTransform; -import java.security.AccessController; -import sun.security.action.GetPropertyAction; - import sun.awt.geom.PathConsumer2D; /** @@ -120,10 +117,7 @@ public static synchronized RenderingEngine getInstance() { /* Look first for an app-override renderer, * if not specified or present, then look for marlin. */ - GetPropertyAction gpa = - new GetPropertyAction("sun.java2d.renderer"); - @SuppressWarnings("removal") - String reClass = AccessController.doPrivileged(gpa); + String reClass = System.getProperty("sun.java2d.renderer"); if (reClass != null) { try { Class<?> cls = Class.forName(reClass); @@ -144,16 +138,12 @@ public static synchronized RenderingEngine getInstance() { throw new InternalError("No RenderingEngine module found"); } - gpa = new GetPropertyAction("sun.java2d.renderer.verbose"); - @SuppressWarnings("removal") - String verbose = AccessController.doPrivileged(gpa); + String verbose = System.getProperty("sun.java2d.renderer.verbose"); if (verbose != null && verbose.startsWith("t")) { System.out.println("RenderingEngine = "+reImpl); } - gpa = new GetPropertyAction("sun.java2d.renderer.trace"); - @SuppressWarnings("removal") - String reTrace = AccessController.doPrivileged(gpa); + String reTrace = System.getProperty("sun.java2d.renderer.trace"); if (reTrace != null) { reImpl = new Tracer(reImpl); } diff --git a/src/java.desktop/share/classes/sun/print/PSPrinterJob.java b/src/java.desktop/share/classes/sun/print/PSPrinterJob.java index e64fb2cb0d5..a0f68a713aa 100644 --- a/src/java.desktop/share/classes/sun/print/PSPrinterJob.java +++ b/src/java.desktop/share/classes/sun/print/PSPrinterJob.java @@ -338,18 +338,9 @@ public class PSPrinterJob extends RasterPrinterJob { initStatic(); } - @SuppressWarnings("removal") private static void initStatic() { - //enable privileges so initProps can access system properties, - // open the property file, etc. - java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction<Object>() { - public Object run() { - mFontProps = initProps(); - isMac = OSInfo.getOSType() == OSInfo.OSType.MACOSX; - return null; - } - }); + mFontProps = initProps(); + isMac = OSInfo.getOSType() == OSInfo.OSType.MACOSX; } /* @@ -512,7 +503,6 @@ protected void setAttributes(PrintRequestAttributeSet attributes) * this method is called to mark the start of a * document. */ - @SuppressWarnings("removal") protected void startDoc() throws PrinterException { // A security check has been performed in the @@ -551,7 +541,7 @@ protected void startDoc() throws PrinterException { } } else { PrinterOpener po = new PrinterOpener(); - java.security.AccessController.doPrivileged(po); + po.run(); if (po.pex != null) { throw po.pex; } @@ -641,22 +631,16 @@ protected void startDoc() throws PrinterException { paperWidth + " "+ paperHeight+"]"); final PrintService pservice = getPrintService(); - Boolean isPS = java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction<Boolean>() { - public Boolean run() { - try { - Class<?> psClass = Class.forName("sun.print.IPPPrintService"); - if (psClass.isInstance(pservice)) { - Method isPSMethod = psClass.getMethod("isPostscript", - (Class[])null); - return (Boolean)isPSMethod.invoke(pservice, (Object[])null); - } - } catch (Throwable t) { - } - return Boolean.TRUE; - } + Boolean isPS = Boolean.TRUE; + try { + Class<?> psClass = Class.forName("sun.print.IPPPrintService"); + if (psClass.isInstance(pservice)) { + Method isPSMethod = psClass.getMethod("isPostscript", + (Class[])null); + isPS = (Boolean)isPSMethod.invoke(pservice, (Object[])null); } - ); + } catch (Throwable t) { + } if (isPS) { mPSStream.print(" /DeferredMediaSelection true"); } @@ -677,9 +661,9 @@ public Boolean run() { mPSStream.println("%%EndSetup"); } - // Inner class to run "privileged" to open the printer output stream. + // Inner class to open the printer output stream. - private class PrinterOpener implements java.security.PrivilegedAction<OutputStream> { + private class PrinterOpener { PrinterException pex; OutputStream result; @@ -704,9 +688,9 @@ public OutputStream run() { } } - // Inner class to run "privileged" to invoke the system print command + // Inner class to invoke the system print command - private class PrinterSpooler implements java.security.PrivilegedAction<Object> { + private class PrinterSpooler { PrinterException pex; private void handleProcessFailure(final Process failedProcess, @@ -767,21 +751,13 @@ mNoJobSheet, getJobNameInt(), /** * Invoked if the application cancelled the printjob. */ - @SuppressWarnings("removal") protected void abortDoc() { if (mPSStream != null && mDestType != RasterPrinterJob.STREAM) { mPSStream.close(); } - java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction<Object>() { - - public Object run() { - if (spoolFile != null && spoolFile.exists()) { - spoolFile.delete(); - } - return null; - } - }); + if (spoolFile != null && spoolFile.exists()) { + spoolFile.delete(); + } } /** @@ -789,7 +765,6 @@ public Object run() { * this method is called after that last page * has been imaged. */ - @SuppressWarnings("removal") protected void endDoc() throws PrinterException { if (mPSStream != null) { mPSStream.println(EOF_COMMENT); @@ -814,7 +789,7 @@ protected void endDoc() throws PrinterException { } } PrinterSpooler spooler = new PrinterSpooler(); - java.security.AccessController.doPrivileged(spooler); + spooler.run(); if (spooler.pex != null) { throw spooler.pex; } @@ -859,28 +834,18 @@ protected void startPage(PageFormat pageFormat, Printable painter, paperWidth + " " + paperHeight + "]"); final PrintService pservice = getPrintService(); - @SuppressWarnings("removal") - Boolean isPS = java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction<Boolean>() { - public Boolean run() { - try { - Class<?> psClass = - Class.forName("sun.print.IPPPrintService"); - if (psClass.isInstance(pservice)) { - Method isPSMethod = - psClass.getMethod("isPostscript", - (Class[])null); - return (Boolean) - isPSMethod.invoke(pservice, + Boolean isPS = Boolean.TRUE; + try { + Class<?> psClass = Class.forName("sun.print.IPPPrintService"); + if (psClass.isInstance(pservice)) { + Method isPSMethod = + psClass.getMethod("isPostscript", + (Class[])null); + isPS = (Boolean) isPSMethod.invoke(pservice, (Object[])null); - } - } catch (Throwable t) { - } - return Boolean.TRUE; - } - } - ); - + } + } catch (Throwable t) { + } if (isPS) { mPSStream.print(" /DeferredMediaSelection true"); } diff --git a/src/java.desktop/share/classes/sun/print/RasterPrinterJob.java b/src/java.desktop/share/classes/sun/print/RasterPrinterJob.java index 82f47824bfa..bf380873d2b 100644 --- a/src/java.desktop/share/classes/sun/print/RasterPrinterJob.java +++ b/src/java.desktop/share/classes/sun/print/RasterPrinterJob.java @@ -174,9 +174,7 @@ public abstract class RasterPrinterJob extends PrinterJob { * use a particular pipeline. Either the raster * pipeline or the pdl pipeline can be forced. */ - @SuppressWarnings("removal") - String forceStr = java.security.AccessController.doPrivileged( - new sun.security.action.GetPropertyAction(FORCE_PIPE_PROP)); + String forceStr = System.getProperty(FORCE_PIPE_PROP); if (forceStr != null) { if (forceStr.equalsIgnoreCase(FORCE_PDL)) { @@ -186,9 +184,7 @@ public abstract class RasterPrinterJob extends PrinterJob { } } - @SuppressWarnings("removal") - String shapeTextStr =java.security.AccessController.doPrivileged( - new sun.security.action.GetPropertyAction(SHAPE_TEXT_PROP)); + String shapeTextStr = System.getProperty(SHAPE_TEXT_PROP); if (shapeTextStr != null) { shapeTextProp = true; @@ -731,20 +727,9 @@ public PageFormat pageDialog(PageFormat page) GraphicsEnvironment.getLocalGraphicsEnvironment(). getDefaultScreenDevice().getDefaultConfiguration(); - @SuppressWarnings("removal") - PrintService service = java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction<PrintService>() { - public PrintService run() { - PrintService service = getPrintService(); - if (service == null) { - ServiceDialog.showNoPrintService(gc); - return null; - } - return service; - } - }); - + PrintService service = getPrintService(); if (service == null) { + ServiceDialog.showNoPrintService(gc); return page; } updatePageAttributes(service, page); @@ -812,20 +797,9 @@ public PageFormat pageDialog(final PrintRequestAttributeSet attributes) } final GraphicsConfiguration gc = grCfg; - @SuppressWarnings("removal") - PrintService service = java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction<PrintService>() { - public PrintService run() { - PrintService service = getPrintService(); - if (service == null) { - ServiceDialog.showNoPrintService(gc); - return null; - } - return service; - } - }); - + PrintService service = getPrintService(); if (service == null) { + ServiceDialog.showNoPrintService(gc); return null; } @@ -953,7 +927,6 @@ protected PageFormat getPageFormatFromAttributes() { * returns true. * @see java.awt.GraphicsEnvironment#isHeadless */ - @SuppressWarnings("removal") public boolean printDialog(final PrintRequestAttributeSet attributes) throws HeadlessException { if (GraphicsEnvironment.isHeadless()) { @@ -1008,19 +981,9 @@ public boolean printDialog(final PrintRequestAttributeSet attributes) } final GraphicsConfiguration gc = grCfg; - PrintService service = java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction<PrintService>() { - public PrintService run() { - PrintService service = getPrintService(); - if (service == null) { - ServiceDialog.showNoPrintService(gc); - return null; - } - return service; - } - }); - + PrintService service = getPrintService(); if (service == null) { + ServiceDialog.showNoPrintService(gc); return false; } @@ -1033,13 +996,7 @@ public PrintService run() { services[i] = spsFactories[i].getPrintService(null); } } else { - services = java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction<PrintService[]>() { - public PrintService[] run() { - PrintService[] services = PrinterJob.lookupPrintServices(); - return services; - } - }); + services = PrinterJob.lookupPrintServices(); if ((services == null) || (services.length == 0)) { /* diff --git a/src/java.desktop/share/classes/sun/print/ServiceDialog.java b/src/java.desktop/share/classes/sun/print/ServiceDialog.java index 983be70bdbb..ae2c787ce36 100644 --- a/src/java.desktop/share/classes/sun/print/ServiceDialog.java +++ b/src/java.desktop/share/classes/sun/print/ServiceDialog.java @@ -448,21 +448,13 @@ private void updatePanels() { /** * Initialize ResourceBundle */ - @SuppressWarnings("removal") public static void initResource() { - java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction<Object>() { - public Object run() { - try { - messageRB = ResourceBundle.getBundle(strBundle); - return null; - } catch (java.util.MissingResourceException e) { - throw new Error("Fatal: Resource for ServiceUI " + - "is missing"); - } - } - } - ); + try { + messageRB = ResourceBundle.getBundle(strBundle); + } catch (java.util.MissingResourceException e) { + throw new Error("Fatal: Resource for ServiceUI " + + "is missing"); + } } /** @@ -542,15 +534,7 @@ private static int getVKMnemonic(String key) { * Returns URL for image resource */ private static URL getImageResource(final String key) { - @SuppressWarnings("removal") - URL url = java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction<URL>() { - public URL run() { - URL url = ServiceDialog.class.getResource( - "resources/" + key); - return url; - } - }); + URL url = ServiceDialog.class.getResource("resources/" + key); if (url == null) { throw new Error("Fatal: Resource for ServiceUI is broken; " + @@ -2943,14 +2927,7 @@ public IconRadioButton(String key, String img, boolean selected, { super(new FlowLayout(FlowLayout.LEADING)); final URL imgURL = getImageResource(img); - @SuppressWarnings("removal") - Icon icon = java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction<Icon>() { - public Icon run() { - Icon icon = new ImageIcon(imgURL); - return icon; - } - }); + Icon icon = new ImageIcon(imgURL); lbl = new JLabel(icon); add(lbl); diff --git a/src/java.desktop/share/classes/sun/swing/JLightweightFrame.java b/src/java.desktop/share/classes/sun/swing/JLightweightFrame.java index d83b940a0bd..8e4b0ff3f7c 100644 --- a/src/java.desktop/share/classes/sun/swing/JLightweightFrame.java +++ b/src/java.desktop/share/classes/sun/swing/JLightweightFrame.java @@ -40,7 +40,6 @@ import java.awt.image.DataBufferInt; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; -import java.security.AccessController; import javax.swing.JComponent; import javax.swing.JLayeredPane; @@ -55,7 +54,6 @@ import sun.awt.DisplayChangedListener; import sun.awt.LightweightFrame; import sun.awt.OverrideNativeWindowHandle; -import sun.security.action.GetPropertyAction; import sun.swing.SwingUtilities2.RepaintListener; /** @@ -105,24 +103,21 @@ public void updateCursor(JLightweightFrame frame) { * by the lock (managed with the {@link LightweightContent#paintLock()}, * {@link LightweightContent#paintUnlock()} methods). */ - @SuppressWarnings("removal") - private static boolean copyBufferEnabled = "true".equals(AccessController. - doPrivileged(new GetPropertyAction("swing.jlf.copyBufferEnabled", "true"))); + private static boolean copyBufferEnabled = "true".equals( + System.getProperty("swing.jlf.copyBufferEnabled", "true")); private int[] copyBuffer; /** * Constructs a new, initially invisible {@code JLightweightFrame} * instance. */ - @SuppressWarnings("removal") public JLightweightFrame() { super(); AffineTransform defaultTransform = getGraphicsConfiguration().getDefaultTransform(); scaleFactorX = defaultTransform.getScaleX(); scaleFactorY = defaultTransform.getScaleY(); - copyBufferEnabled = "true".equals(AccessController. - doPrivileged(new GetPropertyAction("swing.jlf.copyBufferEnabled", "true"))); + copyBufferEnabled = "true".equals(System.getProperty("swing.jlf.copyBufferEnabled", "true")); add(rootPane, BorderLayout.CENTER); setFocusTraversalPolicy(new LayoutFocusTraversalPolicy()); @@ -331,7 +326,6 @@ private void notifyImageUpdated(int x, int y, int width, int height) { content.imageUpdated(x, y, width, height); } - @SuppressWarnings("removal") private void initInterior() { contentPane = new JPanel() { @Override @@ -392,8 +386,7 @@ public void componentRemoved(ContainerEvent e) { contentPane.add(component); contentPane.revalidate(); contentPane.repaint(); - if ("true".equals(AccessController. - doPrivileged(new GetPropertyAction("swing.jlf.contentPaneTransparent", "false")))) + if ("true".equals(System.getProperty("swing.jlf.contentPaneTransparent", "false"))) { contentPane.setOpaque(false); } diff --git a/src/java.desktop/share/classes/sun/swing/SwingUtilities2.java b/src/java.desktop/share/classes/sun/swing/SwingUtilities2.java index d763a72d528..2613ca326ea 100644 --- a/src/java.desktop/share/classes/sun/swing/SwingUtilities2.java +++ b/src/java.desktop/share/classes/sun/swing/SwingUtilities2.java @@ -61,8 +61,6 @@ import java.io.IOException; import java.io.InputStream; import java.lang.reflect.Modifier; -import java.security.AccessController; -import java.security.PrivilegedAction; import java.text.AttributedCharacterIterator; import java.text.AttributedString; import java.text.BreakIterator; @@ -1706,10 +1704,8 @@ private static Object makeIcon(final Class<?> baseClass, final String imageFile, final boolean enablePrivileges) { return (UIDefaults.LazyValue) (table) -> { - @SuppressWarnings("removal") - byte[] buffer = enablePrivileges ? AccessController.doPrivileged( - (PrivilegedAction<byte[]>) () - -> getIconBytes(baseClass, rootClass, imageFile)) + byte[] buffer = enablePrivileges ? + getIconBytes(baseClass, rootClass, imageFile) : getIconBytes(baseClass, rootClass, imageFile); if (buffer == null) { From cf158bc6cdadfdfa944b8ec1d3dc7069c8f055a9 Mon Sep 17 00:00:00 2001 From: Jan Lahoda <jlahoda@openjdk.org> Date: Wed, 20 Nov 2024 09:24:05 +0000 Subject: [PATCH 120/311] 8341631: JShell should auto-import java.io.IO.* Reviewed-by: asotona, cstein --- .../jshell/tool/ConsoleIOContext.java | 5 ++ .../jdk/internal/jshell/tool/IOContext.java | 4 ++ .../jdk/internal/jshell/tool/JShellTool.java | 47 +++++++++++++++---- .../jshell/execution/impl/ConsoleImpl.java | 20 ++++++-- .../jshell/tool/resources/PREVIEW_DEFAULT.jsh | 1 + .../langtools/jdk/jshell/ConsoleToolTest.java | 36 +++++++++++++- .../langtools/jdk/jshell/StartOptionTest.java | 45 ++++++++++++++++-- 7 files changed, 141 insertions(+), 17 deletions(-) diff --git a/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/ConsoleIOContext.java b/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/ConsoleIOContext.java index f4ca58d6af4..c92e6e11f1f 100644 --- a/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/ConsoleIOContext.java +++ b/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/ConsoleIOContext.java @@ -1001,6 +1001,11 @@ public synchronized String readUserLine(String prompt) throws IOException { return doReadUserLine(prompt, null); } + @Override + public String readUserLine() throws IOException { + return readUserLine(""); + } + private synchronized String doReadUserLine(String prompt, Character mask) throws IOException { History prevHistory = in.getHistory(); boolean prevDisableCr = Display.DISABLE_CR; diff --git a/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/IOContext.java b/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/IOContext.java index e22d927911c..7a1234628de 100644 --- a/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/IOContext.java +++ b/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/IOContext.java @@ -64,6 +64,8 @@ public char readUserInputChar() throws IOException { } public String readUserLine(String prompt) throws IOException { + userOutput().write(prompt); + userOutput().flush(); throw new UserInterruptException(""); } @@ -76,6 +78,8 @@ public Writer userOutput() { } public char[] readPassword(String prompt) throws IOException { + userOutput().write(prompt); + userOutput().flush(); throw new UserInterruptException(""); } diff --git a/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/JShellTool.java b/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/JShellTool.java index d2d2ed10e63..1adcb472b77 100644 --- a/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/JShellTool.java +++ b/src/jdk.jshell/share/classes/jdk/internal/jshell/tool/JShellTool.java @@ -35,6 +35,7 @@ import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; +import java.io.OutputStreamWriter; import java.io.PrintStream; import java.io.PrintWriter; import java.io.Reader; @@ -1192,7 +1193,7 @@ private void initFeedback(String initMode) { //where private void startUpRun(String start) { - try (IOContext suin = new ScannerIOContext(new StringReader(start))) { + try (IOContext suin = new ScannerIOContext(new StringReader(start), userout)) { while (run(suin)) { if (!live) { resetState(); @@ -3125,7 +3126,7 @@ private boolean runFile(String filename, String context) { throw new FileNotFoundException(filename); } } - try (var scannerIOContext = new ScannerIOContext(scanner)) { + try (var scannerIOContext = new ScannerIOContext(scanner, userout)) { run(scannerIOContext); } return true; @@ -3288,8 +3289,10 @@ private boolean doReload(ReplayableHistory history, boolean echo, Options oldOpt resetState(); } if (history != null) { - run(new ReloadIOContext(history.iterable(), - echo ? cmdout : null)); + try (ReloadIOContext ctx = new ReloadIOContext(history.iterable(), + echo ? cmdout : null, userout)) { + run(ctx); + } } return true; } @@ -4107,6 +4110,8 @@ public void close() throws IOException { public String readLine(String prompt) { try { return input.readUserLine(prompt); + } catch (UserInterruptException ex) { + return null; } catch (IOException ex) { throw new IOError(ex); } @@ -4125,6 +4130,8 @@ public String readLine() throws IOError { public char[] readPassword(String prompt) { try { return input.readPassword(prompt); + } catch (UserInterruptException ex) { + return null; } catch (IOException ex) { throw new IOError(ex); } @@ -4144,6 +4151,12 @@ public Charset charset() { abstract class NonInteractiveIOContext extends IOContext { + private final Writer userOutput; + + public NonInteractiveIOContext(PrintStream userOutput) { + this.userOutput = new OutputStreamWriter(userOutput); + } + @Override public boolean interactiveOutput() { return false; @@ -4178,17 +4191,33 @@ public void afterUserCode() { @Override public void replaceLastHistoryEntry(String source) { } + + @Override + public Writer userOutput() { + return userOutput; + } + + @Override + public void close() { + try { + userOutput.flush(); + } catch (IOException _) { + //ignore + } + } + } class ScannerIOContext extends NonInteractiveIOContext { private final Scanner scannerIn; - ScannerIOContext(Scanner scannerIn) { + ScannerIOContext(Scanner scannerIn, PrintStream userOutput) { + super(userOutput); this.scannerIn = scannerIn; } - ScannerIOContext(Reader rdr) throws FileNotFoundException { - this(new Scanner(rdr)); + ScannerIOContext(Reader rdr, PrintStream userOutput) throws FileNotFoundException { + this(new Scanner(rdr), userOutput); } @Override @@ -4202,6 +4231,7 @@ public String readLine(String firstLinePrompt, String continuationPrompt, boolea @Override public void close() { + super.close(); scannerIn.close(); } @@ -4215,7 +4245,8 @@ class ReloadIOContext extends NonInteractiveIOContext { private final Iterator<String> it; private final PrintStream echoStream; - ReloadIOContext(Iterable<String> history, PrintStream echoStream) { + ReloadIOContext(Iterable<String> history, PrintStream echoStream, PrintStream userOutput) { + super(userOutput); this.it = history.iterator(); this.echoStream = echoStream; } diff --git a/src/jdk.jshell/share/classes/jdk/jshell/execution/impl/ConsoleImpl.java b/src/jdk.jshell/share/classes/jdk/jshell/execution/impl/ConsoleImpl.java index 876f61ec856..a697a37141e 100644 --- a/src/jdk.jshell/share/classes/jdk/jshell/execution/impl/ConsoleImpl.java +++ b/src/jdk.jshell/share/classes/jdk/jshell/execution/impl/ConsoleImpl.java @@ -117,6 +117,9 @@ private int readChars(char[] data, int off, int len) throws IOException { private char[] readChars() throws IOException { int actualLen = readInt(); + if (actualLen == (-1)) { + return null; + } char[] result = new char[actualLen]; for (int i = 0; i < actualLen; i++) { result[i] = (char) ((remoteOutput.read() << 8) | @@ -267,6 +270,9 @@ public String readLine(Locale locale, String format, Object... args) { remoteInput.write(Task.READ_LINE.ordinal()); sendChars(chars, 0, chars.length); char[] line = readChars(); + if (line == null) { + return null; + } return new String(line); }); } catch (IOException ex) { @@ -417,8 +423,12 @@ public synchronized void write(int b) throws IOException { char[] data = readCharsOrNull(1); if (data != null) { String line = console.readLine(new String(data)); - char[] chars = line.toCharArray(); - sendChars(sinkOutput, chars, 0, chars.length); + if (line == null) { + sendInt(sinkOutput, -1); + } else { + char[] chars = line.toCharArray(); + sendChars(sinkOutput, chars, 0, chars.length); + } bp = 0; } } @@ -432,7 +442,11 @@ public synchronized void write(int b) throws IOException { char[] data = readCharsOrNull(1); if (data != null) { char[] chars = console.readPassword(new String(data)); - sendChars(sinkOutput, chars, 0, chars.length); + if (chars == null) { + sendInt(sinkOutput, -1); + } else { + sendChars(sinkOutput, chars, 0, chars.length); + } bp = 0; } } diff --git a/src/jdk.jshell/share/classes/jdk/jshell/tool/resources/PREVIEW_DEFAULT.jsh b/src/jdk.jshell/share/classes/jdk/jshell/tool/resources/PREVIEW_DEFAULT.jsh index 4644ac86386..975d1215535 100644 --- a/src/jdk.jshell/share/classes/jdk/jshell/tool/resources/PREVIEW_DEFAULT.jsh +++ b/src/jdk.jshell/share/classes/jdk/jshell/tool/resources/PREVIEW_DEFAULT.jsh @@ -1 +1,2 @@ import module java.base; +import static java.io.IO.*; diff --git a/test/langtools/jdk/jshell/ConsoleToolTest.java b/test/langtools/jdk/jshell/ConsoleToolTest.java index 8fa85a3ec27..0af85a61862 100644 --- a/test/langtools/jdk/jshell/ConsoleToolTest.java +++ b/test/langtools/jdk/jshell/ConsoleToolTest.java @@ -23,7 +23,7 @@ /* * @test - * @bug 8331535 + * @bug 8331535 8341631 * @summary Test the JShell tool Console handling * @modules jdk.internal.le/jdk.internal.org.jline.reader * jdk.jshell/jdk.internal.jshell.tool:+open @@ -56,6 +56,40 @@ public void testOutput() { ); } + @Test //JDK-8341631 + public void testIO() { + test(new String[] {"--enable-preview"}, + a -> {assertCommandWithOutputAndTerminal(a, + "java.io.IO.readln(\"%%s\");\ninput", //newline automatically appended + "$1 ==> \"input\"", + """ + \u0005java.io.IO.readln(\"%%s\"); + %%sinput + """);}, + a -> {assertCommandWithOutputAndTerminal(a, + "java.io.IO.readln();\ninput!", //newline automatically appended + "$2 ==> \"input!\"", + """ + \u0005java.io.IO.readln(); + input! + """);}, + a -> {assertCommandWithOutputAndTerminal(a, + "java.io.IO.println(\"Hello, World!\");", + "", + """ + \u0005java.io.IO.println(\"Hello, World!\"); + Hello, World! + """);}, + a -> {assertCommandWithOutputAndTerminal(a, + "java.io.IO.println();", + "", + """ + \u0005java.io.IO.println(); + + """);} + ); + } + void assertCommandWithOutputAndTerminal(boolean a, String command, String out, String terminalOut) { assertCommand(a, command, out, null, null, null, null, terminalOut); } diff --git a/test/langtools/jdk/jshell/StartOptionTest.java b/test/langtools/jdk/jshell/StartOptionTest.java index 60926e69843..b84b454480e 100644 --- a/test/langtools/jdk/jshell/StartOptionTest.java +++ b/test/langtools/jdk/jshell/StartOptionTest.java @@ -22,7 +22,7 @@ */ /* - * @test 8151754 8080883 8160089 8170162 8166581 8172102 8171343 8178023 8186708 8179856 8185840 8190383 + * @test 8151754 8080883 8160089 8170162 8166581 8172102 8171343 8178023 8186708 8179856 8185840 8190383 8341631 * @summary Testing startExCe-up options. * @modules jdk.compiler/com.sun.tools.javac.api * jdk.compiler/com.sun.tools.javac.main @@ -366,14 +366,49 @@ public void testShowVersion() { } public void testPreviewEnabled() { - String fn = writeToFile("System.out.println(\"prefix\");\n" + - "System.out.println(MethodHandle.class.getName());\n" + - "System.out.println(\"suffix\");\n" + - "/exit\n"); + String fn = writeToFile( + """ + System.out.println(\"prefix\"); + System.out.println(MethodHandle.class.getName()); + System.out.println(\"suffix\"); + /exit + """); startCheckUserOutput(s -> assertEquals(s, "prefix\nsuffix\n"), fn); startCheckUserOutput(s -> assertEquals(s, "prefix\njava.lang.invoke.MethodHandle\nsuffix\n"), "--enable-preview", fn); + //JDK-8341631: + String fn2 = writeToFile( + """ + System.out.println(\"prefix\"); + IO.println(\"test\"); + System.out.println(\"suffix\"); + /exit + """); + startCheckUserOutput(s -> assertEquals(s, "prefix\nsuffix\n"), + fn2); + startCheckUserOutput(s -> assertEquals(s, "prefix\ntest\nsuffix\n"), + "--enable-preview", fn2); + } + public void testInput() { + //readLine(String): + String readLinePrompt = writeToFile( + """ + var v = System.console().readLine("prompt: "); + System.out.println(v); + /exit + """); + startCheckUserOutput(s -> assertEquals(s, "prompt: null\n"), + readLinePrompt); + //readPassword(String): + String readPasswordPrompt = writeToFile( + """ + var v = System.console().readPassword("prompt: "); + System.out.println(java.util.Arrays.toString(v)); + /exit + """); + startCheckUserOutput(s -> assertEquals(s, "prompt: null\n"), + readPasswordPrompt); } @AfterMethod From 3a4a9b7af7693a836c3caa3112d0d68100535b28 Mon Sep 17 00:00:00 2001 From: Aggelos Biboudis <abimpoudis@openjdk.org> Date: Wed, 20 Nov 2024 10:29:45 +0000 Subject: [PATCH 121/311] 8340145: Problem with generic pattern matching results in internal compiler error Reviewed-by: jlahoda --- .../com/sun/tools/javac/comp/Flow.java | 2 +- .../tools/javac/patterns/T8340145.java | 66 +++++++++++++++++++ 2 files changed, 67 insertions(+), 1 deletion(-) create mode 100644 test/langtools/tools/javac/patterns/T8340145.java diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Flow.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Flow.java index 29ab8435ada..df28548152a 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Flow.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Flow.java @@ -910,7 +910,7 @@ private Set<PatternDescription> reduceBindingPatterns(Type selectorType, Set<Pat Set<PatternDescription> toAdd = new HashSet<>(); for (Type sup : types.directSupertypes(bpOne.type)) { - ClassSymbol clazz = (ClassSymbol) sup.tsym; + ClassSymbol clazz = (ClassSymbol) types.erasure(sup).tsym; clazz.complete(); diff --git a/test/langtools/tools/javac/patterns/T8340145.java b/test/langtools/tools/javac/patterns/T8340145.java new file mode 100644 index 00000000000..04b12664b72 --- /dev/null +++ b/test/langtools/tools/javac/patterns/T8340145.java @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8340145 + * @summary Problem with generic pattern matching results in internal compiler error + * @compile T8340145.java + * @run main T8340145 + */ +public class T8340145 { + public static void main(String[] args) { + Option<Integer> optionInteger = new Option.Some<>(21); + Number number = Option.unwrapOrElse(optionInteger, 5.2); + + Option2<Impl> optionBound = new Option2.Some<>(new Impl (){}); + Bound number2 = Option2.unwrapOrElse(optionBound, new Impl(){}); + } + + sealed interface Option<T> permits Option.Some, Option.None { + record Some<T>(T value) implements Option<T> {} + record None<T>() implements Option<T> {} + + static <T, T2 extends T> T unwrapOrElse(Option<T2> option, T defaultValue) { + return switch (option) { + case Option.Some(T2 value) -> value; + case Option.None<T2> _ -> defaultValue; + }; + } + } + + interface Bound {} + interface Bound2 {} + static class Impl implements Bound, Bound2 {} + sealed interface Option2<T> permits Option2.Some, Option2.None { + record Some<T>(T value) implements Option2<T> {} + record None<T>() implements Option2<T> {} + + static <T extends Bound & Bound2> T unwrapOrElse(Option2<T> option, T defaultValue) { + return switch (option) { + case Option2.Some(T value) -> value; + case Option2.None<T> _ -> defaultValue; + }; + } + } +} From afee7405bd13cbe1cb829dd150a9de7e6faf49ae Mon Sep 17 00:00:00 2001 From: Xiaolong Peng <xpeng@openjdk.org> Date: Wed, 20 Nov 2024 10:34:07 +0000 Subject: [PATCH 122/311] 8343541: C1: Plain memory accesses are emitted with membars with +AlwaysAtomicAccesses Reviewed-by: shade, vlivanov --- src/hotspot/share/gc/shared/c1/barrierSetC1.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/hotspot/share/gc/shared/c1/barrierSetC1.cpp b/src/hotspot/share/gc/shared/c1/barrierSetC1.cpp index fbaef426b51..8eaa23ab476 100644 --- a/src/hotspot/share/gc/shared/c1/barrierSetC1.cpp +++ b/src/hotspot/share/gc/shared/c1/barrierSetC1.cpp @@ -140,7 +140,8 @@ LIR_Opr BarrierSetC1::atomic_add_at(LIRAccess& access, LIRItem& value) { void BarrierSetC1::store_at_resolved(LIRAccess& access, LIR_Opr value) { DecoratorSet decorators = access.decorators(); - bool is_volatile = (((decorators & MO_SEQ_CST) != 0) || AlwaysAtomicAccesses); + bool is_volatile = (decorators & MO_SEQ_CST) != 0; + bool is_atomic = is_volatile || AlwaysAtomicAccesses; bool needs_patching = (decorators & C1_NEEDS_PATCHING) != 0; bool mask_boolean = (decorators & C1_MASK_BOOLEAN) != 0; LIRGenerator* gen = access.gen(); @@ -154,7 +155,7 @@ void BarrierSetC1::store_at_resolved(LIRAccess& access, LIR_Opr value) { } LIR_PatchCode patch_code = needs_patching ? lir_patch_normal : lir_patch_none; - if (is_volatile && !needs_patching) { + if (is_atomic && !needs_patching) { gen->volatile_field_store(value, access.resolved_addr()->as_address_ptr(), access.access_emit_info()); } else { __ store(value, access.resolved_addr()->as_address_ptr(), access.access_emit_info(), patch_code); @@ -168,7 +169,8 @@ void BarrierSetC1::store_at_resolved(LIRAccess& access, LIR_Opr value) { void BarrierSetC1::load_at_resolved(LIRAccess& access, LIR_Opr result) { LIRGenerator *gen = access.gen(); DecoratorSet decorators = access.decorators(); - bool is_volatile = (((decorators & MO_SEQ_CST) != 0) || AlwaysAtomicAccesses); + bool is_volatile = (decorators & MO_SEQ_CST) != 0; + bool is_atomic = is_volatile || AlwaysAtomicAccesses; bool needs_patching = (decorators & C1_NEEDS_PATCHING) != 0; bool mask_boolean = (decorators & C1_MASK_BOOLEAN) != 0; bool in_native = (decorators & IN_NATIVE) != 0; @@ -180,7 +182,7 @@ void BarrierSetC1::load_at_resolved(LIRAccess& access, LIR_Opr result) { LIR_PatchCode patch_code = needs_patching ? lir_patch_normal : lir_patch_none; if (in_native) { __ move_wide(access.resolved_addr()->as_address_ptr(), result); - } else if (is_volatile && !needs_patching) { + } else if (is_atomic && !needs_patching) { gen->volatile_field_load(access.resolved_addr()->as_address_ptr(), result, access.access_emit_info()); } else { __ load(access.resolved_addr()->as_address_ptr(), result, access.access_emit_info(), patch_code); From e2f8f1aded319034a79fe78af7e011e83df75d62 Mon Sep 17 00:00:00 2001 From: David Holmes <dholmes@openjdk.org> Date: Wed, 20 Nov 2024 11:51:52 +0000 Subject: [PATCH 123/311] 8344621: ProblemList runtime/CommandLine/OptionsValidation/TestOptionsWithRanges.java Reviewed-by: jpai --- test/hotspot/jtreg/ProblemList.txt | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/test/hotspot/jtreg/ProblemList.txt b/test/hotspot/jtreg/ProblemList.txt index d3de1f871e8..f2f1c4f2f50 100644 --- a/test/hotspot/jtreg/ProblemList.txt +++ b/test/hotspot/jtreg/ProblemList.txt @@ -100,6 +100,17 @@ gc/stress/gclocker/TestExcessGCLockerCollections.java 8229120 generic-all # :hotspot_runtime +runtime/CommandLine/OptionsValidation/TestOptionsWithRanges.java#id0 8344583 macosx-aarch64 +runtime/CommandLine/OptionsValidation/TestOptionsWithRanges.java#id1 8344583 macosx-aarch64 +runtime/CommandLine/OptionsValidation/TestOptionsWithRanges.java#id2 8344583 macosx-aarch64 +runtime/CommandLine/OptionsValidation/TestOptionsWithRanges.java#id3 8344583 macosx-aarch64 +runtime/CommandLine/OptionsValidation/TestOptionsWithRanges.java#id4 8344583 macosx-aarch64 +runtime/CommandLine/OptionsValidation/TestOptionsWithRanges.java#id5 8344583 macosx-aarch64 +runtime/CommandLine/OptionsValidation/TestOptionsWithRanges.java#id6 8344583 macosx-aarch64 +runtime/CommandLine/OptionsValidation/TestOptionsWithRanges.java#id7 8344583 macosx-aarch64 +runtime/CommandLine/OptionsValidation/TestOptionsWithRanges.java#id8 8344583 macosx-aarch64 +runtime/CommandLine/OptionsValidation/TestOptionsWithRanges.java#id9 8344583 macosx-aarch64 + runtime/jni/terminatedThread/TestTerminatedThread.java 8317789 aix-ppc64 runtime/handshake/HandshakeSuspendExitTest.java 8294313 generic-all runtime/Monitor/SyncOnValueBasedClassTest.java 8340995 linux-s390x From ea7e722ca04752f0b58bf98e0a1907c015644fb5 Mon Sep 17 00:00:00 2001 From: Robbin Ehn <rehn@openjdk.org> Date: Wed, 20 Nov 2024 12:05:53 +0000 Subject: [PATCH 124/311] 8344010: RISC-V: Zacas do not work with LW locking Reviewed-by: fyang, mli --- .../cpu/riscv/macroAssembler_riscv.cpp | 102 +++++------------- .../cpu/riscv/macroAssembler_riscv.hpp | 10 -- 2 files changed, 25 insertions(+), 87 deletions(-) diff --git a/src/hotspot/cpu/riscv/macroAssembler_riscv.cpp b/src/hotspot/cpu/riscv/macroAssembler_riscv.cpp index ac0445e5e4e..81d3338638d 100644 --- a/src/hotspot/cpu/riscv/macroAssembler_riscv.cpp +++ b/src/hotspot/cpu/riscv/macroAssembler_riscv.cpp @@ -3466,6 +3466,17 @@ void MacroAssembler::cmpxchg(Register addr, Register expected, assert_different_registers(expected, t0); assert_different_registers(new_val, t0); + // NOTE: + // Register _result_ may be the same register as _new_val_ or _expected_. + // Hence do NOT use _result_ until after 'cas'. + // + // Register _expected_ may be the same register as _new_val_ and is assumed to be preserved. + // Hence do NOT change _expected_ or _new_val_. + // + // Having _expected_ and _new_val_ being the same register is a very puzzling cas. + // + // TODO: Address these issues. + if (UseZacas) { if (result_as_bool) { mv(t0, expected); @@ -3473,8 +3484,9 @@ void MacroAssembler::cmpxchg(Register addr, Register expected, xorr(t0, t0, expected); seqz(result, t0); } else { - mv(result, expected); - atomic_cas(result, new_val, addr, size, acquire, release); + mv(t0, expected); + atomic_cas(t0, new_val, addr, size, acquire, release); + mv(result, t0); } return; } @@ -3510,15 +3522,16 @@ void MacroAssembler::cmpxchg_weak(Register addr, Register expected, enum operand_size size, Assembler::Aqrl acquire, Assembler::Aqrl release, Register result) { - if (UseZacas) { - cmpxchg(addr, expected, new_val, size, acquire, release, result, true); - return; - } assert_different_registers(addr, t0); assert_different_registers(expected, t0); assert_different_registers(new_val, t0); + if (UseZacas) { + cmpxchg(addr, expected, new_val, size, acquire, release, result, true); + return; + } + Label fail, done; load_reserved(t0, addr, size, acquire); bne(t0, expected, fail); @@ -3581,83 +3594,18 @@ ATOMIC_XCHGU(xchgalwu, xchgalw) #undef ATOMIC_XCHGU -#define ATOMIC_CAS(OP, AOP, ACQUIRE, RELEASE) \ -void MacroAssembler::atomic_##OP(Register prev, Register newv, Register addr) { \ - assert(UseZacas, "invariant"); \ - prev = prev->is_valid() ? prev : zr; \ - AOP(prev, addr, newv, (Assembler::Aqrl)(ACQUIRE | RELEASE)); \ - return; \ -} - -ATOMIC_CAS(cas, amocas_d, Assembler::relaxed, Assembler::relaxed) -ATOMIC_CAS(casw, amocas_w, Assembler::relaxed, Assembler::relaxed) -ATOMIC_CAS(casl, amocas_d, Assembler::relaxed, Assembler::rl) -ATOMIC_CAS(caslw, amocas_w, Assembler::relaxed, Assembler::rl) -ATOMIC_CAS(casal, amocas_d, Assembler::aq, Assembler::rl) -ATOMIC_CAS(casalw, amocas_w, Assembler::aq, Assembler::rl) - -#undef ATOMIC_CAS - -#define ATOMIC_CASU(OP1, OP2) \ -void MacroAssembler::atomic_##OP1(Register prev, Register newv, Register addr) { \ - atomic_##OP2(prev, newv, addr); \ - zero_extend(prev, prev, 32); \ - return; \ -} - -ATOMIC_CASU(caswu, casw) -ATOMIC_CASU(caslwu, caslw) -ATOMIC_CASU(casalwu, casalw) - -#undef ATOMIC_CASU - -void MacroAssembler::atomic_cas( - Register prev, Register newv, Register addr, enum operand_size size, Assembler::Aqrl acquire, Assembler::Aqrl release) { +void MacroAssembler::atomic_cas(Register prev, Register newv, Register addr, + enum operand_size size, Assembler::Aqrl acquire, Assembler::Aqrl release) { switch (size) { case int64: - switch ((Assembler::Aqrl)(acquire | release)) { - case Assembler::relaxed: - atomic_cas(prev, newv, addr); - break; - case Assembler::rl: - atomic_casl(prev, newv, addr); - break; - case Assembler::aqrl: - atomic_casal(prev, newv, addr); - break; - default: - ShouldNotReachHere(); - } + amocas_d(prev, addr, newv, (Assembler::Aqrl)(acquire | release)); break; case int32: - switch ((Assembler::Aqrl)(acquire | release)) { - case Assembler::relaxed: - atomic_casw(prev, newv, addr); - break; - case Assembler::rl: - atomic_caslw(prev, newv, addr); - break; - case Assembler::aqrl: - atomic_casalw(prev, newv, addr); - break; - default: - ShouldNotReachHere(); - } + amocas_w(prev, addr, newv, (Assembler::Aqrl)(acquire | release)); break; case uint32: - switch ((Assembler::Aqrl)(acquire | release)) { - case Assembler::relaxed: - atomic_caswu(prev, newv, addr); - break; - case Assembler::rl: - atomic_caslwu(prev, newv, addr); - break; - case Assembler::aqrl: - atomic_casalwu(prev, newv, addr); - break; - default: - ShouldNotReachHere(); - } + amocas_w(prev, addr, newv, (Assembler::Aqrl)(acquire | release)); + zero_extend(prev, prev, 32); break; default: ShouldNotReachHere(); diff --git a/src/hotspot/cpu/riscv/macroAssembler_riscv.hpp b/src/hotspot/cpu/riscv/macroAssembler_riscv.hpp index dc06708b0ff..568df056222 100644 --- a/src/hotspot/cpu/riscv/macroAssembler_riscv.hpp +++ b/src/hotspot/cpu/riscv/macroAssembler_riscv.hpp @@ -1175,16 +1175,6 @@ class MacroAssembler: public Assembler { void atomic_xchgwu(Register prev, Register newv, Register addr); void atomic_xchgalwu(Register prev, Register newv, Register addr); - void atomic_cas(Register prev, Register newv, Register addr); - void atomic_casw(Register prev, Register newv, Register addr); - void atomic_casl(Register prev, Register newv, Register addr); - void atomic_caslw(Register prev, Register newv, Register addr); - void atomic_casal(Register prev, Register newv, Register addr); - void atomic_casalw(Register prev, Register newv, Register addr); - void atomic_caswu(Register prev, Register newv, Register addr); - void atomic_caslwu(Register prev, Register newv, Register addr); - void atomic_casalwu(Register prev, Register newv, Register addr); - void atomic_cas(Register prev, Register newv, Register addr, enum operand_size size, Assembler::Aqrl acquire = Assembler::relaxed, Assembler::Aqrl release = Assembler::relaxed); From 21b8749bfdede7dfee3e8433dd9443320db99076 Mon Sep 17 00:00:00 2001 From: Coleen Phillimore <coleenp@openjdk.org> Date: Wed, 20 Nov 2024 12:21:41 +0000 Subject: [PATCH 125/311] 8344479: Declare MetaspaceObj::operator delete to be deleted Reviewed-by: stefank, kbarrett, jwaters --- src/hotspot/share/memory/allocation.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hotspot/share/memory/allocation.hpp b/src/hotspot/share/memory/allocation.hpp index 9841ce3183c..ae834ec9a72 100644 --- a/src/hotspot/share/memory/allocation.hpp +++ b/src/hotspot/share/memory/allocation.hpp @@ -353,7 +353,7 @@ class MetaspaceObj { void* operator new(size_t size, ClassLoaderData* loader_data, size_t word_size, Type type) throw(); - void operator delete(void* p) { ShouldNotCallThis(); } + void operator delete(void* p) = delete; // Declare a *static* method with the same signature in any subclass of MetaspaceObj // that should be read-only by default. See symbol.hpp for an example. This function From 7bb4474d81a55028de5434f445747c56a8dc333c Mon Sep 17 00:00:00 2001 From: Coleen Phillimore <coleenp@openjdk.org> Date: Wed, 20 Nov 2024 12:22:43 +0000 Subject: [PATCH 126/311] 8344579: Clean up forward declarations and includes Reviewed-by: stefank --- src/hotspot/share/oops/instanceKlass.hpp | 2 -- src/hotspot/share/oops/klass.hpp | 4 ---- src/hotspot/share/oops/method.hpp | 1 - src/hotspot/share/runtime/vmStructs.cpp | 1 - 4 files changed, 8 deletions(-) diff --git a/src/hotspot/share/oops/instanceKlass.hpp b/src/hotspot/share/oops/instanceKlass.hpp index b3283a04d44..13b50859ee3 100644 --- a/src/hotspot/share/oops/instanceKlass.hpp +++ b/src/hotspot/share/oops/instanceKlass.hpp @@ -45,7 +45,6 @@ class ConstantPool; class DeoptimizationScope; class klassItable; -class Monitor; class RecordComponent; // An InstanceKlass is the VM level representation of a Java class. @@ -68,7 +67,6 @@ class ClassFileStream; class KlassDepChange; class DependencyContext; class fieldDescriptor; -class jniIdMapBase; class JNIid; class JvmtiCachedClassFieldMap; class nmethodBucket; diff --git a/src/hotspot/share/oops/klass.hpp b/src/hotspot/share/oops/klass.hpp index 8c128ab9ce6..2c75d6da3b8 100644 --- a/src/hotspot/share/oops/klass.hpp +++ b/src/hotspot/share/oops/klass.hpp @@ -25,8 +25,6 @@ #ifndef SHARE_OOPS_KLASS_HPP #define SHARE_OOPS_KLASS_HPP -#include "memory/iterator.hpp" -#include "memory/memRegion.hpp" #include "oops/klassFlags.hpp" #include "oops/markWord.hpp" #include "oops/metadata.hpp" @@ -60,8 +58,6 @@ class fieldDescriptor; class klassVtable; class ModuleEntry; class PackageEntry; -class ParCompactionManager; -class PSPromotionManager; class vtableEntry; class Klass : public Metadata { diff --git a/src/hotspot/share/oops/method.hpp b/src/hotspot/share/oops/method.hpp index cc3caccd16a..271d8b39863 100644 --- a/src/hotspot/share/oops/method.hpp +++ b/src/hotspot/share/oops/method.hpp @@ -32,7 +32,6 @@ #include "oops/methodFlags.hpp" #include "oops/instanceKlass.hpp" #include "oops/oop.hpp" -#include "oops/typeArrayOop.hpp" #include "utilities/accessFlags.hpp" #include "utilities/align.hpp" #include "utilities/growableArray.hpp" diff --git a/src/hotspot/share/runtime/vmStructs.cpp b/src/hotspot/share/runtime/vmStructs.cpp index bc941534242..a1c1551ae09 100644 --- a/src/hotspot/share/runtime/vmStructs.cpp +++ b/src/hotspot/share/runtime/vmStructs.cpp @@ -1930,7 +1930,6 @@ declare_toplevel_type(jbyte*) \ declare_toplevel_type(jbyte**) \ declare_toplevel_type(jint*) \ - declare_toplevel_type(jniIdMapBase*) \ declare_unsigned_integer_type(juint) \ declare_unsigned_integer_type(julong) \ declare_toplevel_type(JNIHandleBlock*) \ From 6f4dfa66268c7aef0298af7f18d8e8bd4eb21656 Mon Sep 17 00:00:00 2001 From: Jaikiran Pai <jpai@openjdk.org> Date: Wed, 20 Nov 2024 12:29:32 +0000 Subject: [PATCH 127/311] 8344190: Cleanup code in sun.net.www.protocol.http and sun.net.www.protocol.https after JEP 486 integration Reviewed-by: dfuchs --- .../protocol/http/AuthenticationHeader.java | 5 +- .../www/protocol/http/AuthenticationInfo.java | 9 +- .../protocol/http/BasicAuthentication.java | 10 +- .../protocol/http/DigestAuthentication.java | 28 +- .../www/protocol/http/HttpURLConnection.java | 558 ++++-------------- .../http/NegotiateAuthentication.java | 14 +- .../net/www/protocol/https/HttpsClient.java | 122 +--- .../http/ntlm/NTLMAuthentication.java | 4 +- .../http/ntlm/NTLMAuthentication.java | 48 +- 9 files changed, 129 insertions(+), 669 deletions(-) diff --git a/src/java.base/share/classes/sun/net/www/protocol/http/AuthenticationHeader.java b/src/java.base/share/classes/sun/net/www/protocol/http/AuthenticationHeader.java index 8083fb36f39..8bccc53cafc 100644 --- a/src/java.base/share/classes/sun/net/www/protocol/http/AuthenticationHeader.java +++ b/src/java.base/share/classes/sun/net/www/protocol/http/AuthenticationHeader.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -32,7 +32,6 @@ import java.util.Set; import sun.net.www.*; -import sun.security.action.GetPropertyAction; /** * This class is used to parse the information in WWW-Authenticate: and Proxy-Authenticate: @@ -98,7 +97,7 @@ public String toString() { } static { - String pref = GetPropertyAction.privilegedGetProperty("http.auth.preference"); + String pref = System.getProperty("http.auth.preference"); // http.auth.preference can be set to SPNEGO or Kerberos. // In fact they means "Negotiate with SPNEGO" and "Negotiate with diff --git a/src/java.base/share/classes/sun/net/www/protocol/http/AuthenticationInfo.java b/src/java.base/share/classes/sun/net/www/protocol/http/AuthenticationInfo.java index 4a2b5b628c6..f567d7bd643 100644 --- a/src/java.base/share/classes/sun/net/www/protocol/http/AuthenticationInfo.java +++ b/src/java.base/share/classes/sun/net/www/protocol/http/AuthenticationInfo.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1995, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1995, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,8 +25,6 @@ package sun.net.www.protocol.http; -import java.io.IOException; -import java.io.ObjectInputStream; import java.net.PasswordAuthentication; import java.net.URL; import java.util.HashMap; @@ -67,10 +65,7 @@ public abstract class AuthenticationInfo extends AuthCacheValue implements Clone * repeatedly, via the Authenticator. Default is false, which means that this * behavior is switched off. */ - @SuppressWarnings("removal") - static final boolean serializeAuth = java.security.AccessController.doPrivileged( - new sun.security.action.GetBooleanAction( - "http.auth.serializeRequests")).booleanValue(); + static final boolean serializeAuth = Boolean.getBoolean("http.auth.serializeRequests"); /* AuthCacheValue: */ diff --git a/src/java.base/share/classes/sun/net/www/protocol/http/BasicAuthentication.java b/src/java.base/share/classes/sun/net/www/protocol/http/BasicAuthentication.java index 73d5ff98b3a..f008c185b5d 100644 --- a/src/java.base/share/classes/sun/net/www/protocol/http/BasicAuthentication.java +++ b/src/java.base/share/classes/sun/net/www/protocol/http/BasicAuthentication.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -32,11 +32,8 @@ import java.nio.ByteBuffer; import java.nio.CharBuffer; import java.nio.charset.Charset; -import java.io.IOException; -import java.io.OutputStream; import java.util.Arrays; import java.util.Base64; -import java.util.Objects; import sun.net.www.HeaderParser; import sun.nio.cs.ISO_8859_1; import sun.nio.cs.UTF_8; @@ -49,10 +46,7 @@ */ -class BasicAuthentication extends AuthenticationInfo { - - @java.io.Serial - private static final long serialVersionUID = 100L; +final class BasicAuthentication extends AuthenticationInfo { /** The authentication string for this host, port, and realm. This is a simple BASE64 encoding of "login:password". */ diff --git a/src/java.base/share/classes/sun/net/www/protocol/http/DigestAuthentication.java b/src/java.base/share/classes/sun/net/www/protocol/http/DigestAuthentication.java index faee05b4dfd..28d7bc5cf4e 100644 --- a/src/java.base/share/classes/sun/net/www/protocol/http/DigestAuthentication.java +++ b/src/java.base/share/classes/sun/net/www/protocol/http/DigestAuthentication.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -35,17 +35,13 @@ import java.nio.charset.Charset; import java.nio.charset.CharsetEncoder; import java.nio.charset.StandardCharsets; -import java.security.AccessController; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; -import java.security.PrivilegedAction; import java.security.Security; import java.text.Normalizer; import java.util.Arrays; -import java.util.Collections; import java.util.HashSet; import java.util.Locale; -import java.util.Objects; import java.util.Random; import java.util.Set; import java.util.function.BiConsumer; @@ -65,10 +61,7 @@ * @author Bill Foote */ -class DigestAuthentication extends AuthenticationInfo { - - @java.io.Serial - private static final long serialVersionUID = 100L; +final class DigestAuthentication extends AuthenticationInfo { private String authMethod; @@ -110,26 +103,15 @@ private static void processPropValue(String input, HttpURLConnection.getHttpLogger(); static { - @SuppressWarnings("removal") - Boolean b = AccessController.doPrivileged( - (PrivilegedAction<Boolean>) () -> NetProperties.getBoolean(compatPropName) - ); + Boolean b = NetProperties.getBoolean(compatPropName); delimCompatFlag = (b == null) ? false : b.booleanValue(); - @SuppressWarnings("removal") - String secprops = AccessController.doPrivileged( - (PrivilegedAction<String>) () -> Security.getProperty(secPropName) - ); - + String secprops = Security.getProperty(secPropName); Set<String> algs = new HashSet<>(); - // add the default insecure algorithms to set processPropValue(secprops, algs, (set, elem) -> set.add(elem)); - @SuppressWarnings("removal") - String netprops = AccessController.doPrivileged( - (PrivilegedAction<String>) () -> NetProperties.get(enabledAlgPropName) - ); + String netprops = NetProperties.get(enabledAlgPropName); // remove any algorithms from disabled set that were opted-in by user processPropValue(netprops, algs, (set, elem) -> set.remove(elem)); disabledDigests = Set.copyOf(algs); diff --git a/src/java.base/share/classes/sun/net/www/protocol/http/HttpURLConnection.java b/src/java.base/share/classes/sun/net/www/protocol/http/HttpURLConnection.java index 83511853502..602f798448c 100644 --- a/src/java.base/share/classes/sun/net/www/protocol/http/HttpURLConnection.java +++ b/src/java.base/share/classes/sun/net/www/protocol/http/HttpURLConnection.java @@ -25,7 +25,6 @@ package sun.net.www.protocol.http; -import java.security.PrivilegedAction; import java.util.Arrays; import java.net.URL; import java.net.URLConnection; @@ -37,7 +36,6 @@ import java.net.InetAddress; import java.net.UnknownHostException; import java.net.SocketTimeoutException; -import java.net.SocketPermission; import java.net.Proxy; import java.net.ProxySelector; import java.net.URI; @@ -47,11 +45,7 @@ import java.net.CacheResponse; import java.net.SecureCacheResponse; import java.net.CacheRequest; -import java.net.URLPermission; import java.net.Authenticator.RequestorType; -import java.security.AccessController; -import java.security.PrivilegedExceptionAction; -import java.security.PrivilegedActionException; import java.io.*; import java.util.ArrayList; import java.util.Collections; @@ -81,7 +75,6 @@ import java.net.MalformedURLException; import java.nio.ByteBuffer; import java.util.Objects; -import java.util.Properties; import java.util.concurrent.locks.ReentrantLock; import static sun.net.www.protocol.http.AuthScheme.BASIC; @@ -90,8 +83,6 @@ import static sun.net.www.protocol.http.AuthScheme.NEGOTIATE; import static sun.net.www.protocol.http.AuthScheme.KERBEROS; import static sun.net.www.protocol.http.AuthScheme.UNKNOWN; -import sun.security.action.GetIntegerAction; -import sun.security.action.GetPropertyAction; /** * A class to represent an HTTP connection to a remote object. @@ -178,8 +169,7 @@ public class HttpURLConnection extends java.net.HttpURLConnection { * Restrict setting of request headers through the public api * consistent with JavaScript XMLHttpRequest2 with a few * exceptions. Disallowed headers are silently ignored for - * backwards compatibility reasons rather than throwing a - * SecurityException. For example, some applets set the + * backwards compatibility reasons. For example, some applets set the * Host header since old JREs did not implement HTTP 1.1. * Additionally, any header starting with Sec- is * disallowed. @@ -222,12 +212,6 @@ public class HttpURLConnection extends java.net.HttpURLConnection { "Via" }; - @SuppressWarnings("removal") - private static String getNetProperty(String name) { - PrivilegedAction<String> pa = () -> NetProperties.get(name); - return AccessController.doPrivileged(pa); - } - private static Set<String> schemesListToSet(String list) { if (list == null || list.isEmpty()) return Collections.emptySet(); @@ -240,11 +224,9 @@ private static Set<String> schemesListToSet(String list) { } static { - Properties props = GetPropertyAction.privilegedGetProperties(); - maxRedirects = GetIntegerAction.privilegedGetProperty( - "http.maxRedirects", defaultmaxRedirects); - version = props.getProperty("java.version"); - String agent = props.getProperty("http.agent"); + maxRedirects = Integer.getInteger("http.maxRedirects", defaultmaxRedirects); + version = System.getProperty("java.version"); + String agent = System.getProperty("http.agent"); if (agent == null) { agent = "Java/"+version; } else { @@ -254,34 +236,30 @@ private static Set<String> schemesListToSet(String list) { // A set of net properties to control the use of authentication schemes // when proxying/tunneling. - String p = getNetProperty("jdk.http.auth.tunneling.disabledSchemes"); + String p = NetProperties.get("jdk.http.auth.tunneling.disabledSchemes"); disabledTunnelingSchemes = schemesListToSet(p); - p = getNetProperty("jdk.http.auth.proxying.disabledSchemes"); + p = NetProperties.get("jdk.http.auth.proxying.disabledSchemes"); disabledProxyingSchemes = schemesListToSet(p); - validateProxy = Boolean.parseBoolean( - props.getProperty("http.auth.digest.validateProxy")); - validateServer = Boolean.parseBoolean( - props.getProperty("http.auth.digest.validateServer")); + validateProxy = Boolean.getBoolean("http.auth.digest.validateProxy"); + validateServer = Boolean.getBoolean("http.auth.digest.validateServer"); - enableESBuffer = Boolean.parseBoolean( - props.getProperty("sun.net.http.errorstream.enableBuffering")); - int esBufferTimeout = GetIntegerAction.privilegedGetProperty( + enableESBuffer = Boolean.getBoolean("sun.net.http.errorstream.enableBuffering"); + int esBufferTimeout = Integer.getInteger( "sun.net.http.errorstream.timeout", 300); if (esBufferTimeout <= 0) { esBufferTimeout = 300; // use the default } timeout4ESBuffer = esBufferTimeout; - int esBufSize = GetIntegerAction.privilegedGetProperty( + int esBufSize = Integer.getInteger( "sun.net.http.errorstream.bufferSize", 4096); if (esBufSize <= 0) { esBufSize = 4096; // use the default } bufSize4ES = esBufSize; - allowRestrictedHeaders = Boolean.parseBoolean( - props.getProperty("sun.net.http.allowRestrictedHeaders")); + allowRestrictedHeaders = Boolean.getBoolean("sun.net.http.allowRestrictedHeaders"); if (!allowRestrictedHeaders) { restrictedHeaderSet = HashSet.newHashSet(restrictedHeaders.length); for (int i=0; i < restrictedHeaders.length; i++) { @@ -292,7 +270,7 @@ private static Set<String> schemesListToSet(String list) { } int defMaxHeaderSize = 384 * 1024; - String maxHeaderSizeStr = getNetProperty("jdk.http.maxHeaderSize"); + String maxHeaderSizeStr = NetProperties.get("jdk.http.maxHeaderSize"); int maxHeaderSizeVal = defMaxHeaderSize; if (maxHeaderSizeStr != null) { try { @@ -439,9 +417,6 @@ public enum TunnelState { private int connectTimeout = NetworkClient.DEFAULT_CONNECT_TIMEOUT; private int readTimeout = NetworkClient.DEFAULT_READ_TIMEOUT; - /* A permission converted from a URLPermission */ - private SocketPermission socketPermission; - /* Logging support */ private static final PlatformLogger logger = PlatformLogger.getLogger("sun.net.www.protocol.http.HttpURLConnection"); @@ -462,36 +437,30 @@ public final boolean isLockHeldByCurrentThread() { } /* - * privileged request password authentication + * Calls Authenticator.requestPasswordAuthentication * */ - @SuppressWarnings("removal") - private static PasswordAuthentication - privilegedRequestPasswordAuthentication( - final Authenticator authenticator, - final String host, - final InetAddress addr, - final int port, - final String protocol, - final String prompt, - final String scheme, - final URL url, - final RequestorType authType) { - return java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction<>() { - public PasswordAuthentication run() { - if (logger.isLoggable(PlatformLogger.Level.FINEST)) { - logger.finest("Requesting Authentication: host =" + host + " url = " + url); - } - PasswordAuthentication pass = Authenticator.requestPasswordAuthentication( - authenticator, host, addr, port, protocol, - prompt, scheme, url, authType); - if (logger.isLoggable(PlatformLogger.Level.FINEST)) { - logger.finest("Authentication returned: " + (pass != null ? pass.toString() : "null")); - } - return pass; - } - }); + private static PasswordAuthentication requestPassword( + final Authenticator authenticator, + final String host, + final InetAddress addr, + final int port, + final String protocol, + final String prompt, + final String scheme, + final URL url, + final RequestorType authType) { + + if (logger.isLoggable(PlatformLogger.Level.FINEST)) { + logger.finest("Requesting Authentication: host =" + host + " url = " + url); + } + PasswordAuthentication pass = Authenticator.requestPasswordAuthentication( + authenticator, host, addr, port, protocol, + prompt, scheme, url, authType); + if (logger.isLoggable(PlatformLogger.Level.FINEST)) { + logger.finest("Authentication returned: " + (pass != null ? pass.toString() : "null")); + } + return pass; } private boolean isRestrictedHeader(String key, String value) { @@ -640,7 +609,6 @@ private void writeRequests() throws IOException { if (requestLineIndex != 0) { // we expect the request line to be at index 0. we set it here // if we don't find the request line at that index. - checkURLFile(); requests.prepend(requestLine, null); } if (!getUseCaches()) { @@ -654,9 +622,7 @@ private void writeRequests() throws IOException { host += ":" + String.valueOf(port); } String reqHost = requests.findValue("Host"); - if (reqHost == null || - (!reqHost.equalsIgnoreCase(host) && !checkSetHost())) - { + if (reqHost == null || !reqHost.equalsIgnoreCase(host)) { requests.set("Host", host); } requests.setIfNotSet("Accept", acceptString); @@ -776,47 +742,6 @@ private void writeRequests() throws IOException { } } - private boolean checkSetHost() { - @SuppressWarnings("removal") - SecurityManager s = System.getSecurityManager(); - if (s != null) { - String name = s.getClass().getName(); - if (name.equals("sun.plugin2.applet.AWTAppletSecurityManager") || - name.equals("sun.plugin2.applet.FXAppletSecurityManager") || - name.equals("com.sun.javaws.security.JavaWebStartSecurity") || - name.equals("sun.plugin.security.ActivatorSecurityManager")) - { - int CHECK_SET_HOST = -2; - try { - s.checkConnect(url.toExternalForm(), CHECK_SET_HOST); - } catch (SecurityException ex) { - return false; - } - } - } - return true; - } - - private void checkURLFile() { - @SuppressWarnings("removal") - SecurityManager s = System.getSecurityManager(); - if (s != null) { - String name = s.getClass().getName(); - if (name.equals("sun.plugin2.applet.AWTAppletSecurityManager") || - name.equals("sun.plugin2.applet.FXAppletSecurityManager") || - name.equals("com.sun.javaws.security.JavaWebStartSecurity") || - name.equals("sun.plugin.security.ActivatorSecurityManager")) - { - int CHECK_SUBPATH = -3; - try { - s.checkConnect(url.toExternalForm(), CHECK_SUBPATH); - } catch (SecurityException ex) { - throw new SecurityException("denied access outside a permitted URL subpath", ex); - } - } - } - } - /** * Create a new HttpClient object, bypassing the cache of * HTTP client objects/connections. @@ -922,7 +847,6 @@ private static URL checkURL(URL u) throws IOException { return u; } - @SuppressWarnings("removal") protected HttpURLConnection(URL u, Proxy p, Handler handler) throws IOException { super(checkURL(u)); @@ -931,119 +855,8 @@ protected HttpURLConnection(URL u, Proxy p, Handler handler) userHeaders = new MessageHeader(); this.handler = handler; instProxy = p; - if (instProxy instanceof sun.net.ApplicationProxy) { - /* Application set Proxies should not have access to cookies - * in a secure environment unless explicitly allowed. */ - try { - cookieHandler = CookieHandler.getDefault(); - } catch (SecurityException se) { /* swallow exception */ } - } else { - cookieHandler = java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction<>() { - public CookieHandler run() { - return CookieHandler.getDefault(); - } - }); - } - cacheHandler = java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction<>() { - public ResponseCache run() { - return ResponseCache.getDefault(); - } - }); - } - - /** - * opens a stream allowing redirects only to the same host. - */ - public static InputStream openConnectionCheckRedirects(URLConnection c) - throws IOException - { - boolean redir; - int redirects = 0; - InputStream in; - Authenticator a = null; - - do { - if (c instanceof HttpURLConnection) { - ((HttpURLConnection) c).setInstanceFollowRedirects(false); - if (a == null) { - a = ((HttpURLConnection) c).authenticator; - } - } - - // We want to open the input stream before - // getting headers, because getHeaderField() - // et al swallow IOExceptions. - in = c.getInputStream(); - redir = false; - - if (c instanceof HttpURLConnection) { - HttpURLConnection http = (HttpURLConnection) c; - int stat = http.getResponseCode(); - if (stat >= 300 && stat <= 307 && stat != 306 && - stat != HttpURLConnection.HTTP_NOT_MODIFIED) { - URL base = http.getURL(); - String loc = http.getHeaderField("Location"); - URL target = null; - if (loc != null) { - target = newURL(base, loc); - } - http.disconnect(); - if (target == null - || !base.getProtocol().equals(target.getProtocol()) - || base.getPort() != target.getPort() - || !hostsEqual(base, target) - || redirects >= 5) - { - throw new SecurityException("illegal URL redirect"); - } - redir = true; - c = target.openConnection(); - if (a != null && c instanceof HttpURLConnection) { - ((HttpURLConnection)c).setAuthenticator(a); - } - redirects++; - } - } - } while (redir); - return in; - } - - - // - // Same as java.net.URL.hostsEqual - // - @SuppressWarnings("removal") - private static boolean hostsEqual(URL u1, URL u2) { - final String h1 = u1.getHost(); - final String h2 = u2.getHost(); - - if (h1 == null) { - return h2 == null; - } else if (h2 == null) { - return false; - } else if (h1.equalsIgnoreCase(h2)) { - return true; - } - // Have to resolve addresses before comparing, otherwise - // names like tachyon and tachyon.eng would compare different - final boolean result[] = {false}; - - java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction<>() { - public Void run() { - try { - InetAddress a1 = InetAddress.getByName(h1); - InetAddress a2 = InetAddress.getByName(h2); - result[0] = a1.equals(a2); - } catch(UnknownHostException | SecurityException e) { - } - return null; - } - }); - - return result[0]; + cookieHandler = CookieHandler.getDefault(); + cacheHandler = ResponseCache.getDefault(); } // overridden in HTTPS subclass @@ -1073,34 +886,6 @@ private boolean checkReuseConnection () { return false; } - @SuppressWarnings("removal") - private String getHostAndPort(URL url) { - String host = url.getHost(); - final String hostarg = host; - try { - // lookup hostname and use IP address if available - host = AccessController.doPrivileged( - new PrivilegedExceptionAction<>() { - public String run() throws IOException { - InetAddress addr = InetAddress.getByName(hostarg); - return addr.getHostAddress(); - } - } - ); - } catch (PrivilegedActionException e) {} - int port = url.getPort(); - if (port == -1) { - String scheme = url.getProtocol(); - if ("http".equals(scheme)) { - return host + ":80"; - } else { // scheme must be https - return host + ":443"; - } - } - return host + ":" + Integer.toString(port); - } - - @SuppressWarnings("removal") protected void plainConnect() throws IOException { lock(); try { @@ -1110,66 +895,7 @@ protected void plainConnect() throws IOException { } finally { unlock(); } - SocketPermission p = URLtoSocketPermission(this.url); - if (p != null) { - try { - AccessController.doPrivilegedWithCombiner( - new PrivilegedExceptionAction<>() { - public Void run() throws IOException { - plainConnect0(); - return null; - } - }, null, p - ); - } catch (PrivilegedActionException e) { - throw (IOException) e.getException(); - } - } else { - // run without additional permission - plainConnect0(); - } - } - - /** - * if the caller has a URLPermission for connecting to the - * given URL, then return a SocketPermission which permits - * access to that destination. Return null otherwise. The permission - * is cached in a field (which can only be changed by redirects) - */ - SocketPermission URLtoSocketPermission(URL url) throws IOException { - - if (socketPermission != null) { - return socketPermission; - } - - @SuppressWarnings("removal") - SecurityManager sm = System.getSecurityManager(); - - if (sm == null) { - return null; - } - - // the permission, which we might grant - - SocketPermission newPerm = new SocketPermission( - getHostAndPort(url), "connect" - ); - - String actions = getRequestMethod()+":" + - getUserSetHeaders().getHeaderNamesInList(); - - String urlstring = url.getProtocol() + "://" + url.getAuthority() - + url.getPath(); - - URLPermission p = new URLPermission(urlstring, actions); - try { - sm.checkPermission(p); - socketPermission = newPerm; - return socketPermission; - } catch (SecurityException e) { - // fall thru - } - return null; + plainConnect0(); } protected void plainConnect0() throws IOException { @@ -1215,14 +941,7 @@ protected void plainConnect0() throws IOException { /** * Do we have to use a proxy? */ - @SuppressWarnings("removal") - ProxySelector sel = - java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction<>() { - public ProxySelector run() { - return ProxySelector.getDefault(); - } - }); + final ProxySelector sel = ProxySelector.getDefault(); if (sel != null) { URI uri = sun.net.www.ParseUtil.toURI(url); if (logger.isLoggable(PlatformLogger.Level.FINEST)) { @@ -1399,29 +1118,12 @@ private void expect100Continue() throws IOException { * - get input, [read input,] get output, [write output] */ - @SuppressWarnings("removal") @Override public OutputStream getOutputStream() throws IOException { lock(); try { connecting = true; - SocketPermission p = URLtoSocketPermission(this.url); - - if (p != null) { - try { - return AccessController.doPrivilegedWithCombiner( - new PrivilegedExceptionAction<>() { - public OutputStream run() throws IOException { - return getOutputStream0(); - } - }, null, p - ); - } catch (PrivilegedActionException e) { - throw (IOException) e.getException(); - } - } else { - return getOutputStream0(); - } + return getOutputStream0(); } finally { unlock(); } @@ -1591,29 +1293,12 @@ private void setCookieHeader() throws IOException { } // end of getting cookies } - @SuppressWarnings("removal") @Override public InputStream getInputStream() throws IOException { lock(); try { connecting = true; - SocketPermission p = URLtoSocketPermission(this.url); - - if (p != null) { - try { - return AccessController.doPrivilegedWithCombiner( - new PrivilegedExceptionAction<>() { - public InputStream run() throws IOException { - return getInputStream0(); - } - }, null, p - ); - } catch (PrivilegedActionException e) { - throw (IOException) e.getException(); - } - } else { - return getInputStream0(); - } + return getInputStream0(); } finally { unlock(); } @@ -2060,17 +1745,9 @@ private InputStream getInputStream0() throws IOException { private IOException getChainedException(final IOException rememberedException) { try { final Object[] args = { rememberedException.getMessage() }; - @SuppressWarnings("removal") - IOException chainedException = - java.security.AccessController.doPrivileged( - new java.security.PrivilegedExceptionAction<>() { - public IOException run() throws Exception { - return (IOException) - rememberedException.getClass() - .getConstructor(new Class<?>[] { String.class }) - .newInstance(args); - } - }); + IOException chainedException = rememberedException.getClass() + .getConstructor(new Class<?>[] { String.class }) + .newInstance(args); chainedException.initCause(rememberedException); return chainedException; } catch (Exception ignored) { @@ -2392,7 +2069,7 @@ private void setPreemptiveProxyAuthentication(MessageHeader requests) throws IOE * Gets the authentication for an HTTP proxy, and applies it to * the connection. */ - @SuppressWarnings({"removal","fallthrough"}) + @SuppressWarnings("fallthrough") private AuthenticationInfo getHttpProxyAuthentication(AuthenticationHeader authhdr) throws IOException { @@ -2430,44 +2107,40 @@ private AuthenticationInfo getHttpProxyAuthentication(AuthenticationHeader authh proxyAuthKey = AuthenticationInfo.getProxyAuthKey(host, port, realm, authScheme); ret = AuthenticationInfo.getProxyAuth(proxyAuthKey, authCache); if (ret == null) { - switch (authScheme) { - case BASIC: - InetAddress addr = null; - try { - final String finalHost = host; - addr = java.security.AccessController.doPrivileged( - new java.security.PrivilegedExceptionAction<>() { - public InetAddress run() - throws java.net.UnknownHostException { - return InetAddress.getByName(finalHost); - } - }); - } catch (java.security.PrivilegedActionException ignored) { - // User will have an unknown host. - } - PasswordAuthentication a = - privilegedRequestPasswordAuthentication( - authenticator, - host, addr, port, "http", - realm, scheme, url, RequestorType.PROXY); - if (a != null) { - ret = new BasicAuthentication(true, host, port, realm, a, isUTF8); + ret = switch (authScheme) { + case BASIC -> { + InetAddress addr = null; + try { + addr = InetAddress.getByName(host); + } catch (UnknownHostException uhe) { + // Ignore the exception. The Authenticator instance will + // be passed a null InetAddress when requesting a password from the + // Authenticator. + } + final PasswordAuthentication a = requestPassword(authenticator, + host, addr, port, "http", + realm, scheme, url, RequestorType.PROXY); + if (a != null) { + yield new BasicAuthentication(true, host, port, realm, a, isUTF8); + } + yield null; } - break; - case DIGEST: - a = privilegedRequestPasswordAuthentication( - authenticator, - host, null, port, url.getProtocol(), - realm, scheme, url, RequestorType.PROXY); - if (a != null) { - DigestAuthentication.Parameters params = - new DigestAuthentication.Parameters(); - ret = new DigestAuthentication(true, host, port, realm, - scheme, a, params); + case DIGEST -> { + final PasswordAuthentication a = requestPassword(authenticator, + host, null, port, url.getProtocol(), + realm, scheme, url, RequestorType.PROXY); + if (a != null) { + DigestAuthentication.Parameters params = + new DigestAuthentication.Parameters(); + yield new DigestAuthentication(true, host, port, realm, + scheme, a, params); + } + yield null; } - break; - case NTLM: - if (NTLMAuthenticationProxy.supported) { + case NTLM -> { + if (!NTLMAuthenticationProxy.supported) { + yield null; + } /* tryTransparentNTLMProxy will always be true the first * time around, but verify that the platform supports it * otherwise don't try. */ @@ -2484,14 +2157,14 @@ public InetAddress run() } } - a = null; + PasswordAuthentication a = null; if (tryTransparentNTLMProxy) { logger.finest("Trying Transparent NTLM authentication"); } else { - a = privilegedRequestPasswordAuthentication( - authenticator, - host, null, port, url.getProtocol(), - "", scheme, url, RequestorType.PROXY); + a = requestPassword( + authenticator, + host, null, port, url.getProtocol(), + "", scheme, url, RequestorType.PROXY); validateNTLMCredentials(a); } /* If we are not trying transparent authentication then @@ -2500,29 +2173,27 @@ public InetAddress run() * and password will be picked up from the current logged * on users credentials. */ + AuthenticationInfo authInfo = null; if (tryTransparentNTLMProxy || - (!tryTransparentNTLMProxy && a != null)) { - ret = NTLMAuthenticationProxy.proxy.create(true, host, port, a); + (!tryTransparentNTLMProxy && a != null)) { + authInfo = NTLMAuthenticationProxy.proxy.create(true, host, port, a); } /* set to false so that we do not try again */ tryTransparentNTLMProxy = false; + yield authInfo; } - break; - case NEGOTIATE: - ret = new NegotiateAuthentication(new HttpCallerInfo(authhdr.getHttpCallerInfo(), "Negotiate")); - break; - case KERBEROS: - ret = new NegotiateAuthentication(new HttpCallerInfo(authhdr.getHttpCallerInfo(), "Kerberos")); - break; - case UNKNOWN: - if (logger.isLoggable(PlatformLogger.Level.FINEST)) { - logger.finest("Unknown/Unsupported authentication scheme: " + scheme); + case NEGOTIATE -> + new NegotiateAuthentication(new HttpCallerInfo(authhdr.getHttpCallerInfo(), "Negotiate")); + case KERBEROS -> + new NegotiateAuthentication(new HttpCallerInfo(authhdr.getHttpCallerInfo(), "Kerberos")); + case UNKNOWN -> { + if (logger.isLoggable(PlatformLogger.Level.FINEST)) { + logger.finest("Unknown/Unsupported authentication scheme: " + scheme); + } + yield null; } - /*fall through*/ - default: - throw new AssertionError("should not reach here"); - } + }; } if (ret != null) { if (!ret.setHeaders(this, p, raw)) { @@ -2604,7 +2275,7 @@ private AuthenticationInfo getServerAuthentication(AuthenticationHeader authhdr) break; case BASIC: PasswordAuthentication a = - privilegedRequestPasswordAuthentication( + requestPassword( authenticator, url.getHost(), addr, port, url.getProtocol(), realm, scheme, url, RequestorType.SERVER); @@ -2613,7 +2284,7 @@ private AuthenticationInfo getServerAuthentication(AuthenticationHeader authhdr) } break; case DIGEST: - a = privilegedRequestPasswordAuthentication( + a = requestPassword( authenticator, url.getHost(), addr, port, url.getProtocol(), realm, scheme, url, RequestorType.SERVER); @@ -2650,7 +2321,7 @@ private AuthenticationInfo getServerAuthentication(AuthenticationHeader authhdr) if (tryTransparentNTLMServer) { logger.finest("Trying Transparent NTLM authentication"); } else { - a = privilegedRequestPasswordAuthentication( + a = requestPassword( authenticator, url.getHost(), addr, port, url.getProtocol(), "", scheme, url, RequestorType.SERVER); @@ -2753,7 +2424,6 @@ String getRequestURI() throws IOException { * resets the url, re-connects, and resets the request * property. */ - @SuppressWarnings("removal") private boolean followRedirect() throws IOException { if (!getInstanceFollowRedirects()) { return false; @@ -2783,27 +2453,7 @@ private boolean followRedirect() throws IOException { // treat loc as a relative URI to conform to popular browsers locUrl = newURL(url, loc); } - - final URL locUrl0 = locUrl; - socketPermission = null; // force recalculation - SocketPermission p = URLtoSocketPermission(locUrl); - - if (p != null) { - try { - return AccessController.doPrivilegedWithCombiner( - new PrivilegedExceptionAction<>() { - public Boolean run() throws IOException { - return followRedirect0(loc, stat, locUrl0); - } - }, null, p - ); - } catch (PrivilegedActionException e) { - throw (IOException) e.getException(); - } - } else { - // run without additional permission - return followRedirect0(loc, stat, locUrl); - } + return followRedirect0(loc, stat, locUrl); } /* Tells us whether to follow a redirect. If so, it @@ -2838,12 +2488,6 @@ private boolean followRedirect0(String loc, int stat, URL locUrl) String proxyHost = locUrl.getHost(); int proxyPort = locUrl.getPort(); - @SuppressWarnings("removal") - SecurityManager security = System.getSecurityManager(); - if (security != null) { - security.checkConnect(proxyHost, proxyPort); - } - setProxiedClient (url, proxyHost, proxyPort); requests.set(0, method + " " + getRequestURI()+" " + httpVersion, null); diff --git a/src/java.base/share/classes/sun/net/www/protocol/http/NegotiateAuthentication.java b/src/java.base/share/classes/sun/net/www/protocol/http/NegotiateAuthentication.java index 27442382ec7..c27d866f5ef 100644 --- a/src/java.base/share/classes/sun/net/www/protocol/http/NegotiateAuthentication.java +++ b/src/java.base/share/classes/sun/net/www/protocol/http/NegotiateAuthentication.java @@ -36,7 +36,6 @@ import sun.net.www.HeaderParser; import static sun.net.www.protocol.http.AuthScheme.NEGOTIATE; import static sun.net.www.protocol.http.AuthScheme.KERBEROS; -import sun.security.action.GetPropertyAction; /** * NegotiateAuthentication: @@ -45,10 +44,7 @@ * @since 1.6 */ -class NegotiateAuthentication extends AuthenticationInfo { - - @java.io.Serial - private static final long serialVersionUID = 100L; +final class NegotiateAuthentication extends AuthenticationInfo { private final HttpCallerInfo hci; @@ -61,14 +57,6 @@ class NegotiateAuthentication extends AuthenticationInfo { static ThreadLocal <HashMap <String, Negotiator>> cache = null; private static final ReentrantLock negotiateLock = new ReentrantLock(); - /* Whether cache is enabled for Negotiate/Kerberos */ - private static final boolean cacheSPNEGO; - static { - String spnegoCacheProp = - GetPropertyAction.privilegedGetProperty("jdk.spnego.cache", "true"); - cacheSPNEGO = Boolean.parseBoolean(spnegoCacheProp); - } - // The HTTP Negotiate Helper private Negotiator negotiator = null; diff --git a/src/java.base/share/classes/sun/net/www/protocol/https/HttpsClient.java b/src/java.base/share/classes/sun/net/www/protocol/https/HttpsClient.java index 9bc28a353ab..fb2dfe6fff3 100644 --- a/src/java.base/share/classes/sun/net/www/protocol/https/HttpsClient.java +++ b/src/java.base/share/classes/sun/net/www/protocol/https/HttpsClient.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -30,7 +30,6 @@ import java.io.UnsupportedEncodingException; import java.io.PrintStream; import java.io.BufferedOutputStream; -import java.net.InetAddress; import java.net.Socket; import java.net.SocketException; import java.net.URL; @@ -48,7 +47,6 @@ import sun.net.www.http.HttpClient; import sun.net.www.protocol.http.AuthCacheImpl; import sun.net.www.protocol.http.HttpURLConnection; -import sun.security.action.*; import sun.security.util.HostnameChecker; import sun.security.ssl.SSLSocketImpl; @@ -138,10 +136,8 @@ final class HttpsClient extends HttpClient // // If ciphers are assigned, sort them into an array. // - String ciphers []; - String cipherString = - GetPropertyAction.privilegedGetProperty("https.cipherSuites"); - + String[] ciphers; + String cipherString = System.getProperty("https.cipherSuites"); if (cipherString == null || cipherString.isEmpty()) { ciphers = null; } else { @@ -162,10 +158,8 @@ final class HttpsClient extends HttpClient // // If protocols are assigned, sort them into an array. // - String protocols []; - String protocolString = - GetPropertyAction.privilegedGetProperty("https.protocols"); - + String[] protocols; + String protocolString = System.getProperty("https.protocols"); if (protocolString == null || protocolString.isEmpty()) { protocols = null; } else { @@ -183,65 +177,12 @@ final class HttpsClient extends HttpClient return protocols; } - private String getUserAgent() { - String userAgent = - GetPropertyAction.privilegedGetProperty("https.agent"); - if (userAgent == null || userAgent.isEmpty()) { - userAgent = "JSSE"; - } - return userAgent; - } - // CONSTRUCTOR, FACTORY - - /** - * Create an HTTPS client URL. Traffic will be tunneled through any - * intermediate nodes rather than proxied, so that confidentiality - * of data exchanged can be preserved. However, note that all the - * anonymous SSL flavors are subject to "person-in-the-middle" - * attacks against confidentiality. If you enable use of those - * flavors, you may be giving up the protection you get through - * SSL tunneling. - * - * Use New to get new HttpsClient. This constructor is meant to be - * used only by New method. New properly checks for URL spoofing. - * - * @param url https URL with which a connection must be established - */ - private HttpsClient(SSLSocketFactory sf, URL url) - throws IOException - { - // HttpClient-level proxying is always disabled, - // because we override doConnect to do tunneling instead. - this(sf, url, (String)null, -1); - } - /** - * Create an HTTPS client URL. Traffic will be tunneled through - * the specified proxy server. - */ - HttpsClient(SSLSocketFactory sf, URL url, String proxyHost, int proxyPort) - throws IOException { - this(sf, url, proxyHost, proxyPort, -1); - } - - /** - * Create an HTTPS client URL. Traffic will be tunneled through + * Create an HTTPS client URL. Traffic will be tunneled through * the specified proxy server, with a connect timeout */ - HttpsClient(SSLSocketFactory sf, URL url, String proxyHost, int proxyPort, - int connectTimeout) - throws IOException { - this(sf, url, - (proxyHost == null? null: - HttpClient.newHttpProxy(proxyHost, proxyPort, "https")), - connectTimeout); - } - - /** - * Same as previous constructor except using a Proxy - */ HttpsClient(SSLSocketFactory sf, URL url, Proxy proxy, int connectTimeout) throws IOException { @@ -268,37 +209,6 @@ private HttpsClient(SSLSocketFactory sf, URL url) // This code largely ripped off from HttpClient.New, and // it uses the same keepalive cache. - static HttpClient New(SSLSocketFactory sf, URL url, HostnameVerifier hv, - HttpURLConnection httpuc) - throws IOException { - return HttpsClient.New(sf, url, hv, true, httpuc); - } - - /** See HttpClient for the model for this method. */ - static HttpClient New(SSLSocketFactory sf, URL url, - HostnameVerifier hv, boolean useCache, - HttpURLConnection httpuc) throws IOException { - return HttpsClient.New(sf, url, hv, (String)null, -1, useCache, httpuc); - } - - /** - * Get a HTTPS client to the URL. Traffic will be tunneled through - * the specified proxy server. - */ - static HttpClient New(SSLSocketFactory sf, URL url, HostnameVerifier hv, - String proxyHost, int proxyPort, - HttpURLConnection httpuc) throws IOException { - return HttpsClient.New(sf, url, hv, proxyHost, proxyPort, true, httpuc); - } - - static HttpClient New(SSLSocketFactory sf, URL url, HostnameVerifier hv, - String proxyHost, int proxyPort, boolean useCache, - HttpURLConnection httpuc) - throws IOException { - return HttpsClient.New(sf, url, hv, proxyHost, proxyPort, useCache, -1, - httpuc); - } - static HttpClient New(SSLSocketFactory sf, URL url, HostnameVerifier hv, String proxyHost, int proxyPort, boolean useCache, int connectTimeout, HttpURLConnection httpuc) @@ -379,15 +289,6 @@ static HttpClient New(SSLSocketFactory sf, URL url, HostnameVerifier hv, ret.authcache = httpuc.getAuthCache(); } } else { - @SuppressWarnings("removal") - SecurityManager security = System.getSecurityManager(); - if (security != null) { - if (ret.proxy == Proxy.NO_PROXY || ret.proxy == null) { - security.checkConnect(InetAddress.getByName(url.getHost()).getHostAddress(), url.getPort()); - } else { - security.checkConnect(url.getHost(), url.getPort()); - } - } ret.url = url; } ret.setHostnameVerifier(hv); @@ -395,22 +296,17 @@ static HttpClient New(SSLSocketFactory sf, URL url, HostnameVerifier hv, return ret; } - // METHODS - void setHostnameVerifier(HostnameVerifier hv) { + private void setHostnameVerifier(HostnameVerifier hv) { this.hv = hv; } - void setSSLSocketFactory(SSLSocketFactory sf) { + private void setSSLSocketFactory(SSLSocketFactory sf) { sslSocketFactory = sf; } - SSLSocketFactory getSSLSocketFactory() { - return sslSocketFactory; - } - /** * The following method, createSocket, is defined in NetworkClient - * and overridden here so that the socket facroty is used to create + * and overridden here so that the socket factory is used to create * new sockets. */ @Override diff --git a/src/java.base/unix/classes/sun/net/www/protocol/http/ntlm/NTLMAuthentication.java b/src/java.base/unix/classes/sun/net/www/protocol/http/ntlm/NTLMAuthentication.java index 8a2944081d5..c034cd4dcd7 100644 --- a/src/java.base/unix/classes/sun/net/www/protocol/http/ntlm/NTLMAuthentication.java +++ b/src/java.base/unix/classes/sun/net/www/protocol/http/ntlm/NTLMAuthentication.java @@ -35,7 +35,6 @@ import java.security.GeneralSecurityException; import java.util.Base64; import java.util.Locale; -import java.util.Objects; import java.util.Properties; import sun.net.www.HeaderParser; @@ -70,8 +69,7 @@ * through a proxy, rather between client and proxy, or between client and server (with no proxy) */ -public class NTLMAuthentication extends AuthenticationInfo { - private static final long serialVersionUID = 170L; +public final class NTLMAuthentication extends AuthenticationInfo { private static final NTLMAuthenticationCallback NTLMAuthCallback = NTLMAuthenticationCallback.getNTLMAuthenticationCallback(); diff --git a/src/java.base/windows/classes/sun/net/www/protocol/http/ntlm/NTLMAuthentication.java b/src/java.base/windows/classes/sun/net/www/protocol/http/ntlm/NTLMAuthentication.java index d3b60daad74..a7056082e12 100644 --- a/src/java.base/windows/classes/sun/net/www/protocol/http/ntlm/NTLMAuthentication.java +++ b/src/java.base/windows/classes/sun/net/www/protocol/http/ntlm/NTLMAuthentication.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -31,14 +31,11 @@ import java.net.UnknownHostException; import java.net.URL; import java.util.Locale; -import java.util.Objects; -import java.util.Properties; import sun.net.NetProperties; import sun.net.www.HeaderParser; import sun.net.www.protocol.http.AuthenticationInfo; import sun.net.www.protocol.http.AuthScheme; import sun.net.www.protocol.http.HttpURLConnection; -import sun.security.action.GetPropertyAction; /** * NTLMAuthentication: @@ -46,14 +43,11 @@ * @author Michael McMahon */ -public class NTLMAuthentication extends AuthenticationInfo { - - private static final long serialVersionUID = 100L; +public final class NTLMAuthentication extends AuthenticationInfo { private static final NTLMAuthenticationCallback NTLMAuthCallback = - NTLMAuthenticationCallback.getNTLMAuthenticationCallback(); + NTLMAuthenticationCallback.getNTLMAuthenticationCallback(); - private String hostname; /* Domain to use if not specified by user */ private static final String defaultDomain; /* Whether cache is enabled for NTLM */ @@ -68,18 +62,10 @@ enum TransparentAuth { private static final TransparentAuth authMode; static { - Properties props = GetPropertyAction.privilegedGetProperties(); - defaultDomain = props.getProperty("http.auth.ntlm.domain", "domain"); - String ntlmCacheProp = props.getProperty("jdk.ntlm.cache", "true"); + defaultDomain = System.getProperty("http.auth.ntlm.domain", "domain"); + String ntlmCacheProp = System.getProperty("jdk.ntlm.cache", "true"); ntlmCache = Boolean.parseBoolean(ntlmCacheProp); - @SuppressWarnings("removal") - String modeProp = java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction<String>() { - public String run() { - return NetProperties.get("jdk.http.ntlm.transparentAuth"); - } - }); - + String modeProp = NetProperties.get("jdk.http.ntlm.transparentAuth"); if ("trustedHosts".equalsIgnoreCase(modeProp)) authMode = TransparentAuth.TRUSTED_HOSTS; else if ("allHosts".equalsIgnoreCase(modeProp)) @@ -88,27 +74,6 @@ else if ("allHosts".equalsIgnoreCase(modeProp)) authMode = TransparentAuth.DISABLED; } - @SuppressWarnings("removal") - private void init0() { - - hostname = java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction<String>() { - public String run() { - String localhost; - try { - localhost = InetAddress.getLocalHost().getHostName().toUpperCase(Locale.ROOT); - } catch (UnknownHostException e) { - localhost = "localhost"; - } - return localhost; - } - }); - int x = hostname.indexOf ('.'); - if (x != -1) { - hostname = hostname.substring (0, x); - } - } - String username; String ntdomain; String password; @@ -147,7 +112,6 @@ private void init (PasswordAuthentication pw) { ntdomain = null; password = null; } - init0(); } /** From db7ee3dad1d9c9578794d946dd5de1f51d77e5a1 Mon Sep 17 00:00:00 2001 From: Jaikiran Pai <jpai@openjdk.org> Date: Wed, 20 Nov 2024 12:41:39 +0000 Subject: [PATCH 128/311] 8344223: Remove calls to SecurityManager and doPrivileged in java.net.URLClassLoader after JEP 486 integration Reviewed-by: alanb, yzheng --- .../classes/java/net/URLClassLoader.java | 197 ++---------- .../internal/loader/BuiltinClassLoader.java | 23 +- .../jdk/internal/loader/URLClassPath.java | 289 +++++------------- 3 files changed, 112 insertions(+), 397 deletions(-) diff --git a/src/java.base/share/classes/java/net/URLClassLoader.java b/src/java.base/share/classes/java/net/URLClassLoader.java index 4d43d358a64..d867b7e2b62 100644 --- a/src/java.base/share/classes/java/net/URLClassLoader.java +++ b/src/java.base/share/classes/java/net/URLClassLoader.java @@ -30,14 +30,10 @@ import java.io.FilePermission; import java.io.IOException; import java.io.InputStream; -import java.security.AccessControlContext; -import java.security.AccessController; import java.security.CodeSigner; import java.security.CodeSource; import java.security.Permission; import java.security.PermissionCollection; -import java.security.PrivilegedAction; -import java.security.PrivilegedExceptionAction; import java.security.SecureClassLoader; import java.util.Enumeration; import java.util.List; @@ -76,10 +72,6 @@ public class URLClassLoader extends SecureClassLoader implements Closeable { /* The search path for classes and resources */ private final URLClassPath ucp; - /* The context to be used when loading classes and resources */ - @SuppressWarnings("removal") - private final AccessControlContext acc; - /** * Constructs a new URLClassLoader for the given URLs. The URLs will be * searched in the order specified for classes and resources after first @@ -94,18 +86,9 @@ public class URLClassLoader extends SecureClassLoader implements Closeable { * @throws NullPointerException if {@code urls} or any of its * elements is {@code null}. */ - @SuppressWarnings("removal") public URLClassLoader(URL[] urls, ClassLoader parent) { super(parent); - this.acc = AccessController.getContext(); - this.ucp = new URLClassPath(urls, acc); - } - - URLClassLoader(String name, URL[] urls, ClassLoader parent, - @SuppressWarnings("removal") AccessControlContext acc) { - super(name, parent); - this.acc = acc; - this.ucp = new URLClassPath(urls, acc); + this.ucp = new URLClassPath(urls); } /** @@ -122,17 +105,9 @@ public URLClassLoader(URL[] urls, ClassLoader parent) { * @throws NullPointerException if {@code urls} or any of its * elements is {@code null}. */ - @SuppressWarnings("removal") public URLClassLoader(URL[] urls) { super(); - this.acc = AccessController.getContext(); - this.ucp = new URLClassPath(urls, acc); - } - - URLClassLoader(URL[] urls, @SuppressWarnings("removal") AccessControlContext acc) { - super(); - this.acc = acc; - this.ucp = new URLClassPath(urls, acc); + this.ucp = new URLClassPath(urls); } /** @@ -149,12 +124,10 @@ public URLClassLoader(URL[] urls) { * @throws NullPointerException if {@code urls} or any of its * elements is {@code null}. */ - @SuppressWarnings("removal") public URLClassLoader(URL[] urls, ClassLoader parent, URLStreamHandlerFactory factory) { super(parent); - this.acc = AccessController.getContext(); - this.ucp = new URLClassPath(urls, factory, acc); + this.ucp = new URLClassPath(urls, factory); } @@ -176,13 +149,11 @@ public URLClassLoader(URL[] urls, ClassLoader parent, * * @since 9 */ - @SuppressWarnings("removal") public URLClassLoader(String name, URL[] urls, ClassLoader parent) { super(name, parent); - this.acc = AccessController.getContext(); - this.ucp = new URLClassPath(urls, acc); + this.ucp = new URLClassPath(urls); } /** @@ -203,12 +174,10 @@ public URLClassLoader(String name, * * @since 9 */ - @SuppressWarnings("removal") public URLClassLoader(String name, URL[] urls, ClassLoader parent, URLStreamHandlerFactory factory) { super(name, parent); - this.acc = AccessController.getContext(); - this.ucp = new URLClassPath(urls, factory, acc); + this.ucp = new URLClassPath(urls, factory); } /* A map (used as a set) to keep track of closeable local resources @@ -299,11 +268,6 @@ public InputStream getResourceAsStream(String name) { * @since 1.7 */ public void close() throws IOException { - @SuppressWarnings("removal") - SecurityManager security = System.getSecurityManager(); - if (security != null) { - security.checkPermission(new RuntimePermission("closeClassLoader")); - } List<IOException> errors = ucp.closeLoaders(); // now close any remaining streams. @@ -369,40 +333,24 @@ public URL[] getURLs() { * or if the loader is closed. * @throws NullPointerException if {@code name} is {@code null}. */ - @SuppressWarnings("removal") protected Class<?> findClass(final String name) throws ClassNotFoundException { - final Class<?> result; - try { - result = AccessController.doPrivileged( - new PrivilegedExceptionAction<>() { - public Class<?> run() throws ClassNotFoundException { - String path = name.replace('.', '/').concat(".class"); - Resource res = ucp.getResource(path, false); - if (res != null) { - try { - return defineClass(name, res); - } catch (IOException e) { - throw new ClassNotFoundException(name, e); - } catch (ClassFormatError e2) { - if (res.getDataError() != null) { - e2.addSuppressed(res.getDataError()); - } - throw e2; - } - } else { - return null; - } - } - }, acc); - } catch (java.security.PrivilegedActionException pae) { - throw (ClassNotFoundException) pae.getException(); - } - if (result == null) { - throw new ClassNotFoundException(name); + String path = name.replace('.', '/').concat(".class"); + Resource res = ucp.getResource(path); + if (res != null) { + try { + return defineClass(name, res); + } catch (IOException e) { + throw new ClassNotFoundException(name, e); + } catch (ClassFormatError e2) { + if (res.getDataError() != null) { + e2.addSuppressed(res.getDataError()); + } + throw e2; + } } - return result; + throw new ClassNotFoundException(name); } /* @@ -575,18 +523,7 @@ private boolean isSealed(String name, Manifest man) { * if the resource could not be found, or if the loader is closed. */ public URL findResource(final String name) { - /* - * The same restriction to finding classes applies to resources - */ - @SuppressWarnings("removal") - URL url = AccessController.doPrivileged( - new PrivilegedAction<>() { - public URL run() { - return ucp.findResource(name, true); - } - }, acc); - - return url != null ? URLClassPath.checkURL(url) : null; + return ucp.findResource(name); } /** @@ -598,10 +535,11 @@ public URL run() { * @return An {@code Enumeration} of {@code URL}s. * If the loader is closed, the Enumeration contains no elements. */ + @Override public Enumeration<URL> findResources(final String name) throws IOException { - final Enumeration<URL> e = ucp.findResources(name, true); + final Enumeration<URL> e = ucp.findResources(name); return new Enumeration<>() { private URL url = null; @@ -610,23 +548,14 @@ private boolean next() { if (url != null) { return true; } - do { - @SuppressWarnings("removal") - URL u = AccessController.doPrivileged( - new PrivilegedAction<>() { - public URL run() { - if (!e.hasMoreElements()) - return null; - return e.nextElement(); - } - }, acc); - if (u == null) - break; - url = URLClassPath.checkURL(u); - } while (url == null); + if (!e.hasMoreElements()) { + return false; + } + url = e.nextElement(); return url != null; } + @Override public URL nextElement() { if (!next()) { throw new NoSuchElementException(); @@ -636,6 +565,7 @@ public URL nextElement() { return u; } + @Override public boolean hasMoreElements() { return next(); } @@ -666,7 +596,6 @@ public boolean hasMoreElements() { * @throws NullPointerException if {@code codesource} is {@code null}. * @return the permissions for the codesource */ - @SuppressWarnings("removal") protected PermissionCollection getPermissions(CodeSource codesource) { PermissionCollection perms = super.getPermissions(codesource); @@ -712,23 +641,13 @@ protected PermissionCollection getPermissions(CodeSource codesource) String host = locUrl.getHost(); if (host != null && !host.isEmpty()) p = new SocketPermission(host, - SecurityConstants.SOCKET_CONNECT_ACCEPT_ACTION); + SecurityConstants.SOCKET_CONNECT_ACCEPT_ACTION); } // make sure the person that created this class loader // would have this permission if (p != null) { - final SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - final Permission fp = p; - AccessController.doPrivileged(new PrivilegedAction<>() { - public Void run() throws SecurityException { - sm.checkPermission(fp); - return null; - } - }, acc); - } perms.add(p); } return perms; @@ -746,18 +665,7 @@ public Void run() throws SecurityException { */ public static URLClassLoader newInstance(final URL[] urls, final ClassLoader parent) { - // Save the caller's context - @SuppressWarnings("removal") - final AccessControlContext acc = AccessController.getContext(); - // Need a privileged block to create the class loader - @SuppressWarnings("removal") - URLClassLoader ucl = AccessController.doPrivileged( - new PrivilegedAction<>() { - public URLClassLoader run() { - return new FactoryURLClassLoader(null, urls, parent, acc); - } - }); - return ucl; + return new URLClassLoader(null, urls, parent); } /** @@ -770,53 +678,10 @@ public URLClassLoader run() { * @return the resulting class loader */ public static URLClassLoader newInstance(final URL[] urls) { - // Save the caller's context - @SuppressWarnings("removal") - final AccessControlContext acc = AccessController.getContext(); - // Need a privileged block to create the class loader - @SuppressWarnings("removal") - URLClassLoader ucl = AccessController.doPrivileged( - new PrivilegedAction<>() { - public URLClassLoader run() { - return new FactoryURLClassLoader(urls, acc); - } - }); - return ucl; + return new URLClassLoader(urls); } static { ClassLoader.registerAsParallelCapable(); } } - -final class FactoryURLClassLoader extends URLClassLoader { - - static { - ClassLoader.registerAsParallelCapable(); - } - - FactoryURLClassLoader(String name, URL[] urls, ClassLoader parent, - @SuppressWarnings("removal") AccessControlContext acc) { - super(name, urls, parent, acc); - } - - FactoryURLClassLoader(URL[] urls, @SuppressWarnings("removal") AccessControlContext acc) { - super(urls, acc); - } - - public final Class<?> loadClass(String name, boolean resolve) - throws ClassNotFoundException - { - // First check if we have permission to access the package. This - // should go away once we've added support for exported packages. - @SuppressWarnings("removal") - SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - int i = name.lastIndexOf('.'); - if (i != -1) { - sm.checkPackageAccess(name.substring(0, i)); - } - } - return super.loadClass(name, resolve); - } -} diff --git a/src/java.base/share/classes/jdk/internal/loader/BuiltinClassLoader.java b/src/java.base/share/classes/jdk/internal/loader/BuiltinClassLoader.java index ddf35a88d0a..f6cc79fd127 100644 --- a/src/java.base/share/classes/jdk/internal/loader/BuiltinClassLoader.java +++ b/src/java.base/share/classes/jdk/internal/loader/BuiltinClassLoader.java @@ -315,7 +315,7 @@ public URL findResource(String name) { if (module.loader() == this) { URL url; try { - url = findResource(module.name(), name); // checks URL + url = findResource(module.name(), name); } catch (IOException ioe) { return null; } @@ -355,7 +355,7 @@ public URL findResource(String name) { */ @Override public Enumeration<URL> findResources(String name) throws IOException { - List<URL> checked = new ArrayList<>(); // list of checked URLs + List<URL> resources = new ArrayList<>(); // list of resource URLs String pn = Resources.toPackageName(name); LoadedModule module = packageToModule.get(pn); @@ -363,12 +363,12 @@ public Enumeration<URL> findResources(String name) throws IOException { // resource is in a package of a module defined to this loader if (module.loader() == this) { - URL url = findResource(module.name(), name); // checks URL + URL url = findResource(module.name(), name); if (url != null && (name.endsWith(".class") || url.toString().endsWith("/") || isOpen(module.mref(), pn))) { - checked.add(url); + resources.add(url); } } @@ -376,17 +376,17 @@ public Enumeration<URL> findResources(String name) throws IOException { // not in a package of a module defined to this loader for (URL url : findMiscResource(name)) { if (url != null) { - checked.add(url); + resources.add(url); } } } - // class path (not checked) + // class path Enumeration<URL> e = findResourcesOnClassPath(name); - // concat the checked URLs and the (not checked) class path + // concat the URLs of the resource in the modules and the class path return new Enumeration<>() { - final Iterator<URL> iterator = checked.iterator(); + final Iterator<URL> iterator = resources.iterator(); URL next; private boolean hasNext() { if (next != null) { @@ -395,7 +395,6 @@ private boolean hasNext() { next = iterator.next(); return true; } else { - // need to check each URL while (e.hasMoreElements() && next == null) { next = e.nextElement(); } @@ -485,7 +484,7 @@ private URL findResource(ModuleReference mref, String name) throws IOException { */ private URL findResourceOnClassPath(String name) { if (hasClassPath()) { - return ucp.findResource(name, false); + return ucp.findResource(name); } else { // no class path return null; @@ -497,7 +496,7 @@ private URL findResourceOnClassPath(String name) { */ private Enumeration<URL> findResourcesOnClassPath(String name) { if (hasClassPath()) { - return ucp.findResources(name, false); + return ucp.findResources(name); } else { // no class path return Collections.emptyEnumeration(); @@ -686,7 +685,7 @@ private Class<?> findClassInModuleOrNull(LoadedModule loadedModule, String cn) { */ private Class<?> findClassOnClassPathOrNull(String cn) { String path = cn.replace('.', '/').concat(".class"); - Resource res = ucp.getResource(path, false); + Resource res = ucp.getResource(path); if (res != null) { try { return defineClass(cn, res); diff --git a/src/java.base/share/classes/jdk/internal/loader/URLClassPath.java b/src/java.base/share/classes/jdk/internal/loader/URLClassPath.java index 297c77bc106..75418111f74 100644 --- a/src/java.base/share/classes/jdk/internal/loader/URLClassPath.java +++ b/src/java.base/share/classes/jdk/internal/loader/URLClassPath.java @@ -39,13 +39,7 @@ import java.net.URLConnection; import java.net.URLStreamHandler; import java.net.URLStreamHandlerFactory; -import java.security.AccessControlContext; -import java.security.AccessControlException; -import java.security.AccessController; import java.security.CodeSigner; -import java.security.Permission; -import java.security.PrivilegedActionException; -import java.security.PrivilegedExceptionAction; import java.security.cert.Certificate; import java.util.ArrayDeque; import java.util.ArrayList; @@ -70,7 +64,6 @@ import jdk.internal.access.SharedSecrets; import sun.net.util.URLUtil; import sun.net.www.ParseUtil; -import sun.security.action.GetPropertyAction; /** * This class is used to maintain a search path of URLs for loading classes @@ -83,20 +76,16 @@ public class URLClassPath { private static final String JAVA_VERSION; private static final boolean DEBUG; private static final boolean DISABLE_JAR_CHECKING; - private static final boolean DISABLE_ACC_CHECKING; private static final boolean DISABLE_CP_URL_CHECK; private static final boolean DEBUG_CP_URL_CHECK; static { - Properties props = GetPropertyAction.privilegedGetProperties(); + Properties props = System.getProperties(); JAVA_VERSION = props.getProperty("java.version"); DEBUG = (props.getProperty("sun.misc.URLClassPath.debug") != null); String p = props.getProperty("sun.misc.URLClassPath.disableJarChecking"); DISABLE_JAR_CHECKING = p != null ? p.equals("true") || p.isEmpty() : false; - p = props.getProperty("jdk.net.URLClassPath.disableRestrictedPermissions"); - DISABLE_ACC_CHECKING = p != null ? p.equals("true") || p.isEmpty() : false; - // This property will be removed in a later release p = props.getProperty("jdk.net.URLClassPath.disableClassPathURLCheck"); DISABLE_CP_URL_CHECK = p != null ? p.equals("true") || p.isEmpty() : false; @@ -125,12 +114,6 @@ public class URLClassPath { /* Whether this URLClassLoader has been closed yet */ private boolean closed = false; - /* The context to be used when loading classes and resources. If non-null - * this is the context that was captured during the creation of the - * URLClassLoader. null implies no additional security restrictions. */ - @SuppressWarnings("removal") - private final AccessControlContext acc; - /** * Creates a new URLClassPath for the given URLs. The URLs will be * searched in the order specified for classes and resources. A URL @@ -140,12 +123,9 @@ public class URLClassPath { * @param urls the directory and JAR file URLs to search for classes * and resources * @param factory the URLStreamHandlerFactory to use when creating new URLs - * @param acc the context to be used when loading classes and resources, may - * be null */ public URLClassPath(URL[] urls, - URLStreamHandlerFactory factory, - @SuppressWarnings("removal") AccessControlContext acc) { + URLStreamHandlerFactory factory) { ArrayList<URL> path = new ArrayList<>(urls.length); ArrayDeque<URL> unopenedUrls = new ArrayDeque<>(urls.length); for (URL url : urls) { @@ -160,14 +140,10 @@ public URLClassPath(URL[] urls, } else { jarHandler = null; } - if (DISABLE_ACC_CHECKING) - this.acc = null; - else - this.acc = acc; } - public URLClassPath(URL[] urls, @SuppressWarnings("removal") AccessControlContext acc) { - this(urls, null, acc); + public URLClassPath(URL[] urls) { + this(urls, null); } /** @@ -209,7 +185,6 @@ public URLClassPath(URL[] urls, @SuppressWarnings("removal") AccessControlContex // the application class loader uses the built-in protocol handler to avoid protocol // handler lookup when opening JAR files on the class path. this.jarHandler = new sun.net.www.protocol.jar.Handler(); - this.acc = null; } public synchronized List<IOException> closeLoaders() { @@ -279,17 +254,16 @@ public URL[] getURLs() { /** * Finds the resource with the specified name on the URL search path - * or null if not found or security check fails. + * or null if not found. * * @param name the name of the resource - * @param check whether to perform a security check * @return a {@code URL} for the resource, or {@code null} * if the resource could not be found. */ - public URL findResource(String name, boolean check) { + public URL findResource(String name) { Loader loader; for (int i = 0; (loader = getLoader(i)) != null; i++) { - URL url = loader.findResource(name, check); + URL url = loader.findResource(name); if (url != null) { return url; } @@ -297,29 +271,6 @@ public URL findResource(String name, boolean check) { return null; } - /** - * Finds the first Resource on the URL search path which has the specified - * name. Returns null if no Resource could be found. - * - * @param name the name of the Resource - * @param check whether to perform a security check - * @return the Resource, or null if not found - */ - public Resource getResource(String name, boolean check) { - if (DEBUG) { - System.err.println("URLClassPath.getResource(\"" + name + "\")"); - } - - Loader loader; - for (int i = 0; (loader = getLoader(i)) != null; i++) { - Resource res = loader.getResource(name, check); - if (res != null) { - return res; - } - } - return null; - } - /** * Finds all resources on the URL search path with the given name. * Returns an enumeration of the URL objects. @@ -327,8 +278,7 @@ public Resource getResource(String name, boolean check) { * @param name the resource name * @return an Enumeration of all the urls having the specified name */ - public Enumeration<URL> findResources(final String name, - final boolean check) { + public Enumeration<URL> findResources(final String name) { return new Enumeration<>() { private int index = 0; private URL url = null; @@ -339,7 +289,7 @@ private boolean next() { } else { Loader loader; while ((loader = getLoader(index++)) != null) { - url = loader.findResource(name, check); + url = loader.findResource(name); if (url != null) { return true; } @@ -363,8 +313,26 @@ public URL nextElement() { }; } + /** + * Finds the first Resource on the URL search path which has the specified + * name. Returns null if no Resource could be found. + * + * @param name the name of the Resource + * @return the Resource, or null if not found + */ public Resource getResource(String name) { - return getResource(name, true); + if (DEBUG) { + System.err.println("URLClassPath.getResource(\"" + name + "\")"); + } + + Loader loader; + for (int i = 0; (loader = getLoader(i)) != null; i++) { + Resource res = loader.getResource(name); + if (res != null) { + return res; + } + } + return null; } /** @@ -374,8 +342,7 @@ public Resource getResource(String name) { * @param name the resource name * @return an Enumeration of all the resources having the specified name */ - public Enumeration<Resource> getResources(final String name, - final boolean check) { + public Enumeration<Resource> getResources(final String name) { return new Enumeration<>() { private int index = 0; private Resource res = null; @@ -386,7 +353,7 @@ private boolean next() { } else { Loader loader; while ((loader = getLoader(index++)) != null) { - res = loader.getResource(name, check); + res = loader.getResource(name); if (res != null) { return true; } @@ -410,10 +377,6 @@ public Resource nextElement() { }; } - public Enumeration<Resource> getResources(final String name) { - return getResources(name, true); - } - /* * Returns the Loader at the specified position in the URL search * path. The URLs are opened and expanded as needed. Returns null @@ -455,17 +418,6 @@ private synchronized Loader getLoader(int index) { closeQuietly(loader); } continue; - } catch (SecurityException se) { - // log the error and close the unusable loader (if any). - // The context, if there is one, that this URLClassPath was - // given during construction will never have permission to access the URL. - if (DEBUG) { - System.err.println("Failed to access " + url + ", " + se ); - } - if (loader != null) { - closeQuietly(loader); - } - continue; } if (loaderClassPathURLs != null) { push(loaderClassPathURLs); @@ -491,34 +443,24 @@ private static void closeQuietly(final Loader loader) { /* * Returns the Loader for the specified base URL. */ - @SuppressWarnings("removal") private Loader getLoader(final URL url) throws IOException { - try { - return AccessController.doPrivileged( - new PrivilegedExceptionAction<>() { - public Loader run() throws IOException { - String protocol = url.getProtocol(); // lower cased in URL - String file = url.getFile(); - if (file != null && file.endsWith("/")) { - if ("file".equals(protocol)) { - return new FileLoader(url); - } else if ("jar".equals(protocol) && - isDefaultJarHandler(url) && - file.endsWith("!/")) { - // extract the nested URL - @SuppressWarnings("deprecation") - URL nestedUrl = new URL(file.substring(0, file.length() - 2)); - return new JarLoader(nestedUrl, jarHandler, acc); - } else { - return new Loader(url); - } - } else { - return new JarLoader(url, jarHandler, acc); - } - } - }, acc); - } catch (PrivilegedActionException pae) { - throw (IOException)pae.getException(); + String protocol = url.getProtocol(); // lower cased in URL + String file = url.getFile(); + if (file != null && file.endsWith("/")) { + if ("file".equals(protocol)) { + return new FileLoader(url); + } else if ("jar".equals(protocol) && + isDefaultJarHandler(url) && + file.endsWith("!/")) { + // extract the nested URL + @SuppressWarnings("deprecation") + URL nestedUrl = new URL(file.substring(0, file.length() - 2)); + return new JarLoader(nestedUrl, jarHandler); + } else { + return new Loader(url); + } + } else { + return new JarLoader(url, jarHandler); } } @@ -541,59 +483,6 @@ private void push(URL[] urls) { } } - /* - * Checks whether the resource URL should be returned. - * Returns null on security check failure. - * Called by java.net.URLClassLoader. - */ - public static URL checkURL(URL url) { - if (url != null) { - try { - check(url); - } catch (Exception e) { - return null; - } - } - return url; - } - - /* - * Checks whether the resource URL should be returned. - * Throws exception on failure. - * Called internally within this file. - */ - public static void check(URL url) throws IOException { - @SuppressWarnings("removal") - SecurityManager security = System.getSecurityManager(); - if (security != null) { - URLConnection urlConnection = url.openConnection(); - Permission perm = urlConnection.getPermission(); - if (perm != null) { - try { - security.checkPermission(perm); - } catch (SecurityException se) { - // fallback to checkRead/checkConnect for pre 1.2 - // security managers - if ((perm instanceof java.io.FilePermission) && - perm.getActions().contains("read")) { - security.checkRead(perm.getName()); - } else if ((perm instanceof - java.net.SocketPermission) && - perm.getActions().contains("connect")) { - URL locUrl = url; - if (urlConnection instanceof JarURLConnection) { - locUrl = ((JarURLConnection)urlConnection).getJarFileURL(); - } - security.checkConnect(locUrl.getHost(), - locUrl.getPort()); - } else { - throw se; - } - } - } - } - } - /** * Nested class used to represent a loader of resources and classes * from a base URL. @@ -616,7 +505,7 @@ final URL getBaseURL() { return base; } - URL findResource(final String name, boolean check) { + URL findResource(final String name) { URL url; try { @SuppressWarnings("deprecation") @@ -626,10 +515,6 @@ URL findResource(final String name, boolean check) { } try { - if (check) { - URLClassPath.check(url); - } - /* * For a HTTP connection we use the HEAD method to * check if the resource exists. @@ -653,7 +538,11 @@ URL findResource(final String name, boolean check) { } } - Resource getResource(final String name, boolean check) { + /* + * Returns the Resource for the specified name, or null if not + * found. + */ + Resource getResource(final String name) { final URL url; try { @SuppressWarnings("deprecation") @@ -663,9 +552,6 @@ Resource getResource(final String name, boolean check) { } final URLConnection uc; try { - if (check) { - URLClassPath.check(url); - } uc = url.openConnection(); if (uc instanceof JarURLConnection) { @@ -693,15 +579,6 @@ public int getContentLength() throws IOException { }; } - /* - * Returns the Resource for the specified name, or null if not - * found or the caller does not have the permission to get the - * resource. - */ - Resource getResource(final String name) { - return getResource(name, true); - } - /* * Closes this loader and release all resources. * Method overridden in sub-classes. @@ -727,8 +604,6 @@ URL[] getClassPath() throws IOException { private static class JarLoader extends Loader { private JarFile jar; private final URL csu; - @SuppressWarnings("removal") - private final AccessControlContext acc; private boolean closed = false; private static final JavaUtilZipFileAccess zipAccess = SharedSecrets.getJavaUtilZipFileAccess(); @@ -737,14 +612,11 @@ private static class JarLoader extends Loader { * Creates a new JarLoader for the specified URL referring to * a JAR file. */ - private JarLoader(URL url, URLStreamHandler jarHandler, - @SuppressWarnings("removal") AccessControlContext acc) + private JarLoader(URL url, URLStreamHandler jarHandler) throws IOException { super(newURL("jar", "", -1, url + "!/", jarHandler)); csu = url; - this.acc = acc; - ensureOpen(); } @@ -770,24 +642,13 @@ private boolean isOptimizable(URL url) { return "file".equals(url.getProtocol()); } - @SuppressWarnings("removal") private void ensureOpen() throws IOException { if (jar == null) { - try { - AccessController.doPrivileged( - new PrivilegedExceptionAction<>() { - public Void run() throws IOException { - if (DEBUG) { - System.err.println("Opening " + csu); - Thread.dumpStack(); - } - jar = getJarFile(csu); - return null; - } - }, acc); - } catch (PrivilegedActionException pae) { - throw (IOException)pae.getException(); + if (DEBUG) { + System.err.println("Opening " + csu); + Thread.dumpStack(); } + jar = getJarFile(csu); } } @@ -826,11 +687,9 @@ private JarFile getJarFile(URL url) throws IOException { } /* - * Creates the resource and if the check flag is set to true, checks if - * is its okay to return the resource. + * Creates and returns the Resource. Returns null if the Resource couldn't be created. */ - Resource checkResource(final String name, boolean check, - final JarEntry entry) { + Resource createResource(final String name, final JarEntry entry) { final URL url; try { @@ -842,10 +701,7 @@ Resource checkResource(final String name, boolean check, } @SuppressWarnings("deprecation") var _unused = url = new URL(getBaseURL(), ParseUtil.encodePath(nm, false)); - if (check) { - URLClassPath.check(url); - } - } catch (@SuppressWarnings("removal") AccessControlException | IOException e) { + } catch (IOException e) { return null; } @@ -885,8 +741,8 @@ public byte[] getBytes() throws IOException { * Returns the URL for a resource with the specified name */ @Override - URL findResource(final String name, boolean check) { - Resource rsc = getResource(name, check); + URL findResource(final String name) { + Resource rsc = getResource(name); if (rsc != null) { return rsc.getURL(); } @@ -897,17 +753,16 @@ URL findResource(final String name, boolean check) { * Returns the JAR Resource for the specified name. */ @Override - Resource getResource(final String name, boolean check) { + Resource getResource(final String name) { try { ensureOpen(); } catch (IOException e) { throw new InternalError(e); } final JarEntry entry = jar.getJarEntry(name); - if (entry != null) - return checkResource(name, check, entry); - - + if (entry != null) { + return createResource(name, entry); + } return null; } @@ -1058,8 +913,8 @@ private FileLoader(URL url) throws IOException { * Returns the URL for a resource with the specified name */ @Override - URL findResource(final String name, boolean check) { - Resource rsc = getResource(name, check); + URL findResource(final String name) { + Resource rsc = getResource(name); if (rsc != null) { return rsc.getURL(); } @@ -1067,7 +922,7 @@ URL findResource(final String name, boolean check) { } @Override - Resource getResource(final String name, boolean check) { + Resource getResource(final String name) { final URL url; try { @SuppressWarnings("deprecation") @@ -1077,10 +932,6 @@ Resource getResource(final String name, boolean check) { // requested resource had ../..'s in path return null; } - - if (check) - URLClassPath.check(url); - final File file; if (name.contains("..")) { file = (new File(dir, name.replace('/', File.separatorChar))) From 4bc826ac1ea824113a07713f6973c06361c1392e Mon Sep 17 00:00:00 2001 From: Vlad Zahorodnii <vlad.zahorodnii@kde.org> Date: Wed, 20 Nov 2024 13:38:08 +0000 Subject: [PATCH 129/311] 8342785: XWindowPeer::getNewLocation() adheres to ICCCM 4.1.5 only with some WMs Reviewed-by: prr, azvegint --- .../unix/classes/sun/awt/X11/XWindowPeer.java | 28 ++++--------------- 1 file changed, 6 insertions(+), 22 deletions(-) diff --git a/src/java.desktop/unix/classes/sun/awt/X11/XWindowPeer.java b/src/java.desktop/unix/classes/sun/awt/X11/XWindowPeer.java index 1c0f8e27ffb..267ad9349ea 100644 --- a/src/java.desktop/unix/classes/sun/awt/X11/XWindowPeer.java +++ b/src/java.desktop/unix/classes/sun/awt/X11/XWindowPeer.java @@ -767,28 +767,12 @@ protected Point getNewLocation(XConfigureEvent xe, int leftInset, int topInset) // a window is resized but the client can not tell if the window was // moved or not. The client should consider the position as unknown // and use TranslateCoordinates to find the actual position. - // - // TODO this should be the default for every case. - switch (runningWM) { - case XWM.CDE_WM: - case XWM.KDE2_WM: - case XWM.MOTIF_WM: - case XWM.METACITY_WM: - case XWM.MUTTER_WM: - case XWM.SAWFISH_WM: - case XWM.UNITY_COMPIZ_WM: - { - Point xlocation = queryXLocation(); - if (log.isLoggable(PlatformLogger.Level.FINE)) { - log.fine("New X location: {0}", xlocation); - } - if (xlocation != null) { - newLocation = xlocation; - } - break; - } - default: - break; + Point xlocation = queryXLocation(); + if (log.isLoggable(PlatformLogger.Level.FINE)) { + log.fine("New X location: {0}", xlocation); + } + if (xlocation != null) { + newLocation = xlocation; } } return newLocation; From 21f0ed50a224f19d083ef8e3b7b02b8f3dd31cac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Volkan=20Yaz=C4=B1c=C4=B1?= <volkan.yazici@oracle.com> Date: Wed, 20 Nov 2024 13:59:52 +0000 Subject: [PATCH 130/311] 8344215: Remove calls to SecurityManager and doPrivileged in java.net.Socket and java.net.ServerSocket after JEP 486 integration Reviewed-by: dfuchs, alanb, jpai --- .../share/classes/java/net/ServerSocket.java | 58 ++---------------- .../share/classes/java/net/Socket.java | 60 +------------------ 2 files changed, 6 insertions(+), 112 deletions(-) diff --git a/src/java.base/share/classes/java/net/ServerSocket.java b/src/java.base/share/classes/java/net/ServerSocket.java index c6560fee35a..945693ef65e 100644 --- a/src/java.base/share/classes/java/net/ServerSocket.java +++ b/src/java.base/share/classes/java/net/ServerSocket.java @@ -33,7 +33,6 @@ import java.util.Set; import java.util.Collections; -import sun.security.util.SecurityConstants; import sun.net.PlatformSocketImpl; /** @@ -89,13 +88,6 @@ public class ServerSocket implements java.io.Closeable { // used to coordinate creating and closing underlying socket private final Object socketLock = new Object(); - /** - * Creates a server socket with the given {@code SocketImpl}. - */ - private ServerSocket(Void unused, SocketImpl impl) { - this.impl = Objects.requireNonNull(impl); - } - /** * Creates a server socket with a user-specified {@code SocketImpl}. * @@ -106,16 +98,7 @@ private ServerSocket(Void unused, SocketImpl impl) { * @since 12 */ protected ServerSocket(SocketImpl impl) { - this(checkPermission(), impl); - } - - private static Void checkPermission() { - @SuppressWarnings("removal") - SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - sm.checkPermission(SecurityConstants.SET_SOCKETIMPL_PERMISSION); - } - return null; + this.impl = Objects.requireNonNull(impl); } /** @@ -237,7 +220,7 @@ public ServerSocket(int port, int backlog, InetAddress bindAddr) throws IOExcept this.impl = createImpl(); try { bind(new InetSocketAddress(bindAddr, port), backlog); - } catch (IOException | SecurityException e) { + } catch (IOException e) { close(); throw e; } @@ -338,11 +321,6 @@ public void bind(SocketAddress endpoint, int backlog) throws IOException { if (backlog < 1) backlog = 50; - @SuppressWarnings("removal") - SecurityManager security = System.getSecurityManager(); - if (security != null) - security.checkListen(epoint.getPort()); - // SocketImpl bind+listen throw if already bound or closed SocketImpl impl = getImpl(); impl.bind(epoint.getAddress(), epoint.getPort()); @@ -364,14 +342,7 @@ public InetAddress getInetAddress() { if (!isBound()) return null; try { - InetAddress in = getImpl().getInetAddress(); - @SuppressWarnings("removal") - SecurityManager sm = System.getSecurityManager(); - if (sm != null) - sm.checkConnect(in.getHostAddress(), -1); - return in; - } catch (SecurityException e) { - return InetAddress.getLoopbackAddress(); + return getImpl().getInetAddress(); } catch (SocketException e) { // nothing // If we're bound, the impl has been created @@ -631,17 +602,6 @@ private void implAccept(SocketImpl si) throws IOException { throw e; } - // check permission, close SocketImpl/connection if denied - @SuppressWarnings("removal") - SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - try { - sm.checkAccept(si.getInetAddress().getHostAddress(), si.getPort()); - } catch (SecurityException se) { - si.close(); - throw se; - } - } } /** @@ -835,15 +795,10 @@ public boolean getReuseAddress() throws SocketException { * * @return a string representation of this socket. */ - @SuppressWarnings("removal") public String toString() { if (!isBound()) return "ServerSocket[unbound]"; - InetAddress in; - if (System.getSecurityManager() != null) - in = getInetAddress(); - else - in = impl.getInetAddress(); + InetAddress in = impl.getInetAddress(); return "ServerSocket[addr=" + in + ",localport=" + impl.getLocalPort() + "]"; } @@ -884,11 +839,6 @@ public static synchronized void setSocketFactory(SocketImplFactory fac) throws I if (factory != null) { throw new SocketException("factory already defined"); } - @SuppressWarnings("removal") - SecurityManager security = System.getSecurityManager(); - if (security != null) { - security.checkSetFactory(); - } factory = fac; } diff --git a/src/java.base/share/classes/java/net/Socket.java b/src/java.base/share/classes/java/net/Socket.java index 9825457aac1..83c0dec682c 100644 --- a/src/java.base/share/classes/java/net/Socket.java +++ b/src/java.base/share/classes/java/net/Socket.java @@ -28,7 +28,6 @@ import jdk.internal.event.SocketReadEvent; import jdk.internal.event.SocketWriteEvent; import jdk.internal.invoke.MhUtil; -import sun.security.util.SecurityConstants; import java.io.InputStream; import java.io.InterruptedIOException; @@ -157,15 +156,6 @@ private static boolean isOutputShutdown(int s) { return (s & SHUT_OUT) != 0; } - /** - * Creates an unconnected socket with the given {@code SocketImpl}. - */ - private Socket(Void unused, SocketImpl impl) { - if (impl != null) { - this.impl = impl; - } - } - /** * Creates an unconnected Socket. * <p> @@ -212,22 +202,10 @@ public Socket(Proxy proxy) { : sun.net.ApplicationProxy.create(proxy); Proxy.Type type = p.type(); if (type == Proxy.Type.SOCKS || type == Proxy.Type.HTTP) { - @SuppressWarnings("removal") - SecurityManager security = System.getSecurityManager(); InetSocketAddress epoint = (InetSocketAddress) p.address(); if (epoint.getAddress() != null) { checkAddress (epoint.getAddress(), "Socket"); } - if (security != null) { - if (epoint.isUnresolved()) - epoint = new InetSocketAddress(epoint.getHostName(), epoint.getPort()); - if (epoint.isUnresolved()) - security.checkConnect(epoint.getHostName(), epoint.getPort()); - else - security.checkConnect(epoint.getAddress().getHostAddress(), - epoint.getPort()); - } - // create a SOCKS or HTTP SocketImpl that delegates to a platform SocketImpl SocketImpl delegate = SocketImpl.createPlatformSocketImpl(false); impl = (type == Proxy.Type.SOCKS) ? new SocksSocketImpl(p, delegate) @@ -259,18 +237,9 @@ public Socket(Proxy proxy) { * @since 1.1 */ protected Socket(SocketImpl impl) throws SocketException { - this(checkPermission(impl), impl); - } - - private static Void checkPermission(SocketImpl impl) { if (impl != null) { - @SuppressWarnings("removal") - SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - sm.checkPermission(SecurityConstants.SET_SOCKETIMPL_PERMISSION); - } + this.impl = impl; } - return null; } /** @@ -497,7 +466,7 @@ private Socket(SocketAddress address, SocketAddress localAddr, boolean stream) if (localAddr != null) bind(localAddr); connect(address); - } catch (IOException | IllegalArgumentException | SecurityException e) { + } catch (IOException | IllegalArgumentException e) { try { close(); } catch (IOException ce) { @@ -684,15 +653,6 @@ public void connect(SocketAddress endpoint, int timeout) throws IOException { int port = epoint.getPort(); checkAddress(addr, "connect"); - @SuppressWarnings("removal") - SecurityManager security = System.getSecurityManager(); - if (security != null) { - if (epoint.isUnresolved()) - security.checkConnect(epoint.getHostName(), port); - else - security.checkConnect(addr.getHostAddress(), port); - } - try { getImpl().connect(epoint, timeout); } catch (SocketTimeoutException e) { @@ -743,11 +703,6 @@ public void bind(SocketAddress bindpoint) throws IOException { InetAddress addr = epoint.getAddress(); int port = epoint.getPort(); checkAddress (addr, "bind"); - @SuppressWarnings("removal") - SecurityManager security = System.getSecurityManager(); - if (security != null) { - security.checkListen(port); - } getImpl().bind(addr, port); getAndBitwiseOrState(BOUND); } @@ -795,15 +750,9 @@ public InetAddress getLocalAddress() { InetAddress in = null; try { in = (InetAddress) getImpl().getOption(SocketOptions.SO_BINDADDR); - @SuppressWarnings("removal") - SecurityManager sm = System.getSecurityManager(); - if (sm != null) - sm.checkConnect(in.getHostAddress(), -1); if (in.isAnyLocalAddress()) { in = InetAddress.anyLocalAddress(); } - } catch (SecurityException e) { - in = InetAddress.getLoopbackAddress(); } catch (Exception e) { in = InetAddress.anyLocalAddress(); // "0.0.0.0" } @@ -1855,11 +1804,6 @@ public static synchronized void setSocketImplFactory(SocketImplFactory fac) if (factory != null) { throw new SocketException("factory already defined"); } - @SuppressWarnings("removal") - SecurityManager security = System.getSecurityManager(); - if (security != null) { - security.checkSetFactory(); - } factory = fac; } From e11d126a8d50e8b3dce2fd02b263aba3b38b1172 Mon Sep 17 00:00:00 2001 From: "David M. Lloyd" <david.lloyd@redhat.com> Date: Wed, 20 Nov 2024 14:17:28 +0000 Subject: [PATCH 131/311] 8333796: Add missing serialization functionality to sun.reflect.ReflectionFactory Reviewed-by: liach, rriggs --- .../java/io/ObjectStreamReflection.java | 177 ++++++ .../JavaObjectStreamReflectionAccess.java | 33 ++ .../jdk/internal/access/SharedSecrets.java | 16 + .../internal/reflect/ReflectionFactory.java | 68 ++- .../sun/reflect/ReflectionFactory.java | 111 ++++ .../ReflectionFactoryTest.java | 509 +++++++++++++++++- 6 files changed, 912 insertions(+), 2 deletions(-) create mode 100644 src/java.base/share/classes/java/io/ObjectStreamReflection.java create mode 100644 src/java.base/share/classes/jdk/internal/access/JavaObjectStreamReflectionAccess.java diff --git a/src/java.base/share/classes/java/io/ObjectStreamReflection.java b/src/java.base/share/classes/java/io/ObjectStreamReflection.java new file mode 100644 index 00000000000..35c7019419c --- /dev/null +++ b/src/java.base/share/classes/java/io/ObjectStreamReflection.java @@ -0,0 +1,177 @@ +/* + * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package java.io; + +import java.lang.invoke.MethodHandle; +import java.lang.invoke.MethodHandles; +import java.lang.invoke.MethodType; + +import jdk.internal.access.JavaObjectStreamReflectionAccess; +import jdk.internal.access.SharedSecrets; +import jdk.internal.util.ByteArray; + +/** + * Utilities relating to serialization and deserialization of objects. + */ +final class ObjectStreamReflection { + + // todo: these could be constants + private static final MethodHandle DRO_HANDLE; + private static final MethodHandle DWO_HANDLE; + + static { + try { + MethodHandles.Lookup lookup = MethodHandles.lookup(); + MethodType droType = MethodType.methodType(void.class, ObjectStreamClass.class, Object.class, ObjectInputStream.class); + DRO_HANDLE = lookup.findStatic(ObjectStreamReflection.class, "defaultReadObject", droType); + MethodType dwoType = MethodType.methodType(void.class, ObjectStreamClass.class, Object.class, ObjectOutputStream.class); + DWO_HANDLE = lookup.findStatic(ObjectStreamReflection.class, "defaultWriteObject", dwoType); + } catch (NoSuchMethodException | IllegalAccessException e) { + throw new InternalError(e); + } + } + + /** + * Populate a serializable object from data acquired from the stream's + * {@link java.io.ObjectInputStream.GetField} object independently of + * the actual {@link ObjectInputStream} implementation which may + * arbitrarily override the {@link ObjectInputStream#readFields()} method + * in order to deserialize using a custom object format. + * <p> + * The fields are populated using the mechanism defined in {@link ObjectStreamClass}, + * which requires objects and primitives to each be packed into a separate array + * whose relative field offsets are defined in the {@link ObjectStreamField} + * corresponding to each field. + * Utility methods on the {@code ObjectStreamClass} instance are then used + * to validate and perform the actual field accesses. + * + * @param streamClass the object stream class of the object (must not be {@code null}) + * @param obj the object to deserialize (must not be {@code null}) + * @param ois the object stream (must not be {@code null}) + * @throws IOException if the call to {@link ObjectInputStream#readFields} + * or one of its field accessors throws this exception type + * @throws ClassNotFoundException if the call to {@link ObjectInputStream#readFields} + * or one of its field accessors throws this exception type + */ + private static void defaultReadObject(ObjectStreamClass streamClass, Object obj, ObjectInputStream ois) + throws IOException, ClassNotFoundException { + ObjectInputStream.GetField getField = ois.readFields(); + byte[] bytes = new byte[streamClass.getPrimDataSize()]; + Object[] objs = new Object[streamClass.getNumObjFields()]; + for (ObjectStreamField field : streamClass.getFields(false)) { + int offset = field.getOffset(); + String fieldName = field.getName(); + switch (field.getTypeCode()) { + case 'B' -> bytes[offset] = getField.get(fieldName, (byte) 0); + case 'C' -> ByteArray.setChar(bytes, offset, getField.get(fieldName, (char) 0)); + case 'D' -> ByteArray.setDoubleRaw(bytes, offset, getField.get(fieldName, 0.0)); + case 'F' -> ByteArray.setFloatRaw(bytes, offset, getField.get(fieldName, 0.0f)); + case 'I' -> ByteArray.setInt(bytes, offset, getField.get(fieldName, 0)); + case 'J' -> ByteArray.setLong(bytes, offset, getField.get(fieldName, 0L)); + case 'S' -> ByteArray.setShort(bytes, offset, getField.get(fieldName, (short) 0)); + case 'Z' -> ByteArray.setBoolean(bytes, offset, getField.get(fieldName, false)); + case '[', 'L' -> objs[offset] = getField.get(fieldName, null); + default -> throw new IllegalStateException(); + } + } + streamClass.checkObjFieldValueTypes(obj, objs); + streamClass.setPrimFieldValues(obj, bytes); + streamClass.setObjFieldValues(obj, objs); + } + + /** + * Populate and write a stream's {@link java.io.ObjectOutputStream.PutField} object + * from field data acquired from a serializable object independently of + * the actual {@link ObjectOutputStream} implementation which may + * arbitrarily override the {@link ObjectOutputStream#putFields()} + * and {@link ObjectOutputStream#writeFields()} methods + * in order to deserialize using a custom object format. + * <p> + * The fields are accessed using the mechanism defined in {@link ObjectStreamClass}, + * which causes objects and primitives to each be packed into a separate array + * whose relative field offsets are defined in the {@link ObjectStreamField} + * corresponding to each field. + * + * @param streamClass the object stream class of the object (must not be {@code null}) + * @param obj the object to serialize (must not be {@code null}) + * @param oos the object stream (must not be {@code null}) + * @throws IOException if the call to {@link ObjectInputStream#readFields} + * or one of its field accessors throws this exception type + */ + private static void defaultWriteObject(ObjectStreamClass streamClass, Object obj, ObjectOutputStream oos) + throws IOException { + ObjectOutputStream.PutField putField = oos.putFields(); + byte[] bytes = new byte[streamClass.getPrimDataSize()]; + Object[] objs = new Object[streamClass.getNumObjFields()]; + streamClass.getPrimFieldValues(obj, bytes); + streamClass.getObjFieldValues(obj, objs); + for (ObjectStreamField field : streamClass.getFields(false)) { + int offset = field.getOffset(); + String fieldName = field.getName(); + switch (field.getTypeCode()) { + case 'B' -> putField.put(fieldName, bytes[offset]); + case 'C' -> putField.put(fieldName, ByteArray.getChar(bytes, offset)); + case 'D' -> putField.put(fieldName, ByteArray.getDouble(bytes, offset)); + case 'F' -> putField.put(fieldName, ByteArray.getFloat(bytes, offset)); + case 'I' -> putField.put(fieldName, ByteArray.getInt(bytes, offset)); + case 'J' -> putField.put(fieldName, ByteArray.getLong(bytes, offset)); + case 'S' -> putField.put(fieldName, ByteArray.getShort(bytes, offset)); + case 'Z' -> putField.put(fieldName, ByteArray.getBoolean(bytes, offset)); + case '[', 'L' -> putField.put(fieldName, objs[offset]); + default -> throw new IllegalStateException(); + } + } + oos.writeFields(); + } + + static final class Access implements JavaObjectStreamReflectionAccess { + static { + SharedSecrets.setJavaObjectStreamReflectionAccess(new Access()); + } + + public MethodHandle defaultReadObject(Class<?> clazz) { + return handleForClass(DRO_HANDLE, clazz, ObjectInputStream.class); + } + + public MethodHandle defaultWriteObject(Class<?> clazz) { + return handleForClass(DWO_HANDLE, clazz, ObjectOutputStream.class); + } + + private static MethodHandle handleForClass(final MethodHandle handle, final Class<?> clazz, final Class<?> ioClass) { + ObjectStreamClass streamClass = ObjectStreamClass.lookup(clazz); + if (streamClass != null) { + try { + streamClass.checkDefaultSerialize(); + return handle.bindTo(streamClass) + .asType(MethodType.methodType(void.class, clazz, ioClass)); + } catch (InvalidClassException e) { + // ignore and return null + } + } + return null; + } + } +} diff --git a/src/java.base/share/classes/jdk/internal/access/JavaObjectStreamReflectionAccess.java b/src/java.base/share/classes/jdk/internal/access/JavaObjectStreamReflectionAccess.java new file mode 100644 index 00000000000..ea3e219e8ab --- /dev/null +++ b/src/java.base/share/classes/jdk/internal/access/JavaObjectStreamReflectionAccess.java @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package jdk.internal.access; + +import java.lang.invoke.MethodHandle; + +public interface JavaObjectStreamReflectionAccess { + MethodHandle defaultReadObject(Class<?> clazz); + MethodHandle defaultWriteObject(Class<?> clazz); +} diff --git a/src/java.base/share/classes/jdk/internal/access/SharedSecrets.java b/src/java.base/share/classes/jdk/internal/access/SharedSecrets.java index c29d0dd01a5..43a1daf762c 100644 --- a/src/java.base/share/classes/jdk/internal/access/SharedSecrets.java +++ b/src/java.base/share/classes/jdk/internal/access/SharedSecrets.java @@ -77,6 +77,7 @@ public class SharedSecrets { private static JavaObjectInputStreamReadString javaObjectInputStreamReadString; private static JavaObjectInputStreamAccess javaObjectInputStreamAccess; private static JavaObjectInputFilterAccess javaObjectInputFilterAccess; + private static JavaObjectStreamReflectionAccess javaObjectStreamReflectionAccess; private static JavaNetInetAddressAccess javaNetInetAddressAccess; private static JavaNetHttpCookieAccess javaNetHttpCookieAccess; private static JavaNetUriAccess javaNetUriAccess; @@ -431,6 +432,21 @@ public static void setJavaObjectInputFilterAccess(JavaObjectInputFilterAccess ac javaObjectInputFilterAccess = access; } + public static JavaObjectStreamReflectionAccess getJavaObjectStreamReflectionAccess() { + var access = javaObjectStreamReflectionAccess; + if (access == null) { + try { + Class.forName("java.io.ObjectStreamReflection$Access", true, null); + access = javaObjectStreamReflectionAccess; + } catch (ClassNotFoundException e) {} + } + return access; + } + + public static void setJavaObjectStreamReflectionAccess(JavaObjectStreamReflectionAccess access) { + javaObjectStreamReflectionAccess = access; + } + public static void setJavaIORandomAccessFileAccess(JavaIORandomAccessFileAccess jirafa) { javaIORandomAccessFileAccess = jirafa; } diff --git a/src/java.base/share/classes/jdk/internal/reflect/ReflectionFactory.java b/src/java.base/share/classes/jdk/internal/reflect/ReflectionFactory.java index bcaa8bacbaa..687e32cdf61 100644 --- a/src/java.base/share/classes/jdk/internal/reflect/ReflectionFactory.java +++ b/src/java.base/share/classes/jdk/internal/reflect/ReflectionFactory.java @@ -29,6 +29,7 @@ import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.ObjectStreamClass; +import java.io.ObjectStreamField; import java.io.OptionalDataException; import java.io.Serializable; import java.lang.invoke.MethodHandle; @@ -39,7 +40,10 @@ import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.Modifier; +import java.lang.reflect.Proxy; import java.security.PrivilegedAction; +import java.util.Set; + import jdk.internal.access.JavaLangReflectAccess; import jdk.internal.access.SharedSecrets; import jdk.internal.misc.VM; @@ -66,6 +70,7 @@ public class ReflectionFactory { private static volatile Method hasStaticInitializerMethod; private final JavaLangReflectAccess langReflectAccess; + private ReflectionFactory() { this.langReflectAccess = SharedSecrets.getJavaLangReflectAccess(); } @@ -363,6 +368,46 @@ private final MethodHandle findReadWriteObjectForSerialization(Class<?> cl, } } + public final MethodHandle defaultReadObjectForSerialization(Class<?> cl) { + if (hasDefaultOrNoSerialization(cl)) { + return null; + } + + return SharedSecrets.getJavaObjectStreamReflectionAccess().defaultReadObject(cl); + } + + public final MethodHandle defaultWriteObjectForSerialization(Class<?> cl) { + if (hasDefaultOrNoSerialization(cl)) { + return null; + } + + return SharedSecrets.getJavaObjectStreamReflectionAccess().defaultWriteObject(cl); + } + + /** + * These are specific leaf classes which appear to be Serializable, but which + * have special semantics according to the serialization specification. We + * could theoretically include array classes here, but it is easier and clearer + * to just use `Class#isArray` instead. + */ + private static final Set<Class<?>> nonSerializableLeafClasses = Set.of( + Class.class, + String.class, + ObjectStreamClass.class + ); + + private static boolean hasDefaultOrNoSerialization(Class<?> cl) { + return ! Serializable.class.isAssignableFrom(cl) + || cl.isInterface() + || cl.isArray() + || Proxy.isProxyClass(cl) + || Externalizable.class.isAssignableFrom(cl) + || cl.isEnum() + || cl.isRecord() + || cl.isHidden() + || nonSerializableLeafClasses.contains(cl); + } + /** * Returns a MethodHandle for {@code writeReplace} on the serializable class * or null if no match found. @@ -468,6 +513,28 @@ public final Constructor<OptionalDataException> newOptionalDataExceptionForSeria } } + public final ObjectStreamField[] serialPersistentFields(Class<?> cl) { + if (! Serializable.class.isAssignableFrom(cl) || cl.isInterface() || cl.isEnum()) { + return null; + } + + try { + Field field = cl.getDeclaredField("serialPersistentFields"); + int mods = field.getModifiers(); + if (! (Modifier.isStatic(mods) && Modifier.isPrivate(mods) && Modifier.isFinal(mods))) { + return null; + } + if (field.getType() != ObjectStreamField[].class) { + return null; + } + field.setAccessible(true); + ObjectStreamField[] array = (ObjectStreamField[]) field.get(null); + return array != null && array.length > 0 ? array.clone() : array; + } catch (ReflectiveOperationException e) { + return null; + } + } + //-------------------------------------------------------------------------- // // Internals only below this point @@ -556,5 +623,4 @@ private static boolean packageEquals(Class<?> cl1, Class<?> cl2) { return cl1.getClassLoader() == cl2.getClassLoader() && cl1.getPackageName() == cl2.getPackageName(); } - } diff --git a/src/jdk.unsupported/share/classes/sun/reflect/ReflectionFactory.java b/src/jdk.unsupported/share/classes/sun/reflect/ReflectionFactory.java index b6c538c507f..e671e1db526 100644 --- a/src/jdk.unsupported/share/classes/sun/reflect/ReflectionFactory.java +++ b/src/jdk.unsupported/share/classes/sun/reflect/ReflectionFactory.java @@ -25,6 +25,9 @@ package sun.reflect; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.io.ObjectStreamField; import java.io.OptionalDataException; import java.lang.invoke.MethodHandle; import java.lang.reflect.Constructor; @@ -129,6 +132,50 @@ public final MethodHandle readObjectNoDataForSerialization(Class<?> cl) { return delegate.readObjectNoDataForSerialization(cl); } + /** + * Generate and return a direct MethodHandle which implements + * the general default behavior for serializable class's {@code readObject}. + * The generated method behaves in accordance with the + * Java Serialization specification's rules for that method. + * <p> + * The generated method will invoke {@link ObjectInputStream#readFields()} + * to acquire the stream field values. The serialization fields of the class will + * then be populated from the stream values. + * <p> + * Only fields which are eligible for default serialization will be populated. + * This includes only fields which are not {@code transient} and not {@code static} + * (even if the field is {@code final} or {@code private}). + * <p> + * Requesting a default serialization method for a class in a disallowed + * category is not supported; {@code null} will be returned for such classes. + * The disallowed categories include (but are not limited to): + * <ul> + * <li>Classes which do not implement {@code Serializable}</li> + * <li>Classes which implement {@code Externalizable}</li> + * <li>Classes which are specially handled by the Java Serialization specification, + * including record classes, enum constant classes, {@code Class}, {@code String}, + * array classes, reflection proxy classes, and hidden classes</li> + * <li>Classes which declare a valid {@code serialPersistentFields} value</li> + * <li>Any special types which may possibly be added to the JDK or the Java language + * in the future which in turn might require special handling by the + * provisions of the corresponding future version of the Java Serialization + * specification</li> + * </ul> + * <p> + * The generated method will accept the instance as its first argument + * and the {@code ObjectInputStream} as its second argument. + * The return type of the method is {@code void}. + * + * @param cl a Serializable class + * @return a direct MethodHandle for the synthetic {@code readObject} method + * or {@code null} if the class falls in a disallowed category + * + * @since 24 + */ + public final MethodHandle defaultReadObjectForSerialization(Class<?> cl) { + return delegate.defaultReadObjectForSerialization(cl); + } + /** * Returns a direct MethodHandle for the {@code writeObject} method on * a Serializable class. @@ -144,6 +191,53 @@ public final MethodHandle writeObjectForSerialization(Class<?> cl) { return delegate.writeObjectForSerialization(cl); } + /** + * Generate and return a direct MethodHandle which implements + * the general default behavior for serializable class's {@code writeObject}. + * The generated method behaves in accordance with the + * Java Serialization specification's rules for that method. + * <p> + * The generated method will invoke {@link ObjectOutputStream#putFields} + * to acquire the buffer for the stream field values. The buffer will + * be populated from the serialization fields of the class. The buffer + * will then be flushed to the stream using the + * {@link ObjectOutputStream#writeFields()} method. + * <p> + * Only fields which are eligible for default serialization will be written + * to the buffer. + * This includes only fields which are not {@code transient} and not {@code static} + * (even if the field is {@code final} or {@code private}). + * <p> + * Requesting a default serialization method for a class in a disallowed + * category is not supported; {@code null} will be returned for such classes. + * The disallowed categories include (but are not limited to): + * <ul> + * <li>Classes which do not implement {@code Serializable}</li> + * <li>Classes which implement {@code Externalizable}</li> + * <li>Classes which are specially handled by the Java Serialization specification, + * including record classes, enum constant classes, {@code Class}, {@code String}, + * array classes, reflection proxy classes, and hidden classes</li> + * <li>Classes which declare a valid {@code serialPersistentFields} value</li> + * <li>Any special types which may possibly be added to the JDK or the Java language + * in the future which in turn might require special handling by the + * provisions of the corresponding future version of the Java Serialization + * specification</li> + * </ul> + * <p> + * The generated method will accept the instance as its first argument + * and the {@code ObjectOutputStream} as its second argument. + * The return type of the method is {@code void}. + * + * @param cl a Serializable class + * @return a direct MethodHandle for the synthetic {@code writeObject} method + * or {@code null} if the class falls in a disallowed category + * + * @since 24 + */ + public final MethodHandle defaultWriteObjectForSerialization(Class<?> cl) { + return delegate.defaultWriteObjectForSerialization(cl); + } + /** * Returns a direct MethodHandle for the {@code readResolve} method on * a serializable class. @@ -197,4 +291,21 @@ public final OptionalDataException newOptionalDataExceptionForSerialization(bool throw new InternalError("unable to create OptionalDataException", ex); } } + + /** + * {@return the declared {@code serialPersistentFields} from a + * serializable class, or {@code null} if none is declared, the field + * is declared but not valid, or the class is not a valid serializable class} + * A class is a valid serializable class if it implements {@code Serializable} + * but not {@code Externalizable}. The {@code serialPersistentFields} field + * is valid if it meets the type and accessibility restrictions defined + * by the Java Serialization specification. + * + * @param cl a Serializable class + * + * @since 24 + */ + public final ObjectStreamField[] serialPersistentFields(Class<?> cl) { + return delegate.serialPersistentFields(cl); + } } diff --git a/test/jdk/sun/reflect/ReflectionFactory/ReflectionFactoryTest.java b/test/jdk/sun/reflect/ReflectionFactory/ReflectionFactoryTest.java index 03dade05b14..b86ee4db0b9 100644 --- a/test/jdk/sun/reflect/ReflectionFactory/ReflectionFactoryTest.java +++ b/test/jdk/sun/reflect/ReflectionFactory/ReflectionFactoryTest.java @@ -29,12 +29,16 @@ import java.io.ObjectInputStream; import java.io.ObjectOutput; import java.io.ObjectOutputStream; +import java.io.ObjectStreamClass; import java.io.ObjectStreamException; +import java.io.ObjectStreamField; import java.io.OptionalDataException; +import java.io.Serial; import java.io.Serializable; import java.lang.invoke.MethodHandle; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; +import java.util.Arrays; import sun.reflect.ReflectionFactory; @@ -46,7 +50,7 @@ /* * @test - * @bug 8137058 8164908 8168980 8275137 + * @bug 8137058 8164908 8168980 8275137 8333796 * @summary Basic test for the unsupported ReflectionFactory * @modules jdk.unsupported * @run testng ReflectionFactoryTest @@ -327,6 +331,509 @@ static void newOptionalDataException() { } + private static final String[] names = { + "boolean_", + "final_boolean", + "byte_", + "final_byte", + "char_", + "final_char", + "short_", + "final_short", + "int_", + "final_int", + "long_", + "final_long", + "float_", + "final_float", + "double_", + "final_double", + "str", + "final_str", + "writeFields", + }; + + // test that the generated read/write objects are working properly + @Test + static void testDefaultReadWriteObject() throws Throwable { + Ser2 ser = new Ser2((byte) 0x33, (short) 0x2244, (char) 0x5342, 0x05382716, 0xf035a73b09113bacL, 1234f, 3456.0, true, new Ser3(0x004917aa)); + ser.byte_ = (byte) 0x44; + ser.short_ = (short) 0x3355; + ser.char_ = (char) 0x6593; + ser.int_ = 0x4928a299; + ser.long_ = 0x24aa19883f4b9138L; + ser.float_ = 4321f; + ser.double_ = 6543.0; + ser.boolean_ = false; + ser.ser = new Ser3(0x70b030a0); + // first, ensure that each field gets written + MethodHandle writeObject = factory.defaultWriteObjectForSerialization(Ser2.class); + Assert.assertNotNull(writeObject, "writeObject not created"); + boolean[] called = new boolean[19]; + @SuppressWarnings("removal") + ObjectOutputStream oos = new ObjectOutputStream() { + protected void writeObjectOverride(final Object obj) throws IOException { + throw new IOException("Wrong method called"); + } + + public void defaultWriteObject() throws IOException { + throw new IOException("Wrong method called"); + } + + public void writeFields() { + called[18] = true; + } + + public PutField putFields() { + return new PutField() { + public void put(final String name, final boolean val) { + switch (name) { + case "boolean_" -> { + Assert.assertFalse(val); + called[0] = true; + } + case "final_boolean" -> { + Assert.assertTrue(val); + called[1] = true; + } + default -> throw new Error("Unexpected field " + name); + } + } + + public void put(final String name, final byte val) { + switch (name) { + case "byte_" -> { + Assert.assertEquals(val, (byte) 0x44); + called[2] = true; + } + case "final_byte" -> { + Assert.assertEquals(val, (byte) 0x33); + called[3] = true; + } + default -> throw new Error("Unexpected field " + name); + } + } + + public void put(final String name, final char val) { + switch (name) { + case "char_" -> { + Assert.assertEquals(val, (char) 0x6593); + called[4] = true; + } + case "final_char" -> { + Assert.assertEquals(val, (char) 0x5342); + called[5] = true; + } + default -> throw new Error("Unexpected field " + name); + } + } + + public void put(final String name, final short val) { + switch (name) { + case "short_" -> { + Assert.assertEquals(val, (short) 0x3355); + called[6] = true; + } + case "final_short" -> { + Assert.assertEquals(val, (short) 0x2244); + called[7] = true; + } + default -> throw new Error("Unexpected field " + name); + } + } + + public void put(final String name, final int val) { + switch (name) { + case "int_" -> { + Assert.assertEquals(val, 0x4928a299); + called[8] = true; + } + case "final_int" -> { + Assert.assertEquals(val, 0x05382716); + called[9] = true; + } + default -> throw new Error("Unexpected field " + name); + } + } + + public void put(final String name, final long val) { + switch (name) { + case "long_" -> { + Assert.assertEquals(val, 0x24aa19883f4b9138L); + called[10] = true; + } + case "final_long" -> { + Assert.assertEquals(val, 0xf035a73b09113bacL); + called[11] = true; + } + default -> throw new Error("Unexpected field " + name); + } + } + + public void put(final String name, final float val) { + switch (name) { + case "float_" -> { + Assert.assertEquals(val, 4321f); + called[12] = true; + } + case "final_float" -> { + Assert.assertEquals(val, 1234f); + called[13] = true; + } + default -> throw new Error("Unexpected field " + name); + } + } + + public void put(final String name, final double val) { + switch (name) { + case "double_" -> { + Assert.assertEquals(val, 6543.0); + called[14] = true; + } + case "final_double" -> { + Assert.assertEquals(val, 3456.0); + called[15] = true; + } + default -> throw new Error("Unexpected field " + name); + } + } + + public void put(final String name, final Object val) { + switch (name) { + case "ser" -> { + Assert.assertEquals(val, new Ser3(0x70b030a0)); + called[16] = true; + } + case "final_ser" -> { + Assert.assertEquals(val, new Ser3(0x004917aa)); + called[17] = true; + } + default -> throw new Error("Unexpected field " + name); + } + } + + @SuppressWarnings("removal") + public void write(final ObjectOutput out) throws IOException { + throw new IOException("Wrong method called"); + } + }; + } + }; + writeObject.invokeExact(ser, oos); + for (int i = 0; i < 19; i ++) { + Assert.assertTrue(called[i], names[i]); + } + // now, test the read side + MethodHandle readObject = factory.defaultReadObjectForSerialization(Ser2.class); + Assert.assertNotNull(readObject, "readObject not created"); + @SuppressWarnings("removal") + ObjectInputStream ois = new ObjectInputStream() { + protected Object readObjectOverride() throws IOException { + throw new IOException("Wrong method called"); + } + + public GetField readFields() { + return new GetField() { + public ObjectStreamClass getObjectStreamClass() { + throw new Error("Wrong method called"); + } + + public boolean defaulted(final String name) throws IOException { + throw new IOException("Wrong method called"); + } + + public boolean get(final String name, final boolean val) { + return switch (name) { + case "boolean_" -> { + called[0] = true; + yield true; + } + case "final_boolean" -> { + called[1] = true; + yield true; + } + default -> throw new Error("Unexpected field " + name); + }; + } + + public byte get(final String name, final byte val) { + return switch (name) { + case "byte_" -> { + called[2] = true; + yield (byte) 0x11; + } + case "final_byte" -> { + called[3] = true; + yield (byte) 0x9f; + } + default -> throw new Error("Unexpected field " + name); + }; + } + + public char get(final String name, final char val) { + return switch (name) { + case "char_" -> { + called[4] = true; + yield (char) 0x59a2; + } + case "final_char" -> { + called[5] = true; + yield (char) 0xe0d0; + } + default -> throw new Error("Unexpected field " + name); + }; + } + + public short get(final String name, final short val) { + return switch (name) { + case "short_" -> { + called[6] = true; + yield (short) 0x0917; + } + case "final_short" -> { + called[7] = true; + yield (short) 0x110e; + } + default -> throw new Error("Unexpected field " + name); + }; + } + + public int get(final String name, final int val) { + return switch (name) { + case "int_" -> { + called[8] = true; + yield 0xd0244e19; + } + case "final_int" -> { + called[9] = true; + yield 0x011004da; + } + default -> throw new Error("Unexpected field " + name); + }; + } + + public long get(final String name, final long val) { + return switch (name) { + case "long_" -> { + called[10] = true; + yield 0x0b8101d84aa31711L; + } + case "final_long" -> { + called[11] = true; + yield 0x30558aa7189ed821L; + } + default -> throw new Error("Unexpected field " + name); + }; + } + + public float get(final String name, final float val) { + return switch (name) { + case "float_" -> { + called[12] = true; + yield 0x5.01923ap18f; + } + case "final_float" -> { + called[13] = true; + yield 0x0.882afap1f; + } + default -> throw new Error("Unexpected field " + name); + }; + } + + public double get(final String name, final double val) { + return switch (name) { + case "double_" -> { + called[14] = true; + yield 0x9.4a8fp6; + } + case "final_double" -> { + called[15] = true; + yield 0xf.881a8p4; + } + default -> throw new Error("Unexpected field " + name); + }; + } + + public Object get(final String name, final Object val) { + return switch (name) { + case "ser" -> { + called[16] = true; + yield new Ser3(0x44cc55dd); + } + case "final_ser" -> { + called[17] = true; + yield new Ser3(0x9a8b7c6d); + } + default -> throw new Error("Unexpected field " + name); + }; + } + }; + } + }; + // all the same methods, except for `writeFields` + Arrays.fill(called, false); + Constructor<?> ctor = factory.newConstructorForSerialization(Ser2.class, Object.class.getDeclaredConstructor()); + ser = (Ser2) ctor.newInstance(); + readObject.invokeExact(ser, ois); + // excluding "writeFields", so 18 instead of 19 + for (int i = 0; i < 18; i ++) { + Assert.assertTrue(called[i], names[i]); + } + Assert.assertEquals(ser.byte_, (byte)0x11); + Assert.assertEquals(ser.final_byte, (byte)0x9f); + Assert.assertEquals(ser.char_, (char)0x59a2); + Assert.assertEquals(ser.final_char, (char)0xe0d0); + Assert.assertEquals(ser.short_, (short)0x0917); + Assert.assertEquals(ser.final_short, (short)0x110e); + Assert.assertEquals(ser.int_, 0xd0244e19); + Assert.assertEquals(ser.final_int, 0x011004da); + Assert.assertEquals(ser.long_, 0x0b8101d84aa31711L); + Assert.assertEquals(ser.final_long, 0x30558aa7189ed821L); + Assert.assertEquals(ser.float_, 0x5.01923ap18f); + Assert.assertEquals(ser.final_float, 0x0.882afap1f); + Assert.assertEquals(ser.double_, 0x9.4a8fp6); + Assert.assertEquals(ser.final_double, 0xf.881a8p4); + Assert.assertEquals(ser.ser, new Ser3(0x44cc55dd)); + Assert.assertEquals(ser.final_ser, new Ser3(0x9a8b7c6d)); + } + + static class Ser2 implements Serializable { + @Serial + private static final long serialVersionUID = -2852896623833548574L; + + byte byte_; + short short_; + char char_; + int int_; + long long_; + float float_; + double double_; + boolean boolean_; + Ser3 ser; + + final byte final_byte; + final short final_short; + final char final_char; + final int final_int; + final long final_long; + final float final_float; + final double final_double; + final boolean final_boolean; + final Ser3 final_ser; + + Ser2(final byte final_byte, final short final_short, final char final_char, final int final_int, + final long final_long, final float final_float, final double final_double, + final boolean final_boolean, final Ser3 final_ser) { + + this.final_byte = final_byte; + this.final_short = final_short; + this.final_char = final_char; + this.final_int = final_int; + this.final_long = final_long; + this.final_float = final_float; + this.final_double = final_double; + this.final_boolean = final_boolean; + this.final_ser = final_ser; + } + } + + static class Ser3 implements Serializable { + @Serial + private static final long serialVersionUID = -1234752876749422678L; + + @Serial + private static final ObjectStreamField[] serialPersistentFields = { + new ObjectStreamField("value", int.class) + }; + + final int value; + + Ser3(final int value) { + this.value = value; + } + + public boolean equals(final Object obj) { + return obj instanceof Ser3 s && value == s.value; + } + + public int hashCode() { + return value; + } + } + + static class SerInvalidFields implements Serializable { + // this is deliberately wrong + @SuppressWarnings({"unused", "serial"}) + @Serial + private static final String serialPersistentFields = "Oops!"; + @Serial + private static final long serialVersionUID = -8090960816811629489L; + } + + static class Ext1 implements Externalizable { + + @Serial + private static final long serialVersionUID = 7109990719266285013L; + + public void writeExternal(final ObjectOutput objectOutput) { + } + + public void readExternal(final ObjectInput objectInput) { + } + } + + static class Ext2 implements Externalizable { + public void writeExternal(final ObjectOutput objectOutput) { + } + + public void readExternal(final ObjectInput objectInput) { + } + } + + record Rec1(int hello, boolean world) implements Serializable { + @Serial + private static final long serialVersionUID = 12349876L; + } + + enum Enum1 { + hello, + world, + ; + private static final long serialVersionUID = 1020304050L; + } + + interface Proxy1 { + void hello(); + } + + static class SerialPersistentFields implements Serializable { + @Serial + private static final long serialVersionUID = -4947917866973382882L; + @Serial + private static final ObjectStreamField[] serialPersistentFields = { + new ObjectStreamField("array1", Object[].class), + new ObjectStreamField("nonExistent", String.class) + }; + + private int int1; + private Object[] array1; + } + + // Check our simple accessors + @Test + static void testAccessors() { + Assert.assertEquals(factory.serialPersistentFields(Ser3.class), Ser3.serialPersistentFields); + Assert.assertNotSame(factory.serialPersistentFields(Ser3.class), Ser3.serialPersistentFields); + Assert.assertNull(factory.serialPersistentFields(SerInvalidFields.class)); + } + + // Ensure that classes with serialPersistentFields do not allow default setting/getting + @Test + static void testDisallowed() { + Assert.assertNull(factory.defaultWriteObjectForSerialization(SerialPersistentFields.class)); + Assert.assertNull(factory.defaultReadObjectForSerialization(SerialPersistentFields.class)); + } + // Main can be used to run the tests from the command line with only testng.jar. @SuppressWarnings("raw_types") @Test(enabled = false) From 75420e9314c54adc5b45f9b274a87af54dd6b5a8 Mon Sep 17 00:00:00 2001 From: Emanuel Peter <epeter@openjdk.org> Date: Wed, 20 Nov 2024 14:23:57 +0000 Subject: [PATCH 132/311] 8334431: C2 SuperWord: fix performance regression due to store-to-load-forwarding failures Reviewed-by: chagedorn, qamai --- .../cpu/aarch64/c2_globals_aarch64.hpp | 1 + src/hotspot/cpu/arm/c2_globals_arm.hpp | 1 + src/hotspot/cpu/ppc/c2_globals_ppc.hpp | 1 + src/hotspot/cpu/riscv/c2_globals_riscv.hpp | 1 + src/hotspot/cpu/s390/c2_globals_s390.hpp | 1 + src/hotspot/cpu/x86/c2_globals_x86.hpp | 1 + src/hotspot/share/opto/c2_globals.hpp | 6 + src/hotspot/share/opto/superword.cpp | 1 + src/hotspot/share/opto/vectorization.cpp | 12 +- src/hotspot/share/opto/vectorization.hpp | 1 + src/hotspot/share/opto/vtransform.cpp | 268 +++++++++++++++++ src/hotspot/share/opto/vtransform.hpp | 18 ++ .../loopopts/superword/TestAlignVector.java | 117 +++++++- .../superword/TestCyclicDependency.java | 273 ++++++++++++++++-- .../superword/TestDependencyOffsets.java | 95 ++++-- .../runner/LoopCombinedOpTest.java | 5 +- .../compiler/VectorStoreToLoadForwarding.java | 142 +++++++++ 17 files changed, 881 insertions(+), 63 deletions(-) create mode 100644 test/micro/org/openjdk/bench/vm/compiler/VectorStoreToLoadForwarding.java diff --git a/src/hotspot/cpu/aarch64/c2_globals_aarch64.hpp b/src/hotspot/cpu/aarch64/c2_globals_aarch64.hpp index 34e6e688abb..e57dab7d1ed 100644 --- a/src/hotspot/cpu/aarch64/c2_globals_aarch64.hpp +++ b/src/hotspot/cpu/aarch64/c2_globals_aarch64.hpp @@ -66,6 +66,7 @@ define_pd_global(bool, OptoScheduling, false); define_pd_global(bool, OptoBundling, false); define_pd_global(bool, OptoRegScheduling, false); define_pd_global(bool, SuperWordLoopUnrollAnalysis, true); +define_pd_global(uint, SuperWordStoreToLoadForwardingFailureDetection, 8); define_pd_global(bool, IdealizeClearArrayNode, true); define_pd_global(intx, ReservedCodeCacheSize, 48*M); diff --git a/src/hotspot/cpu/arm/c2_globals_arm.hpp b/src/hotspot/cpu/arm/c2_globals_arm.hpp index 57ed8f11c08..a44a8f649ae 100644 --- a/src/hotspot/cpu/arm/c2_globals_arm.hpp +++ b/src/hotspot/cpu/arm/c2_globals_arm.hpp @@ -64,6 +64,7 @@ define_pd_global(bool, OptoBundling, false); define_pd_global(bool, OptoScheduling, true); define_pd_global(bool, OptoRegScheduling, false); define_pd_global(bool, SuperWordLoopUnrollAnalysis, false); +define_pd_global(uint, SuperWordStoreToLoadForwardingFailureDetection, 16); define_pd_global(bool, IdealizeClearArrayNode, true); #ifdef _LP64 diff --git a/src/hotspot/cpu/ppc/c2_globals_ppc.hpp b/src/hotspot/cpu/ppc/c2_globals_ppc.hpp index 00a92ff6b62..f45faa21f01 100644 --- a/src/hotspot/cpu/ppc/c2_globals_ppc.hpp +++ b/src/hotspot/cpu/ppc/c2_globals_ppc.hpp @@ -59,6 +59,7 @@ define_pd_global(bool, UseCISCSpill, false); define_pd_global(bool, OptoBundling, false); define_pd_global(bool, OptoRegScheduling, false); define_pd_global(bool, SuperWordLoopUnrollAnalysis, true); +define_pd_global(uint, SuperWordStoreToLoadForwardingFailureDetection, 16); // GL: // Detected a problem with unscaled compressed oops and // narrow_oop_use_complex_address() == false. diff --git a/src/hotspot/cpu/riscv/c2_globals_riscv.hpp b/src/hotspot/cpu/riscv/c2_globals_riscv.hpp index 53a41665f4b..e9947f9888a 100644 --- a/src/hotspot/cpu/riscv/c2_globals_riscv.hpp +++ b/src/hotspot/cpu/riscv/c2_globals_riscv.hpp @@ -66,6 +66,7 @@ define_pd_global(bool, OptoScheduling, true); define_pd_global(bool, OptoBundling, false); define_pd_global(bool, OptoRegScheduling, false); define_pd_global(bool, SuperWordLoopUnrollAnalysis, true); +define_pd_global(uint, SuperWordStoreToLoadForwardingFailureDetection, 16); define_pd_global(bool, IdealizeClearArrayNode, true); define_pd_global(intx, ReservedCodeCacheSize, 48*M); diff --git a/src/hotspot/cpu/s390/c2_globals_s390.hpp b/src/hotspot/cpu/s390/c2_globals_s390.hpp index 1de38f100f6..7f780ca63a0 100644 --- a/src/hotspot/cpu/s390/c2_globals_s390.hpp +++ b/src/hotspot/cpu/s390/c2_globals_s390.hpp @@ -61,6 +61,7 @@ define_pd_global(bool, OptoBundling, false); define_pd_global(bool, OptoScheduling, false); define_pd_global(bool, OptoRegScheduling, false); define_pd_global(bool, SuperWordLoopUnrollAnalysis, true); +define_pd_global(uint, SuperWordStoreToLoadForwardingFailureDetection, 16); // On s390x, we can clear the array with a single instruction, // so don't idealize it. define_pd_global(bool, IdealizeClearArrayNode, false); diff --git a/src/hotspot/cpu/x86/c2_globals_x86.hpp b/src/hotspot/cpu/x86/c2_globals_x86.hpp index f7315011e6b..084dde217e4 100644 --- a/src/hotspot/cpu/x86/c2_globals_x86.hpp +++ b/src/hotspot/cpu/x86/c2_globals_x86.hpp @@ -76,6 +76,7 @@ define_pd_global(bool, OptoScheduling, false); define_pd_global(bool, OptoBundling, false); define_pd_global(bool, OptoRegScheduling, true); define_pd_global(bool, SuperWordLoopUnrollAnalysis, true); +define_pd_global(uint, SuperWordStoreToLoadForwardingFailureDetection, 16); define_pd_global(bool, IdealizeClearArrayNode, true); define_pd_global(uintx, ReservedCodeCacheSize, 48*M); diff --git a/src/hotspot/share/opto/c2_globals.hpp b/src/hotspot/share/opto/c2_globals.hpp index 45a067a830b..d4b55ec2d8d 100644 --- a/src/hotspot/share/opto/c2_globals.hpp +++ b/src/hotspot/share/opto/c2_globals.hpp @@ -355,6 +355,12 @@ product(bool, SuperWordReductions, true, \ "Enable reductions support in superword.") \ \ + product_pd(uint, SuperWordStoreToLoadForwardingFailureDetection, DIAGNOSTIC, \ + "if >0, auto-vectorization detects possible store-to-load " \ + "forwarding failures. The number specifies over how many " \ + "loop iterations this detection spans.") \ + range(0, 4096) \ + \ product(bool, UseCMoveUnconditionally, false, \ "Use CMove (scalar and vector) ignoring profitability test.") \ \ diff --git a/src/hotspot/share/opto/superword.cpp b/src/hotspot/share/opto/superword.cpp index 20c8dfbff17..8000e4fd39e 100644 --- a/src/hotspot/share/opto/superword.cpp +++ b/src/hotspot/share/opto/superword.cpp @@ -1868,6 +1868,7 @@ bool SuperWord::schedule_and_apply() const { } if (!vtransform.schedule()) { return false; } + if (vtransform.has_store_to_load_forwarding_failure()) { return false; } vtransform.apply(); return true; } diff --git a/src/hotspot/share/opto/vectorization.cpp b/src/hotspot/share/opto/vectorization.cpp index fc4eaccff5c..4d152189625 100644 --- a/src/hotspot/share/opto/vectorization.cpp +++ b/src/hotspot/share/opto/vectorization.cpp @@ -31,7 +31,7 @@ #include "opto/vectorization.hpp" #ifndef PRODUCT -static void print_con_or_idx(const Node* n) { +void VPointer::print_con_or_idx(const Node* n) { if (n == nullptr) { tty->print("( 0)"); } else if (n->is_ConI()) { @@ -1369,12 +1369,12 @@ void VPointer::print() const { tty->print("adr: %4d, ", _adr != nullptr ? _adr->_idx : 0); tty->print(" base"); - print_con_or_idx(_base); + VPointer::print_con_or_idx(_base); tty->print(" + offset(%4d)", _offset); tty->print(" + invar"); - print_con_or_idx(_invar); + VPointer::print_con_or_idx(_invar); tty->print_cr(" + scale(%4d) * iv]", _scale); } @@ -2168,15 +2168,15 @@ void AlignmentSolver::trace_start_solve() const { // iv = init + pre_iter * pre_stride + main_iter * main_stride tty->print(" iv = init"); - print_con_or_idx(_init_node); + VPointer::print_con_or_idx(_init_node); tty->print_cr(" + pre_iter * pre_stride(%d) + main_iter * main_stride(%d)", _pre_stride, _main_stride); // adr = base + offset + invar + scale * iv tty->print(" adr = base"); - print_con_or_idx(_base); + VPointer::print_con_or_idx(_base); tty->print(" + offset(%d) + invar", _offset); - print_con_or_idx(_invar); + VPointer::print_con_or_idx(_invar); tty->print_cr(" + scale(%d) * iv", _scale); } } diff --git a/src/hotspot/share/opto/vectorization.hpp b/src/hotspot/share/opto/vectorization.hpp index b084edd44b3..98aa3336ded 100644 --- a/src/hotspot/share/opto/vectorization.hpp +++ b/src/hotspot/share/opto/vectorization.hpp @@ -870,6 +870,7 @@ class VPointer : public ArenaObj { static int cmp_for_sort(const VPointer** p1, const VPointer** p2); NOT_PRODUCT( void print() const; ) + NOT_PRODUCT( static void print_con_or_idx(const Node* n); ) #ifndef PRODUCT class Tracer { diff --git a/src/hotspot/share/opto/vtransform.cpp b/src/hotspot/share/opto/vtransform.cpp index 7c7aca3b90e..d09a4c899f6 100644 --- a/src/hotspot/share/opto/vtransform.cpp +++ b/src/hotspot/share/opto/vtransform.cpp @@ -144,6 +144,274 @@ void VTransformApplyResult::trace(VTransformNode* vtnode) const { } #endif +// We use two comparisons, because a subtraction could underflow. +#define RETURN_CMP_VALUE_IF_NOT_EQUAL(a, b) \ + if (a < b) { return -1; } \ + if (a > b) { return 1; } + +// Helper-class for VTransformGraph::has_store_to_load_forwarding_failure. +// It represents a memory region: [ptr, ptr + memory_size) +class VMemoryRegion : public StackObj { +private: + Node* _base; // ptr = base + offset + invar + scale * iv + int _scale; + Node* _invar; + int _offset; + uint _memory_size; + bool _is_load; // load or store? + uint _schedule_order; + +public: + VMemoryRegion() {} // empty constructor for GrowableArray + VMemoryRegion(const VPointer& vpointer, int iv_offset, int vector_length, uint schedule_order) : + _base(vpointer.base()), + _scale(vpointer.scale_in_bytes()), + _invar(vpointer.invar()), + _offset(vpointer.offset_in_bytes() + _scale * iv_offset), + _memory_size(vpointer.memory_size() * vector_length), + _is_load(vpointer.mem()->is_Load()), + _schedule_order(schedule_order) {} + + Node* base() const { return _base; } + int scale() const { return _scale; } + Node* invar() const { return _invar; } + int offset() const { return _offset; } + uint memory_size() const { return _memory_size; } + bool is_load() const { return _is_load; } + uint schedule_order() const { return _schedule_order; } + + static int cmp_for_sort_by_group(VMemoryRegion* r1, VMemoryRegion* r2) { + RETURN_CMP_VALUE_IF_NOT_EQUAL(r1->base()->_idx, r2->base()->_idx); + RETURN_CMP_VALUE_IF_NOT_EQUAL(r1->scale(), r2->scale()); + int r1_invar_idx = r1->invar() == nullptr ? 0 : r1->invar()->_idx; + int r2_invar_idx = r2->invar() == nullptr ? 0 : r2->invar()->_idx; + RETURN_CMP_VALUE_IF_NOT_EQUAL(r1_invar_idx, r2_invar_idx); + return 0; // equal + } + + static int cmp_for_sort(VMemoryRegion* r1, VMemoryRegion* r2) { + int cmp_group = cmp_for_sort_by_group(r1, r2); + if (cmp_group != 0) { return cmp_group; } + + RETURN_CMP_VALUE_IF_NOT_EQUAL(r1->offset(), r2->offset()); + return 0; // equal + } + + enum Aliasing { DIFFERENT_GROUP, BEFORE, EXACT_OVERLAP, PARTIAL_OVERLAP, AFTER }; + + Aliasing aliasing(VMemoryRegion& other) { + VMemoryRegion* p1 = this; + VMemoryRegion* p2 = &other; + if (cmp_for_sort_by_group(p1, p2) != 0) { return DIFFERENT_GROUP; } + + jlong offset1 = p1->offset(); + jlong offset2 = p2->offset(); + jlong memory_size1 = p1->memory_size(); + jlong memory_size2 = p2->memory_size(); + + if (offset1 >= offset2 + memory_size2) { return AFTER; } + if (offset2 >= offset1 + memory_size1) { return BEFORE; } + if (offset1 == offset2 && memory_size1 == memory_size2) { return EXACT_OVERLAP; } + return PARTIAL_OVERLAP; + } + +#ifndef PRODUCT + void print() const { + tty->print("VMemoryRegion[%s %dbytes, schedule_order(%4d), base", + _is_load ? "load " : "store", _memory_size, _schedule_order); + VPointer::print_con_or_idx(_base); + tty->print(" + offset(%4d)", _offset); + tty->print(" + invar"); + VPointer::print_con_or_idx(_invar); + tty->print_cr(" + scale(%4d) * iv]", _scale); + } +#endif +}; + +// Store-to-load-forwarding is a CPU memory optimization, where a load can directly fetch +// its value from the store-buffer, rather than from the L1 cache. This is many CPU cycles +// faster. However, this optimization comes with some restrictions, depending on the CPU. +// Generally, store-to-load-forwarding works if the load and store memory regions match +// exactly (same start and width). Generally problematic are partial overlaps - though +// some CPU's can handle even some subsets of these cases. We conservatively assume that +// all such partial overlaps lead to a store-to-load-forwarding failures, which means the +// load has to stall until the store goes from the store-buffer into the L1 cache, incurring +// a penalty of many CPU cycles. +// +// Example (with "iteration distance" 2): +// for (int i = 10; i < SIZE; i++) { +// aI[i] = aI[i - 2] + 1; +// } +// +// load_4_bytes( ptr + -8) +// store_4_bytes(ptr + 0) * +// load_4_bytes( ptr + -4) | +// store_4_bytes(ptr + 4) | * +// load_4_bytes( ptr + 0) <-+ | +// store_4_bytes(ptr + 8) | +// load_4_bytes( ptr + 4) <---+ +// store_4_bytes(ptr + 12) +// ... +// +// In the scalar loop, we can forward the stores from 2 iterations back. +// +// Assume we have 2-element vectors (2*4 = 8 bytes), with the "iteration distance" 2 +// example. This gives us this machine code: +// load_8_bytes( ptr + -8) +// store_8_bytes(ptr + 0) | +// load_8_bytes( ptr + 0) v +// store_8_bytes(ptr + 8) | +// load_8_bytes( ptr + 8) v +// store_8_bytes(ptr + 16) +// ... +// +// We packed 2 iterations, and the stores can perfectly forward to the loads of +// the next 2 iterations. +// +// Example (with "iteration distance" 3): +// for (int i = 10; i < SIZE; i++) { +// aI[i] = aI[i - 3] + 1; +// } +// +// load_4_bytes( ptr + -12) +// store_4_bytes(ptr + 0) * +// load_4_bytes( ptr + -8) | +// store_4_bytes(ptr + 4) | +// load_4_bytes( ptr + -4) | +// store_4_bytes(ptr + 8) | +// load_4_bytes( ptr + 0) <-+ +// store_4_bytes(ptr + 12) +// ... +// +// In the scalar loop, we can forward the stores from 3 iterations back. +// +// Unfortunately, vectorization can introduce such store-to-load-forwarding failures. +// Assume we have 2-element vectors (2*4 = 8 bytes), with the "iteration distance" 3 +// example. This gives us this machine code: +// load_8_bytes( ptr + -12) +// store_8_bytes(ptr + 0) | | +// load_8_bytes( ptr + -4) x | +// store_8_bytes(ptr + 8) || +// load_8_bytes( ptr + 4) xx <-- partial overlap with 2 stores +// store_8_bytes(ptr + 16) +// ... +// +// We see that eventually all loads are dependent on earlier stores, but the values cannot +// be forwarded because there is some partial overlap. +// +// Preferably, we would have some latency-based cost-model that accounts for such forwarding +// failures, and decide if vectorization with forwarding failures is still profitable. For +// now we go with a simpler heuristic: we simply forbid vectorization if we can PROVE that +// there will be a forwarding failure. This approach has at least 2 possible weaknesses: +// +// (1) There may be forwarding failures in cases where we cannot prove it. +// Example: +// for (int i = 10; i < SIZE; i++) { +// bI[i] = aI[i - 3] + 1; +// } +// +// We do not know if aI and bI refer to the same array or not. However, it is reasonable +// to assume that if we have two different array references, that they most likely refer +// to different arrays (i.e. no aliasing), where we would have no forwarding failures. +// (2) There could be some loops where vectorization introduces forwarding failures, and thus +// the latency of the loop body is high, but this does not matter because it is dominated +// by other latency/throughput based costs in the loop body. +// +// Performance measurements with the JMH benchmark StoreToLoadForwarding.java have indicated +// that there is some iteration threshold: if the failure happens between a store and load that +// have an iteration distance below this threshold, the latency is the limiting factor, and we +// should not vectorize to avoid the latency penalty of store-to-load-forwarding failures. If +// the iteration distance is larger than this threshold, the throughput is the limiting factor, +// and we should vectorize in these cases to improve throughput. +// +bool VTransformGraph::has_store_to_load_forwarding_failure(const VLoopAnalyzer& vloop_analyzer) const { + if (SuperWordStoreToLoadForwardingFailureDetection == 0) { return false; } + + // Collect all pointers for scalar and vector loads/stores. + ResourceMark rm; + GrowableArray<VMemoryRegion> memory_regions; + + // To detect store-to-load-forwarding failures at the iteration threshold or below, we + // simulate a super-unrolling to reach SuperWordStoreToLoadForwardingFailureDetection + // iterations at least. This is a heuristic, and we are not trying to be very precise + // with the iteration distance. If we have already unrolled more than the iteration + // threshold, i.e. if "SuperWordStoreToLoadForwardingFailureDetection < unrolled_count", + // then we simply check if there are any store-to-load-forwarding failures in the unrolled + // loop body, which may be at larger distance than the desired threshold. We cannot do any + // more fine-grained analysis, because the unrolling has lost the information about the + // iteration distance. + int simulated_unrolling_count = SuperWordStoreToLoadForwardingFailureDetection; + int unrolled_count = vloop_analyzer.vloop().cl()->unrolled_count(); + uint simulated_super_unrolling_count = MAX2(1, simulated_unrolling_count / unrolled_count); + int iv_stride = vloop_analyzer.vloop().iv_stride(); + int schedule_order = 0; + for (uint k = 0; k < simulated_super_unrolling_count; k++) { + int iv_offset = k * iv_stride; // virtual super-unrolling + for (int i = 0; i < _schedule.length(); i++) { + VTransformNode* vtn = _schedule.at(i); + if (vtn->is_load_or_store_in_loop()) { + const VPointer& p = vtn->vpointer(vloop_analyzer); + if (p.valid()) { + VTransformVectorNode* vector = vtn->isa_Vector(); + uint vector_length = vector != nullptr ? vector->nodes().length() : 1; + memory_regions.push(VMemoryRegion(p, iv_offset, vector_length, schedule_order++)); + } + } + } + } + + // Sort the pointers by group (same base, invar and stride), and then by offset. + memory_regions.sort(VMemoryRegion::cmp_for_sort); + +#ifndef PRODUCT + if (_trace._verbose) { + tty->print_cr("VTransformGraph::has_store_to_load_forwarding_failure:"); + tty->print_cr(" simulated_unrolling_count = %d", simulated_unrolling_count); + tty->print_cr(" simulated_super_unrolling_count = %d", simulated_super_unrolling_count); + for (int i = 0; i < memory_regions.length(); i++) { + VMemoryRegion& region = memory_regions.at(i); + region.print(); + } + } +#endif + + // For all pairs of pointers in the same group, check if they have a partial overlap. + for (int i = 0; i < memory_regions.length(); i++) { + VMemoryRegion& region1 = memory_regions.at(i); + + for (int j = i + 1; j < memory_regions.length(); j++) { + VMemoryRegion& region2 = memory_regions.at(j); + + const VMemoryRegion::Aliasing aliasing = region1.aliasing(region2); + if (aliasing == VMemoryRegion::Aliasing::DIFFERENT_GROUP || + aliasing == VMemoryRegion::Aliasing::BEFORE) { + break; // We have reached the next group or pointers that are always after. + } else if (aliasing == VMemoryRegion::Aliasing::EXACT_OVERLAP) { + continue; + } else { + assert(aliasing == VMemoryRegion::Aliasing::PARTIAL_OVERLAP, "no other case can happen"); + if ((region1.is_load() && !region2.is_load() && region1.schedule_order() > region2.schedule_order()) || + (!region1.is_load() && region2.is_load() && region1.schedule_order() < region2.schedule_order())) { + // We predict that this leads to a store-to-load-forwarding failure penalty. +#ifndef PRODUCT + if (_trace._rejections) { + tty->print_cr("VTransformGraph::has_store_to_load_forwarding_failure:"); + tty->print_cr(" Partial overlap of store->load. We predict that this leads to"); + tty->print_cr(" a store-to-load-forwarding failure penalty which makes"); + tty->print_cr(" vectorization unprofitable. These are the two pointers:"); + region1.print(); + region2.print(); + } +#endif + return true; + } + } + } + } + + return false; +} + Node* VTransformNode::find_transformed_input(int i, const GrowableArray<Node*>& vnode_idx_to_transformed_node) const { Node* n = vnode_idx_to_transformed_node.at(in(i)->_idx); assert(n != nullptr, "must find input IR node"); diff --git a/src/hotspot/share/opto/vtransform.hpp b/src/hotspot/share/opto/vtransform.hpp index ee298e7fe72..8ceca318f4a 100644 --- a/src/hotspot/share/opto/vtransform.hpp +++ b/src/hotspot/share/opto/vtransform.hpp @@ -66,6 +66,8 @@ class VTransformVectorNode; class VTransformElementWiseVectorNode; class VTransformBoolVectorNode; class VTransformReductionVectorNode; +class VTransformLoadVectorNode; +class VTransformStoreVectorNode; // Result from VTransformNode::apply class VTransformApplyResult { @@ -157,6 +159,7 @@ class VTransformGraph : public StackObj { const GrowableArray<VTransformNode*>& vtnodes() const { return _vtnodes; } bool schedule(); + bool has_store_to_load_forwarding_failure(const VLoopAnalyzer& vloop_analyzer) const; void apply_memops_reordering_with_schedule() const; void apply_vectorization_for_each_vtnode(uint& max_vector_length, uint& max_vector_width) const; @@ -221,6 +224,7 @@ class VTransform : public StackObj { VTransformGraph& graph() { return _graph; } bool schedule() { return _graph.schedule(); } + bool has_store_to_load_forwarding_failure() const { return _graph.has_store_to_load_forwarding_failure(_vloop_analyzer); } void apply(); private: @@ -310,6 +314,11 @@ class VTransformNode : public ArenaObj { virtual VTransformElementWiseVectorNode* isa_ElementWiseVector() { return nullptr; } virtual VTransformBoolVectorNode* isa_BoolVector() { return nullptr; } virtual VTransformReductionVectorNode* isa_ReductionVector() { return nullptr; } + virtual VTransformLoadVectorNode* isa_LoadVector() { return nullptr; } + virtual VTransformStoreVectorNode* isa_StoreVector() { return nullptr; } + + virtual bool is_load_or_store_in_loop() const { return false; } + virtual const VPointer& vpointer(const VLoopAnalyzer& vloop_analyzer) const { ShouldNotReachHere(); } virtual VTransformApplyResult apply(const VLoopAnalyzer& vloop_analyzer, const GrowableArray<Node*>& vnode_idx_to_transformed_node) const = 0; @@ -333,6 +342,8 @@ class VTransformScalarNode : public VTransformNode { VTransformNode(vtransform, n->req()), _node(n) {} Node* node() const { return _node; } virtual VTransformScalarNode* isa_Scalar() override { return this; } + virtual bool is_load_or_store_in_loop() const override { return _node->is_Load() || _node->is_Store(); } + virtual const VPointer& vpointer(const VLoopAnalyzer& vloop_analyzer) const override { return vloop_analyzer.vpointers().vpointer(node()->as_Mem()); } virtual VTransformApplyResult apply(const VLoopAnalyzer& vloop_analyzer, const GrowableArray<Node*>& vnode_idx_to_transformed_node) const override; NOT_PRODUCT(virtual const char* name() const override { return "Scalar"; };) @@ -347,6 +358,7 @@ class VTransformInputScalarNode : public VTransformScalarNode { VTransformInputScalarNode(VTransform& vtransform, Node* n) : VTransformScalarNode(vtransform, n) {} virtual VTransformInputScalarNode* isa_InputScalar() override { return this; } + virtual bool is_load_or_store_in_loop() const override { return false; } NOT_PRODUCT(virtual const char* name() const override { return "InputScalar"; };) }; @@ -472,6 +484,9 @@ class VTransformLoadVectorNode : public VTransformVectorNode { VTransformLoadVectorNode(VTransform& vtransform, uint number_of_nodes) : VTransformVectorNode(vtransform, 3, number_of_nodes) {} LoadNode::ControlDependency control_dependency() const; + virtual VTransformLoadVectorNode* isa_LoadVector() override { return this; } + virtual bool is_load_or_store_in_loop() const override { return true; } + virtual const VPointer& vpointer(const VLoopAnalyzer& vloop_analyzer) const override { return vloop_analyzer.vpointers().vpointer(nodes().at(0)->as_Mem()); } virtual VTransformApplyResult apply(const VLoopAnalyzer& vloop_analyzer, const GrowableArray<Node*>& vnode_idx_to_transformed_node) const override; NOT_PRODUCT(virtual const char* name() const override { return "LoadVector"; };) @@ -482,6 +497,9 @@ class VTransformStoreVectorNode : public VTransformVectorNode { // req = 4 -> [ctrl, mem, adr, val] VTransformStoreVectorNode(VTransform& vtransform, uint number_of_nodes) : VTransformVectorNode(vtransform, 4, number_of_nodes) {} + virtual VTransformStoreVectorNode* isa_StoreVector() override { return this; } + virtual bool is_load_or_store_in_loop() const override { return true; } + virtual const VPointer& vpointer(const VLoopAnalyzer& vloop_analyzer) const override { return vloop_analyzer.vpointers().vpointer(nodes().at(0)->as_Mem()); } virtual VTransformApplyResult apply(const VLoopAnalyzer& vloop_analyzer, const GrowableArray<Node*>& vnode_idx_to_transformed_node) const override; NOT_PRODUCT(virtual const char* name() const override { return "StoreVector"; };) diff --git a/test/hotspot/jtreg/compiler/loopopts/superword/TestAlignVector.java b/test/hotspot/jtreg/compiler/loopopts/superword/TestAlignVector.java index efd328dc5cc..60d753ee75f 100644 --- a/test/hotspot/jtreg/compiler/loopopts/superword/TestAlignVector.java +++ b/test/hotspot/jtreg/compiler/loopopts/superword/TestAlignVector.java @@ -168,6 +168,9 @@ public TestAlignVector() { tests.put("test14aB", () -> { return test14aB(aB.clone()); }); tests.put("test14bB", () -> { return test14bB(aB.clone()); }); tests.put("test14cB", () -> { return test14cB(aB.clone()); }); + tests.put("test14dB", () -> { return test14dB(aB.clone()); }); + tests.put("test14eB", () -> { return test14eB(aB.clone()); }); + tests.put("test14fB", () -> { return test14fB(aB.clone()); }); tests.put("test15aB", () -> { return test15aB(aB.clone()); }); tests.put("test15bB", () -> { return test15bB(aB.clone()); }); @@ -239,6 +242,9 @@ public TestAlignVector() { "test14aB", "test14bB", "test14cB", + "test14dB", + "test14eB", + "test14fB", "test15aB", "test15bB", "test15cB", @@ -1128,9 +1134,9 @@ static Object[] test13bBSIL(byte[] a, short[] b, int[] c, long[] d) { } @Test - @IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", - IRNode.ADD_VB, "> 0", - IRNode.STORE_VECTOR, "> 0"}, + @IR(counts = {IRNode.LOAD_VECTOR_B, "= 0", + IRNode.ADD_VB, "= 0", + IRNode.STORE_VECTOR, "= 0"}, applyIfCPUFeatureOr = {"sse4.1", "true", "asimd", "true"}, applyIfPlatform = {"64-bit", "true"}, applyIf = {"AlignVector", "false"}) @@ -1143,6 +1149,9 @@ static Object[] test13bBSIL(byte[] a, short[] b, int[] c, long[] d) { static Object[] test14aB(byte[] a) { // non-power-of-2 stride for (int i = 0; i < RANGE-20; i+=9) { + // Since the stride is shorter than the vector length, there will be always + // partial overlap of loads with previous stores, this leads to failure in + // store-to-load-forwarding -> vectorization not profitable. a[i+0]++; a[i+1]++; a[i+2]++; @@ -1164,9 +1173,9 @@ static Object[] test14aB(byte[] a) { } @Test - @IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", - IRNode.ADD_VB, "> 0", - IRNode.STORE_VECTOR, "> 0"}, + @IR(counts = {IRNode.LOAD_VECTOR_B, "= 0", + IRNode.ADD_VB, "= 0", + IRNode.STORE_VECTOR, "= 0"}, applyIfCPUFeatureOr = {"sse4.1", "true", "asimd", "true"}, applyIfPlatform = {"64-bit", "true"}, applyIf = {"AlignVector", "false"}) @@ -1179,6 +1188,9 @@ static Object[] test14aB(byte[] a) { static Object[] test14bB(byte[] a) { // non-power-of-2 stride for (int i = 0; i < RANGE-20; i+=3) { + // Since the stride is shorter than the vector length, there will be always + // partial overlap of loads with previous stores, this leads to failure in + // store-to-load-forwarding -> vectorization not profitable. a[i+0]++; a[i+1]++; a[i+2]++; @@ -1200,9 +1212,9 @@ static Object[] test14bB(byte[] a) { } @Test - @IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", - IRNode.ADD_VB, "> 0", - IRNode.STORE_VECTOR, "> 0"}, + @IR(counts = {IRNode.LOAD_VECTOR_B, "= 0", + IRNode.ADD_VB, "= 0", + IRNode.STORE_VECTOR, "= 0"}, applyIfCPUFeatureOr = {"sse4.1", "true", "asimd", "true"}, applyIfPlatform = {"64-bit", "true"}, applyIf = {"AlignVector", "false"}) @@ -1215,6 +1227,9 @@ static Object[] test14bB(byte[] a) { static Object[] test14cB(byte[] a) { // non-power-of-2 stride for (int i = 0; i < RANGE-20; i+=5) { + // Since the stride is shorter than the vector length, there will be always + // partial overlap of loads with previous stores, this leads to failure in + // store-to-load-forwarding -> vectorization not profitable. a[i+0]++; a[i+1]++; a[i+2]++; @@ -1235,6 +1250,90 @@ static Object[] test14cB(byte[] a) { return new Object[]{ a }; } + @Test + @IR(counts = {IRNode.LOAD_VECTOR_B, IRNode.VECTOR_SIZE + "min(max_byte, 8)", "> 0", + IRNode.ADD_VB, IRNode.VECTOR_SIZE + "min(max_byte, 8)", "> 0", + IRNode.STORE_VECTOR, "> 0"}, + applyIfCPUFeatureOr = {"sse4.1", "true", "asimd", "true"}, + applyIfPlatform = {"64-bit", "true"}, + applyIf = {"AlignVector", "false"}) + @IR(counts = {IRNode.LOAD_VECTOR_B, "= 0", + IRNode.ADD_VB, "= 0", + IRNode.STORE_VECTOR, "= 0"}, + applyIfCPUFeatureOr = {"sse4.1", "true", "asimd", "true"}, + applyIfPlatform = {"64-bit", "true"}, + applyIf = {"AlignVector", "true"}) + static Object[] test14dB(byte[] a) { + // non-power-of-2 stride + for (int i = 0; i < RANGE-20; i+=9) { + a[i+0]++; + a[i+1]++; + a[i+2]++; + a[i+3]++; + a[i+4]++; + a[i+5]++; + a[i+6]++; + a[i+7]++; + } + return new Object[]{ a }; + } + + @Test + @IR(counts = {IRNode.LOAD_VECTOR_B, IRNode.VECTOR_SIZE + "min(max_byte, 8)", "> 0", + IRNode.ADD_VB, IRNode.VECTOR_SIZE + "min(max_byte, 8)", "> 0", + IRNode.STORE_VECTOR, "> 0"}, + applyIfCPUFeatureOr = {"sse4.1", "true", "asimd", "true"}, + applyIfPlatform = {"64-bit", "true"}, + applyIf = {"AlignVector", "false"}) + @IR(counts = {IRNode.LOAD_VECTOR_B, "= 0", + IRNode.ADD_VB, "= 0", + IRNode.STORE_VECTOR, "= 0"}, + applyIfCPUFeatureOr = {"sse4.1", "true", "asimd", "true"}, + applyIfPlatform = {"64-bit", "true"}, + applyIf = {"AlignVector", "true"}) + static Object[] test14eB(byte[] a) { + // non-power-of-2 stride + for (int i = 0; i < RANGE-32; i+=11) { + a[i+0]++; + a[i+1]++; + a[i+2]++; + a[i+3]++; + a[i+4]++; + a[i+5]++; + a[i+6]++; + a[i+7]++; + } + return new Object[]{ a }; + } + + @Test + @IR(counts = {IRNode.LOAD_VECTOR_B, IRNode.VECTOR_SIZE + "min(max_byte, 8)", "> 0", + IRNode.ADD_VB, IRNode.VECTOR_SIZE + "min(max_byte, 8)", "> 0", + IRNode.STORE_VECTOR, "> 0"}, + applyIfCPUFeatureOr = {"sse4.1", "true", "asimd", "true"}, + applyIfPlatform = {"64-bit", "true"}, + applyIf = {"AlignVector", "false"}) + @IR(counts = {IRNode.LOAD_VECTOR_B, "= 0", + IRNode.ADD_VB, "= 0", + IRNode.STORE_VECTOR, "= 0"}, + applyIfCPUFeatureOr = {"sse4.1", "true", "asimd", "true"}, + applyIfPlatform = {"64-bit", "true"}, + applyIf = {"AlignVector", "true"}) + static Object[] test14fB(byte[] a) { + // non-power-of-2 stride + for (int i = 0; i < RANGE-40; i+=12) { + a[i+0]++; + a[i+1]++; + a[i+2]++; + a[i+3]++; + a[i+4]++; + a[i+5]++; + a[i+6]++; + a[i+7]++; + } + return new Object[]{ a }; + } + @Test // IR rules difficult because of modulo wrapping with offset after peeling. static Object[] test15aB(byte[] a) { diff --git a/test/hotspot/jtreg/compiler/loopopts/superword/TestCyclicDependency.java b/test/hotspot/jtreg/compiler/loopopts/superword/TestCyclicDependency.java index 3849f1b05cf..7c6b7c92c37 100644 --- a/test/hotspot/jtreg/compiler/loopopts/superword/TestCyclicDependency.java +++ b/test/hotspot/jtreg/compiler/loopopts/superword/TestCyclicDependency.java @@ -24,7 +24,7 @@ /* * @test - * @bug 8298935 + * @bug 8298935 8334431 * @summary Writing forward on array creates cyclic dependency * which leads to wrong result, when ignored. * @library /test/lib / @@ -55,15 +55,30 @@ public class TestCyclicDependency { float[] goldF6a = new float[RANGE]; int[] goldI6b = new int[RANGE]; float[] goldF6b = new float[RANGE]; - int[] goldI7 = new int[RANGE]; - float[] goldF7 = new float[RANGE]; - int[] goldI8 = new int[RANGE]; - float[] goldF8 = new float[RANGE]; + int[] goldI7a = new int[RANGE]; + float[] goldF7a = new float[RANGE]; + int[] goldI7b = new int[RANGE]; + float[] goldF7b = new float[RANGE]; + float[] goldF7b_2 = new float[RANGE]; + int[] goldI7c = new int[RANGE]; + float[] goldF7c = new float[RANGE]; + int[] goldI8a = new int[RANGE]; + float[] goldF8a = new float[RANGE]; + int[] goldI8b = new int[RANGE]; + int[] goldI8b_2 = new int[RANGE]; + float[] goldF8b = new float[RANGE]; + int[] goldI8c = new int[RANGE]; + float[] goldF8c = new float[RANGE]; int[] goldI9 = new int[RANGE]; float[] goldF9 = new float[RANGE]; public static void main(String args[]) { - TestFramework.runWithFlags("-XX:CompileCommand=compileonly,TestCyclicDependency::test*"); + TestFramework.runWithFlags("-XX:CompileCommand=compileonly,TestCyclicDependency::test*", + "-XX:+IgnoreUnrecognizedVMOptions", "-XX:-AlignVector", "-XX:-VerifyAlignVector"); + TestFramework.runWithFlags("-XX:CompileCommand=compileonly,TestCyclicDependency::test*", + "-XX:+IgnoreUnrecognizedVMOptions", "-XX:+AlignVector", "-XX:-VerifyAlignVector"); + TestFramework.runWithFlags("-XX:CompileCommand=compileonly,TestCyclicDependency::test*", + "-XX:+IgnoreUnrecognizedVMOptions", "-XX:+AlignVector", "-XX:+VerifyAlignVector"); } TestCyclicDependency() { @@ -95,12 +110,24 @@ public static void main(String args[]) { // test6b init(goldI6b, goldF6b); test6b(goldI6b, goldF6b); - // test7 - init(goldI7, goldF7); - test7(goldI7, goldF7); - // test8 - init(goldI8, goldF8); - test8(goldI8, goldF8); + // test7a + init(goldI7a, goldF7a); + test7a(goldI7a, goldF7a); + // test7b + init(goldI7b, goldF7b, goldF7b_2); + test7b(goldI7b, goldF7b, goldF7b_2); + // test7c + init(goldI7c, goldF7c); + test7c(goldI7c, goldF7c, goldF7c); + // test8a + init(goldI8a, goldF8a); + test8a(goldI8a, goldF8a); + // test8b + init(goldI8b, goldI8b_2, goldF8b); + test8b(goldI8b, goldI8b_2, goldF8b); + // test8c + init(goldI8c, goldF8c); + test8c(goldI8c, goldI8c, goldF8c); // test9 init(goldI9, goldF9); test9(goldI9, goldF9); @@ -205,26 +232,74 @@ public void runTest6b() { verifyF("test6b", dataF, goldF6b); } - @Run(test = "test7") + @Run(test = "test7a") @Warmup(100) - public void runTest7() { + public void runTest7a() { int[] dataI = new int[RANGE]; float[] dataF = new float[RANGE]; init(dataI, dataF); - test7(dataI, dataF); - verifyI("test7", dataI, goldI7); - verifyF("test7", dataF, goldF7); + test7a(dataI, dataF); + verifyI("test7a", dataI, goldI7a); + verifyF("test7a", dataF, goldF7a); } - @Run(test = "test8") + @Run(test = "test7b") @Warmup(100) - public void runTest8() { + public void runTest7b() { + int[] dataI = new int[RANGE]; + float[] dataF = new float[RANGE]; + float[] dataF_2 = new float[RANGE]; + init(dataI, dataF, dataF_2); + test7b(dataI, dataF, dataF_2); + verifyI("test7b", dataI, goldI7b); + verifyF("test7b", dataF, goldF7b); + verifyF("test7b", dataF_2, goldF7b_2); + } + + @Run(test = "test7c") + @Warmup(100) + public void runTest7c() { + int[] dataI = new int[RANGE]; + float[] dataF = new float[RANGE]; + init(dataI, dataF); + test7c(dataI, dataF, dataF); + verifyI("test7c", dataI, goldI7c); + verifyF("test7c", dataF, goldF7c); + } + + @Run(test = "test8a") + @Warmup(100) + public void runTest8a() { + int[] dataI = new int[RANGE]; + float[] dataF = new float[RANGE]; + init(dataI, dataF); + test8a(dataI, dataF); + verifyI("test8a", dataI, goldI8a); + verifyF("test8a", dataF, goldF8a); + } + + @Run(test = "test8b") + @Warmup(100) + public void runTest8b() { + int[] dataI = new int[RANGE]; + int[] dataI_2 = new int[RANGE]; + float[] dataF = new float[RANGE]; + init(dataI, dataI_2, dataF); + test8b(dataI, dataI_2, dataF); + verifyI("test8b", dataI, goldI8b); + verifyI("test8b", dataI_2, goldI8b_2); + verifyF("test8b", dataF, goldF8b); + } + + @Run(test = "test8c") + @Warmup(100) + public void runTest8c() { int[] dataI = new int[RANGE]; float[] dataF = new float[RANGE]; init(dataI, dataF); - test8(dataI, dataF); - verifyI("test8", dataI, goldI8); - verifyF("test8", dataF, goldF8); + test8c(dataI, dataI, dataF); + verifyI("test8c", dataI, goldI8c); + verifyF("test8c", dataF, goldF8c); } @Run(test = "test9") @@ -328,34 +403,156 @@ static void test6b(int[] dataI, float[] dataF) { } @Test - @IR(counts = {IRNode.ADD_VI, "> 0"}, + @IR(counts = {IRNode.ADD_VI, "= 0", + IRNode.ADD_VF, "= 0"}, applyIf = {"AlignVector", "false"}, applyIfCPUFeatureOr = {"sse4.1", "true", "asimd", "true"}) + @IR(counts = {IRNode.ADD_VI, "> 0", + IRNode.ADD_VF, "= 0"}, + applyIf = {"AlignVector", "true"}, + applyIfCPUFeatureOr = {"sse4.1", "true", "asimd", "true"}) // Some aarch64 machines have AlignVector == true, like ThunderX2 - static void test7(int[] dataI, float[] dataF) { + static void test7a(int[] dataI, float[] dataF) { for (int i = 0; i < RANGE - 32; i++) { // write forward 32 -> more than vector size -> can vectorize - // write forward 3 -> cannot vectorize - // separate types should make decision separately if they vectorize or not int v = dataI[i]; dataI[i + 32] = v + 5; + // write forward 3: + // AlignVector=true -> cannot vectorize because load and store cannot be both aligned + // AlignVector=false -> could vectorize, but would get 2-element vectors where + // store-to-load-forwarding fails, because we have store-load + // dependencies that have partial overlap. + // -> all vectorization cancled. float f = dataF[i]; dataF[i + 3] = f + 3.5f; } } @Test - @IR(counts = {IRNode.ADD_VF, IRNode.VECTOR_SIZE + "min(max_int, max_float)", "> 0"}, + @IR(counts = {IRNode.ADD_VI, "> 0", + IRNode.ADD_VF, IRNode.VECTOR_SIZE + "2", "> 0"}, + applyIf = {"AlignVector", "false"}, + applyIfCPUFeatureOr = {"sse4.1", "true", "asimd", "true"}) + @IR(counts = {IRNode.ADD_VI, "> 0", + IRNode.ADD_VF, "= 0"}, + applyIf = {"AlignVector", "true"}, + applyIfCPUFeatureOr = {"sse4.1", "true", "asimd", "true"}) + // Some aarch64 machines have AlignVector == true, like ThunderX2 + static void test7b(int[] dataI, float[] dataF, float[] dataF_2) { + for (int i = 0; i < RANGE - 32; i++) { + // write forward 32 -> more than vector size -> can vectorize + int v = dataI[i]; + dataI[i + 32] = v + 5; + // write forward 3 to different array reference: + // AlignVector=true -> cannot vectorize because load and store cannot be both aligned + // AlignVector=false -> vectorizes because we cannot prove store-to-load forwarding + // failure. But we can only have 2-element vectors in case + // the two float-arrays reference the same array. + // Note: at runtime the float-arrays are always different. + float f = dataF[i]; + dataF_2[i + 3] = f + 3.5f; + } + } + + @Test + @IR(counts = {IRNode.ADD_VI, "> 0", + IRNode.ADD_VF, IRNode.VECTOR_SIZE + "2", "> 0"}, applyIf = {"AlignVector", "false"}, applyIfCPUFeatureOr = {"sse4.1", "true", "asimd", "true"}) + @IR(counts = {IRNode.ADD_VI, "> 0", + IRNode.ADD_VF, "= 0"}, + applyIf = {"AlignVector", "true"}, + applyIfCPUFeatureOr = {"sse4.1", "true", "asimd", "true"}) // Some aarch64 machines have AlignVector == true, like ThunderX2 - static void test8(int[] dataI, float[] dataF) { + static void test7c(int[] dataI, float[] dataF, float[] dataF_2) { for (int i = 0; i < RANGE - 32; i++) { // write forward 32 -> more than vector size -> can vectorize - // write forward 3 -> cannot vectorize - // separate types should make decision separately if they vectorize or not + int v = dataI[i]; + dataI[i + 32] = v + 5; + // write forward 3 to different array reference: + // AlignVector=true -> cannot vectorize because load and store cannot be both aligned + // AlignVector=false -> vectorizes because we cannot prove store-to-load forwarding + // failure. But we can only have 2-element vectors in case + // the two float-arrays reference the same array. + // Note: at runtime the float-arrays are always the same. + float f = dataF[i]; + dataF_2[i + 3] = f + 3.5f; + } + } + + @Test + @IR(counts = {IRNode.ADD_VI, "= 0", + IRNode.ADD_VF, "= 0"}, + applyIf = {"AlignVector", "false"}, + applyIfCPUFeatureOr = {"sse4.1", "true", "asimd", "true"}) + @IR(counts = {IRNode.ADD_VI, "= 0", + IRNode.ADD_VF, IRNode.VECTOR_SIZE + "min(max_int, max_float)", "> 0"}, + applyIf = {"AlignVector", "true"}, + applyIfCPUFeatureOr = {"sse4.1", "true", "asimd", "true"}) + // Some aarch64 machines have AlignVector == true, like ThunderX2 + static void test8a(int[] dataI, float[] dataF) { + for (int i = 0; i < RANGE - 32; i++) { + // write forward 3: + // AlignVector=true -> cannot vectorize because load and store cannot be both aligned + // AlignVector=false -> could vectorize, but would get 2-element vectors where + // store-to-load-forwarding fails, because we have store-load + // dependencies that have partial overlap. + // -> all vectorization cancled. int v = dataI[i]; dataI[i + 3] = v + 5; + // write forward 32 -> more than vector size -> can vectorize + float f = dataF[i]; + dataF[i + 32] = f + 3.5f; + } + } + + @Test + @IR(counts = {IRNode.ADD_VI, IRNode.VECTOR_SIZE + "2", "> 0", + IRNode.ADD_VF, IRNode.VECTOR_SIZE + "min(max_int, max_float)", "> 0"}, + applyIf = {"AlignVector", "false"}, + applyIfCPUFeatureOr = {"sse4.1", "true", "asimd", "true"}) + @IR(counts = {IRNode.ADD_VI, "= 0", + IRNode.ADD_VF, IRNode.VECTOR_SIZE + "min(max_int, max_float)", "> 0"}, + applyIf = {"AlignVector", "true"}, + applyIfCPUFeatureOr = {"sse4.1", "true", "asimd", "true"}) + // Some aarch64 machines have AlignVector == true, like ThunderX2 + static void test8b(int[] dataI, int[] dataI_2, float[] dataF) { + for (int i = 0; i < RANGE - 32; i++) { + // write forward 3 to different array reference: + // AlignVector=true -> cannot vectorize because load and store cannot be both aligned + // AlignVector=false -> vectorizes because we cannot prove store-to-load forwarding + // failure. But we can only have 2-element vectors in case + // the two float-arrays reference the same array. + // Note: at runtime the float-arrays are always different. + int v = dataI[i]; + dataI_2[i + 3] = v + 5; + // write forward 32 -> more than vector size -> can vectorize + float f = dataF[i]; + dataF[i + 32] = f + 3.5f; + } + } + + @Test + @IR(counts = {IRNode.ADD_VI, IRNode.VECTOR_SIZE + "2", "> 0", + IRNode.ADD_VF, IRNode.VECTOR_SIZE + "min(max_int, max_float)", "> 0"}, + applyIf = {"AlignVector", "false"}, + applyIfCPUFeatureOr = {"sse4.1", "true", "asimd", "true"}) + @IR(counts = {IRNode.ADD_VI, "= 0", + IRNode.ADD_VF, IRNode.VECTOR_SIZE + "min(max_int, max_float)", "> 0"}, + applyIf = {"AlignVector", "true"}, + applyIfCPUFeatureOr = {"sse4.1", "true", "asimd", "true"}) + // Some aarch64 machines have AlignVector == true, like ThunderX2 + static void test8c(int[] dataI, int[] dataI_2, float[] dataF) { + for (int i = 0; i < RANGE - 32; i++) { + // write forward 3 to different array reference: + // AlignVector=true -> cannot vectorize because load and store cannot be both aligned + // AlignVector=false -> vectorizes because we cannot prove store-to-load forwarding + // failure. But we can only have 2-element vectors in case + // the two float-arrays reference the same array. + // Note: at runtime the float-arrays are always the same. + int v = dataI[i]; + dataI_2[i + 3] = v + 5; + // write forward 32 -> more than vector size -> can vectorize float f = dataF[i]; dataF[i + 32] = f + 3.5f; } @@ -380,6 +577,22 @@ public static void init(int[] dataI, float[] dataF) { } } + public static void init(int[] dataI, float[] dataF, float[] dataF_2) { + for (int j = 0; j < RANGE; j++) { + dataI[j] = j; + dataF[j] = j * 0.5f; + dataF_2[j] = j * 0.3f; + } + } + + public static void init(int[] dataI, int[] dataI_2, float[] dataF) { + for (int j = 0; j < RANGE; j++) { + dataI[j] = j; + dataI_2[j] = 3*j - 42; + dataF[j] = j * 0.5f; + } + } + static void verifyI(String name, int[] data, int[] gold) { for (int i = 0; i < RANGE; i++) { if (data[i] != gold[i]) { diff --git a/test/hotspot/jtreg/compiler/loopopts/superword/TestDependencyOffsets.java b/test/hotspot/jtreg/compiler/loopopts/superword/TestDependencyOffsets.java index 8e5ac88a27d..cfa19ce385a 100644 --- a/test/hotspot/jtreg/compiler/loopopts/superword/TestDependencyOffsets.java +++ b/test/hotspot/jtreg/compiler/loopopts/superword/TestDependencyOffsets.java @@ -643,6 +643,12 @@ static List<Integer> getOffsets() { return new ArrayList<Integer>(set); } + enum ExpectVectorization { + ALWAYS, // -> positive "count" IR rule + UNKNOWN, // -> disable IR rule + NEVER // -> negative "failOn" IR rule + }; + static record TestDefinition (int id, Type type, int offset) { /* @@ -656,18 +662,22 @@ String generate() { String aliasingComment; String secondArgument; String loadFrom; + boolean isSingleArray; switch (RANDOM.nextInt(3)) { case 0: // a[i + offset] = a[i] + isSingleArray = true; aliasingComment = "single-array"; secondArgument = "a"; loadFrom = "a"; break; case 1: // a[i + offset] = b[i], but a and b alias, i.e. at runtime a == b. + isSingleArray = false; aliasingComment = "aliasing"; secondArgument = "a"; loadFrom = "b"; break; case 2: // a[i + offset] = b[i], and a and b do not alias, i.e. at runtime a != b. + isSingleArray = false; aliasingComment = "non-aliasing"; secondArgument = "b"; loadFrom = "b"; @@ -712,7 +722,7 @@ String generate() { type.name, id, type.name, id, id, id, id, secondArgument, id, // IR rules - generateIRRules(), + generateIRRules(isSingleArray), // test id, type.name, type.name, start, end, @@ -726,7 +736,7 @@ String generate() { * expect depends on AlignVector and MaxVectorSize, as well as the byteOffset between the load and * store. */ - String generateIRRules() { + String generateIRRules(boolean isSingleArray) { StringBuilder builder = new StringBuilder(); for (CPUMinVectorWidth cm : getCPUMinVectorWidth(type.name)) { @@ -744,29 +754,75 @@ String generateIRRules() { // power of two. int infinity = 256; // No vector size is ever larger than this. int maxVectorWidth = infinity; // no constraint by default + int log2 = 31 - Integer.numberOfLeadingZeros(offset); + int floorPow2Offset = 1 << log2; if (0 < byteOffset && byteOffset < maxVectorWidth) { - int log2 = 31 - Integer.numberOfLeadingZeros(offset); - int floorPow2 = 1 << log2; - maxVectorWidth = Math.min(maxVectorWidth, floorPow2 * type.size); - builder.append(" // Vectors must have at most " + floorPow2 + + maxVectorWidth = Math.min(maxVectorWidth, floorPow2Offset * type.size); + builder.append(" // Vectors must have at most " + floorPow2Offset + " elements: maxVectorWidth = " + maxVectorWidth + " to avoid cyclic dependency.\n"); } + ExpectVectorization expectVectorization = ExpectVectorization.ALWAYS; + if (isSingleArray && 0 < offset && offset < 64) { + // In a store-forward case at iteration distances below a certain threshold, and not there + // is some partial overlap between the expected vector store and some vector load in a later + // iteration, we avoid vectorization to avoid the latency penalties of store-to-load + // forwarding failure. We only detect these failures in single-array cases. + // + // Note: we currently never detect store-to-load-forwarding failures beyond 64 iterations, + // And so if the offset >= 64, we always expect vectorization. + // + // The condition for partial overlap: + // offset % #elements != 0 + // + // But we do not know #elements exactly, only a range from min/maxVectorWidth. + + int maxElements = maxVectorWidth / type.size; + int minElements = minVectorWidth / type.size; + boolean sometimesPartialOverlap = offset % maxElements != 0; + // If offset % minElements != 0, then it does also not hold for any larger vector. + boolean alwaysPartialOverlap = offset % minElements != 0; + + if (alwaysPartialOverlap) { + // It is a little tricky to know the exact threshold. On all platforms and in all + // unrolling cases, it is between 8 and 64. Hence, we have these 3 cases: + if (offset <= 8) { + builder.append(" // We always detect store-to-load-forwarding failures -> never vectorize.\n"); + expectVectorization = ExpectVectorization.NEVER; + } else if (offset <= 64) { + builder.append(" // Unknown if detect store-to-load-forwarding failures -> maybe disable IR rules.\n"); + expectVectorization = ExpectVectorization.UNKNOWN; + } else { + // offset > 64 -> offset too large, expect no store-to-load-failure detection + throw new RuntimeException("impossible"); + } + } else if (sometimesPartialOverlap && !alwaysPartialOverlap) { + builder.append(" // Partial overlap condition true: sometimes but not always -> maybe disable IR rules.\n"); + expectVectorization = ExpectVectorization.UNKNOWN; + } else { + builder.append(" // Partial overlap never happens -> expect vectorization.\n"); + expectVectorization = ExpectVectorization.ALWAYS; + } + } + // Rule 1: No strict alignment: -XX:-AlignVector + ExpectVectorization expectVectorization1 = expectVectorization; IRRule r1 = new IRRule(type, type.irNode, applyIfCPUFeature); r1.addApplyIf("\"AlignVector\", \"false\""); r1.addApplyIf("\"MaxVectorSize\", \">=" + minVectorWidth + "\""); if (maxVectorWidth < minVectorWidth) { builder.append(" // maxVectorWidth < minVectorWidth -> expect no vectorization.\n"); - r1.setNegative(); + expectVectorization1 = ExpectVectorization.NEVER; } else if (maxVectorWidth < infinity) { r1.setSize("min(" + (maxVectorWidth / type.size) + ",max_" + type.name + ")"); } + r1.setExpectVectVectorization(expectVectorization1); r1.generate(builder); // Rule 2: strict alignment: -XX:+AlignVector + ExpectVectorization expectVectorization2 = expectVectorization; IRRule r2 = new IRRule(type, type.irNode, applyIfCPUFeature); r2.addApplyIf("\"AlignVector\", \"true\""); r2.addApplyIf("\"MaxVectorSize\", \">=" + minVectorWidth + "\""); @@ -791,18 +847,23 @@ String generateIRRules() { builder.append(" // byteOffset % awMax == 0 -> always trivially aligned\n"); } else if (byteOffset % awMin != 0) { builder.append(" // byteOffset % awMin != 0 -> can never align -> expect no vectorization.\n"); - r2.setNegative(); + expectVectorization2 = ExpectVectorization.NEVER; } else { - builder.append(" // Alignment unknown -> disable IR rule.\n"); - r2.disable(); + if (expectVectorization2 != ExpectVectorization.NEVER) { + builder.append(" // Alignment unknown -> disable IR rule.\n"); + expectVectorization2 = ExpectVectorization.UNKNOWN; + } else { + builder.append(" // Alignment unknown -> but already proved no vectorization above.\n"); + } } if (maxVectorWidth < minVectorWidth) { builder.append(" // Not at least 2 elements or 4 bytes -> expect no vectorization.\n"); - r2.setNegative(); + expectVectorization2 = ExpectVectorization.NEVER; } else if (maxVectorWidth < infinity) { r2.setSize("min(" + (maxVectorWidth / type.size) + ",max_" + type.name + ")"); } + r2.setExpectVectVectorization(expectVectorization2); r2.generate(builder); } return builder.toString(); @@ -846,12 +907,12 @@ void setSize(String size) { this.size = size; } - void setNegative() { - this.isPositiveRule = false; - } - - void disable() { - this.isEnabled = false; + void setExpectVectVectorization(ExpectVectorization expectVectorization) { + switch(expectVectorization) { + case ExpectVectorization.NEVER -> { this.isPositiveRule = false; } + case ExpectVectorization.UNKNOWN -> { this.isEnabled = false; } + case ExpectVectorization.ALWAYS -> {} + } } void addApplyIf(String constraint) { diff --git a/test/hotspot/jtreg/compiler/vectorization/runner/LoopCombinedOpTest.java b/test/hotspot/jtreg/compiler/vectorization/runner/LoopCombinedOpTest.java index 16d04102082..8a0715eadfe 100644 --- a/test/hotspot/jtreg/compiler/vectorization/runner/LoopCombinedOpTest.java +++ b/test/hotspot/jtreg/compiler/vectorization/runner/LoopCombinedOpTest.java @@ -138,8 +138,11 @@ public int[] multipleOpsWithMultipleConstants() { } @Test - @IR(applyIfCPUFeatureOr = {"asimd", "true", "sse2", "true"}, + @IR(applyIfCPUFeatureOr = {"asimd", "true", "sse4.1", "true"}, counts = {IRNode.STORE_VECTOR, ">0"}) + // With sse2, the MulI does not vectorize. This means we have vectorized stores + // to res1, but scalar loads from res1. The store-to-load-forwarding failure + // detection catches this and rejects vectorization. public int[] multipleStores() { int[] res1 = new int[SIZE]; int[] res2 = new int[SIZE]; diff --git a/test/micro/org/openjdk/bench/vm/compiler/VectorStoreToLoadForwarding.java b/test/micro/org/openjdk/bench/vm/compiler/VectorStoreToLoadForwarding.java new file mode 100644 index 00000000000..ac8940ec675 --- /dev/null +++ b/test/micro/org/openjdk/bench/vm/compiler/VectorStoreToLoadForwarding.java @@ -0,0 +1,142 @@ +/* + * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package org.openjdk.bench.vm.compiler; + +import org.openjdk.jmh.annotations.*; +import org.openjdk.jmh.infra.*; + +import java.lang.invoke.*; + +import java.util.concurrent.TimeUnit; +import java.util.Random; + +@BenchmarkMode(Mode.AverageTime) +@OutputTimeUnit(TimeUnit.NANOSECONDS) +@State(Scope.Thread) +@Warmup(iterations = 2, time = 1, timeUnit = TimeUnit.SECONDS) +@Measurement(iterations = 3, time = 1, timeUnit = TimeUnit.SECONDS) +@Fork(value = 1) +public abstract class VectorStoreToLoadForwarding { + @Param({"10000"}) + public int SIZE; + + @Param({ "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", + "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", + "20", "21", "22", "23", "24", "25", "26", "27", "28", "29", + "30", "31", "32", "33", "34", "35", "36", "37", "38", "39", + "40", "41", "42", "43", "44", "45", "46", "47", "48", "49", + "50", "51", "52", "53", "54", "55", "56", "57", "58", "59", + "60", "61", "62", "63", "64", "65", "66", "67", "68", "69", + "70", "71", "72", "73", "74", "75", "76", "77", "78", "79", + "80", "81", "82", "83", "84", "85", "86", "87", "88", "89", + "90", "91", "92", "93", "94", "95", "96", "97", "98", "99", + "100", "101", "102", "103", "104", "105", "106", "107", "108", "109", + "110", "111", "112", "113", "114", "115", "116", "117", "118", "119", + "120", "121", "122", "123", "124", "125", "126", "127", "128", "129"}) + public int OFFSET; + + // To get compile-time constants for OFFSET + static final MutableCallSite MUTABLE_CONSTANT = new MutableCallSite(MethodType.methodType(int.class)); + static final MethodHandle MUTABLE_CONSTANT_HANDLE = MUTABLE_CONSTANT.dynamicInvoker(); + + public int START = 1000; + + private byte[] aB; + private short[] aS; + private int[] aI; + private long[] aL; + + @Param("0") + private int seed; + private Random r = new Random(seed); + + @Setup + public void init() throws Throwable { + aB = new byte[SIZE]; + aS = new short[SIZE]; + aI = new int[SIZE]; + aL = new long[SIZE]; + + for (int i = START; i < SIZE; i++) { + aB[i] = (byte)r.nextInt(); + aS[i] = (short)r.nextInt(); + aI[i] = r.nextInt(); + aL[i] = r.nextLong(); + } + + MethodHandle constant = MethodHandles.constant(int.class, OFFSET); + MUTABLE_CONSTANT.setTarget(constant); + } + + @CompilerControl(CompilerControl.Mode.INLINE) + private int offset_con() throws Throwable { + return (int) MUTABLE_CONSTANT_HANDLE.invokeExact(); + } + + @Benchmark + public void bytes() throws Throwable { + int offset = offset_con(); + for (int i = START; i < SIZE; i++) { + aB[i] = (byte)(aB[i - offset] + 1); + } + } + + @Benchmark + public void shorts() throws Throwable { + int offset = offset_con(); + for (int i = START; i < SIZE; i++) { + aS[i] = (short)(aS[i - offset] + 1); + } + } + + @Benchmark + public void ints() throws Throwable { + int offset = offset_con(); + for (int i = START; i < SIZE; i++) { + aI[i] = aI[i - offset] + 1; + } + } + + @Benchmark + public void longs() throws Throwable { + int offset = offset_con(); + for (int i = START; i < SIZE; i++) { + aL[i] = (long)(aL[i - offset] + 1); + } + } + + @Fork(value = 1, jvmArgs = { + "-XX:+UseSuperWord" + }) + public static class Default extends VectorStoreToLoadForwarding {} + + @Fork(value = 1, jvmArgs = { + "-XX:-UseSuperWord" + }) + public static class NoVectorization extends VectorStoreToLoadForwarding {} + + @Fork(value = 1, jvmArgs = { + "-XX:+UseSuperWord", "-XX:+UnlockDiagnosticVMOptions", "-XX:SuperWordStoreToLoadForwardingFailureDetection=0" + }) + public static class NoStoreToLoadForwardFailureDetection extends VectorStoreToLoadForwarding {} +} From 7d4c3fd0915cfa8b279f42494625ec6afda338af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Lund=C3=A9n?= <dlunden@openjdk.org> Date: Wed, 20 Nov 2024 15:37:43 +0000 Subject: [PATCH 133/311] 8331295: C2: Do not clone address computations that are indirect memory input to at least one load/store MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Roberto Castañeda Lozano <rcastanedalo@openjdk.org> Reviewed-by: thartmann, chagedorn --- src/hotspot/cpu/aarch64/aarch64.ad | 17 ++ .../jtreg/compiler/c2/TestFindNode.java | 4 +- .../compiler/codegen/TestMatcherClone.java | 232 ++++++++++++++++++ .../TestDeepGraphVerifyIterativeGVN.java | 1 - 4 files changed, 251 insertions(+), 3 deletions(-) create mode 100644 test/hotspot/jtreg/compiler/codegen/TestMatcherClone.java diff --git a/src/hotspot/cpu/aarch64/aarch64.ad b/src/hotspot/cpu/aarch64/aarch64.ad index 1015b631643..017dc0ed85f 100644 --- a/src/hotspot/cpu/aarch64/aarch64.ad +++ b/src/hotspot/cpu/aarch64/aarch64.ad @@ -2632,6 +2632,23 @@ bool Matcher::pd_clone_node(Node* n, Node* m, Matcher::MStack& mstack) { // to be subsumed into complex addressing expressions or compute them // into registers? bool Matcher::pd_clone_address_expressions(AddPNode* m, Matcher::MStack& mstack, VectorSet& address_visited) { + + // Loads and stores with indirect memory input (e.g., volatile loads and + // stores) do not subsume the input into complex addressing expressions. If + // the addressing expression is input to at least one such load or store, do + // not clone the addressing expression. Query needs_acquiring_load and + // needs_releasing_store as a proxy for indirect memory input, as it is not + // possible to directly query for indirect memory input at this stage. + for (DUIterator_Fast imax, i = m->fast_outs(imax); i < imax; i++) { + Node* n = m->fast_out(i); + if (n->is_Load() && needs_acquiring_load(n)) { + return false; + } + if (n->is_Store() && needs_releasing_store(n)) { + return false; + } + } + if (clone_base_plus_offset_address(m, mstack, address_visited)) { return true; } diff --git a/test/hotspot/jtreg/compiler/c2/TestFindNode.java b/test/hotspot/jtreg/compiler/c2/TestFindNode.java index ea7649c713a..fa545da7e58 100644 --- a/test/hotspot/jtreg/compiler/c2/TestFindNode.java +++ b/test/hotspot/jtreg/compiler/c2/TestFindNode.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -27,7 +27,7 @@ * @requires vm.debug == true & vm.flavor == "server" * @summary Test which uses some special flags in order to test Node::find() in debug builds which could result in an endless loop or a stack overflow crash. * - * @run main/othervm -Xbatch -XX:CompileCommand=option,*::*,bool,Vectorize,true -XX:CompileCommand=memlimit,compiler.c2.TestFindNode::*,0 + * @run main/othervm -Xbatch -XX:CompileCommand=option,*::*,bool,Vectorize,true * -XX:+PrintOpto -XX:+TraceLoopOpts compiler.c2.TestFindNode */ package compiler.c2; diff --git a/test/hotspot/jtreg/compiler/codegen/TestMatcherClone.java b/test/hotspot/jtreg/compiler/codegen/TestMatcherClone.java new file mode 100644 index 00000000000..e062cc20538 --- /dev/null +++ b/test/hotspot/jtreg/compiler/codegen/TestMatcherClone.java @@ -0,0 +1,232 @@ +/* + * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8331295 + * @requires os.simpleArch == "aarch64" + * @summary Check that the matcher does not needlessly clone an addressing + * expression that will in any case not be subsumed into complex + * loads and stores. + * @library /test/lib / + * @run driver compiler.codegen.TestMatcherClone + */ + +package compiler.codegen; + +import compiler.lib.ir_framework.*; + +public class TestMatcherClone { + static volatile int[] iArr; + static volatile int x; + static int[] iArr2 = new int[100]; + static int[] iArr3 = new int[100]; + + public static void main(String[] args) { + TestFramework.run(); + } + + @Test(compLevel = CompLevel.C2) + @IR(counts = {IRNode.ADD_P_OF, "reg_imm", "<200"}, + phase = CompilePhase.MATCHING) + public void test() { + iArr = new int[] {x % 2}; + iArr = new int[] {x % 2}; + iArr = new int[] {x % 2}; + iArr = new int[] {x % 2}; + iArr = new int[] {x % 2}; + iArr = new int[] {x % 2}; + iArr = new int[] {x % 2}; + iArr = new int[] {x % 2}; + iArr = new int[] {x % 2}; + iArr = new int[] {x % 2}; + iArr = new int[] {x % 2}; + iArr = new int[] {x % 2}; + iArr = new int[] {x % 2}; + iArr = new int[] {x % 2}; + iArr = new int[] {x % 2}; + iArr = new int[] {x % 2}; + iArr = new int[] {x % 2}; + iArr = new int[] {x % 2}; + iArr = new int[] {x % 2}; + iArr = new int[] {x % 2}; + iArr = new int[] {x % 2}; + iArr = new int[] {x % 2}; + iArr = new int[] {x % 2}; + iArr = new int[] {x % 2}; + iArr = new int[] {x % 2}; + iArr = new int[] {x % 2}; + iArr = new int[] {x % 2}; + iArr = new int[] {x % 2}; + iArr = new int[] {x % 2}; + iArr = new int[] {x % 2}; + iArr = new int[] {x % 2}; + iArr = new int[] {x % 2}; + iArr = new int[] {x % 2}; + iArr = new int[] {x % 2}; + iArr = new int[] {x % 2}; + iArr = new int[] {x % 2}; + iArr = new int[] {x % 2}; + iArr = new int[] {x % 2}; + iArr = new int[] {x % 2}; + iArr = new int[] {x % 2}; + iArr = new int[] {x % 2}; + iArr = new int[] {x % 2}; + iArr = new int[] {x % 2}; + iArr = new int[] {x % 2}; + iArr = new int[] {x % 2}; + iArr = new int[] {x % 2}; + iArr = new int[] {x % 2}; + iArr = new int[] {x % 2}; + iArr = new int[] {x % 2}; + iArr = new int[] {x % 2}; + iArr = new int[] {x % 2}; + iArr = new int[] {x % 2}; + iArr = new int[] {x % 2}; + iArr = new int[] {x % 2}; + iArr = new int[] {x % 2}; + iArr = new int[] {x % 2}; + iArr = new int[] {x % 2}; + iArr = new int[] {x % 2}; + iArr = new int[] {x % 2}; + iArr = new int[] {x % 2}; + iArr = new int[] {x % 2}; + iArr = new int[] {x % 2}; + iArr = new int[] {x % 2}; + iArr = new int[] {x % 2}; + iArr = new int[] {x % 2}; + iArr = new int[] {x % 2}; + iArr = new int[] {x % 2}; + iArr = new int[] {x % 2}; + iArr = new int[] {x % 2}; + iArr = new int[] {x % 2}; + iArr = new int[] {x % 2}; + iArr = new int[] {x % 2}; + iArr = new int[] {x % 2}; + iArr = new int[] {x % 2}; + iArr = new int[] {x % 2}; + iArr = new int[] {x % 2}; + iArr = new int[] {x % 2}; + iArr = new int[] {x % 2}; + iArr = new int[] {x % 2}; + iArr = new int[] {x % 2}; + iArr = new int[] {x % 2}; + iArr = new int[] {x % 2}; + iArr = new int[] {x % 2}; + iArr = new int[] {x % 2}; + iArr = new int[] {x % 2}; + iArr = new int[] {x % 2}; + iArr = new int[] {x % 2}; + iArr = new int[] {x % 2}; + iArr = new int[] {x % 2}; + iArr = new int[] {x % 2}; + iArr = new int[] {x % 2}; + iArr = new int[] {x % 2}; + iArr = new int[] {x % 2}; + iArr = new int[] {x % 2}; + iArr = new int[] {x % 2}; + iArr = new int[] {x % 2}; + iArr = new int[] {x % 2}; + iArr = new int[] {x % 2}; + iArr = new int[] {x % 2}; + iArr = new int[] {x % 2}; + iArr = new int[] {x % 2}; + iArr = new int[] {x % 2}; + iArr = new int[] {x % 2}; + iArr = new int[] {x % 2}; + iArr = new int[] {x % 2}; + iArr = new int[] {x % 2}; + iArr = new int[] {x % 2}; + iArr = new int[] {x % 2}; + iArr = new int[] {x % 2}; + iArr = new int[] {x % 2}; + iArr = new int[] {x % 2}; + iArr = new int[] {x % 2}; + iArr = new int[] {x % 2}; + iArr = new int[] {x % 2}; + iArr = new int[] {x % 2}; + iArr = new int[] {x % 2}; + iArr = new int[] {x % 2}; + iArr = new int[] {x % 2}; + iArr = new int[] {x % 2}; + iArr = new int[] {x % 2}; + iArr = new int[] {x % 2}; + iArr = new int[] {x % 2}; + iArr = new int[] {x % 2}; + iArr = new int[] {x % 2}; + iArr = new int[] {x % 2}; + iArr = new int[] {x % 2}; + iArr = new int[] {x % 2}; + iArr = new int[] {x % 2}; + iArr = new int[] {x % 2}; + iArr = new int[] {x % 2}; + iArr = new int[] {x % 2}; + iArr = new int[] {x % 2}; + iArr = new int[] {x % 2}; + iArr = new int[] {x % 2}; + iArr = new int[] {x % 2}; + iArr = new int[] {x % 2}; + iArr = new int[] {x % 2}; + iArr = new int[] {x % 2}; + iArr = new int[] {x % 2}; + iArr = new int[] {x % 2}; + iArr = new int[] {x % 2}; + iArr = new int[] {x % 2}; + iArr = new int[] {x % 2}; + iArr = new int[] {x % 2}; + iArr = new int[] {x % 2}; + iArr = new int[] {x % 2}; + iArr = new int[] {x % 2}; + iArr = new int[] {x % 2}; + iArr = new int[] {x % 2}; + iArr = new int[] {x % 2}; + iArr = new int[] {x % 2}; + iArr = new int[] {x % 2}; + iArr = new int[] {x % 2}; + iArr = new int[] {x % 2}; + iArr = new int[] {x % 2}; + iArr = new int[] {x % 2}; + iArr = new int[] {x % 2}; + iArr = new int[] {x % 2}; + iArr = new int[] {x % 2}; + iArr = new int[] {x % 2}; + iArr = new int[] {x % 2}; + iArr = new int[] {x % 2}; + iArr = new int[] {x % 2}; + iArr = new int[] {x % 2}; + iArr = new int[] {x % 2}; + iArr = new int[] {x % 2}; + iArr = new int[] {x % 2}; + iArr = new int[] {x % 2}; + iArr = new int[] {x % 2}; + iArr = new int[] {x % 2}; + iArr = new int[] {x % 2}; + iArr = new int[] {x % 2}; + iArr = new int[] {x % 2}; + iArr = new int[] {x % 2}; + + for (int i = 0; i < 50; i++) { + iArr2[i] = iArr3[i]; + } + } +} diff --git a/test/hotspot/jtreg/compiler/loopopts/TestDeepGraphVerifyIterativeGVN.java b/test/hotspot/jtreg/compiler/loopopts/TestDeepGraphVerifyIterativeGVN.java index bcb4a211368..d5ddc048702 100644 --- a/test/hotspot/jtreg/compiler/loopopts/TestDeepGraphVerifyIterativeGVN.java +++ b/test/hotspot/jtreg/compiler/loopopts/TestDeepGraphVerifyIterativeGVN.java @@ -28,7 +28,6 @@ * @summary Test which causes a stack overflow segmentation fault with -XX:VerifyIterativeGVN=1 due to a too deep recursion in Node::verify_recur(). * * @run main/othervm/timeout=600 -Xcomp -XX:VerifyIterativeGVN=1 -XX:CompileCommand=compileonly,compiler.loopopts.TestDeepGraphVerifyIterativeGVN::* - * -XX:CompileCommand=memlimit,compiler.loopopts.TestDeepGraphVerifyIterativeGVN::*,0 * compiler.loopopts.TestDeepGraphVerifyIterativeGVN */ From 9be8ac6fbcf1a91e5eee9d3a3430dc356b89283e Mon Sep 17 00:00:00 2001 From: Calvin Cheung <ccheung@openjdk.org> Date: Wed, 20 Nov 2024 15:41:26 +0000 Subject: [PATCH 134/311] 8344239: runtime/cds/appcds/jigsaw/addmods/AddmodsOption.java fails on x64 with -Xmixed Reviewed-by: iklam --- .../jtreg/runtime/cds/appcds/jigsaw/addmods/AddmodsOption.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/hotspot/jtreg/runtime/cds/appcds/jigsaw/addmods/AddmodsOption.java b/test/hotspot/jtreg/runtime/cds/appcds/jigsaw/addmods/AddmodsOption.java index 114dd6b9f3a..9328cc86569 100644 --- a/test/hotspot/jtreg/runtime/cds/appcds/jigsaw/addmods/AddmodsOption.java +++ b/test/hotspot/jtreg/runtime/cds/appcds/jigsaw/addmods/AddmodsOption.java @@ -39,7 +39,7 @@ public class AddmodsOption { private static final WhiteBox WB = WhiteBox.getWhiteBox(); - private static final boolean isJVMCISupported = (WB.getBooleanVMFlag("EnableJVMCI") != null); + private static final boolean isJVMCISupported = WB.getBooleanVMFlag("EnableJVMCI"); public static void main(String[] args) throws Exception { final String moduleOption = "jdk.httpserver/sun.net.httpserver.simpleserver.Main"; From c4c6b1fe0629d313e7b7bd6b7dc92f8c7d18ec8f Mon Sep 17 00:00:00 2001 From: Brian Burkhalter <bpb@openjdk.org> Date: Wed, 20 Nov 2024 16:01:01 +0000 Subject: [PATCH 135/311] 8344562: Remove security manager dependency from module jdk.jdi Reviewed-by: kevinw, lmesnik, cjplummer --- .../com/sun/tools/jdi/VirtualMachineManagerImpl.java | 7 ------- 1 file changed, 7 deletions(-) diff --git a/src/jdk.jdi/share/classes/com/sun/tools/jdi/VirtualMachineManagerImpl.java b/src/jdk.jdi/share/classes/com/sun/tools/jdi/VirtualMachineManagerImpl.java index c17c46237b6..d49e718db60 100644 --- a/src/jdk.jdi/share/classes/com/sun/tools/jdi/VirtualMachineManagerImpl.java +++ b/src/jdk.jdi/share/classes/com/sun/tools/jdi/VirtualMachineManagerImpl.java @@ -59,13 +59,6 @@ public class VirtualMachineManagerImpl implements VirtualMachineManagerService { private static VirtualMachineManagerImpl vmm; public static VirtualMachineManager virtualMachineManager() { - @SuppressWarnings("removal") - SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - JDIPermission vmmPermission = - new JDIPermission("virtualMachineManager"); - sm.checkPermission(vmmPermission); - } synchronized (lock) { if (vmm == null) { vmm = new VirtualMachineManagerImpl(); From 080f1cc8cd0500c254debec3198dc187bd41c3e8 Mon Sep 17 00:00:00 2001 From: Alexey Semenyuk <asemenyuk@openjdk.org> Date: Wed, 20 Nov 2024 16:54:51 +0000 Subject: [PATCH 136/311] 8289771: jpackage: ResourceEditor error when path is overly long on Windows Reviewed-by: almatvee --- .../internal/ExecutableRebrander.java | 20 ++- .../jdk/jpackage/internal/ShortPathUtils.java | 93 ++++++++++ .../jdk/jpackage/internal/WinMsiBundler.java | 18 +- .../jpackage/internal/WixFragmentBuilder.java | 2 +- .../jdk/jpackage/internal/WixPipeline.java | 159 ++++++++++++------ .../internal/WixUiFragmentBuilder.java | 4 +- .../resources/WinResources.properties | 1 + .../resources/WinResources_de.properties | 1 + .../resources/WinResources_ja.properties | 1 + .../resources/WinResources_zh_CN.properties | 1 + .../windows/native/common/WinFileUtils.cpp | 21 ++- .../windows/native/common/WinFileUtils.h | 4 +- .../windows/native/libjpackage/jpackage.cpp | 23 +++ .../helpers/jdk/jpackage/test/Executor.java | 10 +- .../helpers/jdk/jpackage/test/HelloApp.java | 21 ++- .../jdk/jpackage/test/WindowsHelper.java | 85 +++++++++- .../tools/jpackage/windows/WinL10nTest.java | 46 ++--- .../jpackage/windows/WinLongPathTest.java | 87 ++++++++++ 18 files changed, 500 insertions(+), 97 deletions(-) create mode 100644 src/jdk.jpackage/windows/classes/jdk/jpackage/internal/ShortPathUtils.java create mode 100644 test/jdk/tools/jpackage/windows/WinLongPathTest.java diff --git a/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/ExecutableRebrander.java b/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/ExecutableRebrander.java index a297f507da8..166675b5893 100644 --- a/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/ExecutableRebrander.java +++ b/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/ExecutableRebrander.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -30,6 +30,7 @@ import java.io.InputStreamReader; import java.io.Reader; import java.nio.charset.StandardCharsets; +import java.nio.file.Files; import java.nio.file.Path; import java.text.MessageFormat; import java.util.ArrayList; @@ -40,6 +41,7 @@ import java.util.ResourceBundle; import java.util.function.Supplier; import static jdk.jpackage.internal.OverridableResource.createResource; +import static jdk.jpackage.internal.ShortPathUtils.adjustPath; import static jdk.jpackage.internal.StandardBundlerParam.APP_NAME; import static jdk.jpackage.internal.StandardBundlerParam.COPYRIGHT; import static jdk.jpackage.internal.StandardBundlerParam.DESCRIPTION; @@ -112,7 +114,7 @@ ExecutableRebrander addAction(UpdateResourceAction action) { } private void rebrandExecutable(Map<String, ? super Object> params, - Path target, UpdateResourceAction action) throws IOException { + final Path target, UpdateResourceAction action) throws IOException { try { String tempDirectory = TEMP_ROOT.fetchFrom(params) .toAbsolutePath().toString(); @@ -125,10 +127,11 @@ private void rebrandExecutable(Map<String, ? super Object> params, target.toFile().setWritable(true, true); - long resourceLock = lockResource(target.toString()); + var shortTargetPath = ShortPathUtils.toShortPath(target); + long resourceLock = lockResource(shortTargetPath.orElse(target).toString()); if (resourceLock == 0) { throw new RuntimeException(MessageFormat.format( - I18N.getString("error.lock-resource"), target)); + I18N.getString("error.lock-resource"), shortTargetPath.orElse(target))); } final boolean resourceUnlockedSuccess; @@ -144,6 +147,14 @@ private void rebrandExecutable(Map<String, ? super Object> params, resourceUnlockedSuccess = true; } else { resourceUnlockedSuccess = unlockResource(resourceLock); + if (shortTargetPath.isPresent()) { + // Windows will rename the excuatble in the unlock operation. + // Should restore executable's name. + var tmpPath = target.getParent().resolve( + target.getFileName().toString() + ".restore"); + Files.move(shortTargetPath.get(), tmpPath); + Files.move(tmpPath, target); + } } } @@ -236,6 +247,7 @@ private static void validateValueAndPut( private static void iconSwapWrapper(long resourceLock, String iconTarget) { + iconTarget = adjustPath(iconTarget); if (iconSwap(resourceLock, iconTarget) != 0) { throw new RuntimeException(MessageFormat.format(I18N.getString( "error.icon-swap"), iconTarget)); diff --git a/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/ShortPathUtils.java b/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/ShortPathUtils.java new file mode 100644 index 00000000000..21dc2a1c3ff --- /dev/null +++ b/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/ShortPathUtils.java @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.jpackage.internal; + +import java.nio.file.Files; +import java.nio.file.Path; +import java.text.MessageFormat; +import java.util.Objects; +import java.util.Optional; + + +@SuppressWarnings("restricted") +final class ShortPathUtils { + static String adjustPath(String path) { + return toShortPath(path).orElse(path); + } + + static Path adjustPath(Path path) { + return toShortPath(path).orElse(path); + } + + static Optional<String> toShortPath(String path) { + Objects.requireNonNull(path); + return toShortPath(Path.of(path)).map(Path::toString); + } + + static Optional<Path> toShortPath(Path path) { + if (!Files.exists(path)) { + throw new IllegalArgumentException(String.format("[%s] path does not exist", path)); + } + + var normPath = path.normalize().toAbsolutePath().toString(); + if (normPath.length() > MAX_PATH) { + return Optional.of(Path.of(getShortPathWrapper(normPath))); + } else { + return Optional.empty(); + } + } + + private static String getShortPathWrapper(final String longPath) { + String effectivePath; + if (!longPath.startsWith(LONG_PATH_PREFIX)) { + effectivePath = LONG_PATH_PREFIX + longPath; + } else { + effectivePath = longPath; + } + + return Optional.ofNullable(getShortPath(effectivePath)).orElseThrow( + () -> new ShortPathException(MessageFormat.format(I18N.getString( + "error.short-path-conv-fail"), effectivePath))); + } + + static final class ShortPathException extends RuntimeException { + + ShortPathException(String msg) { + super(msg); + } + + private static final long serialVersionUID = 1L; + } + + private static native String getShortPath(String longPath); + + private static final int MAX_PATH = 240; + // See https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-getshortpathnamew + private static final String LONG_PATH_PREFIX = "\\\\?\\"; + + static { + System.loadLibrary("jpackage"); + } +} diff --git a/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/WinMsiBundler.java b/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/WinMsiBundler.java index f6b0fb4be20..f724e08fc89 100644 --- a/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/WinMsiBundler.java +++ b/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/WinMsiBundler.java @@ -526,9 +526,10 @@ private Path buildMSI(Map<String, ? super Object> params, "message.preparing-msi-config"), msiOut.toAbsolutePath() .toString())); - WixPipeline wixPipeline = new WixPipeline() - .setToolset(wixToolset) - .setWixObjDir(TEMP_ROOT.fetchFrom(params).resolve("wixobj")) + var wixObjDir = TEMP_ROOT.fetchFrom(params).resolve("wixobj"); + + var wixPipeline = WixPipeline.build() + .setWixObjDir(wixObjDir) .setWorkDir(WIN_APP_IMAGE.fetchFrom(params)) .addSource(CONFIG_ROOT.fetchFrom(params).resolve("main.wxs"), wixVars); @@ -605,13 +606,13 @@ private Path buildMSI(Map<String, ? super Object> params, // Cultures from custom files and a single primary Culture are // included into "-cultures" list for (var wxl : primaryWxlFiles) { - wixPipeline.addLightOptions("-loc", wxl.toAbsolutePath().normalize().toString()); + wixPipeline.addLightOptions("-loc", wxl.toString()); } List<String> cultures = new ArrayList<>(); for (var wxl : customWxlFiles) { wxl = configDir.resolve(wxl.getFileName()); - wixPipeline.addLightOptions("-loc", wxl.toAbsolutePath().normalize().toString()); + wixPipeline.addLightOptions("-loc", wxl.toString()); cultures.add(getCultureFromWxlFile(wxl)); } @@ -638,7 +639,8 @@ private Path buildMSI(Map<String, ? super Object> params, } } - wixPipeline.buildMsi(msiOut.toAbsolutePath()); + Files.createDirectories(wixObjDir); + wixPipeline.create(wixToolset).buildMsi(msiOut.toAbsolutePath()); return msiOut; } @@ -678,14 +680,14 @@ private static String getCultureFromWxlFile(Path wxlPath) throws IOException { if (nodes.getLength() != 1) { throw new IOException(MessageFormat.format(I18N.getString( "error.extract-culture-from-wix-l10n-file"), - wxlPath.toAbsolutePath())); + wxlPath.toAbsolutePath().normalize())); } return nodes.item(0).getNodeValue(); } catch (XPathExpressionException | ParserConfigurationException | SAXException ex) { throw new IOException(MessageFormat.format(I18N.getString( - "error.read-wix-l10n-file"), wxlPath.toAbsolutePath()), ex); + "error.read-wix-l10n-file"), wxlPath.toAbsolutePath().normalize()), ex); } } diff --git a/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/WixFragmentBuilder.java b/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/WixFragmentBuilder.java index f0a5840eb6f..48a1d04f8dc 100644 --- a/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/WixFragmentBuilder.java +++ b/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/WixFragmentBuilder.java @@ -74,7 +74,7 @@ List<String> getLoggableWixFeatures() { return List.of(); } - void configureWixPipeline(WixPipeline wixPipeline) { + void configureWixPipeline(WixPipeline.Builder wixPipeline) { wixPipeline.addSource(configRoot.resolve(outputFileName), Optional.ofNullable(wixVariables).map(WixVariables::getValues).orElse( null)); diff --git a/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/WixPipeline.java b/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/WixPipeline.java index 5b626c8a565..d7c1b54a48c 100644 --- a/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/WixPipeline.java +++ b/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/WixPipeline.java @@ -29,65 +29,130 @@ import java.nio.file.Path; import java.util.ArrayList; import java.util.Collections; +import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Objects; import java.util.Optional; +import java.util.Set; import java.util.function.Function; +import java.util.function.UnaryOperator; import java.util.stream.Collectors; import java.util.stream.Stream; +import static jdk.jpackage.internal.ShortPathUtils.adjustPath; import jdk.jpackage.internal.util.PathUtils; /** * WiX pipeline. Compiles and links WiX sources. */ -public class WixPipeline { - WixPipeline() { - sources = new ArrayList<>(); - lightOptions = new ArrayList<>(); - } +final class WixPipeline { - WixPipeline setToolset(WixToolset v) { - toolset = v; - return this; - } + static final class Builder { + Builder() { + } - WixPipeline setWixVariables(Map<String, String> v) { - wixVariables = v; - return this; - } + WixPipeline create(WixToolset toolset) { + Objects.requireNonNull(toolset); + Objects.requireNonNull(workDir); + Objects.requireNonNull(wixObjDir); + if (sources.isEmpty()) { + throw new IllegalArgumentException("no sources"); + } - WixPipeline setWixObjDir(Path v) { - wixObjDir = v; - return this; - } + final var absWorkDir = workDir.normalize().toAbsolutePath(); + + final UnaryOperator<Path> normalizePath = path -> { + return path.normalize().toAbsolutePath(); + }; + + final var absObjWorkDir = normalizePath.apply(wixObjDir); + + var relSources = sources.stream().map(source -> { + return source.overridePath(normalizePath.apply(source.path)); + }).toList(); + + return new WixPipeline(toolset, adjustPath(absWorkDir), absObjWorkDir, + wixVariables, mapLightOptions(normalizePath), relSources); + } + + Builder setWixObjDir(Path v) { + wixObjDir = v; + return this; + } + + Builder setWorkDir(Path v) { + workDir = v; + return this; + } + + Builder setWixVariables(Map<String, String> v) { + wixVariables.clear(); + wixVariables.putAll(v); + return this; + } + + Builder addSource(Path source, Map<String, String> wixVariables) { + sources.add(new WixSource(source, wixVariables)); + return this; + } + + Builder addLightOptions(String ... v) { + lightOptions.addAll(List.of(v)); + return this; + } - WixPipeline setWorkDir(Path v) { - workDir = v; - return this; + private List<String> mapLightOptions(UnaryOperator<Path> normalizePath) { + var pathOptions = Set.of("-b", "-loc"); + List<String> reply = new ArrayList<>(); + boolean convPath = false; + for (var opt : lightOptions) { + if (convPath) { + opt = normalizePath.apply(Path.of(opt)).toString(); + convPath = false; + } else if (pathOptions.contains(opt)) { + convPath = true; + } + reply.add(opt); + } + return reply; + } + + private Path workDir; + private Path wixObjDir; + private final Map<String, String> wixVariables = new HashMap<>(); + private final List<String> lightOptions = new ArrayList<>(); + private final List<WixSource> sources = new ArrayList<>(); } - WixPipeline addSource(Path source, Map<String, String> wixVariables) { - WixSource entry = new WixSource(); - entry.source = source; - entry.variables = wixVariables; - sources.add(entry); - return this; + static Builder build() { + return new Builder(); } - WixPipeline addLightOptions(String ... v) { - lightOptions.addAll(List.of(v)); - return this; + private WixPipeline(WixToolset toolset, Path workDir, Path wixObjDir, + Map<String, String> wixVariables, List<String> lightOptions, + List<WixSource> sources) { + this.toolset = toolset; + this.workDir = workDir; + this.wixObjDir = wixObjDir; + this.wixVariables = wixVariables; + this.lightOptions = lightOptions; + this.sources = sources; } void buildMsi(Path msi) throws IOException { Objects.requireNonNull(workDir); + // Use short path to the output msi to workaround + // WiX limitations of handling long paths. + var transientMsi = wixObjDir.resolve("a.msi"); + switch (toolset.getType()) { - case Wix3 -> buildMsiWix3(msi); - case Wix4 -> buildMsiWix4(msi); + case Wix3 -> buildMsiWix3(transientMsi); + case Wix4 -> buildMsiWix4(transientMsi); default -> throw new IllegalArgumentException(); } + + IOUtils.copyFile(workDir.resolve(transientMsi), msi); } private void addWixVariblesToCommandLine( @@ -141,7 +206,7 @@ private void buildMsiWix4(Path msi) throws IOException { "build", "-nologo", "-pdbtype", "none", - "-intermediatefolder", wixObjDir.toAbsolutePath().toString(), + "-intermediatefolder", wixObjDir.toString(), "-ext", "WixToolset.Util.wixext", "-arch", WixFragmentBuilder.is64Bit() ? "x64" : "x86" )); @@ -151,7 +216,7 @@ private void buildMsiWix4(Path msi) throws IOException { addWixVariblesToCommandLine(mergedSrcWixVars, cmdline); cmdline.addAll(sources.stream().map(wixSource -> { - return wixSource.source.toAbsolutePath().toString(); + return wixSource.path.toString(); }).toList()); cmdline.addAll(List.of("-out", msi.toString())); @@ -182,15 +247,15 @@ private void buildMsiWix3(Path msi) throws IOException { private Path compileWix3(WixSource wixSource) throws IOException { Path wixObj = wixObjDir.toAbsolutePath().resolve(PathUtils.replaceSuffix( - IOUtils.getFileName(wixSource.source), ".wixobj")); + wixSource.path.getFileName(), ".wixobj")); List<String> cmdline = new ArrayList<>(List.of( toolset.getToolPath(WixTool.Candle3).toString(), "-nologo", - wixSource.source.toAbsolutePath().toString(), + wixSource.path.toString(), "-ext", "WixUtilExtension", "-arch", WixFragmentBuilder.is64Bit() ? "x64" : "x86", - "-out", wixObj.toAbsolutePath().toString() + "-out", wixObj.toString() )); addWixVariblesToCommandLine(wixSource.variables, cmdline); @@ -201,19 +266,19 @@ private Path compileWix3(WixSource wixSource) throws IOException { } private void execute(List<String> cmdline) throws IOException { - Executor.of(new ProcessBuilder(cmdline).directory(workDir.toFile())). - executeExpectSuccess(); + Executor.of(new ProcessBuilder(cmdline).directory(workDir.toFile())).executeExpectSuccess(); } - private static final class WixSource { - Path source; - Map<String, String> variables; + private record WixSource(Path path, Map<String, String> variables) { + WixSource overridePath(Path path) { + return new WixSource(path, variables); + } } - private WixToolset toolset; - private Map<String, String> wixVariables; - private List<String> lightOptions; - private Path wixObjDir; - private Path workDir; - private List<WixSource> sources; + private final WixToolset toolset; + private final Map<String, String> wixVariables; + private final List<String> lightOptions; + private final Path wixObjDir; + private final Path workDir; + private final List<WixSource> sources; } diff --git a/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/WixUiFragmentBuilder.java b/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/WixUiFragmentBuilder.java index 5eb23fc58c4..25db6e6ab0b 100644 --- a/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/WixUiFragmentBuilder.java +++ b/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/WixUiFragmentBuilder.java @@ -97,7 +97,7 @@ void initFromParams(Map<String, ? super Object> params) { } @Override - void configureWixPipeline(WixPipeline wixPipeline) { + void configureWixPipeline(WixPipeline.Builder wixPipeline) { super.configureWixPipeline(wixPipeline); if (withShortcutPromptDlg || withInstallDirChooserDlg || withLicenseDlg) { @@ -518,7 +518,7 @@ private final class CustomDialog { wxsFileName), wxsFileName); } - void addToWixPipeline(WixPipeline wixPipeline) { + void addToWixPipeline(WixPipeline.Builder wixPipeline) { wixPipeline.addSource(getConfigRoot().toAbsolutePath().resolve( wxsFileName), wixVariables.getValues()); } diff --git a/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/resources/WinResources.properties b/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/resources/WinResources.properties index 9e7504364d3..584342397a6 100644 --- a/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/resources/WinResources.properties +++ b/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/resources/WinResources.properties @@ -56,6 +56,7 @@ error.lock-resource=Failed to lock: {0} error.unlock-resource=Failed to unlock: {0} error.read-wix-l10n-file=Failed to parse {0} file error.extract-culture-from-wix-l10n-file=Failed to read value of culture from {0} file +error.short-path-conv-fail=Failed to get short version of "{0}" path message.icon-not-ico=The specified icon "{0}" is not an ICO file and will not be used. The default icon will be used in it's place. message.potential.windows.defender.issue=Warning: Windows Defender may prevent jpackage from functioning. If there is an issue, it can be addressed by either disabling realtime monitoring, or adding an exclusion for the directory "{0}". diff --git a/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/resources/WinResources_de.properties b/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/resources/WinResources_de.properties index a7212d9640a..dce8ca6176d 100644 --- a/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/resources/WinResources_de.properties +++ b/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/resources/WinResources_de.properties @@ -56,6 +56,7 @@ error.lock-resource=Sperren nicht erfolgreich: {0} error.unlock-resource=Aufheben der Sperre nicht erfolgreich: {0} error.read-wix-l10n-file=Datei {0} konnte nicht geparst werden error.extract-culture-from-wix-l10n-file=Kulturwert konnte nicht aus Datei {0} gelesen werden +error.short-path-conv-fail=Failed to get short version of "{0}" path message.icon-not-ico=Das angegebene Symbol "{0}" ist keine ICO-Datei und wird nicht verwendet. Stattdessen wird das Standardsymbol verwendet. message.potential.windows.defender.issue=Warnung: Windows Defender verhindert eventuell die korrekte Ausführung von jpackage. Wenn ein Problem auftritt, deaktivieren Sie das Echtzeitmonitoring, oder fügen Sie einen Ausschluss für das Verzeichnis "{0}" hinzu. diff --git a/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/resources/WinResources_ja.properties b/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/resources/WinResources_ja.properties index 352aab7a493..47e5b585869 100644 --- a/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/resources/WinResources_ja.properties +++ b/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/resources/WinResources_ja.properties @@ -56,6 +56,7 @@ error.lock-resource=ロックに失敗しました: {0} error.unlock-resource=ロック解除に失敗しました: {0} error.read-wix-l10n-file={0}ファイルの解析に失敗しました error.extract-culture-from-wix-l10n-file={0}ファイルからのカルチャの値の読取りに失敗しました +error.short-path-conv-fail=Failed to get short version of "{0}" path message.icon-not-ico=指定したアイコン"{0}"はICOファイルではなく、使用されません。デフォルト・アイコンがその位置に使用されます。 message.potential.windows.defender.issue=警告: Windows Defenderが原因でjpackageが機能しないことがあります。問題が発生した場合は、リアルタイム・モニタリングを無効にするか、ディレクトリ"{0}"の除外を追加することにより、問題に対処できます。 diff --git a/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/resources/WinResources_zh_CN.properties b/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/resources/WinResources_zh_CN.properties index a8d4a4471d6..abd3d13a667 100644 --- a/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/resources/WinResources_zh_CN.properties +++ b/src/jdk.jpackage/windows/classes/jdk/jpackage/internal/resources/WinResources_zh_CN.properties @@ -56,6 +56,7 @@ error.lock-resource=无法锁定:{0} error.unlock-resource=无法解锁:{0} error.read-wix-l10n-file=无法解析 {0} 文件 error.extract-culture-from-wix-l10n-file=无法从 {0} 文件读取文化值 +error.short-path-conv-fail=Failed to get short version of "{0}" path message.icon-not-ico=指定的图标 "{0}" 不是 ICO 文件, 不会使用。将使用默认图标代替。 message.potential.windows.defender.issue=警告:Windows Defender 可能会阻止 jpackage 正常工作。如果存在问题,可以通过禁用实时监视或者为目录 "{0}" 添加排除项来解决。 diff --git a/src/jdk.jpackage/windows/native/common/WinFileUtils.cpp b/src/jdk.jpackage/windows/native/common/WinFileUtils.cpp index 993aed8bb13..f801009ed94 100644 --- a/src/jdk.jpackage/windows/native/common/WinFileUtils.cpp +++ b/src/jdk.jpackage/windows/native/common/WinFileUtils.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -668,4 +668,23 @@ tstring stripExeSuffix(const tstring& path) { return path.substr(0, pos); } +tstring toShortPath(const tstring& path) { + const DWORD len = GetShortPathName(path.c_str(), nullptr, 0); + if (0 == len) { + JP_THROW(SysError(tstrings::any() << "GetShortPathName(" + << path << ") failed", GetShortPathName)); + } + + std::vector<TCHAR> buf; + buf.resize(len); + const DWORD copied = GetShortPathName(path.c_str(), buf.data(), + static_cast<DWORD>(buf.size())); + if (copied != buf.size() - 1) { + JP_THROW(SysError(tstrings::any() << "GetShortPathName(" + << path << ") failed", GetShortPathName)); + } + + return tstring(buf.data(), buf.size() - 1); +} + } // namespace FileUtils diff --git a/src/jdk.jpackage/windows/native/common/WinFileUtils.h b/src/jdk.jpackage/windows/native/common/WinFileUtils.h index 2dfb32fa088..ba07efec78e 100644 --- a/src/jdk.jpackage/windows/native/common/WinFileUtils.h +++ b/src/jdk.jpackage/windows/native/common/WinFileUtils.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -315,6 +315,8 @@ namespace FileUtils { std::ofstream tmp; tstring dstPath; }; + + tstring toShortPath(const tstring& path); } // FileUtils #endif // WINFILEUTILS_H diff --git a/src/jdk.jpackage/windows/native/libjpackage/jpackage.cpp b/src/jdk.jpackage/windows/native/libjpackage/jpackage.cpp index 6317842787e..66fa92e3563 100644 --- a/src/jdk.jpackage/windows/native/libjpackage/jpackage.cpp +++ b/src/jdk.jpackage/windows/native/libjpackage/jpackage.cpp @@ -25,6 +25,8 @@ #include "ResourceEditor.h" #include "ErrorHandling.h" +#include "FileUtils.h" +#include "WinFileUtils.h" #include "IconSwap.h" #include "VersionInfo.h" #include "JniUtils.h" @@ -162,4 +164,25 @@ extern "C" { return 1; } + /* + * Class: jdk_jpackage_internal_ShortPathUtils + * Method: getShortPath + * Signature: (Ljava/lang/String;)Ljava/lang/String; + */ + JNIEXPORT jstring JNICALL + Java_jdk_jpackage_internal_ShortPathUtils_getShortPath( + JNIEnv *pEnv, jclass c, jstring jLongPath) { + + JP_TRY; + + const std::wstring longPath = jni::toUnicodeString(pEnv, jLongPath); + std::wstring shortPath = FileUtils::toShortPath(longPath); + + return jni::toJString(pEnv, shortPath); + + JP_CATCH_ALL; + + return NULL; + } + } // extern "C" \ No newline at end of file diff --git a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/Executor.java b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/Executor.java index f182f4f7f7d..00f6ab5263c 100644 --- a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/Executor.java +++ b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/Executor.java @@ -53,7 +53,7 @@ public static Executor of(String... cmdline) { public Executor() { saveOutputType = new HashSet<>(Set.of(SaveOutputType.NONE)); - removePath = false; + removePathEnvVar = false; } public Executor setExecutable(String v) { @@ -85,8 +85,8 @@ public Executor setExecutable(JavaTool v) { return setExecutable(v.getPath()); } - public Executor setRemovePath(boolean value) { - removePath = value; + public Executor setRemovePathEnvVar(boolean value) { + removePathEnvVar = value; return this; } @@ -348,7 +348,7 @@ private Result runExecutable() throws IOException, InterruptedException { builder.directory(directory.toFile()); sb.append(String.format("; in directory [%s]", directory)); } - if (removePath) { + if (removePathEnvVar) { // run this with cleared Path in Environment TKit.trace("Clearing PATH in environment"); builder.environment().remove("PATH"); @@ -478,7 +478,7 @@ private static void trace(String msg) { private Path executable; private Set<SaveOutputType> saveOutputType; private Path directory; - private boolean removePath; + private boolean removePathEnvVar; private String winTmpDir = null; private static enum SaveOutputType { diff --git a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/HelloApp.java b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/HelloApp.java index bc35912bcbb..0c7476e863d 100644 --- a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/HelloApp.java +++ b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/HelloApp.java @@ -354,12 +354,12 @@ public static final class AppOutputVerifier { if (TKit.isWindows()) { // When running app launchers on Windows, clear users environment (JDK-8254920) - removePath(true); + removePathEnvVar(true); } } - public AppOutputVerifier removePath(boolean v) { - removePath = v; + public AppOutputVerifier removePathEnvVar(boolean v) { + removePathEnvVar = v; return this; } @@ -455,7 +455,7 @@ private Executor getExecutor(String...args) { Path outputFile = TKit.workDir().resolve(OUTPUT_FILENAME); ThrowingFunction.toFunction(Files::deleteIfExists).apply(outputFile); - final Path executablePath; + Path executablePath; if (launcherPath.isAbsolute()) { executablePath = launcherPath; } else { @@ -463,18 +463,27 @@ private Executor getExecutor(String...args) { executablePath = Path.of(".").resolve(launcherPath.normalize()); } + if (TKit.isWindows()) { + var absExecutablePath = executablePath.toAbsolutePath().normalize(); + var shortPath = WindowsHelper.toShortPath(absExecutablePath); + if (shortPath.isPresent()) { + TKit.trace(String.format("Will run [%s] as [%s]", executablePath, shortPath.get())); + executablePath = shortPath.get(); + } + } + final List<String> launcherArgs = List.of(args); return new Executor() .setDirectory(outputFile.getParent()) .saveOutput(saveOutput) .dumpOutput() - .setRemovePath(removePath) + .setRemovePathEnvVar(removePathEnvVar) .setExecutable(executablePath) .addArguments(launcherArgs); } private boolean launcherNoExit; - private boolean removePath; + private boolean removePathEnvVar; private boolean saveOutput; private final Path launcherPath; private Path outputFilePath; diff --git a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/WindowsHelper.java b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/WindowsHelper.java index 42ea9e3e9a7..4fb937864aa 100644 --- a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/WindowsHelper.java +++ b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/WindowsHelper.java @@ -23,6 +23,7 @@ package jdk.jpackage.test; import java.io.IOException; +import java.lang.reflect.Method; import java.nio.file.Files; import java.nio.file.Path; import java.util.HashMap; @@ -36,7 +37,9 @@ import java.util.regex.Pattern; import java.util.stream.Collectors; import java.util.stream.Stream; +import static jdk.jpackage.internal.util.function.ExceptionBox.rethrowUnchecked; import jdk.jpackage.internal.util.function.ThrowingRunnable; +import static jdk.jpackage.internal.util.function.ThrowingSupplier.toSupplier; import jdk.jpackage.test.PackageTest.PackageHandlers; public class WindowsHelper { @@ -94,8 +97,9 @@ private static void runMsiexecWithRetries(Executor misexec) { static PackageHandlers createMsiPackageHandlers() { BiConsumer<JPackageCommand, Boolean> installMsi = (cmd, install) -> { cmd.verifyIsOfType(PackageType.WIN_MSI); + var msiPath = TransientMsi.create(cmd).path(); runMsiexecWithRetries(Executor.of("msiexec", "/qn", "/norestart", - install ? "/i" : "/x").addArgument(cmd.outputBundle().normalize())); + install ? "/i" : "/x").addArgument(msiPath)); }; PackageHandlers msi = new PackageHandlers(); @@ -112,6 +116,8 @@ static PackageHandlers createMsiPackageHandlers() { TKit.removeRootFromAbsolutePath( getInstallationRootDirectory(cmd))); + final Path msiPath = TransientMsi.create(cmd).path(); + // Put msiexec in .bat file because can't pass value of TARGETDIR // property containing spaces through ProcessBuilder properly. // Set folder permissions to allow msiexec unpack msi bundle. @@ -121,7 +127,7 @@ static PackageHandlers createMsiPackageHandlers() { String.join(" ", List.of( "msiexec", "/a", - String.format("\"%s\"", cmd.outputBundle().normalize()), + String.format("\"%s\"", msiPath), "/qn", String.format("TARGETDIR=\"%s\"", unpackDir.toAbsolutePath().normalize()))))); @@ -155,6 +161,49 @@ static PackageHandlers createMsiPackageHandlers() { return msi; } + record TransientMsi(Path path) { + static TransientMsi create(JPackageCommand cmd) { + var outputMsiPath = cmd.outputBundle().normalize(); + if (isPathTooLong(outputMsiPath)) { + return toSupplier(() -> { + var transientMsiPath = TKit.createTempDirectory("msi-copy").resolve("a.msi").normalize(); + TKit.trace(String.format("Copy [%s] to [%s]", outputMsiPath, transientMsiPath)); + Files.copy(outputMsiPath, transientMsiPath); + return new TransientMsi(transientMsiPath); + }).get(); + } else { + return new TransientMsi(outputMsiPath); + } + } + } + + public enum WixType { + WIX3, + WIX4 + } + + public static WixType getWixTypeFromVerboseJPackageOutput(Executor.Result result) { + return result.getOutput().stream().map(str -> { + if (str.contains("[light.exe]")) { + return WixType.WIX3; + } else if (str.contains("[wix.exe]")) { + return WixType.WIX4; + } else { + return null; + } + }).filter(Objects::nonNull).reduce((a, b) -> { + throw new IllegalArgumentException("Invalid input: multiple invocations of WiX tools"); + }).orElseThrow(() -> new IllegalArgumentException("Invalid input: no invocations of WiX tools")); + } + + static Optional<Path> toShortPath(Path path) { + if (isPathTooLong(path)) { + return Optional.of(ShortPathUtils.toShortPath(path)); + } else { + return Optional.empty(); + } + } + static PackageHandlers createExePackageHandlers() { BiConsumer<JPackageCommand, Boolean> installExe = (cmd, install) -> { cmd.verifyIsOfType(PackageType.WIN_EXE); @@ -303,6 +352,10 @@ private static boolean isUserLocalInstall(JPackageCommand cmd) { return cmd.hasArgument("--win-per-user-install"); } + private static boolean isPathTooLong(Path path) { + return path.toString().length() > WIN_MAX_PATH; + } + private static class DesktopIntegrationVerifier { DesktopIntegrationVerifier(JPackageCommand cmd, String launcherName) { @@ -525,6 +578,32 @@ private static String queryRegistryValueCache(String keyPath, return value; } + private static final class ShortPathUtils { + private ShortPathUtils() { + try { + var shortPathUtilsClass = Class.forName("jdk.jpackage.internal.ShortPathUtils"); + + getShortPathWrapper = shortPathUtilsClass.getDeclaredMethod( + "getShortPathWrapper", String.class); + // Note: this reflection call requires + // --add-opens jdk.jpackage/jdk.jpackage.internal=ALL-UNNAMED + getShortPathWrapper.setAccessible(true); + } catch (ClassNotFoundException | NoSuchMethodException + | SecurityException ex) { + throw rethrowUnchecked(ex); + } + } + + static Path toShortPath(Path path) { + return Path.of(toSupplier(() -> (String) INSTANCE.getShortPathWrapper.invoke( + null, path.toString())).get()); + } + + private final Method getShortPathWrapper; + + private static final ShortPathUtils INSTANCE = new ShortPathUtils(); + } + static final Set<Path> CRITICAL_RUNTIME_FILES = Set.of(Path.of( "bin\\server\\jvm.dll")); @@ -540,4 +619,6 @@ private static String queryRegistryValueCache(String keyPath, private static final String USER_SHELL_FOLDERS_REGKEY = "HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders"; private static final Map<String, String> REGISTRY_VALUES = new HashMap<>(); + + private static final int WIN_MAX_PATH = 260; } diff --git a/test/jdk/tools/jpackage/windows/WinL10nTest.java b/test/jdk/tools/jpackage/windows/WinL10nTest.java index 814b6401f47..dee1e42267d 100644 --- a/test/jdk/tools/jpackage/windows/WinL10nTest.java +++ b/test/jdk/tools/jpackage/windows/WinL10nTest.java @@ -35,6 +35,8 @@ import java.util.stream.Collectors; import java.util.stream.Stream; import jdk.jpackage.test.Executor; +import static jdk.jpackage.test.WindowsHelper.WixType.WIX3; +import static jdk.jpackage.test.WindowsHelper.getWixTypeFromVerboseJPackageOutput; /* * @test @@ -109,13 +111,13 @@ public static List<Object[]> data() { }); } - private static Stream<String> getBuildCommandLine(Executor.Result result) { + private static Stream<String> getWixCommandLine(Executor.Result result) { return result.getOutput().stream().filter(createToolCommandLinePredicate("light").or( createToolCommandLinePredicate("wix"))); } private static boolean isWix3(Executor.Result result) { - return result.getOutput().stream().anyMatch(createToolCommandLinePredicate("light")); + return getWixTypeFromVerboseJPackageOutput(result) == WIX3; } private final static Predicate<String> createToolCommandLinePredicate(String wixToolName) { @@ -127,10 +129,10 @@ private final static Predicate<String> createToolCommandLinePredicate(String wix }; } - private static List<TKit.TextStreamVerifier> createDefaultL10nFilesLocVerifiers(Path tempDir) { + private static List<TKit.TextStreamVerifier> createDefaultL10nFilesLocVerifiers(Path wixSrcDir) { return Arrays.stream(DEFAULT_L10N_FILES).map(loc -> - TKit.assertTextStream("-loc " + tempDir.resolve( - String.format("config/MsiInstallerStrings_%s.wxl", loc)).normalize())) + TKit.assertTextStream("-loc " + wixSrcDir.resolve( + String.format("MsiInstallerStrings_%s.wxl", loc)))) .toList(); } @@ -183,16 +185,20 @@ public void test() throws IOException { cmd.addArguments("--temp", tempDir); }) .addBundleVerifier((cmd, result) -> { + final List<String> wixCmdline = getWixCommandLine(result).toList(); + + final var isWix3 = isWix3(result); + if (expectedCultures != null) { String expected; - if (isWix3(result)) { + if (isWix3) { expected = "-cultures:" + String.join(";", expectedCultures); } else { expected = Stream.of(expectedCultures).map(culture -> { return String.join(" ", "-culture", culture); }).collect(Collectors.joining(" ")); } - TKit.assertTextStream(expected).apply(getBuildCommandLine(result)); + TKit.assertTextStream(expected).apply(wixCmdline.stream()); } if (expectedErrorMessage != null) { @@ -201,25 +207,27 @@ public void test() throws IOException { } if (wxlFileInitializers != null) { - var wixSrcDir = Path.of(cmd.getArgumentValue("--temp")).resolve("config"); + var wixSrcDir = Path.of(cmd.getArgumentValue("--temp")).resolve( + "config").normalize().toAbsolutePath(); if (allWxlFilesValid) { for (var v : wxlFileInitializers) { if (!v.name.startsWith("MsiInstallerStrings_")) { - v.createCmdOutputVerifier(wixSrcDir).apply(getBuildCommandLine(result)); + v.createCmdOutputVerifier(wixSrcDir).apply(wixCmdline.stream()); } } - var tempDir = Path.of(cmd.getArgumentValue("--temp")).toAbsolutePath(); - for (var v : createDefaultL10nFilesLocVerifiers(tempDir)) { - v.apply(getBuildCommandLine(result)); + + for (var v : createDefaultL10nFilesLocVerifiers(wixSrcDir)) { + v.apply(wixCmdline.stream()); } } else { Stream.of(wxlFileInitializers) .filter(Predicate.not(WixFileInitializer::isValid)) .forEach(v -> v.createCmdOutputVerifier( wixSrcDir).apply(result.getOutput().stream())); - TKit.assertFalse(getBuildCommandLine(result).findAny().isPresent(), - "Check light.exe was not invoked"); + TKit.assertTrue(wixCmdline.stream().findAny().isEmpty(), + String.format("Check %s.exe was not invoked", + isWix3 ? "light" : "wix")); } } }); @@ -276,10 +284,9 @@ boolean isValid() { } @Override - TKit.TextStreamVerifier createCmdOutputVerifier(Path root) { + TKit.TextStreamVerifier createCmdOutputVerifier(Path wixSrcDir) { return TKit.assertTextStream(String.format( - "Failed to parse %s file", - root.resolve("b.wxl").toAbsolutePath())); + "Failed to parse %s file", wixSrcDir.resolve("b.wxl"))); } }; } @@ -297,9 +304,8 @@ void apply(Path root) throws IOException { + "\" xmlns=\"http://schemas.microsoft.com/wix/2006/localization\" Codepage=\"1252\"/>")); } - TKit.TextStreamVerifier createCmdOutputVerifier(Path root) { - return TKit.assertTextStream( - "-loc " + root.resolve(name).toAbsolutePath().normalize()); + TKit.TextStreamVerifier createCmdOutputVerifier(Path wixSrcDir) { + return TKit.assertTextStream("-loc " + wixSrcDir.resolve(name)); } boolean isValid() { diff --git a/test/jdk/tools/jpackage/windows/WinLongPathTest.java b/test/jdk/tools/jpackage/windows/WinLongPathTest.java new file mode 100644 index 00000000000..e9e5ef8ce03 --- /dev/null +++ b/test/jdk/tools/jpackage/windows/WinLongPathTest.java @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.List; +import jdk.jpackage.test.Annotations.Parameters; +import jdk.jpackage.test.PackageTest; +import jdk.jpackage.test.PackageType; +import jdk.jpackage.test.Annotations.Test; +import jdk.jpackage.test.JPackageCommand; +import jdk.jpackage.test.RunnablePackageTest.Action; +import jdk.jpackage.test.TKit; + +/* +/* @test + * @bug 8289771 + * @summary jpackage with long paths on windows + * @library /test/jdk/tools/jpackage/helpers + * @key jpackagePlatformPackage + * @build jdk.jpackage.test.* + * @requires (os.family == "windows") + * @compile WinLongPathTest.java + * @run main/othervm/timeout=540 -Xmx512m jdk.jpackage.test.Main + * --jpt-space-subst=* + * --jpt-exclude=WinLongPathTest(false,*--temp) + * --jpt-run=WinLongPathTest + */ + +public record WinLongPathTest(Boolean appImage, String optionName) { + + @Parameters + public static List<Object[]> input() { + List<Object[]> data = new ArrayList<>(); + for (var appImage : List.of(Boolean.TRUE, Boolean.FALSE)) { + for (var option : List.of("--dest", "--temp")) { + data.add(new Object[]{appImage, option}); + } + } + return data; + } + + @Test + public void test() throws IOException { + if (appImage) { + var cmd = JPackageCommand.helloAppImage(); + setOptionLongPath(cmd, optionName); + cmd.executeAndAssertHelloAppImageCreated(); + } else { + new PackageTest() + .forTypes(PackageType.WINDOWS) + .configureHelloApp() + .addInitializer(cmd -> setOptionLongPath(cmd, optionName)) + .run(Action.CREATE_AND_UNPACK); + } + } + + private static void setOptionLongPath(JPackageCommand cmd, String option) throws IOException { + var root = TKit.createTempDirectory("long-path"); + // 261 characters in total, which alone is above the 260 threshold + var longPath = root.resolve(Path.of("a".repeat(80), "b".repeat(90), "c".repeat(91))); + Files.createDirectories(longPath); + cmd.setArgumentValue(option, longPath); + } +} From 27fda0ea1f7e230a1b8a8413efc2d4314b600a82 Mon Sep 17 00:00:00 2001 From: Phil Race <prr@openjdk.org> Date: Wed, 20 Nov 2024 18:38:08 +0000 Subject: [PATCH 137/311] 8344578: Clean up left over java.security and sun.security imports in Swing classes Reviewed-by: psadhukhan --- .../share/classes/javax/swing/RepaintManager.java | 6 ------ .../classes/javax/swing/SwingPaintEventDispatcher.java | 1 - .../classes/javax/swing/plaf/basic/BasicOptionPaneUI.java | 4 ---- .../classes/javax/swing/plaf/metal/MetalLookAndFeel.java | 1 - 4 files changed, 12 deletions(-) diff --git a/src/java.desktop/share/classes/javax/swing/RepaintManager.java b/src/java.desktop/share/classes/javax/swing/RepaintManager.java index 2636c81be07..4799472d44f 100644 --- a/src/java.desktop/share/classes/javax/swing/RepaintManager.java +++ b/src/java.desktop/share/classes/javax/swing/RepaintManager.java @@ -32,14 +32,11 @@ import java.util.concurrent.atomic.AtomicInteger; import java.applet.*; -import jdk.internal.access.JavaSecurityAccess; -import jdk.internal.access.SharedSecrets; import sun.awt.AWTAccessor; import sun.awt.AppContext; import sun.awt.DisplayChangedListener; import sun.awt.SunToolkit; import sun.java2d.SunGraphicsEnvironment; -import sun.security.action.GetPropertyAction; import com.sun.java.swing.SwingUtilities3; import java.awt.geom.AffineTransform; @@ -185,9 +182,6 @@ public class RepaintManager */ private final ProcessingRunnable processingRunnable; - private static final JavaSecurityAccess javaSecurityAccess = - SharedSecrets.getJavaSecurityAccess(); - /** * Listener installed to detect display changes. When display changes, * schedules a callback to notify all RepaintManagers of the display diff --git a/src/java.desktop/share/classes/javax/swing/SwingPaintEventDispatcher.java b/src/java.desktop/share/classes/javax/swing/SwingPaintEventDispatcher.java index 4bada6e8bc7..1cabf129db1 100644 --- a/src/java.desktop/share/classes/javax/swing/SwingPaintEventDispatcher.java +++ b/src/java.desktop/share/classes/javax/swing/SwingPaintEventDispatcher.java @@ -28,7 +28,6 @@ import java.awt.Container; import java.awt.Rectangle; import java.awt.event.PaintEvent; -import java.security.AccessController; import sun.awt.AppContext; import sun.awt.SunToolkit; import sun.awt.event.IgnorePaintEvent; diff --git a/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicOptionPaneUI.java b/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicOptionPaneUI.java index 2e61967031c..07036eedbf6 100644 --- a/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicOptionPaneUI.java +++ b/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicOptionPaneUI.java @@ -39,10 +39,6 @@ import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.util.Locale; -import java.security.AccessController; - -import sun.security.action.GetPropertyAction; - /** * Provides the basic look and feel for a <code>JOptionPane</code>. diff --git a/src/java.desktop/share/classes/javax/swing/plaf/metal/MetalLookAndFeel.java b/src/java.desktop/share/classes/javax/swing/plaf/metal/MetalLookAndFeel.java index 18547fcbbf9..41d90d31dd4 100644 --- a/src/java.desktop/share/classes/javax/swing/plaf/metal/MetalLookAndFeel.java +++ b/src/java.desktop/share/classes/javax/swing/plaf/metal/MetalLookAndFeel.java @@ -64,7 +64,6 @@ import sun.awt.AppContext; import sun.awt.OSInfo; import sun.awt.SunToolkit; -import sun.security.action.GetPropertyAction; import sun.swing.DefaultLayoutStyle; import sun.swing.SwingAccessor; import sun.swing.SwingUtilities2; From 22a39dc858a27cecfb0a8a8ef42e2cf5f7444545 Mon Sep 17 00:00:00 2001 From: Phil Race <prr@openjdk.org> Date: Wed, 20 Nov 2024 18:45:49 +0000 Subject: [PATCH 138/311] 8344064: Remove doPrivileged calls from print/imageio/media classes in the java.desktop module Reviewed-by: kizune --- .../imageio/plugins/bmp/BMPImageReader.java | 12 +--- .../imageio/plugins/jpeg/JPEGImageReader.java | 11 +--- .../imageio/plugins/jpeg/JPEGImageWriter.java | 11 +--- .../com/sun/imageio/stream/StreamCloser.java | 29 ++++----- .../com/sun/java/swing/plaf/gtk/Metacity.java | 38 +++-------- .../sun/media/sound/JARSoundbankReader.java | 6 +- .../com/sun/media/sound/JDK13Services.java | 6 +- .../sun/media/sound/JSSecurityManager.java | 47 +++----------- .../classes/com/sun/media/sound/Platform.java | 9 +-- .../classes/com/sun/media/sound/Printer.java | 5 +- .../com/sun/media/sound/SoftSynthesizer.java | 64 +++++++++---------- .../share/classes/javax/imageio/ImageIO.java | 4 +- .../javax/imageio/metadata/IIOMetadata.java | 7 +- .../javax/imageio/spi/IIORegistry.java | 34 +++------- .../imageio/spi/ImageReaderWriterSpi.java | 7 +- .../javax/imageio/spi/ServiceRegistry.java | 20 +----- .../share/classes/javax/print/DocFlavor.java | 5 +- .../javax/print/PrintServiceLookup.java | 30 ++------- .../print/StreamPrintServiceFactory.java | 46 ++++--------- 19 files changed, 102 insertions(+), 289 deletions(-) diff --git a/src/java.desktop/share/classes/com/sun/imageio/plugins/bmp/BMPImageReader.java b/src/java.desktop/share/classes/com/sun/imageio/plugins/bmp/BMPImageReader.java index 9eab27031d4..06af183b37c 100644 --- a/src/java.desktop/share/classes/com/sun/imageio/plugins/bmp/BMPImageReader.java +++ b/src/java.desktop/share/classes/com/sun/imageio/plugins/bmp/BMPImageReader.java @@ -48,8 +48,6 @@ import java.io.ByteArrayInputStream; import java.io.IOException; import java.nio.ByteOrder; -import java.security.AccessController; -import java.security.PrivilegedAction; import java.util.ArrayList; import java.util.Iterator; import java.util.List; @@ -2039,17 +2037,9 @@ public void readAborted(ImageReader src) {} private static Boolean isLinkedProfileAllowed = null; - @SuppressWarnings("removal") private static boolean isLinkedProfileAllowed() { if (isLinkedProfileAllowed == null) { - PrivilegedAction<Boolean> a = new PrivilegedAction<Boolean>() { - @Override - public Boolean run() { - return Boolean. - getBoolean("sun.imageio.bmp.enableLinkedProfiles"); - } - }; - isLinkedProfileAllowed = AccessController.doPrivileged(a); + isLinkedProfileAllowed = Boolean.getBoolean("sun.imageio.bmp.enableLinkedProfiles"); } return isLinkedProfileAllowed; } diff --git a/src/java.desktop/share/classes/com/sun/imageio/plugins/jpeg/JPEGImageReader.java b/src/java.desktop/share/classes/com/sun/imageio/plugins/jpeg/JPEGImageReader.java index c28759058c0..24013fb68ad 100644 --- a/src/java.desktop/share/classes/com/sun/imageio/plugins/jpeg/JPEGImageReader.java +++ b/src/java.desktop/share/classes/com/sun/imageio/plugins/jpeg/JPEGImageReader.java @@ -90,16 +90,9 @@ public class JPEGImageReader extends ImageReader { initStatic(); } - @SuppressWarnings({"removal", "restricted"}) + @SuppressWarnings("restricted") private static void initStatic() { - java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction<Void>() { - @Override - public Void run() { - System.loadLibrary("javajpeg"); - return null; - } - }); + System.loadLibrary("javajpeg"); initReaderIDs(ImageInputStream.class, JPEGQTable.class, JPEGHuffmanTable.class); diff --git a/src/java.desktop/share/classes/com/sun/imageio/plugins/jpeg/JPEGImageWriter.java b/src/java.desktop/share/classes/com/sun/imageio/plugins/jpeg/JPEGImageWriter.java index 39189130be3..f263d47f6c9 100644 --- a/src/java.desktop/share/classes/com/sun/imageio/plugins/jpeg/JPEGImageWriter.java +++ b/src/java.desktop/share/classes/com/sun/imageio/plugins/jpeg/JPEGImageWriter.java @@ -175,16 +175,9 @@ public class JPEGImageWriter extends ImageWriter { initStatic(); } - @SuppressWarnings({"removal", "restricted"}) + @SuppressWarnings("restricted") private static void initStatic() { - java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction<Void>() { - @Override - public Void run() { - System.loadLibrary("javajpeg"); - return null; - } - }); + System.loadLibrary("javajpeg"); initWriterIDs(JPEGQTable.class, JPEGHuffmanTable.class); } diff --git a/src/java.desktop/share/classes/com/sun/imageio/stream/StreamCloser.java b/src/java.desktop/share/classes/com/sun/imageio/stream/StreamCloser.java index 3dabca71ffb..b40c53ead3d 100644 --- a/src/java.desktop/share/classes/com/sun/imageio/stream/StreamCloser.java +++ b/src/java.desktop/share/classes/com/sun/imageio/stream/StreamCloser.java @@ -28,8 +28,6 @@ import sun.awt.util.ThreadGroupUtils; import java.io.IOException; -import java.security.AccessController; -import java.security.PrivilegedAction; import java.util.Set; import java.util.WeakHashMap; import javax.imageio.stream.ImageInputStream; @@ -86,21 +84,18 @@ public void run() { } }; - AccessController.doPrivileged((PrivilegedAction<Object>) () -> { - /* The thread must be a member of a thread group - * which will not get GCed before VM exit. - * Make its parent the top-level thread group. - */ - ThreadGroup tg = ThreadGroupUtils.getRootThreadGroup(); - streamCloser = new Thread(tg, streamCloserRunnable, - "StreamCloser", 0, false); - /* Set context class loader to null in order to avoid - * keeping a strong reference to an application classloader. - */ - streamCloser.setContextClassLoader(null); - Runtime.getRuntime().addShutdownHook(streamCloser); - return null; - }); + /* The thread must be a member of a thread group + * which will not get GCed before VM exit. + * Make its parent the top-level thread group. + */ + ThreadGroup tg = ThreadGroupUtils.getRootThreadGroup(); + streamCloser = new Thread(tg, streamCloserRunnable, + "StreamCloser", 0, false); + /* Set context class loader to null in order to avoid + * keeping a strong reference to an application classloader. + */ + streamCloser.setContextClassLoader(null); + Runtime.getRuntime().addShutdownHook(streamCloser); } } } diff --git a/src/java.desktop/share/classes/com/sun/java/swing/plaf/gtk/Metacity.java b/src/java.desktop/share/classes/com/sun/java/swing/plaf/gtk/Metacity.java index 295e474579b..629b107f163 100644 --- a/src/java.desktop/share/classes/com/sun/java/swing/plaf/gtk/Metacity.java +++ b/src/java.desktop/share/classes/com/sun/java/swing/plaf/gtk/Metacity.java @@ -60,8 +60,6 @@ import java.io.Reader; import java.net.MalformedURLException; import java.net.URL; -import java.security.AccessController; -import java.security.PrivilegedAction; import java.util.ArrayList; import java.util.HashMap; import java.util.Map; @@ -506,21 +504,12 @@ void paintFrameBorder(SynthContext context, Graphics g, int x0, int y0, int widt - private static class Privileged implements PrivilegedAction<Object> { + private static class ThemeGetter { private static int GET_THEME_DIR = 0; private static int GET_USER_THEME = 1; private static int GET_IMAGE = 2; - private int type; - private Object arg; - @SuppressWarnings("removal") - public Object doPrivileged(int type, Object arg) { - this.type = type; - this.arg = arg; - return AccessController.doPrivileged(this); - } - - public Object run() { + public Object getThemeItem(int type, Object arg) { if (type == GET_THEME_DIR) { String sep = File.separator; String[] dirs = new String[] { @@ -618,11 +607,11 @@ public Object run() { } private static URL getThemeDir(String themeName) { - return (URL)new Privileged().doPrivileged(Privileged.GET_THEME_DIR, themeName); + return (URL)new ThemeGetter().getThemeItem(ThemeGetter.GET_THEME_DIR, themeName); } private static String getUserTheme() { - return (String)new Privileged().doPrivileged(Privileged.GET_USER_THEME, null); + return (String)new ThemeGetter().getThemeItem(ThemeGetter.GET_USER_THEME, null); } protected void tileImage(Graphics g, Image image, int x0, int y0, int w, int h, float[] alphas) { @@ -673,7 +662,7 @@ protected Image getImage(String key) { try { @SuppressWarnings("deprecation") URL url = new URL(themeDir, key); - image = (Image)new Privileged().doPrivileged(Privileged.GET_IMAGE, url); + image = (Image)new ThemeGetter().getThemeItem(ThemeGetter.GET_IMAGE, url); } catch (MalformedURLException ex) { //log("Bad image url: "+ themeDir + "/" + key); } @@ -1587,18 +1576,11 @@ protected static Document getXMLDoc(final URL xmlFile) documentBuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder(); } - @SuppressWarnings("removal") - InputStream inputStream = - AccessController.doPrivileged(new PrivilegedAction<InputStream>() { - public InputStream run() { - try { - return new BufferedInputStream(xmlFile.openStream()); - } catch (IOException ex) { - return null; - } - } - }); - + InputStream inputStream = null; + try { + inputStream = new BufferedInputStream(xmlFile.openStream()); + } catch (IOException ex) { + } Document doc = null; if (inputStream != null) { doc = documentBuilder.parse(inputStream); diff --git a/src/java.desktop/share/classes/com/sun/media/sound/JARSoundbankReader.java b/src/java.desktop/share/classes/com/sun/media/sound/JARSoundbankReader.java index 6447e654f60..4ff72c7040a 100644 --- a/src/java.desktop/share/classes/com/sun/media/sound/JARSoundbankReader.java +++ b/src/java.desktop/share/classes/com/sun/media/sound/JARSoundbankReader.java @@ -32,7 +32,6 @@ import java.io.InputStreamReader; import java.net.URL; import java.net.URLClassLoader; -import java.security.AccessController; import java.util.ArrayList; import java.util.Objects; @@ -55,10 +54,7 @@ public final class JARSoundbankReader extends SoundbankReader { * {@code true} if jar sound bank is allowed to be loaded default is * {@code false}. */ - @SuppressWarnings("removal") - private static final boolean JAR_SOUNDBANK_ENABLED = - AccessController.doPrivileged( - new GetBooleanAction("jdk.sound.jarsoundbank")); + private static final boolean JAR_SOUNDBANK_ENABLED = Boolean.getBoolean("jdk.sound.jarsoundbank"); private static boolean isZIP(URL url) { boolean ok = false; diff --git a/src/java.desktop/share/classes/com/sun/media/sound/JDK13Services.java b/src/java.desktop/share/classes/com/sun/media/sound/JDK13Services.java index 0d8f34ca225..4ed79db13b5 100644 --- a/src/java.desktop/share/classes/com/sun/media/sound/JDK13Services.java +++ b/src/java.desktop/share/classes/com/sun/media/sound/JDK13Services.java @@ -25,8 +25,6 @@ package com.sun.media.sound; -import java.security.AccessController; -import java.security.PrivilegedAction; import java.util.ArrayList; import java.util.Collections; import java.util.List; @@ -170,9 +168,7 @@ private static synchronized String getDefaultProvider(Class<?> typeClass) { return null; } String name = typeClass.getName(); - @SuppressWarnings("removal") - String value = AccessController.doPrivileged( - (PrivilegedAction<String>) () -> System.getProperty(name)); + String value = System.getProperty(name); if (value == null) { value = getProperties().getProperty(name); } diff --git a/src/java.desktop/share/classes/com/sun/media/sound/JSSecurityManager.java b/src/java.desktop/share/classes/com/sun/media/sound/JSSecurityManager.java index 51482b24aea..e9b99ac1a10 100644 --- a/src/java.desktop/share/classes/com/sun/media/sound/JSSecurityManager.java +++ b/src/java.desktop/share/classes/com/sun/media/sound/JSSecurityManager.java @@ -29,8 +29,6 @@ import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; -import java.security.AccessController; -import java.security.PrivilegedAction; import java.util.ArrayList; import java.util.Iterator; import java.util.List; @@ -41,7 +39,7 @@ /** Managing security in the Java Sound implementation. * This class contains all code that uses and is used by - * SecurityManager.doPrivileged(). + * SecurityManager * * @author Matthias Pfisterer */ @@ -74,24 +72,18 @@ static void checkRecordPermission() throws SecurityException { * @param properties the properties bundle to store the values of the * properties file */ - @SuppressWarnings("removal") static void loadProperties(final Properties properties) { - final String customFile = AccessController.doPrivileged( - (PrivilegedAction<String>) () -> System.getProperty( - "javax.sound.config.file")); + final String customFile = System.getProperty("javax.sound.config.file"); if (customFile != null) { if (loadPropertiesImpl(properties, customFile)) { return; } } - AccessController.doPrivileged((PrivilegedAction<Void>) () -> { - final String home = System.getProperty("java.home"); - if (home == null) { - throw new Error("Can't find java.home ??"); - } - loadPropertiesImpl(properties, home, "conf", "sound.properties"); - return null; - }); + final String home = System.getProperty("java.home"); + if (home == null) { + throw new Error("Can't find java.home ??"); + } + loadPropertiesImpl(properties, home, "conf", "sound.properties"); } private static boolean loadPropertiesImpl(final Properties properties, @@ -124,32 +116,11 @@ static Thread createThread(final Runnable runnable, return thread; } - @SuppressWarnings("removal") static synchronized <T> List<T> getProviders(final Class<T> providerClass) { List<T> p = new ArrayList<>(7); - // ServiceLoader creates "lazy" iterator instance, but it ensures that - // next/hasNext run with permissions that are restricted by whatever - // creates the ServiceLoader instance, so it requires to be called from - // privileged section - final PrivilegedAction<Iterator<T>> psAction = - new PrivilegedAction<Iterator<T>>() { - @Override - public Iterator<T> run() { - return ServiceLoader.load(providerClass).iterator(); - } - }; - final Iterator<T> ps = AccessController.doPrivileged(psAction); - - // the iterator's hasNext() method looks through classpath for - // the provider class names, so it requires read permissions - PrivilegedAction<Boolean> hasNextAction = new PrivilegedAction<Boolean>() { - @Override - public Boolean run() { - return ps.hasNext(); - } - }; + final Iterator<T> ps = ServiceLoader.load(providerClass).iterator(); - while (AccessController.doPrivileged(hasNextAction)) { + while (ps.hasNext()) { try { // the iterator's next() method creates instances of the // providers and it should be called in the current security diff --git a/src/java.desktop/share/classes/com/sun/media/sound/Platform.java b/src/java.desktop/share/classes/com/sun/media/sound/Platform.java index 727718c6ca9..ded8a6496f5 100644 --- a/src/java.desktop/share/classes/com/sun/media/sound/Platform.java +++ b/src/java.desktop/share/classes/com/sun/media/sound/Platform.java @@ -25,8 +25,6 @@ package com.sun.media.sound; -import java.security.AccessController; -import java.security.PrivilegedAction; import java.util.StringTokenizer; /** @@ -74,15 +72,12 @@ static boolean isBigEndian() { /** * Load the native library or libraries. */ - @SuppressWarnings({"removal", "restricted"}) + @SuppressWarnings("restricted") private static void loadLibraries() { // load the native library isNativeLibLoaded = true; try { - AccessController.doPrivileged((PrivilegedAction<Void>) () -> { - System.loadLibrary(libName); - return null; - }); + System.loadLibrary(libName); } catch (Throwable t) { if (Printer.err) Printer.err("Couldn't load library "+libName+": "+t.toString()); isNativeLibLoaded = false; diff --git a/src/java.desktop/share/classes/com/sun/media/sound/Printer.java b/src/java.desktop/share/classes/com/sun/media/sound/Printer.java index c67ca92f574..40e179b1bd8 100644 --- a/src/java.desktop/share/classes/com/sun/media/sound/Printer.java +++ b/src/java.desktop/share/classes/com/sun/media/sound/Printer.java @@ -25,7 +25,6 @@ package com.sun.media.sound; -import java.security.AccessController; import sun.security.action.GetPropertyAction; @@ -66,9 +65,7 @@ public static void err(String str) { * Returns {@code true} if the build of the current jdk is "internal". */ private static boolean isBuildInternal() { - @SuppressWarnings("removal") - String javaVersion = AccessController.doPrivileged( - new GetPropertyAction("java.version")); + String javaVersion = System.getProperty("java.version"); return javaVersion != null && javaVersion.contains("internal"); } diff --git a/src/java.desktop/share/classes/com/sun/media/sound/SoftSynthesizer.java b/src/java.desktop/share/classes/com/sun/media/sound/SoftSynthesizer.java index e951a6a6578..4c33416e470 100644 --- a/src/java.desktop/share/classes/com/sun/media/sound/SoftSynthesizer.java +++ b/src/java.desktop/share/classes/com/sun/media/sound/SoftSynthesizer.java @@ -36,8 +36,6 @@ import java.io.InputStream; import java.io.OutputStream; import java.lang.ref.WeakReference; -import java.security.AccessController; -import java.security.PrivilegedAction; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; @@ -634,15 +632,19 @@ public boolean remapInstrument(Instrument from, Instrument to) { } } + static interface RunnableAction<T> { + T run(); + } + @Override public Soundbank getDefaultSoundbank() { synchronized (SoftSynthesizer.class) { if (defaultSoundBank != null) return defaultSoundBank; - List<PrivilegedAction<InputStream>> actions = new ArrayList<>(); + List<RunnableAction<InputStream>> actions = new ArrayList<>(); - actions.add(new PrivilegedAction<InputStream>() { + actions.add(new RunnableAction<InputStream>() { @Override public InputStream run() { File javahome = new File(System.getProperties() @@ -678,7 +680,7 @@ public InputStream run() { } }); - actions.add(new PrivilegedAction<InputStream>() { + actions.add(new RunnableAction<InputStream>() { @Override public InputStream run() { if (OSInfo.getOSType() == OSInfo.OSType.LINUX) { @@ -712,7 +714,7 @@ public InputStream run() { } }); - actions.add(new PrivilegedAction<InputStream>() { + actions.add(new RunnableAction<InputStream>() { @Override public InputStream run() { if (OSInfo.getOSType() == OSInfo.OSType.WINDOWS) { @@ -729,7 +731,7 @@ public InputStream run() { } }); - actions.add(new PrivilegedAction<InputStream>() { + actions.add(new RunnableAction<InputStream>() { @Override public InputStream run() { /* @@ -749,10 +751,9 @@ public InputStream run() { } }); - for (PrivilegedAction<InputStream> action : actions) { + for (RunnableAction<InputStream> action : actions) { try { - @SuppressWarnings("removal") - InputStream is = AccessController.doPrivileged(action); + InputStream is = action.run(); if(is == null) continue; Soundbank sbk; try (is) { @@ -778,9 +779,8 @@ public InputStream run() { /* * Save generated soundbank to disk for faster future use. */ - @SuppressWarnings("removal") - OutputStream out = AccessController - .doPrivileged((PrivilegedAction<OutputStream>) () -> { + OutputStream out = + ((RunnableAction<OutputStream>) () -> { try { File userhome = new File(System .getProperty("user.home"), ".gervill"); @@ -798,7 +798,7 @@ public InputStream run() { } catch (final FileNotFoundException ignored) { } return null; - }); + }).run(); if (out != null) { try (out) { ((SF2Soundbank) defaultSoundBank).save(out); @@ -897,28 +897,24 @@ public MidiDevice.Info getDeviceInfo() { return info; } - @SuppressWarnings("removal") private Properties getStoredProperties() { - return AccessController - .doPrivileged((PrivilegedAction<Properties>) () -> { - Properties p = new Properties(); - String notePath = "/com/sun/media/sound/softsynthesizer"; - try { - Preferences prefroot = Preferences.userRoot(); - if (prefroot.nodeExists(notePath)) { - Preferences prefs = prefroot.node(notePath); - String[] prefs_keys = prefs.keys(); - for (String prefs_key : prefs_keys) { - String val = prefs.get(prefs_key, null); - if (val != null) { - p.setProperty(prefs_key, val); - } - } - } - } catch (final BackingStoreException ignored) { + Properties p = new Properties(); + String notePath = "/com/sun/media/sound/softsynthesizer"; + try { + Preferences prefroot = Preferences.userRoot(); + if (prefroot.nodeExists(notePath)) { + Preferences prefs = prefroot.node(notePath); + String[] prefs_keys = prefs.keys(); + for (String prefs_key : prefs_keys) { + String val = prefs.get(prefs_key, null); + if (val != null) { + p.setProperty(prefs_key, val); } - return p; - }); + } + } + } catch (final BackingStoreException ignored) { + } + return p; } @Override diff --git a/src/java.desktop/share/classes/javax/imageio/ImageIO.java b/src/java.desktop/share/classes/javax/imageio/ImageIO.java index b11641c82ca..316a74a22ea 100644 --- a/src/java.desktop/share/classes/javax/imageio/ImageIO.java +++ b/src/java.desktop/share/classes/javax/imageio/ImageIO.java @@ -165,10 +165,8 @@ private static synchronized CacheInfo getCacheInfo() { * Returns the default temporary (cache) directory as defined by the * java.io.tmpdir system property. */ - @SuppressWarnings("removal") private static String getTempDir() { - GetPropertyAction a = new GetPropertyAction("java.io.tmpdir"); - return AccessController.doPrivileged(a); + return System.getProperty("java.io.tmpdir"); } /** diff --git a/src/java.desktop/share/classes/javax/imageio/metadata/IIOMetadata.java b/src/java.desktop/share/classes/javax/imageio/metadata/IIOMetadata.java index 3954f886f47..b94d6a85a02 100644 --- a/src/java.desktop/share/classes/javax/imageio/metadata/IIOMetadata.java +++ b/src/java.desktop/share/classes/javax/imageio/metadata/IIOMetadata.java @@ -28,8 +28,6 @@ import org.w3c.dom.Node; import java.lang.reflect.Method; -import java.security.AccessController; -import java.security.PrivilegedAction; /** * An abstract class to be extended by objects that represent metadata @@ -398,12 +396,9 @@ public IIOMetadataFormat getMetadataFormat(String formatName) { throw new IllegalArgumentException("Unsupported format name"); } try { - final String className = formatClassName; // Try to load from the module of the IIOMetadata implementation // for this plugin since the IIOMetadataImpl is part of the plugin - PrivilegedAction<Class<?>> pa = () -> { return getMetadataFormatClass(className); }; - @SuppressWarnings("removal") - Class<?> cls = AccessController.doPrivileged(pa); + Class<?> cls = getMetadataFormatClass(formatClassName); Method meth = cls.getMethod("getInstance"); return (IIOMetadataFormat) meth.invoke(null); } catch (Exception e) { diff --git a/src/java.desktop/share/classes/javax/imageio/spi/IIORegistry.java b/src/java.desktop/share/classes/javax/imageio/spi/IIORegistry.java index b80e6370293..1ea7146ae4a 100644 --- a/src/java.desktop/share/classes/javax/imageio/spi/IIORegistry.java +++ b/src/java.desktop/share/classes/javax/imageio/spi/IIORegistry.java @@ -25,8 +25,6 @@ package javax.imageio.spi; -import java.security.PrivilegedAction; -import java.security.AccessController; import java.util.Iterator; import com.sun.imageio.spi.FileImageInputStreamSpi; import com.sun.imageio.spi.FileImageOutputStreamSpi; @@ -197,30 +195,14 @@ public void registerApplicationClasspathSpis() { } } - @SuppressWarnings("removal") private void registerInstalledProviders() { - /* - We need to load installed providers - in the privileged mode in order to - be able read corresponding jar files even if - file read capability is restricted (like the - applet context case). - */ - PrivilegedAction<Object> doRegistration = - new PrivilegedAction<Object>() { - public Object run() { - Iterator<Class<?>> categories = getCategories(); - while (categories.hasNext()) { - @SuppressWarnings("unchecked") - Class<IIOServiceProvider> c = (Class<IIOServiceProvider>)categories.next(); - for (IIOServiceProvider p : ServiceLoader.loadInstalled(c)) { - registerServiceProvider(p); - } - } - return this; - } - }; - - AccessController.doPrivileged(doRegistration); + Iterator<Class<?>> categories = getCategories(); + while (categories.hasNext()) { + @SuppressWarnings("unchecked") + Class<IIOServiceProvider> c = (Class<IIOServiceProvider>)categories.next(); + for (IIOServiceProvider p : ServiceLoader.loadInstalled(c)) { + registerServiceProvider(p); + } + } } } diff --git a/src/java.desktop/share/classes/javax/imageio/spi/ImageReaderWriterSpi.java b/src/java.desktop/share/classes/javax/imageio/spi/ImageReaderWriterSpi.java index 7abefdd9431..f74415a8a38 100644 --- a/src/java.desktop/share/classes/javax/imageio/spi/ImageReaderWriterSpi.java +++ b/src/java.desktop/share/classes/javax/imageio/spi/ImageReaderWriterSpi.java @@ -26,8 +26,6 @@ package javax.imageio.spi; import java.lang.reflect.Method; -import java.security.AccessController; -import java.security.PrivilegedAction; import javax.imageio.metadata.IIOMetadata; import javax.imageio.metadata.IIOMetadataFormat; import javax.imageio.metadata.IIOMetadataFormatImpl; @@ -584,10 +582,7 @@ private IIOMetadataFormat getMetadataFormat(String formatName, } try { // Try to load from the same location as the module of the SPI - final String className = formatClassName; - PrivilegedAction<Class<?>> pa = () -> { return getMetadataFormatClass(className); }; - @SuppressWarnings("removal") - Class<?> cls = AccessController.doPrivileged(pa); + Class<?> cls = getMetadataFormatClass(formatClassName); Method meth = cls.getMethod("getInstance"); return (IIOMetadataFormat) meth.invoke(null); } catch (Exception e) { diff --git a/src/java.desktop/share/classes/javax/imageio/spi/ServiceRegistry.java b/src/java.desktop/share/classes/javax/imageio/spi/ServiceRegistry.java index 3e0bc06b361..0ba532b0b83 100644 --- a/src/java.desktop/share/classes/javax/imageio/spi/ServiceRegistry.java +++ b/src/java.desktop/share/classes/javax/imageio/spi/ServiceRegistry.java @@ -25,9 +25,6 @@ package javax.imageio.spi; -import java.security.AccessControlContext; -import java.security.AccessController; -import java.security.PrivilegedAction; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; @@ -731,8 +728,6 @@ class SubRegistry { // No way to express heterogeneous map, we want // Map<Class<T>, T>, where T is ? final Map<Class<?>, Object> map = new HashMap<>(); - @SuppressWarnings("removal") - final Map<Class<?>, AccessControlContext> accMap = new HashMap<>(); public SubRegistry(ServiceRegistry registry, Class<?> category) { this.registry = registry; @@ -748,7 +743,6 @@ public synchronized boolean registerServiceProvider(Object provider) { deregisterServiceProvider(oprovider); } map.put(provider.getClass(), provider); - accMap.put(provider.getClass(), AccessController.getContext()); poset.add(provider); if (provider instanceof RegisterableService) { RegisterableService rs = (RegisterableService)provider; @@ -773,7 +767,6 @@ public synchronized boolean deregisterServiceProvider(Object provider) { if (provider == oprovider) { map.remove(provider.getClass()); - accMap.remove(provider.getClass()); poset.remove(provider); if (provider instanceof RegisterableService) { RegisterableService rs = (RegisterableService)provider; @@ -815,26 +808,17 @@ public synchronized boolean unsetOrdering(Object firstProvider, return (T)map.get(providerClass); } - @SuppressWarnings("removal") public synchronized void clear() { Iterator<Object> iter = map.values().iterator(); while (iter.hasNext()) { Object provider = iter.next(); iter.remove(); - if (provider instanceof RegisterableService) { - RegisterableService rs = (RegisterableService)provider; - AccessControlContext acc = accMap.get(provider.getClass()); - if (acc != null || System.getSecurityManager() == null) { - AccessController.doPrivileged((PrivilegedAction<Void>) () -> { - rs.onDeregistration(registry, category); - return null; - }, acc); - } + if (provider instanceof RegisterableService rs) { + rs.onDeregistration(registry, category); } } poset.clear(); - accMap.clear(); } @SuppressWarnings("removal") diff --git a/src/java.desktop/share/classes/javax/print/DocFlavor.java b/src/java.desktop/share/classes/javax/print/DocFlavor.java index 448cc78d9e1..9db970cc779 100644 --- a/src/java.desktop/share/classes/javax/print/DocFlavor.java +++ b/src/java.desktop/share/classes/javax/print/DocFlavor.java @@ -410,10 +410,7 @@ public class DocFlavor implements Serializable, Cloneable { * @spec https://www.rfc-editor.org/info/rfc2278 * RFC 2278: IANA Charset Registration Procedures */ - @SuppressWarnings("removal") - public static final String hostEncoding = - java.security.AccessController.doPrivileged( - new sun.security.action.GetPropertyAction("file.encoding")); + public static final String hostEncoding = System.getProperty("file.encoding"); /** * MIME type. diff --git a/src/java.desktop/share/classes/javax/print/PrintServiceLookup.java b/src/java.desktop/share/classes/javax/print/PrintServiceLookup.java index 2931a1cbae0..29c7b420f7c 100644 --- a/src/java.desktop/share/classes/javax/print/PrintServiceLookup.java +++ b/src/java.desktop/share/classes/javax/print/PrintServiceLookup.java @@ -335,7 +335,6 @@ public abstract PrintService[] getPrintServices(DocFlavor flavor, * * @return all lookup services for this environment */ - @SuppressWarnings("removal") private static ArrayList<PrintServiceLookup> getAllLookupServices() { synchronized (PrintServiceLookup.class) { ArrayList<PrintServiceLookup> listOfLookupServices = getListOfLookupServices(); @@ -344,32 +343,11 @@ private static ArrayList<PrintServiceLookup> getAllLookupServices() { } else { listOfLookupServices = initListOfLookupServices(); } - try { - java.security.AccessController.doPrivileged( - new java.security.PrivilegedExceptionAction<Object>() { - public Object run() { - Iterator<PrintServiceLookup> iterator = - ServiceLoader.load(PrintServiceLookup.class). - iterator(); - ArrayList<PrintServiceLookup> los = getListOfLookupServices(); - while (iterator.hasNext()) { - try { - los.add(iterator.next()); - } catch (ServiceConfigurationError err) { - /* In the applet case, we continue */ - if (System.getSecurityManager() != null) { - err.printStackTrace(); - } else { - throw err; - } - } - } - return null; - } - }); - } catch (java.security.PrivilegedActionException e) { + Iterator<PrintServiceLookup> iterator = ServiceLoader.load(PrintServiceLookup.class).iterator(); + ArrayList<PrintServiceLookup> los = getListOfLookupServices(); + while (iterator.hasNext()) { + los.add(iterator.next()); } - return listOfLookupServices; } } diff --git a/src/java.desktop/share/classes/javax/print/StreamPrintServiceFactory.java b/src/java.desktop/share/classes/javax/print/StreamPrintServiceFactory.java index 29033cb7147..5247d4ef861 100644 --- a/src/java.desktop/share/classes/javax/print/StreamPrintServiceFactory.java +++ b/src/java.desktop/share/classes/javax/print/StreamPrintServiceFactory.java @@ -183,43 +183,23 @@ private static ArrayList<StreamPrintServiceFactory> initListOfFactories() { * * @return all factories */ - @SuppressWarnings("removal") private static ArrayList<StreamPrintServiceFactory> getAllFactories() { synchronized (StreamPrintServiceFactory.class) { - ArrayList<StreamPrintServiceFactory> listOfFactories = getListOfFactories(); - if (listOfFactories != null) { - return listOfFactories; - } else { - listOfFactories = initListOfFactories(); - } + ArrayList<StreamPrintServiceFactory> listOfFactories = getListOfFactories(); + if (listOfFactories != null) { + return listOfFactories; + } else { + listOfFactories = initListOfFactories(); + } - try { - java.security.AccessController.doPrivileged( - new java.security.PrivilegedExceptionAction<Object>() { - public Object run() { - Iterator<StreamPrintServiceFactory> iterator = - ServiceLoader.load - (StreamPrintServiceFactory.class).iterator(); - ArrayList<StreamPrintServiceFactory> lof = getListOfFactories(); - while (iterator.hasNext()) { - try { - lof.add(iterator.next()); - } catch (ServiceConfigurationError err) { - /* In the applet case, we continue */ - if (System.getSecurityManager() != null) { - err.printStackTrace(); - } else { - throw err; - } - } - } - return null; - } - }); - } catch (java.security.PrivilegedActionException e) { - } - return listOfFactories; + Iterator<StreamPrintServiceFactory> iterator = + ServiceLoader.load(StreamPrintServiceFactory.class).iterator(); + ArrayList<StreamPrintServiceFactory> lof = getListOfFactories(); + while (iterator.hasNext()) { + lof.add(iterator.next()); + } + return listOfFactories; } } From da2d7a09f92df547661587348f768f69f0e5a23b Mon Sep 17 00:00:00 2001 From: "Dr Heinz M. Kabutz" <heinz@javaspecialists.eu> Date: Wed, 20 Nov 2024 20:01:37 +0000 Subject: [PATCH 139/311] 8344595: State transitions in internal VirtualThread comment needs to be updated Reviewed-by: alanb --- .../share/classes/java/lang/VirtualThread.java | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/java.base/share/classes/java/lang/VirtualThread.java b/src/java.base/share/classes/java/lang/VirtualThread.java index 1bf4367bed4..1f8e1941c1d 100644 --- a/src/java.base/share/classes/java/lang/VirtualThread.java +++ b/src/java.base/share/classes/java/lang/VirtualThread.java @@ -108,14 +108,14 @@ final class VirtualThread extends BaseVirtualThread { * UNBLOCKED -> RUNNING // continue execution after blocked on monitor enter * * RUNNING -> WAITING // transitional state during wait on monitor - * WAITING -> WAITED // waiting on monitor - * WAITED -> BLOCKED // notified, waiting to be unblocked by monitor owner - * WAITED -> UNBLOCKED // timed-out/interrupted + * WAITING -> WAIT // waiting on monitor + * WAIT -> BLOCKED // notified, waiting to be unblocked by monitor owner + * WAIT -> UNBLOCKED // timed-out/interrupted * * RUNNING -> TIMED_WAITING // transition state during timed-waiting on monitor - * TIMED_WAITING -> TIMED_WAITED // timed-waiting on monitor - * TIMED_WAITED -> BLOCKED // notified, waiting to be unblocked by monitor owner - * TIMED_WAITED -> UNBLOCKED // timed-out/interrupted + * TIMED_WAITING -> TIMED_WAIT // timed-waiting on monitor + * TIMED_WAIT -> BLOCKED // notified, waiting to be unblocked by monitor owner + * TIMED_WAIT -> UNBLOCKED // timed-out/interrupted * * RUNNING -> YIELDING // Thread.yield * YIELDING -> YIELDED // cont.yield successful, may be scheduled to continue From b9bf447209db5d7f6bb16a0310421dbe4170500c Mon Sep 17 00:00:00 2001 From: Harshitha Onkar <honkar@openjdk.org> Date: Wed, 20 Nov 2024 20:28:12 +0000 Subject: [PATCH 140/311] 8344057: Remove doPrivileged calls from unix platform sources in the java.desktop module Reviewed-by: prr --- .../classes/sun/awt/PlatformGraphicsInfo.java | 32 ++- .../unix/classes/sun/awt/UNIXToolkit.java | 40 +--- .../unix/classes/sun/awt/X11/InfoWindow.java | 14 +- .../unix/classes/sun/awt/X11/Native.java | 10 +- .../unix/classes/sun/awt/X11/XClipboard.java | 8 +- .../classes/sun/awt/X11/XEmbedCanvasPeer.java | 6 +- .../sun/awt/X11/XErrorHandlerUtil.java | 6 +- .../classes/sun/awt/X11/XFileDialogPeer.java | 11 +- .../unix/classes/sun/awt/X11/XRobotPeer.java | 14 +- .../classes/sun/awt/X11/XTaskbarPeer.java | 12 +- .../unix/classes/sun/awt/X11/XToolkit.java | 83 +++----- .../classes/sun/awt/X11/XTrayIconPeer.java | 10 +- .../unix/classes/sun/awt/X11/XlibWrapper.java | 11 +- .../classes/sun/awt/X11GraphicsDevice.java | 31 ++- .../sun/awt/X11GraphicsEnvironment.java | 183 ++++++++---------- .../sun/awt/screencast/ScreencastHelper.java | 11 +- .../sun/awt/screencast/TokenStorage.java | 56 ++---- .../classes/sun/font/FcFontConfiguration.java | 5 - .../sun/java2d/x11/X11SurfaceData.java | 8 +- .../sun/java2d/xr/XRCompositeManager.java | 10 +- .../unix/classes/sun/print/CUPSPrinter.java | 49 ++--- .../classes/sun/print/IPPPrintService.java | 20 +- .../sun/print/PrintServiceLookupProvider.java | 112 +++++------ .../unix/classes/sun/print/UnixPrintJob.java | 15 +- .../classes/sun/print/UnixPrintService.java | 4 +- 25 files changed, 260 insertions(+), 501 deletions(-) diff --git a/src/java.desktop/unix/classes/sun/awt/PlatformGraphicsInfo.java b/src/java.desktop/unix/classes/sun/awt/PlatformGraphicsInfo.java index 6640042259e..9ab68a4ff44 100644 --- a/src/java.desktop/unix/classes/sun/awt/PlatformGraphicsInfo.java +++ b/src/java.desktop/unix/classes/sun/awt/PlatformGraphicsInfo.java @@ -28,8 +28,6 @@ import java.io.File; import java.awt.GraphicsEnvironment; import java.awt.Toolkit; -import java.security.AccessController; -import java.security.PrivilegedAction; public class PlatformGraphicsInfo { @@ -47,14 +45,10 @@ public static Toolkit createToolkit() { * headless mode, in the case the application did not specify * a value for the java.awt.headless system property. */ - @SuppressWarnings("removal") public static boolean getDefaultHeadlessProperty() { - boolean noDisplay = - AccessController.doPrivileged((PrivilegedAction<Boolean>) () -> { + final String display = System.getenv("DISPLAY"); + boolean noDisplay = (display == null || display.trim().isEmpty()); - final String display = System.getenv("DISPLAY"); - return display == null || display.trim().isEmpty(); - }); if (noDisplay) { return true; } @@ -67,18 +61,16 @@ public static boolean getDefaultHeadlessProperty() { * code is also set up as headless from the start - it is not so easy * to try headful and then unwind that and then retry as headless. */ - boolean headless = - AccessController.doPrivileged((PrivilegedAction<Boolean>) () -> { - String[] libDirs = System.getProperty("sun.boot.library.path", "").split(":"); - for (String libDir : libDirs) { - File headlessLib = new File(libDir, "libawt_headless.so"); - File xawtLib = new File(libDir, "libawt_xawt.so"); - if (headlessLib.exists() && !xawtLib.exists()) { - return true; - } - } - return false; - }); + boolean headless = false; + String[] libDirs = System.getProperty("sun.boot.library.path", "").split(":"); + for (String libDir : libDirs) { + File headlessLib = new File(libDir, "libawt_headless.so"); + File xawtLib = new File(libDir, "libawt_xawt.so"); + if (headlessLib.exists() && !xawtLib.exists()) { + headless = true; + break; + } + } return headless; } diff --git a/src/java.desktop/unix/classes/sun/awt/UNIXToolkit.java b/src/java.desktop/unix/classes/sun/awt/UNIXToolkit.java index d509fe802b0..8e224414427 100644 --- a/src/java.desktop/unix/classes/sun/awt/UNIXToolkit.java +++ b/src/java.desktop/unix/classes/sun/awt/UNIXToolkit.java @@ -105,9 +105,7 @@ public int getNumber() { private BufferedImage tmpImage = null; public static int getDatatransferTimeout() { - @SuppressWarnings("removal") - Integer dt = AccessController.doPrivileged( - new GetIntegerAction("sun.awt.datatransfer.timeout")); + Integer dt = Integer.getInteger("sun.awt.datatransfer.timeout"); if (dt == null || dt <= 0) { return DEFAULT_DATATRANSFER_TIMEOUT; } else { @@ -118,18 +116,12 @@ public static int getDatatransferTimeout() { @Override public String getDesktop() { String gnome = "gnome"; - @SuppressWarnings("removal") - String gsi = AccessController.doPrivileged( - (PrivilegedAction<String>) () - -> System.getenv("GNOME_DESKTOP_SESSION_ID")); + String gsi = System.getenv("GNOME_DESKTOP_SESSION_ID"); if (gsi != null) { return gnome; } - @SuppressWarnings("removal") - String desktop = AccessController.doPrivileged( - (PrivilegedAction<String>) () - -> System.getenv("XDG_CURRENT_DESKTOP")); + String desktop = System.getenv("XDG_CURRENT_DESKTOP"); return (desktop != null && desktop.toLowerCase().contains(gnome)) ? gnome : null; } @@ -252,11 +244,7 @@ public boolean shouldDisableSystemTray() { result = shouldDisableSystemTray; if (result == null) { if ("gnome".equals(getDesktop())) { - @SuppressWarnings("removal") - Integer gnomeShellMajorVersion = - AccessController - .doPrivileged((PrivilegedAction<Integer>) - this::getGnomeShellMajorVersion); + Integer gnomeShellMajorVersion = getGnomeShellMajorVersion(); if (gnomeShellMajorVersion == null || gnomeShellMajorVersion < 45) { @@ -486,9 +474,7 @@ public boolean checkGtkVersion(int major, int minor, int micro) { } public static GtkVersions getEnabledGtkVersion() { - @SuppressWarnings("removal") - String version = AccessController.doPrivileged( - new GetPropertyAction("jdk.gtk.version")); + String version = System.getProperty("jdk.gtk.version"); if ("3".equals(version)) { return GtkVersions.GTK3; } @@ -499,32 +485,22 @@ public static GtkVersions getGtkVersion() { return GtkVersions.getVersion(get_gtk_version()); } - @SuppressWarnings("removal") public static boolean isGtkVerbose() { - return AccessController.doPrivileged((PrivilegedAction<Boolean>)() - -> Boolean.getBoolean("jdk.gtk.verbose")); + return Boolean.getBoolean("jdk.gtk.verbose"); } private static volatile Boolean isOnWayland = null; - @SuppressWarnings("removal") public static boolean isOnWayland() { Boolean result = isOnWayland; if (result == null) { synchronized (GTK_LOCK) { result = isOnWayland; if (result == null) { + final String display = System.getenv("WAYLAND_DISPLAY"); isOnWayland = result - = AccessController.doPrivileged( - (PrivilegedAction<Boolean>) () -> { - final String display = - System.getenv("WAYLAND_DISPLAY"); - - return display != null - && !display.trim().isEmpty(); - } - ); + = (display != null && !display.trim().isEmpty()); } } } diff --git a/src/java.desktop/unix/classes/sun/awt/X11/InfoWindow.java b/src/java.desktop/unix/classes/sun/awt/X11/InfoWindow.java index d86d49290a4..641e2f86c02 100644 --- a/src/java.desktop/unix/classes/sun/awt/X11/InfoWindow.java +++ b/src/java.desktop/unix/classes/sun/awt/X11/InfoWindow.java @@ -47,8 +47,6 @@ import java.awt.event.ActionListener; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; -import java.security.AccessController; -import java.security.PrivilegedAction; import java.text.BreakIterator; import java.util.concurrent.ArrayBlockingQueue; @@ -227,16 +225,8 @@ public void run() { textLabel.setText(tooltipString); } - @SuppressWarnings("removal") - Point pointer = AccessController.doPrivileged( - new PrivilegedAction<Point>() { - public Point run() { - if (!isPointerOverTrayIcon(liveArguments.getBounds())) { - return null; - } - return MouseInfo.getPointerInfo().getLocation(); - } - }); + Point pointer = !isPointerOverTrayIcon(liveArguments.getBounds()) + ? null : MouseInfo.getPointerInfo().getLocation(); if (pointer == null) { return; } diff --git a/src/java.desktop/unix/classes/sun/awt/X11/Native.java b/src/java.desktop/unix/classes/sun/awt/X11/Native.java index 744e665baaa..773668ff53a 100644 --- a/src/java.desktop/unix/classes/sun/awt/X11/Native.java +++ b/src/java.desktop/unix/classes/sun/awt/X11/Native.java @@ -27,8 +27,6 @@ import jdk.internal.misc.Unsafe; import java.util.Vector; -import java.security.AccessController; -import java.security.PrivilegedAction; /** * This class contains the collection of utility functions to help work with @@ -43,13 +41,7 @@ class Native { static int dataModel; static { - @SuppressWarnings("removal") - String dataModelProp = AccessController.doPrivileged( - new PrivilegedAction<String>() { - public String run() { - return System.getProperty("sun.arch.data.model"); - } - }); + String dataModelProp = System.getProperty("sun.arch.data.model"); try { dataModel = Integer.parseInt(dataModelProp); } catch (Exception e) { diff --git a/src/java.desktop/unix/classes/sun/awt/X11/XClipboard.java b/src/java.desktop/unix/classes/sun/awt/X11/XClipboard.java index a12dddcb7df..3a36c3195a8 100644 --- a/src/java.desktop/unix/classes/sun/awt/X11/XClipboard.java +++ b/src/java.desktop/unix/classes/sun/awt/X11/XClipboard.java @@ -29,14 +29,12 @@ import java.awt.datatransfer.DataFlavor; import java.util.SortedMap; import java.io.IOException; -import java.security.AccessController; import java.util.HashMap; import java.util.Map; import sun.awt.UNIXToolkit; import sun.awt.datatransfer.DataTransferer; import sun.awt.datatransfer.SunClipboard; import sun.awt.datatransfer.ClipboardTransferable; -import sun.security.action.GetIntegerAction; /** * A class which interfaces with the X11 selection service in order to support @@ -129,13 +127,11 @@ private void checkChangeHere(Transferable contents) { } } - @SuppressWarnings("removal") private static int getPollInterval() { synchronized (XClipboard.classLock) { if (pollInterval <= 0) { - pollInterval = AccessController.doPrivileged( - new GetIntegerAction("awt.datatransfer.clipboard.poll.interval", - defaultPollInterval)); + pollInterval = Integer.getInteger("awt.datatransfer.clipboard.poll.interval" + , defaultPollInterval); if (pollInterval <= 0) { pollInterval = defaultPollInterval; } diff --git a/src/java.desktop/unix/classes/sun/awt/X11/XEmbedCanvasPeer.java b/src/java.desktop/unix/classes/sun/awt/X11/XEmbedCanvasPeer.java index 4317136816c..57e06cf94de 100644 --- a/src/java.desktop/unix/classes/sun/awt/X11/XEmbedCanvasPeer.java +++ b/src/java.desktop/unix/classes/sun/awt/X11/XEmbedCanvasPeer.java @@ -35,9 +35,6 @@ import java.util.*; import static sun.awt.X11.XEmbedHelper.*; -import java.security.AccessController; -import sun.security.action.GetBooleanAction; - public class XEmbedCanvasPeer extends XCanvasPeer implements WindowFocusListener, KeyEventPostProcessor, ModalityListener, WindowIDProvider { private static final PlatformLogger xembedLog = PlatformLogger.getLogger("sun.awt.X11.xembed.XEmbedCanvasPeer"); @@ -439,12 +436,11 @@ void canvasFocusGained(FocusEvent e) { } } - @SuppressWarnings("removal") void canvasFocusLost(FocusEvent e) { if (isXEmbedActive() && !e.isTemporary()) { xembedLog.fine("Forwarding FOCUS_LOST"); int num = 0; - if (AccessController.doPrivileged(new GetBooleanAction("sun.awt.xembed.testing"))) { + if (Boolean.getBoolean("sun.awt.xembed.testing")) { Component opp = e.getOppositeComponent(); try { num = Integer.parseInt(opp.getName()); diff --git a/src/java.desktop/unix/classes/sun/awt/X11/XErrorHandlerUtil.java b/src/java.desktop/unix/classes/sun/awt/X11/XErrorHandlerUtil.java index 9d43399e23c..1dfaa4b8d4d 100644 --- a/src/java.desktop/unix/classes/sun/awt/X11/XErrorHandlerUtil.java +++ b/src/java.desktop/unix/classes/sun/awt/X11/XErrorHandlerUtil.java @@ -24,9 +24,7 @@ */ package sun.awt.X11; -import java.security.AccessController; import sun.awt.SunToolkit; -import sun.security.action.GetBooleanAction; import sun.util.logging.PlatformLogger; /** @@ -59,9 +57,7 @@ public final class XErrorHandlerUtil { /** * Value of sun.awt.noisyerrorhandler system property. */ - @SuppressWarnings("removal") - private static boolean noisyAwtHandler = AccessController.doPrivileged( - new GetBooleanAction("sun.awt.noisyerrorhandler")); + private static boolean noisyAwtHandler = Boolean.getBoolean("sun.awt.noisyerrorhandler"); /** * The flag indicating that {@code init} was called already. diff --git a/src/java.desktop/unix/classes/sun/awt/X11/XFileDialogPeer.java b/src/java.desktop/unix/classes/sun/awt/X11/XFileDialogPeer.java index f11f11ba53e..596bc493f00 100644 --- a/src/java.desktop/unix/classes/sun/awt/X11/XFileDialogPeer.java +++ b/src/java.desktop/unix/classes/sun/awt/X11/XFileDialogPeer.java @@ -32,8 +32,6 @@ import java.io.*; import java.util.Locale; import java.util.Arrays; -import java.security.AccessController; -import java.security.PrivilegedAction; import sun.awt.AWTAccessor.ComponentAccessor; import sun.util.logging.PlatformLogger; @@ -139,7 +137,7 @@ void installStrings() { this.target = target; } - @SuppressWarnings({"removal","deprecation"}) + @SuppressWarnings("deprecation") private void init(FileDialog target) { fileDialog = target; //new Dialog(target, target.getTitle(), false); this.title = target.getTitle(); @@ -151,12 +149,7 @@ private void init(FileDialog target) { savedDir = target.getDirectory(); // Shouldn't save 'user.dir' to 'savedDir' // since getDirectory() will be incorrect after handleCancel - userDir = AccessController.doPrivileged( - new PrivilegedAction<String>() { - public String run() { - return System.getProperty("user.dir"); - } - }); + userDir = System.getProperty("user.dir"); installStrings(); gbl = new GridBagLayout(); diff --git a/src/java.desktop/unix/classes/sun/awt/X11/XRobotPeer.java b/src/java.desktop/unix/classes/sun/awt/X11/XRobotPeer.java index 6d155c0bcc8..010c5aeff5a 100644 --- a/src/java.desktop/unix/classes/sun/awt/X11/XRobotPeer.java +++ b/src/java.desktop/unix/classes/sun/awt/X11/XRobotPeer.java @@ -28,7 +28,6 @@ import java.awt.Rectangle; import java.awt.Toolkit; import java.awt.peer.RobotPeer; -import java.security.AccessController; import sun.awt.AWTAccessor; import sun.awt.SunToolkit; @@ -36,9 +35,7 @@ import sun.awt.X11GraphicsConfig; import sun.awt.X11GraphicsDevice; import sun.awt.screencast.ScreencastHelper; -import sun.security.action.GetPropertyAction; -@SuppressWarnings("removal") final class XRobotPeer implements RobotPeer { private static final boolean tryGtk; @@ -50,10 +47,8 @@ final class XRobotPeer implements RobotPeer { loadNativeLibraries(); tryGtk = Boolean.parseBoolean( - AccessController.doPrivileged( - new GetPropertyAction("awt.robot.gtk", - "true") - )); + System.getProperty("awt.robot.gtk", "true") + ); boolean isOnWayland = false; @@ -61,13 +56,12 @@ final class XRobotPeer implements RobotPeer { isOnWayland = sunToolkit.isRunningOnWayland(); } - screenshotMethod = AccessController.doPrivileged( - new GetPropertyAction( + screenshotMethod = System.getProperty( "awt.robot.screenshotMethod", isOnWayland ? METHOD_SCREENCAST : METHOD_X11 - )); + ); } private static volatile boolean useGtk; diff --git a/src/java.desktop/unix/classes/sun/awt/X11/XTaskbarPeer.java b/src/java.desktop/unix/classes/sun/awt/X11/XTaskbarPeer.java index 33bebe77de7..73668bf591c 100644 --- a/src/java.desktop/unix/classes/sun/awt/X11/XTaskbarPeer.java +++ b/src/java.desktop/unix/classes/sun/awt/X11/XTaskbarPeer.java @@ -31,9 +31,6 @@ import java.awt.event.ActionEvent; import sun.awt.UNIXToolkit; -import java.security.AccessController; -import java.security.PrivilegedAction; -import sun.security.action.GetPropertyAction; final class XTaskbarPeer implements TaskbarPeer { @@ -44,10 +41,7 @@ final class XTaskbarPeer implements TaskbarPeer { private static boolean isUnity; static { - @SuppressWarnings("removal") - String de = AccessController.doPrivileged( - (PrivilegedAction<String>) () - -> System.getenv("XDG_CURRENT_DESKTOP")); + String de = System.getenv("XDG_CURRENT_DESKTOP"); isUnity = "Unity".equals(de); } @@ -55,9 +49,7 @@ private static void initWithLock() { XToolkit.awtLock(); try { if (!initExecuted) { - @SuppressWarnings("removal") - String dname = AccessController.doPrivileged( - new GetPropertyAction("java.desktop.appName", "")); + String dname = System.getProperty("java.desktop.appName", ""); nativeLibraryLoaded = init(dname, UNIXToolkit.getEnabledGtkVersion().ordinal(), UNIXToolkit.isGtkVerbose()); diff --git a/src/java.desktop/unix/classes/sun/awt/X11/XToolkit.java b/src/java.desktop/unix/classes/sun/awt/X11/XToolkit.java index 1b4f45b55f1..920e1235fca 100644 --- a/src/java.desktop/unix/classes/sun/awt/X11/XToolkit.java +++ b/src/java.desktop/unix/classes/sun/awt/X11/XToolkit.java @@ -111,8 +111,6 @@ import java.awt.peer.TrayIconPeer; import java.awt.peer.WindowPeer; import java.beans.PropertyChangeListener; -import java.security.AccessController; -import java.security.PrivilegedAction; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; @@ -147,8 +145,6 @@ import sun.font.FontConfigManager; import sun.java2d.SunGraphicsEnvironment; import sun.print.PrintJob2D; -import sun.security.action.GetBooleanAction; -import sun.security.action.GetPropertyAction; import sun.util.logging.PlatformLogger; import static sun.awt.X11.XlibUtil.scaleDown; @@ -246,9 +242,7 @@ static boolean isToolkitThread() { static void initSecurityWarning() { // Enable warning only for internal builds - @SuppressWarnings("removal") - String runtime = AccessController.doPrivileged( - new GetPropertyAction("java.runtime.version")); + String runtime = System.getProperty("java.runtime.version"); securityWarningEnabled = (runtime != null && runtime.contains("internal")); } @@ -326,7 +320,6 @@ public static long getDefaultRootWindow() { } } - @SuppressWarnings("removal") void init() { awtLock(); try { @@ -339,13 +332,10 @@ void init() { arrowCursor = XlibWrapper.XCreateFontCursor(XToolkit.getDisplay(), XCursorFontConstants.XC_arrow); final String extraButtons = "sun.awt.enableExtraMouseButtons"; - AccessController.doPrivileged((PrivilegedAction<Void>) () -> { - areExtraMouseButtonsEnabled = - Boolean.parseBoolean(System.getProperty(extraButtons, "true")); - //set system property if not yet assigned - System.setProperty(extraButtons, ""+areExtraMouseButtonsEnabled); - return null; - }); + areExtraMouseButtonsEnabled = + Boolean.parseBoolean(System.getProperty(extraButtons, "true")); + //set system property if not yet assigned + System.setProperty(extraButtons, "" + areExtraMouseButtonsEnabled); // Detect display mode changes XlibWrapper.XSelectInput(XToolkit.getDisplay(), XToolkit.getDefaultRootWindow(), XConstants.StructureNotifyMask); XToolkit.addEventDispatcher(XToolkit.getDefaultRootWindow(), new XEventDispatcher() { @@ -370,28 +360,24 @@ public void dispatchEvent(XEvent ev) { } finally { awtUnlock(); } - PrivilegedAction<Void> a = () -> { - Runnable r = () -> { - XSystemTrayPeer peer = XSystemTrayPeer.getPeerInstance(); - if (peer != null) { - peer.dispose(); - } - if (xs != null) { - ((XAWTXSettings)xs).dispose(); - } - freeXKB(); - if (log.isLoggable(PlatformLogger.Level.FINE)) { - dumpPeers(); - } - }; - String name = "XToolkt-Shutdown-Thread"; - Thread shutdownThread = new Thread( - ThreadGroupUtils.getRootThreadGroup(), r, name, 0, false); - shutdownThread.setContextClassLoader(null); - Runtime.getRuntime().addShutdownHook(shutdownThread); - return null; + Runnable r = () -> { + XSystemTrayPeer peer = XSystemTrayPeer.getPeerInstance(); + if (peer != null) { + peer.dispose(); + } + if (xs != null) { + ((XAWTXSettings)xs).dispose(); + } + freeXKB(); + if (log.isLoggable(PlatformLogger.Level.FINE)) { + dumpPeers(); + } }; - AccessController.doPrivileged(a); + String name = "XToolkt-Shutdown-Thread"; + Thread shutdownThread = new Thread( + ThreadGroupUtils.getRootThreadGroup(), r, name, 0, false); + shutdownThread.setContextClassLoader(null); + Runtime.getRuntime().addShutdownHook(shutdownThread); } static String getCorrectXIDString(String val) { @@ -409,7 +395,6 @@ static String getAWTAppClassName() { return awtAppClassName; } - @SuppressWarnings("removal") public XToolkit() { super(); if (PerformanceLogger.loggingEnabled()) { @@ -432,16 +417,13 @@ public XToolkit() { init(); XWM.init(); - toolkitThread = AccessController.doPrivileged((PrivilegedAction<Thread>) () -> { - String name = "AWT-XAWT"; - Thread thread = new Thread( + String name = "AWT-XAWT"; + toolkitThread = new Thread( ThreadGroupUtils.getRootThreadGroup(), this, name, 0, false); - thread.setContextClassLoader(null); - thread.setPriority(Thread.NORM_PRIORITY + 1); - thread.setDaemon(true); - return thread; - }); + toolkitThread.setContextClassLoader(null); + toolkitThread.setPriority(Thread.NORM_PRIORITY + 1); + toolkitThread.setDaemon(true); toolkitThread.start(); } } @@ -1120,11 +1102,9 @@ public DialogPeer createDialog(Dialog target) { * Returns the value of "sun.awt.disableGtkFileDialogs" property. Default * value is {@code false}. */ - @SuppressWarnings("removal") public static synchronized boolean getSunAwtDisableGtkFileDialogs() { if (sunAwtDisableGtkFileDialogs == null) { - sunAwtDisableGtkFileDialogs = AccessController.doPrivileged( - new GetBooleanAction("sun.awt.disableGtkFileDialogs")); + sunAwtDisableGtkFileDialogs = Boolean.getBoolean("sun.awt.disableGtkFileDialogs"); } return sunAwtDisableGtkFileDialogs.booleanValue(); } @@ -2139,9 +2119,7 @@ static int getBackingStoreType() { } private static void setBackingStoreType() { - @SuppressWarnings("removal") - String prop = AccessController.doPrivileged( - new sun.security.action.GetPropertyAction("sun.awt.backingStore")); + String prop = System.getProperty("sun.awt.backingStore"); if (prop == null) { backingStoreType = XConstants.NotUseful; @@ -2565,8 +2543,7 @@ public boolean isTranslucencyCapable(GraphicsConfiguration gc) { * Returns the value of "sun.awt.disablegrab" property. Default * value is {@code false}. */ - @SuppressWarnings("removal") public static boolean getSunAwtDisableGrab() { - return AccessController.doPrivileged(new GetBooleanAction("sun.awt.disablegrab")); + return Boolean.getBoolean("sun.awt.disablegrab"); } } diff --git a/src/java.desktop/unix/classes/sun/awt/X11/XTrayIconPeer.java b/src/java.desktop/unix/classes/sun/awt/X11/XTrayIconPeer.java index a53dbebdd15..c3711010b7c 100644 --- a/src/java.desktop/unix/classes/sun/awt/X11/XTrayIconPeer.java +++ b/src/java.desktop/unix/classes/sun/awt/X11/XTrayIconPeer.java @@ -30,8 +30,6 @@ import java.awt.peer.TrayIconPeer; import sun.awt.*; import java.awt.image.*; -import java.security.AccessController; -import java.security.PrivilegedAction; import java.lang.reflect.InvocationTargetException; import sun.util.logging.PlatformLogger; @@ -66,7 +64,6 @@ public void dispatchEvent(XEvent ev) {} static final int TRAY_ICON_WIDTH = 24; static final int TRAY_ICON_HEIGHT = 24; - @SuppressWarnings("removal") XTrayIconPeer(TrayIcon target) throws AWTException { @@ -84,12 +81,7 @@ public void dispatchEvent(XEvent ev) {} // Fix for 6317038: as EmbeddedFrame is instance of Frame, it is blocked // by modal dialogs, but in the case of TrayIcon it shouldn't. So we // set ModalExclusion property on it. - AccessController.doPrivileged(new PrivilegedAction<Object>() { - public Object run() { - eframe.setModalExclusionType(Dialog.ModalExclusionType.TOOLKIT_EXCLUDE); - return null; - } - }); + eframe.setModalExclusionType(Dialog.ModalExclusionType.TOOLKIT_EXCLUDE); if (XWM.getWMID() != XWM.METACITY_WM) { diff --git a/src/java.desktop/unix/classes/sun/awt/X11/XlibWrapper.java b/src/java.desktop/unix/classes/sun/awt/X11/XlibWrapper.java index 7a23c806374..804107d9820 100644 --- a/src/java.desktop/unix/classes/sun/awt/X11/XlibWrapper.java +++ b/src/java.desktop/unix/classes/sun/awt/X11/XlibWrapper.java @@ -25,10 +25,7 @@ package sun.awt.X11; -import java.security.AccessController; - import jdk.internal.misc.Unsafe; -import sun.security.action.GetPropertyAction; final class XlibWrapper { @@ -585,9 +582,7 @@ static native void SetBitmapShape(long display, long window, static final boolean isBuildInternal; static { - @SuppressWarnings("removal") - String dataModelProp = AccessController.doPrivileged( - new GetPropertyAction("sun.arch.data.model")); + String dataModelProp = System.getProperty("sun.arch.data.model"); try { dataModel = Integer.parseInt(dataModelProp); } catch (Exception e) { @@ -639,9 +634,7 @@ static String getEventToString( int type ) { } private static boolean getBuildInternal() { - @SuppressWarnings("removal") - String javaVersion = AccessController.doPrivileged( - new GetPropertyAction("java.version")); + String javaVersion = System.getProperty("java.version"); return javaVersion != null && javaVersion.contains("internal"); } diff --git a/src/java.desktop/unix/classes/sun/awt/X11GraphicsDevice.java b/src/java.desktop/unix/classes/sun/awt/X11GraphicsDevice.java index 03f06408765..ca43142a098 100644 --- a/src/java.desktop/unix/classes/sun/awt/X11GraphicsDevice.java +++ b/src/java.desktop/unix/classes/sun/awt/X11GraphicsDevice.java @@ -33,8 +33,6 @@ import java.awt.Insets; import java.awt.Rectangle; import java.awt.Window; -import java.security.AccessController; -import java.security.PrivilegedAction; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; @@ -447,7 +445,6 @@ public synchronized DisplayMode[] getDisplayModes() { return modes.toArray(retArray); } - @SuppressWarnings("removal") @Override public synchronized void setDisplayMode(DisplayMode dm) { if (!isDisplayChangeSupported()) { @@ -474,24 +471,20 @@ public synchronized void setDisplayMode(DisplayMode dm) { // is already in the original DisplayMode at that time, this // hook will have no effect) shutdownHookRegistered = true; - PrivilegedAction<Void> a = () -> { - Runnable r = () -> { - Window old = getFullScreenWindow(); - if (old != null) { - exitFullScreenExclusive(old); - if (isDisplayChangeSupported()) { - setDisplayMode(origDisplayMode); - } + Runnable r = () -> { + Window old = getFullScreenWindow(); + if (old != null) { + exitFullScreenExclusive(old); + if (isDisplayChangeSupported()) { + setDisplayMode(origDisplayMode); } - }; - String name = "Display-Change-Shutdown-Thread-" + screen; - Thread t = new Thread( - ThreadGroupUtils.getRootThreadGroup(), r, name, 0, false); - t.setContextClassLoader(null); - Runtime.getRuntime().addShutdownHook(t); - return null; + } }; - AccessController.doPrivileged(a); + String name = "Display-Change-Shutdown-Thread-" + screen; + Thread t = new Thread( + ThreadGroupUtils.getRootThreadGroup(), r, name, 0, false); + t.setContextClassLoader(null); + Runtime.getRuntime().addShutdownHook(t); } // switch to the new DisplayMode diff --git a/src/java.desktop/unix/classes/sun/awt/X11GraphicsEnvironment.java b/src/java.desktop/unix/classes/sun/awt/X11GraphicsEnvironment.java index 42b20f66843..9d42e2c92da 100644 --- a/src/java.desktop/unix/classes/sun/awt/X11GraphicsEnvironment.java +++ b/src/java.desktop/unix/classes/sun/awt/X11GraphicsEnvironment.java @@ -59,78 +59,71 @@ public final class X11GraphicsEnvironment extends SunGraphicsEnvironment { initStatic(); } - @SuppressWarnings({"removal", "restricted"}) + @SuppressWarnings("restricted") private static void initStatic() { - java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction<Object>() { - public Object run() { - System.loadLibrary("awt"); - - /* - * Note: The XToolkit object depends on the static initializer - * of X11GraphicsEnvironment to initialize the connection to - * the X11 server. - */ - if (!isHeadless()) { - // first check the OGL system property - boolean glxRequested = false; - String prop = System.getProperty("sun.java2d.opengl"); - if (prop != null) { - if (prop.equals("true") || prop.equals("t")) { - glxRequested = true; - } else if (prop.equals("True") || prop.equals("T")) { - glxRequested = true; - glxVerbose = true; - } - } + System.loadLibrary("awt"); + + /* + * Note: The XToolkit object depends on the static initializer + * of X11GraphicsEnvironment to initialize the connection to + * the X11 server. + */ + if (!isHeadless()) { + // first check the OGL system property + boolean glxRequested = false; + String prop = System.getProperty("sun.java2d.opengl"); + if (prop != null) { + if (prop.equals("true") || prop.equals("t")) { + glxRequested = true; + } else if (prop.equals("True") || prop.equals("T")) { + glxRequested = true; + glxVerbose = true; + } + } - // Now check for XRender system property - boolean xRenderRequested = true; - boolean xRenderIgnoreLinuxVersion = false; - String xProp = System.getProperty("sun.java2d.xrender"); - if (xProp != null) { - if (xProp.equals("false") || xProp.equals("f")) { - xRenderRequested = false; - } else if (xProp.equals("True") || xProp.equals("T")) { - xRenderRequested = true; - xRenderVerbose = true; - } - - if(xProp.equalsIgnoreCase("t") || xProp.equalsIgnoreCase("true")) { - xRenderIgnoreLinuxVersion = true; - } - } + // Now check for XRender system property + boolean xRenderRequested = true; + boolean xRenderIgnoreLinuxVersion = false; + String xProp = System.getProperty("sun.java2d.xrender"); + if (xProp != null) { + if (xProp.equals("false") || xProp.equals("f")) { + xRenderRequested = false; + } else if (xProp.equals("True") || xProp.equals("T")) { + xRenderRequested = true; + xRenderVerbose = true; + } - // initialize the X11 display connection - initDisplay(glxRequested); - - // only attempt to initialize GLX if it was requested - if (glxRequested) { - glxAvailable = initGLX(); - if (glxVerbose && !glxAvailable) { - System.out.println( - "Could not enable OpenGL " + - "pipeline (GLX 1.3 not available)"); - } - } + if (xProp.equalsIgnoreCase("t") || xProp.equalsIgnoreCase("true")) { + xRenderIgnoreLinuxVersion = true; + } + } - // only attempt to initialize Xrender if it was requested - if (xRenderRequested) { - xRenderAvailable = initXRender(xRenderVerbose, xRenderIgnoreLinuxVersion); - if (xRenderVerbose && !xRenderAvailable) { - System.out.println( - "Could not enable XRender pipeline"); - } - } + // initialize the X11 display connection + initDisplay(glxRequested); - if (xRenderAvailable) { - XRSurfaceData.initXRSurfaceData(); - } + // only attempt to initialize GLX if it was requested + if (glxRequested) { + glxAvailable = initGLX(); + if (glxVerbose && !glxAvailable) { + System.out.println( + "Could not enable OpenGL " + + "pipeline (GLX 1.3 not available)"); + } + } + + // only attempt to initialize Xrender if it was requested + if (xRenderRequested) { + xRenderAvailable = initXRender(xRenderVerbose, xRenderIgnoreLinuxVersion); + if (xRenderVerbose && !xRenderAvailable) { + System.out.println( + "Could not enable XRender pipeline"); } + } - return null; + if (xRenderAvailable) { + XRSurfaceData.initXRSurfaceData(); } - }); + } // Install the correct surface manager factory. SurfaceManagerFactory.setInstance(new UnixSurfaceManagerFactory()); @@ -299,9 +292,7 @@ private static boolean _isDisplayLocal() { return true; } - @SuppressWarnings("removal") - String isRemote = java.security.AccessController.doPrivileged( - new sun.security.action.GetPropertyAction("sun.java2d.remote")); + String isRemote = System.getProperty("sun.java2d.remote"); if (isRemote != null) { return isRemote.equals("false"); } @@ -322,41 +313,35 @@ private static boolean _isDisplayLocal() { return true; } - @SuppressWarnings("removal") - Boolean result = java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction<Boolean>() { - public Boolean run() { - InetAddress[] remAddr = null; - Enumeration<InetAddress> locals = null; - Enumeration<NetworkInterface> interfaces = null; - try { - interfaces = NetworkInterface.getNetworkInterfaces(); - remAddr = InetAddress.getAllByName(hostName); - if (remAddr == null) { - return Boolean.FALSE; - } - } catch (UnknownHostException e) { - System.err.println("Unknown host: " + hostName); - return Boolean.FALSE; - } catch (SocketException e1) { - System.err.println(e1.getMessage()); - return Boolean.FALSE; - } + InetAddress[] remAddr = null; + Enumeration<InetAddress> locals = null; + Enumeration<NetworkInterface> interfaces = null; + try { + interfaces = NetworkInterface.getNetworkInterfaces(); + remAddr = InetAddress.getAllByName(hostName); + if (remAddr == null) { + return false; + } + } catch (UnknownHostException e) { + System.err.println("Unknown host: " + hostName); + return false; + } catch (SocketException e1) { + System.err.println(e1.getMessage()); + return false; + } - for (; interfaces.hasMoreElements();) { - locals = interfaces.nextElement().getInetAddresses(); - for (; locals.hasMoreElements();) { - final InetAddress localAddr = locals.nextElement(); - for (int i = 0; i < remAddr.length; i++) { - if (localAddr.equals(remAddr[i])) { - return Boolean.TRUE; - } - } + for (; interfaces.hasMoreElements();) { + locals = interfaces.nextElement().getInetAddresses(); + for (; locals.hasMoreElements();) { + final InetAddress localAddr = locals.nextElement(); + for (int i = 0; i < remAddr.length; i++) { + if (localAddr.equals(remAddr[i])) { + return true; } } - return Boolean.FALSE; - }}); - return result.booleanValue(); + } + } + return false; } diff --git a/src/java.desktop/unix/classes/sun/awt/screencast/ScreencastHelper.java b/src/java.desktop/unix/classes/sun/awt/screencast/ScreencastHelper.java index 78661587554..8f276954d6d 100644 --- a/src/java.desktop/unix/classes/sun/awt/screencast/ScreencastHelper.java +++ b/src/java.desktop/unix/classes/sun/awt/screencast/ScreencastHelper.java @@ -27,14 +27,12 @@ import sun.awt.UNIXToolkit; import sun.java2d.pipe.Region; -import sun.security.action.GetPropertyAction; import java.awt.GraphicsConfiguration; import java.awt.GraphicsEnvironment; import java.awt.Rectangle; import java.awt.Toolkit; import java.awt.geom.AffineTransform; -import java.security.AccessController; import java.util.Arrays; import java.util.List; import java.util.Set; @@ -48,7 +46,6 @@ * org.freedesktop.portal.ScreenCast API</a> */ -@SuppressWarnings("removal") public class ScreencastHelper { static final boolean SCREENCAST_DEBUG; @@ -70,13 +67,7 @@ private ScreencastHelper() { } static { - SCREENCAST_DEBUG = Boolean.parseBoolean( - AccessController.doPrivileged( - new GetPropertyAction( - "awt.robot.screenshotDebug", - "false" - ) - )); + SCREENCAST_DEBUG = Boolean.getBoolean("awt.robot.screenshotDebug"); boolean loadFailed = false; diff --git a/src/java.desktop/unix/classes/sun/awt/screencast/TokenStorage.java b/src/java.desktop/unix/classes/sun/awt/screencast/TokenStorage.java index b05ff7f8c4a..0db18c9c3b7 100644 --- a/src/java.desktop/unix/classes/sun/awt/screencast/TokenStorage.java +++ b/src/java.desktop/unix/classes/sun/awt/screencast/TokenStorage.java @@ -37,8 +37,6 @@ import java.nio.file.WatchKey; import java.nio.file.WatchService; import java.nio.file.attribute.PosixFilePermission; -import java.security.AccessController; -import java.security.PrivilegedAction; import java.util.Arrays; import java.util.HashSet; import java.util.LinkedHashSet; @@ -73,18 +71,8 @@ private TokenStorage() {} private static final Path PROPS_PATH; private static final Path PROP_FILENAME; - @SuppressWarnings("removal") - private static void doPrivilegedRunnable(Runnable runnable) { - AccessController.doPrivileged((PrivilegedAction<Void>) () -> { - runnable.run(); - return null; - }); - } - static { - @SuppressWarnings("removal") - Path propsPath = AccessController - .doPrivileged((PrivilegedAction<Path>) () -> setupPath()); + Path propsPath = setupPath(); PROPS_PATH = propsPath; @@ -226,9 +214,9 @@ public void run() { } if (kind == ENTRY_CREATE) { - doPrivilegedRunnable(() -> setFilePermission(PROPS_PATH)); + setFilePermission(PROPS_PATH); } else if (kind == ENTRY_MODIFY) { - doPrivilegedRunnable(() -> readTokens(PROPS_PATH)); + readTokens(PROPS_PATH); } else if (kind == ENTRY_DELETE) { synchronized (PROPS) { PROPS.clear(); @@ -244,25 +232,23 @@ public void run() { private static WatchService watchService; private static void setupWatch() { - doPrivilegedRunnable(() -> { - try { - watchService = - FileSystems.getDefault().newWatchService(); - - PROPS_PATH - .getParent() - .register(watchService, - ENTRY_CREATE, - ENTRY_DELETE, - ENTRY_MODIFY); - - } catch (Exception e) { - if (SCREENCAST_DEBUG) { - System.err.printf("Token storage: failed to setup " + - "file watch %s\n", e); - } + try { + watchService = + FileSystems.getDefault().newWatchService(); + + PROPS_PATH + .getParent() + .register(watchService, + ENTRY_CREATE, + ENTRY_DELETE, + ENTRY_MODIFY); + + } catch (Exception e) { + if (SCREENCAST_DEBUG) { + System.err.printf("Token storage: failed to setup " + + "file watch %s\n", e); } - }); + } if (watchService != null) { new WatcherThread(watchService).start(); @@ -317,7 +303,7 @@ private static void storeTokenFromNative(String oldToken, } if (changed) { - doPrivilegedRunnable(() -> store(PROPS_PATH, "save tokens")); + store(PROPS_PATH, "save tokens"); } } } @@ -372,7 +358,7 @@ static Set<TokenItem> getTokens(List<Rectangle> affectedScreenBounds) { .toList(); } - doPrivilegedRunnable(() -> removeMalformedRecords(malformed)); + removeMalformedRecords(malformed); // 1. Try to find exact matches for (TokenItem tokenItem : allTokenItems) { diff --git a/src/java.desktop/unix/classes/sun/font/FcFontConfiguration.java b/src/java.desktop/unix/classes/sun/font/FcFontConfiguration.java index 8638bd3f594..0e9b612301c 100644 --- a/src/java.desktop/unix/classes/sun/font/FcFontConfiguration.java +++ b/src/java.desktop/unix/classes/sun/font/FcFontConfiguration.java @@ -363,11 +363,6 @@ protected void setOsNameAndVersion() { private File getFcInfoFile() { if (fcInfoFileName == null) { - // NB need security permissions to get true IP address, and - // we should have those as the whole initialisation is in a - // doPrivileged block. But in this case no exception is thrown, - // and it returns the loop back address, and so we end up with - // "localhost" String hostname; try { hostname = InetAddress.getLocalHost().getHostName(); diff --git a/src/java.desktop/unix/classes/sun/java2d/x11/X11SurfaceData.java b/src/java.desktop/unix/classes/sun/java2d/x11/X11SurfaceData.java index 0210dd929cb..88c44369abf 100644 --- a/src/java.desktop/unix/classes/sun/java2d/x11/X11SurfaceData.java +++ b/src/java.desktop/unix/classes/sun/java2d/x11/X11SurfaceData.java @@ -210,9 +210,7 @@ public Raster getRaster(int x, int y, int w, int h) { initIDs(XORComposite.class); - @SuppressWarnings("removal") - String xtextpipe = java.security.AccessController.doPrivileged - (new sun.security.action.GetPropertyAction("sun.java2d.xtextpipe")); + String xtextpipe = System.getProperty("sun.java2d.xtextpipe"); if (xtextpipe == null || "true".startsWith(xtextpipe)) { if ("true".equals(xtextpipe)) { // Only verbose if they use the full string "true" @@ -248,9 +246,7 @@ public static boolean isAccelerationEnabled() { if (GraphicsEnvironment.isHeadless()) { accelerationEnabled = Boolean.FALSE; } else { - @SuppressWarnings("removal") - String prop = java.security.AccessController.doPrivileged( - new sun.security.action.GetPropertyAction("sun.java2d.pmoffscreen")); + String prop = System.getProperty("sun.java2d.pmoffscreen"); if (prop != null) { // true iff prop==true, false otherwise accelerationEnabled = Boolean.valueOf(prop); diff --git a/src/java.desktop/unix/classes/sun/java2d/xr/XRCompositeManager.java b/src/java.desktop/unix/classes/sun/java2d/xr/XRCompositeManager.java index c2201cb7c7c..0d10e85f607 100644 --- a/src/java.desktop/unix/classes/sun/java2d/xr/XRCompositeManager.java +++ b/src/java.desktop/unix/classes/sun/java2d/xr/XRCompositeManager.java @@ -30,8 +30,6 @@ import java.awt.Paint; import java.awt.geom.AffineTransform; import java.awt.geom.NoninvertibleTransformException; -import java.security.AccessController; -import java.security.PrivilegedAction; import sun.awt.image.PixelConverter; import sun.font.XRTextRenderer; @@ -93,13 +91,7 @@ public static synchronized XRCompositeManager getInstance( private XRCompositeManager(XRSurfaceData surface) { con = new XRBackendNative(); - @SuppressWarnings("removal") - String gradProp = - AccessController.doPrivileged(new PrivilegedAction<String>() { - public String run() { - return System.getProperty("sun.java2d.xrgradcache"); - } - }); + String gradProp = System.getProperty("sun.java2d.xrgradcache"); enableGradCache = gradProp == null || !(gradProp.equalsIgnoreCase("false") || diff --git a/src/java.desktop/unix/classes/sun/print/CUPSPrinter.java b/src/java.desktop/unix/classes/sun/print/CUPSPrinter.java index 8be118c42a5..62c43316065 100644 --- a/src/java.desktop/unix/classes/sun/print/CUPSPrinter.java +++ b/src/java.desktop/unix/classes/sun/print/CUPSPrinter.java @@ -90,16 +90,10 @@ public class CUPSPrinter { initStatic(); } - @SuppressWarnings({"removal", "restricted"}) + @SuppressWarnings("restricted") private static void initStatic() { // load awt library to access native code - java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction<Void>() { - public Void run() { - System.loadLibrary("awt"); - return null; - } - }); + System.loadLibrary("awt"); libFound = initIDs(); if (libFound) { cupsServer = getCupsServer(); @@ -308,18 +302,12 @@ static String[] getDefaultPrinter() { IPPPrintService.getIPPConnection(url); if (urlConnection != null) { - @SuppressWarnings("removal") - OutputStream os = java.security.AccessController. - doPrivileged(new java.security.PrivilegedAction<OutputStream>() { - public OutputStream run() { - try { - return urlConnection.getOutputStream(); - } catch (Exception e) { - IPPPrintService.debug_println(debugPrefix+e); - } - return null; - } - }); + OutputStream os = null; + try { + os = urlConnection.getOutputStream(); + } catch (Exception e) { + IPPPrintService.debug_println(debugPrefix+e); + } if (os == null) { return null; @@ -424,17 +412,11 @@ static String[] getAllPrinters() { IPPPrintService.getIPPConnection(url); if (urlConnection != null) { - @SuppressWarnings("removal") - OutputStream os = java.security.AccessController. - doPrivileged(new java.security.PrivilegedAction<OutputStream>() { - public OutputStream run() { - try { - return urlConnection.getOutputStream(); - } catch (Exception e) { - } - return null; - } - }); + OutputStream os = null; + try { + os = urlConnection.getOutputStream(); + } catch (Exception e) { + } if (os == null) { return null; @@ -507,12 +489,9 @@ private static String getDomainSocketPathname() { return domainSocketPathname; } - @SuppressWarnings("removal") private static boolean isSandboxedApp() { if (PrintServiceLookupProvider.isMac()) { - return java.security.AccessController - .doPrivileged((java.security.PrivilegedAction<Boolean>) () -> - System.getenv("APP_SANDBOX_CONTAINER_ID") != null); + return (System.getenv("APP_SANDBOX_CONTAINER_ID") != null); } return false; } diff --git a/src/java.desktop/unix/classes/sun/print/IPPPrintService.java b/src/java.desktop/unix/classes/sun/print/IPPPrintService.java index 5a6437014dd..4d217ec6e3e 100644 --- a/src/java.desktop/unix/classes/sun/print/IPPPrintService.java +++ b/src/java.desktop/unix/classes/sun/print/IPPPrintService.java @@ -119,9 +119,7 @@ protected static void debug_println(String str) { private static final String FORCE_PIPE_PROP = "sun.print.ippdebug"; static { - @SuppressWarnings("removal") - String debugStr = java.security.AccessController.doPrivileged( - new sun.security.action.GetPropertyAction(FORCE_PIPE_PROP)); + String debugStr = System.getProperty(FORCE_PIPE_PROP); debugPrint = "true".equalsIgnoreCase(debugStr); } @@ -1874,18 +1872,12 @@ private void opGetAttributes() { AttributeClass.TAG_URI, ""+myURI)}; - @SuppressWarnings("removal") - OutputStream os = java.security.AccessController. - doPrivileged(new java.security.PrivilegedAction<OutputStream>() { - public OutputStream run() { - try { - return urlConnection.getOutputStream(); - } catch (Exception e) { - } - return null; - } - }); + OutputStream os = null; + try { + os = urlConnection.getOutputStream(); + } catch (Exception e) { + } if (os == null) { return; } diff --git a/src/java.desktop/unix/classes/sun/print/PrintServiceLookupProvider.java b/src/java.desktop/unix/classes/sun/print/PrintServiceLookupProvider.java index 5e45b00861e..15025d43d6f 100644 --- a/src/java.desktop/unix/classes/sun/print/PrintServiceLookupProvider.java +++ b/src/java.desktop/unix/classes/sun/print/PrintServiceLookupProvider.java @@ -28,12 +28,8 @@ import java.io.BufferedReader; import java.io.IOException; import java.net.MalformedURLException; -import java.security.PrivilegedAction; import java.util.ArrayList; import java.util.Vector; -import java.security.AccessController; -import java.security.PrivilegedActionException; -import java.security.PrivilegedExceptionAction; import javax.print.DocFlavor; import javax.print.MultiDocPrintService; import javax.print.PrintService; @@ -95,9 +91,7 @@ public class PrintServiceLookupProvider extends PrintServiceLookup * can be used to force the printing code to poll or not poll * for PrintServices. */ - @SuppressWarnings("removal") - String pollStr = java.security.AccessController.doPrivileged( - new sun.security.action.GetPropertyAction("sun.java2d.print.polling")); + String pollStr = System.getProperty("sun.java2d.print.polling"); if (pollStr != null) { if (pollStr.equalsIgnoreCase("true")) { @@ -111,10 +105,7 @@ public class PrintServiceLookupProvider extends PrintServiceLookup * can be used to specify minimum refresh time (in seconds) * for polling PrintServices. The default is 120. */ - @SuppressWarnings("removal") - String refreshTimeStr = java.security.AccessController.doPrivileged( - new sun.security.action.GetPropertyAction( - "sun.java2d.print.minRefreshTime")); + String refreshTimeStr = System.getProperty("sun.java2d.print.minRefreshTime"); if (refreshTimeStr != null) { try { @@ -132,9 +123,7 @@ public class PrintServiceLookupProvider extends PrintServiceLookup * take lots of time if thousands of printers are attached to a server. */ if (isAIX()) { - @SuppressWarnings("removal") - String aixPrinterEnumerator = java.security.AccessController.doPrivileged( - new sun.security.action.GetPropertyAction("sun.java2d.print.aix.lpstat")); + String aixPrinterEnumerator = System.getProperty("sun.java2d.print.aix.lpstat"); if (aixPrinterEnumerator != null) { if (aixPrinterEnumerator.equalsIgnoreCase("lpstat")) { @@ -202,18 +191,15 @@ static int getBSDCommandIndex() { return BSD_LPD; } - @SuppressWarnings("removal") public PrintServiceLookupProvider() { // start the printer listener thread if (pollServices) { - AccessController.doPrivileged((PrivilegedAction<Thread>) () -> { - Thread thr = new Thread(ThreadGroupUtils.getRootThreadGroup(), - new PrinterChangeListener(), - "PrinterListener", 0, false); - thr.setContextClassLoader(null); - thr.setDaemon(true); - return thr; - }).start(); + Thread thr = new Thread(ThreadGroupUtils.getRootThreadGroup(), + new PrinterChangeListener(), + "PrinterListener", 0, false); + thr.setContextClassLoader(null); + thr.setDaemon(true); + thr.start(); IPPPrintService.debug_println(debugPrefix+"polling turned on"); } } @@ -871,7 +857,6 @@ private String[] getAllPrinterNamesAIX() { return printerNames.toArray(new String[printerNames.size()]); } - @SuppressWarnings("removal") static String[] execCmd(final String command) { ArrayList<String> results = null; try { @@ -886,51 +871,46 @@ static String[] execCmd(final String command) { cmd[2] = "LC_ALL=C " + command; } - results = AccessController.doPrivileged( - new PrivilegedExceptionAction<ArrayList<String>>() { - public ArrayList<String> run() throws IOException { + Process proc; + BufferedReader bufferedReader = null; + File f = Files.createTempFile("prn", "xc") + .toFile(); + cmd[2] = cmd[2] + ">" + f.getAbsolutePath(); - Process proc; - BufferedReader bufferedReader = null; - File f = Files.createTempFile("prn","xc").toFile(); - cmd[2] = cmd[2]+">"+f.getAbsolutePath(); - - proc = Runtime.getRuntime().exec(cmd); - try { - boolean done = false; // in case of interrupt. - while (!done) { - try { - proc.waitFor(); - done = true; - } catch (InterruptedException e) { - } - } + proc = Runtime.getRuntime().exec(cmd); + try { + boolean done = false; // in case of interrupt. + while (!done) { + try { + proc.waitFor(); + done = true; + } catch (InterruptedException ignored) { + } + } - if (proc.exitValue() == 0) { - FileReader reader = new FileReader(f); - bufferedReader = new BufferedReader(reader); - String line; - ArrayList<String> results = new ArrayList<>(); - while ((line = bufferedReader.readLine()) - != null) { - results.add(line); - } - return results; - } - } finally { - f.delete(); - // promptly close all streams. - if (bufferedReader != null) { - bufferedReader.close(); - } - proc.getInputStream().close(); - proc.getErrorStream().close(); - proc.getOutputStream().close(); - } - return null; + if (proc.exitValue() == 0) { + FileReader reader = new FileReader(f); + bufferedReader = new BufferedReader(reader); + String line; + while ((line = bufferedReader.readLine()) + != null) { + results.add(line); } - }); - } catch (PrivilegedActionException e) { + } + } finally { + f.delete(); + // promptly close all streams. + if (bufferedReader != null) { + bufferedReader.close(); + } + proc.getInputStream() + .close(); + proc.getErrorStream() + .close(); + proc.getOutputStream() + .close(); + } + } catch (IOException ignored) { } if (results == null) { return new String[0]; diff --git a/src/java.desktop/unix/classes/sun/print/UnixPrintJob.java b/src/java.desktop/unix/classes/sun/print/UnixPrintJob.java index 913c69e40ee..1249d29ec72 100644 --- a/src/java.desktop/unix/classes/sun/print/UnixPrintJob.java +++ b/src/java.desktop/unix/classes/sun/print/UnixPrintJob.java @@ -86,7 +86,6 @@ import java.awt.print.PrinterException; - public class UnixPrintJob implements CancelablePrintJob { private static String debugPrefix = "UnixPrintJob>> "; @@ -525,8 +524,7 @@ public void print(Doc doc, PrintRequestAttributeSet attributes) // now spool the print data. PrinterOpener po = new PrinterOpener(); - @SuppressWarnings("removal") - var dummy = java.security.AccessController.doPrivileged(po); + po.run(); if (po.pex != null) { throw po.pex; } @@ -599,8 +597,7 @@ public void print(Doc doc, PrintRequestAttributeSet attributes) if (mDestType == UnixPrintJob.DESTPRINTER) { PrinterSpooler spooler = new PrinterSpooler(); - @SuppressWarnings("removal") - var dummy2 = java.security.AccessController.doPrivileged(spooler); + spooler.run(); if (spooler.pex != null) { throw spooler.pex; } @@ -911,9 +908,7 @@ private String[] printExecCmd(String printer, String options, private String mDestination, mOptions=""; private boolean mNoJobSheet = false; - // Inner class to run "privileged" to open the printer output stream. - - private class PrinterOpener implements java.security.PrivilegedAction<OutputStream> { + private class PrinterOpener { PrintException pex; OutputStream result; @@ -941,9 +936,7 @@ public OutputStream run() { } } - // Inner class to run "privileged" to invoke the system print command - - private class PrinterSpooler implements java.security.PrivilegedAction<Object> { + private class PrinterSpooler { PrintException pex; private void handleProcessFailure(final Process failedProcess, diff --git a/src/java.desktop/unix/classes/sun/print/UnixPrintService.java b/src/java.desktop/unix/classes/sun/print/UnixPrintService.java index bbd8c6c9c78..201487e9ca4 100644 --- a/src/java.desktop/unix/classes/sun/print/UnixPrintService.java +++ b/src/java.desktop/unix/classes/sun/print/UnixPrintService.java @@ -145,9 +145,7 @@ public class UnixPrintService implements PrintService, AttributeUpdater, "| grep -E '^[ 0-9a-zA-Z_-]*@' | awk '{print $4}'" }; - @SuppressWarnings("removal") - private static String encoding = java.security.AccessController.doPrivileged( - new sun.security.action.GetPropertyAction("file.encoding")); + private static String encoding = System.getProperty("file.encoding"); /* let's try to support a few of these */ private static final Class<?>[] serviceAttrCats = { From a599c30171fe2b1557ad967d61048656fdb8c752 Mon Sep 17 00:00:00 2001 From: Jaikiran Pai <jpai@openjdk.org> Date: Thu, 21 Nov 2024 00:49:25 +0000 Subject: [PATCH 141/311] 8344471: Remove SecurityManager related code from java.compiler module Reviewed-by: rriggs, jlahoda, jjg --- .../classes/javax/tools/ToolProvider.java | 22 ++----------------- 1 file changed, 2 insertions(+), 20 deletions(-) diff --git a/src/java.compiler/share/classes/javax/tools/ToolProvider.java b/src/java.compiler/share/classes/javax/tools/ToolProvider.java index 8cdfd63b17d..03a56139fdd 100644 --- a/src/java.compiler/share/classes/javax/tools/ToolProvider.java +++ b/src/java.compiler/share/classes/javax/tools/ToolProvider.java @@ -25,8 +25,6 @@ package javax.tools; -import java.security.AccessController; -import java.security.PrivilegedAction; import java.util.Objects; import java.util.ServiceConfigurationError; import java.util.ServiceLoader; @@ -118,29 +116,13 @@ private static <T> T getSystemTool(Class<T> clazz, String moduleName, String cla try { ServiceLoader<T> sl = ServiceLoader.load(clazz, ClassLoader.getSystemClassLoader()); for (T tool : sl) { - if (matches(tool, moduleName)) + if (Objects.equals(tool.getClass().getModule().getName(), moduleName)) { return tool; + } } } catch (ServiceConfigurationError e) { throw new Error(e); } return null; } - - /** - * Determine if this is the desired tool instance. - * @param <T> the interface of the tool - * @param tool the instance of the tool - * @param moduleName the name of the module containing the desired implementation - * @return true if and only if the tool matches the specified criteria - */ - @SuppressWarnings("removal") - private static <T> boolean matches(T tool, String moduleName) { - PrivilegedAction<Boolean> pa = () -> { - Module toolModule = tool.getClass().getModule(); - String toolModuleName = toolModule.getName(); - return Objects.equals(toolModuleName, moduleName); - }; - return AccessController.doPrivileged(pa); - } } From 400eb9b10ae0e53e58893b7ea5233d2d2e4046b6 Mon Sep 17 00:00:00 2001 From: Jaikiran Pai <jpai@openjdk.org> Date: Thu, 21 Nov 2024 00:55:23 +0000 Subject: [PATCH 142/311] 8344524: Remove SecurityManager related code from jdk.jlink module Reviewed-by: alanb, lancea, iris --- .../jdk/tools/jlink/internal/Jlink.java | 12 ------ .../tools/jlink/internal/JlinkPermission.java | 42 ------------------- .../jdk/tools/jlink/internal/Main.java | 8 +--- 3 files changed, 1 insertion(+), 61 deletions(-) delete mode 100644 src/jdk.jlink/share/classes/jdk/tools/jlink/internal/JlinkPermission.java diff --git a/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/Jlink.java b/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/Jlink.java index 465a1cae8d9..99029651bfb 100644 --- a/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/Jlink.java +++ b/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/Jlink.java @@ -242,18 +242,6 @@ public String toString() { } } - /** - * Jlink instance constructor, if a security manager is set, the jlink - * permission is checked. - */ - @SuppressWarnings("removal") - public Jlink() { - if (System.getSecurityManager() != null) { - System.getSecurityManager(). - checkPermission(new JlinkPermission("jlink")); - } - } - /** * Build the image. * diff --git a/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/JlinkPermission.java b/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/JlinkPermission.java deleted file mode 100644 index f1725e77ee2..00000000000 --- a/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/JlinkPermission.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package jdk.tools.jlink.internal; - -import java.security.BasicPermission; - -/** - * The permission required to use jlink API. The permission target_name is - * "jlink". e.g.: permission jdk.tools.jlink.plugins.JlinkPermission "jlink"; - * - */ -public final class JlinkPermission extends BasicPermission { - - private static final long serialVersionUID = -3687912306077727801L; - - public JlinkPermission(String name) { - super(name); - } - -} diff --git a/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/Main.java b/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/Main.java index df08b2b54a4..eb743bc4dad 100644 --- a/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/Main.java +++ b/src/jdk.jlink/share/classes/jdk/tools/jlink/internal/Main.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -44,13 +44,7 @@ public static void main(String... args) throws Exception { * @param args command line arguments * @return an exit code. 0 means success, non-zero means an error occurred. */ - @SuppressWarnings("removal") public static int run(PrintWriter out, PrintWriter err, String... args) { - if (System.getSecurityManager() != null) { - System.getSecurityManager(). - checkPermission(new JlinkPermission("jlink")); - } - JlinkTask t = new JlinkTask(); t.setLog(out, err); return t.run(args); From 13439113c361dcb0629ece37844443cbf99ef704 Mon Sep 17 00:00:00 2001 From: Leonid Mesnik <lmesnik@openjdk.org> Date: Thu, 21 Nov 2024 01:32:09 +0000 Subject: [PATCH 143/311] 8340334: Update jcmd VM.events max parameter to be INT Reviewed-by: cjplummer, kevinw --- src/hotspot/share/services/diagnosticCommand.cpp | 14 +++++--------- src/hotspot/share/services/diagnosticCommand.hpp | 2 +- src/jdk.jcmd/share/man/jcmd.md | 2 +- 3 files changed, 7 insertions(+), 11 deletions(-) diff --git a/src/hotspot/share/services/diagnosticCommand.cpp b/src/hotspot/share/services/diagnosticCommand.cpp index 240f3604cc1..b807a42661c 100644 --- a/src/hotspot/share/services/diagnosticCommand.cpp +++ b/src/hotspot/share/services/diagnosticCommand.cpp @@ -884,21 +884,17 @@ void CodeHeapAnalyticsDCmd::execute(DCmdSource source, TRAPS) { EventLogDCmd::EventLogDCmd(outputStream* output, bool heap) : DCmdWithParser(output, heap), _log("log", "Name of log to be printed. If omitted, all logs are printed.", "STRING", false, nullptr), - _max("max", "Maximum number of events to be printed (newest first). If omitted, all events are printed.", "STRING", false, nullptr) + _max("max", "Maximum number of events to be printed (newest first). If omitted or zero, all events are printed.", "INT", false, "0") { _dcmdparser.add_dcmd_option(&_log); _dcmdparser.add_dcmd_option(&_max); } void EventLogDCmd::execute(DCmdSource source, TRAPS) { - const char* max_value = _max.value(); - int max = -1; - if (max_value != nullptr) { - char* endptr = nullptr; - if (!parse_integer(max_value, &max)) { - output()->print_cr("Invalid max option: \"%s\".", max_value); - return; - } + int max = (int)_max.value(); + if (max < 0) { + output()->print_cr("Invalid max option: \"%d\".", max); + return; } const char* log_name = _log.value(); if (log_name != nullptr) { diff --git a/src/hotspot/share/services/diagnosticCommand.hpp b/src/hotspot/share/services/diagnosticCommand.hpp index c8e26504ece..92e5849cbcd 100644 --- a/src/hotspot/share/services/diagnosticCommand.hpp +++ b/src/hotspot/share/services/diagnosticCommand.hpp @@ -889,7 +889,7 @@ class ClassesDCmd : public DCmdWithParser { class EventLogDCmd : public DCmdWithParser { protected: DCmdArgument<char*> _log; - DCmdArgument<char*> _max; + DCmdArgument<jlong> _max; public: static int num_arguments() { return 2; } EventLogDCmd(outputStream* output, bool heap); diff --git a/src/jdk.jcmd/share/man/jcmd.md b/src/jdk.jcmd/share/man/jcmd.md index 448dfdd3051..2d2e08bc9f5 100644 --- a/src/jdk.jcmd/share/man/jcmd.md +++ b/src/jdk.jcmd/share/man/jcmd.md @@ -836,7 +836,7 @@ The following commands are available: - `log`: (Optional) Name of log to be printed. If omitted, all logs are printed. (STRING, no default value) - `max`: (Optional) Maximum number of events to be printed (newest first). - If omitted, all events are printed. (STRING, no default value) + If omitted or zero, all events are printed. (INT, 0) `VM.flags` \[*options*\] : Print the VM flag options and their current values. From 4fbf272017d2f6933e66f8a67cb88e3ffc42339e Mon Sep 17 00:00:00 2001 From: SendaoYan <syan@openjdk.org> Date: Thu, 21 Nov 2024 02:05:00 +0000 Subject: [PATCH 144/311] 8344526: RISC-V: implement -XX:+VerifyActivationFrameSize Co-authored-by: Fei Yang <fyang@openjdk.org> Reviewed-by: mli, fyang --- src/hotspot/cpu/riscv/interp_masm_riscv.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/hotspot/cpu/riscv/interp_masm_riscv.cpp b/src/hotspot/cpu/riscv/interp_masm_riscv.cpp index b00b4474d69..897222ef995 100644 --- a/src/hotspot/cpu/riscv/interp_masm_riscv.cpp +++ b/src/hotspot/cpu/riscv/interp_masm_riscv.cpp @@ -441,7 +441,14 @@ void InterpreterMacroAssembler::dispatch_base(TosState state, Register Rs) { // Pay attention to the argument Rs, which is acquiesce in t0. if (VerifyActivationFrameSize) { - Unimplemented(); + Label L; + sub(t1, fp, esp); + int min_frame_size = + (frame::link_offset - frame::interpreter_frame_initial_sp_offset + frame::metadata_words) * wordSize; + sub(t1, t1, min_frame_size); + bgez(t1, L); + stop("broken stack frame"); + bind(L); } if (verifyoop && state == atos) { verify_oop(x10); From a01aa2202602d2fcdb81b4c5b4183cb6b7acfacb Mon Sep 17 00:00:00 2001 From: Phil Race <prr@openjdk.org> Date: Thu, 21 Nov 2024 03:58:49 +0000 Subject: [PATCH 145/311] 8342281: Deprecate for removal javax.sound.sampled.AudioPermission Reviewed-by: honkar, kizune --- .../sun/media/sound/DirectAudioDevice.java | 19 ------------------- .../sun/media/sound/JSSecurityManager.java | 16 +++------------- .../javax/sound/sampled/AudioPermission.java | 3 +++ .../javax/sound/sampled/Lines/GetLine.java | 16 ---------------- 4 files changed, 6 insertions(+), 48 deletions(-) diff --git a/src/java.desktop/share/classes/com/sun/media/sound/DirectAudioDevice.java b/src/java.desktop/share/classes/com/sun/media/sound/DirectAudioDevice.java index cbc5416cd60..77c03c5267d 100644 --- a/src/java.desktop/share/classes/com/sun/media/sound/DirectAudioDevice.java +++ b/src/java.desktop/share/classes/com/sun/media/sound/DirectAudioDevice.java @@ -404,10 +404,6 @@ void implOpen(AudioFormat format, int bufferSize) throws LineUnavailableExceptio // $$fb part of fix for 4679187: Clip.open() throws unexpected Exceptions Toolkit.isFullySpecifiedAudioFormat(format); - // check for record permission - if (!isSource) { - JSSecurityManager.checkRecordPermission(); - } int encoding = PCM; if (format.getEncoding().equals(AudioFormat.Encoding.ULAW)) { encoding = ULAW; @@ -509,11 +505,6 @@ else if (waitTime > 1000) { @Override void implStart() { - // check for record permission - if (!isSource) { - JSSecurityManager.checkRecordPermission(); - } - synchronized (lockNative) { nStart(id, isSource); @@ -538,11 +529,6 @@ void implStart() { @Override void implStop() { - // check for record permission - if (!isSource) { - JSSecurityManager.checkRecordPermission(); - } - if (monitoring) { getEventDispatcher().removeLineMonitor(this); monitoring = false; @@ -565,11 +551,6 @@ void implStop() { @Override void implClose() { - // check for record permission - if (!isSource) { - JSSecurityManager.checkRecordPermission(); - } - // be sure to remove this monitor if (monitoring) { getEventDispatcher().removeLineMonitor(this); diff --git a/src/java.desktop/share/classes/com/sun/media/sound/JSSecurityManager.java b/src/java.desktop/share/classes/com/sun/media/sound/JSSecurityManager.java index e9b99ac1a10..91d5c0284b5 100644 --- a/src/java.desktop/share/classes/com/sun/media/sound/JSSecurityManager.java +++ b/src/java.desktop/share/classes/com/sun/media/sound/JSSecurityManager.java @@ -35,11 +35,9 @@ import java.util.Properties; import java.util.ServiceLoader; -import javax.sound.sampled.AudioPermission; - -/** Managing security in the Java Sound implementation. - * This class contains all code that uses and is used by - * SecurityManager +/** + * Historically this class managed ensuring privileges to access resources + * it is still used to get those resources but no longer does checks. * * @author Matthias Pfisterer */ @@ -50,14 +48,6 @@ final class JSSecurityManager { private JSSecurityManager() { } - static void checkRecordPermission() throws SecurityException { - @SuppressWarnings("removal") - SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - sm.checkPermission(new AudioPermission("record")); - } - } - /** * Load properties from a file. * <p> diff --git a/src/java.desktop/share/classes/javax/sound/sampled/AudioPermission.java b/src/java.desktop/share/classes/javax/sound/sampled/AudioPermission.java index 296360a6550..f834c342b6f 100644 --- a/src/java.desktop/share/classes/javax/sound/sampled/AudioPermission.java +++ b/src/java.desktop/share/classes/javax/sound/sampled/AudioPermission.java @@ -40,10 +40,13 @@ * @apiNote * This permission cannot be used for controlling access to resources * as the Security Manager is no longer supported. + * Consequently this class is deprecated and may be removed in a future release. * * @author Kara Kytle * @since 1.3 + * @deprecated There is no replacement for this class. */ +@Deprecated(since="24", forRemoval=true) public class AudioPermission extends BasicPermission { /** diff --git a/test/jdk/javax/sound/sampled/Lines/GetLine.java b/test/jdk/javax/sound/sampled/Lines/GetLine.java index daa0114ae8a..e31c5ac8d6f 100644 --- a/test/jdk/javax/sound/sampled/Lines/GetLine.java +++ b/test/jdk/javax/sound/sampled/Lines/GetLine.java @@ -21,7 +21,6 @@ * questions. */ -import javax.sound.sampled.AudioPermission; import javax.sound.sampled.AudioSystem; import javax.sound.sampled.DataLine; import javax.sound.sampled.Line; @@ -35,18 +34,6 @@ */ public class GetLine { - static boolean isSoundAccessDenied = false; - static { - SecurityManager securityManager = System.getSecurityManager(); - if (securityManager != null) { - try { - securityManager.checkPermission(new AudioPermission("*")); - } catch (SecurityException e) { - isSoundAccessDenied = true; - } - } - } - static final int STATUS_PASSED = 0; static final int STATUS_FAILED = 2; static final int STATUS_TEMP = 95; @@ -80,9 +67,6 @@ public static int run(String argv[], java.io.PrintStream out) { } try { l = AudioSystem.getLine(infos[0]); - } catch(SecurityException lue) { - log.println("SecurityException"); - return STATUS_PASSED; } catch (LineUnavailableException e1) { log.println("LUE"); return STATUS_PASSED; From 7105bb98cf8797082d2b61f0e08a4e5ba0bae8ac Mon Sep 17 00:00:00 2001 From: Phil Race <prr@openjdk.org> Date: Thu, 21 Nov 2024 04:22:27 +0000 Subject: [PATCH 146/311] 8344664: Remove some un-used java/sun.security imports in the java.desktop module Reviewed-by: iris --- .../classes/com/sun/java/swing/plaf/gtk/GTKLookAndFeel.java | 2 -- .../share/classes/com/sun/media/sound/JARSoundbankReader.java | 1 - .../share/classes/com/sun/media/sound/Printer.java | 2 -- src/java.desktop/share/classes/java/awt/Component.java | 1 - src/java.desktop/share/classes/java/awt/Container.java | 2 -- src/java.desktop/share/classes/java/awt/Window.java | 1 - src/java.desktop/share/classes/javax/imageio/ImageIO.java | 2 -- .../share/classes/sun/awt/im/InputMethodContext.java | 1 - .../share/classes/sun/awt/util/ThreadGroupUtils.java | 1 - src/java.desktop/share/classes/sun/font/TrueTypeFont.java | 1 - .../share/classes/sun/java2d/marlin/MarlinUtils.java | 1 - src/java.desktop/unix/classes/sun/awt/UNIXToolkit.java | 4 ---- .../unix/classes/sun/awt/X11InputMethodDescriptor.java | 2 -- 13 files changed, 21 deletions(-) diff --git a/src/java.desktop/share/classes/com/sun/java/swing/plaf/gtk/GTKLookAndFeel.java b/src/java.desktop/share/classes/com/sun/java/swing/plaf/gtk/GTKLookAndFeel.java index a2414da4559..9490dc6bdff 100644 --- a/src/java.desktop/share/classes/com/sun/java/swing/plaf/gtk/GTKLookAndFeel.java +++ b/src/java.desktop/share/classes/com/sun/java/swing/plaf/gtk/GTKLookAndFeel.java @@ -38,7 +38,6 @@ import java.beans.PropertyChangeListener; import java.lang.ref.ReferenceQueue; import java.lang.ref.WeakReference; -import java.security.AccessController; import java.util.HashMap; import java.util.Map; @@ -65,7 +64,6 @@ import com.sun.java.swing.plaf.gtk.GTKConstants.StateType; import sun.awt.SunToolkit; import sun.awt.UNIXToolkit; -import sun.security.action.GetPropertyAction; import sun.swing.AltProcessor; import sun.swing.DefaultLayoutStyle; import sun.swing.MnemonicHandler; diff --git a/src/java.desktop/share/classes/com/sun/media/sound/JARSoundbankReader.java b/src/java.desktop/share/classes/com/sun/media/sound/JARSoundbankReader.java index 4ff72c7040a..8b492fa7782 100644 --- a/src/java.desktop/share/classes/com/sun/media/sound/JARSoundbankReader.java +++ b/src/java.desktop/share/classes/com/sun/media/sound/JARSoundbankReader.java @@ -40,7 +40,6 @@ import javax.sound.midi.spi.SoundbankReader; import sun.reflect.misc.ReflectUtil; -import sun.security.action.GetBooleanAction; /** * JarSoundbankReader is used to read soundbank object from jar files. diff --git a/src/java.desktop/share/classes/com/sun/media/sound/Printer.java b/src/java.desktop/share/classes/com/sun/media/sound/Printer.java index 40e179b1bd8..af2c3e11988 100644 --- a/src/java.desktop/share/classes/com/sun/media/sound/Printer.java +++ b/src/java.desktop/share/classes/com/sun/media/sound/Printer.java @@ -26,8 +26,6 @@ package com.sun.media.sound; -import sun.security.action.GetPropertyAction; - /** * Printer allows you to set up global debugging status and print * messages accordingly. diff --git a/src/java.desktop/share/classes/java/awt/Component.java b/src/java.desktop/share/classes/java/awt/Component.java index 71618eea95b..36683ff2813 100644 --- a/src/java.desktop/share/classes/java/awt/Component.java +++ b/src/java.desktop/share/classes/java/awt/Component.java @@ -108,7 +108,6 @@ import sun.java2d.SunGraphicsEnvironment; import sun.java2d.pipe.Region; import sun.java2d.pipe.hw.ExtendedBufferCapabilities; -import sun.security.action.GetPropertyAction; import sun.swing.SwingAccessor; import sun.util.logging.PlatformLogger; diff --git a/src/java.desktop/share/classes/java/awt/Container.java b/src/java.desktop/share/classes/java/awt/Container.java index 63bd7467d91..b6fbfb808a6 100644 --- a/src/java.desktop/share/classes/java/awt/Container.java +++ b/src/java.desktop/share/classes/java/awt/Container.java @@ -50,7 +50,6 @@ import java.io.Serial; import java.io.Serializable; import java.lang.ref.WeakReference; -import java.security.AccessController; import java.util.ArrayList; import java.util.EventListener; import java.util.HashSet; @@ -67,7 +66,6 @@ import sun.awt.SunToolkit; import sun.awt.dnd.SunDropTargetEvent; import sun.java2d.pipe.Region; -import sun.security.action.GetBooleanAction; import sun.util.logging.PlatformLogger; /** diff --git a/src/java.desktop/share/classes/java/awt/Window.java b/src/java.desktop/share/classes/java/awt/Window.java index 9b855739443..f6560fb8e58 100644 --- a/src/java.desktop/share/classes/java/awt/Window.java +++ b/src/java.desktop/share/classes/java/awt/Window.java @@ -70,7 +70,6 @@ import sun.awt.SunToolkit; import sun.awt.util.IdentityArrayList; import sun.java2d.pipe.Region; -import sun.security.action.GetPropertyAction; import sun.util.logging.PlatformLogger; /** diff --git a/src/java.desktop/share/classes/javax/imageio/ImageIO.java b/src/java.desktop/share/classes/javax/imageio/ImageIO.java index 316a74a22ea..f085383284e 100644 --- a/src/java.desktop/share/classes/javax/imageio/ImageIO.java +++ b/src/java.desktop/share/classes/javax/imageio/ImageIO.java @@ -34,7 +34,6 @@ import java.io.OutputStream; import java.lang.reflect.Method; import java.net.URL; -import java.security.AccessController; import java.util.Arrays; import java.util.Collections; import java.util.HashSet; @@ -50,7 +49,6 @@ import javax.imageio.stream.ImageInputStream; import javax.imageio.stream.ImageOutputStream; import sun.awt.AppContext; -import sun.security.action.GetPropertyAction; /** * A class containing static convenience methods for locating diff --git a/src/java.desktop/share/classes/sun/awt/im/InputMethodContext.java b/src/java.desktop/share/classes/sun/awt/im/InputMethodContext.java index a0f9baa3112..fd165a52f72 100644 --- a/src/java.desktop/share/classes/sun/awt/im/InputMethodContext.java +++ b/src/java.desktop/share/classes/sun/awt/im/InputMethodContext.java @@ -43,7 +43,6 @@ import java.text.CharacterIterator; import javax.swing.JFrame; import sun.awt.InputMethodSupport; -import sun.security.action.GetPropertyAction; /** * The InputMethodContext class provides methods that input methods diff --git a/src/java.desktop/share/classes/sun/awt/util/ThreadGroupUtils.java b/src/java.desktop/share/classes/sun/awt/util/ThreadGroupUtils.java index 5d58a1c29d4..6944ba44879 100644 --- a/src/java.desktop/share/classes/sun/awt/util/ThreadGroupUtils.java +++ b/src/java.desktop/share/classes/sun/awt/util/ThreadGroupUtils.java @@ -39,7 +39,6 @@ private ThreadGroupUtils() { /** * Returns a root thread group. - * Should be called with {@link sun.security.util.SecurityConstants#MODIFY_THREADGROUP_PERMISSION} * * @return a root {@code ThreadGroup} */ diff --git a/src/java.desktop/share/classes/sun/font/TrueTypeFont.java b/src/java.desktop/share/classes/sun/font/TrueTypeFont.java index a44a013b749..8b7f9b95f5c 100644 --- a/src/java.desktop/share/classes/sun/font/TrueTypeFont.java +++ b/src/java.desktop/share/classes/sun/font/TrueTypeFont.java @@ -45,7 +45,6 @@ import sun.java2d.Disposer; import sun.java2d.DisposerRecord; -import sun.security.action.GetPropertyAction; /** * TrueTypeFont is not called SFntFont because it is not expected diff --git a/src/java.desktop/share/classes/sun/java2d/marlin/MarlinUtils.java b/src/java.desktop/share/classes/sun/java2d/marlin/MarlinUtils.java index 05ea55f170b..49f5ab613a8 100644 --- a/src/java.desktop/share/classes/sun/java2d/marlin/MarlinUtils.java +++ b/src/java.desktop/share/classes/sun/java2d/marlin/MarlinUtils.java @@ -65,7 +65,6 @@ public static void logException(final String msg, final Throwable th) { /** * Returns a root thread group. - * Should be called with {@link sun.security.util.SecurityConstants#MODIFY_THREADGROUP_PERMISSION} * * @return a root {@code ThreadGroup} */ diff --git a/src/java.desktop/unix/classes/sun/awt/UNIXToolkit.java b/src/java.desktop/unix/classes/sun/awt/UNIXToolkit.java index 8e224414427..5881ba55ef3 100644 --- a/src/java.desktop/unix/classes/sun/awt/UNIXToolkit.java +++ b/src/java.desktop/unix/classes/sun/awt/UNIXToolkit.java @@ -51,15 +51,11 @@ import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; -import java.security.AccessController; -import java.security.PrivilegedAction; import java.util.Arrays; import sun.awt.X11.XBaseWindow; -import sun.security.action.GetIntegerAction; import com.sun.java.swing.plaf.gtk.GTKConstants.TextDirection; import sun.java2d.opengl.OGLRenderQueue; -import sun.security.action.GetPropertyAction; public abstract class UNIXToolkit extends SunToolkit { diff --git a/src/java.desktop/unix/classes/sun/awt/X11InputMethodDescriptor.java b/src/java.desktop/unix/classes/sun/awt/X11InputMethodDescriptor.java index d0502505dc6..f05419feef4 100644 --- a/src/java.desktop/unix/classes/sun/awt/X11InputMethodDescriptor.java +++ b/src/java.desktop/unix/classes/sun/awt/X11InputMethodDescriptor.java @@ -30,10 +30,8 @@ import java.awt.Toolkit; import java.awt.im.spi.InputMethod; import java.awt.im.spi.InputMethodDescriptor; -import java.security.AccessController; import java.util.Locale; import sun.awt.SunToolkit; -import sun.security.action.GetPropertyAction; /** * Provides sufficient information about an input method From 10def484dfe5821940c6fef6d857db93c30d0b06 Mon Sep 17 00:00:00 2001 From: Jaikiran Pai <jpai@openjdk.org> Date: Thu, 21 Nov 2024 05:01:52 +0000 Subject: [PATCH 147/311] 8344236: Revisit SecurityManager usage in jdk.net after JEP 486 integration Reviewed-by: dfuchs --- .../aix/classes/jdk/net/AIXSocketOptions.java | 15 +++------------ .../linux/classes/jdk/net/LinuxSocketOptions.java | 15 +++------------ .../classes/jdk/net/MacOSXSocketOptions.java | 15 +++------------ src/jdk.net/share/classes/jdk/nio/Channels.java | 7 ------- .../classes/jdk/net/WindowsSocketOptions.java | 15 +++------------ 5 files changed, 12 insertions(+), 55 deletions(-) diff --git a/src/jdk.net/aix/classes/jdk/net/AIXSocketOptions.java b/src/jdk.net/aix/classes/jdk/net/AIXSocketOptions.java index 086c346ff8f..604386b3718 100644 --- a/src/jdk.net/aix/classes/jdk/net/AIXSocketOptions.java +++ b/src/jdk.net/aix/classes/jdk/net/AIXSocketOptions.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -27,12 +27,10 @@ import java.net.SocketException; import java.nio.file.attribute.UserPrincipal; import java.nio.file.attribute.GroupPrincipal; -import java.security.AccessController; -import java.security.PrivilegedAction; import jdk.net.ExtendedSocketOptions.PlatformSocketOptions; import sun.nio.fs.UnixUserPrincipals; -@SuppressWarnings({"removal", "restricted"}) +@SuppressWarnings("restricted") class AIXSocketOptions extends PlatformSocketOptions { public AIXSocketOptions() { @@ -131,13 +129,6 @@ UnixDomainPrincipal getSoPeerCred(int fd) throws SocketException { private static native boolean keepAliveOptionsSupported0(); private static native boolean quickAckSupported0(); static { - if (System.getSecurityManager() == null) { - System.loadLibrary("extnet"); - } else { - AccessController.doPrivileged((PrivilegedAction<Void>) () -> { - System.loadLibrary("extnet"); - return null; - }); - } + System.loadLibrary("extnet"); } } diff --git a/src/jdk.net/linux/classes/jdk/net/LinuxSocketOptions.java b/src/jdk.net/linux/classes/jdk/net/LinuxSocketOptions.java index 8d3ceeebfa9..bffe094ea45 100644 --- a/src/jdk.net/linux/classes/jdk/net/LinuxSocketOptions.java +++ b/src/jdk.net/linux/classes/jdk/net/LinuxSocketOptions.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -27,12 +27,10 @@ import java.net.SocketException; import java.nio.file.attribute.UserPrincipal; import java.nio.file.attribute.GroupPrincipal; -import java.security.AccessController; -import java.security.PrivilegedAction; import jdk.net.ExtendedSocketOptions.PlatformSocketOptions; import sun.nio.fs.UnixUserPrincipals; -@SuppressWarnings({"removal", "restricted"}) +@SuppressWarnings("restricted") class LinuxSocketOptions extends PlatformSocketOptions { public LinuxSocketOptions() { @@ -143,14 +141,7 @@ UnixDomainPrincipal getSoPeerCred(int fd) throws SocketException { private static native boolean incomingNapiIdSupported0(); private static native int getIncomingNapiId0(int fd) throws SocketException; static { - if (System.getSecurityManager() == null) { - System.loadLibrary("extnet"); - } else { - AccessController.doPrivileged((PrivilegedAction<Void>) () -> { - System.loadLibrary("extnet"); - return null; - }); - } + System.loadLibrary("extnet"); } } diff --git a/src/jdk.net/macosx/classes/jdk/net/MacOSXSocketOptions.java b/src/jdk.net/macosx/classes/jdk/net/MacOSXSocketOptions.java index c2912e8b808..23055954b21 100644 --- a/src/jdk.net/macosx/classes/jdk/net/MacOSXSocketOptions.java +++ b/src/jdk.net/macosx/classes/jdk/net/MacOSXSocketOptions.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -27,12 +27,10 @@ import java.net.SocketException; import java.nio.file.attribute.UserPrincipal; import java.nio.file.attribute.GroupPrincipal; -import java.security.AccessController; -import java.security.PrivilegedAction; import jdk.net.ExtendedSocketOptions.PlatformSocketOptions; import sun.nio.fs.UnixUserPrincipals; -@SuppressWarnings({"removal", "restricted"}) +@SuppressWarnings("restricted") class MacOSXSocketOptions extends PlatformSocketOptions { public MacOSXSocketOptions() { @@ -116,13 +114,6 @@ UnixDomainPrincipal getSoPeerCred(int fd) throws SocketException { private static native boolean ipDontFragmentSupported0(); static { - if (System.getSecurityManager() == null) { - System.loadLibrary("extnet"); - } else { - AccessController.doPrivileged((PrivilegedAction<Void>) () -> { - System.loadLibrary("extnet"); - return null; - }); - } + System.loadLibrary("extnet"); } } diff --git a/src/jdk.net/share/classes/jdk/nio/Channels.java b/src/jdk.net/share/classes/jdk/nio/Channels.java index fbbbaa2b3a4..fa15cf189fd 100644 --- a/src/jdk.net/share/classes/jdk/nio/Channels.java +++ b/src/jdk.net/share/classes/jdk/nio/Channels.java @@ -148,13 +148,6 @@ public static SelectableChannel readWriteSelectableChannel(FileDescriptor fd, if (!fd.valid()) throw new IllegalArgumentException("file descriptor is not valid"); - @SuppressWarnings("removal") - SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - sm.checkRead(fd); - sm.checkWrite(fd); - } - SelectorProvider provider = SelectorProvider.provider(); if (!(provider instanceof SelectorProviderImpl)) throw new UnsupportedOperationException("custom SelectorProvider"); diff --git a/src/jdk.net/windows/classes/jdk/net/WindowsSocketOptions.java b/src/jdk.net/windows/classes/jdk/net/WindowsSocketOptions.java index f5f69e20517..ad824168e79 100644 --- a/src/jdk.net/windows/classes/jdk/net/WindowsSocketOptions.java +++ b/src/jdk.net/windows/classes/jdk/net/WindowsSocketOptions.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,12 +25,10 @@ package jdk.net; import java.net.SocketException; -import java.security.AccessController; -import java.security.PrivilegedAction; import jdk.net.ExtendedSocketOptions.PlatformSocketOptions; -@SuppressWarnings({"removal", "restricted"}) +@SuppressWarnings("restricted") class WindowsSocketOptions extends PlatformSocketOptions { public WindowsSocketOptions() { @@ -97,13 +95,6 @@ int getTcpKeepAliveIntvl(int fd) throws SocketException { private static native int getTcpKeepAliveIntvl0(int fd) throws SocketException; static { - if (System.getSecurityManager() == null) { - System.loadLibrary("extnet"); - } else { - AccessController.doPrivileged((PrivilegedAction<Void>) () -> { - System.loadLibrary("extnet"); - return null; - }); - } + System.loadLibrary("extnet"); } } From 93aa7e2fcf87c4dc62de4ea71be543ee677b11be Mon Sep 17 00:00:00 2001 From: Richard Reingruber <rrich@openjdk.org> Date: Thu, 21 Nov 2024 06:57:09 +0000 Subject: [PATCH 148/311] 8328085: C2: Use after free in PhaseChaitin::Register_Allocate() Reviewed-by: thartmann, mdoerr --- src/hotspot/share/opto/postaloc.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/hotspot/share/opto/postaloc.cpp b/src/hotspot/share/opto/postaloc.cpp index ac91d8a775e..2c1d0098b78 100644 --- a/src/hotspot/share/opto/postaloc.cpp +++ b/src/hotspot/share/opto/postaloc.cpp @@ -402,7 +402,6 @@ bool PhaseChaitin::eliminate_copy_of_constant(Node* val, Node* n, // as they get encountered with the merge node and keep adding these defs to the merge inputs. void PhaseChaitin::merge_multidefs() { Compile::TracePhase tp(_t_mergeMultidefs); - ResourceMark rm; // Keep track of the defs seen in registers and collect their uses in the block. RegToDefUseMap reg2defuse(_max_reg, _max_reg, RegDefUse()); for (uint i = 0; i < _cfg.number_of_blocks(); i++) { From 5ccd5106e023dbb47473e8914035c811e0cc6ee1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Galder=20Zamarre=C3=B1o?= <galder@openjdk.org> Date: Thu, 21 Nov 2024 09:48:08 +0000 Subject: [PATCH 149/311] 8326369: Add test to verify bimorphic inlining happens after morphism changes Reviewed-by: thartmann, epeter --- ...orphicVirtualCallAfterMorphismChanged.java | 115 ++++++++++++++++++ 1 file changed, 115 insertions(+) create mode 100644 test/hotspot/jtreg/compiler/inlining/InlineBimorphicVirtualCallAfterMorphismChanged.java diff --git a/test/hotspot/jtreg/compiler/inlining/InlineBimorphicVirtualCallAfterMorphismChanged.java b/test/hotspot/jtreg/compiler/inlining/InlineBimorphicVirtualCallAfterMorphismChanged.java new file mode 100644 index 00000000000..2f6f7f20d9d --- /dev/null +++ b/test/hotspot/jtreg/compiler/inlining/InlineBimorphicVirtualCallAfterMorphismChanged.java @@ -0,0 +1,115 @@ +/* + * Copyright (c) 2024, Red Hat, Inc. All rights reserved. + * Copyright (c) 2024, JetBrains s.r.o.. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * @test + * @bug 8339299 + * @summary C2 doesn't perform bimorphic inlining on a call site that was monomorphic during tier 3 compilation. + * @modules java.base/jdk.internal.misc + * @library /test/lib + * @requires vm.flagless + * + * @run driver compiler.inlining.InlineBimorphicVirtualCallAfterMorphismChanged + */ + +package compiler.inlining; + +import jdk.test.lib.process.OutputAnalyzer; +import jdk.test.lib.process.ProcessTools; + +public class InlineBimorphicVirtualCallAfterMorphismChanged { + public static abstract class AbstractBase { + public final int callSiteHolder() { + return inlinee(); + } + + public abstract int inlinee(); + + public static void main(String[] args) { + AbstractBase[] classes = new AbstractBase[] { firstInstance() }; + // first step: trigger a compilation while call site is monomorphic + for (int i = 0; i < 10000; i++) { + for (AbstractBase instance : classes) { + instance.callSiteHolder(); + } + } + + // second step: trigger recompilation by loading a second instance, + // also make the call site bimorphic + classes = new AbstractBase[] { firstInstance(), secondInstance() }; + for (int i = 0; i < 10000; i++) { + for (AbstractBase instance : classes) { + instance.callSiteHolder(); + } + } + } + + private static AbstractBase firstInstance() { + return new FirstClass(); + } + + private static AbstractBase secondInstance() { + return new SecondClass(); + } + } + + public final static class FirstClass extends AbstractBase { + public int inlinee() { + return 1; + } + } + + public final static class SecondClass extends AbstractBase { + public int inlinee() { + return 2; + }; + } + + public static void main(String[] args) throws Exception { + test("-XX:-TieredCompilation"); + test("-XX:+TieredCompilation"); + } + + private static void test(String option) throws Exception { + ProcessBuilder pb = ProcessTools.createLimitedTestJavaProcessBuilder( + "-server", "-XX:+UnlockDiagnosticVMOptions", "-XX:+PrintInlining", + "-XX:CompileCommand=compileonly,*::callSiteHolder", option, + AbstractBase.class.getName() + ); + + OutputAnalyzer analyzer = new OutputAnalyzer(pb.start()); + analyzer.shouldHaveExitValue(0); + + String re = ".*AbstractBase::inlinee.+virtual call.*"; + boolean virtualInliningFailed = analyzer.asLines().stream() + .anyMatch(s -> s.matches(re)); + + if (virtualInliningFailed) { + analyzer.outputTo(System.out); + throw new Exception( + "Bimorphic virtual call was not inlined with '" + option + "'" + ); + } + } +} From f2b10c6c228f7be879b3f043accb22e0bc6535d6 Mon Sep 17 00:00:00 2001 From: Axel Boldt-Christmas <aboldtch@openjdk.org> Date: Thu, 21 Nov 2024 09:54:25 +0000 Subject: [PATCH 150/311] 8340422: ZGC: TestAllocateHeapAt.java should not run with transparent hugepages Reviewed-by: stefank, jsikstro --- test/hotspot/jtreg/gc/z/TestAllocateHeapAt.java | 11 +++++++++++ .../os/THPsInThreadStackPreventionTest.java | 3 +++ .../os/TestHugePageDecisionsAtVMStartup.java | 2 ++ .../jtreg/runtime/os/TestHugePageDetection.java | 2 ++ test/jtreg-ext/requires/VMProps.java | 1 + .../lib/os/linux}/HugePageConfiguration.java | 17 ++++++++++++++--- 6 files changed, 33 insertions(+), 3 deletions(-) rename test/{hotspot/jtreg/runtime/os => lib/jdk/test/lib/os/linux}/HugePageConfiguration.java (96%) diff --git a/test/hotspot/jtreg/gc/z/TestAllocateHeapAt.java b/test/hotspot/jtreg/gc/z/TestAllocateHeapAt.java index dbcca704fab..f960ac3a547 100644 --- a/test/hotspot/jtreg/gc/z/TestAllocateHeapAt.java +++ b/test/hotspot/jtreg/gc/z/TestAllocateHeapAt.java @@ -27,13 +27,17 @@ * @test TestAllocateHeapAt * @requires vm.gc.Z & os.family == "linux" * @requires !vm.opt.final.UseLargePages + * @requires !vm.opt.final.UseTransparentHugePages * @summary Test ZGC with -XX:AllocateHeapAt * @library /test/lib * @run main/othervm gc.z.TestAllocateHeapAt . true * @run main/othervm gc.z.TestAllocateHeapAt non-existing-directory false */ +import jdk.test.lib.os.linux.HugePageConfiguration; +import jdk.test.lib.os.linux.HugePageConfiguration.ShmemTHPMode; import jdk.test.lib.process.ProcessTools; +import jtreg.SkippedException; public class TestAllocateHeapAt { public static void main(String[] args) throws Exception { @@ -42,6 +46,13 @@ public static void main(String[] args) throws Exception { final String heapBackingFile = "Heap Backing File: " + directory; final String failedToCreateFile = "Failed to create file " + directory; + final HugePageConfiguration hugePageConfiguration = HugePageConfiguration.readFromOS(); + final ShmemTHPMode mode = hugePageConfiguration.getShmemThpMode(); + + if (mode != ShmemTHPMode.never && mode != ShmemTHPMode.advise) { + throw new SkippedException("The UseTransparentHugePages option may not be respected with Shmem THP Mode: " + mode.name()); + } + ProcessTools.executeTestJava( "-XX:+UseZGC", "-Xlog:gc*", diff --git a/test/hotspot/jtreg/runtime/os/THPsInThreadStackPreventionTest.java b/test/hotspot/jtreg/runtime/os/THPsInThreadStackPreventionTest.java index 519bcc94b01..02fb77bf242 100644 --- a/test/hotspot/jtreg/runtime/os/THPsInThreadStackPreventionTest.java +++ b/test/hotspot/jtreg/runtime/os/THPsInThreadStackPreventionTest.java @@ -45,10 +45,13 @@ * @requires os.family == "linux" * @requires vm.debug * @requires os.arch=="amd64" | os.arch=="x86_64" | os.arch=="aarch64" + * @library /test/lib * @modules java.base/jdk.internal.misc * java.management * @run main/manual THPsInThreadStackPreventionTest PATCH-DISABLED */ + +import jdk.test.lib.os.linux.HugePageConfiguration; import jdk.test.lib.process.OutputAnalyzer; import jdk.test.lib.process.ProcessTools; import jtreg.SkippedException; diff --git a/test/hotspot/jtreg/runtime/os/TestHugePageDecisionsAtVMStartup.java b/test/hotspot/jtreg/runtime/os/TestHugePageDecisionsAtVMStartup.java index daf1269e7ab..2def134b9d3 100644 --- a/test/hotspot/jtreg/runtime/os/TestHugePageDecisionsAtVMStartup.java +++ b/test/hotspot/jtreg/runtime/os/TestHugePageDecisionsAtVMStartup.java @@ -47,11 +47,13 @@ * @summary Test JVM large page setup (+THP) * @library /test/lib * @requires os.family == "linux" + * @library /test/lib * @modules java.base/jdk.internal.misc * java.management * @run driver TestHugePageDecisionsAtVMStartup -XX:+UseTransparentHugePages */ +import jdk.test.lib.os.linux.HugePageConfiguration; import jdk.test.lib.process.OutputAnalyzer; import jdk.test.lib.process.ProcessTools; import java.util.ArrayList; diff --git a/test/hotspot/jtreg/runtime/os/TestHugePageDetection.java b/test/hotspot/jtreg/runtime/os/TestHugePageDetection.java index 2e2d9092c74..7231f30ed41 100644 --- a/test/hotspot/jtreg/runtime/os/TestHugePageDetection.java +++ b/test/hotspot/jtreg/runtime/os/TestHugePageDetection.java @@ -28,12 +28,14 @@ * @library /test/lib * @requires vm.flagless * @requires os.family == "linux" + * @library /test/lib * @modules java.base/jdk.internal.misc * java.management * @run driver TestHugePageDetection */ import java.util.*; +import jdk.test.lib.os.linux.HugePageConfiguration; import jdk.test.lib.process.OutputAnalyzer; import jdk.test.lib.process.ProcessTools; diff --git a/test/jtreg-ext/requires/VMProps.java b/test/jtreg-ext/requires/VMProps.java index 5544ad1bebd..f5dcb44db2b 100644 --- a/test/jtreg-ext/requires/VMProps.java +++ b/test/jtreg-ext/requires/VMProps.java @@ -378,6 +378,7 @@ protected void vmOptFinalFlags(SafeMap map) { vmOptFinalFlag(map, "UnlockExperimentalVMOptions"); vmOptFinalFlag(map, "UseCompressedOops"); vmOptFinalFlag(map, "UseLargePages"); + vmOptFinalFlag(map, "UseTransparentHugePages"); vmOptFinalFlag(map, "UseVectorizedMismatchIntrinsic"); } diff --git a/test/hotspot/jtreg/runtime/os/HugePageConfiguration.java b/test/lib/jdk/test/lib/os/linux/HugePageConfiguration.java similarity index 96% rename from test/hotspot/jtreg/runtime/os/HugePageConfiguration.java rename to test/lib/jdk/test/lib/os/linux/HugePageConfiguration.java index adde51ec75f..0bb6db16021 100644 --- a/test/hotspot/jtreg/runtime/os/HugePageConfiguration.java +++ b/test/lib/jdk/test/lib/os/linux/HugePageConfiguration.java @@ -22,6 +22,8 @@ * questions. */ +package jdk.test.lib.os.linux; + import jdk.test.lib.process.OutputAnalyzer; import java.io.*; @@ -33,7 +35,7 @@ // - a) the Operating System (the truth) // - b) the JVM log (-Xlog:pagesize) // This is used e.g. in TestHugePageDetection to determine if the JVM detects the correct settings from the OS. -class HugePageConfiguration { +public class HugePageConfiguration { public static class ExplicitHugePageConfig implements Comparable<ExplicitHugePageConfig> { public long pageSize = -1; @@ -63,11 +65,11 @@ public int compareTo(ExplicitHugePageConfig o) { Set<ExplicitHugePageConfig> _explicitHugePageConfigurations; long _explicitDefaultHugePageSize = -1; - enum THPMode {always, never, madvise} + public enum THPMode {always, never, madvise} THPMode _thpMode; long _thpPageSize; - enum ShmemTHPMode {always, within_size, advise, never, deny, force, unknown} + public enum ShmemTHPMode {always, within_size, advise, never, deny, force, unknown} ShmemTHPMode _shmemThpMode; public Set<ExplicitHugePageConfig> getExplicitHugePageConfigurations() { @@ -133,6 +135,15 @@ public String toString() { '}'; } + @Override + public int hashCode() { + return Objects.hash(_explicitDefaultHugePageSize, + _thpPageSize, + _explicitHugePageConfigurations, + _thpMode, + _shmemThpMode); + } + @Override public boolean equals(Object o) { if (this == o) return true; From 18df6fd5ba93c3c2d5965c072d482dcf7cbfc675 Mon Sep 17 00:00:00 2001 From: Doug Lea <dl@openjdk.org> Date: Thu, 21 Nov 2024 11:50:46 +0000 Subject: [PATCH 151/311] 8336707: Contention of ForkJoinPool grows when stealing works Reviewed-by: vklang --- .../java/util/concurrent/ForkJoinPool.java | 729 ++++++++++-------- .../util/concurrent/ForkJoinWorkerThread.java | 35 +- 2 files changed, 420 insertions(+), 344 deletions(-) diff --git a/src/java.base/share/classes/java/util/concurrent/ForkJoinPool.java b/src/java.base/share/classes/java/util/concurrent/ForkJoinPool.java index ee2f85249d7..0f9ccbf6284 100644 --- a/src/java.base/share/classes/java/util/concurrent/ForkJoinPool.java +++ b/src/java.base/share/classes/java/util/concurrent/ForkJoinPool.java @@ -259,10 +259,7 @@ public class ForkJoinPool extends AbstractExecutorService { * (http://www.di.ens.fr/~zappa/readings/ppopp13.pdf) for an * analysis of memory ordering requirements in work-stealing * algorithms similar to the one used here. We use per-operation - * ordered writes of various kinds for updates, but usually use - * explicit load fences for reads, to cover access of several - * fields of possibly several objects without further constraining - * read-by-read ordering. + * ordered writes of various kinds for accesses when required. * * We also support a user mode in which local task processing is * in FIFO, not LIFO order, simply by using a local version of @@ -302,8 +299,7 @@ public class ForkJoinPool extends AbstractExecutorService { * * * Slot k must be read with an acquiring read, which it must * anyway to dereference and run the task if the (acquiring) - * CAS succeeds, but uses an explicit acquire fence to support - * the following rechecks even if the CAS is not attempted. + * CAS succeeds. * * * q.base may change between reading and using its value to * index the slot. To avoid trying to use the wrong t, the @@ -410,7 +406,11 @@ public class ForkJoinPool extends AbstractExecutorService { * * Field "runState" and per-WorkQueue field "phase" play similar * roles, as lockable, versioned counters. Field runState also - * includes monotonic event bits (SHUTDOWN, STOP, and TERMINATED). + * includes monotonic event bits: + * * SHUTDOWN: no more external tasks accepted; STOP when quiescent + * * STOP: no more tasks run, and deregister all workers + * * CLEANED: all unexecuted tasks have been cancelled + * * TERMINATED: all workers deregistered and all queues cleaned * The version tags enable detection of state changes (by * comparing two reads) modulo bit wraparound. The bit range in * each case suffices for purposes of determining quiescence, @@ -546,22 +546,27 @@ public class ForkJoinPool extends AbstractExecutorService { * * If computations are purely tree structured, it suffices for * every worker to activate another when it pushes a task into * an empty queue, resulting in O(log(#threads)) steps to full - * activation. Emptiness must be conservatively approximated - * (by checking if there is apparently at most one existing - * task) which may result in unnecessary signals. Also, to - * reduce resource usages in some cases, at the expense of - * slower startup in others, activation of an idle thread is - * preferred over creating a new one, here and elsewhere. + * activation. Emptiness must be conservatively approximated, + * which may result in unnecessary signals. Also, to reduce + * resource usages in some cases, at the expense of slower + * startup in others, activation of an idle thread is preferred + * over creating a new one, here and elsewhere. * * * At the other extreme, if "flat" tasks (those that do not in * turn generate others) come in serially from only a single - * producer, each worker taking its first (since the last - * activation) task from a queue should propagate a signal if - * there are more tasks in that queue. This is equivalent to, - * but generally faster than, arranging the stealer take - * multiple tasks, re-pushing one or more on its own queue, and - * signalling (because its queue is empty), also resulting in - * logarithmic full activation time. + * producer, each worker taking a task from a queue should + * propagate a signal if there are more tasks in that + * queue. This is equivalent to, but generally faster than, + * arranging the stealer take multiple tasks, re-pushing one or + * more on its own queue, and signalling (because its queue is + * empty), also resulting in logarithmic full activation + * time. If tasks do not not engage in unbounded loops based on + * the actions of other workers with unknown dependencies loop, + * this form of proagation can be limited to one signal per + * activation (phase change). We distinguish the cases by + * further signalling only if the task is an InterruptibleTask + * (see below), which are the only supported forms of task that + * may do so. * * * Because we don't know about usage patterns (or most commonly, * mixtures), we use both approaches, which present even more @@ -611,9 +616,12 @@ public class ForkJoinPool extends AbstractExecutorService { * it tries to deactivate()), giving up (and rescanning) on "ctl" * contention. To avoid missed signals during deactivation, the * method rescans and reactivates if there may have been a missed - * signal during deactivation. Because idle workers are often not - * yet blocked (parked), we use a WorkQueue field to advertise - * that a waiter actually needs unparking upon signal. + * (external) signal during deactivation. To reduce false-alarm + * reactivations while doing so, we scan multiple times + * (analogously to method quiescent()) before trying to + * reactivate. Because idle workers are often not yet blocked + * (parked), we use a WorkQueue field to advertise that a waiter + * actually needs unparking upon signal. * * Quiescence. Workers scan looking for work, giving up when they * don't find any, without being sure that none are available. @@ -644,22 +652,36 @@ public class ForkJoinPool extends AbstractExecutorService { * workers are inactive because the caller and any others * executing helpQuiesce are not included in counts. * - * Termination. A call to shutdownNow invokes tryTerminate to - * atomically set a runState mode bit. However, the process of - * termination is intrinsically non-atomic. The calling thread, as - * well as other workers thereafter terminating help cancel queued - * tasks and interrupt other workers. These actions race with - * unterminated workers. By default, workers check for - * termination only when accessing pool state. This may take a - * while but suffices for structured computational tasks. But not - * necessarily for others. Class InterruptibleTask (see below) - * further arranges runState checks before executing task bodies, - * and ensures interrupts while terminating. Even so, there are no - * guarantees after an abrupt shutdown that remaining tasks - * complete normally or exceptionally or are cancelled. - * Termination may fail to complete if running tasks ignore both - * task status and interrupts and/or produce more tasks after - * others that could cancel them have exited. + * Termination. Termination is initiated by setting STOP in one of + * three ways (via methods tryTerminate and quiescent): + * * A call to shutdownNow, in which case all workers are + * interrupted, first ensuring that the queues array is stable, + * to avoid missing any workers. + * * A call to shutdown when quiescent, in which case method + * releaseWaiters is used to dequeue them, at which point they notice + * STOP state and return from runWorker to deregister(); + * * The pool becomes quiescent() sometime after shutdown has + * been called, in which case releaseWaiters is also used to + * propagate as they deregister. + * Upon STOP, each worker, as well as external callers to + * tryTerminate (via close() etc) race to set CLEANED, indicating + * that all tasks have been cancelled. The implementation (method + * cleanQueues) balances cases in which there may be many tasks to + * cancel (benefitting from parallelism) versus contention and + * interference when many threads try to poll remaining queues, + * while also avoiding unnecessary rechecks, by using + * pseudorandom scans and giving up upon interference. This may be + * retried by the same caller only when there are no more + * registered workers, using the same criteria as method + * quiescent. When CLEANED and all workers have deregistered, + * TERMINATED is set, also signalling any caller of + * awaitTermination or close. Because shutdownNow-based + * termination relies on interrupts, there is no guarantee that + * workers will stop if their tasks ignore interrupts. Class + * InterruptibleTask (see below) further arranges runState checks + * before executing task bodies, and ensures interrupts while + * terminating. Even so, there are no guarantees because tasks may + * internally enter unbounded loops. * * Trimming workers. To release resources after periods of lack of * use, a worker starting to wait when the pool is quiescent will @@ -819,10 +841,11 @@ public class ForkJoinPool extends AbstractExecutorService { * overridden by system properties, we use workers of subclass * InnocuousForkJoinWorkerThread when there is a SecurityManager * present. These workers have no permissions set, do not belong - * to any user-defined ThreadGroup, and clear all ThreadLocals - * after executing any top-level task. The associated mechanics - * may be JVM-dependent and must access particular Thread class - * fields to achieve this effect. + * to any user-defined ThreadGroup, and clear all ThreadLocals and + * reset the ContextClassLoader before (re)activating to execute + * top-level task. The associated mechanics may be JVM-dependent + * and must access particular Thread class fields to achieve this + * effect. * * InterruptibleTasks * ==================== @@ -844,7 +867,9 @@ public class ForkJoinPool extends AbstractExecutorService { * shutdown, runners are interrupted so they can cancel. Since * external joining callers never run these tasks, they must await * cancellation by others, which can occur along several different - * paths. + * paths. The inability to rely on caller-runs may also require + * extra signalling (resulting in scanning and contention) so is + * done only conditionally in methods push and runworker. * * Across these APIs, rules for reporting exceptions for tasks * with results accessed via join() differ from those via get(), @@ -904,10 +929,8 @@ public class ForkJoinPool extends AbstractExecutorService { * direct false-sharing and indirect cases due to GC bookkeeping * (cardmarks etc), and reduce the number of resizes, which are * not especially fast because they require atomic transfers. - * Currently, arrays for workers are initialized to be just large - * enough to avoid resizing in most tree-structured tasks, but - * larger for external queues where both false-sharing problems - * and the need for resizing are more common. (Maintenance note: + * Currently, arrays are initialized to be just large enough to + * avoid resizing in most tree-structured tasks. (Maintenance note: * any changes in fields, queues, or their uses, or JVM layout * policies, must be accompanied by re-evaluation of these * placement and sizing decisions.) @@ -996,12 +1019,6 @@ public class ForkJoinPool extends AbstractExecutorService { */ static final int INITIAL_QUEUE_CAPACITY = 1 << 6; - /** - * Initial capacity of work-stealing queue array for external queues. - * Must be a power of two, at least 2. See above. - */ - static final int INITIAL_EXTERNAL_QUEUE_CAPACITY = 1 << 9; - // conversions among short, int, long static final int SMASK = 0xffff; // (unsigned) short bits static final long LMASK = 0xffffffffL; // lower 32 bits of long @@ -1015,8 +1032,9 @@ public class ForkJoinPool extends AbstractExecutorService { // pool.runState bits static final long STOP = 1L << 0; // terminating static final long SHUTDOWN = 1L << 1; // terminate when quiescent - static final long TERMINATED = 1L << 2; // only set if STOP also set - static final long RS_LOCK = 1L << 3; // lowest seqlock bit + static final long CLEANED = 1L << 2; // stopped and queues cleared + static final long TERMINATED = 1L << 3; // only set if STOP also set + static final long RS_LOCK = 1L << 4; // lowest seqlock bit // spin/sleep limits for runState locking and elsewhere static final int SPIN_WAITS = 1 << 7; // max calls to onSpinWait @@ -1246,9 +1264,7 @@ final boolean tryLockPhase() { // seqlock acquire */ WorkQueue(ForkJoinWorkerThread owner, int id, int cfg, boolean clearThreadLocals) { - array = new ForkJoinTask<?>[owner == null ? - INITIAL_EXTERNAL_QUEUE_CAPACITY : - INITIAL_QUEUE_CAPACITY]; + array = new ForkJoinTask<?>[INITIAL_QUEUE_CAPACITY]; this.owner = owner; this.config = (clearThreadLocals) ? cfg | CLEAR_TLS : cfg; } @@ -1294,10 +1310,12 @@ final void push(ForkJoinTask<?> task, ForkJoinPool pool, unlockPhase(); if (room < 0) throw new RejectedExecutionException("Queue capacity exceeded"); - else if ((room == 0 || - a[m & (s - 2)] == null) && // at most one existing task - pool != null) - pool.signalWork(); + if ((room == 0 || // pad for InterruptibleTasks + a[m & (s - ((internal || task == null || + task.getClass().getSuperclass() != + interruptibleTaskClass) ? 1 : 2))] == null) && + pool != null) + pool.signalWork(); // may have appeared empty } } @@ -1351,10 +1369,8 @@ a, slotOffset(m & b), null)) != null) { updateBase(nb); break; } - while (b == (b = base)) { - U.loadFence(); + while (b == (b = U.getIntAcquire(this, BASE))) Thread.onSpinWait(); // spin to reduce memory traffic - } if (p - b <= 0) break; } @@ -1378,12 +1394,12 @@ final ForkJoinTask<?> nextLocalTask() { final boolean tryUnpush(ForkJoinTask<?> task, boolean internal) { boolean taken = false; ForkJoinTask<?>[] a = array; - int p = top, s = p - 1, cap, k; + int p = top, s = p - 1, cap; long k; if (a != null && (cap = a.length) > 0 && - a[k = (cap - 1) & s] == task && + U.getReference(a, k = slotOffset((cap - 1) & s)) == task && (internal || tryLockPhase())) { if (top == p && - U.compareAndSetReference(a, slotOffset(k), task, null)) { + U.compareAndSetReference(a, k, task, null)) { taken = true; updateTop(s); } @@ -1417,28 +1433,25 @@ final ForkJoinTask<?> peek() { * Polls for a task. Used only by non-owners. */ final ForkJoinTask<?> poll() { - for (int b = base;;) { - int cap, k, nb; ForkJoinTask<?>[] a; + for (int pb = -1, b; ; pb = b) { // track progress + ForkJoinTask<?> t; int cap, nb; long k; ForkJoinTask<?>[] a; if ((a = array) == null || (cap = a.length) <= 0) break; - long kp = slotOffset(k = (cap - 1) & b); - int nk = (nb = b + 1) & (cap - 1); // next slot - int sk = (b + 2) & (cap - 1); // 2nd slot ahead - ForkJoinTask<?> t = a[k]; - U.loadFence(); - if (b == (b = base)) { // else inconsistent - if (t != null) { - if (U.compareAndSetReference(a, kp, t, null)) { - updateBase(nb); - return t; - } - b = base; - } - else if (a[sk] == null && a[nk] == null && a[k] == null) { - if (top - b <= 0) - break; // empty + t = (ForkJoinTask<?>)U.getReferenceAcquire( + a, k = slotOffset((cap - 1) & (b = base))); + Object u = U.getReference( // next slot + a, slotOffset((cap - 1) & (nb = b + 1))); + if (base != b) // inconsistent + ; + else if (t == null) { + if (u == null && top - b <= 0) + break; // empty + if (pb == b) Thread.onSpinWait(); // stalled - } + } + else if (U.compareAndSetReference(a, k, t, null)) { + updateBase(nb); + return t; } } return null; @@ -1449,14 +1462,11 @@ else if (a[sk] == null && a[nk] == null && a[k] == null) { /** * Runs the given task, as well as remaining local tasks. */ - final void topLevelExec(ForkJoinTask<?> task, int cfg) { - int fifo = cfg & FIFO; + final void topLevelExec(ForkJoinTask<?> task, int fifo) { while (task != null) { task.doExec(); task = nextLocalTask(fifo); } - if ((cfg & CLEAR_TLS) != 0) - ThreadLocalRandom.eraseThreadLocals(Thread.currentThread()); } /** @@ -1468,23 +1478,24 @@ final void tryRemoveAndExec(ForkJoinTask<?> task, boolean internal) { int b = base, p = top, s = p - 1, d = p - b, cap; if (a != null && (cap = a.length) > 0) { for (int m = cap - 1, i = s; d > 0; --i, --d) { - ForkJoinTask<?> t; int k; boolean taken; - if ((t = a[k = i & m]) == null) + long k; boolean taken; + ForkJoinTask<?> t = (ForkJoinTask<?>)U.getReference( + a, k = slotOffset(i & m)); + if (t == null) break; if (t == task) { - long pos = slotOffset(k); if (!internal && !tryLockPhase()) break; // fail if locked if (taken = (top == p && - U.compareAndSetReference(a, pos, task, null))) { + U.compareAndSetReference(a, k, task, null))) { if (i == s) // act as pop updateTop(s); else if (i == base) // act as poll updateBase(i + 1); else { // swap with top U.putReferenceVolatile( - a, pos, (ForkJoinTask<?>) + a, k, (ForkJoinTask<?>) U.getAndSetReference( a, slotOffset(s & m), null)); updateTop(s); @@ -1512,19 +1523,18 @@ final int helpComplete(ForkJoinTask<?> task, boolean internal, int limit) { int status = 0; if (task != null) { outer: for (;;) { - ForkJoinTask<?>[] a; ForkJoinTask<?> t; boolean taken; - int stat, p, s, cap, k; + ForkJoinTask<?>[] a; boolean taken; Object o; + int stat, p, s, cap; if ((stat = task.status) < 0) { status = stat; break; } if ((a = array) == null || (cap = a.length) <= 0) break; - if ((t = a[k = (cap - 1) & (s = (p = top) - 1)]) == null) + long k = slotOffset((cap - 1) & (s = (p = top) - 1)); + if (!((o = U.getReference(a, k)) instanceof CountedCompleter)) break; - if (!(t instanceof CountedCompleter)) - break; - CountedCompleter<?> f = (CountedCompleter<?>)t; + CountedCompleter<?> t = (CountedCompleter<?>)o, f = t; for (int steps = cap;;) { // bound path if (f == task) break; @@ -1535,7 +1545,7 @@ final int helpComplete(ForkJoinTask<?> task, boolean internal, int limit) { break; if (taken = (top == p && - U.compareAndSetReference(a, slotOffset(k), t, null))) + U.compareAndSetReference(a, k, t, null))) updateTop(s); if (!internal) unlockPhase(); @@ -1557,11 +1567,11 @@ final int helpComplete(ForkJoinTask<?> task, boolean internal, int limit) { */ final void helpAsyncBlocker(ManagedBlocker blocker) { for (;;) { - ForkJoinTask<?>[] a; int b, cap, k; + ForkJoinTask<?> t; ForkJoinTask<?>[] a; int b, cap; long k; if ((a = array) == null || (cap = a.length) <= 0) break; - ForkJoinTask<?> t = a[k = (b = base) & (cap - 1)]; - U.loadFence(); + t = (ForkJoinTask<?>)U.getReferenceAcquire( + a, k = slotOffset((cap - 1) & (b = base))); if (t == null) { if (top - b <= 0) break; @@ -1572,7 +1582,7 @@ else if (!(t instanceof CompletableFuture if (blocker != null && blocker.isReleasable()) break; if (base == b && t != null && - U.compareAndSetReference(a, slotOffset(k), t, null)) { + U.compareAndSetReference(a, k, t, null)) { updateBase(b + 1); t.doExec(); } @@ -1581,6 +1591,18 @@ else if (!(t instanceof CompletableFuture // misc + /** + * Cancels all local tasks. Called only by owner. + */ + final void cancelTasks() { + for (ForkJoinTask<?> t; (t = nextLocalTask(0)) != null; ) { + try { + t.cancel(false); + } catch (Throwable ignore) { + } + } + } + /** * Returns true if internal and not known to be blocked. */ @@ -1630,6 +1652,16 @@ final boolean isApparentlyUnblocked() { */ static volatile RuntimePermission modifyThreadPermission; + /** + * Cached for faster type tests. + */ + static final Class<?> interruptibleTaskClass; + + /** + * For VirtualThread intrinsics + */ + private static final JavaLangAccess JLA; + // fields declared in order of their likely layout on most VMs volatile CountDownLatch termination; // lazily constructed final Predicate<? super ForkJoinPool> saturate; @@ -1773,7 +1805,7 @@ final String nextWorkerThreadName() { * @param w caller's WorkQueue */ final void registerWorker(WorkQueue w) { - if (w != null) { + if (w != null && (runState & STOP) == 0L) { ThreadLocalRandom.localInit(); int seed = w.stackPred = ThreadLocalRandom.getProbe(); int phaseSeq = seed & ~((IDLE << 1) - 1); // initial phase tag @@ -1824,49 +1856,35 @@ final void registerWorker(WorkQueue w) { * @param ex the exception causing failure, or null if none */ final void deregisterWorker(ForkJoinWorkerThread wt, Throwable ex) { - if ((runState & STOP) != 0L) // ensure released - releaseAll(); - WorkQueue w = null; - int src = 0, phase = 0; - boolean replaceable = false; - if (wt != null && (w = wt.workQueue) != null) { - phase = w.phase; - if ((src = w.source) != DROPPED) { - w.source = DROPPED; // else already dropped - if (phase != 0) { // else failed to start - replaceable = true; - if (w.top - w.base > 0) { - ForkJoinTask<?> t; // cancel remaining tasks - while ((t = w.nextLocalTask()) != null) { - try { - t.cancel(false); - } catch (Throwable ignore) { - } - } - } - } - } - } - if (src != DROPPED) { // decrement counts - long c = ctl; + WorkQueue w = null; // null if not created + int phase = 0; // 0 if not registered + if (wt != null && (w = wt.workQueue) != null && + (phase = w.phase) != 0 && (phase & IDLE) != 0) + releaseWaiters(); // ensure released + if (w == null || w.source != DROPPED) { + long c = ctl; // decrement counts do {} while (c != (c = compareAndExchangeCtl( c, ((RC_MASK & (c - RC_UNIT)) | (TC_MASK & (c - TC_UNIT)) | (LMASK & c))))); } - if ((tryTerminate(false, false) & STOP) == 0L && w != null) { - WorkQueue[] qs; int n, i; // remove index unless terminating + if (phase != 0 && w != null) { // remove index unless terminating long ns = w.nsteals & 0xffffffffL; - if ((lockRunState() & STOP) != 0L) - replaceable = false; - else if ((qs = queues) != null && (n = qs.length) > 0 && - qs[i = phase & SMASK & (n - 1)] == w) { - qs[i] = null; - stealCount += ns; // accumulate steals + if ((runState & STOP) == 0L) { + WorkQueue[] qs; int n, i; + if ((lockRunState() & STOP) == 0L && + (qs = queues) != null && (n = qs.length) > 0 && + qs[i = phase & SMASK & (n - 1)] == w) { + qs[i] = null; + stealCount += ns; // accumulate steals + } + unlockRunState(); } - unlockRunState(); - if (replaceable) - signalWork(); + } + if ((tryTerminate(false, false) & STOP) == 0L && + phase != 0 && w != null && w.source != DROPPED) { + signalWork(); // possibly replace + w.cancelTasks(); // clean queue } if (ex != null) ForkJoinTask.rethrow(ex); @@ -1912,12 +1930,9 @@ else if ((v = w) == null) /** * Releases all waiting workers. Called only during shutdown. - * - * @return current ctl */ - private long releaseAll() { - long c = ctl; - for (;;) { + private void releaseWaiters() { + for (long c = ctl;;) { WorkQueue[] qs; WorkQueue v; int sp, i; if ((sp = (int)c) == 0 || (qs = queues) == null || qs.length <= (i = sp & SMASK) || (v = qs[i]) == null) @@ -1930,7 +1945,6 @@ private long releaseAll() { U.unpark(v.owner); } } - return c; } /** @@ -1940,7 +1954,7 @@ private long releaseAll() { * unlocked; if so, setting STOP if shutdown is enabled */ private int quiescent() { - outer: for (;;) { + for (;;) { long phaseSum = 0L; boolean swept = false; for (long e, prevRunState = 0L; ; prevRunState = e) { @@ -1983,64 +1997,61 @@ else if (compareAndSetCtl(c, c) && casRunState(e, e | STOP)) final void runWorker(WorkQueue w) { if (w != null) { int phase = w.phase, r = w.stackPred; // seed from registerWorker - int cfg = w.config, src = -1, nsteals = 0; - rescan: for (boolean scanned = false;;) { + int fifo = w.config & FIFO, nsteals = 0, src = -1; + for (;;) { WorkQueue[] qs; r ^= r << 13; r ^= r >>> 17; r ^= r << 5; // xorshift if ((runState & STOP) != 0L || (qs = queues) == null) - return; + break; int n = qs.length, i = r, step = (r >>> 16) | 1; - for (int l = n; l > 0; --l, i += step) { // scan queues - int j; WorkQueue q; - if ((q = qs[j = i & (n - 1)]) != null) { - boolean taken = false; - for (int pb = -1, b = q.base;;) { - int cap, k, nb; ForkJoinTask<?>[] a; - if ((a = q.array) == null || (cap = a.length) <= 0) - continue rescan; - long kp = slotOffset(k = (cap - 1) & b); - int nk = (nb = b + 1) & (cap - 1); // next slot - int sk = (b + 2) & (cap - 1); // 2nd slot ahead - ForkJoinTask<?> t = a[k]; - U.loadFence(); - if (b != (b = q.base)) - ; // inconsistent - else if (t == null) { // possibly empty - if (a[sk] == null && a[nk] == null && - a[k] == null) { // screen - if (q.top - b > 0) { // stalled - if (!taken) // move unless taking - continue rescan; + boolean rescan = false; + scan: for (int l = n; l > 0; --l, i += step) { // scan queues + int j, cap; WorkQueue q; ForkJoinTask<?>[] a; + if ((q = qs[j = i & (n - 1)]) != null && + (a = q.array) != null && (cap = a.length) > 0) { + for (int m = cap - 1, pb = -1, b = q.base;;) { + ForkJoinTask<?> t; long k; + t = (ForkJoinTask<?>)U.getReferenceAcquire( + a, k = slotOffset(m & b)); + if (b != (b = q.base) || t == null || + !U.compareAndSetReference(a, k, t, null)) { + if (a[b & m] == null) { + if (rescan) // end of run + break scan; + if (a[(b + 1) & m] == null && + a[(b + 2) & m] == null) { + break; // probably empty + } + if (pb == (pb = b)) { // track progress + rescan = true; // stalled; reorder scan + break scan; } - else if (taken) - continue rescan; // depleted; restart - else - break; // empty } - if (pb == (pb = b)) // base unchanged - Thread.onSpinWait(); } - else if (!U.compareAndSetReference(a, kp, t, null)) - b = q.base; // contended else { - q.base = nb; + boolean propagate; + int nb = q.base = b + 1; w.nsteals = ++nsteals; - w.source = j; // volatile write - if (taken != (taken = true) && a[nk] != null) - signalWork(); // propagate signal - w.topLevelExec(t, cfg); - if ((b = q.base) != nb && src != (src = j)) - continue rescan; // reduce interference + w.source = j; // volatile + rescan = true; + if (propagate = + ((src != (src = j) || + t.getClass().getSuperclass() == + interruptibleTaskClass) && + a[nb & m] != null)) + signalWork(); + w.topLevelExec(t, fifo); + if ((b = q.base) != nb && !propagate) + break scan; // reduce interference } } } } - if (!scanned) - scanned = true; // rescan before deactivate - else if (((phase = deactivate(w, r, phase)) & IDLE) == 0) - scanned = false; - else - return; + if (!rescan) { + if (((phase = deactivate(w, phase)) & IDLE) != 0) + break; + src = -1; // re-enable propagation + } } } } @@ -2049,56 +2060,38 @@ else if (((phase = deactivate(w, r, phase)) & IDLE) == 0) * Deactivates and if necessary awaits signal or termination. * * @param w the worker - * @param r random seed * @param phase current phase * @return current phase, with IDLE set if worker should exit */ - private int deactivate(WorkQueue w, int r, int phase) { + private int deactivate(WorkQueue w, int phase) { + if (w == null) // currently impossible + return IDLE; int p = phase | IDLE, activePhase = phase + (IDLE << 1); - if (w != null) { // always true - w.phase = p; - long pc = ctl, qc; - for (;;) { // try to enqueue - w.stackPred = (int)pc; // set ctl stack link - qc = (activePhase & LMASK) | ((pc - RC_UNIT) & UMASK); - if (pc == (pc = compareAndExchangeCtl(pc, qc))) // success - break; - if ((pc & RC_MASK) >= (qc & RC_MASK)) { - p = w.phase = phase; // back out on possible signal - break; - } - } - if (p != phase && // check quiescent termination - ((runState & SHUTDOWN) == 0L || quiescent() <= 0)) { - WorkQueue[] qs; - int spins = ((short)(qc >>> TC_SHIFT) << 1) + SPIN_WAITS + 1; - while ((p = w.phase) != activePhase && --spins > 0) - Thread.onSpinWait(); // reduce flailing - if (p != activePhase && (qs = queues) != null) { - int n = qs.length, step = (r >>> 16) | 1; - for (int i = r, l = n; l > 0; --l, i += step) { - WorkQueue q; // check for missed signals - if ((q = qs[i & (n - 1)]) != null && - q.top - q.base > 0) { - if (ctl == qc && compareAndSetCtl(qc, pc)) { - p = w.phase = activePhase; - break; // self-signal - } - if ((p = w.phase) == activePhase) - break; - } - } - if (p != activePhase) { - long delay = (((qc & RC_MASK) > 0L) ? 0L : - (w.source != INVALID_ID) ? keepAlive : - TIMEOUT_SLOP); // minimal delay if cascade - if ((p = w.phase) != activePhase) - p = awaitWork(w, p, delay); // block, drop, or exit - } - } - } + long pc = ctl, qc = (activePhase & LMASK) | ((pc - RC_UNIT) & UMASK); + w.stackPred = (int)pc; // set ctl stack link + w.phase = p; + if (!compareAndSetCtl(pc, qc)) // try to enqueue + return w.phase = phase; // back out on possible signal + int ac = (short)(qc >>> RC_SHIFT), n; long e; WorkQueue[] qs; + if (((e = runState) & STOP) != 0L || + ((e & SHUTDOWN) != 0L && ac == 0 && quiescent() > 0) || + (qs = queues) == null || (n = qs.length) <= 0) + return IDLE; // terminating + int prechecks = Math.min(ac, 2); // reactivation threshold + for (int k = Math.max(n + (n << 1), SPIN_WAITS << 1);;) { + WorkQueue q; int cap; ForkJoinTask<?>[] a; + if (w.phase == activePhase) + return activePhase; + if (--k < 0) + return awaitWork(w, p); // block, drop, or exit + if ((k & 1) != 0) + Thread.onSpinWait(); // interleave spins and rechecks + else if ((q = qs[k & (n - 1)]) != null && + (a = q.array) != null && (cap = a.length) > 0 && + a[q.base & (cap - 1)] != null && --prechecks < 0 && + ctl == qc && compareAndSetCtl(qc, pc)) + return w.phase = activePhase; // reactivate } - return p; } /** @@ -2106,33 +2099,41 @@ private int deactivate(WorkQueue w, int r, int phase) { * * @param w the work queue * @param p current phase (known to be idle) - * @param delay if nonzero keepAlive before trimming if quiescent * @return current phase, with IDLE set if worker should exit */ - private int awaitWork(WorkQueue w, int p, long delay) { + private int awaitWork(WorkQueue w, int p) { if (w != null) { + ForkJoinWorkerThread t; long deadline; + if ((w.config & CLEAR_TLS) != 0 && (t = w.owner) != null) + t.resetThreadLocals(); // clear before reactivate + if ((ctl & RC_MASK) > 0L) + deadline = 0L; + else if ((deadline = + (((w.source != INVALID_ID) ? keepAlive : TIMEOUT_SLOP)) + + System.currentTimeMillis()) == 0L) + deadline = 1L; // avoid zero int activePhase = p + IDLE; - LockSupport.setCurrentBlocker(this); - long deadline = (delay == 0L ? 0L : - delay + System.currentTimeMillis()); - w.parking = 1; // enable unpark - while ((p = w.phase) != activePhase) { - boolean trimmable = false; int trim; - Thread.interrupted(); // clear status - if ((runState & STOP) != 0L) - break; - if (deadline != 0L) { - if ((trim = tryTrim(w, p, deadline)) > 0) + if ((p = w.phase) != activePhase && (runState & STOP) == 0L) { + LockSupport.setCurrentBlocker(this); + w.parking = 1; // enable unpark + while ((p = w.phase) != activePhase) { + boolean trimmable = false; int trim; + Thread.interrupted(); // clear status + if ((runState & STOP) != 0L) break; - else if (trim < 0) - deadline = 0L; - else - trimmable = true; + if (deadline != 0L) { + if ((trim = tryTrim(w, p, deadline)) > 0) + break; + else if (trim < 0) + deadline = 0L; + else + trimmable = true; + } + U.park(trimmable, deadline); } - U.park(trimmable, deadline); + w.parking = 0; + LockSupport.setCurrentBlocker(null); } - w.parking = 0; - LockSupport.setCurrentBlocker(null); } return p; } @@ -2287,12 +2288,13 @@ final int helpJoin(ForkJoinTask<?> task, WorkQueue w, boolean internal) { int j; WorkQueue q; if ((q = qs[j = r & SMASK & (n - 1)]) != null) { for (;;) { - int sq = q.source, b, cap, k; ForkJoinTask<?>[] a; + ForkJoinTask<?> t; ForkJoinTask<?>[] a; + boolean eligible = false; + int sq = q.source, b, cap; long k; if ((a = q.array) == null || (cap = a.length) <= 0) break; - ForkJoinTask<?> t = a[k = (b = q.base) & (cap - 1)]; - U.loadFence(); - boolean eligible = false; + t = (ForkJoinTask<?>)U.getReferenceAcquire( + a, k = slotOffset((cap - 1) & (b = q.base))); if (t == task) eligible = true; else if (t != null) { // check steal chain @@ -2311,18 +2313,16 @@ else if (t != null) { // check steal chain } if ((s = task.status) < 0) break outer; // validate - if (q.source == sq && q.base == b && a[k] == t) { - int nb = b + 1, nk = nb & (cap - 1); + if (q.source == sq && q.base == b && + U.getReference(a, k) == t) { if (!eligible) { // revisit if nonempty - if (!rescan && t == null && - (a[nk] != null || q.top - b > 0)) + if (!rescan && t == null && q.top - b > 0) rescan = true; break; } - if (U.compareAndSetReference( - a, slotOffset(k), t, null)) { - q.updateBase(nb); - w.source = j; + if (U.compareAndSetReference(a, k, t, null)) { + q.base = b + 1; + w.source = j; // volatile write t.doExec(); w.source = wsrc; rescan = true; // restart at index r @@ -2369,12 +2369,13 @@ final int helpComplete(ForkJoinTask<?> task, WorkQueue w, boolean internal) { int j; WorkQueue q; if ((q = qs[j = r & SMASK & (n - 1)]) != null) { for (;;) { - ForkJoinTask<?>[] a; int b, cap, k; + ForkJoinTask<?> t; ForkJoinTask<?>[] a; + int b, cap, nb; long k; + boolean eligible = false; if ((a = q.array) == null || (cap = a.length) <= 0) break; - ForkJoinTask<?> t = a[k = (b = q.base) & (cap - 1)]; - U.loadFence(); - boolean eligible = false; + t = (ForkJoinTask<?>)U.getReferenceAcquire( + a, k = slotOffset((cap - 1) & (b = q.base))); if (t instanceof CountedCompleter) { CountedCompleter<?> f = (CountedCompleter<?>)t; for (int steps = cap; steps > 0; --steps) { @@ -2389,19 +2390,17 @@ final int helpComplete(ForkJoinTask<?> task, WorkQueue w, boolean internal) { if ((s = task.status) < 0) // validate break outer; if (q.base == b) { - int nb = b + 1, nk = nb & (cap - 1); if (eligible) { if (U.compareAndSetReference( - a, slotOffset(k), t, null)) { - q.updateBase(nb); + a, k, t, null)) { + q.updateBase(b + 1); t.doExec(); locals = rescan = true; break scan; } } - else if (a[k] == t) { - if (!rescan && t == null && - (a[nk] != null || q.top - b > 0)) + else if (U.getReference(a, k) == t) { + if (!rescan && t == null && q.top - b > 0) rescan = true; // revisit break; } @@ -2454,14 +2453,15 @@ private int helpQuiesce(WorkQueue w, long nanos, boolean interruptible) { int j; WorkQueue q; if ((q = qs[j = r & SMASK & (n - 1)]) != null && q != w) { for (;;) { - ForkJoinTask<?>[] a; int b, cap, k; + ForkJoinTask<?> t; ForkJoinTask<?>[] a; + int b, cap; long k; if ((a = q.array) == null || (cap = a.length) <= 0) break; - ForkJoinTask<?> t = a[k = (b = q.base) & (cap - 1)]; + t = (ForkJoinTask<?>)U.getReferenceAcquire( + a, k = slotOffset((cap - 1) & (b = q.base))); if (t != null && phase == inactivePhase) // reactivate w.phase = phase = activePhase; - U.loadFence(); - if (q.base == b && a[k] == t) { + if (q.base == b && U.getReference(a, k) == t) { int nb = b + 1; if (t == null) { if (!rescan) { @@ -2474,10 +2474,9 @@ else if (mq == 1) } break; } - if (U.compareAndSetReference( - a, slotOffset(k), t, null)) { - q.updateBase(nb); - w.source = j; + if (U.compareAndSetReference(a, k, t, null)) { + q.base = nb; + w.source = j; // volatile write t.doExec(); w.source = wsrc; rescan = locals = true; @@ -2603,15 +2602,15 @@ private WorkQueue submissionQueue(int r) { if (w == null) w = new WorkQueue(null, id, 0, false); w.phase = id; - long stop = lockRunState() & STOP; - if (stop == 0L && queues == qs && qs[i] == null) { + long isShutdown = lockRunState() & SHUTDOWN; + if (isShutdown == 0L && queues == qs && qs[i] == null) { q = qs[i] = w; // else retry w = null; } unlockRunState(); if (q != null) return q; - if (stop != 0L) + if (isShutdown != 0L) break; } else if (!q.tryLockPhase()) // move index @@ -2623,7 +2622,6 @@ else if ((runState & SHUTDOWN) != 0L) { else return q; } - tryTerminate(false, false); throw new RejectedExecutionException(); } @@ -2640,7 +2638,6 @@ private void poolSubmit(boolean signalIfEmpty, ForkJoinTask<?> task) { } q.push(task, signalIfEmpty ? this : null, internal); } - private static final JavaLangAccess JLA = SharedSecrets.getJavaLangAccess(); /** * Returns queue for an external submission, bypassing call to @@ -2760,49 +2757,94 @@ static int getSurplusQueuedTaskCount() { * @return runState on exit */ private long tryTerminate(boolean now, boolean enable) { - long e = runState, isShutdown; - if ((e & STOP) == 0L) { - if (now) - runState = e = (lockRunState() + RS_LOCK) | STOP | SHUTDOWN; - else if ((isShutdown = (e & SHUTDOWN)) != 0 || enable) { - if (isShutdown == 0) - getAndBitwiseOrRunState(SHUTDOWN); - if (quiescent() > 0) - e = runState; - } - if ((e & STOP) != 0L && (releaseAll() & RC_MASK) > 0L && now) + long e, isShutdown, ps; + if (((e = runState) & TERMINATED) != 0L) + now = false; + else if ((e & STOP) != 0L) + now = true; + else if (now) { + if (((ps = getAndBitwiseOrRunState(SHUTDOWN|STOP) & STOP)) == 0L) { + if ((ps & RS_LOCK) != 0L) { + spinLockRunState(); // ensure queues array stable after stop + unlockRunState(); + } interruptAll(); + } } - if ((e & (STOP | TERMINATED)) == STOP) { // help cancel tasks - if ((ctl & RC_MASK) > 0L) { // unless all inactive - int r = (int)Thread.currentThread().threadId(); - WorkQueue[] qs = queues; // stagger traversals - int n = (qs == null) ? 0 : qs.length; - for (int l = n; l > 0; --l, ++r) { - WorkQueue q; ForkJoinTask<?> t; - if ((q = qs[r & (n - 1)]) != null && - q.source != DROPPED) { - while ((t = q.poll()) != null) { - try { - t.cancel(false); - } catch (Throwable ignore) { - } - } + else if ((isShutdown = (e & SHUTDOWN)) != 0L || enable) { + if (isShutdown == 0L) + getAndBitwiseOrRunState(SHUTDOWN); + if (quiescent() > 0) + now = true; + } + + if (now) { + releaseWaiters(); + for (;;) { + if (((e = runState) & CLEANED) == 0L) { + boolean clean = cleanQueues(); + if (((e = runState) & CLEANED) == 0L && clean) + e = getAndBitwiseOrRunState(CLEANED) | CLEANED; + } + if ((e & TERMINATED) != 0L) + break; + if (ctl != 0L) // else loop if didn't finish cleaning + break; + if ((e & CLEANED) != 0L) { + e |= TERMINATED; + if ((getAndBitwiseOrRunState(TERMINATED) & TERMINATED) == 0L) { + CountDownLatch done; SharedThreadContainer ctr; + if ((done = termination) != null) + done.countDown(); + if ((ctr = container) != null) + ctr.close(); } + break; } } - if (((e = runState) & TERMINATED) == 0L && ctl == 0L) { - e |= TERMINATED; - if ((getAndBitwiseOrRunState(TERMINATED) & TERMINATED) == 0L) { - CountDownLatch done; SharedThreadContainer ctr; - if ((done = termination) != null) - done.countDown(); - if ((ctr = container) != null) - ctr.close(); + } + return e; + } + + /** + * Scans queues in a psuedorandom order based on thread id, + * cancelling tasks until empty, or returning early upon + * interference or still-active external queues, in which case + * other calls will finish cancellation. + * + * @return true if all queues empty + */ + private boolean cleanQueues() { + int r = (int)Thread.currentThread().threadId(); + r ^= r << 13; r ^= r >>> 17; r ^= r << 5; // xorshift + int step = (r >>> 16) | 1; // randomize traversals + WorkQueue[] qs = queues; + int n = (qs == null) ? 0 : qs.length; + for (int l = n; l > 0; --l, r += step) { + WorkQueue q; ForkJoinTask<?>[] a; int cap; + if ((q = qs[r & (n - 1)]) != null && + (a = q.array) != null && (cap = a.length) > 0) { + for (;;) { + ForkJoinTask<?> t; int b; long k; + t = (ForkJoinTask<?>)U.getReferenceAcquire( + a, k = slotOffset((cap - 1) & (b = q.base))); + if (q.base == b && t != null && + U.compareAndSetReference(a, k, t, null)) { + q.updateBase(b + 1); + try { + t.cancel(false); + } catch (Throwable ignore) { + } + } + else if ((q.phase & (IDLE|1)) == 0 || // externally locked + q.top - q.base > 0) + return false; // incomplete + else + break; } } } - return e; + return true; } /** @@ -2814,8 +2856,7 @@ private void interruptAll() { int n = (qs == null) ? 0 : qs.length; for (int i = 1; i < n; i += 2) { WorkQueue q; Thread o; - if ((q = qs[i]) != null && (o = q.owner) != null && o != current && - q.source != DROPPED) { + if ((q = qs[i]) != null && (o = q.owner) != null && o != current) { try { o.interrupt(); } catch (Throwable ignore) { @@ -4018,15 +4059,10 @@ protected <T> RunnableFuture<T> newTaskFor(Callable<T> callable) { if ((scale & (scale - 1)) != 0) throw new Error("array index scale not a power of two"); - defaultForkJoinWorkerThreadFactory = - new DefaultForkJoinWorkerThreadFactory(); - @SuppressWarnings("removal") - ForkJoinPool p = common = (System.getSecurityManager() == null) ? - new ForkJoinPool((byte)0) : - AccessController.doPrivileged(new PrivilegedAction<>() { - public ForkJoinPool run() { - return new ForkJoinPool((byte)0); }}); + interruptibleTaskClass = ForkJoinTask.InterruptibleTask.class; + Class<?> dep = LockSupport.class; // ensure loaded // allow access to non-public methods + JLA = SharedSecrets.getJavaLangAccess(); SharedSecrets.setJavaUtilConcurrentFJPAccess( new JavaUtilConcurrentFJPAccess() { @Override @@ -4037,6 +4073,13 @@ public void endCompensatedBlock(ForkJoinPool pool, long post) { pool.endCompensatedBlock(post); } }); - Class<?> dep = LockSupport.class; // ensure loaded + defaultForkJoinWorkerThreadFactory = + new DefaultForkJoinWorkerThreadFactory(); + @SuppressWarnings("removal") + ForkJoinPool p = common = (System.getSecurityManager() == null) ? + new ForkJoinPool((byte)0) : + AccessController.doPrivileged(new PrivilegedAction<>() { + public ForkJoinPool run() { + return new ForkJoinPool((byte)0); }}); } } diff --git a/src/java.base/share/classes/java/util/concurrent/ForkJoinWorkerThread.java b/src/java.base/share/classes/java/util/concurrent/ForkJoinWorkerThread.java index 27b9b0812d6..7a468666ad3 100644 --- a/src/java.base/share/classes/java/util/concurrent/ForkJoinWorkerThread.java +++ b/src/java.base/share/classes/java/util/concurrent/ForkJoinWorkerThread.java @@ -41,6 +41,7 @@ import java.security.ProtectionDomain; import jdk.internal.access.JavaLangAccess; import jdk.internal.access.SharedSecrets; +import jdk.internal.misc.Unsafe; /** * A thread managed by a {@link ForkJoinPool}, which executes @@ -225,6 +226,25 @@ static boolean hasKnownQueuedWork() { (sq = qs[i]) != null && sq.top - sq.base > 0) || q.top - q.base > 0)); } + + /** + * Clears ThreadLocals, and if necessary resets ContextClassLoader + */ + final void resetThreadLocals() { + if (U.getReference(this, THREADLOCALS) != null) + U.putReference(this, THREADLOCALS, null); + if (U.getReference(this, INHERITABLETHREADLOCALS) != null) + U.putReference(this, INHERITABLETHREADLOCALS, null); + if ((this instanceof InnocuousForkJoinWorkerThread) && + ((InnocuousForkJoinWorkerThread)this).needCCLReset()) + super.setContextClassLoader(ClassLoader.getSystemClassLoader()); + } + + private static final Unsafe U = Unsafe.getUnsafe(); + private static final long THREADLOCALS + = U.objectFieldOffset(Thread.class, "threadLocals"); + private static final long INHERITABLETHREADLOCALS + = U.objectFieldOffset(Thread.class, "inheritableThreadLocals"); private static final JavaLangAccess JLA = SharedSecrets.getJavaLangAccess(); /** @@ -236,6 +256,7 @@ static boolean hasKnownQueuedWork() { static final class InnocuousForkJoinWorkerThread extends ForkJoinWorkerThread { /** The ThreadGroup for all InnocuousForkJoinWorkerThreads */ private static final ThreadGroup innocuousThreadGroup = createGroup(); + private boolean resetCCL; InnocuousForkJoinWorkerThread(ForkJoinPool pool) { super(innocuousThreadGroup, pool, true, true); } @@ -244,9 +265,20 @@ static final class InnocuousForkJoinWorkerThread extends ForkJoinWorkerThread { public void setUncaughtExceptionHandler(UncaughtExceptionHandler x) { } @Override // paranoically + @SuppressWarnings("removal") public void setContextClassLoader(ClassLoader cl) { - if (cl != null && ClassLoader.getSystemClassLoader() != cl) + if (System.getSecurityManager() != null && + cl != null && ClassLoader.getSystemClassLoader() != cl) throw new SecurityException("setContextClassLoader"); + resetCCL = true; + super.setContextClassLoader(cl); + } + + final boolean needCCLReset() { // get and clear + boolean needReset; + if (needReset = resetCCL) + resetCCL = false; + return needReset; } static ThreadGroup createGroup() { @@ -255,5 +287,6 @@ static ThreadGroup createGroup() { group = p; return new ThreadGroup(group, "InnocuousForkJoinWorkerThreadGroup"); } + } } From a62279ca0a520fdf4bce77dec4cb06d4d573c109 Mon Sep 17 00:00:00 2001 From: Daniel Fuchs <dfuchs@openjdk.org> Date: Thu, 21 Nov 2024 11:54:28 +0000 Subject: [PATCH 152/311] 8344235: Revisit SecurityManager usage in java.logging after JEP 486 and JEP 491 integration Reviewed-by: jpai --- .../jdk/internal/logger/BootstrapLogger.java | 102 ++---- .../internal/logger/DefaultLoggerFinder.java | 38 +-- .../jdk/internal/logger/LazyLoggers.java | 25 +- .../internal/logger/LoggerFinderLoader.java | 64 +--- .../internal/logger/SimpleConsoleLogger.java | 26 +- .../java/util/logging/ConsoleHandler.java | 4 +- .../java/util/logging/FileHandler.java | 84 +---- .../classes/java/util/logging/Handler.java | 157 ++------- .../classes/java/util/logging/Level.java | 8 +- .../classes/java/util/logging/LogManager.java | 307 +++++------------- .../classes/java/util/logging/LogRecord.java | 14 +- .../classes/java/util/logging/Logger.java | 47 +-- .../java/util/logging/LoggingPermission.java | 1 - .../java/util/logging/MemoryHandler.java | 49 +-- .../java/util/logging/SocketHandler.java | 34 +- .../java/util/logging/StreamHandler.java | 99 +----- .../logging/internal/LoggingProviderImpl.java | 54 +-- 17 files changed, 206 insertions(+), 907 deletions(-) diff --git a/src/java.base/share/classes/jdk/internal/logger/BootstrapLogger.java b/src/java.base/share/classes/jdk/internal/logger/BootstrapLogger.java index f351b52968d..a4c9e4baf63 100644 --- a/src/java.base/share/classes/jdk/internal/logger/BootstrapLogger.java +++ b/src/java.base/share/classes/jdk/internal/logger/BootstrapLogger.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,9 +25,6 @@ package jdk.internal.logger; -import java.security.AccessControlContext; -import java.security.AccessController; -import java.security.PrivilegedAction; import java.util.HashMap; import java.util.Iterator; import java.util.Map; @@ -131,15 +128,8 @@ private static ExecutorService getExecutor() { @Override public Thread newThread(Runnable r) { ExecutorService owner = getExecutor(); - @SuppressWarnings("removal") - Thread thread = AccessController.doPrivileged(new PrivilegedAction<Thread>() { - @Override - public Thread run() { - Thread t = InnocuousThread.newThread(new BootstrapMessageLoggerTask(owner, r)); - t.setName("BootstrapMessageLoggerTask-"+t.getName()); - return t; - } - }, null, new RuntimePermission("enableContextClassLoaderOverride")); + Thread thread = InnocuousThread.newThread(new BootstrapMessageLoggerTask(owner, r)); + thread.setName("BootstrapMessageLoggerTask-" + thread.getName()); thread.setDaemon(true); return thread; } @@ -269,8 +259,6 @@ static final class LogEvent { // the parameters etc... we need to store the context of the // caller who logged the message - so that we can reuse it when // we finally log the message. - @SuppressWarnings("removal") - final AccessControlContext acc; // The next event in the queue LogEvent next; @@ -279,7 +267,6 @@ static final class LogEvent { private LogEvent(BootstrapLogger bootstrap, Level level, ResourceBundle bundle, String msg, Throwable thrown, Object[] params) { - this.acc = AccessController.getContext(); this.timeMillis = System.currentTimeMillis(); this.nanoAdjustment = VM.getNanoTimeAdjustment(timeMillis); this.level = level; @@ -298,7 +285,6 @@ private LogEvent(BootstrapLogger bootstrap, Level level, private LogEvent(BootstrapLogger bootstrap, Level level, Supplier<String> msgSupplier, Throwable thrown, Object[] params) { - this.acc = AccessController.getContext(); this.timeMillis = System.currentTimeMillis(); this.nanoAdjustment = VM.getNanoTimeAdjustment(timeMillis); this.level = level; @@ -319,7 +305,6 @@ private LogEvent(BootstrapLogger bootstrap, String sourceClass, String sourceMethod, ResourceBundle bundle, String msg, Throwable thrown, Object[] params) { - this.acc = AccessController.getContext(); this.timeMillis = System.currentTimeMillis(); this.nanoAdjustment = VM.getNanoTimeAdjustment(timeMillis); this.level = null; @@ -340,7 +325,6 @@ private LogEvent(BootstrapLogger bootstrap, String sourceClass, String sourceMethod, Supplier<String> msgSupplier, Throwable thrown, Object[] params) { - this.acc = AccessController.getContext(); this.timeMillis = System.currentTimeMillis(); this.nanoAdjustment = VM.getNanoTimeAdjustment(timeMillis); this.level = null; @@ -444,20 +428,12 @@ static LogEvent valueOf(BootstrapLogger bootstrap, Level level, Objects.requireNonNull(level), Objects.requireNonNull(msgSupplier), null, null); } - @SuppressWarnings("removal") + static void log(LogEvent log, Logger logger) { - final SecurityManager sm = System.getSecurityManager(); // not sure we can actually use lambda here. We may need to create // an anonymous class. Although if we reach here, then it means // the VM is booted. - if (sm == null || log.acc == null) { - BootstrapExecutors.submit(() -> log.log(logger)); - } else { - BootstrapExecutors.submit(() -> - AccessController.doPrivileged((PrivilegedAction<Void>) () -> { - log.log(logger); return null; - }, log.acc)); - } + BootstrapExecutors.submit(() -> log.log(logger)); } // non default methods from PlatformLogger.Bridge interface @@ -510,20 +486,9 @@ static LogEvent valueOf(BootstrapLogger bootstrap, PlatformLogger.Level level, Objects.requireNonNull(level), sourceClass, sourceMethod, msgSupplier, thrown, null); } - @SuppressWarnings("removal") + static void log(LogEvent log, PlatformLogger.Bridge logger) { - final SecurityManager sm = System.getSecurityManager(); - if (sm == null || log.acc == null) { - BootstrapExecutors.submit(() -> log.log(logger)); - } else { - // not sure we can actually use lambda here. We may need to create - // an anonymous class. Although if we reach here, then it means - // the VM is booted. - BootstrapExecutors.submit(() -> - AccessController.doPrivileged((PrivilegedAction<Void>) () -> { - log.log(logger); return null; - }, log.acc)); - } + BootstrapExecutors.submit(() -> log.log(logger)); } static void log(LogEvent event) { @@ -897,37 +862,32 @@ private LoggingBackend(boolean useLoggerFinder) { // We do not want this field to get initialized if VM.isBooted() is false. @SuppressWarnings("removal") private static final class DetectBackend { - static final LoggingBackend detectedBackend; - static { - detectedBackend = AccessController.doPrivileged(new PrivilegedAction<LoggingBackend>() { - @Override - public LoggingBackend run() { - final Iterator<LoggerFinder> iterator = - ServiceLoader.load(LoggerFinder.class, ClassLoader.getSystemClassLoader()) + static final LoggingBackend detectedBackend = detectBackend(); + + static LoggingBackend detectBackend() { + final Iterator<LoggerFinder> iterator = + ServiceLoader.load(LoggerFinder.class, ClassLoader.getSystemClassLoader()) .iterator(); - if (iterator.hasNext()) { - return LoggingBackend.CUSTOM; // Custom Logger Provider is registered - } - // No custom logger provider: we will be using the default - // backend. - final Iterator<DefaultLoggerFinder> iterator2 = - ServiceLoader.loadInstalled(DefaultLoggerFinder.class) + if (iterator.hasNext()) { + return LoggingBackend.CUSTOM; // Custom Logger Provider is registered + } + // No custom logger provider: we will be using the default + // backend. + final Iterator<DefaultLoggerFinder> iterator2 = + ServiceLoader.loadInstalled(DefaultLoggerFinder.class) .iterator(); - if (iterator2.hasNext()) { - // LoggingProviderImpl is registered. The default - // implementation is java.util.logging - String cname = System.getProperty("java.util.logging.config.class"); - String fname = System.getProperty("java.util.logging.config.file"); - return (cname != null || fname != null) - ? LoggingBackend.JUL_WITH_CONFIG - : LoggingBackend.JUL_DEFAULT; - } else { - // SimpleConsoleLogger is used - return LoggingBackend.NONE; - } - } - }); - + if (iterator2.hasNext()) { + // LoggingProviderImpl is registered. The default + // implementation is java.util.logging + String cname = System.getProperty("java.util.logging.config.class"); + String fname = System.getProperty("java.util.logging.config.file"); + return (cname != null || fname != null) + ? LoggingBackend.JUL_WITH_CONFIG + : LoggingBackend.JUL_DEFAULT; + } else { + // SimpleConsoleLogger is used + return LoggingBackend.NONE; + } } } diff --git a/src/java.base/share/classes/jdk/internal/logger/DefaultLoggerFinder.java b/src/java.base/share/classes/jdk/internal/logger/DefaultLoggerFinder.java index 1d077f1531c..348b131b3b9 100644 --- a/src/java.base/share/classes/jdk/internal/logger/DefaultLoggerFinder.java +++ b/src/java.base/share/classes/jdk/internal/logger/DefaultLoggerFinder.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -36,8 +36,6 @@ import java.lang.System.LoggerFinder; import java.lang.System.Logger; import java.lang.ref.ReferenceQueue; -import java.security.AccessController; -import java.security.PrivilegedAction; import java.util.Collection; import java.util.ResourceBundle; @@ -70,7 +68,7 @@ * that provides the necessary configuration. * * @apiNote Programmers are not expected to call this class directly. - * Instead they should rely on the static methods defined by {@link + * Instead, they should rely on the static methods defined by {@link * java.lang.System java.lang.System} or {@link sun.util.logging.PlatformLogger * sun.util.logging.PlatformLogger}. * @@ -81,30 +79,12 @@ */ public class DefaultLoggerFinder extends LoggerFinder { - static final RuntimePermission LOGGERFINDER_PERMISSION = - new RuntimePermission("loggerFinder"); - /** * Creates a new instance of DefaultLoggerFinder. - * @throws SecurityException if the calling code does not have the - * {@code RuntimePermission("loggerFinder")} */ protected DefaultLoggerFinder() { - this(checkPermission()); - } - - private DefaultLoggerFinder(Void unused) { - // nothing to do. } - private static Void checkPermission() { - @SuppressWarnings("removal") - final SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - sm.checkPermission(LOGGERFINDER_PERMISSION); - } - return null; - } // SharedLoggers is a default cache of loggers used when JUL is not // present - in that case we use instances of SimpleConsoleLogger which @@ -139,23 +119,14 @@ synchronized Logger get(Function<String, Logger> loggerSupplier, final String na static final SharedLoggers application = new SharedLoggers(); } - @SuppressWarnings("removal") public static boolean isSystem(Module m) { - return AccessController.doPrivileged(new PrivilegedAction<>() { - @Override - public Boolean run() { - // returns true if moduleCL is the platform class loader - // or one of its ancestors. - return VM.isSystemDomainLoader(m.getClassLoader()); - } - }); + return VM.isSystemDomainLoader(m.getClassLoader()); } @Override public final Logger getLogger(String name, Module module) { Objects.requireNonNull(name, "name"); Objects.requireNonNull(module, "module"); - checkPermission(); return demandLoggerFor(name, module); } @@ -176,11 +147,8 @@ public final Logger getLocalizedLogger(String name, ResourceBundle bundle, * @param name The name of the logger. * @param module The module on behalf of which the logger is created. * @return A {@link Logger logger} suitable for the application usage. - * @throws SecurityException if the calling code does not have the - * {@code RuntimePermission("loggerFinder")}. */ protected Logger demandLoggerFor(String name, Module module) { - checkPermission(); if (isSystem(module)) { return SharedLoggers.system.get(SimpleConsoleLogger::makeSimpleLogger, name); } else { diff --git a/src/java.base/share/classes/jdk/internal/logger/LazyLoggers.java b/src/java.base/share/classes/jdk/internal/logger/LazyLoggers.java index 2c624962876..885e2e8c4d7 100644 --- a/src/java.base/share/classes/jdk/internal/logger/LazyLoggers.java +++ b/src/java.base/share/classes/jdk/internal/logger/LazyLoggers.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,8 +25,6 @@ package jdk.internal.logger; -import java.security.AccessController; -import java.security.PrivilegedAction; import java.util.function.BiFunction; import java.lang.System.LoggerFinder; import java.lang.System.Logger; @@ -44,9 +42,6 @@ */ public final class LazyLoggers { - static final RuntimePermission LOGGERFINDER_PERMISSION = - new RuntimePermission("loggerFinder"); - private LazyLoggers() { throw new InternalError(); } @@ -341,7 +336,6 @@ PlatformLogger.Bridge platformProxy() { // Do not expose this outside of this package. private static volatile LoggerFinder provider; - @SuppressWarnings("removal") private static LoggerFinder accessLoggerFinder() { LoggerFinder prov = provider; if (prov == null) { @@ -350,10 +344,7 @@ private static LoggerFinder accessLoggerFinder() { // the result. // This is just an optimization to avoid the cost of calling // doPrivileged every time. - final SecurityManager sm = System.getSecurityManager(); - prov = sm == null ? LoggerFinder.getLoggerFinder() : - AccessController.doPrivileged( - (PrivilegedAction<LoggerFinder>)LoggerFinder::getLoggerFinder); + prov = LoggerFinder.getLoggerFinder(); if (prov instanceof TemporaryLoggerFinder) return prov; provider = prov; } @@ -403,17 +394,9 @@ static Logger makeLazyLogger(String name, Module module, BooleanSupplier isLoadi * @param module module on behalf of which the logger is created * @return The logger returned by the LoggerFinder. */ - @SuppressWarnings("removal") static Logger getLoggerFromFinder(String name, Module module) { - final SecurityManager sm = System.getSecurityManager(); - if (sm == null) { - return accessLoggerFinder().getLogger(name, module); - } else { - return AccessController.doPrivileged((PrivilegedAction<Logger>) - () -> {return accessLoggerFinder().getLogger(name, module);}, - null, LOGGERFINDER_PERMISSION); - } - } + return accessLoggerFinder().getLogger(name, module); + } /** * Returns a (possibly lazy) Logger for the caller. diff --git a/src/java.base/share/classes/jdk/internal/logger/LoggerFinderLoader.java b/src/java.base/share/classes/jdk/internal/logger/LoggerFinderLoader.java index 932de4ef554..36edb918712 100644 --- a/src/java.base/share/classes/jdk/internal/logger/LoggerFinderLoader.java +++ b/src/java.base/share/classes/jdk/internal/logger/LoggerFinderLoader.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -24,12 +24,8 @@ */ package jdk.internal.logger; -import java.io.FilePermission; import java.lang.System.Logger; import java.lang.System.LoggerFinder; -import java.security.AccessController; -import java.security.Permission; -import java.security.PrivilegedAction; import java.util.Iterator; import java.util.Locale; import java.util.ServiceConfigurationError; @@ -37,9 +33,6 @@ import java.util.function.BooleanSupplier; import jdk.internal.vm.annotation.Stable; -import sun.security.util.SecurityConstants; -import sun.security.action.GetBooleanAction; -import sun.security.action.GetPropertyAction; /** * Helper class used to load the {@link java.lang.System.LoggerFinder}. @@ -47,13 +40,6 @@ public final class LoggerFinderLoader { private static volatile System.LoggerFinder service; private static final Object lock = new int[0]; - static final Permission CLASSLOADER_PERMISSION = - SecurityConstants.GET_CLASSLOADER_PERMISSION; - static final Permission READ_PERMISSION = - new FilePermission("<<ALL FILES>>", - SecurityConstants.FILE_READ_ACTION); - public static final RuntimePermission LOGGERFINDER_PERMISSION = - new RuntimePermission("loggerFinder"); // This is used to control how the LoggerFinderLoader handles // errors when instantiating the LoggerFinder provider. @@ -63,7 +49,7 @@ public final class LoggerFinderLoader { // DEBUG => Do not fail, use plain default (simple logger) implementation, // prints warning and exception stack trace on console. // QUIET => Do not fail and stay silent. - private static enum ErrorPolicy { ERROR, WARNING, DEBUG, QUIET }; + private static enum ErrorPolicy { ERROR, WARNING, DEBUG, QUIET } // This class is static and cannot be instantiated. private LoggerFinderLoader() { @@ -107,8 +93,7 @@ static boolean isLoadingThread() { // Get configuration error policy private static ErrorPolicy configurationErrorPolicy() { - String errorPolicy = - GetPropertyAction.privilegedGetProperty("jdk.logger.finder.error"); + String errorPolicy = System.getProperty("jdk.logger.finder.error"); if (errorPolicy == null || errorPolicy.isEmpty()) { return ErrorPolicy.WARNING; } @@ -122,25 +107,12 @@ private static ErrorPolicy configurationErrorPolicy() { // Whether multiple provider should be considered as an error. // This is further submitted to the configuration error policy. private static boolean ensureSingletonProvider() { - return GetBooleanAction.privilegedGetProperty - ("jdk.logger.finder.singleton"); + return Boolean.getBoolean("jdk.logger.finder.singleton"); } - @SuppressWarnings("removal") private static Iterator<System.LoggerFinder> findLoggerFinderProviders() { - final Iterator<System.LoggerFinder> iterator; - if (System.getSecurityManager() == null) { - iterator = ServiceLoader.load(System.LoggerFinder.class, + return ServiceLoader.load(System.LoggerFinder.class, ClassLoader.getSystemClassLoader()).iterator(); - } else { - final PrivilegedAction<Iterator<System.LoggerFinder>> pa = - () -> ServiceLoader.load(System.LoggerFinder.class, - ClassLoader.getSystemClassLoader()).iterator(); - iterator = AccessController.doPrivileged(pa, null, - LOGGERFINDER_PERMISSION, CLASSLOADER_PERMISSION, - READ_PERMISSION); - } - return iterator; } public static final class TemporaryLoggerFinder extends LoggerFinder { @@ -219,25 +191,10 @@ private static System.LoggerFinder loadLoggerFinder() { return result; } - @SuppressWarnings("removal") private static System.LoggerFinder loadDefaultImplementation() { - final SecurityManager sm = System.getSecurityManager(); - final Iterator<DefaultLoggerFinder> iterator; - if (sm == null) { - iterator = ServiceLoader.loadInstalled(DefaultLoggerFinder.class).iterator(); - } else { - // We use limited do privileged here - the minimum set of - // permissions required to 'see' the META-INF/services resources - // seems to be CLASSLOADER_PERMISSION and READ_PERMISSION. - // Note that do privileged is required because - // otherwise the SecurityManager will prevent the ServiceLoader - // from seeing the installed provider. - PrivilegedAction<Iterator<DefaultLoggerFinder>> pa = () -> - ServiceLoader.loadInstalled(DefaultLoggerFinder.class).iterator(); - iterator = AccessController.doPrivileged(pa, null, - LOGGERFINDER_PERMISSION, CLASSLOADER_PERMISSION, - READ_PERMISSION); - } + final Iterator<DefaultLoggerFinder> iterator = + ServiceLoader.loadInstalled(DefaultLoggerFinder.class).iterator(); + DefaultLoggerFinder result = null; try { // Iterator iterates with the access control context stored @@ -256,11 +213,6 @@ private static System.LoggerFinder loadDefaultImplementation() { } public static System.LoggerFinder getLoggerFinder() { - @SuppressWarnings("removal") - final SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - sm.checkPermission(LOGGERFINDER_PERMISSION); - } return service(); } diff --git a/src/java.base/share/classes/jdk/internal/logger/SimpleConsoleLogger.java b/src/java.base/share/classes/jdk/internal/logger/SimpleConsoleLogger.java index 317e475d1a8..664ffaf7356 100644 --- a/src/java.base/share/classes/jdk/internal/logger/SimpleConsoleLogger.java +++ b/src/java.base/share/classes/jdk/internal/logger/SimpleConsoleLogger.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -29,8 +29,6 @@ import java.io.PrintWriter; import java.io.StringWriter; import java.lang.StackWalker.StackFrame; -import java.security.AccessController; -import java.security.PrivilegedAction; import java.time.ZonedDateTime; import java.util.Optional; import java.util.MissingResourceException; @@ -39,7 +37,6 @@ import java.lang.System.Logger; import java.util.function.Predicate; import java.util.function.Supplier; -import sun.security.action.GetPropertyAction; import sun.util.logging.PlatformLogger; import sun.util.logging.PlatformLogger.ConfigurableBridge.LoggerConfiguration; @@ -56,8 +53,7 @@ public class SimpleConsoleLogger extends LoggerConfiguration PlatformLogger.toPlatformLevel(DEFAULT_LEVEL); static Level getDefaultLevel() { - String levelName = GetPropertyAction - .privilegedGetProperty("jdk.system.logger.level", "INFO"); + String levelName = System.getProperty("jdk.system.logger.level", "INFO"); try { return Level.valueOf(levelName); } catch (IllegalArgumentException iae) { @@ -202,18 +198,9 @@ private String getCallerInfo() { /* * CallerFinder is a stateful predicate. */ - @SuppressWarnings("removal") static final class CallerFinder implements Predicate<StackWalker.StackFrame> { - private static final StackWalker WALKER; - static { - final PrivilegedAction<StackWalker> action = new PrivilegedAction<>() { - @Override - public StackWalker run() { - return StackWalker.getInstance(StackWalker.Option.RETAIN_CLASS_REFERENCE); - } - }; - WALKER = AccessController.doPrivileged(action); - } + private static final StackWalker WALKER = + StackWalker.getInstance(StackWalker.Option.RETAIN_CLASS_REFERENCE); /** * Returns StackFrame of the caller's frame. @@ -439,8 +426,7 @@ static final class Formatting { // Make it easier to wrap Logger... private static final String[] skips; static { - String additionalPkgs = - GetPropertyAction.privilegedGetProperty("jdk.logger.packages"); + String additionalPkgs = System.getProperty("jdk.logger.packages"); skips = additionalPkgs == null ? new String[0] : additionalPkgs.split(","); } @@ -499,7 +485,7 @@ static String getSimpleFormat(String key, Function<String, String> defaultProper // jdk/test/java/lang/invoke/lambda/LogGeneratedClassesTest.java // to fail - because that test has a testcase which somehow references // PlatformLogger and counts the number of generated lambda classes. - String format = GetPropertyAction.privilegedGetProperty(key); + String format = System.getProperty(key); if (format == null && defaultPropertyGetter != null) { format = defaultPropertyGetter.apply(key); diff --git a/src/java.logging/share/classes/java/util/logging/ConsoleHandler.java b/src/java.logging/share/classes/java/util/logging/ConsoleHandler.java index 13a6d294e74..cab4805b9e7 100644 --- a/src/java.logging/share/classes/java/util/logging/ConsoleHandler.java +++ b/src/java.logging/share/classes/java/util/logging/ConsoleHandler.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -78,7 +78,7 @@ public ConsoleHandler() { // configure with specific defaults for ConsoleHandler super(Level.INFO, new SimpleFormatter(), null); - setOutputStreamPrivileged(System.err); + setOutputStream(System.err); } /** diff --git a/src/java.logging/share/classes/java/util/logging/FileHandler.java b/src/java.logging/share/classes/java/util/logging/FileHandler.java index b56f53adbb3..3c36a21516c 100644 --- a/src/java.logging/share/classes/java/util/logging/FileHandler.java +++ b/src/java.logging/share/classes/java/util/logging/FileHandler.java @@ -43,8 +43,6 @@ import java.nio.file.NoSuchFileException; import java.nio.file.Path; import java.nio.file.Paths; -import java.security.AccessController; -import java.security.PrivilegedAction; import java.util.HashSet; import java.util.Set; @@ -267,7 +265,6 @@ private void configure() { * @throws NullPointerException if pattern property is an empty String. */ public FileHandler() throws IOException { - checkPermission(); configure(); // pattern will have been set by configure. check that it's not // empty. @@ -293,10 +290,9 @@ public FileHandler() throws IOException { * @throws IllegalArgumentException if pattern is an empty string */ public FileHandler(String pattern) throws IOException { - if (pattern.length() < 1 ) { + if (pattern.isEmpty()) { throw new IllegalArgumentException(); } - checkPermission(); configure(); this.pattern = pattern; this.limit = 0; @@ -323,10 +319,9 @@ public FileHandler(String pattern) throws IOException { * @throws IllegalArgumentException if pattern is an empty string */ public FileHandler(String pattern, boolean append) throws IOException { - if (pattern.length() < 1 ) { + if (pattern.isEmpty()) { throw new IllegalArgumentException(); } - checkPermission(); configure(); this.pattern = pattern; this.limit = 0; @@ -357,10 +352,9 @@ public FileHandler(String pattern, boolean append) throws IOException { * @throws IllegalArgumentException if pattern is an empty string */ public FileHandler(String pattern, int limit, int count) throws IOException { - if (limit < 0 || count < 1 || pattern.length() < 1) { + if (limit < 0 || count < 1 || pattern.isEmpty()) { throw new IllegalArgumentException(); } - checkPermission(); configure(); this.pattern = pattern; this.limit = limit; @@ -425,10 +419,9 @@ public FileHandler(String pattern, int limit, int count, boolean append) */ public FileHandler(String pattern, long limit, int count, boolean append) throws IOException { - if (limit < 0 || count < 1 || pattern.length() < 1) { + if (limit < 0 || count < 1 || pattern.isEmpty()) { throw new IllegalArgumentException(); } - checkPermission(); configure(); this.pattern = pattern; this.limit = limit; @@ -451,7 +444,6 @@ private boolean isParentWritable(Path path) { */ private void openFiles() throws IOException { LogManager manager = LogManager.getLogManager(); - manager.checkPermission(); if (count < 1) { throw new IllegalArgumentException("file count = " + count); } @@ -481,7 +473,7 @@ private void openFiles() throws IOException { // Now try to lock that filename. // Because some systems (e.g., Solaris) can only do file locks // between processes (and not within a process), we first check - // if we ourself already have the file locked. + // if we ourselves already have the file locked. synchronized(locks) { if (locks.contains(lockFileName)) { // We already own this lock, for a different FileHandler @@ -616,7 +608,7 @@ && isParentWritable(lockFilePath)) { * @param generation the generation number to distinguish rotated logs * @param unique a unique number to resolve conflicts * @return the generated File - * @throws IOException + * @throws IOException if an I/O error occurs */ private File generate(String pattern, int generation, int unique) throws IOException @@ -696,7 +688,7 @@ static File generate(String pat, int count, int generation, int unique) if (unique > 0 && !sawu) { word = word.append('.').append(unique); } - if (word.length() > 0) { + if (!word.isEmpty()) { String n = word.toString(); Path p = prev == null ? Paths.get(n) : prev.resolveSibling(n); result = result == null ? p : result.resolve(p); @@ -714,21 +706,7 @@ static File generate(String pat, int count, int generation, int unique) /** * Rotate the set of output files */ - private void rotate() { - if (tryUseLock()) { - try { - rotate0(); - } finally { - unlock(); - } - } else { - synchronized (this) { - rotate0(); - } - } - } - - private void rotate0() { + private synchronized void rotate() { Level oldLevel = getLevel(); setLevel(Level.OFF); @@ -761,40 +739,14 @@ private void rotate0() { * silently ignored and is not published */ @Override - public void publish(LogRecord record) { - if (tryUseLock()) { - try { - publish0(record); - } finally { - unlock(); - } - } else { - synchronized (this) { - publish0(record); - } - } - - } - @SuppressWarnings("removal") - private void publish0(LogRecord record) { + public synchronized void publish(LogRecord record) { if (!isLoggable(record)) { return; } super.publish(record); flush(); if (limit > 0 && (meter.written >= limit || meter.written < 0)) { - // We performed access checks in the "init" method to make sure - // we are only initialized from trusted code. So we assume - // it is OK to write the target files, even if we are - // currently being called from untrusted code. - // So it is safe to raise privilege here. - AccessController.doPrivileged(new PrivilegedAction<Object>() { - @Override - public Object run() { - rotate(); - return null; - } - }); + rotate(); } } @@ -802,21 +754,7 @@ public Object run() { * Close all the files. */ @Override - public void close() { - if (tryUseLock()) { - try { - close0(); - } finally { - unlock(); - } - } else { - synchronized (this) { - close0(); - } - } - } - - private void close0() throws SecurityException { + public synchronized void close() { super.close(); // Unlock any lock file. if (lockFileName == null) { diff --git a/src/java.logging/share/classes/java/util/logging/Handler.java b/src/java.logging/share/classes/java/util/logging/Handler.java index e5fbc131de6..7b93e517e97 100644 --- a/src/java.logging/share/classes/java/util/logging/Handler.java +++ b/src/java.logging/share/classes/java/util/logging/Handler.java @@ -28,9 +28,6 @@ import java.util.Objects; import java.io.UnsupportedEncodingException; -import java.security.AccessController; -import java.security.PrivilegedAction; -import java.util.concurrent.locks.ReentrantLock; /** * A {@code Handler} object takes log messages from a {@code Logger} and @@ -52,6 +49,8 @@ public abstract class Handler { private static final int offValue = Level.OFF.intValue(); + + // ensure log manager is initialized private final LogManager manager = LogManager.getLogManager(); // We're using volatile here to avoid synchronizing getters, which @@ -66,7 +65,6 @@ public abstract class Handler { private volatile Level logLevel = Level.ALL; private volatile ErrorManager errorManager = new ErrorManager(); private volatile String encoding; - private final ReentrantLock lock; /** * Default constructor. The resulting {@code Handler} has a log @@ -74,19 +72,7 @@ public abstract class Handler { * {@code Filter}. A default {@code ErrorManager} instance is installed * as the {@code ErrorManager}. */ - protected Handler() { - lock = initLocking(); - } - - private ReentrantLock initLocking() { - Class<?> clazz = this.getClass(); - ClassLoader loader = clazz.getClassLoader(); - if (loader != null && loader != ClassLoader.getPlatformClassLoader()) { - return null; - } else { - return new ReentrantLock(); - } - } + protected Handler() { } /** * Package-private constructor for chaining from subclass constructors @@ -100,7 +86,6 @@ private ReentrantLock initLocking() { * nor found in LogManager configuration properties * @param specifiedFormatter if not null, this is the formatter to configure */ - @SuppressWarnings("removal") Handler(Level defaultLevel, Formatter defaultFormatter, Formatter specifiedFormatter) { this(); @@ -111,38 +96,23 @@ private ReentrantLock initLocking() { final Level level = manager.getLevelProperty(cname + ".level", defaultLevel); final Filter filter = manager.getFilterProperty(cname + ".filter", null); final Formatter formatter = specifiedFormatter == null - ? manager.getFormatterProperty(cname + ".formatter", defaultFormatter) - : specifiedFormatter; + ? manager.getFormatterProperty(cname + ".formatter", defaultFormatter) + : specifiedFormatter; final String encoding = manager.getStringProperty(cname + ".encoding", null); - AccessController.doPrivileged(new PrivilegedAction<Void>() { - @Override - public Void run() { - setLevel(level); - setFilter(filter); - setFormatter(formatter); - try { - setEncoding(encoding); - } catch (Exception ex) { - try { - setEncoding(null); - } catch (Exception ex2) { - // doing a setEncoding with null should always work. - // assert false; - } - } - return null; + setLevel(level); + setFilter(filter); + setFormatter(formatter); + try { + setEncoding(encoding); + } catch (Exception ex) { + try { + setEncoding(null); + } catch (Exception ex2) { + // doing a setEncoding with null should always work. + // assert false; } - }, null, LogManager.controlPermission); - } - - boolean tryUseLock() { - if (lock == null) return false; - lock.lock(); - return true; - } - void unlock() { - lock.unlock(); + } } /** @@ -183,22 +153,7 @@ void unlock() { * * @param newFormatter the {@code Formatter} to use (may not be null) */ - public void setFormatter(Formatter newFormatter) { - if (tryUseLock()) { - try { - setFormatter0(newFormatter); - } finally { - unlock(); - } - } else { - synchronized (this) { - setFormatter0(newFormatter); - } - } - } - - private void setFormatter0(Formatter newFormatter) throws SecurityException { - checkPermission(); + public synchronized void setFormatter(Formatter newFormatter) { formatter = Objects.requireNonNull(newFormatter); } @@ -221,24 +176,8 @@ public Formatter getFormatter() { * @throws UnsupportedEncodingException if the named encoding is * not supported. */ - public void setEncoding(String encoding) + public synchronized void setEncoding(String encoding) throws java.io.UnsupportedEncodingException { - if (tryUseLock()) { - try { - setEncoding0(encoding); - } finally { - unlock(); - } - } else { - synchronized (this) { - setEncoding0(encoding); - } - } - } - - private void setEncoding0(String encoding) - throws SecurityException, java.io.UnsupportedEncodingException { - checkPermission(); if (encoding != null) { try { if(!java.nio.charset.Charset.isSupported(encoding)) { @@ -270,22 +209,7 @@ public String getEncoding() { * * @param newFilter a {@code Filter} object (may be null) */ - public void setFilter(Filter newFilter) { - if (tryUseLock()) { - try { - setFilter0(newFilter); - } finally { - unlock(); - } - } else { - synchronized (this) { - setFilter0(newFilter); - } - } - } - - private void setFilter0(Filter newFilter) throws SecurityException { - checkPermission(); + public synchronized void setFilter(Filter newFilter) { filter = newFilter; } @@ -306,22 +230,7 @@ public Filter getFilter() { * * @param em the new ErrorManager */ - public void setErrorManager(ErrorManager em) { - if (tryUseLock()) { - try { - setErrorManager0(em); - } finally { - unlock(); - } - } else { - synchronized (this) { - setErrorManager0(em); - } - } - } - - private void setErrorManager0(ErrorManager em) { - checkPermission(); + public synchronized void setErrorManager(ErrorManager em) { if (em == null) { throw new NullPointerException(); } @@ -334,7 +243,6 @@ private void setErrorManager0(ErrorManager em) { * @return the ErrorManager for this Handler */ public ErrorManager getErrorManager() { - checkPermission(); return errorManager; } @@ -366,25 +274,10 @@ protected void reportError(String msg, Exception ex, int code) { * * @param newLevel the new value for the log level */ - public void setLevel(Level newLevel) { - if (tryUseLock()) { - try { - setLevel0(newLevel); - } finally { - unlock(); - } - } else { - synchronized (this) { - setLevel0(newLevel); - } - } - } - - private void setLevel0(Level newLevel) throws SecurityException { + public synchronized void setLevel(Level newLevel) { if (newLevel == null) { throw new NullPointerException(); } - checkPermission(); logLevel = newLevel; } @@ -426,10 +319,4 @@ public boolean isLoggable(LogRecord record) { return filter.isLoggable(record); } - // Package-private support method for security checks. - // We check that the caller has appropriate security privileges - // to update Handler state and if not throw a SecurityException. - void checkPermission() throws SecurityException { - manager.checkPermission(); - } } diff --git a/src/java.logging/share/classes/java/util/logging/Level.java b/src/java.logging/share/classes/java/util/logging/Level.java index 4a0f876d86d..ac9a6cae374 100644 --- a/src/java.logging/share/classes/java/util/logging/Level.java +++ b/src/java.logging/share/classes/java/util/logging/Level.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -29,8 +29,6 @@ import java.lang.ref.Reference; import java.lang.ref.ReferenceQueue; import java.lang.ref.WeakReference; -import java.security.AccessController; -import java.security.PrivilegedAction; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; @@ -620,9 +618,7 @@ static synchronized void purge() { } private static void registerWithClassLoader(Level customLevel) { - PrivilegedAction<ClassLoader> pa = customLevel.getClass()::getClassLoader; - @SuppressWarnings("removal") - final ClassLoader cl = AccessController.doPrivileged(pa); + final ClassLoader cl = customLevel.getClass().getClassLoader(); CUSTOM_LEVEL_CLV.computeIfAbsent(cl, (c, v) -> new ArrayList<>()) .add(customLevel); } diff --git a/src/java.logging/share/classes/java/util/logging/LogManager.java b/src/java.logging/share/classes/java/util/logging/LogManager.java index 59ab4bfcbce..0b7a854dddf 100644 --- a/src/java.logging/share/classes/java/util/logging/LogManager.java +++ b/src/java.logging/share/classes/java/util/logging/LogManager.java @@ -27,7 +27,6 @@ import java.io.*; import java.util.*; -import java.security.*; import java.lang.ref.ReferenceQueue; import java.lang.ref.WeakReference; import java.util.concurrent.ConcurrentHashMap; @@ -39,8 +38,6 @@ import java.util.function.Predicate; import java.util.stream.Collectors; import java.util.stream.Stream; -import jdk.internal.access.JavaAWTAccess; -import jdk.internal.access.SharedSecrets; import sun.util.logging.internal.LoggingProviderImpl; import static jdk.internal.logger.DefaultLoggerFinder.isSystem; @@ -218,39 +215,36 @@ public static CloseOnReset create(Logger logger) { Collections.synchronizedMap(new IdentityHashMap<>()); // The global LogManager object - @SuppressWarnings("removal") - private static final LogManager manager = AccessController.doPrivileged( - new PrivilegedAction<LogManager>() { - @Override - public LogManager run() { - LogManager mgr = null; - String cname = null; - try { - cname = System.getProperty("java.util.logging.manager"); - if (cname != null) { - try { - @SuppressWarnings("deprecation") - Object tmp = ClassLoader.getSystemClassLoader() - .loadClass(cname).newInstance(); - mgr = (LogManager) tmp; - } catch (ClassNotFoundException ex) { - @SuppressWarnings("deprecation") - Object tmp = Thread.currentThread() - .getContextClassLoader().loadClass(cname).newInstance(); - mgr = (LogManager) tmp; - } - } - } catch (Exception ex) { - System.err.println("Could not load Logmanager \"" + cname + "\""); - ex.printStackTrace(); - } - if (mgr == null) { - mgr = new LogManager(); - } - return mgr; + private static final LogManager manager = initLogManager(); + private static LogManager initLogManager() { + LogManager mgr = null; + String cname = null; + try { + cname = System.getProperty("java.util.logging.manager"); + if (cname != null) { + try { + @SuppressWarnings("deprecation") + Object tmp = ClassLoader.getSystemClassLoader() + .loadClass(cname).newInstance(); + mgr = (LogManager) tmp; + } catch (ClassNotFoundException ex) { + @SuppressWarnings("deprecation") + Object tmp = Thread.currentThread() + .getContextClassLoader().loadClass(cname).newInstance(); + mgr = (LogManager) tmp; } - }); + } + } catch (Exception ex) { + System.err.println("Could not load Logmanager \"" + cname + "\""); + ex.printStackTrace(); + } + if (mgr == null) { + mgr = new LogManager(); + } + return mgr; + } + // This private class is used as a shutdown hook. // It does a "reset" to close all open handlers. @@ -290,11 +284,6 @@ public void run() { * retrieved by calling LogManager.getLogManager. */ protected LogManager() { - this(checkSubclassPermissions()); - } - - private LogManager(Void checked) { - // Add a shutdown hook to close the global handlers. try { Runtime.getRuntime().addShutdownHook(new Cleaner()); @@ -304,20 +293,6 @@ private LogManager(Void checked) { } } - private static Void checkSubclassPermissions() { - @SuppressWarnings("removal") - final SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - // These permission will be checked in the LogManager constructor, - // in order to register the Cleaner() thread as a shutdown hook. - // Check them here to avoid the penalty of constructing the object - // etc... - sm.checkPermission(new RuntimePermission("shutdownHooks")); - sm.checkPermission(new RuntimePermission("setContextClassLoader")); - } - return null; - } - /** * Lazy initialization: if this instance of manager is the global * manager then this method will read the initial configuration and @@ -380,40 +355,33 @@ final void ensureLogManagerInitialized() { // We use initializedCalled to break the recursion. initializedCalled = true; try { - AccessController.doPrivileged(new PrivilegedAction<Object>() { - @Override - public Object run() { - assert rootLogger == null; - assert initializedCalled && !initializationDone; - - // create root logger before reading primordial - // configuration - to ensure that it will be added - // before the global logger, and not after. - final Logger root = owner.rootLogger = owner.new RootLogger(); - - // Read configuration. - owner.readPrimordialConfiguration(); - - // Create and retain Logger for the root of the namespace. - owner.addLogger(root); - - // Initialize level if not yet initialized - if (!root.isLevelInitialized()) { - root.setLevel(defaultLevel); - } - - // Adding the global Logger. - // Do not call Logger.getGlobal() here as this might trigger - // subtle inter-dependency issues. - @SuppressWarnings("deprecation") - final Logger global = Logger.global; + assert rootLogger == null; + assert initializedCalled && !initializationDone; - // Make sure the global logger will be registered in the - // global manager - owner.addLogger(global); - return null; - } - }); + // create root logger before reading primordial + // configuration - to ensure that it will be added + // before the global logger, and not after. + final Logger root = owner.rootLogger = owner.new RootLogger(); + + // Read configuration. + owner.readPrimordialConfiguration(); + + // Create and retain Logger for the root of the namespace. + owner.addLogger(root); + + // Initialize level if not yet initialized + if (!root.isLevelInitialized()) { + root.setLevel(defaultLevel); + } + + // Adding the global Logger. + // Do not call Logger.getGlobal() here as this might trigger + // subtle inter-dependency issues. + @SuppressWarnings("deprecation") final Logger global = Logger.global; + + // Make sure the global logger will be registered in the + // global manager + owner.addLogger(global); } finally { initializationDone = true; } @@ -461,29 +429,6 @@ private void readPrimordialConfiguration() { // must be called while holding con // Loggers are isolated from each AppContext. private LoggerContext getUserContext() { LoggerContext context = null; - - @SuppressWarnings("removal") - SecurityManager sm = System.getSecurityManager(); - JavaAWTAccess javaAwtAccess = SharedSecrets.getJavaAWTAccess(); - if (sm != null && javaAwtAccess != null) { - // for each applet, it has its own LoggerContext isolated from others - final Object ecx = javaAwtAccess.getAppletContext(); - if (ecx != null) { - synchronized (javaAwtAccess) { - // find the AppContext of the applet code - // will be null if we are in the main app context. - if (contextsMap == null) { - contextsMap = new WeakHashMap<>(); - } - context = contextsMap.get(ecx); - if (context == null) { - // Create a new LoggerContext for the applet. - context = new LoggerContext(); - contextsMap.put(ecx, context); - } - } - } - } // for standalone app, return userContext return context != null ? context : userContext; } @@ -552,7 +497,6 @@ Logger demandSystemLogger(String name, String resourceBundleName, Class<?> calle return demandSystemLogger(name, resourceBundleName, module); } - @SuppressWarnings("removal") Logger demandSystemLogger(String name, String resourceBundleName, Module module) { // Add a system logger in the system context's namespace final Logger sysLogger = getSystemContext() @@ -578,14 +522,7 @@ Logger demandSystemLogger(String name, String resourceBundleName, Module module) // LogManager will set the sysLogger's handlers via LogManager.addLogger method. if (logger != sysLogger) { // if logger already exists we merge the two logger configurations. - final Logger l = logger; - AccessController.doPrivileged(new PrivilegedAction<Void>() { - @Override - public Void run() { - l.mergeWithSystemLogger(sysLogger); - return null; - } - }); + logger.mergeWithSystemLogger(sysLogger); } return sysLogger; } @@ -801,7 +738,7 @@ synchronized boolean addLocalLogger(Logger logger, boolean addDefaultLoggersIfNe // the logger's level is already initialized Level level = owner.getLevelProperty(name + ".level", null); if (level != null && !logger.isLevelInitialized()) { - doSetLevel(logger, level); + logger.setLevel(level); } // instantiation of the handler is done in the LogManager.addLogger @@ -826,7 +763,7 @@ synchronized boolean addLocalLogger(Logger logger, boolean addDefaultLoggersIfNe } if (parent != null) { - doSetParent(logger, parent); + logger.setParent(parent); } // Walk over the children and tell them we are their new parent. node.walkAndSetParent(logger); @@ -855,22 +792,15 @@ synchronized Enumeration<String> getLoggerNames() { // If logger.getUseParentHandlers() returns 'true' and any of the logger's // parents have levels or handlers defined, make sure they are instantiated. - @SuppressWarnings("removal") private void processParentHandlers(final Logger logger, final String name, Predicate<Logger> visited) { final LogManager owner = getOwner(); - AccessController.doPrivileged(new PrivilegedAction<Void>() { - @Override - public Void run() { - if (logger != owner.rootLogger) { - boolean useParent = owner.getBooleanProperty(name + ".useParentHandlers", true); - if (!useParent) { - logger.setUseParentHandlers(false); - } - } - return null; + if (logger != owner.rootLogger) { + boolean useParent = owner.getBooleanProperty(name + ".useParentHandlers", true); + if (!useParent) { + logger.setUseParentHandlers(false); } - }); + } int ix = 1; for (;;) { @@ -898,7 +828,7 @@ LogNode getNode(String name) { return root; } LogNode node = root; - while (name.length() > 0) { + while (!name.isEmpty()) { int ix = name.indexOf('.'); String head; if (ix > 0) { @@ -961,21 +891,10 @@ Logger demandLogger(String name, String resourceBundleName, } // Add new per logger handlers. - // We need to raise privilege here. All our decisions will - // be made based on the logging configuration, which can - // only be modified by trusted code. - @SuppressWarnings("removal") private void loadLoggerHandlers(final Logger logger, final String name, - final String handlersPropertyName) - { - AccessController.doPrivileged(new PrivilegedAction<Void>() { - @Override - public Void run() { - setLoggerHandlers(logger, name, handlersPropertyName, - createLoggerHandlers(name, handlersPropertyName)); - return null; - } - }); + final String handlersPropertyName) { + setLoggerHandlers(logger, name, handlersPropertyName, + createLoggerHandlers(name, handlersPropertyName)); } private void setLoggerHandlers(final Logger logger, final String name, @@ -1228,45 +1147,6 @@ private boolean forceLoadHandlers(Logger logger) { && configurationLock.isHeldByCurrentThread(); } - // Private method to set a level on a logger. - // If necessary, we raise privilege before doing the call. - @SuppressWarnings("removal") - private static void doSetLevel(final Logger logger, final Level level) { - SecurityManager sm = System.getSecurityManager(); - if (sm == null) { - // There is no security manager, so things are easy. - logger.setLevel(level); - return; - } - // There is a security manager. Raise privilege before - // calling setLevel. - AccessController.doPrivileged(new PrivilegedAction<Object>() { - @Override - public Object run() { - logger.setLevel(level); - return null; - }}); - } - - // Private method to set a parent on a logger. - // If necessary, we raise privilege before doing the setParent call. - @SuppressWarnings("removal") - private static void doSetParent(final Logger logger, final Logger parent) { - SecurityManager sm = System.getSecurityManager(); - if (sm == null) { - // There is no security manager, so things are easy. - logger.setParent(parent); - return; - } - // There is a security manager. Raise privilege before - // calling setParent. - AccessController.doPrivileged(new PrivilegedAction<Object>() { - @Override - public Object run() { - logger.setParent(parent); - return null; - }}); - } /** * Method to find a named logger. @@ -1350,7 +1230,6 @@ public Enumeration<String> getLoggerNames() { * @throws IOException if there are IO problems reading the configuration. */ public void readConfiguration() throws IOException { - checkPermission(); // if a configuration class is specified, load it and use it. String cname = System.getProperty("java.util.logging.config.class"); @@ -1383,7 +1262,7 @@ public void readConfiguration() throws IOException { } } - String getConfigurationFileName() throws IOException { + String getConfigurationFileName() { String fname = System.getProperty("java.util.logging.config.file"); if (fname == null) { fname = System.getProperty("java.home"); @@ -1413,7 +1292,6 @@ String getConfigurationFileName() throws IOException { */ public void reset() { - checkPermission(); List<CloseOnReset> persistent; @@ -1518,7 +1396,7 @@ private String[] parseClassNames(String propertyName) { String word = hands.substring(ix, end); ix = end+1; word = word.trim(); - if (word.length() == 0) { + if (word.isEmpty()) { continue; } result.add(word); @@ -1553,7 +1431,6 @@ private String[] parseClassNames(String propertyName) { * {@linkplain java.util.Properties properties file} format. */ public void readConfiguration(InputStream ins) throws IOException { - checkPermission(); // We don't want reset() and readConfiguration() to run // in parallel. @@ -1857,7 +1734,6 @@ static ModType of(String previous, String next) { */ public void updateConfiguration(Function<String, BiFunction<String,String,String>> mapper) throws IOException { - checkPermission(); ensureLogManagerInitialized(); drainLoggerRefQueueBounded(); @@ -2054,7 +1930,6 @@ public void updateConfiguration(Function<String, BiFunction<String,String,String public void updateConfiguration(InputStream ins, Function<String, BiFunction<String,String,String>> mapper) throws IOException { - checkPermission(); ensureLogManagerInitialized(); drainLoggerRefQueueBounded(); @@ -2410,16 +2285,6 @@ private void initializeGlobalHandlers() { } } - static final Permission controlPermission = - new LoggingPermission("control", null); - - void checkPermission() { - @SuppressWarnings("removal") - SecurityManager sm = System.getSecurityManager(); - if (sm != null) - sm.checkPermission(controlPermission); - } - /** * Does nothing. * @@ -2456,7 +2321,7 @@ void walkAndSetParent(Logger parent) { if (logger == null) { node.walkAndSetParent(parent); } else { - doSetParent(logger, parent); + logger.setParent(parent); } } } @@ -2590,19 +2455,8 @@ public static synchronized LoggingMXBean getLoggingMXBean() { */ public LogManager addConfigurationListener(Runnable listener) { final Runnable r = Objects.requireNonNull(listener); - checkPermission(); - @SuppressWarnings("removal") - final SecurityManager sm = System.getSecurityManager(); - @SuppressWarnings("removal") - final AccessControlContext acc = - sm == null ? null : AccessController.getContext(); - final PrivilegedAction<Void> pa = - acc == null ? null : () -> { r.run() ; return null; }; - @SuppressWarnings("removal") - final Runnable pr = - acc == null ? r : () -> AccessController.doPrivileged(pa, acc); // Will do nothing if already registered. - listeners.putIfAbsent(r, pr); + listeners.putIfAbsent(r, r); return this; } @@ -2618,7 +2472,6 @@ public LogManager addConfigurationListener(Runnable listener) { */ public void removeConfigurationListener(Runnable listener) { final Runnable key = Objects.requireNonNull(listener); - checkPermission(); listeners.remove(key); } @@ -2652,8 +2505,7 @@ private void invokeConfigurationListeners() { * behalf of system and application classes. */ private static final class LoggingProviderAccess - implements LoggingProviderImpl.LogManagerAccess, - PrivilegedAction<Void> { + implements LoggingProviderImpl.LogManagerAccess { private LoggingProviderAccess() { } @@ -2684,11 +2536,6 @@ public Logger demandLoggerFor(LogManager manager, String name, Module module) { } Objects.requireNonNull(name); Objects.requireNonNull(module); - @SuppressWarnings("removal") - SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - sm.checkPermission(controlPermission); - } if (isSystem(module)) { return manager.demandSystemLogger(name, Logger.SYSTEM_LOGGER_RB_NAME, module); @@ -2697,23 +2544,15 @@ public Logger demandLoggerFor(LogManager manager, String name, Module module) { } } - @Override - public Void run() { + private void init() { LoggingProviderImpl.setLogManagerAccess(INSTANCE); - return null; } static final LoggingProviderAccess INSTANCE = new LoggingProviderAccess(); } static { - initStatic(); - } - - @SuppressWarnings("removal") - private static void initStatic() { - AccessController.doPrivileged(LoggingProviderAccess.INSTANCE, null, - controlPermission); + LoggingProviderAccess.INSTANCE.init(); } } diff --git a/src/java.logging/share/classes/java/util/logging/LogRecord.java b/src/java.logging/share/classes/java/util/logging/LogRecord.java index 9605d348e68..43d196cd538 100644 --- a/src/java.logging/share/classes/java/util/logging/LogRecord.java +++ b/src/java.logging/share/classes/java/util/logging/LogRecord.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -28,8 +28,6 @@ import java.util.*; import java.util.concurrent.atomic.AtomicLong; import java.io.*; -import java.security.AccessController; -import java.security.PrivilegedAction; import java.time.Clock; import java.util.function.Predicate; import static jdk.internal.logger.SurrogateLogger.isFilteredFrame; @@ -767,14 +765,10 @@ private void inferCaller() { /* * CallerFinder is a stateful predicate. */ - @SuppressWarnings("removal") static final class CallerFinder implements Predicate<StackWalker.StackFrame> { - private static final StackWalker WALKER; - static { - final PrivilegedAction<StackWalker> action = - () -> StackWalker.getInstance(StackWalker.Option.RETAIN_CLASS_REFERENCE); - WALKER = AccessController.doPrivileged(action); - } + private static final StackWalker WALKER = + StackWalker.getInstance(StackWalker.Option.RETAIN_CLASS_REFERENCE); + /** * Returns StackFrame of the caller's frame. diff --git a/src/java.logging/share/classes/java/util/logging/Logger.java b/src/java.logging/share/classes/java/util/logging/Logger.java index 3f192ba9612..f40e419c2ca 100644 --- a/src/java.logging/share/classes/java/util/logging/Logger.java +++ b/src/java.logging/share/classes/java/util/logging/Logger.java @@ -26,8 +26,6 @@ package java.util.logging; import java.lang.ref.WeakReference; -import java.security.AccessController; -import java.security.PrivilegedAction; import java.util.ArrayList; import java.util.Iterator; import java.util.Locale; @@ -579,7 +577,7 @@ final void mergeWithSystemLogger(Logger system) { // should never come here throw new InternalError("invalid logger merge"); } - checkPermission(); + ensureManagerInitialized(); final ConfigurationData cfg = config; if (cfg != system.config) { config = cfg.merge(system); @@ -614,13 +612,12 @@ void setLogManager(LogManager manager) { this.manager = manager; } - private void checkPermission() throws SecurityException { + private void ensureManagerInitialized() { if (!anonymous) { if (manager == null) { // Complete initialization of the global Logger. manager = LogManager.getLogManager(); } - manager.checkPermission(); } } @@ -633,17 +630,8 @@ private void checkPermission() throws SecurityException { // These system loggers only set the resource bundle to the given // resource bundle name (rather than the default system resource bundle). private static class SystemLoggerHelper { - static boolean disableCallerCheck = getBooleanProperty("sun.util.logging.disableCallerCheck"); - private static boolean getBooleanProperty(final String key) { - @SuppressWarnings("removal") - String s = AccessController.doPrivileged(new PrivilegedAction<String>() { - @Override - public String run() { - return System.getProperty(key); - } - }); - return Boolean.parseBoolean(s); - } + static boolean disableCallerCheck = + Boolean.getBoolean("sun.util.logging.disableCallerCheck"); } private static Logger demandLogger(String name, String resourceBundleName, Class<?> caller) { @@ -930,7 +918,7 @@ public String getResourceBundleName() { * @param newFilter a filter object (may be null) */ public void setFilter(Filter newFilter) { - checkPermission(); + ensureManagerInitialized(); config.setFilter(newFilter); } @@ -1990,7 +1978,7 @@ public void finest(Supplier<String> msgSupplier) { * @param newLevel the new value for the log level (may be null) */ public void setLevel(Level newLevel) { - checkPermission(); + ensureManagerInitialized(); synchronized (treeLock) { config.setLevelObject(newLevel); updateEffectiveLevel(); @@ -2047,7 +2035,7 @@ public String getName() { */ public void addHandler(Handler handler) { Objects.requireNonNull(handler); - checkPermission(); + ensureManagerInitialized(); config.addHandler(handler); } @@ -2059,7 +2047,7 @@ public void addHandler(Handler handler) { * @param handler a logging Handler */ public void removeHandler(Handler handler) { - checkPermission(); + ensureManagerInitialized(); if (handler == null) { return; } @@ -2091,7 +2079,7 @@ Handler[] accessCheckedHandlers() { * logger's parent. */ public void setUseParentHandlers(boolean useParentHandlers) { - checkPermission(); + ensureManagerInitialized(); config.setUseParentHandlers(useParentHandlers); } @@ -2187,11 +2175,8 @@ private synchronized ResourceBundle findResourceBundle(String name, try { // We are called by an unnamed module: try with the // unnamed module class loader: - PrivilegedAction<ClassLoader> getModuleClassLoader = - () -> callerModule.getClassLoader(); - @SuppressWarnings("removal") - ClassLoader moduleCL = - AccessController.doPrivileged(getModuleClassLoader); + ClassLoader moduleCL = callerModule.getClassLoader(); + // moduleCL can be null if the logger is created by a class // appended to the bootclasspath. // If moduleCL is null we would use cl, but we already tried @@ -2267,7 +2252,7 @@ private synchronized void setupResourceInfo(String name, setCallerModuleRef(callerModule); if (isSystemLogger && (callerModule != null && !isSystem(callerModule))) { - checkPermission(); + ensureManagerInitialized(); } if (name.equals(SYSTEM_LOGGER_RB_NAME)) { @@ -2300,7 +2285,7 @@ private synchronized void setupResourceInfo(String name, * @since 1.8 */ public void setResourceBundle(ResourceBundle bundle) { - checkPermission(); + ensureManagerInitialized(); // Will throw NPE if bundle is null. final String baseName = bundle.getBaseBundleName(); @@ -2359,11 +2344,7 @@ public void setParent(Logger parent) { throw new NullPointerException(); } - // check permission for all loggers, including anonymous loggers - if (manager == null) { - manager = LogManager.getLogManager(); - } - manager.checkPermission(); + ensureManagerInitialized(); doSetParent(parent); } diff --git a/src/java.logging/share/classes/java/util/logging/LoggingPermission.java b/src/java.logging/share/classes/java/util/logging/LoggingPermission.java index 0784bf863eb..c48d5ba9f06 100644 --- a/src/java.logging/share/classes/java/util/logging/LoggingPermission.java +++ b/src/java.logging/share/classes/java/util/logging/LoggingPermission.java @@ -26,7 +26,6 @@ package java.util.logging; -import java.security.*; /** * This class is for logging permissions. Currently there is only one diff --git a/src/java.logging/share/classes/java/util/logging/MemoryHandler.java b/src/java.logging/share/classes/java/util/logging/MemoryHandler.java index f7d67b4cca2..bd585fe5694 100644 --- a/src/java.logging/share/classes/java/util/logging/MemoryHandler.java +++ b/src/java.logging/share/classes/java/util/logging/MemoryHandler.java @@ -178,21 +178,7 @@ public MemoryHandler(Handler target, int size, Level pushLevel) { * silently ignored and is not published */ @Override - public void publish(LogRecord record) { - if (tryUseLock()) { - try { - publish0(record); - } finally { - unlock(); - } - } else { - synchronized (this) { - publish0(record); - } - } - } - - private void publish0(LogRecord record) { + public synchronized void publish(LogRecord record) { if (!isLoggable(record)) { return; } @@ -214,21 +200,7 @@ private void publish0(LogRecord record) { * <p> * The buffer is then cleared. */ - public void push() { - if (tryUseLock()) { - try { - push0(); - } finally { - unlock(); - } - } else { - synchronized (this) { - push0(); - } - } - } - - private void push0() { + public synchronized void push() { for (int i = 0; i < count; i++) { int ix = (start+i)%buffer.length; LogRecord record = buffer[ix]; @@ -267,25 +239,10 @@ public void close() { * * @param newLevel the new value of the {@code pushLevel} */ - public void setPushLevel(Level newLevel) { - if (tryUseLock()) { - try { - setPushLevel0(newLevel); - } finally { - unlock(); - } - } else { - synchronized (this) { - setPushLevel0(newLevel); - } - } - } - - private void setPushLevel0(Level newLevel) throws SecurityException { + public synchronized void setPushLevel(Level newLevel) { if (newLevel == null) { throw new NullPointerException(); } - checkPermission(); pushLevel = newLevel; } diff --git a/src/java.logging/share/classes/java/util/logging/SocketHandler.java b/src/java.logging/share/classes/java/util/logging/SocketHandler.java index 570e074cd9d..380cc20add4 100644 --- a/src/java.logging/share/classes/java/util/logging/SocketHandler.java +++ b/src/java.logging/share/classes/java/util/logging/SocketHandler.java @@ -146,28 +146,14 @@ private void connect() throws IOException { sock = new Socket(host, port); OutputStream out = sock.getOutputStream(); BufferedOutputStream bout = new BufferedOutputStream(out); - setOutputStreamPrivileged(bout); + setOutputStream(bout); } /** * Close this output stream. */ @Override - public void close() { - if (tryUseLock()) { - try { - close0(); - } finally { - unlock(); - } - } else { - synchronized (this) { - close0(); - } - } - } - - private void close0() throws SecurityException { + public synchronized void close() { super.close(); if (sock != null) { try { @@ -186,21 +172,7 @@ private void close0() throws SecurityException { * silently ignored and is not published */ @Override - public void publish(LogRecord record) { - if (tryUseLock()) { - try { - publish0(record); - } finally { - unlock(); - } - } else { - synchronized (this) { - publish0(record); - } - } - } - - private void publish0(LogRecord record) { + public synchronized void publish(LogRecord record) { if (!isLoggable(record)) { return; } diff --git a/src/java.logging/share/classes/java/util/logging/StreamHandler.java b/src/java.logging/share/classes/java/util/logging/StreamHandler.java index 9dfcf293041..31cb6605fbc 100644 --- a/src/java.logging/share/classes/java/util/logging/StreamHandler.java +++ b/src/java.logging/share/classes/java/util/logging/StreamHandler.java @@ -27,8 +27,6 @@ package java.util.logging; import java.io.*; -import java.security.AccessController; -import java.security.PrivilegedAction; import java.util.Objects; /** @@ -99,7 +97,7 @@ public StreamHandler(OutputStream out, Formatter formatter) { // configure with default level but use specified formatter super(Level.INFO, null, Objects.requireNonNull(formatter)); - setOutputStreamPrivileged(out); + setOutputStream(out); } /** @@ -120,21 +118,7 @@ public StreamHandler(OutputStream out, Formatter formatter) { * * @param out New output stream. May not be null. */ - protected void setOutputStream(OutputStream out) { - if (tryUseLock()) { - try { - setOutputStream0(out); - } finally { - unlock(); - } - } else { - synchronized (this) { - setOutputStream0(out); - } - } - } - - private void setOutputStream0(OutputStream out) throws SecurityException { + protected synchronized void setOutputStream(OutputStream out) { if (out == null) { throw new NullPointerException(); } @@ -167,22 +151,8 @@ private void setOutputStream0(OutputStream out) throws SecurityException { * not supported. */ @Override - public void setEncoding(String encoding) + public synchronized void setEncoding(String encoding) throws java.io.UnsupportedEncodingException { - if (tryUseLock()) { - try { - setEncoding0(encoding); - } finally { - unlock(); - } - } else { - synchronized (this) { - setEncoding0(encoding); - } - } - } - private void setEncoding0(String encoding) - throws SecurityException, java.io.UnsupportedEncodingException { super.setEncoding(encoding); if (output == null) { return; @@ -214,22 +184,8 @@ private void setEncoding0(String encoding) * silently ignored and is not published */ @Override - public void publish(LogRecord record) { - if (tryUseLock()) { - try { - publish0(record); - } finally { - unlock(); - } - } else { - synchronized (this) { - publish0(record); - } - } - } - - private void publish0(LogRecord record) { - if (!isLoggable(record)) { + public synchronized void publish(LogRecord record) { + if (!isLoggable(record)) { return; } String msg; @@ -280,21 +236,7 @@ public boolean isLoggable(LogRecord record) { * Flush any buffered messages. */ @Override - public void flush() { - if (tryUseLock()) { - try { - flush0(); - } finally { - unlock(); - } - } else { - synchronized (this) { - flush0(); - } - } - } - - private void flush0() { + public synchronized void flush() { Writer writer = this.writer; if (writer != null) { try { @@ -307,8 +249,7 @@ private void flush0() { } } - private void flushAndClose() throws SecurityException { - checkPermission(); + private void flushAndClose() { Writer writer = this.writer; if (writer != null) { try { @@ -338,30 +279,8 @@ private void flushAndClose() throws SecurityException { * "tail" string. */ @Override - public void close() { - if (tryUseLock()) { - try { - flushAndClose(); - } finally { - unlock(); - } - } else { - synchronized (this) { - flushAndClose(); - } - } + public synchronized void close() { + flushAndClose(); } - // Package-private support for setting OutputStream - // with elevated privilege. - @SuppressWarnings("removal") - final void setOutputStreamPrivileged(final OutputStream out) { - AccessController.doPrivileged(new PrivilegedAction<Void>() { - @Override - public Void run() { - setOutputStream(out); - return null; - } - }, null, LogManager.controlPermission); - } } diff --git a/src/java.logging/share/classes/sun/util/logging/internal/LoggingProviderImpl.java b/src/java.logging/share/classes/sun/util/logging/internal/LoggingProviderImpl.java index 27a42dea3b5..8cccb6e23fa 100644 --- a/src/java.logging/share/classes/sun/util/logging/internal/LoggingProviderImpl.java +++ b/src/java.logging/share/classes/sun/util/logging/internal/LoggingProviderImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,8 +26,6 @@ package sun.util.logging.internal; -import java.security.AccessController; -import java.security.PrivilegedAction; import java.util.ResourceBundle; import java.util.function.Supplier; import java.lang.System.LoggerFinder; @@ -35,7 +33,6 @@ import java.util.Objects; import java.util.logging.LogManager; import jdk.internal.logger.DefaultLoggerFinder; -import java.util.logging.LoggingPermission; import sun.util.logging.PlatformLogger; import sun.util.logging.PlatformLogger.ConfigurableBridge.LoggerConfiguration; @@ -77,15 +74,9 @@ * */ public final class LoggingProviderImpl extends DefaultLoggerFinder { - static final RuntimePermission LOGGERFINDER_PERMISSION = - new RuntimePermission("loggerFinder"); - private static final LoggingPermission LOGGING_CONTROL_PERMISSION = - new LoggingPermission("control", null); /** * Creates a new instance of LoggingProviderImpl. - * @throws SecurityException if the calling code does not have the - * {@code RuntimePermission("loggerFinder")}. */ public LoggingProviderImpl() { } @@ -147,13 +138,13 @@ public void log(sun.util.logging.PlatformLogger.Level level, String msg) { } @Override - public void log(sun.util.logging.PlatformLogger.Level level, Supplier<String> msgSuppier) { - julLogger.log(toJUL(level), msgSuppier); + public void log(sun.util.logging.PlatformLogger.Level level, Supplier<String> msgSupplier) { + julLogger.log(toJUL(level), msgSupplier); } @Override - public void log(sun.util.logging.PlatformLogger.Level level, Throwable thrown, Supplier<String> msgSuppier) { - julLogger.log(toJUL(level), thrown, msgSuppier); + public void log(sun.util.logging.PlatformLogger.Level level, Throwable thrown, Supplier<String> msgSupplier) { + julLogger.log(toJUL(level), thrown, msgSupplier); } @Override @@ -403,18 +394,10 @@ static JULWrapper of(java.util.logging.Logger logger) { * @param module the module for which the logger should be created. * @return a Logger suitable for use in the given module. */ - @SuppressWarnings("removal") private static java.util.logging.Logger demandJULLoggerFor(final String name, Module module) { final LogManager manager = LogManager.getLogManager(); - final SecurityManager sm = System.getSecurityManager(); - if (sm == null) { - return logManagerAccess.demandLoggerFor(manager, name, module); - } else { - final PrivilegedAction<java.util.logging.Logger> pa = - () -> logManagerAccess.demandLoggerFor(manager, name, module); - return AccessController.doPrivileged(pa, null, LOGGING_CONTROL_PERMISSION); - } + return logManagerAccess.demandLoggerFor(manager, name, module); } /** @@ -425,16 +408,9 @@ private static java.util.logging.Logger demandJULLoggerFor(final String name, * corresponding java.util.logging.Logger backend}. * * @return {@inheritDoc} - * @throws SecurityException if the calling code doesn't have the - * {@code RuntimePermission("loggerFinder")}. */ @Override protected Logger demandLoggerFor(String name, Module module) { - @SuppressWarnings("removal") - final SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - sm.checkPermission(LOGGERFINDER_PERMISSION); - } return JULWrapper.of(demandJULLoggerFor(name,module)); } @@ -445,25 +421,17 @@ java.util.logging.Logger demandLoggerFor(LogManager manager, // Hook for tests public static LogManagerAccess getLogManagerAccess() { - @SuppressWarnings("removal") - final SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - sm.checkPermission(LOGGING_CONTROL_PERMISSION); - } - // Triggers initialization of accessJulLogger if not set. + // Triggers initialization of logManagerAccess if not set. + LogManagerAccess logManagerAccess = LoggingProviderImpl.logManagerAccess; if (logManagerAccess == null) LogManager.getLogManager(); + logManagerAccess = LoggingProviderImpl.logManagerAccess; return logManagerAccess; } private static volatile LogManagerAccess logManagerAccess; - public static void setLogManagerAccess(LogManagerAccess accesLoggers) { - @SuppressWarnings("removal") - final SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - sm.checkPermission(LOGGING_CONTROL_PERMISSION); - } - logManagerAccess = accesLoggers; + public static void setLogManagerAccess(LogManagerAccess accessLoggers) { + logManagerAccess = accessLoggers; } } From 8f22db23a50fe537d8ef369e92f0d5f9970d98f0 Mon Sep 17 00:00:00 2001 From: Coleen Phillimore <coleenp@openjdk.org> Date: Thu, 21 Nov 2024 12:14:23 +0000 Subject: [PATCH 153/311] 8330606: Redefinition doesn't but should verify the new klass Reviewed-by: dholmes, jsjolen --- src/hotspot/share/classfile/verifier.cpp | 38 +++---- src/hotspot/share/classfile/verifier.hpp | 1 - src/hotspot/share/oops/method.cpp | 3 +- .../RedefineClasses/RedefineVerifyError.java | 100 ++++++++++++++++++ 4 files changed, 119 insertions(+), 23 deletions(-) create mode 100644 test/hotspot/jtreg/serviceability/jvmti/RedefineClasses/RedefineVerifyError.java diff --git a/src/hotspot/share/classfile/verifier.cpp b/src/hotspot/share/classfile/verifier.cpp index ef3caff6476..9a36584916d 100644 --- a/src/hotspot/share/classfile/verifier.cpp +++ b/src/hotspot/share/classfile/verifier.cpp @@ -105,11 +105,13 @@ static verify_byte_codes_fn_t verify_byte_codes_fn() { // Methods in Verifier +// This method determines whether we run the verifier and class file format checking code. bool Verifier::should_verify_for(oop class_loader) { return class_loader == nullptr ? BytecodeVerificationLocal : BytecodeVerificationRemote; } +// This method determines whether we allow package access in access checks in reflection. bool Verifier::relax_access_for(oop loader) { bool trusted = java_lang_ClassLoader::is_trusted_loader(loader); bool need_verify = @@ -120,6 +122,21 @@ bool Verifier::relax_access_for(oop loader) { return !need_verify; } +// Callers will pass should_verify_class as true, depending on the results of should_verify_for() above, +// or pass true for redefinition of any class. +static bool is_eligible_for_verification(InstanceKlass* klass, bool should_verify_class) { + Symbol* name = klass->name(); + + return (should_verify_class && + // Can not verify the bytecodes for shared classes because they have + // already been rewritten to contain constant pool cache indices, + // which the verifier can't understand. + // Shared classes shouldn't have stackmaps either. + // However, bytecodes for shared old classes can be verified because + // they have not been rewritten. + !(klass->is_shared() && klass->is_rewritten())); +} + void Verifier::trace_class_resolution(Klass* resolve_class, InstanceKlass* verify_class) { assert(verify_class != nullptr, "Unexpected null verify_class"); ResourceMark rm; @@ -273,27 +290,6 @@ bool Verifier::verify(InstanceKlass* klass, bool should_verify_class, TRAPS) { } } -bool Verifier::is_eligible_for_verification(InstanceKlass* klass, bool should_verify_class) { - Symbol* name = klass->name(); - - return (should_verify_class && - // return if the class is a bootstrapping class - // or defineClass specified not to verify by default (flags override passed arg) - // We need to skip the following four for bootstraping - name != vmSymbols::java_lang_Object() && - name != vmSymbols::java_lang_Class() && - name != vmSymbols::java_lang_String() && - name != vmSymbols::java_lang_Throwable() && - - // Can not verify the bytecodes for shared classes because they have - // already been rewritten to contain constant pool cache indices, - // which the verifier can't understand. - // Shared classes shouldn't have stackmaps either. - // However, bytecodes for shared old classes can be verified because - // they have not been rewritten. - !(klass->is_shared() && klass->is_rewritten())); -} - Symbol* Verifier::inference_verify( InstanceKlass* klass, char* message, size_t message_len, TRAPS) { JavaThread* thread = THREAD; diff --git a/src/hotspot/share/classfile/verifier.hpp b/src/hotspot/share/classfile/verifier.hpp index 731d5eb8d3b..7857d472705 100644 --- a/src/hotspot/share/classfile/verifier.hpp +++ b/src/hotspot/share/classfile/verifier.hpp @@ -61,7 +61,6 @@ class Verifier : AllStatic { static void trace_class_resolution(Klass* resolve_class, InstanceKlass* verify_class); private: - static bool is_eligible_for_verification(InstanceKlass* klass, bool should_verify_class); static Symbol* inference_verify( InstanceKlass* klass, char* msg, size_t msg_len, TRAPS); }; diff --git a/src/hotspot/share/oops/method.cpp b/src/hotspot/share/oops/method.cpp index af10efc0f00..d0b29a4a309 100644 --- a/src/hotspot/share/oops/method.cpp +++ b/src/hotspot/share/oops/method.cpp @@ -335,7 +335,8 @@ int Method::bci_from(address bcp) const { int Method::validate_bci(int bci) const { - return (bci == 0 || bci < code_size()) ? bci : -1; + // Called from the verifier, and should return -1 if not valid. + return ((is_native() && bci == 0) || (!is_native() && 0 <= bci && bci < code_size())) ? bci : -1; } // Return bci if it appears to be a valid bcp diff --git a/test/hotspot/jtreg/serviceability/jvmti/RedefineClasses/RedefineVerifyError.java b/test/hotspot/jtreg/serviceability/jvmti/RedefineClasses/RedefineVerifyError.java new file mode 100644 index 00000000000..ea511c05b59 --- /dev/null +++ b/test/hotspot/jtreg/serviceability/jvmti/RedefineClasses/RedefineVerifyError.java @@ -0,0 +1,100 @@ +/* + * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 6402717 8330606 + * @summary Redefine VerifyError to get a VerifyError should not throw SOE + * @requires vm.jvmti + * @library /test/lib + * @modules java.base/jdk.internal.misc + * java.base/jdk.internal.org.objectweb.asm + * java.compiler + * java.instrument + * jdk.jartool/sun.tools.jar + * @run main RedefineClassHelper + * @run main/othervm/timeout=180 + * -javaagent:redefineagent.jar + * -Xlog:class+init,exceptions + * RedefineVerifyError + */ + +import jdk.internal.org.objectweb.asm.AnnotationVisitor; +import jdk.internal.org.objectweb.asm.Attribute; +import jdk.internal.org.objectweb.asm.ClassReader; +import jdk.internal.org.objectweb.asm.ClassWriter; +import jdk.internal.org.objectweb.asm.ConstantDynamic; +import jdk.internal.org.objectweb.asm.FieldVisitor; +import jdk.internal.org.objectweb.asm.Handle; +import jdk.internal.org.objectweb.asm.Label; +import jdk.internal.org.objectweb.asm.MethodVisitor; +import jdk.internal.org.objectweb.asm.Opcodes; +import jdk.internal.org.objectweb.asm.RecordComponentVisitor; +import jdk.internal.org.objectweb.asm.Type; +import jdk.internal.org.objectweb.asm.TypePath; + +public class RedefineVerifyError implements Opcodes { + + // This is a redefinition of java.lang.VerifyError with two broken init methods (no bytecodes) + public static byte[] dump () throws Exception { + + ClassWriter classWriter = new ClassWriter(0); + FieldVisitor fieldVisitor; + RecordComponentVisitor recordComponentVisitor; + MethodVisitor methodVisitor; + AnnotationVisitor annotationVisitor0; + + classWriter.visit(52, ACC_SUPER | ACC_PUBLIC, "java/lang/VerifyError", null, "java/lang/LinkageError", null); + { + fieldVisitor = classWriter.visitField(ACC_PRIVATE | ACC_FINAL | ACC_STATIC, "serialVersionUID", "J", null, new Long(7001962396098498785L)); + fieldVisitor.visitEnd(); + } + { + methodVisitor = classWriter.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null); + methodVisitor.visitCode(); + methodVisitor.visitEnd(); + } + + { + methodVisitor = classWriter.visitMethod(ACC_PUBLIC, "<init>", "(Ljava/lang/String;)V", null, null); + methodVisitor.visitCode(); + classWriter.visitEnd(); + } + + return classWriter.toByteArray(); + } + + public static void main(String[] args) throws Exception { + + Class<?> verifyErrorMirror = java.lang.VerifyError.class; + + try { + // The Verifier is called for the redefinition, which will fail because of the broken <init> method above. + RedefineClassHelper.redefineClass(verifyErrorMirror, dump()); + throw new RuntimeException("This should throw VerifyError"); + } catch (VerifyError e) { + // JVMTI recreates the VerifyError so the verification message is lost. + System.out.println("Passed"); + } + } +} From 882d6358074135b2c4fe21b32bd73f40022980bc Mon Sep 17 00:00:00 2001 From: Artur Barashev <abarashev@openjdk.org> Date: Thu, 21 Nov 2024 14:14:30 +0000 Subject: [PATCH 154/311] 8245545: Disable TLS_RSA cipher suites Reviewed-by: mullan --- .../share/conf/security/java.security | 2 +- test/jdk/javax/net/ssl/DTLS/CipherSuite.java | 8 +++---- test/jdk/javax/net/ssl/SSLEngine/Basics.java | 5 +++-- .../net/ssl/SSLEngine/EngineCloseOnAlert.java | 8 +++++-- .../net/ssl/TLSv11/GenericBlockCipher.java | 6 ++--- .../javax/net/ssl/TLSv12/ProtocolFilter.java | 7 +++++- .../ssl/ciphersuites/DisabledAlgorithms.java | 12 +++++++--- .../ciphersuites/CheckCipherSuites.java | 22 ++----------------- .../SystemPropCipherSuitesOrder.java | 19 +++++++++++++--- .../ciphersuites/TLSCipherSuitesOrder.java | 4 +++- .../pkcs11/tls/tls12/FipsModeTLS12.java | 5 +++++ .../ssl/ClientHandshaker/LengthCheckTest.java | 6 ++--- .../EngineArgs/DebugReportsOneExtraByte.java | 6 ++--- 13 files changed, 64 insertions(+), 46 deletions(-) diff --git a/src/java.base/share/conf/security/java.security b/src/java.base/share/conf/security/java.security index 6374c1951bd..0e24dee6ac2 100644 --- a/src/java.base/share/conf/security/java.security +++ b/src/java.base/share/conf/security/java.security @@ -746,7 +746,7 @@ http.auth.digest.disabledAlgorithms = MD5, SHA-1 # rsa_pkcs1_sha1, secp224r1, TLS_RSA_* jdk.tls.disabledAlgorithms=SSLv3, TLSv1, TLSv1.1, DTLSv1.0, RC4, DES, \ MD5withRSA, DH keySize < 1024, EC keySize < 224, 3DES_EDE_CBC, anon, NULL, \ - ECDH + ECDH, TLS_RSA_* # # Legacy algorithms for Secure Socket Layer/Transport Layer Security (SSL/TLS) diff --git a/test/jdk/javax/net/ssl/DTLS/CipherSuite.java b/test/jdk/javax/net/ssl/DTLS/CipherSuite.java index 7ad8206a37e..b96032fd781 100644 --- a/test/jdk/javax/net/ssl/DTLS/CipherSuite.java +++ b/test/jdk/javax/net/ssl/DTLS/CipherSuite.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -33,16 +33,16 @@ * jdk.crypto.ec * @library /test/lib * @build DTLSOverDatagram - * @run main/othervm CipherSuite TLS_RSA_WITH_AES_128_CBC_SHA + * @run main/othervm CipherSuite TLS_RSA_WITH_AES_128_CBC_SHA re-enable * @run main/othervm CipherSuite TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 - * @run main/othervm CipherSuite TLS_RSA_WITH_AES_128_CBC_SHA256 + * @run main/othervm CipherSuite TLS_RSA_WITH_AES_128_CBC_SHA256 re-enable * @run main/othervm CipherSuite TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 * @run main/othervm CipherSuite TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA * @run main/othervm CipherSuite TLS_DHE_RSA_WITH_AES_128_CBC_SHA * @run main/othervm CipherSuite TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA re-enable * @run main/othervm CipherSuite TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 * @run main/othervm CipherSuite TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 - * @run main/othervm CipherSuite TLS_RSA_WITH_AES_128_GCM_SHA256 + * @run main/othervm CipherSuite TLS_RSA_WITH_AES_128_GCM_SHA256 re-enable * @run main/othervm CipherSuite TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256 re-enable * @run main/othervm CipherSuite TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 * @run main/othervm CipherSuite TLS_DHE_DSS_WITH_AES_128_GCM_SHA256 diff --git a/test/jdk/javax/net/ssl/SSLEngine/Basics.java b/test/jdk/javax/net/ssl/SSLEngine/Basics.java index 3239bfd4ce9..0ee7bfd7738 100644 --- a/test/jdk/javax/net/ssl/SSLEngine/Basics.java +++ b/test/jdk/javax/net/ssl/SSLEngine/Basics.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -57,7 +57,8 @@ public class Basics { "/" + TRUSTSTORE_FILE; public static void main(String[] args) throws Exception { - SecurityUtils.removeFromDisabledTlsAlgs("TLSv1.1"); + // Re-enable TLSv1.1 and TLS_RSA_* since test depends on it. + SecurityUtils.removeFromDisabledTlsAlgs("TLSv1.1", "TLS_RSA_*"); runTest("TLSv1.3", "TLS_AES_256_GCM_SHA384"); runTest("TLSv1.2", "TLS_RSA_WITH_AES_256_GCM_SHA384"); diff --git a/test/jdk/javax/net/ssl/SSLEngine/EngineCloseOnAlert.java b/test/jdk/javax/net/ssl/SSLEngine/EngineCloseOnAlert.java index 7a4f71d8171..57eda1c2a42 100644 --- a/test/jdk/javax/net/ssl/SSLEngine/EngineCloseOnAlert.java +++ b/test/jdk/javax/net/ssl/SSLEngine/EngineCloseOnAlert.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,7 +26,8 @@ * @bug 8133632 * @summary javax.net.ssl.SSLEngine does not properly handle received * SSL fatal alerts - * @run main EngineCloseOnAlert + * @library /test/lib + * @run main/othervm EngineCloseOnAlert */ import java.io.FileInputStream; @@ -36,6 +37,7 @@ import java.util.*; import java.security.*; import static javax.net.ssl.SSLEngineResult.HandshakeStatus.*; +import jdk.test.lib.security.SecurityUtils; public class EngineCloseOnAlert { @@ -61,6 +63,8 @@ public interface TestCase { } public static void main(String[] args) throws Exception { + // Re-enable TLS_RSA_* since test depends on it. + SecurityUtils.removeFromDisabledTlsAlgs("TLS_RSA_*"); int failed = 0; List<TestCase> testMatrix = new LinkedList<TestCase>() {{ add(clientReceivesAlert); diff --git a/test/jdk/javax/net/ssl/TLSv11/GenericBlockCipher.java b/test/jdk/javax/net/ssl/TLSv11/GenericBlockCipher.java index cb67903287e..a634424b3d7 100644 --- a/test/jdk/javax/net/ssl/TLSv11/GenericBlockCipher.java +++ b/test/jdk/javax/net/ssl/TLSv11/GenericBlockCipher.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -172,8 +172,8 @@ void doClientSide() throws Exception { volatile Exception clientException = null; public static void main(String[] args) throws Exception { - // Re-enable TLSv1.1 since test depends on it. - SecurityUtils.removeFromDisabledTlsAlgs("TLSv1.1"); + // Re-enable TLSv1.1 and TLS_RSA_* since test depends on it. + SecurityUtils.removeFromDisabledTlsAlgs("TLSv1.1", "TLS_RSA_*"); String keyFilename = System.getProperty("test.src", ".") + "/" + pathToStores + diff --git a/test/jdk/javax/net/ssl/TLSv12/ProtocolFilter.java b/test/jdk/javax/net/ssl/TLSv12/ProtocolFilter.java index ec58bc74d0c..3291096af48 100644 --- a/test/jdk/javax/net/ssl/TLSv12/ProtocolFilter.java +++ b/test/jdk/javax/net/ssl/TLSv12/ProtocolFilter.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -28,6 +28,7 @@ * @test * @bug 8052406 * @summary SSLv2Hello protocol may be filter out unexpectedly + * @library /test/lib * @run main/othervm ProtocolFilter */ @@ -35,6 +36,8 @@ import java.net.*; import javax.net.ssl.*; +import jdk.test.lib.security.SecurityUtils; + public class ProtocolFilter { /* @@ -156,6 +159,8 @@ void doClientSide() throws Exception { volatile Exception clientException = null; public static void main(String[] args) throws Exception { + // Re-enable TLS_RSA_* since test depends on it. + SecurityUtils.removeFromDisabledTlsAlgs("TLS_RSA_*"); String keyFilename = System.getProperty("test.src", ".") + "/" + pathToStores + "/" + keyStoreFile; diff --git a/test/jdk/javax/net/ssl/ciphersuites/DisabledAlgorithms.java b/test/jdk/javax/net/ssl/ciphersuites/DisabledAlgorithms.java index 994169a7182..8db1dfdeac8 100644 --- a/test/jdk/javax/net/ssl/ciphersuites/DisabledAlgorithms.java +++ b/test/jdk/javax/net/ssl/ciphersuites/DisabledAlgorithms.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,7 +23,7 @@ /* * @test - * @bug 8076221 8211883 8163327 8279164 + * @bug 8076221 8211883 8163327 8279164 8245545 * @summary Check if weak cipher suites are disabled * @library /javax/net/ssl/templates * @modules jdk.crypto.ec @@ -124,7 +124,13 @@ public class DisabledAlgorithms { "TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA", "TLS_ECDH_RSA_WITH_AES_256_CBC_SHA", "TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA", - "TLS_ECDH_RSA_WITH_AES_128_CBC_SHA" + "TLS_ECDH_RSA_WITH_AES_128_CBC_SHA", + "TLS_RSA_WITH_AES_256_GCM_SHA384", + "TLS_RSA_WITH_AES_128_GCM_SHA256", + "TLS_RSA_WITH_AES_256_CBC_SHA256", + "TLS_RSA_WITH_AES_128_CBC_SHA256", + "TLS_RSA_WITH_AES_256_CBC_SHA", + "TLS_RSA_WITH_AES_128_CBC_SHA" }; public static void main(String[] args) throws Exception { diff --git a/test/jdk/javax/net/ssl/sanity/ciphersuites/CheckCipherSuites.java b/test/jdk/javax/net/ssl/sanity/ciphersuites/CheckCipherSuites.java index caa96cdb224..847c69112a0 100644 --- a/test/jdk/javax/net/ssl/sanity/ciphersuites/CheckCipherSuites.java +++ b/test/jdk/javax/net/ssl/sanity/ciphersuites/CheckCipherSuites.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,7 +23,7 @@ /* * @test - * @bug 4750141 4895631 8217579 8163326 8279164 + * @bug 4750141 4895631 8217579 8163326 8279164 8245545 * @summary Check enabled and supported ciphersuites are correct * @run main/othervm CheckCipherSuites default * @run main/othervm CheckCipherSuites limited @@ -99,12 +99,6 @@ public class CheckCipherSuites { "TLS_DHE_DSS_WITH_AES_128_CBC_SHA", // deprecated - "TLS_RSA_WITH_AES_256_GCM_SHA384", - "TLS_RSA_WITH_AES_128_GCM_SHA256", - "TLS_RSA_WITH_AES_256_CBC_SHA256", - "TLS_RSA_WITH_AES_128_CBC_SHA256", - "TLS_RSA_WITH_AES_256_CBC_SHA", - "TLS_RSA_WITH_AES_128_CBC_SHA", "TLS_EMPTY_RENEGOTIATION_INFO_SCSV" }; @@ -124,9 +118,6 @@ public class CheckCipherSuites { "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA", "TLS_DHE_RSA_WITH_AES_128_CBC_SHA", "TLS_DHE_DSS_WITH_AES_128_CBC_SHA", - "TLS_RSA_WITH_AES_128_GCM_SHA256", - "TLS_RSA_WITH_AES_128_CBC_SHA256", - "TLS_RSA_WITH_AES_128_CBC_SHA", "TLS_EMPTY_RENEGOTIATION_INFO_SCSV" }; @@ -194,12 +185,6 @@ public class CheckCipherSuites { "TLS_DHE_DSS_WITH_AES_128_CBC_SHA", // deprecated - "TLS_RSA_WITH_AES_256_GCM_SHA384", - "TLS_RSA_WITH_AES_128_GCM_SHA256", - "TLS_RSA_WITH_AES_256_CBC_SHA256", - "TLS_RSA_WITH_AES_128_CBC_SHA256", - "TLS_RSA_WITH_AES_256_CBC_SHA", - "TLS_RSA_WITH_AES_128_CBC_SHA", "TLS_EMPTY_RENEGOTIATION_INFO_SCSV" }; @@ -219,9 +204,6 @@ public class CheckCipherSuites { "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA", "TLS_DHE_RSA_WITH_AES_128_CBC_SHA", "TLS_DHE_DSS_WITH_AES_128_CBC_SHA", - "TLS_RSA_WITH_AES_128_GCM_SHA256", - "TLS_RSA_WITH_AES_128_CBC_SHA256", - "TLS_RSA_WITH_AES_128_CBC_SHA", "TLS_EMPTY_RENEGOTIATION_INFO_SCSV" }; diff --git a/test/jdk/javax/net/ssl/sanity/ciphersuites/SystemPropCipherSuitesOrder.java b/test/jdk/javax/net/ssl/sanity/ciphersuites/SystemPropCipherSuitesOrder.java index 2817e3400ab..6492e6508de 100644 --- a/test/jdk/javax/net/ssl/sanity/ciphersuites/SystemPropCipherSuitesOrder.java +++ b/test/jdk/javax/net/ssl/sanity/ciphersuites/SystemPropCipherSuitesOrder.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,6 +21,7 @@ * questions. */ import java.util.Arrays; +import java.util.stream.Stream; import javax.net.ssl.SSLServerSocket; import javax.net.ssl.SSLSocket; @@ -86,8 +87,20 @@ public static void main(String[] args) { clientcipherSuites = toArray(System.getProperty("jdk.tls.client.cipherSuites")); System.out.printf("SYSTEM PROPERTIES: ServerProp:%s - ClientProp:%s%n", - Arrays.deepToString(servercipherSuites), - Arrays.deepToString(clientcipherSuites)); + Arrays.deepToString(servercipherSuites), + Arrays.deepToString(clientcipherSuites)); + + // Re-enable TLS_RSA_* cipher suites if needed since test depends on it. + if (Stream.concat( + Arrays.stream( + servercipherSuites == null + ? new String[0] : servercipherSuites), + Arrays.stream( + clientcipherSuites == null + ? new String[0] : clientcipherSuites)) + .anyMatch(s -> s.startsWith("TLS_RSA_"))) { + SecurityUtils.removeFromDisabledTlsAlgs("TLS_RSA_*"); + } try { new SystemPropCipherSuitesOrder(args[0]).run(); diff --git a/test/jdk/javax/net/ssl/sanity/ciphersuites/TLSCipherSuitesOrder.java b/test/jdk/javax/net/ssl/sanity/ciphersuites/TLSCipherSuitesOrder.java index c2171d80889..2ce46eb8471 100644 --- a/test/jdk/javax/net/ssl/sanity/ciphersuites/TLSCipherSuitesOrder.java +++ b/test/jdk/javax/net/ssl/sanity/ciphersuites/TLSCipherSuitesOrder.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -58,6 +58,8 @@ public class TLSCipherSuitesOrder extends SSLSocketTemplate { private final String[] clientcipherSuites; public static void main(String[] args) { + // Re-enable TLS_RSA_* since test depends on it. + SecurityUtils.removeFromDisabledTlsAlgs("TLS_RSA_*"); PROTOCOL protocol = PROTOCOL.valueOf(args[0]); try { new TLSCipherSuitesOrder(protocol.getProtocol(), diff --git a/test/jdk/sun/security/pkcs11/tls/tls12/FipsModeTLS12.java b/test/jdk/sun/security/pkcs11/tls/tls12/FipsModeTLS12.java index e9e4158f20e..f9e9bd472c7 100644 --- a/test/jdk/sun/security/pkcs11/tls/tls12/FipsModeTLS12.java +++ b/test/jdk/sun/security/pkcs11/tls/tls12/FipsModeTLS12.java @@ -1,5 +1,6 @@ /* * Copyright (c) 2019, Red Hat, Inc. + * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -63,6 +64,7 @@ import javax.net.ssl.SSLSession; import javax.net.ssl.TrustManagerFactory; +import jdk.test.lib.security.SecurityUtils; import sun.security.internal.spec.TlsMasterSecretParameterSpec; import sun.security.internal.spec.TlsPrfParameterSpec; import sun.security.internal.spec.TlsRsaPremasterSecretParameterSpec; @@ -80,6 +82,9 @@ public final class FipsModeTLS12 extends SecmodTest { private static PublicKey publicKey; public static void main(String[] args) throws Exception { + // Re-enable TLS_RSA_* since test depends on it. + SecurityUtils.removeFromDisabledTlsAlgs("TLS_RSA_*"); + try { initialize(); } catch (Exception e) { diff --git a/test/jdk/sun/security/ssl/ClientHandshaker/LengthCheckTest.java b/test/jdk/sun/security/ssl/ClientHandshaker/LengthCheckTest.java index 6c9dd847ee9..3aecb84bd94 100644 --- a/test/jdk/sun/security/ssl/ClientHandshaker/LengthCheckTest.java +++ b/test/jdk/sun/security/ssl/ClientHandshaker/LengthCheckTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -270,8 +270,8 @@ public void execTest() throws Exception { * Main entry point for this test. */ public static void main(String args[]) throws Exception { - // Re-enable TLSv1 since test depends on it. - SecurityUtils.removeFromDisabledTlsAlgs("TLSv1"); + // Re-enable TLSv1 and TLS_RSA_* since test depends on it. + SecurityUtils.removeFromDisabledTlsAlgs("TLSv1", "TLS_RSA_*"); List<LengthCheckTest> ccsTests = new ArrayList<>(); diff --git a/test/jdk/sun/security/ssl/EngineArgs/DebugReportsOneExtraByte.java b/test/jdk/sun/security/ssl/EngineArgs/DebugReportsOneExtraByte.java index 7632fcf462f..1446ad786e4 100644 --- a/test/jdk/sun/security/ssl/EngineArgs/DebugReportsOneExtraByte.java +++ b/test/jdk/sun/security/ssl/EngineArgs/DebugReportsOneExtraByte.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -100,8 +100,8 @@ public static void main(String args[]) throws Exception { System.out.println("Test Passed."); } else { - // Re-enable TLSv1 since test depends on it - SecurityUtils.removeFromDisabledTlsAlgs("TLSv1"); + // Re-enable TLSv1 and TLS_RSA_* since test depends on it + SecurityUtils.removeFromDisabledTlsAlgs("TLSv1", "TLS_RSA_*"); DebugReportsOneExtraByte test = new DebugReportsOneExtraByte(); test.runTest(); From eef156180c772a042416fc35d86072e722519f0b Mon Sep 17 00:00:00 2001 From: Phil Race <prr@openjdk.org> Date: Thu, 21 Nov 2024 16:02:28 +0000 Subject: [PATCH 155/311] 8344569: SwingUtilities2.makeIcon_Unprivileged is obsolete Reviewed-by: psadhukhan --- .../classes/javax/swing/LookAndFeel.java | 2 +- .../classes/sun/swing/SwingUtilities2.java | 36 +------------------ 2 files changed, 2 insertions(+), 36 deletions(-) diff --git a/src/java.desktop/share/classes/javax/swing/LookAndFeel.java b/src/java.desktop/share/classes/javax/swing/LookAndFeel.java index 830fadb1c0c..4d31dc9aa02 100644 --- a/src/java.desktop/share/classes/javax/swing/LookAndFeel.java +++ b/src/java.desktop/share/classes/javax/swing/LookAndFeel.java @@ -469,7 +469,7 @@ public static void loadKeyBindings(InputMap retMap, Object[] keys) { * @see Class#getResourceAsStream(String) */ public static Object makeIcon(final Class<?> baseClass, final String gifFile) { - return SwingUtilities2.makeIcon_Unprivileged(baseClass, baseClass, gifFile); + return SwingUtilities2.makeIcon(baseClass, baseClass, gifFile); } /** diff --git a/src/java.desktop/share/classes/sun/swing/SwingUtilities2.java b/src/java.desktop/share/classes/sun/swing/SwingUtilities2.java index 2613ca326ea..eb35920aad0 100644 --- a/src/java.desktop/share/classes/sun/swing/SwingUtilities2.java +++ b/src/java.desktop/share/classes/sun/swing/SwingUtilities2.java @@ -1671,42 +1671,8 @@ public static String displayPropertiesToCSS(Font font, Color fg) { public static Object makeIcon(final Class<?> baseClass, final Class<?> rootClass, final String imageFile) { - return makeIcon(baseClass, rootClass, imageFile, true); - } - - /** - * Utility method that creates a {@code UIDefaults.LazyValue} that - * creates an {@code ImageIcon} {@code UIResource} for the - * specified image file name. The image is loaded using - * {@code getResourceAsStream}, starting with a call to that method - * on the base class parameter. If it cannot be found, searching will - * continue through the base class' inheritance hierarchy, up to and - * including {@code rootClass}. - * - * Finds an image with a given name without privileges enabled. - * - * @param baseClass the first class to use in searching for the resource - * @param rootClass an ancestor of {@code baseClass} to finish the - * search at - * @param imageFile the name of the file to be found - * @return a lazy value that creates the {@code ImageIcon} - * {@code UIResource} for the image, - * or null if it cannot be found - */ - public static Object makeIcon_Unprivileged(final Class<?> baseClass, - final Class<?> rootClass, - final String imageFile) { - return makeIcon(baseClass, rootClass, imageFile, false); - } - - private static Object makeIcon(final Class<?> baseClass, - final Class<?> rootClass, - final String imageFile, - final boolean enablePrivileges) { return (UIDefaults.LazyValue) (table) -> { - byte[] buffer = enablePrivileges ? - getIconBytes(baseClass, rootClass, imageFile) - : getIconBytes(baseClass, rootClass, imageFile); + byte[] buffer = getIconBytes(baseClass, rootClass, imageFile); if (buffer == null) { return null; From aaf3df7bb80d84d3870d8840c2935d4567f83f3c Mon Sep 17 00:00:00 2001 From: Brian Burkhalter <bpb@openjdk.org> Date: Thu, 21 Nov 2024 16:17:58 +0000 Subject: [PATCH 156/311] 8343823: (fs) Files.createLink: inconsistent behavior when creating link to symbolic link Reviewed-by: alanb --- src/java.base/share/classes/java/nio/file/Files.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/java.base/share/classes/java/nio/file/Files.java b/src/java.base/share/classes/java/nio/file/Files.java index 5dd8d219ba9..fa8ff8029e9 100644 --- a/src/java.base/share/classes/java/nio/file/Files.java +++ b/src/java.base/share/classes/java/nio/file/Files.java @@ -982,7 +982,10 @@ public static Path createSymbolicLink(Path link, Path target, * The {@code existing} parameter is the path to an existing file. This * method creates a new directory entry for the file so that it can be * accessed using {@code link} as the path. On some file systems this is - * known as creating a "hard link". Whether the file attributes are + * known as creating a "hard link". If the {@code existing} parameter + * is the path to a symbolic link, then whether the new link is for the + * target of the symbolic link or for the symbolic link itself is platform + * dependent and therefore not specified. Whether the file attributes are * maintained for the file or for each directory entry is file system * specific and therefore not specified. Typically, a file system requires * that all links (directory entries) for a file be on the same file system. From 87be63f85dbbfd8695817a913ef2b2ae5b0d78e9 Mon Sep 17 00:00:00 2001 From: Brian Burkhalter <bpb@openjdk.org> Date: Thu, 21 Nov 2024 16:18:16 +0000 Subject: [PATCH 157/311] 8344659: Some uses of GetPropertyAction were not removed from java.io and java.nio Reviewed-by: lancea, rriggs, iris, dfuchs --- .../macosx/classes/sun/nio/fs/MacOSXFileSystem.java | 5 ++--- .../classes/sun/nio/fs/MacOSXFileSystemProvider.java | 3 +-- src/java.base/share/classes/java/io/Console.java | 3 +-- src/java.base/share/classes/sun/nio/ch/Poller.java | 5 ++--- src/java.base/share/classes/sun/nio/cs/GB18030.java | 5 ++--- .../share/classes/sun/nio/fs/AbstractWatchKey.java | 3 +-- src/java.base/share/classes/sun/nio/fs/Util.java | 6 +++--- .../windows/classes/sun/nio/ch/FileDispatcherImpl.java | 5 ++--- .../windows/classes/sun/nio/fs/WindowsFileAttributes.java | 7 +++---- 9 files changed, 17 insertions(+), 25 deletions(-) diff --git a/src/java.base/macosx/classes/sun/nio/fs/MacOSXFileSystem.java b/src/java.base/macosx/classes/sun/nio/fs/MacOSXFileSystem.java index 9303c713bf2..9b1c5096719 100644 --- a/src/java.base/macosx/classes/sun/nio/fs/MacOSXFileSystem.java +++ b/src/java.base/macosx/classes/sun/nio/fs/MacOSXFileSystem.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,7 +26,6 @@ package sun.nio.fs; import java.util.regex.Pattern; -import sun.security.action.GetPropertyAction; import static sun.nio.fs.MacOSXNativeDispatcher.*; @@ -43,7 +42,7 @@ class MacOSXFileSystem extends BsdFileSystem { static { final String name = PROPERTY_NORMALIZE_FILE_PATHS; - String value = GetPropertyAction.privilegedGetProperty(name); + String value = System.getProperty(name); NORMALIZE_FILE_PATHS = (value != null) && ("".equals(value) || Boolean.parseBoolean(value)); } diff --git a/src/java.base/macosx/classes/sun/nio/fs/MacOSXFileSystemProvider.java b/src/java.base/macosx/classes/sun/nio/fs/MacOSXFileSystemProvider.java index 256a9b5e613..2540478dfca 100644 --- a/src/java.base/macosx/classes/sun/nio/fs/MacOSXFileSystemProvider.java +++ b/src/java.base/macosx/classes/sun/nio/fs/MacOSXFileSystemProvider.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -28,7 +28,6 @@ import java.nio.file.Path; import java.nio.file.spi.FileTypeDetector; import jdk.internal.util.StaticProperty; -import sun.security.action.GetPropertyAction; /** * MacOSX implementation of FileSystemProvider diff --git a/src/java.base/share/classes/java/io/Console.java b/src/java.base/share/classes/java/io/Console.java index 3881b2380ad..4f919c064b9 100644 --- a/src/java.base/share/classes/java/io/Console.java +++ b/src/java.base/share/classes/java/io/Console.java @@ -33,7 +33,6 @@ import jdk.internal.io.JdkConsoleProvider; import jdk.internal.javac.PreviewFeature; import sun.nio.cs.UTF_8; -import sun.security.action.GetPropertyAction; /** * Methods to access the character-based console device, if any, associated @@ -646,7 +645,7 @@ private static UnsupportedOperationException newUnsupportedOperationException() private static final boolean istty = istty(); static final Charset CHARSET = - Charset.forName(GetPropertyAction.privilegedGetProperty("stdout.encoding"), UTF_8.INSTANCE); + Charset.forName(System.getProperty("stdout.encoding"), UTF_8.INSTANCE); private static final Console cons = instantiateConsole(); static { // Set up JavaIOAccess in SharedSecrets diff --git a/src/java.base/share/classes/sun/nio/ch/Poller.java b/src/java.base/share/classes/sun/nio/ch/Poller.java index ec45a398176..d25dfec7f42 100644 --- a/src/java.base/share/classes/sun/nio/ch/Poller.java +++ b/src/java.base/share/classes/sun/nio/ch/Poller.java @@ -36,7 +36,6 @@ import java.util.concurrent.locks.LockSupport; import java.util.function.BooleanSupplier; import jdk.internal.misc.InnocuousThread; -import sun.security.action.GetPropertyAction; /** * Polls file descriptors. Virtual threads invoke the poll method to park @@ -305,7 +304,7 @@ private static class Pollers { Pollers() throws IOException { PollerProvider provider = PollerProvider.provider(); Poller.Mode mode; - String s = GetPropertyAction.privilegedGetProperty("jdk.pollerMode"); + String s = System.getProperty("jdk.pollerMode"); if (s != null) { if (s.equalsIgnoreCase(Mode.SYSTEM_THREADS.name()) || s.equals("1")) { mode = Mode.SYSTEM_THREADS; @@ -418,7 +417,7 @@ List<Poller> writePollers() { * is not a power of 2. */ private static int pollerCount(String propName, int defaultCount) { - String s = GetPropertyAction.privilegedGetProperty(propName); + String s = System.getProperty(propName); int count = (s != null) ? Integer.parseInt(s) : defaultCount; // check power of 2 diff --git a/src/java.base/share/classes/sun/nio/cs/GB18030.java b/src/java.base/share/classes/sun/nio/cs/GB18030.java index 362553a5dbb..2fc58b4ce5e 100644 --- a/src/java.base/share/classes/sun/nio/cs/GB18030.java +++ b/src/java.base/share/classes/sun/nio/cs/GB18030.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -36,7 +36,6 @@ import java.nio.charset.CoderResult; import jdk.internal.misc.VM; import sun.nio.cs.Surrogate; -import sun.security.action.GetPropertyAction; public class GB18030 extends Charset @@ -49,7 +48,7 @@ public class GB18030 // as the system property is not ready to be read in that case. static final boolean IS_2000 = VM.initLevel() >= 1 && - "2000".equals(GetPropertyAction.privilegedGetProperty("jdk.charset.GB18030", "")); + "2000".equals(System.getProperty("jdk.charset.GB18030", "")); public GB18030() { super("GB18030", StandardCharsets.aliases_GB18030()); diff --git a/src/java.base/share/classes/sun/nio/fs/AbstractWatchKey.java b/src/java.base/share/classes/sun/nio/fs/AbstractWatchKey.java index bdb7920b20a..a598302e165 100644 --- a/src/java.base/share/classes/sun/nio/fs/AbstractWatchKey.java +++ b/src/java.base/share/classes/sun/nio/fs/AbstractWatchKey.java @@ -29,7 +29,6 @@ import java.util.*; import jdk.internal.util.ArraysSupport; -import sun.security.action.GetPropertyAction; /** * Base implementation class for watch keys. @@ -44,7 +43,7 @@ abstract class AbstractWatchKey implements WatchKey { */ static final int MAX_EVENT_LIST_SIZE; static { - String rawValue = GetPropertyAction.privilegedGetProperty( + String rawValue = System.getProperty( "jdk.nio.file.WatchService.maxEventsPerPoll", String.valueOf(DEFAULT_MAX_EVENT_LIST_SIZE)); int intValue; diff --git a/src/java.base/share/classes/sun/nio/fs/Util.java b/src/java.base/share/classes/sun/nio/fs/Util.java index 94a5def1e85..01b5238a6b2 100644 --- a/src/java.base/share/classes/sun/nio/fs/Util.java +++ b/src/java.base/share/classes/sun/nio/fs/Util.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -28,7 +28,7 @@ import java.util.*; import java.nio.file.*; import java.nio.charset.Charset; -import sun.security.action.GetPropertyAction; +import jdk.internal.util.StaticProperty; /** * Utility methods @@ -38,7 +38,7 @@ class Util { private Util() { } private static final Charset jnuEncoding = Charset.forName( - GetPropertyAction.privilegedGetProperty("sun.jnu.encoding")); + StaticProperty.jnuEncoding()); /** * Returns {@code Charset} corresponding to the sun.jnu.encoding property diff --git a/src/java.base/windows/classes/sun/nio/ch/FileDispatcherImpl.java b/src/java.base/windows/classes/sun/nio/ch/FileDispatcherImpl.java index 6b7a81c2e85..146e1c17564 100644 --- a/src/java.base/windows/classes/sun/nio/ch/FileDispatcherImpl.java +++ b/src/java.base/windows/classes/sun/nio/ch/FileDispatcherImpl.java @@ -31,7 +31,6 @@ import java.nio.CharBuffer; import jdk.internal.access.JavaIOFileDescriptorAccess; import jdk.internal.access.SharedSecrets; -import sun.security.action.GetPropertyAction; class FileDispatcherImpl extends FileDispatcher { private static final int MAP_INVALID = -1; @@ -189,8 +188,8 @@ int setDirectIO(FileDescriptor fd, String path) { } static boolean isFastFileTransferRequested() { - String fileTransferProp = GetPropertyAction - .privilegedGetProperty("jdk.nio.enableFastFileTransfer", "false"); + String fileTransferProp = + System.getProperty("jdk.nio.enableFastFileTransfer", "false"); return fileTransferProp.isEmpty() ? true : Boolean.parseBoolean(fileTransferProp); } diff --git a/src/java.base/windows/classes/sun/nio/fs/WindowsFileAttributes.java b/src/java.base/windows/classes/sun/nio/fs/WindowsFileAttributes.java index e442c49eadf..6e544b1c926 100644 --- a/src/java.base/windows/classes/sun/nio/fs/WindowsFileAttributes.java +++ b/src/java.base/windows/classes/sun/nio/fs/WindowsFileAttributes.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -28,7 +28,6 @@ import java.nio.file.attribute.*; import java.util.concurrent.TimeUnit; import jdk.internal.misc.Unsafe; -import sun.security.action.GetPropertyAction; import static sun.nio.fs.WindowsNativeDispatcher.*; import static sun.nio.fs.WindowsConstants.*; @@ -115,8 +114,8 @@ class WindowsFileAttributes // indicates if accurate metadata is required (interesting on NTFS only) private static final boolean ensureAccurateMetadata; static { - String propValue = GetPropertyAction.privilegedGetProperty( - "sun.nio.fs.ensureAccurateMetadata", "false"); + String propValue = + System.getProperty("sun.nio.fs.ensureAccurateMetadata", "false"); ensureAccurateMetadata = propValue.isEmpty() ? true : Boolean.parseBoolean(propValue); } From dfa18fe6b395171c821cde02f081e12dd1565ba5 Mon Sep 17 00:00:00 2001 From: Alan Bateman <alanb@openjdk.org> Date: Thu, 21 Nov 2024 16:25:43 +0000 Subject: [PATCH 158/311] 8344328: (dc) DatagramChannelImpl.blockingReceive can now synchronize on packet Reviewed-by: dfuchs, jpai --- .../sun/nio/ch/DatagramChannelImpl.java | 73 ++++++++----------- .../sun/nio/ch/DatagramSocketAdaptor.java | 8 +- 2 files changed, 37 insertions(+), 44 deletions(-) diff --git a/src/java.base/share/classes/sun/nio/ch/DatagramChannelImpl.java b/src/java.base/share/classes/sun/nio/ch/DatagramChannelImpl.java index 74c54105201..33948afbcb0 100644 --- a/src/java.base/share/classes/sun/nio/ch/DatagramChannelImpl.java +++ b/src/java.base/share/classes/sun/nio/ch/DatagramChannelImpl.java @@ -599,8 +599,7 @@ public SocketAddress receive(ByteBuffer dst) throws IOException { * @throws SocketTimeoutException if the timeout elapses */ void blockingReceive(DatagramPacket p, long nanos) throws IOException { - Objects.requireNonNull(p); - assert nanos >= 0; + assert Thread.holdsLock(p) && nanos >= 0; readLock.lock(); try { @@ -615,37 +614,31 @@ void blockingReceive(DatagramPacket p, long nanos) throws IOException { configureSocketNonBlockingIfVirtualThread(); } - // p.bufLength is the maximum size of the datagram that can be received - int bufLength; - synchronized (p) { - bufLength = DatagramPackets.getBufLength(p); - } - boolean completed = false; try { SocketAddress remote = beginRead(true, false); boolean connected = (remote != null); + + // p.bufLength is the maximum size of the datagram that can be received + int bufLength = DatagramPackets.getBufLength(p); ByteBuffer dst = tryBlockingReceive(connected, bufLength, nanos); if (dst != null) { - // if datagram received then get sender and copy to DatagramPacket + // copy to DatagramPacket, set length and sender try { - SocketAddress sender = sourceSocketAddress(); - synchronized (p) { - // copy bytes to the DatagramPacket, and set length and sender. - // Need to re-read p.bufLength in case DatagramPacket changed - int len = Math.min(dst.limit(), DatagramPackets.getBufLength(p)); - dst.get(p.getData(), p.getOffset(), len); - DatagramPackets.setLength(p, len); - p.setSocketAddress(sender); - } + int len = dst.limit(); + dst.get(p.getData(), p.getOffset(), len); + DatagramPackets.setLength(p, len); + p.setSocketAddress(sourceSocketAddress()); } finally { Util.offerFirstTemporaryDirectBuffer(dst); } completed = true; } + } finally { endRead(true, completed); } + } finally { readLock.unlock(); } @@ -835,7 +828,7 @@ public int send(ByteBuffer src, SocketAddress target) * @throws IllegalBlockingModeException if the channel is non-blocking */ void blockingSend(DatagramPacket p) throws IOException { - Objects.requireNonNull(p); + assert Thread.holdsLock(p); writeLock.lock(); try { @@ -843,38 +836,34 @@ void blockingSend(DatagramPacket p) throws IOException { if (!isBlocking()) throw new IllegalBlockingModeException(); - ByteBuffer src = null; + int len = p.getLength(); + ByteBuffer src = Util.getTemporaryDirectBuffer(len); try { + // copy bytes to temporary direct buffer + src.put(p.getData(), p.getOffset(), len); + src.flip(); + + // target address InetSocketAddress target; - synchronized (p) { - int len = p.getLength(); - src = Util.getTemporaryDirectBuffer(len); - - // copy bytes to temporary direct buffer - src.put(p.getData(), p.getOffset(), len); - src.flip(); - - // target address - if (p.getAddress() == null) { - InetSocketAddress remote = remoteAddress(); - if (remote == null) { - throw new IllegalArgumentException("Address not set"); - } - // set address/port to be compatible with long standing behavior - p.setAddress(remote.getAddress()); - p.setPort(remote.getPort()); - target = remote; - } else { - target = (InetSocketAddress) p.getSocketAddress(); + if (p.getAddress() == null) { + InetSocketAddress remote = remoteAddress(); + if (remote == null) { + throw new IllegalArgumentException("Address not set"); } + // set address/port to be compatible with long-standing behavior + p.setAddress(remote.getAddress()); + p.setPort(remote.getPort()); + target = remote; + } else { + target = (InetSocketAddress) p.getSocketAddress(); } // send the datagram (does not block) send(src, target); - } finally { - if (src != null) Util.offerFirstTemporaryDirectBuffer(src); + Util.offerFirstTemporaryDirectBuffer(src); } + } finally { writeLock.unlock(); } diff --git a/src/java.base/share/classes/sun/nio/ch/DatagramSocketAdaptor.java b/src/java.base/share/classes/sun/nio/ch/DatagramSocketAdaptor.java index 6ea20ec6270..4930e1447a3 100644 --- a/src/java.base/share/classes/sun/nio/ch/DatagramSocketAdaptor.java +++ b/src/java.base/share/classes/sun/nio/ch/DatagramSocketAdaptor.java @@ -174,7 +174,9 @@ public SocketAddress getLocalSocketAddress() { @Override public void send(DatagramPacket p) throws IOException { try { - dc.blockingSend(p); + synchronized (p) { + dc.blockingSend(p); + } } catch (AlreadyConnectedException e) { throw new IllegalArgumentException("Connected and packet address differ"); } catch (ClosedChannelException e) { @@ -185,7 +187,9 @@ public void send(DatagramPacket p) throws IOException { @Override public void receive(DatagramPacket p) throws IOException { try { - dc.blockingReceive(p, MILLISECONDS.toNanos(timeout)); + synchronized (p) { + dc.blockingReceive(p, MILLISECONDS.toNanos(timeout)); + } } catch (SocketTimeoutException | ClosedByInterruptException e) { throw e; } catch (InterruptedIOException e) { From 395e404666e51f76270de4de1899aa681ba889c9 Mon Sep 17 00:00:00 2001 From: Abhishek Kumar <abhiscxk@openjdk.org> Date: Thu, 21 Nov 2024 17:39:44 +0000 Subject: [PATCH 159/311] 8344066: Remove SecurityManager uses from the jdk.accessibility module Reviewed-by: prr --- .../accessibility/util/AWTEventMonitor.java | 37 -------- .../accessibility/util/EventQueueMonitor.java | 26 ++---- .../accessibility/util/SwingEventMonitor.java | 89 ------------------- .../accessibility/internal/AccessBridge.java | 29 +----- 4 files changed, 12 insertions(+), 169 deletions(-) diff --git a/src/jdk.accessibility/share/classes/com/sun/java/accessibility/util/AWTEventMonitor.java b/src/jdk.accessibility/share/classes/com/sun/java/accessibility/util/AWTEventMonitor.java index b1b93d795e4..0ba0c5123f2 100644 --- a/src/jdk.accessibility/share/classes/com/sun/java/accessibility/util/AWTEventMonitor.java +++ b/src/jdk.accessibility/share/classes/com/sun/java/accessibility/util/AWTEventMonitor.java @@ -29,7 +29,6 @@ import java.awt.event.*; import javax.swing.*; import javax.swing.event.*; -import sun.awt.AWTPermissions; /** * <P>The {@code AWTEventMonitor} implements a suite of listeners that are @@ -85,17 +84,6 @@ public static Component getComponentWithFocus() { return componentWithFocus; } - /* - * Check permissions - */ - private static void checkInstallPermission() { - @SuppressWarnings("removal") - SecurityManager security = System.getSecurityManager(); - if (security != null) { - security.checkPermission(AWTPermissions.ALL_AWT_EVENTS_PERMISSION); - } - } - /** * Adds the specified listener to receive all {@link EventID#COMPONENT COMPONENT} * events on each component instance in the Java Virtual Machine as they occur. @@ -108,7 +96,6 @@ private static void checkInstallPermission() { */ public static void addComponentListener(ComponentListener l) { if (componentListener == null) { - checkInstallPermission(); awtListener.installListeners(EventID.COMPONENT); } componentListener = AWTEventMulticaster.add(componentListener, l); @@ -190,7 +177,6 @@ public static void removeFocusListener(FocusListener l) { */ public static void addKeyListener(KeyListener l) { if (keyListener == null) { - checkInstallPermission(); awtListener.installListeners(EventID.KEY); } keyListener = AWTEventMulticaster.add(keyListener, l); @@ -222,7 +208,6 @@ public static void removeKeyListener(KeyListener l) { */ public static void addMouseListener(MouseListener l) { if (mouseListener == null) { - checkInstallPermission(); awtListener.installListeners(EventID.MOUSE); } mouseListener = AWTEventMulticaster.add(mouseListener, l); @@ -254,7 +239,6 @@ public static void removeMouseListener(MouseListener l) { */ public static void addMouseMotionListener(MouseMotionListener l) { if (mouseMotionListener == null) { - checkInstallPermission(); awtListener.installListeners(EventID.MOTION); } mouseMotionListener = AWTEventMulticaster.add(mouseMotionListener, l); @@ -286,7 +270,6 @@ public static void removeMouseMotionListener(MouseMotionListener l) { */ public static void addWindowListener(WindowListener l) { if (windowListener == null) { - checkInstallPermission(); awtListener.installListeners(EventID.WINDOW); } windowListener = AWTEventMulticaster.add(windowListener, l); @@ -318,7 +301,6 @@ public static void removeWindowListener(WindowListener l) { */ public static void addActionListener(ActionListener l) { if (actionListener == null) { - checkInstallPermission(); awtListener.installListeners(EventID.ACTION); } actionListener = AWTEventMulticaster.add(actionListener, l); @@ -351,7 +333,6 @@ public static void removeActionListener(ActionListener l) { */ public static void addAdjustmentListener(AdjustmentListener l) { if (adjustmentListener == null) { - checkInstallPermission(); awtListener.installListeners(EventID.ADJUSTMENT); } adjustmentListener = AWTEventMulticaster.add(adjustmentListener, l); @@ -383,7 +364,6 @@ public static void removeAdjustmentListener(AdjustmentListener l) { */ public static void addItemListener(ItemListener l) { if (itemListener == null) { - checkInstallPermission(); awtListener.installListeners(EventID.ITEM); } itemListener = AWTEventMulticaster.add(itemListener, l); @@ -415,7 +395,6 @@ public static void removeItemListener(ItemListener l) { */ public static void addTextListener(TextListener l) { if (textListener == null) { - checkInstallPermission(); awtListener.installListeners(EventID.TEXT); } textListener = AWTEventMulticaster.add(textListener, l); @@ -668,8 +647,6 @@ protected void installListeners(Component c, int eventID) { } } catch (NoSuchMethodException e) { // System.out.println("Exception: " + e.toString()); - } catch (SecurityException e) { - System.out.println("Exception: " + e.toString()); } break; @@ -714,8 +691,6 @@ protected void installListeners(Component c, int eventID) { } } catch (NoSuchMethodException e) { // System.out.println("Exception: " + e.toString()); - } catch (SecurityException e) { - System.out.println("Exception: " + e.toString()); } // [PK] CheckboxMenuItem isn't a component but it does // implement Interface ItemSelectable!! @@ -755,8 +730,6 @@ protected void installListeners(Component c, int eventID) { } } catch (NoSuchMethodException e) { // System.out.println("Exception: " + e.toString()); - } catch (SecurityException e) { - System.out.println("Exception: " + e.toString()); } break; @@ -776,8 +749,6 @@ protected void installListeners(Component c, int eventID) { } } catch (NoSuchMethodException e) { // System.out.println("Exception: " + e.toString()); - } catch (SecurityException e) { - System.out.println("Exception: " + e.toString()); } break; @@ -881,8 +852,6 @@ protected void removeListeners(Component c, int eventID) { } } catch (NoSuchMethodException e) { // System.out.println("Exception: " + e.toString()); - } catch (SecurityException e) { - System.out.println("Exception: " + e.toString()); } break; @@ -921,8 +890,6 @@ protected void removeListeners(Component c, int eventID) { } } catch (NoSuchMethodException e) { // System.out.println("Exception: " + e.toString()); - } catch (SecurityException e) { - System.out.println("Exception: " + e.toString()); } // [PK] CheckboxMenuItem isn't a component but it does // implement Interface ItemSelectable!! @@ -955,8 +922,6 @@ protected void removeListeners(Component c, int eventID) { } } catch (NoSuchMethodException e) { // System.out.println("Exception: " + e.toString()); - } catch (SecurityException e) { - System.out.println("Exception: " + e.toString()); } break; @@ -973,8 +938,6 @@ protected void removeListeners(Component c, int eventID) { } } catch (NoSuchMethodException e) { // System.out.println("Exception: " + e.toString()); - } catch (SecurityException e) { - System.out.println("Exception: " + e.toString()); } break; diff --git a/src/jdk.accessibility/share/classes/com/sun/java/accessibility/util/EventQueueMonitor.java b/src/jdk.accessibility/share/classes/com/sun/java/accessibility/util/EventQueueMonitor.java index cb630223c49..9ef9482e3ec 100644 --- a/src/jdk.accessibility/share/classes/com/sun/java/accessibility/util/EventQueueMonitor.java +++ b/src/jdk.accessibility/share/classes/com/sun/java/accessibility/util/EventQueueMonitor.java @@ -29,8 +29,6 @@ import java.awt.*; import java.awt.event.*; import javax.accessibility.*; -import java.security.AccessController; -import java.security.PrivilegedAction; /** * The {@code EventQueueMonitor} class provides key core functionality for Assistive @@ -142,24 +140,16 @@ static void queueComponentEvent(ComponentEvent e) { /** * Tell the {@code EventQueueMonitor} to start listening for events. */ - @SuppressWarnings("removal") public static void maybeInitialize() { if (cedt == null) { - java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction<Void>() { - public Void run() { - try { - long eventMask = AWTEvent.WINDOW_EVENT_MASK | - AWTEvent.FOCUS_EVENT_MASK | - AWTEvent.MOUSE_MOTION_EVENT_MASK; - - Toolkit.getDefaultToolkit().addAWTEventListener(new EventQueueMonitor(), eventMask); - } catch (Exception e) { - } - return null; - } - } - ); + try { + long eventMask = AWTEvent.WINDOW_EVENT_MASK | + AWTEvent.FOCUS_EVENT_MASK | + AWTEvent.MOUSE_MOTION_EVENT_MASK; + + Toolkit.getDefaultToolkit().addAWTEventListener(new EventQueueMonitor(), eventMask); + } catch (Exception e) { + } } } diff --git a/src/jdk.accessibility/share/classes/com/sun/java/accessibility/util/SwingEventMonitor.java b/src/jdk.accessibility/share/classes/com/sun/java/accessibility/util/SwingEventMonitor.java index df14d2c0da6..f6f3bb686b1 100644 --- a/src/jdk.accessibility/share/classes/com/sun/java/accessibility/util/SwingEventMonitor.java +++ b/src/jdk.accessibility/share/classes/com/sun/java/accessibility/util/SwingEventMonitor.java @@ -976,8 +976,6 @@ protected void installListeners(Component c, int eventID) { } } catch (NoSuchMethodException e) { // System.out.println("Exception: " + e.toString()); - } catch (SecurityException e) { - System.out.println("Exception: " + e.toString()); } break; @@ -1001,8 +999,6 @@ protected void installListeners(Component c, int eventID) { } } catch (NoSuchMethodException e) { // System.out.println("Exception: " + e.toString()); - } catch (SecurityException e) { - System.out.println("Exception: " + e.toString()); } // Look for components which support CellEditor listeners @@ -1023,8 +1019,6 @@ protected void installListeners(Component c, int eventID) { } } catch (NoSuchMethodException e) { // System.out.println("Exception: " + e.toString()); - } catch (SecurityException e) { - System.out.println("Exception: " + e.toString()); } break; @@ -1050,8 +1044,6 @@ protected void installListeners(Component c, int eventID) { } } catch (NoSuchMethodException e) { // System.out.println("Exception: " + e.toString()); - } catch (SecurityException e) { - System.out.println("Exception: " + e.toString()); } // Look for components which support the getModel method @@ -1078,10 +1070,7 @@ protected void installListeners(Component c, int eventID) { } } catch (NoSuchMethodException e) { // System.out.println("Exception: " + e.toString()); - } catch (SecurityException e) { - System.out.println("Exception: " + e.toString()); } - break; case EventID.COLUMNMODEL: @@ -1101,8 +1090,6 @@ protected void installListeners(Component c, int eventID) { } } catch (NoSuchMethodException e) { // System.out.println("Exception: " + e.toString()); - } catch (SecurityException e) { - System.out.println("Exception: " + e.toString()); } break; @@ -1126,8 +1113,6 @@ protected void installListeners(Component c, int eventID) { } } catch (NoSuchMethodException e) { // System.out.println("Exception: " + e.toString()); - } catch (SecurityException e) { - System.out.println("Exception: " + e.toString()); } // Look for components which support Document listeners @@ -1148,8 +1133,6 @@ protected void installListeners(Component c, int eventID) { } } catch (NoSuchMethodException e) { // System.out.println("Exception: " + e.toString()); - } catch (SecurityException e) { - System.out.println("Exception: " + e.toString()); } // Add the monitor as a PropertyChangeListener for document // change events from text components. @@ -1174,8 +1157,6 @@ protected void installListeners(Component c, int eventID) { } } catch (NoSuchMethodException e) { // System.out.println("Exception: " + e.toString()); - } catch (SecurityException e) { - System.out.println("Exception: " + e.toString()); } } break; @@ -1210,8 +1191,6 @@ protected void installListeners(Component c, int eventID) { } } catch (NoSuchMethodException e) { // System.out.println("Exception: " + e.toString()); - } catch (SecurityException e) { - System.out.println("Exception: " + e.toString()); } break; @@ -1234,8 +1213,6 @@ protected void installListeners(Component c, int eventID) { } } catch (NoSuchMethodException e) { // System.out.println("Exception: " + e.toString()); - } catch (SecurityException e) { - System.out.println("Exception: " + e.toString()); } // Look for selection models which support ListSelectionListeners @@ -1257,8 +1234,6 @@ protected void installListeners(Component c, int eventID) { } } catch (NoSuchMethodException e) { // System.out.println("Exception: " + e.toString()); - } catch (SecurityException e) { - System.out.println("Exception: " + e.toString()); } break; @@ -1278,8 +1253,6 @@ protected void installListeners(Component c, int eventID) { } } catch (NoSuchMethodException e) { // System.out.println("Exception: " + e.toString()); - } catch (SecurityException e) { - System.out.println("Exception: " + e.toString()); } break; @@ -1302,8 +1275,6 @@ protected void installListeners(Component c, int eventID) { } } catch (NoSuchMethodException e) { // System.out.println("Exception: " + e.toString()); - } catch (SecurityException e) { - System.out.println("Exception: " + e.toString()); } // Look for components which support getPopupMenu @@ -1329,8 +1300,6 @@ protected void installListeners(Component c, int eventID) { } } catch (NoSuchMethodException e) { // System.out.println("Exception: " + e.toString()); - } catch (SecurityException e) { - System.out.println("Exception: " + e.toString()); } break; @@ -1350,8 +1319,6 @@ protected void installListeners(Component c, int eventID) { } } catch (NoSuchMethodException e) { // System.out.println("Exception: " + e.toString()); - } catch (SecurityException e) { - System.out.println("Exception: " + e.toString()); } break; @@ -1371,8 +1338,6 @@ protected void installListeners(Component c, int eventID) { } } catch (NoSuchMethodException e) { // System.out.println("Exception: " + e.toString()); - } catch (SecurityException e) { - System.out.println("Exception: " + e.toString()); } break; @@ -1396,8 +1361,6 @@ protected void installListeners(Component c, int eventID) { } } catch (NoSuchMethodException e) { // System.out.println("Exception: " + e.toString()); - } catch (SecurityException e) { - System.out.println("Exception: " + e.toString()); } // Look for components which support UndoableEdit listeners @@ -1418,8 +1381,6 @@ protected void installListeners(Component c, int eventID) { } } catch (NoSuchMethodException e) { // System.out.println("Exception: " + e.toString()); - } catch (SecurityException e) { - System.out.println("Exception: " + e.toString()); } break; @@ -1442,8 +1403,6 @@ protected void installListeners(Component c, int eventID) { } } catch (NoSuchMethodException e) { // System.out.println("Exception: " + e.toString()); - } catch (SecurityException e) { - System.out.println("Exception: " + e.toString()); } break; @@ -1466,8 +1425,6 @@ protected void installListeners(Component c, int eventID) { } } catch (NoSuchMethodException e) { // System.out.println("Exception: " + e.toString()); - } catch (SecurityException e) { - System.out.println("Exception: " + e.toString()); } // Look for components which support the getSelectionModel method @@ -1489,8 +1446,6 @@ protected void installListeners(Component c, int eventID) { } } catch (NoSuchMethodException e) { // System.out.println("Exception: " + e.toString()); - } catch (SecurityException e) { - System.out.println("Exception: " + e.toString()); } break; @@ -1622,8 +1577,6 @@ protected void removeListeners(Component c, int eventID) { } } catch (NoSuchMethodException e) { // System.out.println("Exception: " + e.toString()); - } catch (SecurityException e) { - System.out.println("Exception: " + e.toString()); } break; @@ -1646,8 +1599,6 @@ protected void removeListeners(Component c, int eventID) { } } catch (NoSuchMethodException e) { // System.out.println("Exception: " + e.toString()); - } catch (SecurityException e) { - System.out.println("Exception: " + e.toString()); } // Look for components which support CellEditor listeners @@ -1665,8 +1616,6 @@ protected void removeListeners(Component c, int eventID) { } } catch (NoSuchMethodException e) { // System.out.println("Exception: " + e.toString()); - } catch (SecurityException e) { - System.out.println("Exception: " + e.toString()); } break; @@ -1689,8 +1638,6 @@ protected void removeListeners(Component c, int eventID) { } } catch (NoSuchMethodException e) { // System.out.println("Exception: " + e.toString()); - } catch (SecurityException e) { - System.out.println("Exception: " + e.toString()); } // Look for components which support the getModel method @@ -1714,8 +1661,6 @@ protected void removeListeners(Component c, int eventID) { } } catch (NoSuchMethodException e) { // System.out.println("Exception: " + e.toString()); - } catch (SecurityException e) { - System.out.println("Exception: " + e.toString()); } break; @@ -1735,8 +1680,6 @@ protected void removeListeners(Component c, int eventID) { } } catch (NoSuchMethodException e) { // System.out.println("Exception: " + e.toString()); - } catch (SecurityException e) { - System.out.println("Exception: " + e.toString()); } break; @@ -1759,8 +1702,6 @@ protected void removeListeners(Component c, int eventID) { } } catch (NoSuchMethodException e) { // System.out.println("Exception: " + e.toString()); - } catch (SecurityException e) { - System.out.println("Exception: " + e.toString()); } // Look for components which support Document listeners @@ -1778,8 +1719,6 @@ protected void removeListeners(Component c, int eventID) { } } catch (NoSuchMethodException e) { // System.out.println("Exception: " + e.toString()); - } catch (SecurityException e) { - System.out.println("Exception: " + e.toString()); } break; @@ -1810,8 +1749,6 @@ protected void removeListeners(Component c, int eventID) { } } catch (NoSuchMethodException e) { // System.out.println("Exception: " + e.toString()); - } catch (SecurityException e) { - System.out.println("Exception: " + e.toString()); } break; @@ -1831,8 +1768,6 @@ protected void removeListeners(Component c, int eventID) { } } catch (NoSuchMethodException e) { // System.out.println("Exception: " + e.toString()); - } catch (SecurityException e) { - System.out.println("Exception: " + e.toString()); } // Look for selection models which support @@ -1853,8 +1788,6 @@ protected void removeListeners(Component c, int eventID) { } } catch (NoSuchMethodException e) { // System.out.println("Exception: " + e.toString()); - } catch (SecurityException e) { - System.out.println("Exception: " + e.toString()); } break; @@ -1871,8 +1804,6 @@ protected void removeListeners(Component c, int eventID) { } } catch (NoSuchMethodException e) { // System.out.println("Exception: " + e.toString()); - } catch (SecurityException e) { - System.out.println("Exception: " + e.toString()); } break; @@ -1892,8 +1823,6 @@ protected void removeListeners(Component c, int eventID) { } } catch (NoSuchMethodException e) { // System.out.println("Exception: " + e.toString()); - } catch (SecurityException e) { - System.out.println("Exception: " + e.toString()); } // Look for components which support getPopupMenu @@ -1916,8 +1845,6 @@ protected void removeListeners(Component c, int eventID) { } } catch (NoSuchMethodException e) { // System.out.println("Exception: " + e.toString()); - } catch (SecurityException e) { - System.out.println("Exception: " + e.toString()); } break; @@ -1934,8 +1861,6 @@ protected void removeListeners(Component c, int eventID) { } } catch (NoSuchMethodException e) { // System.out.println("Exception: " + e.toString()); - } catch (SecurityException e) { - System.out.println("Exception: " + e.toString()); } break; @@ -1952,8 +1877,6 @@ protected void removeListeners(Component c, int eventID) { } } catch (NoSuchMethodException e) { // System.out.println("Exception: " + e.toString()); - } catch (SecurityException e) { - System.out.println("Exception: " + e.toString()); } break; @@ -1976,8 +1899,6 @@ protected void removeListeners(Component c, int eventID) { } } catch (NoSuchMethodException e) { // System.out.println("Exception: " + e.toString()); - } catch (SecurityException e) { - System.out.println("Exception: " + e.toString()); } // Look for components which support UndoableEdit listeners @@ -1995,8 +1916,6 @@ protected void removeListeners(Component c, int eventID) { } } catch (NoSuchMethodException e) { // System.out.println("Exception: " + e.toString()); - } catch (SecurityException e) { - System.out.println("Exception: " + e.toString()); } break; @@ -2013,8 +1932,6 @@ protected void removeListeners(Component c, int eventID) { } } catch (NoSuchMethodException e) { // System.out.println("Exception: " + e.toString()); - } catch (SecurityException e) { - System.out.println("Exception: " + e.toString()); } break; @@ -2034,8 +1951,6 @@ protected void removeListeners(Component c, int eventID) { } } catch (NoSuchMethodException e) { // System.out.println("Exception: " + e.toString()); - } catch (SecurityException e) { - System.out.println("Exception: " + e.toString()); } // Look for components which support the getSelectionModel @@ -2056,8 +1971,6 @@ protected void removeListeners(Component c, int eventID) { } } catch (NoSuchMethodException e) { // System.out.println("Exception: " + e.toString()); - } catch (SecurityException e) { - System.out.println("Exception: " + e.toString()); } break; @@ -2512,8 +2425,6 @@ public void propertyChange(PropertyChangeEvent e) { } } catch (NoSuchMethodException e2) { // System.out.println("Exception: " + e2.toString()); - } catch (SecurityException e2) { - System.out.println("Exception: " + e2.toString()); } } diff --git a/src/jdk.accessibility/windows/classes/com/sun/java/accessibility/internal/AccessBridge.java b/src/jdk.accessibility/windows/classes/com/sun/java/accessibility/internal/AccessBridge.java index b5a5943d2d9..e6792b3ef10 100644 --- a/src/jdk.accessibility/windows/classes/com/sun/java/accessibility/internal/AccessBridge.java +++ b/src/jdk.accessibility/windows/classes/com/sun/java/accessibility/internal/AccessBridge.java @@ -160,44 +160,23 @@ public final class AccessBridge { initStatic(); } - @SuppressWarnings({"removal", "restricted"}) + @SuppressWarnings("restricted") private static void initStatic() { // Load the appropriate DLLs boolean is32on64 = false; if (System.getProperty("os.arch").equals("x86")) { // 32 bit JRE // Load jabsysinfo.dll so can determine Win bitness - java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction<Void>() { - public Void run() { - System.loadLibrary("jabsysinfo"); - return null; - } - }, null, new java.lang.RuntimePermission("loadLibrary.jabsysinfo") - ); + System.loadLibrary("jabsysinfo"); if (isSysWow()) { // 32 bit JRE on 64 bit OS is32on64 = true; - java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction<Void>() { - public Void run() { - System.loadLibrary("javaaccessbridge-32"); - return null; - } - }, null, new java.lang.RuntimePermission("loadLibrary.javaaccessbridge-32") - ); + System.loadLibrary("javaaccessbridge-32"); } } if (!is32on64) { // 32 bit JRE on 32 bit OS or 64 bit JRE on 64 bit OS - java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction<Void>() { - public Void run() { - System.loadLibrary("javaaccessbridge"); - return null; - } - }, null, new java.lang.RuntimePermission("loadLibrary.javaaccessbridge") - ); + System.loadLibrary("javaaccessbridge"); } } From 6113fa75035440aa211c9df291c02dc9d0d40b4b Mon Sep 17 00:00:00 2001 From: Sean Mullan <mullan@openjdk.org> Date: Thu, 21 Nov 2024 17:45:04 +0000 Subject: [PATCH 160/311] 8344248: Remove Security Manager dependencies from java.security.jgss and jdk.security.jgss modules Reviewed-by: ascarpino --- src/java.base/share/classes/module-info.java | 3 +- .../auth/kerberos/KerberosPrincipal.java | 13 -- .../javax/security/auth/kerberos/KeyTab.java | 16 +-- .../protocol/http/spnego/NegotiatorImpl.java | 4 +- .../sun/security/jgss/GSSManagerImpl.java | 5 +- .../classes/sun/security/jgss/GSSUtil.java | 97 +++++-------- .../sun/security/jgss/LoginConfigImpl.java | 11 +- .../sun/security/jgss/ProviderList.java | 4 +- .../sun/security/jgss/SunProvider.java | 20 +-- .../jgss/krb5/AcceptSecContextToken.java | 7 +- .../jgss/krb5/InitSecContextToken.java | 5 +- .../sun/security/jgss/krb5/InitialToken.java | 11 +- .../jgss/krb5/Krb5AcceptCredential.java | 23 ++- .../sun/security/jgss/krb5/Krb5Context.java | 75 +++------- .../jgss/krb5/Krb5InitCredential.java | 26 ++-- .../security/jgss/krb5/Krb5MechFactory.java | 63 +-------- .../security/jgss/krb5/Krb5NameElement.java | 17 +-- .../sun/security/jgss/krb5/Krb5Util.java | 1 - .../security/jgss/spnego/SpNegoContext.java | 6 +- .../jgss/spnego/SpNegoMechFactory.java | 27 +--- .../security/jgss/wrapper/GSSCredElement.java | 23 +-- .../security/jgss/wrapper/GSSNameElement.java | 26 +--- .../sun/security/jgss/wrapper/Krb5Util.java | 19 +-- .../jgss/wrapper/NativeGSSContext.java | 87 +----------- .../jgss/wrapper/NativeGSSFactory.java | 11 +- .../jgss/wrapper/SunNativeProvider.java | 133 ++++++++---------- .../classes/sun/security/krb5/Config.java | 107 ++++---------- .../sun/security/krb5/Credentials.java | 18 +-- .../classes/sun/security/krb5/KdcComm.java | 106 ++++---------- .../sun/security/krb5/KrbServiceLocator.java | 35 +---- .../classes/sun/security/krb5/Realm.java | 7 +- .../security/krb5/SCDynamicStoreConfig.java | 21 ++- .../sun/security/krb5/internal/Krb5.java | 5 +- .../security/krb5/internal/ReplayCache.java | 6 +- .../internal/ccache/FileCredentialsCache.java | 46 +++--- .../security/krb5/internal/crypto/Des.java | 5 +- .../security/krb5/internal/ktab/KeyTab.java | 7 +- .../internal/rcache/AuthTimeWithHash.java | 6 +- .../krb5/internal/rcache/DflCache.java | 5 +- .../krb5/internal/util/KerberosString.java | 7 +- .../security/jgss/ExtendedGSSContextImpl.java | 8 +- .../sun/security/sasl/gsskerb/JdkSASL.java | 18 +-- 42 files changed, 287 insertions(+), 853 deletions(-) diff --git a/src/java.base/share/classes/module-info.java b/src/java.base/share/classes/module-info.java index 828e0d41504..c91a8d2613c 100644 --- a/src/java.base/share/classes/module-info.java +++ b/src/java.base/share/classes/module-info.java @@ -320,8 +320,7 @@ java.rmi, java.sql.rowset; exports sun.security.action to - java.desktop, - java.security.jgss; + java.desktop; exports sun.security.internal.interfaces to jdk.crypto.cryptoki; exports sun.security.internal.spec to diff --git a/src/java.security.jgss/share/classes/javax/security/auth/kerberos/KerberosPrincipal.java b/src/java.security.jgss/share/classes/javax/security/auth/kerberos/KerberosPrincipal.java index 9a59428f62e..804814f0ef3 100644 --- a/src/java.security.jgss/share/classes/javax/security/auth/kerberos/KerberosPrincipal.java +++ b/src/java.security.jgss/share/classes/javax/security/auth/kerberos/KerberosPrincipal.java @@ -176,19 +176,6 @@ public KerberosPrincipal(String name, int nameType) { throw new IllegalArgumentException(e.getMessage()); } - if (krb5Principal.isRealmDeduced() && !Realm.AUTODEDUCEREALM) { - @SuppressWarnings("removal") - SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - try { - sm.checkPermission(new ServicePermission( - "@" + krb5Principal.getRealmAsString(), "-")); - } catch (SecurityException se) { - // Swallow the actual exception to hide info - throw new SecurityException("Cannot read realm info"); - } - } - } this.nameType = nameType; fullName = krb5Principal.toString(); realm = krb5Principal.getRealmString(); diff --git a/src/java.security.jgss/share/classes/javax/security/auth/kerberos/KeyTab.java b/src/java.security.jgss/share/classes/javax/security/auth/kerberos/KeyTab.java index b58029ed0af..bf8af4d1d75 100644 --- a/src/java.security.jgss/share/classes/javax/security/auth/kerberos/KeyTab.java +++ b/src/java.security.jgss/share/classes/javax/security/auth/kerberos/KeyTab.java @@ -26,7 +26,6 @@ package javax.security.auth.kerberos; import java.io.File; -import java.security.AccessControlException; import java.util.Objects; import sun.security.krb5.EncryptionKey; import sun.security.krb5.KerberosSecrets; @@ -210,20 +209,7 @@ public static KeyTab getInstance(KerberosPrincipal princ) { // Takes a snapshot of the keytab content. This method is called by // JavaxSecurityAuthKerberosAccessImpl so no more private sun.security.krb5.internal.ktab.KeyTab takeSnapshot() { - try { - return sun.security.krb5.internal.ktab.KeyTab.getInstance(file); - } catch (@SuppressWarnings("removal") AccessControlException ace) { - if (file != null) { - // It's OK to show the name if caller specified it - throw ace; - } else { - @SuppressWarnings("removal") - AccessControlException ace2 = new AccessControlException( - "Access to default keytab denied (modified exception)"); - ace2.setStackTrace(ace.getStackTrace()); - throw ace2; - } - } + return sun.security.krb5.internal.ktab.KeyTab.getInstance(file); } /** diff --git a/src/java.security.jgss/share/classes/sun/net/www/protocol/http/spnego/NegotiatorImpl.java b/src/java.security.jgss/share/classes/sun/net/www/protocol/http/spnego/NegotiatorImpl.java index fe9031e9bd0..22c65a9267e 100644 --- a/src/java.security.jgss/share/classes/sun/net/www/protocol/http/spnego/NegotiatorImpl.java +++ b/src/java.security.jgss/share/classes/sun/net/www/protocol/http/spnego/NegotiatorImpl.java @@ -35,7 +35,6 @@ import sun.net.www.protocol.http.HttpCallerInfo; import sun.net.www.protocol.http.Negotiator; -import sun.security.action.GetPropertyAction; import sun.security.jgss.GSSManagerImpl; import sun.security.jgss.GSSContextImpl; import sun.security.jgss.GSSUtil; @@ -74,8 +73,7 @@ private void init(HttpCallerInfo hci) throws GSSException, ChannelBindingExcepti // we can only use Kerberos mech when the scheme is kerberos oid = GSSUtil.GSS_KRB5_MECH_OID; } else { - String pref = GetPropertyAction - .privilegedGetProperty("http.auth.preference", "spnego"); + String pref = System.getProperty("http.auth.preference", "spnego"); if (pref.equalsIgnoreCase("kerberos")) { oid = GSSUtil.GSS_KRB5_MECH_OID; } else { diff --git a/src/java.security.jgss/share/classes/sun/security/jgss/GSSManagerImpl.java b/src/java.security.jgss/share/classes/sun/security/jgss/GSSManagerImpl.java index 8b40b759085..cdfdf795b8c 100644 --- a/src/java.security.jgss/share/classes/sun/security/jgss/GSSManagerImpl.java +++ b/src/java.security.jgss/share/classes/sun/security/jgss/GSSManagerImpl.java @@ -26,7 +26,6 @@ package sun.security.jgss; import org.ietf.jgss.*; -import sun.security.action.GetBooleanAction; import sun.security.jgss.spi.*; import java.security.Provider; @@ -37,8 +36,8 @@ public class GSSManagerImpl extends GSSManager { // Undocumented property - private static final Boolean USE_NATIVE = GetBooleanAction - .privilegedGetProperty("sun.security.jgss.native"); + private static final Boolean USE_NATIVE = + Boolean.getBoolean("sun.security.jgss.native"); private final ProviderList list; diff --git a/src/java.security.jgss/share/classes/sun/security/jgss/GSSUtil.java b/src/java.security.jgss/share/classes/sun/security/jgss/GSSUtil.java index f2e7599c1e0..a0c36df46c7 100644 --- a/src/java.security.jgss/share/classes/sun/security/jgss/GSSUtil.java +++ b/src/java.security.jgss/share/classes/sun/security/jgss/GSSUtil.java @@ -32,16 +32,12 @@ import org.ietf.jgss.*; import sun.security.jgss.spi.GSSNameSpi; import sun.security.jgss.spi.GSSCredentialSpi; -import sun.security.action.GetPropertyAction; import sun.security.jgss.krb5.Krb5NameElement; import sun.security.jgss.spnego.SpNegoCredElement; import java.util.Set; import java.util.HashSet; import java.util.Vector; import java.util.Iterator; -import java.security.AccessController; -import java.security.PrivilegedExceptionAction; -import java.security.PrivilegedActionException; import javax.security.auth.callback.CallbackHandler; import javax.security.auth.login.LoginContext; import javax.security.auth.login.LoginException; @@ -67,8 +63,8 @@ public class GSSUtil { public static final Oid NT_GSS_KRB5_PRINCIPAL = GSSUtil.createOid("1.2.840.113554.1.2.2.1"); - static final Debug DEBUG = Debug.of("jgss", GetPropertyAction - .privilegedGetProperty("sun.security.jgss.debug")); + static final Debug DEBUG = Debug.of("jgss", + System.getProperty("sun.security.jgss.debug")); static void debug(String message) { assert(message != null); @@ -268,8 +264,8 @@ public static Subject login(GSSCaller caller, Oid mech) throws LoginException { */ public static boolean useSubjectCredsOnly(GSSCaller caller) { - String propValue = GetPropertyAction - .privilegedGetProperty("javax.security.auth.useSubjectCredsOnly"); + String propValue = + System.getProperty("javax.security.auth.useSubjectCredsOnly"); // Invalid values should be ignored and the default assumed. if (caller instanceof HttpCaller) { @@ -290,11 +286,11 @@ public static boolean useSubjectCredsOnly(GSSCaller caller) { */ public static boolean useMSInterop() { /* - * Don't use GetBooleanAction because the default value in the JRE + * Don't use Boolean.getBoolean() because the default value in the JRE * (when this is unset) has to treated as true. */ - String propValue = GetPropertyAction - .privilegedGetProperty("sun.security.spnego.msinterop", "true"); + String propValue = + System.getProperty("sun.security.spnego.msinterop", "true"); /* * This property has to be explicitly set to "false". Invalid * values should be ignored and the default "true" assumed. @@ -320,56 +316,41 @@ public static boolean useMSInterop() { (name == null ? "<<DEF>>" : name.toString()) + ", " + credCls.getName() + ")"); } - try { - @SuppressWarnings("removal") - Vector<T> creds = - AccessController.doPrivilegedWithCombiner - ((PrivilegedExceptionAction<Vector<T>>) () -> { - Subject currSubj = Subject.current(); - Vector<T> result = null; - if (currSubj != null) { - result = new Vector<>(); - Iterator<GSSCredentialImpl> iterator = - currSubj.getPrivateCredentials - (GSSCredentialImpl.class).iterator(); - while (iterator.hasNext()) { - GSSCredentialImpl cred = iterator.next(); - if (DEBUG != null) { - debug("...Found cred" + cred); - } - try { - GSSCredentialSpi ce = - cred.getElement(mech, initiate); - if (DEBUG != null) { - debug("......Found element: " + ce); - } - if (ce.getClass().equals(credCls) && - (name == null || - name.equals((Object) ce.getName()))) { - result.add(credCls.cast(ce)); - } else { - if (DEBUG != null) { - debug("......Discard element"); - } - } - } catch (GSSException ge) { - if (DEBUG != null) { - debug("...Discard cred (" + ge + ")"); - } - } + Vector<T> creds = null; + Subject currSubj = Subject.current(); + if (currSubj != null) { + creds = new Vector<>(); + Iterator<GSSCredentialImpl> iterator = + currSubj.getPrivateCredentials + (GSSCredentialImpl.class).iterator(); + while (iterator.hasNext()) { + GSSCredentialImpl cred = iterator.next(); + if (DEBUG != null) { + debug("...Found cred" + cred); + } + try { + GSSCredentialSpi ce = cred.getElement(mech, initiate); + if (DEBUG != null) { + debug("......Found element: " + ce); + } + if (ce.getClass().equals(credCls) && + (name == null || + name.equals((Object) ce.getName()))) { + creds.add(credCls.cast(ce)); + } else { + if (DEBUG != null) { + debug("......Discard element"); } - } else if (DEBUG != null) { - debug("No Subject"); } - return result; - }); - return creds; - } catch (PrivilegedActionException pae) { - if (DEBUG != null) { - debug("Unexpected exception when searching Subject:"); - pae.printStackTrace(); + } catch (GSSException ge) { + if (DEBUG != null) { + debug("...Discard cred (" + ge + ")"); + } + } } - return null; + } else if (DEBUG != null) { + debug("No Subject"); } + return creds; } } diff --git a/src/java.security.jgss/share/classes/sun/security/jgss/LoginConfigImpl.java b/src/java.security.jgss/share/classes/sun/security/jgss/LoginConfigImpl.java index 7052be9bbf6..8e45393bfe4 100644 --- a/src/java.security.jgss/share/classes/sun/security/jgss/LoginConfigImpl.java +++ b/src/java.security.jgss/share/classes/sun/security/jgss/LoginConfigImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,12 +25,10 @@ package sun.security.jgss; -import java.security.PrivilegedAction; import java.util.HashMap; import javax.security.auth.login.AppConfigurationEntry; import javax.security.auth.login.Configuration; import org.ietf.jgss.Oid; -import sun.security.action.GetPropertyAction; /** * A Configuration implementation especially designed for JGSS. @@ -49,8 +47,7 @@ public class LoginConfigImpl extends Configuration { public static final boolean HTTP_USE_GLOBAL_CREDS; static { - String prop = GetPropertyAction - .privilegedGetProperty("http.use.global.creds"); + String prop = System.getProperty("http.use.global.creds"); //HTTP_USE_GLOBAL_CREDS = "true".equalsIgnoreCase(prop); // default false HTTP_USE_GLOBAL_CREDS = !"false".equalsIgnoreCase(prop); // default true } @@ -62,7 +59,6 @@ public class LoginConfigImpl extends Configuration { * @param caller defined in GSSUtil as CALLER_XXX final fields * @param mech defined in GSSUtil as XXX_MECH_OID final fields */ - @SuppressWarnings("removal") public LoginConfigImpl(GSSCaller caller, Oid mech) { this.caller = caller; @@ -72,8 +68,7 @@ public LoginConfigImpl(GSSCaller caller, Oid mech) { } else { throw new IllegalArgumentException(mech.toString() + " not supported"); } - config = java.security.AccessController.doPrivileged - ((PrivilegedAction<Configuration>) Configuration::getConfiguration); + config = Configuration.getConfiguration(); } /** diff --git a/src/java.security.jgss/share/classes/sun/security/jgss/ProviderList.java b/src/java.security.jgss/share/classes/sun/security/jgss/ProviderList.java index 484f0a7cfa6..37745728a35 100644 --- a/src/java.security.jgss/share/classes/sun/security/jgss/ProviderList.java +++ b/src/java.security.jgss/share/classes/sun/security/jgss/ProviderList.java @@ -38,7 +38,6 @@ import sun.security.jgss.spi.*; import sun.security.jgss.wrapper.NativeGSSFactory; import sun.security.jgss.wrapper.SunNativeProvider; -import sun.security.action.GetPropertyAction; /** * This class stores the list of providers that this @@ -102,8 +101,7 @@ public final class ProviderList { * with a valid OID value */ Oid defOid = null; - String defaultOidStr = GetPropertyAction - .privilegedGetProperty("sun.security.jgss.mechanism"); + String defaultOidStr = System.getProperty("sun.security.jgss.mechanism"); if (defaultOidStr != null) { defOid = GSSUtil.createOid(defaultOidStr); } diff --git a/src/java.security.jgss/share/classes/sun/security/jgss/SunProvider.java b/src/java.security.jgss/share/classes/sun/security/jgss/SunProvider.java index b1cb1f7924f..a472795b3e5 100644 --- a/src/java.security.jgss/share/classes/sun/security/jgss/SunProvider.java +++ b/src/java.security.jgss/share/classes/sun/security/jgss/SunProvider.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -27,8 +27,6 @@ import java.io.Serial; import java.security.Provider; -import java.security.AccessController; -import java.security.PrivilegedAction; import java.security.NoSuchAlgorithmException; import java.security.InvalidParameterException; import java.security.ProviderException; @@ -100,20 +98,16 @@ public Object newInstance(Object ctrParamObj) } } - @SuppressWarnings("removal") public SunProvider() { /* We are the Sun JGSS provider */ super("SunJGSS", PROVIDER_VER, INFO); final Provider p = this; - AccessController.doPrivileged((PrivilegedAction<Void>) () -> { - putService(new ProviderService(p, "GssApiMechanism", - "1.2.840.113554.1.2.2", - "sun.security.jgss.krb5.Krb5MechFactory")); - putService(new ProviderService(p, "GssApiMechanism", - "1.3.6.1.5.5.2", - "sun.security.jgss.spnego.SpNegoMechFactory")); - return null; - }); + putService(new ProviderService(p, "GssApiMechanism", + "1.2.840.113554.1.2.2", + "sun.security.jgss.krb5.Krb5MechFactory")); + putService(new ProviderService(p, "GssApiMechanism", + "1.3.6.1.5.5.2", + "sun.security.jgss.spnego.SpNegoMechFactory")); } } diff --git a/src/java.security.jgss/share/classes/sun/security/jgss/krb5/AcceptSecContextToken.java b/src/java.security.jgss/share/classes/sun/security/jgss/krb5/AcceptSecContextToken.java index da1e88c2174..ec4caa507ee 100644 --- a/src/java.security.jgss/share/classes/sun/security/jgss/krb5/AcceptSecContextToken.java +++ b/src/java.security.jgss/share/classes/sun/security/jgss/krb5/AcceptSecContextToken.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -29,7 +29,6 @@ import java.io.InputStream; import java.io.IOException; -import sun.security.action.GetBooleanAction; import sun.security.krb5.*; class AcceptSecContextToken extends InitialToken { @@ -44,8 +43,8 @@ public AcceptSecContextToken(Krb5Context context, KrbApReq apReq) throws KrbException, IOException, GSSException { - boolean useSubkey = GetBooleanAction - .privilegedGetProperty("sun.security.krb5.acceptor.subkey"); + boolean useSubkey = Boolean.getBoolean( + "sun.security.krb5.acceptor.subkey"); boolean useSequenceNumber = true; diff --git a/src/java.security.jgss/share/classes/sun/security/jgss/krb5/InitSecContextToken.java b/src/java.security.jgss/share/classes/sun/security/jgss/krb5/InitSecContextToken.java index a0b0599db7d..1b61dcb36f5 100644 --- a/src/java.security.jgss/share/classes/sun/security/jgss/krb5/InitSecContextToken.java +++ b/src/java.security.jgss/share/classes/sun/security/jgss/krb5/InitSecContextToken.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -29,7 +29,6 @@ import java.io.InputStream; import java.io.IOException; -import sun.security.action.GetPropertyAction; import sun.security.krb5.*; import java.net.InetAddress; import sun.security.krb5.internal.AuthorizationData; @@ -53,7 +52,7 @@ class InitSecContextToken extends InitialToken { // property "sun.security.krb5.acceptor.sequence.number.nonmutual", // which can be set to "initiator", "zero" or "0". String propName = "sun.security.krb5.acceptor.sequence.number.nonmutual"; - String s = GetPropertyAction.privilegedGetProperty(propName, "initiator"); + String s = System.getProperty(propName, "initiator"); if (s.equals("initiator")) { ACCEPTOR_USE_INITIATOR_SEQNUM = true; } else if (s.equals("zero") || s.equals("0")) { diff --git a/src/java.security.jgss/share/classes/sun/security/jgss/krb5/InitialToken.java b/src/java.security.jgss/share/classes/sun/security/jgss/krb5/InitialToken.java index d125d741ce1..0ad0b723ea9 100644 --- a/src/java.security.jgss/share/classes/sun/security/jgss/krb5/InitialToken.java +++ b/src/java.security.jgss/share/classes/sun/security/jgss/krb5/InitialToken.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,7 +26,6 @@ package sun.security.jgss.krb5; import org.ietf.jgss.*; -import javax.security.auth.kerberos.DelegationPermission; import java.io.IOException; import java.net.InetAddress; import java.net.Inet4Address; @@ -171,14 +170,6 @@ public OverloadedChecksum(Krb5Context context, String realm = delegateTo.getRealmAsString(); sb.append(" \"krbtgt/").append(realm).append('@'); sb.append(realm).append('\"'); - @SuppressWarnings("removal") - SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - DelegationPermission perm = - new DelegationPermission(sb.toString()); - sm.checkPermission(perm); - } - /* * Write 1 in little endian but in two bytes diff --git a/src/java.security.jgss/share/classes/sun/security/jgss/krb5/Krb5AcceptCredential.java b/src/java.security.jgss/share/classes/sun/security/jgss/krb5/Krb5AcceptCredential.java index d6a4ca39e28..2278a87f1ec 100644 --- a/src/java.security.jgss/share/classes/sun/security/jgss/krb5/Krb5AcceptCredential.java +++ b/src/java.security.jgss/share/classes/sun/security/jgss/krb5/Krb5AcceptCredential.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -29,10 +29,8 @@ import sun.security.jgss.GSSCaller; import sun.security.jgss.spi.*; import sun.security.krb5.*; -import java.security.PrivilegedActionException; -import java.security.PrivilegedExceptionAction; -import java.security.AccessController; import javax.security.auth.DestroyFailedException; +import javax.security.auth.login.LoginException; /** * Implements the krb5 acceptor credential element. @@ -57,27 +55,22 @@ private Krb5AcceptCredential(Krb5NameElement name, ServiceCreds creds) { this.screds = creds; } - @SuppressWarnings("removal") static Krb5AcceptCredential getInstance(final GSSCaller caller, Krb5NameElement name) throws GSSException { final String serverPrinc = (name == null? null: name.getKrb5PrincipalName().getName()); - ServiceCreds creds; + ServiceCreds creds = null; try { - creds = AccessController.doPrivilegedWithCombiner( - new PrivilegedExceptionAction<ServiceCreds>() { - public ServiceCreds run() throws Exception { - return Krb5Util.getServiceCreds( - caller == GSSCaller.CALLER_UNKNOWN ? GSSCaller.CALLER_ACCEPT: caller, - serverPrinc); - }}); - } catch (PrivilegedActionException e) { + creds = Krb5Util.getServiceCreds( + caller == GSSCaller.CALLER_UNKNOWN ? GSSCaller.CALLER_ACCEPT: caller, + serverPrinc); + } catch (LoginException e) { GSSException ge = new GSSException(GSSException.NO_CRED, -1, "Attempt to obtain new ACCEPT credentials failed!"); - ge.initCause(e.getException()); + ge.initCause(e); throw ge; } diff --git a/src/java.security.jgss/share/classes/sun/security/jgss/krb5/Krb5Context.java b/src/java.security.jgss/share/classes/sun/security/jgss/krb5/Krb5Context.java index 92b694efb86..7df3d8d2de0 100644 --- a/src/java.security.jgss/share/classes/sun/security/jgss/krb5/Krb5Context.java +++ b/src/java.security.jgss/share/classes/sun/security/jgss/krb5/Krb5Context.java @@ -39,7 +39,6 @@ import java.io.OutputStream; import java.security.*; import javax.security.auth.Subject; -import javax.security.auth.kerberos.ServicePermission; import javax.security.auth.kerberos.KerberosCredMessage; import javax.security.auth.kerberos.KerberosPrincipal; import javax.security.auth.kerberos.KerberosTicket; @@ -631,8 +630,6 @@ public final byte[] initSecContext(InputStream is, int mechTokenSize) tgt = proxyCreds.self.getKrb5Credentials(); } - checkPermission(peerName.getKrb5PrincipalName().getName(), - "initiate"); /* * If useSubjectCredsonly is true then * we check whether we already have the ticket @@ -641,33 +638,21 @@ public final byte[] initSecContext(InputStream is, int mechTokenSize) if (GSSUtil.useSubjectCredsOnly(caller)) { KerberosTicket kerbTicket = null; - try { - // get service ticket from caller's subject - @SuppressWarnings("removal") - var tmp = AccessController.doPrivilegedWithCombiner( - new PrivilegedExceptionAction<KerberosTicket>() { - public KerberosTicket run() throws Exception { - // XXX to be cleaned - // highly consider just calling: - // Subject.getSubject - // SubjectComber.find - // instead of Krb5Util.getServiceTicket - return Krb5Util.getServiceTicket( - GSSCaller.CALLER_UNKNOWN, - // since it's useSubjectCredsOnly here, - // don't worry about the null - proxyCreds == null ? - myName.getKrb5PrincipalName().getName(): - proxyCreds.getName().getKrb5PrincipalName().getName(), - peerName.getKrb5PrincipalName().getName()); - }}); - kerbTicket = tmp; - } catch (PrivilegedActionException e) { - if (DEBUG != null) { - DEBUG.println("Attempt to obtain service" - + " ticket from the subject failed!"); - } - } + // get service ticket from caller's subject + // XXX to be cleaned + // highly consider just calling: + // Subject.getSubject + // SubjectComber.find + // instead of Krb5Util.getServiceTicket + kerbTicket = Krb5Util.getServiceTicket( + GSSCaller.CALLER_UNKNOWN, + // since it's useSubjectCredsOnly here, + // don't worry about the null + proxyCreds == null ? + myName.getKrb5PrincipalName().getName(): + proxyCreds.getName().getKrb5PrincipalName().getName(), + peerName.getKrb5PrincipalName().getName()); + if (kerbTicket != null) { if (DEBUG != null) { DEBUG.println("Found service ticket in " + @@ -701,10 +686,7 @@ public KerberosTicket run() throws Exception { tgt); } if (GSSUtil.useSubjectCredsOnly(caller)) { - @SuppressWarnings("removal") - final Subject subject = - AccessController.doPrivilegedWithCombiner( - (PrivilegedAction<Subject>) Subject::current); + Subject subject = Subject.current(); if (subject != null && !subject.isReadOnly()) { /* @@ -714,14 +696,9 @@ public KerberosTicket run() throws Exception { * successfully established; however it is easier * to do it here and there is no harm. */ - final KerberosTicket kt = + KerberosTicket kt = Krb5Util.credsToTicket(serviceCreds); - @SuppressWarnings("removal") - var dummy = AccessController.doPrivileged ( - (PrivilegedAction<Void>) () -> { - subject.getPrivateCredentials().add(kt); - return null; - }); + subject.getPrivateCredentials().add(kt); } else { // log it for debugging purpose if (DEBUG != null) { @@ -816,11 +793,6 @@ public final byte[] acceptSecContext(InputStream is, int mechTokenSize) } myName = (Krb5NameElement) myCred.getName(); - // If there is already a bound name, check now - if (myName != null) { - Krb5MechFactory.checkAcceptCredPermission(myName, myName); - } - InitSecContextToken token = new InitSecContextToken(this, (Krb5AcceptCredential) myCred, is); PrincipalName clientName = token.getKrbApReq().getClient(); @@ -830,7 +802,6 @@ public final byte[] acceptSecContext(InputStream is, int mechTokenSize) if (myName == null) { myName = Krb5NameElement.getInstance( token.getKrbApReq().getCreds().getServer()); - Krb5MechFactory.checkAcceptCredPermission(myName, myName); } if (getMutualAuthState()) { @@ -1322,16 +1293,6 @@ private void setSequencingAndReplayProps(MessageToken_v2 token, } } - private void checkPermission(String principal, String action) { - @SuppressWarnings("removal") - SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - ServicePermission perm = - new ServicePermission(principal, action); - sm.checkPermission(perm); - } - } - private static String getHexBytes(byte[] bytes, int pos, int len) { StringBuilder sb = new StringBuilder(); diff --git a/src/java.security.jgss/share/classes/sun/security/jgss/krb5/Krb5InitCredential.java b/src/java.security.jgss/share/classes/sun/security/jgss/krb5/Krb5InitCredential.java index 4cc306282e6..29176ba3c2b 100644 --- a/src/java.security.jgss/share/classes/sun/security/jgss/krb5/Krb5InitCredential.java +++ b/src/java.security.jgss/share/classes/sun/security/jgss/krb5/Krb5InitCredential.java @@ -37,9 +37,7 @@ import java.io.IOException; import java.io.ObjectInputStream; import java.util.Date; -import java.security.AccessController; -import java.security.PrivilegedExceptionAction; -import java.security.PrivilegedActionException; +import javax.security.auth.login.LoginException; /** * Implements the krb5 initiator credential element. @@ -348,7 +346,6 @@ public void dispose() throws GSSException { // XXX call to this.destroy() should destroy the locally cached copy // of krb5Credentials and then call super.destroy(). - @SuppressWarnings("removal") private static KerberosTicket getTgt(GSSCaller caller, Krb5NameElement name, int initLifetime) throws GSSException { @@ -366,23 +363,18 @@ private static KerberosTicket getTgt(GSSCaller caller, Krb5NameElement name, } try { - final GSSCaller realCaller = (caller == GSSCaller.CALLER_UNKNOWN) - ? GSSCaller.CALLER_INITIATE - : caller; - return AccessController.doPrivilegedWithCombiner( - new PrivilegedExceptionAction<KerberosTicket>() { - public KerberosTicket run() throws Exception { - // It's OK to use null as serverPrincipal. TGT is almost - // the first ticket for a principal and we use list. - return Krb5Util.getInitialTicket( - realCaller, clientPrincipal); - }}); - } catch (PrivilegedActionException e) { + GSSCaller realCaller = (caller == GSSCaller.CALLER_UNKNOWN) + ? GSSCaller.CALLER_INITIATE + : caller; + // It's OK to use null as serverPrincipal. TGT is almost + // the first ticket for a principal and we use list. + return Krb5Util.getInitialTicket(realCaller, clientPrincipal); + } catch (LoginException e) { GSSException ge = new GSSException(GSSException.NO_CRED, -1, "Attempt to obtain new INITIATE credentials failed!" + " (" + e.getMessage() + ")"); - ge.initCause(e.getException()); + ge.initCause(e); throw ge; } } diff --git a/src/java.security.jgss/share/classes/sun/security/jgss/krb5/Krb5MechFactory.java b/src/java.security.jgss/share/classes/sun/security/jgss/krb5/Krb5MechFactory.java index 2c49b14d450..34cd531cf61 100644 --- a/src/java.security.jgss/share/classes/sun/security/jgss/krb5/Krb5MechFactory.java +++ b/src/java.security.jgss/share/classes/sun/security/jgss/krb5/Krb5MechFactory.java @@ -29,12 +29,9 @@ import sun.security.jgss.GSSUtil; import sun.security.jgss.GSSCaller; import sun.security.jgss.spi.*; -import javax.security.auth.kerberos.ServicePermission; import java.security.Provider; import java.util.Vector; -import static sun.security.krb5.internal.Krb5.DEBUG; - /** * Krb5 Mechanism plug in for JGSS * This is the properties object required by the JGSS framework. @@ -71,19 +68,8 @@ private static Krb5CredElement getCredFromSubject(GSSNameSpi name, Krb5InitCredential.class : Krb5AcceptCredential.class)); - Krb5CredElement result = ((creds == null || creds.isEmpty()) ? - null : creds.firstElement()); - - // Force permission check before returning the cred to caller - if (result != null) { - if (initiate) { - checkInitCredPermission((Krb5NameElement) result.getName()); - } else { - checkAcceptCredPermission - ((Krb5NameElement) result.getName(), name); - } - } - return result; + return ((creds == null || creds.isEmpty()) ? + null : creds.firstElement()); } public Krb5MechFactory() { @@ -126,14 +112,10 @@ public GSSCredentialSpi getCredentialElement(GSSNameSpi name, (caller, (Krb5NameElement) name, initLifetime); credElement = Krb5ProxyCredential.tryImpersonation( caller, (Krb5InitCredential)credElement); - checkInitCredPermission - ((Krb5NameElement) credElement.getName()); } else if (usage == GSSCredential.ACCEPT_ONLY) { credElement = Krb5AcceptCredential.getInstance(caller, (Krb5NameElement) name); - checkAcceptCredPermission - ((Krb5NameElement) credElement.getName(), name); } else throw new GSSException(GSSException.FAILURE, -1, "Unknown usage mode requested"); @@ -141,47 +123,6 @@ public GSSCredentialSpi getCredentialElement(GSSNameSpi name, return credElement; } - public static void checkInitCredPermission(Krb5NameElement name) { - @SuppressWarnings("removal") - SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - String realm = (name.getKrb5PrincipalName()).getRealmAsString(); - String tgsPrincipal = "krbtgt/" + realm + '@' + realm; - ServicePermission perm = - new ServicePermission(tgsPrincipal, "initiate"); - try { - sm.checkPermission(perm); - } catch (SecurityException e) { - if (DEBUG != null) { - DEBUG.println("Permission to initiate " + - "kerberos init credential" + e.getMessage()); - } - throw e; - } - } - } - - public static void checkAcceptCredPermission(Krb5NameElement name, - GSSNameSpi originalName) { - @SuppressWarnings("removal") - SecurityManager sm = System.getSecurityManager(); - if (sm != null && name != null) { - ServicePermission perm = new ServicePermission - (name.getKrb5PrincipalName().getName(), "accept"); - try { - sm.checkPermission(perm); - } catch (SecurityException e) { - if (originalName == null) { - // Don't disclose the name of the principal - e = new SecurityException("No permission to acquire " - + "Kerberos accept credential"); - // Don't call e.initCause() with caught exception - } - throw e; - } - } - } - public GSSContextSpi getMechanismContext(GSSNameSpi peer, GSSCredentialSpi myInitiatorCred, int lifetime) throws GSSException { diff --git a/src/java.security.jgss/share/classes/sun/security/jgss/krb5/Krb5NameElement.java b/src/java.security.jgss/share/classes/sun/security/jgss/krb5/Krb5NameElement.java index e8871735302..9e3511708cb 100644 --- a/src/java.security.jgss/share/classes/sun/security/jgss/krb5/Krb5NameElement.java +++ b/src/java.security.jgss/share/classes/sun/security/jgss/krb5/Krb5NameElement.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -28,10 +28,8 @@ import org.ietf.jgss.*; import sun.security.jgss.spi.*; import sun.security.krb5.PrincipalName; -import sun.security.krb5.Realm; import sun.security.krb5.KrbException; -import javax.security.auth.kerberos.ServicePermission; import java.net.InetAddress; import java.net.UnknownHostException; import java.security.Provider; @@ -127,19 +125,6 @@ static Krb5NameElement getInstance(String gssNameStr, Oid gssNameType) throw new GSSException(GSSException.BAD_NAME, -1, e.getMessage()); } - if (principalName.isRealmDeduced() && !Realm.AUTODEDUCEREALM) { - @SuppressWarnings("removal") - SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - try { - sm.checkPermission(new ServicePermission( - "@" + principalName.getRealmAsString(), "-")); - } catch (SecurityException se) { - // Do not chain the actual exception to hide info - throw new GSSException(GSSException.FAILURE); - } - } - } return new Krb5NameElement(principalName, gssNameStr, gssNameType); } diff --git a/src/java.security.jgss/share/classes/sun/security/jgss/krb5/Krb5Util.java b/src/java.security.jgss/share/classes/sun/security/jgss/krb5/Krb5Util.java index e784b7b33ca..acc572b4450 100644 --- a/src/java.security.jgss/share/classes/sun/security/jgss/krb5/Krb5Util.java +++ b/src/java.security.jgss/share/classes/sun/security/jgss/krb5/Krb5Util.java @@ -59,7 +59,6 @@ private Krb5Util() { // Cannot create one of these static KerberosTicket getServiceTicket(GSSCaller caller, String clientPrincipal, String serverPrincipal) { // Try to get ticket from current Subject - @SuppressWarnings("removal") Subject currSubj = Subject.current(); KerberosTicket ticket = SubjectComber.find(currSubj, serverPrincipal, clientPrincipal, diff --git a/src/java.security.jgss/share/classes/sun/security/jgss/spnego/SpNegoContext.java b/src/java.security.jgss/share/classes/sun/security/jgss/spnego/SpNegoContext.java index 37e2c0f5a55..1135ccd8aa8 100644 --- a/src/java.security.jgss/share/classes/sun/security/jgss/spnego/SpNegoContext.java +++ b/src/java.security.jgss/share/classes/sun/security/jgss/spnego/SpNegoContext.java @@ -30,8 +30,6 @@ import java.util.Objects; import org.ietf.jgss.*; -import sun.security.action.GetBooleanAction; -import sun.security.action.GetPropertyAction; import sun.security.jgss.*; import sun.security.jgss.spi.*; import sun.security.util.*; @@ -85,8 +83,8 @@ public class SpNegoContext implements GSSContextSpi { private final SpNegoMechFactory factory; // debug property - static final Debug DEBUG = Debug.of("spnego", GetPropertyAction - .privilegedGetProperty("sun.security.spnego.debug")); + static final Debug DEBUG = Debug.of("spnego", + System.getProperty("sun.security.spnego.debug")); /** * Constructor for SpNegoContext to be called on the context initiator's diff --git a/src/java.security.jgss/share/classes/sun/security/jgss/spnego/SpNegoMechFactory.java b/src/java.security.jgss/share/classes/sun/security/jgss/spnego/SpNegoMechFactory.java index a6b0fb55d87..5d35a25214b 100644 --- a/src/java.security.jgss/share/classes/sun/security/jgss/spnego/SpNegoMechFactory.java +++ b/src/java.security.jgss/share/classes/sun/security/jgss/spnego/SpNegoMechFactory.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -28,10 +28,6 @@ import org.ietf.jgss.*; import sun.security.jgss.*; import sun.security.jgss.spi.*; -import sun.security.jgss.krb5.Krb5MechFactory; -import sun.security.jgss.krb5.Krb5InitCredential; -import sun.security.jgss.krb5.Krb5AcceptCredential; -import sun.security.jgss.krb5.Krb5NameElement; import java.security.Provider; import java.util.Vector; @@ -75,25 +71,8 @@ private static SpNegoCredElement getCredFromSubject(GSSNameSpi name, GSSUtil.searchSubject(name, GSS_SPNEGO_MECH_OID, initiate, SpNegoCredElement.class); - SpNegoCredElement result = ((creds == null || creds.isEmpty()) ? - null : creds.firstElement()); - - // Force permission check before returning the cred to caller - if (result != null) { - GSSCredentialSpi cred = result.getInternalCred(); - if (GSSUtil.isKerberosMech(cred.getMechanism())) { - if (initiate) { - Krb5InitCredential krbCred = (Krb5InitCredential) cred; - Krb5MechFactory.checkInitCredPermission - ((Krb5NameElement) krbCred.getName()); - } else { - Krb5AcceptCredential krbCred = (Krb5AcceptCredential) cred; - Krb5MechFactory.checkAcceptCredPermission - ((Krb5NameElement) krbCred.getName(), name); - } - } - } - return result; + return ((creds == null || creds.isEmpty()) ? + null : creds.firstElement()); } public SpNegoMechFactory() { diff --git a/src/java.security.jgss/share/classes/sun/security/jgss/wrapper/GSSCredElement.java b/src/java.security.jgss/share/classes/sun/security/jgss/wrapper/GSSCredElement.java index bff9e04bf55..4b58778b5e0 100644 --- a/src/java.security.jgss/share/classes/sun/security/jgss/wrapper/GSSCredElement.java +++ b/src/java.security.jgss/share/classes/sun/security/jgss/wrapper/GSSCredElement.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -27,7 +27,6 @@ import org.ietf.jgss.*; import java.lang.ref.Cleaner; import java.security.Provider; -import sun.security.jgss.GSSUtil; import sun.security.jgss.spi.GSSCredentialSpi; import sun.security.jgss.spi.GSSNameSpi; @@ -45,24 +44,6 @@ public class GSSCredElement implements GSSCredentialSpi { private GSSNameElement name; private final GSSLibStub cStub; - // Perform the necessary ServicePermission check on this cred - @SuppressWarnings("removal") - void doServicePermCheck() throws GSSException { - if (GSSUtil.isKerberosMech(cStub.getMech())) { - if (System.getSecurityManager() != null) { - if (isInitiatorCredential()) { - String tgsName = Krb5Util.getTGSName(name); - Krb5Util.checkServicePermission(tgsName, "initiate"); - } - if (isAcceptorCredential() && - name != GSSNameElement.DEF_ACCEPTOR) { - String krbName = name.getKrbName(); - Krb5Util.checkServicePermission(krbName, "accept"); - } - } - } - } - // Construct delegation cred using the actual context mech and srcName // Warning: called by NativeUtil.c GSSCredElement(long pCredentials, GSSNameElement srcName, Oid mech) @@ -81,12 +62,10 @@ void doServicePermCheck() throws GSSException { if (name != null) { // Could be GSSNameElement.DEF_ACCEPTOR this.name = name; - doServicePermCheck(); pCred = cStub.acquireCred(this.name.pName, lifetime, usage); } else { pCred = cStub.acquireCred(0, lifetime, usage); this.name = new GSSNameElement(cStub.getCredName(pCred), cStub); - doServicePermCheck(); } cleanable = Krb5Util.cleaner.register(this, disposerFor(cStub, pCred)); diff --git a/src/java.security.jgss/share/classes/sun/security/jgss/wrapper/GSSNameElement.java b/src/java.security.jgss/share/classes/sun/security/jgss/wrapper/GSSNameElement.java index 0a51a5291cb..773377d93d0 100644 --- a/src/java.security.jgss/share/classes/sun/security/jgss/wrapper/GSSNameElement.java +++ b/src/java.security.jgss/share/classes/sun/security/jgss/wrapper/GSSNameElement.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -36,7 +36,6 @@ import sun.security.util.DerOutputStream; import sun.security.util.ObjectIdentifier; -import javax.security.auth.kerberos.ServicePermission; import java.io.IOException; import java.lang.ref.Cleaner; import java.security.Provider; @@ -168,29 +167,6 @@ private GSSNameElement() { setPrintables(); - @SuppressWarnings("removal") - SecurityManager sm = System.getSecurityManager(); - if (sm != null && !Realm.AUTODEDUCEREALM) { - String krbName = getKrbName(); - int atPos = krbName.lastIndexOf('@'); - if (atPos != -1) { - String atRealm = krbName.substring(atPos); - // getNativeNameType() can modify NT_GSS_KRB5_PRINCIPAL to null - if ((nameType == null - || nameType.equals(GSSUtil.NT_GSS_KRB5_PRINCIPAL)) - && new String(nameBytes).endsWith(atRealm)) { - // Created from Kerberos name with realm, no need to check - } else { - try { - sm.checkPermission(new ServicePermission(atRealm, "-")); - } catch (SecurityException se) { - // Do not chain the actual exception to hide info - throw new GSSException(GSSException.FAILURE); - } - } - } - } - if (SunNativeProvider.DEBUG) { SunNativeProvider.debug("Imported " + printableName + " w/ type " + printableType); diff --git a/src/java.security.jgss/share/classes/sun/security/jgss/wrapper/Krb5Util.java b/src/java.security.jgss/share/classes/sun/security/jgss/wrapper/Krb5Util.java index f40194838b5..58bea221092 100644 --- a/src/java.security.jgss/share/classes/sun/security/jgss/wrapper/Krb5Util.java +++ b/src/java.security.jgss/share/classes/sun/security/jgss/wrapper/Krb5Util.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,7 +26,6 @@ import org.ietf.jgss.*; import java.lang.ref.Cleaner; -import javax.security.auth.kerberos.ServicePermission; /** * This class is a utility class for Kerberos related stuff. @@ -46,20 +45,4 @@ static String getTGSName(GSSNameElement name) String realm = krbPrinc.substring(atIndex + 1); return "krbtgt/" + realm + '@' + realm; } - - // Perform the Service Permission check using the specified - // <code>target</code> and <code>action</code> - static void checkServicePermission(String target, String action) { - @SuppressWarnings("removal") - SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - if (SunNativeProvider.DEBUG) { - SunNativeProvider.debug("Checking ServicePermission(" + - target + ", " + action + ")"); - } - ServicePermission perm = - new ServicePermission(target, action); - sm.checkPermission(perm); - } - } } diff --git a/src/java.security.jgss/share/classes/sun/security/jgss/wrapper/NativeGSSContext.java b/src/java.security.jgss/share/classes/sun/security/jgss/wrapper/NativeGSSContext.java index 90fa10d7dc9..7cd94d6712e 100644 --- a/src/java.security.jgss/share/classes/sun/security/jgss/wrapper/NativeGSSContext.java +++ b/src/java.security.jgss/share/classes/sun/security/jgss/wrapper/NativeGSSContext.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -36,7 +36,6 @@ import sun.security.util.ObjectIdentifier; import sun.security.jgss.spnego.NegTokenInit; import sun.security.jgss.spnego.NegTokenTarg; -import javax.security.auth.kerberos.DelegationPermission; import java.io.*; @@ -79,9 +78,6 @@ class NativeGSSContext implements GSSContextSpi { private GSSCredElement disposeDelegatedCred; private final GSSLibStub cStub; - private boolean skipDelegPermCheck; - private boolean skipServicePermCheck; - // Retrieve the (preferred) mech out of SPNEGO tokens, i.e. // NegTokenInit & NegTokenTarg private static Oid getMechFromSpNegoToken(byte[] token, @@ -112,53 +108,6 @@ private static Oid getMechFromSpNegoToken(byte[] token, return mech; } - // Perform the Service permission check - @SuppressWarnings("removal") - private void doServicePermCheck() throws GSSException { - if (System.getSecurityManager() != null) { - String action = (isInitiator? "initiate" : "accept"); - // Need to check Service permission for accessing - // initiator cred for SPNEGO during context establishment - if (GSSUtil.isSpNegoMech(cStub.getMech()) && isInitiator - && !isEstablished) { - if (srcName == null) { - // Check by creating default initiator KRB5 cred - GSSCredElement tempCred = - new GSSCredElement(null, lifetime, - GSSCredential.INITIATE_ONLY, - GSSLibStub.getInstance(GSSUtil.GSS_KRB5_MECH_OID)); - tempCred.dispose(); - } else { - String tgsName = Krb5Util.getTGSName(srcName); - Krb5Util.checkServicePermission(tgsName, action); - } - } - String targetStr = targetName.getKrbName(); - Krb5Util.checkServicePermission(targetStr, action); - skipServicePermCheck = true; - } - } - - // Perform the Delegation permission check - private void doDelegPermCheck() throws GSSException { - @SuppressWarnings("removal") - SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - String targetStr = targetName.getKrbName(); - String tgsStr = Krb5Util.getTGSName(targetName); - String krbPrincPair = "\"" + targetStr + "\" \"" + - tgsStr + '\"'; - if (SunNativeProvider.DEBUG) { - SunNativeProvider.debug("Checking DelegationPermission (" + - krbPrincPair + ")"); - } - DelegationPermission perm = - new DelegationPermission(krbPrincPair); - sm.checkPermission(perm); - skipDelegPermCheck = true; - } - } - private byte[] retrieveToken(InputStream is, int mechTokenLen) throws GSSException { try { @@ -210,7 +159,6 @@ private byte[] retrieveToken(InputStream is, int mechTokenLen) lifetime = time; if (GSSUtil.isKerberosMech(cStub.getMech())) { - doServicePermCheck(); if (cred == null) { disposeCred = cred = new GSSCredElement(null, lifetime, @@ -230,11 +178,6 @@ private byte[] retrieveToken(InputStream is, int mechTokenLen) if (cred != null) targetName = cred.getName(); isInitiator = false; - // Defer Service permission check for default acceptor cred - // to acceptSecContext() - if (GSSUtil.isKerberosMech(cStub.getMech()) && targetName != null) { - doServicePermCheck(); - } // srcName and potentially targetName (when myCred is null) // will be set in GSSLibStub.acceptContext(...) @@ -258,13 +201,6 @@ private byte[] retrieveToken(InputStream is, int mechTokenLen) isEstablished = (info[3] != 0); flags = (int) info[4]; lifetime = (int) info[5]; - - // Do Service Permission check when importing SPNEGO context - // just to be safe - Oid mech = cStub.getMech(); - if (GSSUtil.isSpNegoMech(mech) || GSSUtil.isKerberosMech(mech)) { - doServicePermCheck(); - } } public Provider getProvider() { @@ -285,12 +221,6 @@ public byte[] initSecContext(InputStream is, int mechTokenLen) } } - if (!getCredDelegState()) skipDelegPermCheck = true; - - if (GSSUtil.isKerberosMech(cStub.getMech()) && !skipDelegPermCheck) { - doDelegPermCheck(); - } - long pCred = (cred == null? 0 : cred.pCred); outToken = cStub.initContext(pCred, targetName.pName, cb, inToken, this); @@ -304,11 +234,6 @@ public byte[] initSecContext(InputStream is, int mechTokenLen) if (GSSUtil.isSpNegoMech(cStub.getMech()) && outToken != null) { // WORKAROUND for SEAM bug#6287358 actualMech = getMechFromSpNegoToken(outToken, true); - - if (GSSUtil.isKerberosMech(actualMech)) { - if (!skipServicePermCheck) doServicePermCheck(); - if (!skipDelegPermCheck) doDelegPermCheck(); - } } if (isEstablished) { @@ -355,16 +280,6 @@ public byte[] acceptSecContext(InputStream is, int mechTokenLen) new GSSCredElement(targetName, lifetime, GSSCredential.ACCEPT_ONLY, cStub); } - - // Only inspect token when the permission check has not - // been performed - if (GSSUtil.isSpNegoMech(cStub.getMech()) && - (outToken != null) && !skipServicePermCheck) { - if (GSSUtil.isKerberosMech(getMechFromSpNegoToken - (outToken, false))) { - doServicePermCheck(); - } - } } return outToken; } diff --git a/src/java.security.jgss/share/classes/sun/security/jgss/wrapper/NativeGSSFactory.java b/src/java.security.jgss/share/classes/sun/security/jgss/wrapper/NativeGSSFactory.java index 6f12c5019a1..a4986cb9a06 100644 --- a/src/java.security.jgss/share/classes/sun/security/jgss/wrapper/NativeGSSFactory.java +++ b/src/java.security.jgss/share/classes/sun/security/jgss/wrapper/NativeGSSFactory.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -65,13 +65,8 @@ private GSSCredElement getCredFromSubject(GSSNameElement name, } } - GSSCredElement result = ((creds == null || creds.isEmpty()) ? - null : creds.firstElement()); - // Force permission check before returning the cred to caller - if (result != null) { - result.doServicePermCheck(); - } - return result; + return ((creds == null || creds.isEmpty()) ? + null : creds.firstElement()); } public NativeGSSFactory(GSSCaller caller) { diff --git a/src/java.security.jgss/share/classes/sun/security/jgss/wrapper/SunNativeProvider.java b/src/java.security.jgss/share/classes/sun/security/jgss/wrapper/SunNativeProvider.java index 11545a25a63..00ba08f1028 100644 --- a/src/java.security.jgss/share/classes/sun/security/jgss/wrapper/SunNativeProvider.java +++ b/src/java.security.jgss/share/classes/sun/security/jgss/wrapper/SunNativeProvider.java @@ -28,14 +28,10 @@ import java.io.Serial; import java.util.HashMap; import java.security.Provider; -import java.security.AccessController; -import java.security.PrivilegedAction; import jdk.internal.util.OperatingSystem; import jdk.internal.util.StaticProperty; import org.ietf.jgss.Oid; -import sun.security.action.GetBooleanAction; -import sun.security.action.PutAllAction; import static sun.security.util.SecurityConstants.PROVIDER_VER; /** @@ -59,7 +55,7 @@ public final class SunNativeProvider extends Provider { "sun.security.jgss.wrapper.NativeGSSFactory"; static final boolean DEBUG = - GetBooleanAction.privilegedGetProperty("sun.security.nativegss.debug"); + Boolean.getBoolean("sun.security.nativegss.debug"); static void debug(String message) { if (message == null) { @@ -68,81 +64,76 @@ static void debug(String message) { System.err.println(NAME + ": " + message); } - @SuppressWarnings({"removal", "restricted"}) - private static final HashMap<String, String> MECH_MAP = - AccessController.doPrivileged( - new PrivilegedAction<>() { - public HashMap<String, String> run() { - try { - // Ensure the InetAddress class is loaded before - // loading j2gss. The library will access this class - // and a deadlock might happen. See JDK-8210373. - Class.forName("java.net.InetAddress"); - System.loadLibrary("j2gss"); - } catch (ClassNotFoundException | Error err) { - if (DEBUG) { - debug("No j2gss library found!"); - err.printStackTrace(); - } - return null; - } - String[] gssLibs; - String defaultLib - = System.getProperty("sun.security.jgss.lib"); - if (defaultLib == null || defaultLib.trim().equals("")) { - gssLibs = switch (OperatingSystem.current()) { - case LINUX -> new String[]{ - "libgssapi.so", - "libgssapi_krb5.so", - "libgssapi_krb5.so.2", - }; - case MACOS -> new String[]{ - "libgssapi_krb5.dylib", - "/usr/lib/sasl2/libgssapiv2.2.so", - }; - case WINDOWS -> new String[]{ - // Full path needed, DLL is in jre/bin - StaticProperty.javaHome() + "\\bin\\sspi_bridge.dll", - }; - case AIX -> new String[]{ - "/opt/freeware/lib64/libgssapi_krb5.so", - }; - default -> new String[0]; - }; - } else { - gssLibs = new String[]{ defaultLib }; - } - for (String libName: gssLibs) { - if (GSSLibStub.init(libName, DEBUG)) { - if (DEBUG) { - debug("Loaded GSS library: " + libName); - } - Oid[] mechs = GSSLibStub.indicateMechs(); - HashMap<String,String> map = new HashMap<>(); - for (int i = 0; i < mechs.length; i++) { - if (DEBUG) { - debug("Native MF for " + mechs[i]); - } - map.put("GssApiMechanism." + mechs[i], - MF_CLASS); - } - return map; - } - } - return null; - } - }); + private static final HashMap<String, String> MECH_MAP = constructMechMap(); + + @SuppressWarnings("restricted") + private static HashMap<String, String> constructMechMap() { + try { + // Ensure the InetAddress class is loaded before + // loading j2gss. The library will access this class + // and a deadlock might happen. See JDK-8210373. + Class.forName("java.net.InetAddress"); + System.loadLibrary("j2gss"); + } catch (ClassNotFoundException | Error err) { + if (DEBUG) { + debug("No j2gss library found!"); + err.printStackTrace(); + } + return null; + } + String[] gssLibs; + String defaultLib = System.getProperty("sun.security.jgss.lib"); + if (defaultLib == null || defaultLib.trim().equals("")) { + gssLibs = switch (OperatingSystem.current()) { + case LINUX -> new String[]{ + "libgssapi.so", + "libgssapi_krb5.so", + "libgssapi_krb5.so.2", + }; + case MACOS -> new String[]{ + "libgssapi_krb5.dylib", + "/usr/lib/sasl2/libgssapiv2.2.so", + }; + case WINDOWS -> new String[]{ + // Full path needed, DLL is in jre/bin + StaticProperty.javaHome() + "\\bin\\sspi_bridge.dll", + }; + case AIX -> new String[]{ + "/opt/freeware/lib64/libgssapi_krb5.so", + }; + default -> new String[0]; + }; + } else { + gssLibs = new String[]{ defaultLib }; + } + for (String libName: gssLibs) { + if (GSSLibStub.init(libName, DEBUG)) { + if (DEBUG) { + debug("Loaded GSS library: " + libName); + } + Oid[] mechs = GSSLibStub.indicateMechs(); + HashMap<String, String> map = new HashMap<>(); + for (int i = 0; i < mechs.length; i++) { + if (DEBUG) { + debug("Native MF for " + mechs[i]); + } + map.put("GssApiMechanism." + mechs[i], MF_CLASS); + } + return map; + } + } + return null; + } // initialize INSTANCE after MECH_MAP is constructed static final Provider INSTANCE = new SunNativeProvider(); - @SuppressWarnings("removal") public SunNativeProvider() { /* We are the Sun NativeGSS provider */ super(NAME, PROVIDER_VER, INFO); if (MECH_MAP != null) { - AccessController.doPrivileged(new PutAllAction(this, MECH_MAP)); + putAll(MECH_MAP); } } } diff --git a/src/java.security.jgss/share/classes/sun/security/krb5/Config.java b/src/java.security.jgss/share/classes/sun/security/krb5/Config.java index 36b8010a6f2..a9ea9d23eb1 100644 --- a/src/java.security.jgss/share/classes/sun/security/krb5/Config.java +++ b/src/java.security.jgss/share/classes/sun/security/krb5/Config.java @@ -34,19 +34,15 @@ import java.nio.file.Files; import java.nio.file.Paths; import java.nio.file.Path; -import java.security.PrivilegedAction; import java.util.*; import java.net.InetAddress; import java.net.UnknownHostException; -import java.security.AccessController; -import java.security.PrivilegedExceptionAction; import java.util.regex.Matcher; import java.util.regex.Pattern; import java.util.stream.Stream; import jdk.internal.util.OperatingSystem; import sun.net.dns.ResolverConfiguration; -import sun.security.action.GetPropertyAction; import sun.security.krb5.internal.crypto.EType; import sun.security.krb5.internal.Krb5; import sun.security.util.SecurityProperties; @@ -164,7 +160,7 @@ private static boolean isMacosLionOrBetter() { return false; } - String osVersion = GetPropertyAction.privilegedGetProperty("os.version"); + String osVersion = System.getProperty("os.version"); String[] fragments = osVersion.split("\\."); if (fragments.length < 2) return false; @@ -188,16 +184,14 @@ private Config() throws KrbException { /* * If either one system property is specified, we throw exception. */ - String tmp = GetPropertyAction - .privilegedGetProperty("java.security.krb5.kdc"); + String tmp = System.getProperty("java.security.krb5.kdc"); if (tmp != null) { // The user can specify a list of kdc hosts separated by ":" defaultKDC = tmp.replace(':', ' '); } else { defaultKDC = null; } - defaultRealm = GetPropertyAction - .privilegedGetProperty("java.security.krb5.realm"); + defaultRealm = System.getProperty("java.security.krb5.realm"); if ((defaultKDC == null && defaultRealm != null) || (defaultRealm == null && defaultKDC != null)) { throw new KrbException @@ -666,7 +660,6 @@ private static Void readConfigFileLines( * @param fileName the configuration file * @return normalized lines */ - @SuppressWarnings("removal") private List<String> loadConfigFile(final String fileName) throws IOException, KrbException { @@ -677,32 +670,15 @@ private List<String> loadConfigFile(final String fileName) List<String> raw = new ArrayList<>(); Set<Path> dupsCheck = new HashSet<>(); - try { - Path fullp = AccessController.doPrivileged((PrivilegedAction<Path>) - () -> Paths.get(fileName).toAbsolutePath(), - null, - new PropertyPermission("user.dir", "read")); - AccessController.doPrivileged( - new PrivilegedExceptionAction<Void>() { - @Override - public Void run() throws IOException { - Path path = Paths.get(fileName); - if (!Files.exists(path)) { - // This is OK. There are other ways to get - // Kerberos 5 settings - return null; - } else { - return readConfigFileLines( - fullp, raw, dupsCheck); - } - } - }, - null, - // include/includedir can go anywhere - new FilePermission("<<ALL FILES>>", "read")); - } catch (java.security.PrivilegedActionException pe) { - throw (IOException)pe.getException(); + Path fullp = Paths.get(fileName).toAbsolutePath(); + Path path = Paths.get(fileName); + if (!Files.exists(path)) { + // This is OK. There are other ways to get + // Kerberos 5 settings + } else { + readConfigFileLines(fullp, raw, dupsCheck); } + String previous = null; for (String line: raw) { if (line.startsWith("[")) { @@ -862,10 +838,9 @@ private Hashtable<String,Object> parseStanzaTable(List<String> v) * The method returns null if it cannot find a Java config file. */ private String getJavaFileName() { - String name = GetPropertyAction - .privilegedGetProperty("java.security.krb5.conf"); + String name = System.getProperty("java.security.krb5.conf"); if (name == null) { - name = GetPropertyAction.privilegedGetProperty("java.home") + name = System.getProperty("java.home") + File.separator + "conf" + File.separator + "security" + File.separator + "krb5.conf"; if (!fileExists(name)) { @@ -942,7 +917,7 @@ private String getNativeFileName() { } private String findMacosConfigFile() { - String userHome = GetPropertyAction.privilegedGetProperty("user.home"); + String userHome = System.getProperty("user.home"); final String PREF_FILE = "/Library/Preferences/edu.mit.Kerberos"; String userPrefs = userHome + PREF_FILE; @@ -1185,7 +1160,6 @@ private boolean useDNS_Realm() { * @throws KrbException where no realm can be located * @return the default realm, always non null */ - @SuppressWarnings("removal") public String getDefaultRealm() throws KrbException { if (defaultRealm != null) { return defaultRealm; @@ -1201,16 +1175,9 @@ public String getDefaultRealm() throws KrbException { } } if (realm == null) { - realm = java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction<String>() { - @Override - public String run() { - if (OperatingSystem.isWindows()) { - return System.getenv("USERDNSDOMAIN"); - } - return null; - } - }); + if (OperatingSystem.isWindows()) { + realm = System.getenv("USERDNSDOMAIN"); + } } if (realm == null) { KrbException ke = new KrbException("Cannot locate default realm"); @@ -1229,7 +1196,6 @@ public String run() { * @throws KrbException if there's no way to find KDC for the realm * @return the list of KDCs separated by a space, always non null */ - @SuppressWarnings("removal") public String getKDCList(String realm) throws KrbException { if (realm == null) { realm = getDefaultRealm(); @@ -1248,21 +1214,14 @@ public String getKDCList(String realm) throws KrbException { } } if (kdcs == null) { - kdcs = java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction<String>() { - @Override - public String run() { - if (OperatingSystem.isWindows()) { - String logonServer = System.getenv("LOGONSERVER"); - if (logonServer != null - && logonServer.startsWith("\\\\")) { - logonServer = logonServer.substring(2); - } - return logonServer; - } - return null; + if (OperatingSystem.isWindows()) { + String logonServer = System.getenv("LOGONSERVER"); + if (logonServer != null + && logonServer.startsWith("\\\\")) { + logonServer = logonServer.substring(2); } - }); + kdcs = logonServer; + } } if (kdcs == null) { if (defaultKDC != null) { @@ -1381,24 +1340,8 @@ private String getKDCFromDNS(String realm) throws KrbException { return kdcs; } - @SuppressWarnings("removal") private boolean fileExists(String name) { - return java.security.AccessController.doPrivileged( - new FileExistsAction(name)); - } - - static class FileExistsAction - implements java.security.PrivilegedAction<Boolean> { - - private String fileName; - - public FileExistsAction(String fileName) { - this.fileName = fileName; - } - - public Boolean run() { - return new File(fileName).exists(); - } + return new File(name).exists(); } // Shows the content of the Config object for debug purpose. diff --git a/src/java.security.jgss/share/classes/sun/security/krb5/Credentials.java b/src/java.security.jgss/share/classes/sun/security/krb5/Credentials.java index d31418ac351..9482177c174 100644 --- a/src/java.security.jgss/share/classes/sun/security/krb5/Credentials.java +++ b/src/java.security.jgss/share/classes/sun/security/krb5/Credentials.java @@ -524,19 +524,13 @@ public static void printDebug(Credentials c) { } - @SuppressWarnings({"removal", "restricted"}) + @SuppressWarnings("restricted") static void ensureLoaded() { - java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction<Void> () { - public Void run() { - if (OperatingSystem.isMacOS()) { - System.loadLibrary("osxkrb5"); - } else { - System.loadLibrary("w2k_lsa_auth"); - } - return null; - } - }); + if (OperatingSystem.isMacOS()) { + System.loadLibrary("osxkrb5"); + } else { + System.loadLibrary("w2k_lsa_auth"); + } alreadyLoaded = true; } diff --git a/src/java.security.jgss/share/classes/sun/security/krb5/KdcComm.java b/src/java.security.jgss/share/classes/sun/security/krb5/KdcComm.java index 688a9183304..60a0e955414 100644 --- a/src/java.security.jgss/share/classes/sun/security/krb5/KdcComm.java +++ b/src/java.security.jgss/share/classes/sun/security/krb5/KdcComm.java @@ -31,7 +31,6 @@ package sun.security.krb5; -import java.security.PrivilegedAction; import java.security.Security; import java.util.Locale; import sun.security.krb5.internal.Krb5; @@ -39,9 +38,6 @@ import java.io.IOException; import java.net.SocketTimeoutException; import java.util.StringTokenizer; -import java.security.AccessController; -import java.security.PrivilegedExceptionAction; -import java.security.PrivilegedActionException; import java.util.ArrayList; import java.util.List; import java.util.Set; @@ -98,13 +94,7 @@ private enum BpType { * Read global settings */ public static void initStatic() { - @SuppressWarnings("removal") - String value = AccessController.doPrivileged( - new PrivilegedAction<String>() { - public String run() { - return Security.getProperty("krb5.kdc.bad.policy"); - } - }); + String value = Security.getProperty("krb5.kdc.bad.policy"); if (value != null) { value = value.toLowerCase(Locale.ENGLISH); String[] ss = value.split(":"); @@ -349,81 +339,39 @@ private byte[] send(KrbKdcReq req, String tempKdc, boolean useTCP) + ", #bytes=" + obuf.length); } - KdcCommunication kdcCommunication = - new KdcCommunication(kdc, port, useTCP, timeout, retries, obuf); - try { - @SuppressWarnings("removal") - byte[] ibuf = AccessController.doPrivileged(kdcCommunication); + byte[] ibuf = null; + + for (int i=1; i <= retries; i++) { + String proto = useTCP?"TCP":"UDP"; if (DEBUG != null) { - DEBUG.println(">>> KrbKdcReq send: #bytes read=" - + (ibuf != null ? ibuf.length : 0)); + DEBUG.println(">>> KDCCommunication: kdc=" + kdc + + " " + proto + ":" + + port + ", timeout=" + + timeout + + ",Attempt =" + i + + ", #bytes=" + obuf.length); } - return ibuf; - } catch (PrivilegedActionException e) { - Exception wrappedException = e.getException(); - if (wrappedException instanceof IOException) { - throw (IOException) wrappedException; - } else { - throw (KrbException) wrappedException; - } - } - } - - private static class KdcCommunication - implements PrivilegedExceptionAction<byte[]> { - - private String kdc; - private int port; - private boolean useTCP; - private int timeout; - private int retries; - private byte[] obuf; - - public KdcCommunication(String kdc, int port, boolean useTCP, - int timeout, int retries, byte[] obuf) { - this.kdc = kdc; - this.port = port; - this.useTCP = useTCP; - this.timeout = timeout; - this.retries = retries; - this.obuf = obuf; - } - - // The caller only casts IOException and KrbException so don't - // add any new ones! - - public byte[] run() throws IOException, KrbException { - - byte[] ibuf = null; - - for (int i=1; i <= retries; i++) { - String proto = useTCP?"TCP":"UDP"; + try (NetClient kdcClient = NetClient.getInstance( + proto, kdc, port, timeout)) { + kdcClient.send(obuf); + ibuf = kdcClient.receive(); + break; + } catch (SocketTimeoutException se) { if (DEBUG != null) { - DEBUG.println(">>> KDCCommunication: kdc=" + kdc - + " " + proto + ":" - + port + ", timeout=" - + timeout - + ",Attempt =" + i - + ", #bytes=" + obuf.length); + DEBUG.println ("SocketTimeOutException with " + + "attempt: " + i); } - try (NetClient kdcClient = NetClient.getInstance( - proto, kdc, port, timeout)) { - kdcClient.send(obuf); - ibuf = kdcClient.receive(); - break; - } catch (SocketTimeoutException se) { - if (DEBUG != null) { - DEBUG.println ("SocketTimeOutException with " + - "attempt: " + i); - } - if (i == retries) { - ibuf = null; - throw se; - } + if (i == retries) { + ibuf = null; + throw se; } } - return ibuf; } + if (DEBUG != null) { + DEBUG.println(">>> KrbKdcReq send: #bytes read=" + + (ibuf != null ? ibuf.length : 0)); + } + return ibuf; } /** diff --git a/src/java.security.jgss/share/classes/sun/security/krb5/KrbServiceLocator.java b/src/java.security.jgss/share/classes/sun/security/krb5/KrbServiceLocator.java index 88b8a14055a..863e09dbc4a 100644 --- a/src/java.security.jgss/share/classes/sun/security/krb5/KrbServiceLocator.java +++ b/src/java.security.jgss/share/classes/sun/security/krb5/KrbServiceLocator.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -27,9 +27,6 @@ import sun.security.krb5.internal.Krb5; -import java.security.AccessController; -import java.security.PrivilegedActionException; -import java.security.PrivilegedExceptionAction; import java.util.Arrays; import java.util.Hashtable; import java.util.Random; @@ -71,7 +68,6 @@ private KrbServiceLocator() { * @return An ordered list of hostports for the Kerberos service or null if * the service has not been located. */ - @SuppressWarnings("removal") static String[] getKerberosService(String realmName) { // search realm in SRV TXT records @@ -86,18 +82,8 @@ static String[] getKerberosService(String realmName) { if (!(ctx instanceof DirContext)) { return null; // cannot create a DNS context } - Attributes attrs = null; - try { - // both connect and accept are needed since DNS is thru UDP - attrs = AccessController.doPrivileged( - (PrivilegedExceptionAction<Attributes>) - () -> ((DirContext)ctx).getAttributes( - dnsUrl, SRV_TXT_ATTR), - null, - new java.net.SocketPermission("*", "connect,accept")); - } catch (PrivilegedActionException e) { - throw (NamingException)e.getCause(); - } + Attributes attrs = ((DirContext)ctx).getAttributes( + dnsUrl, SRV_TXT_ATTR); Attribute attr; if (attrs != null && ((attr = attrs.get(SRV_TXT)) != null)) { @@ -144,7 +130,6 @@ static String[] getKerberosService(String realmName) { * @return An ordered list of hostports for the Kerberos service or null if * the service has not been located. */ - @SuppressWarnings("removal") static String[] getKerberosService(String realmName, String protocol) { String dnsUrl = "dns:///_kerberos." + protocol + "." + realmName; @@ -160,18 +145,8 @@ static String[] getKerberosService(String realmName, String protocol) { return null; // cannot create a DNS context } - Attributes attrs = null; - try { - // both connect and accept are needed since DNS is thru UDP - attrs = AccessController.doPrivileged( - (PrivilegedExceptionAction<Attributes>) - () -> ((DirContext)ctx).getAttributes( - dnsUrl, SRV_RR_ATTR), - null, - new java.net.SocketPermission("*", "connect,accept")); - } catch (PrivilegedActionException e) { - throw (NamingException)e.getCause(); - } + Attributes attrs = ((DirContext)ctx).getAttributes( + dnsUrl, SRV_RR_ATTR); Attribute attr; diff --git a/src/java.security.jgss/share/classes/sun/security/krb5/Realm.java b/src/java.security.jgss/share/classes/sun/security/krb5/Realm.java index 44e044a1e1b..93dbfe2b237 100644 --- a/src/java.security.jgss/share/classes/sun/security/krb5/Realm.java +++ b/src/java.security.jgss/share/classes/sun/security/krb5/Realm.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -31,7 +31,6 @@ package sun.security.krb5; -import sun.security.action.GetBooleanAction; import sun.security.krb5.internal.Krb5; import sun.security.util.*; import java.io.IOException; @@ -48,8 +47,8 @@ */ public class Realm implements Cloneable { - public static final boolean AUTODEDUCEREALM = GetBooleanAction - .privilegedGetProperty("sun.security.krb5.autodeducerealm"); + public static final boolean AUTODEDUCEREALM = + Boolean.getBoolean("sun.security.krb5.autodeducerealm"); private final String realm; // not null nor empty diff --git a/src/java.security.jgss/share/classes/sun/security/krb5/SCDynamicStoreConfig.java b/src/java.security.jgss/share/classes/sun/security/krb5/SCDynamicStoreConfig.java index 1d917c226c6..acd2aa0b7e6 100644 --- a/src/java.security.jgss/share/classes/sun/security/krb5/SCDynamicStoreConfig.java +++ b/src/java.security.jgss/share/classes/sun/security/krb5/SCDynamicStoreConfig.java @@ -45,20 +45,19 @@ public class SCDynamicStoreConfig { private static native List<String> getKerberosConfig(); static { - @SuppressWarnings({"removal", "restricted"}) - boolean isMac = java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction<Boolean>() { - public Boolean run() { - if (OperatingSystem.isMacOS()) { - System.loadLibrary("osxkrb5"); - return true; - } - return false; - } - }); + boolean isMac = loadLibrary(); if (isMac) installNotificationCallback(); } + @SuppressWarnings("restricted") + private static boolean loadLibrary() { + if (OperatingSystem.isMacOS()) { + System.loadLibrary("osxkrb5"); + return true; + } + return false; + } + /** * Calls down to JNI to get the raw Kerberos Config and maps the object * graph to the one that Kerberos Config in Java expects diff --git a/src/java.security.jgss/share/classes/sun/security/krb5/internal/Krb5.java b/src/java.security.jgss/share/classes/sun/security/krb5/internal/Krb5.java index 0850abb53c8..641b860c364 100644 --- a/src/java.security.jgss/share/classes/sun/security/krb5/internal/Krb5.java +++ b/src/java.security.jgss/share/classes/sun/security/krb5/internal/Krb5.java @@ -31,7 +31,6 @@ package sun.security.krb5.internal; -import sun.security.action.GetPropertyAction; import sun.security.util.Debug; import java.util.Hashtable; @@ -317,8 +316,8 @@ public static String getErrorMessage(int i) { } // Warning: used by NativeCreds.c - public static final Debug DEBUG = Debug.of("krb5", GetPropertyAction - .privilegedGetProperty("sun.security.krb5.debug")); + public static final Debug DEBUG = Debug.of("krb5", + System.getProperty("sun.security.krb5.debug")); static { errMsgList = new Hashtable<Integer,String> (); diff --git a/src/java.security.jgss/share/classes/sun/security/krb5/internal/ReplayCache.java b/src/java.security.jgss/share/classes/sun/security/krb5/internal/ReplayCache.java index b79709f93d6..464fbb485de 100644 --- a/src/java.security.jgss/share/classes/sun/security/krb5/internal/ReplayCache.java +++ b/src/java.security.jgss/share/classes/sun/security/krb5/internal/ReplayCache.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,7 +25,6 @@ package sun.security.krb5.internal; -import sun.security.action.GetPropertyAction; import sun.security.krb5.internal.rcache.AuthTimeWithHash; import sun.security.krb5.internal.rcache.MemoryCache; import sun.security.krb5.internal.rcache.DflCache; @@ -54,8 +53,7 @@ public void checkAndStore(KerberosTime currTime, AuthTimeWithHash time) } } public static ReplayCache getInstance() { - String type = GetPropertyAction - .privilegedGetProperty("sun.security.krb5.rcache"); + String type = System.getProperty("sun.security.krb5.rcache"); return getInstance(type); } diff --git a/src/java.security.jgss/share/classes/sun/security/krb5/internal/ccache/FileCredentialsCache.java b/src/java.security.jgss/share/classes/sun/security/krb5/internal/ccache/FileCredentialsCache.java index 594d282424d..8599ffd81b8 100644 --- a/src/java.security.jgss/share/classes/sun/security/krb5/internal/ccache/FileCredentialsCache.java +++ b/src/java.security.jgss/share/classes/sun/security/krb5/internal/ccache/FileCredentialsCache.java @@ -34,13 +34,11 @@ package sun.security.krb5.internal.ccache; import jdk.internal.util.OperatingSystem; -import sun.security.action.GetPropertyAction; import sun.security.krb5.*; import sun.security.krb5.internal.*; import sun.security.util.SecurityProperties; import java.nio.charset.StandardCharsets; -import java.security.PrivilegedAction; import java.util.ArrayList; import java.util.Collections; import java.util.List; @@ -452,17 +450,12 @@ public static String getDefaultCacheName() { // The env var can start with TYPE:, we only support FILE: here. // http://docs.oracle.com/cd/E19082-01/819-2252/6n4i8rtr3/index.html - @SuppressWarnings("removal") - String name = java.security.AccessController.doPrivileged( - (PrivilegedAction<String>) () -> { - String cache = System.getenv("KRB5CCNAME"); - if (cache != null && - (cache.length() >= 5) && - cache.regionMatches(true, 0, "FILE:", 0, 5)) { - cache = cache.substring(5); - } - return cache; - }); + String name = System.getenv("KRB5CCNAME"); + if (name != null && + (name.length() >= 5) && + name.regionMatches(true, 0, "FILE:", 0, 5)) { + name = name.substring(5); + } if (name != null) { if (DEBUG != null) { DEBUG.println(">>>KinitOptions cache name is " + name); @@ -502,12 +495,12 @@ public static String getDefaultCacheName() { // we did not get the uid; - String user_name = GetPropertyAction.privilegedGetProperty("user.name"); + String user_name = System.getProperty("user.name"); - String user_home = GetPropertyAction.privilegedGetProperty("user.home"); + String user_home = System.getProperty("user.home"); if (user_home == null) { - user_home = GetPropertyAction.privilegedGetProperty("user.dir"); + user_home = System.getProperty("user.dir"); } if (user_name != null) { @@ -556,19 +549,14 @@ private static String exec(String c) { } final String[] command = v.toArray(new String[0]); try { - @SuppressWarnings("removal") - Process p = - java.security.AccessController.doPrivileged - ((PrivilegedAction<Process>) () -> { - try { - return (Runtime.getRuntime().exec(command)); - } catch (IOException e) { - if (DEBUG != null) { - e.printStackTrace(DEBUG.getPrintStream()); - } - return null; - } - }); + Process p = null; + try { + p = Runtime.getRuntime().exec(command); + } catch (IOException e) { + if (DEBUG != null) { + e.printStackTrace(DEBUG.getPrintStream()); + } + } if (p == null) { // exception occurred during executing the command return null; diff --git a/src/java.security.jgss/share/classes/sun/security/krb5/internal/crypto/Des.java b/src/java.security.jgss/share/classes/sun/security/krb5/internal/crypto/Des.java index a3572d4943d..db4a1b0722d 100644 --- a/src/java.security.jgss/share/classes/sun/security/krb5/internal/crypto/Des.java +++ b/src/java.security.jgss/share/classes/sun/security/krb5/internal/crypto/Des.java @@ -38,7 +38,6 @@ import javax.crypto.spec.IvParameterSpec; import sun.security.krb5.KrbCryptoException; import java.util.Arrays; -import sun.security.action.GetPropertyAction; public final class Des { @@ -53,8 +52,8 @@ public final class Des { // string-to-key encoding. When set, the specified charset // name is used. Otherwise, the system default charset. - private static final String CHARSET = GetPropertyAction - .privilegedGetProperty("sun.security.krb5.msinterop.des.s2kcharset"); + private static final String CHARSET = + System.getProperty("sun.security.krb5.msinterop.des.s2kcharset"); private static final long[] bad_keys = { 0x0101010101010101L, 0xfefefefefefefefeL, diff --git a/src/java.security.jgss/share/classes/sun/security/krb5/internal/ktab/KeyTab.java b/src/java.security.jgss/share/classes/sun/security/krb5/internal/ktab/KeyTab.java index ff65cb22247..822fae037e8 100644 --- a/src/java.security.jgss/share/classes/sun/security/krb5/internal/ktab/KeyTab.java +++ b/src/java.security.jgss/share/classes/sun/security/krb5/internal/ktab/KeyTab.java @@ -31,7 +31,6 @@ package sun.security.krb5.internal.ktab; -import sun.security.action.GetPropertyAction; import sun.security.krb5.*; import sun.security.krb5.internal.*; import sun.security.krb5.internal.crypto.*; @@ -211,12 +210,10 @@ private static String getDefaultTabName() { } if (kname == null) { - String user_home = GetPropertyAction - .privilegedGetProperty("user.home"); + String user_home = System.getProperty("user.home"); if (user_home == null) { - user_home = GetPropertyAction - .privilegedGetProperty("user.dir"); + user_home = System.getProperty("user.dir"); } kname = user_home + File.separator + "krb5.keytab"; diff --git a/src/java.security.jgss/share/classes/sun/security/krb5/internal/rcache/AuthTimeWithHash.java b/src/java.security.jgss/share/classes/sun/security/krb5/internal/rcache/AuthTimeWithHash.java index 1aa802f952e..5d06dc650de 100644 --- a/src/java.security.jgss/share/classes/sun/security/krb5/internal/rcache/AuthTimeWithHash.java +++ b/src/java.security.jgss/share/classes/sun/security/krb5/internal/rcache/AuthTimeWithHash.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,8 +25,6 @@ package sun.security.krb5.internal.rcache; -import sun.security.action.GetBooleanAction; - import java.util.Objects; /** @@ -40,7 +38,7 @@ public class AuthTimeWithHash extends AuthTime public static final String DEFAULT_HASH_ALG; static { - if (GetBooleanAction.privilegedGetProperty("jdk.krb5.rcache.useMD5")) { + if (Boolean.getBoolean("jdk.krb5.rcache.useMD5")) { DEFAULT_HASH_ALG = "HASH"; } else { DEFAULT_HASH_ALG = "SHA256"; diff --git a/src/java.security.jgss/share/classes/sun/security/krb5/internal/rcache/DflCache.java b/src/java.security.jgss/share/classes/sun/security/krb5/internal/rcache/DflCache.java index 5d5f2ff4821..cc0617b118e 100644 --- a/src/java.security.jgss/share/classes/sun/security/krb5/internal/rcache/DflCache.java +++ b/src/java.security.jgss/share/classes/sun/security/krb5/internal/rcache/DflCache.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -38,7 +38,6 @@ import java.nio.file.attribute.PosixFilePermission; import java.util.*; -import sun.security.action.GetPropertyAction; import sun.security.krb5.internal.KerberosTime; import sun.security.krb5.internal.Krb5; import sun.security.krb5.internal.KrbApErrException; @@ -116,7 +115,7 @@ public DflCache (String source) { } private static String defaultPath() { - return GetPropertyAction.privilegedGetProperty("java.io.tmpdir"); + return System.getProperty("java.io.tmpdir"); } private static String defaultFile(String server) { diff --git a/src/java.security.jgss/share/classes/sun/security/krb5/internal/util/KerberosString.java b/src/java.security.jgss/share/classes/sun/security/krb5/internal/util/KerberosString.java index 6a077eef6a2..973b4bfe269 100644 --- a/src/java.security.jgss/share/classes/sun/security/krb5/internal/util/KerberosString.java +++ b/src/java.security.jgss/share/classes/sun/security/krb5/internal/util/KerberosString.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,7 +26,6 @@ package sun.security.krb5.internal.util; import java.io.IOException; -import sun.security.action.GetPropertyAction; import sun.security.util.DerValue; import static java.nio.charset.StandardCharsets.US_ASCII; @@ -58,8 +57,8 @@ public final class KerberosString { public static final boolean MSNAME; static { - String prop = GetPropertyAction - .privilegedGetProperty("sun.security.krb5.msinterop.kstring", "true"); + String prop = + System.getProperty("sun.security.krb5.msinterop.kstring", "true"); MSNAME = Boolean.parseBoolean(prop); } diff --git a/src/jdk.security.jgss/share/classes/com/sun/security/jgss/ExtendedGSSContextImpl.java b/src/jdk.security.jgss/share/classes/com/sun/security/jgss/ExtendedGSSContextImpl.java index 3421c97670b..486448c944e 100644 --- a/src/jdk.security.jgss/share/classes/com/sun/security/jgss/ExtendedGSSContextImpl.java +++ b/src/jdk.security.jgss/share/classes/com/sun/security/jgss/ExtendedGSSContextImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -41,12 +41,6 @@ public ExtendedGSSContextImpl(GSSContextImpl old) { @Override public Object inquireSecContext(InquireType type) throws GSSException { - @SuppressWarnings("removal") - SecurityManager security = System.getSecurityManager(); - if (security != null) { - security.checkPermission( - new InquireSecContextPermission(type.toString())); - } Object output = super.inquireSecContext(type.name()); if (output != null) { if (type == InquireType.KRB5_GET_AUTHZ_DATA) { diff --git a/src/jdk.security.jgss/share/classes/com/sun/security/sasl/gsskerb/JdkSASL.java b/src/jdk.security.jgss/share/classes/com/sun/security/sasl/gsskerb/JdkSASL.java index b1c050deb0c..7d225ddf511 100644 --- a/src/jdk.security.jgss/share/classes/com/sun/security/sasl/gsskerb/JdkSASL.java +++ b/src/jdk.security.jgss/share/classes/com/sun/security/sasl/gsskerb/JdkSASL.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -24,8 +24,6 @@ */ package com.sun.security.sasl.gsskerb; -import java.security.AccessController; -import java.security.PrivilegedAction; import java.security.Provider; import java.security.NoSuchAlgorithmException; import java.security.InvalidParameterException; @@ -74,19 +72,13 @@ public Object newInstance(Object ctrParamObj) } } - @SuppressWarnings("removal") public JdkSASL() { super("JdkSASL", PROVIDER_VER, info); final Provider p = this; - AccessController.doPrivileged(new PrivilegedAction<Void>() { - public Void run() { - putService(new ProviderService(p, "SaslClientFactory", - "GSSAPI", "com.sun.security.sasl.gsskerb.FactoryImpl")); - putService(new ProviderService(p, "SaslServerFactory", - "GSSAPI", "com.sun.security.sasl.gsskerb.FactoryImpl")); - return null; - } - }); + putService(new ProviderService(p, "SaslClientFactory", + "GSSAPI", "com.sun.security.sasl.gsskerb.FactoryImpl")); + putService(new ProviderService(p, "SaslServerFactory", + "GSSAPI", "com.sun.security.sasl.gsskerb.FactoryImpl")); } } From 4956a766213c3d76e13b98ac5d5efe5d4f553895 Mon Sep 17 00:00:00 2001 From: Vladimir Ivanov <vaivanov@openjdk.org> Date: Thu, 21 Nov 2024 17:54:45 +0000 Subject: [PATCH 161/311] 8317538: Potential bottleneck in Provider::getService: specjvm2008::crypto.rsa have scalability issue for high vCPU numbers Reviewed-by: ascarpino --- src/java.base/share/classes/java/security/Provider.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/java.base/share/classes/java/security/Provider.java b/src/java.base/share/classes/java/security/Provider.java index 385247d4c8f..7012bcc9eeb 100644 --- a/src/java.base/share/classes/java/security/Provider.java +++ b/src/java.base/share/classes/java/security/Provider.java @@ -1157,10 +1157,10 @@ private void parseLegacy(String name, String value, OPType opType) { public Service getService(String type, String algorithm) { checkInitialized(); // avoid allocating a new ServiceKey object if possible - ServiceKey key = previousKey; + ServiceKey key = previousKey.get(); if (!key.matches(type, algorithm)) { key = new ServiceKey(type, algorithm, false); - previousKey = key; + previousKey.set(key); } Service s = serviceMap.get(key); @@ -1188,8 +1188,8 @@ public Service getService(String type, String algorithm) { // re-use will occur e.g. as the framework traverses the provider // list and queries each provider with the same values until it finds // a matching service - private static volatile ServiceKey previousKey = - new ServiceKey("", "", false); + private static final ThreadLocal<ServiceKey> previousKey = + ThreadLocal.withInitial(() -> new ServiceKey("","", false)); /** * Get an unmodifiable Set of all services supported by From 78e5008e91610847bc11103e667fbe602b03d86a Mon Sep 17 00:00:00 2001 From: Vladimir Ivanov <vaivanov@openjdk.org> Date: Thu, 21 Nov 2024 17:59:28 +0000 Subject: [PATCH 162/311] 8317542: Specjvm::xml have scalability issue for high vCPU numbers Reviewed-by: joehw --- .../impl/xpath/regex/RegularExpression.java | 73 ++++++++++--------- 1 file changed, 39 insertions(+), 34 deletions(-) diff --git a/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/xpath/regex/RegularExpression.java b/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/xpath/regex/RegularExpression.java index 7ca00f4ff7f..08cbf0e9b4a 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/xpath/regex/RegularExpression.java +++ b/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/xpath/regex/RegularExpression.java @@ -23,6 +23,7 @@ import java.text.CharacterIterator; import java.util.Locale; import java.util.Stack; +import java.util.concurrent.Semaphore; import com.sun.org.apache.xerces.internal.util.IntStack; @@ -710,11 +711,11 @@ public boolean matches(char[] target, int start, int end, Match match) { if (this.context == null) this.context = new Context(); } - Context con = null; - synchronized (this.context) { - con = this.context.inuse ? new Context() : this.context; - con.reset(target, start, end, this.numberOfClosures); + Context con = this.context; + if (!con.claim()) { + con = new Context(); } + con.reset(target, start, end, this.numberOfClosures); if (match != null) { match.setNumberOfGroups(this.nofparen); match.setSource(target); @@ -734,7 +735,7 @@ public boolean matches(char[] target, int start, int end, Match match) { con.match.setBeginning(0, con.start); con.match.setEnd(0, matchEnd); } - con.setInUse(false); + con.release(); return true; } return false; @@ -752,10 +753,10 @@ public boolean matches(char[] target, int start, int end, Match match) { con.match.setBeginning(0, o); con.match.setEnd(0, o+this.fixedString.length()); } - con.setInUse(false); + con.release(); return true; } - con.setInUse(false); + con.release(); return false; } @@ -768,7 +769,7 @@ public boolean matches(char[] target, int start, int end, Match match) { int o = this.fixedStringTable.matches(target, con.start, con.limit); if (o < 0) { //System.err.println("Non-match in fixed-string search."); - con.setInUse(false); + con.release(); return false; } } @@ -839,10 +840,10 @@ else if (this.firstChar != null) { con.match.setBeginning(0, matchStart); con.match.setEnd(0, matchEnd); } - con.setInUse(false); + con.release(); return true; } else { - con.setInUse(false); + con.release(); return false; } } @@ -895,11 +896,11 @@ public boolean matches(String target, int start, int end, Match match) { if (this.context == null) this.context = new Context(); } - Context con = null; - synchronized (this.context) { - con = this.context.inuse ? new Context() : this.context; - con.reset(target, start, end, this.numberOfClosures); + Context con = this.context; + if (!con.claim()) { + con = new Context(); } + con.reset(target, start, end, this.numberOfClosures); if (match != null) { match.setNumberOfGroups(this.nofparen); match.setSource(target); @@ -925,7 +926,7 @@ public boolean matches(String target, int start, int end, Match match) { con.match.setBeginning(0, con.start); con.match.setEnd(0, matchEnd); } - con.setInUse(false); + con.release(); return true; } return false; @@ -943,10 +944,10 @@ public boolean matches(String target, int start, int end, Match match) { con.match.setBeginning(0, o); con.match.setEnd(0, o+this.fixedString.length()); } - con.setInUse(false); + con.release(); return true; } - con.setInUse(false); + con.release(); return false; } @@ -959,7 +960,7 @@ public boolean matches(String target, int start, int end, Match match) { int o = this.fixedStringTable.matches(target, con.start, con.limit); if (o < 0) { //System.err.println("Non-match in fixed-string search."); - con.setInUse(false); + con.release(); return false; } } @@ -1030,10 +1031,10 @@ else if (this.firstChar != null) { con.match.setBeginning(0, matchStart); con.match.setEnd(0, matchEnd); } - con.setInUse(false); + con.release(); return true; } else { - con.setInUse(false); + con.release(); return false; } } @@ -1575,11 +1576,11 @@ public boolean matches(CharacterIterator target, Match match) { if (this.context == null) this.context = new Context(); } - Context con = null; - synchronized (this.context) { - con = this.context.inuse ? new Context() : this.context; - con.reset(target, start, end, this.numberOfClosures); + Context con = this.context; + if (!con.claim()) { + con = new Context(); } + con.reset(target, start, end, this.numberOfClosures); if (match != null) { match.setNumberOfGroups(this.nofparen); match.setSource(target); @@ -1599,7 +1600,7 @@ public boolean matches(CharacterIterator target, Match match) { con.match.setBeginning(0, con.start); con.match.setEnd(0, matchEnd); } - con.setInUse(false); + con.release(); return true; } return false; @@ -1617,10 +1618,10 @@ public boolean matches(CharacterIterator target, Match match) { con.match.setBeginning(0, o); con.match.setEnd(0, o+this.fixedString.length()); } - con.setInUse(false); + con.release(); return true; } - con.setInUse(false); + con.release(); return false; } @@ -1633,7 +1634,7 @@ public boolean matches(CharacterIterator target, Match match) { int o = this.fixedStringTable.matches(target, con.start, con.limit); if (o < 0) { //System.err.println("Non-match in fixed-string search."); - con.setInUse(false); + con.release(); return false; } } @@ -1704,10 +1705,10 @@ else if (this.firstChar != null) { con.match.setBeginning(0, matchStart); con.match.setEnd(0, matchEnd); } - con.setInUse(false); + con.release(); return true; } else { - con.setInUse(false); + con.release(); return false; } } @@ -2015,7 +2016,7 @@ static final class Context { int limit; int length; Match match; - boolean inuse = false; + private final Semaphore inuse = new Semaphore(1); ClosureContext[] closureContexts; private StringTarget stringTarget; @@ -2029,7 +2030,6 @@ static final class Context { private void resetCommon(int nofclosures) { this.length = this.limit-this.start; - setInUse(true); this.match = null; if (this.closureContexts == null || this.closureContexts.length != nofclosures) { this.closureContexts = new ClosureContext[nofclosures]; @@ -2082,8 +2082,13 @@ void reset(char[] target, int start, int limit, int nofclosures) { this.limit = limit; this.resetCommon(nofclosures); } - synchronized void setInUse(boolean inUse) { - this.inuse = inUse; + + boolean claim() { + return inuse.tryAcquire(); + } + + void release() { + inuse.release(); } } From 191b38e71279151d0444bb38b659e880e6f8a1e7 Mon Sep 17 00:00:00 2001 From: Roger Riggs <rriggs@openjdk.org> Date: Thu, 21 Nov 2024 18:03:12 +0000 Subject: [PATCH 163/311] 8344549: Cleanup AccessController in sun.misc.Unsafe Reviewed-by: alanb --- .../share/classes/sun/misc/Unsafe.java | 20 ++++--------------- 1 file changed, 4 insertions(+), 16 deletions(-) diff --git a/src/jdk.unsupported/share/classes/sun/misc/Unsafe.java b/src/jdk.unsupported/share/classes/sun/misc/Unsafe.java index 2c9f02efae0..563f2039de9 100644 --- a/src/jdk.unsupported/share/classes/sun/misc/Unsafe.java +++ b/src/jdk.unsupported/share/classes/sun/misc/Unsafe.java @@ -31,11 +31,7 @@ import java.lang.foreign.ValueLayout; import java.lang.invoke.VarHandle; import java.lang.reflect.Field; -import java.net.URL; -import java.security.AccessController; import java.security.CodeSource; -import java.security.ProtectionDomain; -import java.security.PrivilegedAction; import java.util.List; import java.util.Set; @@ -1829,7 +1825,7 @@ private static void beforeMemoryAccessSlow() { } /** - * Represents the options for the depreacted method-access methods. + * Represents the options for the deprecated method-access methods. */ private enum MemoryAccessOption { /** @@ -1881,14 +1877,8 @@ static MemoryAccessOption value() { * Holder for StackWalker that retains class references. */ private static class StackWalkerHolder { - static final StackWalker INSTANCE; - static { - PrivilegedAction<StackWalker> pa = () -> - StackWalker.getInstance(StackWalker.Option.RETAIN_CLASS_REFERENCE); - @SuppressWarnings("removal") - StackWalker walker = AccessController.doPrivileged(pa); - INSTANCE = walker; - } + static final StackWalker INSTANCE = + StackWalker.getInstance(StackWalker.Option.RETAIN_CLASS_REFERENCE); } /** @@ -1918,9 +1908,7 @@ private static String singleLineWarning(Class<?> callerClass, String methodName) * Returns a string with the caller class and the location URL from the CodeSource. */ private static String callerAndLocation(Class<?> callerClass) { - PrivilegedAction<ProtectionDomain> pa = callerClass::getProtectionDomain; - @SuppressWarnings("removal") - CodeSource cs = AccessController.doPrivileged(pa).getCodeSource(); + CodeSource cs = callerClass.getProtectionDomain().getCodeSource(); String who = callerClass.getName(); if (cs != null && cs.getLocation() != null) { who += " (" + cs.getLocation() + ")"; From dc9a6ef6100d73a431cd0cfa2c252acf7743f8a3 Mon Sep 17 00:00:00 2001 From: Jatin Bhateja <jbhateja@openjdk.org> Date: Thu, 21 Nov 2024 18:13:32 +0000 Subject: [PATCH 164/311] 8341137: Optimize long vector multiplication using x86 VPMUL[U]DQ instruction Co-authored-by: Vladimir Ivanov <vlivanov@openjdk.org> Reviewed-by: vlivanov, sviswanathan --- src/hotspot/cpu/x86/x86.ad | 28 ++ src/hotspot/share/opto/node.hpp | 3 + src/hotspot/share/opto/vectornode.cpp | 49 ++++ src/hotspot/share/opto/vectornode.hpp | 6 +- .../compiler/vectorapi/VectorMultiplyOpt.java | 249 ++++++++++++++++++ .../vector/VectorMultiplyOptBenchmark.java | 125 +++++++++ .../vector/VectorXXH3HashingBenchmark.java | 85 ++++++ 7 files changed, 544 insertions(+), 1 deletion(-) create mode 100644 test/hotspot/jtreg/compiler/vectorapi/VectorMultiplyOpt.java create mode 100644 test/micro/org/openjdk/bench/jdk/incubator/vector/VectorMultiplyOptBenchmark.java create mode 100644 test/micro/org/openjdk/bench/jdk/incubator/vector/VectorXXH3HashingBenchmark.java diff --git a/src/hotspot/cpu/x86/x86.ad b/src/hotspot/cpu/x86/x86.ad index d135c7bacfa..09023562dd6 100644 --- a/src/hotspot/cpu/x86/x86.ad +++ b/src/hotspot/cpu/x86/x86.ad @@ -6179,6 +6179,7 @@ instruct evmulL_reg(vec dst, vec src1, vec src2) %{ VM_Version::supports_avx512dq()) || VM_Version::supports_avx512vldq()); match(Set dst (MulVL src1 src2)); + ins_cost(500); format %{ "evpmullq $dst,$src1,$src2\t! mul packedL" %} ins_encode %{ assert(UseAVX > 2, "required"); @@ -6195,6 +6196,7 @@ instruct evmulL_mem(vec dst, vec src, memory mem) %{ VM_Version::supports_avx512vldq())); match(Set dst (MulVL src (LoadVector mem))); format %{ "evpmullq $dst,$src,$mem\t! mul packedL" %} + ins_cost(500); ins_encode %{ assert(UseAVX > 2, "required"); int vlen_enc = vector_length_encoding(this); @@ -6206,6 +6208,7 @@ instruct evmulL_mem(vec dst, vec src, memory mem) %{ instruct vmulL(vec dst, vec src1, vec src2, vec xtmp) %{ predicate(UseAVX == 0); match(Set dst (MulVL src1 src2)); + ins_cost(500); effect(TEMP dst, TEMP xtmp); format %{ "mulVL $dst, $src1, $src2\t! using $xtmp as TEMP" %} ins_encode %{ @@ -6232,6 +6235,7 @@ instruct vmulL_reg(vec dst, vec src1, vec src2, vec xtmp1, vec xtmp2) %{ !VM_Version::supports_avx512vldq()))); match(Set dst (MulVL src1 src2)); effect(TEMP xtmp1, TEMP xtmp2); + ins_cost(500); format %{ "vmulVL $dst, $src1, $src2\t! using $xtmp1, $xtmp2 as TEMP" %} ins_encode %{ int vlen_enc = vector_length_encoding(this); @@ -6248,6 +6252,30 @@ instruct vmulL_reg(vec dst, vec src1, vec src2, vec xtmp1, vec xtmp2) %{ ins_pipe( pipe_slow ); %} +instruct vmuludq_reg(vec dst, vec src1, vec src2) %{ + predicate(UseAVX > 0 && n->as_MulVL()->has_uint_inputs()); + match(Set dst (MulVL src1 src2)); + ins_cost(100); + format %{ "vpmuludq $dst,$src1,$src2\t! muludq packedL" %} + ins_encode %{ + int vlen_enc = vector_length_encoding(this); + __ vpmuludq($dst$$XMMRegister, $src1$$XMMRegister, $src2$$XMMRegister, vlen_enc); + %} + ins_pipe( pipe_slow ); +%} + +instruct vmuldq_reg(vec dst, vec src1, vec src2) %{ + predicate(UseAVX > 0 && n->as_MulVL()->has_int_inputs()); + match(Set dst (MulVL src1 src2)); + ins_cost(100); + format %{ "vpmuldq $dst,$src1,$src2\t! muldq packedL" %} + ins_encode %{ + int vlen_enc = vector_length_encoding(this); + __ vpmuldq($dst$$XMMRegister, $src1$$XMMRegister, $src2$$XMMRegister, vlen_enc); + %} + ins_pipe( pipe_slow ); +%} + // Floats vector mul instruct vmulF(vec dst, vec src) %{ predicate(UseAVX == 0); diff --git a/src/hotspot/share/opto/node.hpp b/src/hotspot/share/opto/node.hpp index db8b00c0bda..678b12b04ac 100644 --- a/src/hotspot/share/opto/node.hpp +++ b/src/hotspot/share/opto/node.hpp @@ -193,6 +193,7 @@ class VectorUnboxNode; class VectorSet; class VectorReinterpretNode; class ShiftVNode; +class MulVLNode; class ExpandVNode; class CompressVNode; class CompressMNode; @@ -743,6 +744,7 @@ class Node { DEFINE_CLASS_ID(Reduction, Vector, 7) DEFINE_CLASS_ID(NegV, Vector, 8) DEFINE_CLASS_ID(SaturatingVector, Vector, 9) + DEFINE_CLASS_ID(MulVL, Vector, 10) DEFINE_CLASS_ID(Con, Type, 8) DEFINE_CLASS_ID(ConI, Con, 0) DEFINE_CLASS_ID(SafePointScalarMerge, Type, 9) @@ -970,6 +972,7 @@ class Node { DEFINE_CLASS_QUERY(Mul) DEFINE_CLASS_QUERY(Multi) DEFINE_CLASS_QUERY(MultiBranch) + DEFINE_CLASS_QUERY(MulVL) DEFINE_CLASS_QUERY(Neg) DEFINE_CLASS_QUERY(NegV) DEFINE_CLASS_QUERY(NeverBranch) diff --git a/src/hotspot/share/opto/vectornode.cpp b/src/hotspot/share/opto/vectornode.cpp index cc2fff23acc..dedac80d102 100644 --- a/src/hotspot/share/opto/vectornode.cpp +++ b/src/hotspot/share/opto/vectornode.cpp @@ -2085,6 +2085,55 @@ Node* VectorBlendNode::Identity(PhaseGVN* phase) { } return this; } +static bool is_replicate_uint_constant(const Node* n) { + return n->Opcode() == Op_Replicate && + n->in(1)->is_Con() && + n->in(1)->bottom_type()->isa_long() && + n->in(1)->bottom_type()->is_long()->get_con() <= 0xFFFFFFFFL; +} + +static bool has_vector_elements_fit_uint(Node* n) { + auto is_lower_doubleword_mask_pattern = [](const Node* n) { + return n->Opcode() == Op_AndV && + (is_replicate_uint_constant(n->in(1)) || + is_replicate_uint_constant(n->in(2))); + }; + + auto is_clear_upper_doubleword_uright_shift_pattern = [](const Node* n) { + return n->Opcode() == Op_URShiftVL && + n->in(2)->Opcode() == Op_RShiftCntV && n->in(2)->in(1)->is_Con() && + n->in(2)->in(1)->bottom_type()->isa_int() && + n->in(2)->in(1)->bottom_type()->is_int()->get_con() >= 32; + }; + return is_lower_doubleword_mask_pattern(n) || // (AndV SRC (Replicate C)) where C <= 0xFFFFFFFF + is_clear_upper_doubleword_uright_shift_pattern(n); // (URShiftV SRC S) where S >= 32 +} + +static bool has_vector_elements_fit_int(Node* n) { + auto is_cast_integer_to_long_pattern = [](const Node* n) { + return n->Opcode() == Op_VectorCastI2X && Matcher::vector_element_basic_type(n) == T_LONG; + }; + + auto is_clear_upper_doubleword_right_shift_pattern = [](const Node* n) { + return n->Opcode() == Op_RShiftVL && + n->in(2)->Opcode() == Op_RShiftCntV && n->in(2)->in(1)->is_Con() && + n->in(2)->in(1)->bottom_type()->isa_int() && + n->in(2)->in(1)->bottom_type()->is_int()->get_con() >= 32; + }; + + return is_cast_integer_to_long_pattern(n) || // (VectorCastI2X SRC) + is_clear_upper_doubleword_right_shift_pattern(n); // (RShiftV SRC S) where S >= 32 +} + +bool MulVLNode::has_int_inputs() const { + return has_vector_elements_fit_int(in(1)) && + has_vector_elements_fit_int(in(2)); +} + +bool MulVLNode::has_uint_inputs() const { + return has_vector_elements_fit_uint(in(1)) && + has_vector_elements_fit_uint(in(2)); +} #ifndef PRODUCT void VectorBoxAllocateNode::dump_spec(outputStream *st) const { diff --git a/src/hotspot/share/opto/vectornode.hpp b/src/hotspot/share/opto/vectornode.hpp index 25a381408ca..3f737e6e881 100644 --- a/src/hotspot/share/opto/vectornode.hpp +++ b/src/hotspot/share/opto/vectornode.hpp @@ -441,8 +441,12 @@ class MulVINode : public VectorNode { // Vector multiply long class MulVLNode : public VectorNode { public: - MulVLNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1, in2, vt) {} + MulVLNode(Node* in1, Node* in2, const TypeVect* vt) : VectorNode(in1, in2, vt) { + init_class_id(Class_MulVL); + } virtual int Opcode() const; + bool has_int_inputs() const; + bool has_uint_inputs() const; }; //------------------------------MulVFNode-------------------------------------- diff --git a/test/hotspot/jtreg/compiler/vectorapi/VectorMultiplyOpt.java b/test/hotspot/jtreg/compiler/vectorapi/VectorMultiplyOpt.java new file mode 100644 index 00000000000..a48cd25e47f --- /dev/null +++ b/test/hotspot/jtreg/compiler/vectorapi/VectorMultiplyOpt.java @@ -0,0 +1,249 @@ +/* + * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package compiler.vectorapi; + +import jdk.incubator.vector.*; +import java.util.Random; +import java.util.stream.IntStream; +import compiler.lib.ir_framework.*; +import java.lang.reflect.Array; + +/** + * @test + * @bug 8341137 + * @summary Optimize long vector multiplication using x86 VPMUL[U]DQ instruction. + * @modules jdk.incubator.vector + * @library /test/lib / + * @run driver compiler.vectorapi.VectorMultiplyOpt + */ + +public class VectorMultiplyOpt { + + public static int[] isrc1; + public static int[] isrc2; + public static long[] lsrc1; + public static long[] lsrc2; + public static long[] res; + + public static final int SIZE = 1024; + public static final Random r = jdk.test.lib.Utils.getRandomInstance(); + public static final VectorSpecies<Long> LSP = LongVector.SPECIES_PREFERRED; + public static final VectorSpecies<Integer> ISP = IntVector.SPECIES_PREFERRED; + + public static final long mask1 = r.nextLong(0xFFFFFFFFL); + public static final long mask2 = r.nextLong(0xFFFFFFFFL); + public static final long mask3 = r.nextLong(0xFFFFFFFFL); + public static final long mask4 = r.nextLong(0xFFFFFFFFL); + public static final long mask5 = r.nextLong(0xFFFFFFFFL); + public static final long mask6 = r.nextLong(0xFFFFFFFFL); + + public static final int shift1 = r.nextInt(32) + 32; + public static final int shift2 = r.nextInt(32) + 32; + public static final int shift3 = r.nextInt(32) + 32; + public static final int shift4 = r.nextInt(32) + 32; + public static final int shift5 = r.nextInt(32) + 32; + + public VectorMultiplyOpt() { + lsrc1 = new long[SIZE]; + lsrc2 = new long[SIZE]; + res = new long[SIZE]; + isrc1 = new int[SIZE + 16]; + isrc2 = new int[SIZE + 16]; + IntStream.range(0, SIZE).forEach(i -> { lsrc1[i] = Long.MAX_VALUE * r.nextLong(); }); + IntStream.range(0, SIZE).forEach(i -> { lsrc2[i] = Long.MAX_VALUE * r.nextLong(); }); + IntStream.range(0, SIZE).forEach(i -> { isrc1[i] = Integer.MAX_VALUE * r.nextInt(); }); + IntStream.range(0, SIZE).forEach(i -> { isrc2[i] = Integer.MAX_VALUE * r.nextInt(); }); + } + + + public static void main(String[] args) { + TestFramework testFramework = new TestFramework(); + testFramework.setDefaultWarmup(5000) + .addFlags("--add-modules=jdk.incubator.vector") + .start(); + System.out.println("PASSED"); + } + + interface Validator { + public long apply(long src1, long src2); + } + + public static void validate(String msg, long[] actual, Object src1, Object src2, Validator func) { + for (int i = 0; i < actual.length; i++) { + long expected; + if (long[].class == src1.getClass()) { + expected = func.apply(Array.getLong(src1, i), Array.getLong(src2, i)); + } else { + assert int[].class == src1.getClass(); + expected = func.apply(Array.getInt(src1, i), Array.getInt(src2, i)); + } + if (actual[i] != expected) { + throw new AssertionError(msg + "index " + i + ": src1 = " + Array.get(src1, i) + " src2 = " + + Array.get(src2, i) + " actual = " + actual[i] + " expected = " + expected); + } + } + } + + @Test + @IR(counts = {IRNode.MUL_VL, " >0 ", IRNode.AND_VL, " >0 "}, applyIfCPUFeature = {"avx", "true"}) + @IR(counts = {"vmuludq", " >0 "}, phase = CompilePhase.FINAL_CODE, applyIfCPUFeature = {"avx", "true"}) + @Warmup(value = 10000) + public static void test_pattern1() { + int i = 0; + for (; i < LSP.loopBound(res.length); i += LSP.length()) { + LongVector vsrc1 = LongVector.fromArray(LSP, lsrc1, i); + LongVector vsrc2 = LongVector.fromArray(LSP, lsrc2, i); + vsrc1.lanewise(VectorOperators.AND, mask1) + .lanewise(VectorOperators.MUL, vsrc2.lanewise(VectorOperators.AND, mask1)) + .intoArray(res, i); + } + for (; i < res.length; i++) { + res[i] = (lsrc1[i] & mask1) * (lsrc2[i] & mask1); + } + } + + @Check(test = "test_pattern1") + public void test_pattern1_validate() { + validate("pattern1 ", res, lsrc1, lsrc2, (l1, l2) -> (l1 & mask1) * (l2 & mask1)); + } + + @Test + @IR(counts = {IRNode.MUL_VL, " >0 ", IRNode.AND_VL, " >0 ", IRNode.URSHIFT_VL, " >0 "}, applyIfCPUFeature = {"avx", "true"}) + @IR(counts = {"vmuludq", " >0 "}, phase = CompilePhase.FINAL_CODE, applyIfCPUFeature = {"avx", "true"}) + @Warmup(value = 10000) + public static void test_pattern2() { + int i = 0; + for (; i < LSP.loopBound(res.length); i += LSP.length()) { + LongVector vsrc1 = LongVector.fromArray(LSP, lsrc1, i); + LongVector vsrc2 = LongVector.fromArray(LSP, lsrc2, i); + vsrc1.lanewise(VectorOperators.AND, mask2) + .lanewise(VectorOperators.MUL, vsrc2.lanewise(VectorOperators.LSHR, shift1)) + .intoArray(res, i); + } + for (; i < res.length; i++) { + res[i] = (lsrc1[i] & mask2) * (lsrc2[i] >>> shift1); + } + } + + @Check(test = "test_pattern2") + public void test_pattern2_validate() { + validate("pattern2 ", res, lsrc1, lsrc2, (l1, l2) -> (l1 & mask2) * (l2 >>> shift1)); + } + + @Test + @IR(counts = {IRNode.MUL_VL, " >0 ", IRNode.URSHIFT_VL, " >0 "}, applyIfCPUFeature = {"avx", "true"}) + @IR(counts = {"vmuludq", " >0 "}, phase = CompilePhase.FINAL_CODE, applyIfCPUFeature = {"avx", "true"}) + @Warmup(value = 10000) + public static void test_pattern3() { + int i = 0; + for (; i < LSP.loopBound(res.length); i += LSP.length()) { + LongVector vsrc1 = LongVector.fromArray(LSP, lsrc1, i); + LongVector vsrc2 = LongVector.fromArray(LSP, lsrc2, i); + vsrc1.lanewise(VectorOperators.LSHR, shift2) + .lanewise(VectorOperators.MUL, vsrc2.lanewise(VectorOperators.LSHR, shift3)) + .intoArray(res, i); + } + for (; i < res.length; i++) { + res[i] = (lsrc1[i] >>> shift2) * (lsrc2[i] >>> shift3); + } + } + + @Check(test = "test_pattern3") + public void test_pattern3_validate() { + validate("pattern3 ", res, lsrc1, lsrc2, (l1, l2) -> (l1 >>> shift2) * (l2 >>> shift3)); + } + + @Test + @IR(counts = {IRNode.MUL_VL, " >0 ", IRNode.URSHIFT_VL, " >0 "}, applyIfCPUFeature = {"avx", "true"}) + @IR(counts = {"vmuludq", " >0 "}, applyIfCPUFeature = {"avx", "true"}, phase = CompilePhase.FINAL_CODE) + @Warmup(value = 10000) + public static void test_pattern4() { + int i = 0; + for (; i < LSP.loopBound(res.length); i += LSP.length()) { + LongVector vsrc1 = LongVector.fromArray(LSP, lsrc1, i); + LongVector vsrc2 = LongVector.fromArray(LSP, lsrc2, i); + vsrc1.lanewise(VectorOperators.LSHR, shift4) + .lanewise(VectorOperators.MUL, vsrc2.lanewise(VectorOperators.AND, mask4)) + .intoArray(res, i); + } + for (; i < res.length; i++) { + res[i] = (lsrc1[i] >>> shift4) * (lsrc2[i] & mask4); + } + } + + @Check(test = "test_pattern4") + public void test_pattern4_validate() { + validate("pattern4 ", res, lsrc1, lsrc2, (l1, l2) -> (l1 >>> shift4) * (l2 & mask4)); + } + + @Test + @IR(counts = {IRNode.MUL_VL, " >0 ", IRNode.VECTOR_CAST_I2L, " >0 "}, applyIfCPUFeature = {"avx", "true"}) + @IR(counts = {"vmuldq", " >0 "}, applyIfCPUFeature = {"avx", "true"}, phase = CompilePhase.FINAL_CODE) + @Warmup(value = 10000) + public static void test_pattern5() { + int i = 0; + for (; i < LSP.loopBound(res.length); i += LSP.length()) { + LongVector vsrc1 = IntVector.fromArray(ISP, isrc1, i) + .convert(VectorOperators.I2L, 0) + .reinterpretAsLongs(); + LongVector vsrc2 = IntVector.fromArray(ISP, isrc2, i) + .convert(VectorOperators.I2L, 0) + .reinterpretAsLongs(); + vsrc1.lanewise(VectorOperators.MUL, vsrc2).intoArray(res, i); + } + for (; i < res.length; i++) { + res[i] = Math.multiplyFull(isrc1[i], isrc2[i]); + } + } + + @Check(test = "test_pattern5") + public void test_pattern5_validate() { + validate("pattern5 ", res, isrc1, isrc2, (i1, i2) -> Math.multiplyFull((int)i1, (int)i2)); + } + + + @Test + @IR(counts = {IRNode.MUL_VL, " >0 ", IRNode.RSHIFT_VL, " >0 "}, applyIfCPUFeature = {"avx", "true"}) + @IR(counts = {"vmuldq", " >0 "}, applyIfCPUFeature = {"avx", "true"}, phase = CompilePhase.FINAL_CODE) + @Warmup(value = 10000) + public static void test_pattern6() { + int i = 0; + for (; i < LSP.loopBound(res.length); i += LSP.length()) { + LongVector vsrc1 = LongVector.fromArray(LSP, lsrc1, i); + LongVector vsrc2 = LongVector.fromArray(LSP, lsrc2, i); + vsrc1.lanewise(VectorOperators.ASHR, shift5) + .lanewise(VectorOperators.MUL, vsrc2.lanewise(VectorOperators.ASHR, shift5)) + .intoArray(res, i); + } + for (; i < res.length; i++) { + res[i] = (lsrc1[i] >> shift5) * (lsrc2[i] >> shift5); + } + } + + @Check(test = "test_pattern6") + public void test_pattern6_validate() { + validate("pattern6 ", res, lsrc1, lsrc2, (l1, l2) -> (l1 >> shift5) * (l2 >> shift5)); + } + +} diff --git a/test/micro/org/openjdk/bench/jdk/incubator/vector/VectorMultiplyOptBenchmark.java b/test/micro/org/openjdk/bench/jdk/incubator/vector/VectorMultiplyOptBenchmark.java new file mode 100644 index 00000000000..51f8300a044 --- /dev/null +++ b/test/micro/org/openjdk/bench/jdk/incubator/vector/VectorMultiplyOptBenchmark.java @@ -0,0 +1,125 @@ +/* + * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package org.openjdk.bench.jdk.incubator.vector; + +import java.util.concurrent.TimeUnit; +import org.openjdk.jmh.annotations.*; +import jdk.incubator.vector.*; +import java.util.stream.*; + +@BenchmarkMode(Mode.Throughput) +@OutputTimeUnit(TimeUnit.MILLISECONDS) +@State(Scope.Benchmark) +@Warmup(iterations = 3, time = 1) +@Measurement(iterations = 5, time = 1) +@Fork(value = 1, jvmArgsPrepend = {"--add-modules=jdk.incubator.vector"}) +public class VectorMultiplyOptBenchmark { + @Param({"1024", "2048", "4096"}) + private int SIZE; + private int [] isrc1; + private int [] isrc2; + private long [] lsrc1; + private long [] lsrc2; + private long [] res; + + private static final VectorSpecies<Long> LSP = LongVector.SPECIES_PREFERRED; + private static final VectorSpecies<Integer> ISP = IntVector.SPECIES_PREFERRED; + + @Setup(Level.Trial) + public void Setup() { + lsrc1 = LongStream.range(Long.MAX_VALUE - SIZE, Long.MAX_VALUE).toArray(); + lsrc2 = LongStream.range(0, SIZE).toArray(); + isrc1 = IntStream.range(Integer.MAX_VALUE - 2 * SIZE, Integer.MAX_VALUE).toArray(); + isrc2 = IntStream.range(0, 2 * SIZE).toArray(); + res = new long[SIZE]; + } + + @Benchmark + public void test_bm_pattern1() { + for (int i = 0; i < LSP.loopBound(res.length); i += LSP.length()) { + LongVector vsrc1 = LongVector.fromArray(LSP, lsrc1, i); + LongVector vsrc2 = LongVector.fromArray(LSP, lsrc2, i); + vsrc1.lanewise(VectorOperators.AND, 0xFFFFFFFFL) + .lanewise(VectorOperators.MUL, vsrc2.lanewise(VectorOperators.AND, 0xFFFFFFFFL)) + .intoArray(res, i); + } + } + + @Benchmark + public void test_bm_pattern2() { + for (int i = 0; i < LSP.loopBound(res.length); i += LSP.length()) { + LongVector vsrc1 = LongVector.fromArray(LSP, lsrc1, i); + LongVector vsrc2 = LongVector.fromArray(LSP, lsrc2, i); + vsrc1.lanewise(VectorOperators.AND, 0xFFFFFFFFL) + .lanewise(VectorOperators.MUL, vsrc2.lanewise(VectorOperators.LSHR, 32)) + .intoArray(res, i); + } + } + + @Benchmark + public void test_bm_pattern3() { + for (int i = 0; i < LSP.loopBound(res.length); i += LSP.length()) { + LongVector vsrc1 = LongVector.fromArray(LSP, lsrc1, i); + LongVector vsrc2 = LongVector.fromArray(LSP, lsrc2, i); + vsrc1.lanewise(VectorOperators.LSHR, 32) + .lanewise(VectorOperators.MUL, vsrc2.lanewise(VectorOperators.LSHR, 32)) + .intoArray(res, i); + } + } + + @Benchmark + public void test_bm_pattern4() { + for (int i = 0; i < LSP.loopBound(res.length); i += LSP.length()) { + LongVector vsrc1 = LongVector.fromArray(LSP, lsrc1, i); + LongVector vsrc2 = LongVector.fromArray(LSP, lsrc2, i); + vsrc1.lanewise(VectorOperators.LSHR, 32) + .lanewise(VectorOperators.MUL, vsrc2.lanewise(VectorOperators.AND, 0xFFFFFFFFL)) + .intoArray(res, i); + } + } + + @Benchmark + public void test_bm_pattern5() { + for (int i = 0; i < LSP.loopBound(res.length); i += LSP.length()) { + LongVector vsrc1 = IntVector.fromArray(ISP, isrc1, i) + .convert(VectorOperators.I2L, 0) + .reinterpretAsLongs(); + LongVector vsrc2 = IntVector.fromArray(ISP, isrc2, i) + .convert(VectorOperators.I2L, 0) + .reinterpretAsLongs(); + vsrc1.lanewise(VectorOperators.MUL, vsrc2).intoArray(res, i); + } + } + + @Benchmark + public void test_bm_pattern6() { + for (int i = 0; i < LSP.loopBound(res.length); i += LSP.length()) { + LongVector vsrc1 = LongVector.fromArray(LSP, lsrc1, i); + LongVector vsrc2 = LongVector.fromArray(LSP, lsrc2, i); + vsrc1.lanewise(VectorOperators.ASHR, 32) + .lanewise(VectorOperators.MUL, vsrc2.lanewise(VectorOperators.ASHR, 32)) + .intoArray(res, i); + } + } + +} diff --git a/test/micro/org/openjdk/bench/jdk/incubator/vector/VectorXXH3HashingBenchmark.java b/test/micro/org/openjdk/bench/jdk/incubator/vector/VectorXXH3HashingBenchmark.java new file mode 100644 index 00000000000..32056da49aa --- /dev/null +++ b/test/micro/org/openjdk/bench/jdk/incubator/vector/VectorXXH3HashingBenchmark.java @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package org.openjdk.bench.jdk.incubator.vector; + +import java.util.concurrent.TimeUnit; +import org.openjdk.jmh.annotations.*; +import jdk.incubator.vector.*; +import java.util.stream.*; + +@BenchmarkMode(Mode.Throughput) +@OutputTimeUnit(TimeUnit.MILLISECONDS) +@State(Scope.Benchmark) +@Warmup(iterations = 3, time = 1) +@Measurement(iterations = 5, time = 1) +@Fork(value = 1, jvmArgsPrepend = {"--add-modules=jdk.incubator.vector"}) +public class VectorXXH3HashingBenchmark { + @Param({"1024", "2048", "4096", "8192"}) + private int SIZE; + private long [] accumulators; + private byte [] input; + private byte [] SECRET; + + private static final VectorShuffle<Long> LONG_SHUFFLE_PREFERRED = VectorShuffle.fromOp(LongVector.SPECIES_PREFERRED, i -> i ^ 1); + + @Setup(Level.Trial) + public void Setup() { + accumulators = new long[SIZE]; + input = new byte[SIZE * 8]; + SECRET = new byte[SIZE*8]; + IntStream.range(0, SIZE*8).forEach( + i -> { + input[i] = (byte)i; + SECRET[i] = (byte)-i; + } + ); + } + + @Benchmark + public void hashingKernel() { + for (int block = 0; block < input.length / 1024; block++) { + for (int stripe = 0; stripe < 16; stripe++) { + int inputOffset = block * 1024 + stripe * 64; + int secretOffset = stripe * 8; + + for (int i = 0; i < 8; i += LongVector.SPECIES_PREFERRED.length()) { + LongVector accumulatorsVector = LongVector.fromArray(LongVector.SPECIES_PREFERRED, accumulators, i); + LongVector inputVector = ByteVector.fromArray(ByteVector.SPECIES_PREFERRED, input, inputOffset + i * 8).reinterpretAsLongs(); + LongVector secretVector = ByteVector.fromArray(ByteVector.SPECIES_PREFERRED, SECRET, secretOffset + i * 8).reinterpretAsLongs(); + + LongVector key = inputVector + .lanewise(VectorOperators.XOR, secretVector) + .reinterpretAsLongs(); + + LongVector low = key.and(0xFFFF_FFFFL); + LongVector high = key.lanewise(VectorOperators.LSHR, 32); + + accumulatorsVector + .add(inputVector.rearrange(LONG_SHUFFLE_PREFERRED)) + .add(high.mul(low)) + .intoArray(accumulators, i); + } + } + } + } +} From 93d4ad4dd4cc4c5700af3453cfb3e21a804c8c14 Mon Sep 17 00:00:00 2001 From: Coleen Phillimore <coleenp@openjdk.org> Date: Thu, 21 Nov 2024 18:26:23 +0000 Subject: [PATCH 165/311] 8344763: cpCache print_on doesn't handle nulls Reviewed-by: matsaave --- src/hotspot/share/oops/cpCache.cpp | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/hotspot/share/oops/cpCache.cpp b/src/hotspot/share/oops/cpCache.cpp index bcf3669c9df..66650ee65bf 100644 --- a/src/hotspot/share/oops/cpCache.cpp +++ b/src/hotspot/share/oops/cpCache.cpp @@ -829,9 +829,15 @@ oop ConstantPoolCache::appendix_if_resolved(ResolvedMethodEntry* method_entry) c void ConstantPoolCache::print_on(outputStream* st) const { st->print_cr("%s", internal_name()); // print constant pool cache entries - print_resolved_field_entries(st); - print_resolved_method_entries(st); - print_resolved_indy_entries(st); + if (_resolved_field_entries != nullptr) { + print_resolved_field_entries(st); + } + if (_resolved_method_entries != nullptr) { + print_resolved_method_entries(st); + } + if (_resolved_indy_entries != nullptr) { + print_resolved_indy_entries(st); + } } void ConstantPoolCache::print_resolved_field_entries(outputStream* st) const { From d6b40d3033b306e2cefc12833bb4e99ae6e36008 Mon Sep 17 00:00:00 2001 From: Volodymyr Paprotski <vpaprotski@openjdk.org> Date: Thu, 21 Nov 2024 19:17:57 +0000 Subject: [PATCH 166/311] 8344144: AES/CBC slow at big payloads Reviewed-by: sviswanathan, abarashev, ascarpino --- .../crypto/provider/CipherBlockChaining.java | 32 +++++++++++++++++-- .../bench/javax/crypto/full/AESBench.java | 24 ++++++++++++-- 2 files changed, 51 insertions(+), 5 deletions(-) diff --git a/src/java.base/share/classes/com/sun/crypto/provider/CipherBlockChaining.java b/src/java.base/share/classes/com/sun/crypto/provider/CipherBlockChaining.java index 4bd7faea722..c084d6edd55 100644 --- a/src/java.base/share/classes/com/sun/crypto/provider/CipherBlockChaining.java +++ b/src/java.base/share/classes/com/sun/crypto/provider/CipherBlockChaining.java @@ -59,10 +59,15 @@ class CipherBlockChaining extends FeedbackCipher { // variables for save/restore calls private byte[] rSave = null; + // chunkSize is a multiple of block size and used to divide up + // input data to trigger the intrinsic. + private final int chunkSize; + CipherBlockChaining(SymmetricCipher embeddedCipher) { super(embeddedCipher); k = new byte[blockSize]; r = new byte[blockSize]; + chunkSize = blockSize * 6400; } /** @@ -148,8 +153,18 @@ int encrypt(byte[] plain, int plainOffset, int plainLen, ArrayUtil.blockSizeCheck(plainLen, blockSize); ArrayUtil.nullAndBoundsCheck(plain, plainOffset, plainLen); ArrayUtil.nullAndBoundsCheck(cipher, cipherOffset, plainLen); - return implEncrypt(plain, plainOffset, plainLen, - cipher, cipherOffset); + int processed = 0; + for (; plainLen > chunkSize; cipherOffset += chunkSize, + plainOffset += chunkSize, plainLen -= chunkSize) { + processed += + implEncrypt(plain, plainOffset, chunkSize, cipher, cipherOffset); + } + // note: above loop always leaves some data to process (more than zero, + // less than or equal to chunkSize) so this last call can be + // unconditional + processed += + implEncrypt(plain, plainOffset, plainLen, cipher, cipherOffset); + return processed; } @IntrinsicCandidate @@ -199,7 +214,18 @@ int decrypt(byte[] cipher, int cipherOffset, int cipherLen, ArrayUtil.blockSizeCheck(cipherLen, blockSize); ArrayUtil.nullAndBoundsCheck(cipher, cipherOffset, cipherLen); ArrayUtil.nullAndBoundsCheck(plain, plainOffset, cipherLen); - return implDecrypt(cipher, cipherOffset, cipherLen, plain, plainOffset); + int processed = 0; + for (; cipherLen > chunkSize; cipherOffset += chunkSize, + plainOffset += chunkSize, cipherLen -= chunkSize) { + processed += + implDecrypt(cipher, cipherOffset, chunkSize, plain, plainOffset); + } + // note: above loop always leaves some data to process (more than zero, + // less than or equal to chunkSize) so this last call can be + // unconditional + processed += + implDecrypt(cipher, cipherOffset, cipherLen, plain, plainOffset); + return processed; } @IntrinsicCandidate diff --git a/test/micro/org/openjdk/bench/javax/crypto/full/AESBench.java b/test/micro/org/openjdk/bench/javax/crypto/full/AESBench.java index 7e1eecdace4..f04e5d015a2 100644 --- a/test/micro/org/openjdk/bench/javax/crypto/full/AESBench.java +++ b/test/micro/org/openjdk/bench/javax/crypto/full/AESBench.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,6 +25,9 @@ import org.openjdk.jmh.annotations.Benchmark; import org.openjdk.jmh.annotations.Param; import org.openjdk.jmh.annotations.Setup; +import org.openjdk.jmh.infra.Blackhole; +import java.security.GeneralSecurityException; +import org.openjdk.jmh.annotations.Fork; import javax.crypto.BadPaddingException; import javax.crypto.Cipher; @@ -36,9 +39,10 @@ import java.security.NoSuchAlgorithmException; import java.security.spec.InvalidParameterSpecException; +@Fork(jvmArgsAppend = {"-Xms20g", "-Xmx20g", "-XX:+UseZGC"}) public class AESBench extends CryptoBase { - public static final int SET_SIZE = 128; + public static final int SET_SIZE = 8; @Param({"AES/ECB/NoPadding", "AES/ECB/PKCS5Padding", "AES/CBC/NoPadding", "AES/CBC/PKCS5Padding"}) private String algorithm; @@ -53,6 +57,7 @@ public class AESBench extends CryptoBase { byte[][] encryptedData; private Cipher encryptCipher; private Cipher decryptCipher; + private byte[] outBuffer; int index = 0; @Setup @@ -66,6 +71,7 @@ public void setup() throws NoSuchAlgorithmException, NoSuchPaddingException, Inv decryptCipher.init(Cipher.DECRYPT_MODE, ks, encryptCipher.getParameters()); data = fillRandom(new byte[SET_SIZE][dataSize]); encryptedData = fillEncrypted(data, encryptCipher); + outBuffer = new byte[dataSize + 128]; // extra space for tag, etc } @Benchmark @@ -75,6 +81,13 @@ public byte[] encrypt() throws BadPaddingException, IllegalBlockSizeException { return encryptCipher.doFinal(d); } + @Benchmark + public void encrypt2(Blackhole bh) throws GeneralSecurityException { + byte[] d = data[index]; + index = (index +1) % SET_SIZE; + bh.consume(encryptCipher.doFinal(d, 0, d.length, outBuffer)); + } + @Benchmark public byte[] decrypt() throws BadPaddingException, IllegalBlockSizeException { byte[] e = encryptedData[index]; @@ -82,4 +95,11 @@ public byte[] decrypt() throws BadPaddingException, IllegalBlockSizeException { return decryptCipher.doFinal(e); } + @Benchmark + public void decrypt2(Blackhole bh) throws GeneralSecurityException { + byte[] e = encryptedData[index]; + index = (index +1) % SET_SIZE; + bh.consume(decryptCipher.doFinal(e, 0, e.length, outBuffer)); + } + } From e03b1506d3644f9e4053630adc4c0620eaef71c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eirik=20Bj=C3=B8rsn=C3=B8s?= <eirbjo@openjdk.org> Date: Thu, 21 Nov 2024 20:04:39 +0000 Subject: [PATCH 167/311] 8178966: Don't swallow early bootstrap exceptions in Boolean.getBoolean, Integer.getInteger and Long.getLong Co-authored-by: Peter Levart <plevart@openjdk.org> Reviewed-by: jpai, rriggs --- src/java.base/share/classes/java/lang/Boolean.java | 7 +------ src/java.base/share/classes/java/lang/Integer.java | 6 +----- src/java.base/share/classes/java/lang/Long.java | 6 +----- 3 files changed, 3 insertions(+), 16 deletions(-) diff --git a/src/java.base/share/classes/java/lang/Boolean.java b/src/java.base/share/classes/java/lang/Boolean.java index f5c643881a8..aa64d799b66 100644 --- a/src/java.base/share/classes/java/lang/Boolean.java +++ b/src/java.base/share/classes/java/lang/Boolean.java @@ -275,12 +275,7 @@ public boolean equals(Object obj) { * @see java.lang.System#getProperty(java.lang.String, java.lang.String) */ public static boolean getBoolean(String name) { - boolean result = false; - try { - result = parseBoolean(System.getProperty(name)); - } catch (IllegalArgumentException | NullPointerException e) { - } - return result; + return name != null && !name.isEmpty() && parseBoolean(System.getProperty(name)); } /** diff --git a/src/java.base/share/classes/java/lang/Integer.java b/src/java.base/share/classes/java/lang/Integer.java index 8bf573733f2..a6bf739220f 100644 --- a/src/java.base/share/classes/java/lang/Integer.java +++ b/src/java.base/share/classes/java/lang/Integer.java @@ -1275,11 +1275,7 @@ public static Integer getInteger(String nm, int val) { * @see System#getProperty(java.lang.String, java.lang.String) */ public static Integer getInteger(String nm, Integer val) { - String v = null; - try { - v = System.getProperty(nm); - } catch (IllegalArgumentException | NullPointerException e) { - } + String v = nm != null && !nm.isEmpty() ? System.getProperty(nm) : null; if (v != null) { try { return Integer.decode(v); diff --git a/src/java.base/share/classes/java/lang/Long.java b/src/java.base/share/classes/java/lang/Long.java index e67b751470e..822199bb09b 100644 --- a/src/java.base/share/classes/java/lang/Long.java +++ b/src/java.base/share/classes/java/lang/Long.java @@ -1370,11 +1370,7 @@ public static Long getLong(String nm, long val) { * @see System#getProperty(java.lang.String, java.lang.String) */ public static Long getLong(String nm, Long val) { - String v = null; - try { - v = System.getProperty(nm); - } catch (IllegalArgumentException | NullPointerException e) { - } + String v = nm != null && !nm.isEmpty() ? System.getProperty(nm) : null; if (v != null) { try { return Long.decode(v); From 7709d435d080778a45bd3eb9a5754e356e94e6de Mon Sep 17 00:00:00 2001 From: Phil Race <prr@openjdk.org> Date: Thu, 21 Nov 2024 20:29:53 +0000 Subject: [PATCH 168/311] 8344782: Cleanup left over doPrivileged calls and imports in java.desktop Reviewed-by: honkar --- .../macosx/classes/com/apple/laf/AquaLookAndFeel.java | 1 - src/java.desktop/share/classes/java/awt/Cursor.java | 1 - .../javax/swing/text/html/parser/ParserDelegator.java | 3 --- .../share/classes/sun/awt/im/InputMethodManager.java | 4 ---- .../share/classes/sun/font/FontManagerNativeLibrary.java | 1 - .../share/classes/sun/swing/WindowsPlacesBar.java | 2 -- .../unix/classes/sun/awt/X11/XWindowPeer.java | 9 +-------- 7 files changed, 1 insertion(+), 20 deletions(-) diff --git a/src/java.desktop/macosx/classes/com/apple/laf/AquaLookAndFeel.java b/src/java.desktop/macosx/classes/com/apple/laf/AquaLookAndFeel.java index 34a39525a74..07637d5454c 100644 --- a/src/java.desktop/macosx/classes/com/apple/laf/AquaLookAndFeel.java +++ b/src/java.desktop/macosx/classes/com/apple/laf/AquaLookAndFeel.java @@ -28,7 +28,6 @@ import java.awt.Color; import java.awt.Dimension; import java.awt.KeyboardFocusManager; -import java.security.PrivilegedAction; import java.util.Enumeration; import java.util.Locale; import java.util.ResourceBundle; diff --git a/src/java.desktop/share/classes/java/awt/Cursor.java b/src/java.desktop/share/classes/java/awt/Cursor.java index 8a595f61285..396165e7ec8 100644 --- a/src/java.desktop/share/classes/java/awt/Cursor.java +++ b/src/java.desktop/share/classes/java/awt/Cursor.java @@ -28,7 +28,6 @@ import java.beans.ConstructorProperties; import java.io.InputStream; import java.io.Serial; -import java.security.AccessController; import java.util.Hashtable; import java.util.Properties; import java.util.StringTokenizer; diff --git a/src/java.desktop/share/classes/javax/swing/text/html/parser/ParserDelegator.java b/src/java.desktop/share/classes/javax/swing/text/html/parser/ParserDelegator.java index bf360574f6d..0f89e49a171 100644 --- a/src/java.desktop/share/classes/javax/swing/text/html/parser/ParserDelegator.java +++ b/src/java.desktop/share/classes/javax/swing/text/html/parser/ParserDelegator.java @@ -121,9 +121,6 @@ public void parse(Reader r, HTMLEditorKit.ParserCallback cb, boolean ignoreCharS /** * Fetch a resource relative to the ParserDelegator classfile. - * If this is called on 1.2 the loading will occur under the - * protection of a doPrivileged call to allow the ParserDelegator - * to function when used in an applet. * * @param name the name of the resource, relative to the * ParserDelegator class. diff --git a/src/java.desktop/share/classes/sun/awt/im/InputMethodManager.java b/src/java.desktop/share/classes/sun/awt/im/InputMethodManager.java index f61825d8ddf..3484f7cbebe 100644 --- a/src/java.desktop/share/classes/sun/awt/im/InputMethodManager.java +++ b/src/java.desktop/share/classes/sun/awt/im/InputMethodManager.java @@ -41,10 +41,6 @@ import java.awt.event.InvocationEvent; import java.awt.im.spi.InputMethodDescriptor; import java.lang.reflect.InvocationTargetException; -import java.security.AccessController; -import java.security.PrivilegedAction; -import java.security.PrivilegedActionException; -import java.security.PrivilegedExceptionAction; import java.util.Hashtable; import java.util.Iterator; import java.util.Locale; diff --git a/src/java.desktop/share/classes/sun/font/FontManagerNativeLibrary.java b/src/java.desktop/share/classes/sun/font/FontManagerNativeLibrary.java index 51997571e75..e3baf437a8b 100644 --- a/src/java.desktop/share/classes/sun/font/FontManagerNativeLibrary.java +++ b/src/java.desktop/share/classes/sun/font/FontManagerNativeLibrary.java @@ -61,7 +61,6 @@ top of freetype library (that is used in binary form). * Method acts as trigger to ensure this class is loaded * (and therefore initializer code is executed). * Actual loading is performed by static initializer. - * (no need to execute doPrivileged block more than once) */ public static void load() {} } diff --git a/src/java.desktop/share/classes/sun/swing/WindowsPlacesBar.java b/src/java.desktop/share/classes/sun/swing/WindowsPlacesBar.java index 8cc47c306c4..cd54d40bd0a 100644 --- a/src/java.desktop/share/classes/sun/swing/WindowsPlacesBar.java +++ b/src/java.desktop/share/classes/sun/swing/WindowsPlacesBar.java @@ -36,8 +36,6 @@ import java.beans.PropertyChangeListener; import java.io.File; -import java.security.AccessController; -import java.security.PrivilegedAction; import javax.swing.JToolBar; import javax.swing.JFileChooser; diff --git a/src/java.desktop/unix/classes/sun/awt/X11/XWindowPeer.java b/src/java.desktop/unix/classes/sun/awt/X11/XWindowPeer.java index 267ad9349ea..ebd04f2b7dd 100644 --- a/src/java.desktop/unix/classes/sun/awt/X11/XWindowPeer.java +++ b/src/java.desktop/unix/classes/sun/awt/X11/XWindowPeer.java @@ -47,8 +47,6 @@ import java.awt.event.WindowEvent; import java.awt.peer.ComponentPeer; import java.awt.peer.WindowPeer; -import java.security.AccessController; -import java.security.PrivilegedAction; import java.util.ArrayList; import java.util.HashSet; import java.util.Set; @@ -1322,12 +1320,7 @@ private void removeStartupNotification() { return; } - @SuppressWarnings("removal") - final String desktopStartupId = AccessController.doPrivileged(new PrivilegedAction<String>() { - public String run() { - return XToolkit.getEnv("DESKTOP_STARTUP_ID"); - } - }); + final String desktopStartupId = XToolkit.getEnv("DESKTOP_STARTUP_ID"); if (desktopStartupId == null) { return; } From cee74f9e677e74deda72638bcc0a3e9307262938 Mon Sep 17 00:00:00 2001 From: Aleksei Efimov <aefimov@openjdk.org> Date: Thu, 21 Nov 2024 20:55:02 +0000 Subject: [PATCH 169/311] 8338536: Permanently disable remote code downloading in JNDI Reviewed-by: dfuchs --- .../classes/com/sun/jndi/ldap/EventQueue.java | 2 +- .../sun/jndi/ldap/NamingEventNotifier.java | 2 +- .../share/classes/com/sun/jndi/ldap/Obj.java | 10 +- .../com/sun/jndi/ldap/VersionHelper.java | 63 +---- .../naming/internal/NamingManagerHelper.java | 35 +-- .../sun/naming/internal/VersionHelper.java | 159 +++---------- .../javax/naming/spi/NamingManager.java | 9 +- .../jndi/rmi/registry/RegistryContext.java | 34 +-- .../share/classes/module-info.java | 5 + .../ObjectFactoryBuilderCodebaseTest.java | 223 ++++++++++++++++++ .../objects/TestObjectFactoryBuilder.java | 74 ++++++ 11 files changed, 364 insertions(+), 252 deletions(-) create mode 100644 test/jdk/com/sun/jndi/rmi/registry/objects/ObjectFactoryBuilderCodebaseTest.java create mode 100644 test/jdk/com/sun/jndi/rmi/registry/objects/TestObjectFactoryBuilder.java diff --git a/src/java.naming/share/classes/com/sun/jndi/ldap/EventQueue.java b/src/java.naming/share/classes/com/sun/jndi/ldap/EventQueue.java index 29652dc5e6f..3d88e179894 100644 --- a/src/java.naming/share/classes/com/sun/jndi/ldap/EventQueue.java +++ b/src/java.naming/share/classes/com/sun/jndi/ldap/EventQueue.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff --git a/src/java.naming/share/classes/com/sun/jndi/ldap/NamingEventNotifier.java b/src/java.naming/share/classes/com/sun/jndi/ldap/NamingEventNotifier.java index fd168b3ccb0..27b83b91515 100644 --- a/src/java.naming/share/classes/com/sun/jndi/ldap/NamingEventNotifier.java +++ b/src/java.naming/share/classes/com/sun/jndi/ldap/NamingEventNotifier.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it diff --git a/src/java.naming/share/classes/com/sun/jndi/ldap/Obj.java b/src/java.naming/share/classes/com/sun/jndi/ldap/Obj.java index 1e6b30cb1c5..0d28928559f 100644 --- a/src/java.naming/share/classes/com/sun/jndi/ldap/Obj.java +++ b/src/java.naming/share/classes/com/sun/jndi/ldap/Obj.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -236,7 +236,7 @@ static Object decodeObject(Attributes attrs) if (!VersionHelper.isSerialDataAllowed()) { throw new NamingException("Object deserialization is not allowed"); } - ClassLoader cl = helper.getURLClassLoader(codebases); + ClassLoader cl = Thread.currentThread().getContextClassLoader(); return deserializeObject((byte[])attr.get(), cl); } else if ((attr = attrs.get(JAVA_ATTRIBUTES[REMOTE_LOC])) != null) { // javaRemoteLocation attribute (RMI stub will be created) @@ -246,7 +246,7 @@ static Object decodeObject(Attributes attrs) // For backward compatibility only return decodeRmiObject( (String)attrs.get(JAVA_ATTRIBUTES[CLASSNAME]).get(), - (String)attr.get(), codebases); + (String)attr.get()); } attr = attrs.get(JAVA_ATTRIBUTES[OBJECT_CLASS]); @@ -368,7 +368,7 @@ private static Attributes encodeReference(char separator, * @deprecated For backward compatibility only */ private static Object decodeRmiObject(String className, - String rmiName, String[] codebases) throws NamingException { + String rmiName) throws NamingException { return new Reference(className, new StringRefAddr("URL", rmiName)); } @@ -410,7 +410,7 @@ private static Reference decodeReference(Attributes attrs, int start, sep, posn; Base64.Decoder decoder = null; - ClassLoader cl = helper.getURLClassLoader(codebases); + ClassLoader cl = Thread.currentThread().getContextClassLoader(); /* * Temporary array for decoded RefAddr addresses - used to ensure diff --git a/src/java.naming/share/classes/com/sun/jndi/ldap/VersionHelper.java b/src/java.naming/share/classes/com/sun/jndi/ldap/VersionHelper.java index 53a20b99594..bb888a1457a 100644 --- a/src/java.naming/share/classes/com/sun/jndi/ldap/VersionHelper.java +++ b/src/java.naming/share/classes/com/sun/jndi/ldap/VersionHelper.java @@ -25,22 +25,10 @@ package com.sun.jndi.ldap; -import java.net.MalformedURLException; -import java.net.URL; -import java.net.URLClassLoader; -import java.security.AccessControlContext; -import java.security.AccessController; -import java.security.PrivilegedAction; - public final class VersionHelper { private static final VersionHelper helper = new VersionHelper(); - /** - * Determines whether classes may be loaded from an arbitrary URL code base. - */ - private static final boolean trustURLCodebase; - /** * Determines whether objects may be deserialized or reconstructed from a content of * 'javaSerializedData', 'javaRemoteLocation' or 'javaReferenceAddress' LDAP attributes. @@ -48,29 +36,13 @@ public final class VersionHelper { private static final boolean trustSerialData; static { - // System property to control whether classes may be loaded from an - // arbitrary URL code base - String trust = getPrivilegedProperty( - "com.sun.jndi.ldap.object.trustURLCodebase", "false"); - trustURLCodebase = "true".equalsIgnoreCase(trust); - // System property to control whether classes are allowed to be loaded from // 'javaSerializedData', 'javaRemoteLocation' or 'javaReferenceAddress' attributes. - String trustSerialDataSp = getPrivilegedProperty( + String trustSerialDataSp = System.getProperty( "com.sun.jndi.ldap.object.trustSerialData", "false"); trustSerialData = "true".equalsIgnoreCase(trustSerialDataSp); } - @SuppressWarnings("removal") - private static String getPrivilegedProperty(String propertyName, String defaultVal) { - PrivilegedAction<String> action = () -> System.getProperty(propertyName, defaultVal); - if (System.getSecurityManager() == null) { - return action.run(); - } else { - return AccessController.doPrivileged(action); - } - } - private VersionHelper() { } @@ -89,41 +61,12 @@ public static boolean isSerialDataAllowed() { return trustSerialData; } - ClassLoader getURLClassLoader(String[] url) throws MalformedURLException { - ClassLoader parent = getContextClassLoader(); - /* - * Classes may only be loaded from an arbitrary URL code base when - * the system property com.sun.jndi.ldap.object.trustURLCodebase - * has been set to "true". - */ - if (url != null && trustURLCodebase) { - return URLClassLoader.newInstance(getUrlArray(url), parent); - } else { - return parent; - } - } - Class<?> loadClass(String className) throws ClassNotFoundException { - return Class.forName(className, true, getContextClassLoader()); + return Class.forName(className, true, + Thread.currentThread().getContextClassLoader()); } Thread createThread(Runnable r) { return new Thread(r); } - - @SuppressWarnings("removal") - private ClassLoader getContextClassLoader() { - PrivilegedAction<ClassLoader> act = - Thread.currentThread()::getContextClassLoader; - return AccessController.doPrivileged(act); - } - - @SuppressWarnings("deprecation") - private static URL[] getUrlArray(String[] url) throws MalformedURLException { - URL[] urlArray = new URL[url.length]; - for (int i = 0; i < urlArray.length; i++) { - urlArray[i] = new URL(url[i]); - } - return urlArray; - } } diff --git a/src/java.naming/share/classes/com/sun/naming/internal/NamingManagerHelper.java b/src/java.naming/share/classes/com/sun/naming/internal/NamingManagerHelper.java index 5270c4c916e..856a1b0a444 100644 --- a/src/java.naming/share/classes/com/sun/naming/internal/NamingManagerHelper.java +++ b/src/java.naming/share/classes/com/sun/naming/internal/NamingManagerHelper.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -181,9 +181,8 @@ public static Object getDirObjectInstance(Object refInfo, Name name, Context nam static ObjectFactory getObjectFactoryFromReference( Reference ref, String factoryName, Predicate<Class<?>> filter) throws IllegalAccessException, - InstantiationException, - MalformedURLException { - Class<?> clas = null; + InstantiationException { + Class<?> clas; // Try to use current class loader try { @@ -193,27 +192,11 @@ static ObjectFactory getObjectFactoryFromReference( return null; } } catch (ClassNotFoundException e) { - // ignore and continue - // e.printStackTrace(); - } - // All other exceptions are passed up. - - // Not in class path; try to use codebase - String codebase; - if (clas == null && - (codebase = ref.getFactoryClassLocation()) != null) { - try { - clas = helper.loadClass(factoryName, codebase); - // Validate factory's class with the objects factory serial filter - if (clas == null || !filter.test(clas)) { - return null; - } - } catch (ClassNotFoundException e) { - } + return null; } - + assert clas != null; @SuppressWarnings("deprecation") // Class.newInstance - ObjectFactory result = (clas != null) ? (ObjectFactory) clas.newInstance() : null; + ObjectFactory result = (ObjectFactory) clas.newInstance(); return result; } @@ -401,12 +384,6 @@ public static synchronized void setObjectFactoryBuilder( ObjectFactoryBuilder builder) throws NamingException { if (object_factory_builder != null) throw new IllegalStateException("ObjectFactoryBuilder already set"); - - @SuppressWarnings("removal") - SecurityManager security = System.getSecurityManager(); - if (security != null) { - security.checkSetFactory(); - } object_factory_builder = builder; } diff --git a/src/java.naming/share/classes/com/sun/naming/internal/VersionHelper.java b/src/java.naming/share/classes/com/sun/naming/internal/VersionHelper.java index 6dbdb6f420b..ea2a0f9c179 100644 --- a/src/java.naming/share/classes/com/sun/naming/internal/VersionHelper.java +++ b/src/java.naming/share/classes/com/sun/naming/internal/VersionHelper.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -28,15 +28,9 @@ import javax.naming.NamingEnumeration; import java.io.IOException; import java.io.InputStream; -import java.net.MalformedURLException; import java.net.URL; -import java.net.URLClassLoader; import java.nio.file.Files; import java.nio.file.Path; -import java.security.AccessController; -import java.security.PrivilegedAction; -import java.security.PrivilegedActionException; -import java.security.PrivilegedExceptionAction; import java.util.*; /** @@ -53,21 +47,6 @@ public final class VersionHelper { private static final VersionHelper helper = new VersionHelper(); - /** - * Determines whether classes may be loaded from an arbitrary URL code base. - */ - private static final boolean TRUST_URL_CODE_BASE; - - static { - // System property to control whether classes may be loaded from an - // arbitrary URL code base - PrivilegedAction<String> act - = () -> System.getProperty("com.sun.jndi.ldap.object.trustURLCodebase", "false"); - @SuppressWarnings("removal") - String trust = AccessController.doPrivileged(act); - TRUST_URL_CODE_BASE = "true".equalsIgnoreCase(trust); - } - static final String[] PROPS = new String[]{ javax.naming.Context.INITIAL_CONTEXT_FACTORY, javax.naming.Context.OBJECT_FACTORIES, @@ -101,22 +80,6 @@ public Class<?> loadClassWithoutInit(String className) throws ClassNotFoundExcep return loadClass(className, false, getContextClassLoader()); } - /** - * @param className A non-null fully qualified class name. - * @param codebase A non-null, space-separated list of URL strings. - */ - public Class<?> loadClass(String className, String codebase) - throws ClassNotFoundException, MalformedURLException { - if (TRUST_URL_CODE_BASE) { - ClassLoader parent = getContextClassLoader(); - ClassLoader cl - = URLClassLoader.newInstance(getUrlArray(codebase), parent); - return loadClass(className, cl); - } else { - return null; - } - } - /** * Package private. * <p> @@ -136,37 +99,19 @@ Class<?> loadClass(String className, ClassLoader cl) /* * Returns a JNDI property from the system properties. Returns - * null if the property is not set, or if there is no permission - * to read it. + * null if the property is not set. */ - @SuppressWarnings("removal") String getJndiProperty(int i) { - PrivilegedAction<String> act = () -> { - try { - return System.getProperty(PROPS[i]); - } catch (SecurityException e) { - return null; - } - }; - return AccessController.doPrivileged(act); + return System.getProperty(PROPS[i]); } /* * Reads each property in PROPS from the system properties, and * returns their values -- in order -- in an array. For each * unset property, the corresponding array element is set to null. - * Returns null if there is no permission to call System.getProperties(). */ String[] getJndiProperties() { - PrivilegedAction<Properties> act = () -> { - try { - return System.getProperties(); - } catch (SecurityException e) { - return null; - } - }; - @SuppressWarnings("removal") - Properties sysProps = AccessController.doPrivileged(act); + Properties sysProps = System.getProperties(); if (sysProps == null) { return null; } @@ -199,16 +144,12 @@ private static String resolveName(Class<?> c, String name) { * Returns the resource of a given name associated with a particular * class (never null), or null if none can be found. */ - @SuppressWarnings("removal") InputStream getResourceAsStream(Class<?> c, String name) { - PrivilegedAction<InputStream> act = () -> { - try { - return c.getModule().getResourceAsStream(resolveName(c, name)); - } catch (IOException x) { - return null; - } - }; - return AccessController.doPrivileged(act); + try { + return c.getModule().getResourceAsStream(resolveName(c, name)); + } catch (IOException x) { + return null; + } } /* @@ -217,20 +158,16 @@ InputStream getResourceAsStream(Class<?> c, String name) { * * @param filename The file name, sans directory. */ - @SuppressWarnings("removal") InputStream getJavaHomeConfStream(String filename) { - PrivilegedAction<InputStream> act = () -> { - try { - String javahome = System.getProperty("java.home"); - if (javahome == null) { - return null; - } - return Files.newInputStream(Path.of(javahome, "conf", filename)); - } catch (Exception e) { + try { + String javahome = System.getProperty("java.home"); + if (javahome == null) { return null; } - }; - return AccessController.doPrivileged(act); + return Files.newInputStream(Path.of(javahome, "conf", filename)); + } catch (Exception e) { + return null; + } } /* @@ -239,19 +176,12 @@ InputStream getJavaHomeConfStream(String filename) { * loader. Null represents the bootstrap class loader in some * Java implementations. */ - @SuppressWarnings("removal") NamingEnumeration<InputStream> getResources(ClassLoader cl, String name) throws IOException { Enumeration<URL> urls; - PrivilegedExceptionAction<Enumeration<URL>> act = () -> - (cl == null) - ? ClassLoader.getSystemResources(name) - : cl.getResources(name); - try { - urls = AccessController.doPrivileged(act); - } catch (PrivilegedActionException e) { - throw (IOException) e.getException(); - } + urls = (cl == null) + ? ClassLoader.getSystemResources(name) + : cl.getResources(name); return new InputStreamEnumeration(urls); } @@ -265,39 +195,18 @@ NamingEnumeration<InputStream> getResources(ClassLoader cl, * Please don't expose this method as public. * @throws SecurityException if the class loader is not accessible */ - @SuppressWarnings("removal") ClassLoader getContextClassLoader() { - - PrivilegedAction<ClassLoader> act = () -> { - ClassLoader loader = Thread.currentThread().getContextClassLoader(); - if (loader == null) { - // Don't use bootstrap class loader directly! - loader = ClassLoader.getSystemClassLoader(); - } - return loader; - }; - return AccessController.doPrivileged(act); - } - - private static URL[] getUrlArray(String codebase) - throws MalformedURLException { - // Parse codebase into separate URLs - StringTokenizer parser = new StringTokenizer(codebase); - List<URL> list = new ArrayList<>(); - while (parser.hasMoreTokens()) { - @SuppressWarnings("deprecation") - var u = new URL(parser.nextToken()); - list.add(u); + ClassLoader loader = Thread.currentThread().getContextClassLoader(); + if (loader == null) { + // Don't use bootstrap class loader directly! + loader = ClassLoader.getSystemClassLoader(); } - return list.toArray(new URL[0]); + return loader; } /** * Given an enumeration of URLs, an instance of this class represents - * an enumeration of their InputStreams. Each operation on the URL - * enumeration is performed within a doPrivileged block. - * This is used to enumerate the resources under a foreign codebase. - * This class is not MT-safe. + * an enumeration of their InputStreams. */ private class InputStreamEnumeration implements NamingEnumeration<InputStream> { @@ -314,19 +223,15 @@ private class InputStreamEnumeration implements * Returns the next InputStream, or null if there are no more. * An InputStream that cannot be opened is skipped. */ - @SuppressWarnings("removal") private InputStream getNextElement() { - PrivilegedAction<InputStream> act = () -> { - while (urls.hasMoreElements()) { - try { - return urls.nextElement().openStream(); - } catch (IOException e) { - // skip this URL - } + while (urls.hasMoreElements()) { + try { + return urls.nextElement().openStream(); + } catch (IOException e) { + // skip this URL } - return null; - }; - return AccessController.doPrivileged(act); + } + return null; } public boolean hasMore() { diff --git a/src/java.naming/share/classes/javax/naming/spi/NamingManager.java b/src/java.naming/share/classes/javax/naming/spi/NamingManager.java index c54080ba585..4d57b541ec1 100644 --- a/src/java.naming/share/classes/javax/naming/spi/NamingManager.java +++ b/src/java.naming/share/classes/javax/naming/spi/NamingManager.java @@ -123,9 +123,12 @@ static ObjectFactoryBuilder getObjectFactoryBuilder() { * or {@code Referenceable} containing a factory class name, * use the named factory to create the object. * Return {@code refInfo} if the factory cannot be created. - * Under JDK 1.1, if the factory class must be loaded from a location - * specified in the reference, a {@code SecurityManager} must have - * been installed or the factory creation will fail. + * Downloading a factory class from a location specified in the reference + * can be supported by a custom implementation of {@link ObjectFactoryBuilder}. + * The {@linkplain Reference#getFactoryClassLocation() factory class + * location}, if present, is ignored. A custom {@link ObjectFactoryBuilder} + * {@linkplain #setObjectFactoryBuilder(ObjectFactoryBuilder) may be used} + * if a different policy is desired. * If an exception is encountered while creating the factory, * it is passed up to the caller. * <li>If {@code refInfo} is a {@code Reference} or diff --git a/src/jdk.naming.rmi/share/classes/com/sun/jndi/rmi/registry/RegistryContext.java b/src/jdk.naming.rmi/share/classes/com/sun/jndi/rmi/registry/RegistryContext.java index 3ca0039604e..5becceb8294 100644 --- a/src/jdk.naming.rmi/share/classes/com/sun/jndi/rmi/registry/RegistryContext.java +++ b/src/jdk.naming.rmi/share/classes/com/sun/jndi/rmi/registry/RegistryContext.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -35,8 +35,6 @@ import java.rmi.server.*; import java.rmi.registry.Registry; import java.rmi.registry.LocateRegistry; -import java.security.AccessController; -import java.security.PrivilegedAction; import javax.naming.*; import javax.naming.spi.NamingManager; @@ -57,19 +55,6 @@ public class RegistryContext implements Context, Referenceable { private int port; private static final NameParser nameParser = new AtomicNameParser(); private static final String SOCKET_FACTORY = "com.sun.jndi.rmi.factory.socket"; - /** - * Determines whether classes may be loaded from an arbitrary URL code base. - */ - static final boolean trustURLCodebase; - static { - // System property to control whether classes may be loaded from an - // arbitrary URL codebase - PrivilegedAction<String> act = () -> System.getProperty( - "com.sun.jndi.rmi.object.trustURLCodebase", "false"); - @SuppressWarnings("removal") - String trust = AccessController.doPrivileged(act); - trustURLCodebase = "true".equalsIgnoreCase(trust); - } Reference reference = null; // ref used to create this context, if any @@ -481,12 +466,6 @@ private Object decodeObject(Remote r, Name name) throws NamingException { ? ((RemoteReference)r).getReference() : (Object)r; - /* - * Classes may only be loaded from an arbitrary URL codebase when - * the system property com.sun.jndi.rmi.object.trustURLCodebase - * has been set to "true". - */ - // Use reference if possible Reference ref = null; if (obj instanceof Reference) { @@ -495,11 +474,14 @@ private Object decodeObject(Remote r, Name name) throws NamingException { ref = ((Referenceable)(obj)).getReference(); } - if (ref != null && ref.getFactoryClassLocation() != null && - !trustURLCodebase) { + /* + * Downloading a factory class from a location specified in the reference + * can be supported by a custom implementation of "ObjectFactoryBuilder". + */ + if (NamingManagerHelper.getObjectFactoryBuilder() == null + && ref != null && ref.getFactoryClassLocation() != null) { throw new ConfigurationException( - "The object factory is untrusted. Set the system property" + - " 'com.sun.jndi.rmi.object.trustURLCodebase' to 'true'."); + "Remote object factories are not supported"); } return NamingManagerHelper.getObjectInstance(obj, name, this, environment, ObjectFactoriesFilter::checkRmiFilter); diff --git a/src/jdk.naming.rmi/share/classes/module-info.java b/src/jdk.naming.rmi/share/classes/module-info.java index 6afa13aa84d..f2ba8f7775f 100644 --- a/src/jdk.naming.rmi/share/classes/module-info.java +++ b/src/jdk.naming.rmi/share/classes/module-info.java @@ -58,6 +58,11 @@ * implementation. * </li> * </ul> + * <p> Downloading a factory class from a {@linkplain javax.naming.Reference#getFactoryClassLocation() + * location} specified in the reference can be supported by a custom implementation of {@link + * javax.naming.spi.ObjectFactoryBuilder}. If a location is specified, then + * unless an {@link javax.naming.spi.ObjectFactoryBuilder} is installed a + * {@link javax.naming.ConfigurationException} is thrown. * @provides javax.naming.spi.InitialContextFactory * @moduleGraph * @since 9 diff --git a/test/jdk/com/sun/jndi/rmi/registry/objects/ObjectFactoryBuilderCodebaseTest.java b/test/jdk/com/sun/jndi/rmi/registry/objects/ObjectFactoryBuilderCodebaseTest.java new file mode 100644 index 00000000000..3f7fe91ee9f --- /dev/null +++ b/test/jdk/com/sun/jndi/rmi/registry/objects/ObjectFactoryBuilderCodebaseTest.java @@ -0,0 +1,223 @@ +/* + * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import com.sun.net.httpserver.HttpServer; +import com.sun.net.httpserver.SimpleFileServer; + +import javax.naming.Context; +import javax.naming.InitialContext; +import javax.naming.NamingException; +import javax.naming.Reference; +import javax.naming.spi.NamingManager; +import java.io.IOException; +import java.net.InetAddress; +import java.net.InetSocketAddress; +import java.net.ServerSocket; +import java.net.Socket; +import java.net.SocketAddress; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.rmi.RemoteException; +import java.rmi.registry.Registry; +import java.rmi.server.RMISocketFactory; +import java.util.Hashtable; +import java.util.Objects; + +import jdk.test.lib.net.URIBuilder; + + +/* + * @test + * @bug 8338536 + * @summary Check if an object factory builder can be used to reconstruct + * object factories from a code base specified in a + * @modules java.rmi/sun.rmi.registry + * java.rmi/sun.rmi.server + * java.rmi/sun.rmi.transport + * java.rmi/sun.rmi.transport.tcp + * @library /test/lib ../../../../../../java/rmi/testlibrary + * @build TestLibrary + * @compile TestFactory.java TestObjectFactoryBuilder.java + * + * @run main/othervm ObjectFactoryBuilderCodebaseTest setObjectFactoryBuilder + * @run main/othervm ObjectFactoryBuilderCodebaseTest default + */ +public class ObjectFactoryBuilderCodebaseTest { + + public static void main(String[] args) throws Exception { + setupRmiHostNameAndRmiSocketFactory(); + boolean useCustomObjectFactoryBuilder = + "setObjectFactoryBuilder".equals(args[0]); + + if (args.length > 0 && useCustomObjectFactoryBuilder) { + NamingManager.setObjectFactoryBuilder(new TestObjectFactoryBuilder()); + } + FileServer fileServer = configureAndLaunchFileServer(); + int registryPort; + try { + Registry registry = TestLibrary.createRegistryOnEphemeralPort(); + registryPort = TestLibrary.getRegistryPort(registry); + System.out.println("Registry port: " + registryPort); + } catch (RemoteException re) { + throw new RuntimeException("Failed to create registry", re); + } + + Context context = getInitialContext(registryPort); + // Bind the Reference object + String factoryURL = fileServer.factoryLocation(); + System.err.println("Setting Reference factory location: " + factoryURL); + Reference ref = new Reference("TestObject", "com.test.TestFactory", + factoryURL); + context.bind("objectTest", ref); + + // Try to load bound reference + try { + Object object = context.lookup("objectTest"); + if (!useCustomObjectFactoryBuilder) { + throw new RuntimeException("Lookup not expected to complete"); + } + System.err.println("Loaded object: " + object); + } catch (NamingException ne) { + if (useCustomObjectFactoryBuilder) { + throw new RuntimeException("Lookup expected to complete successfully", ne); + } + } + } + + private static Context getInitialContext(int port) throws NamingException { + Hashtable<String, String> env = new Hashtable<>(); + + // Prepare registry URL + String providerURL = URIBuilder.newBuilder() + .loopback() + .port(port) + .scheme("rmi") + .buildUnchecked().toString(); + + env.put(Context.INITIAL_CONTEXT_FACTORY, + "com.sun.jndi.rmi.registry.RegistryContextFactory"); + env.put(Context.PROVIDER_URL, providerURL); + return new InitialContext(env); + } + + private record FileServer(Path rootPath, InetSocketAddress address, HttpServer httpServer) { + + public static FileServer newInstance(Path rootPath, InetSocketAddress address) { + Objects.requireNonNull(address); + Objects.requireNonNull(rootPath); + var httpServer = SimpleFileServer.createFileServer(address, rootPath, + SimpleFileServer.OutputLevel.VERBOSE); + return new FileServer(rootPath, address, httpServer); + } + + String factoryLocation() { + return URIBuilder.newBuilder() + .loopback() + .port(port()) + .scheme("http") + .path("/") + .buildUnchecked() + .toString(); + } + + int port() { + return httpServer.getAddress().getPort(); + } + + void start() { + httpServer.start(); + } + } + + // Prepares and launches the file server capable of serving TestFactory.class + private static FileServer configureAndLaunchFileServer() throws IOException { + + // Location of compiled classes with compiled MyFactory + Path factoryClassPath = Path.of(System.getProperty("test.classes", ".")) + .resolve(OBJ_FACTORY_PACKAGE_PATH) + .resolve(OBJ_FACTORY_CLASS_NAME); + + // File server content root directory + Path serverRoot = Paths.get("serverRoot").toAbsolutePath(); + Path packageDirInServerRoot = serverRoot.resolve(OBJ_FACTORY_PACKAGE_PATH); + Path factoryClassFileInServerRoot = packageDirInServerRoot.resolve(OBJ_FACTORY_CLASS_NAME); + + // Remove files from previous run + Files.deleteIfExists(factoryClassFileInServerRoot); + Files.deleteIfExists(packageDirInServerRoot); + Files.deleteIfExists(packageDirInServerRoot.getParent()); + Files.deleteIfExists(serverRoot); + + // Create server root and copy compiled object factory inside + Files.createDirectories(packageDirInServerRoot); + Files.copy(factoryClassPath, factoryClassFileInServerRoot); + + // Bind file server to loopback address + InetSocketAddress serverAddress = + new InetSocketAddress(InetAddress.getLoopbackAddress(), 0); + FileServer fileServer = FileServer.newInstance(serverRoot, serverAddress); + + // Start the file server + fileServer.start(); + System.err.println("File server content root: " + serverRoot); + System.err.printf("File server running on %s:%d%n", + serverAddress.getAddress(), fileServer.port()); + return fileServer; + } + + + // Configure RMI to launch registry on a loopback address + private static void setupRmiHostNameAndRmiSocketFactory() throws IOException { + String rmiServerHostAddressString = InetAddress.getLoopbackAddress().getHostAddress(); + System.out.println("Setting 'java.rmi.server.hostname' to: " + rmiServerHostAddressString); + System.setProperty("java.rmi.server.hostname", rmiServerHostAddressString); + RMISocketFactory.setSocketFactory(new TestRmiSocketFactory()); + } + + private static class TestRmiSocketFactory extends RMISocketFactory { + public ServerSocket createServerSocket(int port) throws IOException { + var loopbackAddress = InetAddress.getLoopbackAddress(); + System.out.printf("Creating RMI server socket on %s:%d%n", loopbackAddress, port); + ServerSocket rmiServerSocket = new ServerSocket(); + rmiServerSocket.setOption(java.net.StandardSocketOptions.SO_REUSEADDR, false); + SocketAddress serverAddress = new InetSocketAddress(loopbackAddress, port); + rmiServerSocket.bind(serverAddress, BACKLOG_OF_5); + return rmiServerSocket; + } + + public Socket createSocket(String host, int port) throws IOException { + System.out.printf("Creating RMI client socket connected to %s:%d%n", host, port); + // just call the default client socket factory + return RMISocketFactory.getDefaultSocketFactory() + .createSocket(host, port); + } + } + + // File server backlog value + private static final int BACKLOG_OF_5 = 5; + // Test objects factory class filename + private static final String OBJ_FACTORY_CLASS_NAME = "TestFactory.class"; + // Package directory of the test's objects factory class + private static final Path OBJ_FACTORY_PACKAGE_PATH = Paths.get("com").resolve("test"); +} diff --git a/test/jdk/com/sun/jndi/rmi/registry/objects/TestObjectFactoryBuilder.java b/test/jdk/com/sun/jndi/rmi/registry/objects/TestObjectFactoryBuilder.java new file mode 100644 index 00000000000..60641e70d22 --- /dev/null +++ b/test/jdk/com/sun/jndi/rmi/registry/objects/TestObjectFactoryBuilder.java @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import javax.naming.ConfigurationException; +import javax.naming.NamingException; +import javax.naming.Reference; +import javax.naming.spi.ObjectFactory; +import javax.naming.spi.ObjectFactoryBuilder; +import java.lang.reflect.InvocationTargetException; +import java.net.MalformedURLException; +import java.net.URL; +import java.net.URLClassLoader; +import java.util.Hashtable; + +/** + * Test library class that implements {@code javax.naming.spi.ObjectFactoryBuilder} interface. + * Its implementation allows object factory class loading from any remote location. + */ +public class TestObjectFactoryBuilder implements ObjectFactoryBuilder { + + @Override + public ObjectFactory createObjectFactory(Object obj, Hashtable<?, ?> environment) throws NamingException { + System.err.println("TestObjectFactoryBuilder: Creating new object factory"); + System.err.println("Builder for object: " + obj); + System.err.println("And for environment: " + environment); + // Only objects of the Reference type are supported, others are rejected + if (obj instanceof Reference ref) { + String objectFactoryLocation = ref.getFactoryClassLocation(); + try { + URL factoryURL = new URL(objectFactoryLocation); + var cl = new URLClassLoader(new URL[]{factoryURL}); + Class<?> factoryClass = cl.loadClass(ref.getFactoryClassName()); + System.err.println("Loaded object factory: " + factoryClass); + if (ObjectFactory.class.isAssignableFrom(factoryClass)) { + return (ObjectFactory) factoryClass + .getDeclaredConstructor().newInstance(); + } else { + throw new ConfigurationException("Test configuration error -" + + " loaded object factory of wrong type"); + } + } catch (MalformedURLException e) { + throw new ConfigurationException("Error constructing test object factory"); + } catch (ClassNotFoundException | NoSuchMethodException | InstantiationException | + IllegalAccessException | InvocationTargetException e) { + throw new ConfigurationException("Test configuration error: " + + "factory class cannot be loaded from the provided " + + "object factory location"); + } + } else { + throw new ConfigurationException("Test factory builder " + + "supports only Reference types"); + } + } +} From 22149063101f0c617d8ccaace659671a645d402e Mon Sep 17 00:00:00 2001 From: Stuart Marks <smarks@openjdk.org> Date: Thu, 21 Nov 2024 21:05:50 +0000 Subject: [PATCH 170/311] 8272339: Update notes section from serialver man page Reviewed-by: rriggs --- src/jdk.compiler/share/man/serialver.md | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) diff --git a/src/jdk.compiler/share/man/serialver.md b/src/jdk.compiler/share/man/serialver.md index 5838f1c61a9..2198c9736cf 100644 --- a/src/jdk.compiler/share/man/serialver.md +++ b/src/jdk.compiler/share/man/serialver.md @@ -1,5 +1,5 @@ --- -# Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. # # This code is free software; you can redistribute it and/or modify it @@ -60,15 +60,8 @@ arguments, the `serialver` command prints a usage line. application launcher. For example, `-J-Xms48m` sets the startup memory to 48 MB. -## Notes +## Warning -The `serialver` command loads and initializes the specified classes in its -virtual machine, and by default, it doesn't set a security manager. If the -`serialver` command is to be run with untrusted classes, then a security -manager can be set with the following option: - -> `-J-Djava.security.manager` - -When necessary, a security policy can be specified with the following option: - -> `-J-Djava.security.policy=`*policy\_file* +The `serialver` command loads and initializes the specified classes in +order to determine their `serialVersionUID` values. *DO NOT RUN* `serialver` +on untrusted classes. From efeacfee015d1105dcd75e489d367a7716441fa8 Mon Sep 17 00:00:00 2001 From: David Holmes <dholmes@openjdk.org> Date: Thu, 21 Nov 2024 21:18:18 +0000 Subject: [PATCH 171/311] 8344646: The libjsig deprecation warning should go to stderr not stdout Reviewed-by: mikael, cjplummer --- src/java.base/unix/native/libjsig/jsig.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/java.base/unix/native/libjsig/jsig.c b/src/java.base/unix/native/libjsig/jsig.c index 180dd583393..ebb4d698946 100644 --- a/src/java.base/unix/native/libjsig/jsig.c +++ b/src/java.base/unix/native/libjsig/jsig.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2012, 2015 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -95,9 +95,9 @@ static sa_handler_t call_os_signal(int sig, sa_handler_t disp, if (os_signal == NULL) { // Deprecation warning first time through - printf(HOTSPOT_VM_DISTRO " VM warning: the use of signal() and sigset() " - "for signal chaining was deprecated in version 16.0 and will " - "be removed in a future release. Use sigaction() instead.\n"); + fprintf(stderr, HOTSPOT_VM_DISTRO " VM warning: the use of signal() and sigset() " + "for signal chaining was deprecated in version 16.0 and will " + "be removed in a future release. Use sigaction() instead.\n"); if (!is_sigset) { os_signal = (signal_function_t)dlsym(RTLD_NEXT, "signal"); } else { From 0f458e2c3eb93641864085d18e49daf640cb3858 Mon Sep 17 00:00:00 2001 From: Phil Race <prr@openjdk.org> Date: Thu, 21 Nov 2024 21:24:46 +0000 Subject: [PATCH 172/311] 8342903: Deprecate for removal java.awt.Window.getWarningString() Reviewed-by: kizune, erikj, azvegint --- make/modules/java.desktop/Java.gmk | 12 - .../java.desktop/gensrc/GensrcIcons.gmk | 17 - src/demo/share/jfc/Font2DTest/FontPanel.java | 8 +- .../sun/lwawt/LWKeyboardFocusManagerPeer.java | 7 - .../macosx/classes/sun/lwawt/LWToolkit.java | 3 - .../classes/sun/lwawt/LWWindowPeer.java | 68 -- .../sun/lwawt/SecurityWarningWindow.java | 35 - .../classes/sun/lwawt/macosx/CFileDialog.java | 4 - .../sun/lwawt/macosx/CPlatformWindow.java | 2 +- .../sun/lwawt/macosx/CWarningWindow.java | 475 ------------- .../classes/sun/lwawt/macosx/LWCToolkit.java | 7 - .../share/classes/java/awt/Desktop.java | 23 - .../share/classes/java/awt/Window.java | 94 +-- .../classes/java/awt/peer/WindowPeer.java | 5 - .../classes/javax/swing/JInternalFrame.java | 8 +- .../share/classes/sun/awt/AWTAccessor.java | 11 - .../share/classes/sun/awt/AWTPermissions.java | 3 - .../share/classes/sun/awt/EmbeddedFrame.java | 3 - .../sun/awt/resources/security-icon-bw16.png | Bin 463 -> 0 bytes .../sun/awt/resources/security-icon-bw24.png | Bin 682 -> 0 bytes .../sun/awt/resources/security-icon-bw32.png | Bin 795 -> 0 bytes .../sun/awt/resources/security-icon-bw48.png | Bin 1137 -> 0 bytes .../awt/resources/security-icon-interim16.png | Bin 489 -> 0 bytes .../awt/resources/security-icon-interim24.png | Bin 741 -> 0 bytes .../awt/resources/security-icon-interim32.png | Bin 871 -> 0 bytes .../awt/resources/security-icon-interim48.png | Bin 1387 -> 0 bytes .../awt/resources/security-icon-yellow16.png | Bin 477 -> 0 bytes .../awt/resources/security-icon-yellow24.png | Bin 749 -> 0 bytes .../awt/resources/security-icon-yellow32.png | Bin 866 -> 0 bytes .../awt/resources/security-icon-yellow48.png | Bin 1323 -> 0 bytes .../unix/classes/sun/awt/X11/XBaseWindow.java | 7 - .../classes/sun/awt/X11/XDecoratedPeer.java | 4 - .../classes/sun/awt/X11/XEmbedHelper.java | 1 - .../awt/X11/XKeyboardFocusManagerPeer.java | 7 - .../classes/sun/awt/X11/XScrollPanePeer.java | 1 - .../unix/classes/sun/awt/X11/XToolkit.java | 12 - .../classes/sun/awt/X11/XWarningWindow.java | 416 ------------ .../unix/classes/sun/awt/X11/XWindow.java | 4 +- .../unix/classes/sun/awt/X11/XWindowPeer.java | 82 --- .../classes/sun/awt/windows/WWindowPeer.java | 7 - .../windows/native/libawt/windows/awt.rc | 7 - .../native/libawt/windows/awt_Component.cpp | 3 - .../native/libawt/windows/awt_Frame.cpp | 3 - .../native/libawt/windows/awt_Toolkit.cpp | 60 -- .../native/libawt/windows/awt_Toolkit.h | 2 - .../native/libawt/windows/awt_Window.cpp | 635 +----------------- .../native/libawt/windows/awt_Window.h | 57 -- .../libawt/windows/security_warning.ico | Bin 17542 -> 0 bytes .../libawt/windows/security_warning_bw.ico | Bin 17542 -> 0 bytes .../libawt/windows/security_warning_int.ico | Bin 17542 -> 0 bytes test/jdk/ProblemList.txt | 1 - 51 files changed, 16 insertions(+), 2078 deletions(-) delete mode 100644 src/java.desktop/macosx/classes/sun/lwawt/SecurityWarningWindow.java delete mode 100644 src/java.desktop/macosx/classes/sun/lwawt/macosx/CWarningWindow.java delete mode 100644 src/java.desktop/share/classes/sun/awt/resources/security-icon-bw16.png delete mode 100644 src/java.desktop/share/classes/sun/awt/resources/security-icon-bw24.png delete mode 100644 src/java.desktop/share/classes/sun/awt/resources/security-icon-bw32.png delete mode 100644 src/java.desktop/share/classes/sun/awt/resources/security-icon-bw48.png delete mode 100644 src/java.desktop/share/classes/sun/awt/resources/security-icon-interim16.png delete mode 100644 src/java.desktop/share/classes/sun/awt/resources/security-icon-interim24.png delete mode 100644 src/java.desktop/share/classes/sun/awt/resources/security-icon-interim32.png delete mode 100644 src/java.desktop/share/classes/sun/awt/resources/security-icon-interim48.png delete mode 100644 src/java.desktop/share/classes/sun/awt/resources/security-icon-yellow16.png delete mode 100644 src/java.desktop/share/classes/sun/awt/resources/security-icon-yellow24.png delete mode 100644 src/java.desktop/share/classes/sun/awt/resources/security-icon-yellow32.png delete mode 100644 src/java.desktop/share/classes/sun/awt/resources/security-icon-yellow48.png delete mode 100644 src/java.desktop/unix/classes/sun/awt/X11/XWarningWindow.java delete mode 100644 src/java.desktop/windows/native/libawt/windows/security_warning.ico delete mode 100644 src/java.desktop/windows/native/libawt/windows/security_warning_bw.ico delete mode 100644 src/java.desktop/windows/native/libawt/windows/security_warning_int.ico diff --git a/make/modules/java.desktop/Java.gmk b/make/modules/java.desktop/Java.gmk index 7cc9cf47034..a13b4b1ba35 100644 --- a/make/modules/java.desktop/Java.gmk +++ b/make/modules/java.desktop/Java.gmk @@ -46,18 +46,6 @@ EXCLUDE_FILES += \ javax/swing/plaf/nimbus/SpinnerPainter.java \ javax/swing/plaf/nimbus/SplitPanePainter.java \ javax/swing/plaf/nimbus/TabbedPanePainter.java \ - sun/awt/resources/security-icon-bw16.png \ - sun/awt/resources/security-icon-bw24.png \ - sun/awt/resources/security-icon-bw32.png \ - sun/awt/resources/security-icon-bw48.png \ - sun/awt/resources/security-icon-interim16.png \ - sun/awt/resources/security-icon-interim24.png \ - sun/awt/resources/security-icon-interim32.png \ - sun/awt/resources/security-icon-interim48.png \ - sun/awt/resources/security-icon-yellow16.png \ - sun/awt/resources/security-icon-yellow24.png \ - sun/awt/resources/security-icon-yellow32.png \ - sun/awt/resources/security-icon-yellow48.png \ sun/awt/X11/java-icon16.png \ sun/awt/X11/java-icon24.png \ sun/awt/X11/java-icon32.png \ diff --git a/make/modules/java.desktop/gensrc/GensrcIcons.gmk b/make/modules/java.desktop/gensrc/GensrcIcons.gmk index 28434d3f4c1..dc1c1794e63 100644 --- a/make/modules/java.desktop/gensrc/GensrcIcons.gmk +++ b/make/modules/java.desktop/gensrc/GensrcIcons.gmk @@ -37,23 +37,6 @@ GENSRC_AWT_ICONS_SRC += \ $(X11_ICONS_PATH_PREFIX)/classes/sun/awt/X11/java-icon32.png \ $(X11_ICONS_PATH_PREFIX)/classes/sun/awt/X11/java-icon48.png - -AWT_ICONPATH := $(MODULE_SRC)/share/classes/sun/awt/resources - -GENSRC_AWT_ICONS_SRC += \ - $(AWT_ICONPATH)/security-icon-bw16.png \ - $(AWT_ICONPATH)/security-icon-interim16.png \ - $(AWT_ICONPATH)/security-icon-yellow16.png \ - $(AWT_ICONPATH)/security-icon-bw24.png \ - $(AWT_ICONPATH)/security-icon-interim24.png \ - $(AWT_ICONPATH)/security-icon-yellow24.png \ - $(AWT_ICONPATH)/security-icon-bw32.png \ - $(AWT_ICONPATH)/security-icon-interim32.png \ - $(AWT_ICONPATH)/security-icon-yellow32.png \ - $(AWT_ICONPATH)/security-icon-bw48.png \ - $(AWT_ICONPATH)/security-icon-interim48.png \ - $(AWT_ICONPATH)/security-icon-yellow48.png - GENSRC_AWT_ICONS_FILES := $(notdir $(GENSRC_AWT_ICONS_SRC)) GENSRC_AWT_ICONS_SHORT_NAME = $(subst .,_,$(subst -,_,$(1))) diff --git a/src/demo/share/jfc/Font2DTest/FontPanel.java b/src/demo/share/jfc/Font2DTest/FontPanel.java index 70b1390fd76..559dccedc77 100644 --- a/src/demo/share/jfc/Font2DTest/FontPanel.java +++ b/src/demo/share/jfc/Font2DTest/FontPanel.java @@ -1114,13 +1114,7 @@ public void showZoomed() { /// Position and set size of zoom window as needed zoomWindow.setLocation( canvasLoc.x + zoomAreaX, canvasLoc.y + zoomAreaY ); if ( !nowZooming ) { - if ( zoomWindow.getWarningString() != null ) - /// If this is not opened as a "secure" window, - /// it has a banner below the zoom dialog which makes it look really BAD - /// So enlarge it by a bit - zoomWindow.setSize( zoomAreaWidth + 1, zoomAreaHeight + 20 ); - else - zoomWindow.setSize( zoomAreaWidth + 1, zoomAreaHeight + 1 ); + zoomWindow.setSize( zoomAreaWidth + 1, zoomAreaHeight + 1 ); } /// Prepare zoomed image diff --git a/src/java.desktop/macosx/classes/sun/lwawt/LWKeyboardFocusManagerPeer.java b/src/java.desktop/macosx/classes/sun/lwawt/LWKeyboardFocusManagerPeer.java index 5cecb6040fb..f8f3d70dd4b 100644 --- a/src/java.desktop/macosx/classes/sun/lwawt/LWKeyboardFocusManagerPeer.java +++ b/src/java.desktop/macosx/classes/sun/lwawt/LWKeyboardFocusManagerPeer.java @@ -57,13 +57,6 @@ public void setCurrentFocusedWindow(Window win) { focusedWindow = win; } - if (from != null) { - from.updateSecurityWarningVisibility(); - } - - if (to != null) { - to.updateSecurityWarningVisibility(); - } } @Override diff --git a/src/java.desktop/macosx/classes/sun/lwawt/LWToolkit.java b/src/java.desktop/macosx/classes/sun/lwawt/LWToolkit.java index 9a08fae9f4e..0de6b213299 100644 --- a/src/java.desktop/macosx/classes/sun/lwawt/LWToolkit.java +++ b/src/java.desktop/macosx/classes/sun/lwawt/LWToolkit.java @@ -421,9 +421,6 @@ public final Clipboard getSystemClipboard() { return clipboard; } - protected abstract SecurityWarningWindow createSecurityWarning( - Window ownerWindow, LWWindowPeer ownerPeer); - // ---- DELEGATES ---- // public abstract Clipboard createPlatformClipboard(); diff --git a/src/java.desktop/macosx/classes/sun/lwawt/LWWindowPeer.java b/src/java.desktop/macosx/classes/sun/lwawt/LWWindowPeer.java index 13b6372a3c8..054e74dcef2 100644 --- a/src/java.desktop/macosx/classes/sun/lwawt/LWWindowPeer.java +++ b/src/java.desktop/macosx/classes/sun/lwawt/LWWindowPeer.java @@ -146,8 +146,6 @@ public enum PeerType { private final PeerType peerType; - private final SecurityWarningWindow warningWindow; - private volatile boolean targetFocusable; /** @@ -197,18 +195,6 @@ public LWWindowPeer(Window target, PlatformComponent platformComponent, } platformWindow.initialize(target, this, ownerDelegate); - // Init warning window(for applets) - SecurityWarningWindow warn = null; - if (target.getWarningString() != null) { - // accessSystemTray permission allows to display TrayIcon, TrayIcon tooltip - // and TrayIcon balloon windows without a warning window. - if (!AWTAccessor.getWindowAccessor().isTrayIconWindow(target)) { - LWToolkit toolkit = (LWToolkit)Toolkit.getDefaultToolkit(); - warn = toolkit.createSecurityWarning(target, this); - } - } - - warningWindow = warn; } @Override @@ -274,9 +260,6 @@ protected void disposeImpl() { if (isGrabbing()) { ungrab(); } - if (warningWindow != null) { - warningWindow.dispose(); - } platformWindow.dispose(); super.disposeImpl(); @@ -294,9 +277,6 @@ public void setBackground(final Color c) { @Override protected void setVisibleImpl(final boolean visible) { - if (!visible && warningWindow != null) { - warningWindow.setVisible(false, false); - } updateFocusableWindowState(); super.setVisibleImpl(visible); // TODO: update graphicsConfig, see 4868278 @@ -555,19 +535,6 @@ final void applyShapeImpl(final Region shape) { updateOpaque(); } - @Override - public void repositionSecurityWarning() { - if (warningWindow != null) { - ComponentAccessor compAccessor = AWTAccessor.getComponentAccessor(); - Window target = getTarget(); - int x = compAccessor.getX(target); - int y = compAccessor.getY(target); - int width = compAccessor.getWidth(target); - int height = compAccessor.getHeight(target); - warningWindow.reposition(x, y, width, height); - } - } - // ---- FRAME PEER METHODS ---- // @Override // FramePeer and DialogPeer @@ -753,7 +720,6 @@ public void notifyReshape(int x, int y, int w, int h) { repaintPeer(); } - repositionSecurityWarning(); } private void clearBackground(final int w, final int h) { @@ -991,8 +957,6 @@ private void postMouseEnteredEvent(Component target, long when, int modifiers, Point loc, int xAbs, int yAbs, int clickCount, boolean popupTrigger, int button) { - updateSecurityWarningVisibility(); - postEvent(new MouseEvent(target, MouseEvent.MOUSE_ENTERED, when, modifiers, @@ -1004,8 +968,6 @@ private void postMouseExitedEvent(Component target, long when, int modifiers, Point loc, int xAbs, int yAbs, int clickCount, boolean popupTrigger, int button) { - updateSecurityWarningVisibility(); - postEvent(new MouseEvent(target, MouseEvent.MOUSE_EXITED, when, modifiers, @@ -1094,7 +1056,6 @@ private void postWindowStateChangedEvent(int newWindowState) { postEvent(stateChangedEvent); windowState = newWindowState; - updateSecurityWarningVisibility(); } private static int getGraphicsConfigScreen(GraphicsConfiguration gc) { @@ -1454,13 +1415,11 @@ public LWWindowPeer getBlocker() { @Override public void enterFullScreenMode() { platformWindow.enterFullScreenMode(); - updateSecurityWarningVisibility(); } @Override public void exitFullScreenMode() { platformWindow.exitFullScreenMode(); - updateSecurityWarningVisibility(); } public long getLayerPtr() { @@ -1495,33 +1454,6 @@ public PeerType getPeerType() { return peerType; } - public void updateSecurityWarningVisibility() { - if (warningWindow == null) { - return; - } - - if (!isVisible()) { - return; // The warning window should already be hidden. - } - - boolean show = false; - - if (!platformWindow.isFullScreenMode()) { - if (isVisible()) { - if (LWKeyboardFocusManagerPeer.getInstance().getCurrentFocusedWindow() == - getTarget()) { - show = true; - } - - if (platformWindow.isUnderMouse() || warningWindow.isUnderMouse()) { - show = true; - } - } - } - - warningWindow.setVisible(show, true); - } - @Override public String toString() { return super.toString() + " [target is " + getTarget() + "]"; diff --git a/src/java.desktop/macosx/classes/sun/lwawt/SecurityWarningWindow.java b/src/java.desktop/macosx/classes/sun/lwawt/SecurityWarningWindow.java deleted file mode 100644 index b701ac8b3e6..00000000000 --- a/src/java.desktop/macosx/classes/sun/lwawt/SecurityWarningWindow.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package sun.lwawt; - -public interface SecurityWarningWindow extends PlatformWindow { - /** - * @param x,y,w,h coordinates of the untrusted window - */ - public void reposition(int x, int y, int w, int h); - - public void setVisible(boolean visible, boolean doSchedule); -} diff --git a/src/java.desktop/macosx/classes/sun/lwawt/macosx/CFileDialog.java b/src/java.desktop/macosx/classes/sun/lwawt/macosx/CFileDialog.java index 090a90554f0..37ff19c8455 100644 --- a/src/java.desktop/macosx/classes/sun/lwawt/macosx/CFileDialog.java +++ b/src/java.desktop/macosx/classes/sun/lwawt/macosx/CFileDialog.java @@ -189,10 +189,6 @@ public void setResizable(boolean resizeable) { public void setTitle(String title) { } - @Override - public void repositionSecurityWarning() { - } - @Override public GraphicsConfiguration getAppropriateGraphicsConfiguration( GraphicsConfiguration gc) { diff --git a/src/java.desktop/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java b/src/java.desktop/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java index 0596ad2379e..615fcec9a77 100644 --- a/src/java.desktop/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java +++ b/src/java.desktop/macosx/classes/sun/lwawt/macosx/CPlatformWindow.java @@ -360,7 +360,7 @@ public void initialize(Window _target, LWWindowPeer _peer, PlatformWindow _owner } }); setPtr(ref.get()); - if (peer != null) { // Not applicable to CWarningWindow + if (peer != null) { peer.setTextured(IS(TEXTURED, styleBits)); } if (target instanceof javax.swing.RootPaneContainer) { diff --git a/src/java.desktop/macosx/classes/sun/lwawt/macosx/CWarningWindow.java b/src/java.desktop/macosx/classes/sun/lwawt/macosx/CWarningWindow.java deleted file mode 100644 index bcb18c76ae1..00000000000 --- a/src/java.desktop/macosx/classes/sun/lwawt/macosx/CWarningWindow.java +++ /dev/null @@ -1,475 +0,0 @@ -/* - * Copyright (c) 2013, 2021, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package sun.lwawt.macosx; - -import sun.awt.AWTAccessor; -import sun.awt.IconInfo; -import sun.java2d.SunGraphics2D; -import sun.java2d.SurfaceData; -import sun.java2d.metal.MTLLayer; -import sun.java2d.opengl.CGLLayer; -import sun.lwawt.LWWindowPeer; -import sun.lwawt.PlatformEventNotifier; -import sun.lwawt.SecurityWarningWindow; - -import java.awt.*; -import java.awt.event.MouseEvent; -import java.awt.geom.Point2D; -import java.lang.ref.WeakReference; - -public final class CWarningWindow extends CPlatformWindow - implements SecurityWarningWindow, PlatformEventNotifier { - - private static class Lock {} - private final Lock lock = new Lock(); - - private static final int SHOWING_DELAY = 300; - private static final int HIDING_DELAY = 2000; - - private Rectangle bounds = new Rectangle(); - private final WeakReference<LWWindowPeer> ownerPeer; - private final Window ownerWindow; - - /** - * Animation stage. - */ - private volatile int currentIcon; - - /* -1 - uninitialized. - * 0 - 16x16 - * 1 - 24x24 - * 2 - 32x32 - * 3 - 48x48 - */ - private int currentSize = -1; - private static IconInfo[][] icons; - private static IconInfo getSecurityIconInfo(int size, int num) { - synchronized (CWarningWindow.class) { - if (icons == null) { - icons = new IconInfo[4][3]; - icons[0][0] = new IconInfo(sun.awt.AWTIcon32_security_icon_bw16_png.security_icon_bw16_png); - icons[0][1] = new IconInfo(sun.awt.AWTIcon32_security_icon_interim16_png.security_icon_interim16_png); - icons[0][2] = new IconInfo(sun.awt.AWTIcon32_security_icon_yellow16_png.security_icon_yellow16_png); - icons[1][0] = new IconInfo(sun.awt.AWTIcon32_security_icon_bw24_png.security_icon_bw24_png); - icons[1][1] = new IconInfo(sun.awt.AWTIcon32_security_icon_interim24_png.security_icon_interim24_png); - icons[1][2] = new IconInfo(sun.awt.AWTIcon32_security_icon_yellow24_png.security_icon_yellow24_png); - icons[2][0] = new IconInfo(sun.awt.AWTIcon32_security_icon_bw32_png.security_icon_bw32_png); - icons[2][1] = new IconInfo(sun.awt.AWTIcon32_security_icon_interim32_png.security_icon_interim32_png); - icons[2][2] = new IconInfo(sun.awt.AWTIcon32_security_icon_yellow32_png.security_icon_yellow32_png); - icons[3][0] = new IconInfo(sun.awt.AWTIcon32_security_icon_bw48_png.security_icon_bw48_png); - icons[3][1] = new IconInfo(sun.awt.AWTIcon32_security_icon_interim48_png.security_icon_interim48_png); - icons[3][2] = new IconInfo(sun.awt.AWTIcon32_security_icon_yellow48_png.security_icon_yellow48_png); - } - } - final int sizeIndex = size % icons.length; - return icons[sizeIndex][num % icons[sizeIndex].length]; - } - - public CWarningWindow(final Window _ownerWindow, final LWWindowPeer _ownerPeer) { - super(); - - this.ownerPeer = new WeakReference<>(_ownerPeer); - this.ownerWindow = _ownerWindow; - - initialize(null, null, _ownerPeer.getPlatformWindow()); - - setOpaque(false); - - String warningString = ownerWindow.getWarningString(); - if (warningString != null) { - contentView.setToolTip(ownerWindow.getWarningString()); - } - - updateIconSize(); - } - - /** - * @param x,y,w,h coordinates of the untrusted window - */ - public void reposition(int x, int y, int w, int h) { - final Point2D point = AWTAccessor.getWindowAccessor(). - calculateSecurityWarningPosition(ownerWindow, x, y, w, h); - setBounds((int)point.getX(), (int)point.getY(), getWidth(), getHeight()); - } - - public void setVisible(boolean visible, boolean doSchedule) { - synchronized (taskLock) { - cancelTasks(); - - if (visible) { - if (isVisible()) { - currentIcon = 0; - } else { - currentIcon = 2; - } - - showHideTask = new ShowingTask(); - LWCToolkit.performOnMainThreadAfterDelay(showHideTask, 50); - } else { - if (!isVisible()) { - return; - } - - showHideTask = new HidingTask(); - if (doSchedule) { - LWCToolkit.performOnMainThreadAfterDelay(showHideTask, HIDING_DELAY); - } else { - LWCToolkit.performOnMainThreadAfterDelay(showHideTask, 50); - } - } - } - } - - @Override - public void notifyIconify(boolean iconify) { - } - - @Override - public void notifyZoom(boolean isZoomed) { - } - - @Override - public void notifyExpose(final Rectangle r) { - repaint(); - } - - @Override - public void notifyReshape(int x, int y, int w, int h) { - } - - @Override - public void notifyUpdateCursor() { - } - - @Override - public void notifyActivation(boolean activation, LWWindowPeer opposite) { - } - - @Override - public void notifyNCMouseDown() { - } - - @Override - public void notifyMouseEvent(int id, long when, int button, int x, int y, - int absX, int absY, int modifiers, - int clickCount, boolean popupTrigger, - byte[] bdata) { - LWWindowPeer peer = ownerPeer.get(); - if (id == MouseEvent.MOUSE_EXITED) { - if (peer != null) { - peer.updateSecurityWarningVisibility(); - } - } else if(id == MouseEvent.MOUSE_ENTERED) { - if (peer != null) { - peer.updateSecurityWarningVisibility(); - } - } - } - - public Rectangle getBounds() { - synchronized (lock) { - return bounds.getBounds(); - } - } - - @Override - public boolean isVisible() { - synchronized (lock) { - return visible; - } - } - - @Override - public void setVisible(boolean visible) { - synchronized (lock) { - execute(ptr -> { - // Actually show or hide the window - if (visible) { - CWrapper.NSWindow.orderFront(ptr); - } else { - CWrapper.NSWindow.orderOut(ptr); - } - }); - - this.visible = visible; - - // Manage parent-child relationship when showing - if (visible) { - // Order myself above my parent - if (owner != null && owner.isVisible()) { - owner.execute(ownerPtr -> { - execute(ptr -> { - CWrapper.NSWindow.orderWindow(ptr, - CWrapper.NSWindow.NSWindowAbove, - ownerPtr); - }); - }); - - // do not allow security warning to be obscured by other windows - applyWindowLevel(ownerWindow); - } - } - } - } - - @Override - public void notifyMouseWheelEvent(long when, int x, int y, int absX, - int absY, int modifiers, int scrollType, - int scrollAmount, int wheelRotation, - double preciseWheelRotation, - byte[] bdata) { - } - - @Override - public void notifyKeyEvent(int id, long when, int modifiers, int keyCode, - char keyChar, int keyLocation, int jextendedkeyCode) { - } - - protected int getInitialStyleBits() { - int styleBits = 0; - CPlatformWindow.SET(styleBits, CPlatformWindow.UTILITY, true); - return styleBits; - } - - protected void deliverMoveResizeEvent(int x, int y, int width, int height, - boolean byUser) { - - boolean isResize; - synchronized (lock) { - isResize = (bounds.width != width || bounds.height != height); - bounds = new Rectangle(x, y, width, height); - } - - if (isResize) { - replaceSurface(); - } - - super.deliverMoveResizeEvent(x, y, width, height, byUser); - } - - protected CPlatformResponder createPlatformResponder() { - return new CPlatformResponder(this, false); - } - - CPlatformView createContentView() { - return new CPlatformView() { - public GraphicsConfiguration getGraphicsConfiguration() { - LWWindowPeer peer = ownerPeer.get(); - return peer.getGraphicsConfiguration(); - } - - public Rectangle getBounds() { - return CWarningWindow.this.getBounds(); - } - - public CGLLayer createCGLayer() { - return new CGLLayer(null) { - public Rectangle getBounds() { - return CWarningWindow.this.getBounds(); - } - - public GraphicsConfiguration getGraphicsConfiguration() { - LWWindowPeer peer = ownerPeer.get(); - return peer.getGraphicsConfiguration(); - } - - public boolean isOpaque() { - return false; - } - }; - } - public MTLLayer createMTLLayer() { - return new MTLLayer(null) { - public Rectangle getBounds() { - return CWarningWindow.this.getBounds(); - } - - public GraphicsConfiguration getGraphicsConfiguration() { - LWWindowPeer peer = ownerPeer.get(); - return peer.getGraphicsConfiguration(); - } - - public boolean isOpaque() { - return false; - } - }; - } - - }; - } - - @Override - public void dispose() { - cancelTasks(); - SurfaceData surfaceData = contentView.getSurfaceData(); - if (surfaceData != null) { - surfaceData.invalidate(); - } - super.dispose(); - } - - private void cancelTasks() { - synchronized (taskLock) { - if (showHideTask != null) { - showHideTask.cancel(); - showHideTask = null; - } - } - } - - private void updateIconSize() { - int newSize = -1; - - if (ownerWindow != null) { - Insets insets = ownerWindow.getInsets(); - int max = Math.max(insets.top, Math.max(insets.bottom, - Math.max(insets.left, insets.right))); - if (max < 24) { - newSize = 0; - } else if (max < 32) { - newSize = 1; - } else if (max < 48) { - newSize = 2; - } else { - newSize = 3; - } - } - // Make sure we have a valid size - if (newSize == -1) { - newSize = 0; - } - - synchronized (lock) { - if (newSize != currentSize) { - currentSize = newSize; - IconInfo ico = getSecurityIconInfo(currentSize, 0); - AWTAccessor.getWindowAccessor().setSecurityWarningSize( - ownerWindow, ico.getWidth(), ico.getHeight()); - } - } - } - - private Graphics getGraphics() { - SurfaceData sd = contentView.getSurfaceData(); - if (ownerWindow == null || sd == null) { - return null; - } - - return new SunGraphics2D(sd, SystemColor.windowText, SystemColor.window, - ownerWindow.getFont()); - } - - - private void repaint() { - final Graphics g = getGraphics(); - if (g != null) { - try { - ((Graphics2D) g).setComposite(AlphaComposite.Src); - g.drawImage(getSecurityIconInfo().getImage(), 0, 0, null); - } finally { - g.dispose(); - } - } - } - - private void replaceSurface() { - SurfaceData oldData = contentView.getSurfaceData(); - - replaceSurfaceData(); - - if (oldData != null && oldData != contentView.getSurfaceData()) { - oldData.flush(); - } - } - - private int getWidth() { - return getSecurityIconInfo().getWidth(); - } - - private int getHeight() { - return getSecurityIconInfo().getHeight(); - } - - private IconInfo getSecurityIconInfo() { - return getSecurityIconInfo(currentSize, currentIcon); - } - - private final Lock taskLock = new Lock(); - private CancelableRunnable showHideTask; - - private abstract static class CancelableRunnable implements Runnable { - private volatile boolean perform = true; - - public final void cancel() { - perform = false; - } - - @Override - public final void run() { - if (perform) { - perform(); - } - } - - public abstract void perform(); - } - - private class HidingTask extends CancelableRunnable { - @Override - public void perform() { - synchronized (lock) { - setVisible(false); - } - - synchronized (taskLock) { - showHideTask = null; - } - } - } - - private class ShowingTask extends CancelableRunnable { - @Override - public void perform() { - synchronized (lock) { - if (!isVisible()) { - setVisible(true); - } - repaint(); - } - - synchronized (taskLock) { - if (currentIcon > 0) { - currentIcon--; - showHideTask = new ShowingTask(); - LWCToolkit.performOnMainThreadAfterDelay(showHideTask, SHOWING_DELAY); - } else { - showHideTask = null; - } - } - } - } -} - diff --git a/src/java.desktop/macosx/classes/sun/lwawt/macosx/LWCToolkit.java b/src/java.desktop/macosx/classes/sun/lwawt/macosx/LWCToolkit.java index d3ffcfc7730..2ce71b1fb95 100644 --- a/src/java.desktop/macosx/classes/sun/lwawt/macosx/LWCToolkit.java +++ b/src/java.desktop/macosx/classes/sun/lwawt/macosx/LWCToolkit.java @@ -117,7 +117,6 @@ import sun.lwawt.PlatformComponent; import sun.lwawt.PlatformDropTarget; import sun.lwawt.PlatformWindow; -import sun.lwawt.SecurityWarningWindow; @SuppressWarnings("serial") // JDK implementation class final class NamedCursor extends Cursor { @@ -292,12 +291,6 @@ public DialogPeer createDialog(Dialog target) { return super.createDialog(target); } - @Override - protected SecurityWarningWindow createSecurityWarning(Window ownerWindow, - LWWindowPeer ownerPeer) { - return new CWarningWindow(ownerWindow, ownerPeer); - } - @Override protected PlatformComponent createPlatformComponent() { return new CPlatformComponent(); diff --git a/src/java.desktop/share/classes/java/awt/Desktop.java b/src/java.desktop/share/classes/java/awt/Desktop.java index 89a78518873..c3e89140dc9 100644 --- a/src/java.desktop/share/classes/java/awt/Desktop.java +++ b/src/java.desktop/share/classes/java/awt/Desktop.java @@ -378,22 +378,6 @@ private void checkActionSupport(Action actionType){ } } - - /** - * Calls to the security manager's {@code checkPermission} method with an - * {@code AWTPermission("showWindowWithoutWarningBanner")} permission. This - * permission is needed, because we cannot add a security warning icon to - * the windows of the external native application. - */ - private void checkAWTPermission() { - @SuppressWarnings("removal") - SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - sm.checkPermission(new AWTPermission( - "showWindowWithoutWarningBanner")); - } - } - /** * Launches the associated application to open the file. * @@ -411,7 +395,6 @@ private void checkAWTPermission() { */ public void open(File file) throws IOException { file = new File(file.getPath()); - checkAWTPermission(); checkExec(); checkActionSupport(Action.OPEN); checkFileValidation(file); @@ -434,7 +417,6 @@ public void open(File file) throws IOException { */ public void edit(File file) throws IOException { file = new File(file.getPath()); - checkAWTPermission(); checkExec(); checkActionSupport(Action.EDIT); file.canWrite(); @@ -493,7 +475,6 @@ public void print(File file) throws IOException { * @see java.net.URI */ public void browse(URI uri) throws IOException { - checkAWTPermission(); checkExec(); checkActionSupport(Action.BROWSE); Objects.requireNonNull(uri); @@ -510,7 +491,6 @@ public void browse(URI uri) throws IOException { * found, or it fails to be launched */ public void mail() throws IOException { - checkAWTPermission(); checkExec(); checkActionSupport(Action.MAIL); URI mailtoURI = null; @@ -548,7 +528,6 @@ public void mail() throws IOException { * @see java.net.URI */ public void mail(URI mailtoURI) throws IOException { - checkAWTPermission(); checkExec(); checkActionSupport(Action.MAIL); if (mailtoURI == null) throw new NullPointerException(); @@ -860,7 +839,6 @@ public void requestForeground(final boolean allWindows) { * @since 9 */ public void openHelpViewer() { - checkAWTPermission(); checkExec(); checkEventsProcessingPermission(); checkActionSupport(Action.APP_HELP_VIEWER); @@ -903,7 +881,6 @@ public void setDefaultMenuBar(final JMenuBar menuBar) { */ public void browseFileDirectory(File file) { file = new File(file.getPath()); - checkAWTPermission(); checkExec(); checkActionSupport(Action.BROWSE_FILE_DIR); checkFileValidation(file); diff --git a/src/java.desktop/share/classes/java/awt/Window.java b/src/java.desktop/share/classes/java/awt/Window.java index f6560fb8e58..ac1a2e41dc1 100644 --- a/src/java.desktop/share/classes/java/awt/Window.java +++ b/src/java.desktop/share/classes/java/awt/Window.java @@ -209,18 +209,6 @@ public static enum Type { POPUP } - /** - * This represents the warning message that is - * to be displayed in a non secure window. ie : - * a window that has a security manager installed that denies - * {@code AWTPermission("showWindowWithoutWarningBanner")}. - * This message can be displayed anywhere in the window. - * - * @serial - * @see #getWarningString - */ - String warningString; - /** * {@code icons} is the graphical way we can * represent the frames and dialogs. @@ -398,13 +386,6 @@ public static enum Type { transient boolean isTrayIconWindow = false; - /** - * These fields are initialized in the native peer code - * or via AWTAccessor's WindowAccessor. - */ - private transient volatile int securityWarningWidth; - private transient volatile int securityWarningHeight; - static { /* ensure that the necessary native libraries are loaded */ Toolkit.loadLibraries(); @@ -428,10 +409,6 @@ public static enum Type { * Constructs a new, initially invisible window in default size with the * specified {@code GraphicsConfiguration}. * <p> - * If there is a security manager, then it is invoked to check - * {@code AWTPermission("showWindowWithoutWarningBanner")} - * to determine whether or not the window must be displayed with - * a warning banner. * * @param gc the {@code GraphicsConfiguration} of the target screen * device. If {@code gc} is {@code null}, the system default @@ -532,10 +509,6 @@ private void init(GraphicsConfiguration gc) { /** * Constructs a new, initially invisible window in the default size. * <p> - * If there is a security manager set, it is invoked to check - * {@code AWTPermission("showWindowWithoutWarningBanner")}. - * If that check fails with a {@code SecurityException} then a warning - * banner is created. * * @throws HeadlessException when * {@code GraphicsEnvironment.isHeadless()} returns {@code true} @@ -1361,11 +1334,14 @@ public Toolkit getToolkit() { * Gets the warning string that is displayed with this window. * <p> * Warning strings are no longer applicable, - * so this method always returns {@code null}. + * so this method always returns {@code null} and may be + * removed in a future release. * @return null + * @deprecated since JDK 24 */ + @Deprecated(since="24", forRemoval=true) public final String getWarningString() { - return warningString; + return null; } /** @@ -3075,9 +3051,6 @@ private void readObject(ObjectInputStream s) shape = (Shape)f.get("shape", null); opacity = (Float)f.get("opacity", 1.0f); - this.securityWarningWidth = 0; - this.securityWarningHeight = 0; - deserializeResources(s); } @@ -3977,69 +3950,12 @@ private static double limit(double value, double min, double max) { return value; } - /** - * Calculate the position of the security warning. - * - * This method gets the window location/size as reported by the native - * system since the locally cached values may represent outdated data. - * - * The method is used from the native code, or via AWTAccessor. - * - * NOTE: this method is invoked on the toolkit thread, and therefore is not - * supposed to become public/user-overridable. - */ - private Point2D calculateSecurityWarningPosition(double x, double y, - double w, double h) - { - // The desired location for the security warning - double wx = x + w * RIGHT_ALIGNMENT + 2.0; - double wy = y + h * TOP_ALIGNMENT + 0.0; - - // First, make sure the warning is not too far from the window bounds - wx = Window.limit(wx, - x - securityWarningWidth - 2, - x + w + 2); - wy = Window.limit(wy, - y - securityWarningHeight - 2, - y + h + 2); - - // Now make sure the warning window is visible on the screen - GraphicsConfiguration graphicsConfig = - getGraphicsConfiguration_NoClientCode(); - Rectangle screenBounds = graphicsConfig.getBounds(); - Insets screenInsets = - Toolkit.getDefaultToolkit().getScreenInsets(graphicsConfig); - - wx = Window.limit(wx, - screenBounds.x + screenInsets.left, - screenBounds.x + screenBounds.width - screenInsets.right - - securityWarningWidth); - wy = Window.limit(wy, - screenBounds.y + screenInsets.top, - screenBounds.y + screenBounds.height - screenInsets.bottom - - securityWarningHeight); - - return new Point2D.Double(wx, wy); - } - static { AWTAccessor.setWindowAccessor(new AWTAccessor.WindowAccessor() { public void updateWindow(Window window) { window.updateWindow(); } - public void setSecurityWarningSize(Window window, int width, int height) - { - window.securityWarningWidth = width; - window.securityWarningHeight = height; - } - - public Point2D calculateSecurityWarningPosition(Window window, - double x, double y, double w, double h) - { - return window.calculateSecurityWarningPosition(x, y, w, h); - } - public void setLWRequestStatus(Window changed, boolean status) { changed.syncLWRequests = status; } diff --git a/src/java.desktop/share/classes/java/awt/peer/WindowPeer.java b/src/java.desktop/share/classes/java/awt/peer/WindowPeer.java index 07013a10bd0..0c6c991959b 100644 --- a/src/java.desktop/share/classes/java/awt/peer/WindowPeer.java +++ b/src/java.desktop/share/classes/java/awt/peer/WindowPeer.java @@ -114,11 +114,6 @@ public interface WindowPeer extends ContainerPeer { */ void updateWindow(); - /** - * Instructs the peer to update the position of the security warning. - */ - void repositionSecurityWarning(); - /** * Requests a GC that best suits this Window. The returned GC may differ * from the requested GC passed as the argument to this method. This method diff --git a/src/java.desktop/share/classes/javax/swing/JInternalFrame.java b/src/java.desktop/share/classes/javax/swing/JInternalFrame.java index 38bd5ef2c41..d6b6958e084 100644 --- a/src/java.desktop/share/classes/javax/swing/JInternalFrame.java +++ b/src/java.desktop/share/classes/javax/swing/JInternalFrame.java @@ -1862,12 +1862,14 @@ public final Container getFocusCycleRootAncestor() { /** * Gets the warning string that is displayed with this internal frame. - * Since an internal frame is always secure (since it's fully - * contained within a window that might need a warning string) - * this method always returns <code>null</code>. + * This method always returns <code>null</code>. + * Warning strings are no longer applicable, even to top-level + * windows, so this method may be removed in a future release * @return <code>null</code> * @see java.awt.Window#getWarningString + * @deprecated since JDK 24 */ + @Deprecated(since="24", forRemoval=true) @BeanProperty(bound = false) public final String getWarningString() { return null; diff --git a/src/java.desktop/share/classes/sun/awt/AWTAccessor.java b/src/java.desktop/share/classes/sun/awt/AWTAccessor.java index 1303ef7b282..5a3d2c46773 100644 --- a/src/java.desktop/share/classes/sun/awt/AWTAccessor.java +++ b/src/java.desktop/share/classes/sun/awt/AWTAccessor.java @@ -305,17 +305,6 @@ public interface WindowAccessor { */ void updateWindow(Window window); - /** - * Set the size of the security warning. - */ - void setSecurityWarningSize(Window w, int width, int height); - - /** Request to recalculate the new position of the security warning for - * the given window size/location as reported by the native system. - */ - Point2D calculateSecurityWarningPosition(Window window, - double x, double y, double w, double h); - /** Sets the synchronous status of focus requests on lightweight * components in the specified window to the specified value. */ diff --git a/src/java.desktop/share/classes/sun/awt/AWTPermissions.java b/src/java.desktop/share/classes/sun/awt/AWTPermissions.java index 57ed7a96644..da0dcd1c3af 100644 --- a/src/java.desktop/share/classes/sun/awt/AWTPermissions.java +++ b/src/java.desktop/share/classes/sun/awt/AWTPermissions.java @@ -33,9 +33,6 @@ public final class AWTPermissions { private AWTPermissions() { } - public static final AWTPermission TOPLEVEL_WINDOW_PERMISSION = - new AWTPermission("showWindowWithoutWarningBanner"); - public static final AWTPermission ACCESS_CLIPBOARD_PERMISSION = new AWTPermission("accessClipboard"); diff --git a/src/java.desktop/share/classes/sun/awt/EmbeddedFrame.java b/src/java.desktop/share/classes/sun/awt/EmbeddedFrame.java index ff68d45f623..e024a6466cb 100644 --- a/src/java.desktop/share/classes/sun/awt/EmbeddedFrame.java +++ b/src/java.desktop/share/classes/sun/awt/EmbeddedFrame.java @@ -590,9 +590,6 @@ public void setOpaque(boolean isOpaque) { public void updateWindow() { } - public void repositionSecurityWarning() { - } - public void emulateActivation(boolean activate) { } } diff --git a/src/java.desktop/share/classes/sun/awt/resources/security-icon-bw16.png b/src/java.desktop/share/classes/sun/awt/resources/security-icon-bw16.png deleted file mode 100644 index 98dcd0f4e77d099c6d344ed0a3cdb7287e838c14..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 463 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbL!WQl7;NpOBzNqJ&XDuZK6ep0G} zXKrG8YEWuoN@d~6R2!h8nE^f_u7!n#FJ8R3dGqFzCr{qKeS7E5o$J@HKX~xq)TvVq z4Gs71-8*#X(9xquYinx{95^t2`t<qp=N~z8q_VPd?%cVPCr@r^Y3b<b=;`TMxNxDA zl+^wE_lt{*FI>2A>(;FkCr*@=m0h`VW!9`&6DCaX^73+Ua4<GD4hRUy%gf8n&2@5e za&>h*ckZ08ukYr~n>92v)Ya9ktgNO?nezYt|1E1~I{_VOToU9L4CIms7z*d@?E`A> z^>lFzskjw#B3$f{0gp?da>s_t)$hOX-TVJ&!(@Ru-wiMAZ0TS6^2>yeJErX7=J;e2 zuyA$h-ghDeTTaIo{}Y&X^>x6^hdj0p+n8U}Pmt(1Z@XxskAU){-zsWyik}!BREa%y zWj65rvg2f`kj^gAjr}oMoFA@ldSf9ofAX>z&8fVaZ_13X-(r23BKV)nfT2fNdXl2v SCl#Q>7(8A5T-G@yGywpg#P84m diff --git a/src/java.desktop/share/classes/sun/awt/resources/security-icon-bw24.png b/src/java.desktop/share/classes/sun/awt/resources/security-icon-bw24.png deleted file mode 100644 index 5e5acae2e43758d7e27c5fd1238d53478f375ab1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 682 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM3?#3wJbMaANtU=qlmzFem6RtIr7}3C<R_&n zc;+Uirv{}arc@T5Otk?j`W)aB;#yEp@b2BaSFc{(yLa#7$Bz#mKD=?`#;seo?%cWa z<jIrg&!1nrcJ2E0>xT{<x_R^Fv17+hojP^@{{6#;4>vbApFVy1_U+pi78VN^E}TAn zdTD9t)vH(Q>gp;hD~}vGGIQq4*4EZ}^XAQ+JGZ>N{KSb96DCaP=;#m>6l`c{c<|ss zZ*Ol=QIU#@ijtC2adEM(u5NdC_tdFV7c5wC{`~ps>gw6EXIolYPMS1HQc}{|+FC+F zV#9_FOP4Mc6%}2*dUb7W?f(7y_w3oj&d#2fm$!cX`kgy>&YCrA^5n^9&YWRlV%ocR z?}`;G*x1<4o;|yD>sD@V?h6+#{Qv*|)bi?=K<@{Z1o;I6xl{!V8E;k`1RDOq)5S5Q z;#SVd=TV0hB-#?Us4ZX>GT!z5UiGeBTS{ktwwLl;;Ct)Cp9j@D^B(*-`nZw*!}AN9 z+JZDRyd2qF_g=ivEi~iKX0^l<Q<c{g>9KIO)P-@V>Lo6?`TJ!_Zgw;G49ARbRn{Eo z&jU^d{krthCV1A`IgY`hSI__abHLA-qqfPgZq3yj-JbRgS2bQgE`K>M<7)e!g}Z8X z_ar~@PjFiQU1I+;!B<kBx^jPBeZ_Q1Q0}L&^4Y{S+IzyCd1~J{KAZOaT3&QgT8u{T zy9)l<>RQiM98svOeRJFH>=Nc(E44jW>SYMl2y;yqD`+rz9^b&ou<LlTer@c7UqHVz Nc)I$ztaD0e0st1TeJ%h1 diff --git a/src/java.desktop/share/classes/sun/awt/resources/security-icon-bw32.png b/src/java.desktop/share/classes/sun/awt/resources/security-icon-bw32.png deleted file mode 100644 index 9d92b96e2fe8a2e27cb98f2ad4bf1fb92b28c0d2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 795 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE3?yBabR7dyk|nMYCBgY=CFO}lsSJ)O`AMk? zp1FzXsX?iUDV2pMQ*9U+7`X#{LR<?93f{bV^Zxz&yLaz?{P^+V!-x0p-@kqP_Kh1i zu3x|Y`0?XcuU<WW{`}UhTTh=py?OKIwQJYz-Me?_&>?1KW@BUHqeqXPI(6#KojZJd ze3K_ne(>Odwzl^4>C=mfifn9bYHMrj>guemtrsp_c;du~<HwITG&B?z79Kfrq^zuL z?%cVXHf_?>)KpPXIeGHrj2SbQFJIo#(Q)k9v7Vlul9H0r(o%78@wT=$cX#*V;$k^D zxkry4UAlBhP*8B*ym<>2EU2ic@b&fW?(UvCb?VZkOD9a2ke{F5*Vi{`(j+!Ew#v%N z#fukrb#(~|3C*58n~RI9y1M$@xpQaEoS8Li*8KVNo0^(hT3VQxm_kBA{{R2~z^E__ z7<Q2*L4LtNE=>S~e=8$DFzg*YT^vIyZq;169@gw2;t*(}#$w8LFhJx|_4~cw?{WYC zuX>JQp~`{EnbnE<attmP#Chyu9KK|KFL)8v6uh}|6O-(zyyaG63Lm+>W;FXAV?34P zbMRyIn+ikvN*)EYLQEIgJFvEXInb?XH$4_y%0pwacO;lM$u#+k>T7X58J@NlMN z!$xTlkLAoCWbB(WdG5V1m#VEew#<LQi<Y}uQ)gR<$RF%Fkg)XYE)~8buNa>c8qQ0s z$UODhF|>-|Snl>YCW4`|J1mw?`}{LVPCu%k?LEUZm6J<ss?JFXIKGcve@Y^-(Z1%t zk6Bybu?_KzcI`oW%g^nzzR_rZQ6o#e`RMLj8A~F?gkHSeKSgcj6_>l;Yz2?lU(I@3 z=DYcrqQ-W+D-n}YOtV+>IQ%`jXjj9BAFEw0`dv8RoHgm`P-04&`9c2x!~b{3{8v6* RDgcZz22WQ%mvv4FO#pE}tHJ;P diff --git a/src/java.desktop/share/classes/sun/awt/resources/security-icon-bw48.png b/src/java.desktop/share/classes/sun/awt/resources/security-icon-bw48.png deleted file mode 100644 index 9615364226a9744814bd2ce673adba31ccb72c07..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1137 zcmeAS@N?(olHy`uVBq!ia0vp^1|ZDA3?vioaBc-sk|nMYCBgY=CFO}lsSJ)O`AMk? zp1FzXsX?iUDV2pMQ*9U+7^?z&LR_z3zkcJ!jeGa*-Mo48_U+pR1qBZuK79ZF{hd2^ z9z1yP=FOXrA3wf*`}XeLyPrONx_0f_qeqW!-MaPS#fw+3UOj#K^!fAWPo6xvfB(L$ ztn9I4$Mp2{EG;cHH8qWmjoH}P=FOWYARut|?AZki7BDh0mX(#2mzSSBc~VkRvbwr@ z;lhOzCQLYb^r(=K(5X|WL`6j{EG!fi70;hPUsP0d`0!y>RaGu7u0w|oB_<~F^YfoL zae{+`gNKJ_`t<1~B_&IjE}b!B#;jShX3m^BXU?38iV7wsrYl#jFf%isK7IPgks}8W z9%Nx*adUG^O--FRaiW2NK}<}HtE=nd$B&O6KW=Sp?c?L)@9#ft+O+xe=lAyZ3JVL@ z*Vot8)$QNEKQAw@wzjspxp~s0Npt7UojiGRXJ=<eM@L^@-;yOu?Ck6|ZQ4{^Tzuxt znW<B!>g((G^z<|~Hnz01%$_~Fva%8w1*N5>?d|QCE?sJEZOzTi?e6Zbs;X*eXlQC` zDl9Dg|Nnm~bHx&%y1J4ezhEGD-~huJyJtlV3{1?PE{-7;x29aVUUkbspy47b_jZ?e zor^WtlDiCBEF72=-|hW=uloJoPw(W`hB;m0$}C-1*7h_1k7U5P5N?D2EHm?F`=zJ( z&7Q*&dcbjmi3+Q;_nF4^5}!A+?b{)9q_*dvpXA2FVqe-`cNXXe7sRgLmBzVib6)7S z*@`a;v%lP6kKJr@eto~ZZ14KR$=gnwWwaaHUFI^nwEC`Igou|Tv)bMk*Vzwzc4__X zd-!~2=?3kBN%9hPT)U?oG_!l8_P@dN=iXdVpChX_w%$*0tUIoz)08nW=b!Wpb>}Sw z1qMEO^JX0smTcqaVmqy;^n;saYUa*>f{8(Xdi71-sa~-n9P=hF`Yit<<aqk$1pT#f zGTR!ROMTwYWcxjJ)rWY2bLW4j9jvvg5BMpcaqP=p&kr3YVSDb0zWw9D9{y^+hf-f( z*DcFZSJr6Ps7DVLtccE$Y&QQC?~?NCxA895H)jR*6j@0(9%!rkyox{UqqweqQML5N z{Fczz4aZ)qE?X|#c6FB7jWfG)Q_W2sm-INQ$nTjjKRf%Qxap3SMxWdl*JV{MW~u$R zo=y4D&z%-YcYgi$5LjhAYtp{U!B?zQ*bg2NU%b)Hz-_Itqs*PF0ZwrOi@ui!UHBN_ z{qPx6qh;Sc`x1wOpmzs6`Bd5MtPLi(oD_1O^g_0_h~b>=@pW8j>yr6TRmz;K<uG7K Y>hs#U<dV`&V8UeZboFyt=akR{0I^hDF8}}l diff --git a/src/java.desktop/share/classes/sun/awt/resources/security-icon-interim16.png b/src/java.desktop/share/classes/sun/awt/resources/security-icon-interim16.png deleted file mode 100644 index f543f65d8b17d0d62180f75f35b2871124e5624b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 489 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbL!WQl7;NpOBzNqJ&XDuZK6ep0G} zXKrG8YEWuoN@d~6R2!h8)d4;suD$iPA6`!Q^mfX-r#-Llw!C@R@#04P%Ug{vZ#KQU z-En9`==I|z6B_LftP7dd?fmZH?DvlsPHT6(dvWrKgN2(H`E6eo@cM55oh$XX&vo29 zT|cki_13w{MU&kpx7c4lQF8Bk^WHVV%cgt2y+3u=%AnP=yw=b2@p990cCwp2HCbI< zy)@5JOG8##TGZdyW&h^vJLhZctyQF?q(TBsTN@(%yv)k;olK1NTphLl|Noy{$Y%g_ zwq;3>UoenM7GSVilj;C8q~FuUF{I*F$cd|BhZO`|1G7Bt++F(a)c^WO#U+_Va_`RE zYUol~S>Ir>Ds`o>2G3#%XW1830sRNonk_%|w^_Jq_jYkB<}EFE=Cy3G&q(Rvm+yJH ztX;^dqIRPutBRyk#@_VFs<JNL*M1%{f3)DJ_O;~G=GP=<aNqlQPj+(CmHEA&f*0KQ kS);LC)Zw7YFVO@B>G$$UVr#1>0G-C*>FVdQ&MBb@0PKeM-2eap diff --git a/src/java.desktop/share/classes/sun/awt/resources/security-icon-interim24.png b/src/java.desktop/share/classes/sun/awt/resources/security-icon-interim24.png deleted file mode 100644 index 753a2adab88e4719cf3dbd4d1e2b65ba5df5c64c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 741 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM3?#3wJbMaANtU=qlmzFem6RtIr7}3C<R_&n zc;+Uirv{}arc@T5OtoQPV3Z2*332`Mc~(!I?dSK?KE9d!_EG1%r#&BD^uM~({N{e! z%Ug{vZ`8lIUjOoD%iH_Y-aVZC;C9>l#|vKH>3wy(<KFeADXk7FDk>8i?fM#Qw=WBr z)NH?HvH#tR69okYmrQYAIMMCK$&y1GLT7e4?OhYRa;Dd<GmSQuN^kB>n%(0pDJl8k z$<p1cf|Qh$K0aG@@6yzH{jQdlmUqr|E}QOo>uiOtuI}|?MQi4G-#A%$;$Y#<6@i-; z`W;*!vVU#Jor|^8+8x)=^Vz<+P)t<7-dgq0p2|bp8_plAC@XNjcctO%vARu5lXtAm z<L2gOXJ_BKGV{*aS|%o@tLGZp>OvRIP2Ihr^zprJHa51a7n{!<Y&*5TaqiTtv-=Ar zC4`<l=<R8V{r~^}`7QTn0E05FB*-rq$fX@%*my!u4QSJMPZ!6Kid#7+pI0>*NVGlN zaxIK?$%A`b@AiJrn=5;3SJc$c_PorUO|zc6?=!#7tFkpA;4|Z^oHQd}r7f3UigB{| zD?JqCm{8NI`hMX&^TVIMS{E3dxjij$&h`g<?*EH+#+tm@*T{BU)_ZAuUv`Z1_EVov zhh!c5eD$4ZNXD#xJ;(PySefCd6D(r-wd$ewR99XRpAG+i#@Q`v;@Z~`m}eW{cc7f{ zfA^(wme~K2n_QcNQd;s1yA{8+RLMUUbQZ{Z9e9{i?(GDox#?H>&u%-gS-JV@BImDm zzqD<1!#LI*FP?okb(cy)I-}w>J{i-d4W{f9<T^an8QB<Sa+mmaR38)t1_6VotDnm{ Hr-UW|w4Rk@ diff --git a/src/java.desktop/share/classes/sun/awt/resources/security-icon-interim32.png b/src/java.desktop/share/classes/sun/awt/resources/security-icon-interim32.png deleted file mode 100644 index 9ea41d490eafe731f58b2ac42be774ce1815d530..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 871 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE3?yBabR7dyk|nMYCBgY=CFO}lsSJ)O`AMk? zp1FzXsX?iUDV2pMQ*9U+7+nH<LR@?5Y`%P&`T6~{ub*eVd)o8i)x?i)Cck~$_5OL^ zn+NT$@3p?V+w$sm)61I;FK*PoxL*J2R@=)PP46Dges#O+^_|`~cPGBNKjr=7MeiTY zXJ%%8`(TE)w)V$ot3Etk_TYA#v9Ym`kkG_t`)TctAD^#XG}-;y@uKU;OXl>tY+RAb z#l>~wWaZ=*`-AI4`S~~|G}`T78*=aRbUr@5oy!Az>um#lEw?WVxN)+CiHWJU)NAjW z;5(P=_N)q8Im2^Cr<1t2cy*E6{>@n%7x->ilDK)1->#KGx6W7JyWS)yD5$BadG~z( z$LDJfZ3taG%d05gPen!L=IQb!Q$6lonzC%Vr>DE2oSfX0Hixxyybr7kIlL?P*6EhM z2HUMm{AYDLFPa_|8DceKYAhQY+q{0)DZQDu&vh=C=w@SMV{2`=W?BCFc|NyJ*WWx< z_y7O@hEo?}fq|Y=666;Q<kAZ;Obd<-0mh@Fr;B4q#jToCuHlCrB-|c8c(-K&!@_s( zyzbt;EBfjGcb_E_%}#Ef`F(b=V$bS;8^0TNEI*lM+{re#W}mWHM7CGzSuLR-_Kf=r z1kThl?p%;Cp+;GymFf7Sxf=>NSl*>~&9;~LB9O8#>a5@r^9Q^_K`XyVGx#^@cl`BI znZ(avQ*Ssg;WyWs(@#zR<?%Ofd&pW~I$Q6L=@$N`N6LABJ{zmK720!T&MUB+dB&Z` zH$#7gy?|0#bxTZXUO?!5VYjNk9Wk%8)C2BLd~`W;&Md964PWj|T4W%zbXodIt~7J& zIDOl6p9O1U-p@GuWlhG*gbLToFK5`^VSRXob$!STE|KLuXWL3OPAm}Jv1IC|n?l8` zQ7#EK$tFfK*<PDGYP6|6H{-yEmeOTU6*kCpZ%7D`w-svqrkE~nE7(#tSAeba&_7lQ ZhM0gaS6r6QI0=kI22WQ%mvv4FO#s=4*5CjD diff --git a/src/java.desktop/share/classes/sun/awt/resources/security-icon-interim48.png b/src/java.desktop/share/classes/sun/awt/resources/security-icon-interim48.png deleted file mode 100644 index b619966b88da2ef51dfed428ff320b265f70065f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1387 zcmdUt`#Tc~9L9%blIXGYq^K?7=(6ePJZITO6Ee-rwoY{%PlkmQ?L00^8iu*YTsIw3 zi78CCC2^#iTkE*R?rgbj#-`{w)seIFXPozW-uHdp@ALiflSd>R-)y<V5&!^f#`*h@ zjP3rPEzFD=Cg1qjSoR6NrxVEW=Ms{sztaHN$oOy?1b2}dMI+Iuk(cTHG!y_}x`&9T z_<mffC}g5O8LC!3@>V`o&rdKH)p^Uhvc(Vi%L}DCRjxr(vNThupD)(W7U?G03(D*T zMV3~csg<!bl5~wUV_ux55oc&5*&2!Qn5UKIEXWHM<V89~$&%{&lB&kh(NX{5rcPO^ zSKrW0mYbWK>!)uoPFA|Pxh+m{4byjEFqnsjhqJS@VTNyIWo2VyV`5^0Kp>z{sD*`v zy}kXGEn94DZ7nS=muK(3Xgg_VXQvvuA`@kf4>Hv6OJ$-A#aQ~li<E{cTxAZnf{j%v za+`Pof3}c|(=lpAzH)-~;3ff$a?!|nG3O{-!PZIf-VbjP?o|hjzD|}7GJ6CRVSNyV zh&tqcAT2rYNds|8#_kcEoR=20HxkGD6N!O{qBL{?D|kYbQeAM2m+yV2!hfQd{^)j4 zbU0Em%q(Q0&xT@el=!~w$$8#NDb4hvQG+_~kvJ?b$zb~OT(h7S4~N4|O-*ZyeV^SW zm1iG)$`2O3PBb$!YpV+c0)h4A$D98+A?Z)K$?+2pvBdppHAOzR%8p|&m<J7!Wm#UH zo`*Y{Nb|Ca)XR8<C{-gXt>n-W<8ab}<dO_bS2OuqI@;gQJuCIZ^}=JSv8%Gd%V<w0 zVRJb8h*N;yK0X(Bzn(fHuIz51NCq>i^1O|lwASF|Z<7`jl^-TbwaOYvUxK)oE+1sf zNjOu(DN0e&`ue&R@ZPHNRhU2`kd5>ICqVve*CiwGjyNAIg&{2;jkvuNyPd5%NVq5q z935+-Uyune%7lw#r*(n;-5w9*b)9ZCM(O(03l<f;YR_MP(bS6Lz+fDlCu?4$)rz7& z*FDmL`TJ<rLS`pm^2uqlvyHB~W$*}h@IMwCYpI*|3H5ox{ahBC1G>dAuMBISyVe}V zg+_l(3i;fKL;BNy;^Cd4Yim$v!==DsE890kei2_{iPpu-z!r#$7Rq271pMtq5cn4i zBi|sHMt#FF<_;<&fN12)Me~fGIqh>00s|!7^lNV%<bM3oX2Y)7$KbKw!1am^G3ww5 zq&TDl#!UseypD+Z>)a6CckB9wS0_&8v_RBzCxhRBN}!?LP8WcfDrYmn^YqlOe9%I- z!`_|n9(L;YkW-sc(_RStRUmm>cI;qZe^=z{wy>zUYXL({6YzQWEOj!{ab>M5_e@-D z$Q!-jDrG2f*AwZ;g8-}0fjaTB1FX9hc4NCkfgN`3j5k-};0Ifc9D2rJyLUfB2Ehut zeA+HmQ`&^T)N!{NAp2Lj4Pyrm^kH5>WIJ?--PEa0Cs3_xd55b@N7FFbvh&9vw|1NN z<JM32PvGH)qESthS81cZWAYz>nQ^@pv&zgP=aY8&U?sr=e3QbFEB3o7<_-;igLoqB z_my45jXj4OUp~tI6gv(+{EhzbTOw~}1Z*>3!hL7g%Gez_+ePX-^H~%A1^yg>a0#`E TcSGkJQ3v3B2|lgfVXS`v6_*LB diff --git a/src/java.desktop/share/classes/sun/awt/resources/security-icon-yellow16.png b/src/java.desktop/share/classes/sun/awt/resources/security-icon-yellow16.png deleted file mode 100644 index 8dd91a92898a29c3b584f6474cf798a11980bc27..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 477 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!63?wyl`GbL!WQl7;NpOBzNqJ&XDuZK6ep0G} zXKrG8YEWuoN@d~6R2!h8r2#%6u5+3g{(p7(|J&#Pd)xo7%>O?%`2SG*|6TR}ca8qv zR(pF*=kQ{N%NrT~KMsF;N^Z+^hJEuH-d>43zmDPUd8O6;3_E8t{D0&<zm?(bMYp%- zjE*m7IK7%-aR<Zg3x@xnCjY;0w|+9i@@|G3+Ze8GVQ4B8JHJc4p-?Q)*J{};vtVxp zT}>f%b#+r?&G*-J13ma7Lu7heOkJEUU2OPdqy?m;q`VwO{{R24midYu=wS1bAirQB zmkhul5IMISXhgTCi(^Q|t&kH}#SSY7xCUl<+_@WE{`9~7T7gS!=MK+}lnw~I-penr zy!>t)<Kk63l6#Jr2>UnLRJ~bL)1<T3|GCxKe+!cT*d?s_e_$hrWgW-HIf70t7mClS zi6s0MIP`j2Z$AHpH4(G9@3%QG(2e|V8?T#iL9b%{?Sd$-u9-oMkBam{k2Nr<{t``K Zh)9-w^}yo!A)vDuJYD@<);T3K0RU>i=1u?r diff --git a/src/java.desktop/share/classes/sun/awt/resources/security-icon-yellow24.png b/src/java.desktop/share/classes/sun/awt/resources/security-icon-yellow24.png deleted file mode 100644 index 0a3205ff67c358e1f2e1d7475af9334a886710d1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 749 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM3?#3wJbMaANtU=qlmzFem6RtIr7}3C<R_&n zc;+Uirv{}arc@T5OtoQPU{nb332~j>$ngKG%m0t||9^V^e`)srnbH5ZR{tOC{ePhK z|DO8)JF5ThsQ<sK|Nox(>&JHgpJn`i67m0O!v6;j{~vn1KBshgHN(!?4C^N|teL=Y zaXrJaWekFXg6GyUT;0rYcrk;LlG5wTnvRy-uTQHi?`C*?*6`#?hS%rqUf(p>Gml~O zRED|D4D(wVu5V?yv5mpf((?bKfXf>hR`xRNU&!$KYV!Y=m9H;H9@(t$`m~&`uI{!O z3`;s0{=X=Yl$2c9&Y+^A(oi5OF3QEk#B~3%`R(JT4-cu_Kdy0Viz7ET_loJRw~q#& z-yO7iuHK{bM$_7@PHeDXXJ<dWO8xakA1MjmLtFITKeA?HV{@_L`*7d<{Z;LcmrReY z)xUYjdqSh(`8{T@FM9v~|DV^CMHU#K2_->(!9Xr80Yh=_6K9}Z-#uL%Ln?0NoP1u@ zWFXP@Fhh1NQ&55ao$B{{)3-0)J@vCaH*;sxr04GY%&+shEUk(A%6RHb=xR$PmaMG| zoL*n^w#O+o9B2ESad7|6cG*8t1smQRo|P(lUBF)?y!BANq2PWd{qy$QqqygNk8?6O zR#@Nk;ZWhm2dp6(v;MvOy6@r26^fz@HC~;4-mEX`x$;0}>)C11FC*r1ZJ8~$@;m=e zliTSY_fPg7ezDB|!KVACTH9aTij}yNcI6K@zj;&9iH=|M9|>xm7BF2P$KI@NvskEP zlG>GbrC&PJH!&|<Z*O{YetJAhq?>!k$tIuXofnUo7&)*UIkK36nZeqtylq-`syHwR O7(8A5T-G@yGywn=bB$5} diff --git a/src/java.desktop/share/classes/sun/awt/resources/security-icon-yellow32.png b/src/java.desktop/share/classes/sun/awt/resources/security-icon-yellow32.png deleted file mode 100644 index 6e178672b1fe8dad627f677ce8b656ca32dc7af0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 866 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE3?yBabR7dyk|nMYCBgY=CFO}lsSJ)O`AMk? zp1FzXsX?iUDV2pMQ*9U+7##zALR@DzGW`GH`Tvja|G)nKzq<ba<oN%M<^Pvv|KHpG ze`fUmiT?jbI{)vf|G%&K|BmYa+p7QXX#c+p6p#FW&*J|B`~MH!{y*~h|1{zMvovjO zZDV6&W@hI9kAwfeDEa?9_w{4DIZX`nni&KI1($X*oLtGUvX^1)M25>78TQR*SU;KJ z%^97!{qCBYn#Y$j?4HZ8e~s$J4GeECILvQlcyl#r`%H$jYZ;iBnBH9Uy1td+&6U{2 z9Soah$-cQ~zH>Ii@@@t>Ik^kll#VWCu(7dub4p1_Na)Q?!-P=z|1T>~uV&b`%KF+C zh64*37Pc{Lna*%y8^htn44b9`P1Y6{7r(NZ;mujIgDd2HJ!RjVl3O@S_y5Z(E-o$= z6_t*1xg(nu-dqZ1V`B^RQ>`e{e{)go{5l4E8+8FbW<EZ?wi3zJ{Xp%C|NsAIHrRa+ z7~<I_L4LtNE}Z~F#Z1?Sz&Ld9ba4!+xK(p1w5r)bqBZf=J728}LgnSTckbSu`&WNK zGmB@#_q22N=h+iuo_;#We#ExcZ@It8iFBjNjSC*W|N4h_qQh_Ij8^8`Kg1<&vos%7 zPgE4yu~(jDeYC=feL<W4G@j~HI973|L!nGGKVh2J()$b*XKEbRXioIl$MC@<*~amy zYy=;h_n);g?5u~S4SHRc{m9mkVcjJjvn$SD*tuLHLg@UCL?cTTw?jn&E%P~Mf30#} zXJB4XD#v-S&fa5PU$^j-cb;ocE^$38WWC~@oJXKUUr=#)D(kP^w*Bq%s?;u=$^Rav zU3Jd1WW(Ntk!#P~d&gY*wkzD%m$iO+PfTCwpNWk|rM|Og`WQd+((F_yIGCX=l6y_^ zKy%WIITu?W>b>R>b$nnU`0#*&WtA4wROd~CRcaivClz>vTK{qzFf>2=%wI3o1d2ii MPgg&ebxsLQ0Oi)ZdjJ3c diff --git a/src/java.desktop/share/classes/sun/awt/resources/security-icon-yellow48.png b/src/java.desktop/share/classes/sun/awt/resources/security-icon-yellow48.png deleted file mode 100644 index fcbfd7ff567b6da2225d65603b63d5413fcc9001..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1323 zcmdT?{WBDJ9R66^*0!5>-Ckp^l~rqHY45bGmlkcyO034^dPA1FUW9e2T#D#TL!HK@ zh)^hMlT1mML#0CAQWDl~`Id@^nsWEKy}7^Qo|)(K%=63VGtV=h!+`<Ine=bz0KoK> z`p9+a_%CVtx*67ISgjM5a@lHSa7>hPXLy_f#E~%(ig~`<!lM;(MR??{*k*+rfZpGM z{;QUq-VgX$iXXl4iwvhEIK2YN_c**5$Hn-;6JI*v8)tkc!clh|5u%olY90<P!a+M6 z;9~y*d|``y9DHtreG9OUhcEc}LVyDz>|cTdo~RAQK`+#<L$x2i3`e!Z%E}5gavTc4 zSDW#b0yQC2D%HWkfy?FM@HQl|0)e2X8dxlrv9Yn9o}Pt;1%tt0v)NCt1HMia3WZ1# zXfzs~PUmnqrlzJwMn)qV57KN`brSMY;rj2;p@NVA&VzCw4~3+~$IF#T9yzG8fjkaL zO`88_>AYL{&{#E(JQj%EO^OadLz&Ix-=Mn+MxWR}ya<6(qbJv3tkt^Z66ovelYSpQ zpC1~;6}j?t#a_(Rt>uxf7}Dunc^rBhgGgJ@r7RFQEx309BG=pQ-C=w8JoMcCq5U$D zR=@gl5F2UUse=3i@JAt#j*U47tZ$r#;jSg*`O^Gs*V|{oUpjYlgh$~)*dFa&ngM0U zpsf-zlUWoBrT8#dn$h;fS{fJ_kj|e+HSVO_g|x40t$-uDY{-Mf-XbPx=6QH{T+4yx zGH5J;GbvDV1R9ET*B!|tkFKjwlMA(Hpdbw{9MyH0M4q~zO@omkH$<FGtC8qZl`G`| z!8-f@08|^^?*^bSeSO5M5__{d6?@FY=ILs&terCBr!$sY<i(t(MF~6q!;j;97ZLB& zvuBafqbuY4>+&;?Zq2<-dB>N=Px3@A+zEkcl0G%%?X&N~oKK6SxUXb_`ZaG<)%t5| z!Mlp$V|?1WvE%j!;%2PqKVq97W<Ql?{Y%FD)k%`oT}E*i{cVF^j`jBL;JB5?C8R#; z2^$lAW4`{>ZgJwo+%Xfg^(|`G`t+PTa~j&1!{TjPS-ptiIe$wYmD#4s9Vn0_EfLOg z{*)h)wqa@E=l<tP)3<JxX?2wF4wXi@>2RWT`KOta9VYEVjwI10ln%1-ZuLU4Vei7% zU-WNkx7-*IXAN>?f6bDg6o^H_wUb#*$<z-IZtN~)DLn(V(-fDf+BG~O?N-buGvnyN z{SxE2Oh<+D%Hum}b1&uGGz*D}3b|ja%ri`Rf8yNu__<QH)T+^EfL$Hne@*VK%&?Qj z7x}NT@BDZ|GSi~AhO236(tNzSMm(dtW)mwklvQ4q%kVo<`Nq$Vof0%>cF|N=@$}+@ z<0c&8?ekAMdwLo&?!{ekPYy0ol@=6~2GzC3$m+ET)voHZl^b9AI!RsX3Z2Ic8IBX1 z>9f<<vSOo*@4ff-+R?Qq%_(QA%BD@VXVk<XdYCD!Dx8`=O4ZgB4aTP%6jdb8VO-hH n&fZkl*phoFi^+=k%D)5Kzb=yL?dEyu-WhzC1^85Yg{AxhM!3NM diff --git a/src/java.desktop/unix/classes/sun/awt/X11/XBaseWindow.java b/src/java.desktop/unix/classes/sun/awt/X11/XBaseWindow.java index 2b5b78fd027..5bc605cd82b 100644 --- a/src/java.desktop/unix/classes/sun/awt/X11/XBaseWindow.java +++ b/src/java.desktop/unix/classes/sun/awt/X11/XBaseWindow.java @@ -943,13 +943,6 @@ public static void ungrabInput() { void ungrabInputImpl() { } - static void checkSecurity() { - if (XToolkit.isSecurityWarningEnabled() && XToolkit.isToolkitThread()) { - StackTraceElement[] stack = (new Throwable()).getStackTrace(); - log.warning(stack[1] + ": Security violation: calling user code on toolkit thread"); - } - } - public Set<Long> getChildren() { synchronized (getStateLock()) { return new HashSet<Long>(children); diff --git a/src/java.desktop/unix/classes/sun/awt/X11/XDecoratedPeer.java b/src/java.desktop/unix/classes/sun/awt/X11/XDecoratedPeer.java index 102a76b16a7..49515bb2031 100644 --- a/src/java.desktop/unix/classes/sun/awt/X11/XDecoratedPeer.java +++ b/src/java.desktop/unix/classes/sun/awt/X11/XDecoratedPeer.java @@ -112,9 +112,6 @@ void postInit(XCreateWindowParams params) { content = XContentWindow.createContent(this); - if (warningWindow != null) { - warningWindow.toFront(); - } focusProxy = createFocusProxy(); } @@ -843,7 +840,6 @@ && getDecorations() != XWindowAttributesData.AWT_DECOR_NONE) { reconfigureContentWindow(newDimensions); updateChildrenSizes(); - repositionSecurityWarning(); } private void checkShellRectSize(Rectangle shellRect) { diff --git a/src/java.desktop/unix/classes/sun/awt/X11/XEmbedHelper.java b/src/java.desktop/unix/classes/sun/awt/X11/XEmbedHelper.java index 0c2acc44c1c..b4cddacf9a1 100644 --- a/src/java.desktop/unix/classes/sun/awt/X11/XEmbedHelper.java +++ b/src/java.desktop/unix/classes/sun/awt/X11/XEmbedHelper.java @@ -216,7 +216,6 @@ int getModifiers(int state) { // Shouldn't be called on Toolkit thread. AWTKeyStroke getKeyStrokeForKeySym(long keysym, long state) { - XBaseWindow.checkSecurity(); int keycode; diff --git a/src/java.desktop/unix/classes/sun/awt/X11/XKeyboardFocusManagerPeer.java b/src/java.desktop/unix/classes/sun/awt/X11/XKeyboardFocusManagerPeer.java index 2ec736feb29..400f8168f72 100644 --- a/src/java.desktop/unix/classes/sun/awt/X11/XKeyboardFocusManagerPeer.java +++ b/src/java.desktop/unix/classes/sun/awt/X11/XKeyboardFocusManagerPeer.java @@ -79,13 +79,6 @@ public void setCurrentFocusedWindow(Window win) { to = AWTAccessor.getComponentAccessor().getPeer(currentFocusedWindow); } } - - if (from != null) { - from.updateSecurityWarningVisibility(); - } - if (to != null) { - to.updateSecurityWarningVisibility(); - } } @Override diff --git a/src/java.desktop/unix/classes/sun/awt/X11/XScrollPanePeer.java b/src/java.desktop/unix/classes/sun/awt/X11/XScrollPanePeer.java index 8b58fccacb5..bd05dd578c9 100644 --- a/src/java.desktop/unix/classes/sun/awt/X11/XScrollPanePeer.java +++ b/src/java.desktop/unix/classes/sun/awt/X11/XScrollPanePeer.java @@ -272,7 +272,6 @@ void scroll(int x, int y, int flag) { */ @SuppressWarnings("deprecation") void scroll(int x, int y, int flag, int type) { - checkSecurity(); ScrollPane sp = (ScrollPane)target; Component c = getScrollChild(); if (c == null) { diff --git a/src/java.desktop/unix/classes/sun/awt/X11/XToolkit.java b/src/java.desktop/unix/classes/sun/awt/X11/XToolkit.java index 920e1235fca..5a2a849b757 100644 --- a/src/java.desktop/unix/classes/sun/awt/X11/XToolkit.java +++ b/src/java.desktop/unix/classes/sun/awt/X11/XToolkit.java @@ -199,7 +199,6 @@ public final class XToolkit extends UNIXToolkit implements Runnable { private static final X11GraphicsDevice device; private static final long display; static int awt_multiclick_time; - static boolean securityWarningEnabled; /** * Dimensions of default virtual screen in pixels. These values are used to @@ -211,7 +210,6 @@ public final class XToolkit extends UNIXToolkit implements Runnable { private static XMouseInfoPeer xPeer; static { - initSecurityWarning(); if (GraphicsEnvironment.isHeadless()) { localEnv = null; device = null; @@ -240,16 +238,6 @@ static boolean isToolkitThread() { return Thread.currentThread() == toolkitThread; } - static void initSecurityWarning() { - // Enable warning only for internal builds - String runtime = System.getProperty("java.runtime.version"); - securityWarningEnabled = (runtime != null && runtime.contains("internal")); - } - - static boolean isSecurityWarningEnabled() { - return securityWarningEnabled; - } - static native void awt_output_flush(); static void awtFUnlock() { diff --git a/src/java.desktop/unix/classes/sun/awt/X11/XWarningWindow.java b/src/java.desktop/unix/classes/sun/awt/X11/XWarningWindow.java deleted file mode 100644 index ba7359dc5c4..00000000000 --- a/src/java.desktop/unix/classes/sun/awt/X11/XWarningWindow.java +++ /dev/null @@ -1,416 +0,0 @@ -/* - * Copyright (c) 2003, 2021, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package sun.awt.X11; - -import java.awt.*; -import java.awt.geom.Point2D; -import java.lang.ref.WeakReference; - -import sun.awt.IconInfo; -import sun.awt.AWTAccessor; -import sun.awt.SunToolkit; - -class XWarningWindow extends XWindow { - private static final int SHOWING_DELAY = 330; - private static final int HIDING_DELAY = 2000; - - private final Window ownerWindow; - private WeakReference<XWindowPeer> ownerPeer; - private long parentWindow; - - private static final String OWNER = "OWNER"; - private InfoWindow.Tooltip tooltip; - - /** - * Animation stage. - */ - private volatile int currentIcon; - - /* -1 - uninitialized. - * 0 - 16x16 - * 1 - 24x24 - * 2 - 32x32 - * 3 - 48x48 - */ - private int currentSize = -1; - private static IconInfo[][] icons; - private static IconInfo getSecurityIconInfo(int size, int num) { - synchronized (XWarningWindow.class) { - if (icons == null) { - icons = new IconInfo[4][3]; - if (XlibWrapper.dataModel == 32) { - icons[0][0] = new IconInfo(sun.awt.AWTIcon32_security_icon_bw16_png.security_icon_bw16_png); - icons[0][1] = new IconInfo(sun.awt.AWTIcon32_security_icon_interim16_png.security_icon_interim16_png); - icons[0][2] = new IconInfo(sun.awt.AWTIcon32_security_icon_yellow16_png.security_icon_yellow16_png); - icons[1][0] = new IconInfo(sun.awt.AWTIcon32_security_icon_bw24_png.security_icon_bw24_png); - icons[1][1] = new IconInfo(sun.awt.AWTIcon32_security_icon_interim24_png.security_icon_interim24_png); - icons[1][2] = new IconInfo(sun.awt.AWTIcon32_security_icon_yellow24_png.security_icon_yellow24_png); - icons[2][0] = new IconInfo(sun.awt.AWTIcon32_security_icon_bw32_png.security_icon_bw32_png); - icons[2][1] = new IconInfo(sun.awt.AWTIcon32_security_icon_interim32_png.security_icon_interim32_png); - icons[2][2] = new IconInfo(sun.awt.AWTIcon32_security_icon_yellow32_png.security_icon_yellow32_png); - icons[3][0] = new IconInfo(sun.awt.AWTIcon32_security_icon_bw48_png.security_icon_bw48_png); - icons[3][1] = new IconInfo(sun.awt.AWTIcon32_security_icon_interim48_png.security_icon_interim48_png); - icons[3][2] = new IconInfo(sun.awt.AWTIcon32_security_icon_yellow48_png.security_icon_yellow48_png); - } else { - icons[0][0] = new IconInfo(sun.awt.AWTIcon64_security_icon_bw16_png.security_icon_bw16_png); - icons[0][1] = new IconInfo(sun.awt.AWTIcon64_security_icon_interim16_png.security_icon_interim16_png); - icons[0][2] = new IconInfo(sun.awt.AWTIcon64_security_icon_yellow16_png.security_icon_yellow16_png); - icons[1][0] = new IconInfo(sun.awt.AWTIcon64_security_icon_bw24_png.security_icon_bw24_png); - icons[1][1] = new IconInfo(sun.awt.AWTIcon64_security_icon_interim24_png.security_icon_interim24_png); - icons[1][2] = new IconInfo(sun.awt.AWTIcon64_security_icon_yellow24_png.security_icon_yellow24_png); - icons[2][0] = new IconInfo(sun.awt.AWTIcon64_security_icon_bw32_png.security_icon_bw32_png); - icons[2][1] = new IconInfo(sun.awt.AWTIcon64_security_icon_interim32_png.security_icon_interim32_png); - icons[2][2] = new IconInfo(sun.awt.AWTIcon64_security_icon_yellow32_png.security_icon_yellow32_png); - icons[3][0] = new IconInfo(sun.awt.AWTIcon64_security_icon_bw48_png.security_icon_bw48_png); - icons[3][1] = new IconInfo(sun.awt.AWTIcon64_security_icon_interim48_png.security_icon_interim48_png); - icons[3][2] = new IconInfo(sun.awt.AWTIcon64_security_icon_yellow48_png.security_icon_yellow48_png); - } - } - } - final int sizeIndex = size % icons.length; - return icons[sizeIndex][num % icons[sizeIndex].length]; - } - - private void updateIconSize() { - int newSize = -1; - - if (ownerWindow != null) { - Insets insets = ownerWindow.getInsets(); - int max = Math.max(insets.top, Math.max(insets.bottom, - Math.max(insets.left, insets.right))); - if (max < 24) { - newSize = 0; - } else if (max < 32) { - newSize = 1; - } else if (max < 48) { - newSize = 2; - } else { - newSize = 3; - } - } - // Make sure we have a valid size - if (newSize == -1) { - newSize = 0; - } - - // Note: this is not the most wise solution to use awtLock here, - // this should have been sync'ed with the stateLock. However, - // the awtLock must be taken first (see XBaseWindow.getStateLock()), - // and we need the awtLock anyway to update the shape of the icon. - // So it's easier to use just one lock instead. - XToolkit.awtLock(); - try { - if (newSize != currentSize) { - currentSize = newSize; - IconInfo ico = getSecurityIconInfo(currentSize, 0); - XlibWrapper.SetBitmapShape(XToolkit.getDisplay(), getWindow(), - ico.getWidth(), ico.getHeight(), ico.getIntData()); - AWTAccessor.getWindowAccessor().setSecurityWarningSize( - ownerWindow, ico.getWidth(), ico.getHeight()); - } - } finally { - XToolkit.awtUnlock(); - } - } - - private IconInfo getSecurityIconInfo() { - updateIconSize(); - return getSecurityIconInfo(currentSize, currentIcon); - } - - XWarningWindow(final Window ownerWindow, long parentWindow, XWindowPeer ownerPeer) { - super(new XCreateWindowParams(new Object[] { - TARGET, ownerWindow, - OWNER, Long.valueOf(parentWindow) - })); - this.ownerWindow = ownerWindow; - this.parentWindow = parentWindow; - this.tooltip = new InfoWindow.Tooltip(null, getTarget(), - new InfoWindow.Tooltip.LiveArguments() { - public boolean isDisposed() { - return XWarningWindow.this.isDisposed(); - } - public Rectangle getBounds() { - return XWarningWindow.this.getBounds(); - } - public String getTooltipString() { - return XWarningWindow.this.ownerWindow.getWarningString(); - } - }); - this.ownerPeer = new WeakReference<XWindowPeer>(ownerPeer); - } - - private void requestNoTaskbar() { - XNETProtocol netProtocol = XWM.getWM().getNETProtocol(); - if (netProtocol != null) { - netProtocol.requestState(this, netProtocol.XA_NET_WM_STATE_SKIP_TASKBAR, true); - } - } - - @Override - void postInit(XCreateWindowParams params) { - super.postInit(params); - XToolkit.awtLock(); - try { - XWM.setMotifDecor(this, false, 0, 0); - XWM.setOLDecor(this, false, 0); - - long parentWindow = ((Long)params.get(OWNER)).longValue(); - XlibWrapper.XSetTransientFor(XToolkit.getDisplay(), - getWindow(), parentWindow); - - XWMHints hints = getWMHints(); - hints.set_flags(hints.get_flags() | (int)XUtilConstants.InputHint | (int)XUtilConstants.StateHint); - hints.set_input(false); - hints.set_initial_state(XUtilConstants.NormalState); - XlibWrapper.XSetWMHints(XToolkit.getDisplay(), getWindow(), hints.pData); - - initWMProtocols(); - requestNoTaskbar(); - } finally { - XToolkit.awtUnlock(); - } - } - - /** - * @param x,y,w,h coordinates of the untrusted window - */ - public void reposition(int x, int y, int w, int h) { - Point2D point = AWTAccessor.getWindowAccessor(). - calculateSecurityWarningPosition(ownerWindow, - x, y, w, h); - reshape((int)point.getX(), (int)point.getY(), getWidth(), getHeight()); - } - - protected String getWMName() { - return "Warning window"; - } - - public Graphics getGraphics() { - if ((surfaceData == null) || (ownerWindow == null)) return null; - return getGraphics(surfaceData, - getColor(), - getBackground(), - getFont()); - } - void paint(Graphics g, int x, int y, int width, int height) { - g.drawImage(getSecurityIconInfo().getImage(), 0, 0, null); - } - - String getWarningString() { - return ownerWindow.getWarningString(); - } - - int getWidth() { - return getSecurityIconInfo().getWidth(); - } - - int getHeight() { - return getSecurityIconInfo().getHeight(); - } - - Color getBackground() { - return SystemColor.window; - } - Color getColor() { - return Color.black; - } - Font getFont () { - return ownerWindow.getFont(); - } - - @Override - public void repaint() { - final Rectangle bounds = getBounds(); - final Graphics g = getGraphics(); - if (g != null) { - try { - paint(g, 0, 0, bounds.width, bounds.height); - } finally { - g.dispose(); - } - } - } - @Override - public void handleExposeEvent(XEvent xev) { - super.handleExposeEvent(xev); - - XExposeEvent xe = xev.get_xexpose(); - final int x = scaleDown(xe.get_x()); - final int y = scaleDown(xe.get_y()); - final int width = scaleDown(xe.get_width()); - final int height = scaleDown(xe.get_height()); - SunToolkit.executeOnEventHandlerThread(target, - new Runnable() { - public void run() { - final Graphics g = getGraphics(); - if (g != null) { - try { - paint(g, x, y, width, height); - } finally { - g.dispose(); - } - } - } - }); - } - - @Override - protected boolean isEventDisabled(XEvent e) { - return true; - } - - /** Send a synthetic UnmapNotify in order to withdraw the window. - */ - private void withdraw() { - XEvent req = new XEvent(); - try { - long root; - XToolkit.awtLock(); - try { - root = XlibWrapper.RootWindow(XToolkit.getDisplay(), getScreenNumber()); - } - finally { - XToolkit.awtUnlock(); - } - - req.set_type(XConstants.UnmapNotify); - - XUnmapEvent umev = req.get_xunmap(); - - umev.set_event(root); - umev.set_window(getWindow()); - umev.set_from_configure(false); - - XToolkit.awtLock(); - try { - XlibWrapper.XSendEvent(XToolkit.getDisplay(), - root, - false, - XConstants.SubstructureRedirectMask | XConstants.SubstructureNotifyMask, - req.pData); - } - finally { - XToolkit.awtUnlock(); - } - } finally { - req.dispose(); - } - } - - @Override - protected void stateChanged(long time, int oldState, int newState) { - if (newState == XUtilConstants.IconicState) { - super.xSetVisible(false); - withdraw(); - } - } - - @Override - protected void setMouseAbove(boolean above) { - super.setMouseAbove(above); - XWindowPeer p = ownerPeer.get(); - if (p != null) { - p.updateSecurityWarningVisibility(); - } - } - - @Override - protected void enterNotify(long window) { - super.enterNotify(window); - if (window == getWindow()) { - tooltip.enter(); - } - } - - @Override - protected void leaveNotify(long window) { - super.leaveNotify(window); - if (window == getWindow()) { - tooltip.exit(); - } - } - - @Override - public void xSetVisible(boolean visible) { - super.xSetVisible(visible); - - // The _NET_WM_STATE_SKIP_TASKBAR got reset upon hiding/showing, - // so we request it every time whenever we change the visibility. - requestNoTaskbar(); - } - - private final Runnable hidingTask = new Runnable() { - public void run() { - xSetVisible(false); - } - }; - - private final Runnable showingTask = new Runnable() { - public void run() { - if (!isVisible()) { - xSetVisible(true); - updateIconSize(); - XWindowPeer peer = ownerPeer.get(); - if (peer != null) { - peer.repositionSecurityWarning(); - } - } - repaint(); - if (currentIcon > 0) { - currentIcon--; - XToolkit.schedule(showingTask, SHOWING_DELAY); - } - } - }; - - public void setSecurityWarningVisible(boolean visible, boolean doSchedule) { - if (visible) { - XToolkit.remove(hidingTask); - XToolkit.remove(showingTask); - if (isVisible()) { - currentIcon = 0; - } else { - currentIcon = 3; - } - if (doSchedule) { - XToolkit.schedule(showingTask, 1); - } else { - showingTask.run(); - } - } else { - XToolkit.remove(showingTask); - XToolkit.remove(hidingTask); - if (!isVisible()) { - return; - } - if (doSchedule) { - XToolkit.schedule(hidingTask, HIDING_DELAY); - } else { - hidingTask.run(); - } - } - } -} diff --git a/src/java.desktop/unix/classes/sun/awt/X11/XWindow.java b/src/java.desktop/unix/classes/sun/awt/X11/XWindow.java index 38e35bdbeea..3ade95f5870 100644 --- a/src/java.desktop/unix/classes/sun/awt/X11/XWindow.java +++ b/src/java.desktop/unix/classes/sun/awt/X11/XWindow.java @@ -1488,8 +1488,8 @@ public void postKeyEvent(int id, int keyCode, int keyChar, static native int getKeySymForAWTKeyCode(int keycode); /* These two methods are actually applicable to toplevel windows only. - * However, the functionality is required by both the XWindowPeer and - * XWarningWindow, both of which have the XWindow as a common ancestor. + * However, the functionality is required by XWindowPeer + * which has XWindow as an ancestor. * See XWM.setMotifDecor() for details. */ public PropMwmHints getMWMHints() { diff --git a/src/java.desktop/unix/classes/sun/awt/X11/XWindowPeer.java b/src/java.desktop/unix/classes/sun/awt/X11/XWindowPeer.java index ebd04f2b7dd..573d98390b4 100644 --- a/src/java.desktop/unix/classes/sun/awt/X11/XWindowPeer.java +++ b/src/java.desktop/unix/classes/sun/awt/X11/XWindowPeer.java @@ -79,7 +79,6 @@ class XWindowPeer extends XPanelPeer implements WindowPeer, private boolean cachedFocusableWindow; - XWarningWindow warningWindow; private boolean alwaysOnTop; private boolean locationByPlatform; @@ -277,15 +276,6 @@ void postInit(XCreateWindowParams params) { } } - // Init warning window(for applets) - if (((Window)target).getWarningString() != null) { - // accessSystemTray permission allows to display TrayIcon, TrayIcon tooltip - // and TrayIcon balloon windows without a warning window. - if (!AWTAccessor.getWindowAccessor().isTrayIconWindow((Window)target)) { - warningWindow = new XWarningWindow((Window)target, getWindow(), this); - } - } - setSaveUnder(true); updateIconImages(); @@ -502,9 +492,6 @@ public void setBounds(int x, int y, int width, int height, int op) { boolean isResized = !bounds.getSize().equals(oldBounds.getSize()); boolean isMoved = !bounds.getLocation().equals(oldBounds.getLocation()); - if (isMoved || isResized) { - repositionSecurityWarning(); - } if (isResized) { postEventToEventQueue(new ComponentEvent(getEventSource(), ComponentEvent.COMPONENT_RESIZED)); } @@ -807,7 +794,6 @@ public void handleConfigureNotifyEvent(XEvent xev) { AWTAccessor.getComponentAccessor().setLocation(target, x, y); postEvent(new ComponentEvent(target, ComponentEvent.COMPONENT_MOVED)); } - repositionSecurityWarning(); } final void requestXFocus(long time) { @@ -1101,9 +1087,6 @@ public void setVisible(boolean vis) { } updateFocusability(); promoteDefaultPosition(); - if (!vis && warningWindow != null) { - warningWindow.setSecurityWarningVisible(false, false); - } boolean refreshChildsTransientFor = isVisible() != vis; super.setVisible(vis); if (refreshChildsTransientFor) { @@ -1153,7 +1136,6 @@ public void setVisible(boolean vis) { if (isOverrideRedirect() && vis) { updateChildrenSizes(); } - repositionSecurityWarning(); } protected void suppressWmTakeFocus(boolean doSuppress) { @@ -1162,9 +1144,6 @@ protected void suppressWmTakeFocus(boolean doSuppress) { final boolean isSimpleWindow() { return !(target instanceof Frame || target instanceof Dialog); } - boolean hasWarningWindow() { - return ((Window)target).getWarningString() != null; - } // The height of menu bar window int getMenuBarHeight() { @@ -1176,68 +1155,14 @@ int getMenuBarHeight() { void updateChildrenSizes() { } - public void repositionSecurityWarning() { - // NOTE: On KWin if the window/border snapping option is enabled, - // the Java window may be swinging while it's being moved. - // This doesn't make the application unusable though looks quite ugly. - // Probably we need to find some hint to assign to our Security - // Warning window in order to exclude it from the snapping option. - // We are not currently aware of existence of such a property. - if (warningWindow != null) { - // We can't use the coordinates stored in the XBaseWindow since - // they are zeros for decorated frames. - ComponentAccessor compAccessor = AWTAccessor.getComponentAccessor(); - int x = compAccessor.getX(target); - int y = compAccessor.getY(target); - int width = compAccessor.getWidth(target); - int height = compAccessor.getHeight(target); - warningWindow.reposition(x, y, width, height); - } - } - @Override protected void setMouseAbove(boolean above) { super.setMouseAbove(above); - updateSecurityWarningVisibility(); } @Override public void setFullScreenExclusiveModeState(boolean state) { super.setFullScreenExclusiveModeState(state); - updateSecurityWarningVisibility(); - } - - public void updateSecurityWarningVisibility() { - if (warningWindow == null) { - return; - } - - if (!isVisible()) { - return; // The warning window should already be hidden. - } - - boolean show = false; - - if (!isFullScreenExclusiveMode()) { - int state = getWMState(); - - // getWMState() always returns 0 (Withdrawn) for simple windows. Hence - // we ignore the state for such windows. - if (isVisible() && (state == XUtilConstants.NormalState || isSimpleWindow())) { - if (XKeyboardFocusManagerPeer.getInstance().getCurrentFocusedWindow() == - getTarget()) - { - show = true; - } - - if (isMouseAbove() || warningWindow.isMouseAbove()) - { - show = true; - } - } - } - - warningWindow.setSecurityWarningVisible(show, true); } boolean isOverrideRedirect() { @@ -1266,10 +1191,6 @@ public void dispose() { SunToolkit.awtUnlock(); } - if (warningWindow != null) { - warningWindow.destroy(); - } - removeRootPropertyEventDispatcher(); mustControlStackPosition = false; super.dispose(); @@ -1299,7 +1220,6 @@ public void handleVisibilityEvent(XEvent xev) { // if (ve.get_state() == XlibWrapper.VisibilityUnobscured) { // // raiseInputMethodWindow // } - repositionSecurityWarning(); } void handleRootPropertyNotify(XEvent xev) { @@ -1475,8 +1395,6 @@ protected void stateChanged(long time, int oldState, int newState) { for (ToplevelStateListener topLevelListenerTmp : toplevelStateListeners) { topLevelListenerTmp.stateChangedICCCM(oldState, newState); } - - updateSecurityWarningVisibility(); } boolean isWithdrawn() { diff --git a/src/java.desktop/windows/classes/sun/awt/windows/WWindowPeer.java b/src/java.desktop/windows/classes/sun/awt/windows/WWindowPeer.java index 7b82229c02c..af1b77198c7 100644 --- a/src/java.desktop/windows/classes/sun/awt/windows/WWindowPeer.java +++ b/src/java.desktop/windows/classes/sun/awt/windows/WWindowPeer.java @@ -651,17 +651,10 @@ public void ungrab() { private native void nativeGrab(); private native void nativeUngrab(); - private boolean hasWarningWindow() { - return ((Window)target).getWarningString() != null; - } - boolean isTargetUndecorated() { return true; } - @Override - public native void repositionSecurityWarning(); - @Override public void print(Graphics g) { // We assume we print the whole frame, diff --git a/src/java.desktop/windows/native/libawt/windows/awt.rc b/src/java.desktop/windows/native/libawt/windows/awt.rc index 3bc072180d4..36981f35f67 100644 --- a/src/java.desktop/windows/native/libawt/windows/awt.rc +++ b/src/java.desktop/windows/native/libawt/windows/awt.rc @@ -27,10 +27,3 @@ AWT_ICON ICON DISCARDABLE "awt.ico" CHECK_BITMAP BITMAP DISCARDABLE "check.bmp" - -// Note: the number of icons used is specified in the -// securityWarningIconCounter constant in awt_Toolkit.cpp. -SECURITY_WARNING_0 ICON DISCARDABLE "security_warning_bw.ico" -SECURITY_WARNING_1 ICON DISCARDABLE "security_warning_int.ico" -SECURITY_WARNING_2 ICON DISCARDABLE "security_warning.ico" - diff --git a/src/java.desktop/windows/native/libawt/windows/awt_Component.cpp b/src/java.desktop/windows/native/libawt/windows/awt_Component.cpp index 640b06d0521..c49c2265ca3 100644 --- a/src/java.desktop/windows/native/libawt/windows/awt_Component.cpp +++ b/src/java.desktop/windows/native/libawt/windows/awt_Component.cpp @@ -6420,10 +6420,7 @@ void AwtComponent::PostUngrabEvent() { void AwtComponent::SetFocusedWindow(HWND window) { - HWND old = sm_focusedWindow; sm_focusedWindow = window; - - AwtWindow::FocusedWindowChanged(old, window); } /************************************************************************ diff --git a/src/java.desktop/windows/native/libawt/windows/awt_Frame.cpp b/src/java.desktop/windows/native/libawt/windows/awt_Frame.cpp index 9ca12aa5802..e679eb88dd2 100644 --- a/src/java.desktop/windows/native/libawt/windows/awt_Frame.cpp +++ b/src/java.desktop/windows/native/libawt/windows/awt_Frame.cpp @@ -910,9 +910,6 @@ MsgRouting AwtFrame::WmWindowPosChanging(LPARAM windowPos) { MsgRouting AwtFrame::WmSize(UINT type, int w, int h) { currentWmSizeState = type; - if (currentWmSizeState == SIZE_MINIMIZED) { - UpdateSecurityWarningVisibility(); - } if (m_ignoreWmSize) { return mrDoDefault; diff --git a/src/java.desktop/windows/native/libawt/windows/awt_Toolkit.cpp b/src/java.desktop/windows/native/libawt/windows/awt_Toolkit.cpp index b467a685516..4de63a19e30 100644 --- a/src/java.desktop/windows/native/libawt/windows/awt_Toolkit.cpp +++ b/src/java.desktop/windows/native/libawt/windows/awt_Toolkit.cpp @@ -1438,24 +1438,6 @@ LRESULT CALLBACK AwtToolkit::MouseLowLevelHook(int code, } tk.m_lastWindowUnderMouse = hwnd; - - if (fw) { - fw->UpdateSecurityWarningVisibility(); - } - // ... however, because we use GA_ROOT, we may find the warningIcon - // which is not a Java windows. - if (AwtWindow::IsWarningWindow(hwnd)) { - hwnd = ::GetParent(hwnd); - if (hwnd) { - tw = (AwtWindow*)AwtComponent::GetComponent(hwnd); - } - tk.m_lastWindowUnderMouse = hwnd; - } - if (tw) { - tw->UpdateSecurityWarningVisibility(); - } - - } } @@ -1909,48 +1891,6 @@ HICON AwtToolkit::GetAwtIconSm() return defaultIconSm; } -// The icon at index 0 must be gray. See AwtWindow::GetSecurityWarningIcon() -HICON AwtToolkit::GetSecurityWarningIcon(UINT index, UINT w, UINT h) -{ - //Note: should not exceed 10 because of the current implementation. - static const int securityWarningIconCounter = 3; - - static HICON securityWarningIcon[securityWarningIconCounter] = {NULL, NULL, NULL}; - static UINT securityWarningIconWidth[securityWarningIconCounter] = {0, 0, 0}; - static UINT securityWarningIconHeight[securityWarningIconCounter] = {0, 0, 0}; - - index = AwtToolkit::CalculateWave(index, securityWarningIconCounter); - - if (securityWarningIcon[index] == NULL || - w != securityWarningIconWidth[index] || - h != securityWarningIconHeight[index]) - { - if (securityWarningIcon[index] != NULL) - { - ::DestroyIcon(securityWarningIcon[index]); - } - - static const wchar_t securityWarningIconName[] = L"SECURITY_WARNING_"; - wchar_t iconResourceName[sizeof(securityWarningIconName) + 2]; - ::ZeroMemory(iconResourceName, sizeof(iconResourceName)); - wcscpy(iconResourceName, securityWarningIconName); - - wchar_t strIndex[2]; - ::ZeroMemory(strIndex, sizeof(strIndex)); - strIndex[0] = L'0' + index; - - wcscat(iconResourceName, strIndex); - - securityWarningIcon[index] = (HICON)::LoadImage(GetModuleHandle(), - iconResourceName, - IMAGE_ICON, w, h, LR_DEFAULTCOLOR); - securityWarningIconWidth[index] = w; - securityWarningIconHeight[index] = h; - } - - return securityWarningIcon[index]; -} - void throw_if_shutdown(void) { AwtToolkit::GetInstance().VerifyActive(); diff --git a/src/java.desktop/windows/native/libawt/windows/awt_Toolkit.h b/src/java.desktop/windows/native/libawt/windows/awt_Toolkit.h index 29485c8ba41..d2adeca6776 100644 --- a/src/java.desktop/windows/native/libawt/windows/awt_Toolkit.h +++ b/src/java.desktop/windows/native/libawt/windows/awt_Toolkit.h @@ -394,8 +394,6 @@ class AwtToolkit { return value; } - HICON GetSecurityWarningIcon(UINT index, UINT w, UINT h); - /* Turns on/off dialog modality for the system. */ INLINE AwtDialog* SetModal(AwtDialog* frame) { AwtDialog* previousDialog = m_pModalDialog; diff --git a/src/java.desktop/windows/native/libawt/windows/awt_Window.cpp b/src/java.desktop/windows/native/libawt/windows/awt_Window.cpp index a135d6f0113..9eb6cb51c7b 100644 --- a/src/java.desktop/windows/native/libawt/windows/awt_Window.cpp +++ b/src/java.desktop/windows/native/libawt/windows/awt_Window.cpp @@ -137,10 +137,6 @@ struct RequestWindowFocusStruct { jobject component; jboolean isMouseEventCause; }; -// struct for _RepositionSecurityWarning() method -struct RepositionSecurityWarningStruct { - jobject window; -}; struct SetFullScreenExclusiveModeStateStruct { jobject window; @@ -156,24 +152,18 @@ struct OverrideHandle { * AwtWindow fields */ -jfieldID AwtWindow::warningStringID; jfieldID AwtWindow::locationByPlatformID; jfieldID AwtWindow::autoRequestFocusID; -jfieldID AwtWindow::securityWarningWidthID; -jfieldID AwtWindow::securityWarningHeightID; jfieldID AwtWindow::windowTypeID; jmethodID AwtWindow::notifyWindowStateChangedMID; -jmethodID AwtWindow::getWarningStringMID; -jmethodID AwtWindow::calculateSecurityWarningPositionMID; jmethodID AwtWindow::windowTypeNameMID; int AwtWindow::ms_instanceCounter = 0; HHOOK AwtWindow::ms_hCBTFilter; AwtWindow * AwtWindow::m_grabbedWindow = NULL; BOOL AwtWindow::sm_resizing = FALSE; -UINT AwtWindow::untrustedWindowsCounter = 0; /************************************************************************ * AwtWindow class methods @@ -189,7 +179,6 @@ AwtWindow::AwtWindow() { m_iconInherited = FALSE; VERIFY(::SetRectEmpty(&m_insets)); VERIFY(::SetRectEmpty(&m_old_insets)); - VERIFY(::SetRectEmpty(&m_warningRect)); // what's the best initial value? m_screenNum = -1; @@ -208,11 +197,6 @@ AwtWindow::AwtWindow() { m_opaque = TRUE; m_opacity = 0xff; - - warningString = NULL; - warningWindow = NULL; - securityTooltipWindow = NULL; - securityWarningAnimationStage = 0; currentWmSizeState = SIZE_RESTORED; hContentBitmap = NULL; @@ -232,9 +216,6 @@ AwtWindow::AwtWindow() { AwtWindow::~AwtWindow() { - if (warningString != NULL) { - delete [] warningString; - } DeleteContentBitmap(); ::DeleteCriticalSection(&contentBitmapCS); } @@ -355,19 +336,6 @@ MsgRouting AwtWindow::WmWindowPosChanging(LPARAM windowPos) { return mrDoDefault; } -void AwtWindow::RepositionSecurityWarning(JNIEnv *env) -{ - RECT rect; - CalculateWarningWindowBounds(env, &rect); - - ::SetWindowPos(warningWindow, IsAlwaysOnTop() ? HWND_TOPMOST : HWND_NOTOPMOST, - rect.left, rect.top, - rect.right - rect.left, rect.bottom - rect.top, - SWP_ASYNCWINDOWPOS | SWP_NOACTIVATE | - SWP_NOOWNERZORDER - ); -} - MsgRouting AwtWindow::WmWindowPosChanged(LPARAM windowPos) { WINDOWPOS * wp = (WINDOWPOS *)windowPos; @@ -385,19 +353,6 @@ MsgRouting AwtWindow::WmWindowPosChanged(LPARAM windowPos) { prevScaleRec.scaleY = -1.0f; } - // Reposition the warning window - if (IsUntrusted() && warningWindow != NULL) { - if (wp->flags & SWP_HIDEWINDOW) { - UpdateSecurityWarningVisibility(); - } - - RepositionSecurityWarning((JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2)); - - if (wp->flags & SWP_SHOWWINDOW) { - UpdateSecurityWarningVisibility(); - } - } - if (wp->flags & SWP_HIDEWINDOW) { EnableTranslucency(FALSE); } @@ -424,29 +379,13 @@ void AwtWindow::FillClassInfo(WNDCLASSEX *lpwc) lpwc->cbWndExtra = DLGWINDOWEXTRA; } -bool AwtWindow::IsWarningWindow(HWND hWnd) -{ - const UINT len = 128; - TCHAR windowClassName[len]; - - ::RealGetWindowClass(hWnd, windowClassName, len); - return 0 == _tcsncmp(windowClassName, - AwtWindow::GetWarningWindowClassName(), len); -} - LRESULT CALLBACK AwtWindow::CBTFilter(int nCode, WPARAM wParam, LPARAM lParam) { if (nCode == HCBT_ACTIVATE || nCode == HCBT_SETFOCUS) { HWND hWnd = (HWND)wParam; AwtComponent *comp = AwtComponent::GetComponent(hWnd); - if (comp == NULL) { - // Check if it's a security warning icon - // See: 5091224, 6181725, 6732583 - if (AwtWindow::IsWarningWindow(hWnd)) { - return 1; - } - } else { + if (comp != NULL) { if (comp->IsTopLevel()) { AwtWindow* win = (AwtWindow*)comp; @@ -461,21 +400,6 @@ LRESULT CALLBACK AwtWindow::CBTFilter(int nCode, WPARAM wParam, LPARAM lParam) return ::CallNextHookEx(AwtWindow::ms_hCBTFilter, nCode, wParam, lParam); } -void AwtWindow::InitSecurityWarningSize(JNIEnv *env) -{ - warningWindowWidth = ::GetSystemMetrics(SM_CXSMICON); - warningWindowHeight = ::GetSystemMetrics(SM_CYSMICON); - - jobject target = GetTarget(env); - - env->SetIntField(target, AwtWindow::securityWarningWidthID, - warningWindowWidth); - env->SetIntField(target, AwtWindow::securityWarningHeightID, - warningWindowHeight); - - env->DeleteLocalRef(target); -} - void AwtWindow::CreateHWnd(JNIEnv *env, LPCWSTR title, DWORD windowStyle, DWORD windowExStyle, @@ -485,25 +409,6 @@ void AwtWindow::CreateHWnd(JNIEnv *env, LPCWSTR title, COLORREF colorBackground, jobject peer) { - // Retrieve the warning string - // Note: we need to get it before CreateHWnd() happens because - // the isUntrusted() method may be invoked while the HWND - // is being created in response to some window messages. - jobject target = env->GetObjectField(peer, AwtObject::targetID); - jstring javaWarningString = - (jstring)env->CallObjectMethod(target, AwtWindow::getWarningStringMID); - - if (javaWarningString != NULL) { - size_t length = env->GetStringLength(javaWarningString) + 1; - warningString = new WCHAR[length]; - env->GetStringRegion(javaWarningString, 0, - static_cast<jsize>(length - 1), reinterpret_cast<jchar*>(warningString)); - warningString[length-1] = L'\0'; - - env->DeleteLocalRef(javaWarningString); - } - env->DeleteLocalRef(target); - InitType(env, peer); JNU_CHECK_EXCEPTION(env); @@ -517,330 +422,13 @@ void AwtWindow::CreateHWnd(JNIEnv *env, LPCWSTR title, colorForeground, colorBackground, peer); - - // Now we need to create the warning window. - CreateWarningWindow(env); -} - -void AwtWindow::CreateWarningWindow(JNIEnv *env) -{ - if (!IsUntrusted()) { - return; - } - - if (++AwtWindow::untrustedWindowsCounter == 1) { - AwtToolkit::GetInstance().InstallMouseLowLevelHook(); - } - - InitSecurityWarningSize(env); - - RECT rect; - CalculateWarningWindowBounds(env, &rect); - - RegisterWarningWindowClass(); - warningWindow = ::CreateWindowEx( - WS_EX_NOACTIVATE, - GetWarningWindowClassName(), - warningString, - WS_POPUP, - rect.left, rect.top, - rect.right - rect.left, rect.bottom - rect.top, - GetHWnd(), // owner - NULL, // menu - AwtToolkit::GetInstance().GetModuleHandle(), - NULL // lParam - ); - if (warningWindow == NULL) { - //XXX: actually this is bad... We didn't manage to create the window. - return; - } - - HICON hIcon = GetSecurityWarningIcon(); - - ICONINFO ii; - ::GetIconInfo(hIcon, &ii); - - //Note: we assume that every security icon has exactly the same shape. - HRGN rgn = BitmapUtil::BitmapToRgn(ii.hbmColor); - if (rgn) { - ::SetWindowRgn(warningWindow, rgn, TRUE); - } - - // Now we need to create the tooltip control for this window. - if (!ComCtl32Util::GetInstance().IsToolTipControlInitialized()) { - return; - } - - securityTooltipWindow = ::CreateWindowEx( - WS_EX_TOPMOST, - TOOLTIPS_CLASS, - NULL, - WS_POPUP | TTS_NOPREFIX | TTS_ALWAYSTIP, - CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, - warningWindow, - NULL, - AwtToolkit::GetInstance().GetModuleHandle(), - NULL - ); - - ::SetWindowPos(securityTooltipWindow, - HWND_TOPMOST, 0, 0, 0, 0, - SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE); - - - // We currently don't expect changing the size of the window, - // hence we may not care of updating the TOOL position/size. - ::GetClientRect(warningWindow, &rect); - - TOOLINFO ti; - - ti.cbSize = sizeof(ti); - ti.uFlags = TTF_SUBCLASS; - ti.hwnd = warningWindow; - ti.hinst = AwtToolkit::GetInstance().GetModuleHandle(); - ti.uId = 0; - ti.lpszText = warningString; - ti.rect.left = rect.left; - ti.rect.top = rect.top; - ti.rect.right = rect.right; - ti.rect.bottom = rect.bottom; - - ::SendMessage(securityTooltipWindow, TTM_ADDTOOL, - 0, (LPARAM) (LPTOOLINFO) &ti); -} - -void AwtWindow::DestroyWarningWindow() -{ - if (!IsUntrusted()) { - return; - } - if (--AwtWindow::untrustedWindowsCounter == 0) { - AwtToolkit::GetInstance().UninstallMouseLowLevelHook(); - } - if (warningWindow != NULL) { - // Note that the warningWindow is an owned window, and hence - // it would be destroyed automatically. However, the window - // class may only be unregistered if there's no any single - // window left using this class. Thus, we're destroying the - // warning window manually. Note that the tooltip window - // will be destroyed automatically because it's an owned - // window as well. - ::DestroyWindow(warningWindow); - warningWindow = NULL; - securityTooltipWindow = NULL; - UnregisterWarningWindowClass(); - } } void AwtWindow::DestroyHWnd() { - DestroyWarningWindow(); AwtCanvas::DestroyHWnd(); } -LPCTSTR AwtWindow::GetWarningWindowClassName() -{ - return TEXT("SunAwtWarningWindow"); -} - -void AwtWindow::FillWarningWindowClassInfo(WNDCLASS *lpwc) -{ - lpwc->style = 0L; - lpwc->lpfnWndProc = (WNDPROC)WarningWindowProc; - lpwc->cbClsExtra = 0; - lpwc->cbWndExtra = 0; - lpwc->hInstance = AwtToolkit::GetInstance().GetModuleHandle(), - lpwc->hIcon = AwtToolkit::GetInstance().GetAwtIcon(); - lpwc->hCursor = ::LoadCursor(NULL, IDC_ARROW); - lpwc->hbrBackground = NULL; - lpwc->lpszMenuName = NULL; - lpwc->lpszClassName = AwtWindow::GetWarningWindowClassName(); -} - -void AwtWindow::RegisterWarningWindowClass() -{ - WNDCLASS wc; - - ::ZeroMemory(&wc, sizeof(wc)); - - if (!::GetClassInfo(AwtToolkit::GetInstance().GetModuleHandle(), - AwtWindow::GetWarningWindowClassName(), &wc)) - { - AwtWindow::FillWarningWindowClassInfo(&wc); - ATOM atom = ::RegisterClass(&wc); - DASSERT(atom != 0); - } -} - -void AwtWindow::UnregisterWarningWindowClass() -{ - ::UnregisterClass(AwtWindow::GetWarningWindowClassName(), AwtToolkit::GetInstance().GetModuleHandle()); -} - -HICON AwtWindow::GetSecurityWarningIcon() -{ - // It is assumed that the icon at index 0 is gray - const UINT index = securityAnimationKind == akShow ? - securityWarningAnimationStage : 0; - HICON ico = AwtToolkit::GetInstance().GetSecurityWarningIcon(index, - warningWindowWidth, warningWindowHeight); - return ico; -} - -// This function calculates the bounds of the warning window and stores them -// into the RECT structure pointed by the argument rect. -void AwtWindow::CalculateWarningWindowBounds(JNIEnv *env, LPRECT rect) -{ - RECT windowBounds; - AwtToolkit::GetWindowRect(GetHWnd(), &windowBounds); - - jobject target = GetTarget(env); - jobject point2D = env->CallObjectMethod(target, - calculateSecurityWarningPositionMID, - (jdouble)windowBounds.left, (jdouble)windowBounds.top, - (jdouble)(windowBounds.right - windowBounds.left), - (jdouble)(windowBounds.bottom - windowBounds.top)); - env->DeleteLocalRef(target); - - static jclass point2DClassID = NULL; - static jmethodID point2DGetXMID = NULL; - static jmethodID point2DGetYMID = NULL; - - if (point2DClassID == NULL) { - jclass point2DClassIDLocal = env->FindClass("java/awt/geom/Point2D"); - if (point2DClassIDLocal == NULL) { - env->DeleteLocalRef(point2D); - return; - } - point2DClassID = (jclass)env->NewGlobalRef(point2DClassIDLocal); - env->DeleteLocalRef(point2DClassIDLocal); - } - - if (point2DGetXMID == NULL) { - point2DGetXMID = env->GetMethodID(point2DClassID, "getX", "()D"); - if (point2DGetXMID == NULL) { - env->DeleteLocalRef(point2D); - return; - } - } - if (point2DGetYMID == NULL) { - point2DGetYMID = env->GetMethodID(point2DClassID, "getY", "()D"); - if (point2DGetYMID == NULL) { - env->DeleteLocalRef(point2D); - return; - } - } - - - int x = (int)env->CallDoubleMethod(point2D, point2DGetXMID); - int y = (int)env->CallDoubleMethod(point2D, point2DGetYMID); - - env->DeleteLocalRef(point2D); - - rect->left = x; - rect->top = y; - rect->right = rect->left + warningWindowWidth; - rect->bottom = rect->top + warningWindowHeight; -} - -LRESULT CALLBACK AwtWindow::WarningWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) -{ - switch (uMsg) { - case WM_PAINT: - PaintWarningWindow(hwnd); - return 0; - - case WM_MOUSEACTIVATE: - { - // Retrieve the owner of the warning window. - HWND javaWindow = ::GetParent(hwnd); - if (javaWindow) { - // If the window is blocked by a modal dialog, substitute - // its handle with the topmost blocker. - HWND topmostBlocker = GetTopmostModalBlocker(javaWindow); - if (::IsWindow(topmostBlocker)) { - javaWindow = topmostBlocker; - } - - ::BringWindowToTop(javaWindow); - - AwtWindow * window = - (AwtWindow*)AwtComponent::GetComponent(javaWindow); - if (window == NULL) { - // Quite unlikely to go into here, but it's way better - // than getting a crash. - ::SetForegroundWindow(javaWindow); - } else { - // Activate the window if it is focusable and inactive - if (window->IsFocusableWindow() && - javaWindow != ::GetActiveWindow()) { - ::SetForegroundWindow(javaWindow); - } else { - // ...otherwise just start the animation. - window->StartSecurityAnimation(akShow); - } - } - - // In every case if there's a top-most blocker, we need to - // enable modal animation. - if (::IsWindow(topmostBlocker)) { - AwtDialog::AnimateModalBlocker(topmostBlocker); - } - } - return MA_NOACTIVATEANDEAT; - } - } - return ::DefWindowProc(hwnd, uMsg, wParam, lParam); -} - -void AwtWindow::PaintWarningWindow(HWND warningWindow) -{ - RECT updateRect; - - if (!::GetUpdateRect(warningWindow, &updateRect, FALSE)) { - // got nothing to update - return; - } - - PAINTSTRUCT ps; - HDC hdc = ::BeginPaint(warningWindow, &ps); - if (hdc == NULL) { - // indicates an error - return; - } - - PaintWarningWindow(warningWindow, hdc); - - ::EndPaint(warningWindow, &ps); -} - -void AwtWindow::PaintWarningWindow(HWND warningWindow, HDC hdc) -{ - HWND javaWindow = ::GetParent(warningWindow); - - AwtWindow * window = (AwtWindow*)AwtComponent::GetComponent(javaWindow); - if (window == NULL) { - return; - } - - ::DrawIconEx(hdc, 0, 0, window->GetSecurityWarningIcon(), - window->warningWindowWidth, window->warningWindowHeight, - 0, NULL, DI_NORMAL); -} - -static const UINT_PTR IDT_AWT_SECURITYANIMATION = 0x102; - -// Approximately 6 times a second. 0.75 seconds total. -static const UINT securityAnimationTimerElapse = 150; -static const UINT securityAnimationMaxIterations = 5; - -void AwtWindow::RepaintWarningWindow() -{ - HDC hdc = ::GetDC(warningWindow); - PaintWarningWindow(warningWindow, hdc); - ::ReleaseDC(warningWindow, hdc); -} - void AwtWindow::SetLayered(HWND window, bool layered) { const LONG ex_style = ::GetWindowLong(window, GWL_EXSTYLE); @@ -854,195 +442,9 @@ bool AwtWindow::IsLayered(HWND window) return ex_style & WS_EX_LAYERED; } -void AwtWindow::StartSecurityAnimation(AnimationKind kind) -{ - if (!IsUntrusted()) { - return; - } - if (warningWindow == NULL) { - return; - } - - securityAnimationKind = kind; - - securityWarningAnimationStage = 1; - ::SetTimer(GetHWnd(), IDT_AWT_SECURITYANIMATION, - securityAnimationTimerElapse, NULL); - - if (securityAnimationKind == akShow) { - ::SetWindowPos(warningWindow, - IsAlwaysOnTop() ? HWND_TOPMOST : HWND_NOTOPMOST, - 0, 0, 0, 0, - SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOMOVE | - SWP_SHOWWINDOW | SWP_NOOWNERZORDER); - - ::SetLayeredWindowAttributes(warningWindow, RGB(0, 0, 0), - 0xFF, LWA_ALPHA); - AwtWindow::SetLayered(warningWindow, false); - ::RedrawWindow(warningWindow, NULL, NULL, - RDW_ERASE | RDW_INVALIDATE | RDW_FRAME | RDW_ALLCHILDREN); - } else if (securityAnimationKind == akPreHide) { - // Pre-hiding means fading-out. We have to make the window layered. - // Note: Some VNC clients do not support layered windows, hence - // we dynamically turn it on and off. See 6805231. - AwtWindow::SetLayered(warningWindow, true); - } -} - -void AwtWindow::StopSecurityAnimation() -{ - if (!IsUntrusted()) { - return; - } - if (warningWindow == NULL) { - return; - } - - securityWarningAnimationStage = 0; - ::KillTimer(GetHWnd(), IDT_AWT_SECURITYANIMATION); - - switch (securityAnimationKind) { - case akHide: - case akPreHide: - ::SetWindowPos(warningWindow, HWND_NOTOPMOST, 0, 0, 0, 0, - SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOMOVE | - SWP_HIDEWINDOW | SWP_NOOWNERZORDER); - break; - case akShow: - RepaintWarningWindow(); - break; - } - - securityAnimationKind = akNone; -} - MsgRouting AwtWindow::WmTimer(UINT_PTR timerID) { - if (timerID != IDT_AWT_SECURITYANIMATION) { - return mrPassAlong; - } - - if (securityWarningAnimationStage == 0) { - return mrConsume; - } - - securityWarningAnimationStage++; - if (securityWarningAnimationStage >= securityAnimationMaxIterations) { - if (securityAnimationKind == akPreHide) { - // chain real hiding - StartSecurityAnimation(akHide); - } else { - StopSecurityAnimation(); - } - } else { - switch (securityAnimationKind) { - case akHide: - { - BYTE opacity = ((int)0xFF * - (securityAnimationMaxIterations - - securityWarningAnimationStage)) / - securityAnimationMaxIterations; - ::SetLayeredWindowAttributes(warningWindow, - RGB(0, 0, 0), opacity, LWA_ALPHA); - } - break; - case akShow: - case akNone: // quite unlikely, but quite safe - RepaintWarningWindow(); - break; - } - } - - return mrConsume; -} - -// The security warning is visible if: -// 1. The window has the keyboard window focus, OR -// 2. The mouse pointer is located within the window bounds, -// or within the security warning icon. -void AwtWindow::UpdateSecurityWarningVisibility() -{ - if (!IsUntrusted()) { - return; - } - if (warningWindow == NULL) { - return; - } - - bool show = false; - - if (IsVisible() && currentWmSizeState != SIZE_MINIMIZED && - !isFullScreenExclusiveMode()) - { - if (AwtComponent::GetFocusedWindow() == GetHWnd()) { - show = true; - } - - HWND hwnd = AwtToolkit::GetInstance().GetWindowUnderMouse(); - if (hwnd == GetHWnd()) { - show = true; - } - if (hwnd == warningWindow) { - show = true; - } - } - - if (show && (!::IsWindowVisible(warningWindow) || - securityAnimationKind == akHide || - securityAnimationKind == akPreHide)) { - StartSecurityAnimation(akShow); - } - if (!show && ::IsWindowVisible(warningWindow)) { - StartSecurityAnimation(akPreHide); - } -} - -void AwtWindow::FocusedWindowChanged(HWND from, HWND to) -{ - AwtWindow * fw = (AwtWindow *)AwtComponent::GetComponent(from); - AwtWindow * tw = (AwtWindow *)AwtComponent::GetComponent(to); - - if (fw != NULL) { - fw->UpdateSecurityWarningVisibility(); - } - if (tw != NULL) { - tw->UpdateSecurityWarningVisibility(); - - // Flash on receiving the keyboard focus even if the warning - // has already been shown (e.g. by hovering with the mouse) - tw->StartSecurityAnimation(akShow); - } -} - -void AwtWindow::_RepositionSecurityWarning(void* param) -{ - JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); - - RepositionSecurityWarningStruct *rsws = - static_cast<RepositionSecurityWarningStruct *>(param); - jobject self = rsws->window; - - AwtWindow *window = NULL; - - if (self == NULL) { - env->ExceptionClear(); - JNU_ThrowNullPointerException(env, "self"); - delete rsws; - return; - } else { - window = (AwtWindow *)JNI_GET_PDATA(self); - if (window == NULL) { - THROW_NULL_PDATA_IF_NOT_DESTROYED(self); - env->DeleteGlobalRef(self); - delete rsws; - return; - } - } - - window->RepositionSecurityWarning(env); - - env->DeleteGlobalRef(self); - delete rsws; + return mrPassAlong; } void AwtWindow::InitType(JNIEnv *env, jobject peer) @@ -1919,7 +1321,6 @@ MsgRouting AwtWindow::WmSize(UINT type, int w, int h) currentWmSizeState = type; if (type == SIZE_MINIMIZED) { - UpdateSecurityWarningVisibility(); return mrDoDefault; } // Check for the new screen and update the java peer @@ -3356,20 +2757,10 @@ Java_java_awt_Window_initIDs(JNIEnv *env, jclass cls) { TRY; - CHECK_NULL(AwtWindow::warningStringID = - env->GetFieldID(cls, "warningString", "Ljava/lang/String;")); CHECK_NULL(AwtWindow::locationByPlatformID = env->GetFieldID(cls, "locationByPlatform", "Z")); - CHECK_NULL(AwtWindow::securityWarningWidthID = - env->GetFieldID(cls, "securityWarningWidth", "I")); - CHECK_NULL(AwtWindow::securityWarningHeightID = - env->GetFieldID(cls, "securityWarningHeight", "I")); - CHECK_NULL(AwtWindow::getWarningStringMID = - env->GetMethodID(cls, "getWarningString", "()Ljava/lang/String;")); CHECK_NULL(AwtWindow::autoRequestFocusID = env->GetFieldID(cls, "autoRequestFocus", "Z")); - CHECK_NULL(AwtWindow::calculateSecurityWarningPositionMID = - env->GetMethodID(cls, "calculateSecurityWarningPosition", "(DDDD)Ljava/awt/geom/Point2D;")); jclass windowTypeClass = env->FindClass("java/awt/Window$Type"); CHECK_NULL(windowTypeClass); @@ -4016,28 +3407,6 @@ JNIEXPORT jboolean JNICALL Java_sun_awt_windows_WWindowPeer_requestWindowFocus CATCH_BAD_ALLOC_RET(JNI_FALSE); } -/* - * Class: sun_awt_windows_WWindowPeer - * Method: repositionSecurityWarning - * Signature: ()V - */ -JNIEXPORT void JNICALL -Java_sun_awt_windows_WWindowPeer_repositionSecurityWarning(JNIEnv *env, - jobject self) -{ - TRY; - - RepositionSecurityWarningStruct *rsws = - new RepositionSecurityWarningStruct; - rsws->window = env->NewGlobalRef(self); - - AwtToolkit::GetInstance().InvokeFunction( - AwtWindow::_RepositionSecurityWarning, rsws); - // global refs and mds are deleted in _RepositionSecurityWarning - - CATCH_BAD_ALLOC; -} - /* * Class: sun_awt_windows_WLightweightFramePeer * Method: overrideNativeHandle diff --git a/src/java.desktop/windows/native/libawt/windows/awt_Window.h b/src/java.desktop/windows/native/libawt/windows/awt_Window.h index 5b0b8ba2ae4..d683a6cc7db 100644 --- a/src/java.desktop/windows/native/libawt/windows/awt_Window.h +++ b/src/java.desktop/windows/native/libawt/windows/awt_Window.h @@ -50,20 +50,15 @@ class AwtWindow : public AwtCanvas { public: /* java.awt.Window field ids */ - static jfieldID warningStringID; static jfieldID locationByPlatformID; static jfieldID screenID; /* screen number passed over from WindowPeer */ static jfieldID autoRequestFocusID; - static jfieldID securityWarningWidthID; - static jfieldID securityWarningHeightID; /* sun.awt.windows.WWindowPeer field and method IDs */ static jfieldID windowTypeID; static jmethodID notifyWindowStateChangedMID; /* java.awt.Window method IDs */ - static jmethodID getWarningStringMID; - static jmethodID calculateSecurityWarningPositionMID; static jmethodID windowTypeNameMID; AwtWindow(); @@ -240,7 +235,6 @@ class AwtWindow : public AwtCanvas { static void _SetOpacity(void* param); static void _SetOpaque(void* param); static void _UpdateWindow(void* param); - static void _RepositionSecurityWarning(void* param); static void _SetFullScreenExclusiveModeState(void* param); static void _GetNativeWindowSize(void* param); static void _OverrideHandle(void *param); @@ -257,8 +251,6 @@ class AwtWindow : public AwtCanvas { jobject peer); virtual void DestroyHWnd(); - static void FocusedWindowChanged(HWND from, HWND to); - inline HWND GetOverriddenHWnd() { return m_overriddenHwnd; } inline void OverrideHWnd(HWND hwnd) { m_overriddenHwnd = hwnd; } @@ -304,58 +296,15 @@ class AwtWindow : public AwtCanvas { void RedrawWindow(); void DeleteContentBitmap(); - static UINT untrustedWindowsCounter; - - WCHAR * warningString; - - // The warning icon - HWND warningWindow; - // The tooltip that appears when hovering the icon - HWND securityTooltipWindow; - //Allows substitute parent window with JavaFX stage to make it below a dialog HWND m_overriddenHwnd; - UINT warningWindowWidth; - UINT warningWindowHeight; - void InitSecurityWarningSize(JNIEnv *env); - HICON GetSecurityWarningIcon(); - - void CreateWarningWindow(JNIEnv *env); - void DestroyWarningWindow(); - static LPCTSTR GetWarningWindowClassName(); - void FillWarningWindowClassInfo(WNDCLASS *lpwc); - void RegisterWarningWindowClass(); - void UnregisterWarningWindowClass(); - static LRESULT CALLBACK WarningWindowProc( - HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam); - - static void PaintWarningWindow(HWND warningWindow); - static void PaintWarningWindow(HWND warningWindow, HDC hdc); - void RepaintWarningWindow(); - void CalculateWarningWindowBounds(JNIEnv *env, LPRECT rect); - - void AnimateSecurityWarning(bool enable); - UINT securityWarningAnimationStage; - - enum AnimationKind { - akNone, akShow, akPreHide, akHide - }; - - AnimationKind securityAnimationKind; - - void StartSecurityAnimation(AnimationKind kind); - void StopSecurityAnimation(); - - void RepositionSecurityWarning(JNIEnv *env); - static void SetLayered(HWND window, bool layered); static bool IsLayered(HWND window); BOOL fullScreenExclusiveModeState; inline void setFullScreenExclusiveModeState(BOOL isEntered) { fullScreenExclusiveModeState = isEntered; - UpdateSecurityWarningVisibility(); } inline BOOL isFullScreenExclusiveMode() { return fullScreenExclusiveModeState; @@ -363,8 +312,6 @@ class AwtWindow : public AwtCanvas { public: - void UpdateSecurityWarningVisibility(); - static bool IsWarningWindow(HWND hWnd); protected: BOOL m_isResizable; @@ -374,10 +321,6 @@ class AwtWindow : public AwtCanvas { BOOL m_iconInherited; /* TRUE if icon is inherited from the owner */ BOOL m_filterFocusAndActivation; /* Used in the WH_CBT hook */ - inline BOOL IsUntrusted() { - return warningString != NULL; - } - UINT currentWmSizeState; void EnableTranslucency(BOOL enable); diff --git a/src/java.desktop/windows/native/libawt/windows/security_warning.ico b/src/java.desktop/windows/native/libawt/windows/security_warning.ico deleted file mode 100644 index 67793ed82648ad9f6f9164075ecbd60e1555da51..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 17542 zcmdU0dvFz389xw)Ag=^0&z2;_gftCF2ocBw5-1dT)>0JBA2?X5w$7;FRBfG(go1r( zhjwg5X`y1J<=K{pbd-)wp%e>+5C~92AqADINlfaf6E*Vr`)zWTy_?;=yZ7E)Ak2^R zo$q|Fy*JrC-}jwWs)y>OGBOm#47E8`shLWt;ln%TkAF<5zk!zuaQ(hsN_~5zQsc&T z%4aKeK251xp#u|YDnL2UpOw#xx)xwikGvomyWf$DOO5jB|4BkXU-U`eYSjkA_xyH| zM1nEUxADDv|3#VICJBXtPxE);(Ty_ce3RVqPw|cXbsHrqDaiooAiDIW;M4R^;_;Vc z+TX=DM$Mitg9Z&UKstyneTDhv<cUpEbhb&Rw1_Vhe)B=e&CNAH+OHmc&{r4#Wc=V2 zDQyzpDBrqQh#)%j;pm&pr?yDmsV15D7wHzzHhsAI=faw8GXBrv3)$P>62h-MZF~CW z;xjvBOkI-{{!t<#X<(`leq?Erwj=tdz>i*&u@@yGdiLxogdbVj^yQmE&+U@YN1G(~ zg191c?{V|*pR|`OZPBK0{}f!iM{>@KE7CW=Exmj9HbB}-mbL=<rtnYSkhH^1lKp#e z#He+<q;KE821vWf(FSb=_D_Z9e<j)H;NJlw9(Ys+4jgEJw37^Zv=NnWDy`oqnTS6R zpMf1|-+5dH4<2lQw0)g(>e5Ek{;BxlZ)E%*a6hmi{j*DC*sx&+NZZ#rr*2HXsl2g9 z#=hSqCHP&mBKyuol9rZcfV6duG<B#Ovws?R>3~!=NEmV^S4vh^mI2cCb?U^$H;rsM zC=>BFJo7^_k(ZYzR#?|4OP#p+r=eF4$voT>HHwRi#R|>mNZGjhrm-#W$<*Ubvhb1^ z_|%&9GI{c31Ee*dGL((Ge;V9&M5^#y@&aYL#W#)aI4X1S99!}yaRk>W({27~_|;nZ zGWG{f;99r(rt#P7WZ{V>`PyX(19@EQcK>v+^Q1fwk}!~$5Z`pNyIvO8H_3OgPb5f_ zmoWcywCA)u1m6Vdg!-nlU!IYBu%9JJC)__B?)^Xv#NfP|<$=y0(nO6?NkoHE$waGC zDMXu6=|sCymBbaLRuH&&d<j5xj}Fu%i4YCR9cWDvA==VA&|WD*Tv;KkQ=qh=P`<c! zbqe@atJa%!h}r)}E*=M%bq3gGzRmdz<k<0qQAg0Z{9_xX@+0gMB4E<V3sQcuC88Yd zDA?r3WBfev3mJE|QOcUd6$N|tOLB6u^c^xxCS7QCm7@*XQn0Db8zb^lul%!M{Wf#o zGrsnsr>tYHi~KY9WTR)!IPuL|nQ-Wwrwnbl=CV(3mjdh)+;Hom3&^uuT-T|mU?c2v zu}+Z7Wgcsk+ps5eLch{!GGtk`;~M3u8!;bzZntYr#hjBq+;T1jU2C|G^iTFm+L1=b zyoq_;z{xWl*QleQ>uA%?MDCM=Jj9Bu{U1ude*I*?@R4DBEfXkT+VG}iA)Z3y8X7rU z514f+&C?@g6?E)jdd@e#h1#5$DBN*SMvNF?V8V%yOg?24WIb&;Eh0}SI@%~x@q0lO zt$bQCGcyg8y#Cv(e8@zdQ@s4H%tG!!ls)!i$<NO>Fm2CaldmA-6rL|0_S+S;jdB<E z{&%e1ETyHT2IlTRYw)-h^PU|0>d#~EP29b&Ru&#SXU^lY=iYHl=G8TJ*;mg6Phrj1 z=MYKgwK};EduJ;Yc#+h6uVW8dh5O<%>`e*Mao?BjK6Q292ikXReg(0YTY9R|K)3Dd zqS&`pU)`oD(nO6)GSHxs7163v4790qMYO9*16R}vMTq{l5)^?Ffq~0n^ovsQ8D#(w z`$g=VL<4>Y*sByBKPU74i(EbcsAKdjP`i(I|76zvvBz+#*Qefmi`?>=D#x|3y#(sW zV^25Bq`%_6Y{7)pPszk}FNg8CPT4NCXFS8lA&<5q=hwB8f2Jjj$92bNHENofwat=; zd#XmttOYW3d9^twpE9oXPd*><?9$*fcj)p*%sKg<&qLJL(hfJv7}Obw!MXWz)3iC} zoNEzlaCrXc+TF;JBPC<*LUZoxd4pQd_+!mdaRJwnlOwss6AYR>-*q6|+vnohQ96Bw zl+9mY(1Gshs5{K8YnIPp-$sxQT#LZHb1A-SBC2~Pa^R}^W&=^@!#?gy)n>M+6ltO+ zsRIqkN)fFo9cW8eifFIwz?BspeQD-;OMr;?nQPILj)zZN8~f?Hubs%gaxA{ge3hR8 z?(dT?Hp<-p$PEP}A2#~>>tz;t>Ng@-i%_dK$c*zLnfWi=Pi`PEX2#Ax0Y0y%|3hvl z7<&vOc*g%TnR+f1=xl-4IfN;fT4d0aY0{%d4+Esh^U?{j##kA%4&NAk)`TL}jJW=Z zhgX?BSKWIh&yTJjnXp=uz6k91rhE``+><%&;k<Y^&zdKxsi|Qg&r8Sm8e%l}mpXPm zqQ+H@dRMF%^M!k5)TmKmATL(C)bCP<)3I}Wa+8#v3Q0*LdZ002!n<dru&i7P3ky2{ zn!H$SQkStYMr+7jXx0_67mpQ_>Mu*#vl|SMj@2IZ!*Yu*fp;=~xLGEi49O>vS6@$H zObW5Ng&oF6?R7l*X4ey3Yq(*7cTSM^6(0{t5%%cU0~kw}ywWLdD-U&LKj)R)WX7Iu zk(60?86fQ@=ZEiE<F>|ZrJs3K#vKbuKJv9_Fk;0T{;nDz9gPj@Fb0KKtfBd)k^AeM zJ?O~%Uhg05xqc8^jx`0p7x3&(DR@8R+Fx+$Nod|p_bxZitg(kcTJwX9^sNws-*6q} z(4)vj%^)ZSl-+Kgdm|lGpYp!?BaT5^n5h5c9SOPiVBC5$1InjMuU@?jkam-E<I|^W zJ;@TDFA{y6F{m*GL7$HgHTR&TgXmJ$ckjs01+05RZhJ4}*r#$k57?(qAF;ws&WTT7 z3O@aW=353ez%116{2=pKt9j;8pM50Hk1l0AYl*%Cwh6wlPxA1&=>DD8n6Y`k^zYw4 z4CHy~=r#IK@MZHJpDB8RPUk1>ysRw;Bqb#!4CLA6oaTZ1jzO-BXEYCo%pR!jciP9y z)oaZ&qx$S9d3HJboVFv@k%PqRB#Yi@G42mu$a?5W88T!@7|8R|;aXIES*IAict3wz zN^ozs_KNNFm}TEHd&jzmOrBlNI;Twq+g`5YwuW9nIi8Ph;5l1+{!5;lJo&zQ2=Tgr zO?Zz9dy`7|bwcifDj7X`bQs8Uk|mF}6l}&TJYROuhrb=?0GyChR4m!q*<m2hNtV2r zdiuVCbr3>7XvR_0P0{<ZL%*+MAMJ9S(}wT<kwX|Uv2dPY4q~vQprAmUV3*@O=JO7* zT)@`DG6(t5oye1{u%6ep(pDML)K#z%O9(ORq9=GadU;k<+;hK_l$3;lJgW@pK)u75 z19dU5{irOc4ap+Jqp{$f-^ui^d|fIkDh!Y&Pp@;Nj)Ja>)x@%K?xiZid3XDI+|J6x z<4VyNUW6LWVqAkCP&RPiI396&*}(arFQVS%2XQ@1<P}qpwVfwqaa~BhgmX_`pp1fS z5Yq{h#o2)S5x*CrIx~={3)odJOHYKt-j}exKfyHxnM8#Xl^>inTOJZesO~t27FCcQ zN;n_#Rn+Rgg=?^ayr|EMc)079C7jKB5bt|f(QRk+y5j;6|2OJG@-VJ}Abmr{&(B1k z5z=FKd`_@gO}mz}Mw~kRRFlbbNS$L1N1jLO92+?DTvF$V_gL^I3(hBXj(DF1Z?xc? zQs;>GTJUBI&MS3}c)ta2xG0>T>==!k6#g^EYPjcIk2P@5xgHzfo^w6IaSG>pgyVG1 w^~e`%IM<_o!A6f<3j<%eAy1Ed@rH9f@+BP3^~e`-IM-uaddFOk?UkJWA7e~-^Z)<= diff --git a/src/java.desktop/windows/native/libawt/windows/security_warning_bw.ico b/src/java.desktop/windows/native/libawt/windows/security_warning_bw.ico deleted file mode 100644 index 68a1824a2f529c830407f433863b101338c8478d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 17542 zcmdU$S&U836UUno<A<0*#FAJ;5Wyr~Y(XSQgz(_e!{3AC|6<<>GxlBV`x=DA10fzH z#Mt*GVqeD=BK9W_qW|Y}?$rJFZD+l6?&UY~Ro&IqU3JdA_jFZt9i^(N8md(*<<M5@ zV6jpIl~PTbr20$#QR=h9D|W#6e`_c;wV6^SC6)5+lzQGmsSeH@X9?BM0dhfq<HwKJ ze*)MvVZsD`_Uu{x;K2j^?c2A!0A1)r_r!@4_5J(z^_MSS@(OgKn|m;6(j@)y<Hx)L zo#^Io%9JVk&Ye5@!-o%%v2NWuT~JWqf_9v_=t5^od+PtGQ>W^8@7_hmph1Il{rdG? z(2g?~U8Zi@)2C0@H*en5Z{NO+gmL4>>5d&cx}Y6(9y-uv>!&|s#ti-X_3Oykzkk05 zaps`IOE<h(vu5e5SFh@qFJI;atc?yo{qSeco~>WJco7K)4jj-Rsyu54>1J%soH_c^ zrAzwRvuB~GSFfH1QDj+@wZrr?URGA7pFDXIit5#?YY;`2HKXW8X5PGc`oe_^`tjq( zzBqdHX!`e0J4lwbSTm}A<Q6PgpdUVb=!?C3_v)H8Yr3EvB+FWHbR)ZH(W3Oe#C~C8 z)22<jcJ10OXxrn`XP;rMxcZS_vSf+7H?ddPVDFIcpX_0_41LzfMmKYoEnDV$4<=8Z ztQ$0F;DWYXuSvOf*2q>r^H!`_;rZE)7%@UOZrs=fZLiOtxmD54+*PYq>GS8$>qn0s zWnk#gp}Iwj7A|Pp<IG`hRrND}_3G8Xt>3FxFWt6nTNku#{me;1H*2h2yY{!|L8nfg zv<dU~&+nZ%N$F=Dd<^qB*R5MOZNeNwHc8#AwPC{seevQ&{q*Tm7t5C~*S&l9c0pVC z$RL}ve%9kT6SmhNlMCIfxq0(uefjcb{rvfJPcVi|uJp6+)~#DTbz>7_xzx?t+qP}f zSFT+7&F6r}Sg!T6{*E0xbVWr)2H@pGH#&Ci+?nAg;@82;mwxo@+O<o+diBZ$?R@G+ z*Y4fB_4Vu5UC_?Ae)R3xvqyuf=q@8YQ29q2lq*#LDwHY&UzI8XKa^?-ek#=${8FkE zI0k4JW!1C><pn8J6lx8=7Nzi`rPknQ-xPk8YVs6LYC}2ci$9j9a8xUNsHF1{_(H77 z+Qi%U?%mU$KYvaXtSPZPF?EzU{KkzN?p_*2){N7qO`E1~-MSSRYacmsL>Cqo>PC$k zxjsoyT+Ujo$^Dl<;?p;8-uQxNy!buWu3ht$V-2rZH%g3q;=~Dk?%cV+7&s`FCC>BP zBjNL%xPAL}piEG#NGxaiBI0`p?cTk+9y@ky+9wgdQ09ikgY)Ol_l@a@IniPId}f=u z@_G8vg$ozD_t?vCC$7V%^%~=IVXoi0Cf_T5I(6!lu2ZLuZqlU5Z!uNecnQBxo*5GN zkdKkPl<<Ti%N*0ju=dK8D>LrH!Gi~N)22;bu>Y9%2-&dp>~Z1*Grl25(xy!t7l#fV zO2-w*WE)cu3&{6_??&g&on0J0d^pXoO1vPxIWYjfe~%tLT%0_4(tXY);gjQ6%kSs- z@#FgR>C@?c5<d5qEn7T&YkX?P?9VNmKK`klD@)R6#RuiND84D}r2SI-Ovz8?!so=7 zV_yNe^6Rqk+sgj$rYYK>Tot&eP=yM7RYfj-sFn)+RDE6iQl$!L`8U^Tfpe93r`_|S zV&_ZM%0bw95$7h^fbT56N_ly?zI*qs{`BcnBp}Ni=90T-?|lFMeJn6X^8S84Mzdzk z^zh-sJ$(w(m*5#`e$VCm&Yrq{{rdFxU--z{xo2eMc_Q@Kv19HTg!F}a?bYNo&F41x zp8*2~=rLo)q@UUFknziZvOmh+1nt?gr|UPEyrBFc`89L@>(HTt?$@thdQHZ{a&TsD zi~B!#@ZhxlQT7|2_mZn_-@d(@6JoD{7c~zg&-VWP`)hJ}-1j)obbL}XFG4$RE`sNz zJe#w5W)cJQJp<Xs!%?0~W$9?qIj3;ipu8Z3ibAEp*P;}Dv{VZG?3==`($u*$vEF|i zggs~e#F=ywI-N^Xti!no{@M5M-~ScBR&2(0p6@&d@^vPklpbuBbNzgu=_jR+d;y5F zM@HRCb1jF>*v@Z&{W{-u4OP`AxfJZ@Tq|x}L{LtJ_=LE&TD58}Xu}Jd6K4!tu^HRt zkNizsU&&9NT#cN$3Wet<AD3_Dn#6v5wy>O2P>#tQ8#r*FE-o(406bGB+cq|ee<`*L z<sL<?4+)YRIdY_K-n@AR;04WzI%enL#C9n4D&!1<@^Vqe&YU^p#^qhRcGZA59bS~V zK{D9pS5qU`f&VV&1y!Nw!Y>81tFo5NHDe30*QPUP&UAe{iGBYTioc0%w!L0`a<38- z{Vg=C9?858VmQ;!56bc8V+>pDxYD%Ot4&@x><l?*oaY>ICZHW88#We{<My&0UTJA* zVD4LDW<Of_dGmdBYtj7V!uaGAvBl5MAU^TDS+5YMO<rI82ikGwnzCLwg&>>Fu_*On zlJB+Ys8OTbnl;W4Xxrma`q|WznfB8r4{g`XMCr3<N!=^$D06I?DCZ-#y>_3R4rd`| z{y$0^n`_jl;evLQIi?Ic{qjk+jbVMxam-v(ly<|04bwg-?I?3hnW$$+VYV~Ac=2L4 z|K(M8=f|s6tClw5C+Ec{pN7sTwndfkIwSMa4UZZZsd*F%&rjaw2jvo@+H1=#UAi<Q z2WfuRc6;BxeY$Slx*33H%X#&=_vo_qC(-9j&`YPy<7~00s3-&QY&oxf+;hh`*F}yu z%Cl(h+_~wRQK=n;XFgxN+N>RxM~-8!m#lrx>SYJ<9d!*R;CacKyll>8y=)BP`PHeK zdk<#=a&|1#J})rkX>)#%R2^%O{fwDs0k$3VhYT5#5&IGg!}F3AUX(M0FuS6TuUWGu zeHP*6#|#@bOt)^`Is@>$WZ~iGux3>KNyu>yZ~BR5yQHK<w`<of1Mo~4vt5-l{cNv= zGar0&(++9N`#Lt2ag(w})bpckZS|W+J%d;L(WOfl?FBE{T-6}^*=+JRZrtb@qnY*E zX4|%(d(Rr?n)z;X{%6Op#4FT2nSf`@#W_37)pb#aZNJAv&C2M}qjjG?eO%CnXWGx4 zT-R_%y=LlO;^tA3s+EaqW00JEE*y3(*_;~(=}%(Jt7b^fsco8MEm0D-v&Q!A+db>` zZQF@skWET&lIu_p5SA~^re+{X8-v!e-xsiR*W{3MQOgx%Q`|AL?##CTZ?~Omr6z=$ zHaT+;3NPDwk+}D;s`Aw1iQPhTRijr`TfOFED>b|FzBcWDll@$i)CdXny3QncWh`RU z8u_g$aze`yq#mh~RzRsss-(_)EY6!OPJL1(b>3%j-e_^^lq#w7UW;<dCY`#;6m{Nj zaSk1nQ$Lxa?grufm!@Tone>I0JL>5Rt#H)S7wRZ3qA%1@+>*XfUaX-nR9>(V%2)<? f;Rc>iUcR9(loxR53*}`T`a*djhrUo=&Qa=rl`>vm diff --git a/src/java.desktop/windows/native/libawt/windows/security_warning_int.ico b/src/java.desktop/windows/native/libawt/windows/security_warning_int.ico deleted file mode 100644 index d773dca9e643c9916849428fc601ed4f856cee6b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 17542 zcmdU0X>b(B6>boP2vA6n5Dpio!59;+!bu^J5C{<WY4O9Uq7v+oGET(=iu=&6BoL=8 zBqVX$fB^#rn<F-kO@hE>%q0ls5a_bF3=#qfaH{x0@$$Z2^)frm%+4NK3b{V@>(}qv zwV3Jm`n3?XL><w#t>Ce(*cmBAybz*!bJu+7uY|bIyhsMt->W0Utd>Ib=us`-QHYY( zLcGp8Y(n&BK+ftXI&mev2q2~yM;iV8o9`&Ku$0z6`d>%@U+@XvG0qRA?{yD<p-=)b zz&E~weo3n+r}9xq0iW=VpV*WPO3p8#)fEqHV`BDN3JVL90PTw|e8H#7yX$xCqScg9 zUS%6ShYX{}jT=jV_C*)Iw7x<2PtBsl3q|zd?Mho1J#{*D?%Y`dv|T;;fG@p&%m*yV zp_RAp+s4!#dkFAF2R@8^gBQ1KEzLhyK+A93s}aC9e3<zMf8dJsw4}7c7AEi9Pk>!{ z*tYVGwLxhcY4+)>w7BH1SJZ11L4X}u*o19w{;@td{UcgbT<#UMYu6^gjx222@eP^y zjLkIT<P}OTEH}mb2amY_{e!lWg)P{$>mPDMR&OQe)iP5|+P07C)~zc6+DaC-eDMw0 zq1oGL`VW`MapjI7{<vl<)vsS)0<@VNY`~VU{vkhX%?@(pvws7`PoGbX8a0vtZ6pI8 zZ203_`d_<?X8e#($ydsr!|<64sY#P25}=J_pgW9h`0F2f!`FXCsRiZFp-;lw)T~)E z3D8C|&<(^lbVqF5OLO_}cRBxC&?0KoIBMOxwFGGG8ffT1H&Fl3ANkQ2lvZ@t13ml3 zP=^j3BtYxep%V<>urX@$esY{Hpp4=QH@bA`LRx6o5>H(v=mg6@?2O)ekg|TNaHChR zUZjO~4YI-X4O?TjeMyV>J6KzKPhv`17DY!#OMq5<$UrvO{$X$IjzhHJ+I>qvrY3yD z=D1J)Ma#|>(#O{;4S_Yt)RceN9lz@v+IpkX5Ll~8-_rl?!<2rmn0DN%@&I__d99}X z!~R=){!P1oe&7M{Lg5=e680XUtRG8g@9hT?pur23e;LE)xwMD<0|`ur(l>lf_~Iz7 zxlkejI@JDU4Ev7J1V$jfohT1f|9}Q^g$M&mg$M_#gopqh3(*F6!YL#0R0s#a0g!~V z77>se=0a&W5l|K3!s9kXz>`=Po;nD13NCF3E?;=9Q^atcq9(wu1#<CeM^9AOA%5XH zMBqS<51X)!eA`vy2;8nVHrQ0Td~8altr|kg`Ad{mdefFHY~uUDPyfYPUh4$Y4j!WL z@NkN3`deC2a>KGNfI0wdx~#i?BR@^QQ)P<Do3^_5J<hY2Oyyw1DA$c!zK#~2FS5*; z=N>*riO2ISWncrgw6QCC;K~iO?D{=Z%sGCJoEJ+>*P#m=%AS5iE;lEyfKqusWQ6un z(KPTMvkccD4_$BhV0^|FN+~Kg1aeOJFk6SNK4$%VNY*x)V<r`pksiqFI`)lyjt@EH zlF-%LGn&i%iE|f+2Gfq@QG*5zs7dn{9(*O^OTILG-7cDbJl`YtdUyK)cU?-KlR*|b zMzNalMr_<ei#QKfn6m3jYSE&F#KOEHHy`VeHM3*JN1lLOWhv(@z=Xt9YTv%S#0Pu7 zcJm?QZ%#3K%K>+OGI7yL>e{ud#LRu)y7`bXi_sf@%qRb(q%#GSSyDmoXK$jYs3?h~ zBc~(}Ymo6~$7&t>>YShMNjMK3qtv5k-1A`UxyS9q-n!_yy*+qXvx?2`+W6hy(q`T} zYXP2JeQ$EugJzsBrtLSYBtQpyUy6OE+WXeTo-={>a@o9}1wecI%>Jxn&*tmC&G~Gb zCO`wZB21!GgbScbL`XaqZ3OT{#7aCB4grw*FNrDOyK3Afd0rIBAEqtC+j)^ZH^JG7 zkHB|@y$be3Dg5rwy7$l)APXJnqIU1NSVXJJs(b=;RNddK&ffHuSLpZS5)9w_+Pwto z$aBvY(9&xa9(dcinBL9a;K73oWc9UYSB>{B*KVKTZ(K)RaE_np8Xjn)cQtC7Gfw1t zyd&R;A5H^4nCZcTj9LBD^?rO--|WEe+_<T;J!+X&??cqrWPOm|J;{t#ufIWE1`L)o z=2-JqgTp&Ty?a`=Y)O9@KH5FE^S(i?$HBGrbpD<?b?QXjdc7%W@a)!s@cho^XM4Z6 zfi!5;7)kr`Oh?^eDc3$!Z3eWjwFo>XxA3zW@aLI{9C$T9ZvlVvVLQ(yr#o8|0yK~t z=0a(>5I|Lg3y<3f0X&Iy;i<!QE{$C8&kS$RnHO;;9SooR(FF3;clLZmON*}sC70CZ zd^JTQR>UlGY<{*Qw+!W(crbh+W_7N=rs@&BjF9yLXFARNK992RKYXcxnEP?;_&0#} z^~)B&s-+<Q*ks@PBCPr#mKR^A*P>&nR;^kRpuw}!@nuc+RdCFRUHzbblX>?+P%v`t z0{5A#I(r2#SoXEGCU^Y2-*a9p_GzzYwm0k%Ka?UPBRv3~nY=H2#HjX{Dt0xZ#+81j zGGGjt_$O-Bs+9-83x;id9ZtoLaX@M|&CAQDw4W;j!n|Xr=*>QTsC)PB5}?5g*e=J0 z7_~9$X|p}QFTFF6P5$o{nw*g%0oqr6BYACZp^sb5<Cd+VIj1kzNMBAM{XU2Zv8gz% zM$}8K>Y^`V&8&uN^f{2j%{+Pex%^I_2Zm~nSoC?NQQTS{>dHnnW4pXW&M%N>0-){c z8Od4IxV15B=|O3mXyL_cwtB9N`m#nWScJb-3D8C|c6f*Zv1ntnOB?0>`kdcv9yfKC zd;b91OwJqMsHR{${#75-{2#BG*8k1U1;Fq7&U><F4QB|Ttz^yC;CnE~U^iYPIh;{g z^{kn#y&4tc?t24mCTGRBb3S4evzCXN&b;%b9<?6*If~Kz)jly)r%oLS&_*&=yjf?8 zOzTP7`0UU)$Fb_$Gg@o(>)*KdprDOptax_Mj_kxgG<!Qu;~JM)@1GIBUcGvxg^`RI z55C~jPHc8%P~S`BK0!N}eX79S^Qd|s!Ly?a8LL{N-FWqK!`ANP{|8rW#V~2xernjT zp$EXT6aTEd67FT(8PxAyeHNSvCh-}iH~eMC0g8x-@Bnz;^sw&hxuc5B&M51^C$3To z*L<xoE_sE!XH@l$f@h_JwK=DYyw;KJ#Azjiv(v@w%L=1rJE&>XrXB##N(XEHoXc9p zYP2?T)8{nzbRjL_URg5?<Ff&EcC1G5%;dp`P1rW_8EhWv{mb|a+6=u%jrGWVkqd)o zCJ(-yGlXD$j!~QU(Sp2UTEV@#Mu;ApK<(PK^8k28vf#lMYz8YnJ9e~Z_4=OT-}UH8 z9XodP0C;*iH4o%W-%hMXGC1>@ck(K&;$CGv)O{WOsF%YWHte1s8O0F@54{R$1$Sic z0(u%0x^?SDMo{Z&gl?ey4gtl#?JG*;K4@)EHfU|XwwBh*L3a$>2qcC;b#eZeSy<-o z@j&m#m`RhVckkXF08jOWV1$k@XNQ5tX{JB+)2}Hhuh89>j{fu|+_RGK*D2JmUq1=Z z;HlnqjL?CuncYzG(f5+W=ep`#)!UeH^>)yDWrFcJaR%(*zNt;zvu_8G_4V917;#$J zKz~qn;T^+%f9*X0$ON;O$SNjZ*2aH!n3A{`K%K3djgWz?FSbJ^i++H0MP>BK%}PUH z&7Youkj20EKa|4H71bA}AF=ip%Y-T(fBc}=Y*R@&?c{qOT4d(m2>IOyzvAcq5GVhQ ztKK;^g6D6)h(B=zqJw_CoGZ87_dY<^RF7UDahmDkp2+O)FHq*C>k^<})ZG!Y7`^dT zkB}O@$@{zRgrcU`$jpwCQ)4a!(T`L;mSRL-QuWC9SokIj_a{}4e4mAHv~ZtN^~m>H z_~4)Wm8wU+-@-Rs1ouz6M){E9U+&S#VPdYvTy~GS8cW$d=4xce5tyry9k;<;jks8Y rxf<048#Q9h1GsPlo*Hra26Hvy0uJVC#AO`J)rbo@n5z+&bA<RmRCZa* diff --git a/test/jdk/ProblemList.txt b/test/jdk/ProblemList.txt index 702a426df0a..65fe0e71a2f 100644 --- a/test/jdk/ProblemList.txt +++ b/test/jdk/ProblemList.txt @@ -465,7 +465,6 @@ java/awt/event/MouseEvent/FrameMouseEventAbsoluteCoordsTest/FrameMouseEventAbsol # Several tests which fail sometimes on macos11 java/awt/Window/MainKeyWindowTest/TestMainKeyWindow.java 8265985 macosx-all -java/awt/security/WarningWindowDisposeTest/WarningWindowDisposeTest.java 8266059 macosx-all java/awt/Robot/Delay/InterruptOfDelay.java 8265986 macosx-all java/awt/Robot/InfiniteLoopException.java 8342638 windows-all java/awt/MenuBar/TestNoScreenMenuBar.java 8265987 macosx-all From c199f5326b8dd41f33a12e5db7552331e0844601 Mon Sep 17 00:00:00 2001 From: Roger Riggs <rriggs@openjdk.org> Date: Thu, 21 Nov 2024 21:50:41 +0000 Subject: [PATCH 173/311] 8344336: SM cleanup of java.lang.System, Runtime, String, StackWalker Reviewed-by: dfuchs, alanb, lancea --- .../classes/java/lang/LiveStackFrame.java | 35 +---- .../share/classes/java/lang/Module.java | 11 +- .../share/classes/java/lang/Runtime.java | 30 ----- .../share/classes/java/lang/StackWalker.java | 14 -- .../share/classes/java/lang/String.java | 19 +-- .../share/classes/java/lang/System.java | 124 +----------------- 6 files changed, 14 insertions(+), 219 deletions(-) diff --git a/src/java.base/share/classes/java/lang/LiveStackFrame.java b/src/java.base/share/classes/java/lang/LiveStackFrame.java index 77a02d083c8..7b61d191e3b 100644 --- a/src/java.base/share/classes/java/lang/LiveStackFrame.java +++ b/src/java.base/share/classes/java/lang/LiveStackFrame.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -154,8 +154,6 @@ public long longValue() { /** * Gets {@code StackWalker} that can get locals and operands. * - * @throws SecurityException if the security manager is present and - * denies access to {@code RuntimePermission("liveStackFrames")} */ public static StackWalker getStackWalker() { return getStackWalker(EnumSet.noneOf(StackWalker.Option.class)); @@ -171,12 +169,6 @@ public static StackWalker getStackWalker() { * The returned {@code StackWalker} can get locals and operands. * * @param options stack walk {@link StackWalker.Option options} - * - * @throws SecurityException if the security manager is present and - * it denies access to {@code RuntimePermission("liveStackFrames")}; - * or if the given {@code options} contains - * {@link StackWalker.Option#RETAIN_CLASS_REFERENCE Option.RETAIN_CLASS_REFERENCE} - * and it denies access to {@code RuntimePermission("getStackWalkerWithClassReference")}. */ public static StackWalker getStackWalker(Set<StackWalker.Option> options) { return getStackWalker(options, null); @@ -193,19 +185,8 @@ public static StackWalker getStackWalker(Set<StackWalker.Option> options) { * * @param options stack walk {@link StackWalker.Option options} * @param contScope the continuation scope up to which (inclusive) to walk the stack - * - * @throws SecurityException if the security manager is present and - * it denies access to {@code RuntimePermission("liveStackFrames")}; or - * or if the given {@code options} contains - * {@link StackWalker.Option#RETAIN_CLASS_REFERENCE Option.RETAIN_CLASS_REFERENCE} - * and it denies access to {@code RuntimePermission("getStackWalkerWithClassReference")}. */ public static StackWalker getStackWalker(Set<StackWalker.Option> options, ContinuationScope contScope) { - @SuppressWarnings("removal") - SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - sm.checkPermission(new RuntimePermission("liveStackFrames")); - } return StackWalker.newInstance(options, LOCALS_AND_OPERANDS, contScope); } @@ -213,9 +194,6 @@ public static StackWalker getStackWalker(Set<StackWalker.Option> options, Contin * Gets {@code StackWalker} of the given unmounted continuation, that can get locals and operands. * * @param continuation the continuation to walk - * - * @throws SecurityException if the security manager is present and - * denies access to {@code RuntimePermission("liveStackFrames")} */ public static StackWalker getStackWalker(Continuation continuation) { return getStackWalker(EnumSet.noneOf(StackWalker.Option.class), continuation.getScope(), continuation); @@ -232,21 +210,10 @@ public static StackWalker getStackWalker(Continuation continuation) { * * @param options stack walk {@link StackWalker.Option options} * @param continuation the continuation to walk - * - * @throws SecurityException if the security manager is present and - * it denies access to {@code RuntimePermission("liveStackFrames")}; or - * or if the given {@code options} contains - * {@link StackWalker.Option#RETAIN_CLASS_REFERENCE Option.RETAIN_CLASS_REFERENCE} - * and it denies access to {@code RuntimePermission("getStackWalkerWithClassReference")}. */ public static StackWalker getStackWalker(Set<StackWalker.Option> options, ContinuationScope contScope, Continuation continuation) { - @SuppressWarnings("removal") - SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - sm.checkPermission(new RuntimePermission("liveStackFrames")); - } return StackWalker.newInstance(options, LOCALS_AND_OPERANDS, contScope, continuation); } } diff --git a/src/java.base/share/classes/java/lang/Module.java b/src/java.base/share/classes/java/lang/Module.java index 4f9c09bace4..dcc92d012de 100644 --- a/src/java.base/share/classes/java/lang/Module.java +++ b/src/java.base/share/classes/java/lang/Module.java @@ -39,6 +39,8 @@ import java.lang.reflect.AnnotatedElement; import java.net.URI; import java.net.URL; +import java.security.CodeSource; +import java.security.ProtectionDomain; import java.util.HashMap; import java.util.HashSet; import java.util.List; @@ -294,9 +296,12 @@ void ensureNativeAccess(Class<?> owner, String methodName, Class<?> currentClass String mod = isNamed() ? "module " + getName() : "an unnamed module"; if (currentClass != null) { // try to extract location of the current class (e.g. jar or folder) - URL url = System.codeSource(currentClass); - if (url != null) { - mod += " (" + url + ")"; + CodeSource cs = currentClass.getProtectionDomain().getCodeSource(); + if (cs != null) { + URL url = cs.getLocation(); + if (url != null) { + mod += " (" + url + ")"; + } } } if (illegalNativeAccess == ModuleBootstrap.IllegalNativeAccess.DENY) { diff --git a/src/java.base/share/classes/java/lang/Runtime.java b/src/java.base/share/classes/java/lang/Runtime.java index 2f8f003af7c..764a9d7fa63 100644 --- a/src/java.base/share/classes/java/lang/Runtime.java +++ b/src/java.base/share/classes/java/lang/Runtime.java @@ -174,11 +174,6 @@ private Runtime() {} * @see #halt(int) */ public void exit(int status) { - @SuppressWarnings("removal") - SecurityManager security = System.getSecurityManager(); - if (security != null) { - security.checkExit(status); - } Shutdown.exit(status); } @@ -232,11 +227,6 @@ public void exit(int status) { * @since 1.3 */ public void addShutdownHook(Thread hook) { - @SuppressWarnings("removal") - SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - sm.checkPermission(new RuntimePermission("shutdownHooks")); - } ApplicationShutdownHooks.add(hook); } @@ -259,11 +249,6 @@ public void addShutdownHook(Thread hook) { * @since 1.3 */ public boolean removeShutdownHook(Thread hook) { - @SuppressWarnings("removal") - SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - sm.checkPermission(new RuntimePermission("shutdownHooks")); - } return ApplicationShutdownHooks.remove(hook); } @@ -293,11 +278,6 @@ public boolean removeShutdownHook(Thread hook) { * @since 1.3 */ public void halt(int status) { - @SuppressWarnings("removal") - SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - sm.checkExit(status); - } Shutdown.beforeHalt(); Shutdown.halt(status); } @@ -779,11 +759,6 @@ public void load(String filename) { } void load0(Class<?> fromClass, String filename) { - @SuppressWarnings("removal") - SecurityManager security = System.getSecurityManager(); - if (security != null) { - security.checkLink(filename); - } File file = new File(filename); if (!file.isAbsolute()) { throw new UnsatisfiedLinkError( @@ -840,11 +815,6 @@ public void loadLibrary(String libname) { } void loadLibrary0(Class<?> fromClass, String libname) { - @SuppressWarnings("removal") - SecurityManager security = System.getSecurityManager(); - if (security != null) { - security.checkLink(libname); - } if (libname.indexOf((int)File.separatorChar) != -1) { throw new UnsatisfiedLinkError( "Directory separator should not appear in library name: " + libname); diff --git a/src/java.base/share/classes/java/lang/StackWalker.java b/src/java.base/share/classes/java/lang/StackWalker.java index a6756f3278b..0c6e400b2fb 100644 --- a/src/java.base/share/classes/java/lang/StackWalker.java +++ b/src/java.base/share/classes/java/lang/StackWalker.java @@ -379,7 +379,6 @@ public static StackWalker getInstance(Set<Option> options) { } EnumSet<Option> optionSet = toEnumSet(options); - checkPermission(optionSet); return new StackWalker(optionSet); } @@ -409,7 +408,6 @@ public static StackWalker getInstance(Set<Option> options, int estimateDepth) { throw new IllegalArgumentException("estimateDepth must be > 0"); } EnumSet<Option> optionSet = toEnumSet(options); - checkPermission(optionSet); return new StackWalker(optionSet, estimateDepth); } @@ -433,17 +431,6 @@ private StackWalker(EnumSet<Option> options, this.continuation = continuation; } - private static void checkPermission(Set<Option> options) { - Objects.requireNonNull(options); - @SuppressWarnings("removal") - SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - if (options.contains(Option.RETAIN_CLASS_REFERENCE)) { - sm.checkPermission(new RuntimePermission("getStackWalkerWithClassReference")); - } - } - } - /* * Returns a defensive copy */ @@ -637,7 +624,6 @@ static StackWalker newInstance(Set<Option> options, ExtendedOption extendedOptio static StackWalker newInstance(Set<Option> options, ExtendedOption extendedOption, ContinuationScope contScope, Continuation continuation) { EnumSet<Option> optionSet = toEnumSet(options); - checkPermission(optionSet); return new StackWalker(optionSet, 0, extendedOption, contScope, continuation); } diff --git a/src/java.base/share/classes/java/lang/String.java b/src/java.base/share/classes/java/lang/String.java index 3d8481be1c3..e497e8faa6c 100644 --- a/src/java.base/share/classes/java/lang/String.java +++ b/src/java.base/share/classes/java/lang/String.java @@ -685,12 +685,6 @@ private String(Charset charset, byte[] bytes, int offset, int length) { cd.onMalformedInput(CodingErrorAction.REPLACE) .onUnmappableCharacter(CodingErrorAction.REPLACE); char[] ca = new char[en]; - if (charset.getClass().getClassLoader0() != null && - System.getSecurityManager() != null) { - bytes = Arrays.copyOfRange(bytes, offset, offset + length); - offset = 0; - } - int caLen; try { caLen = decodeWithDecoder(cd, ca, bytes, offset, length); @@ -828,10 +822,6 @@ private static String newStringNoRepl1(byte[] src, Charset cs) { } int en = scale(len, cd.maxCharsPerByte()); char[] ca = new char[en]; - if (cs.getClass().getClassLoader0() != null && - System.getSecurityManager() != null) { - src = Arrays.copyOf(src, len); - } int caLen; try { caLen = decodeWithDecoder(cd, ca, src, 0, src.length); @@ -850,9 +840,8 @@ private static String newStringNoRepl1(byte[] src, Charset cs) { private static final char REPL = '\ufffd'; // Trim the given byte array to the given length - @SuppressWarnings("removal") - private static byte[] safeTrim(byte[] ba, int len, boolean isTrusted) { - if (len == ba.length && (isTrusted || System.getSecurityManager() == null)) { + private static byte[] trimArray(byte[] ba, int len) { + if (len == ba.length) { return ba; } else { return Arrays.copyOf(ba, len); @@ -907,7 +896,7 @@ private static byte[] encodeWithEncoder(Charset cs, byte coder, byte[] val, bool int blen = (coder == LATIN1) ? ae.encodeFromLatin1(val, 0, len, ba) : ae.encodeFromUTF16(val, 0, len, ba); if (blen != -1) { - return safeTrim(ba, blen, true); + return trimArray(ba, blen); } } @@ -937,7 +926,7 @@ private static byte[] encodeWithEncoder(Charset cs, byte coder, byte[] val, bool throw new Error(x); } } - return safeTrim(ba, bb.position(), cs.getClass().getClassLoader0() == null); + return trimArray(ba, bb.position()); } /* diff --git a/src/java.base/share/classes/java/lang/System.java b/src/java.base/share/classes/java/lang/System.java index b5cea4236ad..e5e8d4df27a 100644 --- a/src/java.base/share/classes/java/lang/System.java +++ b/src/java.base/share/classes/java/lang/System.java @@ -42,25 +42,18 @@ import java.lang.reflect.Executable; import java.lang.reflect.Method; import java.net.URI; -import java.net.URL; import java.nio.channels.Channel; import java.nio.channels.spi.SelectorProvider; import java.nio.charset.CharacterCodingException; import java.nio.charset.Charset; -import java.security.AccessController; -import java.security.CodeSource; -import java.security.PrivilegedAction; import java.security.ProtectionDomain; -import java.util.Collections; import java.util.List; import java.util.Locale; import java.util.Map; import java.util.Objects; import java.util.Properties; -import java.util.PropertyPermission; import java.util.ResourceBundle; import java.util.Set; -import java.util.WeakHashMap; import java.util.concurrent.Executor; import java.util.function.Supplier; import java.util.concurrent.ConcurrentHashMap; @@ -92,7 +85,6 @@ import sun.reflect.annotation.AnnotationType; import sun.nio.ch.Interruptible; import sun.nio.cs.UTF_8; -import sun.security.util.SecurityConstants; /** * The {@code System} class contains several useful class fields @@ -200,7 +192,6 @@ private System() { * @since 1.1 */ public static void setIn(InputStream in) { - checkIO(); setIn0(in); } @@ -212,7 +203,6 @@ public static void setIn(InputStream in) { * @since 1.1 */ public static void setOut(PrintStream out) { - checkIO(); setOut0(out); } @@ -224,7 +214,6 @@ public static void setOut(PrintStream out) { * @since 1.1 */ public static void setErr(PrintStream err) { - checkIO(); setErr0(err); } @@ -275,32 +264,10 @@ public static Channel inheritedChannel() throws IOException { return SelectorProvider.provider().inheritedChannel(); } - private static void checkIO() { - @SuppressWarnings("removal") - SecurityManager sm = getSecurityManager(); - if (sm != null) { - sm.checkPermission(new RuntimePermission("setIO")); - } - } - private static native void setIn0(InputStream in); private static native void setOut0(PrintStream out); private static native void setErr0(PrintStream err); - private static class CallersHolder { - // Remember callers of setSecurityManager() here so that warning - // is only printed once for each different caller - static final Map<Class<?>, Boolean> callers - = Collections.synchronizedMap(new WeakHashMap<>()); - } - - static URL codeSource(Class<?> clazz) { - PrivilegedAction<ProtectionDomain> pa = clazz::getProtectionDomain; - @SuppressWarnings("removal") - CodeSource cs = AccessController.doPrivileged(pa).getCodeSource(); - return (cs != null) ? cs.getLocation() : null; - } - /** * Throws {@code UnsupportedOperationException}. Setting a security manager * is not supported. @@ -681,12 +648,6 @@ public static native void arraycopy(Object src, int srcPos, * @see java.util.Properties */ public static Properties getProperties() { - @SuppressWarnings("removal") - SecurityManager sm = getSecurityManager(); - if (sm != null) { - sm.checkPropertiesAccess(); - } - return props; } @@ -725,12 +686,6 @@ public static String lineSeparator() { * @see java.util.Properties */ public static void setProperties(Properties props) { - @SuppressWarnings("removal") - SecurityManager sm = getSecurityManager(); - if (sm != null) { - sm.checkPropertiesAccess(); - } - if (props == null) { Map<String, String> tempProps = SystemProps.initProperties(); VersionProps.init(tempProps); @@ -762,12 +717,6 @@ public static void setProperties(Properties props) { */ public static String getProperty(String key) { checkKey(key); - @SuppressWarnings("removal") - SecurityManager sm = getSecurityManager(); - if (sm != null) { - sm.checkPropertyAccess(key); - } - return props.getProperty(key); } @@ -790,12 +739,6 @@ public static String getProperty(String key) { */ public static String getProperty(String key, String def) { checkKey(key); - @SuppressWarnings("removal") - SecurityManager sm = getSecurityManager(); - if (sm != null) { - sm.checkPropertyAccess(key); - } - return props.getProperty(key, def); } @@ -822,13 +765,6 @@ public static String getProperty(String key, String def) { */ public static String setProperty(String key, String value) { checkKey(key); - @SuppressWarnings("removal") - SecurityManager sm = getSecurityManager(); - if (sm != null) { - sm.checkPermission(new PropertyPermission(key, - SecurityConstants.PROPERTY_WRITE_ACTION)); - } - return (String) props.setProperty(key, value); } @@ -853,12 +789,6 @@ public static String setProperty(String key, String value) { */ public static String clearProperty(String key) { checkKey(key); - @SuppressWarnings("removal") - SecurityManager sm = getSecurityManager(); - if (sm != null) { - sm.checkPermission(new PropertyPermission(key, "write")); - } - return (String) props.remove(key); } @@ -905,12 +835,6 @@ private static void checkKey(String key) { * @see ProcessBuilder#environment() */ public static String getenv(String name) { - @SuppressWarnings("removal") - SecurityManager sm = getSecurityManager(); - if (sm != null) { - sm.checkPermission(new RuntimePermission("getenv."+name)); - } - return ProcessEnvironment.getenv(name); } @@ -945,12 +869,6 @@ public static String getenv(String name) { * @since 1.5 */ public static java.util.Map<String,String> getenv() { - @SuppressWarnings("removal") - SecurityManager sm = getSecurityManager(); - if (sm != null) { - sm.checkPermission(new RuntimePermission("getenv.*")); - } - return ProcessEnvironment.getenv(); } @@ -1376,13 +1294,6 @@ public void log(Level level, ResourceBundle bundle, String format, */ @SuppressWarnings("doclint:reference") // cross-module links public abstract static class LoggerFinder { - /** - * The {@code RuntimePermission("loggerFinder")} is - * necessary to subclass and instantiate the {@code LoggerFinder} class, - * as well as to obtain loggers from an instance of that class. - */ - static final RuntimePermission LOGGERFINDER_PERMISSION = - new RuntimePermission("loggerFinder"); /** * Creates a new instance of {@code LoggerFinder}. @@ -1393,20 +1304,6 @@ public abstract static class LoggerFinder { * loading cycles during the instantiation of the service provider. */ protected LoggerFinder() { - this(checkPermission()); - } - - private LoggerFinder(Void unused) { - // nothing to do. - } - - private static Void checkPermission() { - @SuppressWarnings("removal") - final SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - sm.checkPermission(LOGGERFINDER_PERMISSION); - } - return null; } /** @@ -1476,11 +1373,6 @@ public Logger getLocalizedLogger(String name, ResourceBundle bundle, * @return the {@link LoggerFinder LoggerFinder} instance. */ public static LoggerFinder getLoggerFinder() { - @SuppressWarnings("removal") - final SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - sm.checkPermission(LOGGERFINDER_PERMISSION); - } return accessProvider(); } @@ -1493,10 +1385,7 @@ static LoggerFinder accessProvider() { // just fetch it again. LoggerFinder finder = service; if (finder == null) { - PrivilegedAction<LoggerFinder> pa = - () -> LoggerFinderLoader.getLoggerFinder(); - finder = AccessController.doPrivileged(pa, null, - LOGGERFINDER_PERMISSION); + finder = LoggerFinderLoader.getLoggerFinder(); if (finder instanceof TemporaryLoggerFinder) return finder; service = finder; } @@ -1602,17 +1491,6 @@ public static Logger getLogger(String name, ResourceBundle bundle) { if (caller == null) { throw new IllegalCallerException("no caller frame"); } - final SecurityManager sm = System.getSecurityManager(); - // We don't use LazyLoggers if a resource bundle is specified. - // Bootstrap sensitive classes in the JDK do not use resource bundles - // when logging. This could be revisited later, if it needs to. - if (sm != null) { - final PrivilegedAction<Logger> pa = - () -> LoggerFinder.accessProvider() - .getLocalizedLogger(name, rb, caller.getModule()); - return AccessController.doPrivileged(pa, null, - LoggerFinder.LOGGERFINDER_PERMISSION); - } return LoggerFinder.accessProvider() .getLocalizedLogger(name, rb, caller.getModule()); } From db44e97c5dfd286a58985be9b091fd43f5ad03be Mon Sep 17 00:00:00 2001 From: William Kemper <wkemper@openjdk.org> Date: Fri, 22 Nov 2024 00:05:50 +0000 Subject: [PATCH 174/311] 8344798: Shenandoah: Use more descriptive variable names in shPhaseTimings.cpp Reviewed-by: ysr --- .../gc/shenandoah/shenandoahPhaseTimings.cpp | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/src/hotspot/share/gc/shenandoah/shenandoahPhaseTimings.cpp b/src/hotspot/share/gc/shenandoah/shenandoahPhaseTimings.cpp index 5e60cf92393..50fd543851f 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahPhaseTimings.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahPhaseTimings.cpp @@ -185,33 +185,33 @@ void ShenandoahPhaseTimings::flush_par_workers_to_cycle() { for (uint pi = 0; pi < _num_phases; pi++) { Phase phase = Phase(pi); if (is_worker_phase(phase)) { - double s = uninitialized(); + double sum = uninitialized(); for (uint i = 1; i < _num_par_phases; i++) { ShenandoahWorkerData* wd = worker_data(phase, ParPhase(i)); - double ws = uninitialized(); + double worker_sum = uninitialized(); for (uint c = 0; c < _max_workers; c++) { - double v = wd->get(c); - if (v != ShenandoahWorkerData::uninitialized()) { - if (ws == uninitialized()) { - ws = v; + double worker_time = wd->get(c); + if (worker_time != ShenandoahWorkerData::uninitialized()) { + if (worker_sum == uninitialized()) { + worker_sum = worker_time; } else { - ws += v; + worker_sum += worker_time; } } } - if (ws != uninitialized()) { + if (worker_sum != uninitialized()) { // add to each line in phase - set_cycle_data(Phase(phase + i + 1), ws); - if (s == uninitialized()) { - s = ws; + set_cycle_data(Phase(phase + i + 1), worker_sum); + if (sum == uninitialized()) { + sum = worker_sum; } else { - s += ws; + sum += worker_sum; } } } - if (s != uninitialized()) { + if (sum != uninitialized()) { // add to total for phase - set_cycle_data(Phase(phase + 1), s); + set_cycle_data(Phase(phase + 1), sum); } } } From e21d06f488bce227eedc4c92d976301a7b54fda8 Mon Sep 17 00:00:00 2001 From: Prasanta Sadhukhan <psadhukhan@openjdk.org> Date: Fri, 22 Nov 2024 03:07:26 +0000 Subject: [PATCH 175/311] 8344338: javax/swing/JTextArea/bug4265784.java fails on Ubuntu 24.04.1 Reviewed-by: achung, kizune --- test/jdk/javax/swing/JTextArea/bug4265784.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/jdk/javax/swing/JTextArea/bug4265784.java b/test/jdk/javax/swing/JTextArea/bug4265784.java index 3465fced595..2b1ea06834f 100644 --- a/test/jdk/javax/swing/JTextArea/bug4265784.java +++ b/test/jdk/javax/swing/JTextArea/bug4265784.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -50,7 +50,7 @@ public static void main(String[] args) throws Exception { try { SwingUtilities.invokeAndWait(() -> { frame = new JFrame("bug4265784"); - ta = new JTextArea(); + ta = new JTextArea("some text", 50, 50); frame.getContentPane().add(ta); frame.pack(); frame.setLocationRelativeTo(null); From 50c099d69e9cef5c38a2624d7c798360eb6c1fba Mon Sep 17 00:00:00 2001 From: Phil Race <prr@openjdk.org> Date: Fri, 22 Nov 2024 04:00:46 +0000 Subject: [PATCH 176/311] 8344799: Remove permissions checks from java.awt.Desktop Reviewed-by: azvegint --- src/java.base/share/classes/module-info.java | 3 - .../share/classes/java/awt/Desktop.java | 81 ------------------- 2 files changed, 84 deletions(-) diff --git a/src/java.base/share/classes/module-info.java b/src/java.base/share/classes/module-info.java index c91a8d2613c..057bae02efc 100644 --- a/src/java.base/share/classes/module-info.java +++ b/src/java.base/share/classes/module-info.java @@ -319,8 +319,6 @@ java.management.rmi, java.rmi, java.sql.rowset; - exports sun.security.action to - java.desktop; exports sun.security.internal.interfaces to jdk.crypto.cryptoki; exports sun.security.internal.spec to @@ -346,7 +344,6 @@ exports sun.security.tools to jdk.jartool; exports sun.security.util to - java.desktop, java.naming, java.rmi, java.security.jgss, diff --git a/src/java.desktop/share/classes/java/awt/Desktop.java b/src/java.desktop/share/classes/java/awt/Desktop.java index c3e89140dc9..3f73fa6cd81 100644 --- a/src/java.desktop/share/classes/java/awt/Desktop.java +++ b/src/java.desktop/share/classes/java/awt/Desktop.java @@ -38,7 +38,6 @@ import java.awt.desktop.SystemEventListener; import java.awt.peer.DesktopPeer; import java.io.File; -import java.io.FilePermission; import java.io.IOException; import java.net.URI; import java.net.URISyntaxException; @@ -47,7 +46,6 @@ import javax.swing.JMenuBar; import sun.awt.SunToolkit; -import sun.security.util.SecurityConstants; /** * The {@code Desktop} class allows interact with various desktop capabilities. @@ -274,15 +272,6 @@ private Desktop() { } } - private void checkEventsProcessingPermission() { - @SuppressWarnings("removal") - SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - sm.checkPermission(new RuntimePermission( - "canProcessApplicationEvents")); - } - } - /** * Returns the {@code Desktop} instance of the current * desktop context. On some platforms the Desktop API may not be @@ -395,7 +384,6 @@ private void checkActionSupport(Action actionType){ */ public void open(File file) throws IOException { file = new File(file.getPath()); - checkExec(); checkActionSupport(Action.OPEN); checkFileValidation(file); @@ -417,7 +405,6 @@ public void open(File file) throws IOException { */ public void edit(File file) throws IOException { file = new File(file.getPath()); - checkExec(); checkActionSupport(Action.EDIT); file.canWrite(); checkFileValidation(file); @@ -443,12 +430,6 @@ public void edit(File file) throws IOException { */ public void print(File file) throws IOException { file = new File(file.getPath()); - checkExec(); - @SuppressWarnings("removal") - SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - sm.checkPrintJobAccess(); - } checkActionSupport(Action.PRINT); checkFileValidation(file); if (file.isDirectory()) { @@ -475,7 +456,6 @@ public void print(File file) throws IOException { * @see java.net.URI */ public void browse(URI uri) throws IOException { - checkExec(); checkActionSupport(Action.BROWSE); Objects.requireNonNull(uri); peer.browse(uri); @@ -491,7 +471,6 @@ public void browse(URI uri) throws IOException { * found, or it fails to be launched */ public void mail() throws IOException { - checkExec(); checkActionSupport(Action.MAIL); URI mailtoURI = null; try{ @@ -528,7 +507,6 @@ public void mail() throws IOException { * @see java.net.URI */ public void mail(URI mailtoURI) throws IOException { - checkExec(); checkActionSupport(Action.MAIL); if (mailtoURI == null) throw new NullPointerException(); @@ -539,32 +517,6 @@ public void mail(URI mailtoURI) throws IOException { peer.mail(mailtoURI); } - private void checkExec() throws SecurityException { - @SuppressWarnings("removal") - SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - sm.checkPermission(new FilePermission("<<ALL FILES>>", - SecurityConstants.FILE_EXECUTE_ACTION)); - } - } - - private void checkRead() throws SecurityException { - @SuppressWarnings("removal") - SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - sm.checkPermission(new FilePermission("<<ALL FILES>>", - SecurityConstants.FILE_READ_ACTION)); - } - } - - private void checkQuitPermission() { - @SuppressWarnings("removal") - SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - sm.checkExit(0); - } - } - /** * Adds sub-types of {@link SystemEventListener} to listen for notifications * from the native system. @@ -583,7 +535,6 @@ private void checkQuitPermission() { * @since 9 */ public void addAppEventListener(final SystemEventListener listener) { - checkEventsProcessingPermission(); peer.addAppEventListener(listener); } @@ -605,7 +556,6 @@ public void addAppEventListener(final SystemEventListener listener) { * @since 9 */ public void removeAppEventListener(final SystemEventListener listener) { - checkEventsProcessingPermission(); peer.removeAppEventListener(listener); } @@ -624,7 +574,6 @@ public void removeAppEventListener(final SystemEventListener listener) { * @since 9 */ public void setAboutHandler(final AboutHandler aboutHandler) { - checkEventsProcessingPermission(); checkActionSupport(Action.APP_ABOUT); peer.setAboutHandler(aboutHandler); } @@ -644,7 +593,6 @@ public void setAboutHandler(final AboutHandler aboutHandler) { * @since 9 */ public void setPreferencesHandler(final PreferencesHandler preferencesHandler) { - checkEventsProcessingPermission(); checkActionSupport(Action.APP_PREFERENCES); peer.setPreferencesHandler(preferencesHandler); } @@ -668,9 +616,6 @@ public void setPreferencesHandler(final PreferencesHandler preferencesHandler) { * @since 9 */ public void setOpenFileHandler(final OpenFilesHandler openFileHandler) { - checkEventsProcessingPermission(); - checkExec(); - checkRead(); checkActionSupport(Action.APP_OPEN_FILE); peer.setOpenFileHandler(openFileHandler); } @@ -693,12 +638,6 @@ public void setOpenFileHandler(final OpenFilesHandler openFileHandler) { * @since 9 */ public void setPrintFileHandler(final PrintFilesHandler printFileHandler) { - checkEventsProcessingPermission(); - @SuppressWarnings("removal") - SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - sm.checkPrintJobAccess(); - } checkActionSupport(Action.APP_PRINT_FILE); peer.setPrintFileHandler(printFileHandler); } @@ -726,8 +665,6 @@ public void setPrintFileHandler(final PrintFilesHandler printFileHandler) { * @since 9 */ public void setOpenURIHandler(final OpenURIHandler openURIHandler) { - checkEventsProcessingPermission(); - checkExec(); checkActionSupport(Action.APP_OPEN_URI); peer.setOpenURIHandler(openURIHandler); } @@ -746,8 +683,6 @@ public void setOpenURIHandler(final OpenURIHandler openURIHandler) { * @since 9 */ public void setQuitHandler(final QuitHandler quitHandler) { - checkEventsProcessingPermission(); - checkQuitPermission(); checkActionSupport(Action.APP_QUIT_HANDLER); peer.setQuitHandler(quitHandler); } @@ -762,8 +697,6 @@ public void setQuitHandler(final QuitHandler quitHandler) { * @since 9 */ public void setQuitStrategy(final QuitStrategy strategy) { - checkEventsProcessingPermission(); - checkQuitPermission(); checkActionSupport(Action.APP_QUIT_STRATEGY); peer.setQuitStrategy(strategy); } @@ -788,8 +721,6 @@ public void setQuitStrategy(final QuitStrategy strategy) { * @since 9 */ public void enableSuddenTermination() { - checkEventsProcessingPermission(); - checkQuitPermission(); checkActionSupport(Action.APP_SUDDEN_TERMINATION); peer.enableSuddenTermination(); } @@ -806,8 +737,6 @@ public void enableSuddenTermination() { * @since 9 */ public void disableSuddenTermination() { - checkEventsProcessingPermission(); - checkQuitPermission(); checkActionSupport(Action.APP_SUDDEN_TERMINATION); peer.disableSuddenTermination(); } @@ -822,7 +751,6 @@ public void disableSuddenTermination() { * @since 9 */ public void requestForeground(final boolean allWindows) { - checkEventsProcessingPermission(); checkActionSupport(Action.APP_REQUEST_FOREGROUND); peer.requestForeground(allWindows); } @@ -839,8 +767,6 @@ public void requestForeground(final boolean allWindows) { * @since 9 */ public void openHelpViewer() { - checkExec(); - checkEventsProcessingPermission(); checkActionSupport(Action.APP_HELP_VIEWER); peer.openHelpViewer(); } @@ -854,7 +780,6 @@ public void openHelpViewer() { * @since 9 */ public void setDefaultMenuBar(final JMenuBar menuBar) { - checkEventsProcessingPermission(); checkActionSupport(Action.APP_MENU_BAR); if (menuBar != null) { @@ -881,7 +806,6 @@ public void setDefaultMenuBar(final JMenuBar menuBar) { */ public void browseFileDirectory(File file) { file = new File(file.getPath()); - checkExec(); checkActionSupport(Action.BROWSE_FILE_DIR); checkFileValidation(file); File parentFile = file.getParentFile(); @@ -903,13 +827,8 @@ public void browseFileDirectory(File file) { * * @since 9 */ - @SuppressWarnings("removal") public boolean moveToTrash(File file) { file = new File(file.getPath()); - SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - sm.checkDelete(file.getPath()); - } checkActionSupport(Action.MOVE_TO_TRASH); checkFileValidation(file); return peer.moveToTrash(file); From 2ea0364b6e3f10977f7b607d239c29ee616a8f7c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johan=20Sj=C3=B6len?= <jsjolen@openjdk.org> Date: Fri, 22 Nov 2024 08:55:27 +0000 Subject: [PATCH 177/311] 8343893: Test jdk/jfr/event/runtime/TestNativeMemoryUsageEvents.java failed: heap should have grown and NMT should show that: expected 0 > 0 Reviewed-by: gziemski, mgronlun, lmesnik --- src/hotspot/share/nmt/memoryFileTracker.cpp | 14 +++++--------- src/hotspot/share/nmt/memoryFileTracker.hpp | 17 +++++++++++++++++ src/hotspot/share/nmt/nmtUsage.cpp | 11 +++++++++++ src/hotspot/share/nmt/nmtUsage.hpp | 1 + test/jdk/ProblemList-zgc.txt | 2 -- 5 files changed, 34 insertions(+), 11 deletions(-) diff --git a/src/hotspot/share/nmt/memoryFileTracker.cpp b/src/hotspot/share/nmt/memoryFileTracker.cpp index ede483ed337..0777d5aafc3 100644 --- a/src/hotspot/share/nmt/memoryFileTracker.cpp +++ b/src/hotspot/share/nmt/memoryFileTracker.cpp @@ -179,15 +179,11 @@ const GrowableArrayCHeap<MemoryFileTracker::MemoryFile*, mtNMT>& MemoryFileTrack }; void MemoryFileTracker::summary_snapshot(VirtualMemorySnapshot* snapshot) const { - for (int d = 0; d < _files.length(); d++) { - const MemoryFile* file = _files.at(d); - for (int i = 0; i < mt_number_of_tags; i++) { - VirtualMemory* snap = snapshot->by_type(NMTUtil::index_to_tag(i)); - const VirtualMemory* current = file->_summary.by_type(NMTUtil::index_to_tag(i)); - // Only account the committed memory. - snap->commit_memory(current->committed()); - } - } + iterate_summary([&](MemTag tag, const VirtualMemory* current) { + VirtualMemory* snap = snapshot->by_type(tag); + // Only account the committed memory. + snap->commit_memory(current->committed()); + }); } void MemoryFileTracker::Instance::summary_snapshot(VirtualMemorySnapshot* snapshot) { diff --git a/src/hotspot/share/nmt/memoryFileTracker.hpp b/src/hotspot/share/nmt/memoryFileTracker.hpp index 42902701a16..94f9cb2006c 100644 --- a/src/hotspot/share/nmt/memoryFileTracker.hpp +++ b/src/hotspot/share/nmt/memoryFileTracker.hpp @@ -39,6 +39,8 @@ // The MemoryFileTracker tracks memory of 'memory files', // storage with its own memory space separate from the process. // A typical example of such a file is a memory mapped file. +// All memory is accounted as committed, there is no reserved memory. +// Any reserved memory is expected to exist in the VirtualMemoryTracker. class MemoryFileTracker { friend class NMTMemoryFileTrackerTest; @@ -72,6 +74,16 @@ class MemoryFileTracker { MemoryFile* make_file(const char* descriptive_name); void free_file(MemoryFile* file); + template<typename F> + void iterate_summary(F f) const { + for (int d = 0; d < _files.length(); d++) { + const MemoryFile* file = _files.at(d); + for (int i = 0; i < mt_number_of_tags; i++) { + f(NMTUtil::index_to_tag(i), file->_summary.by_type(NMTUtil::index_to_tag(i))); + } + } + } + void summary_snapshot(VirtualMemorySnapshot* snapshot) const; // Print detailed report of file @@ -99,6 +111,11 @@ class MemoryFileTracker { const NativeCallStack& stack, MemTag mem_tag); static void free_memory(MemoryFile* device, size_t offset, size_t size); + template<typename F> + static void iterate_summary(F f) { + _tracker->iterate_summary(f); + }; + static void summary_snapshot(VirtualMemorySnapshot* snapshot); static void print_report_on(const MemoryFile* device, outputStream* stream, size_t scale); diff --git a/src/hotspot/share/nmt/nmtUsage.cpp b/src/hotspot/share/nmt/nmtUsage.cpp index a854f001593..aa1d681b8a5 100644 --- a/src/hotspot/share/nmt/nmtUsage.cpp +++ b/src/hotspot/share/nmt/nmtUsage.cpp @@ -24,6 +24,7 @@ #include "precompiled.hpp" #include "nmt/mallocTracker.hpp" +#include "nmt/memoryFileTracker.hpp" #include "nmt/nmtCommon.hpp" #include "nmt/nmtUsage.hpp" #include "nmt/threadStackTracker.hpp" @@ -90,6 +91,16 @@ void NMTUsage::update_vm_usage() { _vm_total.reserved += vm->reserved(); _vm_total.committed += vm->committed(); } + + { // MemoryFileTracker addition + using MFT = MemoryFileTracker::Instance; + MFT::Locker lock; + MFT::iterate_summary([&](MemTag tag, const VirtualMemory* vm) { + int i = NMTUtil::tag_to_index(tag); + _vm_by_type[i].committed += vm->committed(); + _vm_total.committed += vm->committed(); + }); + } } void NMTUsage::refresh() { diff --git a/src/hotspot/share/nmt/nmtUsage.hpp b/src/hotspot/share/nmt/nmtUsage.hpp index 390d207250c..2011e7ed240 100644 --- a/src/hotspot/share/nmt/nmtUsage.hpp +++ b/src/hotspot/share/nmt/nmtUsage.hpp @@ -26,6 +26,7 @@ #define SHARE_NMT_NMTUSAGE_HPP #include "memory/allocation.hpp" +#include "nmt/memTag.hpp" #include "utilities/globalDefinitions.hpp" struct NMTUsagePair { diff --git a/test/jdk/ProblemList-zgc.txt b/test/jdk/ProblemList-zgc.txt index cab33229a5b..e81ac813747 100644 --- a/test/jdk/ProblemList-zgc.txt +++ b/test/jdk/ProblemList-zgc.txt @@ -38,5 +38,3 @@ sun/tools/jhsdb/heapconfig/JMapHeapConfigTest.java 8307393 generic-all sun/tools/jhsdb/HeapDumpTestWithActiveProcess.java 8307393 generic-all com/sun/jdi/ThreadMemoryLeakTest.java 8307402 generic-all - -jdk/jfr/event/runtime/TestNativeMemoryUsageEvents.java 8343893 generic-all From a07b72bfcfa603453ea042e89adeb9dcec8bf63a Mon Sep 17 00:00:00 2001 From: Daniel Fuchs <dfuchs@openjdk.org> Date: Fri, 22 Nov 2024 09:55:07 +0000 Subject: [PATCH 178/311] 8344346: java/net/httpclient/ShutdownNow.java fails with java.lang.AssertionError: client was still running, but exited after further delay: timeout should be adjusted Reviewed-by: jpai --- test/jdk/java/net/httpclient/ShutdownNow.java | 17 ++++------------- 1 file changed, 4 insertions(+), 13 deletions(-) diff --git a/test/jdk/java/net/httpclient/ShutdownNow.java b/test/jdk/java/net/httpclient/ShutdownNow.java index 47eb1f6d7c9..d175840724d 100644 --- a/test/jdk/java/net/httpclient/ShutdownNow.java +++ b/test/jdk/java/net/httpclient/ShutdownNow.java @@ -30,6 +30,7 @@ * isTerminated. * @library /test/lib /test/jdk/java/net/httpclient/lib * @build jdk.httpclient.test.lib.http2.Http2TestServer jdk.test.lib.net.SimpleSSLContext + * jdk.test.lib.RandomFactory jdk.test.lib.Utils * ReferenceTracker * @run testng/othervm * -Djdk.internal.httpclient.debug=true @@ -41,8 +42,6 @@ import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; -import java.net.InetAddress; -import java.net.InetSocketAddress; import java.net.URI; import java.net.http.HttpClient; import java.net.http.HttpClient.Redirect; @@ -58,20 +57,12 @@ import java.util.concurrent.CompletionException; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ExecutionException; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.concurrent.RejectedExecutionException; -import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicLong; import jdk.httpclient.test.lib.common.HttpServerAdapters; -import jdk.httpclient.test.lib.http2.Http2TestServer; import javax.net.ssl.SSLContext; -import javax.net.ssl.SSLHandshakeException; -import com.sun.net.httpserver.HttpServer; -import com.sun.net.httpserver.HttpsConfigurator; -import com.sun.net.httpserver.HttpsServer; import jdk.test.lib.RandomFactory; +import jdk.test.lib.Utils; import jdk.test.lib.net.SimpleSSLContext; import org.testng.annotations.AfterTest; import org.testng.annotations.BeforeTest; @@ -211,7 +202,7 @@ void testConcurrent(String uriString) throws Exception { } CompletableFuture.allOf(responses.toArray(new CompletableFuture<?>[0])).get(); } finally { - if (client.awaitTermination(Duration.ofMillis(2500))) { + if (client.awaitTermination(Duration.ofMillis(Utils.adjustTimeout(1000)))) { out.println("Client terminated within expected delay"); assertTrue(client.isTerminated()); } else { @@ -277,7 +268,7 @@ void testSequential(String uriString) throws Exception { }).thenCompose((c) -> c).get(); } } finally { - if (client.awaitTermination(Duration.ofMillis(2500))) { + if (client.awaitTermination(Duration.ofMillis(Utils.adjustTimeout(1000)))) { out.println("Client terminated within expected delay"); assertTrue(client.isTerminated()); } else { From 8903854e01d2912218c4ea6973f0a36fd20167c7 Mon Sep 17 00:00:00 2001 From: Matthias Baesken <mbaesken@openjdk.org> Date: Fri, 22 Nov 2024 11:10:32 +0000 Subject: [PATCH 179/311] 8344718: Test runtime/cds/appcds/jigsaw/addmods/AddmodsOption.java fails on Linuxppc64le after JDK-8344239 Reviewed-by: ccheung, mdoerr --- .../runtime/cds/appcds/jigsaw/addmods/AddmodsOption.java | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/test/hotspot/jtreg/runtime/cds/appcds/jigsaw/addmods/AddmodsOption.java b/test/hotspot/jtreg/runtime/cds/appcds/jigsaw/addmods/AddmodsOption.java index 9328cc86569..2d8f90e61fe 100644 --- a/test/hotspot/jtreg/runtime/cds/appcds/jigsaw/addmods/AddmodsOption.java +++ b/test/hotspot/jtreg/runtime/cds/appcds/jigsaw/addmods/AddmodsOption.java @@ -34,13 +34,10 @@ */ import jdk.test.lib.process.OutputAnalyzer; -import jdk.test.whitebox.WhiteBox; +import jdk.test.whitebox.code.Compiler; public class AddmodsOption { - private static final WhiteBox WB = WhiteBox.getWhiteBox(); - private static final boolean isJVMCISupported = WB.getBooleanVMFlag("EnableJVMCI"); - public static void main(String[] args) throws Exception { final String moduleOption = "jdk.httpserver/sun.net.httpserver.simpleserver.Main"; final String incubatorModule = "jdk.incubator.vector"; @@ -143,7 +140,7 @@ public static void main(String[] args) throws Exception { .shouldContain("subgraph jdk.internal.module.ArchivedBootLayer is not recorde") .shouldHaveExitValue(0); - if (isJVMCISupported) { + if (Compiler.isJVMCIEnabled()) { // dump an archive with JVMCI option which indirectly adds the // jdk.internal.vm.ci module using the --add-modules option archiveName = TestCommon.getNewArchiveName("jvmci-module"); From 847f65c14a8fea3d5e2ee9d920c458b8923da3b4 Mon Sep 17 00:00:00 2001 From: Tobias Hartmann <thartmann@openjdk.org> Date: Fri, 22 Nov 2024 11:37:35 +0000 Subject: [PATCH 180/311] 8344844: ciReplay tests fail with -XX:+UseCompactObjectHeaders because CDS is disabled since JDK-8341553 Reviewed-by: epeter, rcastanedalo --- test/hotspot/jtreg/compiler/ciReplay/CiReplayBase.java | 10 +++++++++- test/hotspot/jtreg/compiler/ciReplay/InliningBase.java | 10 +++++++++- .../ciReplay/TestInliningProtectionDomain.java | 7 +++++-- 3 files changed, 23 insertions(+), 4 deletions(-) diff --git a/test/hotspot/jtreg/compiler/ciReplay/CiReplayBase.java b/test/hotspot/jtreg/compiler/ciReplay/CiReplayBase.java index dcb8dff8f7d..a974a09d615 100644 --- a/test/hotspot/jtreg/compiler/ciReplay/CiReplayBase.java +++ b/test/hotspot/jtreg/compiler/ciReplay/CiReplayBase.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -30,6 +30,9 @@ import jdk.test.lib.process.OutputAnalyzer; import jdk.test.lib.process.ProcessTools; import jdk.test.lib.util.CoreUtils; +import jdk.test.whitebox.WhiteBox; + +import jtreg.SkippedException; import java.io.BufferedReader; import java.io.File; @@ -126,6 +129,11 @@ public CiReplayBase(String args[]) { } public void runTest(boolean needCoreDump, String... args) { + // The CiReplay tests don't work properly when CDS is disabled + boolean cdsEnabled = WhiteBox.getWhiteBox().isSharingEnabled(); + if (!cdsEnabled) { + throw new SkippedException("CDS is not available for this JDK."); + } cleanup(); if (generateReplay(needCoreDump, args)) { testAction(); diff --git a/test/hotspot/jtreg/compiler/ciReplay/InliningBase.java b/test/hotspot/jtreg/compiler/ciReplay/InliningBase.java index 4cf4045aebc..e3ec7527123 100644 --- a/test/hotspot/jtreg/compiler/ciReplay/InliningBase.java +++ b/test/hotspot/jtreg/compiler/ciReplay/InliningBase.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -24,6 +24,9 @@ package compiler.ciReplay; import jdk.test.lib.Asserts; +import jdk.test.whitebox.WhiteBox; + +import jtreg.SkippedException; import java.io.IOException; import java.nio.file.Files; @@ -51,6 +54,11 @@ protected InliningBase(Class<?> testClass) { } protected void runTest() { + // The CiReplay tests don't work properly when CDS is disabled + boolean cdsEnabled = WhiteBox.getWhiteBox().isSharingEnabled(); + if (!cdsEnabled) { + throw new SkippedException("CDS is not available for this JDK."); + } runTest(commandLineNormal.toArray(new String[0])); } diff --git a/test/hotspot/jtreg/compiler/ciReplay/TestInliningProtectionDomain.java b/test/hotspot/jtreg/compiler/ciReplay/TestInliningProtectionDomain.java index 31e05ba7ecf..339b6b59f4e 100644 --- a/test/hotspot/jtreg/compiler/ciReplay/TestInliningProtectionDomain.java +++ b/test/hotspot/jtreg/compiler/ciReplay/TestInliningProtectionDomain.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -28,7 +28,10 @@ * @summary Testing that ciReplay inlining does not fail with unresolved signature classes. * @requires vm.flightRecorder != true & vm.compMode != "Xint" & vm.compMode != "Xcomp" & vm.debug == true & vm.compiler2.enabled * @modules java.base/jdk.internal.misc - * @run driver compiler.ciReplay.TestInliningProtectionDomain + * @build jdk.test.whitebox.WhiteBox + * @run driver jdk.test.lib.helpers.ClassFileInstaller jdk.test.whitebox.WhiteBox + * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI + * compiler.ciReplay.TestInliningProtectionDomain */ package compiler.ciReplay; From bf374c33f5cd5048cabe151050fada773b7d9458 Mon Sep 17 00:00:00 2001 From: Raffaello Giulietti <rgiulietti@openjdk.org> Date: Fri, 22 Nov 2024 11:41:04 +0000 Subject: [PATCH 181/311] 8343453: Modernize FloatingDecimal tests Reviewed-by: darcy --- .../jdk/internal/math/FloatingDecimal.java | 2 +- .../FloatingDecimal/OldFDBigIntForTest.java | 491 ---- .../OldFloatingDecimalForTest.java | 2434 ----------------- .../FloatingDecimal/TestFloatingDecimal.java | 233 +- test/jdk/jdk/internal/math/ToString.java | 73 - 5 files changed, 36 insertions(+), 3197 deletions(-) delete mode 100644 test/jdk/jdk/internal/math/FloatingDecimal/OldFDBigIntForTest.java delete mode 100644 test/jdk/jdk/internal/math/FloatingDecimal/OldFloatingDecimalForTest.java delete mode 100644 test/jdk/jdk/internal/math/ToString.java diff --git a/src/java.base/share/classes/jdk/internal/math/FloatingDecimal.java b/src/java.base/share/classes/jdk/internal/math/FloatingDecimal.java index dcfa9e88da2..0c1732956c9 100644 --- a/src/java.base/share/classes/jdk/internal/math/FloatingDecimal.java +++ b/src/java.base/share/classes/jdk/internal/math/FloatingDecimal.java @@ -1872,7 +1872,7 @@ static ASCIIToBinaryConverter readJavaFormatString( String in ) throws NumberFor } } // look for and process decimal floating-point string - byte[] digits = new byte[ len ]; + byte[] digits = new byte[len]; boolean decSeen = false; int nDigits = 0; int decPt = 0; diff --git a/test/jdk/jdk/internal/math/FloatingDecimal/OldFDBigIntForTest.java b/test/jdk/jdk/internal/math/FloatingDecimal/OldFDBigIntForTest.java deleted file mode 100644 index f500040a922..00000000000 --- a/test/jdk/jdk/internal/math/FloatingDecimal/OldFDBigIntForTest.java +++ /dev/null @@ -1,491 +0,0 @@ -/* - * Copyright (c) 1996, 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -//package jdk.internal.math; - -/* - * A really, really simple bigint package - * tailored to the needs of floating base conversion. - */ -class OldFDBigIntForTest { - int nWords; // number of words used - int data[]; // value: data[0] is least significant - - - public OldFDBigIntForTest( int v ){ - nWords = 1; - data = new int[1]; - data[0] = v; - } - - public OldFDBigIntForTest( long v ){ - data = new int[2]; - data[0] = (int)v; - data[1] = (int)(v>>>32); - nWords = (data[1]==0) ? 1 : 2; - } - - public OldFDBigIntForTest( OldFDBigIntForTest other ){ - data = new int[nWords = other.nWords]; - System.arraycopy( other.data, 0, data, 0, nWords ); - } - - private OldFDBigIntForTest( int [] d, int n ){ - data = d; - nWords = n; - } - - public OldFDBigIntForTest( long seed, char digit[], int nd0, int nd ){ - int n= (nd+8)/9; // estimate size needed. - if ( n < 2 ) n = 2; - data = new int[n]; // allocate enough space - data[0] = (int)seed; // starting value - data[1] = (int)(seed>>>32); - nWords = (data[1]==0) ? 1 : 2; - int i = nd0; - int limit = nd-5; // slurp digits 5 at a time. - int v; - while ( i < limit ){ - int ilim = i+5; - v = (int)digit[i++]-(int)'0'; - while( i <ilim ){ - v = 10*v + (int)digit[i++]-(int)'0'; - } - multaddMe( 100000, v); // ... where 100000 is 10^5. - } - int factor = 1; - v = 0; - while ( i < nd ){ - v = 10*v + (int)digit[i++]-(int)'0'; - factor *= 10; - } - if ( factor != 1 ){ - multaddMe( factor, v ); - } - } - - /* - * Left shift by c bits. - * Shifts this in place. - */ - public void - lshiftMe( int c )throws IllegalArgumentException { - if ( c <= 0 ){ - if ( c == 0 ) - return; // silly. - else - throw new IllegalArgumentException("negative shift count"); - } - int wordcount = c>>5; - int bitcount = c & 0x1f; - int anticount = 32-bitcount; - int t[] = data; - int s[] = data; - if ( nWords+wordcount+1 > t.length ){ - // reallocate. - t = new int[ nWords+wordcount+1 ]; - } - int target = nWords+wordcount; - int src = nWords-1; - if ( bitcount == 0 ){ - // special hack, since an anticount of 32 won't go! - System.arraycopy( s, 0, t, wordcount, nWords ); - target = wordcount-1; - } else { - t[target--] = s[src]>>>anticount; - while ( src >= 1 ){ - t[target--] = (s[src]<<bitcount) | (s[--src]>>>anticount); - } - t[target--] = s[src]<<bitcount; - } - while( target >= 0 ){ - t[target--] = 0; - } - data = t; - nWords += wordcount + 1; - // may have constructed high-order word of 0. - // if so, trim it - while ( nWords > 1 && data[nWords-1] == 0 ) - nWords--; - } - - /* - * normalize this number by shifting until - * the MSB of the number is at 0x08000000. - * This is in preparation for quoRemIteration, below. - * The idea is that, to make division easier, we want the - * divisor to be "normalized" -- usually this means shifting - * the MSB into the high words sign bit. But because we know that - * the quotient will be 0 < q < 10, we would like to arrange that - * the dividend not span up into another word of precision. - * (This needs to be explained more clearly!) - */ - public int - normalizeMe() throws IllegalArgumentException { - int src; - int wordcount = 0; - int bitcount = 0; - int v = 0; - for ( src= nWords-1 ; src >= 0 && (v=data[src]) == 0 ; src--){ - wordcount += 1; - } - if ( src < 0 ){ - // oops. Value is zero. Cannot normalize it! - throw new IllegalArgumentException("zero value"); - } - /* - * In most cases, we assume that wordcount is zero. This only - * makes sense, as we try not to maintain any high-order - * words full of zeros. In fact, if there are zeros, we will - * simply SHORTEN our number at this point. Watch closely... - */ - nWords -= wordcount; - /* - * Compute how far left we have to shift v s.t. its highest- - * order bit is in the right place. Then call lshiftMe to - * do the work. - */ - if ( (v & 0xf0000000) != 0 ){ - // will have to shift up into the next word. - // too bad. - for( bitcount = 32 ; (v & 0xf0000000) != 0 ; bitcount-- ) - v >>>= 1; - } else { - while ( v <= 0x000fffff ){ - // hack: byte-at-a-time shifting - v <<= 8; - bitcount += 8; - } - while ( v <= 0x07ffffff ){ - v <<= 1; - bitcount += 1; - } - } - if ( bitcount != 0 ) - lshiftMe( bitcount ); - return bitcount; - } - - /* - * Multiply a OldFDBigIntForTest by an int. - * Result is a new OldFDBigIntForTest. - */ - public OldFDBigIntForTest - mult( int iv ) { - long v = iv; - int r[]; - long p; - - // guess adequate size of r. - r = new int[ ( v * ((long)data[nWords-1]&0xffffffffL) > 0xfffffffL ) ? nWords+1 : nWords ]; - p = 0L; - for( int i=0; i < nWords; i++ ) { - p += v * ((long)data[i]&0xffffffffL); - r[i] = (int)p; - p >>>= 32; - } - if ( p == 0L){ - return new OldFDBigIntForTest( r, nWords ); - } else { - r[nWords] = (int)p; - return new OldFDBigIntForTest( r, nWords+1 ); - } - } - - /* - * Multiply a OldFDBigIntForTest by an int and add another int. - * Result is computed in place. - * Hope it fits! - */ - public void - multaddMe( int iv, int addend ) { - long v = iv; - long p; - - // unroll 0th iteration, doing addition. - p = v * ((long)data[0]&0xffffffffL) + ((long)addend&0xffffffffL); - data[0] = (int)p; - p >>>= 32; - for( int i=1; i < nWords; i++ ) { - p += v * ((long)data[i]&0xffffffffL); - data[i] = (int)p; - p >>>= 32; - } - if ( p != 0L){ - data[nWords] = (int)p; // will fail noisily if illegal! - nWords++; - } - } - - /* - * Multiply a OldFDBigIntForTest by another OldFDBigIntForTest. - * Result is a new OldFDBigIntForTest. - */ - public OldFDBigIntForTest - mult( OldFDBigIntForTest other ){ - // crudely guess adequate size for r - int r[] = new int[ nWords + other.nWords ]; - int i; - // I think I am promised zeros... - - for( i = 0; i < this.nWords; i++ ){ - long v = (long)this.data[i] & 0xffffffffL; // UNSIGNED CONVERSION - long p = 0L; - int j; - for( j = 0; j < other.nWords; j++ ){ - p += ((long)r[i+j]&0xffffffffL) + v*((long)other.data[j]&0xffffffffL); // UNSIGNED CONVERSIONS ALL 'ROUND. - r[i+j] = (int)p; - p >>>= 32; - } - r[i+j] = (int)p; - } - // compute how much of r we actually needed for all that. - for ( i = r.length-1; i> 0; i--) - if ( r[i] != 0 ) - break; - return new OldFDBigIntForTest( r, i+1 ); - } - - /* - * Add one OldFDBigIntForTest to another. Return a OldFDBigIntForTest - */ - public OldFDBigIntForTest - add( OldFDBigIntForTest other ){ - int i; - int a[], b[]; - int n, m; - long c = 0L; - // arrange such that a.nWords >= b.nWords; - // n = a.nWords, m = b.nWords - if ( this.nWords >= other.nWords ){ - a = this.data; - n = this.nWords; - b = other.data; - m = other.nWords; - } else { - a = other.data; - n = other.nWords; - b = this.data; - m = this.nWords; - } - int r[] = new int[ n ]; - for ( i = 0; i < n; i++ ){ - c += (long)a[i] & 0xffffffffL; - if ( i < m ){ - c += (long)b[i] & 0xffffffffL; - } - r[i] = (int) c; - c >>= 32; // signed shift. - } - if ( c != 0L ){ - // oops -- carry out -- need longer result. - int s[] = new int[ r.length+1 ]; - System.arraycopy( r, 0, s, 0, r.length ); - s[i++] = (int)c; - return new OldFDBigIntForTest( s, i ); - } - return new OldFDBigIntForTest( r, i ); - } - - /* - * Subtract one OldFDBigIntForTest from another. Return a OldFDBigIntForTest - * Assert that the result is positive. - */ - public OldFDBigIntForTest - sub( OldFDBigIntForTest other ){ - int r[] = new int[ this.nWords ]; - int i; - int n = this.nWords; - int m = other.nWords; - int nzeros = 0; - long c = 0L; - for ( i = 0; i < n; i++ ){ - c += (long)this.data[i] & 0xffffffffL; - if ( i < m ){ - c -= (long)other.data[i] & 0xffffffffL; - } - if ( ( r[i] = (int) c ) == 0 ) - nzeros++; - else - nzeros = 0; - c >>= 32; // signed shift - } - assert c == 0L : c; // borrow out of subtract - assert dataInRangeIsZero(i, m, other); // negative result of subtract - return new OldFDBigIntForTest( r, n-nzeros ); - } - - private static boolean dataInRangeIsZero(int i, int m, OldFDBigIntForTest other) { - while ( i < m ) - if (other.data[i++] != 0) - return false; - return true; - } - - /* - * Compare OldFDBigIntForTest with another OldFDBigIntForTest. Return an integer - * >0: this > other - * 0: this == other - * <0: this < other - */ - public int - cmp( OldFDBigIntForTest other ){ - int i; - if ( this.nWords > other.nWords ){ - // if any of my high-order words is non-zero, - // then the answer is evident - int j = other.nWords-1; - for ( i = this.nWords-1; i > j ; i-- ) - if ( this.data[i] != 0 ) return 1; - }else if ( this.nWords < other.nWords ){ - // if any of other's high-order words is non-zero, - // then the answer is evident - int j = this.nWords-1; - for ( i = other.nWords-1; i > j ; i-- ) - if ( other.data[i] != 0 ) return -1; - } else{ - i = this.nWords-1; - } - for ( ; i > 0 ; i-- ) - if ( this.data[i] != other.data[i] ) - break; - // careful! want unsigned compare! - // use brute force here. - int a = this.data[i]; - int b = other.data[i]; - if ( a < 0 ){ - // a is really big, unsigned - if ( b < 0 ){ - return a-b; // both big, negative - } else { - return 1; // b not big, answer is obvious; - } - } else { - // a is not really big - if ( b < 0 ) { - // but b is really big - return -1; - } else { - return a - b; - } - } - } - - /* - * Compute - * q = (int)( this / S ) - * this = 10 * ( this mod S ) - * Return q. - * This is the iteration step of digit development for output. - * We assume that S has been normalized, as above, and that - * "this" has been lshift'ed accordingly. - * Also assume, of course, that the result, q, can be expressed - * as an integer, 0 <= q < 10. - */ - public int - quoRemIteration( OldFDBigIntForTest S )throws IllegalArgumentException { - // ensure that this and S have the same number of - // digits. If S is properly normalized and q < 10 then - // this must be so. - if ( nWords != S.nWords ){ - throw new IllegalArgumentException("disparate values"); - } - // estimate q the obvious way. We will usually be - // right. If not, then we're only off by a little and - // will re-add. - int n = nWords-1; - long q = ((long)data[n]&0xffffffffL) / (long)S.data[n]; - long diff = 0L; - for ( int i = 0; i <= n ; i++ ){ - diff += ((long)data[i]&0xffffffffL) - q*((long)S.data[i]&0xffffffffL); - data[i] = (int)diff; - diff >>= 32; // N.B. SIGNED shift. - } - if ( diff != 0L ) { - // damn, damn, damn. q is too big. - // add S back in until this turns +. This should - // not be very many times! - long sum = 0L; - while ( sum == 0L ){ - sum = 0L; - for ( int i = 0; i <= n; i++ ){ - sum += ((long)data[i]&0xffffffffL) + ((long)S.data[i]&0xffffffffL); - data[i] = (int) sum; - sum >>= 32; // Signed or unsigned, answer is 0 or 1 - } - /* - * Originally the following line read - * "if ( sum !=0 && sum != -1 )" - * but that would be wrong, because of the - * treatment of the two values as entirely unsigned, - * it would be impossible for a carry-out to be interpreted - * as -1 -- it would have to be a single-bit carry-out, or - * +1. - */ - assert sum == 0 || sum == 1 : sum; // carry out of division correction - q -= 1; - } - } - // finally, we can multiply this by 10. - // it cannot overflow, right, as the high-order word has - // at least 4 high-order zeros! - long p = 0L; - for ( int i = 0; i <= n; i++ ){ - p += 10*((long)data[i]&0xffffffffL); - data[i] = (int)p; - p >>= 32; // SIGNED shift. - } - assert p == 0L : p; // Carry out of *10 - return (int)q; - } - - public long - longValue(){ - // if this can be represented as a long, return the value - assert this.nWords > 0 : this.nWords; // longValue confused - - if (this.nWords == 1) - return ((long)data[0]&0xffffffffL); - - assert dataInRangeIsZero(2, this.nWords, this); // value too big - assert data[1] >= 0; // value too big - return ((long)(data[1]) << 32) | ((long)data[0]&0xffffffffL); - } - - public String - toString() { - StringBuffer r = new StringBuffer(30); - r.append('['); - int i = Math.min( nWords-1, data.length-1) ; - if ( nWords > data.length ){ - r.append( "("+data.length+"<"+nWords+"!)" ); - } - for( ; i> 0 ; i-- ){ - r.append( Integer.toHexString( data[i] ) ); - r.append(' '); - } - r.append( Integer.toHexString( data[0] ) ); - r.append(']'); - return new String( r ); - } -} diff --git a/test/jdk/jdk/internal/math/FloatingDecimal/OldFloatingDecimalForTest.java b/test/jdk/jdk/internal/math/FloatingDecimal/OldFloatingDecimalForTest.java deleted file mode 100644 index 9978c7870c2..00000000000 --- a/test/jdk/jdk/internal/math/FloatingDecimal/OldFloatingDecimalForTest.java +++ /dev/null @@ -1,2434 +0,0 @@ -/* - * Copyright (c) 1996, 2022, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -//package jdk.internal.math; - -import java.util.regex.*; - -public class OldFloatingDecimalForTest{ - boolean isExceptional; - boolean isNegative; - int decExponent; - char digits[]; - int nDigits; - int bigIntExp; - int bigIntNBits; - boolean mustSetRoundDir = false; - boolean fromHex = false; - int roundDir = 0; // set by doubleValue - - /* - * The fields below provides additional information about the result of - * the binary to decimal digits conversion done in dtoa() and roundup() - * methods. They are changed if needed by those two methods. - */ - - // True if the dtoa() binary to decimal conversion was exact. - boolean exactDecimalConversion = false; - - // True if the result of the binary to decimal conversion was rounded-up - // at the end of the conversion process, i.e. roundUp() method was called. - boolean decimalDigitsRoundedUp = false; - - private OldFloatingDecimalForTest( boolean negSign, int decExponent, char []digits, int n, boolean e ) - { - isNegative = negSign; - isExceptional = e; - this.decExponent = decExponent; - this.digits = digits; - this.nDigits = n; - } - - /* - * Constants of the implementation - * Most are IEEE-754 related. - * (There are more really boring constants at the end.) - */ - static final long signMask = 0x8000000000000000L; - static final long expMask = 0x7ff0000000000000L; - static final long fractMask= ~(signMask|expMask); - static final int expShift = 52; - static final int expBias = 1023; - static final long fractHOB = ( 1L<<expShift ); // assumed High-Order bit - static final long expOne = ((long)expBias)<<expShift; // exponent of 1.0 - static final int maxSmallBinExp = 62; - static final int minSmallBinExp = -( 63 / 3 ); - static final int maxDecimalDigits = 15; - static final int maxDecimalExponent = 308; - static final int minDecimalExponent = -324; - static final int bigDecimalExponent = 324; // i.e. abs(minDecimalExponent) - - static final long highbyte = 0xff00000000000000L; - static final long highbit = 0x8000000000000000L; - static final long lowbytes = ~highbyte; - - static final int singleSignMask = 0x80000000; - static final int singleExpMask = 0x7f800000; - static final int singleFractMask = ~(singleSignMask|singleExpMask); - static final int singleExpShift = 23; - static final int singleFractHOB = 1<<singleExpShift; - static final int singleExpBias = 127; - static final int singleMaxDecimalDigits = 7; - static final int singleMaxDecimalExponent = 38; - static final int singleMinDecimalExponent = -45; - - static final int intDecimalDigits = 9; - - - /* - * count number of bits from high-order 1 bit to low-order 1 bit, - * inclusive. - */ - private static int - countBits( long v ){ - // - // the strategy is to shift until we get a non-zero sign bit - // then shift until we have no bits left, counting the difference. - // we do byte shifting as a hack. Hope it helps. - // - if ( v == 0L ) return 0; - - while ( ( v & highbyte ) == 0L ){ - v <<= 8; - } - while ( v > 0L ) { // i.e. while ((v&highbit) == 0L ) - v <<= 1; - } - - int n = 0; - while (( v & lowbytes ) != 0L ){ - v <<= 8; - n += 8; - } - while ( v != 0L ){ - v <<= 1; - n += 1; - } - return n; - } - - /* - * Keep big powers of 5 handy for future reference. - */ - private static OldFDBigIntForTest b5p[]; - - private static synchronized OldFDBigIntForTest - big5pow( int p ){ - assert p >= 0 : p; // negative power of 5 - if ( b5p == null ){ - b5p = new OldFDBigIntForTest[ p+1 ]; - }else if (b5p.length <= p ){ - OldFDBigIntForTest t[] = new OldFDBigIntForTest[ p+1 ]; - System.arraycopy( b5p, 0, t, 0, b5p.length ); - b5p = t; - } - if ( b5p[p] != null ) - return b5p[p]; - else if ( p < small5pow.length ) - return b5p[p] = new OldFDBigIntForTest( small5pow[p] ); - else if ( p < long5pow.length ) - return b5p[p] = new OldFDBigIntForTest( long5pow[p] ); - else { - // construct the value. - // recursively. - int q, r; - // in order to compute 5^p, - // compute its square root, 5^(p/2) and square. - // or, let q = p / 2, r = p -q, then - // 5^p = 5^(q+r) = 5^q * 5^r - q = p >> 1; - r = p - q; - OldFDBigIntForTest bigq = b5p[q]; - if ( bigq == null ) - bigq = big5pow ( q ); - if ( r < small5pow.length ){ - return (b5p[p] = bigq.mult( small5pow[r] ) ); - }else{ - OldFDBigIntForTest bigr = b5p[ r ]; - if ( bigr == null ) - bigr = big5pow( r ); - return (b5p[p] = bigq.mult( bigr ) ); - } - } - } - - // - // a common operation - // - private static OldFDBigIntForTest - multPow52( OldFDBigIntForTest v, int p5, int p2 ){ - if ( p5 != 0 ){ - if ( p5 < small5pow.length ){ - v = v.mult( small5pow[p5] ); - } else { - v = v.mult( big5pow( p5 ) ); - } - } - if ( p2 != 0 ){ - v.lshiftMe( p2 ); - } - return v; - } - - // - // another common operation - // - private static OldFDBigIntForTest - constructPow52( int p5, int p2 ){ - OldFDBigIntForTest v = new OldFDBigIntForTest( big5pow( p5 ) ); - if ( p2 != 0 ){ - v.lshiftMe( p2 ); - } - return v; - } - - /* - * Make a floating double into a OldFDBigIntForTest. - * This could also be structured as a OldFDBigIntForTest - * constructor, but we'd have to build a lot of knowledge - * about floating-point representation into it, and we don't want to. - * - * AS A SIDE EFFECT, THIS METHOD WILL SET THE INSTANCE VARIABLES - * bigIntExp and bigIntNBits - * - */ - private OldFDBigIntForTest - doubleToBigInt( double dval ){ - long lbits = Double.doubleToLongBits( dval ) & ~signMask; - int binexp = (int)(lbits >>> expShift); - lbits &= fractMask; - if ( binexp > 0 ){ - lbits |= fractHOB; - } else { - assert lbits != 0L : lbits; // doubleToBigInt(0.0) - binexp +=1; - while ( (lbits & fractHOB ) == 0L){ - lbits <<= 1; - binexp -= 1; - } - } - binexp -= expBias; - int nbits = countBits( lbits ); - /* - * We now know where the high-order 1 bit is, - * and we know how many there are. - */ - int lowOrderZeros = expShift+1-nbits; - lbits >>>= lowOrderZeros; - - bigIntExp = binexp+1-nbits; - bigIntNBits = nbits; - return new OldFDBigIntForTest( lbits ); - } - - /* - * Compute a number that is the ULP of the given value, - * for purposes of addition/subtraction. Generally easy. - * More difficult if subtracting and the argument - * is a normalized a power of 2, as the ULP changes at these points. - */ - private static double ulp( double dval, boolean subtracting ){ - long lbits = Double.doubleToLongBits( dval ) & ~signMask; - int binexp = (int)(lbits >>> expShift); - double ulpval; - if ( subtracting && ( binexp >= expShift ) && ((lbits&fractMask) == 0L) ){ - // for subtraction from normalized, powers of 2, - // use next-smaller exponent - binexp -= 1; - } - if ( binexp > expShift ){ - ulpval = Double.longBitsToDouble( ((long)(binexp-expShift))<<expShift ); - } else if ( binexp == 0 ){ - ulpval = Double.MIN_VALUE; - } else { - ulpval = Double.longBitsToDouble( 1L<<(binexp-1) ); - } - if ( subtracting ) ulpval = - ulpval; - - return ulpval; - } - - /* - * Round a double to a float. - * In addition to the fraction bits of the double, - * look at the class instance variable roundDir, - * which should help us avoid double-rounding error. - * roundDir was set in hardValueOf if the estimate was - * close enough, but not exact. It tells us which direction - * of rounding is preferred. - */ - float - stickyRound( double dval ){ - long lbits = Double.doubleToLongBits( dval ); - long binexp = lbits & expMask; - if ( binexp == 0L || binexp == expMask ){ - // what we have here is special. - // don't worry, the right thing will happen. - return (float) dval; - } - lbits += (long)roundDir; // hack-o-matic. - return (float)Double.longBitsToDouble( lbits ); - } - - - /* - * This is the easy subcase -- - * all the significant bits, after scaling, are held in lvalue. - * negSign and decExponent tell us what processing and scaling - * has already been done. Exceptional cases have already been - * stripped out. - * In particular: - * lvalue is a finite number (not Inf, nor NaN) - * lvalue > 0L (not zero, nor negative). - * - * The only reason that we develop the digits here, rather than - * calling on Long.toString() is that we can do it a little faster, - * and besides want to treat trailing 0s specially. If Long.toString - * changes, we should re-evaluate this strategy! - */ - private void - developLongDigits( int decExponent, long lvalue, long insignificant ){ - char digits[]; - int ndigits; - int digitno; - int c; - // - // Discard non-significant low-order bits, while rounding, - // up to insignificant value. - int i; - for ( i = 0; insignificant >= 10L; i++ ) - insignificant /= 10L; - if ( i != 0 ){ - long pow10 = long5pow[i] << i; // 10^i == 5^i * 2^i; - long residue = lvalue % pow10; - lvalue /= pow10; - decExponent += i; - if ( residue >= (pow10>>1) ){ - // round up based on the low-order bits we're discarding - lvalue++; - } - } - if ( lvalue <= Integer.MAX_VALUE ){ - assert lvalue > 0L : lvalue; // lvalue <= 0 - // even easier subcase! - // can do int arithmetic rather than long! - int ivalue = (int)lvalue; - ndigits = 10; - digits = perThreadBuffer.get(); - digitno = ndigits-1; - c = ivalue%10; - ivalue /= 10; - while ( c == 0 ){ - decExponent++; - c = ivalue%10; - ivalue /= 10; - } - while ( ivalue != 0){ - digits[digitno--] = (char)(c+'0'); - decExponent++; - c = ivalue%10; - ivalue /= 10; - } - digits[digitno] = (char)(c+'0'); - } else { - // same algorithm as above (same bugs, too ) - // but using long arithmetic. - ndigits = 20; - digits = perThreadBuffer.get(); - digitno = ndigits-1; - c = (int)(lvalue%10L); - lvalue /= 10L; - while ( c == 0 ){ - decExponent++; - c = (int)(lvalue%10L); - lvalue /= 10L; - } - while ( lvalue != 0L ){ - digits[digitno--] = (char)(c+'0'); - decExponent++; - c = (int)(lvalue%10L); - lvalue /= 10; - } - digits[digitno] = (char)(c+'0'); - } - char result []; - ndigits -= digitno; - result = new char[ ndigits ]; - System.arraycopy( digits, digitno, result, 0, ndigits ); - this.digits = result; - this.decExponent = decExponent+1; - this.nDigits = ndigits; - } - - // - // add one to the least significant digit. - // in the unlikely event there is a carry out, - // deal with it. - // assert that this will only happen where there - // is only one digit, e.g. (float)1e-44 seems to do it. - // - private void - roundup(){ - int i; - int q = digits[ i = (nDigits-1)]; - if ( q == '9' ){ - while ( q == '9' && i > 0 ){ - digits[i] = '0'; - q = digits[--i]; - } - if ( q == '9' ){ - // carryout! High-order 1, rest 0s, larger exp. - decExponent += 1; - digits[0] = '1'; - return; - } - // else fall through. - } - digits[i] = (char)(q+1); - decimalDigitsRoundedUp = true; - } - - public boolean digitsRoundedUp() { - return decimalDigitsRoundedUp; - } - - /* - * FIRST IMPORTANT CONSTRUCTOR: DOUBLE - */ - public OldFloatingDecimalForTest( double d ) - { - long dBits = Double.doubleToLongBits( d ); - long fractBits; - int binExp; - int nSignificantBits; - - // discover and delete sign - if ( (dBits&signMask) != 0 ){ - isNegative = true; - dBits ^= signMask; - } else { - isNegative = false; - } - // Begin to unpack - // Discover obvious special cases of NaN and Infinity. - binExp = (int)( (dBits&expMask) >> expShift ); - fractBits = dBits&fractMask; - if ( binExp == (int)(expMask>>expShift) ) { - isExceptional = true; - if ( fractBits == 0L ){ - digits = infinity; - } else { - digits = notANumber; - isNegative = false; // NaN has no sign! - } - nDigits = digits.length; - return; - } - isExceptional = false; - // Finish unpacking - // Normalize denormalized numbers. - // Insert assumed high-order bit for normalized numbers. - // Subtract exponent bias. - if ( binExp == 0 ){ - if ( fractBits == 0L ){ - // not a denorm, just a 0! - decExponent = 0; - digits = zero; - nDigits = 1; - return; - } - while ( (fractBits&fractHOB) == 0L ){ - fractBits <<= 1; - binExp -= 1; - } - nSignificantBits = expShift + binExp +1; // recall binExp is - shift count. - binExp += 1; - } else { - fractBits |= fractHOB; - nSignificantBits = expShift+1; - } - binExp -= expBias; - // call the routine that actually does all the hard work. - dtoa( binExp, fractBits, nSignificantBits ); - } - - /* - * SECOND IMPORTANT CONSTRUCTOR: SINGLE - */ - public OldFloatingDecimalForTest( float f ) - { - int fBits = Float.floatToIntBits( f ); - int fractBits; - int binExp; - int nSignificantBits; - - // discover and delete sign - if ( (fBits&singleSignMask) != 0 ){ - isNegative = true; - fBits ^= singleSignMask; - } else { - isNegative = false; - } - // Begin to unpack - // Discover obvious special cases of NaN and Infinity. - binExp = (fBits&singleExpMask) >> singleExpShift; - fractBits = fBits&singleFractMask; - if ( binExp == (singleExpMask>>singleExpShift) ) { - isExceptional = true; - if ( fractBits == 0L ){ - digits = infinity; - } else { - digits = notANumber; - isNegative = false; // NaN has no sign! - } - nDigits = digits.length; - return; - } - isExceptional = false; - // Finish unpacking - // Normalize denormalized numbers. - // Insert assumed high-order bit for normalized numbers. - // Subtract exponent bias. - if ( binExp == 0 ){ - if ( fractBits == 0 ){ - // not a denorm, just a 0! - decExponent = 0; - digits = zero; - nDigits = 1; - return; - } - while ( (fractBits&singleFractHOB) == 0 ){ - fractBits <<= 1; - binExp -= 1; - } - nSignificantBits = singleExpShift + binExp +1; // recall binExp is - shift count. - binExp += 1; - } else { - fractBits |= singleFractHOB; - nSignificantBits = singleExpShift+1; - } - binExp -= singleExpBias; - // call the routine that actually does all the hard work. - dtoa( binExp, ((long)fractBits)<<(expShift-singleExpShift), nSignificantBits ); - } - - private void - dtoa( int binExp, long fractBits, int nSignificantBits ) - { - int nFractBits; // number of significant bits of fractBits; - int nTinyBits; // number of these to the right of the point. - int decExp; - - // Examine number. Determine if it is an easy case, - // which we can do pretty trivially using float/long conversion, - // or whether we must do real work. - nFractBits = countBits( fractBits ); - nTinyBits = Math.max( 0, nFractBits - binExp - 1 ); - if ( binExp <= maxSmallBinExp && binExp >= minSmallBinExp ){ - // Look more closely at the number to decide if, - // with scaling by 10^nTinyBits, the result will fit in - // a long. - if ( (nTinyBits < long5pow.length) && ((nFractBits + n5bits[nTinyBits]) < 64 ) ){ - /* - * We can do this: - * take the fraction bits, which are normalized. - * (a) nTinyBits == 0: Shift left or right appropriately - * to align the binary point at the extreme right, i.e. - * where a long int point is expected to be. The integer - * result is easily converted to a string. - * (b) nTinyBits > 0: Shift right by expShift-nFractBits, - * which effectively converts to long and scales by - * 2^nTinyBits. Then multiply by 5^nTinyBits to - * complete the scaling. We know this won't overflow - * because we just counted the number of bits necessary - * in the result. The integer you get from this can - * then be converted to a string pretty easily. - */ - long halfULP; - if ( nTinyBits == 0 ) { - if ( binExp > nSignificantBits ){ - halfULP = 1L << ( binExp-nSignificantBits-1); - } else { - halfULP = 0L; - } - if ( binExp >= expShift ){ - fractBits <<= (binExp-expShift); - } else { - fractBits >>>= (expShift-binExp) ; - } - developLongDigits( 0, fractBits, halfULP ); - return; - } - /* - * The following causes excess digits to be printed - * out in the single-float case. Our manipulation of - * halfULP here is apparently not correct. If we - * better understand how this works, perhaps we can - * use this special case again. But for the time being, - * we do not. - * else { - * fractBits >>>= expShift+1-nFractBits; - * fractBits *= long5pow[ nTinyBits ]; - * halfULP = long5pow[ nTinyBits ] >> (1+nSignificantBits-nFractBits); - * developLongDigits( -nTinyBits, fractBits, halfULP ); - * return; - * } - */ - } - } - /* - * This is the hard case. We are going to compute large positive - * integers B and S and integer decExp, s.t. - * d = ( B / S ) * 10^decExp - * 1 <= B / S < 10 - * Obvious choices are: - * decExp = floor( log10(d) ) - * B = d * 2^nTinyBits * 10^max( 0, -decExp ) - * S = 10^max( 0, decExp) * 2^nTinyBits - * (noting that nTinyBits has already been forced to non-negative) - * I am also going to compute a large positive integer - * M = (1/2^nSignificantBits) * 2^nTinyBits * 10^max( 0, -decExp ) - * i.e. M is (1/2) of the ULP of d, scaled like B. - * When we iterate through dividing B/S and picking off the - * quotient bits, we will know when to stop when the remainder - * is <= M. - * - * We keep track of powers of 2 and powers of 5. - */ - - /* - * Estimate decimal exponent. (If it is small-ish, - * we could double-check.) - * - * First, scale the mantissa bits such that 1 <= d2 < 2. - * We are then going to estimate - * log10(d2) ~=~ (d2-1.5)/1.5 + log(1.5) - * and so we can estimate - * log10(d) ~=~ log10(d2) + binExp * log10(2) - * take the floor and call it decExp. - * FIXME -- use more precise constants here. It costs no more. - */ - double d2 = Double.longBitsToDouble( - expOne | ( fractBits &~ fractHOB ) ); - decExp = (int)Math.floor( - (d2-1.5D)*0.289529654D + 0.176091259 + (double)binExp * 0.301029995663981 ); - int B2, B5; // powers of 2 and powers of 5, respectively, in B - int S2, S5; // powers of 2 and powers of 5, respectively, in S - int M2, M5; // powers of 2 and powers of 5, respectively, in M - int Bbits; // binary digits needed to represent B, approx. - int tenSbits; // binary digits needed to represent 10*S, approx. - OldFDBigIntForTest Sval, Bval, Mval; - - B5 = Math.max( 0, -decExp ); - B2 = B5 + nTinyBits + binExp; - - S5 = Math.max( 0, decExp ); - S2 = S5 + nTinyBits; - - M5 = B5; - M2 = B2 - nSignificantBits; - - /* - * the long integer fractBits contains the (nFractBits) interesting - * bits from the mantissa of d ( hidden 1 added if necessary) followed - * by (expShift+1-nFractBits) zeros. In the interest of compactness, - * I will shift out those zeros before turning fractBits into a - * OldFDBigIntForTest. The resulting whole number will be - * d * 2^(nFractBits-1-binExp). - */ - fractBits >>>= (expShift+1-nFractBits); - B2 -= nFractBits-1; - int common2factor = Math.min( B2, S2 ); - B2 -= common2factor; - S2 -= common2factor; - M2 -= common2factor; - - /* - * HACK!! For exact powers of two, the next smallest number - * is only half as far away as we think (because the meaning of - * ULP changes at power-of-two bounds) for this reason, we - * hack M2. Hope this works. - */ - if ( nFractBits == 1 ) - M2 -= 1; - - if ( M2 < 0 ){ - // oops. - // since we cannot scale M down far enough, - // we must scale the other values up. - B2 -= M2; - S2 -= M2; - M2 = 0; - } - /* - * Construct, Scale, iterate. - * Some day, we'll write a stopping test that takes - * account of the asymmetry of the spacing of floating-point - * numbers below perfect powers of 2 - * 26 Sept 96 is not that day. - * So we use a symmetric test. - */ - char digits[] = this.digits = new char[18]; - int ndigit = 0; - boolean low, high; - long lowDigitDifference; - int q; - - /* - * Detect the special cases where all the numbers we are about - * to compute will fit in int or long integers. - * In these cases, we will avoid doing OldFDBigIntForTest arithmetic. - * We use the same algorithms, except that we "normalize" - * our OldFDBigIntForTests before iterating. This is to make division easier, - * as it makes our fist guess (quotient of high-order words) - * more accurate! - * - * Some day, we'll write a stopping test that takes - * account of the asymmetry of the spacing of floating-point - * numbers below perfect powers of 2 - * 26 Sept 96 is not that day. - * So we use a symmetric test. - */ - Bbits = nFractBits + B2 + (( B5 < n5bits.length )? n5bits[B5] : ( B5*3 )); - tenSbits = S2+1 + (( (S5+1) < n5bits.length )? n5bits[(S5+1)] : ( (S5+1)*3 )); - if ( Bbits < 64 && tenSbits < 64){ - if ( Bbits < 32 && tenSbits < 32){ - // wa-hoo! They're all ints! - int b = ((int)fractBits * small5pow[B5] ) << B2; - int s = small5pow[S5] << S2; - int m = small5pow[M5] << M2; - int tens = s * 10; - /* - * Unroll the first iteration. If our decExp estimate - * was too high, our first quotient will be zero. In this - * case, we discard it and decrement decExp. - */ - ndigit = 0; - q = b / s; - b = 10 * ( b % s ); - m *= 10; - low = (b < m ); - high = (b+m > tens ); - assert q < 10 : q; // excessively large digit - if ( (q == 0) && ! high ){ - // oops. Usually ignore leading zero. - decExp--; - } else { - digits[ndigit++] = (char)('0' + q); - } - /* - * HACK! Java spec sez that we always have at least - * one digit after the . in either F- or E-form output. - * Thus we will need more than one digit if we're using - * E-form - */ - if ( decExp < -3 || decExp >= 8 ){ - high = low = false; - } - while( ! low && ! high ){ - q = b / s; - b = 10 * ( b % s ); - m *= 10; - assert q < 10 : q; // excessively large digit - if ( m > 0L ){ - low = (b < m ); - high = (b+m > tens ); - } else { - // hack -- m might overflow! - // in this case, it is certainly > b, - // which won't - // and b+m > tens, too, since that has overflowed - // either! - low = true; - high = true; - } - digits[ndigit++] = (char)('0' + q); - } - lowDigitDifference = (b<<1) - tens; - exactDecimalConversion = (b == 0); - } else { - // still good! they're all longs! - long b = (fractBits * long5pow[B5] ) << B2; - long s = long5pow[S5] << S2; - long m = long5pow[M5] << M2; - long tens = s * 10L; - /* - * Unroll the first iteration. If our decExp estimate - * was too high, our first quotient will be zero. In this - * case, we discard it and decrement decExp. - */ - ndigit = 0; - q = (int) ( b / s ); - b = 10L * ( b % s ); - m *= 10L; - low = (b < m ); - high = (b+m > tens ); - assert q < 10 : q; // excessively large digit - if ( (q == 0) && ! high ){ - // oops. Usually ignore leading zero. - decExp--; - } else { - digits[ndigit++] = (char)('0' + q); - } - /* - * HACK! Java spec sez that we always have at least - * one digit after the . in either F- or E-form output. - * Thus we will need more than one digit if we're using - * E-form - */ - if ( decExp < -3 || decExp >= 8 ){ - high = low = false; - } - while( ! low && ! high ){ - q = (int) ( b / s ); - b = 10 * ( b % s ); - m *= 10; - assert q < 10 : q; // excessively large digit - if ( m > 0L ){ - low = (b < m ); - high = (b+m > tens ); - } else { - // hack -- m might overflow! - // in this case, it is certainly > b, - // which won't - // and b+m > tens, too, since that has overflowed - // either! - low = true; - high = true; - } - digits[ndigit++] = (char)('0' + q); - } - lowDigitDifference = (b<<1) - tens; - exactDecimalConversion = (b == 0); - } - } else { - OldFDBigIntForTest ZeroVal = new OldFDBigIntForTest(0); - OldFDBigIntForTest tenSval; - int shiftBias; - - /* - * We really must do OldFDBigIntForTest arithmetic. - * Fist, construct our OldFDBigIntForTest initial values. - */ - Bval = multPow52( new OldFDBigIntForTest( fractBits ), B5, B2 ); - Sval = constructPow52( S5, S2 ); - Mval = constructPow52( M5, M2 ); - - - // normalize so that division works better - Bval.lshiftMe( shiftBias = Sval.normalizeMe() ); - Mval.lshiftMe( shiftBias ); - tenSval = Sval.mult( 10 ); - /* - * Unroll the first iteration. If our decExp estimate - * was too high, our first quotient will be zero. In this - * case, we discard it and decrement decExp. - */ - ndigit = 0; - q = Bval.quoRemIteration( Sval ); - Mval = Mval.mult( 10 ); - low = (Bval.cmp( Mval ) < 0); - high = (Bval.add( Mval ).cmp( tenSval ) > 0 ); - assert q < 10 : q; // excessively large digit - if ( (q == 0) && ! high ){ - // oops. Usually ignore leading zero. - decExp--; - } else { - digits[ndigit++] = (char)('0' + q); - } - /* - * HACK! Java spec sez that we always have at least - * one digit after the . in either F- or E-form output. - * Thus we will need more than one digit if we're using - * E-form - */ - if ( decExp < -3 || decExp >= 8 ){ - high = low = false; - } - while( ! low && ! high ){ - q = Bval.quoRemIteration( Sval ); - Mval = Mval.mult( 10 ); - assert q < 10 : q; // excessively large digit - low = (Bval.cmp( Mval ) < 0); - high = (Bval.add( Mval ).cmp( tenSval ) > 0 ); - digits[ndigit++] = (char)('0' + q); - } - if ( high && low ){ - Bval.lshiftMe(1); - lowDigitDifference = Bval.cmp(tenSval); - } else { - lowDigitDifference = 0L; // this here only for flow analysis! - } - exactDecimalConversion = (Bval.cmp( ZeroVal ) == 0); - } - this.decExponent = decExp+1; - this.digits = digits; - this.nDigits = ndigit; - /* - * Last digit gets rounded based on stopping condition. - */ - if ( high ){ - if ( low ){ - if ( lowDigitDifference == 0L ){ - // it's a tie! - // choose based on which digits we like. - if ( (digits[nDigits-1]&1) != 0 ) roundup(); - } else if ( lowDigitDifference > 0 ){ - roundup(); - } - } else { - roundup(); - } - } - } - - public boolean decimalDigitsExact() { - return exactDecimalConversion; - } - - public String - toString(){ - // most brain-dead version - StringBuffer result = new StringBuffer( nDigits+8 ); - if ( isNegative ){ result.append( '-' ); } - if ( isExceptional ){ - result.append( digits, 0, nDigits ); - } else { - result.append( "0."); - result.append( digits, 0, nDigits ); - result.append('e'); - result.append( decExponent ); - } - return new String(result); - } - - public String toJavaFormatString() { - char result[] = perThreadBuffer.get(); - int i = getChars(result); - return new String(result, 0, i); - } - - private int getChars(char[] result) { - assert nDigits <= 19 : nDigits; // generous bound on size of nDigits - int i = 0; - if (isNegative) { result[0] = '-'; i = 1; } - if (isExceptional) { - System.arraycopy(digits, 0, result, i, nDigits); - i += nDigits; - } else { - if (decExponent > 0 && decExponent < 8) { - // print digits.digits. - int charLength = Math.min(nDigits, decExponent); - System.arraycopy(digits, 0, result, i, charLength); - i += charLength; - if (charLength < decExponent) { - charLength = decExponent-charLength; - System.arraycopy(zero, 0, result, i, charLength); - i += charLength; - result[i++] = '.'; - result[i++] = '0'; - } else { - result[i++] = '.'; - if (charLength < nDigits) { - int t = nDigits - charLength; - System.arraycopy(digits, charLength, result, i, t); - i += t; - } else { - result[i++] = '0'; - } - } - } else if (decExponent <=0 && decExponent > -3) { - result[i++] = '0'; - result[i++] = '.'; - if (decExponent != 0) { - System.arraycopy(zero, 0, result, i, -decExponent); - i -= decExponent; - } - System.arraycopy(digits, 0, result, i, nDigits); - i += nDigits; - } else { - result[i++] = digits[0]; - result[i++] = '.'; - if (nDigits > 1) { - System.arraycopy(digits, 1, result, i, nDigits-1); - i += nDigits-1; - } else { - result[i++] = '0'; - } - result[i++] = 'E'; - int e; - if (decExponent <= 0) { - result[i++] = '-'; - e = -decExponent+1; - } else { - e = decExponent-1; - } - // decExponent has 1, 2, or 3, digits - if (e <= 9) { - result[i++] = (char)(e+'0'); - } else if (e <= 99) { - result[i++] = (char)(e/10 +'0'); - result[i++] = (char)(e%10 + '0'); - } else { - result[i++] = (char)(e/100+'0'); - e %= 100; - result[i++] = (char)(e/10+'0'); - result[i++] = (char)(e%10 + '0'); - } - } - } - return i; - } - - // Per-thread buffer for string/stringbuffer conversion - private static ThreadLocal<char[]> perThreadBuffer = new ThreadLocal<char[]>() { - protected synchronized char[] initialValue() { - return new char[26]; - } - }; - - public void appendTo(Appendable buf) { - char result[] = perThreadBuffer.get(); - int i = getChars(result); - if (buf instanceof StringBuilder) - ((StringBuilder) buf).append(result, 0, i); - else if (buf instanceof StringBuffer) - ((StringBuffer) buf).append(result, 0, i); - else - assert false; - } - - @SuppressWarnings("fallthrough") - public static OldFloatingDecimalForTest - readJavaFormatString( String in ) throws NumberFormatException { - boolean isNegative = false; - boolean signSeen = false; - int decExp; - char c; - - parseNumber: - try{ - in = in.trim(); // don't fool around with white space. - // throws NullPointerException if null - int l = in.length(); - if ( l == 0 ) throw new NumberFormatException("empty String"); - int i = 0; - switch ( c = in.charAt( i ) ){ - case '-': - isNegative = true; - //FALLTHROUGH - case '+': - i++; - signSeen = true; - } - - // Check for NaN and Infinity strings - c = in.charAt(i); - if(c == 'N' || c == 'I') { // possible NaN or infinity - boolean potentialNaN = false; - char targetChars[] = null; // char array of "NaN" or "Infinity" - - if(c == 'N') { - targetChars = notANumber; - potentialNaN = true; - } else { - targetChars = infinity; - } - - // compare Input string to "NaN" or "Infinity" - int j = 0; - while(i < l && j < targetChars.length) { - if(in.charAt(i) == targetChars[j]) { - i++; j++; - } - else // something is amiss, throw exception - break parseNumber; - } - - // For the candidate string to be a NaN or infinity, - // all characters in input string and target char[] - // must be matched ==> j must equal targetChars.length - // and i must equal l - if( (j == targetChars.length) && (i == l) ) { // return NaN or infinity - return (potentialNaN ? new OldFloatingDecimalForTest(Double.NaN) // NaN has no sign - : new OldFloatingDecimalForTest(isNegative? - Double.NEGATIVE_INFINITY: - Double.POSITIVE_INFINITY)) ; - } - else { // something went wrong, throw exception - break parseNumber; - } - - } else if (c == '0') { // check for hexadecimal floating-point number - if (l > i+1 ) { - char ch = in.charAt(i+1); - if (ch == 'x' || ch == 'X' ) // possible hex string - return parseHexString(in); - } - } // look for and process decimal floating-point string - - char[] digits = new char[ l ]; - int nDigits= 0; - boolean decSeen = false; - int decPt = 0; - int nLeadZero = 0; - int nTrailZero= 0; - digitLoop: - while ( i < l ){ - switch ( c = in.charAt( i ) ){ - case '0': - if ( nDigits > 0 ){ - nTrailZero += 1; - } else { - nLeadZero += 1; - } - break; // out of switch. - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - while ( nTrailZero > 0 ){ - digits[nDigits++] = '0'; - nTrailZero -= 1; - } - digits[nDigits++] = c; - break; // out of switch. - case '.': - if ( decSeen ){ - // already saw one ., this is the 2nd. - throw new NumberFormatException("multiple points"); - } - decPt = i; - if ( signSeen ){ - decPt -= 1; - } - decSeen = true; - break; // out of switch. - default: - break digitLoop; - } - i++; - } - /* - * At this point, we've scanned all the digits and decimal - * point we're going to see. Trim off leading and trailing - * zeros, which will just confuse us later, and adjust - * our initial decimal exponent accordingly. - * To review: - * we have seen i total characters. - * nLeadZero of them were zeros before any other digits. - * nTrailZero of them were zeros after any other digits. - * if ( decSeen ), then a . was seen after decPt characters - * ( including leading zeros which have been discarded ) - * nDigits characters were neither lead nor trailing - * zeros, nor point - */ - /* - * special hack: if we saw no non-zero digits, then the - * answer is zero! - * Unfortunately, we feel honor-bound to keep parsing! - */ - if ( nDigits == 0 ){ - digits = zero; - nDigits = 1; - if ( nLeadZero == 0 ){ - // we saw NO DIGITS AT ALL, - // not even a crummy 0! - // this is not allowed. - break parseNumber; // go throw exception - } - - } - - /* Our initial exponent is decPt, adjusted by the number of - * discarded zeros. Or, if there was no decPt, - * then its just nDigits adjusted by discarded trailing zeros. - */ - if ( decSeen ){ - decExp = decPt - nLeadZero; - } else { - decExp = nDigits+nTrailZero; - } - - /* - * Look for 'e' or 'E' and an optionally signed integer. - */ - if ( (i < l) && (((c = in.charAt(i) )=='e') || (c == 'E') ) ){ - int expSign = 1; - int expVal = 0; - int reallyBig = Integer.MAX_VALUE / 10; - boolean expOverflow = false; - switch( in.charAt(++i) ){ - case '-': - expSign = -1; - //FALLTHROUGH - case '+': - i++; - } - int expAt = i; - expLoop: - while ( i < l ){ - if ( expVal >= reallyBig ){ - // the next character will cause integer - // overflow. - expOverflow = true; - } - switch ( c = in.charAt(i++) ){ - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - expVal = expVal*10 + ( (int)c - (int)'0' ); - continue; - default: - i--; // back up. - break expLoop; // stop parsing exponent. - } - } - int expLimit = bigDecimalExponent+nDigits+nTrailZero; - if ( expOverflow || ( expVal > expLimit ) ){ - // - // The intent here is to end up with - // infinity or zero, as appropriate. - // The reason for yielding such a small decExponent, - // rather than something intuitive such as - // expSign*Integer.MAX_VALUE, is that this value - // is subject to further manipulation in - // doubleValue() and floatValue(), and I don't want - // it to be able to cause overflow there! - // (The only way we can get into trouble here is for - // really outrageous nDigits+nTrailZero, such as 2 billion. ) - // - decExp = expSign*expLimit; - } else { - // this should not overflow, since we tested - // for expVal > (MAX+N), where N >= abs(decExp) - decExp = decExp + expSign*expVal; - } - - // if we saw something not a digit ( or end of string ) - // after the [Ee][+-], without seeing any digits at all - // this is certainly an error. If we saw some digits, - // but then some trailing garbage, that might be ok. - // so we just fall through in that case. - // HUMBUG - if ( i == expAt ) - break parseNumber; // certainly bad - } - /* - * We parsed everything we could. - * If there are leftovers, then this is not good input! - */ - if ( i < l && - ((i != l - 1) || - (in.charAt(i) != 'f' && - in.charAt(i) != 'F' && - in.charAt(i) != 'd' && - in.charAt(i) != 'D'))) { - break parseNumber; // go throw exception - } - - return new OldFloatingDecimalForTest( isNegative, decExp, digits, nDigits, false ); - } catch ( StringIndexOutOfBoundsException e ){ } - throw new NumberFormatException("For input string: \"" + in + "\""); - } - - /* - * Take a FloatingDecimal, which we presumably just scanned in, - * and find out what its value is, as a double. - * - * AS A SIDE EFFECT, SET roundDir TO INDICATE PREFERRED - * ROUNDING DIRECTION in case the result is really destined - * for a single-precision float. - */ - - public strictfp double doubleValue(){ - int kDigits = Math.min( nDigits, maxDecimalDigits+1 ); - long lValue; - double dValue; - double rValue, tValue; - - // First, check for NaN and Infinity values - if(digits == infinity || digits == notANumber) { - if(digits == notANumber) - return Double.NaN; - else - return (isNegative?Double.NEGATIVE_INFINITY:Double.POSITIVE_INFINITY); - } - else { - if (mustSetRoundDir) { - roundDir = 0; - } - /* - * convert the lead kDigits to a long integer. - */ - // (special performance hack: start to do it using int) - int iValue = (int)digits[0]-(int)'0'; - int iDigits = Math.min( kDigits, intDecimalDigits ); - for ( int i=1; i < iDigits; i++ ){ - iValue = iValue*10 + (int)digits[i]-(int)'0'; - } - lValue = (long)iValue; - for ( int i=iDigits; i < kDigits; i++ ){ - lValue = lValue*10L + (long)((int)digits[i]-(int)'0'); - } - dValue = (double)lValue; - int exp = decExponent-kDigits; - /* - * lValue now contains a long integer with the value of - * the first kDigits digits of the number. - * dValue contains the (double) of the same. - */ - - if ( nDigits <= maxDecimalDigits ){ - /* - * possibly an easy case. - * We know that the digits can be represented - * exactly. And if the exponent isn't too outrageous, - * the whole thing can be done with one operation, - * thus one rounding error. - * Note that all our constructors trim all leading and - * trailing zeros, so simple values (including zero) - * will always end up here - */ - if (exp == 0 || dValue == 0.0) - return (isNegative)? -dValue : dValue; // small floating integer - else if ( exp >= 0 ){ - if ( exp <= maxSmallTen ){ - /* - * Can get the answer with one operation, - * thus one roundoff. - */ - rValue = dValue * small10pow[exp]; - if ( mustSetRoundDir ){ - tValue = rValue / small10pow[exp]; - roundDir = ( tValue == dValue ) ? 0 - :( tValue < dValue ) ? 1 - : -1; - } - return (isNegative)? -rValue : rValue; - } - int slop = maxDecimalDigits - kDigits; - if ( exp <= maxSmallTen+slop ){ - /* - * We can multiply dValue by 10^(slop) - * and it is still "small" and exact. - * Then we can multiply by 10^(exp-slop) - * with one rounding. - */ - dValue *= small10pow[slop]; - rValue = dValue * small10pow[exp-slop]; - - if ( mustSetRoundDir ){ - tValue = rValue / small10pow[exp-slop]; - roundDir = ( tValue == dValue ) ? 0 - :( tValue < dValue ) ? 1 - : -1; - } - return (isNegative)? -rValue : rValue; - } - /* - * Else we have a hard case with a positive exp. - */ - } else { - if ( exp >= -maxSmallTen ){ - /* - * Can get the answer in one division. - */ - rValue = dValue / small10pow[-exp]; - tValue = rValue * small10pow[-exp]; - if ( mustSetRoundDir ){ - roundDir = ( tValue == dValue ) ? 0 - :( tValue < dValue ) ? 1 - : -1; - } - return (isNegative)? -rValue : rValue; - } - /* - * Else we have a hard case with a negative exp. - */ - } - } - - /* - * Harder cases: - * The sum of digits plus exponent is greater than - * what we think we can do with one error. - * - * Start by approximating the right answer by, - * naively, scaling by powers of 10. - */ - if ( exp > 0 ){ - if ( decExponent > maxDecimalExponent+1 ){ - /* - * Lets face it. This is going to be - * Infinity. Cut to the chase. - */ - return (isNegative)? Double.NEGATIVE_INFINITY : Double.POSITIVE_INFINITY; - } - if ( (exp&15) != 0 ){ - dValue *= small10pow[exp&15]; - } - if ( (exp>>=4) != 0 ){ - int j; - for( j = 0; exp > 1; j++, exp>>=1 ){ - if ( (exp&1)!=0) - dValue *= big10pow[j]; - } - /* - * The reason for the weird exp > 1 condition - * in the above loop was so that the last multiply - * would get unrolled. We handle it here. - * It could overflow. - */ - double t = dValue * big10pow[j]; - if ( Double.isInfinite( t ) ){ - /* - * It did overflow. - * Look more closely at the result. - * If the exponent is just one too large, - * then use the maximum finite as our estimate - * value. Else call the result infinity - * and punt it. - * ( I presume this could happen because - * rounding forces the result here to be - * an ULP or two larger than - * Double.MAX_VALUE ). - */ - t = dValue / 2.0; - t *= big10pow[j]; - if ( Double.isInfinite( t ) ){ - return (isNegative)? Double.NEGATIVE_INFINITY : Double.POSITIVE_INFINITY; - } - t = Double.MAX_VALUE; - } - dValue = t; - } - } else if ( exp < 0 ){ - exp = -exp; - if ( decExponent < minDecimalExponent-1 ){ - /* - * Lets face it. This is going to be - * zero. Cut to the chase. - */ - return (isNegative)? -0.0 : 0.0; - } - if ( (exp&15) != 0 ){ - dValue /= small10pow[exp&15]; - } - if ( (exp>>=4) != 0 ){ - int j; - for( j = 0; exp > 1; j++, exp>>=1 ){ - if ( (exp&1)!=0) - dValue *= tiny10pow[j]; - } - /* - * The reason for the weird exp > 1 condition - * in the above loop was so that the last multiply - * would get unrolled. We handle it here. - * It could underflow. - */ - double t = dValue * tiny10pow[j]; - if ( t == 0.0 ){ - /* - * It did underflow. - * Look more closely at the result. - * If the exponent is just one too small, - * then use the minimum finite as our estimate - * value. Else call the result 0.0 - * and punt it. - * ( I presume this could happen because - * rounding forces the result here to be - * an ULP or two less than - * Double.MIN_VALUE ). - */ - t = dValue * 2.0; - t *= tiny10pow[j]; - if ( t == 0.0 ){ - return (isNegative)? -0.0 : 0.0; - } - t = Double.MIN_VALUE; - } - dValue = t; - } - } - - /* - * dValue is now approximately the result. - * The hard part is adjusting it, by comparison - * with OldFDBigIntForTest arithmetic. - * Formulate the EXACT big-number result as - * bigD0 * 10^exp - */ - OldFDBigIntForTest bigD0 = new OldFDBigIntForTest( lValue, digits, kDigits, nDigits ); - exp = decExponent - nDigits; - - correctionLoop: - while(true){ - /* AS A SIDE EFFECT, THIS METHOD WILL SET THE INSTANCE VARIABLES - * bigIntExp and bigIntNBits - */ - OldFDBigIntForTest bigB = doubleToBigInt( dValue ); - - /* - * Scale bigD, bigB appropriately for - * big-integer operations. - * Naively, we multiply by powers of ten - * and powers of two. What we actually do - * is keep track of the powers of 5 and - * powers of 2 we would use, then factor out - * common divisors before doing the work. - */ - int B2, B5; // powers of 2, 5 in bigB - int D2, D5; // powers of 2, 5 in bigD - int Ulp2; // powers of 2 in halfUlp. - if ( exp >= 0 ){ - B2 = B5 = 0; - D2 = D5 = exp; - } else { - B2 = B5 = -exp; - D2 = D5 = 0; - } - if ( bigIntExp >= 0 ){ - B2 += bigIntExp; - } else { - D2 -= bigIntExp; - } - Ulp2 = B2; - // shift bigB and bigD left by a number s. t. - // halfUlp is still an integer. - int hulpbias; - if ( bigIntExp+bigIntNBits <= -expBias+1 ){ - // This is going to be a denormalized number - // (if not actually zero). - // half an ULP is at 2^-(expBias+expShift+1) - hulpbias = bigIntExp+ expBias + expShift; - } else { - hulpbias = expShift + 2 - bigIntNBits; - } - B2 += hulpbias; - D2 += hulpbias; - // if there are common factors of 2, we might just as well - // factor them out, as they add nothing useful. - int common2 = Math.min( B2, Math.min( D2, Ulp2 ) ); - B2 -= common2; - D2 -= common2; - Ulp2 -= common2; - // do multiplications by powers of 5 and 2 - bigB = multPow52( bigB, B5, B2 ); - OldFDBigIntForTest bigD = multPow52( new OldFDBigIntForTest( bigD0 ), D5, D2 ); - // - // to recap: - // bigB is the scaled-big-int version of our floating-point - // candidate. - // bigD is the scaled-big-int version of the exact value - // as we understand it. - // halfUlp is 1/2 an ulp of bigB, except for special cases - // of exact powers of 2 - // - // the plan is to compare bigB with bigD, and if the difference - // is less than halfUlp, then we're satisfied. Otherwise, - // use the ratio of difference to halfUlp to calculate a fudge - // factor to add to the floating value, then go 'round again. - // - OldFDBigIntForTest diff; - int cmpResult; - boolean overvalue; - if ( (cmpResult = bigB.cmp( bigD ) ) > 0 ){ - overvalue = true; // our candidate is too big. - diff = bigB.sub( bigD ); - if ( (bigIntNBits == 1) && (bigIntExp > -expBias+1) ){ - // candidate is a normalized exact power of 2 and - // is too big. We will be subtracting. - // For our purposes, ulp is the ulp of the - // next smaller range. - Ulp2 -= 1; - if ( Ulp2 < 0 ){ - // rats. Cannot de-scale ulp this far. - // must scale diff in other direction. - Ulp2 = 0; - diff.lshiftMe( 1 ); - } - } - } else if ( cmpResult < 0 ){ - overvalue = false; // our candidate is too small. - diff = bigD.sub( bigB ); - } else { - // the candidate is exactly right! - // this happens with surprising frequency - break correctionLoop; - } - OldFDBigIntForTest halfUlp = constructPow52( B5, Ulp2 ); - if ( (cmpResult = diff.cmp( halfUlp ) ) < 0 ){ - // difference is small. - // this is close enough - if (mustSetRoundDir) { - roundDir = overvalue ? -1 : 1; - } - break correctionLoop; - } else if ( cmpResult == 0 ){ - // difference is exactly half an ULP - // round to some other value maybe, then finish - dValue += 0.5*ulp( dValue, overvalue ); - // should check for bigIntNBits == 1 here?? - if (mustSetRoundDir) { - roundDir = overvalue ? -1 : 1; - } - break correctionLoop; - } else { - // difference is non-trivial. - // could scale addend by ratio of difference to - // halfUlp here, if we bothered to compute that difference. - // Most of the time ( I hope ) it is about 1 anyway. - dValue += ulp( dValue, overvalue ); - if ( dValue == 0.0 || dValue == Double.POSITIVE_INFINITY ) - break correctionLoop; // oops. Fell off end of range. - continue; // try again. - } - - } - return (isNegative)? -dValue : dValue; - } - } - - /* - * Take a FloatingDecimal, which we presumably just scanned in, - * and find out what its value is, as a float. - * This is distinct from doubleValue() to avoid the extremely - * unlikely case of a double rounding error, wherein the conversion - * to double has one rounding error, and the conversion of that double - * to a float has another rounding error, IN THE WRONG DIRECTION, - * ( because of the preference to a zero low-order bit ). - */ - - public strictfp float floatValue(){ - int kDigits = Math.min( nDigits, singleMaxDecimalDigits+1 ); - int iValue; - float fValue; - - // First, check for NaN and Infinity values - if(digits == infinity || digits == notANumber) { - if(digits == notANumber) - return Float.NaN; - else - return (isNegative?Float.NEGATIVE_INFINITY:Float.POSITIVE_INFINITY); - } - else { - /* - * convert the lead kDigits to an integer. - */ - iValue = (int)digits[0]-(int)'0'; - for ( int i=1; i < kDigits; i++ ){ - iValue = iValue*10 + (int)digits[i]-(int)'0'; - } - fValue = (float)iValue; - int exp = decExponent-kDigits; - /* - * iValue now contains an integer with the value of - * the first kDigits digits of the number. - * fValue contains the (float) of the same. - */ - - if ( nDigits <= singleMaxDecimalDigits ){ - /* - * possibly an easy case. - * We know that the digits can be represented - * exactly. And if the exponent isn't too outrageous, - * the whole thing can be done with one operation, - * thus one rounding error. - * Note that all our constructors trim all leading and - * trailing zeros, so simple values (including zero) - * will always end up here. - */ - if (exp == 0 || fValue == 0.0f) - return (isNegative)? -fValue : fValue; // small floating integer - else if ( exp >= 0 ){ - if ( exp <= singleMaxSmallTen ){ - /* - * Can get the answer with one operation, - * thus one roundoff. - */ - fValue *= singleSmall10pow[exp]; - return (isNegative)? -fValue : fValue; - } - int slop = singleMaxDecimalDigits - kDigits; - if ( exp <= singleMaxSmallTen+slop ){ - /* - * We can multiply dValue by 10^(slop) - * and it is still "small" and exact. - * Then we can multiply by 10^(exp-slop) - * with one rounding. - */ - fValue *= singleSmall10pow[slop]; - fValue *= singleSmall10pow[exp-slop]; - return (isNegative)? -fValue : fValue; - } - /* - * Else we have a hard case with a positive exp. - */ - } else { - if ( exp >= -singleMaxSmallTen ){ - /* - * Can get the answer in one division. - */ - fValue /= singleSmall10pow[-exp]; - return (isNegative)? -fValue : fValue; - } - /* - * Else we have a hard case with a negative exp. - */ - } - } else if ( (decExponent >= nDigits) && (nDigits+decExponent <= maxDecimalDigits) ){ - /* - * In double-precision, this is an exact floating integer. - * So we can compute to double, then shorten to float - * with one round, and get the right answer. - * - * First, finish accumulating digits. - * Then convert that integer to a double, multiply - * by the appropriate power of ten, and convert to float. - */ - long lValue = (long)iValue; - for ( int i=kDigits; i < nDigits; i++ ){ - lValue = lValue*10L + (long)((int)digits[i]-(int)'0'); - } - double dValue = (double)lValue; - exp = decExponent-nDigits; - dValue *= small10pow[exp]; - fValue = (float)dValue; - return (isNegative)? -fValue : fValue; - - } - /* - * Harder cases: - * The sum of digits plus exponent is greater than - * what we think we can do with one error. - * - * Start by weeding out obviously out-of-range - * results, then convert to double and go to - * common hard-case code. - */ - if ( decExponent > singleMaxDecimalExponent+1 ){ - /* - * Lets face it. This is going to be - * Infinity. Cut to the chase. - */ - return (isNegative)? Float.NEGATIVE_INFINITY : Float.POSITIVE_INFINITY; - } else if ( decExponent < singleMinDecimalExponent-1 ){ - /* - * Lets face it. This is going to be - * zero. Cut to the chase. - */ - return (isNegative)? -0.0f : 0.0f; - } - - /* - * Here, we do 'way too much work, but throwing away - * our partial results, and going and doing the whole - * thing as double, then throwing away half the bits that computes - * when we convert back to float. - * - * The alternative is to reproduce the whole multiple-precision - * algorithm for float precision, or to try to parameterize it - * for common usage. The former will take about 400 lines of code, - * and the latter I tried without success. Thus the semi-hack - * answer here. - */ - mustSetRoundDir = !fromHex; - double dValue = doubleValue(); - return stickyRound( dValue ); - } - } - - - /* - * All the positive powers of 10 that can be - * represented exactly in double/float. - */ - private static final double small10pow[] = { - 1.0e0, - 1.0e1, 1.0e2, 1.0e3, 1.0e4, 1.0e5, - 1.0e6, 1.0e7, 1.0e8, 1.0e9, 1.0e10, - 1.0e11, 1.0e12, 1.0e13, 1.0e14, 1.0e15, - 1.0e16, 1.0e17, 1.0e18, 1.0e19, 1.0e20, - 1.0e21, 1.0e22 - }; - - private static final float singleSmall10pow[] = { - 1.0e0f, - 1.0e1f, 1.0e2f, 1.0e3f, 1.0e4f, 1.0e5f, - 1.0e6f, 1.0e7f, 1.0e8f, 1.0e9f, 1.0e10f - }; - - private static final double big10pow[] = { - 1e16, 1e32, 1e64, 1e128, 1e256 }; - private static final double tiny10pow[] = { - 1e-16, 1e-32, 1e-64, 1e-128, 1e-256 }; - - private static final int maxSmallTen = small10pow.length-1; - private static final int singleMaxSmallTen = singleSmall10pow.length-1; - - private static final int small5pow[] = { - 1, - 5, - 5*5, - 5*5*5, - 5*5*5*5, - 5*5*5*5*5, - 5*5*5*5*5*5, - 5*5*5*5*5*5*5, - 5*5*5*5*5*5*5*5, - 5*5*5*5*5*5*5*5*5, - 5*5*5*5*5*5*5*5*5*5, - 5*5*5*5*5*5*5*5*5*5*5, - 5*5*5*5*5*5*5*5*5*5*5*5, - 5*5*5*5*5*5*5*5*5*5*5*5*5 - }; - - - private static final long long5pow[] = { - 1L, - 5L, - 5L*5, - 5L*5*5, - 5L*5*5*5, - 5L*5*5*5*5, - 5L*5*5*5*5*5, - 5L*5*5*5*5*5*5, - 5L*5*5*5*5*5*5*5, - 5L*5*5*5*5*5*5*5*5, - 5L*5*5*5*5*5*5*5*5*5, - 5L*5*5*5*5*5*5*5*5*5*5, - 5L*5*5*5*5*5*5*5*5*5*5*5, - 5L*5*5*5*5*5*5*5*5*5*5*5*5, - 5L*5*5*5*5*5*5*5*5*5*5*5*5*5, - 5L*5*5*5*5*5*5*5*5*5*5*5*5*5*5, - 5L*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5, - 5L*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5, - 5L*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5, - 5L*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5, - 5L*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5, - 5L*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5, - 5L*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5, - 5L*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5, - 5L*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5, - 5L*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5, - 5L*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5*5, - }; - - // approximately ceil( log2( long5pow[i] ) ) - private static final int n5bits[] = { - 0, - 3, - 5, - 7, - 10, - 12, - 14, - 17, - 19, - 21, - 24, - 26, - 28, - 31, - 33, - 35, - 38, - 40, - 42, - 45, - 47, - 49, - 52, - 54, - 56, - 59, - 61, - }; - - private static final char infinity[] = { 'I', 'n', 'f', 'i', 'n', 'i', 't', 'y' }; - private static final char notANumber[] = { 'N', 'a', 'N' }; - private static final char zero[] = { '0', '0', '0', '0', '0', '0', '0', '0' }; - - - /* - * Grammar is compatible with hexadecimal floating-point constants - * described in section 6.4.4.2 of the C99 specification. - */ - private static Pattern hexFloatPattern = null; - private static synchronized Pattern getHexFloatPattern() { - if (hexFloatPattern == null) { - hexFloatPattern = Pattern.compile( - //1 234 56 7 8 9 - "([-+])?0[xX](((\\p{XDigit}+)\\.?)|((\\p{XDigit}*)\\.(\\p{XDigit}+)))[pP]([-+])?(\\p{Digit}+)[fFdD]?" - ); - } - return hexFloatPattern; - } - - /* - * Convert string s to a suitable floating decimal; uses the - * double constructor and set the roundDir variable appropriately - * in case the value is later converted to a float. - */ - static OldFloatingDecimalForTest parseHexString(String s) { - // Verify string is a member of the hexadecimal floating-point - // string language. - Matcher m = getHexFloatPattern().matcher(s); - boolean validInput = m.matches(); - - if (!validInput) { - // Input does not match pattern - throw new NumberFormatException("For input string: \"" + s + "\""); - } else { // validInput - /* - * We must isolate the sign, significand, and exponent - * fields. The sign value is straightforward. Since - * floating-point numbers are stored with a normalized - * representation, the significand and exponent are - * interrelated. - * - * After extracting the sign, we normalized the - * significand as a hexadecimal value, calculating an - * exponent adjust for any shifts made during - * normalization. If the significand is zero, the - * exponent doesn't need to be examined since the output - * will be zero. - * - * Next the exponent in the input string is extracted. - * Afterwards, the significand is normalized as a *binary* - * value and the input value's normalized exponent can be - * computed. The significand bits are copied into a - * double significand; if the string has more logical bits - * than can fit in a double, the extra bits affect the - * round and sticky bits which are used to round the final - * value. - */ - - // Extract significand sign - String group1 = m.group(1); - double sign = (( group1 == null ) || group1.equals("+"))? 1.0 : -1.0; - - - // Extract Significand magnitude - /* - * Based on the form of the significand, calculate how the - * binary exponent needs to be adjusted to create a - * normalized *hexadecimal* floating-point number; that - * is, a number where there is one nonzero hex digit to - * the left of the (hexa)decimal point. Since we are - * adjusting a binary, not hexadecimal exponent, the - * exponent is adjusted by a multiple of 4. - * - * There are a number of significand scenarios to consider; - * letters are used in indicate nonzero digits: - * - * 1. 000xxxx => x.xxx normalized - * increase exponent by (number of x's - 1)*4 - * - * 2. 000xxx.yyyy => x.xxyyyy normalized - * increase exponent by (number of x's - 1)*4 - * - * 3. .000yyy => y.yy normalized - * decrease exponent by (number of zeros + 1)*4 - * - * 4. 000.00000yyy => y.yy normalized - * decrease exponent by (number of zeros to right of point + 1)*4 - * - * If the significand is exactly zero, return a properly - * signed zero. - */ - - String significandString =null; - int signifLength = 0; - int exponentAdjust = 0; - { - int leftDigits = 0; // number of meaningful digits to - // left of "decimal" point - // (leading zeros stripped) - int rightDigits = 0; // number of digits to right of - // "decimal" point; leading zeros - // must always be accounted for - /* - * The significand is made up of either - * - * 1. group 4 entirely (integer portion only) - * - * OR - * - * 2. the fractional portion from group 7 plus any - * (optional) integer portions from group 6. - */ - String group4; - if( (group4 = m.group(4)) != null) { // Integer-only significand - // Leading zeros never matter on the integer portion - significandString = stripLeadingZeros(group4); - leftDigits = significandString.length(); - } - else { - // Group 6 is the optional integer; leading zeros - // never matter on the integer portion - String group6 = stripLeadingZeros(m.group(6)); - leftDigits = group6.length(); - - // fraction - String group7 = m.group(7); - rightDigits = group7.length(); - - // Turn "integer.fraction" into "integer"+"fraction" - significandString = - ((group6 == null)?"":group6) + // is the null - // check necessary? - group7; - } - - significandString = stripLeadingZeros(significandString); - signifLength = significandString.length(); - - /* - * Adjust exponent as described above - */ - if (leftDigits >= 1) { // Cases 1 and 2 - exponentAdjust = 4*(leftDigits - 1); - } else { // Cases 3 and 4 - exponentAdjust = -4*( rightDigits - signifLength + 1); - } - - // If the significand is zero, the exponent doesn't - // matter; return a properly signed zero. - - if (signifLength == 0) { // Only zeros in input - return new OldFloatingDecimalForTest(sign * 0.0); - } - } - - // Extract Exponent - /* - * Use an int to read in the exponent value; this should - * provide more than sufficient range for non-contrived - * inputs. If reading the exponent in as an int does - * overflow, examine the sign of the exponent and - * significand to determine what to do. - */ - String group8 = m.group(8); - boolean positiveExponent = ( group8 == null ) || group8.equals("+"); - long unsignedRawExponent; - try { - unsignedRawExponent = Integer.parseInt(m.group(9)); - } - catch (NumberFormatException e) { - // At this point, we know the exponent is - // syntactically well-formed as a sequence of - // digits. Therefore, if an NumberFormatException - // is thrown, it must be due to overflowing int's - // range. Also, at this point, we have already - // checked for a zero significand. Thus the signs - // of the exponent and significand determine the - // final result: - // - // significand - // + - - // exponent + +infinity -infinity - // - +0.0 -0.0 - return new OldFloatingDecimalForTest(sign * (positiveExponent ? - Double.POSITIVE_INFINITY : 0.0)); - } - - long rawExponent = - (positiveExponent ? 1L : -1L) * // exponent sign - unsignedRawExponent; // exponent magnitude - - // Calculate partially adjusted exponent - long exponent = rawExponent + exponentAdjust ; - - // Starting copying non-zero bits into proper position in - // a long; copy explicit bit too; this will be masked - // later for normal values. - - boolean round = false; - boolean sticky = false; - int bitsCopied=0; - int nextShift=0; - long significand=0L; - // First iteration is different, since we only copy - // from the leading significand bit; one more exponent - // adjust will be needed... - - // IMPORTANT: make leadingDigit a long to avoid - // surprising shift semantics! - long leadingDigit = getHexDigit(significandString, 0); - - /* - * Left shift the leading digit (53 - (bit position of - * leading 1 in digit)); this sets the top bit of the - * significand to 1. The nextShift value is adjusted - * to take into account the number of bit positions of - * the leadingDigit actually used. Finally, the - * exponent is adjusted to normalize the significand - * as a binary value, not just a hex value. - */ - if (leadingDigit == 1) { - significand |= leadingDigit << 52; - nextShift = 52 - 4; - /* exponent += 0 */ } - else if (leadingDigit <= 3) { // [2, 3] - significand |= leadingDigit << 51; - nextShift = 52 - 5; - exponent += 1; - } - else if (leadingDigit <= 7) { // [4, 7] - significand |= leadingDigit << 50; - nextShift = 52 - 6; - exponent += 2; - } - else if (leadingDigit <= 15) { // [8, f] - significand |= leadingDigit << 49; - nextShift = 52 - 7; - exponent += 3; - } else { - throw new AssertionError("Result from digit conversion too large!"); - } - // The preceding if-else could be replaced by a single - // code block based on the high-order bit set in - // leadingDigit. Given leadingOnePosition, - - // significand |= leadingDigit << (SIGNIFICAND_WIDTH - leadingOnePosition); - // nextShift = 52 - (3 + leadingOnePosition); - // exponent += (leadingOnePosition-1); - - - /* - * Now the exponent variable is equal to the normalized - * binary exponent. Code below will make representation - * adjustments if the exponent is incremented after - * rounding (includes overflows to infinity) or if the - * result is subnormal. - */ - - // Copy digit into significand until the significand can't - // hold another full hex digit or there are no more input - // hex digits. - int i = 0; - for(i = 1; - i < signifLength && nextShift >= 0; - i++) { - long currentDigit = getHexDigit(significandString, i); - significand |= (currentDigit << nextShift); - nextShift-=4; - } - - // After the above loop, the bulk of the string is copied. - // Now, we must copy any partial hex digits into the - // significand AND compute the round bit and start computing - // sticky bit. - - if ( i < signifLength ) { // at least one hex input digit exists - long currentDigit = getHexDigit(significandString, i); - - // from nextShift, figure out how many bits need - // to be copied, if any - switch(nextShift) { // must be negative - case -1: - // three bits need to be copied in; can - // set round bit - significand |= ((currentDigit & 0xEL) >> 1); - round = (currentDigit & 0x1L) != 0L; - break; - - case -2: - // two bits need to be copied in; can - // set round and start sticky - significand |= ((currentDigit & 0xCL) >> 2); - round = (currentDigit &0x2L) != 0L; - sticky = (currentDigit & 0x1L) != 0; - break; - - case -3: - // one bit needs to be copied in - significand |= ((currentDigit & 0x8L)>>3); - // Now set round and start sticky, if possible - round = (currentDigit &0x4L) != 0L; - sticky = (currentDigit & 0x3L) != 0; - break; - - case -4: - // all bits copied into significand; set - // round and start sticky - round = ((currentDigit & 0x8L) != 0); // is top bit set? - // nonzeros in three low order bits? - sticky = (currentDigit & 0x7L) != 0; - break; - - default: - throw new AssertionError("Unexpected shift distance remainder."); - // break; - } - - // Round is set; sticky might be set. - - // For the sticky bit, it suffices to check the - // current digit and test for any nonzero digits in - // the remaining unprocessed input. - i++; - while(i < signifLength && !sticky) { - currentDigit = getHexDigit(significandString,i); - sticky = sticky || (currentDigit != 0); - i++; - } - - } - // else all of string was seen, round and sticky are - // correct as false. - - - // Check for overflow and update exponent accordingly. - - if (exponent > Double.MAX_EXPONENT) { // Infinite result - // overflow to properly signed infinity - return new OldFloatingDecimalForTest(sign * Double.POSITIVE_INFINITY); - } else { // Finite return value - if (exponent <= Double.MAX_EXPONENT && // (Usually) normal result - exponent >= Double.MIN_EXPONENT) { - - // The result returned in this block cannot be a - // zero or subnormal; however after the - // significand is adjusted from rounding, we could - // still overflow in infinity. - - // AND exponent bits into significand; if the - // significand is incremented and overflows from - // rounding, this combination will update the - // exponent correctly, even in the case of - // Double.MAX_VALUE overflowing to infinity. - - significand = (( (exponent + - (long)DoubleConsts.EXP_BIAS) << - (DoubleConsts.SIGNIFICAND_WIDTH-1)) - & DoubleConsts.EXP_BIT_MASK) | - (DoubleConsts.SIGNIF_BIT_MASK & significand); - - } else { // Subnormal or zero - // (exponent < Double.MIN_EXPONENT) - - if (exponent < (DoubleConsts.MIN_SUB_EXPONENT -1 )) { - // No way to round back to nonzero value - // regardless of significand if the exponent is - // less than -1075. - return new OldFloatingDecimalForTest(sign * 0.0); - } else { // -1075 <= exponent <= MIN_EXPONENT -1 = -1023 - /* - * Find bit position to round to; recompute - * round and sticky bits, and shift - * significand right appropriately. - */ - - sticky = sticky || round; - round = false; - - // Number of bits of significand to preserve is - // exponent - abs_min_exp +1 - // check: - // -1075 +1074 + 1 = 0 - // -1023 +1074 + 1 = 52 - - int bitsDiscarded = 53 - - ((int)exponent - DoubleConsts.MIN_SUB_EXPONENT + 1); - assert bitsDiscarded >= 1 && bitsDiscarded <= 53; - - // What to do here: - // First, isolate the new round bit - round = (significand & (1L << (bitsDiscarded -1))) != 0L; - if (bitsDiscarded > 1) { - // create mask to update sticky bits; low - // order bitsDiscarded bits should be 1 - long mask = ~((~0L) << (bitsDiscarded -1)); - sticky = sticky || ((significand & mask) != 0L ) ; - } - - // Now, discard the bits - significand = significand >> bitsDiscarded; - - significand = (( ((long)(Double.MIN_EXPONENT -1) + // subnorm exp. - (long)DoubleConsts.EXP_BIAS) << - (DoubleConsts.SIGNIFICAND_WIDTH-1)) - & DoubleConsts.EXP_BIT_MASK) | - (DoubleConsts.SIGNIF_BIT_MASK & significand); - } - } - - // The significand variable now contains the currently - // appropriate exponent bits too. - - /* - * Determine if significand should be incremented; - * making this determination depends on the least - * significant bit and the round and sticky bits. - * - * Round to nearest even rounding table, adapted from - * table 4.7 in "Computer Arithmetic" by IsraelKoren. - * The digit to the left of the "decimal" point is the - * least significant bit, the digits to the right of - * the point are the round and sticky bits - * - * Number Round(x) - * x0.00 x0. - * x0.01 x0. - * x0.10 x0. - * x0.11 x1. = x0. +1 - * x1.00 x1. - * x1.01 x1. - * x1.10 x1. + 1 - * x1.11 x1. + 1 - */ - boolean incremented = false; - boolean leastZero = ((significand & 1L) == 0L); - if( ( leastZero && round && sticky ) || - ((!leastZero) && round )) { - incremented = true; - significand++; - } - - OldFloatingDecimalForTest fd = new OldFloatingDecimalForTest(Math.copySign( - Double.longBitsToDouble(significand), - sign)); - - /* - * Set roundingDir variable field of fd properly so - * that the input string can be properly rounded to a - * float value. There are two cases to consider: - * - * 1. rounding to double discards sticky bit - * information that would change the result of a float - * rounding (near halfway case between two floats) - * - * 2. rounding to double rounds up when rounding up - * would not occur when rounding to float. - * - * For former case only needs to be considered when - * the bits rounded away when casting to float are all - * zero; otherwise, float round bit is properly set - * and sticky will already be true. - * - * The lower exponent bound for the code below is the - * minimum (normalized) subnormal exponent - 1 since a - * value with that exponent can round up to the - * minimum subnormal value and the sticky bit - * information must be preserved (i.e. case 1). - */ - if ((exponent >= FloatConsts.MIN_SUB_EXPONENT-1) && - (exponent <= Float.MAX_EXPONENT ) ){ - // Outside above exponent range, the float value - // will be zero or infinity. - - /* - * If the low-order 28 bits of a rounded double - * significand are 0, the double could be a - * half-way case for a rounding to float. If the - * double value is a half-way case, the double - * significand may have to be modified to round - * the right float value (see the stickyRound - * method). If the rounding to double has lost - * what would be float sticky bit information, the - * double significand must be incremented. If the - * double value's significand was itself - * incremented, the float value may end up too - * large so the increment should be undone. - */ - if ((significand & 0xfffffffL) == 0x0L) { - // For negative values, the sign of the - // roundDir is the same as for positive values - // since adding 1 increasing the significand's - // magnitude and subtracting 1 decreases the - // significand's magnitude. If neither round - // nor sticky is true, the double value is - // exact and no adjustment is required for a - // proper float rounding. - if( round || sticky) { - if (leastZero) { // prerounding lsb is 0 - // If round and sticky were both true, - // and the least significant - // significand bit were 0, the rounded - // significand would not have its - // low-order bits be zero. Therefore, - // we only need to adjust the - // significand if round XOR sticky is - // true. - if (round ^ sticky) { - fd.roundDir = 1; - } - } - else { // prerounding lsb is 1 - // If the prerounding lsb is 1 and the - // resulting significand has its - // low-order bits zero, the significand - // was incremented. Here, we undo the - // increment, which will ensure the - // right guard and sticky bits for the - // float rounding. - if (round) - fd.roundDir = -1; - } - } - } - } - - fd.fromHex = true; - return fd; - } - } - } - - /** - * Return <code>s</code> with any leading zeros removed. - */ - static String stripLeadingZeros(String s) { - return s.replaceFirst("^0+", ""); - } - - /** - * Extract a hexadecimal digit from position <code>position</code> - * of string <code>s</code>. - */ - static int getHexDigit(String s, int position) { - int value = Character.digit(s.charAt(position), 16); - if (value <= -1 || value >= 16) { - throw new AssertionError("Unexpected failure of digit conversion of " + - s.charAt(position)); - } - return value; - } - - -} diff --git a/test/jdk/jdk/internal/math/FloatingDecimal/TestFloatingDecimal.java b/test/jdk/jdk/internal/math/FloatingDecimal/TestFloatingDecimal.java index de245ff2f5d..5f5267a1b7c 100644 --- a/test/jdk/jdk/internal/math/FloatingDecimal/TestFloatingDecimal.java +++ b/test/jdk/jdk/internal/math/FloatingDecimal/TestFloatingDecimal.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,6 +21,7 @@ * questions. */ +import java.math.BigDecimal; import java.util.Random; import jdk.internal.math.FloatingDecimal; @@ -30,46 +31,13 @@ import static org.junit.jupiter.api.Assertions.assertEquals; -/* -OldFloatingDecimalForTest - -public class OldFloatingDecimalForTest { - public boolean digitsRoundedUp(); - public OldFloatingDecimalForTest(double); - public OldFloatingDecimalForTest(float); - public boolean decimalDigitsExact(); - public java.lang.String toString(); - public java.lang.String toJavaFormatString(); - public void appendTo(java.lang.Appendable); - public static OldFloatingDecimalForTest readJavaFormatString(java.lang.String) throws java.lang.NumberFormatException; - public strictfp double doubleValue(); - public strictfp float floatValue(); -} - -jdk.internal.math.FloatingDecimal - -public class jdk.internal.math.FloatingDecimal { - public jdk.internal.math.FloatingDecimal(); - public static java.lang.String toJavaFormatString(double); - public static java.lang.String toJavaFormatString(float); - public static void appendTo(double, java.lang.Appendable); - public static void appendTo(float, java.lang.Appendable); - public static double parseDouble(java.lang.String) throws java.lang.NumberFormatException; - public static float parseFloat(java.lang.String) throws java.lang.NumberFormatException; - public static jdk.internal.math.FloatingDecimal$AbstractD2ABuffer getD2ABuffer(double); -} -*/ - /** * @test - * @bug 7032154 - * @summary unit tests of FloatingDecimal (use -Dseed=X to set PRANDOM seed) + * @bug 7032154 8343453 + * @summary FloatingDecimal parsing methods (use -Dseed=X to set PRANDOM seed) * @modules java.base/jdk.internal.math - * @library .. * @library /test/lib - * @library /java/lang/Math * @build jdk.test.lib.RandomFactory - * @build DoubleConsts FloatConsts * @run junit TestFloatingDecimal * @author Brian Burkhalter * @key randomness @@ -79,184 +47,53 @@ public class TestFloatingDecimal { private static final Random RANDOM = RandomFactory.getRandom(); - private static int check(String test, Object expected, Object actual) { - int failures = 0; - if(!actual.equals(expected)) { - failures++; - System.err.println("Test " + test + - " expected " + expected + - " but obtained " + actual); - } - return failures; - } - - @Test - public void testAppendToDouble() { - int failures = 0; - - for(int i = 0; i < NUM_RANDOM_TESTS; i++) { - double[] d = new double[] { - RANDOM.nextLong(), - RANDOM.nextGaussian(), - RANDOM.nextDouble()*Double.MAX_VALUE - }; - for(int j = 0; j < d.length; j++) { - OldFloatingDecimalForTest ofd = new OldFloatingDecimalForTest(d[j]); - StringBuilder sb = new StringBuilder(); - ofd.appendTo(sb); - String oldString = sb.toString(); - sb = new StringBuilder(); - FloatingDecimal.appendTo(d[j], sb); - String newString = sb.toString(); - failures += check("testAppendToDouble", oldString, newString); - } - } - - assertEquals(0, failures); - } + /* + * The tests rely on the different conversion implementations + * in FloatDecimal and BigDecimal. + */ @Test - public void testAppendToFloat() { - int failures = 0; - - for(int i = 0; i < NUM_RANDOM_TESTS; i++) { - float[] f = new float[] { - RANDOM.nextLong(), - (float)RANDOM.nextGaussian(), - RANDOM.nextFloat()*Float.MAX_VALUE + public void testParseDouble() { + for (int i = 0; i < NUM_RANDOM_TESTS; i++) { + double[] d = { + RANDOM.nextLong(), + RANDOM.nextGaussian(), + RANDOM.nextDouble() * Double.MAX_VALUE, }; - for(int j = 0; j < f.length; j++) { - OldFloatingDecimalForTest ofd = new OldFloatingDecimalForTest(f[j]); - StringBuilder sb = new StringBuilder(); - ofd.appendTo(sb); - String oldString = sb.toString(); - sb = new StringBuilder(); - FloatingDecimal.appendTo(f[j], sb); - String newString = sb.toString(); - failures += check("testAppendToFloat", oldString, newString); - } - } + for (double v : d) { + String dec = Double.toString(v); + assertEquals(new BigDecimal(dec).doubleValue(), FloatingDecimal.parseDouble(dec)); - assertEquals(0, failures); - } - - @Test - public void testParseDouble() { - int failures = 0; + BigDecimal bd = new BigDecimal(v); + String full = bd.toString(); + assertEquals(bd.doubleValue(), FloatingDecimal.parseDouble(full)); - for(int i = 0; i < NUM_RANDOM_TESTS; i++) { - double[] d = new double[] { - RANDOM.nextLong(), - RANDOM.nextGaussian(), - RANDOM.nextDouble()*Double.MAX_VALUE - }; - for(int j = 0; j < d.length; j++) { - OldFloatingDecimalForTest ofd = new OldFloatingDecimalForTest(d[j]); - String javaFormatString = ofd.toJavaFormatString(); - ofd = OldFloatingDecimalForTest.readJavaFormatString(javaFormatString); - double oldDouble = ofd.doubleValue(); - double newDouble = FloatingDecimal.parseDouble(javaFormatString); - failures += check("testParseDouble", oldDouble, newDouble); + String hex = Double.toHexString(v); + assertEquals(FloatingDecimal.parseDouble(dec), FloatingDecimal.parseDouble(hex)); } } - - assertEquals(0, failures); } @Test public void testParseFloat() { - int failures = 0; - - for(int i = 0; i < NUM_RANDOM_TESTS; i++) { - float[] f = new float[] { - RANDOM.nextInt(), - (float)RANDOM.nextGaussian(), - RANDOM.nextFloat()*Float.MAX_VALUE + for (int i = 0; i < NUM_RANDOM_TESTS; i++) { + float[] f = { + RANDOM.nextLong(), + (float) RANDOM.nextGaussian(), + RANDOM.nextFloat() * Float.MAX_VALUE }; - for(int j = 0; j < f.length; j++) { - OldFloatingDecimalForTest ofd = new OldFloatingDecimalForTest(f[j]); - String javaFormatString = ofd.toJavaFormatString(); - ofd = OldFloatingDecimalForTest.readJavaFormatString(javaFormatString); - float oldFloat = ofd.floatValue(); - float newFloat = FloatingDecimal.parseFloat(javaFormatString); - failures += check("testParseFloat", oldFloat, newFloat); - } - } - - assertEquals(0, failures); - } - - @Test - public void testToJavaFormatStringDoubleFixed() { - int failures = 0; - - double[] d = new double [] { - -5.9522650387500933e18, // dtoa() fast path - 0.872989018674569, // dtoa() fast iterative - long - 1.1317400099603851e308 // dtoa() slow iterative - }; + for (float v : f) { + String dec = Float.toString(v); + assertEquals(new BigDecimal(dec).floatValue(), FloatingDecimal.parseFloat(dec)); - for(int i = 0; i < d.length; i++) { - OldFloatingDecimalForTest ofd = new OldFloatingDecimalForTest(d[i]); - failures += check("testToJavaFormatStringDoubleFixed", ofd.toJavaFormatString(), FloatingDecimal.toJavaFormatString(d[i])); - } - - assertEquals(0, failures); - } + BigDecimal bd = new BigDecimal(v); + String full = bd.toString(); + assertEquals(bd.floatValue(), FloatingDecimal.parseFloat(full)); - @Test - public void testToJavaFormatStringDoubleRandom() { - int failures = 0; - - for(int i = 0; i < NUM_RANDOM_TESTS; i++) { - double[] d = new double[] { - RANDOM.nextLong(), - RANDOM.nextGaussian(), - RANDOM.nextDouble()*Double.MAX_VALUE - }; - for(int j = 0; j < d.length; j++) { - OldFloatingDecimalForTest ofd = new OldFloatingDecimalForTest(d[j]); - failures += check("testToJavaFormatStringDoubleRandom", ofd.toJavaFormatString(), FloatingDecimal.toJavaFormatString(d[j])); + String hex = Float.toHexString(v); + assertEquals(FloatingDecimal.parseFloat(dec), FloatingDecimal.parseFloat(hex)); } } - - assertEquals(0, failures); - } - - @Test - public void testToJavaFormatStringFloatFixed() { - int failures = 0; - - float[] f = new float[] { - -9.8784166e8f, // dtoa() fast path - 0.70443946f, // dtoa() fast iterative - int - 1.8254228e37f // dtoa() slow iterative - }; - - for(int i = 0; i < f.length; i++) { - OldFloatingDecimalForTest ofd = new OldFloatingDecimalForTest(f[i]); - failures += check("testToJavaFormatStringFloatFixed", ofd.toJavaFormatString(), FloatingDecimal.toJavaFormatString(f[i])); - } - - assertEquals(0, failures); } - @Test - public void testToJavaFormatStringFloatRandom() { - int failures = 0; - - for(int i = 0; i < NUM_RANDOM_TESTS; i++) { - float[] f = new float[] { - RANDOM.nextInt(), - (float)RANDOM.nextGaussian(), - RANDOM.nextFloat()*Float.MAX_VALUE - }; - for(int j = 0; j < f.length; j++) { - OldFloatingDecimalForTest ofd = new OldFloatingDecimalForTest(f[j]); - failures += check("testToJavaFormatStringFloatRandom", ofd.toJavaFormatString(), FloatingDecimal.toJavaFormatString(f[j])); - } - } - - assertEquals(0, failures); - } } diff --git a/test/jdk/jdk/internal/math/ToString.java b/test/jdk/jdk/internal/math/ToString.java deleted file mode 100644 index 0d050a13e28..00000000000 --- a/test/jdk/jdk/internal/math/ToString.java +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -/* - * @test - * @modules java.base/jdk.internal.math - */ - -import jdk.internal.math.FloatingDecimal; - -public class ToString { - private static int fail = 0; - - private static Throwable first; - - public static void main(String argv[]) { - test("10.0"); - test("1.0"); - test("0.1"); - test("0.01"); - test("0.001"); - test("1.0E-4"); - if (fail != 0) - throw new RuntimeException(fail + " failure(s), first", first); - } - - private static void test(String exp) { - float c = Float.parseFloat(exp); - String got = FloatingDecimal.toJavaFormatString(c); - if (!got.equals(exp)) - fail("float '" + "': Expected '" + exp + "', got '" + got + "'"); - - double d = Double.parseDouble(exp); - got = FloatingDecimal.toJavaFormatString(d); - if (!got.equals(exp)) - fail("double '" + "': Expected '" + exp + "', got '" + got + "'"); - } - - private static void fail(String s) { - if (first == null) - setFirst(s); - System.err.println("FAILED: " + s); - fail++; - } - - private static void setFirst(String s) { - try { - throw new RuntimeException(s); - } catch (RuntimeException x) { - first = x; - } - } -} From 64e4aa21a42688f8b2095a609e20f05af7672ca4 Mon Sep 17 00:00:00 2001 From: Andrew Haley <aph@openjdk.org> Date: Fri, 22 Nov 2024 12:09:30 +0000 Subject: [PATCH 182/311] 8339916: AIOOBE due to Math.abs(Integer.MIN_VALUE) in tests Reviewed-by: shade --- test/micro/org/openjdk/bench/vm/lang/TypePollution.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/micro/org/openjdk/bench/vm/lang/TypePollution.java b/test/micro/org/openjdk/bench/vm/lang/TypePollution.java index 4994bcf9c2d..94c00d60b33 100644 --- a/test/micro/org/openjdk/bench/vm/lang/TypePollution.java +++ b/test/micro/org/openjdk/bench/vm/lang/TypePollution.java @@ -178,7 +178,7 @@ int instanceOfInterfaceSwitch() { probe ^= probe << 13; // xorshift probe ^= probe >>> 17; probe ^= probe << 5; - dummy += switch(objectArray[Math.abs(probe) % objectArray.length]) { + dummy += switch(objectArray[(probe & Integer.MAX_VALUE) % objectArray.length]) { case I01 inst -> 1; case I02 inst -> 2; case I03 inst -> 3; @@ -192,7 +192,7 @@ int instanceOfInterfaceSwitch() { probe ^= probe << 13; // xorshift probe ^= probe >>> 17; probe ^= probe << 5; - dummy += switch(objectArray[Math.abs(probe) % objectArray.length]) { + dummy += switch(objectArray[(probe & Integer.MAX_VALUE) % objectArray.length]) { case I18 inst -> 8; case I17 inst -> 7; case I16 inst -> 6; From 82c3612d775840aa4b851a29b8ee3337950d5aeb Mon Sep 17 00:00:00 2001 From: Aleksey Shipilev <shade@openjdk.org> Date: Fri, 22 Nov 2024 12:28:03 +0000 Subject: [PATCH 183/311] 8344830: [BACKOUT] JDK-8341334: CDS: Parallel relocation Reviewed-by: dholmes, jpai --- src/hotspot/share/cds/archiveUtils.cpp | 185 ---------------------- src/hotspot/share/cds/archiveUtils.hpp | 93 ----------- src/hotspot/share/cds/cds_globals.hpp | 5 +- src/hotspot/share/cds/filemap.cpp | 36 +---- src/hotspot/share/cds/metaspaceShared.cpp | 6 - src/hotspot/share/runtime/java.cpp | 5 - test/hotspot/jtreg/ProblemList.txt | 11 -- 7 files changed, 3 insertions(+), 338 deletions(-) diff --git a/src/hotspot/share/cds/archiveUtils.cpp b/src/hotspot/share/cds/archiveUtils.cpp index 3c778cbb523..4d717879e0f 100644 --- a/src/hotspot/share/cds/archiveUtils.cpp +++ b/src/hotspot/share/cds/archiveUtils.cpp @@ -399,188 +399,3 @@ size_t HeapRootSegments::segment_offset(size_t seg_idx) { return _base_offset + seg_idx * _max_size_in_bytes; } -ArchiveWorkers ArchiveWorkers::_workers; - -ArchiveWorkers::ArchiveWorkers() : - _start_semaphore(0), - _end_semaphore(0), - _num_workers(0), - _started_workers(0), - _waiting_workers(0), - _running_workers(0), - _state(NOT_READY), - _task(nullptr) { -} - -void ArchiveWorkers::initialize() { - assert(Atomic::load(&_state) == NOT_READY, "Should be"); - - Atomic::store(&_num_workers, max_workers()); - Atomic::store(&_state, READY); - - // Kick off pool startup by creating a single worker. - start_worker_if_needed(); -} - -int ArchiveWorkers::max_workers() { - // The pool is used for short-lived bursty tasks. We do not want to spend - // too much time creating and waking up threads unnecessarily. Plus, we do - // not want to overwhelm large machines. This is why we want to be very - // conservative about the number of workers actually needed. - return MAX2(0, log2i_graceful(os::active_processor_count())); -} - -bool ArchiveWorkers::is_parallel() { - return _num_workers > 0; -} - -void ArchiveWorkers::shutdown() { - while (true) { - State state = Atomic::load(&_state); - if (state == SHUTDOWN) { - // Already shut down. - return; - } - if (Atomic::cmpxchg(&_state, state, SHUTDOWN, memory_order_relaxed) == state) { - if (is_parallel()) { - // Execute a shutdown task and block until all workers respond. - run_task(&_shutdown_task); - } - } - } -} - -void ArchiveWorkers::start_worker_if_needed() { - while (true) { - int cur = Atomic::load(&_started_workers); - if (cur >= _num_workers) { - return; - } - if (Atomic::cmpxchg(&_started_workers, cur, cur + 1, memory_order_relaxed) == cur) { - new ArchiveWorkerThread(this); - return; - } - } -} - -void ArchiveWorkers::signal_worker_if_needed() { - while (true) { - int cur = Atomic::load(&_waiting_workers); - if (cur == 0) { - return; - } - if (Atomic::cmpxchg(&_waiting_workers, cur, cur - 1, memory_order_relaxed) == cur) { - _start_semaphore.signal(1); - return; - } - } -} - -void ArchiveWorkers::run_task(ArchiveWorkerTask* task) { - assert((Atomic::load(&_state) == READY) || - ((Atomic::load(&_state) == SHUTDOWN) && (task == &_shutdown_task)), - "Should be in correct state"); - assert(Atomic::load(&_task) == nullptr, "Should not have running tasks"); - - if (is_parallel()) { - run_task_multi(task); - } else { - run_task_single(task); - } -} - -void ArchiveWorkers::run_task_single(ArchiveWorkerTask* task) { - // Single thread needs no chunking. - task->configure_max_chunks(1); - - // Execute the task ourselves, as there are no workers. - task->work(0, 1); -} - -void ArchiveWorkers::run_task_multi(ArchiveWorkerTask* task) { - // Multiple threads can work with multiple chunks. - task->configure_max_chunks(_num_workers * CHUNKS_PER_WORKER); - - // Set up the run and publish the task. - Atomic::store(&_waiting_workers, _num_workers); - Atomic::store(&_running_workers, _num_workers); - Atomic::release_store(&_task, task); - - // Kick off pool wakeup by signaling a single worker, and proceed - // immediately to executing the task locally. - signal_worker_if_needed(); - - // Execute the task ourselves, while workers are catching up. - // This allows us to hide parts of task handoff latency. - task->run(); - - // Done executing task locally, wait for any remaining workers to complete, - // and then do the final housekeeping. - _end_semaphore.wait(); - Atomic::store(&_task, (ArchiveWorkerTask *) nullptr); - OrderAccess::fence(); - - assert(Atomic::load(&_waiting_workers) == 0, "All workers were signaled"); - assert(Atomic::load(&_running_workers) == 0, "No workers are running"); -} - -void ArchiveWorkerTask::run() { - while (true) { - int chunk = Atomic::load(&_chunk); - if (chunk >= _max_chunks) { - return; - } - if (Atomic::cmpxchg(&_chunk, chunk, chunk + 1, memory_order_relaxed) == chunk) { - assert(0 <= chunk && chunk < _max_chunks, "Sanity"); - work(chunk, _max_chunks); - } - } -} - -void ArchiveWorkerTask::configure_max_chunks(int max_chunks) { - if (_max_chunks == 0) { - _max_chunks = max_chunks; - } -} - -bool ArchiveWorkers::run_as_worker() { - assert(is_parallel(), "Should be in parallel mode"); - _start_semaphore.wait(); - - // Avalanche wakeups: each worker signals two others. - signal_worker_if_needed(); - signal_worker_if_needed(); - - ArchiveWorkerTask* task = Atomic::load_acquire(&_task); - task->run(); - - // All work done in threads should be visible to caller. - OrderAccess::fence(); - - // Signal the pool the tasks are complete, if this is the last worker. - if (Atomic::sub(&_running_workers, 1, memory_order_relaxed) == 0) { - _end_semaphore.signal(); - } - - // Continue if task was not a termination task. - return (task != &_shutdown_task); -} - -ArchiveWorkerThread::ArchiveWorkerThread(ArchiveWorkers* pool) : NamedThread(), _pool(pool) { - set_name("ArchiveWorkerThread"); - os::create_thread(this, os::os_thread); - os::start_thread(this); -} - -void ArchiveWorkerThread::run() { - // Avalanche thread startup: each starting worker starts two others. - _pool->start_worker_if_needed(); - _pool->start_worker_if_needed(); - - // Set ourselves up. - os::set_priority(this, NearMaxPriority); - - while (_pool->run_as_worker()) { - // Work until terminated. - } -} diff --git a/src/hotspot/share/cds/archiveUtils.hpp b/src/hotspot/share/cds/archiveUtils.hpp index 128fdc4d33a..606f5137e9d 100644 --- a/src/hotspot/share/cds/archiveUtils.hpp +++ b/src/hotspot/share/cds/archiveUtils.hpp @@ -33,8 +33,6 @@ #include "utilities/bitMap.hpp" #include "utilities/exceptions.hpp" #include "utilities/macros.hpp" -#include "runtime/nonJavaThread.hpp" -#include "runtime/semaphore.hpp" class BootstrapInfo; class ReservedSpace; @@ -321,95 +319,4 @@ class HeapRootSegments { HeapRootSegments& operator=(const HeapRootSegments&) = default; }; -class ArchiveWorkers; - -// A task to be worked on by worker threads -class ArchiveWorkerTask : public CHeapObj<mtInternal> { - friend class ArchiveWorkers; - friend class ArchiveWorkerShutdownTask; -private: - const char* _name; - int _max_chunks; - volatile int _chunk; - - void run(); - - void configure_max_chunks(int max_chunks); - -public: - ArchiveWorkerTask(const char* name) : - _name(name), _max_chunks(0), _chunk(0) {} - const char* name() const { return _name; } - virtual void work(int chunk, int max_chunks) = 0; -}; - -class ArchiveWorkerThread : public NamedThread { - friend class ArchiveWorkers; -private: - ArchiveWorkers* const _pool; - -public: - ArchiveWorkerThread(ArchiveWorkers* pool); - const char* type_name() const override { return "Archive Worker Thread"; } - void run() override; -}; - -class ArchiveWorkerShutdownTask : public ArchiveWorkerTask { -public: - ArchiveWorkerShutdownTask() : ArchiveWorkerTask("Archive Worker Shutdown") { - // This task always have only one chunk. - configure_max_chunks(1); - } - void work(int chunk, int max_chunks) override { - // Do nothing. - } -}; - -// Special worker pool for archive workers. The goal for this pool is to -// startup fast, distribute spiky workloads efficiently, and being able to -// shutdown after use. This makes the implementation quite different from -// the normal GC worker pool. -class ArchiveWorkers { - friend class ArchiveWorkerThread; -private: - // Target number of chunks per worker. This should be large enough to even - // out work imbalance, and small enough to keep bookkeeping overheads low. - static constexpr int CHUNKS_PER_WORKER = 4; - static int max_workers(); - - // Global shared instance. Can be uninitialized, can be shut down. - static ArchiveWorkers _workers; - - ArchiveWorkerShutdownTask _shutdown_task; - Semaphore _start_semaphore; - Semaphore _end_semaphore; - - int _num_workers; - int _started_workers; - int _waiting_workers; - int _running_workers; - - typedef enum { NOT_READY, READY, SHUTDOWN } State; - volatile State _state; - - ArchiveWorkerTask* _task; - - bool run_as_worker(); - void start_worker_if_needed(); - void signal_worker_if_needed(); - - void run_task_single(ArchiveWorkerTask* task); - void run_task_multi(ArchiveWorkerTask* task); - - bool is_parallel(); - - ArchiveWorkers(); - -public: - static ArchiveWorkers* workers() { return &_workers; } - void initialize(); - void shutdown(); - void run_task(ArchiveWorkerTask* task); -}; - #endif // SHARE_CDS_ARCHIVEUTILS_HPP diff --git a/src/hotspot/share/cds/cds_globals.hpp b/src/hotspot/share/cds/cds_globals.hpp index 811740cfbcb..38f5d8f46a6 100644 --- a/src/hotspot/share/cds/cds_globals.hpp +++ b/src/hotspot/share/cds/cds_globals.hpp @@ -117,10 +117,7 @@ product(bool, AOTClassLinking, false, \ "Load/link all archived classes for the boot/platform/app " \ "loaders before application main") \ - \ - product(bool, AOTCacheParallelRelocation, true, DIAGNOSTIC, \ - "Use parallel relocation code to speed up startup.") \ - \ + // end of CDS_FLAGS DECLARE_FLAGS(CDS_FLAGS) diff --git a/src/hotspot/share/cds/filemap.cpp b/src/hotspot/share/cds/filemap.cpp index d33710a65a3..00d8fba4411 100644 --- a/src/hotspot/share/cds/filemap.cpp +++ b/src/hotspot/share/cds/filemap.cpp @@ -1972,32 +1972,6 @@ char* FileMapInfo::map_bitmap_region() { return bitmap_base; } -class SharedDataRelocationTask : public ArchiveWorkerTask { -private: - BitMapView* const _rw_bm; - BitMapView* const _ro_bm; - SharedDataRelocator* const _rw_reloc; - SharedDataRelocator* const _ro_reloc; - -public: - SharedDataRelocationTask(BitMapView* rw_bm, BitMapView* ro_bm, SharedDataRelocator* rw_reloc, SharedDataRelocator* ro_reloc) : - ArchiveWorkerTask("Shared Data Relocation"), - _rw_bm(rw_bm), _ro_bm(ro_bm), _rw_reloc(rw_reloc), _ro_reloc(ro_reloc) {} - - void work(int chunk, int max_chunks) override { - work_on(chunk, max_chunks, _rw_bm, _rw_reloc); - work_on(chunk, max_chunks, _ro_bm, _ro_reloc); - } - - void work_on(int chunk, int max_chunks, BitMapView* bm, SharedDataRelocator* reloc) { - BitMap::idx_t size = bm->size(); - BitMap::idx_t start = MIN2(size, size * chunk / max_chunks); - BitMap::idx_t end = MIN2(size, size * (chunk + 1) / max_chunks); - assert(end > start, "Sanity: no empty slices"); - bm->iterate(reloc, start, end); - } -}; - // This is called when we cannot map the archive at the requested[ base address (usually 0x800000000). // We relocate all pointers in the 2 core regions (ro, rw). bool FileMapInfo::relocate_pointers_in_core_regions(intx addr_delta) { @@ -2036,14 +2010,8 @@ bool FileMapInfo::relocate_pointers_in_core_regions(intx addr_delta) { valid_new_base, valid_new_end, addr_delta); SharedDataRelocator ro_patcher((address*)ro_patch_base + header()->ro_ptrmap_start_pos(), (address*)ro_patch_end, valid_old_base, valid_old_end, valid_new_base, valid_new_end, addr_delta); - - if (AOTCacheParallelRelocation) { - SharedDataRelocationTask task(&rw_ptrmap, &ro_ptrmap, &rw_patcher, &ro_patcher); - ArchiveWorkers::workers()->run_task(&task); - } else { - rw_ptrmap.iterate(&rw_patcher); - ro_ptrmap.iterate(&ro_patcher); - } + rw_ptrmap.iterate(&rw_patcher); + ro_ptrmap.iterate(&ro_patcher); // The MetaspaceShared::bm region will be unmapped in MetaspaceShared::initialize_shared_spaces(). diff --git a/src/hotspot/share/cds/metaspaceShared.cpp b/src/hotspot/share/cds/metaspaceShared.cpp index a8c10e38577..b2f5f420365 100644 --- a/src/hotspot/share/cds/metaspaceShared.cpp +++ b/src/hotspot/share/cds/metaspaceShared.cpp @@ -1088,9 +1088,6 @@ void MetaspaceShared::initialize_runtime_shared_and_meta_spaces() { assert(CDSConfig::is_using_archive(), "Must be called when UseSharedSpaces is enabled"); MapArchiveResult result = MAP_ARCHIVE_OTHER_FAILURE; - // We are about to open the archives. Initialize workers now. - ArchiveWorkers::workers()->initialize(); - FileMapInfo* static_mapinfo = open_static_archive(); FileMapInfo* dynamic_mapinfo = nullptr; @@ -1682,9 +1679,6 @@ void MetaspaceShared::initialize_shared_spaces() { dynamic_mapinfo->unmap_region(MetaspaceShared::bm); } - // Archive was fully read. Workers are no longer needed. - ArchiveWorkers::workers()->shutdown(); - LogStreamHandle(Info, cds) lsh; if (lsh.is_enabled()) { lsh.print("Using AOT-linked classes: %s (static archive: %s aot-linked classes", diff --git a/src/hotspot/share/runtime/java.cpp b/src/hotspot/share/runtime/java.cpp index d2338cd74d0..c9c7ae8e4c3 100644 --- a/src/hotspot/share/runtime/java.cpp +++ b/src/hotspot/share/runtime/java.cpp @@ -441,11 +441,6 @@ void before_exit(JavaThread* thread, bool halt) { #if INCLUDE_CDS ClassListWriter::write_resolved_constants(); - - // Initiate Archive Workers shutdown. These workers are likely already - // shut down, but we need to make sure they really are. Otherwise, workers - // would fail hard on broken semaphores. - ArchiveWorkers::workers()->shutdown(); #endif // Hang forever on exit if we're reporting an error. diff --git a/test/hotspot/jtreg/ProblemList.txt b/test/hotspot/jtreg/ProblemList.txt index f2f1c4f2f50..d3de1f871e8 100644 --- a/test/hotspot/jtreg/ProblemList.txt +++ b/test/hotspot/jtreg/ProblemList.txt @@ -100,17 +100,6 @@ gc/stress/gclocker/TestExcessGCLockerCollections.java 8229120 generic-all # :hotspot_runtime -runtime/CommandLine/OptionsValidation/TestOptionsWithRanges.java#id0 8344583 macosx-aarch64 -runtime/CommandLine/OptionsValidation/TestOptionsWithRanges.java#id1 8344583 macosx-aarch64 -runtime/CommandLine/OptionsValidation/TestOptionsWithRanges.java#id2 8344583 macosx-aarch64 -runtime/CommandLine/OptionsValidation/TestOptionsWithRanges.java#id3 8344583 macosx-aarch64 -runtime/CommandLine/OptionsValidation/TestOptionsWithRanges.java#id4 8344583 macosx-aarch64 -runtime/CommandLine/OptionsValidation/TestOptionsWithRanges.java#id5 8344583 macosx-aarch64 -runtime/CommandLine/OptionsValidation/TestOptionsWithRanges.java#id6 8344583 macosx-aarch64 -runtime/CommandLine/OptionsValidation/TestOptionsWithRanges.java#id7 8344583 macosx-aarch64 -runtime/CommandLine/OptionsValidation/TestOptionsWithRanges.java#id8 8344583 macosx-aarch64 -runtime/CommandLine/OptionsValidation/TestOptionsWithRanges.java#id9 8344583 macosx-aarch64 - runtime/jni/terminatedThread/TestTerminatedThread.java 8317789 aix-ppc64 runtime/handshake/HandshakeSuspendExitTest.java 8294313 generic-all runtime/Monitor/SyncOnValueBasedClassTest.java 8340995 linux-s390x From 9769ee86978584a65703712c1a845fe4f5fffe29 Mon Sep 17 00:00:00 2001 From: Sean Mullan <mullan@openjdk.org> Date: Fri, 22 Nov 2024 13:18:26 +0000 Subject: [PATCH 184/311] 8344652: Remove access control context text from SSLEngine and SSLSession APIs Reviewed-by: jnimeh --- .../share/classes/javax/net/ssl/SSLEngine.java | 11 ----------- .../share/classes/javax/net/ssl/SSLSession.java | 15 +-------------- 2 files changed, 1 insertion(+), 25 deletions(-) diff --git a/src/java.base/share/classes/javax/net/ssl/SSLEngine.java b/src/java.base/share/classes/javax/net/ssl/SSLEngine.java index 27f3c31e0e9..6d066ea5ca9 100644 --- a/src/java.base/share/classes/javax/net/ssl/SSLEngine.java +++ b/src/java.base/share/classes/javax/net/ssl/SSLEngine.java @@ -377,14 +377,6 @@ * } * </pre></blockquote> * - * <P> - * Applications might choose to process delegated tasks in different - * threads. When an {@code SSLEngine} - * is created, the current {@link java.security.AccessControlContext} - * is saved. All future delegated tasks will be processed using this - * context: that is, all access control decisions will be made using the - * context captured at engine creation. - * * <HR> * * <B>Concurrency Notes</B>: @@ -818,9 +810,6 @@ public abstract SSLEngineResult unwrap(ByteBuffer src, * {@code run} method returns, the {@code Runnable} object * is no longer needed and may be discarded. * <P> - * Delegated tasks run in the {@code AccessControlContext} - * in place when this object was created. - * <P> * A call to this method will return each outstanding task * exactly once. * <P> diff --git a/src/java.base/share/classes/javax/net/ssl/SSLSession.java b/src/java.base/share/classes/javax/net/ssl/SSLSession.java index e83238e140c..3293f86f743 100644 --- a/src/java.base/share/classes/javax/net/ssl/SSLSession.java +++ b/src/java.base/share/classes/javax/net/ssl/SSLSession.java @@ -148,9 +148,6 @@ public interface SSLSession { * replaced. If the new (or existing) {@code value} implements the * {@code SSLSessionBindingListener} interface, the object * represented by {@code value} is notified appropriately. - * <p> - * For security reasons, the same named values may not be - * visible across different access control contexts. * * @param name the name to which the data object will be bound. * This may not be null. @@ -163,9 +160,6 @@ public interface SSLSession { /** * Returns the object bound to the given name in the session's * application layer data. Returns null if there is no such binding. - * <p> - * For security reasons, the same named values may not be - * visible across different access control contexts. * * @param name the name of the binding to find. * @return the value bound to that name, or null if the binding does @@ -181,12 +175,8 @@ public interface SSLSession { * bound to the given name. If the bound existing object * implements the {@code SSLSessionBindingListener} interface, * it is notified appropriately. - * <p> - * For security reasons, the same named values may not be - * visible across different access control contexts. * - * @param name the name of the object to remove visible - * across different access control contexts + * @param name the name of the object to remove * @throws IllegalArgumentException if the argument is null. */ void removeValue(String name); @@ -195,9 +185,6 @@ public interface SSLSession { /** * Returns an array of the names of all the application layer * data objects bound into the Session. - * <p> - * For security reasons, the same named values may not be - * visible across different access control contexts. * * @return a non-null (possibly empty) array of names of the objects * bound to this Session. From 15dbb6a38064d4779a44e584ae67ba26885c8436 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Volkan=20Yaz=C4=B1c=C4=B1?= <volkan.yazici@oracle.com> Date: Fri, 22 Nov 2024 14:39:07 +0000 Subject: [PATCH 185/311] 8344219: Remove calls to SecurityManager and doPrivileged in java.net.SocksSocketImpl after JEP 486 integration Reviewed-by: dfuchs --- .../classes/java/net/SocksSocketImpl.java | 67 +++---------------- 1 file changed, 11 insertions(+), 56 deletions(-) diff --git a/src/java.base/share/classes/java/net/SocksSocketImpl.java b/src/java.base/share/classes/java/net/SocksSocketImpl.java index e6efddae65c..54ff612be02 100644 --- a/src/java.base/share/classes/java/net/SocksSocketImpl.java +++ b/src/java.base/share/classes/java/net/SocksSocketImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -29,7 +29,6 @@ import java.io.OutputStream; import java.io.BufferedOutputStream; import java.nio.charset.StandardCharsets; -import java.security.AccessController; import java.util.Iterator; import jdk.internal.util.StaticProperty; @@ -75,30 +74,10 @@ private static boolean useV4(Proxy proxy) { return DefaultProxySelector.socksProxyVersion() == 4; } - @SuppressWarnings("removal") - private synchronized void privilegedConnect(final String host, - final int port, - final int timeout) - throws IOException - { - try { - AccessController.doPrivileged( - new java.security.PrivilegedExceptionAction<>() { - public Void run() throws IOException { - superConnectServer(host, port, timeout); - cmdIn = getInputStream(); - cmdOut = getOutputStream(); - return null; - } - }); - } catch (java.security.PrivilegedActionException pae) { - throw (IOException) pae.getException(); - } - } - - private void superConnectServer(String host, int port, - int timeout) throws IOException { + private synchronized void doConnect(final String host, final int port, final int timeout) throws IOException { delegate.connect(new InetSocketAddress(host, port), timeout); + cmdIn = getInputStream(); + cmdOut = getOutputStream(); } private static int remainingMillis(long deadlineMillis) throws IOException { @@ -151,15 +130,8 @@ private boolean authenticate(byte method, InputStream in, String userName; String password = null; final InetAddress addr = InetAddress.getByName(server); - @SuppressWarnings("removal") - PasswordAuthentication pw = - java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction<>() { - public PasswordAuthentication run() { - return Authenticator.requestPasswordAuthentication( - server, addr, serverPort, "SOCKS5", "SOCKS authentication", null); - } - }); + PasswordAuthentication pw = Authenticator.requestPasswordAuthentication( + server, addr, serverPort, "SOCKS5", "SOCKS authentication", null); if (pw != null) { userName = pw.getUserName(); password = new String(pw.getPassword()); @@ -250,8 +222,6 @@ protected void connect(InetAddress address, int port) throws IOException { * @param endpoint the {@code SocketAddress} to connect to. * @param timeout the timeout value in milliseconds * @throws IOException if the connection can't be established. - * @throws SecurityException if there is a security manager and it - * doesn't allow the connection * @throws IllegalArgumentException if endpoint is null or a * SocketAddress subclass not supported by this socket */ @@ -266,29 +236,14 @@ protected void connect(SocketAddress endpoint, int timeout) throws IOException { deadlineMillis = finish < 0 ? Long.MAX_VALUE : finish; } - @SuppressWarnings("removal") - SecurityManager security = System.getSecurityManager(); if (!(endpoint instanceof InetSocketAddress epoint)) throw new IllegalArgumentException("Unsupported address type"); - if (security != null) { - if (epoint.isUnresolved()) - security.checkConnect(epoint.getHostName(), - epoint.getPort()); - else - security.checkConnect(epoint.getAddress().getHostAddress(), - epoint.getPort()); - } + if (server == null) { // This is the general case // server is not null only when the socket was created with a // specified proxy in which case it does bypass the ProxySelector - @SuppressWarnings("removal") - ProxySelector sel = java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction<>() { - public ProxySelector run() { - return ProxySelector.getDefault(); - } - }); + ProxySelector sel = ProxySelector.getDefault(); if (sel == null) { /* * No default proxySelector --> direct connection @@ -337,7 +292,7 @@ public ProxySelector run() { // Connects to the SOCKS server try { - privilegedConnect(server, serverPort, remainingMillis(deadlineMillis)); + doConnect(server, serverPort, remainingMillis(deadlineMillis)); // Worked, let's get outta here break; } catch (IOException e) { @@ -361,13 +316,13 @@ public ProxySelector run() { } else { // Connects to the SOCKS server try { - privilegedConnect(server, serverPort, remainingMillis(deadlineMillis)); + doConnect(server, serverPort, remainingMillis(deadlineMillis)); } catch (IOException e) { throw new SocketException(e.getMessage(), e); } } - // cmdIn & cmdOut were initialized during the privilegedConnect() call + // `cmdIn` & `cmdOut` were initialized during the `doConnect()` call BufferedOutputStream out = new BufferedOutputStream(cmdOut, 512); InputStream in = cmdIn; From 6d3becb486ab38c9c2d2a6fbc428bf794375317c Mon Sep 17 00:00:00 2001 From: Tobias Hartmann <thartmann@openjdk.org> Date: Fri, 22 Nov 2024 14:48:39 +0000 Subject: [PATCH 186/311] 8344861: Disable CheckJNICalls in tests until JDK-8344802 is fixed Reviewed-by: coleenp --- test/jdk/java/lang/String/IndexOf.java | 4 ++-- test/jdk/java/lang/StringBuffer/ECoreIndexOf.java | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/test/jdk/java/lang/String/IndexOf.java b/test/jdk/java/lang/String/IndexOf.java index baab83e19c4..e37e253f251 100644 --- a/test/jdk/java/lang/String/IndexOf.java +++ b/test/jdk/java/lang/String/IndexOf.java @@ -34,7 +34,7 @@ * @summary test String indexOf() intrinsic * @requires vm.cpu.features ~= ".*avx2.*" * @requires vm.compiler2.enabled - * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -Xcomp -XX:-TieredCompilation -XX:UseAVX=2 -XX:+UnlockDiagnosticVMOptions -XX:+EnableX86ECoreOpts IndexOf + * @run main/othervm -XX:+IgnoreUnrecognizedVMOptions -Xcomp -XX:-TieredCompilation -XX:UseAVX=2 -XX:+UnlockDiagnosticVMOptions -XX:+EnableX86ECoreOpts -XX:-CheckJNICalls IndexOf */ public class IndexOf { @@ -255,4 +255,4 @@ IndexOf test4() { // Test needle at unreachable offset } return this; } -} \ No newline at end of file +} diff --git a/test/jdk/java/lang/StringBuffer/ECoreIndexOf.java b/test/jdk/java/lang/StringBuffer/ECoreIndexOf.java index ccaee0f77ea..942486e85b8 100644 --- a/test/jdk/java/lang/StringBuffer/ECoreIndexOf.java +++ b/test/jdk/java/lang/StringBuffer/ECoreIndexOf.java @@ -34,7 +34,7 @@ * @summary Test indexOf and lastIndexOf * @requires vm.cpu.features ~= ".*avx2.*" * @requires vm.compiler2.enabled - * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+EnableX86ECoreOpts -XX:UseAVX=2 -Xbatch -XX:-TieredCompilation -XX:CompileCommand=dontinline,ECoreIndexOf.indexOfKernel ECoreIndexOf + * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+EnableX86ECoreOpts -XX:-CheckJNICalls -XX:UseAVX=2 -Xbatch -XX:-TieredCompilation -XX:CompileCommand=dontinline,ECoreIndexOf.indexOfKernel ECoreIndexOf * @key randomness */ From 13987b4244614d594dc8f94c288eddb6239a066f Mon Sep 17 00:00:00 2001 From: Ben Perez <bperez@openjdk.org> Date: Fri, 22 Nov 2024 16:36:52 +0000 Subject: [PATCH 187/311] 8298390: Implement JEP 496: Quantum-Resistant Module-Lattice-Based Key Encapsulation Mechanism Co-authored-by: Ferenc Rakoczi <ferenc.r.rakoczi@oracle.com> Reviewed-by: valeriep --- .../com/sun/crypto/provider/ML_KEM.java | 1511 +++++++++++++++++ .../com/sun/crypto/provider/ML_KEM_Impls.java | 233 +++ .../com/sun/crypto/provider/SunJCE.java | 21 +- .../security/spec/NamedParameterSpec.java | 24 + .../sun/security/provider/SHA3Parallel.java | 94 + .../classes/sun/security/util/KnownOIDs.java | 5 + .../internalProjection.json | 1023 +++++++++++ .../internalProjection.json | 630 +++++++ .../security/provider/all/Deterministic.java | 1 + .../bench/java/security/MLKEMBench.java | 1240 ++++++++++++++ 10 files changed, 4781 insertions(+), 1 deletion(-) create mode 100644 src/java.base/share/classes/com/sun/crypto/provider/ML_KEM.java create mode 100644 src/java.base/share/classes/com/sun/crypto/provider/ML_KEM_Impls.java create mode 100644 src/java.base/share/classes/sun/security/provider/SHA3Parallel.java create mode 100644 test/jdk/sun/security/provider/acvp/data/ML-KEM-encapDecap-FIPS203/internalProjection.json create mode 100644 test/jdk/sun/security/provider/acvp/data/ML-KEM-keyGen-FIPS203/internalProjection.json create mode 100644 test/micro/org/openjdk/bench/java/security/MLKEMBench.java diff --git a/src/java.base/share/classes/com/sun/crypto/provider/ML_KEM.java b/src/java.base/share/classes/com/sun/crypto/provider/ML_KEM.java new file mode 100644 index 00000000000..40bbc6c56cc --- /dev/null +++ b/src/java.base/share/classes/com/sun/crypto/provider/ML_KEM.java @@ -0,0 +1,1511 @@ +/* + * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package com.sun.crypto.provider; + +import java.security.*; +import java.util.Arrays; +import javax.crypto.DecapsulateException; + +import sun.security.provider.SHA3.SHAKE256; +import sun.security.provider.SHA3Parallel.Shake128Parallel; + +public final class ML_KEM { + + public static final int SECRET_SIZE = 32; + private static final String HASH_H_NAME = "SHA3-256"; + private static final String HASH_G_NAME = "SHA3-512"; + + private static final int ML_KEM_Q = 3329; + private static final int ML_KEM_N = 256; + + private static final int XOF_BLOCK_LEN = 168; // the block length for SHAKE128 + private static final int XOF_PAD = 24; + private static final int MONT_R_BITS = 20; + private static final int MONT_Q = 3329; + private static final int MONT_R_SQUARE_MOD_Q = 152; + private static final int MONT_Q_INV_MOD_R = 586497; + + // toMont((ML_KEM_N / 2)^-1 mod ML_KEM_Q) using R = 2^MONT_R_BITS + private static final int MONT_DIM_HALF_INVERSE = 1534; + private static final int BARRETT_MULTIPLIER = 20159; + private static final int BARRETT_SHIFT = 26; + private static final int[] MONT_ZETAS_FOR_NTT = new int[]{ + 1188, 914, -969, 585, -551, 1263, -97, 593, + -35, -1400, -417, -1253, 742, -281, 185, -819, + -1226, 895, -530, 52, 25, 1000, 1249, -909, + -373, -1604, -259, -1369, -82, 49, 1496, -406, + 445, 1155, -405, -714, 553, -1183, -1401, 1598, + -128, 1538, -669, 744, 1382, -1313, 201, -332, + -1440, -1007, -36, -1617, 567, -623, 1429, 290, + -1269, -825, -1613, 510, -395, 845, -426, -1003, + 222, -1107, 172, -42, 620, 1497, -1649, 94, + -595, -497, -431, -1327, -702, -1448, -184, -607, + -868, -1430, 977, 884, 425, 355, 1259, 1192, + 317, -636, -1074, 30, -1394, 833, -1200, -244, + 907, -339, -227, 1178, -586, -137, -514, 534, + 1153, -486, -1386, -668, 191, 982, 88, 1014, + -1177, -474, -612, -857, -348, -604, 990, 1601, + -1599, -709, -789, -1317, -57, 1049, -584 + }; + + private static final short[] MONT_ZETAS_FOR_VECTOR_NTT_ARR = new short[]{ + // level 0 + -758, -758, -758, -758, -758, -758, -758, -758, + -758, -758, -758, -758, -758, -758, -758, -758, + -758, -758, -758, -758, -758, -758, -758, -758, + -758, -758, -758, -758, -758, -758, -758, -758, + -758, -758, -758, -758, -758, -758, -758, -758, + -758, -758, -758, -758, -758, -758, -758, -758, + -758, -758, -758, -758, -758, -758, -758, -758, + -758, -758, -758, -758, -758, -758, -758, -758, + -758, -758, -758, -758, -758, -758, -758, -758, + -758, -758, -758, -758, -758, -758, -758, -758, + -758, -758, -758, -758, -758, -758, -758, -758, + -758, -758, -758, -758, -758, -758, -758, -758, + -758, -758, -758, -758, -758, -758, -758, -758, + -758, -758, -758, -758, -758, -758, -758, -758, + -758, -758, -758, -758, -758, -758, -758, -758, + -758, -758, -758, -758, -758, -758, -758, -758, + // level 1 + -359, -359, -359, -359, -359, -359, -359, -359, + -359, -359, -359, -359, -359, -359, -359, -359, + -359, -359, -359, -359, -359, -359, -359, -359, + -359, -359, -359, -359, -359, -359, -359, -359, + -359, -359, -359, -359, -359, -359, -359, -359, + -359, -359, -359, -359, -359, -359, -359, -359, + -359, -359, -359, -359, -359, -359, -359, -359, + -359, -359, -359, -359, -359, -359, -359, -359, + -1517, -1517, -1517, -1517, -1517, -1517, -1517, -1517, + -1517, -1517, -1517, -1517, -1517, -1517, -1517, -1517, + -1517, -1517, -1517, -1517, -1517, -1517, -1517, -1517, + -1517, -1517, -1517, -1517, -1517, -1517, -1517, -1517, + -1517, -1517, -1517, -1517, -1517, -1517, -1517, -1517, + -1517, -1517, -1517, -1517, -1517, -1517, -1517, -1517, + -1517, -1517, -1517, -1517, -1517, -1517, -1517, -1517, + -1517, -1517, -1517, -1517, -1517, -1517, -1517, -1517, + // level 2 + 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, + 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, + 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, + 1493, 1493, 1493, 1493, 1493, 1493, 1493, 1493, + 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, + 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, + 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, + 1422, 1422, 1422, 1422, 1422, 1422, 1422, 1422, + 287, 287, 287, 287, 287, 287, 287, 287, + 287, 287, 287, 287, 287, 287, 287, 287, + 287, 287, 287, 287, 287, 287, 287, 287, + 287, 287, 287, 287, 287, 287, 287, 287, + 202, 202, 202, 202, 202, 202, 202, 202, + 202, 202, 202, 202, 202, 202, 202, 202, + 202, 202, 202, 202, 202, 202, 202, 202, + 202, 202, 202, 202, 202, 202, 202, 202, + // level 3 + -171, -171, -171, -171, -171, -171, -171, -171, + -171, -171, -171, -171, -171, -171, -171, -171, + 622, 622, 622, 622, 622, 622, 622, 622, + 622, 622, 622, 622, 622, 622, 622, 622, + 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, + 1577, 1577, 1577, 1577, 1577, 1577, 1577, 1577, + 182, 182, 182, 182, 182, 182, 182, 182, + 182, 182, 182, 182, 182, 182, 182, 182, + 962, 962, 962, 962, 962, 962, 962, 962, + 962, 962, 962, 962, 962, 962, 962, 962, + -1202, -1202, -1202, -1202, -1202, -1202, -1202, -1202, + -1202, -1202, -1202, -1202, -1202, -1202, -1202, -1202, + -1474, -1474, -1474, -1474, -1474, -1474, -1474, -1474, + -1474, -1474, -1474, -1474, -1474, -1474, -1474, -1474, + 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, + 1468, 1468, 1468, 1468, 1468, 1468, 1468, 1468, + // level 4 + 573, 573, 573, 573, 573, 573, 573, 573, + -1325, -1325, -1325, -1325, -1325, -1325, -1325, -1325, + 264, 264, 264, 264, 264, 264, 264, 264, + 383, 383, 383, 383, 383, 383, 383, 383, + -829, -829, -829, -829, -829, -829, -829, -829, + 1458, 1458, 1458, 1458, 1458, 1458, 1458, 1458, + -1602, -1602, -1602, -1602, -1602, -1602, -1602, -1602, + -130, -130, -130, -130, -130, -130, -130, -130, + -681, -681, -681, -681, -681, -681, -681, -681, + 1017, 1017, 1017, 1017, 1017, 1017, 1017, 1017, + 732, 732, 732, 732, 732, 732, 732, 732, + 608, 608, 608, 608, 608, 608, 608, 608, + -1542, -1542, -1542, -1542, -1542, -1542, -1542, -1542, + 411, 411, 411, 411, 411, 411, 411, 411, + -205, -205, -205, -205, -205, -205, -205, -205, + -1571, -1571, -1571, -1571, -1571, -1571, -1571, -1571, + // level 5 + 1223, 1223, 1223, 1223, 652, 652, 652, 652, + -552, -552, -552, -552, 1015, 1015, 1015, 1015, + -1293, -1293, -1293, -1293, 1491, 1491, 1491, 1491, + -282, -282, -282, -282, -1544, -1544, -1544, -1544, + 516, 516, 516, 516, -8, -8, -8, -8, + -320, -320, -320, -320, -666, -666, -666, -666, + 1711, 1711, 1711, 1711, -1162, -1162, -1162, -1162, + 126, 126, 126, 126, 1469, 1469, 1469, 1469, + -853, -853, -853, -853, -90, -90, -90, -90, + -271, -271, -271, -271, 830, 830, 830, 830, + 107, 107, 107, 107, -1421, -1421, -1421, -1421, + -247, -247, -247, -247, -951, -951, -951, -951, + -398, -398, -398, -398, 961, 961, 961, 961, + -1508, -1508, -1508, -1508, -725, -725, -725, -725, + 448, 448, 448, 448, -1065, -1065, -1065, -1065, + 677, 677, 677, 677, -1275, -1275, -1275, -1275, + // level 6 + -1103, -1103, 430, 430, 555, 555, 843, 843, + -1251, -1251, 871, 871, 1550, 1550, 105, 105, + 422, 422, 587, 587, 177, 177, -235, -235, + -291, -291, -460, -460, 1574, 1574, 1653, 1653, + -246, -246, 778, 778, 1159, 1159, -147, -147, + -777, -777, 1483, 1483, -602, -602, 1119, 1119, + -1590, -1590, 644, 644, -872, -872, 349, 349, + 418, 418, 329, 329, -156, -156, -75, -75, + 817, 817, 1097, 1097, 603, 603, 610, 610, + 1322, 1322, -1285, -1285, -1465, -1465, 384, 384, + -1215, -1215, -136, -136, 1218, 1218, -1335, -1335, + -874, -874, 220, 220, -1187, -1187, 1670, 1670, + -1185, -1185, -1530, -1530, -1278, -1278, 794, 794, + -1510, -1510, -854, -854, -870, -870, 478, 478, + -108, -108, -308, -308, 996, 996, 991, 991, + 958, 958, -1460, -1460, 1522, 1522, 1628, 1628 + }; + private static final short[] MONT_ZETAS_FOR_VECTOR_INVERSE_NTT_ARR = new short[]{ + // level 0 + -1628, -1628, -1522, -1522, 1460, 1460, -958, -958, + -991, -991, -996, -996, 308, 308, 108, 108, + -478, -478, 870, 870, 854, 854, 1510, 1510, + -794, -794, 1278, 1278, 1530, 1530, 1185, 1185, + 1659, 1659, 1187, 1187, -220, -220, 874, 874, + 1335, 1335, -1218, -1218, 136, 136, 1215, 1215, + -384, -384, 1465, 1465, 1285, 1285, -1322, -1322, + -610, -610, -603, -603, -1097, -1097, -817, -817, + 75, 75, 156, 156, -329, -329, -418, -418, + -349, -349, 872, 872, -644, -644, 1590, 1590, + -1119, -1119, 602, 602, -1483, -1483, 777, 777, + 147, 147, -1159, -1159, -778, -778, 246, 246, + -1653, -1653, -1574, -1574, 460, 460, 291, 291, + 235, 235, -177, -177, -587, -587, -422, -422, + -105, -105, -1550, -1550, -871, -871, 1251, 1251, + -843, -843, -555, -555, -430, -430, 1103, 1103, + // level 1 + 1275, 1275, 1275, 1275, -677, -677, -677, -677, + 1065, 1065, 1065, 1065, -448, -448, -448, -448, + 725, 725, 725, 725, 1508, 1508, 1508, 1508, + -961, -961, -961, -961, 398, 398, 398, 398, + 951, 951, 951, 951, 247, 247, 247, 247, + 1421, 1421, 1421, 1421, -107, -107, -107, -107, + -830, -830, -830, -830, 271, 271, 271, 271, + 90, 90, 90, 90, 853, 853, 853, 853, + -1469, -1469, -1469, -1469, -126, -126, -126, -126, + 1162, 1162, 1162, 1162, 1618, 1618, 1618, 1618, + 666, 666, 666, 666, 320, 320, 320, 320, + 8, 8, 8, 8, -516, -516, -516, -516, + 1544, 1544, 1544, 1544, 282, 282, 282, 282, + -1491, -1491, -1491, -1491, 1293, 1293, 1293, 1293, + -1015, -1015, -1015, -1015, 552, 552, 552, 552, + -652, -652, -652, -652, -1223, -1223, -1223, -1223, + // level 2 + 1571, 1571, 1571, 1571, 1571, 1571, 1571, 1571, + 205, 205, 205, 205, 205, 205, 205, 205, + -411, -411, -411, -411, -411, -411, -411, -411, + 1542, 1542, 1542, 1542, 1542, 1542, 1542, 1542, + -608, -608, -608, -608, -608, -608, -608, -608, + -732, -732, -732, -732, -732, -732, -732, -732, + -1017, -1017, -1017, -1017, -1017, -1017, -1017, -1017, + 681, 681, 681, 681, 681, 681, 681, 681, + 130, 130, 130, 130, 130, 130, 130, 130, + 1602, 1602, 1602, 1602, 1602, 1602, 1602, 1602, + -1458, -1458, -1458, -1458, -1458, -1458, -1458, -1458, + 829, 829, 829, 829, 829, 829, 829, 829, + -383, -383, -383, -383, -383, -383, -383, -383, + -264, -264, -264, -264, -264, -264, -264, -264, + 1325, 1325, 1325, 1325, 1325, 1325, 1325, 1325, + -573, -573, -573, -573, -573, -573, -573, -573, + // level 3 + -1468, -1468, -1468, -1468, -1468, -1468, -1468, -1468, + -1468, -1468, -1468, -1468, -1468, -1468, -1468, -1468, + 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, + 1474, 1474, 1474, 1474, 1474, 1474, 1474, 1474, + 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, + 1202, 1202, 1202, 1202, 1202, 1202, 1202, 1202, + -962, -962, -962, -962, -962, -962, -962, -962, + -962, -962, -962, -962, -962, -962, -962, -962, + -182, -182, -182, -182, -182, -182, -182, -182, + -182, -182, -182, -182, -182, -182, -182, -182, + -1577, -1577, -1577, -1577, -1577, -1577, -1577, -1577, + -1577, -1577, -1577, -1577, -1577, -1577, -1577, -1577, + -622, -622, -622, -622, -622, -622, -622, -622, + -622, -622, -622, -622, -622, -622, -622, -622, + 171, 171, 171, 171, 171, 171, 171, 171, + 171, 171, 171, 171, 171, 171, 171, 171, + // level 4 + -202, -202, -202, -202, -202, -202, -202, -202, + -202, -202, -202, -202, -202, -202, -202, -202, + -202, -202, -202, -202, -202, -202, -202, -202, + -202, -202, -202, -202, -202, -202, -202, -202, + -287, -287, -287, -287, -287, -287, -287, -287, + -287, -287, -287, -287, -287, -287, -287, -287, + -287, -287, -287, -287, -287, -287, -287, -287, + -287, -287, -287, -287, -287, -287, -287, -287, + -1422, -1422, -1422, -1422, -1422, -1422, -1422, -1422, + -1422, -1422, -1422, -1422, -1422, -1422, -1422, -1422, + -1422, -1422, -1422, -1422, -1422, -1422, -1422, -1422, + -1422, -1422, -1422, -1422, -1422, -1422, -1422, -1422, + -1493, -1493, -1493, -1493, -1493, -1493, -1493, -1493, + -1493, -1493, -1493, -1493, -1493, -1493, -1493, -1493, + -1493, -1493, -1493, -1493, -1493, -1493, -1493, -1493, + -1493, -1493, -1493, -1493, -1493, -1493, -1493, -1493, + // level 5 + 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, + 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, + 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, + 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, + 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, + 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, + 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, + 1517, 1517, 1517, 1517, 1517, 1517, 1517, 1517, + 359, 359, 359, 359, 359, 359, 359, 359, + 359, 359, 359, 359, 359, 359, 359, 359, + 359, 359, 359, 359, 359, 359, 359, 359, + 359, 359, 359, 359, 359, 359, 359, 359, + 359, 359, 359, 359, 359, 359, 359, 359, + 359, 359, 359, 359, 359, 359, 359, 359, + 359, 359, 359, 359, 359, 359, 359, 359, + 359, 359, 359, 359, 359, 359, 359, 359, + // level 6 + 758, 758, 758, 758, 758, 758, 758, 758, + 758, 758, 758, 758, 758, 758, 758, 758, + 758, 758, 758, 758, 758, 758, 758, 758, + 758, 758, 758, 758, 758, 758, 758, 758, + 758, 758, 758, 758, 758, 758, 758, 758, + 758, 758, 758, 758, 758, 758, 758, 758, + 758, 758, 758, 758, 758, 758, 758, 758, + 758, 758, 758, 758, 758, 758, 758, 758, + 758, 758, 758, 758, 758, 758, 758, 758, + 758, 758, 758, 758, 758, 758, 758, 758, + 758, 758, 758, 758, 758, 758, 758, 758, + 758, 758, 758, 758, 758, 758, 758, 758, + 758, 758, 758, 758, 758, 758, 758, 758, + 758, 758, 758, 758, 758, 758, 758, 758, + 758, 758, 758, 758, 758, 758, 758, 758, + 758, 758, 758, 758, 758, 758, 758, 758 + }; + + private static final int[] MONT_ZETAS_FOR_NTT_MULT = new int[]{ + -1003, 1003, 222, -222, -1107, 1107, 172, -172, + -42, 42, 620, -620, 1497, -1497, -1649, 1649, + 94, -94, -595, 595, -497, 497, -431, 431, + -1327, 1327, -702, 702, -1448, 1448, -184, 184, + -607, 607, -868, 868, -1430, 1430, 977, -977, + 884, -884, 425, -425, 355, -355, 1259, -1259, + 1192, -1192, 317, -317, -636, 636, -1074, 1074, + 30, -30, -1394, 1394, 833, -833, -1200, 1200, + -244, 244, 907, -907, -339, 339, -227, 227, + 1178, -1178, -586, 586, -137, 137, -514, 514, + 534, -534, 1153, -1153, -486, 486, -1386, 1386, + -668, 668, 191, -191, 982, -982, 88, -88, + 1014, -1014, -1177, 1177, -474, 474, -612, 612, + -857, 857, -348, 348, -604, 604, 990, -990, + 1601, -1601, -1599, 1599, -709, 709, -789, 789, + -1317, 1317, -57, 57, 1049, -1049, -584, 584 + }; + + private static final short[] MONT_ZETAS_FOR_VECTOR_NTT_MULT_ARR = new short[]{ + -1103, 1103, 430, -430, 555, -555, 843, -843, + -1251, 1251, 871, -871, 1550, -1550, 105, -105, + 422, -422, 587, -587, 177, -177, -235, 235, + -291, 291, -460, 460, 1574, -1574, 1653, -1653, + -246, 246, 778, -778, 1159, -1159, -147, 147, + -777, 777, 1483, -1483, -602, 602, 1119, -1119, + -1590, 1590, 644, -644, -872, 872, 349, -349, + 418, -418, 329, -329, -156, 156, -75, 75, + 817, -817, 1097, -1097, 603, -603, 610, -610, + 1322, -1322, -1285, 1285, -1465, 1465, 384, -384, + -1215, 1215, -136, 136, 1218, -1218, -1335, 1335, + -874, 874, 220, -220, -1187, 1187, 1670, 1659, + -1185, 1185, -1530, 1530, -1278, 1278, 794, -794, + -1510, 1510, -854, 854, -870, 870, 478, -478, + -108, 108, -308, 308, 996, -996, 991, -991, + 958, -958, -1460, 1460, 1522, -1522, 1628, -1628 + }; + + private final int mlKem_k; + private final int mlKem_eta1; + private final int mlKem_eta2; + + private final int mlKem_du; + private final int mlKem_dv; + private final int encapsulationSize; + + public ML_KEM(String name) { + switch (name) { + case "ML-KEM-512" -> { + mlKem_k = 2; + mlKem_eta1 = 3; + mlKem_eta2 = 2; + mlKem_du = 10; + mlKem_dv = 4; + } + case "ML-KEM-768" -> { + mlKem_k = 3; + mlKem_eta1 = 2; + mlKem_eta2 = 2; + mlKem_du = 10; + mlKem_dv = 4; + } + case "ML-KEM-1024" -> { + mlKem_k = 4; + mlKem_eta1 = 2; + mlKem_eta2 = 2; + mlKem_du = 11; + mlKem_dv = 5; + } + default -> throw new IllegalArgumentException( + // This should never happen. + "Invalid algorithm name (" + name + ")."); + } + encapsulationSize = (mlKem_k * mlKem_du + mlKem_dv) * 32; + } + + /* + Classes for the internal K_PKE scheme + */ + private record K_PKE_EncryptionKey(byte[] keyBytes) {} + + private record K_PKE_DecryptionKey(byte[] keyBytes) {} + + private record K_PKE_KeyPair( + K_PKE_EncryptionKey publicKey, K_PKE_DecryptionKey privateKey) { + } + + protected record K_PKE_CipherText(byte[] encryptedBytes) { + } + + private boolean isValidCipherText(K_PKE_CipherText cipherText) { + return (cipherText.encryptedBytes.length == encapsulationSize); + } + + /* + Classes for internal KEM scheme + */ + protected record ML_KEM_EncapsulationKey(byte[] keyBytes) { + } + + protected record ML_KEM_DecapsulationKey(byte[] keyBytes) { + } + + protected record ML_KEM_KeyPair( + ML_KEM_EncapsulationKey encapsulationKey, + ML_KEM_DecapsulationKey decapsulationKey) { + } + + protected record ML_KEM_EncapsulateResult( + K_PKE_CipherText cipherText, byte[] sharedSecret) { + } + + protected int getEncapsulationSize() { + return encapsulationSize; + } + + // Encapsulation key checks from section 7.2 of spec + protected Object checkPublicKey(byte[] pk) throws InvalidKeyException { + //Encapsulation key type check + if (pk.length != mlKem_k * 384 + 32) { + throw new InvalidKeyException("Public key is not the correct size"); + } + + //Encapsulation key modulus check + int x, y, z, a, b; + for (int i = 0; i < mlKem_k * 384; i += 3) { + x = pk[i] & 0xFF; + y = pk[i + 1] & 0xFF; + z = pk[i + 2] & 0xFF; + a = x + ((y & 0xF) << 8); + b = (y >> 4) + (z << 4); + if ((a >= ML_KEM_Q) || (b >= ML_KEM_Q)) { + throw new InvalidKeyException( + "Coefficients in public key not in specified range"); + } + } + return null; + } + + // Decapsulation key checks from Section 7.3 of spec + protected Object checkPrivateKey(byte[] sk) throws InvalidKeyException { + MessageDigest mlKemH; + try { + mlKemH = MessageDigest.getInstance(HASH_H_NAME); + } catch (NoSuchAlgorithmException e) { + throw new RuntimeException(e); + } + + //Decapsulation key type check + if (sk.length != mlKem_k * 768 + 96) { + throw new InvalidKeyException("Private key is not the correct size"); + } + + //Decapsulation hash check + mlKemH.update(sk, mlKem_k * 384, mlKem_k * 384 + 32); + byte[] check = Arrays.copyOfRange(sk, mlKem_k * 768 + 32, mlKem_k * 768 + 64); + if (!MessageDigest.isEqual(mlKemH.digest(), check)) { + throw new InvalidKeyException("Private key hash check failed"); + } + return null; + } + + /* + Main internal algorithms from Section 6 of specification + */ + protected ML_KEM_KeyPair generateKemKeyPair(byte[] kem_d, byte[] kem_z) { + MessageDigest mlKemH; + try { + mlKemH = MessageDigest.getInstance(HASH_H_NAME); + } catch (NoSuchAlgorithmException e) { + // This should never happen. + throw new RuntimeException(e); + } + + //Generate K-PKE keys + var kPkeKeyPair = generateK_PkeKeyPair(kem_d); + //encaps key = kPke encryption key + byte[] encapsKey = kPkeKeyPair.publicKey.keyBytes; + + //Derive decapsulation key = kPkePrivatKey || encapsKey || H(encapsKey) || kem_Z + byte[] kPkePrivateKey = kPkeKeyPair.privateKey.keyBytes; + byte[] decapsKey = new byte[encapsKey.length + kPkePrivateKey.length + 64]; + System.arraycopy(kPkePrivateKey, 0, decapsKey, 0, kPkePrivateKey.length); + Arrays.fill(kPkePrivateKey, (byte)0); + System.arraycopy(encapsKey, 0, decapsKey, + kPkePrivateKey.length, encapsKey.length); + + mlKemH.update(encapsKey); + try { + mlKemH.digest(decapsKey, kPkePrivateKey.length + encapsKey.length, 32); + } catch (DigestException e) { + // This should never happen. + throw new RuntimeException(e); + } + System.arraycopy(kem_z, 0, decapsKey, + kPkePrivateKey.length + encapsKey.length + 32, 32); + + return new ML_KEM_KeyPair( + new ML_KEM_EncapsulationKey(encapsKey), + new ML_KEM_DecapsulationKey(decapsKey)); + } + + protected ML_KEM_EncapsulateResult encapsulate( + ML_KEM_EncapsulationKey encapsulationKey, byte[] randomMessage) { + MessageDigest mlKemH; + MessageDigest mlKemG; + try { + mlKemH = MessageDigest.getInstance(HASH_H_NAME); + mlKemG = MessageDigest.getInstance(HASH_G_NAME); + } catch (NoSuchAlgorithmException e){ + // This should never happen. + throw new RuntimeException(e); + } + + mlKemH.update(encapsulationKey.keyBytes); + mlKemG.update(randomMessage); + mlKemG.update(mlKemH.digest()); + var kHatAndRandomCoins = mlKemG.digest(); + var randomCoins = Arrays.copyOfRange(kHatAndRandomCoins, 32, 64); + var cipherText = kPkeEncrypt(new K_PKE_EncryptionKey(encapsulationKey.keyBytes), + randomMessage, randomCoins); + Arrays.fill(randomCoins, (byte) 0); + byte[] sharedSecret = Arrays.copyOfRange(kHatAndRandomCoins, 0, 32); + Arrays.fill(kHatAndRandomCoins, (byte) 0); + + return new ML_KEM_EncapsulateResult(cipherText, sharedSecret); + } + + protected byte[] decapsulate(ML_KEM_DecapsulationKey decapsulationKey, + K_PKE_CipherText cipherText) + throws DecapsulateException { + + //Check ciphertext validity + if (!isValidCipherText(cipherText)) { + throw new DecapsulateException("Invalid ciphertext"); + } + + int encode12PolyLen = 12 * ML_KEM_N / 8; + var decapsKeyBytes = decapsulationKey.keyBytes; + MessageDigest mlKemG; + SHAKE256 mlKemJ; + try { + mlKemG = MessageDigest.getInstance(HASH_G_NAME); + mlKemJ = new SHAKE256(32); + } catch (NoSuchAlgorithmException e) { + throw new RuntimeException(e); + } + + byte[] kPkePrivateKeyBytes = new byte[mlKem_k * encode12PolyLen]; + System.arraycopy(decapsKeyBytes, 0, kPkePrivateKeyBytes, 0, + kPkePrivateKeyBytes.length); + + byte[] encapsKeyBytes = new byte[mlKem_k * encode12PolyLen + 32]; + System.arraycopy(decapsKeyBytes, mlKem_k * encode12PolyLen, + encapsKeyBytes, 0, encapsKeyBytes.length); + var mCandidate = kPkeDecrypt( + new K_PKE_DecryptionKey(kPkePrivateKeyBytes), cipherText); + mlKemG.update(mCandidate); + mlKemG.update(decapsKeyBytes, decapsKeyBytes.length - 64, 32); + var kAndCoins = mlKemG.digest(); + var realResult = Arrays.copyOfRange(kAndCoins, 0, 32); + var coins = Arrays.copyOfRange(kAndCoins, 32, 64); + + // Zero out unused byte arrays containing sensitive data + Arrays.fill(kPkePrivateKeyBytes, (byte) 0); + Arrays.fill(kAndCoins, (byte) 0); + + mlKemJ.update(decapsKeyBytes, decapsKeyBytes.length - 32, 32); + mlKemJ.update(cipherText.encryptedBytes); + var fakeResult = mlKemJ.digest(); + var computedCipherText = kPkeEncrypt( + new K_PKE_EncryptionKey(encapsKeyBytes), mCandidate, coins); + + // The rest of this method implements the following in constant time + // + // if (Arrays.equals(cipherText.encryptedBytes, + // computedCipherText.encryptedBytes)) { + // return realResult; + // } else { + // return fakeResult; + // } + + int mask = 0; + byte[] origCiphertestBytes = cipherText.encryptedBytes; + byte[] compCipherTextBytes = computedCipherText.encryptedBytes; + for (int i = 0; i < cipherText.encryptedBytes.length; i++) { + mask |= (origCiphertestBytes[i] ^ compCipherTextBytes[i]); + } + mask = - (mask & 0xff); // sets mask to negative or 0 + mask >>= 31; // sets mask to all 1-bits or all 0-bits + int notMask = ~mask; + + byte[] result = realResult; + for (int i = 0; i < realResult.length; i ++) { + result[i] = (byte)((notMask & realResult[i]) | (mask & fakeResult[i])); + } + + return result; + } + + /* + K-PKE subroutines defined in Section 5 of spec + */ + private K_PKE_KeyPair generateK_PkeKeyPair(byte[] seed) { + + MessageDigest mlKemG; + SHAKE256 mlKemJ; + try { + mlKemG = MessageDigest.getInstance(HASH_G_NAME); + mlKemJ = new SHAKE256(64 * mlKem_eta1); + } catch (NoSuchAlgorithmException e) { + // This should never happen. + throw new RuntimeException(e); + } + + mlKemG.update(seed); + mlKemG.update((byte)mlKem_k); + + var rhoSigma = mlKemG.digest(); + var rho = Arrays.copyOfRange(rhoSigma, 0, 32); + var sigma = Arrays.copyOfRange(rhoSigma, 32, 64); + Arrays.fill(rhoSigma, (byte)0); + + var keyGenA = generateA(rho, false); + + int keyGenN = 0; + byte[] prfSeed = new byte[sigma.length + 1]; + System.arraycopy(sigma, 0, prfSeed, 0, sigma.length); + byte[] cbdInput; + short[][] keyGenS = new short[mlKem_k][]; + short[][] keyGenE = new short[mlKem_k][]; + for (int i = 0; i < mlKem_k; i++) { + prfSeed[sigma.length] = (byte) (keyGenN++); + mlKemJ.update(prfSeed); + cbdInput = mlKemJ.digest(); + keyGenS[i] = centeredBinomialDistribution(mlKem_eta1, cbdInput); + } + for (int i = 0; i < mlKem_k; i++) { + prfSeed[sigma.length] = (byte) (keyGenN++); + mlKemJ.update(prfSeed); + cbdInput = mlKemJ.digest(); + keyGenE[i] = centeredBinomialDistribution(mlKem_eta1, cbdInput); + } + Arrays.fill(sigma, (byte)0); + + short[][] keyGenSHat = mlKemVectorNTT(keyGenS); + mlKemVectorReduce(keyGenSHat); + short[][] keyGenEHat = mlKemVectorNTT(keyGenE); + + short[][] keyGenTHat = + mlKemMatrixVectorMuladd(keyGenA, keyGenSHat, keyGenEHat); + + byte[] pkEncoded = new byte[(mlKem_k * ML_KEM_N * 12) / 8 + rho.length]; + byte[] skEncoded = new byte[(mlKem_k * ML_KEM_N * 12) / 8]; + for (int i = 0; i < mlKem_k; i++) { + encodePoly12(keyGenTHat[i], pkEncoded, i * ((ML_KEM_N * 12) / 8)); + encodePoly12(keyGenSHat[i], skEncoded, i * ((ML_KEM_N * 12) / 8)); + Arrays.fill(keyGenEHat[i], (short) 0); + Arrays.fill(keyGenSHat[i], (short) 0); + } + System.arraycopy(rho, 0, + pkEncoded, (mlKem_k * ML_KEM_N * 12) / 8, rho.length); + + return new K_PKE_KeyPair( + new K_PKE_EncryptionKey(pkEncoded), + new K_PKE_DecryptionKey(skEncoded)); + } + + private K_PKE_CipherText kPkeEncrypt( + K_PKE_EncryptionKey publicKey, byte[] message, byte[] sigma) { + short[][] zeroes = new short[mlKem_k][ML_KEM_N]; + byte[] pkBytes = publicKey.keyBytes; + byte[] rho = Arrays.copyOfRange(pkBytes, + pkBytes.length - 32, pkBytes.length); + byte[] tHatBytes = Arrays.copyOfRange(pkBytes, + 0, pkBytes.length - 32); + var encryptTHat = decodeVector(12, tHatBytes); + var encryptA = generateA(rho, true); + short[][] encryptR = new short[mlKem_k][]; + short[][] encryptE1 = new short[mlKem_k][]; + int encryptN = 0; + byte[] prfSeed = new byte[sigma.length + 1]; + System.arraycopy(sigma, 0, prfSeed, 0, sigma.length); + + var kPkePRFeta1 = new SHAKE256(64 * mlKem_eta1); + var kPkePRFeta2 = new SHAKE256(64 * mlKem_eta2); + for (int i = 0; i < mlKem_k; i++) { + prfSeed[sigma.length] = (byte) (encryptN++); + kPkePRFeta1.update(prfSeed); + byte[] cbdInput = kPkePRFeta1.digest(); + encryptR[i] = centeredBinomialDistribution(mlKem_eta1, cbdInput); + } + for (int i = 0; i < mlKem_k; i++) { + prfSeed[sigma.length] = (byte) (encryptN++); + kPkePRFeta2.update(prfSeed); + byte[] cbdInput = kPkePRFeta2.digest(); + encryptE1[i] = centeredBinomialDistribution(mlKem_eta2, cbdInput); + } + prfSeed[sigma.length] = (byte) encryptN; + kPkePRFeta2.reset(); + kPkePRFeta2.update(prfSeed); + byte[] cbdInput = kPkePRFeta2.digest(); + var encryptE2 = centeredBinomialDistribution(mlKem_eta2, cbdInput); + + var encryptRHat = mlKemVectorNTT(encryptR); + var encryptUHat = mlKemMatrixVectorMuladd(encryptA, encryptRHat, zeroes); + var encryptU = mlKemVectorInverseNTT(encryptUHat); + encryptU = mlKemAddVec(encryptU, encryptE1); + var encryptVHat = mlKemVectorScalarMult(encryptTHat, encryptRHat); + var encryptV = mlKemInverseNTT(encryptVHat); + encryptV = mlKemAddPoly(encryptV, encryptE2, decompressDecode(message)); + var encryptC1 = encodeVector(mlKem_du, compressVector10_11(encryptU, mlKem_du)); + var encryptC2 = encodePoly(mlKem_dv, compressPoly4_5(encryptV, mlKem_dv)); + + byte[] result = new byte[encryptC1.length + encryptC2.length]; + System.arraycopy(encryptC1, 0, + result, 0, encryptC1.length); + System.arraycopy(encryptC2, 0, + result, encryptC1.length, encryptC2.length); + + return new K_PKE_CipherText(result); + } + + private byte[] kPkeDecrypt(K_PKE_DecryptionKey privateKey, + K_PKE_CipherText cipherText) { + int uBytesLen = mlKem_k * mlKem_du * ML_KEM_N / 8; + byte[] uBytes = Arrays.copyOfRange(cipherText.encryptedBytes, + 0, uBytesLen); + byte[] vBytes = Arrays.copyOfRange(cipherText.encryptedBytes, + uBytesLen, cipherText.encryptedBytes.length); + var decryptU = decompressVector(decodeVector(mlKem_du, uBytes), mlKem_du); + var decryptV = decompressPoly( + decodePoly(mlKem_dv, vBytes, 0), mlKem_dv); + var decryptSHat = decodeVector(12, privateKey.keyBytes); + var decryptSU = mlKemInverseNTT( + mlKemVectorScalarMult(decryptSHat, mlKemVectorNTT(decryptU))); + for (int i = 0; i < mlKem_k; i++) { + Arrays.fill(decryptSHat[i], (short) 0); + } + decryptV = mlKemSubtractPoly(decryptV, decryptSU); + Arrays.fill(decryptSU, (short) 0); + + return encodeCompress(decryptV); + } + + /* + Sampling algorithms from Section 4.2.2 of the spec + */ + + //Combination of SampleNTT and KeyGen/Encrypt generation of A + private short[][][] generateA(byte[] rho, Boolean transposed) { + short[][][] a = new short[mlKem_k][mlKem_k][]; + + int nrPar = 2; + int rhoLen = rho.length; + byte[] seedBuf = new byte[XOF_BLOCK_LEN]; + System.arraycopy(rho, 0, seedBuf, 0, rho.length); + seedBuf[rhoLen + 2] = 0x1F; + seedBuf[XOF_BLOCK_LEN - 1] = (byte)0x80; + byte[][] xofBufArr = new byte[nrPar][XOF_BLOCK_LEN + XOF_PAD]; + int[] iIndex = new int[nrPar]; + int[] jIndex = new int[nrPar]; + + short[] parsedBuf = new short[(xofBufArr[0].length / 3) * 2]; + + int parInd = 0; + boolean allDone; + int[] ofs = new int[nrPar]; + Arrays.fill(ofs, 0); + short[][] aij = new short[nrPar][]; + try { + Shake128Parallel parXof = new Shake128Parallel(xofBufArr); + + for (int i = 0; i < mlKem_k; i++) { + for (int j = 0; j < mlKem_k; j++) { + xofBufArr[parInd] = seedBuf.clone(); + if (transposed) { + xofBufArr[parInd][rhoLen] = (byte) i; + xofBufArr[parInd][rhoLen + 1] = (byte) j; + } else { + xofBufArr[parInd][rhoLen] = (byte) j; + xofBufArr[parInd][rhoLen + 1] = (byte) i; + } + iIndex[parInd] = i; + jIndex[parInd] = j; + ofs[parInd] = 0; + aij[parInd] = new short[ML_KEM_N]; + parInd++; + + if ((parInd == nrPar) || + ((i == mlKem_k - 1) && (j == mlKem_k - 1))) { + parXof.reset(xofBufArr); + + allDone = false; + while (!allDone) { + allDone = true; + parXof.squeezeBlock(); + for (int k = 0; k < parInd; k++) { + int parsedOfs = 0; + int tmp; + if (ofs[k] < ML_KEM_N) { + twelve2Sixteen(xofBufArr[k], 0, + parsedBuf, (XOF_BLOCK_LEN / 3) * 2); + } + while ((ofs[k] < ML_KEM_N) && + (parsedOfs < (XOF_BLOCK_LEN / 3) * 2)) { + tmp = parsedBuf[parsedOfs++] & 0xFFFF; + if (tmp < ML_KEM_Q) { + aij[k][ofs[k]] = (short) tmp; + ofs[k]++; + } + tmp = parsedBuf[parsedOfs++] & 0xFFFF; + if ((ofs[k] < ML_KEM_N) && (tmp < ML_KEM_Q)) { + aij[k][ofs[k]] = (short) tmp; + ofs[k]++; + } + } + if (ofs[k] < ML_KEM_N) { + allDone = false; + } + } + } + + for (int k = 0; k < parInd; k++) { + a[iIndex[k]][jIndex[k]] = aij[k]; + } + parInd = 0; + } + } + } + } catch (InvalidAlgorithmParameterException e) { + // This should never happen since xofBufArr is of the correct size + throw new RuntimeException("Internal error."); + } + + return a; + } + + private short[] centeredBinomialDistribution(int eta, byte[] input) { + if (eta == 2) return centeredBinomialDistribution2(input); + if (eta == 3) return centeredBinomialDistribution3(input); + // Below for arbitrary eta, not used in ML-KEM + short[] result = new short[ML_KEM_N]; + int index = 0; + int shift = 8; + int currentByte = input[0]; + for (int m = 0; m < ML_KEM_N; m++) { + int a = 0; + int b = 0; + for (int j = 0; j < eta; j++) { + if (shift == 8) { + currentByte = input[index++]; + shift = 0; + } + a += (currentByte >> shift) & 1; + shift++; + } + for (int j = 0; j < eta; j++) { + if (shift == 8) { + currentByte = input[index++]; + shift = 0; + } + b += (currentByte >> shift) & 1; + shift++; + } + result[m] = (short) (a - b); + } + return result; + } + + private short[] centeredBinomialDistribution2(byte[] input) { + short[] result = new short[ML_KEM_N]; + // A 64-bit number divided into 16 4-bits, representing all 4-bit + // patterns of input with values are CBD samples in [-2, 2]. + long bits = 0x0112f001f001eff0L; + int j = 0; + + for (int i = 0; i < input.length; i++) { + // One byte has 2 4-bit sequences, each producing a sample + int a = input[i]; + int shift1 = (a << 2) & 0x3c; + int shift2 = (a >> 2) & 0x3c; + result[j++] = (short) ((bits << shift1) >> 60); + result[j++] = (short) ((bits << shift2) >> 60); + } + + return result; + } + + private short[] centeredBinomialDistribution3(byte[] input) { + short[] result = new short[ML_KEM_N]; + // A 32-bit number divided into 8 4-bits, representing all 3-bits + // patterns (one half of a 6-bit input) with values in [0, 3]. + int bits = 0x01121223; + int j = 0; + + for (int i = 0; i < input.length; i += 3) { + // Every 3 bytes has 24 bits that produce 4 6-bit sequences. + // We calculate values for both halves of each sequence and + // do the subtraction to get the sample + int a1 = input[i]; + int a2 = input[i + 1]; + int a3 = input[i + 2]; + int shift1 = (a1 << 2) & 0x1c; + int shift2 = (a1 >> 1) & 0x1c; + int shift3 = ((a1 >> 4) & 0x0c) | ((a2 << 4) & 0x10); + int shift4 = (a2 << 1) & 0x1c; + int shift5 = (a2 >> 2) & 0x1c; + int shift6 = ((a2 >> 5) & 0x04) | ((a3 << 3) & 0x18); + int shift7 = a3 & 0x1c; + int shift8 = (a3 >> 3) & 0x1c; + result[j++] = (short) + (((bits << shift1) >> 28) - ((bits << shift2) >> 28)); + result[j++] = (short) + (((bits << shift3) >> 28) - ((bits << shift4) >> 28)); + result[j++] = (short) + (((bits << shift5) >> 28) - ((bits << shift6) >> 28)); + result[j++] = (short) + (((bits << shift7) >> 28) - ((bits << shift8) >> 28)); + } + + return result; + } + + /* + NTT algorithms from Section 4.3 of the specification + */ + + // Works in place, it returns its (modified) input so that it can be used in + // expressions + private short[][] mlKemVectorNTT(short[][] vector) { + for (int i = 0; i < mlKem_k; i++) { + mlKemNTT(vector[i]); + } + return vector; + } + + // Works in place, it returns its (modified) input so that it can be used in + // expressions + private short[][] mlKemVectorReduce(short[][] vector) { + for (int i = 0; i < mlKem_k; i++) { + mlKemBarrettReduce(vector[i]); + } + return vector; + } + + // Works in place, it returns its (modified) input so that it can be used in + // expressions + private short[][] mlKemVectorInverseNTT(short[][] vector) { + for (int i = 0; i < mlKem_k; i++) { + vector[i] = mlKemInverseNTT(vector[i]); + } + return vector; + } + + static void implMlKemNtt(short[] poly, short[] ntt_zetas) { + implMlKemNttJava(poly); + } + + private static void implMlKemNttJava(short[] poly) { + int[] coeffs = new int[ML_KEM_N]; + for (int m = 0; m < ML_KEM_N; m++) { + coeffs[m] = poly[m]; + } + seilerNTT(coeffs); + for (int m = 0; m < ML_KEM_N; m++) { + poly[m] = (short) coeffs[m]; + } + } + + // The elements of poly should be in the range [-ML_KEM_Q, ML_KEM_Q] + // The elements of poly at return will be in the range of [0, ML_KEM_Q] + private void mlKemNTT(short[] poly) { + implMlKemNtt(poly, MONT_ZETAS_FOR_VECTOR_NTT_ARR); + mlKemBarrettReduce(poly); + } + + static void implMlKemInverseNtt(short[] poly, short[] zetas) { + implMlKemInverseNttJava(poly); + } + + private static void implMlKemInverseNttJava(short[] poly) { + int[] coeffs = new int[ML_KEM_N]; + for (int m = 0; m < ML_KEM_N; m++) { + coeffs[m] = poly[m]; + } + seilerInverseNTT(coeffs); + for (int m = 0; m < ML_KEM_N; m++) { + poly[m] = (short) coeffs[m]; + } + } + + // Works in place, but also returns its (modified) input so that it can + // be used in expressions + private short[] mlKemInverseNTT(short[] poly) { + implMlKemInverseNtt(poly, MONT_ZETAS_FOR_VECTOR_INVERSE_NTT_ARR); + return poly; + } + + // Implements the ML_KEM NTT algorithm similarly to that described + // in https://eprint.iacr.org/2018/039.pdf . + // It works in place, replaces the elements of the input coeffs array + // by the transformed representation. + // The input elements should be in the range [-MONT_Q, MONT_Q]. + // The result elements will fit into the range of short + // (i.e. [-32768, 32767]). + private static void seilerNTT(int[] coeffs) { + int dimension = ML_KEM_N; + int zetaIndex = 0; + for (int l = dimension / 2; l > 1; l /= 2) { + for (int s = 0; s < dimension; s += 2 * l) { + for (int j = s; j < s + l; j++) { + int tmp = montMul(MONT_ZETAS_FOR_NTT[zetaIndex], coeffs[j + l]); + coeffs[j + l] = coeffs[j] - tmp; + coeffs[j] = coeffs[j] + tmp; + } + zetaIndex++; + } + } + } + + // Implements the ML_KEM inverse NTT algorithm similarly to that described + // in https://eprint.iacr.org/2018/039.pdf . + // It works in place, replaces the elements of the input coeffs array + // by the transformed representation. + // The input elements should be in the range [-MONT_Q, MONT_Q). + // The output elements will be in the range (-MONT_Q, MONT_Q). + private static void seilerInverseNTT(int[] coeffs) { + int dimension = ML_KEM_N; + int zetaIndex = MONT_ZETAS_FOR_NTT.length - 1; + for (int l = 2; l < dimension; l *= 2) { + for (int s = 0; s < dimension; s += 2 * l) { + for (int j = s; j < s + l; j++) { + int tmp = coeffs[j]; + coeffs[j] = (tmp + coeffs[j + l]); + coeffs[j + l] = montMul( + tmp - coeffs[j + l], + -MONT_ZETAS_FOR_NTT[zetaIndex]); + } + zetaIndex--; + } + } + + for (int i = 0; i < dimension; i++) { + int r = montMul(coeffs[i], MONT_DIM_HALF_INVERSE); + coeffs[i] = r; + } + } + + // Performs A o b + c where + // A is a mlKem_k by mlKem_k matrix, + // b and c are mlKem_k long vectors of degree ML_KEM_N - 1 + // polynomials in the NTT domain representation. + // The coefficients in the result are in the range [0, ML_KEM_Q). + private short[][] mlKemMatrixVectorMuladd( + short[][][] a, short[][] b, short[][] c) { + short[] product = new short[ML_KEM_N]; + + for (int i = 0; i < mlKem_k; i++) { + for (int j = 0; j < mlKem_k; j++) { + nttMult(product, a[i][j], b[j]); + mlKemAddPoly(c[i], product); + } + mlKemBarrettReduce(c[i]); + } + return c; + } + + // Performs a^T o b where a and b are mlKem_k long vectors + // of degree ML_KEM_N - 1 polynomials in the NTT representation, + // with coefficients in the range [-ML_KEM_Q, ML_KEM_Q]. + // The coefficients in the result are in the range [0, ML_KEM_Q). + private short[] mlKemVectorScalarMult(short[][] a, short[][] b) { + short[] result = new short[ML_KEM_N]; + short[] product = new short[ML_KEM_N]; + + int j; + for (j = 0; j < mlKem_k; j++) { + nttMult(product, a[j], b[j]); + mlKemAddPoly(result, product); + } + mlKemBarrettReduce(result); + + return result; + } + + static void implMlKemNttMult(short[] result, short[] ntta, short[] nttb, + short[] zetas) { + implMlKemNttMultJava(result, ntta, nttb); + } + + private static void implMlKemNttMultJava(short[] result, + short[] ntta, short[] nttb) { + + for (int m = 0; m < ML_KEM_N / 2; m++) { + int a0 = ntta[2 * m]; + int a1 = ntta[2 * m + 1]; + int b0 = nttb[2 * m]; + int b1 = nttb[2 * m + 1]; + int r = montMul(a0, b0) + + montMul(montMul(a1, b1), MONT_ZETAS_FOR_NTT_MULT[m]); + result[2 * m] = (short) montMul(r, MONT_R_SQUARE_MOD_Q); + result[2 * m + 1] = (short) montMul( + (montMul(a0, b1) + montMul(a1, b0)), MONT_R_SQUARE_MOD_Q); + } + } + + // Multiplies two polynomials represented in the NTT domain. + // The result is a representation of the product still in the NTT domain. + // The coefficients in the result are in the range (-ML_KEM_Q, ML_KEM_Q). + private void nttMult(short[] result, short[] ntta, short[] nttb) { + implMlKemNttMult(result, ntta, nttb, MONT_ZETAS_FOR_VECTOR_NTT_MULT_ARR); + } + + // Adds the vector of polynomials b to a in place, i.e. a will hold + // the result. It also returns (the modified) a so that it can be used + // in an expression. + // The coefficients in all polynomials of both vectors are supposed to be + // greater than -ML_KEM_Q and less than ML_KEM_Q. + // The coefficients in the result are nonnegative and less than ML_KEM_Q. + private short[][] mlKemAddVec(short[][] a, short[][] b) { + for (int i = 0; i < mlKem_k; i++) { + mlKemAddPoly(a[i], b[i]); + mlKemBarrettReduce(a[i]); + } + return a; + } + + static void implMlKemAddPoly(short[] result, short[] a, short[] b) { + implMlKemAddPolyJava(result, a, b); + } + + private static void implMlKemAddPolyJava(short[] result, short[] a, short[] b) { + for (int m = 0; m < ML_KEM_N; m++) { + int r = a[m] + b[m] + ML_KEM_Q; // This makes r > -ML_KEM_Q + result[m] = (short) r; + } + } + + // Adds the polynomial b to a in place, i.e. (the modified) a will hold + // the result. + // The coefficients are supposed be greater than -ML_KEM_Q in a and + // greater than -ML_KEM_Q and less than ML_KEM_Q in b. + // The coefficients in the result are greater than -ML_KEM_Q. + private void mlKemAddPoly(short[] a, short[] b) { + implMlKemAddPoly(a, a, b); + } + + static void implMlKemAddPoly(short[] result, short[] a, short[] b, short[] c) { + implMlKemAddPolyJava(result, a, b, c); + } + + private static void implMlKemAddPolyJava(short[] result, short[] a, + short[] b, short[] c) { + + for (int m = 0; m < ML_KEM_N; m++) { + int r = a[m] + b[m] + c[m] + 2 * ML_KEM_Q; // This makes r > - ML_KEM_Q + result[m] = (short) r; + } + } + + // Adds the polynomials b and c to a in place, i.e. 'a' will hold the sum. + // 'a' is also returned so that this function can be used in an expression. + // The coefficients in all three polynomials are supposed to be + // greater than -ML_KEM_Q and less than ML_KEM_Q. + // The coefficients in the result are nonnegative and less than ML_KEM_Q. + private short[] mlKemAddPoly(short[] a, short[] b, short[] c) { + implMlKemAddPoly(a, a, b, c); + mlKemBarrettReduce(a); + return a; + } + + // Subtracts the polynomial b from a in place, i.e. the result is + // stored in a. It also returns (the modified) a, so that it can be used + // in an expression. + // The coefficiens in both are assumed to be greater than -ML_KEM_Q + // and less than ML_KEM_Q. + // The coefficients in the result are nonnegative and less than ML_KEM_Q. + private short[] mlKemSubtractPoly(short[] a, short[] b) { + for (int m = 0; m < ML_KEM_N; m++) { + int r = a[m] - b[m] + ML_KEM_Q; // This makes r > -ML_KEM_Q + a[m] = (short) r; + } + mlKemBarrettReduce(a); + return a; + } + + private byte[] encodeVector(int l, short[][] vector) { + return encodeVector(l, vector, mlKem_k); + } + + private static byte[] encodeVector(int l, short[][] vector, int k) { + int encodedPolyLength = ML_KEM_N * l / 8; + byte[] result = new byte[k * encodedPolyLength]; + + for (int i = 0; i < k; i++) { + byte[] resultBytes = encodePoly(l, vector[i]); + System.arraycopy(resultBytes, 0, + result, i * encodedPolyLength, encodedPolyLength); + } + return result; + } + + private static void encodePoly12(short[] poly, byte[] result, int resultOffs) { + int low; + int high; + for (int m = 0; m < ML_KEM_N / 2; m++) { + low = poly[2 * m]; + low += ((low >> 31) & ML_KEM_Q); + low = low & 0xfff; + high = poly[2 * m + 1]; + high += ((high >> 31) & ML_KEM_Q); + high = high & 0xfff; + + result[resultOffs++] = (byte) low; + result[resultOffs++] = (byte) ((high << 4) + (low >> 8)); + result[resultOffs++] = (byte) (high >> 4); + } + } + + private static void encodePoly4(short[] poly, byte[] result) { + for (int m = 0; m < ML_KEM_N / 2; m++) { + result[m] = (byte) ((poly[2 * m] & 0xf) + (poly[2 * m + 1] << 4)); + } + } + + // Computes the byte array containing the packed l-bit representation + // of a polynomial. The coefficients in poly should be either nonnegative + // or elements of Z_(ML_KEM_Q) represented by a 16-bit value + // between -ML_KEM_Q and ML_KEM_Q. + private static byte[] encodePoly(int l, short[] poly) { + byte[] result = new byte[ML_KEM_N / 8 * l]; + if (l == 4) { + encodePoly4(poly, result); + } else { + int mask = (1 << l) - 1; + int shift = 0; + int index = 0; + int current = 0; + for (int m = 0; m < ML_KEM_N; m++) { + int currentShort = poly[m]; + currentShort += (currentShort >> 31) & ML_KEM_Q; + current += ((currentShort & mask) << shift); + shift += l; + while (shift >= 8) { + result[index++] = (byte) current; + current >>>= 8; + shift -= 8; + } + } + } + + return result; + } + + private static byte[] encodeCompress(short[] poly) { + byte[] result = new byte[ML_KEM_N / 8]; + int xx; + int currentByte; + for (int i = 0; i < ML_KEM_N / 8; i++) { + currentByte = 0; + xx = poly[i * 8]; + currentByte |= (((832 - xx) & (xx - 2497)) >>> 31); + xx = poly[i * 8 + 1]; + currentByte |= ((((832 - xx) & (xx - 2497)) >>> 30) & 2); + xx = poly[i * 8 + 2]; + currentByte |= ((((832 - xx) & (xx - 2497)) >>> 29) & 4); + xx = poly[i * 8 + 3]; + currentByte |= ((((832 - xx) & (xx - 2497)) >>> 28) & 8); + xx = poly[i * 8 + 4]; + currentByte |= ((((832 - xx) & (xx - 2497)) >>> 27) & 16); + xx = poly[i * 8 + 5]; + currentByte |= ((((832 - xx) & (xx - 2497)) >>> 26) & 32); + xx = poly[i * 8 + 6]; + currentByte |= ((((832 - xx) & (xx - 2497)) >>> 25) & 64); + xx = poly[i * 8 + 7]; + currentByte |= ((((832 - xx) & (xx - 2497)) >>> 24) & 128); + result[i] = (byte) currentByte; + } + return result; + } + + private short[][] decodeVector(int l, byte[] encodedVector) { + short[][] result = new short[mlKem_k][]; + for (int i = 0; i < mlKem_k; i++) { + result[i] = decodePoly(l, encodedVector, (i * ML_KEM_N * l) / 8); + } + return result; + } + + private static void implMlKem12To16(byte[] condensed, int index, + short[] parsed, int parsedLength) { + + implMlKem12To16Java(condensed, index, parsed, parsedLength); + } + + private static void implMlKem12To16Java(byte[] condensed, int index, + short[] parsed, int parsedLength) { + + for (int i = 0; i < parsedLength * 3 / 2; i += 3) { + parsed[(i / 3) * 2] = (short) ((condensed[i + index] & 0xff) + + 256 * (condensed[i + index + 1] & 0xf)); + parsed[(i / 3) * 2 + 1] = (short) (((condensed[i + index + 1] >>> 4) & 0xf) + + 16 * (condensed[i + index + 2] & 0xff)); + } + } + + // The intrinsic implementations assume that the input and output buffers + // are such that condensed can be read in 192-byte chunks and + // parsed can be written in 128 shorts chunks. In other words, + // if (i - 1) * 128 < parsedLengths <= i * 128 then + // parsed.size should be at least i * 128 and + // condensed.size should be at least index + i * 192 + private void twelve2Sixteen(byte[] condensed, int index, + short[] parsed, int parsedLength) { + + implMlKem12To16(condensed, index, parsed, parsedLength); + } + + private static void decodePoly5(byte[] condensed, int index, short[] parsed) { + int j = index; + for (int i = 0; i < ML_KEM_N; i += 8) { + parsed[i] = (short) (condensed[j] & 0x1f); + parsed[i + 1] = (short) ((((condensed[j] & 0xff) >>> 5) + + (condensed[j + 1] << 3) & 0x1f)); + parsed[i + 2] = (short) ((condensed[j + 1] & 0x7f) >>> 2); + parsed[i + 3] = (short) ((((condensed[j + 1] & 0xff) >>> 7) + + (condensed[j + 2] << 1)) & 0x1f); + parsed[i + 4] = (short) ((((condensed[j + 2] & 0xff) >>> 4) + + (condensed[j + 3] << 4)) & 0x1f); + parsed[i + 5] = (short) ((condensed[j + 3] & 0x3f) >>> 1); + parsed[i + 6] = (short) ((((condensed[j + 3] & 0xff) >>> 6) + + (condensed[j + 4] << 2)) & 0x1f); + parsed[i + 7] = (short) ((condensed[j + 4] & 0xff) >>> 3); + j += 5; + } + } + + private static void decodePoly4(byte[] condensed, int index, short[] parsed) { + for (int i = 0; i < ML_KEM_N / 2; i++) { + parsed[i * 2] = (short) (condensed[i + index] & 0xf); + parsed[i * 2 + 1] = (short) ((condensed[i + index] >>> 4) & 0xf); + } + } + + // Recovers the 16-bit coefficients of a polynomial from a byte array + // containing a packed l-bit representation. + // The recovered coefficients will be in the range 0 <= coeff < 2^l . + private short[] decodePoly(int l, byte[] input, int index) { + short[] poly = new short[ML_KEM_N]; + if (l == 12) { + twelve2Sixteen(input, index, poly, ML_KEM_N); + } else if (l == 4) { + decodePoly4(input, index, poly); + } else if (l == 5) { + decodePoly5(input, index, poly); + } else { + int mask = (1 << l) - 1; + int top = 0; + int shift = 0; + int acc = 0; + for (int m = 0; m < ML_KEM_N; m++) { + while (top - shift < l) { + acc += ((input[index++] & 0xff) << top); + top += 8; + } + poly[m] = (short) ((acc >> shift) & mask); + shift += l; + while (shift >= 8) { + top -= 8; + shift -= 8; + acc >>>= 8; + } + } + } + + return poly; + } + + // Prerequisite: d == 10 or d == 11 + // Compresses a vector in place, i.e. it modifies the coefficients of the + // polynomials of its input vector. It returns its (modified) input so that + // the function can be used in an expression. + private short[][] compressVector10_11(short[][] vector, int d) { + for (int i = 0; i < mlKem_k; i++) { + vector[i] = compressPoly10_11(vector[i], d); + } + return vector; + } + + // Prerequisite: for all m, 0 <= poly[m] < ML_KEM_Q, d == 4 or d == 5 + // Replaces poly[m] with round(2^d * poly[m] / ML_KEM_Q) mod 2^d for all m, + // where round(z) is the integer closest to z, i.e. + // compresses a polynomial in place. + private static short[] compressPoly4_5(short[] poly, int d) { + int xx; + for (int m = 0; m < ML_KEM_N; m++) { + xx = (poly[m] << d) + ML_KEM_Q / 2; + poly[m] = (short)((xx * 315) >> 20); + } + return poly; + } + + // Prerequisite: for all m, 0 <= poly[m] < ML_KEM_Q, d == 10 or d == 11 + // Replaces poly[m] with round(2^d * poly[m] / ML_KEM_Q) mod 2^d for all m, + // where round(z) is the integer closest to z, i.e. + // compresses a polynomial in place. + private static short[] compressPoly10_11(short[] poly, int d) { + long xx; + for (int m = 0; m < ML_KEM_N; m++) { + xx = (poly[m] << d) + ML_KEM_Q / 2; + poly[m] = (short)((xx * 161271L) >> 29); + } + return poly; + } + + // Decompresses a vector in place, i.e. it modifies the coefficients of the + // polynomials of its input vector. It returns its (modified) input so that + // the function can be used in an expression. + private short[][] decompressVector(short[][] vector, int d) { + for (int i = 0; i < mlKem_k; i++) { + vector[i] = decompressPoly(vector[i], d); + } + return vector; + } + + // Decompresses a polynomial in place, i.e. it modifies the coefficients + // in its input. It returns its (modified) input so that the function can + // be used in an expression. + // Prerequisite: 0 <= x[i] < 2^d < ML_KEM_Q . + // Computes Round(ML_KEM_Q * x[i] / 2^d), + // where Round(z) is the integer closest to z, + // for each coefficient of a polynomial + private static short[] decompressPoly(short[] poly, int d) { + for (int m = 0; m < ML_KEM_N; m++) { + int qx = ML_KEM_Q * poly[m]; + poly[m] = (short) ((qx >> d) + ((qx >> (d - 1)) & 1)); + } + return poly; + } + + private static short[] decompressDecode(byte[] input) { + short[] result = new short[256]; + for (int i = 0; i < 32; i++) { + int currentByte = input[i] & 0xFF; + result [i * 8] = (short)(((currentByte << 31 ) >> 31) & 1665); + result [i * 8 + 1] = (short)(((currentByte << 30 ) >> 31) & 1665); + result [i * 8 + 2] = (short)(((currentByte << 29 ) >> 31) & 1665); + result [i * 8 + 3] = (short)(((currentByte << 28 ) >> 31) & 1665); + result [i * 8 + 4] = (short)(((currentByte << 27 ) >> 31) & 1665); + result [i * 8 + 5] = (short)(((currentByte << 26 ) >> 31) & 1665); + result [i * 8 + 6] = (short)(((currentByte << 25 ) >> 31) & 1665); + result [i * 8 + 7] = (short)(((currentByte << 24 ) >> 31) & 1665); + } + return result; + } + + static void implMlKemBarrettReduce(short[] coeffs) { + implMlKemBarrettReduceJava(coeffs); + } + + private static void implMlKemBarrettReduceJava(short[] coeffs) { + for (int m = 0; m < ML_KEM_N; m++) { + int tmp = ((int) coeffs[m] * BARRETT_MULTIPLIER) >> + BARRETT_SHIFT; + coeffs[m] = (short) (coeffs[m] - tmp * ML_KEM_Q); + } + } + + // The input elements can have any short value. + // Modifies poly such that upon return poly[i] will be + // in the range [0, ML_KEM_Q] and will be congruent with the original + // poly[i] modulo ML_KEM_Q, for all i in [0, ML_KEM_N). + // At return, poly[i] == ML_KEM_Q if and only if the original poly[i] was + // a negative integer multiple of ML_KEM_Q. + // That means that if the original poly[i] > -ML_KEM_Q then at return it + // will be in the range [0, ML_KEM_Q), i.e. it will be the canonical + // representative of its residue class. + private void mlKemBarrettReduce(short[] poly) { + implMlKemBarrettReduce(poly); + } + + // Precondition: -(2^MONT_R_BITS -1) * MONT_Q <= b * c < (2^MONT_R_BITS - 1) * MONT_Q + // Computes b * c * 2^-MONT_R_BITS mod MONT_Q + // The result is between -MONT_Q and MONT_Q + private static int montMul(int b, int c) { + int a = b * c; + int aHigh = a >> MONT_R_BITS; + int aLow = a & ((1 << MONT_R_BITS) - 1); + int m = ((MONT_Q_INV_MOD_R * aLow) << (32 - MONT_R_BITS)) >> + (32 - MONT_R_BITS); // signed low product + + return (aHigh - ((m * MONT_Q) >> MONT_R_BITS)); // subtract signed high product + } +} diff --git a/src/java.base/share/classes/com/sun/crypto/provider/ML_KEM_Impls.java b/src/java.base/share/classes/com/sun/crypto/provider/ML_KEM_Impls.java new file mode 100644 index 00000000000..f59883a410e --- /dev/null +++ b/src/java.base/share/classes/com/sun/crypto/provider/ML_KEM_Impls.java @@ -0,0 +1,233 @@ +/* + * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package com.sun.crypto.provider; + +import sun.security.jca.JCAUtil; +import sun.security.provider.NamedKEM; +import sun.security.provider.NamedKeyFactory; +import sun.security.provider.NamedKeyPairGenerator; + +import java.security.*; +import java.util.Arrays; + +import javax.crypto.DecapsulateException; + +public final class ML_KEM_Impls { + + static int name2int(String name) { + if (name.endsWith("512")) { + return 512; + } else if (name.endsWith("768")) { + return 768; + } else if (name.endsWith("1024")) { + return 1024; + } else { + // should not happen + throw new ProviderException("Unknown name " + name); + } + } + + public sealed static class KPG + extends NamedKeyPairGenerator permits KPG2, KPG3, KPG5 { + + public KPG() { + // ML-KEM-768 is the default + super("ML-KEM", "ML-KEM-768", "ML-KEM-512", "ML-KEM-1024"); + } + + protected KPG(String pname) { + super("ML-KEM", pname); + } + + @Override + protected byte[][] implGenerateKeyPair(String name, SecureRandom random) { + byte[] seed = new byte[32]; + var r = random != null ? random : JCAUtil.getDefSecureRandom(); + r.nextBytes(seed); + byte[] z = new byte[32]; + r.nextBytes(z); + + ML_KEM mlKem = new ML_KEM(name); + ML_KEM.ML_KEM_KeyPair kp; + try { + kp = mlKem.generateKemKeyPair(seed, z); + } finally { + Arrays.fill(seed, (byte)0); + Arrays.fill(z, (byte)0); + } + return new byte[][] { + kp.encapsulationKey().keyBytes(), + kp.decapsulationKey().keyBytes() + }; + } + } + + public final static class KPG2 extends KPG { + public KPG2() { + super("ML-KEM-512"); + } + } + + public final static class KPG3 extends KPG { + public KPG3() { + super("ML-KEM-768"); + } + } + + public final static class KPG5 extends KPG { + public KPG5() { + super("ML-KEM-1024"); + } + } + + public sealed static class KF extends NamedKeyFactory permits KF2, KF3, KF5 { + public KF() { + super("ML-KEM", "ML-KEM-512", "ML-KEM-768", "ML-KEM-1024"); + } + public KF(String name) { + super("ML-KEM", name); + } + } + + public final static class KF2 extends KF { + public KF2() { + super("ML-KEM-512"); + } + } + + public final static class KF3 extends KF { + public KF3() { + super("ML-KEM-768"); + } + } + + public final static class KF5 extends KF { + public KF5() { + super("ML-KEM-1024"); + } + } + + public sealed static class K extends NamedKEM permits K2, K3, K5 { + private static final int SEED_SIZE = 32; + + @Override + protected byte[][] implEncapsulate(String name, byte[] encapsulationKey, + Object ek, SecureRandom secureRandom) { + + byte[] randomBytes = new byte[SEED_SIZE]; + var r = secureRandom != null ? secureRandom : JCAUtil.getDefSecureRandom(); + r.nextBytes(randomBytes); + + ML_KEM mlKem = new ML_KEM(name); + ML_KEM.ML_KEM_EncapsulateResult mlKemEncapsulateResult = null; + try { + mlKemEncapsulateResult = mlKem.encapsulate( + new ML_KEM.ML_KEM_EncapsulationKey( + encapsulationKey), randomBytes); + } finally { + Arrays.fill(randomBytes, (byte) 0); + } + + return new byte[][] { + mlKemEncapsulateResult.cipherText().encryptedBytes(), + mlKemEncapsulateResult.sharedSecret() + }; + } + + @Override + protected byte[] implDecapsulate(String name, byte[] decapsulationKey, + Object dk, byte[] cipherText) + throws DecapsulateException { + + ML_KEM mlKem = new ML_KEM(name); + var kpkeCipherText = new ML_KEM.K_PKE_CipherText(cipherText); + + byte[] decapsulateResult; + try { + decapsulateResult = mlKem.decapsulate( + new ML_KEM.ML_KEM_DecapsulationKey( + decapsulationKey), kpkeCipherText); + } catch (DecapsulateException e) { + throw new DecapsulateException("Decapsulate error", e) ; + } + + return decapsulateResult; + } + + @Override + protected int implSecretSize(String name) { + return ML_KEM.SECRET_SIZE; + } + + @Override + protected int implEncapsulationSize(String name) { + ML_KEM mlKem = new ML_KEM(name); + return mlKem.getEncapsulationSize(); + } + + @Override + protected Object implCheckPublicKey(String name, byte[] pk) + throws InvalidKeyException { + + ML_KEM mlKem = new ML_KEM(name); + return mlKem.checkPublicKey(pk); + } + + @Override + protected Object implCheckPrivateKey(String name, byte[] sk) + throws InvalidKeyException { + + ML_KEM mlKem = new ML_KEM(name); + return mlKem.checkPrivateKey(sk); + } + + public K() { + super("ML-KEM", "ML-KEM-512", "ML-KEM-768", "ML-KEM-1024"); + } + + public K(String name) { + super("ML-KEM", name); + } + } + + public final static class K2 extends K { + public K2() { + super("ML-KEM-512"); + } + } + + public final static class K3 extends K { + public K3() { + super("ML-KEM-768"); + } + } + + public final static class K5 extends K { + public K5() { + super("ML-KEM-1024"); + } + } +} diff --git a/src/java.base/share/classes/com/sun/crypto/provider/SunJCE.java b/src/java.base/share/classes/com/sun/crypto/provider/SunJCE.java index 6e3efe8c285..4185980ce2e 100644 --- a/src/java.base/share/classes/com/sun/crypto/provider/SunJCE.java +++ b/src/java.base/share/classes/com/sun/crypto/provider/SunJCE.java @@ -76,6 +76,8 @@ * * - DHKEM * + * - ML-KEM + * */ public final class SunJCE extends Provider { @@ -85,7 +87,7 @@ public final class SunJCE extends Provider { private static final String info = "SunJCE Provider " + "(implements RSA, DES, Triple DES, AES, Blowfish, ARCFOUR, RC2, PBE, " - + "Diffie-Hellman, HMAC, ChaCha20)"; + + "Diffie-Hellman, HMAC, ChaCha20, DHKEM, and ML-KEM)"; /* Are we debugging? -- for developers */ static final boolean debug = false; @@ -752,6 +754,23 @@ void putEntries() { "|java.security.interfaces.XECKey"); ps("KEM", "DHKEM", "com.sun.crypto.provider.DHKEM", null, attrs); + attrs.clear(); + attrs.put("ImplementedIn", "Software"); + ps("KEM", "ML-KEM", "com.sun.crypto.provider.ML_KEM_Impls$K", null, attrs); + psA("KEM", "ML-KEM-512", "com.sun.crypto.provider.ML_KEM_Impls$K2", attrs); + psA("KEM", "ML-KEM-768", "com.sun.crypto.provider.ML_KEM_Impls$K3", attrs); + psA("KEM", "ML-KEM-1024", "com.sun.crypto.provider.ML_KEM_Impls$K5",attrs); + + ps("KeyPairGenerator", "ML-KEM", "com.sun.crypto.provider.ML_KEM_Impls$KPG", null, attrs); + psA("KeyPairGenerator", "ML-KEM-512", "com.sun.crypto.provider.ML_KEM_Impls$KPG2", attrs); + psA("KeyPairGenerator", "ML-KEM-768", "com.sun.crypto.provider.ML_KEM_Impls$KPG3", attrs); + psA("KeyPairGenerator", "ML-KEM-1024", "com.sun.crypto.provider.ML_KEM_Impls$KPG5", attrs); + + ps("KeyFactory", "ML-KEM", "com.sun.crypto.provider.ML_KEM_Impls$KF", null, attrs); + psA("KeyFactory", "ML-KEM-512", "com.sun.crypto.provider.ML_KEM_Impls$KF2", attrs); + psA("KeyFactory", "ML-KEM-768", "com.sun.crypto.provider.ML_KEM_Impls$KF3", attrs); + psA("KeyFactory", "ML-KEM-1024", "com.sun.crypto.provider.ML_KEM_Impls$KF5", attrs); + /* * SSL/TLS mechanisms * diff --git a/src/java.base/share/classes/java/security/spec/NamedParameterSpec.java b/src/java.base/share/classes/java/security/spec/NamedParameterSpec.java index 296d353449b..1e36fe3befe 100644 --- a/src/java.base/share/classes/java/security/spec/NamedParameterSpec.java +++ b/src/java.base/share/classes/java/security/spec/NamedParameterSpec.java @@ -68,6 +68,30 @@ public class NamedParameterSpec implements AlgorithmParameterSpec { public static final NamedParameterSpec ED448 = new NamedParameterSpec("Ed448"); + /** + * The ML-KEM-512 parameters + * + * @since 24 + */ + public static final NamedParameterSpec ML_KEM_512 + = new NamedParameterSpec("ML-KEM-512"); + + /** + * The ML-KEM-768 parameters + * + * @since 24 + */ + public static final NamedParameterSpec ML_KEM_768 + = new NamedParameterSpec("ML-KEM-768"); + + /** + * The ML-KEM-1024 parameters + * + * @since 24 + */ + public static final NamedParameterSpec ML_KEM_1024 + = new NamedParameterSpec("ML-KEM-1024"); + private final String name; /** diff --git a/src/java.base/share/classes/sun/security/provider/SHA3Parallel.java b/src/java.base/share/classes/sun/security/provider/SHA3Parallel.java new file mode 100644 index 00000000000..d9abfbe413f --- /dev/null +++ b/src/java.base/share/classes/sun/security/provider/SHA3Parallel.java @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package sun.security.provider; + +import jdk.internal.vm.annotation.IntrinsicCandidate; + +import java.security.InvalidAlgorithmParameterException; +import java.util.Arrays; + +import static sun.security.provider.ByteArrayAccess.b2lLittle; +import static sun.security.provider.ByteArrayAccess.l2bLittle; + +import static sun.security.provider.SHA3.keccak; + +public class SHA3Parallel { + private int blockSize = 0; + private static final int DM = 5; // dimension of lanesArr + private byte[][] buffers; + private long[][] lanesArr; + private static final int NRPAR = 2; + + private SHA3Parallel(byte[][] buffers, int blockSize) throws InvalidAlgorithmParameterException { + if ((buffers.length != NRPAR) || (buffers[0].length < blockSize)) { + throw new InvalidAlgorithmParameterException("Bad buffersize."); + } + this.buffers = buffers; + this.blockSize = blockSize; + lanesArr = new long[NRPAR][]; + for (int i = 0; i < NRPAR; i++) { + lanesArr[i] = new long[DM * DM]; + b2lLittle(buffers[i], 0, lanesArr[i], 0, blockSize); + } + } + + public void reset(byte[][] buffers) throws InvalidAlgorithmParameterException { + if ((buffers.length != NRPAR) || (buffers[0].length < blockSize)) { + throw new InvalidAlgorithmParameterException("Bad buffersize."); + } + this.buffers = buffers; + for (int i = 0; i < NRPAR; i++) { + Arrays.fill(lanesArr[i], 0L); + b2lLittle(buffers[i], 0, lanesArr[i], 0, blockSize); + } + } + + public int squeezeBlock() { + int retVal = doubleKeccak(lanesArr[0], lanesArr[1]); + for (int i = 0; i < NRPAR; i++) { + l2bLittle(lanesArr[i], 0, buffers[i], 0, blockSize); + } + return retVal; + } + + @IntrinsicCandidate + private static int doubleKeccak(long[] lanes0, long[] lanes1) { + doubleKeccakJava(lanes0, lanes1); + return 1; + } + + private static int doubleKeccakJava(long[] lanes0, long[] lanes1) { + keccak(lanes0); + keccak(lanes1); + return 1; + } + + public static final class Shake128Parallel extends SHA3Parallel { + public Shake128Parallel(byte[][] buf) throws InvalidAlgorithmParameterException { + super(buf, 168); + } + } +} diff --git a/src/java.base/share/classes/sun/security/util/KnownOIDs.java b/src/java.base/share/classes/sun/security/util/KnownOIDs.java index 8cd0a03a365..19e482b63c2 100644 --- a/src/java.base/share/classes/sun/security/util/KnownOIDs.java +++ b/src/java.base/share/classes/sun/security/util/KnownOIDs.java @@ -179,6 +179,11 @@ public enum KnownOIDs { SHA3_384withRSA("2.16.840.1.101.3.4.3.15", "SHA3-384withRSA"), SHA3_512withRSA("2.16.840.1.101.3.4.3.16", "SHA3-512withRSA"), + // kems 2.16.840.1.101.3.4.4.* + ML_KEM_512("2.16.840.1.101.3.4.4.1", "ML-KEM-512"), + ML_KEM_768("2.16.840.1.101.3.4.4.2", "ML-KEM-768"), + ML_KEM_1024("2.16.840.1.101.3.4.4.3", "ML-KEM-1024"), + // RSASecurity // PKCS1 1.2.840.113549.1.1.* PKCS1("1.2.840.113549.1.1", "RSA") { // RSA KeyPairGenerator and KeyFactory diff --git a/test/jdk/sun/security/provider/acvp/data/ML-KEM-encapDecap-FIPS203/internalProjection.json b/test/jdk/sun/security/provider/acvp/data/ML-KEM-encapDecap-FIPS203/internalProjection.json new file mode 100644 index 00000000000..7b93e278298 --- /dev/null +++ b/test/jdk/sun/security/provider/acvp/data/ML-KEM-encapDecap-FIPS203/internalProjection.json @@ -0,0 +1,1023 @@ +{ + "vsId": 42, + "algorithm": "ML-KEM", + "mode": "encapDecap", + "revision": "FIPS203", + "isSample": true, + "testGroups": [ + { + "tgId": 1, + "testType": "AFT", + "parameterSet": "ML-KEM-512", + "function": "encapsulation", + "tests": [ + { + "tcId": 1, + "deferred": false, + "ek": "DD1924935AA8E617AF18B5A065AC45727767EE897CF4F9442B2ACE30C0237B307D3E76BF8EEB78ADDC4AACD16463D8602FD5487B63C88BB66027F37D0D614D6F9C24603C42947664AC4398C6C52383469B4F9777E5EC7206210F3E5A796BF45C53268E25F39AC261AF3BFA2EE755BEB8B67AB3AC8DF6C629C1176E9E3B965E9369F9B3B92AD7C20955641D99526FE7B9FE8C850820275CD964849250090733CE124ECF316624374BD18B7C358C06E9C136EE1259A9245ABC55B964D689F5A08292D28265658EBB40CBFE488A2228275590AB9F32A34109709C1C291D4A23337274C7A5A5991C7A87B81C974AB18CE77859E4995E7C14F0371748B7712FB52C5966CD63063C4F3B81B47C45DDE83FB3A2724029B10B3230214C04FA0577FC29AC9086AE18C53B3ED44E507412FCA04B4F538A51588EC1F1029D152D9AE7735F76A077AA9484380AED9189E5912487FCC5B7C7012D9223DD967EECDAC3008A8931B648243537F548C171698C5B381D846A72E5C92D4226C5A8909884F1C4A3404C1720A5279414D7F27B2B982652B6740219C56D217780D7A5E5BA59836349F726881DEA18EF75C0772A8B922766953718CACC14CCBACB5FC412A2D0BE521817645AB2BF6A4785E92BC94CAF477A967876796C0A5190315AC0885671A4C749564C3B2C7AED9064EBA299EF214BA2F40493667C8BD032AEC5621711B41A3852C5C2BAB4A349CE4B7F085A812BBBC820B81BEFE63A05B8BCDFE9C2A70A8B1ACA9BF9816481907FF4432461111287303F0BD817C05726BFA18A2E24C7724921028032F622BD960A317D83B356B57F4A8004499CBC73C97D1EB7745972631C0561C1A3AB6EF91BD363280A10545DA693E6D58AED6845E7CC5F0D08CA7905052C77366D1972CCFCC1A27610CB543665AA798E20940128B9567A7EDB7A900407C70D359438435E13961608D552A94C5CDA7859220509B483C5C52A210E9C812BC0C2328CA00E789A56B2606B90292E3543DACAA2431841D61A22CA90C1CCF0B5B4E0A6F640536D1A26AB5B8D2151327928CE02904CF1D15E32788A95F62D3C270B6FA1508F97B9155A2726D80A1AFA3C5387A276A4D031A08ABF4F2E74F1A0BB8A0FD3CB", + "dk": "A5E26E1B2360203944ACFC2D7C376780E55B5A5CA38674919437C794F54B8217BB0629C84C692EF7827EED864D0C508990CA4553F16F4720CB75368C1B8CA9DBC175F51BBEBAA456F36611A2364775D248C0F4C40B342608F7370A983CF75C915570248E367375B665D9357CE4A8553E659BE4A60CA68B58724689C23B74D34C9E78E168E7CB0DF84641E41B6E6807BE6CF4CF8F338525D57090B08AAB5721216395C49147F6E817B117B129987317A7A5FF15A279F86AF93C6A4995954000C3D4D8B0A07499A95A5C98D0B8303702DFD801B67C37268904C96ABC462750384BAEA767A5AD30C5D452682B3AC864D1671DB38F1CF2CE6E6C901D39C144DA3D93B863F95717C3C585AB876D3EF2B10AFA0B8142164C3C27FB179A923A3F924B15CEBB22EC762907324F1CD4C47573CA1F103CA88844F3B86687280B3B5BB569B1C118B63565055834F39F320CB88C05C199E29684D7802CF45D8DA342CC444D91A84D6D9461C873B66F9785488723A167412019077C9A7FCF4C7BD028BE3007B3483026A442A095124C9607C950443FD69993615697E9AC1CB9D380437B85EB300CE4D9B5A5BC2132660DA3527031A1057A565F2C76775565B0088637707410F2E955355425EFE496113149CF52C901BCCC48864C8AA4262367213602B63AA1A8BED77826C0C476152AB3464A20C9CD73F17A1D019466F2AE37859E6E5A8BB8862A480C1B12D6797B79663ED2333F188F34E6CF6EC87E43979F88787CE35877DDF0B689547BF5BA9EEBB2659D76354EBC39EE83975310ACA4F8867FF290793CC08BF29E60A97C28A71EA3084FE27845AB3664E80592412043B03056FDD5744BD74C9584094C2B75C689ACA8E4B3D3F91994E4722B9B331399310975275A0065935B6CDF5A6A8216188452394238BC82736488A84A0C96C580A81C69032AD5E96F4C3061DF5AB246C258CBA0B68A32916BFC6686730B3FF0944A070F535A113FC349CDDB0B67B40DEBFB5215167090F9891365BB3D87639FDA05843A079A430FD5892F57AC4510450DEC00B7905A3A14442231919F9ED4A76B2B159A6CCC3685B3DD1924935AA8E617AF18B5A065AC45727767EE897CF4F9442B2ACE30C0237B307D3E76BF8EEB78ADDC4AACD16463D8602FD5487B63C88BB66027F37D0D614D6F9C24603C42947664AC4398C6C52383469B4F9777E5EC7206210F3E5A796BF45C53268E25F39AC261AF3BFA2EE755BEB8B67AB3AC8DF6C629C1176E9E3B965E9369F9B3B92AD7C20955641D99526FE7B9FE8C850820275CD964849250090733CE124ECF316624374BD18B7C358C06E9C136EE1259A9245ABC55B964D689F5A08292D28265658EBB40CBFE488A2228275590AB9F32A34109709C1C291D4A23337274C7A5A5991C7A87B81C974AB18CE77859E4995E7C14F0371748B7712FB52C5966CD63063C4F3B81B47C45DDE83FB3A2724029B10B3230214C04FA0577FC29AC9086AE18C53B3ED44E507412FCA04B4F538A51588EC1F1029D152D9AE7735F76A077AA9484380AED9189E5912487FCC5B7C7012D9223DD967EECDAC3008A8931B648243537F548C171698C5B381D846A72E5C92D4226C5A8909884F1C4A3404C1720A5279414D7F27B2B982652B6740219C56D217780D7A5E5BA59836349F726881DEA18EF75C0772A8B922766953718CACC14CCBACB5FC412A2D0BE521817645AB2BF6A4785E92BC94CAF477A967876796C0A5190315AC0885671A4C749564C3B2C7AED9064EBA299EF214BA2F40493667C8BD032AEC5621711B41A3852C5C2BAB4A349CE4B7F085A812BBBC820B81BEFE63A05B8BCDFE9C2A70A8B1ACA9BF9816481907FF4432461111287303F0BD817C05726BFA18A2E24C7724921028032F622BD960A317D83B356B57F4A8004499CBC73C97D1EB7745972631C0561C1A3AB6EF91BD363280A10545DA693E6D58AED6845E7CC5F0D08CA7905052C77366D1972CCFCC1A27610CB543665AA798E20940128B9567A7EDB7A900407C70D359438435E13961608D552A94C5CDA7859220509B483C5C52A210E9C812BC0C2328CA00E789A56B2606B90292E3543DACAA2431841D61A22CA90C1CCF0B5B4E0A6F640536D1A26AB5B8D2151327928CE02904CF1D15E32788A95F62D3C270B6FA1508F97B9155A2726D80A1AFA3C5387A276A4D031A08ABF4F2E74F1A0BB8A0FD3CB0AC923A76D541CA65FDEC9C788A407326C7DB508119F617F43B6E8A6F48A398702E051C20C31DE77A1BA6777829F5539C886E3E14DED294D56AE5E88AC06AB09", + "c": "19C592505907C24C5FA2EBFA932D2CBB48F3E4340A28F7EBA5D068FCACABEDF77784E2B24D7961775F0BF1A997AE8BA9FC4311BE63716779C2B788F812CBB78C74E7517E22E910EFF5F38D44469C50DE1675AE198FD6A289AE7E6C30A9D4351B3D1F4C36EFF9C68DA91C40B82DC9B2799A33A26B60A4E70D7101862779469F3A9DAEC8E3E8F8C6A16BF092FBA5866186B8D208FDEB274AC1F829659DC2BE4AC4F306CB5584BAD1936A92C9B76819234281BB395841C25756086EA564CA3E227E3D9F1052C0766D2EB79A47C150721E0DEA7C0069D551B264801B7727ECAF82EECB99A876FDA090BF6C3FC6B109F1701485F03CE66274B8435B0A014CFB3E79CCED67057B5AE2AD7F5279EB714942E4C1CCFF7E85C0DB43E5D41289207363B444BB51BB8AB0371E70CBD55F0F3DAD403E105176E3E8A225D84AC8BEE38C821EE0F547431145DCB3139286ABB11794A43A3C1B5229E4BCFE959C78ADAEE2D5F2497B5D24BC21FA03A9A58C2455373EC89583E7E588D7FE67991EE93783ED4A6F9EEAE04E64E2E1E0E699F6DC9C5D39EF9278C985E7FDF2A764FFD1A0B95792AD681E930D76DF4EFE5D65DBBD0F1438481ED833AD4946AD1C69AD21DD7C86185774426F3FCF53B52AD4B40D228CE124072F592C7DAA057F17D790A5BD5B93834D58C08C88DC8F0EF488156425B744654EACA9D64858A4D6CEB478795194BFADB18DC0EA054F9771215AD3CB1FD031D7BE4598621926478D375A1845AA91D7C733F8F0E188C83896EDF83B8646C99E29C0DA2290E71C3D2E970720C97B5B7F950486033C6A2571DDF2BCCDABB2DFA5FCE4C3A1884606041D181C728794AE0E806ECB49AF16756A4CE73C87BD4234E60F05535FA5929FD5A34473266401F63BBD6B90E003472AC0CE88F1B666597279D056A632C8D6B790FD411767848A69E37A8A839BC766A02CA2F695EC63F056A4E2A114CACF9FD90D730C970DB387F6DE73395F701A1D953B2A89DD7EDAD439FC205A54A481E889B098D5255670F026B4A2BF02D2BDDE87C766B25FC5E0FD453757E756D18C8CD912F9A77F8E6BF0205374B462", + "k": "0BF323338D6F0A21D5514B673CD10B714CE6E36F35BCD1BF544196368EE51A13", + "m": "6FF02E1DC7FD911BEEE0C692C8BD100C3E5C48964D31DF92994218E80664A6CA", + "reason": "no modification" + }, + { + "tcId": 2, + "deferred": false, + "ek": "49469911485CB1C06A48A449F1A43B0456406243AF447A7CECD5467DF322A159AF32B6C59CB05D200CAC34DA66D8DBCFF8326FCCC08A77C9286F590F33C06AC36049B91442F18AC6C00C240E713D387C8BB2BA3780E6BBFE90A4B1D7B155360ED9ACBD63205BC3482B8953B3490427F28392B083A47BE5B18EF6AB51B9859FDB659B8424BA93A8F470014FCB6AB9E61FACC61311BC1BCB098469D9702FE54F8F931DE7B2B57543750A346367371F3724384261B569AB5D8C870A01822BB4E6C617F17DB6EB0D0989C5644459281828EF4AC11A119EF794530436CAA0E28B8CB5365E4854E1AB4BF87CA018AC6A8E62C36C97117014A569AB472DEAC7E7B1108BB8BDBD710AE8D033A1961917E171AAC6841B5A9C5D869E68974D79B8C70775955520CEC21B5EDB05B60FE230EC143BFCC15B550370E1D58E76D1B5BDB0747412B952131DB306A4DB2395CA69CB9912C0A1660517553C92A7210056C4B6F347CDF33C326A27155CA1A7BB809F8A4A46703537B6530E5987E02A9EDD83297A1218C68699E5A898F9487279D35BD01B57B57A30E85483194C68069BAB0FC4BA0F48880DD1089DD21ABCD07228D9B213C32EA184291A2B12E3E19B4E4B7CA51879C46AB93057AE748236265935F0B16CB456256419AFD82147C9247CE6A7CEE4F349AAA59DA7A4AEBB2B0ED225775CE085A9AABBF49B756CF833CAF22B39AB4D9AC4A26758430866C9D76C5EA68300AF90697FD304AD715C591798C7948FC1A954FFB40301A432B29726884266A3D8B8EED13F3A33A106349FF58075C9D67923A59E06322FC7258017179E7859ABB2A83234D81330B1297AE842AA1C0C8543972E5B3AEA4490D4B0CCC1F9681266A6A0F96DD955924EF25E39642556F18443497D2EAB77AFC01B1D2003F1981C92060743141458FC606BA85DE9DBB1BAC78D6ABBBC73BC7F4E0C6BCE13C8B49BA367E60929C61C34FC7BFF013D4743BF92A70B4683C724B06717237A76D58F81EA39A9F96F6D627162299BC82A355D06C766318BBFEA3386860D683AB75FA03A87B1B2C1D99A30EAAD78A79CEEB43C1621C54F79AEDF82C7F8CD5FB11F119FA35CCA71B4CCF3E1D83F07C3A66C3E82F2D84F640DE5", + "dk": "5639898D7A061A47880E01A1DD869A4393A58EC5811124A22AF2CAB3C61BE3E70492F22EACBA0B52E2C2F31914A466C647379957EAA4F16C9A10440BD25B6A6260626C76C2B5B7391A16897681535B1A279C38CD4661CC04044425297E47F6827BB8258C246894DB965EDCBD6C864D7ED91DC3A12FE0A86C6D2C40EB5812FAF8421F447DAD43BF2140AB9F473C1ED23EFEE952DC0ACB86C068CADCCCC32BB22117B6F8F9B6184BBEE13184B21BB78B87B33879147ED01BE9441D6D240019C2AF998C771A51B616983627354BF0EA1A4C73B8E2A092AB1772CA7CA194666DBD5C06A3464F3A55946C8B816147103AC24934A3488B95185414AB05FAA360C63FBB00A915271C50F25987E817CF849463B8C65CA76F71A83676D75436D27F2362294EB8C55017BAF3A77C57064586D0BC08AA4906E86DDD13830E2C21716258DB81592814681C823DC499752D62B414925B76B5A4BCA94EA30B2B20D489D887B63BFA72D9A327C121C635904800D68F3BF50A01E765E86894D802C1679964A0CC528CA558F960A5A9D8243CF01D94A99E68E4C2BDAB0576A1780ABC3BB8783E35F7441F395F7A1134C4016200E32602640D42252AFE3CBB3A624724066D5644BF93B8BE699B42B052591FC685D00A289AE76766C5A8A384034F5274E4B81ACC6A52EC0A33EDA0201FB600C702606D5806E95C2610C367426A02A7F1808B09B0119B2D71B7A1D9E93F9339309B941C67C855236761B7DCBDCD501AD736C15C0609C4141D1920651A631C39EBB1ABF4AFF51A56F3BC11BCAB098E960DFF115DB306121F19723A3CA5B9838349DC25781CC9804551C8B80FE9897216D72E1036CDB1C11D6BD710BB60C110507392B32DCB3A1ABCA4B67AD5A88DF76399E5134B8063CA068736E626C0CAC3655711D7004E19D56FF0C11F18417061E70C7F2B9A2DD920E297284EF21CF30BA29E1124C3945357C0AF8EF060D949613417A6B35305239BAC986B8E51468655744CD31BC9BAEA4E0BEA33CF665EDE79BAFEE8102A68AD5891AF29FC0409C00AEB904458FC73ED36460D191003A707EA81CBD3ABC5C2C24049469911485CB1C06A48A449F1A43B0456406243AF447A7CECD5467DF322A159AF32B6C59CB05D200CAC34DA66D8DBCFF8326FCCC08A77C9286F590F33C06AC36049B91442F18AC6C00C240E713D387C8BB2BA3780E6BBFE90A4B1D7B155360ED9ACBD63205BC3482B8953B3490427F28392B083A47BE5B18EF6AB51B9859FDB659B8424BA93A8F470014FCB6AB9E61FACC61311BC1BCB098469D9702FE54F8F931DE7B2B57543750A346367371F3724384261B569AB5D8C870A01822BB4E6C617F17DB6EB0D0989C5644459281828EF4AC11A119EF794530436CAA0E28B8CB5365E4854E1AB4BF87CA018AC6A8E62C36C97117014A569AB472DEAC7E7B1108BB8BDBD710AE8D033A1961917E171AAC6841B5A9C5D869E68974D79B8C70775955520CEC21B5EDB05B60FE230EC143BFCC15B550370E1D58E76D1B5BDB0747412B952131DB306A4DB2395CA69CB9912C0A1660517553C92A7210056C4B6F347CDF33C326A27155CA1A7BB809F8A4A46703537B6530E5987E02A9EDD83297A1218C68699E5A898F9487279D35BD01B57B57A30E85483194C68069BAB0FC4BA0F48880DD1089DD21ABCD07228D9B213C32EA184291A2B12E3E19B4E4B7CA51879C46AB93057AE748236265935F0B16CB456256419AFD82147C9247CE6A7CEE4F349AAA59DA7A4AEBB2B0ED225775CE085A9AABBF49B756CF833CAF22B39AB4D9AC4A26758430866C9D76C5EA68300AF90697FD304AD715C591798C7948FC1A954FFB40301A432B29726884266A3D8B8EED13F3A33A106349FF58075C9D67923A59E06322FC7258017179E7859ABB2A83234D81330B1297AE842AA1C0C8543972E5B3AEA4490D4B0CCC1F9681266A6A0F96DD955924EF25E39642556F18443497D2EAB77AFC01B1D2003F1981C92060743141458FC606BA85DE9DBB1BAC78D6ABBBC73BC7F4E0C6BCE13C8B49BA367E60929C61C34FC7BFF013D4743BF92A70B4683C724B06717237A76D58F81EA39A9F96F6D627162299BC82A355D06C766318BBFEA3386860D683AB75FA03A87B1B2C1D99A30EAAD78A79CEEB43C1621C54F79AEDF82C7F8CD5FB11F119FA35CCA71B4CCF3E1D83F07C3A66C3E82F2D84F640DE5B2F75D3486FE6CEBB15F8E0CB70ED8950970C944912A03717D9D168C7B589DB71AC2F3294D2ED2611E9CB1E07CD9684148F13E9ACEB931C8CDA7427873B44B37", + "c": "FEB020751BCADF864161AFEA7B63E63088517A5EADBC52F0833E6DE2E03C66EF3F71F92FB61B277A26D6C2D9E01B88F0738E1A7409CEBFC9D7230C69E02D3BC7F0403B01512F0E082CB9023C7174623478CDBD6CC5E6D65A09AFA63C8B2686234DAC6FAA19A82087F0847B40AB47ABDE90108A13F3AB3601B7EA70B766F1645E7B4428C4AF8CCC19B62C057C8EE9F41E77DC00E5FF5F4ADD0E8EDAD2CC9D6DB40015E5207E7CDAFC915B8FDB1FACD6415FE3E8EB4DACADD7742560C3E2D3EE0EFCD306FAC97A8FE45CFEBEF1AC1B2F5D5316A4EF9C7D3DB6582354680E8932079567D148473CCDFCF32FD7E6D7F3226EC30EF2792F819229B55C5CB8514A77CFA44F6E8531102D073E8CEC089B4268C86B759F043A0E9D8EC8D57EB5618C6D0ABD44D64E9CA25913588F6CB4CF7D0BC914625737140C0C7E559BD00B2C448886B983893FF7F18ADEA02E41A07117644D5A208928892B20685F7A8476C641B25C48EF63551712AB97B0FB759431B287DFD1488EA11CEF813240E2F4E1F5619084B5D7EFFDE09ECE072614BDF6A970168F8D6628FBD521F1431C9ADC46CE31281AB6D6E762E8A7779FDE0F5CFCC36AA677E1F032010F110FA6B460F7294545DE7BB28D6D5CEDA5D8832EFD3E32F9605A7BD43673A00EFD0CCAF63BDEB49C9AC1872B9D3C8CF7A9C81936F18667D15261DECB9A354144D7C3F2BE726FD0A83B1C27E8C6AD66B1AB77425541EBE321EED279526C79154FF27C1B5306414E60684ED42DB69BC2785A1CBE14CD0AEE879173CD3C94020210CAB4BABC531C058857522D9ADF25FC5C3F2FB0A0DB8BD15F23807AC84C7319EC29FABCA43C99F72354415ECA9844D06D299C9F4AE49E0BD8CA7623B8FC9D2DAFFF3F368E4BBA32489F3EC202A9799094469C674CC216750AE88F387A6C030D94BD8E870706D2D74A27A27CEC92CFF8CFD9E09BE6FEF40F807CACAB3628262C501ECAABCE9CBDDE8B3766813BBB8189CAE1AB38A3605F6354F95432E8EBB8B3A5768D2B816E2F7D22139C0135D0070CC41D40ACEECC4CA16636F08C404E3E5E6F6C7D8D652F6084F6477729", + "k": "9183CD7EF4AAF2F21E2E852771F524B10CB2BDB8C0BA1DD36EF48AB391DC7307", + "m": "4660985A5838041F2E50381CB4E7AC908BAC83CC1E074220C6705E3F5FBFC2EF", + "reason": "no modification" + }, + { + "tcId": 3, + "deferred": false, + "ek": "C70876917C9AC2A2CF2110000910898E21804D940D6F761A525578E2B0399F1C0800B62C8720060F88746122C948446472E73AFE78A205857C6D32B6C01CA0EC742311840A36A8BD157B1C50A944B4C213FCF9558E3068D9714ACDBBC88A1538B59764C1F59C079C5BDA31BF55EB731BF69717A9CA63DC316636461CE2CC42201C359B88D044156DA30AAB932F902030BEEA6D58998FB2363C8223BE3DDC437AAB4D1BA27FCE058E701B10FD211E5862542C058F3DE33D5561B8BB3A83D6C55377862181150173D2135CA3C8084615668C38ABE8B72F193FDF96ACFA3470FAA53450017EFC36882C5AC722659D229225E01C5F976171E19172BCE5290073AA08276FFC85218F208BA3A1108B62545941C8991C4CE279C697D8CD06436134511D300C3A5FEB963D36CF29D6065E085C9663443342A8388763B16566D99C5C5DA4A451C2688E10936293948A57C4CE7B73BCBB698D9B71E2974638D5433E56A411E4089F966F603120D56A48DB653A5CD373D42A6AF3117D71AA4D26A1639D63A305B8BE1DE15C6F678519FA671A91483E46AEA26C0C59872CDAF57B3A6453CD660A0D9A0A562BA23678CDCDEAAD1CDA5820C65EC480347FF2872EA9574C4148C7D59980C584646409793190BC721CA6EA9BF029C695563B0598BCB357A1A221CEB3AB96F2269F45C24108E137D1BC34708B1B66352627340CCAE6CB22F41A75A0A55F58701DC4157A1316FF968CEE300FD55A37B5957F41220BF547933C67201D67B1AE278D9649BCAFC68F082B7D1C6016EF360D200CA0EBC76046DC5AAB171A0D544719E3411B587DCE380D467BC13368A25FA51A3E9B4EDC77561408B776F83A76B24B489310E3B608F1B40EB7395470F86C1D0622C1545065707462D89B364CAB2CEAC9501157F91BC52A2816E9598846B56C1F7B1A6D06195F92BD53931078E923C9D1552782325878832224B21A1C26562245B636943803ACBADC559D3BB6DEC54ED360239F74695ED3364DE562751892F2B2936F6895C166697A4A44D10A49C59C53DDE4B2631705440B957100AF4E1BBD47F2AADF22780AE0255D0AC18A87A28D282DD1C59C0C51D373C8F4A912400D5C87B499E0BE8CA991939F160B", + "dk": "AC789443C51AB5E60BFE7B56D8418AFB874C4C563C88C60B77A1A1516B01CCBC36445B90EAFA778CAA4EFD759982D2313EC061F1E259827214E415A583A911A68581E8B228DA8C30182B3157B50742F835121BB501F7B96947330867BABC615D1044BEFC0467D8B88E78FCC2089C9C8E563DD56BB08FDBB8A5451EDBDBB7ABCA20573B7AA8BA48BD5BCA558CC7B2E512A314CBD5D6A4CECBAEED533216007A7AD988B0D06A37C1C443F16B5B246C2F7C38BF68CDA1DA8098C6307C60658D6C596EF67759923FFAD16EBCC4912010785B7798AF299296653E2D865A12631C2BB49C417C19A655897CA6491CB6ABBCA64B6BFA5D811096D2F99773888153590068F8220534705C7C0E0B1C2538D31A7F0C70ABA02B50B9449D111792372B17C11F85AA67202017A2D07CDB6B25C1D97ECE11991E0C0374167E82419802BBB45F87899F262CBA0C5C74C993849B4CF412C858700B4BC9BBAC82907EA400118C59289CC07BE9CCB265B85B7B2294944F8E50465FAA496FF3865EE52CF6A07492231FBEC32064B30B5E6672616650983B730CC19F0C3BA4B354CB7A1B77A9AAC32D30712EE302CF131B6E38C40A9CC40C3C661848690710BC4DAB94D484B4D7EA7596C380F6C6AC023C01CD773260C95DB6A317F56C62CE0B62A0A59D5BFB99A77B6533C026F4FC25AB3221C643C44C75AB5F70A73A40487AAB651CB62D6E0B7AE24A2D736BBB26777417328078B6A16E151966A72DCEDC8E3C309F99A3989FC61722CB5EB6EB8D3C8993FA57B487D8B6D9C82D37D865FFC172D5478262C3AD8498593E2CC6E9D559F3356DA36CADD4560356351DC40466FB2B840048C4FC857F323126C5944C5C762E5835A90629C0155428B9F99472555FAAD44131E0193021C40DB0A9006543965B8CC1FC0B80092C69938DE4874EC92BB3207AA76CF32ABDF57848BCAFB6F242BF7905C782B38AE1B77DD2787FAA90112768544AB9A8354B9AD41304B15167747A1DE82B52B7CC55CC0D6A59140AC29FDA1654C628492AF47DBE02C8D809189B098D9F8C90C57A91CF853BDE416F6D09638AD2AFF2A0A7987C25C70876917C9AC2A2CF2110000910898E21804D940D6F761A525578E2B0399F1C0800B62C8720060F88746122C948446472E73AFE78A205857C6D32B6C01CA0EC742311840A36A8BD157B1C50A944B4C213FCF9558E3068D9714ACDBBC88A1538B59764C1F59C079C5BDA31BF55EB731BF69717A9CA63DC316636461CE2CC42201C359B88D044156DA30AAB932F902030BEEA6D58998FB2363C8223BE3DDC437AAB4D1BA27FCE058E701B10FD211E5862542C058F3DE33D5561B8BB3A83D6C55377862181150173D2135CA3C8084615668C38ABE8B72F193FDF96ACFA3470FAA53450017EFC36882C5AC722659D229225E01C5F976171E19172BCE5290073AA08276FFC85218F208BA3A1108B62545941C8991C4CE279C697D8CD06436134511D300C3A5FEB963D36CF29D6065E085C9663443342A8388763B16566D99C5C5DA4A451C2688E10936293948A57C4CE7B73BCBB698D9B71E2974638D5433E56A411E4089F966F603120D56A48DB653A5CD373D42A6AF3117D71AA4D26A1639D63A305B8BE1DE15C6F678519FA671A91483E46AEA26C0C59872CDAF57B3A6453CD660A0D9A0A562BA23678CDCDEAAD1CDA5820C65EC480347FF2872EA9574C4148C7D59980C584646409793190BC721CA6EA9BF029C695563B0598BCB357A1A221CEB3AB96F2269F45C24108E137D1BC34708B1B66352627340CCAE6CB22F41A75A0A55F58701DC4157A1316FF968CEE300FD55A37B5957F41220BF547933C67201D67B1AE278D9649BCAFC68F082B7D1C6016EF360D200CA0EBC76046DC5AAB171A0D544719E3411B587DCE380D467BC13368A25FA51A3E9B4EDC77561408B776F83A76B24B489310E3B608F1B40EB7395470F86C1D0622C1545065707462D89B364CAB2CEAC9501157F91BC52A2816E9598846B56C1F7B1A6D06195F92BD53931078E923C9D1552782325878832224B21A1C26562245B636943803ACBADC559D3BB6DEC54ED360239F74695ED3364DE562751892F2B2936F6895C166697A4A44D10A49C59C53DDE4B2631705440B957100AF4E1BBD47F2AADF22780AE0255D0AC18A87A28D282DD1C59C0C51D373C8F4A912400D5C87B499E0BE8CA991939F160BBD4FAFE5DBA7B6E6DEE2892A0D23D7FF97262CF3BE7D86976521FD0E33969DD804179FA8AF901D178A41C1E9F51DBADF03A4393E002689723B0C5963C5EE326E", + "c": "7E132EADB0E35C2A8E0916939F5BD7EA42DF683EE4E64D0512D75B2882FB6372A5233B6BA26A9A1C418171EC4C3EF24E98FD578C87396DB28E35C980A6B3DEC1F772086EDD53126C46A82C6D4F51C1B57F49CF1487D188336CBF99F740EDF5A01D30729FA486B551E0B236D5E08C56C80FFDB2D1CA10040C6435A1E0711E2ED6FBC1A48AEEB6A5D8A59D036D9B702EB3A884476C781BF2996F9BF27C79648552F2A150BDAFBF8E134D44B4B4558EFD9D92F2289CA975E65B601BE687B31D6F028A51B16A5C83B0C20DF3F279C9EFCB66060330854355C02405CD9690BA6F8942918CA5F7C37CE3BA8BBF1F285A4ECBEEEF53BE3366D4AE61377BA5A1730CC82444753A11931790D1228E8CB87F7BC9CA71E6E871351EB81A332D33EE06E83048F84169BE950991863814917D56F97F8A0896B8D8A4725CA965C726BD3C1EF3892175B19D8B9CF83AB82CF55B02558BD255A35085E88D3E3B6185537D8559A6675F8773EC7775FF6518E281701D50A450009B845327D2FA5FEF85FD5B5F6F3BC3895742FF16E483CAF3356B4AFA6ADE61C96D09AE63AC9715B4C0D4AD64072EFEE7B70D7BE0E3AD7D84CAF9A8439AABBFCEF44B624DAB8ED6A4AA57E2AADB22AE7D42DEF201862DADEECBF0BA88EE5D4BB723EC35F99A8556E67DD592A04920B8B228D0460ECDD389EACD55BE9F77EFE906176C5C9A1C3D3B4788410CB4E7035260FA2A2E6E3906E5BA6F3C4CF5AD16098392A0F3EAB85FBC59673BB49B3231229963647402533FE2A8E6EE7B85110300B7E20955974347CE5547521032BD57D8D7A1B202220142FE22676239F8C84BF4ECC2A9A18482EFEF216A232E7ED7583E090DB56F61AAE17B6755506D366ACC6516CCB54537D45B10324A46282E4CD881AC40B45BECDC5238A9605BC722FDA5332E2596049AC12DF07FD8011AD170E12CD8B05E261BC4DAC52D7B0BF42B88267D0AA310F480D67022C740666F9101701ED5319C1DBDEF15F6AAC5E0173CC5436B28848443C7099324F78FB2363CE5BA841DB75C3987C3840659FCE7C675BC5047F9F5C6BBC0057F28B32DFAF9A09E969A", + "k": "941DA82106D0DB42FFCB4EEDBC4123DF57BF0DF2A4E9119969872904FDC0B9B5", + "m": "0D643FF311D83CEDCB3A95BA0F76216A49BCA389A225396F708EC9A51BF18517", + "reason": "no modification" + }, + { + "tcId": 4, + "deferred": false, + "ek": "E868A60B3888165A293FDBAB8B75C008E2695AE85A1C839CB08290AE87200868623049839674CF8E87C8D20C5C369B17ADDB344E263045017370D6885DD25785A0C430250795FC4AA1AB215109692B44C530005054020B32D73DED4B06AC32CC1AC47571B7244F2A05AD063DB57BB285C03C465A5FECB4489F82908EC72908B942153C318509C1508556B15B3BC7A671F6A69EDE283C5B87C2383324C3183B645086261B7CC4B53CEC6C5694106142A12A108A29D749AD47B93583020B3CFC328CCCA1611338A8576BA98659D9181607C42D7EE9B0C3174309FA7B3EDBC6BE422515C203B208C9AA1B3C387909EF511FF2A47AB03A747E0A83326B894168136BD6361D170B8D4087C99552D992929D832D58F26BF3D707B6D302F741456DE30FA6509A1314773FFC079AC94AAA10376ADBB70D857E556272F2A32E68485F84E28AD9326F656A57CE234AD2826298BA4C1CD4960BE4523126A405BC3E772121B1F7AB256239E9761B0EDB5C8D746B4D3323134742D69182091170E08C6E0D3B1862E202F332C7A70A25A3E2482113A5A2C257BDC6AF93C981E5ACC95118CCBBDB5B6244C1D060C9288BB2BB1A6791F748C4182B4AE6A68E060E2028690DEACB1E887A9213C693D57971FB6EDF6A95BA3821D445479B142737887BAD938B944376EAF87B15B210CF273B0BE07707FC52475C01B4485893710D84F5132D025E82630F8415330D257E1642ABFD8CC878E8B199C44107672FBDB8330F3C8CE8154E4E8036E86CCDBCE4B693B0C513132B8B740FFDFC51341BCFFA0BC204D63D6696B2271BABA633A572143E74382346C701F92C099B4371D18269A32769889C61AD428FBC110D450ACC95892791656A7DB39868E03FE6F97420910AE8476D43851AEC9A03734AB4E8E4087DDB9626F36ABF7480705C0E81C3887A64794CCB29587593BBB435C2377477B7A0E6A3C9050A84A99936B94C09DE28B018E73CA7C48B083C5BC1E73A24E20D16771711A863D1423E884808E0C8B6E250986AD4BF1B8592F8EB1549DACB4117747F2994D1808B65DB2AA5B05EBD7A0E614888EF86494B93822876C351BA487DB0D0C6F33C353B368BDEA3BC149CB74DAFCBEE209C50B88354", + "dk": "F9D66260ABC38576A4B54864B8CB3C1380365EEB412D896570BB243C29359D36366CE050D839462A5CCFD56BC4B28224715C39E0848C72094B5DE99C63252F20BB07D1AC305F34845A914684E0B03CEB6F0DDCCBC118CE06E7708CDC1E7F660824F7AA21487B7CFC1D6B788428FAB2F5062223CC6EC6285B70D7AAFD50832970525B7406F59C2A974AC1A6C0C813B4A71EA45371B1A7E2168F3E972F9EBBA639236E9947482ED75891FC834FC8CB44C51AC272A8CA2A0058F57A05C22D9166028D063BF5EB3576467368024C739514DB517D4E1B1CE2AAB8004D4987A96444B4B14CE633A4793D2B40071A77373D630A8CFAA884B074AFA03152C882E9C14806E65797340F0ED100F9D161ED46581B7C750926C009861C3CC89894258E9CF2032283708D1B83AFFBB7A6B890D9F9C725A1CF2790ACB1424C5BAA05C0B3CDBDFC78808695D6531877254B85819370F971CD196080B70AA1AAA8C691A8BA40C44FB60A898543979B5C29C3A40C0117C0162BC06A816626152B472F57178050E1BE9D66CB6C30584912C39FC45D60F26689696836FC60521298F4529888286636C5435A36BF6F2841D058AC19AAB8789924778B473A567189B4711F655BF5D25871D548AF92CC5392C30D2B50EB3C3381033D00C48B89C58E8EC81FA9942A2FB11A79549487F602FD8A85D6439C54C34493966AC4B3C04BB670A2AC537DE04E52218DE78ABF019085E470949565C111106F0C321620A65133439180783BC7261D0F47024423C43A2038544A2C72D480AFD1C219EAC504AB4003D11FAFDA4173B4A4E7E038AA659A3309AD9D1B2489C270F88CA659547F49F45E56FA149603B54A1611061762DB1B4D8AF629D1DC1396069BF1B9324195B5DA92ADE118588A664389BABDC35B92E5919DA2BA30254521DA834DD728749F9814D6777EB4A24AB4BC7BE5910EB39331CF3461D7B56392F99AFCD2B25E4A2948925C7BB744FB05C3BACAA53500B25109B4881C5BCC28661BA6626D648F3396450692503624737D5496C68BB7A83801534A9F86285EAB94B80536292F0A2FFD59647428CB15DA481DCB2DE868A60B3888165A293FDBAB8B75C008E2695AE85A1C839CB08290AE87200868623049839674CF8E87C8D20C5C369B17ADDB344E263045017370D6885DD25785A0C430250795FC4AA1AB215109692B44C530005054020B32D73DED4B06AC32CC1AC47571B7244F2A05AD063DB57BB285C03C465A5FECB4489F82908EC72908B942153C318509C1508556B15B3BC7A671F6A69EDE283C5B87C2383324C3183B645086261B7CC4B53CEC6C5694106142A12A108A29D749AD47B93583020B3CFC328CCCA1611338A8576BA98659D9181607C42D7EE9B0C3174309FA7B3EDBC6BE422515C203B208C9AA1B3C387909EF511FF2A47AB03A747E0A83326B894168136BD6361D170B8D4087C99552D992929D832D58F26BF3D707B6D302F741456DE30FA6509A1314773FFC079AC94AAA10376ADBB70D857E556272F2A32E68485F84E28AD9326F656A57CE234AD2826298BA4C1CD4960BE4523126A405BC3E772121B1F7AB256239E9761B0EDB5C8D746B4D3323134742D69182091170E08C6E0D3B1862E202F332C7A70A25A3E2482113A5A2C257BDC6AF93C981E5ACC95118CCBBDB5B6244C1D060C9288BB2BB1A6791F748C4182B4AE6A68E060E2028690DEACB1E887A9213C693D57971FB6EDF6A95BA3821D445479B142737887BAD938B944376EAF87B15B210CF273B0BE07707FC52475C01B4485893710D84F5132D025E82630F8415330D257E1642ABFD8CC878E8B199C44107672FBDB8330F3C8CE8154E4E8036E86CCDBCE4B693B0C513132B8B740FFDFC51341BCFFA0BC204D63D6696B2271BABA633A572143E74382346C701F92C099B4371D18269A32769889C61AD428FBC110D450ACC95892791656A7DB39868E03FE6F97420910AE8476D43851AEC9A03734AB4E8E4087DDB9626F36ABF7480705C0E81C3887A64794CCB29587593BBB435C2377477B7A0E6A3C9050A84A99936B94C09DE28B018E73CA7C48B083C5BC1E73A24E20D16771711A863D1423E884808E0C8B6E250986AD4BF1B8592F8EB1549DACB4117747F2994D1808B65DB2AA5B05EBD7A0E614888EF86494B93822876C351BA487DB0D0C6F33C353B368BDEA3BC149CB74DAFCBEE209C50B88354804C79976E41410C336BD08C60D65A16BAABB81987C8E6C6716060488905CF550084F403AAD82B09B96BB6C85D25165EB9E5BDFE784F096522D8BEA8007E19F1", + "c": "0756A8BA612C014FECBE00AC1E49271C6FDD87EF587C9879D6F8159E10982B920D3D1F477D9DCA08619185AD10D802A9C4C68D4E68F54E7A530126EEAB93386AE1F184843D90C34A1FCF7E9F54EE61B40A6DD52BD091A4E44DED49D8E8C9B63A395FA22ED602D03E399755F49AD766C49E24994969CCDA54C986DD47DE9646BF5D1DD5AC0EF7B10F86837C7EF18A05E6AEA2254A956D06062EE2B9FB3640C60E8F5907E99524B4B0EC608B7A0FA698B78B7485B6C07DB74897290659A99FBBA2D8CE4FBA364F4A5978984D1ACF0C175B90B1A04C14DEC67561FD9FA789D418EB8033C99863CF52E6653CC4C951F95D718D77088CBBC36A9B520156803B85F3BAA123008C4B2CBEB52C47D790BDEDFD7E7E8B7693DA18AE01A034781DF62CE288DDD29949DCCF28D0B2FD712C4A28282FCBADAF8CC9F811C1D81893161EE2ACEF36D0C3BF128FDFC77C514DE6CE81A9762E7CFDD53D90FA643F64C68969B2076A259BE106D4C5E5DE63461F48C50ECA1AACCF7EB56C288672FD5E7F2EE3167FD01C3A0FE73BDC97BA69474ADD93203BC01BC1D9F8DEFD59433CE26D117C66692149CC8610C89B5DF5B6741AF6C4BDA814657321AE6CEBCCBD5169B32C70083E2A52D6135FB4262862E080888716245CCEEFD6243F0C2C757A3C2915ED58F2D0C82CA5F9C24547601DDAD0EE1832DF0D779D001C28AE57845444F9A527F32ABA50318135931D3991E629B575762B7DDD0239A9E9EBA94603EB5CAA3B2245A608D84325D5D8093DC4136AA736F5D70E581ABA35EFE446E0FFF5F727D413A9C5C5ABAE83AB0F27A710D32BAEF300BA753C4DC7A997AC24A3E8908F1A705DF7D16876DC3854FD25D747CB8FCFD9202EA8DE379891B98A1859CE74F035BCC28ACE3EFD85B7AE2AD566CF64B91B9808686A4D4ECF498F53DA2F514A34F45EE14E28CECFC12BBB34A08F5FD68D6A856C039102C298F40787D64786085255A855965AE4A4B61C7CC395B4E04CE55BC9875F6C179F707008544901D64C3A3C987C88525323D075586A3FDC6FEEA867F0161F619F8004E4093D40FAB63AF2737C51C9637B5F", + "k": "8A77C7C5D298C5A9724AC05B9FE0D8843A7D859CC40E07C786F1F96F921F76C3", + "m": "AA28DCC71FA83D9997DD733D8B0D0394D84D33A3D3E1B74CB74DC6049628F861", + "reason": "no modification" + }, + { + "tcId": 5, + "deferred": false, + "ek": "76608E0B9539C1B6470F9ACCCF5465C6B355CFA9424DA750CC085477B4A0E9F671DE185995FA38088506A8524D6384A8F505058800B3F14019DF2977E79436D81B8653B844920BB927D2CC7657666DE99C4D865FCAEA3F18302A36961ECA216740075244215625419758B8B8A82C46FBB79333E56D8076BC2F98610FB3474E75A471AA6D746708037020D3578381CC7C959459FDF21839E8413B44C218643CAC49A0179B2DCCB11235345641A10F3D369FD03C8FF733589607616A50926C176CEB45217A0A62A1F4AD3D06669EEC8C947372E8D082E34789A8D9867C0198E5B06934D904AC5318B58A2A5F3AB2522C611F7BA5A1351231F836881116847551D834A310EB82E0B2C6E1728196B7206D00094AA928AD8138F97879B56B55FCDC0D35C76C336526CF52C6192B0793745658E53155241F46663A8DC153ED12862942674B029492D701BAB56D2468C4B165B588D2A6A94C515E9BCB91A55BD372A613590CD76416C6A0AFC40A60669C90BC3A228F05A6DCEA473688CCB80A4CFA3C9BC5157CE4D37BCED562D5B52B70A48294912BD127BE37C39EC4F23F7C3C01A521C56D121D6829A76B7235C2BAAA2BC841634521D8F360D5B7B31B0648FA442C546878A7CB2FCBA5559F94A90308CBDB72C60551409E364CEC93CE24D16593609159735111F918FEBA4B35465BA14AB8AA1A705AA9ABDFC596864347C6E445F23B64B81AB330B454D14413ED47CCAFA49946B828AC3056CB4195C5351FD65A4BAA57262F9A85A4DB552D939BF539B8C4C547B801C1D99C7044393A08143C332AA440477258E04A83F6089C864B1A69418D0B4B739A4BA729B3FCC9C10F9834BB9409950449A8EC09ACAC79BA0681B31A2C7E687793C352F496010AF4A30CFBBB89CB3012216D8E2B489676B05E4B8F142825C4C4552FF7A48802C3E8040C4B2C744AC477EA84901A27BACA79635BA6C0ED28947BBA8B788ACBD17CBB01CA931E4BCF2BC15EC01476AF0A5F8672897AB5A2F9F850BB0ABE6B61A2A4C800F5671F13D712E8686C780677952A0AF65B463CD0289FE3B56F89A6F7D1643F0823093589FC76619ECC2590076DEAA2D895CF1A81924A0490D99446E364BBA45C3BAC1D40", + "dk": "7880A126F08E51F0A6E89329E38741B15C1D4F2410131BA19CD49B9BD32A71487081E4B0E4692CBFC01CCEFA210BA23303DC9C05E317A9F5A51C535BDB6BBE7F1043A5F841E04B7F70E566AD3C28A84352B5064B25DA223B16A8478BB038E221E2F853A1BC07E8940F97175292C6BB8236661D587F6F539BF0616642B82456F7839BF0A9A393919E1356E070058E0442A61CA6F9019240194E61C453420181F8D0A108F87BAAB970AB0B6DC5A7909AF7193C975BE88849641341E42C6F92851EB8885A951779D606AE9CF7271732B728C35B5FD7611FC7C44362A14B16B16F779CEBDC1740F6A8CD9540CFF05BCB95B1C10044EA14256C34B4DF46C2B5363B33390728C152A6CC9778E21A0C909D83001608C773F4DB30E6774DC7F6B80F966BB1494764E8983EE62F35B14C977C1B05C43734528B4281412738C3C10CB4A1016C5EA5B220A4899D91311B786706285804038EB83357DB1B4FF3B12C71850F33733A52582707351EDEA8336C30A326C66805638318E32E4027C97485A77FE4817AA65A48085824D24ABED83443296EE2A306D4642F71FA98C2647124022812C5652FE4AD7B6892E2239FAAA9261F9B2374F242900461A469AE7F2259CDF527F062C1D55C3948840E4FA7305A088B126C27F40C6A9FE0938879A5C7F56157C32E77E417E5356BA200CAC228C647244CFC03479373C40EEC90CB115D4C723D1057233D42AEF5E7557B0713E29700A246BD168272EB0348D282408FF66B6DC16968E7AB493A64EE626F96436D996A181FD5583BDC2F8609B9A6736FAFF56C80375055A8992EEC85FF6575CCAC18C2B763F1E745691259BF4695324C0A42C3C87B7639CD45352A7603730A44FC7473C79A3C72F18D77CCCCE489C897FB3C7204145DA416C214818EDC7AAFA0262D5A330A4C4FDD72C03DD5568AD1620F6564F19A98630C90482C7C064A9788F0A227F7332B901BC359A6FB2ABB30C5131B98429DF96C35A2A81359C0D9426B516847375B8AF236687A071179EC53B54C1736918599C193FBF5C6B421CF7F029B691482DD2A539C0268E590A3CA563FA88674A6238576608E0B9539C1B6470F9ACCCF5465C6B355CFA9424DA750CC085477B4A0E9F671DE185995FA38088506A8524D6384A8F505058800B3F14019DF2977E79436D81B8653B844920BB927D2CC7657666DE99C4D865FCAEA3F18302A36961ECA216740075244215625419758B8B8A82C46FBB79333E56D8076BC2F98610FB3474E75A471AA6D746708037020D3578381CC7C959459FDF21839E8413B44C218643CAC49A0179B2DCCB11235345641A10F3D369FD03C8FF733589607616A50926C176CEB45217A0A62A1F4AD3D06669EEC8C947372E8D082E34789A8D9867C0198E5B06934D904AC5318B58A2A5F3AB2522C611F7BA5A1351231F836881116847551D834A310EB82E0B2C6E1728196B7206D00094AA928AD8138F97879B56B55FCDC0D35C76C336526CF52C6192B0793745658E53155241F46663A8DC153ED12862942674B029492D701BAB56D2468C4B165B588D2A6A94C515E9BCB91A55BD372A613590CD76416C6A0AFC40A60669C90BC3A228F05A6DCEA473688CCB80A4CFA3C9BC5157CE4D37BCED562D5B52B70A48294912BD127BE37C39EC4F23F7C3C01A521C56D121D6829A76B7235C2BAAA2BC841634521D8F360D5B7B31B0648FA442C546878A7CB2FCBA5559F94A90308CBDB72C60551409E364CEC93CE24D16593609159735111F918FEBA4B35465BA14AB8AA1A705AA9ABDFC596864347C6E445F23B64B81AB330B454D14413ED47CCAFA49946B828AC3056CB4195C5351FD65A4BAA57262F9A85A4DB552D939BF539B8C4C547B801C1D99C7044393A08143C332AA440477258E04A83F6089C864B1A69418D0B4B739A4BA729B3FCC9C10F9834BB9409950449A8EC09ACAC79BA0681B31A2C7E687793C352F496010AF4A30CFBBB89CB3012216D8E2B489676B05E4B8F142825C4C4552FF7A48802C3E8040C4B2C744AC477EA84901A27BACA79635BA6C0ED28947BBA8B788ACBD17CBB01CA931E4BCF2BC15EC01476AF0A5F8672897AB5A2F9F850BB0ABE6B61A2A4C800F5671F13D712E8686C780677952A0AF65B463CD0289FE3B56F89A6F7D1643F0823093589FC76619ECC2590076DEAA2D895CF1A81924A0490D99446E364BBA45C3BAC1D405D5240D40DACB83C6E97603086982B2BF96DC0108BE0A5C76AB85AD6985BD6891BBEDEA993E606D87B101D21308B55560DA8BC3F7C7AED02BFD2D42E4D722BF4", + "c": "371904CA3678917FEE951EF2AF3C21CFFAE77DBD02E836EABA8AFF8B687D8FC28E2443E2F6FA020FDD2962976C6D8062FB57F22A3ADB52EB9AC8472EE2A08C4F4D98632D1D752AB7BE7D57F5FDFCF6355E1AECF7C68DA4FAA809177F9C8A749CB779F49F97B65E3467DDE74CE2C68590465B53E91F2C5C988AF7A0BEEC8090E3E3C60441FEB212D2602CFA3AFC27EAA686EB92CC5BF7E914489A33646FC6A63AF1284C108CD287001CC9867A70E3D62B7A437B1B87C095A26543F1B7EF16EA944F7D4FB382AD3329121281FD6CE8EF3EC215C7C13C2FDBD971CD5599ECF5ACD46616B1C911F03AD284826291F56BB412467143D392C07AA0A50BCF9E7B66CB9FDB25041CA81413B9B392C2F937F033D34A8A293E737D7487E2BCFC2C48E101878E03B1EB0CDEB3BC55BC318286521347828C9A5B4B12AF365EE268A743AE1F12B4A145264E628FC9D35DEE5ACB6122996E01E78221E46AD966B53C122EFD33774C7908BCAC16D79BCF41CB6F648DA913293434B237DD06511D2A5A05E8E5C01C44408E53CB4DB6FB22874D492362AE1D2BF16170690392D979A76627C3D5F5347EBAD4315A76649BF09C0DA85A741CC72C5D63A71E3F7BAFA97337FEE2C8C5EB5583257AC1A94C601AC42071FC3ACCA48A8C42ED3667847B3D938BCEC9AB45C8B150E35F2323127583DFBEEF5C1E8CD0E1333B7F4204FED4B5C2FBFD978B3D42352BAC156AD32916B2C22C76C10BEC77BD31046AD7AEACC2A55DAB6E5DFBF9212FD45A763E125762D6E6D35B253F05E18656DF844594987ACC39A34CA480497CCB2981207E16A2FB2F4FA75C8F603CEF272CC63E771EA6F45AF51B18AFFBBB7B2D3C8E31260D11CE04224FFFEE8E665D20977C3C30FE1C9E34495C3AA47019020B2B4582F8CCA36D34D5D27904A769DFD6C6A224B7B7AD693A7C24D04E04063D5B0CC653047895DF676CADCA882DB762FC3E432171E358B2E2C24BF514FDB6303635C6D3F3CEBDFB711E97A730D63D8C71A6DBD0349041BCE85864CF021EC2D335E48647DDB8EDC5C2DA942D87B922FCE5BCBA8E4E59DDF31EAB6A97D6F01049", + "k": "7251DB9D63102DAC680DD894609F12B795371A4012BBD22C05AF846E5D43E884", + "m": "A4BAA4C603DA1368C1F2AC552A331F77BF1D598C6BCB540D43CA1E6D4B8BDE77", + "reason": "no modification" + }, + { + "tcId": 6, + "deferred": false, + "ek": "E331342D560ED6120D12B8044C013C5A8A1204164B00130354015213361BFB439417F5AB35A18A4D1600ADE0163F6A1760B08B3BD8A16C3A82D253428508216E3952923070BCBC922FDA6D0E1A734232194EF979790828A110B9F096CD37B5C07D758D3D68CDB9642FAF100D732031DEA07BA884ADA7D4436C490924920D3B3B7B67297E5D8A984DB9136F44557C6BAA5023219048600B8550DEE669A9F38858D79BAB8682FFAC37B0CB9362723B7A1087A21C477513BD386A30D92A5F52F008A32784019B61E0C8C22B096B356C65CEA631CAB14632A2B978A40A91BA7544559A116CC74C28332DC745EB19AC5EF50425E59FE2C777EB0AB7F4EB49A3393CEFCBC846B63D399A6B86CB6168958E71045208C81F07F62CE826729BA2162C2B835185759CF4AEA00025F4AB46EB56AEDD408B0E016C6ED538A1280F6A0CAB2CE7B573258937F0A265D663F0F33495BC4852D73C774061DC388C3E75ACC69A84DE303EDB605CDBB238DB265AA26A8267FCB4A0922A5413CB65783CF37CA2051071FF00CF57BB6000C6057BD93D4DF31EF35CA5A4327CA8AA2EF7D33A04E5261E732EE8FB819AA446E02CB4370B2934140EDF17BAF6040F71B34F251C6C65B766D317C4DD181AC04103409B65C6A7ADA248549BE72A2B43B2E4B85B58CB5FFC0B33C675C0E0D50B2020BED86005BDE97B9862436CF7A7ED687591F9719E4803254BCE195185CB3C9A48DB6F148A0876B00D1132AFDFBA1C91F57E980B96F1906439489093194F2CEA56C46942796749926B36D498B026353CCBAC0BFDC84C208502E0518512D427DB058219B35DC793B789F5C579D9A5E7285B3AE90F71FBB40FA39C5AACAE582211D9130B7D309AB3C34FC279AD6016C611F902AF959C984564BFA565891A5D1FE13C9D27181A512EE1CA31BCB55114C316BE427B01B6A519E441F66B926CE959A90A712DA1B81DCB0AE6D67749987B3E541A59D2680B11AF845234937B63065B32BFBBC1C9086C7DCA12E258C21E7AC52F812CE4A16E347C5CC115C2A16355F4745B810A4B5140CAE72248B554725D9C186523CF625013D5CA11B7951425CCC18E014EE5E94C2695BB469BD83646256DE038ADDF203E0B60B1F6", + "dk": "C97A2268733ED7822CD3B809F395637709A15E02CA5CD7381F27B78D9060BF67B334E193372029FA6601FA5BCAD83429A1F22ED0291AEED22790F62F27A57AE87B81D2A7B2BE812B6988400A62156FDC6DA8261C81283DCEA41C0ED48291128E38007784F65A2B39681BEA58945971551BB873869DFD5C093EF64172583AC2CA8A4646B81786A0A5B039C1F00D3503B31D352A92C2AA7880945924AF63D872E8C85BA6D499B22B17682B508CF981F9C9A8B0DB33B0E7917F9197D0D05FF4A5C38A5102E20317DED4837F46A88A41A1A9D588EBCA92440651A1F5774DC7803D3C88547C57A297A4086855AF7C197254CBEC831A0A4666E265C68CA35678068600303AA17B49A4893B0ED913BBEC197E323DD48B94893AAA0999096E7791F9E628C2E26A9E70C8B6B6AC3D1C6B61943E0220BF30D3A70BEA3272069DAAE676CEC68405A6821E0918B0730CD8D282AC733E4749C05CC382D5E727567A5B8F7258E3358831B160D9F90DC76856A0F462D2D6C66B9266C487131F37634B276E2817A2A946B71B7B84F93C64495CA2BA2947F731442B38BA9A954676580B1CB504E3903AE2B8B02CBB1FCF19A6F37342CB5A13FC923529C0AA1B18B16CC1C7AF1946A41950FB81617C369555F5CBB720971DC8076764A20AE54557AB2208684426F25B0CB0ACC6B75D0ACA76713495528461449C2DDA394FEF871B81D38D651529D7BACADFA3CC05ECB0C27444E1A53C3822641BD0B43220A682772D67D7AFEEF60EAB2B3AD3A87DB56391E471968A65261CB3B219CABFE9975A71645A7A2C9E2A234AB49B77EB689063ACA410134AA8570B687767D8F50687F4844A2B3C1C5B05B188005A0B17D4710086D283F6834EBA728F12996841350507CB5BBE247355A464AC7A008D4B9A07240475C2BD3FE1C469788F51003762F7AB89A9C980F4ABBE76782C084BB8F106AB453A7B7A16047222BB4484F992472ABB62D4EBC053BAC367EBB80579A31F2C949D53AACBCB8ECD9AAB2FF07D86388B26E47AEDE4971A4290DCD7358D306FDD951681513FFD5054BB568534D188D608870ED2028DA36B65A37AE331342D560ED6120D12B8044C013C5A8A1204164B00130354015213361BFB439417F5AB35A18A4D1600ADE0163F6A1760B08B3BD8A16C3A82D253428508216E3952923070BCBC922FDA6D0E1A734232194EF979790828A110B9F096CD37B5C07D758D3D68CDB9642FAF100D732031DEA07BA884ADA7D4436C490924920D3B3B7B67297E5D8A984DB9136F44557C6BAA5023219048600B8550DEE669A9F38858D79BAB8682FFAC37B0CB9362723B7A1087A21C477513BD386A30D92A5F52F008A32784019B61E0C8C22B096B356C65CEA631CAB14632A2B978A40A91BA7544559A116CC74C28332DC745EB19AC5EF50425E59FE2C777EB0AB7F4EB49A3393CEFCBC846B63D399A6B86CB6168958E71045208C81F07F62CE826729BA2162C2B835185759CF4AEA00025F4AB46EB56AEDD408B0E016C6ED538A1280F6A0CAB2CE7B573258937F0A265D663F0F33495BC4852D73C774061DC388C3E75ACC69A84DE303EDB605CDBB238DB265AA26A8267FCB4A0922A5413CB65783CF37CA2051071FF00CF57BB6000C6057BD93D4DF31EF35CA5A4327CA8AA2EF7D33A04E5261E732EE8FB819AA446E02CB4370B2934140EDF17BAF6040F71B34F251C6C65B766D317C4DD181AC04103409B65C6A7ADA248549BE72A2B43B2E4B85B58CB5FFC0B33C675C0E0D50B2020BED86005BDE97B9862436CF7A7ED687591F9719E4803254BCE195185CB3C9A48DB6F148A0876B00D1132AFDFBA1C91F57E980B96F1906439489093194F2CEA56C46942796749926B36D498B026353CCBAC0BFDC84C208502E0518512D427DB058219B35DC793B789F5C579D9A5E7285B3AE90F71FBB40FA39C5AACAE582211D9130B7D309AB3C34FC279AD6016C611F902AF959C984564BFA565891A5D1FE13C9D27181A512EE1CA31BCB55114C316BE427B01B6A519E441F66B926CE959A90A712DA1B81DCB0AE6D67749987B3E541A59D2680B11AF845234937B63065B32BFBBC1C9086C7DCA12E258C21E7AC52F812CE4A16E347C5CC115C2A16355F4745B810A4B5140CAE72248B554725D9C186523CF625013D5CA11B7951425CCC18E014EE5E94C2695BB469BD83646256DE038ADDF203E0B60B1F6A1E6FF9222F4F2C0B6E2F4CE6BCCB009EFFC6A423DF374F485EDBC06000C8FBAF7868913CFD39EE71033FD55572599095F2E641FFD2175F6472AD7E38809A25E", + "c": "A5A62163CA438B8A067E66246A18B815146656D4015E6CF9A1FF0EA73BAF7FEC4B3E177D850822CCAA0EC3191B18CBC05EFF51C78947E4565E105DC3570946E1CD76EC2AAF0AA18FC41D8C8F74A1FA602891DBF82FA7CBDA9E0235A35E9256DBEE2A4708C7472AA5E55F8AB1362883C267D1629163E5BF048056BC8D1C67D934B274C4CC0A486BCAEE2B8BE3FB21126643417607393E57A93483BF37A3091CE196D4FB3F1B645A17B8CD6259301BBE4FDAE4174512690D68CA888DBE194E3E2F2B7AFC4C43B6AF0EF99BD4A9CFB5114A178F501BF2ABAFBD74230C9BD549D91165E96D0B19BBF96C3A938B8E6F0C30EE148933399F0FB13B70F606094EF9B02C526BD66B6E1C2FCAFAB16E0A24911B7F3BC7904FBA00C27A752072CD94E9DC7A894BAAB5E4118AA74A32B3F8668A4C5098B466746B99008A979670572944122DFD32807564C4B56D387B7C48F727D121CC34365BA85FAFE27793EFDDD70E5B0183CF9E8BE4E9B92276E49DC675001E0CC8D061CCC36845C05833308CB99C9FDCA57CB8AF659E30BE417B776D31DD99835373396E7F58A9D07D301525DCA367C1FC39C228BDDC630E0FD76D651558B220891B209DC7AF154E2C51A254B088F083A1099F80CDE8274C6FCA19CAF00338D02208327967537F8FCE0CAD2F37CB90F10DB8FEAF457A25E049D85165433115787CD7487D8ABBF1BAC4A1D694715FDA4E145BE3D9F68E18551C2A8EA31163A6407AB6968FBAA88A0CBD30870CA3DE1D61BF4F72E582B9045C83BDD3E2E26276C9A3E0D81FD9E9BBFEDE81C047E2B3F3445AA5BDE4FF909160181B1F8089F759AE9CB206C5027E04991ACBA93A098585857CB1A983DF67F8E543B626449D7F2A52B64296B2DFEB1673FFDE4CDA17F62AA035A909FF44853AE23DBABF048248C1333BA6E6BE74D2EAFAB8FF52AB31CC47CBE84A2221D4CCC498D670C8BCF382ECCEDAE8599C4FDBE7F1B328A4AC91EAC2CA326D216BC904EA0AC019DAD008ACEAFCC6CC71C97A8AB70DDCB16761EFC8ED656CA72E0385E97F14F971132370DE24A682764A88B2BAD33C56E095C7DDC6F355", + "k": "F8F9921AC3524E9AF70CAAFCE21A20ED5FC76DC988625CA9465A257D43A6FBBB", + "m": "C08584D2F5C950E371668A4FC8F527E20AF1532CC28EE6B5620729155B06389F", + "reason": "no modification" + }, + { + "tcId": 7, + "deferred": false, + "ek": "83B08010002CFAE6362BC02EA2C08809E5031C213F78795391E4390F4A4F7D8403B79458B792B3B2A0BA0EA82811912CEA1C2553B264C03992D28A29AFC0C50FCC0343DCA764457D7F1A73A975044752CFAE0101AA47A3B706594B403B5561A451013EDAD45B60E42905A97D2A0288510B66E9E75CCA8A6B2E5504A9380785DB36B21B5B1839111A543B18E3B41F30232E1BC816A1992A01C51C32CEEA8B4CDBD4C30CF792AAA5BFF2D54DA6B988FD8C14534B2D24334625A68CACF5897B495D55A873AAD557C29957DA2644714303CCC8744640C932B8307B8A08C2403A94E17387F4BDF786B38276756D95C0B9FC4E56C7AB925643A21A9BB7BC6AC58262DAAB33AD09348F7C569147359DCC794EA4673ED1ABDFB71EE199B31FE1CADD2579F94682FB013039B935A3167FF8460EB3006DC7EA297B643B150C5CE360BB197732B7F9198F4A7479EBB8CB97A22010618E22200E896C807C5056D78CE088A8478A751B95750A849D12677C6DCA08CDA502EF603FB5C67566338EB13114FD10622BF8B0212C70E92C68827999ED7177CEA44A7A055F12A00231F3C5FEC1BC07812EA902CAEE99B899B39E88FC7FF6973311483F2A9BAB7917A56D2CBB549AA887E545A7554910947CB9F09423C75EE63B626E8BAAA7A00890340DA33B7C2CB6052B5CC47CE65A0873CE9126816D8BCB6A1C8D39265BD1797F610244C565670DF05E58760690D52B6882A9A303582AA03ACB3B2D857CA0D7B8A2BF859860DB729D2740FD87AF798497D558042319638A33326E3C5CB0D3CD6E71A346365B308221A1DC2E49F51E818B22ACF66FA0C586958CA78204A1FAF135F17977ED2801C4591F2893A756A0C4988BCCB011B389D0656A717A069BBBF1F893A3BB64FF28B66BD2106FC23C2BAA2E4495580D08C896A92F2AF36CBB13CEF4AB94E4CC9D866459BF6CCCDCE7912B3119EEF0AD4CF5093CD85674679A298272EAD6B14F2950F18C602C52AB821234F655419B843C31491C47C596596967F1EB036550A941A03790874FD8498DAFDA127C8B0561116F9D414171778C7C36012DA9BC543158A00352A2E39D802CA5254FB4A43FF40242ACA967C85D45EE0F8E13DDD9951336DADD5E", + "dk": "2DE77A797897F74413868189055980F0040EE0C0917405662CE681BC387D80339E8F5190B63CC50F66867CE78841379DE141141EB15A06E3948439A0F438BC56656A5846C98B21C037A888D1D23DE23A1C945B8B2691CAB7B1570606149A930200BC23B2EC335542619619BF8CB6C7C1A0B8F60C4EFF721ADE91C4AAC36E17894E54D3A006B60FDC62616666927C90A5BFD633F124BBCCB1355A901AE432CB344A72B525B58BD3C78ACBB919C3118E1346631B7E8A514F19006CC3D93AA693296EDABB57D37B61A863D3E6BC95F9C5BF114124FA5BE9425679CCA54BF316C97392BB5A7A16BCBD00953BA7650BB73BCDA3278E1EFC1C7D07B73F942326D871FFD470006657AD2B26E930759C474FEFC2CE64F631C7A39017C9B07D41434925740F03CB10335543D17BEFD57C5312A4C8609503924A4880A7664339FBCAAC331863E88C21F1109740CC8516201A20F349CF62CD56E3004DD1C56B255918699B3DBB3F262724C3F75AE212C9B0093781222B10EB9953806644F958702B80FF6274169979ED5C02ED270634B68F435433B6A36F49731C216C7C3E58BBD58ABC299C14CD1AADD4E9098F7C14354702194412A7F5341A451B6672AD433BA3A7331A006D781CC66BDD8680F5A201FA71B3B9D69FE81A624491CE09D461A8B50558B66C72F198B650A329E729C0753FF7E33E6DD41161AAA43B881DA83CB862BA187FD9AFF7885DCBA80C18C730F51360AA08CABA71C88DA42587600E59B97EDFDA010308A2E8483C71F92C3DE34625DB9E09540A8EDB1696E09C97EBB86507BABB3A901186815128A3A331CE51042E03875278048D4B085DB51094D967CD6BF6A872641E3DFA0A5DD7ADC582A303F3CC5C032C89C6B841397FE901702682939452C88D615BF488C7AF3CB433B72163436DC4E7112EF62F82D91C783ACEEB047D6F46036B70578F79634C98B5962C0EBE98AA97401ACA4B19E6A86D451206E9B06E4CB774F392AF4E1C587AA415B191818E438D0585459E43A50F61AAD3E934FCB09D6C78B43DC7BA6DFA50236984C6992149900843959AE8A7A9AA35146F78AABE2C2983B08010002CFAE6362BC02EA2C08809E5031C213F78795391E4390F4A4F7D8403B79458B792B3B2A0BA0EA82811912CEA1C2553B264C03992D28A29AFC0C50FCC0343DCA764457D7F1A73A975044752CFAE0101AA47A3B706594B403B5561A451013EDAD45B60E42905A97D2A0288510B66E9E75CCA8A6B2E5504A9380785DB36B21B5B1839111A543B18E3B41F30232E1BC816A1992A01C51C32CEEA8B4CDBD4C30CF792AAA5BFF2D54DA6B988FD8C14534B2D24334625A68CACF5897B495D55A873AAD557C29957DA2644714303CCC8744640C932B8307B8A08C2403A94E17387F4BDF786B38276756D95C0B9FC4E56C7AB925643A21A9BB7BC6AC58262DAAB33AD09348F7C569147359DCC794EA4673ED1ABDFB71EE199B31FE1CADD2579F94682FB013039B935A3167FF8460EB3006DC7EA297B643B150C5CE360BB197732B7F9198F4A7479EBB8CB97A22010618E22200E896C807C5056D78CE088A8478A751B95750A849D12677C6DCA08CDA502EF603FB5C67566338EB13114FD10622BF8B0212C70E92C68827999ED7177CEA44A7A055F12A00231F3C5FEC1BC07812EA902CAEE99B899B39E88FC7FF6973311483F2A9BAB7917A56D2CBB549AA887E545A7554910947CB9F09423C75EE63B626E8BAAA7A00890340DA33B7C2CB6052B5CC47CE65A0873CE9126816D8BCB6A1C8D39265BD1797F610244C565670DF05E58760690D52B6882A9A303582AA03ACB3B2D857CA0D7B8A2BF859860DB729D2740FD87AF798497D558042319638A33326E3C5CB0D3CD6E71A346365B308221A1DC2E49F51E818B22ACF66FA0C586958CA78204A1FAF135F17977ED2801C4591F2893A756A0C4988BCCB011B389D0656A717A069BBBF1F893A3BB64FF28B66BD2106FC23C2BAA2E4495580D08C896A92F2AF36CBB13CEF4AB94E4CC9D866459BF6CCCDCE7912B3119EEF0AD4CF5093CD85674679A298272EAD6B14F2950F18C602C52AB821234F655419B843C31491C47C596596967F1EB036550A941A03790874FD8498DAFDA127C8B0561116F9D414171778C7C36012DA9BC543158A00352A2E39D802CA5254FB4A43FF40242ACA967C85D45EE0F8E13DDD9951336DADD5ECD8D9B32FE7AB08059F4D70A3AB29FDAA5385C32E8F39DA46953FF323FAF2E6A0E461934F91330CFBCBD4CF4142F5CDF2065476376506BA36FA778DBFB29077A", + "c": "A07E5CA46B6B8A0370B19BEAC4FD58C994AF463C5F773D1638C3A296CF17CA8C18F3A0AB8E1DEBAB9E42995471B0EC8B473AD1F54EDDC84F48DA0EB534C567A73775CFE32F81C94246D991FA1E05EC6C31AA0B802949D5D7D8E5C4D7EF65E3080C01946F02CBE93F65BBAC03898FD25CDC32010EC4BB0119E30BF07F71A38E30FB5091F17D9F856653263F1982F526855324B6898C2671751DF332E58EC54C903A6BB6BEA0C96263913025DFB386651E6187BBDDB1FFE726C0DE8266FAF77384D2992E5EE8DCB31F41044754839C4525B9DB85B57E13F8C02120816D98B1C220687287CD7192C4DF31327676DE1D94C4EFEBEF3628E5E444386ADC087773ECF0FC79306828E58CD5A64CEB419EF383CE920A6FBB59ED2D2C86A78A069C90F9D52BAEBF4007AFA02C1D541BCAF0C8379D1788AD0AAFD6AAD91F4AFDF9C1C165CAB4EEC304DF6FF9F4E40E18F20FB78B3669DE6C0EDD35A38DA399BCD513C49A07F517AB446B19F4A0D13905C3D496CCCE68E8E778DAAB503CADD99B10951D417B5B6A3753CF9189C2DB624C39D1913F97C8ACC47A399DC2DD3539B083A7EDC3F1B7968B2D342BB78B0D8D9B2D026273D8CA46930A98C113E515F9FF779D10AFC857E44A0E190F90DF1E9B2AF4F5EAFCB451535AA8046CC7338722C29E729E93976D097C0BA766C1C977E20796472770BA41F4964107FE11F9412EA5846E512A7FFD42E71BF50DE6D8D86BBF01EC2A867006A0F881AE97104F2E476244A869C1FF895DF12FC04DB5BF2830191E1CF58CDED8EF7494C9E532282B36C6E72D1F961ECABE75CE5A572E30250E73CE74FA5A2D3C9E5DDB5DBA93865BAD0A219A3A8670D3EFFC7CA1119F383F36768CAD4B514E0644DF95D2E7EF768D487FB98C73EB489D79EB8849A96AB0E84B8B4C97464E7E1BE4F0CCA859BDDC3881DB30E333B68CFC90D8B472E577983544EBB38B729CA073FFA80DE085C861668B7843E3576BF89579A1B9FE0CC7884675A2530D5BCC38E88136A50BB28C491BB6579D789106315C91AF1F0465FF5853D1D1F9D762514523A80559A90DFBD682C4B0E1F522D855", + "k": "70D18ECFFEA01D8C2D4BA32516A042A925618FE4A3A69FF7B932361EAE5C6B47", + "m": "1D51A0CC52E85972001B77047D97DF5F47AE11FFC6C31B4AF42FB0791A3DB40F", + "reason": "no modification" + }, + { + "tcId": 8, + "deferred": false, + "ek": "28D9320FC6A5EC10059D3A531C364A99CA5A13CA98FCA773FE3B4EC6851E29EB8C0CC19440922CBF26859DAC0801FB0D0868B7C6C2917C51B7F644B4CE2C9C8AD9697D1102496B9B11B012105915C1A897065B05E6E7713740A391FC2B486249779864C74A1820F34C44063E47C87278C696DE5260270901190A5A618CAED0DB8B21D15C2D0552678833C1793070128DE0E43257413E99A1A58BC50323B0C722D69C36E82659410683CA4107C51D2D2126156C7357586EA553CD88CAC0E4530EA66B1FFBA700EF3A85259B5FABA131517CAAA0383028E125DC1670FF7C62D74775EC58A5B2B6074794225BAB8BEE7C14FE950AFDBC33B9A6CBE8492B3EC2BC16734EEADA20A45C07ADF81FE3401547F06603018BF5C4AD908AADCD9B5FA1D08244D922EE3AB1B3C693335AB64060369E328D31EBB3699BC3F390363610B2333A61BD67CB7DE4C6050C47D6D1402E7B997EC2C2E9B76AE5C77DF610A893183A1117747B3927BA7BB9B9ABB00E0B7E376C3310C3A63CBB03A2CC4BE1265CA35BC4D5C0CEB4187E9F686290472E9B0264B110C80F7A5D5C34678A746A5C4623CF8B54021A725F2C96E4923C2F531A7AC1405E275C44697A9C794625878F4CCB5D9DB9CF903C4F9DD180D0CB25D09AA389675A972223DBDA0435169C8652967C74C583223398F34E86D46DA0D026F5D661A4C4A85A85AD3DA358ACBA0B7E6C9C25D2CCB1A89B5D35A4F6516349CB1E983B793A04BC495311FF7433CFB8BE2722965308014D914014DA39322C0844F3C657804F9561274936B6556A639903808F8495F13C1138DBA65B573327490D8A772961B70B5C6CB4F8906B1B92639AE1AD25045CE5401AAE924491108B81044ED9E6B996A991AF83011B39021FB177FC8834A244B38C850C6FFCA4BD2323F896431FE64658B45299C280CF02894DFC03593135E172CF5B523734153E3CA24D160CCD64340AE6D021C21B8D5B98AEA0D9187F85AE1E5B0D9B06B1D1B12EC223B35FB2B07D81A42B11120A869C0B873831A41632CB0C1D819418647BBD92712920CFC2F24DC7871A194860105A6F0E10302C391E1DC2FA4BAA0C8576BC6E55F40A12DE2944202C00C192B497300E587946F1FACB", + "dk": "DBB9466138876E21BE1B9311F2D37C4BC447ACE23FED0137DF657CF6A396BAAB372552BB03B6AB73F6B534DCCC9CC9A40740BB0D833D64220340661BE56346C9A6A6B2E9787D5A588D1B8721218075048146F75434936CB948A8A66B5DB020C54B542D03BB4C0F352E0377B171AACD222259AEF33D2DD0A341C2BFF5BAC187391800363AF7EA21A6E535C6E226FC50661B85CF44BC1782E74963C4329D785C8661CBFA4B402CC9493A2042CA0743B156C11DDBCC2B1667EDD786C3C73C83C793A069ACC9F9CD353B94F88222A732575937B5BE0B23FAF5BD1BE1A958D77DEAA54C8AD5845E712241D92F8D1218E4070E527771495277FF0828E3C8BFFEC984832141A49264BF146FC9CC9676C59A8EA66C223888A3835932C39C7DDC15D2862C5EC54F125C799C804E6839309FD446C65A1285547662E79E54389030874A55EB6AC6D488E45863E6259D0473366E7A228EEC9A2BFB747378146010B78A712098E81F3FE0666A4669DC2B1BF9FB2BE6444AAC940427D764153575B82A143DCBB78B2097953731618A947F7057949A2B9890A43B702C052C61A5F35BA53825C02C1685A0ABCFD378F232A5251C38444B8F8349A860D67499B832271457940C8B437529D92A92B7676380628394244A8D55B4B845BBA7A674675289BEF6B1DCD532F42C6C9CE199D2AB0CF0AC4FDE7BA0B85266E540A651D6264B0A071C3C3DBBB0BBA579B587A0CEAA6C4E30305888C3BB9D073427173672063D8D5751BE6133996332846264DFC5092DA38246A74BE3A415895CC978C7A890961487650177EC32F6E30F5BFC928C2B36D7181D8F925266355A48247C4DB35E099363D303C157122F5606180C8AB08200CBBBD19B8240CDF7110C5F558F61565DD920213C60A906370D9D5820987AA2D0F00264221B5FCA7EB791A9075552FB015CFE3582B0A37F8D392D8FA3371531B9AEB54B07C0521CD9BD625669D26AB998E354CB1A5FE0D058FC866D1C67080FF99F1163917FFBCBA3D16D1071A895FC87967230A40BA46610AAB97169085700BE733346758E9B567C11C93C334145A37BB65F55CF09849128D9320FC6A5EC10059D3A531C364A99CA5A13CA98FCA773FE3B4EC6851E29EB8C0CC19440922CBF26859DAC0801FB0D0868B7C6C2917C51B7F644B4CE2C9C8AD9697D1102496B9B11B012105915C1A897065B05E6E7713740A391FC2B486249779864C74A1820F34C44063E47C87278C696DE5260270901190A5A618CAED0DB8B21D15C2D0552678833C1793070128DE0E43257413E99A1A58BC50323B0C722D69C36E82659410683CA4107C51D2D2126156C7357586EA553CD88CAC0E4530EA66B1FFBA700EF3A85259B5FABA131517CAAA0383028E125DC1670FF7C62D74775EC58A5B2B6074794225BAB8BEE7C14FE950AFDBC33B9A6CBE8492B3EC2BC16734EEADA20A45C07ADF81FE3401547F06603018BF5C4AD908AADCD9B5FA1D08244D922EE3AB1B3C693335AB64060369E328D31EBB3699BC3F390363610B2333A61BD67CB7DE4C6050C47D6D1402E7B997EC2C2E9B76AE5C77DF610A893183A1117747B3927BA7BB9B9ABB00E0B7E376C3310C3A63CBB03A2CC4BE1265CA35BC4D5C0CEB4187E9F686290472E9B0264B110C80F7A5D5C34678A746A5C4623CF8B54021A725F2C96E4923C2F531A7AC1405E275C44697A9C794625878F4CCB5D9DB9CF903C4F9DD180D0CB25D09AA389675A972223DBDA0435169C8652967C74C583223398F34E86D46DA0D026F5D661A4C4A85A85AD3DA358ACBA0B7E6C9C25D2CCB1A89B5D35A4F6516349CB1E983B793A04BC495311FF7433CFB8BE2722965308014D914014DA39322C0844F3C657804F9561274936B6556A639903808F8495F13C1138DBA65B573327490D8A772961B70B5C6CB4F8906B1B92639AE1AD25045CE5401AAE924491108B81044ED9E6B996A991AF83011B39021FB177FC8834A244B38C850C6FFCA4BD2323F896431FE64658B45299C280CF02894DFC03593135E172CF5B523734153E3CA24D160CCD64340AE6D021C21B8D5B98AEA0D9187F85AE1E5B0D9B06B1D1B12EC223B35FB2B07D81A42B11120A869C0B873831A41632CB0C1D819418647BBD92712920CFC2F24DC7871A194860105A6F0E10302C391E1DC2FA4BAA0C8576BC6E55F40A12DE2944202C00C192B497300E587946F1FACBFA704DBD0B4F1351219286AA8A868F5F17C01DAFF0AA77B36857D416B7CCD47EA078DF2CFDAAC3393EB22F912F4DD6B49366F5C33F3FFACBD766EA7DC8E2EA48", + "c": "B687F42683C3C4EC4D178FC0B437B20E0612D06B76E78D3F74CDD1A3FFC75D5CAD7271CBF01C65BFC917B214CFFE0041AD9E0ABAAAD326746159E02A81567075CD4EA0B3ADC31DFD8F7D85099E2C5E43CECC717C9D9AC27530EBF7FF76D529A499CE1DA92A15AF94261076A42696A24708C8314E9707D14969BC20F0FE15CD26BD53793A24220DC346526884027C2EB342C680DE9F6CCC816035B9263F8CA25F47E5FFBF564C08CCD4C2CBFD7A53C68BA6C8429093C0474D9840734838664C7250D1A19DCC381434BDDE0DCF8403E7C5FB4F79DD595DC601BAA787173F5946F9594379C2D81DCA8E460D46A19E5C6881607BB08DD66DAB954DC5650EB18ADCD3AD5C4E50DD88EB8CD224159748EE0921EBEBF569C91C0CA37151BFE3688049F791D7389E7E8356611E6FB2221C407F3AB2C8DAFEC6B7336BDF115BE3F2A6D22A852FFDFFC258DA596A1C760672708D16A0DEF4902538EA39FD8D34D79B43F45236D265DDE44B64AC3A6106652FA301F2A5E8AE8E5D181812EE0EF7039EB6C34E954E85568BC882F0AB4EAE260621FE45B79C2A71421A3CC73576439F9B15410A62DEDB1E1C1DAD45AEBD86C6B91E0C6600D28590BCF8DFCB5222890DC48AB7931136AA5793998C1C7C97267B460B5E7726EC03287BCE6A815A5CCB408E2C945BA6E0BA9539C7DA8182478F2F466661B5780FA99C875D9B0FBA379E43526B479B202313728EECE94B3EFDCA70696AC99EE56237C3E5665A4495AC4BAC8B9E2DC1386CB2FCAD904EA3BA78B9053E631D8F84B34BDAAA590D74705911E27D14B012BD85364E2CC2B92E11852B0AEFB3CE7082998C7AEF3B376AC05984091BBFD25697F4F1161C7379B84C8F0E84435D3023782BF65BB2DE49B32A7D432310C87AF0D79B1CB59D86EEB8EA100C17CF92EB85881E2A29D17363EE263F787D8BB054079161ABF904717024B40293B1E9064CA9937805BAC81B4ED9809557CFFBDB1E68F39E4176046769C85124A66A78671B9BB2B105560883521E2B000B423D5AA9D94945BC0480500BE1BD0F2F13214AC13189CCF95A6EC0E825389D4462AE9B7E7B", + "k": "82D886E17A88F82C66E8B1E7E329CC61EB0EA64EE63FA02676B362F8DFF29D51", + "m": "BC2D661E6283B835BAEE160D1448957AC2366DCD087176E252F81F1D11E28781", + "reason": "no modification" + }, + { + "tcId": 9, + "deferred": false, + "ek": "70A72E79BA178F8951F762242A240036093906A0AC1F2501402779AC6315AE8A0BBDD47A8F347A7E8840269157C93A00CCE5A27CBB16AD9179798376BE8638FD97C976D3513F96B2F0542B78893644793185425864C7950E23102BBA9A4BC9B14F2B4981B673F8C55480FCB4B834490C9BCBCAC7566747A38777CAA5FCADFE9710D8627236E52D9B5463456586E4F963A7308040EA243E62A8EF87B418D92F95D41A57AC468ED5CD51A2B643D11E8F03AAB4F43F2C8160A89B5ACA63C7C9B59E2602458AB103AC58085EF7A98465884BF16A662342BAC721C1E59EBEBCB2CCB9A4FB8A3A650C52B612243D133F870613BF5A9F30095456247C34C779C899B6CD17A181903E0BD1A13AC73BD2848724F25EC2EC037852CD6A960E2A3509E982513FBA840D28BB3B732D76C5909B6612A6650548C709961368F8116236B6709AEC97F7C625094B93BE5B11E9217C8E845ACEF8ABE3742724969C74622C5CFA7776135CC2616B5079AE4535C39C1A3154866AD548C950052B88888761D846C6240C9B3BC0EECAA284ECC4499660DD2BC1B3959AB943612F35610EF1688C41105693061BF16D6E290BFD4941C0460FC173694538604CEC6774C9614EF16B08666ADD3916CFBB39B4BB75EFC166C7E8BF70AB8B872630AC554028E8C147BBB56D3BA312029A68300CC743B81BB35878B26892696F538334BB0A22DC91391D71CFDE723D9E813B2EB844B6A534280880C37B9421572A6B85AFB8AAAF5AF0BACEF356B7F32636B50B3336B7636ACD6C685ACB178AF9986BCB93BBF1C4C69AF1AB569B60B133A480D39B4BA319A6535CA92293D5082ABE76204C7420CEE02C1D372D0413B9F8368098104120D432CD184550667A976C9DDFE0916D423EA2221E64FA95B3F254F59359BE711087732B7D8336B99CB95C7BAC714742D0595BE953273E551D1122AF9B49495DD1B935255726A643D2F8A4EC9A6F573A97C8507FBE6754179A9439C33B0CA5BE3DBC9F19A18C3253A6830C6B69821C86E38A71CAB632E0A578F57A5377015FF43DEE85BF9C67591A1CCAF2C6917387C4B5193404C87AEED269310ABA894FCF51793DDA786F80CA209AE909B8147FAF316B06E4AD8C516BC83B", + "dk": "E2FA96EA25A100737368D8A9D7C3B3CE4C0085DC98854BB29306C45025C0CEFB64EFC64688D46485F8CEF9A81C8D4B53A3BC04DE05BA93EA006A760F55FC46FFE1B659A14FBB16AA00CC1EC3ECBD6C55CB64055F95B8308B690488B146669308C3C3B82D59736CA2A204F07D7984BAAC0109868C666D8644D4A29F0CB02F9C50853428A2FF773E7534989DA2567D044AD9A353628C107D9635637AC330C5A5ABFA1D548C6D552199746C0770B433848258FD185834C309DB32588E57250E206998C8783C177D8DEA3DDBE3473FA8688D7065E1BBB3F5EA79DE04AA4EC5AB16609FB3C4CFEF1659AC60B00765B38106A860506DF15C20E3D474546559822B91D5208CC03931B2C81F54122E9AC68115FA5F608CC0BFBBA7CA4211FF330154D591A48859F39B68BA36BE285B1147DC45FBCC5147A84C42315E4A412BA3D28D537C54AE295CF3400AD400807A38270578692DB112BE01359BC1CFBC001A6AC9AA070B024DD2C6E16B10C3987118F680389A34DC05606CAC4192599D2360125093905FF719A3792A1D83AAC0370A2286959C0B00A7371FF96B9035415DFCD6A0433B19D36800489C4636469BB195C4EA2563B2131B22AAB5059A30A4648E2A956535073E08376650024E52A72F1303BFD1393C7B7C2D320C74DDDB36EF035DDB3CB81F74ABCB2616EDB97FA96AAF8AC65311F790518636D89A80CA289FBFFB2B9E899A8169B0F855BA584263031C8CB5D7598AA43FBA3214FF490D56223168F6BE27557277734CEB673EFED604EF647990A27C0D8B5AB126649E3590A6F5588C7468AAFA7E4AE1C01BD96F66A645B88565310C3CF917B512C22A19589929D867D977B5D33A55DBE92C13F28FF92C6866CC4E75528CC7F5AC58FA4CE523435E08CAACA26CB71B9564C1B167BA48D9E724032368FFC29D8B15A695903210F2300B5415AA25A7034BC5E35B7C91670164DC5559185D489CCF9F168F4F175AB1F2B42249B95589474D8C9FC7EC1D15449C233A41F7A0CBE9284866A7B47170BFCCD2052F5838391A15DB0018F96CBAE3356356BB00B963ACA97A1E15757FCA358E63453F70A72E79BA178F8951F762242A240036093906A0AC1F2501402779AC6315AE8A0BBDD47A8F347A7E8840269157C93A00CCE5A27CBB16AD9179798376BE8638FD97C976D3513F96B2F0542B78893644793185425864C7950E23102BBA9A4BC9B14F2B4981B673F8C55480FCB4B834490C9BCBCAC7566747A38777CAA5FCADFE9710D8627236E52D9B5463456586E4F963A7308040EA243E62A8EF87B418D92F95D41A57AC468ED5CD51A2B643D11E8F03AAB4F43F2C8160A89B5ACA63C7C9B59E2602458AB103AC58085EF7A98465884BF16A662342BAC721C1E59EBEBCB2CCB9A4FB8A3A650C52B612243D133F870613BF5A9F30095456247C34C779C899B6CD17A181903E0BD1A13AC73BD2848724F25EC2EC037852CD6A960E2A3509E982513FBA840D28BB3B732D76C5909B6612A6650548C709961368F8116236B6709AEC97F7C625094B93BE5B11E9217C8E845ACEF8ABE3742724969C74622C5CFA7776135CC2616B5079AE4535C39C1A3154866AD548C950052B88888761D846C6240C9B3BC0EECAA284ECC4499660DD2BC1B3959AB943612F35610EF1688C41105693061BF16D6E290BFD4941C0460FC173694538604CEC6774C9614EF16B08666ADD3916CFBB39B4BB75EFC166C7E8BF70AB8B872630AC554028E8C147BBB56D3BA312029A68300CC743B81BB35878B26892696F538334BB0A22DC91391D71CFDE723D9E813B2EB844B6A534280880C37B9421572A6B85AFB8AAAF5AF0BACEF356B7F32636B50B3336B7636ACD6C685ACB178AF9986BCB93BBF1C4C69AF1AB569B60B133A480D39B4BA319A6535CA92293D5082ABE76204C7420CEE02C1D372D0413B9F8368098104120D432CD184550667A976C9DDFE0916D423EA2221E64FA95B3F254F59359BE711087732B7D8336B99CB95C7BAC714742D0595BE953273E551D1122AF9B49495DD1B935255726A643D2F8A4EC9A6F573A97C8507FBE6754179A9439C33B0CA5BE3DBC9F19A18C3253A6830C6B69821C86E38A71CAB632E0A578F57A5377015FF43DEE85BF9C67591A1CCAF2C6917387C4B5193404C87AEED269310ABA894FCF51793DDA786F80CA209AE909B8147FAF316B06E4AD8C516BC83BB3E7410628F44018D9DFC0EEDB18DCFAC7847E688013C039343B7FA08E0F9E191F64385D36D685D9D38D2A68F5825A84B881DECD0CE337355956C68C7F2B32EC", + "c": "FEBB296071C87A2541D8C0BBEF2F132BC433D608E04E65C035055494F9D3AEE01231784514801870A66357792C0F73238C18B99DEB53522AB3DE54A40EA37D24D62EB782187CCAE51E9DEBE131910ECABE37F312D6FAFCC8A5C1091C0C80769CDF6ADFC3A1C1F3F11DAEAAB65966885B193ABEB6D2B1A81082BB171713A983F073346E672D9F51ED6F1F1D71DDAC85B3A8188B37956709240C78D1EF276E6F534BFA98C52DBDD43E0506F665319506D11642110BA872A9DF8C197ADA9575980048639C930F29C9C45BCD7BE9774B49C2FBD7954ECBE0158D1B6911ED7FDB4EA3FA92F63BBBC34DAB800B2843B5BDC15B2EDECF6DC700A304B31C8E19049EE0371BC9A22E3F6B1C710BCC3AC662148FD9FD729DC3C339E17C4123EEBE60A36269AF28F8A81136379E76C35903C3E017B40E38F273D1B95238F71FB2D2FE6C880307762CB855C0C1951DD2C2779DCEC5285052D60CFCDE76C73B3E95F1D4868C491C71928A3DC04455F0B7F10564D4D65F358DE0AEF7C27D25E89B89E85F6A0B3C34C8AEAC06276F93E4E631EA6120F4E0130F1617891F67731075F6438DF717A4208E45DE930CDA28B737F902C3CC1592CDDF805FA269BC0DC98C40CB9DDD24AF71EAFC6B0B10C9EF2CE262F6D4A22F3C9FAF2553638DE522E5207570248FB87AE1C3DF5144F8EC2DBB4DC57F1C5F74D401D92D0F9E1D7AB98A6BE2090169FAC2C9FC9C6CFF726BD87C3FF2565052C85478FF53CE69EAE1700254AAA94125FA1B7236F4D9258987257B57988D8091AE2B0C06732C8C9FA35C2BC0896EE39825CB2C1B889EC496CE290DB565F403107E58F3DB1B2D40261EBB52492F11E3AEE9B755332B1A000595AF766AAA3D15116865BD3C6C1FDE48A149766BBE0381498B5B2BED28E4E8AA2C87FBA08D28AC8AE64ED47E8796D006169A90CEBDAA2DF63C8E809F169ABEAA9662349D740312B7ED2F26B7762352DDF8BCFF3E545DE5CAB29B5057086438944128DDA68C36C937ADA250A1826532231082E7CEEBB082C62E0BC2E1424D14FC40E057A1591886A6141C49EE309E97AF0C64D1F70FCF8BE9EBEF", + "k": "21CFA40FDE8834A21A9E419B7AD8B9E1F59B7CB184A0CC18932523CF45A1CA75", + "m": "6745F4F0730AE3F14A428A95C9CDFE82717EAA94F65B00A01566A4DCC9ED1E5E", + "reason": "no modification" + }, + { + "tcId": 10, + "deferred": false, + "ek": "5E101D0614A50B307E1AEABE717721690422A1A97C1D05713ED3B206D57919AAB32F6096A503C5C1C1BA332063489038FD1BC7F7B816F6F343274C19E01B1F9C088B311A0C8C09864BEA142BA2C829C5B74C988266BC9F12D37EEAD97FFD48AC5DF0C7C595A5626A23E20663E8F11A6BB66BEFF4A91D6C7CF551B34DD541D3DBA1F16BAB95312A60F9625DDC4FF1C6690E9B05FCC5CE05742D65D5915740AD9A7B60F9D098AA62A6DD3968DFAB5ED93A54E305596AC8B1E4967A5AAC15BB4B540C421571EA324FB422990C2B9B82A12915745C24BFF841731C6C07FE705CCC9B4C15EC42193472A4542ED5FC0B0CA98A91B7CDEF68A6E7ABBCD07B984795151D72365F31BFC76793FE485FDC663C6B7CC43F5A9D410BAAFFBA43CA968988337C9BF802CA221B3C366A22E66F703C695B178830473D7C372D338A4548E7C88A9C4837860419A2B60A3CA9AA19A21B570BD22CA228C019EC6420E77B340F32265BF86A666C9FFC75B64FAA22860B205DE33492B1720BE514BCD5A47496BDEC246D97ABC377430528940BA447579A90C9E18152F69BAD12CB7C51C48CAA8BAD1EEB2867F31691B32B75528056E56955BC4400A249550569C722410FA2573007BCD2B7331648AC9B424667582131473C2E8B11D1299DB6927384B257A81B6E7868AD00216C8548739EC83485CB330B03BE99DB38EDA338C6240828D7A5FF463B1C0C88092CBFEF3A2598993C72F922F2EBA31FEC317570B73DBC53C7F04810878FC9718552CA2C5B7220B6B7298886C94D9C8762A4BD05D8BDE7E9483850C0F75617686174D42CABA69B2968004992467D1CE078B03884F9E00B901473E7059195487C5E3BB0B938049A257C8046B92D129A906669BB1B92B1A83FAF951A9E8332A1833D665A720D0451801874036A7A5133318CA94015A63FEB52C40158644C3869F2E37BC18160C8ACA2381BB9B20B5A58961AF2E8593884ABB47A6D968A8C6BBB83CF089C6B75B6522C77B2B4064EFC50C2948A18C85B1436787C3A076547271F33B864D5CCC585B317193572428FEDD54B923973A11287B6527F68535DA629C904AFED0646115879DB4F48777D2CCDC3784E28834C7E503964FBD58C3652152D", + "dk": "09035BBB278F4BBB6709E427B18149B8D60E9697BA4DEB42DFF673B87682244B907B476132C8914F26045F1794ABF41234F829E4C38A3E1007FF6C74CDD639057185AF8A419B6C56129101D4A428CA92BB42481F23F5888C596ADF8A0F51BC42BBCB7D93305D072832251466D65C864B48794D126F6EFA34FC22592FA2A843D1AEAFC5B7B84CC982CA54B0C62A4C083EF545BB8B38B7F3C97BF9067277A5CB65B0618192091159200A321948415C387B7E4D65C7061331C65A29FC323E76E11E2811A76788B1B811BF7B17952820C077954A6F731A1209A4F5F68A2059C3E7969B01FB3A2FEB7EBE0C304F2C604DC0B1628A839478059674574DE82A35B0B55A22818399247DFA2363161EF981A2E2E117B3B1A61EA42ACA4A6030E5C139D663171867AA364E7DD904AC9BAFD69B480CD35D1A9964CA5C96E3D0660E10B51E805605968AF4747D1414B258190CEBC6C87B1C476AC9B48A0A8161F66E10BBA0D2FC619C415A0846346C9AABFD2B25773A40B3A242DE25004001CD409B8E5B99C0408ACCD8127355790E0D9B03A7AC3BF9F54E1B4466DA83CC0CC7920BF583DCA743568907AF8B381B4553EFA608204A86FD59A03B333F8E4049D3FC36E04A89EF2091169BCE577368043C20725861E7D76C68497D9EAC7F2838B0DF8CB44A829C1A89A7030A3D5BE81F480275B2DBCE88BB08435446EBEB5236C1A38ABA7B1F64304B289AE2073A414434F7521E44B8CBCCCC4784B16649F5B63812AA5C723B6C4024FA8BA361E44DBF21684FCC9FE99BAF2B71BE70AB358A867D85628FA4402A97B836713036AED2A8C14141424581917B6A88A48B9037CE5AD49A4B3CB86972BE77A83A773BB64E63B8AD552E97D9604F596E1B64A891B4526BA6B9C31226C7B491F0C529BC93A2E5651FC1F5C02F27A800683E52ECC087121D4A515864A8602E3432761A385D7355B20475804B98A193BF503326EE3163821677FBC371DBD76502398199D1577C576DD7128BE9E7621AA7BE650A1A4841262BE23A6946A4809875279A93107589C8821DDD23B0C0EBB16FB047364221E3C1671F32325575555E101D0614A50B307E1AEABE717721690422A1A97C1D05713ED3B206D57919AAB32F6096A503C5C1C1BA332063489038FD1BC7F7B816F6F343274C19E01B1F9C088B311A0C8C09864BEA142BA2C829C5B74C988266BC9F12D37EEAD97FFD48AC5DF0C7C595A5626A23E20663E8F11A6BB66BEFF4A91D6C7CF551B34DD541D3DBA1F16BAB95312A60F9625DDC4FF1C6690E9B05FCC5CE05742D65D5915740AD9A7B60F9D098AA62A6DD3968DFAB5ED93A54E305596AC8B1E4967A5AAC15BB4B540C421571EA324FB422990C2B9B82A12915745C24BFF841731C6C07FE705CCC9B4C15EC42193472A4542ED5FC0B0CA98A91B7CDEF68A6E7ABBCD07B984795151D72365F31BFC76793FE485FDC663C6B7CC43F5A9D410BAAFFBA43CA968988337C9BF802CA221B3C366A22E66F703C695B178830473D7C372D338A4548E7C88A9C4837860419A2B60A3CA9AA19A21B570BD22CA228C019EC6420E77B340F32265BF86A666C9FFC75B64FAA22860B205DE33492B1720BE514BCD5A47496BDEC246D97ABC377430528940BA447579A90C9E18152F69BAD12CB7C51C48CAA8BAD1EEB2867F31691B32B75528056E56955BC4400A249550569C722410FA2573007BCD2B7331648AC9B424667582131473C2E8B11D1299DB6927384B257A81B6E7868AD00216C8548739EC83485CB330B03BE99DB38EDA338C6240828D7A5FF463B1C0C88092CBFEF3A2598993C72F922F2EBA31FEC317570B73DBC53C7F04810878FC9718552CA2C5B7220B6B7298886C94D9C8762A4BD05D8BDE7E9483850C0F75617686174D42CABA69B2968004992467D1CE078B03884F9E00B901473E7059195487C5E3BB0B938049A257C8046B92D129A906669BB1B92B1A83FAF951A9E8332A1833D665A720D0451801874036A7A5133318CA94015A63FEB52C40158644C3869F2E37BC18160C8ACA2381BB9B20B5A58961AF2E8593884ABB47A6D968A8C6BBB83CF089C6B75B6522C77B2B4064EFC50C2948A18C85B1436787C3A076547271F33B864D5CCC585B317193572428FEDD54B923973A11287B6527F68535DA629C904AFED0646115879DB4F48777D2CCDC3784E28834C7E503964FBD58C3652152D01E6E2FFEC99716B96F8708E8702954EEF4142F1526CE74057D0049AF5D0376D8846E9C3DB8A50D814B91408C2FF732842F8D8DCAB2AA5CBD2848D44A65C056A", + "c": "8830427E2A9F37CCFBE39067C9D14B9404B83F9DE1BD9AF3E167D2053FD526F8534FB8960B8425CBA720065307602B8E89EB9810D7436CD44C4ADF87EB25F8B8F87865325383238931ABB418580D4774D645C71ECDDAC6B9F4EBAF3410DC142ECFDC357CB3521E62EBE0EF28BD41DF94A593374D8B9EF362D71A7D5AD6300E9C31514B5DE5AAB25E421646E152D5EE9A530F8BE6D0FF5D77DDB93827E525862437A9B6593ED284AFCC8453B409745DE7AB21FABC824307CEACF7D68D9E0EB54E69C98E3B94C61D9B0B84EAF064A966A7F99746EDC93F36DDF7826FB08C635891861FEE8D72A4FDE67F5BE139044BC775E73E7CB2695E24D81D84B2274461EC66E6A7E62571D306A667BB7C6F53AA1C3D403E2C6D48E03B29A164DB2AB7ACBB7F955F1E8CA6F836125B386453E047CB800F65656684FDD5BE79A8F12A2C90839B6EE89D73EFE016C09D878F16B92D62819B85E4275637305BBCD4FB25C578FB5CEDEFB3F9DB6165B5211623B2E53B53A71C5C2EF62A4255BB2E5AB6B9743353D0013760F89CF8A07140EC75D6BB8335DC3E1D2DC1393E43535119F3661F476168522CC25C7A702B58967113771FC6EC6B0F133DD349209C35012AA380819450487670359A906529490000F7B7179C8B6B44ED64C5700B190FD2B80E089F81E724B560E2F9479F8CA9C325B2D0E3873458E9B387BD1B2D84BF4CADF8924F55DC9C410871157B9999E0F580DEF7449F4CAF080028DED23F5437ADD8C3BF004268C9E6BAA21EF9F9C117A543E946D469A9FED47AE20524C3110D1F968A02A8C1DB24DE10316D5C2C0C28A10A043A1FC6393D7C0D6F2AA5DC379D64C1B870A1FA8D543FB17F0E5CF8F174208B370C6A4C44FA851CBA345EF09C70DCF5CE5412BC11A56E4FCC38A48D9BFF662DAFEBE105DDD686575DB01A1AA327A35E64B1DE9F55D1B3C6439E5A0396DC60A2BEF31D52ACEAB818B7068456FAA775F3F3D0BFDB4E78A3E3D38FF6162AC0AACEEFDB04474C93F071833BFC0DF73E0EB4B3A6AE04B87EB3490151A6A1DDE59BB286D449347ED0370929059D775E7909E8F35470DBDC6C", + "k": "CEC6DF7A0A9B79894EE00697CA123B88C4CF94EDAE8514C8A024498E909C72D9", + "m": "C3ED79224CB07A8D37DC9C789BC7AC8E278968E429087E5B2C0E878934DAA53F", + "reason": "no modification" + }, + { + "tcId": 11, + "deferred": false, + "ek": "F3007CA415887CB8294B07BEDD802012CAB18EAC1E58268C821BA9A63739E64AC4ECA1A1CFCC7E61E73E72214981ACC725B3040205134A998E3B0168F46901788054FB20C88EA08F8A96B1AA86CCF2D778E3363F4202CD8C655A14C13D8F954709F46FB78175DA1C839C612CC94984D33A40A2B3CE56C28302E9C849CB51F8C60B614924E21B374A381F473344847CA1E4C610A538645EBB7CF3E1894CB2AA2EF2884F1CBF7734426AA315BD52569E533D374A91EE6A8BF8E05393EBC1506BA0718C40465A7F24483D933926EBF49E9A65C56A1B25F1A122D03A14F150C62EF186EE39335DB1A99D2498F8C552F32568CF714C678943D74651AE345513A4B4D1460040831603874CB281CFF1F49A3FD43EC80724560136C07C3392D4B4493726AB25CC00585B1966B8E73246ABF05D78C43293670F18B02EC5D107A8518F014ABC1108B60B3781AAD6BB5152B228A5BAD5D81FBF0ABADFC1B89047C3EFFC77FA5ACF0FE88CFBD40A5270408F20601A981FA666B1FF9B6324A47D67DA9621F60042C593725A604CA25483714AEE23A38B01AE7EEC4BD2422D7231157533B819F554BB76BF26D9A2EFC10C758B584B1B663CB91023C1869E5283FE13144CC3149F6A2037D53008F720337A58534360765038AC222F97B9C7551004740A5F526597712504FB2B102906A35375943C011C8BC4B44323CBC690A5814A385CAAC581A8530CB201FDC902546C924E1A51B1154EA2D56C3D898394A722FB3B962102262B9A410B12AFDCE8250947BC13A88B40399E05B025A9770D6381206D895E2D319D6C2A237A26B06C7302B61C1288EBABCC439A2B8284B81407BE18674102AA5569A10461C8B1E550ABF41F5773C7EBC8B2E2B968EDD56800B9AD3D95057CCCBEF4CB143489C219A6570B9A4CE23B6044580F7AD2CD2597B8EB5300AFC63C4DA2A98E1C7ACB57C2D7A06E836781F5CB86BDB82AE4CB1577A0AE5540B4D23B8EB100B02966C440B68CAFF36801B99F38649D3D8A49DA61C719D196888481C798B76CB0BEC1AA037AE4271E04BE54075AA51569D700A95254A8CFF1874522935259AF76CC7555A056505D0ED973B075E185A37AE9EC366F52023FE381ED83FB42486B", + "dk": "8B177D624AC1BC09657FF155207B487BE10A043371240026BB1578A6B96017F0BD124038F96422C1898C85C2B5ACA61292D39C1E4A472E99B5EA32631364C6B509A54CF0810FAA061F668199F32673EC6BCDE700894236B64B1F01A4A9599529E6950748830E3E64B9C1E12EAFD26147A86D585C35F56BB1B2689B30614185DC9E2EB96A72FA560EBBA991C36BD5D5B75CF2A7E217CB07AC500FCA1314470B99977248475BA90504EFD64D9BE624C3C13FF9DB9BF3E85EC9B70536451C2D2C993455C8F1061C53A404328788A80877D6BB2CD2432375B37D9DA1146A0904F7263D7E01429DC1767274A654699E862C4064F6C165C6440B3A9393315E8B74493A0C430DEA414C5AA1166B47CD611DD072A0E78A64E191B8C369809F644603C2C92527B3328B9C4C491CB92364E0B632A1F86052302DF0CC196D259828113977347AB59528C91409C2B15E9262966B6980A4FC3A472318FDA787A94B52D9499076D118D02259DC5A6A16D3B90EDB5AA88C40315C703EA52A4B227A2D7103C2C0BF0EB455442A692B3BB9DE56B6528B8DCF383569610872C9469B21BE123C7B30B251310BAD364272C4D7691514755C149EDB752A67854A7830A2B5E6C7913549A4B78709007F30178C832BB9BEB8072FE42B96AC73C17A55ED10CFAB0690AEE71739A8828EF27D3B356156461A9E406E864A931906AF731A241B8B55D344B7ADF93C0477B4A8EC41E82457798666DFB96BAE33876E384CFE3AAB021622599078F15CAD6FD5A7829BC87D20595A5430BFC6AB2B138D54BC36A6B58BE1148906C2566C5347BE340C71949DC849A0F38081DC0B7B7CAC8DBBA5341EC61A1DD889D262BDA734A0EE691063D0CB08045414E37548195C6CA41B1F69BE334638582441E3A3CAF965962277466CC1A5056608B72C5B6232B2901A93D615CBADB57F2265917A330EC8208BAF046BA2960B80E502B4F48ACCA6AA972528D3504C1696C6D4D116325361CEB15F9CEAC560019C3B3A8F374397DD17AE23588D40779473684DE24768EB628D38F336C075A2CD56402783863FA2827AE03B74A2B3B0C4AE36300FF3007CA415887CB8294B07BEDD802012CAB18EAC1E58268C821BA9A63739E64AC4ECA1A1CFCC7E61E73E72214981ACC725B3040205134A998E3B0168F46901788054FB20C88EA08F8A96B1AA86CCF2D778E3363F4202CD8C655A14C13D8F954709F46FB78175DA1C839C612CC94984D33A40A2B3CE56C28302E9C849CB51F8C60B614924E21B374A381F473344847CA1E4C610A538645EBB7CF3E1894CB2AA2EF2884F1CBF7734426AA315BD52569E533D374A91EE6A8BF8E05393EBC1506BA0718C40465A7F24483D933926EBF49E9A65C56A1B25F1A122D03A14F150C62EF186EE39335DB1A99D2498F8C552F32568CF714C678943D74651AE345513A4B4D1460040831603874CB281CFF1F49A3FD43EC80724560136C07C3392D4B4493726AB25CC00585B1966B8E73246ABF05D78C43293670F18B02EC5D107A8518F014ABC1108B60B3781AAD6BB5152B228A5BAD5D81FBF0ABADFC1B89047C3EFFC77FA5ACF0FE88CFBD40A5270408F20601A981FA666B1FF9B6324A47D67DA9621F60042C593725A604CA25483714AEE23A38B01AE7EEC4BD2422D7231157533B819F554BB76BF26D9A2EFC10C758B584B1B663CB91023C1869E5283FE13144CC3149F6A2037D53008F720337A58534360765038AC222F97B9C7551004740A5F526597712504FB2B102906A35375943C011C8BC4B44323CBC690A5814A385CAAC581A8530CB201FDC902546C924E1A51B1154EA2D56C3D898394A722FB3B962102262B9A410B12AFDCE8250947BC13A88B40399E05B025A9770D6381206D895E2D319D6C2A237A26B06C7302B61C1288EBABCC439A2B8284B81407BE18674102AA5569A10461C8B1E550ABF41F5773C7EBC8B2E2B968EDD56800B9AD3D95057CCCBEF4CB143489C219A6570B9A4CE23B6044580F7AD2CD2597B8EB5300AFC63C4DA2A98E1C7ACB57C2D7A06E836781F5CB86BDB82AE4CB1577A0AE5540B4D23B8EB100B02966C440B68CAFF36801B99F38649D3D8A49DA61C719D196888481C798B76CB0BEC1AA037AE4271E04BE54075AA51569D700A95254A8CFF1874522935259AF76CC7555A056505D0ED973B075E185A37AE9EC366F52023FE381ED83FB42486B5FA88098305912B30A55D51412219D3B2A6271BD46046F454AA4AE238431115880FCD17FAB3E190E96CE2AB5E42ADCEE8E516644801B0C0D42BA08B82F5E6E9A", + "c": "128FEFB85AF81CD2D9BE101E5B2C6D4D10C43C870A5E180D9E811541F16875B9D1D4842CD6B2A9555D16C7C47A1A30647BECC8628788194ACA88048B291A3A83CB5D4346C5D741CAA1AE631B59020795049046BA09C262D50896BC4D390F4963970FECB91DF2DE283EAD7CBA46F8DEF0AF5C9819B3F76B7EA1C653584911809310ECF9CB171F1B0C83F147D70996F57B18D0D7BF596983017E02AA7B465210B5BF402444167831D409D2D9A7CE9C24D3DC6CE7A3F71DD0E7F13F66214B29753D625A7874D4606B3688D8FDFDF0459034C4B61794EB476D02C375DE54E543F4C5CE160D0764AD5F001B4CAC7FEFE69B06B5DD4188D6A75DA0EFE81C8BF2B378F888BBD41F9976B56CEE9B6A30AC1F7DAED843FF1A6C209CBA6AB8CFA42E0270817C7CD1A8EE1D8E5552A5771A95B0C621666AAB4738897A5C35F54618D41E4BE592EB6E530228B21A09D56A86039DADA8A8D530E7D95658CF9C3AD3E2476FA037B38F8730EBA96423F5CDF884E9F707B18326A9BC9EE51072AEF8096B9D2CA9D2347E4981AE99ABAB9A2DEE0DBFE2AEE8BBFF5F2EBACE1899089B2AF44318F1530E2DB95F6A6004BEA7BA1643801C2384E254A4E42372E74B30CDAABA3A5A7868A43A91F58503C7DF9FEA920D8C29EECFCCD6D42332D2DF6E2A689865BA65A03B65F0E9338BCCE725BB3E50B28FBCF0F194E24D7EBF89FE4B7B546014667962D92FB7F33681110958A6F5AA0129717FE505C5EB2A009E641FFA73AAC6F214F9B75EA658D012FC638D7C607D6C8292140D856BC2FF86E5DCA2B357C6C92934E342C84AB22374E2C65C5071F1A29E21A3D346A5F4F2B6EDFC1985CEDAFD9F62BC44B07C42E4C34B24450FA07394FE067804775F98846E5F72977CA6B58484D2EC6A5634B2C11485DA0D4AC1F96226EC3920A3FCE229E801F2C9F175C56DC03059B00154A7540CBC4A538B700DD948C19EAF88EF6C206B5F58EB6538DEE0C87E132C62086F38C8F1E9A799E845E2A7472DD393A3FD455617A9C687C1503ED17D8E01C992F503A699249B81BCBA9A9F7606217BAFABAC90995A85DF6663A7BB6370DD", + "k": "9015AB2A00F4E86BC82E6B3F5208D45BA0A725876A9E19D52C9A43332554D3CB", + "m": "41C74E66327238C6F7B2ED2683FC5E88CC35083512BC285CCB7165499F34A0B8", + "reason": "no modification" + }, + { + "tcId": 12, + "deferred": false, + "ek": "A4F9A7CDCC7E700196FFF92085458D7D6855DCEBC5D98260E4C32C94DCAA47606619C6C02752333D30BCB0E82909D7657FF199668B8824C7B323A50D51203E97A944467930FEDC000C69496751C3C69A4FA4492CA6454665E56C9B677845D6CEF70A21DC7028C4D487629B9738C300D17995F839B59793A0A8813BF9012E0139BDD0EA31582BA31E070BC7F2B44FE57CF5F36CB9D92C6926B271C290CA44BC3068C2981C6CC7932A82E69C1AA9616D99C36CF37D8DE7642F2A0A615B6B85660224ECA4AA6B4779A20A2DC93BF31BB25582705B56B04FC1898CAB5FF97B6934158B4BD9994B4A1643F8A185483F93AB349536A29A3445250575CFE07122021AEB450DF71943E0818B664951137880AA5586C66260B835BAC540378374869084B8E3CC91B9C12248E2A75C060EFB6925C35A3DF34BB5A8E76B4FC4706DA00C2C0331502A3B4030A8CA25AC07EA139FB8B4733957784551208662250B542FFB6B6985A130C109FEF00E30D6C238FC0A10E567737B8776B94D3FEAC0FD9B055FEC78BBC4961015033CF78805872F1F9899F69492AF6A35180C8F8393071BF020F746506FA50E5AE7A675542610F883B24A103A32CC407933CC2160FBEB0375A514A2D405992BCC8FCB82F3799365D238E02C1886B9499CA2C90D8B33FF32AF51F5933F721FAD5CBF78EC78802C7DD06777DB8C0FA3C0CF09790F65630E772177D4D9A35718ADEA8758057601C249C92876799167604664BFAA93537572A6A1425BC0AC53C85AC64DD9A7BE436F110C3AA68BA0552994DC019F9AD80B2767B879C8B7D4664AFA6C937276AB40417AFDC2895FA756909864C4E1867A537B42E271C86953B16279843C88DB9385EFF67FCB8A6BA13025B259398F149B49E1A4A9271CD7C1B5F0C6BD7AEA36CC6739C2660E262A3189E9AD342215FB5A95DB2B179CA763A8AC500EF59A4A243F6E6C96C278426D472161C1069A31992ED9AF9B88275D21815F1584CE7381D487457CC15E04E13FB4B93F309588D238BA0B59867680585C043857516395BACC287491B0E65B1C175B41045F2B94202F888B103A6683BA958FFE411135C3552BD546F9E3AAECB8C783AB074E809056545A8F7B89E7BD8DF0", + "dk": "5260A5E1F6990DCC65328126BAE9BABC0B28E7010A2F9244362218C5E9074A331179B16A07676727966476FBBFACA90119722A168C6CD5A1619A0548C15144FB408C1099BEE94C25DCB119EC6A677F3B0D0D705BF8B7047C564BA5C1843378903CA64D1EE7357D0A2102865417865CC97C93EA5362B4BACB5E5604ADE8CF16E6A70F455A91D104E98C9D63273476C067AAF45B8739099C527B7ABBA56E9B1D939C8A776C4931A14B9B34907EB309FED94406145274738D7C061F5F7038CC2AB9AF6243C913A3CE212ADD4B983FB646A7732BF1B30BF2759CB52936C325CF475C47A6A54979BA2A17D4066D52A728BA6198CB52762829D85C56F0DC1B4352A191AAACE6CB1C26A348E45A25BE0C86A66B16DEF9AC236C2C03BA883CC80908F8586501C5C8D02F0EFAB2D9924CBC2B2935CC73D946A8A370362FAB0C8D94891D980CC8665290B7471D5477902B8A83A0C5B5B2A8BBA4622E272AA9FCA8AF59C40E109C682AAE7BA0C61B49C127629AB0628E402828E7246219AC368063660B1910C7D10CC5992501841612C44F4056B319044721EC9550E235BBFC6D384A9013C52C61257BB9D315F8C383DA7C66A4690C29930F6912665BB494CE63A96185B4DA193C1D58CD79A312ED57BD4E4A86FDBA31D87995C9409A6D03924D6C35145BB0233BBDE8A717E2291F673903839047C23B401FA680EFFA41869664F7F3612C552B01C9CB05D518E6010A744CB5756A31A50BB965AB3ACD62781955295D7C4A07FA13EF911DE93AA477952D99CBCCB3A83FB0E50046917506352B34158E8E451AFFCB9E31F7B800D00D23CA1A927C4AD9B57E0DC7B69EE270A063B3B286ABDAA22C946AC6C436233C6979C3570BB5889F39264017A63E09FB54547C5711B0B6C8576A8F1C8B013A0EF8190795F42E376C803EA4A8908605C8F51E07C3983A357423D594D79080C71AB3EF930901D31D6539328BA5B18725BD47E6AE466C2891F4C889426D5BD267A9B696EC4739C5F978619C786333472EF241353688A02C1154D4650C0C5E22C61AB77B0FE1D193573760720CB2E633868B0B114DD8CD03316DA4F9A7CDCC7E700196FFF92085458D7D6855DCEBC5D98260E4C32C94DCAA47606619C6C02752333D30BCB0E82909D7657FF199668B8824C7B323A50D51203E97A944467930FEDC000C69496751C3C69A4FA4492CA6454665E56C9B677845D6CEF70A21DC7028C4D487629B9738C300D17995F839B59793A0A8813BF9012E0139BDD0EA31582BA31E070BC7F2B44FE57CF5F36CB9D92C6926B271C290CA44BC3068C2981C6CC7932A82E69C1AA9616D99C36CF37D8DE7642F2A0A615B6B85660224ECA4AA6B4779A20A2DC93BF31BB25582705B56B04FC1898CAB5FF97B6934158B4BD9994B4A1643F8A185483F93AB349536A29A3445250575CFE07122021AEB450DF71943E0818B664951137880AA5586C66260B835BAC540378374869084B8E3CC91B9C12248E2A75C060EFB6925C35A3DF34BB5A8E76B4FC4706DA00C2C0331502A3B4030A8CA25AC07EA139FB8B4733957784551208662250B542FFB6B6985A130C109FEF00E30D6C238FC0A10E567737B8776B94D3FEAC0FD9B055FEC78BBC4961015033CF78805872F1F9899F69492AF6A35180C8F8393071BF020F746506FA50E5AE7A675542610F883B24A103A32CC407933CC2160FBEB0375A514A2D405992BCC8FCB82F3799365D238E02C1886B9499CA2C90D8B33FF32AF51F5933F721FAD5CBF78EC78802C7DD06777DB8C0FA3C0CF09790F65630E772177D4D9A35718ADEA8758057601C249C92876799167604664BFAA93537572A6A1425BC0AC53C85AC64DD9A7BE436F110C3AA68BA0552994DC019F9AD80B2767B879C8B7D4664AFA6C937276AB40417AFDC2895FA756909864C4E1867A537B42E271C86953B16279843C88DB9385EFF67FCB8A6BA13025B259398F149B49E1A4A9271CD7C1B5F0C6BD7AEA36CC6739C2660E262A3189E9AD342215FB5A95DB2B179CA763A8AC500EF59A4A243F6E6C96C278426D472161C1069A31992ED9AF9B88275D21815F1584CE7381D487457CC15E04E13FB4B93F309588D238BA0B59867680585C043857516395BACC287491B0E65B1C175B41045F2B94202F888B103A6683BA958FFE411135C3552BD546F9E3AAECB8C783AB074E809056545A8F7B89E7BD8DF0AE9CB398180B4EFE7B808B5881B8F0E5F9A8C23F7FF068DF3BD63457D3B48469DFD461BAA311495C347EFC0C40ACCA288BED6D4DBCF3BEA45D5AFCB6E7FFBC2D", + "c": "D9B7CFCCD8D7790A264374AD1ACF09AAAEEEF36B2AE84D657C05C697901FCC6C6B6F31BE49D729E31FBE760A93D9BF54D0FC37B81F6240D3BCBD911142EE7C330A570CED051BA7DE20810F59D6A2BB0B00F7525F071EDFB8B9DCAD854C70FD454784EB8F68638A1880D468FEA90EF517EA77594B53E901A2BD3FE2BA66F69B6F644FA0556D43FD799145B389CDDCEBAFB1A84B9C6F34231D0028584A8FFD70E69E1C84F33884ED6D95793803281561ADABF1EEEE72C22790558F3A6B7F0A54FCB96BFAB67314951158CE54880D201E9E8B0E76A47DB6FE8E7C767A4F604ACA6A598A25233440687ACEE588E5085B7A28C09E01E4906F3D834938833F165CD6FDAB1524F7FAA64C0B44C1691DA39FE88C19548F9D3ED4EAB68E853CAE954C7749AD6C55383E254E7FFC9662D500AFB1FF1A6A0312D7FDA9606C9E3665C46D0F7DA6C3B3F61EFB25DF574126D3843FFFE720651A06ABF241A68702B7B9A07648AD17E5238FD29D1CCF781605FF482857F1B10E36CE1BCFDEC8D8A0AEFFE0643E65E1BF0B060FCDC5C591CA15B645B701D33D1FB4ADEA2D13562D73CF68361BED92FF108BCC5C31B8E9AA913C112EF54C529BE6A4D2CC64808DFB5CD5EA8499007FA9F156CFA686248FD7232E797E4944E433FCE98B3864B46751D2C55FBC1C4C71FE96A875CBEA1F47F1D6A3C98E80876780B95936EB0368CD56284B211E670BE4ABB5536E6F9C7BB1D2A23C04705BA1D851408A2C566E9893B5C9EC60245EA2174016096B9FB8E8476A94E174E7CD68C66AA805512A5D851ADB17A99B49C33754BAA091E834A09C90880C95032D385458BF514A3B88C67FBA9E93317998AB39F712A5C38F1BB51BD9FDC0B538189580DFDAB817341145752F840FB4207EDB939855745977A65B27642F7C28C91FA7D78075ADB813D896DBBD57DF60EEB46A9C00E07F1F63867978B61AE357F695A1E2D415496773CB52258E94012527DD1FBD35B0A239A48894C4F54FD2606C9B5919BDD52C671D9FD169D8F4C6FE9D01E19B358A84876D303AF979222BAB23CEECE34209D8C1F890091B547374FEFEA7E5A6B8", + "k": "6D339C7DE13DA2BC3F672AEC4DDE931C811FAA91A8E91182DE4F94F2009EF16B", + "m": "6DB6A3F134471A89ABEC3384BB48A3C405DD3B2A5EF53821A3C1EA74DD562799", + "reason": "no modification" + }, + { + "tcId": 13, + "deferred": false, + "ek": "34166E98297165A69FE3818A3857B7D6E97180D938B8B56ADE8C361F010DA4E933F85A911214465BA7A0432AB99A519BDC81647CF72C4498A220C5B5CFD28566F4AE2CDB025E6270668153AE8B54C22BA5270A1DDB5660984A9812C32E6AF44385C494D55013814900FDC0CCECD7963D9945C4A7329FD5038F382181507D43A96402A973EF683499854D29BA964A530763A09DFCF4B97EF549E5A60C1EC921F8A2C9745B364316784AB27D96F8A9980727E5AB1FEC832DCD023D1774807BAB6D02E898EB0CCDC0EA26DCD16518089BAFE96AE395348481427788794D357B59E4421355656318B3984623C472A01C215CC13B74A3A154FBFC4DE4877ACE367B20397F6FD29E757354E6542A31E48E01B43EFED71BC6AA3540D3093E5794D889B74CF73C6096AD1CE46F4D5A912BB77C10C8CD2F92A6A952B7EE647D7E73C73185942CC331AABC3CAEAB4E0F86776DE4B5EC53B571B818B6F9BB31937EEBFA22C6E9B486E0CBC8658CF2537B6128C939A477E5376C59024440C56E853994FC588EE3D883B3A369D6CA24F228412140BEE37C11E8718831B24C91C46A54D09F75B99015A92AC7049697260652A4288E49A25F8C223709A035F36DAED2749DF387F6C53DB022535E729A10C8542D84B79AC5B44029BAAA360EAFC90CDCC754835A207378309045B7DAF6B8C5B6462A3B777150BA65C73B68F75089E79F1E820889A7705F4B6C7E404436F68DE4B50F0A082C0A8258E80B22646C29E7C732D9489AEFC11AC788593EA8C865970F83C3957829A818D1734DA277871493B45B93DBFBCDF0366C3635C0247358B1C7B8EF81B4B2EC8B4AFAC90E1983FB1C70121691E5913AC3B2689EB28773179E7225788FC319490393149A352EEC56732BB61B1C086CAC906D422D05917F3F1C6F3A57A7B61BAF9A852A8859B5B4F183B36715E578C63DFC347F86005FA11B407494AC4B19A7FABF59D10A34C58C6308768CF88BA463AE8BC243405277AC935D1C5238335B47066910917183444C79E959AAB64915C9609A5A12461F9125062C2536B73C5A5C1002269B0C023E7228AD1084918A247167D0CA5D87F83ED7B3EF523CA41BB22FA002ADD4DCDB3E7B68C892797481BC0B", + "dk": "BE01752AEA3528793D84B87D34010B58DA56FA4219F62A2BF66530B4115EA494A0AEC432AB2A2F6624C984E522BBEB6B34B1329D1501BF41B48CE820D99B3476413A87FC1055EA373BF32DCEE2573F13B14AA43A441BB2FBD97CB863B1D2CB0B60078552E8941F7A9A4703C6ED6621CB055C5C2CA4BE869887140746131CEDD20FCE9C38AE2221E49C384D76A9CD6141EAB46CDEE4B8F9EB734C0A698A038E1F14C4EB92A526711EE058502F54005DF57A443C11806496F14756687136F44B80FAB94E5A145F6A1A8224886DECB1B5C872202190106A95C588C0BC8ABA28EA5BB4C3D39330D17FA78098E1BA7550EA3CE47516F91801D01BC09AB8C9897495DCE68E45366A8BE5962612A4B0E6943DA72EBC87270A64B083225C2D408EDB1596B0FAB8BE0540098B0BF32C18B7401AE1F65C14F4C81337AB8F64A4A7818127AC10195C929C51B85001498D9CA7BB5A13D2FA515CDA75D6E795611B1ABE18981B972D3086136E5841EADCC52C2162B1461250C9111A3016B3B78BADDC6F59E4BEDF989DE0DC03D1555B98CAB2CDD150ACE44B241B6C4938002EE610910A22126B94937A9A7DB1BCB2079DB81B0BAF0A2A1AA80D609B76381888E0FA05329C49C379BA71300A9171B0227B442C610FDC2995C9778CE990B3C1DA83F3C8C1F2C499A1B9A1D936538C9C61B71C83524747C4775FADC055F08AC79622B4CFAC6996C5602C992713607F2D59621A9B1BCE67517A26BFFD636922362E96DA43B5C72BB0697F24167DF97B724971AA5C8B5011C02DE7857F761154E24B6D1741C49616BD17E360A9586D612589FA81625A5C55083092550C8F69B883E6C1510A122C94860EA277274BE1028353219F7B0CFE837B59D895F0A0597BB1AB93D39C6EEA6FE41A70BA395B97FA20B7161437543CBD107BA552CC13BA389F985622C5B4BE7C7F600A6C45196DF7B66BC1053C5A4C7EE2027B49E6ADBC100996717936C89B1F878ED03C4254E84FCD3251129A078749AFB1713635A83FAAE1C201F1012D68940BFB0B44BB87D43344FBC1C2F58B29B2943B148BCD9D4C368837B0BB6A0AEF083134166E98297165A69FE3818A3857B7D6E97180D938B8B56ADE8C361F010DA4E933F85A911214465BA7A0432AB99A519BDC81647CF72C4498A220C5B5CFD28566F4AE2CDB025E6270668153AE8B54C22BA5270A1DDB5660984A9812C32E6AF44385C494D55013814900FDC0CCECD7963D9945C4A7329FD5038F382181507D43A96402A973EF683499854D29BA964A530763A09DFCF4B97EF549E5A60C1EC921F8A2C9745B364316784AB27D96F8A9980727E5AB1FEC832DCD023D1774807BAB6D02E898EB0CCDC0EA26DCD16518089BAFE96AE395348481427788794D357B59E4421355656318B3984623C472A01C215CC13B74A3A154FBFC4DE4877ACE367B20397F6FD29E757354E6542A31E48E01B43EFED71BC6AA3540D3093E5794D889B74CF73C6096AD1CE46F4D5A912BB77C10C8CD2F92A6A952B7EE647D7E73C73185942CC331AABC3CAEAB4E0F86776DE4B5EC53B571B818B6F9BB31937EEBFA22C6E9B486E0CBC8658CF2537B6128C939A477E5376C59024440C56E853994FC588EE3D883B3A369D6CA24F228412140BEE37C11E8718831B24C91C46A54D09F75B99015A92AC7049697260652A4288E49A25F8C223709A035F36DAED2749DF387F6C53DB022535E729A10C8542D84B79AC5B44029BAAA360EAFC90CDCC754835A207378309045B7DAF6B8C5B6462A3B777150BA65C73B68F75089E79F1E820889A7705F4B6C7E404436F68DE4B50F0A082C0A8258E80B22646C29E7C732D9489AEFC11AC788593EA8C865970F83C3957829A818D1734DA277871493B45B93DBFBCDF0366C3635C0247358B1C7B8EF81B4B2EC8B4AFAC90E1983FB1C70121691E5913AC3B2689EB28773179E7225788FC319490393149A352EEC56732BB61B1C086CAC906D422D05917F3F1C6F3A57A7B61BAF9A852A8859B5B4F183B36715E578C63DFC347F86005FA11B407494AC4B19A7FABF59D10A34C58C6308768CF88BA463AE8BC243405277AC935D1C5238335B47066910917183444C79E959AAB64915C9609A5A12461F9125062C2536B73C5A5C1002269B0C023E7228AD1084918A247167D0CA5D87F83ED7B3EF523CA41BB22FA002ADD4DCDB3E7B68C892797481BC0B25939AD5E8DF2448392861CD66369376BE1E6828D87503F46841BB7682A42BA34940BEAD249B04A55DC051633480E518638E7792F57535B3FAC26F0A535A9494", + "c": "3BCD7972030D4F3414C2D151C52BDB8F96500ADB92F89A721A305EA938987F4B0314F093FAE503D8375C134046365443E3E000E19984777AE9189169E20AEC928F3DF3E1CCD2963BAEF94436E3D8116721413C7254F90208C788644A3AD90AECA2814526EEE017E07E222ED0987E5693C2C4EBD524F2B79772B974FD738C59D18FDC9E091F32351F86C57F57A21BE5706C6394D06253FB4526FEB48ACD18668324B7E662E5909CD76F160FE8C562975789F6C7290D1BD167E647FA2FA61FC753D5AA6FF7C62BCF3D7144D3EC02AFCB3E162C3D47F268D78F08FD3B621F66970C9A2A95C003092C3246DFDB1104AB31FAF7FC140D7AA39AF34F429C51041AE7BEDC26608A8BF52D43901BE92E65DCB87B832442ABC64A9F61745F70596A148D3EB7E40E7C8A49B24155BDE63635FD26FDB6458145D06FBA000E577073A407B36D4CD898A312285871487B50B25589D39BB453521F8436DB251710CA8F6F3E5D6EEF56F52291F7AC3DB7520E03DD95058C5CC4AE39E35FCAEC9C7E0284A9483C09D473EA173BAED7BAE5E6397F128C872469CB092A65FD1D2CEDA8E659CA97E7781EDDE6EDA94E68746182FB5A44BF7951C4768F66532445F577950642756BB1FD08448128CAE0D819BDB41DA547914CE892963F64C609C44170AED7918B3192EFCAB9AFB493CEEB327A4A6D21F7FDA7ABAEFED12FCE2F180C8A01FB905482B8BD65859CBED2FB8D13C65CFF497D8C9E0621DFCF8ABA62FB0FF0DE460C04313127031FF4883E9077A4A3FFF4D21740E02563F9595E2DB7B5867A7D5AAC7D7CC2E6206B9DD07CA8D2743F69D3FD0D5C00EB16E55827EE917205816DB1C6ED1BEECD4D529C9A1FA1C9115312B3C9392790BDBDE5EAE4078C90D7CA55CDC4021EEE7D488949AFCC05F2D7F4AD5505B3613983A87ED316B0D16443CBACD8206B593D86ED37B4C884B7C1124B74F30C6F2FEC61AA6EB96CA206EED58164F87D5849814F793FC54BFE5D5AF81E497F60E3C1CBBE2FA1FA8A602A4A36F60A567E9605CD439A2096B2EB051F3F9DD901BF119E172F52D617B6E5EC6422B0B05C030C20649C", + "k": "63AC7D8750E143131B3FE26C0FD5484F5D60DC8D22B542EBFF0D5D8B54F34EEF", + "m": "121DC782B740EAE666E709EA6E3CC6CEB8EAD204CD7D85D2256839E98CA57003", + "reason": "no modification" + }, + { + "tcId": 14, + "deferred": false, + "ek": "F3BACC6A8C9D390141981325C2DBA6EEF3805950199468661ED4BA300174FCE35411963B2B07599E14524446892603BC300AA3A25B45B41A857D50C06595B40B80159A477D8AD628F455038960BB23B0BC32D90D48E014BBF0AC12F93F17E36976A8BFD1E7B682212815A18B10B5301E0B88A7C17C850AAEC549B98195532C9323559591F9DA52703CA2EF921B1DA82D46A5B522F69109AC83351C46BBC375B61A8E7FEB0161423D5246362DBC8C866A899FE42F3C3C52EF82AF2CD05C11913B87E67B060A2200BB60D8B94E58C1B609DC9FE36A147B5C83CBFAB3C5F59F2032307E5745B7C68E324CA91EC987AF771D9D774B49E18E1F828E3D17641C51CFAAC9450D3A4404141187546AEA64939D94B884868876C86348E27DB0F66BD1A06ABD331B8999A446370982EB25979C35733791A49608D412500E9A144036970C086F15AC90F1699CA79928416858389908F1300356B9C382C94A2AD5491E86C51905BC398CA41FCBB05951A54A3681C806CC4868266E100EC2A334DDEAB98BCC5699E192AEE81DAB58C5C3D24C564C9821C7C0F981A500D91E66108C52013134B9440591AAC5A9BDC6208B22BA88F269B823DC08BD0C4067B7BDE01B5B12985CFA30C9172C9A2D95A33D4BC4EC181F17CA7A294989F0306FE2A7C7F16BCF301752BDE3CD3F2CB81460C0E3B0373EB8B79FD84B05A783E14454A2F2ABC693AF0AB78A0095A3695158A2B6783D32BFF25A4F6EBC4AB5010C0E394437D208ED001CB3B2C92A794607A6BC5EB580E7D52342B004B3A17E20FB70A4C5C2B8CB39C9E265E012C7D03540E7B47681409E30D169AE1277F1230D97B432E4276406D0C4FE52661E69ABD03472F2A56F52B51A5A317B57D229EE0898DE0CB2FEF71DFB71A85ADA97E93B9F2CE3113E838AB458A9FE826090369EA0F496DBB2A21D98981AC4410CF698CCBB6EC6724E498ACD1AF8C480A6AB1A67907D0492098015DB80A98FA8CFD79A74AFD439B4327C07A03C71AA7589D757CAD8BF86DCAC20B133A5511A47DC74B12317FB305098069DFE360250AB29A4239B1792352C3571978B708323BD2CCE72D18392A9C3CB7F504A14014231E9B4F65FEC62AD3125780D51E256CFE1", + "dk": "DB859103F7ADE02C4713C26A95447BCB6BC359F21EE93B845C5C0A145A9841BB576D206B60E46417AB9163A86BE30AC95FE3C9F9EB21DE282FF8D61A68CC43EFFA3FE3BBC9A5D56C304194DADCB94BDAAEF8CA74857C6C5C58A35D415D4E23BEBB602ECCE89B376CB61365C5014C128D090BD3F1CD51380A7D63965C7B143A19663F007CDCC5736BE624ED2721B5F915B8AB4405E5B44C3CAEA181B60A6347A1F0AD7278A879C75829935B056600D078133361A495539E612B9F677263A4A808A0851C54F65D54E8195BD4313D76A9590213EEC21B8FF2561E191DF5B8227D03632782B8A539524E6349D1693B61C0BD4F47B7CAC2AD539A69C609BD6146400F9590A0796DA89ABD99B62C30756CDA7854A792AD8DFC8FC695CE68FAB4AFE88134090AAECB29C0D75C1916A3B6225A76CB6C0E530BE46A60A3A2C8C07427ECB7C090002378B98F03450AA7AA0D8AE5226967C7E9F43AB50C098EB80FC72347E631120B8BBBA3E5C731A7ADE238B55A1763772A86C1159F96EB0B96D5CE0D3C9BA68B9D099A7184A461F91010B8B98C08E0B67A67CC6D4414390A0009493955172B85076F17BAA9A9645C21101ED962574E7C5AADA2B1EA401D05C92494A07664E6521219CDB248CF2D7B76E4D8BC77E30A6CC80017B282F6F55DD81355A8D296D4F0C71D95C14D9031510B012C989BCF959B51B44913B0808C786467AACB0E870C4297034F47AF6226BF8C3527D83B15C547CB94070739367CD48949DC7126E3672068C09C55C48BFB610AC87B81CDE4619221656C624DC1C24C6A038EEF5B58A09A801B225A132C85EAD459DB0A49DEC270B2F046C9482D41B20699E97C11905D4333ADD8139C659289537A411E3BA8FEB1072DB3C723551C7057BA55ABBF0F6755A465B73A93312D4C0BE8C9BAEFC872B48131B6920CBB48114846436E091554F2C352C919B6B16BABAABAB0D1424A5AA5CDD32FFF661DFF15A5BE1A83A0E517FEA9CE2462554F3C64A21C2769A18206F34071C1B2AFA03403B814CFB90DAB476F29B6ABE9DA68F4AB42A10C11C54A54CE51BD03B23DF85072B333114589BCF3BACC6A8C9D390141981325C2DBA6EEF3805950199468661ED4BA300174FCE35411963B2B07599E14524446892603BC300AA3A25B45B41A857D50C06595B40B80159A477D8AD628F455038960BB23B0BC32D90D48E014BBF0AC12F93F17E36976A8BFD1E7B682212815A18B10B5301E0B88A7C17C850AAEC549B98195532C9323559591F9DA52703CA2EF921B1DA82D46A5B522F69109AC83351C46BBC375B61A8E7FEB0161423D5246362DBC8C866A899FE42F3C3C52EF82AF2CD05C11913B87E67B060A2200BB60D8B94E58C1B609DC9FE36A147B5C83CBFAB3C5F59F2032307E5745B7C68E324CA91EC987AF771D9D774B49E18E1F828E3D17641C51CFAAC9450D3A4404141187546AEA64939D94B884868876C86348E27DB0F66BD1A06ABD331B8999A446370982EB25979C35733791A49608D412500E9A144036970C086F15AC90F1699CA79928416858389908F1300356B9C382C94A2AD5491E86C51905BC398CA41FCBB05951A54A3681C806CC4868266E100EC2A334DDEAB98BCC5699E192AEE81DAB58C5C3D24C564C9821C7C0F981A500D91E66108C52013134B9440591AAC5A9BDC6208B22BA88F269B823DC08BD0C4067B7BDE01B5B12985CFA30C9172C9A2D95A33D4BC4EC181F17CA7A294989F0306FE2A7C7F16BCF301752BDE3CD3F2CB81460C0E3B0373EB8B79FD84B05A783E14454A2F2ABC693AF0AB78A0095A3695158A2B6783D32BFF25A4F6EBC4AB5010C0E394437D208ED001CB3B2C92A794607A6BC5EB580E7D52342B004B3A17E20FB70A4C5C2B8CB39C9E265E012C7D03540E7B47681409E30D169AE1277F1230D97B432E4276406D0C4FE52661E69ABD03472F2A56F52B51A5A317B57D229EE0898DE0CB2FEF71DFB71A85ADA97E93B9F2CE3113E838AB458A9FE826090369EA0F496DBB2A21D98981AC4410CF698CCBB6EC6724E498ACD1AF8C480A6AB1A67907D0492098015DB80A98FA8CFD79A74AFD439B4327C07A03C71AA7589D757CAD8BF86DCAC20B133A5511A47DC74B12317FB305098069DFE360250AB29A4239B1792352C3571978B708323BD2CCE72D18392A9C3CB7F504A14014231E9B4F65FEC62AD3125780D51E256CFE1C9EFC09C35370E689B7071A0232850E93F30C5E774FCD37BEE6F8DB91C039E822D53C0A2C522F3E692881F0A4C65BBA41050E7D310898A6747509513A03A418C", + "c": "DC29B9910BC0978FDB8F6D7C215C91E003C550A7244B5D98509145A3544C5CB2AD40A332B2817D15182C8A31108109073D4416992C99149241C5FD147A48F23981C2B69C34E7A72D11B7DA6ED9973AA55A4812239BF8E0DD193E1EDC85635D31FCB26F094E23D47C84F805755D58D3FF7B30E81B8066986D2DC94210778F2F52F94C569AEF36A35F4AAA445B54180F703C28684D842763C9C1C0AFBFED51895B06670D97F68548E40202BF56A1BE5F874A6A440E4673E4A3E4095DB97FD9D36B30F4BE492FC957FA898E4E9BDE175C91927B058D0A1E10A500DA733B640B08DEE07AB4ABA009DC5B5E300F477E6E34431CC8A5DD699EC6D7C509637B6475C5D28DDB73E790F7EB60F7398303B4501D56E2161755D3E43B24AB4C1B391E4FA041C8FE0153BAD4CB6072213EFCE733FD9490583B93DB3D319B51E8DD497A1CFCCBFCC3B227747A9B86B2C5DA52F36894450B2750CEF3B425671EF059C0C4BAE8CB25E6CD626409F79E63CE4262B2275A45D18618DB57E9CF3D8CEA6B22B69340B9807B1DD696B9CDBEA445BD0E1FBDE9D86C92265C808B677A10EEAEDBB71E04949A2FDCC3094ECCD5C37C08A9B3636AAD670356633BAE9B7C16B5A8C4AC79C2873B4056C65E1CBDF13F7A55FA5EC9C4E530B3F13479D8435AC937C165C1269AA8AA7D939433AB0EF01BB87D2FC4D9B9405545D59FAFE004DF0A8086F486B04B1105DF829840CE198BCCE0F55C7486572891E31EFAE42785A2557CA8A685AC8A2655D71E4266D3418BAF29728193C3C5C22E7BF12A933CBEA2D3665C8A155B7B8B8E9EFFC7F99B580393AF3F76ECF9D731D5A299E8D8B2ACD2EDF58F6AE336D3DEE5D7258DE80C86B0E311536F8FAB511574504DB04B4E8326176C15DE143E5DA575C027585E1C8DA38CB50A2A72DAE9D5E266F106261395CC2F9575C6E59B7C73476A65BDCEDDB9E03CF299EEB5089683043FC97A8EB247CD46656A7CC5812DEB8E111CA1040E9BD541CD8AD4786FFB04ED643456E72F3C6DF4D595B1ECB097D6564D42D5915BE55D339D7583AC55B4C1D8221258C0A5BA1443F9BFFFDD2AEE31", + "k": "CEC93D98469424039335CB12FD0ABA4CAAFF3E3B99E55A53507F2CD3458536F4", + "m": "307C7DF0692D264A8186B8D844C7287B236D0FC7EC148BCFBF261A16B0FB7B61", + "reason": "no modification" + }, + { + "tcId": 15, + "deferred": false, + "ek": "E3F49934F999E0884E019B9299EA5DED8B5374851D9BC24079FA481C534793D328BC3B3563D0922098B98AE26406BB81A48AC0D24102E1D3624F974FCE49786890AAF9EA2E9CC058133C66847B67EFD61C7B469DC8E983ACB6ACB98C25D2A84A6EA82DB780531D0A4FA3A84400C70DDB48CC52406CB3155EC059894A4C01902129D1614C3BC25372C730CDD6CA8B204B9D18793ECA8B080881119549779A67FD456520B1011C6609CD4329C1832F7ABA7997D79B9510409C920E8EBA32A476B72061CE58A8A0A8B369315A814982A519E88E8FB25B3C74B527776C671C7B48C3C9EEB76F2A60BB39D5722A71459B180BCA9A9FBA14B3AB764E5F931DA0A55FB247A93ABB8509334050A029CB7145D4141990929A7D224FDC905419D62828625E316778E1517B151CAFB1B8B8E5E96958447944E266F808017C7CCAED571C64D9BA153709C303C92DC69B808941A8C3C760E52EC7388E800159CBF8626F953E356A827AB8692FE1982F07884FE3B094ACC0075128B3D54D85C39C08D065B6E40B5475CE1F269A2227AD4B368C683A7E797A7857C26EBC1C5207E6113C8B17F1A77186549FB63617611C33CCF38102062094F12EFD292A7B0B98A1423B92DC318E919B3DF441E58A36C04C7E60B270A453707DE23958974EC3A455294168D1265EC6E606AC40C79B690E5829A0F72910A0F5031ED1A5AEF841C58A036A10025B419E0E2BB4C6782EC317786BC1CD538C18B7223345699D44860D0BA04413E70B7D5126D2237545E550893427E34C6FFA40200AFB5D527B80C4A3A32B42B49FF5043B14AAF6A69144D58388A254F7F05F1DDA51F980A3D5DA436540A67569042E6B42337A712FB65A208392016710B8FAA763321DAC533BD06219AC6C48B6929D54D7B6A4A46280D2B242A8C1BA5B2BB42487AB031558BAC899EC3188A1459DB434C5463DEB43BEA974C1167B83C657C93A9604114128256156EDFBC604000C05C84FDEFB2218203131F40483F9C3B06C0FD524129FD65D0AB55714052A24588184164AD4B5929668A5A6F26F9CF44BA946874A21827E5B68A71B21F20785308A3F8DD6EFE22012FA9F25E348661EA987E6455F85D1A368EF1789708DC7AA8E849A", + "dk": "372270C8D59DBC34CF01B107E7E711D265669C5C01EE729926C033D53B0790D05F97DBB75059B3BBB122B73309ACA75D91582C409B39886416F5D97219872FD564935DF0B30F0A5BE2B3B6D08AC5193283E70C93C25C558BE17A93020F375C44B640AE41D974EC2020640515D74CC083143677B32C73D688088B03E8455DF248212B7AA82FC01F1BA0AD96B9430711BF05DBCCB075732F700B124C6B298B171D84C4F338994E0611FEA9AD4244C968DB44AB2967AA7666B8652C12588A3E728235C7A9B88A4D3D7A6C05B46A0D53C31744ACED6BC02B372B364085DE5CC13B2B4B7BBC36C0B06127A67AB170B9BC7C7F938A0A26254808E35A6024920B463EC8D223ECACA90327488EE8246EE5B076CCB5A734B197D61676576A2A4714FE0B3D69B87B581660981CCEA31923A1FB3498802BEA542FF3F1078529161291B014B94785F6BDE14595ED2B0B0560614C547F6952AEAF44974B6365C488235CA23A93759C9F707CDAFB8D81D701B31B08E473852605A493B8CE06B15BB95641069C85B0BB7D826A6F77D743B4051210C742314B787C77AB9193A9765256402C4575F3910C63C92EB816DFB9821C324D6852A5792041FEB441102839DDCB4D49E6ADFB291395B12DD409756E7CCB67192A3137CDAB072DD5004C7742C60A68CB45D63EC2A85F4452A9DD1A06781200D9D65A049BA37A7349402175E6D82AE4F16F802598A1463B46C2A45F583C8F051A84C399F227797F0A0A5051A3B13171C47A8A2CBA99EDBA992E58A5B4E544D19944DF60A1E7A2CFAD69216F4377B48B4B04C206BE5C6F83EA47F702620015029AD3AEF31970EA739ED5E887195C8DC94CAA7B199AB88634326A8303F535B71BCD514C44FFA33F5613388D32778B3C91BACC9F5E659CD170CEFD174D76B096AA2923E99C1AB288CE5897C9066631E1D82267212FAE1221905A7454D753FA916F85094B9DD87972F49D832C19351125BD754047F7200FE049868185658318BEFB8D913A41C6C1887F79C02567AB9236B485148D736B063B6B1EEA0C5F9D8491D279264261B375A799144C9BA787B5DEA211BB85A2E3F49934F999E0884E019B9299EA5DED8B5374851D9BC24079FA481C534793D328BC3B3563D0922098B98AE26406BB81A48AC0D24102E1D3624F974FCE49786890AAF9EA2E9CC058133C66847B67EFD61C7B469DC8E983ACB6ACB98C25D2A84A6EA82DB780531D0A4FA3A84400C70DDB48CC52406CB3155EC059894A4C01902129D1614C3BC25372C730CDD6CA8B204B9D18793ECA8B080881119549779A67FD456520B1011C6609CD4329C1832F7ABA7997D79B9510409C920E8EBA32A476B72061CE58A8A0A8B369315A814982A519E88E8FB25B3C74B527776C671C7B48C3C9EEB76F2A60BB39D5722A71459B180BCA9A9FBA14B3AB764E5F931DA0A55FB247A93ABB8509334050A029CB7145D4141990929A7D224FDC905419D62828625E316778E1517B151CAFB1B8B8E5E96958447944E266F808017C7CCAED571C64D9BA153709C303C92DC69B808941A8C3C760E52EC7388E800159CBF8626F953E356A827AB8692FE1982F07884FE3B094ACC0075128B3D54D85C39C08D065B6E40B5475CE1F269A2227AD4B368C683A7E797A7857C26EBC1C5207E6113C8B17F1A77186549FB63617611C33CCF38102062094F12EFD292A7B0B98A1423B92DC318E919B3DF441E58A36C04C7E60B270A453707DE23958974EC3A455294168D1265EC6E606AC40C79B690E5829A0F72910A0F5031ED1A5AEF841C58A036A10025B419E0E2BB4C6782EC317786BC1CD538C18B7223345699D44860D0BA04413E70B7D5126D2237545E550893427E34C6FFA40200AFB5D527B80C4A3A32B42B49FF5043B14AAF6A69144D58388A254F7F05F1DDA51F980A3D5DA436540A67569042E6B42337A712FB65A208392016710B8FAA763321DAC533BD06219AC6C48B6929D54D7B6A4A46280D2B242A8C1BA5B2BB42487AB031558BAC899EC3188A1459DB434C5463DEB43BEA974C1167B83C657C93A9604114128256156EDFBC604000C05C84FDEFB2218203131F40483F9C3B06C0FD524129FD65D0AB55714052A24588184164AD4B5929668A5A6F26F9CF44BA946874A21827E5B68A71B21F20785308A3F8DD6EFE22012FA9F25E348661EA987E6455F85D1A368EF1789708DC7AA8E849A8034B3E7058DC6E140C0F4220A80B43CACD9758598E55F2931A11A2F5C9026556B16944CAA344BD9BB904392078ADBE511660D4F9228446D69DF2A20A6CEE850", + "c": "7122A73DFE33E937B2D3350EADC73B3EE70C3BC5E9C4B2E7DC590A491CB7DA736B3B37294B0F13013BA8FFD8B25C2164E8EE528044A230220D8203AC4D2ED48FF05C479762CE72DC62957E839580C7FAFA23556119AFA66A53655C48E6193E1B386E4689821F5FA81643B22A7455A8BF30523098721042830259D90B69E21F038607140030A9EEAF30EBC813835AF12CAC2E018F7EF30473D235E6631ECA0306D6AB9E45608DEB559416CC92A7B4D465CD56184B0C4353D8A8D96C257FFAD6A90E090C8D735FD32A14849DCA6B383ACA3FE0A9F482A5A5069AE3B9542E83BD873C3D3C0B052C5DF69D267DB237D65EAB2E84F38B4272F079F84FB6D64F17D864464522E6F79D2BA9C4F1C2E6A0EB8FAEA6CF8AFC71E79B084E77D7BDBAAEB233F107697D245EF9BA19E142C73C9513E711621530B040DCC9B70088436DA2564F97FDC79E8D062ED490778BE78BBAB0B9E71559C6F5A7A314D73C4E16CE627E88F27F1502BD90C001607214772DDEA44C59040DCE7051F0BF2BBD712EC82CEE54A6F41E19DFEB32AF373BFAC06469346AF5CD7B32A15B66A5147E0D880FC180C228ADDC6755C3957740CF7A41F83B3DB58D23B19A33A4275EC795FD1EA20CF6BE52F5070B261A68AA0504CDCF3391A84EAB931FB14EAB16BDA72F69E15364962DA5988E4F0C37C715E5805DDC9674CC1E44449A0E534FB5E4499B32B6B959DFC0E937F40C4F0922EC6B29D8D4C8676F2555FC43B6D860696294A0FE7776D4944CDDCE8133646A0DCFD9D9117595E542E8F82BDFFDD969DA7736724A7FF71E322333EFE3CFD97BC04E80968248BAD48BDFF5F8AA6B0BC1C5141A7B70755199F83B0A896B2FE547F68CBEDAFFCB101A1520E1AC1E6FC364078D626FF53140271CF9E6FE8299D58DF313C50D082D7EEF995DC34BB98BE6026EB87EBB6AE6B776F72C71030DA2DE3F9A84B45953F80EB0A5F06B7408E7F9BC9EBE7064AD8BD9DA234CF4F29DED508106416A6B39131862D4DE2774663658F02F53D85206C8A9A3B78AF18623574E109DBF54EE08659ED285543ACEA5DD2533045FB16EDFF387612CB0", + "k": "BD132E98714A75116BB032DFA0C7B0C34EAD0780C576DF9EC11200256B4BDA87", + "m": "60363F5CDB16BC516A1367DFCE1B72926FB2189B88AA1DEBFD22F440B9CAF0C2", + "reason": "no modification" + }, + { + "tcId": 16, + "deferred": false, + "ek": "964B324032B0EA05C8042A49F702AE0FCB19257B1EB97079994A9C67043D99CB08708A2F64E694CCA51B71431DD20A77BAC80AE5A259EB99517020CC8CD53D525454A1B6052D4C598D9C504795835D9A45CB5CC7BC6313B857B1884067B0D97961108E57AB00DDD8AA5A69356093348948208947ABEFE117AD92C8562B5DB7DC037AE89C76D00C4315548372A272C32B30168620380CA0A697724913C173AE31AAB4B3B54F3760246A310F199027A72BACAB7046AA702710C145EB9A6F312B3B8FC291762BC301C900E7AB41D298A01D890AC3C85A40D0BE406000C6537BF9503E70986861D90B2EE3C8B0047E66B8B88CAB3AE9FAC382C23D06B835789BBB47A94823180859969535D058E7946C69438F89236AEEA110E404B51C1C22ED04CBB2EA32C957795797806F179A38642023E8AF6516A11393A0256A7EA3C27A8600A669FABB89E144E30A839D391E6C1A1F7F96A1E5FCCA889C8B09C3779B407075D97EE893AA4CAA1F5E5CCF3C5CC4DC361C8C80525BA81C05488012CB61D3EC87720A2CF0977BBA49B8F9D81D3EBB50FBFAA420E27AFABC387EDB87F114C1688830D4137BAAB10D1A6554179398B2D939C8F4387AF0007CEA2AFA9BC56E2766182B0C8D876123FB1A64C405CCD7A9869466B5825E23F41C4BD1747D5CC95C27912DA559535B195B96879F8C14F6030020278DBA6CA371C76F6FB7059F0B7E1EC67AD410B12F36878274C0B19A2F571A49A0358B945BBCAC5142F131C94E05C6A96C08DCA52819640431930D4089B2CA85A4FBA62F2B2614ADC7C4C80B06745320F837CFDBCB0A2885C321738C2B4233085A1B5F4AAAA658354078CCD008C496F0006AE08FE917BBE35433570B4C1838AB48593466D58F18A43A025355ADD4B333EB8146251E32FAAD8742BC847A7916212D5DC69329D0A3AE57147628928FD0B08752A21AC308515229EDC169FB6141FFAB3347F427ABC759C40C8D29448A273441A9C53654042967087F470024EC714B0708C033436995AC4FA678A9FCD724F703411454C04C21764C1B243146587C774897C6752BF79868846811106552C8AA574AD8DB7372836844DA6BABBFE62263107076C4CB48CB256D359D08F68375BC", + "dk": "879036ADEB2F85A51E3AB14979E71A494A8D3DC4CCB6B6A35F826CB03761A1A799F621957DB260133988DD12600DC33602226CEC50434BF059E3B11FE5F19A42BA1DF9164EA118090FB7A1AE857AB7E8ADBAF66DCE7CCC01B8BFA93153D3E5A644C56B1116058F47C663CCA1F54C3184BBB0FE8CBD05E53265ACBE72CB37286929D85B856CC8587DB46DBB3622930465775893FB7401E9E98430FCBDB9966DB60280C8319349C18C62E56DC9BB538DD296A47169753A1394680D202A7EC33ACAA12B315BD69F93A07F77B9C6396209FF4198FA88508A4548F16503B1C4079F7086CEB9BB4F751A0B8175B3F193805685F098A45E0BA16EF3828599842A240B05A201ACFB45B63C4C2D6BC35EC36D69E4142666B8600AAA123B6E6D7C15171BA2FDD94B0205BBD4963A45CC46BC089BDF817C52933E36DBC911174EB62CC4AE4AC8C4E45782736125948A97A2C66E7C9A756CA146253D8C07349A6C4D4D97BE122BA433DC388F972CBE79695C878A23537F33C3B339879BA0481A41032E961618198529DD154FB38B918A019A0FB75827084881871176E02C1E8ACB746832F44191C1B36D2B96CB630499E83007636AC656707998F436C1472EC3406515276E7A4840DC509123D2907AC7424416A656A74E49EB478A01750470ABA7F5AA416BB99A50CC6FD823AC1B9178376A8DDACCDDD2975CD68724FBA3970216983219B70A4ECE563A00C44CF121880FC8C5936124DA62008BAC6319806E1368B4B8467CA8980962C826FC20761D131D6692C2F1907BDDC83F2CEBCDE692C8CFE6880BA357D1D056A022A1D3A4C0D7F638161011AA83B18500096591A1D6B55110976CBE0A03BB78AC7CC34FC5774D794B3871B94BC7C081D5895CB44C0EC7E9B2782004C5C61564F582C537C6B72B5B0B924799181D6D012EA130B2D5E0C998F0C3CD829BBE48645A6905F6D240AA518CE42851989C987CB9CCE9F71C43328703F5882DD13EA0841251FA4177B593BFD58AFD146631D876C1D96310CB2C6850783C5939A431483DA78E09C3041880B1C3686B0C45B442427B61443D957C01A580B287B1AE964B324032B0EA05C8042A49F702AE0FCB19257B1EB97079994A9C67043D99CB08708A2F64E694CCA51B71431DD20A77BAC80AE5A259EB99517020CC8CD53D525454A1B6052D4C598D9C504795835D9A45CB5CC7BC6313B857B1884067B0D97961108E57AB00DDD8AA5A69356093348948208947ABEFE117AD92C8562B5DB7DC037AE89C76D00C4315548372A272C32B30168620380CA0A697724913C173AE31AAB4B3B54F3760246A310F199027A72BACAB7046AA702710C145EB9A6F312B3B8FC291762BC301C900E7AB41D298A01D890AC3C85A40D0BE406000C6537BF9503E70986861D90B2EE3C8B0047E66B8B88CAB3AE9FAC382C23D06B835789BBB47A94823180859969535D058E7946C69438F89236AEEA110E404B51C1C22ED04CBB2EA32C957795797806F179A38642023E8AF6516A11393A0256A7EA3C27A8600A669FABB89E144E30A839D391E6C1A1F7F96A1E5FCCA889C8B09C3779B407075D97EE893AA4CAA1F5E5CCF3C5CC4DC361C8C80525BA81C05488012CB61D3EC87720A2CF0977BBA49B8F9D81D3EBB50FBFAA420E27AFABC387EDB87F114C1688830D4137BAAB10D1A6554179398B2D939C8F4387AF0007CEA2AFA9BC56E2766182B0C8D876123FB1A64C405CCD7A9869466B5825E23F41C4BD1747D5CC95C27912DA559535B195B96879F8C14F6030020278DBA6CA371C76F6FB7059F0B7E1EC67AD410B12F36878274C0B19A2F571A49A0358B945BBCAC5142F131C94E05C6A96C08DCA52819640431930D4089B2CA85A4FBA62F2B2614ADC7C4C80B06745320F837CFDBCB0A2885C321738C2B4233085A1B5F4AAAA658354078CCD008C496F0006AE08FE917BBE35433570B4C1838AB48593466D58F18A43A025355ADD4B333EB8146251E32FAAD8742BC847A7916212D5DC69329D0A3AE57147628928FD0B08752A21AC308515229EDC169FB6141FFAB3347F427ABC759C40C8D29448A273441A9C53654042967087F470024EC714B0708C033436995AC4FA678A9FCD724F703411454C04C21764C1B243146587C774897C6752BF79868846811106552C8AA574AD8DB7372836844DA6BABBFE62263107076C4CB48CB256D359D08F68375BC6D63B8A32687E3ADAB407548CE8B83437F355FCE2D96C1BCEC6C006F7E493B743ABD1651588386750AD3B35DADE74C328DF82778D99596561ABD71F194AAD28C", + "c": "4DBE5E9CC3989D6CCE8D9F491B94985E770AA2ED9D214D45B03832D90EC0817A9F06856EB4D6AD8BEB6B64B7F1892EF9E13C594C7BC1B9222C655F259603868047D35ABAA67FE36816BDC493502E0B3E4129DD58A8971590E182B71386F6BA4F4580618EF186668C0579109E6DED3DC1A8F22EF6FEAD9D20D9435C144CA8D46367F178CD0957A638AFCDA69C96C59B3FE03557107915629E21F148603EF68FFDE3327FDCA00A6B1A3E498F90FE7634E56AEF588DE8E9C567D3C9F8E5E66A7DA505DEB1AF29DB37CBC5089C27BDCAF1E06614D796B89B3C1D9B40294FF479D6E64BEA14520E734600CCAEF6AFB0DFE7B66291F79859E988A4FC78431EBAEF90F511273B16DA1FB42C404D793EB36414A40DAFEFCA07F1787FF9454FCE27EB142B985D21D8E086ECDF1B2DB9B7DB12F1BA442BA3C8C16613A8BB7D4F155155F6AED9196E54BA77027B8C040E6A047AD6F41FF174FF3CA4F38A167221B8715FF60661E744EA43F49335C3E2197E57D7A1DD5CF53DA8D3ABF359251675461EFEF9CC2F033B6ABD73B35A8CF740D65089CCF5FBB94DFE1CCAF26AE43F7E5F630209C7A6EC93753E808345AAD1068D18DE64BFC4A8BAA6EB6E72D97824216F922729D9FE73401EABD11113FD7B69AB97FB10525F273EE35B2390446EFFF9BDEF7FEBC416E6668B06FF5AA7A5C50DDE17554606228B8586BC93E6A7B9B239D8DCFF2E4E55ECBC75C9E449F25E48CC2100C3F130429EB3F841EC2C1A8297769AE8CA81DE932833DB2CF10C9EA57A682A48E26E3D42D9BA9A6D61C82F4014B804B8AD8619CF84AFD3645976ACD87D1B3B7D40CDD87C35C2E3973296D22851C80F84B792FDBD81F549968E2BC6DF18C37F50805D29CB657DCD9C392070FF3EB4EDEBA8DB298447A713E517B94B1CA4C11CD462B2ACED35C4AEA82D65E5D5F050CBD7DD8B40BE07628025F8A352CE8A15D8FCA7FEB78F9D6A1D179FF4AA336CDF3925FDE9631BB53649DC65BAA226CDA770E50ADB9E2E3651A4E6776748D76F9444960FD14B9116AD419F6E5A4D74116890F05AC8ED0BE52A1C70DDECDEEE8C6914B40B1BCF", + "k": "CAA24999EFE659AEFCF18FC9C722FAC1D5DACE583B716AD3828B15C7DF5D94DF", + "m": "579474C123B3381801867203E0021E2B7F15E5F9426D75A3EDA6CBCAECECCF43", + "reason": "no modification" + }, + { + "tcId": 17, + "deferred": false, + "ek": "87EB24113349A40704B7243F2AE3653F24B87EF50E2220924BE06BC1E86E8AD9011768B255969F4F29C21BD38D6687756D795F07286B4EB04C30143C4F76810CD3233E630417F86EC751CAA87806CDD93EC0B5332758CDEC3A37B4F84878F89A4E687F0E457E45602517B676FC944E0BF9A9E9903EF895800D019304AC223E37623EE0C7DB798AA1A7452D298036A4197E89B0F279A385DC19D20BCED386352FE512A9EA90F973B6890964490538FD82A1748C98384C38C1434EECDB6EBF561366C228AD0086D142966BE1B8E1025097509E460850087935CF543A7309342424394267032A84358CD76E4F98C34B0005B39811233CC425A237AB49CDA9A884DEF6832B1A2031F5AF07DA4C23681B561C7D91A22C65129206187EFD2926016717F1F318EA95CC037208D2B313E0BBC59257710EE99F9B81187837861404CF4E930D0A4185CD3779CD4830CE2A02049AA0BBA0BF06003DF8A358CFA4CB2D3B7C7A508FEA1B930D1BA379E246B9BB793D1C2548F8BD908315BF521200261E42C843D963074CE4CBB3A5898976815CF3CB0DCC137F0CC414ECAA8883CDE897649E81BF707216FFF23B124B3FE6A39A45EA317BA5ACF8116E9825BE6AC518B4658D5D23CAFA600F94A9ACDDD38F303978BD64B4CDE34E73334C1B212060E29085925E6A3319EAF72097826F4233CEF2F4AB1BC9CD99B9338FF43BB9EAB9723140CCB86741C44E5D083CF6FC97D071CAB3135F6B358172468DAD6834FF3A1AD0750F06837EC25C6AA4F179D259A0FFBCB4E6756B627BC1F9F76DFCE2712F7340F6AB2109F023D6BAC5F0A6A63063BDA11625FD93B3E8C7315D387AABBCCF763237D785A89130A3DF63AB2F587D8AC4BC90B795C3639EF2352D0314AD638A532E625A78F296B5C5A38BE65995F8859F279795D0795433BDDACA847140650A72637DEB3529E8179CC056FF58C3FA094678526E12E791272BB623367D0103A68F6811B0636AE101090B2480EF8C6C59B51426E6A3E8C5303C3200EB783A9A133AD2E5261B5371FA338B6D016367650BE0D4A93BF3CD9C48629F8A448AD9AE86258F454BB2F60B1BCA578FE20B26DF0732C3222BD4B8A71A2F5038031BEF9EB0DFEFB2666C", + "dk": "77E8C08006BBA3A7423AE68A67F48336EB0F5FA3B14F931F8B88AAAD384FBCC3CC291480228079D4179A3B6A0E555A4D3E6A5C8BD72A5C0779E770C56B53BAE1974EE047AC3DC953525C03C5ACCC0164C02C65B10407CBEA6AB0F9A413F0E169CCE31446BA219F765B90353F8FB327F9F8C767F6BEA749666FEA81D1186AFEB5170977BADAC98E0BE57854431756C042DB86430C27A358A3BBCF823261C8017FC8B81F9970BF9B73433531C13AAE0A960D82C06CC491865CF4450BA6641D1729B0F7769D073FFE99BF2A8C8D40538CA08318FD163FC5F12264266710D7259F765DA6786EA386C5E9543BEAA54FC785C1C83940FEBB2C866B737DB93D2E798E03A52645330901D118D0C973A1E997E5BC39967577E51C752DE187EAAC8E5C167BEF272F79483A658B6382B93F67E07E3182A183AB9842951FBEFC8CA6525D571B9B7C995D89366AF8E62B371B6A5A0990F3B7AFA054B997E921AD708623950EE7A2C6AED3316580735002C48A298AAD0174DB794A5C862092061E0C25824AE84B6BE824A33911A112AD51509E29424B4D933946528224E64B4BF924552706E7307B4FB7B8C2D083B2245A5787A19100CE78465C3B663330006C8BD0B626CBB9ABFAA3F551ABF18AC146081ED1AC99A37944915CB6E1713DDA4049C3F0CCE4611E6A21458124A850119CD5B846867C6DF0E9592B0A1AF7F1C5210C6CC2E5192A44778AF59BF90935AB8812E811B909528A402174B3747ECF6CB6DBC58DFAF15CE849BE309760A0F9274409C8EB25A679764090E59F27553AE4B31A00DA84B25A843F23C6D9024B23CA942EFC05753123C703391C21B539C9973E14611562036C793CCEA69B0A51785664C0367B94BBDC45833BBD6F132F1A34A31134A934E72A6F988A36A9BA6516981F242F67C33C9F71C113D40380147274427F429A1F26FC5C5EAB9379F0A73DF442B4B2A299E827B0A522DA24690DE17F72A547E9E228D98541C5C02058B1879D5946AC83B338277B6362C72371A6F866C2C72481024A4ACCD0B91AA560249CB5B01B0BABEC227D1AA1D6FB5E878C66214A9DFF0BA989C78987EB24113349A40704B7243F2AE3653F24B87EF50E2220924BE06BC1E86E8AD9011768B255969F4F29C21BD38D6687756D795F07286B4EB04C30143C4F76810CD3233E630417F86EC751CAA87806CDD93EC0B5332758CDEC3A37B4F84878F89A4E687F0E457E45602517B676FC944E0BF9A9E9903EF895800D019304AC223E37623EE0C7DB798AA1A7452D298036A4197E89B0F279A385DC19D20BCED386352FE512A9EA90F973B6890964490538FD82A1748C98384C38C1434EECDB6EBF561366C228AD0086D142966BE1B8E1025097509E460850087935CF543A7309342424394267032A84358CD76E4F98C34B0005B39811233CC425A237AB49CDA9A884DEF6832B1A2031F5AF07DA4C23681B561C7D91A22C65129206187EFD2926016717F1F318EA95CC037208D2B313E0BBC59257710EE99F9B81187837861404CF4E930D0A4185CD3779CD4830CE2A02049AA0BBA0BF06003DF8A358CFA4CB2D3B7C7A508FEA1B930D1BA379E246B9BB793D1C2548F8BD908315BF521200261E42C843D963074CE4CBB3A5898976815CF3CB0DCC137F0CC414ECAA8883CDE897649E81BF707216FFF23B124B3FE6A39A45EA317BA5ACF8116E9825BE6AC518B4658D5D23CAFA600F94A9ACDDD38F303978BD64B4CDE34E73334C1B212060E29085925E6A3319EAF72097826F4233CEF2F4AB1BC9CD99B9338FF43BB9EAB9723140CCB86741C44E5D083CF6FC97D071CAB3135F6B358172468DAD6834FF3A1AD0750F06837EC25C6AA4F179D259A0FFBCB4E6756B627BC1F9F76DFCE2712F7340F6AB2109F023D6BAC5F0A6A63063BDA11625FD93B3E8C7315D387AABBCCF763237D785A89130A3DF63AB2F587D8AC4BC90B795C3639EF2352D0314AD638A532E625A78F296B5C5A38BE65995F8859F279795D0795433BDDACA847140650A72637DEB3529E8179CC056FF58C3FA094678526E12E791272BB623367D0103A68F6811B0636AE101090B2480EF8C6C59B51426E6A3E8C5303C3200EB783A9A133AD2E5261B5371FA338B6D016367650BE0D4A93BF3CD9C48629F8A448AD9AE86258F454BB2F60B1BCA578FE20B26DF0732C3222BD4B8A71A2F5038031BEF9EB0DFEFB2666C29148150CC61C6C8B7FD408B3C9B21B6BF530E9D9AB72573FC6DED2E4A10C4C0D01000728E8DA5326C713E45EDF82C441D51791E0AE7663DF7E931EA208B7313", + "c": "A707FA4EE57BCFA296EF6D10B848DEE8A48BBF84A465529F837977FFACB3E429D0D2C58BA2A10406995B6328AE91728087648B7F018FF9E570E533F982EB58FFECF6BB104CF2E6D819E3E17CFEC29F31F275C64450B5D8C14E231C563F03FB978B214A51DAE1118D8BD235920B401A706F8C3917D3CA066CF0D1D6591893B244ADF6F0E514575E67BCE3CA8217330153EFF5F91FBA1C23CAB3906F2DB8BEFE01742EA2DBBDC0D3B7127BCA805430792E30CC2CC7C1108EE02CF429820C232A65E4A3CED4949FA184A8B624EB4C4B72DE88750FF7565E35A54E71DC289AE7E59F9F05A915BB0B35C7FD36967EBEFAAD806779A116DEEB462306E3757C94F2B6EEC836DDF1CAE12E3AA58F44AF495F410321661E5451ACCE0365C74EE70A630E59A16CB48532A8A7DC7B2276120450820CDE94FB32DE747E643176FB02ED2BB06111E56627E790C304AB163AA0B424C280940459900F51B95FFFAEB244B31873A5C452508E354FD8C7B1C9DFCD73B79F9D1D5A76413CF25C1E378461F075990599F452E0221C0C8ACE25BF0227632C667D8930D12E5A136F8EE42E19677FC3A1ED91D88238527F4F5B8DDCA69A9E25B2AA84719F9D6550D57D8B2BF8B42C3B46D760694A15FB894155F75FAF61E67672A5BD8AC7C1A2F82812944558701181A8F7AD48E1C5E3048F1DEDF19BF5DDB322B0A5559616DABFFDABA2AF717EEA488379E75446524023563FB1CB34102715A63F1E2966C72EBD6A7C590174699BCF325C627970DFA7DB82D8FA9C39D82E412FA7827CD6CC04D23607985B97E5E5E368A23F25FC516BF771DFA1AF4CD65794F72FF61DEB1541001C08C8038E633800967F6AAE7F9CFED288921DB4A8CBF0BA1562B93016DCD051444F4E23817EB081E23309B044390E33F8D73AADC7ED244239B090740C30C73663170E0703DF06B886BBE4735BCA02E44E25382A18D6F18C0CF9CD452DA692C5958CFBA89F84E4BF5DBFDF2B3002318E08E8215BE0E5D770439BECB122A8F8A93CD93D3E8CEB6E89F83B224CF6D7F7526B1181E4D7781FED7A0177BAC4FD82FC229E6A8A61FD4A958A2D", + "k": "F9F4E46B44C781A74DC60E149C81047C89C75469123ABC787DEAB36EE769102C", + "m": "E2F0D46B6C4A43E94CF967EF2BAC7B68C6E0424A37DB52F2BC0C1695D1A66B67", + "reason": "no modification" + }, + { + "tcId": 18, + "deferred": false, + "ek": "FC93AF4B238968BC258C1CB5B94592501A51C3368DC9041A56DC5E5D230343380E287396E9B821270633DAD37C920182C82C9236FB28BA025DE94A8E552A605AF1393C988E08419BAB6C8709EBB41076192435699F1C48DC149D3F040A5A36ACC7C869FAA5AB3507B8B32A6847EC901DC8B9B19A04B70865955C4B3B01676DBA6B463C36397B2A42218BE0DA0B55E1A5ED8975C002A9520C114CB672DF5B3A7F838911F7869F148D51DA2584AA0C15F4C2A8C95653C95970D2BB4805928DC02D3DB050D6338A50B6C76332911E639DE912656B72619DC66790F491E0DB15C258C000650DE47268303BA52A49A9179A4DBECB45E7B47A74A35DAB781F52D27CCD2B6C75474474DA0374E25D21AC152E5AAB5225BC7EC5A16F5A1FEE930C300A8A15C090CEEA999D045D80CA73B5484C9E8823604AB464404F9A9609AE920ECDC688E17090CA6B7DF2108151E04BEB6A27F7EC8ABF95BF84D23CAA254A93F89DBBE133A6B1862A20B2B7241ED0695C31B17A7AF1A6A557BDB431A3D2DC06580A8DFB52C91592A80E3C1995E5B69D03AE3B8C13F37AC4852C888E077C290928420A4170A377F0A519DEE8789FB7BFE6A214C394038E281B56AC36B5474286A23142E14561D494AC2CCF95322919A34369B94D79BA787194A471F3A3271BAEFB4019FFC040C831447FDC9BC19B948A0710471A233F0B7104826A83B881CBF4764B1BB4441A843255A8445A034AD6972F4C66C906550C1C5E0D30B718C339618B3564456EFDD0AF36A14D7B705E62153F5C880F017740288545A6D51B13A671EE00970217BB3B33B69B56C823148A60499CFA960B06EACB3F9224275BC907D89E4722C1E35C425DB0ACE65B7929F66F82204AA2F0148BC0B7126B4EB13C4692EB3732E3B2559AB0B833AECF072C2060B1DAB6A9F8BACE386A098CB9B7B7447E6957B6219C6607B3CD83BB64A4B12C973C28DD7933A4B95AC3C7C59824A32E271007ABB369FB06FCC82B20D38BD436B54B155A5FC25381361D13B41D0C4B309E3A4C295C18B4F845573051C81B0E6E37A0D7869D23412F9CF55B3AF5121E491E45292535577EBB8EB2CFF39D783AE72D468F687BBFD838E6A61F5C5B95FF1F20379091", + "dk": "F38BB156C26C61164521D1A109AA9B8108251877AE7E9878ACD67C3B497E40323A94D891BF700CA9E1A2219C7BFFEC710F575AA6A3BBCF9090FAAA82D2F0544F325A8B72A5B2F616CF87A9B698C7D5790974547EC5A8963D9649B598370861AB3C1628DB704368A256542B944BE03E28BAB87B6C28AB08ABFAA65827C5045871CB9F7911B81A0D577C1EFE3AB8FA5671A1565AEB286CE9C2175E60CFCDF809AC7384CE260D904C56CF6036AEB18A7B14B3B09C902337707BF739C365748B08BE40885DA99AB3F909C6C9D401ACE3C1816B2D2C8731BF46910A636D5882460C061DDC175290290B40B2AF1CC80CBD1C3BC669339CB95FD3D320A663C5937CC6D0C98D7D211D9CAB2D9D26764DD446893646569A14DE84A7BD7037DD4C644B633D4BC23BACE8308811BD0232A8737A011E98C2F82627BBE173640BC6A22AC957C5BBED4433F802908ECC8837152152C167C296C9254695523AA427A919D7942AC5952EC691697E0216F7A4C0A8C3A6D9B9CFBAC6A47EBB6C80C05BA64B2C94CA8A99F717B1E503C8185A3103A6A6C229D34753ABA4A2D1E9C977EAB176EA1B3882051ABC9C37ABC0D9F29F01753730C90E811391FB75B8EBDC3A9AC525BA3A02B54378BEF835EC51A824C63C5D8509A394183176004A2A0D0A565B439A909A5271D1A3C7CE3A9C09F809C1E2220D28AC38B52ED6F93D73D7A97779B61433CC709323EB8349D5902242861F99E261744A4EDC58073E676D1D84BA5C070A87240F6E82BD700B7AE7EA08E720815FE820A5629CBB498509AB53F359526977B09EC7A33C78CF3985BDDDCC86770106F834900E6A41622AB6A4C2B02F8A7AB54A53A0AC112180B5CA02452056A421F140C5B1BAF5EA0BA5B34B95B7CC71678F31E97C95056C1E4569B3359261A1AB1DF4749358468526CFC922C499C97888588EEF14BC31DB595B71742BB038CAC479B79B3083E77460C9CD860C1AB4E2595A99942E97A40CB0743E5403A9749B5DE2ADDB5A1A1A850353B213F4B6667A561A1E25266773577BD2367193A156DA92C9E72E036BA63D103BE6E0AAD5325F9F5A55E1D749FC93AF4B238968BC258C1CB5B94592501A51C3368DC9041A56DC5E5D230343380E287396E9B821270633DAD37C920182C82C9236FB28BA025DE94A8E552A605AF1393C988E08419BAB6C8709EBB41076192435699F1C48DC149D3F040A5A36ACC7C869FAA5AB3507B8B32A6847EC901DC8B9B19A04B70865955C4B3B01676DBA6B463C36397B2A42218BE0DA0B55E1A5ED8975C002A9520C114CB672DF5B3A7F838911F7869F148D51DA2584AA0C15F4C2A8C95653C95970D2BB4805928DC02D3DB050D6338A50B6C76332911E639DE912656B72619DC66790F491E0DB15C258C000650DE47268303BA52A49A9179A4DBECB45E7B47A74A35DAB781F52D27CCD2B6C75474474DA0374E25D21AC152E5AAB5225BC7EC5A16F5A1FEE930C300A8A15C090CEEA999D045D80CA73B5484C9E8823604AB464404F9A9609AE920ECDC688E17090CA6B7DF2108151E04BEB6A27F7EC8ABF95BF84D23CAA254A93F89DBBE133A6B1862A20B2B7241ED0695C31B17A7AF1A6A557BDB431A3D2DC06580A8DFB52C91592A80E3C1995E5B69D03AE3B8C13F37AC4852C888E077C290928420A4170A377F0A519DEE8789FB7BFE6A214C394038E281B56AC36B5474286A23142E14561D494AC2CCF95322919A34369B94D79BA787194A471F3A3271BAEFB4019FFC040C831447FDC9BC19B948A0710471A233F0B7104826A83B881CBF4764B1BB4441A843255A8445A034AD6972F4C66C906550C1C5E0D30B718C339618B3564456EFDD0AF36A14D7B705E62153F5C880F017740288545A6D51B13A671EE00970217BB3B33B69B56C823148A60499CFA960B06EACB3F9224275BC907D89E4722C1E35C425DB0ACE65B7929F66F82204AA2F0148BC0B7126B4EB13C4692EB3732E3B2559AB0B833AECF072C2060B1DAB6A9F8BACE386A098CB9B7B7447E6957B6219C6607B3CD83BB64A4B12C973C28DD7933A4B95AC3C7C59824A32E271007ABB369FB06FCC82B20D38BD436B54B155A5FC25381361D13B41D0C4B309E3A4C295C18B4F845573051C81B0E6E37A0D7869D23412F9CF55B3AF5121E491E45292535577EBB8EB2CFF39D783AE72D468F687BBFD838E6A61F5C5B95FF1F20379091CF21077C6E3D08D75668EB9DE6088C89F26636404240ED78CF9683E58F178427D527C588E4CBF3A4A4F983B4DFEFB28FAAD96A659A16B403180DDC7E49391AE6", + "c": "34F172C9C056D82BD5DA9A1EBEF6241212452C78A2FB05DBC7C234F46847B3C3B8A1DD0B3316D4C96F84FF3F45B9A8E2BE97417A58946A83892A39C553C59B20164F64C37A3BEA9A14913A6F384AE5FE4B3E00861B903FDA24D740C29F086D1A517B24FB1A101F5855A9D2FA1237472595889F9826C6C5DC0F0FD14A359B2FC4A39A49BE7095E9CDD57D112BF4792433078CB93FF7A36BF5500B61E94545E1578C3817D81AC2E86414BE0339E26E9395E65957370762A5AD089FDB6C74960E7D6AAD7FBCA78833E69F0FCD60A581E836EC41CCDAB3659E422CD2EA42F95D86D79A5974DDF913E6E85061C29467BA1610B5C81E5A5E527F7B7BD1E2B1A21F64E00E11D7ADD5EDCD8898CA3CF5E497DB64DC68502D6183F583FB4BBF7826F8ED843F99634FD6E00DC4E9A87E0271777C7980FD2E72ED83B253B6F0BFE363413E9FEBCDD261ADED6822EBD9501A0C10EF825D4D20D6DAF36068AE03C9B8426939B81761689A6EC6019389B99BFD1DA02D3B0725FAD3DB4B9DF9FE5F291E91414B81B3E64680CF7DA55CFEF76C14D883C7A85299971F328402CFA1EF2064737AFECC27E4A49074C47F08DFFCD4E3AE86062BE0802F7F0FC1BA9C4791BEDEDB83BF432D9B81925C968467A42CDB2C7CF581C2B645933CBC5B03C9B285B6C559BB7985C0CDF7C242A908F0B78DE6DEEBB9BA848F8B3BBAD7A4663BBD26540660E1160C918EA19DF06C64395BE4A439F9963F4982A6EC981F0FD844F1C6FB5507B54618ED1491710ABE264339AB866D393C0FD953AC8B38AEE24AFFE1988F988982506E5D7CAACD8B5A78E13F68321C77F8AEF760B8D45CE5307CF6A3DF13B2D77C6901847E7E9715D1B84DD43CD7A806F8D0DF99B257F8F34C1F2E7891B226F54562FF3C48A05728020E768B863FBF5A2331CA967D55DC8F3468CE8BF5ED401D0E98159C5882720CC34F61FF9076256371377A179A25228AA5450C28AE27826491ECBF5174D70D94C5B6E4AF04853DD89003F7FBBBC241CE87B96AD6F6BB0C3407E448F2E75D2A040F7978B8FC717F69B3C1124FF46667234B2D7EE8946FE63BB18E19", + "k": "52C8EBA213E652AC3F3CDDACCC5586E3C26332A4BF5E57B69421E6DD45C5B873", + "m": "7B34969C65DB28996B6F9C440DE09074CC98DB4F08BD43E4CD948EE4ECFDE8CA", + "reason": "no modification" + }, + { + "tcId": 19, + "deferred": false, + "ek": "894C58C872A67C630143FB29F5C2533614AC1ED6CA436463EFB38C7BF8A8DA348DAF4BBEF00A8E61E650CA9C6BCAD30CD330CC2D032ED7E42F41A9967C3AB568A0301A5A12EF70A2A6EA97B187691AEAC151029CBE350065B0C2239B67E303050D92A692237E21900BF2901A69231B14F04901ABA8D22A881365B943BA429AE31A72B8701CB07029E129B5D3BECF9090A70A5D3A86BE1BBABCBEF35592A7A74C2CC0560C0EC2ABA3095589C7DB2A5849CBCD483730F479ACD55B212C942F900407E46C0C584200C1CAD7D05C7DF467FD31C31E266A50C375689CAB1BE672774C77062018E74CA1BF6BC5F223802EF93CF7A1383F548196A9B4DE958C49014EDA8501BC8A56B2E1A2B0D46E18101D68816EFCE2297CAA5CC509399A0152232026B754A90FF104B9189426742C2FD8055191BC162B04A262C3D23B996C2AA867F3154521BB19E0A69647718FB76EA5B487C930A454943F0FECA6FE163F40557AAFB9785DA0B6450B0BB4095BA23AAFE83B731356B290DB64B4C39DEB5B30FEF38086E6841B660D41EA593E1C24028C60BC44A6D83696F88772425235A4F05A1847AFD5C84DEDC0B4C1D003F29AAC29710AEDA5053A4C0AF556C4F5508C45FB20141B1FB641AAA6EC6E88D0859553896C31A0206631750C954EE73B415CA163D30FBB75CFEB15714E3330AA346F7DE02014214C2EC5AE550906EC5632CF429BF3467FCB0327017703D08A7F3E9A7785D0C9D6377FAFE527259A0ED5894E2A8C766F688FE2574DF57108C81C60A8705DC7D102891437CB2B9988C879D7403967A83A70CA48D6F1B18A3408BAA13BAD9C26297CC10D920F0C53CAE4D85C6EE0C95DF22321F0A05894CB97C4A45F79CC002DA373AA857B65C726F54B03184934B11376852E9FF58099C72BBF531943EB5626C2C3EF6BCA145A2896B4C1BD29A353F49EC2FBB746134C1F50AE6D771160E64848396A5DA65EC32014F9669BB83AC52298B24DC2AB0BA2C82C0B4017B34F9D979D7D07659C4B76160999C47221DEE91521418948CB2EA72532E6A1C273B764D3160EA072A48782336B648C12B6AE93B5AFF289F81236AF0F9A338E8EC35154DB40386949D6E32A71D635053D5F55990C92", + "dk": "62BA496B01A577F941C19004EACA6997F59F417945028925FFBBC684CA3BA6D1A1B9427387E7B7E84A1AD2E00418D471BFE304428AB3D0F1587411BA3971679FD42DDF418546B6681AC8AE63774E62F16460402A3A4730505A650D23B2E14534A1D00CF974A0BA035DA2E29A4A616F1E7832B3C37181967DDB5C37A18023EEB07B0E645FED3A34EF4544F336960CCA7B83A2139DD671C8369016A1BDFDB6980184B98E376A92701D36D07E6D0964ADEC327EFA08D0F84283A58895466A47EB084E042938450D5A2209962358A719B305844210971766C2A756D372B1228302601853C37B3F1AB45571C6F714528F223BB6F8A74F91BCD4840E61924872F7B7FF7469BE8935EB743BED787E4FD753D56494C44591B15990A4F9445856C7938CBD38D546CAD98179C03DB1973CB4BBC3DBD0AF79B28386240FC008357F346552F21ADB551219433E3950675F100E10345B942672205924A80607D6160BDE629EA14C012EC62817D28527A80BA5081F7867AD3516193E80B6EE726428F6409BC6B0A391A6DDA32839A9B6B9F23625DC1FE2CA6FA021BC1A44CE6DABB640E480CB0B5306E5A466BC4C16BB51CFA79AA5467753A5A47873A11B0C670F1C584C4AA39C91A76BC361F1DB598BA63FD3490517DA397F36C669686BC6122131E713AB8083C3F10869C80689B5141BD4BF1C92C22D9ACE8651AF5A236132428E2C2A064C977143528CF9233DBE4B8B913A69E8C34D97D5309A9B1EDC5915EBC42138C93005C2C4BF7C83E857379529A6FC124C4297568EDB7EE47C031308A26B8A17F3F0BA1D217142E300340945BE8B0A85035C5F926ACD21066B8248EFD730E842772996259BE076BDFB1398424360EB38DF029E9893A274E20A44A87CB4FA5E90A55099F96961AA5BB6E69913C7B9117697570A261A4A24C3862198D359114C767092824BB7B7684BCAB4B7017CA3172DE25C187B4728792A305C966BE64B7F2A8A22432136B864E75A14AFA433B7A1C617D80C3F20707124BB3B53CE17E605DAEA53A6677530305C56927D5F5C8493E33B1C37B4D796955CD4A7DC60C56A44703AAAA0894C58C872A67C630143FB29F5C2533614AC1ED6CA436463EFB38C7BF8A8DA348DAF4BBEF00A8E61E650CA9C6BCAD30CD330CC2D032ED7E42F41A9967C3AB568A0301A5A12EF70A2A6EA97B187691AEAC151029CBE350065B0C2239B67E303050D92A692237E21900BF2901A69231B14F04901ABA8D22A881365B943BA429AE31A72B8701CB07029E129B5D3BECF9090A70A5D3A86BE1BBABCBEF35592A7A74C2CC0560C0EC2ABA3095589C7DB2A5849CBCD483730F479ACD55B212C942F900407E46C0C584200C1CAD7D05C7DF467FD31C31E266A50C375689CAB1BE672774C77062018E74CA1BF6BC5F223802EF93CF7A1383F548196A9B4DE958C49014EDA8501BC8A56B2E1A2B0D46E18101D68816EFCE2297CAA5CC509399A0152232026B754A90FF104B9189426742C2FD8055191BC162B04A262C3D23B996C2AA867F3154521BB19E0A69647718FB76EA5B487C930A454943F0FECA6FE163F40557AAFB9785DA0B6450B0BB4095BA23AAFE83B731356B290DB64B4C39DEB5B30FEF38086E6841B660D41EA593E1C24028C60BC44A6D83696F88772425235A4F05A1847AFD5C84DEDC0B4C1D003F29AAC29710AEDA5053A4C0AF556C4F5508C45FB20141B1FB641AAA6EC6E88D0859553896C31A0206631750C954EE73B415CA163D30FBB75CFEB15714E3330AA346F7DE02014214C2EC5AE550906EC5632CF429BF3467FCB0327017703D08A7F3E9A7785D0C9D6377FAFE527259A0ED5894E2A8C766F688FE2574DF57108C81C60A8705DC7D102891437CB2B9988C879D7403967A83A70CA48D6F1B18A3408BAA13BAD9C26297CC10D920F0C53CAE4D85C6EE0C95DF22321F0A05894CB97C4A45F79CC002DA373AA857B65C726F54B03184934B11376852E9FF58099C72BBF531943EB5626C2C3EF6BCA145A2896B4C1BD29A353F49EC2FBB746134C1F50AE6D771160E64848396A5DA65EC32014F9669BB83AC52298B24DC2AB0BA2C82C0B4017B34F9D979D7D07659C4B76160999C47221DEE91521418948CB2EA72532E6A1C273B764D3160EA072A48782336B648C12B6AE93B5AFF289F81236AF0F9A338E8EC35154DB40386949D6E32A71D635053D5F55990C929492E80637971E303800ADF446B35E44F02C1B2936E5381CAAA9738F9F9F79B077A1D61917B642825666A5D08C5DCD13E5ADC0A5E248F28DA3A32BF1188864A4", + "c": "1077E1871719ACE56B2178A208B3F891C187DA970A51633C9996D278EB738375627AF9052866F15ADB21D21B8D0070A19A3024893FA32773D2E832DDC2480070FCDC03A61504857CC40E0E024AF04532E288F5F37F3877303263F4C66848ABD68E5D7FFBBA91B8BE624B63019D69088ACC1C37E79AFEDD5D1D2CD7721A0E5328AF2081C19417873E2B29794A2D2BAEAF67783B64BFD6E473B27E6B05EACC6079F4B8EE61C07FF13060DA3DC04B556307A1D6A7B896AB496CCC52C94897885E59061E70D12B4A9EB0B4C81F331CE3AE2B47B753CFD5CADF96E9C81EC90021F28F3FD33E2EA2EDB61B87D9B7894EFDDD968DE92A232A148AF1F0C31CA9419DE93ECDCB06055FCDAFBF655F2FEED26D3A6316BA259F7AC18A15893A95A635E364A1338C4EAF1F480B6E6DF424584F8DF7EF411902CA5A9A12FC440EC4E2E9CF0E1C3631EECE02A5134B793EC9C8EFFEA700CB8F6729C413AD1432EE4C8A92AE41D9FCA9D19D7871ED136EE3E0B8ADAAE428F0D4BCFCED8C107040D53C858DD2167E0415C98F46FB6327FE7D1B0359D8B3F3A491F4C708CB46064BF872D8830580D41AA8BA93E40570307A21554E5204284974F23287BD6A92D8A2C64A6F1687FBE7AEF7E224455F639BBE235F027DCF160D7249FF010F2BF6E1E358DA17314399C4B5129741E1171B0BAFF8E5BDD4A7BB8DA81F8D387BB32B8A3192136231C49D9A5B88BD1B6A30A9DA7B508893152FC5FCA58592F808E98914781D48D0CA7314A9A166F5154F9354D060BEFFDCCA00227F3BDAA59672820803FA83720D5BA5035B78E02E3ACA332DD0427CA7B2075D6770D8DE005947EC6E82389117D51C7186ECBA9F0BA3C81BF927AC6D75ACAA9826C612328A908E47684D7A97D49673261A7794EE63B9E99F378FDDE9580492FFFE99535CFC76C4D57CDAD1B5C51E751FFEFABE8772F6CCC1634808E2A0C9E09548AA41A267CE0086BB78B14163AFF59E45D603C495E3B1EBB4F2527A5B1DD4638A5DA9CF1429370E1A2F886EE35AC4287FDDC19297F7F96C223191698B35C4C78E1E4A46FFBD3B3CCE38FE63199BB8D46B1E", + "k": "F7AE95AAB26A52F3E8976BEEC50476D3B5FBD7ECF1A610054DC199A99497A1B9", + "m": "4F7798D88974637071717FCAD2C0ED5333945D51341FBA4BF1962A3915D986DA", + "reason": "no modification" + }, + { + "tcId": 20, + "deferred": false, + "ek": "42803BF789094EEA7D875BC10D50C7D3947CB77CA48A301323B54FDBC94E480372E54AAB12C9680765A3E22988FF42184741A440E348C8D19EE8E7CF87B23CE6944663A4B28937160B0C25943A8742F811D0E417CABA034628A11FA2A06E3A5F51E47EC26A9AA5209582F73F1C705F9CAA74F1F300FE9049030061B9C61DB9999E1498BDC9250EBD324F61827463A6A5104796EFF25405AC687092B78248A2F9171E891729CFC11F86316AD6754E8AD249E7849958B2AB380783CC4123BBC087EDF1075BA8304E339F01242C15385A4007616D873587FCAA5AC786731447DB8C537F0CC64731A790E1BF23412AD9342F9654B87DB07E8EA506C534611F48A9453855CA669EC8AB548F648F8AA9A715D0BC09757A285320DC666637950A691AB8E2630A08B59258205BFCAB9DD37C94B9F4706A1114FCCB806E54751A12576063666252CE7F5041432C095CB469B5A1A634508CF1E2398716272E9570C1790FB53A3100D57B5EBCAECC6CCA50B4656F5219DF477C8AD4B7B727BC2BE25246C526D06B8DCC30423421667E554DB0ECC21837539F43A719CA8952A95B143745F79899F7D1C79BD546B6559B1109BF6D60275CBA5DBDCA608FE34CD96369D67B880CCB00F4B3CE6D3C6CD3A35DB44A6F8E440215B027E03109A6546662789B6A096784A0C64A1A4F07F981CFD201F3687691955184684E22C872400749A180CB5B6317599316790A7ECAB711861469EC794FC894AEDEDB90E45164413B82F18CB162769EB92A47630A98FDFCB09C94456E74C0FBE345ED88A43466860CF0472B6C9D4780AC4CC7189F77A19684C54789A9CB99CDD46534914B1990659E71F2662933148E13272E723C46B4809CB32A42D378DA7688F21CB53DA08AD3897ACBA940640089C73049B1E92C94C943D5EA32EAA19AE7EC072527912643ADCB591CC86B97696B98386615AABC1D32D23D4D22919E35786E77A4E7E30C2F6730DF129089943FFCC1678AA600AF4C3F40741867DAA06701A8DFE6421CD0A5DF34C32C933C9AC2B141C5134A7BBD469266D952AFF44995F8904A148B363E3C2A13978A049B968E24051FF6E312DF77FC5663502B0187A5588C1D84149B2DB835045F9BDC1F70", + "dk": "DDBA891C987B8439ADA0114885B54CB210ADE141C92E3226F4B25E1303B93A68092FC95B5FD9BB80805D8EB2869AE6320A90458E4432E6510ABC3C478C291B63F02E476235390C0162468145234744C6208D642DE2E56031A95B83843B7FBC2E20A83AE5229A4ADA7DEF77864B975D475132CFE0C94BCA0762E369ACD52BC8C1135BACC67083819EC229D8962E989C1FF548A127F86E17C60C8695B592D1C9C3689EC3A9096970931BEC56E99499FB3AA982F663F67CA547115D320ACFECE132B3CA9CD5D223EF20B39F7B78E1526E82C816436BCB6FA822C105319AEB9D2B5450129ABD8D1971A043AC7BFB129B5504F35BCB13DA4E1700CB215A3B7ED6512F558D62EC83DAB765D0816B4D085C09E0035E830996EBAE1475B86F39B23613BE9E403A12A7ACE2DCA602722C593043301A35B4DA84A3BC1D53107F3C1C6260323739C27CE09566882BBE3B31C86CF8381EEB10D86167F300A6E510A70E0A881F282FD8C4A1DCE069F417753F069EDFE46A91837C2FA57D737B425B7A4D0544B6DA399368926296C98F7C5C2532374B95C03F3EE15E526B98E2C48EEB3718DCE2C9FB760147434D6FD1BF040AA5A329867DE87094BABEFA563759E49E1A94A737D6488E2280DE5BC827A90A39930BB78CA70D33A476C65CC9F6CB2F8BBB7024652E43212821568288533A51627F8765E1B64AACB86F08333A428AAD4902518DCC3F77563BAD858CA32515BFA8992A5304D8B69E5A6C79E40B7D361B70C2762BC359CB08401AF7967D8C3186EA826A3C4C0748F67E471B92D3216D39091F26EC477051CCACB27696D9AB918904D75743A709CDD09460AC04863B5412E6E935CCE23B3F6217FBF2CEAA6CC37B8C2B6719C4661510A88BBB74220622B589EBA490309A0FC8E7998739CF6205883BC64B86A317A3E1A86F0C65348C2D62A741E80A8AC416467133581BAB2EAA7B5B88025F4711914ED6996DA29E429B5A03C358192C049AD17E6280CCC231AC0C075E3396AD9258AEFAF757FA23259CEC41F5E7CD7AF7B12DD8219AAA5272E7CC30C240B2E2A7B92CBEC265149EAC2A42E3B92C2C0242803BF789094EEA7D875BC10D50C7D3947CB77CA48A301323B54FDBC94E480372E54AAB12C9680765A3E22988FF42184741A440E348C8D19EE8E7CF87B23CE6944663A4B28937160B0C25943A8742F811D0E417CABA034628A11FA2A06E3A5F51E47EC26A9AA5209582F73F1C705F9CAA74F1F300FE9049030061B9C61DB9999E1498BDC9250EBD324F61827463A6A5104796EFF25405AC687092B78248A2F9171E891729CFC11F86316AD6754E8AD249E7849958B2AB380783CC4123BBC087EDF1075BA8304E339F01242C15385A4007616D873587FCAA5AC786731447DB8C537F0CC64731A790E1BF23412AD9342F9654B87DB07E8EA506C534611F48A9453855CA669EC8AB548F648F8AA9A715D0BC09757A285320DC666637950A691AB8E2630A08B59258205BFCAB9DD37C94B9F4706A1114FCCB806E54751A12576063666252CE7F5041432C095CB469B5A1A634508CF1E2398716272E9570C1790FB53A3100D57B5EBCAECC6CCA50B4656F5219DF477C8AD4B7B727BC2BE25246C526D06B8DCC30423421667E554DB0ECC21837539F43A719CA8952A95B143745F79899F7D1C79BD546B6559B1109BF6D60275CBA5DBDCA608FE34CD96369D67B880CCB00F4B3CE6D3C6CD3A35DB44A6F8E440215B027E03109A6546662789B6A096784A0C64A1A4F07F981CFD201F3687691955184684E22C872400749A180CB5B6317599316790A7ECAB711861469EC794FC894AEDEDB90E45164413B82F18CB162769EB92A47630A98FDFCB09C94456E74C0FBE345ED88A43466860CF0472B6C9D4780AC4CC7189F77A19684C54789A9CB99CDD46534914B1990659E71F2662933148E13272E723C46B4809CB32A42D378DA7688F21CB53DA08AD3897ACBA940640089C73049B1E92C94C943D5EA32EAA19AE7EC072527912643ADCB591CC86B97696B98386615AABC1D32D23D4D22919E35786E77A4E7E30C2F6730DF129089943FFCC1678AA600AF4C3F40741867DAA06701A8DFE6421CD0A5DF34C32C933C9AC2B141C5134A7BBD469266D952AFF44995F8904A148B363E3C2A13978A049B968E24051FF6E312DF77FC5663502B0187A5588C1D84149B2DB835045F9BDC1F700F0ED35733D6D2807A9D1358FDEA6AAB613409738917AEA1C9F4D0CBAC25D0298A10A703C91D253B506276C2E15E683FF297EE8713F9AA8F400F73AFB9DBB392", + "c": "4391421C7C0C25DA903B2A944EC32FAEC0E88682FB3146AA621952E3219016F2FFCF97EBB7C7D6EB95891350EE783147BD5B0B1B089743DFEB15C4D81D6BA42B119A7765A73F19EBB39C565D2564EDFF9D57B2C48E8F42DC891315198D9EB17A9C5B5A9FCC169EA8695D1FCB82A96F79BB5432D47BB06106A9AC0D0AC91C3A23D28FFC19971041716D6688759DA314D6DFD40D087489E85780D7BA66D9D526E70038A5DEDFE6576DD240E7C3E3A629606632B71CA08CDC9206F593B51B80190364FDE88448EF5F110E650DE902C27E48BB82E9F2A007610B671AE048F29119FA07A98C86A46174598E0DFD6BD21C8D59C95408600D5181D600EF0BC302ACDF00F99E6D391257432D314696E4E12F2FEE1334574773F28EFFD813F70E9327D83FC239D04315B1F9C95C4C214B71946A733503064F3171C17DCD219DAD8BAF21A31EC0F9817B6A8B3C4B73C43B70357DBC771955F797F8BA28B56F31032376044F3BB33EBCAAE4AF9A93E2584A142008AE3A9CF75ADC2B3AED29ABCB8D03B28DA272AA5E4A695F9E6CFED430EFF445881F9208913A2E0CD61FDB5BA029D3228AB334EE9CBFC730AF95161ECDD1852E52C41291E0CF8ADE3790DA710C5307B5EFFF0E528A9FE2F6C2027E52501244A3E29CBA29E6AD9447AB43F5B4FCFFF9F3A8E7AC090CF1C6D2BC85B39DE79153E7BC36EF2D37FFC98D9BB21D37AD41E457D5D4E36E7C128DEC48422DB0E26D3E76823687F39D43ACDA2F77531612D449295D1740EFC6AD532C233F2CE6A14121C62171DF4B7166355E1F1E939FD597B3038F54AA056BDEEDB25026998E1D0C047C78D648C2D3373782E1862C8BC0D9BCDA9FBBEAAACD80104122091B3AEA9EB113533C75F1C2FDBA188A08DC549D229F408B592CFDF438B61E8321A367F6956CCA81F0E13DFC3CBD1DC9FC1504307A3F14843B4B3E09571E26FF61F69F2775BEEBBEDB5059A3333D5BFD5A7DECCE8FBD89E50B8CB5C52779A9B9CB19866560DB4EE457E3D18991A561268869E47DAA00C59445ECC7B683171CE81E58CD4FEFFD93E31D5EFAE77CCCECFC995A16DC190F59F91A", + "k": "5418AE44ED01EC65F14D5CDB12AB6004B35744E935AC8A9C3D8D607F946BB706", + "m": "E20AC1D70FA6A2C8A286EF0E3665C79668A5E6AE80197BBF13A0D0EF553ACF1F", + "reason": "no modification" + }, + { + "tcId": 21, + "deferred": false, + "ek": "39B893D833BC95E37373D2C71FCA4336AC84DFB6460F156174B7B95DA92351468EC97439F2B88656F9B0B944850F499415981A66B76333402D43EC30F511AFDE7623BC00A1C58136484350A15824AB0A434561CDA2305C815318D204CA0315C5C9703954224522E76DAB0716719A06F723006D66A2916941139B1F29E53783E6BCC568628D6B0A0E72A44D3C19BAF35FD6FAAA9B2396CABA9B3BEA5C901B836758671391304E5330448A62CBAB155811C5018064FA002A73A71EE6146458DAB896B716560649BB823BA9F73ABFE44E80E1C4D0D58E8C9B397A5841FF9C93CB8488851C482C534BB710B27C6C9CF7A15356427EE8F1B40815A9416B233F4A05065495D4B88BD2A42A36DAA392A9CE49D67F4017484368017FB91ECDC34488F463B99A6CE60359A7F3C32D3A3DFAB70817726B73BC1C36FA4CAC3A0EEC9C6BD3A63DF9957502076150C4759F5362BA493F71D669A724C79788532DA797445942FDD214C3A9103738C00AB54CDE3639497A951C03A70A0B01182B2B9C8C889052857A2A541EBBBB77C78F90377EADA6CF21796E44EC4D5BF03BBDE6773E571785F1847252B1D7182BB4B08B41C54C889072CA0922A56C19CAA890D7F899EA21C9186A3A7106458BDA086FE017640B77FF554FEA32A2C2297D82144EFFE20D7836180CE46FDBDC18D357B6FA7ABDDB2858770598C03169BFCAB9B8794BCC48B779E87672D83F62E04D2B42B7E31451273BA0362B682C955C382442C010005E66A2644550BF9390FB427E4839616AD8C8342ABB0944B3ACE932FC134BC6EC7C16D35427E22DBC4A454D9B09FB49AA496BAC88909F54CA88E1747E1081AEDB23BF370394D3492F5B6AB02C721FE3E0A199AAAEA03A91EA1C44FCB70BD4140912AAAEC9F779DCB4A8C0CA9D903C0FA15BB7E5335ECB3724CE621D602772255775EEF07ED060734E7365ACBAA557E25AEC10A27EF405E1A431AD8052E0B752A08346D1961134C77CE4FA356D66094856141EC05FD7385D009000DC6C4F97A91B074CA154773498F61C646951BA5B6B5D50C4E35C6206A6C33043308B474A7CF587C0F07578DB4D6FF52DC654A5BCD997296C79A97F8C16E5667F527DAA3ABEC018CF1671", + "dk": "F5A19CCA8A702ECA16162166BE451187A9300AB182DEF2987683383B3861ADC83BFFB41FCED714706AB26B1751B53B09282500F3320776A4C75F22C7710636C21B008988203599BCE9D53EA8E044E9F37720D2C1E34101186B896FC590A6593AC6B2131A093185C82D61D58405780D16927BF7514B9814BA5CB42B4AE66A37C55E06044CC0CAC774B01CEC02554CC40FE55326A612AE1DC76D7BD6418FD01C7ED25A15AC16F5B8129265C54B0065758390EAEA0F69B212D33B94A4854E912172BEF1AED684AEAF1560DB303AB1FA0146C715EEA9950D317A87953730B32886C164FD7845DDF6B3894A7460509DD9122B12A3938EC40649537EF21592BAB202500331ECC1A39C5AC2D63A1139AC93E18886F68189078C7090593584D59C50D12A2B5CC08EC6A9FD33BC3C2391A7C3BB4FC51F6A536D962C6AB3EA7978D57290719A80A8926A812CD034422CB0CB49416ABE61B03B041E88882059624843679AB699ABEC6988D918710F5B3FDB188B6031C7FEA47C292A04E05CA2961BA4263C298A06956631705254AAB817C46903B537328B6233B06E9530F0AAB1F3F9C16BC6276B746DC0F44FD9A476CBF23DFD27C45B4B56F8B5BF9AE0092028CE72819DA1C6A5FA48942CFC0A24B04ADE63B33642B5B112CECD370C3F3930FF6305B1B0A1D2C490DFF73706A8AC5D34B21CD8AB8D3111559B915634430D9C78460961F805214DD2434411C1C28C769DFAA9FF19C3E240638181B5C83422E5431028420F74A707914354881938BA842228D2C19440CA99DA68AF9372B8AC6D68A34CC75832C41B1406C66EFD1161E8D0B42CD27EFB18A162006375D40E13E24FAA32489DD91E0DB8A32F11A4BB9139E0123C5DB00D5CB1BD4617809CF3214C581276312BA0819699841C6072128A8C3046656AE6815B78F61AB3890FD7E2BAE1A2A37CB27D3CFC3E4EAA84F65350E5DB36DF499FBA17839192901FA7570EC72381A86581B69760A277A8E63EE3C16D0FC45EEDF4270EEC32733B6D0DA8BFC0539D64136E4E260725191B78831F37F942018946C5113807F9161BB89F6A168C6CE2991DEA0F39B893D833BC95E37373D2C71FCA4336AC84DFB6460F156174B7B95DA92351468EC97439F2B88656F9B0B944850F499415981A66B76333402D43EC30F511AFDE7623BC00A1C58136484350A15824AB0A434561CDA2305C815318D204CA0315C5C9703954224522E76DAB0716719A06F723006D66A2916941139B1F29E53783E6BCC568628D6B0A0E72A44D3C19BAF35FD6FAAA9B2396CABA9B3BEA5C901B836758671391304E5330448A62CBAB155811C5018064FA002A73A71EE6146458DAB896B716560649BB823BA9F73ABFE44E80E1C4D0D58E8C9B397A5841FF9C93CB8488851C482C534BB710B27C6C9CF7A15356427EE8F1B40815A9416B233F4A05065495D4B88BD2A42A36DAA392A9CE49D67F4017484368017FB91ECDC34488F463B99A6CE60359A7F3C32D3A3DFAB70817726B73BC1C36FA4CAC3A0EEC9C6BD3A63DF9957502076150C4759F5362BA493F71D669A724C79788532DA797445942FDD214C3A9103738C00AB54CDE3639497A951C03A70A0B01182B2B9C8C889052857A2A541EBBBB77C78F90377EADA6CF21796E44EC4D5BF03BBDE6773E571785F1847252B1D7182BB4B08B41C54C889072CA0922A56C19CAA890D7F899EA21C9186A3A7106458BDA086FE017640B77FF554FEA32A2C2297D82144EFFE20D7836180CE46FDBDC18D357B6FA7ABDDB2858770598C03169BFCAB9B8794BCC48B779E87672D83F62E04D2B42B7E31451273BA0362B682C955C382442C010005E66A2644550BF9390FB427E4839616AD8C8342ABB0944B3ACE932FC134BC6EC7C16D35427E22DBC4A454D9B09FB49AA496BAC88909F54CA88E1747E1081AEDB23BF370394D3492F5B6AB02C721FE3E0A199AAAEA03A91EA1C44FCB70BD4140912AAAEC9F779DCB4A8C0CA9D903C0FA15BB7E5335ECB3724CE621D602772255775EEF07ED060734E7365ACBAA557E25AEC10A27EF405E1A431AD8052E0B752A08346D1961134C77CE4FA356D66094856141EC05FD7385D009000DC6C4F97A91B074CA154773498F61C646951BA5B6B5D50C4E35C6206A6C33043308B474A7CF587C0F07578DB4D6FF52DC654A5BCD997296C79A97F8C16E5667F527DAA3ABEC018CF16717815E832D512DB0C38A08C78F9C7D3CD3010367902146A12A335AD3148A3C8BBDBEC6DE5ABF972F91D59054FDF0B3F927DDD6EC3477C162C2294048A4E6C3FE2", + "c": "9CA67EEE0B5C186A08356C38E33B9E7317637F3CDE3EE9D6E04C1208F9B9CF63386553425BD51F35E523180B29E3DDB8161F1FC632528A5D5AF0418F5C32B767106A774E5D97047B0A49F6C9FE2ACD3C12A6D45B49BAB8A4C95958507BDEEE88B4659373F8A1D605744F5B65AD2E5A5EA081AD2C55670793CB78691B2BF2CFBA1FD1BD6AD4D9E87FBB64A52CADAB26B4D66684AB2FCAE330173F864FBC3B6461ED1B4EF1BB054D59F2CE2B8C62CA06808B99AA29AB2BC941026494B3233FB5AC8B5E200DE2F2F40DB93C0F567348033C1CBF08D491F3CDF59835791BF4751B4A22AB312A7A9C6FAA6B3FD5021F10F8F3D5C0CCC40483CA28322CB75A80E0DA05BE5D848F43CB3473864B26591C27DAC580D354A9D2DB35C9BFF76B42DA9675A2CD63075F33C2A1D1626992D5ACFAB3E7DAFB8F017F54757C26074DBFD523F18C7757ADDB23476528D540A96EC669E6BF0C1DDA200BABEDB965511546F2C96024D344EF0E17A4481ABFB5C2C07C8D23757321BFC9A58529D5B71428D08A056083E5A027BB059E2813AA9A015BDF7C941DDA306B3C54A08D1613109716F11FCA932EC55A4D31806BE21C47CB1B10A88587276C57CF389CA28AD40EACEEC94A57A5361007B5A85F0A44E5B5E8E354B2EC791F42BDD1830CACF5722788A48837AAD2A2DB34E33B56F9C986DA6E9C485FA96487C1AB608CE903B6D335C47B1ECB129D39194B99DD369A122C6A16948F689C94C8A54D6CB4C5E39D073570460BBE04AEDDB0D0432B69E1724DD61A8941B9C2D26B49ABE6CB87FA1D093CD6DE08033C77C11808B0315D8B347E7EBA33537F99F64250C65690F8AC19951679C580CBE6E36A7FF0A624FADFC84B220FF5EB7B9BA306B4A03DCC305669C1DF2210FE76024E21904E1950446EC85FD5A04580CBD9843D5BE7F90F82A901BDFEED370AB83D416F92C58B5CF143D4306C9FDF43FEE62B6D1A0248C2B6F305331F4159382D92AC6388614EC84729450B85B7DDCCBFF9A97403B186DA21480DFD1DDA6499600C326B3A813AE123F8175D2AFCBCD5A519BF706CFCDDD6F36A2DEE5FC3F34263D8CC", + "k": "89D60F46DC4A11DD81C284E97631F08DE239C06B157529A15BF9B53C9EFBF9DE", + "m": "AC25F29AF8D8A2DBD359600C8A500144D6C0236D729DA016C3F116CBBF621002", + "reason": "no modification" + }, + { + "tcId": 22, + "deferred": false, + "ek": "0AF62D21757B6AF2C9853421D2D74E0DD86A416A228A9035299C27B32528CC526B371C56ECE17C93B7CBBDBAC84D35441E6B3A17811F3C0A6556825174AC3C2BA51D53F176F027C20FEC424F7539ED3C6C7B964260489C3D8BBA94323630B87E856064E3BA81D3F018516971DFA54AC903C9AD9747AD8C5DB35780A033C385C23CBCB21D26153F93626C41237A02185C41C3935B306FDF568F453B255072348D9716AE9CB9B9ECA6FB0B78DF7927D093A3BCCC7F7BA711B27CCDC0051BE4A31BF3A0B224E0770BFAAF26F599AD190173A4A012A52C29DB006CD37076A12CBA65B679C10455E5442D92609DF209F6556CA36BC852D3A282F14AF3EB2A852AA268B1AA92346631953204F4ABD9726338B8B275A26ECFB80428881613C952545B082AC2BC75699F3285AC10905A00449AE6A42B43D1A4890155A9080A587090F7C91FD97833E13B601EEA06104CA41C408EE73C055EB1CD9FB0934E25660381518758CF3A8C95BB0397931427FCBA515D320D423A7440459C614B9ACDB25A9C143A6F704541A339D9811409D6BE200429B33674F61CA6626C7FB879001AC65F08C18310A4BCE685C37944079DA907316060A64069F87CC5D9FB3B56604AD8A52E72A1405AF5C549498F147CCA4A7749A37B5D96084B01AA3241288BD22592AEEC778FAC1C4A2BBF6085C2B5DB7D9C00B9864C480D8826C2E02B246AA945EB61F9425DE8E604B7D76486418FF0F5AB59BC6EEBB4932D6075F667A6AFA74BB66255F03C6F15A63818E759A4B05F480A4C0CD1072E26627513BCB85474E89676501AB2ED21A8F487780CA8CB8560B27A766213092DCA0B02ED3A24C8351EAE88947A764F142C0E24B192A2421367265C0B37093E0A69AE31756C5906845A8C7D01550E07C72FBB18DEF56E1E8B320F688110C4C4DC7680C9FA05D5B1AB63EB65450283ED6A52F9F535FDEC31C207A483413725022A2256663E2657977660AE63CA8671A8C343AFEFA8C43D9B8D0B93B458416CA4C5B87D121469EA5B520ABC0C079546BC1353757AE2BB1D301974BA03C86F624F34A4B481B29036F59F37DC2D5C1721EFBE0A0C22A966C895E5198A91F916DE62C0FB3A769806AE5827AE6F358D8CD6", + "dk": "ECC90EA4A07BB0F318F976967D17B40206A6D06C00FC1CA6AF95AA38712DB92093E8E94CFF6450BE071127ACB7AF76A5FE8A71FB511488E57DBEE396D65807A5D0A86BAB9DFAF69DF38A362E62ACE8F7AE7CC638931716F2411ECCB621CDF181C4677D66793AA969BBEAE71211991DAF14968C95754B2BAFC6779BA5E4697094B28C1340276322527C7F259B4F39CA48AB2AAD90B2959BF1B12F983C0B3B9014A04392902C5C47A92987ADFBC654BB87C4DE63AAC4B2C45A3BC37972A607F491C0D891FD7BB9FC96032850BD110A2B09EACC134B9E99B5A09BB11D9D5163B880CBD73817085C68E571AAB45439A79117F7DA5E81735808F97A42249728A0B63834001D1C008AABAFD72A068309BE74D49C7BEB0EA9251BE6C1C7323B84402C725C212D361BBA03385FB7641AB1D74B39690DD1448B6B01A85F82A7F43C22B0E3962214246133750D23CFD1776FF64B4D1FE17B8257670379320FAA81447395D7069A74254156E900C9278B9789629EB33CE7C0C867992596966ED9875579CC2A525BAD71E920AB5B0A69E69995152BABEB1D4272A04F3283D988826AD0AB24E24C0B505EA5AA02EAD063D7B587603383148521005034E6162106E29A7EC3926EEC024DAB8AA0A5768C7142EF56A5AF17829E505224A2C3F8526DAB6A76E714766D2450D60A68D23AA4FA392A2903C276A965FD1A15693644515A336F6115CB050709855E95035564157308F3062FA03B0DE2C00269BD8D414C6A574D485061A6A28245375513009F205CC1402694BE76338D0795849AB011205E880537E0696E6F4636CBD9ACE8E279A8015D57108BE0A638B3D8516487BF763257C00A6175407433A204C099BBA4972EDE1763EA5889FBFC25742CB66B9360A6A5661DE7BD4DEC856E55A5BD354E01DC6843B4C306B957E72CA528188403E324AC69AF09820C74E6A389881CE882B86517BCFA881435BC8817A1489250A35EA19B80C62CCE52A0A6935A89E47F658041BC93B2B979A7DE815D97D15E5B55310568BBDCE78C6437C848D479E65C60B75391FEE94683BBC379EB83A545AD98A070F281837E24090AF62D21757B6AF2C9853421D2D74E0DD86A416A228A9035299C27B32528CC526B371C56ECE17C93B7CBBDBAC84D35441E6B3A17811F3C0A6556825174AC3C2BA51D53F176F027C20FEC424F7539ED3C6C7B964260489C3D8BBA94323630B87E856064E3BA81D3F018516971DFA54AC903C9AD9747AD8C5DB35780A033C385C23CBCB21D26153F93626C41237A02185C41C3935B306FDF568F453B255072348D9716AE9CB9B9ECA6FB0B78DF7927D093A3BCCC7F7BA711B27CCDC0051BE4A31BF3A0B224E0770BFAAF26F599AD190173A4A012A52C29DB006CD37076A12CBA65B679C10455E5442D92609DF209F6556CA36BC852D3A282F14AF3EB2A852AA268B1AA92346631953204F4ABD9726338B8B275A26ECFB80428881613C952545B082AC2BC75699F3285AC10905A00449AE6A42B43D1A4890155A9080A587090F7C91FD97833E13B601EEA06104CA41C408EE73C055EB1CD9FB0934E25660381518758CF3A8C95BB0397931427FCBA515D320D423A7440459C614B9ACDB25A9C143A6F704541A339D9811409D6BE200429B33674F61CA6626C7FB879001AC65F08C18310A4BCE685C37944079DA907316060A64069F87CC5D9FB3B56604AD8A52E72A1405AF5C549498F147CCA4A7749A37B5D96084B01AA3241288BD22592AEEC778FAC1C4A2BBF6085C2B5DB7D9C00B9864C480D8826C2E02B246AA945EB61F9425DE8E604B7D76486418FF0F5AB59BC6EEBB4932D6075F667A6AFA74BB66255F03C6F15A63818E759A4B05F480A4C0CD1072E26627513BCB85474E89676501AB2ED21A8F487780CA8CB8560B27A766213092DCA0B02ED3A24C8351EAE88947A764F142C0E24B192A2421367265C0B37093E0A69AE31756C5906845A8C7D01550E07C72FBB18DEF56E1E8B320F688110C4C4DC7680C9FA05D5B1AB63EB65450283ED6A52F9F535FDEC31C207A483413725022A2256663E2657977660AE63CA8671A8C343AFEFA8C43D9B8D0B93B458416CA4C5B87D121469EA5B520ABC0C079546BC1353757AE2BB1D301974BA03C86F624F34A4B481B29036F59F37DC2D5C1721EFBE0A0C22A966C895E5198A91F916DE62C0FB3A769806AE5827AE6F358D8CD6CD2DB91B660C482E6C8B2AAB016B0354DC138DC2BF97D5F960E1D8CC51F09806BF737AC0198871CA09B8C1E4928C4F51B47816A69F4174A4BC9A274F2E10D051", + "c": "398189254F2C82F3B9F6826C377BE31222C4E199954CE883CD44E135BE51E8B1A767969BAAC6FB3DFBF59BF38F2A005798D45B1032FF660C37E1AB24E629D84F79B0673E44D12359CD6632BF4AFDB2ECDB2A1BC960E7B7E12ED89116AC5423ADE1AF5CB43FFD173D2878F11BFF604E8D2B59FF847B570F52D5A5048D16038FFD3A6A86F00513C8394434DB5D87019D6CC46738678A45577698DA6E13B466504DCAE736EB36C83369ABC434B8296C3D9BAC5C46C700F5D0CB0EA37A64017E0DCD82A1301649ADBB8339E7F7C0D6CC42B1EF2690F769BBBFFD50AC546447858CD1B46A31E43CD1133691C4600D745BE6BAFD4E9A4B08E4147DEF63E52516FDC2AAD98A77011876DB533374A85805AAE72B25F0A1B30331750914E79570ADEC5D20B391EEED8C235D295C5C7B3A6FC9C6F8D46EF0F2288785BDB4A99BA461BF2EEE99E58BF46A34989DD128062B511A4724FA7A528CAD251A3D4144E0CC39B89DB093A07FF65204B3A44FD20079ADFE17AAE7AC3306C79495338B73D711C11ECD0BF5BACA4F51BCC6A8CD54EE1D339C146241344433B91436E54E17B7999C3101F4FAC0C6D765407A8F7357DB41C43E1E899C5A786ABA6FA1CF216D8C795A98A9A4E6F4FCB6BD38D82A4AE26E556D672504CB8C33ED921B6CE69FF9B7E1F29FEDB7926956278C1010375360E9F149CDEDC4F44C69D18940E85EFDB467C6D7979549882B94BA635694EC91AB5D3459F244DF94863C180BC623C6FCD5297A1797A272F6CCE06EFCDC1F24E6FEEF30C30D50605D7D7FEB2886854281F573B0ECA200739B307706ACB22B05A6755C50FDD9DDED42442990E9F34778B6615DB04A3F39EE3959C0407AEAB90B580ECEC910836C6E2C30561B056BBCF04EB576284314135CA48630155915195B36039B52CD4B546882F536E2B71E5E952AD560059AFA6DEB52305DC8923FCB52E5C8031596E9596BCFF1F0D05CE5106969532F040BCEF32A7FFAEED70A12050FB21835E3BBEF84C548830C9CDEAC86BC6D3AFACDA53CCA62ACC28ACF22089C70014469D22E967C81D3D7B8BD77F50CA03930B7099801CECB", + "k": "66D121707FFB368BC5D4C73FD24DC2DFB742419B203DED2B3E157EE56044C128", + "m": "7114A4B4195826CFF174FCB75336B25D4D1BF2224D585014CBADB0C4CFBF7729", + "reason": "no modification" + }, + { + "tcId": 23, + "deferred": false, + "ek": "F568158F1981259934435BC2BFD38A4A100BB9826E429312EA3CBF04A5397A723E740112859C74CA0C2783D5CC9798AB3C273D3AD6911FF76BF7235AEA38C4459761FD4262F483AC5D081900FC1EA3337439A3B4A2787E0D5763DDD2100E6A60DEC12B07B84FA8226017456B7F65679FFC31518C172F93895CFCB75FB74054116CA5662886BBCAD5F6B63534703E8B0DC807952EA32577389F94A7355DB079639AAF39B13D9F95CEF9AC9BC4B3AAB0F7070358644ED38C401A73BC2B2270D01D1C207D7FAA5233D74296302A90E4551D380C715265DD0B22F94681EE6093450186738B32BAA1B1FCC3C1F0A309312B662D25120F6B6D31B2B29809537C4A220D303DB4E5CE51B606DB64CA4B86947056015E8857220B8AE4822F28D31A37F63A89644C4E3A797FD7236A52640CDA3DA6D1782E933361A74B2CF665D04A07DC3843A40A0D8C526BE790721FBA16492557F51B6B6904998422B6848C93EA5043A782312C1250D81C5BD0407F5FFC99DF3993D91A71AD8499BDA29427E51BBC93AF43AB49E9062397F58CFD4B8048392AED850D95BB2F26DC55D3D8AA2A7249DFC35DD145569BA276ABA90B78BA143A876C3D97A66E02BDA3A34BD5DC4918F776E2E2C09E46047771B8C6FAB8C5215BE7514900A77567896899E94282E326D4848606FA8F2D350509B19251B4CA4B5B016C4181E8091D501327CCB9AFACD14C6FE4808E6802A8875FB786A52B70359845634BF1C185C887F1BC6FB8221347DB1DEB6C183C412C6D3684A3CC244D37C1C503B69DE67D4B02773DB8096DE18BC717CB3FD9CBA06A370EE84B9ED13597E6BC4CF88474E6956370C88078A56383799DF76621183C70D522DCB8BF07A9546D9CB9873997AFB51F94B49EDE924643900E201097D9853593F2A7E430AF5C57C754142AB462A12D327D04115540B505B8146BB64347A22BC71C02BD2E9C8CB360AAE5C9B173BC2E844CABA9659C2CC695D0019C135963987A5F019989B3064F8A0A8E4CAC8C7909AC4BC028C4AC4750E8C4FBC1433826AEFDDB2315002A27A2B43C539935649890B31710C56BCDDB64E7866BD07009CF11E676BD64E680645DFC88E803063DFE292C2047525EE37B4F3BF7AC", + "dk": "9A6264C4F2200B6775B81585D2665C5FB3711C7CA596C23FA6883AF47C8FF44158278A7437A32488F5C2AAA9A763674ABD01056A767E1CC48D327B0639E85148C8A60F97AC7EB55BDDF389057C72EAB6419640C4EC7174E420BBEAC4C4B9B8A1A726CAA6A27D226529245A6BE1496303395ADD725CCFB43FAA37206011931852B2E117AA93CC99EBECA070B6B9F5C28B60A3469A6497423A638D6C03E711AE1B64CF613824957973F0E30253B355545206585113A4921DBC32336E750CB940C574F7740E145CDD41C6FB1AB4C7186A3BE12026F1CDA6D80A15916CEB8C78A95A094B330C83111F6EB50A6EC17129363F6684443C09716D129ECF0A097DAA50CB021014228E77F6826350C03F16388BFB7578DB3B368591397650ABF39C947736D2D49E1D4625A9DC3CFF2B14520282FE9AC9E92C9C72745DFD1550474AB13510BB0709A69BFBBC7CB2BB1C4BADB45709F093AA24D09CE75BC8DAC99FF5243E98872233E0B51BB87C7785B5BF558DB3CC5CBEDA8D710039D1E260C878836E4A493EF67534F4C269D090F5F0906BE7117F6B848AA72187DB8DDBB62728143A4F569D31439D72D7085C299CD2F77ACB2C8D8C7C33D4860BD9C5AAE7821D1D67BA3FB81FAC8AB513F035816B019B5C464DCA4A289C1E503654E0A8160D1C37174C565EB876644A6EE3FA6107369A08D27EEA331614406ABA1B7EBD91AF36ABB2A7F9870272CEB7EA69DC0431CA1960A8352BDEB4526E729F49AB6428C15C00EC30D6A9757A953AC4D51063973BC954BB30CA1A37C57B1E402C9E7AA653679F88B6CA0BEA8EBF992F7EB422E90697E6EBB1AD72C754130088759E95091AD4DA61B5350138D9387E5744D2B8049457A0E07265A42961ECFA043498ADD3FA517518C8FD8C0C16A059B4E02BBCA459E3FCABC68C0E656C2AADF50DEC8624E14AB964174393F0A152952069160F1A3724234316C290C398F4AE3F7C3D8720464A4125E3F831B3ACAC315B2DF6F58160F98AFEBCBBDC85702584442DDC9306E66BF234B5017B9AD9B51D95C7AB7431428E36C31F8288DB21B8771B12784866A4189FFDA8B7F568158F1981259934435BC2BFD38A4A100BB9826E429312EA3CBF04A5397A723E740112859C74CA0C2783D5CC9798AB3C273D3AD6911FF76BF7235AEA38C4459761FD4262F483AC5D081900FC1EA3337439A3B4A2787E0D5763DDD2100E6A60DEC12B07B84FA8226017456B7F65679FFC31518C172F93895CFCB75FB74054116CA5662886BBCAD5F6B63534703E8B0DC807952EA32577389F94A7355DB079639AAF39B13D9F95CEF9AC9BC4B3AAB0F7070358644ED38C401A73BC2B2270D01D1C207D7FAA5233D74296302A90E4551D380C715265DD0B22F94681EE6093450186738B32BAA1B1FCC3C1F0A309312B662D25120F6B6D31B2B29809537C4A220D303DB4E5CE51B606DB64CA4B86947056015E8857220B8AE4822F28D31A37F63A89644C4E3A797FD7236A52640CDA3DA6D1782E933361A74B2CF665D04A07DC3843A40A0D8C526BE790721FBA16492557F51B6B6904998422B6848C93EA5043A782312C1250D81C5BD0407F5FFC99DF3993D91A71AD8499BDA29427E51BBC93AF43AB49E9062397F58CFD4B8048392AED850D95BB2F26DC55D3D8AA2A7249DFC35DD145569BA276ABA90B78BA143A876C3D97A66E02BDA3A34BD5DC4918F776E2E2C09E46047771B8C6FAB8C5215BE7514900A77567896899E94282E326D4848606FA8F2D350509B19251B4CA4B5B016C4181E8091D501327CCB9AFACD14C6FE4808E6802A8875FB786A52B70359845634BF1C185C887F1BC6FB8221347DB1DEB6C183C412C6D3684A3CC244D37C1C503B69DE67D4B02773DB8096DE18BC717CB3FD9CBA06A370EE84B9ED13597E6BC4CF88474E6956370C88078A56383799DF76621183C70D522DCB8BF07A9546D9CB9873997AFB51F94B49EDE924643900E201097D9853593F2A7E430AF5C57C754142AB462A12D327D04115540B505B8146BB64347A22BC71C02BD2E9C8CB360AAE5C9B173BC2E844CABA9659C2CC695D0019C135963987A5F019989B3064F8A0A8E4CAC8C7909AC4BC028C4AC4750E8C4FBC1433826AEFDDB2315002A27A2B43C539935649890B31710C56BCDDB64E7866BD07009CF11E676BD64E680645DFC88E803063DFE292C2047525EE37B4F3BF7ACCBD82243C1021E9F731F11A6853EABBA8F4E69636C67C2FA6A4718AA4B2BEBB16CC4395DB6F56E75AEC04D1DDE60A119BD846E85AFA528388FF76A185EF98201", + "c": "6DB2BA6A74409C3771A865799F60210A98E0FC38795DE8978FFCF49CDCF97CD68942C89386E5EEBC6273E1C61223BD2BBBE096B43A45E9585076D2A522B2D14FB24A60164B5D49BD4C648CEA83059D12344E32AE6807AC1BF67C7CEEB08C23AC7A0E379FBE383C0986C3B93AD367CEBEE306082B1B26CE6C47EF6F1ECE2CF6EBF836AB453D1A574E7931E1E1DCDF709DED62B534D84BEA05BDB0C6EE0FED3A8465EC43AE00766E4BE8FFA01AFFE5B40165140D1723F3456FE95F62FB4E299295E417F1EA19DF70E45B17FF5951F2D68C87D16FF823FFD6DB683C0E0D89280BFCB6E0E273705230CB70BE7E1890C461A534DCC73C94A2430190E6380A0F48919D7349327E0514F53D4E10677C8FAF771590C9A6E4F8F5443527275962686BACDA101701B399D6BB2911460F84B636C6B1FF92A5D3141CD28A00B1E2484D9A708A1B2BE85C4FBDEF8939634D3DD1B9C9AFF193D9D97850B92880AC8E859C0328551BE21CEB3D553339A5FE9D450F08087465F333FFECE8472AD6C0DD4E41F1C2189178952DEE12A444E1346F744A3A315FF524F41339A0395F65FD97DB4211106118CBCC438BE76087E7E04F47F8C999A8AF661D652FB4EAABC82DC3718739C5D5106C3A85CAB0EC34FB53913000DACE82573FC1682BCE19BF8816B075DDBC871D8DECF5D2350FBB1392A54E94222C9A038AFFEC64ECA6AE2B963D5D45E82DA816B893B4327E0A8A7F11C5D4A2E153F3B4FB1226F707DFA65409439B152B65E38256D8288DE3339BCE574747E5AB26F5B0B114B29A3503DA863D32E3193434ABC77F35807386EAFB37959E9F18C8A0FE654062ED0A589B71C6539A1251B00E816DAAC71F63D35CA189893E0A95D9205A2FE5DA7CD9408EFA51EC442B6EDD8DC1666BE3B222A7429D76A1B70F39A291948D47ACBD8CE0D581F6A8984407377F0CF3A2D7C23A62351B8151AC0FDCB7CF5C3458CE9F69F5DB1E57EE177B46AD28306E1701F91C8BA0864BF447C0E5CB39FFF907EA79B92E86672CE8CB4CC3639FD95EFEC48EB59F855AEE1417ED920BFDA282EC36A2035FD0D7FC64F1B74BB300AA05", + "k": "5E95F007FFA0F4C822238DE22203E3ECCF50020594E1A8D993E8026FE9039159", + "m": "C78E7B1E5EE8F20EF0B67089306E1ABAFD15760B2DD2D7A59D2C00D496FA0FE0", + "reason": "no modification" + }, + { + "tcId": 24, + "deferred": false, + "ek": "F9238B1B1744FCE415242CB135300B13831D95854E3CEB49E72074B4C09B64859AF81A0C078418C79150D0083B8F9834B14116AF308BC7194C92575119371AA9C74C83350519C0108FC18620453E4820810B5A89D42B5B84FC134F0741E4C0466B2C4B58758A3D561EEA095CB3F469C3A34F19A29F3D20C1381669A6AB1857D3859561096BD8B7A917B40D4B754AE5CDDA47002CD870867203D9901AC5B852EB778705360DF4D35DA7B217951CBD2C026A4AE15221368DA5635D17EA307EFABED74342A6C387D29B59868C4955F6A5B0786AF5CB03F130AC7420663E343BF00998D83B9BFD6458DD63A3B5045C467957A729417CC133FB2048B8DB71BE36905B213A1D8C1BEB76BD27A7CBE281C305F44769746F90307B01613080D50F96CB451D717EF5F372D488B6FDCB762927B910936F161764131C80F09316526CBE62EBB07DB7300D7A81890557000046FD7C098999994FB87691A59F437A7F6D3690075921E973805693AC1CCBC6637471B2C561437A8E30220BDA078435455FBC368DFAD026F85417A5DA96D8FB6272D06F785929B38529D5990DAE3C7596AA72B9381121C6C94A7A593A5AA62BE830BFC0BF5B34C57221AE288302559045F3686D8941576EB41F32516763A90553A5727697AAD39B46C5D84A2382980FE3AC0F904DD10C97078B197B0BC4CB8764F22943F584BFA9F3609D417D65B3C367DA544FAB84AD16025CBA7CE7794CB3ACA32F3042CBB4C25605998A74BC16F80B91C5635DABA3B8AA0D90B1B59CC042BEE19709A747666348577088DC4C5C3168CEFCC5C12C3B4A06C08CFE4CBE21359F03FB99E1C6CF8C84ABDADB1DA905C4EB605FB9C8CE7979458080AC594759CDD82A6E164A9EB781F4BB24147039CFC98889C077698B2471417504E99BE7F283B0929A35E14E3670291DD728599181A6911EA2912B48515F88689A73E9688957473B0CAEDE73937C7BC385D6B2FCF6B76017A8F23A2A7CB54E8A98004E0C97EBC826D1A1142D8162EBC9A311C325AAD94900D9B115276E91DCABA8D015D8A549F7F56A4B182CB3304FCFFB3232F64C2FCB839420663E9391828968D6FEA820C57B8816E1F5D3B414481523D24B81E1E2C429FFF401", + "dk": "DA28574C93C4660286CCC27A47B8437391BE1A3774E46106D689A28AAB03C3BC86FD066384FCB69B51840B1647730A63B7A44D338C7DCAACC24DDA232615962E027E4F5A6638A222EF484826EBAEB557801EC3C0E597BC9653863C534A5232024DBB234F6014E940346B27CB391B87DB64CDF6C642FE87C534D554212C4A8B531AF5F13F1BF1B49E837A2080908C802567C23C7FC1C4274152C8E3A11AC92D9C71639590007C2175E3396339A55F9181AB21525E1EF64EF64B08C3739EF003A6312A439D18AADB1673665B3E154241708C88551941EE9C6DD1126E3C6294026476586907AEBA78A9D04F3E885EBE6B1413CB01BE3383A3DB7626500D8A95C076A7CA5F0CCB7CF785C6939C7E67A16E015583433739D588C0420D57F4719539722B3B4A1FC8A89F93C5766280C2DB4BE16296DB8236A4F7AD2F963A24E9CBF10659E4F7332EBC549471CF84A0A7A17A3942947E4C807C11B37F2144431955C9C4BCC6A9D87DE013408D6C735F9C150F51290254C70D1573838271039661D9860805148B8721A0D73C6589A49DB56C5BC524418DB313972A0277773EFE82139F800501ACA4295A2E95933D0C97A38B27814775C951C0585413CCD8F2197BA169A599A0F8429279584D38D569FF4B3F8B8B40D2C11DFFF524E490490CA21E7312A5B4423D6AA46907B9C1FF46173F3A0C257A80A8E9601C5C4551EC28F52433B62A1391A87EFC466C2AD564EA4B84D8A50128533EA32663A0969CA22A4E34622F1EC1659A2884D76267F904A7D1BBACE0FCCF8340B1680A3FFCB1A53B3213E59C5A7245467CFBC5C1C27910E97F455B8B4B73C04DB36DDE46C063F9AF178853DE82A83C2AA453286B71E14BF6372D4FF46EDD207962079C1E46CDDBF5C40135765465AEA5B5A2BD9059C32A530A8816A63126651AA0A446AA6EA30FC6B09E0F6350EE4C4BD2A750020083B1F60AF0B13702DB7B69693D2F00A06710B7C59710FB813C24E27767E28A1422B266D18A29664B6CF1A179735640EACD3C0A8FFBBB9498D57C4F399DF0F638537A6815024C04D70DF7378DA0910590E58F59977B858465F9238B1B1744FCE415242CB135300B13831D95854E3CEB49E72074B4C09B64859AF81A0C078418C79150D0083B8F9834B14116AF308BC7194C92575119371AA9C74C83350519C0108FC18620453E4820810B5A89D42B5B84FC134F0741E4C0466B2C4B58758A3D561EEA095CB3F469C3A34F19A29F3D20C1381669A6AB1857D3859561096BD8B7A917B40D4B754AE5CDDA47002CD870867203D9901AC5B852EB778705360DF4D35DA7B217951CBD2C026A4AE15221368DA5635D17EA307EFABED74342A6C387D29B59868C4955F6A5B0786AF5CB03F130AC7420663E343BF00998D83B9BFD6458DD63A3B5045C467957A729417CC133FB2048B8DB71BE36905B213A1D8C1BEB76BD27A7CBE281C305F44769746F90307B01613080D50F96CB451D717EF5F372D488B6FDCB762927B910936F161764131C80F09316526CBE62EBB07DB7300D7A81890557000046FD7C098999994FB87691A59F437A7F6D3690075921E973805693AC1CCBC6637471B2C561437A8E30220BDA078435455FBC368DFAD026F85417A5DA96D8FB6272D06F785929B38529D5990DAE3C7596AA72B9381121C6C94A7A593A5AA62BE830BFC0BF5B34C57221AE288302559045F3686D8941576EB41F32516763A90553A5727697AAD39B46C5D84A2382980FE3AC0F904DD10C97078B197B0BC4CB8764F22943F584BFA9F3609D417D65B3C367DA544FAB84AD16025CBA7CE7794CB3ACA32F3042CBB4C25605998A74BC16F80B91C5635DABA3B8AA0D90B1B59CC042BEE19709A747666348577088DC4C5C3168CEFCC5C12C3B4A06C08CFE4CBE21359F03FB99E1C6CF8C84ABDADB1DA905C4EB605FB9C8CE7979458080AC594759CDD82A6E164A9EB781F4BB24147039CFC98889C077698B2471417504E99BE7F283B0929A35E14E3670291DD728599181A6911EA2912B48515F88689A73E9688957473B0CAEDE73937C7BC385D6B2FCF6B76017A8F23A2A7CB54E8A98004E0C97EBC826D1A1142D8162EBC9A311C325AAD94900D9B115276E91DCABA8D015D8A549F7F56A4B182CB3304FCFFB3232F64C2FCB839420663E9391828968D6FEA820C57B8816E1F5D3B414481523D24B81E1E2C429FFF40142C07F795BB51073526A3ACAC38565B3001A89053744886DEBA29F978A97E55A5E31EBD9243C452668809BE6A57BD4E87955928132F1C0AE88233769F141957F", + "c": "B098B60E7D24AFD22B6D949017D7EB64F5B22E09486CDABBF5C968A552E570814AA7EE78C4812AE1F9A62DFEE18AE28C460FAF64B34DF838C868D9F68605E6B174DB175DB8703BB461228725743526B4746CF3196BF15980B6D765D0C70E0435D06EB99DE367CCDBA94ED3062E793DA70678CF40581F1510A715971231429E4CBB97BB68442147ABCD0604D77D1B086F224039B81289C4BB649427BF1509A72FC94F5D239D45DEF93CB926E031049BCAC7E75EEC5689D731EA0A619BB91EDE099252EC631FECA51583C80EA01271310DEB2B075080D7E57141536CE566CC42BDA1EE5D57783C47460597D6919E6993FD57E0C35C612182C6EF8F6924273E1749C7BF6963F37C5A0CE92473A69487A5E40E29339920376F369BCDE9C3CD87A1FBC5E204CAF004372C5839BB725DFD16ED3311898CA15F05BFCD53429074679D0A40FFC162409B339ADF37877343F18C6658ACC96A451940FC09CB7441E0C8A6D309C2223D69095CD8409AF38557836AB5F1DED6B0CB8B3EC30E4C18C15FE1B764A7B932DC3831E91BB5DC62E50A880E1E1F6FA94EA688994E682E6EB28958367456BEFBF61D4CE5B84F64CE980AA2D6AEB4685188E1EA1844292912E5E00D89CA39B11C326BFB076688FB2F03E6BF6EBE8CDD381B5A3776771BA80D88C2625B357815925235B111AA823980512103ED6C861ACC918FC9EA208F08D0923E2CE6A168B13597D91C2F05A9FE7649BB37018922C700C90C5E467DC58E4E51EF87FBEEFBCC8D64E9C4DCA60C4F32B250FD19A0DC8D9159FC936082175C52E0A73953A0E9B8A1000C9F87F0A6E49D271F053D8549FD1A014BEBE89405A54A3F77DE7CB136BEA832E94E18B8BABE44F11CA6E798B1827AF292235A896D865CB3CECD98F8F6AED3952CB33C85F6D1156E1B16481DBB8D74158A1F84A403764BB120F4853D17167E176CFEF7787826DD9A1281E269A7418CB87D80485FDB0D1B73C0DBAC76F5E07FEED9511090B303B4785A72BF77A9445C512703E1942F2E72BDED8508DD4C1B5D4C21F76D0B535ED7915B8AB709521F85814F1AE3F0FF3F4357DCC94216", + "k": "759E8EB2831DCCEE0EADA89C237570E11A9419694AD1CF4474892DFC6877AB16", + "m": "D23A22F6DE6C0F3C28F5A7A8E54581BDB312A56BC90CF3B22A5BB39C9ABF420E", + "reason": "no modification" + }, + { + "tcId": 25, + "deferred": false, + "ek": "305988FF211E278150CE00B65C2669A14830AAA1A4EF2973101443E2A73A1BDC2CFD5AB88C54539573A7A5FA705C573693599C850370CA4A66E853CC283CCA0D2B52084C054C420ABC71ACC2C10D34C61C9CB0459331511107832B0A3BDEC7A0CD941D15A13F193162477211F29345414987ADD22C0FE95AA734745FB32F1114081957017B479108F626EF004D08AA327F0274B1DC2AC9963D8F557BBB58A9E16B7613DB8E379679006119B2DCC441DA80F9AA7F0BC2A8456CB78713A13985625AAA3AA9C6375BA06395F66EC3B63D4EAB2524322979A9B9E1178C4A966FB808C75416338237B3165AB20135ACB0437ABCD96251218F0C382731C45C9FA8141943743C1B1F5D77A064FC7968CA1F26B2B756F0B623323A01D8B0E8DCCB714441D7D5647F6C4338477926B248FAFC997B77C4A2BA625A3A5AAAC60C7A57682DE39D91D46778790CC5B45738D7866F7A909FEB27F70C9C4445A534C0AAF7A487CA8499BA372D3380A13C87978D82677A37C5C7A4490B716CCA2BC262C8853CB60CFA571D2DFAC83D428A010C760FC291E390102E3B6384C35067886940336AF5751E8BA399D11CC9788228E1E21A61F69E2AF7409CABB70DA8C775AA217EACABA3B2BFC7D608B374A47A2C96F56C57748B5137F8093121C0150C1A61803D5C6B42CA439E81A8C9926084F5B98931B7079DD44E2C9376DE77626EB543DF071C7A2C630A995502535FE8570EF7C987675C70DF8525D495C5F93B0B5EC7CF59154CE08A84ECCA36FADA9962160A1C2CCD3A728B148CCC9DE733719387D6C166BD9691E3EA6B22550A85A09989A49C90D68A51F195561A4F424CBE3152652272200FD642DE292A2061065EE1B962964BA33281B9B88222B122A3247AB9C247A9A6342F5082A685C8C355A1F96A0277BB8A97979937C17A47A2C36B3040C6B437BFC28B8DECB59DD9AF1B6818C146B74B0AAFFDCCB710E6BB3AD5A5F6AB7F8B2C2AD8980D6B569A5DD523E20379A6005695033260ECB823C7579E610F00A30EF745811DE05762A874A1986764A399B5CB1212403F6E7184028C5B2C47BCBA1A6537F180F096BAD9FA53AA495443314B91B46600EC339B950E9C4F1B1AD5E92385E3F7CA", + "dk": "CB402B0AB79835868924D80496343B0AC32FD1A13D7B39BF75893DE4529754B68219C58ACFDAA4CD964316AB05C170249A763416DA3DB9449BF32B0D41F7B53C406C62C24C33E2820A6C818B93992A1CAF55F155370BB18FA415DBC45977A335A0D03C0C9757FD26A4CC00980A2C35D699B96838525867A8A17719A109BA6FDAC6D187671F065BA38255D2824FDF5C66D0065858942982EB5C9839181170C633D76D123918D30A23A3A8884B7073C1E2C914FC0117F190C6C85DD327886A8CAAF01A6F9DD537E7797DE0D906DF15CB305765AE6BC724B7B911D293CF8AB7A9C9119D4B09A1794D388347A492CEB7C0664427320537B6CBA990F76581856A2AB6534AAC19B3015132EDB1023F68BD4A935C293168DFDB96C49A6C40B0C86592CFCFF74F59781C6264528A63653649A021568E71290EF4BB3FA445A925682CC04A161549696F3A984BE61B3CA46D3615983F50987E049A5DD1B0BC885F44F0AAE5E836E468789BEB6F7DB10F2AE07C479607AD156C96E49A790078D13C8205B366974AA32A696962434CB972BB78724123E33396463E83A30BD4265CAB598BCC61895D6BC4443C8D3B1B5D27B607599707E3C0454BC2A84BB53FDE1678FE905A0EC7A9458C2540E7741A10AA079802BAA2BBE90C03C3C80EA6178989CC6A3B9488551252B6828B9138B8C259A38DF9412ABCC01A4183BFD19545216E0FC1532119AF0019603F3C247D408ADBC9215E3614832BCEDA531F63A0729552B2EC99B120B8722275440B0C764E7A6BF0A10E73ABC0098761C45068E7E1549611822ED923131A91DA17B523309A1B59525CE427359B6BF54250B282C56985519C151FBD788F9D4737D8EC1968E79B0BB8CFC9E012C26AA66DA8284EAA3E9770B1D0D760A68254D8A111CD722362BA6E4969422B21BBC41838B3171046E87277CC400120C293417E411673373B98303BC533540192E256BAC46E57BB96F6D906FE291FBD843899A3212A894709349C3A22084A3CC4DE7B86CFF66B841583991747C36CAD49667AE4EC295D76765B401B78E59B68B0B0208A6D12FB3720BC9B77FCC3E56287305988FF211E278150CE00B65C2669A14830AAA1A4EF2973101443E2A73A1BDC2CFD5AB88C54539573A7A5FA705C573693599C850370CA4A66E853CC283CCA0D2B52084C054C420ABC71ACC2C10D34C61C9CB0459331511107832B0A3BDEC7A0CD941D15A13F193162477211F29345414987ADD22C0FE95AA734745FB32F1114081957017B479108F626EF004D08AA327F0274B1DC2AC9963D8F557BBB58A9E16B7613DB8E379679006119B2DCC441DA80F9AA7F0BC2A8456CB78713A13985625AAA3AA9C6375BA06395F66EC3B63D4EAB2524322979A9B9E1178C4A966FB808C75416338237B3165AB20135ACB0437ABCD96251218F0C382731C45C9FA8141943743C1B1F5D77A064FC7968CA1F26B2B756F0B623323A01D8B0E8DCCB714441D7D5647F6C4338477926B248FAFC997B77C4A2BA625A3A5AAAC60C7A57682DE39D91D46778790CC5B45738D7866F7A909FEB27F70C9C4445A534C0AAF7A487CA8499BA372D3380A13C87978D82677A37C5C7A4490B716CCA2BC262C8853CB60CFA571D2DFAC83D428A010C760FC291E390102E3B6384C35067886940336AF5751E8BA399D11CC9788228E1E21A61F69E2AF7409CABB70DA8C775AA217EACABA3B2BFC7D608B374A47A2C96F56C57748B5137F8093121C0150C1A61803D5C6B42CA439E81A8C9926084F5B98931B7079DD44E2C9376DE77626EB543DF071C7A2C630A995502535FE8570EF7C987675C70DF8525D495C5F93B0B5EC7CF59154CE08A84ECCA36FADA9962160A1C2CCD3A728B148CCC9DE733719387D6C166BD9691E3EA6B22550A85A09989A49C90D68A51F195561A4F424CBE3152652272200FD642DE292A2061065EE1B962964BA33281B9B88222B122A3247AB9C247A9A6342F5082A685C8C355A1F96A0277BB8A97979937C17A47A2C36B3040C6B437BFC28B8DECB59DD9AF1B6818C146B74B0AAFFDCCB710E6BB3AD5A5F6AB7F8B2C2AD8980D6B569A5DD523E20379A6005695033260ECB823C7579E610F00A30EF745811DE05762A874A1986764A399B5CB1212403F6E7184028C5B2C47BCBA1A6537F180F096BAD9FA53AA495443314B91B46600EC339B950E9C4F1B1AD5E92385E3F7CA320C1B0462C9C95B0367A4A13BEE7F2574BFBDF01921E7C2BA5AD3D6954E8334C39524D35D19623E3F4B21EA8BFFAFE599515D49A90278F7529215781B9A9F82", + "c": "BC00B2A45132B099533C3441157FE9E260F7B47CFA31730421FC913920B72A7AF375DAA469C22A17E8A4EBACB8ACB89D1DC841028190538BCACF028B7709D14E38DE97A99004F54B8D84A1372C250185895486C5426E6AD1D4C42F69D4902DF59A2ECEF40979E6C240EBA46FC0ED0788CD75B1B6BA6F382950BBA1C2A0F779B3100C0A26639A9733F3B912FB1CAD4DDD118D4AE13198204FAE7EE59277315662B9CBC9EFBC1D756127525B4996CFDCDF9B7DF7E9A2E71B9BA72650370DBF75A2F39D0004CA6F7FA59C8951FAA76091362C8938D5EC82E6EDAA06BFDA4852DB9F11EAB5C659D21777AD6365AFC524FD0090551535A6DD2EBB8E5F8A2D1C1DDA87655BC1038C6501610291382969EF3CA1730947DEBFCD5B95B68D63750E77A59CCBB328D57347824D6FF2F09B0152F0B404DD023A6F2DF7E61030BAEDC765500ED03A81237FEEBCC3022403D17EF9398296B0AF4747209E0CFE925DCD71B70DD71DFD96181CA30129EC97A21C0D18E3B6315CDA1E88DCBCDDD1912A4947E6E1BAE6250CBDD931CA1B7D146041E973AC0139FF6A23107D44E61293D1AC9E249B5F4E3CF69E55361440DDF9B2558EC793F8968CC09716CD9DEC2BAE26A0A5587BE97CEE4B9CBD3506794559C2D7D3550011CA37424CCBDA8BF479098A5E76031D729EDE3B67C6E5A0A2AF11627C1AAFD3C16F548C4841AD9307096AE806210CC0173429C9699F5D95162B9B56D7199D4809A294579905E2C5D3BE1F890F65727F92D97CEF4915724FE3CEBF00E3A01336FAC1C86ADF6A8ED654256DEAC45464E537EAB98A918C69CC6AD91A53E69158DBD71A18A83DA3EACD67A65F7DAB277E82B5F9535E61448A1AEE1F52FAD989E14332EFFE97D3309CC2BD58E45AFB5A7056C20AEAF1E4D5A0EF5B0C1507923CAF7937657109A83A437EF10CC035BDF983F88FA04EE6C338346FABEAD3413DF0071F960AEB121FECDE71BEF8800142CC159F9A6EB729205D3A980F11B5960699EB3A9394237B96E58F141058F8057A4D15895D4F77C49BBC021B452FFBACFF2C74279EA83D0C57EA4CE5D7952314206A3FABC3", + "k": "2239EC88DA575EBB9329448904221C63CDF517DBE3029713E3840CF4C54819E3", + "m": "C0A5ECA859643D0134F2231C8F3764044B7E6073C92C9CDF71BD64FBC59ADDB9", + "reason": "no modification" + } + ] + }, + { + "tgId": 2, + "testType": "AFT", + "parameterSet": "ML-KEM-768", + "function": "encapsulation", + "tests": [ + { + "tcId": 26, + "deferred": false, + "ek": "89D2CB65F94DCBFC890EFC7D0E5A7A38344D1641A3D0B024D50797A5F23C3A18B3101A1269069F43A842BACC098A8821271C673DB1BEB33034E4D7774D16635C7C2C3C2763453538BC1632E1851591A51642974E5928ABB8E55FE55612F9B141AFF015545394B2092E590970EC29A7B7E7AA1FB4493BF7CB731906C2A5CB49E6614859064E19B8FA26AF51C44B5E7535BFDAC072B646D3EA490D277F0D97CED47395FED91E8F2BCE0E3CA122C2025F74067AB928A822B35653A74F06757629AFB1A1CAF237100EA935E793C8F58A71B3D6AE2C8658B10150D4A38F572A0D49D28AE89451D338326FDB3B4350036C1081117740EDB86B12081C5C1223DBB5660D5B3CB3787D481849304C68BE875466F14EE5495C2BD795AE412D09002D65B8719B90CBA3603AC4958EA03CC138C86F7851593125334701B677F82F4952A4C93B5B4C134BB42A857FD15C650864A6AA94EB691C0B691BE4684C1F5B7490467FC01B1D1FDA4DDA35C4ECC231BC73A6FEF42C99D34EB82A4D014987B3E386910C62679A118F3C5BD9F467E4162042424357DB92EF484A4A1798C1257E870A30CB20AAA0335D83314FE0AA7E63A862648041A72A6321523220B1ACE9BB701B21AC1253CB812C15575A9085EABEADE73A4AE76E6A7B158A20586D78A5AC620A5C9ABCC9C043350A73656B0ABE822DA5E0BA76045FAD75401D7A3B703791B7E99261710F86B72421D240A347638377205A152C794130A4E047742B888303BDDC309116764DE7424CEBEA6DB65348AC537E01A9CC56EA667D5AA87AC9AAA4317D262C10143050B8D07A728CA633C13E468ABCEAD372C77B8ECF3B986B98C1E55860B2B4216766AD874C35ED7205068739230220B5A2317D102C598356F168ACBE80608DE4C9A710B8DD07078CD7C671058AF1B0B8304A314F7B29BE78A933C7B9294424954A1BF8BC745DE86198659E0E1225A910726074969C39A97C19240601A46E013DCDCB677A8CBD2C95A40629C256F24A328951DF57502AB30772CC7E5B850027C8551781CE4985BDACF6B865C104E8A4BC65C41694D456B7169E45AB3D7ACABEAFE23AD6A7B94D1979A2F4C1CAE7CD77D681D290B5D8E451BFDCCCF5310B9D12A88EC29B10255D5E17A192670AA9731C5CA67EC784C502781BE8527D6FC003C6701B3632284B40307A527C7620377FEB0B73F722C9E3CD4DEC64876B93AB5B7CFC4A657F852B659282864384F442B22E8A21109387B8B47585FC680D0BA45C7A8B1D7274BDA57845D100D0F42A3B74628773351FD7AC305B2497639BE90B3F4F71A6AA3561EECC6A691BB5CB3914D8634CA1E1AF543C049A8C6E868C51F0423BD2D5AE09B79E57C27F3FE3AE2B26A441BABFC6718CE8C05B4FE793B910B8FBCBBE7F1013242B40E0514D0BDC5C88BAC594C794CE5122FBF34896819147B928381587963B0B90034AA07A10BE176E01C80AD6A4B71B10AF4241400A2A4CBBC05961A15EC1474ED51A3CC6D35800679A462809CAA3AB4F7094CD6610B4A700CBA939E7EAC93E38C99755908727619ED76A34E53C4FA25BFC97008206697DD145E5B9188E5B014E941681E15FE3E132B8A3903474148BA28B987111C9BCB3989BBBC671C581B44A492845F288E62196E471FED3C39C1BBDDB0837D0D4706B0922C4", + "dk": "B09125AFB3CFB5295581373AB6885284D9706318280D223EDC987FD14410DBE82E6AC89ADFAB70E67CA4B1C641AD037FD8C47870F159EC79CDCD52605B9890499BB6DBD8347F342C61436B642C0DDF4617DB06198B8285DCE4C09D9775A2F41C8CD18AF8E75F57D4127DF94D901AC83BACBD584CC50C43750F49B357F59350875C9B475480A8AAA168592DDB158614A639813566D205368C6C39F0413CA3230DF60D44008282B682AC66B76C3C95F00B2A555035529C86EF3905B4A3968FEA7802B6C5EECB08E8F0C42D7AB7CD21A62FB136412A1840B52C99970CCF51892F73497C3775BE2189F7FC25E7C74D81FC217683292AA4866DDB04469855323A0810F0893DE5C7F94A9C0B5337DB83C44891B2E694695B76575032BF51761682958BD4F97BE9A355B4A85BB6858B7E5A5EF653AB781056AF9187D811C3A8936E5706503DB57062410BCC9421F1AB867A657856C411C4E025ECB3C387729AE8E112F330B988E22F47C35C280750D21B107687AF7B329EF3CB5289F06FB7D44548391E97BA6DD499B5907C54958413D92AA99D5646CF47A8F48CB70A07AD056B4EEFE6C8C46645F7028A32410558638C48E83AC1570160C3833BF64052F5B7DF4364D3E0B24E790AA7C98CEE0441E6731D9DE22D156C61E1C740397672EF54724F01B9D49923AA321F86B98823F21360138392B90C69434635275F9BFBB9B8A99E8E1B7F4EC25F75DBCE33C13F750170BD6722EFE496E7463E16AAA5867B869A96AD41B22BD2556C924596FD778D79A102F6E46D8EB18FEFAC8DB19993E5414AC816705286892492C8C9E852D6145DFF0C10E4A6703A459E7E732A6DFA2766A622B0622BFEDB8F41C125F61B2EC264853B9CCC165979F6A263BEB148905AAC7618A70E829E23F28696F92EF6FA07C102CDBDB1288BA5CFF3A81ABBA15974535FE3106A80068F14E98964572350A7112B1601C196710C096CCF164FBCE1AABAC9C5B9535070E61AB8068D611CA765FABB6412607DAB30C4FC6AD073731FDC4C48B88E267C47B439AD2560C30561815CEB1F52C896489944BBBAB52B1B1D1680A1057964DAFA600C93A39A447DDBB0ADF911AFE3E823D8ACC7CC04659F625F2C1837BB175282542CD22601F621581AB5A6C0384E087CCD32A5380B522FDD3A4202B5B41C85CAFF2903B2DC2645703D9BC711FBB404C0C0376187AC588AAF5718522D2273A9408DABCBC9701698D2DA172AA6267A4C9693A24011C2265A2B6DC8E96304A98DDC5319A3140C399A08412C20F48537870BB84C32A094457895511FF7EC421DE01A64B78534653F78327441B90CD115939DFAAFA95B40D0A63D62D12EB5C9096018CC83871E44E6CD0BE26D16B7B5A209B8E6471D2954ADF9FABD0153707C9CAA2BCC38DED841C791A0EB597EEEE2C518D926EDB28AB53CAA5B7746466931B0AC9150688BF37049C1F82BCF648332434CD0A92FD2C958353A26CB65CB499057109B2D688CC43C4B385DA7C50868AF1B8075E57088F5DB12DFA493EACB6DC4EC6E205BAA2A89858EC2823C00553714CDE47A96E36C7C198B3EC57CCF74D92CDDB86AA0A8B8B5CA9D52BB60ABA79F4F72B0125532CEB7A9077480D2BB60DF51A989D2CB65F94DCBFC890EFC7D0E5A7A38344D1641A3D0B024D50797A5F23C3A18B3101A1269069F43A842BACC098A8821271C673DB1BEB33034E4D7774D16635C7C2C3C2763453538BC1632E1851591A51642974E5928ABB8E55FE55612F9B141AFF015545394B2092E590970EC29A7B7E7AA1FB4493BF7CB731906C2A5CB49E6614859064E19B8FA26AF51C44B5E7535BFDAC072B646D3EA490D277F0D97CED47395FED91E8F2BCE0E3CA122C2025F74067AB928A822B35653A74F06757629AFB1A1CAF237100EA935E793C8F58A71B3D6AE2C8658B10150D4A38F572A0D49D28AE89451D338326FDB3B4350036C1081117740EDB86B12081C5C1223DBB5660D5B3CB3787D481849304C68BE875466F14EE5495C2BD795AE412D09002D65B8719B90CBA3603AC4958EA03CC138C86F7851593125334701B677F82F4952A4C93B5B4C134BB42A857FD15C650864A6AA94EB691C0B691BE4684C1F5B7490467FC01B1D1FDA4DDA35C4ECC231BC73A6FEF42C99D34EB82A4D014987B3E386910C62679A118F3C5BD9F467E4162042424357DB92EF484A4A1798C1257E870A30CB20AAA0335D83314FE0AA7E63A862648041A72A6321523220B1ACE9BB701B21AC1253CB812C15575A9085EABEADE73A4AE76E6A7B158A20586D78A5AC620A5C9ABCC9C043350A73656B0ABE822DA5E0BA76045FAD75401D7A3B703791B7E99261710F86B72421D240A347638377205A152C794130A4E047742B888303BDDC309116764DE7424CEBEA6DB65348AC537E01A9CC56EA667D5AA87AC9AAA4317D262C10143050B8D07A728CA633C13E468ABCEAD372C77B8ECF3B986B98C1E55860B2B4216766AD874C35ED7205068739230220B5A2317D102C598356F168ACBE80608DE4C9A710B8DD07078CD7C671058AF1B0B8304A314F7B29BE78A933C7B9294424954A1BF8BC745DE86198659E0E1225A910726074969C39A97C19240601A46E013DCDCB677A8CBD2C95A40629C256F24A328951DF57502AB30772CC7E5B850027C8551781CE4985BDACF6B865C104E8A4BC65C41694D456B7169E45AB3D7ACABEAFE23AD6A7B94D1979A2F4C1CAE7CD77D681D290B5D8E451BFDCCCF5310B9D12A88EC29B10255D5E17A192670AA9731C5CA67EC784C502781BE8527D6FC003C6701B3632284B40307A527C7620377FEB0B73F722C9E3CD4DEC64876B93AB5B7CFC4A657F852B659282864384F442B22E8A21109387B8B47585FC680D0BA45C7A8B1D7274BDA57845D100D0F42A3B74628773351FD7AC305B2497639BE90B3F4F71A6AA3561EECC6A691BB5CB3914D8634CA1E1AF543C049A8C6E868C51F0423BD2D5AE09B79E57C27F3FE3AE2B26A441BABFC6718CE8C05B4FE793B910B8FBCBBE7F1013242B40E0514D0BDC5C88BAC594C794CE5122FBF34896819147B928381587963B0B90034AA07A10BE176E01C80AD6A4B71B10AF4241400A2A4CBBC05961A15EC1474ED51A3CC6D35800679A462809CAA3AB4F7094CD6610B4A700CBA939E7EAC93E38C99755908727619ED76A34E53C4FA25BFC97008206697DD145E5B9188E5B014E941681E15FE3E132B8A3903474148BA28B987111C9BCB3989BBBC671C581B44A492845F288E62196E471FED3C39C1BBDDB0837D0D4706B0922C472E31DF613DA9A1DD33B5D2D8939684B89F7649E1C59B959FFBE972786C477F66177DBF3B059173FD06AFCD90E80E862174FC57F97607BBFF5B73D6360FB5C37", + "c": "56B42D593AAB8E8773BD92D76EABDDF3B1546F8326F57A7B773764B6C0DD30470F68DFF82E0DCA92509274ECFE83A954735FDE6E14676DAAA3680C30D524F4EFA79ED6A1F9ED7E1C00560E8683538C3105AB931BE0D2B249B38CB9B13AF5CEAF7887A59DBA16688A7F28DE0B14D19F391EB41832A56479416CCF94E997390ED7878EEAFF49328A70E0AB5FCE6C63C09B35F4E45994DE615B88BB722F70E87D2BBD72AE71E1EE9008E459D8E743039A8DDEB874FCE5301A2F8C0EE8C2FEE7A4EE68B5ED6A6D9AB74F98BB3BA0FE89E82BD5A525C5E8790F818CCC605877D46C8BDB5C337B025BB840FF471896E43BFA99D73DBE31805C27A43E57F0618B3AE522A4644E0D4E4C1C548489431BE558F3BFC50E16617E110DD7AF9A6FD83E3FBB68C304D15F6CB700D61D7AA915A6751EA3BA80223E654132A20999A43BF408592730B9A9499636C09FA729F9CB1F9D3442F47357A2B9CF15D3103B9BF396C23088F118EDE346B5C03891CFA5D517CEF8471322E7E31087C4B036ABAD784BFF72A9B11FA198FACBCB91F067FEAF76FCFE5327C1070B3DA6988400756760D2D1F060298F1683D51E3616E98C51C9C03AA42F2E633651A47AD3CC2AB4A852AE0C4B04B4E1C3DD944445A2B12B4F42A6435105C04122FC3587AFE409A00B308D63C5DD8163654504EEDBB7B5329577C35FBEB3F463872CAC28142B3C12A740EC6EA7CE9AD78C6FC8FE1B4DF5FC55C1667F31F2312DA07799DC870A478608549FEDAFE021F1CF2984180364E90AD98D845652AA3CDD7A8EB09F5E51423FAB42A7B7BB4D514864BE8D71297E9C3B17A993F0AE62E8EF52637BD1B885BD9B6AB727854D703D8DC478F96CB81FCE4C60383AC01FCF0F971D4C8F352B7A82E218652F2C106CA92AE686BACFCEF5D327347A97A9B375D67341552BC2C538778E0F9801823CCDFCD1EAADED55B18C9757E3F212B2889D3857DB51F981D16185FD0F900853A75005E3020A8B95B7D8F2F2631C70D78A957C7A62E1B3719070ACD1FD480C25B83847DA027B6EBBC2EEC2DF22C87F9B46D5D7BAF156B53CEE929572B92C4784C4E829F3446A1FFE47F99DECD0436029DDEBD3ED8E87E5E73D123DBE8A4DDACF2ABDE87F33AE2B621C0EC5D5CAD1259DEEC2AEFF6088F04F27A20338B5762543E5100899A4CBFB7B3CA456B3A19B83A4C432230C23E1C7F107C4CB112152F1C0F30DA0BB33F4F11F47EEA43872BAFA84AE22256D708E0604DADE4B2A4DDE8CCCF11930E13553934AE3ECE52F3D7CCC00287377879FE6B8ECE7EF79423507C9DA339559C20DE1C51955999BAE47401DC3CDFAA1B256D09C7DB9FC8698BFCEFA7302D56FBCDE1FBAAA1C653454E6FD3D84E4F79A931C681CBB6CB462B10DAE112BDFB7F65C7FDF6E5FC594EC3A474A94BD97E6EC81F71C230BF70CA0F13CE3DFFBD9FF9804EFD8F37A4D3629B43A8F55544EBC5AC0ABD9A33D79699068346A0F1A3A96E115A5D80BE165B562D082984D5AACC3A2301981A6418F8BA7D7B0D7CA5875C6", + "k": "2696D28E9C61C2A01CE9B1608DCB9D292785A0CD58EFB7FE13B1DE95F0DB55B3", + "m": "2CE74AD291133518FE60C7DF5D251B9D82ADD48462FF505C6E547E949E6B6BF7", + "reason": "no modification" + }, + { + "tcId": 27, + "deferred": false, + "ek": "F5841D6AEA683FDBA16308BDAB828DDDD7735B8B7A0DAC6A57EB5134B91D8D6CBD989580411144E1FB5A6A559A7056376210A8284742D22A5881C5214C90023FC910D5D02A869087557900273BB875420B5717CD0B23064AA820CDF372F3E4778D70AEB5D02B6182C4D37110D782B6E80303332697B4C610A384A0C632C0D9484A1D3B5EA921525BEC5755C839DF942F24A027DB50B2D760066D10A117BC9A1B65C448CB9ACF3B4F644316E8941C449803F6851A74D832A739B2C0EA9258C7258E98BD3E833D879A6845EC4ECC44B6FA699388135F5E4830F2625E9FA5CC982C578B2593D350B06288A854D3349C24586D3AA2E68726A873B1E5AAA3B22671D8C69AEB180718CB456B942E4B6678E620A00BCA310C722DDD499EAD9C6B66666A3DE39A45D7AF0BBB7AB6A0BEAF8BBCBBA17B1D097ABB09A70E410352D2084423AC53ECBB4C196021F01E662A60C68B3BF48A5F0864A25577912F52620CE6347BD27FF68A17D4B92CD7D01B89E3487A5BC2859781F3EBB8B5B4C2D682636C486A000A576A4B63AFFC05082B5ABE3CC0B37B1E586C2107D97157E325A067BB86453414A15594A510DCFB2FE1A0074483120FB83440DB1B8C3B41E36364F92056083CB9CF91B39F28CF00F6AD098AA10FDB4B4D9B64ED1338E0D5B7A5169C3D8C0184B19966E54272F765C0337BBD307F8C97369A7A87DA44A5BF468DB8A9AA5EA598F885AB50174B0F9025A4EB53D2323D202A05265331FD836DF8E02B4595458551ABED8A3875B83BF976942372CB37296C813ACD2C27B41A5514B66AB25759009DB38A9D0473D5B7A9A7D6795F1188A079B1792A01141347AF2194CA681055D36E954C02D6935BBA7C2EF7F4B5E47C8B0A0069F29575E863967CE4C53105230472172FB79E69089D5A7BCAA95784BFA279EFE67DA145308BAAA1A5A303757946C2866B4841660A99C1968B8F7DE799ABD71806EB9F091397C1CC4171152A6AFC36BD733FC6C53545361AB6258CB45C9F1331BAEA85BE4558935984C081F73E4B377E0251CA7C396BBBB81D271BB9F0589E1BE3218B0B5840372253AA80A5DB79E11199C0832B2433880B68BD84FC02AA3CBBEC205EBBC7B050967B4DFB11E2FA63BCF6B7656A8028AB607CB084C21747ED573A055166F82215D7201D5D439A19F584F470B4272962C137B38545309547CEC25B09C96459AB7B4DA69C8D7B9277BBC4B5568813DA904141A011D9B45AC1F181273149F3C46F45CA9735221B97CB528E8AB59C5711A57C603F7A91803254E8CC4A37D84D1F6535E5A791A50145E1E073430810B3AB79DF4053538C7DB4826A1B428A84553BB881A23507385271B32F854706BB2D3E884E7B391985B39B7BA373071455187B3DD7DA75F6988BBD6BC39EF2808C245AEC9C024CA16546A16F63831A7B6797951A40894A5E38422F30B87E70355CCBE960B216592D0073F1240C21BB109AE76C9DE5B7835BC08AC6601C314A82232FA6F6896BD7834F0254BF112602022844F0CBA9FC3D2E3A58EDD56DDC498ADC9A03FCB43CA138640F85397FD5731F537D6BDC3AC76563D6516F1CF24F84B7C957635DEFBBB70071621C8B2585380A63660EF2CB6CA5910BAD42A1B621CAB8C26780D4251DFD1C6370EF12193C3CEF0223187A4557BC08F4ADD382", + "dk": "62DC65F32C94A1365605B30807CA5A34996AC9311532B3A23906683B44A9D9B6136BD9AA72F369E77C701E72086E5137EC7350DF480B6437B31B2863DAEBBFC08B9C27D00CE7F6349A971ED1E505039B73EDA8C7614334216A5F2719587DA3CE79B92D14581BF58590BBB3C01108C21F9B6933E4128B28A7834B2DA4922431F921ABD52EBB5295AC4957EFD662ADF97265E912A3D115F6695536AA2D6AD15E74D58C29FC0ACB536C2B43157FF21C57AC1B600979FFB223DDB70E76EB8D56502921654BBCE29B30E5C7E359B86E25A5EB018B0428BA5D53B23F6BA37E3265854C1A58DA09B9FC3DE4B98906E3A8E9C575DC82AD2389CF2E9C32D3BB8337A8221C59077722C7D39C9F536B3CB523C8756250176155907B20F5BB2C7F3A9B85E5A527FB0FCBC01D7EA971162789BDBC840ED68D24AB7F626B0E401BCA03A225F5E4AD2C17B8C87893683B7D1CA83B1AE0B3D0CBC34FE793A07469049C60E9169A47701828B395ACB3BE3364CC5C2A5892713137B04AD0720FF7307D917C61A269CD5B583F4CB65BA2FB562AFC535117264CD46AB03637D832A37585640379A2C3C80D4CD621D4638D3F6972B1EBBEF61A3CE5461B6F1A253AC2C150255B188656CCF492BDD41A921BA7CEF679C8D33265FC0A8AEB6988E2B813561EE6C4A9A8297E935008173C58112756E5288A4ADB6FD192A478546A41D88041038289A4708704BEDA425988D493DF57044E6304E89896CE25C4978A6278AC70EECC27EFC271F1E4A9C0F5AF17E1441357B8EDC88799421FA56A8731063776322837E01FED1AA6B2E4C86A5C55FC5B735E315C22284B37C238FAE93916188247815554DA511AFB634C75A1B8E783F5530BD38A57B4F77E48C812DE683507F5A24CA867AA3A96440678F21404D9D6B182259190C87ED86C6F632C90D03070F7761ED85C7AC22261C6566C76B66C2E800DC427C07633C90A61077B078E2DB251527835239957DFC2055F176FF758506983135D437650E71D77957A8A48B56CE59C566395078C2E7008A4D7604BAAB7AB78C461B7718D6BB27C55206630C331823619A08773DC562392F817D73B350421929D83BC49C6C8DD5C38F6D46F08755C316093F5C5454280A3DBDA4E5B508E40E0ADCC80AD27112E2D2C9DA3392A034B6277F8157FA1BC0ACA1C1F857CC4D6A6EB880C667164F6AB886B5A1D84C6321D735A5A1047AD985FA0DC317B22BB54E0C04FD3C27FA976F2EC633DC1B14A502E5A02275AE67E6B68583B8C7FF97827059BAE1CC3765A5C7202227AB640C1BB68924B928B489A3F6BAB68E2F0C9D338589443C3909353FB98487BFA6A91B71A62A9CDD39AC6065668680388E1A33467A3C32EC61A1D605E6AC92751D05BDE0930867A96E2713D933582D1BA4A85434590324B33A522A5B2BE13F667A96914D2F6289CE735BD3CAD15F6ADDB4B4BC7AC47C88A2C52FAA7CF434E7B8995A4F54A7043273E357FD6B37F3EC924457913C351BADB0B415CE60754BA7621A8C85FD0C678E1C9BF4C3283749A33784098B9065B4724A6A4A5A155751E0845F908B67C673C0B6C278C35CFC86A450A8526608683DFE69D59E1C905D4A3EF95B9E134AF8E6A54FDCBAF3E028EF5841D6AEA683FDBA16308BDAB828DDDD7735B8B7A0DAC6A57EB5134B91D8D6CBD989580411144E1FB5A6A559A7056376210A8284742D22A5881C5214C90023FC910D5D02A869087557900273BB875420B5717CD0B23064AA820CDF372F3E4778D70AEB5D02B6182C4D37110D782B6E80303332697B4C610A384A0C632C0D9484A1D3B5EA921525BEC5755C839DF942F24A027DB50B2D760066D10A117BC9A1B65C448CB9ACF3B4F644316E8941C449803F6851A74D832A739B2C0EA9258C7258E98BD3E833D879A6845EC4ECC44B6FA699388135F5E4830F2625E9FA5CC982C578B2593D350B06288A854D3349C24586D3AA2E68726A873B1E5AAA3B22671D8C69AEB180718CB456B942E4B6678E620A00BCA310C722DDD499EAD9C6B66666A3DE39A45D7AF0BBB7AB6A0BEAF8BBCBBA17B1D097ABB09A70E410352D2084423AC53ECBB4C196021F01E662A60C68B3BF48A5F0864A25577912F52620CE6347BD27FF68A17D4B92CD7D01B89E3487A5BC2859781F3EBB8B5B4C2D682636C486A000A576A4B63AFFC05082B5ABE3CC0B37B1E586C2107D97157E325A067BB86453414A15594A510DCFB2FE1A0074483120FB83440DB1B8C3B41E36364F92056083CB9CF91B39F28CF00F6AD098AA10FDB4B4D9B64ED1338E0D5B7A5169C3D8C0184B19966E54272F765C0337BBD307F8C97369A7A87DA44A5BF468DB8A9AA5EA598F885AB50174B0F9025A4EB53D2323D202A05265331FD836DF8E02B4595458551ABED8A3875B83BF976942372CB37296C813ACD2C27B41A5514B66AB25759009DB38A9D0473D5B7A9A7D6795F1188A079B1792A01141347AF2194CA681055D36E954C02D6935BBA7C2EF7F4B5E47C8B0A0069F29575E863967CE4C53105230472172FB79E69089D5A7BCAA95784BFA279EFE67DA145308BAAA1A5A303757946C2866B4841660A99C1968B8F7DE799ABD71806EB9F091397C1CC4171152A6AFC36BD733FC6C53545361AB6258CB45C9F1331BAEA85BE4558935984C081F73E4B377E0251CA7C396BBBB81D271BB9F0589E1BE3218B0B5840372253AA80A5DB79E11199C0832B2433880B68BD84FC02AA3CBBEC205EBBC7B050967B4DFB11E2FA63BCF6B7656A8028AB607CB084C21747ED573A055166F82215D7201D5D439A19F584F470B4272962C137B38545309547CEC25B09C96459AB7B4DA69C8D7B9277BBC4B5568813DA904141A011D9B45AC1F181273149F3C46F45CA9735221B97CB528E8AB59C5711A57C603F7A91803254E8CC4A37D84D1F6535E5A791A50145E1E073430810B3AB79DF4053538C7DB4826A1B428A84553BB881A23507385271B32F854706BB2D3E884E7B391985B39B7BA373071455187B3DD7DA75F6988BBD6BC39EF2808C245AEC9C024CA16546A16F63831A7B6797951A40894A5E38422F30B87E70355CCBE960B216592D0073F1240C21BB109AE76C9DE5B7835BC08AC6601C314A82232FA6F6896BD7834F0254BF112602022844F0CBA9FC3D2E3A58EDD56DDC498ADC9A03FCB43CA138640F85397FD5731F537D6BDC3AC76563D6516F1CF24F84B7C957635DEFBBB70071621C8B2585380A63660EF2CB6CA5910BAD42A1B621CAB8C26780D4251DFD1C6370EF12193C3CEF0223187A4557BC08F4ADD38239082384D084D2B67B5956A1463685AAA7BDE716AC1791935C47504893E18F24866531E34AD01E68FD6CE8DEE12B40398FFC74FDC4A8DA6785A966640FCC4F85", + "c": "BE483938DAC565B129658D168D494E522B52D031DE7FCC2FC6D52BDCE3F649AB140ECE5B25486B5F85D43ED6D85F6BBDC4141DCFA6C03F680C7B6D51484B461F700E207E2E281070DD48AED510A64E6849C462705AE29C566E6F2461F90387DAA3108FE9372A2B8D11CC2CD6CA20D9D1CEBC31C12B3DAF01F9CB67A4DB488DAF1760A48A29BB4E25A26752FF161B94DFC82A9773A8E5B9F761DA751FBBA982FEAB1A7FA3460CF669D5B8B3BEF8EDA6310009EE7130478222FBCC59CCCC248FBA6384DB7BF5D3B553C8ED134135F09DECA3877C9C4B22A478F892317841DE917E642B966906886358B09E8761E98EED4EC8309C578502C070E7C4E43CF2FFDDF1E4CED37762FC8D5D5C65348FDF01A0CC85314C022040982B94F4CC7FB565EB00C218CC61740062F896E992038F58D02B170DC903BB665B2A6CD724E201C17E646816E2AD528BAA20C43BC8ECC090F644256AA22FA3365820FE7C8AA5D168D67A21785D4BB2BEEE4FD3943FE351A0E94AACF9A5B4859EA97F3A5AECD213169356876B756137697F4C40A567CD960AA0436E61986407B2B88839FA226966271004C1445E057F932BBDE1274757A55F2AC8846FF770B1565C746814276487A9D3E454F5FAB0D77C82723A114BDE9882911A02192DA811D9B3DD2B2C7255C15E3346D6ED745C28A1F3C7BF4CE2DF9213E6FAB9CE90D7941C86E5EBA1CD90C9D12B94274D2D2C3AF727690A425BA8DF2527B26071D5A4C969EA61B646773810513A1AEF7F7E6AD5C5922569611CE5E94B674069C7914EB0CCB3DD03842A9C32302EFD8CAF9A1E4094339D7E857C994FB30C01D7F116EF66D8A502267848E38B080F0E5206DA26549FC7EC8F3D713F1241A09941CD7EA71DD86044F909A0D8C67361996D12E2D42C16E08CA7F789DF296C00393BFC83E47AA8130454F78DE07149D4FBCB304810BEDF462542B4B24A1A1D0A9F2B5B8706431287BA88B026E329E8865AB4F0AAD74D849F34945EDF6B3719E8103B110404A8FBC300592807851C442B506295B2FC76A600A0F9C3B3D796CDCD3C27B10FEB1BBBB462BBCE0BDD33292CD873D2396B0924BDDF8DA7408C4E680956DAD992E45925E9721985D4547BBE2684F4D4FD220FA87773447BF7A620F979FD529D86D2753F0E77C498E02B1EB55812D9E19EE6C99A61543EEF1C124716448FDDB46EB2D460179148DA2F01AA91C9B9B04A350A63D98B8CEB6005A39734C8F3CF9094D650812E1707CAAA98EC35D4ACFE425C48E4D8A1BF190DA3438684A27564255C8E5D1A97033F87077429711128BDF396DEB75E304376FAB9CC33EBA906D3804819534817EA309E3C260F9697F55BF4AA5C08A8A59EAB27BFCA0C2301434D7B490312CFB5095BF9948E3554E5409AA74EA7BFEFB9BC7CA61FAC565F2F7384F5832C2C29FC9F5D1EBAB56612C6696DC93FF21DB4DCD87F09705EE062DB948F68C6D5F7D1886059C87604089ADADA5DB49EA2BF3C3813A71018F1F559B2D72E35A013E3D9CBFDA480B43E616B9C7A", + "k": "44263624052C18E3AA23310697414499F1C0EAE45A1060D84EEB65FCDBCB5733", + "m": "76D04F481E68B2F901ECAB58B6369A2CC31A9DCCED82A1BBD426BE0AEE266AEE", + "reason": "no modification" + }, + { + "tcId": 28, + "deferred": false, + "ek": "92D1A81751C40C606885C737EFD2B599413311EAAC707939B37500699131A44535F21C5AE596741F7668525108B4B7AFBA814FAC8AB0063B6A9060CED936CC6DA2CE4131695A89C35F2BA2F39A27D3925775FA9F43486E4C95C165A666FC3305AF30B419611D291775E0F08F34A65EFA146E46D207533B908F744BD246A94A4A35137731D02AC43E779E262A66F668784B30B231D83E4369400248AF3EE28432821F07B5020725C8D769B305B3AFA685A42E28C4F0E35BF407549361A67D7B6699CA0F293CCB776019585759502792F8D76A3698872F817A0C621084E53695701795ABBE16C466017BCC02B518EA387103C59D17127B844350AE428929810559A08BC91C2A29DAC3D6C14DA0979DCB4210142C6CD5B7CF18CB77E2E13029C3C23D2089C295411560024AC2AF25B94FBC14796652CFD8A524B6ACB8D9A262B7C26A279BBA7D4995A92A5500E081864200BFB51D46686AE14130E3C5A728FBB76944BA658718FC041DFD3A2480B9B6658A9D595BC4CBDC105BE019E128909978240EA29DA7C66664E17183E0B44969B284DB06D4311751DA4ECC6CC75C06395D5B9537078D24E2091AA45A92D18378415F1183C6B4E7546A1A1792CC07384106A5D5C8B1A369D3D6A8C83B927B72C1FDC7CE27449A5228C85BB6B0CFA85954C0CE5A5BB947F68C8107C1FF3B7D3D4900FEE59206B4CCAC5A1B4E65465609692F76227EEC0721A59B92262DB0F735E391343DC5836BBA779D6A558F8BC0001388E8363E3CB63CE49C4C7669C82B2B650B4611D094707571065B943F2108BCA33747367AB953D9423AFC5609591BF49B8A99650E4D8010617CC58645080DC0A141C34DE1D69E5932032E7B1BAB0CB2A8BAC3506B7D5E713DA79CA4E177A6CB27A545C9A80B3A489941A47AF84F59F292E314302ACB8EF0006F50A539E319951F6CCEE9F478773A8B0AE73C14B729EF4C0B89A99B87F4C9B8BAC735D31BB833342BD501EF458F955496138A6D07D1777A9489A24C74A5799A70C942FC839D20A8C228F7453BC29C02BBA3B0827801143F67691EC3481F9609BF79D9A8B7A1A7A610B05856B5FC8C3521968ED9695A00D71FE8C390C60A59D6734C608B7AC0B4643F7BA1DFD05B5BD853C9432269A9555E3912E9B263C7B939384A1794A50F8688296869AADB4B853091A291E42F485A6F93547E03BC1B57A603C81B7897198DC59252F9805A6266435EB2A26B6300D22667A878C3401800E6612C026C4F0FF99C889531D637036126227B674B95A38A2A93497FF83C8D3143A5398BE9C59909800B02C677B27A42621C190D865AFAC05513F72758B494585435F2357B97342D951A2AB23A1CF8A229BE909487BB2B8F521B09E0C4849632BFCC821CE30025B837A455B2D7D58EE4B0AAE1A25F8A5693F62B1AB77C229890899264BF63189ABBCC80AD1B8ADFDB21B0C2481342A137FCAE8A64B1E21C805B187AB7C1B637D57FCD8811E49C1D2A065848A769B7F02D99E40F4BE3783DE3AE4FE97E23CA716AFC0814C935293641D7C40EA1088EE89C2A43505237A593565A05065081F6181F35C55338C427CA628727DAAF8F5B5322E34488904949E45C61BB915525676ED2659EFC97C6A53376478B629FB32D49047412A49E98F186564A36EEF1CA4920C912B1211B", + "dk": "96B453C51B12941167F1E155BF08755F122716B9C82F92B94DA348B5BA4D8FD517A1756B82522444DB1F28172BB0C37658351DC545053D7995D6591897B39B3A7478FFCAA784D4210B0B291D81AD3921BF093B4329C505C63C1ED5B481F30CA2CB3A9951F00F5091BFBC21319132A0C4B46980248014967E687102D689B0CC04813503988F2C1FDC6CB62AD7616C1A85A12134A6F57F00052AABCBC990CCA1FFB91D14344E4A193F9F6346E8455221830D14B9216AD54E82432402CB51AC44A988A6A2D6035BDAA69FD46206C83B8FF43C33EBCCC47B22B3E57151E09C803869709A5A9597E1830B0C050F87580C23A64BE7C82506CFD238A36F34CF613CBA3AAC9358B84043D9A1938CA244454D7F6753E7A2012D5497F437662B57791189C7878B04617A719B659416BB22ABA04E01159CC7745802DB76F7334CE0715956065F01F8BB2CCA7F9787271CD75E4A918B0462B715ECCBEAC34ACE288A0A23C98924289DF32F13B04831798D9DFA64B229CFEB380F4F70A598A93A8C3A68AA7469C2027101B30A26298099A8CD456826EB5B21826A0C56F4C619938E5150523BA79595BA73B8460A681391B052CA2060AD68344A8A2CCD2F64A211C3A3802336FC583B7C21C53311CB89793D7DB5C68EA15FE49158F5E73E065574EB537D382C7D82B14231732CC1633686E53C723A1F43874AC6B543C4D99335B327DDA3BFC49119B00B3576321513D156E415A2D85689641A7A782800DC234BC8D589F5A384ADCA2A91053E41E18F2AB97F89E98B0C7984C0497EED8B2FD9D828C4BC7676C54C009D994E1786A4B177B7557508947BC8C706FCE8271D4A9630F3BA9D993ED9E82C5CE4A4F2BA83225C08E37A43116708A7B27C1B3620A539334F846FEF6084F8193071BA34CC9B919A0311FD7526C647A38674C81871B4F6D49DCBF83D46C545E5C543D26472EE9BBD04628B0E5434A2B342FF3A950DFCBD9EF078EE8BABBA09BC420967EA06832E78C2946746224B1FB539BF1E44CD67A9BD42F9C319EC7244EA5088949925778304E1BE08A2A9048B37B225325B22A3FCF2BAFF45C55110175E930BB7F6603F95577325B809179A09662E948453DF33313620BF195155C2D36E2B7B4BB4E6AE680B5C9A050A341B25D8BBA007B98C4AB554169952ACEC26864B9CD62B20A43BA2221903516BA174D25143D872B6D5C1C3961950D08EE1350E5700A111289987619E8FD5A18067A94D0B16D27318E4623BC80312F5017FFD241EA1A58E8F4A19EC0B4B7CE44E832A80D1C8C39FE7A535838179789115E83873CAB5BAA2BFEDA8CB07414C3BB0BC44C09D5765911F3233A7C32216914C520A5BBD63944C0153A8054B2E825A83ABBD3C564E7FAB19D081AB59AB138D1B250455B5FDDC16A8D080339182C1540BDC615D0B1C9EC1DC01455B4E59E5917D26BC0EC746A7D300D836B74D0BA16099BF4D87A9C6526BB8A5A9115C59B5F538CC0A17B3965513D92335487A4263C17AD4BA9C6144A0A4AA4DB83EFFEA9970B96C01260E91CAC3D652C88375C50CD0516929B364AB3BBEB15D68FA83C4F72449C47112557741058FDDD3CBD6898241E27FCB16090280002AD686F43A91F9186DC6898292D1A81751C40C606885C737EFD2B599413311EAAC707939B37500699131A44535F21C5AE596741F7668525108B4B7AFBA814FAC8AB0063B6A9060CED936CC6DA2CE4131695A89C35F2BA2F39A27D3925775FA9F43486E4C95C165A666FC3305AF30B419611D291775E0F08F34A65EFA146E46D207533B908F744BD246A94A4A35137731D02AC43E779E262A66F668784B30B231D83E4369400248AF3EE28432821F07B5020725C8D769B305B3AFA685A42E28C4F0E35BF407549361A67D7B6699CA0F293CCB776019585759502792F8D76A3698872F817A0C621084E53695701795ABBE16C466017BCC02B518EA387103C59D17127B844350AE428929810559A08BC91C2A29DAC3D6C14DA0979DCB4210142C6CD5B7CF18CB77E2E13029C3C23D2089C295411560024AC2AF25B94FBC14796652CFD8A524B6ACB8D9A262B7C26A279BBA7D4995A92A5500E081864200BFB51D46686AE14130E3C5A728FBB76944BA658718FC041DFD3A2480B9B6658A9D595BC4CBDC105BE019E128909978240EA29DA7C66664E17183E0B44969B284DB06D4311751DA4ECC6CC75C06395D5B9537078D24E2091AA45A92D18378415F1183C6B4E7546A1A1792CC07384106A5D5C8B1A369D3D6A8C83B927B72C1FDC7CE27449A5228C85BB6B0CFA85954C0CE5A5BB947F68C8107C1FF3B7D3D4900FEE59206B4CCAC5A1B4E65465609692F76227EEC0721A59B92262DB0F735E391343DC5836BBA779D6A558F8BC0001388E8363E3CB63CE49C4C7669C82B2B650B4611D094707571065B943F2108BCA33747367AB953D9423AFC5609591BF49B8A99650E4D8010617CC58645080DC0A141C34DE1D69E5932032E7B1BAB0CB2A8BAC3506B7D5E713DA79CA4E177A6CB27A545C9A80B3A489941A47AF84F59F292E314302ACB8EF0006F50A539E319951F6CCEE9F478773A8B0AE73C14B729EF4C0B89A99B87F4C9B8BAC735D31BB833342BD501EF458F955496138A6D07D1777A9489A24C74A5799A70C942FC839D20A8C228F7453BC29C02BBA3B0827801143F67691EC3481F9609BF79D9A8B7A1A7A610B05856B5FC8C3521968ED9695A00D71FE8C390C60A59D6734C608B7AC0B4643F7BA1DFD05B5BD853C9432269A9555E3912E9B263C7B939384A1794A50F8688296869AADB4B853091A291E42F485A6F93547E03BC1B57A603C81B7897198DC59252F9805A6266435EB2A26B6300D22667A878C3401800E6612C026C4F0FF99C889531D637036126227B674B95A38A2A93497FF83C8D3143A5398BE9C59909800B02C677B27A42621C190D865AFAC05513F72758B494585435F2357B97342D951A2AB23A1CF8A229BE909487BB2B8F521B09E0C4849632BFCC821CE30025B837A455B2D7D58EE4B0AAE1A25F8A5693F62B1AB77C229890899264BF63189ABBCC80AD1B8ADFDB21B0C2481342A137FCAE8A64B1E21C805B187AB7C1B637D57FCD8811E49C1D2A065848A769B7F02D99E40F4BE3783DE3AE4FE97E23CA716AFC0814C935293641D7C40EA1088EE89C2A43505237A593565A05065081F6181F35C55338C427CA628727DAAF8F5B5322E34488904949E45C61BB915525676ED2659EFC97C6A53376478B629FB32D49047412A49E98F186564A36EEF1CA4920C912B1211B1EAAA1990D4FB6A021D7CF8F417D45FE1F49BA84E111A448E8B7DEBBEF902A966BD5EEEA2E6D38487D083F30093ECF02E7EDC4FD4585C73EF6E71FAD24E15E2F", + "c": "2E7CDA2E97146A7BB3C33C5EF76D1A4F4D93A59F1B8441BF6A32D88EBA5609490CB3283DE2C43E4D1DFF2DB55E4DB9B4C3A377B3E9B33FF1CD3D6A2047C7FE0B6D8155DBD4C0296E8CE60C74DCC82080E31AF13169D638EE6396439F49AE426BBE5AC6BEF9B2BFF423AA24BD2C168E0F4F2078419A5865F1808B866FBD19CC221791952D9C2101C3EC3A6F597F97C2268F8F6FF273E4B443B8E95D93B6AEED85F71509ACA3F366938E6BFECC3B0A35F859D3EB486BF321A1F3A7350B39F7A89773DA2C5B235132C9580380DDCDA3A910E89734F03F871FE504BEA38918299DFE7C9F60A6E4CB607768F0A3338910D45612B31BFB6A0424489E0A4E514D2F41C3B4A0001E794A5275F8D047C892870E647BBED53BEE167BE27EC2A43D2D7DC10982F96E3B586119D27EEA5909A18800B79644FC9D15CD7D2200229C1380FE2E939DF89FEACF4834DFD1D3C8ADDB8F365BB94359C4698AF15AAFD4F3289233701C217CB4FF979EE781C8420ED9EEFF53D58F046B774B821EA3021F7DFE33A79F882C955C86FED0702AEABDCC6D32186B7D40DD325B9FB7BFDFB1D34C63B19433F0D80739765EB9D8BD210669675DB3F4349BBF23B49B7A967CA2304ED8F143D27981C26FECCB1658B5BE11DD858BEFC3DEDE25DBA9FD22341E63A5884C41A0ECB68C543E0B021135BE381D42DDB9F67CE1473D8840E00138B39998018E0E869FB0F94823A5191B928C7D13F157318901EA8F8E5A5A0DF0ED71FD2CBC6489A46E5171FD14A09F73420C77947941DCCB4F122866E93D94A9DB0030A20663705B11C93E89396F1B7E7728B6B450AB5DCA0932850190D712E3F27EB207473D18E29B20B433F4E6BBC99B28AEFB5ED0DC74BA529377F0F8A93BB7208CE98049A862FD513E81290187A5B2765E4EC5B4F211058310D0396CFCEB90B9E86E681AEC3D3D81C787A3BF16A412329AE643576A50F2A72E59165AA357ADE9C194A4DE0ED5254FD206D05BC375D1B5E8960B7293C768B7A66796DE0D5587752CDF7921C2053A5A970B9FEBD7A20F336C93839D567D1CE241F061565A893A409EAC2645C02D3FF00AA024F31E50946A8CEC435508486AD757114FC138E57B42F2CE12A248355CF35191341892DD910DF5528306C947B0ADFC0AFAD68DE715E8B2D9A43B8858BFC04F73B44A04C4E0D331DEFD57587276B188965C5924BF1118713C05E975090C52C4DC2BF7BCAF47E4E274DEEF4FEF3D91EBA65F616B8C476FB9EFCE61CB8A0524D97C27491A0C9BD7D99B0EDDB2A3E50248793FEF1C248C15301A3B765E9AE21FEA0AF86F09A5BF42D21638FF6D169D6127463962D3BA17F5CA63ADF63F317CE2B7CED21311A05CA842E0DD6664953DA479851E80F270B4A7FD11C3FD6A52862716AF8A67FEC893BBD104F5394F118D579B787730D6C37AC242A328F724DE9C0AC6E091A3E4CE01E29400836ABB6D1363E049C3CDFF2048F0FB1D36FA1B70070576B8A14E766CC098989EA9C624446DA2D4D45E7381AF63041EDAC0197149AA0E", + "k": "69B8F091A450890C0DCCE0120E9BAB05054C7785A797C93B6FA39FF5E0BC5A70", + "m": "FD3C91294D8C974930B4B6135AB647D4A7885C83FCDCB30CBD38332E14094491", + "reason": "no modification" + }, + { + "tcId": 29, + "deferred": false, + "ek": "CB2468A0185567F8A60ADB33CA5239C11C4A3E0C031D385DCFA28C3AE2A9F71904BF379CB9E0BEDEAC82B2A537357A9C3AD33362602A1CF6458A745ABED9233A092B962BBA2B0A66DD4A85DAE11B0C28230AA44C40F2B68687B7D54833062CBB5B0233E25496D1C84204B2BAB06050C00C308EF53DD8345143BA810AAC477C8119B1C595D964B13F837849B58D8E1BCE56437F2ECA84B86C91173670E0995D9769642B0AB0BB0713D313AEB7C41C9B2CC411B3B62B110308D94F0DA1BB69D406DFE7286519692502BC83E15BD50494C1047980AC6043B18D7CB72EECB00EEDA515C97C0ED08B5D4BB001BBF08D9821B9A75C02666C357F00278279348462759A602359F5A953247C1928172A013E3C53B7E95B81A64A6DB3AA86CD7670CF7C38AF357A317B71671B950E2BB85EAA6138A5AD93A1640618BD98092D85D36015C0B0DFF6059F3B09AE5007F89AB551230D8B9A2BCA59238405372BAB7F4D8069FF7457EF3720A171C3A6312CC8D69191CA909A13946CF8577A96086893C0C59B026A21835543B8583A05F569977E072299BA580C179EA2976810AAAA93F57DE223B97CBB4CBE559E18139372EB1A2095B8B509AE2CEA5B4944335ED385B23B5EB7D0847A557AAAE89611937495C825B7236280ABB6D409CD513A03C91139A251B3278C929DB23BD815BF68007D50B8356C03BE88F86E410ABFF6CCB3B11BC5D41C7839D48F365AB4E9E29F0B0094A4C4ABBD6761527850286432530241968122D2BC877DF5781D17AE12095C177B69BE3B989E81CB539A2FF2E28D623303FED5750C58B9CE051A6B813899BB3C74D82B2F127E51030BCEB396EF547ED37ACAF1D46A77F7B2B24B48AD399B53FAA69C079FFEFCB9F8367F7C513D142C8392A8BE6089CC2301685460BCCB19BFD6AC821DD840A3DA30C3208668C7103EAB78C6520C1291239DF8217C25450B70302020A4BFF384F0619142A04C769C9B18D27E42FA30BCE60A1EC2AFB618752A3917EEDC37BD15C44D0ABA1FA3A40C23AA14C98E016A592B459BF4C13C07354A1DE0539445882E21B97B1767015810325086AE71CDC0B5C0D7287BBD99B381680BD6559B04FB84835C4419316FCD223B84D03816D86C738334FDC894BC81B1E26813A2159D426AB1FB70A88FFC1782E649BD860D148B33F7607083A5928F1C835F880DC9E3235EA51E78A403F7BA726D17951CB7AE7630AA7394A80D95A1EDB1059F140F3EBC8D1C9BA9F43B75ED90538CB219F8E4A2B202084E049473D57D987CAAD2B51DB009CF8A538F8205B0B4049F41ECB344F84C538CA49F5A8FF309D036C6C520932F08072F5678CA68568A41330D9BEB34BD308F963224F80B5DB9B10E54D146CFAB5AEF84A7F9C62B7BC24A26A578FCC51E36738BDCC8AD24410155AAB74D8691C1E699E3722481BA074EEC75DAFB723863C308F60E10D195617BCDB877153D9CAA775647A83B1DE113019CD6C3A7CA38554023A6BC7EEC594FA6C14DA8353737F0A549715E39C49FD9625F187C3BE1602B6BA178D1784B52690B1E1380847203C13624418C1C1DAA0B231AC0FB39293843CC3D6B48C32B15098748DB0B3672377407EB7441B82371B56EB3E90C983A895AF85D57E76C53088D944840CC309853814266D66DCE88915049579CC45CD602", + "dk": "58C845051321CDE3A3C19C0D3BDA49688751B7C113CAA67BDAF87204D20ED9D79E39D135E64708827BAF19D25807B35F76500445B971DEB6A7D2680D46032490D042FD59B963291B5BA589776499DF1635B1249A12C3CF42322EFEECADEC1A243738260F2503364087A6AC839D1B5B85DA2A0B337BEE74761683A0ED501F67869FA587CEAD708A2309329A7483A8A3C895241A15732C46E2A864C94A33C36C6A71400E70678863B89A5B6BB8B0129679591A87127518BC2D903F06826605D7CC0DEB7E5A95B5BCB691ED852C94CA95683025771235156B406DB024CCD430822C785C3B265633AAE6BC18E4BBC4C6C983F1F0B0F514001E4106F36CAECE1380D661242E43B585A8B1203431BF46BE69567B9A883E2F67539B4C62EA6294B7365796578FAACA0F212B8B87B2AEE6BA128A07A03F20085D8122182465D46A8C227363EA7B4400920CA22C454CEBA538E5CAA110B7762087B86B37CC1932A2B5595D265F3326335D407712D80EA34C4ABAF0BF9D4429300B14BCD2B9E186301BF25C43EB544FB32D30BC6C643BB028577142761C33243D9C038BA0BCBD7502B63196AEE79A4D8DB630BC748D7220C43F76C2A77A7D60F728EE1133DB0C7AA8F0CD1DC0100B85460EB31D0BC9658021443D6564C0D3AFFC6CA1E59C5DCCAA454156923CE7B2E8B123B1EB39EFBAA7EE0CB17F627C79B690816B5EB317210C16A1BB13A803C2453197A19E2728C9F61017D20D6C19C48D21566A583A848A3BDE79628CD4150A30AC1C44AA2673C1810B89545971D9E4199A12B82FC05774475797C6CCD0A9C699F50F0CF663DFA14FD809437E0889B285959DFA29A08040802BA77E3C3CE275CDC3A92388518C9B70BD66BC3424F67FC9FB924F59C500D2C138E7C06179A3EBD800D6F96490DB82C041AE9C958D5015A66D91320D86A243AABB8BE17260D86AE4F5A6229859811552E0BC1000F3C47543698DDC7A61CA5F68E68D47A96733F32C8437B893B10FCA1B0A6866ADDA2CC610E22D155984855A9CB99339FBCCC972F62867D7BA04DA7C10377419E36D8E3876B2C5ACE1380A505CBC418A181196B150B53F5FA3B9AC08CF34E78A39A9B66559A859EC22461C9D836CCC433B8342C94712EC46BF716D0628AA3D421AF6A24B02F38DD4C54E3CDAC15AE47863B0AF21214723FB9592893825031DA00664C1CBAC1585B60E7A71022A35B3E23063CB49B278CA82B51EB9E010E6A3B7C3227356733A6ED0BD3D84A6B7C1C0BFF42842168F9703B1636698B171902AC4775E1A15F0A44B39E9247FB61C0BC90BBE2AB156B11EB2CA98BAB75DB92B844154258FC6BB29C164DA177441968F094941C3FB417C078654CC6358C6143FC32BC1518059105EA8DCA282F138C3EB61A48B2D63266012966BA12654C7B4142129AA0D5841BE0B5784A94CF1007FFD5112EE21AE82D7BF3FE0B1509710569CA6749A0B706C5B79A883BA985967731276FC2B8431BCAB9B1E2E9330FFAC9DF591AB5B17317AA93D8903708CA8929EFB8DBB2861E067CF57A2606F174C5DC80FB26A70EDEA0D849A6977D39866A78F3AA417B3B87D1EF00A7AE2734F249D64C68A84F016DFA57C8FE72443848EB058A5D5B784CB2468A0185567F8A60ADB33CA5239C11C4A3E0C031D385DCFA28C3AE2A9F71904BF379CB9E0BEDEAC82B2A537357A9C3AD33362602A1CF6458A745ABED9233A092B962BBA2B0A66DD4A85DAE11B0C28230AA44C40F2B68687B7D54833062CBB5B0233E25496D1C84204B2BAB06050C00C308EF53DD8345143BA810AAC477C8119B1C595D964B13F837849B58D8E1BCE56437F2ECA84B86C91173670E0995D9769642B0AB0BB0713D313AEB7C41C9B2CC411B3B62B110308D94F0DA1BB69D406DFE7286519692502BC83E15BD50494C1047980AC6043B18D7CB72EECB00EEDA515C97C0ED08B5D4BB001BBF08D9821B9A75C02666C357F00278279348462759A602359F5A953247C1928172A013E3C53B7E95B81A64A6DB3AA86CD7670CF7C38AF357A317B71671B950E2BB85EAA6138A5AD93A1640618BD98092D85D36015C0B0DFF6059F3B09AE5007F89AB551230D8B9A2BCA59238405372BAB7F4D8069FF7457EF3720A171C3A6312CC8D69191CA909A13946CF8577A96086893C0C59B026A21835543B8583A05F569977E072299BA580C179EA2976810AAAA93F57DE223B97CBB4CBE559E18139372EB1A2095B8B509AE2CEA5B4944335ED385B23B5EB7D0847A557AAAE89611937495C825B7236280ABB6D409CD513A03C91139A251B3278C929DB23BD815BF68007D50B8356C03BE88F86E410ABFF6CCB3B11BC5D41C7839D48F365AB4E9E29F0B0094A4C4ABBD6761527850286432530241968122D2BC877DF5781D17AE12095C177B69BE3B989E81CB539A2FF2E28D623303FED5750C58B9CE051A6B813899BB3C74D82B2F127E51030BCEB396EF547ED37ACAF1D46A77F7B2B24B48AD399B53FAA69C079FFEFCB9F8367F7C513D142C8392A8BE6089CC2301685460BCCB19BFD6AC821DD840A3DA30C3208668C7103EAB78C6520C1291239DF8217C25450B70302020A4BFF384F0619142A04C769C9B18D27E42FA30BCE60A1EC2AFB618752A3917EEDC37BD15C44D0ABA1FA3A40C23AA14C98E016A592B459BF4C13C07354A1DE0539445882E21B97B1767015810325086AE71CDC0B5C0D7287BBD99B381680BD6559B04FB84835C4419316FCD223B84D03816D86C738334FDC894BC81B1E26813A2159D426AB1FB70A88FFC1782E649BD860D148B33F7607083A5928F1C835F880DC9E3235EA51E78A403F7BA726D17951CB7AE7630AA7394A80D95A1EDB1059F140F3EBC8D1C9BA9F43B75ED90538CB219F8E4A2B202084E049473D57D987CAAD2B51DB009CF8A538F8205B0B4049F41ECB344F84C538CA49F5A8FF309D036C6C520932F08072F5678CA68568A41330D9BEB34BD308F963224F80B5DB9B10E54D146CFAB5AEF84A7F9C62B7BC24A26A578FCC51E36738BDCC8AD24410155AAB74D8691C1E699E3722481BA074EEC75DAFB723863C308F60E10D195617BCDB877153D9CAA775647A83B1DE113019CD6C3A7CA38554023A6BC7EEC594FA6C14DA8353737F0A549715E39C49FD9625F187C3BE1602B6BA178D1784B52690B1E1380847203C13624418C1C1DAA0B231AC0FB39293843CC3D6B48C32B15098748DB0B3672377407EB7441B82371B56EB3E90C983A895AF85D57E76C53088D944840CC309853814266D66DCE88915049579CC45CD60235DC954C8CA6DC15AB79B2C974D77BA09F049C2007BFD5F81A2BE06F178A0EA5FA1646B083D3C34FDC56A8B5797E26890EC84F86E18EAA17ED3DDC78300313E9", + "c": "1DA1EF5325F46C686D3AB385F8AA79758CA0E6C0092265C636DEDF9C5F34A0F7A36783AED59E21EFF5A8CEA55439E5B13C42AA68E1C19BCD0CA8C629FFF79198673D416A9CE82DCB80D7905968B02E84EB04005D0AD971700B87A023708F169369DED4833B8C13C8C277CC1CD7EF32488DB63E5C1058CCDB73F88A679C41A36144EC2866130D68914503889E783A5E28A1E701B0C198AAB245E6F61337CC9B1CE2CE8B8CD6EB106B969E120CD09EE174E458AAB80ABB5795B091E07166A39F15349C0EE271D063100D07E46E9AA07DE76DF152753EE298930E0172900F7A4E47128E5BE9CE81A317B07282E3735AFA02FC0F89A6561F5B4275E3DBD31FFE2A04947F8CC6067C3A8E8FB625E6BD23BC20F63DB535FAB0E2C44CCD50339959D3A83AF0FD57AFB2C6BBEE6B9920D56A805447CBF7ADB6F957B9DDE850044E7DC47ADA07BAAC747069241FE4B46F1F1DD8DC2E4BF52ED6792ACB987A1528B89213E10EAC95D86519A95EF6EF5D9701971AEC0608EFA2A51A5D0127B3BDFED8E8107FDA600D17D913ECDD8D9860C16E8788CC9CBBC99EEA2A7AD8CF35B85670A0B15607F3ED98D88AB1A6585E1E0561C37DCE34AA00757BC1F6CFC81C7BC2EDC7A011FF12C1C35CEF9D1F8BE5B80860B5ED0707A04472E94D2C3D7C1B1BA4611EFE6D023CEED3B486A066E3B0121687DD9AFE0C4771678EB7B0D85D249C77BE8721B89DC086C4C5F14D9851C51D51CA2646A32929E36A33A35EFA58B0978B2DEE5CBFCD23F3B830CF1AF3EE6743538F82E246F7A9F76B6B8E43C84C9539EAA2A0DAB6EDECB4061B0B211C5547574088B8EC42BF6F21FCF299BEEC8CFF41CFD1B49639032F4ACAC92251B9F37CBF51098F4DEE7D88363A1910C9A6BF689E8DB93EEDBFBE8FACC4D1707686E1BF9E5E790DDBC6874218FBB43128783F611D1EBAE677D526057A87FD33AF449648EDF506E93342CDD38AFB6EC3FAE952101B384E841D889C025FAD91099F2AE41EC3E3DEC70252663C01B4B04EC1501422A97B5AD5AA27CC9EBBE2C22BC22B8C706F04FEE274764F1DBC4CA60DC56631BB2CADDD5399A2F061FCC21541D2595D15CFB6DB464775D4ED48559CCC97DD25F64CF2FCD30013EC35AFA96C1E3368CEAB29AD03FDD5B9BDF1FA1356132210702466719DF52FC34A0A1479FB913B6DFD9CCAA0F9D672AC618591B808B4315A5E17889D99E271FCBBC3C4B496DE8179A74C1293468392E2B592F3E6925B9F81604790DDC3EC0D1056F31F3184FC0330497961EC8E2737FE866AE4C262E5218E06EA7C24B464AC7D5FBB44069B9BDAFC96E014DDCD168C457140078B0A7DEAABFE04773BB1335497CBCCF4083E6D41288B3901029F1B266AA938A9F14763C679DF1E1C58EF406BC2ACE2A236B37557219DA24812036E557ED6B6C1A3A1776C5C0E64E1AE1A2A0747CF2CC55E32D48A7B1387FC9158222AB2582AF43580043F858E527B25379081B97CF0BE6AA5653E186CA066BB7D57B6C4AB8131C68423B12622CFE234696D761E", + "k": "C21C8C4B59906D0C4ADB1F3CAF47F9EB326B8A62B3392407211D502F40C7E07A", + "m": "7DB18CA35A53AB3A65E4C17FA096DDECB19FC7747E657B49D1C1710DBD1D197B", + "reason": "no modification" + }, + { + "tcId": 30, + "deferred": false, + "ek": "0F613B04128F82A73867D9185891C29D6C3E1381843BD502D86099A740BAD5BAC68C590510CA3F6F2B5463B264BED34952F10C784A92AB7696268410F1F28C06DA7A18416A7B1B5FD23393C33592248C9A8B3956A999483E000F2A2C6F796052FBB22F7F182A191602FD93AC066355B71B7E6BE36E531B1D34F0382E34A4CF623B7B1127519A7BC4EA3FB0D1C91626A417B6129DECAFF2865273F759B4DA1A95F79FAD0CAB09FB61D34B9AD78B8046F5601FB53D28951AB73842B8921B2FF10417DB4F9964A41EE820FBA83D61D30D0EF2C2CBCB1F6CCB9E77523DCCBC37ADB8B9E31A0F0E1C4192911060E8677140690EC671A5445F42FB1A68DB4D1678BF9B60129D98A859837599ABA0DF465DAE76972946C73E8343A19A3C03657806574F59D2611163334FDB0EE8B0C13C679C6D175C22807C86F0C199C89CC43C0DBE6587F0A36199143EAE30116B3B0D49839AA18CA49E2992740B5DBF1C91ADA352D39AB7D0C23FCCFC41E783CA0A333FFE00074E72BC834669931630898B718CD5304E253071E730F1EB067F94861DD98FD9A262FAC919FE870E3D21BCFBF67180C57A5D2797F6C7B96F544CDF92C3FA8B49EB366C02885140D128B88225750733E6105868AC48A468002F35C34C38AD70A7BEC9C37713B98D9EA8A716CBC85D0C3EF5B4BF8F20BC6BBC61CE8150B4F842CEE0A40E0A7FBADB76BE9B5CF2B39749F51BEED8400822044E2CB01C021B0D9B7FE67A8AFF9B227C120F643B85152B40EC4A1734E2A141159A5A96C8B74115A0C92E6B913464994E980A8A304194A595BAB892801C15CBC5033FFAE70F368A62C65A598773C199E20EC07B73B1ACAAF48CC963A6986D9A3D2D236352F66065025751B9884D7CBE3A5538A9B90372D4C22797659B5CA8D357CF00B27C5714344374A5131B261D948DE22390D0521F50553E78223388903CCF241FD608CB4FC1AC7C44A2D3141F0B998B99E704ABEA1E634C1F44231D347254DC2CCDDC114AC4488A549BC4696400F0BABA18198F46E8CE43C93581FB661C745AB5A5520D4450982569BA1B192FEACF37EA8EC8B8B267271A042022DFA177A7C1CC1CF6765492AEC59729D6F61690F27B5D010F22C30E44D15864395BF01771158BCC5F8B48F656CE5D9049D6F1C11CDA96F8C724E0460BDAAA1DD9CCAF0C46162B943461B729AF3543BC9A8CE3B34971B39DD25A6051D41A248BBCD5555D7E2028A5B453FC4062DAB1337B134009C71BDDD705C2E44C64E15C18F26361D8A7A2F7A13D3C31CB3147ED777024B8A90B558812B47AC861BE5B894B989200BEDB242E559801C164003C6EFA61AC34649993F782CCA150DEE1443892BA3DB87B094C491C798B5FA1AA30491B7C7CC3769476D28AA17E754773390316647CF33076CC6CA84C804B26E75295D2A4754B505A3831DC793ABD874C6C1451911B97AD39825EA42D65DA63C42CCE1EFB1397167F1E8933399C2E288AA57E000406A4C66B5A357AC59036F37A52516701B52934C6A1109593809C0F72170A0EC9AD22EA6DA64B0028680B405924287280A8C49B2D516DC9D6B93D42A9B544C6833C0340865905EB00F4661B200686A0A47FE280937BB00F8022B8F0E64AC251BB62D09FBAB3E7C79CCD450EECA94120B05A0B071588E2150EDA6B14150F", + "dk": "E434A051F4253EDCA7BAF48841E07438B892F47ACBE249CA763061CD3B6C9112629CCB760107BA96C260793CBDA5BB4EFA184DE27432683C96A20B39D1B72C4FEA3D05D299EC16CB7BCC7C853B83E92AC8064C38DBE256C86C711ACCA9B0C480A0444C6F8C8EB187C32BE0C5A1F20EED5365C32656AF7335275920091A38EFB8BAF8629E87928E51B2370FEA2B66D188A09264D21CB0AE66B5590A051CA16CE77CAE914003AB994691DC0A09FBCA27644A7E48405AFC5F4CCA9525C113DFF133C1BC057E742FCEC38531EBA8E2D252C543172459817C18774CACCFEBC227D267B5684C325E17C0EAC74B34D22E136B98C9A8532139ADB4ACCA2F3A63A21751D0324CDA8A15230918E3856A07C4A51813569B76093A14771E3606A33C389ACC42453C05027501E9B5AE311C9D2D640E165816FCA60BF6C5423C9C585D642151F7314C9C656E8C3572C407C6DC0EEF1169AF4B5B130ABC0507ABBB52681135984BAB688AF080F567B93F1C2C37E231828A3106600FE11429DDA8C673380105E26423A06BC97BBB7B619A5E54429EF549BD9120BE23892073777F8C21E3700C90751BE53658BA9035380ABAD8A6522DA19ED801646A772353DA9355A75C65164940189A79439985545863DB9896F95F7553BE184ABD982C4EE692CC08046A8951C95EDCCC3B5B942359B82FF4C3ACD86AB0AAA5DEF49ADBD344291A8A15F613A1A8591710BC1B854682659D7FABA1D05924F063942E384953EB59CCD55F3EA4081AB38E13AA12DCDA528CD06907018E9C287042583191B8BC75767266A0C9AE074F0CC4B946906941D17591014ED2FB4A0A3A01179C26BFC85A5EB9A859284E13F04F65F589FCB9557EE5095AE79036033E2D5336A0AB191776A4CF01A6F45B62F3B8767A8413DF6539A5B1781DD30C2BB41A940A4E2D209526E600C713AC522C104BC8C428895F35547E4DF1214804869EC5B92BF9C2FC28A361E050182805E4919BB4EAB368EA0417E03D8611CB09F884C05B3E66294A93EC62D694BD5393AB3114046E29B3B177B997F7CE9E2305BA257A923B10C7A3BE7FA881DC1376FA879BFBDBBF0B8000DEF00DB26A522A96598B450D5B39B943553291D42AC6EA0D1FD04247A41420DB7314F676557765FBB15BBE314EFC968C76074BC3B609268C264B0441EAF92E09E59793273DD8B50ECFFC103DF067496C8015893D05DC28ED3445D726BF0936145720CF7794290FF189B8C38AAE3BC55D2167BAA3AE39BB90D19948DD439C7D827CB2F37C17B0A0D8A74D6CA82D4448114DC72D91991972F122018197F192B4ADC4AC41EB0F2C220DF2A94E61463BCC105A174C985933B09D3326AA2989E2CB4BBD7C5B557C46AD9990BDE8183CA63CDFE98F51070D97C7AA635C8149276C58E9CFC314BE31455939C854B03055436650D3651C3D566F8129648749499AC1946F120D02A6CD230100D5A2788FC35D4C47B7CF086363193843523A81221FD09461F06919DBB5287D727957EA4A2E448D0D8CB3A8860E71E8C60EEA37885878B7E07DE6323908830491DACCA88B50CB901B384ABC4B33236F727D1A5466E5506F6100AB16AB4567937E39A2605A52783D574DA5C961254704795C450F613B04128F82A73867D9185891C29D6C3E1381843BD502D86099A740BAD5BAC68C590510CA3F6F2B5463B264BED34952F10C784A92AB7696268410F1F28C06DA7A18416A7B1B5FD23393C33592248C9A8B3956A999483E000F2A2C6F796052FBB22F7F182A191602FD93AC066355B71B7E6BE36E531B1D34F0382E34A4CF623B7B1127519A7BC4EA3FB0D1C91626A417B6129DECAFF2865273F759B4DA1A95F79FAD0CAB09FB61D34B9AD78B8046F5601FB53D28951AB73842B8921B2FF10417DB4F9964A41EE820FBA83D61D30D0EF2C2CBCB1F6CCB9E77523DCCBC37ADB8B9E31A0F0E1C4192911060E8677140690EC671A5445F42FB1A68DB4D1678BF9B60129D98A859837599ABA0DF465DAE76972946C73E8343A19A3C03657806574F59D2611163334FDB0EE8B0C13C679C6D175C22807C86F0C199C89CC43C0DBE6587F0A36199143EAE30116B3B0D49839AA18CA49E2992740B5DBF1C91ADA352D39AB7D0C23FCCFC41E783CA0A333FFE00074E72BC834669931630898B718CD5304E253071E730F1EB067F94861DD98FD9A262FAC919FE870E3D21BCFBF67180C57A5D2797F6C7B96F544CDF92C3FA8B49EB366C02885140D128B88225750733E6105868AC48A468002F35C34C38AD70A7BEC9C37713B98D9EA8A716CBC85D0C3EF5B4BF8F20BC6BBC61CE8150B4F842CEE0A40E0A7FBADB76BE9B5CF2B39749F51BEED8400822044E2CB01C021B0D9B7FE67A8AFF9B227C120F643B85152B40EC4A1734E2A141159A5A96C8B74115A0C92E6B913464994E980A8A304194A595BAB892801C15CBC5033FFAE70F368A62C65A598773C199E20EC07B73B1ACAAF48CC963A6986D9A3D2D236352F66065025751B9884D7CBE3A5538A9B90372D4C22797659B5CA8D357CF00B27C5714344374A5131B261D948DE22390D0521F50553E78223388903CCF241FD608CB4FC1AC7C44A2D3141F0B998B99E704ABEA1E634C1F44231D347254DC2CCDDC114AC4488A549BC4696400F0BABA18198F46E8CE43C93581FB661C745AB5A5520D4450982569BA1B192FEACF37EA8EC8B8B267271A042022DFA177A7C1CC1CF6765492AEC59729D6F61690F27B5D010F22C30E44D15864395BF01771158BCC5F8B48F656CE5D9049D6F1C11CDA96F8C724E0460BDAAA1DD9CCAF0C46162B943461B729AF3543BC9A8CE3B34971B39DD25A6051D41A248BBCD5555D7E2028A5B453FC4062DAB1337B134009C71BDDD705C2E44C64E15C18F26361D8A7A2F7A13D3C31CB3147ED777024B8A90B558812B47AC861BE5B894B989200BEDB242E559801C164003C6EFA61AC34649993F782CCA150DEE1443892BA3DB87B094C491C798B5FA1AA30491B7C7CC3769476D28AA17E754773390316647CF33076CC6CA84C804B26E75295D2A4754B505A3831DC793ABD874C6C1451911B97AD39825EA42D65DA63C42CCE1EFB1397167F1E8933399C2E288AA57E000406A4C66B5A357AC59036F37A52516701B52934C6A1109593809C0F72170A0EC9AD22EA6DA64B0028680B405924287280A8C49B2D516DC9D6B93D42A9B544C6833C0340865905EB00F4661B200686A0A47FE280937BB00F8022B8F0E64AC251BB62D09FBAB3E7C79CCD450EECA94120B05A0B071588E2150EDA6B14150F81E7F3A4D5E46DC6FA36B4C63BAC9B8DB69CD90E250ACFD99280A13C10C4F6F9B02201A4ED8B58B3F3F38D4B28A3C6E87D6AAB11566531DEA6FC00781E6216E1", + "c": "A0C773196F91C0A7A3CD3BA0764E4FFA331F6962116C3B9FFF775F47A02AE2B0BE69FB89CAD33F5E059E051B92FA124FA25810EDA08AA89F4E5838A250315952E85BF73246C4019DC0F8DC7E6FAC2C0BD1E0191EA0032221F4C5549D914145B3BE2AF25886DB7526439BB9ABB6EF57C959D9CC76404FA02206B5CD4A2EDFA23B9F137729E7FDFD46CE8CB326CC04E73EAD7DBDA6C76EC19972E10049394E03BE7933315AD8B4DF72D0582EA9E36205F07A5B3A0B007A683D677D4571B907F0F967227E5562873D45F96FF2A117040EF2AC2026BF1B6470FF40F50D0A2E53979F3F61AE0E041EFA26E058F753D2436AE9DF06E70252268CA9502859C291BFED18AB563C2A5A74EB4E572E1A916C75E8E7C6B31FF39EC44D29B581598439F8A5E7FDD72C720E703FA24FD10FDEA3A43B06CE30B5C41D2C891724C7872642381860252B20345665038444E8E1167D5CCA83FF29A40C306E18CEE1B22CC583E26B8FAD23D2FA3862CAA0A21F6EF090959982E0E6B1E58413969892A41614A76325DA18C7FE4A73F27FCF275A3495134DF24D94AA1D4DD96174922360F39441F69F8F07EC5B060178AAE1CA5D00F3DD37ED4B55DABFD28203E65205AAAE8B2A885E211A5E35B9FE23CCF991A7A5C156FF8E1B0253B42AE6A4605A55C1A0F47E8054D9195D4F2496458EE4FC64DFA8FC4D2BAEE710900120ABDFD16E6AEA23550BB1D33175B9441E04BA281998D89CF3DE29184CC2EBD2626A1FEA4BA05D1867AD3FEE28C7154EA5FB0E463268B2AD17DF5388C2A7259F044CAE83D51894D61FBB4690E6DCAE9822D63A39B2D887BB2D81E8D57085C8D52773ABE2AA9B8AB04735669311655A3B6AEA829AB486B54E54F6E2AC63FDED2FF90C8EF88C9E2812218433B59677DD9FBAB3E15558DF418DA6F3D61ED45900FB3415B5F1A2A7C600DB715EFD6A17F729FA317086180BB126BF26FDB8637B8D7C2523651A70E233C5B180403B507C04D93DD01A60591BCC77D60FA874CD3DDBCCF7246ECC63FF447DB9CF31C114D3A9E4518D672E803E0D5A9A7821855340DD65FB91157FBA1005EA5EB64E4AB762210EA81E7F93F8F3DCFA6164C5F68060FCA6E3D52F83E6FBABC47B3684C96F5F718EC731CD5CE61A3C368AF5E68EF74020A2B143D37AB268AA4DAF203EE27702DA2446915D000F55B90E2C67B01D1B2ADC07D613B6C88760E6AF7B50C08B88446B43FF419ED8994B9E380A8E35C60AB495DBFD8424F50BB85B1A4DA62597B630811EC6DEACCAB4B049AD3C99DFB034A91DD144D757D88B6DFD0E1F62F4ECFCDD76A40F6B01C6CF27FD2B3B8656CE335A194A9A7E04FCC08F234BE1ED5DFF2A73650EFE7A65A8F9298F522926275FCBA55BF167DF37CD48208F37894949973E3A3E8FA7DE0F45317C01B5A5139BB30BA10767DDAD39864C7DE034601577C600C929245C97016E82534B74575135F2326303B1532DAB96500D314B41903C22D79F7067FE2BBB33424238AC1BAA581BBC6E0DDF3A0162A8066D3D88CED57736", + "k": "7265696182169279EF65779A021AC0A0E0E7E4CFD37C8546D4DCB1BF08572AA3", + "m": "876B17263B409171B746C6936EC65FC94137F958DC974BF98110A1D07F6D95F9", + "reason": "no modification" + }, + { + "tcId": 31, + "deferred": false, + "ek": "C9CB9FD04057EB96006455C062E3C0722346ADB366DA0AB980C782C417B360EB1C1F6762EBF967D713A0D93A28CF9206E95451E91373805047D8A14FFD2041B4468B26C79B697A14EA75A33876BB865096C0289C1AC4B91A4399821349DC66496DF02B15CA433FD97D96F46F72E0B23EB561E809601C053A35F4171A963EC3F542B423BAFC56134B7C0C5927C746E6C8055B3B70B31CAD6A168DD78F63C64FE3044280297C6630562C48A822B570E3FA8A76995BEFE67734274337F14FE00C723AF55D596BBD0B2C04E5AC6D52A0AEDB04B2BF09B1F9736E9456C40D5976B1EC2CA21C28AC761E39C583CDF256AA3262C3264250B1C19B00849FA83BCB6614DA0BB19752AE9BCB7BD16A71017066F73804AEB3C7F9213BE4634401A7AAE7BC56E603516FA2839A791EA89C58052030DB4AA2887737D9BC9AD21ABB94246546892785CBBBFBD45102C24D2F2370BE91923E732892E599D3154502E878CCB990CE8383D2F5ABF021BA424008D07685B8B54C6A6550D9CCBD93066A5A651A9B2710D25B382E72CC57096900E16B7B9868A06909F441104860BF03134316382F64D4CDDB596C57866E0776C04F8C0F67F2286B7242477059EBE022BDA200B6271AF875A829FC368E1574F4F3C56BB39D7FF61131F014FC59870FE45466D968C109339F0CCC67F6A7092372CB977C75998EBECB68A46059D7146A2EEAADDB258FCDD404D6E95E5400C8432535EFD635AEE5235D3B8ABA4153B46C7D234AA94DDB66B229456C41B2FBF93F39AA048C158E50C312FD623DC1E818A494980A34C41568942C30373E430DD5250D0CC27D4AAB2AAFB13CD719ABC7F466B702A983318B8D0C3040DC56B0960291F30EA75986917A17BFB76BC4B4AA8EA396F127A41F73219DD06F27126A5F06519E328B5CEA9D67AC122B092FC3613D99F403DB86CCDD760BF8398C1AD6BE4B5474C34864F2B10D97E265FEDB464E01CB3A426A3BD8B3457267317B7649D62D4847C3AADB7036391CE068758BF1847B96C5F3A69BD36A9468F9CAB27476456B4EB510BB063C46D529758C6680B4588CE4F5CD9D225BF700B27F53C13D49808D561F0413315C01989B1582755CC4CC765391AA68A0617F39B843526081658532C2C0025CF378B31411E867C978109454818916F8052336CFC9788F87E53236DAB54112B876042FE9054D9C07B80F7B43AA900BD2580F386058CFF5624A9A062474990C2C126E22BFB300C452306B859201B3C67B7356CC7DCC36CAD7A7BFC44DA0591D8CC45BC7765E405A2F2373996A72433F332CF77A5C9F3146DE121447264A84339A652960109044B1FC707680AF70E457B41259A1B84C37892C1079B8F08204F218CE85796701B05BEE5961F55584FDD3BBAFF25F53F78D0B48266EFC4991E090EEB28799C002CFE902D1222EDB8A026813295E604921269D0E0A1F4CC70F4E528A092B4E15300EB67808ED20995EF3A80CB999553456DEFA4769791FE24C934DDB490AF61FE1FC0027FB10AD260A7C33BCFBF212D3B50568844FB022B7DAC9509B308A0040C9B5482D89EB41A655B7C193C01BF96E5CF8A08B4C1C344336FF53CE9F79009FAA3A3921807D9B4C25739C38568584367F5D882E4AFD33697EB22AD03D369E37C0FE3B981047BED55E0BC0999976E4A36C", + "dk": "F0AA12AF6024851A922B789BA87B869072382CF829D8AC455EA25BBD3C3B7BE58C4DA362494369D9482AD1C42952C64DF0A220B6668DD4364AD3E698BBA190DA9C5E67263A7ED27C3E90C8FA38441327CE092C0B91E08ECDE5C4CFAB7A24271DD782ADF8FC6984701625579F26A196E9B7A7A80B8804C564A735B7A9BC7161129F5FDB0FD0E6226A89071FB288884C3635CBA37294253EA57AF9BBAC807135876A338A9A2CAE4CB35938BE4735BBF06CABFC797FD2137282C8CC15F70BEDA8BBE41962119C4D326113A534B4E29AB464924858CAB7B8ECB0B388C6D184B8765C29B5218806944ED636B8793A0D70B3B1B2664F9AAA0F18D5991AC4C6AA3CCF0A633707BBC97D291BC8C96FE6B32490632383886F3723BC6EA606D09C50B28314736A317C15804E1B17C07045A1971869178E9864C21C24902EE70CE3682A31336DB482BAA9AB22686A725716CDC84623CF39365B44AE6F88AF7C1B42C3168C4CEAADD875609AD247068202056C59DAE502C7B421394328D6197EC4FABDDAC3A47D9C614F7A0587A54476A7C370BA84FDEAC91B460C8E266C28AA5209D80885B7279CB685D5D184FEF93525B41CBDB6AEE769BD7C3BA3806338A27399398B617B45C6A94A9A58089E91367366DA0646624BBFCC35CE5B33971243EA0A8D61137CE7AB99636008326003B02B13BF200A93CABC55A2B2A2382EEF3732ADA819E3806AF2E8BC0602CA86A8ADFC41B0DD4A0E95FB9A25296EEA0027550A8FD04921EC30B7D50558E4B7CE82193F39A998012299CCDA061FFA23391519023C1CFD66C341765E62E38871D9A57F80A657D7347E927E55751A9F768A842A187E76C70440517523B7D1C88B1635208D5C7C4C357002E55768B21462D483318B9AECA5BD81A13507D36CCC7063084CB2657183A6C0C78D5B62A7E75C0275C29B304375C77BC8E85B569B968FCCA5E0E2146C951B7590CD0F3CB38E85586D02763610C67885AC56E84048C40FAA129EB05B8F7A67468B6145F949963CF165CA0B56F7E45DE523C1663B311F0B5DA037862559B2739C974B5CB18D16CE2695668D7B0DECA64EC9928523893C91850D91AA4B76B030C2E74C65A0AC5576399ECBB4E6723DE63825D3B9A1CA374AB763A52A541E8382245542896177AD07D9CFB5F2C3EA87AE2164625DEA89DCD06AF22753DFB1A3CEE1A45146409FE655F1C80ACFF107772562784C2C5CE67E9F395EFEA4609BB7308E13031B68C7B3B0C1CE9626E311264127CF8634C9DC35CA53036E9E30BB7B35C286236A2DB2BB9808006F68BAE0125512531320B3661305D0D4B1672D64C424D38536BA98C6417E3EB175D6C1857788C231C02ECABC4B28BA325FD47F3B56C62D0856703C5296E2576D258B98AA273E3418B43C9A52804EF842C543313ADF481F1E974E93210BFFAA36CFF758CC74914BC43110FB1C819678CB03952DB71C0A560D5425287D9590E6F1373902884A38A908082363E0CAB4B646AB016754BBA4E2FCB14E572025C806BD031C7F415377287001811E4F69A110D48449D24085FC43BFAA5465C1AF82A833A7575C578A464442A33C93B0CEC7952ACAA53EA70B01F49200827956B7B21AA697A6859F248C1DC9CB9FD04057EB96006455C062E3C0722346ADB366DA0AB980C782C417B360EB1C1F6762EBF967D713A0D93A28CF9206E95451E91373805047D8A14FFD2041B4468B26C79B697A14EA75A33876BB865096C0289C1AC4B91A4399821349DC66496DF02B15CA433FD97D96F46F72E0B23EB561E809601C053A35F4171A963EC3F542B423BAFC56134B7C0C5927C746E6C8055B3B70B31CAD6A168DD78F63C64FE3044280297C6630562C48A822B570E3FA8A76995BEFE67734274337F14FE00C723AF55D596BBD0B2C04E5AC6D52A0AEDB04B2BF09B1F9736E9456C40D5976B1EC2CA21C28AC761E39C583CDF256AA3262C3264250B1C19B00849FA83BCB6614DA0BB19752AE9BCB7BD16A71017066F73804AEB3C7F9213BE4634401A7AAE7BC56E603516FA2839A791EA89C58052030DB4AA2887737D9BC9AD21ABB94246546892785CBBBFBD45102C24D2F2370BE91923E732892E599D3154502E878CCB990CE8383D2F5ABF021BA424008D07685B8B54C6A6550D9CCBD93066A5A651A9B2710D25B382E72CC57096900E16B7B9868A06909F441104860BF03134316382F64D4CDDB596C57866E0776C04F8C0F67F2286B7242477059EBE022BDA200B6271AF875A829FC368E1574F4F3C56BB39D7FF61131F014FC59870FE45466D968C109339F0CCC67F6A7092372CB977C75998EBECB68A46059D7146A2EEAADDB258FCDD404D6E95E5400C8432535EFD635AEE5235D3B8ABA4153B46C7D234AA94DDB66B229456C41B2FBF93F39AA048C158E50C312FD623DC1E818A494980A34C41568942C30373E430DD5250D0CC27D4AAB2AAFB13CD719ABC7F466B702A983318B8D0C3040DC56B0960291F30EA75986917A17BFB76BC4B4AA8EA396F127A41F73219DD06F27126A5F06519E328B5CEA9D67AC122B092FC3613D99F403DB86CCDD760BF8398C1AD6BE4B5474C34864F2B10D97E265FEDB464E01CB3A426A3BD8B3457267317B7649D62D4847C3AADB7036391CE068758BF1847B96C5F3A69BD36A9468F9CAB27476456B4EB510BB063C46D529758C6680B4588CE4F5CD9D225BF700B27F53C13D49808D561F0413315C01989B1582755CC4CC765391AA68A0617F39B843526081658532C2C0025CF378B31411E867C978109454818916F8052336CFC9788F87E53236DAB54112B876042FE9054D9C07B80F7B43AA900BD2580F386058CFF5624A9A062474990C2C126E22BFB300C452306B859201B3C67B7356CC7DCC36CAD7A7BFC44DA0591D8CC45BC7765E405A2F2373996A72433F332CF77A5C9F3146DE121447264A84339A652960109044B1FC707680AF70E457B41259A1B84C37892C1079B8F08204F218CE85796701B05BEE5961F55584FDD3BBAFF25F53F78D0B48266EFC4991E090EEB28799C002CFE902D1222EDB8A026813295E604921269D0E0A1F4CC70F4E528A092B4E15300EB67808ED20995EF3A80CB999553456DEFA4769791FE24C934DDB490AF61FE1FC0027FB10AD260A7C33BCFBF212D3B50568844FB022B7DAC9509B308A0040C9B5482D89EB41A655B7C193C01BF96E5CF8A08B4C1C344336FF53CE9F79009FAA3A3921807D9B4C25739C38568584367F5D882E4AFD33697EB22AD03D369E37C0FE3B981047BED55E0BC0999976E4A36C9D71C52D37B30F0CADA8753234F7BE062673BAC70613CE6AA0C704C60E481CC1DA9B17E5EB62AD1009253B91A5C9D143F7BAAA3E76BD89AA399B671CCEB7619D", + "c": "2248562375F15D15580AAD60BF6C78957F86C7BD1F78D47B6FA78E68DACBEF2BE4ABB382C409B81A7F746CFA6F90246E0A33540A1C22ECF83298C0E0104E37C29755D5C0025DC5D9655A0A861A534DC58B23522B4F0961F8D40DCE1FAB1A8FED98B7ED1A027C784AA3AFC5B06680C8F64CD281788326CC4CC2F746E0AEE756F71DD7C3F594458E87382B0135DEE1F4897B80086A4667F260FA19C9A9C4BFEFA1FB054504EE11AA7286FADBAA1192C176294EC7E5A9E383A8AF658077348CF74D1707DA1A8F3E400187401D26BF9225B4B36A00466F75276BF2D10A0146C4611951D75B3AFCA5CB4F8ABA70D3999D56273C86413CCD6944AEAC00FE4D5FBD49F00186950126847AAA2F1D87732E4A42B5944BCBA773A83A8F168875B89ECFC6AB3642A7CF2303EB9929825F1B9A4BAD731EB6C2A6848A959EDE0FBF95ADEA3C4E159A30A376DE5DD9BCE1DD4B85500EAF83871A13F3EC1DFE74D86A383C957D6FE3BA1BB81CCCFB3DEFAC3567FCD167F9B202E72677D2F2012BE72CCA62DCA41E5F92519266FBDE6F60A691D78F0366FB0D79BF924C98D565511CE23EC62F3C7FAE1A3C1BC7817CA67CDCE53D1493EA94ECF0176372F9891D81D0964E409C38079D7548D9DBD463D5CF2302E07FD565EA41E8958C563293EBD58620D08CA822D70F87F4F2CF37E963A730DD5A591F2C5F372C9697118AFF2995170308BE96C21A0EF094CAE5372E1FC43172EEA54509C74E5C83A0BD352663BC49F8100C64A65D45D216CFDC69D8333049487261EF03F492D1DE706B00867BEBCF86ED3CF0CAAF4D94D2869E7BC62DBD4C5127FBE626DC26891D67EEE545CE2A3C6CFA5EE273FC017493B08535B907A852E9F4A166C7B8D7261773B73B6FC96822150484A04954A92FC05D0F8AB9716F6653251794F6B2FA63616322DA4CDF97D352566EBD6E23ED822A118A41C0A80FD420408645D077F7F1561FF5B342445C0C8DDDA5E46CF2F253513BEDED0548DE267ABEDF4A9B7809436AAD6F5258FF89581B4D66D9A1B5DCD1A35BE090DD4B67C29944ACFFAC110B65332C469D1266B256BB4B462CB3B6C2B71D8A119D3218D40B00CF449F9807ABF0B54313845FCAB484AFA418ED6E532136EBFD242E0BC499C7A6788FA9BF64CCFA6E5E0B78FA2708D3B9DB1ACD3EF4E3EB1B105EF73ABD0C0AB0D0055279478FDFF8F154CBAB11A9A5FA8F8170D9DD4B1DAD43F9B0DEBA377E674B2CB9424E754B3B203BCF6AF2C71C8A012320DD57CCAA59F2017545CC64A76523C79DC9932AF8999F2C01687CC80FE4CCC45C6C66F6453CAC8BE9545686920FDC8FE4C5D7B1A9C4C556585D70D520ABDC01B650A409FC907A4472229EB981F74E70EDE2DFD97122AA2C1468210932B8A48A9A38A5836F387B5086D1D3BBE516E33D4D989F73105D3CA0B6E126CFA3C11DD270E2D0168C4E08D9E61C951D4E759E6B97313F4A2BA4E5C7CED65D8800083CF016750646A851F533F631FEA14E8CBDE9EEB02FBB5E2621E31DCA51A60EAAB8D9C57BC3", + "k": "9C6EF50DAE26887F7FE5B0173C055E88DC2FE09384890E11777F742B99AD7C6C", + "m": "E0AAD46FDDE0B8E64361C3233263D8A751F5583DBE91AAA6E69E6318FC7A8EE0", + "reason": "no modification" + }, + { + "tcId": 32, + "deferred": false, + "ek": "B7F522438A05310B12921A8ABE79B4887CB548317B23A21A4213A0F940BC3268464343C89540B83155C980698C657251CE30C75073C3D3C73AD9902ED10C32CB101B0537827F338A94D9615154370165B9D22707693C5E0657BF890A1C5E820899087683D176986162156ABA109CADB1729A0B0A057C8007E4A6AE7E272C860190ED4CBC126082C1992B9F541FF68A419226A666F6A9439CC82B3424C3515ED1821DA501449B84B1D6C169B9F336AFC9109F4B0AA6A069D5C46095B40EC7C886C1B2BA060CC8C0A1B2FBB53FC102701FF33BE42C92FC8287EB311CBE4BB5D523420850B9D962158D14188C4A794E4C0A8A065757EA0C9A65429F114A983B4D55743FBEE267ACA76C14B1492E2CA839AA5B4762868FF2123A30B76D858B0EE4CEB0B9ABD3A2711BA5167B73226C3B96C184A1681A562F07365D686E17F10EB75545F4E0C52CA6BF41627B8D6A19787A3676159EF334A3F4C538E50484F97CBAA334C5B800A34C642D097549D8AAA6E6E16261E038CDDB816CE46BA2B8B821445209E5AB1CF71B008965FBF3A2673B5074943D2102092DF603F2989F32085B96CCB2BA245A7AAAC06C763640D11730E828A0BA3129A43F6F0825A682886D8CCD9E84B93999474B63CC8D272911D72729E79E2A494AF5EA20C1CA8434323164709090382644B11F0F6C806A5044098BB936F5CECB28A81AB516A1857B651B93CBABB6E3D76B7F79AAF6B503762A10ED8499347771F221C2A96A90049C73E6E1132AF53A88D38EA817CEFA29848FCC0AAD125CA1C829F03896CBA635DAA33ACE7C7EBD18CD7AE03A0F9A3659090F5F9976D600B451BB6C1F3281D6C2884522618AE20CD583AB9B32344B6A2C294B0684E6BAB686A39431292F70748AD02AACB57CC3153CA6862D2B15108EE71FD51C2B7F81ABCA9367D4619964EC7C63EC653FD1374EE3A9BF22C4819264C2A750DEC193D5CC836430B18C535D3E573F4574104D471D972361A6955E2E10AF34D95B4A123218667685B1AC6D696053966F3C56297B844657C85402A357649A82E4579B667A36734B665583AB026699D2F6B8F4F1BB25186858543B61260BD3CCBBA264A30135088C0422ADB4508A60485AAB3C63ECC9AF981A1C5913950CB8949B5179E48C7240CD6C858E1144C7EE92A885008209A055C1C3795FA3C49A98082CA077CE4A75B0021108454D3B0C9F01C00CB29166281A24BCA77ABB471A036C9DB1B8946B930BBE8615CBE4AEF6608DEC389BC75C443753C56F5A62FB6C532BD13D89506C4C5985307A53B2403B42265B35B1CFFD6B2CB443A359D75587B2947C7076EB2A2B5BFCA8B1CBA865674C1A2C1A5EB4917BFB9707590434ACADADC92CC7739933323924B17FB516974714A42E38BFB7F20E752AC6464503170C860FD91ABFAA4C6B70CCBB8A2FE3EA91C94B26D5C64CDEE57F936C1AC10704D473AE10479D798BCD6026BACF4C599DC104D70439B0E2A32C91A5D58010ABA9984A34689E360C7B296486A4C681405EC3FB92B44210D5D3CF52534095859E42BC9BCA7B3864D43CB9F46E685C0BEE8853FBD31285DC2EDF129635C70437B612955B7E56A128DEA321298662F4F96A8E1ABE81B54DA4292AFD5FE45E31E16B17919D9EBF8E87B38D48053AA9F6F41C5B55AB86C4E0BEE558", + "dk": "B4581DD3A668DEBB44ADEB1EB7274625494C6E4A8B303528A3C0CE78F58CA988834A4766B1941DA48898D7A8022589AE577B79DFA056A0305A034385EE20543941ACBAACB71A0184F3D308E790C52F1C210E12C726006DF729448B8B4C2B58B14D150461CB69BE1C840463AC5D4A5BCD07AA81246A3DAB0E82D555B624A3D878021E4604B4907BFD906308024D77B15836C64984C422F5EC3784448DE4D5AA98BC9DFAE665F82B046C446D33321734A2AFE72638683CA596822614994F54B856D9E80ABBC312303C7341F99720C080DB72C635D647BA733CBE521230F528D0119377436CE8CB1F7A48B7ED15904C414FB8404A5DD403D3B07FEBDBC129D274472C634DD2A5BF14C304F702C0861DBDA793834ACE9A851BE24B5DA56A4D433AB08E48C1BE6C5BA22067FD59C38F39A25E1230CEA26BB89BA94A0A3A5FD78788E4A150819E951C1C09B6B9D7B7B56DAB4C38A51A80B56DE30790B72B1743FA7782E40320104B2715A22A7794E4C3BB90CB493B8A4304C8084D18C0E822217A9985BD282B26F60F0A986865C39759CCB69109177A826275E663CF81179FA6181D746230DA0F73D991274BB1C3F802FD324CCA01B284BC6E33D9B853D76B95778DAD094E1DBB2DFCB099055C848B540CBA3962A843211DF6B15B5591C5630ECBAA834A9460BA5822A6200DA8E51B5B5292FE221862A36282B306B08AC03454C8A4A3B0C4AC15127C1CCA392E78B9C15BB8B4460A357DC90C2CCABDB7284D50D440D651410AA849648435CB320CDAC8782E31CB868C7F0375C5EAF51B6628C52AC6BEAEB1777C9B53277BB014EC831F3783E6086455CBA77E2391F89C2182DA4D95058120D2451944C0C9D91272BA1C70732EB332B83518B8925781CF90887F43446885C3A1FA6AB1636052731E7D3B126E556AECD9572DA449F97509D9C795E03961A1B82BBECB74A3859A802BC47EA0B014F5606C678FA15323D571AEDFF78575038374D99F13724FB5120890099A3DD531B7ACC7CD286C78C7182AA00140F48595F47BF0B8B6B74535DEE35C1FE904AEF4CCC591AF85E9BDDC978C95DB382BD82278028C79F0741AA85DE2DB4353C1C38299B010F7378CA21F0DE3A337B15135318E5DF69144593947B1A0F9110E5D3B7710D3892EFAB3FEB3BA67D0B977671F81CC44F38355D6D7C3B8677846A08159CA574CD150E5999C9DCABCBB342B5DD1C26B95762B5619EA21350616BFB06C04058BCBD6F9887879574020C4234CA77021CD52074BEDD81AFCFCC5ACA6691B2B4364183EC3C220E20A0060C4A40D4A5592C4BEE8D87E57E6A2CE99CA299631DDE545AA745D5FB9594A67011C5C2AA1090608E4078CCC59CAEC5F40DAAB6991AF1782B9F4F58F8CD25A597393AE1771DAF2246838C1A4E40BFD3A2C1366A563D698E3321B06672E523AA863A3B68E1053FC8A8428F7393F037290BC177337B534F80E93A19021DC3D5C94AA6859022CEC5AC5E8C16A83470AAA4C72952F823408D52981D8BAAB4D529751D02596CA129031C03576BF3B32304913BEAA20759F245D3F658C8A3C1A41D69EC10C6DEB336CC00B25E332253385B1E6F52DE1EBC45A487CAF133EF1104F286AA12FB1A2552AB1B7F522438A05310B12921A8ABE79B4887CB548317B23A21A4213A0F940BC3268464343C89540B83155C980698C657251CE30C75073C3D3C73AD9902ED10C32CB101B0537827F338A94D9615154370165B9D22707693C5E0657BF890A1C5E820899087683D176986162156ABA109CADB1729A0B0A057C8007E4A6AE7E272C860190ED4CBC126082C1992B9F541FF68A419226A666F6A9439CC82B3424C3515ED1821DA501449B84B1D6C169B9F336AFC9109F4B0AA6A069D5C46095B40EC7C886C1B2BA060CC8C0A1B2FBB53FC102701FF33BE42C92FC8287EB311CBE4BB5D523420850B9D962158D14188C4A794E4C0A8A065757EA0C9A65429F114A983B4D55743FBEE267ACA76C14B1492E2CA839AA5B4762868FF2123A30B76D858B0EE4CEB0B9ABD3A2711BA5167B73226C3B96C184A1681A562F07365D686E17F10EB75545F4E0C52CA6BF41627B8D6A19787A3676159EF334A3F4C538E50484F97CBAA334C5B800A34C642D097549D8AAA6E6E16261E038CDDB816CE46BA2B8B821445209E5AB1CF71B008965FBF3A2673B5074943D2102092DF603F2989F32085B96CCB2BA245A7AAAC06C763640D11730E828A0BA3129A43F6F0825A682886D8CCD9E84B93999474B63CC8D272911D72729E79E2A494AF5EA20C1CA8434323164709090382644B11F0F6C806A5044098BB936F5CECB28A81AB516A1857B651B93CBABB6E3D76B7F79AAF6B503762A10ED8499347771F221C2A96A90049C73E6E1132AF53A88D38EA817CEFA29848FCC0AAD125CA1C829F03896CBA635DAA33ACE7C7EBD18CD7AE03A0F9A3659090F5F9976D600B451BB6C1F3281D6C2884522618AE20CD583AB9B32344B6A2C294B0684E6BAB686A39431292F70748AD02AACB57CC3153CA6862D2B15108EE71FD51C2B7F81ABCA9367D4619964EC7C63EC653FD1374EE3A9BF22C4819264C2A750DEC193D5CC836430B18C535D3E573F4574104D471D972361A6955E2E10AF34D95B4A123218667685B1AC6D696053966F3C56297B844657C85402A357649A82E4579B667A36734B665583AB026699D2F6B8F4F1BB25186858543B61260BD3CCBBA264A30135088C0422ADB4508A60485AAB3C63ECC9AF981A1C5913950CB8949B5179E48C7240CD6C858E1144C7EE92A885008209A055C1C3795FA3C49A98082CA077CE4A75B0021108454D3B0C9F01C00CB29166281A24BCA77ABB471A036C9DB1B8946B930BBE8615CBE4AEF6608DEC389BC75C443753C56F5A62FB6C532BD13D89506C4C5985307A53B2403B42265B35B1CFFD6B2CB443A359D75587B2947C7076EB2A2B5BFCA8B1CBA865674C1A2C1A5EB4917BFB9707590434ACADADC92CC7739933323924B17FB516974714A42E38BFB7F20E752AC6464503170C860FD91ABFAA4C6B70CCBB8A2FE3EA91C94B26D5C64CDEE57F936C1AC10704D473AE10479D798BCD6026BACF4C599DC104D70439B0E2A32C91A5D58010ABA9984A34689E360C7B296486A4C681405EC3FB92B44210D5D3CF52534095859E42BC9BCA7B3864D43CB9F46E685C0BEE8853FBD31285DC2EDF129635C70437B612955B7E56A128DEA321298662F4F96A8E1ABE81B54DA4292AFD5FE45E31E16B17919D9EBF8E87B38D48053AA9F6F41C5B55AB86C4E0BEE558A7F40DCE21FC27EB6E7596A711E8B29FA33B3AEAFCA1F90450EFB0FA358688A591271D83D0E2BF964B9C7D2CA6227184BBE74EC134043A44DBBF8EF3B18EC43C", + "c": "72CFAA01CB4D24B32D0A12BD199C20BD3CFDB6F063CE9608A0DEDF0FABFFE8EDAFF2536244B7942B6FBB62297D85456519E9CBE3E587ACCF54FC28062765E0C6250A204007F82ECF4AB4CE33D78CD0B4B6E502B44B0259A4634FDCE0116835E5449313C089E603EAD7C49C08DEA8DECC81D8E2528B5AC9C98A5EE6BD58E3B60E98922614ADFA9390F9A2B6B66272024B20263AF2126C3477447C04F0C8A42FB8399ACBD6DD669AF1C805A204C2173503ACFD770ACE4470B7D683F751906B7B3E5E8B1EB6241EFAC9ACCC3AB204F4AF77AE4C1033F3B177C322B72AD1C52A10B35782631B74EB883A5CEABDEA1961F327AA53EB14A1DFB2B58A4E7B37D14B5B565CA21340F181BDE4EB3C6445AE772B07ADEE4237262DE99245ADEBDCCFE7E68F96AE76ED8ADB62A6FCA116397011F3A77074D568F38BA6A131EAA7727FC9BC8A2B00016A37ABA76BA1CC11989771E3FC7AF635B46AB69487347B6C8684885436AC1E8CFFB1B65054AC01268005C71C70F36899F543F876C0B9742E29FC4086564A074EE95AC5CB395D6CE1B1E384920AFE580C5526C713D963DAC69D20C4A96932303B632ADCB361D2D3AD37CA4F7875A5BE6AE62C333751283A430E78842CEF8092F85B54B064A558DC1D25A18BBF3C0B496FFF38B214F5D9A611019BC4EE49C3C1ED06DD705D720D58A97AB6FEF5518969F2A8605BB10B64E6FA31B8E096BAC3573043854921E4210DFFF279578D2DAFD40738F0714EDDF16C2868809223FC8BD6EBCBB3B331B1E8ADAAA7597E53E31D9E7B478A9F6E7DDA731AE9571F698A1C977C4F3401C9A05665E0B8C080B34964C15E13ADEF0348AB9CA3B64F18BEE6117D7DACAD1F08FD9B8AA8C5F47881338BAEE1B94FC40ABA11B0FB914154583BDBCCDA62D3AE898BD60B9C643D67514534FCE277087CCB66A25D345290AEE7C1B07D57D53896574CA762AE8D17A61D796F4A8270022DB314E27CE7906E4119C003385D88BE165BB80493FEE768001BB42676D2B71D58FA19199E714A0864546F2166F46F4787845525CB59B2F6F8C3E0943421A70EAB2705420BA3A62ED9AB8288DF8CA09A5ABFA64FDCD0049C61FC7B226249E0E116FA5CC0D9C2EB3B7391A40BDC0921F4D2936D368D8263791156741EE85F2C0267E858FC01E89B6149EAA18B0F8C8F827CAD5F8AC68F24FDE5E185B3223333E3A0B8245EF30B8E5E5B3E04874ED3F75A5CD25E1AB1130F0DD6D5DECF88E332F96B4F9A4C58F14ED57250B47B1CF3AD093E2B9C54922B1214000A98049003D1266ECD0F68237285A709E24704ED1CD37F3C64E15CA637D431AF5CA060AEBF5E0CFBFE464510669317944FE07F7EA48618478300725961E04EECDB73B411206EF5F3DF2809573D7FC42458D262EFB242D19F9D9AD9A8F2C05AFD31AE350E83CEDA11AABDAE85E2E32B1A226BBDBFD2D5C2B7B4DDA94012D53AA7289AE675C33E9E8F8F6F06537E240A97998DADCC39C836FCB8AC24D794AD291D42127E8B513CE0346E145B488FA220BA149A", + "k": "05BD5B91C2F634E5B8BC59697D180CF1B36A244C6EDFEFE7458308B5854C77FB", + "m": "90347D478D5D964D66A54BE930FD9F7FD3C2AE1492DAC35A6CBDD02616BCE14A", + "reason": "no modification" + }, + { + "tcId": 33, + "deferred": false, + "ek": "AF98338A682D431CA0E17775EB170E3742ABEA300D6A46C567C364DE8939831695C59BB7686729C9001E25A85FE926CC6E584E2BC86D3B25BC9D6ABB97EB7F15AC23656B3185CBAFE0C39FA0789DF0678FBF5A43E6E0C53EC38076572D9D84B1ABE742E2F6C0C8CB08CDCACD23B71D57D06708F32D50870D9D636DF1DC01A8378A211A134BB255DDDC0B62C75812AB1677C50DF56B1FF62024FD722D3E732F56A2C6EA10CC31F280ABC8347788CB291AC5A1820525B9A33A7089DD689962A046B652AD182639278279EB884163E2B115A29A3899CB0EDB4514A0836BFB8A51D834C1939B8DC108B6138FB88B9199DCA5F7F64AFF36B9296613F891265778C7963C3E702B81C54834469AC8B59920BEE7878F01052B77B0F54B6DC61AA3DE695D20786F7D309C3B16A8D2C90A921CC317E91C015AC80DB106D4810EBBF2C5A1530506AB1E28B7A32BF67A6981185F98B44CABCF6706B134B5537DC697D16AC003808119B0BF94C84BF569422C8BCFF834237B902D83BC4C16F5CDFBBA5CDAF0A69FC87DDC885DD3AAA852342C1EB8179756087C678EAE2878A777655FC19719593FF600789ACC6322018791874D33D9284EA512AF1231D4CC87F1BA6F6293A653036E590A892F101CC518110C984AC55C2931C976828283F0266609A45A8C7CBF8C23CA0279B133A38F9DC797D5E58011096D45441F11DC59AB5B66846A87059314FDC64E8CF50040B57432A18F46078AF5A6132B006856604CE009128FC5445BCB6891E91A8677060F39A2CAAA183FB8A0F6751051AB85474A539A4183A4486471418FDBEBCF40055AC46075C3B2190248A8202431DB828B82E1320DBA47A23A94DE5CC378B48FF4B633E2D666B561827F8013429956D3F5947FBB848B3A511452870D00BE30610D0ACC418F8536686ABF66851707D89FCBF65959BA3062F6A16E268488D04BE4E370C4247947FA823B27133ADA76DB58CF3ED1109CE433CA0042CDB809AA1B5D5E9C4258C6067B0004A905786473A0CA4B3E9D90443891A148407A8D89121379A1F37C70770586365A74FFE5C6FF170791681E5CE10BB88BC0BCCA82CFC81424AA5BDA072D1BB5BC62F6687A05A949C2B04005284FBA8ED0646A394658A5868304C42C05605E9292801630129C76A1FC083DC3696DC4E904BB1916BA2287DC37232AE2C962108F245C3A0B702F53271F6BB00363D88690A7BF37B345ACEB5426F34BCD7670ACF15955401A20F938A4407E00D8008C147DA00C080A226F71F15DD8DA20D0C6AFEE431B6B2733513BC877F5545753305E8C03FAEA935C183BFC1C40561B59FE80956CE2C5BD3C28F2248249E2A0527891B3B64BF0EB89938A42008C32D668054E508871012FE8653473FB70CAFA0A8F1A509948A2A967CECFC7B5DAE34E166086433C5977208C45D97B24238E875A790C2779974B4721F573C03C4D20777F1C4589227765E8E7AFD0D59EDDDC722CC6230356B477C490234CAF858893F0E446727CC88E1411242344DAC6AE6C2CC1D2B1AF2B8C32BCFB253013411F18693ACAB9A7A86CA5590964D39A8A50768718BD948566A2822206226020165965F7B68871AAFD3474FA306A2DC31A98C60FD2E5AAA8A0B72BDD2F70D6D5DEDE7D679758D8A325B6CF11E7922902ACD92A3A8CB43863CE98", + "dk": "D261A4F71B7248868BE7C32F8AC688174747FA519CC3A4A5D757C3D1E7641893849AE969D8F8A6B553A1CDBA41D46B74ED9B8C8C19409D3AC3664226BC74AD96A74221C086BD3A0BACD66438239E0A8B7EADDC72ED7A453C6B7570B4C763D84883D788D8F8A080972A0635AA563842526327AACC510688B648231B4AD019B3CB9ED6F161673A6C13A6CC850A6C5692B5A3150D2A4805C0875028217DE1058132E68A97501C97AB81DC229F5804079DA5A7F353A1B999BBFE63BD9A4A4B6BC212BCC5B4AFA795C6D25541A522E3BC4FF86841AC12034D9553504217E7DB127504682046604401381FBBC08DEA12095AB71C882FE01BB95B7723F3CB196E1B8917639FC74007845A1FEDFB890F096A13E281D66B9CFAA22A93C8CEC9C9393C2BC81395B37C001D56C659D3C541AA97133D09CDB4758F148966EDD675999248CB786BBCF2A15138165016114F5ABB9BE105D8BB8A3DE8835C85A28B3C49E0C928B89512F4E380F371882C745056899B2FE465DA9130D478C46B2B4075B487AFB96DE727B88A83962B8B99D42C89CEDB5C4369BE78F7737F721AF0645263709E2DE0CE96C0CEEBA76DAAEA7757077905DA5F75D932C965C844C91F09381147C021549783A47609111965C619AA7540881F281633607F7B9983E0E2B7AD011E41CB5BBC186B4BE084CFA136B5E01B36328416C997D87376EFCC277C5AABE703C0E70C741D1809A0A36DADE7BC5111B1F046AD63449BD1C149B1C47FC18C091CF430C377A8AB0A92C9249FBBD106E7A060A4B252E1ACA050941A1AE333F2C3651F27B2CBA7C5CDDC86F0519B9F485ED563CA9E5773F72742877109006D8E9A3B49712612B5B94115024632AA0FE39A8F527891E03C97FF2C57EA532DA594C73C3B03151376702C21B6191826E7BC42DCC5D9CA2295165A85B4981D311AD1E84DB1E0249933AC134796D84166E335C478A46D1AD893325256620B2E60FC9D71832685D406C2AA13D3A614A10410A27876B1F6CEA13A88CF401242665B9051C137802A63991D82733801FA5611131D2CC745481253FBA4788E520CA165AF49E6AB6BD59B10C95CE5911B73745383D91A9E99620FB9862DF06FC248AE44C43D042A7ECF21B6E70A32660377651A24A486AB48598D1D55AB858ACDC7007D98B66D74B368BB03AA4992CA32D2483BC67050F2A302D0133F31071F3CC286A09CEB2139320B496A607B2B36B07A245E90F3850CAA8F9823AF2CA6B537439C861737348765A988256C597370954B02F44244AB15A9F78BBE9C7908701E4571B384A3147D8A4ABB0256D3E45DB5057AB156A4B6405085D31D8A602ACF6280C0E9CFDFF756A0EC3D43C65FB70867B09CBB596206E0E3C14B62188DE815544247A10122788884C3103BE557877698708236BC2363BE9C0424A0930CA63922174C3AA2585B53784D2362B25EAB9AC55AA866C8CA59A7859006937D206D6FD1AC4F80BC1C433F4A67BCAAC05221385A70042AA011104C56037FE0875E2C86BDF384772600EF391E8DF30AE370CC792569D7A5213A6C7866DB65A196652F0C699E4C57ADB90AF0498D33CBB1C6969659C22C3A2596FBAB175C992530776CB8A6463D37CD70E89E075506AF98338A682D431CA0E17775EB170E3742ABEA300D6A46C567C364DE8939831695C59BB7686729C9001E25A85FE926CC6E584E2BC86D3B25BC9D6ABB97EB7F15AC23656B3185CBAFE0C39FA0789DF0678FBF5A43E6E0C53EC38076572D9D84B1ABE742E2F6C0C8CB08CDCACD23B71D57D06708F32D50870D9D636DF1DC01A8378A211A134BB255DDDC0B62C75812AB1677C50DF56B1FF62024FD722D3E732F56A2C6EA10CC31F280ABC8347788CB291AC5A1820525B9A33A7089DD689962A046B652AD182639278279EB884163E2B115A29A3899CB0EDB4514A0836BFB8A51D834C1939B8DC108B6138FB88B9199DCA5F7F64AFF36B9296613F891265778C7963C3E702B81C54834469AC8B59920BEE7878F01052B77B0F54B6DC61AA3DE695D20786F7D309C3B16A8D2C90A921CC317E91C015AC80DB106D4810EBBF2C5A1530506AB1E28B7A32BF67A6981185F98B44CABCF6706B134B5537DC697D16AC003808119B0BF94C84BF569422C8BCFF834237B902D83BC4C16F5CDFBBA5CDAF0A69FC87DDC885DD3AAA852342C1EB8179756087C678EAE2878A777655FC19719593FF600789ACC6322018791874D33D9284EA512AF1231D4CC87F1BA6F6293A653036E590A892F101CC518110C984AC55C2931C976828283F0266609A45A8C7CBF8C23CA0279B133A38F9DC797D5E58011096D45441F11DC59AB5B66846A87059314FDC64E8CF50040B57432A18F46078AF5A6132B006856604CE009128FC5445BCB6891E91A8677060F39A2CAAA183FB8A0F6751051AB85474A539A4183A4486471418FDBEBCF40055AC46075C3B2190248A8202431DB828B82E1320DBA47A23A94DE5CC378B48FF4B633E2D666B561827F8013429956D3F5947FBB848B3A511452870D00BE30610D0ACC418F8536686ABF66851707D89FCBF65959BA3062F6A16E268488D04BE4E370C4247947FA823B27133ADA76DB58CF3ED1109CE433CA0042CDB809AA1B5D5E9C4258C6067B0004A905786473A0CA4B3E9D90443891A148407A8D89121379A1F37C70770586365A74FFE5C6FF170791681E5CE10BB88BC0BCCA82CFC81424AA5BDA072D1BB5BC62F6687A05A949C2B04005284FBA8ED0646A394658A5868304C42C05605E9292801630129C76A1FC083DC3696DC4E904BB1916BA2287DC37232AE2C962108F245C3A0B702F53271F6BB00363D88690A7BF37B345ACEB5426F34BCD7670ACF15955401A20F938A4407E00D8008C147DA00C080A226F71F15DD8DA20D0C6AFEE431B6B2733513BC877F5545753305E8C03FAEA935C183BFC1C40561B59FE80956CE2C5BD3C28F2248249E2A0527891B3B64BF0EB89938A42008C32D668054E508871012FE8653473FB70CAFA0A8F1A509948A2A967CECFC7B5DAE34E166086433C5977208C45D97B24238E875A790C2779974B4721F573C03C4D20777F1C4589227765E8E7AFD0D59EDDDC722CC6230356B477C490234CAF858893F0E446727CC88E1411242344DAC6AE6C2CC1D2B1AF2B8C32BCFB253013411F18693ACAB9A7A86CA5590964D39A8A50768718BD948566A2822206226020165965F7B68871AAFD3474FA306A2DC31A98C60FD2E5AAA8A0B72BDD2F70D6D5DEDE7D679758D8A325B6CF11E7922902ACD92A3A8CB43863CE98D74B9CCDA4F1119680B65475539C5D6AD9CC013C32F7DC34DD644E17FD8FCE117743372B043D1C0784B22FE9852E14D43E7A05A19D7FBDEF102AB9743822A129", + "c": "36A6244DF4F7569DCCA35691306D2E1CE906993034093AA928CA368540FD0D1787051D491033CFFCC6805520137FD271585D651FD67D6C4B9D9BDE958892705DF8A8D2C55C426B6ADEA1F187732579DA8F922D881994BE04A1CFF591F669019FC4AF9411FA61BD3DD88073F8E119C67BAEFCD221DE8230E8B6D7D4D739AD28A1F6B2C9FCE301DB55CAC39778FCDDD389A44DADCF65513AA05853A88D472A7E46319CAB47E3AF09913623360E1ACC954BA17AACB84486F81B0FB34AA3966F6796293EB7F4233052BAD3BD2EC9B1CE1079D8A5C0F9B795C9113EA865F62F1103260ABF902A5D6497BA7F74D1F0E5B2CF564D5B3ED6E6D6AD186F07B62FAB78577CCBCFE6A2DA803E9199785EADA1B6675B6846535FA157166713D37A55C8A99AF87A4038B2225C3E55DD21557238C96226D618979A57204F9EA5447A57106EE6E6E8211C30CAFCCB709B3CFB42B3F4A538F29671578B66F406FC5A6AB274219A58629DE5F84C55AB1D8C39077A42342A1A220C65D5AA8BBB0097E3AF13A03166823474F0798D4D0B36C8EE7C2F71C665D49AAF9CFAB1E72E69783347AA4416055DB68DD30B31C604799D970430209A4F73E70ED3F8FF056A8C9E9F8064766A3CC31304DF31AF27BC6A5AA9BB6143483A89DA5F376EFFD539CF90BF120E8D8E2F5753F99D9415D27E79FC888907325E45316CF5975D717690DE4D587B4539CB36008C127205650865376B78FC07CF7F5B2EC247553A116E386307570913C423F6713875D532EBD576B440E47732FFEEFA7EFA76F29ED763C088183C08471AEB47CDE561D01FC41D063C41BE58BBBAE2EF0C1DBEA24C20FB789697836E0BD63FE39F914278C75BF6CB1C8B1A73F67913D56DFF3451834CCF02B57411DDAB251AEE7D939DEDA1F3CA918B76F6757241E97F068F8D4024731258CFCFBB5CAB90DB10337D2FE85BA4139A329B1BC44DFE1D26D36CDD7E43A62DDDB749098AA2F403659EE15356FDF8C23FECCD02482851310BB702031E126D1D9AF109B6F2B452F65B685C85A67E97D4658FC7D551286AEA960FF348D47F81583B94032D1F0AB71997077F8D119AFD039B3D4DAF678A9EE0F23422B90F6898E39E8F42C6A3B2D7BCA38364EA6BDD2277A8FE32AECDDD4C2822F78B3E0B7DBB0250126D4A8F813EF6B6471EECB3B48753439D099E2B43FD315A259A5757D0DFFF298ACCB6EAB59C964AE7FDD3FA35630FC7E72CF9D538F226916BC11250B36C24DDE8404A5F4FA684321713E57AC84CFB0F1DFB813102E77ABA2D5D77F789CCDC760F75DBF26827FD5833BC42C9EB86AB9B1C2E4DE4E4D5D257170D20D8673FB0E4795FDB5DAC063EA801AC14E67C8E98F3DBEF3F3A0059CBCEF321AB5A288A4BC9B093F0FB958CFD8694E6DD9BD3F37344A9454AC4F86D1CC5959CB6714DAF0116338479B99F251D5C2C8965F3CF1B4966348E1102972AF4FA858B09F9173A72A1ECC911ECA8B578BAEE37F7413D821655F3A207B6DBFBB7FD7974EAC6C9923DE8F65F3A4F8321D16B34", + "k": "4EF33F2E08DB26B11979F95FF6C624B4168CE9055FD31390EDFAAD5E2DABA6A8", + "m": "119BC36B5F856C0A2F136B3EE42041B817125A600E829FF6B4B402131A26ABF1", + "reason": "no modification" + }, + { + "tcId": 34, + "deferred": false, + "ek": "463B553102898CA297E0C205F3C9582273ACFBDB13BEC53341BBB6724C774C741ABB16B2F992C878114FAF67C248603D8AD5842E7230E59B7537119B204AA8B2E0830CA3511886AC5280242A9A817D9A8C7EC8B95DE23254174D1F507129BAA49CAC9C6800CD1039BA2F6625584B8F3AB27657E6B7BA2A58080591D572C7E0B5ABCBA3BABF0525736ACA427A1F13245426C08DCAC5752891169B1A8373B4BEA8A49DAC3B8163E78E74195E8AB54007534133C02AD1930DD3CB066E7114DBF4CC9545C3616B1895469A1E08A57273B235874AEEB32EA3433DBE8732B871B4D0E3192ADC30AC002E4B82798E0C9AF004973F5749456605B897C5AA9938C38343B3690160615B3406AFC6FA20D04AA0214B9C224AC7E64A6E85F38AAC01632A501A6CA1A4D3E0ABAE384AA2A50911E8BFE945792C9283F9A898A1CB2E2934550E3CC52E9BB4C2EC125F64C28B0B12E0805A031824F423B7CFD9A11086523F1305E4C130C17161AFF366472875645BC8A1B14DBB104494C746F84B4599C07FF4E74A3A1408CC983CC2C6CC34BA04333659C1F960E06B73257C5EAD5B3406D70C3DCA05B9EB1E0EAA89EFF046B58471FB7268BDB6402174BF03F92D4D22C7F204A35AC6551455603D8382CA3AC726C1BA3ECB5D4244BC62F10989B4B9851C4346DBCDB959516CC260CE2599EB1232CFD65FDF39AE7EB0763AE47A359367A7720D02B07A5A634DBDF74F4AD589EE2691BB4862D06B6836F70BA8C582F3A7996BD7BECB998CB1AB1564C812AD04920B9121139817E8F06172B217481C379E2C368C0A12194195A03177A822C76B0C7C79AB700FD5C24EFB24BF29139F4930E6515E7A1880D971644ACA12E4278AD22CB96370AE09614D96CC0328265F27E2B2D60465C8A370736632257B191B72185DA1A2E6FAA6759580C6E51E6290B76944C2A8743610424DCAB89CC9B79AFEC512DF9CC5B4807B0C93A889F872D1D8950CB4B371335718035709F36710647157141E6F596FF677B132352D3C35389903375999B2A0D460CF16A581C3CE5A057DF42051A7BA167D6647BD683290ABBEB3E67277C055C5E70674555B98D365442BB8D2859FE47C1309178537E78DA79B7016890C94864328CACF327746D0E32D65D9C7C0574FA5BA9E1FBBA72D990C62E1AD74759BAD3B7F9759B334B10EC8A1AC3D8453783A621C898C99945195928445D21B6F40215724919C3959D77731C2ECB171489AF6F545C7055D55778CADD250DF49913A7769D14774D87940D9C0C53969BB2AA151E063CF78CC541EF643AD7C916B961983983F886C7D7B6A016391C6B9C64E95A03FD1F65B6C924B2353678D3079676C25E236745955CE5A9500BDE96A1287B6A795B3382B438E64C588878CE447530D174B53641416E328E428BBC347AAD32342C0F17D1EA15FBE147E3D0009C1CA0C0E5A437F1708A602026F0252BBEA8B7C70445A456678E0777994C021F61A8C689DCDA40BB196512C8C53FC3B0EC26B3E2474419AD79EBFA58087AC8987BC15C802028ADBCFB37722B0999F6EF71629AC2966FAB95A5A2D3F74300FE668F9D912F8815561C53E1BD24455E58FF3F7BFBC2207D7966B1414CD0D695C5BABA93618A89F32CF29B33FE97EE961F5DF14FDCCD0E81878F6C76D5651730F6456DB0938BF", + "dk": "ACE60FD2C1783948CE064702818B3CD0DC8151C34BFE02B16DBA87042A58A26286E6E20D990C478CCA9A56F729F5F34AD28A85FAA71F8B89C6D188539685BD873C76902229D0C982039A5B95DA6A91C7883E1AA82C81834169C74B45A021C04A4FE665EFB41CD07B660D9478D6F831A9BC70ABD757D7BA3790E559625186C197CE99E6979640A60DA017FCC83351D955F03A32B9234CA6CB226331C5F5A342506422E3C099FF702444659BCE0BAEBA2194C8089284F8A218C903B368C563B6A05557402D30BC73EB91B6B2A5626664E34C44B4A04BCA0187B7C733FDF4BF02A84A513753261646B01BC4F333BA66EB4D710B6884A26D2AFB3032C5474E741940F556D9F963B97BAD3715B6002C941833C8216B220600B57A2544AD497D5E5029E0A0148146755F0A72E1205AB7FCA58E31256C44178F8309F6A81FE9FB083F019D1C4407BAC85EF6264B72531C3BD5A5F270A68884841E190667759CA884478F3A641F798057DA702B998ED17C18D099B71986045A7B5163D72C40225B0BEB48943B444477B56EBABF34877501F94477CC6582B9025395B387E23D41321D225065DDB933E2CB0C1C35A927619BE10217DEBA2A812A15AE83AE46C9B22F03C65C73B108E571302CCC7922AB500C3525F34B572946309C7FAEC5930122772377BCB1B9990C3B1DBB19051FC4805BE809B63A67B5D9096F7693E78762E4640A2C55C8A4957C8B1130A3C464F2B67AAED0191145944887CAAE29C4595C7FE9B4630706968A6B8AB79AAB481A31C1C02E2C46A43CD69D7F5CA1CDA7AFA185AECE69AFAC3156D7F1470C26B812C7453DC724B94A809B94A6880C02DE987247EB777D451645689969F1450906B82949273A216D60C757E470A9C6C6415A8051B33049B6E82885A78A12FA4375A323A686CADF08C5AE52699F6383C1F6B27C558F915B0D2261927B3C24BBD19097A19A6C905544FB664BD766074B31C870140B8840B1E73F63A68D6A876C40EB80EA96563A469423206929DB169BC80B749A1AB26C9EA4AC44B2AC611C51910B9300636570D79C362FF2571404622E6510AB1B9E6B2530E9E420D423579B5802BE18913F8CC06F3789E74C69DF8C80FF451EE84603868523581438CFB9959A83BA0C9A6C5A629E97C867955B84BAEC4FA36597BC2999AF7638D10BA3F6B68C3DBA1F5828B234CA83B2F14C9B7281FDE8B7A318A00D1A3E87DB04A94091F1D0A326858AB8BB54B1F27BDA8BA3E7C75C48B03386A06903487CA830517369120B8103E86809286C92E6033D37F5C6918139B8CBBFEFA9871B5934C16B6441635E7C478C010A554BD4CBBE119C4B77062BE49F0FC301D4D6394AF0C5518325C9C327E8E001FFB78D157940468AAC6B8BAA38A20A11F439DE402DEE5856A5866EA6A9B2FF549AB040B3F4B43772F89F66138B543A644E6B337850A09D7A747827473406A82973479C1700CF72B39C813F8EB51B4DD04B13FB9D945C42BCE147E56074F30485F800C63510B634C08BEA128AFCA6B4EF543724CB6CABC6B160DB957490816BC8C33122C2923B78FD87BBE1453C7DA562F185289C56017CA572DAC0AA2865499FC0322DA35EDD7919FD9A20D2D9C1D1586C8E5205463B553102898CA297E0C205F3C9582273ACFBDB13BEC53341BBB6724C774C741ABB16B2F992C878114FAF67C248603D8AD5842E7230E59B7537119B204AA8B2E0830CA3511886AC5280242A9A817D9A8C7EC8B95DE23254174D1F507129BAA49CAC9C6800CD1039BA2F6625584B8F3AB27657E6B7BA2A58080591D572C7E0B5ABCBA3BABF0525736ACA427A1F13245426C08DCAC5752891169B1A8373B4BEA8A49DAC3B8163E78E74195E8AB54007534133C02AD1930DD3CB066E7114DBF4CC9545C3616B1895469A1E08A57273B235874AEEB32EA3433DBE8732B871B4D0E3192ADC30AC002E4B82798E0C9AF004973F5749456605B897C5AA9938C38343B3690160615B3406AFC6FA20D04AA0214B9C224AC7E64A6E85F38AAC01632A501A6CA1A4D3E0ABAE384AA2A50911E8BFE945792C9283F9A898A1CB2E2934550E3CC52E9BB4C2EC125F64C28B0B12E0805A031824F423B7CFD9A11086523F1305E4C130C17161AFF366472875645BC8A1B14DBB104494C746F84B4599C07FF4E74A3A1408CC983CC2C6CC34BA04333659C1F960E06B73257C5EAD5B3406D70C3DCA05B9EB1E0EAA89EFF046B58471FB7268BDB6402174BF03F92D4D22C7F204A35AC6551455603D8382CA3AC726C1BA3ECB5D4244BC62F10989B4B9851C4346DBCDB959516CC260CE2599EB1232CFD65FDF39AE7EB0763AE47A359367A7720D02B07A5A634DBDF74F4AD589EE2691BB4862D06B6836F70BA8C582F3A7996BD7BECB998CB1AB1564C812AD04920B9121139817E8F06172B217481C379E2C368C0A12194195A03177A822C76B0C7C79AB700FD5C24EFB24BF29139F4930E6515E7A1880D971644ACA12E4278AD22CB96370AE09614D96CC0328265F27E2B2D60465C8A370736632257B191B72185DA1A2E6FAA6759580C6E51E6290B76944C2A8743610424DCAB89CC9B79AFEC512DF9CC5B4807B0C93A889F872D1D8950CB4B371335718035709F36710647157141E6F596FF677B132352D3C35389903375999B2A0D460CF16A581C3CE5A057DF42051A7BA167D6647BD683290ABBEB3E67277C055C5E70674555B98D365442BB8D2859FE47C1309178537E78DA79B7016890C94864328CACF327746D0E32D65D9C7C0574FA5BA9E1FBBA72D990C62E1AD74759BAD3B7F9759B334B10EC8A1AC3D8453783A621C898C99945195928445D21B6F40215724919C3959D77731C2ECB171489AF6F545C7055D55778CADD250DF49913A7769D14774D87940D9C0C53969BB2AA151E063CF78CC541EF643AD7C916B961983983F886C7D7B6A016391C6B9C64E95A03FD1F65B6C924B2353678D3079676C25E236745955CE5A9500BDE96A1287B6A795B3382B438E64C588878CE447530D174B53641416E328E428BBC347AAD32342C0F17D1EA15FBE147E3D0009C1CA0C0E5A437F1708A602026F0252BBEA8B7C70445A456678E0777994C021F61A8C689DCDA40BB196512C8C53FC3B0EC26B3E2474419AD79EBFA58087AC8987BC15C802028ADBCFB37722B0999F6EF71629AC2966FAB95A5A2D3F74300FE668F9D912F8815561C53E1BD24455E58FF3F7BFBC2207D7966B1414CD0D695C5BABA93618A89F32CF29B33FE97EE961F5DF14FDCCD0E81878F6C76D5651730F6456DB0938BF885E38C95A03788929E70D0A17C2D4E23764EF31D826BD4E78F114E7D8F056B2C07BD30B423B29EC3F26A36A916A247C45D1C67392F267A9C3CF0AE0B2F75A56", + "c": "434A4E54F4450AF0673AE77E391B9C25BE63AF58D3F65507AFCC28E6C17B8238585085E39D89280C7F8BF73948AD6A543F9A5A73D3EFDC039F654EDFAD6B4216D60E121EE433C9A347DF67792F8C99169066AD7E5B19A3F4236C240C506887E2F98EC51C565940249D992006D04CA1391A433A43EE2C8EDA8C54D4B731A1570FCDC0AEFF0837D42827D2570AF1A9FA900445F51FCC482F0AC088DE5D4DA40015535EFB350A8797F62DB7DB8DAA0B96ECF6DA3024EF80520533C6E394A197BFB22E91A38E7F6A7CD7FCB4A7A78C9510144D42E94C3AC8B2F0F6914C11078720D3B9B848E6BC211D56447D2FC7F20F59F4C5A72716176CF2274CD82DF2FB2BB0E634AA0EFE9D4EED10C790B14754A54AC295BBCF4DF1A129987EAEDB0DA0FE3931888C9F0EAFD5399BD91A6036B7169C788FAF63FF8ED16DD3A92E8040FFFCB6487DC15B734297FCA279155F365C9AFFEE13EB303B05C52F6365D8F64D61EBCFCE6076458D80E97D325C12B1B9FAF46D8B078DB977963DE5DD75A353C1E7FBD9A1EFA97A6F10AA77B65FF0FD699D2118D6A9ED13499BA2FD10AE9513F1417F6BA75448D7490CA487241CDD2D3300677695095EA755495F6327E92257FA9E29A39793F4E9B8CF6E43E0E1D6EB4620B523E79917C0C328C3A0C55ED76B16191AC58325C32FF4E6E4FA570F2F8174C2F21A9A6B8B1E82E2F7E0388CF7BA95AF70C7F0884C4D2876C3C6E479510520D62DA9D49F435026A401CA1E5E6D5F0DF062CD34C8478336BEB3073D38EA7F37ECC969545DD503F4C10FBDEB112C947EA8CA38A180BE6E3CE1095BCE75EAC5BAB6C436784E83DC03A9CAF1D90DED7784D97F141E642334FD2B51D957224278948CADE3885003777031CCAF8BF81D40C9EBD7127CF4AA9FD983A2F8209EB7C8F27360123EFAFA1A5ECC2B5C07CC4F1F6F5268BF0655C9AF176E0D6913BB5A2886D74DC727C8B72AF1721A4F75B0C54A76365B87367EBB38B7B294B8F75019A2C96E1C5D62E782E903B7A772589410A84857F565939018612EE18E81D535C8435273E5ED6ED28FF4CE7734D643501EC0330F3C46A11F8E17A2E8041D4E0F0F01B7B865ADCF440B7313ECC1C1D5E956AB82783D89A635BDBF7CCE80EF21D3151A80A83FA01DA706394592140E882B8F86A36D58BBFFCC897F5B6A26B1AEBDA91B56EE668EACE53E6DE716939B8FEDDF0133849DAFD340B3B658778CD9F6E7BFA550463903E46C9BE92EA6B6AA6327BD197EEAB7F8DA8FD7CB0E1C4A4FF5D4EBA425D647353549C853621D4B617CF2301CD6D2F2BBEBEF733D7C403F3EBA5F3FA504EBA0069C4CBD4E017F2A0F15750D89F1A0D129806C6466350F87F3939593DF02F211A2096EAB5C917320FE98173D66DCC57EC74500FDEA7A56D011C32D60007D2F416FD1971AB61F2BCF075831F094BA7F75F4DF07525D747E4A313F9388465AA0A9448F75DE2524DD4012A4161982B927F743B5813F35120EA5BCA90551DD3ABEADCC9AA7238B115DA518464E51526F213D4555", + "k": "A2F646AC5A87355FBFE9A37E58F405420221E523844C9D00AB089EFA0FABF280", + "m": "697CC7445AE2C9ECCA2569B7871F0BBB364E63E4B782F734FAFED4FE33E4AF14", + "reason": "no modification" + }, + { + "tcId": 35, + "deferred": false, + "ek": "0387B2D669850AD9379CA70B3EF1BBFD487214F08616824787C4506C83740BE76CBE452CF99369CA80674D3B22D3E04FF95093BD00369BDC5C8126133C5A15B8A99A912132B19C275489B7914858E806CF4CB10D3FF33E018CA8776A88FA30C8782179D289132E0CA4A1BB19463571BE1977109C2BBE4C9433D6986AF12E7079C4B5783390C95C8468545F48A5D669CC0567CDBAC54420DAB1DA63456C692678105E08A822D0F99584D7A8BC76CD9038C2768663FA11A8D8E7B86BA52DD21B323EC22AC2E7B921216282233039546803D509FFB12BA2FB7D3FD38F4B06B848233BC90C2ED68AC41FF24C6425C6C9321A7B697BA5588B434B1B5A49CBB9FC479BE68257498A05865A7A0217B8319E7BB8B55C15967319CC510147BE9BA5511A967CAA2102C6A41298C0F7620E626693E976318E6A7635536B2CAC9DDDFA58E2382401AC778D145774494D2F476F43E0C3AEE004D360C4A65571BA02C7DA13002661B4838B22B9378F34579F46653A30A88BB501B325956B0B5A261174360F128850908B5A3CCDB5B611CAA26773368B13330C48C6667BB351A2AAACEC4B2A2C70601513CC3A18B5B1DC421C5A056D1645FE9312507AA1D52929AC289F6D75269BA42061D556243B34C638A72DEAB939B496435951C53B22095906C68B1299A288D5F5CCB8762E76477C5A0611EB468ADA9073C79B09E80621CA9C4D69A7146A812133B9637F074586A5BFF4AAB6CD0140B43A1B6E2ABEE7AC50489B9E5270A93541CE03B72C00A26E274A7CD3793334CC04E9285FDA673E0241BB9C9A34AB7935508739E52A29F22CBB9664251C6068FD3842C80B17A0C1772F285525B22C65AC1DCD520217DB5715381C9A663DB0E512B9F9711537BEF235313DC46B758839321341E95348A75972A7FB1DBFB183910A442E985628843B93505534C63C8D8A5358B61D7353C2D174AA1416677172ABC66725E7317ECC83BFF257819790C9F9C506DBFC647DB27BD9747673F666D1239845744BE742BB27067BEC53437D48A528F3221D60C3E1EB00D87045D050BEBCC2B433F2BB2962B0E2E70FF0CC52A5BA7412E39194AA226872184108C4FBC459090C59E4A27FA4823ED8B3CD3C59C2CC6A81D3017A08234206C3854EB3B75BA441AB8C321C55CC8574A04DF42E201180846982333A92D057C61140874A9A80A46037DC2A3CECD534E9EC39943BB300B1772510B7E8186C2D5B6555584F54E39A2AB6473806B9C9E71ACDC8C15E43A885A4C9B42763766C49DDDB890C8C7B22159DC91865D0E79AB10372A9F45963C59D8C1857CB654B2BDAC0AF0A24A663C71B744DAD1AB68A90462BD79F6BA55376125562A5B1326AABA7C19E593B7D0CC1C8711B8CFE3547A00ACCE1646E766BC03767CF5BFBAD8F08590E2165C7706544DB5A942925070A878D13418D31CED35092F19C197DC2A517967E41898796A51AF8911A1857244C085045677865B125573CA5E24231251243682C6DCEE524088572D2015D9A25691F2532E75907C107323731591BB061D525757540338BE19913323D08A4082239363CE4741C92AA29F8CAF146AF1D277A76BB22CD54663914647532AEFDA02406099A75A63F7F2CA5BEFC74A6724896CAB84D12376744CCB1C6ECB1DCABFD20AAEB88BDBD04AA5A7E2C867B", + "dk": "030C762257832CD05D14B5940C483177EB3ABD152BF255C7E3131FD131867DF38679D2B554B2B397282071344DFFB7729FAB95F893B912D15B3BF43D39A97CBFD50C84D83C0D39AAAC921827981AD5D0001954369C3344FE869EAF7A45332334E4F30A1B94350D7951A0E4549612AD016528E2C94128052A304A87E2E666CB101E2F765ABFF89C17F1823D211C4B4355E1B734BCD42326B1BA24491903063B2CC18ABE453B003389C67590F00046D174C1C8B237A60AC9FC78AC381C11C358B37FF7B791FC1560D493630BBDB3C40CD4556B9E671B36814AB439687CF248B0CC794C491C4DB2066325257B45370F2CC8519071615BC73095CA69834955131ED7826FB9E89E56926615730EF1B6C4538B3253030578F63BEF067C0EB70CC4D08FEF146488988EB2EAB0648CBBCC4C163F129D32318536CC91AE103CE058318A9530AFB73EABC518B59AA546AC64B736167AB41DC27C8BB21912CE011C50EA1C4315A5A480183D9616ADC79EEC86B813D38E449B1FE0BA07038811BCF63C1EF57AE6DC2F58BB522B51C356901501A608D547B2ED4439C420853D1BB62E438CDF4CC179E760CEEB0B35DA53C0606E7AFB4BE14B5ACD9B7DCA6174D990670A8BA5F5D391B22781A051946F6B33B7D098155048515413819A0544058265403F6272B6FE4625A78A0F4196871578A6DD041476D0339049B1D70A2583E6514E089144E32960DBC233CB16CCF5691B8A5A1434B42F9B9C73A7BDFF384CCD952A79C507E5A4552FE2ACC3CBC118974DC0260024951FAB3A8347CA016CC220E1B8CFB22B769258223AF300639C5F3F2387D4B204C802BDAE8179222B4D8626C88E63BB74E33C7D210F34749465991B38844AF6A43BC81BBE232698B8CB8416BB55B385CB23C086ABD92F59B209ECCC9C4F660061309815434C5B27B6B2CA33918B0F97A813A59B007E57AD04B24D31379964D1923B218CC79798EB8AC65489B9F4ACA5097B248D1A25FB5A3C44411CA0195B02E0538A7B9A89EC660F2B796FF39D42A18E7C585A0B737798C75AFE74B1EB8941D10831012841CAB389A1DCBFAEC211F3535C34EC05F07619B883B3EC04A4CFEC19E4670486E57DAF0C086CB0395B537D06BC2955F90684FCB38D17B0AB43A5061659C69A522B2970F5579A6450AD2DC76163B5480F89437F5B46CF74AD6A85961E265F595375B36A2C96C52F80D4246DA29BAAD2A18DDB3E38F3C9C18B8732123299A00F689B1E32C492ED24280992CD5C8B3AC3109405A631C5F49C77D97158F93F7473B263F8B3395276346156FA7044732CB5273B27715228EDA6C53CAC9165AB3325622BFA9941C0F93913CB29D55A1A4C1404C8C8025DB6A80EB95B16E80A0E348D8EF54947E6CCC4C8374EF14284373C83B677D83ABC9B5BC0B7C67AFF0664B0A2786575B0A2A962209335D13B003D013C11C68176B6C3337C920AB063D12331D2D0282BF0B460634A3F823F2EE8776E4088D33651392B7E16BCC44E46345F2414CF175734286A73251C6163C1B3F60AAE7A1A3E478EF5E56AFA7C3391F7B0C4D380A1A60DBA7ACFDA1155975C1FCC7603929247DF2B8040A12D63369B54849A52F41B2AA77A32DC867B7304E092110387B2D669850AD9379CA70B3EF1BBFD487214F08616824787C4506C83740BE76CBE452CF99369CA80674D3B22D3E04FF95093BD00369BDC5C8126133C5A15B8A99A912132B19C275489B7914858E806CF4CB10D3FF33E018CA8776A88FA30C8782179D289132E0CA4A1BB19463571BE1977109C2BBE4C9433D6986AF12E7079C4B5783390C95C8468545F48A5D669CC0567CDBAC54420DAB1DA63456C692678105E08A822D0F99584D7A8BC76CD9038C2768663FA11A8D8E7B86BA52DD21B323EC22AC2E7B921216282233039546803D509FFB12BA2FB7D3FD38F4B06B848233BC90C2ED68AC41FF24C6425C6C9321A7B697BA5588B434B1B5A49CBB9FC479BE68257498A05865A7A0217B8319E7BB8B55C15967319CC510147BE9BA5511A967CAA2102C6A41298C0F7620E626693E976318E6A7635536B2CAC9DDDFA58E2382401AC778D145774494D2F476F43E0C3AEE004D360C4A65571BA02C7DA13002661B4838B22B9378F34579F46653A30A88BB501B325956B0B5A261174360F128850908B5A3CCDB5B611CAA26773368B13330C48C6667BB351A2AAACEC4B2A2C70601513CC3A18B5B1DC421C5A056D1645FE9312507AA1D52929AC289F6D75269BA42061D556243B34C638A72DEAB939B496435951C53B22095906C68B1299A288D5F5CCB8762E76477C5A0611EB468ADA9073C79B09E80621CA9C4D69A7146A812133B9637F074586A5BFF4AAB6CD0140B43A1B6E2ABEE7AC50489B9E5270A93541CE03B72C00A26E274A7CD3793334CC04E9285FDA673E0241BB9C9A34AB7935508739E52A29F22CBB9664251C6068FD3842C80B17A0C1772F285525B22C65AC1DCD520217DB5715381C9A663DB0E512B9F9711537BEF235313DC46B758839321341E95348A75972A7FB1DBFB183910A442E985628843B93505534C63C8D8A5358B61D7353C2D174AA1416677172ABC66725E7317ECC83BFF257819790C9F9C506DBFC647DB27BD9747673F666D1239845744BE742BB27067BEC53437D48A528F3221D60C3E1EB00D87045D050BEBCC2B433F2BB2962B0E2E70FF0CC52A5BA7412E39194AA226872184108C4FBC459090C59E4A27FA4823ED8B3CD3C59C2CC6A81D3017A08234206C3854EB3B75BA441AB8C321C55CC8574A04DF42E201180846982333A92D057C61140874A9A80A46037DC2A3CECD534E9EC39943BB300B1772510B7E8186C2D5B6555584F54E39A2AB6473806B9C9E71ACDC8C15E43A885A4C9B42763766C49DDDB890C8C7B22159DC91865D0E79AB10372A9F45963C59D8C1857CB654B2BDAC0AF0A24A663C71B744DAD1AB68A90462BD79F6BA55376125562A5B1326AABA7C19E593B7D0CC1C8711B8CFE3547A00ACCE1646E766BC03767CF5BFBAD8F08590E2165C7706544DB5A942925070A878D13418D31CED35092F19C197DC2A517967E41898796A51AF8911A1857244C085045677865B125573CA5E24231251243682C6DCEE524088572D2015D9A25691F2532E75907C107323731591BB061D525757540338BE19913323D08A4082239363CE4741C92AA29F8CAF146AF1D277A76BB22CD54663914647532AEFDA02406099A75A63F7F2CA5BEFC74A6724896CAB84D12376744CCB1C6ECB1DCABFD20AAEB88BDBD04AA5A7E2C867B429A81D1EF4BA900CF2342C35E355A429B5480869376869E37EF269561E028999F094D80AFE79A90E314F0064F00819FCA23920F563589055EAFF682CE66C3D3", + "c": "DB1E2920A7C52A79F588F79A711636149E2D0FEE6FBE132DA3F0AD98EA4AEDACA476BEADF3CF1D6DB5337430B833AB4FB4ABB07A0F05A0874E80C3CBE9BF0C044F711444EDCFE6D0F168BB56687CE965D35FDD06E1E4C5E004D2BFB1DE6767BC41D834DABD875A15AAB03F3A0F8155495684F45AAF2A28803F50C994681E1677FF8A960B3864B7E95599FACD1ECB063B54837C0C6F3D3C39C7183601251F6CF3156C8F544D789D28348F2F26513766362D6430AF36216791592C2F496D77BBC5B1793047E7EC5561CD7393AC4A540104745EFC932D744ABFCC302943905BCC00073E19509CBF876699095CC53425B772F8567120C662219A40F3A818E32756806C0A283D949AAB6477BED8C0C4E1E3510FF96C929D4173B38B10E6C93E5B9B98914FBD4809D9B8576FB4B403B199117087668B19799B19E3B830E132F98DDA88ACE8FF3154D92233CFC5FD02186E13DA50AC91C6CA8E1CA486BAE9255A57FDEF5EA7DE7C0703E5093493F8D0E0EE50400EE69AF8EBA22FF27C834033B39E0A48F81E58F5E5A7D801B0BDFD8B57981AF14E7267A3C24F897F97A6CF2A4D2E143707C49B51A234C54EEF76DA73C5681F302E272D195DB2C52A79505387B0B6B0DDDD5022ACE0AB94AE87A3F0B6F1663571EC9F3494163EF107957365778EBA8E0ECAC280DB5197C6E6349DF677D653084013578D2840DC3490D50CB863360ABB5CDA3A2DDE41992FC9805B8D418EB4BEF140F199FABC45039AA26697346C1C4A6D32E8F52D4077E4081BC7355D3E4D8864B98F8B9EF7911EECD44C5F3587827B7E8B8E4870B67491B61104A9442CF662FD0A9BD795FBDD5C364ACD4B40300B60C6225D6B6C4F5994D86B9EA4ADBA280B3781C11ED11F9CDEDCB03BD372DB567279D332C794D3C5CC49A335C4D8E174D25C4EAFF55FC23342EADD9F55E1D180B88EFA835286DFCBE8CA28D14F6E4C900BBF80A693A32D8654FAE9819612A1DD9C3C08C5B5E97F3F8E74ECBDA90E5DD8D661E2C81ABC2BB571F977CF86637F06E0CB5E9EBEB9CBBE8CEA5B223FA6343A7CB7C8F138364E9E4DC4D1D4055DCE415A682EF76DA70679F72527B3E913EF12A28E22F8609BE456638DFF0756BE30CE010262DEBE5B8A1656FD5823705D9AF35666FA6B7B1E43977B0AA229C8343C45B8BAEEC0F0833B1A2462A19E78F4A6B4A909BA41FFA10C2FD8F98FCB0B10E75B1E2EFC54552747105AEF1589E8BB8BA7DC9A2127121FC63F9834F0FFEAF85D87D53FAE1BE362B394A8574701599A8918D855D2F39A798D6A2268C984507D46FF978F1DF46F2752D6D593630459E9ECF827ADD4693CBA0D6A22DA6ECFD6A7A2B9B2448292C850EBB5FE03C0DB452D7F06278D779EBD87FDDFA445A387A2F40D040D9F97DCE88E164A766105D95CF2A91CD85795A09F5299D5C51AD28FED62F4B67186185FD52837691956EF5A116A1C37B6CEE25B59025A319847A4EC9062FA343BFAC0FDF62A9C4FAE854823FA0D8A906632DF5466DAF9D8B631DCA3310C090D9B7E", + "k": "DEC4780793A61DC6222167547E251BEC419B282883B18F9BD06E053DB258C174", + "m": "52CEBDECF06579F4A9351F77CA95B5CEDD034D812F3FB7FB50320CA80E4118D5", + "reason": "no modification" + }, + { + "tcId": 36, + "deferred": false, + "ek": "82DCBC98650A04861DDF15380C8644C6B93F197A5B10702CB944439BF7AAFF090C49E8CA58DC507E5643C17A4D2912BACFB76454D45FD6EACD191910B472463C49B76684777BFA71BC18973677256F649FA6041A6158046F75268E7CB72E8A974EB2CC7DF1B8AB45B0C651BF3D99211C071D55B9443E6A4A65B976962300E5F7325A228A61727D8733C0B3012CC51C2332FC5BEDB05962B771A232B55B4BCB41AC4D85FC6BE5380ECD3259CDE1B809D8B6E67978213798A828540ADB86124B6F137CBEDC4B64E7CCACF78031211A300A79C59508A60A73ABF93580AA64A7E661C282F5C00AD8784B002F5AC79EC4AC85E0290FA861B9D8B30D9E56CB934C6F4CD5C033C7AF7FB55F20C5A11574B3A460C7A3D73376E6CA77AB911CA118C963B97AB675ACAAC6BB73B0080BB5E0261F79E40C0FCA9129A9C118EA705B0BC7A2B45FF06CC15214A807D3521026BFF008024E951AA0752BFEC022CCF92A519B8D1CA910809B63CFA57C341490BC673243B7CC3E2A6AEA2BAD2B885E39738E3973011A67B266C438F2C2C1F63B251558947C00741939278055ACB8569F91110D895B97DC07BACF1389EED1271051CBF6A7B633A47848FB57BEF485993C5462E3B5548B96CD161D58510794CA60951A2A046C8743807619861D37A420DBE94633877134A92180C05B14E10615783C7B32B135428E59311BAAA32FE37A7C35C4390D1185F2931BAD539F08A02198D6450DC55BFEF625E3E209EEF2A7F38074DC681126CBBEE6AA3C974BA8D7ACCBA719292CFA33E4D5094F527BE94AA2231A762CC0970C7C81793471295B9B2A58810952A63B6589B29953C942CE49C87FB7B49B400210FF645C88179FD76BA408DA81C7464E76FCC3329589AA99855564329D8914E34A7B0D02685A92817C28B2B3F8A7A7615BBD569F2DAC20E161077EF46C6FB926ACF3C94DCC9A4B0A27641370B4027AB082896E188BC5CA32BDE911C5D865C87A22207AC35B72B0B8FB342E3A53BF735796F3C8930417CA84CEBDA48FC1E34AF9610F88C18523A4037E3540757162875CB5F82B1718B32EE70A39E5B216220AB3148CB1CCD118CE213F2D5680EBF865AB018631C88FDB6C763C082F59C6CD95156595E22FB0DAACB56341B7645027845813A59DF203104D9C8B1F647BD3537937F59030979463BB63F7C9B69E57CA17491F3618CDD162A9FE1C3F9B326F567C26D1AC6050685FC68A93CF59178BB87EC8D8B703519E60A22702BB5FBCF3BCD6D496B79B65415C175C554298572AAE35437BF899ADAA5C4F513E9F220553093BEBF1769743C6AB0B9FB64703C6305CC64B84CD76B7C8E61429781A822990B698852A3B583AF48C3B22092C513A223110589941D530C8B4CA25CB4361F2001B166C85CF910F006C5B0B71A109AC5986F8264BA26563E69D122644B6348818145CC026B783D917E74C4F46E0C9BF86250F521C21B64D50E910D1F1CAEF4B05F5A50491E9CAC2F3B5CE36407D9937D0E28E47B52AC460103F272642093CC9EB18BAD44AD36B8EEC367F155159ADBA0251F195E52032F1B0514BE83F8DEBCBBFDB5755267E76B028BD07CB8327CD431A7B73D289247210EC905A0529234B2C62C7A66338C1D381C88466B4832204B1B05CD1BF8E0A4693D941A178F62E9E09B74CAD5B", + "dk": "1BE898512189156358E1203AD43B548D039403004E5A5287505054A04B6C9E13B13E76332AF0B500435505D8C9C46B1FD6DABACBF58258479F0459BB13F5977A842AB7102092CB9BF67C3C4524AC2D25608348756529C8CD0652D5E1BCE22A1C8BEA2A72655EBB6A4A25C95A4EB242C760091DA949805A8F16BA7CA0874E01173D873590EBECC87CF79B103096574524B8149BBB9BC4A813AFC20C2D11ABAD8802834A362908480E76E79A3BE55ABEE3336326184E9A7B044603C4A5636EE88FD4974F82511926B95339AC23001B342041735719AF81C23A003C540DD79F34584A025429D477B7B4858FBE4A9D01F5572E8287385C5C69B0223296924EE27BFBA2757D5B11A194803B1094ECF66267411052BC0C021A77C773A940AC08487B90FB33631AAB5D9190AD613C6F360216725505178952CFC63DD5737B1917A63208586E5ABFF7EB03C9B7066B190C03B6CF77048E2D222719D8517E707DA6AB4FE42B4058161F7DEC4145231A6BAA9FB04C638898081543503A5CB7488C77CB0C6D39E45FD793B38B9019D7216C0027A06729854F378C7FFA6BF599A54BD290BAA60A92FB60CFA46BE667C052C176DE9A1C526406566093B4E899E6738C05595FDEB833BC06B3C5014AE6820082566E65AB9F55D915FB3B0B2E560EF2675E34107AE23BC746E23554996DB1AA94A6DBB20A0B43865A9907D644BF46C2F8E5BDCD298BD78A214049A69F650055725174FABE4CD2309A509BA3CC96EC611BD0C6BC5677B95D0B3BF3A51B5BCB06780591B60A0D22291922C27DC9F24C1EEABE27A704463B5F52829DB80CA0EAF917437841C8230526930705EA5CE2BBCD6FEA79F2F196E7CC74A560B13D48C7A2650D5929C08D53168145935C7638103291A5B2518314AFE8819088A25205D17F4ACB5F8080A824874B5DC559597B24E7D706AF510746EA651A3B66137973E163CC96F13E0D631BC696C451470B4145B073360EC034A39421626FF7510C1B88518262D764CE8D342720674B368C8A17F96F992979EFE25272E50402796A2FE59B3AA37EA1E63640B470BD0763D40029CCE3C54024BF33E63A8FE313AB9549E4D32A75C67D21E77D846AC79BEB704ED576C914A866359EA64A548252395E5A873805472C233FFAA6B5766179E0B1CD83098A16971313871762E531C7AB2483A1AF2C19559633B10FE80053504E5584104082C6B8967E86D63025BA11949B6CCC10BB52C93B032936512166099680C83A90E0EBAB162723208AA16E21418010C6C8B79354422695429F382380B08BAE2138C6679958A7711B78362DB5E087BD0459F27AC095031CA024A37ED1624638A7EE4C54A89009888659B2C9779EC4548D0257EA03CE5ED553A4DBC6C8BC7FDB21017EF4353EA450D4B1548BC65E42097B5C86411693260EF44CAB02A008158BCF81CE94388E87BC38E0BC1261544C8670A9CFC954458C02A310BD00DC174C3C1F06326F9A34AC0D2B4D37DA1389D31F83F49E169CBE4A5B742E475CB6609C4CA9B90B584B664741FB97BCDB84A08FC6028317BC03F2C0EA665355E589BB24448F3222976A59426A93E4711072664DDF616D5D5C3971EB03F2D4076399649F11CBF23194208C0D82DCBC98650A04861DDF15380C8644C6B93F197A5B10702CB944439BF7AAFF090C49E8CA58DC507E5643C17A4D2912BACFB76454D45FD6EACD191910B472463C49B76684777BFA71BC18973677256F649FA6041A6158046F75268E7CB72E8A974EB2CC7DF1B8AB45B0C651BF3D99211C071D55B9443E6A4A65B976962300E5F7325A228A61727D8733C0B3012CC51C2332FC5BEDB05962B771A232B55B4BCB41AC4D85FC6BE5380ECD3259CDE1B809D8B6E67978213798A828540ADB86124B6F137CBEDC4B64E7CCACF78031211A300A79C59508A60A73ABF93580AA64A7E661C282F5C00AD8784B002F5AC79EC4AC85E0290FA861B9D8B30D9E56CB934C6F4CD5C033C7AF7FB55F20C5A11574B3A460C7A3D73376E6CA77AB911CA118C963B97AB675ACAAC6BB73B0080BB5E0261F79E40C0FCA9129A9C118EA705B0BC7A2B45FF06CC15214A807D3521026BFF008024E951AA0752BFEC022CCF92A519B8D1CA910809B63CFA57C341490BC673243B7CC3E2A6AEA2BAD2B885E39738E3973011A67B266C438F2C2C1F63B251558947C00741939278055ACB8569F91110D895B97DC07BACF1389EED1271051CBF6A7B633A47848FB57BEF485993C5462E3B5548B96CD161D58510794CA60951A2A046C8743807619861D37A420DBE94633877134A92180C05B14E10615783C7B32B135428E59311BAAA32FE37A7C35C4390D1185F2931BAD539F08A02198D6450DC55BFEF625E3E209EEF2A7F38074DC681126CBBEE6AA3C974BA8D7ACCBA719292CFA33E4D5094F527BE94AA2231A762CC0970C7C81793471295B9B2A58810952A63B6589B29953C942CE49C87FB7B49B400210FF645C88179FD76BA408DA81C7464E76FCC3329589AA99855564329D8914E34A7B0D02685A92817C28B2B3F8A7A7615BBD569F2DAC20E161077EF46C6FB926ACF3C94DCC9A4B0A27641370B4027AB082896E188BC5CA32BDE911C5D865C87A22207AC35B72B0B8FB342E3A53BF735796F3C8930417CA84CEBDA48FC1E34AF9610F88C18523A4037E3540757162875CB5F82B1718B32EE70A39E5B216220AB3148CB1CCD118CE213F2D5680EBF865AB018631C88FDB6C763C082F59C6CD95156595E22FB0DAACB56341B7645027845813A59DF203104D9C8B1F647BD3537937F59030979463BB63F7C9B69E57CA17491F3618CDD162A9FE1C3F9B326F567C26D1AC6050685FC68A93CF59178BB87EC8D8B703519E60A22702BB5FBCF3BCD6D496B79B65415C175C554298572AAE35437BF899ADAA5C4F513E9F220553093BEBF1769743C6AB0B9FB64703C6305CC64B84CD76B7C8E61429781A822990B698852A3B583AF48C3B22092C513A223110589941D530C8B4CA25CB4361F2001B166C85CF910F006C5B0B71A109AC5986F8264BA26563E69D122644B6348818145CC026B783D917E74C4F46E0C9BF86250F521C21B64D50E910D1F1CAEF4B05F5A50491E9CAC2F3B5CE36407D9937D0E28E47B52AC460103F272642093CC9EB18BAD44AD36B8EEC367F155159ADBA0251F195E52032F1B0514BE83F8DEBCBBFDB5755267E76B028BD07CB8327CD431A7B73D289247210EC905A0529234B2C62C7A66338C1D381C88466B4832204B1B05CD1BF8E0A4693D941A178F62E9E09B74CAD5B988AD4B51E1589D3379C6D3E70209E6EA8655AF17EB0907869F974DAB202F540A54A288137BE236A5FCF6A8FBB160B2C2EDCF2F1F63A92F0E985CC634563DB61", + "c": "443DCF704633C6E74255A6E83F0F4BB686BCD9CEFACFC536EC6292A2F4D70C11E4F9FE4A94F4B8E92548EC234FECAFA84BF1372D7858C554BAF1E2556865185C02B0214E950F2C30624E5E42FFD1702CFFC5045F3FAC68E8D2E48063F9402DA21E69E49A1E9AA77DAC5EA1E60ED77E8C498D70FC67782EC17255E0CB7E116DC75168A5FC7C08A2D4A974A71E08A12CE9948A15631A90CE034C04ADF9E99F3B93D5FC4B2C9E880018496F8C92D40181C6A47E313DB9565B377BC3EC2D5ECF0D43A9ACE5EB0439A230DF989A01A662D83C8D2BD7C0A5402ADBFADF91507A8313F1C6B7D705E930182FA10B91FF7359C0D2BF26317015DFF6845E2F4275C76F5CA9F115BF90067E95EA7AA2847F05ED50897F62CC8AE42DAD71C3CDA04AF5FBB756CB7F11C78794F8FC4544D8B3AC1E9B44B545AFDAA2E7C5945E11832DD2D693952F51B87837DA9049D080843D1A4CBF551227822A7B522F449C974925886961E7FE0849790F9B2FF8DF8D0D741E9A1B8B08647810A64D5420BF795E5EA336CA4FAEDD55876E12FA6EEE591AF0F1989D0C1E1CD1252A305467CED0B12766D12316CEDD93FA773B11AA9BDC9D74827C30FE4AAEB456B8AB700D4AF165F13D8A0D8AAF741C445F341628AC4F4254C96063A6986A5851EB19438FE9F633B131029545A2665093F2972678F62EAACEBDF7A49F3D4D67790E4142E2B2A0AA57327ED89A0B9E641CFAD529F61A82ADEABFE7DE1C0D7A99078A8C1E7A00C8CD251B9EB8ED4997508E16AE39B50AF7A132A6AC83031C7E0207E894AED90066CA97F2F616D0C935738D18401B9BC7904424DF5756525EC5D8358EC0B9AD428D0EB195541A93E75D35FADC6B0F8D5CBC8BF15C9F3A7C22BF95A4D864D011D6944BAD207A27E2B05C8C51C6686E9164EACB06D3C675642575739BEC34660A31CC45970C28954297FB37B4C51C4B3337C9725E5A6F1DD0831A8A06B4DF2F445DBF08612AF2D65EF19594C4B3E3F034C5547491EFC3AE9B34A47CB2F35159AA21C097A2FF9CBD66C7A50143DE4F7FF9E4218DFDAF52DAF4040EA17B8F1616E590699FF6C71C37D1386806B2F36E534195460E2774D475052EFE3338B43F8C906D3FC0A736E103FD192B4084F6311F34A2BD162C0B2B9A60EF6F3468E881D7CF56A1455B815F2999934311894F4EAD90DF175E60F56B56C1A2BEF12892563FA216D1C477F061C46DCF2CC056C5E972C5F3018DF6346983163FA7C787EF85BA9979E30AF9CB4C4E2A0F4DFD6EE5B95AC7F8ECFD46E7491B4424C22E82C521F436E4656E298931E3791164360A0502BEAE7654D43C3BCF66B2D69B5E2EDF0CE17961ADCE8A600789E6545AA31FDC12030CCD478C82D1E319F4DFF1681B1209BD867627A443329B48FCD884BD986D105772CA3786CD336366C0DEC0E9469ACDE5FEC612DC24862A7FA00D45EBA7019D237FBA37EA67A4A074C652E6EF910B2C206FBA0DE6D23CF8EFCA947A18737410DCF14E496F64582B06D78FCCD7538232C4D8F122CD9FAB29568B", + "k": "9DC0B2ED91CF4609FFB8F7240D6CD3F65D45105A35770A105B910BD9CC911CD1", + "m": "161889F2E92B1BB28A257B45D179FB76847B664E6D7B5FD9698204A426EE96EC", + "reason": "no modification" + }, + { + "tcId": 37, + "deferred": false, + "ek": "FC964FC0820E5DE7A73BC507469B013F2C81A225C8C067C4A9351467847DC4D38FF3237A9A38A8F7C273B08B260C5A9B20F8493A668459E0BCAC480E0BB50BC62941720283F758B7AB13B444E8A1F8366FB247C3CC339D413671ACDA6354220B9CA0515881A688063FA87487356C842324B35B064B5847A75509AFF086086CAB80DE6C7218D95877313B0663031E867610107F1491A9F069A2DAA4A88F26CD6CB97B43B51FB7156A47550434421024CC360500AA7595BBBA99116057A64A98C76D61082ABC47BBC2614D2B23EEF8A68D1065ABBCC057B2717DBA5D6B82BEC6683551F082C85C3C430580D7125D1EBB1EA410748D6835C5BA080D1140F9574A4460752C5278E5F24DA829235DEACBFC3663FF71421F3B4C3F073764D11C39C9AB6B6B2F1F24A7CC84AA73A976721AA7BBEC515D0A0613D06F80FA461A032A274911B82CCB9B9A4AC86C3555D37A267C54137B141A043E9C861C58D6A88F5A47B895ADDCA736D11CB227D190481B4FDF680943539437B04BA202B21B19C06BC8037B93681E2121E7A49DB8271422834CA4253F5B96AB7E723FDC599B8BF0567C176BC7C754B6402642921ADB8C30CB8329A1E3CCFFC8A501A077E34495D9333B897C41F9E2A11151902A9B19AEE16BD4038DCFA6118192CC3B09523BD89C0DD158B87276A6316DA118785551B9E1078C22949D6D5302EE5945F87C5A8EBB6220B673B8B7AE6499C993633E844BA8A14CCBDFA931D1145BBC260EC933CA2B8B861F505A9691CEB2B5716CDB1E07DC6ECA0693CE0B8BBEACB59F705814F2C46B336C65240BA7791B10226D3892AC60D11F67F29283ECBCB459CADF6867F41847A99A2E0469A417078AD80B1BB35549FEA2164B8B557B5610C64C810E211DB697ADC43034DE45BF407729B9F8CCBE3379D471367DE881E6EC741A4130C78A90FF24C7C3899129038851069BC68B9EB533354AAB155F829F6AEC9EC9D82B20B4927EECC243F014EC846D59D5C8F3517F96873511967408128A1705B834F81C4F1169EA500A66EB21682A09CE44CE4C9541FD506A6AF12CA3634733E4661681871717A560685794685DA121565671B50FE866B0A565B0A9728A97C6AEC4442C498C54D77184C44D919083921204334CB058FC5EA4765C0478104770B743A5093E842C013769F16B02A46083872C58D3D678DCE87A3799381DF117D0F357998C853606692ECC1F087C0883CA575D9159BE882045E60DDBA38ED3BC8660121FB8EB2D6049A5843A2D2A53BD529881799487B30438B4A585B2E77768E87D060C0D676283431A55BA9C129F036751835299D78CD2D85748C246F8915927B1C9A1194BAC1A103B5A1BB69370C685B15AA264C436683ABA9F4A03C49DACC5A1D3CD5C133599EB16006850BAC4108239144CE682B7301EB220A363032FB608137786898375366B002719580EC7F7733BB2C3DE27974FEB56C72AA61252A2D63CB63D380F1FE3142439AD1151B543591AB0915B514B3E97EBA17CCAA73FF0A3459393BAE20B1D8A8961C0615B180DECE602335A11F7617EBCE0A3A0B3AD1A78A3C8C682976388851285D83BA9E358AF22A14039CA015FE1B42F8A3EB454578504153817455045166F24D6DF0071E884AF76ECBBFA430FC31D1F77405F4B404B538725F561884EDA", + "dk": "7F7A7CC42A00986601D7E76792ABC9454422BF39AA4FA93144980345066236F60D629ABA3BB74FA79718F0A95F6434508A9B0F0BC672D4F5152A8561B8674892BBCD79AC8082394DF7E95F7910C8A2945C55DA8D847B5480B34671E20532B03229D51B2D9A3288E867D59A9C189A8686295D2604B048425331700FC329A948236AF5A83E9DE525417BB235604C43B3B2628642CE11B911A2A88038A5FA233555B3104BCBB733E446E9455B9D1A7409357AA19656F23590CA11CE05336B0BE8406DD39CD3B6A725D49A499B1809791540A948D72C56623A768C27A32826744D75871579B85D16695905BC62744885929723F308D4870ABD61B7EC3CAF86D2422D6C53CBF92DACB85AE49622F6E37B96F3BA812B26F0C1220B4C4D37A9BA4032197FD4025FC2C75147534F28CC8258A0314151DED61CB391B17E842FDE96AA3AB89C2C13C6BC015EA2DA00D12877320B4610C34526D31E2C7A981028C2C55BA22479A62F375BA7400AA4076617258C1E5A35650312F75253CCB11B28FA2FCF170FCF9A96C34385EB181C6D777621BB3CF6081A8457A7B92C89F0167B80976CF7512C10E1662DA3018AA9129E3661A59ACD85D75BA9707CECDC23A9FAB2DBD6AD85938DACF56C8FA27C2A7BBB520CBACEEBCDB088B65E47B9687865A231A393D645F080B61BB288C9166976208FAE67B8919766A7910BE02BBFD8586186361740926182A3ACA832B2151B5FB01A0E726650D4E92EDF59BA973446E4C886904919D07A8EB67267AE366D8FF6311C78B6F17193C655B46F51CC47E05B4D3416984CBD2C14AE228B44C1141427876AB6818DE42807FC1723B3BB2266418219004E68B59CA71C5C2B8B8C6D7405A0508D6A63ACC2B4C19E228F943718F18C8C743A020BE75DCC1B1CE1F1793FA52C6AD5CA3D63C871366237DC82F01A837A758D9005CE677C9E1477CF5B49A2427932F971821461593426498DF90AAB257A1683355DAB67FE9234AD2832216AA0A2F4690E0785A08459A2809717DB7A231C3A5D84A98EC91A446B1BEB8851D2A65D7D61569EA98DA56C7A2CA24C71BC511747111FB31CCDA0CB391638BC3126D4427ACD9171D7D2A79AB9815ED62C332ACB36335CED45411D1545E3832B52685D444344C77325F1372E89F254F5E33A1BB450B1A54FFE32CB4811B813E27C12EB95161A5A18105D2D937012070868AB3975D552C056267F0946E1A5C9EB585F170CC5A6A578405382E030A2A3265F468A9911341F7A4746B71C65C090398E4443EC6AB4486BA36788AF0996AF5C6389EB31237CFA0DC8C17132051A28060376A0C133FC51F6EB81BC035501952164504115F8C567B52E96BCA0FE13A2BBCCAF08637AE31BB4C0032EE32514E041C2DC4587684027D988133658414567328F42AEC2FB89B4C830ACE152C326443D82687A19C87D122EEF72C1E742BB4A8C52B81646CB0C487EDB917A122B44751F209489ABD629A0F232D0502DF7A5BF5710215DFCAD13F2B6374535A839CBC9A505EB3A9E8EF17B16B70FE04752C8E1936926BBEE856A188C02183768217293656C4B1E9372B363BC673110255014FAC01ECF6B48371B8E7E401C01E1640B8A4F1C3A4009489FF2D46BFC964FC0820E5DE7A73BC507469B013F2C81A225C8C067C4A9351467847DC4D38FF3237A9A38A8F7C273B08B260C5A9B20F8493A668459E0BCAC480E0BB50BC62941720283F758B7AB13B444E8A1F8366FB247C3CC339D413671ACDA6354220B9CA0515881A688063FA87487356C842324B35B064B5847A75509AFF086086CAB80DE6C7218D95877313B0663031E867610107F1491A9F069A2DAA4A88F26CD6CB97B43B51FB7156A47550434421024CC360500AA7595BBBA99116057A64A98C76D61082ABC47BBC2614D2B23EEF8A68D1065ABBCC057B2717DBA5D6B82BEC6683551F082C85C3C430580D7125D1EBB1EA410748D6835C5BA080D1140F9574A4460752C5278E5F24DA829235DEACBFC3663FF71421F3B4C3F073764D11C39C9AB6B6B2F1F24A7CC84AA73A976721AA7BBEC515D0A0613D06F80FA461A032A274911B82CCB9B9A4AC86C3555D37A267C54137B141A043E9C861C58D6A88F5A47B895ADDCA736D11CB227D190481B4FDF680943539437B04BA202B21B19C06BC8037B93681E2121E7A49DB8271422834CA4253F5B96AB7E723FDC599B8BF0567C176BC7C754B6402642921ADB8C30CB8329A1E3CCFFC8A501A077E34495D9333B897C41F9E2A11151902A9B19AEE16BD4038DCFA6118192CC3B09523BD89C0DD158B87276A6316DA118785551B9E1078C22949D6D5302EE5945F87C5A8EBB6220B673B8B7AE6499C993633E844BA8A14CCBDFA931D1145BBC260EC933CA2B8B861F505A9691CEB2B5716CDB1E07DC6ECA0693CE0B8BBEACB59F705814F2C46B336C65240BA7791B10226D3892AC60D11F67F29283ECBCB459CADF6867F41847A99A2E0469A417078AD80B1BB35549FEA2164B8B557B5610C64C810E211DB697ADC43034DE45BF407729B9F8CCBE3379D471367DE881E6EC741A4130C78A90FF24C7C3899129038851069BC68B9EB533354AAB155F829F6AEC9EC9D82B20B4927EECC243F014EC846D59D5C8F3517F96873511967408128A1705B834F81C4F1169EA500A66EB21682A09CE44CE4C9541FD506A6AF12CA3634733E4661681871717A560685794685DA121565671B50FE866B0A565B0A9728A97C6AEC4442C498C54D77184C44D919083921204334CB058FC5EA4765C0478104770B743A5093E842C013769F16B02A46083872C58D3D678DCE87A3799381DF117D0F357998C853606692ECC1F087C0883CA575D9159BE882045E60DDBA38ED3BC8660121FB8EB2D6049A5843A2D2A53BD529881799487B30438B4A585B2E77768E87D060C0D676283431A55BA9C129F036751835299D78CD2D85748C246F8915927B1C9A1194BAC1A103B5A1BB69370C685B15AA264C436683ABA9F4A03C49DACC5A1D3CD5C133599EB16006850BAC4108239144CE682B7301EB220A363032FB608137786898375366B002719580EC7F7733BB2C3DE27974FEB56C72AA61252A2D63CB63D380F1FE3142439AD1151B543591AB0915B514B3E97EBA17CCAA73FF0A3459393BAE20B1D8A8961C0615B180DECE602335A11F7617EBCE0A3A0B3AD1A78A3C8C682976388851285D83BA9E358AF22A14039CA015FE1B42F8A3EB454578504153817455045166F24D6DF0071E884AF76ECBBFA430FC31D1F77405F4B404B538725F561884EDA1279BE1122713D340A3C86B3CE48C6C5CB5E48522DE5B24AB57F59FC341BE6ECC2F75B1351CDC350BD1726A124C06B996F566FF820A4D3569F634D564EE84224", + "c": "58919FC3F7105957A7599EC0F84E2A1031F42E26DFD7DE44CAC5B99E1272313BB2A6F52B8D33C9054B368439A123AB49E75C7B3FD397F1E6B962126FEB574D0005C69572CCF752B10D9E84569C9BCF3F3550784AA1239E0B4B4FFB38EB5937B287B5C7D8DD0FDBB38E3BDC081B43FB7967E7E35D8FDA89153AEBB7FCD7DD810738A555C653B84F6BD246A17FE2EDD0FFA8AFF151EAB2973F2F8600FDDE69B61D06EC99CC547D4A81896A36BA9A3DC66A5251EF145C9A690B2C696C165FEE89B8C2A14ACF8B5A12CBF2216118FE3B29E2FB0F194D418BCE181B096FFBAA4AA515CD45275459BC5FA6E1D1ED33D00609F11DCDC5247FDFE841E01ABB7B935BCFAF9960E7E06C82463BD27BCDBCC3D12AA0F033BDC4605109AF3D7B270FC5D18C3CFDDEC2CDBB3587DBE25E4B0E9AB2049ACFCDE49874960482CD25DCF45433179A9BB69145DFDECA9AD2D3BA9AFA4B6B8681DED8DEDAD95241557BE198A7CBBBAE937F70D7FC513782258D89AE870FD2411BEE47E4993B9BC1F66852E4D314BD54C848143398278F11776CD8FA01FF345E606A514ECF780AA5EEDD94B7F88C495F8E56FEE7FADE2F6CBD3406FE540428BF89CDF66357A0F5F45DE330D9FAF72F02D41D9BD7B6EC9165C70386824DBA7E2322A0409764FA9DCA366B4A9C1D3E01495806F959D13213471978833CA2BA501C634322E67CBEC59FFA4193E848025BADE1971035636CE8CC833047EACF669FF064772647AF66CBA4C5C87D101C1EB2EAB87A8C3CF31D6C970E846C8B50289DD1572B19705CCA364D2B3090A75AB299749D0A320C2260A686DF569F802FDE0589799BD54BB5FB8873ED15CFCE76CD20954E52BF7B3DBC68B573EC0502F3D6715C249486B5691F91CD11B4A7B3CD1ABB8C942E2426B0AC782B306BAF6C0D9F2E2EF53FA9E142BDDFC4FFC6930084036BE9E51D997C8E24F89556E0CB21BCCCE16330AD104A8C6851B2E6CE8C58613E19459E2C2398C9B33A5FFD19CE5D9624344C52F379AF49F04F1405E9510598622B9C6F88E95DEE43A91C0540661AF86E3016BBC2339C2E922166AA2D6ABF987F1E78EB1E3CA9486380E62577FF487E1E7A4536C7ABE7F8FC9569E254B96BBAE04DE314F7D5C36A388336D53B9BA8667350C7F3A04DA68BCEA28BD95C52D14E1DFBBF78C8CAC150CC15D015E4332FE109E9FDAEB64BC3A400599CA3D2CBD2A720FB35675A5BA78BE61C4A82B4315D3AF4FBB0150592B7EC135E063CD5D7C23CDD256D4501513BA576BD6726878F2B43B64ED0DB79CEAA344365617570A1E7957ACA8F5B5F2FF708190B2A4985A6101CE0475DBD528489F4FDD8A9E4276CBB7E6FCF74866A49B430A666C4DB800DEEEABC4E7AE9DCF6D91C421246F91394B949575CFDCAA8527CB9A4CE58CC1A53C7FB43193FA39E4C12EF8DEC1F1C6CB8134E5938AB23A9CDADB4099498F5F39274F10228FC297EEB7BE6E392F00B092E70B0BC262F5E8720E87C8BE1730E22193290DC1AFA0AD2D98BA6206AB3E7B63FFE6C69D576", + "k": "D8D24017609D9ABA1414D18AD4AC9E14A0954AC1A80AE9F29527351898F61483", + "m": "3349557DA70FF69886ED032A91D8FC23BE9E5245406670679A6E92AED870D369", + "reason": "no modification" + }, + { + "tcId": 38, + "deferred": false, + "ek": "ECEC377523150E39B8E5A4B85F8237A685630EA7A3443A9249D4B90E1BA3438CB095AB5555706EACB3A61D5143029856C7E80B0D9156BDE63AB4632605F6009450B1CFB6B81A58A43687C4DB56BF087A75DF047237E9A9B79408A8369CA3AA1731A7190FF3C11A7699E3F83A1F655B3E2C252D732BEED0703A642BA3500859AC70C51C3DE886C26BAA47EB221074F97FB74957F9C61A02405D2E2B95FE198C2AA24AB3D649A3B6803C3636C03B3E199AC07D103960577738CC833CD42CFF97C55FB4BC577B70D1A8642ABB77A1530ED0F1405B2245347256C0D47005A634C9237420574130F607BE82CD00D81E15562AB8461F681159737ABDA7441F7871AE7B28401A6BAB14412A5BE5A4BDA22A46425B8B51964A673278B873C4F61DD8CC5A7DD3B89E11652C677E052643A32139AB971B5B0061D600440495B96AA3113725640F6A91DA0B4B651630EED446BE53C6C6365BDD2BA0F757CEFE05C1231B666404199937736E6A5FB3466BC4590767C2BFB2041DCF254886466288BB45F8E91BBA876B9C093BE2616BB3D2B516526495E74BD19B1E9C36543697ACDA981687111FD05A1B9F2255E8809152138B983790EFE836DD7A68A8A150513699969015BD65B05D364FBC851E11B506C607BE0CD116910C94A3E3258AD263683462F5826B85B4BB1DD2917B4034AD25210AC26F2355B05681015C9A2BF622BD28431CF2868ED213124F124C7C6797C34952870CCEA4970AF909BE10A57BC7AC37A536B7DE2A8B0C4459A6223B4EB781C2462ED3AA135015754BE56F2B501AFE68022C81C16D40726B8C77B0845209FC4B77B64FF08609C0567390F4C9A8187A15C719FC5C9C01433CA77809D3F9195D8BAA94B24CFD909D6374B8DCD2355D1723400AB552F264C938B4E1E8033BE2A0B6FBA03729B38FA39F285AC01A136C07D10DEF390BEA5688C41B155D81174662AE48766D1791C60F1606BDF9177D995D9167B755908A68E7A7CEE4AF53A42EDB486C8D119FED00BFA643ABEB12666E2CC2295B8336122E7D9601F4DA405B7666EA276A172026264C23863665E2C21FF72A6CE4186016D88F167A358889AC1F8B028CB4622CF07474181BBA6BC5D331088B88A1C185B28B90CBDDD54D88D4A911DB638EF236D6D06EE968B8E5FC11F2D9AEF14A3248EC921FF0ACA4BB1369F7B5B3991ED6B16C3A918FD9397BA4E454FD209567D97C8BFB47558B6AC7726D6C83768E0A64B034C0EB36C8BFB0BB86C52B51FB7DE503C390B97B00A4534206B267C42333B4C05BC90C7FD25609548B2E7087E792BA21E360038A6218872F94035E5F13149CB440B302A591817EB0E229AFF03CE9005535978F930622DD422722C059E0BB855143053F348B23D5ABBD49B7DE9478EBB63380E75F9054922AB65F4E897D02F9AF641CC6A34957B91A7969A1270E4264451053267137ECAB8C8C8B9B76354A63E1ADFDCA087E54A67F8A2DE4AC6A636348017C6203B4A27322167C2ACC85F63335E8AE4D1909DD1C3DD228C0E3B84470446EDDE572F7924DD409764FD98F43A20E5AC15AE9202BC1AB58BADB3D06B6B77E81ADF763836398BBC45433015B6523652751B8292AC51230440C112C6317A66F24C4BF927C7EB8C186C9DA10E1BC25A4DF1CCA9B6C3407955972448DEBDB284B", + "dk": "F8B574AEFA5362C79AA69AC10326288D0571F154CB001C7FBE1C274C1586792068209CB65D70CFFB21947ED752EBE9B7D72502726C1DAA9450FCCCC3A4C4BA0D1890C530C601C18A7001B079684EEA47AC24251E9A599967A24EF47B52B4FC580E995E411237C02687CB38030DE74F3EA0C1740316269322482C64414A8C73230A3B58554C57142F2613D190BAA3142220FC4D99A5806C89785B8730B39C12CBEA94F69573A61999C82B7E4BE3A9B605243D25971E24B330A7A51E5681774AB7120C13DA25ACE8494019192F8CFC3043628F7E6B531F8886AB2BAFA1D39E09CA373AFC1A46919F8244066ED1B7C2124C01D760D216978191BF3573C093A15FEC579D83EB5C6074B0A4BC13094232857181DADACD2C5A4AAD97C016894EB413C2CE671687A875B45CC1BA0C63D9696C4FA102BBE797FDC86634DC28FD121EA9D904642ACFC56C2DACD2A7BEF96A43A23F11591EB81C954182403416ABDA87BB5AA75D510007B8D53491E0BEFD149658AC135D1341FEA37983D1A0EA0B40CE08A2547122C3022AE2DA8E2E7BBE8DF46548A91A50A1C8FE651E8E487788A2AB894B7912B15C10D09571E23589D166C989329B29349CF7A037916B467AB29ED59CCD37AC63C0AF6F335F5FD6BC09845BDEC1C86748BC389889425026E3105DCBDA9E4C5664BC2B75208287EC78B8AB031B6B494B37D51B0F540B4BE0360BA4744DAA369FF384C1D5BEF1640A7C76C7FD4743C7EB631ED126F0408809E00700120CD6DA114C5211521C067F1C7EE001AF1AFB46F7DCB90D70A3A35098946A4EE53629CCB678642A11E18B687C9680FAA3AE926C60A5672A0C786F17273C313548D6894B27D52AB5F51E9623B4B03398FE9014E376040E522178185230456D505BC1026AB91BCCAD5B2C38ED2BB445753F30845A65A816816476BF184CB55714A64375E480CEF74917E616CD50E7AB635A88D96414DA6710E49A468C3AC91B85726536B78C9B93DABB5866998619B377BE0B54C5B6AAD4940156C549782C64653A68FB0B15E02089FBAB37955104BED20696C48E388257375C080C33BDEEA081EA3285F6A94A128736DC221C17A88CB50A6283F4C6684AC0FBF8C110344DCDE703E4A7C3DC49296AA684A31CCC0DBAB7EDDB2EF9C40D35A42D077C62ACD734BAD82E7475833A1527222112739C8591F61D2156BD6BC886FE501873EC67061C3EBEF03427C969647918433088C0C8C7CBACC9CFEABDCA3A91AD17A2F5AC8C9F195D53C294878529B0B9C8D310897C09483B3C46A841CBB6183107154E99E7A91DF44972C7BC7162926C9672ECA74FE155BBBD4160D039821049A8FDDB91C99752B99B34E122173F654CFD5C69DFE7608CC96F7AF1A0B8476FA4B715E8B81F01E24A79565D01005667DC264D31AF87F6777E118EAC48346ABCB281523E97A787194B6A6DE33362F31117958C1D35AB4C190818C0049FCB6B42151C8F038B8018B997CA0E7DD9962B0A62FE38A424C06A4E650E68191C4538AE67B1C3E997627BE3B26BE14166F016A8E80070CA86B034ABCC358B2CE917FCA34CC2850920656E80597A35936B28794C63FA944151C0CAF278CB589F86171D0F263767F294A71B6059E496ECEC377523150E39B8E5A4B85F8237A685630EA7A3443A9249D4B90E1BA3438CB095AB5555706EACB3A61D5143029856C7E80B0D9156BDE63AB4632605F6009450B1CFB6B81A58A43687C4DB56BF087A75DF047237E9A9B79408A8369CA3AA1731A7190FF3C11A7699E3F83A1F655B3E2C252D732BEED0703A642BA3500859AC70C51C3DE886C26BAA47EB221074F97FB74957F9C61A02405D2E2B95FE198C2AA24AB3D649A3B6803C3636C03B3E199AC07D103960577738CC833CD42CFF97C55FB4BC577B70D1A8642ABB77A1530ED0F1405B2245347256C0D47005A634C9237420574130F607BE82CD00D81E15562AB8461F681159737ABDA7441F7871AE7B28401A6BAB14412A5BE5A4BDA22A46425B8B51964A673278B873C4F61DD8CC5A7DD3B89E11652C677E052643A32139AB971B5B0061D600440495B96AA3113725640F6A91DA0B4B651630EED446BE53C6C6365BDD2BA0F757CEFE05C1231B666404199937736E6A5FB3466BC4590767C2BFB2041DCF254886466288BB45F8E91BBA876B9C093BE2616BB3D2B516526495E74BD19B1E9C36543697ACDA981687111FD05A1B9F2255E8809152138B983790EFE836DD7A68A8A150513699969015BD65B05D364FBC851E11B506C607BE0CD116910C94A3E3258AD263683462F5826B85B4BB1DD2917B4034AD25210AC26F2355B05681015C9A2BF622BD28431CF2868ED213124F124C7C6797C34952870CCEA4970AF909BE10A57BC7AC37A536B7DE2A8B0C4459A6223B4EB781C2462ED3AA135015754BE56F2B501AFE68022C81C16D40726B8C77B0845209FC4B77B64FF08609C0567390F4C9A8187A15C719FC5C9C01433CA77809D3F9195D8BAA94B24CFD909D6374B8DCD2355D1723400AB552F264C938B4E1E8033BE2A0B6FBA03729B38FA39F285AC01A136C07D10DEF390BEA5688C41B155D81174662AE48766D1791C60F1606BDF9177D995D9167B755908A68E7A7CEE4AF53A42EDB486C8D119FED00BFA643ABEB12666E2CC2295B8336122E7D9601F4DA405B7666EA276A172026264C23863665E2C21FF72A6CE4186016D88F167A358889AC1F8B028CB4622CF07474181BBA6BC5D331088B88A1C185B28B90CBDDD54D88D4A911DB638EF236D6D06EE968B8E5FC11F2D9AEF14A3248EC921FF0ACA4BB1369F7B5B3991ED6B16C3A918FD9397BA4E454FD209567D97C8BFB47558B6AC7726D6C83768E0A64B034C0EB36C8BFB0BB86C52B51FB7DE503C390B97B00A4534206B267C42333B4C05BC90C7FD25609548B2E7087E792BA21E360038A6218872F94035E5F13149CB440B302A591817EB0E229AFF03CE9005535978F930622DD422722C059E0BB855143053F348B23D5ABBD49B7DE9478EBB63380E75F9054922AB65F4E897D02F9AF641CC6A34957B91A7969A1270E4264451053267137ECAB8C8C8B9B76354A63E1ADFDCA087E54A67F8A2DE4AC6A636348017C6203B4A27322167C2ACC85F63335E8AE4D1909DD1C3DD228C0E3B84470446EDDE572F7924DD409764FD98F43A20E5AC15AE9202BC1AB58BADB3D06B6B77E81ADF763836398BBC45433015B6523652751B8292AC51230440C112C6317A66F24C4BF927C7EB8C186C9DA10E1BC25A4DF1CCA9B6C3407955972448DEBDB284B3185127E1DB71871889DFF67F5D4E97656F7115F28F00AED6D032FB3816189C9EC00525B2D58F1FF5026A6F9CEE39EF8DCA115C0BADF3ABF3244BB9FCD113DD9", + "c": "0E505EABFC938559CA3FE4C830365B6EDCCA3FF29E815FB9EC8CF1857458A49E461FA69EF81E5C2EC80875885CB2FA27B810375368E7ACB588915944CCA39F196EFCA8D7D8DC4C7A41B12997052C80141058C24FB77E37AF8B590836B81913ABC4F8705F8A1005CE016E33230C04437C8187C4D94613CF60AABA4D664A836D5DC8F5CBDA739A1E464CB8838CC6E9B8D5A80A90799AF838724256BE25AC34E6A3D4E622B254E3FB8AE2D7C55BF64A88562853C876CF18E8FCA1AF3548570492AA3B400E3FE33C58B303BFEA014166ADA4E2BA779B463C4E606F46DBB00EE7F937788872F52B25E8DAE7BBCBB47956A1117B84E8B3A01354C5C2C276F89EFFD60A0CBB8B7B8BB5F29E26C47B34F9026E05B41C06B10CAD7F15446DCCF2740B9EF4E26E7AA3DDF63DF06A530E0E6765B24E213DCE686C292B4210C0492ED87B08BEA2C18F0B7AAF6EBC0C67FFE888F9BD0D55B4F232BDDE3F6C00DC972C16601EF2DBEFA5496547C913C2A51367E8E5B1B16AE02182E668BF8B7B5EEA226EEB93BC4564B74AF9B2EC5A9210EA9608E23B7104DF0C400EB97CD23694EC81B529B0B4E5F5881E3FC53414534482E6A22386B7A6AAA7D79B714395FC88A1C626BFE0174A14FBD8025E6841904D7D3DDD3BE941A102C1D435EC9ED62C0F07A60BE6BEFCD8E3BF34B2EA2FCA21DE91469479D5466CD6B599CC6DC9358319BDDE21484BA923A8293FA5A3A6664B81709FFFFC61180602F2E82E09DE6F80098DCDE7E50543A32A2AE4DF13F30A2ACC1F143AEA50388380F68ED9A70D8F90709839557E87B71A348A6BBE8F2BCD513B8AAD667113868F8DBA8B44F844CDDFBD6079B0964BC9164D7153EA9042B0166C2D35048CEF2FEEAC4979C5DC6E7C3470F99820C1B6FB72BBBB421D7E7602BE9424179515D6A6EF4E9599F44C878D25F2A3EAF38C1B06C6C45DBFCA9E53199AB78C9BB7CDFC9DBCEC46BFF12CF77D6F1F00B8A52A943BCA9D85A5E485E07C053FEAC6A2FA26CCE9FDBE9441CE1F379F15FBA36417EFB888EC69C2966EF3E52088E395843A32607575CE79C686FAD4E20223E198C069AA592CBF7EAA2B5FA375A01D2DD78326F5FDA930630D93C7C095B8BB7D0B6FC6020F2729412EC1C0D89F03989B1FDD708F21D22E5EE9C7C1F0D6E116BF633F7F989D693508EB1CCFD87F0455CF8B796FBE8BAA5B9043DCCB18FE013C91FC6CD47CDD38FCEDE636266FF5495A0493EF8932FE569D1E8E3AB4C477A106FE4C5426493DDC24C02CC59CD086D16DC4C7F494C12F75FB7971C0309ADE96445CEFAED2067A18D0AF1B6992FE1087F0A863D52DD2AA128CFA888B0FED293F674E29F2C9215A0558331F52F8E8F2C58EB9AD654A3978C8294A083795CFFC311F94E743A83FC684921D5A56AF179FD9EEA692D3AC2B937B07D54CD132DD802238AD59E8504603368EF12114F6E21E2536AEF4956715F24A58F8F59971FF0075DC6FFA14965A4813503674A3FF2946C4B36BA9520B5C8E905DCB770296F7A1C991C28C6AA5D3", + "k": "330D1A2D0E0B5DD7F759C29A22D91A09BEF17F8C5566A0D3F30E3817CFB7CBFF", + "m": "6F1694589DFFCE022DC4DF1852FA49A41C6E8AB9F7887E70DDAEF4232B045DFE", + "reason": "no modification" + }, + { + "tcId": 39, + "deferred": false, + "ek": "48E11D1B0572F2892B8F81A8BE330B16C7353B5C319A34874F959409E6A41A71585BF36AEB651869AA87D400C6AF32B7F8270BB9D5C53BC3B600F493904AB000149FAFA1B090B544EA0101EE940EFE878DD64739CBD78D317A09A45775B2AB9E0383C75D049083BA64019658B4F44573C1B7C0B3A59495606D9162438B1A0A000C3AA5834AD5BBD11893598052E5B543E209215E41B8D49C4107F5658F7685CE53459F21452AC66F0D2398B6971A5A23A056444947220E95454A404C7213686E58A42E346CC0C44759504B2FA07198D742B1BE01A66C2BC64498CBCF6482DAC99DE7DA703EC1441D08C4A701BF84FC956B11411AD610146C59DA6454A8B3B742D91DE3C09A5317A9DADC23ED0A922AF339C090060B869B55FB3AA1C603C40868337687EBB27E37B804EA834D4D0084B21307DB0A64F69B7B49B5B0D237AC428ABDFACC01D1012A04008CFDD336A06B9728A036B6C60430A8CE887C4B006AA7E7C54834E2934F8400D030AA63E61FEE96C22FD49685A7C3DC2287EC2964CAC78B40340200C3AA6C8A67BDD30FB7605F0205CC0CA043A4574235B342FCE51195873F7FD99077CB31229B91D5923B67D391B457198125B7F198BC7CE58FD6B96BC35CC3D0281957B4110A011262B1C4CC0445722CB5E8C102408593CE6445C4584E373AC890187986A49414643CCB2861742466939C347CF021D1C19D36398A82C64D1FBA4C44B56CF384C04A1944449258700A66B1E2C9185A5E8B17772538B33B038B877353DC251952DBB899F04A6C677247D4CF4E4A5D2B22313A33A6D49237E7C04C61B2B0026531583C6CF6332C4C7853B7A8C6A4A5783D1B79FC5725F9C7157600747C0203E313CE91976CE44CC4E0D67DFA830448999357F076F2D41EE6FBA68C53C9AE5C025DF867E3060F3CF164218142D6C2B5B526BCE6789DBCBC5765846565575AB154C545FC3A81AB8FA1353B703B72B011A0405588FC0B8C20D13ACE9A93F6B28EA1C05CC686CB0AE722662A9ED902AE87D48B8A9667CBC0BD75742CEF313F1649C42C760796C979369736CFF05516A72BA36849D2E213AA497A6E7774EB9A896AF0A13387ADE8F594DEB482D9FB9E4C740360B5089CD101E5450C837C8214247243417C05ACB9D319809D33168E707BD1168709F7829B584053B554D95557DC032683D885AB406E205B6F495C23EB673E05651ED9DCB87C4967987B7B78EB349F4AABD35C7242079FB30607ED82A0503173A1B785CC36A2181892114003E2D33D17AA3B0A5CA47974B8F1C93B35107DA3900A87792433F154C643B34519941CC60710F07A71E4AE09A7539E72B9235A07D5DB53C048493B4AC8B9F0A3696892A0164DCE38B7F8E711506A9220A5C6C61AC2EF3942D3984907E59DC703ADBD93B6B509A156CC34B226188778BD191402DC94124CC7981151934F68733D131540056466437CE2B31C1320362AE5247C35CDA6E13E5D9BB89D0C8DCFB16BE8BC355A0C0C54E7ABAC12621ADB1EAF82B3D1E915315A3B7F3C98F6CC117BC3C850258059737171478E3AAA7FE5D7B5CD218CB428153C07AF80667C096C96656C85B8B0BD1F606A7CEA963717A18AE642E9E8A853D938C66651EE31034CAEC7DA6097A3C35BA420022324EC00CF53B53E9EBADC6FEB57C9B5BF5F53DA", + "dk": "C6DAC8A176AC00983EE672BD5B613267D594ADD9096A5B3FC477B5E5E3AA05D1981313CB7848B1A8CCBC7DFB8134C56FD4EBCFB1CB1069663FF5425829F23ED1501E5C506C4FC8CD2CC36C74A63EF2956F3D71C3A22CCB622282069584D019090148CAD445333881AFACB2CD7FA2C5FED9A081678718D9A16982B5F35869B682620C968E9341760DFB6BA865CEB1873B31021848C348B30982619CA19C268F77312F20FB939778A09020A4D1220EFCD70862975930D5B36D37C361687FBB0186F972881D3CAEBA0686719C8FE2713B28B7C470BB23A0F47095286F9B5BA8F019C8B04623734800C205BFC4702E7DFC70FA32390159565E39A18C19CB1E758FB47BB8905BBAC6E53C92C52822C51D90CC869E0C0354B94C54F181252714C45426F71839146510564AC3CDF3ACFB0213C1F1CDEE523472D043EC8564209B123FAA0D5BF344C31C74ECE10E66B2C169079AD7D7366D404349F01BA6D247A46B57A2264C7093BB4D27514DC5620AA91E3EC407041AB3B8E4585CC870F4B5153BE304C31A9A3EA54EBC071D03D5758F00C6CFE8BE6C6635B45498031072EA0932045763744A1C8BAB8819EA6764805D73D994A20A5C8C4ACD505022205A4405020E1C74B06B89A498D871DBF37E7E46B3439BCEB0809FF1141678D428A2866BB14B00E7296961C7BFA9D932F664BC310B341C9158172876421736CF18CC14B7B3384A35319B8552351A30BC5225AC7DF5DBA28AE696E4B9AC30F426EF7C1272EC4567D21E16D6B5C8E44DEE901AD7C6146271A7C2215F2D3438AF669D572B12E3639888416F9979448A45A6528883C9F41EF0D6263FF04CA17385771C007053A5DA700DE42B05CB0468ECA8840B822D73F5268D192F5FE6B15B87A8CB790902A295BE32A62413A9867239FE08A422322E688BA4306BA98359A8FA726A7A1400756CAFE4DC67F97904496B5FFEF21D5CD1396558B4F7982D77001A87830057F569355C0E7D7870A6696C0EF47B31A0CD97757B94F195AF717CBC205FACFC10A8368F06F747AFCC6922297C3500248616781825A07A03626A371EB78A065DB3A7BD25CE0C722EF4F6747CBB5997EBC98BDCAAC92B12CA4A4647327FBB980F35B8102A105DB7361B82161B89880F1AB008B739775B4726D856C1A8D13024F36CF0B9C1E5828677127F0D82A870CB19572B93215B02281C0ECB96204C40B13653416F3C8CC761931FC452258A65EDB2C0A10560E184052D87CE52D2CB90311578494562307606195E2C484C91D93A3ED11957E3B162F7CBF66832E2C0143AAA80C9D309F14B8FED067C745A74BEA5AAE36CA0F264199B2892A00B430F616C43939F0F0C5E64DBBFE858AD17E5122CD96E5E312F27CB2AD4DAC9F628C28DE55AA957CEE08CA6B8C9C35136702C12233FF42919331C01D53DD4F817F2DB2B587585CD92867B7786212475325C50EB9254D0A2BBCB1B2AE563634224A8DCC167C8910F7405A8BFC0C978877528C71EECD3632E13997B66C242A9A3D69A768355C333D73BCB66AA3664074DE3A644D24B5AC48CD0F13A39AA3996209E9522C499F87777407E24B746C9CBC7C63256D2C5ABA644B2C1267DA61520FBB756724C9D09095803A13F48E11D1B0572F2892B8F81A8BE330B16C7353B5C319A34874F959409E6A41A71585BF36AEB651869AA87D400C6AF32B7F8270BB9D5C53BC3B600F493904AB000149FAFA1B090B544EA0101EE940EFE878DD64739CBD78D317A09A45775B2AB9E0383C75D049083BA64019658B4F44573C1B7C0B3A59495606D9162438B1A0A000C3AA5834AD5BBD11893598052E5B543E209215E41B8D49C4107F5658F7685CE53459F21452AC66F0D2398B6971A5A23A056444947220E95454A404C7213686E58A42E346CC0C44759504B2FA07198D742B1BE01A66C2BC64498CBCF6482DAC99DE7DA703EC1441D08C4A701BF84FC956B11411AD610146C59DA6454A8B3B742D91DE3C09A5317A9DADC23ED0A922AF339C090060B869B55FB3AA1C603C40868337687EBB27E37B804EA834D4D0084B21307DB0A64F69B7B49B5B0D237AC428ABDFACC01D1012A04008CFDD336A06B9728A036B6C60430A8CE887C4B006AA7E7C54834E2934F8400D030AA63E61FEE96C22FD49685A7C3DC2287EC2964CAC78B40340200C3AA6C8A67BDD30FB7605F0205CC0CA043A4574235B342FCE51195873F7FD99077CB31229B91D5923B67D391B457198125B7F198BC7CE58FD6B96BC35CC3D0281957B4110A011262B1C4CC0445722CB5E8C102408593CE6445C4584E373AC890187986A49414643CCB2861742466939C347CF021D1C19D36398A82C64D1FBA4C44B56CF384C04A1944449258700A66B1E2C9185A5E8B17772538B33B038B877353DC251952DBB899F04A6C677247D4CF4E4A5D2B22313A33A6D49237E7C04C61B2B0026531583C6CF6332C4C7853B7A8C6A4A5783D1B79FC5725F9C7157600747C0203E313CE91976CE44CC4E0D67DFA830448999357F076F2D41EE6FBA68C53C9AE5C025DF867E3060F3CF164218142D6C2B5B526BCE6789DBCBC5765846565575AB154C545FC3A81AB8FA1353B703B72B011A0405588FC0B8C20D13ACE9A93F6B28EA1C05CC686CB0AE722662A9ED902AE87D48B8A9667CBC0BD75742CEF313F1649C42C760796C979369736CFF05516A72BA36849D2E213AA497A6E7774EB9A896AF0A13387ADE8F594DEB482D9FB9E4C740360B5089CD101E5450C837C8214247243417C05ACB9D319809D33168E707BD1168709F7829B584053B554D95557DC032683D885AB406E205B6F495C23EB673E05651ED9DCB87C4967987B7B78EB349F4AABD35C7242079FB30607ED82A0503173A1B785CC36A2181892114003E2D33D17AA3B0A5CA47974B8F1C93B35107DA3900A87792433F154C643B34519941CC60710F07A71E4AE09A7539E72B9235A07D5DB53C048493B4AC8B9F0A3696892A0164DCE38B7F8E711506A9220A5C6C61AC2EF3942D3984907E59DC703ADBD93B6B509A156CC34B226188778BD191402DC94124CC7981151934F68733D131540056466437CE2B31C1320362AE5247C35CDA6E13E5D9BB89D0C8DCFB16BE8BC355A0C0C54E7ABAC12621ADB1EAF82B3D1E915315A3B7F3C98F6CC117BC3C850258059737171478E3AAA7FE5D7B5CD218CB428153C07AF80667C096C96656C85B8B0BD1F606A7CEA963717A18AE642E9E8A853D938C66651EE31034CAEC7DA6097A3C35BA420022324EC00CF53B53E9EBADC6FEB57C9B5BF5F53DA963F10A9456E56F427F58784728D6C58B3417E8D6F83A50E16130B751D979C1AA9580773A2674830CD525167DF109974FFD07155CF55615E23916E428C12925C", + "c": "36D0BCFFC4727964FF08A0DD933907E5DEEA4776C814FACD5EB4A45CB3C5FF4D0FA77C7A3E3922863E6403DD9D13A7762A72EABE484109399F14D8855CCF28E66A0E33B8055F815B61CEFCDDDA9B434556C3F696997FD5889EFD254D8340F84D845AF95ADEE7907126ADF6CEF4B4F37A9F6F9CCB2877821A0D7DEE947D13DF4BA7F1FD358D430F49B92962EB32A7B39B20666298A82B5EE52CBADD02D4D4E202330A640663D98CC30759DF86D4F5D8542B940A80C87B3E4AD6EAE0419AB6BC6696AEEBDCE1A8550F95947AD04F47A3C9A4F84E8490FBAB2C7137E8FBD20AFBE7D94FC35558C14149AA277F937AB28BFB33B7084C74A4F860D5738DDF8283248F22DB16F752B55900C8FED3B9C56B94A1BB525CE054504DF3FD651894F0F1EAC0B20D052DD0504C6E2DB7BD742CC3527D55BBBBB184E7E311F72A125B230E7D1364D77CE5B5B104BF1DDA76E054BDE897DE4437DEB871E99C5CC16D537BD40462F0756B796477E7B0FE435202CDCE1A3B5F30C0F757BC0263F3E8B6B4A7275CFB1EA24637752034BB32108BB1627DB0461EE9C521630022E00F7B340B69F95917A8AC0C6D7EF6E37D8E4635E77A8C3FF9E42F452EABA5CADCEA4D686C220A252DF9FE3B25F897C163EF40820DFE0A5CB27A1926CF26D78E307FCB67A9019017BC667116A46BFF210FAE126688765ACC48EA0F8D8D13819A3CBD9DBCCFCFDCBB604EB97E51F7D23C20B8221D34B5053DFAFA549C2D374BB2668CAAC16DBF6A9ED52A86DCCB5B59CA41DAC1661C597896A399CB6ED3FBA6A4C1F5DF6A29E3A65CB6C2F0ECECECE778CD1DBAEE4260D3FDFBCA9AAC3E161FE45B88152B8AF6AD0EAAE9D964E9EA362B5643621B997E35781B1232AEDF4B02543B339F074FE630C5D97AA49BACF3A0D3EA57246005B4497A14165C8BF39AD54B430A30D2EDABF024E0245F4C7B732DD90BF4BA1145C4B88CB81E6408E9D8CFB9CCDC4A9BFC4D9240A21091A11543FBD9DC8BE2F5A02E3650FD273EF529BEC9AAF5C2E30284075326B7CDFAB4FF448CFAFDF21AAA5DB1E0B2D3B181BB7BC9F4665557CEB08DFE29E0CE924F7ABB3D226E9A3EE74BF69EB0F59E58A232E778724770591219F2744E8149028CD61F6AD182E8F42462DA51546882D77F44243C698AC7B61B8FEEEF91EDC73C0B96A40DB2616BECA5A5686D8506090BB3F02075400A151B26682C8D81F05E9E87BF59024EE5AF6B6D015F9A81E19817CE5493571CBF8946C5BE67548ED11971877617B6550F372D5219BC07AD00D659196149250A2A32CD1387B46F793FAE968BCF3F1D4F0BEEDDE6E685C975E176DE2B5CCEC08930D0C7D176A43CB43AD728D131C5B5646C41113904B919AF4E8783EC14CBF11B341CB81CEAD8FF4599E2B58FE97E297C79EDFF394891C5D7318DB5684FDC0AA867F677B6147886AF4F28BCD8E69F3DE22A597DE59909FAEB7D7BD991DFEBE3A40EF9A61D0C725619A83F82088A14E2A1703CF700BD0189D39F031FC2E7E01A3BD8E8A4D6790A2262669A", + "k": "44AB396F38942BB69C09B2602629B53B820FCA6D3D1043B24AFB3184AE9B5565", + "m": "D8EF97421196B1A91448B2BA7E2B4D4B035B91DD85AE4E57E8FE3F0B0D524AE7", + "reason": "no modification" + }, + { + "tcId": 40, + "deferred": false, + "ek": "AE742E0C4761E7731F98A96F57374EB4E321E1D33E3133C031355AFA974E82F50E7EB36084471D94490150188B34A113E300B2CB65BB44E6940124BFE3E21FBB4B01A7640817567949286922A22A8EF654D8465CA39722AE9A4D0054906F52C79428716971ABA0703C2A3C497DF73D0D0C8AF3BC36D12C80AC2701D8C4689E05645B2017B7EC830F8CC3C3419B1B14AA890B2A8B274C5316185B26473456A196D8C836352B437A4EB0E924E9D5776B528DE1BB433B7C703F302EDE284C9B22A6A502A7FD6B17AB5546B52C86DE883C80F74A9A7302E7270B73C521FCC51EB7E02BCC68CB257A1FD6EA63C195610AB8A8AEF2486E18AA081056B5F474FEBCBAA48560325C06DDBCB79EFA10589A62D9D54268062CC8E3693373066E57C876558FF3180C632269E77A96F305175F3A2F9833BDA9C43BAF62500C202D0DBA91B28CC6473703960785C8711604C9CC04A98BD19904189A6D62A159E6A83F25907EDCF457A080C70627C6F5B0612AE84D4317261BE728B786A111B74478044B7CF192DC6490475C9AE1E5C0FF97B812E0094A63AD818C5BE5304AE8981B52867912787114A14088261CF0747732548EE105927DB086088B89DA4773F3C4CCA0E44431D98A8EAB89C1D6C1D26109EA32CE99473E509B9D478614D26B06387B89D64C6785A50DB4C78FEB65786550647EA30C9029884DD34FC9227596B091E91766F8389A82B01623D7721F2069911128C309602F047F44825EF6A12BEDC72880AA3BB91504904276E3E9583228A7896570676B8DA28723EE17553A156AD5884AF0E1066E518D19951F98079F2244009369157E1915B4FC99254C4691D4A64A0AB0129BB235B00552C5B606220E45683341086F2DB3ACC16C8DB563259C6C8E6A360B9CBA54D048335E455FB406415D147122903325B341727C76ECD2C16D33188055534196C071F6B6806B9E057B5597158E036C3CA90174A83B965F8C3CA7562A3A24AE99298A10791D38FA3E5F30B5CE3A8438E6708A156FD51C055EFB5C65759D76B1BEBC231896095F213148AF839B4DEAA03C9628D0C943B0F14770A9A223FA3CF05C7EA983BB64501885A919678001E9219AEBFA71E5D3CB5BE585E7B939194C87C1EBA5BD56A953645D28C21F0E45686C9AC96F820A3AC26F69F705EC920392601E55FC1ED2B9BDC3C6BA00179F9DC687C2C01C29EC05D8BC5A3145C1F936CB8B20CB2015233E01184AE68BB0F96728C27521118466A5CE602CC4419881DEA62381D7870C14209B6A874FBB498472B3420A3A2A4203938863C7610DF73325B5C12EA5D2CEC78610F7237C4453536D7180EE7425C9DA6C43604DC6A074E2B203A0FC6B44679879AC2D94427746041809D84820379D14168BB0E816FD241598195CA1C447C2EA5D5B455A28E66527088E24163C6DE46D36DC1753CAB7451A6ACF09ABBAA1223E7A3B07E801F84071A7A3ADE760C7A2A12F4D12734530538D2179EA204ADD3A40222467649B4245942E80B50EFAF60B83E4591951101D025B05CC1EEFEA996BF1C015A6CDC9325EACBC349592B881CB3C3DA8C096127953F0B9697561DCDA6BA3D566FF3C14BF718ADFA47877A12E390A6CD0544D9524AFA37069C8ABA24F918FDD15986F9B1C6471A5C7A495588F79B71FCDBD7376406E5DC064", + "dk": "B7649A90D87901527052079DCBF86946E8C05A3558D5B35B185BB6224938B6B5A18F490AD2B439FCEA41F1A7A2DAE9B97245469237422B2422CA8B0E36D9A045E296DCD817CBB29CDA6A94445848C9EBAE5314CA9B063D7C666C9D533D6CC1CC4CB3CCEEF55E5F4A9681125142B77C6EC6CF4C94452E9CCFF601276DAC56AE1020CE7A0E9817501856ACE069566C62766827335E4897F9D47D7C777DE56561654386CD579A1535C569EA4172312E7106AFF19836E671399A172AE853656D206C63A2824D46C6DACB6AC3E21681E324728818CC977134531C329A9982686680E542208C3DCE02579051B37667814C439B45A3ADC9F12D597B42D7372B5E863E96FA8EB8A61EE999A2CC22607A057E6E69516BF8628A041E38C378E0A360CAE6BBB3E7846698C5917A2416BC5B81117CBA8905410C959B4A7241BB96974B29AB976BD2069F41960EDA9778D1EAA1BD7A74F6E40611EB68EA33583C707D6F005CA202ADB84C6009354679604B3D78A21DDC1910DA0FE554A872889CFF801AA496B0B5D498DF245965B783517A2B9F495FFA714FF17B28873A3BD6B5313C8AC70967AC62B90762620818EC1EC1E21080F5427A59C08BF7631F91AF9BF17814A238983526221774C8176F932AC90C240BF48996B9E912A7E6A187831EAF2A9B69616447C26BB598CDF1D52542E6C39BB5BCDC25B457241CE9F2B2E9713639916EEAD5B5E85637C8D527629018925A7F59C539F35371AB49CD49098DAD905296F28B2CA29295641633ABBD29513C886A82F0094715380A6B013B16E578FADBC7089C637BE0C6FC85A68275CDA850981DF357CD40C3DBE21B10376ED5C9AEB6FB3049889431D23C3BB6BB175A24A7233C5983C5D1864F1035C805631FDCCCCF301739BD1A82B4A9CF895439A05629024312BED71D4E93863B22B05B5494BA666D4686971513559E5815A0C7371D50B209C185E3326AEB222AE51C74B72B07F3A7A913E338DD3B94F750406D533703663B6DF204A7A1BCF2D608E3F9A72BACAF83B8393E8456A1D25CEAB511BCB7452DF51CC2EB75D5042E6FB26BD8B518034348A795878CC52906A478F57107A0D8548D9442AA964954B60F91EA1EFFD80C8511A26A7907234ABE3440BD60A595E02813F8BC76C9B83D85D7C0D707378D2B4081C7B0F7FB5F37C4BA0C7AB2670800D698134F4538E6D79224D9ADDF82986B91C856FCBE1B70940A103081D09CEDF1B527D94DAEF6427F968742961C6D910F6CBB3CB2734CB710BA1BF2C02838CDCB34482A452290843B12251FE776C5319A7319F47F22C4AF431996A7602E35841B0120151F427A307590E5321735CC8B2885B9B190A0C6466DDE597E41FC4AAC417882FB23E3866D3B325DCF8B0994434CE75A988B4B30EE9162E56809F638300CB647623A708351555AC4705081C628D48DC7FC7EC0F27A822B1650888CAD4CBD9D9B07DE6B82BBE47A966C331C743F46917104736D3ED15277B75250401B7A030CBB7A82935BB7E885C606A851701776E1B5487640444F33994C325D0DC99B2E06021C753F3C6A4B556A5B4A7705F2C0A32F4315E9AB35267C17002131AB608CDB13C02C50A1B152C4FF0C4D80AB8AAB6C4C8BC508AE742E0C4761E7731F98A96F57374EB4E321E1D33E3133C031355AFA974E82F50E7EB36084471D94490150188B34A113E300B2CB65BB44E6940124BFE3E21FBB4B01A7640817567949286922A22A8EF654D8465CA39722AE9A4D0054906F52C79428716971ABA0703C2A3C497DF73D0D0C8AF3BC36D12C80AC2701D8C4689E05645B2017B7EC830F8CC3C3419B1B14AA890B2A8B274C5316185B26473456A196D8C836352B437A4EB0E924E9D5776B528DE1BB433B7C703F302EDE284C9B22A6A502A7FD6B17AB5546B52C86DE883C80F74A9A7302E7270B73C521FCC51EB7E02BCC68CB257A1FD6EA63C195610AB8A8AEF2486E18AA081056B5F474FEBCBAA48560325C06DDBCB79EFA10589A62D9D54268062CC8E3693373066E57C876558FF3180C632269E77A96F305175F3A2F9833BDA9C43BAF62500C202D0DBA91B28CC6473703960785C8711604C9CC04A98BD19904189A6D62A159E6A83F25907EDCF457A080C70627C6F5B0612AE84D4317261BE728B786A111B74478044B7CF192DC6490475C9AE1E5C0FF97B812E0094A63AD818C5BE5304AE8981B52867912787114A14088261CF0747732548EE105927DB086088B89DA4773F3C4CCA0E44431D98A8EAB89C1D6C1D26109EA32CE99473E509B9D478614D26B06387B89D64C6785A50DB4C78FEB65786550647EA30C9029884DD34FC9227596B091E91766F8389A82B01623D7721F2069911128C309602F047F44825EF6A12BEDC72880AA3BB91504904276E3E9583228A7896570676B8DA28723EE17553A156AD5884AF0E1066E518D19951F98079F2244009369157E1915B4FC99254C4691D4A64A0AB0129BB235B00552C5B606220E45683341086F2DB3ACC16C8DB563259C6C8E6A360B9CBA54D048335E455FB406415D147122903325B341727C76ECD2C16D33188055534196C071F6B6806B9E057B5597158E036C3CA90174A83B965F8C3CA7562A3A24AE99298A10791D38FA3E5F30B5CE3A8438E6708A156FD51C055EFB5C65759D76B1BEBC231896095F213148AF839B4DEAA03C9628D0C943B0F14770A9A223FA3CF05C7EA983BB64501885A919678001E9219AEBFA71E5D3CB5BE585E7B939194C87C1EBA5BD56A953645D28C21F0E45686C9AC96F820A3AC26F69F705EC920392601E55FC1ED2B9BDC3C6BA00179F9DC687C2C01C29EC05D8BC5A3145C1F936CB8B20CB2015233E01184AE68BB0F96728C27521118466A5CE602CC4419881DEA62381D7870C14209B6A874FBB498472B3420A3A2A4203938863C7610DF73325B5C12EA5D2CEC78610F7237C4453536D7180EE7425C9DA6C43604DC6A074E2B203A0FC6B44679879AC2D94427746041809D84820379D14168BB0E816FD241598195CA1C447C2EA5D5B455A28E66527088E24163C6DE46D36DC1753CAB7451A6ACF09ABBAA1223E7A3B07E801F84071A7A3ADE760C7A2A12F4D12734530538D2179EA204ADD3A40222467649B4245942E80B50EFAF60B83E4591951101D025B05CC1EEFEA996BF1C015A6CDC9325EACBC349592B881CB3C3DA8C096127953F0B9697561DCDA6BA3D566FF3C14BF718ADFA47877A12E390A6CD0544D9524AFA37069C8ABA24F918FDD15986F9B1C6471A5C7A495588F79B71FCDBD7376406E5DC0648599741BE85FB959084A514EEF8306CAB0D933C51707EEE4782831FEADF8AFAFD6228B0EA7F3512B3757EC1D5057642AA3ED2265E73179113245683986C8FF04", + "c": "5DB0F63E2A2E640FCD26AD49D437B9287E2C3EEDC2E82A25A49AD859C867929BB10185B6457D64B467A1DE9176B5B4C163FAC1C6C0CF0132BB685F4B99366B8CE702BBFC369CBC1D294B9490E47FBD2335EE6641404D6444E7F7EC3C435F5FBA9134DA5D807B2D41ADF37FF44497826FC31E447C6BF66888893F38CFF04C5B565B036E1F9BF255EECC0F0CDBC625010C8CD211E74164394A87569B08469C2C892ECFB90D5D614C1F503182D9F7C168CEE2A1E9553BDC7E0919B9FAA1C2FC652A13F87394B1B43595CC6218BFE6CB8602F864295D06F0A60119723972BEFE7E73A70F8F9B99ED62FF27317DA4BE60F7CE98BD70A0C138E4E4874CC3D254CE3F93DCAFFB2C8F0E200C64DFF97437878E4FD6BE6F8AC8FF6C5982EAAB879955A699AB6071F0276E6999CFD2FB58329718C64928A18C404539CC1DBDA372098F9686C3CB9D945824424B76469D1DAC5D52D0A172447C19781B43BE9067DB2DC18B6C2CB1A5F9F0C0B4234FB605D4C96396DB5C2E38EDAA114B4C6181BE8AFE6DE1FDCF38EAA4C7EC97FD629F17F2E530CA5CF17DA32F14549F7361E38D64A08180E2FB7AEEFB2CACD993BF39020555596BF421C95C6DB96A0FF59CE65B2F624249EB73D19F34D6F9874CFA8AFD71C9BA1455055077BA7E5E2A9D074B8CD2DFBF1767BAFF41AECD9DDC1239CDB6BBA904A017665B57F2CA765A3C08CE233782A2AB13C66F6B6E55B14D71E1AFDF18F093FCDC1155B7471E12FFAEF7F13C01458544DA9157A898B6756620A8219DB5FDBCCBDC3C4FE21AF3902B2210631E63939D1BBA4B0B674F184000C985D4BFA7C7E3F0FE87850DB0504977693AA2B8D12A35B7619117D5DC8FA5AED0E556909D9533A25A5130F779D3DB7C5250F12DB5E1E51D035BED789BC6EC2D135F9BE244E28563E011535A09AE6EDBFAD5311EA083F0431F9C555F07AB21F0741B7DD4508A99CA4E6A6334C21FCDCD25482E987510FE623822F9033441844F99B4A489491F70C4459BDCA67DEF22C76528A8F0D0FD36B7099A7A34460B5EA1CFAF7ED83F0C7773B062A6EF062383703ECA07612D4960C410C86AAB9AEA0764F060C08B4B20941AA2541E8B8521A8E4B03913A48FBDA62BA060A762EF6199649D7FB6869BEF764B6688A7B77DEABB337BE54452947282E9B001D6B54974180B756219087AA81A8DA6C2E708BB894F099A0C5FD5E858867F083E504983E3FA1F0D9580CB926C7C4DEED4BA51D1E5EC0F8A6102880928BDC7A996F2257AAC86F25313B1D51E7EB784B2CB78102AFA94389E30E5FFA336ED49B1F9FC0D557DD7F9A9C9DB959806C9509160FB9EC4758825C5CC1D49D95CF134CFD1565016899A7C102C4E19220F011DF4D363F3B8EAAA419DBFBDC5CA66FAC7DDAE1F144AACD4209BC01569E0BCFA4FD383EC9AD4CF36474E0C2F8A9335A5E6CC595C781F3AA2EEEEDCF593AC27AAD55FDD46D0224CB3B88C3BBBF6CA6F2E7BB4043FF2B0C88D304B962F108C052E8B7CDB4D2573E47074BF146BC9E94783F811", + "k": "E5DCCE174C4B39536E548CC326893C4C4CF649699CEE746476A827CA567D12CF", + "m": "132E7CDAB9CD5199FF0937C266D50BC50BE764AD027DE45C858E3C2F79B7F07A", + "reason": "no modification" + }, + { + "tcId": 41, + "deferred": false, + "ek": "11A62A8896CFDF943396BB8F58D9CE2C8A4DD07ABB736CA309614224E13CBC2A4EECE6A9E134B65625BF7332A0B978921F4B9B689736C7A90CD77120FB33124BC272EE9B656952980077BA0A2108AA34355C391118E2ADB2A1A6A61498DA2B3E7A6B3477890A6EB74CA66161979B1C44D10ECA94CC26C93B43E42FC68A93B85AAF0F9381DF309291E2160CA19615031576D1448AE4A36DB5A7EFA99542DA5F633C4A75470F9369AFF4D20FD2D96B62348745A46C81053A17FCA3FB927871E88E996C3555B696CDCB7639E13E1148397F4845364A7CCD245DB28577C678B061555A8F97C7DC4C861201C69106CA2F375E94B597BBB09067F4C730606D2AF3B6FDB98C14CA1A339B3D23174AB19C0849836C33720C9A04821F59B929D72421D7583E9919531327B296BD2325B5CB172FB7E620647091A99A053E20907588950E303237FA68F57B1A305233B6E931F22AB46769C4690420A94C3C234B564DEB3052C4ADB3B08A1F455E2B1B8132E6232E42CE33904146AB6FFB693158AC411DB0C49CA3990498BBBEC8BB06812A31E67761FC26AA861E328906D5B873CD2A8C92778260BC84B50703EAC6BB10432BC0115AF9FB60C8F02D90D6A2CFF80A69FC0E23A3068868A7A522CF96876FD1170BC8552E45EB65656740CF2AB106A553CC61112B659E6862346F64359FC6B58FAA70386B955DE918C5B641F9EAA2BE559A5BEBC40E113BB6B63058A80C1FE1664A81873BE506F8A795D9A8B4318342FEAA2A28C7ABAF1C624D5A8DCA352906D037B883AF54295328180EEB06C910A0B7945A14371C885EAC006E24B6A8F95936763B54C89BEB2379DE061AD5D0A65D8398310A5B8844A81F2C8C77E71F974BB0297ABB1C02442385621D607BD3138E063AC36D728ADE7AA6A90BBA32DC2FEC1498F3D68DA3290C17618E35DBC43262B009357CF6F79B04004316E82076961DE4B47F2E5229A9008D4CE902D9F26E5011A4B044AB0FDC668DBB6813479ECA3B0B18E028B1622A9F6B899420899FC7246CA86C00E7C4E1434365067544D02C44C840EF34CDEA6C3063BB64F18B05EE379A18F125514A6A94A95AAD315A55F0ACC567BBD0705B0AF70643F318A7C70EEE059F52C7A67353C89AB55BB091705F3059C93B7EFB305C7716A86F1363E977827C57713622236A365014B87E030BCCB3696F42E6365201CDDB5778951736BD92A4D78BBF3AC4939D3772C0D58F3F895DFD124AEF4B6C454140C002568AC4298062C1C755B99B5113F0AA2DC742077B3B6BAE714742C04789FA3BC12B83A9248092A0452451A7ACA25504EAB21073744EA7826260AB03C84D22066D2199A72FDBC6F818613FC16E45F00B1EDB2F07ACB5E653731F8B701BF0833A258F12B648CCE74A0DA79DD4CC08B2209042F478E897677871538B90BB0C954312574F90A0B189897AC05C5A2E345D91574C6051766DAC73B7B38A3414714C24B175C302CB095F79DCC430438069541D6E9835EAD22789900C2E56ADC602559D595906C8B5AE01A03572183283533C64064290BEEB0A73B9E2137A50C05C1BC635710C3A4525E9C87054CBBE986B49ECC2706C2AC3AC1A474CCA723208CCB6AA1BB7C5851B390DFA3B0E09B6AE60159D231D59DAD26BF5AD617218FD68D6157E4A276122133E14BA4208", + "dk": "8620482F5A28310A3DA5870035D90D8A47ABCC1A9653E4458EB04D20E6CD97A8CEF6652748156C89DC35AF000653FC4BC94165ACB185154400D53C9BBD746C8A3BB010C9A3CC5C305C32A8EA817B5B743747B63B726937644090ABD7B0AFD73AF359007ED3418FA18E4455928599971E95C0F321B2BA193E9BE79FDC00B70096A05455BD201C36F669C1BB830468D135D4972E0B363E6366555630AF095447009590EC93993E9A862B791B8E0555A8E9634D39145598C5F733C9052934ADFC7F491A787DF06DD4C5B7765A2C26D73A4C9A928E60C81A8595883894317B07ACE63342450FAD15659D4491C1387B66D743B9557F21540A3F8B501DD6BC69D7B9BB056ED5B04D21B8065EA95E83272B42485E22FB1EC394C0E0839F255A75403355B8C60F8FE3859BFB8854E418DA0266BB26C92EBA7F3D37821942B367167893F35B8C4C71BE82540E441DB9B252C7CC2753923A5AA15CA8393803B453BDC5435120965B0C96D7FB54276789A157B84A398142BAA351124EEBA2102969C8CF733B0A4008EA2B1FE7CA9D6A1827A6C51C8128CE97CC96C3188019D596A0CC7CE3705DAF489AC823A4813490B84963504026F4537218F1AE1757638318386AFA447191AEC0F14446D093ABCAB1E897405C67A547D0743E145C1015B9EB064FE743761DD717D42C8801C0B79623A622233066573F7A264D172C44884CAEA0C1A7A7CC5E8874B8D68212CE884943822B2E190C98A6033B9004626203705676801414AAAA2C44D6AD81828F821A85793B903B2A10EACA5AAB455297B8C6D6C4816664B97B99B74E194C3A5465FB8A2F1932B5E42500F67C2799328552EB8DBFB71200C9AE2075032A99B2C25863A045AD44324D31378CC1BB8C7B2673F9E0003431235139A6296A03E3C8A7E102A8DC7224E7D1296B4B2D3B284AFB3346E5332C43F01AF48703FDA319A6691364E36B41B8BA2022120F300ABD2A45D0BA630970BB07104E9B8A35274A6674E534A0880D89F13CCA889E705B188ABAC8F3B62A25228DED82291FB4A06D9483CB49442C02B4CE038498A691FFC98A890C4BC34C7FEE52373ED9A72A3725093A123C2B1DC7105C8A1C435693503DA87374644C1AA4A4A2A6C1A42C411BFCB20D038105137529A91114CCC5ECD5622FF5C8B36522EF5106C68885C19C579A68ACDBFA76A6C4AEF031B5C00A0F2A5B243D2A1C97ABA7B0792F3AA57583C9981ED1392E70CEEF210527AB5C7C1261A6D3501B16974E402FE29AAE78588E85339C6DA0152DA9025C95B5F09A2627A76C23651323096D3459C286DB946EBCBE3C8096A18C290874644B654DFF62CFBBBA909C37917D572E50D90048086FD76B346235858A796627FB0A9B1AC79E90615C47309F87A14275A1D17A11BB2B523FBCAB0CD5C0FD8744FF70453D1AB2AA98BAF93697BA411E07E1BB7174669945B6388844D692B324E4382533B0BF454682B155EA408011BBA2373A4FBBB6BF147CB75CFB213D428BBBF6074D38CEEEE78D3F9C2F230A11930308FDE482261C14C5B1B499321798105231C7375BDA983DD03EAFC8682369198802D0510626760A7CE5CC45F38377E93A685D7369310631711230C618CB83A20A92963D11A62A8896CFDF943396BB8F58D9CE2C8A4DD07ABB736CA309614224E13CBC2A4EECE6A9E134B65625BF7332A0B978921F4B9B689736C7A90CD77120FB33124BC272EE9B656952980077BA0A2108AA34355C391118E2ADB2A1A6A61498DA2B3E7A6B3477890A6EB74CA66161979B1C44D10ECA94CC26C93B43E42FC68A93B85AAF0F9381DF309291E2160CA19615031576D1448AE4A36DB5A7EFA99542DA5F633C4A75470F9369AFF4D20FD2D96B62348745A46C81053A17FCA3FB927871E88E996C3555B696CDCB7639E13E1148397F4845364A7CCD245DB28577C678B061555A8F97C7DC4C861201C69106CA2F375E94B597BBB09067F4C730606D2AF3B6FDB98C14CA1A339B3D23174AB19C0849836C33720C9A04821F59B929D72421D7583E9919531327B296BD2325B5CB172FB7E620647091A99A053E20907588950E303237FA68F57B1A305233B6E931F22AB46769C4690420A94C3C234B564DEB3052C4ADB3B08A1F455E2B1B8132E6232E42CE33904146AB6FFB693158AC411DB0C49CA3990498BBBEC8BB06812A31E67761FC26AA861E328906D5B873CD2A8C92778260BC84B50703EAC6BB10432BC0115AF9FB60C8F02D90D6A2CFF80A69FC0E23A3068868A7A522CF96876FD1170BC8552E45EB65656740CF2AB106A553CC61112B659E6862346F64359FC6B58FAA70386B955DE918C5B641F9EAA2BE559A5BEBC40E113BB6B63058A80C1FE1664A81873BE506F8A795D9A8B4318342FEAA2A28C7ABAF1C624D5A8DCA352906D037B883AF54295328180EEB06C910A0B7945A14371C885EAC006E24B6A8F95936763B54C89BEB2379DE061AD5D0A65D8398310A5B8844A81F2C8C77E71F974BB0297ABB1C02442385621D607BD3138E063AC36D728ADE7AA6A90BBA32DC2FEC1498F3D68DA3290C17618E35DBC43262B009357CF6F79B04004316E82076961DE4B47F2E5229A9008D4CE902D9F26E5011A4B044AB0FDC668DBB6813479ECA3B0B18E028B1622A9F6B899420899FC7246CA86C00E7C4E1434365067544D02C44C840EF34CDEA6C3063BB64F18B05EE379A18F125514A6A94A95AAD315A55F0ACC567BBD0705B0AF70643F318A7C70EEE059F52C7A67353C89AB55BB091705F3059C93B7EFB305C7716A86F1363E977827C57713622236A365014B87E030BCCB3696F42E6365201CDDB5778951736BD92A4D78BBF3AC4939D3772C0D58F3F895DFD124AEF4B6C454140C002568AC4298062C1C755B99B5113F0AA2DC742077B3B6BAE714742C04789FA3BC12B83A9248092A0452451A7ACA25504EAB21073744EA7826260AB03C84D22066D2199A72FDBC6F818613FC16E45F00B1EDB2F07ACB5E653731F8B701BF0833A258F12B648CCE74A0DA79DD4CC08B2209042F478E897677871538B90BB0C954312574F90A0B189897AC05C5A2E345D91574C6051766DAC73B7B38A3414714C24B175C302CB095F79DCC430438069541D6E9835EAD22789900C2E56ADC602559D595906C8B5AE01A03572183283533C64064290BEEB0A73B9E2137A50C05C1BC635710C3A4525E9C87054CBBE986B49ECC2706C2AC3AC1A474CCA723208CCB6AA1BB7C5851B390DFA3B0E09B6AE60159D231D59DAD26BF5AD617218FD68D6157E4A276122133E14BA42086B6697FD26E70625FE8F9F9519FD2E06C00167545ABD566773BE01A874722DBDF9212A246D98C21B61EEFDBFD8BABEB04F75EFF4D8BD5EC606AFF11F6C20F33A", + "c": "199604618D182236DCCB6F33D02C92C0B22A122FE24D08AF0E4360D48F2626A6D3FC9CBB712608997F1C3806DBDD2CA5CFA9223B3D9BEC3892B7680E6B6ACA245D024D349B1162610D87B3E80B45496B2C8A930666F52A94665169B3D1242540DB797E4E2CCBA389240BCFBA2FD6E0FD3C7C01D908EA99AEB014362E2B20C2793D58E7D6B7B6DFE4FC06D2962AA2BBC7DCCAAA9FCA60493E90BBA138C7D2F300758A8A04446F277E9681B29FD6F572923B4A1D0D3A8E0E26C952D348607E39F69A4FA6F4AB7D9A4B9715A8CA8926C33442DD72BDAD6E1E72817973C6E1C8D5518558A3727678F89D141E3959F572EE533D9AB12633A65E032CF1F434A73E7FA552FD45D2B43BA5152A3172AD58FDB6E2D005F9D8A836AEC708B28972C231D4BD69E77A18FED0BACA032A5D11FEC1266F532FDAEAF3C2F231D07332B274E07226B4D35B30611FB4B3E2F49343B6DFA74CF312FF82AAEC402A1995F7CC1866DC78AC4B7B05EF8500C5C8AD5285E035CF44A6E7CCBD7B11068425D60A66C6D8F5D24415D5C8146C47835B5FBE4882F5AA33164C8BC348BCC3F57DE43AF5EC5400B37CD32913DECB132379278C1B672B006CC0F09510A4A4D1FC139263E2A163AC39FE625139DD75553A8922005E6BE716CE6E5376DFBED8CB7CB4D5F52C2948C033BE9960AD3B910AC5DA388B14E19355C6A0829E5A804E65AE885062BB8B3527DB4FF50BA41A5CE45263720B4A7877D838D1C29EEBCC7C5CF9F5212088D99DE9AE7BE18C74EC7D677BBAEA6BD25F57D0233FB167C5BA0D20F4D32EF6DBA12C6F7AF794247EF35C32D9E4C989B43935BAC97071D3D966C37EF0028E7487077F71A0380E3F32FDEE8250972CCAE6857483C01BB4CD2B177F4F9504A636C307670AEC32510312BEB2EFFE0639A68218FEA75E0E4B6E654DECAA6F57656017E77217E6FFD095A7522F0DBA295986A3998ACF71BDA96016552DF74E6991060098A20585E99E33F7D6200B6EF22958B2207D029566EC96B02CF2AEED17F66C426C5DF559A98E5966918FD0ACFA54B6E6EE70BF3042100047FD481E5E3B73288BF03877C7B2F3A1D206C76B3426F37362388ADE66C05461441D944D99FC1EC3E67511C1B9B9919117A09680A7CF99D367EAB6E493790942C4394875B86B464D1DC98F5025B9F71D27D146C7AD9EFBFFF979552AF5DD127C2231E4452513C106E8D7EC6DD9CBD4BD706AC1F022DCDCD235CC45EF6804FA2D98D371D713178FDA88C5DD6DF98E1B3573D6092DE3C022E49D8E51EF237947AEEC5EEAB775107D714E3C4DB7DC2E408EA0F3CA80AFCA83288CD1E147930FCC727C8E944A1E013919C92109E9A764ABA96A090D31C83C93F8735ACD66A087193CE7664757D9B8868F03F7DBC3FC44C1049826B4876FA2FE06B16091E2E78335FA55A839E719FA5BBDC46B659C3BCFD91122F775DF9A9E8D0C43FF9CC2BDAB401B64E5CC35FB17681512C03C14C3B1EDB2A84D8998829A12E1C7FA590B8CE15CC8AFB37253FF5BB78E0B0EDA76AA", + "k": "66D5307AE26DCE8CFFFBBA9BC0B2C66E38B6E77537AE525B3E9A18BADBD72FE1", + "m": "E15BD4603F0EB64E32B3F1D1FA8EF6CC25D673A1D0BB659CEFBA2C153724C1E1", + "reason": "no modification" + }, + { + "tcId": 42, + "deferred": false, + "ek": "E65223F4AB1C53267449A616AA32393E441F346887329AC4B9D006F61A25BCC3779C740EED0BBDEF0A371B95171C70C60F2387265469A8E7C612353FC51968AA43C04D1685EB27364E26065EDA53D2879D36552E51EA01BD818DD57319DFB127F2A578CD48BB6080C5AFE13ABA7808B5894893BB414A532C5223B91EB1CD2392333190054DFB4722F5B548E570FA19C7C485790AC4913892249E63BB324C620D835E5B8C922924791B08937F139CCBEB2D5C9A72F344888BA37B8CD7B06349A310BB71B06A3EACC1236AB03A5FF9B923FC5FADE54C5A1A2E803424CF9C42E5043305127F3EFC956D97946E6BB02EB913D6D21695A0A88708B6CC5611FEC61932774E462C18F4726FE992A301B74DE2F56E9F791E90992C3C109860474FBD6C5EB81CBFEC4A0C7F154E5C2375A2A379A83B4DA4C6796102B20C553F015AC5AC49785138B2460925BA3B156EA337D31214EB942EAA27062EC07328080927DCCA3CFAC51A243645D5055EE0C644428C4715032DB2757AF2AE25D727C78B08D7B59D8841B9D26139C3717FFED92E09FC5286BC1E1D290366E183FD2B5562859FC9C321B73132635A532DC3541096657225082CB37DDED92C8C480B5CA68F93AB53168B1FF2F08D8265AA8035753C96897DD06793A145EFDBBBC4518E0C87AA90A895E6955E5B62929999143CB16B09E26433A1C0D761051AC3776EB126A8C890940632B4C50DA7FC181439A11B483554E208D6FAA627B11DC6BB5073DA156D2A4A08832D2590873672066B9A35C65515B4CB5602753B26C9C865716A6BC3C059272F0DF54DB6395F59012ACF2A783BBB03CBBC3A95F65E04A0BA76149A8DC4A305901418324885D44780F65E17E4C6AAD08355A59C21558B0D206C73F59B5FE49F8C5B86A6747DD9E8CB9D560B22B51B5A6AA82277B676F04399570402818A97881EAE8A245E1B75FA1AC50BB0A952E319E523A292316DE3E5C4AA271265B79D37795AA3596CAAB1072F3775D06502880359D73C5EE0C782ECD04ABCB1255B8A5051CA51EC6C17EC955BB6E715659B4CCC4C74484313C4F5149A288178C49F99586AF54710BA549C09CAC0CDC76D15183C8748146A07C72049108E86C0447B371B844C3715A914E3853F4184337381320A02F94BA1D9EBBDB0033D377254E4EA51AF455A775CB8E85336A761864239426A449FFCB967B82461F6F5A21D7A36DB8B54A5AA3AEB2297C30463064C8AFA12908D4B2D1E5B0F1A23B1D55A5E96886B96C39E10C6A68008B0527703EA2799F42B5098C4178F47490983793DF4CE2B0A2D2B56719256206493C395C54292E516D4F8A5C906736C89810BE0846B8BA654C86A355B56736B9144853286D65E61413F7DD26D1D2ACF6728BF6B028F912602CD132E3D6603DCBAB4CF65B0E961A8B597A0810B9F78A14F0DFAA108811CF22C394F21BFC56155A67B85722C755351576B0AB614B7C9C2278DBAE211E33839B55383C5744E6270C92D65BA82590AC613BF1493768E7ACE60A14644C9A02FB30BB1A6B42A6B69A142BF670C48EE03077BA7A2964020D528C51CB17B0245AF11C4A8EB0785ACC738E4F0CF0FFB838748314CA51C81331DE2596345B44F44BC516EF123CD8997E1FBC93AD95C0A9CB71D46C5535A99B75122E5E710DA961BD873E66DDD", + "dk": "F755A8CDD185E9791ABB61B4028A435B336475DC9D3B20B5FB7C703BE6096C23C2AB95BB71127264E29EF9349001C70D26548797D2C3B6C23D841C1063513738F398C281786C908AD623B22CE690838579A7A08ECB5419366A65CAB11B7B598A38D1A878535819C21E08E1B25EAA50D5740C80D90877B921B522831ABC6EA9F7C5753292CDB21D47402F0E95179D0C3247E16C66801F9B057EEDE48070F456FE58906ECA7EA91ACD9B537AABE8A105B5B0AAE634A1E59E1A456B49215E9C792A0453ABACE0539D14C661ABA1033B7097945BF7D0AA35E9B2E98C9C48232C041BBB32A928AF58613898010DC0892591781343369EA7CC68D93ED41808B53AA1E7C69370281653109BF900A783A231E0E78FB9ECC75C5262D99A5401D974B6069E6ACB7DCDFA2B9E61A7D87117576C1076A497E096382775C47B2C20AEAC91FAFB5709670277B20E88D8B8174A44B0B565D669B108A4B61A22CC53262A79948A3779C4DEF87E8AE7222EA1061C76B052B3B3A07BAB2BC52104D7B093481B6E7A9AEF4530502126E718153F259C6D9142EA7ABD97D9037799368349CFCB4C6AFB541201856B6F8CBC4A6219FC963BA4951AA266402749C4F066B5A1703CAE32831901B6E51215F7F0A5370A6D1691284EC80126710224D42B7671A207C06822EC5420C186D253339D9A058DC552B6F8C38230015605883E777158413F915C3284E6C8203B21F502830B51193B39230A963BA38A3C2F0B122559847972923B67AAABE0A4450BBCE87A1F180A9EFDD8A63CD3ABA8274BED24C4E464A9AB1B893F9C08B6D4CF2F93107CB1148C5719DC81358C07C14D41883439C7D0E5C757815140CC79E1AB252281A4D190590AB36C0945C03EA3369CA244E3ACAAAE9C4BE8A77C9458A28774B3C1E794B459CA0EFA190FD681DB8BAC0A771D40651516073D91DCB763CC2761CBA360EA5B8BA402A2110E3E92522DC9A9C3737FC7D7012C33B928184AE22BA23B5854953648D4E9AF49DC3456EB3A38569F27915ED388AC17D1C71193CBCB4AAB74726D4A324294A47ED72C86D84064EF707A4AD7BE50948D82B671C49A19AA338948947993F6A819A669D9C70F910B6D86325BF3046E6FE3913745ACAE5A0EB1A62B203CC46774CF210B2B19C9C63E1A0E8EA9428FC20E2ADA4BF87A871F7C12125AAA8CF38550AA09EF4B82CDDA83121363345327C4FA9FB8C61877216441610F3368752B16121AD7746B405303E83E495CB8C19C3E32F039240392CA8C4E9EA1BAE0136463D032A3139231E61C9947C987980124B56D19C478A060C3A40AC9AFC311BD247818B499AA3811A2584303A58DD5F82355D963F3C27EA57556A5CC5A369619AA7267CCC49C6138ACAF63BE55E81EAB119C923B1163795ED4901F51F1C163FAC7A3F8C080C40E8F0895CD774B0654B137CB72E244B0B7FB58C8F133A9974E8AB74226F7BE847B5205E80E479633EA574B16005B47512E28F3AEAFB0B0775A1A30664888C45913301832F6C80737964EE58D79103F3BD12B1B704F6E8A770B012A0AAA003990BBA4E092A666C6FB1BABF941B94A6089C775479790A996C37B5E44923384874FC103690763B892702E6832CC3A3F69157CE65223F4AB1C53267449A616AA32393E441F346887329AC4B9D006F61A25BCC3779C740EED0BBDEF0A371B95171C70C60F2387265469A8E7C612353FC51968AA43C04D1685EB27364E26065EDA53D2879D36552E51EA01BD818DD57319DFB127F2A578CD48BB6080C5AFE13ABA7808B5894893BB414A532C5223B91EB1CD2392333190054DFB4722F5B548E570FA19C7C485790AC4913892249E63BB324C620D835E5B8C922924791B08937F139CCBEB2D5C9A72F344888BA37B8CD7B06349A310BB71B06A3EACC1236AB03A5FF9B923FC5FADE54C5A1A2E803424CF9C42E5043305127F3EFC956D97946E6BB02EB913D6D21695A0A88708B6CC5611FEC61932774E462C18F4726FE992A301B74DE2F56E9F791E90992C3C109860474FBD6C5EB81CBFEC4A0C7F154E5C2375A2A379A83B4DA4C6796102B20C553F015AC5AC49785138B2460925BA3B156EA337D31214EB942EAA27062EC07328080927DCCA3CFAC51A243645D5055EE0C644428C4715032DB2757AF2AE25D727C78B08D7B59D8841B9D26139C3717FFED92E09FC5286BC1E1D290366E183FD2B5562859FC9C321B73132635A532DC3541096657225082CB37DDED92C8C480B5CA68F93AB53168B1FF2F08D8265AA8035753C96897DD06793A145EFDBBBC4518E0C87AA90A895E6955E5B62929999143CB16B09E26433A1C0D761051AC3776EB126A8C890940632B4C50DA7FC181439A11B483554E208D6FAA627B11DC6BB5073DA156D2A4A08832D2590873672066B9A35C65515B4CB5602753B26C9C865716A6BC3C059272F0DF54DB6395F59012ACF2A783BBB03CBBC3A95F65E04A0BA76149A8DC4A305901418324885D44780F65E17E4C6AAD08355A59C21558B0D206C73F59B5FE49F8C5B86A6747DD9E8CB9D560B22B51B5A6AA82277B676F04399570402818A97881EAE8A245E1B75FA1AC50BB0A952E319E523A292316DE3E5C4AA271265B79D37795AA3596CAAB1072F3775D06502880359D73C5EE0C782ECD04ABCB1255B8A5051CA51EC6C17EC955BB6E715659B4CCC4C74484313C4F5149A288178C49F99586AF54710BA549C09CAC0CDC76D15183C8748146A07C72049108E86C0447B371B844C3715A914E3853F4184337381320A02F94BA1D9EBBDB0033D377254E4EA51AF455A775CB8E85336A761864239426A449FFCB967B82461F6F5A21D7A36DB8B54A5AA3AEB2297C30463064C8AFA12908D4B2D1E5B0F1A23B1D55A5E96886B96C39E10C6A68008B0527703EA2799F42B5098C4178F47490983793DF4CE2B0A2D2B56719256206493C395C54292E516D4F8A5C906736C89810BE0846B8BA654C86A355B56736B9144853286D65E61413F7DD26D1D2ACF6728BF6B028F912602CD132E3D6603DCBAB4CF65B0E961A8B597A0810B9F78A14F0DFAA108811CF22C394F21BFC56155A67B85722C755351576B0AB614B7C9C2278DBAE211E33839B55383C5744E6270C92D65BA82590AC613BF1493768E7ACE60A14644C9A02FB30BB1A6B42A6B69A142BF670C48EE03077BA7A2964020D528C51CB17B0245AF11C4A8EB0785ACC738E4F0CF0FFB838748314CA51C81331DE2596345B44F44BC516EF123CD8997E1FBC93AD95C0A9CB71D46C5535A99B75122E5E710DA961BD873E66DDDBB5310F78E18E35EBA80A0D5382866560D6E502D58908A97DB5FED7E935FD7178E82546B2BD2675908B124B41D52CB487BD98DF8D7BFF3AC859F4C685F91001E", + "c": "50F0E77866A24C305F778B6D08E9C33CB04C31B98D93A1637D5B2E9BB2443337333E91626DEC0C1C59EF1DBD000BDC394FDB2B6B471885CE4A2777A3E0094122A6DA08400897A635CBE0AF1D56654F4D56CCA59BE3B36B20666036DB3C02BD6E6E605ABC070525756A9CD08767335072D99A067D816DD3438E0F4EA4BA1150A7806E41BBC7521C70B66FD46496354CB47500C28695034480CE91E1D63937EFD2FA4F92FE0B95CB65EA70F610B1B4C9519DFC8C175410BAB2E337F07B3FEF8A8CFBFD45B2827A771EE5D6C2E6A3DED56D21E15563490F763B5FA668F5F4E982823A762AD38B78B573B72C9624798FD092A11EE9A010A31A60F8EBD647A5B11E437FF4502863F78EB2104A270692A541E15AB5731F13D11C20391716D60A912DE796D83387C152E9C171F86CA1EA439B369DFED63C68FBCC103F72E3A9D4C01558FEAC56C2DA7BD797A48257FD342870523C56102CB413069C833BF51AAA31403BE6C2CDB64B2C7A7F6CC9F848139320B974C165717D6A0A891CBDB27EACF96F23FB67C1B218360CB68B158981D32FAB2C12AB14890B0230673A29678EDCBCFC6D2857D2F78EA375962F459213F377E7CAE4DD79393D3C2ECC44FB64091D46F30926FF7E8C5D07E70B1407636300382633E2093FF708F541544FDC5F642D92B78CA167D2A73A871AB4C4D611AF2804B3BAD14CD64AD5BFE9C1DC4E142192A90ABCE2C5A8F6BA6D7D30A19E5AD8F9FAF34AB516A02511EA8D88B1A96DE9F6DA9616550753AFC151E7064E4024C661667807728CF85350B32DDAF7606E4BD491FA61FE05070311DEECE16F30F796E0B6BA179A4D7C8B3756BFF942AD2E412299C911EAECC18A3AC3C68EC76D82195615DBAB4C492AD1E2C7F210923B2E54056E557F78422A90FD647520B32626D017BC661E28CD7FF81492EDC2AB88D10F26B576BC6C8F7A79C5DB1279204859A3C82C06A391214F6331973A0332B27A339540D00AE047FE2C4296352190C2DA7C3B2849AB1A36E7EC74FD641A46D2EC61B3C0D394FB3218C6A0C7FC8B4ECB47E026929E15B0D1CA2513C17564E48543793466D72EC2F5355D43DAC60EC6E55FDCCB27A403148386DBF7BAEEE056AF976B1B4D06111701A3AFDF289A0E3969942CEC96E33C095DAE1334DDA76C54FB67A36735C96AE5DD53D379F5B05A51684D997593B7B25B2EEA0001834A9737AD050F6A7CE679D27D852C0DBF0A6644185FCBE7BE97200C586002206341CE063B042CFF9289CAF378EF0A4F93CD6B0736E8A0EA91A1D4FBB6FF30B255E9B604BB8A5F06D2C7C0607876568465352E76C5A31A44B54B8BBB7F0B016D7ADD77B23C443D3C8B1A7E67C05C80A77E2D9BD0662A37A4EC501482FCE4CEA342BE00321E2968107D0B265F168E6560C427B3ACEF9C14478A80DE557AC0A41025E32D8741D638CC8F76E35AF1AA32728E5C5592122973D1947538B8793420FE6A1FB6877ADFE5677F677761F5071AF5D6A70D706AFC275B7E551623E97EF793B814239DC1E3C53D23C3CE", + "k": "BE4A7B739BBBFEA62A02A555571465EDCFDECEEC83846760A0D39944F99266E0", + "m": "D176C0836015362D1DEFFC1901127B5C41C14AA518BFEE6C62F2EAEA1F226AB5", + "reason": "no modification" + }, + { + "tcId": 43, + "deferred": false, + "ek": "6453B4019A8E77C7607ACC6DF337097A9A10EA4836DBFC7C796A4E73A236069C2005C2BA2D5843AE7A008A337876182C44B92E66EB5146826B246CC7C3F44D40B0C88A98C11B873A29D7A4C7336512E00413EB519AA39025AC463C7CC289270A680B88A7FB9CFF592FD65626E831A019EA9E4C9BB57BD34B8D28B8855616FCF15FD6138947CA36D863510E6B3D4B22B8F812249913143F7CADBF15AF991C7E36C1A610879D9240398A1A1224837F904C65F0C1527BCCCE8459B594739F4BC243D2360CAC320AFEB5B2F5A310C90B42D3EC369F64C0FD2118D0359DBC3141F602CA8D7507EF830F1E47682068ABF22593563A071653ACAFF19506B5630F2B6401B78953B152C7A78D33216695B7778F9467FA239E4ED089A1E6BCDB682C4EC1B7CF407B37B0882777B12436063AC0C47CB7A58BB7CF34C5CDEC291BF1EB851DDCBE42535E0639580B191CDBA9AB22F0243D1334048964968941E7140C44A1658FE20C8AA023D2CB133D5B06FFD99FFD4751EBEA170F9C30BAD8CA39C64C7FF357F0FA2585BB13645682DAE24518517545175E38D5276FC442FB2143FFD2A7B61903CD72583FC64DDFA654081A4533457D36A366BA538B6772C5FF11674F0A702340C542357B80B2C206BBAF2CF6406F339436A7A1050792AA674C2E9C9B7986404C94CEEFC343E0781155D8B737978BFAE3C8CA64723D0656E9B89D23568AC6658F0732C332096A217CC6FA3A09FEB16552F5C982CA6B540C3AC96C8D0AD576820CC46DD60EC82BA0CFC14073424902578AFEBB44C321A4A6B7AF9709B1D9F05EC9BB6B928C936B670543E1B05E649FA7C2B3B9FB441C976FDCEB889FF63019F26EB2326F36F82231A68F230C9BF384710E11CCA858970A33445FF05CC4399DC28B285857168DD388F0B95B7E3B1699830950022FBA81984AA1B1540959EC1469DC696D7BB9A3C42153540B24A350CFCCBC33E5D9136824500319ADEE626BEE22A53FF8CCE2FB195D38257DDB8C305949D720342EB58AF72236F2275F98D335DE35A0C0C66BA752BEAAC32D113AA43DA092C4888D1750A59BEC4EB14A94A84C9947660891457B52F1BC3EF33C951A1DE64ACAEEC99F7795B8C94A0320F40D0ED92EB7FA346E042453995F2394B714A372E6B678C0BB4E04670B347C156794672FCA87966B26F0EBBD2B8304C9B6560459019ED95539C7C0C20999971521F8F7537B13937AEAB1E23736186C672AF0B084D4C5C3E1887BDC0BB281B7DB924BFDD9034C6456C427B9643C89FEBA3440947DD6B0B4BDD54C38215371E1A74E543A6073CB46118DE3B2BD1154AC536652BD2666F5F710C03CB6ACE948FB61692FA3A3E2EC4E3AD971884412640342BBB4C09D1C11856825D79A8E5249243062033E379DD1EA6526676A2492520BC55A4533CEC47C54CDAC7483500C0751BA84F0CBB020CFAD07B6F4E893CAE78DA0C7082F7A9C78D2BAA064C33D20644431BEDCB9B493D05C13104B88870361433490927B015261B63B1ABF2B59777359F74BC2597238DE6729669383E8188C0DFA7235D935657B936101BA4DA9CB90F1AED0F06C03700574B99159FC3E59EB3258A9BD5F47439B45A30163309A6A29CDBBC017840C5655E3E8FAFDBCA14293B91C07EEAB7E6C066A6B8BA7EC5FAEC0350B9C887B18", + "dk": "A996A675909C3F1B1B676B54D0F29769F24B86FA482FD3127086C82E336C9D606B7CDA5F5002C6E27AC69DC26DA9D90BF31561C798CFB9B78B37F788CAE520116A4FAA4826765A41A16C650A1C33CFA91311682ACF0144825370D76657E7B18B87233A0B1393BA92022AA22D28D04B4A302380D780854519C014862545467626B8F7C0228E19960C528D4A511259C7B8C92A5C4E7060A76B8182A0A0ED5B6AF6F920FED0B1DB4C76A4149910B755D69A43217B942D796B9AC549ED9A464799C25AC0B1EE229F14FB485A795A2E072684CC33C8F20B49862157351A0BCB37932B7C4708374B7481C2A5C19DC752164235823935B96A9AABDBC4AE88C4D87131D3131467A8C969671503CA85B65B229491A33B4789C41722D9F10F97F335C2BB86B7945E0A489AA7171C13817D04C4534D324ABCF0CC78957A82214DAC93667E92CAC094003C4440C560CCA698A2287BB0A19CB0352C951D238D13BB89F9AC3AB184A2664423281681E8813D6B433A8CA7BE7B3C99368A1DADBB984FF298FBBB2645C11D6576131DDA12586C6DE2539641FA21D4870D471C3702A4C3376355C1EB42A90B5676756905C2173BCA5775192069382B3AA4CBEF7C95CAB35E44C49981D6ADC8C68E9D41109F5C18BBD80D13E80B661371B0CA6B48D19886E610FEB6AB4CB500EE0C12A7C770EA6B16F80C4D2EC016AE26B02A2520B5692437C80A857A09A6659218D147923375203AB1F2799462F28427C01900B08A8307B5F3BCBF833104A04C7B4444BD069BAEFAC4A271537702514703FC2388777CB7735AAB3684E03741F1B45261CB53ABC800E9F8AA77B62C7A805B9FD8895B568FA1136CE80A6E47D470B26A0ADD4A69BB33ABC8A6A49D61525866256D2656E46827BE895162A01CADBACBEE418695089BD9F1940408483FE87C31A68FEB4C35AA561827BB49E97776C64036379B16E719AD10F02BEC795760BC167FEC3F7B571D88075B161862B6C556B8C87B3636398D32426B1A11350203B93112531BC8AA0ABD23454C9D863E1E150990918A96B2B3A3A1416B0A8C2968AE5A110DCA445F515A15373026138865F5C64F625151FC546F9DC1B8A2F17C2E719BC97659CD255D34A3A6E28B8BAAB1C47EFBA49CB4B1220142EE843E24402462E785B01B664854BC54D6205312B6B70117C5C1C32D91C7B8032CD46A83B327609AD91519C9AA203A0A0B9C36B3671AF62890F301CB6BD4A3D39175E79A572253331144144BB2133F924A3E88142FE04BFBFC15EC84BF968A2E9A2459B109144E0445097349EBF3AD8E0C87641C74FA71699B687AB505B43CF0A668C7B5C4BB1A4D676081D8C1EE7B8A881791B9D16F92116C5D786B1678AFD49A761D9AAA33754E919972DAF27CEBE3CEFD3C90072119A78387FB056D98D41CEA45648CB5B87D217DE730703CCA26C7726F14CB9FCA3760646A627B255EF9AC156B6C1721445E20417CEFB3085394A3D94AAFD1273E4B75A5C340274160A52F26C376A018E0D880A578A24A8961D9D443A5908A32859F2A9794F80C62DDB001C411965802C6A0F10D572171FA32A44BD56ECAE78B7FD34492E28E61C47C8CC66686B401EC082013CA8CBA84545596A9D781786453B4019A8E77C7607ACC6DF337097A9A10EA4836DBFC7C796A4E73A236069C2005C2BA2D5843AE7A008A337876182C44B92E66EB5146826B246CC7C3F44D40B0C88A98C11B873A29D7A4C7336512E00413EB519AA39025AC463C7CC289270A680B88A7FB9CFF592FD65626E831A019EA9E4C9BB57BD34B8D28B8855616FCF15FD6138947CA36D863510E6B3D4B22B8F812249913143F7CADBF15AF991C7E36C1A610879D9240398A1A1224837F904C65F0C1527BCCCE8459B594739F4BC243D2360CAC320AFEB5B2F5A310C90B42D3EC369F64C0FD2118D0359DBC3141F602CA8D7507EF830F1E47682068ABF22593563A071653ACAFF19506B5630F2B6401B78953B152C7A78D33216695B7778F9467FA239E4ED089A1E6BCDB682C4EC1B7CF407B37B0882777B12436063AC0C47CB7A58BB7CF34C5CDEC291BF1EB851DDCBE42535E0639580B191CDBA9AB22F0243D1334048964968941E7140C44A1658FE20C8AA023D2CB133D5B06FFD99FFD4751EBEA170F9C30BAD8CA39C64C7FF357F0FA2585BB13645682DAE24518517545175E38D5276FC442FB2143FFD2A7B61903CD72583FC64DDFA654081A4533457D36A366BA538B6772C5FF11674F0A702340C542357B80B2C206BBAF2CF6406F339436A7A1050792AA674C2E9C9B7986404C94CEEFC343E0781155D8B737978BFAE3C8CA64723D0656E9B89D23568AC6658F0732C332096A217CC6FA3A09FEB16552F5C982CA6B540C3AC96C8D0AD576820CC46DD60EC82BA0CFC14073424902578AFEBB44C321A4A6B7AF9709B1D9F05EC9BB6B928C936B670543E1B05E649FA7C2B3B9FB441C976FDCEB889FF63019F26EB2326F36F82231A68F230C9BF384710E11CCA858970A33445FF05CC4399DC28B285857168DD388F0B95B7E3B1699830950022FBA81984AA1B1540959EC1469DC696D7BB9A3C42153540B24A350CFCCBC33E5D9136824500319ADEE626BEE22A53FF8CCE2FB195D38257DDB8C305949D720342EB58AF72236F2275F98D335DE35A0C0C66BA752BEAAC32D113AA43DA092C4888D1750A59BEC4EB14A94A84C9947660891457B52F1BC3EF33C951A1DE64ACAEEC99F7795B8C94A0320F40D0ED92EB7FA346E042453995F2394B714A372E6B678C0BB4E04670B347C156794672FCA87966B26F0EBBD2B8304C9B6560459019ED95539C7C0C20999971521F8F7537B13937AEAB1E23736186C672AF0B084D4C5C3E1887BDC0BB281B7DB924BFDD9034C6456C427B9643C89FEBA3440947DD6B0B4BDD54C38215371E1A74E543A6073CB46118DE3B2BD1154AC536652BD2666F5F710C03CB6ACE948FB61692FA3A3E2EC4E3AD971884412640342BBB4C09D1C11856825D79A8E5249243062033E379DD1EA6526676A2492520BC55A4533CEC47C54CDAC7483500C0751BA84F0CBB020CFAD07B6F4E893CAE78DA0C7082F7A9C78D2BAA064C33D20644431BEDCB9B493D05C13104B88870361433490927B015261B63B1ABF2B59777359F74BC2597238DE6729669383E8188C0DFA7235D935657B936101BA4DA9CB90F1AED0F06C03700574B99159FC3E59EB3258A9BD5F47439B45A30163309A6A29CDBBC017840C5655E3E8FAFDBCA14293B91C07EEAB7E6C066A6B8BA7EC5FAEC0350B9C887B1835EF87CAD46B39215CEC187D9B96A895FC9A8EC843B7CD3531BBCDF1BD64A22D5001876DCE843B5761DA9110759CDD04CE17B8936541525FE830CA69E53E1655", + "c": "ABF144FD5F6B1CC8E11E1405A8AEC1039BE0D84CB1E4EE622E50F721F9C76C74AF363507C354BFAE546030A8BF746315F1B223F2092AB783CFA62CF86C9E5F504BD489D8C6B009D1EE77B082C5112CE2675990F401573FA6643551C6189B8545363835404066736BE712553FC8408BC370DB3603B086198B338C55368F0342B617A6314C4147C27D75925591C30BB2BD39BC34F0006C056BEDF6D072A4F3719C5FCE7AFA82CAD9A21EB92A4E6C833318671EC4D262E4DC321164DDDFAAFF6EA91514F7942888C0625DC03D16878DD5F2A4ECBD0B4C508849D20E98D6C84D0D2BD7A7F1E70687EE04F8EA275D8BE04926F3213055107135F726DB314F6BA9E4FFAA23CC074BD50A5D192C25F4354082A7B25C128F3FCD87FC6BD842BCF0E8A05AD2DE51942978F5B2B322D5205095570FB1855B7AF3AD9B5A6FD6CE7D418921EF31E15928E733D10F96553401ACF750001D7814B4233F7A512F2A7F768C189ECCB5ABD0206F7463C812E0186B60D9C06DD93DBC9DFF13B3B39AB3610C03184A4FB2AFDFA964BCD95C1DC8692A01EDF4C22F0D8840D997D13FE228E393F47DC5591E68F64DF855127B5951E1F8259CF40D9EB5281781B5E171B908CFBEF4FCE13BCC41975890182AB74E9739D9CB4CEB30D600EE3FA70D858D60CF89D795E583BADFD5EE032653C731C52A67F401B2927C7492926651044608727570FAA99F618678000A61EBFCEFF973E40A0B56B961CF24959EF4E324811A4F1EC878E41B386F27A13BD322C012756B0E29ACAC140641B77B1986BB7C41D3DEA0E38A768475C3D6C6EA3A6851CE4578893592A5EA633C7C6E6144BE6DCE7B47EA653B8176C84E2754F3AC6AEF843A5E759626D3862A13B85C222A6E5E0836FA4ABE18DC57267BC77F2187258CB81D24E62CF972F13D74C56F970E4BB29D0D0F39E35E61D6DDBCDA0D90549AB5D87C78F8B7F7543CC95B2AECB0CEBA735A8EBDB8F78BCBAA41A27A9AF77C2F9EEACE5176C12B340ACCF63639538A6308139C1D9D4A68DCFDA14F2AE7239EA6D0454EA8A1684455DF3B57C4581F9E5B243F4A3A7B74537F8F8815B30758DA124044D9EECED7BD9AEB699CEB3D0C708D76F4176AB94DC47B6BE84AB40E677C937146D5EF26F854BC96C0050C2C7B1A99DEA2F8873DDEB668F2E4129C1159D8C4312E6D4FA1AF9E5739B04416B7E54AF21EA1864037B7D74094F970E9B7914066F7ED2220BB8CE88594050A8D20EFAAE7993E3CD4C4206542047A0B8D00DA347D8F97066BF9EBC2D6F77A68E91524809CA14E5B9559098A25F2BE13CF64F97EE4B9277C798EF544C07114E1B4ACEA057DB041D8006561E97AA4C60BB5E3E84974FD51A8B12254950508272883A06394EBD680732F9A0AC66DEFF31BA045174D2FA5B15D8D9E326CDA635799F38A5AE0D13EC12145B3EAD39FA1E8F6F97AAF5F437F28936362A235D00A7C85A4AA6BBD73A998347F06F83F1EA9F71F318B2EA96BBDA89B9149A5765C41D018BBF2190B3C6C526933BC828EBE4FF35B", + "k": "CC54EFA4BA6B3C0B651258EFA6C6850B1B31FB159C282D6F354DC18C8749ACD7", + "m": "4E302EB2BB5392782E7820868DEDB61F5A6AE558CA307A01ECDE4970E43EB448", + "reason": "no modification" + }, + { + "tcId": 44, + "deferred": false, + "ek": "409471E1024944D5203F82C62D1CA67E96567F3A525F6AA22683C4D537BA87DCA66864C88F292630484CE6C2592BE194A59B9642B0C0C1C4771DF87710F11FC8898573BB874965B774C3BCF30920312BC3C1945876AC6CC1221C9019677087951EF43031373BE34492CC5638D530A4D01C86F9B70296162950D92B5D97724BC1B7E9056C78D16290F3BEA459AC21395FD8A60EA8551B5D935510557CC36CC5C42605A4459CD7CC603408C3AB2380F7F00F44EB0DE7457E6F40B8DA2042F34C18554606E8A274FC8B6842F299C1E80068F11870907D8D44269BB7789AF0C8465B72CE64B5431A885A00B0C200102C811E8ADB7893502277FB87213AA89051852E896B3A170A33CA8F44A7367756944760B1D3C37318AB76EACBB47BA15DBD83CF8151BD2E3672934702C3A21886B27BC3506DFA8CCDB77C818734A18230868092186431221E3020157374ADD138C8F3C69D7709BF60C5A06BA3E410AF156B2175020EBD7603AE10C76DB7C2CE066A98A0AD4131781CC30311B38A78CB809BA48136009C36144B47AA2052E59F16E0216561BB42062817C67D81C96223C37DA9332B261152ED90350BB2BBEDBC438641CC082C8E4A4181628253734CB262061E40143BA11BB5AB75A89270636B330E922C5298068C85C1352FA5A133C3900A762F57B831A907AC37A6C9CBA9C915290E10A447A8B454A0F735DDB8852D79B0FCEB207C25568F44CE9568305A9362ED584D77123A3716A667CA2952CACFD7382303A69A817B17D895441D0A9AE1F71ECE1277C0432A7FA2A63C81A545910B4B212F1D983DC634313BC4B3B1B39190438D47B16747FAB48DE4777911B8D3FB65FAC68CA096919267783B0497868A9F95E89A1A3B2861A3BC89CB77F6976463CC7B1CA6CB8D447AA65463174A384217CFD41B4B80B7AA4072B10BCCBFA73C53E45684C542B031288C1192AFB1077B4E2B560E248169C6B741904304B06D23C86C9434AD64C67D92FB872D28BF9F745F2CF210D6D0C9C72176A3242447E06925718FE6530E2B5018833831819C23D3402BF9DC22FA7B1B754C6CD5A5C610275352D8B0A04159713C26422C688ED70B14209DA8EC23E8A2B285D61B8C5993739707386B4A084B22F70BA9EE3073644521E9B60D77755C30B36180B6B6A64A94ACEA2AFAA784C53C0C78E79203F36E98016CD1D109E17952A49021572B5F43857FA401BA617146E09450C8F392E423AF9FA294B7E2C2D772784B157FF591A4A13919C573713312291BC02F0F0C93721796477608E8E69FC64262D404C95DB98E548A767A184047A92C8FD8AED972945E676D946AA0DF5A88C7A13D03E501D228482FF97D62E27529372CCA9681F0758C2B500BB5D691D1734859B93E8E177605729337B39860E256D61C75BD462A6607692BF74A4CCC346240058B766502E740AF864531301226EBC3B8B5B1378846190AAD61C9BEF1362537606DEAA531EF97582DD1551E7A5F960B8DEA7A1815272145B25C7D175CDB568A68F05058F255B5B586866278F3AA56568179DF4B848FE535132B7C52D3AA3829686EA7CB6FA1BF07099F055416B8041AA9E2522CD23FE29981B06B6556432ABEF02E0780BEAE777D26FC062D94F1BC4C683AD2B92303D532101461FC0B8115556C3D2F2B855D1009704611", + "dk": "895C17908C9C3325068A545C951A7E5A2970A205783F8426BF3359F556014D79ADFDBB03CDD8B2E56BB3F8A095CD143B2D73AC87D997DD64633C0056203971E38A1C1E268F1C3A0C19D0A573F9B6A0401FD6FA93B65BCACB7C5E7FD660C4F7802D99A01B41BE77C776240737BD2234BE38B655857AF88AB3E40294355A5B485316A2109447606B3F86C512D726F3B915524589D4A3929B223D9B9157CAAC627F037AAD467C256A39484B3C1F3CCAC9F20F4A8AA840009998298C7FFC453607B1E1F43F0F740631B051720A3CA1392A34D84C06AC135B3A22AB277E51C56664917254842ABB134EC4576D33C69C7C66211C0B40C6912547EB5B9DCA0AB2035552956860DC230FC616940AA8B3249F8D8570F763419DE0C8FB1678AFEA395A553D1E3592DB6B4766684FF4421E97CB3C6D12C7798C63EEC9CA09868D8290C0A8ECA681AC1280958BD67A615F947625C35EE0C36F15D6B6EEF79FBB811386A9713A78B9FB581A6D47178A0A3C8D11B23BF6A2D997BED0CC34662C109B843C455C87ECE728C790AD24E690376806776A0F1AB9CEF70C6E96B46916321F77251E42DC7775BBC8BA5C295473186A7A277B2561F0901E96602E5ED31D50038CA839B75A3164AD17CA92308F3E75264A6C8EF0D940FACB9DFAF855283551609B4B2CE0329BCBB76A0710E4807F95169439C6AB571477C4C485B73503F87157B75418780C4CADB54B4E2CADD6791688E867FAC57812671D31A92F18141AE033570D21A12C1420733CB7A9835B60AB4677445C49756DAE5477F1D400FAB10C5134092AAC2C0D42693283147E033CA08A6672C4001734233F496966C214E7A36ACE327AC883C944446DE2085233A84D18C6A24BA95B3684CEE5BA0FA30A2C1A483EC4668B74C356CC97C5995247AF39549C92BA9D544580579B1E3B49FC2864D945A7DD555D2F5CA42A519615AB75EA593B15E9BCAE108A3B711CABA18E58ACA44CF2BBEF8C00E99540888297AD37CFEE4BA60F843750AAB223889AD7148164F28330926368F009CC440801989BB4003FEAF3A25B76C6E6686C06E3889DA28DC62383035042F1E64196560775C3B2E6CB667D30578BFB889CE194CA582039710C5D673B2983A8004BBADA80627A7A33C3B524F5CABFC88995D99A58709A634398505D77121D76ABA1FA8B12F93E171321C8EC7CD2C996FD714D07A9B6FFB389A05C2761C45AC9F3B35C24A246E348AC7B0C7BA347589041EE24BCA378888CB6471546CD9E04A68469956BD59865B6682011BF1FE71226077BE7E9C81828AC7312417E46A00570A6D65C4FC4274CC43B73305B43EC8C96CC46BFC898535CB578A7F483D63C43DBF36F3D698613ECA11019581301AA319BBEEB29701ED472955B4C453110BD381F328573EF83677C65107BEA546CD930ADA0CBD153ADF7C7986557438CE099583C6F517C99AE62BB35769385459FF2FB1C38E130F7060AF97333D38BC6725374EAE980FF69046E905DD3E33F4D546C3AFB6EC146CF85A66366B700CB544FEFF9439D9521486240DCF31B821121DB914F107B32FFCA171B764B299C4A5DE793DB42AE20505381B820E7970AFC2064C80203D9B63188DC6689D67B009BB1B4A912409471E1024944D5203F82C62D1CA67E96567F3A525F6AA22683C4D537BA87DCA66864C88F292630484CE6C2592BE194A59B9642B0C0C1C4771DF87710F11FC8898573BB874965B774C3BCF30920312BC3C1945876AC6CC1221C9019677087951EF43031373BE34492CC5638D530A4D01C86F9B70296162950D92B5D97724BC1B7E9056C78D16290F3BEA459AC21395FD8A60EA8551B5D935510557CC36CC5C42605A4459CD7CC603408C3AB2380F7F00F44EB0DE7457E6F40B8DA2042F34C18554606E8A274FC8B6842F299C1E80068F11870907D8D44269BB7789AF0C8465B72CE64B5431A885A00B0C200102C811E8ADB7893502277FB87213AA89051852E896B3A170A33CA8F44A7367756944760B1D3C37318AB76EACBB47BA15DBD83CF8151BD2E3672934702C3A21886B27BC3506DFA8CCDB77C818734A18230868092186431221E3020157374ADD138C8F3C69D7709BF60C5A06BA3E410AF156B2175020EBD7603AE10C76DB7C2CE066A98A0AD4131781CC30311B38A78CB809BA48136009C36144B47AA2052E59F16E0216561BB42062817C67D81C96223C37DA9332B261152ED90350BB2BBEDBC438641CC082C8E4A4181628253734CB262061E40143BA11BB5AB75A89270636B330E922C5298068C85C1352FA5A133C3900A762F57B831A907AC37A6C9CBA9C915290E10A447A8B454A0F735DDB8852D79B0FCEB207C25568F44CE9568305A9362ED584D77123A3716A667CA2952CACFD7382303A69A817B17D895441D0A9AE1F71ECE1277C0432A7FA2A63C81A545910B4B212F1D983DC634313BC4B3B1B39190438D47B16747FAB48DE4777911B8D3FB65FAC68CA096919267783B0497868A9F95E89A1A3B2861A3BC89CB77F6976463CC7B1CA6CB8D447AA65463174A384217CFD41B4B80B7AA4072B10BCCBFA73C53E45684C542B031288C1192AFB1077B4E2B560E248169C6B741904304B06D23C86C9434AD64C67D92FB872D28BF9F745F2CF210D6D0C9C72176A3242447E06925718FE6530E2B5018833831819C23D3402BF9DC22FA7B1B754C6CD5A5C610275352D8B0A04159713C26422C688ED70B14209DA8EC23E8A2B285D61B8C5993739707386B4A084B22F70BA9EE3073644521E9B60D77755C30B36180B6B6A64A94ACEA2AFAA784C53C0C78E79203F36E98016CD1D109E17952A49021572B5F43857FA401BA617146E09450C8F392E423AF9FA294B7E2C2D772784B157FF591A4A13919C573713312291BC02F0F0C93721796477608E8E69FC64262D404C95DB98E548A767A184047A92C8FD8AED972945E676D946AA0DF5A88C7A13D03E501D228482FF97D62E27529372CCA9681F0758C2B500BB5D691D1734859B93E8E177605729337B39860E256D61C75BD462A6607692BF74A4CCC346240058B766502E740AF864531301226EBC3B8B5B1378846190AAD61C9BEF1362537606DEAA531EF97582DD1551E7A5F960B8DEA7A1815272145B25C7D175CDB568A68F05058F255B5B586866278F3AA56568179DF4B848FE535132B7C52D3AA3829686EA7CB6FA1BF07099F055416B8041AA9E2522CD23FE29981B06B6556432ABEF02E0780BEAE777D26FC062D94F1BC4C683AD2B92303D532101461FC0B8115556C3D2F2B855D1009704611FA9DC07F088B86A0879CEC27AE467955EFA0EE0A57A996B3B2846ADB293805DF1C399367603CB39ADC06F676FC6C04ACC64F24D88C1E3F36191D5294C82C45A4", + "c": "8C8DAB2B1D37BFAB6EBC4E502788E061EA1097C8708ABFBCB2375B77B25A985C608D83AF0A1049594D56F920830B98292E64DE1D6F6D748F543D9EF3847492DAB472D7C54949CEFFED40434519816E9C9C1E5477C209F4518EB441DB2036B7C1A4A26833A25BFAA6FD5DAFB2F39C04266A0E53F1E2886137943AD5EA9996206F10D5043C8E3BDA12122BB4419E1D9192285F153999A270CCB7BF0EF68E638A95F3BB416F670A8D13A4625B4FAA29B0E6DFE65C74F1007A3716113A3F194C6319D5FC3B354E2EE56C9C2CCF256A2CCB3B3B0E5BF573CAB638F826AAF85291DCBC01B763E83A834B1423400FC170B3112D2CB44653E6C17684CB2ED01CB247FF1FF1BB242F2519C73B41969CF912713F8BE34D5F9EDF33D431307A0F42481CB904E2A6A7D062A6E0A4CC2E63699029615F5F3B35361369A0D827D4052D50A8EBDE1469B1CA6546DAADFBBEB1424330BFB488BCA9B1B594E5E2962BF10F000098C2CDBFD9249A65DCEE7A887FBF19A4CE484AA3ACC53736FB24DC1DF4D54E6E4B37BBCACAD87E9E324BC5B48B7F8612575EC416219DFDDD225A13BACE2FC7498A92F6B19DF2ACBB8408259E4058A96A2831E71DC6DCB396B350DCEC403DDBF3262BC70721F1B7EFCF8653560189B70A78F4C74A0F1DE28490F9ED08E0E93C7AABA92BC52384DCB8D24B2B998B1D4345C47778832355A7B87C66987C53B0E0F1BE3A163CE306E2A9A579291C582E7FDB7A8845D85C6AFA78361F8B1EBE36D3B65D6EEE875363F1087DAA2A04183AEEEB2F65643E4D75217C8EEF3438052049C581187E405A792D1CB25D2BAC78B2F92BF8E90B60841B2CF13CB2439F2CFFEC0927B1C47D6415ECECBAD2BAC55122BE81C4C745B18111806670A4BC77C89B25C0FC79249481A6619877067D2C7B06350BEAD29AA0DF24D966F7BF5D6B46A2AE89408895121568F5CB93575A33E5CF7304A162C89AAE63C9F044D5BFF63542E60140E25EC9AC5A653CA7B2C8CFE2904CC4E829B32F3382E5CEC4D443DE510D970D17D42333B8951CDCCDB40FED38118AEEB3AB13A1AF93AD106620CF5538007A92E3354B6EB0E8DDC3A733DAB98BDC532171B4A44907E444BB13F44B78E5DA4BF142C4A8BA8BEE4CFE55045D42517016F86CD088C992AA15486A4236C55FBBDB052F26E15AF989A2045B647F5CAF5C970EA516696B237080AAEF314A05E76064EF8DE9AF726147B24BA2936F92429FD7BA2DEB5D1D955C73F81BEB2EA6471356E3E503A6C04BFE39E3CD98F9A1C8F10BA19C454D2053EB67B6CEE908A05A5D08B5E89D2B539D2123EBCFA9A8F9DDEDE7E6DA52B992F5AA88339BD16DF594CF53E81B6550B49544A70A1268D36A43AFB52FB0CB164E183FC7578A1CC5A1F162A1F0C86017E5B24D07BF9B554DF40916A35E708A736F6AE1732BE39F11265BB083DF21B41F92824A44E9A6CBFA9CD7803261085965F2B7E6561087041ADBC58E00BBC8FC111D89C36DA9FC71721451A106137B2D2A221D3F9A8E09171D64B98CB1EF4F1C", + "k": "C26DA6A23332B20914F703E7CB237D84F807CC7248DDC47599DDB0D40FDC1FAF", + "m": "7B334E045896C00F90D811489D491E8D72C4E3A22ED831C019FD4BD967B7A802", + "reason": "no modification" + }, + { + "tcId": 45, + "deferred": false, + "ek": "D0F1B584A87CBA7409D8B98B49B1332ACA1545B29FA2D42BC537CF959C6182305C95E06F5040B447D00737B0BBBFD9AB0A6062FAE209B24959EB83C2F0C5A2D8AB36161B90E2A92C5939059F8B9586F071FB1B26121604D5252D136705D33911703B91DDD85ECF80A7A1741C29FCB06F321E8BDB8166EA8C899B8064B69D77927C0B503989101F1A6941F4DAB06BAC9973378C2E6B3B19D9506B2C9A6BC29A51582C8B47B46306C1B35A438A097B07405645FC66C2660F4C14457A41B91907CB2864338C09C0CBAA7A877A9543F775950487DCB8CD8A105822B93882271A17B6936912A55FB4109B45B09BB14EAC2134E0D7471DE891CA984FD7B194B1529EBDA3CE0C24C1A9A170D76145215C8CA7217A138C9FB7DA8385E8A0C56B5342DA66F9FAB03AACA4E3A1BC5495C7AB0AB0E451A22D480B00FB29CE641C46E7A5EF16867101A26911B0A49140F70B8684845850DB8E15CB7BF842CE712480B19343077674D8A7B7C47A5E1170A629E53ADDD10F4BB35A601A843B49391D7337D7B3B592182F3A1636E4A7CEA14676A0DC508423B94B115041EA5F925BA0F2FA8536AB11E6D451321450CDFA076EAA3577D605A7E0B354754B92F1B411487FD8122E8DAC14D8464EC4331DC746B5693451B52878923649144182C1F03DC4281A7991C60F4A4076117B50C21670809832F3A67DC82E448A49AA3A2002B1A8667CC947253015A6A88FFC133554746256A103D11C7BC98013264D5EFC15A0B2825B37C356A96F0A5B701B4CBABF57640F2A92796C5663570B30FAC65BB79ACB59CE5C4CC7757920496B85CF938992EB32048360559745368854EC7A85A8E862A973AD50D67938265D3541161BE9C4097323F5E77EB8F66887A89FB7DA1A2585A4DD52782AD221B515A1D37778B5911AC7C90FA7722FD5A9484486A6210157188ACB617413516955F5EB91D2691E1E38CC2D10638330029D033005A88606E6A941962F3FAC506FDA5211609138E503E3382BD71640364066A2C27780898AFC1CCA9509C23F022AA77546017B1943360FAE24A54A0B965BAA7966F45AA7F3BAA7C6271CD28D4E0263BCCBBFE4FBCDFFE05269B048E948BF2EEA1E3C1825FBB3AA8F182B2B7BA52877B2304434DCD561BF365BCDC6AE0960211BA14EE1F9C8CBEA3750472A02271BA7E79C4FE6C9019B25470962315C4F50332414F46233A354928980A7752D7A07215EC24133446521DA5E4C50B615AC4E78F07B6EEA141AE146FF5BC2C63167483CCAD311B847996339AA50B2C237B4486E3B538C75B14969676465F106B9069A6F627938690139F011F5FA7D1832B96A0309FC85920E142C9C57CF64852E4564334281BA63068C5666A71B194319E99FB024AD33F879D08C16743B34038AAD20D2C84CB7440EE04C1AF4B944227FE94B5D666C3E51523248D913B9A3693DD1147AD7064696CE5B613DFAE1B83A207742264E878C7804D603BDD71E56C5CA7F887158E805161C959F072CBFF82DAE020C80135A8D1890F1A9A839032B0D69B9A7A97785DA5C201685C683844DDC99F4A97E00A063E15122AF22C27430328EA1435ACB07ACDA0A3B6B784EB19E30E08353CA26118AC4D5C4A218A262C4BA135AAC24F1EE7C5EA0E13C86749E5E72541CA6CAA1E1C05174B08745437FEED0B9", + "dk": "51901DD6E7BF9FB37046292E2CEA4037DB8874DA2A9B24403D879FC8104A512C52903CA118E159D235C9344B815908C62C99AAEECA688F8756BB844AB02A15F7380BF92BAF4DE4CA5BD05F5E66914C136838231C563CC1D1729B026190D5085DF49C01794541408A4C50042636804E16D3AB3FBACEB6798119436D42945A25860825025F21279057A775ED835510E2B99439CF13B7261A83CDCBE39D62E42DE49CC96C45AA6E8018779B372FA0A1661146A2A33924298920DAAEE3E81FBFBBC5EF514B0E773C35D76D8FD413E9D4C07D60212E91B06EE1B795E3B8734660C4E3C44F745CF2058AF3AA5A7045317395078193C53B034A621A9798208FFEAA3B53802554AB077AC3B59AD33CF7782065F9466A782484F6049F54BCE6E85B2C957460478B7070860F108655C0901C26ADFDF553755B1CC1634A2FC820CE1B3F190C8A81A78C6E0789478B1D6F594300CC0C91979E222AA9BDA73F1C88286C94472944AFDC97326904C982855EBA982068B4A88BE346D939A2C4316FD1268E6E0200D40C7A7F701003028F1A05A50A0355F8D2CA5FC074B7CA4D7CD1087EEC90FD77300F73214C68093DFC4AB81C2B718B278A411185B9C86C8237C3A402809C632779136C641BF938CA3650900B62BF2101B827133C014398C503A7FB1B98C23BC5F492AC50B706E387993EDA7707B9662F180AAB380793D9B77D0006CB4BB83A1356E6033BECF84111A89FCC8A9A1E313A1EEC78227206670854CE4C7DE9CC87728B8F94F647A5147CC7B5B569D8B1572468D3E012FC3558A59C6BB808A1E7F1400B7CC92F1C55FA9C6DB91B884FE4C60F77A2C77624F5185EEF787D8DEAA066C50A4E71A1CBE964F06674EF8730B4E8BD599496A6322F25093321EA618B624D7CF15D2E18426842BE2F289AA4515D86CA89A077B254D95E037853780A238DECCF91A1123D3176A68C40B72085DD5179A49207B2A7AF7FDCB49F536B8A4884DF25684736BBCD546551589576499F7AB43625EC30F3786214961C89E32FB2C13E306B8C85A64D68A063B43425110420FEA50222D9A78A0409A550A4CC633DF75843C2CC3D71CA55CE012733997028E8778709B30A4C03FFBCA251990A8DF57D22B761978149DF42C8560246C72CAF55448B7FF114D2245CC58453CF836E40A851D23C754DC66574604FCDB49DD5F74C1EEC429293C3394CCE920A9522B598ADD73C8BC8C71E5122369B4429B88B0FD08DB19690C65518C8E243746734F6649C2DE845E19A19E594894D8B5382639AA87C9806525BCE13CABCFAC521884B4E2B26BDE7632A9A8C581BC42F87241F1408325B16C46532D0522F51E7B3E7E2A7F4532A2B4B8710589CD6B32EA0C7BEB60194CE9372A0FA79005214FA45153CE556E724A383AA5DFAC973EC73CD7D6CA1EFCA49DFAB32C32B0EC27879ED18932140AC340006BC5CB547A532DA668684218B997325F206AC22D169FCE0BABF6A1B0336B1CC039776A7A33952ADA8E54706FAC9E4B295ED219D2C334A30149647720F025920DF980DA164B0FAD128D415652F3BB8DFB0AD6B23A8EBC776E1035E863ACA12C9497F189185C7C2591072210C97BCF833ED28302E388247D325302394D284CBD0F1B584A87CBA7409D8B98B49B1332ACA1545B29FA2D42BC537CF959C6182305C95E06F5040B447D00737B0BBBFD9AB0A6062FAE209B24959EB83C2F0C5A2D8AB36161B90E2A92C5939059F8B9586F071FB1B26121604D5252D136705D33911703B91DDD85ECF80A7A1741C29FCB06F321E8BDB8166EA8C899B8064B69D77927C0B503989101F1A6941F4DAB06BAC9973378C2E6B3B19D9506B2C9A6BC29A51582C8B47B46306C1B35A438A097B07405645FC66C2660F4C14457A41B91907CB2864338C09C0CBAA7A877A9543F775950487DCB8CD8A105822B93882271A17B6936912A55FB4109B45B09BB14EAC2134E0D7471DE891CA984FD7B194B1529EBDA3CE0C24C1A9A170D76145215C8CA7217A138C9FB7DA8385E8A0C56B5342DA66F9FAB03AACA4E3A1BC5495C7AB0AB0E451A22D480B00FB29CE641C46E7A5EF16867101A26911B0A49140F70B8684845850DB8E15CB7BF842CE712480B19343077674D8A7B7C47A5E1170A629E53ADDD10F4BB35A601A843B49391D7337D7B3B592182F3A1636E4A7CEA14676A0DC508423B94B115041EA5F925BA0F2FA8536AB11E6D451321450CDFA076EAA3577D605A7E0B354754B92F1B411487FD8122E8DAC14D8464EC4331DC746B5693451B52878923649144182C1F03DC4281A7991C60F4A4076117B50C21670809832F3A67DC82E448A49AA3A2002B1A8667CC947253015A6A88FFC133554746256A103D11C7BC98013264D5EFC15A0B2825B37C356A96F0A5B701B4CBABF57640F2A92796C5663570B30FAC65BB79ACB59CE5C4CC7757920496B85CF938992EB32048360559745368854EC7A85A8E862A973AD50D67938265D3541161BE9C4097323F5E77EB8F66887A89FB7DA1A2585A4DD52782AD221B515A1D37778B5911AC7C90FA7722FD5A9484486A6210157188ACB617413516955F5EB91D2691E1E38CC2D10638330029D033005A88606E6A941962F3FAC506FDA5211609138E503E3382BD71640364066A2C27780898AFC1CCA9509C23F022AA77546017B1943360FAE24A54A0B965BAA7966F45AA7F3BAA7C6271CD28D4E0263BCCBBFE4FBCDFFE05269B048E948BF2EEA1E3C1825FBB3AA8F182B2B7BA52877B2304434DCD561BF365BCDC6AE0960211BA14EE1F9C8CBEA3750472A02271BA7E79C4FE6C9019B25470962315C4F50332414F46233A354928980A7752D7A07215EC24133446521DA5E4C50B615AC4E78F07B6EEA141AE146FF5BC2C63167483CCAD311B847996339AA50B2C237B4486E3B538C75B14969676465F106B9069A6F627938690139F011F5FA7D1832B96A0309FC85920E142C9C57CF64852E4564334281BA63068C5666A71B194319E99FB024AD33F879D08C16743B34038AAD20D2C84CB7440EE04C1AF4B944227FE94B5D666C3E51523248D913B9A3693DD1147AD7064696CE5B613DFAE1B83A207742264E878C7804D603BDD71E56C5CA7F887158E805161C959F072CBFF82DAE020C80135A8D1890F1A9A839032B0D69B9A7A97785DA5C201685C683844DDC99F4A97E00A063E15122AF22C27430328EA1435ACB07ACDA0A3B6B784EB19E30E08353CA26118AC4D5C4A218A262C4BA135AAC24F1EE7C5EA0E13C86749E5E72541CA6CAA1E1C05174B08745437FEED0B94BEB59C105550656320DE3955835AB95443E5E29C3324284CAA26E76BB6AB3D0B37534D57066DAE72629C29DC0B9090EDDA3D3AE710D53C3EDF2C0A8DEA0FF08", + "c": "3812F9581A4D32DB0FA1D98110858E6539FE3150FBD28F25574851F4A073CEA119A2389B50CE230D6AB30EBC0042DF57FD9C0EF7A0A2EFFCC08765EEC2454306948221F8C2E6AF8415C2E9AF939A148CE20C052C9E56429DD4DDA625485A6918CE70A9319B5AF49392EDA205449C083B3A14096C1AF57BB39A1C9453EEDB85F69FA268B3404E686F9FFFAE236D97DAD29AE3E2B84EE8522ED3D51EDC12203620BDE2783C061D248CFF786AB3C61C5BA6FE1804CB514D872A391E968C1A980050324DABAA48BBD7878117333B8BB793B3198E4D94AC7AF564C5D4947163C84FBAD5DBA3D8C8FFF49518550299FA5323FE20C50979E44EF0D943EA1CA8D03ABEB261E09D0D0CC2F60E108D462823771C9E789500088462DF65EEE971DF976018CA33D38028855C3CC6B3019ADCC82F31F2EFC7C82AD3A46BF9EFE934AB2C9BC7EB7B2745416A3722B03DD7A6030C697E1C5318D032C8F506BFAF1C6F3D0049B4F9741A9CD3165DA27E955A116545BC5FA274980FA302A3083DD3025310BCE0E88D13D58CEEC02D6AEC1D1DF9D90FA8C206C0BC9E2DF2C9145503BD7363F1BEEBCC5EB6797F6732D7D0BD9299E2B395F75C5ED574513E17E2378E0F53DA0ADFD69921B88DE01FF6A2B94059451FA9F4D19864178E3FE343624EC063617AEA697960EC61C01A6943FF92D32EDA1BC6BE8AB12690ADC7E7983E269CB552DD01D5A61C549D932B9D936BC2B8E15375216C2BB391E96F021A7B1D46C625FD76E8A9111E1AEC67885C9DD04A72BDBEA5377E543A393B8989A02D65FD269EAF8BF9C8EED223277EF118D888B3CC8D3E0D9CB75CAA04BC22B7440260B74594C9DC2B2398DC6FDCF7B7BBA625E475E6CCCA2089241D6F3492E9FC35E29A3DD934E6CD0E3BE920B165207117C9CA858B88E57F7175CF1B1773EB8C292DDE4FA978504160C1F19C1FA4991FBEA15DA8700FDCD70B938283EB38FBCB740250CFE2510C85B5CBC1967A94C065A446133BB4C1FACB5305DD3B497CDEDE3440150868746E5A8E1775C07ED534793DECC83458A3BBD1110739E3668F3E1195134458D23210E2C973696B542D99392447921BC6249C84959DA4657E2D3C675520B3A52349CE7AE92D0900A085F3A59E73438C3281505744ECFB53D8FE24494D129BA778A28113651535D6BC5D47C9E8FA0F4AA159C3A9EDFC40DDD399A808EACB88EE6524B481217A1F1575A3F77A25A98C46CC674CD53C369B69755C66D637CE35ECA9DE6B660A718DA7F5A88E77ED68D99616CEA7165AA840F60A289157FA01DA864478A519686657F0D88EEB1B9A601F80FCFCDF430A07A2A86CD076497C894297ACFE9B9DE1F27B6107E19CD278E3AD83E135D153B0D8B44E9A4A97F869D1F6DF45B4C96722316D22023990BF12B9D177119B4985B0FEE3317557EA0B832E9745A9E09AA814E718DDCC077C2809BA164AC5AB1B47020804A5C5E135BB67582BF6B10830030E7656E09CB55DB575EB54ACBACBE80D901011A5F73594772368F47B7528D8BE68940C", + "k": "104177A27A18B5F35D2CBE9BFABAA2EA987B4296946DEE575B45A3A9B44CA99D", + "m": "947AFE33934E8150B06BDD1EAE40CF82EA99C0C0106B101283EA382EDAD94A8E", + "reason": "no modification" + }, + { + "tcId": 46, + "deferred": false, + "ek": "28C938C98060954AA557102D5BF39C17444A811156ADB2554562C5ADE5666704171AA3B19964449E1C12E721A30299307EC7ABC2CBBC82010E3ADC6DFEB2C497DABBDAC973021C6535773C127B3793792EBC717D392BBFD4906D4F21C62FD6C565935DA98550A2A310488956799AB9743B94446658FC97A9E1C3B263C23022132D33D2789295C994B6A441000F7FBA45C83A920739A17312AA97B1625FE5118ACB1552B647FA91C93C11182D9B9AFBFCB1A0D1412A7BCF92FC2E1A197EE4E728BB1812B88A87729C6E117A45E4E0ACAB2BC4E4A214DBF3BB4528316718C477329DFB1229AF9BCF0A00317FF526B8E4828CA797B354A0BD304FFFFC3E16C86A49355A54A0005CB1CE532CBA6A19267451ABC9C645A3F49FB075922BA931B1F139F8C627113B5358E02E81E71C231A41C1D647840B5AA96937B22926D6477E5B3A5D1C00485BD91FE5679CEEF18670223E670879EB3B02D03958A7751C007564EDC37DC0524790C8A0035AB30AC310F8419897597721D6B4EA87300453CFE981440FF0C18A323A0159B47A9C262545359F5031EF8B24A0080BDF0B55E1606355B88FC57803A3E25AB5ABA59582054E184FD97CC3E4635BC77AB797A748677B52BA76A16A9564BA218655A0070F20BD52B0A8C512A947534BBDC99D38621C655970B209C6DC8A0033105060133B600367E62366030810062387BDD120CEA00424C4C307E64EED5A3685F7B78E51138E02C4FAF51AE359499E2A97BF3799E216377EC3581AC81C12CC8B41AB95EA98C6D0500BBC3960AC05A2292789844602CA7528B2B91EAAB7A5F21399E13927C58BB030F492102B4361DBB4B3023961117099A7648EB11B2BF25703972CF778B5D8AC087BA59BC5122DBA63AD03EABC02031EF60CC765A0478F2C15DF31165903CE56680C2A62CF7FA8459D26C2D3C346617C51042351B321BEDBDC751D9080E0F64D2673C17055BF5DA53D74A0088357C1BDB8589AF5505C40CEEFD7140B95780BDC9B31482C75F5C6F395264A54C2A54B3EB6454C879510BCFB42DCD9548C3A53996030CE76A8A2435316CC227B591FEA7A0C12405D27936A0326A66A6CAF0B271BB64337D9DCB2E2471DDC632F3E0300F92C04B288191F0856C59376FD755729F195C264824657725E221BD017350982BB982078CA7A6783C64C5EF462F329BF6BDAC685D1BE483AA78B7BA7F2A0BD0C0C3A24341C9AF09C72D82674B0849BB70BD4861E5FEC25375223F5E4A4E20095F330C43A3AB23B633A0DA04553F69043A0B6AF862A94835AD284C31F82C23E80C2A488872E4B314636094C70A5F7614B1174AE46C11F45661256D566C6801985A2A91990889999631FB5BD4072C884B85BA79521BB2C7A729CA3CA8C18F5EB340EB84B00CB991D17933B3212293828BE1734F21B775BE289F77CA45846B3B6F029D6C610A0738F61B5C80BC808A8A506BD1022940AC755A7A4765A1C4A36B42DA453AA4B516F78B2C48CB94500401FDC654C1BA5C0D58FCE894E455667B25269A429671B668114181F06060842D16980F7A772480F3EE46D58C01682AA538DF1813CF95B67D9156D945E2FD84A7003CBCF265CDC12AA7148B7AA55C66F44A82E4BCF7D8C7B1ECF22E1BD7033C0588FEB6A1D553CF8BC477D94FF875323943762AB1B", + "dk": "367C6ABCB47754ECB23287CB530C5F29BA90464CA083AC4C7698C44487B209639E37E43DDC8055CC936A0C3A4EEB215EBF7651B6D8849CF2077C5969D66194D6BCC1DC96B21695856E072D83194D4F2966C649A55BECA2E9D9BA3E9049F985C9F06311A5619975653D0617288EC85BB13626C2A713E1245EBB914E4EC7651366615470483E478DAD1276A3C46C08E0BB1AB4AD833A584DD84222E2B880450806426937626FCC4597133B9FF2A4355EE20258334AA20C5BF7639A215AB2FB4B3A4D74AD8D66C06EEB290D370447053F9EAB57FB42821C2667011A95BE07CD33847FBBA78F44C7B10537C3AE97C2BA653232827C9400538D4BCCB371B2E7BBBCBA0C34A83851C0236750A472AAA163080C562A40908D1585549A4F8C44798AC877D4C2027A2018399C3B5A03C278B20057436B1A00BD83B8ABC3B6B78D18B7A94252BED77128617ACAF3BEB1A937F516AD7D0330DC9694D7835E38A35E63156D0C9B48473639B3C1A34315C67C389D686669CA4759C41748E6A43BB6648820061C54E41B193B79F147659DFA83D5FA3EE7D195D0D826203899EC813070D325D943CE82A7194D3A5114FCAA71266A5A2CB8CC2B837D261E28FA2B12C5AF2C20C19DC6CB49559BEDE9A793A5B272F8BC357A291D55CC0347093AF3547D6913E61C4316E49422874D84342BDEB508C4B1259757C4D9D139729404B4C083B242A1A9920328FA912A5B9B1D67300528741C2A0D56F5870C1316710C6950B93E8535A8D1512891A257FF17B71FA46BE18167951BB87A5CBCCFFA8DA5C3C471144523400F7C06B6F6E9CF2595101D230CF4B256BEE416638389569C774D1B5A25BB2690B4BE446C4FF68B1C64D87CAB248C9E7682E56CCA64FA8CEF2C9C43CC8B8C265EAED9A45945B308A4A946399CBFE59541D144DBA75F72E87272996AD1C1752E1524DE6C8965735E7A12544283A7438264644B32E9D78DCB99B82602AF6AA75D10C645AAC8A30CA90B02C914FD512C1367AACD1C38FD38588F527A24E01C9118A71BA0B4C71AB6298845A26A24B6A4762A537BC6A0797A8725DB5BA56FD67038B1CF6ADA8E7B4887B9E369478061228B8985922B6A909FA318AB2477867DE299BC957087B26E11E134C3EA4198659971F69302618E1146CFEDB6210A99657C075C7A14A569780E6E94395EA4AE38CC735F7375B71A4C6066CF08251859036A9111BB21D03EB9294A756C7D3002052E9492500C77B88C4F9E41A0D347424D095B816C96EC790527D74928028A7F542F4541BD3AE06E11E24481B36F4E22930D29742E4A3F3D1B2126258CFE080503F9CDE8133A99D31AF41047269077DAD309AB705DDA9A7CC44374FDFBC26E771ECBA3A420D162DEBB440BCB87C4A993B1C656F4A0250B029F20449C63105F865A1E26E21915C0099A2CB0279A0824DC1DEAD981AF301E34759EB985C313C7488673AEE516655421997C811E6F3676D07C9D52C27022C665D7518864840F7536AC69432451A1C3E86093852B12C465BF460317C5311E12D3790EDB06B22B54F9B7018AB16E1C06049B774C68C35177F369BF2B6423F5175A76777E4A30E67489A1D0319CB1040454B9CD1C9976658DFFA43009D62128C938C98060954AA557102D5BF39C17444A811156ADB2554562C5ADE5666704171AA3B19964449E1C12E721A30299307EC7ABC2CBBC82010E3ADC6DFEB2C497DABBDAC973021C6535773C127B3793792EBC717D392BBFD4906D4F21C62FD6C565935DA98550A2A310488956799AB9743B94446658FC97A9E1C3B263C23022132D33D2789295C994B6A441000F7FBA45C83A920739A17312AA97B1625FE5118ACB1552B647FA91C93C11182D9B9AFBFCB1A0D1412A7BCF92FC2E1A197EE4E728BB1812B88A87729C6E117A45E4E0ACAB2BC4E4A214DBF3BB4528316718C477329DFB1229AF9BCF0A00317FF526B8E4828CA797B354A0BD304FFFFC3E16C86A49355A54A0005CB1CE532CBA6A19267451ABC9C645A3F49FB075922BA931B1F139F8C627113B5358E02E81E71C231A41C1D647840B5AA96937B22926D6477E5B3A5D1C00485BD91FE5679CEEF18670223E670879EB3B02D03958A7751C007564EDC37DC0524790C8A0035AB30AC310F8419897597721D6B4EA87300453CFE981440FF0C18A323A0159B47A9C262545359F5031EF8B24A0080BDF0B55E1606355B88FC57803A3E25AB5ABA59582054E184FD97CC3E4635BC77AB797A748677B52BA76A16A9564BA218655A0070F20BD52B0A8C512A947534BBDC99D38621C655970B209C6DC8A0033105060133B600367E62366030810062387BDD120CEA00424C4C307E64EED5A3685F7B78E51138E02C4FAF51AE359499E2A97BF3799E216377EC3581AC81C12CC8B41AB95EA98C6D0500BBC3960AC05A2292789844602CA7528B2B91EAAB7A5F21399E13927C58BB030F492102B4361DBB4B3023961117099A7648EB11B2BF25703972CF778B5D8AC087BA59BC5122DBA63AD03EABC02031EF60CC765A0478F2C15DF31165903CE56680C2A62CF7FA8459D26C2D3C346617C51042351B321BEDBDC751D9080E0F64D2673C17055BF5DA53D74A0088357C1BDB8589AF5505C40CEEFD7140B95780BDC9B31482C75F5C6F395264A54C2A54B3EB6454C879510BCFB42DCD9548C3A53996030CE76A8A2435316CC227B591FEA7A0C12405D27936A0326A66A6CAF0B271BB64337D9DCB2E2471DDC632F3E0300F92C04B288191F0856C59376FD755729F195C264824657725E221BD017350982BB982078CA7A6783C64C5EF462F329BF6BDAC685D1BE483AA78B7BA7F2A0BD0C0C3A24341C9AF09C72D82674B0849BB70BD4861E5FEC25375223F5E4A4E20095F330C43A3AB23B633A0DA04553F69043A0B6AF862A94835AD284C31F82C23E80C2A488872E4B314636094C70A5F7614B1174AE46C11F45661256D566C6801985A2A91990889999631FB5BD4072C884B85BA79521BB2C7A729CA3CA8C18F5EB340EB84B00CB991D17933B3212293828BE1734F21B775BE289F77CA45846B3B6F029D6C610A0738F61B5C80BC808A8A506BD1022940AC755A7A4765A1C4A36B42DA453AA4B516F78B2C48CB94500401FDC654C1BA5C0D58FCE894E455667B25269A429671B668114181F06060842D16980F7A772480F3EE46D58C01682AA538DF1813CF95B67D9156D945E2FD84A7003CBCF265CDC12AA7148B7AA55C66F44A82E4BCF7D8C7B1ECF22E1BD7033C0588FEB6A1D553CF8BC477D94FF875323943762AB1BF710097FD6086E9C14C3703A3FE5A5573EEA9872B6F28B4A383B70F37099CCB55B07AB371A4D050DDEB134D78D044F9937A01F9E17DFBFC4E495051A4948CD4C", + "c": "20BA3A872DA897C006AA6DA3D6793AE2B384C1F7B97CFF48DF291419D3CA55C4745A4C5336D6D62BCBD9941140506E39B4E080A3E669DBC5A123A20D2ADBA8A47D89F81209CFCCCE9253A639860333201E0505EC1E58AFC7DF41EBDE37569A22D3DF0C6E1D41F0D32F8118F83674D681E907E1B1E7F5A14A9E3E1B3435B30C375F5A8776CE5CDA68BA32BDDC44B900A6AD0C0AE3CFB468ADB9F8B21FA3C1D7EF97C4DFE1CB1B4F785479FFE9AB47FBAEEC6A688D288C2904124C2DF76C5674813C92E8DC3F246A515D268E44FE1BD1F562B0705C5DEA91B9782E96E740852CAE7949A84C14ACC6996F1D5CE5B5A2261DEAAD4787031CEFCA49AE532FFDDB7E097DD67D2C22238D8279EE0F8D1657F80E630DA1629F0C12910CCAF1296F2BA404CE59F8C22A792611A8A4BA5C88D88971C86A9E45E0DBEF51D4D14C5E01DA5F2C46E9D031A07BD9BED7A4375C895EE84B57C6D14211D90DC327BC6ABEF72779C9AE856E93BC74F1D8FFE00ECFB2A212AFE587B0022727082FE09B79A130CCADEDECCA7CFBD852AACA426819A688E9AF837A6EB5DAE47F73B46EB48CE5E059403F7C5D522E3B7E26D0115677428946C516023319D78AADC641C7B3F7A1F6E5F4429C00C0C5798DA60CDCD79111C0EC5B4BD86CA2A47F676B45D4380D2C94D6AA360E6497BC9B25C092D0B58D8DFD0D315DE457D95C09355DD9B36950245FD8909EE0AD6A1637F4F00476861FB8930E81040CCD6224FF19D2B84D37D0C7A383C6E2CBB122B0167260EB0B47BB6C424123213AAB6C89F2D527E20275966638B194F01F16863E2371D45572FC0D63541B896DA6943CF59CEB74EF53834ED8632FFF4975AACAEE7818F7B3F0514333CEE2CDC4284E2CF68BE084AF748880988CF77011EFCC00A66B0B4C6EE5628A950984127CFB4322FB98A9FBF1DFFA28A9E5C2893F3CBA1DF900D9ADB533DD9A991FBCB94E5E5167A4C8FF2DF80E504679090B7F729AD702F3EAA6A35FC4336FD0FCEFA1C8532E60321A7D72FEC4F10EAD95D210479B060EAB5BAC9A3AB6F33D22FCDC514401B50DED0187D3483C8F49C2B00D39502689E666009DBDD1A0B9AAD5EE2F3A7EE70D7E381D478F70D38C1455A7A39FA854BDB75C2E3F32A01F42936D684283A9E12A10CFCE0C8ED77CA394930A68E1CE4383C25C18A93D26A2B997DF21F12BCA7A478CED58C08CD353FB91E01BC163354791C9F7B43A5A90FEA0ED92D4E9041D0D9C36F1C204498568105DD409FD71A3A0BA7B0E740EA3690F5B8C487BC026DF1BD7C8F9C9B9BADBAB28D815D3EA200A9F75F0BB9D55AFC4AFC5F38A0609616DB5B41C7AF9479003BD2F1868AE2BDA2682922CB1C90270DB852FEA6F7489E686C85C20534151D94DB33367F02454C415251682A53CC2A0EE1A845A77F6DD04ED14B3E0B6099375B7DD10D4412215F2413EE326DDA5A4285481A2A70CC0FEC98DE1D77A8FF93BAC3196D7610E842B6A3D2908B61AB7A864C0CE2DB55D3E7DC4BDE89766BED1709986009DCB00FCA4BDC3", + "k": "A2718B4EB96D591690F62FDFCC264BC457C3A1B755F4CF64B359BC945C254CE9", + "m": "DC8510F45528D6981E59C1AA6B743BB844377D7339E359036929F0EEC54FE63C", + "reason": "no modification" + }, + { + "tcId": 47, + "deferred": false, + "ek": "4A6C1F1A816FB66471E6C18CE6126CD02BA76C730E721572DC730566496B3AC28F92A15F4C534C48578C18B443F24681BA2B3C3B390669A288EF7676C9A6B0970340F567C90407617B28A9A03274D8288006288B0A5B686FFCBACB273536941CD06927BCE109BF2330CF65A3CD0A2706EB33150A88504484FE182BC3C78CC5A7711845C3A277C763DCBDF16B19F1001727D5677687ABCF4B32CD161350EBA4206B2E1A65848528B7E1A90E04165BEE054F43793C23B0660FE7AF3E5964DC7C275458040AFC05EEC71A57E67C2BB794CE2680E7C4170FDB67F0F36DBA809F724B805BE66EEC38181FF1B0E9F94F7903661ABB17FD9BC0B0B19BCE2560E2C2C764F4863BCC40B5FC10B6513483A827C1668CCA8AA0B68039C8ACBE81B639E55AAACF2C761D78A77C2651573471434A14949943D945BC0ED2187DB442E41B901DBA0B14580710870B81B78D21996AFDDC6ACD1473673414E5C7C35EE60EDE3579223A7A2A436667CC51DD366DEAF615CAA4CAA073B60718B1E5B62ABF50BEBF4844EADC2ADA98CEAA8CAEBF187C2F26882673307A13CF83904607A8865A65592866499505051F10A4DE52893E07BABEEBAA4272B14EA974B5114101385AF1A011A488BA25179A118B312D8AC86FB58592D328941A3A0DEA6102C86F1E237DDB321615297A2BB660D5E0705A6672FD08A5CF212AC9B5B7A1306C87952B1C11B7D4E7C5B5FCB7030725C2A14AED641D78453E9FE5C6E6280D2CA57832FBB091C4418303CB4AA32DCC3C211DFC8A9BB429E750B2251149727ACBB112607EAB9B7744173D795B06D10EF8B1AC1AE54DA30A05188B0164B6B6E9223E93D377259163D62530CE9A0584F82E59534AC3E061B1B48BAAAA9DE1F8BEC150A63EB579DC528EDF977E7E421743F6A4C5DB61DD31334D3C63ED7755529064D67A4BA3780BC7C87731B86509738C1F7215275ACFC6E3B651FA91539B2B10111452570639E966766B64477C3F1E255390840FB9635500F2B513281E9D8B5BCCEB360F05913591899C1CBF95D23CB8D714A007990BB344C3A62446A80945D0CA84D3727CC8C39E0553A13B7050C12A1FB8BE6567930E0B6ABF6C484FD340CE916596B36BDC4085595CB2CF088467B0BA7F915A4E9581E7269C9A234F1A004A8BD0A2D7654018E55D6861B4067A29F6425FF1F5A00A804E3B3461DAAB9265D15BD530AC10686FE11038E772BC1CC46DB5C401FA76C1EE70165FB7C67C5025C2515E4182B46B92194FF361E252CCC43B060F50A64C79750BD162A586C5A63071D6E93DABA8BD525548F444C621A77E3EC583218788E3A7113DE38EB2ECCEBB0CAD737BAD9C21B39DB255458B8D6EE70C250CACC74A3A19C342B052A0FA5B92399013EEEC1BEEBC8E02F80C137030BA0A5DC8C3028B550925367BC732CE0E09570AB1AF01B7CACBB78A89BCC8C674449B932B98487AF0257928E64AD06967B38B30A0620FF9D49D2D63C2E7847E5B26046B457A7BB37CF012A7F18AAE0CAA41AEF72937B35AFDAB0174688B0724B25D67563536950081931A3ABE89B59297F701F246A6462B6016EA4EFD42A15C984E7157B5B4A335064809BD7739BAA23519098233C7454E241B23C4644A2AA1EB16E456E23567C4C3C6662ABFE76F52FE97F07F1298BDB70F62A5650A", + "dk": "74D0A332727A99FB07FA104DBAA09E120A80F2C3BD27971D5C8283E14C587A4C1064FBBD25919712C34D561270980352939739D378881F21813C077FD4A30A14873E01FA659B567069F9BF7BE0A94C9B2F62A9243C986F4B8671074BCCE5421FB12922F8B9BC50A9B4A4015F3B58BB493B34CDB7909817B0E1CC76F4B71A6BA45E32C03152D0BD972B6C557A3E84B62CA0F830DCF55FAE743AF419C75B253210347B00383043B3BC5B9425DA8151294C03FC422F1C22235AC1B3D487C84D63882A504CBBCA84CC192173225FCC3BAE53601AD905554BD1CAE026867141802F41111411824580837E35B5B4E47FA3173530A40285000E695610488407ED986041DA7B0059A054F1877BE8887CFC028417C1D78ACFF8A09FED7B289BF96F3F993E805CAB566CC0FAEB3A29EAA40A2820CF20912A1A4F3EE1C5A48C212C421D78326D367C6C41E7136E810F8A8B00E2514AC351358D574CD0F7344A121B05131B05040EBEBC08D0E203599503F3029EB3A586DBA5862F371B78852338281982B1CA30C70580ABC429D80EBF9A972D9B026FF24C387352F63943131AAE1A804B10D47059E00885EB670D462DD36BAA0FDB7E798915A0688D6FB3313B100445465E66E35CF664B060E399ADFA9712A32AC631B542B66145505627C95664A6117BE68E7BF3B12FD53CE02B43AEA449652A6BBAE782FD4178F832C766C09DFCA17686E57CFC563B32A43566C30BE1A85A923A6620FA5623ABCCF5133CED5499D424A67983620BC519BD3730C51B6E894BAAEB516A5AF16881619903B3051243013E6B8AFD20B2AA56ADAF436EA9A9A59AF2922DC07B644936C94B0F7E4057621519AFB8C53485BBA390777C591BDA7716C8B1383141197DA00CB9975B37C6A8DEFBA0E45563ED27336F3A19D64AB0A803A7CE5A5D5C2C513A1CB53434681AB0AF7AA96A946B5A598A15C6AC54192B447ADA0B1DFB08DBE72734A87AAC6B4F65CB9F2D319CC984AF4428A41825A504C1963B719548418A79918A5723514155389EE70E2DE0BFC46706918B7C0EE0022CE04E86B21A98646850A6329E8BB08EA78FE1633B4C64BA32C4B1D920C543CA6DAC053338716F2F194DDC8AC1CEF24EDD52CB6EF39FCD6B5B04C306223BBBE511CA8D1315C56942D4EC321C63331F099655349F174A0A4729841C8B5DEA646D34218E9DDBC48C968B6CD949587922D8CC9E94EB780055663085B02DB26063F14651218B31210A74C72CD273383FBB1236659F4EE69315651785C822B425BFDEB96D53D674118B249EE6AA963C31CCB76E9CB068C4681680FB6167EB6AB3F518CAA5175693843BCC678E0C5477D93CE95ABC023590F3EA9708FC98C7045C75EC3905662DBC485ABB02A23CAB7E36D6B48FCB8E43F74D507BBEC5CC827FF186111ACE6BB1B2802C5EB9552698C320B523A692F68112267BA5BCA8C49589352C17F117078376A1FDB6B91F9C6ABB3059BBC53796F90E0FA575DC203DBB893AF1B7AC43F2050BD56A8C4212F055AB9BF7579EB809BF9C71F64BB3D6314AD5E8643A4240F5AB35880905E9D4176D25567C502C4C103910F78356C1C47867A9E2AAAD057C909865614612AC0DB4679561922487116064BF4A6C1F1A816FB66471E6C18CE6126CD02BA76C730E721572DC730566496B3AC28F92A15F4C534C48578C18B443F24681BA2B3C3B390669A288EF7676C9A6B0970340F567C90407617B28A9A03274D8288006288B0A5B686FFCBACB273536941CD06927BCE109BF2330CF65A3CD0A2706EB33150A88504484FE182BC3C78CC5A7711845C3A277C763DCBDF16B19F1001727D5677687ABCF4B32CD161350EBA4206B2E1A65848528B7E1A90E04165BEE054F43793C23B0660FE7AF3E5964DC7C275458040AFC05EEC71A57E67C2BB794CE2680E7C4170FDB67F0F36DBA809F724B805BE66EEC38181FF1B0E9F94F7903661ABB17FD9BC0B0B19BCE2560E2C2C764F4863BCC40B5FC10B6513483A827C1668CCA8AA0B68039C8ACBE81B639E55AAACF2C761D78A77C2651573471434A14949943D945BC0ED2187DB442E41B901DBA0B14580710870B81B78D21996AFDDC6ACD1473673414E5C7C35EE60EDE3579223A7A2A436667CC51DD366DEAF615CAA4CAA073B60718B1E5B62ABF50BEBF4844EADC2ADA98CEAA8CAEBF187C2F26882673307A13CF83904607A8865A65592866499505051F10A4DE52893E07BABEEBAA4272B14EA974B5114101385AF1A011A488BA25179A118B312D8AC86FB58592D328941A3A0DEA6102C86F1E237DDB321615297A2BB660D5E0705A6672FD08A5CF212AC9B5B7A1306C87952B1C11B7D4E7C5B5FCB7030725C2A14AED641D78453E9FE5C6E6280D2CA57832FBB091C4418303CB4AA32DCC3C211DFC8A9BB429E750B2251149727ACBB112607EAB9B7744173D795B06D10EF8B1AC1AE54DA30A05188B0164B6B6E9223E93D377259163D62530CE9A0584F82E59534AC3E061B1B48BAAAA9DE1F8BEC150A63EB579DC528EDF977E7E421743F6A4C5DB61DD31334D3C63ED7755529064D67A4BA3780BC7C87731B86509738C1F7215275ACFC6E3B651FA91539B2B10111452570639E966766B64477C3F1E255390840FB9635500F2B513281E9D8B5BCCEB360F05913591899C1CBF95D23CB8D714A007990BB344C3A62446A80945D0CA84D3727CC8C39E0553A13B7050C12A1FB8BE6567930E0B6ABF6C484FD340CE916596B36BDC4085595CB2CF088467B0BA7F915A4E9581E7269C9A234F1A004A8BD0A2D7654018E55D6861B4067A29F6425FF1F5A00A804E3B3461DAAB9265D15BD530AC10686FE11038E772BC1CC46DB5C401FA76C1EE70165FB7C67C5025C2515E4182B46B92194FF361E252CCC43B060F50A64C79750BD162A586C5A63071D6E93DABA8BD525548F444C621A77E3EC583218788E3A7113DE38EB2ECCEBB0CAD737BAD9C21B39DB255458B8D6EE70C250CACC74A3A19C342B052A0FA5B92399013EEEC1BEEBC8E02F80C137030BA0A5DC8C3028B550925367BC732CE0E09570AB1AF01B7CACBB78A89BCC8C674449B932B98487AF0257928E64AD06967B38B30A0620FF9D49D2D63C2E7847E5B26046B457A7BB37CF012A7F18AAE0CAA41AEF72937B35AFDAB0174688B0724B25D67563536950081931A3ABE89B59297F701F246A6462B6016EA4EFD42A15C984E7157B5B4A335064809BD7739BAA23519098233C7454E241B23C4644A2AA1EB16E456E23567C4C3C6662ABFE76F52FE97F07F1298BDB70F62A5650A159FA6BCB8D2EF121A97A25B0607D94B3DC6D5D48B620839F143E8BA01BDFC55E8D41C96F1D340408D550400AF1CABD517EAC8447644605BD2B50A850216815D", + "c": "473A1EB71AE24A5F5F3A2FC86E9F48EFF07570BAF66E36C2C86453424F218BFDCD2338EA9514242A877ECC28BCD1BE87A71CC4D413ED8A2E3EE4D3209AC01DF03EC3B28FDF3D572B0F8713D41EF8800C3C1DD4B60AB084711F9B402AA34593D1549624DB9F895FA48314E0AE94DBF0EBE54EC81733DF6B3F5F38DF0DB91F051ACCEFEE0B32A26EBE37A5B12302F3F809121E879A7D0A3F29F5F9973CAFDD09220F848F03E2CAA1E64B6C6AC1D46A9F9874796D63738B11C91D9971AA2C1595A4148B145379CD0DD606596CCE45C334255BBD6761C4720870771CE40D8A9D51BA655854915F2C23FCBB0D40930B0EB27C96356A6C5503FF5453E10DC198F5D2AB476988030BCD2A56FC235EDD3538E997D50B3007CE0D28E46D2FFEDA62545F2AC5D6ACEB37B089C900CE167D68D358A445D1BCCF6429B810E74BDF07E04CFAFD5FD30E59CE541B2BE55AAFA1B928306715741BD806256E4D71F9CEE10A119D6C8D860866324901C8E582A7FD658EC83185103F7F0C9E9230052F0DAE235A93646F3754CCB6FF9D4E4E1CF47B262E5ADB4412376A3D1969CD7B2413F37382F665E642699696FA9868B25BEC0DF374789AE0B476E206194691C0EA5A16878113D39903FF112207B36F7617D6A06B864AFDB5C83095C194A71694623C31EAF91CEDB387F5A1DEE666B6EF95065222D6F98384FD59005B2807A68F3BC75D99D298C7A432B2160A2079B5A8AFB97EA67F37588FA5E246FEC3BF82E18A75370BA268A4FFD85B957D2A573F23BFB004E79ACCB100087065B33DEFCA73AB7523F17AD2C17F76773B84646D92CB3187C1F6E5B74EBC7C7DC71048C7358F21F029B7DBCAC8543CE74BA6C59625E7897832CEA6CBCDB64DBDAA3E603A9374F16942E00C2BAFA6A44D9451365AA1B9ECADE2963C8BCB79FD2F836229B8BB5A0385D39A017CFA6F875DFF4CADF9E9D9290D9B7BF6D0F3BC009972B9F15D330A9EFCD42246EA642209A712F922630EF2AAFE31414F0C4990513C2A208BF7D230ED7F9827C5E449E32FC4242851EB2D78E1EFC11C26A15BBD6DE677549B2939D075A0F53C3BECE462E56ED9324878928B58A85A5269025B9FED7080D77482A4AC5747310BD52367126B6322DABDFB5B75CFF41E4AC012B1FC141285D6533A78A8D13DEC193C1826B20EE5B7FA13FCB85E514FDC69C7D6E5C48633F2E7524F9420074719FF206D5E1757FF9512D4F8B44FC7242E9DE11DA99B2388D1B0F2327407FB01E5CDF0A24C94CD9D706E9DC8D0673DDC5AC818D96A221B732996DBA40BF68AE1FFBFB6FC1E0294908601D3AC88D76891FE62A93402D69EF797D2024966EEC8E6B96848F0B9E39CA6CC80E0C4556EDD85D6E70473DEEBEDDC4CC49DB1D41EF18B0B3B3F17E28B436C29460B6C9BCEB3492BE8ABAC057C03ECA4D266D60B173D206ED77C1D3480D7666DEC028F31367BAFE002C9F63EC6CBA2528D72220D5E987CEA74E9AF7B3072F681C72D2E6DE1DBAE3D8ED43DA7F2F5AC75516E38F5C244D42B061C3538", + "k": "E87B61A6496FDA38F948EDC5F9CA5735579D47F6355B214727EF5BEB3C13CA32", + "m": "62A2DA94F109C0DEF56DFB275B1A0EEABF82AF8C6CDFFA94085AA93015BC1821", + "reason": "no modification" + }, + { + "tcId": 48, + "deferred": false, + "ek": "36C053F748B3A0655C3BA86303E099538971AB05BB4B2167D84B4F8BE79CCE515F28A90A5AD5CBC97B84CE10A39BB59AD2FB4AED7CAD205200A3C688AA32AE73F552A33B7DF1BA197F16CFA853C7FF24C1DD586ADE74CB0982449AB9815A63672C32420C1812326554C7219CA7698324115615C41D2E74A0138A42356232D7218549684CD9800F1A8413F3D952E78C915AD56FB0D1CC76D48F2ABCC0E6D79C67198D53B3B6FA57A4E9140D3C4286C97C7CBE48C3FCC81C6CD1540B12A077BC54F6F46711C844B46559194B5597A815827307E0E58AD7C4CFDDE826FC3594002A88C83760B56331A61C542C7B4487A851D7FC4D6A4072B7FA7C77647F8F252337252B1C9709517A7E217B26F26984D8D0AF75C9C1012977A3996D855A86C47266224C2167E585C9687C0FC5259E5BA10FA23DC4A2C163E74EFDA01956965A5DCA57BCCA2EBD4606B810882A337CB33347820C937E821E75A5BFBCC75BD1E37D81342F8248366945C0AA2B98F6E228A3AC6EF9CC28208470A3FA56C2F51AF83418E3D13212BC2C64304B4EC55001BC3620635C989CC4E4ECA06A453C8E5689BE8CA010C4026FE201EFAA271C2A772563CE7147932DFB7256F28975E2829D454BB2CC64AF8684B9ECAE285A93EC2212AF4CB65E484461D2B2121B15B37AC9446A8308437B887271564BC8143A8AF1F912BAC58E06AA8E03764FDD823180E30D47056A6D217ABA6533AF4399BCC798AB59AB0880913E14895526AD2F06A6D6536A0DE701D7DB9B2EAC7466FB85AC0020D961B39B88A8DFFC3FAC57524170B70490876F3A6FB16020EFBBA26E17C012AC4280C46E7F643CC334BCC302BF3BAC10A3891FF0F2BB81D29D8E421A71272C0F2439AAF29916461DC24B4899325FF005C0E30085AAAC7BF21B58B114BB0025305C8A1DADE9A1811329792713C5236B44B52AB8791856C535DC8B0E4DD0753689BFE0636DB99697B074BD2D3A8C4AE69929F00B8B256617FCAA96C980E8A629BDA58CF6A76DA49A004055CD4BE21E2C02B5533A7FBBC4525A95167175480A7B09BAC2BAA47A03D4872620C191287932029C9B53737A69148B7F483C607148DB23594DDB2F149ACA20F13AE693C2265A71E911A4D22ACB1ECCCC4C96B1A2C0CD45A5AC25533AF6829919D93770E42BEAD230BF8739B48C9990ECAD9E679C501137C49019C2F857C9D08FD533B01D50AC6BF2398655A1CBABC670299ABF46B95913A845151DE2796666BA6824237AF61789857CCAF0AB0F4B430FE966C85818B11E469CA2D7B705833813B8A775C77138F91700C64BCC6360231B1540F77113A33DA08189E454465474947EAA7F6731613BF9AD6BCC6D7DD1B62E1A3AA67C647A62712BC9CF67FBB690205E6E6997FDA7719EB9994D199505342D42FB3C6AB1936825534980768102619D79B9F197CB05C16A9922B4AD752C4926539AE184756114601A6ED90443D2869D0FDBAC6F447D91F37FD4E6649A90B70C73182B6162375610E9166AC76656A9B9242DA02CEAEB970A1803BD570F48B7B7557928CC4AC5D494BCC9386078183675D760322A91A1FAB770198A437C052EF366F6C905062010AC09AAD9594F581036A7E11B0D6C3B40BBBBC340CBF6D130BFB4E7CE4696BDB01ABE0436AC41B279FD576FE86BE94D213F70", + "dk": "705A6AD224AB8C18A1DAB7039A7282EEF71B9AB515ECA53B257B43E39C5890B131027737F089115599CA3513CBFBDB536FA39A872CBD8DC10CCB3CCDA36CB910902CDECB4522AC2146A39EF42465921A767F56670EE297CE2A3C67A24D7D55540DBC15F2500831F384E9D9646946A4D133CD0686A9F8AC3919C36466AB2B72E668B1659A81699B5A9B62C79905D6F2674CA471BDC657FE973FF95437304708E88B0805858077D28BA3632821239B2C3174B21849A0492E4B1B6A42D39C656B41277B0D8D868DCE06906D82210F9424FBD1CFD81134E503AFE93AAE02574AE1D32608D92CCFF667BD87B45F58ADD75B79A2912A73672F0A9794086084B9F58F21B7137FF42333B47661FC6695B56AC18996064606B37426C4E04A9173425B985B6214ADE879B8A0116309466BB0408DB243A39E123F3EC68E7D47C7743A22A062A12F9224861069BF8C50B80A1799AC28BDEB43FD0A3F6C72BE1AE97699A1607B68644D09A546945B57E69DBEACC41165C8E221031DA43A41B8312E3A1C1D1C7329189EEACB0D9946600D63B533ECA1EFB11C3E6C12D888C0C8C331553361E9623CE2D29854FCB3064A9054C93F7142A8862CB83529183BFA66309858444293CDE44CADA626AD100DD0D76DF7C07B455C4A7C3B04354529445C9D12B65B0C59A7CE3C7F350619C1D3A65AB314F624A0F456715A1CBFB970BF0A571F0B9C78766014FEB46CD750C52A06B5CC8B5FFDBC8754792E44B7AC0B6332BEF32C57976688800EEDB0482062011E99C801CBC5A42C8768624B84DC4FEEF6580CD86275891B460218A8E652CCF228251B9ABCD9A9083A5AFE088BA85A0F1F10485784903623C347F9554EF0722E605C2D8012CCA89822500EEA037C3F319F5EB8A070373F34196842D96BFEE44E1EC9904754A3A143218E23968D28A83F91CE70908AA9178336E50688A446BDD85E1DB69DB9018A88D427F94474BAC3CD473A687201801D590277736C10047ED9790A33A39FC3267EFD154351956374339F50D75EF0F61661B68E7E59111D153505DB69E65190F80C9B64CBB77B958E83FA82F9CC6A945B3F46039D3B368E18A34CE7038D597C2ED16833C3F7B286EA17D58CCE86DC4FB7F1007E9A4C64F573AA053F778B9ED71825D97C8E1C52C953B08942A1AE30935F8765787F44505FA38B9CD93258F0CA6D34269852786CA82D980BBD72254D4D0A9C1A8559420C232E98CF222A469AC9893B6643DE6A499A53B4E73A9D989A615D3A22507694FC051EEAA27274BB3F19938758E90BB83B0999BC43A90B60D424901B7522220414D5D475AFABA945DBCD83807A58D3B5C4313F9F7027EFDB2299E873AA6A18658963691070D9A6A8C8BC061FD9935D521C0B319323F1B7209866BB052207B6AE8FF81EC8C12A3E035E29404FD28086EEC313517BBCF4A173F3573D69BBB77B177615874C0C04C0138C83AC8CB576E4C29363ADC8F88FF29A67C44952937B7ED61A1A0F11147C345555DA1089B768D7A0751875B44E36A63488A23C281FFC518E4A548D3EA6491E634AB97A5EE71805F5A7C037E2B2720CD037A2501D9C239DA14A618C2A53DA7C7D096EC2D0481B70A1D45075F2A000F5C60EBF9A8F36C053F748B3A0655C3BA86303E099538971AB05BB4B2167D84B4F8BE79CCE515F28A90A5AD5CBC97B84CE10A39BB59AD2FB4AED7CAD205200A3C688AA32AE73F552A33B7DF1BA197F16CFA853C7FF24C1DD586ADE74CB0982449AB9815A63672C32420C1812326554C7219CA7698324115615C41D2E74A0138A42356232D7218549684CD9800F1A8413F3D952E78C915AD56FB0D1CC76D48F2ABCC0E6D79C67198D53B3B6FA57A4E9140D3C4286C97C7CBE48C3FCC81C6CD1540B12A077BC54F6F46711C844B46559194B5597A815827307E0E58AD7C4CFDDE826FC3594002A88C83760B56331A61C542C7B4487A851D7FC4D6A4072B7FA7C77647F8F252337252B1C9709517A7E217B26F26984D8D0AF75C9C1012977A3996D855A86C47266224C2167E585C9687C0FC5259E5BA10FA23DC4A2C163E74EFDA01956965A5DCA57BCCA2EBD4606B810882A337CB33347820C937E821E75A5BFBCC75BD1E37D81342F8248366945C0AA2B98F6E228A3AC6EF9CC28208470A3FA56C2F51AF83418E3D13212BC2C64304B4EC55001BC3620635C989CC4E4ECA06A453C8E5689BE8CA010C4026FE201EFAA271C2A772563CE7147932DFB7256F28975E2829D454BB2CC64AF8684B9ECAE285A93EC2212AF4CB65E484461D2B2121B15B37AC9446A8308437B887271564BC8143A8AF1F912BAC58E06AA8E03764FDD823180E30D47056A6D217ABA6533AF4399BCC798AB59AB0880913E14895526AD2F06A6D6536A0DE701D7DB9B2EAC7466FB85AC0020D961B39B88A8DFFC3FAC57524170B70490876F3A6FB16020EFBBA26E17C012AC4280C46E7F643CC334BCC302BF3BAC10A3891FF0F2BB81D29D8E421A71272C0F2439AAF29916461DC24B4899325FF005C0E30085AAAC7BF21B58B114BB0025305C8A1DADE9A1811329792713C5236B44B52AB8791856C535DC8B0E4DD0753689BFE0636DB99697B074BD2D3A8C4AE69929F00B8B256617FCAA96C980E8A629BDA58CF6A76DA49A004055CD4BE21E2C02B5533A7FBBC4525A95167175480A7B09BAC2BAA47A03D4872620C191287932029C9B53737A69148B7F483C607148DB23594DDB2F149ACA20F13AE693C2265A71E911A4D22ACB1ECCCC4C96B1A2C0CD45A5AC25533AF6829919D93770E42BEAD230BF8739B48C9990ECAD9E679C501137C49019C2F857C9D08FD533B01D50AC6BF2398655A1CBABC670299ABF46B95913A845151DE2796666BA6824237AF61789857CCAF0AB0F4B430FE966C85818B11E469CA2D7B705833813B8A775C77138F91700C64BCC6360231B1540F77113A33DA08189E454465474947EAA7F6731613BF9AD6BCC6D7DD1B62E1A3AA67C647A62712BC9CF67FBB690205E6E6997FDA7719EB9994D199505342D42FB3C6AB1936825534980768102619D79B9F197CB05C16A9922B4AD752C4926539AE184756114601A6ED90443D2869D0FDBAC6F447D91F37FD4E6649A90B70C73182B6162375610E9166AC76656A9B9242DA02CEAEB970A1803BD570F48B7B7557928CC4AC5D494BCC9386078183675D760322A91A1FAB770198A437C052EF366F6C905062010AC09AAD9594F581036A7E11B0D6C3B40BBBBC340CBF6D130BFB4E7CE4696BDB01ABE0436AC41B279FD576FE86BE94D213F70E1D563B9DD64A334930BDF5141DF65BF77A06052C9EA81679080E231A8A61E0B97442F30F0F28F7A851B0D3E76BC74DF890916D2ECBA20DEBCBE3453655F78C9", + "c": "07C9FAC7CCCF6B5497C9BCE51371F26B574BE236DB8009103A7617953AD68ABF08A3F134B5C2807229AC884903D3B6B2596020D6C789FE3CAC6468EE89F4004C037125BD1F848B1731424A94574AF2A67ACB415E6EED82167C590C61DB7B34BCC571178794DBCDDA2B404B4F4A25D17EA1503A820504BD0819F248F472B48FF54B3CF01F8DD743ABA8495AADD848F1F8B3114614463FFD7CE3E9726B9F13F2A4DA5DD7B761C484E2C98D457FF788BB5DECB6C9223F112BA6A5064854056D3884DFAA65A677C13E785CB30925BD5878A1515087472F285969D38B937458F7A8C968BB86D8AF7EB851EF950F83D554115E84D743A886F7B2922D581499B36CE7A049E35C9CB629889B626620872BDAF1B31B1BA08545CC57D2680B17E21F0FBA6EA16EDE8B956E497DF4C2960221FA3D697BB33CD592BB3D370834D9A5DD325ECAF88B87E8249CC70643FC807D085B357105B235800A0A7260267A9C1888D9CF620AE27315EF42A808BCBCE4D705C63EB5319530B228FD233BAB8C53F84277037A441ABC26EE386A06028BF75470D3B2CD441E93547F519DE930EF1871F96FEB3210FBADA58A39CE69417137A9EC019A12CDC5DD340B613F6DB2C08AD937EA3C31B553D40D176CA69643ED16CB525A1FBDA92FF6FA87528DC20022B75B99ABB49A5838022F271698EA91F25D3613A34C686712A9327ADD20F2324E3A32C5C33F234F879CD28024E312926C9B2D5C327AB26A29CE4E4200D23B4BA7CD541370AECFAA6A20AA025B969EC6017033B32798CC20E3A2C69725B5262ED9B8384110FFFE13687EDEE0AEACA60DEC2576CBE150508C25E69796B792F28A08DF7A1949FEA5FEA4AB9376CC4C3A604847CD69B1ADFD171983D6E894FD886CBB3F1CF3704ABA6EA413D0846CE803AF766B67A37A058F95818AF1FACC2AAA90DE7CD503A188295701F1CF204344E31EBDFBAEEF2521201DBFA905774C31791F7A766E4221611FA3D0ED8F0CC491EB9A8B8A9994073D746619FB2BD6A11F9770C0DD00B17D56234240CF014BE52ABB743DA0F9CCA508BEDE7BC5A011DA9F24C55F1AC2BFD18A813CA6A10985FCE51722211B8A6FFAA3C793D9CA4675F56B8743D454F78FA5EAA75CF80030905B844ADF4FB15EABB755FE5BC18523C8BDD6CB75BBEB3EEA082D9A7FBF97F409CE8B92F366195C80EB216C052C45A1915530BA7B9ED90C6ABB5B13B723759FCA390BACA96C582DE3B3C5D4AB46A9DB5E241935F12284ED11BA6AACA5988F39D2F0196DBE0C15640DD2FC44F206C60C936C53C4443F4BAC175BF5C60C3FB28ECC4862C03AB3AC197577B3CC4FBA1289733124E8E247392D7C87AD9E365A46003FC510DD9C71194600BFF8AD87792F251E9141E577A274253ABD987E239B69A59CE5277576236423865B59891BA9BB053CC215CF0F1885BF5E54E33CE85A9C2D915839616D44CAB2E34E1E4509F49FBA104E0CF58A8327A6A7C53A2F3508E34568923B4CD21E1B31D7B985A290D08422EFD30715EC0F6A0EC0DC7789", + "k": "2418BB42B89BA875664583EDF241327F3798379BD14B64351044F6C96B3D2C27", + "m": "F374D3C7172C308D7AC5AB1F1CE5BB9785B98AFCBF4E9120B42EA83BD3BB1867", + "reason": "no modification" + }, + { + "tcId": 49, + "deferred": false, + "ek": "75F91DC864B819E71CE8CA50A7BB41AE94818BAB31B7F888ACE44071D2795361CA2B2666704721B02558212AB41A300B6D80B332A50448E36786D101A68A94D42325F718CCC4EB3521424C35E02A0A1A7A3514696C547E1918982B1066A3CB633E2B1D23280CDB333AA7B3C4BE7C18AEC44678D649C8774A4C552E45948801681F883165EB2C5E9D43CF38628E8C934C5F30819D4287AE4A51A797BDB0769534169E293C3A76A76361D79DEDA8068FAC187EF6B647C148E919141F02564B0AC4996B27794915A2D1C669DA50DD9B6E9BB57612CBC83765AA962068B8477D703848DEA456592A89B3CC321C3B86C55AB980BACD2F2605395BCF9E965B95D59DD608A8B8B85F66C8822F5B2DEDD36D3F97BC1503686F74991093A5799A146B434C7C2A6C573B3AD8C44FC517C92D042D623A7414D56DC45454CD08919FDB8D79A7316A4C14AA9961DA76C9DDC4CC6CDB37B474835E9A86563212F2B3908875588E2484BE8C4A49E3BC5EC609FB4BCD52D62AFB1B713B556CDDCC8BBD3B322E1766C627A0410A3D5E0B6F3E499272FCAFEAC90CDD100AB5D686F22023F8413F64521D19E38EBAB1CA6E31CC10278184F50843DA5CB1BB5164DBAB23374065B1043B1A7B1A241DDBD4BC6EA9057CC1A995644AE73231348414414C7EBC58BCB9B538A091434DC9010904BAB0613FA640C0A903BBE57A100B08A44A70507436C366268E7531C84A977B9EA2263E770E98306537B505A01284F653C066BA2F9FBC6CB3740258892076C01FA5CBBC8BE97FF0830BC746BA27555305D17A931371D04873CE2B89F5694BEF68515E7552EE03BB8E0517622768E6022DFD1044CA86A715930530E504D8031574087572974915885CD0351AF3610A5154559F688492579BB723A22F791B089C2CE3A383C09CBEFDC151DC266DCD54C196F25F0EE34092109C6AA6CAA76373E9125E143B2D0EA0874E4A35F06961DD812E60700F598926FAA7C1F7CA579CE9AEF3557F74E2039059258A001FC7F3B4A4ECAC6303672F12B9CC366E448124A27CA6FC43C6157A378535817B8B0C981809ECD54D92F135D0126480804EFFE40134E6C2190B95BC7C5E6A72B6487A6A454239DFE10AA99614AFA6A8F0E12FA86007CE464AED4063025B213D8597D412C9617AB62D9592D4320D7F97A6AC4092DCB311C21636358172C43B5626642336A96C1466BC30426DFAD5C0DEA50F715B19827B1935C79CFA1C9CA1F799F3954EB1C0720D134CF9A3122263B995E9268C3A1BE18A7112ECA0C4914F2659734A31A5D5708F3A145E6801C18761A280465C2D4600B9D968B3CA61EF9C7687FB1597499597ABADA930AEA4666DF40029F645A601984646144DB4CB68B3466CD7DA154C027536886A390234CA792FF6AA5C7CA258831AC1B0FAAFC21890BFE522A7685837A550CB343B79B2955C4ABF4939792133AB0D4A77C909BE0F0233AA80AC6B6AAB0F8102F374982C6BA88563ACF7254760263D7EC8C302F656BC227B3B558BBB444365A2CD95B421DA5914417C50E84311C6A2218A49169866518C201622F10970D75D38815787355A0C6126EBF189AB30321C15898AB117F6183C47174DAAB7BB8F96C3F4F239B642516A48F015E838A3DBAA500DE409C13F28FCCE5F266A98ABCB2D92E1BE99E438BF", + "dk": "95A85BE67984E9D6BEA070223A469C08D73C6012AD76261380F45A7DA43CFC831E92D55C566BBDA6E6B1BFE83CE7E5523829C5D3C2B5CF874FED240032B43A011823D38856E519868CB0A9B0433A51167835568EBD67A2A6991B8C529E9BDAA0A4A95BBA93480909AF3931B969869C3A425669B412C60B5AF2D6B874C98E01DA95FD0672599303E25CCD42D7B19B73508CF286FAB706074A98437B7C9B7357DE242200AC71FA8636381623233135E530BE92E83133092B17A26F688919C5A45634971D129542FF2362E94243F2249B65C9B2F9729FE6425E76E36FB88019C2A863CB617C58DA9209A92C2A405E35574198E83739772F63C97CD90753795C981C81BD3CFA384A6CC51DA15F21D7BDB87B6CD2BA10F928C9AEB1595A4539C8A3600331B07256680E4C0648A0A786747E00672B08DA47F29A3FA7D9CC2E119BC6EB579BB30037F66ABD645951F499FDF12ABB3C979FF90E15A5397D2358BDD6CEF02B5658B44242A74573D41C216554CFCC2CC4CCB48BC488ED5A450210CDD0FA1D04831E14514BB93148E01BA975B71E5463001CA8330AB2064F31346C716ED431BD91A477C660535D88B32E3AAB39C4A9DDC2BABDA392FDBB3DDB3611E06A42E1AA18F985B8D202C23A5443F5B6C161579B6FE0C2A1A20347B2A48D77CE8F954F7EEB193470C90A66B3EC7266AAE78BCD2469A5573ED4D2CFB600A7764364ED47C4C3DB97E5E5170361C09BA07E7B3B16D07432A7100F0615506D32771A7258F1D33B71101941A148C6368C9DCBC403037037F6BE9620BDFFB418BE497942C410C6E6A957E604B0F4467678B83BF9BBD628BF5929A63C6170C065B6F5D84D7E2BCD8EA019ED72A600E6AED7187A1CAC1506F95127CA235AE9ACC89B2CD709C18FD895002C3B2400C38DA16DFD7B2221D9BB212A471475845A58B7342830DC49B6676516EA9BBE4C458BE77B6A99E518AB1C1BB8CC54B50392FAB00367940B790C6AEE35B587E6060ADB3C92FC579AFB459B3992B6E110776115ECD03C625B9DE1378C85FC5EA0C8AAB6818D123A5F20866984D4C6D261156E78A15D322E9BB4B5B288B6E6C03ADD4A9285ABBB460C9D2C0629AD7CC48351BEA588848D95283995CC7C081A8BF453EA62B3AA48608AC2BC02067C93D01CBF1531C0B35F52C32BF1748E56185FC4C24127E9CD94A9C4E8AB12C38086F5A17B0234A41A6C772466255B1C8F95C4BB4D7048E9A542D8B7B36DD59CB3F48F08891B2BC6590A179787CC83E41453438CBC34318BB0B072AC6A013571270194508986BD5D74724BB22724B2B18AC92A3939C9589A03448B8C8E812C4E2486501A97ECFCC84D3A32824160EA183C16F3839FB20CA8FAAA4ED54FE9625993F1A064809537525F9872AB31EC9B6AB922CF6806714959AC63A89F51570A98033585A99E72713DA18A34C57A2E5A558F56A04E185864398C56888FFE66ABB96BBD12B39DFEB0909D0A932D6943031693F0296373246D35767E74B4C29EF52ECB1B371B77AD5588AFEAD9CDD978331B7A51E4C4CFBE9B17550C20DB02742EA8737D8C26214791F4EB3D7CF1329E45600542560E9A350CF74412F1681178A0ABEB6706595084A19D8FD5C99811A275F91DC864B819E71CE8CA50A7BB41AE94818BAB31B7F888ACE44071D2795361CA2B2666704721B02558212AB41A300B6D80B332A50448E36786D101A68A94D42325F718CCC4EB3521424C35E02A0A1A7A3514696C547E1918982B1066A3CB633E2B1D23280CDB333AA7B3C4BE7C18AEC44678D649C8774A4C552E45948801681F883165EB2C5E9D43CF38628E8C934C5F30819D4287AE4A51A797BDB0769534169E293C3A76A76361D79DEDA8068FAC187EF6B647C148E919141F02564B0AC4996B27794915A2D1C669DA50DD9B6E9BB57612CBC83765AA962068B8477D703848DEA456592A89B3CC321C3B86C55AB980BACD2F2605395BCF9E965B95D59DD608A8B8B85F66C8822F5B2DEDD36D3F97BC1503686F74991093A5799A146B434C7C2A6C573B3AD8C44FC517C92D042D623A7414D56DC45454CD08919FDB8D79A7316A4C14AA9961DA76C9DDC4CC6CDB37B474835E9A86563212F2B3908875588E2484BE8C4A49E3BC5EC609FB4BCD52D62AFB1B713B556CDDCC8BBD3B322E1766C627A0410A3D5E0B6F3E499272FCAFEAC90CDD100AB5D686F22023F8413F64521D19E38EBAB1CA6E31CC10278184F50843DA5CB1BB5164DBAB23374065B1043B1A7B1A241DDBD4BC6EA9057CC1A995644AE73231348414414C7EBC58BCB9B538A091434DC9010904BAB0613FA640C0A903BBE57A100B08A44A70507436C366268E7531C84A977B9EA2263E770E98306537B505A01284F653C066BA2F9FBC6CB3740258892076C01FA5CBBC8BE97FF0830BC746BA27555305D17A931371D04873CE2B89F5694BEF68515E7552EE03BB8E0517622768E6022DFD1044CA86A715930530E504D8031574087572974915885CD0351AF3610A5154559F688492579BB723A22F791B089C2CE3A383C09CBEFDC151DC266DCD54C196F25F0EE34092109C6AA6CAA76373E9125E143B2D0EA0874E4A35F06961DD812E60700F598926FAA7C1F7CA579CE9AEF3557F74E2039059258A001FC7F3B4A4ECAC6303672F12B9CC366E448124A27CA6FC43C6157A378535817B8B0C981809ECD54D92F135D0126480804EFFE40134E6C2190B95BC7C5E6A72B6487A6A454239DFE10AA99614AFA6A8F0E12FA86007CE464AED4063025B213D8597D412C9617AB62D9592D4320D7F97A6AC4092DCB311C21636358172C43B5626642336A96C1466BC30426DFAD5C0DEA50F715B19827B1935C79CFA1C9CA1F799F3954EB1C0720D134CF9A3122263B995E9268C3A1BE18A7112ECA0C4914F2659734A31A5D5708F3A145E6801C18761A280465C2D4600B9D968B3CA61EF9C7687FB1597499597ABADA930AEA4666DF40029F645A601984646144DB4CB68B3466CD7DA154C027536886A390234CA792FF6AA5C7CA258831AC1B0FAAFC21890BFE522A7685837A550CB343B79B2955C4ABF4939792133AB0D4A77C909BE0F0233AA80AC6B6AAB0F8102F374982C6BA88563ACF7254760263D7EC8C302F656BC227B3B558BBB444365A2CD95B421DA5914417C50E84311C6A2218A49169866518C201622F10970D75D38815787355A0C6126EBF189AB30321C15898AB117F6183C47174DAAB7BB8F96C3F4F239B642516A48F015E838A3DBAA500DE409C13F28FCCE5F266A98ABCB2D92E1BE99E438BF3220B4816EF8681B4DB93059811DA8B0D65AB12AB874E57F3B09C33BC6C20A028449B1C5A6D50E3AE0E604C9CA666594335BB1B083669CB54EE7E960D8905C8B", + "c": "36DC4E1498A52C255C5AC4A9A1AE3F17F8472B71548C919FB7C2F3ACF0A35D6FA8584307282CB7FC9B5B04E5E1047BF03686981708A62ED593B6DAB954F39670036102A0BB348839857A68212C783319678819F6CA6CE1191B34D86157838523BA0A69B7B695139C17C21FECFEEC191930E81C66D1177A277E77D714B2EDCC33BDC89A7F14A6B83862300AFA860F229FABA58D2B2E8C89C734591E7A1CB1D65D87C6A0841B78ACD1BF05BCCCDED0F27B38DD27E57EFFF3BC4C3E80ABD4A78F85D233EB8046FF2BB7EDC87BABBD280D1F3650A3BF621A23E0C3A7BD42F8AC90B0F741EA3B3E8D65F0B1774FCCAF35FC809514F5D4EF303D821A2DE926BD700B085B92BDB91E8D04B6EC23C8000D8E1426EB7743D999B845E79CE993A83F202E2E82B0B491DC6BB006D9BE69311BC5E980A95EBDFCD65DECDF42B887C29281E8F8C19607175080D04485E5DFD0F84219A5FBF8E94C7C16C44F10274166CE965AEA357AC9C5A2BE63E47603F6D4D5469308793D8E3F6ED473AEA36C68E3F9FDFDB97996B34020978BD69410961FB216DF9F3349CC6B6028ACD3255EEC2C14F2341858782B8C34D3141A19F8A64E989F70A6B67B200E8E482A2E271077489B7C97D567449E2543CD5735D7A70DC1FB26539B996A550DB92C9857C9687492238B108B40548C22A5442150604D0C097FB02061F5E45552B4B443E7F31D85CB5BA9BAEDCD839445613E9C9826F1427755A36988A7E175E729D801468F986B6A0553C00562606B032F7580D51AA5DB6CD214D69E8636A8FC957E7D3907CB5A33B2C80780B7D782E040B9914A7B8EC51AA7711B9D27581FD2D5055E618467D2EB94B4FEECC66C96268C62222E3F438293C2733EB921706F1D669B55C3EC9AB54F6507A4E0D742494B8788988E9A628A5F5C1DCC2C5AA659723006BDF0ED4E70A8CC194416E11F5BC812599ADB937A25B302F6A371808443377EEF2E2A3F8C7A3C7294EC7D7FFF22DBD3BE07F89207B30228A20DBF432CA96549794514BA4BD27C0FBAAD1290505471E7BBAFE53E039B7476D4DBADF13F1DBE83A9101F58351682AAEBB435C0AD8FD6148981AF7885A9F49E7A802BF226182597EC5BE5DD5E0381C1D72CAA2678D0FC4B354469669C271D331C328560055057B25F92FCDE0BC378AE6886434BB85EC96FEDFA369DDCE4F36F8AD8FF79894A1628DFC68CD53542EDDEBC0D92BBFE2F7601621693B10AA2A3CE2ED2CAFCE6BCBA4E7B0BEC2E5656F1ED4B751F081BD4A0356B89815F724A823030979AC1D6C8B1CEB63980717EA24803B2D6E3FDD9F5B4A3397F4DA86834D99FDD91661CB1A808A197F9FF122B2843B0E4230230604640D82FC26AF612AC980E6516E1B6C5724B579154EF2F770983C0BA33B832C14B691282B9381AA708E49D812F7EE180B0F9858D4D21386C5D60490083ACA768181C2840E5EA30833C3FFE79E2747892AB225703396D792BE152DE2E8802264B2939296A9E1733883F430F372455D520B839C0DFF54BF76F2BA87B4A5960", + "k": "2F323DFA37A737802227ED21012FA0BA624F532F8A3DD979AEFCC554C1C2BE92", + "m": "DD252F728FC9553CFEE90924565E984C8E1462CDE58AD8C4ED8DFCE98A7F39B9", + "reason": "no modification" + }, + { + "tcId": 50, + "deferred": false, + "ek": "19E628A96B033E4358CFA8C3C4A642D7127C16A50BEEE5C57A25476D8BB86D019DAD84C613D96A389802EED2031B1A07D478612DB405BBE9BB42A4BF9E7AA91CF2950D00013C4CB7A9B0CF88A87B19E41995EA9EB09660746B1A81A2C74F0BBC28287851CCAE8CB8118ABAA627F44289A9C355DB863095B397D1C449C20AA60B5F1EF94F9002B212C733D81C5A92631CD3B661B11056C9026E84A34E19836411A76AA53089071194E2C9696B31BE8351CB735521A42CB83C52C421724F2FB76D245BB5571358314A2967604084F64AD30911600B33AC9B236DB66487058F35611D0894051F31C032972A03A1CA5822317F953F91A74885E21766824F0FB601C593BC64253E7C36639462721C232D32A076EE245B9A7BC96C0A70ACEA36F8F41E1242AB2D00593BDA4C550018B1345D0806A3D1E8C7A8CC29790127370754A24A73E3A4B08DEC3A88C04C2022235E55CDCAF80938B579B63123E306603C781FF3ACA1105076AA2BBA1D966BC28BB3F3A7340D210D7E7A1735B01E749C0AE990775E2306AEB80229B918542608B7E281B6BB696E1C82342BA196D15EBEF20D541CC57CA928A9DB41E972CC1CD333BC7A64952247FCBC578860191FA67971A29E40C06B81CB5A765C7B26522C19A63C40EC31EBECCF7DF44CDB8B4E7BC805D42A28ACAC3EB2684ABDF46DB7E4C5B01A770B4C0D79D7190B97461BB75CD4A78574677CE26BC30CC25215B1C20C290A1575790C86AEBDEC7993CC94CAE23D5FA2871A184E721886BC920CAC11607FE96878971F161B788E5653698A9F8981339E581969C1B61A6073C02CC3822A2A2D0A6F5BABCA0D57175B86942CFAC2B0FC9F1684324A4139CB1342D7A6B26643A923FA14988173E58A82B67532C6AB89C0D5AA1CB47E44703FD7AA6816501023229B1E76833D7948F0743BE373BCD361130899010727CDACD4347B3A6645541BC7173361860953E61F5824BA2ECB94101383DA6A95CB4591C1BAAAB1B221F43B91D7985A173A0FDA756FE9B38ED1EA4F2A428E34F352A37A45EA83998B66C4E60B40650A87FF5185DCB0055B9C011378442462C285D18A0DBA658DC5B17D1620CE566C86879F38754CC8C1BA014827B444CCF8E9029A7763318CBFE0220DBED60F6720C6F96B4E70C712B58091BE3A6C1C4639D1ABAB09674D2E653DEC768D728BA593AA3C61B17DE17A07B3E85558F38DBF848D65AB3A1AC183A62AAD4CB18344E71BE4C97FEB59001F4ACA46342AAC389B22C47C2A216D9AB50B1A02405DA01494C44184363C31F5C39AC90507D94093F882E6891E24571BF39932DC5482554C12AF6A5F0B3AB4CBD276D6D850894CB4F414196D511731D23C8E039282F6C11D089BEBFB91F0A766935B3ED66458842B4C757585FA6657947529294930C886A50689CA5DF1AA39B8346A14150F051E5462A99E56CA383BA5ABD455F00AA9BBBA660FCCA2C5A8A74299581C274B89E4756552570A33514CB46CD7A3AED34A2DA42C49DE1A8645D64AF3D644BE586068A1B5804965BB7A6134CC8DACD82FF2E954625C92B0D9763E22CCF7450A8FA70F5793400D2832A03A5A75D404D1E2822DA607F6F9C4FB510858978372C621AA72399A34B9E2618F97EAB82B56D93E51FD73A90A78E2AC85826B8E6335330DEB8C644A29A1", + "dk": "D9758470207110D1C1DE602163F955BA262CCF3564AFD86DA03047AE9C63F5A67587E008CC3423D221949505C534B6998900114A3B6775F1715AB139CF4C8C5849A034929F957407C4512091930A5B9A38846402AAB49DBC39160B0ACF4B6A3E9EEAA095917828F28F667C9904B8A7BD4C231652A32343BEA81A7EEDB68AB1229FFD16CAA46B67B9F264150AC2DB97CE09B55E4312654E9012F2699243F41B380073C6A5985F87125DC199BB05620455A2BB77222764C9D7966CEFF2467D632964567CBD1B98FF062CEDF1C23A31B891C48C0B3833660C3C39762C4A470C85F802C5A03FCE328B21A658391A7B417B2EB5B37EA1262817EA78BB72C833C08CF74C9C34075AC0B975AD6ABF2DBB1AB72A9EE5758A1E47B1E5B41506D39995D04CC942A0C2306BF270CD43E1373F82B2DFD8A0294BB2AA37C762684969B2046FB04DA621AD990336E2FB3E53780B311872F9E581B1890A67EC4951C071FD7091DF250F06F367220B0EAD226286E6BF1DCC63D0E85A2C64B39BF924C3716F045411A54A31EEC41BE1846E08649EF19C78E1A938CDB1034BC5879CE91444BB126DACC12EA2A32D4C5749E3C6F9E270F1B4B0E2244E3308014499CAE3640E96E4ACD5F1C641D5B2E1CA4B9D65654CBC2A53499E643A9E9E1A2453EBC707A20E070793FDE87E12F71FD060186E5690E5B031F858CB991714DF959D6269209454360471C4E1E365DED681636B02592A2747F78EFDBBA0841C54DAF980CBF728EDAC5EA7B9556AAA7746CC209408495DA8547E392A4A02887618A7F7C25537596254D48E9AD94A52E1A334A06D2A22A358D1121C9A81AA6C1EFC08B3C8356212F259699163EBF1A31EE845E13AA10652B41580BAE9D683E8B958BA95257E947C12B04DC73299EF510FF5C94F598524CE790D21372728B38AFE966AF114C2DBB094BA216F65D2476E6B5898BB2C72A0C8C1311A81DA95C0B03D942C81ACB73BF13A7B1C22B289C0A5DC7C8E9A71480600BE6F5A14BC7340C9290C03F984EDA2A8499534FD0BB96BA1B4D1335974350A32FA9911396C3BEB940AA1A87C86C3F08C393A18CEFE7565EA6402F8C0914735AE938C3977576CF9941070583015A8499E84C588F13F9BB29FD278659759A08978585CB33D213CAC9270BD7AE3C6A1612523C8ABF8F7C4D3EAC1F6F7860F02C9316005C647B30B7C3E75CB73CBA301F2DB327C0B38F7223881B70456834565B3B0461B030EE68891F22F09129AED4613EEE57DBF0ACD9745ADB89633EDE163ED1C3CBF935C5EF90E4591C7E0B79E2CD629E9A963415B1071256BC2C3905BA30516D01B3CB1C10101830095BBA6D08E7F2006AAAB4B11852A0E2C8D780001C99899A65B96E6BC3B68D84F28F34FE64A9578C078611AA507F15BDBB99DB9F943768B1D4DD6A335D6BAAAE33288B16EAA6496C312B0A08B052F9B9552E23A0EA59E9FE329D461A8CAD9176BFC7006E20985157023BB503599A1798AA89D406FB3E4586F230F797CA17D121CA4AA568BA579AFD8575C801A734083F9214CACA3C6CF3ACADAAC27BE1807432C11CAF806C66953EC6A3F24390FA4AA78F5B90BBA061238F9817FAAAB5D2AB0CE8A3CBB6C686645C6A08CC919E628A96B033E4358CFA8C3C4A642D7127C16A50BEEE5C57A25476D8BB86D019DAD84C613D96A389802EED2031B1A07D478612DB405BBE9BB42A4BF9E7AA91CF2950D00013C4CB7A9B0CF88A87B19E41995EA9EB09660746B1A81A2C74F0BBC28287851CCAE8CB8118ABAA627F44289A9C355DB863095B397D1C449C20AA60B5F1EF94F9002B212C733D81C5A92631CD3B661B11056C9026E84A34E19836411A76AA53089071194E2C9696B31BE8351CB735521A42CB83C52C421724F2FB76D245BB5571358314A2967604084F64AD30911600B33AC9B236DB66487058F35611D0894051F31C032972A03A1CA5822317F953F91A74885E21766824F0FB601C593BC64253E7C36639462721C232D32A076EE245B9A7BC96C0A70ACEA36F8F41E1242AB2D00593BDA4C550018B1345D0806A3D1E8C7A8CC29790127370754A24A73E3A4B08DEC3A88C04C2022235E55CDCAF80938B579B63123E306603C781FF3ACA1105076AA2BBA1D966BC28BB3F3A7340D210D7E7A1735B01E749C0AE990775E2306AEB80229B918542608B7E281B6BB696E1C82342BA196D15EBEF20D541CC57CA928A9DB41E972CC1CD333BC7A64952247FCBC578860191FA67971A29E40C06B81CB5A765C7B26522C19A63C40EC31EBECCF7DF44CDB8B4E7BC805D42A28ACAC3EB2684ABDF46DB7E4C5B01A770B4C0D79D7190B97461BB75CD4A78574677CE26BC30CC25215B1C20C290A1575790C86AEBDEC7993CC94CAE23D5FA2871A184E721886BC920CAC11607FE96878971F161B788E5653698A9F8981339E581969C1B61A6073C02CC3822A2A2D0A6F5BABCA0D57175B86942CFAC2B0FC9F1684324A4139CB1342D7A6B26643A923FA14988173E58A82B67532C6AB89C0D5AA1CB47E44703FD7AA6816501023229B1E76833D7948F0743BE373BCD361130899010727CDACD4347B3A6645541BC7173361860953E61F5824BA2ECB94101383DA6A95CB4591C1BAAAB1B221F43B91D7985A173A0FDA756FE9B38ED1EA4F2A428E34F352A37A45EA83998B66C4E60B40650A87FF5185DCB0055B9C011378442462C285D18A0DBA658DC5B17D1620CE566C86879F38754CC8C1BA014827B444CCF8E9029A7763318CBFE0220DBED60F6720C6F96B4E70C712B58091BE3A6C1C4639D1ABAB09674D2E653DEC768D728BA593AA3C61B17DE17A07B3E85558F38DBF848D65AB3A1AC183A62AAD4CB18344E71BE4C97FEB59001F4ACA46342AAC389B22C47C2A216D9AB50B1A02405DA01494C44184363C31F5C39AC90507D94093F882E6891E24571BF39932DC5482554C12AF6A5F0B3AB4CBD276D6D850894CB4F414196D511731D23C8E039282F6C11D089BEBFB91F0A766935B3ED66458842B4C757585FA6657947529294930C886A50689CA5DF1AA39B8346A14150F051E5462A99E56CA383BA5ABD455F00AA9BBBA660FCCA2C5A8A74299581C274B89E4756552570A33514CB46CD7A3AED34A2DA42C49DE1A8645D64AF3D644BE586068A1B5804965BB7A6134CC8DACD82FF2E954625C92B0D9763E22CCF7450A8FA70F5793400D2832A03A5A75D404D1E2822DA607F6F9C4FB510858978372C621AA72399A34B9E2618F97EAB82B56D93E51FD73A90A78E2AC85826B8E6335330DEB8C644A29A16A3A54F67614A889B92ACBD1D3EC4CBD6C46E8B33FBC2F3C92DF3887DC1DA71A003B9B894A4AE13E6F46DED925CA80189437C0910FA73E146A646178544922DC", + "c": "958FB0A1F80268072D82D593A66B039E548E205C63A4689B48E0752F9041E5D1C2246EF6A1BEA2773CCCFF2A80059C651DA70EAE2AFCF2E83CA15AE29684A11213C01E0DC9F3A25B492A8B44AC188D187A24A6A30B82AA7BD80CBFB992455F280D0D36D2E0A0B3EF65606D55922D29C5A0920D57F8F6EA2AD518B41CCBA23BCC35BAD2E844B5D9000E36AE1F1DCB3D3CF23922D82446506038D5C33925AE96E174876F0C96220BB775EBEF7AD0E48A1E1C785633F6B3585F5FEDAF521F8343440981FCB72DF5860A42343824A0F43A0A371E7D41472199F749B310AA32A5769DD29328E60A7424FAF2D90E6FAC34653B5F59602785FBD09BE26D184B61447327F3772A072AF1A7D4317722AF139EE56D4A7D765D6D73D7B13DA6BF4ABACD1B82320ADE56624CC75BA78278B38F4F4E17FC704B5C88E4800A6E4F626DF21974E2D76AD9BCF70BB9826D790D8A7BF7F23FF9D03021D9B6F48D89D855F4D070CEDA92B28915EF2F77BB79BF80D9E03D9730F1B018AB3AD932588805E995010134774C9C061D11BF852AA5C7403515956D29924EAA1B6BBBE4E4BAD554F4C91F67A268744A12FBE28C3D7A403776DD742431EABE6EE093B988B7F5ACCFF53AC714E03306773F9E54234BA12B1F35421CEE91D81E8A2F91D8AF62733A97A93B1FC2053216083044156ECBFB9919B25C9F3187E07FAE83E9C662AAD0571505413664FAC5ED94C5407CA06036B8C377D8D7D306E1548539B5219CB3DD77D78475EC2FA6DD4C06121230D99151ACE36BF3A3B8DEA00636EE1F6E80D3604E76B3A8E13395B4D590A389F492931A6B37EE27DFB145C1F5C6EEF8615E673E6F6A44BB69F2C19E83A1BCFB3ADAE4815C2DFF7C8A6FA39D41D2A95BB4452D3AF38221754A41E132BFDC70B6B8097D2EB19DA00D55D8DFA80C59070D325766831451B932C2686A71399DEB0F8CF3EBD32C1F6360C1106522BDDD3F3D061196372BE337BF35040A57D1BA098AEDEC56ED240B8AEED2E8A8C0ACEA5BF4109CFD6C55DEF7883A848132BA492FBD364A8B0BDE322EF62D907106F07BD44D97D07AFBF9AF057D7397A2FDE829123FABECC1890B08C18EAAAB2F32B76A7099B3DC09EBEE6B9774AAEF06EDB414E5DB1559CCFA65023D203EE7D867AF48931F06BB86B3AD7E9C0D52A8BD97027A9AA865CDDAE57853BF8F3AB4279533C5D83F240F181A748BF0761CA97130D59C751F8C87544E93E98BAE954EC84AACE8F70E2E6BBDA10389C825E29A147415FAE1B75DF6F1F17191458081EC5CC791250805E5BC1E51273AD723BCA56B3C99FC51EF8B304B960928BF40737BE291C9FB3BC1B051F8D40DB99EFD3260E0121C66336F78901451D3A2D1C2F080FF3EB5480295E949BE9CC5EAB852483B6E7668C6414CF10F6B416603D82F517224FA679BF3057EC4F6DB856A010B74769F78171156A7A604B1F63980A4AA1C8C57442A1596FF8605F3BE684C1D0841F8F4016EC54F4BE2527349B2F0B21E926DC01D324D5842ED2A69290E908F5ABC8855", + "k": "C44EE4E3EB80C46D6BF5CC3E08CB93019C8C80DB0CBE89708E8A6902DE87B699", + "m": "297ECD18E2880A596F572B66458410A0D827851EFA55F1C9CC513F7991F0DA0A", + "reason": "no modification" + } + ] + }, + { + "tgId": 3, + "testType": "AFT", + "parameterSet": "ML-KEM-1024", + "function": "encapsulation", + "tests": [ + { + "tcId": 51, + "deferred": false, + "ek": "307A4CEA4148219B958EA0B7886659235A4D1980B192610847D86EF32739F94C3B446C4D81D89B8B422A9D079C88B11ACAF321B014294E18B296E52F3F744CF9634A4FB01DB0D99EF20A633A552E76A0585C6109F018768B763AF3678B4780089C1342B96907A29A1C11521C744C2797D0BF2B9CCDCA614672B45076773F458A31EF869BE1EB2EFEB50D0E37495DC5CA55E07528934F6293C4168027D0E53D07FACC6630CB08197E53FB193A171135DC8AD9979402A71B6926BCDCDC47B93401910A5FCC1A813B682B09BA7A72D2486D6C799516465C14729B26949B0B7CBC7C640F267FED80B162C51FD8E09227C101D505A8FAE8A2D7054E28A78BA8750DECF9057C83979F7ABB084945648006C5B28804F34E73B238111A65A1F500B1CC606A848F2859070BEBA7573179F36149CF5801BF89A1C38CC278415528D03BDB943F96280C8CC52042D9B91FAA9D6EA7BCBB7AB1897A3266966F78393426C76D8A49578B98B159EBB46EE0A883A270D8057CD0231C86906A91DBBADE6B2469581E2BCA2FEA8389F7C74BCD70961EA5B934FBCF9A6590BF86B8DB548854D9A3FB30110433BD7A1B659CA8568085639237B3BDC37B7FA716D482A25B54106B3A8F54D3AA99B5123DA96066904592F3A54EE23A7981AB608A2F4413CC658946C6D7780EA765644B3CC06C70034AB4EB351912E7715B56755D09021571BF340AB92598A24E811893195B96A1629F8041F58658431561FC0AB15292B913EC473F04479BC145CD4C563A286235646CD305A9BE1014E2C7B130C33EB77CC4A0D9786BD6BC2A954BF3005778F8917CE13789BBB962807858B67731572B6D3C9B4B5206FAC9A7C8961698D88324A915186899B29923F08442A3D386BD416BCC9A100164C930EC35EAFB6AB35851B6C8CE6377366A175F3D75298C518D44898933F53DEE617145093379C4659F68583B2B28122666BEC57838991FF16C368DD22C36E780C91A3582E25E19794C6BF2AB42458A8DD7705DE2C2AA20C054E84B3EF35032798626C248263253A71A11943571340A978CD0A602E47DEE540A8814BA06F31414797CDF6049582361BBABA387A83D89913FE4C0C112B95621A4BDA8123A14D1A842FB57B83A4FBAF33A8E552238A596AAE7A150D75DA648BC44644977BA1F87A4C68A8C4BD245B7D00721F7D64E822B085B901312EC37A8169802160CCE1160F010BE8CBCACE8E7B005D7839234A707868309D03784B4273B1C8A160133ED298184704625F29CFA086D13263EE5899123C596BA788E5C54A8E9BA829B8A9D904BC4BC0BBEA76BC53FF811214598472C9C202B73EFF035DC09703AF7BF1BABAAC73193CB46117A7C9492A43FC95789A924C5912787B2E2090EBBCFD3796221F06DEBF9CF70E056B8B9161D6347F47335F3E1776DA4BB87C15CC826146FF0249A413B45AA93A805196EA453114B524E310AEDAA46E3B99642368782566D049A726D6CCA910993AED621D0149EA588A9ABD909DBB69AA22829D9B83ADA2209A6C2659F2169D668B9314842C6E22A74958B4C25BBDCD293D99CB609D866749A485DFB56024883CF5465DBA0363206587F45597F89002FB8607232138E03B2A894525F265370054B48863614472B95D0A2303442E378B0DD1C75ACBAB971A9A8D1281C79613ACEC6933C377B3C578C2A61A1EC181B101297A37CC5197B2942F6A0E4704C0EC63540481B9F159DC255B59BB55DF496AE54217B7689BD51DBA0383A3D72D852FFCA76DF05B66EECCBD47BC53040817628C71E361D6AF889084916B408A466C96E7086C4A60A10FCF7537BB94AFBCC7D437590919C28650C4F2368259226A9BFDA3A3A0BA1B5087D9D76442FD786C6F81C68C0360D7194D7072C4533AEA86C2D1F8C0A27696066F6CFD11003F797270B32389713CFFA093D991B63844C385E72277F166F5A3934D6BB89A4788DE28321DEFC7457AB484BD30986DC1DAB3008CD7B22F69702FABB9A1045407DA4791C3590FF599D81D688CFA7CC12A68C50F51A1009411B44850F9015DC84A93B17C7A207552C661EA9838E31B95EAD546248E56BE7A5130505268771199880A141771A9E47ACFED590CB3AA7CB7C5F74911D8912C29D6233F4D53BC64139E2F55BE75507DD77868E384AEC581F3F411DB1A742972D3EBFD3315C84A5AD63A0E75C8BCA3E3041E05D9067AFF3B1244F763E7983", + "dk": "673751CBB596541131C66398662CB4B0EB80796A88B28144A5BBC854F80D4B35BE0AB241E4795F8FBBA814F50FA80498CBE8BF68A0A583A4C5981B41DF0667DB614A628C3060697438E62C8D36026EE29C96B673BF1A194EE49481351F4D1748DD01CD023142F01057142B741CBA8302E432F88C63D0B4B5767AC3A5A59AFA3A321E65B1D1511807A06E16A04B2F1070E465586D4A9B68E2B42D57A356FA7BB3D04E51B193FF4C757CFA0F15924EA6E49AFB83B2919C985869ADA544338F44AE96A874C425AF87BC73F3CB0FD2627B1539B1F19A77E36B7FC817851D39BD8A069A6C2202C17469D421A588E65DAF450030B6674EC1C734AA25414B119E61B26EFC90DF81059D2B9599414F93692BF45A4B1C5CC09EDB37B1B1433026AEA6B0200722B819C7BC061C53A4304992FCA2AEE2324A324AB91C3E5D562096B8A141756940F15A2800C274EA4F65817E639C5D2A278C6A294F9DB331F84CCB0A10309F530A06EB962573C86005C15BFC7531A143026396721297E25CB655A294964B2FE531905F2802376B8ACE35AE3E2814BAB7062BC1A840657DBFCB5F41BB55475697849A31E2222E995518CA7640AD4B9CEE9820984138BE0510FFD6AC225393A5F0CB030528CD2A0610E78A5CF1B073039A6D143068C53DBD15A1D4446DA7B310EE795D1FB31B2F97008F83BDF348A593A3BDCBB571907B36D0978162C253E6F50106C463149834ABFB0707D8AB4A4BABC323598A085B309764B7C32C9DB0C9F2D52EF2F00BACE7846868C33B82AFA430A4C2F67B698A60526A161CD62115DCA767C203E3E2CC787031A73B5B7DBA1EEE5AB04B77BB569B952D9A15D198779804197D23C18E5B055F5C8087D742F64418D6505E70418ABFC6B1BF7BB3DE286599F4676CF87946D65144998AFAE1C689449E3F349FD0809AFB856DDE4A94A2C0258D56432F40C3DA812D3FD3B72259A61D2882E0F50B355121E564C6BD33366F32BF4A5996B9998961354925A2BACDF48056118453AC3792A7879B71579ADB65F5D83B1ED6C8C49836DE379DAA027E62B96F683C1688935CB3FCCD64329267273E60C6CD59BA1B7FC911E2662527ECCB7A474E5EF00CA9F789A3838E889242E7FB2B08F3790613C4EED3C912EC4EB029B971096B384727697B4DDC3B698C9A6DA6971FA4C574ECD18EB1C84C0C5790153AA6B9DB61D8BAC0A680A37ED623582A7E8C0885EBB35AF341477764368E0647B14553672316D0B90317C5B53AA747E61B4750DB9E63CC3712900005CA24226B523E0A179582C85968C107857BB41521B7342B13DCAC462A53BE38446F2142519667B48B1C68FCAFA4D3C7E3E5AFF163C41F2C1B4DBAC5456C30776078E7C3A713819F6B9ACA55D77D60637183A723035730F94285C42AC3587637F66AC30F2C4039E60420967576E27B96C8C004D9585F33939AC44F0D195B35D472FC219076F12D0984AC844728D5D2266BB5CD8B325DDA497B4F397BFE722C9D7684201A921F502271985CB3F31C04884C090B063631253DC454537031F2C82C10A1722DE6C556464DC9D64389DA37E469480C921065C79A30C83C867C952B30548A6B5BDFEB6EA6247480F163B427B17CF94889220FE934564DAB90F5B6A11648870B654495A6691AE21FEA86BDC8C49093FA07E926AF3ABA0E7CEC21F613B49986C6C8A139EDA70B7ED8211A3215E8C43EF8C151AE61740EF83B48276033614B58E9CEB992233CD21DFF70C7A6F7171707A2ADD37ACBF136A4EB4A79517FD0C8AFF0B5126435C3100331F208A546C9A4044A8F0503C8ADE9506A018B4CA7C6E8D70120017D38B13B52786A85A540D81B8E71C376B796A7215ABF065086D3C80EE94B8F09E2A3BA13B82583B825388E87BA010AF507173563789A1DCD088907C52BD7FC1C6930605F060F37978211C10FB5717E3FA291D20B5D43FB74CD4711394B0027E41C52B523797470532CBE123C92950720E5E255256577D4E156EBD4C698D813405C61430B978694ACDE78031E74BA1D8517DAE2346F008411231FCCE7BFF75BC361E691E776049004097B36490D876288701B2D3A1743AB8753D47AC6200E2DA7458D3A059681233872794E6720186B20108B1D1033971CE19ED67A2A28E499A360A4AD86AE4194034F202F8FA3626FE75F307A4CEA4148219B958EA0B7886659235A4D1980B192610847D86EF32739F94C3B446C4D81D89B8B422A9D079C88B11ACAF321B014294E18B296E52F3F744CF9634A4FB01DB0D99EF20A633A552E76A0585C6109F018768B763AF3678B4780089C1342B96907A29A1C11521C744C2797D0BF2B9CCDCA614672B45076773F458A31EF869BE1EB2EFEB50D0E37495DC5CA55E07528934F6293C4168027D0E53D07FACC6630CB08197E53FB193A171135DC8AD9979402A71B6926BCDCDC47B93401910A5FCC1A813B682B09BA7A72D2486D6C799516465C14729B26949B0B7CBC7C640F267FED80B162C51FD8E09227C101D505A8FAE8A2D7054E28A78BA8750DECF9057C83979F7ABB084945648006C5B28804F34E73B238111A65A1F500B1CC606A848F2859070BEBA7573179F36149CF5801BF89A1C38CC278415528D03BDB943F96280C8CC52042D9B91FAA9D6EA7BCBB7AB1897A3266966F78393426C76D8A49578B98B159EBB46EE0A883A270D8057CD0231C86906A91DBBADE6B2469581E2BCA2FEA8389F7C74BCD70961EA5B934FBCF9A6590BF86B8DB548854D9A3FB30110433BD7A1B659CA8568085639237B3BDC37B7FA716D482A25B54106B3A8F54D3AA99B5123DA96066904592F3A54EE23A7981AB608A2F4413CC658946C6D7780EA765644B3CC06C70034AB4EB351912E7715B56755D09021571BF340AB92598A24E811893195B96A1629F8041F58658431561FC0AB15292B913EC473F04479BC145CD4C563A286235646CD305A9BE1014E2C7B130C33EB77CC4A0D9786BD6BC2A954BF3005778F8917CE13789BBB962807858B67731572B6D3C9B4B5206FAC9A7C8961698D88324A915186899B29923F08442A3D386BD416BCC9A100164C930EC35EAFB6AB35851B6C8CE6377366A175F3D75298C518D44898933F53DEE617145093379C4659F68583B2B28122666BEC57838991FF16C368DD22C36E780C91A3582E25E19794C6BF2AB42458A8DD7705DE2C2AA20C054E84B3EF35032798626C248263253A71A11943571340A978CD0A602E47DEE540A8814BA06F31414797CDF6049582361BBABA387A83D89913FE4C0C112B95621A4BDA8123A14D1A842FB57B83A4FBAF33A8E552238A596AAE7A150D75DA648BC44644977BA1F87A4C68A8C4BD245B7D00721F7D64E822B085B901312EC37A8169802160CCE1160F010BE8CBCACE8E7B005D7839234A707868309D03784B4273B1C8A160133ED298184704625F29CFA086D13263EE5899123C596BA788E5C54A8E9BA829B8A9D904BC4BC0BBEA76BC53FF811214598472C9C202B73EFF035DC09703AF7BF1BABAAC73193CB46117A7C9492A43FC95789A924C5912787B2E2090EBBCFD3796221F06DEBF9CF70E056B8B9161D6347F47335F3E1776DA4BB87C15CC826146FF0249A413B45AA93A805196EA453114B524E310AEDAA46E3B99642368782566D049A726D6CCA910993AED621D0149EA588A9ABD909DBB69AA22829D9B83ADA2209A6C2659F2169D668B9314842C6E22A74958B4C25BBDCD293D99CB609D866749A485DFB56024883CF5465DBA0363206587F45597F89002FB8607232138E03B2A894525F265370054B48863614472B95D0A2303442E378B0DD1C75ACBAB971A9A8D1281C79613ACEC6933C377B3C578C2A61A1EC181B101297A37CC5197B2942F6A0E4704C0EC63540481B9F159DC255B59BB55DF496AE54217B7689BD51DBA0383A3D72D852FFCA76DF05B66EECCBD47BC53040817628C71E361D6AF889084916B408A466C96E7086C4A60A10FCF7537BB94AFBCC7D437590919C28650C4F2368259226A9BFDA3A3A0BA1B5087D9D76442FD786C6F81C68C0360D7194D7072C4533AEA86C2D1F8C0A27696066F6CFD11003F797270B32389713CFFA093D991B63844C385E72277F166F5A3934D6BB89A4788DE28321DEFC7457AB484BD30986DC1DAB3008CD7B22F69702FABB9A1045407DA4791C3590FF599D81D688CFA7CC12A68C50F51A1009411B44850F9015DC84A93B17C7A207552C661EA9838E31B95EAD546248E56BE7A5130505268771199880A141771A9E47ACFED590CB3AA7CB7C5F74911D8912C29D6233F4D53BC64139E2F55BE75507DD77868E384AEC581F3F411DB1A742972D3EBFD3315C84A5AD63A0E75C8BCA3E3041E05D9067AFF3B1244F763E7983D48BA34134BAB88D635D8CF8FF5D686058FA68B6C2FEEAA5FA4DE65757086C0125E937BCC0D02FAA8988AE7169DF07F6A771E6E7FE3AB65E965C63C3E40ED909", + "c": "E2D5FD4C13CEA0B52D874FEA9012F3A51743A1093710BBF23950F9147A472EE5533928A2F46D592F35DA8B4F758C893B0D7B98948BE447B17CB2AE58AF8A489DDD9232B99B1C0D2DE77CAA472BC3BBD4A7C60DBFDCA92EBF3A1CE1C22DAD13E887004E2924FD22656F5E508791DE06D85E1A1426808ED9A89F6E2FD3C245D4758B22B02CADE33B60FC889A33FC4447EDEBBFD4530DE86596A33789D5DBA6E6EC9F89879AF4BE4909A69017C9BB7A5E31815EA5F132EEC4984FAA7CCF594DD00D4D8487E45621AF8F6E330551439C93EC078A7A3CC1594AF91F8417375FD6088CEB5E85C67099091BAC11498A0D711455F5E0D95CD7BBE5CDD8FECB319E6853C23C9BE2C763DF578666C40A40A87486E46BA8716146192904510A6DC59DA8025825283D684DB91410B4F12C6D8FBD0ADD75D3098918CB04AC7BC4DB0D6BCDF1194DD86292E05B7B8630625B589CC509D215BBD06A2E7C66F424CDF8C40AC6C1E5AE6C964B7D9E92F95FC5C8852281628B81B9AFABC7F03BE3F62E8047BB88D01C68687B8DD4FE63820062B6788A53729053826ED3B7C7EF8241E19C85117B3C5341881D4F299E50374C8EEFD5560BD18319A7963A3D02F0FBE84BC484B5A4018B97D274191C95F702BAB9B0D105FAF9FDCFF97E437236567599FAF73B075D406104D403CDF81224DA590BEC2897E30109E1F2E5AE4610C809A73F638C84210B3447A7C8B6DDDB5AE200BF20E2FE4D4BA6C6B12767FB8760F66C5118E7A9935B41C9A471A1D3237688C1E618CC3BE936AA3F5E44E086820B810E063211FC21C4044B3AC4D00DF1BCC7B24DC07BA48B23B0FC12A3ED3D0A5CF7671415AB9CF21286FE63FB41418570555D4739B88104A8593F293025A4E3EE7C67E4B48E40F6BA8C09860C3FBBE55D45B45FC9AB629B17C276C9C9E2AF3A043BEAFC18FD4F25EE7F83BDDCD2D93914B7ED4F7C9AF127F3F15C277BE16551FEF3AE03D7B9143F0C9C019AB97EEA076366131F518363711B34E96D3F8A513F3E20B1D452C4B7AE3B975EA94D880DAC6693399750D02220403F0D3E3FC1172A4DE9DC280EAF0FEE2883A6660BF5A3D246FF41D21B36EA521CF7AA689F800D0F86F4FA1057D8A13F9DA8FFFD0DC1FAD3C04BB1CCCB7C834DB051A7AC2E4C60301996C93071EA416B421759935659CF62CA5F13AE07C3B195C148159D8BEB03D440B00F5305765F20C0C46EEE59C6D16206402DB1C715E888BDE59C781F35A7CC7C1C5ECB2155AE3E959C0964CC1EF8D7C69D1458A9A42F95F4C6B5B996345712AA290FBBF7DFD4A6E86463022A3F4725F6511BF7EA5E95C707CD3573609AADEAF540152C495F37FE6EC8BB9FA2AA61D15735934F4737928FDE90BA995722465D4A64505A5201F07AA58CFD8AE226E02070B2DBF512B975319A7E8753B4FDAE0EB4922869CC8E25C4A5560C2A0685DE3AC392A8925BA882004894742E43CCFC277439EC8050A9AEB42932E01C840DFCEDCC34D3991289A62C17D1284C839514B93351DBB2DDA81F924565D70E7079D5B8126CAAB7A4A1C731655A53BCC09F5D63EC9086DEA650055985EDFA8297D9C95410C5D1894D17D5930549ADBC2B8733C99FE62E17C4DE34A5D89B12D18E42A422D2CE779C2C28EB2D98003D5CD323FCBECF02B5066E0E734810F09ED89013C00F011BD220F2E5D6A362DF90599198A093B03C8D8EFBFE0B617592FAF1E64220C4440B53FFB47164F369C95290BA9F3108D686C57DB645C53C012E57AF25BD6693E2CC6B57651AF1591FE5D8916640EC017C253DF0606BB6B3035FAE748F3D4034223B1B5EFBF5283E778C1094291CF7B19BE0F317350E6F8518FDE0EFB1381FB6E16C241F7F17A5210693A274159E7FAC868CD0DC4359C3D9EEFEA0D9E31E43FA651392C65A543A59B3EEE3A639DC9417D056A5FF0F160BEEE2EAC29A7D88C0982CF70B5A46379F21E506AAC61A9BB1B8C2B9DAB0E44A823B61D0AA11D94F76A4A8E21F9D4280683208F4EA911116F6FD6A97426934EC3426B8C8F703DA85E9DCF99336136003728B8ECDD04A389F6A817A78BFA61BA46020BF3C34829508F9D06D1553CD987AAC380D86F168843BA3904DE5F7058A41B4CD388BC9CE3ABA7EE7139B7FC9E5B8CFAAA38990BD4A5DB32E2613E7EC4F5F8B1292A38C6F4FF5A40490D76B126652FCF86E245235D636C65CD102B01E22781A72918C", + "k": "7264BDE5C6CEC14849693E2C3C86E48F80958A4F6186FC69333A4148E6E497F3", + "m": "59C5154C04AE43AAFF32700F081700389D54BEC4C37C088B1C53F66212B12C72", + "reason": "no modification" + }, + { + "tcId": 52, + "deferred": false, + "ek": "16E08D929596ABD2BA47558090531AA277B00DC8337AF578F3A18B3DA8738CA434ED41B537ACCC58182310352331A43A0CA85C606823C824602085B2338142BE48A00E068289310559E9155C6A991CF457F098C61C6B79C584B24C883296B03F9D100489C546ACB28B2DB181BF7B4EC80140F1ABA4130512BA2A0F96C9453DFC479BA1CA9689629779AD731B159A61582CF67989266EFF84455D191032486242E6A9CCA6314B788A3783A0D003A4BE1AC50700611DA61476962E48E38AA5250CB4E60E44B52F00C5233D0A72E3D010D65ACF50CA1704CAB0EBA28D084387DA4BC8BAF7BF3212954652577CE52CD0E9768B3CC606000FEAEC499CB13AC1CBCA0F5B6A0BC7B8B9C140DB83174448050D72C51F18BF1A570FD6314ED91A4DACA6C231404250704A86561F5861785F4B47A15420975225300C621EC11FB6F04C8613982CD16AC85A8EAF62B07FB16A2BAB515D84941AB7AC45DC58D43ACA35697DC711BF8D7BBB41B95BF48716A1BC462F332DB93B67CF858D694B66D9899069EB795B4C1E407ACC74493CC5908B21441838702A3ED0683AE0599CB487A2AC154727A1CFB30104A9B0715698D5E51417832AC67139EF752BA77B7C27217472C62AB8099B4EE2A1D6D98A37EA56058A94D8B86FBFD17972E46A496B2530232F821B68D306AC78BA8D719C6DF278AC79E6036CE55D4E3995CC772E4538BC99E5A5AFF866AA733E6A15A4C7D61ABE8A315E908B588566DBF922C17B6ECB773B59D15416935EB8197FE751A4A5C49AD6FA5D087489F299B20E6721DCC297990751A57489C3A9CB59745FA51191A37873A166C84AF394D280982FA2171183345FF5BC17077B5432236108C6537CB68465C08EA6C98D4B1B606B73BD2A6036B16922B712B68553CAE23630B926276762E3D55DBC1A2FA1CB1372C9460B7727E2CA7382F0B696D005E07AA6C2C763225C30D846710D2286244BC2C751A5BB5CB71F24C75B40C3D1DC0369506D78D39BE3564358764A074567C51BB81B1090ACB301AB95864406B500CD04A2517C582601057328C8467847B4A3248A4BB63251317A9AF93475063CA34D382C4AEC93164011882A6AEE1771EFC99E84E1B68217281B123672999431BB1D4DAA180E9202372C8CD7150FBE3166718AC3746CB0E020AB0A349F88E21D319394676919CB08B29203A6EAC112B63178C7B8C29CC28C4C085A7D6660B12BC64B10A00C038F80076AF0769FB6D42240CA010843AA33B5C534A1C3391928ACF90132D0598E35BFAB062F771696C93696A351C5322C6648CB539660902526202AB34BED4ABC9DA427A1602ED5278897785A9375110A87529D74B951750649DC2B03C0642755132734B808897B1494C98F87376F223207C267A9D5961BC6472B3B8EBBE9ACB9A79A3E2A3FFF428282BB1B79525B7DD265A9986D362566E93886B106C7DBA07FD1C78CC24008852B152822120E73807D8B17486067FAA964330BA67027A84E2BA8A91801D46A059DDA37EDD31875600794E3588AD44331741CEB3990908A57A7C1CA8D7AA3D9864F8E501E9B5603C1FA8ED23327BEB22B08BA26E79C90928B756F96771FD7244B346CB18415CD3CC5BD845E394BCB5C6399F96338534182F015947EF7230A0AB825382957F8950B31CF94F31C0867255A597D9501A76DC2BB7AE455D8296953C51C7BA03A3A0A769207082F45A5100CB49C86317B1650B5898BEBAC512960830A37022CDCBBABCA0AA6DAB3E452A12C1040D54C1BBC372F1997C0DF75BE5D1C88C1618F1833B223D02E2B0980FC187D93A75B57E0487D2CC36AFC1838519378E5634502106AA7B3923830C9B9BA6717694E340B7B51CD63917FF9770635F42F212085458A45BFA09265F074036545FB39CCD08522135AA522670A640B3AA37782D9C7794DACAC86D651B030B33F14464B9CAAE3E883E9582F16558B03D77EFC01AF01E2327CAC368268A4A7141F375C833AD3B4369533FA727FE051C33A1ACAEE8832E32986067468EAD91D79A90058F608F97A1226CBC26339540778B3C1B0421E88458CF69C8DC73287A36D80B57F7FB5B787B66C22658863DB1F60985156BC28BDA25C56C5BD35812020880DCCE46546965817DCC3F1667496F12589065EC68853863C1C581B7F378C82ECEB88D1AB88CFD7DE4C88E0E556D945755EE2558034EC6FFEFAFC68E26128BD7625563BF279", + "dk": "4DD7722880771C554AA6D99D5A873FA7723F18EC976BE29EE5438D7671BA97438000F91A396CAA464BA3CFA2598586AB4D1BB0C9803A82AA1C5B13AD1647972FDC154B61800B0C87215657D13B6BF8CCC69E5C8572EB9AADEB6CDC8871F8F7416FD032ADE5A3E863591B6B3756293057F80024F67A7ED35706185FB6B30F8C836F9624B291C009BA6742C23C65F718291DA3210D25B594E7C00F575B6B87316682115D84116974389248921E0A94302C5DED39CF6C6455B9B277E9F48C2880AD64CB5E96115EBDF1BF42A540228A092FEB8A09449BC626571F4007AE84824AC8CF92EBAD8E25A62E776183BCA7EFF1417CB30EB4043B98649C9276B4AF9CAE89232C7F7C920608A527A92AADF809EC69C651447664E98F369B2704B3054C656AC4570D991C6C5859063C249B70DC5D49CC8202541B13B6005AB09F4A471C28F4785D1A5B52389C3E0B1544DC2098F5284C43802AA16E29F32C93CA611CB170B82C4F6F514A18A985755C3622C2A8C15514340660E9F7025462909DBB6FBBDB3BADDB700714CC47297316F45589922440D6A0AACA8216902AD00647E920C4584AB73CB7C546DA0021C22EA2E59D229536E9596EA6598ADEE85D563C2CB5D82908D60462F430F6245D882A3395F754D561B949CC5CD27240C2CA41406C3D09313ED2A4A600046871F030F41B4528E7316F9104ED550C38C43844789BFD330EC75A8EB3909C156A9E54805C568B5581E603C6C9CD9713AC995077AA52747D281C28BBB535B9BADBD867C65111680C2FDD1032E1E49A67C6C141F53F44461AE427A416B8538747C144025EE3278B6EB26EFE09C9CC8AC7075324D8392A44CC260A1297FCBA4096DC537AC82E5DB560E0C541D114A5E3891068B4B123CBA214D72C36A519B409874D4011E7DB2F7978343B3656EE600031229BDA3171E4480413716B97E5486F07C32E94805FDB48ABA2144288B96C1281AB180A1BECAC17B4C206677920C52B77B53F7D7C782C562C4DA6CB69C5A828056ACB445CCFA62A8EC3AB75C5940D302BD4E38A381015947B973D547A5CFB1460668476529F6411C7AD3A2B13A0C1AC5B71D0132568591374CB27ECB02DE9CCB41D150025C26CD48CAC600C6E9A6A1398884F49EA97096662C06C56F5B76E3F444336A2C7E2FA201A66AD65F2C8BB2340C89C7572698D84190031545CC14420564722820CB1CC6C34708530207B10F3660AF2D72E1C4A4A5729896F79B6BD85B93E8C1B74C521EFC79B10085C92D5857CD200E7A4C7A284524D25636C04BA9120B76A86957F848AA2540A6CB36EBD26354C38213F6713F255457821A47CB00F01185CFBE45E50C624985130086C392226501E6B84D1C666DCC959FA0209114804EF8B99456C16D0B59E81568AD092B3DAF8B70737C3BCD10DC9D48D7DDAAD2159A96B28AA77505364DC92E170699FA95BEF6C26DBB6CD4D972026A00A74896CA2E883E0FBCB19D21E5EFA2776837BE30C373CF405A1628C1FB795095B7FDCBC063357B862FA2823D43A2F1819B0D892A59104B7E64889703F8BE2C39C9892ED393AED6A62330C3EF2B32F5B8A59975488FDF60D8CA366888B9EAC3A094EBA3513F6225638A6D2916CE6F76ABE1242EFEBAD49F29D4A289D6ED2549383B66868A33018107C1618ED3613933A9360F27E6885B7A18167E3F124115184671506F8B6C2F4A18A4EA30FD7FBBE5752A1FB72BE2E909CFA441AFF70C15BE67640F12672DA671224B6BD1B39A7F744E158B9B37B859633068F493902870BD2043A41B605E1395CC305288D9C3ADE5551D92B199260156F3710EF09C8B20A44ADA53D17E31C829BA8775579CEB110F4177BC314653EB6BF03514ECBF009BC6A95A8B79B90E18DB763C46699A9C0C23C32A31B1BD350D4301ADC63A298A486DA95B006175E99E2959881B2D84CA0588C44410173D1148AEA165E93C34CF4711FA3E215F0A193AC679E6298874221B727F141480356D408017D5215D2463C7F62A554E11D0C204A6B93314116BA19CB3F7E1571DF533EB64372FB68A7544C3A7B793D9D79CDB0CC4DD3855E9337C7E8932B1DD3BAE23245FF854FEA2BA93FE06B18E4C694322873DC8C7B70816325A9AE1A1E08686A982715A3C10CACD17F8C2920CB13B251510C55775251850A21D3BB16E08D929596ABD2BA47558090531AA277B00DC8337AF578F3A18B3DA8738CA434ED41B537ACCC58182310352331A43A0CA85C606823C824602085B2338142BE48A00E068289310559E9155C6A991CF457F098C61C6B79C584B24C883296B03F9D100489C546ACB28B2DB181BF7B4EC80140F1ABA4130512BA2A0F96C9453DFC479BA1CA9689629779AD731B159A61582CF67989266EFF84455D191032486242E6A9CCA6314B788A3783A0D003A4BE1AC50700611DA61476962E48E38AA5250CB4E60E44B52F00C5233D0A72E3D010D65ACF50CA1704CAB0EBA28D084387DA4BC8BAF7BF3212954652577CE52CD0E9768B3CC606000FEAEC499CB13AC1CBCA0F5B6A0BC7B8B9C140DB83174448050D72C51F18BF1A570FD6314ED91A4DACA6C231404250704A86561F5861785F4B47A15420975225300C621EC11FB6F04C8613982CD16AC85A8EAF62B07FB16A2BAB515D84941AB7AC45DC58D43ACA35697DC711BF8D7BBB41B95BF48716A1BC462F332DB93B67CF858D694B66D9899069EB795B4C1E407ACC74493CC5908B21441838702A3ED0683AE0599CB487A2AC154727A1CFB30104A9B0715698D5E51417832AC67139EF752BA77B7C27217472C62AB8099B4EE2A1D6D98A37EA56058A94D8B86FBFD17972E46A496B2530232F821B68D306AC78BA8D719C6DF278AC79E6036CE55D4E3995CC772E4538BC99E5A5AFF866AA733E6A15A4C7D61ABE8A315E908B588566DBF922C17B6ECB773B59D15416935EB8197FE751A4A5C49AD6FA5D087489F299B20E6721DCC297990751A57489C3A9CB59745FA51191A37873A166C84AF394D280982FA2171183345FF5BC17077B5432236108C6537CB68465C08EA6C98D4B1B606B73BD2A6036B16922B712B68553CAE23630B926276762E3D55DBC1A2FA1CB1372C9460B7727E2CA7382F0B696D005E07AA6C2C763225C30D846710D2286244BC2C751A5BB5CB71F24C75B40C3D1DC0369506D78D39BE3564358764A074567C51BB81B1090ACB301AB95864406B500CD04A2517C582601057328C8467847B4A3248A4BB63251317A9AF93475063CA34D382C4AEC93164011882A6AEE1771EFC99E84E1B68217281B123672999431BB1D4DAA180E9202372C8CD7150FBE3166718AC3746CB0E020AB0A349F88E21D319394676919CB08B29203A6EAC112B63178C7B8C29CC28C4C085A7D6660B12BC64B10A00C038F80076AF0769FB6D42240CA010843AA33B5C534A1C3391928ACF90132D0598E35BFAB062F771696C93696A351C5322C6648CB539660902526202AB34BED4ABC9DA427A1602ED5278897785A9375110A87529D74B951750649DC2B03C0642755132734B808897B1494C98F87376F223207C267A9D5961BC6472B3B8EBBE9ACB9A79A3E2A3FFF428282BB1B79525B7DD265A9986D362566E93886B106C7DBA07FD1C78CC24008852B152822120E73807D8B17486067FAA964330BA67027A84E2BA8A91801D46A059DDA37EDD31875600794E3588AD44331741CEB3990908A57A7C1CA8D7AA3D9864F8E501E9B5603C1FA8ED23327BEB22B08BA26E79C90928B756F96771FD7244B346CB18415CD3CC5BD845E394BCB5C6399F96338534182F015947EF7230A0AB825382957F8950B31CF94F31C0867255A597D9501A76DC2BB7AE455D8296953C51C7BA03A3A0A769207082F45A5100CB49C86317B1650B5898BEBAC512960830A37022CDCBBABCA0AA6DAB3E452A12C1040D54C1BBC372F1997C0DF75BE5D1C88C1618F1833B223D02E2B0980FC187D93A75B57E0487D2CC36AFC1838519378E5634502106AA7B3923830C9B9BA6717694E340B7B51CD63917FF9770635F42F212085458A45BFA09265F074036545FB39CCD08522135AA522670A640B3AA37782D9C7794DACAC86D651B030B33F14464B9CAAE3E883E9582F16558B03D77EFC01AF01E2327CAC368268A4A7141F375C833AD3B4369533FA727FE051C33A1ACAEE8832E32986067468EAD91D79A90058F608F97A1226CBC26339540778B3C1B0421E88458CF69C8DC73287A36D80B57F7FB5B787B66C22658863DB1F60985156BC28BDA25C56C5BD35812020880DCCE46546965817DCC3F1667496F12589065EC68853863C1C581B7F378C82ECEB88D1AB88CFD7DE4C88E0E556D945755EE2558034EC6FFEFAFC68E26128BD7625563BF279560143610E550E6C27E7AE725C958594A71FCB0350F3CE623FFD626D381C38A24D9D475487B57327D5EFD4EB3307FC1A19EF63E2E11D82AFDC95B51A4FF19D77", + "c": "6930583C55501AF07198C21B52C1A66D60D3E6A403EE412E9751AF2DB2AE360BBE29EA953050D455E25CFFB6E9DB5CB6D881375E7B28BABAF2C7946BC5A4757F61A4970BBF1CADC21C72E782A4A31E92FAB1980E7B2D51AC68CCC6222636D05645B4C85DC7DBDDD6EDE4D52478BD336C81D85708857359DB863F73B839660C3383EED5F621D1CBD3C1C1E5B3F5A5E2BD340824FF5F48690D185F725C821A2681E27EF8C3BB76CDC4CDAF720A8C657601107FFAFE761D4709C35CF62023B1690F2068038D444B9867F2FD7D619F3162D286A42E4B4A5C23E9768AC694B466DAEC80C6A09BED0CAEAE9B1F063708BB800068CE610C0346114981A48921A9BA7091F4E615B5E4FB91CDDBA00272B98FC8DB9282C43B3BF34A393BAC9EB25B6C92235204AAAAB683142BF66E9B37DC1EE10122A3492CC31EAE416D4C364780F696C0691E6449F3570C0AF421192CF44684B1F2BBFD97E2C2B15D6DC4D589069C351BCEAFCE7D2AF4C57DAA75601EECA9CCF72A47D473688B9E21D3EEF68E79BEC63BA7CFCA6D1B47AF8F45DBDE1D3CF6DD108F756F935379303DC3FEBF11BAECA5A2B299586D8DD45B0A17DAD6F2E3F2A63FC0F6435C2108DE90E3C42387A068D7E26C52C966C50A253F9CE19F1B13CDBB75C445D0C01C2EC3133BF9EAB4B6FF0DDA9C87C37FB677827B62107685793406698F08AF44632260D8C298042BDE014A8E3510705719CE0F2A75169363FAF9A0575558809940D3C7FD1E8CC027055789A1A69D9252330410C66CF41F00E67935A7A0D927D6E8EEF2F183377D6CA76F5C0A06F606462B6110600B8345421CCF5F77FF096A800030A0729BFA24521DEB7ECD3AC12B2A7F3A65921F60CB10B3C23C572F5248CDF83C34AB1EFA70AB3F1E78F3CBC0361A407F649ED4F4372A59DE9C11183DBB2661A1707029EB5334BA67231A53C118412723C9E146E0AADC891AA7A37F05F1E63DCB22CCD774FC0AAFBE2A0148DA31EEA8D855F05427E0D416C8A24259EE7D7F0584F01348316BB637F9F18080466610FF013D050F41941CEED3854A90D92E6DA33181D7DA541F148153728C64BEFB5A9CE23F2506FF5A97F3E6372AEBB119646D8E7DE1892F357FF6B4BCA001AC9543BE983E4A919F841A6AC30945F3D516222A1BA8418DCC05D3C2A26D36F43BB2A64F66737EB94CD5D973392CF47EF81CA2BCE1A5C89023EA226E4FB0136D922AD2E67364858213A2CD951369712E3E61DA5C1E8B2F6C21A4A80908CEAA1DF311CED7EBE78E245DDAB3C298C7D2ECC6C78DC5C8ADA322281F6C1B8A33ECE1720E32614085986220A8F8A128097E65904B9285327A8940F02CBBDBB36E8C650FE065F7FE69B30197FDA4F61A7EB3AF7B517668921A6E3C10D79E00853A4DFA985DBEA19AD55BF0BA53CB5EE16DDBD417FE498D2E98921E743B1D2B0192590C738E770F7BCB60B129F0BFB3F2BCC3752DBA1B433C6AF5CFFC18E963BB906BDBFA0564205C482BF032F21DEA5D9A61278ABA2122560FB2030A7893868D10B03E1105AC27527C206DE6538BB235F14FC6DE386A9418A3227264297B09A9A9F1401C24F81B8A2A5A7A6373457AD9DD02642300D564E3030629DED71D014C834F6A5005F2DB283687A2744841A86D3F9DD6A5D332AB097FE04715DA746915FD07A1E6D65C9C60DAA1ECCF71D1F4A4BA8AA9516263790DAEFC1D606DD009E079D1AB84E808DFF4BD56D76336345B23291EC5EF217FAC6CBE590CBE5D31EFDE35D4F7041EB20F7B2232DF031699927D9FC2B08E44A36DB2FE5BFABB6CA53FF050F7CC1D31660EB375D788D83AE56CF359C557E5FD4B881327181C2CA6D86B39BCC22A4C45F7B915183CA0CA00B65A06BE77A56163674F49CA79822BA11596BB5EA52ECBDC139364D84153F97D193E5E05A4F0A618F6018B45F9A646163C999F8D40CEBF85A3D51C05024E39AEF608625C93A1B1144F34EA25A4F3C588BF6841E736921BA111215740F8A1903C065CF08FB2BCD24EAF3E7733CD59066DC85AC0206822402A6AEE784F194BDD411806731CC42430678D4A0D027900D5427639AF42262D57E7BC8242A3FAB2BE536C931DE54D406535AB881C71D9C9A4CFFFB37AD298FE879EB7279DF03B9A42C6B69618478C0886C23688AF1799227163E90955B016BA01F3B9AEE10DC5C889D3883F1163CE483584D7FC09D570BE76968081485086", + "k": "4BE636AD0F1522EE10798CE9EF454ED219A13B6791FD2E042A417B2A220DAE79", + "m": "2E2C821791D3EA49D0AF380B97AA24532F6109D85360A751BB8B4C048C48D26F", + "reason": "no modification" + }, + { + "tcId": 53, + "deferred": false, + "ek": "54570A4B2AB131F9139EC171AC5ABD140863A6A0C5C13C8AF54094E95620E4866BCB8483EBF0B21FF9987B44650951750EF0BB76334235651CFA85153451B1975380513552FDC693124617F395121DA27F86AC80AE363707CC3F264CBA1B703DA67348BE45BDB4293C69E31EA73B0DFC35083F2493185B108E09467B2BCD44AB17D7BBC41F73057FBA8C2732730EF110E740AE75178890746FE149C8898B467CE116F68743A7B35453720BC5D9261946CEF3D9931A4C5F2F271041F0C4BA277778D56EF9DCA3E8CC2A4937BD9A276D173258B70C0BD9A0C695732CED11079D816E9D00A1C44A095F746D4EF14C53C64399964884977D503961A48C14E02A4B7055A74A31C5C55AA503C9927F017A194917F3AA13B33BB8FC86126A8B33EAE53CC2631C15C39FFE2615877084FE0C94BD5013A9CB467FA66E780A46EC5BA392D3C7B6579F63F2656796622AE9428D128BC546B33B26C697392B57A240338117107ABB0C146B2F789FB1A4552A4747C520B161C6A356F1368F2ABF7340BFC8031535876A185C11BFF5176B474B3812BE1E7603085453BD5B289CA97F20B82D88E30064B39872ECBC35E447E8431D5A61B25220CABA58594E96CAE054A791736B51E42F3FCC1F2F7CB8C86C9B67FB5FD53C93ABF3123D11CF5AE491B25703AD386839F4B0370C3AFF50903724C592141B88EBC6F61732F1DB038B15528F1389FC574634071CFF89B39D5A3F50D5B8E6E932C434C9BEF450E42765EE1486C3FB1221A3B3FC42C5ACA709602BBAB9A9BDE4A9716CDA0370B767D1E29128A5560164ACF0D03EC60833AEE125040B5A5D45827C1A2E2B3CACA923BD51134E216921656579F2773C4F0002A285A9EA975670F02399626D65135119754F01F09E204C305C880E93816516B0CCF996076AC93540144231F54ECD27C7C3DBA3DE988E8BC1838F68550ED8BA14D35E14586516BCCF459A3E63C9C69366A5A2992302092790341E7FE08FCA4B77906C839FE929635B89971512EB73456462BA9DB473770B9689446E4D69848E21670CD76F04896456E7BCB4352B086979DBF4905F656C1D67169D71933FD8B827EA5D0B5B00E0C3476BE53F56D11FE47C1BCB5727C51198381916572257D9E5A811E6601191477F45B2244BAB96943B16B28074B7129337333BE218DC114DF16A83C4C1B76A28223489384CAA096097A26B0C17E1E6686D52214F756A12F3C5E08985843909DDC1C4FB99CBB552C9D2594B85C796856C48A3D99A2B93510425A90B4AAA035150DD1394174429B6A394EE495E060812C6044678CA6F5DE9AAD4C11CB4060225F07F004969FFE991B7442176E00D7AD4C6C266435764CAECC34DEE027ED1CC4B80BCA242495378F0097B797C9A0C3F49D7BC2961A41D751728915166730DAE7A588C550F64F06CEA7A868640157F05C69C781682967CD4720040060782500C97593FD5715CD84A05AA10958FB482C38C7DA01A910C5B0C055BC2252B6FDC659A94F36422285F2CD477E350575C4AB3048C0F2AF83116BCA3EF65B0FB73C77747C3D585AAA478945288CDB0853C14D04DAD16052B71C02AF9A3CE254095C26736E6235CD6B0C340812DEB282249AAC87C7E35639E31A5943F61CE43728332B9280495CC9268825AA923DD5155BCE616B3675EAA5891FFA7A6BBA07F14196001253427E8BC4C609318940EF31030C5C9965A26B7B5A2440EF56BCCB424DC75350AA0129E05C83C19856CD93BC9928A8D674381E6B79EBB0319DA1BC7F427DBC1830FF1CCC468B5E68B23AAD73526D16DFDFA30D8CB3559296E35449F36B280B191587A692DBCD610D75342DB7A919F8ABB1E12BA44B185B7560AF79200427150D34601EA5A929025855B34B3067A01BB0B9564C186B2820917D5BC444B30755BAB812C89D201AB6D376135F2220F37AC35876B6012975731077F464ACBEB7A1E7764AD8502A68C9616B09C33FC6688166E1E3170CF6534C0212731049A31D4353BF80A99390064953419E9CD1DECA6F3007D31298DD335B69B971E4F5261F4888318A6A0C0E2AD79C19A827436E87886E29768AB261863243EB5D101A11922B2558D8F53BBCFC1BDD652CA6B10C123C41575F609630C660DD9205E571B276A36C64C770CF3B2D362064F0C94E2BBA158F235F27464280CA9026DE7D64D513C6120035933D3067D03AAFB1021A78860771BC04B4652", + "dk": "B3E23EDA19008B5C42573A1A3BBA8CC34B23AA7A36761143480C8FCFF318FC4048B8C697004D82D12907C031885B92C7EF5BBC4D22A75B493FB19512C5FA208D800C134B1AE9A1CB19E8978B2003EBA888609CB147D7A451CB5199B0259FF8511CC5561338C6C54C2607CBCFE85C9809278F5D0B79925B0522A017B4B45D380C77020A722FA93CCA36904D0B4F04770F4DE13EAD906DBEE00C0FD98212E21B4BF1AD4BD0536FA232C8733719B20B2D8250ED698B01104019957F532B2B4D9489529A265CA9C773178EBAB24659C16423C4C00517AF879AC016A53E70929292140DC9849B65F5406A730CC20C84BA41B29888607A49B4F9C7947D155E60C707A6DC6AE42C6091886ED8F3B5D2655E45DCC945603365E4548DC568C8558C310C84D8E729793226FC30649FBB7FF989565393BD4DA91ECAB1325A49B76BF20A2303B081180B08DC324E01A3526B5B17E13B5C46694948997424179C29434DDC09DAB11CB4A47A6FBB669E02172CA30B2655B2658813F1666281E33EF520CBFC40ADB07A45E8D56B9EC28617DAB8D0BB1C6098CD474444AE523A5C0C47A17C5AFD845BDB14CD3661676C5194C9C48C10230D3A08A48A23B50861CD1EC19EFD5B25137435CB676DCF322F40043998E801467422471752B8FC1CB9E8CEBC2B218F60228C2452396598D186CC9008AFA626326784656228A8A0B00829F56B1C9184E32C757205C80AE5113242B4B41C16C6730A54059F37E0338A215431B9260307BE517776EDFAC0537630C62688B4586CF5A93EB4959C7BA0CEDCB904B2B6B41CE0B966B73C4DCB22F0B420734137C5276E1EF428976C2EBBC055CF583721805D64C57E42C7B2FFB5C3ED33B83E21190B1432E8D6B7D7845D467499F4F1C28BBA4F69568B2680283E779645605901FC918194165C0B62386CB2570809AA1283B31652CC4283568B16D5B2397AE3BD7A19254AC4C711067E98C6203316AFE29337B570ABFC5B272AF386A4A27893B03D3D5C67D2649250F20B10D09DF1E93216EA2A6E2BA8B5B768E9084F6675915AFB917E39051895A5485877CB7C9F7192144704920413666C069B0B731AF8D29953669FD51BB16B2960B6A2470562A0CFE49CDA85982CDC4BD9DC3D28109F32E5365D056469027EBA86904A4AB5CF592819B5848CE425543309DD76B8FA6B9D854A1434A48A636759C8128818E3197ABB33584A4F9AF94FF56839D625799D01B4AEC07EAE36C0FCA3C5A76B6CE97C7F83D3617550A0D309063EAC9E37616065774B6E78C9E3C4140D618CF707295AF10A90702E84168A65B40E172879D6B249DC2094FBAC234E563C1DA060C4A65AE4C2357179CF87480B14919A5DA7BF64BBB40B148C91A960E4A2C3BCB903CF57BF09251AB19830028088FA49C4EF61511FD2A23299CA8FE16873B81E015A724BA5C8BD110BD2D657D212751FE88875975B0322351989831854397DF90DDC82A3F59CB8952086C8F10973242CB778597EC0370838651F02313C575535D97298FC2C9CF312FE066797FC2B61B15B3874858BAC6460D600856703B6CA5A8A90BDCF3490938368670C2E29FC8EDDEB8793481CB3BA9C2D14AF5C8A135329AAA18C31BFB72C1E8A9BBA1756E687300206B3796903A3C2C2704904CC00C947998F97F46388D83CD4E4526CE3A68348A1D7701C120C0F46D0509F904B5092594E4970E8D35F60F87132E68A369BBD4BAAAC11EC976B840BFCC19B1EF48CD2937E54F3AE5B0B482443A80DD0843DE7B66C3014227A383768537D009184F86D17655A5CBCA6D9A01AD988AFA6A52BBFD6C7048285F63C0A160B965F4C39DB142029C9BCF78235ACF2132A14B946D23DFCD7C44564BB8A71879DE2C038F2359D2793B30695A4E23942D08711630CE8E06F1DFCCC987C347BBC0AFE093A5BC0177C873052A26395806C936AB453B79B24F74B7120085AD7377590AC2BEAC5FB41536C152DAF934EE2D568EC8C60EEA14F958A18E6F0ADF0D87321CCCA163A4F8BC31C0867A32C74BE4CD3245FB7C9DB3535CE3C220EE9ACEC0663DA907364EB9673038A90E18C1DF523E5F98A115490F11368DF939A9405CF8E3B0E90E32931935170E28312AB7C8B875CD4AB4FB991BDBE1C692CC356B9B96159B69142E723C6599CF5B3502DA142DE136E54570A4B2AB131F9139EC171AC5ABD140863A6A0C5C13C8AF54094E95620E4866BCB8483EBF0B21FF9987B44650951750EF0BB76334235651CFA85153451B1975380513552FDC693124617F395121DA27F86AC80AE363707CC3F264CBA1B703DA67348BE45BDB4293C69E31EA73B0DFC35083F2493185B108E09467B2BCD44AB17D7BBC41F73057FBA8C2732730EF110E740AE75178890746FE149C8898B467CE116F68743A7B35453720BC5D9261946CEF3D9931A4C5F2F271041F0C4BA277778D56EF9DCA3E8CC2A4937BD9A276D173258B70C0BD9A0C695732CED11079D816E9D00A1C44A095F746D4EF14C53C64399964884977D503961A48C14E02A4B7055A74A31C5C55AA503C9927F017A194917F3AA13B33BB8FC86126A8B33EAE53CC2631C15C39FFE2615877084FE0C94BD5013A9CB467FA66E780A46EC5BA392D3C7B6579F63F2656796622AE9428D128BC546B33B26C697392B57A240338117107ABB0C146B2F789FB1A4552A4747C520B161C6A356F1368F2ABF7340BFC8031535876A185C11BFF5176B474B3812BE1E7603085453BD5B289CA97F20B82D88E30064B39872ECBC35E447E8431D5A61B25220CABA58594E96CAE054A791736B51E42F3FCC1F2F7CB8C86C9B67FB5FD53C93ABF3123D11CF5AE491B25703AD386839F4B0370C3AFF50903724C592141B88EBC6F61732F1DB038B15528F1389FC574634071CFF89B39D5A3F50D5B8E6E932C434C9BEF450E42765EE1486C3FB1221A3B3FC42C5ACA709602BBAB9A9BDE4A9716CDA0370B767D1E29128A5560164ACF0D03EC60833AEE125040B5A5D45827C1A2E2B3CACA923BD51134E216921656579F2773C4F0002A285A9EA975670F02399626D65135119754F01F09E204C305C880E93816516B0CCF996076AC93540144231F54ECD27C7C3DBA3DE988E8BC1838F68550ED8BA14D35E14586516BCCF459A3E63C9C69366A5A2992302092790341E7FE08FCA4B77906C839FE929635B89971512EB73456462BA9DB473770B9689446E4D69848E21670CD76F04896456E7BCB4352B086979DBF4905F656C1D67169D71933FD8B827EA5D0B5B00E0C3476BE53F56D11FE47C1BCB5727C51198381916572257D9E5A811E6601191477F45B2244BAB96943B16B28074B7129337333BE218DC114DF16A83C4C1B76A28223489384CAA096097A26B0C17E1E6686D52214F756A12F3C5E08985843909DDC1C4FB99CBB552C9D2594B85C796856C48A3D99A2B93510425A90B4AAA035150DD1394174429B6A394EE495E060812C6044678CA6F5DE9AAD4C11CB4060225F07F004969FFE991B7442176E00D7AD4C6C266435764CAECC34DEE027ED1CC4B80BCA242495378F0097B797C9A0C3F49D7BC2961A41D751728915166730DAE7A588C550F64F06CEA7A868640157F05C69C781682967CD4720040060782500C97593FD5715CD84A05AA10958FB482C38C7DA01A910C5B0C055BC2252B6FDC659A94F36422285F2CD477E350575C4AB3048C0F2AF83116BCA3EF65B0FB73C77747C3D585AAA478945288CDB0853C14D04DAD16052B71C02AF9A3CE254095C26736E6235CD6B0C340812DEB282249AAC87C7E35639E31A5943F61CE43728332B9280495CC9268825AA923DD5155BCE616B3675EAA5891FFA7A6BBA07F14196001253427E8BC4C609318940EF31030C5C9965A26B7B5A2440EF56BCCB424DC75350AA0129E05C83C19856CD93BC9928A8D674381E6B79EBB0319DA1BC7F427DBC1830FF1CCC468B5E68B23AAD73526D16DFDFA30D8CB3559296E35449F36B280B191587A692DBCD610D75342DB7A919F8ABB1E12BA44B185B7560AF79200427150D34601EA5A929025855B34B3067A01BB0B9564C186B2820917D5BC444B30755BAB812C89D201AB6D376135F2220F37AC35876B6012975731077F464ACBEB7A1E7764AD8502A68C9616B09C33FC6688166E1E3170CF6534C0212731049A31D4353BF80A99390064953419E9CD1DECA6F3007D31298DD335B69B971E4F5261F4888318A6A0C0E2AD79C19A827436E87886E29768AB261863243EB5D101A11922B2558D8F53BBCFC1BDD652CA6B10C123C41575F609630C660DD9205E571B276A36C64C770CF3B2D362064F0C94E2BBA158F235F27464280CA9026DE7D64D513C6120035933D3067D03AAFB1021A78860771BC04B4652CCC54F1107CDD25CC96547EDFEE21D1854D037E1DA63CCC916569AAD31B3AF3BA28EBA34CB5F909FD026770036785C668C4181E8C5E6C458C1B786999C42E152", + "c": "E56A8BBA70BA91912F94B7B44F860C332F1CE8D6990EFEE73AA8BC42E890CC1932C65FF3C22B543EFC1E3ADD83757542160EB4C34C129B1260D4E0CA57CB3E403DEC9DC4DD08875BBE186D82401552D82B7E838C50ACE4096D2E2A07F0D4E5C0AA36EFA6674AD28367536AA0B608A552DA186C1F816731675A635CF39D1629D064736495DDEC6E8D494E27E64A05646D6F9C9FB7C02D62F8978969B1184C55B231560561934CD1EC48476E16F980A879EAF400EACE154F294D359ADE5E189D926FC567402BA0F031E1738A286B18AE6D4565CEF9CF884FF5108019704776D62FA44F0ED1D5E8083A449C5E6A1E7BCD0B5380406B05CB43493B7D91B731C0559CFD51ABC4CB452DD304B63061236F6E8845D469D593755CA9ED6DCD181F672DC4DCD6D950A44D632A7A820F3F3147AE93492A4C6F9F565ABA3DAEB648F6AF723C032CCBE300A83AC138C1D203368E2E407162686ED09955251777AC26DF72DED523E39EEF1A5C0885595A0F46F0BE5BA370A1CCFF54E7E34C6EF92EEDD2432C1860019B58E4B3091AC6DE14677522C037707D61C0B028B498E4CAD3A162B4579CEC0A72F2E4AF38E771F0D4A3BDE3F4B7AD110846B5C1B34A5828C3003EAE34707E0B51D8EE4C32E678F7F581386159182C142B1CDA23991573CCB84DC621737212D8146C8490517BF4AA8C16CC32E7B8157993147872802A8D6894F0B73F11B3225D5D210AD1F8DA8FB1332BDD4A88A559D2C8C8890360F9E91234AC29CACD7434DBF44B8F96FEE02103D6B6499B889A166E30F1B2A3EF53532866C65FC8990F6F00E5165DC2A46E77178EB12809B8D15DF1284DB61DC21A87198E59BBFF3583F8D1AD2774B398F36B8F7AC326D76C23A30F670CE2F5853A79C9C9BE46E98D3BF069CFDB292089142091D3D3CCE6EDE3FCA9C5E0168B655630072755B2BC4DCEF5AE34CA27FAE997CEA1A3FB94B9C94E1975DA4122BC65F563D6D515D2ED8A145B3DB0BC8AA945834FCB84E8C8F41029C8EA3DDF2182733B1CE6F806BFB6A8A702ECB73FA66DE4477D5467FBAE85E5E86BE9403B1ABD824B9E00C7DD4E9B7FA0F663A286B6C5461912EF8AB26A8EF900F060D491D2647A3E0111E5DC83B9E481D0D8DE18482F8D705C046EABA60574116D974FE8721AF9F2FC6C73D2D85CA9063FEB299BAE4AB386D23696EAE5D65BADF7148232D39CFB719642787B539DB6EA3FA9082DE19021AB24C29985CD3EF6EAAA6E6E28ADECEA9CB8CAD6D1D81B84C93ECC8F30FDD04B9D5234ADDC4872976687C667BA02EF41DE88E09DF18916CC26FBAC32D10F9AFF3ACF636FF8B4CEDEADB4F9DC1466EC65884AAA34D6DCCDCA02C86417FB9A98D4CCBCF8119C217DF2D3F5A43768D96250704C44ECC8E6FEE91ED46B4AA59FFDB154217DA4ACABDF56B7B05EE41E7EB4F1A5962B24617CD36F7C4C3A2700AD6315C83EBEEBCB6D799810841286C8EB75F7B7FC249A1195C331E617AA8FFF34171C5BE52F753E1C998F1801D3EFE61F135E963140C1EF17CCE1CB9006ACA4A2045F4D508249165F74DC718D5625017E6856590F439842EA064114CB3F34FEE61877829BBB688B4F9DC04DE3C7AC455AF176CEF8719DA7A44A1E3E379BF7936AC3693DDA97E5AA0E384CC7A7C20C4FE13B98AD95F2CCE880A9E3438DCDB50296CD3463DD0DBC3DADAD3D72D00836C7BD3232D4F43B89F73665E9B94BE84A31C9256DCCF57BB1DCCFEB11989576965C0007B054636A85DC70E6C54E5FABD7875E609AA4B9413DBA1DDDE880ECC37DBF1C3CF6D50F797282A623FBD04AC7EB21596123811C6635614B8F75952B83B11E635FB87F0229DDFC7F527197EE4FF99AAFDB9110057C075F2436B08A4A4D6B565CF0EFEBF397E3C565EABC7A26E662203109823E82978AC0B61496D773925D56982373B009127E2A75E33B1490C07FBEB30E04205C305689A233C5C2A1E5700D64C8D1A58304854CD0D06BC51F7C4B592790A2B0B786051E60EAB9D6515E54F2D1AFE4828FA4C904E5E7922B326E8EE663B5A4950444B396EF66471217BD0547FCD65C10B81F9223680D8F84B1BC33894B1D8B6FA2FEF37E79BCEEEB70AFCAA007B75E52BAD27F66889BA4EEF7428BB3F800345A2C2C95B9BED9C86C715A572D6B0EFC7439CB1711A632551F770EC5BEDCC67A68FE83EE6C30EC08E0BF8317819F7B1A5C9C27B6252D48B80E", + "k": "FBF22CE8BD5102D34529C46FBA28B1BBC9787A570C0DDED9CBAA48D29D76725E", + "m": "5729B2AF60A4A5EE3BA6D7F255D7D2437812579942FF2C6F48611669135DD695", + "reason": "no modification" + }, + { + "tcId": 54, + "deferred": false, + "ek": "6914CE520C02BF6687BEB9330C704296E40E350303EB356AFFE66FE8C11A83102472EBC96B6634E76C19B89A5E3E4078AC751480B66288120A0D9B69D78387CFA44F32C08BB7768B292BCC03141D77871F5405ACD1403564A27EEA55298AA0544460CB1C8AB9E4C006EC2A1FB5B48F39745D66FA899C456DE0CA4A5CC4B2E4979820F635B5A286ADB3B8AEA97855504935E21C37E226DAEB41D2B1778EB84F764651B66ACF2E7B44FDD43E037400B50C97485047B06BB5B3D1A16FE95AAB462305933A3C730EB43CB6D5C10D9DC25FE0F8085A689C0C611700F894CAF593BA4833466BAC987211BD548C81A2BBDFABB5CCA192FEAB0E1AF3774F851A646281D1841681A40A1FC34EBC8BBD731BBAE927C403BA9E2993588B885008317965F9967D249EAEB85C650C18251AC22930A6A68366F72037B2250CD9B5A568766842A812C3C7BF7106CCFB122007808A84236C2E5A88BB111EAE388F3756B2410776C6D745F770208F5B8BDC087F16F86D52098B7EFC2416A786772124D41187546BB8681672951960C6148591713C19783186A189806CA9D6EC3BC0BCB49404362B82B311E8C970107C9B7A3D6D526BC59C48BE93C699C79167C63A45289AF1773BA21A9A2F99C6A982034914B55A301C27C73D27B50AF02B35B6307DE2F24B1453064F847308836604C56C1ADB3306114AEBA38331A56E6C126445EAA258E25FB692A761EB62FB1BCC88AC79E5EC8CB583CD8ED799D00516B1021958333394B30166718EA0A600CC37403115516768BA1F110F4F27042D589E719350931735023604BC6B0412B67423826EB91711ADB11AE8067C688B080CCC3939142CFE33C9D58710FDEC082A88903E9238D3276316018D38A841930C919A2493A06051CD9CCEF8E46D62F61AAE1A8600A291B55C35EFA8974F1CBE0DA10005A68659904E13631BBD92AE617ACB7618223931C989EB45C5C88FCD74715DD17AA86704C57A2A2561533B562FA7E5B45BF7212682900E70CB2C8227BEC67CB1D7536B405EB6424CF2F5A5593AB77D579156750B78148C33E79BD9E798BA162FA3332A6A7AC354CA3818C174CA0B354B4C13564111DAB79A0BB95FFBA8A71355558A303FF4E9333A708DCA860915B19EC026B7C4022635E404228776931683467337372B7FF7665E9DF38CD11921594C899AA3B55852B76FBCAD0159254B91B06C412DBB5C998A283314A673FDE81009A6C27F733554914B3582C31D3B2B7FA80B9BE6157122ADCC891B21E43AD0343CB014455BD00DFC2C5A671A86A884A5757336D267ABB2F61E18A68CEBD24E09311AA6621B09E4437CB8C6FFF7A0930771D48AC952E317DCE9A5C1261DD83287D7B950ABEBA6C5300105188DD4B4A992840FE996AE2C3B20D7BA00B11AB9396C73A5DC5477FC0141171F6BB05D4806CC9B244A7AF264D84956FFB8A67384CC522BB1335737D5A680ACD3AD478191638A92A0E7292672A75982AAA8A93E321CAB0DCC616A4B9C344735BF6521FC86B0AA3CB1568A9EF7B19AFFE9C352B5B84BD7B66B07C7378B23B601B88C43B794E25DA22083AAFC52682B2CA90302453AA595C6B43E24A84FF07BF298CE2FF1CB22C6BAC6511784AB4FD5AB1A3B376684867951AA4C78986E04A639E8770A77BBA187F08F7E910AAC433FB5461D374C7022693594FB0E25E52882D310495B1340820AA5FA13E187B6335460C37B0DC1848D7CD6C85711CD292994184481560837820A2B9E3A09B34ACCD1E296BE3816B26764DE9B0B16ECA200B21B9E338014FC5F99A8323C657061C59683DA62B22A370313BF5150476DE36B09912283544E2DB6398B1168BC6A33A257605DB863D3C4A6F190488C402D07C754245C804AF6CE9E2589904666AA335B09C35B78731E14739EE2829AFDC991EFEA87BCB3529EFB1677D5378E59B31167792C89449F2A7BDBE01C8B2883C9B880E626AB1837836BD9216118302690148308A944B1B20D92089E113DF5845AD2F489DEB51DD4D4906E93AB9D027D89261C0317561710A033F55B6D19756967159D70870446A48E6B1B26E05258210918C38DC5985D832556FF6872ECB2BDC1A009F8071DA7992F3249AF49C675DB4502F3D235A63C6321B56DE227AC0AE436E44723FF293FC2979DFEF64B9686A3E28597D5954DCF3594F10EB4D23B649636B79B831AD8AEE1E86B66A18D9A3E3F249BC38D79AE", + "dk": "F13845558CB25F9604BF64CA636A3086E28549689AD94450429C7E1D3A556EF52DFD543ED6209423C58827149C8F121DB21950D06C2D2ABC883E260178CBC5B3FC4036CCA60B147B7B31BBA888913A2B16F0956ED922645F8AC26A9607A5B1C984FB5B983BA78838642B3789513790B738CD2A7805EEE46FE88A645CE282DDD823A1B6BE3B19503932A0B8E0BC0CD89AE9E657F8F519283648638C67545CA06BF7A3DBEC594358C2FC21528940300774A60B6316A7160A73CC806513278ABCB10214922C266E2339CAD7FC921A6C643432766A617EFFAC457F70087C923DD9E959E62839C1287F2611C4DAC7548E536E8A4764CA570AF315C2A46CAC87725D04003EC9E261B6AB2CFBBA931F76323BB52EBDBACD62E0418A1C5DFAC0AAFB556D33D5979F9A29EA264DECF7B7E59BAFE4EC3A03588483D27C9F275EF5E409B034CBEE79B9DDB9C2A04964B11437930C9F54161283E1B1BCAB696A82C6C983010E3A769609AA51B75E53C012DA673746676EA9A7CFF84016DD28B3554060E6B4B6DA9334476A230CC12DC4458B447B27A4D427E45256A6A4BAA1705AF7BC5BB19406D828B729D27147A93B52A4416B460EB72896000705956917F74578424179F4A42F7BF61999B9800294757CD992A1B3B17C08116B0B942B4585E5728AACA79FD8E05B5F90478B56276AB0B7EA18B2DEE307A8C0C017200F2DC687C6D8453F8813807610A043B0C0124092910E82D84BAF169B39E5AB55FCC5B7DA8749998D26836CF30A3F1393750EA670E10A763C64590E3CBF20380F6F329468603E8C5092477AC1A15081FB977A5076771ED2B127D82A555905BE784D5D0477A1D01FF450B863026374287F925AA3518359EF1236119C1304A28E6503480E72273493553255B416032841D907BE8B709C3C145EE890ED16C7F5AA9B8139715307C846083A23550688989CF214A05B4B8C4BF81C4190338A4707DFEAC69D54399C30A046259C7F75435DF3A1105C1F095261283612223582F8FB7258003597E96E5B062450A3665369B962B3B447BBB6262242043B4462721943250BAA684CA55629C8591AB7A65D0AF80B772190418083D06BA7943251E2AC5891821730701DBD2C3AF4678563B8590572223CE14DDBC59AE8E0BA67D8370C2092389B060CF601B433216AE04191E2C608DBC5D6093336884773562BBE7036858158DEEA032B505E8E275B1C7259C4DA6EE450AE1D108FC592C7BF327D2EC484E4586E74C7930233851FC7AA4BE99267D56E4DF11624762E78241D051BBCFE710F78797069364133D8B80DA2CB15E96DEC9A82BCD5B80142AD054532CBB87033B55C22987E7F9B45D007866EE057C1371098783D53662E33A9249B94ADF038554A467090448FCA0543F7B00D29A7B4FFE95D5BDA0DF929B7FFE619BCFA46C0F632FBA13014F09BE589C1D6372757877E62579F806336FDC6B93A210A04E64B43A693FB20C333259C1572930A778BFED83F2C1CA974C0701DA3576720A50185A8AD36C2DA2402679899BEB34B1732796F3B7A939B48D9C56164820531A755F7128C3B7517F29235E174CB72309239674FFAE391A35A6DB97785190C21B256273280422829806C344B3885C2C057558538631F82871678649FFC3F152B0D31B6CAF6F0CF7EC821BF80579B75B099A167C0680D946AB236E3525BC160A0A184F1C13194D909C26B3E9DD18236BB6FC4D71BFAE589A2E119A6EC668BA39965A64A3A920BAFAA9E1DBC18CF143A3DA9461F3050CF4A4CE1C53041972C81E2818B9BB332504BB2F40DCD18A8D852C0B9DC4A72C03EE74922F0596F119A58282A28BA6813D76AAFE9369D4C4B333CE5BC1085676AD58180CB20CBF829827207DC3565EDD1B435A5501803BEB4034F48C07D737AB924871B3B0C879B86976E2C8ED769A6CE8771C947B4EAF75229B8508BA85D41E9529402BA5B626975FAA48C08CFE5F6CA345A4EE105CC5E01B9CD826E9EFB7EEA3157CF5B34A66839ECD34CA355311EEB91A61A5EF6301CCEE5B60D05A4D3D02AF4D8CD1FCB7C914683F53B2CB6E620A2367420043927CA88129C2561709CD5C6AFE7D0A00D3BCD8DA9AAFE605E9F0291B5097806E112C773CFA81C1192811D24ABCAA691600CFBBFF230BB86E781C37B7EFD547DFC79208516956914CE520C02BF6687BEB9330C704296E40E350303EB356AFFE66FE8C11A83102472EBC96B6634E76C19B89A5E3E4078AC751480B66288120A0D9B69D78387CFA44F32C08BB7768B292BCC03141D77871F5405ACD1403564A27EEA55298AA0544460CB1C8AB9E4C006EC2A1FB5B48F39745D66FA899C456DE0CA4A5CC4B2E4979820F635B5A286ADB3B8AEA97855504935E21C37E226DAEB41D2B1778EB84F764651B66ACF2E7B44FDD43E037400B50C97485047B06BB5B3D1A16FE95AAB462305933A3C730EB43CB6D5C10D9DC25FE0F8085A689C0C611700F894CAF593BA4833466BAC987211BD548C81A2BBDFABB5CCA192FEAB0E1AF3774F851A646281D1841681A40A1FC34EBC8BBD731BBAE927C403BA9E2993588B885008317965F9967D249EAEB85C650C18251AC22930A6A68366F72037B2250CD9B5A568766842A812C3C7BF7106CCFB122007808A84236C2E5A88BB111EAE388F3756B2410776C6D745F770208F5B8BDC087F16F86D52098B7EFC2416A786772124D41187546BB8681672951960C6148591713C19783186A189806CA9D6EC3BC0BCB49404362B82B311E8C970107C9B7A3D6D526BC59C48BE93C699C79167C63A45289AF1773BA21A9A2F99C6A982034914B55A301C27C73D27B50AF02B35B6307DE2F24B1453064F847308836604C56C1ADB3306114AEBA38331A56E6C126445EAA258E25FB692A761EB62FB1BCC88AC79E5EC8CB583CD8ED799D00516B1021958333394B30166718EA0A600CC37403115516768BA1F110F4F27042D589E719350931735023604BC6B0412B67423826EB91711ADB11AE8067C688B080CCC3939142CFE33C9D58710FDEC082A88903E9238D3276316018D38A841930C919A2493A06051CD9CCEF8E46D62F61AAE1A8600A291B55C35EFA8974F1CBE0DA10005A68659904E13631BBD92AE617ACB7618223931C989EB45C5C88FCD74715DD17AA86704C57A2A2561533B562FA7E5B45BF7212682900E70CB2C8227BEC67CB1D7536B405EB6424CF2F5A5593AB77D579156750B78148C33E79BD9E798BA162FA3332A6A7AC354CA3818C174CA0B354B4C13564111DAB79A0BB95FFBA8A71355558A303FF4E9333A708DCA860915B19EC026B7C4022635E404228776931683467337372B7FF7665E9DF38CD11921594C899AA3B55852B76FBCAD0159254B91B06C412DBB5C998A283314A673FDE81009A6C27F733554914B3582C31D3B2B7FA80B9BE6157122ADCC891B21E43AD0343CB014455BD00DFC2C5A671A86A884A5757336D267ABB2F61E18A68CEBD24E09311AA6621B09E4437CB8C6FFF7A0930771D48AC952E317DCE9A5C1261DD83287D7B950ABEBA6C5300105188DD4B4A992840FE996AE2C3B20D7BA00B11AB9396C73A5DC5477FC0141171F6BB05D4806CC9B244A7AF264D84956FFB8A67384CC522BB1335737D5A680ACD3AD478191638A92A0E7292672A75982AAA8A93E321CAB0DCC616A4B9C344735BF6521FC86B0AA3CB1568A9EF7B19AFFE9C352B5B84BD7B66B07C7378B23B601B88C43B794E25DA22083AAFC52682B2CA90302453AA595C6B43E24A84FF07BF298CE2FF1CB22C6BAC6511784AB4FD5AB1A3B376684867951AA4C78986E04A639E8770A77BBA187F08F7E910AAC433FB5461D374C7022693594FB0E25E52882D310495B1340820AA5FA13E187B6335460C37B0DC1848D7CD6C85711CD292994184481560837820A2B9E3A09B34ACCD1E296BE3816B26764DE9B0B16ECA200B21B9E338014FC5F99A8323C657061C59683DA62B22A370313BF5150476DE36B09912283544E2DB6398B1168BC6A33A257605DB863D3C4A6F190488C402D07C754245C804AF6CE9E2589904666AA335B09C35B78731E14739EE2829AFDC991EFEA87BCB3529EFB1677D5378E59B31167792C89449F2A7BDBE01C8B2883C9B880E626AB1837836BD9216118302690148308A944B1B20D92089E113DF5845AD2F489DEB51DD4D4906E93AB9D027D89261C0317561710A033F55B6D19756967159D70870446A48E6B1B26E05258210918C38DC5985D832556FF6872ECB2BDC1A009F8071DA7992F3249AF49C675DB4502F3D235A63C6321B56DE227AC0AE436E44723FF293FC2979DFEF64B9686A3E28597D5954DCF3594F10EB4D23B649636B79B831AD8AEE1E86B66A18D9A3E3F249BC38D79AE684426A70833DA1EEB4B57F24F46357D5F7E2BC00853A19775E51394883FD13808716659B02B188799AF5A6BB44CA2C61E4453C93B8AFE22EEAD4A006E31AE22", + "c": "4EDB49DE2FB344B6E0CBFA6023FB26F38B58A6378247CEAEDC9C375B426C2AB0AAD40FAEF291E7022CE4A71CB4550A8128D627218864FA4FCB726778A560C6D2EE40829024CF2077DF34575B37B5FA95D9F1645C7C8121679E4E2D96B591203266CEF61A137039637BB347C828C550B725C551396E72976D23A354947200BA37633ECA962A164A7780B7E737BCF92CEDA690E87A28491C95E751DCC89E65BF511514E0D68A0CAF8EF6AF7207066FD10CB841EA7A2638EC1B652FD43C256CD207AB20B32BEAE063D3EEB063825FAF3C82D978CC01FCDDDE2F093E6B76ADBC6FAEC94FF4B3DD399AB7A24D4DC79BC9A70178A10D31CFA874A34A8953B2BBD60318F90907A3FCE6B85A45954FAC3143139EAFAD8450BB225E21AD4D40BEF3A812D26B1EDF5495523048FF8E7B646BA657F8123ECD950EC5A037FE6476B23466059F372FCC934B47FCEBA612C6D4BEFD6A1AA9553D376EE2F0DB2D2CF763C4C2D3B9DF0BE73A39C785A8B1ACD2CDAB9748443065F6A8FBE891A7B20CD2EB3D0718522C60B6A3ADB949779B17EDE8FF21798D6515758983570EE14F7A7C092CF91E53DEB45555EB0F888BAF4C6BF403DC0982C461E5D4EB51256A5D91FD0E41ADB0D15FD2AA7E2EEAFC12CDB508E03EC2285664D317130650191F578F4DB195D3FB2AEE0804B81939AB040A9DCC4B0523F18599E69611A83B2CE7DE1B77E3DB031498F7DF3F1B95F6ED23FC9E716B365DB32E4AB1A599D41E4C13EAD0BBE635329688122C13C1563D6D882160D75C62B1D72448A2B3F7415C1EC1D87E1C6D1CF3746764001698CD079BD9DC25C8D31F981AD1592A1339708300892187955163F74C937D61635842D07F919D8AAB565927D81FCDA514467C7C22F81E9F2585B423092D6AB13A97697337EA2568E268F84739AD1C04F2A2214919F967958500DBDB448559CEAC825B9CCA2B16B94D85B3BA2E0F2D8C22AE3E9267E73C30CA52E2EB9EBD295F6906A88277DA0FD7BD7E2C986561177B7E1CFD204368C6A82F2DF63DAAC040DFBD3F92C300A49A8884B8BE2C2C5EA32135640BAF8CC22547B3EAA81E259AF2BB1C67B45749ECAEF090CBDC7A3DA9DA00E2B879453EA20EBE8A73AD6E37B81D041F2BA9DA99F8140E0793BF1257F809C04702B2FF942BC9E6DFF57F7D477F361513A21D04ECBA1F17694E6E82347AF22C04CF8FBA55E6271A128BB17CBBAC1B07327E56B4904151EA709AD5E96D2AA731507C0C32F1F79EA64B64D172F7591F14C3D3C1B27F179FF8683B5C89BB63F790C2AF58DE6C529FCB0156ADA6A14E752D8D7F7F1E5ACC2FEF83D6EB0206B30044008E18A6C51C01E949B64243A889FA568AFAA6D3B39A04B9953090D39B7C127BAD662B8C146279E554FAF92892819F015C2A87604793E14B64C13F21A728753DA36E67CF7A9CB31E4CD48EFBDBC875EE29E3ED797D99127AD84361F285A117897E66908220FF417BB560268D3AE754E9C8C7981F210B6F3A0B0EBAB428EBCBFFBA22A7E9FF52ECBE3D9B12E12CAD2E80EAC592E42D17290E3B1E68982FCC7198C8007301E026FC4EEBE482F5132577FF39EF4ED9EA44E6BF410D6203187890139650907CBFBFF75284E5B07A0546552F41903A85E5F074B80F9D484AFBD86EF53667C259855015AB795ED6864FC8DEF018471524900995A7925D5B28900C28AC06D79CB795DF93B46D480417C9BCBD1E1BF3876CD5A2874E60025B0F9AD7A0CC35FBAC64E17528A668F3C005EF0D3CE305BA400413DD0A28F5046180564D689D55D9E8380D766E0C397A2E3F26F70E4833353E4C30A1B007C299D0CB5DAB0A1273A1873E2F5ED10651AA844C61FFBFBB753512A5A3A6A105B9AFF1F8E9A92E0C4EA7998E7261460A83CF36D553992611EC607097421F1A7034297EECAE76DE14AF5011BFD8E3407AECCC47FBFC86A702C04BEC48B47D8CF4C7AA760C5F5323D29832857B86E9347DDDD05C7110A7B8AD3752DBB3A335786AA1C1AA0409FB33FD69F85AFC5B4FD9D7864361675B7796AC9DFB77B17EDD34B84A217966055A818A09E17B0490AA39A19F048A9294DA105F285FF698394ABFCDCDDD21AE40BC31E273A3A814BA54C211962D80784DE017C75A247ACF22CC657E11BF64DEB7696CA6E23BB12410B57708174DD9B47E903BD44193CFBE47719417DA52154E1B1A3EF89DC46EBC855061262DA5C6E933AA", + "k": "FBC5B7112172B55A75DD415C4CB3D5C46A54D90A3DE27BEA4CDD116B19FB99A9", + "m": "FE8AD6E3F3EF1FD1890FB7FF75A8CD9B2A04CAFA7ACEAA99D06D116B81039DEE", + "reason": "no modification" + }, + { + "tcId": 55, + "deferred": false, + "ek": "DF970CC655479D5361B2C99F4E6A60F9D15D9941A36F126062564EEFC3C75871437C021BCE4314A243236FA06A1657B68526652AC65AB05712A1381084254D048670AA24A995096D139236D6A7AEC6A830A4CC259EBA039B6A6E451A0B29D0B4D5FB5FD365B2D81C0D54FBBCFEE19993FA70FB5C92B29C95F0065629D84760272076BC11C3B72B96BC15B3651093DC440F6876E8A27834560B61B8A041499172045ABB4223F0D1AFC71616E8B6958653A08CA776B8916849C81A45A8BCE158B055B69E2F7487D4962FE31061B4B60034567E85496503108CB70167AC4BCFE402A50763941A15A3AB8CBA7DCC220D707ADBE4983A16C3484536EFC860833A527A7388CCB89693FC21906B932BD21584B046677AB9C4E0A54325CD3DD5A78E17CBC3D8CECEDC096CE167E9048C35973F359B7E9B729F95535408919958790427B1CA951080C9A45AA451CADCFAC9FB5804F8CABA9F88C09412ADA0FC2553B5921BE60FA01505BBBA2C33A22B73A69EAFB530AA090ED1734D7561C25299AE954ABA49A0464480B731198A68F9583CF0663322A1A493B6E2A2A2B06CB18B84C701E4AC73E91765FA72641B86249C5817511565023B6719252268585F2B077A3588C0291B36D9CEC74A1DF4FB33A4B95DE0FC7EB1746FD4E17401133F583954B9C947AE6A9AB443CC99924913646F70B29387293459F6317919C177F87EC01CA9E3210455EA25429ACCD4020CF4E43F98999D3739979CE39DECC5361F152B330255444A05F13406F6742BB51156A07854BB0A91C0B45C0F1678FE034BB7B2558232C14F83C822A22C7AAB6934661682E23CADB26D9D9284B519A4595954BC56CBDD0062BF657898B24C80F3010B849E20B269BBC68A538749A6F06DA2D62BC7FA8A25074629D12D22C6517BD4A20D8531B26BB13D2C9B2AE1639243B803D30455A1C0E4CCB5E3C206F4A6BB5C65B3205C56BFA678AC4189CD108DA5C654F4DA7EA30B0D7B23985EE80EECC2297CDBCB6A2A6B3A3C474181BB42F9150CE57FBC6C8ECCE43990F8C31F5579C71C7DC9615D47506666D05BC59339052BB090078E58858780671A65A14CEA22018661B9945A0D0EA2679388C308460AA9367CCC97CE6EA3960AA04BDD28B1B98158E02BAD3EBC3A97F2BB3A1319FB6178B99B42016826F4814960355722B8CE3338BAE0E97084613DBE41064D0A6F3082CFE25A18978975AFC04D0E1C9CCB0C1DF5C9054B22912844077DBAC39E40CC18C87179D420AC782D40E3AB5294C5B5E786814918D048835BC5333F421B366B26568C20E832AEB0410605C3B78394CB1CF5108F5C7538630C8EE4A611412F75F1691133A93EF744D36ACDCE302516735B09B05776049DEEE674F894580A55B792CB4ECC5916D0E3042D3231C8E70DAE111AF3A386ABE5A251FB9F18B6AAB4D79CF16BC884BC0993266C35CB267A9AAD057CBAE4ACC071123CD8D35C86A7C23A6771FC5799CF29ACD8F08E6C0B719E3173162418CD6B008C52A29EC5A701C97ADC906BA4852F7590353B190E96BB8A6C67AB9245CF45BC7DA31B5888B5B6FD77912E81A9CB522946D77305303B6F28B6A89469E734B5FFC4009C341114768EF8C0489E66C7EA3106F224A9AB4B0E147911757521BF39587BF211D9DB8F9BDC9EC21B881AC727810B4D1303A38938A70AB3248BC547B3783F68A84C5C77053726B808825FE17BB8D5672D77E4A178AB3C8EFA8AAEE419A09BB31CD40692A4BA273A137530CEB7198C5F38CD960049BE317AA924ACBAE241FAC48AB540C6CF7A4E58CA5AD3076DD7FAC09DDB1B49DA3D5FC751AE812A416B098CD712ECB99CD0567AAC9BB48DE700120584FD09A201D49A77D16132527F5C0138868C18FEC89B3D593EFA912FF66C79A2832A1B0234F5F0B67091ADFBC507913A41A5C22FFED19109AA9EC0F99395685682F6934010056543AA88738F1D88ABB1BAA21D35585F5534EF6241D81476FF33B434B4C335323C77318156F75370E1403C390242E6C7A75A9D800C0CFD84AE2AD52B9A0A492D441131B68C27DCAAEA93C2E3E2C661E054D8228B03243539649B861927947C76500910A5EA0164D43865B62BB1B30D032334EAF296ABBA4780DA5F12EBABFD021C3FF3A164B0745C09328D5BA0F6127807824E2A7C8012201510C3368067847C71C50A9D8DE22AC182D1644E25A39ABFCE37DB3224F725F065", + "dk": "D6E3B9FCA0A85F25A724020E8FB38AB88BCBD82A7149897E5D0945DF34B0AE07B17055198A7A50A1328E844A186C375EE9B15008B8978235445CA39A73EC8941A14ABB6750B8B2A8CEE62CE44BAAE93585AA6945476B073D176EEAD288060801F9B71C27E366180782E0AC500E2105D6995E47141D25901632DC20D2D89AEA997B5031033F295F92C5C599A0237E1C24B9DB75C03A01C08A78E42A8A0BE3B469FCC341601823160581B529226B7FC161042A3680EA476F12AB121D6A3CB90C24DE501CFAE8C275239F4DB27D22D58CD47440052210DB6A291E080A51A34440A768B70085EF3251AA045FA40A6722C44619512D08E873F1645D0D542EEF6CB12F5B2DB3E3186403B9670A39E0F2CAD3F54998E459AD7647FA8B4F6D900EAE144547F9C506728D080AAE5B2726F5E5212036C5DF172648E6762E09792056C8269289CAD365CD18405A0C182FBC0132443701462B32F31F62E92DEDD4BACF3135F2453A28A92E0D308EED64854D009A700C0BC49B2BFF97C3D12BC481D131174B06AB1B9C10C92EDE463655506E13069B277A0A37201A8B3C6E3EC020B5882ACAE56A23B84232E66211821E2DEA3C9C8B069269229D59AB7FF7758A7C51FA388D74A85B0459364C3669E4B1A230E063AF9868F4CA31694B5E69752872B15FD4A6C577BC4B1821867C456DC6547954C8845425BA9CA5868135159417BD314BAC8BD8533E477B0C759F7FD48F1BF0281C79774A82927FE1264BC2BBB7D4AA479A76EFB9314FA856AD608793AA1D571775A7E363F9E220122047C84648F8596727817F80ECA00E0B4A046AA1255223632098E696BC0E40ACC6A5CACD84C19148B5B4716FDFC2C4CD477D923269E662370C105190983F45550FAD198AE6D512D72362E16C350E783DB9F4BAC4B525C163A20FF261E14A3757B8503C14ABB7F0C7618737A2E0822DA837D606996C073F389A8B68CC2B25170A282C051BE02FF9901FE3D53EF8367587824D4E8051CFE0731E676D754A532B3329BDE45A7F2A92A5055D96560E5B902DFC67B4AEF100E90115E6393BF70397981CA1DF6C8FD6249941FB4D7849434CE52CC0257E98A1724E9BA47425AA21A0C465372D0A299643564EDBD44E3E4119CC063B7A12B969A40A38D33DA23A059968965B405077A8084439AD9D8495876953896827C8E02855F8CD34B288789CA03DB8C8D5914D538794B97B2F6444CCE53686EB07CB21C0BEAC757B3424CE969BBA4685081F926B30791D63C14573C01E999455B1395B6EB19102B7A70CB524C5DA378259461D1284E1EACA66419C166306BB6A8980A54ECA11C2797C988716ADB5E5BE7F4B0E2C2C0BA6118D93A934D8980742285738EBA7F8997F2C9B4D6A3C18968772C821A8E7A9A6969B948CB39977D88AF487A7C7795F4156BB076588A2DC5C2E361EA31BBEBD689194D55D8C43A7420B9D1B0842C0FC45BAB664B310657F57B8BA72A5CC34CE9A1BA939164ADFA40A643B4EE786415891B5F67444567A5B85156F0CB4931F7A7E50157345CA00EEBCA7921A8B0AB00519C0AC2E174452C69D3D963D4FAAA68F6066DAF78D25F798F333949CD80E055116C3F687BA4B16E1A50820155BF6D0740533C4A9A7AFC863CB2C44175DC0BC3D2026EC66408CF893C65B8E31C79D17F33D1C101963D46C0E77C265A977E2D45969B602550873EC3AAE1536339BF51CC1F033B1130B3B269026331B17662B9DB79CE42078FA870946782BC169306DB8034AA72D38572342F621E08895303165A5303BC8B24C81062A14A6B84ED929127920E3EA2763A6A4E65060DB9565DC13305F112D61685ED4A1A8B52969143A7BB42B6B76A3C2FCF96242AB3B58B752188670D4F14CC6BB278C31B59E19A1EBB9905D019B21B8B054933B006823100B5015054A9B26587D9B594B083F01D80B43648A428A514D11814C42059A0C5EA8377BDD25351FD000178485241BB72C28CE0EF210052259DA97C589D66657F4A6B6BACB54F417ABF485E01A1B58FCB0D455925A21605274C16684C1C69034672082D6B923F08BC339753CB0A4329E37C6A7DCCAF3801D1EB72A49C03E7CD0B1A8DB9B44106E33ECC8CB432367C7C061E122DB7C31B8E2AFF9A750F579AA1561950924A44ADA9A60ACCEE2159028C356A431741D0037DF970CC655479D5361B2C99F4E6A60F9D15D9941A36F126062564EEFC3C75871437C021BCE4314A243236FA06A1657B68526652AC65AB05712A1381084254D048670AA24A995096D139236D6A7AEC6A830A4CC259EBA039B6A6E451A0B29D0B4D5FB5FD365B2D81C0D54FBBCFEE19993FA70FB5C92B29C95F0065629D84760272076BC11C3B72B96BC15B3651093DC440F6876E8A27834560B61B8A041499172045ABB4223F0D1AFC71616E8B6958653A08CA776B8916849C81A45A8BCE158B055B69E2F7487D4962FE31061B4B60034567E85496503108CB70167AC4BCFE402A50763941A15A3AB8CBA7DCC220D707ADBE4983A16C3484536EFC860833A527A7388CCB89693FC21906B932BD21584B046677AB9C4E0A54325CD3DD5A78E17CBC3D8CECEDC096CE167E9048C35973F359B7E9B729F95535408919958790427B1CA951080C9A45AA451CADCFAC9FB5804F8CABA9F88C09412ADA0FC2553B5921BE60FA01505BBBA2C33A22B73A69EAFB530AA090ED1734D7561C25299AE954ABA49A0464480B731198A68F9583CF0663322A1A493B6E2A2A2B06CB18B84C701E4AC73E91765FA72641B86249C5817511565023B6719252268585F2B077A3588C0291B36D9CEC74A1DF4FB33A4B95DE0FC7EB1746FD4E17401133F583954B9C947AE6A9AB443CC99924913646F70B29387293459F6317919C177F87EC01CA9E3210455EA25429ACCD4020CF4E43F98999D3739979CE39DECC5361F152B330255444A05F13406F6742BB51156A07854BB0A91C0B45C0F1678FE034BB7B2558232C14F83C822A22C7AAB6934661682E23CADB26D9D9284B519A4595954BC56CBDD0062BF657898B24C80F3010B849E20B269BBC68A538749A6F06DA2D62BC7FA8A25074629D12D22C6517BD4A20D8531B26BB13D2C9B2AE1639243B803D30455A1C0E4CCB5E3C206F4A6BB5C65B3205C56BFA678AC4189CD108DA5C654F4DA7EA30B0D7B23985EE80EECC2297CDBCB6A2A6B3A3C474181BB42F9150CE57FBC6C8ECCE43990F8C31F5579C71C7DC9615D47506666D05BC59339052BB090078E58858780671A65A14CEA22018661B9945A0D0EA2679388C308460AA9367CCC97CE6EA3960AA04BDD28B1B98158E02BAD3EBC3A97F2BB3A1319FB6178B99B42016826F4814960355722B8CE3338BAE0E97084613DBE41064D0A6F3082CFE25A18978975AFC04D0E1C9CCB0C1DF5C9054B22912844077DBAC39E40CC18C87179D420AC782D40E3AB5294C5B5E786814918D048835BC5333F421B366B26568C20E832AEB0410605C3B78394CB1CF5108F5C7538630C8EE4A611412F75F1691133A93EF744D36ACDCE302516735B09B05776049DEEE674F894580A55B792CB4ECC5916D0E3042D3231C8E70DAE111AF3A386ABE5A251FB9F18B6AAB4D79CF16BC884BC0993266C35CB267A9AAD057CBAE4ACC071123CD8D35C86A7C23A6771FC5799CF29ACD8F08E6C0B719E3173162418CD6B008C52A29EC5A701C97ADC906BA4852F7590353B190E96BB8A6C67AB9245CF45BC7DA31B5888B5B6FD77912E81A9CB522946D77305303B6F28B6A89469E734B5FFC4009C341114768EF8C0489E66C7EA3106F224A9AB4B0E147911757521BF39587BF211D9DB8F9BDC9EC21B881AC727810B4D1303A38938A70AB3248BC547B3783F68A84C5C77053726B808825FE17BB8D5672D77E4A178AB3C8EFA8AAEE419A09BB31CD40692A4BA273A137530CEB7198C5F38CD960049BE317AA924ACBAE241FAC48AB540C6CF7A4E58CA5AD3076DD7FAC09DDB1B49DA3D5FC751AE812A416B098CD712ECB99CD0567AAC9BB48DE700120584FD09A201D49A77D16132527F5C0138868C18FEC89B3D593EFA912FF66C79A2832A1B0234F5F0B67091ADFBC507913A41A5C22FFED19109AA9EC0F99395685682F6934010056543AA88738F1D88ABB1BAA21D35585F5534EF6241D81476FF33B434B4C335323C77318156F75370E1403C390242E6C7A75A9D800C0CFD84AE2AD52B9A0A492D441131B68C27DCAAEA93C2E3E2C661E054D8228B03243539649B861927947C76500910A5EA0164D43865B62BB1B30D032334EAF296ABBA4780DA5F12EBABFD021C3FF3A164B0745C09328D5BA0F6127807824E2A7C8012201510C3368067847C71C50A9D8DE22AC182D1644E25A39ABFCE37DB3224F725F0655D6E5BFC5F96134D2C183ABB3911441EC66B794509ACECEDFB7359BA96E9097A6AE0162D48029F424D913B464EC63CFADB3A377109A8759849A8D8542508F050", + "c": "5F7721D08E0CABF5F01821C90767B448F4F53DAAA7ED10FC21702CEE8FC28C32FE20AE36052291C7887B9E84D3C22EA9B401F870A12DFDDC32F1A848E0EEF27C9B7A7A3AD57340946A180596A38757BD6B2570FD92102528B2D0DD804D7F4A76620DAF0767428B3B63B842512EE6816B86B5C5AE08EA8B3A2D61431F185382E8957D399C3E32BF832322915705700EE2A19CBBFD12069CB903F30053B0FFEB61149266593F0733ACE7356455A6D70F7EE6BF7D07199FDEAC313CEE1E06EE5AD50E89BE5A39A73C82277E67DDAB9C88FE4E734FEF19065ADE9C548CB6F91F90C6B899E5FB243284AA1F16CF19F607E18AE8E8A01BDF06AA7F0EEC34E7C1ACA8C407807D986B6B64AAC6A6F5D395AE57A48A4C135F17DD2B5B62EA5C3B83675545787F5EF43832A908D5D8FDCA3D7E60E884F70EAABB062CFC0078539FBE68087CA01CB0401B634A275EBCE328633428EBFDCBA373505BEE1DAB5B531C90C4136036D5981B93CAFD71F6F9FEFF5BF2BF5B01F44FE57F87ACC60DAB8C88DE57087E08506097F31191C376B40048D0349B7F6F5A77E83A8A0B0F3C317AACDEA059F7B7949C2F14087924A28B752206ECEAE424BD7F3B379F29F74D3ABE320BDE982911C15FF6990A3546A8391AC98ED942C63290307F10C398F85D5B0CC11758DCA79B320EA26BDE1F898CFB061882B984FCE7487A69AEB5E4DFECD42EEF146B93F38318F5766F263C67771EC67B0644FB0854E77B02DBA2C05797D24EB1D219F473A732FCDF41317259C0AD919C0AA77B329CC8B3A448C4BE35CDA609F0C4EB4A01B801F380A4F5441BAA6D415507A4BAADFD80E50B563F570ABA9701B264AF7830482F536B49EC2EAC2ED19E853CD51A0C2D3F234135EE3B0A627F1070DCA5016CA3F381333CC546EBED09BD5A7B53B31874FD7A7391451C0195CD64C4256089D709182F4D5DC83CBABC94F53D94FAFCD60A4DF94E06C51F95C7854B5A9A34BB3A8BB06E6B25F2C4098D3A5010DC0793EC23AFE1F55B667E2D2685CC8D335509E41217F05DC99B9998369845F4793C55869300283E119A0C6445A214B5DB10CC62D7214D3DA936A264F566E28B06D9EE12DE50CBF2C68B6DA8E80AC1B1780E5A2EB95CF40F1B947AE4CE0AE1D169408D63FE4209522A5B4686E32E5F8EC4DF81B4EF33837D9C120843234B7431D997D1EA678430CAA9F0228518C8D7E1F0FC3AA31900CAC9EC0BBE002E478527F8E2B24A41253851B4954FB935094C2E3766BEDB53C75CFE7A76EDEA1365B925BFA047D8A3463E5F5709EB39C7E69B2E1B58375D177522C25BFCF29D8E58EFD215350C76CC4D5996AD0FBC7E3ADD94A87E154C49C68F5F18AD4728C9EF1D5040F795EB62DD8CFDDCC83DFF8C5FAA7861D0AE62AED8B232FAB8DB8F64A62A613480D1087F1430D6783490BF29E418BD1B524008676FAF04A29ED9F07FB8E3F4800E2217DD5176392CDEB059762AB5515E243618D7D6CA7B7988CBE52D7B76D0EBB87420644CDB018C92BFA53B57C116643D3DA1F194687E8004BEE958FE968F90E50153550992EFB49AF037D28835E292CF8867A7FDD055833700026E8A97CE9C65A446E9B424EDA15B036DD37C4122609CF70C04E238078A1B759B9A3901AB3336AB47D208FAC6D8B45946D9533F9F48D5B44FE228CEF14F9B9E67F140708E2CC4C9F8D4F55B57658566D9A5E2BBB6554AF989C89A0ED2C88934477F59C14480AF77CF7B3773BF5FA29D0BFD89DFFE4BD597634DF3FCB8C404CC935651D4EDCAD17E5150595D0E7A2599965CAC799C30D37BC2882E0088FEC1DD687471F194130925F931B0A6BC56DF3FA0962CDCB75C008F30F5664B065BA94091C7961BF7549089EFEA6D79372A7C21F2728363EBE32654A5E2AFDEE5E2E9584A658868F48F481032BCC65930031CFE3B777B2FDE5551013481D7584D133772E5230ED502D4208C6128998F140ED9589530B9CD312AE221A8DF4CF979F0D65D8556C5EA30C310AA84E493767C583954931F151DE4DB5491869875B89B7A49294044FFC59BC732CAB155BD549043F30968B821463E4F61B6E10C151A1F1C873F29C49D88B1C075EBF120951018A6C289A6DB7E352557F2DA5D2F2FD8A7AF33FB9664650B63EFA6778C4BE12B104BB3778193C6683B1EACF0264B448A195DB8566951B0BFB3D64EAAFDE75ACE82C067CD1656D88440F029FBF010", + "k": "7F8443BFA35178C5DD7008B9D8DDEFF28BADAD893E16313FCED911730A9F0B3B", + "m": "0AA3B1F8FFA63F89F949DA18B6D8570BC5811F85A4BFB293E9D411ACD43C3227", + "reason": "no modification" + }, + { + "tcId": 56, + "deferred": false, + "ek": "8FB403D0105FD0EBAFD6505968774504C7823474A1C26280A178BFD33368E14491C100CF58379A55575D753B75456196B5257D2B4BCBEB586EB0397BDC20B798DB6F12A8245FE80DAD6026DCC76EEC5B6DD6F9B5EEAC5211D408CE0553B11394F1440220F03FBBF4158A1C31F4735BB2296AF336C4869713BDD14D686940EC57CDAEFAB8FEBA2FEDD2C51AE61B4D67C5FA6B444FFA2E150788F1D4A12CC7875EF70711A38207C840C2A0337BC3CF42EC1F81464F731C5F460820CD473532983EA710846279B000586140A9B8F2B873C200B8F8D55D1A422F2668103FA8169DB77EA5957C4FA9A72259B60DC27EA16BCD31A051BB528246F05DE7B22398EA32C2230FB520A0D600CD8C049DF9BA6A5C665961344974385FA55525AE340342757BE2831807C552881C13BA133CB9BA2394453818D579787A6CFA356FA560BBDED6182A676126494D98A80161A4987B126DF67633E7433BCEF68690A12DE679512507AC1B9186367139213A3023418C69D0C67DF320C2CC88BB7045543C3380E4A953A03E63854FB986BDC898111F6A7A8FCC74A4F3971F21850E9770CC07CB0C5122CE8B2F873813AC558D9D4474C80084F0A924B3E2B7F4F4137EF5007F0C5605658DED4677A314A44D783C2E3222683B4DBEEC349FABA4430AAFD49160B6C91F2AF4092EF63EBEBA1937705F18A387A6307A733773206B8F2D4052D4C36D2F557FC0E226266116CE41B59233363ECB728C0343C0648AB1045CB03A1C225B89FA488114A060AAF48A68CB7B20A3C55A71ACDD7742DD05AA8495815646353DB21D4A7235450076CB94041D94A5D0245BBFA3598E870FF0E30FB81213B6F9916B78AEF3D43574CC07C9B5CF257A92876C49ECD73B5AC24DEC0BB25FBA54B29CC4A410AD40B5C6FAA398CFB82D2401878C79AF021CA0653A0FDA4B6474F942F93700ABA364AE3611B7666EDE2A8B2EBBA701AA61387500D674A9A9FB0351F06A5CB699EF73457A8ACE9E8B63184768363C50AC000220F2CB708AA27522149975BC951553EFD5B577D507279346E5D00F2EB31EF1DC1EECB59007027E65D28F0D10B7484654241984010B224F174EA69B1C36A302BC20B3244B030B231FA5532A4B206D3B3398E9EBB773B9CD9821BA688C06BABAB29DFB6AA2D427A258693BD1AB13276990B1775AC94B6BDA89F8866AA3A94003B3985086232A4A61CEEA8B1B711609B3285AD158BAE4C21581AA1541CEC7101AB7541098EC7093E442B21296ED172540972F52C04EAF6581EE942C6ADB287A2AC956D84B7F726158D8637962A40986B1F2AA1AD6762C08412F67D1A7F69B6F0F87AB022B1A48F4727CEC2277D1B157932B860A156DE79FEADB99DA7CA0D0B7A4A9D0B3686A100505369C47AD5DF8661CDBA888FC4C7EB1CBF9555548D87755C3232BC3467727AC4625B49145BBD95537585018A7FBA2A8834ED587CCA5F44884C87BF5B5AF8857A188B77A36A01B16F28934E38C9513B5A44926FF41212B13629E2986B8458AE3E9975BBC40C69214068BB78C127FFD4A664DB90BFC068B67106A43F1BC7B094E6048A529B974EF615517ABA2ACA75C97093487C2A265330EE5454985C6435FB989E100B5C9B80DB0A49421D6A75E1632F4B03F5AD96515039D8291C67A15902FE1C027133939183EA0434AD25B45CCBC0C69162CFC1CB527E392B1756E64561F4442BC5814098F33AC673614A8DA326F8818718603110836AB31778536A9C47BA820960CF181CA829A9911792D67DB209E9A66CAC38BC57A4CBD4AA3D07C3447F72D4231A69326AF512314D9AC918DA0BE19B624E5446180166D05F607B1EABC04B2A442DB33C71B66CAD3AA8E559662284807A69EB0469E8B321C73900A74C4A66D40B3CF382D53A12FFA26B9C8888516633E9F292052FA231404483FA41E42A9AC72312838BC7E17027C5EA055967497F3C9988D5A6C4076913DAA9D33C11D4335C850121A93C25A89E3AC0612087943A35E23204EEB12921675AEAB244BB53EA24C969DFC2A0F99BF925666C9A69F123A756104CFBCC88C5A2C8AD7A21956272E22F58035C140BDA371DDE7329D6728E2A05A150719C2D578FC511DD3361DF765C83BF2B04BA7546E0CB5C28C211489C96265335FB5BF6B3C3779E3CFF1C77379E336F3481CEF55F2F61A3CD1F98B88F29760A2BBCCFA7BC9270DCD07F290CEB1D75B0F5941", + "dk": "A707213F208CD438561CF949B2A2066EA1234F619588A6A9B9771E26055FCBC313E918C225B8A6E4234C3664965F20B7F722CE407A68A578888343621AB24E429B1C88C5CA352B98BFFC66B6C7B01D861634B64A986CB5BC16CA4A89C87C455FBF8B74BBEC707F67C552F9B03DA8C521E02D147192AF05BE3C394091B60934EA3032646DF68680A91396BC091CD8806A76D676693C2366EA7196DAC82D060336FC81FB4BCA553C2E21449A69E3C4F84B9906D0AEC2B9C18262C8BA231BA5608972A67B1396BF98D26839901F0BEB0EFCD907E0015BB21CC7F0C22E09B76969E8C09FEBCF105AB9D6A754F6EC6253F615445180BC8668A8D03CE68C2609470092A29FF2127990B14467F960C536B37BB4A980843C8CC76D9D10B2CA26823D513380655883216B5E49C9DFE62D14C1A37132BB072511557118C7B43AC4488D962989394366B3402E739BBA1F69A4F2512F3A50568B8046EDC4A319725E5067CE423B58F496399C44AB2A51C866A26323C68891F5AFCC5B0FE7D37AC31403629CC5B65B9A71E192EED60B7989006B824E0B510E3577C92A3751BD2AA5B1538742303700212CD3C54183724B351C40BAA4CAE46C79CD9383FE1719D333BD4FC33F019B3096065087039CCD21A48C582DF54BC1BDF4BB5391A1DFCC5EC3C57FB95BC9FBE5B611453812E936EFC35AA4C51B42329C31A39A2860C921D9B326F51FE47945877CBFC95178450972BB4A57AD2B2AF1D28AC1D7B01505AB18E964FA567FD9F53B397C2C0891408BEC73494A4563598BD2D1B4DD58603CA80C35A708448B3CFBD4B1490C9ADDD35FA0A4A6F01ABCEFA421DA989DBB506550194FBBA8623AFB8AB97B6E90B0570676191B23AD8D25C5EC054948A8416D13AA890B7FACC6CBA03B1E12F819564A44A9054594500F8F74AFAC8B188EB350FE35A8841A144950C5C75538E8F78621C07FDBEB9A187B0A12773700E0B3BFC7CA6B317B89783250C8263FAA6CA8B53CAA662E3AEC1F07B1AA9461ACE168CD873787B28A6ED501451D5CA306E0000621C35E8BBE57A8795E978637FC781CBC76C60663CAE160D4968988634C9B5937234C5F88BC4CE140763D0520F635BA2BC107049C78B826A1B8A23DB4EA58EB1BCD5D1931329C04DF199030B07F258045DFCBC426B36A8BD0A3A7AA55CFBA400654A879AB97342CA506D6579738913E702C7630AEF8778C4CF61CFEAC53F9EA8D17CC766A09C646662A14077DC95600783B9E372660FB2BB806D84DA12C64CD110F05EA1A8E373D3606083E3382C9EC7FAA649E61F0343FD721F99745F8E2ACFD0707DB053B6F67A0214740BB999D9B434E9218B388F73097F83EAE9792D4515B8267B1F650896AB9BA11C778E3897871B28893281FF33C0441C767556B4FB5852608B01909398115216191A98E38A5B16C8578F1748D69B84BCC474817714CA29534ED17CA995973D0E935D3221A394BAB5F70BAC95590D2791E5C724F77C09B5E0542BB1279EFB4C2F842BB2A8288DF512451D503727187CD3B7812B67257E107248CBF2B63C099228064020AC45B46DF110FEC3960ACD0B4F992745450116BE351123896A2489A76FA4739DAC06DA63CE4FCB6C2C46BA3577D37BA1AFB296ABD2819F324100106745E99B534606F67898ACD724D2F390F67B8AFEA0B7310491F86A31680755AD1FB78E9AA2AC61769DFC01013C38D7D9430F697A51FD627B7699656751407DA16AD8173585BA595ACB14E019ABEF921CD49BA131CA7DA2B2C7D5107356961973039FAF30E551478CD3C7137BA6637673CF715439A09A6D7FC955A35330FC923F09CB33D31B5E3F906EC3BB229C4813F2B1D4D449388507A9377BC100264CDD2C50D5B9E5410A92B7A6B8C5263896CB2BF3C4643F7142A8CA2CD571779766890ECC84453584EE666D4A3C651762E1E267BAF71108E04C847B8693DC1CB2D6929DB811D505588D03629A25753A6787A02B19F3111C6F025B33BC80905DB11A15282A97A031AF8A52AE40B7B83939F7C210D995E24757B589182D92903647256A921C0520445D9B177F4F33F77174CA76577FDA72289D49592FA0E58EC50F9EBC0DB40482F277A1F6381E4372289168F3675A4F3731378590671301A9164390DD3656EEACEC005954F3B3399E6045966434021168FB403D0105FD0EBAFD6505968774504C7823474A1C26280A178BFD33368E14491C100CF58379A55575D753B75456196B5257D2B4BCBEB586EB0397BDC20B798DB6F12A8245FE80DAD6026DCC76EEC5B6DD6F9B5EEAC5211D408CE0553B11394F1440220F03FBBF4158A1C31F4735BB2296AF336C4869713BDD14D686940EC57CDAEFAB8FEBA2FEDD2C51AE61B4D67C5FA6B444FFA2E150788F1D4A12CC7875EF70711A38207C840C2A0337BC3CF42EC1F81464F731C5F460820CD473532983EA710846279B000586140A9B8F2B873C200B8F8D55D1A422F2668103FA8169DB77EA5957C4FA9A72259B60DC27EA16BCD31A051BB528246F05DE7B22398EA32C2230FB520A0D600CD8C049DF9BA6A5C665961344974385FA55525AE340342757BE2831807C552881C13BA133CB9BA2394453818D579787A6CFA356FA560BBDED6182A676126494D98A80161A4987B126DF67633E7433BCEF68690A12DE679512507AC1B9186367139213A3023418C69D0C67DF320C2CC88BB7045543C3380E4A953A03E63854FB986BDC898111F6A7A8FCC74A4F3971F21850E9770CC07CB0C5122CE8B2F873813AC558D9D4474C80084F0A924B3E2B7F4F4137EF5007F0C5605658DED4677A314A44D783C2E3222683B4DBEEC349FABA4430AAFD49160B6C91F2AF4092EF63EBEBA1937705F18A387A6307A733773206B8F2D4052D4C36D2F557FC0E226266116CE41B59233363ECB728C0343C0648AB1045CB03A1C225B89FA488114A060AAF48A68CB7B20A3C55A71ACDD7742DD05AA8495815646353DB21D4A7235450076CB94041D94A5D0245BBFA3598E870FF0E30FB81213B6F9916B78AEF3D43574CC07C9B5CF257A92876C49ECD73B5AC24DEC0BB25FBA54B29CC4A410AD40B5C6FAA398CFB82D2401878C79AF021CA0653A0FDA4B6474F942F93700ABA364AE3611B7666EDE2A8B2EBBA701AA61387500D674A9A9FB0351F06A5CB699EF73457A8ACE9E8B63184768363C50AC000220F2CB708AA27522149975BC951553EFD5B577D507279346E5D00F2EB31EF1DC1EECB59007027E65D28F0D10B7484654241984010B224F174EA69B1C36A302BC20B3244B030B231FA5532A4B206D3B3398E9EBB773B9CD9821BA688C06BABAB29DFB6AA2D427A258693BD1AB13276990B1775AC94B6BDA89F8866AA3A94003B3985086232A4A61CEEA8B1B711609B3285AD158BAE4C21581AA1541CEC7101AB7541098EC7093E442B21296ED172540972F52C04EAF6581EE942C6ADB287A2AC956D84B7F726158D8637962A40986B1F2AA1AD6762C08412F67D1A7F69B6F0F87AB022B1A48F4727CEC2277D1B157932B860A156DE79FEADB99DA7CA0D0B7A4A9D0B3686A100505369C47AD5DF8661CDBA888FC4C7EB1CBF9555548D87755C3232BC3467727AC4625B49145BBD95537585018A7FBA2A8834ED587CCA5F44884C87BF5B5AF8857A188B77A36A01B16F28934E38C9513B5A44926FF41212B13629E2986B8458AE3E9975BBC40C69214068BB78C127FFD4A664DB90BFC068B67106A43F1BC7B094E6048A529B974EF615517ABA2ACA75C97093487C2A265330EE5454985C6435FB989E100B5C9B80DB0A49421D6A75E1632F4B03F5AD96515039D8291C67A15902FE1C027133939183EA0434AD25B45CCBC0C69162CFC1CB527E392B1756E64561F4442BC5814098F33AC673614A8DA326F8818718603110836AB31778536A9C47BA820960CF181CA829A9911792D67DB209E9A66CAC38BC57A4CBD4AA3D07C3447F72D4231A69326AF512314D9AC918DA0BE19B624E5446180166D05F607B1EABC04B2A442DB33C71B66CAD3AA8E559662284807A69EB0469E8B321C73900A74C4A66D40B3CF382D53A12FFA26B9C8888516633E9F292052FA231404483FA41E42A9AC72312838BC7E17027C5EA055967497F3C9988D5A6C4076913DAA9D33C11D4335C850121A93C25A89E3AC0612087943A35E23204EEB12921675AEAB244BB53EA24C969DFC2A0F99BF925666C9A69F123A756104CFBCC88C5A2C8AD7A21956272E22F58035C140BDA371DDE7329D6728E2A05A150719C2D578FC511DD3361DF765C83BF2B04BA7546E0CB5C28C211489C96265335FB5BF6B3C3779E3CFF1C77379E336F3481CEF55F2F61A3CD1F98B88F29760A2BBCCFA7BC9270DCD07F290CEB1D75B0F5941582D82EF332E43017214599D3E49B9F9CDF7E5EF8417B8A95EF46A21618AE908AEA17274D9BC31873ECE5211AAA326A34048F067A162DE56CD27FB17CEE38628", + "c": "78BDBF1509D64B097F89F9158A5474E57CC04818DC01713DADF6C574AAF9115C23C641077EBE2CB2B713066501DDEB196A72067639F30890A41EAE9A565E6EF4735F1DA233FC7647F1B9397BD00E7F387B58BD4C90CC310172AD52BCC4EFE4FF533A096061EE5DF3E3F86D7F196EBFCB02FCF5EF6BDC5CEA034D5F33E61F6F805E4F76CB425B466D620EA166E828D692E12C568767482BF32C98A5A8142015A66BE48618347D49997AB6B0F53426BBDECF1A653458C2D8A6D80D49B736C2445216BF580E85BB794987986955523C6D78573608F1E2A2EDEC9F2862A289DB9D9BC8780B96FAF5D2DCDB0C6AA4A381C97FDA9A67C2F6052B145C8DA98C5BEE640ACD64586DEFDEF5FE6430F883B68C57366083B24C783561A41A3AFE3435ACFDC8BC5F14711079A8B0419000D41BAA5D45B70F9BA844DAD01E3CE992BACCD90B6B22B6CD81BC67BBFF830FA5EACFD6F508EDE4A11998DCE7F9C715F404F20C0AA98FABA50E0028994DCC9BEA50EC89A8CE26F49791DDAB8E16150A4C0A9883E59DD6737EB9EC79B63CF6612A71DF6F4CA023591DF6B5800EDF02942EA286C95F650415EF28C6F71E6D29DFAD488D2BB735E5658352A38F9DB04541716122AB51AD5B8DB07098232536F93210B5350A473ABEC4AC6ED14C0F91E069D0208A3E7B805474D48069AF8143530A8002C682F6D2987841EBBF4DD0FE49ADC161EF507C05B705720395F7D2187AB92EA8F02B2B29863DBAD1E4A293E7FF2F9DAB5B522087C756A4A5560A60B1F79C017F85AB5B854A431CB36C8A675BDC8568EE681B62C71F0FE67AE59A56DC61D4731AC415B1D33ED23D52491446AB14AF99314B7B160A39EA56CB2C1BDA78A8396DF2F5382FFAAE8EF66A9152BA6FE38D0A0B8D12FA2B74C1FEF982D69E9F16A3A75EC3FE31AEB7531CB37E0E067232C2C3C3A441C8A8345DD2E538B8BDE88AE750CE6BC8CF8219F401F34671C1933C63FE46E24E422A1FEA8D46B0A59792956ADE770D306D358DDE52B6EE0C437581096370FB85BF38105D939DE745E7B08221E9F8AA9892E4B7EFEE803452748825E1BD338B3DB87E09395970206D97FEF5219387F5C56FF9FB18C1A711FE28FED5C6CBF6A65D4B86480F7A05FC1922272C0AF27CC072ACD598ED7C7B068717CACDF8222CDD114B977B0D1E49FE3EA2EF8624EC73865A6D89ACB77AA0F05BFB3386795686938A98CDAD4930E141B05AB6DC401E89B719DFA8A40C9641561BB38EC2C288FCDD6032C8575298B020DAEEAD80FBCF43645E893F34CC29B7ADD1D815A2F735B15E30A1A3192D00C525E859D3ADEB62CBFEF3D0FF0D5026E0249DEC8DBFCF57300AFD3A40C9838284D2622FE07588BD81B542E6E12CC3FBC2CB7991F55FEE665F9F19BE36E49A4AD541718592F1829FF22DECDA26A8D595F71438F899512E409C24D2B2D679094E9A65C994566166D27BC299C89D5E78713DE0AE04372EE150A93985177E3CA7423CA96D4CA89E6A862EF80223D88887B6075F63130D4E3292EEFE9F850F57D67CD0C57FFE88DEFB61D9A6AFA917550160A1806CC525792899C9BB3B8D4506138233724A159C824DF5164C34405DE662897F601FF533CF70307CF7CDA04C072F0777CF5C31A7F90AEE8C169ED37D15CCC23743F5C77A9A5D12B1C90260DBA9C94A1B98EAE019B09EA2A94D34DAFB8A06856AE14B42483746C52A41A403E5F116DEE001AE45F2DA987CE56CF5CD9BE99EBD0D2AC1231E9BDBE5715A594F277B4BDD6D96C23199B72A1495DFDC1A28EA7178C02F623D4B6E77520AC134870A8BD62C1083110755222C69C685DCAFD8D58B881A72626B46D8CF3F01BB37134B5CF47EAF95C5FB6E0DB5EBE822DD98F2061A7695C2D5BCBAA26926DA9BC55F2FD8B5A009E0F8EE9838D86B6434CCD28E05BE7E1FAE1AE2DEA7DAA1270890C170378B65995D53A7D3DD5076B86A73B3FC7EB73C0C59D2A9B54210458E0ECA8EB3FD1278FC1B8A87395B59A3BF37E4C52BE2A59640D944169B53D109E348B3ADBB62026FDE56E422372DDD77713B546ED46279C13382441F9553A28D55313FA07709A227230120FAC743028D49D58C1989E32A03E58D0F2D87D28663B05ED75F91AE849657ACD9685AA1F528A6F9331E891F7028537F08D86B4F8118D52105F297D1FFD3503AD700C5FC5A1187ACAD5FC6AD2B4EAE36CFB99146D6FFC6B8F8F3B7", + "k": "71E743C143334C36D7078D290BFF42D53E7D775C6DE3FEA876E054CB8042D3F9", + "m": "2429F93D29E48EB6A25ABBA3EE2F3423CDDDD0ECF4B2090C6CA5BF4883F4F3BA", + "reason": "no modification" + }, + { + "tcId": 57, + "deferred": false, + "ek": "FDE545438A542588554452B13FB2092F3113D0DB9541437B6ABB3A02A713871AA479A1B6F5C20F208226A0028B5A680AE845335DBC9B9C3B91E833C8FEECC89F0CCCBE4216949684E094A96A469EA2B09F5EC49A352084CADA99EAC591661A1A2C468CCDCC4C374310E78BB0FA38803B1B1B078C9BF0D9280323067BE76B1BD3912901695FE1C4AF4A1BC38661AF797F9D7B9D8EF091EA3A0A53210C57A706ACE6A33F09083B728F767B51520BBA7BEB364817B820DAA55877CCBA3CBFEDF60E48FC8A0B5BC6D223CF56C3392021A6DE432F4B4A3E58ECBF462376BB62933D6815FD085653D5C3A267C150697BCDACC54E336D7024662BCA1782E531DC339851B33A0778A779544F4B081C05998787916A802436DA982B79164C5A5823D11AA271187E8F90790CE95C1E474E2861960F756F3191267E0158C1150608B5CA7AF09C23579608386822ACB02D559974FC6FED8558CFA6383ED0B5FCA318648699DBB7195F24A000E6A99FF8B4DCD0C3C7B84E59F7CA21979F646B4D8E7A61289605FB027DDD3A10CAB301B9918C365714E1391C42185874980328C04900AA9967627660C6ADA737260D74A1CEA5578A254FF0F203DFD6C832E86EFDB25A08AC5609DBBB469A7125A7C1C8644223AA51EBF9C98DFB64FE530FBF47210BB3C142360EA864AEB447459C6B361757AECFCA733CA2C5EA485B0AC065E2951F145CCA4FB6951579B4A19CB042A3B34419CF29B99A6E579945EC357C7C7BCD7578175BBD51444C1DC9A7AA54574A32623D2C90146B44F2547EE9930282F25447207B03C04EF6AC1294B9BAC6C36AE1666401E318B730020A832ED789199CA8445239B765D48610C6B25DC4C592DA7906C130A6E356C066534388651A0B4F495C39962C9F20DB1224B40AE0642091115BFCA34B5455568E97B0D45B74592905E02BBEB8FC1E2D1C49051242AD000D69009B12A206B988B8CB26A91DBC6305777234FC22142AC85B828D1E8B9E589800214173E858497B964E6DD98997576F5F4B9C68090563F1B004D38643E2872B196B1F607AAB3C22D73324DDD49CE4214F13065405767348A20BC82329EAE2283FB65ED1EB939CF25A7B1762E9686DD3576602073112141ED315300BE6B75F860884E0718C7596FC39172AD9BA4EB837393C49DCA98AD8CC15B849965C017CECDAC67161A7DE6863698C8A64E23A19402E977539E834887954867A29CD2F46B0FBD6240D89141FD8C9ED390099D905C5101B63B30D4D61AF14965FAC227470B38642064412747BDDD2063A942EB0F02843156C1D637D2D8C6C5161CC3A21A69C6220B39CA03BE975B81921C56C140422A8791A9CA2A9AFEC49353B65AC2440C31E2084FACC6F7F23A027A682CAAC402A69675305363BA85947BA5275B6868660B654D91264870FCBE39BD2E68B9048C29732A3A7306AEAEA8A08BB65E5E078105424A3B8803EF9C62CD65D8A65CE6D528A1A818E1BAAA4139CB451F5A20C135F8A231E843531CD700A2E69BFFF186DFF49108562361F353A8E5A23C900043034BA6B9C6CDF2A7C67847F78E0955F7C49EA94785AD3495CF4562EC86F72E22B562382B82B392DBACC1F536C18C20086A879B82C291F45CCB4C24221836383D03997C43EDFE165A1A046405A193E0ACDD08B122AF6925DB303491BCB87DAA36CAAB91197BA64A9A9E3C4A760174129B080FD18339E07ACAF00CAA118A84360AF0333755B869694D07BD108AF4A094C51A9165CCA9ABA36C2E3E43FE4DBBDDF257E08D03B333773D5E051F8101B8EC7B80FD1AF5E9C053FC71C0A1C785954C3AA4C33FFC95AF6CA3B248B5F050AC11B3998C51C8A294544CA4A60DC47529EE1A3849314AAA62A05D3557827AF57FCA1DF9435C4014669B9142DB620AF044C195B6BF046582C52BE435473C74A34CBE751599412B96480678B668B238DF373302076856BA63AB627CB21F3707BA18B999A3A27DBC727EAA8E0497FC3854A4A926905D0968E3886FFFC4F6A2B4273993282635B9BA013B4B8C91E7A47AA624F8262A14C42B4B8A36027573D4790BCF5D386B9181FA0F357230A2185747875970C668142E3673087AA02A5B7AA058C7527B1C0A1C9B05C912D49D1BC8FF629FA77CFEDD1A7F6EA52F9BB49A82B38C022C52C87C346482D42A797BD3A972E19DC352C66A0A315C04CEDAE314DC0D335EEADEA8ED3B75EA17EB388", + "dk": "698C6D273359EFC42931A425DA3B8B9772747190B26204AD5B352807098287B672019B9604337BD50988A1C7AEEA975795E12AF9348A6D180B6F086AA9E92B43F31813B0A357C36CD31504F65285EEE03CBC288C0EC06AEF318622B21839E74A38D33C1FACC773A29BBB0652DFD728B90A613B323D735790DA292ED25403EDF5B2260342D75889732852FF4813F701AD3CE1C9F960C53057C293A09779A88745E901EF744A07E511290277D1467A2A082501DA4C10755E5F2AA8E3560AE33A5D37C77EC0809A1B766484422D00E3422CF19F64DCCC1DA80816E321ADBAB7E7E79B3BF382EB732F86FB771FC1A6B63A6655D161D8B21141034722480C31328AEE1167FCB477626521E833208EA53F95D46B8F2A4D36AB00E34B5E9D324D9C2A6E8AB7752E54CE1AFA9CA5DC461C208F66AB0370C90E96DA0E90340E014BCCC9676094BAB2FD7B831298C4589429E012739989BCEB5B09C8A0AA7F56CE2B680FE0D19D9C8171DA580034184C52E30FF3B712C5D92BA93B9FE8D61C7583227503B3F33A83CB613FCD23C3CA0B4689823380B4037ABA9CF1698F48C50ACEAA2D4BD524BC34BBFF4204C4A359CD3896E3057F9C367F0ED074896B6DE44CC5B492AF3E52A29643B87EC895FB3375E21A48FE5CC0CF3A8810B9ADC950C158F13E29994FDB67C093C09A09A4C4565A21E808916040431250BA91B95D8E42C3DE2A1DB032AF1A3529D1820ECE9A686DC554B86950FA9ABEF1D8B416EA11AAA5984232662F2734609C9DD7112E19B5550F115FA571CAC73078F08B601C649B1A6949875461FBBC416CD951CEA13B8E996DA68382A14664A4920B4E9240562C6893AC8D089BCC4B3B55719C4F9C331F2576985A07C8A0192FA599197C49260CF57B6793ABEF0619258B886975422DE0CFBC20383C3124F74004E3360D988855DA225E810A9D9C910079D80A21B2A806D851E8831581F68D3914C0A0FA9B518B71E387113EC8616592BB71E481928C2E48AB75C9C7A4BFC48ABBEA6DA77A45B4FA5C71BC31F85C902552B517EA36C2E3436A506371C8A827AA721CF57045D21D52597640F1536D518268B65B19F2BE40ACCE482B26671AC51ACA27DEF703497770083611AEB83795EC58C84262EC4A3D78258953D248580CC6D069273D12984BA5BFA359AB25484F79A3B8CE4739D570CA1C6844C8FB525CB764970A72B1381B68394AA6308AD00C96F19A17F7441B544C3C95903A2E9125090C12A8BAC7461CBD8E37025CBAAFA797B70D8896E6E5A60AD332516B3594D06F75A18DF335BFFF876F4B103F8ECBB85547246F226A95285F081337F0719A9EC453D4517B0A2838DF0117EB480039583C27B53A4684138875C4CFD06C7E357F6C836D5797A88323A8D7600979E95025372160A9BFDBD32101012034E64613E198FBD92226A4AD9954795A9227A9777C78F3B8669CC524446D77C8219839AD23B21DEA6486995A029A875D4767A866E51D7E00205FFC5FF43222CE923882D88D72B856FD7C00EA07266FCA70A849A3C9D227021B3BC90B8FB2BBA0173930984847B42B90CBE930DFF08FE4C14D424CBC82FC81DA1B6AE5477D49C30D9E4CC9C651AB6976AF47A18C188388ED0C3163E0B5C9152C82E859DF0C16D3B2478AEC5ECBFA4AFA7560B858142AB48EDB94617C92522CB07C39767CABC55F8BEB00CB48C9ED19497594A161E744E764104347777F5B8168A95F579315394C6F184CAB00CB3B27C19FEE96354E4B62E490572D597455888BCA0259E6F7027AE44F7F95CBF4592B722696102448E7B437CEE5565569B27ED9CCB23A75DD094A98678129272A6C2C27DB5B272B7B9BEADB34CEC5091C405649897665BB633012694F4094C595370E2B91BD8C585817063F556A39FC625EC38D86A5CD6D83CCEA20BA6DC108FBC3C723ABC62092C612F503F8896102E9124DA46BDD00748141891782AD9086876AC920B11C5A6849C67A4B70434236937243D940817C2016A644C53EB7C0F8540C52301D63122CD7E43E98116511D455D3675DBB42944F7CA936F51364D07249200A17A7C83FDA1A2017835C68965EE617DFD5B5C1F026CBD2B79B68A6D76443278972B6914A5937AC8C213292050F0578A0D9219EA00345D17BA529D6B5190381C255B307ABBEEF7025FA36C1FDE545438A542588554452B13FB2092F3113D0DB9541437B6ABB3A02A713871AA479A1B6F5C20F208226A0028B5A680AE845335DBC9B9C3B91E833C8FEECC89F0CCCBE4216949684E094A96A469EA2B09F5EC49A352084CADA99EAC591661A1A2C468CCDCC4C374310E78BB0FA38803B1B1B078C9BF0D9280323067BE76B1BD3912901695FE1C4AF4A1BC38661AF797F9D7B9D8EF091EA3A0A53210C57A706ACE6A33F09083B728F767B51520BBA7BEB364817B820DAA55877CCBA3CBFEDF60E48FC8A0B5BC6D223CF56C3392021A6DE432F4B4A3E58ECBF462376BB62933D6815FD085653D5C3A267C150697BCDACC54E336D7024662BCA1782E531DC339851B33A0778A779544F4B081C05998787916A802436DA982B79164C5A5823D11AA271187E8F90790CE95C1E474E2861960F756F3191267E0158C1150608B5CA7AF09C23579608386822ACB02D559974FC6FED8558CFA6383ED0B5FCA318648699DBB7195F24A000E6A99FF8B4DCD0C3C7B84E59F7CA21979F646B4D8E7A61289605FB027DDD3A10CAB301B9918C365714E1391C42185874980328C04900AA9967627660C6ADA737260D74A1CEA5578A254FF0F203DFD6C832E86EFDB25A08AC5609DBBB469A7125A7C1C8644223AA51EBF9C98DFB64FE530FBF47210BB3C142360EA864AEB447459C6B361757AECFCA733CA2C5EA485B0AC065E2951F145CCA4FB6951579B4A19CB042A3B34419CF29B99A6E579945EC357C7C7BCD7578175BBD51444C1DC9A7AA54574A32623D2C90146B44F2547EE9930282F25447207B03C04EF6AC1294B9BAC6C36AE1666401E318B730020A832ED789199CA8445239B765D48610C6B25DC4C592DA7906C130A6E356C066534388651A0B4F495C39962C9F20DB1224B40AE0642091115BFCA34B5455568E97B0D45B74592905E02BBEB8FC1E2D1C49051242AD000D69009B12A206B988B8CB26A91DBC6305777234FC22142AC85B828D1E8B9E589800214173E858497B964E6DD98997576F5F4B9C68090563F1B004D38643E2872B196B1F607AAB3C22D73324DDD49CE4214F13065405767348A20BC82329EAE2283FB65ED1EB939CF25A7B1762E9686DD3576602073112141ED315300BE6B75F860884E0718C7596FC39172AD9BA4EB837393C49DCA98AD8CC15B849965C017CECDAC67161A7DE6863698C8A64E23A19402E977539E834887954867A29CD2F46B0FBD6240D89141FD8C9ED390099D905C5101B63B30D4D61AF14965FAC227470B38642064412747BDDD2063A942EB0F02843156C1D637D2D8C6C5161CC3A21A69C6220B39CA03BE975B81921C56C140422A8791A9CA2A9AFEC49353B65AC2440C31E2084FACC6F7F23A027A682CAAC402A69675305363BA85947BA5275B6868660B654D91264870FCBE39BD2E68B9048C29732A3A7306AEAEA8A08BB65E5E078105424A3B8803EF9C62CD65D8A65CE6D528A1A818E1BAAA4139CB451F5A20C135F8A231E843531CD700A2E69BFFF186DFF49108562361F353A8E5A23C900043034BA6B9C6CDF2A7C67847F78E0955F7C49EA94785AD3495CF4562EC86F72E22B562382B82B392DBACC1F536C18C20086A879B82C291F45CCB4C24221836383D03997C43EDFE165A1A046405A193E0ACDD08B122AF6925DB303491BCB87DAA36CAAB91197BA64A9A9E3C4A760174129B080FD18339E07ACAF00CAA118A84360AF0333755B869694D07BD108AF4A094C51A9165CCA9ABA36C2E3E43FE4DBBDDF257E08D03B333773D5E051F8101B8EC7B80FD1AF5E9C053FC71C0A1C785954C3AA4C33FFC95AF6CA3B248B5F050AC11B3998C51C8A294544CA4A60DC47529EE1A3849314AAA62A05D3557827AF57FCA1DF9435C4014669B9142DB620AF044C195B6BF046582C52BE435473C74A34CBE751599412B96480678B668B238DF373302076856BA63AB627CB21F3707BA18B999A3A27DBC727EAA8E0497FC3854A4A926905D0968E3886FFFC4F6A2B4273993282635B9BA013B4B8C91E7A47AA624F8262A14C42B4B8A36027573D4790BCF5D386B9181FA0F357230A2185747875970C668142E3673087AA02A5B7AA058C7527B1C0A1C9B05C912D49D1BC8FF629FA77CFEDD1A7F6EA52F9BB49A82B38C022C52C87C346482D42A797BD3A972E19DC352C66A0A315C04CEDAE314DC0D335EEADEA8ED3B75EA17EB3882A9072AC6B041BA7624CF3158048EE475506482D536D15DBEC594818AB0E91025AB34FAEA7275E5D6C8EE1104CB19F4B1C14B6C51ADB118163C6A48540E1C5D2", + "c": "4CBA673C63D21AF9EF1A30F8AE10628CA81926A8C0799D276BE363A182F64C312CA1AE996865034FB1F2F4FFAB6D132B141C9CC01FE4BA6B16B8FA1F6F59D140B89CE159239BCEDA3E93EBF6D858D647385392563BCC1B421505F29D0C74FC6028AC536DF5D8693C6E4BD36A9AE85737B1C14632DCB11896B50775A75C8A334D334B7983D6778D1BB2452090736CD9B488025AAA2AADC091ADEF4705BEE3BA81A404772916AD78B4CE2E2EFA0C54F77FCB4AF0AB62720D52C9B181F80BD6A71B65456BB8A6EBC4203C8D224B6B8CD544559734A9E51270D06680240E48E72F6A294F29CE05C7B9226DB34E2883A065E6FB742FD38A00DCA0938D0DB500A012E84903425EC1680A71BD7688F26DDCAD3C8368C2B384BDF407E83C5441B427CACB25FEF42F6A8C350E67DEDC9BFA7007B28F6742028268358981D72C07C455630D8B845D61F77F0129CFD4DB594BDC4BE54D958E8A3D8B6A9A4DE77BB66B393DA7B823F5D3C25C5EACCFA258A9F7D9E05038E7F8CB06A32886296FAD4B7822DC2249B1809E5244716A552462C8F1E21D87A30703A3000C6D3AA082BDA96C441F65014AC10C74F708AB8BD83E5CF6BF42124746FBB44F5F65A9D564DB514AC49D43335A6D8677A30A54F673BEE43784B2596346F49073EA27BF4C2AEA4CD790A5F24E772F69F591129CF33CBCF5D012384230AD91D8603D3A54EEDF75EBB579CF4027F1E40792F0FB2769EA83494CBAA6D8732C0ACF474AA422DF63B8BB1D19AA37078C690E5C44B495C87AADFFEEBDF0FCCD969A22E151978AE67E9B7D950BDDB18D9014536E91B1FDA68F41394653E4A066EF8AC92D61CA56CA3B504A6FFD5993785A958A3E2890D40D58CE12790CA35AFCAD8569B75DE5E033B6813B6E85F1837C5F62BD61C3E94132ADE97F2F8F3FDA5A54A958865BA898A8A67C38E61C8625C563A5EE7F6D059E22FF626976332D0E0A4F7A240434999F16BB194FC77B21DD09A47EB819B1D5365553E8A86A09A83BFC612BB38618C84132C0E7A8212C5D2327F5BB7BBB5C55DE72E013A198CD806239112D0ECFCD05092DDFC34A9453EAAE2EA59061734C4A480CA346652025BDD35F49FEDE97B301E3AE6246EF54C298F26968D44F144958CF7094520473198C6A654B4105D2F8CE350C05359BFF40C15D61B633C6F963F3EF5D37FCE3383EBB14F3FC04150B4D6FF34A16A29AE0D38A802EE52B0585D9CE8BB8D3F27BA43A577673AC96FF063AD37FF4081A67BEBF1FAB1AFF168A0DE3B0220249765EF67481C7C30ED4A1FDE1BB62F10557034A6226B6B64892D4443BD8965D1A632F3EC8D58A82FA39FF13B43A02A82D6A1ED0FA651342192B4B4E799A398914C49FC5C71A7B8798ACD44871859E3D8CE777833D0295A9782EC48334D098D10EEBD198CF06B0795AD505FE0342D5AF7E4E99EE34BF0C70AAA2E4978419DEDBFD6EFD30E985E6539DC139DC2D96E28BE541642645F54781EB682BAEF49C109E0665F4928E9BDA891AB87D872BCD28B683F13336419010BF53DB4349873544331823BAF9789DDDD5BCC7831E2C10F50C6E33632C9D4C47ECACFC664D7D683B34934BA03AAA4A9FD1236C4F97A1EFFBE3B183268308BE20A781DD22D0A3BDFB450A102988525832F03DAC2A9441DEAF2F3C5DBE47060930EF9687008D7B58AA81FB79F08DB833D7F2C3E880B4F621AC7FC6601849C7CED42166D31A530619BB9D8CCFF269C20EEF4AD814C42B3BD2B35C4100DA58C8EFE5B46C2957673ECBE586C95163ABD5D9F2ACE64059218685F369B3815F01D693098B7EF8E7F89F202F8AE76594EA7A66D5F4B74F80CE0FC274E647B26CD1E63E88FF27AE783648DFA85D5DD56863000F03D8D215E21EF11A1C2E8E57D5CF770D0B7AE22557F458F3ABAAF5B9BE1408E9CF4823D7FE129472B9E4B89394DE4907F85F94A3A42299E432BCA661BE17D23B6B61A7F20630B0ACA4529AB8B03FBDABA1625D2D49E724BF7748AF96FD3FF11915A84408BF80C70FC0381E39016CFC8739B80F7C9E2DEF0C53383557E15FDE9BB31FF367C2625542433388F19CF70B568D64E958FD33FAB2DCAB72D4778E2F094D94A62DA941D13B56BC6CFEE6D1C3D81A82DA67344994FA405C31A90B9EFCAA8C7242F07BE73B3AD9ADE3CC4EB73017FD6D7AB37F3B34BCF1D2B291EFE9D4F8C4C33952C479AA0AA7B824E3B895F8B954", + "k": "91C5D5F6016A421C4C5017CD8E805008533F67FF7037E8C62FB52A2D6657EE5E", + "m": "B65043CD3672CF9AE2CACC94F923CEF63B5127ABC63C2A5AE6C064B8C6FE7C57", + "reason": "no modification" + }, + { + "tcId": 58, + "deferred": false, + "ek": "E7104DFD284FC4B28110B06282BA8EB859CD60F8934CBA78B1F1653CD4A9613B4BCD5C32A3B30EF863A448D3A17FFC5908438800C5CE12475F3D5445761CCB25541FAE3653A8B8776256C7F5384481772ED0E3C4E512988E605E1C75A85606AA574442888B87F0A77C08824FDFF2B5FDEA4834112BF77C011F7855AA065ADEC66F505A72EE45300E2C9B18588E2F6B57B1C2B26F491166AA9D89D9BC2ED26DD311A81E4232FCC720CA8A788D5A00DB696763256F58B2B68BC32653C71F84088383473F19A76ADE5CB5B6BB466561AE7294770F9148E9E44B2FA1A23B1B99CEC1327F60A002728F21CB9D25AA79F526CCB4EC1531864AA550C72336509FB3061717BADFB2682EB59053333CEC75BD6E244F002D0BC2B1C8008737AB62CD42D2BDF9CA2FECE31DCF836264F84F76569A16046761885C163CCCE986122A11C8911C9257B88FA2CB792BE55FC14048BB995F11606E4C3C82B3113D99B451686ABB1F129E22D63EB14C6C3EC2479BD0243F57876175B138BB0D42313A28C67F1134733F76977BA87B5A11523953947B684282905F2AE90F5BE1CFB0088539313A9FE2A3AC9729C2FB5FBCF492C5ACC90A74C934B1A29AC19D2E20CE74436742A1415A9A0A4CE3756C199AF7593A7685C02F19768C6A1F4859B04B0186C63580916915053404054929F8B417F6A3919882C8D31B220F1817DCE08267DB0EAF61301C2844CA4556F813279D122C43A8820560A09A18AE2807163547B9A3E22F83E14AC4DC3FE69A25FD5C2CACB6A67905C9C754565EB5B17AF089C4653302AA830375B9CF0BB6D43904DD8277D50BBF4D43ADE05918ECFA74DD432CFBD829C4F9838DD76EB75813DCF397E3507FC9C6BD69C2B220644D3EB8839769CFCED608F98874EBAC4367A11274317297DBB424B95B9062ACB4C83CC5E879E6688447F26C0D2BA3763406318BCDA3228CEB0641C7250DAC193A8713744A6ABE5F6C106DC4049CDB49FB946DDB7A08D2D73556648F4CB82E2AE989ED61677B805F3A61344A14A2F3DC3964A90E4B83CC22AA8E7CD532BAB55880F212751C4CFB93AC14F564AFAA723FF6B31990A88DD32A557AA86EC2ABC114745C8038F4C1C924258B5BF02134605923E865539425F10424319131B0CB17D72C2981A944FCE3CD85A2509E93BE3AB5A65E53380772A56D74945D60C57A112FD87A2EB7989CC14A973CD05590495122811A6D8992C0064C77A78C7E390C43FB695726B7582C96C50A8EC5B4081CAAB6E9B64870166326A8ADA4731030290CD444B9E28149E06BACC7A79C5E7B24BAC292B7F92C7AD720F957013E1B118B3A40095C705DB33DE334ADD011CF3DCCBACCABA3B12A6FB5962E01C7C8D83912D9F98ACF8B1BA073B25AEA0C177074E7EB08CFF3CC7D7709E723340BCC00B014A0B313008DE52533B72393D70B3EC767A8B6CBAB61B8B7A9C86B263A1528A9FE366D60104C0D320CEFB76A688B407C0742F8BA4AB8007A3651C0F26B81E92746DB701837B575AB00A6B6D56FC5C12C956685ED0AC3F0C6A5870935298640E5070A8B74AD540CBCF273705C68115A828F72B09C83551714D67455EB46DC0BC14145CC38F5C1DF675A3677ADD28C69F0D462B1F1A0ACE8AA30B877382280F903B7DF9503E4C5048F4368B2A58565552EFB106E9AACC75562C31E3A3FE7790EC9269987C627EFF798A9A0484F215A3968525A0915C4B4AA7A8170EFB1466936A8B8440DAD499CB2F94373CC91F62673B59A90C728A818247513445D5AE25D85AAAB0036135DB5BD74D106AC557E0E8754D1E071B5B62FFF7575847B47905BBDCD5958A7A86852C34DD01286CBD50F0CA4628E31C5EBA531DBC02C9DE1BCD82C218C2CCA87A42A28D98ACFD1103F80AA9073C127381B4584C923492960537A28B868F214251E328FF44CC984972949003916B76D89D472B97013A52141FBAB0939B03D8D57364A387FFFB4A59D7B5D586680D7F54DC27AA7BAC39580103C74621E6D8970176AB2965ACBF453A7217A3C21769449E9AAE851090B52390642C467C9A233501110F059EF4A1A02BB06CBE1084A08C85AEA6237DCA55E2698D177716E662E2DC711D475C2EC9745BB061A90432C6463BA827BC32E0B0FA6B015324C9B574078AD823ECAB9010D0BC640C0A20E17317B2A30AE8AAC4C94695EAFDEB2BDD14D78D1CA07CEB411455C0EF10D23FB50CA", + "dk": "1A47BE10A1273C9312ECD31E36786BF2C9A13382CE6919AB8F4C33A92A5E4C5A862CF22E39F34793A4BEA35B4CAC858A32B79EF3C56A6C1C7E9205A22F0CAF77936722424CB6B207B15484BD602239D66AB2D5A0C342AEAEC83C95E42BD6D1817A1AC7C50A189F4248A9EAAB81B53EE952C9897178C2E92BBBA7B84A7348D8C504CECCA2261A4F72EC9EECD82E1329A55D5A64B8743F08999B78B88D4C60C0FB1387398A2323946D7A071B6898C8BA3250734933764C31A91782F2050CB3597B0FC63C280C576298C062D0968539C740D6B89A6A28D20871F8E2C35BDB86EE8B747CA81B83D856407B7C0A604AB1F753D38844DD890209B337F2770883B82FD44808356B24A36195D23C88D5F5857F4624ACD31211B695F0638C6AB870856C1277EC24C525A37C39259A99707256BCE0DC9F2B9606AC93A0146A5B5BE41B22E63382B56F7203733682CA87EC80F8C58F4294167F4772F0E83176BCBA554545EAF711B02A7DB7B896D44BB0F47BC46659A8305329D82172A1DB4C72955839D9752277C3401A7D1800088A768F473B80B7C746AACC8205BB798E905C1E1008F454AA5363B1F8E9CF3CCA72AFE1703C03A585D66C528BC42A311E0479CAE4763D789C583A56A3F6836E73A73BBF01073703AC90254CE50B27560842B3FBBF5DAA4C6DA37B9858BC7F2054A596348187BB99646A7933234721B1A3FA65564A5E3525276C5A7D68960FBC7C095AD403EA0C0380E68B4A5083F0527D3C563313B21A2816446A4AAFB32B52D8A60CDFF26281412353D02205868F9452BF50E0440049630C022CCF05AE6A7289747C573062560A3316C895586994CC7D2C4FCBEA0974C5845400C0C9218BA8BA2FBFB8C93C025AFB6C341FB2B44DDC6046B99F2CA2A269F931B76C0BB89BB424C9CDFE54136F716C8613C461B92297429EB471AE1C47AB4C3199281039D41A3B67908F3586997C8A9980D9145BBA2A098524461184AF05576BE349A614862310AC68788A0F06C418E255FE6B63F03C99E30699DBD77378E02AACF6C2021ACE42F69F42A5716CC37C64617FA7C68721BB8A3CEC3609BB8799422074D143E676599154B186554D2D5C9EA57B3EA3917BEC6C61C5A351A9908471B94856758964B77EB7D7C2CB1A4DB3000D4A87B9448686DF075031263EE5C0253668AF61C8259CD33E1E9C1FDAB4B4B17012EF831BE6C3BABC8463B3084FE2524B3227829D24BA38F88D850B21CC06638F258378D15F73D4C6B3D1BA498959E3A9C9257C8DFB2624F99A15CB09B1CB7469F61421B929A5C07ACFD781A8F4069C446760E7ACABA6E2B4CFC89553969EC1B21A41432965A8BE9E5A73CD402900472CB184812E1B5B2136149E4083D17AAF728242B470209C9C466AA3823A9A7B1C35A36F062BB670573EA059BEE9A2F1E4612AAC19B7A3337C3AB647318A88A22226F606FD645E324971D5D58E89A0838B00553A14449679A01149298294B9FB641B08674BE4615DCE174CEB019982D75996220F33E2393D8397FFF6217AF3452CDA8D3820AE291839B2280BEFC2179B344340777009378E56FBB90D934F04809C3E0A8512AC69D087BF669214A7125337C15CECC2165FB7C620D06CE422A9E5EB17D5983AC0509BF598AF45428BAAB16546480670DA4042F93FFD147E4418254109B8E0D97260429E5AD2553A2C86E6E7294764943CF14014B57B8A5113B2F02E54220981177BA1D4720A0556AC211B44509F0F913407560961E0AA084A0AE2C15CFA7CA77D9CB8CB683400CC72FB39AC7A758C0C21013CE6046CE2950762704BB0050D43083D85751AA5A141771DD5E9B4E1785E83C2B5997758B6FC3628DC43EFF472C73C4C15100BAE570513AA532296405C5936847976AEDA9F5B0AA704E35EFFE533840599EFC74F3A1C587C2640F2509F39FA14C0630F8393C96AB864EBC0B4996468D08A5515A3B4D71856AC31BA1B141D36E0794A6633167A471E199C7694B105230E0D11268E809029F72CB0C798F889CBF4F79418505DD5E9112F775C77D6C75E089DEE49AB0B685B837ABB7391B6965A432DD6CBA0670871F601AC186FF56C8C40169238E71BCD866546603F59B0C3D510371DD53923C1C92EE71037C47A8EF830132519F1666BC574AD1A74661A1C46DBA709E317974829CEE7104DFD284FC4B28110B06282BA8EB859CD60F8934CBA78B1F1653CD4A9613B4BCD5C32A3B30EF863A448D3A17FFC5908438800C5CE12475F3D5445761CCB25541FAE3653A8B8776256C7F5384481772ED0E3C4E512988E605E1C75A85606AA574442888B87F0A77C08824FDFF2B5FDEA4834112BF77C011F7855AA065ADEC66F505A72EE45300E2C9B18588E2F6B57B1C2B26F491166AA9D89D9BC2ED26DD311A81E4232FCC720CA8A788D5A00DB696763256F58B2B68BC32653C71F84088383473F19A76ADE5CB5B6BB466561AE7294770F9148E9E44B2FA1A23B1B99CEC1327F60A002728F21CB9D25AA79F526CCB4EC1531864AA550C72336509FB3061717BADFB2682EB59053333CEC75BD6E244F002D0BC2B1C8008737AB62CD42D2BDF9CA2FECE31DCF836264F84F76569A16046761885C163CCCE986122A11C8911C9257B88FA2CB792BE55FC14048BB995F11606E4C3C82B3113D99B451686ABB1F129E22D63EB14C6C3EC2479BD0243F57876175B138BB0D42313A28C67F1134733F76977BA87B5A11523953947B684282905F2AE90F5BE1CFB0088539313A9FE2A3AC9729C2FB5FBCF492C5ACC90A74C934B1A29AC19D2E20CE74436742A1415A9A0A4CE3756C199AF7593A7685C02F19768C6A1F4859B04B0186C63580916915053404054929F8B417F6A3919882C8D31B220F1817DCE08267DB0EAF61301C2844CA4556F813279D122C43A8820560A09A18AE2807163547B9A3E22F83E14AC4DC3FE69A25FD5C2CACB6A67905C9C754565EB5B17AF089C4653302AA830375B9CF0BB6D43904DD8277D50BBF4D43ADE05918ECFA74DD432CFBD829C4F9838DD76EB75813DCF397E3507FC9C6BD69C2B220644D3EB8839769CFCED608F98874EBAC4367A11274317297DBB424B95B9062ACB4C83CC5E879E6688447F26C0D2BA3763406318BCDA3228CEB0641C7250DAC193A8713744A6ABE5F6C106DC4049CDB49FB946DDB7A08D2D73556648F4CB82E2AE989ED61677B805F3A61344A14A2F3DC3964A90E4B83CC22AA8E7CD532BAB55880F212751C4CFB93AC14F564AFAA723FF6B31990A88DD32A557AA86EC2ABC114745C8038F4C1C924258B5BF02134605923E865539425F10424319131B0CB17D72C2981A944FCE3CD85A2509E93BE3AB5A65E53380772A56D74945D60C57A112FD87A2EB7989CC14A973CD05590495122811A6D8992C0064C77A78C7E390C43FB695726B7582C96C50A8EC5B4081CAAB6E9B64870166326A8ADA4731030290CD444B9E28149E06BACC7A79C5E7B24BAC292B7F92C7AD720F957013E1B118B3A40095C705DB33DE334ADD011CF3DCCBACCABA3B12A6FB5962E01C7C8D83912D9F98ACF8B1BA073B25AEA0C177074E7EB08CFF3CC7D7709E723340BCC00B014A0B313008DE52533B72393D70B3EC767A8B6CBAB61B8B7A9C86B263A1528A9FE366D60104C0D320CEFB76A688B407C0742F8BA4AB8007A3651C0F26B81E92746DB701837B575AB00A6B6D56FC5C12C956685ED0AC3F0C6A5870935298640E5070A8B74AD540CBCF273705C68115A828F72B09C83551714D67455EB46DC0BC14145CC38F5C1DF675A3677ADD28C69F0D462B1F1A0ACE8AA30B877382280F903B7DF9503E4C5048F4368B2A58565552EFB106E9AACC75562C31E3A3FE7790EC9269987C627EFF798A9A0484F215A3968525A0915C4B4AA7A8170EFB1466936A8B8440DAD499CB2F94373CC91F62673B59A90C728A818247513445D5AE25D85AAAB0036135DB5BD74D106AC557E0E8754D1E071B5B62FFF7575847B47905BBDCD5958A7A86852C34DD01286CBD50F0CA4628E31C5EBA531DBC02C9DE1BCD82C218C2CCA87A42A28D98ACFD1103F80AA9073C127381B4584C923492960537A28B868F214251E328FF44CC984972949003916B76D89D472B97013A52141FBAB0939B03D8D57364A387FFFB4A59D7B5D586680D7F54DC27AA7BAC39580103C74621E6D8970176AB2965ACBF453A7217A3C21769449E9AAE851090B52390642C467C9A233501110F059EF4A1A02BB06CBE1084A08C85AEA6237DCA55E2698D177716E662E2DC711D475C2EC9745BB061A90432C6463BA827BC32E0B0FA6B015324C9B574078AD823ECAB9010D0BC640C0A20E17317B2A30AE8AAC4C94695EAFDEB2BDD14D78D1CA07CEB411455C0EF10D23FB50CA524A8A240ABCAF9BEA0AEAA9C7EFC5BDD617D02E395BA073E0E6F8E621D501F698174C242417B71B8FE5465BADDC9DED85C393381CD5F07E2B05B9437BA39448", + "c": "E34FC9C40C386D57D2086BB28B5907228054405BBA248DE609729521BCE8DFB4A24E4742B780449CD66C32D969D8325550FD1545E5008956F040E1CA31358B79193044F77A0AE406A36D28C53A50678570A880A5FD4547BD7C805F9C4129FBA6B0671BD997F696426AADC8BA7682844D43089E33C622AF15BFFFEA5F622B65E74EA912CFE0C7B6EA3693E30DE4DE61AEB0D19C42B94CD84D72016355CAAC4C450BB4B8789A0BC67BC1785DBE9EF751E516110957E5CE8B03B59557343424472888666D8BDCA40A2700711F45C398CD92D1969CAF226EA229D1FD0666D831F92081A7A4C0B3033CB7824339E15C2E92AF53420F482E8597D6A47F1DB85C2680424E4E6B465E844259DEDC4C8D7C36AEBABA1BA872975C0B4D09D3881161734BD52100CFC3EA63119DF2CB1F43464584FC689098798CBF89057E69E480FE292DBF4663CD797094E746C6A99A27B88A7ADA2960117A7649B98F5CEA23B98952C77F5101061BACBD974256EF9F9CBB47DAC1978D31F257A1FF7E3C7291BCF3C466F815C019E2752DCD250A73C90F361C5A183A7F98FD9ED2E26D8BC3D3448267857E5C3744425F89941F89FB1D0433B107198E1583BC1AC83D903C40D4A357BE69CD3E840075CD315794CBE003D3C4E7FD04650C69F86DDC7C375EFA202AE129B1283C65F9E251F94000BCBA61AA0231A230EF0224BD6D955B06D2F3E2C978C0A9D48E68EC967C886B39CEB2B0C538551B89E6C71E750480E6DD1249658AB6C8835EFFE9593A178F619DE6BA506C2805E96B2C6D52584FBB78036D35514945AC008DAE2CBA6A1B6845320B3810C66432D628B01D99241FB70FFAA6842330D1A4361619025F24B3EA7F95C9892B95FC60F84B6230FEE12FA4638339792B225F04798E574A95209ECE2C4BB1C0C1A021820C5C6169095FA425693948D3A6204362B855D58B8B8942ED05DEAC54FF776F7F6296EE3730EE0A48B143833D7C1D30AA9266202B66928D07DB9D22E893BF96AE5C84823AF84ED4C32790A959F5C282EA6D8F4488A587EB3EAA1A3A79DDC74AF8FD8F093E2C43016E9954733FF50A37DF4CCC3DECDC2C433BA22C6A400399DE7567E028758D0AE28ADAC787109A94C75B428D38757D3E14D4D4F332CA1B12B5ED2D8526F89BFAEE860ADAF3A7A68B2E18F1099B95351D13B36FBF624CF3493FDC5AF9E6E2A42F66760A79D5BC3778DA0673AC2D374FB101F4A54133E4606F5BDA0888E722FC8D721FEA7FC02F05C649BDB7C1B5B0598BCDEB6B4CEDB58EEFE2C85CB732A2F17B3C74C6893D051BA1806963FB75B3F4BB54D03B208534BD49709E7D3FA752F71936926B03C3B2409717D6F6670B4C448FA0BAE47144A90E175524CEE0595C9D1C2EFBB34197BF4095E4255AD1DA5D74C854C03934AAC68C88629219563AAF017732BBA45049F4011056AE8F624D4D2A7B53A1DEE0DAABAC0E0D9E6D1B7B910CD8C70FA5BD58A078BD3821ABDDA5520D8C3389D268171A433ACE1E247994BB54D78B06BFDC9C71587D9B5EF9C202E15A2977AE436D3E2401D78E6E63E74C1056CA5EFC62D978AB473E8AE49BBF81ED62670BC860909F294984453930E53733DD31383D804723848CF0DEA6407737EC575D6C9F11F80068855ADB886D5FF956E70CB09F86D5D5548FA33CA645E3ACE04DF2F8CB4F6FB283CD6274188C90C6A8DF1DE37EF648B73CC33ACD56C914D2F083CF7E3063EBA33C58F0E261E8F0CDFA45DBACD99CF7290FA5F8EACC9869CB88E4ABF16EF483EDF5792193BE06347ABF719439E0AD27CCF613B688201585730110FBD2584348200A110C4CA81FB2CFAB41505B345577E97A994FEA7363B3B0CBEE900CDCF41A4EA067BE2451214F878163789AE67A49739EB09F6E8B40F6DD1B0D8EE039CB0157D0DB71158463CE866145A62DA83E7D3CD10C99153307ECA66B1B076686FF5B023F532F58B2781E44F8CBEA51C07FEAE217CE1E202A4CF8662C6D848FDF432AF34C6662F43562D5D81374C72A9673B379D0DD2CCE47C6224CE16899172DE2F26E039D82C9DB631E8AF85E326424C299BEB570C943F8ABC251CF1AC2481BE4E7B2B8CA0247195730002E69748E6BB8A7E1CB22AEB7D74A651BACE2856D114CCC994D3B833AEFE17D7015D450568E776789D173485D389C136DAE32459FFB88EC8A46C102672F75DB509AC6A486D68BD9780B76B2FDF34807", + "k": "D82B00EC3ECC8818741F6CBFFBC99350E84EE4D4A104214774525D8B78C93CC5", + "m": "6C8C075658F4257D42010EDFB1D7EA290D3344EE6E4C43DA799366985AD52243", + "reason": "no modification" + }, + { + "tcId": 59, + "deferred": false, + "ek": "F1E27E473692D70B178B466FB72CABA716C2468B308C0689615A0077215741D70A633734F0140F4479BAC081370D3565D24A4D0D7AA189F1C28792BAFFE9928436B9C0215FC655253D645B3B84C237212A7868131AA623DCD8BC2ED65A2E082C4EE29A978B0C458C9E5BD656ADFC68BF64291C387886493D12825B8363932AD17B8752BB49B63D074A508AB3CDB7341ACDC5AB76B8C5F9C93FD4EB74CD9891BAA467DDB28E1733A4260A2A4D496A3F705E318A042AAC818E408DC7A9BA20520E3A4CA237C1C581598D839B67822CAEE8C04E7BA6219ABB23D9455917B84CC5C94BF8594A2D1127601BC3E76B54155B1AD8C5754D13B564906E3688C3DCB9B963B7295310341EB0A36917919D289C2A1B001CC4360285A40DE87978FC532A242422829BF8079D71F347EDC072B9884A5D26C84E07B72E529DA1FCC8E57C1C2BC30685D12635B3A136755A70224D79FA7AB1124A69701DFF4AB135508014FB4BCF044218D4918790455923039AF9591087A5ACAC37363097C41B4153D375C933C488C216C5CC1AC56134F9B3567519CA21496A4CA06AFB84C0DC2743673AA94B15867EEC0945398376DC6981C6A9BFBA78D9950E27E16D3852A63CB08BDCE1C99172B4181654BF5A90496C764B6B96A25331E84162F902009BB4B76D8BC41C08AB7FA8B1C4657AB51CAD6FCC324E4BC70979AEE6125F2BF916FE8C3F4F5A72A695A6F8E34084728B0FF59CE1FB5161D8AF07CAB498D23475869F746563DAFB49B64103EAE0CE8A17BFDF1853E743262593C327608B27614F32C1ADCCC9B638029F7F9377B302248017747AB5553833ADE94A3846D309D5BB9872C89AC4E7831D9A3A3FDA26A42747E96AA6EE375FD407585E964CC4D6821323C7874986A1192FC0C62099A764A4554B8D89B9D9585A339072E9D677ED3475181197EA28BF6D84A3DE367D7529AE481133D1618007D5832E0A13B7028BCF5CAA36F4861DD22DAA497167E171CAF912B9FC8056016520ACCE1F68397246097A5755F8462FAE3413408264BDD915BB253A6229C26B14426F439D9AB79C39B11A7F51B9376A300C7530744B754713A50D71BDC299B9C0C7B266CC41F31AB512D0BCF5AC9BEE85BEA109734E7861646A7160BC3A27AA5CA3F87128468F3266B2B156210AF79D03890386A9AC0CB71BA3B41937960E575494F60B0704960518399199CA227D48B99ABC8E85C1795DA67C0D331B40CA8E448A934A38CB24D0730E181A7B30366335958D5993385871DE69C97B22A1DDC6BE8C5242BFD93073893D2B498627B76B6D39ACD7405B64C16E60E190CF45B5EB12735572AEF8F99E37CC3C1492979D3718BD363EABD56E1E416ADF9CB106F3540ECB4ABB052D57C728A558AB52FC4FB9C078374919F29558481C3ACB782959E2C41AC05B8701217E7BBF945B970298A694FCB0E12490A6C5665E267A8AA1A5F060CC0A08093E816EF9644720024FD0ABC5C30C39EA095FC5426E732C2490B288FB38AA6A3517D16BAE8F38BFB091BD70260BE1D80B2694B3651316484C1E97B714A67A0416179F2C582E25F770EDE422453607ACA79C1EF217C2418840609FEDF914D083595C10CC4CA70D40A8BAC5470DFE4638DD86A03DD428CC305569963CF620931B40245FF3098DB6C6A1870D5D7B838C976D0D0B462F441B2D79BED3A488697A191C20C0A8281CA8A39D61E69A0767CE753A02EE8987414AA3BB99BAB032CF451BAC1075162CD1097B00AF6A4A82F8112F28861BF0A6AA22733DB462BD15F95A211161ABC0C5B5330FE4D63854F3C0F074C077D06AC2839F06913FBAF33F7F91A948A19D01D6110AE54025CA068D1B0D7CC66A6EE0BA83E377FD2313EF44C87A58354D841B0158C8010B6EEC2898A9A0778072149452C2B6A628256C257FC224C0B767DCB3710071A71B43015D994ADCACCBF7B3A234C11FB2B56E75E4154DBB473978BC25758EEDB5319AECCEEF44AD82C3584F8378437763C3055C4A84AB71815EE5E360AE0A363286936486C69976AF602885769C1CBE21229B9C350562AAD4A91BE145AB3B090B9031175EF96CD275CDC68444BF890CAC56241159C55A474647A4257A978470BC97D28549F21590EAEC25D9603ECB5909D375CAA56B076DE917B8C7251C92B34563BB56AA6C3749113A837B5F6B5496259F5EB94195E2AADEDA453309F91EC2AACB59E01FBAB4B8F8", + "dk": "01105ACEB10675548E2BCB6C4FA56A7B70C0824039D35A5B9BE38DA1187274C8135C24692024A44430BE5D0834CE64964F7CC0D2A8C86A6A64AFA8CA4F2BAEE347C05374B6A58A764D493F1F765122575A31AB87C5278B6E94C8704880795462E3E16177B1C3ED4B4432194148089B5218777BB3927B4650CE44160C8ACDC7153802A266612C9102289A73606498F3A6F79001E37330C5A848908C34C0C8559E056537C25309B10FC4377DDF305167D41714A70CAB02133C500627664D84359173DCA053922D874C927C1C0BF86468730254A9CB279DBB19EE0929E9776A20E3574C4403DAB3344DE865312B2CF49301DFF86BE06481C3EA9F7969AC5AD777CB9C8FC887B2782885E8F97B13728EDE4661AF68CA9CE80208763831F9385D5547DDC81ECE830716557242072039C469E9876247C53D1847955795414A6946FDFC6786F9389CF09EFC021B7B2796B4A2A48C0A3DCBBB8256507CC0CB7FDE45B87B7C2DCC8C9210279E84DA022AE65434F139A70629D15882A1B05ACB847049E9B72E1CB6AA7647F09447EB47BB052B9D8C92850E72ABEFD734BFB55DA941905B99228EC17CA66BA82C541D3D669BFC3AA05AE6966E4B67EEDC3468A632DEA41C30EA5D0F943B53D828CE6879699933AC6C15D85A6D78DA3F84D744455784642B520DC4C40951AC26725E3723BB48A75BA247B5A4EC5C5E832DCB68861F4A6A6F8CBF13719A834AA2F6C9B9A99A7A64785F65D4768EB01A2C5B719FEC6418BC98428C321C40B7AB923C0AB107F59B5AD0EC37FD82850F64782293C1CD0700C062AAC0752CA91CCF5409147F9526099997AE622945A91BD4CB32B61569C1E1347766935B3C76D67B4D704B5D9E362CCA28833DFA1A089C2C6A2380E63C812F7ABC9BCC6B53380E6B9943009A1CB4325A2D529EE5E6A428BC1F0F190BD9E20C4EB761F8B6C6B5916371FBCEAC171E2E976927D8401218623E3C403B072273EB2D68F78CEEC20DBB89669E56151B83775489CC6EB9C11903A81A001FB6408F0AA2AED1B576C16B2AD71C4293832DADE8769833A7FE517F332B9AA9394D915838F8A62A7ED850DFB7AD82D94517087B4F4C8B4314A6E0E0A49CA96FAD929184030FBA82A86E9A214F3C5E5CB7AFA31A3FC5217AC400C6FCF18C61686564F01D0C5B1832794103E8A198552202E8CD265203009D0882D4AA4508727D2749FC0A06944B7071DC0FA2B5A849B0922F78C3A8D300E5D536792348F56630D3A75A74EA143BD5C8B93429B8F74B8239BD9FF54F2F293A94AA3F4B4B9D9D6434D85750BE959F15479D2CD0C7C2CC0DFB8C95990653B7AB2F32100C97688672E09E672670CDF4CF5B4714968C533D81997FE8A92996949603691BD2216A320B46035DF84B256E23298B2B3FCD12748D550120988785C6B72B20C3BAA22CAF8789C0880A86A12C8C6C11B022A908BCCD8B144C191A299D2A95426C5127447AD3D3A70E31B95F38BFEFDC0D781097685CCE6FD8468EEA7046C54715968B9394B3934B6229067636ABC41AB644F555B5DB95CC5EF25FEFF8186BA226EA95AEB6D76DB3B9BDE2A1C3BCB72CC0B7AF0DC4BAB0F0AB7B1A12763A2485B22649CA392E8C0CCBA819BE77745BB1C4CB68AA8A439A970A939006B3AF9C3A585B094FF7A1A7F7AED61085EE4816D632A327CAAFBB6899C4458ED43B327975A0E2325D5A225D7F2CADFDFBC016D439147B892B05A61FD34AB2D62BB462468E1A9F310307F33928BD16AC3626B484CA82DBEB405400801AE2A06CA624673C3BDD2B72DDD3641FBBB7952703A5349339813404810E554B7DF7BC18793A485E97535038919046BB8558545B87248E3B80852BB7D5A23EF5E0A396C0239D57582A03350110426CB0317A5005D558A5516727B257B54CFABCDA8B49D433AD96979E575A93AB2376515C0E31AA5B0F08B2B7B69E232CB3D8C7C809C03752F355CDB5118A11BC3AF00BF2513095D4A6594457098199544C0224A80BA18C02D5FB951B4118235B1C7E9C966FF891059B11DC566F872441158C61CA2326B7D171A50015AC663E0ED71612247ED3712ABCC121052CA5AC04032DEB786B91735D612DD4BC5CEB514072145ED6B2AF926037B7655BC7379DE4FB3AAC64A3428558B8871B5979593BD33E22DA826E44CC313A2EF1E27E473692D70B178B466FB72CABA716C2468B308C0689615A0077215741D70A633734F0140F4479BAC081370D3565D24A4D0D7AA189F1C28792BAFFE9928436B9C0215FC655253D645B3B84C237212A7868131AA623DCD8BC2ED65A2E082C4EE29A978B0C458C9E5BD656ADFC68BF64291C387886493D12825B8363932AD17B8752BB49B63D074A508AB3CDB7341ACDC5AB76B8C5F9C93FD4EB74CD9891BAA467DDB28E1733A4260A2A4D496A3F705E318A042AAC818E408DC7A9BA20520E3A4CA237C1C581598D839B67822CAEE8C04E7BA6219ABB23D9455917B84CC5C94BF8594A2D1127601BC3E76B54155B1AD8C5754D13B564906E3688C3DCB9B963B7295310341EB0A36917919D289C2A1B001CC4360285A40DE87978FC532A242422829BF8079D71F347EDC072B9884A5D26C84E07B72E529DA1FCC8E57C1C2BC30685D12635B3A136755A70224D79FA7AB1124A69701DFF4AB135508014FB4BCF044218D4918790455923039AF9591087A5ACAC37363097C41B4153D375C933C488C216C5CC1AC56134F9B3567519CA21496A4CA06AFB84C0DC2743673AA94B15867EEC0945398376DC6981C6A9BFBA78D9950E27E16D3852A63CB08BDCE1C99172B4181654BF5A90496C764B6B96A25331E84162F902009BB4B76D8BC41C08AB7FA8B1C4657AB51CAD6FCC324E4BC70979AEE6125F2BF916FE8C3F4F5A72A695A6F8E34084728B0FF59CE1FB5161D8AF07CAB498D23475869F746563DAFB49B64103EAE0CE8A17BFDF1853E743262593C327608B27614F32C1ADCCC9B638029F7F9377B302248017747AB5553833ADE94A3846D309D5BB9872C89AC4E7831D9A3A3FDA26A42747E96AA6EE375FD407585E964CC4D6821323C7874986A1192FC0C62099A764A4554B8D89B9D9585A339072E9D677ED3475181197EA28BF6D84A3DE367D7529AE481133D1618007D5832E0A13B7028BCF5CAA36F4861DD22DAA497167E171CAF912B9FC8056016520ACCE1F68397246097A5755F8462FAE3413408264BDD915BB253A6229C26B14426F439D9AB79C39B11A7F51B9376A300C7530744B754713A50D71BDC299B9C0C7B266CC41F31AB512D0BCF5AC9BEE85BEA109734E7861646A7160BC3A27AA5CA3F87128468F3266B2B156210AF79D03890386A9AC0CB71BA3B41937960E575494F60B0704960518399199CA227D48B99ABC8E85C1795DA67C0D331B40CA8E448A934A38CB24D0730E181A7B30366335958D5993385871DE69C97B22A1DDC6BE8C5242BFD93073893D2B498627B76B6D39ACD7405B64C16E60E190CF45B5EB12735572AEF8F99E37CC3C1492979D3718BD363EABD56E1E416ADF9CB106F3540ECB4ABB052D57C728A558AB52FC4FB9C078374919F29558481C3ACB782959E2C41AC05B8701217E7BBF945B970298A694FCB0E12490A6C5665E267A8AA1A5F060CC0A08093E816EF9644720024FD0ABC5C30C39EA095FC5426E732C2490B288FB38AA6A3517D16BAE8F38BFB091BD70260BE1D80B2694B3651316484C1E97B714A67A0416179F2C582E25F770EDE422453607ACA79C1EF217C2418840609FEDF914D083595C10CC4CA70D40A8BAC5470DFE4638DD86A03DD428CC305569963CF620931B40245FF3098DB6C6A1870D5D7B838C976D0D0B462F441B2D79BED3A488697A191C20C0A8281CA8A39D61E69A0767CE753A02EE8987414AA3BB99BAB032CF451BAC1075162CD1097B00AF6A4A82F8112F28861BF0A6AA22733DB462BD15F95A211161ABC0C5B5330FE4D63854F3C0F074C077D06AC2839F06913FBAF33F7F91A948A19D01D6110AE54025CA068D1B0D7CC66A6EE0BA83E377FD2313EF44C87A58354D841B0158C8010B6EEC2898A9A0778072149452C2B6A628256C257FC224C0B767DCB3710071A71B43015D994ADCACCBF7B3A234C11FB2B56E75E4154DBB473978BC25758EEDB5319AECCEEF44AD82C3584F8378437763C3055C4A84AB71815EE5E360AE0A363286936486C69976AF602885769C1CBE21229B9C350562AAD4A91BE145AB3B090B9031175EF96CD275CDC68444BF890CAC56241159C55A474647A4257A978470BC97D28549F21590EAEC25D9603ECB5909D375CAA56B076DE917B8C7251C92B34563BB56AA6C3749113A837B5F6B5496259F5EB94195E2AADEDA453309F91EC2AACB59E01FBAB4B8F8839735FC7BB6B7B2B3ECAFF53F7CCEA5AED1A76414F3B57EB29825F79A4E7AD90330DE5C761E9371E9BBC4EBD1B98C390180BB2BF749D427500D5F562A6CAC38", + "c": "17EC1004F9E3F5AC1BB90F19D09F7CA08983179820FC9B945CC220973112318E0C212814C5F852B8E675B392140C4B2E20D5B1E4F972CBA5CE389792DBAF7C068C17211C376CFB907FA4FD468835703F559CEA25E0A12F2267326894AB7A3F4D7D83D9D5C98F922F16DEBD6D77663D2421A60F54248F5784A4D5AE151532E6573B8FFD81421B3A7E3FDAE32104F347049785EDC6AF47A417EA8BAAEC8B89E88D3B6870835EF552F7CB57E480C06B3CE95D238B460BA40EFECB0F6C9510211F02C92CBE6B4D7AE23471D187D1AC95AB0C33D2E886E32232427C1BE7DBD3342A4396378E263D7D64CF996B76ABE1BC57F12E55C9A4789B20CC087ABB217A09951BF4CF2778304F95231C05BCB803AEFD0596BF1164270ADAD28944771BE9B5050075F3F47E5C3FB5859D19E989F4E03429E1A877CE9D65FE605FA0B10F7062A003BA13614E35C940204D321D1676DB769817FAFF8D1C02321748189BCD6CBB961858FA080326BB24536A29CD19D7A25D7818FD212E28FCCC25E1949F8F6A0EFDBDB402710B4E0E7EE67C8CF475E2E0CDCD29B0B8F52712550499E24F0EC0DFB8DB333ED1C5B8F1B3D93DE676AF65ED80CBC1406E6EE78B35EC607986130F85EC3766BE06B01FBD1C93F98F8AF8FF8224CF7F23DCFD9B3CD4576A933672AC1817114BD218647BB5AD70B249F65981C2F12FDAF575A009240B11F92702527692310719D0EDBC87BD7B80D0067381BDAAEAE5FFBF82E9487CED9C51B5A2689C338E410EC6200EE40289166DD37EFD87CF4433FE78E470089DA0B2AED03EC4601B1BA3EB4C85A261462F32B2886F6BBFB6C509E058C2CB3643FE5DAB864676ADF3AAC9C4172E5BAFBDCA0BE501BFAD5A35EAEA5608E1D2200361E581385D640C2F71DCD585B6C9946F455A071DF253EAECBF61E1ADF160BF32F4AA1ED1B4F35B0D6FE5F83B2980EB81C0E4DF06CE50530919920AB319D3233DB5A5FBDE2E33DE18B66F78045F79EF9536C4AE168689B51F54619324BA1FAD9A60C406041BDD8B01A2D83C0406B72F5A6854625F41BA1AD27E15309C9763ED8FF0FE2CBEAEC0033EBE14B211DF23D16411476B637688C6269A0B7A9CE57A344373B948B3210F8666120B6A5F4F5EA238A8EEF5A757C7D20E37835CFE472843F94C043E12AC6F36EB65075480DC580E4B7510D7D6B49A794FEFD6F0FEE8AA3477AABFB26B3D1D1F0D7D694F5B1BB2618A57FE655AC2EC19869DF7EF57C422ADE6A181B57F33E6FC9B4810AE23F41EE82EC760F571F5511FFA71EFFC867B8417D719E5986D366AD7D01CB021EA809E80C508D68DEACB4C5C116982BEE6BF99BC2D052430A29BFF82EAD2A28FC816065EBBB05E4A20722BC677D0CB1E1AAD732DA8F0D854E044B5176279F1C401CF553A565668794AAB06956019E291916DB406641A0B4A94CD2F94AD954AF203B440997C9AA315D00E9791DF171B724859DF1FE44C6AFE66C1FB35543C8AC69F5953A98B015357AA829605D7246555F20296DC8D8ACC312AFBA78920C6922AD1A3C895BCE9D54C902DD87334391D5D68692E67EE3D5E1471E4EDD20A28AD22B5EEAF2A27B7DC70D5C53CFF4884DDDF837B74E8581BB2473C969DCE8B55F31EE0098932A0BFBACC0428CCA1E130466898637D876DFB972B0E0AF10C1133A8AAA8703172DDCF28A08BF8698228952E3BD3B29D6DD22C72EFC18583E80AD5523BF3828ECA00DE5D3149F09BB31B588D2F3FA205CD00C78DE8D01DA73EA5956EB0FBCFF01A3C6FA7A4B6C08B23724C47989F7E999FD49961820A8F9C7E84ACE6D7FFED8EC119BA3EACB18E1E16DDBAA0503F227BAF09E5620ED738BCCADF3FACF7F57364865B61D21107EABE4E961B04DF62CEA1EF0E7604711994CF92CF1A8B7940CBA6212AB98ED5E37934CFE9F4122C7AB33F8666BD5F0C4B240C3FCEE1A3AF8A4574CAD95D68230F9A8E66D96079CF2D58FBF7090885E83D99F6810DDAD3B0A546F3FF71CEDB22558F3C823886E2DC089916F9164CE4007F93D6BFCE1AAD3AB69A4CEFEF87F430D73F95FE96A290A3A61E4F6C5EAC36377A0F0B50A460404590E5B1AE3B4499A85123055B73296396E29083EBC31CFB4C9946C7EC4A4D6D46ADDF64C4D9EB9FC81D4BE566C464C9F93EEA01E739BC8077E9B13856AB53AE9A12C3C85DB5B06FB3A47CF855240F87D4715EE99EAC7B9C8D1F331C811547DD", + "k": "8AF0912F3635D93D537E9065529A3D69590AB2E66607540B4ED97BF6D985AD09", + "m": "BD990171C3252230BE21FA7F186A121686187B77C234C37CA5122A7AC77E318B", + "reason": "no modification" + }, + { + "tcId": 60, + "deferred": false, + "ek": "1909B5ED6C0D8D3C301F144373956424139AFF46757A070167BAA70BE7BC375A6D43E18FB0EB4A69B49A2D951E9265BC159A282B724F3477A2DFC89378CB9FE6CA8CBF55BE9976CEC668402D7A3D2E4CA2AF6A1E479621DB16A3187461036513C84ABE5BB228484023760266DE5CA11F1A8C63EA77F6E45F35D4CAB24443B51B851DD2C58EAAB9D426C90064AF14F8BD8984CDBB84C7E2208C5AA2C7E3A222249943985CC1F199BBAC9B8719849E5D539986D8B063A363B76953D22A508CEB03C46A04F19769E327A774A063B1D412B7B43D5651051E547487F2293EE2B78849BD36D2A54E966F8B386BC735152DC34E1A12772F67506B6474A2C57AC0A8CF53122949D52828D69E8A7A326F18599BDCA23C8C8E3B28624F26609DA18044411A9866C3A7D7083F09707A70192CEA40B936BCE696112AC92582428F30A800876BA7BB40560561AC5996A4B11639BDF00DD67A52F85C6BAB54055C2352121591260B656C43B2C2E89A891C97F39B7921794CB5A552C05A2D8E8BAEC89250666734C2DB73EAE68484DA254969918B10914CF4274C2C27319412360433ED27C810712F4E3145B5265D1EDA7B6917CFFCA61CC087926CB116020C7C49D1A8A723C197CB44118B3861A0773D52C6CE25A9E2C66BCFB6C5BEB43185EAC855D1A99C0A2FD5A348BB0C579DC23C7E777AA57249008497C7332EAD85C491A89B76427835983E00F5856B1443A60C83C714B122369A97C356C0755FE1F249C8D56F0D9897680CAC247A7EFA8386744B607BD7C195B52C07001384C17EE70AA04393C081EB43C7F912F3D786C7E63DF043A277329AE2C90A0E721C5713A47417A9ED1370C2761C1C029630C26DD215028EBA6CEF5239C25383F6370863F622BC055517946EC0D2C4CD909182CB51C817A04C53B4309B14507069303245B4B55B47226970D269D87340DD5A864A85A62CE3115AB7A972C813FD18C9AA0B582E79C228468292A8A133CA5C53A4C842233FFFDA7DD0002444C51B2009654067C7AA34BA17B7368745C1719572A2C66D6D894B92049EBDF629C7C5A2D1EA82C7791B7840729DFC7975C2C18F3B319B45AFD1E0BB0C527D3FE8BB7E95A7DF958EF9268ACDCA208053ABEA894928DA891788177185B362EC3364F93D4B602167942603412CCB595DA8910B748A2EC022C3EDA8437781BEC4A913D2C56043A1BD6A5B2A858A8F7742A82986509891A9EDA7859D3A99FD78A11335910D830FBA1B13823154ADF8984DB9066B6735704196D49C8771B870C05504EA110E252B4DEC2743F1F39142B6BC5B635110CB37925A3CB0AA83858A54294B29054805B969A6352925CC53017235CD75DB70C86198EAE30AE8F933412C0504DAAFE7516BC9D7A780E04290891E5594819F08C2ECF083711A85E1A679235441976B03E37B0B0DAC6BC8456497220F2D4B927688021FF90F2E00A64DA33D3C878462529B98CB709B01BDA6D27FCAF7899BE90853BC6C8652137851C3C7FB40CB3647AD8B7B081B46C8A2587086426D48819AC1AE43C429954BB5F7F2227FD8058C18AD81203462C055ADD5045BF48CE22271C5A67E20ACC0EC93B182684E2B230C0E44C0688A2BA0A6BFB7D10C476B24719700C70A7EDEC0C6879345AA781B6B415FCFE4373F78BB33CC62A659B8286154073193894B6D8AE85284033082186478FC763231154518B1A8A59B1CBBB56A50A8F9C38223C5BFDA5C310A1C30F2569C4E179D4039331293CC18870E1D1B90E0008B29008FECF00152748FA9248B7D64491455044D86C6C3565AB4618233A2154BD277DD5067B2E6784DA94876D1BEC361869493542C470D7E58A7B6F9236E200D66CB16D70A6273E40C8C69C033CA8EBD7A2E5ACA69A5E0CAD2C352D0F36BC8A0B90A29B604EA0DD6A77FE9505E717A721849A0B435C08C66AA44E202015CAC90D364D1D83F21E5177A100A9E7855A5C5C0A4B46B388C58D256088E455D59016A4DF337C8A69827A399E2E9BCAAA7B11CE6440A7536D0BC544CDA12392340504088B8EC6CB737C3B1C0A11F9B83C049759D74BA44507C6881B1F98167720C0B35A095DB1A7659B52E38803935241766237E073B1D2C52BB5F4152AD80625E7C52352AA4EBD89820F4AD1DDC3944784A239A9F71B243AB50C1700BA6FE82A501B275DC3391EE30C022997F00F09D0F5FC8A9F5B02358F99511C32A582B24C0", + "dk": "5D802C21CB29AE541E06365D0E295C066C199C1668BC5255FD02C99323C31646625E2363BEF0900E13BFA27307D1712BF4D3AFFB80383A5ACCBAC575EE02980EB855245121E6359AF388B57AB94C47989497C38A09E517E6726316F2474ACBBE2E999A16E9989B8951C8DB8955F790E61B5D3F7304CD9A41BC64C8B692707A4418EF05B57CD34DE597172F7926A46868B2264FE7521289654944A066B63B67CE375CA069357D9B0B905AC871D0851DCC3DD49847A131AB6F92934CDB794A28A1AB07309811BF06633A5DDA037FF3BA5021C251589738C2A794721E42735D1EF733F8F0812BF12B628158D83577E0107E6DAB92361CA40A904F5BC3788FF609F04854B38210D441222128B0CEBC0F6CD25D6AC3CC14E616EB4A0D6E500EDF5BA06ED7ADF647A11E365533D9C3ED2C93CFA08FA715BE8A71534D007647FBBE164C4C077094BC372B64546354235861434192B85C68B7AB3610C15D5B59A30C1832F4659ACA2FA99118614C804AD75DD8FC51B2772E7225858CEC196B60008366C1F1BA8C837A4539EC10C7A14F938283175121489019BB419350121EA18284DD14B8BEDC9304CA42AC3C9E5674773CE84D621072F90873212669988978A9C3CA012610979A4BBA114A0F39BE7E6820FE881948D444D6254887E362FDA99407446584D75D78B848DB869FE5230FA2093B5C170FEBCACC3D55B1BD6CC9EDD2850FDA3C9937648DD614CBC86640453C05B403CE145C0A1A7AFF29A05663432DEAC8FEB4343B054692E923C0B99600F56697B77394CB6DD8618605EB5CCD5B6546545056081CA8A12FD38787C3FB759BE18F300B4ABC9BBE37E2873521355BF7091C6576A792B2BD6A42F367A3FA94310B14049AD8A0F710C6877A481753A0B42A8979824F1F850EA961959E87113CA2608C59AABCCC1332B5394B1B8EFF2A486AA7B0CB36361DF5C2C91AA039109F99249379B4339013352AFA68D41A0800E02572539D557496D944726677399BB136DA27B248A901ABB76890D10ABDA81172172BCCE82807A1900D2AA5D919B0211BA64C9806231C543EB6C35D2B27EF96AA2FA26C80742029D0BF7F72676CD0369FAAC07CB99251F69A0D45C952785D48655AC3B74A1E019FAFE1430B78B7B5DCCC42D6BF5956B6333925C13BAD2E853F0E75BE0D78935695214AC252EE1AA0653BB9C5330E2508616F4057A49C7BBAD11F10422B84E5252ED320611853F39C42C9E811B0B458B0B44142BC16D017B2896C8C223B96AEC573BD43AFEEBB34E4260B88D91238F3861E587648A6BC74128CF1024B034755CEA4927202CC7879A0AF778F04C47888B13ECBE48B7F08A4CEE7CB97A4C272B8A014622389281EC7E996AB1024379A5833362C420297AB97A98248CAE6E0A65B2644F0DA07C7193C0AC096ABD59D24603ABF827DFC6B7A5B7CACD23090AD900BE4E7C8E34C736AB4CE71750D537784206489810BAF00E2B3076628D0B13C058264D13B5B67064C9DCA02DF9C93B5002091347EA1522B15228B031276EAE603B88B384B075063569CF8E7634E598F2D872B238287B8BB0A681A4F3D711497949E93FB91753A0DF27258F79B3D8B44A62C2929E265789843717AC518024BBCB23C9EC658891128CBAAC9010E700B7371C37F48B75059443D89CF35C62294E68A1A65B19E7900A80B59D78808EC462AF659398D934077A3785F999B66C60059D24601D83957597C6EA99FC5E95E4B436AD988653BA05A9FE3AD8118237B1A84D448498B426247FB5DE4979209C06800D6A9D39543AE787A461B1E433066EF2B2FB0A481388C5A68557915C4B8CF7531120C1D340133F5D5705E59136531265E3B0B4A1A501172AD8918C1F02A7B06453D8C05B48D561345050B49F893DB946AE26B6245F1926CC205E6F81A7455935B775324F1298A3BBDFFE53ABFB950176C7F65820A43C519FF596E898166B9A1563CBA7CC971B73077AEE1DA384E88887289B63E662AE7984FB8F974B7A42CCCF17750B37FB8A9424106275F122DFD9245A0A28A319CCD49D985FC58A1AAB178F12B8B3034AE7AF89532619EF24A0A77637C0033981103CB5CF9AB09D879EA067193427FBA219D49A5A35F95137EBC4A0D046186BC9E3C091B14195E2B43BC5A79C0B793C97E02823EEA301678723815631909B5ED6C0D8D3C301F144373956424139AFF46757A070167BAA70BE7BC375A6D43E18FB0EB4A69B49A2D951E9265BC159A282B724F3477A2DFC89378CB9FE6CA8CBF55BE9976CEC668402D7A3D2E4CA2AF6A1E479621DB16A3187461036513C84ABE5BB228484023760266DE5CA11F1A8C63EA77F6E45F35D4CAB24443B51B851DD2C58EAAB9D426C90064AF14F8BD8984CDBB84C7E2208C5AA2C7E3A222249943985CC1F199BBAC9B8719849E5D539986D8B063A363B76953D22A508CEB03C46A04F19769E327A774A063B1D412B7B43D5651051E547487F2293EE2B78849BD36D2A54E966F8B386BC735152DC34E1A12772F67506B6474A2C57AC0A8CF53122949D52828D69E8A7A326F18599BDCA23C8C8E3B28624F26609DA18044411A9866C3A7D7083F09707A70192CEA40B936BCE696112AC92582428F30A800876BA7BB40560561AC5996A4B11639BDF00DD67A52F85C6BAB54055C2352121591260B656C43B2C2E89A891C97F39B7921794CB5A552C05A2D8E8BAEC89250666734C2DB73EAE68484DA254969918B10914CF4274C2C27319412360433ED27C810712F4E3145B5265D1EDA7B6917CFFCA61CC087926CB116020C7C49D1A8A723C197CB44118B3861A0773D52C6CE25A9E2C66BCFB6C5BEB43185EAC855D1A99C0A2FD5A348BB0C579DC23C7E777AA57249008497C7332EAD85C491A89B76427835983E00F5856B1443A60C83C714B122369A97C356C0755FE1F249C8D56F0D9897680CAC247A7EFA8386744B607BD7C195B52C07001384C17EE70AA04393C081EB43C7F912F3D786C7E63DF043A277329AE2C90A0E721C5713A47417A9ED1370C2761C1C029630C26DD215028EBA6CEF5239C25383F6370863F622BC055517946EC0D2C4CD909182CB51C817A04C53B4309B14507069303245B4B55B47226970D269D87340DD5A864A85A62CE3115AB7A972C813FD18C9AA0B582E79C228468292A8A133CA5C53A4C842233FFFDA7DD0002444C51B2009654067C7AA34BA17B7368745C1719572A2C66D6D894B92049EBDF629C7C5A2D1EA82C7791B7840729DFC7975C2C18F3B319B45AFD1E0BB0C527D3FE8BB7E95A7DF958EF9268ACDCA208053ABEA894928DA891788177185B362EC3364F93D4B602167942603412CCB595DA8910B748A2EC022C3EDA8437781BEC4A913D2C56043A1BD6A5B2A858A8F7742A82986509891A9EDA7859D3A99FD78A11335910D830FBA1B13823154ADF8984DB9066B6735704196D49C8771B870C05504EA110E252B4DEC2743F1F39142B6BC5B635110CB37925A3CB0AA83858A54294B29054805B969A6352925CC53017235CD75DB70C86198EAE30AE8F933412C0504DAAFE7516BC9D7A780E04290891E5594819F08C2ECF083711A85E1A679235441976B03E37B0B0DAC6BC8456497220F2D4B927688021FF90F2E00A64DA33D3C878462529B98CB709B01BDA6D27FCAF7899BE90853BC6C8652137851C3C7FB40CB3647AD8B7B081B46C8A2587086426D48819AC1AE43C429954BB5F7F2227FD8058C18AD81203462C055ADD5045BF48CE22271C5A67E20ACC0EC93B182684E2B230C0E44C0688A2BA0A6BFB7D10C476B24719700C70A7EDEC0C6879345AA781B6B415FCFE4373F78BB33CC62A659B8286154073193894B6D8AE85284033082186478FC763231154518B1A8A59B1CBBB56A50A8F9C38223C5BFDA5C310A1C30F2569C4E179D4039331293CC18870E1D1B90E0008B29008FECF00152748FA9248B7D64491455044D86C6C3565AB4618233A2154BD277DD5067B2E6784DA94876D1BEC361869493542C470D7E58A7B6F9236E200D66CB16D70A6273E40C8C69C033CA8EBD7A2E5ACA69A5E0CAD2C352D0F36BC8A0B90A29B604EA0DD6A77FE9505E717A721849A0B435C08C66AA44E202015CAC90D364D1D83F21E5177A100A9E7855A5C5C0A4B46B388C58D256088E455D59016A4DF337C8A69827A399E2E9BCAAA7B11CE6440A7536D0BC544CDA12392340504088B8EC6CB737C3B1C0A11F9B83C049759D74BA44507C6881B1F98167720C0B35A095DB1A7659B52E38803935241766237E073B1D2C52BB5F4152AD80625E7C52352AA4EBD89820F4AD1DDC3944784A239A9F71B243AB50C1700BA6FE82A501B275DC3391EE30C022997F00F09D0F5FC8A9F5B02358F99511C32A582B24C0011C0579E0446E2C171BEAF2BD014E13D2B88B6515E2B8A11CCB8FA4B91BF2B8A932A47B71E782BA97D69908DB41682AF409C94C050DD621CF8D958627D0FD2F", + "c": "588B326FAF4C640216A4E3DD75FFAE0D4E6BA0B6AE4214491C3BDEF276E98585CCC730B0188706E3CB275EECBF0F023EAE4E4A5D07A68D961EBA5DB25061AE3C76C2FBF6B898D90C44E479E2859F0245D579032146BB34AF36DC16A9CA55E6FAF15A6D53C5A0554F9D5D39582AD6225A1729C4F3672C5FAC82AFC900740F7B738D99FFF2E4A660BAF194E2C129CE4C6DB57859C8334D859D49F1FB46B55D6A0AA71CFA726E6289E808AB016129CCCA273A56E78812B1F1A390311286E9C4F0E8ACF6806E9DB5EB2BC782AD0D68FF394331BE7DE253AACDE455E4185C81E7DE685B7358CED67FCB92DA724A93AA86A09D33B504DFD0DC2A5F113168E6DEE9098BDEA0054B3035142503A5AD671B5041113AD0395A40A476DCF52F2C41CAD9A862762639ED23205A90EAC964B68785DE9883BCC7EB43CAB6126A116F1303B53C0DEBF9A574F3835F3CD791CEC539CF15C4C20894013F21C3E903E39DC36B230A505D33F6F81A713533494F62241E1ABE839FDFA972648EDB64D3329CAF8786C4B19DE97A4188A5D2AE995FB45333ADE7122BAF902062B56E0C5A34732C493A2F4BE714B431B6E29AF52AC27061CEE02F05ED5A96D71DBB42B06C3BAEE5E23136B015C9A7DECA77AD6A7850B58119CFF9F445D1F36FA628564F02F1BCFABA5C2783469CE4CEBF996F6BE9C2FDF5210AE428C221039BB4E343A09460C81DA72C43B52DDB44616CD03BB9F1319AB399FF44837D14966A5BCBEBCF7CC482B1E691E20D2FDE85CC327011D1A6E5514641E3F0B76E5B6E1B403A76F735C785BA81CD53B72B237B18220F9EC51BE811CF614B454BA43FB58591A0C3385421810E7EDE6895DDF6566C1B265DF21965F9BEAF6FD3599CE636E66987F2DF9559D27E04E37F7428C205DC52061B92238777199ADC0F5A19FCA01617129284A6FE91AB3F880B5741932BB690ABE5AD7D68107E330534EAA8F13A35218CD16109C1E7D4F9203EC7A21404745EB0F1CD614B8AAC8E030F6FBD84FA4C554C3699170CB2EC060FCF2E21B7FDDBCA825418BF3266EABC203F77AD94668A6CDDCE524A805115562ACDAFB88381CC0EC7A00BC7CC168BB40AC36BA89A6637DE33A31B6E90209752F8364B0D659530BDACF2D695F1D1BADE99FCC6A726CF110491CC3C19A18786E2EEAF7E7978DF2D90E92B9C0C3344D506978F09F5F33AFBA3CCAACB76F9B6C11261E9AA0965F22DDE4FB8ACE9BD7EF16AA9BB1633DF10D96CFF15930D760898A2CC48DEF58546DA07D0A74FACB66F2A37D9DE09F1D95EAB1D695A247E55C648DFA2D2E23A89E755051C9CAAA410B6A0947140AE1A8B0E1411933AD5A53878D1FD6CB980217F96C6DCBD6F4D3D8490B34D110500C95435B4AF6946B019DFA20476B31AFDEE8CA8346DF824D2DCE53996F1960570E1A8360B2C583A44239CAF65591D931F85AFA503BB3A4AB3FD763E824721BAE2537B2FEB4AF06C9459D18CD6B07A68328132C5D4C06E0088812EE20689BCF8183C953854A48A3B8848A8990D3ADBC2F3D2D789029A1E58869B4347D1955E776F0DD0BF9E86AF8381DBEF172AFC9917595CD0E85921315E81F69AC5DFD4D334A13EA8ED5EFDF8D1334E4C873A10CC5E1BEA470977D17A5E4C0DA2EDA1DB017BE8152447DE1D3FBDBA79168C33BF393BAB32630658F10EAF6DBABE5184EA6437C69386F154D1505492271CFF931381E29B8442DEF27A3D123DCE1422F099D505C237509D6AC344A3B7C84DC0C3E5070E5DADCE76404456E6B46EBB1C38BAF1DC5F9677A969DD2BBBB351E3D0BBC54C50FC2A6F15BEE73EC0CBE906895573B02615518BEA90A75B1623F5E11D86D6019461691891C1CB518EAEDC8AF0AE64F92AF0A653685C4F219B974D3DC52496E8EB7DBCE61568BE3987E28A5B6F5B5161CA4B46E42DAE63ADB497C75552142F6C93EF95189601AD27F3213C150F34BE5C38DCB3A703024F00F9D4BFEE3058DEBAF13EC461C61CD51463D50AB338CC9475D0C3F8FEF25D4B65B5657E7AC200B633148C587549A6E0EEAE7EF63BDBE1AFA1625873991FCD7C11DB82E5358931024A10911F43C289A7816F293527279F90A3C0A62D5FDA98995AA784E557B0C4DE77FD18872F07351791623668541FFC4373731B5751689C313AD5BA560BC58A8BBB3514AB20F27CB721A65C1D88006FFF5F9EDFB69A89304A6CDBEDCE1261BE42BB7BF7", + "k": "3D14BBCD60FFC1EBB9E96EA5FB23A5A18BA6E370D092E2BA5E3232ACB5A5FF70", + "m": "135056EAAD8A28DEB1BE77EEA30CDEBC7B3DD89D1444DBAE145F39898256ADB3", + "reason": "no modification" + }, + { + "tcId": 61, + "deferred": false, + "ek": "11068DF3FB0ED1514D8B2B8F424C03B75995406482FC8AA24BA003886711E921832222367CB2C2EE87617A30A270B447D4A1BAA3377B83FAC80A7C8D779669C49C461B311DDA442FF10C9F2B9057225423BD119C68E34FA7A92DA2D36C58014A9076C391A451EBA75B5C92A2F14853845838D0DB502629B796703523C29575B4A5094C1BE329066BFB7AB6E17FD0163BE4E60E9D676FB970C68AE416897174D4577E0AA8BE0D234FBC80279FD724AD5925FAE2B478816CB07C165A335F1B27B030E7BA5CA40F610B0E07C82FA134812D9A4E083836B158231DEB7568B73A9B3C60780266BB550A36C7288A9387D1E4C904D79296088047F34F4E72A23A1720B7543FADC3821C6442F4B501E6894A6E25231437AAA7A04329A8CC6AC729B185781B8BC4D9142063E55A0F053FFF57CF93C5851C86714E872840A264E316C37CF90CE60960EC2B0F4D18418AC96E202C07EA61B2B1E6A430DC5DD1A18926E0BD88351B56434E26CB10268468D67B2D04FB2AE7C43C032675A2C88A3E704A7D110B4A544975616D694C9E6E243E3D546217471B14711505B945E87C0D39170E3AA71A0663062CF07FFD0C3952D526B662CAFCE429A35839D667C7F0090965CB1F87642D2A8C28A0A57B4FF539CBC3195A0B063F3966CDF41FB4D9451A84970B6B93E006342247BF5DF06B041A6A2B019C3FF93DFD39502E198F5587B358B39B640C7A71C43A31D711E9E5434B75AABC436531542F90730EC7FA6B72A3613BAA4C0579A245B06B979B22623C93D5CB6437D17A7E3302BA1CA5EA0533F02B1D481573C1C3AB05424900F1613B379707433D7089A316F52012B646B9A24A90F87584C36C1F58B891F5482B757F758A03E53B38F282C2700502984ABE9F1C2BA00376091021DB8A1ED27B01AB11B7F404B2C5FC9E0F8943BE434FA4135A4714507FA628F4027D0DBA912E0B3B096C057BE77506FB8BCF5A8EE6DA96CF335BE8C0555EE446DCB96DC2567348433E98D46C83319E3FE1624AF07AD838241C5CBC3C78C8493214447C8AD0D40DBF319057531FC456CFDEF999F9F280234A03C7437786B1469D705655D01EDE1A72BD0981978815086A0DE74B059BE879199A67C67BBCAAAA87201A1910F39B5D35670A9790DB3B5EFC798BD9EC46F2FA1E993110F180203BD1A7D3506B87325DDDD695211440F60CC1C5B7A947F42DB94ABF0C8C3B203A7038682DA9840BC8B50C4343A4D49AB89DE916CE72835AD4C7298B68BDB417EE999EFE7B20C6C99A0B36BACE2C35D7388DCECA369768463051B377CB57BC0B155B969EFAD615BF7B3AA1189702A7494CCBADB0266224FB5BA75189766771BD1B54FE1139E6C607C95A2DCC2462515C4C1981C931C6628202A1BAD941AB7667F89BBE94118568F0C5CC59914AB113AA4C9DC2787F92BA2E9DD7363D99CB7EF6AD2EB5C1B992670B5541B1BA9368E7986D4628AE96836018934FD100670260ED931BF9A47652B85C44F988B559A48B2007361A3E4FA88AB8CCCF94939D5F419861FCC617250C38DCBA082CA50035A196880540E50A0E1BB363E81B1FD158DCA79DFFFACEB2494712F28A52249A103C5FCF888D275A8BA3768BA0599F5FE1CF632B07F4120570EC5A3EF96CD3031A3425A0CF3A7E408337412288575C1A414A271149A2B115825D409A1C478980CCBB4B4B1C2AF675DB141A3CD12B0860318EC340B7D3C2C0521C57D5675864243AA55C517BAFDA7187A174C109CC1C65BA42AB5288EA23CBA8C286EF98479BBA0396106999C220CFD043C60C4B9610ACF0086AE9D883A0A89BDA5AB9993C1DDF82610B0A1C6D75093B207A72037E77E76CCB282F2A0C7A9149941F3A149EA18CA519C1800B392F48C3DB358EF1179498CC2DA8EB48180A99F1BA280012A324AC8DF3FC8B3D6859A0B4334980157994502C80C0AAD301F6E9311AE9C132889A3C26501678CFED55427F94B05B57404B4BACC7607E19E873D1902163B25C06BB3CEBBA5D403456C2CA26CBE27240ABC8B6A85E50762FFBCA34FF96C1525B2A35435A7CCA663B37C202931CC16039EBAB2D6E45BE1002023BE959F2568D4FDCADD8A1B6EDE529AB088D79DAB407D4791AB43FE5087E4A9CCEBFE02C0C44C3FA925B7294A92E928C29663D2854210D405ECA2C2E5032A3058C6FB2B381F5597FE98855CD09B73DDFB831B56551306BA4591ECF403545BA", + "dk": "01D50182530F72E8711F976B0254B13EC997A6C63338E2A0009B3470A9AE5A014765380C3DD1964F4C92AAB0182DC07C11E278DC6C3619E2125AE86985F09107A48208B62AA764A5ACFA56AB5ABBEB93402092A86CC347FD674EDDDC9307D42B593C62D94181F85729657288EC88915066306ABC84D8C888AC4607C739590B8B5F08543816B13E5539007EE732825CAF044210371A4BB85382B7D76F3A1520296207654CC2F94B9735800161B952C8928BFC611DDBBC16DC13A12CCC4A6CF776B8EBC0A800BD72B71A138BB045CB0455A4B8BE59187ED12AE2D6C9A242BAF78B21CF544AF2EB7988100B3B85C68A638C3A123E58959559063C53C53568A326BEF9696E9CAEAD689F67B59087A0AD6721755B8C0DFC83654D3ABBA0B0484CB43FAC99BA196B86E0D26A99FA6697A80B7607020EA2CB4BEC39FF556ED6934678821BDCF69D91116EB82469C183173672195C74A0EE836E55AB57B2BB340A4569B0B91DB07270A5902ACE3647F75C429A78C942B40E64C1712C274FA4711F3494937661048F85BF81BA39F1B1CB2ACA86B4D7B4480A433B0407C7D4306CDA7A13F536AB3386C95301102657556C240A576D8791048609782E3A2593886EF8C41556B4209D45250C5B063412BCAB9718AC64C7F9A5BA775AA566EBB957C947447353F9B8C958679FCB2B93C4D4842E65405AF3A9F8D49C22225081C27F5470A6E3A44C8EE9979866A4F1E5AF959C2082494AC9A34F4B3813B0760CA45C8D489227F23CACD7D21BC4999243AB7286679E1E9B12DFF50AC8C68B7F8794FADA1B15A2235CF84752A714C8DCC5297AABF8C529B8C470F9E24A972056FE5776AC9C53359828152B984E016BAB14774BA956F3C6197452BA9956302EB63D9591307F7891B9F60BA85057FD48913E210845513FE744418B7348C66CB309A93DD4CCC15FE836456AB94BAB6D7078482CEC5D92FA178B0558225358F571C851E720A40446BD23CF2136B18D0530A460CB6BF67FC2B1C5C255999D868DDC5A04B0C0205A44278E7C100B2857DE304D37B93959E76D59D801A1D111CA17281BA2C82407243012626DA8066C6891CE9765E3691F1ABC16A56534F7EA0AD3517C8911C42B8085E3D1423F650957293AC6FC64E7F955926689CF72B62B6C8EAF178FCA4B10A147BA8A1201BBF20B3F4414C09594AAB84CFF465BC5AAAF17240AF7B47600E83336FA8FA5887CC761697DD148ADC21B12294281E25B08B22636E48E0AD94868B984CAD77BF1F1AC6FB9A3281B05CBC940929520A7A3094B1B611E096441313139E7C47A0B15859959BC8A76B2CAAB5A015EE09C19181693020B4130D3A6079947B0003CB0A94C644B190C24CA786889AA22882B37119274B4B8941967C49FB1811BAD43B7BB539A0EC143CBF61D9245AB96287164A4B1CCE519CAB092442C370E885794A81B185065AD41BE2760A83BC426D68C8E82C194A7C7020180BAA051705D21B291A95791D42081F68066AB243075A5E4A82F940C802A06BB910296DB82C4923A6DF25333576069E1900E0979570FD67832C37FFAAC3DACC48184EACE1FE0379F6C0C2EC6BC08F6A80EE6ACE301B8C259539CE7B7A87B5AB098978CCB0EA2A602DB1B287AB03568080CAB141066478A5E7728A642A5B9A97E435021FA8B5FC6B333C22185EC10839A94BD630126565972DB56408405BC35DA1786D068DC80992C3A0178F5C8A2CBBADB13B8F35A5B307A8086D216432B616DD5B47A02551CABA49BB82D306715097059D92019150549C70C0B7C53C4E763CB73384365C1004B369136D51662C41F0525CB6374193A498E23862ED0578619B20557E3A095355AA39A2F78E4257AC24DD3C519AB178C0700205C34639184B128B069BC14979885BFB7C81C89409165743AAABC78495A0BBA11950243A56C645BE4329624E71692B09E20EA4F81079FA50CC1A49946EAC26127833546FCC923ECCD3CE894BA5A4F5913192B07BECE87B3A81095C82B55B5D72A3DF1CA438668DEC2BE1CB0674C25CC51938ED5E9B2399502A2157A66B5053CC2117957490A113699975383F69ADB51A87CC9582D041628424D76E547BE32C273CB013F75388E7C9CF91190CA293CE2AA7F3FD749B2FC2DBDC9468B80904E061F06E8593CF33A74B305EFE157BD6B7E11068DF3FB0ED1514D8B2B8F424C03B75995406482FC8AA24BA003886711E921832222367CB2C2EE87617A30A270B447D4A1BAA3377B83FAC80A7C8D779669C49C461B311DDA442FF10C9F2B9057225423BD119C68E34FA7A92DA2D36C58014A9076C391A451EBA75B5C92A2F14853845838D0DB502629B796703523C29575B4A5094C1BE329066BFB7AB6E17FD0163BE4E60E9D676FB970C68AE416897174D4577E0AA8BE0D234FBC80279FD724AD5925FAE2B478816CB07C165A335F1B27B030E7BA5CA40F610B0E07C82FA134812D9A4E083836B158231DEB7568B73A9B3C60780266BB550A36C7288A9387D1E4C904D79296088047F34F4E72A23A1720B7543FADC3821C6442F4B501E6894A6E25231437AAA7A04329A8CC6AC729B185781B8BC4D9142063E55A0F053FFF57CF93C5851C86714E872840A264E316C37CF90CE60960EC2B0F4D18418AC96E202C07EA61B2B1E6A430DC5DD1A18926E0BD88351B56434E26CB10268468D67B2D04FB2AE7C43C032675A2C88A3E704A7D110B4A544975616D694C9E6E243E3D546217471B14711505B945E87C0D39170E3AA71A0663062CF07FFD0C3952D526B662CAFCE429A35839D667C7F0090965CB1F87642D2A8C28A0A57B4FF539CBC3195A0B063F3966CDF41FB4D9451A84970B6B93E006342247BF5DF06B041A6A2B019C3FF93DFD39502E198F5587B358B39B640C7A71C43A31D711E9E5434B75AABC436531542F90730EC7FA6B72A3613BAA4C0579A245B06B979B22623C93D5CB6437D17A7E3302BA1CA5EA0533F02B1D481573C1C3AB05424900F1613B379707433D7089A316F52012B646B9A24A90F87584C36C1F58B891F5482B757F758A03E53B38F282C2700502984ABE9F1C2BA00376091021DB8A1ED27B01AB11B7F404B2C5FC9E0F8943BE434FA4135A4714507FA628F4027D0DBA912E0B3B096C057BE77506FB8BCF5A8EE6DA96CF335BE8C0555EE446DCB96DC2567348433E98D46C83319E3FE1624AF07AD838241C5CBC3C78C8493214447C8AD0D40DBF319057531FC456CFDEF999F9F280234A03C7437786B1469D705655D01EDE1A72BD0981978815086A0DE74B059BE879199A67C67BBCAAAA87201A1910F39B5D35670A9790DB3B5EFC798BD9EC46F2FA1E993110F180203BD1A7D3506B87325DDDD695211440F60CC1C5B7A947F42DB94ABF0C8C3B203A7038682DA9840BC8B50C4343A4D49AB89DE916CE72835AD4C7298B68BDB417EE999EFE7B20C6C99A0B36BACE2C35D7388DCECA369768463051B377CB57BC0B155B969EFAD615BF7B3AA1189702A7494CCBADB0266224FB5BA75189766771BD1B54FE1139E6C607C95A2DCC2462515C4C1981C931C6628202A1BAD941AB7667F89BBE94118568F0C5CC59914AB113AA4C9DC2787F92BA2E9DD7363D99CB7EF6AD2EB5C1B992670B5541B1BA9368E7986D4628AE96836018934FD100670260ED931BF9A47652B85C44F988B559A48B2007361A3E4FA88AB8CCCF94939D5F419861FCC617250C38DCBA082CA50035A196880540E50A0E1BB363E81B1FD158DCA79DFFFACEB2494712F28A52249A103C5FCF888D275A8BA3768BA0599F5FE1CF632B07F4120570EC5A3EF96CD3031A3425A0CF3A7E408337412288575C1A414A271149A2B115825D409A1C478980CCBB4B4B1C2AF675DB141A3CD12B0860318EC340B7D3C2C0521C57D5675864243AA55C517BAFDA7187A174C109CC1C65BA42AB5288EA23CBA8C286EF98479BBA0396106999C220CFD043C60C4B9610ACF0086AE9D883A0A89BDA5AB9993C1DDF82610B0A1C6D75093B207A72037E77E76CCB282F2A0C7A9149941F3A149EA18CA519C1800B392F48C3DB358EF1179498CC2DA8EB48180A99F1BA280012A324AC8DF3FC8B3D6859A0B4334980157994502C80C0AAD301F6E9311AE9C132889A3C26501678CFED55427F94B05B57404B4BACC7607E19E873D1902163B25C06BB3CEBBA5D403456C2CA26CBE27240ABC8B6A85E50762FFBCA34FF96C1525B2A35435A7CCA663B37C202931CC16039EBAB2D6E45BE1002023BE959F2568D4FDCADD8A1B6EDE529AB088D79DAB407D4791AB43FE5087E4A9CCEBFE02C0C44C3FA925B7294A92E928C29663D2854210D405ECA2C2E5032A3058C6FB2B381F5597FE98855CD09B73DDFB831B56551306BA4591ECF403545BAC17C983272288473C7676430281761C00CD2557C8470374B257D99D63E68C2631D1B02042D01389FB44726DCFE6501D72FE645D5F098EC86393687E2E245FDEF", + "c": "6802F268BD6991AF8993B2CE0365253B67FBFF0422D0536119A91A8AA3591EBA7BEEF1B3E08702DD63D9FB48D8FAEF6BD7BA282095687A9C70FFA21960EC27EC9D899A50FD2C6103E1018DB559D7CE368FE9CB0D4206445CDCE0B74F1BBB4DDE53008E50C632A36D9B02E97192DD633AF5936DFEB0F5FEBF306428E7993F9E3A8E47617F224AB50403725624023DC43AD6CCD3A37931E6514458D7F16294AB8ABDB042842F259937B31BF2BF327B2E8A86B20B6A0BA3AB87D897EFE6ED969E10D80BA1C7F53ACD704542DA064B8BFE8EEA9D73CF6453F3E1F0137E0A52C41A709689D3311A0695FF25B8E54512A4BEE5ABD52A887C52B1A509C2E7547EE621117E1A024800B935C1D50DC7B3A7D9D385A1172713336EB49C630EDA7E1490AD13316E5E0F7302006FB6ACEBDC6ED9EDBCFE2F9846ED0F7CB1CC2BBB593A7DBC6879B916C81BE5FEA5F4361B4B2FF17AF7B7D21DEB36D9DF9E504EBDF11ACD7273A1D7BB13D690BAB23A52777E208A740E75F797251E9F87915B975E7E764D3B2ADF90937D79D5F8FB1EA8CBA525C4786457E497ECA4A10757E533A7644FA04034308FB197FB133D136D0B0C9B40E0977E6C2572156F164F3917A4D0E6100B7EB9F22517450309B479634E9770F23C83EF87FA9AE94E90FEA32FBADB9DF1D50DB1F1F8ADE62F1501FDD1D90ACED42446A859AE7802F7F66BF785AA454E89EA8CBD5F600F9AC4E8237C3C2812D5439BAF89CB2D636441C566BD43C5D45489B61B2BD637119A5E5E0CE452EB309B4D7F6C7C387930A9FF6B90CB3C225C99554543EED7A71533090EE0C8A6CF857F4BAFF48244FAF5DC85DAC61D737B7E6CCDA8D9C439B2120A47A2CBEDC95D1C3E56EA4CBB9DDC89DEDEE5103ED468C8115F544DDEE5DBF41456F6465E1CD5C01DC470D9A9A64763BB679BA6592E64C82F9488E008235D6FCB84AFA7D2E454058AE57875F2782BAEF71F1512069FA24802E62AFB5298E307AA1EC074B2B91356045159CD6EF8EB946B6EED50D25E729FB176D4A866BAF36BFFAFF3907928D25764BE3EE7D226E7C82A7D9F2A3AA69022083082FAC7250E6DBDB43BBB8C77E03924D8D297CAE45097CC7A3833CBB75E69D03D01198A9B9331A8E9E10AB82EE349099918B07878120EF812B1B278283042234B36DCCA031B13687E9F1853E5503B32C1E1CBC51FB88FA5B1B044CC715F24883FBB2B5D45C7F461E3023AEE3F18A34030EACCB8A21FE0178F845A5380C3BD8B8DAB193BE5E02F45D30F8B8A0173D89ED0D6C4A6959CC1AEB34CA8B96FC46393FFA35123BC87D580CBA66A21F0F30E30F9899216343D6E65B8FBB1BB5130AEDFC4BE7234AE6665E0D087CD92812437E18C81AF042A55840A58C8C15FFFE182E19D9F156A246CC1D359C36CF355B71076BB6B9F9E9C8C6F9A909CC58F41CB79560D7D849626D6CD1739D90B3067D6B33B9A989A4107F6B0103F0F7F391DE8FABF9DB10F580EF53885DEA39CD96AA8343164EDE94E6CB7CEB8347C24A23C40A3D0C851808B46D5A84EE6E1676626DB741C7674B0D33DAB62FC8AAED40F4E6A9590354B0D24226FEF439D5D89D1B48DA564D30744F5ACE5C61ED8C3AD522D87381E0311850F03B76497AC92AF2D9B7FF8DB0BA1D5A2D63586AE3DD08C4A0462A39441A20C59332D2F07053B1436117B1A9D43C477D3D956E129ABE92D7E6D7A2A383E4F0A19F59F8C565DA746D847368ACC95E7A00581B6A330129AA1A718D0B1860CE775A1BBBE244B04C2D1A94F37E2E360757B9830D2E7814D402E808689C9B02E871061D3B8A6DC408ADE9D9C3B77C8B0CE8B3B23A246FC1BFCAAC2B2635C1AA12AB3EA937237EB224B5E87331B5411A2B2F17214B1A86B7644B2BC9CFC2515A6BF413E58380FD49FE624C0E3DE4FFCE4B880907436F425596A1005D55B366FD18188EE6DE1CBF9614A35CF163268DCB56C76355D4ABB3913D9C31C1AB3E9755A305FE2E186715DC3274EFBC1A7C97E2A70F5D6DC31FAE5C56F4F335D8C77AAAD4CA2DB284ED2E56E79FABE984758C6348B7F195BB082BF5D8482965CA1C6F6BE8D8FB9F0E176BB4308F8B064E48A848332A81E34D28811B76AD62EF9F51EE606F74DB8E98E9CD5D7B2356B28D6A5C7398625549DC0C35E4D44E9CFE30BF8AB8A75AFEA84CECC051D9298D7B91EA8DE1FE7736F1D2038B8D3BD2A1A1FEFF4730254D2BA", + "k": "B45BA5490571D2DFAB9D9204398EE8F141A3FF5B415A2E2A8AA3391263992C82", + "m": "54E7B2E3305950EA570F823FE36A7999E419BB36181B5514860BED41F418EE77", + "reason": "no modification" + }, + { + "tcId": 62, + "deferred": false, + "ek": "4F4504922C38F9871EEABAB438D03555F272E9F9493F005F5F8CAF8A620F362A1D1B90A66289111D03929118CAF31B0AD9ECBB203017A02711BAD26B02310379C117F6F58257F6C6ED5A14BB32760D5A9EA062A9C106064D703BC9E378DF498B347075A7F6515787C500472BFACA0729A4590D39C291DCAB327C10BDCC6B1837883BC90B379B3C32F56C30F78C2A347EE0452FFE4878E2280608265931CC7E123768B0F93EB0081D642B4DC756210952541BB3BE08352CB983911F3B944671B759A16FB28C3883020892865E903045C84BA1E5E54159604AC058056C6153F738745140CB8B5ABE3318809651790EDC20CA5380CC76568DA5915C5AB8272748B42446EFAB58852C619332A08F537C28E93EC676345E0A2666708CB5D5281F981D3B8A19180565704808963B4015DC9B8C06905DA43680402E6B5888F2EC7448AA6578787EBF42329D060998E74B09C13D1C432A17F56D18BC624F02AC7ECB6235C42A24B42639FC490D07A635360932C71E25720EF59340F21836B74AB8F31C2CAC035AEFEA846210AD665A5D64616861F1CA3B963A2C10C662F7AC66298751AB3CE6A64C59770568B4B234129550702375D722AE4BBA5FD0899C84A834E7B7938627C9285912D346099423BA37B25364B67258A121650E895660C8E014A5B08D38B7AEC29175B424C234D2B87C791B60159AE753CB61D240DDD2814F1A7EB69A79AC37634850CBFBE2CCE6E918D1CCC70E13707732A6AB11329A3336D8E221531335BED560A468092CF690D1B8791F58993BEA001186AF5E48A2BE0B3D17656A3ED98BC3628C9F863A2C88C90AF25A11AB41FE7CADBB3C1013B59A115AB83F9003BE28759A3148706B891D9770961AC53D4C8B6CE5788ECA3F4A4A47D7F5165DC7B94B358591348BAD7B8CDA482B26F650DA1765A0911527260703E2CCC703A69F10331095BD3AB167DB52A3EC16B69F233862EA11AA9118FF539071A05066388A6DFA10BA4819D31A03B3980677CC6B888263D74007057C6C3C272464497A58681816C3C59E05064D147F62D5C848B8919C97C3BAC20A43CB58F8CA98EAB48B221851F634459B7AC514161A1C490B8B576A0FB2497A65006EA78F9ED50763A19F8D2C99D546642A68B6C2A49FFF919687E67EF0ECBCE23266114982FDF15F572A9519EC12CB90BDB3516E85E01106B9BA456738F4206F5F0C314156307F4CADC8983A91F730219C322A1602714849CD1B7DF5D02C24758DA6DA8FC8600CA2C1CF7294B1F6598D9E844625C29F589006C0875F3FB33EB357B7AAF0607BB31743153B98D64A8FC56DE56714D71303E9F6A3ED228961E607D6D6C0D4776828B7574A8CA28D837D24470E56F3A6CB6A4A90F5A9BA8A3F60576857E1C7AA52A16E1A84F7421EDF46C312BC83EE0776A9819DFA8B66FF2BB907A96F4D6228FF34ABC68248C1990C2484CBBC70745B045C602C1552B952FE8B4D24D027E1C65B3704945E507D09A9A6AA7000C1607A27591F606AC1D2C5CB55BBA149A15C4B261894EC9A9AB9C3DE446C1832744CF6BBBF949D54498319504BABACB8DFB15F90F66DA9E0B7F8B7A42A7B09C5E19DF58CAD8641C2DFAC77412B49D17A0C02341C6FB78DF00809903835518392D0288907184F126A69BA77863C84C1813835926311EA705433298D77AACA4DFC30CA218DAE405732841605840625E57D7CC3AEFCBA637CF8077ACBB9CBA0744E462D02F406ACB24E9A3C5CC5048337390E4EAA295F6831161CC7FED8938EC6287C8C08DCB0AAE66340C4A380B5B816B8110F3D190EB97C8457DCCB410739C48B8132A32C0CF59028962A8BD1B03F0229C908BE9D22C9AE65880E110977508595F6754776B4203AB1633870C4EACF7B3689A8D43F4C213FA839B7C0281D242452455A31F396BBBDC41D9C4C5F99960ECA0537DCDA3FC6405B139241EFFB20CFA05A739A43EBD39E2A516A6D136F78F43CC5E24C2335CBBBD7335DB820A235129F10C62D13C5013732214012B00C1383E670D5D37484850D2EA49E9E835A750C63BFCB2357E472A4406C6DD2990349987707CAAA1030D4206460848F3C988179E31A4334AEE89511AE4297A668A154270D963C7EB930CD3C35290C9585F428690F88721443757D793D9DF912680C21923138D119B777530A3FBB406E110F408199CFAE822AF8B67807B0181714C1EB366D2750DBA3CEE603", + "dk": "7A8721EBD06F9A1845A2089AA7437CBCDB4B86C4529BDB0043B7BDC5CB95639CA32989550F64296482C8CFC15590444D8CF5C699348C0541AC0224B94435B972BA98832A7B6C86600E8C4AD9DCB0409CC278F01A6748005E7BC06AD00BE8D731E4182F16563234960634683956B58217D1B69848C934840F02C49398F0BBB5EBCDD422C54249C7195066F9F900C0C982A9048F4CF3800A10CDD1858269E59C307B06DD050F5A58C6230A44D8A9979D491A289A4B3C88CD7AA9307FD93DA99910B9F3A97FA759BD25C6D9F3A41677B8DE41CA23D3089C43B584C11C8031205BFCC8A813BE1D5169714C84BFD499A019030514072E59A50E5B7BFBD8A03DAB360E16AB02FB270B434F274A77ED1A67F870C6461A5C641618254C8F2061BFDA921B1E906626CC956758685190017487128D491C07A33E3C023972488D9F504BBF27BBF02CC85D5B8F98E61C59F27B7C879F4CB341FEC1A7B7A13E7FC496B3A511AF593312B17C9691369C10B7E440A93292BB25B501A3522E4ECC1DCE5A8255092F87248C6DF39D9027C5ABA21E10F003F88BC2ABE25B5533C2F390C4C500927DAC631307C6BF17CF511C8927FB75BA1B44499900FE0545F20565FC139BE9A5221D99C656643FCD38CA16756D1D81ABE54971961A60D47C4365600EF43BC97862A41AAC136A396D3E549ED7469B1CF0AFB4D107E9C685AA8BB26FAACBD070B4BC9C1FF502BBF64350902972A75810EF04670EC9A9CB99830FB88C150AADA8C457BD338894A18ED751AE584758E16660C221B7FF538347C05EA7987FA92A96BAC91FCBF0CAE004107C8472E0118D78F0166971CA14E1BDCDD229FB631FBB81CA8D4A3282064E9FD3374D674D3D212DE71B0FE8765E05F66C251BAD690C300858A220A620205239907274B754AF091701E3EC2ACE6B7213190F69187164C8606355CE0C1B3D7716CB7BE1C335B506F2646EF18A092F6B6328A656A66A5F6D534962F5ADA6E335D7F37EB61776A8D26326B639B48C95099C3F801A7F3E511CA1E45400DD1735444055624F1235A21757349502372C4B6C01C96D96D9220D0638C2163CA7765DDEB58F80BB5F42442D20972DC94131EA83B6CB687E6664B66A3736AA29828F40949B4636A4A505B2F7B2EB9626B491BC96B16664B545127957B846626DE12506CA449D13A657EA9D8D495D0F8B1C0CE367591C1186172CD6E380828B1E5C4B0224D0298D872E0BAC79524707F7014369D520AF821BC1F706BFAC6C692C0CBDD9B96B8292EDB27EB7C43530F8A3ED848513946EA1D0BA5FA00784D0A85A528800B1C463440080750C7AC6043B0529F73B29B40358F457A68E164855E7626E964CF5DC2011DAC25DE82EF72A3503280F3F23A058783625E68D9480ADDBFA4FFDE76F5AE87ACC209C43C65F11F652954A658C86C9FEE684BB1B7BF73211EA002A25E1BED40750D41CB3665291843B0DB542BBAD481D6B3B021DD8635AE93D60D07807A95753C79DE35829DE5C88DF095301C433130A511210792624A8556379B0F35D9E3A2E583B24B1BC587D038C5C59BE09CABEE6597BB9CA49AD022E35C7319CE928140A026D05B9761AC129524332151DE9E65E4E9A0289032E5EBB7A47A82AAE9BB2ACE6AD16162336BC8507C0C24AC0C4A2D076D929A67AF8959EE472E14CA87BD0B89076AE9B4C3F95E3BCBE8815AA7A849F6A385A8B0756917A3EBB44122989A49A33517657D67021D2F6BE9D64A1ABE9B8C590A9EF81043D19C556B97DFDFC03D7A4173405C8BD38235EC07BA7C80BD97B4566BB89C227855673B63A09925028C24834ADAD1C26B7D804ABA3110326B5273B8430045B2D317B1770BB3FE592BBD32F55244601F58583580431C35BCC955C9A5656A3431B943A7E03D5B76967749C886458348FCF9CA7487A66F9B0AB3D92462ED192D19B7D8B58532B09642F490940803EE97576093C5C32D1A4770B86E7F58530776B5BA1051F1B1F35309ACDF97319846789292DB784259185B80C3B0288D103CC1C2E4E23B97E9B140E18B34AE8A4484647B66430996844E73B0A0F79A6F5179234E22C8DA676A379AB8EDA542DD1921B481E866422BD0822C2FC33391293EB31B31D7A9574E31D7E070FAF298E46BA8CEA3001FA0210A6890A6C68B73DFA519B66A23ED78D4F4504922C38F9871EEABAB438D03555F272E9F9493F005F5F8CAF8A620F362A1D1B90A66289111D03929118CAF31B0AD9ECBB203017A02711BAD26B02310379C117F6F58257F6C6ED5A14BB32760D5A9EA062A9C106064D703BC9E378DF498B347075A7F6515787C500472BFACA0729A4590D39C291DCAB327C10BDCC6B1837883BC90B379B3C32F56C30F78C2A347EE0452FFE4878E2280608265931CC7E123768B0F93EB0081D642B4DC756210952541BB3BE08352CB983911F3B944671B759A16FB28C3883020892865E903045C84BA1E5E54159604AC058056C6153F738745140CB8B5ABE3318809651790EDC20CA5380CC76568DA5915C5AB8272748B42446EFAB58852C619332A08F537C28E93EC676345E0A2666708CB5D5281F981D3B8A19180565704808963B4015DC9B8C06905DA43680402E6B5888F2EC7448AA6578787EBF42329D060998E74B09C13D1C432A17F56D18BC624F02AC7ECB6235C42A24B42639FC490D07A635360932C71E25720EF59340F21836B74AB8F31C2CAC035AEFEA846210AD665A5D64616861F1CA3B963A2C10C662F7AC66298751AB3CE6A64C59770568B4B234129550702375D722AE4BBA5FD0899C84A834E7B7938627C9285912D346099423BA37B25364B67258A121650E895660C8E014A5B08D38B7AEC29175B424C234D2B87C791B60159AE753CB61D240DDD2814F1A7EB69A79AC37634850CBFBE2CCE6E918D1CCC70E13707732A6AB11329A3336D8E221531335BED560A468092CF690D1B8791F58993BEA001186AF5E48A2BE0B3D17656A3ED98BC3628C9F863A2C88C90AF25A11AB41FE7CADBB3C1013B59A115AB83F9003BE28759A3148706B891D9770961AC53D4C8B6CE5788ECA3F4A4A47D7F5165DC7B94B358591348BAD7B8CDA482B26F650DA1765A0911527260703E2CCC703A69F10331095BD3AB167DB52A3EC16B69F233862EA11AA9118FF539071A05066388A6DFA10BA4819D31A03B3980677CC6B888263D74007057C6C3C272464497A58681816C3C59E05064D147F62D5C848B8919C97C3BAC20A43CB58F8CA98EAB48B221851F634459B7AC514161A1C490B8B576A0FB2497A65006EA78F9ED50763A19F8D2C99D546642A68B6C2A49FFF919687E67EF0ECBCE23266114982FDF15F572A9519EC12CB90BDB3516E85E01106B9BA456738F4206F5F0C314156307F4CADC8983A91F730219C322A1602714849CD1B7DF5D02C24758DA6DA8FC8600CA2C1CF7294B1F6598D9E844625C29F589006C0875F3FB33EB357B7AAF0607BB31743153B98D64A8FC56DE56714D71303E9F6A3ED228961E607D6D6C0D4776828B7574A8CA28D837D24470E56F3A6CB6A4A90F5A9BA8A3F60576857E1C7AA52A16E1A84F7421EDF46C312BC83EE0776A9819DFA8B66FF2BB907A96F4D6228FF34ABC68248C1990C2484CBBC70745B045C602C1552B952FE8B4D24D027E1C65B3704945E507D09A9A6AA7000C1607A27591F606AC1D2C5CB55BBA149A15C4B261894EC9A9AB9C3DE446C1832744CF6BBBF949D54498319504BABACB8DFB15F90F66DA9E0B7F8B7A42A7B09C5E19DF58CAD8641C2DFAC77412B49D17A0C02341C6FB78DF00809903835518392D0288907184F126A69BA77863C84C1813835926311EA705433298D77AACA4DFC30CA218DAE405732841605840625E57D7CC3AEFCBA637CF8077ACBB9CBA0744E462D02F406ACB24E9A3C5CC5048337390E4EAA295F6831161CC7FED8938EC6287C8C08DCB0AAE66340C4A380B5B816B8110F3D190EB97C8457DCCB410739C48B8132A32C0CF59028962A8BD1B03F0229C908BE9D22C9AE65880E110977508595F6754776B4203AB1633870C4EACF7B3689A8D43F4C213FA839B7C0281D242452455A31F396BBBDC41D9C4C5F99960ECA0537DCDA3FC6405B139241EFFB20CFA05A739A43EBD39E2A516A6D136F78F43CC5E24C2335CBBBD7335DB820A235129F10C62D13C5013732214012B00C1383E670D5D37484850D2EA49E9E835A750C63BFCB2357E472A4406C6DD2990349987707CAAA1030D4206460848F3C988179E31A4334AEE89511AE4297A668A154270D963C7EB930CD3C35290C9585F428690F88721443757D793D9DF912680C21923138D119B777530A3FBB406E110F408199CFAE822AF8B67807B0181714C1EB366D2750DBA3CEE603BF822762AA356CDBD08EADB7D166690F4A00D797419ADCCB9133C3E5EB671B5654CBE9E686EFF218AD6583359070544146921F5107809454E73FC105FA7A9A0F", + "c": "566EE0837DD0AD41C30D9C318F736E6722D037E07BAE16234A2051509180D399518883004079AED8B2B6E18A2CD1E2056DB76EECF47C3E1268A5E662FA6D029F7EEFBEBE1587919346CF7D38C6DA819D7A3A89B2BE65D6E2F87A6F348E8F9C67F99B5ED655B5C0A6AFA15DA8CBB310B364552195C8F70B37F153270322E5E45B86F074EB3BFB3B03DAA7E81B474011F2F3DCEFC3CACB7E701B1AC7DEF0650362CDF5F6531E5E5FEEC973208124DD22BE3167F49BBB9F160AE159E692C007801E1FEA10034A20EC460F72FCC57C9C2E6CC749F5110AC6CD7A20B6CBAEECC6E6C5FA131F09B19EFDD175420B2762E4CCCC03906524AC63C6AC92B1995935A83B674299095DC4D2E26E3D31B8A4D71E9094A4D50F76DEED368F2DDABA358C306646AD0148408F8B8E6F5899F598CFDAF90C9CFB50A285150692EA3955EB4FD80BE445777C601EA5B59EE07E5B828BA576F6F300D674973D658A8D4B6967C3A3ECE68BAE27A46AFAED43D3392B985FC5BC7D79B0D56321316649FCFA84EA05F02EB8E3142D72C06D93FA73451CC0134B53AE1B038B4EEF71946665AFDD50CF3A33D188389DA9A32E7B46DEBA552C337DEC2B28CB3570DF15A229AB8D3FD86277FD5AB595A0ABA2DAFB7AA62F2CDAC997F13BCBC93A42D37CB83A52FAA8B01F8C97D196F1FD7A618566CE8593BE11DE0437D2F82476E65D522ECC3D8B1C247ED0EB7590648E1A51057F953F0932A567B799BD431344E1E0A6211BF07CCFB0B53DA9D39C59C4290ABA2930BC691F83830779C89F14FF6643D277035E5711333979D563DD1BD4F52295D45C98A60C5D59AEFFF4ED119B2D88C7D5C7E7EAE0F58207389547BA5FA995678A94D7127C407EA0BDA29CC8701B83B27447654B156461226BBE337FD69BF0FCC99013646751BC53D9070568E4D2C0DB6A06CA491BF80EB6C2C5807542CF6569BA84B88EAE67FCBE2DEABB56A5D06E945F8389EB68ADCDBDF0CD9018ED713BE071A0A87415647A97DBB6665C09C5F27899BED8837CBCE0010C70D7D04419240EDAA185EE7AB14A1C55AC6546ECA6781804997AB2B15CCFC9035ED7F170CEDBA0E280195E7B2C2C33CBD5BFD10CA8A2E82D977762BA6AE5476767F7E9FE787FBC624A81D1467C26CF2C1F1B1BAE476522DD198FB9FD5130EC41DA3683B788D07DBA2FFA0D460B66E5967D161AF00E61388BF317897E30B35BF8EF1A580DF5071471808E764E01043982082DD2BAC13DCD049B1DC66D44A670EF6E063B31AE29F391BBBA0ED0ADBDE06B0E5403B68BD1A4D997EF3F965E591D8CE8A0843D64EA4554FAB3DC9D5A96540DC2ADA49504F25213CC4EAD1E097E0CC516A4E3DE6F272D8DFF93604C39551E8F848E349315F46011AADDAD6F0BA68F1D6CCC68AB6AFCDAA1D47FAFBC056A063641DE73414C26D997F243DDA0817AEB734BAFD35C59F86AC30D45D1E5A0FBE63AED51B02E6C7851A858D5E0C23E53DE1DD0413D408F665D62F24FF2F314A283B7E3848F1E17AF5000BB9D279C0647C1434F783A1A21BC7A8349D62AAEE19FF06677F81C954F9D6A69ACE7BE06518ED800923C6ACB36842CE65EC81749C388AA92164D28FD34D75637F23C49DBD74353181655EC029593BCA3214C73A540CD9C3F6B1056A2137D0C280BDC90C13E973555D8C4D64531CB7360F1E67C1CACBE9F2D59AFD3BB5962C4DEA4FD9341D87E0DF55D344F4CF0A30CACB8CFB10D4B6B07AAA6B28CAEBFBEF4F0B4CF6EAD9387392A27DDE2C4BED1F9908DFCB9E1383864AF6B9271F0C265D2651919C66BC5D3850CA741A7705D0B4F7D2FB82DBD376079AFDA8523756200E6E400BED88992520429215C3702C97721D76F0C9EEAD7DFD2ED0D604D6BFED6D942DF0AC48ECE1BD16FB35A301165816B0B4DDD881255FCA8C2EBD6A4C1ED56CA83CD868AA7EFB0199709DAEC10171B870D3A9808809FF0670BC96B66CB45EE5D0198146C0AF1CD920B1E315879E8D24ECD8DC03F3E8C43A973ECFD91344F2E9520DE4922544592C26F085D53A7AE03A866C369366A4CD78EC059E871C90996CB4463F21C7F0A9914E38ED324743570818FEF155915F2E1087744DCCC6B6DE8991371DEAA4DACC534974B1838BF8A98066F20B07B809936A36B6D4C4CBEA220B16241FC875DA5D5573FF74E3ABBD2D110FB2B288136857CF5F0AF36E226EB792BEF4CB79A6A8741FFE20E", + "k": "27CEEFAB9BC1F2050BE2874B3A81CF1148567A1E73A5DFE89C640C0C88F35580", + "m": "F2C864FFBDC366EB96BC5F5FDE0D4B3348A07E861D9EBA90E70896F7FFCBD55E", + "reason": "no modification" + }, + { + "tcId": 63, + "deferred": false, + "ek": "44DB8BD3C4B5FE45CD408B054B878343261AB8F812BC75A953C8617582B10D789F7114A00E0166EBEBA0BA149370639BCF020197F82080BCBB9BDB49D15493114698079B7021C55CC275612D843FBFEB0F2B86CB659C6EED1CC5661B711621320A85B307C96F66C4C35C3081410045AF4B898C2C14B645AF9E0C9CFC03BE42DA4DB3A759E77B7D6894BF380991C3D4CB0D5B2CFFAAA08DF0085B8555228CA8E18672880C4F96E555F879C2CD6740960B94B6A60BE7557D2E230083D757DF76506311BEBF28C5496C00F338594AF41AA15566B24B004E60956AD09CCDB034B7C35BC5D550F52828007C1F85503AD86A9C811C440E6600B16CCD51EC098AE298042C128494A203D20BDB4789C4314C8D14543C9553954C9FC34C40912862500B2F3A5929471382D3531FC9767CAE6937D6E37D6AE18FE5B858BA968927201912782C6D436851C80E7AB0782FC5AC1D9C2F8CAC0D6C29148E220EB30909B2A43A4322B90E741C90C19AD52CBC1527CCC883209952A5A7C68E3E580BD987338BDC75FA84CDCAC3A0990246A7050E1022AF89C7165E45B32ED995A8C4B7FB28999E4CC2C79250DAB67119AC2C6B5B195526439E17A913F3BE3BE896E8023AE6A78AC00244B8EB2891CB5634955F908424C4B77BFDDA017D3B71909320CC53C4D4196E0C39701F8839711BCAE59BAB4B4908F5121B931777E17B331AFA5E955B5CD5840A734A41E35CC016C01407B02039B5064E97C24F4B9197091DE6AB22D0FC0459033EF7816D12596CCEDA120F534CE74571A4E668F5C1488C1503BC0354161BB651F673DA9019C9A83D9D97381E72CCBB1628F8F9A42039CFA07B1D67A1AC37407319360883539E7E060D32469CB9D87DE784439D2B453B77C158045F4BE5A96F090603963A18574FC027C0A0597D6A30B9235ACF5FD49619F47F7E8833D5D719B9F95825571B32C17B0B4AAE2DDB7EC0B14413E73EFA105EA308AAAAC76C2A257DD4A36407468802703787C4AF27D21EDD08108534AE994A1805AB5E6235B88AE7C6997374E50C1077F7702F809B092368F43A9CB2AB539FA104F5B23A4E69B9D46C4452208E3DCA58CC1045955784C82099EFB01ADB86CFEEFBA1EF3A43F16B7CDAE28A3E74C24B6648B8F20AB88088974B75BCC79E692C57501783F57434B7C2BCDE20B2E7129857EC9FC95452BACC9D96D89CB892C78CA07E790906A6FAB62CE170B63443CBC9BAD6F48B383050FB788270392F396C8CB8A73D4912115C41869D54AE1AE6173A34B6C3C91A5F6C39DA659268456E0B51389D7B05D4367C9F5C6CBD371E84EA9BEEB4C09DF9205296B9E947BD4E086A97760CCCDBA94A2108D02CC6544028E05A2FED297F32491042241EFC36A24F634DF3626A217ABA75882A050B7569318E8E00AE8A267EC0207CE9E8A524E1CE8F8CA117B0C77A680231F773B756152878363A9C38D93423C0378A60C8AAF8063BBD1484A3F37D055215A4403AB3C80DC9223D91165BC2D077C71A49093548D4A32922633258844193759D4DF26E1CE367C3229FECA492A9E7669ED4158CC08D9FF0C24027AE9759A517DACA6CD58090D5673C753101987B8914BD8B71C552D96DD093257A9313CBB757AE42860790AC70A593ED65A492078B6043B7B2AC4CC7D85A7145C6EE210C26D60906A5571AAC3EE71333155055381281A584A66C090252A3CA70D9AF09063F3DCC9BBF020715126122602AC9F9930D59669647CE64F356DA97A5C1740BB283781C2A10CB161BAB6B709CF9AC7C7911A23A9F4D6507537C497F3BA5CFE52AE9E34B1D9922669520DA2662BAA0282B33C5029145CC34B0FA9CCF201C6491E12646DB1D1548C0FBF6C7925C9670F4ABC84AB289958A26A9310ABA90CF8C41B39B7DC96673724CBF4BCC7754A71E3158B35214A8706652E11621635C5B6AEBAF64365497518D5D1B6635178E318569D23C50C3683CEEF593498037457C4494F03C7E92C055BABEB96C70EBBA20658787C1B27D6CBAB485741712F9169E3265E376A0241A36C0B2303F8865E6AA9D89213CA1F874E758A569E4055D70BB1B512C0845B933E470B1D9730B5024F520C8F2221B9D49836405525EC3864065BCA04A6AFDA11CC59A9BC28479D9D0B42B1B733E186D50B603CEDA34E8D283AB0939005B06815FD3531BAD6AA926F931C478F71A699A17741447FAAF6CF360D4C64098E9F1", + "dk": "1149A69B309A5FEA7002DA1B0D4B4A45A37D863841D68452692A96223C203CC24B05285915D48F00091A033328ED12167A4BA398A9BBC5063A0A28802CDB3D8B108C359601AEDC31AB8C8729E81DF9828ED5900715264EFDD3B0C77176D6D0ADE200685A239CFF946EAD338351A54A82921E9CFC6BCC60813F2873BB50C1796276501740FE2554E130A01DE941D8CA3A0B37318C467D893491718BA84A26A4229A06476986C668843198C12F034178064D4A4B7A889C921C49028D6B9272497A4C0C6E03F78C6433538484C3B5D662058BA9C9E9B474E636A4E20CE194BA87F98B7EE4A26D4A414A4C4D97A3A1F420885098871D2036D6E9A2FFAB978E217996E64CAFC34E30F453D2E1CF20AB6747D1C0931A23147052F2A30E1EA07927A28733799F88FC8199896EEBD324845119D03838F17286F32A7F1EE89408606E66C72A546333E3E714DE56467DF46AA6C10CED9626C999506AB60DD5226259762D6A028E2B4798DCD77217073907962DAF17BC6E54B11A8618F97104602250DFE40409E615226077BE778D8791838CB1B11A925AFF9622BD4328539CC015BC321E9CAEE3699B8CF9C075376E6F2C50C495821DB1903C2BC04DAB2BE90913CF845C368BABEAAAA79E998D1F066ACB67CBBA673FD3C1014CB743060B1DB2A93593C316BD982FE9FC24049221B9BBAD0EAAA47561AD4B81C81B46C69FD3847C8559E77A368C57520329A06CE7542C4771039072500AA324B723FC96605BA225654008EE7BB68AEA14843B18D3977B050914DCF2BC77A91EA7C4B46ED04CBAF47B2BF04129B05644EA360F3B69C2867FF7F5B710A4947AB29BC5882BE2169E5D7442D659CFB46BABA459869FD291B9D505181A306394AB9643810FAA68E5534351D3744E4CA3053AAAFBDA7523A33996BC344D91BBF8B7C41B1998C2623F261A94DC123244AC9DAAF49902D407882B067D12C1A835A5AC546BF99C2264B525F9628EEF5BBE78458A103236AB8B37D67A5EAE21369BE740D4D3B567242517404A53A049C3076C310560AFE9AE495557699B28B2DA72B91720A1524CC265067BD3227381741E0410F19C960E0B8AF48CACCCD70002403884A95E578B04864A81BC1737373135E9A2573B51CA9CD4C11A8248C3122C5192A3ACF167FA1A21879C09A7C21754980485A3272D8985A0F52A4CF77813AAC828231B06F4BAEC5B15D55638F889679653458620C54B45BE8C67C6D2FCAE05368741B26E9F6646D0142298079740A61A0743A10412BF2C4469D60C6B08966F1180C4B3C83E62D3B0E4D13AA29CB765D67A97524D1AC75A0212928766CA29114B906A93F42CC0CF1B2B6A6C2948F80E9A5954120660BBB2B1B42297B8C53D9BF349A86327249779C4C41442655D321A55F12A589CC62F18147599C6059D08B4365A3DE541C845FA37061C13338A8A1475BA67C12F0C67A3430B7CC53A46875241D3359A64F104910B73763197C5E1A88D5B1D05EA98B97524D4B9A59A7655276905D6B1662EC9C638AB0D8B746D93C9CFFAA59EAE762A54096B124344B0F4BC7CA6696D53385554B115C2707E203C6D161D14B31025F336C08B17F907442E369A54F404CC6B0DF3C62ECFC805C8D967A29A1B17030EA26C45AB71684F7A6065A8715AE7A37D6C5E3AE25A862B3185FA53C0424A3892197A339A6EA435264798948462F8846DE6A04C77C951F3C5C9262B16D3DC8E7D7B3ADFE75EE3CC84706BBE9B830DC0972C15E404B147C4FAC09BF089B057E5850153978C8C625513ADF872A30FD7B1D9F69B97AC123E11A611C6A416B4410483894BC8AC738B3E0A9C0D7F611D88611A5C62CAF879307A20732F17B26CC52531B447894193AD45497D64B8562193F670C8B8AB1F74DA79A945B16E01AD18006AC222345C20CA5B2099E9818E0DD155E14B64215C88E0A72A57C6574C692AFD1A382EB832F6033E8B78AD68BB60CB218F58908B92533C635A4D41723DB231BC2CBB5B7AC03D718A96D3D80120C79AE43493A9404E3BC46391721F68F80FEB7C47CA4A79BE9618480344D6790402799AA5E155F2E229C45C970E772D517995493661A04A2CB8FB90DFB056044616669096ED51C8E2F131B5FC729DFBC876A412024C692899540334071DA2911EDAA7D1C49FF6C96D4C4C2A51199B44DB8BD3C4B5FE45CD408B054B878343261AB8F812BC75A953C8617582B10D789F7114A00E0166EBEBA0BA149370639BCF020197F82080BCBB9BDB49D15493114698079B7021C55CC275612D843FBFEB0F2B86CB659C6EED1CC5661B711621320A85B307C96F66C4C35C3081410045AF4B898C2C14B645AF9E0C9CFC03BE42DA4DB3A759E77B7D6894BF380991C3D4CB0D5B2CFFAAA08DF0085B8555228CA8E18672880C4F96E555F879C2CD6740960B94B6A60BE7557D2E230083D757DF76506311BEBF28C5496C00F338594AF41AA15566B24B004E60956AD09CCDB034B7C35BC5D550F52828007C1F85503AD86A9C811C440E6600B16CCD51EC098AE298042C128494A203D20BDB4789C4314C8D14543C9553954C9FC34C40912862500B2F3A5929471382D3531FC9767CAE6937D6E37D6AE18FE5B858BA968927201912782C6D436851C80E7AB0782FC5AC1D9C2F8CAC0D6C29148E220EB30909B2A43A4322B90E741C90C19AD52CBC1527CCC883209952A5A7C68E3E580BD987338BDC75FA84CDCAC3A0990246A7050E1022AF89C7165E45B32ED995A8C4B7FB28999E4CC2C79250DAB67119AC2C6B5B195526439E17A913F3BE3BE896E8023AE6A78AC00244B8EB2891CB5634955F908424C4B77BFDDA017D3B71909320CC53C4D4196E0C39701F8839711BCAE59BAB4B4908F5121B931777E17B331AFA5E955B5CD5840A734A41E35CC016C01407B02039B5064E97C24F4B9197091DE6AB22D0FC0459033EF7816D12596CCEDA120F534CE74571A4E668F5C1488C1503BC0354161BB651F673DA9019C9A83D9D97381E72CCBB1628F8F9A42039CFA07B1D67A1AC37407319360883539E7E060D32469CB9D87DE784439D2B453B77C158045F4BE5A96F090603963A18574FC027C0A0597D6A30B9235ACF5FD49619F47F7E8833D5D719B9F95825571B32C17B0B4AAE2DDB7EC0B14413E73EFA105EA308AAAAC76C2A257DD4A36407468802703787C4AF27D21EDD08108534AE994A1805AB5E6235B88AE7C6997374E50C1077F7702F809B092368F43A9CB2AB539FA104F5B23A4E69B9D46C4452208E3DCA58CC1045955784C82099EFB01ADB86CFEEFBA1EF3A43F16B7CDAE28A3E74C24B6648B8F20AB88088974B75BCC79E692C57501783F57434B7C2BCDE20B2E7129857EC9FC95452BACC9D96D89CB892C78CA07E790906A6FAB62CE170B63443CBC9BAD6F48B383050FB788270392F396C8CB8A73D4912115C41869D54AE1AE6173A34B6C3C91A5F6C39DA659268456E0B51389D7B05D4367C9F5C6CBD371E84EA9BEEB4C09DF9205296B9E947BD4E086A97760CCCDBA94A2108D02CC6544028E05A2FED297F32491042241EFC36A24F634DF3626A217ABA75882A050B7569318E8E00AE8A267EC0207CE9E8A524E1CE8F8CA117B0C77A680231F773B756152878363A9C38D93423C0378A60C8AAF8063BBD1484A3F37D055215A4403AB3C80DC9223D91165BC2D077C71A49093548D4A32922633258844193759D4DF26E1CE367C3229FECA492A9E7669ED4158CC08D9FF0C24027AE9759A517DACA6CD58090D5673C753101987B8914BD8B71C552D96DD093257A9313CBB757AE42860790AC70A593ED65A492078B6043B7B2AC4CC7D85A7145C6EE210C26D60906A5571AAC3EE71333155055381281A584A66C090252A3CA70D9AF09063F3DCC9BBF020715126122602AC9F9930D59669647CE64F356DA97A5C1740BB283781C2A10CB161BAB6B709CF9AC7C7911A23A9F4D6507537C497F3BA5CFE52AE9E34B1D9922669520DA2662BAA0282B33C5029145CC34B0FA9CCF201C6491E12646DB1D1548C0FBF6C7925C9670F4ABC84AB289958A26A9310ABA90CF8C41B39B7DC96673724CBF4BCC7754A71E3158B35214A8706652E11621635C5B6AEBAF64365497518D5D1B6635178E318569D23C50C3683CEEF593498037457C4494F03C7E92C055BABEB96C70EBBA20658787C1B27D6CBAB485741712F9169E3265E376A0241A36C0B2303F8865E6AA9D89213CA1F874E758A569E4055D70BB1B512C0845B933E470B1D9730B5024F520C8F2221B9D49836405525EC3864065BCA04A6AFDA11CC59A9BC28479D9D0B42B1B733E186D50B603CEDA34E8D283AB0939005B06815FD3531BAD6AA926F931C478F71A699A17741447FAAF6CF360D4C64098E9F1E5AEC6C6BE5AE6CFBB5E8B66EAFEFC8DDDDDA717B32220C994BE42776B296D9F7814DC0CDB963F257E983581EFD3A55A7B58E09734B10FB5A6F1CE03B12D16D4", + "c": "E4BE80FBAA47E08AB72D52DDAB90B35FF1F4C1DA793739388E49A548C6A1EE07770C6FD8153A3984AC2800150B20E2347DCE0A06D2C83D2A203DFF7788C969C969616FC1BE122067614989F34D0D84F9CEA1767D0D9D83DF8C573CF4A3EEAA6A0147731A373768DD38505BAA12C18B524FB2682BDEF71FEFFFCCAF0A8CB4F42A3A1E048DF6A66CF898A171FAFC840B46A8994F7D9A00CA42CFC2539FB3404472A39EF65B0AA7A376A421FB55B619E65C295A51047EC80334A7B40F3925FEAE500350D71139F6DF4C7EA9655ED2C869A7DE115FF7E926DB881E3372D47079FF3F48A944DBA7F70B0AE01CE961F16CBADD7C57A94EBCEEBD709B414F7DA764FCDA39FF044FB0EDC16BDE8C68AA7DBE92C1AE3C226EFDB7C5F1746BB56FAA7ED34B2A32C7A95A05EEB7E75DF4F7BEC3EB78B74A058FB95C20B33EB9E30ACD8340B685CCA66F2D1F6737646F67B28CD62FBEDF708A4277A8B6E82F012895438D14A3807C087BACAA432ED6A099470E28E4B06B64CF6B249E4AE72DB468948E874565ABA879FC3322A1A89881C55628C37781D28B39102E97E74F0921932434ECB061E6C388611217D29E16A0DDAEFDA0B420DCB83D5FEC1552025A98C4D6F19D6C1E23E934842D07856CDF0E5A9E8CE20F68C8425C8D54F7216B6B66BC3E1ABCC6DD5841EE0E1CC5C7BDC5A7F729A9930CD4BC946A33D6534ADB2BE0DB65490E58075FE3A8CFC273AFDE116A6A4C317177613DC93AED69D85ECEA4C55E43DA1D08780B30D7FAE75BD1000043A3B56E58ADE657679A54E3828A97CBF7436601408E5C00936D4BD3A4137E75AEFE338C6843EF3626FAF2684C6AB8C3F3A04773C913DDC72DEDEE9D45E3F0E37A3D8D5AD2D3DC9CA90B0CEB666C646F265E5A75D3D6F7E2455E11B5866C9D620FB2EF4D9CE86D0106DC84B35D603985B2562B3FA0BF6868313907B852F4B23E2AF6840C808EF8AD8A7B51456CE3CAAB34CF68CCED6A81EC1F9AC7E090AA1F854E275169C888499407C52CD6A7E1A7D572E31BBE6365056686E53A430015E330E89CEC44BA98A1DD6872FA3D4D71B19C65903DCEA30932C2FB94CF8233F26D50EDF3213A9574874B0AEBB1B6AF0807F352C40E2945A134EE7DF88439ED578AD4E2D7EA11D0C9C6CCDB83A03B6B9D026DEF328D2B3DEE0335C8092C46381E65B159E7478C615D14C2E800126ECF70455C3B4DA925F36C186DE2AE1B22D814F974D5BFB988F7D09140AB99A662382EF56370373DEA434AC42D1664EF116E92A90442518FD84952C7F35D0F42859BE3427C4F28741335485258756B00E2A90E7CCAF6B564326D25D76CE8A6FEEBAFCAE375135C1CCCCF12D232A0B062FA46F166AE2D99A36DCA64BF2F55B0151F64028700F831D26E62C41DF8DF1A46A8697C5A2F8EDB75C910CA1D382BEBFD3A4521E174F4FB3A258AF666501D00ECA819D310257E7AF85F4087AD1501EC4E18D1661EAF75F50BCF8DC80968FEF78770065699E8A857C12E507D88626AF509A2331CC228E1A2BB3526B687E63EC763EEFB375FE751EECFEA143BACD4455E8F6E1ABF0F82E4D41C5CB770BDFC3F78150D584DBAE744BE4C20199984445F435BDB46454D662F41C61A848A7C887C1A04D41D4B92EFE657ECDB9387E84495EC37CD183F9C2EB5E859D722A614F3EEBFD13FFE2491FECDB4DD2C06914EED59F8211908516C799AD7B9B46C5EE5AFA808B67B1E36F81D9DD3C9B27188BFD40495BAAC44DAB36AC61ECDE47CDFDA7AFD9C40952AA477818A38E3060613D879E78874254C599697ACADD42F1049A3E5BCAE75F88F7771E294EFC9D3899DCA955263671F5205953D62378A310FAB336EAAF4837CE6DAAEF1C4A141F6192E934A20AE23BCF803215B5A96D6CA99EE65A205EFAF39082A42193C5090783B426B35A1C8BA6A6FD00D3341ED24008E1D70946E22126F7CBD71A49AB15D2561FFB4DDE90A497A89049B22BE50905B63107BBBD13E5AEF39FB761091C7384519455057CC407FFAD746145BFFEE33E120922E06FAAD8C5349B46B3133B4EBF1AD9C84E9ADF35B5DFCA3141353A1766C04907A6CE0C3E9C6D84EF9E732637AD033829B13E0B9526A1C8BDF4296AB460B32CF29845888277C479565EBAA7C30811D2DA71BED5560A5688DC18643818FAE07D531DE7196B947CD1D94F4447B77CB48F82DAC0C7404E302F0445B656475DC65608B", + "k": "0CA16C93880B3BF4802D0EF7F03E5C192440CC4B399E9A55637F1E6AE6DB225E", + "m": "EF29D988D373C381541AC8723EB67C68CEDFB9DEC0FF2B40CDC763378B380C12", + "reason": "no modification" + }, + { + "tcId": 64, + "deferred": false, + "ek": "E2C18353FB0F024A0E05FC7F0F14B49A9A36CB49CE7EB963A2C20A5228B0B6ECA4AF63A1F7B1B8260B64D2F2C0718397F4F402A0946C9DE5B0F083B57903418C30BD7CC321574531B2163DDDF23A69B04B1D393C5916280DC11485FAC369D0AD1C85656D4A6A7BA480FA5ACC1788AC37C9706C26A357D7821D636078FC2204530C3D3358DA002F3136CF033443C519B6C505D00FE92B04A305A890267B238882EA9010554A1671862BE8097B67B8E8A37E8F0A5C96F94FBE296162AB1FA456785550AEE6B05A80554606B76714AA91C5E7B747A2005900077874CBD91970111C800C49CF05A4332570863929497AD6617D1B5614F2670390574F554C7D337417C792FF8953143638F60A7BF9517890D56D02039AD30392DEB045D8CC4994274E5CF83B702784637C6D53284F4F14C15335A86A642427E589AA454C6FB9707155BE23745FEAD04EC1CB07DA341F7FF1B6D17C315BC3282634A39C9104392B1D12222E8D091AAC69CD5A72276B01BE22FC3C634B41AB613DDC602EAAA00A72478D713C7A0F895880224CA8489E6860868A7B72CF876FDDB230C55C0523342C5F42B0A533A8FEB798D3104145E27D29CC96D54301D5B07274F700B9201555430D8EB961AA7C3307B0B56B479BCB6147D9035D786A58E7199F6BC9335918204A345826446A50801603EAC992E93FB104B834D7220B1494FAA2CB1A59650B00AAB00AA15F6909DFA969DED0B540648830360ED052661557280683084B93B746E27D916A05C96CB73964A4AE15CEBF4C84A1528506A69D2FC27A2A16CF270A09654A8B566651D097C61079A859171BDFD35262116479742DF74C0845D596FB83984F27811FF81CEEE0C37D618B93321A7DF0C0D22124CF521D92715EA7DBA1DD6112E9152CE2E15FED4769805A5857896EDAE13854648AC9DC26B770109372929FA511B573685D7951ACF21BDEBBC97D384D454B5625059A7EB8034FB4533F55B897B77930F3911F2808F54944CFB96BC0CC5AEDB8960A9C024984CDE756441C6381B3E38909DB3E85A36408C5414B471A68093B188134B3F54C751061093C4DEEF54891039AD71A74134806C7F102CDE67432D37DDDB4ABF33987A2AA47634C80260B5A246758102C864B2B40613C42425313855897FCC835C7C587B007C94760AF26A1531CEC874B9C492F4AA4C97567D6A61C21EB00FC52B1E0F24E9D680F8FE38B82243FD0B562C0DC86E2024593562B4AF4A682ACBE720813859B92A9C20DEEE4B4FFA1A1B17A24C394455077450B4C2CCE67A0E5C4016C746FF508A1DF89A5BE2A2A7B866ACA0A72A603843949909CD16DA542068604A380741C32E986366749CDD461A4362401CB8243613A2C442983B52C681A3CFC362FEDB337910668C5732906C41637778BFA619D502640545715F709C31B506534C0216790779EFC053B4A7789662B989A75C6580754A92588A30617E960C714171C8310A2802092261A85A5C882D407AE263A119B3E68E3BE158BB0325C30026BAB21D30B09637A54FA0A4B980DF807048F139223D33CCF206FC68672113A55E2084B6700B396F68873636DD8E5479BC0CA3E47B52329BD7F20681D5C2208AC0DE2123D50F6023A4472B0300CB3F8865BF7B49374AF01B002C4087BDAF4CAAE4336AA3A78E3856DC408B04E9AAAE77C464351C97938CAE829171BF724A8779C7FE20E5FC254D0BC283B773C2DFC83D28C3E854140A81267C2D2C67F361DFAF623D817B1655CA8A626A8A91BB088F539576C8795CC8A53044FF547B328377F4D17273AC323E6481CBFA058CCC456741057F1F668CAC51F34D666AEDCC176382037C674B4793104A4BF6B336E3D59A1C43958FD827493CB956C046025737B7FC0A3C2098BAB916E397191BEF5CC13F3BA0FD98F7A25BE0CCB113EE081B9AC808E2C728801C70CFBB2BD9A34469C064EA07952BA0D579380F7E782D0D5C6E1C26F3E17619CD47D4BA88C61600721BC2AB3C50F591988CCD77AFD3C43655272565401AD0778671939636C8BC24C794FB73EFFB99232503A0B50030A672CC8C2C0FDD5CD43B131DF0C9B9F867039E2A2B41B3CFB1A82C983AC54E002388692AD885C676AC2D7D0C5645B06A2684E9463AAAFEBC6C07709DC68078F7BCA36F5584579C3E3261D319A58392518ED507ED54ABFCA95CCDDB6C74949DCA48D01DBE3525A0BD91AC78428D5A930A5", + "dk": "A5AB9B1E9973958172E182A9133A3DAB22806CDA0B88E72BAF581183973220061D836405C702A8494422B43568291CC432443543270DE0B7C85C56AAB20C0A17617C13B9903458C20C423A65092533AC4BDE6609E90711BC031A953C3A3139960F14CB17F8B3C3C68BBE6B84271AC5F003898A79912DB2B68A1C05AC204626C0275551BA6BE211D6962E7147863B44CF9CCB6D6836007FE44AC028B43EC9AB65B792B61159AE35477FFA5D783281BE62CB707496F1AAB956F364ED1B8971F35B6F8179FD77C30980A163A51836B06F44311C3E7062172B80391AC5B20409CF16BDAAB4047DBB56255C325580976CD60113C72A194772149C6C2F342507016FF6B919613260902B3DAC2673D4584C9F87BD093AAD02950B8D750C1304A749F703D0365433065476B0CED26B3DF644B5F34B89A055C707EC6D059620F12962C74A0B78FC7CE12311B1F94504558DCB10BB27B198E2D80E1F8378C1462133209AA1A99BE03A978726AA4F88152C05859F667C708A9430C6C1FED06784E72D0F30198749AE8BA86172263175FA6FF380CE7E325AC4A6BF3201881DC16705A530EDABB7E0A28383D16E6F5BB0A87164917A6E942A9768B049FE37931D0192C7B5928FE14846B2686307A77757AB142996B049ACFF85AD5F058526510AF0D72E67DBBB17179A91B3847929145AF84FC355A1F454A82963A52CE6CAAB7BBAF7B22044391AD76187F37ABFF9210905495292F289A45077EC567D0F5C077FD44DF2A568F682368D2046803880B85994C61637B4B19C32D217B3DC961D9858D88A6D8FF2620E9674D9F5C9D066B3346A765E8684CDE20C4ED300395B6C1AC200F28930668B426FBC509F810EFC1396B167953ECA9670D34594415B61293D849C4245A57F6E2481ED0A40AFC8B2C1F7476151AE95C68B26E6679C155239C922D0F89E10B9C58ABA7A56EC7890F97B31E05CE97C4691F27167929313531086D46041E3452F74390BF06A787416F58537F6395AD5397E59CBC118D6825F26C181BA514D0BB42AF862BA5670C592132D4473C66A13EBF58E63021887E96DAFB14FFC408149F55D8A68AFAB24AFD1482C27555818495BF1B88E0F072ECCB44A0145A880C51172C6A411940FAD3BC31CAB64D5A2160FD8903445A6361B9FBCE5B7CE74761E339BD6CC3517551C0D2357095CAB8B34656C182165979A7F01930B331D6AF6A5DA8B57BAF76ABE198C2492AF2365843D33C84D013E13D13ADA4B1B387B8CF4DB7445C002D689CD93017A7D3A03F1B224EF7075AB88616C5B2DC343C0D46504D292A1A51960189A5FB968C985D707902B54DC390C8EA9A8EEE19DA0B0436B1259268C7B87A26D48A978901B1C44C6C0646CBB0A079F999345C31147AA9B3A51451F11C766C5B3C0851A00BB78350D60AA6437228B84A9DDF6869310946B46C483A05D7C04060AC89402691CE07B1769B23062927B875B4506E208F939A02BFA0AFC954FD0B034FB5B268EFCA527B01712E12F83E8B7E52996A68B63EE865782593C0FDC222E4449BE0657567903D48827CE526BB4215A31B8147D475C06D629B2A39DA7D258123AA844CCBBEDC83872A96E426B4DCF546BF2455DD739B8D973BD5C43C1A48A2FC4EACC676C5062069F9AEBA459D3A8ED880C63FA6ED80C06CA906FDCA895F2D9CECAB617740891F2A20B14DAA6343840F0CB33AFD38850CA87B0813388339B582A8DB0721339DBA66C2B9C118CC1400047FB7634CE8A8063B20175D49BD4B22E87B3AF335535528CAEEFE31827F20FC75831113B3013492F3F1709C873C09666928559110A5947626A14093128292022EA021750828D8121477BB0150D07D00E715F08598520F2744BD849E7082DEF2384A742B1DE61B44073691D6A34519A541F7B265E9B7F500155931628FF194D29225BEFC366ACE60F3394ACA71C1E9A7C2021DC241B339244F0CA3685AF2CB16AA668692F485D31590DD3448352E3C7C892191DD81605EC9211330EB720922F5A096FF342BEDB2D02160B95686E8302B82408A5076324EEA620ED81AB3BD097E173AE25BA777BC03AD2459191B225CAB540F8C1197885AD7ADB324206652BC678FCA24A57263DE089ACE6E1794E4B49EC85735B91830513AA9808572818C7716A61A51B7C59408703F066B7466CE2C18353FB0F024A0E05FC7F0F14B49A9A36CB49CE7EB963A2C20A5228B0B6ECA4AF63A1F7B1B8260B64D2F2C0718397F4F402A0946C9DE5B0F083B57903418C30BD7CC321574531B2163DDDF23A69B04B1D393C5916280DC11485FAC369D0AD1C85656D4A6A7BA480FA5ACC1788AC37C9706C26A357D7821D636078FC2204530C3D3358DA002F3136CF033443C519B6C505D00FE92B04A305A890267B238882EA9010554A1671862BE8097B67B8E8A37E8F0A5C96F94FBE296162AB1FA456785550AEE6B05A80554606B76714AA91C5E7B747A2005900077874CBD91970111C800C49CF05A4332570863929497AD6617D1B5614F2670390574F554C7D337417C792FF8953143638F60A7BF9517890D56D02039AD30392DEB045D8CC4994274E5CF83B702784637C6D53284F4F14C15335A86A642427E589AA454C6FB9707155BE23745FEAD04EC1CB07DA341F7FF1B6D17C315BC3282634A39C9104392B1D12222E8D091AAC69CD5A72276B01BE22FC3C634B41AB613DDC602EAAA00A72478D713C7A0F895880224CA8489E6860868A7B72CF876FDDB230C55C0523342C5F42B0A533A8FEB798D3104145E27D29CC96D54301D5B07274F700B9201555430D8EB961AA7C3307B0B56B479BCB6147D9035D786A58E7199F6BC9335918204A345826446A50801603EAC992E93FB104B834D7220B1494FAA2CB1A59650B00AAB00AA15F6909DFA969DED0B540648830360ED052661557280683084B93B746E27D916A05C96CB73964A4AE15CEBF4C84A1528506A69D2FC27A2A16CF270A09654A8B566651D097C61079A859171BDFD35262116479742DF74C0845D596FB83984F27811FF81CEEE0C37D618B93321A7DF0C0D22124CF521D92715EA7DBA1DD6112E9152CE2E15FED4769805A5857896EDAE13854648AC9DC26B770109372929FA511B573685D7951ACF21BDEBBC97D384D454B5625059A7EB8034FB4533F55B897B77930F3911F2808F54944CFB96BC0CC5AEDB8960A9C024984CDE756441C6381B3E38909DB3E85A36408C5414B471A68093B188134B3F54C751061093C4DEEF54891039AD71A74134806C7F102CDE67432D37DDDB4ABF33987A2AA47634C80260B5A246758102C864B2B40613C42425313855897FCC835C7C587B007C94760AF26A1531CEC874B9C492F4AA4C97567D6A61C21EB00FC52B1E0F24E9D680F8FE38B82243FD0B562C0DC86E2024593562B4AF4A682ACBE720813859B92A9C20DEEE4B4FFA1A1B17A24C394455077450B4C2CCE67A0E5C4016C746FF508A1DF89A5BE2A2A7B866ACA0A72A603843949909CD16DA542068604A380741C32E986366749CDD461A4362401CB8243613A2C442983B52C681A3CFC362FEDB337910668C5732906C41637778BFA619D502640545715F709C31B506534C0216790779EFC053B4A7789662B989A75C6580754A92588A30617E960C714171C8310A2802092261A85A5C882D407AE263A119B3E68E3BE158BB0325C30026BAB21D30B09637A54FA0A4B980DF807048F139223D33CCF206FC68672113A55E2084B6700B396F68873636DD8E5479BC0CA3E47B52329BD7F20681D5C2208AC0DE2123D50F6023A4472B0300CB3F8865BF7B49374AF01B002C4087BDAF4CAAE4336AA3A78E3856DC408B04E9AAAE77C464351C97938CAE829171BF724A8779C7FE20E5FC254D0BC283B773C2DFC83D28C3E854140A81267C2D2C67F361DFAF623D817B1655CA8A626A8A91BB088F539576C8795CC8A53044FF547B328377F4D17273AC323E6481CBFA058CCC456741057F1F668CAC51F34D666AEDCC176382037C674B4793104A4BF6B336E3D59A1C43958FD827493CB956C046025737B7FC0A3C2098BAB916E397191BEF5CC13F3BA0FD98F7A25BE0CCB113EE081B9AC808E2C728801C70CFBB2BD9A34469C064EA07952BA0D579380F7E782D0D5C6E1C26F3E17619CD47D4BA88C61600721BC2AB3C50F591988CCD77AFD3C43655272565401AD0778671939636C8BC24C794FB73EFFB99232503A0B50030A672CC8C2C0FDD5CD43B131DF0C9B9F867039E2A2B41B3CFB1A82C983AC54E002388692AD885C676AC2D7D0C5645B06A2684E9463AAAFEBC6C07709DC68078F7BCA36F5584579C3E3261D319A58392518ED507ED54ABFCA95CCDDB6C74949DCA48D01DBE3525A0BD91AC78428D5A930A5BD1F755E964833390BB7E9BEE7B1C5B34D07CF3593530572F57DFFDE8C0A167CBF377142317C203D37A8BCA5289614884A22271B47D91E03EE6D366B24902271", + "c": "4995176407FA65D288DDBA1FE91F7D2ED8B686096D49FCB85655AE5BBB09001FA8B8167F20C31A62169C319F798E38BDFD580DD070FA31499931C580950E2023C739D0D9C13F96ABAD0DF1F1E8B718C78D228BE5855CDCB5EB3A0B63C6EF156640615A763CD211FB94F540379F1876DD0B8619FC2EF14CEDC6BB9265F5C01B2833EA4F726F68B9F8B3AFFD39E71925AEA4EBF66894DDD1C4761155E9663AB89ADE8A50E9EA6B8253DB7085B8002FFB6C409921D7295F37E9E0ECD45C7B204FFC45792238CCB54997D2CA0B7CC4F056FA2B783A384528721CE77A7AE5C6938FD1CAE8CE5E7BB57405C6D5DC0B9517D45C580B0BD91AF807EB1989BB713C2DE9D3C7A891E31FECEBB5244E89F7F9DD574159415A81C459BA845F36E39B7B5FEBAF565D8A79D1E9119C618258297FECEF53430933956BF4BDB3BD9F12DEEE9BD0691FBE24512C178F1086DD2063B46166A3B00679C8D26EA493F28490523DDE0AA711DA3BBE9E6F05F569808C97EAC0AB5C8C0CA1F1BD7172DB19D94625904C08EBB3AA704108D033BE20B6EC6520065E1FD328C01437B4373E8DDE6F86170563D1E17ADF963F9D82AD654702AF5FBD30B76727A75982DCDCA3B5398C82FA42E6225AFB16C6FB466E9D5CC040BEA834DCE7704F94E0296504DF1C63908AD8729FA8DF7C9DEEE23D1D5922AF0548BBBA27873CF73E2970976DD56CBD562AEBA199906F86847AB60FD9D25BDEAD0EC2DC3C7D251D2396EDBBEFB438A098C7665094C088D9BF57AD4327C61CB484E0E730D5E7E98926B11CD4519C729FDCEBF625D7C743996F3B2E8FC38C29433ECE14D427C08EA079AD0B47466A7533C480E06C48CBA27E180011BD10A1B1F7089A150D48FF59EAA9154046F954303F3FD9BBAB91C667F7367868DCE21471B2ED4F2200674E221F71BBE457A323EFF93E89C5DFA4E8EDF87C8DE741ADAB529587663EE1180D60BB42CD8BDC050AC41457C8FB931EDD71B68B0448D036679D5BCEF2C91EDDEE940BC8D3E412A363712413F6EE9697D932941281381F1FD1EB6ACBC6FCEA805CC6FB301C4FDF4062B6BF12AF691FF0E65EF4448DEB4E403C2D62610A8451807B14D722C0940AE6C7C30EE6EA4C4D7CE51076A27AA93F3DECBFF2E0D753DCFCC8444A223074FB0A291764DA8B4A8E7B17CA12F7F3AEAF69B11C0D00835140769C59EACD9E9363DEDD402F126480F1763C50676FF0DD8D21C2DD74B2F0C988A88D49EB40F99A728A3A896AFA9A27F865DE5F4F97A2899CA92F1804C5F3A6969EA60DA4EF3B27D822B5FA6D71C8690721A531EB637CFE3D1369A08F4B0B978FAFADB14A26242810F5B5906576A7F3F9C7B57837CAE2F10E164067E08E35D5A6E2A27DC81EB1C9E6058047EC8127C388AAD709C0632CA237FB23BCA6204763AEE078E876C78AF48B6D22867DC199065880E52EE13449568300EC14396B35CCE9878D6A6517B425F7E0C7A146F62198D1165AABCA7158C7F6E91F32D427006B9F1B160FF7E5570FA36DDBBD16971A165E6A550B1648DCD01BA4854FF7627FC35C95F2CAE53A742645C859A96AF248F6686201DD3AD31D783C093E8AF94F15B099EAF49A0DD4664A8767E0F618ADCE6394E09562AE39FB4A249852B00DE3A14B263DD7DC12617839FDFC57A7E219C638514BF6635B5D6D32379D15452302C9EB9EDFEF626FDF46110D10195B605EE6A78B5C772F57E91FFC73FF4DC0DB7461512D66D2B7BBBFA9B85D0B28F9FAE8FB979FEDCC59AFF493E1C3E03DD91FAAD36CA4B2430AFB342566379E49CD06591D70AA18C9880B121CDD802A5C37622175191C4497C11447ACB6390E604F9D026C9624D8A6E23292A4EE82F7D99AC1AE2C541D9380280F9FE484F4E996D9D39D471450DAD5BA51C0268AA0BBBAA02B06DEE0FB2E956E303AB1DBE5C221B69C5239EC35F95C0A723AB4CA76C4E0C57E6D559695DAEA5E7BD1070BCFC3D0968B7A2A2EC80B3E663421D47D9D5F0970D6651A62A1270D4B47B03AD4E1C3615F9593266849E6C0496CF40333AF199734051EBE1FC3B02B3B72F61872D0BC86E729DD73C81571421FC9C58DB88DCB0318A25B0112206B1BD2141435294CEC995B18A4FFB723C2F73327602656EB7C84D82266D1B288AB7D363497E009AACD7454F00052B96B0A6205A91CE542F6CA0C7C187001FB0EC8C917ABAADAED2C5DE369224B8F00EBADB8", + "k": "0CB1CD5F942305DFEEC6F10D2138621F61283C5A87EE1C5205D3BEC21D9E5489", + "m": "3D6441A62F1998E2B5B9B1E73A9A5022FD005778204977F66F7A5FCEAF17E30E", + "reason": "no modification" + }, + { + "tcId": 65, + "deferred": false, + "ek": "53EA0623859BC606082104996B5CC3FF292846658A17D60CEFF78B4EE37FD693876084A46A9A8337B61079705D2269BFE7486161E3370FC7492B92C666A889962B7450B15993C027051B8F0ABBAC66EB2024F6CBB63868D6389F39E580E05A357E5179367A48D5E00F03503C0E4C11EF5758B05C8B61AA51B3019C5CB017DEE224685035651703D0C5877414846C30A20DFC25B6E8AA76D98AC95534D1CA8A7E9177C57B2B46A0237B8B678BF889221C64C1882B7196AEFCB8056E0CAB1AFB0E50D467F09A9733960C4BDB5AEA3C9F0447B8A7198AF5D6A9DFA6785ADA30456B843F84CEDFC6761CE507B85A3715C3CC53409972D28E8F2A1E9EDC9DC3A368E2257A57373C967CCCF8002B5AC3C762E8C3B9B607C7451A9DD28F06472F3B4503C1A31A276727958210810716F53A8578FC76CFDAA35CB757BF069CC8429A9DB9C4F5B1602315882F11C83C260720A11FD6D01FB94171588539C5328E951B1E7F5605B4557F5A476430456A33572B60161A43A18A3780516D232F8B87B5E821081B109A39DAA7D74396B8213B37D314DE258B3FF0934FB27C276A913A337051E038EEE78542D78C8A04051A76A3BCA319BBDB99D3FA87FC9A03AADB8D0561B77C394D2F60A84B096D873BAAE7342378D8513E8B8B13DC6AC9E285966CB2E53521E4928465841ED7CA8F76B56BAC958E011C6CB751A4F7D788DC73CDE1F67A24EA9CAC41A0676C11B3D618386465C7557FB0BBB7A3441497764C9D898313A2ADF59983E0B2031BF7364EF0C25E347D2EF1111F29B8509085264C9D366970FE8CC19293AE8407602A21001391A51C609C7184C8FC0267E683C6FB83B0EE66B6EC1C930B1A5D60C108EDB646841415EDC5CCAE32CD8581BC48E58E8598285A4B31F805A56E395556B120B2DA591D3985B4D7C50ACB1D5DD12617343F9FBC9854250500C03725B010D45361C3DC745648CF337774AFE704EECAB4DEB9746104566C8CB0DC512A06E198CF04A8DF13AB6966AF12D552F3B6BA72A266625749D6AA30D1DC9DE8DC26870C317C9C26324A265787635E2CAC1922057916A425872C48E29C39AA4C06E24A462161C20ACFA6B458F56012B3A828300570F9EB92ABB3400691C8E76BBC1D3B36E6254E771130B555A68CA05A3A8112051CB10A2A3B0F547A11E53D803970E671B0E85C146BE1AB47F63AC46439F1C7AF41326DAAC72AB1274CC6D0AA3291C0C2843229B820E3C7B0B3B600EE72AF71671FA875CBA59782221781F3338F45B1466D60C31F6189F2D29C1F427D440B3560C11CEBBA7B0E298D2B270FB6D21DDEB30990271F15A3947B464802062851984AF1DCCC5A7083FE7C81A454A03AA9674D98CCDE10A76B3C696802347E519156F977CDA5923D73656A0081A26320C6CA7E1AD7A12362176D9A18AA75356E147FE3278C911070D2D61111B87FBBCCA67B991E5915196994034CC83246C024F27C1C62353E79290C26552DD52A57F19ACE5C006BF7774CD6C07BAED7696D61C51C8108C42237D8F4846BD4891AC44605D93F8EC03DE607456555365212C35D59B7FB267BE713CA43502BF3045CC2400C11A571C8468093F499C7E46D34C9A75602782BA606AE67A5D3C50D31CA5FD6E3B963FB7650DC5BB312BC35F67650E4B12B780D4B6680F640372A99C90433A7AA388AE8043DC5E9AB6105CC6FD91E61F35CBA99CA39E979256A1700AA9373AC14F282B71ECC419417984AC34677F0A83386B91028B4B7ACAC22C57908AA9F04F878E7B6420132A47AB5A1BF5A30116A6E59B6157E4228BFF499CEB59A09276B5D398B6A8677E725725D5C54809097833CA7E6136EC994AEFFE00C87F6845F20BF76C2A348E08C3895277AA082B84202229B7698924B4D5684E8C8AB81B34B87CA28D3E95FFF82B5DDA9BA9172076D937B6D02745DB7C1F77B3B3C795872CA728EC36029DA80353310D4A50CDDAB29E1381FC20AC97F48920A445F566C390206C6183666B2523B6A43BFC3E077CC0C422C1C91176C50B34C419AB4C97D640F1FB913B760685B64126725C7527A313A454D5F683B23828965067943E12BF633411B7B8C71F648E4FCCBD2A1262FD350A66CCAF2FB1D9CD66515C52E1BDB1478726426C84022F60A6DC61F7CA2B33A60957BC50B4E248DA86071FDF8080E7801F81199A9FB0C5888643D8192ABA9DA4D73869D884AA2A7E0727231D4FD", + "dk": "76956EE8A1A973DBC0C7D40334A81B43D495168A6FBA8AB9A4392069096B598B99F1D0B9F0285DDB138DCBD1B0301ACAB6AA370C101EEDC17C748AA6B1F69A796AA6D20232AD98C64A4627EA98B3A595C0DCF558EFA42077B8BA2F29CEDF464E21858112E3A29EB327CABBA5FA33BDD1297E4224ABCADC68BD0B3AE7895FAEF1692BE2A79F95720D541245657C754330DFAC485CF3275D5C613FA74E99185AA8B38E21856C0995567DE346D2D9B8C691689A6A3442C0C2EE871D0D6B7D6D46C8C4C504CAE38EF7957886F70538803079F986AA945D0F0C25F1EA9C41FBB4D2C145460C39E4695A7A9560714A954647CEAEE703EC8B40AC38423C64A46E64196109C6776424007866AB06B85D73A267CB789A2A7EE4B827FF0ACEC846C4A31A01BBEB3EDDD7336C5BBB4575BF40365673DB24B4034F6AF1C0906C71AA3701ACAC8EC96114399B1CF3712FB1840C31A255477C2709D05C80981AC892B2275223007C8D84E9C4E9854F3A426819084EC2823714F47452B921B200834BD659758705BFF3CEE671756513A6562424EF1A1F21589CF321A9D790C846E768D3A022527937CB82309E95962643C2AF5A6422EBB2DEA1ACF32839A30993C3A604EA97A5AE000DB8F8144F414D7E86513E5CB0B0E2596C53C7851222CDC48C48224D4863A7B35C478A42285B8935B594970AA67B89323DA2B67B6A7A6A9FEA7B3BF648FA64067EBA6BAAD6BF640A44CDD896B68B125504C3DA5BB9DD552BA400618C453FE57683568CB2A8B86BC33B519885A06889981A87CE21D913D102AEB9A26E5474784F499914670AF5DC8613D9BBBB9A51CE708FFBC8A63F2A6E5DF6CB461A7F215A8CE2E472F1B813028C49E9E11777B3B1317ABF96513C1E349352FC2BFF7AB0995147CF46AAEBB71D18399F678CA8F72960C6C5052585027D180435551A3F8B44FCF06E6BC8B9D57A171601AE1EF3C21E7133C6C83C365C72B3C0A56EDCBB6B40695738C713D34C4BE6282896539EB261425C1572685C7026B4F56967F359A121FA031FF007772B5BB92B1167E25D706B99097A2F38ACAAC81C02748BCF02748DE17A8D2B857DC2474366CA0660328BA08CC6D52B3CD844B0B821AFF3B22F10294813702F7E24A78FE083BA1BB88EF55C11534524E059588A02EC83B652CCB4D55968E8B52F293B4E75BA1790E95701D850C8313EA5E77D62681156991B67146D1C1A6DC6E7004D2037C7C7AC48C80BD566A78EE811F3E0C7598948BF897A6F0AAB81001FB52B4974A3C1150BA5C9685D3A632E68BB9D4925882A48AA5B01AEE9A44DF574ABDECB7B1B3B755188804F74A9524231EC444300B4644BB56E6606523DE99ACC8A4CC6EB2D7A93C1847B5FE288CF19F96E86C49DAE2B39FD678C63844EB4A7C39A25895F338ADF1330ED92AFB2013EB1B5729BACBB36EA25B56B6C5C309021B74E96D037B14077F025830E8044EEA0BC36D1610B9741E1B5CDC9584469864CCBF413A2DAAA260C8FADD82702EA66B6C811CECA5BE4DCCE53DACEBBDA081A184C7A55371AAB3A53ECC2E9B82C27D743635C4240F5394ED05F5C265AE6A120249103D7E2443680C655F10D45050AEF210B9CD306465282A5A2C182089129E53C0B4C028F34761D19C4096A622EEAB6C5262338735FB1D28E1C50032DD31434E149E90CCD8123ADDBB0AD5B903FAD334F4EFAAA04376E225C17353B278CCAAB104C83A855941A1583D6938C5466A9D6C63AC98253338BB19AD8645B70C05F90744C96779FC9479384CA19D46AD43567799AA248CB3768F324D8320160712BFA9B781681AEC61675CE2230C1F02E59A1CE52836F3CC252A0D4B27B14C46B2A08A2D0C656B5449A390C90DB69B3571BED8A76A2E26E41E08C728B68A1B659E8E8466D96B653D132EAC36F2578338D2334DB7B237AF744FCC08013288C1FA9AA26D88E1E399549A323F41718C138A857EB5103A131578ABF0221520E2ABD914B8F993455F980B726597345942F4A319963E65A704B884FF02D01C76A0A3503020CAA99F6C5D8894FFA3917645BAF9AF793CD46577291216A4A415033C31E78AD8F8793E4E97048FAAC12887267C9C043BA1A5DE6C009E5C8A68026F6798479F45496A142CA031CF0A3C0F8FB1110C3C37148322897A6899895C125B385CCB153EA0623859BC606082104996B5CC3FF292846658A17D60CEFF78B4EE37FD693876084A46A9A8337B61079705D2269BFE7486161E3370FC7492B92C666A889962B7450B15993C027051B8F0ABBAC66EB2024F6CBB63868D6389F39E580E05A357E5179367A48D5E00F03503C0E4C11EF5758B05C8B61AA51B3019C5CB017DEE224685035651703D0C5877414846C30A20DFC25B6E8AA76D98AC95534D1CA8A7E9177C57B2B46A0237B8B678BF889221C64C1882B7196AEFCB8056E0CAB1AFB0E50D467F09A9733960C4BDB5AEA3C9F0447B8A7198AF5D6A9DFA6785ADA30456B843F84CEDFC6761CE507B85A3715C3CC53409972D28E8F2A1E9EDC9DC3A368E2257A57373C967CCCF8002B5AC3C762E8C3B9B607C7451A9DD28F06472F3B4503C1A31A276727958210810716F53A8578FC76CFDAA35CB757BF069CC8429A9DB9C4F5B1602315882F11C83C260720A11FD6D01FB94171588539C5328E951B1E7F5605B4557F5A476430456A33572B60161A43A18A3780516D232F8B87B5E821081B109A39DAA7D74396B8213B37D314DE258B3FF0934FB27C276A913A337051E038EEE78542D78C8A04051A76A3BCA319BBDB99D3FA87FC9A03AADB8D0561B77C394D2F60A84B096D873BAAE7342378D8513E8B8B13DC6AC9E285966CB2E53521E4928465841ED7CA8F76B56BAC958E011C6CB751A4F7D788DC73CDE1F67A24EA9CAC41A0676C11B3D618386465C7557FB0BBB7A3441497764C9D898313A2ADF59983E0B2031BF7364EF0C25E347D2EF1111F29B8509085264C9D366970FE8CC19293AE8407602A21001391A51C609C7184C8FC0267E683C6FB83B0EE66B6EC1C930B1A5D60C108EDB646841415EDC5CCAE32CD8581BC48E58E8598285A4B31F805A56E395556B120B2DA591D3985B4D7C50ACB1D5DD12617343F9FBC9854250500C03725B010D45361C3DC745648CF337774AFE704EECAB4DEB9746104566C8CB0DC512A06E198CF04A8DF13AB6966AF12D552F3B6BA72A266625749D6AA30D1DC9DE8DC26870C317C9C26324A265787635E2CAC1922057916A425872C48E29C39AA4C06E24A462161C20ACFA6B458F56012B3A828300570F9EB92ABB3400691C8E76BBC1D3B36E6254E771130B555A68CA05A3A8112051CB10A2A3B0F547A11E53D803970E671B0E85C146BE1AB47F63AC46439F1C7AF41326DAAC72AB1274CC6D0AA3291C0C2843229B820E3C7B0B3B600EE72AF71671FA875CBA59782221781F3338F45B1466D60C31F6189F2D29C1F427D440B3560C11CEBBA7B0E298D2B270FB6D21DDEB30990271F15A3947B464802062851984AF1DCCC5A7083FE7C81A454A03AA9674D98CCDE10A76B3C696802347E519156F977CDA5923D73656A0081A26320C6CA7E1AD7A12362176D9A18AA75356E147FE3278C911070D2D61111B87FBBCCA67B991E5915196994034CC83246C024F27C1C62353E79290C26552DD52A57F19ACE5C006BF7774CD6C07BAED7696D61C51C8108C42237D8F4846BD4891AC44605D93F8EC03DE607456555365212C35D59B7FB267BE713CA43502BF3045CC2400C11A571C8468093F499C7E46D34C9A75602782BA606AE67A5D3C50D31CA5FD6E3B963FB7650DC5BB312BC35F67650E4B12B780D4B6680F640372A99C90433A7AA388AE8043DC5E9AB6105CC6FD91E61F35CBA99CA39E979256A1700AA9373AC14F282B71ECC419417984AC34677F0A83386B91028B4B7ACAC22C57908AA9F04F878E7B6420132A47AB5A1BF5A30116A6E59B6157E4228BFF499CEB59A09276B5D398B6A8677E725725D5C54809097833CA7E6136EC994AEFFE00C87F6845F20BF76C2A348E08C3895277AA082B84202229B7698924B4D5684E8C8AB81B34B87CA28D3E95FFF82B5DDA9BA9172076D937B6D02745DB7C1F77B3B3C795872CA728EC36029DA80353310D4A50CDDAB29E1381FC20AC97F48920A445F566C390206C6183666B2523B6A43BFC3E077CC0C422C1C91176C50B34C419AB4C97D640F1FB913B760685B64126725C7527A313A454D5F683B23828965067943E12BF633411B7B8C71F648E4FCCBD2A1262FD350A66CCAF2FB1D9CD66515C52E1BDB1478726426C84022F60A6DC61F7CA2B33A60957BC50B4E248DA86071FDF8080E7801F81199A9FB0C5888643D8192ABA9DA4D73869D884AA2A7E0727231D4FD1AE23027CC9C62AB641D0F46EB5F17471706A42AFC921B48AC0A39E50F560DC1502C2C1BF811FABD14733D6ABE45283CBB7292278166018EC48D33904703828D", + "c": "6070F979C45C39BC4191E7B6C735F278337E043F0DB0D24B7321A51391896F4A7D122CD14F98A2C0272C4D3FD039F029227B6D83BB800C7C6E09A7894B6CD86FD68A32F31CE3880EB9D4694C4551058BC58193AB13EAA62DF3DD14BB9606C29511E4AFC1E0566DA175D4AA45E428B241D6F3419710A8FDCCB0BB74792811570E0C24A29D034B83FFCF98755CF227AA3F8C80E9AF7370DC7A7705AD3808C3B33FF40EF131C879779F72722EA582E130D825B7912B3F6DBC5659D59088333C1883DD43B7FFF8F942D584F42352FE4A15AA8D3D0D5829884293A693585FD4763085541FF83BFDBB506DE54796D3641038410E4617E009042881A942311849CC789658BEC01554A4D6F9E5636E59A76C1733C40D90ED8B0763F16B8217684F484B9FE19E07A8947A3EF04C27645F300A664505ADD17015C2B1A319D414AAD10C638B1F37FCF61F81A80624CE7D75E2759E0B9942CE6251349DEB9EF56A5A4245D6B598046186D91240626F1F37AEE04704E7F6A14214A520603B7ED44CCADB8A2E39093718EAC9AEFDB96CA2822D8213F66655017BCBD465716DF13542B053FBF0D99018D4549E2D1B19735D6DB95041C0AF04A169183CE0A634BA114E90C30429984633097141E1BE19DF941F2FFD228E2C627F02798BBE3A886147CE23168E335590C1C3DD337E980CE4769AB187A2A6E855166646F91E14E3B97700753ABB6F811D474A412FCB951C2568EBA98EC9D2C51F08F3DB5D2EA797531D65A250579F98BEF2EC5FA1179C2DC6D9E27E66F983AD70AADB1F5067C104FE7B7A22F808F4C5AB71B881F2D6510EE85A0118C74DDCDDDC8DE8DC551D41BC14DF90294567AB06FD76FC87B92AF9AC0B456386C714D5773B500CF15596A4A71D8A6E23578AA9D89C596D67FD08A379868305148076106FDE47DAC20882E913BD2D397179D4E611E8CF25608AC3B50D12A7F7EEE1572B403387DE2D0EFDC35A3C8644BC3BD4DA9F1E2E1F2ED341CC1DFEE0E39416DCD6261AF74E84E0F6D33D91EB0DAECF19597BEABEA1B690514766F3C8EEE663923B3FD25D36401D33A39E5972B8B17A41D230374D7C1783B208545167243B31C32C9DAA330B3636A1305F96DD612990A5F1D7A4C407DCE61CF73F5BAF5C55B737D9152A5FDB19DC4969E9CB4B049318B88EF4AEF97DA536DFAF3BE6D3EE6D1F2E4C3F7E17963418CDA89C2A481237A6F2EC303F380595872F050D1569ACABEDA5A3219F8E7BB75CA77541395AC44EE9CEEBD1D4BF59507D77014F310CEBE3A322C8636DC450A279C54332F46C8205653556360B51B31E06BC1B5AC9FC9091859DFF301EA407E5AC051231F774C94E2E932A08CE22ADA65E4EF74D7A4BB1CB1947F5490E88D569BAFDFF756EC451494E4315FA25283BA63FF61BAE0E45C4582342CFF3F3B42E297B97C9E73E946151F8D29A47E57A6ABF45EFC5411B607DC160FAF7674665D0F0E5039ED8C7E59BE98FEBA7C81ED54DD51A4542E5CEE2712F25825B18177FB8E8BF4FE1657062F31B8D8090A9512CAF8876B09E97725CD36C9BA2738F1D4C863A7B99B27476812700D24F3576EF6007D2A26B79ACE6CDA9B291527C800F0D666B784A11BED29B8D8267D5A643E33F255B6693B129F38BEB976E4FE7AEEB0C78BDBD8D31326A155921236255B7FD029307B80CB002BE230DC3036F8AB7CA446BE34BF5A5F29E2D5A0DBAEFABABFF6DFDE4E400FE491F40C2861B0BFEEF44DCB14803C79E8FE79C7C3AE113E8FA0B2F507A3711B8C56ACD0B090935EF932E6004A36B9390260F3080C2DC75A61B69E758EA4D31F8142845218E1DDD85AB7579428258CB5C57286FE308D1BC164BFBD574246FE6F7ECD9BE6C91B24EDFEAE6F2BEF86B13780649AE57B1F7D764786FC4C7EDE4775C2461CBE37026BBE6BE5D8B0637239BE3A7F8B6E56E2B86478E9B5461F5040596B2207061BE9E7851DDBCD619DBFD7410B05A361FD25613BBCF5379D347E43DA571EE03EA19C8553B966E9FEAC579635241E82749F648A7935077163523D19B9936648EE5FE5CC902E66F4379156721A63824E97294D8FF0C4CA93D995F6C635E010937B8C94AF28BE078FC94E94F9DFF2E6747E2F0287BB6C756D8D3E1D1B0A736B92279F37861FBBFF8322C676472B44667815755EFD9BB4920AAFB689B7692892960E059D010AC883ACD8B5068C1EE9B87E82A4B637A006B", + "k": "12266ADDBCC27B282DC0566CCE7473F4D705D1DB4B3D82130AE29C3999C6A999", + "m": "637B7A1B57EB76C50417601EB71269E050008F415DF974C07BEF46CEFD08368E", + "reason": "no modification" + }, + { + "tcId": 66, + "deferred": false, + "ek": "51F74568AA5F4A54B2F4C9CFBC7666B7075A9D65A016416A49F16EC0CA716B75A3D80609FAAB06DFE69661706013A0C5FB7AB0340CC1BA72C2D7E1635B33B0EC3B29FEB369CEF671BFB907B3A2219B1554151A62B43638C635219F86B792B18527D8CFF00BB24853A5A6B81C9BB77790B25BA8A71A7CF7231A9007EB8B50F586139279CACCACCA4C7C64EDEAA194768D6A33BDFC42218EB279FD111E1C9633307AA30830B161D93F13973BDBB3772FA57309E36880816F97DB8E7E6411CC569A578A5C6F62AA33C2354CDC15D2065451E1ACC212ADBDE104F094378ED8882BFA416B1C55BBBC20C1E5AC89892B0CBA2B54516937E781F7A4A9B1802876598FF95832F6478ABEA33362A40EE28AA957E74540129D6FF3BCC0114A4AC8A40AD30BBDDA2BFD2BC5A6CB4DE5978F9AAB64CC8659A5765AB11AC3A654A247165253C81065359E070921188A312805417FA149D335ABE8404293329C73DA1E2E43CBF9B22B0D84339F792C9FC97006345FE6DB931AD71F897878B4318073B9A64400B5B4D0C4D6FB57E8B511743859D8E873B9C5052578282F9A6362172014089F2993BA7FCC2444FB185EF055D9D6A0EB564D5E4667E537AC9B49AD1241950140B188F4C88CD6A241BC42122A3DD7720E6E6B214D2721BDFB9358E7026F1A024132CBD0BB0EDFD83552F271B151099CE55D783C88B29A578B2943E3809A68D268DF746557435B5EE1597CCB58446403B98C88DF38399CE58BCDA1CD00462B9D933A83546526BB9E5C887050F5109090600CE84072DBAFAED20D137A7D129ACCDF1712C94098267148C0B1A301DC618D684152C817F27B3E8AF83F91951347C633C7921804D853A2E66C948143DF1B3C15B201EEA56E764273CF50AA58B45E71950FFD32C69B079564C48B08A43857E09FC33B8222A3852A055E3E4CA7B72B190E6C8B557AAB84D7BD138CA148330B75AB5FEAB8419A55938771053A5B09261CB0D4A42575E72F8F505D77F0896780CCF589376D5A651E4008CF600972008540A0896F80C17BFC78E16B64956677CBF864683735A279B966A4A906B1972AE4875BFC81EEFB75248B72E3A3768EB56D2DC3C04921011F4A92FDCC8EC9347353FA0055CAB83B7465D221B877A70B59715A6075799C19C8818595E6D478D659C7F9155A841B28EC751866CA3C2A829D43467E12563F5A4154947581D4B4ACD827B3315B44B3E31BEE0C04E9C03D1A186AAA7438EA9AA15FCA83D26B79A2093CC4505051B31F3D563832F397C8671516648AE92108A8E149392209A04816EFA1207CF854FA655538C161F6561274E5154D89A223665FC285B6D3A45A2F38278DA7B5055BAF8B1A052196C2547C3BACE09CFBA1299071635510ADDE3898C4C20E4F8034B454BFCD0CA262812D43C4A8660A5B2CA42E2FFA7AAB513DFCBC437077609596A45FE8BF330741A88A5FFD20AE19B58C3B19774A047F563AC6CF0A205A2A4C1D6641F93AB4C0F39E6BB51032F0A12B8A45E900954BB3A4379129E44918998A50454050607101BDE2975E66C0AE2436664B15850294FBC985B638C8303767DB7A10A8A74D5AEA0EE2B6105112525890C6D5A8CD1712A2913B73C386C450F7286F4A8ED7284AD9F36A22494E51D43950526B19766E388AAD84A39391399628F9C251D4C784AC2AD0424FC57BBEC391A549D59E5638A8056929203BB8F9A44A27117B28BA2670508680D55B82B4CA8E523BEF1AC4CFE83511B920309A735C62CDD5151338C50D104950C9273263E8250488135240A949958090F06BD46B5AAA3035CF9B7308C09952B66AB5999EC6E6BE7A027964249D63D1817F430737C96F54B391EB44640959277B56B495C49F482B829F97B94FF8B4F0E347A9B6BB83E9AC6617000694AF0C7AA13A273BE2981286ABC62444AA16FC043CE4B1B4F50437C9503F815772A8BFBF6B229D48B75D94BC02219E0F71BA020C37169B42CDC1A88081B7846C3636F3598630B314D809AAD1B7F3D335B41468C019C2C061240BE39325D34DDE9C24FD29CB3ED62F815C248F4B6E8D3908FA3B9C8AB1534AE49176652DB909059402128F18C0C9E52DED217C7CA864E378CB59711B0C764B96F13EC5E3766297C9B303806C685F4A861878CA8415D60B057814E554B04F49C3DF9AAC26A5CDCEC91B59F32BED063E299ACD431F8B781FBC1AB90AE6AD004FFA864E0E16AB57", + "dk": "2E78C01275512282C156828B65705F7163A682878F9E7C0762153C8E63012DB043810B705D9C3DC092C1427808D5C8BBD361A860C5260D36A3DEAA97A3D97771F7804B3B97CE43A4ACD7A54B3068E2727AAAC7C3F960AAE2880F8CF049898A6D90664024136967D18EA0FC6736EB0D20665DF0075BD9789E621158A4A20F036832E71C05D1B3218EF75EFAE05262A21C1A4A8A427350B0C128DF37C775D602732B21E5AB36674C0AF61655E28C56BBB9B1D6174749082F29D8177427A24E5597769758C2C4BCCADC32A618C57837BA8FDAA8B89B35AD8A2C72EC03F9707C0FA4C01A231976B0B15CB39438217C061CB54AFB40475911806952A42441E0F77918E7CBEA9639D1F1A2DB9C785EB5025307C1924862BB68C5FC652D2AA9AE043B31953393FFF3A2616B1DE4649088450617F548005A477C1897260046B60BC120764A25DC4D9E1285C48878D3738A3A47687CF36621267041982E50CB6311827E6D27278E6862C724007E75B35499838D9553D9C79196D84A7BB2B386790ECD7647D3A60BACE84C679AC3A0B212181A0478D72E4E50B7C10CC5A1B154970C0625111A4ED8CFB47209672B7597B16FE79786E8B571A32A7EC59BB71F745439C181FF23C26B96A5B10A41324B2F8021648CCB016BDB92D894CEEFEA1876A30DFDE22973DB8B70D7CBACF5B6B4B54CFB9B2522919007B6526C084B8F392326461F0BD6CA9966351BB45F2B77564D1723A0EAAF0A2AAB372B9C18FAAA21A00DD2F4570A367EB2EB4E3E719D1E72A164C4A8DE6609540B6E93F71759362C2A6C930385217821BA00D0BD41C059176086E61620187B6B7D448A34A8631B9913B2C3307E529D360749DE11571BF91866A098CCD29DBE9314A770C217356EC4A0CC3D98CA22EC85F9C3C4F3A065EC5C48AA9269A8E5482B9781E7A39B6FFB287FF730919535C5987034A32AD4101986BC9F17B2AEC906169E3C56DBB213D6FC4BFE48038B0C1E235C4E106C1616D95F75142CD02B18AF13B56CD45EB1C46E6F008234992385EB21A6A7C219021EF47B55F5301E60F9CE8FDB1E3BC56F4DA253F9799A160A077872AB7551013375A2C8B3B9AF70BB048C4389EB90CF31512E080AEC7673C7F23EADDA8BC17372C8BCAF100438B0167FE2737BDD54C9571CBDB843510D615198821A2AB16126D107507B5D31D4349C0A2E47D6044B6802700C9FBB5B3300A2B65D4C457578639696BE7336B618284D99514701CA0B3C6701B008CDE5A88908D813E2BCB86D032CB13B70D34A35D07567B6DCBFF3343DA4A9B7390CA1FBE195E384464D154FCB169AC35087C3013127835F3F98B996E9815DD4C14A6995ED766DCA79ACCAB324AC20184A93C616F53BFA722BC9FC55924048702820A423193A858E6E399470C3373F8B0FAE335A1694B96BC29B15B939F81312311B548BD819A8E9168B303E2F82AD8110531B8B21F00517A0483516C160E8229971CA293016B8A5828B83F87951B266523388A82458ACFCC98647B2043A2525EA8F5F0A66436AA8F0A2C736E8284C8257FA49475B2A54DB2C3A9B0BA5DB92C48088CB79572CB21B7CFCD8285B54600F75035A00AAA5B31AE4B201755BCF0E4B32A84588136C9D48B129837CBA057AB02BD34A3871BA824A286685B3598007E39B931886BC22944535F95A5E6C1E8A95B48E22A6541C1EC078903CD05DE9E43EF054661412629D860717A90F91685BC54B62A315348F4B8A74B672C19883BA58C854D349394B20FDBACC8AB0C0A8972DAF080759EC20C6677DD956A9A48B07A727ABB239382A2767FF2522E7217AD3A2AC6C13331799BB0BD39803598FC04921A1F90B7DDA2FDE2A2FBA4173C9D390FC31B6388684D6970BB4562A69688283EB6327D960DB19B308A9BEF87CBE30606C56F8306AB134E32ACECE27011F740004D473A6C1016C5C9F4ACB992933801DA80B379043845A3432B375EF670DE54C6AC7206BDF711B38F272DC916BEAEA6A370008845C792CC9C2F64BA10DB51ACBB18EE0EA99D028CDDE671F14FC00492BC43E282813A8B0BB13C3BFC0404F362A8A45012B77377B8CAEF7734E0C22C4BA4969F610482E47882B209C4201378611C88E9CAB82E5CA8BDA976F11803A11AD5B288C043B2B8891168E4C75F62678BCB05EA5B11FC66A2551F74568AA5F4A54B2F4C9CFBC7666B7075A9D65A016416A49F16EC0CA716B75A3D80609FAAB06DFE69661706013A0C5FB7AB0340CC1BA72C2D7E1635B33B0EC3B29FEB369CEF671BFB907B3A2219B1554151A62B43638C635219F86B792B18527D8CFF00BB24853A5A6B81C9BB77790B25BA8A71A7CF7231A9007EB8B50F586139279CACCACCA4C7C64EDEAA194768D6A33BDFC42218EB279FD111E1C9633307AA30830B161D93F13973BDBB3772FA57309E36880816F97DB8E7E6411CC569A578A5C6F62AA33C2354CDC15D2065451E1ACC212ADBDE104F094378ED8882BFA416B1C55BBBC20C1E5AC89892B0CBA2B54516937E781F7A4A9B1802876598FF95832F6478ABEA33362A40EE28AA957E74540129D6FF3BCC0114A4AC8A40AD30BBDDA2BFD2BC5A6CB4DE5978F9AAB64CC8659A5765AB11AC3A654A247165253C81065359E070921188A312805417FA149D335ABE8404293329C73DA1E2E43CBF9B22B0D84339F792C9FC97006345FE6DB931AD71F897878B4318073B9A64400B5B4D0C4D6FB57E8B511743859D8E873B9C5052578282F9A6362172014089F2993BA7FCC2444FB185EF055D9D6A0EB564D5E4667E537AC9B49AD1241950140B188F4C88CD6A241BC42122A3DD7720E6E6B214D2721BDFB9358E7026F1A024132CBD0BB0EDFD83552F271B151099CE55D783C88B29A578B2943E3809A68D268DF746557435B5EE1597CCB58446403B98C88DF38399CE58BCDA1CD00462B9D933A83546526BB9E5C887050F5109090600CE84072DBAFAED20D137A7D129ACCDF1712C94098267148C0B1A301DC618D684152C817F27B3E8AF83F91951347C633C7921804D853A2E66C948143DF1B3C15B201EEA56E764273CF50AA58B45E71950FFD32C69B079564C48B08A43857E09FC33B8222A3852A055E3E4CA7B72B190E6C8B557AAB84D7BD138CA148330B75AB5FEAB8419A55938771053A5B09261CB0D4A42575E72F8F505D77F0896780CCF589376D5A651E4008CF600972008540A0896F80C17BFC78E16B64956677CBF864683735A279B966A4A906B1972AE4875BFC81EEFB75248B72E3A3768EB56D2DC3C04921011F4A92FDCC8EC9347353FA0055CAB83B7465D221B877A70B59715A6075799C19C8818595E6D478D659C7F9155A841B28EC751866CA3C2A829D43467E12563F5A4154947581D4B4ACD827B3315B44B3E31BEE0C04E9C03D1A186AAA7438EA9AA15FCA83D26B79A2093CC4505051B31F3D563832F397C8671516648AE92108A8E149392209A04816EFA1207CF854FA655538C161F6561274E5154D89A223665FC285B6D3A45A2F38278DA7B5055BAF8B1A052196C2547C3BACE09CFBA1299071635510ADDE3898C4C20E4F8034B454BFCD0CA262812D43C4A8660A5B2CA42E2FFA7AAB513DFCBC437077609596A45FE8BF330741A88A5FFD20AE19B58C3B19774A047F563AC6CF0A205A2A4C1D6641F93AB4C0F39E6BB51032F0A12B8A45E900954BB3A4379129E44918998A50454050607101BDE2975E66C0AE2436664B15850294FBC985B638C8303767DB7A10A8A74D5AEA0EE2B6105112525890C6D5A8CD1712A2913B73C386C450F7286F4A8ED7284AD9F36A22494E51D43950526B19766E388AAD84A39391399628F9C251D4C784AC2AD0424FC57BBEC391A549D59E5638A8056929203BB8F9A44A27117B28BA2670508680D55B82B4CA8E523BEF1AC4CFE83511B920309A735C62CDD5151338C50D104950C9273263E8250488135240A949958090F06BD46B5AAA3035CF9B7308C09952B66AB5999EC6E6BE7A027964249D63D1817F430737C96F54B391EB44640959277B56B495C49F482B829F97B94FF8B4F0E347A9B6BB83E9AC6617000694AF0C7AA13A273BE2981286ABC62444AA16FC043CE4B1B4F50437C9503F815772A8BFBF6B229D48B75D94BC02219E0F71BA020C37169B42CDC1A88081B7846C3636F3598630B314D809AAD1B7F3D335B41468C019C2C061240BE39325D34DDE9C24FD29CB3ED62F815C248F4B6E8D3908FA3B9C8AB1534AE49176652DB909059402128F18C0C9E52DED217C7CA864E378CB59711B0C764B96F13EC5E3766297C9B303806C685F4A861878CA8415D60B057814E554B04F49C3DF9AAC26A5CDCEC91B59F32BED063E299ACD431F8B781FBC1AB90AE6AD004FFA864E0E16AB5777DEF69A903066F0C5A3F4CFAC6B7408862923728492E7E5FF26A83A48EBB8BAE5D9C71D76D5958744741B9FA4B7EB67799F54AA0717478C4BF0EA6E0B012AEE", + "c": "229B069FFA4848A699156C894955CD9BF623BD28ED0E2F34B8E1F62A1B3DD00A6AAD501DFA776604A874C5FF1E60C3FE89EC281DD320BA2C1EA16E99D147B0548710EE11CA2540DEAC882A7B63057400030EDE2E75BDA52622287D3680A2FA7DAA94FE289D1E3879E1039CE2B65C9407E7A49CB93E76B4B4BC1D247227F437696D816C08E401B2D82670E189AC9F6A33EBDB2C0B16C2E18C9009BADD550B1F533C265A3E0153C982D4D64B215B7CCABBEE4B644B1592A766C30B28963F0991EFCCB5A94D38B38813CF9998A362318AAD81CCD6A0251FE63DF879DA7B7CE4C9CC28E86211E97773D3AEC98E1931734CE8629BCC668C490426BA60CE2E28E2871DB69B9683CC6AACC4F588733A7ACED2F17EBEF11061251AA8745F147BF1DA650386F7CC637E9D02870C16E2F06164E694828BAA66610EE984B7C60D0BF82F8B6D79EAF56D75FE605B3CED809DFAFAE3F858632E3147C3BBAB8D931A3B00E90693E5B840A77277C9FBE86FEFB2BAF134AC21B8B47E3D0A009894028DD5645ECE152838290EA835944ACCD78CE3038E8A2DD991ECD66DA742FEEF94125E554BBE04F0E923EF1BB02381DDE16F1D41BEFC8C418A6818FEF891DC75ABF717DD84979FA47FA3280364444AA77D72C26E808EF6202BE04C4FBE4B26A5B8E60317AC1D6860F5E728CF316DA287B3DFA391AEA8AB4CABF0D88419CA2C4B461E8C4BC633F0F2A6AAB7A86179170DCA1DE6A2885983CB4C0BA34B1D2A53AB9751ED91C49DE832ED22BE9443B8C2732B32A9BC14889121E5B261946EDD759394474627A9D82F6962F76D67B94649788EE82FC81081F008F6DD183F27B69CA19A5CD1FCC962502E827183AE32DF8A369F1A6DC44075BED6CD3C909B161FA62CD67F2425DD1D86D8401F7ACD5A4D5CCB94B9E22E4D518A9EBCBC705ED3CE7068977E1F4D7DC12BC51717D00225DA24402BAFB56DA5B7C8580F53CF66CE8F960B1A58A40534D29014A73781323E520D60097B5BBC5492D87D9103F040BDACC7640DAB97E6127458153953E0624A26ADC8875225ED6FEC2876DBCEB536D01DF0001477E64DDC542898B6D502BAE3FD7B49049A1104A290107904CEA445A045EE1432E79D8B358C4F28E42DCB05A94D04B78069AFF8A0A2CF2AF94D9837C2EBEF85A914163EE1F10E411DCBD7805A1EA204468EEE5E6DD682E2C1C7E30E260DE3AAD4AF6F2C6FDFF083847962EDD0052F13F0B8F2E4659F8D00260F38EE0BDDD4D6953CA0BB7B055CF7FD160D19AE5C3A1967FA0AFB09D71AE4AB63FCA185DF32DEF74E786E050FAD63D789546AB7723B64EAB6BBAC9B0B0AC9D3C994A71A68BF5B378B4BA8336CD1D4725F3EFA23E4B9585D3006C42485312AD7EAFFF80CE82F7A82DE7864D9EDB3A569892ABDDAFDBE384225BE377A051B75F0F5FC99C291CEEA13A6D1C1E6F8C1C5E72A86016029761B3E2D024F33B7C5B91CB2481F7BE4986FB381A3B8E20F8FDD5A390572727541B4D4988337CE19014433BB47F31D1847AA0C4E28288B1707744F542383271B32D85B73E3857D89703BC80FA6695F617D6DCCC17147779B9A4522C955D443CAB3F61E3667B44C0FFCACC136C3A487CCC760F7952A28C2826A7F640BEB3B3712EC3DC52D75047B7D3ACBDB74F32B0139FFF1C2A66818EDABF1C3FAE5DDA87512C8ECF60C133D4B98A7D1E1C72DD8A487B0A2FD9F8AA59EA4941B9958A2025385636B9258F4188B8F1CA96C4FA50A34E326616ED2354364C892295D2AD5726E4FA077DCE9FD110A95823B5DC355664ECCB7543E987D9CF986453C5ADBD438F849C6578CE859842F90975365E3FD5D083A0442E7830D580F51819A04941EC9284B31FC457060A7A6EB91BA7A87C0A54F1F422C5F0B6D8D4323881DF5525B35CCF992C2E701534A213BD935D30684086BB916B44FD9D678EE8BA7578B9E427FA36C139F1FD92DACA7FC8DB85607DBBD3532DC24BA45B53A36180316DD4ED5FD4449034308F07A6571F9943E194A4200F6834557CE568712D41078024762C7D020274B6404B326996EBF2464E40B8D9842D0417890DA0BBA9013A97A9259FDEF545EF780FC0D501A0137E9AB22A1BDC96252BD5137C96697628E559B00C2AE813323F2B9A1E2616809AB59945647167AE2B2E757C21273FA0CB3FBEA7E4096DC1CC8F4F114B94F5D760D496C1BA8ECD6B1EC68AECE4C9A25D1C561", + "k": "EBEFAF52036034E249B29A1825226DBF469C492494E9C4F13BD1010B963E0D4C", + "m": "B5C84B4535CC622A5D6B93229BCE68789D3014D500D3263B6E0F54359D20ECE8", + "reason": "no modification" + }, + { + "tcId": 67, + "deferred": false, + "ek": "10971ED51709D256CAD9B57F0E48850C4B803642732C89A84439CD31C6B0F045915090168F8952B3382BF1186A56D2CBC102898F112FD91A2BE5AB0391A67C3C5255CEC88FACF3B6ABD427E3A410ED22C2C6C173F4894E9BF20CA3713CF0E8506846507BC762047715A7A37DA3A5730D8A1556560609E4CCB61298C4B2BEC374B534D0B266C427088816E843B118FA9CB27B9D1F549480F98F7F4B5AE71BA376B0B9180A157D8128D2286C4B5BC54F8590852B5CDDC5C11E6B4B36EC7CD6081D45A9C50272643CF0569A9A237581AD36D0705C004091F7C46D9073739226EFBCBAD5B551680C86E4290C3CA1AA756851A380ACFC033FBDAAC5B82C364DB075633A9A10B8137A05B29863AD1DA1CAEF5ACD2D75A9643B495EBBC184038B58B9A95998AA95B672A2D15CB78B0A00E386F433425C469A7677B8569CAC8F5A3A035C777B4570BAE1898FD379ABA62C960024E55645CA6625327457A37A92FBD68C76E79528D3B9E3E8917F93B5774B9A7DC44AE416006D8955895B6C611814C99432F683C67C09C354B97DA3CB0DB93841991B764C9A08EB26B9BFA96EBB39027D6399AD2688AC047360A7989BAC587FBA7DA76153360298A3D67FE73C983E4563F67207E1B835B7DC7CC9CC3372E12DB6EC759B86A684702D2B6CC805726DCB04AEFBDA224C02405635040EF60FD799A906116410A6C5EFD587BF1778CEDA4CB0152A272B89E43017B40C9B974600F03908EC397556E8AA7271828C049F895753E7BA96569A280CA15F5A82CC1F6121B6F7AEB214C726B1C64F7A958DB7459D4A30E4599A71FAB28D5196288A443D6C35C4AA27DF674EF6B4B72FC6485A31410457C182304538424A7501A7D62086910ABE0C54CC752B5E8E87039E64233EF5B837C3B50286172DE5C9CEB92C9A0BBDE4E7B14A0419DC6AA03F655592D25DF4A6191EDB8545351B2D89A7FA89826988657763A93EB71F8832B159E690B95C04DF37A2C9024451A18088A1C801B40A601AAAA6EB692E229817D8A390BB2474A95A7131C84D1745272A289C84BC2742CA1097A610D8A90F2C609651AAF5D0414C3C3FB3D37AD8CA382C9980A52539BFF73FCDE029FEAB0F184A7EDE4C7142478253C84EA5D7B6DB963ABC39A6B5BC29D43BAA24B4B26C7C53DE096E85E945310A484F591AAEAB48BEF98353C17EEB457E7D0719247A62EA85400B23491CB65932200F74EAAD3DF7184A54654C7B6DC931B574A2A55C7679F15C5944191A58D2A5B24674FD80452B22ABB7305501D9A156D0C48C656A35540FCBD43F14F531557BB9E8A3A710C000AF227FC6878AD28A708A34320191A236B38E64F3C4E705555DFC1FA3A144D8E6A122F7C5F557462579765A017AAF4A814E6B1201CC4E8D0757C378198A5798D3A59186A54FF158A451C42564B4659E0A35BE734600210A68F8A64E3951E849CB1062BCD6335970005B1B69C3A4845226A2C0834C1A467C6A799609CB870C7370C39265C0015BCE968419EC7C58464CB518550338B6807A97528FB34D1011A67F15B06C1BCD7B5909047136702C9AE604B927F28B8918CDC6F07A5D60B38BF7CFF2EAAE3C075D1579A30A76093B7A6DB44AB21A722F818861480129ED03B1FEFCC2607B5A1D5BA6ECB91B75B9810F991DC55823333A927AC13C3C297EBE02A27B949F47CC70A2266FDC76B5B55468A6B98D33955BAB3418F2D3C1D206C29EBB05E97811EC140307F9347255381AE152113C2ED2A7C1812A93FBC67ABFC1C1233B864AFC4B34B9CD30358990F51477911D6C68338A9857335B9152C5302F32BD5602A9ED97892F14951F111CA2B607DC46CFE6297D0A41BEE369CB3EB941FC2701104713A1784D6DE88948032AC78251328A8C58311848EA02008669B4BC811D6232A859756B306F24607DFD812DE89A0A6A00304FE795DD1C4A55366E615957855ABE11D97C7BE95A43A757948C5F4C046E9DF6A70674541B20010837307443444C27AD36C431F1F372EA659EB0693447FA5C40E8A38A7472D4A1BB0180433585B0CEF74650733CD90094199ABDFC1392E24C6D1C74408D00AE27F05D1729433A90AD9BD22F1B6C8155F68BAD1307811770A749A85F060E74625893462CCD946E2C1B79B6CB3CEF971899AB29F4328CE29313E4794C3463AEA46106D9CB82B5EC39D83D27C4CB3B69DAFA2E955D002E61C3E7BB247A76042FFEEE7E", + "dk": "57C613B806BEA20AC23E2CCCF3B36DD7AC5F84843F273C8D9923CB8770A34A63885973AD2E006B45437722151C3D0539D7723AD1682473C378C88670D646646473A18BDC30367C136874BDCCA49E5C42774ED96279CAAB1594777100706BABCBFD46652F42702CC00C810C2F753263551C44C928B6BD319F1C1444EB014DF1A874282B99CD11AE59413ADF4A3459F9A52592B1EC026977E9B26022A6DC059EAF38854D49C4F691A0E96A031D822907C664D3E6B263B35F3E967167F953D91A05A5AA0C4F5B5B288745695AAA2378420B6C0803D855C3D42A623A67B3376712B2B299E3B155134FDB582D0D221CEE318FAE1309A906728ECBADD9CC298BA245A8D4C081B7BDF87AB4E56C07DD98488F342BD405B3CB327FBDD85C80D2766E2485E3A351E0A3039AA60738858FBAF5BBF6D9CB25592E1D82468BC6B23E678BC5E4559F125F69B414E1AC5AD6B4498C9738328CCFC6BC4E7469CCBFE7AAAECA8A22874727A9194EF2BBD7564DB3D927D85A716A4551903944A642B5131511B619323CB620435B501580354BE09C3E46AB78BC25D08B29440B9984E75D75F263A081A562A2C96D538F6A037A6CE9C1B9A0021E0591F874AD08032BBD18A1C6621D597A47D4311AD0CB91E4DA1A03952BA7718187B86BC6E396CD716E539C2AEEC8285629A5A7B4596C6B4B5B5B272FBC00F12B49355C1AC73B5EC245C3B6E59F3C81C76E9675F51616D4608795A7BBFA3B0B96AA90FCF55BA7768CFF752FBBF3C0E2847EA939AA88D0C077A5C721DC1F09D2100DAC98B9F49848A7BF3028931C72451715789C11CEBAD69456131B70CBC27882C598311A0AC50CE188BD4A671197934EAB72B8842157F364ACCE67A4CE358A521895DA285331C412A20A88567B93623875949734D2665FB2A907E03A74D24531294C6FB1B45588AA61655977330C0F46F5CAF50466EF66AA89F8C15145A6903621BA269DA593CA28C5C439BBC2B0F74D3FC213F10029FF66CFA50AAB701048383A188EF7A8F40A7C73C19DB0C92248C95A3F061D53E3A3E9D76966C62C711B7DADD17ECA87B418B891527CCDD872B328C47B0F2798EEB90A9B46C75009523CECB196F5B941769F1167C4AC86249A09521DB9C005BBAE80B1925D01476E5C8ED2519F579CB46A01B1A618AB228342F06993E7252FDED96FEC54ABC11142FFCC6181F2071BF1B5C4A23EB782A0DD03078B1A9C5433C1E1306BBF4C388386814BF859C1070A033016DD599CD221A35DAC93739C9B97435013B6567EA18E8D60CD3F8186BCE420252027FC1C91CAF785135300CE525351A26E1281C05AB6BF9B0CC3AC01706A7B7B855719D7290BF16064D8136A2209A70DB24BC5F693AD385779A8CB144C80FA0435EC6C4EC9492015988634DC88BE46164255B9E78910299CC52174654F48B351B418636A2D41A474384562F9141F37985C343265A3788F7A53414A94A9F8982DE444BDFDBACEE37296FE2B669C307EC0584E975654C3209B082B4E9454B058D439C7CB7FB0D80F2CD77B330271F287A0F481995E26AC2ED0B572F04FE5C75E3B256FD5B2CF6A953EF0A85FC953A5DB971CDE68CCB2F5A804699DDE247D4C09B9AD34BBE2E7188D2C90D862AE1DF56FEA9A8639029CEF0B73C7352D1C94A29CFC28325AB1D14100A7F79AB087A8EAA749119B7F96E29B93293662C57533B47F66163D31BB3E4DF28BE89C48227C3FB2E3673EF858C7B11D37C2658ADA9DF048299EB883472637C774012A935B17C72987253F211C27BA97AB867A5D35C375158A637273993F68B4341A644405C013273C6C881E49D2AAC13C15213C9352D3C84EBA1951DA0394E19B660BC622696AEBF8841912B2B3347D9C8CA1D98565C4AC93A5255FD91B41A9A1BDF255C6C0860F05176D41F58CC8305D40F2622087133EE968165B1CDF41B4A14A7061710D9C00156296C4C428CE2E57163C0C77F2C9416E89905586C29D012111B07C475A79A9D227D9A531857A77B4017F0E800739980BD401503B472749ECA34816B76A22260DC120C986AD57861DFD2B2BE7D184F9B95AFA859392ACAD78016F18479BE83361568001F9187BC22C35A2A0BCE4AC7840354F3E9C43D711CC12E57E3FA2BACB6AC8B7993FC698B48574AEE7F6ADECA360233371F95240FF492210971ED51709D256CAD9B57F0E48850C4B803642732C89A84439CD31C6B0F045915090168F8952B3382BF1186A56D2CBC102898F112FD91A2BE5AB0391A67C3C5255CEC88FACF3B6ABD427E3A410ED22C2C6C173F4894E9BF20CA3713CF0E8506846507BC762047715A7A37DA3A5730D8A1556560609E4CCB61298C4B2BEC374B534D0B266C427088816E843B118FA9CB27B9D1F549480F98F7F4B5AE71BA376B0B9180A157D8128D2286C4B5BC54F8590852B5CDDC5C11E6B4B36EC7CD6081D45A9C50272643CF0569A9A237581AD36D0705C004091F7C46D9073739226EFBCBAD5B551680C86E4290C3CA1AA756851A380ACFC033FBDAAC5B82C364DB075633A9A10B8137A05B29863AD1DA1CAEF5ACD2D75A9643B495EBBC184038B58B9A95998AA95B672A2D15CB78B0A00E386F433425C469A7677B8569CAC8F5A3A035C777B4570BAE1898FD379ABA62C960024E55645CA6625327457A37A92FBD68C76E79528D3B9E3E8917F93B5774B9A7DC44AE416006D8955895B6C611814C99432F683C67C09C354B97DA3CB0DB93841991B764C9A08EB26B9BFA96EBB39027D6399AD2688AC047360A7989BAC587FBA7DA76153360298A3D67FE73C983E4563F67207E1B835B7DC7CC9CC3372E12DB6EC759B86A684702D2B6CC805726DCB04AEFBDA224C02405635040EF60FD799A906116410A6C5EFD587BF1778CEDA4CB0152A272B89E43017B40C9B974600F03908EC397556E8AA7271828C049F895753E7BA96569A280CA15F5A82CC1F6121B6F7AEB214C726B1C64F7A958DB7459D4A30E4599A71FAB28D5196288A443D6C35C4AA27DF674EF6B4B72FC6485A31410457C182304538424A7501A7D62086910ABE0C54CC752B5E8E87039E64233EF5B837C3B50286172DE5C9CEB92C9A0BBDE4E7B14A0419DC6AA03F655592D25DF4A6191EDB8545351B2D89A7FA89826988657763A93EB71F8832B159E690B95C04DF37A2C9024451A18088A1C801B40A601AAAA6EB692E229817D8A390BB2474A95A7131C84D1745272A289C84BC2742CA1097A610D8A90F2C609651AAF5D0414C3C3FB3D37AD8CA382C9980A52539BFF73FCDE029FEAB0F184A7EDE4C7142478253C84EA5D7B6DB963ABC39A6B5BC29D43BAA24B4B26C7C53DE096E85E945310A484F591AAEAB48BEF98353C17EEB457E7D0719247A62EA85400B23491CB65932200F74EAAD3DF7184A54654C7B6DC931B574A2A55C7679F15C5944191A58D2A5B24674FD80452B22ABB7305501D9A156D0C48C656A35540FCBD43F14F531557BB9E8A3A710C000AF227FC6878AD28A708A34320191A236B38E64F3C4E705555DFC1FA3A144D8E6A122F7C5F557462579765A017AAF4A814E6B1201CC4E8D0757C378198A5798D3A59186A54FF158A451C42564B4659E0A35BE734600210A68F8A64E3951E849CB1062BCD6335970005B1B69C3A4845226A2C0834C1A467C6A799609CB870C7370C39265C0015BCE968419EC7C58464CB518550338B6807A97528FB34D1011A67F15B06C1BCD7B5909047136702C9AE604B927F28B8918CDC6F07A5D60B38BF7CFF2EAAE3C075D1579A30A76093B7A6DB44AB21A722F818861480129ED03B1FEFCC2607B5A1D5BA6ECB91B75B9810F991DC55823333A927AC13C3C297EBE02A27B949F47CC70A2266FDC76B5B55468A6B98D33955BAB3418F2D3C1D206C29EBB05E97811EC140307F9347255381AE152113C2ED2A7C1812A93FBC67ABFC1C1233B864AFC4B34B9CD30358990F51477911D6C68338A9857335B9152C5302F32BD5602A9ED97892F14951F111CA2B607DC46CFE6297D0A41BEE369CB3EB941FC2701104713A1784D6DE88948032AC78251328A8C58311848EA02008669B4BC811D6232A859756B306F24607DFD812DE89A0A6A00304FE795DD1C4A55366E615957855ABE11D97C7BE95A43A757948C5F4C046E9DF6A70674541B20010837307443444C27AD36C431F1F372EA659EB0693447FA5C40E8A38A7472D4A1BB0180433585B0CEF74650733CD90094199ABDFC1392E24C6D1C74408D00AE27F05D1729433A90AD9BD22F1B6C8155F68BAD1307811770A749A85F060E74625893462CCD946E2C1B79B6CB3CEF971899AB29F4328CE29313E4794C3463AEA46106D9CB82B5EC39D83D27C4CB3B69DAFA2E955D002E61C3E7BB247A76042FFEEE7E94666B893AB96697ADA5692E4E959DE6DB5C00F2B2353E615C5704ECCDE45D38404AEA8B2BDAF3FCB7F4FAD5FAA16EBA8A4BC94618FE14508C39F39A66BC59DD", + "c": "2467AFABEC5F378284AB6501C7322603DA732D11497FAF4C59B2E858222844D4780B1F7B0777EF4B7F61DF0253584BE5C46638535FB39072286DB984DD3DE335282458ACD297A585B64DC354858A8167AC4F4E1D00CDFDDE658A6D217C9C1255442C66B1B6F74EB0529A54A8B07290A9E07D2F74B18345757E21894639A8267830E6B065FCF746F8D3DFBBD23878B76F8B606B1227BDA4F221D2CA559BE133DDF9343811A5E5B3B0DFA27B4F9E24D86B7E959A9FD83392EC4B616C39AD9DB1D96D465A509F92647E4149A9D38381457A3A45A393BE987886FC7E8CDC561341383E35FD80680FE7F2D39DF791681D3C6A7C74031788C1D92F1D731F4261E5E385D9BD8D23D37B1AEBF2611707A6CF7C55418FEAF01577A2E26A248E02AB9F7FEA4A79CE55A2E4A8733AD8B3DE19639588DB04A5D8EAB7A1BF139C2BC0028E30988E3F2C1331B65AFC026FF68C08D3111B8E919A380A7CF4EE02DBB48CF552221B6C55C1C7EC9435A44316A6A8C35C8CE1F36EF657CFF16BC06A4F42CCDA96082CCCF0F903E5F1870B5BBA2EE4A1CD2EA06BF782421C8FCC73B43AFBA339D4EBB0FCA2958473FAE663B62DAE9805D1E7B469EF0F121A3528B4BD07556635EB0D3A83C7D3F776264F3667FE41C5EFF8B1861377E1671E2BD552202CA3F26A98BBF7E2453C1910F686A2EE82221ED50AC18A8538E02B7C70BEDB0E60B42D894B232073B8A222C055A4DA8ED707DF8F63471C7E8773DF9D0B3A4F0CA2861B2B8DD74AA3F216003672E5B132890628C7F279AE70A509E7A744C285F08ACB6BBE7F75D6B5200A5530188F93BE1D4416FF46A9BEE9E77FCB9079E11B264471C9F6FE2AC6927D3FD860A18931ED80D6AF7424FE3C93289D7787EA6334854DF131046E40C8ABD10FBFF2D4D4507352A619F5BFFE9EFF570C59D4DDEF3A1443EC91725F4488521E8941646B7E040DB141AB414E90E38E97F04F7BA3523DAB892494E5F2AF8B46E84761079AB191AFCE3571086A3EDBF02654791FBFDCF604762B84AE98B4E23A4F8CE9471A720C9C4E3AAB26CCD831361887DE84637B275EBC41BB4D98D53670603242297254B8E2C240B62A29EAB940640B2625FDBE2ED8511D0C4F2E04507177AAA81DA30C7FBFF30F7A4F03A2876E5C91722AFEF4DCF7929B3A1055645A7DE5F96CB13A81F7FABE6717E86773CD031390D10A36CB9E2A1FAECE1F318619FB2AFEA3C4C985630DE1E2651DA675A4930AF07A5B64162B28D16E700E3B389E5F142ABE21FF972B40F8EF6DF51411685F350BB6EDE53054E93ECCECA9384770B45E206ED7829D59E90A7345128ED2D4C8FD74075B240C47787F8D8AD3CB3BBBCC796328E701510BF5999EFFCB75FCB30B23D4B8F25D607901A6A942D263E5D1F4103914BEE27C4342F34591F923CB81D893AE4F4FF0B8B23076240C8B034F31D69622A6068C9428CFBE4996C1259EAFBA0DBF2AC43FB876D11A5A6F7944DE18DB2BE640F812ED6BF68A6CD09925D2EA64D46CF6BB5D3DBCF5BBD42D932FA017411DADE4857C279C70DFC12BB3BBC9AC09E21A7D7337E666EC9E823C0A5B03423F3398B53B877299DAD9097F986FB11C8E6E4C9673A9D10AC9FA80A23A88A5DF3BB7E722BA0439845EA58082534D0D7BD495C62EC40A86BB39EDDBF508DB899E3CD037CE1B08286127B3E62034635A98C1DA1E03CC60E0C5962B83CCDB942A33442F6BCBFDA4A5746CE94BA762ED1768C974281EF1736346708E4CA4D3EA7B2AD6462E807D12C33A8786D1BB3D384A6D5A6A739661A553ACE176044F5BE194A3C34F5BD5F23D4A2741D79C2799F25C486B51BDB1216CAF00FCFD1B2C1864807D347784E1E6C268C1A44D2D1603F544C7FAC0D278FA3386BE2E67896B39C965FED7A965B48E3B41F53EAC185352305DCE69DBE5F3C2EA28A6A87F1D5F1F3D5414CB78CF3195DF57B4C002601C0080C86F0E2D48DDA703E5F6234FD2B630A3FD65F2788ACECB31DE9E218686875A610C25EEC894E4CCB1D8FB645C97827DFEA89EDE57713BAD1F3CAA3D6EBC177F7F3B8FBDC61689952202B5AF485E2931EA07C89A8FEB0D344F216E82C4036BCA0FE766162C804EF25DB55D0D69617166D4DC23933956E13EEEB85695683F74D7CE5E162A1C5A0ABDA10D4C2E9531B4A898E6575179EB571CAE7D5848B065893E8FFA721DB4BC3C8F7E767DCC80C346CC014223", + "k": "77A12A7C2BCCD4700A35BF559EB1B8062628C5F7D540F2FB50A99516A11F639D", + "m": "FCB46FB66E388182DF6149F60DBD0FCA88D1BB1A9866A2C97B84848531230B48", + "reason": "no modification" + }, + { + "tcId": 68, + "deferred": false, + "ek": "54B452960A93BBC12032E0507F7B83F112BA14CAC4A733700AF288D6DC0918C2B3D1625F475083E7967ED8A708B2B147D50658E1881DA6501D6AC6B7EF5AA4EAA5A7AB85844E3994E44A5431145A873834EB88A177400E95ABA99FCBA079914074209E06E17CED04636AB4ABD7824B98DB2A35215D5FEC091D5428B2928B809AA94C57694B2B65DE050817D6AD7326687E9A68695151F60A9B1502789AB8017760A6F3E7029B5074CBA929765B5C1DA8217C1105535699FC59195ED3A0E8799C66E3264F692C8DA198082860793446FD0536EA0301F5104AA689CC0263633F7A436621864099AF9C108D882043467B4888922D2254CFE8F937DCE040AC5B8641102959A90539F5177E21AF7AEBAEA2D9731AC87150A52068A71C183B8F4BE312A033719EA12E2CB8A197C1BA28B093E50437FF9779F0377BF5698557B9A45BBB7C8ED1AED0D982D71993F80CC5E7F16330D142BD0AC602F42DF89391156CCF1621AEAEB95701933A3CA82487E057FD186199BB5F4E2341D91A1D5B753B53E3719F65CBF0B3AE33153461459708B6B6E1131C9573C7B0CBCDF3A1C8ADA919D09C020FE6648221CE7AD35AB37C16010A3CAB1251B5930EC69C1728CA45E6639E97626A09469A6E204386E6A458D35E58ABCBE5C279BF79BA85021DEA6B6DE6E9A802198B969560F2C8C99328C5427207623C03E68181851401BDD615E2263761DAA3D0D16324FCAC9FF98E85ECA88FE668526501AF4C135F259277202E96D56F91C07D86692C91FC14187B99F1847EF11AB06CC019EA89AA88E114C034608C03A77280BC1B96307F81531009278193BBD1F5ADD812B278796309102CC2CAA9CF8C127472C4C63B47015CB852798379C73D0C4517E985ADC6F60E49053CB2B5BEDE0230A9E9A138C44178489EC5D5C2F069B737A143D6802454647C1B8C0837B43A89C879A0656CF087C733B7A1A7D153E092AAF193B6334A729B2B9F64D311090B29BDBBC5F1CA5E054461EEF72CAB14580B505BED3543ED15B02E33AD2A63B6EF980C407998AA5C357705B047D1848B4CB551845D3FE9A2BD491AD8E60308D880D6C56607F4AD24616845F092FCAC559CDCAA6FB16F2BB19475B700BC16C8FA8526055333EF389F6983C105E879FB4738166A1705BB625412B847553C462145A13175C60820783998150C40A2F673A3117FE1778A0A4A75F37BAC7D8A6C9690870D6874D2650182FC51C003698FD164BF5314FE3A4FA291BDD9EC3920F5A656000BA05A8F6CB020EE4701E8D8AB8BFC8DBA31887E65C7E403BFB036BCCF3C281ECABDAEC3984FB87D1C97C1F1112F8252C31A986941A50107D40EC6CC67E6E20F446C598832061BA21212E37943359B6B005621BB275235AAD581985168C468E15BF6C56C9AB65C7574B44FD83A32ABA5CA9831A6769135FA9916E3729361CF0D1142610C9A98363ED6642B853461C062C7D0B9B5F70694C8D4C2F073AE788A9CCA13446CD6BE40C82478E338C5DC34CCFB538451B6F94877A4B56B5AE6B3136B9BAFA1CCCC4902585907331C1F4811602716A5EAC209953B75A3B30EFD1B4E42F716B37A2F79E2C8ED062B1F79976C010EDFE4838929589A90B0A0ABB3E41CC8AA974C4C1308C4E12FE2D24162738A3811070D796701929C12E9A94FA96A823B6903498C4862732D48122D0265B0E571F0B4C43C62015F422753B2A562A80D68F19E2637581AD77592B67AC785B923AACD631A0B53D375E911797C0B76C79C53161015DFA7A67D1485C21A5B039A609F7386F8AC339B962472907D48F753314155C78A3DCF2010B1880C48196C0CD3B38B79BA9243CCB4AB5DF9D4569EC11F2F88525082B1C2224573C94FE3D24927B7AFF7E44B27755A0DA4C8053A7B8876AF4F809C22205B710B43C4D8B046CBB562B2BEED1C27CE736BDEA5317B658139509E4737C52A77186666947F7796D4261FAA8B9767814B7D096856A272BF6572B4998D2F6128D3FC6AA0FB2B66486A578B984C8835D1223D9E446AE6752D355A0FA09379F108ADD50683AD57AE731942C4F9C938464EB95C4D08264456F565E5981625FC75260496D05610CEBA5A751560059C38A8E2809609BAC2C853B819A781F61A7AF0C6FD728D9DB2C5623521D762440568272DD8831A4AA1B2F4CC8016BC53964CD7D3262D93710C56033B0F515A7B9E0AD3D6CBF0049DF4E55FD931257F", + "dk": "BD706C3D795690598DD0B25656791B6B6B40262B01474B55119796CFB2642E827DEB6C21F8E8A9E8B10C78156963C1A81D66580F061DF187A7C19984CE9ABA8C598EA109C7EC0173CBEB9DC3594F87772DF044AFD5312345F499ED502E5D42C5ED280BC35B1F9B79C86E00A9DF6422B5C8CFC455544EFC91542ABC594C7240747ADAF429A9B7C1F0F8BD7530B1ECD1CE98541EFA4032BA23CAA16B723524A5D9223CC1FC954F56B2BCA820E0E50F30696ABD11AC5359615A17815A155F7C27C84B0A85B649C8E3C75C8003A9541A77EDCB2FE00376EE25A0FEC314D6B3057D21335D52607504B278D5A05AE4C653458525393149401E1B2751FCF09831831A20899A115BB0D5585E64F42AEDE11A31271FFAD587C8B6117B346BDE545B88311349DCC89B39664939AF3925A289353FC5F48B37F547A6BB2CFD1A1B1A1C245D74078E0C8CE9172D4F853DCB35B5CAE79B26C607F25530B9500D1E645904E4047424309380C3332B0001B11A9CBA8BEF28161995411503610773A801492AB47C4AD32A08D9D621C08B553EC2AF4010CF0B8B6D894B86B4E8032C535FA39B0053218515C6B27E807C73EC2B966601FA976367005FA0183340534063D6CBDDD46287AA78205B5738D49426F0A5E87440FB01B70EBA2EF522743A65AB88736C1144093B76A1317849A5C9CAD9119FE6E5A8CBA27E0AD9B1AD6C3EE7238B386B7DB24872DBF09C6FB3485C58669BDC4264C5CBEF94200DDA8635B0AE23455F156135C9BA68DC675FECF3568D100BF022CA70F09AF609262B1636006644799038E5903D39688BEF9364E6482EBE347EFA71231CA1B08D0B2F83E5302F205AFF055DCBDC4B309933D5C737B35806DB19A3CC62A63AF56652833A67174196261A091918C933C21CAB913BE2965E760EAB34AEBB1B756F028A4DA7B0B6C20C43CC47BBE837A74AA5B42180B31333A2E6887C1616292C9C2855200006C34EC21C4BF3139DB74C1F06686BF88233B25B6C59A332372FB86A45568A120306428580BF72E082886C240A1980EB027F61560BCC1906DAEC1D48583B4AE85366840CBAD733E5AB2DC5044C9500A1ECD7B1060CB870A705F73618F0DB015A4BA33CB57ADC33A825FB3761F0758B7B7DBE5C4377020C8FF30750E53CA05C6F2E2704F4149267EAA355F2878A89C8E7394268437A807BB29A839FB2173D85102C8F06BC91B3679905200D581CFBE69C9BE25A53641D4619C12AB887E618B2798570C61108884C7AA22A3727A08EB5653F9E869678CA049C55389B9A235D27195DA868BC82C3A572B8CB878C96EC0FC0A07511923A23069C26CBAB2B879F40C081E55772E9A9A8BA826719185D627342A0411901C6396E0A086946A271B64750B32673266975A124ECEA8F3FE66115F543C9FA7D64064EFDFB368038918F5773344A2D01B288E80321EA67BC9FF7614A8BCF3C92A77040B316E66619A68D000CB60B543DC3953C3F92BD14516560833273542B3C1ACD85A49FAA4AB1C9474D8F203B8D49C66005364AEA0214444C779AC700F8878C15914D0A8CD2DB8C19F3943DFA17707C268381CC8BA02195B689B9362C5DB137BDE853A97976CAD043E7455A1CE2A86DA7701B884BFB937C6444150C68147DC0494B0B369D82181FDB90F8949AE3FC5283DB35504006F46C6EFCF08FF60330B720826722B945E3233A14CDD11AC888F3A561E767F6F48C2EC92DBC76489EB516C6226E063C08E6208228CC14940455E9C3700883BD6158074821CAA410A9AA6C3DB41A1E02367163E761260A8C1205B28429B53A6408DB144EEEE9BAC587521D725529A75C8EF83F2A4BC9F91258443CA265ABB54DA06114541F4B1B385D677C33B473BC0045A64078F84C977A3BC73DB8B30643B3CEBB073F0B2C0CCC8E7CB98F94242F50598447A84CDA593396490CF74071256B0F5EFC0A2EE9732E611F07487A839261A0677219838BEDFC5CC932601B500340777F0C7A92AC18596438C04EA82783EC3F119B8BCA09A4BE77748E9C83FEFC3B582110415C6AB5C76EC830929185172B325D9439CD96AB463D3021435306AC72BF476A70BF96A486537BBB87467B0329E855B5B1E7CDCD405EAA3C63E179277A959E5858AAC275964CF9569FB22F18C5C175930406B9CB89085D9230309030A554B452960A93BBC12032E0507F7B83F112BA14CAC4A733700AF288D6DC0918C2B3D1625F475083E7967ED8A708B2B147D50658E1881DA6501D6AC6B7EF5AA4EAA5A7AB85844E3994E44A5431145A873834EB88A177400E95ABA99FCBA079914074209E06E17CED04636AB4ABD7824B98DB2A35215D5FEC091D5428B2928B809AA94C57694B2B65DE050817D6AD7326687E9A68695151F60A9B1502789AB8017760A6F3E7029B5074CBA929765B5C1DA8217C1105535699FC59195ED3A0E8799C66E3264F692C8DA198082860793446FD0536EA0301F5104AA689CC0263633F7A436621864099AF9C108D882043467B4888922D2254CFE8F937DCE040AC5B8641102959A90539F5177E21AF7AEBAEA2D9731AC87150A52068A71C183B8F4BE312A033719EA12E2CB8A197C1BA28B093E50437FF9779F0377BF5698557B9A45BBB7C8ED1AED0D982D71993F80CC5E7F16330D142BD0AC602F42DF89391156CCF1621AEAEB95701933A3CA82487E057FD186199BB5F4E2341D91A1D5B753B53E3719F65CBF0B3AE33153461459708B6B6E1131C9573C7B0CBCDF3A1C8ADA919D09C020FE6648221CE7AD35AB37C16010A3CAB1251B5930EC69C1728CA45E6639E97626A09469A6E204386E6A458D35E58ABCBE5C279BF79BA85021DEA6B6DE6E9A802198B969560F2C8C99328C5427207623C03E68181851401BDD615E2263761DAA3D0D16324FCAC9FF98E85ECA88FE668526501AF4C135F259277202E96D56F91C07D86692C91FC14187B99F1847EF11AB06CC019EA89AA88E114C034608C03A77280BC1B96307F81531009278193BBD1F5ADD812B278796309102CC2CAA9CF8C127472C4C63B47015CB852798379C73D0C4517E985ADC6F60E49053CB2B5BEDE0230A9E9A138C44178489EC5D5C2F069B737A143D6802454647C1B8C0837B43A89C879A0656CF087C733B7A1A7D153E092AAF193B6334A729B2B9F64D311090B29BDBBC5F1CA5E054461EEF72CAB14580B505BED3543ED15B02E33AD2A63B6EF980C407998AA5C357705B047D1848B4CB551845D3FE9A2BD491AD8E60308D880D6C56607F4AD24616845F092FCAC559CDCAA6FB16F2BB19475B700BC16C8FA8526055333EF389F6983C105E879FB4738166A1705BB625412B847553C462145A13175C60820783998150C40A2F673A3117FE1778A0A4A75F37BAC7D8A6C9690870D6874D2650182FC51C003698FD164BF5314FE3A4FA291BDD9EC3920F5A656000BA05A8F6CB020EE4701E8D8AB8BFC8DBA31887E65C7E403BFB036BCCF3C281ECABDAEC3984FB87D1C97C1F1112F8252C31A986941A50107D40EC6CC67E6E20F446C598832061BA21212E37943359B6B005621BB275235AAD581985168C468E15BF6C56C9AB65C7574B44FD83A32ABA5CA9831A6769135FA9916E3729361CF0D1142610C9A98363ED6642B853461C062C7D0B9B5F70694C8D4C2F073AE788A9CCA13446CD6BE40C82478E338C5DC34CCFB538451B6F94877A4B56B5AE6B3136B9BAFA1CCCC4902585907331C1F4811602716A5EAC209953B75A3B30EFD1B4E42F716B37A2F79E2C8ED062B1F79976C010EDFE4838929589A90B0A0ABB3E41CC8AA974C4C1308C4E12FE2D24162738A3811070D796701929C12E9A94FA96A823B6903498C4862732D48122D0265B0E571F0B4C43C62015F422753B2A562A80D68F19E2637581AD77592B67AC785B923AACD631A0B53D375E911797C0B76C79C53161015DFA7A67D1485C21A5B039A609F7386F8AC339B962472907D48F753314155C78A3DCF2010B1880C48196C0CD3B38B79BA9243CCB4AB5DF9D4569EC11F2F88525082B1C2224573C94FE3D24927B7AFF7E44B27755A0DA4C8053A7B8876AF4F809C22205B710B43C4D8B046CBB562B2BEED1C27CE736BDEA5317B658139509E4737C52A77186666947F7796D4261FAA8B9767814B7D096856A272BF6572B4998D2F6128D3FC6AA0FB2B66486A578B984C8835D1223D9E446AE6752D355A0FA09379F108ADD50683AD57AE731942C4F9C938464EB95C4D08264456F565E5981625FC75260496D05610CEBA5A751560059C38A8E2809609BAC2C853B819A781F61A7AF0C6FD728D9DB2C5623521D762440568272DD8831A4AA1B2F4CC8016BC53964CD7D3262D93710C56033B0F515A7B9E0AD3D6CBF0049DF4E55FD931257F068034A9F16D0024CC9BB412EA9C778DE819A4CB27EBE5614C8994C9F2DDE25A96672A036E27BA0C2A7ECD385E3F4381DEAF2BB1EC0F30A8AC7B01F0A15A0716", + "c": "F0E6EFFC0E4FFDDEF79E12EAD79C5CCA3416B4F5E251DBE96E14A1E5865FD41C3A45900AE13534BAE5D95CDF84A02CB66143A44B86ED2E535FA1F0787F0C3E3B9736CC02D88A169D698C3ECCACCC4E2569F06A470CE0D012CF2920F9F04BF96C80CFCB0686B0CF93F01F28DD66ACD772A68B978DA2BD77E9C65178FE8FFE23509E440030ABA284F4C94DFFDDB2393FF8EA554AB99D568ADE6DD18B3240EB792F004216F3B528A4BF3B6DBDDE1F19F51498AB876CF9492D93CFCD060BA476E91B12845FE7BB290E42841B7FDF4056765A6460FDF4047B8DA73269511D748A27EFB971A9AE4233555EFC77F826F0C0BD3E3AC9BD2ACA40C7CEE537BFB288CFE14788366C04D9B2460775774268EFA0C3C73B5B60675750D65362D97C43341B6B559EFD27AADE3CD256BF89487DFB9BD467E3E3CDB7C06539CD20F314EB2E0582C1C46FAA5E8E6918EE28B2DF21AE24397DDB1FF70AAC4B7C861876B2A9034DCABC05CC4768494C77F3436D7F2D6CA8EA7CDDCA32D11BC22DC59049873EFB2A113AC61610C8833665ECCF7AD30936673371B0F9B561833AB5B76B2BA0FE402394C57692F900F01842BE61C45AFEDFB88194626E533BED9C9EE00CAAC2400FE98B66A9EEAC83CB7A337CC7731E90FFF9AF002B92DDAAB612A657F62B422C233CB019939EA79C434F71809DCFF197149C08D76EEC52EE00CE5AEAACC68ACF75373F20EF63F6195B1D550836E847F14FBBD48ABE5BC70698C46FC8C05856398686E249FA189B11423F4663092C74AA8CCD080FB100FB89060AF9813CE8E1EEFDEA21EA1A849DFA066200498F99BD3FBF4D57BBC992C5C8BB0918DB64B59DED4F5DFAF5DE70B9491E33AAEEFAEAC4E56F9D038CF2CE7A706A290E4CF9996387C789E0C133D5E1ECDDE5452548FAB8243BD5344EB3EDEF93465A53693EFCC664E0A845135C35E8702FC692CF64A7F8DBE02397C514B9918AB946F83C557CC85E70B258767E0FFAB91D4A1377AA7FFCAA5E1A43D07D1AD9649368F0A40E0E0EFDB16F68042DEFE20A75CDDE570B54895A03BAC59789BFA49633DA8E1B50552904650727C0799AE441E1499C6FDBA71FC0D362535EF708C8B9268D2C9962E777AB94F6A6390EEA9E296D46CE376EB295FE0B1E8E8FBC1B9ED154E32BA81F83EEB4BED921102E284D671961FE849E7EE7DB54B4972A6BD65022B8F5C3324AED5B177D6699D64C0D12462E35B0A00D66655DCEF462C7EC070E8D402B33AC617D8276CE022FB9550A6E4BB320DF06E903E7F5081CA65D644997454CD2EE845DB85746E91B9CEEF823D60665B930285B9D13B8120474F1E0C25D4ADAA3C9DD1AA33B34DA066C8527CCCB844284D4DE9A8F7E01CA702802C49FDE099442BD010224F83BA5FE71CA01EA4CBCAF4B01AA4E128B86E8D1478A4E06D8A107FB36C5FD6A73CD92E3CBE4FF1C18E972A552E9E733536E97F6B609336E3BFEACB0CF89D7D110D4A422500BA6A80EB169FECB4AF0C3AFC9B8BEF2EB150BB23B362FDB5E097CC75A17E25673DB42E434D7C0D331F8469456BF01F5A40DF00A7B07D955A8F47241B9359C8444DA41764C6F6B90D1BCCA4BA61FE386E63F4B51FF2A6E4242620463FD4011EEE199F748A572284F817521CB59B7EC568F9EE259257E77ED1B3A209B3B9E0C92FC96BEA77B0494D1004F84D299DF67A8E37668C98672A3F896A82D7C4D05A8E78EC412912085B3A63511FB1275EE70A28ACA0B879D43100DF07D43E9AE5D68224BD7A29658C1342F0D5C920B4914CEE39B0CEB3FC10E5E2D76789795D1C136E82E94E7951B370C3E3C41A8811C789D74DE1F888AE9C36AF369596F9FFB654A707B5416B2BAB90D52A4D4958CA9F389D1C46E4574848D2BD9132DCEB5A1B71BCDB5AECD627333358B0F311F6A5356161D6E78F6AEA499FF4378FDFEBF2105210D3E48FE5DC992362A9347A02CF032A568B6337BCC71C40A4AB4D64860BE0CE0E336E97E18063AEA8133C77B2B53BF9E9DF7CBDD146821E0CD1A1BEA0C73BD25D30DBFC994FFE911EC1CEC3524DBF480E9908439E00DEE4E3765DDF0C5459858E4EB68A0570B2EB6F8C1D90DA25215B10F2F5AC9053C243019524B82CA9AB0E184BCBACB131622582BEE592837EDB94FEE88B4AF8668714D8A7AA30C47A90CC0EFB1C421000FA6D2BA54741B238193E86CBFE4F7956B00F2A857417F95C50D69C0EB", + "k": "80376EC749550B531BC5CB538F78FAB38342C7DCD74B83FD83CD058227B9B3BD", + "m": "4CED177C0A454052BCBD682B39BEA31D0D219A73184BC00C100964C25BD106D3", + "reason": "no modification" + }, + { + "tcId": 69, + "deferred": false, + "ek": "C701BA88063589288E73E4BE1AB28C6E3ABB70AAA03F656AE87B38A9EC947786A41D722EC63C0E9E8C1DDA078E28608D11E84219E35239D8030C212F34CC284EEC748D34C6CAB04A7F3C15A5DBA8C74C8666167CA4508EB47774A7C3BCD6589306FC6365D74018D2082DE1753A854EC6FA7813431D31C6A3FA711E03F042E6251E2E27787BEC65AA8CA47FEB5662599083E6944F442716342DF25AA551C36643EC3B9598184431405C8C8EB4AC8360E1789A06B2D13232E831C39A005881273B0086591760AE8A20913D942314F45BA5094AAAA05444469D12C20566B0C008CB2C5FB90257929DCB648E0D616001095309E00FE19235DD29B1EFC2A80E1402E851CD19D2BE9B4001ED214E418C156BB6BB85C0744C3B81AFEA59BBF055C8046386B576BDD009CB412D13B3918B19A658C690726BC93D4928F1B2A7C386320D41BE98C1AECFB75288B94511113B902489FFF157DEF97D762A5302B89AD18546F5C9262C06C98F62632681859D132F756A7008B76CD92C760BB12EB276BC5611B5A1F20A22982AB7616F8802136F54815D66BDF87859C7A79F29769AB4CA735181557AEB9D76468D8855302D4A5E9CC171DC6000C7363789C3A76E59905EF5686C31C765541131E62120399B16CAB27A4677C8E36150E728CE747D2C2B305CB780250CBB1282044B5443DB128695F4A6637102ED3469E3548592D3BE83FB30FDCAB034C1499F69ABDD174E82041FA4CB9B25773BAFCB071BAC2394B6B9E3D5446289A8E08339D91BC12E84ABEE2BA51A563E1DD154E075CC33409609835A8345C86EF96B31F28E3B42ACEAB464380413F475B00CA904E958CB260B186E3C5CFC6068914638AE831D8AA78BEE7B65B9233F8950783973C4971AB0C3BC9F7A7A5176083B4B9B1C045157738C460F77A6D9311A3591789DB0BDE85C3A863594DE182D789A7244E05FA05965A4294FDEB2AF843CAB9F273687E3487C4756B0D441303C9C8B6284733652F074B087288F6BB08AEFA990517C08E9E984A4029FA1C420FCB19FAA78B61C35B4DBA021889826108A1A95A6816DCAA08D535C77959C7EB20209307996592E94DA842A52C329E3625CECC6A8624EDDF7B77C2264933B7B263499AD0930F539C0F24A14A157A56AA469891403BEA0A3531CCFF5A217282652B027513C05D03FE142DD14BD85755507473AC91767C69CBDDDA71CAF8A12A611C0F7F50CEBE87BE9D88514611A9516A6433B8FCBA54527FA10532A808E57979E73C8EB444DB3404D4888370A419E1AB04760617AA0E66BB2E715FB17036D300D9F3480D691450BF0571F875EDFA668D68B16D426668A68BE91F1337AD15577375477045633984AEE80824A08C486F25443E61B47658D03A21A51B085C656664B8345C1149CF690A9B99543B9E98CD090CC4B57C5A1D7BDE6E256E2059B20752E44331486515083DA5A99697A47A342BCD9679C77C6A243896B05CDED231919D0448994ACEC094E082A7434C9A3F6B97F21056CD827AB2648613B3B95CA065E1B3CC3740BC7F4F156650A722FF26D70E5276F53267CCCA11513A719624A2F1BB99677B845A436C9AA3A2D1202F1094F9040813B26BA6DA05E904206DC33A665959228B62BD9391133AB21B79967AF31CA0C727B464A8737535973042831FB06A0B89CA65B6DF8F3983037957DC838CFE0C65D7791D3148A3FB59656472BFBBC8AFC7C6EBBCB6BD83B6760643425FA72FE343DEE61187A73C98B9000E2577990F9109A8B1DAF30BF384227D45BB8BD4CABFA4A9CB20B0B81152BB46281A68445F7F78AA56545B59C75E9852912870373B1CCBB14396EDC70C2C00896762A129B775B4B9168C97F9A259FC22219DDB0CAD614C4F06030140A1F335B033AA2A1753CA5E2A2ACBBA83A3CD65978686FDB8959B4F39CF41B98EFD2048241B69B27AFBD142FD5046AF69AA3EBF67ED1632C4683B88C6BB7B388B4A4D7178A8ABEDF1523A6816F10C40065056DC9393D21F76A48EB7C122331900406D960A4D46C9EF12429B8E4C45C4032F089458818C759584947F6415D1468A6436E764CC86E725A936000B242155CA0A9B884B69490CBD223C76FBA954319161748706CE5A31FB067C20663F443B885E4C5C1A421D589777AA4C13555432AF00B27571D8217B09AD4BC9732C8ED10BB8841315539DA5DD99F9A7FACC71557853FA10547CF7B89E98345", + "dk": "5C9509C7986A2EB53A2BA32392CB6D1C103793B5A8D2938E635B3BC1124B730B63B4A061DAABCD2257C733AA010357376D631178D231E30037625BC6CC9192E6678D815353E6E10519586385F6224526A3662687284AC3734C7A4B5C16FA2B81D9568CDAC1CCE8A01F9BA991D2C2693A2569A9C47E378C591CBA78870449A977C11E8B8117731F815ACA82365D709C2C5E532CB6FAA33D9C0D36551B07C8172AD48D424C818F47C1CEE1B0AC0C80565A2D9D397129557DD2C0372A898A79F5ABAF4B07400C359CDC7A67844AA7530F3ED4A8E9AA9FECE383B37A365FD6A6A980196C4B3AC7A6B511671769A9888267514E01A45A8125264781C9C1B7A7F4143359217A455A6A2A00E1C38FCB174BBBD1729270661752BF56B53AB9D1766D3CCB1F6A537FE37E6C30329FC1C5B2E62BBAE28AF9310E5F773FCE940FBE9C6A0FA302126A98BC87BA830B77B81154BC525FDE8209585B95E810384BEBB6156A6A77771F74392F2592557F4C8556D8689C2B56EDE29E0821304D9255E063C7B972C6DACC860930915411CBC1EA62E11B45072091E7F24333613698F842D5374513A69966A61842509ACCA0445C51366F7AC7CEB0B6681116C8F4BA4AAA256E8C6909CC596F167F9FB1AEB7533DC1F2149EB14A8F6531D3F36CC6A339FD3A711B94067BC4BBA63100385396192216741C8AE5FB955B7B4E80A23049603B7EA2CA0BB2A79800CF533B50F133B345C2344061AF6EDCA4614299701040C31128D99C1B851497A9BC843F537F7D31A16B65490EB1158EC29E4F88B722D76AC1F58C05F3B4E0F6CD9FD69FA86898727AA9E799957BF4B4893A67B624C285E2A99378823AD60AF5D2287BC703A0E377F84539A19C1B13BB5B6199A355728F6B313931B566FC54C592410E81A7506E60BDF4525BCE9C73CDF7C58DAA7880D8AD628A51450606FD0325F0CA3D75CCBCAB41AD7D80391147A57201D0A9FA06DBD13870E4051B297753A8075C3B2C5404C9DA6A20FB12CF45AA745C05A219D21DEE1793AFE144221BB2FFDCABA47CB6BB4B0F3C25AFA5938F5FB566A28601D6783488E2671DF06115C125C0D93AC13A8CA4ACA2404727F6D13194C563B602668D886FC45B3AA8FA357A19BBC06CBAA109B9A47B01D814CA8CCB2815C8AD8F466A936C0659234888B8C55F71C75792896CD9C8E8641F548225B7C7AD388A5CDFF705DF37A1F2901749C48791E62CDC5076E394BA15B26AEF1A38434564088B0D741C11970931CB8C75EEE092A71571F4409F76192C64971F8F395F69DA9F3582A8E9B64B8629743E3B94117B0DA2EBB7BE522697663E9BE12515659AB8811539D22933B7BDA0400883982B430430B1E261A25734D0D990BA819F2C59584FD29EF2FC10F95B05E7C7A73B66C4F6984153C45030F99A1E9A378028A17961465C1C3146A0AE7096300CF966D4320356C3CC1079A53DF829DEA5A711A683AF708968C4811A8725A0397C332B0344537F4E2391AB9BA656075251C216435894DFD97F8F0B63E3E5B48DFA8852C43A30D67475E64F32B9952DC6732E165D1D854A00B72B7D8A44AF57621C7B7FB6B17D8ED597CF825242778A4F5A03AB305EAB2BB9ED27C504816A05C2B2B13A9E41C233AF420FE7BC6E7202B850A24C861C1B0196B8B4C87F2986063C04CB90F56CD3207B93229E197150FD8BAB314C8D71892FA633001F5469F3AAAF694B051F7A1362C3C6D3485077A12DB0052907C493BC6109CE627CF2F953AAD71F654A9167B05D708789EC0100DDD4421237C6814073A5B10E3D1001D18B69A57815D203ADDA9610A7232EEC6C33763B86C4F777F2D7392CCCCF8D6C4297C1111020B11C8258D9B61B26D50E3142A94A6B50C0AB51607B43F6147DC6D45BD1E64A1AA25F2309BA2C525489A75BDF5848D80B6F3087735D55246D9723D3B7CCA2848536F7CECFE6B0FD031B0AD538EBF091B4F674AC53BE78F1A00E2AAE18B537CFDA0CDE143ED8D7217763C6CA2C052775298FD1662913859A1276DD1B2305D3469EE39164D568C1904D89B66CA4366FA3907CCE699D9AA12F36719BC4CA47800B765D392D0AEC702F452EE411271BF945FF58B5E68C7197AA4882F8A5C7C4C11C4A1BB3AC39205775298A9A1A4B677322413187CAFE99C178AC181F0446F9875FC701BA88063589288E73E4BE1AB28C6E3ABB70AAA03F656AE87B38A9EC947786A41D722EC63C0E9E8C1DDA078E28608D11E84219E35239D8030C212F34CC284EEC748D34C6CAB04A7F3C15A5DBA8C74C8666167CA4508EB47774A7C3BCD6589306FC6365D74018D2082DE1753A854EC6FA7813431D31C6A3FA711E03F042E6251E2E27787BEC65AA8CA47FEB5662599083E6944F442716342DF25AA551C36643EC3B9598184431405C8C8EB4AC8360E1789A06B2D13232E831C39A005881273B0086591760AE8A20913D942314F45BA5094AAAA05444469D12C20566B0C008CB2C5FB90257929DCB648E0D616001095309E00FE19235DD29B1EFC2A80E1402E851CD19D2BE9B4001ED214E418C156BB6BB85C0744C3B81AFEA59BBF055C8046386B576BDD009CB412D13B3918B19A658C690726BC93D4928F1B2A7C386320D41BE98C1AECFB75288B94511113B902489FFF157DEF97D762A5302B89AD18546F5C9262C06C98F62632681859D132F756A7008B76CD92C760BB12EB276BC5611B5A1F20A22982AB7616F8802136F54815D66BDF87859C7A79F29769AB4CA735181557AEB9D76468D8855302D4A5E9CC171DC6000C7363789C3A76E59905EF5686C31C765541131E62120399B16CAB27A4677C8E36150E728CE747D2C2B305CB780250CBB1282044B5443DB128695F4A6637102ED3469E3548592D3BE83FB30FDCAB034C1499F69ABDD174E82041FA4CB9B25773BAFCB071BAC2394B6B9E3D5446289A8E08339D91BC12E84ABEE2BA51A563E1DD154E075CC33409609835A8345C86EF96B31F28E3B42ACEAB464380413F475B00CA904E958CB260B186E3C5CFC6068914638AE831D8AA78BEE7B65B9233F8950783973C4971AB0C3BC9F7A7A5176083B4B9B1C045157738C460F77A6D9311A3591789DB0BDE85C3A863594DE182D789A7244E05FA05965A4294FDEB2AF843CAB9F273687E3487C4756B0D441303C9C8B6284733652F074B087288F6BB08AEFA990517C08E9E984A4029FA1C420FCB19FAA78B61C35B4DBA021889826108A1A95A6816DCAA08D535C77959C7EB20209307996592E94DA842A52C329E3625CECC6A8624EDDF7B77C2264933B7B263499AD0930F539C0F24A14A157A56AA469891403BEA0A3531CCFF5A217282652B027513C05D03FE142DD14BD85755507473AC91767C69CBDDDA71CAF8A12A611C0F7F50CEBE87BE9D88514611A9516A6433B8FCBA54527FA10532A808E57979E73C8EB444DB3404D4888370A419E1AB04760617AA0E66BB2E715FB17036D300D9F3480D691450BF0571F875EDFA668D68B16D426668A68BE91F1337AD15577375477045633984AEE80824A08C486F25443E61B47658D03A21A51B085C656664B8345C1149CF690A9B99543B9E98CD090CC4B57C5A1D7BDE6E256E2059B20752E44331486515083DA5A99697A47A342BCD9679C77C6A243896B05CDED231919D0448994ACEC094E082A7434C9A3F6B97F21056CD827AB2648613B3B95CA065E1B3CC3740BC7F4F156650A722FF26D70E5276F53267CCCA11513A719624A2F1BB99677B845A436C9AA3A2D1202F1094F9040813B26BA6DA05E904206DC33A665959228B62BD9391133AB21B79967AF31CA0C727B464A8737535973042831FB06A0B89CA65B6DF8F3983037957DC838CFE0C65D7791D3148A3FB59656472BFBBC8AFC7C6EBBCB6BD83B6760643425FA72FE343DEE61187A73C98B9000E2577990F9109A8B1DAF30BF384227D45BB8BD4CABFA4A9CB20B0B81152BB46281A68445F7F78AA56545B59C75E9852912870373B1CCBB14396EDC70C2C00896762A129B775B4B9168C97F9A259FC22219DDB0CAD614C4F06030140A1F335B033AA2A1753CA5E2A2ACBBA83A3CD65978686FDB8959B4F39CF41B98EFD2048241B69B27AFBD142FD5046AF69AA3EBF67ED1632C4683B88C6BB7B388B4A4D7178A8ABEDF1523A6816F10C40065056DC9393D21F76A48EB7C122331900406D960A4D46C9EF12429B8E4C45C4032F089458818C759584947F6415D1468A6436E764CC86E725A936000B242155CA0A9B884B69490CBD223C76FBA954319161748706CE5A31FB067C20663F443B885E4C5C1A421D589777AA4C13555432AF00B27571D8217B09AD4BC9732C8ED10BB8841315539DA5DD99F9A7FACC71557853FA10547CF7B89E983458E7830EA58B9A79ECA86EC2D5F5589D9A7F30FC06A0E33AFC44CE2717FA011A531E55E9C652B7C9456926E3A720B75ED2D4028057F31ED51E22D1C75FC29DB2E", + "c": "34BCAF3DBA6667162E71A484F74C056A37DB223C1F9FE03CC4246BD9B1542C6AAA6B8C21FBA518633B8824D3ECDFEE9F5981C4E75F0CCEF4E957EDC63BD1A49E5D599A01C5B60D2391D280CEA34637692B80083AF030424DAA91D95A2E10D372B827A0A7214CC74CCD91B9EA4E85D4919CEE6BD08BDC8303317157E3D95D0A94F486F595E64D246EF015A3E2780854B09C9E1C077FAF641DE76218986FE7CF6C8C94C37252C5315C1B1CC9434F286789FD159A6993FB75F3936D4C04602C1EEF033F4E95E412EE772DEBBF4872600981D4B45749AFE498763D11541177031232D4F14143B6053ACEC654F2C9906896E79DC5A5AB57402923BDFDCED57FA49E8CA155EF37012F78B5353484C006980D90DA581410857C152F2E1DEA213B8C28A6DDDED12A782E23858F204CC1BDC84BED3C05F93EF03911342CA7AA280EE850749EDC1A3F5F998505014A824B63BC67D68BCAACFB6511D4BF2EB1ABA077899912540D78426AF13CC0888BCC7807E932445E30F72DABD6E35B8C04D454B4FCEF1E6BD17CD53EF04B363942C1361959AA7305D5F68844C3271146DADF8C588B470217CC10778FEA4AE93A5C5D5B5925AFA212E25A4CC34A8CE84D56DC476297B512EC89BD7DC67FC109B829BF101648D9B7F6494817AFDED31D85F68E5E98F717A2F0D1B6554066DF76713ACB17A1520127223E5E4B59B030EE714C1A9D3A7C4D08B928DCCFF1B53BA776B250DF9CFE6CE299F2AF835D78E62BD3BEC8FCE068858AB1D31C4F371291D54EE4FD87E6936299DB9051884155AA8F7C9A9EAB177E33787FBBA8C5026CE8FE935A5A7944BC6E48352E61314888F7A7EC5F08894829A88A4C955FB4E8D8DDFE4193CCA985A4FE6F6E16815BC524B0CDA186CECC4B6CA23A11330E9E2B9982EB6D3E24B36FDA826633E4D36318B8BDFE6628ADD238BEB63325EFA3F27F93BE9287E1AC9E3FDB6A5B39729961173E65D21F5A51373CC63F24F710064A177290613A172FAD51D607BA075805976F65331F5197307A30F12DBA0824DAE229394757EB5593E1AD31D98E45E7E6B864F7FC1ED00F85891C65C91C9E76A1E5B336D8E3AEA8DB52AF3A36ACD0E64EB877D19887E0B803DCCA831E58F6194F0FC651342A49860803240BC32FB8751FB3F513F43352DBCEBE6DAA56A3DC457F705BEE993BB325A9CDAF929C513BBD9194F4379BF8350F8AD81BC11D3CEFD110AD315E6402F6D01AC5B2B8DA5D0E78832AAE47D1836400B681229A363E184BCD5E45BC8A3F1F3C38FBF7D84C493BC712E1BFC80CDE8C15E53DE6EF27F10D68500EE9D3709E059B8A6BA91589B5F8DBD6E62E127C36BF3C97007E2E7E1A97E45C1ADC60D1B97F8348CB5D88C3592C375B4AEE18648DC8648CE3305E2D055ED01C3830D9E329C76E13E4616FFDCD6773B31BC5502BF35C5BC81193FF0873A77644CAE2AEDAD246925F4CFDF567F6853D45BF1485E8DA3DDB049F39A0CAFC67EBE2D155F41B9B938B0B22B082FB6D2336CAE45E17BBDCDA5E87AE0CF5C8E80F2757A40005DB5071475A183A200EE0563AA483B29DBC58F49C3C322F999E00D185204E448A838E9C63C85777D76B1057F08D552112B636A4E0F0EDB123997B062F1DD1CC79F8ED186A2C6F4DC8B2F1F1A2BD490623CDC7DC7AFBB5CD23708BB45F52C716E5490EDD2BADFE24B77F138C466A6DBA515485FAADBCE9413B6CDE0E7D997B9BEA49023867323B57FB8BF795F272883FB3F3A0D21BF74229158ABE822F1018B5AFDB650CF012D2251F0A4E5BC1974ADE394D77E0E4116B2A11ACA9618B000EFBCEFEB7D4FDE9738C75A05E14461B6064FD5399D260EBCB7B89D2C0D1589C1324259C37ED7C2224A6CF7350849B401D2A6AC909AE433DE8C7ABF0199ED44ED2B569221815455088611AA6C88FCAE75DE832E390CBB9CA075F07C31FE72B9C7CA88EBB6D446B60644CE9BC62DDA18F5C2C95EE2BD4955EF8CB50FA4157396CB156314110B531BC209EF90AC16608A2E080618BBE9BCE24A3900131EE334CC106AF9A1C41E9DC33151EEE2E980A45E7EAA649369585C9FC52CC614C8226F8AB2768285C320BE1FB6E18CC66CD160C66AA2098A3BA33F036FE1C743274F5D9029A8C8F0BEF6834A9F4BA6C0E26DB903DED5519F566B02FD32CDA1624BDE365191738C9C98CB0687CB138DC3F8833948A2090F0F55FA68F186D711D26F1", + "k": "E941F064338BCC6AC1F7679881709DDEBD2A94AAF087EA9FB5021838DACC8E72", + "m": "F594FE1E810814496BC73A1523FA1E0FF207AD5F5F0FD4B232C25EB9F6EB5B1C", + "reason": "no modification" + }, + { + "tcId": 70, + "deferred": false, + "ek": "24155F435909068A815A6853C9F17BD928B0B7891B83F4447C2C5213760678D74FDA8C793C071002040EF4D81BCF676483B85D2AC796F964C9B4F8B7EF77656FA2976BFA65B9E6AFB7811903E114D3060A1A967A1465C512D2C1513863A548A787279E81674FFD45BCBD7C398D567F22D7291F50324D45C9A2FB26DE3A7A7CB875058979FCF4BF19A03A8A721F17E514773A83FA0A939393ADE55CC7176AC984CB43C7092DC2D0A55DEA11F3E41B879B5B52984BE72158B08BC0EDF25866563A56D4B98DF9528FFB28BF345C4D136EA84791DAE11ED324AB279C6C8983AF725818829CCE05770AC3837A2C92AE2B1812D143032C72A32C94C2A06882ECE2CB73C0C41EDA64B607BDBFD9258E03A013B9CB3BBC5C40FB10CE413B11897E81D32585240851E487877C4D5274C6CCD45CDE88978994CF463111A20BBA9905A6114899BDBAAB1053541BB3502D9779DCB48FC8E523FA260F8582B6B8F30232342848492DAB73197EC492407ACDB52844033C9ACBC79C366A4583D98585942B05281328659506D714FF856A9C2B5F370B5136F896BCB87A23331AD0A7610FB69515E84A0A302407FB9949ECCFD91550A8618049A48BA2F4096567A0D383BDEDC705645C4025E0B139C22E6A16023062901B8A2B6B515DC8E06A4D5514489229D926521942BE150B96F2486CB34B09D7E7237A440588C357CE061DFDE1362DF1C2E58C1E1D72235E922B61EB2163D906B5E051BC58497C7CAAF5363724985D0FB3BAE964A86AB36EC46AA3D7AA290B428744623A3DF900DE975E3AFCCCA539837BD897F12CC555D684E34BBB3CD7041FCB2004A687B5E6A3E801CFE9C8C2815C2AC4783042A23736137447337D9221116A62C0E1D8C191B53E22C92A71A15D9D22505FA5BE17221A7236392C0348562216BCB037D4880A6D1236D3626E1B354142B5C897C646BD62CE000C27C53991A1C69176D03A16A61FCA51067C596CF01B89933A258B43C22F489AC70C1D8658B2C0FB2D3A6924A704302F33C25BDB556E97780747CF652C80E87B23479AB2C8119DFCEC47265A4F7D524E50294C826AC4C7B39C3C0782763A1A6ABABB9E14903720A9380939FDC9A99C6766C9D8B2828881BAFA555A35022A23A6F57CCA446319E71780AFB3767E9311D5C990F1E4ABDFF51A0E7238AA98AC412C05356583B05C170BF793CE770F79F81E99F78FD46310EEE27F614226F42367319C81C98A1FE2B2C09F886ED827610C8621B079A5A51863BB69ABC01C4A75051B50D83D1AF85B89F6918313AE5AB0999035088813102BEA06CBCB14656928DCD53A30255B4931017BBC4682CBA54378CB7E118A275728B83A4BD2586D271A8F64C06562248CCAD9A1FFB8265512712D0B707424B015157788318C7086BD964490A11A35FA43BED6ECC533E07D2A6ACC806990072A7DC0322573D6B88E29A7B47CC42508C7CCE64AD436AAE0160309E6922B655FD3B96FEC22CFC7349A746A0012D60A88C17D7934246EA0290369B3F7783FB177534F300BBED06EDCA87786D5175B93239B115254D676C921C1E5C3BA42737AD51B4BA30B1E65A8B59EB6A45C34950E9AABB7E5CD2F556485036BEF93CEAFBA97E83408D61C6FEEB908873B7FCBE93D7E386F2563CB4A80A671A1155762A02968622CE9163284777A3B4AF4B8858392BDEB9446BF59CEDEB689C609859C9B47561A8B39A19F7B36896DE82AF89BC41CE6C54791A78D6258534AB7090C502CE0A6F70CB3DB442A9DCA58E766A2E72286B42BB431B4740B125C73D43F49C1994761A57E3291CE95A2F4B88B3DA31CA994685A75B71CC622B3C2BEF60C222696C031789EFA1A3DBDA576EC1B802C261D1F44A5E4B973AB73946E41159D622BD8A0833396517DD2C51904AB67F05BF5FCBF9B47BF05A18DA600C1AA411B60901096838A5CBB8EA236A0D4C7109BF65EF8E6B2507651F2FAA61ACA225744A1B56354CB945065D6ACFD3697B8D331C0929A59AAA06570B0FD3B02135006DD198A92D4037301BEC0B328725533FC385B2E03033ABC4E1CD4975E438B19D902C3E3435019A42F664C063A5A5E31932ABAC10420A10A89B54582138CE812A473945952460F541B9CE51C9A23C5CC6BA0896249F097218210A329956057E6BE66DB1BD139A791FCB95B3603F12BC19E2876617520522AE31D827CAE8422FAE85C30AF33DBAA77967001910F", + "dk": "A3254A747B57C2065E22233D7D2C1F9CD32B8586CD2FD5A2C1FBA0BF976ED7FB3A36B6710662B9A5AC6DC7AA11D581A0B6E36307E76C9C14128129C30322375381688A6C4A01137018557DCA3184B26091B91AB05241A4A080C813B20686596A5CA8C29188B2F005378E41055DD24D0544C624813A527CC25EB546B30B004B054438E333E5B5C467E08094EC07EBD25758B57FFCF9A958AB343B08BC248B0721A8C17DFC019DA719C4037DAE956F22C41711910513C79F7668B075BBBAA5307AE8131E2184C4164C17BE098E9C9755FCA53C0C781D7889544731A3F24C986C517C43156FFBD35328BACFF1DC436EAC6CB1F92F05231BAEE052D060AFC2C298B5C2877CA8B6BE22C3BA9C3348368DEC30AC7B05A58DA06A6CD1B47B32B709704679839DD873239A8A76F3CB8DABB621AF84BEE644A3C9C348A2B071ADAB3BE40973CD01958778600325CB70B486A7C84A0BD577B313328F792A284B5E1CA4B17F476F24C75C3FC325C07508E4EB9EEDAB0D321B2603582F765C481BF908E0CB574925046C50196A59B35AA282EF1936FE574016E4017F8A9E90E49D20F9279E262CF332CFC0E45E34E22FE460091DEC6DE5EC3A6DE702051284BC234E250B7A63D282215A27DD036149E412DC2C58D8E42E2F8A3C680C9A88B73C8603A53D08509849B379C5A3A6EA6B910539BF420510A833EC6527036139029AADD250A095B56C96A25DAEA70EE8B737366A1A6786769B78C874CA377B652C2BBC93276785D0893A196316F6DBA1248BAB288086D783811A2C1FBB7685B979822306C6B2CCC736562AEF3A19B5A364DD472442B37BC7A363CEC9073872BB4E65667B794A2CCAA319F6C437D2A4EC4A73F0FC5CC3D485837778A3C880005A5FE8890BB42BC88D070E5D7788CED8BFAFB28A07294C81F911A9700A38A880B0A85A97D2A08EA3B0FCBB69BE19A6D330B9AE492D8F3174F83BC22A3A98147621651CADCEEBB3A2D3B18954121D82183A7B465B034454E5390C191BBC063BE47B3DB5381FA2C6862BFC8D34226471E90C45E38EF602511BD4BA1807B95CB72930C537C99B0C1864267FBB206A66A836293F4775416521C175424191CA749A251549F6155EC8883890161BD09EDEA361C3F3CA3C086AAD70A3012C2C196366209264FAC4076E977408A91FDCEB60B8FC01F6B1C1F44C65AE14C3AC366D46F24333B567A9503C8AB0C0B2CC9BDA25400DFA0632058DBDB40309F91CDB42ABD76B82CD5248AE982C994119E08A524D5506395BAE3CBA8EFEA758973C8B87C8B132D12B32A29C75F94A44350413D38F426A57A6609C9D50B1CCC41183BB35CDE7026295777B5A0A5E29765BF80F319C8C7BC9BABF8102E798BF92F923BBD71DE01A28FDD3A0EFC27C52C30B5E7157E90C3E3F3019FA128FDC6934B5E773BEA3935CBB79BEB360B2841D6BD317757805F6E4CBE61012011BCE8E60CF0505A607E757AA96ABD0C75F15A948B45A56A137AB28BB3795FB7192C3501D060E4EE642F9A26AD661490982857E49280D99196899A70DC63926F41A9BC8A5BCA13B3CCA3B2A3998083A9BEFE93CD41A800AD6252D9993716B7AEBE46FB003C850EB86CD045FF963A528558353903FB0A62552C0818A43370EF32CA5E4045EB13035A1793AE75852229825ABBABB591DB2F1CDBED76DB7E5CB74086FA9A6A803D8B0D23B9BAFB112B029721AB70974E6A17757413FE363CDC040CB789562326302F509F317CEC82B489560B2C83C5E3E214579CC76A9140FD9975176B97A8E086E4CF46989C024A16067155971704130D4743BEF8A9E4E63B196142C2F46CCC5FC41FA2009AC1BC25B8A67DDB03982A161F5544AAB7CA22DA70E7CBA515AE7AB46185AF4473E04B593333799C9E31C91CA9CF85187D2D76FBA1B6086B6499C5CC614636CFEDB3A2C226AA0851AA7182D4C4296A2825A83ACA2B0C38E5538B5C7F42A36FC2102F6BDDB5870CA9B1EFD1942861C038B88122FA9929BAAC480B5C9AC6964A8DA9D59ABB52D69A8A5897EF745CB31E5891A1867674BA526A3B79C9405924B00896A97A83394DE4C4539E1B877822BF35968C09188B81ACA2852335AF8A711493E6FD843B7863EC61013B9401AD1B860B6B555AE394A11601518D45C7F089EA746A7852A0D72F2699DD98D24155F435909068A815A6853C9F17BD928B0B7891B83F4447C2C5213760678D74FDA8C793C071002040EF4D81BCF676483B85D2AC796F964C9B4F8B7EF77656FA2976BFA65B9E6AFB7811903E114D3060A1A967A1465C512D2C1513863A548A787279E81674FFD45BCBD7C398D567F22D7291F50324D45C9A2FB26DE3A7A7CB875058979FCF4BF19A03A8A721F17E514773A83FA0A939393ADE55CC7176AC984CB43C7092DC2D0A55DEA11F3E41B879B5B52984BE72158B08BC0EDF25866563A56D4B98DF9528FFB28BF345C4D136EA84791DAE11ED324AB279C6C8983AF725818829CCE05770AC3837A2C92AE2B1812D143032C72A32C94C2A06882ECE2CB73C0C41EDA64B607BDBFD9258E03A013B9CB3BBC5C40FB10CE413B11897E81D32585240851E487877C4D5274C6CCD45CDE88978994CF463111A20BBA9905A6114899BDBAAB1053541BB3502D9779DCB48FC8E523FA260F8582B6B8F30232342848492DAB73197EC492407ACDB52844033C9ACBC79C366A4583D98585942B05281328659506D714FF856A9C2B5F370B5136F896BCB87A23331AD0A7610FB69515E84A0A302407FB9949ECCFD91550A8618049A48BA2F4096567A0D383BDEDC705645C4025E0B139C22E6A16023062901B8A2B6B515DC8E06A4D5514489229D926521942BE150B96F2486CB34B09D7E7237A440588C357CE061DFDE1362DF1C2E58C1E1D72235E922B61EB2163D906B5E051BC58497C7CAAF5363724985D0FB3BAE964A86AB36EC46AA3D7AA290B428744623A3DF900DE975E3AFCCCA539837BD897F12CC555D684E34BBB3CD7041FCB2004A687B5E6A3E801CFE9C8C2815C2AC4783042A23736137447337D9221116A62C0E1D8C191B53E22C92A71A15D9D22505FA5BE17221A7236392C0348562216BCB037D4880A6D1236D3626E1B354142B5C897C646BD62CE000C27C53991A1C69176D03A16A61FCA51067C596CF01B89933A258B43C22F489AC70C1D8658B2C0FB2D3A6924A704302F33C25BDB556E97780747CF652C80E87B23479AB2C8119DFCEC47265A4F7D524E50294C826AC4C7B39C3C0782763A1A6ABABB9E14903720A9380939FDC9A99C6766C9D8B2828881BAFA555A35022A23A6F57CCA446319E71780AFB3767E9311D5C990F1E4ABDFF51A0E7238AA98AC412C05356583B05C170BF793CE770F79F81E99F78FD46310EEE27F614226F42367319C81C98A1FE2B2C09F886ED827610C8621B079A5A51863BB69ABC01C4A75051B50D83D1AF85B89F6918313AE5AB0999035088813102BEA06CBCB14656928DCD53A30255B4931017BBC4682CBA54378CB7E118A275728B83A4BD2586D271A8F64C06562248CCAD9A1FFB8265512712D0B707424B015157788318C7086BD964490A11A35FA43BED6ECC533E07D2A6ACC806990072A7DC0322573D6B88E29A7B47CC42508C7CCE64AD436AAE0160309E6922B655FD3B96FEC22CFC7349A746A0012D60A88C17D7934246EA0290369B3F7783FB177534F300BBED06EDCA87786D5175B93239B115254D676C921C1E5C3BA42737AD51B4BA30B1E65A8B59EB6A45C34950E9AABB7E5CD2F556485036BEF93CEAFBA97E83408D61C6FEEB908873B7FCBE93D7E386F2563CB4A80A671A1155762A02968622CE9163284777A3B4AF4B8858392BDEB9446BF59CEDEB689C609859C9B47561A8B39A19F7B36896DE82AF89BC41CE6C54791A78D6258534AB7090C502CE0A6F70CB3DB442A9DCA58E766A2E72286B42BB431B4740B125C73D43F49C1994761A57E3291CE95A2F4B88B3DA31CA994685A75B71CC622B3C2BEF60C222696C031789EFA1A3DBDA576EC1B802C261D1F44A5E4B973AB73946E41159D622BD8A0833396517DD2C51904AB67F05BF5FCBF9B47BF05A18DA600C1AA411B60901096838A5CBB8EA236A0D4C7109BF65EF8E6B2507651F2FAA61ACA225744A1B56354CB945065D6ACFD3697B8D331C0929A59AAA06570B0FD3B02135006DD198A92D4037301BEC0B328725533FC385B2E03033ABC4E1CD4975E438B19D902C3E3435019A42F664C063A5A5E31932ABAC10420A10A89B54582138CE812A473945952460F541B9CE51C9A23C5CC6BA0896249F097218210A329956057E6BE66DB1BD139A791FCB95B3603F12BC19E2876617520522AE31D827CAE8422FAE85C30AF33DBAA77967001910F38849E1BC23427C122859A98B41D65FC5EACBF4FD851681FEA0ED777FAFFB534B49335D1DEC43FE7888BDDD29CD891FC632616E3B4107E091ADAE014BF7F473A", + "c": "6FC99751A98DB6AE5A504A1E4D3D37A91E7FC63F2D3457F3EACA0BF1045668E13D39B5F93F5EDE0CA55A0F5FBB90CFFEFE9292D8B723235CD6E2C7E92AB086852CCFC31D674BC95FEFD2505DD650FC3EFD43ED787A5BBE009B33E7BC2C47C1377C874796F0A01B9E3F4028C797932E39819EC4B3EDCDDF25EDE63EFBA53935BB421F0C63C1AC1BD0E879DD0B3A47B5A35A5F215158A35A22151EE86AB2C3E9F5CDC387FABE327FC38D0943F1F0D9891BE86F1D8F78D1C29C7700CEFB35FA629CF8120798D9FB27E3882E948C7B3BC08D09527BBE1F4D9D88F3336316FE93FD91D00A9A53F17AEC68E2AD8B335F18330ED608857C3996D111776F9B29855E75F59FAA9ACAB79CDEFA617AE017C0EB7F797206BDA76E1F01AE4C83D24A1166B68A7DDCD3B7B2A1C6D0A470D7120A273758BD4A078F1D851C9EF50C846B246213948F273B045185965028EF8B02AC189135BA3B83904EC978998F1F8A55303057F985BA26A85FA467C4E620C4742A36BE7250ADB5A937CC9355FCDEBB045DA27369DCABDE4ED33CA66906AB0BAD8C6310507BA241F54F37BD6F778DFAAF9B7530574B526D742D74DC1CE917843E27533E014C3A8348D9EF56768829BA4A03FA2A215DBF2C45E2FE06ABC268E6D335EAC3C584B6F221414955EE02BA70996CB27AFAD316D18D90BAAB3DED3C5CE0EF31F3B4155977381E5C76A106CC7BC934B4EA92142E18837930842DFD225FE0E57D32DB7C079C26DCC936C7A526E3A117202E0A29304899D08EF478BAF0A2413AA5D41F5758B22597B11E5A24659C514DB176E7448CED43D5087665E48FA2CBEBD8F300168BEC904E1DC1A39ABBB4558DE1F31725DB46DBD6C847D4BA1E260651473553002688FBE3DCF05ACBDAB5B0EA28DA9D83D6EA5EECA8862799DE09B42AAB2641E84A158240C495EBD6A527DC3840D099EE019F919E9667904D22B6A73EBBE5D5B1A781B9D480FE9915905722358DF0268E1BF3362FEC849C5883C4A34A707CF2C02E4CDA03CA8904659B933ADD46A81171F7155C7275C6035B2B572CDEF3599E5B4779E606F5FA757411BC97D9B46806AE144920B29213D2C887CBD79121D091FCC02B1D922B11D05583F1C8DB8C1CF4092667784BF4B766DD263A5832FBA3EFE2297224E01581AF372511D1C6FBA61D933D36DDC2FC845694B67D34F11F95B8CCD626463F58918D6A99C5D06F502518939C9AB9187F1BA2C1FBF9541B4AC2D9181495B0FE2A3741B556600CCE8B78CA02AD412B62856D7F588F6C49B08EE4E304D145FED15E2212FF167FA48E1D75883504C5CCDB4F4F2BBC3798DC2BFD9A74D747E9C8755127E73EA344FFC110F88164605A1813A8BF1EA4C0EDE38592CBC857A976FC07E64C149705EABA7EA02D8BBC3340AB38C4196FE28DBFAC25FC1A7A8C9E096D8FA5BAFC110862B47282472B8C731A45A7A7EC3BC19ABBC35077824B05FF19B9831D4BBEA9B34F8B28D50E3451D9DCF9B05E0C2330BB78C30A71F774760116894444B37B0FF1E36ABA0D0375DCEE290CF46219DB7D5110D4E51A217C0456227FD342CE67A922935005B3C7D1785FA79C608C149050373097258AA5B36D187B23DC602A970ED7CE5D36CB1AD10970C19AF67AF01BBFCC620D9BFC9C7DD355F274B6D2B585B730CE9449F697A51208FC742261780FBB178AB667FAEDE8422F734FE341DCF8D635DC7F2804735286F83EBB7CFB482685064BDA42E825120CF078F487B76D69402A74D6D4149922EFE4A8FC0837D8FADB1225A54434EBA471D0FE90DB55A3252B902BAAE0D3569F35055F1EDD9F0AA2AEC8DB9D1AE8A5F2D9D6B51D6FA65DEC58308274628EA66CC199CB209372EFD70D1B1DFBFDDED0B3F60F83C069A2E26B0A38F7DE67209E8BCD09FFC17B48FA95CB02D686CCC0E419D9ADCBCF5154CD18BF8F5D13A6FBF083A018F66D9BF28B84CBE9A1C3902BD55C8EAC8D72C8E7B11828D3F9B1794FCB3E6A50F498901DEAE1381E7F10A30244C94EA9F2471A1500772B3ACD0869F00FFFDAC3CB2E8F69385C60D7E8013B3C7D2C358DE712F3F34598A7D1623E6C68373C30F7EE7666FC4C96AB93CC33E4A3839C33BFDCFAA4EA20A25DD3E2325FE93D142A18D3AC06CAAA2EAC6A9CBF67E5E087BBB896E803DC358BB69992A7CE72A69C7C511A85535EF05B4FA790A574E21585C3FBB0B7DB585CFD98076816BE849379", + "k": "D3772614A38598397B21269656EFBA39B15E482299F3ADAF1F82225595A1B7DF", + "m": "ACDF91D5B4F2047AB9C7A8C2F4809FF69B9D480334C501E6BC66D535D309B100", + "reason": "no modification" + }, + { + "tcId": 71, + "deferred": false, + "ek": "FE456F478002570478BED88055B4567135B19DB8CF52A56E41824984A8BEDB64467D7A0A45654153C8645C5054C0E35C2C75877633BA83AB25857CBE5EA998FC6C79D983B5B1A984FCBB14CBEB483587BC5D952A4BF422344A70C4BB8E9162CB31D2411637526514920CBBACA6A911FB80662096B85194B308B881189813D171CDF6463893CC58EC512DDBFA31920CB1F33AC72C15BE64A3BBD114B27185455DBCCE9BC67AFDF6C8A393CD8A427A73E052FAC64AC22B5DAA7481E7D017B8E14BD84690D9054BCF2557E942BC7248AFAE57911FC64732C450EC3C1CCA599B96DB685EB704764CA7EED07F9BAC7103F38356F86FB9639665C35A576B8627CA6DF0F138FD198405B6371AB1BBB7EC4175F739B408B281D28BCA369AC0F1971A374A97E9097FEC3A5ADA6C2C7714B5CA0958E4848C9CCCB5172F1A6B7F2BDBB37EA346D1C9AC0C31A5822218F9D3544DB6464E605029073DF5F030939C8B7CF84A714904DDF56E63F04B2240376820417FF320BED27D8C385841C54222097742E23B972A6B7491524B88538A07988FFB9861D0B693CC80BDF6BE9B645193C06EF8132813E715A2D72C55140A1A9C54163B2780414A5996489326CF52112640B08166FB9F9461BA19661F1F47B8270396A0A6C8218B636E8496CDAB3639338D50D0919BB7610AD1BF9FF76D7D0B1F0E241E61A6377CD83D430118DC222452426A9259709D91BB46444793741AEC8998F876553B7770E9CC1E3FC749DF81AA4461BF5E6CC1622980968878ABF113CA67B7646A0463604D90353C635C2F2E330F71949E2E21806091319B328731B298E99127777808153652C9C763AB386ED7F6CFEFF10034090D134A642A218D277B6B00511F35A25BB3DA1F299C22B4A3889D10B3754C52D3F1B1373840A973793EC4A5DBE76D2C29626F1BB469722BBB99B003ECAA85545CBC313AEFFA6006F0AB7A857AEA991F9BDBB92E3B75DC300D1C656B2324CCE8DA2FD95C9F510676A8D6AAE77535BE3A9ADF8B1C974293FCCA05DDB31AE1CC81768CA90D00A4A7F8191C127F6B8CA010B46F3C05A808D9911A626B80365E6AE6BCB428BF3EC8710557485DDAC34583B43BF55D257089EC997F857B94752B8BFE7942689A5397F71944343088D6A9A2BA4936B2AAB663857B87278C3293491A75C861987C187655F13FC2A28749E3891E8C236B1B675E250639E5461BFC94F6B7CAB6D8077E4CB8719420DFD4951F76CC6288229EF49C8B8821C3D497CD860C58A619C9294689B5029F5B2D0BC95C370A8C7FA3C521A695C829A9A1F8012D479E38DB4CFE650550664CC9E0B631E2682AABC81A601A62EA16548584A571CE417508AABC4F1970407ACC47B449890598621EA7623530409EC49AEEDA8AED0336DE4BC4D4F9163A3C82C12A2C5D86B24FE56235CCCD26F5AE517367523AC739C6B69E977E3FF2A854F8040DC4B97FB3A29967005D373E0D91166A679A517822F7AA59BD4B00185AA25E0929091ACEA1FA4ED7F7BF7E463005D59403010539465D5D918C1CE22C55A50C749C6B02A360345A0A0790970717986AE9A020564D82DC851AE815D5FC76FDEC1411D01C56166773D7067FB29CF842BA9E8136F755631ECA53D49B7B2B296D65E63D29F96931C02E2AC013C016BB05EA6817F19E1286C3C2B9A803276FB58A916C838E923932895C9961BB3A4BA6ABD52880B86B391035764C4B953684AD13C5918ADA13AFBC42D4B6B1D523B39C380AB8390E6984179A5863AD488897258CBEF615D53281AF99239D4A59AEE6ABD6EA9F72B88E34D544F25A18FB9A45B0BA7906367ADBFBBE3BC467EE7BA3520360DF56040E730C2ADB162F78BA49EA4E2D1969839BA16B2AC991CA439D337CED7153A6E80877B73F6A16A22FE196F5F833ED7C0133505EF9E323C00355D2405B8CA01FAB6B780385121DAB8544C2C609C708193B969701728BE36F5F972C0C402D2E230370175971A601C0560A22789262E539AFB55B4EDA9F8DAC1C63FB77B91B2E77F17D98C0297FB17919CB23E4D45BA538523047A17690C245E009B031469F6CCB30980649A14211997A823C092C98452517A2BFBCBAA0B43478AC399FA9B58FB96687CBBEF715AC3855C493665735192A718965D3825325F151D3A325318A667492B7F6324FB28DE4A16F77BBA3884809A3445D53289ABBBA26997E95B89029457749E9B70D", + "dk": "4FEC81A2301E8E900CDCAB71152484E745CDDEF6C1394A31663046548620E41BB4B96B275AD23D004AC2AE606EEFACACA4815E06DC3F1CE76659E8517CD107F6BB3FBEDAA9F448999544771B773EC5A0CD23E8A090585DDF0892EA7720F35B2AABDA2E113AA85E9CA26EC49BCB6299368A66F2385E7D22884E708ADE3185FACBABFA4904D1378F86934A81217B7E273F47DC67BB91B64EE20DAD457531B4C7545B72AB397CDCF1158150B7A7E3193A322F9B4B0B72838BA8A642DBA31176095E8A338C889A0A8E419D2F2709D109863DA90D3A88C4D95A5C61E805A7815696391EAAC76FAF252B9763A1A390441C70B585A908E8829A60885CE870A50CA0697F56CD63E856FF2C24791A80E7284EDFC8C36580142F757A27DAB8279160CDF4581FC05AE611021C689666FA300281B3E46589A07925923A3F32260FD9B8454EB862A3E29F8F3C5B500AB7F911422DD737A1E117E7329FF88950E9A3549B41BFCAD103A0C7853F7241F48CC9A6C4A45901230C3358021489DF2AB5DCE2B626653B00F62A9533B3394136E934B1B977310638099B79AB29161A13F839294683BF99C031F3B3CA4778F76268785CA85E0580317B8FD225566BA2069409815BF05D21218E517A64DD9CC0140C90B3C05C8E1B9912028BFDB04722F407116598BFC4A80A71576F06918F6BA64663970980B6473845B9AC281915893F5376FCB00B90C323B447518F7A8C7214CEECF85918A97829718BB0D594F429C0BC990D9CC7AE39B73EA737832CC66BA0BB4EB07780CA40B4BA43B8CE54AA90C74F40E57567B1822BF83FD7C7ACE97509B3B6BF101C23CC6B92F5CB36472C1DF4B3B97218C1D3880EDCC6AFBE63A096A279F16785CCB7233D5B423BA35D6BFC383CE12B0A7B4F44C5620A197FD6C1AABE457DB5A274781340FA9CB603D830884BA7B632B0FB56753A5117F0C806FA208F89E1B7F4156DF6B8A0937C1EB0E5148AFB6BA88090E50366161BC222C17464719BC6026EF806B77578994877345D0111D834CAC01362CDA26868957032249AFCB522B92555A3C414B544A4F2CBA499FB918D7079EED7221A2738BF915AC7033A897BC1F8812C64A5271EDCAA29125C9F273578E73CECE2CBE628BA49C4C06450AC06C7BD960B31694A86C6322D7F35BAABF415E43B4A2A074E8CBB945BF9A79453B44B05C4A252AE8240087C97204D1A1954B8AC438A2293690C470384948C094D59A9346A1314F22D589844760C626488381F4CC62E647D4175BCDFB16DDA3C4DE819BCB3A00AF208B7AA2C652996993277932C79697AA3A0A777C56B506ACB1C7EAD291459C995942B3396FACFD5B8951CCA1D64A55CD09B6A3E5772E5B754C3DC065D312A5C41394CF75094DB95A741319199ABBC996255F06F8E52025FB81785813B95D89E32A19EC1803616C2CEAE484883F8A438F40E38735C3FB4452534BA16025553C5C459E9A9E65C6E7E84474B9B6FE17606D476099E2A3861CC1E01611A368ACA50EB2A01760BFBA72CFD75AC60A0C95B161CE759001E742CD8327373E6B507206C798167362C3ADD26216A105094575CADB712E2B3A10DAB8A8828496F3C805F61C0D0087783BB47173C6BCD850BE86B780CFA8463F555ABA49981C63DAA4A1E9550550901A012CA53ACB3B71CE400542C2B5CD6366F84A2D4DCB64F9C6D6B790376A0042A1285E4E52522A090E42266CE8AA8919C036E7C1B8A776CA945ABD96690463A766180942A126876C9BA0DC9961C634E049448B217AFF7D16D5B2C1B20768CC5E73CC88637C217138B917AE522AE3F742165B6B754649ECF7ACDB974B9DD310D69C58DF3A23D01B8A7456C6FE76CB6649C7049EB0634FC633D4C7E99B754C8A679D50861974CC8F5F01059A5B97F40C301C3471768A668D2CECBCA91DAABAAC5E59A80453F846CC3751B0DF8B0701F20BD35C9AD564211E2C3991A5606B823903B981CC9D66CC1E5044F484085800BCBD835C553B781086750675C04C1A1916781D363643932BA8E8C2BDDB65E00E0AC990684EFF2217BB02AE0F33FE520C73FBAAD021346882AC6794B9045213D265103E4C25B1DE68254253EEE9C4B81253987B193794B4E23B67FEA3B5036508F798229BC7C1D8CB476022B616C65674683384787C1ED222D5E5903BA31BBFE456F478002570478BED88055B4567135B19DB8CF52A56E41824984A8BEDB64467D7A0A45654153C8645C5054C0E35C2C75877633BA83AB25857CBE5EA998FC6C79D983B5B1A984FCBB14CBEB483587BC5D952A4BF422344A70C4BB8E9162CB31D2411637526514920CBBACA6A911FB80662096B85194B308B881189813D171CDF6463893CC58EC512DDBFA31920CB1F33AC72C15BE64A3BBD114B27185455DBCCE9BC67AFDF6C8A393CD8A427A73E052FAC64AC22B5DAA7481E7D017B8E14BD84690D9054BCF2557E942BC7248AFAE57911FC64732C450EC3C1CCA599B96DB685EB704764CA7EED07F9BAC7103F38356F86FB9639665C35A576B8627CA6DF0F138FD198405B6371AB1BBB7EC4175F739B408B281D28BCA369AC0F1971A374A97E9097FEC3A5ADA6C2C7714B5CA0958E4848C9CCCB5172F1A6B7F2BDBB37EA346D1C9AC0C31A5822218F9D3544DB6464E605029073DF5F030939C8B7CF84A714904DDF56E63F04B2240376820417FF320BED27D8C385841C54222097742E23B972A6B7491524B88538A07988FFB9861D0B693CC80BDF6BE9B645193C06EF8132813E715A2D72C55140A1A9C54163B2780414A5996489326CF52112640B08166FB9F9461BA19661F1F47B8270396A0A6C8218B636E8496CDAB3639338D50D0919BB7610AD1BF9FF76D7D0B1F0E241E61A6377CD83D430118DC222452426A9259709D91BB46444793741AEC8998F876553B7770E9CC1E3FC749DF81AA4461BF5E6CC1622980968878ABF113CA67B7646A0463604D90353C635C2F2E330F71949E2E21806091319B328731B298E99127777808153652C9C763AB386ED7F6CFEFF10034090D134A642A218D277B6B00511F35A25BB3DA1F299C22B4A3889D10B3754C52D3F1B1373840A973793EC4A5DBE76D2C29626F1BB469722BBB99B003ECAA85545CBC313AEFFA6006F0AB7A857AEA991F9BDBB92E3B75DC300D1C656B2324CCE8DA2FD95C9F510676A8D6AAE77535BE3A9ADF8B1C974293FCCA05DDB31AE1CC81768CA90D00A4A7F8191C127F6B8CA010B46F3C05A808D9911A626B80365E6AE6BCB428BF3EC8710557485DDAC34583B43BF55D257089EC997F857B94752B8BFE7942689A5397F71944343088D6A9A2BA4936B2AAB663857B87278C3293491A75C861987C187655F13FC2A28749E3891E8C236B1B675E250639E5461BFC94F6B7CAB6D8077E4CB8719420DFD4951F76CC6288229EF49C8B8821C3D497CD860C58A619C9294689B5029F5B2D0BC95C370A8C7FA3C521A695C829A9A1F8012D479E38DB4CFE650550664CC9E0B631E2682AABC81A601A62EA16548584A571CE417508AABC4F1970407ACC47B449890598621EA7623530409EC49AEEDA8AED0336DE4BC4D4F9163A3C82C12A2C5D86B24FE56235CCCD26F5AE517367523AC739C6B69E977E3FF2A854F8040DC4B97FB3A29967005D373E0D91166A679A517822F7AA59BD4B00185AA25E0929091ACEA1FA4ED7F7BF7E463005D59403010539465D5D918C1CE22C55A50C749C6B02A360345A0A0790970717986AE9A020564D82DC851AE815D5FC76FDEC1411D01C56166773D7067FB29CF842BA9E8136F755631ECA53D49B7B2B296D65E63D29F96931C02E2AC013C016BB05EA6817F19E1286C3C2B9A803276FB58A916C838E923932895C9961BB3A4BA6ABD52880B86B391035764C4B953684AD13C5918ADA13AFBC42D4B6B1D523B39C380AB8390E6984179A5863AD488897258CBEF615D53281AF99239D4A59AEE6ABD6EA9F72B88E34D544F25A18FB9A45B0BA7906367ADBFBBE3BC467EE7BA3520360DF56040E730C2ADB162F78BA49EA4E2D1969839BA16B2AC991CA439D337CED7153A6E80877B73F6A16A22FE196F5F833ED7C0133505EF9E323C00355D2405B8CA01FAB6B780385121DAB8544C2C609C708193B969701728BE36F5F972C0C402D2E230370175971A601C0560A22789262E539AFB55B4EDA9F8DAC1C63FB77B91B2E77F17D98C0297FB17919CB23E4D45BA538523047A17690C245E009B031469F6CCB30980649A14211997A823C092C98452517A2BFBCBAA0B43478AC399FA9B58FB96687CBBEF715AC3855C493665735192A718965D3825325F151D3A325318A667492B7F6324FB28DE4A16F77BBA3884809A3445D53289ABBBA26997E95B89029457749E9B70DBD81FE53DAA89CC40752B7C0394154498DA83D6C03DF3B7834AB3CB12CE24953093744B72373F405DAB7EAC89D0B66540FBF92B623BCC950B73DC2251610E6A8", + "c": "C1C14C85C884F4FE4CEE2D0C470FB97D54B2A992F7900B8E57025CD88C755895415E67F6CCE90E241F534E950F91CDF2E0A72F59D6A721B6203F7E08BDE5197407F0E79220238A6AE9D6A5F95EE0246E86C35E9F4473D5CF3F59421187DAF3346A513EE8E628ED64F18F9ECAA1968D8CE28BE468C01C0792F5B70FFFC3F2C7AEFE601D8B12B2252E01856579B56AD5E686EF2A3D27FFD75DA7337D7866078F2C830B405450F0233D60BCC06F90612A1C516770A0BF25EE2F59607ABA0704DFBB01C18DE2EEDCE64472A93F417797AA5A0BB4C83D03E283D2A0EA37BDA94B060C5D1EAF854A05DCD60D4A6BF7925E1182F15BA3E9D992534D4C6953B9AE08DAAFBA92802D63E0A67161CD00F0AE3D26645688B00398BDA91F7507B8112D24DE8C7146F223DF6ABA561FD67B1B58CC909DED55FF34EF8478C76195B269BB650C30B522724A46209998DD77C6D55653C39CA608770B8863F2BA3A12EEE891C9BF94E77E95F2578907966B121DF02527E68A100A7E2D528BDC50BEAAB63F70803A61A5F93FC3FF8D1EBB46A96F88FB3CEAC5BFD3AD2434875430EE00EC06CC1F79D4811E7BD4DFA4F07A25052579440AB733BC189ECEFF0F37929E93ACA05F52AB4FAF030E8A39E37974F421E97FEB08F0238AF55F9FD33BA30797651FA5AA4D8D44EFD3F00E1F805AE89585D1A36C13AE8C3059CEA591B69C54835E8A112E45371CF46DEBCB625698CDB3AB1E1712740B3C7C2AAABF543477CF835193944513200AE2FF7D634D6ADC7B947238717C2E313D606A9759CF9CE2CDAD5E271FF0C55FFF1CBFF2391C21D22C0969FA9525F920F0BBE5948B99F1A3E91CEAE892148B443F312B66534A7C4276D88E981BB01956E06E1AF8F2399EA1DFC6FA67E0185575E82E1A4ACF62E240A63BE3AE57D9F93BD1208CF2E36BF7DF24812A431E2966849F8C46610E7889A89DC4F2F3B3221B2A6A99E2811072ECCC7FABA0F4188D33E4A40EA8CA5B48A6644FE367B54C4D2C16B4F3392A8D6399AC09D820E2DD4D9756C63D9AA22D8E591C04E0F2D79D22C1B75EA4F393080C168EEF1F1CF4AE4FB87086D5E6ED067D1764BACD6002E4AE63E250364F09C2B1E0EE6D68E2F3454F541FD58704DAD3DD1E195AB98E9EB91D3F167CE1FF578D7F1E465996F14D281EDD48BFF29DA518678A7D17A7AAF37A4B0A4194E5F4948337EC7B6CBFF9BBFBC90F2CD1B9C778FFD69164AC71F3034A1031C08A669499DCDCC097E893BBA7520888F69CC9F29599576E44DFABB0FC4C3EF5C1F2BB9E5816D51F6602FF8B88F2F3B63BC66D685610BDB30076E6C8F3E99C99F483534B46813E0144101A82972F5C843884E613B9A75B0FAC9A5A64D1CD6FD44BB12233FB9E50183E66815F9CFE7AD7D12C24556E826323F7A2ABBA8036E84DF71292F3C209A4B5D1DBD69FAF65B5860A500AF82E17E6421EA59F11DE2ADB9737C4EADDE3F7334A53DAB3AFCA556762D2B7D0D1565C9952B93BA394C4A0CD75DF1FFE76ECB4DB2D755A29563A7A85258194CF8C7899A0EC125453747CB775496BB172D9CD580396A15487D2A1801D19B899DDAFEDBBC9E8832C0E602D25A4CE237EE79460A069445952BC7476F31B3C67CD2CDDA4167DCB65F09B32B800CB04D716D6D2995BBBC5497085F543AAC81A0944E7FAD8FDDF92B67058AA0C4BC32EDAA9760844C7351D64726C506A61226124C816035A3A32F8F42B9CB808429E77EFDAC4E6731FFE83EBB97E0E805065B25A318A2545EB6B5A7306F687F1144C3812209CDA0CA9F9AC0F66A9C29BCB5279BA4061105BE2BCC187C37A186EF9399B93E5EAFD81C70C91696DBFB0721024145E0018A135EBC7004BA5DD824F5CD95515B8E2AC94C6DF5D07C40ABF03B59CDBD138270B049A640A1C1075E2703DB1B547D8C013DA7E3970E1F8946F3C9112AE214109D4AEF6EE0136576457150E8C54C2056D3688147CBB3C533E1DCC781551477FE4FCE6A1BE0116C5C0748CCFC8179B28F27797F58600A99AD1A3C5595F0A09AA6442A516D122EEE099C60EFD54389ED65389DAD246386C6CA2BD9BB3EBFB0034A3B65D08AE6F10AFBA3B4558946543462D627188EA244AC96020FA9BC43313A46B22259AAEFC421E6A2BFDF450990A0732C8518DA7286AC923804928161D3C8CA77516AB03D2631AFA65CA44E3820295673A1ED5E012DA4294541FAA8964A6AA", + "k": "7E151A29276FA13C06F530A46EA14DC37B820963562AE9069C17A7FAD27C5F1F", + "m": "696EF6079C573B67BA3531CC69730216A3A8136EB6F647481382A5CD93C6B7AF", + "reason": "no modification" + }, + { + "tcId": 72, + "deferred": false, + "ek": "FD1B79ACFC0D6D79464A3A59A5E18DA6D54C7E272B77703A22610C75FAC3675B89E350047C80C6F5B6023A455C88A44B0327BBB6F40E1D502861F77E7F2732742C88DCFBB539464E3189A5B21ACA30474E3758AA8BD2259987B8390698FD52378DD505D964350AA30B26AA925D83B6C3CB069113A2A3133FC2C19714A042C3056C774805262595CD2504FDE7A82D19878AE208E8173D9A855D39173D027B05CBAC4DE7408A4C0A4427109D60571D98D1738FA09B1D80BE859B34F3268F31A6CC472846C6E5C50F2A3E22CC8E81C78DA627CB2F474CE1EA0B6C02C7F9135129056D05F62D9B36BA466B9806F4ACF09302B135906AF7BFB43020A68444D22168388C8944BA60E7E803458B10D3B061F0652E08607CC2214CFCD2BC0B1B2148BA14691635C40492A4464230F7B6C9AC0366D813249B37FF57AD8533C752C0CE2B765D0319B84F204B9960B8C553721E5C1B93178621D4A16B8C5D2BEC6A91018F80861BC92CB44B25AC1B8C937793892A989D8FF465623666B1E467340984F45A1A591453D894C0E27876F851C664E19C3DBB3F62D7C7B9AC5C4D201FD3C0B3F7597D56A34CABC65F5E62898B0358A803B8A8651E8526C010184EDC0A1008F047E082BC63F0236FB93A9E70750255A28065A32B582CBADB3178F4B146A47893C62AF7CC63DF404715182013F13A11249CE5513D242A2E8B33C4B1B730B59A1B121181BB39449CC021C97C7B6F187966522C4DABA78BF231B945806B590C5638B1767280C29A070C0619A74A6D3D65C704DA99018418266A2AB1D2861B80700F67C6C845744A51220C4743E2A6639F188C95871B44D586F05A1EDEEAB382D123FF731042C29D50096155EB59906A7BDD2881D94081BC330CC3A71D3C1391485109CBD8026744AB57632D0EB35087B11EBDDC24222B4ECB435586C7226B11644AB9A243291CAC62CF3EF90B7991014CB7906D9B455A023FC94C7DC935221C4B2A58398F803801BD2A1BD5B40C17B529FABBC5F3219419DCC911E70FA0397AB407BD73258002594EEBECB45218154196A07A53AEA0ECC56F25AC5184CC39DAB2399B555851B933B45971C85CD3299819A27F756848C33C4E67B6449796B99A914AC8083719D752F06580D328087510AF7A5122F95A02A30190CE72482BF04FA37306A28836AB7A6AB11A2A311C1D9591630FD827431A54C2C738C5AC9CFC67BAC2480763E2CAA1C81E52C9455E305438BAC378D8A4A05168D72C39FEA242DBC794BD11B504E4630487142AE867903C4872F0B9A8F1572403A51940CCEF99618958A71569A8E32992F881B6084354548046F1E4186E11707CA72103DC7292A7858EC77D24BA225819B9574470C467033E35C3FC8A8CF955CD82565576EA576F5C43E0682C50D0260A30043CD40010B2B70C60A86F242EF193C4D3B837F33771DCA999253278D2CA2B9B88473DFC7565F282EED3739967345F90AB34A902F393A2389A557C815591665D63652F43C321ABF0712A012DFA6C04EF86A67F95A16B784E3BA18CB13215EA09CC2B5238F9391BB6A5C6DDA2C6F670A1E58329A8544C1E2C3E5D2A478057A5E46A26982911CC599D83A5A18D918FAECC86217A165C052344A38ECD885AA0E4CBC7D4742C99B1700578D454ABD5C83F587CA48A3A219D72B55F1934BAF1249ED25110177B6B126E0E1379111BCAFFF719D65B5570681164A80AE5E71D677586625020F605103513A0CC94A6632220A5687D89EC887956CC3F6575DF735C738222FF7AC70D468860420D0E53C192FBB31C8B834FD10EBB4B38C1517BC6E60BCC7A5831741DE067274B637060D4CFB3A82624B4207D94355EA3BB562AA9C5B9C04E2182C45955A06C5C7DEC5AD78BC9FAC6A87637BCB14AAC3CA76D5695196937CA34A36F183C599645CD67F33E060C6BB784227C735773534B4D501D25584C0F412A1A697C041C59EB85472ECC1B780C509E3417C9890722E57003A1B5AEEB11A764A6248C724F8770400747F04675C2F54BB1A983C59573EB8C64B39A3F552B79F5D365FC461A0414CA2BCA1DAC961C2E3A0A72109D79E26A59C1B659C4A45E9C8C2882CF6E26B67764244E3BC739349EFA0B9DB47B2152634240CB7A44A0A2B9CC70D557B6849A9976118DD8E74CB7896915368BFD120E31C4A261683DE548D0D6BF829F1E94FCF9E53757DC7EC8255975E848CD84360CBEF3FD", + "dk": "DD5097EC5CB6CEA0268886223C0370FA495D5BD55C93D6B52F74B426A2BF1EBC3A791A6BB6A1B7EF585291E3C4176AA91CE998D73A2359361B20D715D8250385DABF4B4438CD26326A19A651D16817F514A317795496349BE3024BD7AE24C75BE3F313A64151E31BCB0BD533B7388A0A865C41AC4FD2D087AEEB1F2758771433A780D88A6D47255B523A72358BEDB3BD64895039EB2C9434524A926B0291C0D4084C743CBBE35C35F2866DA31C27A5EB1CB87C014B021056507702702D196B34F5B15E11B953B3972123A757084CB50E46B6A03B5F66F41CA7C7720A63C380935A90F9AFD820C1A4D305C7D3929E0C93A5801D62C31F3CD9C92A8C9C61350587F0972AD0C22B32209ABCB16F69C2ECFA89197B27D64507001C71AA22475E851560F046DFBC935397C28A9237D19081983652C80C4C5CC6C5757C8AB5AAA39FC591F88322B851CA8CE5609FE51C1D5B3B6086531046A4688121F86326D03A5E9FBB761B22B67A0CB84EFCB0EDA957B1587F8FB8330AF5BD01581DAAC976C46A9B0684131B75519251CCFB33A6E32322CCC9BDE7A2504A31A7C1642A631B116089BBE4D12B90A761C5D2BE88B58B373351C385467D196A169BB328970B196A3E3F5C0B06FB45A5C84020F37A9A94CA47F11D04B5A40B14C1093C45EB29AA834A3BF275B1483A4762E7434F761456F45F0C3116E78AC4B619B9174027B830882C53A845E9BAF1B750C8F52D1B5A3DE474A57F57BA9B0BA122A67ED4BB13A0C608325295F2E41629312E26674CE55C9C1B1A252988908315A662956AFD73609F546A70D48F63CB0B6650B9FEA1787AF017609B2CBB30B8F605A08BF12FAE63A0BAA37C25054FAB5004C9635CB2508E46E979777A6AB2F412072999A717030CC4C55EC13314E509D22A27BB290BC9778414C42552F88E739570FBEC7A4F87A4E9BCAB909377F5288A9F64AF721562B05CB5D92268614142BB8A9FBA30ADE6B825F8D9B0E2CB686AC9AF7EBAACB0695F24C1BD29C9CB1C5CAC6C9778FD8C45AFE6B6B3D32CE07570B2A804A3F111F07678E141AB27F12CB375B1E329974FCA796E2247B7B31B6AE23372978D7F7BB7A278897C25C7138510430CBB6F23BF5AC1B9B124B5E546472C80877D503906841547B45A72A319537C1E6A335B3E71AC04DC01D4A678F7C75538590120D2BCB0B767AC601148B12D66F1AD59A6CF4AC125C229C4C7A75DEE611862A47FD82A049600ACA1266BF4B06BEE3C6540E1796E23AE3C11317C8B158BC814F1931F2E68A4281B7DC0F48344E50FEE201F2022BF7E48C79B89AD917B3F6795A8E6C0A3F4C795467983EE9457CE57C22C18B65CAAB119BCBF10328EFBE91A9AB8765E989C190A1108799200552545706964D045FA54478CAC50DC1044266B70298AB27231592B2675E09705EBEC47C64868C26A416D6C97A1D87563DC56FD5A3715B45E063A632BA278A4C11B3ED76557782D1F3640EE305238842D5D8A0251021D63F976696516970CC6D8A8214CCA2F5A265BF2B5AF145A8109413147E88E9C7926F7C668B38289BC6556C10334DC3438904212A02B868F0B5773C088BEEC7F1A914DE0520260E5823F89935103727CF8325206963491335ECB4BC20ABB8D76481F0703BB077881958F5E55274BF9A149C11B7B92B4BB63B8BAF06CEC031A8F899A66E28E9610837100207DF7155B096A33BA1EC3A779634C3F571AAEF3B6B7B97960E268685466CF06E683DD6586315413FDAC5303E664330AB575832C394A084C65BE3D41BD533C631BCB411C718145C264F977435B51BFA8A7C2999147792493B8DB0892540B93E27E452C47F7E57B1DE09C04519F9CB1023855A06B2C76F5252FEBFC1527D55DB1087ACFB7AEA532471AE14449F843B47B96B8C06775F27642630DEEE6877DB17D2BE4C101950332614B4A5040FC74C52C07597C1B6C9D46443D68A2652C2FF9EB57E4F4B247CC31D6E5C732D9083A985BE9752506C07F02CB868004CE0B3154FB5A92F6F5A15472A9FDE333AB1B0F08386397F9621566790BD8AE0CB89763F2CE74495D1A54A800E657A8D42613B12A8F3A416795359AF55E89B28D2D18A3E8B110DA297D33CB0BEF9C14D4058AC8DCC633CC682A7C3BCF10BE800BCBCDB7CC773412EC643DC77B5F5CF0A87DFB25FD1B79ACFC0D6D79464A3A59A5E18DA6D54C7E272B77703A22610C75FAC3675B89E350047C80C6F5B6023A455C88A44B0327BBB6F40E1D502861F77E7F2732742C88DCFBB539464E3189A5B21ACA30474E3758AA8BD2259987B8390698FD52378DD505D964350AA30B26AA925D83B6C3CB069113A2A3133FC2C19714A042C3056C774805262595CD2504FDE7A82D19878AE208E8173D9A855D39173D027B05CBAC4DE7408A4C0A4427109D60571D98D1738FA09B1D80BE859B34F3268F31A6CC472846C6E5C50F2A3E22CC8E81C78DA627CB2F474CE1EA0B6C02C7F9135129056D05F62D9B36BA466B9806F4ACF09302B135906AF7BFB43020A68444D22168388C8944BA60E7E803458B10D3B061F0652E08607CC2214CFCD2BC0B1B2148BA14691635C40492A4464230F7B6C9AC0366D813249B37FF57AD8533C752C0CE2B765D0319B84F204B9960B8C553721E5C1B93178621D4A16B8C5D2BEC6A91018F80861BC92CB44B25AC1B8C937793892A989D8FF465623666B1E467340984F45A1A591453D894C0E27876F851C664E19C3DBB3F62D7C7B9AC5C4D201FD3C0B3F7597D56A34CABC65F5E62898B0358A803B8A8651E8526C010184EDC0A1008F047E082BC63F0236FB93A9E70750255A28065A32B582CBADB3178F4B146A47893C62AF7CC63DF404715182013F13A11249CE5513D242A2E8B33C4B1B730B59A1B121181BB39449CC021C97C7B6F187966522C4DABA78BF231B945806B590C5638B1767280C29A070C0619A74A6D3D65C704DA99018418266A2AB1D2861B80700F67C6C845744A51220C4743E2A6639F188C95871B44D586F05A1EDEEAB382D123FF731042C29D50096155EB59906A7BDD2881D94081BC330CC3A71D3C1391485109CBD8026744AB57632D0EB35087B11EBDDC24222B4ECB435586C7226B11644AB9A243291CAC62CF3EF90B7991014CB7906D9B455A023FC94C7DC935221C4B2A58398F803801BD2A1BD5B40C17B529FABBC5F3219419DCC911E70FA0397AB407BD73258002594EEBECB45218154196A07A53AEA0ECC56F25AC5184CC39DAB2399B555851B933B45971C85CD3299819A27F756848C33C4E67B6449796B99A914AC8083719D752F06580D328087510AF7A5122F95A02A30190CE72482BF04FA37306A28836AB7A6AB11A2A311C1D9591630FD827431A54C2C738C5AC9CFC67BAC2480763E2CAA1C81E52C9455E305438BAC378D8A4A05168D72C39FEA242DBC794BD11B504E4630487142AE867903C4872F0B9A8F1572403A51940CCEF99618958A71569A8E32992F881B6084354548046F1E4186E11707CA72103DC7292A7858EC77D24BA225819B9574470C467033E35C3FC8A8CF955CD82565576EA576F5C43E0682C50D0260A30043CD40010B2B70C60A86F242EF193C4D3B837F33771DCA999253278D2CA2B9B88473DFC7565F282EED3739967345F90AB34A902F393A2389A557C815591665D63652F43C321ABF0712A012DFA6C04EF86A67F95A16B784E3BA18CB13215EA09CC2B5238F9391BB6A5C6DDA2C6F670A1E58329A8544C1E2C3E5D2A478057A5E46A26982911CC599D83A5A18D918FAECC86217A165C052344A38ECD885AA0E4CBC7D4742C99B1700578D454ABD5C83F587CA48A3A219D72B55F1934BAF1249ED25110177B6B126E0E1379111BCAFFF719D65B5570681164A80AE5E71D677586625020F605103513A0CC94A6632220A5687D89EC887956CC3F6575DF735C738222FF7AC70D468860420D0E53C192FBB31C8B834FD10EBB4B38C1517BC6E60BCC7A5831741DE067274B637060D4CFB3A82624B4207D94355EA3BB562AA9C5B9C04E2182C45955A06C5C7DEC5AD78BC9FAC6A87637BCB14AAC3CA76D5695196937CA34A36F183C599645CD67F33E060C6BB784227C735773534B4D501D25584C0F412A1A697C041C59EB85472ECC1B780C509E3417C9890722E57003A1B5AEEB11A764A6248C724F8770400747F04675C2F54BB1A983C59573EB8C64B39A3F552B79F5D365FC461A0414CA2BCA1DAC961C2E3A0A72109D79E26A59C1B659C4A45E9C8C2882CF6E26B67764244E3BC739349EFA0B9DB47B2152634240CB7A44A0A2B9CC70D557B6849A9976118DD8E74CB7896915368BFD120E31C4A261683DE548D0D6BF829F1E94FCF9E53757DC7EC8255975E848CD84360CBEF3FDD737B4854C1D79C36194DA7346217580DB481C0DB2116D4DC3A296BF64A89F466B256F764B817B1F7901D0B12CDC08EF3C2419B0A23EB25ACBA70917A39F3171", + "c": "163F9FDECE0DFEC9D2BA04A7CF3A72A3CEF584D0F4CA5B041B72AA48068C21D474A61C0AC96725C657E6BA96210929BA18C5192AF13724E72F4CFCB551F6D0C2A59A4C4410D284D45077AF6C3A7911D0D0B4534409EC8C521C2C8BCB8B14D4901C0F8C85FD3CCABE31B6C5784F4818B2A195B9B837DEB60D739C608CBDF9E13C06B7F1132F6EC0A4823CE42B00079A19F1A81269BF26820474F0C0CAA81E20FB059AAF8E11B51741B5849A87FD0349CE05FC37759B61D191479B391CBB4EEE04908B7680E047232DA268EE4388D9D92FD944689D6BB8BEB9C4FFDE45FD77435E6CDE430D34C5D50C107B963D8E1AA79B0DC4633F31B79B5DAF009B76ACE6BD277F5F71EBF3B08A4BD511E26B8B1291D23689818E0BFE4DCA6EE0023297926D777F44B1A3DB409A5013E366118B98571059AAAF40FEB83E660894E11DEFCEB4A08CBAED1C17CA20836F81F78A128D42D94B3D71B010AFF7818FD2FFE7D34FAA458CDEEE897E79DD9D8632CA772303EFBAAAE1591810823BBD57BCD3858B37673436FA41D89D8219DDF163243FD773A40D1402CF4AADB34AB4BD75FA675DBA29B69A7C464372111EEEA8263D05ACAB73BA1655556CCEE0057417DE564B7C3CAA72DAC1AE5936E75EBD9B30671653FCF5C4C007ACF7C076688815492189D4BD7B76E6BDD2E4C5372B963DEE5DA9719C57B228299C4DE44D136FD5E125C9781CDDD9DA18F58AD586DCA62DFDBF3683AFB7BD5AFCFDBD0E5238DD89EA6ACEC0EBE39103DE643D017C67576017F550D7C6047AE2AEC3C1E4EE85D33C2B1C33AB551887C035BC437B7C5DDC5D06E08C35E1F46502CDBE630A4C59C14309EB2921D8468713246408FDC894C993FBBFAEA06A4CD8D8AF2E86A672E8763AD4E4003CD4379DBB1DB93B08CA8BA9B16BE4D039623DC264C6E0C730921B9B42CD665F7CAD4462B233DEB6DBC0A9CC5969D98D8783203C3E3004D29ABCDEF33E83D8FF5DAEF548B2AB91F558D23B2973A882A41B85FFABD54F908A79A8A0D2889BA54195405D8C24DB03EA21A92FA9B733EFB75480E8E7757F60F0E58433E599D9B9325368F1135FC3EDB9791E4A25D9A714F37970ECAFD78EA94582BB370F405216D4F22998AEE28D0FEB31FE42D2F533D5F97BEFA759F25684C1714677CC96E23668F697D2C39087A50A131BF8AE98E5618476464283F6F75DEDB24D7174D090C3E3685F10B6D90C423778EE272FBEA69D53C0BEAB7024A4D64AC85B147F9BE83EF3B26DEB5C3843131BD4BFB24CAE9564503F41197DD33355F0E7C7CF069A87B7D68B5BA0343AA5E6B9BAFE6C93D1894241C86F9163353B2E79C28ADB24A7F052A21BE8F3B3807AC16E66AC3B04EAC1D92ED78DD2468A58599DF566DA1F052DF6E7786F38EE15510D7491B1AFD87578C42075103C9EFCC49362AEAB9FB8F6BBA88506B32A536A5D535BA449AF8AA79FC4418F6A43A0289899CEFD33D93685FF4AA2BF413526D06DBFBE5BB95C6481A61755E961B2CFCECA472BE408EC95175A942EB27F21212E7C8E26F40E241650460471477B600A5895D934940C8B86AF54889C7D42454D8E40BA689FE02C7653AA7F6A6CBE16DA3C81BB6653B20B2AD24E172073C38CB3E73C192D7C6D0AB2E7DA418A3DFA2C6A45C53A8DC81EF0FDD349E91C2D62B1B38197B2AB41C8478B6F551437FEFE9BA127F19BDA0185E63E9DBB09BEB1519DE53A4811070B8E89F447D6639E76D4DAC5719D64A22B161D9A13D3FBCF707C2FEA9E92DC675B92F0AE208DE93E49D2015A33249CEA4B8AA236E4B27C3B4111B7E62A5FB4E841746AFCC5E37A81A7C501AD8E1C725BAF7C358848B63FF0ED9461ACED678DD501BA506C5376A69BA03258F681CC343BEFAB1AAAE513AED9910AF6A5970CEBC113532A18BF94366C280A992DAD57F2E57D6EA6DDC5AC1A465B1D5CA8EC6016A592B5CFB240D3C11532F0DAD89190E2B2B597AD12A4648EB605A69F2B34BFDD19F092738CAE74E5182A9E2BB91FBC5C87116F10D8DFDD751FD68806ACC64BED13D832873EA674D70755C89F60F1C0046B182D1F5BFE5C851AF7707A1B1A2E2C3A8BA52088454C8798D344F29283B006DB102910766C9CA33F405CA44207057479C4BA23D11C564D21D3DC98D6AB45C57B969DBF42513E8D589C0DFD602922CD875B6D0988527B9EC39917BE456FA0D8339999E68E51E07CDAB598D1B8", + "k": "42D06DEDA4AB863ECE98FCA1C9C3E5CCCF7CB03B8411B381B028034F12B282F7", + "m": "B2180DB6D5A468155A4C45C90495F8875538F05B8B8587644B4A668CC8936447", + "reason": "no modification" + }, + { + "tcId": 73, + "deferred": false, + "ek": "5AE08BEC33AF8C2967C72B389BF868211B80B3F3621279CB84739860479BE408929695B043BBC623B13B7313494111C07EACCBAEDA248DF4BFD4E480526958FB9811FF98CCC755231045C744D29A6A3103012A3C61613C3305C0A424C8F483362B5150A045888AB09E39F08FCC81B79005C1B3B0BA5FAC23BF438048C675122ACE4CA672D4D6540F9064AA9766937017B147CB05111C0706A5B549498899423B1000A27B648F0BAB03307F8E492D582723BB20B044E91CE259C611F71B7BB57E90D4A249D02A7892B4589A63EB591CC559A3477766776505689820601B9CBD75AFC344C43FD9C9FF55AA4C791DC0188B17177032796E07368CEA357874882F32948EE0B63D589C808F833AD2566E22FB02C77AA78767B194731EBF5728F1A858C6C85102B70C56B96D32428364EA7A904A7EC4F2517AFB2AAC817AED1A53D701CF16168AC2E45730D57F93C12B9CDB38D602025B1C53E4A1CEB4EBBDC9403DAAA368BBDC9BD9858BB0B53945948CC3DBBD7B2B41A97B847447402C5624D30CA0738912BA19780BC5C81A7B9E26C3C2E155CF5C1A58D26413988267738B848F20681B823E9828BE7A6A8799A1360C2298F448BFCB5C422ADB3D6CE32D8FFC1A2E52244DB9C994416F15C3B5433319C04559E3C3B895B1B322232A69029AFEF53500AC5C87A4606F5268BFAA26FD99B45C456D96E1B248BC8D2D79CBC9435D3A8B962E91A81FC76B1670ADFD12B3FF044078A72BC36C8A435B966DBA5C0CC97B71635206CCCCE2972B80C818DC43325830A02C6482CB5B2079B5AB6AC50C24E95D16C8259945AAE9D45CC66B1F125B70915C5F222670E54A5B8CCBA4F973BFCBD763BF2BCACFF5AD51A9255481925C893C630B38678A355EF40A39F56570D961846A2E6CD827CC1BA4B3813B6B956CF4AA26D7E9CCE1721E04B9A5B8D4910CDC484134730B639B57B39CB5F69663EC7490B339C61B4EE4AA83393ABEBC60868B945CFDE98933296793F74466320615F03DC4222F69461DBEA4458E2B6E1573CFF4F610F78C3AB609036641007EE369BBE382ECDC888EF97C1E1812B87964EC19B04DF5194B4049DFD2A87B63034F7A02C3BB731CB67F7282B8DCB131146570AFB993661B059797799CEB7D081CA13421BE41B32ADE2404B0519A00B88A0E088E29F846F5B738113B31C680BB96AA736CEC1138CC5F5D9C67CBAC9B29E1C1226812E1BAA39F151BDFF15037E30E1D3B9CF86423131A4FBAD95FA0585015485B5DB755E0F45D129841EB7614D6C7AFF6194061DB727B299A30238E8B716C72400828B377D46B3F2AE9119EF72AB410C97CD4B31EF77A610242D3ACB17CC2B335C5B2DCB3759A4255921096087CA0ED428AE6703CB15A9D9D8A5E0D64B85534AEB4F2076130848CB450EE55954AE61F40CC25932851A2D80FA3601C74906F1A5360A69120A5FCB4793326F0C8222969A40FC16D46F1CDB318BA511C72AB516A4F31CE67204938E68EB4F16202F42D9E095F1714BF2719C7E571498CE304DA997FEF45549B5BB9F3834209096ABB39C686E4B2C9C796BA69B368417A45970178E9801221944EAB90656B623B53903554AF1F0C7644D79B2BC186C0EA5C791795F99A0B9C29346CF9639EA892935878E6F2AAB73CCEC7201D38A26305A286BB1970BCE86033A14D3677AFEFC81757A69C07299164790473055F10A8279357BBEB31C173B87B62293BF963C453988B390B3697A3CDE4EBBA5CF1B08F78CAC7498DFBB6407D6220C376A4799AA3A8871D0270870B9495499C88C98A5762F7CCB6FB0CA10046F06C06864345CF4C5B40B11181A973E473ABB9786FF307C65CB7048FEA4885041E65E0013422BCCFB65BE8CC9CFBB4448A645FD3F81779AAB29ACA1648708F249C8B3F9CBF55C736F5746854D89A923C1CFFA781D26C241616CD01D7B372F568B50BCA58D88D01FCBB23931DE6DA2D688A6751158971A5B19C6B46C3B761D8385238F8B9831266B09B16B5559B5EB82F64B7133AD36C5497C9BBA4AC9DCC094C3673691207D3587C97197F5CF7C1DDAB6A9F1383211639F3C57BFFF3B01709974C79C9C51B2E29E91770911A52281F030531239CB049BBCD841B1D764C49E0E8492AD383A093925AA818FC0CCEA049271F307C51F3C97A7AB5A81B43B52A6BCE2CEDB2D0E706D280DDE4A0991FCAF55CD36AC05F3593F3C797A9DCFD0FD0E0", + "dk": "3B052C99E38F21B24FB9461F66218E682A2343807AC6B0BFA79B8E077257EA63B5AFEC54AA9565D85536EBDB036E82389E228ABF62167E1539F31A5CD19C87896C2A31117C180C954E8BC5FCC63ECDA30762383D7C7990F8C1689BF90F28F460C66AB468337353838D6B675CFE475C4FDC6BCF3112F5B4A142A439D64C557F0075B8DB9D059AC883A1548B031CA8EB58D2930A47A18A0B2518DD6B56A8AC961CB41B1C7A9DF2479E3E43C4A45703C2C66103A0199BC09347CB5E0D700E27B61024C45B28C3B9112A899855CF7C77B1B2D3237B6A3E36157E888597D87C07D7885A89A257AEC29369800C9DEBB1EC5A188DD367A6437FF3B97EF3D7201589987C3238570A8CD1F9089591068F572BF72954A07A160380C2B4C23DD9381878BC54140B101C27873356381EA7425D3C83EBE93C4CABAD33B292B15B68F794816175A5B69B36DD973966CB9EDE35C4EF46326CAA08B95C961F693D0B499103BB0CBB42CA25E08607600438E004E5E373A994A0883508BBFA002566BBB3A79269CCC9687434B22350A4B0720C549529298CDB3126D8162FAFF29ADD11154A73A1B3A4BE3799CD53C533A6A6331C9843E83678B2226F36931424367976211E834A50C0101A6B9144BBE12522B42B660915812C6D07204EF0934B258711E0C50C99A0979CA7A765817AB57A75264B336CD8AB86DB894BBB3414726466A7857E92509B8BB39C67315C205BBE19321756B6A3C925910A1CDA417AAE4B268B8C771D311DF152696BA0659384A0D5AB2EF5B7AED2880C75C83CB5232A3BD126668307BD725E901A77AB46855DAAAD109BB6BE8A3AD49755FB4450624296BAA08BFC48CE9DF0BE6A00016C966D1B6A8C6E959A5C8ABF6799B63F2280CA1610971C046C960C691183C233A1CFA889489BCE2DC927B6C388BCB74EE1FB4000EAA98D081BF2F95907A10CE2D4548B91159EE877C12A775538508AAB9A6BC59201B3ABE4F7539E34C56BFC13CC559F80D9A1796B81F90308AFF381B99B686680990E9CB7E830AAA8612862C1C0DC0AC74B3016E3649FA5D7B8BBF870C7459BB34213DA480D33C56C170C71C912B78DD4264C979ED64098401A96F353BE82EA241B200B7094B60566B1042A39B94120B053CD0F56644EF8BD88079BF8A935083A94D169C765014917A391A0A780CA6C9C0CB88CABE20928D2CF7BAC04589B108E0C7E55A64070C52EDD65CE50EACE1DD63B10471266B1547D79C919593C36A10894320DEFD85CEBD12647E984B48C259F59B398286142F0059726408E56538F5C876067821685C1CE3C8F05006BAFA48718D54295B64BBF82BD6DA9403A2AA5E9F21380756A4AF71F9EA1CF99F31F22BA7513609AB3ACBCFDEBA09D5C5DE45B0D83F13D0557AB627805D02588C2E772351B2679F86ADE56873C509D6F15120BE86BEF908BFEE629DE3B221D4B03A9909B6B722181085B82C087BD4C985601C6EF1665890054E90A897CFB06C38314F2766C7BF31E4664C0EE025EAB2A80233AA1533032AC809718A8577F1C2D968475E4A0BBD25514A3B27C68EB49775ACBDC22377A920948F2A7B4C78F17520273E4206AFC8E6B580BC597CC1773CB34963EB7726C55B7555041852075A7C06602B9D717EB5574823352FE49134D972EC7B2532A273CA0EB5540B9CE9C6A9CBD1B3079C0BE96B178CA71593DA4A49A52B287144C962B28063292EDDCC84C13A6F7B0B26F0B252E2835A7694AB7B8C6F8B132448583F1A27F8AA9A86224648B05551E332187B296F542CDF746754B13B395B16B451625A032AB7C044AFC6C8EF548321183B695A8CE05E29296804BA0D96902B98ACDA81E98B996748385796CC3DFFB46026A434A71428531C0D7F5C05B877815265B989A16BBBC928DB6CE11CA3249FC3410EBC8EE088B7053AC44090D050A1DA73275118B9D3272AD38234A294C6A52C98AA1CAB0A2089450BB7AAC635D55D1A9099A1FC951783078AD83B771135836FD32425C16C8C5EB259DBB0F27840BA574AFEFB52ABC6091BBC8AEF6D6684B02BB5414BB39BC65378B715A492E0BFA13ABE7713D401EE930AB98E5CEE7DC3C12F1085C528DB8121552D95E7A081C6DB34DD616BAF3D0427E0CCE01E5A804DC5A100958F94C89A2FB1D88ECC13B702ADD75B5847234DBCB015AE08BEC33AF8C2967C72B389BF868211B80B3F3621279CB84739860479BE408929695B043BBC623B13B7313494111C07EACCBAEDA248DF4BFD4E480526958FB9811FF98CCC755231045C744D29A6A3103012A3C61613C3305C0A424C8F483362B5150A045888AB09E39F08FCC81B79005C1B3B0BA5FAC23BF438048C675122ACE4CA672D4D6540F9064AA9766937017B147CB05111C0706A5B549498899423B1000A27B648F0BAB03307F8E492D582723BB20B044E91CE259C611F71B7BB57E90D4A249D02A7892B4589A63EB591CC559A3477766776505689820601B9CBD75AFC344C43FD9C9FF55AA4C791DC0188B17177032796E07368CEA357874882F32948EE0B63D589C808F833AD2566E22FB02C77AA78767B194731EBF5728F1A858C6C85102B70C56B96D32428364EA7A904A7EC4F2517AFB2AAC817AED1A53D701CF16168AC2E45730D57F93C12B9CDB38D602025B1C53E4A1CEB4EBBDC9403DAAA368BBDC9BD9858BB0B53945948CC3DBBD7B2B41A97B847447402C5624D30CA0738912BA19780BC5C81A7B9E26C3C2E155CF5C1A58D26413988267738B848F20681B823E9828BE7A6A8799A1360C2298F448BFCB5C422ADB3D6CE32D8FFC1A2E52244DB9C994416F15C3B5433319C04559E3C3B895B1B322232A69029AFEF53500AC5C87A4606F5268BFAA26FD99B45C456D96E1B248BC8D2D79CBC9435D3A8B962E91A81FC76B1670ADFD12B3FF044078A72BC36C8A435B966DBA5C0CC97B71635206CCCCE2972B80C818DC43325830A02C6482CB5B2079B5AB6AC50C24E95D16C8259945AAE9D45CC66B1F125B70915C5F222670E54A5B8CCBA4F973BFCBD763BF2BCACFF5AD51A9255481925C893C630B38678A355EF40A39F56570D961846A2E6CD827CC1BA4B3813B6B956CF4AA26D7E9CCE1721E04B9A5B8D4910CDC484134730B639B57B39CB5F69663EC7490B339C61B4EE4AA83393ABEBC60868B945CFDE98933296793F74466320615F03DC4222F69461DBEA4458E2B6E1573CFF4F610F78C3AB609036641007EE369BBE382ECDC888EF97C1E1812B87964EC19B04DF5194B4049DFD2A87B63034F7A02C3BB731CB67F7282B8DCB131146570AFB993661B059797799CEB7D081CA13421BE41B32ADE2404B0519A00B88A0E088E29F846F5B738113B31C680BB96AA736CEC1138CC5F5D9C67CBAC9B29E1C1226812E1BAA39F151BDFF15037E30E1D3B9CF86423131A4FBAD95FA0585015485B5DB755E0F45D129841EB7614D6C7AFF6194061DB727B299A30238E8B716C72400828B377D46B3F2AE9119EF72AB410C97CD4B31EF77A610242D3ACB17CC2B335C5B2DCB3759A4255921096087CA0ED428AE6703CB15A9D9D8A5E0D64B85534AEB4F2076130848CB450EE55954AE61F40CC25932851A2D80FA3601C74906F1A5360A69120A5FCB4793326F0C8222969A40FC16D46F1CDB318BA511C72AB516A4F31CE67204938E68EB4F16202F42D9E095F1714BF2719C7E571498CE304DA997FEF45549B5BB9F3834209096ABB39C686E4B2C9C796BA69B368417A45970178E9801221944EAB90656B623B53903554AF1F0C7644D79B2BC186C0EA5C791795F99A0B9C29346CF9639EA892935878E6F2AAB73CCEC7201D38A26305A286BB1970BCE86033A14D3677AFEFC81757A69C07299164790473055F10A8279357BBEB31C173B87B62293BF963C453988B390B3697A3CDE4EBBA5CF1B08F78CAC7498DFBB6407D6220C376A4799AA3A8871D0270870B9495499C88C98A5762F7CCB6FB0CA10046F06C06864345CF4C5B40B11181A973E473ABB9786FF307C65CB7048FEA4885041E65E0013422BCCFB65BE8CC9CFBB4448A645FD3F81779AAB29ACA1648708F249C8B3F9CBF55C736F5746854D89A923C1CFFA781D26C241616CD01D7B372F568B50BCA58D88D01FCBB23931DE6DA2D688A6751158971A5B19C6B46C3B761D8385238F8B9831266B09B16B5559B5EB82F64B7133AD36C5497C9BBA4AC9DCC094C3673691207D3587C97197F5CF7C1DDAB6A9F1383211639F3C57BFFF3B01709974C79C9C51B2E29E91770911A52281F030531239CB049BBCD841B1D764C49E0E8492AD383A093925AA818FC0CCEA049271F307C51F3C97A7AB5A81B43B52A6BCE2CEDB2D0E706D280DDE4A0991FCAF55CD36AC05F3593F3C797A9DCFD0FD0E004FA8E0B4695D94C8D670F7E010B0562E8AAA1C46B3EDD2CF2457F39E36967B6F7A6D1FC80331296B8B5568C0B506ED3EDD6DE5E81E0F76F63F7297FB41C2CC8", + "c": "8C4E7C59965B9CBF50961819684ABE5DAFC3AA381F779869ABFD60C263407D4C03CE96CD714C0A62532CEB8E460D2455B84374F4EA30FA5BCECC77EF9FE108AC3EBD24AF4E60194E8FE7E50152AC312B50F9DFF28AB23FD2C9ABE4C970E7752016C84093F9D8483E93F526B1E505097BA5687C7A7FC8CC2CD0AE94DACBAAFC2D4F766CD212F6C04E23762045A1C856EA1D6F505FC96BFF1D1E485654690E7A7698A05B48847784E2629E6D81A692C93793FC2BEE69194A106E3BEA85A82FC692A0A3360D96128ABD52E72E7B3A12838C5BAA00B5A5B5DF9CFF4E027EBB7D8270C2D6183BBB10CFBDAD15FC56C7E3166751E7DC11C7DB5E5ED6CA5414ABEDD0619890A03C713C910F55526451171A826997B3D86CD9EFCA8E5276D7CA2CE1EDC0266CF876380901AB366E0EF60849774A2DE260D2D155F27440A6FC88EF99DF76C70F4D4EECB4A901CB714C6EA72D6D3BF6FE1D71988E6DD8EA001E0A55C00BF49B62900A801AF1A0CDEB6096503F70B36CD85AB57DB22536FE202E1DD796461E6E78AF79F56C332C97833BD91260540C4A5245E81C08CCB70A62EC17B0E2BBF46D5601B76E2B8AF386F7A3F210D44A7E61A4885D0981907B40F01736E9C65CC4FEFF0EF978AD93B84C6C5071A8E793EF0572F584BF27C328EF33B5ECE0844A83590394D834E225C2CC87DABC829068FC0E7549EA93EB52C3311C4723EF6F84A0C0B94B7F8C610876DE7DA886354B7984A6715B4F0C9A22F422144ECDFC23AF2858D147C26F3BBE5663F5006521CBF222748F67B01CD80CE5B6BB9DC7807C93EDA3B882C7CD5E668E40E6026F70D6E58AB760162816ADF71E7B785E67EC786441FBCA9BE950377BB7256C3C559DCD937413131AB80DDD24BDD441551CC4F1A956CA96039ADDBB919EC52594A1D8BBAC241FF615685B05850A206BD4CAE5FDFE50DC848FFA52334DAC3C9A1BA55D481C579E5CB3F9D9206DA201908606E15B494373C458785362DA9FB2DFFE91C415FC6FA81B1DD682BF0971F6ABD89B954E4C97F5986033AD13A26EFA12C5D52CF90B513C9B0604EF1676F7CB440276602BB0EA117BD20B4F4FD1BD2F05D5ED3473DB2F047433E228E92BEA1A7C602A691196CE71B1745E4453E0E7F510BD78963CC0C31D30CDC5EFDD55CAD3DA519CDC565D73DF8A611CDEBA8D18F0B7B0DF3C5678198B6F39B478903ECAA791C3ACAD02CE3641C174C35BB210A48530426E39914980DFE742E4982BD3BC043585A4D6F65FCD35ED6C5CE403EA2DFB84B1E7E380EC0947D84E85EA70D116FB5D8F4E883261AB7BBD78AC094F45FE830E69451642C4C294E20509A6F13E769706ADEED355931F1193B5E76B1106F5F0D718DEC2EF7DEBFEDE714CD2D65370629FB920E54781535ADD8CCEF0981684103065785B34045190028E4E03AD5E5D509C68A117B4A00B6FEA07D26CEE453BA12321115BE2BE279E12D6EC5F80B263347D87DD6612A14F7BE08BD1A8F3A6A3D1E78C33E71C0F64152322277EE4E03DBFB009D5A1DDD9DCBA1BEE12BFA9B39DD542710B5AAD1052C767782FFC04180478E0AAF3F775DA8F68C094F84FB2E3A56B6E0FB98C79DF1A2A83449F63A351CB9BDEB0C83E871CD9146113EB5E4B28B8723F949D6AD19A5148F73541A7CDEE4ECFCF51A8EE474B27E65E983BACAE976C0E18873795C278489EF8C8503769037CF6173F2B62369AE7C39939AA5A806F423A76BA18B258748305FCBA016A12160C2428E7C60B839E98DA95742E15C8B32BCFA990B6B41F043910D3AAB1D1FCABD8AABA55D13A713D7FD62D25F396C67D9516576E2DE37A319556698104D1560FCB5A690C4D48D0E23D24717E8FAD776DE0DEE2339A0A6CF3338F930874EAEB38C75B62DD99F751D5616973E538C641F1C47034C8C9A1A565A889A1B565FFC3D012E16457CAC00856BFCCA7305CD90E295E98F26F8FBC438D2743D0849FCF0A05DAA139A64837C8FF56601475A80BABEF0A62671D4BA8F7A2D3B836DBCDC49CCE8685FED7C9B27ACF203687176B86D316C4EA9C549669363CC6D76E99A8E3426F34623224E7707DA7D1AECA02E19CA0985F05794E239BB8E21843D49C4C2F8EF59894A437BE6BC4C67838EC5DEA6D09DCB93B914D9E73628155D87C90E6D4B3D3DB2F31513BF692313E28E452BF205ABED9D7AE841AFD11B7483389F89E14CEC729A3CC69F0390A9F2F", + "k": "6FE2B3BA0E972312DB3DBD84F9B8E1D7E3AF411BAB1750D75E7374BAA6B25F45", + "m": "ACA147DD83685FDC5BE522178384DDB0C8714D0F818A5A20CD1AAA71730D8E36", + "reason": "no modification" + }, + { + "tcId": 74, + "deferred": false, + "ek": "9EBAA37C34B6F0C92BC7E98A0C56689C989E33E9126DAA3D94C95C6D60639DDCC008E4220F8C6348E44738C1AC50521A926B9BCD42511A33C1A704871C11A962E062B9625169A842F8D15CF3F3A0A2411017860C88A22D01262666F6895390AF652204ED9CB0F7589A63C23ECA851C25B527D242AC8D310B3199AF5EF7C54472739E17A6986ACAEE76B0B262C5BFB051343580E60150250865397B4C498B465B6C62E1C3A4B89B756871313AC1C4034509803C59103AA4B9A50CFC7C7EE0A34EAA417009538570C197D04C60CFB41578E274AF9ABED10B4BB7B71A4B925DDCF5432940934B222A36BC80E96C1094E5C264364660012514444ADE22A6121C30C4F037FAD29C2819350700A10C9861FEA471BD05C3D31A2EEA2A9CEFABCCF0B4AB9C33C19FF126B017370073561857084A83ABFA5B3550C2A93B785A4223AC57F4B6FCA0B4D12422B509CA45B63775FBCA4E785972E775E2989D844A4308B786F230CE990010541868C2C21B3D311E6AB14C4D417B37D10DEEBBA6309686896017F08C224DC806AE87658A0B00ECABC2A9F66029873C6C3446914C5A967441BB4AC6900575FA52238636707C69097E19C30ED66A9F28762056585C5738A6F51ADE3603B963476213B78EF65AB6CA7F612134E82A6BECF48D4DB4AD7958787A377483F0A8BAA76B06243DA4F61CF803807C17837A6293D144637BD3A92039282DA86485B005767519C9C0A0B513CA5325866DB3AA67638A2C0117FC80C4845ABADCA92C529C539431363A9A58E6A25CE6A42AB8E5CAD3865AC1B69E77B2B48DD5CFEDABAC79257D15269D72B1CE90265556DA687D894D15F11B1268692E22AD8313877FA8629F3BA224F8C5A98AA31FA58FDD05101C3705496516970B200F984B67EB497DB9AACBD6922EC84C73DB42EC0BA4D1D11859DC356765C82947B4953ACFAECB5969D34A4A8A44BA53346023517C2474A301AE7177A0253904186A5527772CD7845A4129A90B292051765772C09EF585A5BBC976F1F9B24C7AA4478B04B47398491785D9B9B9376B89D6C90320831117949A72406BE6076B4268A356E615A2168C9EEA37B2165B143304B9C51B3CC97AE3A6B0DDB185825C8B7AB073B5086B7D215D4C953F7BC9863339A045DBA784F5489FA51096234DD08B7C457B1C326B8F73672881562310E90B43FA7A37B7550696422A1B32A2615D4E8C5B3C3C61C4479A15D94F210A165311BB4C95060FB8287BC526C212B1EE0470C5497480DA396B2C39B9BB413E267583C249911029DF9B7822327764C16FA67307EFA499F0A7CADCE8B1732C91D284B505D59A444B41ED738C09A40F335C7F7050B80DAC9E5609C000473E440840D1799A86705276761E8CAC3474C1836AA9C6B4D732118AC515EC2A4DFCACB7929776501EF02415A0638819582F6AA2853DD189CF7900F834671718221933C2962B3FE598BC2EB0245C229B2ECA5B1A1A2F94BC6E278875570BCB92C043493267F7DB06C887BD66E38CDEECBCD0A998FFC094376119E4A961020C8BA05B15FE06062FD4892DC0C023AC6B2806BF863ACD85A120A0701435305A65E91D5D908B0BDBBCCBD518BC9481A5920BB4900468A893589128845BC95294A0DC5918274C4FDE2A0B18467699D637AF4CB62DBA3735E33DFE25AE1493501A590DFD0342506B748EFA5590BB689D18A50B2151C9E9B559B346E8E530A14A1CBE5AA2843431CA32AEDEEC4E9081B50A3BA764B1B0EDCC99B17B3FCB3046E6C2C1B1966F2F481E4E1CBFA4E7546E0A9E6ADB649D59151209942B92B019E8394416C19004CEF1E9235BE0228E6B2CE3603A37966BBF51CA366A3F2D18B931E4B3A827887FB3147331A746E713F60040F3277CEBC2BDB7251E84EBA5012A10CCE965E4A9963151698AF1492CF51372C37AD0D78F817B466A26372F3213873802EE26558C9ACD0F511B3F9138EDCA56FCCB36392ACE11411EB2936CCE03A0F2F347E2332E14E85B8652984D09CCEFEB8963E2A5EF845888576EE1B36EF362274D292F10355163BCBD51A7AD7B284BC4A10C3370A1391003289016F22310FD3C4CFB31CF88A42685103F3813393C1A12915981C11A616FBB8DD6905712F387D279C24B17230D32B018E14902CA1BB0561CCB73A0E2F4C8DAD9969745A1D238250B76FAA9FE97E3E08E3BCBB6E860DC8EC5EF30B92C5648EDF353871C148883FC", + "dk": "BAB28389C4A099F98AC074612F487570115D0A031BEDC16B46D77C7493318891B30B259E7284749676A76B1637CB6CBD842260B4BB9FA1230DE3E151F1E5170A82110BB2B1EB992AF9E2BA98BA4AFCFA3E71765B9346412E10998BC8461232AB5AB24A16F23BC358AFE01A1C7F8A3B05A8AC5EA9591D2689B56466438761A6220D151682BBD0CD23C42B998A1871352C1C2C0AFB1889A47C0B0FA8B2768A5ACF1C4D0B34BD7C16CEF3611851432F361A9176D77ACBA7C88C219CB98819552279819B6BD6C57BB93AC239DAA6A8D53F9D1665F8B866ABDB52FDB1BD818923FFB803C5A8B61CF9B9750A2F03522B4DD5AAC7FC345CF28278F93B1E976A381818AC2275AA16CA44204C6513394439A75D7B1E5970735F016CA6045FA4E68F4A9C31F9C4766C6A56DCA1C83101346B3A1BD796170904398A859734B145933660AE905433B40A8763AA37A868C2E3A33ED709BC9CC1F4411472B31981F6AE08560C68759966B047CA295FAFB60485A28A8181CEF7954C78BC85F395952583CC026C46D9A540E8640B9FD175F4702E5A3A131503C3251097C93332D5113C57082B7CE09A9DD271EFB7ACBB92257C0B5B50EC7BB418B83AC53623AC6B7109C713D0C9C79A750A603B2B2714A109545FB4506A474BBB7AB8556462CA596741E9B0CE3A7FC63A49039450B41675F6E0AF517623C060218C755CD3702FB4A44DB91A80F50CA32F3AC56555B8EA0B26C9E8BAB210889873470873CAD9D7346D8253E2268BCA725E900C22D72318FF686EB9CC80616315AF936F6DC7579748094BDC1301B4A17E826F60A59519B66C2599B52E963054906AA85025F1E26E85CBCC2985ABA727C77A12794D7A67C82B8B41D1110C63C3DB43CD4684001E486E18789B4E207C34D3A207674EF842C2DE7322FB400747B3246387C84F18608DE182BA3C79C2414EB60A7F75040301F32AC543334EC028C0F92914089602D15099C696019A625D357D91E6BC79581F463127A2641060460F526025A0C020352303BEAC1F1BF53E7B258744813308DC69022A37B4D72969586DEFB883A299CF814A98601766CB861F97CC7321764794D1AA928B081593AE3FAC6D3BB71ADD53C52C21B350FB3C6BE59AF019C0384941B8932C673211134C34BE8C8697FA038C90C09730B3ED556118C455B6168C84E3CF5E1AB818C02E4F00002099C78D4120252B9D86B4051A7C446E5509C5839B1023A6F9A9947AFC10AB1764774B9475D941104278AC59C87A18C1F2B17FA0306068F291D0F2CE5F5069B4A3055118C60DDAA96AB0826FD374B4F8B6DDAC28BCF6398FDB9393C718F0BA2775E54F2556CE2C2678241BCD68A00B81B87991ACBA1D9003DB76AA36075A0131023A373C51B065E2EC083F9A3A5CEB22D246711346A357E94E10C199D7A09C87D1188D1C3C0D1134DA650D5E479051B140D4A0B49492C303A40FCE4457C00A023202B81BABB699845EC77244DA184A495196446C96C0D3A0644710225A744E458782D38C63C459BF2A08833755C7066396042479874976C1512BCC046C83786B4424C2D022BDA1925DCA930067AEE3E6454E1C78B1C5A7C603B85D506892852C9D39AC7808CDE5CB71E371378042CA0B5C35414BA7A64294DC42A0463841626A5BC6F37B98D4393BD9B9E5E020B7849EE72188CD1231DF530E36E4CD72580E05359A8D97108CB82E9D1B7CFA94BC92FCC174F3A4767CB1D6FA719E202D8AD68657A81ECBC0861B645D3A781A725A6552ECC12B64CB12A6CB0AE33C64624A8D28B026C482AEBC6A69D95557FC3CFCF4B2FEE502CC7210B42C089AFB636AD573E7430A8A184685465C6B882987255430D2842BA75E892A5AE23A3A636840E6B3CD9F76975EF41C034CBD799412584CC85625208855083BAC67D85B0FE011568ECC7365798AC3EA91C61442EE260BD380C2494680FB411BD16714CBB6468BE41013F724CCA4B4FF364D095422124652D4A53110C05B89B095BDD1C7B8D19689A706E1DC656E6C1A3FC767A1D44EBD67C5B370A0F5925DC551551AB6B604A27F56A19003731DC071B2E98C86F7BA9872DA783DC68E1B19ADED603CE7F3BCF806A7774A044D9C51B26C9DDB8B809C0CC5F8D0682C7C8A56A9C89F412DB5BC4ED438AA89574B8A77206396807FC431F9A2B29EBAA37C34B6F0C92BC7E98A0C56689C989E33E9126DAA3D94C95C6D60639DDCC008E4220F8C6348E44738C1AC50521A926B9BCD42511A33C1A704871C11A962E062B9625169A842F8D15CF3F3A0A2411017860C88A22D01262666F6895390AF652204ED9CB0F7589A63C23ECA851C25B527D242AC8D310B3199AF5EF7C54472739E17A6986ACAEE76B0B262C5BFB051343580E60150250865397B4C498B465B6C62E1C3A4B89B756871313AC1C4034509803C59103AA4B9A50CFC7C7EE0A34EAA417009538570C197D04C60CFB41578E274AF9ABED10B4BB7B71A4B925DDCF5432940934B222A36BC80E96C1094E5C264364660012514444ADE22A6121C30C4F037FAD29C2819350700A10C9861FEA471BD05C3D31A2EEA2A9CEFABCCF0B4AB9C33C19FF126B017370073561857084A83ABFA5B3550C2A93B785A4223AC57F4B6FCA0B4D12422B509CA45B63775FBCA4E785972E775E2989D844A4308B786F230CE990010541868C2C21B3D311E6AB14C4D417B37D10DEEBBA6309686896017F08C224DC806AE87658A0B00ECABC2A9F66029873C6C3446914C5A967441BB4AC6900575FA52238636707C69097E19C30ED66A9F28762056585C5738A6F51ADE3603B963476213B78EF65AB6CA7F612134E82A6BECF48D4DB4AD7958787A377483F0A8BAA76B06243DA4F61CF803807C17837A6293D144637BD3A92039282DA86485B005767519C9C0A0B513CA5325866DB3AA67638A2C0117FC80C4845ABADCA92C529C539431363A9A58E6A25CE6A42AB8E5CAD3865AC1B69E77B2B48DD5CFEDABAC79257D15269D72B1CE90265556DA687D894D15F11B1268692E22AD8313877FA8629F3BA224F8C5A98AA31FA58FDD05101C3705496516970B200F984B67EB497DB9AACBD6922EC84C73DB42EC0BA4D1D11859DC356765C82947B4953ACFAECB5969D34A4A8A44BA53346023517C2474A301AE7177A0253904186A5527772CD7845A4129A90B292051765772C09EF585A5BBC976F1F9B24C7AA4478B04B47398491785D9B9B9376B89D6C90320831117949A72406BE6076B4268A356E615A2168C9EEA37B2165B143304B9C51B3CC97AE3A6B0DDB185825C8B7AB073B5086B7D215D4C953F7BC9863339A045DBA784F5489FA51096234DD08B7C457B1C326B8F73672881562310E90B43FA7A37B7550696422A1B32A2615D4E8C5B3C3C61C4479A15D94F210A165311BB4C95060FB8287BC526C212B1EE0470C5497480DA396B2C39B9BB413E267583C249911029DF9B7822327764C16FA67307EFA499F0A7CADCE8B1732C91D284B505D59A444B41ED738C09A40F335C7F7050B80DAC9E5609C000473E440840D1799A86705276761E8CAC3474C1836AA9C6B4D732118AC515EC2A4DFCACB7929776501EF02415A0638819582F6AA2853DD189CF7900F834671718221933C2962B3FE598BC2EB0245C229B2ECA5B1A1A2F94BC6E278875570BCB92C043493267F7DB06C887BD66E38CDEECBCD0A998FFC094376119E4A961020C8BA05B15FE06062FD4892DC0C023AC6B2806BF863ACD85A120A0701435305A65E91D5D908B0BDBBCCBD518BC9481A5920BB4900468A893589128845BC95294A0DC5918274C4FDE2A0B18467699D637AF4CB62DBA3735E33DFE25AE1493501A590DFD0342506B748EFA5590BB689D18A50B2151C9E9B559B346E8E530A14A1CBE5AA2843431CA32AEDEEC4E9081B50A3BA764B1B0EDCC99B17B3FCB3046E6C2C1B1966F2F481E4E1CBFA4E7546E0A9E6ADB649D59151209942B92B019E8394416C19004CEF1E9235BE0228E6B2CE3603A37966BBF51CA366A3F2D18B931E4B3A827887FB3147331A746E713F60040F3277CEBC2BDB7251E84EBA5012A10CCE965E4A9963151698AF1492CF51372C37AD0D78F817B466A26372F3213873802EE26558C9ACD0F511B3F9138EDCA56FCCB36392ACE11411EB2936CCE03A0F2F347E2332E14E85B8652984D09CCEFEB8963E2A5EF845888576EE1B36EF362274D292F10355163BCBD51A7AD7B284BC4A10C3370A1391003289016F22310FD3C4CFB31CF88A42685103F3813393C1A12915981C11A616FBB8DD6905712F387D279C24B17230D32B018E14902CA1BB0561CCB73A0E2F4C8DAD9969745A1D238250B76FAA9FE97E3E08E3BCBB6E860DC8EC5EF30B92C5648EDF353871C148883FCED356581C66D62FCFDA63A9ED071F7E5EE0A9AC9DBF48E4653DB78A6BBFFF1919399B9CE712E51B00A12EBA403E181CDA45AC150688E2D09614014661B339E6F", + "c": "E9FFEAEAA83250A944F247022FA3F6572C8496C0AFF81462BFDDE2FF310DBA5E6820FE52E33C2CE7BF0C8DEE97175E20000B3577BF84DFD69BF45DAD481E94AAF25BEB959CEAD9DC539492202E85AFB680165C8A1C2BA42490CEE563E4EF4B821EF34B0EE08C0ED8452235F99E123B650985D9B1477D21F936BD937CAF67343FAEE1EB684EB4E0EF202F5A58445DA5F6D5D8AE7071BD531C0D736C2570F5FD593FAE9BCA5EF988B6BE44A323DCE5883806DFB7678704004B228FCADE75EDC4CDB7F4F87B0C315FC9A40B4AE1E6944C96CAE75481907804BF308780F411FE068CF09BF99AE3FEC2F656C9CA02158694E5B22F044FCAB131B7D942BE6ACA98128CEC79DAD0AAB4BD566A2F041AA043520B9D8642C9B744D4155F926DFE87AA8A031BA5E54090A93EA5091D9938C6C3CD31F83D2BD46661FF339E66513E284DF7FFD64A047F741DC81F46A6A7F03A9025D554F93D889A5F8DDD75B3C0F31DD64CD4218050AB496C5D01E632D35981237F248D7B31C6F39678D4FED7DABB29C242699F2F588D2FC56972B6EE7A94C1FF01584F56B86BC3C1B58DA0B9616B9C5E316D7FD7AA9C22D51F0BF69A080E595D794B5F0924A4448CEDD0E03B414B91D03FB511AEAFDD5CBD4FDEA6CBC0C62849B2CA7A6023251CEB720E52407D03C9412F0C87ECD974EFE304C7791CDE5911F7731EBCBE969F039C6C3FAD7138CAECCE0D3FBB5F47FAF77B80531D53CFE23E1E04921864F5346EC3EAA4B663512DB4344A5579BC4CF32C8FF33C5F32CF44238608C19EF4074CFF9ECE4265084C4515E919E2118FE535480CA816E4AD6632BBA726D9B43DA4DFDD2DD1E0E85D001BD9FBD52BD9A6A8548A41251F939A63E683CC5A076FF3F0A2C33B223AF28997CCB36D3577FD09BF46F5988C0042C666929B877132B0D5375210D20C7F3816FA1AB81F3699091874E0CADBC1550BD6DFE24335EDDA44FFC421C9D89D9E250562408BEFF06D01719CA54FE91727CCBD08FB4B45BEF75B08F560B0FB9618103FBC216A3D5AE72A869BD40E51170E88DDBB713F8A0531DCC2645CB185F2F31BEEA7086B5AA84F5248B2014F9D85E56B330F119F88E26EEDF055A5DFD87582E91D3FF59FAF9AF3032D60424DF0DFEEC98F2BCD2702A10551E7DA73628D4F6E9065049B172AB861EE64176E21FC7DFEA1208A632C78D72DD2409798DE854C3EB67A985A4C04CFF154A69D8443F6AD9EDBAA666CD29260D203739F3B77891DAE26F03DD469CE4C55377B5F3AB9DA1A42F7F8F8AA944E7A921A53F7ADB99533F48D4E9922982FA0B149ABFD95095CCFBF3CD719F59535349E66653FFAC1D0DB3857688DA952426D6AFEF5EDFAA7732133FD9CD86831BE5A7809E209B5E1214FCEFD775D3627511340F53976B571BA909BF5234DF037C8D1E4A11BBBC8DBBABCD39AC47CA6CBBF38C7326CC253FC59163FA313CB86DDADC05AA6CEF529AC23FA315734922885BAD9E5CCFEE38CD20AD2A245590CAA674AE6195F4938A95F46E59CE060E7D7960362A7C19F19DCE8424E8E7FF5B084BC093FCCA9BBE9228B089497D51BE411AB06CC60301A510799539287BAD4E2FE023B6B29386349794AF3F8165AB8F6F4BDFFF114B817B10F4598355E7AEAA31CA73F8F06FFB478483EFFA2C11C94C10E8053E95E041ABF346498F1A2765B460DAA89EAF3EAFE952E35B10630D78FF742977F2F5FCB63712901FD9181A1C97E0918DF81FEBD517E6820D70A509C15C144CDF6D1EC37FDC7CF2353A3CA7136071DF8777E45D5D8B5146C058666926096F51025881DACFE2392F82019580BF82E998CFA5AE06A9EDE3FEA2B4C6C1FA0D02822CFAF4F2452AE695AF70264D5D7935FC19F2917090FAAE36790032CB85A5E875C05D0483B2D4021892E825A2D0977724DD1E73BBC8C430A0F6F4574AE112575F87AE30BFE94EE8260B5141A9E414739B518C11378A7C574962F0DFEF8E2DA1C1FB8B4E502D182E14F64A91FC55A80D65183B7B592FF077D3504B9AB88F6CC5F4356488DE0DED68A1C469AD9556E2B467187EB2B0B466DB99DE24BFEF3D9944B244C022F6977C0CA987BA8D0D10944CAF8AE6B89C226EE50E338F653A641EC39DB3AA834E25576B0A5853A7BA26E59D65031DC780E8588EB936D182D988BB77B4C9276A737E44CA1A27804687E137A84A872EE1970448BFBC7C42007E4518FAFDB544F9A", + "k": "7BCDBA65823F7A36497091555C7E558D933E707016AA485708FADD30EFB8D8D5", + "m": "B974689F6F36C7AB262C8B97D5469ACD3BCAA3A3454F611FF0B304FE1DF6C66E", + "reason": "no modification" + }, + { + "tcId": 75, + "deferred": false, + "ek": "A6902B0559182B341E3A6ABE0B646DCC84B39881948CA396CA782A65D6221589333E98A88A9C320D83A10422948B64A0DA1C4ED165B0144B22190656F1DAAE36A5641A4863A3985AE9D08456629C153A596289C01BD2912FC3603EF7ADD1EBAE1A745675F316ED0A6D4CB5C5A431C2871B939B5648D1018911D752BF08B40CC571D863B33C9043E3B2C73C67CB9A4C8087F28D7D37B9B66B638CC66796C146135C2A743AB94FC693473089E6D32492842D8D114C9A92C6721818CD0530C91A09FD7C3A124B7E98DB056C77049008A112AB61D03A8C38738B96F64D4E530E5345958EA38F19517B7293B6D2DA11BAD668988820CE8479C3B5A832C708FE09481CAA7ABDAC2E8658544067810AA31D88A52F66459B3E0A5AA8EBCBA1B5C9B8776FAAF59CFCAC69A1CC8EF166615998AE88968FABC67D67C7675B94CEF447667FF53D2B3890943303BC88C5B3DB08BA75187B6CBC97503E9A563745824A533C59A71B66D5CC21972B843BE0C0768970571796AB992B39F43F2CD8017B5517A91235474A821C541B526B0404212C194238B18AA5B8A175E4A59417D119EF8A385B7458980335842BB318214E55794C635692736B6708863A066462EEF41ED66771EAC578E029642954111C0B20F9BA3B8646456DA39873B89F6449324CBAB5ED017CC1C72E1ED4322D55B2030A8E0B390E54384449096A2DE676BEA01F03A458160341B7C743719B89A158120B790AE8E1AB4468467C4507F7CB659EB8C16A77315E553AB287836C4472EA1075C7A1C84DB4CABDD5CEB2CB5638D75FE3567659443B38B2B21C422DF97A14A8A633C2279DDB056302AB0FA83905C846AB57D2120EA1CC92195320B5B873B406CB44B73FB02160200460431581979967FC16233333A8EB7D48A120F451B3FAE9BAF6318E384B6D42B36D5B38188D849652935494C4BBBDFA22A562A27BFAB60B3455E775912D27698AA30F76CC291107629E3627EB443D0F00AA3F220877010876B485F57495C9E80DC4F3AFD6118E1849ABA06919968163CC9CB358DA03B3550198A2C43F476954F1557058C05EF828D8EB982340C9BC6A5AC1A27977402B2242A40D89072C1270DD8772008A505D4604831C1924B97C980B01788107472800EFD807FAFA1ED3466548D698CAB76B820667D630C7D03447820BB8815BBCB8DCC11752788782CA3BFC51DB9BA0D16198132A0ACDA7BD7A6531A8AAB9C8AC2770030C512740CE62CB60F79F8087CC9177B56E6A4B8155B854993E2BCB78AA849E72398590B24E87A31097AA54ACA80A9CEB29BBC5B24CBB7DA084B76B5C522F73185A05A8024629F8A6AE304CC7FE88258C94A396912A16B491DD0843D8A82BBA86843F458E91261588D7AFE89A1D7EA9786DD13C4111CF89EAB9118A7EA39A72408C8F1EA2C77765C12881192A33C552D61A76424783E5C48C881E9A541B8F6157EC138AD5E93AA925194FA37644F397A98C60DBE786983C8B2CB6C76C73CCD0371CF0CA85998C65D1F76DD5E545991A00567A48EE69A537921379923D7676401A06A81D68BD9FC4C2A28B4B72C966576BC6DA870BE8C415F94174F8137B3EE4793786652EAC97D6C91DBA4749CE4B69DB82209B24C5FAA0C4A0CAA71A39BA51E7A6F19381219900E6F8AF06F0B224326EFC2C8560A95AF8296D2B87353360A5AD3B6DCDD95377B0B201EA7A6E475D5D563A373554E83982A35503E1C179324276F6147B698C32AD24AAEFE0B2B1FA911444808C6A25CBA21B4BB008F49C0CA8D209E2BA02E3B164DA41793C212F9C5B2E0EB00CE7146284C0B26FF940268318EB330C6F0100ADD43FBF0615D2EBC27B0819CDEB6A327C590DC83D678AA4BA910E509B4EBCDCBF3B74CA581A2B55F46154D17F9AEB3A09D5C30356A75AA2859BC11DFE866E3C463C96826613880470A1CE8276B033C1810BD645B5278C25F81B678228F4D20FA3726C5715311DA4BE1F1C0752DB6D16D889D27313C4046E05FC161E889DFDE2255F434C8008AB12167F3B6A15D74B4791B293C902CCC6F4C98A75344864C35E6B189C8C116735C7636A6F0AF653DB17CBE0E3CA7C677CF9604CFADA8031611321DBC90308BCF7F93AFE1B02B0C9826A4139C4B2097CD061BCCCC5B3C562BB13A30CDBB318CB9457C1B9A69236B820AC0717EB65554D8CBB46EC883E0392B79C92DB8D07FCD393633C020FE2C469A32D", + "dk": "8CCAC9928C0FBEDB3AD6A04E1853BF4689B035E0C8EE7C26BA2140CE1CC8476960CE51732FA0310D636D06D802B164B826F376395AA0D371C9D56275D6AC5878D13655083769E14974B22FF9B02C5D1370332A47626702E5E2044E05B597F94FBC429E50E65B437223F32662A1C37081C3B7A884B37DECCA999C1EC3997F38696A48880589805E965ABDE6558722F5481666120D4C6B12447593399CFBE881BFA754B57350CB060A80CC7F95C65CC6905F6E701E1DB03A38CAB8ABE9412A990DE094C99A514C68969940B5A82776B6EDEC32F7DB9A5D7417F4012DB6F36AD8D8967F2B144488483779AAF36188A7F27B9FB8A9222A02411B110137BDFB835040E220E19A8B2F8A25453286561240C9E02A36591B6829BE48177E086599DFA003D951CBDB4B24313CB8D5FABF9ED54140FBA91E3921BA9184FAFB5136D64F22A2B59B27116DE13893AB6FAED8A1346742F838641DB76912D30D2481657194CE3E709E9AC272DE638C21580CAE015CB04A89E587CCEB0B05A972407F9C96F8474A859344EE0C31A2D30AFA74948FE2B6A4C26C3CD2C9C0D7400B802AA36487F6C216989A5F806536853B9FAEA2C2A91C039CD07A4E435A58D80DAD50A991150B1A1B0042818A38F6929E325B6D29C70BEA1877D73403DB08B856C10C2851D0E30EC6BAAA9DA6974851CFB31211EA282B8ADBC7425274D1BCAA806652344BB663D7297304192E06AA53A438A2D147DB58A1901786FA9924216923B01C1FAD85C0B79332E9DB420A94964CE9BC2CC19276615B7FA3A489DBCBFCD07412F186ED412CC866270AA53A5E645ECDE278ACA36BF5381DE2DC57C9B812BA13863E55BCA68C76E1F496F216663E877AAF2C1959397AB9B1BC21B1A1D9AB5091484780F58A399C058D17AC7653A288D27E18D43B4506C69C477640069446A5B00F9ACD93200E21B40905A09035886B11647F1182BC6F824CF7A5B1D1951FD9049690450EB559677E888BAB0924DEF1741E22B610894109CCB549E4A5EE0A5F4C761E6A293F61EB2C5739B659E4B5086A0C1B4A0382B27980B07C1D2035F1DB53BB82787AC249B2011F3590CD9FE5515F813C65953AE46CCCB7C3210E24AF82B16DB5916A6B23393844636C278641C48CEE2276760518C919AF3E16C3C9714D1544CED4D2A64DF482CB4794B8A77BC5E6CA2718513E6213F620BFC8063A667CCCCBC99C7CC1328A5CAA31DB820A4088CD825313D677C49419B2692E00813E33A0B62604CEB47A547FB2A92B63CAFEAC4B63A41FB1805CCACACDC62C373EE63C49F09899929ED85C89D884287ACABDBF717F3C49A511DA53DB43AF1AF30CAA7B09E0D760B66C805382C427C3BB77F24381D71F691CCA9DA8AB1FA56695E2CAC9B543B1F5C3BE2749A804928BC005F0908576FC87CDB88AFFC4869105A1B5C6364A64083793A4900434AD7B9A0196BAFBB3B54B7A0D23FB8440A65170296008BA3A94A94AC5AB36F11507F6B7443A928F592589ACA7C6AA5BA6932840124A7DD65A20F72A5D8CB356846A1D670CAA2BC06A4D64C4001154CDAACCC7F21CE0C1C877B2556833165890056D929510D4252A065EDFE2152FEA9876210DB26B7619F220BF5C4DE7D05AF2530E47FB43C6BA7D385482998994024C04D576AAA4AC2B1A951A01596A0EE36F6D8B0BFE0A5800EB2ADD9758DCCB368B701EA6D4B9605A11E7369E44F67DD499896CE297CEF763CFE99C14D41E11913337714C6C79084DE7C37AD76C7A838D6C40B485034C6F55345EF729C0930397166AE317AE5FE85F4DB999B3842387C245EAB7500A51260097CF87D77C56B86009F15CA8B60B624011086C229CB73C6A90A81296B4216145FDF76528DB8AEC671E7062AE1105214F01770BF98477F9098482AEA044B92B6AAB0C70480759108B4AABDCA580A1C640F32826B7CB4734D2743DB5090E8B97C1AC46E3F755AD8BCA6D9A93B414B7CDB15E81D9017CB1291FD263585A02E2EA555EE176E8D29AFAB58AF189C5480199409CBE7D871E42EAA4702C7647D023FCA094232ACEC3B994B1B93930CB9631E34C3BC6BD71116FBC751C872A5F7435376E05941D9BA80BB520EB9A6ADA4174B671B682472F3EE9AA57579265190D618575E2B996C3A1A5AC868B96339BB0024BC4385C96D1B5146871A6902B0559182B341E3A6ABE0B646DCC84B39881948CA396CA782A65D6221589333E98A88A9C320D83A10422948B64A0DA1C4ED165B0144B22190656F1DAAE36A5641A4863A3985AE9D08456629C153A596289C01BD2912FC3603EF7ADD1EBAE1A745675F316ED0A6D4CB5C5A431C2871B939B5648D1018911D752BF08B40CC571D863B33C9043E3B2C73C67CB9A4C8087F28D7D37B9B66B638CC66796C146135C2A743AB94FC693473089E6D32492842D8D114C9A92C6721818CD0530C91A09FD7C3A124B7E98DB056C77049008A112AB61D03A8C38738B96F64D4E530E5345958EA38F19517B7293B6D2DA11BAD668988820CE8479C3B5A832C708FE09481CAA7ABDAC2E8658544067810AA31D88A52F66459B3E0A5AA8EBCBA1B5C9B8776FAAF59CFCAC69A1CC8EF166615998AE88968FABC67D67C7675B94CEF447667FF53D2B3890943303BC88C5B3DB08BA75187B6CBC97503E9A563745824A533C59A71B66D5CC21972B843BE0C0768970571796AB992B39F43F2CD8017B5517A91235474A821C541B526B0404212C194238B18AA5B8A175E4A59417D119EF8A385B7458980335842BB318214E55794C635692736B6708863A066462EEF41ED66771EAC578E029642954111C0B20F9BA3B8646456DA39873B89F6449324CBAB5ED017CC1C72E1ED4322D55B2030A8E0B390E54384449096A2DE676BEA01F03A458160341B7C743719B89A158120B790AE8E1AB4468467C4507F7CB659EB8C16A77315E553AB287836C4472EA1075C7A1C84DB4CABDD5CEB2CB5638D75FE3567659443B38B2B21C422DF97A14A8A633C2279DDB056302AB0FA83905C846AB57D2120EA1CC92195320B5B873B406CB44B73FB02160200460431581979967FC16233333A8EB7D48A120F451B3FAE9BAF6318E384B6D42B36D5B38188D849652935494C4BBBDFA22A562A27BFAB60B3455E775912D27698AA30F76CC291107629E3627EB443D0F00AA3F220877010876B485F57495C9E80DC4F3AFD6118E1849ABA06919968163CC9CB358DA03B3550198A2C43F476954F1557058C05EF828D8EB982340C9BC6A5AC1A27977402B2242A40D89072C1270DD8772008A505D4604831C1924B97C980B01788107472800EFD807FAFA1ED3466548D698CAB76B820667D630C7D03447820BB8815BBCB8DCC11752788782CA3BFC51DB9BA0D16198132A0ACDA7BD7A6531A8AAB9C8AC2770030C512740CE62CB60F79F8087CC9177B56E6A4B8155B854993E2BCB78AA849E72398590B24E87A31097AA54ACA80A9CEB29BBC5B24CBB7DA084B76B5C522F73185A05A8024629F8A6AE304CC7FE88258C94A396912A16B491DD0843D8A82BBA86843F458E91261588D7AFE89A1D7EA9786DD13C4111CF89EAB9118A7EA39A72408C8F1EA2C77765C12881192A33C552D61A76424783E5C48C881E9A541B8F6157EC138AD5E93AA925194FA37644F397A98C60DBE786983C8B2CB6C76C73CCD0371CF0CA85998C65D1F76DD5E545991A00567A48EE69A537921379923D7676401A06A81D68BD9FC4C2A28B4B72C966576BC6DA870BE8C415F94174F8137B3EE4793786652EAC97D6C91DBA4749CE4B69DB82209B24C5FAA0C4A0CAA71A39BA51E7A6F19381219900E6F8AF06F0B224326EFC2C8560A95AF8296D2B87353360A5AD3B6DCDD95377B0B201EA7A6E475D5D563A373554E83982A35503E1C179324276F6147B698C32AD24AAEFE0B2B1FA911444808C6A25CBA21B4BB008F49C0CA8D209E2BA02E3B164DA41793C212F9C5B2E0EB00CE7146284C0B26FF940268318EB330C6F0100ADD43FBF0615D2EBC27B0819CDEB6A327C590DC83D678AA4BA910E509B4EBCDCBF3B74CA581A2B55F46154D17F9AEB3A09D5C30356A75AA2859BC11DFE866E3C463C96826613880470A1CE8276B033C1810BD645B5278C25F81B678228F4D20FA3726C5715311DA4BE1F1C0752DB6D16D889D27313C4046E05FC161E889DFDE2255F434C8008AB12167F3B6A15D74B4791B293C902CCC6F4C98A75344864C35E6B189C8C116735C7636A6F0AF653DB17CBE0E3CA7C677CF9604CFADA8031611321DBC90308BCF7F93AFE1B02B0C9826A4139C4B2097CD061BCCCC5B3C562BB13A30CDBB318CB9457C1B9A69236B820AC0717EB65554D8CBB46EC883E0392B79C92DB8D07FCD393633C020FE2C469A32DF3F0316106B102E875DF4653219F35BEEBE7CFD5F0C59D1CF68055C61539BAD1231FA46366271E63D3B696A0FD4569870859EFF47CB57C3C6A65B22253A739FB", + "c": "3E07145AEE491606A4DFBBF9C7301FB8F21A6F46F8F87253346A5981C7D83EE23CB6BDC508AB0756A8E2D8713A03275A551C0B291DECBF6C0A3F976758ACA963B590FEE44E8D1056AA95AB5D1B77A0016E3AA605EB564337BE2FB33E54054A08C7A3174E8E7FC0F079B1BE8C30BC0FA7C03972DE8294F9F24251F834711C0BD340C9EE20BFC74CF99E8C0CC8AEFBB057B0F7E3CD0AE6E0C47EF67F22C13C2B16179942D8AC24FF81D99CD9C5ECC5065C0BB0C4A9B36FEAB42B2F06A6A0F9AC2FF4AC50864C6D03CD97F785B7B3C521392E246DD0D5FA5218EE1AC30A223194E5A21267D1DBBF4DDF1018858D69EBB382907597BED3D90936B5C039DA96E5BDDDB8A5645EB1BE21C1504221067B293B4C6C81EB983CD49B5A1DAAF7DB602E990DEBF76613C6111B3FDD2ACA243C3B92D4E6988BD43082F6339A89898FA0CC05C1859DF99EE74F3748DA53BA99561A5F5C1EB1544A314343FB9167EE9E822814A6CE530836239DB515A8582CD9ED338B2A4765A7C265F0825B1DFC6E6CDD41E137C5FDEBCDA6878433EE1BAFFD7F64020D9606E397A12AF66253E19EE2CF4115C173EE73535DE0DD5A7EB7E2EBD769362982F9B09AA5D6548AE9163D0ECBF4929A950853069AECB829AF4F91A517C8E8D2DE761CC9F5729931E4396D261DDC3C66350B20FA1B37ED3BAF2092F7BE7C85DC1D73ED66A5C7ECA6D6ABA46E09B03102D0325E712699DEB28426AA5309D8892BC767BF099EFEE2481A589CE304427D9FB13A65913FBB37C039C9390C9E9BA3988A81C98CC60014117CEDBB09234FEE8529B9C3CDA11292EBF1678BB9B2A76C5CBB43AD1F947A984348DD8983509D7A3D3B3A560D6337CBE40D32F554C24E10BB720150D4440B630492CDF711193498E4CFCF3F8983BEC12DDC14EA3084C63A418050FE55085E279F94109B4AC6CE02E91D5CDFA62E9EDF05947A40F4BDF8C4A5FB712F86772DC1D9393482D45692463E3697A925BB7CB49F7B9E030199F4955EFF2C829C128DBDCFCB68A3CC57FA5DB71D90ABE690B97FD9387BB517352045F509A9C7A2F01EEDACB35E5E660ACF9ECDEA3F4201DA07BFB8AFBEE7AE32A77779D68A77EB23DF57FAB5E1C7B21E7515709F0BD475361311B831D336461ECBDA68646B8D036779AD9DE23EFDC399C4C90ACFCEC65B877C75A6C5782DFF158B618C0E4B43FC0EBAA641550A44721F35C09864508A3FD0718C2D6C0F235E454D30D969882DBADE20BAE506244B0D99EC1F9664A624A9F46B99B573210A4959CA9B3B897B40FDD92346953BB526893EE06C96C39EBAFDCAC9BC45759299754812CA556E5E5525477F88D207187B1916251B703CAE95B1CCC3585F7431B23969D20646BD1E61066BEA322F16CF8E58DEC2A5CFED648DD98826DEFD121C30302979B215FA0FFD233E61CACF09CD929605EAFA9D2083ACD78CA7C97227B379B0359832B5E1EFDD2CD72562DEC3B8D23B39003539E4E9B8F3C6A74398F18A3DF3F05067F95410F274B3DC0A3A8680CA8C53C746BB4208BA23B5752FB24121B8088AE702C8CE10CBAC6E733108072B29FBA6261491EF0F06161592C19846F18B9341B85D6A5DF4863F7F9F00EC4F8A669085F03F6461B3DC0271D38198FCD546AA1A8DAA4925E9172633816686FC07A855C92AB7D9B4E692D5BA6F51B0B9928EA778DE8A167123B0A80C8AB0B8CAABC5FDD12736A9089D8F60CFDC9D5A8231EB64EE8CEAD2B1FF610BE325DB34520495792E8B9D5403B0C2451671ECF9871BD5FCECDAE8CAD4E9E19815A60CBDA867CB0F5CD1A8A2366B5129B4A5799609909D43968BC296DF77592E8FF5F3ED02248279B761A4397F6930D30D47C31B657F8D1A13C99210CB3E17E84D414FAE4DC6E9E182106D353256A7271D0A5D23050FF33CDC1C48A64BCDD6069F71522BA1D33D9F13470EC1D0D348EAAFADD2DA2EF5D1CA6B05699EC818B6FBD719F8D42FC0F1172574F71C468204034E24A68DD7F92E341852984CF349CA5059E69B19E88CD4929EA8220D04CB4F06BC9A59F0F0528C83D59D4DC36B17EFE9F0B83FC581CECFCD981F419A987D2380AAEAAD7684EE7EF2B920DEF9C0801781B5B34C7E6FABE8EBB4B531A476D970248F2E0D0F17B38C5E2C46B45779383180620C5440C2FBD59033877B84CB411970862FD2C47CA91757B33243CD74EC15E5A622F44940F65E3F42372F8B", + "k": "06B511E4AFDB9427A2296FD9BD7C6467DE6A25D78866F770C2F41462D299038E", + "m": "7B93EBA796CAD98FDBCEAF0B8F3BFF196C1F89125B2AA88F623A91DC6AEE3771", + "reason": "no modification" + } + ] + }, + { + "tgId": 4, + "testType": "VAL", + "parameterSet": "ML-KEM-512", + "function": "decapsulation", + "ek": "5AC81984D4A5A83619735A842BD172C0D1B39F43588AF170458BA9EE7492EAAA94EA53A4D38498ECBB98A5F407E7C97B4E166E397192C216033014B878E938075C6C1F10A0065ABC3163722F1A2EFFEC8D6E3A0C4F7174FC16B79FB5186A75168F81A56AA48A20A04BDDF182C6E179C3F69061555EF7396DD0B7499601A6EB3A96A9A22D04F1168DB56355B07600A20370637B645976BBD97B6D6288A0D3036360472E3AC71D566DB8FBB1B1D76CB755CD0D68BDBFC048EBA2525EEA9DD5B144FB3B60FBC34239320CBC069B35AB16B8756536FB33E8A6AF1DD42C79F48AD120AE4B159D3D8C319060CCE569C3F6035365585D34413795A6A18EC5136AB13C90E3AF14C0B8A464C86B9073222B56B3F7328AEA798155325911250EF016D72802E3878AA50540CC983956971D6EFA352C02554DC760A5A91358EA56370884FD5B3F85B70E83E4697DEB1705169E9C60A74528CF15281CB1B1C457D467B5F93A60373D10E0CF6A837AA3C9596A72BEC29B2D7E58653D533061D381D51759752217EB46CAC7807C4AD38B611644ACF0A3F26B6B084AB47A83BF0D696F8A4768FC35BCA6BC7903B2A237C27749F5510C863869E6AE56BB2AFE4771C9221874F50F5B14BAAD5993B49238FD0A0C9F79B7B4584E41301F7A885C9F91819BEA00D512581730539FB37E59E86A6D19CA25F0A811C9B428BA8614AA4F94807BC031CBCC183F3BF07FE2C1A6EBA80D5A706EE0DAB27E231458025D84A7A9B0230501116C290A6BB50626D97B939850942828390B0A2001B7853AD1AE9B011B2DB36CAEEA73A2328E3C56485B491C299115A017C907AB54317260A593A0D7BA6D06615D6E2CA84B860EFF3CCB597211BFE36BDEF8069AFA36C5A73392722650E4957DCA597ACBA5605B63C163CFA94B64DDD62301A4332083361972589DB0599A694DD4547A5EE9196577C22ED427AC89BB8BA3753EB76C41F2C1129C8A77D6805FA719B1B6CA11B740A78A3D41B5330526AB87D58D5925315A1485EDC647C1604EB38138DE637AD2C6CA5BE44E1008B2C0867B229CCC36619E2758C4C2029EAEB26E7A803FCA305A59CD585E117D698ECE011CC3FCE54D2E114545A21AC5BE6771AB8F1312", + "dk": "69F9CBFD1237BA161CF6E6C18F488FC6E39AB4A5C9E6C22EA4E3AD8F267A9C442010D32E61F83E6BFA5C58706145376DBB849528F68007C822B33A95B84904DCD2708D0340C8B808BCD3AAD0E48B85849583A1B4E5945DD9514A7F6461E057B7ECF61957E97CF62815F9C32294B326E1A1C4E360B9498BA80F8CA91532B171D0AEFC4849FA53BC617932E208A677C6044A6600B8D8B83F26A747B18CFB78BEAFC551AD52B7CA6CB88F3B5D9CE2AF6C67956C478CEF491F59E0191B3BBE929B94B666C176138B00F49724341EE2E164B94C053C185A51F93E00F36861613A7FD72FEBD23A8B96A260234239C9628F995DC13807B43A69468167CB1A8F9DD07EE3B33238F63096EBC49D5051C4B65963D74A4766C226F0B94F1862C2124C8C749748C0BC4DC14CB34906B81C5524FB8100798542DC6CC2AA0A708575EABCC11F96A9E61C017A96A7CE93C42091737113AE783C0AE8755E594111EDFABFD86C3212C612A7B62AFD3C7A5C78B2F07344B789C2B2DBB5F4448BE97BBA4233C0039C0FE84300F9B03AC99497E6D46B6E95308FF84790F612CF186EC16811E80C179316A63B25703F60B842B61907E62894E736647B3C09DA6FEC5932782B36E0635085A3949E694D7E17CBA3D9064330438C071B5836A770C55F6213CC1425845DE5A334D75D3E5058C7809FDA4BCD78191DA9797325E6236C2650FC604EE43A83CEB34980084403A33259857907799A9D2A713A633B5C904727F61E42520991D655705CB6BC1B74AF60713EF8712F14086869BE8EB297D228B325A0609FD615EAB7081540A61A82ABF43B7DF98A595BE11F416B41E1EB75BB57977C25C64E97437D88CA5FDA6159D668F6BAB8157555B5D54C0F47CBCD16843B1A0A0F0210EE310313967F3D516499018FDF3114772470A1889CC06CB6B6690AC31ABCFAF4BC707684545B000B580CCBFCBCE9FA70AAEA0BBD9110992A7C6C06CB368527FD229090757E6FE75705FA592A7608F050C6F88703CC28CB000C1D7E77B897B72C62BCC7AEA21A57729483D2211832BED612430C983103C69E8C072C0EA7898F2283BEC48C5AC81984D4A5A83619735A842BD172C0D1B39F43588AF170458BA9EE7492EAAA94EA53A4D38498ECBB98A5F407E7C97B4E166E397192C216033014B878E938075C6C1F10A0065ABC3163722F1A2EFFEC8D6E3A0C4F7174FC16B79FB5186A75168F81A56AA48A20A04BDDF182C6E179C3F69061555EF7396DD0B7499601A6EB3A96A9A22D04F1168DB56355B07600A20370637B645976BBD97B6D6288A0D3036360472E3AC71D566DB8FBB1B1D76CB755CD0D68BDBFC048EBA2525EEA9DD5B144FB3B60FBC34239320CBC069B35AB16B8756536FB33E8A6AF1DD42C79F48AD120AE4B159D3D8C319060CCE569C3F6035365585D34413795A6A18EC5136AB13C90E3AF14C0B8A464C86B9073222B56B3F7328AEA798155325911250EF016D72802E3878AA50540CC983956971D6EFA352C02554DC760A5A91358EA56370884FD5B3F85B70E83E4697DEB1705169E9C60A74528CF15281CB1B1C457D467B5F93A60373D10E0CF6A837AA3C9596A72BEC29B2D7E58653D533061D381D51759752217EB46CAC7807C4AD38B611644ACF0A3F26B6B084AB47A83BF0D696F8A4768FC35BCA6BC7903B2A237C27749F5510C863869E6AE56BB2AFE4771C9221874F50F5B14BAAD5993B49238FD0A0C9F79B7B4584E41301F7A885C9F91819BEA00D512581730539FB37E59E86A6D19CA25F0A811C9B428BA8614AA4F94807BC031CBCC183F3BF07FE2C1A6EBA80D5A706EE0DAB27E231458025D84A7A9B0230501116C290A6BB50626D97B939850942828390B0A2001B7853AD1AE9B011B2DB36CAEEA73A2328E3C56485B491C299115A017C907AB54317260A593A0D7BA6D06615D6E2CA84B860EFF3CCB597211BFE36BDEF8069AFA36C5A73392722650E4957DCA597ACBA5605B63C163CFA94B64DDD62301A4332083361972589DB0599A694DD4547A5EE9196577C22ED427AC89BB8BA3753EB76C41F2C1129C8A77D6805FA719B1B6CA11B740A78A3D41B5330526AB87D58D5925315A1485EDC647C1604EB38138DE637AD2C6CA5BE44E1008B2C0867B229CCC36619E2758C4C2029EAEB26E7A803FCA305A59CD585E117D698ECE011CC3FCE54D2E114545A21AC5BE6771AB8F13122FAD295E745A503B142F91AEF7BDE99998845FDA043555C9C1EE535BE125E5DCE5D266667E723E67B6BA891C16CBA174098A3F351778B0888C9590A9090CD404", + "tests": [ + { + "tcId": 76, + "deferred": false, + "c": "161CD259FEAA7EC6B286498A9A6F69F8B262A2E2093D0FBD76D5DC1C9FDE0DEDB36581004CB48112F852E7F87F649E8A42CD9E0349E7DABDF0A9AC1B521C37EA5241370A8AB2911CC79902C95D28224FA8896AD715209ECDD5D784E91DD9D0BE916B4565F4D5669AEE0DEF931E9768294EEC5258DE8391ECE271E7E4CFD9D23A79FAC3A8E0DB5DDD6E0107235688BBDF7BC5D5632F206C63A0C9564F30965CA58C69FF92D25A4F93A09EAB9B9085947E078A23E4D9C13B8A56E73E18DF42D6949FAF5921F2E373D450C8C09D07B152A97C245447429481D498BEB7256BC47F68F9922B0B1C62D9C23F9F733DD73792CFC7B43CBCEA277D51B2B8AD4A4F522F642CAD5C5DEB21F3627F8AF4D3E5BC9E91D4CB2F124B5BD7C2F4A050CA755BDB8056609663FB9511C9AD83B5039088CC01F0DD54353B0DD7433F0C6CEE0D075959810DEC5416522BB1F1F65547A0C2E9CC9BC17F8D39D29309EBE79F21331B75E12AF2E93F03F74F7F87D360F1DAF86CED736092A211A8158859C42E223CFE2E6E553437D80576CFD1944E97EEFF9B49E5ECCFC678EE165268DFE3D3596B4B86204A81C6063B0CDCE619FDBB96DF7DE6E0BD5270B4D59C4DC508476E7F0708F98C7A4F6645C49D06100C760C599528D1B8BBFE628191CC083C8D225A093F9F17E35574986F86BAA46898B589F3CB7DB46A45F3EDD4FAC20808F4CD0249DA693F8FABFBD4E10C02C65BA8C8610FA8C6DF3DBAEB6763DD482AF41558B1E15CC9C7A72E071685AC19A051F19245B9F77C3038A54E2958623EB8105955609E27D67CF72EC5C4A8E9B9C2924A9E2298508BABA13CF111FDFB062C9607AC1AAA6C637310A8894BF0B96F0C19136186B618DFFB275528BED1CC2715DEF412F77A3CF96645733B048A78474320D1A380F5EEDBDA21FA0125C91D3C37C54BF3752A1F8471C81FCAE2D3EDA966E14E66F223B054D79848FF9411D634024A098970ADE6A88B5F9069F760584DC4CFFFCEA8ECE11BB5566BD2360AB707DF2D21B67488D931F020069176423E6944490CB385E70B358A25346BAFCDD06D402FF24D6C1E5F61A85D", + "k": "DF462AD68F1EC8972ED9B02D6DE0604BDEC75720E050497351E6EC933E71F882", + "reason": "no modification" + }, + { + "tcId": 77, + "deferred": false, + "c": "5C26D456C6C7B0E8DF0B125E5D5428FE393655127A5E05BDD1BCAC14C47493783097B6185058FA700555DD8AF10F0F979A39A603826FFEB0B44E9487539F3F1A07C673E96640DDF754C8B98CD83473568B49D095F682C1ACF0E160AB93EB41A16A57D53B419620D351C837315080D530845CF8D63CFCCDB6E9DFBE220A2C14221AA392E6337FA364DF0D2E0398F15AC3DC822B5DD7217081107A45C8CB8EACA51E034117962AEE7EC0EE212FA67A5D4B07D355A0981E4285116ECF5CA9FAB6E3105E4DE4AEC5E32938A1EB91E65CE7B39C3B9829AA1E72B8092C3622E519EE092FAC8106D6597CEB941C763288723CB55044A36D4181052A78B424B0DE1B0260F624A8D3B317095371EE9BEEA9272250D598AC63C2138D23F99087777A902EBA2163171A07546B72FCE7F86EE3B1DC1B8EAC85440B8D241742C3771F91BF981909E4F3E2505C594761259ED3AADA6AA09181B99037A395D66E6EE4BBEF97DE6BA36C53A1808CBA50938038C151603105BD6A4199EA44BF4B08961672598CB708F896E03CD9B8F8AD89DECFBE6BE0EF0006B7BD2F4AA6EB21C0218EDE601D46924CF391AE3A44E43D96EBE84A630937C3409EF0710970C27E3ADD4E64DC64E83942ABEA9CCF498EF1FE72B254043D2775A37E0B5DDD3F596EA131E0734AFA9D0223F4CD9D1AB7304CA979AD37F717BEDC3A9526F8FC94433FE4614F82E709456F39BEE7BACC84E5A70114AF1C2AC8B9B3FAA81C8F35F5A5D24189E1A457F58166473F5F1DF0170AAB5E4AC8FC719F945CCBE6F2FED24B23321D95C4C850B278B8C4EA02E3098D5A599AA3D842CF889B7F284AC5E6E66386D63F2C860B997966B4DF2C32288A50045012B7362727B856AF4F8258509B563758752FFBB1040F3C2AD8B0DED64FC15C95C1A16DE0DAE6625A9EFFCE190FC7F3261D844C114913C6B1152A258A37761B81879B59C37A1DFAC07C3E934510B45DA44C2581A79DAFBF00FABB207306269D9B74B93F4367B3BA22CCC51B362DE16E49D9FDBF8CFF84F6CE6892CA2245D34CEB9C8759E702832B66A572DE9F3016A38F7328700F96B2E947", + "k": "A4A24E182FEA12FF128AB2D4AFE6569817513FFC547DB70636752C9C66C002B8", + "reason": "modify ciphertext" + }, + { + "tcId": 78, + "deferred": false, + "c": "79E255908B83DAD198AA6EA7219D5C170DA8548B172A2C28D53EB890914E16A6CE4405E8867112D35228DAC037743E25D26D720742C95935218ABBD93B4EB1C145794697EE761EA567BD561C6F5C076A48A34485539C49D23784606432B4913640644CDEE799961E5332E9502E683FEE98C9E1D071D8976E7F652EEE92E736D598F3B4D7217C0ED30FFA7DE590BBADCC0574A7280E502694A13A4E1D5D8837633A2EABDC97F36722D772A380595859134B9ACE346360860F8E60EACAB4AA3F9CF1DA73B5813F773008E0153B1BA0A5940DBC5C9E71E9A46BB4EA04AA9757E8E1AD0209C86334D05FCB611F3A00C7D983C7B9C160B7807CED18E5BC64A52462F4F9438199C2E4C6E9E70EDE2614913BE6D0C28894319B7B646444B5C86FCE61297EC11B21D216AC79159801ED3181667B15A7F30873BFD5727802E7B6588BDD04A5F7CFCD47043E600B4B3A0227E924E2CB92E514547BE4C1236C7AB2139F986AB956C704485DE570841F5857108D2AA57C535B3D44D0535208D501A9B56FFCBE8FDE32B375B90A5578EE44940E1E1888C21A4045D0338149D4C80CEF47BA25558E1842116E1E25499714163C0EE9A95A87A27CA2A61C4BD8D28BB04DE34EFB6E44FA7026B158883019B89AC4A5B5CA8F347A3FE892EE3949BD40D0614B9923052ED174FFBA720F516B6FD1317754A95520C66E3907B32A1648B344C34B3FA2ACEA2C8410DEEB40483529AC7D83351D888E968E457644CD76B8CAA55FC25BA1359F4A50119B1E69242DCE30E93983E50285DC0592537C6202F2E3C9878067A1777EA6A4E5ACC31614AE52787454FEEF503B82492828A736BF22E3278CF2ECAC1D0E11EC67815046CB4A66A8F48D04D4FB3C91CE7C251B37A8F3FB62A37489FFE63BDE22BAA18D4AA5BCCC0D8C709786B6C94D268382B649598A7A6785582CB2C02A2E9BECE29AC919785CCD026ADB6C9D8E85C3332DA956DC20B8470F8DD78B47E19B49BA5B27326D4937E93CC3453BB67EAFE42CAB03A70960DF236C04C344CA7177FD1E72E7E0A2C10D14F0C054337BD14152D4AFE9BB6243260E696EEE1327", + "k": "3B506D5A3BFB30D82FDD45B918F032A4023B9692D7EA6426FB2ADAB7DD5E274C", + "reason": "no modification" + }, + { + "tcId": 79, + "deferred": false, + "c": "D980E3002A28401678E1641E9E7A34D12CB2B4C9D986C7DB0FAB941AA83E43F42C44368138ED65B7A917B22ABA2DB0FBE44E5E9E7A3DAC3301379F7152585C8C7195031774CBEC61D8E1E093D694970B5377DC94CEDC53B6D3802BAF1C6F9152E05DCF66C1643528155C78118DFB00646B90726C75131DC934DCBB706ADBEC64E07F0D113BF71D4205D8E47DE67B9E01B224B82CA24405AE5591BBB1307D44E405E3866B1BB51ECE5985EE95D54568A81E7F285596DCAEBDC807EE6C8322EF2100EB38D10327DF92BC10A74A2D44842AA02AE9101A24736949D116CEC81F30C3092AAD941FC7F4BA10670CC0894A2F81E3155B9081004B4ADFB6532A1458F727F418D3F8F228E7425ACB7A4E4A3653529D1B9F72E57B8AB5852E35D0093B548FCC354A590C256B50BCADC30B55B5E05A3231611C93D5E34775741374F3E703B6E6362B35A68E33D859918D93EC03633220C61E1B81ED7AB1A5E46D4E640A9DE4E5A19FD11F0C24C556FE8D91F2358E7E78033A3C9FBF68C99DBA351F8F866CFF14E990C29E4A47579376606EB85A9D07D0BFD835C7670A5F4F2D4EA62B2BB13528A27BA3420095B852E3B73AB38E3CD068E276D8BD7A0B85BEFA48FEB72EBFC5240408B069FBC28F48B3A8E6556D7C601ADF98F0E9D64108F0BFE3C3B56C800D76E6DB14736809CEC22FA811EE92EA7950421B22F613E1349D259CF877075D476798C66FF58DBED013675BF6C5D3704528FBBE91486D7E956F785F73EDB6EB42861694F5C27E318C7B481377770125D99F236875D5B26CC8ED9859393BA2D8531E25FD6E2B3560BBC13176EBA638C72626C32D0250AB7F7EFFE661B18A641F75AE279C39771C7F23EAD50CD3AE461BB0EAACDDAD4F9C6436EDA5F2348F0ED4CD9514310AAE609B539368F53EA787ACD630080B832221B1CEF67FEB63CD2DDBA25282B020A3CB418130AD96D66EBAC09F09CB35BE0539B44924CEE15C6DBEAEE04C5BE5B9C43535FCA64B32BB204497AF175513375971B15F107F88980F0C0EB15D34762C98198A94EDCA385F32FD82CE7F6FB36F12B742C1755417A8D3F7D8A9", + "k": "68EE2117F8A66503091AEF490D1B9DC9EF3B3E62B97567F46A5EF2328263E5A6", + "reason": "modify ciphertext" + }, + { + "tcId": 80, + "deferred": false, + "c": "E1E906D018CCDE68680DF762DE4612106E918C29FF5D576D8FEF01D5241B666C26CB7B2F80793146AEEB9308511D9BA264A9A05D6621425730A50479B889F8C6E5AF66CFC9A3123D3B7335C06C8CD2F867484240E8B6C19EFBD3C15C33CFD10EA482D1897A516D07E39C3C1AA866C10655736F18689ECE7359D91E6EF5CEE957930258CD890C09EE1714150347A18DC97AD955B60750624755135AC81AFF8352B701EC5FF50AD925ADA003A617AE64DBFD305038E1E40108C6F12CCDD7738A83C9F7A76164F670ED4756097426700E51BA02EE36BF12FF22A316790F2C2FE7216C12F03023D87E2ADB99683229E77D6B1938EACF10D8686CEE46127CD7652A33FC05414FE370A159C516D250F7D345BAE5E1C9628A65FA9F5ED9E39FA10A316620A2D760C5DC128A5C6137F193226D18B5E013E300A41B1F2D1B47D90E3DF8B4FD71A794FAE0404570261477B32DC80CEA32F2DE743ACF7EBDD41EDBB0119EAF7F872A50A5F4C92A8B85DF792DBAC764C3A9A5A5C12D9E3913356C7F5463BEE9BD2A739FD485493B1C0DEEF716E129ED1E085F146E0D70A7E58D924F576F948BEBEF7842ED831FFD58B4656F91686B4D0F832DD3A4E6FA9F11A4870E9602E0DF0EF4FE9312EC4C7EC216D3EEDCA2076D0F0B5C9FE139145222347E816EBDC1AA70CBEB5D65954427A3DF6A78BEA86C410462596950AB8798F9BACE51A46A544C1BD17A86C2995E3BC82A7F965401A599103B0896E1B9EBA540614CE8F218DC7290103A6044E87069286E5BB18CBD89EF562B6AE1C7353F64D8CED183FA8D05D6B6A6633751EF342D839562733CDC1977684317EBC71378EC02B298671F76EEDCC3041E943A76ED9E0C496B798E10B59BAE17A195544C05CD1FA6A161358EA1D4DC7DF454220D79B235C24720021174C1BF47859CA30BCB57FC19CAD92ABF24C051D48B3D9D46779F910D26AAB4543DB2A0044BEDD491E1D72D8FDF361B50F1FD10AF4668D78F56FDC7E96CA16DCCD9BE8C1819DECAEBBECE41C09093DD508191562D6510307FA4685144D9679E84F58929D79E693DA041B12B76F629912B1E49", + "k": "B5191E505481428549AC5B5548EB747FE5290D51DAB6D49BD15CBD702129EA45", + "reason": "modify ciphertext" + }, + { + "tcId": 81, + "deferred": false, + "c": "3EAE23CC5F424EDC10108FCAE8EA3AC2BE8E90EB6AFC438B5A7DCD8E149AEBA25F0D5B25052C030F8157CC5BFB876A62F6A85B6C1C954F7C0F99EF4E3AE4B48C1CA9AF035543ECA1069B067057FEFB1E50FE0374F4162F0628F1D383A8B111EA9DE854EF33FB79488AA81E75712E5B9B6485290F0956B0574A6A9E1B4D677A832A85717CF7FF5A9E23B205C4FBD4ED7C2F7C5D91F46CD6A1EDB692750A4C1B11DB15C5643C7572FF9B765713C5C97C05BC2B861997CC6CC2C4D82CC62A32EA361630454756138C015D5501E362BC4E2B03A7AD679293658E45CF155B1C4F165954D594871CBF556CFAD2C3E6EB238DA3FF3A8140C5FCB74A278ED495DD14849D4C874C3E1F6E56EE657238F4E927FAE4588F1628DECE45C625AE0A6137868B9E86CFE29CCB4483CCA6FEE905F084B2B03A84DA421417CA5087B19654C803CF072B3C9E37A70B24E30E2F52B1DFCB6817ED05D38BB6FC7558B9B96AFA0CDBE708025D8D0454B90767753524CEEF8372150480BD104F1B7E659AD28EB155842CA81A55E81B707DAAF2F42A0B1CCE0B3BFF23F5ACF984ED20B0970ECF973DD0D5E33D34FBFD1672BFFF6725B5F1F869945FC67C5D01F3ED1CD8CD43A2008181AF7F65B0922D4BC634670AAD8A23A698AC3675EB3452DCE23D7E1A130964CCF4E26A9CD3D424A54ED7861E2D807F9C98E434A78695EFAC8BC86C69CD5911A2F52B5DAF50866151C5D00FAFCAB6219A9BA675413B4BB28619CFFACA38B9ABD1C3647BCE412336C02044EAA752B79248EBA1A7AED403801DAE5377CD55F517432B677A75DE4D4B504EBBF6453E319BB6EDACE30EE44810332CC84CBFFEE2B20548EEEEE1CA131AD87CCC284B3677E7F632D69F776060005439DE5648E466AF68C6616C63144451126D10311798A9B311064301BFAC1E4641830B1FAF4963F14A740529C360A73A351B6D330364BCCD2B012CD2B571ED243BF63F2FC1F1963604923B397A57680290D413FE7413B2C6C01D5BD6A0E314A644ECB10C69418251F48D3C3941211CEDB083F6FCDE24C5F5832034780B539D3FB1493C631F0C10F2F50262FA", + "k": "6262EB082F7C05044FAD90335BF60D117E52B382BACDDAB97D776CCB427AB672", + "reason": "modify ciphertext" + }, + { + "tcId": 82, + "deferred": false, + "c": "B3B6B84D9A33C59758CBEEF8EA26540D4E3D4A45BDC623CA1D0AC05D8E780D2DA1FAB26A0E250527FB0B9BD56B2A0686BD0FD310164A17244374B82FC9A93FC0AC6067929C4718B2054C7AA4AF1FDBC9EBCC55A787F7C0B98A8E6181E5604E8F7108B181AD1385422EB747286FF72BD1EF650AB88865BFC37EA5536A220C29ACE17F8AA82A77F92E0A031E526171C44BD5FA1E7946CD063B1A7E113FAEAF92015CB3CCFBDD9C5E0329CD3DBD1B8CA90EC226ACC27716615B5998E0F5A5BFBA347FDD3DD851682B8968858F4A73FE5FD952CE7FF597185855E4B7F76F44BC1B24DB7C8C3A37217DBDF0BA7168D91B59DE9EA219195D29A5C67327D51D4E05131119C81722794D825B9F01DDA93C74B176545E32E638243891EE09E2AC1A9693C83D4BEFACCF25C81554802FC422C75812E18BCCF4D3CF208BE6EB16FB4E82C4ECE33C838A0B3D3EA4C027F41B4027643D9E4B6A7EFBD8D42A65B29786F4A00C16ED4492F4E945469C6E03A9A297AD9763333A2B9725DB5C6F8DF1CA7B0E77F5E6364FB6E8E528578350A04E4E4617E72E5FD67FE029AE2D738D8DFE24730D9D737D8E30ADCB602102FE2D99B915C9B04CDA463D444ED9C6E6A71BCAAFE503BF1D15270DEF8B9D7AA5557177EDEAD75E2FB01A4635A46D2F95DEA6314DE4965EBA8358210F79E64933AB4B6600856124363A47C6063433BB670266AA8FB968D947AD96D97C4003A50B0D1119E3A73E00363AE5EE85B5815A5BD944280031F0DC9B98F1F5C589F259A486BFE26EE1446D937EEDAE41275AB72E0CD15EAA6368F59686DE08E147CE2F5978B366D0A4F98ACD7D4004D1D0A4897A0DF5B1AF9F811BBAC64952D10E36A3EF78D379EF0E95DCD2D804C07AD8D1A8882FE1F2FF188F31B886BB597FF16F4D597EB337319AB4E81565EE4AC0A9BB3B6C3184C9C66511D7313555EF703194A747D0857DD27F92A6DE12DB311828B684FF3F1D848D5E92E0EFD7BC6B3EA7039296D587A075781880039A7C0DD6DB66EDEE3A22F7F2EF02B267429F6BEE16F214A59EB96CA79EC5065784445ED2FB631BADF6645991736BE7ED", + "k": "94EAE21B192F9D8FEB94E72B8F24BB0E1442F1F569323B202A497DCB64F9791D", + "reason": "no modification" + }, + { + "tcId": 83, + "deferred": false, + "c": "FA42A8B407B527A8CD9351560BA4DA60756B27FEF326BC549B3A4429B2E58EAF22B3A36AE554B416DCE209E8CC708846312992DCDD43AB177347363F81578B94F451F1D046233BEEC6B42C9E0D55F3D741A55F7C564C4A9D5ECF6B067723E4403A17CBCFAA00E2F8D2EDFE1E236AE861011A5DB659042AA23BEB01A0471D178DB91039EEE5FC7EE85AC6FF3845959E5001C61CD1756EC681C97F4A70887884157D664A505ED7E4E1F4598EBF8BCDC0BEDE7FC0A89B3E14237187CED97BB0C0E54D21F4DF47BC8FC3F863978DBB673835D17931B7819535C1ACCD8706F8726BB0A0DE20BB824560AE5BAAE2F0BF0E3E676FF74C681474534C857837E7040C33B7F031AD9900A29DCB71BC305DB0ABF92CEB5DD2EB8E644F23AC0BFD8DCD2B44101FD7CB8A287318979BAE754661FFB13097B2A52B50236094693A754DC97CFAB550877A4D8C6CBA8B4A2E3D719ABF0EB13D40976B9E3F6C433DB1E16D794466D2C023988528AD0336CE43636DD50FA6A5E899578EACEFACA5FFC5B6FCC8C53E21503B83ABEDF2174FE08B4B960476934C5D6021829AB7AA7767492FAFBEE492A08524FBED46E8D0451C6BE1BE02B55653326735B0D8CCE951A5CF534E3547731EE36EB9BA38E0AE253B8CEC35001EECE0058E634A11F59FD6F21C1A3882E291F59B1FE3EC7F55315E0A65F9D011210462A8CAFC9779208452FD4F3B64FF456EA8588D2CB394A9169F1392646880A1C63721A2277FDA432FC6EBB61FF87AD473FF41D831DD95111CF0A1D69F001A008C3FD00B46F5342EDB8DADC818E6470D21C915F3E91992806E5B18DB314F9592E0EC8B8F0DEAF92DC89C194449A2539BE7C6A1B01B6F3DC496CF33CA25825B66971880652BC6E4FBD901A286C50D625F0F682B0B4CC769EB00940C45ADE947844175A3BBE8DB92BA6DAE5BE456CEA41384BB29A8C9D4E08F1375D4865A69A59619724900DDFAE48A2D12975C789E76104AE114F30ED4F836E46BCD8CA7520F4838651225894595C4F7BEFD7ED41EAF6F395EDE40F988CBDA7E08122A61E552801C7F3E84039FFF17E3534610D3434B996312", + "k": "23B74A4AD3F8E3EE73481A768E1F5CFAAE068ED38C0AE1E7A03159D2E9B0BA93", + "reason": "modify ciphertext" + }, + { + "tcId": 84, + "deferred": false, + "c": "9F972164967C0CD03A3DD68714FE0B4EE0EDF9ACF63AA068C10FA947F8A03264B4309EE61C8C9B0C03C5FEDFC7B77AA862DDEFEFE394FB09A2396097452585ACD0CE510324A03F36904AF07B765575DCB3B1A84131C352EF14C2572E39DDBC8118875ECFD7EF7D2E41D9C9BE858FF08DBFABF8A80BCF18FDA8735F440D9B8FCAE0E67C5BF0171B99800BBF0F3EADF76F9FD69BB0734F1356C53EA9CD64E86C14C084BC3B1FEF040E5FA939F8F0D5171AD02628AFD8B02DB7D7B5C3B32F1A8EF3AD4116ADD4502414163C14D49EC73E5F4B25C5BAAB82C73401975F2119C569E1F2873DA202F32BDFB76F9AF49F22604D1B1BB173DDF6ED70D82B360C13822F5F9BC4C4D5F2391E4FB6BCB723A56666087A55E033E50202EFBBE7DAAF96AC541C855AA4154E37CDA55B1BEAB005554947F781512E2873B5CD8B118EE0932DB2FF427A15BD114D7DA79C7D899FD820A0222DF90D8E85CEAD8A1BD96A88D6D58C0A4FBDE3AA55DFA1E4B12AE6964DEDE20FE337E4BA5EE8B67CE1ADAE9851D021A56B999DED62D0E4471CD928E9AA4AEEC5C878199149D82C3CF4FCB68F63DF27842C37E52182A7E3B332F24948F3646874326B4FDF215524A1095A224F6EB02355974A6DE9746824A3954B700903292DA43D5DD51DD9D8E98E63DD01C357E4913855190049E0F1A8D9725B095ADAC4885FE832E0BEE82BF3DC355668093B475FFCF7D92228FDEDF0451C441B345372D6EE58408462E2C3BF22A095E5E23A159397FC959C126CAF936A3E64552003FEB2B963AF7F915885445EB25B934D659900DD0506A5FCB7168392824945AABFCCD01D9EA8A2256FC8E7AAF0C4243025A9F47F295F9D2713D5257D626057E904E34B8C0530A11DF2D15AE6BF1ADA6971B233B5DFB59EF8B9EB813E7E52794883BD6D676119B5B86333CBE6427F97ED719C432127805A9790837A1EB04B82907A59CED1286164A9F02716CDAAEE48799599CB09F5CA8BDE83CE8278382776CC3246EB2C0EA91C1A9D0CD7406B419A22CD6115018B9641405F9F44E13D2CD6AB457825326FC5CDE85C94DF86097BFB5204530FE8", + "k": "E9A6006C6C4D5A51829AADEADE89CC104358D0823BA8CB5AF4599D59E1679638", + "reason": "no modification" + }, + { + "tcId": 85, + "deferred": false, + "c": "082411FFADCEE22B6C33277C32130E4C77CCB1849A2E7BDCE47EB519CAAACAAAA8DF129C5D876EAA7495ADED159D27F525EDD5F1F86B7A4FD50AC0B1F7B07C23F726D96F82D17818EEE6F032D0AEAD04D0F56EC244218905FD779268B259E29BAEF8BC66B42F47DC5BBFEA06620F38E0F373BA3F598CA7244A9F5B6823CA293BDACDD6D7B2E49BB2D00D1811C0F7FB2736876699D3F115C1D5AC58EBCFF10F514D863A56901F3DEE1328ACEF5D37DFEF841392BB29A88324CB51820A0CB30A4C222F7450F321B6617EEE7E722004AEBB5A52ABC3A984B8A142F0193EB90654FF86B8799EF7BDC01BBCD7C151587557334E01B833E950260C5E126C2BBF35EC030BBACFEF2812819A20960A9CA4E8D4836A7282F8F99AAC18BC02F6275582C7D1E6197938F67A80FB2363BF77A96355FA9E0AB19883CEA65A3010795E4A48A8B22FD04EC4578DA4452DC1B851C03A93AB147F3A34981515B75AB80D10A96570C2BF9ACB2E1662CF86E077EA455ED1B130D59CCA1F603A3471C408A342C42BE1AF6BA3E096E78CCF36CFCF6705078800E4E968FF372CE836AF5090E2442CF73E565146C69CBC0F55DB89BE1179CDF24DB6DD2C73371B00BD8CEC89FBBFAB3537DD0F50156FFA2D604BD135B91728DC93AAF31EBB51BCA15C02270D93051FBC0CF006C57F6BDDF5B8E60866E7A051358C4D0363ECB9A5EC3B6C745C41A3EFA2887B6B5AD8DC68E3C3FA17291D3D044D7085C6E2D3EB12FC3536CA8A6BEAC7B55BC2DD77B6F102C577B988E03AD963FF34CE4DFAF5194A05F12606D8E62FA7E20329E6630177BD60BCE780E014A856207A2745E5A22801A680CDBF0653EFC71F263E795AD7C495A90B7A5BECE0CC3F879B411A39A4346C677F53094298C0B2596DA1B136A32415E68A249161217414CC0F5F4D40614E162A3A757BDA41A80FCD17202AE062832D971FFD0A2F66D5EE94A26B1B78582E9F79F65A20D94EAC98DCC54D62B191DA89108126143E810AF6F8345723C69C009C481837FCED2408A8E37C96A248D7DDEFC7BBF73A5A91BFC10163813D22B0B26D5C6E380CCFCD6598844913", + "k": "3136E97F0A1CB0208B1CD89E510F2A37A5412AA5A2012E24327572886DD69408", + "reason": "no modification" + } + ] + }, + { + "tgId": 5, + "testType": "VAL", + "parameterSet": "ML-KEM-768", + "function": "decapsulation", + "ek": "F80751877A80FB724A0210C3E1692F397C2F1DDC2E6BA17AF81B92ACFABEF5F7573CB493D184027B718238C89A3549B8905B28A83362867C082D3019D3CA70700731CEB73E8472C1A3A093361C5FEA6A7D40955D07A41B64E50081A361B604CC518447C8E25765AB7D68B243275207AF8CA6564A4CB1E94199DBA1878C59BEC809AB48B2F211BADC6A1998D9C7227C1303F469D46A9C7E5303F98ABA67569AE8227C16BA1FB3244466A25E7F823671810CC26206FEB29C7E2A1A91959EEB03A98252A4F7412674EB9A4B277E1F2595FCA64033B41B40330812E9735B7C607501CD8183A22AFC3392553744F33C4D202526945C6D78A60E201A16987A6FA59D94464B56506556784824A07058F57320E76C825B9347F2936F4A0E5CDAA18CF8833945AE312A36B5F5A3810AAC82381FDAE4CB9C6831D8EB8ABAB850416443D739086B1C326FC2A3975704E396A59680C3B5F360F5480D2B62169CD94CA71B37BC5878BA2985E068BA050B2CE50726D4B4451B77AAA8676EAE094982210192197B1E92A27F59868B78867887B9A70C32AF84630AA908814379E6519150BA16439B5E2B0603D06AA6674557F5B0983E5CB6A97596069B01BB3128C416680657204FD07640392E16B19F337A99A304844E1AA474E9C799062971F672268960F5A82F950070BBE9C2A71950A3785BDF0B8440255ED63928D257845168B1ECCC4191325AA76645719B28EBD89302DC6723C786DF5217B243099CA78238E57E64692F206B177ABC259660395CD7860FB35A16F6B2FE6548C85AB66330C517FA74CDF3CB49D26B1181901AF775A1E180813B6A24C456829B5C38104ECE43C76A437A6A33B6FC6C5E65C8A89466C1425485B29B9E1854368AFCA353E143D0A90A6C6C9E7FDB62A606856B5614F12B64B796020C3534C3605CFDC73B86714F411850228A28B8F4B49E663416C84F7E381F6AF1071343BF9D39B45439240CC03897295FEA080B14BB2D8119A880E164495C61BEBC7139C11857C85E1750338D6343913706A507C9566464CD2837CF914D1A3C35E89B235C6AB7ED078BED234757C02EF6993D4A273CB8150528DA4D76708177E9425546C83E147039766603B30DA6268F4598A53194240A2832A3D67533B5056F9AAAC61B4B17B9A2693AA0D58891E6CC56CDD772410900C405AF20B903797C64876915C37B8487A1449CE924CD345C29A36E08238F7A157CC7E516AB5BA73C8063F726BB5A0A0319E57127438C7FC601C99CCAAE4C1A83726FDCB5045ED1A82A985EA995396D77272C66CE493289F6110910F37C2741CE47026A6F8261999C6482572B1693912EF12EEBEA7ACF9234FB409F2A6090E6B0BFD895469D0B2A921BB723F87A33EA5465AB90F514B67698C0768B6CA498B022C512FA0875F054AA2265867E31C0E522651E024A07D60DD9F633166921F4126BC2B6AA01CC15A09B85BFF8218C5AAE95BC1FFB26AE5A137670F04910CA9D7241B6660C394C5455917746A26682FB71A432EA9530E839BDEB07433004F45A0DDAA0B24E3A566A540815F281E3FC259AC6CBC0ACB8D62268B603BC676AB415C474BB94873E4487AE31A4E3845C79901550890EE8784EEF904FEE62BA8C5F952C68413052E0A7E3388BB8FF0AD602AE3EA14D9DF6DD5E4CC6A381A41D", + "dk": "1E4AC87B1A692A529FDBBAB93374C57D110B10F2B1DDEBAC0D196B7BA631B8E9293028A8F379888C422DC8D32BBF226010C2C1EC73189080456B0564B258B0F23131BC79C8E8C11CEF3938B243C5CE9C0EDD37C8F9D29877DBBB615B9B5AC3C948487E467196A9143EFBC7CEDB64B45D4ACDA2666CBC2804F2C8662E128F6A9969EC15BC0B9351F6F96346AA7ABC743A14FA030E37A2E7597BDDFC5A22F9CEDAF8614832527210B26F024C7F6C0DCF551E97A4858764C321D1834AD51D75BB246D277237B7BD41DC4362D063F4298292272D01011780B79856B296C4E946658B79603197C9B2A99EC66ACB06CE2F69B5A5A61E9BD06AD443CEB0C74ED65345A903B614E81368AAC2B3D2A79CA8CCAA1C3B88FB82A36632860B3F7950833FD0212EC96EDE4AB6F5A0BDA3EC6060A658F9457F6CC87C6B620C1A1451987486E496612A101D0E9C20577C571EDB5282608BF4E1AC926C0DB1C82A504A799D89885CA6252BD5B1C183AF701392A407C05B848C2A3016C40613F02A449B3C7926DA067A533116506840097510460BBFD36073DCB0BFA009B36A9123EAA68F835F74A01B00D2097835964DF521CE9210789C30B7F06E5844B444C53322396E4799BAF6A88AF7315860D0192D48C2C0DA6B5BA64325543ACDF5900E8BC477AB05820072D463AFFED097E062BD78C99D12B385131A241B708865B4190AF69EA0A64DB71448A60829369C7555198E438C9ABC310BC70101913BB12FAA5BEEF975841617C847CD6B336F877987753822020B92C4CC97055C9B1E0B128BF11F505005B6AB0E627795A20609EFA991E598B80F37B1C6A1C3A1E9AEE7028F77570AB2139128A00108C50EB305CDB8F9A603A6B078413F6F9B14C6D82B5199CE59D887902A281A027B717495FE12672A127BBF9B256C43720D7C160B281C12757DA135B1933352BE4AB67E40248AFC318E2370C3B8208E695BDF337459B9ACBFE5B487F76E9B4B4001D6CF90CA8C699A174D42972DC733F33389FDF59A1DABA81D834955027334185AD02C76CF294846CA9294BA0ED66741DDEC791CAB34196AC5657C5A78321B56C33306B5102397A5C09C3508F76B48282459F81D0C72A43F737BC2F12F45422628B67DB51AC1424276A6C08C3F7615665BBB8E928148A270F991BCF365A90F87C30687B68809C91F231813B866BEA82E30374D80AA0C02973437498A53B14BF6B6CA1ED76AB8A20D54A083F4A26B7C038D81967640C20BF4431E71DACCE8577B21240E494C31F2D877DAF4924FD39D82D6167FBCC1F9C5A259F843E30987CCC4BCE7493A2404B5E44387F707425781B743FB555685584E2557CC038B1A9B3F4043121F5472EB2B96E5941FEC011CEEA50791636C6ABC26C1377EE3B5146FC7C85CB335B1E795EEC2033EE44B9AA90685245EF7B4436C000E66BC8BCBF1CDB803AC1421B1FDB266D5291C8310373A8A3CE9562AB197953871AB99F382CC5AA9C0F273D1DCA55D2712853871E1A83CB3B85450F76D3F3C42BAB5505F7212FDB6B8B7F6029972A8F3751E4C94C1108B02D6AC79F8D938F05A1B2C229B14B42B31B01A364017E59578C6B033833774CB9B570F9086B722903B375446B495D8A29BF80751877A80FB724A0210C3E1692F397C2F1DDC2E6BA17AF81B92ACFABEF5F7573CB493D184027B718238C89A3549B8905B28A83362867C082D3019D3CA70700731CEB73E8472C1A3A093361C5FEA6A7D40955D07A41B64E50081A361B604CC518447C8E25765AB7D68B243275207AF8CA6564A4CB1E94199DBA1878C59BEC809AB48B2F211BADC6A1998D9C7227C1303F469D46A9C7E5303F98ABA67569AE8227C16BA1FB3244466A25E7F823671810CC26206FEB29C7E2A1A91959EEB03A98252A4F7412674EB9A4B277E1F2595FCA64033B41B40330812E9735B7C607501CD8183A22AFC3392553744F33C4D202526945C6D78A60E201A16987A6FA59D94464B56506556784824A07058F57320E76C825B9347F2936F4A0E5CDAA18CF8833945AE312A36B5F5A3810AAC82381FDAE4CB9C6831D8EB8ABAB850416443D739086B1C326FC2A3975704E396A59680C3B5F360F5480D2B62169CD94CA71B37BC5878BA2985E068BA050B2CE50726D4B4451B77AAA8676EAE094982210192197B1E92A27F59868B78867887B9A70C32AF84630AA908814379E6519150BA16439B5E2B0603D06AA6674557F5B0983E5CB6A97596069B01BB3128C416680657204FD07640392E16B19F337A99A304844E1AA474E9C799062971F672268960F5A82F950070BBE9C2A71950A3785BDF0B8440255ED63928D257845168B1ECCC4191325AA76645719B28EBD89302DC6723C786DF5217B243099CA78238E57E64692F206B177ABC259660395CD7860FB35A16F6B2FE6548C85AB66330C517FA74CDF3CB49D26B1181901AF775A1E180813B6A24C456829B5C38104ECE43C76A437A6A33B6FC6C5E65C8A89466C1425485B29B9E1854368AFCA353E143D0A90A6C6C9E7FDB62A606856B5614F12B64B796020C3534C3605CFDC73B86714F411850228A28B8F4B49E663416C84F7E381F6AF1071343BF9D39B45439240CC03897295FEA080B14BB2D8119A880E164495C61BEBC7139C11857C85E1750338D6343913706A507C9566464CD2837CF914D1A3C35E89B235C6AB7ED078BED234757C02EF6993D4A273CB8150528DA4D76708177E9425546C83E147039766603B30DA6268F4598A53194240A2832A3D67533B5056F9AAAC61B4B17B9A2693AA0D58891E6CC56CDD772410900C405AF20B903797C64876915C37B8487A1449CE924CD345C29A36E08238F7A157CC7E516AB5BA73C8063F726BB5A0A0319E57127438C7FC601C99CCAAE4C1A83726FDCB5045ED1A82A985EA995396D77272C66CE493289F6110910F37C2741CE47026A6F8261999C6482572B1693912EF12EEBEA7ACF9234FB409F2A6090E6B0BFD895469D0B2A921BB723F87A33EA5465AB90F514B67698C0768B6CA498B022C512FA0875F054AA2265867E31C0E522651E024A07D60DD9F633166921F4126BC2B6AA01CC15A09B85BFF8218C5AAE95BC1FFB26AE5A137670F04910CA9D7241B6660C394C5455917746A26682FB71A432EA9530E839BDEB07433004F45A0DDAA0B24E3A566A540815F281E3FC259AC6CBC0ACB8D62268B603BC676AB415C474BB94873E4487AE31A4E3845C79901550890EE8784EEF904FEE62BA8C5F952C68413052E0A7E3388BB8FF0AD602AE3EA14D9DF6DD5E4CC6A381A41DA5C137ECC49DF587E178EAF47702EC623780691A3233F69F12BD9C9B9637C51378AD71A831055277254CC63C5AD4CB76B4AB82E5FCA135E8D26A6B3A89FA5B6F", + "tests": [ + { + "tcId": 86, + "deferred": false, + "c": "74A26C7D27146A22C7EAB420134E973799CEC1DA2DF61AE0FA7905A3A47485A063076BFA22D6E4FE5059DE0A32E38F11ABD63F990E91BD0E3A5BC6E710DFE5DC0F6D4A18147EBC2E2D9B179374D83692C53EFBD45F28A2A928C2494F903576C410EB1773895EBEADB119960EEBDA9C3C710795A6D9B781FC58B30D08107F4E20944A382AFB079F31D21724F2C26E6A53412F0A908BE7586F2B3D6D7C1DEA0270E98AA209244BD88ED68AAE01432342BA5F49E015CB476B5B78D15EA77A354CC9E9FD07137D8760BE42FD4746C62C02028E7B405DDC95DF3D021921CFEDDB3D961B957ECA302A263DAB2DC117BEB3E79EFACFCF936DFC09FC0D19C358D724FA381EA06CA067C384E944302C3907AB15A1DA4B41352692ADD59B061541F07EFF25EC42F46E1A0E370CAD06FF3FD997D4D2C5648AF762231B382D0593401936CBA21551A2AE30D8E8EFFCF43916B83138BB5E610364429879FA9CDD5B7D3CF2FEABAA1DC8D50CE69402E21103E795DF7074D1FCF65F8A4E18986D5417780602C63BE5A044863384BD3D8FFB685EAC567ED8349DCF2CEB702B7375B145729998049D13E2CD466CF2231B9D3A20018EE908F8514A6C6A89DF7232F91FCD84B81EBC8BC539E9A37A4324755564BE1BF4FA1FB4571E0ABBC9B52F9D090C33BE599DE6C8532C7CB7EC8B4E2D3C07505280E99923865903FFD18BC13B9C8164AA1EAE84E38D3F57FDB8801785F105A6A8574BD2FE9BF305848E525330BC2D24F0257E47A4950F433A9233E8CDEBA81DBAE7D8C1A06D01F70DE6EF663207D84952827BAB3D451CBEA0990007FBDB4240FE899A706F7C1563E05C70BE9D575189EF83E0CF76195F6652491CCE04F1CE2092170A92E0DD7301246A4C44FC0B4EE6AAA63FC7027840ABD2EC25F654589738CD38B9E10B975CFB6C1D2EB4DA97736998F84FDDDD810D72DA3C5AB13507420DDBFAA4F7750C1FAE9C7DFB30F40A12AEA689FC78DA900020E3ABB32A364D5C6B3C7544A1B5734A41E95C8314B448CD0B738D829AF772A8F81C51ADBA2D85F326C8F5D6961CF12D44A9BEDEA00D1DF5B48F429B1CE0C15EA5F5BC10B017247BA2C6BE922B0563B8E9698677CB6C45CCF2081BF84219D2904C11FF92199F8AEFAD62D8608E200802C5A07202CC820E9E520E31BF36A83002ECA4018B0B3A398801562AA86C77AB0D50A8FBC3768B0A643B97E7F9072168DE29B8175999C9AA48D301A3F0303172E9C7D4F16329D5CA9D42397C3982E10C9DA42DE88BD6C2AB91C1E71E778E58BB8F801F207A88A9B47F9C687AFBBA34EDA6D2899E4FA0008AA2B539711753DC7C07F614E814F683D6C037562AE1FBBE6D7D5FA54B7A6D9451E11B01AACCC3BF2ED64742DD100E0EAB2DF6CCCF937B6D5981ECA0E01F3245CF26A72AD1ADF066C8F5430D72F509963A657D85E554C14E26E8BEC5D5F3AB998C9B29F16B04747D80749B30E51FD2A7F690C22F9986AAF6358D6FAB8DED54971B32641DE2B258590EEAA6BF1F32324A7C4C983F49466D86", + "k": "3D23B10DF232A180786F61261E85278251746580BEBCA6ACBAD60AEF6952BE69", + "reason": "modify ciphertext" + }, + { + "tcId": 87, + "deferred": false, + "c": "39EFB90089F1DC32A54370B3EEDF2B12880DC7D657F0404E41F7DAAA73E7F06CB90BBEEC7544160768EC3B56681D057AE1DB58F0123286D3A8CDD0B414CF9894FDA1CFF3A37CF67B82C5C7AD3427F2F2B393978B94E524F33334E4A98AFFEA8D7514D6E12E85086E58A0C078EBA64435441F3E3702EA27EEA984E46893BB886572491F22AE09F8D50774B4DDD5CF478CB0B2D070437E86645EF62AA83599093732F81A75D1D5DE15C31EC81AC4D67852FDE089D580B71E3DB07C71394424E0936BF74D0C9405BD3DFB60B920E7EFA38C72D5912BBD301BD3F3709CBEEEB7BFD0767B77A8639913E8C228FBB7E3E13C423BF05AC65B7E75F29C9048F161AF1B4B41C495ADB53FECC57FED0DCF792050A2A586C33AA4A7F6BCDA9068EA295FB692BDCA756FCC47CA0A8C84DB5DCB6A616605F3D3A34C4D23EC14942492C07EF123C8D084DF21F3B2141D277FA16E3CF4D5A3AB8D78CE8370F411DF737647A2D6123120AEE1CCF7DEFC35A5408FA6013E94703E8E04C50BADCBBF2E1FF0FB82DB4AAC595B9EAA9E370C9C6175CEF20B1D0B8A4309AB91918451E6C8A6DF04AE468D446FD9E83F9252F145A2B44A19E7B27DA56044717DB5A6ED5F6E5CDD90208ABC324290292B1F2E84FB69F5989D9921DCB4F058DCAF7B99DF71B26BD1090E457767954B8ACC84FDDFD663D64027528077B3C9E370600942E4C1175B487FBF25E267474B5238576010CCCE3315CEDD5634658B2028F3FB9959D77FA23756DB4878697C9BC491DBD68986B9073D187F2A9E72C943D94C97DA865CFD9C23508105637FED62E56E745555909A49D23B86E620D48FD55A92CC2266C38B857F5DF9BB683D60B084819CF04F5BB8CBED05AC6F48C518EDB5B222F5E6DCBB438182A7BA3B2279E5856828CBE9BDA6009A70D20DA082D2FFBD092EDAD4B272E46D215B8ECC26222499F024327A391CEB007789757FF8FA8267429F0534F305F75709DCC4229803EA8E612F55890C5FDF8252794D5C9C4058C2258A5599BA858A02F89A6FDB35C4F2364A4C6B326A31F7D04F62C2FAFE51D280CD7A4CAB66404FDFD033EADD07974BCAA7F0CB7401B9484DAF9F325B6BA53FBF41219384B264F24AA8D65281693295E6F71FCA885F808026829A3FC32DC9603F0CED36F0B58A296B44ADDA3AAF10638C31F354D1A5AC34E77D4D0154C9546709E920258F73E039FBC223EE74A270840165F64E3051B10B5E63F9ACCF5D1EF40E43F5823B15F8C25CAFCE698A64F9AE316D3905B8E510C56CF7544CA94719735A640F2B8C3A2B828A04E0568863937595E5B9DADA33533D9D676AA657FE69152E93159A00C5962F4DFF9C901A9AB32DB28B93F4BA780E44A2F73878AA76E112E3490205AF83000EFD889FCEEA5E87AE9AE01EE1CCF6BA0461A8D8654B7702C09BB41C4F61A00D05F031B244EDED8D1CAC7916BEB9AA67A3880F4C3516A8D8204932EA00EFB3AA20369FB6BE404843C7411E88428568AB9A39124EAD115298D49C998651E5EF613A6819336683", + "k": "1D2DCACEC14CBB78FE9E418937835EED088CC0683300C965EF3972081F01C4E9", + "reason": "modify ciphertext" + }, + { + "tcId": 88, + "deferred": false, + "c": "A5C81C76C24305E1CE5D8135D41523682E9EE6D7B40AD41DF1F37C9B17DCE78076019A6B0B7C95C9BE7AF29507B2D5A6987C8EE3259190855243E6E56F5620608C52D96FAB103A8700FBA1A87DCA6078118A0871762C9534C0C0C3978C91C3A01F0F608DCF757815438FE8957C8A859183B1B6721A0865BEBC799D4E5C0E7BD3EAE4858E6AB6A2E7658ED80D4ED158B036B93FA03AFA6AE3136CF3D693C911BCC75905E5B0CB2865B9E9884522A77777613E53111D5A1C7D3DAB734CEB03657AE0C89763E99471054776BAE7D51B0E73A5BB35AEC30FF6BC93684916FEF1162586452F426653E2CA844D5744307FF9AEB287A6447783B21A0E939C81421D631F5DCB452E51ED34E3DAD1CF504E0A3B0F4711A8DC6499D1691D109569336CE1558A4C0A464E2087EA8F9E3B18F747EF61F4576AEB42B17CADB7F0FD84DA8E3A6F471D95EDFA65BE9E6C9F6AE756A22A4F1A5C543C26BA7BAD88E16D5F5B7E12E2D4CA34B3A64D17F87CCFC4FF8C5E4F53752A077C68721E8CC817F9FF24876170FF2AF89FA95855A5B1DE347C07FDDBCFE7264AA5ED6401491561D831538F852B0ED7B9E8EBAFFC060284F22D2BAEE56FA9F6D01432A115A2D6A64C38AE0A50BA362FB57B53E3E855B83CE8C42274045599F65FA6A8921D85F94ED230B516712DB6FD2FF28B3A3371D9BE058AE75C2FA591B7EC3C3DAA1F7642BC26C324C08090607E6662154DB37CF747967A1F9FC29089F570EBE60EEEF89FD24481028C85AEF1DC3B09F22CD3691BBBB821C7A8A0F35AD12BE1DD199B977048F3D48C16BB2CA94CECB8928770D5BB329A0327E0B286FAA1C65281031A31C84F2EDC9C04D475ED4E128E51EFA97D0148CBA6C95F674C589F301C265BED708E9AD8DA3C5CECBDEEED35EF1E253132BA89920D786B88230B013BCF2DC92D6B157AFA8DA8592CD0743D4982BE60D7C2D5C472AB9FA7F4CC3D12B0EBAF0ABE555C75805426844DD9428643F84406A1B8D6FAEDFD8AE6E73A72772A2159ACABD972AEB6F7DE091AC5FDD7F49A3DC6641CDF62446B4B04A31F73B80A62F80A404A8CB18CE3E65480EF7B52BF0091117E5D08EAE1B0AABB72E6DFFFF76F6E44BBD7EA570D6604BC2E74318BAFA315A38861AA1B21AFB2A53F2614F1D640075984AE62E2FCA1D1B4DB369F15705CE7D4DF8AE98264501051C0DEF21D645D49625AF02CA428D9F0C2CD9FBAEEAB97E8E9151662B6992B4C99AB1B925D08920363373F76D3FDF0828CAA69C8B1BDC6F521DF641CF1C8A4E7EF0C23289A4E2CF18ACEBBE4C1E68369BD5235120142ECDD1A73811E2E533A647D7AEE16DAA03B683639DCF1E1F1E71CFAED48F69AEC3E831733DA19CEBEC1DDBF71CBAE0800F2F6D64A096EC495D62F4344F7AA5621B322353A795AA099EA3A070272D053D4653A20CF210EAAF12CAE6023D8E5118DF04B384A44D1EDB91C44989EF7EE57F2BF81A24BDC76807DA967EE6525410C5C485067EFC3D39A9AD42CC753BAA59A1FD28AF35C00D18A406A28FC79BA", + "k": "DC5B8888BC1EBA5C1969C21164EA43E22E7AC0CD012A2F26CB8C487E69EF7CE4", + "reason": "no modification" + }, + { + "tcId": 89, + "deferred": false, + "c": "0BAF0F6E91ECAE3199F4921631891A14C13B418B53384992DA3A8DADA7DEFFB9E1E5F559D27344B60BE81ECD01CAB1E316573D571ED46F59248F4023DB0282207E730549CDB60E793E4CD17AC6F2800E2D1FFB83477A6FE1D73992682123EA730C63269DB13088D6DA46D086CCEA2176398EAC663270B8B2F337A55E19F4C500DE066B5441794C2D0CCADFE5ABDE7D93FD7D6468BC4F925633366D9316788B90B110A4D99485E7E578537A267744FB266A4F243FA02E3A81DA67ED477923B36B37BE21DDA21EB51DCA1F0CE41652145F4C542B2E5C922617033608246BBE2B5250A368804ABDB2EF6C31C491CE3DD852AEABF6EEF1530F4C99286B4B595D57CF3A99580B59AAA2C55E080B5230EA19CF2701D21A37FEFD6F9709657A21ADD063ECBC197B5AD068BE502A2E090D83F4156B671E46617BE6D6A17D0425FAC565C4A0E48966E9D900CB2C2B0D296E0BAA9D6C5E0514CD78834053058A97D3DDF81529079858737440812670E818C9891681D350ECEC93DAE389D534A5C78F01811917061CAC0003D2BEA390EB63FA0FE9BABCD7FF302D4B66567B2BFA67B20F962847D010AA4193CBE9F8CC1B14F8B237C22675B298A8376DFB6037BF7CEA36BDEAD5B505111F67730824B4964815D00F63EE98B9BEA0F2F47CC007D5606ED7F967CB15CCD4AFBC99881CFD297BDC2A509ED3CB320DF58DC4A5BCD1CB100B9D6418CB8E0F40DEF293DA2370CA729B0FAB071FA6AEB0F3F5D1925AB2DF732F98DDBFF23D5411E4921A1C506F2F93251E822C4CF83998B000FE65ED386F5745B1D4D91AD9F98B45E713C8D944409E9D354F42FDB9749A5107C8831562E683498C55E1475E552AC10858AB9867BF8003FB88B3B09F6E8AD8E94CE82E342B1780D68EC8565FC0684AB6C798BF09FA65BE62C37A0862ABFE99D7DBE1431B4CFE007B7EC7930B14F6D161BDCAAE2217D69D9FDBB4F882B9F464F8642ACD9BA018B93A8E3A965194ACCD96E661CF0CF4A2662076E20E8BC319693F1953DAB93FEB9BCAD666832DF42F250FADBCFAF742D68642021BD6FFD97720C3E5AB86D82CE8B14C0289DBF51B50C13CFCEC12A3922DCD2DE8473329AEB23580B22F9C36B4F06D6579751BE0593120F808F0E145D94D1DDBBE1D489B744CF6C35964C3DD96D95FB693543C69766877DA80BDE8ACDF62C366D0A4A553187461F671376F7E70F554965D57760CDF5C6F6366E33B3BFB550CC1F93D98D250F90D7D36BC01581C49417546BF6BBA9D10D41C0A008855F321547BDD5A6CFA2A2516F71415B5BC2D5FA1B9B79FDC7F2B78AA113375EC1717F0F273BD8CBEF59139518A4E8A67DB4D071257000336BB07497F72FAAC2C1FC0F553B2EBA53475F466A2B36AFE0B72B4342E995C544E6E14FF7D327F80E7AC6F65190045F380B5978F50E33272484626266125A39DA08B46256624CE34223BB17299B8B8162753812F2644C9A13C51430B02ABD188DD1A4547C920BA27CDAF145BDEBC6F45EEE3F2F55553010F7B35AC63A3C7C61C", + "k": "DCBEB5E4E8B14BD3031D5916BA03258119A5DACDAC850CB483BD7AA80B7038D8", + "reason": "modify ciphertext" + }, + { + "tcId": 90, + "deferred": false, + "c": "2513DE1E55ED0E862614587FE47F308C90A1F426470CA1293BDDF7B9DDD6C368DC152F45C71354904ED48E15A1CB449B4C45D0F201ED5C7D3A047A72F080265D66C47D39469097EEEABBAA3B07ED1F1AEAB80C7D24552FA8889C674A5D4840289DE6B0FA9A222E693708D1F252DFE8B993956883C07067C1C0844EF0BEB49F63534D21D471D6B727FFC59477F9E89E5BEB2AF0CBEB052F003414DA4070008753CFC0C6D0FA9D1C15388FE5886EADD3474F28E4682C0E01784A037DC3799330EA380767B0D0B6EDFC9730E04D1039548A6F83889098522EBAB684DA6FE26A4A6891D86D40FCD9A24F743D74B23B1596810727C81BB3F9F3BADFAE9997949EE0E24987FA182A00D73DCEADF667E90E5AE76A1F83A91FCEA78C96269F0C9501F1D4CE682506A7EA89302A1480E18CDC1F6D57B5312EAF808895B20897E9A782F916CD75B4981DA1381F14EB1EC248B27F0E6966A0CD75414A735928B2120615D88FA57AF5C40E61750F0A0F8E605747E7C32D5A23F14124969C072E949C8475E3108D689D2D20797FE14618811E9A497FD26B9E71355852D4B36340B61695E3745F8D07644AC6E2C18B3FC276D4D19DB69A7CF26086F172E2BCE1618A740A0C739FD504F72C2A72ADB5564BC85DAB4C9CE790D78D14D3BD242DF04106D96CE7C3B392CCED9B99DF359FD51F306CBCBD5B46B8487CD7B7EDD3C5C02965C84630DA1B6B8B317FE55F7C79E05CDAC9E863023DAF470E9C3FB8C01FDF3AEDF2193BFA69A806E2E70151ABCF96D31CF6A317C059CA8C7D456A8E5EBAA6C1283A319F188AAA80D8301E321754E5FB4E0B25594B01BC5F82FF25B064C766424D658459EFD7A20B65DB181811E6D5A4BD153F7066BD7757D2D417D21F83D7C4CB6A0703A42032F0FD198D9D8B0F91B359FBE908432C3286E1EF9D601702157EFBAB68E0E7136BFC90D26BD8A9A7018DE4C4BF05CE465F917D20A4F221A4EE78813A1E8A117C8470929701CCC201A85E7F18B6BC96FE80B1E074661525D3FD0CE2565AB11155DAFE4D3410328D6DBB4DD99A84FE96283D32322522B88B3AA2A11C0324B1D5556EF408D37B0DF802D163FE38D7C38916A26810BD175D22762353C3175DC6040C899E07A339CD4DDBD4D5549E02C0D691263936A9F63111412B60AA9F57486334E40B2BC1B8EAA487A094E45C3F77F72EA741CE225ECBE2B5E4A1FC080070A658FDF9E2B388722855267B30D94B63C3ED35D475B7EB22E3D2462ABA9CF2A86B738EBB270AB29708A2614A557E33A620B507286E5D4CA57E2CEEDB9965FF1C3E1777F980CDFB1445BBE0B6ACBA0216980F962FBFABE265B3ADFE8641088287468827AE601B6A165DEED39C0E8773BF2046BBF63634BDBCAF98358D25FDE475781733DDE8C6D6383D13B6D48FF1B65E2FF13AAA9CCCFC3C626935C5270F9E23A71A87CF2BD793CB175D23EA5FBD82C18A1822428C32DB9E31B94BE3144ABB00F5ACAAA431C17386719C3FF47C38720B1AB01889DAD877BADC9FC716F648FC8B551F", + "k": "2C37C49E94DF715B3C09E63A39E04DB8D26BD2B9072C9B21076BDFC0B608534C", + "reason": "no modification" + }, + { + "tcId": 91, + "deferred": false, + "c": "8A4336FDDB3F55D16ADBBE54C6EF0DB27F20679393D86EA4590CB6F5F09BC4EB76181A13C9826FBD2A7174BE8A11F13759EE23DA15337A4C5612480E0A843CC6D04F3A902E144EFDC0AC118BF8553B984E758E6D7ED1373B20A5726271C5F4B542FCCD6379671CE37A5D0128F55539B9A855172CA2DA3BB6823484A87DC2333F56CBADF4A694A5DAE341A0E3FBB3D852929FBAFBF4A5C12CD3494CDF910010A0FAFBC09B375BABFFDEACCD12E6E7BD347CBFBD0C84CDABB5004CA11DDC6D14C1BD700FE3EB2371E3293F7185E2A065532C3B6529E60240E7AB6456139D66745F17B94FDF2C54B13EE4DEBF1B77099718804BAEAAACD2BC60A190487CDC76AF2EEB906E4C9F2664A30FAFB65013B8CA393793B650CAC4A93377A6511D739C2136CEC59E1BD14584989A591E1F3B7F6D7237AEDB556880810FABDB1D7F8250B61A2D16A3337DA65AEA644D7E2226BE5F24CBE01C8A33A4CCA06F6F646A3F5453FE2D9FDEA8D8613F491BCF2AEA950DB1D9B43C7C3F86FA2F4A51CB44EB9761363C38723852925247D92E37FC694D2CB00248023D5448CDE2867125250B17388440C188F7E500CEF7747A101E0BF2521E2C8A2D04F42D834C0274ECBC73E94612CCDB1C4B908BAF63C09C945AD4645912A0666E9844A1614B7F34415C1842F9B1C7DAF7EE4459A8724B7050F6B5833341691019149F351A7F11AE2416DCD5B36F18B1A4B82CC3E924114CFC126CA309E319D497A594B0AB2AFB58C19DEF3BC3AD885B29AEAC81F346A19683B8577F4A1E0F30BDC85A3814CD1196E6B29E55E5C0E4E028872477CB675B2408E136D15E54C85E8A468423CB795D9348BFCC975B4EC20A23991E6E9EF91D676983AC26B66C71548FB46C4BF06E280D7C55E7B8DB90743A8F893F95AEB4DED1DC65C5E0B61FBAD9DA0DDAC274591AA6CF23C79C09414356584F0BE02CE9B500A3EE6BD4FA0119783F50E800ED36D3A4445934DCFD87A31AF3ABC02CAC39C4B28068EECC6D16B6FA187A073BA143209C0F38AFE100BC700D461B1B364ED298AAFDFC716FA6E3870E6258B66645091FCF9413EDF6BC79B75132A46D1DFBBCE3CE9B0558EF003929CC6E3D57BC4FD3092EEAC4ED71B7B7FC70D0E65901DC9196928C5B8CF4A63C62797727C192CF1CE4315120A57D4C8CFD03143AF8754432EEBADCADBCD26C2E3A14BB43A951AFDC19EE67AAEC5DE0722E9D11E3627AD1B624ADF0FB6FD2A6733B2B1B1411DD14EE87AD3BCBBCAD2EB4A38EA00575BFA99332400083FC519C3733F6EDCCAAF71D09A7164E18A9E9587A8D9B9A46563FD3F14BFA2F2B8EBD9FDEAAEF466E591F502151E43A7E1123273E5E0574814B20253A17917D7BDF8370BC50461AC8D86127DC527B8290FE386F1AC1E6E9D7B493BB7FEDEC9E5A82DC1402DEAE71B18AB4B658E43F707259039EB9978D4FB0D62839A0DD8E3A1183CE330D57BC7927F7CCF06BA10A0478B7E2EC818195171AFF75C29B283E759F4D2F5D55F0FFC35E0581D98E582107BF64A6D80603", + "k": "47033B02A6DC056FFEB5FC1E96205C166374AB84A5F3F7B06427BB006E71A5A4", + "reason": "no modification" + }, + { + "tcId": 92, + "deferred": false, + "c": "6095A951753A644DD898D69138B4E521A704DCFAAD44EB53E284F836A469349C5B9279248AFC57AC93FA34A643DE02B724615CF5865927FED60A6B41E4AB15B4DA3599F13D2C1996C6D6989443BE6FB81F5BA03BDD53462BE5812A3E177876A102B0EBDFCB16DE7B29B5123A79DD82E5CD47ABA02759FAF5401E3BF03144A90AE957EC04DB9864ADE1C5A700CEC7872CCB64FF931984DDC3FB8D4971D761E5544130278C75A1B04E641E070A747789A71E09409C155C7D341D5F828A575EE74439155930DF22FD7716185BDF917472432A30A6762C9FE1A254442F755804D295B1698B47A67BBFDE178200F9CC3D4C705F4AC1B00C372D468E16ED3CBAAA862A2574A9574A7280878BB82DA7BD1B2A58943456838F2E6AA9F6EF1827C5B24FA09DE07E9B3153B0F44A4F2AEA7610F9CCA92565740E7295BA3AC5764A20A44D4E1862E55B1DF7913B279F438B3B34E0C22FD90E06497F7DCF8D62352447C2B8C51C214796194CDF66D5001278D0D55F82FA31DAA72BA6CDA34E60D696ED79C7056BFE97265F3D1BC07719B745ADD4A83404D91A184E629FC24AE236CF6AFAE46295D24B431D819E366F51E1BB2B44B1FB7A3060091DEA1D416268CA550EE4E41FCA1F387E941DBE4EBAE222D3CF625632D1A61414038FD437BFA20005EBC404ADCDE2DC10DB741A3B7534C40822520C4703FDFB6B380F7DB72B725B330D0C20DF256BBDDC31E0EA20E636A9FAE310185A5081923BAFE041AC6FCD4E73F5F7237142B74681F637996D28C3FDE6052243269D19316C56993722EADF19A985E579ED559F971E69EB5125937EBC80ECD15A4F80D7067905A4D39C6220EFE43883CF22E9A366F8911E21D0491B8FF61FD07B733E707A08DB400E438DAA00D481C5AC62064CF47AFE3AB08027B3890E8C8835CEAF8128F9D887A6CB7FDE879D9611C01281A0F02DE0E969C9131F8512138036EC1967DCA45AA30BE8C5B1008113E17A91D9F8E9995C07C0B13A45668C96356F09C3E08FE4C7DF5F7230E0C93EEF08E8958B55E213718C516E624B57765257D21696A3458FFBA11DE708C4EE9AF2EDC5F37458DEC8B985076882D3F4DEB00BFD8E7EA4D57BAEAEC6BABC0E28C15419CCD785CF6ACEC96D1111CDD1DA9A151F59A7366B64A53F0497D3B5A8ECB60D7C220E99126CDE82938C7E131BD841300AE461A1817703ED5B0510B47F2C2980F1E11CFBECB524B295C42187F15B0C9F6B0EB1E70B3EC43ED955528B1E42E2BCB31F3A1CFB5E9C807E8D366E9227A87784748B277D6C885B1385C6C691B3DBD7841DD89721B3A8BF96EBA99C53D4BB3B41DB9409B992BCC2D8FC53E70723CA1FDC1341A3E608D7F62F2322C6A9BA1316639690A22AECEE364B4F13949A0310FBA1A0E35DDA5FF840DABAC55041B0931D9EBEC89B78DD930512340B4B5D0877AF546FF0F342FB76B647D604EE2E20207924F39907D6E72DD4A9A1ED0B6D7364CCE69981F56CBDEDD51CBAF6FDDB36E327AD65D4FE283D253E6BF3C7969FFF1F34DCC742", + "k": "F0CF9CF06A81EE545A33B310616117D6096FB56F0D4F7E49FE0A37550320D3C4", + "reason": "modify ciphertext" + }, + { + "tcId": 93, + "deferred": false, + "c": "2AACD2E6B884BE6A3DDD80155BDCA80EBAF0E2BF714312BBA30D5B367F2D95AC7BEC3965AB05AFA370A42A512B5EFE4B0DEFF3E163AF186B725BCAFD2AFB2BD2A0DBAB74C2BF9362E27D69B6B4B5AA6500EBC9316EA4112745F1C6E98F2DEF9132C7C0BFFEAAFAF994C89B96D3F436B875178963FBC18D2E06ECAF3871787C1AE93B3210896837EC1DA87F0FD8F14AB7C5CB2531E90F415FEBDA378E5492E1DEC8243FE2E8A7BAA6FB6A034D9C524E99D848A804F150915BFD66067C8603B5DB0FE29E27D3F6CA629E96BF3E9C77A5919701EC19646C69A73DFAAB0ABA28FE3E9EAAEB475A441B9B0D62B259DC6B77DEC964AB57D5D776988D54E6246C526F1E8EFDF454E7F0DDAED5363CE02B279CD3B554C251793C3A616C07A7BABA8062919A2B46C64C152BC887A27E382254EA6D50CCC0702B7BC0994BAC09B7891FA64A773AE0B4FBF8204C13A4950FC2C4DF60CEFED7582FD9FBB8C83442517BA0E3B60D9A04FBB24ABCECB303E3FDD37F1037741FD2489F632192A6B9C122A7344CB781A0F61D5011EB0251A842AD4838F9B8D52E21A783F0D839E8BA221CCDD6B968A2B5FD21B8458BF53C9C8076AC0C52C0F53097ED1C25C9F6F12407772D6743EB8E0CE8B1A926F0FDD0DB00482D9590675E56D4509CB5E5F32FC3B4A2DAB2BA080F9A7CDD0B611742A8F83CEE1B091E629D2A0371FDB5A64412B5FA63716961527640D02885C4A09B04A3A6F5EC01A9E0DBB8FC4DDD9E05BDB240AC4878F0D41461C4661777417D6150422FEAB6A39F156CADB5F5D3BEBE417BABCEFF5AAD1B7A624FC23ABE28B2AB2E8273E8F44636A60CDAD9236DCB02FCF87722C899AA321C564B25BC33B4976BC9603BB8B8AB18B5B04625981FB38B2A42722CE2358FC0BA99EF4B122C7B70BB347D0D482DA30638EF8B9C1D9121D83BCDBBEB2A608617054F4B3FDD33E9A08F8DF999A98E715DBF04F8EFACF123BBEB37B9038E9AD906E3C570BB398C10E6D36647A2B0B2731FD39F726171EFC7321BC67D936F7989EA58336E549A34B73F097E3EA2C25887EC6A2E9FED5D2CFF475E99F392162D959DE1C4A4DAD3C96542756AEC3367F7B2515F2225BF7B704B780A6D0B279B8B4EE4879A9BBB2F3303216CBADEA00D229C03E3E2843892FA8E5B0A600D0E3EBDD14FA229819CE9C10B8D5F393DE0119A5B509B80D56B06783447F931177123824910C9BFDE9A29FBA0252E69A90B3E717832866115C06EA73B033EC3B0D45DFDB69A76B484DB0BE7A81215B3817E1C02F9A5DEE8967B147DF9F63C93A6E396DE4251A5A706DFDE9670B8B2F6C4C3E2509142256FDDA905C125FBBB294EB29A3B4D9BE3B67762AFC049B96B3F41B8C31BC5D7B522DCD1AD12B252370A8A57E42F6A9AC26FF784B374DA4B86FFDB65CC753CD049F1A21CF832447E1DF7BA7D0D11E403FC18BC545501E16568595AEB6BD7811C214CF2FB1CDFB07BB32321F536E3896B6EF4D16130ADD71B271CD1027E35538D9E475A3A53DFEA430C151DF7D516CD0D9B", + "k": "0EA983FF9D76F056AA42BB772AA27C8A163172F43E6BC9BC55B83038E095792B", + "reason": "no modification" + }, + { + "tcId": 94, + "deferred": false, + "c": "8FFBC80E4662864D6F373DC8837AA91B3CC26B68124ABD73DAD025A1D1C18829DCF077D303579E5F39F4BE101BB9E355DFB5323882EACB3D184E6812C03A7BEBE25166D55F821A00F80B8D2BAB1A7EEC83D384AFDF30F6BBC9960C4662067EF7E200E37268B9F5348FF484642799258B45E541101A21FDD6FBFAA2374A28FAA97204953B95BBD1BB519785210DA7C8A09D071D8AFC9B29F2C3C2909A4C53671408B8083BCF5AE03D45C0CFBA399F44D24A06321BB74F6863B7D4BF0BFE73C8AF8EE1DDA45212E3F9C853D4D0E16F8EBDB8581C4ADEEE833D81A9E0A9E8587E9C19E689E6DF715564BCE27CFA73BA16226A77CE44DC496992F41AB918643C6D86A8B26ABA6F94F3502D22DD94FE55483F67C635B307745D33F17133293639118E70CE42C6DB7332D4862C73D5B84415454AD51F89B5559B5C85D6B6ED47B6958F21FBC2ADF8C8A9D43FD2E1B0C02418D227B83F85CBC3A81C719E8602781AE71E15E6D714919E52FCCCFD9A68B4751825BFBB53B7940B15B546158DBBC612E602F660B9E0FF439E0156C4C8792346014BA1B4838C7425AB34744DE51D854CBBA58B7E67E014122518036CE1541A1675AFEAE4F29A5318602ABBD0A1540F33176C984E306098DBD08E822ABB55F9FF38D9E31EA4695150F2CB60BC2EB5F4780CBEBB210CF48662C454C7A42360F306FB03617C998AD8A9297D6B71A71285F7AE8DFB336FA922540C92DC71F777D3B4D11D87B8D082FA8A00DF647CF7FEB27403D3CF50D829EEE3575A01E2CCA57849B11B14F001BE180DD5FA13C03B98EDEA6358C5AB30A526027CB45E33E646B37988CC84B979CC5CFC3BFDA05BD2C7B8CB1B11AFEE007E20FCCF8D0F764F4A6D2F6A8B74281800CBDCBBCF0DF1EC9D27E6A94968604D9EFD37928B6856C48F0108155595D03231DFC22DC0C8EE614090F37E0828B48A4DD371C677B5DBA95E417F12C9A396875FB05623F7A544AEAE41A0AA536FB8D767BA2E14752C84E147149F655AE7B903CAA591AE00267ADD3EA816612AB0B9A5FB263C70C4367062F7794274C75AC66F706AE93699859D55B2E4960E9D538F38A2FAEE366B80DC78BB673A9E1B057D711F9DDB3770947E6DD7BCFB425B96670506758AEA39A5ECB33A1B76B822AF903787DA3B61A7B9263C0FAE1B729B1A2E16FEB50C32A8728181D4E8A9F8376C39F6AABC2C022306B05E494CF9B6ADEEEC95887440508981D6A74707FCEFA24B9F0DC3AABC984E9C44174E6DFB51FCF4588C57F9659A8E7A6FAEAFBAE7ABE4600444936B3763463D4AE411DDC1C98585E0DE58867251079BE72075973275141801B98F7B9397C096A56B8CD83CFBD374E182F7DCC9A7C764DBBF4D7576A1CC9239848E7295D29CF034A1A7AE33A386C3DDC24A535168ED23D7ADE9433B50DC5694C969F4C546EF2293CD842F4B62B6B7435F597CF5C1733884E0A6AA47FA31887DEDC6C402D8ED013E49E5CAD7718CCEFEE0E6A041715CC9ADD79965413049ABCE88636AA7543EE2601F162838EF6B", + "k": "342765B77A09BA6863F2ADA782E3719803F7AB714EE807DE89A1617B5C74F60F", + "reason": "modify ciphertext" + }, + { + "tcId": 95, + "deferred": false, + "c": "17976BAC62F66CEF2B6F947C121079B6F2E9350C137E738BFD884FF2BA6E211640A30FBF2695EDF7046E1F5234AB1C8A9B0E8A3FF88EF18C1E5512D5F69E4A36CC9362F00920481E5460B1FB0C2B9FF0CD0D95718966AF7EC1F76B8DA93F6AB179A5DE70DEE34C579E284AE8504ED96E1A85898076F69AAFEC1357533EBB636FBA2372204DAB87C47AF27D4D9EB1B4FF4286D6A9FA7FD506C9FEBA596D2047DB765C1EBF1F7921867D394487F6BE926E6B0323058CB591195436ECC805C8B88615C7A03833AABF490337063DFEED698F7DA8DD589A794C956C2BF8D8CA4AE18B0A7767693802BD6DD53F543E105EC526C1D1D00AC9C0B606BD9B3A1D52CB8C56F8535ECADD8239308F2FE7E1D7BFAC5848B547B4579AFC13A0B2BEDEFA46322F92E2B73980695369C5F48D37F9345F20C7820DB6DE09D5E8313B73ED705B33646FB14CC4D40D65290A4C27360FBBD080E61A16BB15E9560A097E4AEC16F8B8030FAE1D47E024F10C33E6A1C56AEB8EC2F6AD6EF4B8FF04C67307B23E470FB3E5BCB6F533F955C36FDB46516A07DFF2956130AD0924158CC2A083378FB9AE32DE89CF774D82C2FC70DA48536372299C61927A5AE67E55E792B64FE61F06EFFC1F216CC9D739ADBF3B2190E1D080E00F169F145FE32AF7EC7CBA1D76FA6839D5FD2068E1DFFF557755FF2F4271204A5468C79C7BB8D00FAD63938F12D53B243B3FF866556913EB57AD2AE034F8B62B1A1B9DA2B1D45800B4CEF1E1943A0C92F0EF2EE924F80CF67EBD3D0199D45ED4DCC00140829A0992DB43616CC468508B852EB822066A05CC91D6BC2B47E5622B774F8128ECBBB94CADD15588B36A71E9FD97B05D69E8BAF00D30A3D3C00E663E00AFC9F5E1BAC8534ED5F6E5AB47D7EFDF6537753408299A9E8D5F5AE0FE36A9EC41C6DC9F78A891BFA9C8E90AA1A457A0C01AF70CBC9E55B68A5D8CC5CD3BD6886AE11FF510C6ED0EB2F5C081B25989518BA217BC1C153864E5BB312EF0D43D6DA4A0FDE44F1157CD238E8D70BEB420BD310F8E5DB9D74EF4EC9980CBA74358FC77C5D4FAE3036E176647D78C73900C79BFBF0BC545ABF7CBB4DC7F6041D4FA3B66E4D4655E24B11DC30B0061C452A605CE73362F2A3F052370D873FC68DFFCD3999FDEDB45DD9F2A02B4699BCF1FC5F888B019B5028465F30AEFAD946D481285D1122EA78F3BD8B1982558C38FA3DF0F058B12EEBB11F4C7809F6334EA1D7FE0B529C0BC9C67044648178D2AE9232E4E88DD6D0016D8A590B7703F1A017A4A2671BBB24FA97ADE1B61C489AFE9B3E63CF4CCC42168C98880921C2C0EA7D24DB6DD676B77F7B6C0525C8D0578C7F5A20DBF2F82873904D7CF2522CE6360397B254B18C3059A4BEA169A44D9BA17CFDA1827EABECD269FD391CBC0D49D71FA81AC16F9A0DED9E72A58D1BC2262979D8D7E531D1C46A8F107BDA18A1D2CCD17334183DD3E79D905ACA7DAD348BC6D5CE124A1397EB3B89BE7580720B5DD00BD3A63DAD813E0E967EFEDF17F3D960E70A4F83F", + "k": "F175CA29D36784E3B7A6F6D8682DE3548115C25EC1751DAF6B5FC3318F690802", + "reason": "no modification" + } + ] + }, + { + "tgId": 6, + "testType": "VAL", + "parameterSet": "ML-KEM-1024", + "function": "decapsulation", + "ek": "3BC1858826C6B39279C2DA7438A370ED8A0AA5169E3BEC29ED88478732758D454143E227F8595883297842E6AF133B17E4811B0F5713AC73B7E347423EB92822D2306FA14500A7207A0672672046544ACC4EA9C16ED7421A069E0D737A98628519C6A29A424A868B46D9A0CC7C6C9DDD8B8BCBF422C8F48A73143D5ABB66BC55499418430802BAC544463CC7319D17998F29411365766D04C847F3129D9077B7D8339BFB96A6739C3F6B74A8F05F9138AB2FE37ACB57634D1820B50176F5A0B6BC2940F1D5938F1936B5F95828B92EB72973C1590AEB7A552CECA10B00C303B7C75D402071A79E2C810AF7C745E3336712492A42043F2903A37C6434CEE20B1D159B057699FF9C1D3BD68029839A08F43E6C1C819913532F911DD370C7021488E11CB504CB9C70570FFF35B4B4601191DC1AD9E6ADC5FA9618798D7CC860C87A939E4CCF8533632268CF1A51AFF0CB811C5545CB1656E65269477430699CCDEA3800630B78CD5810334CCF02E013F3B80244E70ACDB060BBE7A553B063456B2EA807473413165CE57DD563473CFBC90618ADE1F0B888AA48E722BB2751858FE19687442A48E7CA0D2A29CD51BFD8F78C17B9660BFB54A470B2AE9A955C6AB8D6E5CC92AC8ED3C185DAA8BC29F0578EBB812B97C9E5A848A6384DE4E75A31470B53066A8D027BA44B21749C0492465F9072B28376C4E290B30C1863F9E5B79996083422BD8C272C10ECC6EB9A0A8225B31AA0A66E35B9C0B9A79582BA20A3C04CD29914F083A0158288BA4D6EB62D87264B912BCA39732FBDE536A377AD02B8C835D4A2F4E7B1CE115D0C860BEAA7955A49AD689586A89A2B9F9B10D1595D2FC065AD018A7D56C614471F8E946FE8AB49E8226591119FCADB4F9A861631378736B6688B782D58E97E4572753A9664B6B8536812B25911AA76A242375433192738EEE762F6B84315BB3436231E0A9B277ED28AE0050728346457E13405062DB2804B8DA60BB5C793D4CC0E101CBA2D9182FD7124FF52BF4CA28292AC26D678088953971DBA0B6FEC2C9659353291C70C5B9245A0CA253304AFD3C95102BEA66875C6201680B4BDA38687B648C28EB37478E3BC00CA8A3CC27204642B42B68FCBE7B21A366D0668A5029A7DEEF94CDD6A95D7EA8931673BF7112D4042107B1B8B9700C974F9C4E83A8FACD89BFE0CA3CC4C2FCE80A03D3576C222A792B72B1F070AB7F6B6F2B5CA2AF5054AFA70A896990159B45D1003E2A05648675E596016F1B71DD0F7BDA7E2097FC73B3A143D12C726020AC34958AD7062B92B9ABF3CA6BE5AE29F57135E625A367971837E6363D1532094E022A23467CF932E1F89B5B0803C1EC99B585A78B5865096746F32258214ECB38065C97F455E155ACC2DD005A9C76BED59CDA73837D303504E6C976A606A2BE7BBEC5948B91A349E8936688CC0279754B743ABC58666B19B6C3260051F19206BB962BB6633EB0048E32BAACC5B020D02C86CA9770AD469DB54A106AC73A35B8057422B3DB202C5A5B4E3D535F0FC99326C4B8B7B16F1CB5AF96803FA8C195FC0BCEDDAAF012A51728B76489082373C91E92C87ACCA795160782E3B0DD643544BB96ABC2708D49B759CF057AA223BAFD96A330BAF39810FE8671B4343C297DA1E1969C996216AB5106DA668941B160D4477017136CBCA5B5A8D44C4A8B1CF3EF79785E5AA25C3A1AD6C24FD140F79207DE5A499F8A1534FFA804AA7B3889CBE25C0414704AA57897F17862364ECA56258007248813912B836497F0359C2F7238A05D305A0EA152E72B44417A868134E91B3CA7931232FD4C25F8C2A492A339CDC0A138967211451F2562678FA14080A34436C42B07865AC036A81E97A7787A938025CAF813450368BED0C94B1857604526405D27A1C1ABC81B5B6EC13C71930A97D9232CF7021EF87A4D155328E62B583A83B4AF21F9F5750F8575150424F63B899D71CAD267C09E4467146E16E9B6C653F008C311375E2E006D4076A546B82F5314222F7C654317E79EC6035B73FAF491757E61C828326D53044541C4D4537ABD3EA1E67998C3382974CA78AE1B1960E4A9226B0219AB070F0D7AA66D76F9316ADB80C54D6499771B471E8168D47BCAA08324AB6BA92C3A70275F24FA4DC10E251633FB98D162BB5537202C6A553CE7841C4D40B873B85CA03A0A1E1CFADE6BA5180AB1323CCBA9A3E9C53D37575", + "dk": "8445C336F3518B298163DCBB6357597983CA2E873DCB49610CF52F14DBCB947C1F3EE9266967276B0C576CF7C30EE6B93DEA5118676CBEE1B1D4794206FB369ABA41167B4393855C84EBA8F32373C05BAE7631C802744AADB6C2DE41250C494315230B52826C34587CB21B183B49B2A5AC04921AC6BFAC1B24A4B37A93A4B168CCE7591BE6111F476260F2762959F5C1640118C2423772E2AD03DC7168A38C6DD39F5F7254264280C8BC10B914168070472FA880ACB8601A8A0837F25FE194687CD68B7DE2340F036DAD891D38D1B0CE9C2633355CF57B50B896036FCA260D2669F85BAC79714FDAFB41EF80B8C30264C31386AE60B05FAA542A26B41EB85F67068F088034FF67AA2E815AAB8BCA6BF71F70ECC3CBCBC45EF701FCD542BD21C7B09568F369C669F396473844FBA14957F51974D852B978014603A210C019036287008994F21255B25099AD82AA132438963B2C0A47CDF5F32BA46B76C7A6559F18BFD555B762E487B6AC992FE20E283CA0B3F6164496955995C3B28A57BBC29826F06FB38B253470AF631BC46C3A8F9CE824321985DD01C05F69B824F916633B40654C75AAEB9385576FFDE2990A6B0A3BE829D6D84E34F1780589C79204C63C798F55D23187E461D48C21E5C047E535B19F458BBA1345B9E41E0CB4A9C2D8C40B490A3BABC553B3026B1672D28CBC8B498A3A99579A832FEAE74610F0B6250CC333E9493EB1621ED34AA4AB175F2CA231152509ACB6AC86B20F6B39108439E5EC12D465A0FEF35003E14277A21812146B2544716D6AB82D1B0726C27A98D589EBDACC4C54BA77B2498F217E14E34E66025A2A143A992520A61C0672CC9CCED7C9450C683E90A3E4651DB623A6DB39AC26125B7FC1986D7B0493B8B72DE7707DC20BBDD43713156AF7D9430EF45399663C2202739168692DD657545B056D9C92385A7F414B34B90C7960D57B35BA7DDE7B81FCA0119D741B12780926018FE4C8030BF038E18B4FA33743D0D3C846417E9D5915C246315938B1E233614501D026959551258B233230D428B181B132F1D0B026067BA816999BC0CD6B547E548B63C9EAA091BAC493DC598DBC2B0E146A2591C2A8C009DD5170AAE027C541A1B5E66E45C65612984C46770493EC896EF25AA9305E9F06692CD0B2F06962E205BEBE113A34EBB1A4830A9B3749641BB935007B23B24BFE576956254D7A35AA496AC446C67A7FEC85A60057E8580617BCB3FAD15C76440FED54CC789394FEA24452CC6B0585B7EB0A88BBA9500D9800E6241AFEB523B55A96A535151D1049573206E59C7FEB070966823634F77D5F1291755A243119621AF8084AB7AC1E22A0568C6201417CBE3655D8A08DD5B513884C98D5A493FD49382EA41860F133CCD601E885966426A2B1F23D42D82E24582D99725192C21777467B1457B1DD429A0C41A5C3D704CEA06278C59941B438C62727097809B4530DBE837EA396B6D31077FAD3733053989A8442AAC4255CB163B8CA2F27501EA967305695ABD659AA02C83EE60BB574203E9937AE1C621C8ECB5CC1D21D556960B5B9161EA96FFFEBAC72E1B8A6154FC4D88B56C04741F090CBB156A737C9E6A22BA8AC704BC304F8E17E5EA845FDE59FBF788CCE0B97C8761F89A242F3052583C6844A632031C964A6C4A85A128A28619BA1BB3D1BEA4B49841FC847614A066841F52ED0EB8AE0B8B096E92B8195405815B231266F36B18C1A53333DAB95D2A9A374B5478A4A41FB8759957C9AB22CAE545AB544BA8DD05B83F3A613A2437ADB073A9635CB4BBC965FB454CF27B298A40CD0DA3B8F9CA99D8CB4286C5EB476416796070BA535AAA58CDB451CD6DB5CBB0CA20F0C71DE97C30DA97EC7906D06B4B939396028C46BA0E7A865BC8308A3810F1212006339F7BC169B1666FDF475911BBC8AAAB41755C9A8AABFA23C0E37F84FE46999E030494B9298EF9934E8A649C0A5CCE2B22F31809AFED23955D87881D99FC1D352896CAC9055BEA0D016CCBA7805A3A50E221630379BD01135221CAD5D9517C8CC42637B9FC0718E9A9BB4945C72D8D11D3D659D83A3C419509AF5B470DD89B7F3ACCF5F35CFC322115FD66A5CD2875651326F9B3168913BE5B9C87AE0B025EC7A2F4A072750946AC61170A7826D9704C5A23A1C0A2325146C3BC1858826C6B39279C2DA7438A370ED8A0AA5169E3BEC29ED88478732758D454143E227F8595883297842E6AF133B17E4811B0F5713AC73B7E347423EB92822D2306FA14500A7207A0672672046544ACC4EA9C16ED7421A069E0D737A98628519C6A29A424A868B46D9A0CC7C6C9DDD8B8BCBF422C8F48A73143D5ABB66BC55499418430802BAC544463CC7319D17998F29411365766D04C847F3129D9077B7D8339BFB96A6739C3F6B74A8F05F9138AB2FE37ACB57634D1820B50176F5A0B6BC2940F1D5938F1936B5F95828B92EB72973C1590AEB7A552CECA10B00C303B7C75D402071A79E2C810AF7C745E3336712492A42043F2903A37C6434CEE20B1D159B057699FF9C1D3BD68029839A08F43E6C1C819913532F911DD370C7021488E11CB504CB9C70570FFF35B4B4601191DC1AD9E6ADC5FA9618798D7CC860C87A939E4CCF8533632268CF1A51AFF0CB811C5545CB1656E65269477430699CCDEA3800630B78CD5810334CCF02E013F3B80244E70ACDB060BBE7A553B063456B2EA807473413165CE57DD563473CFBC90618ADE1F0B888AA48E722BB2751858FE19687442A48E7CA0D2A29CD51BFD8F78C17B9660BFB54A470B2AE9A955C6AB8D6E5CC92AC8ED3C185DAA8BC29F0578EBB812B97C9E5A848A6384DE4E75A31470B53066A8D027BA44B21749C0492465F9072B28376C4E290B30C1863F9E5B79996083422BD8C272C10ECC6EB9A0A8225B31AA0A66E35B9C0B9A79582BA20A3C04CD29914F083A0158288BA4D6EB62D87264B912BCA39732FBDE536A377AD02B8C835D4A2F4E7B1CE115D0C860BEAA7955A49AD689586A89A2B9F9B10D1595D2FC065AD018A7D56C614471F8E946FE8AB49E8226591119FCADB4F9A861631378736B6688B782D58E97E4572753A9664B6B8536812B25911AA76A242375433192738EEE762F6B84315BB3436231E0A9B277ED28AE0050728346457E13405062DB2804B8DA60BB5C793D4CC0E101CBA2D9182FD7124FF52BF4CA28292AC26D678088953971DBA0B6FEC2C9659353291C70C5B9245A0CA253304AFD3C95102BEA66875C6201680B4BDA38687B648C28EB37478E3BC00CA8A3CC27204642B42B68FCBE7B21A366D0668A5029A7DEEF94CDD6A95D7EA8931673BF7112D4042107B1B8B9700C974F9C4E83A8FACD89BFE0CA3CC4C2FCE80A03D3576C222A792B72B1F070AB7F6B6F2B5CA2AF5054AFA70A896990159B45D1003E2A05648675E596016F1B71DD0F7BDA7E2097FC73B3A143D12C726020AC34958AD7062B92B9ABF3CA6BE5AE29F57135E625A367971837E6363D1532094E022A23467CF932E1F89B5B0803C1EC99B585A78B5865096746F32258214ECB38065C97F455E155ACC2DD005A9C76BED59CDA73837D303504E6C976A606A2BE7BBEC5948B91A349E8936688CC0279754B743ABC58666B19B6C3260051F19206BB962BB6633EB0048E32BAACC5B020D02C86CA9770AD469DB54A106AC73A35B8057422B3DB202C5A5B4E3D535F0FC99326C4B8B7B16F1CB5AF96803FA8C195FC0BCEDDAAF012A51728B76489082373C91E92C87ACCA795160782E3B0DD643544BB96ABC2708D49B759CF057AA223BAFD96A330BAF39810FE8671B4343C297DA1E1969C996216AB5106DA668941B160D4477017136CBCA5B5A8D44C4A8B1CF3EF79785E5AA25C3A1AD6C24FD140F79207DE5A499F8A1534FFA804AA7B3889CBE25C0414704AA57897F17862364ECA56258007248813912B836497F0359C2F7238A05D305A0EA152E72B44417A868134E91B3CA7931232FD4C25F8C2A492A339CDC0A138967211451F2562678FA14080A34436C42B07865AC036A81E97A7787A938025CAF813450368BED0C94B1857604526405D27A1C1ABC81B5B6EC13C71930A97D9232CF7021EF87A4D155328E62B583A83B4AF21F9F5750F8575150424F63B899D71CAD267C09E4467146E16E9B6C653F008C311375E2E006D4076A546B82F5314222F7C654317E79EC6035B73FAF491757E61C828326D53044541C4D4537ABD3EA1E67998C3382974CA78AE1B1960E4A9226B0219AB070F0D7AA66D76F9316ADB80C54D6499771B471E8168D47BCAA08324AB6BA92C3A70275F24FA4DC10E251633FB98D162BB5537202C6A553CE7841C4D40B873B85CA03A0A1E1CFADE6BA5180AB1323CCBA9A3E9C53D37575AB1FD9E7316C6FEECB0A14DF6F2DA56C2F56F55A89635CFCFDA47927AF1F0A47B2D4E4E61634B1B51D37A3A307A972420DE1B7A481B83E583B6AF16F63CB00C6", + "tests": [ + { + "tcId": 96, + "deferred": false, + "c": "0C681B4AA81F26ADFB645EC24B3752F6B32C68645AA5E7A999B62036A53DC5CB060A473C08E5DA5C0F5AF0E5170C6597E50EC08060F99B0C00EE9BDDAD7E7D25A22B226F90149B4CE887C72FB60AFF2144EA2A72383B3118F922D032A16F554289902A14CF7755512BB1186BAFAFFE794D2B6CDE90109E6582D39CE0C96197484B3FA07FC91D394FC8D88E7FC4BE002E2DB56F0C4D9D3FBDA274536A0B86ABC6E39BDA52931AEBB8F1084C5C1F7CB3177788B7F331B7074361163491D428E78BCBB57B630841AA987333377CF09569CFD14CC2A11C501BDF82C93DE05BEA20060DE89C686B824571CEF94AB3FDAFA8512619813669D4F53637FEFA4D028CB233E56930E2235F7E6034CA94B143B77AD4A68756E8A9184DBA61A89F91EDFB51A39211402473A5F89145736B2BF8569C705B0CDB8980A447E4E1EAAD3E7E0578F5F86B8D03C9DAFE875E339B4423845616799EDCE05F31B92664C5A59253A60E9D89548A300C1ADB6D190A775C5EE6E8A89B6E779B034C3400A625F4BBEDBF919C45B2BCD14C669248FC43C3EF47E100758942E75E8ED6075A96D70D4EBD2B61358224DDA1EC4C19C2A92898176FEB3C02EDCB9908BAE49BD94AF028EDF8CFC2E5F2E0BD375006986AD49E717548E746FEF49C868BCEA2790AA97E04061B75605CB39EFD463D7B3D68BA574434FF7BE8E2B84BFC47E67E9CD15F3ED450C61AFBA79A20B0B6F287777C72F4AD248174F1959477AA7A7C97F122C50447C7484F382BC47D81FCC9C7E892C8839D37B35394B53E6B2B1895ABB0DE8C98F2633DC4413A8D5735DFC9A64026B6F34779D6AC8AD99CC31AA898C2E7057F3DB8A1A8A98527A79E43552F28D1023E1F6A6B84855CF5E6DF889BA269F048946E84021C65C5A93B007B07741C1EE176C73949110F548EF4332DCDD491D2CEFD0248883F5E9525BC91F30AF17CF5A98DD44EF9A71F99BB732985BA10A723EF476FCF966DA9456B24978E33050D0EC90D3CE46378851C9ECFCFD36C895D44E9E506993082523D26185766B23568CB95E64108F89D1014747C67B6F3C8767BE5FC341227DE9488861C5FE811409F80957D07522A72CF6AB0378D0F2F28AF548185C3936777994466A019D33B18A54F380A33892AB4D4BD507B5A61D0D358341AC92F07B43B8F6AFC6991BB6A1EAC23CA6F73E91F2464BD119098D7E768E77ECE53FB899BEB42265ECF7B271F66546282D472C36239006BB0ABABCCA24550BAA0A601348C810FF5F9EE504BF7155DEE4141A11605A4F3509AC9CAEF6624D21DE332D5D50828B52E92885D3B90553B14463AFB1EDCCD3B569B5A7F00BB66769DADAC23AD8BB5D73A6F390E6FC2F6F8EE3CF4009A5C3E1EF60E8F040672D262E6490379BBC70495DFF237BECD9952CD7EDEB6D1DFC360B3FC8B0AF480FFE024AEEFCD4E9CE95D9B469C9A70E5110DA0BAC124FC3741DCF49116261796504D5F490B433C33C40EDCE2B75151DA256A868A5E35F86226B8151C91934CCC3DACA391DECCA745375660B6EC41AE5D810838CBEEFFA12557884412357B1008363D32B237AA1DD8E2D9C6367ADA09B2C95060206CEC3EED391FDC5DBEF6F08BDF0408E585AE5EBC8E9745D44FECA975ABBC140BB37B8ADD16FCC2956910DC72BB3F02E9A130C9A84F9CCB74D134CDF40AFCBA2009C8F0040239BC99220EF64C4DCCDE2E2E5C9B68602FBE8EF4C98B3468C79DF4E078511BFB8AA3DA09597A02511E7C21A7CF66A93843A94868F19E8552552E3ACDF6CB810634DB97CBC4BB569709DAD4845645446FA8D289FC59307B801E60CE2A91E06E9C22C16E2E59BDE38A416BB1B4AC5457438FDC5D64450A89ECB832C1BB279DBF59334681776AC00409846D09D6F687772E340850AB8673384215E12C8D0F531C451E58493E0EE415AD594DF38C34408C7ED9F0C392F1534604EAC3D9C15465A9A46632214B536990D78078E5BD7EAE2013FFF8FDD8B275C89D97C9353DF3C42A28E814D8468E2B48DB0976D88F5EECEFEAFB8F7F4AF291A728F6249ECF5622339269AA945329E919F8B441C83D5507F30DF0FD2B13FF806F522DAA11AF676A513C149C70F0D6E99A880450A54E0417FE3C1E513E9D920E30A8B42891267A2DC50AD81F98044920C099DF22C73998A25C581A5178C72B17AC875BC68548A0FB0CBEE38F05017B12433343A658F1980C8124EA6DD81F", + "k": "8F336E9C28DF349E03220AF01C42832FEFAB1F2A74C16FAF6F64AD071C1A3394", + "reason": "no modification" + }, + { + "tcId": 97, + "deferred": false, + "c": "4F90106FF7C3DC4E47417F31AB56B1C5E426C1ECD5878AAD2B705E75062DA5FA6F4D18B704C941C6C6D941FD21191A69210BC39E24950D9F851B6DE8CE30023DC7536439104D42245F3E04E6AA6763F8AC97ADBD04CC69547BCE0BF290FFB5D12946301174AF1B0868C14D4293FA9DCC5B23F809B02CC78DEFE7F27935B9B681E531FC21CCB2AF8EF6144D8498E63E0EE48AF8D4CEF7AC1F669AC740B06F79DDB58E794F2FC2CA832E05A0374C18A4F2CC78343EEA064ABC5F468F4DD11E0B6E8FA1D18A221D8241450C05EB9EDF90D9D7F666AC82E7FD44AF9328E0BC6004D5B114E80E9B980D18E081D771DFCB2ACFD40142A2EB33234F75733EAB7D8EE8A5A6F796681A4A8AF85CCE86971B821D4AD8371049E94E280B77B15D111A42AEADFC08D4F804BD78885443E81A393DF7C8754C460915846E09A0596587460038F55D06EC21434A1C2DF44D0C16706E8D2B83F0E7833976EF05BF1D9F0DDC9A37597E401B817C2BEC8E02EB9DF7591E239F25F8648E7F2F4F673093BD9CB703DA32B353F58514C6AB55748B194E52F153D52F5F33FE95C5F9F65EA97BA721E8DDF333B64D233A867A12701E00C5D8A9B5AE344F3D847C27C079DCC9C3B40EC4604A9F041E7987E8B930C658B9A132DE4E422C0E27553A2A0EAB8C859EB0E5677E83272725C5C1652E61B9BBF5C9C59BC2357A4D1DB9C607F34DC1BA074B84DFC69E4097A7AD2BA9A58000027296AD39FC1CE218A5EEC7ADFA8AA3B9100B0B603CFC83C152589E12E6BD9EE10C49131A701D315DFEC38E018328916F9FFAA7305CFB66781707D2D1020EB782F9F003DB4E46B87D693F62E8BDE170141FF71F26DDF5310C00C9163655F5217DD2C8B0466AC89DB55BD7FB3B0964BC9009E9686185117DCB50D6D0297753CF7F1217E819EE60E3F0FAEC4A5AF0C2EA83CCDE15CF045C6961DE8FF6235C9D93BA4C89B7A82A7471FCFB0B8EAD54D56E8A1DE21B3933AC5B4A0689EEF3598926E17BBB16AEC61EC30A2CCC0E0323EC282887C108C3A4E83E3666493D8653D0E92443808C79D770BFF48A49E65AE089FEC790BBA4C66354EF67A334C1EA5C6C5707B6928EBD1BDB6A940FA242C6EBD7F3E71272421C9082841A6CAD2894BB8AC85F105D8BBC9E6F0A3DF0D7C46F6E2F4CAB904ED157AFA85D4A852220A9636E1E8821643A9E4028D87A430432F09354B3973182385CF5ABFC8F84982BEE0BCBF5D18637399163A09EB45711E07C4458498C76979107CF91B3FC590EA4AD715D656D5E56DC32146580101C952E02ED7017960D54CAACCC70607196980ADBDAEA420A52C0559ED23C9514F8CA7AB7F3BAAFD2FAB58960A64128D5A50E9AD8DB7D23A90CE64C1BC349D118D3603358377F84FF5A64457FA1CF41B27094BCA72360BD429415B9EF9ACCB7A5D7B9E5F5FDCA8FCFA4592E91D7E5120DF7E3C6675AF2211BB94D856A5D2285FBBB36984A1345590930B13232565D54812A9345324C232653190323CC67C840E478D09E6DDBCF999F7AA3B556F80332E67ACA41EC0661088D7696BB64E9A98A0749FAA9854D9B48754023BACAF3C8081A46157C6453BDC89341D3092F3B5337874CE5DE559A56A2FFB7F401F6E28EECAF4FDE5B60DEA73D6B2182EF68E07A8297F3C959E17139B5DEDC72C7A0E103AFF866E89D1F62A1F6B97B61BC059BDE5A2A06087EF783A441F23DD191C692D03C097FF9EE831F7715C6E508BF475E79A8353E84B06A9356045C8FD09FBA35879069B9A3F478FBD051143C13D753BC45F3040E85985EFD6B149EFA9455A18E2894E6EA0BE58F451FF1156F93CC7117B5D091E9DD50D41BFCCD44F2C4EB7812AEFD13C8B68D7F0103BB6CA38D233B6AADD01845B7E44D13C1CB1577D6C4354B063991344787F8C0BE667A7440B98917AD64CC2EF2BC82EFC3398B3B1B238540756CE9FC5EDD26CC20E761D592A1A0530AA8BEFCFE8DADBAC99A417CA0827F4983FF5BE656669F2B5F985FF6B16C44BBEA131D1FCC70FC53BF31EF225D1F5D41863B51B57EA65C6164F7531AE492EFA64161B7DABA3EF4586F3459BE8A962367DC276597B98E91FF594EFE8849BAD4CF91B9E5F244CF03CA9615BE128E96958533544A56E735994B92E4EF0D5FAB54B78EC66641C7463F225D261C144F00A0270741D7A511994833635A8A9B670CBFBEF239BF83327E247943B205DA68DB94E3F3", + "k": "7545CC458E0A274A83B13554224F0BD01D57CC4775AD12468D3FEE5B08C93A6A", + "reason": "modify ciphertext" + }, + { + "tcId": 98, + "deferred": false, + "c": "26CC4F22E035BC00687D557655C46B6E1C447ACB824204FEF7582EB8DBC704D7CE72B0A5FFE54FB89BD7B779B5B1DD1573010B227473FDEFFFB74DF7DCC1E6B48B554563C6C23004AE2CB1996943821F480E91081F1A6765E08A8AAB7F203E95DEEA49A1129A676DCB21540D2AAE1B21223DDDF1453150483176F3EA3580CE631FC85508690D8DDCBC9513A4A5951A440232223FB2ED9E0E5A8ACFEE113D22548B8E98131EE1F45A33656F079870A146F12819BFDDF8792C3C9AC3BBEA3A92B8606FF2B7296DB9D9782C8E788AF4C961840041735DE456A35E5536D861CA118D67408E84D8BB9128B65F2C11C7147EAC928599979EF195A7979CFC48277CF1FDF4B0CAAEB3F8A172A3CA25A3A8C39AAB4495A70E0AFD3861C41A8C01FAD1E9D81281CAE1C33572BA4BCA9A5294000FFD040545B021AF583F56434ACCD4CB7B788517243B09737D355ECE53273FC0C492F251FA02E47EA846121DFF00CBF2767D4DEB25F705591D26FB1B6F839A58EBA4572745A618CB2EBE02CC0CB1C62AA9F0EFB794C385BC47E440BEB38BA742C7357A97CF33098E2EA4D823BD0B9699FB1EBFA806D64FAB18E106D4A97B23A889355C7A2635A9D3BB330A1B8EE5E707DC32C20CACFED68C8DE783562488A64400A4528EF568D833D73E456A9AC22431B2C22441EF5BCE3E77CCEC99D2D1C092ED8A28D686214313F683D4A020FA714459C36A257DDFF7B19B7ED05A16FCACA2570279A11E1439D07F2F23B88411404749C37836585182F31AD65CFEADCFEC3FA905CD4BFE2B6ECAE99D469F3EFC55615D45D19360EBB7C68C73ABD4562EEDA283776C887E70A971176DDC10FC399EAD6B9E247353C25289C0836C626E5376326FE5630C3098436556D61F5C75DA6057008A6E1D50B4F270FCB86F868D5F235428B4D7E13010D20175D4CF0759F56422CF955A721792DEB8EC887E5225F6E52CDFF40B8BD3FEE4DEBC7B363574FD1F3CC113A3B4281F4E8DC3AEBE4B67500ACB50B5DB1BB64F0634B19D4612F597DE2B4CAEEE8A3258DDF8436ACADF3677B46E7E5CF41071DEAD3FBCE2A73388E19AC0C7748E10E3F586E2EB844ADFC079EC0A2CD8C9BAC8E859460DCDAB688AAAA179882B91111A604F75198F55B17C79AD4BE3FDB493B59775ED449BF938B594D87A1C9F721D1C39868591496E62BDBF5CC2947DD81B65ED8CA0BAF0A64E924B5F4FFA88BE86C3594EA7472B822D2D84CDBFC7A2C5039FEC6EBB14FAE2D5D7E9CAF1C2B8788E7354BB6A12C4EA1ABDF0811417586F01553AFD9D8B1EA233066023BC45FA4BC064E7D289AE9DDAF1F985E4BAA86C55BA1F1866E010C55E166C3AA29A682A81195819B7165DF6CC72045D143135EDABA08ACF9DD9FCB8CE732F9CDF1A99C772A2EDAB78647132C33B80E7F03C84A044491B311BC6F3571E7935C6EDFB283BC59F29DD5CCFF9DD6A9640139B173E64F2755F6BBD977F15AF1524827DCE4C2FDF1EBB7C35F0F34800E5A07FC83821FA6CD41695B322F0909D55251372DB8B3CB147FBBF6264BF764B1A20BFA41EFB84D109D4E374564C760AAB66EE823970EE7BFC1D9DB860840BC4767E4A46F1855526A7D902D4FA954C7F337C7C1205FD4AAA70D7F5D904F1D0CF1DBFB63675991B26B590260714920A7249E75D21199D8C002BD702C5398C45A359965D367FA15A73B83197DB3BF3AE9E987479CD81283419E557F993884EA4F17996CCA39FBA8941EDD70FC86E3A46C84C656F77E9DFA5DB31D8761A8FC1D5A2FE9C1CF67DDA1408A212951A5A1D5E9260BF367FD824ECBE8534AA5C63F3E9E2EE4EC53CB42663A79706088A846614B10EDB58B45BF063ACEF64DBB5ED8808588B51A80EC327B95DB34A2107FA96776F1DD0340C7918D0B846883EED35F5730D67165D4A51DC50533458F045E1266CE5C1CA6A30D931DA81732A876987482F2DB58694C574731E92CE6F9083A5EAD8143F244A8DF04C6DE1B2B07ED86D5593CAFC2A7B3E819C03C70B7B32AC0D576AC2E2E5843A39E4D36EFACBCE679307A1998F9C9DED50BF39CD29A529A82F26B5B4538F9CBBD547B9E4D5F7F31B555A8FCA1F9ABDEF3483640DE77D558735C15A588D944F9D76B06E417B1DA873F38A21321CDACE8D4BDDC49EBA4165D40820BA19A437D65B337B8C037041631D09F8ADD1400524F4A3BC33F9213AC7926548B9C43A4BC0148807D9", + "k": "1A9EC19662B68932E5DE4EED9C3F16A4AA8E6E4129F8EFC2E9C7F0B6E82E3327", + "reason": "modify ciphertext" + }, + { + "tcId": 99, + "deferred": false, + "c": "B36564F2BBECFE4DD315E84612BD765E3F2E84F5D8D86FC0708F72FCAF284A0850708CE6E11D0BE154C00F930D18C0A8D8071B612556238A64B679A083B2FC1A204079EE19A4095E71E0EED695B3CA764F4F4E5D7366430A8933F0356DB074C2D68048E046481E5481E4F5A2F365EA9C4C7A6BEA51CDBF1BF31366F863327126DDD101F8220034FB4A3C68232C5CC84229EB1E35F19AC2016A8E4805A87797F940B72A472F129FF5B751964AEEC96847B0BCA5D7F391CA9053380DE83CBC31F341599FEFE36A1CD83B30A1B7CB588874CCC5F443F73ADFA2CE7E7271A5726272A7E5FC721E85D9755D672F5B2A0EAC8065D2C3835B7F0B2F7C77A27AAC438E345BAA378A572AA676632434737FA59A7E197135BD6AF2619A828AAC865D7F34AFB771BB55B5B7E93B9489AE98C694EAA26C6A86F41D0C53522DA4D90F2AB267675BABFBE963C4C68534A24D1EAEA2BE97702E28CABE5FD080DA6B3C432EB0E55F9FE8C1C0422A44F57002A1F96E6D53E8AB9539E909346D150082DF69F54D27017B9A7633B7BD9F7E6274B1F97D7CB4BF5FC2E34E77ECA1317E7854304C75C388CCD1386C694E93CADC856E136C2C0EE7E113A125C79443C5D1A80A9698BF58248B0903A45961603D1EA0E89E3C0650EA3E82368A6C477CCD1B0180542401BB1DE70E25F64A5DE41D62D0467353EE488E1F692EB60778452B53088473B084D0819B725268AAE752FC8CB56384C7AF9D319CAAEC958FC3EAEF57E0F35F1BFE1BABAA2C64A2D9813EE16F22A94C1C00B29EE82F11C47224A9C5424E647B9883918C9CF2CAF51B7FA825121C5D13ECEB5F66E4EA11526E0C37DBCD464C5BA78A36A31A62B2DECC7DF51C24843EC2325C74A771A7D73D35BF2AC4578932A6C2A7323375A2B7679188CFE804E5EFF4A04B7E14F8851770048F076B32BA4F19F4530364C0529EC3FB2D0DDABDC85DE2257F4DF05686AB498FDBEAE3A1439627DD8885E4C8744156C2B155BD2F965AF0F2017F163A6016C274E8532CA43C784B7AD4747A58253EDFB739D68E376D7ED246E5474454F463F4212090DF4F4D7F88C097B18180B05F2E89EEBB834B9BB6DD9E5F6036ECDD5908CA4962609C208A557A36B7FBC72158A6D86322F4303434F6AFFB34527E47E0599DDC88EAD31814646A81188E79E1B6D562E01FE1EF148FE8825758CFA5BD7B738E3BECDDDCA4C59093CA24581E531667DBA2C295B565951445E410FBC99D795887BD48AB87D6D413B64957993CD7525A0A0A5D393CA1EDF7788E4DFACDFA7B394B6163BB948C9C6779BDDCC8F26BC073BEAD0FC87236704A0DC0D89DEB4F8174E91D249C4DCD9260BC7C86CFB35B985813E1689D83083949927303741550CB782E256E79800F41B5C7D981D68E60978E5190A2C51C812DCC3952AA34212625834B2F8CF8CE8019AD6CE8F00FF910CCCF0CAF5A3596AF8DF947EFDE954F361665458F77787E528937BC52C59950746C783D8C5216570E6F0A944E6BD661F23C7A9AF3C602DF851EA2E5627186A6CCBCC470E07B290E4F754D5A8D6BAD8C34F39B4BA838CB467681B0173C33FA51ABE122BAE3DC06660950CFA5C228CDBA2F5EEF2613D2850DF9B5FEBE7333BE93F90E4DEE219AD18425DEE4006FA3009666C83DF7EDFB2EA4F99902C694248F9D51C7B6FBE53780EB218732C11368C33449D051489FDB01B1A1064FB06DED747ADE38F7A12DCDAA92D64DB4C2C43DFE53068A77339E1479C8C93192793B1C752FA7FB23B57DB5B428622D27CBF608CD7406FDB543FF3BD26FD7ED7269427C6B93491BE6724D071F58AF434FDAD2F0FAD5730A60F3EEF94C59CBC5884F36274C4CD984303EEAAD17E1785914DC804BBAF35406995E3D56094F0FDD71C7650A6C37393C0EF4C167CD2FBC28EB4EDD34B5383CA3D1B89D7BADB0270065B5AE2D461E6DEE53291230ED3CC3B616A7E8A86A4265A98C10A44066301470BBCDB257F35489BA5DCA320A390AF23CEF6ABA8B291538D9C4E965969087E394EDA44C060E28220BF72AB98F1C055159892DFF079D283C52997DCFDC2FD8291FFDF322809BE3CDC113DE9D495EA5F9FA5DDE5052192CA6F26BD510433B197131A7E954AEC5E58F0A341D7E4602BAE46BB1987B5C1D845E6AE5569DC2AFE0C7984DDD9B0B184CD6ABC0AADF5E13E0F110E8876D572200DD837FEF193278119B861C196C7522", + "k": "F098B5187D66F9687666207379D9A52532C38C0396F917827BE99222D0BE8762", + "reason": "no modification" + }, + { + "tcId": 100, + "deferred": false, + "c": "4B30E5256A941008BAD9BD14060445AD208769EDEA1C5B6E4ED506FB334A2378520B5EDC9217D626E1377839A18F2D21C0CC8902622E4AB79E83DEC449FFFD45A4CBF3AC253142D935DD310B5E4C5D591A9BD61795F8ABF00AA04EBAF96195B6CC7D7C3910FD7D75E25A9D0D79FA453178B06FC6B1E99F189CDA90276D6B69FBEA28D68CC82707A46CBEAB819239BE69BA76D749E27CAC9E5FFE88064B9972DB77C49679D6DDC6E6B03DAA0DDF0106B1A61141DF827E96AC542DC90A69CB316EB4F78C611C0155F9138F527006121DA16DB46531ADEC2FF599378A819CFBE3B079C9FE7E368B91A9E40F97A3E79A4F1F05574CE2AC3A525C206D9E55CE16D42D2F0F4863F896E808FE168B34A102BB81BD607BD02CCFFBA5C189497502A55F3E601F8F61B40A5202BAF9AC87D058E67B9E1CDEA0E4B02FF2DEED7477609A9AE2116512C42079D87AD74B05622E02979EF0A0F1D6375D93576EB6553FB1AC70ABDACBFBDB18735E949EC6D1667E978547A5CEAF2F4DCA6FF5D8346A960CE6925BF2B3F316238D6BC8ACBE67BC1AACD5A9A5D130A3D3B39C3BD7C1B06227A59BF4723AE9656D9922D9228A3404D4856E39702DFDC01C6E8CB6000E0779364BAD4F021BCFD7288CE7049D544E8423B2890C3083FDDB9BC720AC4C6A1A4EEA6BA1927B307E6CB72131B6B831AAD036A50A54608D106EDACD83EBDF104AA80C917314D295E903FDF36CD04EB786CF93AFF1279C2172002F7EE92DFAB3A99BF42C2BE7B7D0EDDD38029AB5AE18F5CFF8A2F1D2EA2EC7F34770FBA8A8BEEB0E1FF6F1C1A036F1BD84030004696BF4FB4161F252436C0401AEC911CBF1D7530D9D801B1B9B3A682329AE2F6930191E48189CD40706256B864D6F016597B4AA86FEE4F0E2362D8BCC743E98531EB2B335DE2DD299F231FAA808F6BC7D8F13DE8EAA30C5698D64E508D3534935B9941C2E40A458BEA82DAE4151ECF6DCD40320E1009BD9FBEE248F4EB6DB4437482BDFD83FDAF8367CC1845E64A23A310F904D5FAAD67241AA7748764C26EC881788D1EE0A39944071E5ACB656AB8CEA285C282545030EBBE6FB595E296E1EA37D7AE529B96CAECED11331D80C92D3DACDD7DC93237D815A9C6CEB9209C0BF3548ED1AD691929B2C1035E80A21477747E313049DEAD43A40B0960A96BF3C3E9BADEBC3B4D424FE7DC4DE5CE7788E31AEA3EC8965740D424CEB66D4A5678260051BFEFF09A3CB24C1AB7782AFBFEDE5EE1ED4EB14AD2A13142E8201CD1B52CE064F05ACFB019E21A73D84A80E30FAA48ABEFECA970BBF17FFA6F3A90AEF80EFA31C494E721231289143416AB9621737FC016380E6079EC6CD962BF7CC0750582EB218F869CE117D399DEF9AA66F7D2F07FD22BEB9E50B94CA5FC758C9DD4D2984A156748C52307731FC78F8539F8264BAD6DD56C0C23937A9A850E66BA298C3D39105ECACA9A573D887C9A4FE33D487F2126097B165594E1F8106C937758AB6EE75EDF39D2BCDE78AB611A034A72FDBEE67A80F3315571AB4DB94C56A19EFB63B8E7708566412F73D4974B160183FB5B6C44C8CED990B29C57BBEEAC5EABDCB11CCED9A17322B6EF197121B4094D7EA4A1B4EC44A68B447FE4C8119A6A33BFB66EA6844DB5B6094119AD1DE89449DE922B9A0D1253EA18C62418EB87330C6B33EEE02D4486F62A4D31CA24F098BE2F187CA6019025AD6E1C2FE69800D8BFA2C646F9FC6BCB3D369A78310084FF163D2065631C41748E7E3B25E8F2C9EDA2E107AA2046FE3F5DCC0A9A39FCE41813C8F1946C3AC07A22A6A56C4AFC626E68FF8CBC4982C1E60C3A9F288D1C4F2B8D7187EF2FAE30B77C4DD73499C2B3793B24014CFFEF6D80063DD1C1F3AC7F14FB61E5E81F850AB865BA873404BEB898FF7A2DCFA3B955DDB161B5781AFE8EF127BA2C8BFDBC2FB1C7D80FC650420214314023F6F65C17FC48927BBAE88D48D2E1976119C2F8310232942DD4C3AD4518D1E4DA9DD588691837122F5E5DE0FF1FA685DE134DFD1348CE3B5BE60B18BBF474074829E7D81AE087F149259122D47B728F369D1D8455EE571F715788C254F2EF438034BFF0A11F2F008E19B370BBEEE135A00DBE7F3C2970208F5F5D0E2765C395CA81B2FD80FC384AD046564229C759315B6CFFAD03A56996556E7714DABDE28F7A9BB5DE2C05B1F3596AF66C747D9A9313673F19AD4BAC6EAA7", + "k": "FBC9EB4E8D611C153AA9ADCAEE5781DA5C0112B3AB75956180A5CA40BFA0F53E", + "reason": "no modification" + }, + { + "tcId": 101, + "deferred": false, + "c": "CA9564B54F15561C8238E6CFD88137EBD4D277FD5D64BAFC33D6E575947F0FF9F93E3B0A4023DDB6FE480D7D6A2B9ABCD6E6E011EF37C0699A6D60D9AB4B05BC685B0A9AF7D3BD999C7AC1CDF017E6AF1DCF0313759CBB21539D7774C31D7ED8C039AC34D0C6A5F7590A3DFE193D73FA96B3458A364DE1555284D85A2BAE7BA9E57ABA00134E6B09C09777F2F1D7125AF858D81D14C71E34E8F668468997334B72E002920FD3FAD8D588355343FA949F1CC0BC263C7F7A7FEA6AD708DB756AF983B16A593EC224F7D69208938A4526400E326CBED532A777301DDEB5E539CFCE60DB8A022AFC52204C71710C204968FD1457919EB71CA15522AD56ED6B60404D62D1DAD0D06E4A2AD6BC746B28859A77226B774BF56BF7F019F2837F51509E9EBE9EB069DA27401CD1D7BF2A74CBE8341A7F213D061619F4E5F52984FE47066D910F1146CCD8DB48210FA2518D6B9FADFF16ED9D389292C07C8A7021F32BCD538AB06A6D5ADB13D7A96F65A4062A17E26B301CC8AD420732126D7CB801DD489AFF2D717D07A2748B4B01D162D228D5F1533CD5FEE8DFF8F032DFB270B61095785E44CEBBD4EA27158362D2A27582CE78594D4D7428B6AD958A9F1604EBA76A8CC0530E1001AC97E5ACC5EE670D5DC6A78AA45300A2BD5F0802CDEE564FA640A19FB554383A4E4CCF2E5BB3A41879C9428CBDB8DE1F4D3FDEFC18C2A8BAE42C096244279E57B307614C843B341BCCF530F6B187121DD83A9A160A3579C3188A98FE2F49A85A2705B9F76DEF04D5D04676D8319F243DFC99A5F90771B34D2A45EFF92C0CA8E4B542B8ED4C2AFBC92C26F8DD20B26B15F9E719AF22F571EE5B9573D5BD1931138D6315C5104BF80AECF830548E98AB23DFA44E5A23C6CF57740926D1E146937AF8D220684919FD89082E260286AB66F66F8A1B81BEE07A85907D07FCCFB9A1002CDD47A33535C9FC0938E3CDDED04D3FABE6326CBF5643373BAE1151704220E49E177C4D0C6168647E5976670DB7F6D0C12F169955E31F553A53A76093DA2A9A0C589F9AFDCCAAD9EC5449ACC01E12A70BCEB389AC104407415782AF2EA3C73D9EB2797CE6D3C005061C5059AB625DD7D273D4D92D1F4EB411A4033492F19921F60D0317AF286866B865E33B6235F0E3528228CF9DB242124F0A6375D50CAB3851DD2A3A022C1E636E332C90D97FBBFC2CF0B971AB1A89014BC2D942FDF015555431ACB3E7A6F258B816BA84892A1DFE3780A0E0C2E6C06149218E70D60D62573BB51856716C0DDA63A983C4008982E842E655E5767DD203DB3490E1E6BDBEC16350296D879F017BA695FC1CB3BBE516B741A67CA6CE09314AE27F718DF68DE698198289B457884FFF1E439F30D9117D19ED7E466084BD5A73E26B5E1567B148D4C7ACD1368B1CE2709B3AF233679E61914202D0DCFC81EF3ACC250DCEA602103C7E529FD6F31A186927E790E3DEE09DCE87DF694ADA7A3B7BB3BEC64456EE983E25DC6CA1CBCD752D72ABE6FDA2FC81A46F81E83AA9738D528C6FA3E69C453346D0C9A0734DF36BB7650D1D2AFA8A5C4C5A936D41258BD4193DA74FFB180CFF582A32D6F6ACB93836E009E8C880592BE61532215F1F6FA50E8FFBB82208A94D8510F70DC6633DC04F9D94C6AC46EDDD4EB36873E064CBBE65D343957CA7B75024EEBB56F589C3DD2253D68D12DC892ABB1FA4BF033B9B732E89A8B89541F04C6462F62F13B09C6705B31036294F1AC38EDC0C2298D7C6F4374C3B5C368D10DA8D371383CBFB4491126A83D1F75DF44F29BCD39349A9BF6526D14B339FCB440647A5FAB63A370089DF162DDBCEAC8966648DDAD6669E1EADC1C8A33E9B7378693E229C6B715F2F0AE54A67455E79FF8970F23E655E7A540D28958E2E102DC99B5CE5772D00831671CC6F7024BBAE8B04173E439054C96AB3BE918C40C5A8D42A9122CA29C56044D340420D2EAAEB738EEF70331D488169FE91B521835297D7326CA272B2614144EAA0B7A75CC7F3849138255B8A1D7DB875BC7C25D28EE5941DE89BF7B063046CA0CFF31A99D7B1846E01B519137B67647F024B3F6DC70045B6950EC6ADBD68F43F67464858D515D6E3EC5F99D9F1C849831BEB4224FEDB01236712E1D715F6A752D0682169A0E83F064FD6F081F338837FE654BCE7C8CAAA8CA90C8505945D9BB3EA58661102FF0ED3F0DE30C4013122D8CF08E0", + "k": "D970209BBE4676405E1CF15D053A04F93D800AF1B32EAEB1E4B644ED09ADE8E8", + "reason": "modify ciphertext" + }, + { + "tcId": 102, + "deferred": false, + "c": "C18D7D95DB69D4FE1E6DB385024D83C01F4790E2BFD25DB3F5DD5A208ABE06551BE0936A84091F081308471E82AC9ED6BAA90824D5525701AE0B638003C21D5EBBCBC17FCA8F522BE4F9FE5ECF38BB66131578163D50994E532D0776B187498C5A85AFF617D4550345F3855F968A8964B4F3CACCFFEC82C92BC8617C78C98E10C91AB505A92CEFE0AD6C8B66406AEA4C3FBC5275047B3E983AD42BCD31838A39B92E1C61E9E62443DF3A45044819D9E289B5514D4F74E08FC3914C0B66D2352CF8B1FABB4AC9B0748A43547BECD29D447D01083803D34E8B7EC89B4F0D78B88AEB33E308989BED2D7A78E1C06A11F3BE808F0B9D9712C80D63DA10475849DDF6CB0DBB1007FCDEDCA3C4220386B78D9EC6E380B4F57731D964470B42CF7D4B4E6D98A12A9021121C8BACC4B132A274941DA57D824FCB60B83565F5CE05D140653DD4C70F385B55D485D24935F3631AC63FA12FF50BCF4E431EE4074B2A05A2A97354C7B4169B13EB225F1727F8424F7CA6317A04C355FE785248E67E053C4D4BDBBC47DC7760AC71DFA2502FBAD1180F2B095425198A26BD5A0F7DFAB70524B8F076E7C7F215B0536B0023F8A9F7784809FF4DA245C2EAC5F9E0AB85D987C5B6FEBDB3DF197347BDFB8D5F1547FD2A59D4B434FA7ECF8D8535903D3892868BA0632F194AD6E4D5A3B30E5A6B92F829642DD4A3031358F9F0D9D46530602A35CE455F0E360C14A754828972D85561AA835D87275AC510856D26192EA319FEB45709346929DA5C5919510CB2A482CBB0F1CB4BF6FCC0343F6DBDFDE734919EF335356ABE82F80786EF0CA22E5B03A05963E7051E1FA7EA4BC3141B5746D264BE1A32CCCD39DFF8F9E5E2AB4C5F51CEFEDE3C1CD118351F9A8ED30649D407FD31F6C4BDA3AF44888ADFC3D118BBD04412FF810A7E106EC32F7524E4750DC5F35A9C55541421B5E412E57BAF24622627F02633F524FF854F71011580598C5CE01190258310BB12D7DB5F95E9EBE5F72C97E89287C2F9007A9332EC51DEF1AA2F2CADA9A8A547C3508B4D294364EAFC858B98C60C5469CC7C3CE3ED659B5A54E889FEFAF825FC777AA74A8896C9447704CA7300FC5DF5810681E3ABE083C1285B3B97EFB0E21F78F45409D00B2E1680DA79439734190AFF0D68E062970F8F6B0F1E84A559B09ACD9938913FC26484DF2125FB6D7FC2E3F0DCBD72D9E5DEDBE7E44CE7D895CC9CF6945BDE0C52F92340F9FAD3009BC90D4C2D3DEF7C1F10A862F9D71681537FE4E2716912DAAB8C9DCBD81A083220F68B05F7502F3911B1B6E3B26DA14EF646DCE67852FAB6145BBE7E21725C21CBB2849C63D01AEAD932F8EE9345D8666786AF06AD0C89B08495A6EA95992301E2D8B6A14426971C7B31626BC93BBE76CF3DB9487B5BFC5BAF298F1A92FC3BE276983E53701F9A550E2961E6E2F07317381364719BF3FC741E2A5A0664D8873120D0C11287E92DB12126332D43F35407C01F7F85DF7916B651EE4A30D602E71227733EC9252EC8346361DEFC23397CEAD0C23AF44C77A4C97242C7FA9065BF0C81983AF3E516C1B8FFF3DD5A6C43B6ED5AD8BB3327A09B6B459168F3E497DCB65FE7593E8AB429B8EB2B31F76DF08A6A8F35EC4CA994037493A8C04A73D8191D682542FCBE16E657D3E477A7D25A1D650450E94FAF485CB76FE7110BAA902D74C335FEE1546D076163B5540D8495E16E909E1D28C15BFB421756B921778A784E16207BAD407B64B9CD83AFB0A602374DE06F5C836F4A1ADFD495012DA8D3FA4B829F735B31BAA6364A2AC11BD18E40628DCF82238D86B0B5EE9DF6D179103E1D12F5191475FE3008A5382CC24648CBB24F2298758823B7F93DF10B380C3179F07DC3277021E9EEA2BE5CED646260165B57A18C26E259F83576938828D4C7617623006682CAA613AAB770791874B55E2D0BB32DDB628919B42C09BB7DAE1FBEE8661CC13F8B6A47CF5D6085A2AED796E305738B508599673DCD03AFC267023814FB1DF7EB928D5762BBAB4515921D81C6CAF551DC6EA16C1D31125B99299ADE63FBFB9BC1CE46331394CE472DE6DCEFB2BF9B3828B0110246419C47D2A1FEF16097B943A310C0664A92A155C8273402E83CB94D7E733E4527E7525E9BAB219B69676804C1F67088184038668D55AC4F6E04CEC0EED4B05DE649A9C2064F241AAF9732B09B0EE4E5BB2C0386E45FBD44", + "k": "B93CAB6CB4C636B56EDF0DDA556D2AF2622AE197B5AB78F95249204A6E2E824A", + "reason": "no modification" + }, + { + "tcId": 103, + "deferred": false, + "c": "E7B361D043C4A0B3A780121E9648DCF38DFC10ED5E47EE4DB5523C1EE1F53552640C89D9D7EFB9DFAA8EBAC7AF137A850AE41A0FF8F8CE31FDFD3E671555180EE46AB58322FE4E5F525146F9D4CDD1D1CA01413C5AC7259E1A2604A5951755F47D1761ED16B26D3DCFF79A263BC38852007BD3F381FC3B79B46A4B372918AF3117180726117BDB33C063BF5EE5D69CB48D267929CEDC890B743DEA43205EAD46FFA69D9B30C1AA5F146CBA3B0B7C4D4A50FA8D120777F1661430DA1B9D1C1DB4E10C5C3C2436D381EB13DDCC61EEB3F9AB46B60D2FB714929139E9C27F8730684EE17B077BDC003500027FAC94DA80870B382EFE41BAAD902A491C29DC95A8F80BB075A4E61C8F100FA738BED869B48F897ABC9CCE08917B5073229A94F3790947FC1AB6C2DEB5B012D60EC156A8A041DE151EED8884EC616089CB08EAEE37C006F5BBD10ACE9596A34FB09345A14FC4EA674E4A74699BA5240FF1282ED1E64360BDC9F7336051A33DD48809CF0011BEB3CE8C681588AB29F5F26175A8A6FD7884CB96CE3964FF10A67FC4A4E14CA516162C16D8127CBC45BCF7C88C89C8602032298B53C19FD099809814BE0504BCFD2407F48F2F24C5ACB89DB4F54A018DD586D871C58CC0D998FB4B0E5F5DAC631BE8367DDE88ED711F069FC8A80EBB573A7DA12AD8F13A4CA1E8A22D9EB53C55B80F700C58E6EADE6CDEB35C262EB42C903AD854F843547B79464524833A05E3FDC46092E41D8E339E7662D1209D338B8A02994D15A10439C1DC02A5B0EDEA58AF197866F43269A57C747DF389EC597F523211770E9C7E4CEFC5E43EEF791897EE43CA6146F3F757B66B9E7592E728565325D1740A1736CD0E678BBAA043F4C355FDE27094F74FAE27AD8C270930DF637C652BC1957F958DB013C146F2A4C5F451AB58A55C2B638A82755C11991B049E82F8D3CD3E7D3571FD5A83B60280E92031B610FADAC9E5F61DA469DC4C51381C970E03F09CA560E5D69D9B32AD6C1DDB6FBE9F8FC0551A909187AD65AFDC067EC6AA01AD684AE4C4F2E1F64046083D3EB347A6B6B23BBBF14668B9650D9364A6A7666593DB86FEB59628A91169F8AE24F67680789D316338B2F27766A83957831D98C88C837215AE3BD49767ADCADE758320ACE76D7F39E2970EDD19657F0EC12583164C325F0A000D065036BA2522F960C87F9852F30BC6BB5419CD8C0A1F9757BD358E748CB244A5E677AB9F9319A43A9BAC847A566052CA42C1C1DB36A0D97F144BED3BC5F11A5C8BEF7A74A4CC67748F1DF53F8B4714E0A04256B36A814B08B78A9737757E3F1347F9E5535DF1AC98B08ACC1409278B925F3B6C7863BC0969520FC6183E216B4E8E449B0FB999F1C65567AE2064774454EFDA67E1749FB24A91B55DFFE7DB75C4E24E8EF2389214EC3E95972CD53234CDAF8958D651A7A95802E65499A8A7811A65ABBA90129D5EC4247D8183316EF818E79BE839BB3379E4B8F4EE9438BFE310105C91F8703AE94D8F9D53096E2341E74E0237DB2665F16954B9713DD9638B05970A9A96261586B04F9FF369028DCC43D35B51F95E69B0323A1CEACC4A5E2EF640CDAF3407BF5F5E14C9042FF299786BC55965EB7C8BB161487FCD7911BDC2FBB65100F2200E16C690F801EA6615F9130EB99DF816B188B06E9A3105B78212B76609DF190FF102CCC451746CBAD16464E8E2F647B75777F664DE86F5089C37E3A54A6AA8B456CB98B42DEB5529C06DA45C2D2A13060BE56A061CE210ECD307FF5AD5BE39CDD8D27B4A3403323D4F53BE35FB4E31670F73CCE74CF73CFBB29A5FC2EECB5F852CA911942066D826404B77251BE5BC5980D0A6E0DB4D753D86490D4250536DACF05D82064A28324B49AD4AD202CD0FC939BB7A3CD9FB1E3E196348EF336DCDBE4BC831DF5847070D0B2BE1C4910FE1C69F58C6A7A2E7FEBD51BE1D0E050D5D721D7537A0325E7ED30AECA75A2A81BBD86EBF91CAFE4483D2729271ABDBB65C2CD9973627D2820DC7ADE3E26CA2F466EB117B2BA98EC868DC728ABC6907D49E2495504133FAA7F8758FD23076D1A65A91C75512F89EE4E2F3E480D6ECB0EE90793F4F93FFB75DF58A7072C91D5A1D9EF0C3B1DDAE79EF576E6A276F78CDC24664897F07B3A20691601EAD2F499C50589BDBCEC74FCADED1A8AFDFC061C2712ED599D48A3ACB3D86515D664D0CF3FA349A1910CB", + "k": "2E85AE4441DB0930391278E9D6920D9AC77D6C752DB2628CBFE9D76228DDC954", + "reason": "modify ciphertext" + }, + { + "tcId": 104, + "deferred": false, + "c": "EDD3FAB8AEB1240FB31B836CD1603E1F904BD1F87318DCB02A7DE18B4044385CDB51E343787E583CB043EE23899658420F9DEDB23CAB2BCD1013F573C0C7978521596631F6590105CB7B281AB1591B7056BE068DF838E0B1679F3B88D95208EF4B3019625EEA7704CE79F33AF339AB883B0C48B3C4413921F43AF2515A85023B5D98D06E619238C8D033FB7DD19611CC60CF395A03B0681913B299531B13728B278D353FA093C633710B65000772DD6D7CA59C85DB62196DCCE1B75559ECD3FB42DDD8E57EB4CF3B4E35B57EA3D6063221B81F1B802DD7D76DE308CB0A738C3B5833E9F4427AF3C3D79B521E7E665B052B9A365DCDFE5A688B06EDCDFA2143C938F852E32D6B49808CFFD01A8655B767034F8C638E8AF94BF3EB9EA39AED1D2D22E181888DD608BF9392FD73822303A41996F41D51A924FA6EF76A9C82709A21BEF1DD004693EC9468B335F9BD1FD94D5E6D89D570FC6D23B7F5CAD2975F418B8C4A0EB82EA2A3C979B1C15B0FB0A23F844764DDD49A8B89C0D4BC8C311BB43725EE9BAACC4796F58C0F1180A4F6AFEF45178659B35A74FF34A8E93A64FA4CD003269EC67C5BD528E015B2311B5E2D33472638CD65FC7D5127335EDA862BDEA05F4290EF9B370BE69DC89E7D71DD2522E669700D5D02D8DCD75FE2AD9EDC307225D61C7805CE1EBBC806A08BD360F86FD27B599582B22C57DDE77B08F7537482FB5D75BDB9F3F4EA07DFB0711C25AD1950058EAAA2E17D8F676BE6B72B1687383D8E0DD60A8277F6FDA202D6F8957EE21308AE81ABF72A89924DB44238B262D2FCE733E12E5413C31FDEF94860D5BB0FB0AEDCB1EFA8F87CCC76189FA5D8157FB4FB14652DC188157B2B746B596FE6F2FEB197DE139B80922C2EC14B58E743E3335893ABF85B99BC4566FA1BEED449658C5993CD08BF78F7DBFF808F611D6EB8F0BD7977E854BC195D711C03EA532403547B6ABEAE827481BB5D53C867710215835260097B6CA730FC722A74E230434B08F38EB1ABAF555CD4CC6CB9310E32F93E0ACAC1E915A4B57E0774B013BE7DD435B5C6AF6018944349841F84E8C28260149F266C99FC05E0DB8D5A63DE362CDE45F5BDFB6F30D55A84ACA22E8640A1287DA51714F2C8D4B184A5F671E0E907134E34D875C9A4709ECE3B7FE15713A0DD972505298C18A9D35956149EC9AF45C475016D7C8B5CBFFE2108882B86FFD380A79892BA1909489E016CF9933705E2FA72ACC8569501553401C397648DC47948935C0197D6F162464DE42BA537611CCB67A988030ABF6081946FDD1ED8C6B23691EA160E8543735894839F13C270B3E1F68607A7EECE09AF06A34F4FC9096D4EFFE4905BE56F3EB397C13472F6621F3EE45A59C8001ABF9302E036BEDEB2E0EC92A03FFE0DF52262621728C6791C4E7D8C226D17A04B6E7EB2FF8586585D639B449C85224EEC67E30537ABE85C8F7E2306DB80E968D8585CED3A9E21622BBC38D43A7D79E2457C67307CC208064D3568C476ED79359CD0A4B0BECA02FA702661056E187A51C2D154638F9000DF856ABB82CFE12C47543E46FFDBADD2DC69EBB3FF444E7E1E95235541015E6CC7A0429C82EBD6942C6420AD598C08080DCEC800509C142ED5A642951F491E748B5436148B90ACCBEC35D0D85FAF4E472ED3F1A089113808D3ECDF77EEF3E089FA5A1635B90EF99034AAA49D4D13058EAA5A8797E37C59CEB86C7CCFE1F574E1086DB9BE744BDE5067AD5D6C450FADFF2338DB110736FBBD86B41B29C29D3899CE60E9BEDF775416541350AAA9BD9B5D57573C542375BB0297912863C86AAE39D153CCB29F1811CDE58978951CE8EEFA6F9D10121AD1FB89F02AF8E96AC08DD10E3274E8CA79D910667166797468D3D3BD6D7EF5F2C6FC4F110268A2716CB273F29BBC347050BD98BDD88F30A96E7A9E840A55087F42A09B03D04E612640BA4D86BE87DA6D20ED0ECCCA2523EE7C4E9D2A96E7378BF71308850832769417EB6250FC768B0EDF92FD45216A235435A3E32AE5B22BF913027D81B0D5508D2AF88120A50206DD7837B79C45B21DB4FE59D23F4AB051BF012B13F6EE5B34C83C8D8CC9BB35266D0EF3834F52CE6CC5BCB7C5989198465A9E9DEE1A1F262FAB26FE0D0964E624869DF2607858815418F85A1F503BE5217794CED29D02E19D40C4BC8E65C46FE3815C1E548976649D4332B1841EA03022", + "k": "5CDD11E1565AF6FBC0DC373651C6F2DC833EBBC54FC0FE2855C0C19EFDD6D877", + "reason": "no modification" + }, + { + "tcId": 105, + "deferred": false, + "c": "C72FA15560FEE6B014E73F5F93C307F74EF9C49AA8F7DF578C002AF20419040D6AB6AC46F78FB03F56A9C5C95902D8CBCE34D79853EDF0C319AF5469E32D0B9FC3C41628970E0B3A6C408B509C74DFA218BD23FA7A11DEA2D2277B3522BEF6606E3415D0DD51556440CC1AF59CAE6F23368BCAC3E1509503368354D1E3EC9E91F8B2D377DCC323D578DEB222585E43F97A6D1855B576297F3EC39F5F9EA1B2F72A0E701DB35D633DBCC5FFF76A2D39AE9DF2A3F6326B7671A4C0BB7177897DFF4FAF9FE5CFBCC94966BD298EA2627CF19C1CA866E5927C6E41970F544479D9A6D814AB72E2963F959CBEF37BF905BE98D8C8F3C25FAD3983F71D0C0D27D9FF17E4B34C2F8664406151E92ECA980F6CBE8F8926638398C9BCE9C69A92A30CE82F28CB4FE4110EAC40437BD64D38412030FB8DB3A4242672807737E707E59A0ACFA782127EFCB7BCEC39DFEC55C3109F958E86E0D381C4E9E9FE43110517778C08A140CF440F209011768EE34E5742ECC1E4CED045922D698A29E5557A29C237885D8559F110E4B540FE1298B97920EDF59BC8EBCA11EB91F471B6647864B384AE5A6BB494942BB1F537301B39EDD6F664E4A7877C173614B09D981401D5AA98A8BA4BF1992DD7B7A65BCE7E87FCDFC7B29AB69ADDC9036D71BB9BC08F4E7D9A57B784911CEE7D0EE5A559332981B6475290FB4410D8BA1F00FFC4850031708EB6A83AF524447F491CC25F23FBED71476FBA5C64BCD50D88A3ACD2BE1DF461B11F6D537B2929D073FCFB9E2545E1B097A12F52C411B2AF6C20A27ECD1C084568F4A76A87A4A79F7711012CBEDA777D913CC6B15E6C4E9BCE2C773991946CB9CEFB7F105B15FD2CD3E721E6C1DF69B66BEDF2157ACAD45458FD8C9C1AF910394A13C300696BBBB5B1E1145076BC6B9E3D30A680EA29B6370618B47AF77108EDE6BFCEBFBCFEDDD27FD9F0DA6D289060095C4E309DC3D26DCBFB9E8AF34E12BDD335FAC434663D4D802C8B04AC884352D27739C4DF22F3D7DB38084BAE2C0A15485DF4E356DF2FFBB5BBACA78D0B4886909C4482A6366991776B788C0941437BF858DD83AAA50104D725171C09B7DB521AA65CCCA3CDAFB2E61CDEF66B55D80E201DF44654E7B1FFCA29EFC1E44A8CBA406C8DAC6207C0BD5DA964FBE137ACCD84405A94F5F51D82CE701DD16774BA5F0A7A2BED7F9BB9A4F25C3095D1F8980721A7ECBCE957825A9BE9F4F818E56D35909A3F9DE5487DA0011EBCF9F4D768B72D236042175ED599D731AAFCD45D3D837FB8B64304ED7F22A8C3949BFA25B83A8C05FE9748F63A38201B460E16FFE4329C8464C9BF07D45DF2BA9AE7A84DCFC4CAB7BE42CBD360F61051CD56F68A71FE9E78231986832C9564D02B973EA2D3FCDBAEC374612C1B74DD483F08BAC30F6C9306E7092CC8FE1D20B937AFA4BC605ED4398A8B81A470870E97EA7D51562111D04BF9D09D9BC07533FCDA1E8DA2F2823AD621DB169C99FB112E44FDEFD597B61160815A1776139B685DA9DF6B4C22F6FF6CA3CC46B3264E456E98FF1F301122C88D42928403ED0E0E5F49BB0B450429980ACEFA1A80DA26638B5D2310FCADB0836223CB0894E6FA014D351AE052A70AB5F515641F153509FFB90B8DE495B946AB8C7D7CFEF56D3C66DC871F1D3A38494EF6AB82066E96B9F2782D6B5931B78B7117C389D155759CBC1690897DA66E50D0865209887552C8A6035B8F6911760F8D0A450FB926096721D962877FBFD87D92C37C71836B8BB9FCE92B4637785DC8E8C1D379081C14C73872E676A1C854F1BB68649BD552B48D12F62B17E9A48CCAF63885899C7B781DC3A6D7DE7DA28E286C9FD644D3521F0320B7ECA8FD0AAFFFFF90DAEC85BA80868A2EC69CC73AE00AE29FF5BA37D94510CA19E1EDAA64F30CD79A58B42FC9A6402CE31AF54BAE84DFED8D0C76142A347542265B794A0AEF4A08B4B5DFCADBD56757ECD98F175D80B44121257964293F300FF750107C1B72463D4634EBEDF4705F76C908844763D0D6813FFBE5411FBBFE16C08F32BD1BB3FB8EA5C5339A1B0194DA543E64C1F8065CE526D2754EF95A287DDC97B790FF34EA37863BB166BF0BD99E3A961BC91C1A4F84B63700C9EF5D8D31CEC9E1AE33C554BE638D5C1217CD2DBA13CC143F969DCBF285407A9B608F859812E7F668D4538BE179D11ED767A6971A2AA9CBB545EA01998E", + "k": "C751783FCA654B1FB5F210C6CAAAB9D5E46A969E546A0834D618A952DCCCF3E3", + "reason": "modify ciphertext" + } + ] + } + ] +} \ No newline at end of file diff --git a/test/jdk/sun/security/provider/acvp/data/ML-KEM-keyGen-FIPS203/internalProjection.json b/test/jdk/sun/security/provider/acvp/data/ML-KEM-keyGen-FIPS203/internalProjection.json new file mode 100644 index 00000000000..4c338175910 --- /dev/null +++ b/test/jdk/sun/security/provider/acvp/data/ML-KEM-keyGen-FIPS203/internalProjection.json @@ -0,0 +1,630 @@ +{ + "vsId": 42, + "algorithm": "ML-KEM", + "mode": "keyGen", + "revision": "FIPS203", + "isSample": false, + "testGroups": [ + { + "tgId": 1, + "testType": "AFT", + "parameterSet": "ML-KEM-512", + "tests": [ + { + "tcId": 1, + "deferred": false, + "z": "84CC9121AE56FBF39E67ADBD83AD2D3E3BB80843645206BDD9F2F629E3CC49B7", + "d": "2CB843A02EF02EE109305F39119FABF49AB90A57FFECB3A0E75E179450F52761", + "ek": "A32439F85A3C21D21A71B9B92A9B64EA0AB84312C77023694FD64EAAB907A43539DDB27BA0A853CC9069EAC8508C653E600B2AC018381B4BB4A879ACDAD342F91179CA8249525CB1968BBE52F755B7F5B43D6663D7A3BF0F3357D8A21D15B52DB3818ECE5B402A60C993E7CF436487B8D2AE91E6C5B88275E75824B0007EF3123C0AB51B5CC61B9B22380DE66C5B20B060CBB986F8123D94060049CDF8036873A7BE109444A0A1CD87A48CAE54192484AF844429C1C58C29AC624CD504F1C44F1E1347822B6F221323859A7F6F754BFE710BDA60276240A4FF2A5350703786F5671F449F20C2A95AE7C2903A42CB3B303FF4C427C08B11B4CD31C418C6D18D0861873BFA0332F11271552ED7C035F0E4BC428C43720B39A65166BA9C2D3D770E130360CC2384E83095B1A159495533F116C7B558B650DB04D5A26EAAA08C3EE57DE45A7F88C6A3CEB24DC5397B88C3CEF003319BB0233FD692FDA1524475B351F3C782182DECF590B7723BE400BE14809C44329963FC46959211D6A623339537848C251669941D90B130258ADF55A720A724E8B6A6CAE3C2264B1624CCBE7B456B30C8C7393294CA5180BC837DD2E45DBD59B6E17B24FE93052EB7C43B27AC3DC249CA0CBCA4FB5897C0B744088A8A0779D32233826A01DD6489952A4825E5358A700BE0E179AC197710D83ECC853E52695E9BF87BB1F6CBD05B02D4E679E3B88DD483B0749B11BD37B383DCCA71F9091834A1695502C4B95FC9118C1CFC34C84C2265BBBC563C282666B60AE5C7F3851D25ECBB5021CC38CB73EB6A3411B1C29046CA66540667D136954460C6FCBC4BC7C049BB047FA67A63B3CC1111C1D8AC27E8058BCCA4A15455858A58358F7A61020BC9C4C17F8B95C268CCB404B9AAB4A272A21A70DAF6B6F15121EE01C156A354AA17087E07702EAB38B3241FDB553F657339D5E29DC5D91B7A5A828EE959FEBB90B07229F6E49D23C3A190297042FB43986955B69C28E1016F77A58B431514D21B888899C3608276081B75F568097CDC1748F32307885815F3AEC9651819AA6873D1A4EB83B1953843B93422519483FEF0059D36BB2DB1F3D468FB068C86E8973733C398EAF00E1702C6734AD8EB3B", + "dk": "7FE4206F26BEDB64C1ED0009615245DC98483F663ACC617E65898D596A8836C49FBD3B4A849759AA1546BDA835CAF175642C28280892A7878CC318BCC75B834CB29FDF5360D7F982A52C88AE914DBF02B58BEB8BA887AE8FAB5EB78731C6757805471EBCEC2E38DB1F4B8310D288920D8A492795A390A74BCD55CD8557B4DAABA82C28CB3F152C5231196193A66A8CCF34B80E1F6942C32BCFF96A6E3CF3939B7B942498CC5E4CB8E8468E702759852AA229C0257F02982097338607C0F0F45446FAB4267993B8A5908CAB9C46780134804AE18815B1020527A222EC4B39A3194E661737791714122662D8B9769F6C67DE625C0D483C3D420FF1BB889A727E756281513A70047648D29C0C30F9BE52EC0DEB977CF0F34FC2078483456964743410638C57B5539577BF85669078C356B3462E9FA5807D49591AFA41C1969F65E3405CB64DDF163F26734CE348B9CF4567A33A5969EB326CFB5ADC695DCA0C8B2A7B1F4F404CC7A0981E2CC24C1C23D16AA9B4392415E26C22F4A934D794C1FB4E5A67051123CCD153764DEC99D553529053C3DA550BCEA3AC54136A26A676D2BA8421067068C6381C2A62A727C933702EE5804A31CA865A45588FB74DE7E2223D88C0608A16BFEC4FAD6752DB56B48B8872BF26BA2FFA0CEDE5343BE8143689265E065F41A6925B86C892E62EB0772734F5A357C75CA1AC6DF78AB1B8885AD0819615376D33EBB98F8733A6755803D977BF51C12740424B2B49C28382A6917CBFA034C3F126A38C216C03C35770AD481B9084B5588DA65FF118A74F932C7E537ABE5863FB29A10C09701B441F8399C1F8A637825ACEA3E93180574FDEB88076661AB46951716A500184A040557266598CAF76105E1C1870B43969C3BCC1A04927638017498BB62CAFD3A6B082B7BF7A23450E191799619B925112D072025CA888548C791AA42251504D5D1C1CDDB213303B049E7346E8D83AD587836F35284E109727E66BBCC9521FE0B191630047D158F75640FFEB5456072740021AFD15A45469C583829DAAC8A7DEB05B24F0567E4317B3E3B33389B5C5F8B04B099FB4D103A32439F85A3C21D21A71B9B92A9B64EA0AB84312C77023694FD64EAAB907A43539DDB27BA0A853CC9069EAC8508C653E600B2AC018381B4BB4A879ACDAD342F91179CA8249525CB1968BBE52F755B7F5B43D6663D7A3BF0F3357D8A21D15B52DB3818ECE5B402A60C993E7CF436487B8D2AE91E6C5B88275E75824B0007EF3123C0AB51B5CC61B9B22380DE66C5B20B060CBB986F8123D94060049CDF8036873A7BE109444A0A1CD87A48CAE54192484AF844429C1C58C29AC624CD504F1C44F1E1347822B6F221323859A7F6F754BFE710BDA60276240A4FF2A5350703786F5671F449F20C2A95AE7C2903A42CB3B303FF4C427C08B11B4CD31C418C6D18D0861873BFA0332F11271552ED7C035F0E4BC428C43720B39A65166BA9C2D3D770E130360CC2384E83095B1A159495533F116C7B558B650DB04D5A26EAAA08C3EE57DE45A7F88C6A3CEB24DC5397B88C3CEF003319BB0233FD692FDA1524475B351F3C782182DECF590B7723BE400BE14809C44329963FC46959211D6A623339537848C251669941D90B130258ADF55A720A724E8B6A6CAE3C2264B1624CCBE7B456B30C8C7393294CA5180BC837DD2E45DBD59B6E17B24FE93052EB7C43B27AC3DC249CA0CBCA4FB5897C0B744088A8A0779D32233826A01DD6489952A4825E5358A700BE0E179AC197710D83ECC853E52695E9BF87BB1F6CBD05B02D4E679E3B88DD483B0749B11BD37B383DCCA71F9091834A1695502C4B95FC9118C1CFC34C84C2265BBBC563C282666B60AE5C7F3851D25ECBB5021CC38CB73EB6A3411B1C29046CA66540667D136954460C6FCBC4BC7C049BB047FA67A63B3CC1111C1D8AC27E8058BCCA4A15455858A58358F7A61020BC9C4C17F8B95C268CCB404B9AAB4A272A21A70DAF6B6F15121EE01C156A354AA17087E07702EAB38B3241FDB553F657339D5E29DC5D91B7A5A828EE959FEBB90B07229F6E49D23C3A190297042FB43986955B69C28E1016F77A58B431514D21B888899C3608276081B75F568097CDC1748F32307885815F3AEC9651819AA6873D1A4EB83B1953843B93422519483FEF0059D36BB2DB1F3D468FB068C86E8973733C398EAF00E1702C6734AD8EB3B620130D6C2B8C904A3BB9307BE5103F8D814505FB6A60AF7937EA6CAA117315E84CC9121AE56FBF39E67ADBD83AD2D3E3BB80843645206BDD9F2F629E3CC49B7" + }, + { + "tcId": 2, + "deferred": false, + "z": "5D473027666FECF7024ABAF175B9BC42E84768C00AE2C5CF27A668121B02CD3A", + "d": "9EFF3FF8252400827F3B4389E4EC07E67948257C744278048C889D0789C5BFFA", + "ek": "3A51932399C6144CA7930C3B9C165BED5BA7B93635D2699EC5C85615254B9B8705D5922A0FCB48C9B561DE4114738BBD2F043E1E0B0DD601A095CA540944A20DE89CD4B637B4AABF983C61381A1CC0F03EC8E82F1D4C62269B1114B2673EB5BEC287703C42AA6B574AE2701EB35C5A017228A7E0B91DBB34537B9B19600DCCB26869813E5B1B1A92D22C5D89CF49BCCB75F3BC8DF9648B634B992141F05BCE85F19E64597D688234AFD830B7B5A41E317ACEF6707A0A60213622564440CD89A520287FDF8556453233282435CC813FA4356478448FE5D63AAF539FD526279F02A47CA692F385A7C2D8448EF6B830424FC7A88329C7B02554B72EB2A0994A649F33254C33001FF72C1034A87D79A34F2894AD0296CA529C029A5238154706C43B76B8568775BC1239C08DA177809BBFCF6A833CB62CF4C0A7103C2C7140963861A3B653A82F008D8D78742F1985B340552723AE6EF4095D22383393065F5B8AC63CCB8974614C1C7222458D5D638FEA48C577EB9D64760898B54411A4926CA95E23AA8DDEC12CB33B8F38131C3229A97757BCADA966CF1CCBFF47758DD14875957BE9607C6F66CEAA00A32DC99E575C6F624BC29AF1CE164A1CC2D5909FF93AC25821FBEA8BCFD27FC9211A0AFA2CEDAA0B1AFC89F7F3362ABC67A52AB88763803273C8B6CB2119831DD0D7774839386838946A9067155808F07A6A846B18024506675A618C8093B6D8C8E7AB47CDC847B60C660E7524737649EB11C481EB6273B28E68075E482C4A727C1FC1C0AF904539D335BFC837BFC7F62225FA8F3692566AF3247832CFE9B6C3A92743B2938CC543374A7637ED3C36724C651DD16499A023D40B07494C3018E39BFF4303BA9A3576D8C9BEAC6F45EAAE48A0ABF4770E9C697EC4E834AE04258F7C5912BA8B76FC613914AE31035276A5015CF75A9F3126AA37BED964CE13340942081DFC620ABA65963E33320912614D18CF69656F30BA15E079BE8A53A9E68C7C5D967469294D8833A81605BDD459A65C194B15F241B0D732A0BC87231B682E84B7AEF151C933C0C83410292017B85AA51537C1CAA114690AE2FFA37B4FBBC3591BD28EC78CB5254E52EA0C474EEE871848C83A5C90E6", + "dk": "FAB74ACD14154B721C4F5446B0020EAEFA1B8CE0897607CBF4DB9CF5472751D8AD3418B76614361B30CE0195596E832DDA286D69270EAFFBBC22E11B1EF4912D02B4F02B4C4E5073A7038BBD793ACFA39C3E92615063B460920BD44B815D02ABB872861EE720D73204FBC98978D228362CBA7FB9B999506137502813F92D7958895EB8C1F3E87CCDD25743F2279E8B2C60FA814860BFBEB52F0C3441FF9265882748A8B88E656C0366CB876BA5C8A32385977C1AF0A710A033277D3C53C2942AD7F250E9B3100B675E5539AC11842C09F717B62C60E85195FC0776F80C80612C273F836C5E9300FD0904D097A7609108EFC8CE4DD1077B951CE95257E2921EAB774A97C33724E295B6C9B72C357C7953BF01D6AE4145A708A1351CB800D60A7EE0FA8348F91C6C054F21403A88EBA965196813AA184C187EDF466AA6CC33F7E11E290508DB822019F50A09965A898BA270D6CE8FE6C6A5F059DC311D9BAC0D9EE289EA323838D317A2CBBF5B9C2296EB18708015B05427278B430E7A99BB5793E9E197666A02FC44514AB7041DBB1608F2B2A4A21ED885449D8566D9575977C3A7BCF45757074C3E3631EF1548453B9068685C35B9C4CBAA3A9F9B5978B03F7274076B99A3860172D038CC1CE2345E5A6FE372249DC3289895A9E567602DFC7A0A047A5625A055109747B09B35BB9CD9412A87F92A7F282258F1594B5A9AE9D38C9768A47D4A7ED108A502C222F2B51A30A46AC90A418F6C3CF953BFB50B9229EABE3FDCC51BE021D94A6F5DC4407954C073F76C509725CD0131130037E1F0A7216BC826E5037EC60F2D736DA4B72185895AEBD41FE6E6BFCC154C00F648A4CC62C686AE787445847C5128C924F7E15046124379258B8D651A14573584B50E95AA0674228DE8D6211D5083D849657E53868C08743B6479711A9B7832B99461C629635F91512C71E5662CA37BD31298FD116A9CC87F7A0036A4A55907CBB2AA640161F8A4FC4B7AA1FAC21D67360570B17A212E6E2B672E29A3C50B9063BCBEADACBA95DBADF509672172415F006E82A313916B6E4CA705EE12AB5447214E60C33A51932399C6144CA7930C3B9C165BED5BA7B93635D2699EC5C85615254B9B8705D5922A0FCB48C9B561DE4114738BBD2F043E1E0B0DD601A095CA540944A20DE89CD4B637B4AABF983C61381A1CC0F03EC8E82F1D4C62269B1114B2673EB5BEC287703C42AA6B574AE2701EB35C5A017228A7E0B91DBB34537B9B19600DCCB26869813E5B1B1A92D22C5D89CF49BCCB75F3BC8DF9648B634B992141F05BCE85F19E64597D688234AFD830B7B5A41E317ACEF6707A0A60213622564440CD89A520287FDF8556453233282435CC813FA4356478448FE5D63AAF539FD526279F02A47CA692F385A7C2D8448EF6B830424FC7A88329C7B02554B72EB2A0994A649F33254C33001FF72C1034A87D79A34F2894AD0296CA529C029A5238154706C43B76B8568775BC1239C08DA177809BBFCF6A833CB62CF4C0A7103C2C7140963861A3B653A82F008D8D78742F1985B340552723AE6EF4095D22383393065F5B8AC63CCB8974614C1C7222458D5D638FEA48C577EB9D64760898B54411A4926CA95E23AA8DDEC12CB33B8F38131C3229A97757BCADA966CF1CCBFF47758DD14875957BE9607C6F66CEAA00A32DC99E575C6F624BC29AF1CE164A1CC2D5909FF93AC25821FBEA8BCFD27FC9211A0AFA2CEDAA0B1AFC89F7F3362ABC67A52AB88763803273C8B6CB2119831DD0D7774839386838946A9067155808F07A6A846B18024506675A618C8093B6D8C8E7AB47CDC847B60C660E7524737649EB11C481EB6273B28E68075E482C4A727C1FC1C0AF904539D335BFC837BFC7F62225FA8F3692566AF3247832CFE9B6C3A92743B2938CC543374A7637ED3C36724C651DD16499A023D40B07494C3018E39BFF4303BA9A3576D8C9BEAC6F45EAAE48A0ABF4770E9C697EC4E834AE04258F7C5912BA8B76FC613914AE31035276A5015CF75A9F3126AA37BED964CE13340942081DFC620ABA65963E33320912614D18CF69656F30BA15E079BE8A53A9E68C7C5D967469294D8833A81605BDD459A65C194B15F241B0D732A0BC87231B682E84B7AEF151C933C0C83410292017B85AA51537C1CAA114690AE2FFA37B4FBBC3591BD28EC78CB5254E52EA0C474EEE871848C83A5C90E6A8ADE3E0536F87E2E908AA77EC32AD0A8555B3045331059C5AEBBADA69D0F0735D473027666FECF7024ABAF175B9BC42E84768C00AE2C5CF27A668121B02CD3A" + }, + { + "tcId": 3, + "deferred": false, + "z": "7A7FC526215D5AE3262985D17B00726462D1479CB038DE8C8A8FEA896A037B2C", + "d": "C6636E8C2F87DD52A7F165A2A3BAD562ADB28CF738AA56B996B6062E95F66148", + "ek": "FA66C756BA9DAF40BBBEE9473B35BD71AC1DFA52A33D4A47B9BBC7EA9524DD344E086A6A0CC72941B645B3D49F6D12382CDBB843883F723078D096169F1373C6C8C5132260116963A0316E7D4268D6E36946E1AFC0457CABB3B848190E52A27BBFA42F7EBC0839E52E43611C6E49ABFD97299C4804BD08376020CC21B92BEB1B6D43EA52155B2E8D8B36B584807ACC96F237AD8365C822C66DDFD8A313849E8481A61116939CA8281EFC3D446B6CAA7583EB086FA5214DA67CA46DF75D25537A8C970CA718113DB96392B92435A88053D9141C2BC646D801E9697ED9C35A008AAB59245F56D74F64D1A81DABAB29C4571A6AC000501F1426A7AAAB5F44D4BD4BFB6E8D1CA75AE7949161B10DF906BF72BC460A08C346B5B3A5A6D3325E628546D6F4AF26F92FAEE81C97CBA29E06691AB64F185595B1F35A97A9BCB7E0011AAB485CB4ACA1E04DC534192A0B0E3C248BCF197E7D9B4A317C75C59812ED1694084CBBB8A40EDE334832B714AEA19DC2EA645CD0C3113C31C68379E9ECB5875C58C77B3084709062D77C72416CAC063D04FAA8A7825254CB2B539A78E3197D56153D4E775FF04930DF90546FC145493152A1D37FEA05A86C1A88FD86A8EF32C00B7A5EB04989AA9317C49AC7E9AC82032715F1B4CA448ACDF51198FD1BBA4FC00D1E22693572B0E1F71CF768ACE73C9733F2250B8A7BA3B74D8C12383B465C1D33881411C143FCB621C5CCD7469259A96330343352B699B7C5B850534145E10271897656F4328864A0FAC59C7886B854E8B6D7981307AB4F8B222AAA200D3435562B95554FCA31A0533B5581087AF492E444647F27789A1BC501016079B8C4F5208B0D2574206C7E6A63147950AD0190751E9C3EC0621DF05539A724732069C9D0CB2B7D77940A9A9C0AE40A4410B73B6747A1625D0548BB4AB337CED7442F55063D58CBBC6C6F70B839C8303CFB17ABEE195283A6010DA5BF86A20F7522B9CD0B9F59204C2DF50424AB659280BC27E72916542A0918AA5D618AA739729039169C7838838022E1E61805C83BDBD84BCA9A7C936060D9722DE33B2F3882075028BE255365C5523B6A9BDD23CD16255D8240B07F18D481D988D769FD9588C0BA064E", + "dk": "8D0A672A78C8D3C6A7F4608806D062DE426BF05360F33A000DA72551D56250BB8A8DA19A553A79FCD0ADE3989D1C999C5A57B58761A2D34B7F6B202910384BB38473931356E801B67BF5CDFEA96E7F541982534821D6818FA20829AB9F3F3AA05C4096A1CBB0E907634E7707E2A73DF8C213E118742CC12E0353C9D0B3BAEB296A8EE69FC5D312AA3554C2176411D009D67BAA4F07B45F5B55DFF00713CC3408C46F37389BCF149945B437EB234C81F724FAD57156D370FBF5B726193371A58C48176F8AE9A339DB91A7D7047B55C060DA7EDD910D20ABB6BB9905B41500F3246FABF1AC56BA0D2925600E333E241B72C44ABA71DBBDE6E55197B225D5C42BDD8C62E3313161DBA36094A98D555F99134CFC2382E5877D2530397FC48E7E5AA90676A7B41468C042433C09A09F7C9B5F633E636B316244191F00CF053ABA7365905B7BAA716A9645E54F75706610058761F7113D689320514D38A60A44F8191FAA5C3B13910E4218A703C98E48754B4431F630676928B5641807182C74A3A45B8E8B9568BA210EF8BACA4300E98592533A965FAB9EDD8B3004442E04340C3D3B8528283344E262B9F755E1223EE8108073A36DDF17C9DDF00276B5AC81339E1D8AC541BBB65E5A8D3857B28E60C516A75CA109C7A602B66EA6C9B0B4BBCB27C4F93C8EC44472DA9A7D7AF195DEC6547992AB8ACBBCEDCC87E88140D765518DDB3779F57C8C02C75FAB9515C3807F02740361280B539048DCB6ABB875FA6659E3083834DC450C67BE32D9709F8651840C5A4FB96B048677F9E735FCC1B0BC09CE2F1C39FEA8B0D29193EC886D02F23A413AB7E98001CDE7C8D4F69AB60C6C9270159931702BF5AA226936E7D0B53B29722AE3B29C497B5B74747061838FD8978BC2249FE83A453C3AFF02C67D6B563CE7B3FCDA452C52CA3E1282C4EB90683999FAF29D509BC4E4C41023E332E3C82433AC4371B84824B07C05A1B76D58BCE86AAAEC5AB0DD09A774291A65705BD0764A00C5CFA859938F942EE72C5520E26DD1C27B4C87C77712266DF6819A5C5A39BA8CB9667F862AC66E40069022BACA0B91FA66C756BA9DAF40BBBEE9473B35BD71AC1DFA52A33D4A47B9BBC7EA9524DD344E086A6A0CC72941B645B3D49F6D12382CDBB843883F723078D096169F1373C6C8C5132260116963A0316E7D4268D6E36946E1AFC0457CABB3B848190E52A27BBFA42F7EBC0839E52E43611C6E49ABFD97299C4804BD08376020CC21B92BEB1B6D43EA52155B2E8D8B36B584807ACC96F237AD8365C822C66DDFD8A313849E8481A61116939CA8281EFC3D446B6CAA7583EB086FA5214DA67CA46DF75D25537A8C970CA718113DB96392B92435A88053D9141C2BC646D801E9697ED9C35A008AAB59245F56D74F64D1A81DABAB29C4571A6AC000501F1426A7AAAB5F44D4BD4BFB6E8D1CA75AE7949161B10DF906BF72BC460A08C346B5B3A5A6D3325E628546D6F4AF26F92FAEE81C97CBA29E06691AB64F185595B1F35A97A9BCB7E0011AAB485CB4ACA1E04DC534192A0B0E3C248BCF197E7D9B4A317C75C59812ED1694084CBBB8A40EDE334832B714AEA19DC2EA645CD0C3113C31C68379E9ECB5875C58C77B3084709062D77C72416CAC063D04FAA8A7825254CB2B539A78E3197D56153D4E775FF04930DF90546FC145493152A1D37FEA05A86C1A88FD86A8EF32C00B7A5EB04989AA9317C49AC7E9AC82032715F1B4CA448ACDF51198FD1BBA4FC00D1E22693572B0E1F71CF768ACE73C9733F2250B8A7BA3B74D8C12383B465C1D33881411C143FCB621C5CCD7469259A96330343352B699B7C5B850534145E10271897656F4328864A0FAC59C7886B854E8B6D7981307AB4F8B222AAA200D3435562B95554FCA31A0533B5581087AF492E444647F27789A1BC501016079B8C4F5208B0D2574206C7E6A63147950AD0190751E9C3EC0621DF05539A724732069C9D0CB2B7D77940A9A9C0AE40A4410B73B6747A1625D0548BB4AB337CED7442F55063D58CBBC6C6F70B839C8303CFB17ABEE195283A6010DA5BF86A20F7522B9CD0B9F59204C2DF50424AB659280BC27E72916542A0918AA5D618AA739729039169C7838838022E1E61805C83BDBD84BCA9A7C936060D9722DE33B2F3882075028BE255365C5523B6A9BDD23CD16255D8240B07F18D481D988D769FD9588C0BA064E851F4FBEBBC2AB265691CDBF130A1A566398C6316707F7A9AE78ECC419698DD97A7FC526215D5AE3262985D17B00726462D1479CB038DE8C8A8FEA896A037B2C" + }, + { + "tcId": 4, + "deferred": false, + "z": "6E584B168BB5399D52B458A8BD122DE14EEF214515B70F38F972F41783005755", + "d": "EDE2E63FDEE6ADA2FC6EA906AA8D92DE87FA6199AC15446B0B6F075BF9F76148", + "ek": "72828AB4196357F09AA50129BCA411CE9255422C4AC1C492A2A60544C26B8F37A7EC9B053F27656AB1AE2BE0B1C95346083C15C8F89AD92C477D5C03BB95AC4F8B6A1C9BAA8D199F1D83823072082737BEBBCC1BC1E7BFF9742C4AE86313001F2519C8E93080C2AA1D63376BD61C31BC189BCA8C8385E5A7B3A69380EB72F14B164166227B453C6F43C59A34A8B6724193D77858113AB5C90B2A605F5C3C8E3FF8BDDF82C82F0C3045A7CEBA99891A60016C660BE767809977CAE5B8ADA668BEAC5374CE54692DD02F51E9A90BC68C51955797975F63707E1DF3AC14BC877529A02EF7A317976EA722CA3B80A316B2688B074108F05C3CAAAEB0241D1C5B05D458A150B692E288CE47CCABAE255B9EA13F80D16066155B2E46524BA5A3BDF74C9F77A25402CFB4439C497C03314465C4A91152671E4F79239937BEC7A72DAB0B97B30C1A00F100216B1E2AB67C6520608F54BC92985504033CE63363E015B9E0C9BF75CC2F90AA9E09DBC221258B389585927905DE077927D3AF6C59309B12B3DDD0029BE56EC0CC1CF8AA3A5041BD954B0B7DB68AF2BC02284C9FCBF954875816DAA11E6668455C8978A247B4011B1010289EC564999D069AA2392E9CD9A0E45636C014315C15AFB5148F513CC87EEB8B56334ECA1C061058C06B3C285DA8203DCCBEA8B750E9D43E8CB837F1AA0635954A924C866C33441E7C0C23C97CF62CAE10D32C2A641C1538C2A7B1C4DBB7BF069B43D4210941A4AA0E41748D788AE831018BE1916D056AE4598834B6BD56AB86C3B7528456751B33A0406A2FCF8C0FE18C25A1C208A5A4CDBE593DA6581E27C6A5B4DB793154233CA5B3C2469A80F8C8D3C22C25A8537270CAD4480B20D47C6AC56EDAD91BFFEACBF605AD61C44BF86B7624B95CB1A5248E9210D9F18837FCB01EC68BF434725FB75FF67C016DD78E303C2C6E775D17E61642776368F17F467BC9E0E153659C5219678490BC110B8184B556A2AD275FE6913B6BC744DF313EECDB273CD637A84234601599F05C6B358312FDD959E20B81A434A6FE200AF26A50C670837E8266303A7C23219F18A670CE910DF8756E403C31C561245110CD2DE051B61979D5BCFCC3E03F68C1D3412C", + "dk": "871B000F61C393DA0F0C56B0CA4135223162F177373BB58BA97856F3A0AAAF9540AE6BB239C5221D6B3CC3BB623B5ABBA1D7CE45A75571E01B6AD429B4A1A73E0130DF3947BCE4123AE4A9AEB52987D4BEC94446CD70AECEC5CC98EA13DF3A323D8BB48B08B07161499CA76962737F36A17A4F83045B78AA33879BEED71287B70C35B92BB01AB9E7B0813DCA539F63CAC3B87B419A852104B73F05979BD8296D0967E58A6333F88E8CCC9A8A4A4E0CE25A57851FB0F568665163553BC200C190C9178526FB53328119E99C42EFC0C77729BD6873900394CAD9197E37C00FE9C703CB25AA54E73DA5A41132C1B9ACA95ABD4508872B1F6B8288477998A0842E58B1BC9CE061CEC2703AEBBD3C230AFCD2AE7E576126BC72A7925BFED55E62C06E16187E24086452344B8A5A5A462522AB693A88F57C69835DF0A603145C6DF2244A1F221977AB54C3E2023363A72F277217E15E616B54D6BB3959E3322EC9A276B7434A796BB5296E83407999F16408B11DDC79CBCEB46D01033C5FD091300855D7E64536480DD945CD33CC9D4221ABE5014D068BAE1851717633AE03E6627BB17976ECCE84807D5C2602030844AFB30994D26CDAA0C71AB591AE6069403C13E4B6BA89439F2C5393955AA1C4A6270339505B59009DA51527C33334D6903DF3A37613546F076AEE723046C13FFC729D64583A4A01CAB68C5C95C25706F0A918635E61A390FDA5745A9756EE32975CA4483982505981A3589232EAC3C0C31748A49429A711CBC16355DDD10660557C9270438D9635850918AA366A34B251F311C65C579FBBD2341A53CB79BC9A993475CB6AB9455B82A9DB5EBA53592EEC9A2C481792798A1483037F115336FAA8A4B07AC253B0A347227A7B12E3197531F875C91B0A636107CB38BB0BD613B057869403A77DDA0A80A26266B61D14A75433B99BA055A7FB625C4A17BE9A92B2E168899B6539972B4BC674040645496972617FF70DF5EB63B17B03F54BCAEB3118C4F31EAE075D2C1C9F1D5036FEA818A539ADEA50795AC933EC886FCC248E49F12DBBD23D8F812BE0678B19888116254A27B5A372828AB4196357F09AA50129BCA411CE9255422C4AC1C492A2A60544C26B8F37A7EC9B053F27656AB1AE2BE0B1C95346083C15C8F89AD92C477D5C03BB95AC4F8B6A1C9BAA8D199F1D83823072082737BEBBCC1BC1E7BFF9742C4AE86313001F2519C8E93080C2AA1D63376BD61C31BC189BCA8C8385E5A7B3A69380EB72F14B164166227B453C6F43C59A34A8B6724193D77858113AB5C90B2A605F5C3C8E3FF8BDDF82C82F0C3045A7CEBA99891A60016C660BE767809977CAE5B8ADA668BEAC5374CE54692DD02F51E9A90BC68C51955797975F63707E1DF3AC14BC877529A02EF7A317976EA722CA3B80A316B2688B074108F05C3CAAAEB0241D1C5B05D458A150B692E288CE47CCABAE255B9EA13F80D16066155B2E46524BA5A3BDF74C9F77A25402CFB4439C497C03314465C4A91152671E4F79239937BEC7A72DAB0B97B30C1A00F100216B1E2AB67C6520608F54BC92985504033CE63363E015B9E0C9BF75CC2F90AA9E09DBC221258B389585927905DE077927D3AF6C59309B12B3DDD0029BE56EC0CC1CF8AA3A5041BD954B0B7DB68AF2BC02284C9FCBF954875816DAA11E6668455C8978A247B4011B1010289EC564999D069AA2392E9CD9A0E45636C014315C15AFB5148F513CC87EEB8B56334ECA1C061058C06B3C285DA8203DCCBEA8B750E9D43E8CB837F1AA0635954A924C866C33441E7C0C23C97CF62CAE10D32C2A641C1538C2A7B1C4DBB7BF069B43D4210941A4AA0E41748D788AE831018BE1916D056AE4598834B6BD56AB86C3B7528456751B33A0406A2FCF8C0FE18C25A1C208A5A4CDBE593DA6581E27C6A5B4DB793154233CA5B3C2469A80F8C8D3C22C25A8537270CAD4480B20D47C6AC56EDAD91BFFEACBF605AD61C44BF86B7624B95CB1A5248E9210D9F18837FCB01EC68BF434725FB75FF67C016DD78E303C2C6E775D17E61642776368F17F467BC9E0E153659C5219678490BC110B8184B556A2AD275FE6913B6BC744DF313EECDB273CD637A84234601599F05C6B358312FDD959E20B81A434A6FE200AF26A50C670837E8266303A7C23219F18A670CE910DF8756E403C31C561245110CD2DE051B61979D5BCFCC3E03F68C1D3412CE81BFE29AC4AA0EDF35537F3ADEEF43D0411B85C7E1D1C54612167DCE488EBE36E584B168BB5399D52B458A8BD122DE14EEF214515B70F38F972F41783005755" + }, + { + "tcId": 5, + "deferred": false, + "z": "37B87F960BF862D8B81AB5F56E9E24ED8EB011A05867A04DEC9BAA519AF45E22", + "d": "CD568FB1EEC23C436C011A55BE2FD4362EF000C890BDE7611EB5C4618AB74F8B", + "ek": "F2137B2BD0A33F81C4DF584BB46C60FED985D09589C125A6F7A9C4B3132F7BF4A4B4A268BB52702C3B5DED770B3AA30EC2708B93500C5E3C6998FB6EA1586EAE409B6D617C330827F2A417DEB0007C78C8F8C025B8C3415A31313378536EA672FF92625B3443EBE61836421841750E1372A81BA99825B67898F2009E4AC8D5F89396724B7BF29E16C72C1DF192AA5277F01A5428B4AF8B284D85D987E015AE1CB89AD9C9230E2313601B5B49416D0B18B9D75326123A02E363C444993213D387A1C7A021449FE4E35C4FC30DF0066CEA593BF7DA67EF6322537802CF068E2D56B178F929A630C3A5043528A489928CBE1A1468F2802F8F890C042114426BCE7FA6A335441BF1B159410C62FED916CEF3B0D6F0B54FDC3ABF9778743A87D3F417EE573897B45CD5BA4F893CB13AA077A696BB37DBA964D0189FD83DC725129D9425D9291652CC84EB3145FDC88482407748985D72C124EC835CD800BB11F81415A44E474BC553998C1CA945FBB0035EDA52B93B3D341A29E7F808418AAD2FE388D0483E15F68E3B903E7D9C6E051347B1988B6A0A441C8B1FA05C743CBA003BA946BF07996EE14F9E93AC88382CD7F2CE8028352CA7C36A73C9303337CF5377AEA685718C8802B7683019892A904C5ADA3661C1CCA5B4CCB81350D8484BA34CA49AC15B9DA09E1E6887A10802060AB20E04B0142367BEE71CFE023A15602BA83B7761FB08CF79424715CB6CF563E2ACB3E11CA3D6C4095084779213275E13A1E7F14389C301AD53CDE6369E6A9058CE282530593A9E8B1BF38BA08F40B85A94678B619550C437411861B957528CD0175170A1F2308B766209EBF454B4AC4E24C1B230CC793C935770543831131CE38A77A7248C43C79814A03E35D8CBFE02A4F5482E73B1B7F41569E42443A733CFA185B63A120809007A46D5C718C003DE2945B295C0EC42C30EF5BDA5107ADB2125A5E61575382F961C43A585C7400C5AAFBA2BCF595C71C94F0F59CE48904531E0C2EB862C4E66CD6CF280A84B926C42489CCA778A587F0935B7CA369B1140594A1114DDCA6A6F104671CA26E8804EE0D0513F39519217F5A027363BAA21AA561E954B5494D2482873722C7BF20ACCA9B880", + "dk": "DAF41A7FBA550B084674F174453A18D33994460409F80232044AB7411865F90281EA191165940794957CB0C26E1609B941117C38350F653A04E28438D54C3452379687EBBE463A4A7447CEE3836E7EACBFEE6AAFD5114DF0A595C9F98FD85C2DE879857236CDD0287B2F0041E58390C5510E1D288B0F690A49451B1F7002E13594CE71045AB1B455A280377393F54A0BB0C44EE06C024733675A1821E619434401608A824F86ABBB55B07B1DBB7A96B0B88C6885735966DCEC666CA3281352B8651A8C13E48C52C61220572676E500A6E0A5FFD238A76CA6FF29915CC975B3E5B3B6819C61495410F095023077EC3CB282675578C948B01C63146B8904C56A1D419B1FC0AC8E5B5CFEDA4D8A8A562206B4A8E93EDD180936960CCD206964EA5CD9D4BFD3540A4D5BB2AF302A7594820EF8115F2B0E38324EB024AD5E6AC92584C681D5A42079450EC464B900BEC5D9B8268A843A5095D2F41DCD648CF30B746F6C4EFDD77A5C432100073CA36B61C0EC4C4D64341A675E9E06369EC30D0E63CB702B6D32CC1DA0253D4CFB08E2255FA5A3B29305520AB737B5D820A0817EC5BB4A99C8936A5B396D927FA97177573CA01E568A67EC059E897A75E058429BA03321B2D190BFF5F8A4C1AA3CFF7A54EF3BBECFE4985BF253B2F126B092A8808175C0AC253C6C9BCDF3710C7B90FDC77B4F95BFEDF78347E72F806191FDB4481CD7794A993EABA23AF5E76A081243D54C118868BC1C51A2AC00808196573326AF95A1B4A4DA8AE0173588A978130772792284AF456E8B651A974A09D5795F0BE0B08F1570A6C21B33440FAE93966071ACEC727FD74728E4A9A1EC7687AA2884BB6B4A599129F857113637BF248C54CABC6BDA91739036B7B605491625062678638BDA4F111BA376DA0D04262BA8A082FCEA37E9C82FFFB330BB15506FE8038D6CAED266BC63316BECD6400DD7297E76068FE16A7EE6A13900857AB6C2D8234BAF41C4967C2535F9BF8F888DC655887B5C74F6D17A9AB2AB16F02D57D311CF6700CB238C297489C5016A09A15BAE7428128B158C23000E80A88978993E956489B93BF2137B2BD0A33F81C4DF584BB46C60FED985D09589C125A6F7A9C4B3132F7BF4A4B4A268BB52702C3B5DED770B3AA30EC2708B93500C5E3C6998FB6EA1586EAE409B6D617C330827F2A417DEB0007C78C8F8C025B8C3415A31313378536EA672FF92625B3443EBE61836421841750E1372A81BA99825B67898F2009E4AC8D5F89396724B7BF29E16C72C1DF192AA5277F01A5428B4AF8B284D85D987E015AE1CB89AD9C9230E2313601B5B49416D0B18B9D75326123A02E363C444993213D387A1C7A021449FE4E35C4FC30DF0066CEA593BF7DA67EF6322537802CF068E2D56B178F929A630C3A5043528A489928CBE1A1468F2802F8F890C042114426BCE7FA6A335441BF1B159410C62FED916CEF3B0D6F0B54FDC3ABF9778743A87D3F417EE573897B45CD5BA4F893CB13AA077A696BB37DBA964D0189FD83DC725129D9425D9291652CC84EB3145FDC88482407748985D72C124EC835CD800BB11F81415A44E474BC553998C1CA945FBB0035EDA52B93B3D341A29E7F808418AAD2FE388D0483E15F68E3B903E7D9C6E051347B1988B6A0A441C8B1FA05C743CBA003BA946BF07996EE14F9E93AC88382CD7F2CE8028352CA7C36A73C9303337CF5377AEA685718C8802B7683019892A904C5ADA3661C1CCA5B4CCB81350D8484BA34CA49AC15B9DA09E1E6887A10802060AB20E04B0142367BEE71CFE023A15602BA83B7761FB08CF79424715CB6CF563E2ACB3E11CA3D6C4095084779213275E13A1E7F14389C301AD53CDE6369E6A9058CE282530593A9E8B1BF38BA08F40B85A94678B619550C437411861B957528CD0175170A1F2308B766209EBF454B4AC4E24C1B230CC793C935770543831131CE38A77A7248C43C79814A03E35D8CBFE02A4F5482E73B1B7F41569E42443A733CFA185B63A120809007A46D5C718C003DE2945B295C0EC42C30EF5BDA5107ADB2125A5E61575382F961C43A585C7400C5AAFBA2BCF595C71C94F0F59CE48904531E0C2EB862C4E66CD6CF280A84B926C42489CCA778A587F0935B7CA369B1140594A1114DDCA6A6F104671CA26E8804EE0D0513F39519217F5A027363BAA21AA561E954B5494D2482873722C7BF20ACCA9B880BC69A3AF4B4C837C8018E52F6A1466D86D23BDBECBDD1F610245F0A670ED311637B87F960BF862D8B81AB5F56E9E24ED8EB011A05867A04DEC9BAA519AF45E22" + }, + { + "tcId": 6, + "deferred": false, + "z": "4B0A877F51434F70E2D8DB0A51BEB0A7572EF0DB7AC26ABC5D333C503B68BD5E", + "d": "35DEE1F800CA85E482BB12AFDB882FAE62CC77A338E65CA2265D77243ADAE3F3", + "ek": "49B884A964CAE5E0223906A09366063C46250A551DE820A58FF3CDE2C69719316B91F6CF1178768B082F97822DF4D6172ED11876940230978B6B0156EC190C462BA75DE722E206535564A68F311C7EE015701CCD7E954B5B4074CF43CE700C70B221ABB2198FE63639D622669F309855C490F916BF39917E3E440C97FA6BFF270AF540476215A8845A88D3E3528F6715E86C26164B86F28263B01123DD05553B8964775B0C4E50A8DFE08CBF08B830A0973A963A09C1B077564EBC355A07546BCF2422C42500F9B26F586B2873ABC392633555F72126A2B51EC935333939C73580E44314407ABEB4B06DFC570287C5B758E8AC30A6B2E912833E2B72C55CB9BAC9BA7FB2AC03E560796480EF9A4342D49A6FC19E5C1A9386826C42EC6319759B1CA260D43247A0756E857A00D05B78AF65A9759159EEEB72E7118CB6D039930584111A8F2E0CB5FB449423871F7030AB5908B964C2ADE84195802521C16088D14403EBEAC1A7963BD9DA827DF908752568B230919791A6F21AADDDC05E77525FAD0323F215215DF107B4A3474DE3711A447192537145127D7CF2B33F9A4268106B2CE487612B000E6B9520CCC70D7225E2A6055ADA0DB8F024333AB1EF182C8309A697666FE2850C29A1B7B9394DCDDA8AADB9C3EE2910AD1CA85E34874ACCA693C8CDCB66A477E38CF1B5AF5B97260377B4A43B8C0E085C41F5B2EE44B4A7CA1D58D9720C62475986798C13C1A8887F3EC660C04C92F0AA7F0C581407F67CA03247DFC5AE411CBC6F3BBC6F16CA66B8389BBABC9193C22858AF6BFCCF5A4595747B9F9F9BA043E69DFE06110BF970B2F4C9FF1A149F76CC4A64C7C283A716791EA6CC6B3554367A83AE1545054B02A725185EC8042966F10F3F3B4EAA872DEBF7B10947986D1884F3C59116538A85537016B03BA4B7A156061EED350BD04868A60C93ABBB05F97314BAC935EF99BB4301C4EE6A59936443A7298F0584980E588E76CA44F12182DCBACED7F90F4C864F8747C0F2B6A796083656FB9953495787071E61B41B46B582771320B8969C9B5941055637D69A5D0DF3C798D00D16E7259CAB3C67520D2FDE0A3C05715DE22382E369D7644EA2C180C0FC5385E6394054", + "dk": "4795036ADB898D0B5E69AA2F9913270B8899A97750A219C2B88C2BC0795CBE255E04E959A081263087706619A1C9C19FE54C05B14B1BF3E5910E128643771DA298839CFA2D752836B1759C5B58CFCD3B4782976EA96729315958FCB11C66B25F0A1B57EB85B1B892A0937A877C4508796B3D6DF66CC19598D55B9842C848A7485CF87ABB2A340497CAB032376E16613B55147C78864B7D0B9AB1F52985F32561A3A80AA4BE63588983E90EC659B2C9FC45207972C8199B46095BB56B878E256732C892C9395021521780D40778C4BCA06C91404428FEB050F44225CE0693972796A3D2AC3C028377782F9C26528F45962175C42B526872E6B34D95355BD0B1EAA2707B6C2A7F1074217CAA1EE842C4064A5D556B9F70C37A7C52CB468694245E427CC71959B390BAA5FF744869165189C1A4A43BB3D39A9799A17305999A9F3171711398FB412D3BC4625FF04444B0557A765FE785414BF08B308A5F44A64CEA59988F294483F623063B602D55624BE494F2D057396883D48995D10080AB399663C00FE0E17162B2C47A19BD2A69CDB2DB76A3861336F04C2FE0A498FC9698C34BDCE751CCC3C9D4E9539CAA0C6523C1C3AA87C65908D9045203C32AB19442F0065CB1003E02E735999441DBB7ACB1E73C92C62E87D7A4A65A508829739A576B13A7C94331146EA66897248B4887862A4152B72B2FC1B9C7CC7447C8E449EE93BCB5F88AFC43226EE51AD47BB548C665A9A2833AB7938FE403A602051685A3CC89B4AA6225E47564DD09D05B101CAC312369A54B320194710AC53DF57C5479A7485250D1EACD5B8BB19069266A03C852F81947A1BAC5005E344447A9DB5FC4B87255C638524A9ED255BDB9700B31D514A5A72E08A51F42D963D71A88BF605E29C41EB8C88D48BCC0493CAE6129BA4B046B54AA08177634C8E8B1A5A948301256D3C3B6A9A8808B2B0F3716CBBF196427C661F342CC7B50CDB56990AD252242C2C996FC98DE1A26374C0575DB6773937F0E86A16F051D59DCBFA88058BC4801E096BAF9866B9C5A01A922A6EEA34D22CA346975BADBD28454821EFA0B1288281849B884A964CAE5E0223906A09366063C46250A551DE820A58FF3CDE2C69719316B91F6CF1178768B082F97822DF4D6172ED11876940230978B6B0156EC190C462BA75DE722E206535564A68F311C7EE015701CCD7E954B5B4074CF43CE700C70B221ABB2198FE63639D622669F309855C490F916BF39917E3E440C97FA6BFF270AF540476215A8845A88D3E3528F6715E86C26164B86F28263B01123DD05553B8964775B0C4E50A8DFE08CBF08B830A0973A963A09C1B077564EBC355A07546BCF2422C42500F9B26F586B2873ABC392633555F72126A2B51EC935333939C73580E44314407ABEB4B06DFC570287C5B758E8AC30A6B2E912833E2B72C55CB9BAC9BA7FB2AC03E560796480EF9A4342D49A6FC19E5C1A9386826C42EC6319759B1CA260D43247A0756E857A00D05B78AF65A9759159EEEB72E7118CB6D039930584111A8F2E0CB5FB449423871F7030AB5908B964C2ADE84195802521C16088D14403EBEAC1A7963BD9DA827DF908752568B230919791A6F21AADDDC05E77525FAD0323F215215DF107B4A3474DE3711A447192537145127D7CF2B33F9A4268106B2CE487612B000E6B9520CCC70D7225E2A6055ADA0DB8F024333AB1EF182C8309A697666FE2850C29A1B7B9394DCDDA8AADB9C3EE2910AD1CA85E34874ACCA693C8CDCB66A477E38CF1B5AF5B97260377B4A43B8C0E085C41F5B2EE44B4A7CA1D58D9720C62475986798C13C1A8887F3EC660C04C92F0AA7F0C581407F67CA03247DFC5AE411CBC6F3BBC6F16CA66B8389BBABC9193C22858AF6BFCCF5A4595747B9F9F9BA043E69DFE06110BF970B2F4C9FF1A149F76CC4A64C7C283A716791EA6CC6B3554367A83AE1545054B02A725185EC8042966F10F3F3B4EAA872DEBF7B10947986D1884F3C59116538A85537016B03BA4B7A156061EED350BD04868A60C93ABBB05F97314BAC935EF99BB4301C4EE6A59936443A7298F0584980E588E76CA44F12182DCBACED7F90F4C864F8747C0F2B6A796083656FB9953495787071E61B41B46B582771320B8969C9B5941055637D69A5D0DF3C798D00D16E7259CAB3C67520D2FDE0A3C05715DE22382E369D7644EA2C180C0FC5385E6394054BAEFAE1CB7C96BC32E97C146C2AD302DB01C6E7B8E43BC7A236C00C6FCA6F17C4B0A877F51434F70E2D8DB0A51BEB0A7572EF0DB7AC26ABC5D333C503B68BD5E" + }, + { + "tcId": 7, + "deferred": false, + "z": "B1EF909D94C56C134107B913B0ED29BC0851CCE424D0FB69EDC04C685A540871", + "d": "D9502C86FB461300B8D142A906B766B0B42481EA9C83AAE2BB74390F882B0509", + "ek": "36C0A54CE714E66B18D200AF7C822E555A9BCE32884D2313C0012FDB81436D8038C37258EDECB2EABC9174974758C55DCE98933322B49CE815DE3B83F3F4A7C0D7CEC0D2A08D68475853B64D21ACEE3C74BAF17C19306BFFEAAD2303ABFEB0AE941839A4F69B48B23447081BC42BC1CEC648C9D1B319E778DDBB262A7B7D0A0946E5B7B71AD54E881C42AA6B1DF268B998D45C2CA18B9F35900A6106F1D8CF88F07C37A7AE283AAAF1B94BCAC6A102F631053760C57B157A098FF4F47B023527BD526365259898484211749AD8493ACBA57C2E02C346EA5032553F2F590F785B7691C83DEB9C7124318969FBBEB81C361F6CADF4EA78C27185CD9B9BD99670ECB41F56C4CC261A39EC251DF34A144B189E108094244557F217312B1BA083F7804928C4950950CF75555BB0B7140406F38CC8B9D21449A756AEC213328AAFD6A8596BB20152BA888F4A591CE162968BC263984655F332ED420473FB6DD0BCCA2D0A3595E43046C61AF6D6317C123BC18AAD6E80736F41BF97134CA7DB2DA8C963F9E2518D865F7FB770C5BA20C2501B44A36E13782583C1579133260E41A77871CB0CD7827D7015FB66251EE9622EEC007FA88227C153B9E7509866AC836A85BF960182F14032606123608E302C0C07D2BDF79B9C398CC437A7A3A2688E0327418B483D1C2B6C3B92B76554A7E14555BF742180FC7F2036C260F50AF5D47AD24033FC62B08A6C10E2F0096B4C5EC5DA8260D2CF9B3816C92A353148C19AC410466C05699209C6B0628A5CA12472544AA822442B93D4F549F5C94A54C4A3BEE5A9375B55B69C77DC260AFE242F6333591279AD1E269D36F02722F62D235186074B3B1AD1C731E0A36996672E74797DC7BA677AA577A523FD38A4A3FA71B7782185911BD837432920A753996776465D33692C859252E294622EE86F2340A5BB624898774851B587B6203A7E94CC909623D027C9EF06493596B9E6A63C02A4CAD21B2EC4792C6FA70ED9AB90D8988F85D24BB37579D4A71C0823167DCC30382178E12C2082AC70F1D7A2DE652296A203D93C2E3CC1473C411C17390BB0ECA50981905AD7F76DCD197C5867AF1F94E3221BF042DCDC99B3B3679587BB2507C464618D", + "dk": "F9AA2D50611583687E826193429B23F39B07E2988D6A018D98E05E01A853C40BA5E321730868A55D245769F17CAE243F39D6389346A307934BEE6A011C4A00ED72610E61548A64C5F2D98BFAC484518C4304E454289CAD24A5BBFD3717AB191E5C83AEE1E22CC1B756C147786A13580715B3482A5301D2271588BE13374251B68EDF6024AE553F1BCB83CFECBB4DA1A0E759627A37BF3F83B73E267D40F867629380482CA32D6743A5C8565C7AC3DB3542813B010E98642B490B361638483728B47737A1B8367EDCC93D8B3960EB963038184AB09DF1945A154A8437556CE659054AA64D81048032375D795A21C89B5F5DB68DF203C496A06CD9B26B6331B2B00BC5ABC95DD6BB596DA819958A11A2F57A8C85C9471691F7570F41C0390C6571BFA22A91909BC9C09070C0B1A0F5AEBE59ABF0C3C36B2C17A5D1767454C15697C10CE453A1597F63440D6127A09941A5FB3A96DFFC86C82015BC623986E6BE7CB02AAA23B5D5E26E4CE01F8FD91D99B637A5BCAA23532D46B993D4EC5797C28EC6D248589CAC83A600A7D555E3EA7F07D09726B174AF282162A3B268A5280CFB6AAD7012E7E639598AA2003D9DD6707FA285AD334619978BA227B879B1F37DF83157DA95B5DE8CB66A01D036E766262719E21224A65932C6D1185676598BDC51C4A29330BB8C4B5176A069B93848B57BD24AD5F277A5681674138B5C1CA73075706C9797D6F8BF23E2AE5DB44D5D6B4144C09AC9C6BF6E556790968717C847A6C01AB99215162BC5B2DB6E02E19ED568A56C54BA4735A793DB473BE5708C705C784B9EE2E02532855F2F420608990101E34CA930C63A0833744B67965BCE0C1ACA3D67793DB7BCEFB32A7D378D38E87209F69C66097908EB8B07A94584335F37C44586A55C5024847C654B97C85BACE70B495559BCB60AB1625525E808DCA2496F549C8130CCAF60BDC3F782DA61AA98E03A80C05C6AF99308165B1291AE613C97C646A46E05AB87796DF6447E1D8326C03A7E9D7921BE218B69D469BA2449E5C714B7C5B1385C407BE14E7A978566E27409B72D04B9540FDC43D7BA0C95754C36C0A54CE714E66B18D200AF7C822E555A9BCE32884D2313C0012FDB81436D8038C37258EDECB2EABC9174974758C55DCE98933322B49CE815DE3B83F3F4A7C0D7CEC0D2A08D68475853B64D21ACEE3C74BAF17C19306BFFEAAD2303ABFEB0AE941839A4F69B48B23447081BC42BC1CEC648C9D1B319E778DDBB262A7B7D0A0946E5B7B71AD54E881C42AA6B1DF268B998D45C2CA18B9F35900A6106F1D8CF88F07C37A7AE283AAAF1B94BCAC6A102F631053760C57B157A098FF4F47B023527BD526365259898484211749AD8493ACBA57C2E02C346EA5032553F2F590F785B7691C83DEB9C7124318969FBBEB81C361F6CADF4EA78C27185CD9B9BD99670ECB41F56C4CC261A39EC251DF34A144B189E108094244557F217312B1BA083F7804928C4950950CF75555BB0B7140406F38CC8B9D21449A756AEC213328AAFD6A8596BB20152BA888F4A591CE162968BC263984655F332ED420473FB6DD0BCCA2D0A3595E43046C61AF6D6317C123BC18AAD6E80736F41BF97134CA7DB2DA8C963F9E2518D865F7FB770C5BA20C2501B44A36E13782583C1579133260E41A77871CB0CD7827D7015FB66251EE9622EEC007FA88227C153B9E7509866AC836A85BF960182F14032606123608E302C0C07D2BDF79B9C398CC437A7A3A2688E0327418B483D1C2B6C3B92B76554A7E14555BF742180FC7F2036C260F50AF5D47AD24033FC62B08A6C10E2F0096B4C5EC5DA8260D2CF9B3816C92A353148C19AC410466C05699209C6B0628A5CA12472544AA822442B93D4F549F5C94A54C4A3BEE5A9375B55B69C77DC260AFE242F6333591279AD1E269D36F02722F62D235186074B3B1AD1C731E0A36996672E74797DC7BA677AA577A523FD38A4A3FA71B7782185911BD837432920A753996776465D33692C859252E294622EE86F2340A5BB624898774851B587B6203A7E94CC909623D027C9EF06493596B9E6A63C02A4CAD21B2EC4792C6FA70ED9AB90D8988F85D24BB37579D4A71C0823167DCC30382178E12C2082AC70F1D7A2DE652296A203D93C2E3CC1473C411C17390BB0ECA50981905AD7F76DCD197C5867AF1F94E3221BF042DCDC99B3B3679587BB2507C464618DC0D607E1D82C3729DDE4E456836E956E187ACC8BB29F262BA6B5038F51F9F8D3B1EF909D94C56C134107B913B0ED29BC0851CCE424D0FB69EDC04C685A540871" + }, + { + "tcId": 8, + "deferred": false, + "z": "671C8C054A52A67BEF8015DFDB5711C9197E84A5A553E794AE0811C8432FEF6A", + "d": "07A9BEBF21C83F6E5417A73D8CF5B527568C903B5883CEC8347B4ADE73AD92D6", + "ek": "A2178E9F524466CAC53EB49DBC5367F4F096394526BBFCBBCF0178721902A0373BB4520D50F039517950C5C0115FCB53DE3ACAA4916C94BB19D746972DC882129B3A4F658E4671B538183A93B1775E56845C00569987103D1A3270D17D0C807EDEDC3F9390774F074741611A3A2B8723C671CCF6688051CFAF25B2310221BD0290F5E6C32DC03DD44C87E395B7E8B56FFE15BE62926411AC28F1A34DFE5B460091520BA244EF5A0D26401DE2B3A64DAA9CCAE3C6A09823D9C84DE1A17E1E94CB26992050F2381C3C947EF575C564CCB6580148A12200E97D9F2969295A90EA78548743C95D15AC8FDB0D91B83AF0A9A75A862AE2558FFE6A7CDA7008F0CC9B5831642047841314406DD0815A09ACA883667F080C6AB959C969140A767FF56A087DA5BD285265149963404293E2E1BCF7599A30A20CAAA056D5285C2731914D85C9F87BB3FC613A809293C81922343A0565B27B779A72BBB0B961D1AD8AC4AF5EC677F997A29C38BEF5F6CD90A897F379871C0B658A7849BA2C43725694B361331236ACCFB55C5E9650277C3D378259067354A8E2167E5578D8F8B610476B997403FAB4AEE365C118929956309B7F7114BAEABFA43408820593D334834B1826C9E705092953C5B73421785C3371687D8C366F9420706389A06198422BC13BAA7075F9B54BF6679A166942E231E1D60637B42FE9BC00E0A9ABC646B3D740201C3985EFE87FE5467F88D6456423A58B07B8FF8C1159E738DCB1A2B3313654DC9F60A072A34ABC3A8ACDBEF6429AA5C088666A9FB14119B69D37D9369D1662DFF3487E826686E812CFF23CEF60C52948424C4A11A933A2D28A8FA880A3E6753CAC7C79F4E111893016E0C067573CB588A6B1FDFB23DE855B9BA6441A837C9F47329A014732CB3DA8B9AC850816E7EAA56584734F3B60E8C732214A86D0309FEC791E7EB28A93836A0FD85C5FD497CED070D71101EACBB92A052140393B18D83FEF654CDF1CB587B2B5CD56CE8C4215C57C065F954CE2A2C0BB65744DC8C2D49930702663D2A0173E515450524B973B7AF4D6B7C816773B6C3B68EC1A06A3C74E038F9143015D3401CA6DBDBEF1D5EF5A349B1C9DAFB96E20DCFEE7BA2EECCE5A3AE6", + "dk": "2B409CB0052C3BB60811731A4CCA005D8C06028BB26D166770E680B1C3CF981608DCEC93069393EDC4559E56673D0B12B8884B8056BBB988672D373E26A3268153288EB91D1EC4642657B7081B7EA587294074555067ABC197A9FB83A15502CD103458CE2736FAF068B2344163A6913E8A232601C217ECB3DA3B57D8D4AA0AFB56A4AB20D250CF97206D78FC004CFA63DB3C27233B3A9A1B8369B102F03AC44F231683F10C4676C2E0BC19273606C8534C1151ACDDC299C9F0C432CB0F03FA1A8FBA4299B4C3AB6638FC924742B8871876989B7C4CC3685FB09B68F5F7126B5645F9D365E5342B23A12E09E4B7CA3ACC3EE06EACE941EAF54A8475492537295F732D8D88538A594CE96333A5E16EEF42155D241E0E2A1077477929A9C51B6737942A57AF4964E26CAD78F22859C453FCD1927592CEEC583724718C92B4BCABF121BC079992A1CA574894ABC1C364456D806A435291CE2C702247F286E9989FB108283B52CE5B6A209BF43F1C991BA200550D90CE2B2A23B715519AD3BC3ED277AA6A50975C2B54B6B47AE7C7E55A7B28BA996ED344A03C21824C9F0E0C55050A54F1F4CC3955353B955419B4BBE0962FB8D4C9EB94B2D2764BFEB41EBC6AB8383B4B6D58B97FC9394E6AA2D1B389E4BB5C4A72AECA0780F15B5F29D5910D3A40D1D21989379C640310F9598F05607F2E47129B27C347830388CA25DC0721B9927FD4B594819965843083B4D761DC76C67626393353999BB4149D4A0B7B5BB51987C96F10731E2BC51ED7621E68179120869226CBC3D4A5B4D07DE6E5396747674150B07720BAC4E94A982B76ABA552E880BE6B7227357028528A26850750685C5B73AB95FBAB8F0F604E3DCC5B4112A72133478942C68A878BD9D92C0E6CCAFB46B57E563C062922AEF461FD093463483C9A2188AE9113B24748077AC624726BD3D30D354497616359B292A9C4381ADEF34B215BB326147713274284F6B3CAC38A40BC9856E459C029A639299B528BA553C892F2219635D0489456B3577AAC3453B6075A72DBCA89B4F27B16F55B5E1C1A35214F24579033E5584A813F8F502DA2178E9F524466CAC53EB49DBC5367F4F096394526BBFCBBCF0178721902A0373BB4520D50F039517950C5C0115FCB53DE3ACAA4916C94BB19D746972DC882129B3A4F658E4671B538183A93B1775E56845C00569987103D1A3270D17D0C807EDEDC3F9390774F074741611A3A2B8723C671CCF6688051CFAF25B2310221BD0290F5E6C32DC03DD44C87E395B7E8B56FFE15BE62926411AC28F1A34DFE5B460091520BA244EF5A0D26401DE2B3A64DAA9CCAE3C6A09823D9C84DE1A17E1E94CB26992050F2381C3C947EF575C564CCB6580148A12200E97D9F2969295A90EA78548743C95D15AC8FDB0D91B83AF0A9A75A862AE2558FFE6A7CDA7008F0CC9B5831642047841314406DD0815A09ACA883667F080C6AB959C969140A767FF56A087DA5BD285265149963404293E2E1BCF7599A30A20CAAA056D5285C2731914D85C9F87BB3FC613A809293C81922343A0565B27B779A72BBB0B961D1AD8AC4AF5EC677F997A29C38BEF5F6CD90A897F379871C0B658A7849BA2C43725694B361331236ACCFB55C5E9650277C3D378259067354A8E2167E5578D8F8B610476B997403FAB4AEE365C118929956309B7F7114BAEABFA43408820593D334834B1826C9E705092953C5B73421785C3371687D8C366F9420706389A06198422BC13BAA7075F9B54BF6679A166942E231E1D60637B42FE9BC00E0A9ABC646B3D740201C3985EFE87FE5467F88D6456423A58B07B8FF8C1159E738DCB1A2B3313654DC9F60A072A34ABC3A8ACDBEF6429AA5C088666A9FB14119B69D37D9369D1662DFF3487E826686E812CFF23CEF60C52948424C4A11A933A2D28A8FA880A3E6753CAC7C79F4E111893016E0C067573CB588A6B1FDFB23DE855B9BA6441A837C9F47329A014732CB3DA8B9AC850816E7EAA56584734F3B60E8C732214A86D0309FEC791E7EB28A93836A0FD85C5FD497CED070D71101EACBB92A052140393B18D83FEF654CDF1CB587B2B5CD56CE8C4215C57C065F954CE2A2C0BB65744DC8C2D49930702663D2A0173E515450524B973B7AF4D6B7C816773B6C3B68EC1A06A3C74E038F9143015D3401CA6DBDBEF1D5EF5A349B1C9DAFB96E20DCFEE7BA2EECCE5A3AE6E2DD64A46E296448B930EA2D39F462B16DD4AC6AE402DA573C0968CCDAAC7F50671C8C054A52A67BEF8015DFDB5711C9197E84A5A553E794AE0811C8432FEF6A" + }, + { + "tcId": 9, + "deferred": false, + "z": "C02D5CAD9E565727E19B2EFE4FA2E083F93EA0F5ADAF97522F33F416F786765F", + "d": "F682949EBFCFA5DA31368E3F177DD146448D0E62178959FCBA4CD4F02CD8B17E", + "ek": "0285512CF6422AFB54DD1C54CD200FFB3AC28AE053E8B6443B96C83DE8595F710D883A513271CF0D93804BE93C84B9A754802C04455D89887DE048B2484088733A701847300FF3B137F509D46033CEC89A4B9602D5A83F77CC20FF4066BCF95904E2789755359F7B04B174983CC883BDB393BE2A02FD3433FEB126A4288EFC4670B0670B2715CDC5700DF6631DF29643E33382EC89B89BB1AD41C6ACAD704BEE982841CC588249BB91A818890BBB3C590A08446D88647FCB5CB15824CDB09C55FAA2457961BB3C79ADAA833F55F154072CAA445B8D61E23993CB69441C956492AF07E702568A350C01BD072CB2E379071845A67149B2F7B2358551770A34A9AE6AB45B2B6D5F700E597184A1425B28047817720C1981C583717F7F4BBF2F13A6D31A691DD3951310A9D135591717A451F00FDD71ABF325B041E3A1EB095F31D27653D1AD0F3CC945D431333A3349B7B8D786B16769309808C11095209CCA1442AA40B9A863B4973E85586899ABC17D1034E64505C1F9987172538E227111EB86A66C9077C268B7A24A477991DDA6753672BD972510EF3347E1B7314BE172A457A4A0B9909718418C478D396B9F15BB6D49D919E192BB714BA992686292056DEB4B1AC84C0A356911437BAF2E053B170162BD25A0E554A757037C1E40BA6E341EE230B592D33F0B910D32C01CC3F865D104C3B652A63229A90B155D41C68C3008C3DF42CB757A36634C6C7372CA47A82A652C5115BC0383842E5AC18CA6239799A37C91700845180AEB407B88D9390F0A6353EA1459D258E70567E2A5530588C63257B3A33050FEDC1C4FD58BF7F547648B96927A4B6C01901F2CC97995AD993C41A7290F7D555C173C1FB12AA514446E2495471305C9D94236656729DBF9832415C3F130864C4A2807509B14BB187F6450F9A92F020B62238A8F23BBC8ECE7BB33305E3C70B43589BF43C88D712B386C68945F7A7F56A23DC8D45ABA95A89BF18BB0E1AEF4DA810723775AD3125C4316056433EB04202BEC5B83D84040514407E7862685652AE2BAADE15056A2106E546A134A8527A7CDF78866E42CC7C322861CD5BC3D7424AA358204AE6D07694FAE81991F5C67C160B09429BE12543DE0F8", + "dk": "893175C6F86630760EFF4332E35A8642202B2F8503DD24AF50B1BCF10B63951B8E6D426D0357B27A93293252852911C14765099D330D25608885934216114FE2300D5119262C4B959A9928EB058DCBF1636E30A173F5A31EB580A90ACD8774233E652CF4E78AC1C51282D2BDA92A0F6B74ADBFEA4CB8A68F2D3CBFA3298AA8F203EB32063DAB216F811363E69A28A8C8417B524F09BC5D864CB5B502D88B2226193C3729CBB968105FDA459ED9688B12580957180D6A01FB16CCF3E78A9D07CB35A55135B2A1C3D559F5B01A4DD58311417F4E1B98875456849C6E1A632B539180A9108DBF872D96847E79E82C6D23A51AE23042763361A125AE4572BD104F03C548D3F1A377F481F261BD596321BC68B34B31A40829B8AE3CB49C2631A229244EBC08C722839DD8748346C979A9AEB36901E0D9980B6220CD2B32F6C8B1C01C5C61AA0055C32C4F99B1268CC806BBA9D0139D867389B04A54AD51816E965B5CE4A0EF245D6C2006457AA0265081D26214CEFB5671BA20166680CE0C8A817005F7574878B9AA168A8E6A6CB99924543A374834742C48665253E03DCCBC552A5938C0115C5F709B298B0C0E245696CACA53152728B60ACF3C5EE1F92DB30131DB853371021AECE73936D0606A8BAC25430CE0138CCE05048395301A03860D439F9CF45F82680DB9B98B0DBAAA41BB776B60CE41734AA92B914458A7C1CB9CCD55731FA5660D567F489B3BB56754319954FD6A78E6626C69C68A6EA882482113886B8BBB980F118193C1165FFA3A9A8D1A20626514F998CE61EA8BF92B09E253C773D5B2BFDC7C3DA38115B8AA30361C7BC4344CB772EC722B55D1AC4FB7C8510CAA1886C345DAA0CC440EA1DAB0BD131177B9013925418B4B1D54B90BF7F5914AA49B65882FF1297ACED09E36B066671666B875BA1BC37D2FB76F80240D2B996BF6515A0198B66B66A4DEE40DF748C807E1378EA76308076A05FB1F6A071E2D635576F952E4F62A15CC6442563EDE9C8E204789A8F06EC8EA6032D5032A77CAA5963CDDAB24EBEA5708C7B761A67CD0464A2A00233AA648080AB5B2191D73A91D0285512CF6422AFB54DD1C54CD200FFB3AC28AE053E8B6443B96C83DE8595F710D883A513271CF0D93804BE93C84B9A754802C04455D89887DE048B2484088733A701847300FF3B137F509D46033CEC89A4B9602D5A83F77CC20FF4066BCF95904E2789755359F7B04B174983CC883BDB393BE2A02FD3433FEB126A4288EFC4670B0670B2715CDC5700DF6631DF29643E33382EC89B89BB1AD41C6ACAD704BEE982841CC588249BB91A818890BBB3C590A08446D88647FCB5CB15824CDB09C55FAA2457961BB3C79ADAA833F55F154072CAA445B8D61E23993CB69441C956492AF07E702568A350C01BD072CB2E379071845A67149B2F7B2358551770A34A9AE6AB45B2B6D5F700E597184A1425B28047817720C1981C583717F7F4BBF2F13A6D31A691DD3951310A9D135591717A451F00FDD71ABF325B041E3A1EB095F31D27653D1AD0F3CC945D431333A3349B7B8D786B16769309808C11095209CCA1442AA40B9A863B4973E85586899ABC17D1034E64505C1F9987172538E227111EB86A66C9077C268B7A24A477991DDA6753672BD972510EF3347E1B7314BE172A457A4A0B9909718418C478D396B9F15BB6D49D919E192BB714BA992686292056DEB4B1AC84C0A356911437BAF2E053B170162BD25A0E554A757037C1E40BA6E341EE230B592D33F0B910D32C01CC3F865D104C3B652A63229A90B155D41C68C3008C3DF42CB757A36634C6C7372CA47A82A652C5115BC0383842E5AC18CA6239799A37C91700845180AEB407B88D9390F0A6353EA1459D258E70567E2A5530588C63257B3A33050FEDC1C4FD58BF7F547648B96927A4B6C01901F2CC97995AD993C41A7290F7D555C173C1FB12AA514446E2495471305C9D94236656729DBF9832415C3F130864C4A2807509B14BB187F6450F9A92F020B62238A8F23BBC8ECE7BB33305E3C70B43589BF43C88D712B386C68945F7A7F56A23DC8D45ABA95A89BF18BB0E1AEF4DA810723775AD3125C4316056433EB04202BEC5B83D84040514407E7862685652AE2BAADE15056A2106E546A134A8527A7CDF78866E42CC7C322861CD5BC3D7424AA358204AE6D07694FAE81991F5C67C160B09429BE12543DE0F855656EF499C81763075415747986E379B5BE816E964FFC959698CAA61FC6B31BC02D5CAD9E565727E19B2EFE4FA2E083F93EA0F5ADAF97522F33F416F786765F" + }, + { + "tcId": 10, + "deferred": false, + "z": "70567D6DFD6622814417BBF673812F2D02E5BFA897D464957AA4219841A93C19", + "d": "170CA6BB76C065255DFDCA3EB93C772E57EBEF8C9A291C8F0BC4444BF008C868", + "ek": "E295110B123EADD95814826F65D2568360578F2011EB917A24E45AAFA629D7E3C8DF3210D85831CB806B8EC64CF5157938CA08FF6848A11B19D8CBCACE2090474C30C6053E20138C01149114A2A73C129C8055ACA352B05AA4A464B07614C4ADCD002B0B477F624CAA0026820A2455FCE2CE9FF2CEAC299554DCC21FCBBE9C36A07AD67103C112B9F955A1B551D109C88EE54075F203016A30B4A437AFD635F105B7F5B1BD5ADC5925C9347176AC0374CB38250A6583928012A283D4B067E0CDCA554C04A3C1CB0578070CA5A545894841AD38E599643B1CDF94ADF4E917057886A8BC577ACB4668769707DC73D7186700F65DBCF3BA3964B952B7244070053532042924552CA4A8DB807FA12B572D7582B15BCC6DC152A1125955885ED176915448CB7CF5680FE7AB37D22FED7A5E76552481139112351E4FA01EC3B829822788E3A9A463A582F98B9DAFEC1E05378413D805D3D043234578C73032D9006C21C733FF45CB649AA10C09775350523476A5F760175FEC96A26B2E52BCBA008C1C28707ABE5189F2515164B0194BCC1803231B41DCAA20C335FFE0A8BEE5425CAA5832649450924BB1424734A0940E7A7A24D917741010B9B00C81DCBD4BF394BDB5BF03358614718FB1F162877824EE0156F4C462C597B937EB8768C2CFB6F7BE36D7C307C431AFA83824C812CDA245A6B923A5199DD59C1344895E4E67C07F448641D32E4F526693724E0A025369621B220341AAD6C43A4C7CF6C27A5CC65095BCCFD569019808B2AD850168A24371E292D55851A0BC58DFB0AE57E3512B1A26C57CB373F996C0341BDC4714C451979524A58B0502A9996CE09980AC9CB4EA763B8490B4A7B2530B87962B702BF1F04E3CA65AECA1086AA4317331C78848504A9784F40B4A36BCBE01948F08AB400036BAD091AA1AFA1020D60B6278686AB365F208A6D4021C90468FDBE7243BD89D5994A7FF092841389243AC308CECBC5C12105E1408D500A5931B86FD16B555E0AEC9509A63103EACA5A0090C0A0CBB90F8F970980B60954C5985F5644C0914D1C558B65C9F54A42343E824D713B0F1EC9F2BAAADFC824BAE43FE99FD58BF6E845A2AA9ABB4AD4171FD9ADD88AD012EA97F", + "dk": "17F2393AA323522A7D4A6590D57BB2C0EB6B54F578FEECC61C742BFFAA01C2E2A01F68586BC083907728C4431AD6726C58C3C35030CDF1B9808BD14773A91E01577B6E3B37312617D50672B9B9643638229BD151D6F904AB4023A5B1203556B690A41DC558A2BCB00B167C611F9977E5538F227023F088BDAC535556280D3BA63E65721797998FC2FABA44BBB697ACA8835ABF06247A184A8B91518B32A8295B086A9D6313E2825C27C7C126EA1365C68735FCA9128C6256202AF141CAF93525B833578CDC0E31EBB4B2A601643249D32B4C1021C79A1933ADB593E02555E0A467687A5E3044C1815163EDB75A27F15236F03437DA44BB0BBDC24751F04C1F5ED8CD87AC1D6A295CAE175C301781FD39555D688794E74C70D6674A80613A3AC4286A28095CBF68D51A98F50EA4415C6D35460049125A9197A18ACEB0819962BBC6C1055F64B09CD46B6CF9564EBE085767893F7A67AD021AB9157081250A150C904633F9314B6192E221543BB1B68B152B26A3BA74C0C50F54A00E3163505BB51658CDDFA59583847D99133520D08054F6CDF69618402A848A79571479AF36F84A33082E4E05B71401A31879CDDE8346412A481703A88C698416540D85380D8AF880933B5A252B731E9071FEB951500CA7422144A8080280E7054F840BB88763EC33C734754430CA01C5D8A0430B2843975BD1A283DB930CD4CB2B89425F63760426A93AAA27337F22B32577998C34BDD66B6CF6313EFCA95BE3A9CED1A8402533CB3DE7B52A94C551CBA6AF20010D0C7377F8165CB21445D9CD102A15A6A72C91BC4898A47A4C4262A06CCCF3B384E0A52116F05B3FCACF5E1137B96342B3E6BDFE9CCE7C0BADF855A8DA9A00439335ECD15062998609116A1B16BEBB208ECC37CD4ED3BBB3F6A022A9B708513D47164FB5CB51910448CE82186D3000CD487A20B84034929245108AAC455445743BEDAC9B62918644F7183F17C2BCC7770CB5355AB719024177B623478C2C4326E3474DA1924C963DDCF80048999E7D6BB3C9128083B83B9A13710F65ADDDB604FFF15B24E78221C427236799F9B942FA123BE295110B123EADD95814826F65D2568360578F2011EB917A24E45AAFA629D7E3C8DF3210D85831CB806B8EC64CF5157938CA08FF6848A11B19D8CBCACE2090474C30C6053E20138C01149114A2A73C129C8055ACA352B05AA4A464B07614C4ADCD002B0B477F624CAA0026820A2455FCE2CE9FF2CEAC299554DCC21FCBBE9C36A07AD67103C112B9F955A1B551D109C88EE54075F203016A30B4A437AFD635F105B7F5B1BD5ADC5925C9347176AC0374CB38250A6583928012A283D4B067E0CDCA554C04A3C1CB0578070CA5A545894841AD38E599643B1CDF94ADF4E917057886A8BC577ACB4668769707DC73D7186700F65DBCF3BA3964B952B7244070053532042924552CA4A8DB807FA12B572D7582B15BCC6DC152A1125955885ED176915448CB7CF5680FE7AB37D22FED7A5E76552481139112351E4FA01EC3B829822788E3A9A463A582F98B9DAFEC1E05378413D805D3D043234578C73032D9006C21C733FF45CB649AA10C09775350523476A5F760175FEC96A26B2E52BCBA008C1C28707ABE5189F2515164B0194BCC1803231B41DCAA20C335FFE0A8BEE5425CAA5832649450924BB1424734A0940E7A7A24D917741010B9B00C81DCBD4BF394BDB5BF03358614718FB1F162877824EE0156F4C462C597B937EB8768C2CFB6F7BE36D7C307C431AFA83824C812CDA245A6B923A5199DD59C1344895E4E67C07F448641D32E4F526693724E0A025369621B220341AAD6C43A4C7CF6C27A5CC65095BCCFD569019808B2AD850168A24371E292D55851A0BC58DFB0AE57E3512B1A26C57CB373F996C0341BDC4714C451979524A58B0502A9996CE09980AC9CB4EA763B8490B4A7B2530B87962B702BF1F04E3CA65AECA1086AA4317331C78848504A9784F40B4A36BCBE01948F08AB400036BAD091AA1AFA1020D60B6278686AB365F208A6D4021C90468FDBE7243BD89D5994A7FF092841389243AC308CECBC5C12105E1408D500A5931B86FD16B555E0AEC9509A63103EACA5A0090C0A0CBB90F8F970980B60954C5985F5644C0914D1C558B65C9F54A42343E824D713B0F1EC9F2BAAADFC824BAE43FE99FD58BF6E845A2AA9ABB4AD4171FD9ADD88AD012EA97FA29C976B07F9A7D707839A6D72116355207826F54F27A23B6BAF16524F3C4DA570567D6DFD6622814417BBF673812F2D02E5BFA897D464957AA4219841A93C19" + }, + { + "tcId": 11, + "deferred": false, + "z": "71A6E59B13B36CAA406DBEC53F3FF2F0CC529098A4C8FBFD032C8BDB8B0E16FE", + "d": "176719D76EE1CEA83F7751BC4E3DDD00868B5C504C79AF8730B9F7595E7914A4", + "ek": "19288830B0ACACEC7E939B82BAFC8FBFBABAEF732309CACE58533E4F5C62B711C5D84820EA520F030A7E61534275206EB4BB00A53472AB206E50D68C7B3C3D82119BDF508272EA5D40116C9DAAB1F7BC5595B9623DEA2D683C69A079494E3A10BEB2B3A1667CDC031F76CC73595C20D3587970FC17671CAFACE83495037444EC6F485329F6A13328F67D5B839609A56D336C05FB712B1C78A944037CB3E9CEF1D46C420A118EF8712593172548C64FF616E1166649819FDE13235D5341C52A69BB154F48C672D3370B59C19A86B13196F25388089D8ED463FA93AEF6F3857832ADFB874765E318A59801ECA9799BB0A303B87867846A025129AED31C5D2336EA968120C0B88199A83221B1FE6BB2365A086165C0EFBC6185332FB10BB542A32547AB549B3C9E666246CEF04EBF3CCB3CD445C7FA2DA1DA6633E227B5209654AC28DCE78E45B2AA927244D8BC4D881C9462C87F228C07B9C488FA660EC29B60BCF494D6D97C163C53607556361298CEC90332732D7A921D5ABCC3BFE0A3439055093CA7EA1A5E75D70809A55ED886C5A9E90353860239EB907635BD3B46B78EB42821E773E62A1910331F127162B694CF64213305055AD00923FBD137A7F305F345884A6BC5B6C534CFFB6F986A9C444446E3D74170AA375D359E4FAA6C99E4315D230F9B69C37E2C444F29C7EC64C277864836410E8FC703437975E3E83E76F988432570BC635F868C96CBDAAE5C6B37D2E203D452C762747FE7494F146AB7591C9285B68E3973364BB1126C3585BB694DC2262E38D94CCA5C1427992E563C72C9A103FCDB4EEFEB46F5171E9DC2B611D9CE42197352E140B50902EFD676EDF89896B5A4808095FCAC5DDDB218E6AB2F5EB88D831648FF75B1382B6558BA9BF1D8316EF4040E82860716075E80CDC24799733B9EEE74702582320C5CB56C495670FC239CCB6FB8F91F7F217E5BC4A0376B9832F0AB8EB4184704B69C33CBECA37579FB085462705BC72AB7F37C3804B1BD14089FC07C85956038F80C67F409F433854B99198307B2ECB38170DBB55F422260D594F33B3DA9F35C4AC2C2DB9275CE21D56E9CDCF309777C616223E7C0ADD4FA7A6472CC0BC13CDE85BD4536ECB1", + "dk": "ADECAEBF22777691A57353B3D6DA4AC5959286C157A3245282D34812374C88067ED3109817C86447F5A807D24E82316C56944EBCC8A68C761170A218390193CBC14C2859466BD164753944C39269660A5583B2B3309216447886A702127BD77F4A5A03F9B19BE0A76A4ACC0F82267A8659BFC72054AA5A23C84940354323DA78569F1370553A71DFC54AFDFCB669377F3E324098E17709361CE1F824DD2C47ABB25FFFC25ADD519F6079C226D77E6B3231B5D74E11221869881A8DCC2188505628E86FAA2ABA16638400CD58B569002851288E631991C3C545B345A1D5646FE304059A4C742A4A27AAA9FBE9593F374B51B453C7E09427A6325474AC7FAB0A3168630202A016632B3E490D77CB61798320C4139780015F6B521A81E2C34494A6C4FA45DD3712B5349B142A1A57166C1FBC120FD5BEA702BA1878A9064028C575BD5535BF5DF70D46536A826BB687E82BB9A541DD795114359222A8733CFB5D6856269D977AE07887DF5395CA6553F74907E27B011320C103A4191E5AC4F6BCC1C12624D02B2295150C52CB6E5C1423E50922AFBCCB0BF70B2CE8379C2B9C635C44D7C72BBE11C23E4417BDDC9339A6CEE23514E790B1931820FDA6927DF74D79DA1B762562F207A2B14776B98615AAEA7276A585C6972BFEDB7327415AF609227A4BCB757762AB819236D5C615772CF00A492B846C731825E6643C53F55BE7D3555EA4B484A891FC35C47E406F12E6C6B34C090144C6754A12E969B13D0A98231AB7CEC0AABC414BB2066FE6F7297F2635BA79A18656914F4977721C6FA526081E2436975B85E9B7687ED16DA57413B5C16400823522434E38658983B7AC65A39EABD32043693D9B87C1F9F08D80E540A4A86033ACC7D6C961F1DC0C47981CD9588FE469BDDB86762992118B94CB9A213CB62A12E651B654518C843B3E3959612F0C6D97F419866CB89AFA055DF145FA28C302BB1E41E342FA852E3F47380F7536A3824A9B8697BCE6525271B3D0936C4BC172F5A5CB2AF5AD78B72A1DA30C761CA84F123E1BFA58B0454279B87517B906A030562F7691DA4A09C456975E601319288830B0ACACEC7E939B82BAFC8FBFBABAEF732309CACE58533E4F5C62B711C5D84820EA520F030A7E61534275206EB4BB00A53472AB206E50D68C7B3C3D82119BDF508272EA5D40116C9DAAB1F7BC5595B9623DEA2D683C69A079494E3A10BEB2B3A1667CDC031F76CC73595C20D3587970FC17671CAFACE83495037444EC6F485329F6A13328F67D5B839609A56D336C05FB712B1C78A944037CB3E9CEF1D46C420A118EF8712593172548C64FF616E1166649819FDE13235D5341C52A69BB154F48C672D3370B59C19A86B13196F25388089D8ED463FA93AEF6F3857832ADFB874765E318A59801ECA9799BB0A303B87867846A025129AED31C5D2336EA968120C0B88199A83221B1FE6BB2365A086165C0EFBC6185332FB10BB542A32547AB549B3C9E666246CEF04EBF3CCB3CD445C7FA2DA1DA6633E227B5209654AC28DCE78E45B2AA927244D8BC4D881C9462C87F228C07B9C488FA660EC29B60BCF494D6D97C163C53607556361298CEC90332732D7A921D5ABCC3BFE0A3439055093CA7EA1A5E75D70809A55ED886C5A9E90353860239EB907635BD3B46B78EB42821E773E62A1910331F127162B694CF64213305055AD00923FBD137A7F305F345884A6BC5B6C534CFFB6F986A9C444446E3D74170AA375D359E4FAA6C99E4315D230F9B69C37E2C444F29C7EC64C277864836410E8FC703437975E3E83E76F988432570BC635F868C96CBDAAE5C6B37D2E203D452C762747FE7494F146AB7591C9285B68E3973364BB1126C3585BB694DC2262E38D94CCA5C1427992E563C72C9A103FCDB4EEFEB46F5171E9DC2B611D9CE42197352E140B50902EFD676EDF89896B5A4808095FCAC5DDDB218E6AB2F5EB88D831648FF75B1382B6558BA9BF1D8316EF4040E82860716075E80CDC24799733B9EEE74702582320C5CB56C495670FC239CCB6FB8F91F7F217E5BC4A0376B9832F0AB8EB4184704B69C33CBECA37579FB085462705BC72AB7F37C3804B1BD14089FC07C85956038F80C67F409F433854B99198307B2ECB38170DBB55F422260D594F33B3DA9F35C4AC2C2DB9275CE21D56E9CDCF309777C616223E7C0ADD4FA7A6472CC0BC13CDE85BD4536ECB1EDE9E402A11646293C3851259F4E8E4412A3C5986F8BE4427BE39C4E869C061F71A6E59B13B36CAA406DBEC53F3FF2F0CC529098A4C8FBFD032C8BDB8B0E16FE" + }, + { + "tcId": 12, + "deferred": false, + "z": "B63478F2FC887334C707E9D836E3104892566B3568CD32B583F8C9A0DE1A1F0C", + "d": "3C90FC402DA953172300194876B3B3BC958268747751346DE7134566CB8FAA5A", + "ek": "99263CC303C92A0BC6810487CA1664E5405EEE5987A621C33E30483D4C7862F9760399B4C23822507810AA321D04009CFEB2505860BCA818BC0CFB9DF44A5F47D23AE80C25C2A67455B64AF2D276606A208C74867EDB5373BCB93B06AE81DC67FB73514FAB8E62516D0A0760FA0228E6BB0A252120FC7676A0340FC2939CE8118782631B91F962CB14200C928091876998B1B19EBCCD59F92815930DC6F9BE629099B3334772AB3A16D630D971B2093C136F29C2EEB09F03F8592FA4980599542E422FF636C8BDD6672454238D4C547FCB43DE1B10FB385CFAFB1F84D95E6C776973867E2E40615531A3126B076E9B30D3E9BDD2E12C34A9764E90000AD179CB159259202800299B2902606603227BB37A9B679320B60B3EB9A917D2C0F0CA6A3248B1F371801661A58FEC24B8807B06A5B67D087CC6E3008D823024575C5D7678C93973E8201101765DD5A10889091F8AF87512C206C2C60A96081FCFE32C3B7C18A643AD56515674A3B745D154F7076B65E191D5026301AB45076B00288B91DA147F02795A0D0AC9E8C61540405F44C8B7C766BB454525B8D48B9418B34E3135B8BA3AC9E2486B162C23B266856BC370B4833028C0F753C1E6490A9608B1C5169E6EF0B43BF6C5CE0A6122CCB28C9A96F794B4A5479394C49253217D4DE0A93884A1E47860B127B7DCEA8A0B17019AB410A0737BD81C6EE6EC6DA84569DA3A8ED34ABBC6588325007C4F5651814C45F9DB9AB460AF28B68671E6075AA8AC5F9B2166B79B81154274F058E38B24309017D2B098532964A3DC453F133194D1160A356098321C89033BD195848FF1C989FBCB92192A9E54C528F5259DA796DAF18831A040D8E8C999857FF5251A2A1510929940F1836216566F443AA903BC90528A9E7D842DE70BB75CC8939E48044BD67A4287CEABE22C3481B1F4775260E65A9DB00BF5218136143FC2E21CA720B11540A83DB93C16F10A12E7BAD3A27DCD807E15678687D325CB23256FCAB5073690E3B645329C87379C7B1DD7375755B2E9355D38A9870911B10BD5680FFA08C1442E412A6ACE489E4C89BC7923053748132526C541A0EC4C2A84B606573C36E027356F49F0978B029037455A22E3FA2390", + "dk": "30015BCADC63AF4C80E5F94529725041C8C0746963B3D1A5F655CBF9A8BBCB8B983DBA06CDD1256C1147B0ECCC4D03B600744139D84E6664B40AC22BFB1B03CD61908724078A8B405D868A462B7272594FC448C3EA5908A824091653CD71EC858291B26AB60ABB403884EAA6909A3AF7FB0519384D91856ECCF48C1843C50F1130B1A66DD38355DDE0533EF08484F4536968691BB1900CB52A80039F6CD201FD6C9AA45B0D1830576289C1D3B233BB11AC2D153F6E42A7B5A5AB4B204EEC2707AFB266BFE93C17B6AE2183513E38AAF7F6C0D29B347E6AAA31D24C2804606608A078A25CFE607846103744135E44872C0C410028908E2A608601730DE42B01D45400271033CF90691340ADF473C487DA2BA2E6B7BD2CC6B6EB0D9F01CD7031015F1015C6A24E0C19853E749E2F16C61C2809FF1AC00D113465868E56A919A8310FF6D43E3511322D293F9DBC5F965458A184744F3970B0A16359172B16B7C8CA43B311F4AE96380DA46292A3D1404604054069A181B1C202A02B9AB34DCE833BE08C2EB0DAC641C024C416BA0DB34E10546682F02B6B6B630B801CF8B2CC4F98C671307B92407BDFDCA4CD41B30B4AC8EA3811ED9665FAF479D1057B313CB113941155E539D4C61011360BEAB816CAC019051356533991343434E5C28AEEA797FAF85668B824F3F8BB0329CFC7ACA9992C3990C56CCE31A53F40CB2D07940093504E8A7CF091B137308E1D30B3B40A3624776F9955B62F3828DE769EDE44B89DC828473213AD08488C73A9C9FB2813C6750CE148E37AB3BEB0B60D2203BB444DE44ACCEF685047D9C325478F7CF3A72C9A6F1040A898B1A71EDA1B5F87B57FA08F2F75C4ED616C02512F205159F1881BC559C93925A639F05639589FFA2C38E3062A4FE091A507267916495B033FC0901A47C645A8D82425216EC251C8C0D37A4BFA44C0435E23D090D9D10528A03E611628C5654C5AA1C42280A3C54CB73CB26A5A68CC5D13496093B14B470E3A57038C30CA15712EECA379978521EC298E7BFA6AA698A04925CE47413A62283ECE3C79D955CC3E9C69F783C9B2D58438565A99263CC303C92A0BC6810487CA1664E5405EEE5987A621C33E30483D4C7862F9760399B4C23822507810AA321D04009CFEB2505860BCA818BC0CFB9DF44A5F47D23AE80C25C2A67455B64AF2D276606A208C74867EDB5373BCB93B06AE81DC67FB73514FAB8E62516D0A0760FA0228E6BB0A252120FC7676A0340FC2939CE8118782631B91F962CB14200C928091876998B1B19EBCCD59F92815930DC6F9BE629099B3334772AB3A16D630D971B2093C136F29C2EEB09F03F8592FA4980599542E422FF636C8BDD6672454238D4C547FCB43DE1B10FB385CFAFB1F84D95E6C776973867E2E40615531A3126B076E9B30D3E9BDD2E12C34A9764E90000AD179CB159259202800299B2902606603227BB37A9B679320B60B3EB9A917D2C0F0CA6A3248B1F371801661A58FEC24B8807B06A5B67D087CC6E3008D823024575C5D7678C93973E8201101765DD5A10889091F8AF87512C206C2C60A96081FCFE32C3B7C18A643AD56515674A3B745D154F7076B65E191D5026301AB45076B00288B91DA147F02795A0D0AC9E8C61540405F44C8B7C766BB454525B8D48B9418B34E3135B8BA3AC9E2486B162C23B266856BC370B4833028C0F753C1E6490A9608B1C5169E6EF0B43BF6C5CE0A6122CCB28C9A96F794B4A5479394C49253217D4DE0A93884A1E47860B127B7DCEA8A0B17019AB410A0737BD81C6EE6EC6DA84569DA3A8ED34ABBC6588325007C4F5651814C45F9DB9AB460AF28B68671E6075AA8AC5F9B2166B79B81154274F058E38B24309017D2B098532964A3DC453F133194D1160A356098321C89033BD195848FF1C989FBCB92192A9E54C528F5259DA796DAF18831A040D8E8C999857FF5251A2A1510929940F1836216566F443AA903BC90528A9E7D842DE70BB75CC8939E48044BD67A4287CEABE22C3481B1F4775260E65A9DB00BF5218136143FC2E21CA720B11540A83DB93C16F10A12E7BAD3A27DCD807E15678687D325CB23256FCAB5073690E3B645329C87379C7B1DD7375755B2E9355D38A9870911B10BD5680FFA08C1442E412A6ACE489E4C89BC7923053748132526C541A0EC4C2A84B606573C36E027356F49F0978B029037455A22E3FA23904DEBEEC7CC5EFAB5DAD8559722613802856CD726336A26B171DEC76493C71460B63478F2FC887334C707E9D836E3104892566B3568CD32B583F8C9A0DE1A1F0C" + }, + { + "tcId": 13, + "deferred": false, + "z": "4EA6EC5384C51903758B807395181F6D6B4CCA3FA1CA24110B08A8AB1742C411", + "d": "24B783E39214CC39910799ADECE53B32408C19CD9ED10DEC039A9FA2CFC1CA30", + "ek": "37949792925BBDD82552AC59C024AE05B6C9FBAA558A9C4D1FD2A64EF27E2C077617C864F0FB704093B8ECA24CE0CBC9073125070C0CD24426CAF58F97B6549585C249E147E7440DA19B5D55C94EB99274B2D390D9BB6DEDC66545863AD1247013BA4021228AAB05060C9C6749599D8E74895E297C7F05ABB661B98D6003E6F064DF663BB5204D6E12A7ABF58ECF0BBF8C9B3379653E2AE073C3945E410BBF14FA6AF910B3562C7852923242B894E677777398413F511FE38B34E12C787AB75C7CB50C23E432A437B83B483236D7736BA515A3A76C956261B68274FF368CE9B04F1BA3C93E51A6A220744E370620C17B8A851B8A3B01A7017C6765150959AE4C567282D3C087FC6150279A8A3873A4A9231B5C4EFB998DF0A62B808A934F2701CFB2289DA578F1621151C136D79509EF3B5D9C16706CC3BAB798B1777A6A9C9A53F1B277D50CB7A40148485AC1550417AD735899532AB03AC8DACC790987A76AB988CADA1B1FE02400ABA70DA5C9C991725744740FCA0D5EE37486645E4B6047DA0C862A26A89268CB8B9781301AB43ED88FB5403BDA3A63882AA6780A6075474486643896B285F0E2272E261A54B09F0931099323781E797DD7173AFE84569F05BD12134C39B631A13812F2958B872950E25AA07CF2BC5CC90E930B71056B562F06AD2CA268CA82548BC6C7E079690B22B900E8C16CB9463C8B4FD731A74890C325B7CAD3871FD1F67DB78077A13A5E5F9720A4581DF75C4B9C15050D9C4923D7AC7669BE31C523D2C377F1917550862E8E5C39253A5317DCB16529528DD9B1993006DC796668B892DEBB8AE9E8A7E28877403872EF4BAC5367CB09795BD209ADDC54A329CB7549959F286A1237287756AC9943D2B5D21A936D1C7C2CC784E69661D76317ED0241B9C978C02A6E7DF86667506129697936E557251AABDF769CBAE5614BB2BD354110ADFCC8770CBC72738C13064DD14BA724B6755FBC176683B2B5283F6B99B60919A70A2C49CF29378847BD8AE1C502801334F8360369462DD97AD9E0836BEB57B98815D43734CA4C95247CAC55F38786A7747AFB8D8E678465921D7BF29D607FEDF94631E9377AFD92D51FF18D4F91280783577370AC011B", + "dk": "F6FA89BA9A8A3752C28830B89884388B95A2CB3624DF530E143346BBA491DC7082D5144BF36C9B2B828D1D516F9E8165826C1D9CD081F301224F8409FDE22C54F72AD6319033524F0331248043304CF53D44F31C24914689EA9E04A204C96561678A73ECF40E8938ADB137B9F3970464F72C4C115314304DC317ACEB5C2733661F49F1038141BF82174F3634AD82E08E69117A27B4292937482466CBB3041223B51E2BE32C8F7348E3B427F2C77A94D475FADB68C5613312B92A38A86DD694735EABB42ED21A90BC7FB0A5C90049BBC42926F5FC5A0F563E702266BFD44479D8B1C620C670E6AB0E7551619B8661F7BF33B97D12C20414C35866B007E34523184B967B9C6B4AA5AD7DD3CAB39497377C2F468538D52463A3E9945ED90F24FB964C85C47B202CA5EC533CDB286206A14B681A9F145B2BBB3F8CA65000B92CFFA80693EBBA5521C624D1B84906A8C6AC3C7881B10BC592B3B5549861B53BF1B6C1C19E70579EE366006D019E06492EF375BB1D8800B6C60EB7D3B5D78348EEE4B7AFA10E6786043B1C3A9BBCB3DE313189801BCEAC0F9B0C4E631366863297CE39C845835F5B25136BFC8C25C737054C184CE18074A1B079A00A6AF778EF8C3D45F5178A604CC19AC427118FEEF0014A047CC394589617040D96682BA919EDD61E0BC572A21CBE7D189F2AF69F02A6A313881D94A5259D8872A04854D11482635C9746CA083581680E5429BEC2C3A7164D39FB766D786F5FD54B9AFB3B90BB55459C2811860D7159BBAE38B67B4B18865B326CAB9AE62C9B1E636F0CE48260A4B90D6B1F4197371DC1661EA07E27993684CC9423FC5C15F8B1F34C0EDEB0B837A847B9ACBC53F4CF3E88766161C121595A0F940DF1E01C4CC3192F839BD7B660835C570C83577F3C9D88851EE3E9B74B00416F034DBDC2B7D081995854ACB5F4CFB55C9605E6891A8041CBB6101FA94B52F7902CFBB256B28648C9585E8B564E7322911B9A9030013157501D1991210B754983777FF99B42CCC87FE5A847E8A084662DC1D3058C6999EB6C7935B4470A25B4720925ACB046773B16C1E70E2AA5BD37949792925BBDD82552AC59C024AE05B6C9FBAA558A9C4D1FD2A64EF27E2C077617C864F0FB704093B8ECA24CE0CBC9073125070C0CD24426CAF58F97B6549585C249E147E7440DA19B5D55C94EB99274B2D390D9BB6DEDC66545863AD1247013BA4021228AAB05060C9C6749599D8E74895E297C7F05ABB661B98D6003E6F064DF663BB5204D6E12A7ABF58ECF0BBF8C9B3379653E2AE073C3945E410BBF14FA6AF910B3562C7852923242B894E677777398413F511FE38B34E12C787AB75C7CB50C23E432A437B83B483236D7736BA515A3A76C956261B68274FF368CE9B04F1BA3C93E51A6A220744E370620C17B8A851B8A3B01A7017C6765150959AE4C567282D3C087FC6150279A8A3873A4A9231B5C4EFB998DF0A62B808A934F2701CFB2289DA578F1621151C136D79509EF3B5D9C16706CC3BAB798B1777A6A9C9A53F1B277D50CB7A40148485AC1550417AD735899532AB03AC8DACC790987A76AB988CADA1B1FE02400ABA70DA5C9C991725744740FCA0D5EE37486645E4B6047DA0C862A26A89268CB8B9781301AB43ED88FB5403BDA3A63882AA6780A6075474486643896B285F0E2272E261A54B09F0931099323781E797DD7173AFE84569F05BD12134C39B631A13812F2958B872950E25AA07CF2BC5CC90E930B71056B562F06AD2CA268CA82548BC6C7E079690B22B900E8C16CB9463C8B4FD731A74890C325B7CAD3871FD1F67DB78077A13A5E5F9720A4581DF75C4B9C15050D9C4923D7AC7669BE31C523D2C377F1917550862E8E5C39253A5317DCB16529528DD9B1993006DC796668B892DEBB8AE9E8A7E28877403872EF4BAC5367CB09795BD209ADDC54A329CB7549959F286A1237287756AC9943D2B5D21A936D1C7C2CC784E69661D76317ED0241B9C978C02A6E7DF86667506129697936E557251AABDF769CBAE5614BB2BD354110ADFCC8770CBC72738C13064DD14BA724B6755FBC176683B2B5283F6B99B60919A70A2C49CF29378847BD8AE1C502801334F8360369462DD97AD9E0836BEB57B98815D43734CA4C95247CAC55F38786A7747AFB8D8E678465921D7BF29D607FEDF94631E9377AFD92D51FF18D4F91280783577370AC011BBEDEE8ABCAA18E82777BD6D7F6E49B9CED29D3E3687A5FE2B528C6AB45700A2F4EA6EC5384C51903758B807395181F6D6B4CCA3FA1CA24110B08A8AB1742C411" + }, + { + "tcId": 14, + "deferred": false, + "z": "9FA6AA53F505506BE269CE201A1A6EF95692DD1350A7188F468D34C5DAE5EAD7", + "d": "E4F2972F746E028108A5BB98EC97A307DC9363909DEAFC491F040B964675B9FC", + "ek": "32CBA337E8CA7A629B588B26218CAC94C03A73E67F6C2037B80607AD6907E2B7468774A836A270CBB03075173D97D837DF5C9E1A3889E26992900902F15A131DE49E6E36B212700C91715AB5AB568C50AA7851A83C353D60BCA348A76D26A62126B9152301A9164C3A01F05907E3283512BC72C2B39E4A7BAE0AB3963A129D2AA39A091F3534110243BCD036A0AD4A3BE03A1A7D3272D1F0ABE2E7455E82BDADBC8B25057667E79EEA898731D85B42381692419E3C101DFBF0132CE91448718B3E5C3F04274251C0854B8C3B3352B77F082DD8C10FEC06A7EE09A8ACC8A5370186E2DA4FA0DAC06CCB09610B23D8E32A1E756E2CB6A8A2BA9265C04075397EFF66A21D2B2C2990603B6664A1283297730C6E1C024D42783D982B875BA957DA4C4F695B49370A4F407ED3059614147D522936DADA78B34C1749C6C04A099BD1C19E09A32F2CB89DFD24696B2C3E97BA38C1BBB198D81C13B73B007D53B5CC70E4C3A856E0ABEB44B5ABEA1E449C72FA106DDD57C3BDBC592D01538A05B32FC85DE8E4952C2B4A2CBCCCA0100E3007885EB68473B95C9406515568AA0B1844EE2376308C841F70605BEBA3E8901707F7A874F087FBAC9A917977CFD63BC16269AC7800DE605663C16D3741077A099DBE6809C6EB162EF0AE62302114D01172567A11EB3BA5B1B425507966639E9916886A8882038B6FEDCC44DC2519DF6C79D8CCA6E7821CA96655136102FDC394A0F13FDF283B43A6BB06E2528E825398303F5940A852396B40C0560D14BC66243FE6773588591907005C5B39CA56267F2DAA4CF9455ADECA0E1CBA99E5E3991251072426C0BDB024A3F8771A8C19684A8CCF42C39948A0E7D951E9A63C5994340E43AB6937513608125FCC86346308BC87ADB154499802878A42273CAC8CA77B14D156A22921CD2AE9AEC363CCBDF2008A28621461700D288C199A51F2A6118BF2921FDA1FB963B9C048B989DC282AA9BBC9D0615F66CE21123CE5465273786886DA0289C55856B08569BC2A880742383A4B07A28E7F6B326AEA9BB5FB5070196BED6698015C232ED5A60EF9900347864D57229DCB6A9AEDC2A45045F720191A1AFCECAADC8C1E65E470DE2C6360C098955016", + "dk": "58B5077542461D311F6B00A10EAC4432C70881109FF588BFCB3073CB15382BB886119B2FF390C4BFD329D18C74A524CBFDA709CDEA35CE2AB73B13B399A9327731A29ECCC0589C762D594D80E12F1A005698B406E2D025F9AC025C46658AF413A17053CDE4CA13D128CFF52922F046535816ECD8601401C4E5CB15854567A9A7B165B42D84424F8CABA817B6631F9B20BDF41A859C56B1D6991F21257BF606C37A2503A83BEED9AD5085B4A0B709719CAA57484B8C639E613B766BF65C2CD449F8332142E0C650A618EA165DD0B594471C3C1E80BB95F504F8D2764A7984830765E182011336B9D2A23B07E2BAD8CA964E4A56007460F59A41A42AC62C17234E0443CBA6CF27724A6E8B651BDA3B788C8D99981A8281789C478143923883261C976475BD5602B013933CBC89A9959A9C2984CB3728D3E29702B26C3E728EDFB4165B387952FC5FDBF70AA32204147C458F471375AA961C1773A8AC3746EC49B7A120AF022A22878958B98FB6E37639D582C07233964106B3F015E95CCAF8A621945B00B61059804C8D47A82FD014269E2C5068B3ABE6B310D9C63C7D37B778D07DEB47B1178BA19C5B59C3E86796F2CF939341E1226C4A5537076085CD9B66CD731125CCB20E4249CD655E547748A8000392BA37F7840E515863E54575167A98B4BB81CAB934CCD53AF976CAB207868B18AB7530AF2D1908ADB85D000D32AFA706F81B90178001F2C57449402C64353F0FE33FE8139153FB3EC3577522373A0B092C55CA22EEA64FA886CF53E92B571C04465A7DF9909FCFC20463258957023097845C88A0C09CFB96AA960692F546B8A1893CE5846AD3CA83C98DB7650A42E56AEDC197ABB09579F6247F79257E71CBE27BA494F668EA60807DC61DCBCA1D1531261D776BD41901156B82C40BC5852517EA130D52D02132D151D28670F14494A207193E668613C58E0E8A2F5124B47EB5CFB2276FA75B27DF08359C5920FA9757A8AB32D40631F593C26E63ADD40B3DF6B849BC8AA8BCF7AC1530C73A802F2FF2CE94CC4EF26158A1F66C37EC4A947568CB68442A42C6E5BB358643BD90014232CBA337E8CA7A629B588B26218CAC94C03A73E67F6C2037B80607AD6907E2B7468774A836A270CBB03075173D97D837DF5C9E1A3889E26992900902F15A131DE49E6E36B212700C91715AB5AB568C50AA7851A83C353D60BCA348A76D26A62126B9152301A9164C3A01F05907E3283512BC72C2B39E4A7BAE0AB3963A129D2AA39A091F3534110243BCD036A0AD4A3BE03A1A7D3272D1F0ABE2E7455E82BDADBC8B25057667E79EEA898731D85B42381692419E3C101DFBF0132CE91448718B3E5C3F04274251C0854B8C3B3352B77F082DD8C10FEC06A7EE09A8ACC8A5370186E2DA4FA0DAC06CCB09610B23D8E32A1E756E2CB6A8A2BA9265C04075397EFF66A21D2B2C2990603B6664A1283297730C6E1C024D42783D982B875BA957DA4C4F695B49370A4F407ED3059614147D522936DADA78B34C1749C6C04A099BD1C19E09A32F2CB89DFD24696B2C3E97BA38C1BBB198D81C13B73B007D53B5CC70E4C3A856E0ABEB44B5ABEA1E449C72FA106DDD57C3BDBC592D01538A05B32FC85DE8E4952C2B4A2CBCCCA0100E3007885EB68473B95C9406515568AA0B1844EE2376308C841F70605BEBA3E8901707F7A874F087FBAC9A917977CFD63BC16269AC7800DE605663C16D3741077A099DBE6809C6EB162EF0AE62302114D01172567A11EB3BA5B1B425507966639E9916886A8882038B6FEDCC44DC2519DF6C79D8CCA6E7821CA96655136102FDC394A0F13FDF283B43A6BB06E2528E825398303F5940A852396B40C0560D14BC66243FE6773588591907005C5B39CA56267F2DAA4CF9455ADECA0E1CBA99E5E3991251072426C0BDB024A3F8771A8C19684A8CCF42C39948A0E7D951E9A63C5994340E43AB6937513608125FCC86346308BC87ADB154499802878A42273CAC8CA77B14D156A22921CD2AE9AEC363CCBDF2008A28621461700D288C199A51F2A6118BF2921FDA1FB963B9C048B989DC282AA9BBC9D0615F66CE21123CE5465273786886DA0289C55856B08569BC2A880742383A4B07A28E7F6B326AEA9BB5FB5070196BED6698015C232ED5A60EF9900347864D57229DCB6A9AEDC2A45045F720191A1AFCECAADC8C1E65E470DE2C6360C09895501683E3ACD9B35DCF6D9E93B006201B0FE23745F0E2E2CD1793BD7B3F6B84220BBC9FA6AA53F505506BE269CE201A1A6EF95692DD1350A7188F468D34C5DAE5EAD7" + }, + { + "tcId": 15, + "deferred": false, + "z": "A9EE7619E4F0250147ADC188649A45EB6D82DE5EACD5643CDC52E6DF8DF2F8EB", + "d": "C5C26DF5BA8BAB4A293292BD070986A8063F736469F6ABBAB684F7127575172B", + "ek": "230563C475571E5CA17BF116280196E0AB1ADF4CC7F4909859177190D17E6A7390DB291CDAAC33A0A08F6FD11608DC404A43AF7E467AD3E77F6004192A758409C459F4CBCCD5AA4DB3D47891416EDC659F8628B20A656CEEA904893B84EE9B6D44B4B1E3D2A5DAE49D7A38882D6C01A07720565A878E3A3B715B27DE84B14721885D5A8D06CBC93268A35A8A3360BB10530130A1C8664117A83BD550D8CA2846250D0FF722931ACF79824A537915D21C9892A786681B44997CBD17F7C02498AB3EE4C6204C79E848BBFDC06C0112C3BD622B9FC4964F64B539630F943583E962B765816E111C850AFA6073C1BB1EFA6E450B9B518C9EB98144F5912F75B30238297F0A934116D63BC9007DE2F21D192A4A515504BD7C73E58462DB50BC1A373922EA1AD5CC4C5FCC64030B4863B047D37A0CBC2AC48484CA642615F287610DDB718BC562559992206191D1507B3BB94B6714BB062468C13921692ABD9EB93A8D3CA09C8A52FCFA36D0F9711E545028BC737DB2B3ACF9BC850A48491488DE346DED5C47DFC089EF074F6C38B3BCA7C42746AED58660C5C984D8E59F3D28276D45263D667191A25BF35A3469B55E36A449DDE713F648A18469A8E417BFDE0784E2CA68589A50FFD38EA5744116F951BF79B90B1380717C6E4C8940627C5BD4F395EF0B38BEA7C556A14C03F2A3C5A2A039BA8CB0BBAB2C0C2B4C88A5D76849F657C361212E18CC96E39788B1D086ED61440F2B10266225C48A36E0380D783677E64564BF39BF8FC8AF7C581FCE252FFF73858533B24F2610A78A2D83D7625FC1687D0CB87088B8F53B475A7A2E8E1720E6E97C1471712AD948C8A2537DDC06BEA22BC6CA8575A26D4315180FB17ABC797DD135545AE953925795FD12167796A54A9793DE8621B5E6851180CF681583AB7A33C4584B709836D79A1913E6197FC4A66876C638B12C77BC9C8BB95FE2A251D61BC260016287DBCCE42C0FB6F30B1E41440957AF90318A48F61AF588C8A86C4E6DF854808C88F2343EB075BD4BF89F7CC081F76B2FC1D410475C27244C8377852B60204636AA7619FB3D7196CCD0B211AAE40E5BE5AAF9651F99A040D32D1335AC61B1685014B4839D3BFEE2660706F9", + "dk": "206C8727F6315309314A290D77492763F8391F365742B55AA2AAB82B98492E008869EBAC27545657E38FA68A37B97B1147111A21E10AB0D522495B92F2530032D440D0C966C5D56762C841D4E68556748D15509F25142E090473D48312B453750C155B4E763B23D515CB32487BF1922E7747DA07A6F3613A50630ADBF0A9CF7A9CF2F11D2C2A244FAC0E4878A6EE24609BE2098A047A0B45173AE5788BD831A5C6C237B601371CC0594CA08E8C1BC5A040ABEAB693ACAE59B058F59B633612081B170E334432C44C80F4EA4758C75701E22A66963425840752D49E92821356149D1328C275669A3B319EE92A2B32A87D313C3F20A8A2C56021503B0FB90B599F775FD008C182F54BE04A63236B459186586804CFF9F479CD531386EB57B6133BF3545076EBCA22BC3002F62B247147C1057BCAAC43B559B6F05842E2687ACA49CF2D0C855E5051C86A74567503D975C342C2AFAC165857C90BA5472C517226A4297FBB62ACD11458788736D592475ED00B2F5C41F2C5B90D6762B064BA0DFCC40E5CA433B2BE5F6B69AD364A63999E4067944F12AA7D2203167318EF6B5220A10504778987F59A6A8A9B2B702799E2A03DEA73A66B7AC776364D2A487E043030F8A476416BA05C62E918AA8670A39E769CEF5993CC34A2A28533AA79635988278A2B2F5E787A63502F41EC81FF660E96B9801E5566F80868C843B992B86976671C9BE56B1A146F83163250558F2B489E065B11AE976872D3B4B0897A9495527B3CCDA0A9A83784CA8E764943AA1F8497451AF259B61B306EBA0995B29C246812F090481F837FDF6663FB277E384250DED44B6297A46BB58C0628A48FE92EF5802BF14666E4282101D3CCBDE76675C6B99B7125A5A262374165F3BC7918F06CBD651DC302C793820281A0B83657A836365E9C982FF973C83FB6A57754967F7112061B9198A6B749064F7FB247FF262D7B234DE684319BA5A4AC0831078116AC70BB643081E9D9AB63D06061852CC3607931184CFD7A904238CC8B894F22C2269A682360E3C844894B830611A3E896CE69B63B96365E4B32CC215A5645AB721A74230563C475571E5CA17BF116280196E0AB1ADF4CC7F4909859177190D17E6A7390DB291CDAAC33A0A08F6FD11608DC404A43AF7E467AD3E77F6004192A758409C459F4CBCCD5AA4DB3D47891416EDC659F8628B20A656CEEA904893B84EE9B6D44B4B1E3D2A5DAE49D7A38882D6C01A07720565A878E3A3B715B27DE84B14721885D5A8D06CBC93268A35A8A3360BB10530130A1C8664117A83BD550D8CA2846250D0FF722931ACF79824A537915D21C9892A786681B44997CBD17F7C02498AB3EE4C6204C79E848BBFDC06C0112C3BD622B9FC4964F64B539630F943583E962B765816E111C850AFA6073C1BB1EFA6E450B9B518C9EB98144F5912F75B30238297F0A934116D63BC9007DE2F21D192A4A515504BD7C73E58462DB50BC1A373922EA1AD5CC4C5FCC64030B4863B047D37A0CBC2AC48484CA642615F287610DDB718BC562559992206191D1507B3BB94B6714BB062468C13921692ABD9EB93A8D3CA09C8A52FCFA36D0F9711E545028BC737DB2B3ACF9BC850A48491488DE346DED5C47DFC089EF074F6C38B3BCA7C42746AED58660C5C984D8E59F3D28276D45263D667191A25BF35A3469B55E36A449DDE713F648A18469A8E417BFDE0784E2CA68589A50FFD38EA5744116F951BF79B90B1380717C6E4C8940627C5BD4F395EF0B38BEA7C556A14C03F2A3C5A2A039BA8CB0BBAB2C0C2B4C88A5D76849F657C361212E18CC96E39788B1D086ED61440F2B10266225C48A36E0380D783677E64564BF39BF8FC8AF7C581FCE252FFF73858533B24F2610A78A2D83D7625FC1687D0CB87088B8F53B475A7A2E8E1720E6E97C1471712AD948C8A2537DDC06BEA22BC6CA8575A26D4315180FB17ABC797DD135545AE953925795FD12167796A54A9793DE8621B5E6851180CF681583AB7A33C4584B709836D79A1913E6197FC4A66876C638B12C77BC9C8BB95FE2A251D61BC260016287DBCCE42C0FB6F30B1E41440957AF90318A48F61AF588C8A86C4E6DF854808C88F2343EB075BD4BF89F7CC081F76B2FC1D410475C27244C8377852B60204636AA7619FB3D7196CCD0B211AAE40E5BE5AAF9651F99A040D32D1335AC61B1685014B4839D3BFEE2660706F970C2B01D9EDB8083BFB5CAC9AFC6E0A6D63D33F40E61F6A8055B63E799623A39A9EE7619E4F0250147ADC188649A45EB6D82DE5EACD5643CDC52E6DF8DF2F8EB" + }, + { + "tcId": 16, + "deferred": false, + "z": "80CE5D65D1795C90B637C10360B04A4C21A70851F0A59D4D753F54CC00103FF4", + "d": "EF0F6EDB707059073378E3419C8D9031D0732CFA931190EBD07FE291B1A3EBD3", + "ek": "8ED594BFE63B64E0C4C5A27BAF4C198E11AB91629C1C77788A05977042B4C452CDB7D66F0991BF05480763591226BCB1830B8527E5BEACC15A191ACCA3947DA6C015DA1B1800FB7B98E94BC3A61733669C6ACB8E6EDA749F879F565077FB637FC8A6892165AF17A77DB17856FA9266EE017105449C514CC6780B41A867757AD551A33341AA145085687E2C9C0CB51224A3C164BE9A36024AA8CFE97BD6C01F8F06A51F36964F1C6367D6A4C22C6B759756ADB3C558E49FE45395D7E8BF73C24305632A6573A8BB574EB6072441D66EDCE17A5B080D6F97C3A7030583837395E7378901A80B1B2CCC2B89E4C9AF74EAABD5604F9957C08D18635D68AD566A56D0D773CD71ACCEE3C697C851544B96FA4CB18A42183E2C0071A46F01F47E1455133DA73A0599AD2EEA39EBF9216DDA7012533CC4610C035C9D00E2962FA6ADFC065BDFA09AFD7A981CA0C3A010CE7040CB6A838B9C65A2E1580FFDD36911F23D69D25F211C0811215C96DA9E0B1C9C2DF24CF583633ADA8D786B6591D4A306D874A6E8A8DBD09443578D128648A9163E8734057D4449E1917B73ACCF7F87CD85DC0CA473756D42A174A8A6CF1A8A5A452F0FE17034E216A03224A423ACA52BB2EC7A6BBCF06E5616A4154683FF6CA625AA78ADD4CEEAF8BB48D37D36B79BBDC3650DA67982F6C4B2DCC00973525B4A3F06CB56B2A35F68974DCF508E6D093BBBA7780B59AAADDABFEF569A480903B648B41D4929C8A5110D6625DBB5B206CA384FBA479898B840D50E45D5CAA30C3EF143593C5BB75224629DD906AA754394F8549E4C7E5EAC45F2C216225C487CF247BAD2C5397B4A42D9B128054A80D24D4D9068373462547799EF612CF61906E224C03693B4CA28983F302B0E935EE11882BD8A8596533E004C8F59380412299A97BA5727A02CE3E410DA564BBD713BE085BDA1192EB27314136754513008A99CC3A2949FBD664C92920807860C1AB1814E1428642151CFAB3C8256832541A957F5020F89230C5C162A03437A917A7B96791F4B1401E79CB55375F585C9C4D166D9760CC36B802E6B5079B0836CEA1078B3BD7E5D33AB48E02C5BE40EFF344F369B920AC3F396FE7F940C6218CBE3B81D3904", + "dk": "207B287A81A1C2223C1BB9B373614F93B575DCA90BE6567EEF7B535C1684A6D0CA4B36420E989A830C9CDA69B8A7655D28F18325741A8CD874A88686A802C26DD6B450966C1EB02D271B89FB528988D4C6ECFA95E7BACF0BF11AF655AA48717CD69497D611CDD2F3437E4C96342305F300953EB9881B4678E4317C400228D945A6924042FD5A86A566A49A577E90955EB6B068ED0568CD535DB1B957597B4B90D864BDB05EDE024EF7D4AF63D282C3D876A7F2BE1DCC0848353818F91ACB935C2CF76E652CB720DBACA86522FB4B0E276A5BE79740F2706DF0E0C64BA18C42E9A7A71092B880328F6866EC599DCF56A4254578CF219D87DBC2AD78186FC3865366415B7932E4B28C70C30D7256BEEA676300700336A814D122ADE949BF6872AE7762CCAD2C7701557139CB5D403215A52327048789CC86A5E689B609260425E7291AA15B7C30460B1B04C1E70647741739F03575E348DDF4996DB587DEFB61940C61A6C1CE6A118C46A701D3F345C1747A666283871B2BB00661AD995B26112DC1B48EDC25A1899019213A3555AB4FE17AACDBE2B4E404A117B7B4A779134090342250613CE2B632A8083D1B56B0501D026C309D25A711AACCD82806DB867A6CDC85F03BB667B2354AC4820ED4A823A0BB93C3921706259F55336D7443FA26BCA90C94D94514C38B17D0DB2909CA4C1E3568CEA34266DB9D5C6CBEC1E104B60BCB3C77A6E3B45FAD814F3773699DD86BAAEA5A6CF6CBF856A5EF6B7F21A74B61A49956935895AA7368640266291088D7BC64E70F7462343F2B943C75B68069435E53684CB74BB3EC3ABB0C1CF17621BD811D95F488C4E035B0A2C2B00C7C6F4757F5711DBD285ABF018E28E87FC95212E7A8CF91BB43C95A69C86B42ADE439189242A4F43252B0950BC43FEFE39BA66334FA1A0114E822A97B6E81356B5C7A7393F9206A38B308CBCC0EC49F079979E0739196020FD6FB07D222B8F9D7C36E5241E973BC37B58C180473E122A4A4554391A3BFAA8658A74940BB856878D39598A1C7DC485971801226F64655E310DF8C689C492A3FFC509840143BB2681C92028ED594BFE63B64E0C4C5A27BAF4C198E11AB91629C1C77788A05977042B4C452CDB7D66F0991BF05480763591226BCB1830B8527E5BEACC15A191ACCA3947DA6C015DA1B1800FB7B98E94BC3A61733669C6ACB8E6EDA749F879F565077FB637FC8A6892165AF17A77DB17856FA9266EE017105449C514CC6780B41A867757AD551A33341AA145085687E2C9C0CB51224A3C164BE9A36024AA8CFE97BD6C01F8F06A51F36964F1C6367D6A4C22C6B759756ADB3C558E49FE45395D7E8BF73C24305632A6573A8BB574EB6072441D66EDCE17A5B080D6F97C3A7030583837395E7378901A80B1B2CCC2B89E4C9AF74EAABD5604F9957C08D18635D68AD566A56D0D773CD71ACCEE3C697C851544B96FA4CB18A42183E2C0071A46F01F47E1455133DA73A0599AD2EEA39EBF9216DDA7012533CC4610C035C9D00E2962FA6ADFC065BDFA09AFD7A981CA0C3A010CE7040CB6A838B9C65A2E1580FFDD36911F23D69D25F211C0811215C96DA9E0B1C9C2DF24CF583633ADA8D786B6591D4A306D874A6E8A8DBD09443578D128648A9163E8734057D4449E1917B73ACCF7F87CD85DC0CA473756D42A174A8A6CF1A8A5A452F0FE17034E216A03224A423ACA52BB2EC7A6BBCF06E5616A4154683FF6CA625AA78ADD4CEEAF8BB48D37D36B79BBDC3650DA67982F6C4B2DCC00973525B4A3F06CB56B2A35F68974DCF508E6D093BBBA7780B59AAADDABFEF569A480903B648B41D4929C8A5110D6625DBB5B206CA384FBA479898B840D50E45D5CAA30C3EF143593C5BB75224629DD906AA754394F8549E4C7E5EAC45F2C216225C487CF247BAD2C5397B4A42D9B128054A80D24D4D9068373462547799EF612CF61906E224C03693B4CA28983F302B0E935EE11882BD8A8596533E004C8F59380412299A97BA5727A02CE3E410DA564BBD713BE085BDA1192EB27314136754513008A99CC3A2949FBD664C92920807860C1AB1814E1428642151CFAB3C8256832541A957F5020F89230C5C162A03437A917A7B96791F4B1401E79CB55375F585C9C4D166D9760CC36B802E6B5079B0836CEA1078B3BD7E5D33AB48E02C5BE40EFF344F369B920AC3F396FE7F940C6218CBE3B81D3904BFFB491B529857FB52940ADB7920E6785BF951468B8578AF5D830FC94BA1C12F80CE5D65D1795C90B637C10360B04A4C21A70851F0A59D4D753F54CC00103FF4" + }, + { + "tcId": 17, + "deferred": false, + "z": "B923CFEEC804B8C6A9E36B77B38A2886C45B1C731A33528ED2CB5A1F65E792F6", + "d": "BEE40356679E3EAE8B0C3FA07C1BFDC8835CEC26CA194D5EFC4301481C256C0E", + "ek": "28669B7A46A351A14CDD8C5676451577D43AAF842AEF96BDD6AB11A948832082CE85A21CBA773EB01508EE3B230F8A5D9FC6617E959FAB9171AB232BBB560D84579992E00E9C338E77043B89B1804C4021DE8124E61C6D6D72BDE0DA854C19CC69D88FFB43B1F983BAC8A84B65480175B8C74B6BCCA470482FD813FA7773570B52B0221B73F48635821427D3B6CEC089CC0C1ECB398BF4956DB4666555F90385A500F24868545848C96C5553FC7387671957745582D662FBBCA46AC9C3392B929BF634DF35638C8255B8492BDBD98FB43B207604919FE855CB48911BB3186690600D80B417FB54E7641560BA5800D46784F97C4961856EA25AB3F2A0608019B0234F41571618851D2D6831B28B37AE777AF3C79A8CD9509BB9348A30A37CD04083660047A0AF514B328B4B3835EC0C2E66C03CFBB05D7418AE4B5578A58BC051A616180F899B371DFC1C441362B6F8359A7B83754AA2B46884072977AE1651137875D4440F04F173405A4E60BA58BD950EA49255ADF53D16B2B97E0C0943FC2ECAF4CF01357382708BE946448AF8721B10AE95A4BFF876B4D6C4571187CA8DF9940AEA45E7C8C63E4081C2096BCEF1679AFCC79EA272C3BC35E9DA7171712A0C3BC679F5379B3512DBA54583A6978A2050AC679F60C295099C82564489E3ACC816BB2E5D775D9D3522AEBC21856AB947F1C497CB20C1CB3F91446AF20646920A34A72394442504A7C817887C177E75459A902323B87A3186CD5001C16CEB73B9BA6A5EF9AFFEA729423C261F121F8653384740A50551CD90292B0671A15599C9164A5054AA9382F55C3FA5A376C868C5498D29E00F0CD9ADADC07E62431D11C21B22374474D5BB513C20C020400B696132EAC94CCCB684937B6CDC507B9B06C3B7C21AC37C5F70C8EB024565D896854C9507082C96A8B7D260C7496AC7546C3EDDA17620DA177F931BD91692890570716455497C8114D8B1FC78506E137813F1067869AB940AB5BF452EA0C02F450972570C4F96F144CA368D77614BF42494D84B3EE6A9AA8A74CE8D0988D038CD971A8C5924BB25923FDE557CD0F336DBA90CB12C38A604FB1DA89F328816D27707C8971D43A9C34B11B683DA50A2B46D270D", + "dk": "FF6013CDBC6DFCF608A3178E7F251FF65867B72B2B4A87A0C0B5BA5B908B0CD878B76BA6F5DBCA047C40FA96479EE2BB2B97CCF6C894AA68505DA331F932BF05CB5F41D394F7875733261E68A02DBFD360AD29589AA06E2440165B16A46913AD6675B68D8B9A27661B709B687969BE0E53CBD567A84CA5A8DD84A2D522C6643A9CA5321987FA7EEB1C0C3742BBF43060DA234AC9F21881644E4E18C7D49A9501930ACAAC17CF536485805E928169584B8C013C30C924A5C81508A9928D54E1325A298115C76F9F95C154DA38B1C857E8676F7A18A35EF2690F743C4F49AEAB6A5E0D67AA18B908F4E0477C7399139490BE077D3B3946BB7C086B3C261323844DBACE09F008F0D3AB5996498E164466421294AC3852C3066FB7191EC33415868CE554C73E0316B1FA0C414405D4FC576BBB6D45FBC2A6BA1882C8575CAC70BD33472AA62BAAD07586D7631D73CBC9AA8875A8927092A0498483A48575E8538760D253A73A8B4905253285A07239B4CF6A091699274BAA5D692CB2614661104AA94AA38228583AE3326548151F39821AFA55752DAC4B25DC0530115027B3CAEAE44AC824ABEEF301BBBBB79113651C686067131A6D41031A34B4AAEB9B868C6CA1122B63363EF7C373064B62E894A654651F348C7055EC758C90642B793622B050D48BB5C241793AA701388C70B3AAA248B270B1E996DB4024D8FB56810C985038C4CE6647B497A233915924E3A9E47A382FE277AE063C02D0371EE964E16B817A6919B7DBAE053117E2012ED3D54FA9A216B0CC3812168A56B34FDFE107E2157E4DD55460C8753293CD614CC9EFA12CA0CCC712CB97703C60D6B763BF23C6CD71539023B1D2958098524A115B2B201B4A1CFC7B0CE3A667C9814AD7C90D24A2295076605687D7CCC8926A1F3D209F02D2486A9764F8D26CA7BBCBA8E53714B52AB87148E7E69A99348514192C8C360718438E2A70ADB107C7D005B1F9537D50D930574A5ED684AE5DB38E6876255D188AF85CCB4ED946FEA92B2E29C5F93083AEF30C6D37B39FD45120BC0FB39711A52A3C108105AF039530505D48069580650528669B7A46A351A14CDD8C5676451577D43AAF842AEF96BDD6AB11A948832082CE85A21CBA773EB01508EE3B230F8A5D9FC6617E959FAB9171AB232BBB560D84579992E00E9C338E77043B89B1804C4021DE8124E61C6D6D72BDE0DA854C19CC69D88FFB43B1F983BAC8A84B65480175B8C74B6BCCA470482FD813FA7773570B52B0221B73F48635821427D3B6CEC089CC0C1ECB398BF4956DB4666555F90385A500F24868545848C96C5553FC7387671957745582D662FBBCA46AC9C3392B929BF634DF35638C8255B8492BDBD98FB43B207604919FE855CB48911BB3186690600D80B417FB54E7641560BA5800D46784F97C4961856EA25AB3F2A0608019B0234F41571618851D2D6831B28B37AE777AF3C79A8CD9509BB9348A30A37CD04083660047A0AF514B328B4B3835EC0C2E66C03CFBB05D7418AE4B5578A58BC051A616180F899B371DFC1C441362B6F8359A7B83754AA2B46884072977AE1651137875D4440F04F173405A4E60BA58BD950EA49255ADF53D16B2B97E0C0943FC2ECAF4CF01357382708BE946448AF8721B10AE95A4BFF876B4D6C4571187CA8DF9940AEA45E7C8C63E4081C2096BCEF1679AFCC79EA272C3BC35E9DA7171712A0C3BC679F5379B3512DBA54583A6978A2050AC679F60C295099C82564489E3ACC816BB2E5D775D9D3522AEBC21856AB947F1C497CB20C1CB3F91446AF20646920A34A72394442504A7C817887C177E75459A902323B87A3186CD5001C16CEB73B9BA6A5EF9AFFEA729423C261F121F8653384740A50551CD90292B0671A15599C9164A5054AA9382F55C3FA5A376C868C5498D29E00F0CD9ADADC07E62431D11C21B22374474D5BB513C20C020400B696132EAC94CCCB684937B6CDC507B9B06C3B7C21AC37C5F70C8EB024565D896854C9507082C96A8B7D260C7496AC7546C3EDDA17620DA177F931BD91692890570716455497C8114D8B1FC78506E137813F1067869AB940AB5BF452EA0C02F450972570C4F96F144CA368D77614BF42494D84B3EE6A9AA8A74CE8D0988D038CD971A8C5924BB25923FDE557CD0F336DBA90CB12C38A604FB1DA89F328816D27707C8971D43A9C34B11B683DA50A2B46D270D9F2CB0E23865248EA1B9E200008F61F1D55C1D4C1F30686982C673E44312AE6CB923CFEEC804B8C6A9E36B77B38A2886C45B1C731A33528ED2CB5A1F65E792F6" + }, + { + "tcId": 18, + "deferred": false, + "z": "1F4863F16E38DFD2C42A9322FA1ACB941DF3BDFA000A202AC621936FCC5FE33A", + "d": "C6D5B35B90FA9AB9A7B438B57942D653CAE67B314C7FD152013B4E90BEF8201B", + "ek": "77531B993B3BFDA74DAA9964E4D8781244493F3133DED822179B5E12C252AA5655B7748D3A187F3B017E6E9C7B82A1A494CCA1AB590DFCECC946087293BC42DC7A48584808FF62A0E1CB46B04122144004507610FBE7A359E399B44A08E4452FEFD0BC6C906078210B84D981E936CD54F1BAE79A57B7F64E7B7C69585C783E9C4A1CC30F3F6302DB928C1AF4CC0E0ACC4E627F78D41329303265FB0FA565CF83D7BEDD6833873A9EF6A32F33575884C1639A054998DA1B1D93C6A25379A367C9A14C1F7F1C75258A2ECD071809953E9293BF8ADB2E5BB109A50B6C290211BE035F3B6B481A341CF9EA372A1626FD0B193BD42A7B622D8253BE1123B37B28B6AFC7A1937AAB444CAC44740FA112BB7C960BCFC0818689C7E2607080D24D53DB80B2811EA5E74287090604AAB587F392DA186F693B06F59B45256128C33A942E05779CC570143196E85A45032984C5A834FFA23F0C114BA96B0B0392959BD4CAA859B12377A905330B77C2BAFB4A754924157B6367910C91C3AA41EEA76EA9ECCD4B9667FC4839A8EB2076D935E86694B8D9A6C7A1558F70391067A0B26BB368AB571621957F097B3CD1870D02A5DD5A646774391CC48BFBC012C315B1F06A6474C279599490C76049028B7EE886C55D979C24FB03A28C8756ABBB9D9B7E3F281AB8107EB22104992240A9E92089361E65643CF270C222971D3FB385CC5594C41B35BD2A0FADB51923143762944219459A56726ACEE42C91D03DA6C49D1B46C5EAB710BA68540981C65B2B7638273C4341058E54CCDC8130B155CBA88C2A16A9B2DDC4C92CAC9AC9267151AC39379C0F2078958C33563E360B8118118B185F906CB438AC052D625D04A17DCFA7A5CE4200509784D679081E173ECC2B4278618363637555464876D47E3494CA408BA45507A492039ECE577A17725D6472ABAE1562F3721195D193C962B01CACBD80A85DCFDC221698B54B52874DEB8450A435DCF1204A9CB329E21374268046AB00CB4416BFE207F018390E37CDF8797DB1238CFDC2C0B4F495B015CEDB138C36D415DF9672AB506095DC6862D49D5541CD3D93748955E792F5729A3191AE5DCAC826DE5B8ACB573648D95D36C5BF399CB4D9C4F8", + "dk": "9904CDEB001524F59BA84901022C3B4D81C1A0BA1724B373F4A6869D0574199787069A1FEDF8AEAFD82AFB823F5F718490E1359F495390393A12B15257C2C9E56BC52691228E00C0311C9577FACAAC34B65BD5428CE226779C8208DB6B25F5BFF40CCC1DA60A4C6AAE8EE553EB64B235918C879B5690E4B421375A1A1350A960C643DB4B8AE405E58974878B9F6F87CBAB57B4A3B8B1BFDA9823797C239740588A854D9AAB4283400E8B93168A1D680C05B07231B8A455C39893C260B0182B66E13ACAAA20ADFBFC11CCE0CBBE29C1C7B79B6D78A931878C4604174BBBC28C0A54F8C50459F7A93CE97D393424A4B8C9728871E9741AB54129E5919742BC4CD95B1775499DEF0753839622677739E87A8A8C651062F7408B389EC818C15D300A7B95AEFBEABFF078BA0E27A842DC89FDDC5378A5CADE512B3CFC65D8472ACD311E8BAB4979C15A17F33125327C9C73AEEA3642AC225958778618D522472AA89853142D35AC93264CC423A1EC8CB460A398746CC9C1615326B5819B0697D1452BFE3A86F21B7B3D11B1F6284806B5A09FF362CC5B50E0A45EB84B084EE024B3A654AA5BB7EC34604BD6627FDCA48EFCB410B9769FB6BB3A94835B2A4850128CAB534E2B3A5A5B4B367DAC9E3BE913AA12C887589150FA64EC0C1293F8410499220DF0ACA7A52C2C66CAFE9567C3B0B32F593E7ADBAE1BE64197110E9D8B77864158AAF77AD1F8232212758A5C7BA401B32C258389347C37B0B3D8B78C30436D54B800FD88772E309621955C49B77A5F9452B4B74876DAC662F76B63760D52D20692647BD1707045A09DAE8324D9688CA56B034F0BB4E378288C328ACD742169B3704C02BAECB68AF8309DC2D30BC836A856635CA4701BFB74C5662C69B11B6BE0CC984F12493540CE50DB83D3D764A5E63A13C2AD3CF5C67E8638CEEC9193470C6AA069240A53DF6C68C439B3EED8C5F4DA7076306E5223B9104662DFB35276B4823531C848747AF50081BD56A6C4B154C39B2E0CD3131B4742D241A385D938EB2C673028636FD893BCF59519C2A87D4BC42862CBFA0370D8D44CF3E032178AA077531B993B3BFDA74DAA9964E4D8781244493F3133DED822179B5E12C252AA5655B7748D3A187F3B017E6E9C7B82A1A494CCA1AB590DFCECC946087293BC42DC7A48584808FF62A0E1CB46B04122144004507610FBE7A359E399B44A08E4452FEFD0BC6C906078210B84D981E936CD54F1BAE79A57B7F64E7B7C69585C783E9C4A1CC30F3F6302DB928C1AF4CC0E0ACC4E627F78D41329303265FB0FA565CF83D7BEDD6833873A9EF6A32F33575884C1639A054998DA1B1D93C6A25379A367C9A14C1F7F1C75258A2ECD071809953E9293BF8ADB2E5BB109A50B6C290211BE035F3B6B481A341CF9EA372A1626FD0B193BD42A7B622D8253BE1123B37B28B6AFC7A1937AAB444CAC44740FA112BB7C960BCFC0818689C7E2607080D24D53DB80B2811EA5E74287090604AAB587F392DA186F693B06F59B45256128C33A942E05779CC570143196E85A45032984C5A834FFA23F0C114BA96B0B0392959BD4CAA859B12377A905330B77C2BAFB4A754924157B6367910C91C3AA41EEA76EA9ECCD4B9667FC4839A8EB2076D935E86694B8D9A6C7A1558F70391067A0B26BB368AB571621957F097B3CD1870D02A5DD5A646774391CC48BFBC012C315B1F06A6474C279599490C76049028B7EE886C55D979C24FB03A28C8756ABBB9D9B7E3F281AB8107EB22104992240A9E92089361E65643CF270C222971D3FB385CC5594C41B35BD2A0FADB51923143762944219459A56726ACEE42C91D03DA6C49D1B46C5EAB710BA68540981C65B2B7638273C4341058E54CCDC8130B155CBA88C2A16A9B2DDC4C92CAC9AC9267151AC39379C0F2078958C33563E360B8118118B185F906CB438AC052D625D04A17DCFA7A5CE4200509784D679081E173ECC2B4278618363637555464876D47E3494CA408BA45507A492039ECE577A17725D6472ABAE1562F3721195D193C962B01CACBD80A85DCFDC221698B54B52874DEB8450A435DCF1204A9CB329E21374268046AB00CB4416BFE207F018390E37CDF8797DB1238CFDC2C0B4F495B015CEDB138C36D415DF9672AB506095DC6862D49D5541CD3D93748955E792F5729A3191AE5DCAC826DE5B8ACB573648D95D36C5BF399CB4D9C4F8956A0C263895B5FB51D08CE116A156237494A6C79B54BD23134DB26D3D3F0B9B1F4863F16E38DFD2C42A9322FA1ACB941DF3BDFA000A202AC621936FCC5FE33A" + }, + { + "tcId": 19, + "deferred": false, + "z": "53F5EE39A553E831BE32EB490A6E1DE62FD4FE486EF58A4B99F6347759BB8905", + "d": "5C6051E18E28FC5719E3172B967D25BB1649D87743440F7715E860AA212A256C", + "ek": "DA73368E74CEA1A5B1B1AB47FBF38B33A47BA9F98F3D719F938082806CCB59503E1EA999C35272875B112BE8097414BD304C5C8AE127EDDAB111F6B5A8C5B8F8C39E8C41754BBA57683C2397B612A11747C508103C689ECB9394FA9B54F898678A3459FF6104B3350B8B548F064C47EE0702D6910213CA5A5909134D5B4176BC60D7533CD1BA294EB4751054AECFB73478EC38322A7D7DA829DF8A2F19C31EA9442E5AD30E00707747787F005B9CA9B9544FC61290262247B8AF26B490704B21676A138E11A797391ACFE7A6C9D0692ABA2FEB982262327749D55E34A6A4AFE3A061E3256383667035236422A38A371FA6D48120CB1C78E53607ABBECF319A46C0834D2A05B8E303CAF734A9370BD6855C7E676E637576D50B0DE8676D209305A11C5202288B9E80BD235CC543458FBB470702B4A2C4758EAA992320F08FDDE8B25AA4A08480BC401C534A6C4A79867A26B19297FBBB90739973A79E05998140587E26CB8C464A96A3DB1FC24C5ADCA02D076B352576B506C451CEA40E3EA4412DA2048B25093D80C39AC6300BD0B318A7BE644C5838A301ECEAAC5AD6364807255476AC75CB0C9ED033E5350900C0795584034DEA59D8844FB669B09EBC8AFA43C45135640316A5D86947B9CA445D432D02A624D0F46D396C5A09E3C43F0148ECA5A926147A200750FAFCC13D53CAFF188718883AA4B4BE97C72C1A6136CE266FF6451669BC78C862C883C86422366657097AAFD77F88693A9ED328CEC05D2E984D188A044E026C65E212B2307D838A549E623793865E2D13926F85128841BE2FBC666C6921212AC85D804D4655448A07CF7F41CB8A9623D4E48D72958004C1C28093AB060371642307F8F7859F1B08D0E45259021E2FEA5D4DD99E3CCB980DD51307776AFECCB7EAE1776FF09676F3697EB98DB283414D9872337565D0450FF3765DB8F5CD3DA30DEC806ACEC879ACF9995D789F03F182B8E2C314C92E6C36512FD223D6A99CA9657A04125CA5CCCDD0F967B1A767D37AB08F26759886C555E9713ECC22C5FB2663398592549D731C84693449AF0675767A72E9817E131209F3CC907B5337C46F460DA1941825DA2DEBE7A27ADDE90CF053AD520522866B24", + "dk": "6656048914A30A786B57E77371D5AC2F5327D5D26EC077B6D2D817FB1ACA449A34990B5DC22638BF6473560BB853212343203F60298E91C64454B87121147BF55742218327E0D84ED1C07FD7755AED894A3BF3393068B7E99009678BCBC6028B74F0BA5862B3AA5B704AA3A4EA658E40751F69B51171177620E2794A64864A2617B603BB6CF7068435CF38371F84977E9D507F298CBC6D717E4955B9FB5B307870BA8B09952DBB9724252A622A22F6C89956077099919BF2D7CE7D456AB3F70FAE9B68362593D7ACCA8C4955D072908C981DF377B58881A8F4046F342178812C99E2E86F9557A81CF632430333C5E961F0B167A1FC2FAA8B7648F342E1022FB8478661D7505503BD6D18275029C8588C8E675B80B6D722E707C8E9B28636B894AB8164CFFB3BDE769116078F83B97953DBA7C00378DBCB620E3C650AE72955E5434A2CAEE4B15DFBD937BBCC3D1D256ABB361B7E007C8C53429698BBCAF54B3283AE02461D17A2C41AFA21BA466B2247CBE01483A0C0743A32B854A9AC78175E6BE102A9C62CFAC5811FE527D0F433B8E708FA106DA30A5E0C9C0E63B6B3356557982B3B03B437CB412EAB525668A7723CBBAE801025D5AA7EF2D5A5AF5051B0B958FFE677DDC30E70D8507BB24D2600344D226CF602916AA175D4BAAF27D96696B4BEA828895AE8BABB449649798905575D71C60F3B9C0B73EB3AF92B98B90284421988F257510BC822DA501C6C8C54FE0117BE44AF4A12820AC9203C52466C76651580B962B2543BD0BA7EE73CE28B76411316FEC5859576CE5F83C8C3B159BD16CE58A92730F627E4B9770EC9BAA5D343FD630ADB9326DE8340BF5AC319DC43E5E03B50809876B6804582069258B9078267666416022382A1816DC6E670FAC16D18D861DAF022389762D915912EC7A7A3F0534F93B7D38CAD99670734883BD8D31E8B70BE90839963ECC83091086E689091CA6EF8477AB21960432593DD7694D0E898038BBBD603ACA19B8BB150B80960A63894A231ABB7826B1976FC331839586E3C816A1450742C719E674A2D1BC6B1B54D5F407D1E96849FB841703005DA73368E74CEA1A5B1B1AB47FBF38B33A47BA9F98F3D719F938082806CCB59503E1EA999C35272875B112BE8097414BD304C5C8AE127EDDAB111F6B5A8C5B8F8C39E8C41754BBA57683C2397B612A11747C508103C689ECB9394FA9B54F898678A3459FF6104B3350B8B548F064C47EE0702D6910213CA5A5909134D5B4176BC60D7533CD1BA294EB4751054AECFB73478EC38322A7D7DA829DF8A2F19C31EA9442E5AD30E00707747787F005B9CA9B9544FC61290262247B8AF26B490704B21676A138E11A797391ACFE7A6C9D0692ABA2FEB982262327749D55E34A6A4AFE3A061E3256383667035236422A38A371FA6D48120CB1C78E53607ABBECF319A46C0834D2A05B8E303CAF734A9370BD6855C7E676E637576D50B0DE8676D209305A11C5202288B9E80BD235CC543458FBB470702B4A2C4758EAA992320F08FDDE8B25AA4A08480BC401C534A6C4A79867A26B19297FBBB90739973A79E05998140587E26CB8C464A96A3DB1FC24C5ADCA02D076B352576B506C451CEA40E3EA4412DA2048B25093D80C39AC6300BD0B318A7BE644C5838A301ECEAAC5AD6364807255476AC75CB0C9ED033E5350900C0795584034DEA59D8844FB669B09EBC8AFA43C45135640316A5D86947B9CA445D432D02A624D0F46D396C5A09E3C43F0148ECA5A926147A200750FAFCC13D53CAFF188718883AA4B4BE97C72C1A6136CE266FF6451669BC78C862C883C86422366657097AAFD77F88693A9ED328CEC05D2E984D188A044E026C65E212B2307D838A549E623793865E2D13926F85128841BE2FBC666C6921212AC85D804D4655448A07CF7F41CB8A9623D4E48D72958004C1C28093AB060371642307F8F7859F1B08D0E45259021E2FEA5D4DD99E3CCB980DD51307776AFECCB7EAE1776FF09676F3697EB98DB283414D9872337565D0450FF3765DB8F5CD3DA30DEC806ACEC879ACF9995D789F03F182B8E2C314C92E6C36512FD223D6A99CA9657A04125CA5CCCDD0F967B1A767D37AB08F26759886C555E9713ECC22C5FB2663398592549D731C84693449AF0675767A72E9817E131209F3CC907B5337C46F460DA1941825DA2DEBE7A27ADDE90CF053AD520522866B24F8568A428B981C5C2DCD0C7E8B487824825DC3F9C0356ADF0CE075394DD1BDC553F5EE39A553E831BE32EB490A6E1DE62FD4FE486EF58A4B99F6347759BB8905" + }, + { + "tcId": 20, + "deferred": false, + "z": "9C7C3E68F827936D8DC435942DC4925D180E6D5C911550089E1337D8BA77A06C", + "d": "CA351B0F454DE9DB364E1DAB8AEF6E49C2E69439941935B24C00BB9952E65BB3", + "ek": "F7F7C6DCFA28B52749357994F5C18DF3138166373F1D9C613410287E1BADEC6C23120889829C251831507BE05E137202A9336EF5C69D33823B69F91EC25369FE3C8FA8F2A244A1ACBAF5C851418515548920333F0B584F60C22063D66AAF545328F1CFA23BA676140D0E7BA6D6D94D4409AEBF5B209524A68645277111BAC6A2B09A13944D9471E9F704441215D6B93D63FA01E3BAA4BEF7C701E485A1A89CC8E8602C5259CF3A176EBB85487C3BEAB80B4E5B8AE1B54335BC5BD1E94D35090CDE556E2559A27F770053541090CB94BFE3CDECB1B99C0B9914460631061060927507096A16B37DB0091616BC00CF68461C3A47BB585E8997C6A46C09B07C98ECCB10E30C45D014A1B9C2559EB190651296E97C7DE0BBC475BC49AB13398CD98C91A06273654977AC3B70EA83BD5657F47381D9090909735EB899BE2DA5BC73B56232736AA326845FF5AE6C452523406901781E095244C8F689B0271D53327659D0A625D75914E34394149C955935ED88C1B41475671338451B61234549C74091C9CB14E90B02356BA21CD4C960522190CC68C71AA088FB2EA5D1A777075DB4210A289B208BE66F6BFB6DA19540B740A34E822232A4BBFD028BCC304976A4C2ACD924153A974FA345959AC74D13C6C287265FFA6F8639BB0E407C1380627D74BA3ADCC81176A85503213109493A2C745D5A65EAD31333537C51CA45E8A34A3D555C19649726C6675B645519645E6331A81EE47C6EA35B49283AD8E48FAD465A426A3352C0001E8BAE99607A26A71126355A0127C288266951E845CBC0942023950CC73677228059321C2BC9414A190EDB61021BE21A4CC26CE4E1303C430BBE607B996AB304519A4148BCBD72B0B23BB947A36DA2C983898A71A8D18F8CD571ED274EE76713C540118B0CB45CA6BC72C5C96FF1B231823ABBF112FD2683F12973DCCA995B007DEC83B600999535590AA98A61C711A2DF076E65803746E93885621557821F49E3497EFB4A0F8C34ADB34B42CC0F32B09D898903F946A569C6CEAE0630E13004BC75241343061D2BA6B1D7BF44A00712941C10E64183E5A007708F798456C695B15F75C3C6A27310393A3049089ED8EF92DDB01CE5F59229FF7CC3", + "dk": "B0A66733CA122538CA1C747B2DB0CD8E3A67D1F3B1F695BC40540BC5BBAB6CB1664697B5DA7BB181DBC1546A2F5F4C4958D8C73833372F0355BED21262146574E24BD42B3FDCD45B333750B0AA8A29E34FB9AA76BDD2B1CB6799539463026029EC43655B716351288C95D1B81DC572A8980CC1EB42914B0B7E957FDC8373533201317A54D2A497A4D85E3F695F579942750AC04A9A7D068C4429FBAE653AB8AED01227C9892D79CFE300191BD310BC704BAAF78F982BC09F40325D869C962AB618F25A18477B46A9A42657C00DEC939A5187C26342C552880DEAC83A5338D3B10EF4C71D54DB77A8EB01EA87A534ACA53C70B25C98988AC4828A0B49B3627F7B6156F665133AB01F42B47E298B983939857849409BB76C4B0856A364C86FF6B32AD81F28DB51740048853836ED972B92295E16FC51A15465FE592090874FEB183C28090465204490F561A388430AAC26C8B133EABA1FADD91C9832C43EDB9A9B8195490B4153D1CD3B34523CD98F570B33502C818C765188B40E43A8B26D120E4A67ABD430650F7978FD3551620A782615214085C28B44B4986C952212C0A7F681B355964FC0C4EA914E66FC8E4EA40750404D1441C543FCC3B938B20464229FC99AEF56B1123C11EEB40DFA68C6F473C3B955685875256CA0BFCFA39944443C3F1160F808682933053E7759F8F2494DE65D4E4C159AFB4F34C6862D26C41DF2AFF896116007785D58068E5086B2426EB5124FCD0A9C8339BFA01116F862581F5307DD0C8B361113D346629BC29CE3A21CBCEA14483010A878A9048C11E1E6A07E011E4BAC09870037E1FC4987F94513403FF9D9964639885C14851A1B5FF5C119F4522976AC4E7839B1BD607F113A48739670BF0CC7A37498F8A0CB74B8A9DFD298C9F916DF547F68C2A369966D99C623CF782DBFF542C885BB5D9B027FE3CD50B54656179332EB3D162B8CF59B604BE519A5ABB105C0012967CD794217A8E4A3C43B785255AAF80988DFE0979413C31EE13D55DBC43B316E85EB0C7470C5F2577BFD185774CB03CB39CDB408C243F26DA2B424A55C3D8975CB1F900EFA1A3FF7F7C6DCFA28B52749357994F5C18DF3138166373F1D9C613410287E1BADEC6C23120889829C251831507BE05E137202A9336EF5C69D33823B69F91EC25369FE3C8FA8F2A244A1ACBAF5C851418515548920333F0B584F60C22063D66AAF545328F1CFA23BA676140D0E7BA6D6D94D4409AEBF5B209524A68645277111BAC6A2B09A13944D9471E9F704441215D6B93D63FA01E3BAA4BEF7C701E485A1A89CC8E8602C5259CF3A176EBB85487C3BEAB80B4E5B8AE1B54335BC5BD1E94D35090CDE556E2559A27F770053541090CB94BFE3CDECB1B99C0B9914460631061060927507096A16B37DB0091616BC00CF68461C3A47BB585E8997C6A46C09B07C98ECCB10E30C45D014A1B9C2559EB190651296E97C7DE0BBC475BC49AB13398CD98C91A06273654977AC3B70EA83BD5657F47381D9090909735EB899BE2DA5BC73B56232736AA326845FF5AE6C452523406901781E095244C8F689B0271D53327659D0A625D75914E34394149C955935ED88C1B41475671338451B61234549C74091C9CB14E90B02356BA21CD4C960522190CC68C71AA088FB2EA5D1A777075DB4210A289B208BE66F6BFB6DA19540B740A34E822232A4BBFD028BCC304976A4C2ACD924153A974FA345959AC74D13C6C287265FFA6F8639BB0E407C1380627D74BA3ADCC81176A85503213109493A2C745D5A65EAD31333537C51CA45E8A34A3D555C19649726C6675B645519645E6331A81EE47C6EA35B49283AD8E48FAD465A426A3352C0001E8BAE99607A26A71126355A0127C288266951E845CBC0942023950CC73677228059321C2BC9414A190EDB61021BE21A4CC26CE4E1303C430BBE607B996AB304519A4148BCBD72B0B23BB947A36DA2C983898A71A8D18F8CD571ED274EE76713C540118B0CB45CA6BC72C5C96FF1B231823ABBF112FD2683F12973DCCA995B007DEC83B600999535590AA98A61C711A2DF076E65803746E93885621557821F49E3497EFB4A0F8C34ADB34B42CC0F32B09D898903F946A569C6CEAE0630E13004BC75241343061D2BA6B1D7BF44A00712941C10E64183E5A007708F798456C695B15F75C3C6A27310393A3049089ED8EF92DDB01CE5F59229FF7CC3BDC6A66F789A31E64AFEBCBB1DD2F94747FC7559309D17920DCBBC3C38C4BB059C7C3E68F827936D8DC435942DC4925D180E6D5C911550089E1337D8BA77A06C" + }, + { + "tcId": 21, + "deferred": false, + "z": "97A4C9A65A82BAEC15FF165E10490976EBB19FAFBA8F9E8E0DFFBDB4D5E1ACE5", + "d": "C467A43BF9E9CCADCE4581B53F8CA0B605583775AFCD0EBBB587907B3A813D94", + "ek": "E5169D5BCB1CFED42BBC044B89208FBE0399AAF9A3552B7B0A579A43BCACF0D1610F6057CF938A157A9DF8B797D402461559CEDDA6A15D754343DB49C4D095A4E763FD22833FAB8B909A2129E628B9FA656482AFE9659B52AB9C74EB885A667D42946B35D163136672F30404FB881FAE153B13589299C515185B25D878ADB1D903743B4ED2B96838C29FF3C5183CEB6CDA510E6EF85037163DB1D658831B97921273CA84A924947E47F88BD2E3ACFDB5B7EA634C70794D9CACABC67C08E4379DBEB84575542A108671FFD6289FC97B97F073C98A845E10BF63C1990347A6C165317A51CEA3231632A967D2A97619414701BCC6F839C51FB1885B7993A891B31F7A79B19176FF215EAD642BD9015DE7DA03584A867C83C0ED7B5EBB16CD6FB671B1F48BF426BCCC24529F91819931921016A627FC2960C8104913A6D4372964013B0951593E09B8256984E8999A28DA134AF4556F5A5A39A63FBE950828474FAEA86F33629DDA45C42CBB90A885AAD3A4C006E66741362A3FC9CFD92B94D6979EA5623554986F36F4C9898681B345C81823852FABC76234023587B10462008562262BB37981EAC047D458E8D14789C18CB740BE85B57BA613B884104DF64159B277C469F72EEF73095F34C4341374992BCE5D02169CCA1FEE5456F44BBB52C4C12610AB2E3A48DBC9A4FAE18B5CB6A1E2177191338AF490A18F107C4A9704DCE3A40F997233347A7ED8116BEC2469BBAEE4EC141AF80F45E67FDE896838761BCA4B7213D260BC362EB3924F0964A59A83827BDC69A1D816DB49A077150486245E07C3B7261B1DFA7492B778073BCA7BA8B690C4F47AC8398A3B10A18779935614282D64428C4B50FC879109B22F44E079AEFC50741677CB4566AE80114DE8033AEC9B04202EB45176E7BB77A9A1220845C9C2E5746037C422A96D23EB07E4B4996B2B12470C62EAE1C972A22A259B7B4098197C69571B9066DA5712BAC75AA1D69C4B289E2301927CC730E9E15F3E01928DE1AAE25B80D6A80DB4D834E61AA6BDCC8615C0638865C573B5B06EC9C16DC014BF53239F91BBE0D5C25D09A766405C35D11B3732B2D2AD39A22C1FCDBADDC3A81EDC8E5EF80FE66B2A69753C82FD63", + "dk": "4A7429DD79A88B892D16D35201558135962685EA2F76A67DAD213DBB846FA229764E354745381DF8B64217A9BAB2CBA9E143C22F901A3C0089081C6B7D4B91D7115C2A740D57745B782122A4D015BAB56E41FA2642DA060CE20078E57FC2706A676BB2E1381D639951F0866A401127A4312BA3F89CB8E558AFF6B86899617D57606BACA6351185F1159D9F4A469A0A8B36B50E13B164BCBC13F473B31A7118DC6A5C79702405E0ADEB466A359B8F47EB807ECCC0E0E28E55C28266219FFC3A530220B97B080C91302B77819A017B2689F7A5F9367EA8422412FA8AADB20B4E34006236454C9B6BA1B1C160BB46ABFA8CB0AC530EBC3D63909FD2CABCB009C67759AF90201C3808B35C917E82847232074C67D37D55454EACE4B4CEC23300BD58836786A5C02014E537848A012EA7C0E88071D305C539B7B4EBBB5DE188B566119956E264C8131DD318C80C56C000848C3EA22C0B358AC0B08B7B5A864601AE8C72C9A4113188251243E951FD9542061653502475D1396696C4C9E94105C3806E26128D24ECB03BDABEB2F49DFCF0795D4918E4394374DB596DD47B23BA543207C2C744C5D83C1C4E78C0C2B0072CF4A9870C4A6F1CB9B41867F6C1278D477928307752F0975FF30106982EDB719F1BB97B70C8828EF4C1C475B59BD61C7CFB95D95ACB251A0984E37C8ABC92A8B564DEA4A5C2301E60D10227AA7161B52B8BF4370CFB7342A756F343A020B84052626D3E9B2B11CB819D0358D2B99041320209248B9049B6D96302F871A0F69493721935F2753786CA1673A907618C83C9D3B9D2B6C702EB90C8A8BCCDA54EB782AE17513E38840BA30C6920F8B9C2E32653D7B5B7F6B50A08BC86CA5A1C756610A595F1D8034B26B29ED676AF2C26788A3CC3B271A9F30B2BB473D0E47C941711ED6355823A82FD957D1D709EA7152E5B5BA97F78CC2A997405BC46AE8CB24223B0B39129D8B7CE677C82BFA332B66B26C9E61DC13656EDF538C65C88AB15A1F019044BD0A5DD32090D0C7E59E269A4213EDDC469FFD18F1532A7AEAB051DF7727C14BC721B2F39326C43A266BC531850FBA0E5169D5BCB1CFED42BBC044B89208FBE0399AAF9A3552B7B0A579A43BCACF0D1610F6057CF938A157A9DF8B797D402461559CEDDA6A15D754343DB49C4D095A4E763FD22833FAB8B909A2129E628B9FA656482AFE9659B52AB9C74EB885A667D42946B35D163136672F30404FB881FAE153B13589299C515185B25D878ADB1D903743B4ED2B96838C29FF3C5183CEB6CDA510E6EF85037163DB1D658831B97921273CA84A924947E47F88BD2E3ACFDB5B7EA634C70794D9CACABC67C08E4379DBEB84575542A108671FFD6289FC97B97F073C98A845E10BF63C1990347A6C165317A51CEA3231632A967D2A97619414701BCC6F839C51FB1885B7993A891B31F7A79B19176FF215EAD642BD9015DE7DA03584A867C83C0ED7B5EBB16CD6FB671B1F48BF426BCCC24529F91819931921016A627FC2960C8104913A6D4372964013B0951593E09B8256984E8999A28DA134AF4556F5A5A39A63FBE950828474FAEA86F33629DDA45C42CBB90A885AAD3A4C006E66741362A3FC9CFD92B94D6979EA5623554986F36F4C9898681B345C81823852FABC76234023587B10462008562262BB37981EAC047D458E8D14789C18CB740BE85B57BA613B884104DF64159B277C469F72EEF73095F34C4341374992BCE5D02169CCA1FEE5456F44BBB52C4C12610AB2E3A48DBC9A4FAE18B5CB6A1E2177191338AF490A18F107C4A9704DCE3A40F997233347A7ED8116BEC2469BBAEE4EC141AF80F45E67FDE896838761BCA4B7213D260BC362EB3924F0964A59A83827BDC69A1D816DB49A077150486245E07C3B7261B1DFA7492B778073BCA7BA8B690C4F47AC8398A3B10A18779935614282D64428C4B50FC879109B22F44E079AEFC50741677CB4566AE80114DE8033AEC9B04202EB45176E7BB77A9A1220845C9C2E5746037C422A96D23EB07E4B4996B2B12470C62EAE1C972A22A259B7B4098197C69571B9066DA5712BAC75AA1D69C4B289E2301927CC730E9E15F3E01928DE1AAE25B80D6A80DB4D834E61AA6BDCC8615C0638865C573B5B06EC9C16DC014BF53239F91BBE0D5C25D09A766405C35D11B3732B2D2AD39A22C1FCDBADDC3A81EDC8E5EF80FE66B2A69753C82FD63D9CD4496493358B59E14BC382D58982A03F9561B4ED09C4D03D89EF77D9CF47E97A4C9A65A82BAEC15FF165E10490976EBB19FAFBA8F9E8E0DFFBDB4D5E1ACE5" + }, + { + "tcId": 22, + "deferred": false, + "z": "973DBB6EAF76AF0C96F0F24EF9AE65ACD854301B5F7A7892A17FBB8601DE78D3", + "d": "D732CF45D7F44788E17C3B6DA9987495AB1AEFA233F74EEF8D3BE5B6C0C04E00", + "ek": "9DA1B8DCA84AF685C5EE685BAF30CA58BC22E9C75ABF67C8D5B8C283BC95004BB51CC6CB001466230710A9E5B43891581C9315A3B579B28B9FB60C5A44D47733105D136ABECE627889E19E4FD25A7C94C404207A4B982327A05451250C173B67A4F7CB2F19CBDA5637E6462842B7688559C599D62A6828AB62B75738E632C381C36E58424AC486BA4C1F4EAB5C4C9A96D27A1F4D3296F65A6094FA7FD27B02707C69A7B92787F737CD4623E3E51444CC698CBC7B38AB98F9883C63210442C8508A126870B7C45127C3C036B39A4C1E44909570382DC20B31E8E262ADA13847599EEAE60BFA024254726D36717C4C43B4BA148F82A93667B82407F2AA3E076E19E513564CA6907C293023773FBA330B8B9C90B08665122D31564BED3632936C5C70C4C452880BFAB97EE6018A67E0891EF64C86E8C4562C29CA609381B8AF55FC09069673FAE60E0412678958053F160F4E4AA135D89FBB0172D10CCCAD38070AE918D85C0866882829603B8E4B90E2074716A05FFE7B1959F8C16FA7CD42CC8A124B930AB87812C4C47B8C58352677EB718F508165CCD4CB3F6B6FA86460B744708F57046FD17215EC9AC6F92EA354AF8C83C0B4369AA475233A310FF7A915F9C64A10327F042C8D6450B0248621DD7748D116C090C6C6B58447433810EA47A07F9956482073FAA67CFE513AECDB87A1695A23E454D918CE0E69BBBBF0761F1B1C8F535469CC25204592DDF8008154144D148B20460F95B1B26D0CC5FF45081E379B85E642EBFA1728CA1435B081F4F608A92148FE27AD97D10BE5D3550ED08319218768D31D5DD9B2E8629B65A2345D259D45B4719AAB8616DB6422B9AEDA535099D503E8A865F3BB46C3A49C3784CCEE19CA3DE5189873C212068DE128C86884C2A3841D2DABA8088B4CECAB729C0C73421B8D0278343DE01584D37971E802A0699CAE5B2CF86800D6C348A0D8C4942538122C521B56A45244AB672402CF7B1A9E999820349F7E311940B5B47FD07C8CAAB8CD817DB897A4CC7591BEB264F043401B06932F81C5E8F525C81BC5D4C75D75CC98B8B6502625CACD671C408C21812277B7BA3388D40B4FE46510A1ADDFC040696BCFF31CD1DE026A9D5E8D3B6F", + "dk": "AB606FB6D65B4A42C61BF14D57C06B8EE33E740ABE1068833667B8CE769EA1FA5AFE7447863C3DBAB8B86C1C818CC3A2AEF08C50641F566BB154D57E293A468437C6A7805318B3578F83C927E6BB56AA31F096809A315C5D88473DD0BF2162BE18CBC013918504E791779A4A2CF82C5085BAAF78CE27690F164478C1F340A3582C845B2114978E2B7029D6A861FE302653213C1F9A437C9C870513ABA2B64A744A92BC37CCC8C0664CD833065613E7770C6C01A6F9091F02A99EB5F85C2361038A0662B3352C09FBC1948993724A87E2C71D63F7392E9950B2A84F241678FC15890247BE20C660AC3B2FDA9CBB9C919193F13EF3A5BA98901CDED47A6E1B300CF779BCD137748B571FC4CF890A69C1B5CDDBE30650877E2D82263448CDB1882D57716A76294CE8EC931AA131F06965678AB8FD778DAB50C58381B8090A7912462400E0B0E8F7C9F1FA78C57A056B423495C75F62D5138BB3A1034C70208917F30263E66B4D2949377BF29362A6531A81B82EA88517D3B943A14868D7691E4873F29AACFA8B71DBA337C9E0BCC1C8AA8BA82A17A28395B45EDCA609BF95B883731C62C000A3D431525391860223579C247AE825CDE91E1FE3B0A056BE5694627BF3BA189031353429D0C64C79448E5E4C80B8963C4D7229E9188B76F1738C30BDDF49B236544558C9A7F979B1C34826C0FC10B3362E84D62A665B16648CC8376BCB1A71116E260E0439A9EFE287AEC68942F3916CC77817C9C89F378E5976B3C8B9815F7013D573C9EA656A95F40F1243B5940B9F6E830341E1108A45CB68B346600406D87403B8352FD7014CA3762070FB8DF892871087B7E0BC5562B9686BAC3A67665AE4CB118A602C28394224D15C5A9615C86B40184A9B7E4A68DE936C8144A157F4B1AB036F30D92F0BC497ED0716380BAB4677111AD19BDDA98B333C960ACAB48E33AE12389492B98CF4FC90F7102012840010F63CF78B6193E133E45B81E6380B4E01CDD0814C8E97732B4BACF3171215728A378BAB58853E38FC51A788829E810292C5089EE972B8850182D37D49F8BFB09178D5CA779E91776BF8579DA1B8DCA84AF685C5EE685BAF30CA58BC22E9C75ABF67C8D5B8C283BC95004BB51CC6CB001466230710A9E5B43891581C9315A3B579B28B9FB60C5A44D47733105D136ABECE627889E19E4FD25A7C94C404207A4B982327A05451250C173B67A4F7CB2F19CBDA5637E6462842B7688559C599D62A6828AB62B75738E632C381C36E58424AC486BA4C1F4EAB5C4C9A96D27A1F4D3296F65A6094FA7FD27B02707C69A7B92787F737CD4623E3E51444CC698CBC7B38AB98F9883C63210442C8508A126870B7C45127C3C036B39A4C1E44909570382DC20B31E8E262ADA13847599EEAE60BFA024254726D36717C4C43B4BA148F82A93667B82407F2AA3E076E19E513564CA6907C293023773FBA330B8B9C90B08665122D31564BED3632936C5C70C4C452880BFAB97EE6018A67E0891EF64C86E8C4562C29CA609381B8AF55FC09069673FAE60E0412678958053F160F4E4AA135D89FBB0172D10CCCAD38070AE918D85C0866882829603B8E4B90E2074716A05FFE7B1959F8C16FA7CD42CC8A124B930AB87812C4C47B8C58352677EB718F508165CCD4CB3F6B6FA86460B744708F57046FD17215EC9AC6F92EA354AF8C83C0B4369AA475233A310FF7A915F9C64A10327F042C8D6450B0248621DD7748D116C090C6C6B58447433810EA47A07F9956482073FAA67CFE513AECDB87A1695A23E454D918CE0E69BBBBF0761F1B1C8F535469CC25204592DDF8008154144D148B20460F95B1B26D0CC5FF45081E379B85E642EBFA1728CA1435B081F4F608A92148FE27AD97D10BE5D3550ED08319218768D31D5DD9B2E8629B65A2345D259D45B4719AAB8616DB6422B9AEDA535099D503E8A865F3BB46C3A49C3784CCEE19CA3DE5189873C212068DE128C86884C2A3841D2DABA8088B4CECAB729C0C73421B8D0278343DE01584D37971E802A0699CAE5B2CF86800D6C348A0D8C4942538122C521B56A45244AB672402CF7B1A9E999820349F7E311940B5B47FD07C8CAAB8CD817DB897A4CC7591BEB264F043401B06932F81C5E8F525C81BC5D4C75D75CC98B8B6502625CACD671C408C21812277B7BA3388D40B4FE46510A1ADDFC040696BCFF31CD1DE026A9D5E8D3B6F960EBBE29B71F9BB16A8B5EDB72516DEB04771759A6A306CCEE5D40D8E2EFFDA973DBB6EAF76AF0C96F0F24EF9AE65ACD854301B5F7A7892A17FBB8601DE78D3" + }, + { + "tcId": 23, + "deferred": false, + "z": "D525CCE60C3E300ED36298A1C0D0165C147CB84197C4028257DAF39239E6EA5D", + "d": "B670CEB5612A1287C4653B158A3CC522AAA1AA45B34A4C770DCA1E5BF3988F3D", + "ek": "0148396E994C3C5809BA5A53B28582B5B12827616D84BC9B6FCC94B84A1FF1EA88D308302F611683EB500953AF2D588EE43C7C4CCACC276128E6509DAE5A78DBF654CB9A0AFEF98339A46002B432C90BB863CA5221522BC7E903E2D1AC26E4968B64888DE455D6CC61A7FB2BD8E03BAF87310337361101BEAE92C64904BFD6D74F9D4327E49B15A7468889C6BE1F6A6DBB3529ED166BB0791381D42A59C85D54C1484B50AFFE893FB2A5BFD60974BC804E30A14E5DD22284C361CFC311C261C02D450B864095109B01DF56016A8BABEAE78F6145CD65343A8E7B098E904453E165D31273ECB4486B1B43BF453AE853B74AB920DB1068E8D9C8C8779BB63545EA0A15D4A1C19897C8BD40CA1C66381832A990FB74ADCB4FDFB2185AC33D9A24B58983B352AC26BE979D2FF8B8975B7D6B09B50E0C635625A99E91C552F37C37C72B763047C36192900B0A49BBCBB19C611CE77562D48D06CB735E174184952614B9236C55A256394FC5661F4F70BAF5B22BC1D67860A51E0F301AC5DB4F15D061028026CBB4A35E1782B406C8F92A40FC500F5FE706CB1A33DDB73597575BE787CEDC5C43383A404C88503B351732BB9FAA65C07C0B1EBCE001D5D18203672885E201C3D9855F81C36D39B060761DCD069E7CACC758026456E266DCA665AB32908069448BD251F3D3C09B15B4DC2234642295BA9419574A8E3987B69C4058FE692DB8124821B1A7F4097712B828AB69C9B0F5A6AF9B515588146EE9A1E79780A2C9634AC9CE38282B1E47856F365F23AC249D0BB7E42520B8B3A08792161B8B86C59CC0DECB2160F536394A750CB9373BC62BB2C6AF8257935465C550382822A915A501693A777CC9E46F415BB581C70B39DCA1F84673B6DCA1BF2897B8A57CE247267013A49D3543CC8533EB5BBCCEA0A9C82909ABEB98CADC45EBC5B4034145B7F5A777759CAC11CE4C359B0AD4BC30567E9F195C9082B3A71779D9A3B4EBA72E557AAE9B964285D142BA0031C3990192912F34B540104A7E13674B30C0569685A4ADA913BEA4439ED3C99172A3672886B857830DB939A2836A8E3186C8B8CFD87CEF4EBC154213985561AF0C82B28B8C856D8923219B1829FE8B51954BD0E8", + "dk": "4ED9B27229CB08667437F2B6F0B28ADA29A384F726E1F86DCD26433D55CDD5511158EC7D257892080A4DEE204FA1103890821E2F233281FB064D299DC9684D3D08A60669B014112338476F0455780714524DE0538628C72AD360A795038DF2C3A44058D71C285A4A951086889A8A4DB9AC9B4F76821E12732DF3713842012F3A8F4A611202434A1E6046E58085568037A4884F3D8539FA5005A8E10E93BC03C58BC9D575761E4A5379AAA8422A1CBAF58C8F9C1DFA00BD0550980F86B32036CC2F55C4C6602F5CC528BD1971ABD7AFB1528F39A7CFE1A42CBA9716B1A6A8A6722F04BC5760497F79556D7C065E4FFB9A4E8019F38744849B57D3F17AB8C37FF71CA594691AE9288BF7E1BFB09C9B113C375B4AAB07C91452E384E8F8B1629B7E38A1943513CB2AC40A5803B71DE455FB2B55FC50CE6170A15DC4A9719193A5C2CB17C62B87C53605E955225080011468913AAAA4946C9A084A2405A335BABFF2E19A3209C34273CC96A4509A0041E474C44F53617A36326A7892B6D079BC4651775B0E06EC01C81CBDAA7574CBF84940384A15777F241268CFE65E6408609E404A372BAE702790E185ADAC6AA93843B3CE88696E3252EF73B46C5A4DDE135372A32762B963670565531784144399C6195EA6C924B89AA5F9B64BA44416D92B3E75F7BDEC264549B045922612C0995BBFF71DC7505F04D4BDBEC3A40E7C402A225EF4153C1A322B6E19BCB0328B9ED23FE36A6F13780A6A78171E875CD37A79C3375671D066EB20072DA5CBFFB8772DA14DE98631899597F7F55AE84BBEBEF076E709CB68946041F0095759360E003665408105184B39A7261545AC0E7984FD32A773D05A04A48FBCF02B08E7B3E326583DB71F59E15C7D1A9D6AF1494CB34E63D5C6CC07C23BE95F3EDB765C33131FC92B07592C724832DEFCC1D5F937AA8323C1089CAB760D26AAA49EE1805FF62382998B0A4B8DFF6C91970126833B44518501A908A0A7C462E678495DF876CE3A71528CA877890B56F6B23C9C2C560B0ADA3A1915E265093267E21A2EC18351079011E6E0CF76967AE3B80E1038B3E203A40148396E994C3C5809BA5A53B28582B5B12827616D84BC9B6FCC94B84A1FF1EA88D308302F611683EB500953AF2D588EE43C7C4CCACC276128E6509DAE5A78DBF654CB9A0AFEF98339A46002B432C90BB863CA5221522BC7E903E2D1AC26E4968B64888DE455D6CC61A7FB2BD8E03BAF87310337361101BEAE92C64904BFD6D74F9D4327E49B15A7468889C6BE1F6A6DBB3529ED166BB0791381D42A59C85D54C1484B50AFFE893FB2A5BFD60974BC804E30A14E5DD22284C361CFC311C261C02D450B864095109B01DF56016A8BABEAE78F6145CD65343A8E7B098E904453E165D31273ECB4486B1B43BF453AE853B74AB920DB1068E8D9C8C8779BB63545EA0A15D4A1C19897C8BD40CA1C66381832A990FB74ADCB4FDFB2185AC33D9A24B58983B352AC26BE979D2FF8B8975B7D6B09B50E0C635625A99E91C552F37C37C72B763047C36192900B0A49BBCBB19C611CE77562D48D06CB735E174184952614B9236C55A256394FC5661F4F70BAF5B22BC1D67860A51E0F301AC5DB4F15D061028026CBB4A35E1782B406C8F92A40FC500F5FE706CB1A33DDB73597575BE787CEDC5C43383A404C88503B351732BB9FAA65C07C0B1EBCE001D5D18203672885E201C3D9855F81C36D39B060761DCD069E7CACC758026456E266DCA665AB32908069448BD251F3D3C09B15B4DC2234642295BA9419574A8E3987B69C4058FE692DB8124821B1A7F4097712B828AB69C9B0F5A6AF9B515588146EE9A1E79780A2C9634AC9CE38282B1E47856F365F23AC249D0BB7E42520B8B3A08792161B8B86C59CC0DECB2160F536394A750CB9373BC62BB2C6AF8257935465C550382822A915A501693A777CC9E46F415BB581C70B39DCA1F84673B6DCA1BF2897B8A57CE247267013A49D3543CC8533EB5BBCCEA0A9C82909ABEB98CADC45EBC5B4034145B7F5A777759CAC11CE4C359B0AD4BC30567E9F195C9082B3A71779D9A3B4EBA72E557AAE9B964285D142BA0031C3990192912F34B540104A7E13674B30C0569685A4ADA913BEA4439ED3C99172A3672886B857830DB939A2836A8E3186C8B8CFD87CEF4EBC154213985561AF0C82B28B8C856D8923219B1829FE8B51954BD0E8379CBECD878337A3709BC5A62C5528CB3504D6A87427DC404EFF9ACAE893CEEBD525CCE60C3E300ED36298A1C0D0165C147CB84197C4028257DAF39239E6EA5D" + }, + { + "tcId": 24, + "deferred": false, + "z": "9F2FC49CD848BA72FC17854B18D88ED65B630BA94A1BC5F6D3A458E1087D3A13", + "d": "3236CB10279681238E5B0E2F5138A7F743443379F5F1A845F3D76B75D2C2A9DF", + "ek": "E08607BB14655E1B5DAA36971A842091513B13720A20971FF32279FDE800CF82A95F96AC390749661958E510605DB13175B941D27AA8D1B07A76BB3EFCF8810F144F2566C938DA012E792F5EA41AB74431DD50584756963C752F8ED1109021521D4CA897019AF967275C92AEBA2655ABB291E9115C964C5E5EE748D8C0258DDC504DBB98218A7DC035251A958CC30821ADC997667616DE2A4497039189F582BC4AA9EA4A33BDC1858D8681D4088622A0CB8EA59413423BEDF0CFF7F36BB419B1B672820EC177B3920797244079738EBEAC8D34057804E9A6AA31B39F589F59198972213A12F80D4163A93511985B892ED8BA9A0FA260A4EA8A3BE1A556174C3A599F31D037293C5B8F6A229E23ACB6C772529B918C5324246C2E6B8C693C512BAD0C1677E013C7B10686E728E66723068256FE924F2F3A1578569D24D8327AC543C43AAF423776EEF10D43A69AD87058A37A95F4D8C444A08EAA9CB687E0851BC2A7D304B39B2953AC81A4E9E6B454DB06E75B495B11416D78C86009904377996BB0489BBC2C1B68C5FED757782082472616BCD7AB7747A36457B7BEE74F9BF39A10C9071BCC9269B61EE93B2062160EC69174229A9EDA906559F677018A28F1A278D6337CA54AC68F7265133A1CB59A64E0699348153613191DA8793D441C1422F498B9088EE3664153F67EC443CD8DD10D3068628F10C49662CEE84CC2C85B3C59553B7220AE499C1A9838A8D0E497C11717B5539575F62CB49597C9466A0331C118849F53CA4EAA516CD8343B28F5A0787313F6F1331976329203B0CF871A2CBA0418A574DB037DD12A139C3B36850C8E2B2C056920A1F656873DA9CEF9427D4FDB15D069CD54FC479DD63464F63598728D050444E2014D6E7040F7942991D34B228076B14207F8777D718180AC9C54379B7952F732E865A915F874D1BB839C1A4E2617455AD061509C83CD9A123A2B34C4393C8D09A2C9BB8D52643FB6205730C98976F99D649428CCDC4D109242E7660DA8187C1C1BA83FA11834B0824E31084F0693ADDC1F06DA292398906CF2C07DB5337EACB9492C57F12499B9BA7828A4D75A3EAF1E72A78C47ED24CDD9A7BE6E15D35A92BD110C97DF3F400DD95B", + "dk": "E3930A94D60F5D896AFC749DC3D5CE56A566D7D28795B7747EF95DF030C97C048657B6C1AC754E15F47120F75129E34B10BC3F11924D42655836D6B7E5D126309070E2D75E616A517481842B851148A586D9015045DA3602FABDE204AEDC633B95C30B8DD533D61222BB465BE3BCCD792868990C3E7C1B0E086ABD3EA9CF4F110B1E7612B0C32FDC693CE2FA3004E40A507674528749A470ACE9201D68F56CA717C19539A0418488CEF40CEA1458D6EC298FD04F60C9878F01851EF07B032C3A91B0C742A445E5E72131E00594D0595794745C26BF17E7A4297A9186B23F3DC90B0EA183CFC13AB5269CBC4310840029644876E6C6C73E066230F182CE3B0F039522DC7ACA25AB1DBEE371574786308C177E1ABE75C202D383C47409111FC29F72E18085542E231486F6F76A9CD0BCB9384DAF6318260761E96A0A36DBB50B902BF6355186B6BFB552AE94385523E02935F98C2A35AA3BBC03B7B9A4E4559C741347C304AA8C033524A8835294738908879374C8AE76BDB52C30203A50D5B9330CD2941E6A9EDD51659C50165C06232778B39AB6041E27BFA5DA56A5811C7CE35140724E7DB5072BEB217518120D5366DADC4653DB4D260C65DBA35342D34BADE3A27E3757345C3DC4D4B4AE1068D02989B63722BE94A2C8589DFF97B236B0CBEBC436F71B4DC2A619FB88C16A476A42E51410ACB5BDFBB01E9B695C2724536BADA18913E3F3555B120D61A158F8722688B6C703675CC9580C37C52E2A338E08192E3472BB600037DA863195F0A0E4C215FD57A19BA20CD57021F5025E0AD79FAB9123238890451547B0670491B03DA6C6567A767449B7BBA1FABEDF7BBD38E56A02F9AE20E0C5BE502350A1A27A9A5457B3C173796986F4703EE6BC2706630ED56859781DE66AA9B9AC87D9F512FE569C5F164B46AC0F3175516F633FE31C60B09893CEE29EAE725F65033E0B1BABBE453F84F6673A963FE74A8B5FA046108A2243690D9072406154C6A0024D2CA4B4EF1A681A911A781C776C126775B0CE65110BD8C76A1B2444F62B2CE4541C102C70C1F46B6B5AC0F8A8574836122A99B1E08607BB14655E1B5DAA36971A842091513B13720A20971FF32279FDE800CF82A95F96AC390749661958E510605DB13175B941D27AA8D1B07A76BB3EFCF8810F144F2566C938DA012E792F5EA41AB74431DD50584756963C752F8ED1109021521D4CA897019AF967275C92AEBA2655ABB291E9115C964C5E5EE748D8C0258DDC504DBB98218A7DC035251A958CC30821ADC997667616DE2A4497039189F582BC4AA9EA4A33BDC1858D8681D4088622A0CB8EA59413423BEDF0CFF7F36BB419B1B672820EC177B3920797244079738EBEAC8D34057804E9A6AA31B39F589F59198972213A12F80D4163A93511985B892ED8BA9A0FA260A4EA8A3BE1A556174C3A599F31D037293C5B8F6A229E23ACB6C772529B918C5324246C2E6B8C693C512BAD0C1677E013C7B10686E728E66723068256FE924F2F3A1578569D24D8327AC543C43AAF423776EEF10D43A69AD87058A37A95F4D8C444A08EAA9CB687E0851BC2A7D304B39B2953AC81A4E9E6B454DB06E75B495B11416D78C86009904377996BB0489BBC2C1B68C5FED757782082472616BCD7AB7747A36457B7BEE74F9BF39A10C9071BCC9269B61EE93B2062160EC69174229A9EDA906559F677018A28F1A278D6337CA54AC68F7265133A1CB59A64E0699348153613191DA8793D441C1422F498B9088EE3664153F67EC443CD8DD10D3068628F10C49662CEE84CC2C85B3C59553B7220AE499C1A9838A8D0E497C11717B5539575F62CB49597C9466A0331C118849F53CA4EAA516CD8343B28F5A0787313F6F1331976329203B0CF871A2CBA0418A574DB037DD12A139C3B36850C8E2B2C056920A1F656873DA9CEF9427D4FDB15D069CD54FC479DD63464F63598728D050444E2014D6E7040F7942991D34B228076B14207F8777D718180AC9C54379B7952F732E865A915F874D1BB839C1A4E2617455AD061509C83CD9A123A2B34C4393C8D09A2C9BB8D52643FB6205730C98976F99D649428CCDC4D109242E7660DA8187C1C1BA83FA11834B0824E31084F0693ADDC1F06DA292398906CF2C07DB5337EACB9492C57F12499B9BA7828A4D75A3EAF1E72A78C47ED24CDD9A7BE6E15D35A92BD110C97DF3F400DD95B402618B875F180B5A47574F635D61BB39EA75D44240CBD759B7B5C22C889851C9F2FC49CD848BA72FC17854B18D88ED65B630BA94A1BC5F6D3A458E1087D3A13" + }, + { + "tcId": 25, + "deferred": false, + "z": "0FB831AFA34B124F7456D0D09E4ED8607DE407101E6E75F305F9D67EF7C2FAE7", + "d": "C155568B6BA74DA317388423F8FB28585977EB858EE306CAE4174120F02A8D72", + "ek": "655CA28309AD58DA0D71919EED2C5676E134C1AB1860923F1E34AF07581D64121B72B8ACE613BE88AA28BD7B0138B44FD9C39B65FAADA741934AF9207AFA367CC1AB29CB71806735973188CD146813331DEA81A811F61FD8F59FC668AB29C581C5878F2D4698E5CA52DD664AEC16ADC357CEA156876BB6663DB12479F488AA46B7873968D0AA43EDC0B847F19FD4410F5E45C2A599A09E634E65B206352383B79BC6EB9309574733F9F2226D4402A4946A00D7B469DCC58F910D5B149BB5731FD89CAF9734C2531381EC2A60F68A9DFCA55C288C68BEE4A919A9A82CF01E5EA86A170B76ED5B35AD9573C3156A24D8A9718683D0F44547F03EF0237B430C16C1A22AF41B7D46E839CA40A7F5F982ECDA7EF21A7E93283B6CBB566E2237636925B887616DB260019876386BB9CB63A42EAC0EADC4C6B99A3EC4131667A4BC3015B19A9A7896422DE73655379BB57675C26F31609BF5525AC13B1A711974F7CB80BACF59B43A8C0AC6B3249968E462F782CF85661207744B4E016C22531D4879B4AD9BC80320503D311CE818A29B95595AA6AA4590876C4C62E0F5A75ECAADF4154634475425B7BD690A09650C7B543589D0342C18A2B774CB7DC8C44F3502A2C2BC148465061842118321A8D4465B4383B45A52727B389FD5A9601E560C9FF68882C629D209527429C79A1ACC000B698181AE827A7E6F14235AF281460A91DBECC30E4AC3AFC4A22E45B3F1209BBDEABDD678197EFCB927B47B0C4204FD473AAB098984349FDF80B960203530E36153BAA675545F5DC6B49A276F1D210373553F9F90B2A5C661415C65A973991E2A99C756273D3261B8750431CA866FA234A7E98035804A0AAACF8D36A0BF4A5C9F9C5614138287858FC106CDB6918E2FB37BEAE2139F806838776E2B3534D78ABB199833E784A6FC144A6D7CB8984C4563E273CE11421927377A992D602BBD11457A2C88B999B13A6B3944445CC7C8328F47040C5CB8B2EB29192FAA2720B1788A408F59828D42017D27587CEC9CA49F44829AAB7FAACC484936B38E02820C03C880F7CEC7057B89A1604D7B1865090CDF056B83E84864E13B8B1B16E5BF2115103F5E1A77266147DEB23013A1A909C1FAE8BE", + "dk": "03D96BD4C488568ABFE20B8FB2C408AAD328481B228C03894BB5248292B2F87714622714A36936DBE1BC477AC57EF3B3F46570B776014F0C12D3B0BA3FE81AA3CA9908ABCFB47AC622AC4A4ADAB3C0052EF8F133E2F8B415C3BE8943BB55C902F792CD6F3A363D3C6530D0A4AB1886EDD770FF18832BB7AD89CA126450A0A2CA587EE1552F149C2DC570447A400C403A2883A8D79B361E4AB99B53B4F6C5CF88E6B2CCE28E69356FACC4217539583ED813ED0A554562C02F6696E9AC5714B5ADD1BA77E603528A3961591B5593337E7EA552E9770AB43009A531679F4C66C0E817BA0354BA24977572956DD7043C911133F28982D4B901307375CB2EEA0089D1C03E6594AA78884BD5E7C9A8A89E9661C2E2629240CCA2E4235B13AB21F75C6FC6A529A574CDE0C5381E40137A9CCBFD910243174BE6225C3ACC8F38393365530F2905294F9ABA5108A3487C9D056559C9E8A11CC94F7CDC46533C391FB2A491973F8BB9545773BB90FB43DD7435DF6C90F8B411A8274FF648A0EEE54FEF30315993C5BFEB6BA0233EE920CE01927F8752A63598528E463A856930598643D825279F99C113B1578EB0B1D72B730D8721B8B149DD0B558977B0C3BBB0E05383C4B8844F661B6C34220D2A5FD7113DA3217EFFA6AB0C382808C0A177987E7DC8B86F39C3872A66412755230B0CB119A3E49541AD1868B9753F069A167E604BE6E01F129A684B880930202221D0BED12B9763B8BF41E639CD233FE6AA0B1A8082D6D46E5316405AA06154C622A384154FD69434E161EC4470B82466D84CCFA01B0C795C9BD7175A2DDBBC5B1CA564D942A0226F096A54AB5719A58A60387B5AFED4878DA08E9763A164E150F50CA719214181165CF1069E29FA2AD81ACA55A802DC9A03F351369F525C5DDA776B93717A617A969811C89CC27ADB185B2A197A47C6C360B7D254C0F32A20C8A35990C67098896180AB9456866B09E62941482B626BC40F63136A677AA7E1236A7B8ADD810193EC4C3E221017A6A8DBF079122CB288D60795482039A4AA7CD785B85B44D1817E5F79232318C0F6F408648A3E5395C4655CA28309AD58DA0D71919EED2C5676E134C1AB1860923F1E34AF07581D64121B72B8ACE613BE88AA28BD7B0138B44FD9C39B65FAADA741934AF9207AFA367CC1AB29CB71806735973188CD146813331DEA81A811F61FD8F59FC668AB29C581C5878F2D4698E5CA52DD664AEC16ADC357CEA156876BB6663DB12479F488AA46B7873968D0AA43EDC0B847F19FD4410F5E45C2A599A09E634E65B206352383B79BC6EB9309574733F9F2226D4402A4946A00D7B469DCC58F910D5B149BB5731FD89CAF9734C2531381EC2A60F68A9DFCA55C288C68BEE4A919A9A82CF01E5EA86A170B76ED5B35AD9573C3156A24D8A9718683D0F44547F03EF0237B430C16C1A22AF41B7D46E839CA40A7F5F982ECDA7EF21A7E93283B6CBB566E2237636925B887616DB260019876386BB9CB63A42EAC0EADC4C6B99A3EC4131667A4BC3015B19A9A7896422DE73655379BB57675C26F31609BF5525AC13B1A711974F7CB80BACF59B43A8C0AC6B3249968E462F782CF85661207744B4E016C22531D4879B4AD9BC80320503D311CE818A29B95595AA6AA4590876C4C62E0F5A75ECAADF4154634475425B7BD690A09650C7B543589D0342C18A2B774CB7DC8C44F3502A2C2BC148465061842118321A8D4465B4383B45A52727B389FD5A9601E560C9FF68882C629D209527429C79A1ACC000B698181AE827A7E6F14235AF281460A91DBECC30E4AC3AFC4A22E45B3F1209BBDEABDD678197EFCB927B47B0C4204FD473AAB098984349FDF80B960203530E36153BAA675545F5DC6B49A276F1D210373553F9F90B2A5C661415C65A973991E2A99C756273D3261B8750431CA866FA234A7E98035804A0AAACF8D36A0BF4A5C9F9C5614138287858FC106CDB6918E2FB37BEAE2139F806838776E2B3534D78ABB199833E784A6FC144A6D7CB8984C4563E273CE11421927377A992D602BBD11457A2C88B999B13A6B3944445CC7C8328F47040C5CB8B2EB29192FAA2720B1788A408F59828D42017D27587CEC9CA49F44829AAB7FAACC484936B38E02820C03C880F7CEC7057B89A1604D7B1865090CDF056B83E84864E13B8B1B16E5BF2115103F5E1A77266147DEB23013A1A909C1FAE8BE213234B8355942F1CF9F299DC63B953C236F330E3D406312E9E0CE14A3987E8E0FB831AFA34B124F7456D0D09E4ED8607DE407101E6E75F305F9D67EF7C2FAE7" + } + ] + }, + { + "tgId": 2, + "testType": "AFT", + "parameterSet": "ML-KEM-768", + "tests": [ + { + "tcId": 26, + "deferred": false, + "z": "A85768F3486BD32A01BF9A8F21EA938E648EAE4E5448C34C3EB88820B159EEDD", + "d": "E34A701C4C87582F42264EE422D3C684D97611F2523EFE0C998AF05056D693DC", + "ek": "6D14A071F7CC452558D5E71A7B087062ECB1386844588246126402B1FA1637733CD5F60CC84BCB646A7892614D7C51B1C7F1A2799132F13427DC482158DA254470A59E00A4E49686FDC077559367270C2153F11007592C9C4310CF8A12C6A8713BD6BB51F3124F989BA0D54073CC242E0968780B875A869EFB851586B9A868A384B9E6821B201B932C455369A739EC22569C977C212B381871813656AF5B567EF893B584624C863A259000F17B254B98B185097C50EBB68B244342E05D4DE520125B8E1033B1436093ACE7CE8E71B458D525673363045A3B3EEA9455428A398705A42327ADB3774B7057F42B017EC0739A983F19E8214D09195FA24D2D571DB73C19A6F8460E50830D415F627B88E94A7B153791A0C0C7E9484C74D53C714889F0E321B6660A532A5BC0E557FBCA35E29BC611200ED3C633077A4D873C5CC67006B753BF6D6B7AF6CA402AB618236C0AFFBC801F8222FBC36CE0984E2B18C944BBCBEF03B1E1361C1F44B0D734AFB1566CFF8744DA8B9943D6B45A3C09030702CA201FFE20CB7EC5B0D4149EE2C28E8B23374F471B57150D0EC9336261A2D5CB84A3ACACC4289473A4C0ABC617C9ABC178734434C82E1685588A5C2EA2678F6B3C2228733130C466E5B86EF491153E48662247B875D201020B566B81B64D839AB4633BAA8ACE202BAAB4496297F9807ADBBB1E332C6F8022B2A18CFDD4A82530B6D3F007C3353898D966CC2C21CB4244BD00443F209870ACC42BC33068C724EC17223619C1093CCA6AEB29500664D1225036B4B81091906969481F1C723C140B9D6C168F5B64BEA69C5FD6385DF7364B8723BCC85E038C7E464A900D68A2127818994217AEC8BDB39A970A9963DE93688E2AC82ABCC22FB9277BA22009E878381A38163901C7D4C85019538D35CAAE9C41AF8C929EE20BB08CA619E72C2F2262C1C9938572551AC02DC9268FBCC35D79011C3C090AD40A4F111C9BE55C427EB796C1932D8673579AF1B4C638B0944489012A2559A3B02481B01AC30BA8960F80C0C2B3947D36A12C080498BEE448716C973416C8242804A3DA099EE137B0BA90FE4A5C6A89200276A0CFB643EC2C56A2D708D7B4373E44C1502A763A600586E6CDA6273897D44448287DC2E602DC39200BF6166236559FD12A60892AEB153DD651BB469910B4B34669F91DA8654D1EB72EB6E02800B3B0A7D0A48C836854D3A83E65569CB7230BB44F3F143A6DEC5F2C39AB90F274F2088BD3D6A6FCA0070273BEDC84777FB52E3C558B0AE06183D5A48D452F68E15207F861627ACA14279630F82EC3A0CA078633B600AFA79743A600215BE5637458CE2CE8AFF5A08EB5017B2C766577479F8DC6BF9F5CC75089932161B96CEA406620AEDB630407F7687EBBB4814C7981637A48A90DE68031E062A7AF7612B4F5C7A6DA86BD136529E64295A5613EA73BD3D4448CB81F243135C0A660BEB9C17E651DEF469A7D90A15D3481090BCBF227012328941FA46F39C5006AD93D458AA6ADD655862B418C3094F551460DF2153A5810A7DA74F0614C2588BE49DC6F5E88154642BD1D3762563326433507156A57C57694BDD26E7A246FEB723AED67B04887C8E476B48CAB59E5362F26A9EF50C2BC80BA146226216FE62968A60D04E8C170D741C7A2B0E1ABDAC968", + "dk": "98A1B2DA4A65CFB5845EA7311E6A06DB731F1590C41EE74BA10782715B35A3102DF637872BE65BAB37A1DE2511D703C70247B35EF27435485024D93FD9E77C43804F371749BA00B20A8C5C588BC9ABE068AEAAA938517EBFE53B6B663282903DCD189736D7296816C733A1C77C6375E5397C0F189BBFE47643A61F58F8A3C6911BE4611A8C7BC050021163D0A404DC14065748FF29BE60D2B9FDCC8FFD98C587F38C67115786464BDB342B17E897D64617CBFB117973A5458977A7D7617A1B4D83BA03C611138A4673B1EB34B078033F97CFFE80C146A26943F842B976327BF1CBC60119525BB9A3C03493349000DD8F51BA21A2E92361762324600E0C13AAA6CB69BFB24276483F6B02421259B7585263C1A028D682C508BBC2801A56E98B8F620B0483D79B5AD8585AC0A475BAC77865194196338791B7985A05D109395CCA8932722A91950D37E12B891420A52B62CBFA815DF6174CE00E68BCA75D4838CA280F713C7E6924AFD95BAA0D01ADA637B158347034C0AB1A7183331A820ACBCB83193A1A94C8F7E384AED0C35ED3CB3397BB638086E7A35A6408A3A4B90CE953707C19BC46C3B2DA3B2EE32319C56B928032B5ED1256D0753D341423E9DB139DE7714FF075CAF58FD9F57D1A54019B5926406830DAE29A875302A81256F4D6CF5E74034EA614BF70C2764B20C9589CDB5C25761A04E58292907C578A94A35836BEE3112DC2C3AE2192C9DEAA304B29C7FEA1BDF47B3B6BCBA2C0E55C9CDB6DE7149E9CB17917718F12C8032DE1ADE0648D405519C70719BECC701845CF9F4B912FE71983CA34F9018C7CA7BB2F6C5D7F8C5B297359EC75209C2543FF11C4244977C5969524EC454D44C323FCCA94ACAC273A0EC49B4A8A585BCE7A5B305C04C3506422580357016A850C3F7EE17205A77B291C7731C9836C02AEE5406F63C6A07A214382AA15336C05D1045588107645EA7DE6870FC0E55E1540974301C42EC14105518680F688ABE4CE453738FE471B87FC31F5C68A39E68AF51B0240B90E0364B04BAC43D6FB68AB65AE028B62BD683B7D28AD38806BEE725B5B2416A8D79C16EC2A99EA4A8D92A2F5052E67F97352289761C5C39FC5C742E9C0A740CA59FC0182F709D01B5187F00063DAAB397596EEA4A31BDBCBD4C1BB0C55BE7C6850FDA9326B353E288C5013226C3C3923A791609E8002E73A5F7B6BB4A877B1FDF53BB2BAB3DD424D31BBB448E609A66B0E343C286E8760312B6D37AA5201D21F53503D88389ADCA21C70FB6C0FC9C69D6616C9EA3780E35565C0C97C15179C95343ECC5E1C2A24DE4699F6875EA2FA2DD3E357BC43914795207E026B850A2237950C108A512FC88C22488112607088185FB0E09C2C4197A83687266BAB2E583E21C40F4CC008FE652804D8223F1520A90B0D5385C7553CC767C58D120CCD3EF5B5D1A6CD7BC00DFF1321B2F2C432B64EFB8A3F5D0064B3F34293026C851C2DED68B9DFF4A28F6A8D225535E0477084430CFFDA0AC0552F9A212785B749913A06FA2274C0D15BAD325458D323EF6BAE13C0010D525C1D5269973AC29BDA7C983746918BA0E002588E30375D78329E6B8BA8C4462A692FB6083842B8C8C92C60F252726D14A071F7CC452558D5E71A7B087062ECB1386844588246126402B1FA1637733CD5F60CC84BCB646A7892614D7C51B1C7F1A2799132F13427DC482158DA254470A59E00A4E49686FDC077559367270C2153F11007592C9C4310CF8A12C6A8713BD6BB51F3124F989BA0D54073CC242E0968780B875A869EFB851586B9A868A384B9E6821B201B932C455369A739EC22569C977C212B381871813656AF5B567EF893B584624C863A259000F17B254B98B185097C50EBB68B244342E05D4DE520125B8E1033B1436093ACE7CE8E71B458D525673363045A3B3EEA9455428A398705A42327ADB3774B7057F42B017EC0739A983F19E8214D09195FA24D2D571DB73C19A6F8460E50830D415F627B88E94A7B153791A0C0C7E9484C74D53C714889F0E321B6660A532A5BC0E557FBCA35E29BC611200ED3C633077A4D873C5CC67006B753BF6D6B7AF6CA402AB618236C0AFFBC801F8222FBC36CE0984E2B18C944BBCBEF03B1E1361C1F44B0D734AFB1566CFF8744DA8B9943D6B45A3C09030702CA201FFE20CB7EC5B0D4149EE2C28E8B23374F471B57150D0EC9336261A2D5CB84A3ACACC4289473A4C0ABC617C9ABC178734434C82E1685588A5C2EA2678F6B3C2228733130C466E5B86EF491153E48662247B875D201020B566B81B64D839AB4633BAA8ACE202BAAB4496297F9807ADBBB1E332C6F8022B2A18CFDD4A82530B6D3F007C3353898D966CC2C21CB4244BD00443F209870ACC42BC33068C724EC17223619C1093CCA6AEB29500664D1225036B4B81091906969481F1C723C140B9D6C168F5B64BEA69C5FD6385DF7364B8723BCC85E038C7E464A900D68A2127818994217AEC8BDB39A970A9963DE93688E2AC82ABCC22FB9277BA22009E878381A38163901C7D4C85019538D35CAAE9C41AF8C929EE20BB08CA619E72C2F2262C1C9938572551AC02DC9268FBCC35D79011C3C090AD40A4F111C9BE55C427EB796C1932D8673579AF1B4C638B0944489012A2559A3B02481B01AC30BA8960F80C0C2B3947D36A12C080498BEE448716C973416C8242804A3DA099EE137B0BA90FE4A5C6A89200276A0CFB643EC2C56A2D708D7B4373E44C1502A763A600586E6CDA6273897D44448287DC2E602DC39200BF6166236559FD12A60892AEB153DD651BB469910B4B34669F91DA8654D1EB72EB6E02800B3B0A7D0A48C836854D3A83E65569CB7230BB44F3F143A6DEC5F2C39AB90F274F2088BD3D6A6FCA0070273BEDC84777FB52E3C558B0AE06183D5A48D452F68E15207F861627ACA14279630F82EC3A0CA078633B600AFA79743A600215BE5637458CE2CE8AFF5A08EB5017B2C766577479F8DC6BF9F5CC75089932161B96CEA406620AEDB630407F7687EBBB4814C7981637A48A90DE68031E062A7AF7612B4F5C7A6DA86BD136529E64295A5613EA73BD3D4448CB81F243135C0A660BEB9C17E651DEF469A7D90A15D3481090BCBF227012328941FA46F39C5006AD93D458AA6ADD655862B418C3094F551460DF2153A5810A7DA74F0614C2588BE49DC6F5E88154642BD1D3762563326433507156A57C57694BDD26E7A246FEB723AED67B04887C8E476B48CAB59E5362F26A9EF50C2BC80BA146226216FE62968A60D04E8C170D741C7A2B0E1ABDAC968E29020839D052FA372585627F8B59EE312AE414C979D825F06A6929A79625718A85768F3486BD32A01BF9A8F21EA938E648EAE4E5448C34C3EB88820B159EEDD" + }, + { + "tcId": 27, + "deferred": false, + "z": "DF0F282411F4A071489A8F618E2AE5AEF40131CAC5233D6D731522720C2FEB1C", + "d": "444F032DD19AE7518C4B35B0732A41DC567845ABA8BD7B04A9C413A0CF2DE0B5", + "ek": "5CC523B2D908C45907A6694A665195171A5B2FB583A5C240CADCA8F0E83E46B14052C9620D3B7EF386CE8B9A5E873B65693B0D341C6EB2D10CE5E937CFB8C4C9134401BABFEEBBAECF47113A34B9C6E011BDC78A54F2B7BF36A5FFD27563D7443F2109F02A64C421411DDB2D1404A86F793A2DE62CDC560BFD6604D4B6330BA6AA621414E8C12DC71C25652ABAF36B875DE1978DD209AB53B885206C3A1B4F8B4A0670C087CDA9CDA7997437155659255C2D024822A448CE5157CF5B6E4C495A949960886A902C79591120117C4A73CE7B380C661851E1CA9EF1973D8A9D2A191B938C4110259C4227B600BA7EC9B033BB0300715032836573382445435A743CA61E923B18ADEC7CFAF10ADE908E582560EE91ACA012942319B4888109E55AA738A7BCF777C92B4B09A50A1C043C982C2C2357F73C1687B35BD123FC905E1A719353466A42B915DBF1A1750339BF0923419681E4531D97E2160AD896DB056570570510FB711169AF2DE0CBA51C5F5056242965AD429301E7020AE0141F845833A3FBA0B192426C001A7147C2926805CD86725442CADC2636BB769DCDE46D1BD12D30F4695593B5753870EF796FB2F3A53F283D5828B77CB75D5DE1BA25357C290A957FD501AEE0AE59D7AE97833B0BB640F781A08BD256C79117C220BDD83280A0069B29A645720096D297A2E5245439268C0ED01F75A939978372B9E05D93DA899C10BF6CDB18698C46EBE00BF90730E2EA393014461DEC6C87F17B2EE16C13B8507C6009BEE074F17367A5FC3067A28B7D804C32860EDE650E6FE85CF6E301D1B1647323199CA296ABC54D2811507572B5DFF92B54E3786D130938417624775D8534B0102B6B8006803DDB376EB830D1CA80E717BB7F260A5CA4A56BFC5DA790151725942AE7C42B2B9E385B4E0F995D4402161070B73A6BB0CDB77EF11B1286D75E315635E719088DC7909D026B198AC93BB4B6FE395843A4428F75C0C1448C605A8CABA0B8CD19CE465764B523628B3334E3885D68D5089E1A3045840C36A73AEFE7B93AB357FD8A46D7547A8EFB243E4953E67CA72CFA0B77835768AA0CD2D976820A97BC21C7033084AD45C0BF6B483ACA8A485641EB55A47BE36ABCEB96143BA90C515D5BE8513BB994CFA88FF4B3600E34C1E656877606B6280384A0F481458044C47732FA9B58195A5DFB48636E1558C56A43CB6941DEE5AEB1E27B89A7121BE166879B62BC01619A9ABE840CC678E028E9BC71CE233FD9DB8816294D71F1A080101912920534750DDE692F782BAC4D4481A0900E6BB952ADA798EE06232C200F57F76A914617914B7398A0433CD7A11B5AC09789034F39338CE567E3E7AEFE35B0C3B85D21506E8886587670761AF9BAD3261DAF22CBFC664604234B3B784EA001CC6702B9222545CFDB2965EB54678780EE3C9CC134CD2E655908D6BDF460BEE364C66D5ACCF4B492ADE9A0F3EB31995BADDE4628B67165FF6014D848541035CDA46949EC1C12FF492726A7214D1C7273FB85D5484E5A178751B56E3FB163D13A53C7B3038E09B847A8C06FF9B42E8C345CC95AAC1A09660AC1FC7A146E7845AB83390871655E604C4C009EE924AE107B61BC3664F488AC60783A1C346BD18C56CED3F03BC1B1E4075E9785F235EBC5CE6621414E77D52CEC3B2E", + "dk": "657004A34B4EA6B278BDC1BC94A997D86B206F88875A934042732CFAF8B3A0141FDD815F2203BD92AC478A9033126A8478FBB6453AAE005C03F60444163066EE922781D08DFB1508F547555B3027A2F75F28401A7D69A09669AC8309C3D4E4B49B214C4C76B3E4C26CED4940A325885C71883881B6C18C57BF22CB4484674A738988708FB7EC68855A96EF033B4A877038612B7B14BB3DCA791DC5CC7C85614A694D0672CB5656CA51C7B3CE11ABE1F4B790800FE7F47F97D640141702B147A3A6D99279B258CAE7899C353A66F6AF3C53C4A632BEB545B65A2724EF06CD05978E3EE20BF264A0335B21FC2137C71161A8A3AAA1A6AFABD023F58C0C393630E41561568C6669C2683B0B493A60A42889A178ACC3289BB135C891D89698C38AAE187C6E3DB16335FA61BF70C6D496B5251BCEFA9A1C95980E3810C0059C62E8838F1B0B46B4C5A2FEA19E790B2EB4C8C3A164C8BF5C89C2812E982B0F3DA0CDE958A26BD03A38C562CC67B2C07509E6742CB44C04320AA87C23C3E3A7506F26AFE94523D1B05280BA53B4ABB8C5717422D071396C6B7733A09B11CE1E6B2280F1C9215913FBA6522F90C009C0988CAAC61721993AE73DD71A551ED8431C1A8D286857455624842C4CFA80B9143CCEBF930AA1E738EFF1A46EFCC0D766B7E4AC39AD508D6CB9891DEB61B0AAC5FB9385E1D0682F786CA37C3DF1A38BDFC1162E975EB604163752CAC6C47E3BD909C53726C6D084188904CA98C743C9B5D700CBE4A809F1756DCF4C65C5A6B7A7F2725595A0C89C26381C218004B1A275701B50586A327652390FB68868CFE8084067ABC53A9A2CECC72BC625CA7751EC158F35E791008543EB202AE258C588E69E695425B9BA4FE0082ECC530EBFAB41DB23CFA8C2A63AAB11D179C91A712062536C4FF1C205287296B001121436C5F813747350C9AB63CEC0CCF7DAB3E642210517155228910C729BC9B24B138B85ED9A4678B2B4C67A73282842EA66CC458C706BF4A591BBCBBD370E09C937E396B76FE4A3B56B4CF638A5CE055CB63C1275D53B4197493A1A4309A4CCDADC3AD1F47A5E8C5C89235321028EF158094A6385C4E010D6F8CCF1C627BCB3600544B276D2AC9CC91D4BD5AD75DBCC8E7B7A981680212B5A3D395F8AA1CF2B0A23EBB63BDDC5185BE53A6C1410D0D96889A74265E3B34F4477FDF5B680D793F35C7A372B25A1F47C5875B34B80ACA2C25A0DE69D58E71856C55E37A79BC7376898C45BDAD66FD0A554D8F9BD69A525BAA4BF40B0AEFDEC66EA329ACF7B44D33C4FA248734F516BB0A69FF751A3E3D95975DC4E25194CD6F88E7264352628AF45B38A3434951FF99CBAEA812C04C354227431B01CCF2B5955B59BBB5A2BF382227D71631C541AF888232EF733A085AA1D14493C063B64E8BB28E3B7D0686CE8F942EEC58734525DBAC07159627863D97F7C198C50E9AB10E54979C394E90395E6A793C882CBA9D56179B75F11799709577F149CC93EA3A764C610EAE641F8FA2801A22B5686B335117C3C7B3D74986F70384A26A33B323787B7888CF873BE39411829D69D6E2CA2279971AE27660B5224D21015440844C457B6B9F2C50D19580489C63AE0612D423A5CC523B2D908C45907A6694A665195171A5B2FB583A5C240CADCA8F0E83E46B14052C9620D3B7EF386CE8B9A5E873B65693B0D341C6EB2D10CE5E937CFB8C4C9134401BABFEEBBAECF47113A34B9C6E011BDC78A54F2B7BF36A5FFD27563D7443F2109F02A64C421411DDB2D1404A86F793A2DE62CDC560BFD6604D4B6330BA6AA621414E8C12DC71C25652ABAF36B875DE1978DD209AB53B885206C3A1B4F8B4A0670C087CDA9CDA7997437155659255C2D024822A448CE5157CF5B6E4C495A949960886A902C79591120117C4A73CE7B380C661851E1CA9EF1973D8A9D2A191B938C4110259C4227B600BA7EC9B033BB0300715032836573382445435A743CA61E923B18ADEC7CFAF10ADE908E582560EE91ACA012942319B4888109E55AA738A7BCF777C92B4B09A50A1C043C982C2C2357F73C1687B35BD123FC905E1A719353466A42B915DBF1A1750339BF0923419681E4531D97E2160AD896DB056570570510FB711169AF2DE0CBA51C5F5056242965AD429301E7020AE0141F845833A3FBA0B192426C001A7147C2926805CD86725442CADC2636BB769DCDE46D1BD12D30F4695593B5753870EF796FB2F3A53F283D5828B77CB75D5DE1BA25357C290A957FD501AEE0AE59D7AE97833B0BB640F781A08BD256C79117C220BDD83280A0069B29A645720096D297A2E5245439268C0ED01F75A939978372B9E05D93DA899C10BF6CDB18698C46EBE00BF90730E2EA393014461DEC6C87F17B2EE16C13B8507C6009BEE074F17367A5FC3067A28B7D804C32860EDE650E6FE85CF6E301D1B1647323199CA296ABC54D2811507572B5DFF92B54E3786D130938417624775D8534B0102B6B8006803DDB376EB830D1CA80E717BB7F260A5CA4A56BFC5DA790151725942AE7C42B2B9E385B4E0F995D4402161070B73A6BB0CDB77EF11B1286D75E315635E719088DC7909D026B198AC93BB4B6FE395843A4428F75C0C1448C605A8CABA0B8CD19CE465764B523628B3334E3885D68D5089E1A3045840C36A73AEFE7B93AB357FD8A46D7547A8EFB243E4953E67CA72CFA0B77835768AA0CD2D976820A97BC21C7033084AD45C0BF6B483ACA8A485641EB55A47BE36ABCEB96143BA90C515D5BE8513BB994CFA88FF4B3600E34C1E656877606B6280384A0F481458044C47732FA9B58195A5DFB48636E1558C56A43CB6941DEE5AEB1E27B89A7121BE166879B62BC01619A9ABE840CC678E028E9BC71CE233FD9DB8816294D71F1A080101912920534750DDE692F782BAC4D4481A0900E6BB952ADA798EE06232C200F57F76A914617914B7398A0433CD7A11B5AC09789034F39338CE567E3E7AEFE35B0C3B85D21506E8886587670761AF9BAD3261DAF22CBFC664604234B3B784EA001CC6702B9222545CFDB2965EB54678780EE3C9CC134CD2E655908D6BDF460BEE364C66D5ACCF4B492ADE9A0F3EB31995BADDE4628B67165FF6014D848541035CDA46949EC1C12FF492726A7214D1C7273FB85D5484E5A178751B56E3FB163D13A53C7B3038E09B847A8C06FF9B42E8C345CC95AAC1A09660AC1FC7A146E7845AB83390871655E604C4C009EE924AE107B61BC3664F488AC60783A1C346BD18C56CED3F03BC1B1E4075E9785F235EBC5CE6621414E77D52CEC3B2EBBA283F4C993A010081E2CC571D97234472CC9858D199CF0D6E6B9BD720C2665DF0F282411F4A071489A8F618E2AE5AEF40131CAC5233D6D731522720C2FEB1C" + }, + { + "tcId": 28, + "deferred": false, + "z": "5AA6DC620A6E9A60CF19A7B4F0FF805BDA8219522A548EE5857C3FF6060C7A2F", + "d": "092271D05CA63C60880AF404D60BC4BB9539E2EA12969581898D56E0AC9A5A68", + "ek": "E1F90F4586A2A7444812451655F63852C48D2745BCC5D95C15552CA7355A216B1B5131656A95453A854DA8291046A05D96E74CC4507D31973D9606171D8405F211AC5040658411A3997CA061C3AD30EC2AE6CC79CD4C9AB1D1CB47996F02E42BD8819F62457CA5CB9923C570FC749531C61AEF02642576A04E88493AB084AFB353FC0B032AE8AEA812373A323268200FA820C88E1881F0A0CED7D9601DF56C891AC2CF6B299C553C6B1C8A470B68CFF347C2A071B26557F185B4E2138B421A9BB6DAB8FB41C5459644F08614E63C8C4BACC3DF5AB7F86C44E48239EF387217C9540DFB50002C08ED9CB631755446786D4B5BC14D16C5EF629CE2916687C40053A2CD50667CBB590F7D3A2AFD54AECBD6211C84739AB75B80A38E9F27B6D6F1BD4C838BB2706E5DA65B95498CFA61AB90169A2C06B0E79CBAE0051683221C98DA365A27C1DE417666ACCA178717934258207A51DFFA0C926B6E3DA5B084F07560D949AD615724C306EF1165A5B9616FBA84C7D71C1117BBF8296722012EFE25B29C63291D31758278430CD90E844764AC252F33135CD2137115933B38F4160FD482CBD9265C27AC3B6582FC201DEB7A52D23AA5B77BCE9B7C6D699655105B9883830D0171882612212272261A0CC9DDCBC7D3439FF3A01B0BD4B63972263D919BCC9B95018114A11BABECEA27A5BCA3DB896AA49543CC50BC07039D31135BE1354B6A2B6B4375513010CAE856B7AEF64BCE20912432C09FD18905200249D4CC250306C341CB837A96F2B67422B63C29FB8887A962A1F743F3D01795D34E277343E7577878F5A3EC02728E9238D56B2115F680AFC70BBB361B60C10FF7F4094FE240089577D59969907B9192097CC05516A7132C2477435C8BC01909B4AAE5537CA2C6AC79806B6B5F32FB688C609200F16279D9CA987B68EA83A6D6309F1230562196BA93767DF126C98E4C3A3A0BB969629BCCDCB428A333D2B96E50B814716A5479192DCC0C0E4B194AED6A169E5074EF977F689528C997C1B99B02E1B18794B56993743456214064F80CCDA66B71BC009772784AF04FB7F468E2E93E03C18778D13C72FA149C50C1C9F45167A53E09657B50BA2A19B31FA95C5C6550B14F9B931EB51C37890C95157DF4F974E3A167DC005481F945D23780B5498AC5AB80DD8ACCF2D1322D3253B9450EDA3C3B365C9EDC4A87D089AF7797B01BE716917842A4E99CE04C86A9F172062C473C203A328C10DF171FB10C97BA6B8E71271D705110C810843D658B15F2040B385B067B1CE160A4205CBD57B74926143609979F6A888EBBECB7703498A278AE963223A8AA41916A3D37D949A3E298F01CCD36A5B6E0BA9CFF38BB890AB18869B4FB7CA8C1711798CAAB2EAC01ABA26A060266A6A91BA877603E650F7D15C24F9B23C52A9C74F43150E3A1D5D25BD0326724A42572C32944DA713457CB36B14E30F72761480035423810D83721A97505668F11EB26285A1709321A1C8016DB8BB085996D1A4880BD3B1D8BF2754F3781D57BBDE68297AF710188486EB6D4AF7DE411D36787E4D945E33C45CDE051601243A1F7028AD52B3B5C7728F35DD5F8994D4B8D9FA767611A1ADEE8B38C5A7A0AA795D0A970C749A06DCE6CF1C8ED19D1F7E9F1F25538877CCEC133881C652489A84F948041", + "dk": "4967CD2CABA6E5B9C671732DA64B59450440532BBC0372C570341637B81346646971834CCB116C49C562D485982B3C602D723B721A8EF9A35CA6CB045F8A09AB9A176C55801901C2924874D65573F5C0B3F97C1DB4821AC3B23F7621BEBBFC4D1F924E9E0762F037904707128ED964B8B2C42B3B1BA7D101BB8C1A36E1040ADA4CBAFC2BFFAA9D12C69C01F3C65E3676C948C18C273F9EB34EB0C00682A285E6B8A514D1AEE73AB93423C187C57C286801A9AB79F2F7100FB08E03A24AB26625D972C1350B951064A0C2122179CB11914C284BB092DA4A044E2C457807CED5662D0DC23F8D8A951C9766AFFB11D3B3669826736A278FA44386CCD5519F3A04A87B0C9D693D0E505EB889CBC90785635CC08FEB4362E3B48134474B43771BAB84A9933BE0988834CB149A5C3724BB17FDA374D5B57F5260C8E60C37F440A8B3DCB5DC94B946495C025CA1258C7CA7AB56B3765C1EE0ADFD854E617AB40E26922EC667FCEB3192D01DF3D37A484239BA427823302440AA439580074D666DB14C1D1F0C9E5203822394988553C8A0925E04F5AA8B9942E6C9B0C6A942CE569F3987CFED7B7E7DE388AC6BBB7CE4C9FBB6C5D15531A558573431C6B398044F989EE581B95793279F0AB97F4355D9C566B231998C9C046C871A59C11A99B2271CA7364ED5C5A6FCC0EF27A7C147C829C69E09D01CEBDAB91F163C68EB18D382A1A081889281414DCB456CD6C2031C382771073B5621C7B60DC4B0A294C8AA62C5CDF68BB6B46692196198C1EB2FC9528B33A0B829CB9B809C010A3054230188DDFA60013375DC1C6A967146D1B77362A448E4FA97C3B72C2AF5C9A4193290630AB400CA5830024888AADB52A9D4894B5AA03322946062D523018131645B825D5BB8DCE285DF2977B96C02977BC889737C78C2A3DCC5666B652C6E8C24141516DD8520DFE84E5129AA6BF55BB1EC79C3771B029A3B91F9701677C854E4105D5A485F8CB6A5C29CB2F47A4A60281F8B1FC8BC150122B08296B45F97C58CEB743B42000720CBBE5022B7143D3E177023ACA482988135197237706C26A94B35E20DE3CC0C53CA9626F2615E4B8D581BC2656AA72A0AB9242670E6322A89489C97177E3EA1AB9C24338AA35FA272C76893053A76051F4A88DE1944FBB0AFC8E904CD1033E7DC0D0ED029A7531EB612C7B46775FDC09B54C483F6B06ED16427F50421B6F59C06FB0AE4F120C54644DD287CE3119E440AAA8E0A611AB9B52DB1B445036E2CF15BB8DC72CEF50DC3788BD85832D0C18B2685659F8A8BD55144A4EC9764109288B21113E4089E598BBA1453041C9717AB25BA5239FC54638B5A20247B9BB755A360E16F83246CA2D024CBD4BC8E966C2F102C6C02CEAABA0F92874179C8777F937D9A3CB74920BEFE6A759CC94DA0A3ADE2D739D43A99E1F06A0D6A41AAC076CA70171BD697F1CB16A3B481EABB2269B57D36599F3B734BCECAABF6D5835E365DF0261C5C11B8B5314E08EB209A8938B9AA6566E159E2472D97553972DAC5B83292EA350AE358C60FA7773B5C1AF64891C72643CBF8085176A05CB47577E50FA6D42E96C5A465E05C7DB75BE4262A7AA58090585A62363B6C989B8274C426802DE1F90F4586A2A7444812451655F63852C48D2745BCC5D95C15552CA7355A216B1B5131656A95453A854DA8291046A05D96E74CC4507D31973D9606171D8405F211AC5040658411A3997CA061C3AD30EC2AE6CC79CD4C9AB1D1CB47996F02E42BD8819F62457CA5CB9923C570FC749531C61AEF02642576A04E88493AB084AFB353FC0B032AE8AEA812373A323268200FA820C88E1881F0A0CED7D9601DF56C891AC2CF6B299C553C6B1C8A470B68CFF347C2A071B26557F185B4E2138B421A9BB6DAB8FB41C5459644F08614E63C8C4BACC3DF5AB7F86C44E48239EF387217C9540DFB50002C08ED9CB631755446786D4B5BC14D16C5EF629CE2916687C40053A2CD50667CBB590F7D3A2AFD54AECBD6211C84739AB75B80A38E9F27B6D6F1BD4C838BB2706E5DA65B95498CFA61AB90169A2C06B0E79CBAE0051683221C98DA365A27C1DE417666ACCA178717934258207A51DFFA0C926B6E3DA5B084F07560D949AD615724C306EF1165A5B9616FBA84C7D71C1117BBF8296722012EFE25B29C63291D31758278430CD90E844764AC252F33135CD2137115933B38F4160FD482CBD9265C27AC3B6582FC201DEB7A52D23AA5B77BCE9B7C6D699655105B9883830D0171882612212272261A0CC9DDCBC7D3439FF3A01B0BD4B63972263D919BCC9B95018114A11BABECEA27A5BCA3DB896AA49543CC50BC07039D31135BE1354B6A2B6B4375513010CAE856B7AEF64BCE20912432C09FD18905200249D4CC250306C341CB837A96F2B67422B63C29FB8887A962A1F743F3D01795D34E277343E7577878F5A3EC02728E9238D56B2115F680AFC70BBB361B60C10FF7F4094FE240089577D59969907B9192097CC05516A7132C2477435C8BC01909B4AAE5537CA2C6AC79806B6B5F32FB688C609200F16279D9CA987B68EA83A6D6309F1230562196BA93767DF126C98E4C3A3A0BB969629BCCDCB428A333D2B96E50B814716A5479192DCC0C0E4B194AED6A169E5074EF977F689528C997C1B99B02E1B18794B56993743456214064F80CCDA66B71BC009772784AF04FB7F468E2E93E03C18778D13C72FA149C50C1C9F45167A53E09657B50BA2A19B31FA95C5C6550B14F9B931EB51C37890C95157DF4F974E3A167DC005481F945D23780B5498AC5AB80DD8ACCF2D1322D3253B9450EDA3C3B365C9EDC4A87D089AF7797B01BE716917842A4E99CE04C86A9F172062C473C203A328C10DF171FB10C97BA6B8E71271D705110C810843D658B15F2040B385B067B1CE160A4205CBD57B74926143609979F6A888EBBECB7703498A278AE963223A8AA41916A3D37D949A3E298F01CCD36A5B6E0BA9CFF38BB890AB18869B4FB7CA8C1711798CAAB2EAC01ABA26A060266A6A91BA877603E650F7D15C24F9B23C52A9C74F43150E3A1D5D25BD0326724A42572C32944DA713457CB36B14E30F72761480035423810D83721A97505668F11EB26285A1709321A1C8016DB8BB085996D1A4880BD3B1D8BF2754F3781D57BBDE68297AF710188486EB6D4AF7DE411D36787E4D945E33C45CDE051601243A1F7028AD52B3B5C7728F35DD5F8994D4B8D9FA767611A1ADEE8B38C5A7A0AA795D0A970C749A06DCE6CF1C8ED19D1F7E9F1F25538877CCEC133881C652489A84F94804166E5248CD311286D6DD03E010391D90D76044BF498B53C9D8202A9EB643527395AA6DC620A6E9A60CF19A7B4F0FF805BDA8219522A548EE5857C3FF6060C7A2F" + }, + { + "tcId": 29, + "deferred": false, + "z": "7CF50F7237A97072F03F31CFD59FA8E863BCA3AF7375E0CA698FF665661C24CF", + "d": "BBF7574CF5F32BE49E1F39CE33870D9D6384056D60D223003B6B0C10D5C42180", + "ek": "602389F7CA3437B9197677CB9E9704A2BB73A7815EC1047D8D63A55CE1184EFBBBA3F701CB0C3D0D18B757BA23C6023B4D34964B66107C92C5E0AA577FB93F31FB9A73786E63E7CA4DA84215F6B05A883C19F8B0D0326025A41A98D056B70A18E6E6469EC63C80BA0B7EE330B89314838883BFA75F2C6155BAA1922FD446235CA76A634EF715776D3AA3728482C5F69931DA1FA0A406D75756D025C08DAA28EB2A226AC56988F68B54E3205C1B341528374B9B9BF07BA42BAAC34219597FDC66156155DED5A7C3F386103BB0EDA1CB1D4258CE1A971447075CAC2AF538A96F1C570014341624607A3C36BB4771DC99916EACCC04268D25DB95DC20B041B394FAB543118B74536187EA32BA1680B006652AEFFA9338FA00BC099846419630D38CE7D726C5CC84CEB9C154E9B309B6A99BC142CBD6B210408455704A3A644ABF7768E6E87B54734C1CD0C139B2292C612DDAD0AAFB239CDAB80629B91AD9585DA88A84857249E68595C0564F2A07735A76C1CAE64D28D14A191A9F0CFB709E216AF6CCC0654AC206B722A2E84BE8A0C13BA359BB1B741F191F076A7B27849D2DC146CD8456FB165157A2ADF2A45FC5647FD5213E8A105084138CF29A583A0B5BFEB0A523798085F2AC8A44745BD556D7C0959EC319563077F5D5137E8B7E9743115D390BFFB91DADDB0DA4A21433B963A15933FAE236A537837CD056F4145EEB7872E8153E0BA9702C7A20598481C630206EC359C5145BF123A18054AF7D6851B59707B010A0BC322D3E3CB0F0BBA619C0CCB5239A5D7B021007211024868DF03B4729578F029EA7DB1CE62C15F1843C16469AD144C805B5C217FB18CFC49CBEB80BDB9CCACCB181153C377997C509B6606DB808F04911FCC4CF1902035DC3016F64498C13AF1BA2C240C6567E5520FDF79A5A04634439641DD2672BA04B11931CCDD3629D860B9EC767C3AA4C9E09BE25A7752B64087B0A973E6B3278E66E89F4BCCBF3090A729467A88FA0AB1A6805C7ED45678E71BA79A85F267771E456B2D56627AD66C7CB07B8D73A69A2682C79B1C13986C07FC7986C7C3C84EA4B6A6C1691675912B2064E3598C32573B6B87E67B006E2F312F15A5AF4E237345468756390DB585514302A80746E985A104C43BA019C5DDA678047C6A48CA36A51CB3A333767BC35CA31B59CCD64A2C59AC884A8B1FB396FCD42C63057663E8A1F809709AE89AC805277E1151B92DB4F0E52923BBC093B7C6D15621D2BEC2C8DB77F25F86A62646C54C114BA03CC6154397127A033D402248383FAA8BD1980C93E123B57075633B6B643941B417890B1AA810C88461E60413264612B890FA83115D22041243C47263B57CB32BD84D839B9CB96E3777E2DC616D8ECCD1BB21D4AB00C83D4B4298A671CCC1FDDFC3E4DBAB48F1B8045D3991B3952D4799B7E1C3D31B74F9B619BF17016D143B16E593F64C08A71078C83B197BD530063D026367993E8C35305D211C2E321ACC889FC6917F70A33EC2AC4D7FA448A79A89B531BE89A59CDB8212E7715144721613619ABA2CC7E53A3D3F84908C09B26320FA3C1CC9D840F21851139236C7CECBB8B3C2681DC145AACC13B4BBB15560793364387A0CFC97C0312351F420A0892084CACAFEA4241305B12C78DF29F2FC5FFEE800216C1DDF275", + "dk": "7BAC37F9C7AC728C78DE12B13C0A2C1B522A837416529A93273A4A14007BADC7BBFAF03EB90A7CE4E8B87B70986806C9DDC9BFFAD06D51C081E8866E7624A373E87E8BE1A60A861650346296F8B89C7A0EC713CA9A0B9BBDBA370104A414C02DE8445B9F4314D4902EBB400226A827DFC6603812178786BB1D6A9CFD048A45B4A160333D73E344497BC526D262EB73AA9D3456375A9F237B004B2414171C6BE0F02A97E83B1F8C411FE350D9B51D42D11BB7A34F8C59AFAD18722B17B21C5253389A98B2A96E5BD798AD10AF6F27950F64638080C7F0284545BA6E2BD93BB141CA924966735C7383631EEBEBC1BFEA7160FC60C143C9359A43C3A03429D663196B723CD35FF4C465B356A77A7C5FA9408E91E08BB6F141F1A9B93B4452843873F5958AC7AB9C8A660BEE218598D09652F921E8980449A8087857B129B02A38FC664F0C21B4E95E3B400AF4B30EAF649B9C968C0AA5B2FF8781F8D01534FA5FCECA771B2A2ADD27710DB25402E94F66D37D52780E25E4317FF80F0C682641301015D7900A312C9643B336AC53C94889342B09138689E8BBA191700791197B0F804BD834064CB3446C9382E6839F25087F5DFC1C741B91A8FAA87E529E375A0CA9B424C429BBF0B6CC7027123EC211A9A5622611536290A0E30A50CBC567D08245B54224133923AE399EEE6454E858352333164510A8A510289F56B073ABAF82F5986BC52778A86253BB96E357AB4F78A7C3159DAD184B8B540BE1DB861FA1951C0C59526305FF005D741B2A312B586D75B72A6B31DE68A07DE4CFF0490A85009442390FB5F45F70F5AE3E286B20C35F55DC39DF6C7CFD992A3203718A58C2D849CFA78C4F9FB20D68E8A7B35065D3DA738F01C6986600677325AD146816137221E3C47B9376A3669CCB23A533A85B1028865BB4A99361486E789C0C42C3D36831D5E86278B48B2EF8042FAA2491B413FDD9AAC2493F44686A649BA866D30F887580857B7159161D1D009920033F9EEA92E37267CA936D0823A8CA195458731DBE45B25F46584268787D664FB7587AF4B67291255C66157CE7646B2F4B5015D75D5332C9E95470F52A9D8EB5438A390BD7254924D46C583A7892D53D42E9406E0A6063121A03F0A550F4AE2E8042D962A3AB69B223C37071F1BDD2BB1639D34041D1BFC2576B268ACDA311A5E0222DDFBC5D67A77EA0C37C90B474317195D567351280AB0E5840A3F60EA9C5162A706550877430F6882A68006A683A90B38F26C90D3FCC780C0CC7E6E88FEA5A02D912A1C485667F88AB329552A93837858235E98044A28A24E1F71435E09DE2AC2744BA2E116A136E95AED53BB906BB46FA214E218A815966214F581C1134545DD05EE4E9495AD172CB2BB199D79328E06A45A42A4EF37443EC6F57631D0959B84A1B169297A0F2DC16B13B1C43567C043237AB18BD53A8898F6ABCB0F8A012E2CE203649C4286C6D3C41346599E953B6899712D4B86BFC4B54A89B061E93B423793CDD798E6E5A1BFFD565245788B0BA6A0FA3BDD97960C9CB0A10DA892D829925FA4F85CC8FF895500933BB78B3993CC04006819FC93224D19A02E11651E5D3AB3CFA6DC1C206F6516A5CD5108D18B47960A6602389F7CA3437B9197677CB9E9704A2BB73A7815EC1047D8D63A55CE1184EFBBBA3F701CB0C3D0D18B757BA23C6023B4D34964B66107C92C5E0AA577FB93F31FB9A73786E63E7CA4DA84215F6B05A883C19F8B0D0326025A41A98D056B70A18E6E6469EC63C80BA0B7EE330B89314838883BFA75F2C6155BAA1922FD446235CA76A634EF715776D3AA3728482C5F69931DA1FA0A406D75756D025C08DAA28EB2A226AC56988F68B54E3205C1B341528374B9B9BF07BA42BAAC34219597FDC66156155DED5A7C3F386103BB0EDA1CB1D4258CE1A971447075CAC2AF538A96F1C570014341624607A3C36BB4771DC99916EACCC04268D25DB95DC20B041B394FAB543118B74536187EA32BA1680B006652AEFFA9338FA00BC099846419630D38CE7D726C5CC84CEB9C154E9B309B6A99BC142CBD6B210408455704A3A644ABF7768E6E87B54734C1CD0C139B2292C612DDAD0AAFB239CDAB80629B91AD9585DA88A84857249E68595C0564F2A07735A76C1CAE64D28D14A191A9F0CFB709E216AF6CCC0654AC206B722A2E84BE8A0C13BA359BB1B741F191F076A7B27849D2DC146CD8456FB165157A2ADF2A45FC5647FD5213E8A105084138CF29A583A0B5BFEB0A523798085F2AC8A44745BD556D7C0959EC319563077F5D5137E8B7E9743115D390BFFB91DADDB0DA4A21433B963A15933FAE236A537837CD056F4145EEB7872E8153E0BA9702C7A20598481C630206EC359C5145BF123A18054AF7D6851B59707B010A0BC322D3E3CB0F0BBA619C0CCB5239A5D7B021007211024868DF03B4729578F029EA7DB1CE62C15F1843C16469AD144C805B5C217FB18CFC49CBEB80BDB9CCACCB181153C377997C509B6606DB808F04911FCC4CF1902035DC3016F64498C13AF1BA2C240C6567E5520FDF79A5A04634439641DD2672BA04B11931CCDD3629D860B9EC767C3AA4C9E09BE25A7752B64087B0A973E6B3278E66E89F4BCCBF3090A729467A88FA0AB1A6805C7ED45678E71BA79A85F267771E456B2D56627AD66C7CB07B8D73A69A2682C79B1C13986C07FC7986C7C3C84EA4B6A6C1691675912B2064E3598C32573B6B87E67B006E2F312F15A5AF4E237345468756390DB585514302A80746E985A104C43BA019C5DDA678047C6A48CA36A51CB3A333767BC35CA31B59CCD64A2C59AC884A8B1FB396FCD42C63057663E8A1F809709AE89AC805277E1151B92DB4F0E52923BBC093B7C6D15621D2BEC2C8DB77F25F86A62646C54C114BA03CC6154397127A033D402248383FAA8BD1980C93E123B57075633B6B643941B417890B1AA810C88461E60413264612B890FA83115D22041243C47263B57CB32BD84D839B9CB96E3777E2DC616D8ECCD1BB21D4AB00C83D4B4298A671CCC1FDDFC3E4DBAB48F1B8045D3991B3952D4799B7E1C3D31B74F9B619BF17016D143B16E593F64C08A71078C83B197BD530063D026367993E8C35305D211C2E321ACC889FC6917F70A33EC2AC4D7FA448A79A89B531BE89A59CDB8212E7715144721613619ABA2CC7E53A3D3F84908C09B26320FA3C1CC9D840F21851139236C7CECBB8B3C2681DC145AACC13B4BBB15560793364387A0CFC97C0312351F420A0892084CACAFEA4241305B12C78DF29F2FC5FFEE800216C1DDF275A918B39F71BBB2C10DB35639E5FD2CE621868CC02149E029EB47899407D963007CF50F7237A97072F03F31CFD59FA8E863BCA3AF7375E0CA698FF665661C24CF" + }, + { + "tcId": 30, + "deferred": false, + "z": "C593627807074684B7D363441F80F6A3D185D67878702D33A4E0BDA2000F857D", + "d": "D12CD9B65B7C58B2195AE0BE0282527BAC06C2D25CB0472628D64715F7F6A378", + "ek": "C85428E8EA5D6D1C7E544703372498F68311C32BBC70B86F2A805FC94089A0421AD680053D5BB139EB95652ABA561B07B9C2639AC693972070F351A3FB6138FEE0A73BF63161B604D7DC0334D6C631BA25F584952045C6CB74A31581B866EB5FB69503A5E3C6F96652547968626CC9C6ACCFE9582778E928235305CC5447661A64363A9FB3CB3720868812B2A3F5E7820DDAA8BC799566773BB62B769A8C54E6B533803A48D877706303A76BA2188EA4900155728DF29E7AF050F8CA9F92B65ED59988496419070B0CD8E964B402491D134F59EB2E3995C1B3B654EA7A5628C677858208A7958C57C7CCC697677BC65091015AF9D6C688E234DEB528608A1AAF35C2CB2A14593376E1417098778439D9BD6EB31BC0B53F277BC6763794CFEB8766957F6B206D439BCDCE4466BE20B74F7A117D7102F4A2CC93B098795146CD2903D131315EB41E0DDBA6B562B8341753DBA98D1ED288D8F33148814847981C735600AF76BFD0B964521A8B3122B3B90BA8228B1C4C834C808550D7780BB33218F155752DD15713F5A32057C42313A6FF5BABD6AAA1F6F5460C774CB83C6EC16C84D4A5B8EF728E58E8B34D7C090692B73DB64BB02AC365800915D78A9452158FA210C99B608DA053F574AFFAF1A49AAA92B3058468346D9D5A6DA97A9269B4713AE17A214921AE76A90EFC5A4AE90147E154A562C1C96598DF670EEED86EB946C9B45460C63A1339BCBE23B4332A32C02A028A892478070624D35C950AC84ED7D1B5640A70A3A45BB47C39EC181F7C8039929003D4D674DE3C5C89B0678CF3B125C864E95439C20AAABD015AA52BB3C27316188A673785CF2C0C77CAAC7604439A69B46005EC646C37C510FA835CBB36C162AB7C944F8228A4FF32340C3C63FFA3CBC48C7E01D35A6DD010E211C21175171237067A614CBCF7B18CF98ED0E8B88B58555D871564B0B71B75B5D078428EE87E0379A23822BC34C00A5661602C4006BF5CA667780E81F1759CD63E6BE63CC6C07ECF44C2E11346E376733D185A281C8648A9B951E14308D7A55A0717BB5C9C3CD5C7D88636873453D6148E674093A406860028AB50FAC90349C5BBFC2A7B6A18E24655DE541356990BA1C7C465630475176A03D58059F26700CBC383A0750F5271B8D5BDD74468E98C189FE302A5A452D2E47340C2B04A0275B47229B2022198F14E674071C6568EB428B0C0748CAA0A2F8BC28FD27862687B452989B034072B69381CF73BA00F7B7C401C699BE466593918EA96C79A3980023B299595179065198F93C6D6456DD53B586E6079340952C1314A140605DD34126291396AD22F2C7820A4AC793768707E071772EA587FFB9AEB234ED7A250DB40A1DD7A3869104864392B6DFA23013C8CF8856EC8E30C0AAA748351284F67A0E3469D3CF7C28A85BAA2630907B70F7C31870E8A29DC7B908CA880BC03C3CD2CC7A57A9D48A238667776B6D9C77247ABEA49B0F6935AA9446F0F2CADCC7A809B651DB55131A7B662CE428EF89109BB33C4E423B05781C42BFB4514092D35BA6D8E77B71F6627C9D91EB3672E656A00EF64CA7551667882444DA47FEE440B0E59755FB33039FACF337CC572D7CBACD680CB882ABEB86D9A3937FF76EFAF15E6AD37597C50B3153DC8B18625508393935D2FBD49D32ECF", + "dk": "9FC4A82AB21F667A50692A482D59A06FF2620ACCAB62394DEDC7AA452761F38A5A499C8091498FD7A5910C1A14324685B9307236CC0773D98B36EB2136708DAEB21F8D4B713CA5456A02C1C8EC012514AE3FF6476D1C3D8D47638AB79AB83433B6592E2F1690BED646C0519EAD1CC58779786B384618604B1AD1340E178FD97A8B3EE4B009A5BA115CBC3832B92ADBA22BBA7823976683B8A4469A3BDEDB8FEF5C3582A5984CEB2CBF5A57C96B246D05BA21F08B8582CDB5632DFFB404C320A004E878E31B877C07B38B7A12142A5628D2BA4CA6680C9B9A6CF18B3B4673962533D7C503A24C0A91EC9E1F75219E573DF630724393A18A61178623224B9C4892F6A41657175D296634474F1C3BBD76E05B9C5788B9857655D142BBD8137F047A4927B923163493FB31EA5C151A4719ABD61634F8A8856A968C7538E2641D5B79CDC78971ADE70AF4F85B09770EA4E05642CBCF02F095A9149DD266809DE0911A5481CA22176BC9B0C5A7066A00434B15AFFF5C532E1042BDA52D425CA202A599D96A92D58B7B40F8A76EA34C6B45B76E6C07FA9CA20B3587DED93E94160AB0412697DAC2591530620242A9B41F37B11CE1347075271091B78EAC2221DD735DEED8189C0029099526E9DA24F234BBB423C590CC44C675AF125B021951576F5953CBD45B8F6326CA9399D3127EB430AA31F2C5154768A7E440F63738419834F41AB4A149278DE5882506085943BB6D19088FC11525973ED9132238A350F201479D9469CBB46117E7B74C0298B5E785F27384A4984452868BF5056D9A966D844ACD946073AE275D7F82C4583C08AE33499CC53D4437C3EF967F6C904B75F503330C4B19981B28CA8F26CB9F5604081B8706E657CB8E9431466CA0EBF1B71828A3238578BC2B38620C3416E84B3058174716A312C205ACFC481871588C37263B6839768C5CA575CF15058C52F39379B79D814788C19034EA17BE4969255EE767578B0B6B347FA9A52D199891B9976A7345B93C659CBD7814F5F300900581674BAB7D03585E802C8AEA7CAD748F5065039788B76813C7F991A642C44EB1F151C6A3BD96C4331F2C01EEC46A3A1BC30555BA7F2C9316F4CC7D18C9CB73962A71CD0EF32B121393041684CFE692D4834FD0B25CB0A04531E656706A7D593AA1D0FC56FA304CCA3B5BB3233E7B141B6AD1C448C35268C99815E451C2B821F034CEEBD748A72625F61B610E478099F6CCCD39BA2A050611894D5524257D9A06D3BA2BE2AC70EDE8717BF593FC159F8433CA0C54420453610DF451C4736512702A95B2B0FA5AB1B4CC3FA74B974A1354F8B2BEE35187BF049D0A8772BCC85443B04303051415324523DC1FD494268E172383F7570D366570DAC588A73FCE3104921B325E45A87BE798683A6C2D0C90A869BB2B4BBC332B7687C81A287853F7C06F596271F5596FDE93BEBA027977C788F472C114C889BA4C4D3F39C7A05A34E57A8D5C4C10A19C3A3BAB1711FBA07854824305AE9D46A6DD11331656C4267C20B511B6672C0CBBCB2D5B67973239B116035BF38C9BED8186762201CE295A5473A825C6210B70A70CC5C5E235384908104278AFE955628D80B43F13BE383A42BDEA6D05EA7CC85428E8EA5D6D1C7E544703372498F68311C32BBC70B86F2A805FC94089A0421AD680053D5BB139EB95652ABA561B07B9C2639AC693972070F351A3FB6138FEE0A73BF63161B604D7DC0334D6C631BA25F584952045C6CB74A31581B866EB5FB69503A5E3C6F96652547968626CC9C6ACCFE9582778E928235305CC5447661A64363A9FB3CB3720868812B2A3F5E7820DDAA8BC799566773BB62B769A8C54E6B533803A48D877706303A76BA2188EA4900155728DF29E7AF050F8CA9F92B65ED59988496419070B0CD8E964B402491D134F59EB2E3995C1B3B654EA7A5628C677858208A7958C57C7CCC697677BC65091015AF9D6C688E234DEB528608A1AAF35C2CB2A14593376E1417098778439D9BD6EB31BC0B53F277BC6763794CFEB8766957F6B206D439BCDCE4466BE20B74F7A117D7102F4A2CC93B098795146CD2903D131315EB41E0DDBA6B562B8341753DBA98D1ED288D8F33148814847981C735600AF76BFD0B964521A8B3122B3B90BA8228B1C4C834C808550D7780BB33218F155752DD15713F5A32057C42313A6FF5BABD6AAA1F6F5460C774CB83C6EC16C84D4A5B8EF728E58E8B34D7C090692B73DB64BB02AC365800915D78A9452158FA210C99B608DA053F574AFFAF1A49AAA92B3058468346D9D5A6DA97A9269B4713AE17A214921AE76A90EFC5A4AE90147E154A562C1C96598DF670EEED86EB946C9B45460C63A1339BCBE23B4332A32C02A028A892478070624D35C950AC84ED7D1B5640A70A3A45BB47C39EC181F7C8039929003D4D674DE3C5C89B0678CF3B125C864E95439C20AAABD015AA52BB3C27316188A673785CF2C0C77CAAC7604439A69B46005EC646C37C510FA835CBB36C162AB7C944F8228A4FF32340C3C63FFA3CBC48C7E01D35A6DD010E211C21175171237067A614CBCF7B18CF98ED0E8B88B58555D871564B0B71B75B5D078428EE87E0379A23822BC34C00A5661602C4006BF5CA667780E81F1759CD63E6BE63CC6C07ECF44C2E11346E376733D185A281C8648A9B951E14308D7A55A0717BB5C9C3CD5C7D88636873453D6148E674093A406860028AB50FAC90349C5BBFC2A7B6A18E24655DE541356990BA1C7C465630475176A03D58059F26700CBC383A0750F5271B8D5BDD74468E98C189FE302A5A452D2E47340C2B04A0275B47229B2022198F14E674071C6568EB428B0C0748CAA0A2F8BC28FD27862687B452989B034072B69381CF73BA00F7B7C401C699BE466593918EA96C79A3980023B299595179065198F93C6D6456DD53B586E6079340952C1314A140605DD34126291396AD22F2C7820A4AC793768707E071772EA587FFB9AEB234ED7A250DB40A1DD7A3869104864392B6DFA23013C8CF8856EC8E30C0AAA748351284F67A0E3469D3CF7C28A85BAA2630907B70F7C31870E8A29DC7B908CA880BC03C3CD2CC7A57A9D48A238667776B6D9C77247ABEA49B0F6935AA9446F0F2CADCC7A809B651DB55131A7B662CE428EF89109BB33C4E423B05781C42BFB4514092D35BA6D8E77B71F6627C9D91EB3672E656A00EF64CA7551667882444DA47FEE440B0E59755FB33039FACF337CC572D7CBACD680CB882ABEB86D9A3937FF76EFAF15E6AD37597C50B3153DC8B18625508393935D2FBD49D32ECFC86A41EFD315191F24D2E6BDD87433D5133D6734FBEAA9DA8043D91950000048C593627807074684B7D363441F80F6A3D185D67878702D33A4E0BDA2000F857D" + }, + { + "tcId": 31, + "deferred": false, + "z": "E01702E1228F530AC96DB053A415BE97749A109A1FD4057BA128649B17EC07AD", + "d": "79C006D5470C229AFCE7588546E52204B09F5086974865B426AAAA198C6CBA7A", + "ek": "52764F398C4AED89848544114193553BB178FBFCA4883C76BE23363B3343F69C8AF0B59F7C0482A64985B50A6EEA5C700CE7BF31DAC43B82372405638010A320E2A28FE6321C0AB85BFA8723DB96E8D1508900996B27812507885C97A1E7C581E35915D0709C9CFB2BC713B305705406C522D0305F5BE51EB3272524A797ECC2AB5330538BCCA62CD51937330849138620032917ACC188E8B70DE56B43E812EF030C0B4C062B1437AAE13A355AA9B41B00EDF4151F2C964FD332F3014BEB990E19C2350050735C7B02C0936B6BD37CA18114854750E32A6790515E1B4A31B2B71F9DE4082C225679CB220522BA6235B89F2C8E231BCFC815B9EBB15534D5B352566942A742AB405194AA74B90B26B98B669DA43FEC232FCF351FA5C50F812057E44858096395CE67AEE48382063A7928CB4904D623C56974FAFBA18519BAB743168510700F715E07EB331050C4160A6AA024C126027D11C324A87BA13C3CB10E86B2212343BD0088382769B9494F769918DA7C8EED21896C75711AA34B0E3BA8527371271AAEA05C906C5CAF6B5A6A08C4998492323E04CD5E63B1857A4FA972BF8B430036A856A5F9183C4B652A9311F1901AE3A4A93D302C4E77282B04046F7AC2DF2333C21B343ADB75C369A5385B9CC70280858971716A0587B74492637DECC8130EC8418954763E39AE47BBB084103225C21F64D94F14D55B9BD2579C5BB03EE4915016C2CA416806CCCD56061F92C0B1EAEA50DBA36B76798F7B8AA8AFF2CC06B04BC3106F22845DC5D847B5D444F05803CBF062DE581E12163094A5C7131A24B9327DAFF9134F32B647D9CA52A65A91A4899D64100F3376E0D318C7B8188BFA88654AC370EB5D693C4D9D481CAA98A2C99C168A0306261165410B32A53BBBBA412B54702476101C6550C286D6615AA98D8FD95ECD88BF45CA383DB3C6239AC7AC16606877751311CE8B447D0F6B9499943706B5A46F291A57302FA4F3ACD4645DBB515868371FD79887636737E333C9B06285508832401107089176E06A2F17E19E4FF61623603E17367D33F023C2CC820961A6E3500092CA3B900BAD66C179249C75A5E08A5563BE1CE312ECDC0AD370518F66594314CF5C8BCA20948D54C70F800542BD5B64ACC9AB68FC90F48662CFFC8F801C06DE972571E8C25EBA7128E95C13011EF88240C2C9C0BA555AA1C70956C9621A600F2817435C09C75F8A08CEF2C5D31C5C5834A745249CEB7641E6B19E404865EB374507DB3394A77A0F47149896AF1C747F86C97201D8C1CC8209E571B8C4D6972ECB1CA930B15516922FF08BF0C942AB5C5D197669AF94457FC9BA5BB47DDBD3A34EE941943B0B262A63FD0922D803CA035C6C54DB71B5A5A76F46C787036BEF777296E80664F73A78175EF7DB567BDB6CD8D97D27649661C76216D99D6264A7EB274C507AA170E1C3F23CA00A04B861AAA29EC33D4584B12985AC3B36689F129F3D29B19DAA5DCE4150162A10FA835E1D89A21FE10E4B1489E457C415961648044774C49DE6908201068D13463F1A999D3103342F03020F043DF3CC2E897B8293D235E8B408F2BAB266CCB0FCE19F6779A9C7DC89E368B07BF56F29911593E78009358CEA0BA304C0C074FC86A0782F99BC38571CD1632770CBEA199AF4181984FD05FF371931", + "dk": "B9C74FBF945530C8B3F846A803ABA28337B79D4B282B127D727A145BD77C19D980ACF4A5B20A09D770BC96F9A32EC16ECC208126D0C755C334BFE36E0AA3B968D0BD9EB80FA4953C9B843AABC828BB044DE62AC903D655C5960F45A4133CEA1AE6C4A09D431B43B19511631483E457C9108D7F3AB090203F712BA759602FED0A68BB7C8B10DB592DC38606978C56198B7F3062A200B03FE281FF95A27ED48C630CC1699423F5C6A07F850F2280101178CA24C282A7455FAC19869B207C46540AA0E4628246777CEB02B24ABC1BFA02326B846D7A20A7E642116B97AE68219AC53712A0077E325B4677AD163A38A6B8754DA8957C52B6CA5905C43131467B86F2CB1B94891A88B79058D6C6D8DCBB2C167156DC81C59B60F66C16938935DCA2BBB80084484B1F11330B5010C2F6C5AADF352D2E5421BD5B8A77758B72A058A0A6074B3C08A9A2B0EFB7261CE38219542CA7759FABFAA924721D7EC8C11EB62976EAB8202AAF0BC082370A47735B0931CAB5D6A92F8A67184DC906856946004B991394C7F1F1B84A4C0BF3F249B73747732AC3F04C5FD94B33FFD8250AE4739FA04233B6C381F69A3B0AC7E0003613329FEF9A63F033CDD09137BE13BA7EF42F36342A1C215A5FF4AA76D044C0AAB7ACD7064BB064C9B66BD7E2C398404AF7164FD0169BC8DB926BF63DD0E2433C7C17854A7E538722E74118CACA4621A532B2FC8DD0E204DBD01B8B3C7AD1A5BC78E78E8C1265BDACB7C78A62A3E10EB7BC3E7FD25ED8827C23428E3A198CB4821B0EEA62C9154F6D305D00BD7BCA42A1BD488AC4412D39B1573ED978EB912CAB796A594C5E9AE6AE7C94C76BE61DD47354163A7E4063B8A592C91A8A6B34451AD400672603C60DDB26F1B0587BE2065362006372081C1A52110774EE4A0231842AC6E7B4345B47C6A5C42D3C2C951014A7B753A90345B0692C8A73A82D8B01589C3CEEC8ABA357931E18026604576141ABE253CA18C356757A9D0BD49C1FC1CD90364D7430B061DCAB362257F80405D35184282C8861613D6EAC28F1360B1888192B25719D7A3ADE28AB76FBAEC4DC35DE5B5CACD64A66A39824993F2FF7783CB339319998AA102369F43E841666CB41CF0D39B998267356DCAC4F0933E5E56CBD920FC56AC33BA82E80FB13C6C64932C65EC4C66E903859C4F20D1AB5825FA8322CDB41F4341811D7663A6397363212DED05DA0D76EB5308D32F4442A488665DA80F54ACD37C406FD44AAA56CB31781AD393171DD539727C6582594BFA278BD2729A9150B916A8CAE861153DEC3493E18277A766019CB556882266521536EF030BCA36115753E08762142B33C5E34A9E80716C57A03BB362F9334AC44744EBA711AD8F44C2EBC151976C49F179D24B53C30615BB42CBE8CE069714A9447D939DCBC128126C1F9AB35C222386D894B6ED50A580B3ED13ACAA18C8D49F5A5826A9D1B6530100702E2C9993C3AC5C9286AF6324EC9B8323C032884B344EAC49F21D76323DA9FCB324E8DD7AFCEE162AC14BB427C0197C4AB9AE490434586EA76AD9AA042A060973F301F5E9BC91072B61FBC27033C52DD160D424CCA566558242C9E4B145C7B5630AC825ED5B932A00381C5C94752764F398C4AED89848544114193553BB178FBFCA4883C76BE23363B3343F69C8AF0B59F7C0482A64985B50A6EEA5C700CE7BF31DAC43B82372405638010A320E2A28FE6321C0AB85BFA8723DB96E8D1508900996B27812507885C97A1E7C581E35915D0709C9CFB2BC713B305705406C522D0305F5BE51EB3272524A797ECC2AB5330538BCCA62CD51937330849138620032917ACC188E8B70DE56B43E812EF030C0B4C062B1437AAE13A355AA9B41B00EDF4151F2C964FD332F3014BEB990E19C2350050735C7B02C0936B6BD37CA18114854750E32A6790515E1B4A31B2B71F9DE4082C225679CB220522BA6235B89F2C8E231BCFC815B9EBB15534D5B352566942A742AB405194AA74B90B26B98B669DA43FEC232FCF351FA5C50F812057E44858096395CE67AEE48382063A7928CB4904D623C56974FAFBA18519BAB743168510700F715E07EB331050C4160A6AA024C126027D11C324A87BA13C3CB10E86B2212343BD0088382769B9494F769918DA7C8EED21896C75711AA34B0E3BA8527371271AAEA05C906C5CAF6B5A6A08C4998492323E04CD5E63B1857A4FA972BF8B430036A856A5F9183C4B652A9311F1901AE3A4A93D302C4E77282B04046F7AC2DF2333C21B343ADB75C369A5385B9CC70280858971716A0587B74492637DECC8130EC8418954763E39AE47BBB084103225C21F64D94F14D55B9BD2579C5BB03EE4915016C2CA416806CCCD56061F92C0B1EAEA50DBA36B76798F7B8AA8AFF2CC06B04BC3106F22845DC5D847B5D444F05803CBF062DE581E12163094A5C7131A24B9327DAFF9134F32B647D9CA52A65A91A4899D64100F3376E0D318C7B8188BFA88654AC370EB5D693C4D9D481CAA98A2C99C168A0306261165410B32A53BBBBA412B54702476101C6550C286D6615AA98D8FD95ECD88BF45CA383DB3C6239AC7AC16606877751311CE8B447D0F6B9499943706B5A46F291A57302FA4F3ACD4645DBB515868371FD79887636737E333C9B06285508832401107089176E06A2F17E19E4FF61623603E17367D33F023C2CC820961A6E3500092CA3B900BAD66C179249C75A5E08A5563BE1CE312ECDC0AD370518F66594314CF5C8BCA20948D54C70F800542BD5B64ACC9AB68FC90F48662CFFC8F801C06DE972571E8C25EBA7128E95C13011EF88240C2C9C0BA555AA1C70956C9621A600F2817435C09C75F8A08CEF2C5D31C5C5834A745249CEB7641E6B19E404865EB374507DB3394A77A0F47149896AF1C747F86C97201D8C1CC8209E571B8C4D6972ECB1CA930B15516922FF08BF0C942AB5C5D197669AF94457FC9BA5BB47DDBD3A34EE941943B0B262A63FD0922D803CA035C6C54DB71B5A5A76F46C787036BEF777296E80664F73A78175EF7DB567BDB6CD8D97D27649661C76216D99D6264A7EB274C507AA170E1C3F23CA00A04B861AAA29EC33D4584B12985AC3B36689F129F3D29B19DAA5DCE4150162A10FA835E1D89A21FE10E4B1489E457C415961648044774C49DE6908201068D13463F1A999D3103342F03020F043DF3CC2E897B8293D235E8B408F2BAB266CCB0FCE19F6779A9C7DC89E368B07BF56F29911593E78009358CEA0BA304C0C074FC86A0782F99BC38571CD1632770CBEA199AF4181984FD05FF37193132F434783F38ED277382AA17ACF5FEC87E72BEF729A63E69AF7387E9CC5BB339E01702E1228F530AC96DB053A415BE97749A109A1FD4057BA128649B17EC07AD" + }, + { + "tcId": 32, + "deferred": false, + "z": "AE51639EF7F26FD2215AD11CBE1EDEB3B943D668EEEFEE13ED5B0DA3E0A5F3ED", + "d": "B04F631B330D83991B5C01E7F69452DFC394F9689632F8C7F60DBFAB92A9CEA5", + "ek": "662293FE760B0826256FA788B6A061039229502B6887527553496F09937F25C86D0762232C5A9C3CF9CE9AC7C43412295A180DAEF55C01053F71242257610F9F2AC7AD80A220991BA632B4DF1CCB43865C7469BB54A24A12D759943921B62563A1665F864C710B947C629B6AC169A05FEBA11DC87BA54420D35C9FBB364CBE5449E7B53A48B6361CF417CBB825AF93CB61D987442C500FF147B8703D6600CBC6789A83119C51D460EE759638D5302DB28B62A1950F6C63311917A51BAE092756D8DA55DDFA066E544FB7C71BD6D512D258CCB0B6B19B6693BEC15BDDD3706FEC949FD2B5AC81327A3349B62475F642927440C757266F8736B995C996DAE6685FDB89285377A38384EED54622052D197098E5D30C74D65F24B8C1F479A78037CD1936868801A7E688B9E8BB5BE333BA48540DE80AC9B12912F017961DF81CD02700CA6B30ED19325C7A507C5C1004652568F6240A060FF0316E1554168C5190DD32895B389580BCB7A1F5712EC3192B601A7FBC7F3EC9A3CA6106BD99B2800CB7E332CFB3824539801D87545711D6ABE408BE2963AA4AEBB76C9814B7808559831CFB84CB9DAA80104C51532B4867C731B53766932453E7058C23B27E7D63CF303ACD0D9A2F69B4A7B07360456A8EAA14C5142824DE66565335B589B01AE667C9CCF79EB5251A11305CF2349A8C9681A17B415F5190B602A5753B917F693B61A04B96D8C4B5AACD873B1B900B940F3C25E568C8293A679E2020C7B88F162B641891C9263116ED94C5A726078325955825CD697440729087C4D67F0CB126395C1E19824BAB9A1A1AABCC8D570CCA3BB4FF1B6F416A6E239926768657BE34B154129982006DD6B5048B2CC06679C27F070D7746870A976F1699802A61882B65B7D66736574C2A4065352F06C056703295291968237850FAAD14D56EAC4816AE5CA72BC59E04AB07FF4185B29B9B4A19970A81ABAA505FB6F4A3C1E632B2421EEA069EA40C450E3AC2435428A18C412F209509D83C69717963C62748C130E5D1CEC8A924F1E81BA852B3780B38B44AC17B3B70F4694E550B497F9A5DD740A2A7651085261A7840B52D3C95D2AAA899160A6AF7289127606A85233044B6F72C2261F3C2B89946053BA91C6120EDA024C70435B8917C1C2413324A179BE34EBA570C4C0762A8490CB76B021C2978B6237A792973EB994DF4714F230374D20C89C2E5A58E777075CC83EADB309EFA73ECF34771205B3B67C2BC848444A247D4F857D8C6679306AABAA3BD2D4A22E9B7B889574A68168B659B8F2C19560EA178BFDCC509996E8A992B2FBCBB6703478F6C3D6E3020AE0086DFE2408D56468AF66722123D6654C7BB1B246C35B9AC8C2CFDB35370D19C9FF173CD999BFC3BBCDAD053B00C941F8173D2621AEC1571DA391654FC50B9F99E51F26C5313B85E73506A0CA7D156012A63C51D228005B26FFB6427D8C279E9BC6A520ABDB38981D04A2B7ED5311F023572D57A01E3BCE0375A51FA5408C193AA80BBA033A20750C2A09521DD94B7F023271EF2A561089E170531DA641CFF4525233B93FCCA87617C685E00D0CB1317C540B770514A97279C04119436F872DE43A96747856339064794801FD00460DA5663ECDDC739C783608FA59F2E27E4AB3DEEC74061C16465780B59E4DC86", + "dk": "74996BF2C7B505FB4AB2E64D9AB83F5169CA5B062CE625184B0315D2B79945D04C818259E454099C55BE3A262B57C31EDA5B4F095169A09A8DBCA39DE41057E3CA126E4781D0503FFDDC89D24B28C3BA4BC5E9437C83A3EB8497E2956D30FCCB29AB0393EB1C1A0B7D2AE177EAF705E69A5B88726839516B096BAE87BB4FFC394FBB86967300AADB340E83CC9BDBC9830171088363BD1080A976EB9FD9A6B92C5273BD09073B8848936C8F1486AF320CA39EA592559A12B191432413C1C4977FD6DB5BB12B0DE877AB4CD63155690C31DB93B5EBBDF29B2A7E642C382478C9794AA5787B7A50CCB9850BF199798DB18861179E6020CC2FAC59925A0B6F775FB219726135237CCB90E321906314B8EAD933D7C53024733DCF076312F358EAD020A88B586DE53AF798C3A87178058207ED806AB4FBB349B953E7C13E6D2122A7C50B1EAC96803C7414DA65020A7ED62A91975BA6EE7174BE62695CA3A7AEC723CA701483B95DEED68A82DB95CE175B0F94A0160332DBE4575DB085215A9A520878FA76C6D3968A8DD9B38EF48738451417B3C835DA8B4F393ABFCA7DA6560278890C2BA8547BD71815043759B5A802130E8957398AE30BCE688CFB3B71E2A77068C88A3C42989735A180B64144817E8AE04A4DB010A3AA4FE24CC0AFC25C89266295532F4BFB89087008F7B265161410B6A72ABECA6B30921A8FF39AED231369D39D8781A7691933F12473B56683FB49CEC4A939BC221C11C11CA904647A7C2F77DBAD979080CBBB624C005488F6211CE7B9B2227A91F04749C2776E399377124FC7BAAC11215E6B75A7725417D049A94AD809711C1B78631DD7D24ED6720458914649F8B5FB6A30E3F97EDD116987655900278EC3A60C278A5132007C91416EA4AA3694A87D481B2EEB40674277783E391D5EE54110787622451D62F922A721C010921F570A095FFC00B8002DE9AC71EA7486A0DACC5CD0727DA19DAE03C9E0C6438CBA0B08F69590C83D6284C2092C2A98CA6405F9B19DEB5C52F7B5F91CB7B653688C633120FC82BB76A8A52AC0D5E68E74009F8E655A2057642A6004FAB653D6C79DFBDC3941E59921D8850399810A881BE80C974929CE9781074D50094D0A469D716B47FA72F2A3A4772A469A31284E91CFE5854F5016CF2747118280276582020D1472EAA3BED0AC192981098EC7524ABB1410A392439A7D9BF940EA19BF3E76BE94D856D5EB3F5D91A917C8886D561BA027AB7E166FDC12CFDA12C7B06AA552BC27E7B67BEE1C19E0612DA58C8CBF0A8EB2B03818D8158BFB1C09268AAB73C1D424C354C8557AC3556D3A944D203276187032771E4C668CDD1145DBF3B00393AAA19447C1FBBF5EE48DE7F07215F85D648A59B3D6602F69ADF57205DC57371CA84C1CFA4D69E32D065CA04A1BC5FFCC1FD215AE3B91936DFAB4EF9591AB18093F36CC6CF36ACC204CE517B9EE9B746E79C5D2E005F96768CB508E7FC96DD38338915C17C95C1BE072CD46A59A3D36887EC80C7B022D3A56C4E495AF71E8A40F2944AF9439241024C6496CD85942AB17359229AB2BB54A0D61301DB560F15263B0196525A2AF546C8EE2CA18F212AC8356AC4B2CB2E3FC7F9A414776A24C662293FE760B0826256FA788B6A061039229502B6887527553496F09937F25C86D0762232C5A9C3CF9CE9AC7C43412295A180DAEF55C01053F71242257610F9F2AC7AD80A220991BA632B4DF1CCB43865C7469BB54A24A12D759943921B62563A1665F864C710B947C629B6AC169A05FEBA11DC87BA54420D35C9FBB364CBE5449E7B53A48B6361CF417CBB825AF93CB61D987442C500FF147B8703D6600CBC6789A83119C51D460EE759638D5302DB28B62A1950F6C63311917A51BAE092756D8DA55DDFA066E544FB7C71BD6D512D258CCB0B6B19B6693BEC15BDDD3706FEC949FD2B5AC81327A3349B62475F642927440C757266F8736B995C996DAE6685FDB89285377A38384EED54622052D197098E5D30C74D65F24B8C1F479A78037CD1936868801A7E688B9E8BB5BE333BA48540DE80AC9B12912F017961DF81CD02700CA6B30ED19325C7A507C5C1004652568F6240A060FF0316E1554168C5190DD32895B389580BCB7A1F5712EC3192B601A7FBC7F3EC9A3CA6106BD99B2800CB7E332CFB3824539801D87545711D6ABE408BE2963AA4AEBB76C9814B7808559831CFB84CB9DAA80104C51532B4867C731B53766932453E7058C23B27E7D63CF303ACD0D9A2F69B4A7B07360456A8EAA14C5142824DE66565335B589B01AE667C9CCF79EB5251A11305CF2349A8C9681A17B415F5190B602A5753B917F693B61A04B96D8C4B5AACD873B1B900B940F3C25E568C8293A679E2020C7B88F162B641891C9263116ED94C5A726078325955825CD697440729087C4D67F0CB126395C1E19824BAB9A1A1AABCC8D570CCA3BB4FF1B6F416A6E239926768657BE34B154129982006DD6B5048B2CC06679C27F070D7746870A976F1699802A61882B65B7D66736574C2A4065352F06C056703295291968237850FAAD14D56EAC4816AE5CA72BC59E04AB07FF4185B29B9B4A19970A81ABAA505FB6F4A3C1E632B2421EEA069EA40C450E3AC2435428A18C412F209509D83C69717963C62748C130E5D1CEC8A924F1E81BA852B3780B38B44AC17B3B70F4694E550B497F9A5DD740A2A7651085261A7840B52D3C95D2AAA899160A6AF7289127606A85233044B6F72C2261F3C2B89946053BA91C6120EDA024C70435B8917C1C2413324A179BE34EBA570C4C0762A8490CB76B021C2978B6237A792973EB994DF4714F230374D20C89C2E5A58E777075CC83EADB309EFA73ECF34771205B3B67C2BC848444A247D4F857D8C6679306AABAA3BD2D4A22E9B7B889574A68168B659B8F2C19560EA178BFDCC509996E8A992B2FBCBB6703478F6C3D6E3020AE0086DFE2408D56468AF66722123D6654C7BB1B246C35B9AC8C2CFDB35370D19C9FF173CD999BFC3BBCDAD053B00C941F8173D2621AEC1571DA391654FC50B9F99E51F26C5313B85E73506A0CA7D156012A63C51D228005B26FFB6427D8C279E9BC6A520ABDB38981D04A2B7ED5311F023572D57A01E3BCE0375A51FA5408C193AA80BBA033A20750C2A09521DD94B7F023271EF2A561089E170531DA641CFF4525233B93FCCA87617C685E00D0CB1317C540B770514A97279C04119436F872DE43A96747856339064794801FD00460DA5663ECDDC739C783608FA59F2E27E4AB3DEEC74061C16465780B59E4DC8644132D7CEA4F7CB9B06AA59C4213FA6293563C4516CF033491742C389AF38643AE51639EF7F26FD2215AD11CBE1EDEB3B943D668EEEFEE13ED5B0DA3E0A5F3ED" + }, + { + "tcId": 33, + "deferred": false, + "z": "6F9FF5654FDA78774498E2643E935D21412CEB49BC393532C80C47A982418F66", + "d": "3D63BD6C310AFCF684292E5F8E1B98CC75B5A27B21526268444144AB24AB2967", + "ek": "FF22387C34AC69033FB8CB685DF308A47B6A8C9978A152A7003B583DEB864C3C26432780D56785BB511EB2507E40BA80100A1E4FEA67A2290F26F75AAF655827E95C1624A127795D88F34927989594D228F1497CF998BBCF012ECF6156FDC63870EC49E38C29C6C35ACB89B031419A0BD835425A255400B05167758F56474D8B83466738383320E22514C69203AFF561DB2B1596C937EEB49044817949B726FDA5B46D6980F9099B17E6BBC4272F4185739A687E8171BA53497E26BBB215163FE18448F1D005E6827C2177CFA0A3CC516B48F3D1BA1484C33169963F071E13C20BEF371DD4013B1D5B0608C0C0C52241AEEB42F81B5D6BC09A6627C6846AC962328A54DA2573CB4A4D71C729A4AEC7411EACD1053B71B8D932C3AA6A759198B26516843B9C344E1A1874AA22EA88353E7C6C410121026CC75DEBA8C5E3083D83BCA0A4C3EBA5C653021AF25C6251FA486CD19AAB6A6458FA6D29C02A7FE6CB2192553193AB92857AB1141458916653432A71FA4667FAB3CD1A602AAA7294148B17C2B82F86900FF55EB4CC0A8A14940982496F417809956874077A4F256448F2B661FB0163C687CE8B08EFE14C1F4279CAF8BE239338535836FE5B12C1A8A4A9EA2BAAB732F3E36262AB028BB30EB88B7042297BF92B22757A0AB0A817DF03707892043DEB2FD8963FB369A8C76A8FFA17237EDB8CC0450B2E9726491A36FFC2B58E7C9CA803517FAC9C047C4CB056B0316C3CAB239FFAC13315A3675BE2B042938C079844F72601CB6A8353205211304DE0229A249148BA13C7E969CA28E95183863AB3F838EFA3BF9159CE989358FC1A69BE3C764C87A4FB8B1739510E7211617806ABF4C19FC48C6112F3C67AD92C342A40B7F5468A559563B2C2BBB7869B221959526B22032059F093BF3287FD652CF51C7A4233C17DE638E8C92EDB41C77ADC5ADA927BDB12A7EE2B00CB2577A6937C0EBA364F9093E8E94AA334545D1797071A85EE0BC9037B352CDA8D2D874E16B344E02894635A3B5380CDCB6674951C0399B10062429593573D39A06817E84F7D517332F92903C7CFF7651D7F1C37F648C22A872CC007BCF33A4E991CBD34069CCC6771B9582D83136F52790E74A24CC86C439AB7C5FF1088CCCB81FACAB6E1D0092D14A05DDC999AE4C006899D6FA6186940925BCB614DF83C5C95555358894A5A4ED2B1A8D8C7AF8B5C63CC917B849B4B544995635845B2F50BCADB9E25BA6AE2C10458D2C1358430A8EB27884B8EE27B6408265CD24C59F9B7B3E0CAA48D744BE36A3906F488C432634D88123A981B79A54C50237275262A5AB111FB51AFE1847C9E284A91733DE5F38C6D39A51987CDD368CB3E136D92A312F515A243F999C04495DD7B3EBB3CA1B82B3647935C77951672BC9520092D203AAD318852F93866E6F6494E695F4C7A97D035956C68B3A56C5A51298F1CB0997528376DD5CBCB5B15AA19A1A5B77B98F1355210543A0C0366F5328B2A49647021CC3246F1856847C637AF4B390B521B890C346CE5B4E3F1A51A874BA7DB1D2D8B8356BB0EDF48C9EA01177E801BFEDAB6444B4B911549BBEA1230FA6183949862A06954B04F4C9192B9EBCBA8151E20D48FA3CA8943F13734D9C4E642A7A7DD2BF360600ABD6E84E29BBA27F96C191480EB71CA68", + "dk": "33D925297A649E979A40147093E74DFFD1749917C75E088AB9800AAAD81ABEEB293FF88634706904220E90490D968C097E33A2925C251904871E78975E564606617D0228227DFC3613CA0BD6F1B6402476AFB25BC4D0AE47A2A401C95C721A04D0536E42DA76244908E8D0769D5524B1A96FC9548A7C7A2C6BAB0B081618F2C19ABC358A1DD18D96AACBAF943A4CC6A7FC316FC629A25346B82B42A746A9C4D27C951D363AC0669AB3D6368D619F17EA93DC2401DF36BDA6835DB6EB02DD211AC6927B918071DEFAB2B9F671DE554E727875746475EB886286A165749504B5919A39BBC4536C8154E5B7A9D3076E0A1F068B2C8305595ED2A1469321A7476D107273221C6C5C9A2224D4AE615991D67869674B3A5994255470BE7383C1FF636AD276B7B810794B3885C1788BDA26256DE13F8AC1179C3614ED27B0A7F220DC22425BB7B8B1A8AE2CA6057CA5BEB447042A43CC82543D43F6134E9C5DE6D52388AB9D4C746202EC759781B4AB0C684B4B270570B23078195D4233A71A451E196131EB8AF598BE86B1511DC2C85CB50D001150CA2A7A3692C7E2CA09C03A243B5B0176E9BEBD629B5F4CB599D15FCAE7A7D7F44566E0A4571740864633FACBAD195AADCDFBA9B322AFEF119436B96624AB410F764083395FCB4C81FE6616CA80CFFCD6A4CB9B35BD8557D0AC2A61AA1042B414AFB0020EE1006E593DF29A625E010C15F7A5DFBA4FE459060F90882EC91AF77181C3E32FB027AD397B8CDBF52D397654CF68B2335A3A75EC24C87852B846BC9FD07FD9D767396A5511402A1993C9AD9138FF800C6B6051A6B94DD2BB457E9883F2954980715706B07A15A186CA57A5F0F83A2CFA01D22C5AD79176C9AABCFC481B67989648000DAE714D49E6C5D9E0396339BA1C22216084BAA7B403DD998F0B9600BCF419698A2CC853CD145156FCB0C193928CC32631A2B3954AABCA05D43E1E4C2A3EE34815C8A0095102E8487A82397D2283562B19A5D88993AEF77B57886B1129B9F442986461A33293AD5B41AAFB25A8D8DC48F128B67B07C047B1CB52603082E422425059A585A7B84BC948D6B7FCA6A9E7BC17B44251343202EC892D2DB09F6EECB9483A03640C4C56B32A5B8AA44D847703C988B1C02FC02C7BCFA7642AA7C1B67B539708743517444D470F273A112EC87FB7145789744F5037095EB88015932EC4B3CE62A4314B97935CDC2F252CB839442D800816CD6AA0FEC81251F6CAF6C4A1E1A9C7CEDA798135639311ACDEC014E4BA0335A9919501C42A729E6E9556AB9BA1A1EC7D96E225159886F7C67F520305436864C9A70FE7272315A7CEEFFA6F39AA8FFEA3CEDBC8CEAB1318A64335C1C5530FFC89C0CC1D6F7905C5809E61363719F54FE7E8844D382BCA679554D368D3976206289B1A4BB987A6AD72B59CA2BC2D91A61902144065B762CDA31255119C9E19C579F4CD2A7620BCE0546565C0C82A35001900E614C62D2B7856142349B25E32CBAF0634BEB9D2B603B67019AC8FECEA9F5144782EE47E2EF823E9E646A253ADA9B8B809435C33F890B0D80A565C7FB5A19E5DCAA39E4983FC149BDC1B8477B808A5FC6379C7018134C73FA197F1E87E7443373D108AFF22387C34AC69033FB8CB685DF308A47B6A8C9978A152A7003B583DEB864C3C26432780D56785BB511EB2507E40BA80100A1E4FEA67A2290F26F75AAF655827E95C1624A127795D88F34927989594D228F1497CF998BBCF012ECF6156FDC63870EC49E38C29C6C35ACB89B031419A0BD835425A255400B05167758F56474D8B83466738383320E22514C69203AFF561DB2B1596C937EEB49044817949B726FDA5B46D6980F9099B17E6BBC4272F4185739A687E8171BA53497E26BBB215163FE18448F1D005E6827C2177CFA0A3CC516B48F3D1BA1484C33169963F071E13C20BEF371DD4013B1D5B0608C0C0C52241AEEB42F81B5D6BC09A6627C6846AC962328A54DA2573CB4A4D71C729A4AEC7411EACD1053B71B8D932C3AA6A759198B26516843B9C344E1A1874AA22EA88353E7C6C410121026CC75DEBA8C5E3083D83BCA0A4C3EBA5C653021AF25C6251FA486CD19AAB6A6458FA6D29C02A7FE6CB2192553193AB92857AB1141458916653432A71FA4667FAB3CD1A602AAA7294148B17C2B82F86900FF55EB4CC0A8A14940982496F417809956874077A4F256448F2B661FB0163C687CE8B08EFE14C1F4279CAF8BE239338535836FE5B12C1A8A4A9EA2BAAB732F3E36262AB028BB30EB88B7042297BF92B22757A0AB0A817DF03707892043DEB2FD8963FB369A8C76A8FFA17237EDB8CC0450B2E9726491A36FFC2B58E7C9CA803517FAC9C047C4CB056B0316C3CAB239FFAC13315A3675BE2B042938C079844F72601CB6A8353205211304DE0229A249148BA13C7E969CA28E95183863AB3F838EFA3BF9159CE989358FC1A69BE3C764C87A4FB8B1739510E7211617806ABF4C19FC48C6112F3C67AD92C342A40B7F5468A559563B2C2BBB7869B221959526B22032059F093BF3287FD652CF51C7A4233C17DE638E8C92EDB41C77ADC5ADA927BDB12A7EE2B00CB2577A6937C0EBA364F9093E8E94AA334545D1797071A85EE0BC9037B352CDA8D2D874E16B344E02894635A3B5380CDCB6674951C0399B10062429593573D39A06817E84F7D517332F92903C7CFF7651D7F1C37F648C22A872CC007BCF33A4E991CBD34069CCC6771B9582D83136F52790E74A24CC86C439AB7C5FF1088CCCB81FACAB6E1D0092D14A05DDC999AE4C006899D6FA6186940925BCB614DF83C5C95555358894A5A4ED2B1A8D8C7AF8B5C63CC917B849B4B544995635845B2F50BCADB9E25BA6AE2C10458D2C1358430A8EB27884B8EE27B6408265CD24C59F9B7B3E0CAA48D744BE36A3906F488C432634D88123A981B79A54C50237275262A5AB111FB51AFE1847C9E284A91733DE5F38C6D39A51987CDD368CB3E136D92A312F515A243F999C04495DD7B3EBB3CA1B82B3647935C77951672BC9520092D203AAD318852F93866E6F6494E695F4C7A97D035956C68B3A56C5A51298F1CB0997528376DD5CBCB5B15AA19A1A5B77B98F1355210543A0C0366F5328B2A49647021CC3246F1856847C637AF4B390B521B890C346CE5B4E3F1A51A874BA7DB1D2D8B8356BB0EDF48C9EA01177E801BFEDAB6444B4B911549BBEA1230FA6183949862A06954B04F4C9192B9EBCBA8151E20D48FA3CA8943F13734D9C4E642A7A7DD2BF360600ABD6E84E29BBA27F96C191480EB71CA68D4F2A9B485FFC544CD3DF67D23C80150AAF7A45CD946F4B7DB2B67F4F8B222536F9FF5654FDA78774498E2643E935D21412CEB49BC393532C80C47A982418F66" + }, + { + "tcId": 34, + "deferred": false, + "z": "D083E6922EF0A818308FD7FE7CF5AD3A96942442BE327B0A307685C2D4315901", + "d": "249D48941ABC01C9290719FB34D91B05E774E70E6F0181E1783F2586E2499536", + "ek": "11709FB3C60AA689CFC149954EE25C7071A4DFD724D0C4CAB2F4B3FF715FC16302ED2BAD6A926443A617AA2B44FE2283A660C0951A0A41C56EBBF5AC1945454B8A878E3C4FEB22C10FF5B0A3C7C177A84EFFD670622479A401A5909399F131909B349799CB116C51BD02778774764EE6B02EA64929311281FB821D074B1385A6A965E71F9A065DB2B78908048AA46118BCF95CFE0BC6F0318B1E3C4C2F895B98613DA1141170680191D896044C40EB4741D2D21E0C506410D9092F821DBDC04839C6C6C73487F9F239DAA0346563433C32B9A1F7254717A456B04F65965C614973DDB5C43B9072A120294021A21275007360940A5B8613C01E703128B9F27B037CBF88049FAAD7A10C2213F39A82510A872C7C2850D3CE5A48CBE5DA4B3547AAA3B8612F64840C00ABBB09BCB4F031EC6C2AC284A35D84796D4B23FA621C9E0CBA6E04632B8BC5D840765168C08F591871986FD44BBD78E56C30AC80E32229A0F57420872528308C52A028B1993A93003A9E40A1B75B6CE4ABB8EDC109C77B3D2A80B21F1827904C94666AB80AC9702CA78963F36510CC7CCC6AAC6E9489342371933AA4C6329926437A58CB8BD5CB64929929FE9707A13805B621A95803C7EC68A83676578C039C8F273B12C8A2C1853D3AC6169CE95364F791F7A6986EF765C5F0829FA888C8DB3FFFC3A701E3B4D8246B62B3A4FB637FF532BF152452A824AC25AC24E416CC21667B09055C77C12925E77FA67CCAF2C9602091149A730CD3F627A8613B149A2D3789C19CB6B09E5CB64E42A82628C4BB168A492529680B1BAD2A6F0F7350708030495768DD9C82D6E9812DE35FA90689087B8DF242414752AAD8E15BB3BAAFFA05A1057A8262FBB1749C9A6C4272750134F72682CA753B1E555A60D91B26728EE540132DE67958D3928C3A72CFF02BF92997B0B39F06FAA333F5987713BD113026D327AFA167B040436D9940C9AE7799A4D9CA86278EFFC846FC102625583B42234EA114B75057531A07A4E23C340E04A066F3ABD69AAEC83CAA5A88BF27A0592F5B443223864A341E2F3B21CD0262AC3B89A1E735D6B9001A1C98C12210A8E45E377A8424132A10D317BF02939B6877DEE6AE1D7818C3115076B741C307B805C4860862382D1770678B4006402B93979B2383868BA1901F50776A28978A016C4F95787E8C875F694F94E3116DD60F284158BC283B79C7CE377C3F1197AD3EEB3BDB2C8E0505250E58BA75816A21E171F9A8730FA2CB8CCA44D02902F07B6BCCDB6AF8705A78E6854935299A340E62A12418B6693A0909CE5A8F1349A993E75CC4806DFC045F4C28B4DE8C9AACA04713E62DBBE3AC857B5445D6A5F5C115D5C29318F2BA9FD126F46960DBEB3B3DE53350051980E7CD5DF450087BA97CF36B7A566F0DC1479545BCEA5C950AA4CD4EA324B04036BB6A93D8519C66B12AB2EBC05F849209A603BEC768C96587A33963BAF3A8F5D8309DB35ABBA81423C365371A9DFFA649A726C4A84604F4B893F3E30934D065CCB0383A2058C0E121C3133C7FAA4C3AB4B7321C3EFC7741400004D279C5D76AA512692774D9C319A59320BA18D5C116838C8CE96A43AB562CED703A05357CDC20AD5A2A32211A2949927F642B278E71BF94390BC90A3969017B88B8EB63FF6AC90AC92362", + "dk": "88A386E9E2401A9A264FABA1EA2B6A13B5BEE6207582309D39C43BD37CAF668AC6D1D36E8003B85FC37755441F94E60719E92294A88B4E72170D1992B5382B7FEB489DD93A60383A2D29316B7179B8462346F85662E1C7AC72C86A496CA1635B55B535CD4348D6C97D3F5A74FB60C6ECD77A62B83CCE9BAF0693952C86CCE257AF464033EDD5AFDB07333C2A7FF358B45097A8FD87BD5642B12E1B5EAFD73761BAC07BA748429426C98961AF89771FB709EAE812F9724697B4C970583012C2C4B12C369BDA8EDED8A1AAD2C042CC7F2FB86C74B82521C55FEEC5C1FB5087A3E1B93DC1750133386A491695428F09F0696158659817C66C86AD2BF388E2F74B848941AD5A8D790081D3A63E85683AB65499C0EC41C8FB146664CF3FB9311C3786B1D90DDB54B1390AC902F42B30C29F02C236DC313026772825FA70DFB8572C3BC5B968B143719A5B132620D811AFE27F3F096BE180817E36B3F1F78700F00AC574CD8287A25EE1CDFB844F9224C39ADB10B99044CB7009DC1A67EF397B23F2BB9AF5A0AE6833210728449026EBF20E354C14C856C930D61A07CABCC510042E079415D67F6CFA0E692344F3397D0A381CD3E56DF6398C6730C346502039FCCDCB0389DD97C07F9C22FFE5AF7D22CAF6150A7D7A4D60787A67C3582EC82AE8A62FD3A175F8E27C653CAB2A2C69F1D844B1972110B2AC3163BC119A69E4D628DF2C0C76266599D08BEB6B659176CDD07B1A50699DD92AB3EB2C787F90533C28156B8405CD46C1B6B67BE6399319A4BAC4A93FCB659C819A6EC9A1845F1C791C6915F7A40F3DC578C8E016A0E2703F776310B3BCD487B638671628BA508101800B94AF45AA0C3C49559A46979906A8BCA9A474D0AD63F035E95B918B0297440203E154A676572F21D0815BC45D3E7402E537669FFA65FD903A76219C94D275B71C3B9D69C024A17E4F0284179A5F4E668F981B7F968507FBD52797B19C89941BBCAA117786C202030C33F476656207B7C87CFDA16699842F72C5746D843501D9977F0804FEFC2D603C9BCE710547AC047F94980899BB1E167C26301FC146A6C89081BA492274C3C894936B57F94C12D1C3B47CBA740023A494C90942AE0290782850613DE10F52727CDD2204B106AE37B0BB3F3626DC41A6F0B3CD8646CB99F56F6ED137EF803E4439878C58B2EB280BB8FCB95F7021CCD41D2B1A40D6609830BB5E2401389733104A8077B3683EEAD98FE5EC5AC7679D3A2C6F227484D73B4F9E285E4B7C4F47E9071F637C5F8B713127CF2FE77378E2CFAFD148E433B2DBF74FE0475596051EF55007AEB8A59959C8B683A6B726BFD706C1F3E4A748430C01C893078178E3063F00F797AAE6394FD637AD155221C49C533977CE8014136873942114C54462B8750264248F04165853944B1F744EDA307B62998DFC0C63D5EB9D23DC2589210493A69C0B9820D12282E5689FDAFC1E1EAACBF88551D04B2983C2163C1A5F5CA647FC3288BCB5B543C89765B9203B5803A3006F5666BD73F5A44B60A5BDAB85B7C63556323EF82B45A4CBA06BEB388707873D28CC096651E817215485129154C15173B7A7AA826DF0649C96592C7AC8E1B27872C56CF0D3495CB54111709FB3C60AA689CFC149954EE25C7071A4DFD724D0C4CAB2F4B3FF715FC16302ED2BAD6A926443A617AA2B44FE2283A660C0951A0A41C56EBBF5AC1945454B8A878E3C4FEB22C10FF5B0A3C7C177A84EFFD670622479A401A5909399F131909B349799CB116C51BD02778774764EE6B02EA64929311281FB821D074B1385A6A965E71F9A065DB2B78908048AA46118BCF95CFE0BC6F0318B1E3C4C2F895B98613DA1141170680191D896044C40EB4741D2D21E0C506410D9092F821DBDC04839C6C6C73487F9F239DAA0346563433C32B9A1F7254717A456B04F65965C614973DDB5C43B9072A120294021A21275007360940A5B8613C01E703128B9F27B037CBF88049FAAD7A10C2213F39A82510A872C7C2850D3CE5A48CBE5DA4B3547AAA3B8612F64840C00ABBB09BCB4F031EC6C2AC284A35D84796D4B23FA621C9E0CBA6E04632B8BC5D840765168C08F591871986FD44BBD78E56C30AC80E32229A0F57420872528308C52A028B1993A93003A9E40A1B75B6CE4ABB8EDC109C77B3D2A80B21F1827904C94666AB80AC9702CA78963F36510CC7CCC6AAC6E9489342371933AA4C6329926437A58CB8BD5CB64929929FE9707A13805B621A95803C7EC68A83676578C039C8F273B12C8A2C1853D3AC6169CE95364F791F7A6986EF765C5F0829FA888C8DB3FFFC3A701E3B4D8246B62B3A4FB637FF532BF152452A824AC25AC24E416CC21667B09055C77C12925E77FA67CCAF2C9602091149A730CD3F627A8613B149A2D3789C19CB6B09E5CB64E42A82628C4BB168A492529680B1BAD2A6F0F7350708030495768DD9C82D6E9812DE35FA90689087B8DF242414752AAD8E15BB3BAAFFA05A1057A8262FBB1749C9A6C4272750134F72682CA753B1E555A60D91B26728EE540132DE67958D3928C3A72CFF02BF92997B0B39F06FAA333F5987713BD113026D327AFA167B040436D9940C9AE7799A4D9CA86278EFFC846FC102625583B42234EA114B75057531A07A4E23C340E04A066F3ABD69AAEC83CAA5A88BF27A0592F5B443223864A341E2F3B21CD0262AC3B89A1E735D6B9001A1C98C12210A8E45E377A8424132A10D317BF02939B6877DEE6AE1D7818C3115076B741C307B805C4860862382D1770678B4006402B93979B2383868BA1901F50776A28978A016C4F95787E8C875F694F94E3116DD60F284158BC283B79C7CE377C3F1197AD3EEB3BDB2C8E0505250E58BA75816A21E171F9A8730FA2CB8CCA44D02902F07B6BCCDB6AF8705A78E6854935299A340E62A12418B6693A0909CE5A8F1349A993E75CC4806DFC045F4C28B4DE8C9AACA04713E62DBBE3AC857B5445D6A5F5C115D5C29318F2BA9FD126F46960DBEB3B3DE53350051980E7CD5DF450087BA97CF36B7A566F0DC1479545BCEA5C950AA4CD4EA324B04036BB6A93D8519C66B12AB2EBC05F849209A603BEC768C96587A33963BAF3A8F5D8309DB35ABBA81423C365371A9DFFA649A726C4A84604F4B893F3E30934D065CCB0383A2058C0E121C3133C7FAA4C3AB4B7321C3EFC7741400004D279C5D76AA512692774D9C319A59320BA18D5C116838C8CE96A43AB562CED703A05357CDC20AD5A2A32211A2949927F642B278E71BF94390BC90A3969017B88B8EB63FF6AC90AC923625D0BB5F514CAC167BB2E2B5FE989CE88ED65315BC610D9A5BCC77BA80DFA2FF1D083E6922EF0A818308FD7FE7CF5AD3A96942442BE327B0A307685C2D4315901" + }, + { + "tcId": 35, + "deferred": false, + "z": "A20ABA8A8DDC212DE825BE0D3BE57701A6B5B3A46A300D9B5945F579A59AFABE", + "d": "E1CFB8195877B2D4FF3363BAC3B4E7BEBA6DC3CBB789B1B24215393F6C9BBFAE", + "ek": "B749934F35347C7251B0359B6582502BABBEB5574F30C63568139B1CD854BE96B8A6F09069460205BA245182334F669E93F8C7D867945C3B75BF1CA810108E0F670249A62B9E6910D793C7F0A24BD3C40839D713F880B4EC6AA8AD8ACF6EB03E12FC5B1BF61ED2480A9CF68E30A441E3102611D25E9925503E704DA69393152A759DB92175E0343560B961759370BBAB159320EFA846E4A316CF8035D8EC991FC4529055A5C7F76F6FC5423AA041CC4691352A44E6E91E54DC129B000C0829C069C1538EAB1E5BEB58BF0733B64A17C5D159ED31AD4B15B36664465B6548CD4060B487C0C76890DF4B4EEC5705DE97BF47712C667023E627480A4533A9258162050F401CACD75232CF7621BB3B00F76A1CE2B42E65A91E65306F6C019C3F0C1E00FD2192E703EE5592A41C95E8263F53B16E54A952D72078A1589FCDD7BCEAB03A41D89E1D9071DB88C344F65C8D6714C367AF7C5287D6B68EA319A7DBE97F7604AFA67A27BA136C2B996B6A1C4647A8B56CB8C0D6A4BC9B33079D5B407522195ECB9FC23C778B27ABBFF026A8CB84ECB66AFDA43D40558990931736D32EC4937629FCCD01D7B14A1241D2ECB7929C443AAC703553C63D7C8410A891986C770200598F98C8AE008CA7D95CC347AC7BEC18ACD24028E6AA4DCC856BCB9D370195BCC85DD8496B62CC3A06B5A2A5961D781659C068143952C4329BBAE9A985DACAB8201B1854995FD2BC544BCA66FB927757B78207E9C44405C04002917B2BAFCAB59AA298B555717B79257AD5BC1AB1B10F92C229A9224CA16433D244770CA18A9CE12841EC38E8D131D75912C05372CF8C845E256DE2DC38283B0E2326A5DF7A3E4AA112EB91292709BA89F7672CA1BBD599859637782C7C25C61C03ED288CA6181F5E194A85C37615A1778BA51F62789614B715ADE62E85BB8490E7B7D1C81C9B578E411904D7C9C287442D406A1BD26CC759DA58FC867B0A39954F7B29702B74BEDB4C8DF87B7E57526C25C2123C1099A21CB3882C966191BAA5C89CB19B08DA6E20C588B68C954DC7CA9483B1B9FB508C694424D85C99E35AE8A084CED1C4D4B9CBB4246D28170BA94109853BB0224A2638E91FF3269AE2B013D515BD867A6BF7797B309342DA513DB1D18031BA29D72A0850669C27A1B27454B427785327225C73968FEA012D5389861B56631F89316F3B9D59C77E007B88607A53A5D7679BEB45320CD0EC605C2B0B6C7221BEFA0BBF1FD65888E5030AA18983AB1DED0979DE800DAF11B54C50971775C98BFB5B30772A6CE835021B4344D075022B4DA1A8A00E0BA140F26CC2A36F1685424642518F57217F60ACCA0B3B24BC2DFF61BF1A903210582B684178181B47116B4139E2478D37BBF006C9B8F849AF07497F493A8A0A0EF67268D8526F3D874A7EE3062E3590AA01CB09A4BB6AE73839602DFF6A0D335132864AA178C19D8D096E3094719D6ACEC6305CF3E59B190961C17B281077838E57805ABC615856C90BE8595B00C19D93B42247B925402ADB132E78C40E18C52459A542636208D0E068C12858BAA380FDB287D7E4B855716F2365354C63706EB5561C64A012F56BD64C06D2582E9CB34DCBBB837CC72C82A2CA557B328FBD9838D19A8BA5CAEF7F516F782E8BFDB53A793223A813F942BB5A6E0965E5", + "dk": "B325042B81C75CEBA41A96A16D9695F5842C3E6B9E7CE97B765A7B44E49B33501E72CB6F5F88A94C9A731A784A1DE1955A3337DD299DA82C5AC31AC581B46BADA8BB08C1736C785633610ECC5B68C2786D82C9A08D6277ED6914C43695F275286B5B5B0AB1C8D936AA569262B6358CA287A49E06392352706068484A14587C9B71084A35A5F8ACF78C47D34B43E84331835C4E75E17645E045ADA45D9F99C267B4345CB92241BCA8CA988353348A9DD73948A941D553BF444B0230A16F7F625DDEA463A2C49246273963BB1A9C2439B3DC18F3377A15414E775700BDC408353C7124E1BCA513AC5D415EAAD5A36D72A965357248E0AA5A8B84920C4BBE4104204449CD947484B42D49D93772C038D6554F0037BCDDCC50417025F4C0694EC7621ED82BE87BB3F3E9CDDE27388F55B730C40B722269D53C6BB388557AE11F960680F8F031443B6BA70C1CE45B329A6269F7B410D9C40ED4D18FF1B6CABFB20D89019F117032C5A2008484B078488D2AE065966C680F7098F860C896461BD1D0C2947B67431B3EBB3734664C4CF1213502E0C7826A4981FB8854A5A45B216F469C72CCA4637D9C61249232760B58D785B3B411683BCB33DBE175F9E240955A7B20D819C06C5AB567C8F289915CBC3C50204443F17EC096B399E11530505D94C93EEB9946E41362BAF7772C7B153AEA4620349BCEBB2243B85759093A98D13E5CDABF2BAA25A31464C19A358B1CCF6DCC10B5341E677C0B37C65EA52717FEB98C84470261E23FC7E02AF5D2CE086A326832174FB089B768B4701A9748225F01F98F1AC42DBD99594F34812DE15A09CAB805B695574145E0AB1D9600B18BE721E70C11978ABB91E159EAB67098A77D8F51ACE14CAAE9F3360645338F0A536450384452C89109AB3D9A5C8328B3CDF0334F748464A383883C033E673A6799678A860548FC4D47D970A8B24DA195CED6B52469AC36CE9BBD159A60FA6944014ABAF99868B963943685C7A15694D4B2BD6ED91734D601680C692314982C4445B6547CDE146B9B82C558F5ADDB84C2CFB93E91E61D4016728BF724377805F0060E3C4C943FB8AB1359979B495723C32AE096130E559604A5BB80817EC947A23785CBD7209D7B7672D1251CB234A196374364A0439623C51E997D2051C0C6630214DBB6FF1C88B1600BA11A0784D68807E830B885007C202376970B92625037677AD1B81270679349DC4CC56529B5BA205EA596AB489B8574CF668303EDA22578258739A525364A7A2C3439B6E74E9BB1A7462B2A51327719528358DA11D7BC856142A4118449F8B89C5BEBA43C117A27C65BB1E70DCF5B36A1E45416E2074BC1211F14AB957C4810C84818932653D17C4805BD6A00C80E0C0FF7C51295C670A8B6758C23A21CB21E6E097AF583AF2761AE3D62AF0EF56226E31492120B90322D76D6C1F657CFD0D2BD2F6CB4F8589012B99A73B82375C54E283C6F1DD12FD53B1DFEB540280375033B0DBA671A7D608FA3BBAF8422AACE1055A787C77506C199D19A01E1A0391798C8BB967A1C797C247C214B790B14606E3403EB91A57340557F872110C0185429AC9C454181375992D6C7C9F743DC832F2A13CCA8C8B42F63A609329DB749934F35347C7251B0359B6582502BABBEB5574F30C63568139B1CD854BE96B8A6F09069460205BA245182334F669E93F8C7D867945C3B75BF1CA810108E0F670249A62B9E6910D793C7F0A24BD3C40839D713F880B4EC6AA8AD8ACF6EB03E12FC5B1BF61ED2480A9CF68E30A441E3102611D25E9925503E704DA69393152A759DB92175E0343560B961759370BBAB159320EFA846E4A316CF8035D8EC991FC4529055A5C7F76F6FC5423AA041CC4691352A44E6E91E54DC129B000C0829C069C1538EAB1E5BEB58BF0733B64A17C5D159ED31AD4B15B36664465B6548CD4060B487C0C76890DF4B4EEC5705DE97BF47712C667023E627480A4533A9258162050F401CACD75232CF7621BB3B00F76A1CE2B42E65A91E65306F6C019C3F0C1E00FD2192E703EE5592A41C95E8263F53B16E54A952D72078A1589FCDD7BCEAB03A41D89E1D9071DB88C344F65C8D6714C367AF7C5287D6B68EA319A7DBE97F7604AFA67A27BA136C2B996B6A1C4647A8B56CB8C0D6A4BC9B33079D5B407522195ECB9FC23C778B27ABBFF026A8CB84ECB66AFDA43D40558990931736D32EC4937629FCCD01D7B14A1241D2ECB7929C443AAC703553C63D7C8410A891986C770200598F98C8AE008CA7D95CC347AC7BEC18ACD24028E6AA4DCC856BCB9D370195BCC85DD8496B62CC3A06B5A2A5961D781659C068143952C4329BBAE9A985DACAB8201B1854995FD2BC544BCA66FB927757B78207E9C44405C04002917B2BAFCAB59AA298B555717B79257AD5BC1AB1B10F92C229A9224CA16433D244770CA18A9CE12841EC38E8D131D75912C05372CF8C845E256DE2DC38283B0E2326A5DF7A3E4AA112EB91292709BA89F7672CA1BBD599859637782C7C25C61C03ED288CA6181F5E194A85C37615A1778BA51F62789614B715ADE62E85BB8490E7B7D1C81C9B578E411904D7C9C287442D406A1BD26CC759DA58FC867B0A39954F7B29702B74BEDB4C8DF87B7E57526C25C2123C1099A21CB3882C966191BAA5C89CB19B08DA6E20C588B68C954DC7CA9483B1B9FB508C694424D85C99E35AE8A084CED1C4D4B9CBB4246D28170BA94109853BB0224A2638E91FF3269AE2B013D515BD867A6BF7797B309342DA513DB1D18031BA29D72A0850669C27A1B27454B427785327225C73968FEA012D5389861B56631F89316F3B9D59C77E007B88607A53A5D7679BEB45320CD0EC605C2B0B6C7221BEFA0BBF1FD65888E5030AA18983AB1DED0979DE800DAF11B54C50971775C98BFB5B30772A6CE835021B4344D075022B4DA1A8A00E0BA140F26CC2A36F1685424642518F57217F60ACCA0B3B24BC2DFF61BF1A903210582B684178181B47116B4139E2478D37BBF006C9B8F849AF07497F493A8A0A0EF67268D8526F3D874A7EE3062E3590AA01CB09A4BB6AE73839602DFF6A0D335132864AA178C19D8D096E3094719D6ACEC6305CF3E59B190961C17B281077838E57805ABC615856C90BE8595B00C19D93B42247B925402ADB132E78C40E18C52459A542636208D0E068C12858BAA380FDB287D7E4B855716F2365354C63706EB5561C64A012F56BD64C06D2582E9CB34DCBBB837CC72C82A2CA557B328FBD9838D19A8BA5CAEF7F516F782E8BFDB53A793223A813F942BB5A6E0965E5B5E964695C24F57CD05B8BDC23949D382C7E9023CC1432BC131689528B1453B0A20ABA8A8DDC212DE825BE0D3BE57701A6B5B3A46A300D9B5945F579A59AFABE" + }, + { + "tcId": 36, + "deferred": false, + "z": "7FB950A8F51DCEC4BC7A573EDDA56ECC049E5688476BD5FD6CD076A8F99A019A", + "d": "ADC4DA59D935DD87420ACEE52AEE19CB371FD0BB498D79BA680159EF7CE37C17", + "ek": "266B5ED5BB000FEB4C73CBCFF6E8A980326E798113223C1FD815922E1247992A2340B70B46A6CFF3638A9E741B478BC7E6C476D2F68CE244BBA73AA919C7A48770C5A9A798DB1901B2D93836F5C507D862811949CEB4BBC65CC2D6FC36E2215078149355B83B83635BEEFAADB6FAA387104213CB6609F8B36D291B3B567ADCD85EF569966E527102AA159F0912E5617E1B0C295D12838EB7790F0C4E4A93562EC21F94C517F5B6CC3F7B3F6E832F93893417A2797F9848D5333CE5741ADB867E64E898362249A2632F7ECA4BD38034BD5184BCAB71F38854A02A2C4693B32CE172C1FB41AF3A2B2AE370889C485F98587293C6758504189050CB437A991B8EA5E25569D1A9ED194D0E470A419B453120288D29763C3BAB00F5180CAB07DA070DB401CD28D69892B77A847A47C51A2D0B39A22074627CBC068D42988A60481BE5934E626201292AD073BFF81CCE044A33E3F3339C7B9446C607E666656A94A0034445635312B20A76CBC4C6763C338AA022D79A826D2841EECA89D433C5E7DC041ED488610A1F5A951FA966148D1B8597101C7CF8AC44F5183D42C689079164E90B5DC582A761571496B7A8C3543FF275D403B923B032CBB87D5EE90EF8853AE78590D0E8B200C3819705AD47E71568051C026B4B5C10760495994208AC61A08C23ABB921828A5D69740AF57507E339EF977649999330C6A9B584642F5539356590C6CB64872517996CAEF853219C5C2CC1BA04F0C8537039C9A3047DBF17CE18673B039B2A9EC083C7E53146863B61199169C9B1838CAB40508A6B709DD8502783654D55766E6B671B6C83201509395BC565B10904DC27BFE30842479528995A5888AA8E04374E2918A9EB642629A135B9306A21CB02C925BC99401EAD40285A7B3CF5A809FFF6502E727B332269E8C445C7D9303BF35C344615E19220E391AB4F2011634C292C22022AC0CD5FB51339B83833EC7404FC38108207B8A5B1416C2DD29785F3D87F0BC75F24C65864C31EDBE243EA0B8AD015A003BC9EAB583FDB5ACB32BA3BBAD6BE5A189472560B22614B5BD257249C4458C7601C8B0E48D0C72DBC5743E77350D64DD6A587B67280D04B20D1DB15275361DCA43CEC893EA5401FB3B459637817A18755876983818CC1C745CF70D2A8CBB36050601BFC34BA9685A02B6652535BA101A5193660A06CE54DB9700A977AB36E612549E51FDFAA5AB0490BA7A302DCB314ED026CA1D765D54145DA1623F9A7064D2926F25A0C9FDC4B8CEB8C765CC9B3A55A4BD79CFB9754ED5786F04395B7A80ABE92687D6900DD14C3AD743E2F9540534C63602858371C3D304263C2185E29261237A848DAE97507DCC5FDF60209112E08D269F56418F2FC875B693D5C9CABB9BC636FBCCE548227F42BB001EA6ED64057656566F51A927B178E17AAA24A0616CA362AD134AAC5D36C5447BF4DD0CB7DB95C9009B7109826B1D8ADEF95CE8B9B444848B41002426812700850CD7572A2530A2BDACB8CCCA5485032454E855116E91E6830A68EC04DF98370CDD18E12372320BB865AE818C6B32628489B59AB53B31ABBBC944861A0BD100B66FDC017AA0C79DD177CAE432024181820D23688BC991AE597981B56C3F45B5E4A92F34C7E72882C6B4F1D791C2719CF3DFBFB8F3FA04ADCC1D4FF07", + "dk": "24C6ABF468CF8893385B625491F2697ED724ED371DD9C76158418A6FFAC9E0A4158694AF115BB82549A0D02BCCB13282C4C37A2AFC617F347D7BC64DD6CB94C50922B8024ED4FA598B4912EE2ACE81FCCE893739678397C343C7DA4446A55687F236201E071B9C2C7715DCA6AC566702A809931B1D65919CDDB51A87B44B07629C659A104EF61BAA8702355128B9215A40E64F818C1CA297698EA14C00756B6D52974A7014E69B59E477362A63BCCD09BB474020FE51BF5337124C24C8E6F60DD2E495F3370E14A4CB1504234A4C8009B97365F166D385AC511A05EC06465D962D1BA88C191A9E28DAC4F517680D6586923BABA11BB30AC13D40466D52977929D62F48751458087830B02F5BD9B100A92DC6E602F3F24686365476C33CB9F5409856C80FA490DD6211AB9776487A3E15B33A92A347F3A92744C16DE3F8B3E942628C926BCDAB6CD80A068ED951F2689EF7066A9E2627F39C638A580441EB8FDFD9B2EA1B39D043AEEA1A0F48EA84490408818C602A828F869098FD2C429B35621DE9BC8039C6ED940BEBC32FD0C6C396B3248CFAC85C74325531A296A9C237FB2C4452457B4C43F0DAC214575A96A770170ACE6E0109E4A9C0E5F8985F4AC37CC84D206306AD7A2058EA58EA09AB3B7926941996B8125D7BD76472006C003784CF4479691BC422E00CA9976840D886DDC8A5BAFB87DB268EBD8248033703F6C6686CF928FFD736BDF3A26653319F22996C52387BF0A294944FDB1051315577B244C78578923F48B435362711B89585841FDFEC9FF047C76864055757CAC7EAC9D0F2999C341D314154DD58519B602D7855B6ED67049AE402F8913177914051E7C5A8400969F5CE9A485D95D544920AA7F169A198FA710FF73440D8949550A054562F16637D5A813C10BB29422AB193616687F062A1FA1693E3A9064982F9E96FDDB812C0763233687EE08928DC800FD2C8A3143148A0BA97633B5D97062A5B0572A89B2B265C4439357F96C01C6F464E72D0BF0CC1C421B3CD38610A9B0C89EE956AB896189C0B03AC173D31792ABD132F7174BE4D210B76E04B87E85B2E4A25F41332BC379B10D672862462F6AA3875DB6A22158EEE6B13135751DD49084862953CF275BA4580DA07921CF9482FC692643A6E9A5073A567C593AC01A57A75FC3735CD89029C99B3945A2BC7949B64377EECC96FCCFA2AC94CBE4C9AB4FC64673D042F416A80D867C9D5B3C9CB276FDB3C693181B071553B0EB66138656F33D0546322330980553BB2400D1256BECCC969937305553E8BC60C2D24AEACA90061CC7D38E3244253414222BC0D321C73EC6FD8804E71092995D48A6CD1C68CD1841011A45F4961BAB52EC176628B49CB0B840FC8B1120701227B0C92E10A1B34BB2475152BD72A82232345CFDB5B46E3403397B5D1276FE3E96703950FCFD49F1172CAF856A333497BB68C2ADAF026A7198BEE890718F474D7090151D21ECBA4B83E56069E1C6D34C5BCBFE94BF0A385702A9D2FC770D1905120A57FEF816AD941633558AEF7F96780C15112710DEDF8517CDB3314687BD4BA4C2B5A0BE253498894C7CA32401B517D812172A2B13146F30ADCBB6E79641A366BBB96B0688EB285266B5ED5BB000FEB4C73CBCFF6E8A980326E798113223C1FD815922E1247992A2340B70B46A6CFF3638A9E741B478BC7E6C476D2F68CE244BBA73AA919C7A48770C5A9A798DB1901B2D93836F5C507D862811949CEB4BBC65CC2D6FC36E2215078149355B83B83635BEEFAADB6FAA387104213CB6609F8B36D291B3B567ADCD85EF569966E527102AA159F0912E5617E1B0C295D12838EB7790F0C4E4A93562EC21F94C517F5B6CC3F7B3F6E832F93893417A2797F9848D5333CE5741ADB867E64E898362249A2632F7ECA4BD38034BD5184BCAB71F38854A02A2C4693B32CE172C1FB41AF3A2B2AE370889C485F98587293C6758504189050CB437A991B8EA5E25569D1A9ED194D0E470A419B453120288D29763C3BAB00F5180CAB07DA070DB401CD28D69892B77A847A47C51A2D0B39A22074627CBC068D42988A60481BE5934E626201292AD073BFF81CCE044A33E3F3339C7B9446C607E666656A94A0034445635312B20A76CBC4C6763C338AA022D79A826D2841EECA89D433C5E7DC041ED488610A1F5A951FA966148D1B8597101C7CF8AC44F5183D42C689079164E90B5DC582A761571496B7A8C3543FF275D403B923B032CBB87D5EE90EF8853AE78590D0E8B200C3819705AD47E71568051C026B4B5C10760495994208AC61A08C23ABB921828A5D69740AF57507E339EF977649999330C6A9B584642F5539356590C6CB64872517996CAEF853219C5C2CC1BA04F0C8537039C9A3047DBF17CE18673B039B2A9EC083C7E53146863B61199169C9B1838CAB40508A6B709DD8502783654D55766E6B671B6C83201509395BC565B10904DC27BFE30842479528995A5888AA8E04374E2918A9EB642629A135B9306A21CB02C925BC99401EAD40285A7B3CF5A809FFF6502E727B332269E8C445C7D9303BF35C344615E19220E391AB4F2011634C292C22022AC0CD5FB51339B83833EC7404FC38108207B8A5B1416C2DD29785F3D87F0BC75F24C65864C31EDBE243EA0B8AD015A003BC9EAB583FDB5ACB32BA3BBAD6BE5A189472560B22614B5BD257249C4458C7601C8B0E48D0C72DBC5743E77350D64DD6A587B67280D04B20D1DB15275361DCA43CEC893EA5401FB3B459637817A18755876983818CC1C745CF70D2A8CBB36050601BFC34BA9685A02B6652535BA101A5193660A06CE54DB9700A977AB36E612549E51FDFAA5AB0490BA7A302DCB314ED026CA1D765D54145DA1623F9A7064D2926F25A0C9FDC4B8CEB8C765CC9B3A55A4BD79CFB9754ED5786F04395B7A80ABE92687D6900DD14C3AD743E2F9540534C63602858371C3D304263C2185E29261237A848DAE97507DCC5FDF60209112E08D269F56418F2FC875B693D5C9CABB9BC636FBCCE548227F42BB001EA6ED64057656566F51A927B178E17AAA24A0616CA362AD134AAC5D36C5447BF4DD0CB7DB95C9009B7109826B1D8ADEF95CE8B9B444848B41002426812700850CD7572A2530A2BDACB8CCCA5485032454E855116E91E6830A68EC04DF98370CDD18E12372320BB865AE818C6B32628489B59AB53B31ABBBC944861A0BD100B66FDC017AA0C79DD177CAE432024181820D23688BC991AE597981B56C3F45B5E4A92F34C7E72882C6B4F1D791C2719CF3DFBFB8F3FA04ADCC1D4FF07BAF18B5A25081C8A9F526111B600954D39BADAB9044F59903D2A8F21F8E1D78B7FB950A8F51DCEC4BC7A573EDDA56ECC049E5688476BD5FD6CD076A8F99A019A" + }, + { + "tcId": 37, + "deferred": false, + "z": "51D509CF26799741631099039F713B22551E2B0F0297BB809DF0CC8FC3E47EEE", + "d": "76CDCA53F781806D55CA8D3BAFB3F4D389D712F1221E85B5E29D6A46580F978C", + "ek": "FE97202108CD725098CDC892FA68301012B3156A2E5BD503F9D388B26B07EE099D5AB0BA6B4A5E7DF369F748BDAFC4C72B171747546B3957BCFE189E312058202885FE853966A7B3DD285E06D37000900228662910260CA1D783DCE2ACBC436BF3669C51A07FB990449AFC153C9C5630F8A2E4E4B7A8E8719A98920B104E72646F83D8C06AB631755239B4303B7AFBBA9DD72577FBB677C054B16813DCF373734A6E4D8B025B66C19936A13278B859165FCC6277E9F149FF979EFEBB9867A9124233A5107B5E29B2CAF81C84A3D05DE3DB316858C5FCB372FCF28705E2BF0B4855E6F97F17DB217AD6A7B7288310086AD129119FF88D20B35F2F287B1358A851185BC12046D5079A2CB3CCAF98BEB9E7C1E82A841F7B48B4F57B3B17467441865288BC7020CDB1B7564989AA3F47BAB9B0919C6819E671235CD7B39F39C71C870FF6A72612CB1BC58A86F565AFA6932C71F059B2F72BA83A8985DC26D91A0CCD49BD32080D30EAC67D96A061E906E2B15E5F43215A9160AD4682A27A2B1B9C3ED1C697CE7AC6A4B2B3963B9A99441FA9D6337739AEF5891D773B4C095C8E97A9BBEA918EFB6058AFBB2A63318972400B11B9523FD335E118CC1FA0BD0B03C8C3278787F9B7D1F752BF5B739FFB0EB0654E753C2F955351243C233E9CB149D49AA1F1459D61B03E452192B64AFD642D00800B4B815D0B9863CE2A4A8AF4C6E7BB3F845A32FD95184812896105946B7A8ED80A5ECAAB0348DC4D2C4C2B7DBA3D1EE6B6A9D35CF03A4585169FBEA45101B97BAD583F9CEB486612761A25AB393960DDF3C1A4E23E23134CE37B7E6833822AF3B278B1B69D27A4ED72221C055C7F006F3DC78BDD3C86759260E31C8D0503954EF31292EB1C8A877A00271109998D9A1A026C16482316994B2573D1673C5B727E75024786C1742414B746C1B2AC74B71920A2C79B0456C08BF1E519CF28AA70627A6A5C8496D9B061E4439B75080A763E50C1A4B32483E87AA5E67C25A8A7CE6FB864012C6A32535DB7123D24F7CA62750A18E96911EA0AD2ECABB7B02252D44DEBB2C55D552349D3798EF7812B991755A278CE158185171B696859968492CAD792DC82767E53333AF9812AA55C443959D14B1C385452367BCFB5A5955163B287254B9C4B0380EB818912BB175605EA55585F82AFEC62C2CB46BE6AC0CB99443E5676AD21EA08A467006E67C5FEF61193F3A54C4C5DE6A4314ABC3F62A83261A4B56AF18172B4A85C00C56CF28EA5C6BFEC6AA703530B7E641E792C35D1F1BBB1914D15708B88B87D161524B44B12167873C19237CAD32BB7C72B0CDB04C516142634101FD81B2B12ADBFE27512C0A091523732B82AA278CA6AD1AF28A03ACCFA28D591040FC950AE475976C5A7E192A9044099A4AC487D5A39E121B9A776CB190A2CA499403C3A5F9F027C49F627E6446D8FB53252E1B098AC8A5DD59EFAA22D2F57C83809003CE2B562231140542AF5D561ED7C74B4E145820CBE387254D78C79A8F6C241F10D94E26454764876631811492221B09B9C2A6C75520D03EA79CC129862A10AC2E0288446AF46165BD1F614C9D1C3606C9C8669C334534266A1946AFC0C580C19283CA1B59C88AD6B8ACAAFD7C3328CE3583325ECDD4B101DC28053788ECDDB4CB7A4B66997F9FD0995", + "dk": "D5DC5D1A0BA3C20670B1306E201A927764654F757026D15DAA35B77F5B81AFD975BE114CC9E9A31A4C5E83C28D86EBAFB1E65674EA7BFC5646EBB49C67D7B0EFD60FE283BD07D71EDD71B93C815C3CC066513A52C74081DFB0773EFB736D6C0E862CC5F11CB88FBA3AC62515C39B0692359AD457210371C65B6031745622BB68BE60337F5ECB065FA678CEA88165BC7AA4E002D3C892115A3504534F5DE12178FC17E2F513B3535813D30EFCCA68018128C5C3181225CACB1C76BF7A6E98195E0B793B78B0305121087A83A37D1989D0145BB4F11B5E579075B6C5AC845949DA2EA03BBDA446A6C7F5B88C8913454A605179004BD47BAF446BAA4705743A0B6E2833011CB4069664E80C58338C71BBF1C72CC89F77849F6FF354B280044DE60B6D16C31355B4AFA199FDBA078B018AAEF88D046B927ADB64935152273B16127701B0093EED2439CC89C3DA9A277D1AC5CAF65B48262A48521361192168425FB1C341D180CABCD7406154CF7F647F0A62700C630F093649E98936D12A1FFE00A368A2622D4579F521B57BB1510D6CC6D35C48AA96B07079C7C6E4265D768E4EF2C9FA463052E716B48053EE0521227544384C7AD1673389DC34029C02DF55199328376A4C07CE6C8AED221DFDB844F770282E537F15A83A5BE8873AA52FD17C324C6C4B763A7D6A3121AB384814D20B879A42E3149BDC58CE709B3DC6E87B6EC03375CB15584C0DFA6A05F48935DB376096293BFF5A311D4373A95AAC117A25C1FA95EB1C21658A2D313A3343F643969148B11727BA64882B8AB3EC772909EB9690FC72A8F1C6B249191317610F81999B161ACE6351AD330E89A18FA0986514848E80AC95BE41BAE18C1885D44CA30047FDC152EFB069D589296AF20337E12A1093CD54BAB36D252AA2A674A7C065A5676CCF507C1A07A2CC471C612500E124573C865F9C3C6D59AA02F54094141B5A3E8BB9CB7A7400A42AE4867440399306627AE9112DB909A1D6820C26ABA62428BCF27842F30BCB97D241D161CD17E8C3789BB94EE60238B2C987601F694A1BBA38581C261DBE2B94A89556F12620141889A7CAA997036D7693BC5EE961D06A1324EB7520953AB7E3BD00FB2B4E306312A6570277C71BF35DF403442325789846AC203B905F28127B3947780201D5B57B6BE7CAC796076D04B838A222C4F08004F585BF79645FE11EF52749B8C0A5656798F8F8BCDA89C29CF1B10B4429F8B65974164C1653B0B6EC8DCF39961A7B82DBE28604C579F3109F94577B42A4574AA36F2778CD424C6238996F4954605C7B25B50C455AC334D73343D90AC6A222324DF6BC4766B3D2C2A04C92A54F084DED24A9A4D5012AE741F12318D283B1CD668375129274149F33175C2E19453F3B4E60A1089E0647D37B0721254C86720DA0A97697B45C4CD5360AC513D4261BDF738A08F1BEA818C722367C30788EA2361384A02528E1423F4143C525B8C9A89A1A574A0D45AB9A8C4E02B01B894634C29A3FF9B1C1BADA025E8A99F38A092CE903CC03411FD25CE61110A4B423A01699BD922353FB65D8E796F4B77F226895EB822552F7AE0CB7C22788429F8132F158C824319030E770D6B9ABBBB912F3E592987826FE97202108CD725098CDC892FA68301012B3156A2E5BD503F9D388B26B07EE099D5AB0BA6B4A5E7DF369F748BDAFC4C72B171747546B3957BCFE189E312058202885FE853966A7B3DD285E06D37000900228662910260CA1D783DCE2ACBC436BF3669C51A07FB990449AFC153C9C5630F8A2E4E4B7A8E8719A98920B104E72646F83D8C06AB631755239B4303B7AFBBA9DD72577FBB677C054B16813DCF373734A6E4D8B025B66C19936A13278B859165FCC6277E9F149FF979EFEBB9867A9124233A5107B5E29B2CAF81C84A3D05DE3DB316858C5FCB372FCF28705E2BF0B4855E6F97F17DB217AD6A7B7288310086AD129119FF88D20B35F2F287B1358A851185BC12046D5079A2CB3CCAF98BEB9E7C1E82A841F7B48B4F57B3B17467441865288BC7020CDB1B7564989AA3F47BAB9B0919C6819E671235CD7B39F39C71C870FF6A72612CB1BC58A86F565AFA6932C71F059B2F72BA83A8985DC26D91A0CCD49BD32080D30EAC67D96A061E906E2B15E5F43215A9160AD4682A27A2B1B9C3ED1C697CE7AC6A4B2B3963B9A99441FA9D6337739AEF5891D773B4C095C8E97A9BBEA918EFB6058AFBB2A63318972400B11B9523FD335E118CC1FA0BD0B03C8C3278787F9B7D1F752BF5B739FFB0EB0654E753C2F955351243C233E9CB149D49AA1F1459D61B03E452192B64AFD642D00800B4B815D0B9863CE2A4A8AF4C6E7BB3F845A32FD95184812896105946B7A8ED80A5ECAAB0348DC4D2C4C2B7DBA3D1EE6B6A9D35CF03A4585169FBEA45101B97BAD583F9CEB486612761A25AB393960DDF3C1A4E23E23134CE37B7E6833822AF3B278B1B69D27A4ED72221C055C7F006F3DC78BDD3C86759260E31C8D0503954EF31292EB1C8A877A00271109998D9A1A026C16482316994B2573D1673C5B727E75024786C1742414B746C1B2AC74B71920A2C79B0456C08BF1E519CF28AA70627A6A5C8496D9B061E4439B75080A763E50C1A4B32483E87AA5E67C25A8A7CE6FB864012C6A32535DB7123D24F7CA62750A18E96911EA0AD2ECABB7B02252D44DEBB2C55D552349D3798EF7812B991755A278CE158185171B696859968492CAD792DC82767E53333AF9812AA55C443959D14B1C385452367BCFB5A5955163B287254B9C4B0380EB818912BB175605EA55585F82AFEC62C2CB46BE6AC0CB99443E5676AD21EA08A467006E67C5FEF61193F3A54C4C5DE6A4314ABC3F62A83261A4B56AF18172B4A85C00C56CF28EA5C6BFEC6AA703530B7E641E792C35D1F1BBB1914D15708B88B87D161524B44B12167873C19237CAD32BB7C72B0CDB04C516142634101FD81B2B12ADBFE27512C0A091523732B82AA278CA6AD1AF28A03ACCFA28D591040FC950AE475976C5A7E192A9044099A4AC487D5A39E121B9A776CB190A2CA499403C3A5F9F027C49F627E6446D8FB53252E1B098AC8A5DD59EFAA22D2F57C83809003CE2B562231140542AF5D561ED7C74B4E145820CBE387254D78C79A8F6C241F10D94E26454764876631811492221B09B9C2A6C75520D03EA79CC129862A10AC2E0288446AF46165BD1F614C9D1C3606C9C8669C334534266A1946AFC0C580C19283CA1B59C88AD6B8ACAAFD7C3328CE3583325ECDD4B101DC28053788ECDDB4CB7A4B66997F9FD0995CEFB593C11ED360F404732EA8B6542FA9796F2AEBB4C61EEA40B6D8A599C7F1351D509CF26799741631099039F713B22551E2B0F0297BB809DF0CC8FC3E47EEE" + }, + { + "tcId": 38, + "deferred": false, + "z": "9C330AB4257D7B87C4742C6E95B66BDF805C6A145BF444836092C6B1D2C5FFFF", + "d": "78AB6C49354A018BD38A39926F822A1AC4ACC4FF32DFD7C047CE0887A3AC182C", + "ek": "85787649612C798187CD986E9578582F607DAED85C09B863A5476626016F88212EF2B70D81145C671162741C70C9DACF566A1B68025A7B66BAC9EB5ED8879D4CD40237D9C791B0A7E6C1C08A7354424B71D6739192B3BE48755CA513170BF3A6197400FBF94E9A707FE6D007E4062BA2D1BFF9192E294A981AB19839120401653208618C6DB25E40A28B8DD1A9E6D91A1408191C8C6638B04D2A50983C6B0640B934E5039729885DAECB0BCED2784B998CC296980626979DCC99A5726C4C07A6CAE1578089BAD68190AFA91491375C1C00624363C4A049A086794A046806117B36FC8BA8D38AA8097C727E3C59A6378703749C97D35CED818DB691783691C138C325541A1ADEE01CAC4800ACB2B008A0A5976C90B6BB8AC55B06B693390C30905866AF2014AB5D340A4EECCB4F91C0A2C700A68C67833C6FE10927D6CA935D8071F98BA31A1AB4B73128CB92BC1B8056372434A7B9524D95AD50508998A4AB179B0EB79C71392515E29BBD09682183394838A52734409EBEF5852DF7B9073098ACE127A7C95FFE48C30599540161C5D12CBF7BE203CD5AA4D861BF6768CBDB5C0401F70E4AC7B0ADC0305FB702C023AF65981A61E11A0B12C169E3AD569C90C417865F708C2A7B4B1C1866381C7EA6D17F4ED35730A84E5AFA975C728DE8B593D92251AEAA5841D8CE9A3037C1F47F8529CDE366BFC08C2A7337B8DEDA345008C43A5A901DF5C6B201B553F07FA799317A216205634130A2ADE04808032B0DC1E715C1B263C8FC07B251B14B9B1EF422C1BB171CA7D281C706A0251911ED345340DA4035D8947B058FE1D38F6EE02548B8056A24501E3B65B2568802417E98567322959EF118AB0C471B37496424FA327751C1DB40AD909424B66C811118A958782F3E57351C24934650B5A110B68C581C26CB7E634A283361B94D544E0EC713FCF52640CB180F25BD40D4114249828D5255B7EB9A1CF6589ED4BDE602317B4909950606F9C91E59E1B68599517A089466D939B43BA14B0A91987662FA63C27E1411DA78255111B961B45366515022421FBA4A04F48244449BCFEAF630CC4397A98226BC0B2A30778743EC2D2A9747A2127889794637F780A0ABC6122C79FE0830691A7EC277239190938F1648FD733C1761A42A84283E40BC7EFB707748CC0FAB76F5141122158B30655765257135EB2F08CB1E84067C64A503F58C8C54D765DADCC4C7181FFE1026E423B44AD717DCE8A6D765BE2A94C115434D16661F82410E7E19B8E3388972484638B6A52A058F2459414D3C57987215FD753434349BA001007940018EB49A52C78FFAF468D939C4AE585F2C1759E0A582BFDA316E53A363A1006BC26474F49C82B93EF4D7CA94A473D3788F5865B5D4323C3471888B06634AE325826144B5D9894CB59E8C6C6E3406459BCA1791FAA9743853175C48AD982F9775936FF68093AACBBCD87F6F30BDC1F19C93B2AECE6A3A4CD99ED3244323A7AF72C8598416543F50643B713AD2722BAFD092084BCF77385B6ECB2AC8F19BF9D97B353229496A0C6A5C73CCB06C2F2C5924E284EE3185D2160ED31B72D1F29B322C1DD11B5DABC5848933B4FB7B9AAFF1394AE76F624A231DB3C2DE108F5BDB1878551FF178901D67188E6B6F3A49C904A5539738F4305053044EEA5F9C", + "dk": "C4AC07C1B9ABFCA3BF31365671954516CB2E01E39337681D54262DB7B06E8CE8B4A98028F7176518098879083F64703207213945684CC4AB9CEC679834A35A8775509FE8CBBB279429D71A48FAA18485446A1A4FFD2996E24B76715A133C1486B2346055F22FB8666F487C44328688E5A6A6376682184B9057C9B65DF21101C3645C58393793B939C9B11C27360AE96E15A43BA3CA3A00358DFBD08A395C0A02C70FA45168BB6667A843A691A9C88FE11B79EB85F2034097166989024414770F0E2537A0F266F659591A06318947A715DB88A84BAD0434750E582A12C7C6981207239935C8529DBE0147E0E1CFB4D1BF8A6C1A699B736991CF2C88B22D466C5E481120A51F21A84877E710228766CEEC0168C2314DB6C85CAB02007875CFE3B5B613B1D50366EC450F1739712D8889D6653CDF41009CD42D3D6064DB930BEB551702813213C02110E435624920C242AEC784351228A847B1BF2C66AA1068364AA2BC674B2ABF2944018273DAEC324ABC94AB2AA5F21B318C84A77FC7A6D60570FB193A795993F2231497D8414B0082DB0A70AE81C8E5A61B461768B5653F51F31EC5E96F9041A49CA27A50598F23C575E0751E10C921A71676C2388C97FA83D481B9C466A265920DD9095005A1CDABA5B76E36AAEAB4BB58892F8A4C9590D2C96615A66F43A06FEC673C57B7376709CB759C61E37DE08C04D194A827173F5BC767FB788CE4A972EF148DADCB00B993A35C5369B3741D4C227E21112FAF923AB8C6478B856849A8B508BB4863D1C4239C0A469079CC677260FC8250C75887728B86A95F46B86E7C01214C1205C727707D9361E619CF792121F746815F9717DB937FAB2C094C90AA118C9D72801135AB87C99BBCB877915F8BA4E2E70B87303672D53EAA80A11A071C5AE307850C2864713287F976F7A465D8E4AC626B2390683ABE583E7AD4012F40778E4676BA30A163C70D5CFB5D755C0F806CCF0CCA7216BC16C2B7CA3F16239C147D81C4BBEAE635B2398E661B68EA863FEE4B94E6F2A44FB0A0BD8A75DEB9CCAF4AA14F14628EEBB7C88B63731587645B721ECA388EFB5495638863A13F4F6440C2E71636C9C1767B192932694C82740CB457D99B30C8396976A32AA5C027D3E36D0C3B09D24128B748CDB5F57BBF703E4173CA5C115B7000625FF06E280574EBB97E759302775093DB2878DB545C345B6525118D1C4458ADC9BD5F212B4D3BC77D66B9882A336231719736B448833B20F5448E759813FB856F95C60E29BA726B1D159B2BB342B737DC3FA7332B4492C583F83D9714029AE52A366C4734D29DB1E88397D22EAAD11D4A9B1FBEB7435F0B7016A400D4547A3C4B8F54B0A5E1F37082B4B751691E7CEB7C07D383705B8F42139326F0A985646B99DAA088C1BEBAB90AEC2B6B30E96229175C07AB4AB78A344A13C9A2F02B782860007A2D5611C7287410BDF0454F76B4F660B488FB94655B19B28B929B45664E6C8374F096B3B9A9A6262E2C2355A1DA73DBFA8160C5A16C08C68C647FDB408C223AB5D7D05820C3A1CF2994345305FBFC7D74CC20EE02C7C97C2FA5445AD4C9093CFAB7DE1C467768A01863347D1990A5882E355937694C0A01F7A9072A8B85787649612C798187CD986E9578582F607DAED85C09B863A5476626016F88212EF2B70D81145C671162741C70C9DACF566A1B68025A7B66BAC9EB5ED8879D4CD40237D9C791B0A7E6C1C08A7354424B71D6739192B3BE48755CA513170BF3A6197400FBF94E9A707FE6D007E4062BA2D1BFF9192E294A981AB19839120401653208618C6DB25E40A28B8DD1A9E6D91A1408191C8C6638B04D2A50983C6B0640B934E5039729885DAECB0BCED2784B998CC296980626979DCC99A5726C4C07A6CAE1578089BAD68190AFA91491375C1C00624363C4A049A086794A046806117B36FC8BA8D38AA8097C727E3C59A6378703749C97D35CED818DB691783691C138C325541A1ADEE01CAC4800ACB2B008A0A5976C90B6BB8AC55B06B693390C30905866AF2014AB5D340A4EECCB4F91C0A2C700A68C67833C6FE10927D6CA935D8071F98BA31A1AB4B73128CB92BC1B8056372434A7B9524D95AD50508998A4AB179B0EB79C71392515E29BBD09682183394838A52734409EBEF5852DF7B9073098ACE127A7C95FFE48C30599540161C5D12CBF7BE203CD5AA4D861BF6768CBDB5C0401F70E4AC7B0ADC0305FB702C023AF65981A61E11A0B12C169E3AD569C90C417865F708C2A7B4B1C1866381C7EA6D17F4ED35730A84E5AFA975C728DE8B593D92251AEAA5841D8CE9A3037C1F47F8529CDE366BFC08C2A7337B8DEDA345008C43A5A901DF5C6B201B553F07FA799317A216205634130A2ADE04808032B0DC1E715C1B263C8FC07B251B14B9B1EF422C1BB171CA7D281C706A0251911ED345340DA4035D8947B058FE1D38F6EE02548B8056A24501E3B65B2568802417E98567322959EF118AB0C471B37496424FA327751C1DB40AD909424B66C811118A958782F3E57351C24934650B5A110B68C581C26CB7E634A283361B94D544E0EC713FCF52640CB180F25BD40D4114249828D5255B7EB9A1CF6589ED4BDE602317B4909950606F9C91E59E1B68599517A089466D939B43BA14B0A91987662FA63C27E1411DA78255111B961B45366515022421FBA4A04F48244449BCFEAF630CC4397A98226BC0B2A30778743EC2D2A9747A2127889794637F780A0ABC6122C79FE0830691A7EC277239190938F1648FD733C1761A42A84283E40BC7EFB707748CC0FAB76F5141122158B30655765257135EB2F08CB1E84067C64A503F58C8C54D765DADCC4C7181FFE1026E423B44AD717DCE8A6D765BE2A94C115434D16661F82410E7E19B8E3388972484638B6A52A058F2459414D3C57987215FD753434349BA001007940018EB49A52C78FFAF468D939C4AE585F2C1759E0A582BFDA316E53A363A1006BC26474F49C82B93EF4D7CA94A473D3788F5865B5D4323C3471888B06634AE325826144B5D9894CB59E8C6C6E3406459BCA1791FAA9743853175C48AD982F9775936FF68093AACBBCD87F6F30BDC1F19C93B2AECE6A3A4CD99ED3244323A7AF72C8598416543F50643B713AD2722BAFD092084BCF77385B6ECB2AC8F19BF9D97B353229496A0C6A5C73CCB06C2F2C5924E284EE3185D2160ED31B72D1F29B322C1DD11B5DABC5848933B4FB7B9AAFF1394AE76F624A231DB3C2DE108F5BDB1878551FF178901D67188E6B6F3A49C904A5539738F4305053044EEA5F9CA8604CD90AAF5FB9BDA220814069AA00CB5B5FFB7B60E4BCC86F16ED0B49BA9B9C330AB4257D7B87C4742C6E95B66BDF805C6A145BF444836092C6B1D2C5FFFF" + }, + { + "tcId": 39, + "deferred": false, + "z": "18EA1C7532F706B06870D0A1047AAE33D9E1FF9E9BCBBD302D8817EB7B022A77", + "d": "13B75620E4CB9AB9A6689F6E2BE44639BAE6C9CB7DD641AC1C9377242D99679A", + "ek": "AAF98BBEF422DAD045B9D3C2F134C71ACA3884604D3B87130EF84890D8870A4783DA18BD4C8B0667FB194393941C7508FE20AE5C077FD06A247DD7C19FD20940568B45938BEB39B1AE18CEA618BB8001C84DEC8CC170C12C77B6704AAE9B745083B3B00A020510A196EE2AA12195CCF650CB50600F35D61910397E645B886BFC58FB7C99C58AAD79552E13D31F05BA5904007E3B504D717156D652CB1D2353270CAFA6986846100B81C7816857AD7EB98D5CDA24E6DB3342F346AE5B162C11BB9E8C2AAF95C857277597398DA82A6DB7D7C34D7ABB1BB3155E72B0C6C811031A06D609C23306473317948E1B1AD9F7B59E22962BE33D750561146B135FF64058BC5524F26DBDE518C872A98D14862FF4599CB16C11D654F6762D531718C9B2BB51C34DDE019364F246891A3891F823AE85B6E54A4ED6A18673D4AFBC2C8C8F47C07C2B51DCFA56E5A57211914F437C2181A92723D5C09844951A0CC0470A594AB0C0E8A378A3015E39C5275E9B9D4E202ED6A4AC9AD1742C8455642932BA68C599E8883A3CB5FA11876023BD153166C7C33B3105C1BA9881F92C99CD8B41A475777F239AF2886570F94AA3626381A6B8B3C3AABDC39C2A6C0CAFF7CB95CB3162652BB0493726A81339377798D78AAE999BD9542565D5491556B716B09D0482C603B99501F8823AC6C5018543527928D2981C2957B9B7ECC33BF423F3B89DF352377DC554590A4BD6E7AEF624B873916CB638AB426A50F7789B25B420E4380413B10416C048A8069FCC62BC727AA9425700AFE835E12682215606F84C70DBAA4BD9B93D1E156913C62959C98A741A74810B996063624061B43D225B1AA71A02C50BF38016B4439FF156ACB652B278E0AAD91C455F03B29998317F596A1CB0051CFC21B1E76B59B52409164233D0C7B01A2B7C93120FC42BFB533347C2B4DA782BB55034C0A152CF51C44F39204A63C1F7867E57F27332791D8E3A1A13DB9A61BB0FE5660C6A8A2EB1365D30A83C3C1B9F03E66E58B0144CB6B292847F68CC3B0600C32FC45569158EBED0BAA50B26303707C1796BF9569193825603FB9237FC2AFBEA9D8D3B283D775583990E2672859155C70DDB7C0FEB84BC07B851F7B4BD44B84DACAC0FC913314113654567BE4370AE3179BB3BA56388A7EAFC3A1A10C25891B5A943C62A4297AD469D8040829029A8960CB9F65C21E10B64B07A713C40313E6A6EE0E939C741AA7BA93526022A8440858039A357EA2CEDB342C9299733381814E1C78FFBB1E289AA93C6ACD93C6DB2704F79922D277C9800EB3983865F65842D5BC8B346207C6C33612250110AB236DE202374132D60F5202C77367912C4FDFAC54DEC5FBC29076BA13FA013CE0FF70543B8989190AB63FA721F677FA5D0B248F2646E008830A06DDD613CB6063A8B9C37B4C263C4904E3B681EFA3568F0E429B947936EF41B2EF704751317EBE86A9597B8C0E6C81AA278FDC93F0379AFA3D1244D917401AB151A7805CE881216F208EB976FC442BB9DE86943143107B4AB479681F109AEDB28309067B9DCD6030DB4B558890FA1C5AD7FDBAA9BE39E6D6CAAED3C5286C73DEA3B6DBB940E6F647D43ABB364D92BCF099937706F8CD48F58BF77E3972CD846B20E9A1331AC0CC350080B65731270F9B2A951D93C68C98C", + "dk": "5C9B6453A08BA6B40F1F7C6C7CA464C76237EEDB9D74F0925D200A599684E85862AF8C29EF28871E7A55CC5824D381A9B7ACA2096B78081862D504010E1A9366000C022B3EE8AB91E6F7334287251F829C00221217823D641153B865A30F24B847154ADD5C9B4FF2350EA51D6C49A975AC2F65B541A52827DA25C93E9B36023C6129BA29E495B4914334E4D02CE21B66F1437874F1A56F03A6726C142F0B03D46543BED89D4597902C0C5B025895A04A9E22563560DB29793A353FD4528D0C6B0D0AC657358B04E7204C21A7378AAF3F0B93730C68D238695EA4CF3C9B35AE19B052B8CB2E041700902B4600BC30A846951BC0B9E42D9453B10ECC37165B08F22675657A6FC2023F0C1B42BBA175D329935B62468522BAC0944B83C5926A1C563D9323F175BB6EA9C2B1CC360FE8B60FAB81F5A1C9F31443D698B34336C0A1EB86E8E162FA21330E909CC0B69FD62738D823B6AC0462DE561DFF33094C1029ABC49381C406A316A3E2A887FFA9C3CDA9CA48E8AD802CB0231142C5F2CD83154DF65540CAFA16D39190FE100812816ACDD0720B4A44D337611651B1E505B7CAC0BF832841C573144BE42EF280B25C7B1700F344F82AB0C575B2D10C3A86449614B592CE42195F9C385E4CA257478E8D5320BAC24A68883DFC399AC236C497C27B5A80842AA018C0C0B459C2B14737197870C0E6D661510951D290B5549331E6C557DAB48F349B829AFBBEAB932E1E8638ECE2279C697220152FB84AA9DB5A8307F93438A51C22E8A1DDC54AB722A692EBCE6E719A82066E60B345C75729B4E7AD173BA7F363908411B6E724262BE0CB05F51E7739A5FE0C304690645C763CF7128DA2F71B2F7238A43003000995737A4DCFD8682BA8923C6752E53150DBD36468D6A2459A5A54450FA6D14A4295B573423E4BE95529C24D7D035C5F65C49D3684943AA505869CD525665545676A52958180538A521AF9274033BAB2C7AC83566041D9D40D92FB2DD2C147E456456DF0105264B0FB17853BF991789B6818F9BB75A381D4978D2EF7098626903C857CAB673353783C12C860258A363CAAA771ECC724B2332C1A254A3CB1547CCFFD149C187B345FA282DBB92D9793374CC67D0C0B5F946B78D81B08E521275AB7357050694C824033B9568BD335A8B837627B1494D9701181C7AA02A95DD3915E55A371F31C14F90C63075555BAAB65AA100AB99A6C1C85A1051D7E58A8E65BB312E02EB5485C05F302DDF814EED49D39E4A9BC688C989A17DF074C7FAC62FB73B0EEA85FD8177AFF41C4C3E40B407028C4F58E60DA14925385E4A0A6BA8B13C8618A8A08BF6A1630AF1B5200BA41596C9E440A5BA11C21F7C62A46379627CC4DB2E43A565A829FB605F186C405C519502C0115D9BDCB8857E03343707843A28047BDD6B445445560A686801C4D3F4C4C773537AFE7C5E2191853F56A8E75A9EA852552440B4E0642C3133FBB4CC678C2A35D093975F17BEC7972C938A7F0159A8BD8910E847DB09A1A2DE43576F9818A338787C10709F085987424C59546BA5493FE9696256C1B147105092A77A8A329563B061AF8CFEED35EA1E625F03716FA75B7839C325B94CB39C6CF1323CF4CA486F8703BAAF98BBEF422DAD045B9D3C2F134C71ACA3884604D3B87130EF84890D8870A4783DA18BD4C8B0667FB194393941C7508FE20AE5C077FD06A247DD7C19FD20940568B45938BEB39B1AE18CEA618BB8001C84DEC8CC170C12C77B6704AAE9B745083B3B00A020510A196EE2AA12195CCF650CB50600F35D61910397E645B886BFC58FB7C99C58AAD79552E13D31F05BA5904007E3B504D717156D652CB1D2353270CAFA6986846100B81C7816857AD7EB98D5CDA24E6DB3342F346AE5B162C11BB9E8C2AAF95C857277597398DA82A6DB7D7C34D7ABB1BB3155E72B0C6C811031A06D609C23306473317948E1B1AD9F7B59E22962BE33D750561146B135FF64058BC5524F26DBDE518C872A98D14862FF4599CB16C11D654F6762D531718C9B2BB51C34DDE019364F246891A3891F823AE85B6E54A4ED6A18673D4AFBC2C8C8F47C07C2B51DCFA56E5A57211914F437C2181A92723D5C09844951A0CC0470A594AB0C0E8A378A3015E39C5275E9B9D4E202ED6A4AC9AD1742C8455642932BA68C599E8883A3CB5FA11876023BD153166C7C33B3105C1BA9881F92C99CD8B41A475777F239AF2886570F94AA3626381A6B8B3C3AABDC39C2A6C0CAFF7CB95CB3162652BB0493726A81339377798D78AAE999BD9542565D5491556B716B09D0482C603B99501F8823AC6C5018543527928D2981C2957B9B7ECC33BF423F3B89DF352377DC554590A4BD6E7AEF624B873916CB638AB426A50F7789B25B420E4380413B10416C048A8069FCC62BC727AA9425700AFE835E12682215606F84C70DBAA4BD9B93D1E156913C62959C98A741A74810B996063624061B43D225B1AA71A02C50BF38016B4439FF156ACB652B278E0AAD91C455F03B29998317F596A1CB0051CFC21B1E76B59B52409164233D0C7B01A2B7C93120FC42BFB533347C2B4DA782BB55034C0A152CF51C44F39204A63C1F7867E57F27332791D8E3A1A13DB9A61BB0FE5660C6A8A2EB1365D30A83C3C1B9F03E66E58B0144CB6B292847F68CC3B0600C32FC45569158EBED0BAA50B26303707C1796BF9569193825603FB9237FC2AFBEA9D8D3B283D775583990E2672859155C70DDB7C0FEB84BC07B851F7B4BD44B84DACAC0FC913314113654567BE4370AE3179BB3BA56388A7EAFC3A1A10C25891B5A943C62A4297AD469D8040829029A8960CB9F65C21E10B64B07A713C40313E6A6EE0E939C741AA7BA93526022A8440858039A357EA2CEDB342C9299733381814E1C78FFBB1E289AA93C6ACD93C6DB2704F79922D277C9800EB3983865F65842D5BC8B346207C6C33612250110AB236DE202374132D60F5202C77367912C4FDFAC54DEC5FBC29076BA13FA013CE0FF70543B8989190AB63FA721F677FA5D0B248F2646E008830A06DDD613CB6063A8B9C37B4C263C4904E3B681EFA3568F0E429B947936EF41B2EF704751317EBE86A9597B8C0E6C81AA278FDC93F0379AFA3D1244D917401AB151A7805CE881216F208EB976FC442BB9DE86943143107B4AB479681F109AEDB28309067B9DCD6030DB4B558890FA1C5AD7FDBAA9BE39E6D6CAAED3C5286C73DEA3B6DBB940E6F647D43ABB364D92BCF099937706F8CD48F58BF77E3972CD846B20E9A1331AC0CC350080B65731270F9B2A951D93C68C98C1783913132F097618BB39BD4748B4EFE63DA07C26697F9B2F4E06CB2D27012AE18EA1C7532F706B06870D0A1047AAE33D9E1FF9E9BCBBD302D8817EB7B022A77" + }, + { + "tcId": 40, + "deferred": false, + "z": "C71F7E44295978FC63BF8F6A68F8609E98D155FD7A74E1FB7982733FBF8A6C25", + "d": "7C345819C7C327AD9571E5DF882449DB243870D686A9764D4129B21E17AC86A9", + "ek": "D6525398362B71938C1C721695157F1A2BC24680BF6E265DE8726594C26CBAB9B040462B4DA30402D70EC050958FF5944D181374CC9A29E867C1B33CC36CBA66C66A75F44CD68112B543AEE0026D9C105EE556AD5FC2989346C7473C93E2641AA42904C7751D83CACACDA6B2175B1B9C1C41435C49027AA21119428C61482F655D4A0CCCFA5315100C314B680F702CAD99FAABEAF08335257F9380066A09BA0D4B04F91A52FBC09F3C348F0A49B840BCBFF51B63D380C53FD17DCA7B76E782580D926865A79AA4992FDCA771F4232AD68956FD1A32547588967B402B2C8E3F2264DC7BC8B5B770EAF4B413C1AC44A8A4A4061CC7FBB7ED809FD97C84B6190BCAD156E36018C44CC0C5A84E9A872EFCE63C370BB257C46AC285058FA09981D1CEF51A07C44994E68C9C3CD6394EEBC545F438858A6D18583E51DC6F15D7B0A3F02F26932928BA1F281012D93050A8D6685F5364FF952BE1C644965A3D255A57C95308E100C4AB8343E2311927212E6F7975A9FC7F72B4761B78069DC5553D740A5433108099BEBC850D5477CE3708474481026931082946A949E3B00DF640AA52BA6D04AB3C1115C91147BCC519DDE6BB953582DE996D38F35A51C7AF0AB999FD78A9B34BBB209869D3776C038B0211849A26674D5D5698904A9DCE362D6BD858B3848B9534B84DF672047930CF63B51D91C79321127FAC7778068E7AD26EF3E61E98B757F33127895A07BA6CCC0FF72A5D5288FEE49AD4D249B7E1B9E695B91EB147D0B1AB2CA4299F9A655BF25AD3B9ABC9B36EE98740FAE598F17113D3C8912BE694A30207E86A5633A32D2335ABE7D7267AEC476771B0A7FC8B0DE2BFE524423D0304AB19632166C790DB214D478726BC7A281685B2CC77E0BB9F8BA64245A80A5DB5570209B1FB0115EEC3CF67383F35E7C05ADC02E8A2BBD1994BBB8818646BB9B87349FDACAE5EC681D40A03A506754700665F4B372C2009711AB55D0C0D62506FD4701EC69C45EA8ABF7A20BBB2669AC460B6728B6845476F49DBCB927723DFFB7A224CA159DB7D1E63322F22BA31B6BD04DACA1E30AB53AA686B8704B483152516C94078916C32064FC638467329CA008784847275A61B44E758A6828D5377747B8848D2557DA23090865A58BB1C7E7448AB61796697DB1B5A70C881CB80A9438F13C8753D662ECD495E74B21CDFA177544A3D5F8912634143938935B4F26874231C2D58BBC0F38DAE4135955793596C4DD44798ED9A57FC178A3AE245DE19BE18C1604A06D041C5560E69093854999EB93D1F82447103B54D46383FD084907060FD756DE74B6FFB3675E0ACA92AC5A89DA53CEF6042FE0CABB55C68DDBA367CB999D7B0B935E752AF97196D465E57081E0378465CC6BA56234CCA1283E22334E65A7F56787BE509C1AAAB0942B39D58167DF5421E35B6C966965FEC61BBD8AAADA8B59DD0664DFCA12F88B92A1CA158E7D5B5B5401DA7D038CE9A70FB5C890E52A19CD32DE63219DD94981CA9B269F0C4BE40CAD533C6DB8687E4497526392B848C4BB706AAD7A68AFFB4AC3D21385A2CB4DDF369D41B6C978719C8D121D43551ADBC54F74CB3528655ADC64F62C59461C3531B6272A4AC9CA013A0203C6D8ECA72D67189DC07FCE68847F0053CA9F0F6AFC7D795AE4ECD3D8E6A02", + "dk": "E4028F81A3115D24B0661A525B546BBC901FF645B4A8D9127E500279A0B67C028DB6E660343012EEC35B8FC5B25B61374B19053D910BFC716E08517187B191582971C7A2C1564BA8B2E6C72F417681224DD3F663719032D0649C4F69229CCC9FB9E6B775D3376708704B5A715B67766CD045DCBBBF861B3170E44EDCAAB276C6190A5B188401353F61C4BBEB413811015BF273C760682F414CB74ACAE3624B9C75036BB32E6113BC59A2A9B0770E928C445B53030A8B262D34950C930BE7ABAF65376C0C90416333B2413C4F849A341BF0124CAA691CC2C2A8C328077302FBA57314E0747569BBE664339219867E42A0E1E92332A2103925CCB85C3ADD190CA3317E0DAB7CFAD92473CC5AD7C31A412417C858AA846721B268642F9641C05A338FA77ED5572A2AFAC80AB0746F07740BD8925E856225D61F73C1BE78381FFB751D6CC456FB488D143208C6E849C0DC10FE295148293251B4300FD72ADBA15BFE82406CAB7E0E4C4F7545869737B46B669EA45470BF9894BEB9CE8C57C4E18042D071C0D58C27AAB46C05446EBF69CA18E45E63039E12A12ABFB3C291692016182349DC805725334DE86E8971449EF7AF09D52089872314757110ABA0BF576C98C1A9D8355DD45A3D842455017A4156101931198920354B0BB66ABD7BC4A2741FB5B06424C14D07104460F3B1A7C54DE8BB6C7AC6091D5B7FDB91BE0A4616AA412C807799D23379756658B9F39345BC5DCF9168AC5B22B2E94BF43071D241129C06714FFAA4B74564B402521942769A391D9CB3C15F7572EE2407ABAB96ED161388C6B76346504650CBB58025155B1527850342E9354804A16626ADD0305532A6387F45781BC080011A1680716C7C1B3CF72717ACC91ECD189A5B03C7ED561DA771B68CF275684C2CCAFA8711F34104E4CFD8F6BD050B5E196564D6D710965740C9A533D1136F7009B9B69CB6BCC388CF7644681B4C2A475410934840A6AA0E316357FC8CFC612E0A57C7ECE8321264A8BE56C468E8C431A0CAE612056D520AC26847DAA4BC71BCA9B3E739D454A4C7B3808CB633A603C22644361611A9D363A407E99D55C459BA856F8295B742357B0BC7C53436A58B434A0280473775B3B3837503828B76D8BA5E182E3AC8154BC99A727A70BEF0B22E631BC56B631276898550443381C1DA223E2CB3A0C38236F35200E1F9C67EA42CA9E620D148209FFBBC07B333BB2B8013233F4C908706F87410C6829C44332C084DB2E0489894593D9627E9F370DECBA867788F9FC99B81127F6EF446412A36E3B2286FD013354C58A04B32E490B7AC53653BD2A15A096682D01689194A0232BFE522B7A85275A5834DBD105D9AC03C3B9416F344302B72C232890390D303DE975B0CE6AF800B0F587A17CA759BE4315EF9D4A3C27033FDD290646C4EBEF4964DB66BCDAB216A80737B2B674F5170B1620E868741792AC8290C1AA21B1460C61B367367A5A084800652E8C9528431AC16F73138A69678B218434463AB5587FDE45ED194B830F02996D81A2C92BC6F524448CAC8B4A5795C7A423625170DEC2120D437BFA96F0E8078771C9AF42943E8A51CC89C9759D3A92896C5494CC584559742FB564C068811ACB6D6525398362B71938C1C721695157F1A2BC24680BF6E265DE8726594C26CBAB9B040462B4DA30402D70EC050958FF5944D181374CC9A29E867C1B33CC36CBA66C66A75F44CD68112B543AEE0026D9C105EE556AD5FC2989346C7473C93E2641AA42904C7751D83CACACDA6B2175B1B9C1C41435C49027AA21119428C61482F655D4A0CCCFA5315100C314B680F702CAD99FAABEAF08335257F9380066A09BA0D4B04F91A52FBC09F3C348F0A49B840BCBFF51B63D380C53FD17DCA7B76E782580D926865A79AA4992FDCA771F4232AD68956FD1A32547588967B402B2C8E3F2264DC7BC8B5B770EAF4B413C1AC44A8A4A4061CC7FBB7ED809FD97C84B6190BCAD156E36018C44CC0C5A84E9A872EFCE63C370BB257C46AC285058FA09981D1CEF51A07C44994E68C9C3CD6394EEBC545F438858A6D18583E51DC6F15D7B0A3F02F26932928BA1F281012D93050A8D6685F5364FF952BE1C644965A3D255A57C95308E100C4AB8343E2311927212E6F7975A9FC7F72B4761B78069DC5553D740A5433108099BEBC850D5477CE3708474481026931082946A949E3B00DF640AA52BA6D04AB3C1115C91147BCC519DDE6BB953582DE996D38F35A51C7AF0AB999FD78A9B34BBB209869D3776C038B0211849A26674D5D5698904A9DCE362D6BD858B3848B9534B84DF672047930CF63B51D91C79321127FAC7778068E7AD26EF3E61E98B757F33127895A07BA6CCC0FF72A5D5288FEE49AD4D249B7E1B9E695B91EB147D0B1AB2CA4299F9A655BF25AD3B9ABC9B36EE98740FAE598F17113D3C8912BE694A30207E86A5633A32D2335ABE7D7267AEC476771B0A7FC8B0DE2BFE524423D0304AB19632166C790DB214D478726BC7A281685B2CC77E0BB9F8BA64245A80A5DB5570209B1FB0115EEC3CF67383F35E7C05ADC02E8A2BBD1994BBB8818646BB9B87349FDACAE5EC681D40A03A506754700665F4B372C2009711AB55D0C0D62506FD4701EC69C45EA8ABF7A20BBB2669AC460B6728B6845476F49DBCB927723DFFB7A224CA159DB7D1E63322F22BA31B6BD04DACA1E30AB53AA686B8704B483152516C94078916C32064FC638467329CA008784847275A61B44E758A6828D5377747B8848D2557DA23090865A58BB1C7E7448AB61796697DB1B5A70C881CB80A9438F13C8753D662ECD495E74B21CDFA177544A3D5F8912634143938935B4F26874231C2D58BBC0F38DAE4135955793596C4DD44798ED9A57FC178A3AE245DE19BE18C1604A06D041C5560E69093854999EB93D1F82447103B54D46383FD084907060FD756DE74B6FFB3675E0ACA92AC5A89DA53CEF6042FE0CABB55C68DDBA367CB999D7B0B935E752AF97196D465E57081E0378465CC6BA56234CCA1283E22334E65A7F56787BE509C1AAAB0942B39D58167DF5421E35B6C966965FEC61BBD8AAADA8B59DD0664DFCA12F88B92A1CA158E7D5B5B5401DA7D038CE9A70FB5C890E52A19CD32DE63219DD94981CA9B269F0C4BE40CAD533C6DB8687E4497526392B848C4BB706AAD7A68AFFB4AC3D21385A2CB4DDF369D41B6C978719C8D121D43551ADBC54F74CB3528655ADC64F62C59461C3531B6272A4AC9CA013A0203C6D8ECA72D67189DC07FCE68847F0053CA9F0F6AFC7D795AE4ECD3D8E6A023B1D861C34DA182BF4DD683ABE8D247898E71E95E27AF72494C02BA6FF3C8147C71F7E44295978FC63BF8F6A68F8609E98D155FD7A74E1FB7982733FBF8A6C25" + }, + { + "tcId": 41, + "deferred": false, + "z": "EF668FB41F49E82EE0FE00919CC06507548321593A7ECD1D2112342608D95FFF", + "d": "8D6DF2EB3DDAF961FE5EB556842B758BEBC7ECB312B6D4628B323F483B77D6F9", + "ek": "499B0EFC9A67CF754833785F22E7AA1AAA43EE135195F42410FAC0F90A6C7658BE53354D81939036C88A44801707CB2C743363D1623DF1C1C0EA474521979497178361A264C5C68DFD5484D6B19B1734CF6C73521266B4B5D81872F059A22C2A9219CAB4055FD8B95661CBCE716694DE5414B4CA0AB0AB3231A896AEA0883E6A6454F0025CB79894D83179F1036378A423D55005C973A297ABAD1B7321CBB89B6875F3B9522A27C83D7716B01AA8523686B3EA5F9F3722CD715A833CBB7AAC7AE3E24F1F08474E096D31EC3B608C3C67C1340E01B9780A09155C03C7971D54E0C9C7A6265C196C0FDB8E0D6C23D549708B9C2E2E7366F146C2BBC290673030BAD304B67A6133B3B22A41359262AF706785EDB44AA6B58EF1B71C69B4C1097230B90702BFD7657464991C46C4BA0775F807C0ACC14FCA9C31FDFAAE5FE525BD9538933C843764B7FC130322235823D55637B721B20B8825603A57862064517D2DC54545A0A7369270B7B15ED2B5265A401532F4ADCFFA3C94A5B6E89660530800CD317B45522AB8CA8E3EC71259FA60E97A808FC49EC9E998DC703FBCB3308069019DF8138E3B9B69D71F9FC708EB1364E7F7C2DB73765F13A53506AD03205EB5AC5DA86B24E322898B79917753839C5A63F400547D75B426F70D479A6340278D0607C765857E44A2A32AAC4A3D324BAB221FACA212E1A9315B452C5FE25EB0344138A1B191F8044C9A4CCF0901A66C8FA56AB468BA4513E8A045C6621F22719762C37C37C6E8C5C04CDA7A02FA287A2B04BD88BAE4A94DFAB47733D74B056C7541EC992372104A470B60F20E394C6994A13932236532A74B716A8D86F5ACCAE10CF6C1708D079766A7B5760474A9E351ACD6774A627CBCF10E441894940164AAC6554CF73EFA6A7C487216FFC93939561130F107E605C5A20A8B3A280F27942F7CA353BEB66EE67A2CC2AC68CD94310E8B67D597AB33368C83179F8F8124180494EC253B395114FDCA9E27FCAC8C7A0B1AE40D31581946C5506B5063E2050D0CCB6AD713024A9C4D08D09D211486ECD371F5033C8804C0531180B99447FEDB91181C327DC000E7159C1634013EC00C03C4C5ECCBA79DD138F20B4975F27946566A629A4819E7C77EE4625CD91C86615AD1A876E7045196E6C09EA22439751304D92B9C2B3C9BD32A6CE010C1BC5608245B76008A58A4A4C9072EADCA4AE103B63487366D130A5135C18FC4C6766CC8E06B988C51AFA6D1CD44133ECFD539BB0B8CE92A3FDD36127B9C03259161E8441A22F0436F9B1A0C57BC8BDC06371078A2C9548442310B4A5479F0054ABC375E75A1D170A949C91865326A76768A2F117CA524CA8047B26F7416FF677DE0BC07D518C5F71686DD544823DBB9622706FCA2A2112472C352B6BBFA0A3A7C2280CC85C35203A6DBCE3D3C4E8F9C1D454C730192968892BD257CBFC06179EADA01362BB1D1258E9F1BB563565535908803822969B3B2A21633390961891A2DC436B55EF392F0379EC484967A9068E99BAEE1F461241070342221660101651B2A2FA896934141DBA9B905E8C309F8981CC5B080C26CB585090EF97C4E01B8ECDB7F5DD88C4F8B85765B7908256D350898450C3592526E6A99B504A0D3D19FF79680DADC9890E865104DA28FE012506D19180565", + "dk": "073C0C1BB67152B5AAB7A58461B1AB82C3BFA8CBCAB360B48CE83CE15B8998579542183C8106743238809A43B848688025D2CAE11857BD75986BC0B2516552F640807A4625D6E28816883BFD48966FA2A39A3486892382BC799FB0C6623D687A2D7A9C6CC0867C2C96C162C272425C503CBB3DF71611565B43777DC805A799FCAE6895C709760689E45FB61779F1FA72EB7628CE299DECFB6D25E883D431069A3002BCE8AE00145AE57785D2F82E76F59B98FA5A5D31426DAC1F394B954377A6ADC243E67A8C05B389E3C013A7F98131DC599B6918B79C665D73C0DD676DB7A864534A536A75C108EA79CA267684812912D8711D32225550788E22A23B861C261083B9A98A3D325A08C828DA42753AB959E4C795FD370A1379C9C926038DAB8BD281AB46FB3D8C1795D6144C25CA1073F00C85A27B441034BE185B43AA0782A70EFA995FDDD35E753B226454A0C5998A8B6C0604991E3942AA699B91C6B17C67B373CDB05A48B05CBBD8B3F1B1139DCB18B15704E221179FD95478A6280DF1518FD3ACE9837E9701503476C230E582AB4BA5F88CA5ED306EBA481BA51B5FB5454BC96100CEACCE14B11A43915E44B0067C44408980CA872B568ADA7432A6B50FC6416DCA06D62B96F701BCFD7A48DB251D6949AD368779FC2858C6108D0F7C0AFCF9A7A8C0A6BC27BF76603B74438B5DB833B3AC8516EB3D99BB24BA310D12EA23FCC0111B02409FC670A1DBA9AED13849C78DFF1229B8CB4B3742046C4744BAA3067F456E8625974E3387662C6ED3B2A1B24262BC8A484EF185F222124C9B3ECAB4B7C4202C64309277B0A28B314C702B72D1C950647C6A27D477E50AC3B675593123961F941750192212B663EA79BE4314096B7A74E7517FDC6818A8C913C59C75BF6A72A2F34F6A77816B9354B48989A5EB62E250372AF04DBB56332B6545AB254CBF9867E354A8F2C4B614646F6F316A8294AE497B3B7E12B6D6953D2A764BC4A22DCE9185C7AB0A939883B2A48531B374F3C499DC746170650BE2F08D0AF4785094C96F3423DC5A8D90F536AAE1C3688353D9A67FF2E01E94CCA7E67A5F9842762B30BF8FB729D0694DAF93397A360E8C200BCF8B7A68B9BFD43159C89C6C88E389B5237CAD95BC85D366DA09BD2AB93A7E8B8CE58AB44E93680201605EF434AF729E3015A3F0F5A69C273724B557BC218360A31C88EB150A545C4BF7922852BE48972D2F479530216F9E75B4F33967214CBA93E601D5D536F8FA3083FB3E5BC6A752F9C3F87413DF31B0235ACB53EA6C96A74D5E02A22FFA4EA8805B0B721DD3A554108000A0BB6F25F4B7FFD11F4CD15F5F34201FB958A8D13F9A530E66B452FC8A160923928B2B9C9BFCA4DBF374923A301751175621A3EAAA2C046AAB0CD42D3B693E4AC19E7171A0ED87186C7C8EE4C576B9EC9A249B7B346B2119B32C78324BCA7C51497458A6E46A24B60E84CB583305BA0A3194E74A5EFA26A1E221CD85B2CD963263C134B2768C3ED37636CE59262A1969C926B29481066C76C17CF80813AA2C30100AE0F20B3C99395E9B2B3438CDDA5857F652A646777F58B38C86EA3F7BF2021ABA4B32070CC8B40CDB7B361AE3219110A00E55249C498F499B0EFC9A67CF754833785F22E7AA1AAA43EE135195F42410FAC0F90A6C7658BE53354D81939036C88A44801707CB2C743363D1623DF1C1C0EA474521979497178361A264C5C68DFD5484D6B19B1734CF6C73521266B4B5D81872F059A22C2A9219CAB4055FD8B95661CBCE716694DE5414B4CA0AB0AB3231A896AEA0883E6A6454F0025CB79894D83179F1036378A423D55005C973A297ABAD1B7321CBB89B6875F3B9522A27C83D7716B01AA8523686B3EA5F9F3722CD715A833CBB7AAC7AE3E24F1F08474E096D31EC3B608C3C67C1340E01B9780A09155C03C7971D54E0C9C7A6265C196C0FDB8E0D6C23D549708B9C2E2E7366F146C2BBC290673030BAD304B67A6133B3B22A41359262AF706785EDB44AA6B58EF1B71C69B4C1097230B90702BFD7657464991C46C4BA0775F807C0ACC14FCA9C31FDFAAE5FE525BD9538933C843764B7FC130322235823D55637B721B20B8825603A57862064517D2DC54545A0A7369270B7B15ED2B5265A401532F4ADCFFA3C94A5B6E89660530800CD317B45522AB8CA8E3EC71259FA60E97A808FC49EC9E998DC703FBCB3308069019DF8138E3B9B69D71F9FC708EB1364E7F7C2DB73765F13A53506AD03205EB5AC5DA86B24E322898B79917753839C5A63F400547D75B426F70D479A6340278D0607C765857E44A2A32AAC4A3D324BAB221FACA212E1A9315B452C5FE25EB0344138A1B191F8044C9A4CCF0901A66C8FA56AB468BA4513E8A045C6621F22719762C37C37C6E8C5C04CDA7A02FA287A2B04BD88BAE4A94DFAB47733D74B056C7541EC992372104A470B60F20E394C6994A13932236532A74B716A8D86F5ACCAE10CF6C1708D079766A7B5760474A9E351ACD6774A627CBCF10E441894940164AAC6554CF73EFA6A7C487216FFC93939561130F107E605C5A20A8B3A280F27942F7CA353BEB66EE67A2CC2AC68CD94310E8B67D597AB33368C83179F8F8124180494EC253B395114FDCA9E27FCAC8C7A0B1AE40D31581946C5506B5063E2050D0CCB6AD713024A9C4D08D09D211486ECD371F5033C8804C0531180B99447FEDB91181C327DC000E7159C1634013EC00C03C4C5ECCBA79DD138F20B4975F27946566A629A4819E7C77EE4625CD91C86615AD1A876E7045196E6C09EA22439751304D92B9C2B3C9BD32A6CE010C1BC5608245B76008A58A4A4C9072EADCA4AE103B63487366D130A5135C18FC4C6766CC8E06B988C51AFA6D1CD44133ECFD539BB0B8CE92A3FDD36127B9C03259161E8441A22F0436F9B1A0C57BC8BDC06371078A2C9548442310B4A5479F0054ABC375E75A1D170A949C91865326A76768A2F117CA524CA8047B26F7416FF677DE0BC07D518C5F71686DD544823DBB9622706FCA2A2112472C352B6BBFA0A3A7C2280CC85C35203A6DBCE3D3C4E8F9C1D454C730192968892BD257CBFC06179EADA01362BB1D1258E9F1BB563565535908803822969B3B2A21633390961891A2DC436B55EF392F0379EC484967A9068E99BAEE1F461241070342221660101651B2A2FA896934141DBA9B905E8C309F8981CC5B080C26CB585090EF97C4E01B8ECDB7F5DD88C4F8B85765B7908256D350898450C3592526E6A99B504A0D3D19FF79680DADC9890E865104DA28FE012506D19180565847F52D9587DA7DD37F7AE07BF1B9D4C94F03C702351FB4C5AF4200EFCA07F38EF668FB41F49E82EE0FE00919CC06507548321593A7ECD1D2112342608D95FFF" + }, + { + "tcId": 42, + "deferred": false, + "z": "26345937ADC9104155275E7114E93D9F5847EEA73A9359358585B2D42301A294", + "d": "DB4ED8E9C3E1AC7A35EA4B67A4EFCFB46972A984D161F79F084125D6D4AEE7AF", + "ek": "7BC585BA01AEAF899394E3C00223562CA2163F977AF21CAF967A9C174B3719B097C440A60C5AB746683F15294E4CE40031F16A6FDA79C608095EEB6945241B25A77DAE55CD95161C94836940C93665D669745A013013875A722FF1B285047C9270687FBF2310D1510680406C70CB97A65CCAB59AC6C80C4937810A2488BA8C37C6CF022E4FC14135D2100B613E3BECC8D74261C0912683067429DB79CAA56469CB537E432257EC2EAF370590613716C64FDA2A0EFEF27727E5A437000C9145919158BE240B426E63AD426018FD3271D899846E6421277C511FDB14CDF1B16C48B99080B6FA68BBFB4C02DB837C65E6CB02235412AC3534FA91AAD35DCB3AA773FC2A050975ACB0C7928201636A7920F46DADAAAAF9072F6B23B138669BA4C9655A660F3911AEDF97633ED966CD1253CD7B947C09839CA53AF33B80A370AAA43C1ED6D26D64981D756060A17331A3D4B452FC34F186986936C2EDACCBE0629DB60493BFA49451D44BDEEA1D6605BE945625654A6A6C13943B2972D0A95CC07B70196579ED9013B8CB5BEC81AA61066B5AF6673B3681B21B65905C1E44B808B1995819B211D0BA9D4AF45E6C030D75D2C63E77264BE92DDBE1B54BD54060CC4E8A760DDC124EDBBA6DD8910922D18222AC42D802A1A377C0979B3D9CF8736ABA7EF223413E6712FA523716DC5A0C41CC3CC462C6FAAD0CF30674EA8469A06B1FFCA3D6E3AF0AE95689C70F3325B3BD6C3158BC36014B836F908D91269FB5B05CE6075A80D4A70562572A64AE090C9C39DCC5C6197D84C62752E30DF9A49657DB5ACA0084393A25C6047E629151C8BCC3C4897CA2BC8BD3EC4115B8230A155C15775C7CB7A3DAD6560E6798C57A607FEC8DF6493C24A11518280F081BAB5359AD5468B1717560F1E60273518ADA29819E11679D16CD20514EE44989C62582B0E79A1C09997CE67B9E46850F294BA940C7A6668B28EB6C953C81F50C2B94F14A0DA76DE5AAC603395ABC8866B92B88890B120A62CB06CA8F0F14806E19A794F73FDBB1A9638169FBC30BF4C764F66475395515683C9CA4E587312B4301547C25B58108408E64D6BC0A6B9BA8A4CEF76649290A185BF25DF5C14B81F633A399325380A91B5C2AB21399C4C88597202A50A966DDD8AAFD4A2A831897385AA5E19480437B5E1EA05F778BB8C616391C2766F1DAC500D1898AF957E022202C33BEE93001F7E56B0589C25DDBC5CACBBDBBA308B30228C5108019280812925E395329D3A72B6566694DE690746A1B244AA21B879E54590A4173197C2C930E683F645A83F6B288D3A48D00A9CA97180AEED5685691B8FCA95ACA9136EEE892B5F46CBF60BEE6D803DDC05555349D4FD1AF405C78D6B86E56C12A26657832D753B9D901557572E7960EADE5A9110CAD2C1353A415BD119BB8A42924B0BA004ECBCEBC430F13B33F82AA1D4727CBD8150F416A14AF1A6CBEE094D0EA963CC4C814E6A9CF097DF9B9BEC7D9B68D5BB23F767F1CE88FD44B5539F80F2EDA4B887576107C725A3A5D80240397907AA15842A400CB6200325B1542E268BA3C054E350364C836370DE786E5077EBB4B4C8961917870019C7A4794D27E332C14D26B6BC02202CABC83B8E9E01A155B3D735CAB97C80992BE75623F2B79E41453AEF4A09F6CCAFFAC73", + "dk": "EE528DC327151C18138C507974649A95121F768132E6C6647F2A193556C06040C80058394883C01D75763041146349BC8FA72E57BA7069656B2D138B85784C79B11E70025D5F3558EB8BB418CC8BEA139310F850F3557FD56A10F0D297BDC0C0DC3B4916CCCA4A419B5DD6A8F8F6B0F1AB6BB2B606C73AC36C0C93267A19B7C7CB82AB9C96CBA726770C5475A6B889CAAC178B8882BFC236CA32197523E95112697F7B75248B3C12F132B45535CD55E274706242A69644429A1C3BAB673B580C7DEC34FF7379AD073241156477D1798D1AB09AA5C53EF195E65A7C15E5569781A9B06376F77337A1E56506C785F5D4C95FE05BBCC736685370648A90320C059CE45E55841F08CC8024C24C473646B128451047B44F1C526FDC4B8D862DA60A97AD91CCE133B5BF7C70CC0A23B458380602882EA2741440CF05B1C960699C8A404444A19345F113DE341279C11B58A7BB6B903DE6054D55DAA4A501741E6953739564770205571CC93861A9D5D785F273338CC90432D00B64A488B023AA5EEAAB0543CB34916B55A5CD69380A330CC194640D41048745FC74CAEA0FC8C95A03FB40F701B763E73FFF6B1C8D2434D2646BA3C870C0A29CFA45A880380F6675CA36AC1A86C57C56A16BC6E5A9ABEC7404F86209B3AEC736A8E436407D2476CECB799A880AC8AC33A3F58C68CC047480BF85258B6C1C159B01BEFC73B7BE506BF75C67DE85893DD2425C467B2F627971925FBF666B80DA59DB285813D688916109EFD2951995953BA729DF127018B7043AA3A57BA33AFE2782F8F319C754C4E91780B446C4D3360A824223657405EA34AB1DE6181C702AD100CADE0380BE942EDB51A93D1A0A884308352CB2D93B920F1B467FC306F6A6AF9E41334F861360646CEFF6770BC1B7211A1D2B95377546A0AC4BA431F824A1953BBAA8BC9CD66789E55EB2C8CCBE4B51233C2578B8115061276B48651B63097BE21BE45868EA513F69B91F6455CA569C1C26317E0E1807C7B7B2D4D43F16958C2BA32CE0585E2DD1991B357C72239817B0484B3258ABF39988933710528E82F11BB8E798CCD5C323DAA16C9C0786C1C73AE396946A0EEDE43FC7568C98D056A1766AD702B4F6478CAC056410FB9B95A9427C32A87C84BE3C9A21C0CB46567ABCB3D1CCDC3B8ABA0A1BBF18A6D23474E3659BA696197E059B6F536523E60C0C69314A12312B37CE51686B5CB742715BBC4F241ED12B342045BA69010CBD24597DA695A331C4B8E7C693157A348C9E16A0A307900D86A032E08B5E802A29842C13DC7509D432C5AA7B679BA10BD090CF9FC086E0C5C2AAAB208F39179E693645672123D894EDA35C5E32031DDA9DF410C32F72BCA22B5645E7A5A9C804A45BC67A861A6FF5C821D9CF79E6BC4D8386BF77AB31C6BDA9DC6E99866B5E43193D9210A790CAA629BAD25304E6A946B3D87235CC39F5B66EE8B4C6EA73022B867C6CDAA133A0962579612C8CAE71BA151754B4862C7193994934F04FC3BB2C20A71CBB6962C5D16224D1719555143E33A0E70B79A2D6134CE0BA1797C8A2F98B71882D5BD214E73A950C849FEA2006B242B83F5C8998113BD27C01C3276FC20041ADE77AB144CBF6368D45C18C7BC585BA01AEAF899394E3C00223562CA2163F977AF21CAF967A9C174B3719B097C440A60C5AB746683F15294E4CE40031F16A6FDA79C608095EEB6945241B25A77DAE55CD95161C94836940C93665D669745A013013875A722FF1B285047C9270687FBF2310D1510680406C70CB97A65CCAB59AC6C80C4937810A2488BA8C37C6CF022E4FC14135D2100B613E3BECC8D74261C0912683067429DB79CAA56469CB537E432257EC2EAF370590613716C64FDA2A0EFEF27727E5A437000C9145919158BE240B426E63AD426018FD3271D899846E6421277C511FDB14CDF1B16C48B99080B6FA68BBFB4C02DB837C65E6CB02235412AC3534FA91AAD35DCB3AA773FC2A050975ACB0C7928201636A7920F46DADAAAAF9072F6B23B138669BA4C9655A660F3911AEDF97633ED966CD1253CD7B947C09839CA53AF33B80A370AAA43C1ED6D26D64981D756060A17331A3D4B452FC34F186986936C2EDACCBE0629DB60493BFA49451D44BDEEA1D6605BE945625654A6A6C13943B2972D0A95CC07B70196579ED9013B8CB5BEC81AA61066B5AF6673B3681B21B65905C1E44B808B1995819B211D0BA9D4AF45E6C030D75D2C63E77264BE92DDBE1B54BD54060CC4E8A760DDC124EDBBA6DD8910922D18222AC42D802A1A377C0979B3D9CF8736ABA7EF223413E6712FA523716DC5A0C41CC3CC462C6FAAD0CF30674EA8469A06B1FFCA3D6E3AF0AE95689C70F3325B3BD6C3158BC36014B836F908D91269FB5B05CE6075A80D4A70562572A64AE090C9C39DCC5C6197D84C62752E30DF9A49657DB5ACA0084393A25C6047E629151C8BCC3C4897CA2BC8BD3EC4115B8230A155C15775C7CB7A3DAD6560E6798C57A607FEC8DF6493C24A11518280F081BAB5359AD5468B1717560F1E60273518ADA29819E11679D16CD20514EE44989C62582B0E79A1C09997CE67B9E46850F294BA940C7A6668B28EB6C953C81F50C2B94F14A0DA76DE5AAC603395ABC8866B92B88890B120A62CB06CA8F0F14806E19A794F73FDBB1A9638169FBC30BF4C764F66475395515683C9CA4E587312B4301547C25B58108408E64D6BC0A6B9BA8A4CEF76649290A185BF25DF5C14B81F633A399325380A91B5C2AB21399C4C88597202A50A966DDD8AAFD4A2A831897385AA5E19480437B5E1EA05F778BB8C616391C2766F1DAC500D1898AF957E022202C33BEE93001F7E56B0589C25DDBC5CACBBDBBA308B30228C5108019280812925E395329D3A72B6566694DE690746A1B244AA21B879E54590A4173197C2C930E683F645A83F6B288D3A48D00A9CA97180AEED5685691B8FCA95ACA9136EEE892B5F46CBF60BEE6D803DDC05555349D4FD1AF405C78D6B86E56C12A26657832D753B9D901557572E7960EADE5A9110CAD2C1353A415BD119BB8A42924B0BA004ECBCEBC430F13B33F82AA1D4727CBD8150F416A14AF1A6CBEE094D0EA963CC4C814E6A9CF097DF9B9BEC7D9B68D5BB23F767F1CE88FD44B5539F80F2EDA4B887576107C725A3A5D80240397907AA15842A400CB6200325B1542E268BA3C054E350364C836370DE786E5077EBB4B4C8961917870019C7A4794D27E332C14D26B6BC02202CABC83B8E9E01A155B3D735CAB97C80992BE75623F2B79E41453AEF4A09F6CCAFFAC7316161113DF646837A28818D9C34EDAD57472944528FFBEC6B1BD204262DCA04F26345937ADC9104155275E7114E93D9F5847EEA73A9359358585B2D42301A294" + }, + { + "tcId": 43, + "deferred": false, + "z": "63435E06C2AA3DFB3477120710D5E7FF0DC0DA68D4644A24F66A8012FB193697", + "d": "C6EFA7D5D500E5BF857D80EAE2A6EE6414159947FD4BE589350724FAE5E51805", + "ek": "B07C141713A0AAD60845A07EFCC54C4DD073348261F7485FF93CCFA7000967A24E7F03BE00D4C0AAF13995F2C19D0C92B3F372D75802891B0A97E78917301D429B0AF9C7693882024AD301C5B1448474BD2B39CBEB18332CB6252FA7920D94AEE849C10A907B5FC827B94A58E37378161A4407647D025B590D1A1C50880B2DECB17774B22D3139445588B9BC93F7020FF6A9959E9A04FFD15669F9A8CFD412EAC051B940B2ED02561A4B9F4B57753423C10DBA0587287D9DD068C4660138E6C3EDB94664797B1C702D9D89A1C9D086C1F7A21238B4A22A8F6BE9075D0B712F4567E55C0CC1BB4788F2A693D6088D36331350B3969B66C35CAEE9A015FC80CCCC556F1C034431FBCD2796BCBD9347B39C472B27CC8F36468BB10D4D1767AFF24C33ACB86D7191AB359903F43E73DB80B5F39AD25933E0645013B2AD56456081495B7036B28B652F577C1D251CCF45D3BEA72539D359B94DB50B150AA5D4E56FDC91B2654A4367C650E3E1310B72403135C185B90C5005A0FA11C569FB82A3DCC71AE774D97B171987B9D128516801B9A7D91FA6DBA6E5341A0147963BD29415E90DDDBBAACB242056E487724285BE3756C37538D60BCD7DDC44FB25AED0C24CAA663BD650CA4E806BC8A259E9794AC4642447F225BE560B541BA90C227629B2ADA4245D83E41117A095874CB676144782439CCCE1893D26B7D427CE0060A106903891687C17D636CB865EBE4C28134885CDB7722D84B0BE41638D5A14E18023191B35AE228C1EF92914A505F93901ECF598E5093E31A41611F6726C42A96DC2200C5178CC320EEEB8B223C8746B72847F9B586A229929A3B5617A54F6E56C6CEB018AA0B02DA6CBFB1278015B68BF15BEE2F223DFE4025349ACBBA505BCF592623C6D3FA975AA661E74948757000CB476757B732F8647C4F8C431C85975A09BAA591B95CFFA3D89FB3AED59330164510A303609D0726BF63479116AB2EA92DB8B89859C82D3A0966CD5348BE479AA15B6BB395165777515688D172265C7018D08D59F72C74A682290CD771C557018A686CE1B3451D6AC0D4149BAF16C871779031BBB9C4E70C9602B38A82200D2D251C5B22C60CAAA98FACB66CC3DF2A3770EE282A9DC328658A2D582B894DB7B5EDBB63A7B90788786072698C2904343A1B9F6DB107E5A6CE1129A444B3DEF542E35728F080294330343B4843AFFE144827499539B0C79B2CC29961158F61A20502BF3BB38A784BC8A673F3E680C5F8406056A035FD1A3A5E445DBAC0282E1B7885A891BFB367D236AEAD15E4F5B5CE26A6ABB4840DD177000806FA066380CD381D5BA64CBD3B048D60CCE49975EF778C1F8240A1484D073CF3B5625E23A0E02D22875465687987FA6EA8D42C5CE28443BF726551F6CBE108732DB119581CC9CFED76D6D1CCC5FE132A9B51D6D4723FE2B64C70B65F7DABB8E71C3A876545CD1AE11B835C1FA4629E69DE1D489D085575FC3A677585CA06C594FFCBD17E76162366092C03F2AB951FFB012E89446F047A4925BA350AB51C1526FD79A853B2273C2B68A590816CA0536C4C467D0918DFED84230E9AA89063530204F096B6E18C29381CC9CE4BB391D6312AA804E84B9170E59272C4835BE92CE2AEE6D55F2AF72FC20B0DD71E5A81C39766E3BD54B78372F1C6A", + "dk": "B4FC40D80B09DECC317933826E7985C4E074C65CA16B6C7184F30CF1AA705ED7CDEF878624007ED6017BF9D4170C20928A71388ECB8FD2906D612525F3A8139261419B1799040BA0F5F29BDF683E1BCCCAA819A65FD3286EA55B98B3B0AEA03972A0988E352112F0984E64A36760317EA9BA7267949BB02423D5A53EFCADEA178FC568464859BD634259C6B8AF7C2BB9A462A3F0BB66A15B2BF0956DD7829DBB2BCFFF47A40AB487E5D76A57AB71A2AC6C5B651597F631F37A9EAAE10E42D4588711B1CCF1331ADA44EF532301900A6BA2764721C81B2ABB3280672386BD64D52356737055EA8F9409756A03A5E0B410EBD4463FEA79ABF65254957447B6BCB9989F733BCD58E8CC34D74500DA128247264E0253F0EC811DF199DF1298F87A34710998045BCCB5205441EA20BFD776EC02CC70075B272533C011A25EBC541CE65B54D03149A4C04E950834D8A33996ADBE386411D168C4F735354171B3BA908A208B8B0C8DD95113BBB301D361189DA703372A7458337027C27682C04A0CE6C0C0098CAFE1594BA01787568B944C58BE9A3EE4600444BCB15376648222C167FA317866745D2495D9B30522C830B6C447F935A38588BEF31CA014C5106402933B098F8432938A1267ED4BCCBE24B4CBB45AB3317BC60C8525FB21AF8B5C35546D49A41E35ACC7B24466E1A7B7138A045BCBCB2D98C0EF242C5762CF38EB29A61AB7CCDB94880710B9E7AA0366AE25034BF131012FD0AFCF211312066A667C3739941BE616B3EE1139D890BF4CC499E6720BD00103B29A05E5B993C6B89E281760B853418A2AC0E6A278A2D2C3A213514D486D2B01AC73A8C21A01AEE891A324E2AD45338431147988799FB8D6AF44F62BC386431F3C664E9100B3E4B86B195F31125D58DB59E7858F45506CC5EA11A9902668601AF0B7599508AFAD51799C389BE4C164691515F59C4D02A2CA092A3CD06181C804AC81A651EE142866B563089BA9A6B459DAA746DBC0263E04050AB458FA97682566C3E4949ABA5CB3DE8548AF3BCE2A253F8043C0EEFC96E3E83CE3A427FAC302AEBB2AD104454790BE531B77604A910640313E5CA5EDB6AD8729AFF6C37705E2BDBC9A9917D36B1925AF45A22C7EEBA2C26544FE5821218A19207990FBE4881FB8B4CA76424FF9022C4C61D680B0F1F668B537103CAB1E1640396050CA524465A9F80221B8A3CB8CCA8979B7C85A141E26649C26BB3DF4666280961CC72060814FB6720DA96979F7E25C4A68588A00801A121E60F217D565460D7C1AD47BA858585A7EA696AFC91544B533A7D86AB68C7F81856F03135912BA1D0F69AA73921C0EC87E8B770C1C332B378A9387C0BC64A64D4FE6AB5FEC50CDF41FEA9883BC44A9175A3DFC0CCAFBE434881CA7E2B53A825ACA950AC2050B20D1FA9B36536A34E83B860850DC90B9568547B7246A115A9394455818A2B081843CBFE129D0389CFE27B192673E13C56B9FA38E99784CA5E1CC0529960534C9AC2497524948C4401259B09628A605FA659661C96CADE04B82894116931C63207F6B46675E14549DC767291B579BDA32B6EA16121B97C19BB4A90287C9B6199C904DA6B6A1278BB7A7B77405A9696493A45C8C27B07C141713A0AAD60845A07EFCC54C4DD073348261F7485FF93CCFA7000967A24E7F03BE00D4C0AAF13995F2C19D0C92B3F372D75802891B0A97E78917301D429B0AF9C7693882024AD301C5B1448474BD2B39CBEB18332CB6252FA7920D94AEE849C10A907B5FC827B94A58E37378161A4407647D025B590D1A1C50880B2DECB17774B22D3139445588B9BC93F7020FF6A9959E9A04FFD15669F9A8CFD412EAC051B940B2ED02561A4B9F4B57753423C10DBA0587287D9DD068C4660138E6C3EDB94664797B1C702D9D89A1C9D086C1F7A21238B4A22A8F6BE9075D0B712F4567E55C0CC1BB4788F2A693D6088D36331350B3969B66C35CAEE9A015FC80CCCC556F1C034431FBCD2796BCBD9347B39C472B27CC8F36468BB10D4D1767AFF24C33ACB86D7191AB359903F43E73DB80B5F39AD25933E0645013B2AD56456081495B7036B28B652F577C1D251CCF45D3BEA72539D359B94DB50B150AA5D4E56FDC91B2654A4367C650E3E1310B72403135C185B90C5005A0FA11C569FB82A3DCC71AE774D97B171987B9D128516801B9A7D91FA6DBA6E5341A0147963BD29415E90DDDBBAACB242056E487724285BE3756C37538D60BCD7DDC44FB25AED0C24CAA663BD650CA4E806BC8A259E9794AC4642447F225BE560B541BA90C227629B2ADA4245D83E41117A095874CB676144782439CCCE1893D26B7D427CE0060A106903891687C17D636CB865EBE4C28134885CDB7722D84B0BE41638D5A14E18023191B35AE228C1EF92914A505F93901ECF598E5093E31A41611F6726C42A96DC2200C5178CC320EEEB8B223C8746B72847F9B586A229929A3B5617A54F6E56C6CEB018AA0B02DA6CBFB1278015B68BF15BEE2F223DFE4025349ACBBA505BCF592623C6D3FA975AA661E74948757000CB476757B732F8647C4F8C431C85975A09BAA591B95CFFA3D89FB3AED59330164510A303609D0726BF63479116AB2EA92DB8B89859C82D3A0966CD5348BE479AA15B6BB395165777515688D172265C7018D08D59F72C74A682290CD771C557018A686CE1B3451D6AC0D4149BAF16C871779031BBB9C4E70C9602B38A82200D2D251C5B22C60CAAA98FACB66CC3DF2A3770EE282A9DC328658A2D582B894DB7B5EDBB63A7B90788786072698C2904343A1B9F6DB107E5A6CE1129A444B3DEF542E35728F080294330343B4843AFFE144827499539B0C79B2CC29961158F61A20502BF3BB38A784BC8A673F3E680C5F8406056A035FD1A3A5E445DBAC0282E1B7885A891BFB367D236AEAD15E4F5B5CE26A6ABB4840DD177000806FA066380CD381D5BA64CBD3B048D60CCE49975EF778C1F8240A1484D073CF3B5625E23A0E02D22875465687987FA6EA8D42C5CE28443BF726551F6CBE108732DB119581CC9CFED76D6D1CCC5FE132A9B51D6D4723FE2B64C70B65F7DABB8E71C3A876545CD1AE11B835C1FA4629E69DE1D489D085575FC3A677585CA06C594FFCBD17E76162366092C03F2AB951FFB012E89446F047A4925BA350AB51C1526FD79A853B2273C2B68A590816CA0536C4C467D0918DFED84230E9AA89063530204F096B6E18C29381CC9CE4BB391D6312AA804E84B9170E59272C4835BE92CE2AEE6D55F2AF72FC20B0DD71E5A81C39766E3BD54B78372F1C6A0B2CEE55AB09D33BEBC1119E3D8268D321CE675CA8233E6AEE598C7652298B0163435E06C2AA3DFB3477120710D5E7FF0DC0DA68D4644A24F66A8012FB193697" + }, + { + "tcId": 44, + "deferred": false, + "z": "8C2942B7207C2C59BD56FF9EE0B120B1DAD81B05602623623CBC7E0C20C9B709", + "d": "20859B01DFC60B6109E0234F3CAC7A247D8386099D83D2D447E9A21AF9DE48BD", + "ek": "33C5396C96C17503A1F0D509FF56A842767B24B4C3D2C080D428090E61C88EFBC69D086B83E56F5F898D99EC04F588567B2077B0270BBA8263132C7690645D38AB584C9773AC35389B88C67E34424E003AE741521545039E1C3D2BEB4BD05674A700C150573E0781CE8EEC7D2AD17F2D214FFDA22BE21A55A9570488108B0A555C6D225A521045F6D002F1B330588049FA6BA2D79B552285542BFC3BF3BCCF76D922E7AB9039189A66B76D58D9C82443A32DD26A6B134DD3783EE3480018B04DE6D9561426287C9A8F35ABAFBFC9CFB69107AFD639E9C622A3DC19D0D19EF2C4394CB10E0F519E9C8A9A40F6C33754279ED5C1DF06B065B4760453A4CEE04C67E571565C82D5882211361B0D15C9C0F8A75892A2F1A79673CB31BFF12EA352A484E6CC82B44D1C7C20EFD72F112CA0C25450C672BC34C2B8ABB84C52FAB5B0C66FC2288C48957664ABC079296401C3A470D6BB0D6B231A591ADB1763EF1C522DC95DD4E47728E5BCCBC05A73D7C856309DFEA90E25B7A4ACB4705FD29715441565682620F992034A0DA861C51873212470BEAEA6096B737235CC2C94165723495D7EF43C6327AD9ED398EDF9BE0A29B83D595AC8C46A374B4F02C4B1820095E223092498503AB926B9302C948A439539ACF3C31E91B50190980BAE4411CC652D3108302BB1C4376975AB510D12642A3098BB7FA5B6C14354D6D490FB247FD9C1BF83D8C4DE9C7DC5D58780115D7E0005874BC813B40A6B6ABD1C802C9ABA01A9D893EAEC7EC3AB011EF44AC42154AE40066A72159A9015286C2115213921AC3182372236E7059D6A352626A6DC0C1F7A728FB35A34BCE2C7FBD0659CB6496CF57455E7034E979DF8F134AC398020F153D2624980625DB9AC24707ACE0D7490335561F8EB5CB0468F88DC934B4763846535701B3671C53D30038CBB2896426AA7460338266160173798E36C0C04FA70FF68A56F52A65379031F2565CCF30929A948A6C222D610BAEE964A32C2BB4AE389C7F85ECD0BB733BA1798BA347D142AEB482AE9200B9B4C589264B64A915B3158401B343AACB256D9E8CA942A9770AC4652066B4E16414C78152C3C1D123C2057EA4FD5A511CEA8B3CAB25B9F4258020144924878CED8ADBC9B4409F34DC1F87ACC4165A0F92A8EB364F469751CA87EF9B87B9674CAD2B8628966C7E7D6BEBDBB0B4E6CB51D017EDE9735CD3C3F12B83BF9651788ECCCB2D9B237A330B13B516BB40BD806974528AD133C8E68D839EFC852F3F04E960102E8A58B40615E3D53152C528291826216125907E352CFB53EAD5A33613AA78ED20F9CA3437FD3615980AC118963C8482AC806CE6237853EEC6FF62657A2B19EB6F8678722A06C2698FD15085ADA9222D211A86B4E1BF007EC5906704A69289A8E1F6C4F49A5CFDB90C13BE4771ED4641CB4987BDB80B09724F9A9982AA27AEBFB69D984A5CC04BD94D335500359095214616184993A37EB0422A263ACBE53A6DF5B316378C22E830E2A968661A840C09ACD6711507DA822FE9749DD4C522CD11CA2E57B225BC2C398BB05A975D7E72EAA2BBBCC6CBD88721CCC762049A44A70926778340F5FB7296BC33A8C010089011CB947C5B5E299D0DB66C9C89C5C3581222435C5EAF79EB6C152255ACF9BDFF03781400C9D599A905605", + "dk": "7C63447D4668CBCB42035803A4C9350E38AF8EA8A6296658D7A545B40215A2E7C70AF7726D32CC4B7062509AB15F776E1FB812C22062ECE079492900F0B18DB3D66B4CB2B871766145E237C51023286700238537DE2187A5F45F7671027B88A7CD372A54621D52063705E1B4C07786360805E8CBAA60D9AE953708C201B70DB39DCFCC88FAA2C0FF855C30F31D9C7193616333AF72C382B92DFDE56F48E20689C2C61E940264027923980ED787CD98AAB8476C4C7511A9EC9C0B08D9523D61BECDA2054E1B01B90947AED40961C7A7FF6BBEF64156B243159E4B3D343363DBD58B2060505CB066A31C629084B9E658425BB28D84642B1E216BED180D688415C81C2BCA4A49354709F4ACBB16B8AAF8263329314818FA98FCB7139E673AE702706D3274E020BF469C651FD5A08E6086F36C6451D00ACD94CA59248FD35C91CCD856056439AF18580C066C34DCCEF1C9700DB7C8206384E25531BBAA39CB3760FB346FF8F77DE85461F7198E8C396AA8CAACB8A42C37B1879B80953C1257E82770F098C4896C76A506B8605742C58385DE754797833FD1E08D3E5B45AB828666F15608B6C81DC7166CCC678D1CCF3CE5967B57ADD583C1CCB089C02CCE05B15F810AB3A43335BB0041F0699302972E23A5C229A67578AC9D5B1061CE5B59E72B81EAE01E0740490D84AF88EB572810CEB18C17008308FC860C65B4C1B9065DF9E2C37DF9AD096C96AA0722B19106984A24804ACFB36A9925B5A32D2019E933C54579959FD536992327BE519CD03190CF9595DC5303D4A24AA7D604FCC7BEFEC4C244E7836F63A876073CB757A61B919973696BE0EC1CC15041ACDB2CD9077E15C66FDDC9343CA2A2ECCBCC3FD2319C842F0099969FFA5DB4EA416DD83DAD971197785A5C3173981700ACAC5232C626A5C52B7AF217BD45A555C4898231B256866098518CA1D379822CBEBA148412A664E5094D24D1B6D77BCA7FD176B88856659B9E8513A078A1BD07781FAF1A697A7778C2B8A4A8A0CA48FB0AD8A03E39F7753C742CCA3911B948167DCA397F935BBE0CCEB9D1AD173A8A64E318F9DCA501B031C745939DE94CDAD55722EB2F022495C063259268CF5193B486315083F3B43997C732BC9DA99324252CB503F409340B5A64E74C11733DF256ADB10631C3C002B4E46C340BB99AE3246E794ED09A5524A742DA01076A78B967BC9204F764EC61B528E97176F92F440252FC1838D187A8ECD821E996B5239A1A0F320B12F11CB5C446001D6D765CB11C4A2B24B41F23894A9945B27902A6433CC4BB5B9AE19637B5E1BCD52A29745693F5742970606A89DAB78CCCB61EEA78B0CA49D678C2477B036C48C3D2A514005459728669F8743A23A26865B04A3AE930B6E9C67148A5A2A3643DE2B837610402E6039319969CD928D39794E1311739C0780A393E076C2DC89038A10C1079275F765CCAA064436BF5052051476C1C3BD4167739E2CBE63545148350CAB4134825B2C5D27A68524BBD937957C40F1C00BC06D677E2D5527550876BD7CA3F036DC0B5625F3976BF63CDA2E9B2FD4BCBBAEB911A01B0D3716CE5369F18A285E4BCC6269B407D42A7BDBB88D724C5AA6188B9716BA3D3A3B962A933C5396C96C17503A1F0D509FF56A842767B24B4C3D2C080D428090E61C88EFBC69D086B83E56F5F898D99EC04F588567B2077B0270BBA8263132C7690645D38AB584C9773AC35389B88C67E34424E003AE741521545039E1C3D2BEB4BD05674A700C150573E0781CE8EEC7D2AD17F2D214FFDA22BE21A55A9570488108B0A555C6D225A521045F6D002F1B330588049FA6BA2D79B552285542BFC3BF3BCCF76D922E7AB9039189A66B76D58D9C82443A32DD26A6B134DD3783EE3480018B04DE6D9561426287C9A8F35ABAFBFC9CFB69107AFD639E9C622A3DC19D0D19EF2C4394CB10E0F519E9C8A9A40F6C33754279ED5C1DF06B065B4760453A4CEE04C67E571565C82D5882211361B0D15C9C0F8A75892A2F1A79673CB31BFF12EA352A484E6CC82B44D1C7C20EFD72F112CA0C25450C672BC34C2B8ABB84C52FAB5B0C66FC2288C48957664ABC079296401C3A470D6BB0D6B231A591ADB1763EF1C522DC95DD4E47728E5BCCBC05A73D7C856309DFEA90E25B7A4ACB4705FD29715441565682620F992034A0DA861C51873212470BEAEA6096B737235CC2C94165723495D7EF43C6327AD9ED398EDF9BE0A29B83D595AC8C46A374B4F02C4B1820095E223092498503AB926B9302C948A439539ACF3C31E91B50190980BAE4411CC652D3108302BB1C4376975AB510D12642A3098BB7FA5B6C14354D6D490FB247FD9C1BF83D8C4DE9C7DC5D58780115D7E0005874BC813B40A6B6ABD1C802C9ABA01A9D893EAEC7EC3AB011EF44AC42154AE40066A72159A9015286C2115213921AC3182372236E7059D6A352626A6DC0C1F7A728FB35A34BCE2C7FBD0659CB6496CF57455E7034E979DF8F134AC398020F153D2624980625DB9AC24707ACE0D7490335561F8EB5CB0468F88DC934B4763846535701B3671C53D30038CBB2896426AA7460338266160173798E36C0C04FA70FF68A56F52A65379031F2565CCF30929A948A6C222D610BAEE964A32C2BB4AE389C7F85ECD0BB733BA1798BA347D142AEB482AE9200B9B4C589264B64A915B3158401B343AACB256D9E8CA942A9770AC4652066B4E16414C78152C3C1D123C2057EA4FD5A511CEA8B3CAB25B9F4258020144924878CED8ADBC9B4409F34DC1F87ACC4165A0F92A8EB364F469751CA87EF9B87B9674CAD2B8628966C7E7D6BEBDBB0B4E6CB51D017EDE9735CD3C3F12B83BF9651788ECCCB2D9B237A330B13B516BB40BD806974528AD133C8E68D839EFC852F3F04E960102E8A58B40615E3D53152C528291826216125907E352CFB53EAD5A33613AA78ED20F9CA3437FD3615980AC118963C8482AC806CE6237853EEC6FF62657A2B19EB6F8678722A06C2698FD15085ADA9222D211A86B4E1BF007EC5906704A69289A8E1F6C4F49A5CFDB90C13BE4771ED4641CB4987BDB80B09724F9A9982AA27AEBFB69D984A5CC04BD94D335500359095214616184993A37EB0422A263ACBE53A6DF5B316378C22E830E2A968661A840C09ACD6711507DA822FE9749DD4C522CD11CA2E57B225BC2C398BB05A975D7E72EAA2BBBCC6CBD88721CCC762049A44A70926778340F5FB7296BC33A8C010089011CB947C5B5E299D0DB66C9C89C5C3581222435C5EAF79EB6C152255ACF9BDFF03781400C9D599A905605EAFE2B26CB96B97C22564B28329B64A206331FF842BFED4ADFE3C7A0C4A471BA8C2942B7207C2C59BD56FF9EE0B120B1DAD81B05602623623CBC7E0C20C9B709" + }, + { + "tcId": 45, + "deferred": false, + "z": "EAE318341D06E0801C0CA4B873520C714740AD017FE5A158D3BD40960D907AB7", + "d": "409E9F3AB58D736E122EFCC4240BF8388FDFDA6759004D42457018014A335BE4", + "ek": "E74A4568457E0C7727A53682E50CBF74082F01C9892F60B9DC57C79A82123703A8375C7EFBE299FC3352584CADA79726D8F039E7885508A897B9C54EE4478568168820DB7FFD82CBD0191FAB477199AC0FFF615475AA96E28980888B34A1E2C76115CDA09C2E1AF83FD7004DBD14AFA76773F755ACD40358A774045B09075703C2C08537C9E09727E23902CC453965CA74F9CDB865A02E228BE92850F078596F64841D093BC7BB9354E50FBFB31FD463762B800B88C6A691F22A815B46EDF848C174108DD7435F178B90690D5C8B0C430935C69C6A4451629958614CF00F5FCA7E88C08230E142C26C991F5782C1BB84A6C8750EE00348582F12365A761150B79489BEF53BE9BABB468A7F72F65B2D70068D5313D5011016CAA97C6961C554CE6419204AD28A7E5A7E807333DB1C759B6A546B087E9704B63A573752A0ABB7C702548CBF15100F3A6A807C016687C05058F76A42BAB1BE88C12FD574F4FBC051DA21234806FC279D122A4DD879175DC24E20570B435A14FAB908CFA5AA91A009164530417655799C0B379A10E7592EECA96F7AA84F9D718B95F595BF5887F2135D2BB106D599AAB77C5DFD5B4733506450923815F451EAEA6DA2FB0EF3C7AE6EB12543F8429B7B1BA00C5B05585964D334741AAAB7B2C787778709D2CBD9D1C42A061398939869FC0B21C37FA1A146965066C50889C5798B3EAACC0B5C6D7721CEDEC86BDF67A17BA37666A4226BE80EFEDC5262373117777B6995262F795735872B5CD4B52A59677B3ABFA302BA89E61DF76866CBF5C8F97C2620258570735C9B70265CB9AC98445416A6A1AA8252F89667EFE277C968101C58ABEC009902497D932C0D33F52C69221F96EB589E231877837491757BF2B05BE03C909AF3B780B8088F75610A02C45CE28097AAB34FE19CF364A865D77A9D402501C843684C1F7825C20BA3ABAF711172024FE6CB6F58591E4EEC4E40CC0CA891725927C56A55CAF5B1CC61F510ACCAA54371085FC9B03C169293E16FE74735648B4E752847CEF130A3FC031BE4C04EEC8614A7749FB7B41C2C69D2D23D73F205575655BD6A0F3FE19CF333A0F28A9BFE69B0DA112771EB2BBC30586AB0BC0176A400345986104F0832CE81A60E198B3180840A8BC528B0960CD2F26564D3797BE64DFD602BEAD0C94E1904773BCCD0162F0A17B3B4868B5CF57FCAD264E3F339C6E240C2861C6B6A0429616D88F5B41E991491652852441817033DD8F95A4B7C40EC5A74781A761D8ABEDA618D53D2CD86989AFCC54E5ED2CE26F8244E0247052364B0A11F42DC14B6B8A72ECC76754208560A479C2C104941404E22C800B0BB52E26449238235F113A23C4E46AAA4E54B6B7CD2A3802A2EBC3799B9556FB0164500C14CEC67BD36C31971291EE891134B9CB3E2DC01EF15143AC04EA1F41D9084B7B2EB91F96B7C9A97774A044E037285C820601E424F761BCCC712172B774FFB900EFF1158D6EBBE13775F27720FADB93CD98111E4E2788D86C0151B1458344025580C509738E490874B773849308B8D36C649373F9147781D58C31938B923218BC2E85F4C9B1233BCAE99D35C67DB3A85647801260409E6CF45924E4DA141B6C3A65B857A3D3DD5F476EF377E54214616593BC8CD4D05915F4F4FB9A98223663407787254", + "dk": "0D1B18A4D52F6BB6367CB50F0005BC6D9CC52E0872E86AB6B0B9132BA90A309B524E7B3EF93B696D9149CC17BF57A1A1F8371004127AA97A79E4B55CCD079470B04FF38833BBD732FE937B4877C3D643B5E489AC312271A2F9AE7B665FEB0AB13829696EF532F43CA2A848BE9787A873A4646CE5CABA271D82CBAEEFF095F153C7DD66C4484384D44663B1E75CCA0B479DEC62D7CCC97C5495D5CB3A1FA0C6DF6309A4E1B443051B00135166D77433C30B17A68B1723B83129B72BB28C61BC561FC25EEBB53E5E98C86B3B3D852B60D75402D636470E0171FC44716CCC4B9931178FD17B80A4895431492BBB1C98317E45C03D787A30A7C6530B814207C64CA1807D92530BF1EBB232460B68D52021A03A0C603AB6497F16267640316A8E5712DBAC68F3E1528A5B1E37D00856A32083E51958A265532B51DBEB02EB7820430C2974716582E92542E29255863DF251419777142691384C876263A544CE03039710B5A407B8BD7428307A739BA4B84E762C643A383B7A3CF266A1B6C7043D040B0A475B2A6402DDE1AAC192321D910553E2CC8A18CDB9D9B27C5CA0AD272F3145120A266C443A484E829DF079C98DA9CD25F4AA20B29F12A79BE03C7E86F4C3EE277C050831D8135DE1C3227627A732C1C337D047524BB0EB487EF75CA0365520C3E67324C5B2AF45A768D3986A395BFC7A65E673AA41057C8F698436C35D655A9D9FB54F441C1BF54A57E73B335D7B40EC992B4AEC0978267CA30387618C76BDB843A5461578C6938BEAAA0F8719E18469D7F76EA6FC5D73C59399689C1BAA8BA4812111EBBA47CAAD17D050B1E506247050FB62C530D0A1BCEB6D1C45C1DF048F0B14511A709D91F62BA10B4FB42591596456E2B4271FE817914B54DA4181ED7A9BCCC84DDF6614716AA561D99267DC1F8D596AF769482DE440F32B72A7B60DCB0035E94588C02CA9E8628D4A4B071007703E67AC0D87B2CD21B4502782A8BA6E201B6497C80A103003EC360374915E57154771C59ED6CA2FF272393DDC9449038B96B77E0E6C50EFCC7837996EBB3B4F1CD0079C474D9B2172E4947F2ADB7BB947090539AA43B48079133FCCBB92ED878ED76364F31CC094B68FDC371FA8DA78931C326F26961BB20F0DE742039A547C6C79B84B93CBC238C2252AFD504EDFDC14E9FCBF8051A43C75CC28897AD318CFFBE4B70A01373B324B4C732DAF4BA2F3019B5722ABB9D452AE092B89A5CCF7E8776C3222F03C50643B3FC3F8937D437DB19A10EB771FB755CD4939B73A24CFCD01BF6879A5905125C2EBC4903B8F3E91906ED479BA8B83DBC1A21BD6A8222A717FB6398AF89312170362D0486E0969F8E9A417B0C7C7069D8A41A8D9D3C3BEC2847ABC722D3851605C8671C23E0E82A96C1B1AC82C3A1DD758A0D63394F26F20BB6A6669883A87A1AB73AF02549F032A6C51E803DDB131EC47524DA9A283C39EE79AAFC78C569B07B403A89A5AFCAC7EB4400A6A8E6397B3BD49318AA5C37E13757B7145DCEC210C92AFC0186902FA74A604B7DE321488B357A8D9904913335E5A7CBE838E43309DE6C90264803F32338F92B6BAF7D89A112554F23C4A64FAA671D24201C61D8DA67D83AB37E25982E74A4568457E0C7727A53682E50CBF74082F01C9892F60B9DC57C79A82123703A8375C7EFBE299FC3352584CADA79726D8F039E7885508A897B9C54EE4478568168820DB7FFD82CBD0191FAB477199AC0FFF615475AA96E28980888B34A1E2C76115CDA09C2E1AF83FD7004DBD14AFA76773F755ACD40358A774045B09075703C2C08537C9E09727E23902CC453965CA74F9CDB865A02E228BE92850F078596F64841D093BC7BB9354E50FBFB31FD463762B800B88C6A691F22A815B46EDF848C174108DD7435F178B90690D5C8B0C430935C69C6A4451629958614CF00F5FCA7E88C08230E142C26C991F5782C1BB84A6C8750EE00348582F12365A761150B79489BEF53BE9BABB468A7F72F65B2D70068D5313D5011016CAA97C6961C554CE6419204AD28A7E5A7E807333DB1C759B6A546B087E9704B63A573752A0ABB7C702548CBF15100F3A6A807C016687C05058F76A42BAB1BE88C12FD574F4FBC051DA21234806FC279D122A4DD879175DC24E20570B435A14FAB908CFA5AA91A009164530417655799C0B379A10E7592EECA96F7AA84F9D718B95F595BF5887F2135D2BB106D599AAB77C5DFD5B4733506450923815F451EAEA6DA2FB0EF3C7AE6EB12543F8429B7B1BA00C5B05585964D334741AAAB7B2C787778709D2CBD9D1C42A061398939869FC0B21C37FA1A146965066C50889C5798B3EAACC0B5C6D7721CEDEC86BDF67A17BA37666A4226BE80EFEDC5262373117777B6995262F795735872B5CD4B52A59677B3ABFA302BA89E61DF76866CBF5C8F97C2620258570735C9B70265CB9AC98445416A6A1AA8252F89667EFE277C968101C58ABEC009902497D932C0D33F52C69221F96EB589E231877837491757BF2B05BE03C909AF3B780B8088F75610A02C45CE28097AAB34FE19CF364A865D77A9D402501C843684C1F7825C20BA3ABAF711172024FE6CB6F58591E4EEC4E40CC0CA891725927C56A55CAF5B1CC61F510ACCAA54371085FC9B03C169293E16FE74735648B4E752847CEF130A3FC031BE4C04EEC8614A7749FB7B41C2C69D2D23D73F205575655BD6A0F3FE19CF333A0F28A9BFE69B0DA112771EB2BBC30586AB0BC0176A400345986104F0832CE81A60E198B3180840A8BC528B0960CD2F26564D3797BE64DFD602BEAD0C94E1904773BCCD0162F0A17B3B4868B5CF57FCAD264E3F339C6E240C2861C6B6A0429616D88F5B41E991491652852441817033DD8F95A4B7C40EC5A74781A761D8ABEDA618D53D2CD86989AFCC54E5ED2CE26F8244E0247052364B0A11F42DC14B6B8A72ECC76754208560A479C2C104941404E22C800B0BB52E26449238235F113A23C4E46AAA4E54B6B7CD2A3802A2EBC3799B9556FB0164500C14CEC67BD36C31971291EE891134B9CB3E2DC01EF15143AC04EA1F41D9084B7B2EB91F96B7C9A97774A044E037285C820601E424F761BCCC712172B774FFB900EFF1158D6EBBE13775F27720FADB93CD98111E4E2788D86C0151B1458344025580C509738E490874B773849308B8D36C649373F9147781D58C31938B923218BC2E85F4C9B1233BCAE99D35C67DB3A85647801260409E6CF45924E4DA141B6C3A65B857A3D3DD5F476EF377E54214616593BC8CD4D05915F4F4FB9A982236634077872549E2FE7DD646C145484E163D6C36DC6EA5D802A0EEE6ADAC932C20FDAABB8BDD1EAE318341D06E0801C0CA4B873520C714740AD017FE5A158D3BD40960D907AB7" + }, + { + "tcId": 46, + "deferred": false, + "z": "EF38264520685080F52975BC957C5FB609FB0E1BD06D26F572CC5425CAE7DE5C", + "d": "CE2CACEBD54AF1B4E71588DE9F22A6AF2C2E2AD7FD66B9FEC0DF19182E7F57EC", + "ek": "3F476A07BA0E59113595E59410B41C61CC5D509895725A7010E20C83CA906EA13C1C58A604F3A2590727D3538ADB2754B879A3F2640C929388DF38A559108A5519B221E3A2DA515EC34B7CDFD704A04C18DB604CCDB2705CF273EFD4B464D4A3A9773FBBD82840C002D8529BE9377009F4558BC747AD33BE9DB2C290EBBE06972544A827BAC51C131684FA3C0111360F59C72E5D1660269672389748E2B8546E648DA50BB8243B832C150ABC1277B4F7A350028EBEA582202917B8247E4A054C84D31B7BC97837C5117D796655A098C1D26BCD6C506DA164F362CD3B231C089371E711890B795B2DB0C5E916A3A169060969001BD88AF165021FBC9B1D649F9A740CC48AA2EE0348D46394C48A776C040D18D867F3506962E4B619C21DB56C9B3042ABD1B78BA814064979C643E6CEB8025B4289BC1716C6E07873B52C545A9488102200E2877C24806E15F790FF15C9677882EAC857C620297B9B9155044D9C26626F6B97FF8491C0FA33742C785DFB3D401BC0B8C50D17D857A13C4918BAB9BDF5BC8695AE1C581334559E4F83B076CA492DE0A9D97409DD676B051C7C97E9655E2BCFC0E88DDB85480F1A5FE60C7E5A002BD33B0F13F7B4897A9B2D3B140468B9114BA041D952B08B340D2B3B970BA44738BDDD3CCFB3039F7C04C0264875C9B0B5B05115C4749B29DB6BD801328DF89307307F6689A43F72C83940B3C7D72BA35B812C660DF39A329867A9727119BD9A379C6C39522B669B461F7C6A5383C23289B4C065862DFD430E7D9B4385401CD870228EE1828C9660F1CC2F9DB63E5318A97FA8AD4B693505B859C5FA86816473080C4AE6C297767A210D355A4DE59AF60844227781BF7B3B09C624C8587B0C2A200BA1196F5C84B99630A03B07C86A1BA50C002E523C8DC498BB89A4DE17CC8BD2A1DE3250E282961C956C6B197904C1269080280E2CC636112CCFE88195536E52D84AC33332C7612A4FDAB8BBFBADA5149E05F1CCBF28C706E5B037F65C7EA47EF5E1792F90B7BA4C01EA027D54AC44C60373EC931BB5E5772AEC45581C613D1497D227C0F65470C05187FF214593B44EE8CB18BFF8195365BC56B3608AD6B228E755D8F52449E7A15E81A26E372E1DC19DED021088B8A2247A33E0C1857C22CAC798575A7ACDBB09B4A018084293CB2E766CB2A8C5D1845B0B878F74BCC41667AD93137B66F352453051EC360559402CED1A1A73EB9D45A97589E05A5C991082F3498D1A75708A3FE582B0EE3B95785C73F7679B374095E1EB47567C41E630A971D60C7A6B9A02C372A9A56B0206144DA6556EF37DACF9002CDCA7A3DAB5319259E06B7F5473643E975BB93B079A451C5AA87CC0B8ABCEE48BC1448482F9769BB27EBCE597214AA73CF8734B9C6C3E79A53FD83F120C642A690C8220008D834DDCB99DF152C8456C817E106717B5CAF96262F2CB3D33892B1506C18D25B065C0CA1017BA4D466D0AC849A112C42E218C7978A14F362BCAEBCA9A5602F1C96AAD325C9BDCB6420B76926157C02A4CAA659134908EB024CC88387FF64317354B87D7383A7317643D71713DA3B25F3B939B060B6BA0CE5838697BDA102310AC67A1080B0C11C4FBB44701CAF7A360730F6EDECDE8635ABC55FAD14FF51E2A271F7D44190ED0D0BA95131BE7DAB95F", + "dk": "9F487527A4789D287401760DE02688DE23B049C0BB20DC05AC651478A591D4178C7E25CC578832B05B1E136BCFB28157AC8A4D75BBAE195CA628028C2BF806EFC1A132D93F40850D64445BC892CE03159E1376A1701C171AB6B18F437184C671158CAF77A9BA9B1B63EB4422011C7E0E602273D94C42820666E18313C61844C403F7127C6E47B17A41C7970CAE2BD78E8BBB353451269C13628C605295AB52F263C655831AE338B1B71AA25C195FB1096E0573CC7AEBBDE9E7751B22A74726354E88322F1BC2FDF03E65342F06C6359B672E679C25FBA03840FC53F147B9A778AE421506C09AB17242CE41735E2168044EF95EC4C4410AA284B79B5B9354C419B5A9663A7C3DFC155BC57A04AB22E7578059994D33D8C76C578C7A98B5B7351D5850BC48820A199B3411350C7DF650B9D1A3E8EA2A0C32A9E88030D4AC3C22078D4950CBBBDA707800293F487D023C6476223FA5DB85E229BEFC13B6B98561EA80C30C8BCD3A48994D255AB6A134AE25A40D4B719BE2BD4FB050C477CA417406FE9A3197495CAC610D6E861CC5A6CFF7BBB8BF84B71701CE6BEB77F273505559752A6B96133A5776B784343797DF2C024C41A9E05ABC38688ED303C5A0553232D2721A13152E9A0154152BD561AA7C1991887912DD79235A8B6E04AA18C1A903280417E42B07DCC0310067BC40633FE441082BF78FE4859D8892A973B78C4F9623EF88C05901AB6C1A039C494CCC4B542474C4B369386842726F13C62E72339A37B472B538FC881711CBBC32A88D72FC93C0E2A8362C7AD8D236C2EA6724616040D799440228EAF306B655754DF78FE941315D419342B426CB273FC4604245459367F30A6A071C4C73718ED1019B1BAA65F273D665CFE79A8967A60367F470BC74C7881A516487BB1A4B4FC38AC6CC21CFEE071CB67119D54A8C077BCBA3E3103EF8724CBA5406519122EB9884F645E7248FA64489FD9763459275BD80787681433C1219C5B31DE587487FD10112274C196A4AAC7794F28A0DE98A8852F37E96A0C0FBCB5CA3B8A33678C71E469B0BE1B7D134100D8A4DA009503F800A56714D06D6BF5ED7A1D1AC8ABA3B458FDB6DAFC28EDE9CC7744A7B3353CD36569A7DF2CC0A4726E5B8AA01093A9B7994B9473E12F346B992C718E825E8F1B05404433B20AE2B464CAC95BD0833C313D96BA607C09998929776A5DEB17D259B4D14E6C1616914B07CBEE1000D11BAA276F64663F23D5CE670C01AB6BBBC9A5BEAA07994099250A54BE9A164EC67174B8C83E7115A72756164491D233A0B38239A90ABD7DB1DD0EBAC93327574DA1B242B4B98B794B8B77E5C9B684F618111EC8A259279A867066B43C4D4540C92FC5E764276A1DA8AFA378F3287C7EDA09A8FD41A8495566E5B1C8C4260EF96B123160221308E97E23F7D6B281EF94F5315CE86F8768FA2270E8953F1851E20A790F0F60ECB03AA414600B7575109FC1632FAA73E173987FBC2EB3BC94B7BB2BEA78ECA17AAA9416CD2905845DC699236517F3A45B06975EC19544C4792E9248C1FC59709C460E907031F831326867FBBE55CB32627822187D93740C2DA9AAA8606FE5979D340B97707144BD437C70C768D292CDA79C23F476A07BA0E59113595E59410B41C61CC5D509895725A7010E20C83CA906EA13C1C58A604F3A2590727D3538ADB2754B879A3F2640C929388DF38A559108A5519B221E3A2DA515EC34B7CDFD704A04C18DB604CCDB2705CF273EFD4B464D4A3A9773FBBD82840C002D8529BE9377009F4558BC747AD33BE9DB2C290EBBE06972544A827BAC51C131684FA3C0111360F59C72E5D1660269672389748E2B8546E648DA50BB8243B832C150ABC1277B4F7A350028EBEA582202917B8247E4A054C84D31B7BC97837C5117D796655A098C1D26BCD6C506DA164F362CD3B231C089371E711890B795B2DB0C5E916A3A169060969001BD88AF165021FBC9B1D649F9A740CC48AA2EE0348D46394C48A776C040D18D867F3506962E4B619C21DB56C9B3042ABD1B78BA814064979C643E6CEB8025B4289BC1716C6E07873B52C545A9488102200E2877C24806E15F790FF15C9677882EAC857C620297B9B9155044D9C26626F6B97FF8491C0FA33742C785DFB3D401BC0B8C50D17D857A13C4918BAB9BDF5BC8695AE1C581334559E4F83B076CA492DE0A9D97409DD676B051C7C97E9655E2BCFC0E88DDB85480F1A5FE60C7E5A002BD33B0F13F7B4897A9B2D3B140468B9114BA041D952B08B340D2B3B970BA44738BDDD3CCFB3039F7C04C0264875C9B0B5B05115C4749B29DB6BD801328DF89307307F6689A43F72C83940B3C7D72BA35B812C660DF39A329867A9727119BD9A379C6C39522B669B461F7C6A5383C23289B4C065862DFD430E7D9B4385401CD870228EE1828C9660F1CC2F9DB63E5318A97FA8AD4B693505B859C5FA86816473080C4AE6C297767A210D355A4DE59AF60844227781BF7B3B09C624C8587B0C2A200BA1196F5C84B99630A03B07C86A1BA50C002E523C8DC498BB89A4DE17CC8BD2A1DE3250E282961C956C6B197904C1269080280E2CC636112CCFE88195536E52D84AC33332C7612A4FDAB8BBFBADA5149E05F1CCBF28C706E5B037F65C7EA47EF5E1792F90B7BA4C01EA027D54AC44C60373EC931BB5E5772AEC45581C613D1497D227C0F65470C05187FF214593B44EE8CB18BFF8195365BC56B3608AD6B228E755D8F52449E7A15E81A26E372E1DC19DED021088B8A2247A33E0C1857C22CAC798575A7ACDBB09B4A018084293CB2E766CB2A8C5D1845B0B878F74BCC41667AD93137B66F352453051EC360559402CED1A1A73EB9D45A97589E05A5C991082F3498D1A75708A3FE582B0EE3B95785C73F7679B374095E1EB47567C41E630A971D60C7A6B9A02C372A9A56B0206144DA6556EF37DACF9002CDCA7A3DAB5319259E06B7F5473643E975BB93B079A451C5AA87CC0B8ABCEE48BC1448482F9769BB27EBCE597214AA73CF8734B9C6C3E79A53FD83F120C642A690C8220008D834DDCB99DF152C8456C817E106717B5CAF96262F2CB3D33892B1506C18D25B065C0CA1017BA4D466D0AC849A112C42E218C7978A14F362BCAEBCA9A5602F1C96AAD325C9BDCB6420B76926157C02A4CAA659134908EB024CC88387FF64317354B87D7383A7317643D71713DA3B25F3B939B060B6BA0CE5838697BDA102310AC67A1080B0C11C4FBB44701CAF7A360730F6EDECDE8635ABC55FAD14FF51E2A271F7D44190ED0D0BA95131BE7DAB95FA5A66716D011EEDF9E6A541F9438F8309660657EAFFCDB01A172998E56D9A60BEF38264520685080F52975BC957C5FB609FB0E1BD06D26F572CC5425CAE7DE5C" + }, + { + "tcId": 47, + "deferred": false, + "z": "17E5AE70771674BE8903CC21B3A90248D993C261B6CEEF2C747873D113869B55", + "d": "7E03015C5D55FD9888E730C1E60F90C5F6C2E3B1E8C7C08D869F0C1D15B540ED", + "ek": "BE62BD6BECB1FBA42DCEB479C8B8AF9D740F272661045437E6D0C13BE05D87821365509758B075C7D15A421876CF83C9BA1458F3C2B85002238DA64ADCD77FE7F1B33F3798B6C87609708DDD1C4F41AB9781A3BEAE2910D3D0A2496927C4907139CBA8D5B791FEDA3CD472538D9AC0FB9895DF079AF86B439096783D2BC6E967C211B3969B876CC0322E59C80A761495F50567276349EA736A43E5BAF638971C355FA4D3621FC60BEF5408067B5968E56DB7F2A2438233EED3AB2792443618A535389E3E7A3A1C061A8AC72423508C2747CBA968B7220911D0324522CAAFBBA85B5D1A830FBB0FA20CCF10F78656B512B34B28815C23DF718AD044937BD73198798858E41FE5AC16EEF5AC6E234DE5D7AA5AF49ED0BBCFA35843C7753613988707C2025F8654A9C8A37B4320BFD243BF8B1143B2644A715910C46DA9C88AB8F033EA233DAF3660F8630ECE308DE44B4699D6CEAF275065BA4DCA584026D261F753CCD0A860F705201B64B32F159C86558E633312DB15C2C3164889F49F181435A1877760C50206816F3502CDC3229107F92355467ECA127B51912EFBC911C5591DEBECA2AA6015274382BA5734F64B08E1160A4CDCA78CF722A1A31A590B5E90185AF809CD39A56A0D945BCDF0769E923C45E52DE4B45E2E22093E856FAD9B9C00641970B31BC0481D91884782D08979AA02484CAA2957CC6CCC4434EB5C814973B7E3A284DBAB2EC068A5DC047336CAD2990D37231604C584E05C689E30CDCD7668BC764E3D96184E7C45D6D988AA9B03CD3275747B2E1F0C68CB76326F263EBB910366D6C4A94A8252F6BA0F5269531188811A7286D6A2AFA3158F8243B7695805B8BDA1322B1A30049C684C6DCB574C20A9574BA78677B1135135ACF200A22749115C7E1BFB6A1614A7BCF612562A3CF6702742F586B6F55169C5AE1D14621074034C109518C86EBF191881D4B692E4027BC9C195E20F54A36B8387845F47BF23482359D90BAAC0B24E091D6937AF4049A043529EB884189D2B6FD4B05473E3696512910E9189C1508DF56450BFCBB6E97747AFA545C64B346CCB04B6F30733A1071BB84DF18A2A762460F8E6A1D9F0AC2840474FB61FE7087818F6A53E7CC799B0508CE97D06987E24BCB4E4B559161C5F1AA628D68B129CD178CE6069236C863AF8A2480C149EE5754AC04719E01D86855201554F922167B623236B417FAC5948D182B12E8210FBE23FFFEB81AF88532F0193FD61BD82D59FE646209D39AD75831EDC605AA6485CE90023DA218CBB19AD8FA858E7A661D85A3ECD136809E70B25F166339C307C350E4D5303AC844257872A2845A7F6CAB996918AFEC669C9A19D43F72A5862BEEA66AAB0D708C59C260DF09EC0BC2A265A311309CCD2ECCA4FEABD6176633863A71D75B0E7957266584D000A6824D467EC50421AA1369193B418072815562928D35C16227D22C821A8552ACD83A513AB683CC39D12537DC4456E1476C4ED9B4014C42A7BA6A78C9B72F3437228A918BCC6C13FCA16BD04C7B2B277AA4C2B903517FB8397598554C9C8885380B4199450A46635E7B4B338075E15DA4A3630862CDC2B811578626C5BBE0B73C0F375376708B4D8654560782F3D56064B96E318E3FAF0D63CBD17F9966EE839107DD8D6530A49F344E194B7", + "dk": "4CFB54B237989DB51A1AA97F36A3B2F4337F46AA0D2C05BB1D043A5513CE6FE84A98D62251360EC740221D1B7BE04098FC37A4AD633E95332075394E1C09AF426C146BF34290F50F318B48076653E9E66E972734CC9422750202995305827736D1F03464F37F8E468886CC8ECCD74F14706AD940B1CA73257451898ADB1476D0C813A0B06648A1DBC3150DC742D4B4CAA8EC12770974F87020B80BA9AA5274E4C63B747051AEEB5A1CF310EBEA23F17035DE2B4D51C226766ABD33F9443AFB1B21563C70E431E4D579E1AB26E5F6A2792A8ECF158C53C737F0582CCF50320FF65E634B26D3F9438E94981927ABBE2899DEF3055DC8AF679569A7AAA9FA4152697454D6DC04E2B5B2A9850AD75A1B9E060F11D817152C043500CE8391C0438BA1670B19D8333881647F5ACB813CAC66AE2065A603457EF3535B7338F32759E95923C4EC84D2248A66802D92A01EFA16CA74619C771048C1111ACF6BCD1508C667CA8C471409FA9C37F4A4AE23D505B9291511C1AD7996488CF7C611B7B3CA3855CB293BDDB19B7A1614017B1953BA7A218C50236A2F7D1B3B39BA1399D251D4D6394BDC244AA9C6A6A29FE0502E9563BEEEFA6066D5A9E52000BE59CB2D246E8A559A3B7B4B2E956BE12C2A6EB4C7156324BFA17EA8DB75A844234545147AB0AF65005D7E2470D71453224399F6C51A970973CCD3339C270A5615528FF1968811C652BA8A991C13FDFCCA4CC661F7895F54BBCC07E95E6AA6178BF56FF496C1F3576A42529A69E713A44A2C9F5B7445F794996C7F944325B34574FF364357910863D99060544606A619515B7103B76E2E4869300750D4766834750FC7867A0D98470AA502193131FC7C001B49A102AA135C7224E937973CB02BA1118520833892327428FA88BDE81E3A19BB030C6EA7E6BA69B7A82F6B20F19CAA2D20507ED3C2BB0A4BF814263D17324814017F7012EFF6886257615AE2B896B045231455235C09F706235A628FDD27685C6491EC91A1C8803BC6820C9788AE919C466F836C8CF50512D149F47322398226F7B791E568BC3B6C3E52B021AF3976E9562F582734796977890AA62DE021C0431527C7C15F4AAFCA3AC6B5B61DBED8652644523029495E268890F36E145C2060B84E2C110DDC0018F2678F99726E4A981D258C14BA453E73858492E786E5B96F6C31687E702D95110A68A77E7847C9B53C181E34434C2A51FEB36DDA926F60556202371A52A04391E662A26289A80774273BC8477968D76717BBAC9D5028965C9A9D537005C6A3CADB62206E5B2E7DFA877411C6DFDB1337FC6DFBD28BE42B774746C625D41D7ABA2D29E21ED3E13D1BF5AE3A12BB25650B480C309079CFC2E1C2114B6618E9BCC0B73D5E4202C992CB375B3A8DE0A35985C235B314DDAB4C4B888B216C761224780F885241F0C1F62837B247B06B719FA4AB85E9B63A52A947972C0678DA85B2298E81414AC5B42D41E04171438A25B56AB30C61DEEA1328562079131A52805C63DA0B8A6C324D56BA6F351B6D91041772A227B17384131A30BBCB9367319721C48743C7A9786252749082623780E4828601AB15BC08A9E103C5170181B0240EB4C00B7B085ACA634626B4069703BE62BD6BECB1FBA42DCEB479C8B8AF9D740F272661045437E6D0C13BE05D87821365509758B075C7D15A421876CF83C9BA1458F3C2B85002238DA64ADCD77FE7F1B33F3798B6C87609708DDD1C4F41AB9781A3BEAE2910D3D0A2496927C4907139CBA8D5B791FEDA3CD472538D9AC0FB9895DF079AF86B439096783D2BC6E967C211B3969B876CC0322E59C80A761495F50567276349EA736A43E5BAF638971C355FA4D3621FC60BEF5408067B5968E56DB7F2A2438233EED3AB2792443618A535389E3E7A3A1C061A8AC72423508C2747CBA968B7220911D0324522CAAFBBA85B5D1A830FBB0FA20CCF10F78656B512B34B28815C23DF718AD044937BD73198798858E41FE5AC16EEF5AC6E234DE5D7AA5AF49ED0BBCFA35843C7753613988707C2025F8654A9C8A37B4320BFD243BF8B1143B2644A715910C46DA9C88AB8F033EA233DAF3660F8630ECE308DE44B4699D6CEAF275065BA4DCA584026D261F753CCD0A860F705201B64B32F159C86558E633312DB15C2C3164889F49F181435A1877760C50206816F3502CDC3229107F92355467ECA127B51912EFBC911C5591DEBECA2AA6015274382BA5734F64B08E1160A4CDCA78CF722A1A31A590B5E90185AF809CD39A56A0D945BCDF0769E923C45E52DE4B45E2E22093E856FAD9B9C00641970B31BC0481D91884782D08979AA02484CAA2957CC6CCC4434EB5C814973B7E3A284DBAB2EC068A5DC047336CAD2990D37231604C584E05C689E30CDCD7668BC764E3D96184E7C45D6D988AA9B03CD3275747B2E1F0C68CB76326F263EBB910366D6C4A94A8252F6BA0F5269531188811A7286D6A2AFA3158F8243B7695805B8BDA1322B1A30049C684C6DCB574C20A9574BA78677B1135135ACF200A22749115C7E1BFB6A1614A7BCF612562A3CF6702742F586B6F55169C5AE1D14621074034C109518C86EBF191881D4B692E4027BC9C195E20F54A36B8387845F47BF23482359D90BAAC0B24E091D6937AF4049A043529EB884189D2B6FD4B05473E3696512910E9189C1508DF56450BFCBB6E97747AFA545C64B346CCB04B6F30733A1071BB84DF18A2A762460F8E6A1D9F0AC2840474FB61FE7087818F6A53E7CC799B0508CE97D06987E24BCB4E4B559161C5F1AA628D68B129CD178CE6069236C863AF8A2480C149EE5754AC04719E01D86855201554F922167B623236B417FAC5948D182B12E8210FBE23FFFEB81AF88532F0193FD61BD82D59FE646209D39AD75831EDC605AA6485CE90023DA218CBB19AD8FA858E7A661D85A3ECD136809E70B25F166339C307C350E4D5303AC844257872A2845A7F6CAB996918AFEC669C9A19D43F72A5862BEEA66AAB0D708C59C260DF09EC0BC2A265A311309CCD2ECCA4FEABD6176633863A71D75B0E7957266584D000A6824D467EC50421AA1369193B418072815562928D35C16227D22C821A8552ACD83A513AB683CC39D12537DC4456E1476C4ED9B4014C42A7BA6A78C9B72F3437228A918BCC6C13FCA16BD04C7B2B277AA4C2B903517FB8397598554C9C8885380B4199450A46635E7B4B338075E15DA4A3630862CDC2B811578626C5BBE0B73C0F375376708B4D8654560782F3D56064B96E318E3FAF0D63CBD17F9966EE839107DD8D6530A49F344E194B76A22A9BE6B0A57E59B2F2194C4AF45A76286DAB2B0E0FE8DD37AF72ED021ACA617E5AE70771674BE8903CC21B3A90248D993C261B6CEEF2C747873D113869B55" + }, + { + "tcId": 48, + "deferred": false, + "z": "BF83E3048B021F22DB57076A885729F95119CE63FAF51A69954BCCC51E014686", + "d": "8590BFC9A6FC25EE7E6DAB4870DBF4B51A1F141B7C9E96230C0403E799BC68E0", + "ek": "1CD8880468590163A4B0692D9569089E24873F9A5738826AA8A326B3D013C0F0C65B41CD81A42290F628F174006E08C3CDF9B012050C2FB083F97A7770F8A3B120972676C6944B06320A56605409E33535ECBC1B1EE6201A457309102D845CC631450C2D802FD62A793AFA82C0C9BAFFB22F8FEAC2B9680DA32A51AC1C75F7E3899FA01471F9668DEC6CD765221E765D7C714D46085CF9B9B6FCC2891EF16E246489CE87B9028A5DEC713B84594847A4554AB4A39985213D009C617C0524217AA1A51DABC9CBF689B66325517726CA3E955F742126F13B72CE936EE1CA2D913B785B4704F975C221437C6A890E354810E27B57689A8564DB22783B3D46488F8646B50C366BE75566EDC0422C2784B7A33D10588BD83A89A07519B754C1EFE901FA9001C0B120A70C0BDC8CC5342C8D20281B8A7A24FF4240FF6990BFAA3197CAA594F63EE4C75B3014AF834BC4FB8249604855597B5ACEF45304D75C035981A8A7267FB04867E9C28EDB8BA6C64BC6B70B218CC738B097FD6527915018EBF712E7044BC7B50CB9151395814278089E9A003965B4AAAE46A19E5791331876B985BF23DA8BE19CC4EF857C98C91084C1CF0441A1B212580E271FEED51C98D88D4003B909B42627860E5B788F99521CB3953371F1686A437A2F3055F8D05B7FB01BA29886DD28A7269A99DF979DD80BCA5D399AC18A919985C643D68910F9C0C5923CC3A30C25E8B9F71935503513AC28A520D194CFA7129BD2A08CE76491B886B7531ED100700EA011D09319EB66B8B44A0C09913A0E40A2B1166DF676C205E648872386A221B45A428B9BDB0C8281032D52C22028BDCC96AC2CA6470F407F98D479ADE32B1D202F1F1141C3E6453084B551554989E00BFC2A44E7F5ABC8530FC174B6FA30B3F26B5A467A39322612B1C9C3CE01CFC540CEF912058FBACCEDD8BED38AAB401B88EE7058195CBCB7D8405CB71DC5B44EA19B34C9D1652E7192D50A03136BB87CB207C9DA8ADD47AD870A3AD5DA51B5E8874F71560C5490AD7137522823B167166E89BFCDD3492AB836ABC952A5E957E7A0CA963A2C697AC1F42664D7379E6AB2361D657D47CB34236B70F9658E71FA7CB2D51BABD2C67187022380335D9014176BC52878C1CB721CFA6B63FB92C55A9A53EA635C7522A93DF572DF5B01E4C4931DD47ECC73514EB5A6085206B79209A712C60BA4B338254411D08DC7C289E00C0C3F230406B47CCF4183D97005A0687F6BA6B7A02A4E9E781C99C28DBA8A32DE80AF53075CACE4629F03872F3606228335424A1311BB58BA3309D4087F839960DC3CC63D83832F0768BD13BA41EC2ECFB03D882799D10653A4F6BAEF00709169346FB83232F9685E309E36B23DF53AC8D0996FAF14440641AD59E3991054678596849FA44436454BD535A2692922A3C57BFFDBAFE0913240EAA29646A8B5E7461C269F58F92680401B70A82529634325D128AD23A452EC9A5E52A622A524F3205B6E9130BAC6830C3B109164A65CA9091226666DEC395AA63B0899BC6C798F86F74E3E5265CABC600C193AB7D1AAD5085D2C198DE66A4BD4649A26349AE5C88FA44BAE97B91D2A17B8578942B7D61E25E367CBDC29841B0116458C97F72499AE6B74006261E57B749B66ABDF0FF71F8CCEA4ED010C6A97739D7351", + "dk": "F14A379CCC4C2B873E4C6366D676712F1B15BC620AAE40C3B6F31739FC2889ECCED39507D9148082B2B37C70BF95E42A98CA9B13C52A22604644839DA14B67B3BB472E376F52E20641E06E3E6104B551353FF24646C97E0D1C8A0008478158CCE8E8B6D522896A395DD8F6AACED41A58D3A9C0C0BB23C55484A9CB9BE11E9BF370BBF045505C99A08C6D8B62825D1020B3794999F63BB083BDF260714D16ABC01C741C48776067C373CBBD24558A1A4938C3369955EB0D8673C1323A243CB72781C68BB64C1E754C702C832D68F5C0A1E1A1CA04A0077955CF131B74CAA9BAE30284BA467AAC056CDB8F47B5848CC03383B275C4E62B34881E8FF504E30893A5A7C6CD9038149C0F83BB0410578A3BF42A7B7BA7CC174ED0613FEBB88E5CFC7A8E9204D30A48D4C33FC0752169874963A88A1019BE594B502FF4A341D3C59E14100AB3773AC43A92F0C901A04A1FCC256DDB73D6F97AE58ABFA75528E6CAC933E2B3A5A84F8C24137670C531E6BE9CD9758BC5BB043266A22104825845196895D6966577325769220775C9C2B480C36E6C2C18B7255BB5277CD40DEA96806858299C201FE60C5A8E590F565863DC254FE8431A3E891149D86D8CC24EF5114103D8812FE282285C3A2806432AC7629716CC5DEA1EB9576E2B9562809A0AE66790F654278C16B355E1A4087A9600382F35BB3BF9F9541B4C5A98382D47D4B569685537662D4D891B7C949FCC4A27C81CA7A594BD66AA09AADB27AD43420863C2CBFC7A5D818984E343785C863085A97B2B77E8C5054418BF43BA61E62594E7011C1B3360F278130595959FA026C14A893579363BDACE7C291065C27C73340D400747BC29458FA324CD8880DD84A09FC973487358E68BB3221C4E5C4133914A13D2C53297BA10F02327FE37C43681A028A865576410F7DA2A7FA8867D563399F59DE8569485043623A1448C613B6424CCDAE8C59CCB53F1E8B0EF4A5751367F193637B6F78E0AFC2013FCBA7FE8AB5D7C70385A6869221A8FD88E246C7DEC6C83187C9680A8654E02269CFABF7438A234037BEAA7AF8D54448035BFE7A7430E264CF3F607DB07C3EB750BBB1926D5ACC839F02612C4BE88422AD9731FACC22F6DB1213DA36ECCAA97F7B5CC94146A0C50671F7725388712B30A1E8EFBBE72F693B7652F7FE5A9C3E10415168F6F9273AF55109BC9BAFFCA3E80989BA88905C1DAB706BB77ABE38D4235C44B43515DBB6CB15813EB4B0D8EF97647B331C689AB67E3921B840FB78804F83B0DE72239EBFA22CA799BD88107C36A505DA09E9EA4C4EE5802DB5047D2FB6B9B2C499EE55CCE4347A33C7A6EB2337D3589A3D099939B0C8619AE7A2414F0698B4B06D07648B2059C8BF8583095426A0776C81D4C5D24EB5AFF450E79FA07FB7026378B1E86D6AD2BA7227475261F37A6C58AABC6447E054AAB9C61A6E19B571AA57005E8906BDB6960A425B8B95671407145837FDD9B5CF51A4E42592CDE24332673CE7D023A3E2544970AB55857A1F0200521114B8096A366417052094175B549F474173E723A2377525EEC95C0D40C94988981792A8C324B61EB381F8ACD3BA987023B2E64D29C0FF63D5134527FA8AA5199667ED2331CD8880468590163A4B0692D9569089E24873F9A5738826AA8A326B3D013C0F0C65B41CD81A42290F628F174006E08C3CDF9B012050C2FB083F97A7770F8A3B120972676C6944B06320A56605409E33535ECBC1B1EE6201A457309102D845CC631450C2D802FD62A793AFA82C0C9BAFFB22F8FEAC2B9680DA32A51AC1C75F7E3899FA01471F9668DEC6CD765221E765D7C714D46085CF9B9B6FCC2891EF16E246489CE87B9028A5DEC713B84594847A4554AB4A39985213D009C617C0524217AA1A51DABC9CBF689B66325517726CA3E955F742126F13B72CE936EE1CA2D913B785B4704F975C221437C6A890E354810E27B57689A8564DB22783B3D46488F8646B50C366BE75566EDC0422C2784B7A33D10588BD83A89A07519B754C1EFE901FA9001C0B120A70C0BDC8CC5342C8D20281B8A7A24FF4240FF6990BFAA3197CAA594F63EE4C75B3014AF834BC4FB8249604855597B5ACEF45304D75C035981A8A7267FB04867E9C28EDB8BA6C64BC6B70B218CC738B097FD6527915018EBF712E7044BC7B50CB9151395814278089E9A003965B4AAAE46A19E5791331876B985BF23DA8BE19CC4EF857C98C91084C1CF0441A1B212580E271FEED51C98D88D4003B909B42627860E5B788F99521CB3953371F1686A437A2F3055F8D05B7FB01BA29886DD28A7269A99DF979DD80BCA5D399AC18A919985C643D68910F9C0C5923CC3A30C25E8B9F71935503513AC28A520D194CFA7129BD2A08CE76491B886B7531ED100700EA011D09319EB66B8B44A0C09913A0E40A2B1166DF676C205E648872386A221B45A428B9BDB0C8281032D52C22028BDCC96AC2CA6470F407F98D479ADE32B1D202F1F1141C3E6453084B551554989E00BFC2A44E7F5ABC8530FC174B6FA30B3F26B5A467A39322612B1C9C3CE01CFC540CEF912058FBACCEDD8BED38AAB401B88EE7058195CBCB7D8405CB71DC5B44EA19B34C9D1652E7192D50A03136BB87CB207C9DA8ADD47AD870A3AD5DA51B5E8874F71560C5490AD7137522823B167166E89BFCDD3492AB836ABC952A5E957E7A0CA963A2C697AC1F42664D7379E6AB2361D657D47CB34236B70F9658E71FA7CB2D51BABD2C67187022380335D9014176BC52878C1CB721CFA6B63FB92C55A9A53EA635C7522A93DF572DF5B01E4C4931DD47ECC73514EB5A6085206B79209A712C60BA4B338254411D08DC7C289E00C0C3F230406B47CCF4183D97005A0687F6BA6B7A02A4E9E781C99C28DBA8A32DE80AF53075CACE4629F03872F3606228335424A1311BB58BA3309D4087F839960DC3CC63D83832F0768BD13BA41EC2ECFB03D882799D10653A4F6BAEF00709169346FB83232F9685E309E36B23DF53AC8D0996FAF14440641AD59E3991054678596849FA44436454BD535A2692922A3C57BFFDBAFE0913240EAA29646A8B5E7461C269F58F92680401B70A82529634325D128AD23A452EC9A5E52A622A524F3205B6E9130BAC6830C3B109164A65CA9091226666DEC395AA63B0899BC6C798F86F74E3E5265CABC600C193AB7D1AAD5085D2C198DE66A4BD4649A26349AE5C88FA44BAE97B91D2A17B8578942B7D61E25E367CBDC29841B0116458C97F72499AE6B74006261E57B749B66ABDF0FF71F8CCEA4ED010C6A97739D7351C57B9807586DB3D99C6AFFAFB04CD2551A4B1DF17FCCB8D7D94C103EE6656B14BF83E3048B021F22DB57076A885729F95119CE63FAF51A69954BCCC51E014686" + }, + { + "tcId": 49, + "deferred": false, + "z": "F42861EFF7691614C3E8975AFB4E353F8C8C39E6F41BB637EC79BAA976D1ADC1", + "d": "D5FD815092620DC42A223909E387369A74AF7DCA285138CF217BC29F29C42C41", + "ek": "A9D674C360C5B1E36D78F66C722392F167A126F09FCC4310A9320137EBA898E786F95B9CC5D0B9114206EC66159BB3A687427D3B2298F1317ADE160EBF44CAFAA62B38871C6239C38F67CA0922C9DD952D8AA55AA6A481386771FD003A271B659F4B730B589B717635E6EB62603C5BD6C96756DB4947C5B1A71B970CD16B6D2519205C08147685B7103BB7C130B40C11CFE9C73866567175CCCDF40522C10A80140D78F9A71C714BADB1CE2732B86BD0518BF4783FAA00694208C3C2BD4BA34DEC08ADD425A0687A0D8B392702DA57504A28E9099912A8AE4A964765D35E739C1C3158330F4C21DC3A58969AAEBC788EC8177443732EAA527DC1E5009E010D8F980369FCCB48527AA27C6553393709F0B252E9346671465D33C072E352B2619175878F946488AEE3B5EE201C753244E6C85A1DE48BC994B4B1F9AB4F81B9C9F6C243C4A57BAB99781CAB1FD152A205A893F07F16431401F746B5EC790EA89C8C672EB7267EC34036F5F541C334B499DAB565387C2341C27F4904546917295B8F640CBCDF9B254502B58A669D36AA3D834793CC2A4D6578397D3A6DA893710F6A1839D8CAD7067A020108BF98415569A5C5856C5678C9A41A3075F077E6150F54B57FE91691A1C05F5022939A322CB919ACDA1236FEC9885AEB2C3A975E5BA238F5E713AA751093846915B003E624577007C7048B23E29445EE123AD3D6604D5006332CCD238A0E23020244D99A2C8A28CB58A76A69A39CC05927767ACBF892E3B6CB27231472C9189FBC1BADD18CB9A0CCB9E9CB08D0BA65C9924BCB2D88EA9739835C3B388A7B416A5BC5A27B01260D732F237474292133F0E458F33CBC3A687F149A1F8D7B08FE76A0C7C9330F8582D378BE0E2B135097CC9527A24FA3913BC3C98F04298CA86A08F6969D98C6EEDC19D6026D18D93479698A237B319B8CBC7E266DD34162FDB07C04A677C7B27E758A9D42DB0E35B4369C325C1F5639E0AA30B87433BC9C977447A2F97413E351BB98242D68E02527053A75A0CA93AB8E1E8B521F4BA09EB1B32D6797C5D7BD2AC76E81946CA48BCC787A9D35022C31F0938F710482B1A5DDF91A9024900D019AE33B182D6424D86B558109158B188C3978B5345A7D85B70B30888083C50CFAEA947258891A192B05D8589A0B7415F6945D1275B9C12DC25055B372553D21ABC7B96BD7F821B0C78D6AC3CD5BEA024720625611126220A5A467A60C268B748632C6B19403391391D649BE701B85592FF7F256937843547339E01179E2D79F9D88168528CE5FD5A819108456A789F094093E3980413A14F11B71C57BC71617CA3234008B2907447B8EF8A58B87450AD9506BB84C9E3F66BCE6CBC5D503434D406387D8CDC22A64D53786C79A90C911723D8799B3A7B9AB20672DA92572FB609AC14D57435736055B89F9851DB4B621AA42610317F15802FFB457620B4A7712212DA5725C049E1FD3670DF15ED5A945549C38DE4826BEC844500A313B41921E21AA5EF186940497462117EBD8B383520680DC2646683E0E819B2DE992A82380F400BAA20560AB7A58D2176D4885204ED705F21084390C5AAB8879214286A1F199B3949A59E11B86582B5C13080766C7E2091EA99F1352D4488C7EA1547DD87024156A9FB2DF0C77B684540084890847AA6D85", + "dk": "49B061657A8EDBA51C06A38F4995CC0D68BD97C515A7576125F7961317046D3B0A21B44415B07592991570D05291AB34DCB808E57041FF249D97F471B57A8B7924BB8B699B9772360A8157CE513C58882B89F79E37287042A353A887761D73B2AA3A5185D999FD1A4609AB7FB3ACC8EA083E6DDB2A9592413CA11E7D51AD6378132AF88D977762A473A4849A303C648183D03773C610B8C07A6F741D2E887768E20FA9B749072CB64292B791731658E7297F8A584EFA2A9446911E155E0E27BD71DB8B1D52395982C40C4C65C7FCCEE20B684C2432A83579468B8A82A730305A157FF46F5C8781CD621143E31A20311803185335855116712E34498045093BAD6B80A8F332AB8C5A90025AD0B1CA6EC53401AA83DD01595540141C749687A53D775B4A691B69F6D32C275187A6CB1A4A336C341CC36CCB295C21609EAB1636EC0BB031345A3BAA345878EF43A46B82A9DBB7019658A43AA0368CAB4310103BD5589499B2C1E89A5C2A297ED707B7FAF8170FD2CAE245146929060CA5BD10D8316980C18824CDA429302B64C14385CBE36AA0DC6CB0941B204A55A710D2C68052C900C34C35A7AE7834CF5552264AA2583913348CDC79A08847ACE64024464E759AA99573BFC7B40F8CC4449379A40558B756B22410934C7969B42ACCCCC7D8231E5CA2DF5574384B9E0712C436FBC67AF74234E49B59480B0CF47C8DC31D47776BA9B000C0E80856B889FF09916CF8CE199680A45B16B1AC1438000D6472C79497014B6384AD069FA8AB1A004B518AA97066DCAC32D00893301D327008020431F2B01A4004523F0453DB14B3A84001EC3749D25473EB219AF1E0A7628BAE4A24BE7A1A5E24C3AB5D0A6661C4C1DE754755EBBC91865E8147C1D0233DEA643C4E648DBE3C50B96B898D81B4DB71CD9CD38BFFCB9E7C384EC58A7A27F29C7C5B20255149EDD02442E4CF8C8A34B73B6D36319F6FD3425BEAB4A8EB1698E03A1A344C88808FCF183AF5F6905B1B445CC9235BE74C1DB07D794BB867331EAEFB52AA165E31DB2048A62CA4D5197B3AB327281B132B0EAA18B1D8699EDCFB730B905A517036E3EC9BF40AC4F47440BFC231693025CA297B4F5198DC094066919934F32E5EA6712937CFE458A2BF916D382933A95487603B4AB303CC81BA94E467576787B7D8095B059020E6C43069745CA03C2B31229F2CE021F4D9BC38FC2886EC9570F2671872C766D40C970A0825083A01961FE97C9214533F3A8562E620A0C8B5354E8989420B4F639B323E415D8AD4732F299EFFF99A7AB47A100CB05F31C158F37FBF8B7B7F477DD3398A20F07F9BA0605AC67CE4379932D0B2E7E236882093846AC42B64806F4C3E035BCD1EBAB1D54084B63C870217B210D2CE816A35BAEA8CCF2C7FB4938FDDC320D9B81751116C4DBC2269C37413206704B631BE653BD20B7F920305F9EC8C46805E95FC504B1C33BDB5A1AD912F8D65221A784922A63578201FF3E869DDE76AFDC9068F657CD0B66E8D441DF7E642A01220F8001D6A1558F5F73F49C13F3E1BB8A9E7BFB56B677CD6AE6FE8C85C24CCD7A78790E1AD8809A8F964B43228155D2872A9B11849514035F154799202A0299C41F80D9D1A67A9D674C360C5B1E36D78F66C722392F167A126F09FCC4310A9320137EBA898E786F95B9CC5D0B9114206EC66159BB3A687427D3B2298F1317ADE160EBF44CAFAA62B38871C6239C38F67CA0922C9DD952D8AA55AA6A481386771FD003A271B659F4B730B589B717635E6EB62603C5BD6C96756DB4947C5B1A71B970CD16B6D2519205C08147685B7103BB7C130B40C11CFE9C73866567175CCCDF40522C10A80140D78F9A71C714BADB1CE2732B86BD0518BF4783FAA00694208C3C2BD4BA34DEC08ADD425A0687A0D8B392702DA57504A28E9099912A8AE4A964765D35E739C1C3158330F4C21DC3A58969AAEBC788EC8177443732EAA527DC1E5009E010D8F980369FCCB48527AA27C6553393709F0B252E9346671465D33C072E352B2619175878F946488AEE3B5EE201C753244E6C85A1DE48BC994B4B1F9AB4F81B9C9F6C243C4A57BAB99781CAB1FD152A205A893F07F16431401F746B5EC790EA89C8C672EB7267EC34036F5F541C334B499DAB565387C2341C27F4904546917295B8F640CBCDF9B254502B58A669D36AA3D834793CC2A4D6578397D3A6DA893710F6A1839D8CAD7067A020108BF98415569A5C5856C5678C9A41A3075F077E6150F54B57FE91691A1C05F5022939A322CB919ACDA1236FEC9885AEB2C3A975E5BA238F5E713AA751093846915B003E624577007C7048B23E29445EE123AD3D6604D5006332CCD238A0E23020244D99A2C8A28CB58A76A69A39CC05927767ACBF892E3B6CB27231472C9189FBC1BADD18CB9A0CCB9E9CB08D0BA65C9924BCB2D88EA9739835C3B388A7B416A5BC5A27B01260D732F237474292133F0E458F33CBC3A687F149A1F8D7B08FE76A0C7C9330F8582D378BE0E2B135097CC9527A24FA3913BC3C98F04298CA86A08F6969D98C6EEDC19D6026D18D93479698A237B319B8CBC7E266DD34162FDB07C04A677C7B27E758A9D42DB0E35B4369C325C1F5639E0AA30B87433BC9C977447A2F97413E351BB98242D68E02527053A75A0CA93AB8E1E8B521F4BA09EB1B32D6797C5D7BD2AC76E81946CA48BCC787A9D35022C31F0938F710482B1A5DDF91A9024900D019AE33B182D6424D86B558109158B188C3978B5345A7D85B70B30888083C50CFAEA947258891A192B05D8589A0B7415F6945D1275B9C12DC25055B372553D21ABC7B96BD7F821B0C78D6AC3CD5BEA024720625611126220A5A467A60C268B748632C6B19403391391D649BE701B85592FF7F256937843547339E01179E2D79F9D88168528CE5FD5A819108456A789F094093E3980413A14F11B71C57BC71617CA3234008B2907447B8EF8A58B87450AD9506BB84C9E3F66BCE6CBC5D503434D406387D8CDC22A64D53786C79A90C911723D8799B3A7B9AB20672DA92572FB609AC14D57435736055B89F9851DB4B621AA42610317F15802FFB457620B4A7712212DA5725C049E1FD3670DF15ED5A945549C38DE4826BEC844500A313B41921E21AA5EF186940497462117EBD8B383520680DC2646683E0E819B2DE992A82380F400BAA20560AB7A58D2176D4885204ED705F21084390C5AAB8879214286A1F199B3949A59E11B86582B5C13080766C7E2091EA99F1352D4488C7EA1547DD87024156A9FB2DF0C77B684540084890847AA6D85E8BEB5E40DA16CD0B6771A006BD6CC2A5BA77C278E3EDF52912210F80A5E1759F42861EFF7691614C3E8975AFB4E353F8C8C39E6F41BB637EC79BAA976D1ADC1" + }, + { + "tcId": 50, + "deferred": false, + "z": "4DD0E86091649A0A08EA44DAB85DF56797F8BF46222C2DBA7DEC6374B9B2268E", + "d": "D21D5AFED9AFAA3B49FB45245B2BCA1505E4000CDC29094A3600F5CAA49A7B3A", + "ek": "744793A77A843520C9EB8B057FF28854193916F711902B1F8B4B9C235251FBDC8040C8A38C022557DB50CB28CC8DF99A859C2EC017C24015877D2A3572571FC783BF1E984401C11158E32A95351BE407A8AE6B5E054A33C2427F4A346761559F776671095B495074AF5CAC98D94297FB05624443CAA8151AF3A497F73203EF184CC7336650427CDFD47B10245EDDE30C3075933E431DC1B1C2A77B2073257C2AB73ABE706DE138CD54922CDB09CEFA60BA473092E43BC3E3CB951939B1C4CB2AFDCB4F8A5310FE9A790E560B25A40AC9E18D35A27238A60A126B398980BE8425C8A01B930FB336CB359F58131BBEE6AC450B8C811B2DDEA836F9D0C2C72A709E134321DCA727641A1D678A8E0CAE6BD6BBDAD8021AE3C1B6067FB1ECA42D215EC2C4297F6891567712F75047775B741713097B1271AFF026323A134DC20DEBFACE46D5B01820A9A862BA93E3AFCB5AC4C2204AF2E15787D0C857896D24DCBD6393C1FDDC12CDDA6A1F337B18D6C3CCD5283B37239A80424780399281C3FF1967B3BB6DAE499D42F511997077F38A8D63EB319342B1BC749924E467C6A2A11728826BEB52A39BA7A1A03C93C613D36A3F1F544B72A8BEC24009FDE07E677101456A2B76EC3353CB8944C339081A4B59672CD1B5446FFA6FC0B468D9FC83EBF896CE12158AFAA6812028F54B7920636784D3B3854030D05A9C19D936C6FACC5B81070CD524728A96A58A2E1207C73A4C533DDB00098141158B11DB674500781F47DB9B45F3CDE244502D377886418287C22075B2BD172606CCFA6F4914844525C113BCC7C049B3D14A2DF91B6C62E0A2EE5922DA3194DFC0C506D48ECCF5697BA31BD0839A4D3B3078CB7C2936CE1C507B0B54023585CADA6BA5657726075659DE16A6403110CE38A247CA85CE02C1DAC79FD175BCAAFA116F710516A4B73D78BFC6F9854228B6C5F035946B1F61B629F31328A65556C8F0661D58622C6021F58C1ACF154C6E78BCF563352AFB89B824513A35502F117861A34C52B1011F696A85185186BBA23B518C720763529C181D902CBBB58CFEF77CD2E72F4780979FD46126C0A4BC1965A6E070FC284B1F856852110E19C268390CA9494116EB293F1A111ABEC1AF04F706B114617F0362B3DB4B99E076287AAFB7127FE2C68904F61664D63D4FB267CE07AD5A659FB81886F8E0A9C26261A0055F48F432E9F8242C439F58B5A21EB777483B2E68B3B1118562430270340243F1E87C22CB5BE2F167DC39CF4C69B8B8E9B726256CBE605342F47E23A871BA7250BDA8997FD474B3375920522F2C511B3EA35CF459342893AA12B128CC2184E304335AC7BA04653898590A664672FE744F301651442BB341D32F36262C576A50F803B02F91105FEBCABEF7030D2A76CBEC6C2CF36283590BB44842853102D3D350801167D7A96968648C0CAB9AFD39CB7F658909283CB83CA78544929AD90069CA3E660196792A654A911CAD7C23024C90E25AA61B30A4D568C5A5C12A53565A93E910D5940EF3583856017BC25B05C4473F48584C6908C13D2B19E7A3A7992976D31A464807199AE3A6307CA55765590F6B4721632D70FA47E2C1098E36898BE3125E43C61CBB7A6C246CBA0002CF325A5D337989289BCCDA54835511DE9656287363DEE85033410AEAE1", + "dk": "045AA22AEAA4A8E0C66661A183700F04025D413CCDCBE1B7CD9B839BA61671B08A859B1AECA9014CB3695B29703CD4314954C48CC19A89E106079720EF23B597FA6A833638B7A7B1E74A40C8BA7A005AA799D22DC5AA97627A037BA2623C659621EA2FF40651DAA0A95B2218CF934DB132BDE8A29F889BA084DA3EA9C8B58FD1BEF4D45EB4A2501447640C7869F21C9B031718209288E442018F63097459AFCEB75815829B16EC48FF822B1F69B6B48C3AA3C65441E60F552A154BD85A71397AB8290564F527FA8B1E84AB4EE6450EB5CA658B2120164B7D84637CC7488FFDF717F9349734E6B2F585C040065A2E910CCCA070C0070C2C215BC8060930D30D7A73A0FADA94E46257BE169B73D7A35DD43EB9B0183589AD657A429D983564031166253B4EE513AFE986E007727D75BA22F41A0AEA4939081C7CE1BEA5AA8D8DFB692AD37726E05A9DBA9D70102A1DE64479A928D9789035D4B645F088ABE8A51B06826BA64079C4AD3EC2C8A7EBC9F5EA6A0C707E88B2224DEA55FC0C39EC258088E319CA48C3F0C86AA203669F164E5FD0BA467548050CA496579BD4099D705A82BF9634995ACE60DCAC96C9115226AF2B6A9D86497DA1C49FEEE35F5639BA1A8363DF5114EA06C190179161C3C4238115DD55200BD28A03EACCAA46C7A9126B6F0CC2BFD9047D9BBF7A2043BD965F244158C7F10548FBBC39E040F040145A45B12BC90A74065BD3E34925C94FFA968BEAD241A79B6B0F1C3911C444E3958906DB8834984897CA886DC1B9D63CA43803C74C5633F003BD148A691D396C98BA81918A560542CC6435082957A70A312DAD0AC54F81903B2280BEF3638A013654D26E0D2705939A31EF39547FB80BE113A336E277E04B8B905C9DD90509C434277246916A1A0A7E66BC1C74C4719751BD8879E07AB97721C0B27BC08B69B284F2BB47E43290F2BB434C489570C22AC867F06643AB100457D336CB944B6B5A185B639A403A332FC755584A9F2EAA315C319D3099B30710B7EFAA5BBE8A3981A9B158E0C7484595AA1B7CA3F335BB38A7E5AB51F2799E0EC2049AB781514A82CA7CC5A53BCFF3029320636285902EC1D24432B5292EF7600097929D374F3485AB2AA5C8A154CC3171693DBBC4382A5E44600AC8B1646A84A47B078D06EC554A309A1FC2BB473C69EA4732B6485BE812A1004D583D9A0B9953312CAB9B014A482D8C7BD1097231D0041FF599D0E043C7CA08FD0CA71AEB977EF271EC13AF122766566BCAEAA26554F87394847C50DC2B8D3885184069B1A173D1183E68C55867E55EA78610CC3183A7F60181D1751A12107225C7156B99F86846FDF5777502A201FB583202B28EB78EEF356918D2B5B7594AE364902D45C2E8691137C98CA7B2425274068D765AFF29095ED546309C2D4CD6A5DE0571E67566DB14C386A87F15379CD1190EF02806D6B8387C87C73B805E01DB128C0A86C1013FAA7CB7D46770A0835C5343C931AB8CFDF56AE4241108C55976F127334AC3E2B52360661B61532CCB641CA043AE9B3173D0133CB0E4581748B6F1AC00BA0BAE4960376782A25F36765A1A4318D73C18781C90755C657847ED6849CE1301B11A2FD75616B4F326DAD545744793A77A843520C9EB8B057FF28854193916F711902B1F8B4B9C235251FBDC8040C8A38C022557DB50CB28CC8DF99A859C2EC017C24015877D2A3572571FC783BF1E984401C11158E32A95351BE407A8AE6B5E054A33C2427F4A346761559F776671095B495074AF5CAC98D94297FB05624443CAA8151AF3A497F73203EF184CC7336650427CDFD47B10245EDDE30C3075933E431DC1B1C2A77B2073257C2AB73ABE706DE138CD54922CDB09CEFA60BA473092E43BC3E3CB951939B1C4CB2AFDCB4F8A5310FE9A790E560B25A40AC9E18D35A27238A60A126B398980BE8425C8A01B930FB336CB359F58131BBEE6AC450B8C811B2DDEA836F9D0C2C72A709E134321DCA727641A1D678A8E0CAE6BD6BBDAD8021AE3C1B6067FB1ECA42D215EC2C4297F6891567712F75047775B741713097B1271AFF026323A134DC20DEBFACE46D5B01820A9A862BA93E3AFCB5AC4C2204AF2E15787D0C857896D24DCBD6393C1FDDC12CDDA6A1F337B18D6C3CCD5283B37239A80424780399281C3FF1967B3BB6DAE499D42F511997077F38A8D63EB319342B1BC749924E467C6A2A11728826BEB52A39BA7A1A03C93C613D36A3F1F544B72A8BEC24009FDE07E677101456A2B76EC3353CB8944C339081A4B59672CD1B5446FFA6FC0B468D9FC83EBF896CE12158AFAA6812028F54B7920636784D3B3854030D05A9C19D936C6FACC5B81070CD524728A96A58A2E1207C73A4C533DDB00098141158B11DB674500781F47DB9B45F3CDE244502D377886418287C22075B2BD172606CCFA6F4914844525C113BCC7C049B3D14A2DF91B6C62E0A2EE5922DA3194DFC0C506D48ECCF5697BA31BD0839A4D3B3078CB7C2936CE1C507B0B54023585CADA6BA5657726075659DE16A6403110CE38A247CA85CE02C1DAC79FD175BCAAFA116F710516A4B73D78BFC6F9854228B6C5F035946B1F61B629F31328A65556C8F0661D58622C6021F58C1ACF154C6E78BCF563352AFB89B824513A35502F117861A34C52B1011F696A85185186BBA23B518C720763529C181D902CBBB58CFEF77CD2E72F4780979FD46126C0A4BC1965A6E070FC284B1F856852110E19C268390CA9494116EB293F1A111ABEC1AF04F706B114617F0362B3DB4B99E076287AAFB7127FE2C68904F61664D63D4FB267CE07AD5A659FB81886F8E0A9C26261A0055F48F432E9F8242C439F58B5A21EB777483B2E68B3B1118562430270340243F1E87C22CB5BE2F167DC39CF4C69B8B8E9B726256CBE605342F47E23A871BA7250BDA8997FD474B3375920522F2C511B3EA35CF459342893AA12B128CC2184E304335AC7BA04653898590A664672FE744F301651442BB341D32F36262C576A50F803B02F91105FEBCABEF7030D2A76CBEC6C2CF36283590BB44842853102D3D350801167D7A96968648C0CAB9AFD39CB7F658909283CB83CA78544929AD90069CA3E660196792A654A911CAD7C23024C90E25AA61B30A4D568C5A5C12A53565A93E910D5940EF3583856017BC25B05C4473F48584C6908C13D2B19E7A3A7992976D31A464807199AE3A6307CA55765590F6B4721632D70FA47E2C1098E36898BE3125E43C61CBB7A6C246CBA0002CF325A5D337989289BCCDA54835511DE9656287363DEE85033410AEAE16C770D1FA4C0F5DBB660530772FCC2297F59BC9DEE338CD124F0924CF7E3762D4DD0E86091649A0A08EA44DAB85DF56797F8BF46222C2DBA7DEC6374B9B2268E" + } + ] + }, + { + "tgId": 3, + "testType": "AFT", + "parameterSet": "ML-KEM-1024", + "tests": [ + { + "tcId": 51, + "deferred": false, + "z": "99E3246884181F8E1DD44E0C7629093330221FD67D9B7D6E1510B2DBAD8762F7", + "d": "49AC8B99BB1E6A8EA818261F8BE68BDEAA52897E7EC6C40B530BC760AB77DCE3", + "ek": "A04184D4BC7B532A0F70A54D7757CDE6175A6843B861CB2BC4830C0012554CFC5D2C8A2027AA3CD967130E9B96241B11C4320C7649CC23A71BAFE691AFC08E680BCEF42907000718E4EACE8DA28214197BE1C269DA9CB541E1A3CE97CFADF9C6058780FE6793DBFA8218A2760B802B8DA2AA271A38772523A76736A7A31B9D3037AD21CEBB11A472B8792EB17558B940E70883F264592C689B240BB43D5408BF446432F412F4B9A5F6865CC252A43CF40A320391555591D67561FDD05353AB6B019B3A08A73353D51B6113AB2FA51D975648EE254AF89A230504A236A4658257740BDCBBE1708AB022C3C588A410DB3B9C308A06275BDF5B4859D3A2617A295E1A22F90198BAD0166F4A943417C5B831736CB2C8580ABFDE5714B586ABEEC0A175A08BC710C7A2895DE93AC438061BF7765D0D21CD418167CAF89D1EFC3448BCBB96D69B3E010C82D15CAB6CACC6799D3639669A5B21A633C865F8593B5B7BC800262BB837A924A6C5440E4FC73B41B23092C3912F4C6BEBB4C7B4C62908B03775666C22220DF9C88823E344C7308332345C8B795D34E8C051F21F5A21C214B69841358709B1C305B32CC2C3806AE9CCD3819FFF4507FE520FBFC27199BC23BE6B9B2D2AC1717579AC769279E2A7AAC68A371A47BA3A7DBE016F14E1A727333663C4A5CD1A0F8836CF7B5C49AC51485CA60345C990E06888720003731322C5B8CD5E6907FDA1157F468FD3FC20FA8175EEC95C291A262BA8C5BE990872418930852339D88A19B37FEFA3CFE82175C224407CA414BAEB37923B4D2D83134AE154E490A9B45A0563B06C953C3301450A2176A07C614A74E3478E48509F9A60AE945A8EBC7815121D90A3B0E07091A096CF02C57B25BCA58126AD0C629CE166A7EDB4B33221A0D3F72B85D562EC698B7D0A913D73806F1C5C87B38EC003CB303A3DC51B4B35356A67826D6EDAA8FEB93B98493B2D1C11B676A6AD9506A1AAAE13A824C7C08D1C6C2C4DBA9642C76EA7F6C8264B64A23CCCA9A74635FCBF03E00F1B5722B214376790793B2C4F0A13B5C40760B4218E1D2594DCB30A70D9C1782A5DD30576FA4144BFC8416EDA8118FC6472F56A979586F33BB070FB0F1B0B10BC4897EBE01BCA3893D4E16ADB25093A7417D0708C83A26322E22E6330091E30152BF823597C04CCF4CFC7331578F43A2726CCB428289A90C863259DD180C5FF142BEF41C7717094BE07856DA2B140FA67710967356AA47DFBC8D255B4722AB86D439B7E0A6090251D2D4C1ED5F20BBE6807BF65A90B7CB2EC0102AF02809DC9AC7D0A3ABC69C18365BCFF59185F33996887746185906C0191AED4407E139446459BE29C6822717644353D24AB6339156A9C424909F0A9025BB74720779BE43F16D81C8CC666E99710D8C68BB5CC4E12F314E925A551F09CC59003A1F88103C254BB978D75F394D3540E31E771CDA36E39EC54A62B5832664D821A72F1E6AFBBA27F84295B2694C498498E812BC8E9378FE541CEC5891B25062901CB7212E3CDC46179EC5BCEC10BC0B9311DE05074290687FD6A5392671654284CD9C8CC3EBA80EB3B662EB53EB75116704A1FEB5C2D056338532868DDF24EB8992AB8565D9E490CADF14804360DAA90718EAB616BAB0765D33987B47EFB6599C5563235E61E4BE670E97955AB292D9732CB8930948AC82DF230AC72297A23679D6B94C17F1359483254FEDC2F05819F0D069A443B78E3FC6C3EF4714B05A3FCA81CBBA60242A7060CD885D8F39981BB18092B23DAA59FD9578388688A09BBA079BC809A54843A60385E2310BBCBCC0213CE3DFAAB33B47F9D6305BC95C6107813C585C4B657BF30542833B14949F573C0612AD524BAAE69590C1277B86C286571BF66B3CFF46A3858C09906A794DF4A06E9D4B0A2E43F10F72A6C6C47E5646E2C799B71C33ED2F01EEB45938EB7A4E2E2908C53558A540D350369FA189C616943F7981D7618CF02A5B0A2BCC422E857D1A47871253D08293C1C179BCDC0437069107418205FDB9856623B8CA6B694C96C084B17F13BB6DF12B2CFBBC2B0E0C34B00D0FCD0AECFB27924F6984E747BE2A09D83A8664590A8077331491A4F7D720843F23E652C6FA840308DB4020337AAD37967034A9FB523B67CA70330F02D9EA20C1E84CB8E5757C9E1896B60581441ED618AA5B26DA56C0A5A73C4DCFD755E610B4FC81FF84E21", + "dk": "8C8B3722A82E550565521611EBBC63079944C9B1ABB3B0020FF12F631891A9C468D3A67BF6271280DA58D03CB042B3A461441637F929C273469AD15311E910DE18CB9537BA1BE42E98BB59E498A13FD440D0E69EE832B45CD95C382177D67096A18C07F1781663651BDCAC90DEDA3DDD143485864181C91FA2080F6DAB3F86204CEB64A7B4446895C03987A031CB4B6D9E0462FDA829172B6C012C638B29B5CD75A2C930A5596A3181C33A22D574D30261196BC350738D4FD9183A763336243ACED99B3221C71D8866895C4E52C119BF3280DAF80A95E15209A795C4435FBB3570FDB8AA9BF9AEFD43B094B781D5A81136DAB88B8799696556FEC6AE14B0BB8BE4695E9A124C2AB8FF4AB1229B8AAA8C6F41A60C34C7B56182C55C2C685E737C6CA00A23FB8A68C1CD61F30D3993A1653C1675AC5F0901A7160A73966408B8876B715396CFA4903FC69D60491F8146808C97CD5C533E71017909E97B835B86FF847B42A696375435E006061CF7A479463272114A89EB3EAF2246F0F8C104A14986828E0AD20420C9B37EA23F5C514949E77AD9E9AD12290DD1215E11DA274457AC86B1CE6864B122677F3718AA31B02580E64317178D38F25F609BC6C55BC374A1BF78EA8ECC219B30B74CBB3272A599238C93985170048F176775FB19962AC3B135AA59DB104F7114DBC2C2D42949ADECA6A85B323EE2B2B23A77D9DB235979A8E2D67CF7D2136BBBA71F269574B38888E1541340C19284074F9B7C8CF37EB01384E6E3822EC4882DFBBEC4E6098EF2B2FC177A1F0BCB65A57FDAA89315461BEB7885FB68B3CD096EDA596AC0E61DD7A9C507BC6345E0827DFCC8A3AC2DCE51AD731AA0EB932A6D0983992347CBEB3CD0D9C9719797CC21CF0062B0AD94CAD734C63E6B5D859CBE19F0368245351BF464D7505569790D2BB724D8659A9FEB1C7C473DC4D061E29863A2714BAC42ADCD1A8372776556F7928A7A44E94B6A25322D03C0A1622A7FD261522B7358F085BDFB60758762CB901031901B5EECF4920C81020A9B1781BCB9DD19A9DFB66458E7757C52CEC75B4BA740A24099CB56BB60A76B6901AA3E0169C9E83496D73C4C99435A28D613E97A1177F58B6CC595D3B2331E9CA7B57B74DC2C5277D26F2FE19240A55C35D6CFCA26C73E9A2D7C980D97960AE1A04698C16B398A5F20C35A0914145CE1674B71ABC6066A909A3E4B911E69D5A849430361F731B07246A6329B52361904225082D0AAC5B21D6B34862481A890C3C360766F04263603A6B73E802B1F70B2EB00046836B8F493BF10B90B8737C6C548449B294C47253BE26CA72336A632063AD3D0B48C8B0F4A34447EF13B764020DE739EB79ABA20E2BE1951825F293BEDD1089FCB0A91F560C8E17CDF52541DC2B81F972A7375B201F10C08D9B5BC8B95100054A3D0AAFF89BD08D6A0E7F2115A435231290460C9AD435A3B3CF35E52091EDD1890047BCC0AABB1ACEBC75F4A32BC1451ACC4969940788E89412188946C9143C5046BD1B458DF617C5DF533B052CD6038B7754034A23C2F7720134C7B4EACE01FAC0A2853A9285847ABBD06A3343A778AC6062E458BC5E61ECE1C0DE0206E6FE8A84034A7C5F1B005FB0A584051D3229B86C909AC5647B3D75569E05A88279D80E5C30F574DC327512C6BBE8101239EC62861F4BE67B05B9CDA9C545C13E7EB53CFF260AD9870199C21F8C63D64F0458A7141285023FEB829290872389644B0C3B73AC2C8E121A29BB1C43C19A233D56BED82740EB021C97B8EBBA40FF328B541760FCC372B52D3BC4FCBC06F424EAF253804D4CB46F41FF254C0C5BA483B44A87C219654555EC7C163C79B9CB760A2AD9BB722B93E0C28BD4B1685949C496EAB1AFF90919E3761B346838ABB2F01A91E554375AFDAAAF3826E6DB79FE7353A7A578A7C0598CE28B6D9915214236BBFFA6D45B6376A07924A39A7BE818286715C8A3C110CD76C02E0417AF138BDB95C3CCA798AC809ED69CFB672B6FDDC24D89C06A6558814AB0C21C62B2F84C0E3E0803DB337A4E0C7127A6B4C8C08B1D1A76BF07EB6E5B5BB47A16C74BC548375FB29CD789A5CFF91BDBD071859F4846E355BB0D29484E264DFF36C9177A7ACA78908879695CA87F25436BC12630724BB22F0CB64897FE5C41195280DA04184D4BC7B532A0F70A54D7757CDE6175A6843B861CB2BC4830C0012554CFC5D2C8A2027AA3CD967130E9B96241B11C4320C7649CC23A71BAFE691AFC08E680BCEF42907000718E4EACE8DA28214197BE1C269DA9CB541E1A3CE97CFADF9C6058780FE6793DBFA8218A2760B802B8DA2AA271A38772523A76736A7A31B9D3037AD21CEBB11A472B8792EB17558B940E70883F264592C689B240BB43D5408BF446432F412F4B9A5F6865CC252A43CF40A320391555591D67561FDD05353AB6B019B3A08A73353D51B6113AB2FA51D975648EE254AF89A230504A236A4658257740BDCBBE1708AB022C3C588A410DB3B9C308A06275BDF5B4859D3A2617A295E1A22F90198BAD0166F4A943417C5B831736CB2C8580ABFDE5714B586ABEEC0A175A08BC710C7A2895DE93AC438061BF7765D0D21CD418167CAF89D1EFC3448BCBB96D69B3E010C82D15CAB6CACC6799D3639669A5B21A633C865F8593B5B7BC800262BB837A924A6C5440E4FC73B41B23092C3912F4C6BEBB4C7B4C62908B03775666C22220DF9C88823E344C7308332345C8B795D34E8C051F21F5A21C214B69841358709B1C305B32CC2C3806AE9CCD3819FFF4507FE520FBFC27199BC23BE6B9B2D2AC1717579AC769279E2A7AAC68A371A47BA3A7DBE016F14E1A727333663C4A5CD1A0F8836CF7B5C49AC51485CA60345C990E06888720003731322C5B8CD5E6907FDA1157F468FD3FC20FA8175EEC95C291A262BA8C5BE990872418930852339D88A19B37FEFA3CFE82175C224407CA414BAEB37923B4D2D83134AE154E490A9B45A0563B06C953C3301450A2176A07C614A74E3478E48509F9A60AE945A8EBC7815121D90A3B0E07091A096CF02C57B25BCA58126AD0C629CE166A7EDB4B33221A0D3F72B85D562EC698B7D0A913D73806F1C5C87B38EC003CB303A3DC51B4B35356A67826D6EDAA8FEB93B98493B2D1C11B676A6AD9506A1AAAE13A824C7C08D1C6C2C4DBA9642C76EA7F6C8264B64A23CCCA9A74635FCBF03E00F1B5722B214376790793B2C4F0A13B5C40760B4218E1D2594DCB30A70D9C1782A5DD30576FA4144BFC8416EDA8118FC6472F56A979586F33BB070FB0F1B0B10BC4897EBE01BCA3893D4E16ADB25093A7417D0708C83A26322E22E6330091E30152BF823597C04CCF4CFC7331578F43A2726CCB428289A90C863259DD180C5FF142BEF41C7717094BE07856DA2B140FA67710967356AA47DFBC8D255B4722AB86D439B7E0A6090251D2D4C1ED5F20BBE6807BF65A90B7CB2EC0102AF02809DC9AC7D0A3ABC69C18365BCFF59185F33996887746185906C0191AED4407E139446459BE29C6822717644353D24AB6339156A9C424909F0A9025BB74720779BE43F16D81C8CC666E99710D8C68BB5CC4E12F314E925A551F09CC59003A1F88103C254BB978D75F394D3540E31E771CDA36E39EC54A62B5832664D821A72F1E6AFBBA27F84295B2694C498498E812BC8E9378FE541CEC5891B25062901CB7212E3CDC46179EC5BCEC10BC0B9311DE05074290687FD6A5392671654284CD9C8CC3EBA80EB3B662EB53EB75116704A1FEB5C2D056338532868DDF24EB8992AB8565D9E490CADF14804360DAA90718EAB616BAB0765D33987B47EFB6599C5563235E61E4BE670E97955AB292D9732CB8930948AC82DF230AC72297A23679D6B94C17F1359483254FEDC2F05819F0D069A443B78E3FC6C3EF4714B05A3FCA81CBBA60242A7060CD885D8F39981BB18092B23DAA59FD9578388688A09BBA079BC809A54843A60385E2310BBCBCC0213CE3DFAAB33B47F9D6305BC95C6107813C585C4B657BF30542833B14949F573C0612AD524BAAE69590C1277B86C286571BF66B3CFF46A3858C09906A794DF4A06E9D4B0A2E43F10F72A6C6C47E5646E2C799B71C33ED2F01EEB45938EB7A4E2E2908C53558A540D350369FA189C616943F7981D7618CF02A5B0A2BCC422E857D1A47871253D08293C1C179BCDC0437069107418205FDB9856623B8CA6B694C96C084B17F13BB6DF12B2CFBBC2B0E0C34B00D0FCD0AECFB27924F6984E747BE2A09D83A8664590A8077331491A4F7D720843F23E652C6FA840308DB4020337AAD37967034A9FB523B67CA70330F02D9EA20C1E84CB8E5757C9E1896B60581441ED618AA5B26DA56C0A5A73C4DCFD755E610B4FC81FF84E21D2E574DFD8CD0AE893AA7E125B44B924F45223EC09F2AD1141EA93A68050DBF699E3246884181F8E1DD44E0C7629093330221FD67D9B7D6E1510B2DBAD8762F7" + }, + { + "tcId": 52, + "deferred": false, + "z": "007BF379B97DA0947F2E9BFDE3359E282C9CF1D2E68A80209B533104E90F432D", + "d": "2D229AB46354901491476CCE8FA96E4A5FBA65AB2F538FEDAA528E35687A782B", + "ek": "C5712512984D94A039FC87739DFCAE09934E7658A82FB0895A060D54F900C5AC1161DA09E2D833D5B60E60FB000AF1BF4F43B059B8272E79AF4572349940209BB21BA3BC3B1B6ACC281A35DAA15923496D0FDB32A8505DC8626847627BDE759175F11B457539465CCE3E591933D8B458F561EBA446711CBDF2B604E53B7EE0E0C2C0A15C35AC2A2C91BAC918170E5372C542636D7526BAFAABD10CC6F4382B01C74AE28B47289AB5E463A584465C9994B739367C9F82639801A3681768E134185C9A0DEB8965079A99451418EC051D0D723FECE5B53488207FF7994082C16043B13D278ED530640BE0B4F9AC75B52429EDCA9BC4FA7BDCB43FAB630DB25A5EF576461313CCAD5B2E85E36EBF9594689201458C9B2D96261221C8D3C21D91F53D83F0676ED7A78A6177791557DDFA33FE39699C19339AA9ACD70B34D9036D5391AB57ABB2A5EA368675A565D24A796193351A37C69A5866F4C99482CE4BB3B7795B83E584761EDAC6BFD8CF2433AFC53641E4689571B999E8236A151B6E42855F7E9BBFB8040FFA59CDE707612C9C717F5827DC2B51766889784A6942E8957E6AAAA5D8413F76A37FE69F6259CCFFDC7BECCCC1DAE419D969620C0AC674367558F532EF697058250113DCA01C051A88FABE2CC65795949166857F0F89104A1187C9D30517F25F49308BE4634AAE29B30C8360FF3CC38B5A7BE717584C10A79929B36C1516DE545566B76EACE143E011A4FD42702E95139EB2A746FC04AC99C5E9F07344C83020C34165F9572CD86F50BB9A55B13C6DF33305C8601FE1B103057519BA43B8EC1BF37603C0495F40087CC68A808848429F64BEC6EB336C37AC50F2B5CAC04D6B59870E4ABFBE773664C3926D2954E3D57F2C8147683A519B7264DF40CAB6F3BF262B760BF794416A5D601776E5165FD50C4BA4B07C49AC494C699C4705254A450B36CB38EAF96D6B0270492B84E5A5C208D6ABED761F033138D3BC9FCE42C17B160696C7CA9726BBD2B1C1E42C92556A06A5018EDF605B2D789688CB85066CAA0528BDA4E32542621727301B90333C1E4393FDB539ACF8AFC202BBC42546BB88A04AF9C089717F4073360B567D3967620BD8ACD0BA1762C56603647DEE371F552C92C82A69B1E461E4D1572FBC881AB526B49358F21A69DD3C7CE32BACFEDA9D5CCC34E09B9443EB189F69798FC80B61011B76239EEDC7C77F1B78D3077C5549C48BA8BC720CC2C8B88FC85A9A5CB6C1DA0829C504A9FA502899926BF0DC8FF9C02DC9FC005676A84CF16E2B23B7A5946289E400D0D2387E36841A227B7F10822572BD62F134EEDBCF1A66B6FCC907F9E0AF8D349FA8B5C4251C66B3690BB21A3253F3916020934381B46F1BB9C5F638BF8C8B256300B62B5D6F3A7FF680B514F6B3352A1994C8511957976836BF65979E13002AF1453C1FC037669B3465A0366B7B5F94F92C7707675FB08B2632AEF3D725CC4B3B6496B4BCEA2C865C982F7946079287D63931C8940B130776F5A7629A64915BC4B1FB09CD4C9114B1018937A83047EB3F22EB7EF5C866E9909CC89072E69C973EB22BEE6A3B1E383DA4006CCA560100C72BBA81237C1C7AB0A48A0CC58ACCE826B735C8BA19A87C9AC74E77295A8B26BDBB7685053C5A1572A09425CAE97D7F246D8D0B85AF20350999356ADA86628A787482393FD85A2166245B442F64B5516D595C471BA4CB577644738F87853F65236FF46ABAABEB9236616CF5999EADC9BA80F1C0FE8B6C45BCB543AB8E9097AF977612CF5A4E22C274A278472FA93E2B817706E11813F2B3865851C96683C83B52D2369DF3F74C111B4F4B01202277A918660B9641691412B637B7991973035F77B02D75A2143813BD49847F082C16E31EC89A2F8A588B2D40519892C939D782FFE18BE5D0BE1B5A41D594C32E246F886C37D43145DB8334B0E3364F65A76E0533FE052535DC7945669019E7310587C4C71A3883E1123A9A5BEA542F6D8CAB83CB905D26C82EF72A84285A07687ED90A2A32083F1D8519AC6289C9F6A5FE994C96ACBE0303BEB3B7A5A7457BC0118AE7008A0AD860310CCEA57BC313595A68CC8B682328D8C4440BA57E749BA40E968D09A0783CEA0CCA59B43FE9B42F157F38B67ED0379802ABC1CD50288D73581CCB59E3768C9801138B658FDAA87AC02DF5B5386C2DEFBB8605988CF7B1BC6CDF5C8F1F770EBE3E49", + "dk": "81D65577F87BECBC2A8975A7FB237049AC574D9C934FDC9764FB79597C0CFD236E8F516C3DB4AC0F627A02DC8426C051A6F0421B6A2689ECC469E92A0D816E85990E9298483902A6CAB76E74D476A9300E8121958306959AA362263C885B483E326285CF970BD84A694A553E9BB3AC3209AAE0F0521F3564CF352890289A530717F5E080A916613EB88304A7340A2413C20B02F62B58D68A3C97F57C8A11B1E58611A2A18B23FB3222E84D2ED287E002C1FDCA2D47C03DD5BC0B69210789241AC177907CC3916088B6D5E6B9B7C4C8C975725E38C5A3F54964057114D7CA565BB71F5C8C866A83F0E62AF7866D94C50E89B1BD8F1A8596B477AB743A427252D2128967B962F2E7590ED47670542BDF2162F8C2B1CBE434862670926330B90002E4C490B80A57CC4B02EC03B40CF6250E727C8E1C05E2C36E9E0AAC4FC0C4C4D89EEA2837408B53542513E5C898E62722415CB71B7A9EE7E8634A00028D549A2F912797C84778B7C5D4559A885430124A5D161789EA8972EC9A5298693F4857A4AC905E53A8866148117AA60D43938F84BA60F8C15B7BC88824611AB8EB74852155BFA82127D052B6138E8A7ACF28774DC2C798EA9097723BCD2EA4A0A1B38CB666830008A256F05057D126E9C440AAD52AC7C4B2E370914C2883ECB13AA5F53E43A25D59661809C960545186BB6931BB45561307A4D45C1A0EB80EB0B4166AB12EAAF8CF4D25CA4A8454B179246D3019B8EB5CD86B2BE40513C7828653BC08CC652FA59665DDDB0B94E4AEA22431F7557329434C688B5CC0789E675B0A9395AD2CAC7DDF166E0F5245DF835A00CC172B3A6192808741652C4025566C43177F5A9911B317009A38ADA45F8339693971AA1D773D6FA240F6D7880BB5244115AC2EAB5FC2408BAF4705C7E016E9B1B6A47567DF5298F47437F1C74949232EC496C3054B0A4805C8CAC2255950A8B7F683CF5B531C4C798554963875928CA4204AE8755AF433C2D52784A36404E1A368CC4FAD29BFD879565CA3CB52D56B3F273E7CEC08A1D7180F5037CA61B289828AA3838D01F9958388779ED2881FE894A9D3699542BC0A2C497F7251986B50EFF284474794C845A53E12205FCB823872640B1A8583856DBE11BD6DE49AFC0142AD940EE43B06D9D7141674212297B8478B784FCB8A886508451B376822726E00CD7FA1CA16DB9F591007B2689E0C827929612035F5150800692ECB83B244964FE6922402297F244E430A06AB897DDEFC70742BCA5AF7B634A1B3C8C719EE2909A99C19EA602B7E22C66001CFE5401440139DD6398B26141C9B23914E5940EB35105131451DD3CBEF8654F0483887004D22AABD57559DFFC11038D3BEDE5CBD44DA0119D87610E0CBE392415B33A35F57364C1177DC514AD94570140217982593CD20BEF5E43BD0638EFAD1478CF9943DA093AFD278037010C7086C04A53C0F607D8B867222DB98A56436E6FC3B28D7382116706DB679D9316C473C6D86F85DC40B0A0FE24D8905321336488E20739FB11652EB62C7A05CFDA115791CAE294A0534491CA5EA8F5BA6730E06AF33964469983770D13C858CB66D091B02DA5181ECAEB9C4A241A2222DAA77B6E5020530474C891D440BA6E3F2137B215526001BE17185F0048F3DEBA1ECF7BBF1A55EC9D57485969B43821930DA7672B33630209F8257B8DD749FA9F6C73CE3C903B2300D7304FBBBC6F5304F6DAB322117A621A851CDB66877A82C350B4F42525E16328C7B8A07948794CECAB06D7A7B13CB070C61A983647319E1B6B4E27FC900BD50F485B98121DB4180CB62AE4C3C68A8D59F18885EFEBC90B3F1C9F480B068DACDAD813A28EB200EAAAABD9A0DC5D72E9B4505778807AA6A52AD6142DC517443FC55CDFA56B2A6AACDB28B4B5045344CB418795241756943CC5BA1A4B73A2C90A2122121559FB15B015DB43B621B20F01A4731438B148395CAE4A7C36888FBF01603336991572753F35DEF2264D93BA831A46AD5FB3F663704617B712B81595A585123F03180F46285397551F27E98970DEBC2BF8298329BC87402869DF5B207C7415D1BA9615300B67FACB7A4AB1287E37938C2347C172F96A8826C944CA75C63488A9BDFD206B41C8E6E854B2D9C59D169361BA549254142387337A89C919C84512B2394C5712512984D94A039FC87739DFCAE09934E7658A82FB0895A060D54F900C5AC1161DA09E2D833D5B60E60FB000AF1BF4F43B059B8272E79AF4572349940209BB21BA3BC3B1B6ACC281A35DAA15923496D0FDB32A8505DC8626847627BDE759175F11B457539465CCE3E591933D8B458F561EBA446711CBDF2B604E53B7EE0E0C2C0A15C35AC2A2C91BAC918170E5372C542636D7526BAFAABD10CC6F4382B01C74AE28B47289AB5E463A584465C9994B739367C9F82639801A3681768E134185C9A0DEB8965079A99451418EC051D0D723FECE5B53488207FF7994082C16043B13D278ED530640BE0B4F9AC75B52429EDCA9BC4FA7BDCB43FAB630DB25A5EF576461313CCAD5B2E85E36EBF9594689201458C9B2D96261221C8D3C21D91F53D83F0676ED7A78A6177791557DDFA33FE39699C19339AA9ACD70B34D9036D5391AB57ABB2A5EA368675A565D24A796193351A37C69A5866F4C99482CE4BB3B7795B83E584761EDAC6BFD8CF2433AFC53641E4689571B999E8236A151B6E42855F7E9BBFB8040FFA59CDE707612C9C717F5827DC2B51766889784A6942E8957E6AAAA5D8413F76A37FE69F6259CCFFDC7BECCCC1DAE419D969620C0AC674367558F532EF697058250113DCA01C051A88FABE2CC65795949166857F0F89104A1187C9D30517F25F49308BE4634AAE29B30C8360FF3CC38B5A7BE717584C10A79929B36C1516DE545566B76EACE143E011A4FD42702E95139EB2A746FC04AC99C5E9F07344C83020C34165F9572CD86F50BB9A55B13C6DF33305C8601FE1B103057519BA43B8EC1BF37603C0495F40087CC68A808848429F64BEC6EB336C37AC50F2B5CAC04D6B59870E4ABFBE773664C3926D2954E3D57F2C8147683A519B7264DF40CAB6F3BF262B760BF794416A5D601776E5165FD50C4BA4B07C49AC494C699C4705254A450B36CB38EAF96D6B0270492B84E5A5C208D6ABED761F033138D3BC9FCE42C17B160696C7CA9726BBD2B1C1E42C92556A06A5018EDF605B2D789688CB85066CAA0528BDA4E32542621727301B90333C1E4393FDB539ACF8AFC202BBC42546BB88A04AF9C089717F4073360B567D3967620BD8ACD0BA1762C56603647DEE371F552C92C82A69B1E461E4D1572FBC881AB526B49358F21A69DD3C7CE32BACFEDA9D5CCC34E09B9443EB189F69798FC80B61011B76239EEDC7C77F1B78D3077C5549C48BA8BC720CC2C8B88FC85A9A5CB6C1DA0829C504A9FA502899926BF0DC8FF9C02DC9FC005676A84CF16E2B23B7A5946289E400D0D2387E36841A227B7F10822572BD62F134EEDBCF1A66B6FCC907F9E0AF8D349FA8B5C4251C66B3690BB21A3253F3916020934381B46F1BB9C5F638BF8C8B256300B62B5D6F3A7FF680B514F6B3352A1994C8511957976836BF65979E13002AF1453C1FC037669B3465A0366B7B5F94F92C7707675FB08B2632AEF3D725CC4B3B6496B4BCEA2C865C982F7946079287D63931C8940B130776F5A7629A64915BC4B1FB09CD4C9114B1018937A83047EB3F22EB7EF5C866E9909CC89072E69C973EB22BEE6A3B1E383DA4006CCA560100C72BBA81237C1C7AB0A48A0CC58ACCE826B735C8BA19A87C9AC74E77295A8B26BDBB7685053C5A1572A09425CAE97D7F246D8D0B85AF20350999356ADA86628A787482393FD85A2166245B442F64B5516D595C471BA4CB577644738F87853F65236FF46ABAABEB9236616CF5999EADC9BA80F1C0FE8B6C45BCB543AB8E9097AF977612CF5A4E22C274A278472FA93E2B817706E11813F2B3865851C96683C83B52D2369DF3F74C111B4F4B01202277A918660B9641691412B637B7991973035F77B02D75A2143813BD49847F082C16E31EC89A2F8A588B2D40519892C939D782FFE18BE5D0BE1B5A41D594C32E246F886C37D43145DB8334B0E3364F65A76E0533FE052535DC7945669019E7310587C4C71A3883E1123A9A5BEA542F6D8CAB83CB905D26C82EF72A84285A07687ED90A2A32083F1D8519AC6289C9F6A5FE994C96ACBE0303BEB3B7A5A7457BC0118AE7008A0AD860310CCEA57BC313595A68CC8B682328D8C4440BA57E749BA40E968D09A0783CEA0CCA59B43FE9B42F157F38B67ED0379802ABC1CD50288D73581CCB59E3768C9801138B658FDAA87AC02DF5B5386C2DEFBB8605988CF7B1BC6CDF5C8F1F770EBE3E4987A74BAADEC58CB97414E0D82652052055EEE3E3B64001A0DC6172A2A48DDD91007BF379B97DA0947F2E9BFDE3359E282C9CF1D2E68A80209B533104E90F432D" + }, + { + "tcId": 53, + "deferred": false, + "z": "E94F4E83E6CAABCA9E319D40F6CE0E3691B77C92D9E3766BE9B6F4B6DF2E640E", + "d": "1D65D0290B15903371D616D7AC3F2FADA8CB24E6C84D52C039A10BC1288C1110", + "ek": "F4A4800C492B0472295F4B65471C6170C96DBD90130867CC68369DF450214ECCA22420CE39341A321682C054719B33469BA78C5F0ACD0CF466F2A188713B5154B279E6A6BC1A91032D4948B2D521E3090E450ACBAFC250EC72B7E6DBA3FED99F22730B0588042F33C50F7A81F368ADCB348864AC6DE5479EB1A041F9E3B04304CA38694B5A5B0A674659D6F9BD49AC964ABC4BCC532DB8CAC7A437371DB665AE4CC5B68CAD6AE475472A05F21981998CBEECA435E14C72293127A12659AAA5572042A2789A3B8FCC1D81AA1B95929BDD1A8E13192CFC700AF0E99C6A839EA71297A2A496D9045FBB9425FACC6CC5111868D48AEF176B7462B321308AB199B02CB3A6783749CA845DAAFC1C1C3BB2BA6B0F6C29BA3B428F971C750223B84A5ABAB4B77285A04E03E78D686B38990208A0FA740D01BD05B828F0D36EF5B1056183B93F8238F4AB7AAF872CB7916BD63AA6288337DABA6A5593BBE431ABE3497314F9529A9B5A7B8212C4BC23989A87419903E7B9A2962B310F865969264F2C0A0E6BD99E21C15EB717626D642FC2C6375578780EE13D05A6B3581C70B32C96E4D4178A7920F3A012D3C4C9FCD16556E5965F12AD08B294582A3F441467A3185111E53DEAC9272869671C2CB435E0B60DE5AE0A1A2A53818667500E986395A997722A626ABFA5310E4A43379C15CD3174F4F209379626EF6C4A1F076C73539F26E7C4651317C4545709BC757A92BAF5F417F6B4235A3535D5CB9A6D903D64C89B857A841EA25747F7A0D207729CBBB3CA9B32CB1A38D2AAAD124658C216533F4380ED108040559C8C92CB343C30A5B6A156903E69BA14A3B3C4E9B8C73B2C1ACFA302DB96B9C724B28E6AB1EE489867AAB84BEBC3B417048DDB0304EA8910C55BEC887E59EC336BD96947DA832B213FCF8C68D9832EE0289DFCD8B91DB20BBC81C2833C144A044E917904E9968D0D096482549C55062C0DFA6FB1415FE491051BD9A1DBE65417CA39A0A5CFC79B1A8D909123D287B1E9B7F2A683CB864D693C65BD770C54FB6C243441328C95C6EC7EE5C0802FC0973CE88AD589353A430A543738FC9A5F9EB1730C7060A8279C61527B486669E1C2995F242DE5C42DD0021858C2A3E07250FEB268BBB38FAEF7BE2C4C6CC8B5CCEC0005627874666055091283B7E522B2D96F52A60B031BC6549410AB769BDDB15717A0557561ACE7082FDC463209E63F94919BF3C33BCD012AB9321A0134C017441B578410204A5BF70C57D572C7D7A17F12A2176668A8D9E0C9C216AE9F2466B4F961CBD1256F247EE3B0B23F2AC39ED8757E8A497E161B551CAE1A2C6B88629EE4788DEF79249606195E186398F01CFA070E8B57156922AE4823468DF5C7C5F9065F38639BC77B78A4ACCE5496459346B6D07C49128F0C9A08BBD3C448B97A31255F0B6A388BC8A221009EDDA1AF9C819840C67DAAC24F54D2220058C378E8A4A23825A49A5D4B631FB3080ACAB9BE2DE3A258EA76B01C47B4D8703CD22EB78B02AA2260302192021A0FC031A6FACB03A33055F25A2BB1D6698B4A8DCA9238DD5ACD6787C8912066EACA67FDE86FB6C14687B076D19450CCF75EE328BF9DD6ABB89030AD08BB917B738024022E69A243E779355850B18A7C97F99039271F6EC47418661779C0A528D4079C5ABED21475B864078AA92F69E64F7F12B0BA661B066114F1F43EFBA89B67C05518C15537115DA0909B4A097361586C064A82B6790766944BF99176D090AA8DF599AAD37922B16A2553503AF1B4D7B90FB967AD5A637EFB019E257A6CF2AABD470157352A3196B9339715A1B254B5FF37C8A799473CAC6D0AC6A4AB56BF03271831A33EBA29AF1AE689FF54A2431B5A3F3BA83DB5A51B0492CC2C0DE31962293539278A11B408BF50C0B6D82A9764280DE4F8155201424DDC63F58AB413813FFA011EDEEB4B8B005E707880AF88392A472AD487CB6B6CBAE8787F5F8B4A5822B269E74FD91635EDE9541B5C2A5C9A6FE15722AB2BB61F225D08A84D4A9577D52617EDEC650E429A45B0397147920DE7201925913F029985C229D1044DC1895BEA961F936165CB24BC9DF884F6F49267A19B9B623FE0095EED29B0C75805BD9AA29EE857A9970533344DA99963C057337D4C25D517A341CA4BDB86C74DF0B23A56762B5838F5C68FACD1433B948824CB86D88A1560E77F4EB4A2A95E140B648DB88D", + "dk": "25ACA925E757A4BBA64CE712864669DD8BC9A55007B2C3510AE778DC85A877AB08EC454C61F32205E76C509B81040466BC47C9EAE77B10067C14F241C2E992A16708D1C1604B0C3F5885BD2C86B7B1E8BBD90903B0CA242AE206A6D31846973FA38B9D09402A35E45E98E84D1B125155D86E667960CC058AB25C2B053352C64BC03A78CD86D53BC298A3D586A08C1506103B301AE502176804C328AE1F24CD270AA76CC223709AB7E4B8AF3F28043F5C21B8721F8C228B7F908ACD7C4F1DE5C8939B643B22BDCC1576B65901FCC0720C622C4FA5BADFB7442CF63CCC513A8C7709D3C399469907DF740DDB3104CEB9C92C33113D258AF7EB220EB9AED0B2C1BCBA70CB9C76B840276EF11FAD35BED30CAFE633CCC4E3606F758A0F993D27F80F84473F770565B371ADF5E61689B0402D681F0D93745D625DAD286356A152F689413FB89A569CCC39E71912B3BD345AC5643725969B896328B24568428E5C651401447B490180003CFA674A5093982FA465FFE017B62BB042CC9C67C955B3123B0755430666330547C333196322843744B9213C5528585B4080265CEA0A4931D77C7D81BFE73008B37ABD62082287608ECB2CA6E50CC4C9529E32DB7BB70917A5BC3F8BDAB897E52320395749629104F3B60E27A0D3C09508E422497B7D6F711DE43C315BD83836538F88C30B7AE4A5B5B122D9394E34479D698C8B535354C25B5BE572513DD24A64985D78517AC2F3861330663C1A2AF6C135E0E49E5B930AC6A6A81A203E0A3A4BD1642A304C654681A8769C6C6AB009690A7BFF3B5B9FB64B30C2AFB9280FCF10377601B9047BC6ED0A07310091A97A8016735695EC704FD8493273B2DFD8C1A372C6B7A1A91DA08D3F2767B372A688228135F69D77D1A20CB03C69482A7B67A1E59249FD098E19BC84CEC247922A52A3EAC641F9383EA19200E16874E876AFA5C2598355F5EC01CDA86BE976A7420061C8D9A2F1E341F1378FBBF31DDFE3699DC60637138DC3A19B5FE17D27F0352743C76477363B7C72CBAA2E0F83CB53A82EEBDACF0642C5C39868CDE28F5E83A08046C38B9A1367B2B68C50869E6A9B44379AF1111133ACBF3E51738D2ACCE510A1B5F40B5D17CF5B5710C70B20A1A4734934123C2BC8B1D3714123A4159021B0688484398CA1346D0B5A9CE6AB299F439CE0B83A29261E67B905B944C8E74041431738D4272FB11254CB483907998F364235668C960AB0BE12580908093C31C37BC769BFB285451FF96155102376B8803DB777C15683B963765F2BC40B29558275864B0668F4C269F36B1D6E935C16A2B160E6B9A922080039A2946198BE02A82DFC1B86B310539502B61BC4B8DB533D939B973830EDD6382DD02AEB876ED7332954D2B0F1831953614CE6622BC91C3729F7BC6C45780974B4A40C07B5E4614C858CFCCC4C42E32CB3492F4F36546FB6ABFF9C6AD8C96B54818B3EE3545D2A2687E14C13B29248C69403A63D79A886195C630BA97AA52539C8949DEBE323F68C53EF5AB121D4AA0AC10D2A28A90B39C03187761DE728FDEB17FEF21257DB7199D665D5A5C37823ACE4830F09B3440A345C3627A136FBB416033BB0E73AD9F1B2417075D1F0C928778DEABB59C03A8813FC8BFC8B27797CAE5467C6FC934AF36922F8983E4A8B4F9BA79E2C1B7D9D2297AB273289B8A1EE2CAF8740A201A9C6F2ACCFAC8A0DDF51BDF076521E22AB196811E0834E96AB84606A1E1F018868604BA32C832FDA967CAB1C3021AA4D59A3E731242D7792729CA646D8B976370C2F93332500A9AF32684EF6B6EE7B3690B57409C4A78AC92F9E58CBCF9854B18A737114045EF72C5B808DB039126A8C22C605287292AF93B932AE153EB932CCC06CA4B8DC18AE8C0237EB1122A1C0C1C95E4A5118CE674990707AFA146B5AE620FB44A3FBEAB22649A37495825485634EAA6B7565BFAEA2493D3605D9AB5140C27FEB1350C93998CA8C5E52B14BDB9679763C20D8CA516CB8B5F089BC30E5B9DAE631D6C571AA572F40922E13E8C9488375603605C1D3505FF27033F57040B904D4B71A30098A260169B49495A1B52C76E924FDA088ACD56B90565A49BA8E0A1C66F186367AA7710157CF4A28B2223C2D034079E5ACAA88DB0E9DFB585C7773142A43535CC6083B1EFAB0A8F4A4800C492B0472295F4B65471C6170C96DBD90130867CC68369DF450214ECCA22420CE39341A321682C054719B33469BA78C5F0ACD0CF466F2A188713B5154B279E6A6BC1A91032D4948B2D521E3090E450ACBAFC250EC72B7E6DBA3FED99F22730B0588042F33C50F7A81F368ADCB348864AC6DE5479EB1A041F9E3B04304CA38694B5A5B0A674659D6F9BD49AC964ABC4BCC532DB8CAC7A437371DB665AE4CC5B68CAD6AE475472A05F21981998CBEECA435E14C72293127A12659AAA5572042A2789A3B8FCC1D81AA1B95929BDD1A8E13192CFC700AF0E99C6A839EA71297A2A496D9045FBB9425FACC6CC5111868D48AEF176B7462B321308AB199B02CB3A6783749CA845DAAFC1C1C3BB2BA6B0F6C29BA3B428F971C750223B84A5ABAB4B77285A04E03E78D686B38990208A0FA740D01BD05B828F0D36EF5B1056183B93F8238F4AB7AAF872CB7916BD63AA6288337DABA6A5593BBE431ABE3497314F9529A9B5A7B8212C4BC23989A87419903E7B9A2962B310F865969264F2C0A0E6BD99E21C15EB717626D642FC2C6375578780EE13D05A6B3581C70B32C96E4D4178A7920F3A012D3C4C9FCD16556E5965F12AD08B294582A3F441467A3185111E53DEAC9272869671C2CB435E0B60DE5AE0A1A2A53818667500E986395A997722A626ABFA5310E4A43379C15CD3174F4F209379626EF6C4A1F076C73539F26E7C4651317C4545709BC757A92BAF5F417F6B4235A3535D5CB9A6D903D64C89B857A841EA25747F7A0D207729CBBB3CA9B32CB1A38D2AAAD124658C216533F4380ED108040559C8C92CB343C30A5B6A156903E69BA14A3B3C4E9B8C73B2C1ACFA302DB96B9C724B28E6AB1EE489867AAB84BEBC3B417048DDB0304EA8910C55BEC887E59EC336BD96947DA832B213FCF8C68D9832EE0289DFCD8B91DB20BBC81C2833C144A044E917904E9968D0D096482549C55062C0DFA6FB1415FE491051BD9A1DBE65417CA39A0A5CFC79B1A8D909123D287B1E9B7F2A683CB864D693C65BD770C54FB6C243441328C95C6EC7EE5C0802FC0973CE88AD589353A430A543738FC9A5F9EB1730C7060A8279C61527B486669E1C2995F242DE5C42DD0021858C2A3E07250FEB268BBB38FAEF7BE2C4C6CC8B5CCEC0005627874666055091283B7E522B2D96F52A60B031BC6549410AB769BDDB15717A0557561ACE7082FDC463209E63F94919BF3C33BCD012AB9321A0134C017441B578410204A5BF70C57D572C7D7A17F12A2176668A8D9E0C9C216AE9F2466B4F961CBD1256F247EE3B0B23F2AC39ED8757E8A497E161B551CAE1A2C6B88629EE4788DEF79249606195E186398F01CFA070E8B57156922AE4823468DF5C7C5F9065F38639BC77B78A4ACCE5496459346B6D07C49128F0C9A08BBD3C448B97A31255F0B6A388BC8A221009EDDA1AF9C819840C67DAAC24F54D2220058C378E8A4A23825A49A5D4B631FB3080ACAB9BE2DE3A258EA76B01C47B4D8703CD22EB78B02AA2260302192021A0FC031A6FACB03A33055F25A2BB1D6698B4A8DCA9238DD5ACD6787C8912066EACA67FDE86FB6C14687B076D19450CCF75EE328BF9DD6ABB89030AD08BB917B738024022E69A243E779355850B18A7C97F99039271F6EC47418661779C0A528D4079C5ABED21475B864078AA92F69E64F7F12B0BA661B066114F1F43EFBA89B67C05518C15537115DA0909B4A097361586C064A82B6790766944BF99176D090AA8DF599AAD37922B16A2553503AF1B4D7B90FB967AD5A637EFB019E257A6CF2AABD470157352A3196B9339715A1B254B5FF37C8A799473CAC6D0AC6A4AB56BF03271831A33EBA29AF1AE689FF54A2431B5A3F3BA83DB5A51B0492CC2C0DE31962293539278A11B408BF50C0B6D82A9764280DE4F8155201424DDC63F58AB413813FFA011EDEEB4B8B005E707880AF88392A472AD487CB6B6CBAE8787F5F8B4A5822B269E74FD91635EDE9541B5C2A5C9A6FE15722AB2BB61F225D08A84D4A9577D52617EDEC650E429A45B0397147920DE7201925913F029985C229D1044DC1895BEA961F936165CB24BC9DF884F6F49267A19B9B623FE0095EED29B0C75805BD9AA29EE857A9970533344DA99963C057337D4C25D517A341CA4BDB86C74DF0B23A56762B5838F5C68FACD1433B948824CB86D88A1560E77F4EB4A2A95E140B648DB88D7456EFF3A15CD68111A12974CB06566E9007C376E09CB10D47C73E43546AB16AE94F4E83E6CAABCA9E319D40F6CE0E3691B77C92D9E3766BE9B6F4B6DF2E640E" + }, + { + "tcId": 54, + "deferred": false, + "z": "EC54F6E1E7FB12B796D0E56BE6FE3BA6EDAAB49B08712318B27D229606D2AC70", + "d": "22D19527844F3CDB8A342620A96E902AC7C36E54677ADA6FE8DB08DF4EF3B36B", + "ek": "0E4C2891EB5497C1BEA0A62A0AE207018A2C0FAA8991D76CD14C47916853C326123A3C2997BC27A0B7073F97881EDA9CA18996779064AB768749869E66C4CA6AA58A8B155371B4729BE2327165B103393B23941FC6941A2BBC3C9D1489D6692E146B73A428241172C1EE63161C82A6666B7F5F757BEA328CE6AB45D0D87FBD007333EA927C3810A0A1790DDCC14A607D45A046E23C043CD96196659337FA940E67C565E70CD7D45511BA4C01631D43DCAD1C09833D64BE170A0681E0978D1B4F27E253BBBC5A4C2377299041333A1FA1FA0329B9B6FF24647E3B03954A85BDD637697CA834C95E1A992011D52D2719AD5FC410A780291CC575E82A2AC229BD8C6C42D4673E958ACBB6DC6EA644AAE5B10D5D90907E82614881182B127A53356A26A62C8463B26E5415C131BD72B16D2BA1175FEC0B6E59723FF7CF917968AFC91FE0698F40F55A9C730A1A493314991CD0329083B84292DB23D706755CEB4CF645A706E43512432848639AA757C61E727E8112A06B590488C4917C74041B92C1F34194A849211785C10FF71D27917D45A3B2A67966BA454A3B4829DCCC3CA8493612AB1EB554469E9950B4DB78E8D96E2352CC1AB2895FB16362143A25B3171D4C05A2AA5E5DB845220AB77EBA1166A5842436B226966988BCA3CAFC7997B0A261F97AA24C70BEC48CDDD491A1D2CFCC4455D06AA956348478580D1C70008C0B4AEA3CCFE9EA6C37A3B467652179B446F4D060B532AAB668554ABB88974BA6AF174861D52124EB9D05E60E62E11D67F34F1747951C2C6CE385BCEDF5476B882571579937F57C5C605351D12AEF9C6CD9B8BF35E95F7AC70D50C62B3E68899C39173101AC8EA326DF755BCEDA4B746BACEBE9CB8B233AFAC73075738BE4EB905D26438C5A68D8A14645462DE90783CCBB841431A452B632AD672494377CCE80974247951711A94CB907611C7E96E501EAA13BF225A041FCCFC0318CAC430C58CA043719668E59B4CAB34E2FC2ADE662C7DAD744CB5963ED6A9EF2449A000A6080C555DE2B3EA80C5AB7091DC18C4811697FF6E0A6D2D98489FB211B6B786ECB0ED793448351B80668A46ECB41FB8A642F10A0CC41A1F836303023C33B3B54BA6C2599268C433C6C0832052174739267CFD80C74C3225AC4D75CA8235108165E69F233C213B5AC547794E7CE59DC8D21D76B2CE0CECE43578FD0A1CD38200DF0C020D39563B519BC138B39D819A7A8AAF7D9C931EA75FA9B69369A7A6038B4D3937F7EFB14CE779CC1227B7732172AD10DB932531E426938D067144B6BF4F67C3DB0135573C219552719CB67ECFC07A489BB81F4A0773988E5AB3ADF7C75445868673B6D255B72AA73B32EFC015EA83010F96148A289B10101990290843CBA81E27AC58495F12CB05F5A8454E66F5B10CF0425BB6A1A8580C4C4110304C4717C84431447E510B837C8D70C8B589241592A107E6920FDF8627357C3C0D931F1F69EEEF1C3C518BFCF4305C98A86CE950FA40195F04B79C1471D0389792502C344DA14C884890898262E8292C3E5912A595D0E561CB3594FB4391BB5F4B6571969C86A8457633A5D8212393773D5D736380707BE35895948AE4AE8A672A16BE1E536549A194427C24080BDE083A63AB65240936F3FCA52DCE473EC08B765246AABD6C1F9549C0236676AA2AD234065C65672ADA92281696CD10A1AF1580A88E602ADBA75BC84B10A57072D1695BAE791E26114FCB408576516B7741D0CA9038D2C100884C417F2739930C50E408CC0A83023E6B13C236965802F62B00BFDD0032F98BBE7084AE0B5C6A26613470A8BE5B6C6BAC59B9B725C55C71E4E8A381BF88A0341943B942228FA6E3B3BB614887846F05461D632685486BC73A8E1794483125E58031DCE0A5C8E175C3B73AE08C01D2EEC8677C32F7A2B0D620ACA1D128E6B42095D8B9179369EA88B5697380B4C13552EEA86D9F8188A1C9093B794A9538EEC3A6D5F621A9D991DA6974E6A804D00A2864450C5AE59C4FFE2AEDC23AC522939D5D2204168CD8F8C59E87723DDD4809D2913F6825043EA6C7C9340A91914FBD13C65384B06B955AA221D302112C1F0802F71443FA9ACA95CB236E64886B4B0332BAF527C4AC3A9B4D8956D5FC2904911B944EC3F9FA07267342FFC4CB9CF15CEFE7325CD4C34B9A742B4214F50A50E58B9BD03C053806F0677A35438CF5EFCD8", + "dk": "3E793CFC068B5ED1B1E6D8ACB44ACF89C78CFCA91603E5182B598ED7937F9CA4973DDC1FD3A5023AC5A7C5B34DDD98B3CAFC2B548C9670C18EA16C15982B8B46F74D5A56AB08A1C517FB3543F678C3A97AB45A7A0FB9BFD12AA9BDA96E695674E5A78F3BAC74E033C5A3687A27A13D889B4A36BA339AA25730DAC64C464970FCB268F20F79F055EFC06964F6679AC56EDFB065C39B475370C98C4670387B97B2FC488E567E3B6109FCF28B764890B1E8529DC3BF58851EDA97358AA7B42C872EBFD832FF17B31E2471B091C3254707FC526521B9256997369927286B332CF3657CF3EA584F46ACDC2901B98A117C86430E00474611BA4043953685449D415237BA4E63D99F92835F3BC04C575008FF02885CE26027D914C67CC7F61CBD1C492C07AB1B278B68AB37A13A9C3CCF0BB84CA18DB371C8C4415D29A47F20DB1BC18B52AE4A831DA34B4A541C0D0C9EB17CB2675845CF809709338242A29C9E6239F7797A790A00CA407CBC536A079201C1E2672E343CCE0714A5E8C446D413BAD40E569280B2C2A255481A169A43F5AA501E61914EE35C2964B295914FC4158F7D3678D9B4C3869782DF96189FAB4FD7C171CF3210B7D27E34A593A5A215A4966CF73BC1045402ED8C0E7E548363600A871A0330B81B6CE482CF33C368956E1A49B848755B910A609B77389AAB1E6CF60D75555D21B16336589B474B059813828A8925C681524D9A5FFEF972736856ED169A5E6096E430466D03598619B3709CC91CF24DD4F55AD484B081356A2241B438C37CB250CDDE46072C16454706922F35C5267614943A9155169483D82CA716327501CE7DB313C771AA197367E8E11E5092A519DB2D26FA390BD8070390294589871EBB26CFD636D3D438BB9B0055A8C99F31AFC91245650483945C2C265170D6724102B0B9D0EAAA914CA85C941A6D90668A39582C515C5EC10200C1458D53B0A5B012B4D8B27F917D151C0896C9328903C49DB6B4FBC4526722ABD17C2CDA19A3519BC781C00DF97C5642798359DB358DC153B2885AD8C4BC59E94242BCB3436460048A248CA40F8AF3BF04799B603037567C0A85D65DF17CB9C520B4B56C01DF4C26BFD39FF4D27A1984358465AF96558054A89320434910A54E80D860BC38168D7C1E0F978720CA64C57B7ADDC98B713813F7098D548631BB062B069682E30547AE8BBE394551CCA1A506ACCF37A8B052E86F03DBBFB3025482EA1B2FDC2A9A9B077024B2F0827A33E7661C199201365A840A11F3F649A4097F630B7EFB734438E83C67284E12014282804C46049AE7438352A9AFAAEA2F843A347D753972728B4AF1954248291B4AC278A8813FF5083C582FBB1B8D4D49A227A49A99FA04827265F8C9902B98B299CA4A22668096DA77F7651DF1DC723CB98DB9B921ECDA5634451BC5B94663440F35A358FD8174057A38EEC579E49209B11CCD2DE729E704749E70AD13678BFD365CA26192965076F1F3868503C450DB964EF48061159B0841A06E9A2D51FB78C6033E5A063D30D2C160526531B3BE8EC561D32857136C3E1FF757D150A7E48B876928A1D4BAB34162180E94545285865A6C6988645D1A746C6C744B196C317E6AC95163353EDC381FB7AAD5E07993BC3141A64489762F6B9041CA438F2C135FCD737503A64FE1E5592FA68587B40A7F9913DC560D1104C1A08CAD82275B4AE0838B3BAB51283078D619B77C82980569C524A50158B8F3D352F3060530E9AF6CBC9613C67110773F1A6892E3A83D30B918DE545FA48B19A797BC2A7246D29B251A46325F453EABC1B8EF795A24E488F3C269CE04C3EBC8C0CAC82DF837B4EC46AD747721695C5C18A45EBB52BE0CF608AA08A759F236BC59357387006968C913E97856810DBF266E16F46DB5585D8DC6510A954D3C090B4283318633609A7B3625C54EFC975A127C625AD768F1C03D57584B7D2012E680CCB4EB7A1C822E4BC3182D0483A6D894AA77AC35795717674EB0FACAA0B9C172DB95D257058E7A31B7F6951A3ACB8AA531EE9516C097AE8981671E2381BB523388082D2B07CC9B576401A5C195C05FD1C0849D02869B2834772A1EE6776EE66A970CE2B9021193D13C2642A2A3271C093DC858424115B9C1628AFC31BCF7AE18783602813012750A4CCABB1E609C2A649E0E4C2891EB5497C1BEA0A62A0AE207018A2C0FAA8991D76CD14C47916853C326123A3C2997BC27A0B7073F97881EDA9CA18996779064AB768749869E66C4CA6AA58A8B155371B4729BE2327165B103393B23941FC6941A2BBC3C9D1489D6692E146B73A428241172C1EE63161C82A6666B7F5F757BEA328CE6AB45D0D87FBD007333EA927C3810A0A1790DDCC14A607D45A046E23C043CD96196659337FA940E67C565E70CD7D45511BA4C01631D43DCAD1C09833D64BE170A0681E0978D1B4F27E253BBBC5A4C2377299041333A1FA1FA0329B9B6FF24647E3B03954A85BDD637697CA834C95E1A992011D52D2719AD5FC410A780291CC575E82A2AC229BD8C6C42D4673E958ACBB6DC6EA644AAE5B10D5D90907E82614881182B127A53356A26A62C8463B26E5415C131BD72B16D2BA1175FEC0B6E59723FF7CF917968AFC91FE0698F40F55A9C730A1A493314991CD0329083B84292DB23D706755CEB4CF645A706E43512432848639AA757C61E727E8112A06B590488C4917C74041B92C1F34194A849211785C10FF71D27917D45A3B2A67966BA454A3B4829DCCC3CA8493612AB1EB554469E9950B4DB78E8D96E2352CC1AB2895FB16362143A25B3171D4C05A2AA5E5DB845220AB77EBA1166A5842436B226966988BCA3CAFC7997B0A261F97AA24C70BEC48CDDD491A1D2CFCC4455D06AA956348478580D1C70008C0B4AEA3CCFE9EA6C37A3B467652179B446F4D060B532AAB668554ABB88974BA6AF174861D52124EB9D05E60E62E11D67F34F1747951C2C6CE385BCEDF5476B882571579937F57C5C605351D12AEF9C6CD9B8BF35E95F7AC70D50C62B3E68899C39173101AC8EA326DF755BCEDA4B746BACEBE9CB8B233AFAC73075738BE4EB905D26438C5A68D8A14645462DE90783CCBB841431A452B632AD672494377CCE80974247951711A94CB907611C7E96E501EAA13BF225A041FCCFC0318CAC430C58CA043719668E59B4CAB34E2FC2ADE662C7DAD744CB5963ED6A9EF2449A000A6080C555DE2B3EA80C5AB7091DC18C4811697FF6E0A6D2D98489FB211B6B786ECB0ED793448351B80668A46ECB41FB8A642F10A0CC41A1F836303023C33B3B54BA6C2599268C433C6C0832052174739267CFD80C74C3225AC4D75CA8235108165E69F233C213B5AC547794E7CE59DC8D21D76B2CE0CECE43578FD0A1CD38200DF0C020D39563B519BC138B39D819A7A8AAF7D9C931EA75FA9B69369A7A6038B4D3937F7EFB14CE779CC1227B7732172AD10DB932531E426938D067144B6BF4F67C3DB0135573C219552719CB67ECFC07A489BB81F4A0773988E5AB3ADF7C75445868673B6D255B72AA73B32EFC015EA83010F96148A289B10101990290843CBA81E27AC58495F12CB05F5A8454E66F5B10CF0425BB6A1A8580C4C4110304C4717C84431447E510B837C8D70C8B589241592A107E6920FDF8627357C3C0D931F1F69EEEF1C3C518BFCF4305C98A86CE950FA40195F04B79C1471D0389792502C344DA14C884890898262E8292C3E5912A595D0E561CB3594FB4391BB5F4B6571969C86A8457633A5D8212393773D5D736380707BE35895948AE4AE8A672A16BE1E536549A194427C24080BDE083A63AB65240936F3FCA52DCE473EC08B765246AABD6C1F9549C0236676AA2AD234065C65672ADA92281696CD10A1AF1580A88E602ADBA75BC84B10A57072D1695BAE791E26114FCB408576516B7741D0CA9038D2C100884C417F2739930C50E408CC0A83023E6B13C236965802F62B00BFDD0032F98BBE7084AE0B5C6A26613470A8BE5B6C6BAC59B9B725C55C71E4E8A381BF88A0341943B942228FA6E3B3BB614887846F05461D632685486BC73A8E1794483125E58031DCE0A5C8E175C3B73AE08C01D2EEC8677C32F7A2B0D620ACA1D128E6B42095D8B9179369EA88B5697380B4C13552EEA86D9F8188A1C9093B794A9538EEC3A6D5F621A9D991DA6974E6A804D00A2864450C5AE59C4FFE2AEDC23AC522939D5D2204168CD8F8C59E87723DDD4809D2913F6825043EA6C7C9340A91914FBD13C65384B06B955AA221D302112C1F0802F71443FA9ACA95CB236E64886B4B0332BAF527C4AC3A9B4D8956D5FC2904911B944EC3F9FA07267342FFC4CB9CF15CEFE7325CD4C34B9A742B4214F50A50E58B9BD03C053806F0677A35438CF5EFCD8CC8CB55EEE0FF5BA0F84F958550BE099B0E692A35E0908A5FD21A36B521C0F1EEC54F6E1E7FB12B796D0E56BE6FE3BA6EDAAB49B08712318B27D229606D2AC70" + }, + { + "tcId": 55, + "deferred": false, + "z": "5B78F8D30AADB59FA617EF807D5C23113A9908342F08E898E02991CA1D7B934D", + "d": "A00D1EE4147DD57B5E76C58A928DED0B720FB2FB6353780B380B5FBC76712E5C", + "ek": "B3C014D82BC4BFA186D2E2A4FCFB57E2205FE91195E1ACAA18A3699D1BA700770482C18160082946D85BE262136B7B1F5BBC00D4D20A1351C66966CE3C1A06EBF35A43036A5498424C73BA01C250C61399CE951AF176C96F317B0A23395164075A23A6D6A55916F5032310B5E28B1B970C3AB75B4058C86DD9A73ACE89B9F5A272A86B433AEB9AD755B166105AE0095645910E0AD6045C075B82596140213DCD231C03D0786C186C95342C01265B03A2A113374307B49062727C82F2CBA44862C7691703374AD76B772DA400C283A1AAE348EDA9582B9B42196216A8218305309C367648F58785B74A9E4DC068318BCE4CA87000DC86ECC52F2D465762A58BCCBA755E7A881AE5704C643278E784E646C48AFC3F240A728C4A6D2B6523EA3499C9344294293497D3A4A3E2373BD2CB48B0575DA052253693D1DB696DA0057B2243525AAB17770D61D09D0F3554D10AA7A56B6CB9A81F59EC73A1FB9A08D7BB08D90F70117A2988409B870AA2F82447E14DE7B3C16503CE645BA54EE5C6E71909642A3F76620AE0D479A6440AA5E457A946A884D0C741A2C7F27C9EA9E716EE1C01154120E777930E991C63E0A3134B030A8A0E220758C074484FC7019C5AAC212246F990C41A5B5E468888A5280A23057CA0B23947F332213A86910912C090421D4A008CC219C9C571AB09A9C59C248FE71A2C928D83E6C4DD5929D4D1B8F0CA98F4608F89EA1D59F063D827123026C7EC093A6360590BF54BA041C2C21473DD89314321B334680CE65B5737857D5FB557F1967075C9889266298F332A19C5888A3497F0580B8BE1AB4F7A300F6248B4D99431E4B9CF163E9B969FD7B664AC8248789C2866D05D01C579B491BC50C8099C30A0E6076800B00CB27929ECC8C9B7C44B32781070188B747C6EC1997017E8435035CAC06B2E74D54EC8B64E2A9B9BD6351604D3875C394C183B4B7D362866C96A78569A9E88C2D8767FE0CC0C55C506E5A50B1FB9CC18910D9F22648681CA8C66529EB3665E08BDDD725146C343BD7B9E51D37F57B602E012A1096793931097228A1536715923CA93D8C41816E04FA27A16F6EB50BDEC8A26D99FCC1901938B7475731DAF85C2058832315B93E9DA81B415B707F95EDC44BAD6AC3016E4A16E787E3FC59DF904AC385ACF28EBA6EE61188883CC72E9B298F02D2D49CEE59B6DED348038C7055202B47CBC0B40774BA78CAE78079B9E8A9392CBB57CE4400E9214C3784BCCF94151D510B182403D990C2F8C984B6AAA3AFC21F9F6711EF91EEB008482845FDF60BB5917720EC9C774943E04A7A5FAF161ED557701BC26717ACB2CC059E1308E2AA76D04919B30A70CC698402FA58D927C8A02773815A144128C5BD183A38C3182BCF19DB7A3158B9393C767926F5737B6B60EDDC01FE8930ADC2C4414146A9968311C0B367647911F4AAA4443AD0648C634828C62C0BA01C161162B5EEAA78CAA9A1425F55950EAAF71841250008FE1CA3B8F8421FB4438E65AAC914AAADCB45FE303CD9165CF867A7E9304CABF0B3E1DA63A5FCB56F03753D7074525425131D555B5E583B303B6616AB6EFB68CD5994E9296608700BD3239B03AA6A662FC354E2A49314B63D9E1801EA5127FE653E459B90E94C039D812DC031D536C400A2A70B860A9AED7BCC286182933C62F7C1E73B615F1525F6A165DFD4461AE0B856B298B96CB6756AA2255949255E6C95C12A969A698D37B6FC8B7B16BF1AAA1734DCFE1160D319B25236F591C7CFC8A08FBA48B42586F3371B0AB061C92F9C0E3E350DE5941C9F380D876480C2623F526111D676AB33ACA5D66185655A94E13418576B632DB8A0D3830738C44AF9C979514254ED8C82E34AE5DD6458E2039690B8492C353E2F0937887088B4786BAE016104648C0544482C562E0D2AADE390DC03765C7C1353634B83AB66AC7E1306378B5032B3148BB799E8B4907188EFA993FE72C73E3162F2DA43F0EC7C2F1C162EFFB5659A947A3AC6203B1C825125023926115605CA1909D912A0108C0115FD75D967BACF32B656EA64BB1808D1C1B43E8D7BE02EB6432D89B59F9A3FD109AEA36ACED2A137214BDD8686D977A68A6E4B6ED6C916A8594CFA3700AF608CB6A91AF150077D5A40EA4471AC19A7177B1E6A6BBD8A357F416BA8935AE73829A5B035B79AE8D108ED5D05A089242ECDBE94664DA47F187D3D493AC23E7", + "dk": "91200CC986B3575202DB535E04BC2E37A499076781ECFC2E5CB0259BE2A5618C1CED22128D194B0BF4397D6AB0E2F30F6AB23260BCCA10507CA7015C80D9409B4BC06DABC661D3A653208A505136926A554CE331E4B692105044DB060576C1C36A726C0E1379C463CFF2183166052813A6BC4B93365F2798825387209C8C53A1C2DE453887B20061E71245CA6C1C27809242C14215924FDB901EA035AAC45EB29B518D0477F5D8CCB7D39E16239EB0A5254F6380F328C1ACFBCDE08310804195B944AE8D98BC1D75325E062973D84C5AD958C14076720C4876A5B903E80DDFC7BD66E1B55356B896263FC3451E2A865212CA3B9C510FF0CA4865B6C1F2791C1A77A67336A429C9569AFABF535888D1075ED2B1A31CA78B9E3353020800FC18C1D47CA6C326529A375FDA667C06134986B891DCBA7F6AAC901768A156270A6E46490B33378EE75648BC4DCB1451A2212931F2096CD8500F23817975C25FDC164F41CB5D8A3613EC993A57711585BDE822B519683F8C9CB95ED701D6905F20A46E29C0C90C448B42742FD1BA05BFF590D2D97317C2473688A4B6AC63CC1CA28AD71FB7C5252C42534D27AF11D5947E1AB196CB2AFBCB41E0A8C50AE274D8CA1971B605520503E9C17AB6F41232FA9130BC951DC031A66A02A663756ADC7C15BC513ABC1592CCBCA9F5CD3AB29B2305B32D98C877217A1B92321930B34A096641070428B65FF4108A36C998E895375640B57788A72302931DB058ECB52F4D7A0623D74AC223C4ED6024515A364D280EE056760CB451280772AA0CADD1E0333AEAAB5357479D01696DE52AE2C8B71705706BF15C05064CA434280D4C8CAC411B0A390C6D6BBDF5E684BE3B850D3A83BC31C5C823604E533242E80DB57B2598CCAB30E53282F140C9897C85EA7BC9FC378761BDAB629E46336B714C0189E214EDB254512AAC558541D30CADEBB9665A1914A9D001F43504A0E0A566B311E746379F56558A760618C753A57B6B1A4251090795466A178A39904268A10F2451484C6B11C037953817AB156EF7383878B1BC38790CABEB4991EB2768A83F580945D46C49A8C0CA26BB99F72C40B73439253180DEE2A425C54C23FC6718A40611455BF4652F8CD91067B42131EC03CC5C0B59EBC5FF30B097D764306CB692ABB95D192CE44B1C0E981162F73997148DF270630AB6B37129813599239AFB46CDAA40CE472310EA67C2E0BA18765D34EC9FBFB82CBDB4BB6797B849BC778C9710BCD0BB2C611990B3232AAA4D1B898371738AAB9375813913DBD178A4CA2EEE4A8D09E72EDE6189272B1EF503AC8302A63396798FE5731C223E53E90EBA3805D1F8A65DF168C71408682C2790A167557A15E697A72CD2CB613B7371838EC85BBFB510B3344C3B61664BAA8B90079C30181ACBA83AB049808CE6421DB67393865C43D43C3825281492AA68413BA560B123E2140DC114060F93101CC08C63D848B172010C56C2F5377AB4B4A31CBCB265FA607F504147C0009EF812788A7EC53514460A8C8225A664348A5347291B73B423C8385CDCCD34A277913841F2C2434F2A34A2EB02B7270274E4AFB3F19933402E1A340D8A8B6F50EC4930086D462A85C9AA80950711C092BA7135A45CE30B37FBB21C574C6A1263D0554AADF36D9A6567716B914F41617047973D54C3F573805CD38170F004BD014989D33D939132A39B44D49345B857792B241B0A870396D95CCA133E7A7001579930DF70C201A71951E11257356129255A044678BDFCA5A7FC32001167155659F41B4022A9B15B37A197FC7C567CA63D74B4E9D286100861658139A98C868EBC9207237A5E4BC26EA867DA305A3C3A36083C9F79523B45F53B8FD40591304836B8520B227905413FBCAB24B22A7D1334452045AF354A4690455144390A381C1172C18D865C86B159AC944906F298A00571B61420BAA7E67787AC2256EC7217FB0C00C48960165CA6E4416059A4CAC2CA9535C8DD2265387B1E18950A7C917EC73AAD76A753E0D4A285B19089E264B6A53A35AC523FA955A4B48FCA59344503B12675B6C6C99593EC996DD9C456D842054A52DDE1106E89A30B5732FBF5C88BA98833A26FB47350D0509B17E8BA76878C2FB485B7CB5E7B4C73F6929FE09B54A09454A7145A4A812C26240EBF4126B3C014D82BC4BFA186D2E2A4FCFB57E2205FE91195E1ACAA18A3699D1BA700770482C18160082946D85BE262136B7B1F5BBC00D4D20A1351C66966CE3C1A06EBF35A43036A5498424C73BA01C250C61399CE951AF176C96F317B0A23395164075A23A6D6A55916F5032310B5E28B1B970C3AB75B4058C86DD9A73ACE89B9F5A272A86B433AEB9AD755B166105AE0095645910E0AD6045C075B82596140213DCD231C03D0786C186C95342C01265B03A2A113374307B49062727C82F2CBA44862C7691703374AD76B772DA400C283A1AAE348EDA9582B9B42196216A8218305309C367648F58785B74A9E4DC068318BCE4CA87000DC86ECC52F2D465762A58BCCBA755E7A881AE5704C643278E784E646C48AFC3F240A728C4A6D2B6523EA3499C9344294293497D3A4A3E2373BD2CB48B0575DA052253693D1DB696DA0057B2243525AAB17770D61D09D0F3554D10AA7A56B6CB9A81F59EC73A1FB9A08D7BB08D90F70117A2988409B870AA2F82447E14DE7B3C16503CE645BA54EE5C6E71909642A3F76620AE0D479A6440AA5E457A946A884D0C741A2C7F27C9EA9E716EE1C01154120E777930E991C63E0A3134B030A8A0E220758C074484FC7019C5AAC212246F990C41A5B5E468888A5280A23057CA0B23947F332213A86910912C090421D4A008CC219C9C571AB09A9C59C248FE71A2C928D83E6C4DD5929D4D1B8F0CA98F4608F89EA1D59F063D827123026C7EC093A6360590BF54BA041C2C21473DD89314321B334680CE65B5737857D5FB557F1967075C9889266298F332A19C5888A3497F0580B8BE1AB4F7A300F6248B4D99431E4B9CF163E9B969FD7B664AC8248789C2866D05D01C579B491BC50C8099C30A0E6076800B00CB27929ECC8C9B7C44B32781070188B747C6EC1997017E8435035CAC06B2E74D54EC8B64E2A9B9BD6351604D3875C394C183B4B7D362866C96A78569A9E88C2D8767FE0CC0C55C506E5A50B1FB9CC18910D9F22648681CA8C66529EB3665E08BDDD725146C343BD7B9E51D37F57B602E012A1096793931097228A1536715923CA93D8C41816E04FA27A16F6EB50BDEC8A26D99FCC1901938B7475731DAF85C2058832315B93E9DA81B415B707F95EDC44BAD6AC3016E4A16E787E3FC59DF904AC385ACF28EBA6EE61188883CC72E9B298F02D2D49CEE59B6DED348038C7055202B47CBC0B40774BA78CAE78079B9E8A9392CBB57CE4400E9214C3784BCCF94151D510B182403D990C2F8C984B6AAA3AFC21F9F6711EF91EEB008482845FDF60BB5917720EC9C774943E04A7A5FAF161ED557701BC26717ACB2CC059E1308E2AA76D04919B30A70CC698402FA58D927C8A02773815A144128C5BD183A38C3182BCF19DB7A3158B9393C767926F5737B6B60EDDC01FE8930ADC2C4414146A9968311C0B367647911F4AAA4443AD0648C634828C62C0BA01C161162B5EEAA78CAA9A1425F55950EAAF71841250008FE1CA3B8F8421FB4438E65AAC914AAADCB45FE303CD9165CF867A7E9304CABF0B3E1DA63A5FCB56F03753D7074525425131D555B5E583B303B6616AB6EFB68CD5994E9296608700BD3239B03AA6A662FC354E2A49314B63D9E1801EA5127FE653E459B90E94C039D812DC031D536C400A2A70B860A9AED7BCC286182933C62F7C1E73B615F1525F6A165DFD4461AE0B856B298B96CB6756AA2255949255E6C95C12A969A698D37B6FC8B7B16BF1AAA1734DCFE1160D319B25236F591C7CFC8A08FBA48B42586F3371B0AB061C92F9C0E3E350DE5941C9F380D876480C2623F526111D676AB33ACA5D66185655A94E13418576B632DB8A0D3830738C44AF9C979514254ED8C82E34AE5DD6458E2039690B8492C353E2F0937887088B4786BAE016104648C0544482C562E0D2AADE390DC03765C7C1353634B83AB66AC7E1306378B5032B3148BB799E8B4907188EFA993FE72C73E3162F2DA43F0EC7C2F1C162EFFB5659A947A3AC6203B1C825125023926115605CA1909D912A0108C0115FD75D967BACF32B656EA64BB1808D1C1B43E8D7BE02EB6432D89B59F9A3FD109AEA36ACED2A137214BDD8686D977A68A6E4B6ED6C916A8594CFA3700AF608CB6A91AF150077D5A40EA4471AC19A7177B1E6A6BBD8A357F416BA8935AE73829A5B035B79AE8D108ED5D05A089242ECDBE94664DA47F187D3D493AC23E7DE32CCA3941492845F6502143FBF02028F22B12F1ABADF29BD12458E5B698A875B78F8D30AADB59FA617EF807D5C23113A9908342F08E898E02991CA1D7B934D" + }, + { + "tcId": 56, + "deferred": false, + "z": "384509DB0E97D4689A3CED953CFBFFA9D3B3B87CCB0C6A360FC0DF3CBCA399F9", + "d": "2C34B1476753095D0C8A48A00136F358A98D1416E5069CBA4540C6E26FA3634D", + "ek": "6A04C9598C985A554021C437246C8E1DB67F69B6092F7A18BA3309245480FEA533B478726E4C761568A00DECB368F104B1E908F1E9BE85022D6998581428881C6C1B06A89141831DCEC1A139303FBFD04174F06E81D09DA38251ABC33C32422917EA165FE821793BB13D553EADD9AE86C750A7C307AC6467F117B778ACA8E1CB8360152388EC20742011FA66C786675AA4813C8CD58EA2FC9ADBC4AECE94C1193B1799306D6DE532EB32928BD5957484B6E38272172B902AFCC4207958A433058280713FF055A9FB0FE6A3C79564A75C32AF13B4338CE1ADCC5825E9475C66201B8E6393D493001C29A44BB20326DB06983BCBA96805EF0573DAB1A506C33150A974EC96462473CA7AC7066F374A131854EF01A99A30770B0B508CDCB2B5D2B5F2208005378AD0935243EA61C8D876A1602CC047871425CF33BC22E07A94C71737BE251E75F85594F523B4CB241E97AC0306B8663075B8B18ECE09332991C774E225D7722DC1E87052E19293F8B802E7366A3C76D388351B63A11AF5703B4862699124E574B0117788DD89C8D7D2BC34806DCD183F28784E54B2725EDC9A797B1A9F110C0C91154BC927B06C77335A07E372B5C10C4DC8C5BD80EC79BB68AEAF8BAC1C583D4055C5EC4592462C60165C636F2A5FC3F9A0035B0094755AEEC7B076A7C84F8C3DA994C9C2C10C1E17CE56943933D733944753DF2546342890BAF305BA3B08628727BBF492F7123CA6DB9E067A02A7FC20B9138E5011A9E08116E77382C9AA594BE18470D0B9B3CA82FC652398A3B7466065732030F8622AFB4C29A88B1F8539976902AE18C9C0EF10780D8B405EBB37D873C6FE4534B8AC444D8A7817F6CE0C36B8C53AC03328B8D4B30DDA4111A7749B6476516B56147B3B9841E29D20520EAFC9247D9C6171A1165C971941A06CE6F58EC0A5B4FCF21CA78857BD6B2F0706BE3F568E380C24E537C31D74B0202014A24321AEE877B7E457FB669903A30D39AC9188239BA29157ACC82AE671C75887C0F1C9AC11DA5974E438EFA438467755EDB0C949536274DA3989972356A845811273E5308DDD4A3774047E7F347330133322521586635622937867DC549E058AC1D65BCAA8C6DED93C52FC329DD038DD244428EC602D0B11D5707AEA029328B61BFDE51B4EE3BA4CA8561031BD939ACBC70276A309D028A7674C736668D1735EF83B555689DD5790852916F450812F0A809C183A4BD2AA79B74FFEB232F3D67EBD0B3F97037ED8EA8A7C6CCAA4D300F3E01F2B8661AAC39FAFA78197A2482ED4745C56C757A692B1900D7DF921D6C35580F9882CFA294DFA0DBFC29BA21C9F648515EB2A81D2BB0F75941C1C1C6541D949A5454D96FB486C79B11BD9B56F45651B3567C75A261CB5C0B077352486C37715CA8D4CB727B167567BC58A530543047C1FA2459F87C837623C5B2939FC53AABCD5B1B8271A67C95B3E33C2D9922836A25BD1E61692BB36FF87229779AB75A883B26CB6B27553FB5782DC3C62D70C4AEFE86A3A36934770834142398187983D766BDE4916EB76852D74010E221460C4C5FEC132AA77B618AA0F81EC6A8E83BE7BE37239F1CEDD206EB8961F0D2AA3FFCB272A0785A36537240274C9993C4904A731995A3019CF6133C714185A449376565A65B5C2B1DEC8896C1BC46A1575CDF80958F2B96329791C208F51B4A8F41A8356000E0F1C51EC584ACE4434BF0035B5127478C11D659B842CAC49AE873F8192659A5735F87B7517B118748A74B8020D2823A25952CA3F43C7D3614741E054DC0B5E5AC11C8FE15E7F908A7B64B3016A39218134FB3092E7482E7399310709BE369CA383E95AD08718CFBA21F9DBCC8E0600DAD2C39B368A24E79DB0DB02395949CAE835AEE683C4A6AA6024B3109C18DC2BBAD65BBDAA52ABA6D9487EE3194579494B2441177019C0BCB78F8A2FCF7BA875548C1C3603AE3A874D2454C11074047310D136AB4EAA348F05B4662989CC6896DAAA24A94154CDBB30FB5023A37779B1E29F71A841830274B733ACAEA69D84FBAD4F138861FBC35F0545489AC8342A4F6F8C584A8442447062D35BAF44B3C92A38CE11A173FD5A3D8D6B24BB390ACE212E41042E75D50E318C6FB037AFCCB2B069E2BA66AC1233D53031279ABA1683AE42A745D0002805374165EAB94A17EF6881F0BA9392CEAC27250E82622E6F40D3810AE40CFF1F8496", + "dk": "BC00ADC7652EA7DCA970F2C234A87D9C3340EF2994A79A71B7200F9168CF76D9A301B85A01E6AE69D8959533A53F4890378067A6068C2C8201D373BA49C69FE6EB1716FB6BFAA4ABCC071B191515ECB758EE859D40A12429DA703052947F4097E7E40180477C01B62944CC2CB7E63952921E1EBBC800E1A7385B01E528548A31B0BBD0A5B0641E9160C36236CB58A36555D88AF118C35EDA2276B38D5A8C0C091795C1254D69AB5D4DD309E376BDD7E4A3E1333B3FFA378FDA8E62525201F9458F53443A255ED79B71102A2F3EC347166CAB38361B3E668BEE7588AEEACB5436B1F8E360F1D73999E290BC25C036ABAD878890C54BC8DBB863F8E23E5323ABDB004141C9C3C0963B7FFB7EDBCB545114A61A6B58F8487A07F388F4F5C00E9CABD425B7BEAA2B9947A0482A21572B48E65C8FCDBA214C0204E246CC3EAA069DD42DAF7285ABB55DAB8B2A016805A1C17D46C131ABD4483BAC6B5CB8C36A810DDD100E4A66A58209CA60877E40E2BF58E37BE97C8122D7097ED173FB272AADEA18EF91120405435365BF670C17B99068226597DDD7C4A6A16F844616C885666AB482B7858FA31405B86789CDA046D6561E997689C0D0A461E776C7313E811AC02D1BA8A95038B12430748644D0B933C9E35F685229D97BC810B3203C874673D18E8E0131FBD368C47466A9882F4A41473166C2E240A82D36B983273208EC4008231773D57FC9D4330703565CA8759E7CA9E64130BC5493C9F52C93AB4A7B3754B0F55EE9779CD08B2BFAD71899B75CD274ACA7C2BA9575AE56DCADFF13A6E6C5266BB7AD0D8BB820660023E9BE0FF759202CCEDFD7C3F2048D6B345CAA1C82D479A4D4E2C48A1818DA022435BC3D64B38C811B0BCFC147FAA505AF13740B78945F973BFD2A21A6A040B65214F934154E722D7F195877C5476EE615344462C2A95744956DCB5B2657F27DC2C6AC14E92E8404082D8A0EB6E488F2E56FD0292FDE931057D534051700AD0CA85ACBB5C6C02077DA856931899BE82CFA0A794AD1182CD3AB5E5188C357C3A2D9BD130A62223293DD249E477271C9E14AC48017D013A1435A5976C4165E8932CA032493B33814F90830A5AD75E32F747B94B4C52BF5EB30F73C02BCEC5903BA01F99ACF8B9ABB671B8D219C029BA1A2A6E847E86091C08C00B3914DF8D075C3913C805104A3B4BBC798B9F1D20AFB8118B7F26C32633B39FC792B3358606054BE3693A6E7B9C6B6B3A848A2D0B2ACD1C406706CB590B4B79B82BB88415CFF45376B8102B644193FA1890040127B58BB351862F3227AF18A50A9A983387A8646C99860BA2373337FDDF25CF8916E00252AD07516D1BC5629245EB341B1ED4B63F93044B131C01E301E8FBA5DE8AABA76F70F7D2A3ED4F78AD5210B47D8756E334D32CAAD88C22DBC537FB766447B09A05F1685C24A80F8C3A3202790B277A6CDC836767793D81955BC90A3DB3B71BD8C2FF01A12A59541A666202CA98689528DF9179A26156A6A414BB8DB350393B6B0F35DC163CBA4C94242A33C9778BB35563A8D213A9914225A0C6876B75035201DD14048DE28AF97D77260476DC399B37DBB48F3C943F3C990ABA7068D4299F7D289C6D66D4243570AF38D8FE95384B27E6B0C01258262CD0465F5FB5F424CBC9C39CF5948804F7034C632CB8A7B4ABC3095B174951C42364B05396E140524B989A889CDCFCA4F222830A98B041338A0273478E3661A5D44214A52A54EC65E933011EB7148EAB94E58EC1C9CB9A0E61C788880B15413B8365A929342B667005D6A35BEC272955F5CBB633798094A0DD84A09B6A04B16BA9D1C005D6B1708CD4300D26B506748CB7B4CCFB59818FFFCAC2A141ABCC1AB85BBA36C69608CCA475BDB61A56BA2FD6B2F75F502FCBA8AE05B11B73A381A810681EB0B1F446007267F7C12526BC3B430CB4BBED0694C290B0EB238056B5C64C1AA072C97F7173647BCBEB75965BD71C0747503929ACA0FD98EFE45C744A4B5BCC748616A8B24C5BDA4F0B9FCD42767420971A00F32415976B5A4DE31C03B10858CF1995B7B8526FC352A0C99A57095EEE0B8E7E40364587623B00B1799C807289DCFAB746B06C3E2912A6D3778FFFA8C1B43A39A433708817E7058C03698268E9275BCF21FB73052874307FE56CC8A384E6A04C9598C985A554021C437246C8E1DB67F69B6092F7A18BA3309245480FEA533B478726E4C761568A00DECB368F104B1E908F1E9BE85022D6998581428881C6C1B06A89141831DCEC1A139303FBFD04174F06E81D09DA38251ABC33C32422917EA165FE821793BB13D553EADD9AE86C750A7C307AC6467F117B778ACA8E1CB8360152388EC20742011FA66C786675AA4813C8CD58EA2FC9ADBC4AECE94C1193B1799306D6DE532EB32928BD5957484B6E38272172B902AFCC4207958A433058280713FF055A9FB0FE6A3C79564A75C32AF13B4338CE1ADCC5825E9475C66201B8E6393D493001C29A44BB20326DB06983BCBA96805EF0573DAB1A506C33150A974EC96462473CA7AC7066F374A131854EF01A99A30770B0B508CDCB2B5D2B5F2208005378AD0935243EA61C8D876A1602CC047871425CF33BC22E07A94C71737BE251E75F85594F523B4CB241E97AC0306B8663075B8B18ECE09332991C774E225D7722DC1E87052E19293F8B802E7366A3C76D388351B63A11AF5703B4862699124E574B0117788DD89C8D7D2BC34806DCD183F28784E54B2725EDC9A797B1A9F110C0C91154BC927B06C77335A07E372B5C10C4DC8C5BD80EC79BB68AEAF8BAC1C583D4055C5EC4592462C60165C636F2A5FC3F9A0035B0094755AEEC7B076A7C84F8C3DA994C9C2C10C1E17CE56943933D733944753DF2546342890BAF305BA3B08628727BBF492F7123CA6DB9E067A02A7FC20B9138E5011A9E08116E77382C9AA594BE18470D0B9B3CA82FC652398A3B7466065732030F8622AFB4C29A88B1F8539976902AE18C9C0EF10780D8B405EBB37D873C6FE4534B8AC444D8A7817F6CE0C36B8C53AC03328B8D4B30DDA4111A7749B6476516B56147B3B9841E29D20520EAFC9247D9C6171A1165C971941A06CE6F58EC0A5B4FCF21CA78857BD6B2F0706BE3F568E380C24E537C31D74B0202014A24321AEE877B7E457FB669903A30D39AC9188239BA29157ACC82AE671C75887C0F1C9AC11DA5974E438EFA438467755EDB0C949536274DA3989972356A845811273E5308DDD4A3774047E7F347330133322521586635622937867DC549E058AC1D65BCAA8C6DED93C52FC329DD038DD244428EC602D0B11D5707AEA029328B61BFDE51B4EE3BA4CA8561031BD939ACBC70276A309D028A7674C736668D1735EF83B555689DD5790852916F450812F0A809C183A4BD2AA79B74FFEB232F3D67EBD0B3F97037ED8EA8A7C6CCAA4D300F3E01F2B8661AAC39FAFA78197A2482ED4745C56C757A692B1900D7DF921D6C35580F9882CFA294DFA0DBFC29BA21C9F648515EB2A81D2BB0F75941C1C1C6541D949A5454D96FB486C79B11BD9B56F45651B3567C75A261CB5C0B077352486C37715CA8D4CB727B167567BC58A530543047C1FA2459F87C837623C5B2939FC53AABCD5B1B8271A67C95B3E33C2D9922836A25BD1E61692BB36FF87229779AB75A883B26CB6B27553FB5782DC3C62D70C4AEFE86A3A36934770834142398187983D766BDE4916EB76852D74010E221460C4C5FEC132AA77B618AA0F81EC6A8E83BE7BE37239F1CEDD206EB8961F0D2AA3FFCB272A0785A36537240274C9993C4904A731995A3019CF6133C714185A449376565A65B5C2B1DEC8896C1BC46A1575CDF80958F2B96329791C208F51B4A8F41A8356000E0F1C51EC584ACE4434BF0035B5127478C11D659B842CAC49AE873F8192659A5735F87B7517B118748A74B8020D2823A25952CA3F43C7D3614741E054DC0B5E5AC11C8FE15E7F908A7B64B3016A39218134FB3092E7482E7399310709BE369CA383E95AD08718CFBA21F9DBCC8E0600DAD2C39B368A24E79DB0DB02395949CAE835AEE683C4A6AA6024B3109C18DC2BBAD65BBDAA52ABA6D9487EE3194579494B2441177019C0BCB78F8A2FCF7BA875548C1C3603AE3A874D2454C11074047310D136AB4EAA348F05B4662989CC6896DAAA24A94154CDBB30FB5023A37779B1E29F71A841830274B733ACAEA69D84FBAD4F138861FBC35F0545489AC8342A4F6F8C584A8442447062D35BAF44B3C92A38CE11A173FD5A3D8D6B24BB390ACE212E41042E75D50E318C6FB037AFCCB2B069E2BA66AC1233D53031279ABA1683AE42A745D0002805374165EAB94A17EF6881F0BA9392CEAC27250E82622E6F40D3810AE40CFF1F84963DA07CBAFFA3C26C86115A24F33F1FAF547933AD64AFA40EF5F0DB03D53B340E384509DB0E97D4689A3CED953CFBFFA9D3B3B87CCB0C6A360FC0DF3CBCA399F9" + }, + { + "tcId": 57, + "deferred": false, + "z": "63DAD9B127F98E72A3C65ACF4B172FDBD9B9C39F24F728D1F40EB02C9949419D", + "d": "F742E7B69E27A57A43E1034CEB5834CAD57C380ABE259F432F96FAAF27F981A9", + "ek": "0C25AFFB80C5BC12C3CA5357097716E75B025C298F040C5AB8C92F93A08A91953277A7CAAA1776440C9E3A5C819D7B9BD58AC0A53C83D9635D3A882C36CC3E48959D01E67A4E363273F05504274BC144C5D4B4774FC98638895EF894A78113362EC428E0314FD5119C40811D22313D42362176E001616901952C1100C59E33428EDF13C68086571E8A65D042556A6A3B18582F79B443EE22B53631C02FC03FA6CA4BF4BB0B8B97410443C0A3CC958AD42BEDB3118254C19752AA70076FF8F312E50433884A72F287266BB83A417134CED7C66EEC3A9C90043044B61C795CA69B8EFEEC56D808610EF5B6FF764A59D308E60B64B577CA70487D340BA3C8027C45766D270969B284B54DB8A29831939174A2FF274F7EC131858355C23624CBE7B6967288C0B660ABAB4C11C2106F98909AA7AAF50BB1CA0221E1CC00B31696DD05C3E46C7CF5A22B28E404B171A8BAB14146B740B946148591C0505CBDA8E2456809D019E6183D4B10E5F9C6122A7E17D579C5AC4FFC62CDC9AA88102CC386E50770E36A257BCCAB1826BC07D0CC58AF9C49291DB9A63753CE3F9C2AE190834AA77662BB5072F89FA29A2388E532361537BC28310A6A4133B5A0A4795304117839832C8AB7A397141B8A3C47A52689BCC26E3851BE6524CF2FACCD8037B69279021539BD084B31FFF084ED7AC403EB8BD3EB5F409B8778783697B5512C0B91B426714C426882F10DD165C91EFC240C2B129500595D08A5AF198FD8C6A1A9D497654A80EAD40E8B3347B7C51F2E220C1B950788139DD07B6F00B1789EB0A7AEA60844339F04DA7811824F9544320064725B809862447397786381615D3EF4AF575A4CB8FCCE137A4C85241A72BBC424343A3C916C6E51BA58768855C29EB17AB4C8C8C3F3A0174F5979AC02795B60716FE96BFCE517821C254F2A8DD8D77FE778B82E3A53C8592048104FC959B23FE36450913BB1265BF91978FBDACFB3601DDB978CDD77314C8102DAA75D1EB8266137CBC2956714294659809E029067D7D6CB6C93148FB102C34450118835C85509E3F980446767FEA734AAF7C8ADB7CB11435E7600842FF96ED8C75FEBD643BC1A34D1666D8B6B9EDB2B8C72AC5614C603AC200D00461EBBA069EC751CB3C36A60616C73CBB8B2C17798358CC4C588BA3122FAD04D97D51687FA3B19D465F6E9AF95C68AE5225FE04A14BDD61B54A502F820C9DB0256B11AA524F463C11A21F1610DBD800A3D690E0139000B026B7C1628FCA3365A358FF8AA01429CAB2106055144CF0597C2DAA1A623DB1A85730AA0046127287BC407073E9C7C74042DDAAB008CEA58B8DC7765C85844B3395561A4772B5D4D551ADF12687B18C63260518576440EC7BD699843F5651F5E04B25085448CD138257C2E2612733ADBA6FE7357F1C366FBB1457C2458C4F848A24A1BAD74B9A2AB1A603408C540C091C6A100850B4A327211A7CE336426E7B250D50012D7262EDA4218C3B1A55D50337C63A9790406A846CEC038B15D157DDD030FDB293B187A63BB38208F075599803E29149B1F097B1867BF65EC69ADB00ACEB21345E1ADE7E5A36E20B69062C5CCA550C95331F069CFEC59429531B4380A079669C777764DCA8ACD8087AC091CC2B6075CB9436A3B4C22AFACBC0CFB95D361C2232390515A21C37AAAA839005AB97D6962BFDC8959A51ABDD427A15BE830319CCEADF3BB23B59B63452F6EE2956D11C47E721FFAD1724CFA7C1ACAC3455C6E0A75834A23AAB786079947ACA32113A2223B2446790738B464A94683D47357E8847063539080987BC742BD149756541F94D5539E886C13FC1FB291BD1FD8445DC47347072D063A71F9224A85366D3364A1B97ACA267C717BECBDCBA78FAE3BB589BC8794FA2D20A8CD8D7B58124843B7E46FF0F629EF92105DC43DF6645ED57BBDA265874B63A193D351BBD0A5A48CB819979C2A57A486A109957487B51AB7D8283076585E6F06AF66A7B7776BB219911391B67380215FA2216FC061C441B87AF6AA077E77777AB3C7101911B3DC5C1D59952879C1DE1B8741A24C4CD28239132E89024C357C76BCA7CD4696423EB6C578C53C32098E8CCC41321C93CDF79A0DF21B6F69C3DE80C9EBD838B7FB0759165DFD7A6200B88588E992CC173E0A6B0B87554CD2C3C4D42B6B575C9180F1A418D8E400CFF37C23D4C3E3EC2627627F6BCDD1E1F45D7E", + "dk": "BE49618EF5BCFD880DC312BFFDC519EFB4269D0B2391B89C01D6A6B05063346A4BBAFACFC8C091B64CC1AAA08D6F40BCB4043BAD7416858BB4121567BC380C042C2D90244943028DFACABBC6219060721832241591BC030410064E45149CF96C36A6A1FAEC889382340A5BBFC9193DBAF8A43CBA44BE25143AE10A33C6AF8541AC2503835E0743BD74CB899373BE77987492A071E57027C688A2123F56A5B3D268C1EB70A21F6A98BD239F9EE5927F21254FA5BF11F41578AA84770C78B9642E2F3C94EAB1CA5D10651F90A1E49033074B78B6F2C9D0D784C7A931E2EB8336F8802EAC29DE8737EF897FD0A31A04F76B30B5C6B68B7C3A2C3CF0C5B4B313A83F70A59A84901C8B819F8502F624368C493231C19340D67EDDE503ED9805A05A3E23102E6256117D9BA283619F0CB3373E743B2771A7D1B020949600098A40BBBBC364F6AE171BC6FBFBBFACF25B0BD37102D336EE1438022AAA2DEC0ABDA6689A4595A18161C7A9728A0C9B4F74A65D8A432A100B1F46263BF525024876B334CD8D9A1BAC2599F1F0AAADF04E7C83C7EFA4663CE59873533A0CB84AB8EA28BC9B808CE71832D45E4ACA223D7CAD92699B2DF37E080B6F3B6861C95A210362C5FB849EFAB8A845C25C375078247C397143C839F45569786E3EAB14A05679098B25785ACBA2D49C4FC47796271949795925A80EC53A8F7DF6A2A6488EB4E991CD7976584A2FE301CDAB93A57070148F8AAA81141BD932951EEA748D6066FE3B9D60143CAA0339CB8AC2530A0AD0EB444ACBBDA16B0E6A0A6E54885FAB6170A7723F4E3B23D18615B6AC580B2401E485C3543519BE6A5590C7469FF47A3DB91338A5AF6FD28A91720402F70DB8A491946192AB573A6E668CDC7B702231986C114EE18902C78A3D92D1CE616511A66999CF5C0071E615E8A7857D561B0B56C3C35560DDA90A18601B8650AE2520784D1257B3A7339C09B5CE95138E57B69FE90C1F97C03280C0806BC366E75E0D3CA2D355A2E2BA661EF0B96F556C50656724567745C1B650634A8DFA4699222010C59257C38C7D202328767663127DF2F294B00390F674C021B1934F65514AB125132B23A0A427919946D1A96A84491C353405F505937FFB8FC0813700E37C8151386E248C0BDABF1961B2859BCCD9B33960E424A87042D45A6AF180B2CF77B25B7912001C958EF55306927E8DE71488C0BB2C7C8B71767403B6185B41C22DE1BCA99AA86297A2A1E17015F553B967720B159160843DE88B3D033B4D5D563326547A404B352466C9A82415B08A54456B37037971B77A937A540A2DE05B91EA5E540996C8D15452467D0F81568DB2482019B783309F77867175A4CED0A0660FF2AFC1F09B09A03A7BDC1621A613AA4C2571B23FD7C1CECD5B75559C37CDB598AC108255479667E117F51B0E30866F20B087D9088765E7613F3584CCDA8EA7A13CF8E5583EA353661AB7A42A264F9AC6EC529C2CB7230CF45D2AC1B95D729F00B8792983AFECD44B3E88A197D34E2447490729BDAE7547B7119A970B0C3153B379148C4BB61472662669E2510C76549102187D891E56C20A3328C03AFB32760BBF09F604AB0B5C5DCABC83E80CB17A7BFE4B147F6670128A80E93B359191424C80C47CE001D926C6830962083B8BF1C03FF9F1A1034139D974229A581035E73F7CC10D56B281FE96755F214738B70AD6351F8F30CE5DC5555F6B69B806C5D2574553E7C94362A623F2C4B31502FF8094F6E08394C880EDA1299B2C03F1C696D80C3640584C13789E32192A27B38896884F6DF0BDE386A1A327C5C52314A4BACA2D7928AC761AD898CB4298905AA76ABE3C5B7BE75704317D44A9C98FE59C812C88A6E334C0163EDE8AB622F351D9F3926375291B5510C6E3AF2641A65FBA17C7778B9B2A6C2E5BBA6BA225EA40CF4ABA7639D488ADC0A970F6581213352A409065CA92AA8694916C57796B42C96C830FA84C6C70C2640C495F10A48D1A210BDB8BD0C20EF2074825651C5D9B3EC606351B34796FC578307CCCE54A2EBD648FF051CA6FC9AB0636CB6ACC49109343F1465052B57404D46EFDF856CF330E539402DF699E0576953C497A9D662E768ACDB8A9822E3A9271C401A364B1D060924B84939F7110B45012EA36121A4A91CD860258D559ADC0530C25AFFB80C5BC12C3CA5357097716E75B025C298F040C5AB8C92F93A08A91953277A7CAAA1776440C9E3A5C819D7B9BD58AC0A53C83D9635D3A882C36CC3E48959D01E67A4E363273F05504274BC144C5D4B4774FC98638895EF894A78113362EC428E0314FD5119C40811D22313D42362176E001616901952C1100C59E33428EDF13C68086571E8A65D042556A6A3B18582F79B443EE22B53631C02FC03FA6CA4BF4BB0B8B97410443C0A3CC958AD42BEDB3118254C19752AA70076FF8F312E50433884A72F287266BB83A417134CED7C66EEC3A9C90043044B61C795CA69B8EFEEC56D808610EF5B6FF764A59D308E60B64B577CA70487D340BA3C8027C45766D270969B284B54DB8A29831939174A2FF274F7EC131858355C23624CBE7B6967288C0B660ABAB4C11C2106F98909AA7AAF50BB1CA0221E1CC00B31696DD05C3E46C7CF5A22B28E404B171A8BAB14146B740B946148591C0505CBDA8E2456809D019E6183D4B10E5F9C6122A7E17D579C5AC4FFC62CDC9AA88102CC386E50770E36A257BCCAB1826BC07D0CC58AF9C49291DB9A63753CE3F9C2AE190834AA77662BB5072F89FA29A2388E532361537BC28310A6A4133B5A0A4795304117839832C8AB7A397141B8A3C47A52689BCC26E3851BE6524CF2FACCD8037B69279021539BD084B31FFF084ED7AC403EB8BD3EB5F409B8778783697B5512C0B91B426714C426882F10DD165C91EFC240C2B129500595D08A5AF198FD8C6A1A9D497654A80EAD40E8B3347B7C51F2E220C1B950788139DD07B6F00B1789EB0A7AEA60844339F04DA7811824F9544320064725B809862447397786381615D3EF4AF575A4CB8FCCE137A4C85241A72BBC424343A3C916C6E51BA58768855C29EB17AB4C8C8C3F3A0174F5979AC02795B60716FE96BFCE517821C254F2A8DD8D77FE778B82E3A53C8592048104FC959B23FE36450913BB1265BF91978FBDACFB3601DDB978CDD77314C8102DAA75D1EB8266137CBC2956714294659809E029067D7D6CB6C93148FB102C34450118835C85509E3F980446767FEA734AAF7C8ADB7CB11435E7600842FF96ED8C75FEBD643BC1A34D1666D8B6B9EDB2B8C72AC5614C603AC200D00461EBBA069EC751CB3C36A60616C73CBB8B2C17798358CC4C588BA3122FAD04D97D51687FA3B19D465F6E9AF95C68AE5225FE04A14BDD61B54A502F820C9DB0256B11AA524F463C11A21F1610DBD800A3D690E0139000B026B7C1628FCA3365A358FF8AA01429CAB2106055144CF0597C2DAA1A623DB1A85730AA0046127287BC407073E9C7C74042DDAAB008CEA58B8DC7765C85844B3395561A4772B5D4D551ADF12687B18C63260518576440EC7BD699843F5651F5E04B25085448CD138257C2E2612733ADBA6FE7357F1C366FBB1457C2458C4F848A24A1BAD74B9A2AB1A603408C540C091C6A100850B4A327211A7CE336426E7B250D50012D7262EDA4218C3B1A55D50337C63A9790406A846CEC038B15D157DDD030FDB293B187A63BB38208F075599803E29149B1F097B1867BF65EC69ADB00ACEB21345E1ADE7E5A36E20B69062C5CCA550C95331F069CFEC59429531B4380A079669C777764DCA8ACD8087AC091CC2B6075CB9436A3B4C22AFACBC0CFB95D361C2232390515A21C37AAAA839005AB97D6962BFDC8959A51ABDD427A15BE830319CCEADF3BB23B59B63452F6EE2956D11C47E721FFAD1724CFA7C1ACAC3455C6E0A75834A23AAB786079947ACA32113A2223B2446790738B464A94683D47357E8847063539080987BC742BD149756541F94D5539E886C13FC1FB291BD1FD8445DC47347072D063A71F9224A85366D3364A1B97ACA267C717BECBDCBA78FAE3BB589BC8794FA2D20A8CD8D7B58124843B7E46FF0F629EF92105DC43DF6645ED57BBDA265874B63A193D351BBD0A5A48CB819979C2A57A486A109957487B51AB7D8283076585E6F06AF66A7B7776BB219911391B67380215FA2216FC061C441B87AF6AA077E77777AB3C7101911B3DC5C1D59952879C1DE1B8741A24C4CD28239132E89024C357C76BCA7CD4696423EB6C578C53C32098E8CCC41321C93CDF79A0DF21B6F69C3DE80C9EBD838B7FB0759165DFD7A6200B88588E992CC173E0A6B0B87554CD2C3C4D42B6B575C9180F1A418D8E400CFF37C23D4C3E3EC2627627F6BCDD1E1F45D7EB647A2888D86D41D8661A91766BA969E80B9741B21D1EC6E349B52DE8191901B63DAD9B127F98E72A3C65ACF4B172FDBD9B9C39F24F728D1F40EB02C9949419D" + }, + { + "tcId": 58, + "deferred": false, + "z": "0A755A829F05597B2F2A90974F22FB1AEAB42892101222967E3A0AD612CEEBCA", + "d": "3BFC9A057D979EC03A705A9CC406DD8A46C106941AF6777B1D7F79C1508D7B24", + "ek": "5BDC0216639954EB53EF77250D2853878BC0183C0EB5359414CAC928E3ADE2E78213904D7DA453E96969A89259822C205FA46CA6703B6D324890E59F0C377C778ABB5ED2466AC929E8AA2E9D47A8CCE606F52B18A7C35C20F4C2AFC99AC327802B856F13BC1D9E3646BF2A2038C454095C147BD1474663274DD50041C9939EECCE460B7FF1605743D4243553A0752465E93C628324BB2D3783EB1B63AE85AA53311C5574071E56991211426DAC6F6AAC3EEA1569B04654D4193DD689A32432447E1A3F0F5595FB37A35FECAE5C55CA839A3CED94AE6FA436A7D34C2A81587CA84018933FDF39A931B03D81491624651A5F6AC75E08077FAAAE8AB023D6344557D15FFCB91C10B06BDA114C5C133F3782C309C347F2A4434DAA89F202817A227C1E1240FF41A4F3CCACFA497CDDC53AC5B0C55614907865118C2C7AC0D5031CBC106CB17A26B97755271C86E871BCC9590E1C2684F2C24A172B10844CA44346FB969CEBA1A02B9922F3AB68457CBB1F2BC6B5F5CC4EACB9D0072EAC617B31D27301E002E978925966B642B00AC53C912EA85DB59C5506F4724B2C356CEB40BD58AE51843537C537EC97B24475318A5B30AE750691765FEE1014644B1CACC77C9C334805A58DE18121FEAC6BDB61184D2C273AB725C32091CA3441E5140433435AEB0B51B9C57066C43F308A12F782BCA5237D7B12119CDC9AE2E7C65EBC66B3F02A0BE7361E08838114BF0D5250304A36935135C61597A03903EF215C6A223DF8A9515E622932F7A29CFA74807B145A20ADAA7987B0B981B7A62D115927504A090F61B37592A5B4E51B977821E4D92228531D2BA1523BAB3D6C850FB0660646892BE2A006DF51743FA383AC47572F651AB02A272A458B81441C8E774547E1773EE29A6A27BA4E839C8E023A13635922009B1111801872C391641F0E239ACA70CE3FC01E5C3736FEE2AB3F85C4AFE3A0BB2529D6EC047337819084222F0ABE8F859925708AE3E62815083196248720EC28174C01D716AD472A0CB2747EDB932F4A58ACE9E2BADFE468BA2A138EAB864EE00C034C1207F92F73AB084E32BC244951477549B2189568BA28553937E5F1CE6ED1B7F0C1012560296442AA6DA0879705A65D77460A86C0C06422A2E6949BB78B955355EEA2749BA0948ED094E5D9CE7C79B9F4047BF4E2128E41CA5AB1BAB1A87A2565CDC018890D426B37F01713DC923CD372605763C3B51A5AD58109F031BD665192F38EED496EAB15AF89DB622DB73A88BB6104D44C49577483F468658A9C72C1A2046252DF7840325978589A85F07C7572E44445F9A8854825E784706A25A70ED0CEC3F5A372C41C54185294975A70AB759B4250E1F2CB35E860ECC25932F55E6991041AC24D56BCCBDA579E421C905469052A34225AD50B69E191B4A36EB7DB1DC1216BB41524497B279230053E910EAB49859D1A99DB3C56CD70995BF031FB71B0AA40CDF031183E5B3D8D8799CFC3ACDDA54010AA6169A80D62479583111FEB337354F6BDF36A33279B7472800EB604710AB94A0D584942E41B78F2C387993A5EA079F3C74207F7972646CFD4E055FB6B10BC69B369D166143B8A8E7400134999F05C6A26DBBEC3B23D92CB90F77156A0C8A96CE93F73962C17F8104B52AFA2B68B62810F998577E07CB16FAC499F38AD628B57FC1C9CC7A568410478176BBC14C8C7A594A07A3568B503BFE26BAD88D2CAE92B90F1E1472E9697F930B6E775A1A9B93EF62757B2A28F6962CF2C1478626A9B65B5AB89CC24EE4C9F765B8071737C25F383DD57598D2289DEE439D28AAE91A3B21E389267FB3D146276B7810D126AA5D096A16F679E28D5C91A580777D9CEA13C46234653634ABD964C720A11A6514A7FB7F5ACB0992BFC7C16FA84CD9686ACDFF2283A89625BC65FEADC9171ECA359BA50BEE412D31414EE110AD1D8748237941683BF292618F740445C0B728D51347928559E569EBFE896DC6295F87517AB31A8639B50C0F3A08E96926816B7B17C8ACB476C4C67B1DF7631DF7540276C99053B102738BFA2876E42A028869C688C18AAA9B00DF0F3A74CD81D86D161912C09362AB35BD8731A48CB45CB92EE8A3374B811EEF93A37F17DD7D8AFF88958E13012E6F7BD6DC63E27BC47F506048CE24BB7411538EB4B969656DCE8DF5ACF28D1BDF5ECD14A44A98350CA45699F033EFA44D25E93FC2094C49E", + "dk": "18A2405BD102699A2B22168A31D2C0E7F946160428EE787E8C6C57ECBCA0FD170DF93BC66203A8F06A3292310EE08495D1BC0DAF2A2D92C243DAC2B558291276217430A08D11B9C5DA411F2D55406BD4182913086489B43D74C602780701295A4C0054765338695231E6798020E7CBF1697573474AB35B27817BB38BC2313E70AFB914B5ABCBB28B7124302B338B471FC89336D1C35FB6D59C007402D1D19A1F96682F7551D8527EAA07389E55A8080791178407301ACF22EB32E0F7119DFA0E623035364CB0243B19918792011023A086016CE39BDAF0868FB08A4E1753B00B444A807787EB973CE52F63650B12A6B51EF435048A9F7136A5A77A99238763F433C00813C5CDF8CAB21B445630AE2D733F7683701242751F5C17A4F15FAFA5AC7E5A231097AD06299DD6AC194D1ABE895A0315E834BB364C286C8CD0216BB032B59D797245F40D624872036BA369355AF73C6FA5540BEC829112F28294191096A8AF53D37C5DA8B151330098582AA06C5455408765D43FE5B24C9C0471C9C85243C205747A43ECE8CEB31CA87BB51B39D15433F99D6FA638BF02373D42A09079399B4CB0A371984061370078A677E166D3D7B82E3174B58885D280A1D44911EB0482C58C7216D5A22694C767B9CB35BB0A1B0271471C558546037BE5585D43C40F6705D8C0C4579025898A2E21A0C5B0A4A42AB290E1F37D58486631210EFA0669819A90742926CEC68B1801B44D597E2CC84661917C9BBB6E2FD4B00D11AC616A245088B6AE323332FA40CFC46845842B02328D6E9A9246632DB8FC960B9340DE367A25D3996F48943ACA2656250D823BC999250C357C718A7CAC1197868D68C70F324391A75EB88C09AE835FD732B9047AC4DE843A6D00BA1EF79AEBC350B1D3541B874C3105B901441BE9F9663C306E085B0B0F98A4132586111417346B85AB5C26FB0522AFCCCA2168308803243BD1C1611574533466A1F709027485D680BE09624B03944EA5399E62A3A8A005B74227041E6C394CA22DBE3A6666541377573AC5357106400B35473B6672A7D4517F1C91A6A1266D25809B57720207E4CAFD88751CCA82AB54593CA126A0C60771CBC49535CC9A83882DA67D6F94BCCF7A5B605215B874C4786B24995A83C679BC12E870C61A3820DA5B89C0863B369A6C79B13ED67099EA02CCA1B9523529992A215C525BD5D37A39E69891FABAB70594AF8119F356A85587604AF35CC3A01692047576D97456BC1BA23639D4452A91C40A732509C70C83CFB080CE2BA6F29A80B0066D10A96A038C72CA7B6860594EE3C7C592016E147C7FE478B90F8A4CBEC166A3C474758642EB76CA3B0A806B16CDA19013986B10A3844A0CF86455F2808429B371A0592129414FD31BA24C995E303C776B014BD35CC644095B7140F2AB3336D55DE6D54F9FF244B6CC8580111C7DB2492A32A073E0196FA256A92CAF6B431B6F6053E52C308D6C0F8D86001258B78290AAAA85C9B2059A931833A6C82825B332943ABABF65451272AFF4BBC0FC279B603CC1E97C18F40641DF91776EDCB7DE245DF98099A9DCBE5B1C6C67FCAE6FB18A4F950833197364D94D224B8D29AB8860199CCF8CA3C8D1217D99484A631DC29923AA582FBB2566A44BAA1FC037C139CA3AF90D9D0516E7B0732F552BF264325A121F20D393C8E794D1E32A3C12BF68C849A6548BB308753524CE72130F037BA1C02A50162CC10437A5337C6056E850E2319474AA21AC223F8330C43E3A0BE3B0A42227266E6639252271CB2023A55866B004B8B43CCF7E212457157893247201B1AA4728BA476AC7D3B303A6F3BDB818641151BAB769C7BF2A1EBF027A79F81214687D0886C99FD5A46C8B4A1F5697A98BC9667CA574A1CA283BB4F424237B37C96A5836709C7FC0717537CA95213322E3396A55439E1F8C7756A0625FC23CD2745E63A054C47259025C92AAD22E2DC52045A8467AC069E6E22B65D25C2DCA2BDD31AF5057B0DBE93E3D921341046E89E5618A62C562349F2A646E65EBB64091ADECE8CFE68460FF95842EA6648C89BFB0E5AB1CE11103904AA04C4F55F7C64DD810917B756B02BC1054A8DB7116D0718E584ACB47C679E39232E1C87934D84111B0087C04C86ADC5C7F060D5B639FD9B1BC85775461100FA6BACCAD22495BDC0216639954EB53EF77250D2853878BC0183C0EB5359414CAC928E3ADE2E78213904D7DA453E96969A89259822C205FA46CA6703B6D324890E59F0C377C778ABB5ED2466AC929E8AA2E9D47A8CCE606F52B18A7C35C20F4C2AFC99AC327802B856F13BC1D9E3646BF2A2038C454095C147BD1474663274DD50041C9939EECCE460B7FF1605743D4243553A0752465E93C628324BB2D3783EB1B63AE85AA53311C5574071E56991211426DAC6F6AAC3EEA1569B04654D4193DD689A32432447E1A3F0F5595FB37A35FECAE5C55CA839A3CED94AE6FA436A7D34C2A81587CA84018933FDF39A931B03D81491624651A5F6AC75E08077FAAAE8AB023D6344557D15FFCB91C10B06BDA114C5C133F3782C309C347F2A4434DAA89F202817A227C1E1240FF41A4F3CCACFA497CDDC53AC5B0C55614907865118C2C7AC0D5031CBC106CB17A26B97755271C86E871BCC9590E1C2684F2C24A172B10844CA44346FB969CEBA1A02B9922F3AB68457CBB1F2BC6B5F5CC4EACB9D0072EAC617B31D27301E002E978925966B642B00AC53C912EA85DB59C5506F4724B2C356CEB40BD58AE51843537C537EC97B24475318A5B30AE750691765FEE1014644B1CACC77C9C334805A58DE18121FEAC6BDB61184D2C273AB725C32091CA3441E5140433435AEB0B51B9C57066C43F308A12F782BCA5237D7B12119CDC9AE2E7C65EBC66B3F02A0BE7361E08838114BF0D5250304A36935135C61597A03903EF215C6A223DF8A9515E622932F7A29CFA74807B145A20ADAA7987B0B981B7A62D115927504A090F61B37592A5B4E51B977821E4D92228531D2BA1523BAB3D6C850FB0660646892BE2A006DF51743FA383AC47572F651AB02A272A458B81441C8E774547E1773EE29A6A27BA4E839C8E023A13635922009B1111801872C391641F0E239ACA70CE3FC01E5C3736FEE2AB3F85C4AFE3A0BB2529D6EC047337819084222F0ABE8F859925708AE3E62815083196248720EC28174C01D716AD472A0CB2747EDB932F4A58ACE9E2BADFE468BA2A138EAB864EE00C034C1207F92F73AB084E32BC244951477549B2189568BA28553937E5F1CE6ED1B7F0C1012560296442AA6DA0879705A65D77460A86C0C06422A2E6949BB78B955355EEA2749BA0948ED094E5D9CE7C79B9F4047BF4E2128E41CA5AB1BAB1A87A2565CDC018890D426B37F01713DC923CD372605763C3B51A5AD58109F031BD665192F38EED496EAB15AF89DB622DB73A88BB6104D44C49577483F468658A9C72C1A2046252DF7840325978589A85F07C7572E44445F9A8854825E784706A25A70ED0CEC3F5A372C41C54185294975A70AB759B4250E1F2CB35E860ECC25932F55E6991041AC24D56BCCBDA579E421C905469052A34225AD50B69E191B4A36EB7DB1DC1216BB41524497B279230053E910EAB49859D1A99DB3C56CD70995BF031FB71B0AA40CDF031183E5B3D8D8799CFC3ACDDA54010AA6169A80D62479583111FEB337354F6BDF36A33279B7472800EB604710AB94A0D584942E41B78F2C387993A5EA079F3C74207F7972646CFD4E055FB6B10BC69B369D166143B8A8E7400134999F05C6A26DBBEC3B23D92CB90F77156A0C8A96CE93F73962C17F8104B52AFA2B68B62810F998577E07CB16FAC499F38AD628B57FC1C9CC7A568410478176BBC14C8C7A594A07A3568B503BFE26BAD88D2CAE92B90F1E1472E9697F930B6E775A1A9B93EF62757B2A28F6962CF2C1478626A9B65B5AB89CC24EE4C9F765B8071737C25F383DD57598D2289DEE439D28AAE91A3B21E389267FB3D146276B7810D126AA5D096A16F679E28D5C91A580777D9CEA13C46234653634ABD964C720A11A6514A7FB7F5ACB0992BFC7C16FA84CD9686ACDFF2283A89625BC65FEADC9171ECA359BA50BEE412D31414EE110AD1D8748237941683BF292618F740445C0B728D51347928559E569EBFE896DC6295F87517AB31A8639B50C0F3A08E96926816B7B17C8ACB476C4C67B1DF7631DF7540276C99053B102738BFA2876E42A028869C688C18AAA9B00DF0F3A74CD81D86D161912C09362AB35BD8731A48CB45CB92EE8A3374B811EEF93A37F17DD7D8AFF88958E13012E6F7BD6DC63E27BC47F506048CE24BB7411538EB4B969656DCE8DF5ACF28D1BDF5ECD14A44A98350CA45699F033EFA44D25E93FC2094C49E47269D7A3C68DB2C273EA465A5A30D6CE94BFF775EF4CB5F323C7EF064701B690A755A829F05597B2F2A90974F22FB1AEAB42892101222967E3A0AD612CEEBCA" + }, + { + "tcId": 59, + "deferred": false, + "z": "681F088AD6962FC397A1B9071852848CE9A7EDAE65A81485CEC87D0974707B7E", + "d": "7C43F2E7D9B1D8D9C41D9F315E052A254CE3A1F098671773B53717A95220AD55", + "ek": "9ADB4E6D612D58585179C9965CF816553BCEAED61651C13CAE0672540BA9763333A25273B59864FB94AB650C6C41A6969EBBAAC0156A9A3621A1104EF578CF1185001316AF57F75C9CF401C4D2C9C8AA15BA8855C730577F128FA32122FB3B29E3813BA9C6CEA1B38BA069662C954794050C1F18C126542644D04EABB9656C446F8C08C6C6214AF2772264872E894086144B30712811A60C27E24C7C51A99A001D296B3CCB5CB1B9CBF4370208C23294442A9C229D1944B59C03CDD663E06CC73AC493D1D75CC1525993059EB4F61C6EE160AD229F3D015BCC919A90449FE8054890006E6BC98D19B602F142515371B8BAF9B456D04B3A429051006997A961422483B2D61857330F74D5117559213CD766E183210DF1100DA49DBD992A9FCAA1AC5834310AA9E9F44B4B2293BDDA76E22C585DB53CB904BD3292C84FDBC38D793136B12C2AF7A58D88C45B0212F0A083DB0929B1B070C74194EA0620A396BB43E6BA9AE43BAB85C589E93986C746EF4643DBDC1F0EF302CAB02512286F846702D4A3AB69FCA5D2B54C7B603CF5D4AE90705F0EA36A6479329B6461DF47026CA86765A79577F2AE1D8A2013E977FF49296247A3717401F7B961090165E34023E8E373CFC8CA5BE146A5690138532A01F9B18C138D9C7B110A66BC47161B708661FB5B5C507A9F3ED396A163A281B2809EDA52C78511C26CC8F478980DC429042A2CBE73600A8A06972260E8F2C387434FB0087435E711E14896B8841BC751A79FF9B3776217E53287270B26023ACD1DC95395F52546E94E287538D2E9539D8587DBE606748A7CDB76449EC2B0ABAC7170C439A4F2BD3F1A3F349B90DDCC13878024087AC33C38B64EE04427EA249D3C7845629CD8D0C82189814E6B2260CBC100B64039599B1BF91938C2B2C35CA2EBA70B8474522FA6C37A917D7B589F646266D2D07B348169F84968C466C9B90A7B00A6505F6A567D5A14BDD2477CFC0B515C7931B3BC1A7021DE7B2CC7C650097B0D2A94A7B024B207B6969E22C720683084CB998E0C422D1B2FD9969DA2BA9096358AE11A5E101C6DE23C8DC041AAA2F441F8693A01A872E6356D9907420EEC3F55B945E34562C0F3838695643DA00336C1CF1802199E093C07347F80F0959CFCA72CE65E2C675BF9CA8B01F97600AD177133CA15932C79C9781AD01B36F606DC74A648054AFE1B74352A4EEA2095A0120D7C5332D1B7A61DB284A3A0519AF63D891A2546D9748FE768604C27827B6E45E1AA1335AC8F2295A83A6AC9E42D0047AF55242EAB2534C7B38AB65749CD21B0441781E643BC16D03D0C437E03E33BCD4B92A9D32BAD6513FBF595DF30BE0475B69A632928A0B4E2A867E4229525953CF303C47CB83F609A1D20EA1D3146C80BF82061E9C5AD670E4288C01E889E95F937611B419C38563228BB9FA85D3E184109A004DEFA472848AC510CB81E18C5301B149B0264942CBB88F8995737C425E44F50F53B9B2A4C44FB0E5C7145775900D7708D51F21173A9170AB2902CB911BFB82D2D4B0333B1832F043A79A6A07530CA00E5CC58E6B0C2706CAE6A6A52D69C6C0B23C90812116AA971398D154404EC531F3712348D0AC62DFA9A1CC0B01C470E16693327AB9BBA8083F22B8314551712475E187400EB801F1BA34F78024A5DEC89B4C7811E68B30EBC91E08373BB92AC0FE8A861F4BF0A0B5877088371209D3294B866A86BB6B470344A069503AF99730773853236AA12CB3C2F679B45D0025876199C68E676298AB1773C92E33276A60C02FF7415EB10838A5035B7114E9834C5BCCA795330009EE57368B139F9D71135D1C86B0833D2CB81D660C56FCB3EDB848721C72A59A8CF45B6543CA7895E686C26A86A5AA7A8C1734C5F576D648482026391CD611389C44807EC771DEC4FE373B483B00D68F34AF776244EC07874A5C22C6C566CCC5C70369FB92A22B6BBC4F4144BDCE6C3A5051268DC8D6E8A2B8F8A8D48020804880FFA32BD01899CA9D3A70FD62A91B74ECEC51BB58594E7F162C7E94D44D64D66592880C55011A8550833A599375CF9207605784C11FABA854BBE6971065479B6D26589D2C756DB93C83E50936CC0C0089CCE8EE0A08149B732559586D07C4FAB56D7A263CAC656314268F55C64A1D6982E665DC42766D84206BAF103D14014221F2914A06162064F7E475811518022B301C262A125BB439D32", + "dk": "92D719984988C65BC4E3E60514E25F64C70318D049A14B110C2196176BB7F9183946C24894F075DE191261544ABE9BABD3280DB7A41B47A937C9597EE995CADC33C1AF87CA2D740F09249CCF376B7D5CBD1B69179323673BD6CD8CD9A84C47B7D232A912F4752BD94B93914427F2CD20C6391CF71F729472095C5D1C3C57E03689D57AB4ABE677909A9895638B790903E5E50D2421117F6A23E7A5CD6A3053FBAA42F386BBD3D82D8B788FF7E652D5830EE676BA978C60342694150A5B28D8A5AAA66C8172AD93D9B3B334C0BB4672DEC182E4395157A0997895BC44C48F3B222C5EABCBF7F2C2973C61B09B3889F0891E35934D4116663A60F751C48E22186B72969EC3BAC346B505CC6699C86BE8B1836152CD6BA37962A23E29B256C555845EF24F52C43DF0C20326841C77E3B87D16C59BEAC267056F40F7117E44C5C957465C09787A52594D1565825243FDE9C568115029F3C378B99F8E28AF395A2119590837B06B75E293682441CD7C5773F5BEFE7CCA172B8DD6EC0E792999D3B40A0439336F2629A1DB78227BB870F44896E112D8094524962F68370AD7092F60375C7A986340D32CC52633B1A714529425DF69BC918A30BBD577E938B6C1D06519078F3D934B7CF77FEB7A179BD8463829AA37D6C449877823231D0EE81B51FB12751946AA1C594ED175607B36D1B7B94CEB8D23B6AA680B9A72857BA61A445AE80C1CF45EF70B44AF6B3C428C8A25689AB8228218C6C0CC858E6A98823E3673913B9163A339327609FD459AFB05CADFCC2943E45A965B54F1A065F68B1F153CC8912329C0F0C0DC605FE6E52905C8B3F1EA3BD0E99418C645A8E6622DD577E9F2BCFB649C1DA09FB8E20DF470CC6317613D788FB544921C325B7B3B7A0A1C3ECAB62B866A513609590E871B17D7866F8A96B838C33A562DD1D47787D795BCE61AD3A9CFBEA5B03290320612A76BC198B0B84D8953909183A14FB318840469E2A909FCFA2C8A9B59E12C77B14A6503829AE8D3B493FB9A6BA6BABDFA7BE215B23ABB5B62C2C6042A909FA9999CFC2A23790548B6055D57B3FCE2C155A6C6115B05855249BEC0887F00369F38379111846946CB25F39305054BAF669E75830A505AC3148299E5AC2B4BF59C68986408270A8CA3A87A70A380EA7AD5871E7DD3165A733AA1D55F1184441DD84183B1002BCA518F370D02D5806498482B4236C8E1B1BF07870C2C7E1D44435077905A5C461238970B603F234B9351FA4213E0CB8DEC764475534AFA18AF07518C573DB0D9790C873A33293424A434B9A933AC644B37B14435D0AFE71B443F83BCEEEC9574016214DA8E66ECCA10668684EB5D776C5B4B2C05C2E03598A602717A72EC4B18E5F550992ABB76A1994B4842FADA39FDAB9DADAB09D6BB9B46AB4EEE69AEBC419F1587B8D7061BE188623F4471852C9294146261A67345F5A2347B206D2870DDA681C44CCFB420708AA398864469B8E08E76081C41F5977893813653A744766125F27C28E6C1DE51978448BB8770B8660B6E4767458DB70990E24FAA35B4DC7571B5EB69BE48C8646586F0ACB48A3B3252A02EF48A7DBD44A5E19177069C6F3F678794B8488C313F70EB4AD6FC09BF078467D362A436411AA689885B987104BC50E00340F8294A06AB8C02B0569B1A6426C13CB9B651677585BA213F7C297A949096B27A02E9510C803EBA002EA423AB3C810595D71F6201366591B60091B305EC7E80371E6DD171DB235D389B480F9C32CC7AA52DEA7714D3004DF5172E034DED271B9C679846A6AC4BE4580E4414EE42CAFED11387CBC98938BA6A59A07E2238B2B54FF6F18D3F48C2FB0636B5CAA3A581948067B1FDB083E92A46EED9B090032655A9BBA2B207EED10D419991AB813140CC898D11B24566970A601326072E15A31D73C0A625FC3E6B697575D293D1B3142F12190B28AD4DB6278CD9A92E50AEB3B60E687A14D2C48623955724582373F16DDE3919A8C7B98CBC514977C5E96895FDB17A952279B8222548EA4B08D4659517A7809C0E786986C2D69A1F7963CE2672726C7CA4A91509856476C13B9488A2A429804815126954C2CAA43F1EA7877BB10346C022A1407CDEEA6322D74C760283CA8699B6433AD16A0DC2238B9714887ACB0315D67139573EAB39A403C3459ADB4E6D612D58585179C9965CF816553BCEAED61651C13CAE0672540BA9763333A25273B59864FB94AB650C6C41A6969EBBAAC0156A9A3621A1104EF578CF1185001316AF57F75C9CF401C4D2C9C8AA15BA8855C730577F128FA32122FB3B29E3813BA9C6CEA1B38BA069662C954794050C1F18C126542644D04EABB9656C446F8C08C6C6214AF2772264872E894086144B30712811A60C27E24C7C51A99A001D296B3CCB5CB1B9CBF4370208C23294442A9C229D1944B59C03CDD663E06CC73AC493D1D75CC1525993059EB4F61C6EE160AD229F3D015BCC919A90449FE8054890006E6BC98D19B602F142515371B8BAF9B456D04B3A429051006997A961422483B2D61857330F74D5117559213CD766E183210DF1100DA49DBD992A9FCAA1AC5834310AA9E9F44B4B2293BDDA76E22C585DB53CB904BD3292C84FDBC38D793136B12C2AF7A58D88C45B0212F0A083DB0929B1B070C74194EA0620A396BB43E6BA9AE43BAB85C589E93986C746EF4643DBDC1F0EF302CAB02512286F846702D4A3AB69FCA5D2B54C7B603CF5D4AE90705F0EA36A6479329B6461DF47026CA86765A79577F2AE1D8A2013E977FF49296247A3717401F7B961090165E34023E8E373CFC8CA5BE146A5690138532A01F9B18C138D9C7B110A66BC47161B708661FB5B5C507A9F3ED396A163A281B2809EDA52C78511C26CC8F478980DC429042A2CBE73600A8A06972260E8F2C387434FB0087435E711E14896B8841BC751A79FF9B3776217E53287270B26023ACD1DC95395F52546E94E287538D2E9539D8587DBE606748A7CDB76449EC2B0ABAC7170C439A4F2BD3F1A3F349B90DDCC13878024087AC33C38B64EE04427EA249D3C7845629CD8D0C82189814E6B2260CBC100B64039599B1BF91938C2B2C35CA2EBA70B8474522FA6C37A917D7B589F646266D2D07B348169F84968C466C9B90A7B00A6505F6A567D5A14BDD2477CFC0B515C7931B3BC1A7021DE7B2CC7C650097B0D2A94A7B024B207B6969E22C720683084CB998E0C422D1B2FD9969DA2BA9096358AE11A5E101C6DE23C8DC041AAA2F441F8693A01A872E6356D9907420EEC3F55B945E34562C0F3838695643DA00336C1CF1802199E093C07347F80F0959CFCA72CE65E2C675BF9CA8B01F97600AD177133CA15932C79C9781AD01B36F606DC74A648054AFE1B74352A4EEA2095A0120D7C5332D1B7A61DB284A3A0519AF63D891A2546D9748FE768604C27827B6E45E1AA1335AC8F2295A83A6AC9E42D0047AF55242EAB2534C7B38AB65749CD21B0441781E643BC16D03D0C437E03E33BCD4B92A9D32BAD6513FBF595DF30BE0475B69A632928A0B4E2A867E4229525953CF303C47CB83F609A1D20EA1D3146C80BF82061E9C5AD670E4288C01E889E95F937611B419C38563228BB9FA85D3E184109A004DEFA472848AC510CB81E18C5301B149B0264942CBB88F8995737C425E44F50F53B9B2A4C44FB0E5C7145775900D7708D51F21173A9170AB2902CB911BFB82D2D4B0333B1832F043A79A6A07530CA00E5CC58E6B0C2706CAE6A6A52D69C6C0B23C90812116AA971398D154404EC531F3712348D0AC62DFA9A1CC0B01C470E16693327AB9BBA8083F22B8314551712475E187400EB801F1BA34F78024A5DEC89B4C7811E68B30EBC91E08373BB92AC0FE8A861F4BF0A0B5877088371209D3294B866A86BB6B470344A069503AF99730773853236AA12CB3C2F679B45D0025876199C68E676298AB1773C92E33276A60C02FF7415EB10838A5035B7114E9834C5BCCA795330009EE57368B139F9D71135D1C86B0833D2CB81D660C56FCB3EDB848721C72A59A8CF45B6543CA7895E686C26A86A5AA7A8C1734C5F576D648482026391CD611389C44807EC771DEC4FE373B483B00D68F34AF776244EC07874A5C22C6C566CCC5C70369FB92A22B6BBC4F4144BDCE6C3A5051268DC8D6E8A2B8F8A8D48020804880FFA32BD01899CA9D3A70FD62A91B74ECEC51BB58594E7F162C7E94D44D64D66592880C55011A8550833A599375CF9207605784C11FABA854BBE6971065479B6D26589D2C756DB93C83E50936CC0C0089CCE8EE0A08149B732559586D07C4FAB56D7A263CAC656314268F55C64A1D6982E665DC42766D84206BAF103D14014221F2914A06162064F7E475811518022B301C262A125BB439D3225F6DF8F68FACBDCE4839DCEEDC2B96D6191CA1DB11F347EA0D66F8C2458A848681F088AD6962FC397A1B9071852848CE9A7EDAE65A81485CEC87D0974707B7E" + }, + { + "tcId": 60, + "deferred": false, + "z": "40BBB2C581B2D694E369C0DA567371E8E53C328A59BCE775A625C9F5CC185E0F", + "d": "C2E1A3161F3734F44F3C2F1736E149803F71321122242A1E95E55E5652A91F55", + "ek": "F93584C1B0237F83AE90B664950B471E763CB7939C28D93604C83F73A30F80B3AA8F948086A142A132442712CBD71A9D495587CAC62F98F922E96C9D0095B1502B42DA76B59B1C183338C1C06A730DFC2E889273326593362006EF948AEE1A521E159FF6283DF3D11DEDB1655FC706DEB2C6BE879D3605C3AA463355FC726CE84962500B72776EBC9AA3D960A8084C3182EB8A43918F80EBCE5425257C2237CAC811022792485772BFA51CC7171F86F4C847782BFF123763FA650CB1B173D1AC78F7C19E764F5039736A3B2BF37B67C9783DA9EA6CD0A96FD7DA758E411575F6744DACB42AE2148B7BC9FBF49B4D25CCE02BB906B025EAB98171B80D55C8A328D15C2668A8FDC3A463CA6508E1818437498AA27B04D8514795BC4675C1B94ACEFD54603C498056038D3445745D44BD6F1A4316191B905C650668A3E2402D74E560CBB7A667A27EA4D38495010A71085957421923E21718E611CD5205FFF6AB91C65407C67E7EE19EF0A885EB88B02901478DAB0456D94E4073576AF0542E33C9286048E491ACD2EC2A02E5181436BE7D829AFCA68FE0A78588D886DF77B6F1F94A959B2AFDE328B8B5888569AC34D23771F0AA12C7954EC82A6E71C1760654C34A926DE4B0F07025B9517B2A036577728C7E35653CEC816C3677F703B0EB3C18AEC948368009CB013E365A1E643244289B0AE11440877266C27C955C7773D4377BA2D7C6B8DA7D23C48A19EAA7374A5A9B931F42E144A6CBB8CA06BBD42396B02C6AD16BA6B1E36B2161903EA4A654A31C507825347B9BB177C655B848BD943162F41818F113E864B456D504573B8C4E5B8A07F14713612F78537128253B1B9712C417CCAFB271DCD9683EB82C55D171723A32A5D40EDF9252D01C7ADB6664D6467421920C5B345B2D93C3DFCBCB1DC538D23454068AAA2B85CE41574079136476CB1CA401C1134977E97C72D2C85C37E872CB725A2AB55BB6C37EF2E517608A95C14A970480856A8A5737A06B46E93D03D6384AB8562AF2C37DBB1D52737CA8C5404632C4E9AA714A4A5CD3D073AF069CCDA490C64C42974B57D3BA6C500588C39BCFC4B26CE6119ECDB6A2A47141DA96BA2331996EA93C5D7618F4FC9A27FB6F5BA336F6801938EC26ADE456FDE01D41C22E1424611FB4487D8A2DA212A09749524F004CDC76B8F6339B11041A3174B8FD58B2C6E7B0166AB4246347D25AC489C43288A23A7E59C3CE320E3FCACE6B6277400ACF9E924FD12C0805B70354F3AD8DE92644F8B4936C81CF301FB87A7DC4578628868ABF501626B045D48537F2212A3FA5396C1C857B1084B21B1EB968AD60B43181C77712001290300C9CC2A3D6562A00FCB4E5F11C2AE412DD29181A034725A0CC75E2BDFB851DBFC28AB3362B8CF378BAC9939D340317C64469C27D8F3675C2A962DC7A00E9F67BA1EB8094F0B205388C59223C7BB963D8E21D933B779B360706AC5E06033C1907A8C8EB6E6017C285A8827E28B8CC7A5891CA381FD50D5EA231FEB5A7A4E4380FB5067A6505FA627D19715667FC5602B041CDF9074A3C58BDB9C77CF23F6AD1005C4A6F2581695F444578A734F8FC3E9FCCC07A873A5AD04CB2C724F6820AB1C081306B429F92834FE8BFE401448431BEBC4C7335EA0EC7050A0A49459DB286B774069B161DCBF3BABB5430FF727A419B1AF2371E1441BDD53C03E5445391A401668B693C6503F35CA6CC7A04CA298FFB81CFEAB4B8DF400E1F670801E7014DFCC8B3D8BD953BACC1D61F184A07B383A8325C1251A56E8BFCA75C04CF8653082D52A8D6C944191155AE886AD9AC010AC50BBD2BBA9144785F02B7B7BBBF7F1AB8DF210241F4AEA1700D840AAD5E2761C4066165A43C487B3AFF68BF3370891933BF46C13BE82331F189B678150748AC609B3378C3581AFF91C9A4F2B9C040661E11A917F7A604100E5B9863B8D3B55BE32CC1F40DC47C4F02622863A560F25B03864502F4304F1401B90E4969EC110331A418770B1CA626B3A86659AE9B7B630C6DE1576286976453377663950353BC8067691BD1E1C24C006204E3502C171BD43C33271548EDDAA641677D8D1161152216A4944D480440E3B418042184194C6E39FBCCD353C58A6C3BAD16A33D666D601237F341B7AEF3C98F237E585C8E152B444DF15A768B20104AFC8CE55CDA630D36C048C7D5206708B4699726C1E2FC3A722CB514", + "dk": "AAE64B6CDBAC89352E7D1311EA15C4C43635D40B98F471A9BB1C1A0B086868D2651546A3F6C1A1F6FB8E75010B8661BE3EF1251737126DBB8157B6A1AD3611B04B95DFE46510BB94E7B0B87B55315A98AB61946FE926984FB5A4BDA10333221B92EAC1CFC2A15BE83ADF9297FF61CF87991EEF977A584A3D4CC765D710CF3C630687990A85F4CD1973861868A8FA1A1D3C26A777371CF6108D1B83243B058F729448ECA2A5665B2B6B032BD83CAD34EB5CA394C6DE96AB3552BEF3B28DB6390978DB65A30C6B0528ADA091C80D42AE470078C1D3C45EA21AB418A865FCC2FA4C3D78B76E84B3C3AFC0BD9B2721A092AA274B7A4BC3B8A9DC57332C81B0695522316755A5B7F1F992F5E22C00B29CDC6281ECAA0E74A24C0C56573AB8453F469872722C8796BFD1B64D8AC93F123C74740511A0B983C20C153F005BCBD04965EC95975858045681DB4B8B70327CCDFC9FF8377D599384C15875EE346FC08066EF3BC09D46016B8754B8C0B6BD944D2B157CFE3392A25B98D48850536B5BFE119F58A0739A48654CC8BBA8EC1C1AF4A197EC758396CE4C0C4E66D0BD43A03CD65A6028C185C6C1C59FCBC4EE7017568061BE551BC0BB3509102E8F14829B603BA1CB910DEC374CEA99C301851111A3DACB2292CB95ED1C8B53B965C6D33307B40C538C63872B83DF8C3922385AA8CA075FC118DBB323035C768149221E2C135291070671270CA5342B89044DB59346314F95B95BCB06D0A1F66645B907862C60B4C8CEC097CA87C7B3F2720DDCB0C5D317B443437CEDD32F2357015F9350778A360219B7FC178531B2442F114F2024595EC4CAB1F6CA26F827542096F8B08C4492156424504CF46DFCAB2DB7074FBA212F72284194C59240EACDE348BFC22394985A09874B5BDCF788DFB9B38031B1AB762BC337195597A662673514603E49C2A485E61D37691B31C46EF67CA30C79A6037726735861BF5A31FE102B448CAF32B7103D3549AAE16BB8186670FCBEFEC61D47E923E4460B8CDB029AF81C99F80456033C1B1351F7FC5932902E791C8D65466A36523BA6D58FD370905F3B21465B88C125B23BEBA9F3DA624685833B4A189CE2480D4739AAD85E3EF41E0683B0376C561AA6685F2289891114CA4C380F43289C201CC6FB6E77213E1FB813F1A12266E9812BE91EED08ABDAD5477801201F313CE6A11B9C155F8E07310D6C7769E637EB123524342DFBC67FC0E20A3D09AB9B5C06B149C39FA12E21870273C8C97FD56A1CD346F627593A01606043A18F35C6A323A22A48B3DB49923D3A2BBC92051BD4A9301CAA0D9A386569A37261CC12172839499F928A6A70806B9D8A24AE304D98876AFE6C3E24D500BA08A8F285C9633414825AA01AFC5E55CB2AB91A53DCB47DC7904F6EA77196A8BB9E057A092208BD81C2B9675E1C263D0BA024D2D92B5E85C164E149572B0288531B6BF4BB1E629D7295842A5709D06810CCC896E64A5516130959881B58633F8C411F5032AADE7879CA3385715C8E590B6AAED47D38A708822AA7570848439867D6CAC7EF7A76DD3B890662CE65271EA065302D3A4B4FAA2143F5530E890A1B80B75935BC3C06569C7365A4166AB4D7C1B26030C2A777A121C0099921C77AAE3644BBDA315429C06CADB33BAA3CA419D5064A5BC9C7BC6C8D34C7FB0A254409372B679FCAB46D47C16B94BB2E8253475C0CC5BA6C7DA39141ECE51EDB844A4EA4AC6E3866625679FFF71CFEE1477A918CD82B0883B67BAF2A383B436FDEE7C58AD372E698778866377561BAFA8C9B596AB48676B08E2BA9EE1AAE07BB194D841586662DC64B1065CC8A52D899D09C6F96286E272895F8865B54DA8B33FB67AEA1133E611BF9ABB459AA4442A60CD09A4E39006616C3981604662F7006E0C9130739A66E79BFD123C679A368B64C331C285AC1CC721512A52148A382C09474773BADCA77CDDCB6E4C40022CA10E35A6BB205239074AD6B6524C2329103D281E8CC479AB4AA2E5C2960A903C1E05B48F07B5C88C384533D93A9BF07EB8B7376163532AFAF32B4C481694C11C97ECA8AF0E714F0427D16CBC331E9821E60C735392AE047303DD637AE5AAD915232EBF481BD03ABC845372C60AC586009BC717B6D1A1E78FBB7ADAC5DFA89C410E786AB4422A87BA21A088EF93584C1B0237F83AE90B664950B471E763CB7939C28D93604C83F73A30F80B3AA8F948086A142A132442712CBD71A9D495587CAC62F98F922E96C9D0095B1502B42DA76B59B1C183338C1C06A730DFC2E889273326593362006EF948AEE1A521E159FF6283DF3D11DEDB1655FC706DEB2C6BE879D3605C3AA463355FC726CE84962500B72776EBC9AA3D960A8084C3182EB8A43918F80EBCE5425257C2237CAC811022792485772BFA51CC7171F86F4C847782BFF123763FA650CB1B173D1AC78F7C19E764F5039736A3B2BF37B67C9783DA9EA6CD0A96FD7DA758E411575F6744DACB42AE2148B7BC9FBF49B4D25CCE02BB906B025EAB98171B80D55C8A328D15C2668A8FDC3A463CA6508E1818437498AA27B04D8514795BC4675C1B94ACEFD54603C498056038D3445745D44BD6F1A4316191B905C650668A3E2402D74E560CBB7A667A27EA4D38495010A71085957421923E21718E611CD5205FFF6AB91C65407C67E7EE19EF0A885EB88B02901478DAB0456D94E4073576AF0542E33C9286048E491ACD2EC2A02E5181436BE7D829AFCA68FE0A78588D886DF77B6F1F94A959B2AFDE328B8B5888569AC34D23771F0AA12C7954EC82A6E71C1760654C34A926DE4B0F07025B9517B2A036577728C7E35653CEC816C3677F703B0EB3C18AEC948368009CB013E365A1E643244289B0AE11440877266C27C955C7773D4377BA2D7C6B8DA7D23C48A19EAA7374A5A9B931F42E144A6CBB8CA06BBD42396B02C6AD16BA6B1E36B2161903EA4A654A31C507825347B9BB177C655B848BD943162F41818F113E864B456D504573B8C4E5B8A07F14713612F78537128253B1B9712C417CCAFB271DCD9683EB82C55D171723A32A5D40EDF9252D01C7ADB6664D6467421920C5B345B2D93C3DFCBCB1DC538D23454068AAA2B85CE41574079136476CB1CA401C1134977E97C72D2C85C37E872CB725A2AB55BB6C37EF2E517608A95C14A970480856A8A5737A06B46E93D03D6384AB8562AF2C37DBB1D52737CA8C5404632C4E9AA714A4A5CD3D073AF069CCDA490C64C42974B57D3BA6C500588C39BCFC4B26CE6119ECDB6A2A47141DA96BA2331996EA93C5D7618F4FC9A27FB6F5BA336F6801938EC26ADE456FDE01D41C22E1424611FB4487D8A2DA212A09749524F004CDC76B8F6339B11041A3174B8FD58B2C6E7B0166AB4246347D25AC489C43288A23A7E59C3CE320E3FCACE6B6277400ACF9E924FD12C0805B70354F3AD8DE92644F8B4936C81CF301FB87A7DC4578628868ABF501626B045D48537F2212A3FA5396C1C857B1084B21B1EB968AD60B43181C77712001290300C9CC2A3D6562A00FCB4E5F11C2AE412DD29181A034725A0CC75E2BDFB851DBFC28AB3362B8CF378BAC9939D340317C64469C27D8F3675C2A962DC7A00E9F67BA1EB8094F0B205388C59223C7BB963D8E21D933B779B360706AC5E06033C1907A8C8EB6E6017C285A8827E28B8CC7A5891CA381FD50D5EA231FEB5A7A4E4380FB5067A6505FA627D19715667FC5602B041CDF9074A3C58BDB9C77CF23F6AD1005C4A6F2581695F444578A734F8FC3E9FCCC07A873A5AD04CB2C724F6820AB1C081306B429F92834FE8BFE401448431BEBC4C7335EA0EC7050A0A49459DB286B774069B161DCBF3BABB5430FF727A419B1AF2371E1441BDD53C03E5445391A401668B693C6503F35CA6CC7A04CA298FFB81CFEAB4B8DF400E1F670801E7014DFCC8B3D8BD953BACC1D61F184A07B383A8325C1251A56E8BFCA75C04CF8653082D52A8D6C944191155AE886AD9AC010AC50BBD2BBA9144785F02B7B7BBBF7F1AB8DF210241F4AEA1700D840AAD5E2761C4066165A43C487B3AFF68BF3370891933BF46C13BE82331F189B678150748AC609B3378C3581AFF91C9A4F2B9C040661E11A917F7A604100E5B9863B8D3B55BE32CC1F40DC47C4F02622863A560F25B03864502F4304F1401B90E4969EC110331A418770B1CA626B3A86659AE9B7B630C6DE1576286976453377663950353BC8067691BD1E1C24C006204E3502C171BD43C33271548EDDAA641677D8D1161152216A4944D480440E3B418042184194C6E39FBCCD353C58A6C3BAD16A33D666D601237F341B7AEF3C98F237E585C8E152B444DF15A768B20104AFC8CE55CDA630D36C048C7D5206708B4699726C1E2FC3A722CB514936B2729D96EFF6FBF9B05E34251304A92EA873A21654F70C4632113C36F62CF40BBB2C581B2D694E369C0DA567371E8E53C328A59BCE775A625C9F5CC185E0F" + }, + { + "tcId": 61, + "deferred": false, + "z": "E15F322315265F9B847960B7185D962761ED79C62286A0DFDB13DBF550CE0107", + "d": "ACB7FDB596B44A88A60ED74A3FAD9EF745BF5BFA4902CADB891EC5CA45F685F5", + "ek": "E42705D23A30A72638425280BCE72CD596BA2AA6B736A922740C52A0F470C0A1311ED82E15F4C5D865B6BE18B4810127282C1BE22A9BC580784EF371F18482F2E43777396A3E6A77FA284CBC6C663D63005DA53232B06A27D65547FA58E263C00AC701B3B6566F199F5EC172AD4BC12FEBA212C7159C90C589551110066D87E01D54924ADFE0CBEC921AC7B273B1FC400F6B81F23073D6AC0D7AC34F2DC60C08777C5559B013F23B91A743443B1B38375E91C254D8721F1AD2B02E9C566FAA294ED75BE16C0B0D82C1DCC8AB4A6C1D6E88B567C11A49AA055EEA87117A4C5B1C030F8ACD3AFC69D5FA8F082210E356A426C973A17492E8C3C64D87087A54589BF468071C0DAE016B6B51C52B628BEB986845B484FA213A27C6A1D505AE09D499FB92C17DF2AF010C71C1FA0FCD89A59EBCBDA4B7AFAB2CA68421AED1C464892C5ACFAA556DCC227929B6670904A01C5AB2AA0A5A246566C61A7BB9CA07630DD005CF8705B1B414CE8070A43D30CCB45572DEEB253E19ABCDE790A7F4BADD7863CB187FE8AAB9B0CC1C8309415F54AF4BA6BD6DC74C3AA13B0126254DA08F833C71810092E7332DD8CA4CC3199D4EB25405D310A3E9A6E65C8BFED0C6973A6F324CCC3EE16CC3E405D1C036086C5BE644A1A3709DB22A392EAC889CFCB6D9A03CCED44AB241AE735490EBE44A8B333C462891AFF72F2482C9B52B98106BB010A4CF03214330C5AEADB9B7314273D88880358A568DAA16DD8B496B6CA9C758B74F207B5001826391175EAA2DD9912E84B77EA257052065364949CE57365CC457854681729B389A7CC4782F7590EA6ABC49C40B4E23A2EF916F53240CA7BCA58370657490C52AC535E7CBA1CC58CAF52585DC148811264C2E6AA6728A254BBCC983D71716E82B7A53A2ABE376A5362E74F57BEB1979E2FA77998C869D6A799D0934D8475C8CB28AEBB3522387251D11352520C9A76697519B2DB6093CCC3A5A99D75E136C9A3D305F46F3176EC07FE4C30E25B21BDC2996DB413E0350AEE4A96125C5337AA70469F392942037674561D85969AC6664F6D92DD9B5108CDAC8A6E86E8BC1C1DF319AF330701E23AC743232680B3370B471CCD91761C110E309B5D77A48F4E06A681A2B38ACC3185946E7DB0D6EB1837D3199D83C676D667AD1CB51DC9982D3D36BCC121627D21AADF01928F32DF347CE495175F84641CC0704A24B7D099C416D3A56CC5CCD3ACA34F3F670B64C57AFD0591A628E4A19A83914C14212BB4D43AB1548CC772C25F38619692A5DD88730B093AFF5968B9AE60DC8AB8BE3D13F16928E4CD0CF604835F23B101BE7903876C8BB9970BC74A0E4752A67C4BE2F20C10BFB7765D863828565D190C5384273DED40E331168A4AC2A6CB8B0C5D600F5359BE70AB0B74C3C427857B34A9D2B7731DA6ABA7206253A67C22AAA10F7ACBFDB093BB7647B50D6AD449257AAA9CF29E5C5AA2982D6E0B67813BEF12B4E2A9669FB94394E34BD9583142456CA048763E0EABA7DDC48E3CB80736C6121F1888DB3CF85177942F322C3F029B427A6B8DB4976E1B80E9047BF91BDF2449F0B20C336E041B587182DD4A459C4800CA85308658E3BA78D66F47639AB1B70C45B43F70CF8197803BC1EC4A4424DD78C26039F4AC3C84F98A5AFB45A6970158E41296B925D33F68ECCD3B5A0B415F5B7CDE3473859DC48279255F9995561C205B244728DFC4F625316776267BD468BFBB287097911F8C2A32A0CBF14C3C708F9C4BF70C612C61FBA3720EC62918149165BBCA3CCD48CC8B272E538A1E818843B272DC694AD8E265E830034ACE5708CF22AE3D256745B50EC328CBF03760CA73E7E35241776864856BFD7C18577D411AAF99AD412CAACF44456228DE0176FA0E13CB925140F8A5BE9589F4B6B199F751B7A58751DB35680C78C69F83333155D80E08FA92A5B0FDAB909F9223D167333765D033213E3A65EB2B709BA200D861012D7145A9039C4A6B032D9D5802846441C379978EBA4B9970B275271292379B96717E48680FAE36DDC7018AFA8B3C1929AD62268F12AB87FEB92535A655158CE4957A1BE37C9922B4E08D57D85525D6F2B7698331FB3F1219D91A1272B7E92D3245E4649A8257BC362BA0E0462991A481A0A602809C46F4342ED40AD99FC74366406ACFCE7708AE11AA2C3436EE06121FE6CD52FACE80AA5FA2B65A0B1B28F8B28DE", + "dk": "8F841DB58339CB208908CA123BFA4FB00413A60A9EA76648FD69BEECE0B731042AB206368858B0AE798A7A26A1C96AA302AB998F352634CBAF93F81EA4C280830B8DE435CD4DFC3C3674CE2338AAF6543A57BAAE1232780B578BC3FB4230919CA56065A6E466FC19B9322404499199ACCCADB0236D6026BC927C58EA225D34A628721C746D2008C7B2A600CB94E5F93351088A1C6609CC350E5E0920D4D3139AC08A28A0A5DCFAACF057C3DCD933DB7A8159A657CE257481AA1AEA69BDCCBA961B82C56AC15A74DA139BF388610879EA716035372042984AE027C910E149FACC954762B75FE41214A7B808B168FA728F4D52500C88B2E96A121AC9249C3761A97C7333332CFFA182018A15D4B550A930BFE60AB73F20573345522162A5DF021C19F290567A95ACF4622A919AC20BB42B11BE06852094947897B4A7987981F989A29A13C31288B8C30B36244894CE502DA3967DC0636C94810A2A0B9EF72B215E936E330556F0309604B99093B246AB102553117CA48458E845CB87399A42499A0F7913A15358F334577D84004CF23522695EBC6630503B7ED77076EA7C0ABFA4218943413AD664F761C429011F8F0A66E5C22794F60E9FE2B995C004FE21AEF73AB339468735731A969A3E0E192998933F2864C6BC9A82B1A5A542CCCFB85CC629EAC5BF2CBF1F1438ED5109BE13B7F182280EFC07D937783FC5407215742329281AB7B8BA687DF328A3380CA3E4C09523B056EED254A4B7AE6C241EEE61A340528308D3C11F96A315D0B4B02BA47AC14388F2C005A0B15C75CC3D72717B2B13AE8A830AE7706064630A1C0B97858B75B228E7E6C12F1344F656A2D0405E3E932BDE3846F91AB60E183F2469C2A0B47E59E20B89303DFCF89EC1368243B03A4864C26D58B691026B2E627E9C36BAC877C048708B058B02B5327B3325423EEA5C52E311A6E208880A688D540127DBA7FF46CBBC35784BF538B5B04CE774BF5FF82BAFC844445719CE532D928339A19744E9F6391852B5B1E2C06F61CC2C28A16D3BB08081825F040CF0AA489751CE8C99CC0930379A426D3E9A15278B7D40021E5F890B06A767E65088311A8818B5088946CE9871A55D602B8FF389FD9B2E80060E053B82275436FC9690D1453B256CC510735CCE3331D109C1247B6875DBA71079A353293B624C6494762BE23B135DB14599F41CF3BA8EE07CA032E652E00B57A6214106C587B96097B45390A4431ED2B524C641112A95C65F93CCE87816E85B7955A91741650C4E8A944FA088CBF274E31244F77A4C50A98D44B96FB8625FFACCA584AB18740C8278A8ACA2E12989E60CE7A70145B394B7137EA86901D629C63ECB42BC59673DD73515DA3BE2C74D595B6E15AB4324786574D842A2518F2247ACCAE3012AE36CCBC48038BB5C69B3BF95D59016492E2E923CA562C8F8F444CDD3756A69336EE972786B88F2DB42DBB2309228279D6AA29474C2C94721556131DFD95E0520B0C23C2C1B49683D425EB313954154935CC06109182BE7C8A5D45A46B97196B6B794F4944EBE2052B3454EDC814938868FA1FC7ED4D76342591BA5EB96C73166AD311F7C80CFE7C149A2301DF1B8BB96C7742F03B5B3541A8E05418A7A3A89E1841B627D85CA7B6D56897DF5C5977A1E67C2B5D97894245620DCDA7B3183771081B4FD77476440013E417FBCFC4C38A51C1045219FEABD3C1258203A716FDC922F95CB71C15BAFCA2C777812C1AC390D540803B917D153B75D7A947AF328B620B93348CE7342212A286FB63812C2930920933473C95BB383B7AC054E4DF8CAF7D2A2C7C8CB3FDC5CA949177B40AF5DE102D9DB382D3C6D918155FAC94EE088A067C43BA21778D4E78FA0157C8457586E1AB6A07922FCE01407D63E7366BF68116EECEC8F01C262F766008C9A33C2A5A7C4575E95DB458E9C8289A30EA4E32E015856FCFC03C0EABD2021473B251C279ABC66D87EA1F66AEF5A8189544DE7A95C6F8544D8481786C72BF0EA329EEC4D2423846770707D922DDA38601B228E12451657725923B25CE29A10398B5D16492061D77E48EA023A929A4EC3634FA0073CB929CD1A42577B1E6F89CB9522A28B6A9248D243D423884E03799E6413F963462B7B3BF0276BAFE5AFE2F161EA76566FF4406649BA3C1B5811188FE42705D23A30A72638425280BCE72CD596BA2AA6B736A922740C52A0F470C0A1311ED82E15F4C5D865B6BE18B4810127282C1BE22A9BC580784EF371F18482F2E43777396A3E6A77FA284CBC6C663D63005DA53232B06A27D65547FA58E263C00AC701B3B6566F199F5EC172AD4BC12FEBA212C7159C90C589551110066D87E01D54924ADFE0CBEC921AC7B273B1FC400F6B81F23073D6AC0D7AC34F2DC60C08777C5559B013F23B91A743443B1B38375E91C254D8721F1AD2B02E9C566FAA294ED75BE16C0B0D82C1DCC8AB4A6C1D6E88B567C11A49AA055EEA87117A4C5B1C030F8ACD3AFC69D5FA8F082210E356A426C973A17492E8C3C64D87087A54589BF468071C0DAE016B6B51C52B628BEB986845B484FA213A27C6A1D505AE09D499FB92C17DF2AF010C71C1FA0FCD89A59EBCBDA4B7AFAB2CA68421AED1C464892C5ACFAA556DCC227929B6670904A01C5AB2AA0A5A246566C61A7BB9CA07630DD005CF8705B1B414CE8070A43D30CCB45572DEEB253E19ABCDE790A7F4BADD7863CB187FE8AAB9B0CC1C8309415F54AF4BA6BD6DC74C3AA13B0126254DA08F833C71810092E7332DD8CA4CC3199D4EB25405D310A3E9A6E65C8BFED0C6973A6F324CCC3EE16CC3E405D1C036086C5BE644A1A3709DB22A392EAC889CFCB6D9A03CCED44AB241AE735490EBE44A8B333C462891AFF72F2482C9B52B98106BB010A4CF03214330C5AEADB9B7314273D88880358A568DAA16DD8B496B6CA9C758B74F207B5001826391175EAA2DD9912E84B77EA257052065364949CE57365CC457854681729B389A7CC4782F7590EA6ABC49C40B4E23A2EF916F53240CA7BCA58370657490C52AC535E7CBA1CC58CAF52585DC148811264C2E6AA6728A254BBCC983D71716E82B7A53A2ABE376A5362E74F57BEB1979E2FA77998C869D6A799D0934D8475C8CB28AEBB3522387251D11352520C9A76697519B2DB6093CCC3A5A99D75E136C9A3D305F46F3176EC07FE4C30E25B21BDC2996DB413E0350AEE4A96125C5337AA70469F392942037674561D85969AC6664F6D92DD9B5108CDAC8A6E86E8BC1C1DF319AF330701E23AC743232680B3370B471CCD91761C110E309B5D77A48F4E06A681A2B38ACC3185946E7DB0D6EB1837D3199D83C676D667AD1CB51DC9982D3D36BCC121627D21AADF01928F32DF347CE495175F84641CC0704A24B7D099C416D3A56CC5CCD3ACA34F3F670B64C57AFD0591A628E4A19A83914C14212BB4D43AB1548CC772C25F38619692A5DD88730B093AFF5968B9AE60DC8AB8BE3D13F16928E4CD0CF604835F23B101BE7903876C8BB9970BC74A0E4752A67C4BE2F20C10BFB7765D863828565D190C5384273DED40E331168A4AC2A6CB8B0C5D600F5359BE70AB0B74C3C427857B34A9D2B7731DA6ABA7206253A67C22AAA10F7ACBFDB093BB7647B50D6AD449257AAA9CF29E5C5AA2982D6E0B67813BEF12B4E2A9669FB94394E34BD9583142456CA048763E0EABA7DDC48E3CB80736C6121F1888DB3CF85177942F322C3F029B427A6B8DB4976E1B80E9047BF91BDF2449F0B20C336E041B587182DD4A459C4800CA85308658E3BA78D66F47639AB1B70C45B43F70CF8197803BC1EC4A4424DD78C26039F4AC3C84F98A5AFB45A6970158E41296B925D33F68ECCD3B5A0B415F5B7CDE3473859DC48279255F9995561C205B244728DFC4F625316776267BD468BFBB287097911F8C2A32A0CBF14C3C708F9C4BF70C612C61FBA3720EC62918149165BBCA3CCD48CC8B272E538A1E818843B272DC694AD8E265E830034ACE5708CF22AE3D256745B50EC328CBF03760CA73E7E35241776864856BFD7C18577D411AAF99AD412CAACF44456228DE0176FA0E13CB925140F8A5BE9589F4B6B199F751B7A58751DB35680C78C69F83333155D80E08FA92A5B0FDAB909F9223D167333765D033213E3A65EB2B709BA200D861012D7145A9039C4A6B032D9D5802846441C379978EBA4B9970B275271292379B96717E48680FAE36DDC7018AFA8B3C1929AD62268F12AB87FEB92535A655158CE4957A1BE37C9922B4E08D57D85525D6F2B7698331FB3F1219D91A1272B7E92D3245E4649A8257BC362BA0E0462991A481A0A602809C46F4342ED40AD99FC74366406ACFCE7708AE11AA2C3436EE06121FE6CD52FACE80AA5FA2B65A0B1B28F8B28DE9213ED7BAA4999FD5812E87439CD569F1510F0536CB5A34D77C48FCD82BE86D8E15F322315265F9B847960B7185D962761ED79C62286A0DFDB13DBF550CE0107" + }, + { + "tcId": 62, + "deferred": false, + "z": "ABD71039AE2E2700391011D9CC8265C2D5C9779002D54E1BDD9607402054CA95", + "d": "0AA4E8D918201BB98464963B076E35337FF3265810723E01C435954DB18B14FF", + "ek": "0902C611CC1D7395142836692CAC578AA1AC7B12970599690FF9958A7048B7D276DE2088D0B06E5C3971190909C6F216287B2344E3922AF9A4BFC1CEB7E5AD35302E555A504B6B65F710356CC30DF957BD60E974FD31729EB63620E30154636FEBD84DA66BBE270151787B7A8B2BA3431491860C8837B5A93C35C62AE2BDBA43BB58D4126EE8139FFB5BFA110C4075C34F9AC648673EECCB59AF60CB8A6372B69C6E39D418AF88BC23161812486A5F2BB9B2D970B811C360329593CC31FA47BEC0FCA95C226E46A6BD5F39674458BD1683CA4673C39D158D9EE13E9736A6863229156BAE9340532D1A1BFBF98145930EE0A5229323468F7B5A9AE9755F6B603A4360CAEC054276BD3E5A4BF29C85F1DACA2C61A514C1449F94A63C4A3CCCA06D195945EDB3C0DAB07FBF75BFDE57A454C564B99C7DA3E5BA095A462C741E634B3D2DD9B7DF837E5FC076A0C363389C8248036EE55477F55BA27F17740E0AB891D0305E77A284ECA7F84CB3C5483FB3992610384E42A731DB8C3B65B6BBAFF04039D09A9BE4494637A9599CA7A4C42FCCA473D4E88B830A4D2358A324620F9B765A0141CB57DC1B70918053611B7AAA7D6D973C8D4C2CC135940C3CA9B7385823C8A86755717A63BD8EDC5712335786B21CA4106C3E6AB14381A87C6C6FB70635159077BE8369699823F54BCCEFEA3D3AD61613409B41C007947015364BCF42F184BF3BC8B03C6976749347EA7564076CAE9360F1CAA3BDF183889766FD428D13936B25EAA8156776C813705B79CF11030ABDE33B87FA4200544740598EA451AF9ED65CE3D0088F948AE07134BC2830253C9A680477C26180621BA679CB78F4E1304743A2AF124054499A21A9B510C78B2F875445B8AD58A559CF624DB8F8ABD1188812C122EAE81AB0F50435C77D72918E03DBAC7FC61DE848B4BC1729140602E738734B43CC62CB48B8131A2E257D82CB58F69AA6C4A348EA48277A0C8504D07323C61C42B68E5A212B01D66DB645BCBB6B34AF9B8AD7F709EB3720C1B79EF09352A078892787AE73D0B5DF546CC5F35D84940999D9CC59FB39C41762AD4AB260E6795F37372BEAC07005BF80F4A5620B4F23A2255D212746F4CFF73995E53C075C6790CAF4745A2AB8CAE2A89D94A601673023819166A709010C9D4A42CE9AA8C96381B1A7A236781C0C0F10C653F71353224242D3A8F0786A31703CD2063929393DAC152186C84253825481FC86BDFC70E3C5975D3A1DE8F23002126A05DB29FDD143A1F60222D7409B468138A8AAE2A34C1FFB6CEAA863CBC9666DBA1FE7138DE19AAED65256B15CBB08110E25FBC7209750C2CB225F6C5C97836AA04BA1B636BDE9235709483998E85BC1A28F713CA3935505E840A82284B879100389EC2D2A5778C990CCDE45B44D26A9AB74C28705807312681BD662F3E5437772CB7C383D72A53537404FB551CC87274294A85C8BB8484C8113E29708664190F923A387E81EBDAC3CE5890A2C440B9D93323E0588CE003606A5204B93288EB6B62F657C6E511059AC4B3DD57D402064B9C086DB955A7958C399F17AB353108E821A1C1084E11B20F2123C1CA6600AD330587988586C8F698BA258165FA3199A423548EED0B46535935C964BB4A0988B2346BD64BA7FA23D42FAAEF424901878012A772FC4815C26D54037F66F8BBC0E82C7753E16C40E1C17C2BC35F470251393B3B7E84534226DB0237DA2960CFDC99EEB4CA4AFEAA15B9271D9F74DF6CA5631935579AA5E189A715827220CE26BB1C07D719751560765E5A2296CB4BD9C44C4D6376E39A89AA8B70AF987AA0C3C10E714931059AFBC6B07B3523B1175AB9E0902BAAA56754A76C09C4CE232B5EED28F58F097BE3A0F5C290615DC7A4C4C328E413D8E43487E124F8C28444E70A7AE02B64D618D8831609CC939859BB100FC31513B90CE30B59061C38BD17DD57A6A2B0A3640E591524A06A6063259467D1F0821813411E62713A742C0ADE48FE3575338356F4CE99C1995667C34CD2582C0F9B7C4A3DA412C737253A3C3957929D5E4CFEFECAC09BB557231A11ED94F3C7A1BE5060313F540EE5576221386DA4C6A7CB71E307B395DB9C6D7DCB256C42D6F52908C565F06DB823463A634AC57299687641A556F5599F961B6E2F0A30053BE44150E1BEA7DC6D1A4488855127512CE9B2B1F4C07FFABDDF9E7FC37FB0A738DED0707", + "dk": "D4B51192A45D0D05BA48D20D7F8210DE386535D2A9204105AF184B50C81E89889DDF30942A9352C6723D2C94C31B709D452266772A8D69D2784C8332687507A1F678142C390737AD55C42CB7D37A28E9B9A18C374D220FC5A9560F655588439D69616620237225B543E6FB67ACE6B149BAA6AB5C45E334B65C87BFA368C581389B1246639B8550F9D94A61BC806850222869AB9041858DD30C16D0B62B53C85A345F26E3113F51C76F137FECACBB26C6AB1C3898E4AA73889039DD61CDEE46379812CB68BA0A03252199F102C661427088A89EB64D9E6CCE4E9929C19CB91BFA2A816340BE89A636339E67A124F659A45E6A061027533BA635854A0CAA45998E6BA21CC10E53A1A9BEB42DF0107F6765C7B9C8A8E98448CF2A6ACC6514765935064417C5E094B038123AF395B78746E4B66AB3E7BCEA783B4F4B5169478C78B82194961F80FC64AD314CD9D089C559815DD91533DC04B9359FD7936D7B8BB5BED435C77057316440926766F3A665F361BC9314230BAC46AEA6AC7EF648C9901DF017BBDE558668A606809CC717C49EFCE5B9F469BE1A0A9853451B130A952C137F6812978270A194C5CFD899CE2E656FE9CBBE8C3C769C700218489DAC47A07CDAA36EF22EE7125EC5223FD959C335B70C56AB8D52333B4C6A1C12DB76A4C02F7E7410CB646E75A5301F19A080561FDE627C9E42B275FBA0800715B1D77643A8193EFB61DDE898305B4B53140A76CC851FB956FE766C8450100A1C9EC0044C32BC17948C3D4CF44C70077447147BCA735EC9F2251A423F96D694F0F01ED4813713545A791282F7086B025BC4B133B86EB4856A3C99F21129AEC57175818360D678FD549ED769365E4720B3A4A433217DBEBA261C48B75C26828199904820C8FC80098DA6A0A9463B24FA5F43A445F33B38985637AA30CE6FC83D7127BFF9DA633E25A362323564D25622064AF20C16D90620AA0875D65217A389438D236EC8F2C18AE3BFC95296CB951A604B9FC15C69A5927F86D98582C3169BD16C7EE1403BCA5BB1C2238B93B5B0F4C6E3969D98325444A09DE2636DA4A046367358CBA66B28531616733FD816B32BB714CAD1B10DF570062223F6366424BB0388DC1A6CC9AD72CCAD22EC51C671BB859C4A3BCAC9525342B6EC97DB62ADE9949339DA5338D07EE433A868060570E087C34B8BF62ACF15F05657869556CC00713CAA9E5C2AF40474F472B3E117B9F8DC4D148183952A0553F49EEF609F3CF12DB7B102855677A443BD8C94429C9168BDC06CA0FB3781E450DAE94A96E4239DF01A74FB3C016B4AA3463AF3E18D8EC653E838249937B50DB57ADA1CC1215972B410AE459BA481836215E12655534A6F183ACE939DEE553435E9BDD00B4273F0A99CD42607E903E85864F0D27CB4A26474265E2E7A56A576971D69C657D237C05CA7C8070F0FE3A8A1AB8549866D32A253F7B4AEBE6521E557131D361999C5CD6B9837299A2100A52450C9AF85890833A9AC8A3B1B1C0B90839295BA6997BDF262AA93196AEA9F9EB1485E8415FF7006CAEC9A0548AFCF6816938A5E77D5A383F6B3C140786A3626207218883597BC3670903364BD275AE420BAE20522D5E69F9D292E7C5A6A3F3134F767004D052E1476B2A95B790B295AE6F68689828F69EC7965F495E7667E7B420EA2E5C738964FC0257E9D423B98C409E9A27B41E0B87A396EC079338019AE8DEC20DFE0477E940B6233C7D6244A201A0DA4B45AE785158C545AE6B28B49F799E030C762F0BAC8987E12F079D28C4BF7074BED316AB4580D21A8CEF4C30D637275FA2C6884E61B6843C4BC696E8615C47D573FF20BA1053C4259076153BB9314E6CA62F1AF91F594ABD444BBD2B3B203A075083AE8036109710F2B169A688CBCF6D563FAE94D3DF65BFA92B1D20546B5A3A0FF6B3FAB634712566B0E021D617232C8029EB2F76DF624C8DC77AB3789739AB12AE3AB59A7B612A40970D5526023F690C8F1A9BEB4A49F066AA8073E1F865DF9313A63464C65510E078B61320A34E3624E2A6A3E16B7BC3FD995436C92C28B18B149C26754C0DFBA3121778D8E345E6FA4CE8F104F71B77FFE64C0AD945F1F227A031522D07990F88BA91FECB244B5936E87298FDC1836E82C0CB178175CAC5A36C27D3B71EFF5ACAA39200902C611CC1D7395142836692CAC578AA1AC7B12970599690FF9958A7048B7D276DE2088D0B06E5C3971190909C6F216287B2344E3922AF9A4BFC1CEB7E5AD35302E555A504B6B65F710356CC30DF957BD60E974FD31729EB63620E30154636FEBD84DA66BBE270151787B7A8B2BA3431491860C8837B5A93C35C62AE2BDBA43BB58D4126EE8139FFB5BFA110C4075C34F9AC648673EECCB59AF60CB8A6372B69C6E39D418AF88BC23161812486A5F2BB9B2D970B811C360329593CC31FA47BEC0FCA95C226E46A6BD5F39674458BD1683CA4673C39D158D9EE13E9736A6863229156BAE9340532D1A1BFBF98145930EE0A5229323468F7B5A9AE9755F6B603A4360CAEC054276BD3E5A4BF29C85F1DACA2C61A514C1449F94A63C4A3CCCA06D195945EDB3C0DAB07FBF75BFDE57A454C564B99C7DA3E5BA095A462C741E634B3D2DD9B7DF837E5FC076A0C363389C8248036EE55477F55BA27F17740E0AB891D0305E77A284ECA7F84CB3C5483FB3992610384E42A731DB8C3B65B6BBAFF04039D09A9BE4494637A9599CA7A4C42FCCA473D4E88B830A4D2358A324620F9B765A0141CB57DC1B70918053611B7AAA7D6D973C8D4C2CC135940C3CA9B7385823C8A86755717A63BD8EDC5712335786B21CA4106C3E6AB14381A87C6C6FB70635159077BE8369699823F54BCCEFEA3D3AD61613409B41C007947015364BCF42F184BF3BC8B03C6976749347EA7564076CAE9360F1CAA3BDF183889766FD428D13936B25EAA8156776C813705B79CF11030ABDE33B87FA4200544740598EA451AF9ED65CE3D0088F948AE07134BC2830253C9A680477C26180621BA679CB78F4E1304743A2AF124054499A21A9B510C78B2F875445B8AD58A559CF624DB8F8ABD1188812C122EAE81AB0F50435C77D72918E03DBAC7FC61DE848B4BC1729140602E738734B43CC62CB48B8131A2E257D82CB58F69AA6C4A348EA48277A0C8504D07323C61C42B68E5A212B01D66DB645BCBB6B34AF9B8AD7F709EB3720C1B79EF09352A078892787AE73D0B5DF546CC5F35D84940999D9CC59FB39C41762AD4AB260E6795F37372BEAC07005BF80F4A5620B4F23A2255D212746F4CFF73995E53C075C6790CAF4745A2AB8CAE2A89D94A601673023819166A709010C9D4A42CE9AA8C96381B1A7A236781C0C0F10C653F71353224242D3A8F0786A31703CD2063929393DAC152186C84253825481FC86BDFC70E3C5975D3A1DE8F23002126A05DB29FDD143A1F60222D7409B468138A8AAE2A34C1FFB6CEAA863CBC9666DBA1FE7138DE19AAED65256B15CBB08110E25FBC7209750C2CB225F6C5C97836AA04BA1B636BDE9235709483998E85BC1A28F713CA3935505E840A82284B879100389EC2D2A5778C990CCDE45B44D26A9AB74C28705807312681BD662F3E5437772CB7C383D72A53537404FB551CC87274294A85C8BB8484C8113E29708664190F923A387E81EBDAC3CE5890A2C440B9D93323E0588CE003606A5204B93288EB6B62F657C6E511059AC4B3DD57D402064B9C086DB955A7958C399F17AB353108E821A1C1084E11B20F2123C1CA6600AD330587988586C8F698BA258165FA3199A423548EED0B46535935C964BB4A0988B2346BD64BA7FA23D42FAAEF424901878012A772FC4815C26D54037F66F8BBC0E82C7753E16C40E1C17C2BC35F470251393B3B7E84534226DB0237DA2960CFDC99EEB4CA4AFEAA15B9271D9F74DF6CA5631935579AA5E189A715827220CE26BB1C07D719751560765E5A2296CB4BD9C44C4D6376E39A89AA8B70AF987AA0C3C10E714931059AFBC6B07B3523B1175AB9E0902BAAA56754A76C09C4CE232B5EED28F58F097BE3A0F5C290615DC7A4C4C328E413D8E43487E124F8C28444E70A7AE02B64D618D8831609CC939859BB100FC31513B90CE30B59061C38BD17DD57A6A2B0A3640E591524A06A6063259467D1F0821813411E62713A742C0ADE48FE3575338356F4CE99C1995667C34CD2582C0F9B7C4A3DA412C737253A3C3957929D5E4CFEFECAC09BB557231A11ED94F3C7A1BE5060313F540EE5576221386DA4C6A7CB71E307B395DB9C6D7DCB256C42D6F52908C565F06DB823463A634AC57299687641A556F5599F961B6E2F0A30053BE44150E1BEA7DC6D1A4488855127512CE9B2B1F4C07FFABDDF9E7FC37FB0A738DED0707C266F50028D4382821B206CE45306AC320BAE56F49DFDD86F37E1B36C23DC86DABD71039AE2E2700391011D9CC8265C2D5C9779002D54E1BDD9607402054CA95" + }, + { + "tcId": 63, + "deferred": false, + "z": "177A8DA7AF8DB3F712E1653D05A47D61B59F4F4950549382E56F761D7126F8F9", + "d": "F43EC0E96A791317938761FFBE97332D5D85F52D22BDA6303FE7E7107DB608A6", + "ek": "F4C227FF124D62F0269297261583A7D7EB570E6A52C8B9240D1B1A79946FF3990DDD20AD71284E7B004656270DFBA0681DD2C5C41939D6391F4AAABA0ED3C6AC55B4907534DE05B775CC6284D53D045BB611F5BC62F603327C143E100B6678176A40A4949A923CA651F1D2589896BA74E41722B3A0C1C652BCC7ACA769119332A080211CCA8AACD4799513BB0906A063F2AC750C99A805B792699400F609960D177BC006227BA40CF1C547BD81C9F5D67947B6A7BFABA98415C81A4137CD2CBF024322633A8B1B242594581ED8720A794293FDB282EBA064DF25301FEABBBD14BA4FB8970B52B4E3574BC57218AEBC5FB9E731F5A85CFD1154B42575A0B3BEE2FC97CB691AE9F4361F11692D9CB07D793A3C6588ADF24FE098B0CEA860E0173C35223C678A10CD3752E97766B28BA562D1CB93935E97E73B6DFC3248217E44FB08684B5419D749D9350F143CC66E9921FA6C4180D43A721424C06864EA98CD3E60C12020AE7123ADBC2CCF40577BA4F87E10B755A1567941F98E0D0A0D26A9303383026D021F2284CE313AAC3C0A765D11747EEA8BC2832EC87B22EF31AD0D1409FC66A782B2B09AC43EBFE215862B6462996A3703525281BA8328621E436DBD533AEA69B62B429F83A78843051AA0D003C6F8BA224148E15A5AB39A6EAD69262627C7B0C46730C66D2109512D424849A53CE58B9FF463B87945CF9E253130A64CB1F18A2ED875D43026BB8AA2B87ACB00186889C082391C95273BB864E548ADD29A876B3445A471B685C659E213853C62E1A802E2B3C4C392575620597C7131F2764AE68B95AE190927E110A10A553E008F39054DE62C16912064F0B7711EF59E85E50E30395A36A11EAED23CB48A01C8F67729F6B638E3B6820A0E530ABDE31A97E7DB117B035897952F0A0473AAE5897A86725C53855AA43A16BB31BE7C564FDBA0BDDB44D6E64E7959C871728C7C5111D989CFB9026902B82544B528D4FA8BE3196C6318CA1BB791B7069EF2D225277C60B03C48C183484250B4FB0A5B05E260E8A9C958CA51F9BC69DA7ACEB006569B427D2A60C070D81C410114E753BF85651E3504418E747B8D787F0237B184834FF8689519034FF6956313120A0495267B754BA5015D8A134688B11160A2CDE5E8B18D4400AB95AC6CFBCF5CE72020C60761128CBCD5BD36817360663F83A7A263B9420A654C7280381092B4D295B3DAC03E918926B5C29BEB0478A01A39A8B0CCCEC05125D84D2872CAFC97A8627866DC7380DE17709FAC24EA1A0E00DAB5990A919E0262DA522CCAF9B0D3F11268D0A2B2BC4D85E641F64048A3557887A266A8DB13EB555608960E49618B1E39708B65151C4BB8D2154CE7B6A13F86B75367B005C9A69DA98B82ABB17EF9678EB50F3F097A6292930191A15FE075BC304D49926B3D71B675C26869B6BB93264F74702E17102DB5BCC881751120CB8D3E05215E4B34A505529BAB1A2A259B7BC7999404BD15272E44B9AA4BDC891E01A21B8A71B46725DD187E2041C07092CFDDC902D3DBAFC29379691644D0E15A8F7378298A8834D1C1B078384C140F460B144826188F51852AE0ACBAA1ADC4D86147C02F61C1B154193B2627C609682A6E656725774A2FC60DE52A3837537C421A58312A7E6BD1CB7B7661FDB3C1D9C51C3A6A44F260982BDCC01FA149697B24B00B76C5DA2908181E8CE21A28D9142F12659023536F392AB3781C74569DBA10506CB79BA214C49CD18A1D9A693734791FDB76360A142B71252B9020099B389AEA8A25796CA43BB5FA881277D742B6C7CC4651CDF47B91C73B7CC816B16F040DCEEBB3E27C68F0388ABE1A4B2B8B88820B30C9D03C1ED75A9E46774B9612C6C039C1F0404F40CAB35369BCAA80FA2C53975C63F75211B1154F94C3AEE4DBB3EEE500091BA629900A54245CBB4C92296769D979530371A0EEC19DC6718AFACCA91D219E37788802B5C162237A7274C3BE821BC969493E884DF2E915ADC3AD6F1919218C844AF94C983ACA8038CC3874C0C080161D5B4F1266420881C906C145ED15692E8C24F2574F80EB3265157EF3E63BDA96390AC160CEE8B6A79B363C290B4B35AEF49CA4DFFAC0F0423249F27A6CF77558F0631581B36E58AD1DB09F4781B8F813B0ED6578FFBA5A73FABA29D94B6F9238A9089CF41BEE300083ABC96CF379FBD0190841D981FE9CFAD1C7FAF23D2426AE", + "dk": "95937E82B41B65D97063375BF2516320419CE2DA063E41B62E50AAB029407A98044163C56670C75B368D6771AB590A40177073DF486D083C62C5698BC02B97DA59CFEDE6305E3ACC6DCA183093622EE80177BC507DCB8C5780A398FAB838A7CBB7126883A006A848B743FB7D0FD4CE1E4CA026FACC5F981AFDF0AD72FACFA69904BAA9944335B14B9521B492876FE30D07F81BDD7162AFD5A4BAB76E13901CCCA7700C45B385C11F23951DA37740FF58818CEC668992C46B5A478AD221A3EC989F77A5D9B1095F2A7AA0849A731AAD51A6B51B0CBEED2A8531B9A3D3C39E55597E1076AE4B4146740A8A16051A9EFC5C4E016695BA97A26AAE6D850590773D00449CA68A4E65D0463EC15DD46813A7810051203ACC7A42814A7121AA6B45EC9E37DC2F40AB96A1C025835CA7C8198F292390E3D5C9967865F2108DD17402DA657175C65AC47842E1473F9BD29DDE44388695109453B823E204A05A9B3AD6A398B69185028460F8230E3241E4012659E05AAA9CAAB8D8079C65919C8304EB6AA78330BDDBCCA763B91729F81B05BAC53BD31332FABC69D4CDB85CC0DF0B47961731D26A2FC1649A5B53A05CD13109479A75B48F67898C63713EC7883BC3744C9A60C23AF5320C645DE8C242C0B17EB97974CCF76D57180E40330663F9BC737A40C2202F47B22580F5CA070C4488B1B139D0155B1006A7B31A79F0BAB9239B9E4B7DBACB534790ABD0F28141D43CA52792503B4C0CE96B0F505A4E263D1E9429F631447719B8580C902385B221FA2C174866E8872D1B299706B860343BC9AAE6660B77C7E2BA5C8C1CAE4A054A60038743655378080044EC7D45D36411768595BC1D30A43AE3805BD77211E1EAB4C97C9A4F6408FC48551D880B4728388F55519757B9B258781AD2915D40C9DA27961145AABC1666253171A62425C8BA9667322C7C9599104C034C1168A50A47A44A7BD078B24726561488661CF70FB2B7242BC354DEEA94324622B55607F06221A65255C2924982964A2FAC5BBA75CAD6B4677DA45F96DB2F91FA7517AB968A66AF8800AD431423F03936F3614D3ED7236C8A32F16B4DED28285CD46A5AC06A42397A2CDAB0FFE1A70208A226233A84B4AA6B0CC8BC1A4913B44322FACAA7917D119556412880286405EB6C9A7E75CE74C75EDF794A067747AA0B31E99C1F68C25696207C90B97CB57C5088982129811E08773249C5898FD4B86D79BCA5A02C1D389530EBB1AA2ACA1DF1A60FE19649F7026B9229B39A60F29982EAA639D9830074CAC4C375295719C4FCD03A36D99DC6306DFF96A4AA1B0110D37A1E716DDCFB0A322134A978C1D0998CD5A8943B267E2B6B0D6936111BF630B0CC89A549405CB295038ACBF22B6E15788CC8966060EC4BD71255511826CF163A6C45AE24FA8536C39F8C19C7856A3700972FDB959AAD019C04269C97D7CA55121A567BBA5711A7F7E28A13F955DD06988AE2BFF90C4C3C605E0B200DCBF139E576BC367C1D151A8F7297B5C76CB826208EDCA1CB23183397A37A92B233F65494E6E3644A364EB8F05FD93248DABAB286991297EA1A87B947A8C0C1E32A9B336B44E5D045E4418C8BD366DF77C2AD90CA2D690C516B032060C32314CB7DDA818E80456E588248609E4E4BAEC2B30FC1E8A984082C23555093D375FF129CDE4498BFD4A40AD1678AE78C5647B6998212CB0010241703A781727FD755B5907B12350A853440B9019F7BC3738A1A2BB291A549A9892D74BD2FC4B13BBA718F9877BDBA32B7D07F0DF33BC0C19AB3C2B567D7110BD3592274723F5A69AFA632FE8C41AE7CADAA115E61B897C4444FA7099AEF0290A6A13E8D551A3DF565490A825DEB6D808AA7AF377B27355324C355C32358955B883F6BBD42C66801CC443BF34F2FA040FCE4B7237C4ECEAACA821AA8B248841D242B6EA5561B070E06F711528109693AA289740F97A4169758151ED57A15381EE35297016B0699C34F9AE039ABA26ABB11148BB4344359CF14466841C7CEE7B3541B6072BF021E3B8348E078510DE0839EC55C38290F5C5095B429AF7BC970CE46110F54967C42A2AF4A3CD5BAAA5BBB500EA382E9427FE02595B0E6811FE32E932BA6B479114F5B7224F98EFDE80CDDE06BC580B30A5175B9B38958393B3BF0573A7086EDD0A1F4C227FF124D62F0269297261583A7D7EB570E6A52C8B9240D1B1A79946FF3990DDD20AD71284E7B004656270DFBA0681DD2C5C41939D6391F4AAABA0ED3C6AC55B4907534DE05B775CC6284D53D045BB611F5BC62F603327C143E100B6678176A40A4949A923CA651F1D2589896BA74E41722B3A0C1C652BCC7ACA769119332A080211CCA8AACD4799513BB0906A063F2AC750C99A805B792699400F609960D177BC006227BA40CF1C547BD81C9F5D67947B6A7BFABA98415C81A4137CD2CBF024322633A8B1B242594581ED8720A794293FDB282EBA064DF25301FEABBBD14BA4FB8970B52B4E3574BC57218AEBC5FB9E731F5A85CFD1154B42575A0B3BEE2FC97CB691AE9F4361F11692D9CB07D793A3C6588ADF24FE098B0CEA860E0173C35223C678A10CD3752E97766B28BA562D1CB93935E97E73B6DFC3248217E44FB08684B5419D749D9350F143CC66E9921FA6C4180D43A721424C06864EA98CD3E60C12020AE7123ADBC2CCF40577BA4F87E10B755A1567941F98E0D0A0D26A9303383026D021F2284CE313AAC3C0A765D11747EEA8BC2832EC87B22EF31AD0D1409FC66A782B2B09AC43EBFE215862B6462996A3703525281BA8328621E436DBD533AEA69B62B429F83A78843051AA0D003C6F8BA224148E15A5AB39A6EAD69262627C7B0C46730C66D2109512D424849A53CE58B9FF463B87945CF9E253130A64CB1F18A2ED875D43026BB8AA2B87ACB00186889C082391C95273BB864E548ADD29A876B3445A471B685C659E213853C62E1A802E2B3C4C392575620597C7131F2764AE68B95AE190927E110A10A553E008F39054DE62C16912064F0B7711EF59E85E50E30395A36A11EAED23CB48A01C8F67729F6B638E3B6820A0E530ABDE31A97E7DB117B035897952F0A0473AAE5897A86725C53855AA43A16BB31BE7C564FDBA0BDDB44D6E64E7959C871728C7C5111D989CFB9026902B82544B528D4FA8BE3196C6318CA1BB791B7069EF2D225277C60B03C48C183484250B4FB0A5B05E260E8A9C958CA51F9BC69DA7ACEB006569B427D2A60C070D81C410114E753BF85651E3504418E747B8D787F0237B184834FF8689519034FF6956313120A0495267B754BA5015D8A134688B11160A2CDE5E8B18D4400AB95AC6CFBCF5CE72020C60761128CBCD5BD36817360663F83A7A263B9420A654C7280381092B4D295B3DAC03E918926B5C29BEB0478A01A39A8B0CCCEC05125D84D2872CAFC97A8627866DC7380DE17709FAC24EA1A0E00DAB5990A919E0262DA522CCAF9B0D3F11268D0A2B2BC4D85E641F64048A3557887A266A8DB13EB555608960E49618B1E39708B65151C4BB8D2154CE7B6A13F86B75367B005C9A69DA98B82ABB17EF9678EB50F3F097A6292930191A15FE075BC304D49926B3D71B675C26869B6BB93264F74702E17102DB5BCC881751120CB8D3E05215E4B34A505529BAB1A2A259B7BC7999404BD15272E44B9AA4BDC891E01A21B8A71B46725DD187E2041C07092CFDDC902D3DBAFC29379691644D0E15A8F7378298A8834D1C1B078384C140F460B144826188F51852AE0ACBAA1ADC4D86147C02F61C1B154193B2627C609682A6E656725774A2FC60DE52A3837537C421A58312A7E6BD1CB7B7661FDB3C1D9C51C3A6A44F260982BDCC01FA149697B24B00B76C5DA2908181E8CE21A28D9142F12659023536F392AB3781C74569DBA10506CB79BA214C49CD18A1D9A693734791FDB76360A142B71252B9020099B389AEA8A25796CA43BB5FA881277D742B6C7CC4651CDF47B91C73B7CC816B16F040DCEEBB3E27C68F0388ABE1A4B2B8B88820B30C9D03C1ED75A9E46774B9612C6C039C1F0404F40CAB35369BCAA80FA2C53975C63F75211B1154F94C3AEE4DBB3EEE500091BA629900A54245CBB4C92296769D979530371A0EEC19DC6718AFACCA91D219E37788802B5C162237A7274C3BE821BC969493E884DF2E915ADC3AD6F1919218C844AF94C983ACA8038CC3874C0C080161D5B4F1266420881C906C145ED15692E8C24F2574F80EB3265157EF3E63BDA96390AC160CEE8B6A79B363C290B4B35AEF49CA4DFFAC0F0423249F27A6CF77558F0631581B36E58AD1DB09F4781B8F813B0ED6578FFBA5A73FABA29D94B6F9238A9089CF41BEE300083ABC96CF379FBD0190841D981FE9CFAD1C7FAF23D2426AE2A959860220DFD26FEE86E0F4EB1D8E31B240EFFB9EF6091AA0BCF551A09B2B9177A8DA7AF8DB3F712E1653D05A47D61B59F4F4950549382E56F761D7126F8F9" + }, + { + "tcId": 64, + "deferred": false, + "z": "79E3B0D4F4AF344ED06FDE8BF4E104753E832294A3D2E4B66BE59149006A7B95", + "d": "0596F1E214B29A0CB7A641EA0BB157FE01FAB73B4A9BCDC165FA44C8FD5FBF71", + "ek": "BF2A86AD3020C241CE4A00913BDB13F82266DD873742A3519E44C39F20874575A780370BDBC32F50F892366C3D3E5A3CBD2A1A9EDAC8D5468A4FD28D18281C4ADB485B033E76B3B604A5394EB6A280F81C93B86839C2198430558889696CA715CA0B901D762A498875DE991479A45725E12340953D95461ED32AA018E33BBA0157F3A6BD1BF07FBE2207D81166F5410AC20096E95B6F48E09190ACB51A86AD4C51AD1733729272BE79BCB14834A230F00C64E0416AF77C2F155776D6528BD0C9762B60350430A3BCC51DEA9966D791A3904A1F6284A32B4C865CC67C1B66A7F00BA3C9971AD846DF61348D2C418DE0901ED19D32582ACA784AC96A55AAE69D27B58973B4816714B2139C2DF5A380739C43CDF0A161AB8535F678FE344C5E4881BAB8785805C615711ADEA09B702201360B2479CC7FBA69868903CED7074D7F93AA7772B3359644B0A3A169A59C177CC60E8B4360978FC7C513A95C355643563BA0371D973F7A991AD099BF94239815C7041A312CC3497E9A40A5D3F9504BE107FDEA73D8769025D75479575F5A45974FAC400F0189076457A2A96D9BC2C1B19C5382C423B3333F0C9B7E26FCA8F2DB01265460A4C253EAC707B39109AF07241DD6A8FC5A9D18494C3D715424108114280F3A5C23CEF53C5507BDF3BA5EDA6327AC15B484793011241305462DADE02D4459419909075C09BA1044B896A28E17866FEBCC0A4970B1734C4EFA42780C380EAAB17C82B96D72CBAA83127FFCD7998071BDF8EC59881AC74177C1E194A20BF5A4DD71C4E03A82D6E40B70986D2A368C53C54BD7B0CCE1B5A161140E01047443497EFB4C4D3FE126686BA354B504B9537C27B21B56355BC0A91F82E94853801801AA5FD8287EB5A1BAEA773EDF16B376311DB6089AF1950A385037DEABA09ECC491F4882CD484604F304730C11EB3C561F36B85D1B1ECAE15FA1326F9EA486CE32978E9C267C70AA33E0113F4C3B618B405A160B4C93BF943C806FB41C62F83200B81AB2CC57CEE96364D86D4630BCA5A70064151545EA9D9A419E41242B6135AF3A516C8DA4447AB71478266E5BF69F2B846075C30F3368B30912BE48A00CA3365BBAE0597A93942396515A72B675C460BF4403872995AF19CC25C737F86B642ED740C9E5477C0154D05860A30C2DD49B14E8DA87600C4E8CA63401DA998D7689D9CB364397C4DD056474C2BEE16060D4408A3E19BF6FF8A331466209F0B428F0316CA89188B9C7B2AC25A7940DB7A1766799361BA984A1BB7E789B2438D6777F92A15CE7A2D156369AB819B116CD99076095C70D265651550BCC1F4307497BB77E75023AF91D31F4414B38CB64CB570AFB56701C17CB692A46A444455C8063A3616590AF6064BC337237ED1824CCD7CFB96B55FFF91D7D4714CBBA74DEE5AB48A28389458E2D43476CEA2B1A0B6EC499A83CEB8EB4C7539BD93D3AC987AD07A1C9F079850C1444D0B5C9CC619614301CD77776661357FA80F29A3CE4A8AF8DF55FB259B754504687508AC12AA81DB8CD19C93875AC5C4CF13E115221EBA49F3BE008D4B80E9EBB8AE0CA997313872010497CF9556DF06D8F766D2025B03099BAC8202C5D90B52C5397CF55BFACEB5A1C079CC02960FB976A735357DF16B90210194627A5089B1D29CA4FE8A03B4FFBB544A645C5FA95EB386408DC65AAD89CDF0285F3745EDA596D070356D350775FA7A088D732A61C1AC57306359B4A642B8AA8BB91A347152A916D33427DAB37143AE14B2D804B0FC033EE2B9D996853ACD202B2689AD945CDA48938BCDB2D8DBA5449C80891B103172381200A68BB7B505EC5A373E15DF301BB7547770A5B21A571CF4CE87B1AF38D3D38329BE9AD366159FF1919DB40233E86BB497652379B9099F68B22EA91552273AB1801CE6BA9FE7B07ACE9A81DBB09B11CC4AECA25B5090C6FD885B7E19941D8561A15CC35046EC191157C393168C80311432C899B0A0AA578460963E7767750560064B93AB148AEF2FC2FBB029C89126535C6BF2DC48A04748D23A6225EE6C3EEA9B68C65BCA2E9C804EA5BDC441BD05293B8C19D96E369B5C3459DABCB20565405824EC3F57475AA4E19DA21A8EAC0DD312E9FC10B56D6C6EF40A130844D8FD68769E2CC08288D770CD00556578D853FE4896886536AF0633EFF38C1439E3E7950091189960045B3B3B18BD45BE846AA63E4D3845BA0", + "dk": "C62AA41327AC132035DF838111878AE1BC660EB53459381290580906A45376761BEDA32D498611D642173E7CA019DA1AF1E60EE43601F1262D3B396FB5611FDEC023C891407AF4A8ADF85D4C010F7DE70829138F0F520EFFB4C8D5230253CA72A6FA3D4C4158A65C12FB9A36BA440A40B476D8C65CED2968BB18A11751993B725920399933F3B18DFA9A4ED87A7AB277DC027CC33A83E43B9DB68C8F68D72FEE7210E9E1471869B347C79B848C623834C586B341B23203D2CB1AE5E9CFB87A1794D43598EB0CC8836BDD42371AC9B7D0513F4A7840C0371D73BA88A7DBC5A5753020298E3D616A8DB46C81C80045A553984939D7593535D6BF2A330BE54A3D1CC0B09774279F952A59F673298C6B1C078E0FC87038D03304E0C4585577A6842815D9C9F41534F216B5B0474F1574BE15051F3DD69CE3E9870AB13FAAD180C82A1ADC2927A1D20EEA168A97DA7ABCFB617B7570009AC7D212B6D05483B7F54F7C201588A879235823038834685BA5C7649CA7931D3D2B155A3410A76900E4738A24A614AAF119D8AB6111E383BA33A4614823063C31EDB9B031953AF6FACFD3D65ED1557EC879B89F3709D177A8818094B35500A10B30E10C7917956A0181BD6B0817F0D85347430EE6724B5380BEF508AB3B468AB6C8868FC48A62F3445104A41C8C288DDC5746C84301E5315C603F80E9B83F6C16920142611CC32B18BD7AFC28D3D343AAEB8AE7133F88E388AE6C7C4911318A3957904AA51E2905D5A02C30CB57DA0551B4134182C060DBE80BAAC4981B410D1D5104D92BB47D3BB6846937CF6B961FE66BDB5C069A0304D91AA22D8898F8067295DA9BD6DC3408F3636DE5CC6948C9DB2B17DD4651F1419668AABEF031CD06FC63BB9749C4DAB8A160B5A4C6A13F3A4F8941712EFA60E5B426E1BB29F65940368594B681CD30D41377F58254964FF0AA4D3A5B553327762036757429CD47D57DD73698BA0C765B3C539CE41A04A58775E70D4EF38D2B9775D203982479937E5135FF1B944F6CAA0E87269E52B52DDC3958C99C668170879B7FD03427C4F38E147B6ADEA1BF0123B01CBB199644AAEA95B76DA7C5E60839C3EC0D50C4A01E79810BBC1220F612FE34A89B173C7E6042BD876D0EDC2D9A03559027AE0844492B539F2843A2A49C6E969C121CC64E4CDBC624167C22911A27656109643F695334F3C73694758F06E94CBC15385F181EA1B012D93C5AF375034514074C92401A455BC21C8B97AB7D8CA64B58C415B53AB4D322CF28F69882A4C0F5BC060AB09AD643311F29398205753D623EA424C7F2D38CF0E1074F1CB5A9E91B19D91A637A83E15B3DF5B7C7987A4D5FC151E9012021F00CA8E31069F9451E4B6E5D7331E85980077367990AA632009EDBE0432722A825829074953E6BB752C7D86490D7C760E7177F54806CDAC557C70C3DA151B9F30877B22FF8742BE8077C7C82A212BA077C148D90E86D5AFA15AE30362CB287D3BC318CC28FF74AA74536A73009C00E9B8A7F8AC11BEB5CB6CC965D672141DB7784B8BAFA395996FA4DF8C5C014C8B73C3302AA6542950A163AAC35D7C222B1A2CF5C9A820D682B6E98242B28B8B9D32E973B823027211784415BF27E2A0C60125295BC35007E21A3CDB4BEB6E26FF26069DC1BB675032FFFF93924870F0616BCF6679353200152369881182937565B3BF4711882C9823B800EA93CF7889B14F521C5A34C81A6354B70CF02D0C195853846505DC2E82B3F3651815480CB739AA49C55E0B763C9982C69D0669DCC76A3D262C304843FD322E973159EA358E5811D4C324914BB89DC7BB1BA61C4C2E9C25B0886B6F5ABEB827992B6798250975BE205B6252CE3DC5DC2E00D4CB427FB9338D6A19166C2978EEC81A645714765095E89799082AB42D08FD2305159B42C80B13F44AA9FEB46B8F3A5552BA534B9F26A2E5B2C00822CFA573106555C9E8C5B1475A38E4782675B9A6FFA294A7B0A2FB26AA8387C46C20363B2BE83E9AF100211B02701CC0A10220134DF6230874A83C49CA846E1106591AC21B82BB587583C33BC97BC62C53C316AA58C525750225C795424B780EA39E9E79588AA9556B2AB9BE98057046EEEC406FB4A81ED364964C1559EFA623307A891A9B7F06433681B2D5F583257E2968786A77CB6C9BF2A86AD3020C241CE4A00913BDB13F82266DD873742A3519E44C39F20874575A780370BDBC32F50F892366C3D3E5A3CBD2A1A9EDAC8D5468A4FD28D18281C4ADB485B033E76B3B604A5394EB6A280F81C93B86839C2198430558889696CA715CA0B901D762A498875DE991479A45725E12340953D95461ED32AA018E33BBA0157F3A6BD1BF07FBE2207D81166F5410AC20096E95B6F48E09190ACB51A86AD4C51AD1733729272BE79BCB14834A230F00C64E0416AF77C2F155776D6528BD0C9762B60350430A3BCC51DEA9966D791A3904A1F6284A32B4C865CC67C1B66A7F00BA3C9971AD846DF61348D2C418DE0901ED19D32582ACA784AC96A55AAE69D27B58973B4816714B2139C2DF5A380739C43CDF0A161AB8535F678FE344C5E4881BAB8785805C615711ADEA09B702201360B2479CC7FBA69868903CED7074D7F93AA7772B3359644B0A3A169A59C177CC60E8B4360978FC7C513A95C355643563BA0371D973F7A991AD099BF94239815C7041A312CC3497E9A40A5D3F9504BE107FDEA73D8769025D75479575F5A45974FAC400F0189076457A2A96D9BC2C1B19C5382C423B3333F0C9B7E26FCA8F2DB01265460A4C253EAC707B39109AF07241DD6A8FC5A9D18494C3D715424108114280F3A5C23CEF53C5507BDF3BA5EDA6327AC15B484793011241305462DADE02D4459419909075C09BA1044B896A28E17866FEBCC0A4970B1734C4EFA42780C380EAAB17C82B96D72CBAA83127FFCD7998071BDF8EC59881AC74177C1E194A20BF5A4DD71C4E03A82D6E40B70986D2A368C53C54BD7B0CCE1B5A161140E01047443497EFB4C4D3FE126686BA354B504B9537C27B21B56355BC0A91F82E94853801801AA5FD8287EB5A1BAEA773EDF16B376311DB6089AF1950A385037DEABA09ECC491F4882CD484604F304730C11EB3C561F36B85D1B1ECAE15FA1326F9EA486CE32978E9C267C70AA33E0113F4C3B618B405A160B4C93BF943C806FB41C62F83200B81AB2CC57CEE96364D86D4630BCA5A70064151545EA9D9A419E41242B6135AF3A516C8DA4447AB71478266E5BF69F2B846075C30F3368B30912BE48A00CA3365BBAE0597A93942396515A72B675C460BF4403872995AF19CC25C737F86B642ED740C9E5477C0154D05860A30C2DD49B14E8DA87600C4E8CA63401DA998D7689D9CB364397C4DD056474C2BEE16060D4408A3E19BF6FF8A331466209F0B428F0316CA89188B9C7B2AC25A7940DB7A1766799361BA984A1BB7E789B2438D6777F92A15CE7A2D156369AB819B116CD99076095C70D265651550BCC1F4307497BB77E75023AF91D31F4414B38CB64CB570AFB56701C17CB692A46A444455C8063A3616590AF6064BC337237ED1824CCD7CFB96B55FFF91D7D4714CBBA74DEE5AB48A28389458E2D43476CEA2B1A0B6EC499A83CEB8EB4C7539BD93D3AC987AD07A1C9F079850C1444D0B5C9CC619614301CD77776661357FA80F29A3CE4A8AF8DF55FB259B754504687508AC12AA81DB8CD19C93875AC5C4CF13E115221EBA49F3BE008D4B80E9EBB8AE0CA997313872010497CF9556DF06D8F766D2025B03099BAC8202C5D90B52C5397CF55BFACEB5A1C079CC02960FB976A735357DF16B90210194627A5089B1D29CA4FE8A03B4FFBB544A645C5FA95EB386408DC65AAD89CDF0285F3745EDA596D070356D350775FA7A088D732A61C1AC57306359B4A642B8AA8BB91A347152A916D33427DAB37143AE14B2D804B0FC033EE2B9D996853ACD202B2689AD945CDA48938BCDB2D8DBA5449C80891B103172381200A68BB7B505EC5A373E15DF301BB7547770A5B21A571CF4CE87B1AF38D3D38329BE9AD366159FF1919DB40233E86BB497652379B9099F68B22EA91552273AB1801CE6BA9FE7B07ACE9A81DBB09B11CC4AECA25B5090C6FD885B7E19941D8561A15CC35046EC191157C393168C80311432C899B0A0AA578460963E7767750560064B93AB148AEF2FC2FBB029C89126535C6BF2DC48A04748D23A6225EE6C3EEA9B68C65BCA2E9C804EA5BDC441BD05293B8C19D96E369B5C3459DABCB20565405824EC3F57475AA4E19DA21A8EAC0DD312E9FC10B56D6C6EF40A130844D8FD68769E2CC08288D770CD00556578D853FE4896886536AF0633EFF38C1439E3E7950091189960045B3B3B18BD45BE846AA63E4D3845BA001699FB3EF1CB24186CF884DBF62F4BC68D598BEB013F7C438C66E180500AD0579E3B0D4F4AF344ED06FDE8BF4E104753E832294A3D2E4B66BE59149006A7B95" + }, + { + "tcId": 65, + "deferred": false, + "z": "EF0F95F630F41B3AF911A30E543822DFA6B7684FEE36956D2BCF8FF080C9FA26", + "d": "D7349F9AD546CFE9830E1197072B6ED9CA21E8E0423F145F1DB84A5AEBA230EC", + "ek": "4D09B276CC63BC453FF20B31FFDCA2FC3C34AEA706769A58AB6CC210551683C2BABC76B5CA69256816172BD926BA7C91A4DC12AC5A3FB087B6E1D3C0042BA5E0F98E5031A6E5077108153CCE342B1F832EFBBAC43A9C0B5A01283522271E649C3AE8C43C541C88603E58F99C1E8502DB34CF70AA48EAD6802844A7B25594308537BF657A07547CE1380AEB994F4F676FF6EA3B9A728AAE5B4E4FF34A5B68530C582194320E6BF76B997A8CF42819DE5B0D1C82491E741CEDA8AA6280094E332D95FA799FBBB769B2BF769798854899D67C1007FA29CD7245F727CB206456E4020F80A9600DE948DD2AB469C1883151A440C49570430D003C97642601CF010C200198ADB7ABC04379864C7FE6CC8BBC29CC1A6335869ACDE9DA9DFFA17C7B8747848CB7DF12B52E8C5EE7144F2EFC3ED00846B9F72598219793A6397E7726F8242B5EB92EBE2577E686B980F34859B07FD24084057B13A98880C93458D59BCD5AA68314EA18E80A94CD826FDBDAC1F05A472DE0872027C1CF924D5BDC9F236B1893DA61486757FC758806F580279919862C0333B15A66C138E4DC6ED50B17EAFABE9074AF14270C20806AFF0B58ED97631884435A55A8AB394EEEF5347B2640E6980C41A30A18E85A86074E03DBAC48855DE4E94538939A4264593B649E5BD981E0917C26D563D287A600EA89CEEA7021E754384157C8ABC5BE47C7DAF72E15787D1CE62723547B0AD86F852B150A25660A4A074E707884CA7934F9BEE2555A0F574B7F750DD293496FF681A09A4976671210FAC3C8C84A03F99F39A7B649A19F3E05A1D0E7A3728B253C5784F92CA7348A4BC086460A24B620845662246F1C0AB9BF91C8CB301D7DC362A3137643C92C8797CBA7E59A17DB9B99D08977D56A4F34AAEBC16FFBC8822822931FC73DC6BAB320972D96C16DAA41CCC89312E43275856856C4598313417C1B5261D9C1430A16C1D2F3CED08C862A21678A170A2E1A643E139873C878AA469F163C97AF7C7A1DA41034878D7E144DB826A7AE48B97A5A131185813D775BEA667CE0518B11429768F58BC30946766A6FE5B7BBCDDA7CE18C29F396307BB456AEC16FCB989F32660CA348A83FF36D1AF452C4584E117A3105C662135997142AB16CBB7C7D28560B087BA4B7B66A00563EFA3DA1C4764F8B7B5D128EC6202C505AC9446015620C359555268BF6AF74144EBB26351E98AF7DA51571F16A01B320595754C0DC23BBC75A8F036A5F6C3AD76907FBEC72530855891381B9F2B719429D4B6BC04F014F50FAB14131C60CBB279B61469E1B8664A38917CC308FE0C7AFF637DD4A76BAB66F08487739B20B9EF850F7F20DD83A1A47B53F00471A1617AD164AC1C04A8180BA68984B4F5DA9BBE1D0CA352509BC0211DA0B321789A61C98222508A03E0A6A7CF3849126435F36575D63B342FC2F02DA45FB8B5C9BBB6E064328550CBB6DA1AF16424A3AE9C1EBE566F4C4A883F966479C0BCB6585D3A2B1E14C3608E05AC5555454EBAF80E5C7BDE47B12F66118027E19F325024A5D51779C17D1B933A1CCE61003D018A3BBD67EA16B02EF997EF0678CB776479C52203875774C05B0EA9586FDE02964B8C3E1968B9940C88763822AE563D814BEEDE38A7D1653B2131558231AE3470608B51FB78CAA99C7252EC8AEAD74025CA8BD5C038283181E9381C73188C403A0B6F88B855FB5673B180F7581AD69513163379B34582128575DCA936A614A17C84C36222C3893D4B5F97829E132449490096605B61925844E31982BD601538739D8E7B378E180FA6A7EB9874CFBB8069447A96CB81169F3514CC20A93A42E0C9CC321EAC10B8AB21A893FC247BD557B6485A9C433390076573EEF854C2EF08AE116C58FC75CBC03BF8FE7312EA5305781CAC7273A78F01C73319B0B26670F26513E57660340563ACB16CEE7CE7CF0BA52671E23A44C85EB994A7A7BA15941F4C301D3B87E0D2A75D2EAAF1789237BB5B02930CE6AE5B965DC5E7277C8EEC0676C55436014AEFB8AA3B1BBA2D07B1F91487C99673A9135611BCC3B3546C42B23CE0A8099D6666FDEF62D402925B4561DEE3986B30C1C6278609496A474928D0A8351DF30C83CB4BF4BD826CB4319BD620C7AD5A7F1EBA1B8913A46D0365285A38C4C1574FA4287C02D71E91A43EF856ECCF60978C7B83099574EAE8C27A0571C4E51B320B34ED55E8B1E576E", + "dk": "CA16BB08B42E527B707E18B2ADDC64F2FB9542C89FF37B4B9187C72DC602FD83CA619836032C19D3497D49FA2AD23C0939721984DA633C14BE7300029CEB1AEE6631F236060D378852F6B1453214D1C87806E42E956286D2356B7B42731B054829B72B6A89BA4C16308A00C35D59A717E72BCFE69DB53C77D6295243FB599FB3BCA5E6C179205E15EAC020826EE8800A97EA3B51400103A362D0669550D1B56C466535B148862258EF25C3FE14A16362B5C940362B30C2E9A660BA66837071AC18D802392BCF17E62AE718288D175B0A61A3010943131070F84374A47C2EA3E690F7660E67E1B813DA13B9E52BB422A2145482C1A536D0E81BDA906A45DA576D09350FE9C223BC31D89571FFAC999EFB71FA59B29B0431FCB68B1FA37DC9585012414212883B640A10E0937CCF3BBA568A2A519B1EB02B515A26335FB52A1D6B9D122C212A913520661A795855A4D65695D4469C3766FEBA11AA4CCB77B4AAE7608A82EA2E22EABD4105075DAB6D88591A2B2B5B11918C15735DAE6546BEB95656F195F0BC70A3FA3D6FE9898BA1284CD368666C8D8A51A7440411525C3F6C694CC586CA15EAC1CD4B88A1A8CCC713233CC5946C009799DA4EC0294CAFB09D94580EE4E705FB842CDE2429694141C0062508C79D69A2515B843204B3857F77A352764A88A5677C885F00A88615E3524C7A609547184FE029EE7572DB3C821C8552FE499478DA9DD708BF602B73F180B5C801C9D7465E77C7B42A97CAA3F4CD7B62BF0AF7A7F2BA6187129012E5C7443738572C1BBDDB784459B9921B9B39D020F169BB7FC6CCC2B71C231A27462BAA34531C3838A1C13B12F353326D870D541895E259208AAC459D44C7CFC44324AC3CC2B7610C96BFAD5806692CA9F567500894A073629D66741A3EB33F56720FC80305F60791BE328DC8C28AA10097CCC03500D1601C25CE03550974F12F8E384C8B310F32A5CA60DCCD230B89788B41CCD6825251C601B54DBEE636CFD491E5B071F8A1BB599144B402C007B80C73B3AA4E6A591AFA2F108C1BDABA34FCE43866661954A046F0D5AEB0F681602490B6118C2ABB67EFF83C349933AF394185F72BCBC80F0C1751688A42E247451DA4BCE4DC5BB5204121236623095B25E91B95E0B5C196699E2CC284B88FFB11426F8944AB174DB91484A2FC7787A97172596DBBE0AF50C68CB9726C11ABB6FF6366CC280A23D457B638A307328FB5E70403EAA029D2B121118AAAA39089E655857391C0D4A85FB7AAA84448CC12A4CE428A37D5B6DE999C7CA82879112E17EAC572001215EB8F3F07C153E6B251E699B3103855C747A6B2A1FF44ADEE996EE5F545373C972D431854DA74DD744CB3C7CCE52A31E332112D70736EE859CD47C381691C9275B8FBB46299A48BEC07506D65337BF64CC5F50E2C3A2FFEE688AF4B52A4DAB2E2E4267851AF5C2CB55255629036674E0185E069266667B9472C8DCDA95B4B16B5845940CB7A378E3CCE2FA9CCDB787415F58C30C46E691B6B6DC4A8B0C892DFBC7699599CE25812A478874568260AB482C5F69D7E773CD928BEDCE7067217C0454310B1694264E3A9D3E41300B87543B4235CF432597A5638EA41637CA894080437766C472047BF5BBFBAEA557B658174A576697613A8A73254DA332F6B232A65B9017928288A44FCF8889CE79718A329CED152E35B4E4EDCCE1B197DACC7942D59C2B0E80A0FC74FC726BB951898AA15CC1B106A383AC10EFB4D48445F9CF59C4BA17D5817618BB27879067FE2615EAD1A2BDABA6C17D422DCA06C3C4578B873B17714A6B8F2AFAF8CB445F04238C954B38B28D1028D451A25C3797872601B98543029F57671F52F8F25AE3C88144D011B22B88F9E60841C3BB52205A00EB24D3254B8C37BB845E10A14B528A8D6C1D07B7AE4E66E4F88C26D116A853B4E41ECC6AFFCA83068188189063030B5BA854541433CC454133FA2B5A3407852A64D9277883DA9AED1D982695854E8D3B114DA709E1BC3B926170C4A2ADECBCF8402A3D9253851274BFED70BDBC817DDE56A166B61DA0793AE0818159C0626BAB102CAC3EAA05D8F996D6EC01FE5E9061147A98EF4A5BA361508B385A5060D5FD0C462F340B943914D117B7EB032348003E89C3D888485E3FA9A3489CACD855F4E55864D09B276CC63BC453FF20B31FFDCA2FC3C34AEA706769A58AB6CC210551683C2BABC76B5CA69256816172BD926BA7C91A4DC12AC5A3FB087B6E1D3C0042BA5E0F98E5031A6E5077108153CCE342B1F832EFBBAC43A9C0B5A01283522271E649C3AE8C43C541C88603E58F99C1E8502DB34CF70AA48EAD6802844A7B25594308537BF657A07547CE1380AEB994F4F676FF6EA3B9A728AAE5B4E4FF34A5B68530C582194320E6BF76B997A8CF42819DE5B0D1C82491E741CEDA8AA6280094E332D95FA799FBBB769B2BF769798854899D67C1007FA29CD7245F727CB206456E4020F80A9600DE948DD2AB469C1883151A440C49570430D003C97642601CF010C200198ADB7ABC04379864C7FE6CC8BBC29CC1A6335869ACDE9DA9DFFA17C7B8747848CB7DF12B52E8C5EE7144F2EFC3ED00846B9F72598219793A6397E7726F8242B5EB92EBE2577E686B980F34859B07FD24084057B13A98880C93458D59BCD5AA68314EA18E80A94CD826FDBDAC1F05A472DE0872027C1CF924D5BDC9F236B1893DA61486757FC758806F580279919862C0333B15A66C138E4DC6ED50B17EAFABE9074AF14270C20806AFF0B58ED97631884435A55A8AB394EEEF5347B2640E6980C41A30A18E85A86074E03DBAC48855DE4E94538939A4264593B649E5BD981E0917C26D563D287A600EA89CEEA7021E754384157C8ABC5BE47C7DAF72E15787D1CE62723547B0AD86F852B150A25660A4A074E707884CA7934F9BEE2555A0F574B7F750DD293496FF681A09A4976671210FAC3C8C84A03F99F39A7B649A19F3E05A1D0E7A3728B253C5784F92CA7348A4BC086460A24B620845662246F1C0AB9BF91C8CB301D7DC362A3137643C92C8797CBA7E59A17DB9B99D08977D56A4F34AAEBC16FFBC8822822931FC73DC6BAB320972D96C16DAA41CCC89312E43275856856C4598313417C1B5261D9C1430A16C1D2F3CED08C862A21678A170A2E1A643E139873C878AA469F163C97AF7C7A1DA41034878D7E144DB826A7AE48B97A5A131185813D775BEA667CE0518B11429768F58BC30946766A6FE5B7BBCDDA7CE18C29F396307BB456AEC16FCB989F32660CA348A83FF36D1AF452C4584E117A3105C662135997142AB16CBB7C7D28560B087BA4B7B66A00563EFA3DA1C4764F8B7B5D128EC6202C505AC9446015620C359555268BF6AF74144EBB26351E98AF7DA51571F16A01B320595754C0DC23BBC75A8F036A5F6C3AD76907FBEC72530855891381B9F2B719429D4B6BC04F014F50FAB14131C60CBB279B61469E1B8664A38917CC308FE0C7AFF637DD4A76BAB66F08487739B20B9EF850F7F20DD83A1A47B53F00471A1617AD164AC1C04A8180BA68984B4F5DA9BBE1D0CA352509BC0211DA0B321789A61C98222508A03E0A6A7CF3849126435F36575D63B342FC2F02DA45FB8B5C9BBB6E064328550CBB6DA1AF16424A3AE9C1EBE566F4C4A883F966479C0BCB6585D3A2B1E14C3608E05AC5555454EBAF80E5C7BDE47B12F66118027E19F325024A5D51779C17D1B933A1CCE61003D018A3BBD67EA16B02EF997EF0678CB776479C52203875774C05B0EA9586FDE02964B8C3E1968B9940C88763822AE563D814BEEDE38A7D1653B2131558231AE3470608B51FB78CAA99C7252EC8AEAD74025CA8BD5C038283181E9381C73188C403A0B6F88B855FB5673B180F7581AD69513163379B34582128575DCA936A614A17C84C36222C3893D4B5F97829E132449490096605B61925844E31982BD601538739D8E7B378E180FA6A7EB9874CFBB8069447A96CB81169F3514CC20A93A42E0C9CC321EAC10B8AB21A893FC247BD557B6485A9C433390076573EEF854C2EF08AE116C58FC75CBC03BF8FE7312EA5305781CAC7273A78F01C73319B0B26670F26513E57660340563ACB16CEE7CE7CF0BA52671E23A44C85EB994A7A7BA15941F4C301D3B87E0D2A75D2EAAF1789237BB5B02930CE6AE5B965DC5E7277C8EEC0676C55436014AEFB8AA3B1BBA2D07B1F91487C99673A9135611BCC3B3546C42B23CE0A8099D6666FDEF62D402925B4561DEE3986B30C1C6278609496A474928D0A8351DF30C83CB4BF4BD826CB4319BD620C7AD5A7F1EBA1B8913A46D0365285A38C4C1574FA4287C02D71E91A43EF856ECCF60978C7B83099574EAE8C27A0571C4E51B320B34ED55E8B1E576E82D819925EC1B1F45E255B12DE1637697CDDD47F41DDAC13484983D75BAEDFB2EF0F95F630F41B3AF911A30E543822DFA6B7684FEE36956D2BCF8FF080C9FA26" + }, + { + "tcId": 66, + "deferred": false, + "z": "DDD4871080BD4F761D972085851DE0A0408A2F5EEC3CD3786297A782402CA440", + "d": "F05117E932CA0E0C202732DFD4F674BF5848219A76C64A0650C27E2E55095513", + "ek": "FB28C9266161FFA370AF3C5C163A9B187A5D2499115A1120F2B84D71948E00A7969685C8FB6B8185566ECF337E1E20AF4E4A87D1F4BEEB1BBAEA51499960683C45B53057891A288E5A8393C4F19A06C222D4C9AFEE5AA984B6798D45A3F271793E77A5404677B08A1BC5D3CAB9D9A20A4880A11B71B7D4221C1302B8BC24FE65C4C63BC7D1B80D8BB40A7FB535C672BA32496904A9976B328A2002B14E9A071713CBD9B48E55359D451C3EEC47C4A7B9CE61AA5A9516C34009A8085A98725C13949644A72A338DBB7621530858FA1B40D6BE5DA89E9A422A08031CA3C003A0E31AFC4B36D97B4508BA3537DB1B16D1A5B5A98E6BC1CB70696F887940A60498E276C1C900036A30735B20B9762A3517C136A9DC20A8F5CD73BBB047A00DDAC6A6DB40BCAE42C1D6329FF54B9C37F82CBE6214C2A99E31DB80AFDA9BAF06916BD3CF83643D27828130495CA2FC67EA441E38A8032CF0003926901245973EA549EF48A9C65ACDD5E25D5F9834CCA805AEC7CD9F687D5CEB8C2CF04EB6A1356B68AA7AB9CCE7452A20C5344F11BA6197343886A80798098C63AC5AA6095FA2A1D2B0A07195ABB3E98057953AA0B20C00FC06FE553FEDE713DD4662DBDA4C7806B44904411D85C8B9C57912A72A2D25460467CA25027BC74C3066C7A941858EE4D04026914B45354D342B6643A280CAC8C9ED60B9AE021D38303799387D12A98419C26010FB9492262002B0002FDB167FB668B2D8C453987E83F570A43AABDFA5762015B9FC196FFF6542B189395BCB5C4AE598A858597622240E01856B17511C480627B4818C413ED065C68F359266008E888B9EC435A906C6721CF8964885A160C0512FC4B9B454A10E9954048B3212AA9C37A27D2697B1AD530FB33974AB25AAA9F33B85358454610E94410D47F85920F2A7F5D13C74CA4C6108B768A476C5BACB57F17AFADB60D437C21D397A09929B2E97915254A0FAB1848779726D766CE6C83639C4172DD5A1306CCCBB1491D56C1A5FB7CB5FC7836F0765246815F05A2A13385920D0B2C518395AA997E1D33A2AF588B7EAC1DEF4BA688555EC4961596873CD0A0A443551269C73F0B97B6F8CBBDD45BC5A15356BE370FAD74805032940AC0E9C2269C0FAAC67A647FED78E83094D08F58C23745E2BA70366F24A42635A944771C3E13C8EA25B8BD6B8B0783487F1A7A4A15776DAB44EF4192880BAE74C62DBA92A24782CB91237CEDA6E84A0C68244B9CD350DA0A67CA5477EBDFC4D40F59EAE1A88E9043653F5882CF614611641380CBAB15B6CB4189491ACA9D1BC22C56928A7B37E678A4819D48A7D27887F12B4E3878E8318BFFCD93B2B9C4ADA1676BB72B93DE19295DB59909315DB1209E3A02193C1126DC30BF77C6DF59AA4EF921020253FE2045BAE6760C206A7FDDB596EF802B1F3C620D353CDB008AA0A4B8393744E25A34ADAA31D2313B480C29DCC8DB110049DF796DF298CEA91015C9686FF3A300A7298F4B7237A893E02BC373641CA88F2345CCB4A6E7441D30B244814A665F08A18146AB65C3761BC5A87860B2E20482EC89D444180D10337C45C702D82A51DD036B5EAB0FA81B017BA82E16AACDB3A96A53775B9874EE8079CEA7845C3CABE0C847B7B4BAB1FE0680B12986D821968579D963703D90AB8DE020A7CF28DA8395887B2ABA5C09BD7102B8662554D1C472578A9F80CC15F431F18980BA1E26754243102D03D42E69C52AC25EB3A19FCF57FF9E1429E78CF6AE0A501AB3EC26C0D729B142636B873E9B68E277370366C0FE0543E44C08716C4F9B06546B1CB3DD243B505B1A15976B33788E8D1987F810D5797A8E9CBA8B126923A1A81855151780CA9CD4055D9495603A84CD7886BBFBCAFF499066496C967501DF3D861B97C5D250016BD3B3A18946C0CACAC1238CD235A6A609611EAE792E0560B831B636309517AF489A30269E172BBE7470C2D158F83C4B20F15C524025D6CF164200B3870663809A00E6A982835C87F80A68AFC1B5393B006D220A0AA26B9666690549523A0A9711E03B2419914FF76CA69A62671260B34F1C1A11A6E64067908839B87D2940D433162393A6F65B08E4CA643201023C63DD3C3808E9625CFF4C346491E34153937589310437069622208C646AB58584DF10F9930BA2F761DE4C2564BAE2B31A9A645135536FCB58B94489E4D993C9FBD4A89198AD91BE052B5E8FF", + "dk": "A6247A7F4938C4589C972C928D7C65B74634ABE136E1C732A094A539E4892780BF56A5A7CA52AFFAC643B7168B997809AB95C8DD4740954164819C4D94453053634316F3186DCA4A03E813BCF763E6436E05DA840EAC0FB65B11D2D97EA80B156966C5A0DC43799B74F3797D483486E4647C8EA61569880774D68C9EE2A5907910839A95E8E33CB10B2AF59C22128B0C8BA9AA7D0B7A48E26C6E157D58122A63E571B059073AF35AF40282D1C8AC2ED5B15B2C980D6437C27212B5CBCDE888BD8F4B1B3AE398182243468C98F453569C417CF3C043BE9A9BBC03D058212523F0A6A2A263381967A562B63E7C1A83A4BBD1D86226B5083F8B54D93413350B39270C9E784430AD30752ACB0CE0F2B7300B478A3801C1133A84009106DBA42AEC03AE413F137812A35B4CB29207A7FC332BD07064019AE8CA3F6A723191058D88A460D40522FFE0841AD5507B1942434939260228CD993266DA1C35B920012C0E349C224D492DD6D197CE7473FA25187AB87C192A5382FC3DB61C817DF62221666D6D4858F807C852853EB1AA8A7DFB4A79935711698572E12485294DF538257F44AB92A60D5D23AC91F56E138025BE0C93F995BB3A9620ED0A7588857B4F847F996C9D7DF40BEB05C87FF79BCBF222956CCA23F377FC36140FA379CB89365532490D470C3C5B4CB8F3560A7A0C7FF9A19AA0B0E03C100B5090AB42A9C652399FE79716B61921DA7211ECABE486A3E95B3EC0E79A4DB614F5282F2C8087F8A1CCEE9417D4F99C108202C92499DACA10E3AA9B46D254BD8593316B9D220A96496372DEE61B51E93D51E9AAFDE006AC267037044E92A3440A469BE8AB36C3A70B070C43BF889F1DAA6E975CA464F32BBA725D75016B86C8089D9338C9816FDA6220169CBD445C7C78136E9F56A431957068373DD3480F7AF88ECE4941A2FC3BA9C2A474FC1D583A59AA42795365B6C0954F3AD810F55B5B0B959F414137B7C3AC0351812E9B00E8B6BE2953C7AA839F24F02D8CDB356CC64B5A361EEF29A2FE12117D9CCB86D4A399F51CA8D796A29778474838D903830706A854E83BD0267C7CD43B927B83DBB29C63E32FF5ACAF1A2A0C50609F4381C32E78B583808841F6300AC40302CCAB18A945FD0CB510588796C61540FC559800A7A1657736B347C50657E559685A226B19F62B34050FA4D76CCEB3A9BDF5A3815A7F4558AAF108958806C16A264132968DC63CC40342239E7640BD394CF418CC3298B7ABE9CFEFFC1714E96486CC73BA380E5A79900AD19558C68EF1BCC3DADC3E7829BC7BC09F407C6384E51620492E5B643B10B45E3BE52CA851709582C9DE447A501A07026528239054901882F5B74E6DC791AA9397DE9403D5519F1368084EC65D8010390F23C7DF604CAD8092E950901F9860A267578AC5043773616BD1792307AC8626201CE2A4FD5613CD97A074F3476094BDA4EC32A161855A4888223327978A8F74625C74A572C37C027E619C7D5577335B3D61E3B53191517C5A50FE62C63A08B6ED65C054EA98CE22C7464CA2DB3C23724C9868007133A235A36A7C56BA237FB58237F7C61E4A66F7B51A2751CF3706367413AD57A01B687107A513A46ED70025B41B785354BF986D4687369F97759D12551C6BB203A609F28931DDC076E6E38FFD083EF4E99B8C3919DE18BC7601260CE74EB75779FD1C6EDD4C843F770F6504B4C468A80C8C3C37D80902C736A15539406A7BF01206173066D29902348708799C2A7C88B751D62BD2760488357836B4019DA55B4A3050242791EF3C94AAC0A821BB71A90840B7E06F842398CD50282A15718E29BB4B75796AE81C76503629056CAABB2A0A319761C10EAEBA23BCD3033D911ADF754C25EB3923331BA0C332CF357758469D765A2C492565923872FB1322F5E1672E010DFEB7815B940595CB4FB6B64FDE59A63C689BE4B7828458B31BB5103EC4C8F1F905FEEC2AD1D10C7689C5C0528A56E4444C958107868E477662C25071E28404AFA86411910D33B618276A5CE51850F3B67584949F75651180298E3C791ACA85590E6BC59C0C8365DC6D5AE02D34D91B1E6C7BEFCA8C7F042070E32BD4883ED1D15128D516A40235A086A6D385784C457FEEB1C704C426CA4C48155445E414200A7CB6A0B9C0DF343CBBF95C7655B4FB28C9266161FFA370AF3C5C163A9B187A5D2499115A1120F2B84D71948E00A7969685C8FB6B8185566ECF337E1E20AF4E4A87D1F4BEEB1BBAEA51499960683C45B53057891A288E5A8393C4F19A06C222D4C9AFEE5AA984B6798D45A3F271793E77A5404677B08A1BC5D3CAB9D9A20A4880A11B71B7D4221C1302B8BC24FE65C4C63BC7D1B80D8BB40A7FB535C672BA32496904A9976B328A2002B14E9A071713CBD9B48E55359D451C3EEC47C4A7B9CE61AA5A9516C34009A8085A98725C13949644A72A338DBB7621530858FA1B40D6BE5DA89E9A422A08031CA3C003A0E31AFC4B36D97B4508BA3537DB1B16D1A5B5A98E6BC1CB70696F887940A60498E276C1C900036A30735B20B9762A3517C136A9DC20A8F5CD73BBB047A00DDAC6A6DB40BCAE42C1D6329FF54B9C37F82CBE6214C2A99E31DB80AFDA9BAF06916BD3CF83643D27828130495CA2FC67EA441E38A8032CF0003926901245973EA549EF48A9C65ACDD5E25D5F9834CCA805AEC7CD9F687D5CEB8C2CF04EB6A1356B68AA7AB9CCE7452A20C5344F11BA6197343886A80798098C63AC5AA6095FA2A1D2B0A07195ABB3E98057953AA0B20C00FC06FE553FEDE713DD4662DBDA4C7806B44904411D85C8B9C57912A72A2D25460467CA25027BC74C3066C7A941858EE4D04026914B45354D342B6643A280CAC8C9ED60B9AE021D38303799387D12A98419C26010FB9492262002B0002FDB167FB668B2D8C453987E83F570A43AABDFA5762015B9FC196FFF6542B189395BCB5C4AE598A858597622240E01856B17511C480627B4818C413ED065C68F359266008E888B9EC435A906C6721CF8964885A160C0512FC4B9B454A10E9954048B3212AA9C37A27D2697B1AD530FB33974AB25AAA9F33B85358454610E94410D47F85920F2A7F5D13C74CA4C6108B768A476C5BACB57F17AFADB60D437C21D397A09929B2E97915254A0FAB1848779726D766CE6C83639C4172DD5A1306CCCBB1491D56C1A5FB7CB5FC7836F0765246815F05A2A13385920D0B2C518395AA997E1D33A2AF588B7EAC1DEF4BA688555EC4961596873CD0A0A443551269C73F0B97B6F8CBBDD45BC5A15356BE370FAD74805032940AC0E9C2269C0FAAC67A647FED78E83094D08F58C23745E2BA70366F24A42635A944771C3E13C8EA25B8BD6B8B0783487F1A7A4A15776DAB44EF4192880BAE74C62DBA92A24782CB91237CEDA6E84A0C68244B9CD350DA0A67CA5477EBDFC4D40F59EAE1A88E9043653F5882CF614611641380CBAB15B6CB4189491ACA9D1BC22C56928A7B37E678A4819D48A7D27887F12B4E3878E8318BFFCD93B2B9C4ADA1676BB72B93DE19295DB59909315DB1209E3A02193C1126DC30BF77C6DF59AA4EF921020253FE2045BAE6760C206A7FDDB596EF802B1F3C620D353CDB008AA0A4B8393744E25A34ADAA31D2313B480C29DCC8DB110049DF796DF298CEA91015C9686FF3A300A7298F4B7237A893E02BC373641CA88F2345CCB4A6E7441D30B244814A665F08A18146AB65C3761BC5A87860B2E20482EC89D444180D10337C45C702D82A51DD036B5EAB0FA81B017BA82E16AACDB3A96A53775B9874EE8079CEA7845C3CABE0C847B7B4BAB1FE0680B12986D821968579D963703D90AB8DE020A7CF28DA8395887B2ABA5C09BD7102B8662554D1C472578A9F80CC15F431F18980BA1E26754243102D03D42E69C52AC25EB3A19FCF57FF9E1429E78CF6AE0A501AB3EC26C0D729B142636B873E9B68E277370366C0FE0543E44C08716C4F9B06546B1CB3DD243B505B1A15976B33788E8D1987F810D5797A8E9CBA8B126923A1A81855151780CA9CD4055D9495603A84CD7886BBFBCAFF499066496C967501DF3D861B97C5D250016BD3B3A18946C0CACAC1238CD235A6A609611EAE792E0560B831B636309517AF489A30269E172BBE7470C2D158F83C4B20F15C524025D6CF164200B3870663809A00E6A982835C87F80A68AFC1B5393B006D220A0AA26B9666690549523A0A9711E03B2419914FF76CA69A62671260B34F1C1A11A6E64067908839B87D2940D433162393A6F65B08E4CA643201023C63DD3C3808E9625CFF4C346491E34153937589310437069622208C646AB58584DF10F9930BA2F761DE4C2564BAE2B31A9A645135536FCB58B94489E4D993C9FBD4A89198AD91BE052B5E8FFF2F75EA69691E4E53E952F98536718602B96B7E5A2FB218648F9353EA65FEABCDDD4871080BD4F761D972085851DE0A0408A2F5EEC3CD3786297A782402CA440" + }, + { + "tcId": 67, + "deferred": false, + "z": "FA29BDC28D989B8C4BE84706A3CF21B36A1C6E355C88A361C7664818E4BC8E03", + "d": "A405D9B07C5771A5BBDA2BE9F8A40D9566CAD7DA1761ED8076A289063DB4A8E2", + "ek": "DD0C664328C53E5B29F9A9CC55D97BA265A18C02AB73427307E78AC23C51A56478CAA21DB400A3AB081A0532729C40BE3FF9ACA2DA1799E29BB2A8325F1A9E7BB99D44F3C27427816B3BBAC0FB3DB6B23B7323A8CF4587D505B1D1FA9D71696064CB6A7D806872D68040714D94162658780295FC056B269D4F16AA4D98A5245C7B33462129130425712798C879079217CC3195E5CA67D137865181B6C2F92EAD04945E97720DE0CF7531BC46847D68E3C13840B94DB2242A048F0F22331050950B8A4B3FAB51A487134A2C9A95FB659342867D252FAF091D1D966836F1CE964428C63CA3950BBCC3D8A800191FF628680D23A8EBF6BE727225E4B91602E46949889D910CC46D6418411B394AF072FF49B894A1586AC7C1823BB89AD2997C726C3FBC65609CC37656BEC80A6B10336A346412FE34075DA69D829B8B937A87F76968BC93BF5D5639AD76448E084DD0D02AF4A7028D7C0892A9728CF1114622494D8B28D05065E6DA0813043504293A17D29273572E34A14816A01F5DF58BDF44AA1AE8CD0C6C6622CBBC07540405D5AAE8C77BB3418A91B982BAAB4F8B388224EC3E345764D9E66C2AFAA27B924A07039720D7B73084098457C488137B75339F1D7A6919A29FCAF71F4DB8A17AF6161488C02813191AA2B98FA51A6FA07BE8F288C51B538292683A4C52C7F7B2863C52C0843452B583CB583B98414B4CF97185082768855206871CC76A0A409802E0DC23036B3586D9991D241FDCE67D4986CECED74EA7E77BCC479EE4768952E0297568528AA1712468B267D474D069CAF9CB11E5B0CD23DA09D5095349E3614194B1C63596E7E65BEB6769516B7B0759C8FEA02C7AAA1466A7B41C759135965ACE8857074B95DD6A5ED9D36FDABB83341A841DB163C1332881322F5D2374EE11ACB0616A6B1CCD9AC7CA6673619BCCABAAE562D4C433147A2802C26B6431BDD73A455CF8CC242174AB5123BF9C26F8280E5755A4BDFC1A98CBBB92C152FD11655EE4459ADB2F163928EAF24ED09C72839145C96179D8C94E6B3227AC793F5FD990DD638ED150020934894684A38BB1AA859A3AAFC49EC5A53B8646CF60F5585F043CD71B13F9BA41DB563677B04EC6D8270FB55C78F8A58ED494D9348B4A774930C00752121081514596D5B86FC0CEFEFB4AFD2682EE056BEBCC0CC9446CC3C1A0F5F34DCCE8AFF0949FF16005D121275A5915C6D4B9407357AFFAA09CF6783ABB260FD53A333879433B45FF25B9D71A500BE315D2635DD4F42B47881803666441871083859D266B96C1327F96B40454D17ED5363A27CB612A69064B268DA9185B4506119D7A71FA1386AF6BA9789AC06E9A0F04DA5C6CF478F18044457418E0FC986681B81BE1A7AC1583AE95155DB64FDCF442E5EB39515B06DB280A23AA5DE2C19A1051A4F9404F712955ADD66A9D1A7E963BAE57BA75190B7447B70EC0170EC0C2CEF480132B375D3991B90B729F9A4356F062C00D030BF8AC4A82032D5F42B7D47B6009B274C4D2A5DD5553D29AC86F148ADE931A81534226EAAD33612AE89BAAB7729F3855339625742AEBAC2B042AF2F5B4F3A017A74342501C274832B314BCCAADF59DC52A0ADFC061F2256875D960CB654CD78BC46C709B2B9133F8801CD6766800E12516D80CA41011D68733901AC540533E0CE532CC82AEDB5CA0DAB476CC5A81188B54E0AC9FE66A1D977A6631519810128F98C3044BAA5991920C381BCF3D63B785701421733FA25C521DC10BA007040B917E55B863F95A1A3E924D3FD0AD3975662D38476BD3B47E46769820C3BF4705DF9A89DAA53A58AA77B65258A444B2002B681031BA765659D9C18D92D826733BB575705D6D7C7DE3D19240339AB4B12BBAD51ECF8638E6456E5CB350FD551E5A5C67DF050DC7E7866F4A10989C40BD3C22FE480343E07DB22734CE89870B6804273447A85169A170BC53B861B9545CC186501E8A541575A480562E5D7198B4D905B8EA51A48688A8E488A2A36F7EB15AAA398E6BF44B69622A14B3473B0AC09401223CE775761B8931D53D25E0AD51426970403B0A243E9307502574B1D6323C11F7CB5D855ADE147211438AA7FAB0DF89CEE8286618D8181DE196A311390BF171EDA88DAF1C0FBF540EF20504209482BF3B7D023100D8795634BC28CCE86A4131048041A23549B016EF00A31156458CC5808590AD8FD2EF59DFCC0C", + "dk": "73831E2C2993800A26266635B586921217B9AF812D5656B9CADA071A384F69D48A210660F51C4AE1F2A6F2E18AC7FC2AF9901318A56E36A483662579736943B7855BCD664BC7441FDEC83DAD5C54187A2FEE338DC9A4AA55780F07F3A94ACA4DAF9145FB099F05648DAC3C19EF450EFF4633500B9205424C2BC4081A017D52BC3302B28BC53668185B147B117C9A7C427249037CC165134B6A9A4663CB13AB0DA3B501C67866201485C5645D4006F929AA4A68831038961B61C950110106CC98C03287D291B080A7212BB4A7AF92AB3A2A06EE19200A531040949C5D57B2D8B09D637638B3690C4F1457A1E9A5BAF903DEEB894300984B76A03F0116D570CDE59981F10A2DD8590EC91765ADF252183C10FBA093004D5700715215427F2FC85D700747C8029B9CAC9A1A4AB8E0641D124540DCC3C1DDD62DBFC89D884C7DA2E515CA87A92DC99B1BA97B0596153EB53D4B8818D2644F638545D94258F5441D5C940A7CDBB3B3E66D3A886457316B15808F0AD71421C34266073B1500CE5279315A00A17FACAA04660A556266C3F44275C67B49793CC0679DE3B29BDAE8C9B15458AFB9B2395547C3DA2FA6010A8171001A50863376C172E64F51F87354C99465796789A854F8362C78588DCFCC98250C4524E51A401203E5D4680C5261CA3440C3077CCC6AAC3E809315781C9081629C4199D925679F02B70A200B3F8C98A3E0B1D3B0CF15442E55A76EF25C0B3734993510B7465C0081B82BA8136C7251C40EFAA6E0819046D1CBAE353A9C8547B9E160DFBCCE85627E2B16C0E5A51DBB50565B3A81DCD27FC9698BB742356CCA03CBA3678028534FD0B1B3C852F734ABE2452BC583A103C3C09445396F1A01F3FCCD951299509B2EE2A7468F15B927B0B2D435B56AC12C548C8107EA5D58682B481A568DB4A4B1209E9E36B879D31876F708A039A39DF58A0F0A2C04A19622C359FD395C99B3C5F497304CC11F5FAAB83842B7DF06344657243968156AC67E7938900D636BFB1C4224F677E6D119827ACBE0BA6E32C590AAFB140A041714B5BD3E06A2D7851BF91098C1647133118CC747AF18B8ADCF01C530C91E805966427A3EC4234272BB9D38A8908285C46EB759F176AE6B7395010878089A21C3FB5132AA789B92C7724C8217E9A5E66923552C4514A915C0B43499F8192324A50BE4679C586A646CB0B9808659792984726EE2420B5FB102B96A3D7898B7C98900913237D5D8885B9580556549C1B59CB4F4ACDB481D92A8CC5D447282F5C7BBA6BD0C7CA0D8EA2D3BDA78633C8FEA1561DE37AE94D51C24414F9178C224A92E79138FCD0337BF00121A51BCF5D27177B0CAD3A6665EB77033B10A00037B908062D381AE5C84C711D4B5CA9888180A0FA742B506D86C03A0C54CA488FA404BC0493C47D531D420360DEAB873C000A87340A2915073429C001A088B212EE46A80852C3B839561CFE5A336557EB689BDD3CB75C70C6FE279AB134A6ED3B20A03750C1CC30BB1D15FCFB37105B34F34026B660905D640BF06D097F0C06BB7E6C628BBBA9386CE6AC212A3370AC4FA65C64C5B235BAF13011E7928B896D78754335E2EF90AC5DB53DF83BFC6340D85D444D469C3B9A329567243E1A2B900A76C756C46E26C6936A0C772F88AA38C03D2137E2BA4179D228F04229F5AF755B3C7128AA16BFFB9354395B575D81EA4F266407A206C0CAF14D5151CC15C178B7D567B8C7DB637FB26A62C048CE9049710B07AD28B6168756234539952282D521313AFA65959432E7235C9991487AAE661B6B7108D48C9E4760D6315C14C1725CCF69CE69C2E407799DB8507A0C66CBE15BC65E4692CD5910B5975A3E3416204949C601F55A438B104026D36A71B5B1399BA6DED58166F210847D863D302AB4C915E969317D806643BB85912B9A0C07AC80FFB588ED86B359840D8B58EEAA0494266A11ACC201C6130DCD523A2C5CE2262A243665AAA45BA30D2CB06D4850CF65CBBFC772E0C20F9F652AB92950F0A3B33F448D6C014F5548A241B53B2C348E494C883409B99B257367BAC0CD42037921F8298647D91C06FB1589A17C1D0A99458938570C871B7C865C98734E1A88C4C112294913F3F0A35E8A26B17F85AFE567780B919C0D94C6ABC5D6EF1C4318A6EF21A1F8FA75653F612DD0C664328C53E5B29F9A9CC55D97BA265A18C02AB73427307E78AC23C51A56478CAA21DB400A3AB081A0532729C40BE3FF9ACA2DA1799E29BB2A8325F1A9E7BB99D44F3C27427816B3BBAC0FB3DB6B23B7323A8CF4587D505B1D1FA9D71696064CB6A7D806872D68040714D94162658780295FC056B269D4F16AA4D98A5245C7B33462129130425712798C879079217CC3195E5CA67D137865181B6C2F92EAD04945E97720DE0CF7531BC46847D68E3C13840B94DB2242A048F0F22331050950B8A4B3FAB51A487134A2C9A95FB659342867D252FAF091D1D966836F1CE964428C63CA3950BBCC3D8A800191FF628680D23A8EBF6BE727225E4B91602E46949889D910CC46D6418411B394AF072FF49B894A1586AC7C1823BB89AD2997C726C3FBC65609CC37656BEC80A6B10336A346412FE34075DA69D829B8B937A87F76968BC93BF5D5639AD76448E084DD0D02AF4A7028D7C0892A9728CF1114622494D8B28D05065E6DA0813043504293A17D29273572E34A14816A01F5DF58BDF44AA1AE8CD0C6C6622CBBC07540405D5AAE8C77BB3418A91B982BAAB4F8B388224EC3E345764D9E66C2AFAA27B924A07039720D7B73084098457C488137B75339F1D7A6919A29FCAF71F4DB8A17AF6161488C02813191AA2B98FA51A6FA07BE8F288C51B538292683A4C52C7F7B2863C52C0843452B583CB583B98414B4CF97185082768855206871CC76A0A409802E0DC23036B3586D9991D241FDCE67D4986CECED74EA7E77BCC479EE4768952E0297568528AA1712468B267D474D069CAF9CB11E5B0CD23DA09D5095349E3614194B1C63596E7E65BEB6769516B7B0759C8FEA02C7AAA1466A7B41C759135965ACE8857074B95DD6A5ED9D36FDABB83341A841DB163C1332881322F5D2374EE11ACB0616A6B1CCD9AC7CA6673619BCCABAAE562D4C433147A2802C26B6431BDD73A455CF8CC242174AB5123BF9C26F8280E5755A4BDFC1A98CBBB92C152FD11655EE4459ADB2F163928EAF24ED09C72839145C96179D8C94E6B3227AC793F5FD990DD638ED150020934894684A38BB1AA859A3AAFC49EC5A53B8646CF60F5585F043CD71B13F9BA41DB563677B04EC6D8270FB55C78F8A58ED494D9348B4A774930C00752121081514596D5B86FC0CEFEFB4AFD2682EE056BEBCC0CC9446CC3C1A0F5F34DCCE8AFF0949FF16005D121275A5915C6D4B9407357AFFAA09CF6783ABB260FD53A333879433B45FF25B9D71A500BE315D2635DD4F42B47881803666441871083859D266B96C1327F96B40454D17ED5363A27CB612A69064B268DA9185B4506119D7A71FA1386AF6BA9789AC06E9A0F04DA5C6CF478F18044457418E0FC986681B81BE1A7AC1583AE95155DB64FDCF442E5EB39515B06DB280A23AA5DE2C19A1051A4F9404F712955ADD66A9D1A7E963BAE57BA75190B7447B70EC0170EC0C2CEF480132B375D3991B90B729F9A4356F062C00D030BF8AC4A82032D5F42B7D47B6009B274C4D2A5DD5553D29AC86F148ADE931A81534226EAAD33612AE89BAAB7729F3855339625742AEBAC2B042AF2F5B4F3A017A74342501C274832B314BCCAADF59DC52A0ADFC061F2256875D960CB654CD78BC46C709B2B9133F8801CD6766800E12516D80CA41011D68733901AC540533E0CE532CC82AEDB5CA0DAB476CC5A81188B54E0AC9FE66A1D977A6631519810128F98C3044BAA5991920C381BCF3D63B785701421733FA25C521DC10BA007040B917E55B863F95A1A3E924D3FD0AD3975662D38476BD3B47E46769820C3BF4705DF9A89DAA53A58AA77B65258A444B2002B681031BA765659D9C18D92D826733BB575705D6D7C7DE3D19240339AB4B12BBAD51ECF8638E6456E5CB350FD551E5A5C67DF050DC7E7866F4A10989C40BD3C22FE480343E07DB22734CE89870B6804273447A85169A170BC53B861B9545CC186501E8A541575A480562E5D7198B4D905B8EA51A48688A8E488A2A36F7EB15AAA398E6BF44B69622A14B3473B0AC09401223CE775761B8931D53D25E0AD51426970403B0A243E9307502574B1D6323C11F7CB5D855ADE147211438AA7FAB0DF89CEE8286618D8181DE196A311390BF171EDA88DAF1C0FBF540EF20504209482BF3B7D023100D8795634BC28CCE86A4131048041A23549B016EF00A31156458CC5808590AD8FD2EF59DFCC0C3D74CF5CC0859F5089855A7EA2267CDBE04185599344C8E93EFCB5B3DC588FC6FA29BDC28D989B8C4BE84706A3CF21B36A1C6E355C88A361C7664818E4BC8E03" + }, + { + "tcId": 68, + "deferred": false, + "z": "08FED872D91297D8059743D3E7B6EE47548357E7F882B5BFE2F04314187ED424", + "d": "E66F17317C40783CE0594CFB5920FF86062591C5EA4254021495749642C0D968", + "ek": "E067AADA829618E4C683C404EA51ADB1A7A116C7A0AAEB995AF1BAB8D0751FBA714957AD6C7A0A9C73ACB8D347F9A9A469D85DD94B1B1E4AB74C94048F9AB578A2BDFCC75A213A65345129F78B26E3D901B3428A0F87952B91517460930386856AE25D00259D58EBBB403621335791EC6C2C6EC50711C07F56714B0ED3753F7459F07B83D1F838CA1875017B24FDC2CA6224B74423842ACC5C4B03D0658C7EED5A713A365CF523C9C2254E9C79059331BD730B123F53538955BC0FBA92FF9388192C950BC46C25339C82E98314D616B50993BB6241224AAE7EEB610EDAACC43ACD775941FD8088E03931F40C999D92360B74B86B857CFC6B5A74367DC72033941C78484031FFF53874308D52AA6FFA3491E0CB98366B8FF2866ACD1AC64B63770BC25BC33531175A4112D7684C01A8C4500F9FC083FE652FF78910B75093A34CADA85947D2602FF0716624FC9617EC71B9E87CACAB31CB3836A022523C3A3BF9F542EC306C22EB815E1038A48CC4F6596A1CB1482C7BADD7390D8DFB1FA01C5C30E458AD31BC5FA717503C0186F5A3B936C2D0AA7197733C2EB708F32B9FF611537773BC38B904CECB5D2BE29C988B22E415C7944726EDE09ACB76175448712F4BB8AE5AAF4498CF4189B0F0332FE774170F343A121071961CA130694B964033BC015F490B85DEA4A81756A95F3526A856327CA68F66E828A66B138C052115C0B6EB910BA703581617299855318BA9AFE6B152CC538836278D781771FA4C033A65AC5630B3EBA8B02A69717FFA1E73E77AFE06441D91CD45289927C40A1425AF113B179CC46C6606CA0EEB0D86765128A726AD50AE8DDC1AED2A07129ABBB3AA67B4E0192DA99D2C36686D3807E0B50CC9E30A82D97B0895B6C7670C01FC214DA38FFC54970D8399EDE259900A081954172F385E037C9B72B43A3ECC7FDB0510F6A930B837618ED756A62A0B3CF58B980C94210BCE63FB9CE88745FE8BC34D57248979398CB0C1C9B83AC979A107C955E97543756221AFF06C553A1F0E764AF19B93E0DCBBB9C327F76AB4BB890D179C90839430A749A2C43A66DC36394FF06DDC54070A2A2F152261E79597AC9B2AD32A39FA489382718E04DA6369C4AA0D4823BE87A60561CF49232C8AA20811EC7B29EC8A90A363F3B367CF9A81A08645C70A17EA41A1AC4C0E9407763D2A91B6732E46C6BA160972ED35CBE6000B7C1B83CA21623859CFB4317306593003B2A90BE01FB5A4030CC062C308C14924CA47A24FA5D13B82FA7153988DCD1077E2759FF250C198ECC4C860170E93BCC48CB009CA7535C62EE2A3AE61D07C828C68D19A55F6A7224F716E77A381E06933AC03A1B0D01B6D231E38D4A19EC9C6E8DCA42C218B290130BCB583F7E958FC3531037716B356948D726E602329A322A410945568BCACBAB75D65DCBB38B80CD20865563699838659E065CE749A6DF66542E8474BD140B50EBB5983F546FB393A0BF10C5891767B935E0F5171CC97A00607332088AED99B13EEF557CEF73429704244FA2B915CC7731BB9BD351FA131A726C837FE19047443A16BEBB02F4A5020878AFCDC72CB780485A793CE23BC6DBC11E04B0DBDA82F51B4327814471C01042A1119D5513408C119266A0476DB89B20B18EBB44A231CC5BC39C6BCFC4DD2A61EF9180BD76327AB05A37ECC4B2E8ABAAA307A6C58040484BF73B06AB4A65F7FD99660A759FA903A56DA3E8DEC389262AFF8BABE1B85168BD21762C86046290F35D51E4BCB8403F160D9DC4E00CA8987E46CE05A5FB04A112EC352B1B03219A4B50345C6F31915FEF4C2EF870D30A244EA4C20D82849628CB61ED677AC9890CB5463EB90BCCFEBAD9FAB23C26A33E6667D76C96220147685EAA84CCC3140104AAA4A559E51209DB124337A2795925C5E0230E7920D4E9338DA23ACCC8693D5952CF49AC26A74CAA6E05011E6385F787A7071CA08C61F59CA017ACBC15E9BAEB78837B99B93908A8CD6D7BD30CB6C23F9CE5E15204E0225B55C120B31C1276695C909C94AA1B5D0C0496278435352B50343A9974A55EAB5105FB4436570181F2B7AE82238CFB9C967F424C1D146BCF74A2349583D36C1F7629E70E0C4702C133F7475985B2DCD923465F39772E8AB76F3634C6A1F6E8088BBB0BD3A050CBF323F9EB76BBC4603617908BE85E6EA5E40A862180D9EF1380B7A859947562EF3A845669146", + "dk": "DDA5A4C182BC2917C5AEEB973FE853A397753BF576B753AD82583E6EF89CDE2B7B9B6B6FC65A349F66BCF4903902D22418E123BE13A3E6A29489362308452991448E53370B9F1315A83540D14A0CB60B9C80549556CB6F839B6062365693CA9665A01CD66574242092954B945D996ADDAA51F106A454002491FC0881D0489722979D90CEFD5235B9A1852D334B6ECB7CB3294C5B50A951E835DCFB24EF9BC124601567C0C05E1C194753CAB73A73E114C91C0341C7DCA0C904217F6BA200752FBD0B74E5503D141C17338AC6B6110E78F5592ED1B599B3A8FE65292779A473D95B3A1860DE955ABBC99349D0A4F85C97A32A154C89AF603799A438890E692370030AF4B69A3AFC91ED283EF4290524CC88E6E67D9CD00790F8B3E8626F528AC4A236570218B1710B82A86A308B4C4068E07422643BB8031E0D556700123F8F948463291257280CFCE2749812AC26A31C145667E9E94FEAE011C037C00E268F617ABC5DE656A8F8C858CA0A392201E144B9101BCD29401C98992E7F4ABDD02705E0F0AAE6D2BF2BF9081813CB1CF78454535146FAA994C666E628A4E1FB15CA5663551962380727A5933F91495B4EF290DE64A1D6D35CFD4A5279EC0460622C2E1B8409619D31144E674B4AE08951B25416F2839AFC4095D7257F34D54D3742997B77893C1C009C55A715D13BAC3092B9911F1BD962645C1A0A91639207BB98E15A37B570E39AA15011280E8B64B2E674CEC8931D26587D003CFC89498C997982AA60FCD8A3ECE93D784B0F9E7C10A6C380B76C1D6E91ACFD4672D4D9485B9C857B92C283B596D714A404444478117FECA0C14B641A0DD1B027DB7BF832316F0BBC256324BD4345C0A7CF3B98B2E6D01B1A9644F29010CEA70BBA08BE6877BFB1570CDC464A049C90C2B28C0A329904C1CFE6C92F076098C300288397CA65581A3BB8BA7D92A3D22C24E8691CFC610C9D3409B73CC2CE78A1C7E5AD07720CC30C984F73272CE4B43541AABF616714400D6D040609286AF1330F342A71BD3276454B3C33B5508817644DF14C42E93199E27FAD15309FD93BC8F88DB9078350797BE9CC027F03A7A18965682C83DDF182C411CB20EC3EF5C435973714255CC8CEE376654CB1AA6554BAB32F7E7587DEA22EB3C2565E760F503B6F103A54B2191FF3EB6E30126B951091B010BCB60C0A8A1C3FC958BC4DE5504A3C50BB6A2A5726B6B8E25024DBB7C02BCB2FE31D7CC581E42185FFA6503BD0A0D1C907FD13302EC37D191C141CCC0BF4D7A371A8C3389C5A799663709949B17195B4EC74B2DA225002CFB13668F83A1092A6C609522C07529BEA7A454EEAB74E15246AA17452451672A6314E5AA5AE0C57C2AB74653005A8F2B122859C0E8A0829CB0240BC0B5213AC9B035E9366BD3A4BC680D3CC45D96EDD33AFA02C747132001C0CA4FEAA29059AB0C1ACB1979B93C087B53911897B928422D0732E134DA0186794B4CD2E242C0EBBB5A7E10A82C44F874B749ADA0F91C6A26290B1CC49B7BFA150EE40886C9ACC8DCA75F813B13E732E94F85F6908C0523CA70C71A5BD394673D22E4648A443B25DB6DA4EB11C50A8AB30CB342A39B130AAD1A421B567601001B86ABA44A1311F05423A939B3F3404E5657476819D9E406FC265935542B48AF47FA78482C4443697358E784BB72B54B373E813E19186D5BA8997053189B314B5BB8DB699059CEC5FC2D58191B2A729D4A3BCA3AA7B377464939CC8E548A7789E56F67D08C1A0772C9836102321F659FF7B088E9968661609003DB687A295FB2BC6AA593DE4C9CFD6C55D2395ABAB916D3A8559451A6BEA299519654E8C8CBB56E455A85C37CA5A74FBF25252812F16B1B9CCA649718C00DDA596C506BB525159659C272FC1C7B5EC8272DA85D506959B231D1394A71D2C421E743964A58F38D52A60407FB8605961A63FA394431D35641991CB17DA5637732A5ABB2F34B81B7384974030ACD43886021A50B70924606BA1A295A489842FE3D10E92FB1507E240AE0B5616F8AA05299C94301E29A638A742028F9321F3955C61A59C021168FAEB17829025071B4015FA167FB6220DE0B29AA3BE2E88A171E32C9499B9B00BB867DB0C9915384F0A49BF3C5CFE539D22D3B998315CB8D09191634C248495C1977837A7B76C9B35E067AADA829618E4C683C404EA51ADB1A7A116C7A0AAEB995AF1BAB8D0751FBA714957AD6C7A0A9C73ACB8D347F9A9A469D85DD94B1B1E4AB74C94048F9AB578A2BDFCC75A213A65345129F78B26E3D901B3428A0F87952B91517460930386856AE25D00259D58EBBB403621335791EC6C2C6EC50711C07F56714B0ED3753F7459F07B83D1F838CA1875017B24FDC2CA6224B74423842ACC5C4B03D0658C7EED5A713A365CF523C9C2254E9C79059331BD730B123F53538955BC0FBA92FF9388192C950BC46C25339C82E98314D616B50993BB6241224AAE7EEB610EDAACC43ACD775941FD8088E03931F40C999D92360B74B86B857CFC6B5A74367DC72033941C78484031FFF53874308D52AA6FFA3491E0CB98366B8FF2866ACD1AC64B63770BC25BC33531175A4112D7684C01A8C4500F9FC083FE652FF78910B75093A34CADA85947D2602FF0716624FC9617EC71B9E87CACAB31CB3836A022523C3A3BF9F542EC306C22EB815E1038A48CC4F6596A1CB1482C7BADD7390D8DFB1FA01C5C30E458AD31BC5FA717503C0186F5A3B936C2D0AA7197733C2EB708F32B9FF611537773BC38B904CECB5D2BE29C988B22E415C7944726EDE09ACB76175448712F4BB8AE5AAF4498CF4189B0F0332FE774170F343A121071961CA130694B964033BC015F490B85DEA4A81756A95F3526A856327CA68F66E828A66B138C052115C0B6EB910BA703581617299855318BA9AFE6B152CC538836278D781771FA4C033A65AC5630B3EBA8B02A69717FFA1E73E77AFE06441D91CD45289927C40A1425AF113B179CC46C6606CA0EEB0D86765128A726AD50AE8DDC1AED2A07129ABBB3AA67B4E0192DA99D2C36686D3807E0B50CC9E30A82D97B0895B6C7670C01FC214DA38FFC54970D8399EDE259900A081954172F385E037C9B72B43A3ECC7FDB0510F6A930B837618ED756A62A0B3CF58B980C94210BCE63FB9CE88745FE8BC34D57248979398CB0C1C9B83AC979A107C955E97543756221AFF06C553A1F0E764AF19B93E0DCBBB9C327F76AB4BB890D179C90839430A749A2C43A66DC36394FF06DDC54070A2A2F152261E79597AC9B2AD32A39FA489382718E04DA6369C4AA0D4823BE87A60561CF49232C8AA20811EC7B29EC8A90A363F3B367CF9A81A08645C70A17EA41A1AC4C0E9407763D2A91B6732E46C6BA160972ED35CBE6000B7C1B83CA21623859CFB4317306593003B2A90BE01FB5A4030CC062C308C14924CA47A24FA5D13B82FA7153988DCD1077E2759FF250C198ECC4C860170E93BCC48CB009CA7535C62EE2A3AE61D07C828C68D19A55F6A7224F716E77A381E06933AC03A1B0D01B6D231E38D4A19EC9C6E8DCA42C218B290130BCB583F7E958FC3531037716B356948D726E602329A322A410945568BCACBAB75D65DCBB38B80CD20865563699838659E065CE749A6DF66542E8474BD140B50EBB5983F546FB393A0BF10C5891767B935E0F5171CC97A00607332088AED99B13EEF557CEF73429704244FA2B915CC7731BB9BD351FA131A726C837FE19047443A16BEBB02F4A5020878AFCDC72CB780485A793CE23BC6DBC11E04B0DBDA82F51B4327814471C01042A1119D5513408C119266A0476DB89B20B18EBB44A231CC5BC39C6BCFC4DD2A61EF9180BD76327AB05A37ECC4B2E8ABAAA307A6C58040484BF73B06AB4A65F7FD99660A759FA903A56DA3E8DEC389262AFF8BABE1B85168BD21762C86046290F35D51E4BCB8403F160D9DC4E00CA8987E46CE05A5FB04A112EC352B1B03219A4B50345C6F31915FEF4C2EF870D30A244EA4C20D82849628CB61ED677AC9890CB5463EB90BCCFEBAD9FAB23C26A33E6667D76C96220147685EAA84CCC3140104AAA4A559E51209DB124337A2795925C5E0230E7920D4E9338DA23ACCC8693D5952CF49AC26A74CAA6E05011E6385F787A7071CA08C61F59CA017ACBC15E9BAEB78837B99B93908A8CD6D7BD30CB6C23F9CE5E15204E0225B55C120B31C1276695C909C94AA1B5D0C0496278435352B50343A9974A55EAB5105FB4436570181F2B7AE82238CFB9C967F424C1D146BCF74A2349583D36C1F7629E70E0C4702C133F7475985B2DCD923465F39772E8AB76F3634C6A1F6E8088BBB0BD3A050CBF323F9EB76BBC4603617908BE85E6EA5E40A862180D9EF1380B7A859947562EF3A845669146A128CDD9B684F4A0907E80ABE2B7584BE10833A4DAF89DE5DCCAB7C001116B5208FED872D91297D8059743D3E7B6EE47548357E7F882B5BFE2F04314187ED424" + }, + { + "tcId": 69, + "deferred": false, + "z": "EB8EA5E8C5EABACCFF162556DA53F0C02F72EE7A7DEA8E9EB70FC51C777645E6", + "d": "F8CF49DA62AA762EC020F3766237520E7FDA4CA3AC11FBE50E6C5F9CAB3CA7B8", + "ek": "36FC681397CD63113EF7756444A3CD1FB693BEA7905A507CABA24AEEFC637104C90D311BCAEBCEDB1335AB26C82F255984118B17E28F2266C5D73818D5ECAC6DA8380189196C9568EC949DDF76694A4B39145758FE66A14301CD64A10CCFE46C3CA8419EE5766160465154680F8C435DC523F5136065555F503883165A525568878EEB4DC675445F300F50A1C42EFBB5F1C9A0A46684414CB4C8187255A2CBAD4321082698F2714F234678D4418E33A70CFD76313EDBADA57C82C65801C0DB89D4F7BE19857E31E16ADAE95F95CA0473082F7FAA0855723B5AE4186A6C26D482905C00689D1737CBA52583893995065B5C76C7FC7839CDFA9BACF1B8F7A68307B459CA96BD7091A06A83AE3F3146FA81296932291B2158E9B09EFADA0A2D5AA8F1DB2489E40E04B0C768335595960CCD586B78844F0E940F2007B3B9EB9747254D83C58443C2B7A347B86FAB1ED4354DA2D9669AA21DC2A938E0FBBA0EB57E4CCA4C2666B79559B70F9B61DA060E03C59850AB2D129064F8D6ADFDCB7C457235CEE9473B003DDC9252AED7C444644832A4AF310C431AB26292488C73C38BC03550F7569909417041E2924AC9338ED8251BF6CD18F2B9D1569FC688AD095A728C574AB8EC549AAC0ED13A6EEF5AB87EE622034CB87045997A6657AED6439AF8951946ABC47BB9BBB55A80C92F40E126D78B4353538B6995830044B6E7220030861E47A5CF0291BDCEF8ACECA5C9FB0B43901CB6CE99246D2A2CFBEA014F902046836CB0B58A6DCB79CB9275519A3295C134289880A0D6CEB91356428294AB0B11CA150B9E362872BC8C25E2A78748C9D245C2D36A05F9D87CB5D0C306A5C0DA74AEF98BB1DC45801B4B9EC5B73A0ABA407B0AB8065B23B8345A6147A258326450E399BFEB86E754561F09CEFD1C832E355939175A347303E0D7815C4056F862B08F7914051834423972C84010CAD31B34321066396D47D5C9A77B9F45111B93988C0692039B5A060805AE4365AF1F8B138CC83F2D681F740886C7F07CD153989DEA4A6B2A3597374F7D5BA8E7D01424BCB721071A59FAA49F74AEF15910E84CC138F09F31574DF9A7000175C80073A10CBA6ECFCB84FA680131B824241BB96FF17BF76C0243A03DE9D49895D640E841A07C2299A7C52E22D37C8EE1AF81847781BB2F25240CF91851A5634AE285825C8809C716B6DB795361CC374B87BF34687E18EB413D21ADCEA883D4837CE874693159BDD2920405FBBBE6674F19D0B3C3D6B6F4095A946A5F7E6B0C5B7252A8F72EA357BAEB475FEA0141621A607324B4B17AA13FB7AF2ED529E1728F4BFC083198628DE3C8968A9A92C8863E08AB34A00EFDC73EEE7A8F29F4906E848B8F56474DB2BDE054A660966C955418E8D387CEF43CCA3B5DFD949E91AA5D75C50C38C96BCFEA7740147FDCD8406C0536325A1B74576392EC1BB1B181D584AFD841B43B0034ACAC33416C8DA02777E1169AD4045CD51674342C468874B16B12CB13776E6E8C702D84C5D13933EC161EC10B82A9F339AB3B1D1A9519F342506A3C0E7DB20ED3D7029CE444C5FB4FDB88525AF4C565DAAED6A51B7776246CA880D0F72D5A40B88FF348E9677B37D19F0088997F77429EDBB63840070D71A60FB34FA5CB59F47B06BB03C3AEE80F393A9DE283604635411151222C696FA6401783431E9690BB8958135537332EFA805ABB5D69C9C8F9084EC38862A68082266CA6A0C3514A71727AB519C359CDBC663066FAC14600132D1216BE63AEC0CA96804096D22904F4194D87D35C6C2C0D5539C93BB909A5287C64DCC1246A48CD9CCD80311089CA694120ABFD5A7F16D06A0BE42C48878BE76253198A703080A463053D43867B73B67B26B99A551A3C0C41115D007E0EA0AEF1446FF88BA7FDD32261FC0776FC427C121B2D231E3AC843015B12583777CCD5AAC502A7FFF9B03FB614246848742342C2E0A871E1AD6D44847D0A5512566098C712AD89904EE051425358CA5A964643577B8C8ED09450E97B55F660C2F2F608FBD87CB59585FEC3218219B1C7C18200DD446402898E065879FB17C97914C1E83F262801A4E256E798598A176BBE952149F8AD5B992CE791559CE6AC90539C096A209B9A4F87AB73E158801EF2B939A511F416BD4DC195D406A55A66B3FEC2925C5474525026488ABE90196230EC15B09CC55CE383DA8ABED781DC5085BC8E58", + "dk": "67973C3154342CA60AE94B0B60FB2CA4DCB70BF13BBEF7CC9B54790AB3CBD882385BBC888321366F4AABE4696D0126B724A3AB8FE40E03137A28D1B9DE280C49342B162196B13C364FBC5E26651702651A15369F1B83A25B945BF7BA7259A329F107C91E13802B0119CBE59C463B3A53B51837683A6E75674174210A871A1F582A6AF0053EB862BDDB6FE53B21924A7A783C4712AC5A6A38062D83A31DDB6537A82EC135616947A7D6456DB50C95DF678B113275238A1A8312100270A730435E06E554268921A04A9B7FF5025884486D817D4D81610C2805B4207A013A4E4B785CCC0052F70318188380FA554E41A64BE315B3294C3EEAACBF46DB8C87105DFAD68575044F59CA15A379579D381ADC65101FBA2EF3CB2F4A02BFEF8A5B28A51A2283979CD45B753C06D3653B9124A04AA64577562C34DBBDC9A5AAE358A5C73259568A3B18E48EB536C6ECB05A00DD727582B2F51C5562D53311C09D26218DEF54455EF86066B76CEBC41584173472A6008C55C94DE4261116CB21D325B514C83FD07C49C30967D23FEDA60CB9373AB9CABD3D528A99E6898E7A6F4E4C9644022060C30757F5AD961369D537551312172ABCC1C228B9F4F642C952006D7C45C40CCC96FB7BD28731A2F277E7284375D03A35F68101278E70AA882AD82940EA1E1DE9616AE99EAEC6BBED52B1B110502062783B102297A144A54C10F43B2D4C529398EB0739DA57F183B195A39E3178501C9539355B8E456760FAF99D5C3C55B1AB3CCA017C04B94581B18AAD4594236456A02B4D99A00412F818D6EC1387680847D10539E0C063A334A2A86EE1794B49DC895EF95C3D801AB33748417C8F60245E69A8AB68C9BD04BB28783293C52051F9C5A532008CA9C0063FC77519709F05358BCD28955C4A9ED3D9319E1939CED04AEF489C0EF2AFF1EA05FF2C8189093B14C6917ACBA94A8C546063B2FCDAA6C77C1A424A81F3717D9DD88C7A3C64FC593AD66748523744BECB2434822F23632D6E362E5F38C6329958AA20096BBB4FE4F43167301D57332BAE31110E186FA5C41597B92922C79CCE8C59FF341A08E56CF7A1B610605D910510DC03308967CC7CEC7A4328600C601566D8766B601855CCCA887BC84ECB05AA1529DF77058EC0760377BF8E3AB30FE477C33594873B59F02CA226966DC9841569564F9A5557BEC87C2C81784664CB2C8A0770C7C15DD61F48B762CAF11E9C189C9E9947D788A13FE554E76CB14A631440AB2560AA747B447B08E20A5C8BADAD31BD79FB27091938C4EC7AFF409E69730E152048D540958458C219C007FB1A7711D9401B86A10685A66E3C439C005563746221F50382825E3D6A779E692022B2B98150B690723B8ECA370283611ACA06B5881F38A7757A38A25EA06FB5176788C68C01D33822DC9CF7248CB81B7511832845CB06FBA36931CC07BDE6BD299A69A18945DF4057ED724292B76FC1A4432C1C16F451CD1BD796451957C5734B90574D809B69A9B19F07837028C97FC56B10CE6779E81CC4B4714A34A254A1100CA2044399658DD878BE873036B8639609786FEB608B5134A79FD74EB3D485F1D44F39854B3C6552965B4F08F998DFA4721B6107C20433AF509FF0E571FB58B8AB15727AE24AA189CCAB216953F72899D823886364994CBA31EA12AEE12B85460D056C761024987F7683B40A692959513C346E3674CA736226A748345D5931D3250949DBAA2F5BBFD7361E748A6D69419A24D3CCF7F7A849A4301497A2BC1588B021314B0784ADF1C5D01B562B89B3863A92D9103638CA305146912A3588F3A6A816224686268FA692031F427036043090A6B93CA944B4DAB10B63421E69C948619229D6323720C773B900A8393BDAD30547E0BE24D26795DAB3F1806779FA13B1A09A4BFA93BCEA34F522430E1BC923E378EF4631BF76A0F1D3B6A6D8BDD6811293F02CC2096C0257A957261E87220169330BE5559B48698EECC58D151C50C85CA19C9471E7754A8524A8C742495D15365189A2156046CD7A916C2816D9F1626306C6575114703091CC7721CB848CA66108746B1C10341BE8608FAC87B869519ED8C6CDB0530EAA6C801110B8BFB8C4C0184660F79AC2485BEA7AC2A2C3C683D483113C8B5747309FF1AC459CB83560C8800502942B09D3870036FC681397CD63113EF7756444A3CD1FB693BEA7905A507CABA24AEEFC637104C90D311BCAEBCEDB1335AB26C82F255984118B17E28F2266C5D73818D5ECAC6DA8380189196C9568EC949DDF76694A4B39145758FE66A14301CD64A10CCFE46C3CA8419EE5766160465154680F8C435DC523F5136065555F503883165A525568878EEB4DC675445F300F50A1C42EFBB5F1C9A0A46684414CB4C8187255A2CBAD4321082698F2714F234678D4418E33A70CFD76313EDBADA57C82C65801C0DB89D4F7BE19857E31E16ADAE95F95CA0473082F7FAA0855723B5AE4186A6C26D482905C00689D1737CBA52583893995065B5C76C7FC7839CDFA9BACF1B8F7A68307B459CA96BD7091A06A83AE3F3146FA81296932291B2158E9B09EFADA0A2D5AA8F1DB2489E40E04B0C768335595960CCD586B78844F0E940F2007B3B9EB9747254D83C58443C2B7A347B86FAB1ED4354DA2D9669AA21DC2A938E0FBBA0EB57E4CCA4C2666B79559B70F9B61DA060E03C59850AB2D129064F8D6ADFDCB7C457235CEE9473B003DDC9252AED7C444644832A4AF310C431AB26292488C73C38BC03550F7569909417041E2924AC9338ED8251BF6CD18F2B9D1569FC688AD095A728C574AB8EC549AAC0ED13A6EEF5AB87EE622034CB87045997A6657AED6439AF8951946ABC47BB9BBB55A80C92F40E126D78B4353538B6995830044B6E7220030861E47A5CF0291BDCEF8ACECA5C9FB0B43901CB6CE99246D2A2CFBEA014F902046836CB0B58A6DCB79CB9275519A3295C134289880A0D6CEB91356428294AB0B11CA150B9E362872BC8C25E2A78748C9D245C2D36A05F9D87CB5D0C306A5C0DA74AEF98BB1DC45801B4B9EC5B73A0ABA407B0AB8065B23B8345A6147A258326450E399BFEB86E754561F09CEFD1C832E355939175A347303E0D7815C4056F862B08F7914051834423972C84010CAD31B34321066396D47D5C9A77B9F45111B93988C0692039B5A060805AE4365AF1F8B138CC83F2D681F740886C7F07CD153989DEA4A6B2A3597374F7D5BA8E7D01424BCB721071A59FAA49F74AEF15910E84CC138F09F31574DF9A7000175C80073A10CBA6ECFCB84FA680131B824241BB96FF17BF76C0243A03DE9D49895D640E841A07C2299A7C52E22D37C8EE1AF81847781BB2F25240CF91851A5634AE285825C8809C716B6DB795361CC374B87BF34687E18EB413D21ADCEA883D4837CE874693159BDD2920405FBBBE6674F19D0B3C3D6B6F4095A946A5F7E6B0C5B7252A8F72EA357BAEB475FEA0141621A607324B4B17AA13FB7AF2ED529E1728F4BFC083198628DE3C8968A9A92C8863E08AB34A00EFDC73EEE7A8F29F4906E848B8F56474DB2BDE054A660966C955418E8D387CEF43CCA3B5DFD949E91AA5D75C50C38C96BCFEA7740147FDCD8406C0536325A1B74576392EC1BB1B181D584AFD841B43B0034ACAC33416C8DA02777E1169AD4045CD51674342C468874B16B12CB13776E6E8C702D84C5D13933EC161EC10B82A9F339AB3B1D1A9519F342506A3C0E7DB20ED3D7029CE444C5FB4FDB88525AF4C565DAAED6A51B7776246CA880D0F72D5A40B88FF348E9677B37D19F0088997F77429EDBB63840070D71A60FB34FA5CB59F47B06BB03C3AEE80F393A9DE283604635411151222C696FA6401783431E9690BB8958135537332EFA805ABB5D69C9C8F9084EC38862A68082266CA6A0C3514A71727AB519C359CDBC663066FAC14600132D1216BE63AEC0CA96804096D22904F4194D87D35C6C2C0D5539C93BB909A5287C64DCC1246A48CD9CCD80311089CA694120ABFD5A7F16D06A0BE42C48878BE76253198A703080A463053D43867B73B67B26B99A551A3C0C41115D007E0EA0AEF1446FF88BA7FDD32261FC0776FC427C121B2D231E3AC843015B12583777CCD5AAC502A7FFF9B03FB614246848742342C2E0A871E1AD6D44847D0A5512566098C712AD89904EE051425358CA5A964643577B8C8ED09450E97B55F660C2F2F608FBD87CB59585FEC3218219B1C7C18200DD446402898E065879FB17C97914C1E83F262801A4E256E798598A176BBE952149F8AD5B992CE791559CE6AC90539C096A209B9A4F87AB73E158801EF2B939A511F416BD4DC195D406A55A66B3FEC2925C5474525026488ABE90196230EC15B09CC55CE383DA8ABED781DC5085BC8E587FE45A6DB8C05EA8FFC788FD2F73C26CEF305BFBC9BF7C5B32466B5417DB33ACEB8EA5E8C5EABACCFF162556DA53F0C02F72EE7A7DEA8E9EB70FC51C777645E6" + }, + { + "tcId": 70, + "deferred": false, + "z": "DAC056B9A373687E44CCAB8751BD334F4942696B9076155F9D0E5BC0E89D85CF", + "d": "08E36AE8586A59B8249A80D7F43506F9711FA4B00A49D182CE06DAD0CF985809", + "ek": "3201469EC68BC7EB2BD457769C69C09F1646DA20B3DB7A8756962DEB905FE387084A58B069901A9FE1A0939C38E6E414E23B516FD0651E174DC0F6388DC2CB8D605D3D5B1F6AEA3425A03B9A903C846ACC128C87CD5A17A46BB474A0BAB64112DDF1C35355C58164B7C6F9B8A5879CE8E1CEB4FCC26EA55E4833A401B54EA5C29D92E03A8FD5AED6C51E2437C7A89221ED73B2BA3BC5DC30276A0692FFFA3E28B8CB9025566D54A3DD84A9004730B2009A73B354644045B44224D9D96B6A137D8F61513BF8555FAA8F61F00215C8C8841091F7647E53055E6762A504C121474120BC70BED5C4102C82813AF656B9248ED6F630BB269CEE33AF26D474C8B3CDD8D959D10A5D2AE221D5C20D9628A26F1A11EDE680F8C8333A54AF8D79B67AB0BD9DA1680927B0B31B1D6653410C4CC0C6E95164C33506D8CD19A73E1031C733C55EFCA33F76BBAB03182BAFECBAEAD364CE38B22B74A0A244A15725B232616EF2CC0A3010758A698880A23FD58BB2199A3946F5CCACCC2D61AA5985488C0EB60D465566B94C762057ACB163CA636B548254C26F139F51A96E492035B9D725AC16B94C537E2FD78B1641882AD20DCD6C5BB21B79921A59631130E7885340F5311F9973CBD31783DA443BF7566AB3BACEB88232F83E7077845061C09D425C7AA01733CC63D5B7C17C6B3309408D1FA31AD909BC1B0AB6535B0AB6064722D847B07811098C7316071A751623654605FA453FDDE8176B42B2ED07CDA4144640EB5984B301390C64D520071F1C66AD69C550AC41D74915DC2156F78127A704CD678A655C87CEB43748F0989AAE1730D3E4B3374A72CE364F1E2ABA2E5CCEBBA440FDA8AD50A749FD908AA1578C02B35342BB96C3350392C5C25CD71093BB2E87A3A466B697489A3C9E9C84805160A7396D001633EE00AE5641A893BB374CF5CF62417AFE67682C08A10E0A59B8346ADD006F2B40669042616D57936593A62D5578808A1E9D55B1EF4C90EB049987DBAB69B3C8C4A596901BA2BFA74DD4B937547A82B7F5290BFB79E5651B2B4AAF3692CCFBA987D5EC778E61281B0B388A71222DA27A90776E66BBAD25118AFDAC425F15599176C5D5F1B491FA1FBBD9005A0AB93AF1C8280292AA468FF0B1218726C52E4AC8FA403C91D12EB1134D6B08ADEE2A065F191DDEC390A1232D63306AE1C60AE1908CA2294ECAC6AB5257644DA45D70E96C6FAA5E1DD02AEC276C5EE2A8D36A2A13EA21359934C8285498370460CCC2A4C886C72A9FF17AA214553F6826177630ACC2F70619D64CE3F04DF17A6599E9AE5D2BB97B731432421012FB229124CD52BB9E2EA7B33CCCACBD9029A69AB76F00CE84A0C0D2C80F54A77D6064AE85465FA74271BDC2C62CB940E9C32A67F9C94AFB7322B93016E31C4E34993C7A65D58117495C44A8EBCEA635AA6C29889F3AB1E39661925136A06BB269483C1D291F90478713A91A178193B25877D416C03242682E76071B78964EA626C6A85E4ED8A45CF573BE56369B9476A2FC76713AA11573A083D0A0B89BAC15228A42B9BE2F8617CF8BBBA21562FEE3313066A8E86063EDF365799B7EFCBCC11570196B535D40F65F59C0972E057E2C70048CC10DD292611028277B325791B865B9D863972AB1725B6BF1546DFE0030CD85621F92472CB0064CC2CD11411127231181E6745A3580F6E8383150C8C098A3EB455F5CD05725719D0F844BE76743F7D962261A5FE5C29E46D58EEBCAAF0C40C04BFA43089C6236AB1AB574CF28A9178A4634C5848259191C21401C05A00A48D0420BB2737816CC72BB3D5BCB5EABD5531ADBB2E875045E861114D2C5AD5997B104A4F3BBA26A6372EA6062C8D6229C196E5B7A572F898D94A307BA051F899C16A34981B818034CA84A14930AF2D38BE095BE4B304FA1BB69DDB72AD605294BD273FD314A4D1940161B97626B5C725935D358153B4A1318F1273C7C6A93FCB372196593D9655F3C41FFD4B7B72B7131D7C2607A8763778556EC2D3E09969A4C968E92240077051446375B2C4C9BA9CEE84563C4491673667C026843C1602A9BAA0705E27918A27E2B01B9E756A77F7A304345117ECC52E81823A0A8170086B89EC64A39C60EA6A78363FB79E7C0B886B1854C5A929DF98077F5AD847650926273A9495000E688124118F1D83CC93D0E4D2565D307F4CD0C166E9083E8CB47F6979CD0C6F05D5A", + "dk": "6F148AB8F31718811FA8326B85A430341A9CB4827004D5897659554F661B37551033D7B51D416CEC7921FFE4711A575BA6EB73643B78856B9C230768B6369A9D9C7C91B7620E4A709D38A73CD7A2CE48712EC03F0C94070B783A4EB3186051A56D469D01152D3799934A69C672600E0B223740F937607B8923768B20F7CBB9712BFC633654119B7299770C764C471399BFF2CE457918F3C3AB3A323CAB53BE1F491EEA526EE95C12A50C2A3D8C75589BB6919B97D37AC96753ACBE493109F60957E268F8CC27C497A89C12CBC7109CCDEA54E174B7AB6C4E9D68326261280D582DF8E976B2F67617B69FD2D58CFBC44F641C9598B293182939D4AB384C6B7920266E6C7BAA133A1A9E841AD0018ECF6010F0D292D7699177864D063641EE8BB1A2C7CCCD7C33C5574E9C499EE9E7417A5C072596C4FB76C2E56950B0907BD653B47966420E866FC3FA367C965A1D096FDA16C3CC1CB651DC693B960443617C58D13FC2595FC267720BB88D0633579BE84DC0232D973AAF92140B20CAB7D4444A96EB6A4235C0665460470994D94005B659BA5A6A345E51677402B69D378A0444B345340BE80230C7730F4342833543BA8079692333128E45B9DC48830C1892E69AB37C632771EA677A47B1518815E4976367888AE552A397576A6838B26426A587828B08EAC520E47463D00D1EF5CDD50838A961832647561BA75D6B1A5C93121949C46CBEE11938C5718013724131C18B0BAB806097C14445FCD303BC8BA3FBE2C0AA2C3FE45A74F5E22F77D6B405A962B1F95CC1E0620E6239AD57042E139955C97C359B09F6990D1C7747DEDB6F02313BDA02839AF16D7F181BDBD3245B272988432B35916144BABDB7F3CBB8A4575677484822B76739577CF945FC944C21D4956B0B2E3C86195B5724A03A896552BEEF5804D583BA6B2B9A67106A47621DBF911E62F677F933527A0095D6F4C0D5C3392548C23584CF91888A51269D15606542E601D8A7B915418F164A6AFEAA7AF60345D7A603A018838237861EF1C99194323773A8A18591F7539821D57856C44D3ABC334D266DFFA64AAD3B56DD7C7B1ED2B5026142CF508D9F25A2CA6199F7937E6AFB66B1C486D5512F1F12754ED5B70871160B8814986C078F006962C956404B6E5EE9C486E786C3C448B902B1841697F1208313F8543B40566E18746EF181DA1195711040E7268CC474A1AF4388A8FA11AB9A54B228A92E569415D12C06B246F8180F4B80395C708089DBA946B459ABB598F6F32708B8316AA73DBFE15D231C2D69627D434CC1674778B4FCAF23227527B2966F0718AC1C9D6D3B374829C46D063A4794C15A189DDA693FB6C08E46C0B7970B8AECB8B52EC35428E8826CF6B1FBC9A988E13ACD089E4DB2967DF64DBCA475BEDA31DA74C3BEE4BF74568EB257763C371BD252A525AC3325941C62EB68BE79701C11C18EFBB1DD010F84BCAF5EBACD35C67671C968A6B5098E0535D7932002EA7739C85F45085247032DE8EBB7109B9A522112DFB89C2904C1B611AF46762E4854AE2652B4A5580B6D902C12788E2F6C72A59A0A5C4385CAC77777C64D9920A5827568734370E891A2638AC12BD164C15C01A3DA0292F325DFA4069068329DDCC25A3964A845694DD6AA99F17AC9C12DADB4431C8707949CBE2E4B9764B65BAA0451146725B6A7B6CD6726E819AA8AE2971E334A66B0501F210C0A1975110BB8647CC8299C2F7D4C16DE4791B25A36B2592E3AFA0D059B9D4B3B50D9981160C23EB96BB1EA0A984D922C1D31A9C105CF5CE64D86222A12773E7ADC01C99B5F4754610A2B3F24C66D8E3212B8584DDF7B68128B215C600336409733049A54A719D0E5A657AC223136B1C9FC5D3F33545A051902AB0FF4B1CE5DA81BC8B3A78EA40828348210F953250211F85C1F3196418A32CAC6158850EA8B44A0CB72EA5C0B165DA1A0751DA41D58514439461942E478D3A3951E3273F35B938A842EAF331471B9B1417672DB5CA82F246B937448A08AA720060C5F2BC084D3157C25CA2F2BB02E2BC4289466C8721D7198B01F92C3EAB020BB92B318E78074218A48180EE799948501B84FDBB447FB009436CD20A69378E4BD87831630329AC0D76460E5134C60561180274E8C94B64C5F17BC4AB39625B49A13F1887B9AF06E3201469EC68BC7EB2BD457769C69C09F1646DA20B3DB7A8756962DEB905FE387084A58B069901A9FE1A0939C38E6E414E23B516FD0651E174DC0F6388DC2CB8D605D3D5B1F6AEA3425A03B9A903C846ACC128C87CD5A17A46BB474A0BAB64112DDF1C35355C58164B7C6F9B8A5879CE8E1CEB4FCC26EA55E4833A401B54EA5C29D92E03A8FD5AED6C51E2437C7A89221ED73B2BA3BC5DC30276A0692FFFA3E28B8CB9025566D54A3DD84A9004730B2009A73B354644045B44224D9D96B6A137D8F61513BF8555FAA8F61F00215C8C8841091F7647E53055E6762A504C121474120BC70BED5C4102C82813AF656B9248ED6F630BB269CEE33AF26D474C8B3CDD8D959D10A5D2AE221D5C20D9628A26F1A11EDE680F8C8333A54AF8D79B67AB0BD9DA1680927B0B31B1D6653410C4CC0C6E95164C33506D8CD19A73E1031C733C55EFCA33F76BBAB03182BAFECBAEAD364CE38B22B74A0A244A15725B232616EF2CC0A3010758A698880A23FD58BB2199A3946F5CCACCC2D61AA5985488C0EB60D465566B94C762057ACB163CA636B548254C26F139F51A96E492035B9D725AC16B94C537E2FD78B1641882AD20DCD6C5BB21B79921A59631130E7885340F5311F9973CBD31783DA443BF7566AB3BACEB88232F83E7077845061C09D425C7AA01733CC63D5B7C17C6B3309408D1FA31AD909BC1B0AB6535B0AB6064722D847B07811098C7316071A751623654605FA453FDDE8176B42B2ED07CDA4144640EB5984B301390C64D520071F1C66AD69C550AC41D74915DC2156F78127A704CD678A655C87CEB43748F0989AAE1730D3E4B3374A72CE364F1E2ABA2E5CCEBBA440FDA8AD50A749FD908AA1578C02B35342BB96C3350392C5C25CD71093BB2E87A3A466B697489A3C9E9C84805160A7396D001633EE00AE5641A893BB374CF5CF62417AFE67682C08A10E0A59B8346ADD006F2B40669042616D57936593A62D5578808A1E9D55B1EF4C90EB049987DBAB69B3C8C4A596901BA2BFA74DD4B937547A82B7F5290BFB79E5651B2B4AAF3692CCFBA987D5EC778E61281B0B388A71222DA27A90776E66BBAD25118AFDAC425F15599176C5D5F1B491FA1FBBD9005A0AB93AF1C8280292AA468FF0B1218726C52E4AC8FA403C91D12EB1134D6B08ADEE2A065F191DDEC390A1232D63306AE1C60AE1908CA2294ECAC6AB5257644DA45D70E96C6FAA5E1DD02AEC276C5EE2A8D36A2A13EA21359934C8285498370460CCC2A4C886C72A9FF17AA214553F6826177630ACC2F70619D64CE3F04DF17A6599E9AE5D2BB97B731432421012FB229124CD52BB9E2EA7B33CCCACBD9029A69AB76F00CE84A0C0D2C80F54A77D6064AE85465FA74271BDC2C62CB940E9C32A67F9C94AFB7322B93016E31C4E34993C7A65D58117495C44A8EBCEA635AA6C29889F3AB1E39661925136A06BB269483C1D291F90478713A91A178193B25877D416C03242682E76071B78964EA626C6A85E4ED8A45CF573BE56369B9476A2FC76713AA11573A083D0A0B89BAC15228A42B9BE2F8617CF8BBBA21562FEE3313066A8E86063EDF365799B7EFCBCC11570196B535D40F65F59C0972E057E2C70048CC10DD292611028277B325791B865B9D863972AB1725B6BF1546DFE0030CD85621F92472CB0064CC2CD11411127231181E6745A3580F6E8383150C8C098A3EB455F5CD05725719D0F844BE76743F7D962261A5FE5C29E46D58EEBCAAF0C40C04BFA43089C6236AB1AB574CF28A9178A4634C5848259191C21401C05A00A48D0420BB2737816CC72BB3D5BCB5EABD5531ADBB2E875045E861114D2C5AD5997B104A4F3BBA26A6372EA6062C8D6229C196E5B7A572F898D94A307BA051F899C16A34981B818034CA84A14930AF2D38BE095BE4B304FA1BB69DDB72AD605294BD273FD314A4D1940161B97626B5C725935D358153B4A1318F1273C7C6A93FCB372196593D9655F3C41FFD4B7B72B7131D7C2607A8763778556EC2D3E09969A4C968E92240077051446375B2C4C9BA9CEE84563C4491673667C026843C1602A9BAA0705E27918A27E2B01B9E756A77F7A304345117ECC52E81823A0A8170086B89EC64A39C60EA6A78363FB79E7C0B886B1854C5A929DF98077F5AD847650926273A9495000E688124118F1D83CC93D0E4D2565D307F4CD0C166E9083E8CB47F6979CD0C6F05D5AA184CD5ADDE3E9D68D66C7AD3ADAD382D8642BF03B85F068AEE861FA55B6340CDAC056B9A373687E44CCAB8751BD334F4942696B9076155F9D0E5BC0E89D85CF" + }, + { + "tcId": 71, + "deferred": false, + "z": "4D727ACABD44DC48980691E0268B5B3FC1E476B3FDF9571F5CBC8DDFD400AB99", + "d": "A491FF48028B67A407F1054D5B1CBA733B665DE667E22596EDCC31C227C2DE1B", + "ek": "3563BADA724011CA9F7154964DB8092AEA60242B273BA94ACD33B61BE47B5AC2115E95BDBE56B214E04166356496A698C81744C06B114E2B37CC441A9AD8C90B936E1D86B9E1D9B17F352B393B9A1DDA0FEBC548989C12C120C7988A460B151895961733F84111058116C427E75A8FB6798B9691626F7A5274F46BCF5A160F0BC59B01C5D5E634EE9C1FD5D665AB59A4B495030855C538C86BE779CCD8CC076D83407A5C9AA3757841DC30F47592233A3AA8F3A721A5902FF8225F51764D59087D5B928E34572C23C511E236ABA0CD710A7EA0FA0CBA999F22445AF63CA783205E4D935CC9304BE9E92364C97993A1BC4DE491C5ACA2932575C99153A0BAA814644DF6A4922F426268EA1F7D97AB7629462F0C8465900AF523CF2FA978CDA56F4FC936BDE529553B56735701FAB3453C1A8ED0492222022E7C799EA11837C952CFF9A059992B26CE774460DAC2D23803A913CDE96662CDD78B4842A09E3A09A8D6A5B4052A25D39F63A43D9B9473FF184EB9B49B78B7165C62141866C2D4D866232A952E89CFC422CA5E510390DB98DE3A5DD0E3728BD5076656941894BD2C85C1B4FC400A9365F744B7EED6637C694D7C3104329AB526193E0CB2BF5E9B8E5D34630C16B097EB027C33621F23BA78E4470DA48354C29C114C242EEB6C62D15395D40B716A6137CB5B5AE2C27CD49D176B5D70416E254753F1150D5D8807F07916330C69B5F236F0672709834523092746897CE489B3FC878FAB716042509AA96BCFB839544449280C7C1CC3F79A22A25BBF47A33228CF1CB619E2492A95EA5F3D12C80BEB2412B81D6EC7CF6147287FF36449205CAAFB3625CC0A6FD4AEE3898D8FE56F62B06F6A7B7F1325B83A30B72FFCBFC9A672767BB2659B1B6500B4A3629F00286B82F9597E6CB21FDBA9AAAAC5F24273B2AC22EA4023219C7B32FCA7694693A2208791E1AC33C00C0DE64E2241001DC04249CCBEB797A1C38CAE3DA81C07364374033917A04AF6A19BE424C07DF33237B9223B7C04890CCB57780126B9A68AEB5783993F6C08783DC254B14482AD37AC90609BF3B0CEC7B39DB4241E0D9502DB60AFAE068749A295BEF8AABF861EA1292542927F6DB939AB7365142A37962A46230C37FB9519642119E03C45CEAC2F0B40198D6211758346E2FB284FF807A4C06552D7B8DF604D2EC771D2F74D0A258261280C60E71C9FE66168DC9493539EC1F018A520C02E6B8562C55831C18900A1C55FCC6A772480BEF2C75322C1CD116483562E6B7A0D16D351E2BC58032B5267325183148CA61079B2E8A8AA293863E0946D6772716053DF4A0260E3A36ADABD19713B46E89ACD650EA7932050724356D1261DA37916E85BF552C8AA628ADB08383781245EDA4A82E27D099496A26B5C893927DF02BEA47742B3C40B0E31B5D621012D1BC0F3B085E5BA6228E9B5E875901F1711CD12516EAAA4FFB16AF44AC384E0AB5469B222666FDFE32B1F5A4F3C0C022F6B4ED770572DB6B9B7FB715CEBA1C0EAAA19FB2361D83DD2465375A2BBE2793255619592A6044B71CFCA2916B0C6C895A38D7A28245398465432878D96446BF71A6C21C0A62500B030BE6B528646C860AEAB7B28FCCD87381C61D7106B518E22A2A03F5B7F48729A50672A4B039FB67B9DB0A803D304BFCF83782BD5A10250A8C8D96A9EA993E692CDE5871C6BF79FED564C5834634B88280D3A4CB18025E332532BC65FBC169DE0308012C08A581A1A5C9B1A89C75162B990FDAAA768A35DBD9ACE608981D589116BC45BD7D49425C7B11B573B8F554976152C9A17C273E4A3CAC15D5DF6724C1605D9A77CE487438248178C10486FD7C7E1EA52BB5467B066245560A2C4523B53304445F956E968C5AFF602B7F9378CB290BA0B4707841D175C01AC0BBEB18435E03850FCA479C1E8B7CF0730A5F23690F862C1970A5E9A8DD3F51E0655B2CE7BBD4B38264929C9499BADB505625B7A7BF260597F1239176C4892E37C3EA0770068C49E14A8DCE526D64791B6E3A1EB70A8FDBA17FF8476CA5B1BC9FB533CE7B1F0373D760AC691DC598899A3798A0D6F967699CCA69420116BE625CFC8C23879215C320B354412DC7311E21A3784A3445134977E995282033BD0080B84487BBF23A499CC1D17172BD029406523707B671E25F9DD605C8473C42FB131B08A1E33F1E85055C2DCBA8B2B04F9B8C07D906384", + "dk": "385CACF0957318BCCDE555CB6933660544AFDAF8BC43D4AED82135F8CA2131201E03C7A42C7875EF309F227684284275F590CAB8078AA51AB95A133BFD9910AD0218260309CE43360ED01926D13255D37FD837462FC685F64350CAD95F9B757B56C79564C57C10B31F25514C570C1EEEC1223AAC91353971D915635E3A0A8F4BC5E1F241B3F31F457B3984CC160E13AB6C46B41808CB067C8396D4425FFA0C2E208E95522D65D0583FE2C50F40C9888066CF3377D494BBCCA2CF5DB55ECF711AA48ACFD6F859F859992E5B57C9C56D9430C6360B076A8C0EDDD544F8BB5B7950A7DDC006E705597FC08AF695AF0765331CC8913D8944EC4262E195B6FAEBCE2A3B7472D44A320B1533AC3917FA8DF7283D33E999DE4756FD37005104C8E2D50C4356BB35A79C021C45A05C05B10688F5A53AB52255D9B6BF8FAA036F09923AF89CC6F66BDACAB817A6C9F88B2339170FDD478A7C674350209C2D0773A413134D9709DA988F743134FA89AFDA3C94C4F75DFEE2656AE2312DE6A42A0B43910A4CF061922456346039BB4AC466B8F9AD7867103C165041220C23F09F264383D183B66C7BA90B93BFF8CB9E736881EEBC21917AAFC9067F8814C17AD8A302184FEC862083D1B39C810B92E3CDDF937773CA9EAA2C342014CF4652A5E5D2816AF4B9586467CC702A4AF342DB0B5908AC2F9B0C4490A8962D011BCCEAB20EE46DE2B6B08D473D79E7A10AA52211191784551E7B289C2FC85318017844674AED2917B3ECCA9C814F9F988CA8A927029AC5A6E8582078220FE44AB8A63EBAD736C4496D726BA3A1B422F1265212503B686A5367279E9661702D21887AE81F283966A5C91A8638C63608CBB59CA80A679F2ECA74D828AB15592A15070CC6915D8B6A1A6CD13723D410276B6F6644A9D0610869347386012340A4C6B1207B57903527C010FFC1C8B59599DAF124999CC4FAE39164A5868107C198519B59FC38E1229021A901F569A009987D76606A1F66C88FD88AA4D552E7C277510316DAD731727928FBB4495560958042773E1B8252BBB14F3328E5079E2206743BFB18A799918E241AF3A808155262A8F9A1CB46C60696763AB1206666BE2659BD1C78B6ACA15FB1F823C6E15A70930D21BC07F306094715A62805C486513837C56F332B97CEA067318C0C8E222B5762968DCA48DAE6C8297C2FA322913EA947B06418096C22D1EC3F2CEC48A7F850BF01B5702A8085108FA53127DE0B949E6352365336BEECA65395106BE79AAA91623931828436A67C0C3917160837532E0949503F7891BED485B5056B211A1E354105E3661AB7A1BFF354BBEC695204F2A8EF55073FF27A313662C1E7C7F4E8AB46399D29E2BE910425CE92976B491A1696CA56827F4571C98B328046269379110A559B463F1B9770050F1750262542A6C6BB728B4332C555CF45468795F2884F10303E212D333A0445EBAC52D669DA8B1BC3033081D0516F01CF22C5BE8CA020C8F671FC27A71A518D08B7A2C1C3AC62D874293A1D33729626968638C85761E78ED704CB86F054BE86C35F6A5233253C0F097B34A557C3A0B7B5D16B0266718AB7BB5DC27AAC3A96BD0B807BE5392FB0C6804739800206C7287C130B2A77E5045D5491FA50C1C68629C538078A3091E7B967B4767C3758A9A4E871C6129D78F0B9BC7963CC110641F7C8350A860B611C3DEC98FBBB8FE4F40BD10BA1F9F6C7061B12E7541EFB527B8E4349469987E4FA42D8F4958D6243A1C032EEB5860DD0BEC0C9A1E4D88967B748BC536020524BF5D06C594199DBD6B6CBB795F64B0F6656655B9B36B7E84316D918E094078D1C4E03C75617197306192338747E32F46551ABC23E74AB757B12C85899C28238FC74C089E4101F0A42BD440E28BB832BD523F03C070FE065D7B96652D680DE68223971ACAF5B5C29B8AF836C41CF80AACE794800FD944B6224B8E207BE27AEF24BAA4B2436B28B6A85AA19612A4F11935DEC482D7EEBB006B35860D13A7FFB159F57812B518E2F3161A9E35C5B272DA3529284DC278664AEDF05B0E1D602BFB60436F026FDBC0A30F2579F1C4252021A132C31C73249065C5BBCF03A5D418DEBE578E5F4A9074685C68491ECEA6DC9EAA7BC819DD2C43F42049B92864A001D533741515EA5090F0870F455B03563BADA724011CA9F7154964DB8092AEA60242B273BA94ACD33B61BE47B5AC2115E95BDBE56B214E04166356496A698C81744C06B114E2B37CC441A9AD8C90B936E1D86B9E1D9B17F352B393B9A1DDA0FEBC548989C12C120C7988A460B151895961733F84111058116C427E75A8FB6798B9691626F7A5274F46BCF5A160F0BC59B01C5D5E634EE9C1FD5D665AB59A4B495030855C538C86BE779CCD8CC076D83407A5C9AA3757841DC30F47592233A3AA8F3A721A5902FF8225F51764D59087D5B928E34572C23C511E236ABA0CD710A7EA0FA0CBA999F22445AF63CA783205E4D935CC9304BE9E92364C97993A1BC4DE491C5ACA2932575C99153A0BAA814644DF6A4922F426268EA1F7D97AB7629462F0C8465900AF523CF2FA978CDA56F4FC936BDE529553B56735701FAB3453C1A8ED0492222022E7C799EA11837C952CFF9A059992B26CE774460DAC2D23803A913CDE96662CDD78B4842A09E3A09A8D6A5B4052A25D39F63A43D9B9473FF184EB9B49B78B7165C62141866C2D4D866232A952E89CFC422CA5E510390DB98DE3A5DD0E3728BD5076656941894BD2C85C1B4FC400A9365F744B7EED6637C694D7C3104329AB526193E0CB2BF5E9B8E5D34630C16B097EB027C33621F23BA78E4470DA48354C29C114C242EEB6C62D15395D40B716A6137CB5B5AE2C27CD49D176B5D70416E254753F1150D5D8807F07916330C69B5F236F0672709834523092746897CE489B3FC878FAB716042509AA96BCFB839544449280C7C1CC3F79A22A25BBF47A33228CF1CB619E2492A95EA5F3D12C80BEB2412B81D6EC7CF6147287FF36449205CAAFB3625CC0A6FD4AEE3898D8FE56F62B06F6A7B7F1325B83A30B72FFCBFC9A672767BB2659B1B6500B4A3629F00286B82F9597E6CB21FDBA9AAAAC5F24273B2AC22EA4023219C7B32FCA7694693A2208791E1AC33C00C0DE64E2241001DC04249CCBEB797A1C38CAE3DA81C07364374033917A04AF6A19BE424C07DF33237B9223B7C04890CCB57780126B9A68AEB5783993F6C08783DC254B14482AD37AC90609BF3B0CEC7B39DB4241E0D9502DB60AFAE068749A295BEF8AABF861EA1292542927F6DB939AB7365142A37962A46230C37FB9519642119E03C45CEAC2F0B40198D6211758346E2FB284FF807A4C06552D7B8DF604D2EC771D2F74D0A258261280C60E71C9FE66168DC9493539EC1F018A520C02E6B8562C55831C18900A1C55FCC6A772480BEF2C75322C1CD116483562E6B7A0D16D351E2BC58032B5267325183148CA61079B2E8A8AA293863E0946D6772716053DF4A0260E3A36ADABD19713B46E89ACD650EA7932050724356D1261DA37916E85BF552C8AA628ADB08383781245EDA4A82E27D099496A26B5C893927DF02BEA47742B3C40B0E31B5D621012D1BC0F3B085E5BA6228E9B5E875901F1711CD12516EAAA4FFB16AF44AC384E0AB5469B222666FDFE32B1F5A4F3C0C022F6B4ED770572DB6B9B7FB715CEBA1C0EAAA19FB2361D83DD2465375A2BBE2793255619592A6044B71CFCA2916B0C6C895A38D7A28245398465432878D96446BF71A6C21C0A62500B030BE6B528646C860AEAB7B28FCCD87381C61D7106B518E22A2A03F5B7F48729A50672A4B039FB67B9DB0A803D304BFCF83782BD5A10250A8C8D96A9EA993E692CDE5871C6BF79FED564C5834634B88280D3A4CB18025E332532BC65FBC169DE0308012C08A581A1A5C9B1A89C75162B990FDAAA768A35DBD9ACE608981D589116BC45BD7D49425C7B11B573B8F554976152C9A17C273E4A3CAC15D5DF6724C1605D9A77CE487438248178C10486FD7C7E1EA52BB5467B066245560A2C4523B53304445F956E968C5AFF602B7F9378CB290BA0B4707841D175C01AC0BBEB18435E03850FCA479C1E8B7CF0730A5F23690F862C1970A5E9A8DD3F51E0655B2CE7BBD4B38264929C9499BADB505625B7A7BF260597F1239176C4892E37C3EA0770068C49E14A8DCE526D64791B6E3A1EB70A8FDBA17FF8476CA5B1BC9FB533CE7B1F0373D760AC691DC598899A3798A0D6F967699CCA69420116BE625CFC8C23879215C320B354412DC7311E21A3784A3445134977E995282033BD0080B84487BBF23A499CC1D17172BD029406523707B671E25F9DD605C8473C42FB131B08A1E33F1E85055C2DCBA8B2B04F9B8C07D906384861D9A8CDDC54069D3E53E033E2530CF83C284A49AD15019F061C40B2D00AC7A4D727ACABD44DC48980691E0268B5B3FC1E476B3FDF9571F5CBC8DDFD400AB99" + }, + { + "tcId": 72, + "deferred": false, + "z": "4E638D8AC3662450E09D8500DED751060B7990D54F137508B9897277F65EA952", + "d": "7B2EC50C53A67E0BCCBA98C2E319F5AB46B6E593D2465F14B23FFA03D0E5BE0D", + "ek": "E8A65EF0C7C7D7391DAB233EB277243732CAA45B53315B645FF9721D8AB0CFE54FF717157663B9098C2267633EFE3544A88014AD15C7B10A4551CB5F9BBA3D74946371B1AA54E6419CA7B4611149B5F02C73819A8C625AC52618F771202338AFF05969ED670BDD0B9DB562B8055884CBEA7A208A2DA850A05484C6B84109A5C2B498E8B8640ACC6F7AA6E1D7A95415469CC1C06D17176146CEFBA58E2B8929770851EBD6CA5DBA444548C622673DFBEBBC95767BEE2B86FF5BB37CF306B2945071EC1FA80C7540C56A36EB684D71C5E8B90AAA8C2421E21D64E0638D63C96E2B0BD9457BD5062199A01253D240C712315778AF487AAFBE28C650532A493C1B3E0251BC0841392839905AAD3D12289506742073862E8549E7E87EC28102DB7B89EBE91627CB95C0928C921978CB8C94875A94F1557498132200B4B76AA3C3AC9755C3B6BC5E5C59C9B3C6F7FB2CBB5AA457904FEFD2C370E29EEB2417BC45977BEA02A0DB9DE57937372298102755BA5B007EC88340B28AE7B819F9E07182F76070043CF3AA7E9256CF1CC3A6442B1726EB889CAB193222BCD3D8141843C1EF9921B8254712C04529D38846F595BC011B3288BCE0231ABC96985145043B579BB0864F40EBA6A66144E0972CDB10A71E44A088112B3C7907E5591D6EE85B34D4AF8DC58633081BA1A0A6EFE133B4C70ED215A22F451A7117B8C5F6A3D3FC4455214F5DCB8C31370546B4C4BA365A25017A9C2296AA641CBC4745BCAA72D17C9EAAB0155627BB45770D6D259BDF5B044053B4C7C8784FC433E89942B5D6C807A0707842CA4FBB98693303C118C9F4952123582FC4E22BB853944BFC1584810153F3AF5DBB74BB2928785C542AB647E9321D724AAC9EB9091707B5075C700A4817CAA2C355D4C99B8C5037B5288FF5279725BEBDAA5CE23609E5320981F11C8A116501D5ADD2D2B057C41E469257057B7A9C508017245C20C13A0C104FE1A517EE4621C367CE283183C07675BBE5895FBA4F30CC406772635982CEBC3153D046161C7B8BC4D87B648236263A44ED50B92DEBB624528C7A984C4C5047737A8021665279E9CF30069AADCC3F4A9245700436E646AF721A612828A07DC463D61B70223C7658F22190C83405999D92889CB0E5020052C31066665C4A021643C20764C370B9A5D1975D47646E1329072335432A19A03590B071482A3774BCA0601D8DBCC35A63742CD127F6384AFC6A971EE8CDD3E13687588D84C358A5537E753B2736840FD4E76A1CD0C68F9A990E5644404BBA84491E5F3B6F23EC45DF91538BD54070A702E69B66BF6C88CBDB8FDE693A2487681379A2AF94C592472FF167BD17966F9DF67E8FC51152AC613512930BA2BC2F453EEBCA91399B6D8F12AE891B3DEAECCFF120751866369BF8902D439D19F77B264002E5901B1C939FD86CA623277E6B09A72A93B52AB00754EAAA74833B8E366C8F0752639437F83CCC00F92EB7057C43AB94A75C31D5F854DCD3784920A36CA0C2DE244D1AE3A9E578B98E0634635549A8932A6BEC1F2EB321572A060EB110AF473F3E04323FD868A241891227222414C663285B05777BE82585DF3AB0ACFC121A642C541B3C3D7BB3157302EF62A1229156DB3609678B3B3E2576902145E5ECC78B65CF69BC8A7E6631494B804C4C89A9B595A8D95C039A9BA356670A536220C1CB54AC5BFCB7CE0125606A40C4EB4BAFC4C43BECFBAC84812F70C66796D6407F887CB0DB41F0FA7062E255896582B2B218FD96B6E5581A6FC26ED40272836950CB348AFE78CB135ABB6D015F299377632C72A7BBB2CDA7CBEC689E7551168483085B6B7426EB6967F729AD695D4E09C49B7A0010F80EAB54CBBAF4B641C956231663DB83512C97067CC7BFBEDCA93CC9A739A813B48C4793354C2DC642F869307AA191B77C2BC72BB048300B54906DFBD45255E92D81A98CD87149FEC3A428540D4E03C757260F3731CB7C4743A37194054AAE5FD6902D48A911F661EAD29321722E8243CE62E75ED82657423163A86362CAC2931954092909B0082BAD382A013A5044FAE9A12BF300670CA5771042933764E700B43259B130F033B023CBDA36815E2C6BC7C0601CEB7586A95DA4033E80E32123AB86C6135222EBAC0EDC17F5549D5B66760E07B2B16BA4FD8040E642990128A39A636B19FD3EDA4611BC1CDFD552AD1DB338FE3700F0920D56F3", + "dk": "0CC61046A844640446F07C1683D649F1168A00F1C859798944790CE1F884B2A99C177C579E314C91B33E483B86B64143EEC23F1587C8E038A42C85397A47CA7600C772D492E4CA5F7DC815100B9155449E72A0A526D24035FB20074941F0622FA9369E79D46378E45D5564245B0C10D9D873420895059428965CC22E064B349A4E40346F77A84BF7734C598C5775D39E1ECBCE2A6BCE6FA5CEA4F41A05949ED766C1A290299D9BB47DDC2E7A782F386C42D2AA04C991304BDB108801AB6802B04259757A63A88B7492A2FB2E93A1AE7646267F434C724134154C407808CEE0A7983C32727E44766E5C34EFD16C52086519FA0DC6C7098282555C069F76832F7707477F69566280BB6D406ED1714205B73A5711C449B91B4F8A2C2638B65221493BD940B5370A4C661F6F9C27AEA6A69DD0B61CEAA861E78328941091A95300602878222290CBC67E907D6C4CB2BD6623CCC5A23E46322498BAC5945E6B28283D7401B30401753859A2D4818ACC8D71437961DA02F2E8B5BA94B494E7A215F518C6BC8214C57237108C6B183F1551696A909C828A0E076341A5C141ED62A9987932D002A714366D8621CCDB0272E7923C6F3461AD341C145A864C6655C8E02AC0C91CC0613CE7D48027206C7D4988D82A1340A7BD337B82FA26400A4B97B5D819AF154CDFA639DA3A522DAA0F524B2B77FB422B8216FA83B8D94903452BCF5054A5081741B2E93F40548793B39B7197AAF027907B763179269CB06671B0CC2820F6015FA158CE93770A1A51CBF033ABA1A5C4363A1AABCA93F2800DC011B19B952774C4F90991001C19F3A688B2E01C934A7BFA705CD093AF85BA5D20FCB498E5C91B186378B63C04123D19A8C2B5209D7D8799EA7192BC3876D1943F17FB63B8185D89A37483AB74E62BB03C27BA845CCE57309DA7A8055642B9AC51B820AA8F61F88B819804DCD8C3CDCA2AA816BDABE9725BF83C61796ECB069D183600FEBC41114182338C97B67618DF818DCA151AED240E36C1A0DCA654886C6CD3731A92E3CE81D7CBB4BB1CCDD238C54C44E89126641AAEE1145BBC378C92C56E400B5DE838A18FB66D365501B406287ED8AF6D03CBCA4BB617B42DBEFB4A0435319A00133F4AB70631C1045515C6C23310F50406780F9E891187FC96736296B9E7AB1609C51A103AC34667925901EE3A9116CA97FB46B8325B13A64B008A88B03E0C383E152D7F8593B6638BA7F9AB500968A830042CBB50638A58AEC5B6BBC1938E5C7A605A80B161BC18841873ABB5F38ABCDDE99464736D3505C9EEB86E8A95747CF9CF3B9A52BB115505B156928A79DC9B9E1F110987D4808AA2C27B806D7B746014476E571AC2F416AABADB36CF994813887195CB63C15C678D480443CC0D2C60365E358F1FA9897A12279CE928E2CA8D67006D48592F54EA4CDEAC2748940AF558356760C420EB71DE2ACADB064586C5C01A698330266DC78C95DB8CB51907C6DD94B507C107E9FA7210C60FA5D8888A3CAD7AC1B6FEE59159D6212403B2B21944D0AC35B0137989F002D4F13E8B873F8B53B3ACB09478F4C00A7486AF0B5FCBD42E21654FF3DB786F2307E7E60236EBC89C36971E2920A27C5E7125BA1DC77B4F944BFDA8C4D3E09BC8A00B3099B6EFEC5F7F59AD925B79C3311A7F02433FB9133F845B58E0BEEF5611DE6890E45AA75645C34F832B08B7655CD6424F733FEDB9825EF3340A010E72781D16F8180F227110402816E6524D8B341EF5CBD098A8CBEB52C02B715D1789B0D38250EA6730E506E569A9E32A5A35C7341181B9E0C46296E91F3FE9C5A7159F9126BE378BAC03D467C7A39AD1605DDB2A3C7FF930A85C0710114ED2094956E005DD770699F4CD50767E53C15D5251B2621336CD6974CCD446C1C4028C62839EB699D869758E502CA158A39798688D95B1C4509EE9C57383209D69D105D56AB55A59955F78A65E49B5A4FC4A5791AE5D79118CE2B22AA9BA2DCB963BD672A6861D78C30D6873893E15C62A428BA3E77D09C94822693166E39C32E32666F4537E70A641181C13609F1C3535A91486FC3ACCCB29A0EC0133DF7917B71B8EE4509264788356E967335942014213E4862AA8B7691AC207A996711AD1AAFC30BCBADC0A35514F3FFAB45E53197E89B918AC75B504647A3684E8A65EF0C7C7D7391DAB233EB277243732CAA45B53315B645FF9721D8AB0CFE54FF717157663B9098C2267633EFE3544A88014AD15C7B10A4551CB5F9BBA3D74946371B1AA54E6419CA7B4611149B5F02C73819A8C625AC52618F771202338AFF05969ED670BDD0B9DB562B8055884CBEA7A208A2DA850A05484C6B84109A5C2B498E8B8640ACC6F7AA6E1D7A95415469CC1C06D17176146CEFBA58E2B8929770851EBD6CA5DBA444548C622673DFBEBBC95767BEE2B86FF5BB37CF306B2945071EC1FA80C7540C56A36EB684D71C5E8B90AAA8C2421E21D64E0638D63C96E2B0BD9457BD5062199A01253D240C712315778AF487AAFBE28C650532A493C1B3E0251BC0841392839905AAD3D12289506742073862E8549E7E87EC28102DB7B89EBE91627CB95C0928C921978CB8C94875A94F1557498132200B4B76AA3C3AC9755C3B6BC5E5C59C9B3C6F7FB2CBB5AA457904FEFD2C370E29EEB2417BC45977BEA02A0DB9DE57937372298102755BA5B007EC88340B28AE7B819F9E07182F76070043CF3AA7E9256CF1CC3A6442B1726EB889CAB193222BCD3D8141843C1EF9921B8254712C04529D38846F595BC011B3288BCE0231ABC96985145043B579BB0864F40EBA6A66144E0972CDB10A71E44A088112B3C7907E5591D6EE85B34D4AF8DC58633081BA1A0A6EFE133B4C70ED215A22F451A7117B8C5F6A3D3FC4455214F5DCB8C31370546B4C4BA365A25017A9C2296AA641CBC4745BCAA72D17C9EAAB0155627BB45770D6D259BDF5B044053B4C7C8784FC433E89942B5D6C807A0707842CA4FBB98693303C118C9F4952123582FC4E22BB853944BFC1584810153F3AF5DBB74BB2928785C542AB647E9321D724AAC9EB9091707B5075C700A4817CAA2C355D4C99B8C5037B5288FF5279725BEBDAA5CE23609E5320981F11C8A116501D5ADD2D2B057C41E469257057B7A9C508017245C20C13A0C104FE1A517EE4621C367CE283183C07675BBE5895FBA4F30CC406772635982CEBC3153D046161C7B8BC4D87B648236263A44ED50B92DEBB624528C7A984C4C5047737A8021665279E9CF30069AADCC3F4A9245700436E646AF721A612828A07DC463D61B70223C7658F22190C83405999D92889CB0E5020052C31066665C4A021643C20764C370B9A5D1975D47646E1329072335432A19A03590B071482A3774BCA0601D8DBCC35A63742CD127F6384AFC6A971EE8CDD3E13687588D84C358A5537E753B2736840FD4E76A1CD0C68F9A990E5644404BBA84491E5F3B6F23EC45DF91538BD54070A702E69B66BF6C88CBDB8FDE693A2487681379A2AF94C592472FF167BD17966F9DF67E8FC51152AC613512930BA2BC2F453EEBCA91399B6D8F12AE891B3DEAECCFF120751866369BF8902D439D19F77B264002E5901B1C939FD86CA623277E6B09A72A93B52AB00754EAAA74833B8E366C8F0752639437F83CCC00F92EB7057C43AB94A75C31D5F854DCD3784920A36CA0C2DE244D1AE3A9E578B98E0634635549A8932A6BEC1F2EB321572A060EB110AF473F3E04323FD868A241891227222414C663285B05777BE82585DF3AB0ACFC121A642C541B3C3D7BB3157302EF62A1229156DB3609678B3B3E2576902145E5ECC78B65CF69BC8A7E6631494B804C4C89A9B595A8D95C039A9BA356670A536220C1CB54AC5BFCB7CE0125606A40C4EB4BAFC4C43BECFBAC84812F70C66796D6407F887CB0DB41F0FA7062E255896582B2B218FD96B6E5581A6FC26ED40272836950CB348AFE78CB135ABB6D015F299377632C72A7BBB2CDA7CBEC689E7551168483085B6B7426EB6967F729AD695D4E09C49B7A0010F80EAB54CBBAF4B641C956231663DB83512C97067CC7BFBEDCA93CC9A739A813B48C4793354C2DC642F869307AA191B77C2BC72BB048300B54906DFBD45255E92D81A98CD87149FEC3A428540D4E03C757260F3731CB7C4743A37194054AAE5FD6902D48A911F661EAD29321722E8243CE62E75ED82657423163A86362CAC2931954092909B0082BAD382A013A5044FAE9A12BF300670CA5771042933764E700B43259B130F033B023CBDA36815E2C6BC7C0601CEB7586A95DA4033E80E32123AB86C6135222EBAC0EDC17F5549D5B66760E07B2B16BA4FD8040E642990128A39A636B19FD3EDA4611BC1CDFD552AD1DB338FE3700F0920D56F3771F1733A4C185573FFD9BC77988A1458D28A64F15512217C7B95C24D7CF48904E638D8AC3662450E09D8500DED751060B7990D54F137508B9897277F65EA952" + }, + { + "tcId": 73, + "deferred": false, + "z": "7459AB99D24C1254EEECC035874BF19A64EFC8EDC9D369C11F5DF4DC83AB5FBC", + "d": "16858AA7C92EBD72FB8CCD0A99D0435EDB2A6EB1B936DBCB637CF43F25D221B1", + "ek": "379C74CE8940E12A1790659FD6C2431D7C1043A8049A3B0AC1000273A0A68EC34AC6435018C19F3A5A18CD28AFF1254C27E92E25149E488A5CF5C724873A7CDEE0182CB874E1564F6036CCC6E5C02FD19937D459ACAA589BC3706BB60E82C93047030524A73C3831232659565FF49DBAB60BC8C18E203B68DE7784D96B4C1969AD8F164EFD531F8A297F46425CBBD0C4E3C858A01982DD4686860B0253D1067AC66353F7554DF00A2FFC46858C6693F04499054458864A4A7AA82230A4B04C1EFF8A2B9C5B1A43F0038A027CCDF73EDA1B16CE878D14B27DBC2AA0019BAED2C86F9741A9DFF624071545A4CABBC2895D9E9602C1027D05EB1C70DC2365423A65740F777565503C53B31C9D7DD06DF115BC2CC1BA80D992D185C485A78FB6A0B725E2A93897CF04F1B421093FA098BAF4B829FED6CC07073F0D13502E430F892A5E344B431DDA1EC9270A0DB64CBF40CFDC78293826BF4701181594B89F8CA52F3168DB931E7242121A71747564AF2DF0312BA4659A8BA2106983957877673269313B953534824E035AB75A5007B7BB5832B37936683B23B563FAB86EB749819616AC467B42D4B11922A9719067039480849B13E125353F54179B5524C7B5905A673E54EC888614AFA7781B918951C2C30E89043119351965256B26CC5B8E1973C1E838C6297D1305D02351A1C2E394DDA666D918545BB8CB69CB8141645AC7CB606A0500E0F94961CC8B33A5250E191169C3B4CBB927438764B356928431A7D5E73067346C9EA02D7F687A9DF1BE9018473CC7442F801B43F2307FD2380329C5D3DB8802823864A8895C0262A97547682A61A1652F4611717C09AC6DF8886D67B1213739DCE29271F65564CC642851005E224D634C996556AE35E3CCA9A6C746F7609CBB526C9B9CB144CEF1F39DBCD11207F43FB7296193B12F1E7B043DAC724FF9A32581192E13166FC91F10CC5330D6A7C4F04BD3248C61D227E70543E041354D55B1E52AC1BDA0657ED3C6F5F3444B3775DE1B0C337409C34B75A5B9A58DA8B7445C2E3A6BCCF1E02A0C1A20DC619893E6370D35BA4CB615D5B2BF12885749865675B9A925B21EE138830E20B2BAD258349A44747A08FC962476A0A7A1676415539086A543A087737DCC8E2565161F8697043819206202AB240C00C496D5254E8B0610D6C55CE52B20B0F63D65092F95879736D989728AA6EC91588F60682512CC50BCAA756A12F13C6C502BBB6CF210A7877DE46831A1E91D7549B50AC391A439BCDF2135FE81C81B25874189726D77AF828876A4F34E19E33009B8217E511DB2A7724B251109646E112823242C964B933F8B4625EDCB1471DC714684045AE79811A56B113803EB272AAB94709421239B009C3D4CC8463906DE646E7374C865103AACD4190206C43BD2334D496005427FDA19CF31872A941C75A6B1663F6C57754CA0D9D8A23A1B9592A1B3FF76A035F89B72B29E6207D05BAC0C349608E71B2E4A3CB3EA7651A26B374CE516C787976691BE124AB671049F3B573905D19906CA6E9C5912F6311410CA3A7B25973895C0E8733557A463E311BA20191EB77B3EDDDA437BC75D5F358AC883B2E8242449834AB6F5ACBF0422ECB438AA4009BB678E88D033C701322DC01D0F9B47EC135A25CB2B491B7F45B33686788F603B28E0A215AA1AA49BC2B2B10906F70004DAEB16F4E5805DB455BD794861BA1F8D55BA6CE29591728CBA492B89255762B25DDB71557E8366601535DD38609652CF47506379673B0124796C3CA7EB384EA0830DBB318E553525DEA69187A2151A227016DC53684C1922A25A90107C64E04CE1C7AF8481A437601D7C4AA014D18CB397B4079C660736453B35A5BAAB9371F0B5D4F867CE15AAA8739F6659B12FB93667DA30ABA01CE923853DD26187BB20A845691AB48785B22767ACC0D7389BA260BF115873CB784CB4C715E67776759511DEEC2B565361B84A8833C7A16C16AA3F29750397B0ABAA9B73A580527100511686A19A7AE757833EF826F4D21E4C020618809A48B67156711E70D5171BCCCF997CC048BBBB2AE064FFB9143F66A2E81A9341831999D822AD947CE88CB153BA595D5B0EF5D08EB856929412B9D2E551C959482AB545B1A0AD8583B7C0D42A95A3A080B772C77424A1AA1852DCA0662BCBA7B96CFAC5B1B689F01A5CEAEB2A0D52EB0FE9BF752B36B37830846812FFB88D", + "dk": "2ED75F448A5247A0BDE73C1A09DA83F27512A9E1998A48C80A0962ED307C0F8C4D221584D3A90D6C7B003EABBA2A2013F4D74CEF9A84AD123E430B316C08AFB04A64EFB31278F4CFAF1156285679203A275B267AAF7786346B40566B5BEC24B122C89108683431D0A8E8531EC70116F648004A9BA3DA807E54755BB10B9DDE973DD1E62C1A6C752D09B18DC00178C52A6F0504ABAA2B3E54B1D1A495A9A38BBF29812C472D28A8386F04BC41F555263A8DF34536E1925434407B3F885F7349A2C20BA5F275BBA62039F77A0BDD236EE4A7205B660AC04A48D6EC0927EC8986C73539754545E96B3F681F461A5424B954C5C69F1899BB8301B0138BBBD934A764168951B0BB42043FC6A441BC329574C726E9D31286063DA4556C02087FFC473C3B4307986A59AA595139A46351FBAAC3E1664B5A4A74D5916EB3BCB0F570B330ADF4574A92589C782A3CA520C43C4BC7987367BC64B9EC1629C41C80223154FFA3161A158647468B8DC670DA26496FB53F1BAB59261B8B9A3A725AC992567ABAECD027856650A9D78FA4656E3BA89BFEB80F7007562AC84EAB2917E18432CC5A4BCB969DEA5C73F1AC620612574F3106D1646FC266959723004C425BEA6B8B8E6326365C540C2844F666A482116D16C1272D90A439567706159C90623B1A79B62B14860926568C32360EDC9C868211E0036C9A3979B6F39126A150A9259CABC8631D9214CB43A8564A6DDBF785AFD44EDCCC7D2428A92766AEBA969D9E065D05E772C6DA572F9B0A7C5A7C0E54020B331CDF321CE7E48EAD96C4EE5062509113E274578F50A7AD131641BB3CEC76CA79B39529F92886B40F22086A6F527623E37797F1009E082277CA420C3310C0F35F2BD61776B8C5FCE14136DA388FE6CC37F3A7496C0062D0ADDC91B8ABA38817F45A7996AE0F7BA41D32C1FC255A43A6BBD9DC6A65A6BB72A306A3446418A77BC58C1D3B1B05437C6F85D01A300C9FADBA40F8F4B8DEA2CC358547165A467AD12BEC5C80C4F7AD6F308550B419BB06AE54CA29011A55502215CB0397C005544404B9A413CF74F5AFAA532C909A3D00FD37146721FB0B35363B9C52B71511D6C45B719E33CC43E016770936BDF6D2056AC21FF65CC813321144B98C965530A80654EFB350EF973AD505791766BDB4734C3E1A0394A89902416C3DE269B9A99E4B6CC39D64BCFAD64A552728905882278A238B214B94F62856C14C6294B8FFE80F3E62B3C91A687503094C2849BE8254314B56CDD35617D61F27C9960388811C830290808F9D0B2DA6AA4728606F55CABCB92AA9384CC3E03537BAA41BE636C7EFB036B5114019E40C74984884DBB512D61CC8A973D8E6C8EAD45E235C7E6235C181C062E82CBD26A2859BD9B510514D83114847ECA0DB8554663B1D74E5084460C396E43F3FF47D379A4574C77E8F1C11CDC5974471663244CE2EC399AAE83CF96889BE7628ED028E477C0658993941AB737861A9F8388AD1309BBBB23EE72181A1EC7BF445B1FCC5527E9C0F7D278362548131CB2132691E232515CB5C5CB6640E01F8B75D96A9E60ABB6929A7582219A8A8CCDAB2C4A03A035B8CB416114FF7604692427B35C135DB956F6BA796145CAFFB066663293FEEB462EF5C4D8C521B86436F011157245A891F233AA122C51AAA0CB0D5100B01575EB04B9A1B86D6A1808357265DA0570DDCCA2766C5802333C64B0D9E5A254A8645328C394F85B337A447F17753BB465F584462B40518705094D891C6143114522BA327547B61C928CF50758FA5C0C6FB2255A51E13E9AAC37000053C180EC7A6E597BF57DC656123793EC0CB24E9306FC0CA5CB723C8F46174179923E819A1DC760229018D7348AAD75263DA565129A39006299CD979BC73062003D0773611B07141FF2265F8E5583284201A4111F5719BD4397909D892AE8AA438121C5DCBABB9413194542E6D98AF6655871DF23C6A7A43B6B6C9D0790F53705F419B226497BBE92A3EC6315C6A443878B283A252423B13505DA298AE100A6E34BDEB734DAF0588BD54B2D5C1198C653B34A8C4D0447C5B6B137D203BB2612E46AC4B82BB97931550F3F835B57B8521828718498A3405C36A345A1323924221505906723847571C6985B0A59F1FE15C961B5F11630D04CA79FFE22F371A96379C74CE8940E12A1790659FD6C2431D7C1043A8049A3B0AC1000273A0A68EC34AC6435018C19F3A5A18CD28AFF1254C27E92E25149E488A5CF5C724873A7CDEE0182CB874E1564F6036CCC6E5C02FD19937D459ACAA589BC3706BB60E82C93047030524A73C3831232659565FF49DBAB60BC8C18E203B68DE7784D96B4C1969AD8F164EFD531F8A297F46425CBBD0C4E3C858A01982DD4686860B0253D1067AC66353F7554DF00A2FFC46858C6693F04499054458864A4A7AA82230A4B04C1EFF8A2B9C5B1A43F0038A027CCDF73EDA1B16CE878D14B27DBC2AA0019BAED2C86F9741A9DFF624071545A4CABBC2895D9E9602C1027D05EB1C70DC2365423A65740F777565503C53B31C9D7DD06DF115BC2CC1BA80D992D185C485A78FB6A0B725E2A93897CF04F1B421093FA098BAF4B829FED6CC07073F0D13502E430F892A5E344B431DDA1EC9270A0DB64CBF40CFDC78293826BF4701181594B89F8CA52F3168DB931E7242121A71747564AF2DF0312BA4659A8BA2106983957877673269313B953534824E035AB75A5007B7BB5832B37936683B23B563FAB86EB749819616AC467B42D4B11922A9719067039480849B13E125353F54179B5524C7B5905A673E54EC888614AFA7781B918951C2C30E89043119351965256B26CC5B8E1973C1E838C6297D1305D02351A1C2E394DDA666D918545BB8CB69CB8141645AC7CB606A0500E0F94961CC8B33A5250E191169C3B4CBB927438764B356928431A7D5E73067346C9EA02D7F687A9DF1BE9018473CC7442F801B43F2307FD2380329C5D3DB8802823864A8895C0262A97547682A61A1652F4611717C09AC6DF8886D67B1213739DCE29271F65564CC642851005E224D634C996556AE35E3CCA9A6C746F7609CBB526C9B9CB144CEF1F39DBCD11207F43FB7296193B12F1E7B043DAC724FF9A32581192E13166FC91F10CC5330D6A7C4F04BD3248C61D227E70543E041354D55B1E52AC1BDA0657ED3C6F5F3444B3775DE1B0C337409C34B75A5B9A58DA8B7445C2E3A6BCCF1E02A0C1A20DC619893E6370D35BA4CB615D5B2BF12885749865675B9A925B21EE138830E20B2BAD258349A44747A08FC962476A0A7A1676415539086A543A087737DCC8E2565161F8697043819206202AB240C00C496D5254E8B0610D6C55CE52B20B0F63D65092F95879736D989728AA6EC91588F60682512CC50BCAA756A12F13C6C502BBB6CF210A7877DE46831A1E91D7549B50AC391A439BCDF2135FE81C81B25874189726D77AF828876A4F34E19E33009B8217E511DB2A7724B251109646E112823242C964B933F8B4625EDCB1471DC714684045AE79811A56B113803EB272AAB94709421239B009C3D4CC8463906DE646E7374C865103AACD4190206C43BD2334D496005427FDA19CF31872A941C75A6B1663F6C57754CA0D9D8A23A1B9592A1B3FF76A035F89B72B29E6207D05BAC0C349608E71B2E4A3CB3EA7651A26B374CE516C787976691BE124AB671049F3B573905D19906CA6E9C5912F6311410CA3A7B25973895C0E8733557A463E311BA20191EB77B3EDDDA437BC75D5F358AC883B2E8242449834AB6F5ACBF0422ECB438AA4009BB678E88D033C701322DC01D0F9B47EC135A25CB2B491B7F45B33686788F603B28E0A215AA1AA49BC2B2B10906F70004DAEB16F4E5805DB455BD794861BA1F8D55BA6CE29591728CBA492B89255762B25DDB71557E8366601535DD38609652CF47506379673B0124796C3CA7EB384EA0830DBB318E553525DEA69187A2151A227016DC53684C1922A25A90107C64E04CE1C7AF8481A437601D7C4AA014D18CB397B4079C660736453B35A5BAAB9371F0B5D4F867CE15AAA8739F6659B12FB93667DA30ABA01CE923853DD26187BB20A845691AB48785B22767ACC0D7389BA260BF115873CB784CB4C715E67776759511DEEC2B565361B84A8833C7A16C16AA3F29750397B0ABAA9B73A580527100511686A19A7AE757833EF826F4D21E4C020618809A48B67156711E70D5171BCCCF997CC048BBBB2AE064FFB9143F66A2E81A9341831999D822AD947CE88CB153BA595D5B0EF5D08EB856929412B9D2E551C959482AB545B1A0AD8583B7C0D42A95A3A080B772C77424A1AA1852DCA0662BCBA7B96CFAC5B1B689F01A5CEAEB2A0D52EB0FE9BF752B36B37830846812FFB88DD27339E75E5E384EBA68A71FE2E52EC7AB0C15CFE33BBAFC892DB62D84ED070E7459AB99D24C1254EEECC035874BF19A64EFC8EDC9D369C11F5DF4DC83AB5FBC" + }, + { + "tcId": 74, + "deferred": false, + "z": "4CC1CA6B662A4CE499EBE66D933CEAE58EE244CBDCAAE3C1F45A0D6947802B76", + "d": "F788F3E21D62E74090582F310BD4FDC8065E56E8D946142B9B9CF8F338F330E8", + "ek": "26160EB381AE1A868F10FA05934958B39790C5858085A82036224D2455823F11A3A5C537DB483A3AA7725ACA567CAC610B4618E3CC0381701FB60917F5DA63CF712618535210D102238A5768F876A17C4437AB8789662F426C5CE69258C3462D70636CD556AD9EF0A2CD9C1DC3C546A0B396CBE2C94BB24C40756815F796AEE7045B6082DCC49EA56849C639419871C480185E51E4AECFA1945DA10B43C366916531ABA8A01502881B76C6E6984F7EA6058DE460C1E3511A06631670B35ED6A8D5D7BC6589A62DE377BAD1582C085A3DB3BC47F176A27604035B9ED13853758A77AA1391E881214894013F1BAB687A699DF18B373A64073BCCBEE469E1C867D221C4675791F40102E1E2B12593152C87A47A9367833854EF5427DE49043308586673274DEA8C2AC8AC5EF5886D06205284831170BC6B9C0844248DF1CB40C5B627A29421AE900EF5F5666720304520ABD826AEC0476E0D32213D550D55442E863B0FB8ECB85A1CBDA002792F6C199838613780BA4CB22605B30372304F88897EEDFA09B6B0C4B4892C0A05746DB80F602C016230129C2B0C83351413D4C2197B92E608485301BFA2EBA2BC5C2E1EFB42109B0119F079560A87F01BC6CFF916E81A1AA4F520C0687C41C91A3BB5C4C1D712449C6E927C0490B2AB4B9422BF5655E332C4A1D1626E587F085A631C250C122537F5B213A0C231DC48CA7B88A4C21706FE701645F43A8A00CFA0F0A13900B3FB5C1B886C66F22520FD685AD0CC396991B0ECE81635BC27AD2813FC377E7A542D9A9602E22775CA34CE85B834ED755048286B82692E3F9AA15E89A8D8568FA2AC47AA32C748582B7889B447C079F404329FE03066E8A46412820EDC8B8878840DE54C80CC2851E08374A89FE8F7417CF90638726ECA61072C893CAF8C501D04CFD2F3BFFC094503234693C530A732324C0516E412137E2B39AFF1292B925205C972F1B6805E67A292B069E8CA73FFFB1DD2B1A5FB2057ABB67ED396494D123D05A579C23263B47ACEAC5862982B20E6BC5E32E03BCA175CDD8996044AA9D90B3A0488500DB340C06CC9B84749B4497AB6A3CDF05B58FD5850CFD911B5C58819D2444CB9386B18784762B16DF6BFBCE86BEDC9CA6EDC191171C88C5060648B419109C5BDDA9A7E98C48B1649B342B7ECA411959A9D62E5C0BEFC5B62F4BB6EE608CA18B43AF78784B8C7384ABC77426B5CD28EE70B93F808317230A686900C83512E2A83CD10749C3E5B7EE6826C1E01CC5FB27FC47B52DA462AE5EB65390A1A33CC9749941D530210AD070AB71487C2176B17621ADB11CFA1F3AA9C379C9FB0CDF00186608246C56584DB61AAA8C157A28B6161F23EDEB7365928C1EA8C962785C338E66FF1897B56154475E17F81C9845C4607E5294E21EA23EE0CC47E4BB9D3539D46D410A3149E098B539B196A2C90C06D5C103AAB08E1110D3F565AA8CC7E4F2167E6969BEDD5C3CC8A6F68F53E18931F8EF0723FE33A2789661C248B15A35ABD5919343AADC93BC6777539E952A3F49A3E34F51291709F6DBCBDCB65B4760B8795B7985DF8249EEA132A473CAB736E72D45A2A100FB560B70E600EB24AA596879F1B1A9DB705AAA489791A503E9463C19EDAA4ADAAADB77A6FB0BABE16973E63333F03B444C85C980D55727532765397B84870BB759469CEA72E28A75BBA8A5098B6A95750ADAB54361C802ADEA678FB6733D3766F7C50BAFC081A384A768E60AA2E6648ED81612778033C6038E7863887F19C1509518E61ABCFF77F1ED9459D10C53C0CC6AD60C95704138B9C579317714F393AE8287909ABAB7FA167B8B237CA52056A199D7558AD5F16821DD364B11B9307421D362BA42AA3002AD2025E347BCD7223EE4BA62C354C1CE9822C8C4B3B70A1708462453292C73ABB177949EA3106FE3075CBA15E2E143DD13A6600E55D801A440004621F6ACDC3CB8D53236FCCDC15B9F9CD321398AA230DA6722DDACBB98106367B3723FEE198E1AA7161C004C9BA1840F19721AA7D99B99A7057B1B33A28F2033904750ED1899551C1C8A9132D86B3781264CAC231C3A21440580A92F4C683CA90BC1CA78CE41B332EEA7D2F461425C9B91FB6867B4270AB785329218D74356A3B8423A044C3C6653B09E60821A1CA6032A0BC526228F18B9E38B3A7B69EA6C1C5C0C39DE56DA9763517FA3F65CEBED43C7B61282772DBC9", + "dk": "A0CBC9A9EB303971AE19D11CB1023CAE83B0578A8BADF6BBCFB444000041941120984930702ABE4D0442E79921D92CCD08364112D41433013110D74ADF2B53A8164582F56E2DF03FC1D283424A16603CCA86C8BB3211030574553A221A4236817DAB9935899201465FCED39A2E0845DDF09F2B346FD3FBB2B6EB72C7C6CB8EA1784A010AC17A79041408A1B7853BDA03161A478D48AC4D19C32F728C36D2CAC5C4784449A0BB5C02C4E506EDF7A7A1A8548F931FF36014A8AA651527A4AFF04AB5E52A29058DA78388192BA72D17A9F3428E784999C9F59ADC561CA971021C7C9DB552926D572F44F9B2B014ACA32A267EFBCB62D1962F48B6D867C12FA25723736088E80CD3024A2610C727CA96AA8C495A8688DD4C5F804C308D4A1693E6B2C676B3B44C127A4911F8522308E20EB5E816A8949D93303BBBA150744511A9C23259F663AB3444AE787FF766A3D76859637588C21634F7338FE98596911A92E1692E75D66CF37AAD1C02720DD47315B1AD9DA95AEDF383D6863D7F06214E626B3299A5EEA648CAC40067C5C271A81A8328C7612858BE4C736ABC35E3F982CD84C596685A3F974D61F450D130C1159993BADC5AEF7B71F9E1503BF2525FD2B191E95E35A852D65082928C47DD989646FC5FA9E92292EBB03FA4B52473B57FF59E52ACC2311844C59104F51147CB600D0DFB42205A225DB32CE6843557F61E3199BE1E8A237AEB1240B51113233C92E453FED3138501327948A68373457AD6271ABBB6CCF860DA15241F89C27D5074B6A7170407B3024708FB3689318AC024E0CCA2836D3D786737D298CA7559FDA75F38CC8CD3D4845A165E18EAA56547928B0875AF564F763C365839879AEB3962F520D37755A17983826843E55567CF2B45F2B59D716666528256651694FD4B5913D90A25637369779991E9246E6A59EE1437D7DBB62466A759301CD0F4CC551161C2662E0D0992DDF07CB4BC61EFAB0D4F81700C0694F971AF7CB0974367AA53A8A914770D03892B639746AF79179AB8405C08A5DF9525E5958D26C4543A82349A192A86D3529F660BFC49490B2147D9170FB5CB78FCB40863550E9AC42DD3215A2D86B3F3A4B0188A9F7F02949CA48A63DBA56224B436B2C22C085EF826AB521B0DBAA4A7ADE8355FA3C4BD708EA1AB68B1FA714D5841208BA9CF3611A9854F69A21E1B67C84903CC382B3663ECC2AA4B069A8639618536FB6B562CCA390C103645D9A06481666E92C1FDE91AD8291596286501B154C8E3AA6E0608E4CA6FB1512EBD25C9EB789E7765B342AABAC415B7B1E65FD38ACC880C61E1C01E96BB8FAC50972D536D49A20B46BAA303DAA481A39D68C71286495F248045B1B82020544B864C3E1951812D01169B4AB79510A284F058CFBC963431BA0FB7209BE995672A264DA3A6EF592EB121093D9B09F35A94BAF125C4F61508B1C339C6B58C5BA65A207571191253C3512503C400C70BEDD9859E363A7A1193CBB2C222782B77B62CDDD09F67BA9F4D632930E73E08F37F24279965C74BB402439E0A8289A43630983BAC924D0261BA07335B3F734428F538B2803DD47B26B2D5183533807CC43B67E79680E6C5E60709406B04548781CF497E8B890423F42186292FB8C988639C2F6DACC513014B91EA2D54393CFF768ACC42504DA84F21A21D372A2C7935334654856BD66C77423F10501CBCD39907EB7478FC0D7D0439C9739B43A363E324B319B219BD25BC1153AABA81B0F6A84B1D5A8C92885EBAC488099BCF47E91C8E4AA8EFACC0748B25B2969EDE004B4BDC3278B139C2445CDCA181FF8A3FD20777DA97CA9D182AC494336D424D87B53402596A0BA339611B5EF459B87C0163744007B008467387B44A680F3D916C8AD9352D7B6643509225874A05E03D2B0297739592AAA37772472162393CE7238482B51E8B6297E665CD9FEAC4B8664BA62CAB68FA25DA4459816922AD50AD06A347E40C4E5E55CF9A5CB738343DFE222FE46349E68A6526B1B1AA8CB5549BAEE622C2DB3C8806AB22F3C92449A67D3C7C5AF7A9C970839AA386A6D5518E00D8B11F42002F52C873DB6A4DB50047F815EE15C3D017676857023C57A017E431CE8555CEBA2BF48950F89095C2D278A1330D9F9416BE6442EC49A21C79BCFCF832677A4CEC8ACE26160EB381AE1A868F10FA05934958B39790C5858085A82036224D2455823F11A3A5C537DB483A3AA7725ACA567CAC610B4618E3CC0381701FB60917F5DA63CF712618535210D102238A5768F876A17C4437AB8789662F426C5CE69258C3462D70636CD556AD9EF0A2CD9C1DC3C546A0B396CBE2C94BB24C40756815F796AEE7045B6082DCC49EA56849C639419871C480185E51E4AECFA1945DA10B43C366916531ABA8A01502881B76C6E6984F7EA6058DE460C1E3511A06631670B35ED6A8D5D7BC6589A62DE377BAD1582C085A3DB3BC47F176A27604035B9ED13853758A77AA1391E881214894013F1BAB687A699DF18B373A64073BCCBEE469E1C867D221C4675791F40102E1E2B12593152C87A47A9367833854EF5427DE49043308586673274DEA8C2AC8AC5EF5886D06205284831170BC6B9C0844248DF1CB40C5B627A29421AE900EF5F5666720304520ABD826AEC0476E0D32213D550D55442E863B0FB8ECB85A1CBDA002792F6C199838613780BA4CB22605B30372304F88897EEDFA09B6B0C4B4892C0A05746DB80F602C016230129C2B0C83351413D4C2197B92E608485301BFA2EBA2BC5C2E1EFB42109B0119F079560A87F01BC6CFF916E81A1AA4F520C0687C41C91A3BB5C4C1D712449C6E927C0490B2AB4B9422BF5655E332C4A1D1626E587F085A631C250C122537F5B213A0C231DC48CA7B88A4C21706FE701645F43A8A00CFA0F0A13900B3FB5C1B886C66F22520FD685AD0CC396991B0ECE81635BC27AD2813FC377E7A542D9A9602E22775CA34CE85B834ED755048286B82692E3F9AA15E89A8D8568FA2AC47AA32C748582B7889B447C079F404329FE03066E8A46412820EDC8B8878840DE54C80CC2851E08374A89FE8F7417CF90638726ECA61072C893CAF8C501D04CFD2F3BFFC094503234693C530A732324C0516E412137E2B39AFF1292B925205C972F1B6805E67A292B069E8CA73FFFB1DD2B1A5FB2057ABB67ED396494D123D05A579C23263B47ACEAC5862982B20E6BC5E32E03BCA175CDD8996044AA9D90B3A0488500DB340C06CC9B84749B4497AB6A3CDF05B58FD5850CFD911B5C58819D2444CB9386B18784762B16DF6BFBCE86BEDC9CA6EDC191171C88C5060648B419109C5BDDA9A7E98C48B1649B342B7ECA411959A9D62E5C0BEFC5B62F4BB6EE608CA18B43AF78784B8C7384ABC77426B5CD28EE70B93F808317230A686900C83512E2A83CD10749C3E5B7EE6826C1E01CC5FB27FC47B52DA462AE5EB65390A1A33CC9749941D530210AD070AB71487C2176B17621ADB11CFA1F3AA9C379C9FB0CDF00186608246C56584DB61AAA8C157A28B6161F23EDEB7365928C1EA8C962785C338E66FF1897B56154475E17F81C9845C4607E5294E21EA23EE0CC47E4BB9D3539D46D410A3149E098B539B196A2C90C06D5C103AAB08E1110D3F565AA8CC7E4F2167E6969BEDD5C3CC8A6F68F53E18931F8EF0723FE33A2789661C248B15A35ABD5919343AADC93BC6777539E952A3F49A3E34F51291709F6DBCBDCB65B4760B8795B7985DF8249EEA132A473CAB736E72D45A2A100FB560B70E600EB24AA596879F1B1A9DB705AAA489791A503E9463C19EDAA4ADAAADB77A6FB0BABE16973E63333F03B444C85C980D55727532765397B84870BB759469CEA72E28A75BBA8A5098B6A95750ADAB54361C802ADEA678FB6733D3766F7C50BAFC081A384A768E60AA2E6648ED81612778033C6038E7863887F19C1509518E61ABCFF77F1ED9459D10C53C0CC6AD60C95704138B9C579317714F393AE8287909ABAB7FA167B8B237CA52056A199D7558AD5F16821DD364B11B9307421D362BA42AA3002AD2025E347BCD7223EE4BA62C354C1CE9822C8C4B3B70A1708462453292C73ABB177949EA3106FE3075CBA15E2E143DD13A6600E55D801A440004621F6ACDC3CB8D53236FCCDC15B9F9CD321398AA230DA6722DDACBB98106367B3723FEE198E1AA7161C004C9BA1840F19721AA7D99B99A7057B1B33A28F2033904750ED1899551C1C8A9132D86B3781264CAC231C3A21440580A92F4C683CA90BC1CA78CE41B332EEA7D2F461425C9B91FB6867B4270AB785329218D74356A3B8423A044C3C6653B09E60821A1CA6032A0BC526228F18B9E38B3A7B69EA6C1C5C0C39DE56DA9763517FA3F65CEBED43C7B61282772DBC9C49E09D937D24CFD29FF7B285F7B478AE4E219BBBD89A54C8B127CB0C65803144CC1CA6B662A4CE499EBE66D933CEAE58EE244CBDCAAE3C1F45A0D6947802B76" + }, + { + "tcId": 75, + "deferred": false, + "z": "D16CC70224474A4D71E1F950C2D5CA72D8F08AF80E0C7F6E292C265A50CC30E8", + "d": "A72608DF0F025B4FEE7D94BAE77BE94CB974F20DD55006A70FD39F3397A8EF90", + "ek": "44AC5FB94668AD165BC9B4B09C50148831B0BFC0563D97B66913AB32846C9206BD2BEA024FB44B6DF239A8A82AD42C5BB69A77A3195AB8A7BD5C3131C9079D05E248D84167B6F569C812CDB1212F0584AEF9C0251FFA0E23A407BD592C7829C5D2A673DF01696AF02DD2A07A9342157EE608A2A91241DBB3F8725CD5D8BDA020C9107747F82A0FC7A97AC30272B694257B135095B27481CC769BB0834586CF70CAA72C2696B105A4B6440FB4D045B61A3D0BDA48490B22CE215C985B313F7C74155015A7D079DE9A2EF4DAB3ADD1A1CB684CA377B428B90D2BBB0980249586056434E2088EE250D065951EF228362B1D8028BC793CC8DCB8805D86C5DA71B4C1396158C79711DCC2F56359D197ABDB890387FA795ED9288FD08851CC620D0357A3450B4C50CF61EABA54A44FD61203F557946027B36224148EB4AEEE709401296BE0B617604B6A48244938279D66CAC75F03809ED49421F518A3270F42273E37793D6162B626771D69C8A27AF27AD0A3B89B6C756068565FB65D245A88D180741A1AA507E116DC504C11358C7EB444180792D210438F96CCB3DC17D8E8B8E79918A106787509B8B570B093C325B8CB81A12A686CACADA32389B8207108E7AEF5447217843932559F1893B250DB8060D068D6D2B06999C36F412D47519C795A7284E3CDD42CA6304C348AAA96E72B8C64C37C92C34F78C56A58B32630812A95F53FFE4B3987B5146E0321AC254573933D03E7356628727F448CF3D9A328C1CA72B59B73AC3F0A3671FF58A604AA5FA7F63ED7C72965A833B5916266796757186784882CE8670CE4F717F057A1C08563B9832B89A759F2380C74821379B343E7E28BEAE6334CDB896587C2585508A78947A54B08055C3C6CAC9357102CDAE58748A337D511BD0BE93C88964720C3AB5367478A4BB82FC148539C1D54F54CD7B1605C113D4E526BEDC4CD8526892198336F344B1A59A83F3ABC890C9AC386954A6B521FC76FFC03B614C32E7F68868400142BD041347614A80A7A59F2511A28B1E6F74053842C8F0A49FA17C378FC0992E14282E394034081AA4164C2E9934E5C8246E334AC606B9BA723237144AB2AAA8E86B2ED33B6750CA239F82C9105CEC46888BD59B2AE6331F47501C01805BF867A63F1B211306009C7B60FE4AB7EC5982B1955059A5D69BB728FAB31681CB0418C033B676158501FD3011A3B6B44503378C2FA1C6EC254861532DCC16F78D743DD065C8F8781F798633B0CAE5172173AE78A02DA472C0BB4DDCB2EC88B70E69C24FF277837646802774C98D87ED20382E4A82C0EB905CCAAA977295AA085A26717578E04B27139B98D260155C0B6189A3A6AA77D0CA76B6409032D3868967C1A5B5AB747B2B1660715F15161E00C383B957062509C495C5B25C26B2EA26B3A74597B913D295728B33A9EC914A2E646ADF0968E07592E48BA1BF0817995B321F05A7DD8FA892A385ED4C052B0CAB7C84945FABA63F2099BBD960843F4ADB512A48991A38439B71D291512333483E8A511FB925A7A770E033EFE6A933F105DF2B5555BE5179F3B8DD8F216B0EC87AD297B5AE941BBD80BFB0A417824A420489CC9281DD1D545BF15C8459627C4E8684D018473EACB1C49C27564614417A9EF6984D708B1FDC03F08453A769C470156884DCC30C18A1970022B01CA2DD0928F50404A9B19CA41FC8C325323EAE97C484015289A5383B5A46DA19641A99DB8763B8E716DF656204616B07BA5C06EF11ABD428D9EC989D848A8CAF65B4CAA41A4F741A497A08EBC2FF8525149FB029FE867939255AB836DB23C87BE120559A99B64F4BE533C6F914149C45A221BE8A3F9C724FC9BB5782C9489346ACCF5CC69A94734C2AB332A272BF135E507163BB3019D9544151A56C1892706F86D40439BF311AC4A477BE17287F829015CCA7A2F416AA178493E9CC86E607C2266924256377E3171B1610F6CBC4654DB870E2A1A2F11774F6147810A44523036EEC6211410091AF54EC71ACC0212BB96CB3CADE37C55A67A3DDBB12FCB6E6DC758EB8B807F75CFB4E4AED460A67C9546C9D668E8F1A560A80D20707AA6A0CE9433BD8D283BCC743FCC9C9D23719C1A05A874339C80F079A5364842AC0F21F804B9BB5D6FF4387D19442C4BAD15A31FB9F5C9A5A0CF4C59A16FA309A69AAAC01C9F1F8817AC8B7DC0153478452C0A379D65A78BB3307E3CA4", + "dk": "275C73EE58A9FFD22DD3EB2B1590CD79407D35E950370892C6B2AAB97392D8200DA10AB7188B9909B191D32073926860F5F5A4D2C21C52F4AF2EF5066BF182A7156D0400319CB462CEA5A2C65126943158823B085B6118449401D5C17A67D9A0CE2C5FEEF515787A423C7446EE795C14B61D33AC8BD06A3D8CA5A78AE5A4BCAB1E5BAA336A4B8DF423A9072A511A98993DF205971C70D84CADF5ABAF5917741B34AE09D280375819059618D748AC48CB425EC54F7A7435C40442FD594EB1C081AE4A80F9D023FDC968968A482BE95A9CD03041CB8B8F3918A5B7957E5CA6C95053A55CB7DA014B15425C6637000C131A664318834C09DE92BC04172209D945C97AAB3240A93559569D03793560AD9C552FBC467516556E4A07A1DCF2A2D2C5332E5074128207E4E4491A8866D760791A18CBC7939835F02DDEC71964428D80AC730FCBB0F0C206434746F75C2A4D95CFD4C398507729845C257D17549AA2983290558453445C3CA35B6BB139B007B003A890996ABF463D5E12CF3DF0728B8259A7854F6A06999C92868AC16C9BB78F571972AA122975C25A68C31B73710DD2EC07C2103BDBFC1A67E7370444CD2394913218816AEA4E1043BF53B83377D4775BAC602871C79A28AD930316FA091E5678582A552B6A5CBEBE25CB6F9C9002469E29F1833FB049D2CA7040499170F4B6BE2915E7C10081DB012DC8B9A8AA2F1FA6A6D3FABFD49B7873C234A21B0C9B572401F80908D7370C4A5BB1D04CF9218CCC5C8BEE0660CB2ABC39501E3F2AA441168B6BC9435A9599EC571D39A35B49FBA16DDC4A3C88828D4B89390B77006026E85A46335354B2B422DE7AAEF60087E2F975A7453FDD6C56B75181F317969F95B7A024A1AE12B66FDBBF27186BB0C0896DE69C5DA5AE4CB638E43A8FA8C283B92687DA372AEF4569826803613824A5DC288E94345209A4D2B42DCF2A251917735636669C3AC06E72A835042504CB6A83026CA4B1A10DB29F9C229575599295881A7358C5949469ACC8B43AC80B4D0CAAB50846CC999B42E0299159049DD370A9B52878AC4B64547E3EC070B4D370B19924D90C6EF153232CF12E64D0BD04E124C55CB2B8D1376A46CE2B91A225985F7BD72D3B316767B3BD3206C5C8B311122300225A02F0E53664CB02B1350859D579A09710EAB927C5207256AC1128C6B0E09C7BBA408A2DC34C1160A8B13766BAC2A747A6BF20B1A6A22992451BA49CB5B97F7597F98B95E44B9B598AA993073ADBD6A9B5C81E10E21AAEA573A95A6716A3298412BE1D661746BB81C2F17744D587E3522143091FA215AC2D9B7C3C00397A1C3807F24AB4E968B0EA1A0E5A6601B7274469CD1A52AE5FAB7BAAB3C4A6D1A5D27A873E21A14DF52AE2C344BFE21B0F8A71A0511828E86F1FB08141C30C842538C61C7ADEB9251E33C73CEA9E7C02CF46E3C3E548355643000D3B715F339DE10745141B8D2A201A4D8C514185A6DC06375E35750E246D4CF1C8937955631CC7350CBC4C34C22B35C4336B95A12478419B8309E0137317B6CCDBAF70630BFD711783087967A93E1F95321EC319CA31004CF677D44359465564A889193FE04A7F8944EF30B5C0B43903279F07E2C04D116BE8322E9FAA4FA2562025910A264A814EA488D72CC03EB5853B40A406E1A7631933EC725D4E71516C751C3C0A3560BC0AD97078ACE63E9FC41A0F2B92B6E46A0836A39AE9B67C6B6F23A2A098987F3B6500ED179C6F14A0E0564166C5CF5C322A1E5654F8E083CD5B13ECD761B727020CDB5EAC5B9DF509AC0D9BCFD2A2976E586F90FC3949AAC845440FB929B9D5743723926FB2E6290EF3ABE663565AF1CC74587CDCB3034F7692D9488142231BE8651C5280A52EF048FD4C1C776210A39463CA0127A2F9065D6AB320E253A1A0C596E8797887844D8471A32795E6DA8D5774648AF25194C3AC8447C534B61C77F364D3136FB358861B05465AB09077912F536500F35002DF56015441A341E30D6458289F47B578B1BFE4C574228B0D16890108BA7D4DBC7EA8C9A5118AA6F6E48ED8E19B19F6629114551442CAB1E88541F09E85B79E123C912C967CBD4C273C47485EF552ACF2744AF83D72007137342D33A00F41EC9E0FE8AF0B641AC0F3BE42984D4D9C2E4D9393AB9992E78913A7DC3444AC5FB94668AD165BC9B4B09C50148831B0BFC0563D97B66913AB32846C9206BD2BEA024FB44B6DF239A8A82AD42C5BB69A77A3195AB8A7BD5C3131C9079D05E248D84167B6F569C812CDB1212F0584AEF9C0251FFA0E23A407BD592C7829C5D2A673DF01696AF02DD2A07A9342157EE608A2A91241DBB3F8725CD5D8BDA020C9107747F82A0FC7A97AC30272B694257B135095B27481CC769BB0834586CF70CAA72C2696B105A4B6440FB4D045B61A3D0BDA48490B22CE215C985B313F7C74155015A7D079DE9A2EF4DAB3ADD1A1CB684CA377B428B90D2BBB0980249586056434E2088EE250D065951EF228362B1D8028BC793CC8DCB8805D86C5DA71B4C1396158C79711DCC2F56359D197ABDB890387FA795ED9288FD08851CC620D0357A3450B4C50CF61EABA54A44FD61203F557946027B36224148EB4AEEE709401296BE0B617604B6A48244938279D66CAC75F03809ED49421F518A3270F42273E37793D6162B626771D69C8A27AF27AD0A3B89B6C756068565FB65D245A88D180741A1AA507E116DC504C11358C7EB444180792D210438F96CCB3DC17D8E8B8E79918A106787509B8B570B093C325B8CB81A12A686CACADA32389B8207108E7AEF5447217843932559F1893B250DB8060D068D6D2B06999C36F412D47519C795A7284E3CDD42CA6304C348AAA96E72B8C64C37C92C34F78C56A58B32630812A95F53FFE4B3987B5146E0321AC254573933D03E7356628727F448CF3D9A328C1CA72B59B73AC3F0A3671FF58A604AA5FA7F63ED7C72965A833B5916266796757186784882CE8670CE4F717F057A1C08563B9832B89A759F2380C74821379B343E7E28BEAE6334CDB896587C2585508A78947A54B08055C3C6CAC9357102CDAE58748A337D511BD0BE93C88964720C3AB5367478A4BB82FC148539C1D54F54CD7B1605C113D4E526BEDC4CD8526892198336F344B1A59A83F3ABC890C9AC386954A6B521FC76FFC03B614C32E7F68868400142BD041347614A80A7A59F2511A28B1E6F74053842C8F0A49FA17C378FC0992E14282E394034081AA4164C2E9934E5C8246E334AC606B9BA723237144AB2AAA8E86B2ED33B6750CA239F82C9105CEC46888BD59B2AE6331F47501C01805BF867A63F1B211306009C7B60FE4AB7EC5982B1955059A5D69BB728FAB31681CB0418C033B676158501FD3011A3B6B44503378C2FA1C6EC254861532DCC16F78D743DD065C8F8781F798633B0CAE5172173AE78A02DA472C0BB4DDCB2EC88B70E69C24FF277837646802774C98D87ED20382E4A82C0EB905CCAAA977295AA085A26717578E04B27139B98D260155C0B6189A3A6AA77D0CA76B6409032D3868967C1A5B5AB747B2B1660715F15161E00C383B957062509C495C5B25C26B2EA26B3A74597B913D295728B33A9EC914A2E646ADF0968E07592E48BA1BF0817995B321F05A7DD8FA892A385ED4C052B0CAB7C84945FABA63F2099BBD960843F4ADB512A48991A38439B71D291512333483E8A511FB925A7A770E033EFE6A933F105DF2B5555BE5179F3B8DD8F216B0EC87AD297B5AE941BBD80BFB0A417824A420489CC9281DD1D545BF15C8459627C4E8684D018473EACB1C49C27564614417A9EF6984D708B1FDC03F08453A769C470156884DCC30C18A1970022B01CA2DD0928F50404A9B19CA41FC8C325323EAE97C484015289A5383B5A46DA19641A99DB8763B8E716DF656204616B07BA5C06EF11ABD428D9EC989D848A8CAF65B4CAA41A4F741A497A08EBC2FF8525149FB029FE867939255AB836DB23C87BE120559A99B64F4BE533C6F914149C45A221BE8A3F9C724FC9BB5782C9489346ACCF5CC69A94734C2AB332A272BF135E507163BB3019D9544151A56C1892706F86D40439BF311AC4A477BE17287F829015CCA7A2F416AA178493E9CC86E607C2266924256377E3171B1610F6CBC4654DB870E2A1A2F11774F6147810A44523036EEC6211410091AF54EC71ACC0212BB96CB3CADE37C55A67A3DDBB12FCB6E6DC758EB8B807F75CFB4E4AED460A67C9546C9D668E8F1A560A80D20707AA6A0CE9433BD8D283BCC743FCC9C9D23719C1A05A874339C80F079A5364842AC0F21F804B9BB5D6FF4387D19442C4BAD15A31FB9F5C9A5A0CF4C59A16FA309A69AAAC01C9F1F8817AC8B7DC0153478452C0A379D65A78BB3307E3CA4D4F2CEEBE65173867CDDEC350D15A72CF1FEE868A9B819DD1DEB4E7478C00DECD16CC70224474A4D71E1F950C2D5CA72D8F08AF80E0C7F6E292C265A50CC30E8" + } + ] + } + ] +} \ No newline at end of file diff --git a/test/jdk/sun/security/provider/all/Deterministic.java b/test/jdk/sun/security/provider/all/Deterministic.java index 66d674da9bf..11a5d4d74b2 100644 --- a/test/jdk/sun/security/provider/all/Deterministic.java +++ b/test/jdk/sun/security/provider/all/Deterministic.java @@ -205,6 +205,7 @@ static KeyPair generateKeyPair(String alg, int offset) throws Exception { case "EC" -> 256; case "EdDSA", "Ed25519", "XDH", "X25519" -> 255; case "Ed448", "X448" -> 448; + case "ML-KEM", "ML-KEM-768", "ML-KEM-512", "ML-KEM-1024" -> -1; default -> throw new UnsupportedOperationException(alg); }; g.initialize(size, new SeededSecureRandom(SEED + offset)); diff --git a/test/micro/org/openjdk/bench/java/security/MLKEMBench.java b/test/micro/org/openjdk/bench/java/security/MLKEMBench.java new file mode 100644 index 00000000000..a013aa1bab9 --- /dev/null +++ b/test/micro/org/openjdk/bench/java/security/MLKEMBench.java @@ -0,0 +1,1240 @@ +/* + * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package org.openjdk.bench.java.security; + +import org.openjdk.jmh.annotations.*; +import org.openjdk.jmh.annotations.Benchmark; +import org.openjdk.jmh.annotations.BenchmarkMode; +import org.openjdk.jmh.annotations.Fork; +import org.openjdk.jmh.annotations.Level; +import org.openjdk.jmh.annotations.Measurement; +import org.openjdk.jmh.annotations.Mode; +import org.openjdk.jmh.annotations.OutputTimeUnit; +import org.openjdk.jmh.annotations.Param; +import org.openjdk.jmh.annotations.Scope; +import org.openjdk.jmh.annotations.Setup; +import org.openjdk.jmh.annotations.State; +import org.openjdk.jmh.annotations.Warmup; + +import java.lang.invoke.MethodHandle; +import java.lang.invoke.MethodHandles; +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; +import java.lang.InterruptedException; +import java.security.NoSuchAlgorithmException; +import java.security.KeyPair; +import java.util.Arrays; +import java.util.HexFormat; +import java.util.concurrent.TimeUnit; + +@BenchmarkMode(Mode.AverageTime) +@OutputTimeUnit(TimeUnit.MICROSECONDS) +@State(Scope.Thread) +@Warmup(iterations = 5, time = 1) +@Measurement(iterations = 5, time = 1) +@Fork(value = 3, jvmArgsAppend = {"--add-opens", "java.base/com.sun.crypto.provider=ALL-UNNAMED"}) + +public class MLKEMBench { + @Param({"ML-KEM-512", "ML-KEM-768", "ML-KEM-1024"} ) + private static String algorithm; + + private static final int TestsPerOp = 100; + + @State(Scope.Thread) + public static class MyState { + Object[] encapKey512 = new Object[encap512TestCases.length]; + Object[] encapKey768 = new Object[encap768TestCases.length]; + Object[] encapKey1024 = new Object[encap1024TestCases.length]; + Object[] decapKey512 = new Object[decap512TestCases.length]; + Object[] decapKey768 = new Object[decap768TestCases.length]; + Object[] decapKey1024 = new Object[decap1024TestCases.length]; + Object[] decapCiphertext512 = new Object[decap512TestCases.length]; + Object[] decapCiphertext768 = new Object[decap768TestCases.length]; + Object[] decapCiphertext1024 = new Object[decap1024TestCases.length]; + + Object ML_KEM_512; + Object ML_KEM_768; + Object ML_KEM_1024; + + MethodHandle generateKemKeyPair, encapsulate, decapsulate; + + @Setup(Level.Trial) + public void setup() throws Throwable, Exception { + + MethodHandles.Lookup lookup = MethodHandles.lookup(); + Class<?> ML_KEM = Class.forName("com.sun.crypto.provider.ML_KEM"); + Class<?> K_PKE_CipherText = null; + Class<?> ML_KEM_EncapsulationKey = null; + Class<?> ML_KEM_DecapsulationKey = null; + Class<?>[] dc = ML_KEM.getDeclaredClasses(); + for (Class<?> aClass : dc) { + if (aClass.getName().contains("K_PKE_CipherText")) { + K_PKE_CipherText = aClass; + } + if (aClass.getName().contains("ML_KEM_EncapsulationKey")) { + ML_KEM_EncapsulationKey = aClass; + } + if (aClass.getName().contains("ML_KEM_DecapsulationKey")) { + ML_KEM_DecapsulationKey = aClass; + } + } + if (K_PKE_CipherText == null) { + throw new Exception("missing K_PKE_CipherText class"); + } + if (ML_KEM_EncapsulationKey == null) { + throw new Exception("missing ML_KEM_EncapsulationKey class"); + } + if (ML_KEM_DecapsulationKey == null) { + throw new Exception("missing ML_KEM_DecapsulationKey class"); + } + + Constructor<?> EKconstructor = + ML_KEM_EncapsulationKey.getDeclaredConstructor( + byte[].class); + EKconstructor.setAccessible(true); + + Constructor<?> DKconstructor = + ML_KEM_DecapsulationKey.getDeclaredConstructor( + byte[].class); + DKconstructor.setAccessible(true); + + Constructor<?> CTconstructor = + K_PKE_CipherText.getDeclaredConstructor( + byte[].class); + CTconstructor.setAccessible(true); + + Constructor<?> ML_KEMconstructor = ML_KEM.getDeclaredConstructor( + String.class); + ML_KEMconstructor.setAccessible(true); + + Method m = ML_KEM.getDeclaredMethod("generateKemKeyPair", + byte[].class, byte[].class); + m.setAccessible(true); + generateKemKeyPair = lookup.unreflect(m); + + m = ML_KEM.getDeclaredMethod("encapsulate", + ML_KEM_EncapsulationKey, byte[].class); + m.setAccessible(true); + encapsulate = lookup.unreflect(m); + + m = ML_KEM.getDeclaredMethod("decapsulate", + ML_KEM_DecapsulationKey, K_PKE_CipherText); + m.setAccessible(true); + decapsulate = lookup.unreflect(m); + + switch (algorithm) { + case "ML-KEM-512" -> { + ML_KEM_512 = ML_KEMconstructor.newInstance(algorithm); + int i = 0; + for (EncapsulateTestCase tc : encap512TestCases) { + encapKey512[i] = EKconstructor.newInstance(tc.ek); + i++; + } + i = 0; + for (DecapsulateTestCase tc : decap512TestCases) { + decapKey512[i] = DKconstructor.newInstance(tc.dk); + decapCiphertext512[i] = CTconstructor.newInstance(tc.c); + i++; + } + } + case "ML-KEM-768" -> { + ML_KEM_768 = ML_KEMconstructor.newInstance(algorithm); + int i = 0; + for (EncapsulateTestCase tc : encap768TestCases) { + encapKey768[i] = EKconstructor.newInstance(tc.ek); + i++; + } + i = 0; + for (DecapsulateTestCase tc : decap768TestCases) { + decapKey768[i] = DKconstructor.newInstance(tc.dk); + decapCiphertext768[i] = CTconstructor.newInstance(tc.c); + i++; + } + } + case "ML-KEM-1024" -> { + ML_KEM_1024 = ML_KEMconstructor.newInstance(algorithm); + int i = 0; + for (EncapsulateTestCase tc : encap1024TestCases) { + encapKey1024[i] = EKconstructor.newInstance(tc.ek); + i++; + } + i = 0; + for (DecapsulateTestCase tc : decap1024TestCases) { + decapKey1024[i] = DKconstructor.newInstance(tc.dk); + decapCiphertext1024[i] = CTconstructor.newInstance(tc.c); + i++; + } + } + } + } + } + + @Benchmark + public void keygen(MyState myState) throws Throwable { + switch (algorithm) { + case "ML-KEM-512" -> { + int count = 0; + while (true) { + for (KeygenTestCase tc : keygen512TestCases) { + myState.generateKemKeyPair.invoke(myState.ML_KEM_512, + tc.d, tc.z); + if (count++ >= TestsPerOp) { + return; + } + } + } + } + case "ML-KEM-768" -> { + int count = 0; + while (true) { + for (KeygenTestCase tc : keygen768TestCases) { + myState.generateKemKeyPair.invoke(myState.ML_KEM_768, + tc.d, tc.z); + if (count++ >= TestsPerOp) { + return; + } + } + } + } + case "ML-KEM-1024" -> { + int count = 0; + while (true) { + for (KeygenTestCase tc : keygen1024TestCases) { + myState.generateKemKeyPair.invoke(myState.ML_KEM_1024, + tc.d, tc.z); + if (count++ >= TestsPerOp) { + return; + } + } + } + } + } + } + + @Benchmark + public void encapsulate(MyState myState) throws Throwable { + int i = 0; + switch (algorithm) { + case "ML-KEM-512" -> { + int count = 0; + while (true) { + i = 0; + for (EncapsulateTestCase tc : encap512TestCases) { + myState.encapsulate.invoke(myState.ML_KEM_512, + myState.encapKey512[i], tc.m); + i++; + if (count++ >= TestsPerOp) { + return; + } + } + } + } + case "ML-KEM-768" -> { + int count = 0; + while (true) { + i = 0; + for (EncapsulateTestCase tc : encap768TestCases) { + myState.encapsulate.invoke(myState.ML_KEM_768, + myState.encapKey768[i], tc.m); + i++; + if (count++ >= TestsPerOp) { + return; + } + } + } + } + case "ML-KEM-1024" -> { + int count = 0; + while (true) { + i = 0; + for (EncapsulateTestCase tc : encap1024TestCases) { + myState.encapsulate.invoke(myState.ML_KEM_1024, + myState.encapKey1024[i], tc.m); + i++; + if (count++ >= TestsPerOp) { + return; + } + } + } + } + } + } + + @Benchmark + public void decapsulate(MyState myState) throws Throwable { + int i = 0; + switch (algorithm) { + case "ML-KEM-512" -> { + int count = 0; + while (true) { + i = 0; + for (DecapsulateTestCase tc : decap512TestCases) { + myState.decapsulate.invoke(myState.ML_KEM_512, + myState.decapKey512[i], + myState.decapCiphertext512[i]); + i++; + if (count++ >= TestsPerOp) { + return; + } + } + } + } + case "ML-KEM-768" -> { + int count = 0; + while (true) { + i = 0; + for (DecapsulateTestCase tc : decap768TestCases) { + myState.decapsulate.invoke(myState.ML_KEM_768, + myState.decapKey768[i], + myState.decapCiphertext768[i]); + i++; + if (count++ >= TestsPerOp) { + return; + } + } + } + } + case "ML-KEM-1024" -> { + int count = 0; + while (true) { + i = 0; + for (DecapsulateTestCase tc : decap1024TestCases) { + myState.decapsulate.invoke(myState.ML_KEM_1024, + myState.decapKey1024[i], + myState.decapCiphertext1024[i]); + i++; + if (count++ >= TestsPerOp) { + return; + } + } + } + } + } + } + + static byte[] xeh(String in) { + return HexFormat.of().parseHex(in); + } + + record KeygenTestCase( + byte[] d, + byte[] z) { + } + + record EncapsulateTestCase( + byte[] ek, + byte[] m) { + } + + record DecapsulateTestCase( + byte[] dk, + byte[] c) { + } + + static KeygenTestCase[] keygen512TestCases = new KeygenTestCase[] { + + new KeygenTestCase( + xeh("2CB843A02EF02EE109305F39119FABF49AB90A57FFECB3A0E75E179450F52761"), + xeh("84CC9121AE56FBF39E67ADBD83AD2D3E3BB80843645206BDD9F2F629E3CC49B7") + ), + new KeygenTestCase( + xeh("9EFF3FF8252400827F3B4389E4EC07E67948257C744278048C889D0789C5BFFA"), + xeh("5D473027666FECF7024ABAF175B9BC42E84768C00AE2C5CF27A668121B02CD3A") + ), + new KeygenTestCase( + xeh("C6636E8C2F87DD52A7F165A2A3BAD562ADB28CF738AA56B996B6062E95F66148"), + xeh("7A7FC526215D5AE3262985D17B00726462D1479CB038DE8C8A8FEA896A037B2C") + ), + new KeygenTestCase( + xeh("EDE2E63FDEE6ADA2FC6EA906AA8D92DE87FA6199AC15446B0B6F075BF9F76148"), + xeh("6E584B168BB5399D52B458A8BD122DE14EEF214515B70F38F972F41783005755") + ), + new KeygenTestCase( + xeh("CD568FB1EEC23C436C011A55BE2FD4362EF000C890BDE7611EB5C4618AB74F8B"), + xeh("37B87F960BF862D8B81AB5F56E9E24ED8EB011A05867A04DEC9BAA519AF45E22") + ), + new KeygenTestCase( + xeh("35DEE1F800CA85E482BB12AFDB882FAE62CC77A338E65CA2265D77243ADAE3F3"), + xeh("4B0A877F51434F70E2D8DB0A51BEB0A7572EF0DB7AC26ABC5D333C503B68BD5E") + ), + new KeygenTestCase( + xeh("D9502C86FB461300B8D142A906B766B0B42481EA9C83AAE2BB74390F882B0509"), + xeh("B1EF909D94C56C134107B913B0ED29BC0851CCE424D0FB69EDC04C685A540871") + ), + new KeygenTestCase( + xeh("07A9BEBF21C83F6E5417A73D8CF5B527568C903B5883CEC8347B4ADE73AD92D6"), + xeh("671C8C054A52A67BEF8015DFDB5711C9197E84A5A553E794AE0811C8432FEF6A") + ), + new KeygenTestCase( + xeh("F682949EBFCFA5DA31368E3F177DD146448D0E62178959FCBA4CD4F02CD8B17E"), + xeh("C02D5CAD9E565727E19B2EFE4FA2E083F93EA0F5ADAF97522F33F416F786765F") + ), + new KeygenTestCase( + xeh("170CA6BB76C065255DFDCA3EB93C772E57EBEF8C9A291C8F0BC4444BF008C868"), + xeh("70567D6DFD6622814417BBF673812F2D02E5BFA897D464957AA4219841A93C19") + ), + new KeygenTestCase( + xeh("176719D76EE1CEA83F7751BC4E3DDD00868B5C504C79AF8730B9F7595E7914A4"), + xeh("71A6E59B13B36CAA406DBEC53F3FF2F0CC529098A4C8FBFD032C8BDB8B0E16FE") + ), + new KeygenTestCase( + xeh("3C90FC402DA953172300194876B3B3BC958268747751346DE7134566CB8FAA5A"), + xeh("B63478F2FC887334C707E9D836E3104892566B3568CD32B583F8C9A0DE1A1F0C") + ), + new KeygenTestCase( + xeh("24B783E39214CC39910799ADECE53B32408C19CD9ED10DEC039A9FA2CFC1CA30"), + xeh("4EA6EC5384C51903758B807395181F6D6B4CCA3FA1CA24110B08A8AB1742C411") + ), + new KeygenTestCase( + xeh("E4F2972F746E028108A5BB98EC97A307DC9363909DEAFC491F040B964675B9FC"), + xeh("9FA6AA53F505506BE269CE201A1A6EF95692DD1350A7188F468D34C5DAE5EAD7") + ), + new KeygenTestCase( + xeh("C5C26DF5BA8BAB4A293292BD070986A8063F736469F6ABBAB684F7127575172B"), + xeh("A9EE7619E4F0250147ADC188649A45EB6D82DE5EACD5643CDC52E6DF8DF2F8EB") + ), + new KeygenTestCase( + xeh("EF0F6EDB707059073378E3419C8D9031D0732CFA931190EBD07FE291B1A3EBD3"), + xeh("80CE5D65D1795C90B637C10360B04A4C21A70851F0A59D4D753F54CC00103FF4") + ), + new KeygenTestCase( + xeh("BEE40356679E3EAE8B0C3FA07C1BFDC8835CEC26CA194D5EFC4301481C256C0E"), + xeh("B923CFEEC804B8C6A9E36B77B38A2886C45B1C731A33528ED2CB5A1F65E792F6") + ), + new KeygenTestCase( + xeh("C6D5B35B90FA9AB9A7B438B57942D653CAE67B314C7FD152013B4E90BEF8201B"), + xeh("1F4863F16E38DFD2C42A9322FA1ACB941DF3BDFA000A202AC621936FCC5FE33A") + ), + new KeygenTestCase( + xeh("5C6051E18E28FC5719E3172B967D25BB1649D87743440F7715E860AA212A256C"), + xeh("53F5EE39A553E831BE32EB490A6E1DE62FD4FE486EF58A4B99F6347759BB8905") + ), + new KeygenTestCase( + xeh("CA351B0F454DE9DB364E1DAB8AEF6E49C2E69439941935B24C00BB9952E65BB3"), + xeh("9C7C3E68F827936D8DC435942DC4925D180E6D5C911550089E1337D8BA77A06C") + ), + new KeygenTestCase( + xeh("C467A43BF9E9CCADCE4581B53F8CA0B605583775AFCD0EBBB587907B3A813D94"), + xeh("97A4C9A65A82BAEC15FF165E10490976EBB19FAFBA8F9E8E0DFFBDB4D5E1ACE5") + ), + new KeygenTestCase( + xeh("D732CF45D7F44788E17C3B6DA9987495AB1AEFA233F74EEF8D3BE5B6C0C04E00"), + xeh("973DBB6EAF76AF0C96F0F24EF9AE65ACD854301B5F7A7892A17FBB8601DE78D3") + ), + new KeygenTestCase( + xeh("B670CEB5612A1287C4653B158A3CC522AAA1AA45B34A4C770DCA1E5BF3988F3D"), + xeh("D525CCE60C3E300ED36298A1C0D0165C147CB84197C4028257DAF39239E6EA5D") + ), + new KeygenTestCase( + xeh("3236CB10279681238E5B0E2F5138A7F743443379F5F1A845F3D76B75D2C2A9DF"), + xeh("9F2FC49CD848BA72FC17854B18D88ED65B630BA94A1BC5F6D3A458E1087D3A13") + ), + new KeygenTestCase( + xeh("C155568B6BA74DA317388423F8FB28585977EB858EE306CAE4174120F02A8D72"), + xeh("0FB831AFA34B124F7456D0D09E4ED8607DE407101E6E75F305F9D67EF7C2FAE7") + ), + }; + + + static KeygenTestCase[] keygen768TestCases = new KeygenTestCase[] { + new KeygenTestCase( + xeh("E34A701C4C87582F42264EE422D3C684D97611F2523EFE0C998AF05056D693DC"), + xeh("A85768F3486BD32A01BF9A8F21EA938E648EAE4E5448C34C3EB88820B159EEDD") + ), + new KeygenTestCase( + xeh("444F032DD19AE7518C4B35B0732A41DC567845ABA8BD7B04A9C413A0CF2DE0B5"), + xeh("DF0F282411F4A071489A8F618E2AE5AEF40131CAC5233D6D731522720C2FEB1C") + ), + new KeygenTestCase( + xeh("092271D05CA63C60880AF404D60BC4BB9539E2EA12969581898D56E0AC9A5A68"), + xeh("5AA6DC620A6E9A60CF19A7B4F0FF805BDA8219522A548EE5857C3FF6060C7A2F") + ), + new KeygenTestCase( + xeh("BBF7574CF5F32BE49E1F39CE33870D9D6384056D60D223003B6B0C10D5C42180"), + xeh("7CF50F7237A97072F03F31CFD59FA8E863BCA3AF7375E0CA698FF665661C24CF") + ), + new KeygenTestCase( + xeh("D12CD9B65B7C58B2195AE0BE0282527BAC06C2D25CB0472628D64715F7F6A378"), + xeh("C593627807074684B7D363441F80F6A3D185D67878702D33A4E0BDA2000F857D") + ), + new KeygenTestCase( + xeh("79C006D5470C229AFCE7588546E52204B09F5086974865B426AAAA198C6CBA7A"), + xeh("E01702E1228F530AC96DB053A415BE97749A109A1FD4057BA128649B17EC07AD") + ), + new KeygenTestCase( + xeh("B04F631B330D83991B5C01E7F69452DFC394F9689632F8C7F60DBFAB92A9CEA5"), + xeh("AE51639EF7F26FD2215AD11CBE1EDEB3B943D668EEEFEE13ED5B0DA3E0A5F3ED") + ), + new KeygenTestCase( + xeh("3D63BD6C310AFCF684292E5F8E1B98CC75B5A27B21526268444144AB24AB2967"), + xeh("6F9FF5654FDA78774498E2643E935D21412CEB49BC393532C80C47A982418F66") + ), + new KeygenTestCase( + xeh("249D48941ABC01C9290719FB34D91B05E774E70E6F0181E1783F2586E2499536"), + xeh("D083E6922EF0A818308FD7FE7CF5AD3A96942442BE327B0A307685C2D4315901") + ), + new KeygenTestCase( + xeh("E1CFB8195877B2D4FF3363BAC3B4E7BEBA6DC3CBB789B1B24215393F6C9BBFAE"), + xeh("A20ABA8A8DDC212DE825BE0D3BE57701A6B5B3A46A300D9B5945F579A59AFABE") + ), + new KeygenTestCase( + xeh("ADC4DA59D935DD87420ACEE52AEE19CB371FD0BB498D79BA680159EF7CE37C17"), + xeh("7FB950A8F51DCEC4BC7A573EDDA56ECC049E5688476BD5FD6CD076A8F99A019A") + ), + new KeygenTestCase( + xeh("76CDCA53F781806D55CA8D3BAFB3F4D389D712F1221E85B5E29D6A46580F978C"), + xeh("51D509CF26799741631099039F713B22551E2B0F0297BB809DF0CC8FC3E47EEE") + ), + new KeygenTestCase( + xeh("78AB6C49354A018BD38A39926F822A1AC4ACC4FF32DFD7C047CE0887A3AC182C"), + xeh("9C330AB4257D7B87C4742C6E95B66BDF805C6A145BF444836092C6B1D2C5FFFF") + ), + new KeygenTestCase( + xeh("13B75620E4CB9AB9A6689F6E2BE44639BAE6C9CB7DD641AC1C9377242D99679A"), + xeh("18EA1C7532F706B06870D0A1047AAE33D9E1FF9E9BCBBD302D8817EB7B022A77") + ), + new KeygenTestCase( + xeh("7C345819C7C327AD9571E5DF882449DB243870D686A9764D4129B21E17AC86A9"), + xeh("C71F7E44295978FC63BF8F6A68F8609E98D155FD7A74E1FB7982733FBF8A6C25") + ), + new KeygenTestCase( + xeh("8D6DF2EB3DDAF961FE5EB556842B758BEBC7ECB312B6D4628B323F483B77D6F9"), + xeh("EF668FB41F49E82EE0FE00919CC06507548321593A7ECD1D2112342608D95FFF") + ), + new KeygenTestCase( + xeh("DB4ED8E9C3E1AC7A35EA4B67A4EFCFB46972A984D161F79F084125D6D4AEE7AF"), + xeh("26345937ADC9104155275E7114E93D9F5847EEA73A9359358585B2D42301A294") + ), + new KeygenTestCase( + xeh("C6EFA7D5D500E5BF857D80EAE2A6EE6414159947FD4BE589350724FAE5E51805"), + xeh("63435E06C2AA3DFB3477120710D5E7FF0DC0DA68D4644A24F66A8012FB193697") + ), + new KeygenTestCase( + xeh("20859B01DFC60B6109E0234F3CAC7A247D8386099D83D2D447E9A21AF9DE48BD"), + xeh("8C2942B7207C2C59BD56FF9EE0B120B1DAD81B05602623623CBC7E0C20C9B709") + ), + new KeygenTestCase( + xeh("409E9F3AB58D736E122EFCC4240BF8388FDFDA6759004D42457018014A335BE4"), + xeh("EAE318341D06E0801C0CA4B873520C714740AD017FE5A158D3BD40960D907AB7") + ), + new KeygenTestCase( + xeh("CE2CACEBD54AF1B4E71588DE9F22A6AF2C2E2AD7FD66B9FEC0DF19182E7F57EC"), + xeh("EF38264520685080F52975BC957C5FB609FB0E1BD06D26F572CC5425CAE7DE5C") + ), + new KeygenTestCase( + xeh("7E03015C5D55FD9888E730C1E60F90C5F6C2E3B1E8C7C08D869F0C1D15B540ED"), + xeh("17E5AE70771674BE8903CC21B3A90248D993C261B6CEEF2C747873D113869B55") + ), + new KeygenTestCase( + xeh("8590BFC9A6FC25EE7E6DAB4870DBF4B51A1F141B7C9E96230C0403E799BC68E0"), + xeh("BF83E3048B021F22DB57076A885729F95119CE63FAF51A69954BCCC51E014686") + ), + new KeygenTestCase( + xeh("D5FD815092620DC42A223909E387369A74AF7DCA285138CF217BC29F29C42C41"), + xeh("F42861EFF7691614C3E8975AFB4E353F8C8C39E6F41BB637EC79BAA976D1ADC1") + ), + new KeygenTestCase( + xeh("D21D5AFED9AFAA3B49FB45245B2BCA1505E4000CDC29094A3600F5CAA49A7B3A"), + xeh("4DD0E86091649A0A08EA44DAB85DF56797F8BF46222C2DBA7DEC6374B9B2268E") + ) + }; + + static KeygenTestCase[] keygen1024TestCases = new KeygenTestCase[] { + new KeygenTestCase( + xeh("49AC8B99BB1E6A8EA818261F8BE68BDEAA52897E7EC6C40B530BC760AB77DCE3"), + xeh("99E3246884181F8E1DD44E0C7629093330221FD67D9B7D6E1510B2DBAD8762F7") + ), + new KeygenTestCase( + xeh("2D229AB46354901491476CCE8FA96E4A5FBA65AB2F538FEDAA528E35687A782B"), + xeh("007BF379B97DA0947F2E9BFDE3359E282C9CF1D2E68A80209B533104E90F432D") + ), + new KeygenTestCase( + xeh("1D65D0290B15903371D616D7AC3F2FADA8CB24E6C84D52C039A10BC1288C1110"), + xeh("E94F4E83E6CAABCA9E319D40F6CE0E3691B77C92D9E3766BE9B6F4B6DF2E640E") + ), + new KeygenTestCase( + xeh("22D19527844F3CDB8A342620A96E902AC7C36E54677ADA6FE8DB08DF4EF3B36B"), + xeh("EC54F6E1E7FB12B796D0E56BE6FE3BA6EDAAB49B08712318B27D229606D2AC70") + ), + new KeygenTestCase( + xeh("A00D1EE4147DD57B5E76C58A928DED0B720FB2FB6353780B380B5FBC76712E5C"), + xeh("5B78F8D30AADB59FA617EF807D5C23113A9908342F08E898E02991CA1D7B934D") + ), + new KeygenTestCase( + xeh("2C34B1476753095D0C8A48A00136F358A98D1416E5069CBA4540C6E26FA3634D"), + xeh("384509DB0E97D4689A3CED953CFBFFA9D3B3B87CCB0C6A360FC0DF3CBCA399F9") + ), + new KeygenTestCase( + xeh("F742E7B69E27A57A43E1034CEB5834CAD57C380ABE259F432F96FAAF27F981A9"), + xeh("63DAD9B127F98E72A3C65ACF4B172FDBD9B9C39F24F728D1F40EB02C9949419D") + ), + new KeygenTestCase( + xeh("3BFC9A057D979EC03A705A9CC406DD8A46C106941AF6777B1D7F79C1508D7B24"), + xeh("0A755A829F05597B2F2A90974F22FB1AEAB42892101222967E3A0AD612CEEBCA") + ), + new KeygenTestCase( + xeh("7C43F2E7D9B1D8D9C41D9F315E052A254CE3A1F098671773B53717A95220AD55"), + xeh("681F088AD6962FC397A1B9071852848CE9A7EDAE65A81485CEC87D0974707B7E") + ), + new KeygenTestCase( + xeh("C2E1A3161F3734F44F3C2F1736E149803F71321122242A1E95E55E5652A91F55"), + xeh("40BBB2C581B2D694E369C0DA567371E8E53C328A59BCE775A625C9F5CC185E0F") + ), + new KeygenTestCase( + xeh("ACB7FDB596B44A88A60ED74A3FAD9EF745BF5BFA4902CADB891EC5CA45F685F5"), + xeh("E15F322315265F9B847960B7185D962761ED79C62286A0DFDB13DBF550CE0107") + ), + new KeygenTestCase( + xeh("0AA4E8D918201BB98464963B076E35337FF3265810723E01C435954DB18B14FF"), + xeh("ABD71039AE2E2700391011D9CC8265C2D5C9779002D54E1BDD9607402054CA95") + ), + new KeygenTestCase( + xeh("F43EC0E96A791317938761FFBE97332D5D85F52D22BDA6303FE7E7107DB608A6"), + xeh("177A8DA7AF8DB3F712E1653D05A47D61B59F4F4950549382E56F761D7126F8F9") + ), + new KeygenTestCase( + xeh("0596F1E214B29A0CB7A641EA0BB157FE01FAB73B4A9BCDC165FA44C8FD5FBF71"), + xeh("79E3B0D4F4AF344ED06FDE8BF4E104753E832294A3D2E4B66BE59149006A7B95") + ), + new KeygenTestCase( + xeh("D7349F9AD546CFE9830E1197072B6ED9CA21E8E0423F145F1DB84A5AEBA230EC"), + xeh("EF0F95F630F41B3AF911A30E543822DFA6B7684FEE36956D2BCF8FF080C9FA26") + ), + new KeygenTestCase( + xeh("F05117E932CA0E0C202732DFD4F674BF5848219A76C64A0650C27E2E55095513"), + xeh("DDD4871080BD4F761D972085851DE0A0408A2F5EEC3CD3786297A782402CA440") + ), + new KeygenTestCase( + xeh("A405D9B07C5771A5BBDA2BE9F8A40D9566CAD7DA1761ED8076A289063DB4A8E2"), + xeh("FA29BDC28D989B8C4BE84706A3CF21B36A1C6E355C88A361C7664818E4BC8E03") + ), + new KeygenTestCase( + xeh("E66F17317C40783CE0594CFB5920FF86062591C5EA4254021495749642C0D968"), + xeh("08FED872D91297D8059743D3E7B6EE47548357E7F882B5BFE2F04314187ED424") + ), + new KeygenTestCase( + xeh("F8CF49DA62AA762EC020F3766237520E7FDA4CA3AC11FBE50E6C5F9CAB3CA7B8"), + xeh("EB8EA5E8C5EABACCFF162556DA53F0C02F72EE7A7DEA8E9EB70FC51C777645E6") + ), + new KeygenTestCase( + xeh("08E36AE8586A59B8249A80D7F43506F9711FA4B00A49D182CE06DAD0CF985809"), + xeh("DAC056B9A373687E44CCAB8751BD334F4942696B9076155F9D0E5BC0E89D85CF") + ), + new KeygenTestCase( + xeh("A491FF48028B67A407F1054D5B1CBA733B665DE667E22596EDCC31C227C2DE1B"), + xeh("4D727ACABD44DC48980691E0268B5B3FC1E476B3FDF9571F5CBC8DDFD400AB99") + ), + new KeygenTestCase( + xeh("7B2EC50C53A67E0BCCBA98C2E319F5AB46B6E593D2465F14B23FFA03D0E5BE0D"), + xeh("4E638D8AC3662450E09D8500DED751060B7990D54F137508B9897277F65EA952") + ), + new KeygenTestCase( + xeh("16858AA7C92EBD72FB8CCD0A99D0435EDB2A6EB1B936DBCB637CF43F25D221B1"), + xeh("7459AB99D24C1254EEECC035874BF19A64EFC8EDC9D369C11F5DF4DC83AB5FBC") + ), + new KeygenTestCase( + xeh("F788F3E21D62E74090582F310BD4FDC8065E56E8D946142B9B9CF8F338F330E8"), + xeh("4CC1CA6B662A4CE499EBE66D933CEAE58EE244CBDCAAE3C1F45A0D6947802B76") + ), + new KeygenTestCase( + xeh("A72608DF0F025B4FEE7D94BAE77BE94CB974F20DD55006A70FD39F3397A8EF90"), + xeh("D16CC70224474A4D71E1F950C2D5CA72D8F08AF80E0C7F6E292C265A50CC30E8") + ), + }; + + static EncapsulateTestCase[] encap512TestCases = new EncapsulateTestCase[] { + new EncapsulateTestCase( + xeh(""" +DD1924935AA8E617AF18B5A065AC45727767EE897CF4F9442B2ACE30C0237B307D3E76BF8EEB78ADDC4AACD16463D8602FD5487B63C88BB66027F37D0D614D6F9C24603C42947664AC4398C6C52383469B4F9777E5EC7206210F3E5A796BF45C53268E25F39AC261AF3BFA2EE755BEB8B67AB3AC8DF6C629C1176E9E3B965E9369F9B3B92AD7C20955641D99526FE7B9FE8C850820275CD964849250090733CE124ECF316624374BD18B7C358C06E9C136EE1259A9245ABC55B964D689F5A08292D28265658EBB40CBFE488A2228275590AB9F32A34109709C1C291D4A23337274C7A5A5991C7A87B81C974AB18CE77859E4995E7C14F0371748B7712FB52C5966CD63063C4F3B81B47C45DDE83FB3A2724029B10B3230214C04FA0577FC29AC9086AE18C53B3ED44E507412FCA04B4F538A51588EC1F1029D152D9AE7735F76A077AA9484380AED9189E5912487FCC5B7C7012D9223DD967EECDAC3008A8931B648243537F548C171698C5B381D846A72E5C92D4226C5A8909884F1C4A3404C1720A5279414D7F27B2B982652B6740219C56D217780D7A5E5BA59836349F726881DEA18EF75C0772A8B922766953718CACC14CCBACB5FC412A2D0BE521817645AB2BF6A4785E92BC94CAF477A967876796C0A5190315AC0885671A4C749564C3B2C7AED9064EBA299EF214BA2F40493667C8BD032AEC5621711B41A3852C5C2BAB4A349CE4B7F085A812BBBC820B81BEFE63A05B8BCDFE9C2A70A8B1ACA9BF9816481907FF4432461111287303F0BD817C05726BFA18A2E24C7724921028032F622BD960A317D83B356B57F4A8004499CBC73C97D1EB7745972631C0561C1A3AB6EF91BD363280A10545DA693E6D58AED6845E7CC5F0D08CA7905052C77366D1972CCFCC1A27610CB543665AA798E20940128B9567A7EDB7A900407C70D359438435E13961608D552A94C5CDA7859220509B483C5C52A210E9C812BC0C2328CA00E789A56B2606B90292E3543DACAA2431841D61A22CA90C1CCF0B5B4E0A6F640536D1A26AB5B8D2151327928CE02904CF1D15E32788A95F62D3C270B6FA1508F97B9155A2726D80A1AFA3C5387A276A4D031A08ABF4F2E74F1A0BB8A0FD3CB"""), + xeh("6FF02E1DC7FD911BEEE0C692C8BD100C3E5C48964D31DF92994218E80664A6CA") + ), + new EncapsulateTestCase( + xeh(""" +49469911485CB1C06A48A449F1A43B0456406243AF447A7CECD5467DF322A159AF32B6C59CB05D200CAC34DA66D8DBCFF8326FCCC08A77C9286F590F33C06AC36049B91442F18AC6C00C240E713D387C8BB2BA3780E6BBFE90A4B1D7B155360ED9ACBD63205BC3482B8953B3490427F28392B083A47BE5B18EF6AB51B9859FDB659B8424BA93A8F470014FCB6AB9E61FACC61311BC1BCB098469D9702FE54F8F931DE7B2B57543750A346367371F3724384261B569AB5D8C870A01822BB4E6C617F17DB6EB0D0989C5644459281828EF4AC11A119EF794530436CAA0E28B8CB5365E4854E1AB4BF87CA018AC6A8E62C36C97117014A569AB472DEAC7E7B1108BB8BDBD710AE8D033A1961917E171AAC6841B5A9C5D869E68974D79B8C70775955520CEC21B5EDB05B60FE230EC143BFCC15B550370E1D58E76D1B5BDB0747412B952131DB306A4DB2395CA69CB9912C0A1660517553C92A7210056C4B6F347CDF33C326A27155CA1A7BB809F8A4A46703537B6530E5987E02A9EDD83297A1218C68699E5A898F9487279D35BD01B57B57A30E85483194C68069BAB0FC4BA0F48880DD1089DD21ABCD07228D9B213C32EA184291A2B12E3E19B4E4B7CA51879C46AB93057AE748236265935F0B16CB456256419AFD82147C9247CE6A7CEE4F349AAA59DA7A4AEBB2B0ED225775CE085A9AABBF49B756CF833CAF22B39AB4D9AC4A26758430866C9D76C5EA68300AF90697FD304AD715C591798C7948FC1A954FFB40301A432B29726884266A3D8B8EED13F3A33A106349FF58075C9D67923A59E06322FC7258017179E7859ABB2A83234D81330B1297AE842AA1C0C8543972E5B3AEA4490D4B0CCC1F9681266A6A0F96DD955924EF25E39642556F18443497D2EAB77AFC01B1D2003F1981C92060743141458FC606BA85DE9DBB1BAC78D6ABBBC73BC7F4E0C6BCE13C8B49BA367E60929C61C34FC7BFF013D4743BF92A70B4683C724B06717237A76D58F81EA39A9F96F6D627162299BC82A355D06C766318BBFEA3386860D683AB75FA03A87B1B2C1D99A30EAAD78A79CEEB43C1621C54F79AEDF82C7F8CD5FB11F119FA35CCA71B4CCF3E1D83F07C3A66C3E82F2D84F640DE5"""), + xeh("4660985A5838041F2E50381CB4E7AC908BAC83CC1E074220C6705E3F5FBFC2EF") + ), + new EncapsulateTestCase( + xeh(""" +C70876917C9AC2A2CF2110000910898E21804D940D6F761A525578E2B0399F1C0800B62C8720060F88746122C948446472E73AFE78A205857C6D32B6C01CA0EC742311840A36A8BD157B1C50A944B4C213FCF9558E3068D9714ACDBBC88A1538B59764C1F59C079C5BDA31BF55EB731BF69717A9CA63DC316636461CE2CC42201C359B88D044156DA30AAB932F902030BEEA6D58998FB2363C8223BE3DDC437AAB4D1BA27FCE058E701B10FD211E5862542C058F3DE33D5561B8BB3A83D6C55377862181150173D2135CA3C8084615668C38ABE8B72F193FDF96ACFA3470FAA53450017EFC36882C5AC722659D229225E01C5F976171E19172BCE5290073AA08276FFC85218F208BA3A1108B62545941C8991C4CE279C697D8CD06436134511D300C3A5FEB963D36CF29D6065E085C9663443342A8388763B16566D99C5C5DA4A451C2688E10936293948A57C4CE7B73BCBB698D9B71E2974638D5433E56A411E4089F966F603120D56A48DB653A5CD373D42A6AF3117D71AA4D26A1639D63A305B8BE1DE15C6F678519FA671A91483E46AEA26C0C59872CDAF57B3A6453CD660A0D9A0A562BA23678CDCDEAAD1CDA5820C65EC480347FF2872EA9574C4148C7D59980C584646409793190BC721CA6EA9BF029C695563B0598BCB357A1A221CEB3AB96F2269F45C24108E137D1BC34708B1B66352627340CCAE6CB22F41A75A0A55F58701DC4157A1316FF968CEE300FD55A37B5957F41220BF547933C67201D67B1AE278D9649BCAFC68F082B7D1C6016EF360D200CA0EBC76046DC5AAB171A0D544719E3411B587DCE380D467BC13368A25FA51A3E9B4EDC77561408B776F83A76B24B489310E3B608F1B40EB7395470F86C1D0622C1545065707462D89B364CAB2CEAC9501157F91BC52A2816E9598846B56C1F7B1A6D06195F92BD53931078E923C9D1552782325878832224B21A1C26562245B636943803ACBADC559D3BB6DEC54ED360239F74695ED3364DE562751892F2B2936F6895C166697A4A44D10A49C59C53DDE4B2631705440B957100AF4E1BBD47F2AADF22780AE0255D0AC18A87A28D282DD1C59C0C51D373C8F4A912400D5C87B499E0BE8CA991939F160B"""), + xeh("0D643FF311D83CEDCB3A95BA0F76216A49BCA389A225396F708EC9A51BF18517") + ), + new EncapsulateTestCase( + xeh(""" +E868A60B3888165A293FDBAB8B75C008E2695AE85A1C839CB08290AE87200868623049839674CF8E87C8D20C5C369B17ADDB344E263045017370D6885DD25785A0C430250795FC4AA1AB215109692B44C530005054020B32D73DED4B06AC32CC1AC47571B7244F2A05AD063DB57BB285C03C465A5FECB4489F82908EC72908B942153C318509C1508556B15B3BC7A671F6A69EDE283C5B87C2383324C3183B645086261B7CC4B53CEC6C5694106142A12A108A29D749AD47B93583020B3CFC328CCCA1611338A8576BA98659D9181607C42D7EE9B0C3174309FA7B3EDBC6BE422515C203B208C9AA1B3C387909EF511FF2A47AB03A747E0A83326B894168136BD6361D170B8D4087C99552D992929D832D58F26BF3D707B6D302F741456DE30FA6509A1314773FFC079AC94AAA10376ADBB70D857E556272F2A32E68485F84E28AD9326F656A57CE234AD2826298BA4C1CD4960BE4523126A405BC3E772121B1F7AB256239E9761B0EDB5C8D746B4D3323134742D69182091170E08C6E0D3B1862E202F332C7A70A25A3E2482113A5A2C257BDC6AF93C981E5ACC95118CCBBDB5B6244C1D060C9288BB2BB1A6791F748C4182B4AE6A68E060E2028690DEACB1E887A9213C693D57971FB6EDF6A95BA3821D445479B142737887BAD938B944376EAF87B15B210CF273B0BE07707FC52475C01B4485893710D84F5132D025E82630F8415330D257E1642ABFD8CC878E8B199C44107672FBDB8330F3C8CE8154E4E8036E86CCDBCE4B693B0C513132B8B740FFDFC51341BCFFA0BC204D63D6696B2271BABA633A572143E74382346C701F92C099B4371D18269A32769889C61AD428FBC110D450ACC95892791656A7DB39868E03FE6F97420910AE8476D43851AEC9A03734AB4E8E4087DDB9626F36ABF7480705C0E81C3887A64794CCB29587593BBB435C2377477B7A0E6A3C9050A84A99936B94C09DE28B018E73CA7C48B083C5BC1E73A24E20D16771711A863D1423E884808E0C8B6E250986AD4BF1B8592F8EB1549DACB4117747F2994D1808B65DB2AA5B05EBD7A0E614888EF86494B93822876C351BA487DB0D0C6F33C353B368BDEA3BC149CB74DAFCBEE209C50B88354"""), + xeh("AA28DCC71FA83D9997DD733D8B0D0394D84D33A3D3E1B74CB74DC6049628F861") + ), + new EncapsulateTestCase( + xeh(""" +76608E0B9539C1B6470F9ACCCF5465C6B355CFA9424DA750CC085477B4A0E9F671DE185995FA38088506A8524D6384A8F505058800B3F14019DF2977E79436D81B8653B844920BB927D2CC7657666DE99C4D865FCAEA3F18302A36961ECA216740075244215625419758B8B8A82C46FBB79333E56D8076BC2F98610FB3474E75A471AA6D746708037020D3578381CC7C959459FDF21839E8413B44C218643CAC49A0179B2DCCB11235345641A10F3D369FD03C8FF733589607616A50926C176CEB45217A0A62A1F4AD3D06669EEC8C947372E8D082E34789A8D9867C0198E5B06934D904AC5318B58A2A5F3AB2522C611F7BA5A1351231F836881116847551D834A310EB82E0B2C6E1728196B7206D00094AA928AD8138F97879B56B55FCDC0D35C76C336526CF52C6192B0793745658E53155241F46663A8DC153ED12862942674B029492D701BAB56D2468C4B165B588D2A6A94C515E9BCB91A55BD372A613590CD76416C6A0AFC40A60669C90BC3A228F05A6DCEA473688CCB80A4CFA3C9BC5157CE4D37BCED562D5B52B70A48294912BD127BE37C39EC4F23F7C3C01A521C56D121D6829A76B7235C2BAAA2BC841634521D8F360D5B7B31B0648FA442C546878A7CB2FCBA5559F94A90308CBDB72C60551409E364CEC93CE24D16593609159735111F918FEBA4B35465BA14AB8AA1A705AA9ABDFC596864347C6E445F23B64B81AB330B454D14413ED47CCAFA49946B828AC3056CB4195C5351FD65A4BAA57262F9A85A4DB552D939BF539B8C4C547B801C1D99C7044393A08143C332AA440477258E04A83F6089C864B1A69418D0B4B739A4BA729B3FCC9C10F9834BB9409950449A8EC09ACAC79BA0681B31A2C7E687793C352F496010AF4A30CFBBB89CB3012216D8E2B489676B05E4B8F142825C4C4552FF7A48802C3E8040C4B2C744AC477EA84901A27BACA79635BA6C0ED28947BBA8B788ACBD17CBB01CA931E4BCF2BC15EC01476AF0A5F8672897AB5A2F9F850BB0ABE6B61A2A4C800F5671F13D712E8686C780677952A0AF65B463CD0289FE3B56F89A6F7D1643F0823093589FC76619ECC2590076DEAA2D895CF1A81924A0490D99446E364BBA45C3BAC1D40"""), + xeh("A4BAA4C603DA1368C1F2AC552A331F77BF1D598C6BCB540D43CA1E6D4B8BDE77") + ), + new EncapsulateTestCase( + xeh(""" +E331342D560ED6120D12B8044C013C5A8A1204164B00130354015213361BFB439417F5AB35A18A4D1600ADE0163F6A1760B08B3BD8A16C3A82D253428508216E3952923070BCBC922FDA6D0E1A734232194EF979790828A110B9F096CD37B5C07D758D3D68CDB9642FAF100D732031DEA07BA884ADA7D4436C490924920D3B3B7B67297E5D8A984DB9136F44557C6BAA5023219048600B8550DEE669A9F38858D79BAB8682FFAC37B0CB9362723B7A1087A21C477513BD386A30D92A5F52F008A32784019B61E0C8C22B096B356C65CEA631CAB14632A2B978A40A91BA7544559A116CC74C28332DC745EB19AC5EF50425E59FE2C777EB0AB7F4EB49A3393CEFCBC846B63D399A6B86CB6168958E71045208C81F07F62CE826729BA2162C2B835185759CF4AEA00025F4AB46EB56AEDD408B0E016C6ED538A1280F6A0CAB2CE7B573258937F0A265D663F0F33495BC4852D73C774061DC388C3E75ACC69A84DE303EDB605CDBB238DB265AA26A8267FCB4A0922A5413CB65783CF37CA2051071FF00CF57BB6000C6057BD93D4DF31EF35CA5A4327CA8AA2EF7D33A04E5261E732EE8FB819AA446E02CB4370B2934140EDF17BAF6040F71B34F251C6C65B766D317C4DD181AC04103409B65C6A7ADA248549BE72A2B43B2E4B85B58CB5FFC0B33C675C0E0D50B2020BED86005BDE97B9862436CF7A7ED687591F9719E4803254BCE195185CB3C9A48DB6F148A0876B00D1132AFDFBA1C91F57E980B96F1906439489093194F2CEA56C46942796749926B36D498B026353CCBAC0BFDC84C208502E0518512D427DB058219B35DC793B789F5C579D9A5E7285B3AE90F71FBB40FA39C5AACAE582211D9130B7D309AB3C34FC279AD6016C611F902AF959C984564BFA565891A5D1FE13C9D27181A512EE1CA31BCB55114C316BE427B01B6A519E441F66B926CE959A90A712DA1B81DCB0AE6D67749987B3E541A59D2680B11AF845234937B63065B32BFBBC1C9086C7DCA12E258C21E7AC52F812CE4A16E347C5CC115C2A16355F4745B810A4B5140CAE72248B554725D9C186523CF625013D5CA11B7951425CCC18E014EE5E94C2695BB469BD83646256DE038ADDF203E0B60B1F6"""), + xeh("C08584D2F5C950E371668A4FC8F527E20AF1532CC28EE6B5620729155B06389F") + ), + new EncapsulateTestCase( + xeh(""" +83B08010002CFAE6362BC02EA2C08809E5031C213F78795391E4390F4A4F7D8403B79458B792B3B2A0BA0EA82811912CEA1C2553B264C03992D28A29AFC0C50FCC0343DCA764457D7F1A73A975044752CFAE0101AA47A3B706594B403B5561A451013EDAD45B60E42905A97D2A0288510B66E9E75CCA8A6B2E5504A9380785DB36B21B5B1839111A543B18E3B41F30232E1BC816A1992A01C51C32CEEA8B4CDBD4C30CF792AAA5BFF2D54DA6B988FD8C14534B2D24334625A68CACF5897B495D55A873AAD557C29957DA2644714303CCC8744640C932B8307B8A08C2403A94E17387F4BDF786B38276756D95C0B9FC4E56C7AB925643A21A9BB7BC6AC58262DAAB33AD09348F7C569147359DCC794EA4673ED1ABDFB71EE199B31FE1CADD2579F94682FB013039B935A3167FF8460EB3006DC7EA297B643B150C5CE360BB197732B7F9198F4A7479EBB8CB97A22010618E22200E896C807C5056D78CE088A8478A751B95750A849D12677C6DCA08CDA502EF603FB5C67566338EB13114FD10622BF8B0212C70E92C68827999ED7177CEA44A7A055F12A00231F3C5FEC1BC07812EA902CAEE99B899B39E88FC7FF6973311483F2A9BAB7917A56D2CBB549AA887E545A7554910947CB9F09423C75EE63B626E8BAAA7A00890340DA33B7C2CB6052B5CC47CE65A0873CE9126816D8BCB6A1C8D39265BD1797F610244C565670DF05E58760690D52B6882A9A303582AA03ACB3B2D857CA0D7B8A2BF859860DB729D2740FD87AF798497D558042319638A33326E3C5CB0D3CD6E71A346365B308221A1DC2E49F51E818B22ACF66FA0C586958CA78204A1FAF135F17977ED2801C4591F2893A756A0C4988BCCB011B389D0656A717A069BBBF1F893A3BB64FF28B66BD2106FC23C2BAA2E4495580D08C896A92F2AF36CBB13CEF4AB94E4CC9D866459BF6CCCDCE7912B3119EEF0AD4CF5093CD85674679A298272EAD6B14F2950F18C602C52AB821234F655419B843C31491C47C596596967F1EB036550A941A03790874FD8498DAFDA127C8B0561116F9D414171778C7C36012DA9BC543158A00352A2E39D802CA5254FB4A43FF40242ACA967C85D45EE0F8E13DDD9951336DADD5E"""), + xeh("1D51A0CC52E85972001B77047D97DF5F47AE11FFC6C31B4AF42FB0791A3DB40F") + ), + new EncapsulateTestCase( + xeh(""" +28D9320FC6A5EC10059D3A531C364A99CA5A13CA98FCA773FE3B4EC6851E29EB8C0CC19440922CBF26859DAC0801FB0D0868B7C6C2917C51B7F644B4CE2C9C8AD9697D1102496B9B11B012105915C1A897065B05E6E7713740A391FC2B486249779864C74A1820F34C44063E47C87278C696DE5260270901190A5A618CAED0DB8B21D15C2D0552678833C1793070128DE0E43257413E99A1A58BC50323B0C722D69C36E82659410683CA4107C51D2D2126156C7357586EA553CD88CAC0E4530EA66B1FFBA700EF3A85259B5FABA131517CAAA0383028E125DC1670FF7C62D74775EC58A5B2B6074794225BAB8BEE7C14FE950AFDBC33B9A6CBE8492B3EC2BC16734EEADA20A45C07ADF81FE3401547F06603018BF5C4AD908AADCD9B5FA1D08244D922EE3AB1B3C693335AB64060369E328D31EBB3699BC3F390363610B2333A61BD67CB7DE4C6050C47D6D1402E7B997EC2C2E9B76AE5C77DF610A893183A1117747B3927BA7BB9B9ABB00E0B7E376C3310C3A63CBB03A2CC4BE1265CA35BC4D5C0CEB4187E9F686290472E9B0264B110C80F7A5D5C34678A746A5C4623CF8B54021A725F2C96E4923C2F531A7AC1405E275C44697A9C794625878F4CCB5D9DB9CF903C4F9DD180D0CB25D09AA389675A972223DBDA0435169C8652967C74C583223398F34E86D46DA0D026F5D661A4C4A85A85AD3DA358ACBA0B7E6C9C25D2CCB1A89B5D35A4F6516349CB1E983B793A04BC495311FF7433CFB8BE2722965308014D914014DA39322C0844F3C657804F9561274936B6556A639903808F8495F13C1138DBA65B573327490D8A772961B70B5C6CB4F8906B1B92639AE1AD25045CE5401AAE924491108B81044ED9E6B996A991AF83011B39021FB177FC8834A244B38C850C6FFCA4BD2323F896431FE64658B45299C280CF02894DFC03593135E172CF5B523734153E3CA24D160CCD64340AE6D021C21B8D5B98AEA0D9187F85AE1E5B0D9B06B1D1B12EC223B35FB2B07D81A42B11120A869C0B873831A41632CB0C1D819418647BBD92712920CFC2F24DC7871A194860105A6F0E10302C391E1DC2FA4BAA0C8576BC6E55F40A12DE2944202C00C192B497300E587946F1FACB"""), + xeh("BC2D661E6283B835BAEE160D1448957AC2366DCD087176E252F81F1D11E28781") + ), + new EncapsulateTestCase( + xeh(""" +70A72E79BA178F8951F762242A240036093906A0AC1F2501402779AC6315AE8A0BBDD47A8F347A7E8840269157C93A00CCE5A27CBB16AD9179798376BE8638FD97C976D3513F96B2F0542B78893644793185425864C7950E23102BBA9A4BC9B14F2B4981B673F8C55480FCB4B834490C9BCBCAC7566747A38777CAA5FCADFE9710D8627236E52D9B5463456586E4F963A7308040EA243E62A8EF87B418D92F95D41A57AC468ED5CD51A2B643D11E8F03AAB4F43F2C8160A89B5ACA63C7C9B59E2602458AB103AC58085EF7A98465884BF16A662342BAC721C1E59EBEBCB2CCB9A4FB8A3A650C52B612243D133F870613BF5A9F30095456247C34C779C899B6CD17A181903E0BD1A13AC73BD2848724F25EC2EC037852CD6A960E2A3509E982513FBA840D28BB3B732D76C5909B6612A6650548C709961368F8116236B6709AEC97F7C625094B93BE5B11E9217C8E845ACEF8ABE3742724969C74622C5CFA7776135CC2616B5079AE4535C39C1A3154866AD548C950052B88888761D846C6240C9B3BC0EECAA284ECC4499660DD2BC1B3959AB943612F35610EF1688C41105693061BF16D6E290BFD4941C0460FC173694538604CEC6774C9614EF16B08666ADD3916CFBB39B4BB75EFC166C7E8BF70AB8B872630AC554028E8C147BBB56D3BA312029A68300CC743B81BB35878B26892696F538334BB0A22DC91391D71CFDE723D9E813B2EB844B6A534280880C37B9421572A6B85AFB8AAAF5AF0BACEF356B7F32636B50B3336B7636ACD6C685ACB178AF9986BCB93BBF1C4C69AF1AB569B60B133A480D39B4BA319A6535CA92293D5082ABE76204C7420CEE02C1D372D0413B9F8368098104120D432CD184550667A976C9DDFE0916D423EA2221E64FA95B3F254F59359BE711087732B7D8336B99CB95C7BAC714742D0595BE953273E551D1122AF9B49495DD1B935255726A643D2F8A4EC9A6F573A97C8507FBE6754179A9439C33B0CA5BE3DBC9F19A18C3253A6830C6B69821C86E38A71CAB632E0A578F57A5377015FF43DEE85BF9C67591A1CCAF2C6917387C4B5193404C87AEED269310ABA894FCF51793DDA786F80CA209AE909B8147FAF316B06E4AD8C516BC83B"""), + xeh("6745F4F0730AE3F14A428A95C9CDFE82717EAA94F65B00A01566A4DCC9ED1E5E") + ), + new EncapsulateTestCase( + xeh(""" +5E101D0614A50B307E1AEABE717721690422A1A97C1D05713ED3B206D57919AAB32F6096A503C5C1C1BA332063489038FD1BC7F7B816F6F343274C19E01B1F9C088B311A0C8C09864BEA142BA2C829C5B74C988266BC9F12D37EEAD97FFD48AC5DF0C7C595A5626A23E20663E8F11A6BB66BEFF4A91D6C7CF551B34DD541D3DBA1F16BAB95312A60F9625DDC4FF1C6690E9B05FCC5CE05742D65D5915740AD9A7B60F9D098AA62A6DD3968DFAB5ED93A54E305596AC8B1E4967A5AAC15BB4B540C421571EA324FB422990C2B9B82A12915745C24BFF841731C6C07FE705CCC9B4C15EC42193472A4542ED5FC0B0CA98A91B7CDEF68A6E7ABBCD07B984795151D72365F31BFC76793FE485FDC663C6B7CC43F5A9D410BAAFFBA43CA968988337C9BF802CA221B3C366A22E66F703C695B178830473D7C372D338A4548E7C88A9C4837860419A2B60A3CA9AA19A21B570BD22CA228C019EC6420E77B340F32265BF86A666C9FFC75B64FAA22860B205DE33492B1720BE514BCD5A47496BDEC246D97ABC377430528940BA447579A90C9E18152F69BAD12CB7C51C48CAA8BAD1EEB2867F31691B32B75528056E56955BC4400A249550569C722410FA2573007BCD2B7331648AC9B424667582131473C2E8B11D1299DB6927384B257A81B6E7868AD00216C8548739EC83485CB330B03BE99DB38EDA338C6240828D7A5FF463B1C0C88092CBFEF3A2598993C72F922F2EBA31FEC317570B73DBC53C7F04810878FC9718552CA2C5B7220B6B7298886C94D9C8762A4BD05D8BDE7E9483850C0F75617686174D42CABA69B2968004992467D1CE078B03884F9E00B901473E7059195487C5E3BB0B938049A257C8046B92D129A906669BB1B92B1A83FAF951A9E8332A1833D665A720D0451801874036A7A5133318CA94015A63FEB52C40158644C3869F2E37BC18160C8ACA2381BB9B20B5A58961AF2E8593884ABB47A6D968A8C6BBB83CF089C6B75B6522C77B2B4064EFC50C2948A18C85B1436787C3A076547271F33B864D5CCC585B317193572428FEDD54B923973A11287B6527F68535DA629C904AFED0646115879DB4F48777D2CCDC3784E28834C7E503964FBD58C3652152D"""), + xeh("C3ED79224CB07A8D37DC9C789BC7AC8E278968E429087E5B2C0E878934DAA53F") + ), + new EncapsulateTestCase( + xeh(""" +F3007CA415887CB8294B07BEDD802012CAB18EAC1E58268C821BA9A63739E64AC4ECA1A1CFCC7E61E73E72214981ACC725B3040205134A998E3B0168F46901788054FB20C88EA08F8A96B1AA86CCF2D778E3363F4202CD8C655A14C13D8F954709F46FB78175DA1C839C612CC94984D33A40A2B3CE56C28302E9C849CB51F8C60B614924E21B374A381F473344847CA1E4C610A538645EBB7CF3E1894CB2AA2EF2884F1CBF7734426AA315BD52569E533D374A91EE6A8BF8E05393EBC1506BA0718C40465A7F24483D933926EBF49E9A65C56A1B25F1A122D03A14F150C62EF186EE39335DB1A99D2498F8C552F32568CF714C678943D74651AE345513A4B4D1460040831603874CB281CFF1F49A3FD43EC80724560136C07C3392D4B4493726AB25CC00585B1966B8E73246ABF05D78C43293670F18B02EC5D107A8518F014ABC1108B60B3781AAD6BB5152B228A5BAD5D81FBF0ABADFC1B89047C3EFFC77FA5ACF0FE88CFBD40A5270408F20601A981FA666B1FF9B6324A47D67DA9621F60042C593725A604CA25483714AEE23A38B01AE7EEC4BD2422D7231157533B819F554BB76BF26D9A2EFC10C758B584B1B663CB91023C1869E5283FE13144CC3149F6A2037D53008F720337A58534360765038AC222F97B9C7551004740A5F526597712504FB2B102906A35375943C011C8BC4B44323CBC690A5814A385CAAC581A8530CB201FDC902546C924E1A51B1154EA2D56C3D898394A722FB3B962102262B9A410B12AFDCE8250947BC13A88B40399E05B025A9770D6381206D895E2D319D6C2A237A26B06C7302B61C1288EBABCC439A2B8284B81407BE18674102AA5569A10461C8B1E550ABF41F5773C7EBC8B2E2B968EDD56800B9AD3D95057CCCBEF4CB143489C219A6570B9A4CE23B6044580F7AD2CD2597B8EB5300AFC63C4DA2A98E1C7ACB57C2D7A06E836781F5CB86BDB82AE4CB1577A0AE5540B4D23B8EB100B02966C440B68CAFF36801B99F38649D3D8A49DA61C719D196888481C798B76CB0BEC1AA037AE4271E04BE54075AA51569D700A95254A8CFF1874522935259AF76CC7555A056505D0ED973B075E185A37AE9EC366F52023FE381ED83FB42486B"""), + xeh("41C74E66327238C6F7B2ED2683FC5E88CC35083512BC285CCB7165499F34A0B8") + ), + new EncapsulateTestCase( + xeh(""" +A4F9A7CDCC7E700196FFF92085458D7D6855DCEBC5D98260E4C32C94DCAA47606619C6C02752333D30BCB0E82909D7657FF199668B8824C7B323A50D51203E97A944467930FEDC000C69496751C3C69A4FA4492CA6454665E56C9B677845D6CEF70A21DC7028C4D487629B9738C300D17995F839B59793A0A8813BF9012E0139BDD0EA31582BA31E070BC7F2B44FE57CF5F36CB9D92C6926B271C290CA44BC3068C2981C6CC7932A82E69C1AA9616D99C36CF37D8DE7642F2A0A615B6B85660224ECA4AA6B4779A20A2DC93BF31BB25582705B56B04FC1898CAB5FF97B6934158B4BD9994B4A1643F8A185483F93AB349536A29A3445250575CFE07122021AEB450DF71943E0818B664951137880AA5586C66260B835BAC540378374869084B8E3CC91B9C12248E2A75C060EFB6925C35A3DF34BB5A8E76B4FC4706DA00C2C0331502A3B4030A8CA25AC07EA139FB8B4733957784551208662250B542FFB6B6985A130C109FEF00E30D6C238FC0A10E567737B8776B94D3FEAC0FD9B055FEC78BBC4961015033CF78805872F1F9899F69492AF6A35180C8F8393071BF020F746506FA50E5AE7A675542610F883B24A103A32CC407933CC2160FBEB0375A514A2D405992BCC8FCB82F3799365D238E02C1886B9499CA2C90D8B33FF32AF51F5933F721FAD5CBF78EC78802C7DD06777DB8C0FA3C0CF09790F65630E772177D4D9A35718ADEA8758057601C249C92876799167604664BFAA93537572A6A1425BC0AC53C85AC64DD9A7BE436F110C3AA68BA0552994DC019F9AD80B2767B879C8B7D4664AFA6C937276AB40417AFDC2895FA756909864C4E1867A537B42E271C86953B16279843C88DB9385EFF67FCB8A6BA13025B259398F149B49E1A4A9271CD7C1B5F0C6BD7AEA36CC6739C2660E262A3189E9AD342215FB5A95DB2B179CA763A8AC500EF59A4A243F6E6C96C278426D472161C1069A31992ED9AF9B88275D21815F1584CE7381D487457CC15E04E13FB4B93F309588D238BA0B59867680585C043857516395BACC287491B0E65B1C175B41045F2B94202F888B103A6683BA958FFE411135C3552BD546F9E3AAECB8C783AB074E809056545A8F7B89E7BD8DF0"""), + xeh("6DB6A3F134471A89ABEC3384BB48A3C405DD3B2A5EF53821A3C1EA74DD562799") + ), + new EncapsulateTestCase( + xeh(""" +34166E98297165A69FE3818A3857B7D6E97180D938B8B56ADE8C361F010DA4E933F85A911214465BA7A0432AB99A519BDC81647CF72C4498A220C5B5CFD28566F4AE2CDB025E6270668153AE8B54C22BA5270A1DDB5660984A9812C32E6AF44385C494D55013814900FDC0CCECD7963D9945C4A7329FD5038F382181507D43A96402A973EF683499854D29BA964A530763A09DFCF4B97EF549E5A60C1EC921F8A2C9745B364316784AB27D96F8A9980727E5AB1FEC832DCD023D1774807BAB6D02E898EB0CCDC0EA26DCD16518089BAFE96AE395348481427788794D357B59E4421355656318B3984623C472A01C215CC13B74A3A154FBFC4DE4877ACE367B20397F6FD29E757354E6542A31E48E01B43EFED71BC6AA3540D3093E5794D889B74CF73C6096AD1CE46F4D5A912BB77C10C8CD2F92A6A952B7EE647D7E73C73185942CC331AABC3CAEAB4E0F86776DE4B5EC53B571B818B6F9BB31937EEBFA22C6E9B486E0CBC8658CF2537B6128C939A477E5376C59024440C56E853994FC588EE3D883B3A369D6CA24F228412140BEE37C11E8718831B24C91C46A54D09F75B99015A92AC7049697260652A4288E49A25F8C223709A035F36DAED2749DF387F6C53DB022535E729A10C8542D84B79AC5B44029BAAA360EAFC90CDCC754835A207378309045B7DAF6B8C5B6462A3B777150BA65C73B68F75089E79F1E820889A7705F4B6C7E404436F68DE4B50F0A082C0A8258E80B22646C29E7C732D9489AEFC11AC788593EA8C865970F83C3957829A818D1734DA277871493B45B93DBFBCDF0366C3635C0247358B1C7B8EF81B4B2EC8B4AFAC90E1983FB1C70121691E5913AC3B2689EB28773179E7225788FC319490393149A352EEC56732BB61B1C086CAC906D422D05917F3F1C6F3A57A7B61BAF9A852A8859B5B4F183B36715E578C63DFC347F86005FA11B407494AC4B19A7FABF59D10A34C58C6308768CF88BA463AE8BC243405277AC935D1C5238335B47066910917183444C79E959AAB64915C9609A5A12461F9125062C2536B73C5A5C1002269B0C023E7228AD1084918A247167D0CA5D87F83ED7B3EF523CA41BB22FA002ADD4DCDB3E7B68C892797481BC0B"""), + xeh("121DC782B740EAE666E709EA6E3CC6CEB8EAD204CD7D85D2256839E98CA57003") + ), + new EncapsulateTestCase( + xeh(""" +F3BACC6A8C9D390141981325C2DBA6EEF3805950199468661ED4BA300174FCE35411963B2B07599E14524446892603BC300AA3A25B45B41A857D50C06595B40B80159A477D8AD628F455038960BB23B0BC32D90D48E014BBF0AC12F93F17E36976A8BFD1E7B682212815A18B10B5301E0B88A7C17C850AAEC549B98195532C9323559591F9DA52703CA2EF921B1DA82D46A5B522F69109AC83351C46BBC375B61A8E7FEB0161423D5246362DBC8C866A899FE42F3C3C52EF82AF2CD05C11913B87E67B060A2200BB60D8B94E58C1B609DC9FE36A147B5C83CBFAB3C5F59F2032307E5745B7C68E324CA91EC987AF771D9D774B49E18E1F828E3D17641C51CFAAC9450D3A4404141187546AEA64939D94B884868876C86348E27DB0F66BD1A06ABD331B8999A446370982EB25979C35733791A49608D412500E9A144036970C086F15AC90F1699CA79928416858389908F1300356B9C382C94A2AD5491E86C51905BC398CA41FCBB05951A54A3681C806CC4868266E100EC2A334DDEAB98BCC5699E192AEE81DAB58C5C3D24C564C9821C7C0F981A500D91E66108C52013134B9440591AAC5A9BDC6208B22BA88F269B823DC08BD0C4067B7BDE01B5B12985CFA30C9172C9A2D95A33D4BC4EC181F17CA7A294989F0306FE2A7C7F16BCF301752BDE3CD3F2CB81460C0E3B0373EB8B79FD84B05A783E14454A2F2ABC693AF0AB78A0095A3695158A2B6783D32BFF25A4F6EBC4AB5010C0E394437D208ED001CB3B2C92A794607A6BC5EB580E7D52342B004B3A17E20FB70A4C5C2B8CB39C9E265E012C7D03540E7B47681409E30D169AE1277F1230D97B432E4276406D0C4FE52661E69ABD03472F2A56F52B51A5A317B57D229EE0898DE0CB2FEF71DFB71A85ADA97E93B9F2CE3113E838AB458A9FE826090369EA0F496DBB2A21D98981AC4410CF698CCBB6EC6724E498ACD1AF8C480A6AB1A67907D0492098015DB80A98FA8CFD79A74AFD439B4327C07A03C71AA7589D757CAD8BF86DCAC20B133A5511A47DC74B12317FB305098069DFE360250AB29A4239B1792352C3571978B708323BD2CCE72D18392A9C3CB7F504A14014231E9B4F65FEC62AD3125780D51E256CFE1"""), + xeh("307C7DF0692D264A8186B8D844C7287B236D0FC7EC148BCFBF261A16B0FB7B61") + ), + new EncapsulateTestCase( + xeh(""" +E3F49934F999E0884E019B9299EA5DED8B5374851D9BC24079FA481C534793D328BC3B3563D0922098B98AE26406BB81A48AC0D24102E1D3624F974FCE49786890AAF9EA2E9CC058133C66847B67EFD61C7B469DC8E983ACB6ACB98C25D2A84A6EA82DB780531D0A4FA3A84400C70DDB48CC52406CB3155EC059894A4C01902129D1614C3BC25372C730CDD6CA8B204B9D18793ECA8B080881119549779A67FD456520B1011C6609CD4329C1832F7ABA7997D79B9510409C920E8EBA32A476B72061CE58A8A0A8B369315A814982A519E88E8FB25B3C74B527776C671C7B48C3C9EEB76F2A60BB39D5722A71459B180BCA9A9FBA14B3AB764E5F931DA0A55FB247A93ABB8509334050A029CB7145D4141990929A7D224FDC905419D62828625E316778E1517B151CAFB1B8B8E5E96958447944E266F808017C7CCAED571C64D9BA153709C303C92DC69B808941A8C3C760E52EC7388E800159CBF8626F953E356A827AB8692FE1982F07884FE3B094ACC0075128B3D54D85C39C08D065B6E40B5475CE1F269A2227AD4B368C683A7E797A7857C26EBC1C5207E6113C8B17F1A77186549FB63617611C33CCF38102062094F12EFD292A7B0B98A1423B92DC318E919B3DF441E58A36C04C7E60B270A453707DE23958974EC3A455294168D1265EC6E606AC40C79B690E5829A0F72910A0F5031ED1A5AEF841C58A036A10025B419E0E2BB4C6782EC317786BC1CD538C18B7223345699D44860D0BA04413E70B7D5126D2237545E550893427E34C6FFA40200AFB5D527B80C4A3A32B42B49FF5043B14AAF6A69144D58388A254F7F05F1DDA51F980A3D5DA436540A67569042E6B42337A712FB65A208392016710B8FAA763321DAC533BD06219AC6C48B6929D54D7B6A4A46280D2B242A8C1BA5B2BB42487AB031558BAC899EC3188A1459DB434C5463DEB43BEA974C1167B83C657C93A9604114128256156EDFBC604000C05C84FDEFB2218203131F40483F9C3B06C0FD524129FD65D0AB55714052A24588184164AD4B5929668A5A6F26F9CF44BA946874A21827E5B68A71B21F20785308A3F8DD6EFE22012FA9F25E348661EA987E6455F85D1A368EF1789708DC7AA8E849A"""), + xeh("60363F5CDB16BC516A1367DFCE1B72926FB2189B88AA1DEBFD22F440B9CAF0C2") + ), + new EncapsulateTestCase( + xeh(""" +964B324032B0EA05C8042A49F702AE0FCB19257B1EB97079994A9C67043D99CB08708A2F64E694CCA51B71431DD20A77BAC80AE5A259EB99517020CC8CD53D525454A1B6052D4C598D9C504795835D9A45CB5CC7BC6313B857B1884067B0D97961108E57AB00DDD8AA5A69356093348948208947ABEFE117AD92C8562B5DB7DC037AE89C76D00C4315548372A272C32B30168620380CA0A697724913C173AE31AAB4B3B54F3760246A310F199027A72BACAB7046AA702710C145EB9A6F312B3B8FC291762BC301C900E7AB41D298A01D890AC3C85A40D0BE406000C6537BF9503E70986861D90B2EE3C8B0047E66B8B88CAB3AE9FAC382C23D06B835789BBB47A94823180859969535D058E7946C69438F89236AEEA110E404B51C1C22ED04CBB2EA32C957795797806F179A38642023E8AF6516A11393A0256A7EA3C27A8600A669FABB89E144E30A839D391E6C1A1F7F96A1E5FCCA889C8B09C3779B407075D97EE893AA4CAA1F5E5CCF3C5CC4DC361C8C80525BA81C05488012CB61D3EC87720A2CF0977BBA49B8F9D81D3EBB50FBFAA420E27AFABC387EDB87F114C1688830D4137BAAB10D1A6554179398B2D939C8F4387AF0007CEA2AFA9BC56E2766182B0C8D876123FB1A64C405CCD7A9869466B5825E23F41C4BD1747D5CC95C27912DA559535B195B96879F8C14F6030020278DBA6CA371C76F6FB7059F0B7E1EC67AD410B12F36878274C0B19A2F571A49A0358B945BBCAC5142F131C94E05C6A96C08DCA52819640431930D4089B2CA85A4FBA62F2B2614ADC7C4C80B06745320F837CFDBCB0A2885C321738C2B4233085A1B5F4AAAA658354078CCD008C496F0006AE08FE917BBE35433570B4C1838AB48593466D58F18A43A025355ADD4B333EB8146251E32FAAD8742BC847A7916212D5DC69329D0A3AE57147628928FD0B08752A21AC308515229EDC169FB6141FFAB3347F427ABC759C40C8D29448A273441A9C53654042967087F470024EC714B0708C033436995AC4FA678A9FCD724F703411454C04C21764C1B243146587C774897C6752BF79868846811106552C8AA574AD8DB7372836844DA6BABBFE62263107076C4CB48CB256D359D08F68375BC"""), + xeh("579474C123B3381801867203E0021E2B7F15E5F9426D75A3EDA6CBCAECECCF43") + ), + new EncapsulateTestCase( + xeh(""" +87EB24113349A40704B7243F2AE3653F24B87EF50E2220924BE06BC1E86E8AD9011768B255969F4F29C21BD38D6687756D795F07286B4EB04C30143C4F76810CD3233E630417F86EC751CAA87806CDD93EC0B5332758CDEC3A37B4F84878F89A4E687F0E457E45602517B676FC944E0BF9A9E9903EF895800D019304AC223E37623EE0C7DB798AA1A7452D298036A4197E89B0F279A385DC19D20BCED386352FE512A9EA90F973B6890964490538FD82A1748C98384C38C1434EECDB6EBF561366C228AD0086D142966BE1B8E1025097509E460850087935CF543A7309342424394267032A84358CD76E4F98C34B0005B39811233CC425A237AB49CDA9A884DEF6832B1A2031F5AF07DA4C23681B561C7D91A22C65129206187EFD2926016717F1F318EA95CC037208D2B313E0BBC59257710EE99F9B81187837861404CF4E930D0A4185CD3779CD4830CE2A02049AA0BBA0BF06003DF8A358CFA4CB2D3B7C7A508FEA1B930D1BA379E246B9BB793D1C2548F8BD908315BF521200261E42C843D963074CE4CBB3A5898976815CF3CB0DCC137F0CC414ECAA8883CDE897649E81BF707216FFF23B124B3FE6A39A45EA317BA5ACF8116E9825BE6AC518B4658D5D23CAFA600F94A9ACDDD38F303978BD64B4CDE34E73334C1B212060E29085925E6A3319EAF72097826F4233CEF2F4AB1BC9CD99B9338FF43BB9EAB9723140CCB86741C44E5D083CF6FC97D071CAB3135F6B358172468DAD6834FF3A1AD0750F06837EC25C6AA4F179D259A0FFBCB4E6756B627BC1F9F76DFCE2712F7340F6AB2109F023D6BAC5F0A6A63063BDA11625FD93B3E8C7315D387AABBCCF763237D785A89130A3DF63AB2F587D8AC4BC90B795C3639EF2352D0314AD638A532E625A78F296B5C5A38BE65995F8859F279795D0795433BDDACA847140650A72637DEB3529E8179CC056FF58C3FA094678526E12E791272BB623367D0103A68F6811B0636AE101090B2480EF8C6C59B51426E6A3E8C5303C3200EB783A9A133AD2E5261B5371FA338B6D016367650BE0D4A93BF3CD9C48629F8A448AD9AE86258F454BB2F60B1BCA578FE20B26DF0732C3222BD4B8A71A2F5038031BEF9EB0DFEFB2666C"""), + xeh("E2F0D46B6C4A43E94CF967EF2BAC7B68C6E0424A37DB52F2BC0C1695D1A66B67") + ), + new EncapsulateTestCase( + xeh(""" +FC93AF4B238968BC258C1CB5B94592501A51C3368DC9041A56DC5E5D230343380E287396E9B821270633DAD37C920182C82C9236FB28BA025DE94A8E552A605AF1393C988E08419BAB6C8709EBB41076192435699F1C48DC149D3F040A5A36ACC7C869FAA5AB3507B8B32A6847EC901DC8B9B19A04B70865955C4B3B01676DBA6B463C36397B2A42218BE0DA0B55E1A5ED8975C002A9520C114CB672DF5B3A7F838911F7869F148D51DA2584AA0C15F4C2A8C95653C95970D2BB4805928DC02D3DB050D6338A50B6C76332911E639DE912656B72619DC66790F491E0DB15C258C000650DE47268303BA52A49A9179A4DBECB45E7B47A74A35DAB781F52D27CCD2B6C75474474DA0374E25D21AC152E5AAB5225BC7EC5A16F5A1FEE930C300A8A15C090CEEA999D045D80CA73B5484C9E8823604AB464404F9A9609AE920ECDC688E17090CA6B7DF2108151E04BEB6A27F7EC8ABF95BF84D23CAA254A93F89DBBE133A6B1862A20B2B7241ED0695C31B17A7AF1A6A557BDB431A3D2DC06580A8DFB52C91592A80E3C1995E5B69D03AE3B8C13F37AC4852C888E077C290928420A4170A377F0A519DEE8789FB7BFE6A214C394038E281B56AC36B5474286A23142E14561D494AC2CCF95322919A34369B94D79BA787194A471F3A3271BAEFB4019FFC040C831447FDC9BC19B948A0710471A233F0B7104826A83B881CBF4764B1BB4441A843255A8445A034AD6972F4C66C906550C1C5E0D30B718C339618B3564456EFDD0AF36A14D7B705E62153F5C880F017740288545A6D51B13A671EE00970217BB3B33B69B56C823148A60499CFA960B06EACB3F9224275BC907D89E4722C1E35C425DB0ACE65B7929F66F82204AA2F0148BC0B7126B4EB13C4692EB3732E3B2559AB0B833AECF072C2060B1DAB6A9F8BACE386A098CB9B7B7447E6957B6219C6607B3CD83BB64A4B12C973C28DD7933A4B95AC3C7C59824A32E271007ABB369FB06FCC82B20D38BD436B54B155A5FC25381361D13B41D0C4B309E3A4C295C18B4F845573051C81B0E6E37A0D7869D23412F9CF55B3AF5121E491E45292535577EBB8EB2CFF39D783AE72D468F687BBFD838E6A61F5C5B95FF1F20379091"""), + xeh("7B34969C65DB28996B6F9C440DE09074CC98DB4F08BD43E4CD948EE4ECFDE8CA") + ), + new EncapsulateTestCase( + xeh(""" +894C58C872A67C630143FB29F5C2533614AC1ED6CA436463EFB38C7BF8A8DA348DAF4BBEF00A8E61E650CA9C6BCAD30CD330CC2D032ED7E42F41A9967C3AB568A0301A5A12EF70A2A6EA97B187691AEAC151029CBE350065B0C2239B67E303050D92A692237E21900BF2901A69231B14F04901ABA8D22A881365B943BA429AE31A72B8701CB07029E129B5D3BECF9090A70A5D3A86BE1BBABCBEF35592A7A74C2CC0560C0EC2ABA3095589C7DB2A5849CBCD483730F479ACD55B212C942F900407E46C0C584200C1CAD7D05C7DF467FD31C31E266A50C375689CAB1BE672774C77062018E74CA1BF6BC5F223802EF93CF7A1383F548196A9B4DE958C49014EDA8501BC8A56B2E1A2B0D46E18101D68816EFCE2297CAA5CC509399A0152232026B754A90FF104B9189426742C2FD8055191BC162B04A262C3D23B996C2AA867F3154521BB19E0A69647718FB76EA5B487C930A454943F0FECA6FE163F40557AAFB9785DA0B6450B0BB4095BA23AAFE83B731356B290DB64B4C39DEB5B30FEF38086E6841B660D41EA593E1C24028C60BC44A6D83696F88772425235A4F05A1847AFD5C84DEDC0B4C1D003F29AAC29710AEDA5053A4C0AF556C4F5508C45FB20141B1FB641AAA6EC6E88D0859553896C31A0206631750C954EE73B415CA163D30FBB75CFEB15714E3330AA346F7DE02014214C2EC5AE550906EC5632CF429BF3467FCB0327017703D08A7F3E9A7785D0C9D6377FAFE527259A0ED5894E2A8C766F688FE2574DF57108C81C60A8705DC7D102891437CB2B9988C879D7403967A83A70CA48D6F1B18A3408BAA13BAD9C26297CC10D920F0C53CAE4D85C6EE0C95DF22321F0A05894CB97C4A45F79CC002DA373AA857B65C726F54B03184934B11376852E9FF58099C72BBF531943EB5626C2C3EF6BCA145A2896B4C1BD29A353F49EC2FBB746134C1F50AE6D771160E64848396A5DA65EC32014F9669BB83AC52298B24DC2AB0BA2C82C0B4017B34F9D979D7D07659C4B76160999C47221DEE91521418948CB2EA72532E6A1C273B764D3160EA072A48782336B648C12B6AE93B5AFF289F81236AF0F9A338E8EC35154DB40386949D6E32A71D635053D5F55990C92"""), + xeh("4F7798D88974637071717FCAD2C0ED5333945D51341FBA4BF1962A3915D986DA") + ), + new EncapsulateTestCase( + xeh(""" +42803BF789094EEA7D875BC10D50C7D3947CB77CA48A301323B54FDBC94E480372E54AAB12C9680765A3E22988FF42184741A440E348C8D19EE8E7CF87B23CE6944663A4B28937160B0C25943A8742F811D0E417CABA034628A11FA2A06E3A5F51E47EC26A9AA5209582F73F1C705F9CAA74F1F300FE9049030061B9C61DB9999E1498BDC9250EBD324F61827463A6A5104796EFF25405AC687092B78248A2F9171E891729CFC11F86316AD6754E8AD249E7849958B2AB380783CC4123BBC087EDF1075BA8304E339F01242C15385A4007616D873587FCAA5AC786731447DB8C537F0CC64731A790E1BF23412AD9342F9654B87DB07E8EA506C534611F48A9453855CA669EC8AB548F648F8AA9A715D0BC09757A285320DC666637950A691AB8E2630A08B59258205BFCAB9DD37C94B9F4706A1114FCCB806E54751A12576063666252CE7F5041432C095CB469B5A1A634508CF1E2398716272E9570C1790FB53A3100D57B5EBCAECC6CCA50B4656F5219DF477C8AD4B7B727BC2BE25246C526D06B8DCC30423421667E554DB0ECC21837539F43A719CA8952A95B143745F79899F7D1C79BD546B6559B1109BF6D60275CBA5DBDCA608FE34CD96369D67B880CCB00F4B3CE6D3C6CD3A35DB44A6F8E440215B027E03109A6546662789B6A096784A0C64A1A4F07F981CFD201F3687691955184684E22C872400749A180CB5B6317599316790A7ECAB711861469EC794FC894AEDEDB90E45164413B82F18CB162769EB92A47630A98FDFCB09C94456E74C0FBE345ED88A43466860CF0472B6C9D4780AC4CC7189F77A19684C54789A9CB99CDD46534914B1990659E71F2662933148E13272E723C46B4809CB32A42D378DA7688F21CB53DA08AD3897ACBA940640089C73049B1E92C94C943D5EA32EAA19AE7EC072527912643ADCB591CC86B97696B98386615AABC1D32D23D4D22919E35786E77A4E7E30C2F6730DF129089943FFCC1678AA600AF4C3F40741867DAA06701A8DFE6421CD0A5DF34C32C933C9AC2B141C5134A7BBD469266D952AFF44995F8904A148B363E3C2A13978A049B968E24051FF6E312DF77FC5663502B0187A5588C1D84149B2DB835045F9BDC1F70"""), + xeh("E20AC1D70FA6A2C8A286EF0E3665C79668A5E6AE80197BBF13A0D0EF553ACF1F") + ), + new EncapsulateTestCase( + xeh(""" +39B893D833BC95E37373D2C71FCA4336AC84DFB6460F156174B7B95DA92351468EC97439F2B88656F9B0B944850F499415981A66B76333402D43EC30F511AFDE7623BC00A1C58136484350A15824AB0A434561CDA2305C815318D204CA0315C5C9703954224522E76DAB0716719A06F723006D66A2916941139B1F29E53783E6BCC568628D6B0A0E72A44D3C19BAF35FD6FAAA9B2396CABA9B3BEA5C901B836758671391304E5330448A62CBAB155811C5018064FA002A73A71EE6146458DAB896B716560649BB823BA9F73ABFE44E80E1C4D0D58E8C9B397A5841FF9C93CB8488851C482C534BB710B27C6C9CF7A15356427EE8F1B40815A9416B233F4A05065495D4B88BD2A42A36DAA392A9CE49D67F4017484368017FB91ECDC34488F463B99A6CE60359A7F3C32D3A3DFAB70817726B73BC1C36FA4CAC3A0EEC9C6BD3A63DF9957502076150C4759F5362BA493F71D669A724C79788532DA797445942FDD214C3A9103738C00AB54CDE3639497A951C03A70A0B01182B2B9C8C889052857A2A541EBBBB77C78F90377EADA6CF21796E44EC4D5BF03BBDE6773E571785F1847252B1D7182BB4B08B41C54C889072CA0922A56C19CAA890D7F899EA21C9186A3A7106458BDA086FE017640B77FF554FEA32A2C2297D82144EFFE20D7836180CE46FDBDC18D357B6FA7ABDDB2858770598C03169BFCAB9B8794BCC48B779E87672D83F62E04D2B42B7E31451273BA0362B682C955C382442C010005E66A2644550BF9390FB427E4839616AD8C8342ABB0944B3ACE932FC134BC6EC7C16D35427E22DBC4A454D9B09FB49AA496BAC88909F54CA88E1747E1081AEDB23BF370394D3492F5B6AB02C721FE3E0A199AAAEA03A91EA1C44FCB70BD4140912AAAEC9F779DCB4A8C0CA9D903C0FA15BB7E5335ECB3724CE621D602772255775EEF07ED060734E7365ACBAA557E25AEC10A27EF405E1A431AD8052E0B752A08346D1961134C77CE4FA356D66094856141EC05FD7385D009000DC6C4F97A91B074CA154773498F61C646951BA5B6B5D50C4E35C6206A6C33043308B474A7CF587C0F07578DB4D6FF52DC654A5BCD997296C79A97F8C16E5667F527DAA3ABEC018CF1671"""), + xeh("AC25F29AF8D8A2DBD359600C8A500144D6C0236D729DA016C3F116CBBF621002") + ), + new EncapsulateTestCase( + xeh(""" +0AF62D21757B6AF2C9853421D2D74E0DD86A416A228A9035299C27B32528CC526B371C56ECE17C93B7CBBDBAC84D35441E6B3A17811F3C0A6556825174AC3C2BA51D53F176F027C20FEC424F7539ED3C6C7B964260489C3D8BBA94323630B87E856064E3BA81D3F018516971DFA54AC903C9AD9747AD8C5DB35780A033C385C23CBCB21D26153F93626C41237A02185C41C3935B306FDF568F453B255072348D9716AE9CB9B9ECA6FB0B78DF7927D093A3BCCC7F7BA711B27CCDC0051BE4A31BF3A0B224E0770BFAAF26F599AD190173A4A012A52C29DB006CD37076A12CBA65B679C10455E5442D92609DF209F6556CA36BC852D3A282F14AF3EB2A852AA268B1AA92346631953204F4ABD9726338B8B275A26ECFB80428881613C952545B082AC2BC75699F3285AC10905A00449AE6A42B43D1A4890155A9080A587090F7C91FD97833E13B601EEA06104CA41C408EE73C055EB1CD9FB0934E25660381518758CF3A8C95BB0397931427FCBA515D320D423A7440459C614B9ACDB25A9C143A6F704541A339D9811409D6BE200429B33674F61CA6626C7FB879001AC65F08C18310A4BCE685C37944079DA907316060A64069F87CC5D9FB3B56604AD8A52E72A1405AF5C549498F147CCA4A7749A37B5D96084B01AA3241288BD22592AEEC778FAC1C4A2BBF6085C2B5DB7D9C00B9864C480D8826C2E02B246AA945EB61F9425DE8E604B7D76486418FF0F5AB59BC6EEBB4932D6075F667A6AFA74BB66255F03C6F15A63818E759A4B05F480A4C0CD1072E26627513BCB85474E89676501AB2ED21A8F487780CA8CB8560B27A766213092DCA0B02ED3A24C8351EAE88947A764F142C0E24B192A2421367265C0B37093E0A69AE31756C5906845A8C7D01550E07C72FBB18DEF56E1E8B320F688110C4C4DC7680C9FA05D5B1AB63EB65450283ED6A52F9F535FDEC31C207A483413725022A2256663E2657977660AE63CA8671A8C343AFEFA8C43D9B8D0B93B458416CA4C5B87D121469EA5B520ABC0C079546BC1353757AE2BB1D301974BA03C86F624F34A4B481B29036F59F37DC2D5C1721EFBE0A0C22A966C895E5198A91F916DE62C0FB3A769806AE5827AE6F358D8CD6"""), + xeh("7114A4B4195826CFF174FCB75336B25D4D1BF2224D585014CBADB0C4CFBF7729") + ), + new EncapsulateTestCase( + xeh(""" +F568158F1981259934435BC2BFD38A4A100BB9826E429312EA3CBF04A5397A723E740112859C74CA0C2783D5CC9798AB3C273D3AD6911FF76BF7235AEA38C4459761FD4262F483AC5D081900FC1EA3337439A3B4A2787E0D5763DDD2100E6A60DEC12B07B84FA8226017456B7F65679FFC31518C172F93895CFCB75FB74054116CA5662886BBCAD5F6B63534703E8B0DC807952EA32577389F94A7355DB079639AAF39B13D9F95CEF9AC9BC4B3AAB0F7070358644ED38C401A73BC2B2270D01D1C207D7FAA5233D74296302A90E4551D380C715265DD0B22F94681EE6093450186738B32BAA1B1FCC3C1F0A309312B662D25120F6B6D31B2B29809537C4A220D303DB4E5CE51B606DB64CA4B86947056015E8857220B8AE4822F28D31A37F63A89644C4E3A797FD7236A52640CDA3DA6D1782E933361A74B2CF665D04A07DC3843A40A0D8C526BE790721FBA16492557F51B6B6904998422B6848C93EA5043A782312C1250D81C5BD0407F5FFC99DF3993D91A71AD8499BDA29427E51BBC93AF43AB49E9062397F58CFD4B8048392AED850D95BB2F26DC55D3D8AA2A7249DFC35DD145569BA276ABA90B78BA143A876C3D97A66E02BDA3A34BD5DC4918F776E2E2C09E46047771B8C6FAB8C5215BE7514900A77567896899E94282E326D4848606FA8F2D350509B19251B4CA4B5B016C4181E8091D501327CCB9AFACD14C6FE4808E6802A8875FB786A52B70359845634BF1C185C887F1BC6FB8221347DB1DEB6C183C412C6D3684A3CC244D37C1C503B69DE67D4B02773DB8096DE18BC717CB3FD9CBA06A370EE84B9ED13597E6BC4CF88474E6956370C88078A56383799DF76621183C70D522DCB8BF07A9546D9CB9873997AFB51F94B49EDE924643900E201097D9853593F2A7E430AF5C57C754142AB462A12D327D04115540B505B8146BB64347A22BC71C02BD2E9C8CB360AAE5C9B173BC2E844CABA9659C2CC695D0019C135963987A5F019989B3064F8A0A8E4CAC8C7909AC4BC028C4AC4750E8C4FBC1433826AEFDDB2315002A27A2B43C539935649890B31710C56BCDDB64E7866BD07009CF11E676BD64E680645DFC88E803063DFE292C2047525EE37B4F3BF7AC"""), + xeh("C78E7B1E5EE8F20EF0B67089306E1ABAFD15760B2DD2D7A59D2C00D496FA0FE0") + ), + new EncapsulateTestCase( + xeh(""" +F9238B1B1744FCE415242CB135300B13831D95854E3CEB49E72074B4C09B64859AF81A0C078418C79150D0083B8F9834B14116AF308BC7194C92575119371AA9C74C83350519C0108FC18620453E4820810B5A89D42B5B84FC134F0741E4C0466B2C4B58758A3D561EEA095CB3F469C3A34F19A29F3D20C1381669A6AB1857D3859561096BD8B7A917B40D4B754AE5CDDA47002CD870867203D9901AC5B852EB778705360DF4D35DA7B217951CBD2C026A4AE15221368DA5635D17EA307EFABED74342A6C387D29B59868C4955F6A5B0786AF5CB03F130AC7420663E343BF00998D83B9BFD6458DD63A3B5045C467957A729417CC133FB2048B8DB71BE36905B213A1D8C1BEB76BD27A7CBE281C305F44769746F90307B01613080D50F96CB451D717EF5F372D488B6FDCB762927B910936F161764131C80F09316526CBE62EBB07DB7300D7A81890557000046FD7C098999994FB87691A59F437A7F6D3690075921E973805693AC1CCBC6637471B2C561437A8E30220BDA078435455FBC368DFAD026F85417A5DA96D8FB6272D06F785929B38529D5990DAE3C7596AA72B9381121C6C94A7A593A5AA62BE830BFC0BF5B34C57221AE288302559045F3686D8941576EB41F32516763A90553A5727697AAD39B46C5D84A2382980FE3AC0F904DD10C97078B197B0BC4CB8764F22943F584BFA9F3609D417D65B3C367DA544FAB84AD16025CBA7CE7794CB3ACA32F3042CBB4C25605998A74BC16F80B91C5635DABA3B8AA0D90B1B59CC042BEE19709A747666348577088DC4C5C3168CEFCC5C12C3B4A06C08CFE4CBE21359F03FB99E1C6CF8C84ABDADB1DA905C4EB605FB9C8CE7979458080AC594759CDD82A6E164A9EB781F4BB24147039CFC98889C077698B2471417504E99BE7F283B0929A35E14E3670291DD728599181A6911EA2912B48515F88689A73E9688957473B0CAEDE73937C7BC385D6B2FCF6B76017A8F23A2A7CB54E8A98004E0C97EBC826D1A1142D8162EBC9A311C325AAD94900D9B115276E91DCABA8D015D8A549F7F56A4B182CB3304FCFFB3232F64C2FCB839420663E9391828968D6FEA820C57B8816E1F5D3B414481523D24B81E1E2C429FFF401"""), + xeh("D23A22F6DE6C0F3C28F5A7A8E54581BDB312A56BC90CF3B22A5BB39C9ABF420E") + ), + new EncapsulateTestCase( + xeh(""" +305988FF211E278150CE00B65C2669A14830AAA1A4EF2973101443E2A73A1BDC2CFD5AB88C54539573A7A5FA705C573693599C850370CA4A66E853CC283CCA0D2B52084C054C420ABC71ACC2C10D34C61C9CB0459331511107832B0A3BDEC7A0CD941D15A13F193162477211F29345414987ADD22C0FE95AA734745FB32F1114081957017B479108F626EF004D08AA327F0274B1DC2AC9963D8F557BBB58A9E16B7613DB8E379679006119B2DCC441DA80F9AA7F0BC2A8456CB78713A13985625AAA3AA9C6375BA06395F66EC3B63D4EAB2524322979A9B9E1178C4A966FB808C75416338237B3165AB20135ACB0437ABCD96251218F0C382731C45C9FA8141943743C1B1F5D77A064FC7968CA1F26B2B756F0B623323A01D8B0E8DCCB714441D7D5647F6C4338477926B248FAFC997B77C4A2BA625A3A5AAAC60C7A57682DE39D91D46778790CC5B45738D7866F7A909FEB27F70C9C4445A534C0AAF7A487CA8499BA372D3380A13C87978D82677A37C5C7A4490B716CCA2BC262C8853CB60CFA571D2DFAC83D428A010C760FC291E390102E3B6384C35067886940336AF5751E8BA399D11CC9788228E1E21A61F69E2AF7409CABB70DA8C775AA217EACABA3B2BFC7D608B374A47A2C96F56C57748B5137F8093121C0150C1A61803D5C6B42CA439E81A8C9926084F5B98931B7079DD44E2C9376DE77626EB543DF071C7A2C630A995502535FE8570EF7C987675C70DF8525D495C5F93B0B5EC7CF59154CE08A84ECCA36FADA9962160A1C2CCD3A728B148CCC9DE733719387D6C166BD9691E3EA6B22550A85A09989A49C90D68A51F195561A4F424CBE3152652272200FD642DE292A2061065EE1B962964BA33281B9B88222B122A3247AB9C247A9A6342F5082A685C8C355A1F96A0277BB8A97979937C17A47A2C36B3040C6B437BFC28B8DECB59DD9AF1B6818C146B74B0AAFFDCCB710E6BB3AD5A5F6AB7F8B2C2AD8980D6B569A5DD523E20379A6005695033260ECB823C7579E610F00A30EF745811DE05762A874A1986764A399B5CB1212403F6E7184028C5B2C47BCBA1A6537F180F096BAD9FA53AA495443314B91B46600EC339B950E9C4F1B1AD5E92385E3F7CA"""), + xeh("C0A5ECA859643D0134F2231C8F3764044B7E6073C92C9CDF71BD64FBC59ADDB9") + ) + }; + + static EncapsulateTestCase[] encap768TestCases = new EncapsulateTestCase[] { + new EncapsulateTestCase( + xeh(""" +89D2CB65F94DCBFC890EFC7D0E5A7A38344D1641A3D0B024D50797A5F23C3A18B3101A1269069F43A842BACC098A8821271C673DB1BEB33034E4D7774D16635C7C2C3C2763453538BC1632E1851591A51642974E5928ABB8E55FE55612F9B141AFF015545394B2092E590970EC29A7B7E7AA1FB4493BF7CB731906C2A5CB49E6614859064E19B8FA26AF51C44B5E7535BFDAC072B646D3EA490D277F0D97CED47395FED91E8F2BCE0E3CA122C2025F74067AB928A822B35653A74F06757629AFB1A1CAF237100EA935E793C8F58A71B3D6AE2C8658B10150D4A38F572A0D49D28AE89451D338326FDB3B4350036C1081117740EDB86B12081C5C1223DBB5660D5B3CB3787D481849304C68BE875466F14EE5495C2BD795AE412D09002D65B8719B90CBA3603AC4958EA03CC138C86F7851593125334701B677F82F4952A4C93B5B4C134BB42A857FD15C650864A6AA94EB691C0B691BE4684C1F5B7490467FC01B1D1FDA4DDA35C4ECC231BC73A6FEF42C99D34EB82A4D014987B3E386910C62679A118F3C5BD9F467E4162042424357DB92EF484A4A1798C1257E870A30CB20AAA0335D83314FE0AA7E63A862648041A72A6321523220B1ACE9BB701B21AC1253CB812C15575A9085EABEADE73A4AE76E6A7B158A20586D78A5AC620A5C9ABCC9C043350A73656B0ABE822DA5E0BA76045FAD75401D7A3B703791B7E99261710F86B72421D240A347638377205A152C794130A4E047742B888303BDDC309116764DE7424CEBEA6DB65348AC537E01A9CC56EA667D5AA87AC9AAA4317D262C10143050B8D07A728CA633C13E468ABCEAD372C77B8ECF3B986B98C1E55860B2B4216766AD874C35ED7205068739230220B5A2317D102C598356F168ACBE80608DE4C9A710B8DD07078CD7C671058AF1B0B8304A314F7B29BE78A933C7B9294424954A1BF8BC745DE86198659E0E1225A910726074969C39A97C19240601A46E013DCDCB677A8CBD2C95A40629C256F24A328951DF57502AB30772CC7E5B850027C8551781CE4985BDACF6B865C104E8A4BC65C41694D456B7169E45AB3D7ACABEAFE23AD6A7B94D1979A2F4C1CAE7CD77D681D290B5D8E451BFDCCCF5310B9D12A88EC29B10255D5E17A192670AA9731C5CA67EC784C502781BE8527D6FC003C6701B3632284B40307A527C7620377FEB0B73F722C9E3CD4DEC64876B93AB5B7CFC4A657F852B659282864384F442B22E8A21109387B8B47585FC680D0BA45C7A8B1D7274BDA57845D100D0F42A3B74628773351FD7AC305B2497639BE90B3F4F71A6AA3561EECC6A691BB5CB3914D8634CA1E1AF543C049A8C6E868C51F0423BD2D5AE09B79E57C27F3FE3AE2B26A441BABFC6718CE8C05B4FE793B910B8FBCBBE7F1013242B40E0514D0BDC5C88BAC594C794CE5122FBF34896819147B928381587963B0B90034AA07A10BE176E01C80AD6A4B71B10AF4241400A2A4CBBC05961A15EC1474ED51A3CC6D35800679A462809CAA3AB4F7094CD6610B4A700CBA939E7EAC93E38C99755908727619ED76A34E53C4FA25BFC97008206697DD145E5B9188E5B014E941681E15FE3E132B8A3903474148BA28B987111C9BCB3989BBBC671C581B44A492845F288E62196E471FED3C39C1BBDDB0837D0D4706B0922C4"""), + xeh("2CE74AD291133518FE60C7DF5D251B9D82ADD48462FF505C6E547E949E6B6BF7") + ), + new EncapsulateTestCase( + xeh(""" +F5841D6AEA683FDBA16308BDAB828DDDD7735B8B7A0DAC6A57EB5134B91D8D6CBD989580411144E1FB5A6A559A7056376210A8284742D22A5881C5214C90023FC910D5D02A869087557900273BB875420B5717CD0B23064AA820CDF372F3E4778D70AEB5D02B6182C4D37110D782B6E80303332697B4C610A384A0C632C0D9484A1D3B5EA921525BEC5755C839DF942F24A027DB50B2D760066D10A117BC9A1B65C448CB9ACF3B4F644316E8941C449803F6851A74D832A739B2C0EA9258C7258E98BD3E833D879A6845EC4ECC44B6FA699388135F5E4830F2625E9FA5CC982C578B2593D350B06288A854D3349C24586D3AA2E68726A873B1E5AAA3B22671D8C69AEB180718CB456B942E4B6678E620A00BCA310C722DDD499EAD9C6B66666A3DE39A45D7AF0BBB7AB6A0BEAF8BBCBBA17B1D097ABB09A70E410352D2084423AC53ECBB4C196021F01E662A60C68B3BF48A5F0864A25577912F52620CE6347BD27FF68A17D4B92CD7D01B89E3487A5BC2859781F3EBB8B5B4C2D682636C486A000A576A4B63AFFC05082B5ABE3CC0B37B1E586C2107D97157E325A067BB86453414A15594A510DCFB2FE1A0074483120FB83440DB1B8C3B41E36364F92056083CB9CF91B39F28CF00F6AD098AA10FDB4B4D9B64ED1338E0D5B7A5169C3D8C0184B19966E54272F765C0337BBD307F8C97369A7A87DA44A5BF468DB8A9AA5EA598F885AB50174B0F9025A4EB53D2323D202A05265331FD836DF8E02B4595458551ABED8A3875B83BF976942372CB37296C813ACD2C27B41A5514B66AB25759009DB38A9D0473D5B7A9A7D6795F1188A079B1792A01141347AF2194CA681055D36E954C02D6935BBA7C2EF7F4B5E47C8B0A0069F29575E863967CE4C53105230472172FB79E69089D5A7BCAA95784BFA279EFE67DA145308BAAA1A5A303757946C2866B4841660A99C1968B8F7DE799ABD71806EB9F091397C1CC4171152A6AFC36BD733FC6C53545361AB6258CB45C9F1331BAEA85BE4558935984C081F73E4B377E0251CA7C396BBBB81D271BB9F0589E1BE3218B0B5840372253AA80A5DB79E11199C0832B2433880B68BD84FC02AA3CBBEC205EBBC7B050967B4DFB11E2FA63BCF6B7656A8028AB607CB084C21747ED573A055166F82215D7201D5D439A19F584F470B4272962C137B38545309547CEC25B09C96459AB7B4DA69C8D7B9277BBC4B5568813DA904141A011D9B45AC1F181273149F3C46F45CA9735221B97CB528E8AB59C5711A57C603F7A91803254E8CC4A37D84D1F6535E5A791A50145E1E073430810B3AB79DF4053538C7DB4826A1B428A84553BB881A23507385271B32F854706BB2D3E884E7B391985B39B7BA373071455187B3DD7DA75F6988BBD6BC39EF2808C245AEC9C024CA16546A16F63831A7B6797951A40894A5E38422F30B87E70355CCBE960B216592D0073F1240C21BB109AE76C9DE5B7835BC08AC6601C314A82232FA6F6896BD7834F0254BF112602022844F0CBA9FC3D2E3A58EDD56DDC498ADC9A03FCB43CA138640F85397FD5731F537D6BDC3AC76563D6516F1CF24F84B7C957635DEFBBB70071621C8B2585380A63660EF2CB6CA5910BAD42A1B621CAB8C26780D4251DFD1C6370EF12193C3CEF0223187A4557BC08F4ADD382"""), + xeh("76D04F481E68B2F901ECAB58B6369A2CC31A9DCCED82A1BBD426BE0AEE266AEE") + ), + new EncapsulateTestCase( + xeh(""" +92D1A81751C40C606885C737EFD2B599413311EAAC707939B37500699131A44535F21C5AE596741F7668525108B4B7AFBA814FAC8AB0063B6A9060CED936CC6DA2CE4131695A89C35F2BA2F39A27D3925775FA9F43486E4C95C165A666FC3305AF30B419611D291775E0F08F34A65EFA146E46D207533B908F744BD246A94A4A35137731D02AC43E779E262A66F668784B30B231D83E4369400248AF3EE28432821F07B5020725C8D769B305B3AFA685A42E28C4F0E35BF407549361A67D7B6699CA0F293CCB776019585759502792F8D76A3698872F817A0C621084E53695701795ABBE16C466017BCC02B518EA387103C59D17127B844350AE428929810559A08BC91C2A29DAC3D6C14DA0979DCB4210142C6CD5B7CF18CB77E2E13029C3C23D2089C295411560024AC2AF25B94FBC14796652CFD8A524B6ACB8D9A262B7C26A279BBA7D4995A92A5500E081864200BFB51D46686AE14130E3C5A728FBB76944BA658718FC041DFD3A2480B9B6658A9D595BC4CBDC105BE019E128909978240EA29DA7C66664E17183E0B44969B284DB06D4311751DA4ECC6CC75C06395D5B9537078D24E2091AA45A92D18378415F1183C6B4E7546A1A1792CC07384106A5D5C8B1A369D3D6A8C83B927B72C1FDC7CE27449A5228C85BB6B0CFA85954C0CE5A5BB947F68C8107C1FF3B7D3D4900FEE59206B4CCAC5A1B4E65465609692F76227EEC0721A59B92262DB0F735E391343DC5836BBA779D6A558F8BC0001388E8363E3CB63CE49C4C7669C82B2B650B4611D094707571065B943F2108BCA33747367AB953D9423AFC5609591BF49B8A99650E4D8010617CC58645080DC0A141C34DE1D69E5932032E7B1BAB0CB2A8BAC3506B7D5E713DA79CA4E177A6CB27A545C9A80B3A489941A47AF84F59F292E314302ACB8EF0006F50A539E319951F6CCEE9F478773A8B0AE73C14B729EF4C0B89A99B87F4C9B8BAC735D31BB833342BD501EF458F955496138A6D07D1777A9489A24C74A5799A70C942FC839D20A8C228F7453BC29C02BBA3B0827801143F67691EC3481F9609BF79D9A8B7A1A7A610B05856B5FC8C3521968ED9695A00D71FE8C390C60A59D6734C608B7AC0B4643F7BA1DFD05B5BD853C9432269A9555E3912E9B263C7B939384A1794A50F8688296869AADB4B853091A291E42F485A6F93547E03BC1B57A603C81B7897198DC59252F9805A6266435EB2A26B6300D22667A878C3401800E6612C026C4F0FF99C889531D637036126227B674B95A38A2A93497FF83C8D3143A5398BE9C59909800B02C677B27A42621C190D865AFAC05513F72758B494585435F2357B97342D951A2AB23A1CF8A229BE909487BB2B8F521B09E0C4849632BFCC821CE30025B837A455B2D7D58EE4B0AAE1A25F8A5693F62B1AB77C229890899264BF63189ABBCC80AD1B8ADFDB21B0C2481342A137FCAE8A64B1E21C805B187AB7C1B637D57FCD8811E49C1D2A065848A769B7F02D99E40F4BE3783DE3AE4FE97E23CA716AFC0814C935293641D7C40EA1088EE89C2A43505237A593565A05065081F6181F35C55338C427CA628727DAAF8F5B5322E34488904949E45C61BB915525676ED2659EFC97C6A53376478B629FB32D49047412A49E98F186564A36EEF1CA4920C912B1211B"""), + xeh("FD3C91294D8C974930B4B6135AB647D4A7885C83FCDCB30CBD38332E14094491") + ), + new EncapsulateTestCase( + xeh(""" +CB2468A0185567F8A60ADB33CA5239C11C4A3E0C031D385DCFA28C3AE2A9F71904BF379CB9E0BEDEAC82B2A537357A9C3AD33362602A1CF6458A745ABED9233A092B962BBA2B0A66DD4A85DAE11B0C28230AA44C40F2B68687B7D54833062CBB5B0233E25496D1C84204B2BAB06050C00C308EF53DD8345143BA810AAC477C8119B1C595D964B13F837849B58D8E1BCE56437F2ECA84B86C91173670E0995D9769642B0AB0BB0713D313AEB7C41C9B2CC411B3B62B110308D94F0DA1BB69D406DFE7286519692502BC83E15BD50494C1047980AC6043B18D7CB72EECB00EEDA515C97C0ED08B5D4BB001BBF08D9821B9A75C02666C357F00278279348462759A602359F5A953247C1928172A013E3C53B7E95B81A64A6DB3AA86CD7670CF7C38AF357A317B71671B950E2BB85EAA6138A5AD93A1640618BD98092D85D36015C0B0DFF6059F3B09AE5007F89AB551230D8B9A2BCA59238405372BAB7F4D8069FF7457EF3720A171C3A6312CC8D69191CA909A13946CF8577A96086893C0C59B026A21835543B8583A05F569977E072299BA580C179EA2976810AAAA93F57DE223B97CBB4CBE559E18139372EB1A2095B8B509AE2CEA5B4944335ED385B23B5EB7D0847A557AAAE89611937495C825B7236280ABB6D409CD513A03C91139A251B3278C929DB23BD815BF68007D50B8356C03BE88F86E410ABFF6CCB3B11BC5D41C7839D48F365AB4E9E29F0B0094A4C4ABBD6761527850286432530241968122D2BC877DF5781D17AE12095C177B69BE3B989E81CB539A2FF2E28D623303FED5750C58B9CE051A6B813899BB3C74D82B2F127E51030BCEB396EF547ED37ACAF1D46A77F7B2B24B48AD399B53FAA69C079FFEFCB9F8367F7C513D142C8392A8BE6089CC2301685460BCCB19BFD6AC821DD840A3DA30C3208668C7103EAB78C6520C1291239DF8217C25450B70302020A4BFF384F0619142A04C769C9B18D27E42FA30BCE60A1EC2AFB618752A3917EEDC37BD15C44D0ABA1FA3A40C23AA14C98E016A592B459BF4C13C07354A1DE0539445882E21B97B1767015810325086AE71CDC0B5C0D7287BBD99B381680BD6559B04FB84835C4419316FCD223B84D03816D86C738334FDC894BC81B1E26813A2159D426AB1FB70A88FFC1782E649BD860D148B33F7607083A5928F1C835F880DC9E3235EA51E78A403F7BA726D17951CB7AE7630AA7394A80D95A1EDB1059F140F3EBC8D1C9BA9F43B75ED90538CB219F8E4A2B202084E049473D57D987CAAD2B51DB009CF8A538F8205B0B4049F41ECB344F84C538CA49F5A8FF309D036C6C520932F08072F5678CA68568A41330D9BEB34BD308F963224F80B5DB9B10E54D146CFAB5AEF84A7F9C62B7BC24A26A578FCC51E36738BDCC8AD24410155AAB74D8691C1E699E3722481BA074EEC75DAFB723863C308F60E10D195617BCDB877153D9CAA775647A83B1DE113019CD6C3A7CA38554023A6BC7EEC594FA6C14DA8353737F0A549715E39C49FD9625F187C3BE1602B6BA178D1784B52690B1E1380847203C13624418C1C1DAA0B231AC0FB39293843CC3D6B48C32B15098748DB0B3672377407EB7441B82371B56EB3E90C983A895AF85D57E76C53088D944840CC309853814266D66DCE88915049579CC45CD602"""), + xeh("7DB18CA35A53AB3A65E4C17FA096DDECB19FC7747E657B49D1C1710DBD1D197B") + ), + new EncapsulateTestCase( + xeh(""" +0F613B04128F82A73867D9185891C29D6C3E1381843BD502D86099A740BAD5BAC68C590510CA3F6F2B5463B264BED34952F10C784A92AB7696268410F1F28C06DA7A18416A7B1B5FD23393C33592248C9A8B3956A999483E000F2A2C6F796052FBB22F7F182A191602FD93AC066355B71B7E6BE36E531B1D34F0382E34A4CF623B7B1127519A7BC4EA3FB0D1C91626A417B6129DECAFF2865273F759B4DA1A95F79FAD0CAB09FB61D34B9AD78B8046F5601FB53D28951AB73842B8921B2FF10417DB4F9964A41EE820FBA83D61D30D0EF2C2CBCB1F6CCB9E77523DCCBC37ADB8B9E31A0F0E1C4192911060E8677140690EC671A5445F42FB1A68DB4D1678BF9B60129D98A859837599ABA0DF465DAE76972946C73E8343A19A3C03657806574F59D2611163334FDB0EE8B0C13C679C6D175C22807C86F0C199C89CC43C0DBE6587F0A36199143EAE30116B3B0D49839AA18CA49E2992740B5DBF1C91ADA352D39AB7D0C23FCCFC41E783CA0A333FFE00074E72BC834669931630898B718CD5304E253071E730F1EB067F94861DD98FD9A262FAC919FE870E3D21BCFBF67180C57A5D2797F6C7B96F544CDF92C3FA8B49EB366C02885140D128B88225750733E6105868AC48A468002F35C34C38AD70A7BEC9C37713B98D9EA8A716CBC85D0C3EF5B4BF8F20BC6BBC61CE8150B4F842CEE0A40E0A7FBADB76BE9B5CF2B39749F51BEED8400822044E2CB01C021B0D9B7FE67A8AFF9B227C120F643B85152B40EC4A1734E2A141159A5A96C8B74115A0C92E6B913464994E980A8A304194A595BAB892801C15CBC5033FFAE70F368A62C65A598773C199E20EC07B73B1ACAAF48CC963A6986D9A3D2D236352F66065025751B9884D7CBE3A5538A9B90372D4C22797659B5CA8D357CF00B27C5714344374A5131B261D948DE22390D0521F50553E78223388903CCF241FD608CB4FC1AC7C44A2D3141F0B998B99E704ABEA1E634C1F44231D347254DC2CCDDC114AC4488A549BC4696400F0BABA18198F46E8CE43C93581FB661C745AB5A5520D4450982569BA1B192FEACF37EA8EC8B8B267271A042022DFA177A7C1CC1CF6765492AEC59729D6F61690F27B5D010F22C30E44D15864395BF01771158BCC5F8B48F656CE5D9049D6F1C11CDA96F8C724E0460BDAAA1DD9CCAF0C46162B943461B729AF3543BC9A8CE3B34971B39DD25A6051D41A248BBCD5555D7E2028A5B453FC4062DAB1337B134009C71BDDD705C2E44C64E15C18F26361D8A7A2F7A13D3C31CB3147ED777024B8A90B558812B47AC861BE5B894B989200BEDB242E559801C164003C6EFA61AC34649993F782CCA150DEE1443892BA3DB87B094C491C798B5FA1AA30491B7C7CC3769476D28AA17E754773390316647CF33076CC6CA84C804B26E75295D2A4754B505A3831DC793ABD874C6C1451911B97AD39825EA42D65DA63C42CCE1EFB1397167F1E8933399C2E288AA57E000406A4C66B5A357AC59036F37A52516701B52934C6A1109593809C0F72170A0EC9AD22EA6DA64B0028680B405924287280A8C49B2D516DC9D6B93D42A9B544C6833C0340865905EB00F4661B200686A0A47FE280937BB00F8022B8F0E64AC251BB62D09FBAB3E7C79CCD450EECA94120B05A0B071588E2150EDA6B14150F"""), + xeh("876B17263B409171B746C6936EC65FC94137F958DC974BF98110A1D07F6D95F9") + ), + new EncapsulateTestCase( + xeh(""" +C9CB9FD04057EB96006455C062E3C0722346ADB366DA0AB980C782C417B360EB1C1F6762EBF967D713A0D93A28CF9206E95451E91373805047D8A14FFD2041B4468B26C79B697A14EA75A33876BB865096C0289C1AC4B91A4399821349DC66496DF02B15CA433FD97D96F46F72E0B23EB561E809601C053A35F4171A963EC3F542B423BAFC56134B7C0C5927C746E6C8055B3B70B31CAD6A168DD78F63C64FE3044280297C6630562C48A822B570E3FA8A76995BEFE67734274337F14FE00C723AF55D596BBD0B2C04E5AC6D52A0AEDB04B2BF09B1F9736E9456C40D5976B1EC2CA21C28AC761E39C583CDF256AA3262C3264250B1C19B00849FA83BCB6614DA0BB19752AE9BCB7BD16A71017066F73804AEB3C7F9213BE4634401A7AAE7BC56E603516FA2839A791EA89C58052030DB4AA2887737D9BC9AD21ABB94246546892785CBBBFBD45102C24D2F2370BE91923E732892E599D3154502E878CCB990CE8383D2F5ABF021BA424008D07685B8B54C6A6550D9CCBD93066A5A651A9B2710D25B382E72CC57096900E16B7B9868A06909F441104860BF03134316382F64D4CDDB596C57866E0776C04F8C0F67F2286B7242477059EBE022BDA200B6271AF875A829FC368E1574F4F3C56BB39D7FF61131F014FC59870FE45466D968C109339F0CCC67F6A7092372CB977C75998EBECB68A46059D7146A2EEAADDB258FCDD404D6E95E5400C8432535EFD635AEE5235D3B8ABA4153B46C7D234AA94DDB66B229456C41B2FBF93F39AA048C158E50C312FD623DC1E818A494980A34C41568942C30373E430DD5250D0CC27D4AAB2AAFB13CD719ABC7F466B702A983318B8D0C3040DC56B0960291F30EA75986917A17BFB76BC4B4AA8EA396F127A41F73219DD06F27126A5F06519E328B5CEA9D67AC122B092FC3613D99F403DB86CCDD760BF8398C1AD6BE4B5474C34864F2B10D97E265FEDB464E01CB3A426A3BD8B3457267317B7649D62D4847C3AADB7036391CE068758BF1847B96C5F3A69BD36A9468F9CAB27476456B4EB510BB063C46D529758C6680B4588CE4F5CD9D225BF700B27F53C13D49808D561F0413315C01989B1582755CC4CC765391AA68A0617F39B843526081658532C2C0025CF378B31411E867C978109454818916F8052336CFC9788F87E53236DAB54112B876042FE9054D9C07B80F7B43AA900BD2580F386058CFF5624A9A062474990C2C126E22BFB300C452306B859201B3C67B7356CC7DCC36CAD7A7BFC44DA0591D8CC45BC7765E405A2F2373996A72433F332CF77A5C9F3146DE121447264A84339A652960109044B1FC707680AF70E457B41259A1B84C37892C1079B8F08204F218CE85796701B05BEE5961F55584FDD3BBAFF25F53F78D0B48266EFC4991E090EEB28799C002CFE902D1222EDB8A026813295E604921269D0E0A1F4CC70F4E528A092B4E15300EB67808ED20995EF3A80CB999553456DEFA4769791FE24C934DDB490AF61FE1FC0027FB10AD260A7C33BCFBF212D3B50568844FB022B7DAC9509B308A0040C9B5482D89EB41A655B7C193C01BF96E5CF8A08B4C1C344336FF53CE9F79009FAA3A3921807D9B4C25739C38568584367F5D882E4AFD33697EB22AD03D369E37C0FE3B981047BED55E0BC0999976E4A36C"""), + xeh("E0AAD46FDDE0B8E64361C3233263D8A751F5583DBE91AAA6E69E6318FC7A8EE0") + ), + new EncapsulateTestCase( + xeh(""" +B7F522438A05310B12921A8ABE79B4887CB548317B23A21A4213A0F940BC3268464343C89540B83155C980698C657251CE30C75073C3D3C73AD9902ED10C32CB101B0537827F338A94D9615154370165B9D22707693C5E0657BF890A1C5E820899087683D176986162156ABA109CADB1729A0B0A057C8007E4A6AE7E272C860190ED4CBC126082C1992B9F541FF68A419226A666F6A9439CC82B3424C3515ED1821DA501449B84B1D6C169B9F336AFC9109F4B0AA6A069D5C46095B40EC7C886C1B2BA060CC8C0A1B2FBB53FC102701FF33BE42C92FC8287EB311CBE4BB5D523420850B9D962158D14188C4A794E4C0A8A065757EA0C9A65429F114A983B4D55743FBEE267ACA76C14B1492E2CA839AA5B4762868FF2123A30B76D858B0EE4CEB0B9ABD3A2711BA5167B73226C3B96C184A1681A562F07365D686E17F10EB75545F4E0C52CA6BF41627B8D6A19787A3676159EF334A3F4C538E50484F97CBAA334C5B800A34C642D097549D8AAA6E6E16261E038CDDB816CE46BA2B8B821445209E5AB1CF71B008965FBF3A2673B5074943D2102092DF603F2989F32085B96CCB2BA245A7AAAC06C763640D11730E828A0BA3129A43F6F0825A682886D8CCD9E84B93999474B63CC8D272911D72729E79E2A494AF5EA20C1CA8434323164709090382644B11F0F6C806A5044098BB936F5CECB28A81AB516A1857B651B93CBABB6E3D76B7F79AAF6B503762A10ED8499347771F221C2A96A90049C73E6E1132AF53A88D38EA817CEFA29848FCC0AAD125CA1C829F03896CBA635DAA33ACE7C7EBD18CD7AE03A0F9A3659090F5F9976D600B451BB6C1F3281D6C2884522618AE20CD583AB9B32344B6A2C294B0684E6BAB686A39431292F70748AD02AACB57CC3153CA6862D2B15108EE71FD51C2B7F81ABCA9367D4619964EC7C63EC653FD1374EE3A9BF22C4819264C2A750DEC193D5CC836430B18C535D3E573F4574104D471D972361A6955E2E10AF34D95B4A123218667685B1AC6D696053966F3C56297B844657C85402A357649A82E4579B667A36734B665583AB026699D2F6B8F4F1BB25186858543B61260BD3CCBBA264A30135088C0422ADB4508A60485AAB3C63ECC9AF981A1C5913950CB8949B5179E48C7240CD6C858E1144C7EE92A885008209A055C1C3795FA3C49A98082CA077CE4A75B0021108454D3B0C9F01C00CB29166281A24BCA77ABB471A036C9DB1B8946B930BBE8615CBE4AEF6608DEC389BC75C443753C56F5A62FB6C532BD13D89506C4C5985307A53B2403B42265B35B1CFFD6B2CB443A359D75587B2947C7076EB2A2B5BFCA8B1CBA865674C1A2C1A5EB4917BFB9707590434ACADADC92CC7739933323924B17FB516974714A42E38BFB7F20E752AC6464503170C860FD91ABFAA4C6B70CCBB8A2FE3EA91C94B26D5C64CDEE57F936C1AC10704D473AE10479D798BCD6026BACF4C599DC104D70439B0E2A32C91A5D58010ABA9984A34689E360C7B296486A4C681405EC3FB92B44210D5D3CF52534095859E42BC9BCA7B3864D43CB9F46E685C0BEE8853FBD31285DC2EDF129635C70437B612955B7E56A128DEA321298662F4F96A8E1ABE81B54DA4292AFD5FE45E31E16B17919D9EBF8E87B38D48053AA9F6F41C5B55AB86C4E0BEE558"""), + xeh("90347D478D5D964D66A54BE930FD9F7FD3C2AE1492DAC35A6CBDD02616BCE14A") + ), + new EncapsulateTestCase( + xeh(""" +AF98338A682D431CA0E17775EB170E3742ABEA300D6A46C567C364DE8939831695C59BB7686729C9001E25A85FE926CC6E584E2BC86D3B25BC9D6ABB97EB7F15AC23656B3185CBAFE0C39FA0789DF0678FBF5A43E6E0C53EC38076572D9D84B1ABE742E2F6C0C8CB08CDCACD23B71D57D06708F32D50870D9D636DF1DC01A8378A211A134BB255DDDC0B62C75812AB1677C50DF56B1FF62024FD722D3E732F56A2C6EA10CC31F280ABC8347788CB291AC5A1820525B9A33A7089DD689962A046B652AD182639278279EB884163E2B115A29A3899CB0EDB4514A0836BFB8A51D834C1939B8DC108B6138FB88B9199DCA5F7F64AFF36B9296613F891265778C7963C3E702B81C54834469AC8B59920BEE7878F01052B77B0F54B6DC61AA3DE695D20786F7D309C3B16A8D2C90A921CC317E91C015AC80DB106D4810EBBF2C5A1530506AB1E28B7A32BF67A6981185F98B44CABCF6706B134B5537DC697D16AC003808119B0BF94C84BF569422C8BCFF834237B902D83BC4C16F5CDFBBA5CDAF0A69FC87DDC885DD3AAA852342C1EB8179756087C678EAE2878A777655FC19719593FF600789ACC6322018791874D33D9284EA512AF1231D4CC87F1BA6F6293A653036E590A892F101CC518110C984AC55C2931C976828283F0266609A45A8C7CBF8C23CA0279B133A38F9DC797D5E58011096D45441F11DC59AB5B66846A87059314FDC64E8CF50040B57432A18F46078AF5A6132B006856604CE009128FC5445BCB6891E91A8677060F39A2CAAA183FB8A0F6751051AB85474A539A4183A4486471418FDBEBCF40055AC46075C3B2190248A8202431DB828B82E1320DBA47A23A94DE5CC378B48FF4B633E2D666B561827F8013429956D3F5947FBB848B3A511452870D00BE30610D0ACC418F8536686ABF66851707D89FCBF65959BA3062F6A16E268488D04BE4E370C4247947FA823B27133ADA76DB58CF3ED1109CE433CA0042CDB809AA1B5D5E9C4258C6067B0004A905786473A0CA4B3E9D90443891A148407A8D89121379A1F37C70770586365A74FFE5C6FF170791681E5CE10BB88BC0BCCA82CFC81424AA5BDA072D1BB5BC62F6687A05A949C2B04005284FBA8ED0646A394658A5868304C42C05605E9292801630129C76A1FC083DC3696DC4E904BB1916BA2287DC37232AE2C962108F245C3A0B702F53271F6BB00363D88690A7BF37B345ACEB5426F34BCD7670ACF15955401A20F938A4407E00D8008C147DA00C080A226F71F15DD8DA20D0C6AFEE431B6B2733513BC877F5545753305E8C03FAEA935C183BFC1C40561B59FE80956CE2C5BD3C28F2248249E2A0527891B3B64BF0EB89938A42008C32D668054E508871012FE8653473FB70CAFA0A8F1A509948A2A967CECFC7B5DAE34E166086433C5977208C45D97B24238E875A790C2779974B4721F573C03C4D20777F1C4589227765E8E7AFD0D59EDDDC722CC6230356B477C490234CAF858893F0E446727CC88E1411242344DAC6AE6C2CC1D2B1AF2B8C32BCFB253013411F18693ACAB9A7A86CA5590964D39A8A50768718BD948566A2822206226020165965F7B68871AAFD3474FA306A2DC31A98C60FD2E5AAA8A0B72BDD2F70D6D5DEDE7D679758D8A325B6CF11E7922902ACD92A3A8CB43863CE98"""), + xeh("119BC36B5F856C0A2F136B3EE42041B817125A600E829FF6B4B402131A26ABF1") + ), + new EncapsulateTestCase( + xeh(""" +463B553102898CA297E0C205F3C9582273ACFBDB13BEC53341BBB6724C774C741ABB16B2F992C878114FAF67C248603D8AD5842E7230E59B7537119B204AA8B2E0830CA3511886AC5280242A9A817D9A8C7EC8B95DE23254174D1F507129BAA49CAC9C6800CD1039BA2F6625584B8F3AB27657E6B7BA2A58080591D572C7E0B5ABCBA3BABF0525736ACA427A1F13245426C08DCAC5752891169B1A8373B4BEA8A49DAC3B8163E78E74195E8AB54007534133C02AD1930DD3CB066E7114DBF4CC9545C3616B1895469A1E08A57273B235874AEEB32EA3433DBE8732B871B4D0E3192ADC30AC002E4B82798E0C9AF004973F5749456605B897C5AA9938C38343B3690160615B3406AFC6FA20D04AA0214B9C224AC7E64A6E85F38AAC01632A501A6CA1A4D3E0ABAE384AA2A50911E8BFE945792C9283F9A898A1CB2E2934550E3CC52E9BB4C2EC125F64C28B0B12E0805A031824F423B7CFD9A11086523F1305E4C130C17161AFF366472875645BC8A1B14DBB104494C746F84B4599C07FF4E74A3A1408CC983CC2C6CC34BA04333659C1F960E06B73257C5EAD5B3406D70C3DCA05B9EB1E0EAA89EFF046B58471FB7268BDB6402174BF03F92D4D22C7F204A35AC6551455603D8382CA3AC726C1BA3ECB5D4244BC62F10989B4B9851C4346DBCDB959516CC260CE2599EB1232CFD65FDF39AE7EB0763AE47A359367A7720D02B07A5A634DBDF74F4AD589EE2691BB4862D06B6836F70BA8C582F3A7996BD7BECB998CB1AB1564C812AD04920B9121139817E8F06172B217481C379E2C368C0A12194195A03177A822C76B0C7C79AB700FD5C24EFB24BF29139F4930E6515E7A1880D971644ACA12E4278AD22CB96370AE09614D96CC0328265F27E2B2D60465C8A370736632257B191B72185DA1A2E6FAA6759580C6E51E6290B76944C2A8743610424DCAB89CC9B79AFEC512DF9CC5B4807B0C93A889F872D1D8950CB4B371335718035709F36710647157141E6F596FF677B132352D3C35389903375999B2A0D460CF16A581C3CE5A057DF42051A7BA167D6647BD683290ABBEB3E67277C055C5E70674555B98D365442BB8D2859FE47C1309178537E78DA79B7016890C94864328CACF327746D0E32D65D9C7C0574FA5BA9E1FBBA72D990C62E1AD74759BAD3B7F9759B334B10EC8A1AC3D8453783A621C898C99945195928445D21B6F40215724919C3959D77731C2ECB171489AF6F545C7055D55778CADD250DF49913A7769D14774D87940D9C0C53969BB2AA151E063CF78CC541EF643AD7C916B961983983F886C7D7B6A016391C6B9C64E95A03FD1F65B6C924B2353678D3079676C25E236745955CE5A9500BDE96A1287B6A795B3382B438E64C588878CE447530D174B53641416E328E428BBC347AAD32342C0F17D1EA15FBE147E3D0009C1CA0C0E5A437F1708A602026F0252BBEA8B7C70445A456678E0777994C021F61A8C689DCDA40BB196512C8C53FC3B0EC26B3E2474419AD79EBFA58087AC8987BC15C802028ADBCFB37722B0999F6EF71629AC2966FAB95A5A2D3F74300FE668F9D912F8815561C53E1BD24455E58FF3F7BFBC2207D7966B1414CD0D695C5BABA93618A89F32CF29B33FE97EE961F5DF14FDCCD0E81878F6C76D5651730F6456DB0938BF"""), + xeh("697CC7445AE2C9ECCA2569B7871F0BBB364E63E4B782F734FAFED4FE33E4AF14") + ), + new EncapsulateTestCase( + xeh(""" +0387B2D669850AD9379CA70B3EF1BBFD487214F08616824787C4506C83740BE76CBE452CF99369CA80674D3B22D3E04FF95093BD00369BDC5C8126133C5A15B8A99A912132B19C275489B7914858E806CF4CB10D3FF33E018CA8776A88FA30C8782179D289132E0CA4A1BB19463571BE1977109C2BBE4C9433D6986AF12E7079C4B5783390C95C8468545F48A5D669CC0567CDBAC54420DAB1DA63456C692678105E08A822D0F99584D7A8BC76CD9038C2768663FA11A8D8E7B86BA52DD21B323EC22AC2E7B921216282233039546803D509FFB12BA2FB7D3FD38F4B06B848233BC90C2ED68AC41FF24C6425C6C9321A7B697BA5588B434B1B5A49CBB9FC479BE68257498A05865A7A0217B8319E7BB8B55C15967319CC510147BE9BA5511A967CAA2102C6A41298C0F7620E626693E976318E6A7635536B2CAC9DDDFA58E2382401AC778D145774494D2F476F43E0C3AEE004D360C4A65571BA02C7DA13002661B4838B22B9378F34579F46653A30A88BB501B325956B0B5A261174360F128850908B5A3CCDB5B611CAA26773368B13330C48C6667BB351A2AAACEC4B2A2C70601513CC3A18B5B1DC421C5A056D1645FE9312507AA1D52929AC289F6D75269BA42061D556243B34C638A72DEAB939B496435951C53B22095906C68B1299A288D5F5CCB8762E76477C5A0611EB468ADA9073C79B09E80621CA9C4D69A7146A812133B9637F074586A5BFF4AAB6CD0140B43A1B6E2ABEE7AC50489B9E5270A93541CE03B72C00A26E274A7CD3793334CC04E9285FDA673E0241BB9C9A34AB7935508739E52A29F22CBB9664251C6068FD3842C80B17A0C1772F285525B22C65AC1DCD520217DB5715381C9A663DB0E512B9F9711537BEF235313DC46B758839321341E95348A75972A7FB1DBFB183910A442E985628843B93505534C63C8D8A5358B61D7353C2D174AA1416677172ABC66725E7317ECC83BFF257819790C9F9C506DBFC647DB27BD9747673F666D1239845744BE742BB27067BEC53437D48A528F3221D60C3E1EB00D87045D050BEBCC2B433F2BB2962B0E2E70FF0CC52A5BA7412E39194AA226872184108C4FBC459090C59E4A27FA4823ED8B3CD3C59C2CC6A81D3017A08234206C3854EB3B75BA441AB8C321C55CC8574A04DF42E201180846982333A92D057C61140874A9A80A46037DC2A3CECD534E9EC39943BB300B1772510B7E8186C2D5B6555584F54E39A2AB6473806B9C9E71ACDC8C15E43A885A4C9B42763766C49DDDB890C8C7B22159DC91865D0E79AB10372A9F45963C59D8C1857CB654B2BDAC0AF0A24A663C71B744DAD1AB68A90462BD79F6BA55376125562A5B1326AABA7C19E593B7D0CC1C8711B8CFE3547A00ACCE1646E766BC03767CF5BFBAD8F08590E2165C7706544DB5A942925070A878D13418D31CED35092F19C197DC2A517967E41898796A51AF8911A1857244C085045677865B125573CA5E24231251243682C6DCEE524088572D2015D9A25691F2532E75907C107323731591BB061D525757540338BE19913323D08A4082239363CE4741C92AA29F8CAF146AF1D277A76BB22CD54663914647532AEFDA02406099A75A63F7F2CA5BEFC74A6724896CAB84D12376744CCB1C6ECB1DCABFD20AAEB88BDBD04AA5A7E2C867B"""), + xeh("52CEBDECF06579F4A9351F77CA95B5CEDD034D812F3FB7FB50320CA80E4118D5") + ), + new EncapsulateTestCase( + xeh(""" +82DCBC98650A04861DDF15380C8644C6B93F197A5B10702CB944439BF7AAFF090C49E8CA58DC507E5643C17A4D2912BACFB76454D45FD6EACD191910B472463C49B76684777BFA71BC18973677256F649FA6041A6158046F75268E7CB72E8A974EB2CC7DF1B8AB45B0C651BF3D99211C071D55B9443E6A4A65B976962300E5F7325A228A61727D8733C0B3012CC51C2332FC5BEDB05962B771A232B55B4BCB41AC4D85FC6BE5380ECD3259CDE1B809D8B6E67978213798A828540ADB86124B6F137CBEDC4B64E7CCACF78031211A300A79C59508A60A73ABF93580AA64A7E661C282F5C00AD8784B002F5AC79EC4AC85E0290FA861B9D8B30D9E56CB934C6F4CD5C033C7AF7FB55F20C5A11574B3A460C7A3D73376E6CA77AB911CA118C963B97AB675ACAAC6BB73B0080BB5E0261F79E40C0FCA9129A9C118EA705B0BC7A2B45FF06CC15214A807D3521026BFF008024E951AA0752BFEC022CCF92A519B8D1CA910809B63CFA57C341490BC673243B7CC3E2A6AEA2BAD2B885E39738E3973011A67B266C438F2C2C1F63B251558947C00741939278055ACB8569F91110D895B97DC07BACF1389EED1271051CBF6A7B633A47848FB57BEF485993C5462E3B5548B96CD161D58510794CA60951A2A046C8743807619861D37A420DBE94633877134A92180C05B14E10615783C7B32B135428E59311BAAA32FE37A7C35C4390D1185F2931BAD539F08A02198D6450DC55BFEF625E3E209EEF2A7F38074DC681126CBBEE6AA3C974BA8D7ACCBA719292CFA33E4D5094F527BE94AA2231A762CC0970C7C81793471295B9B2A58810952A63B6589B29953C942CE49C87FB7B49B400210FF645C88179FD76BA408DA81C7464E76FCC3329589AA99855564329D8914E34A7B0D02685A92817C28B2B3F8A7A7615BBD569F2DAC20E161077EF46C6FB926ACF3C94DCC9A4B0A27641370B4027AB082896E188BC5CA32BDE911C5D865C87A22207AC35B72B0B8FB342E3A53BF735796F3C8930417CA84CEBDA48FC1E34AF9610F88C18523A4037E3540757162875CB5F82B1718B32EE70A39E5B216220AB3148CB1CCD118CE213F2D5680EBF865AB018631C88FDB6C763C082F59C6CD95156595E22FB0DAACB56341B7645027845813A59DF203104D9C8B1F647BD3537937F59030979463BB63F7C9B69E57CA17491F3618CDD162A9FE1C3F9B326F567C26D1AC6050685FC68A93CF59178BB87EC8D8B703519E60A22702BB5FBCF3BCD6D496B79B65415C175C554298572AAE35437BF899ADAA5C4F513E9F220553093BEBF1769743C6AB0B9FB64703C6305CC64B84CD76B7C8E61429781A822990B698852A3B583AF48C3B22092C513A223110589941D530C8B4CA25CB4361F2001B166C85CF910F006C5B0B71A109AC5986F8264BA26563E69D122644B6348818145CC026B783D917E74C4F46E0C9BF86250F521C21B64D50E910D1F1CAEF4B05F5A50491E9CAC2F3B5CE36407D9937D0E28E47B52AC460103F272642093CC9EB18BAD44AD36B8EEC367F155159ADBA0251F195E52032F1B0514BE83F8DEBCBBFDB5755267E76B028BD07CB8327CD431A7B73D289247210EC905A0529234B2C62C7A66338C1D381C88466B4832204B1B05CD1BF8E0A4693D941A178F62E9E09B74CAD5B"""), + xeh("161889F2E92B1BB28A257B45D179FB76847B664E6D7B5FD9698204A426EE96EC") + ), + new EncapsulateTestCase( + xeh(""" +FC964FC0820E5DE7A73BC507469B013F2C81A225C8C067C4A9351467847DC4D38FF3237A9A38A8F7C273B08B260C5A9B20F8493A668459E0BCAC480E0BB50BC62941720283F758B7AB13B444E8A1F8366FB247C3CC339D413671ACDA6354220B9CA0515881A688063FA87487356C842324B35B064B5847A75509AFF086086CAB80DE6C7218D95877313B0663031E867610107F1491A9F069A2DAA4A88F26CD6CB97B43B51FB7156A47550434421024CC360500AA7595BBBA99116057A64A98C76D61082ABC47BBC2614D2B23EEF8A68D1065ABBCC057B2717DBA5D6B82BEC6683551F082C85C3C430580D7125D1EBB1EA410748D6835C5BA080D1140F9574A4460752C5278E5F24DA829235DEACBFC3663FF71421F3B4C3F073764D11C39C9AB6B6B2F1F24A7CC84AA73A976721AA7BBEC515D0A0613D06F80FA461A032A274911B82CCB9B9A4AC86C3555D37A267C54137B141A043E9C861C58D6A88F5A47B895ADDCA736D11CB227D190481B4FDF680943539437B04BA202B21B19C06BC8037B93681E2121E7A49DB8271422834CA4253F5B96AB7E723FDC599B8BF0567C176BC7C754B6402642921ADB8C30CB8329A1E3CCFFC8A501A077E34495D9333B897C41F9E2A11151902A9B19AEE16BD4038DCFA6118192CC3B09523BD89C0DD158B87276A6316DA118785551B9E1078C22949D6D5302EE5945F87C5A8EBB6220B673B8B7AE6499C993633E844BA8A14CCBDFA931D1145BBC260EC933CA2B8B861F505A9691CEB2B5716CDB1E07DC6ECA0693CE0B8BBEACB59F705814F2C46B336C65240BA7791B10226D3892AC60D11F67F29283ECBCB459CADF6867F41847A99A2E0469A417078AD80B1BB35549FEA2164B8B557B5610C64C810E211DB697ADC43034DE45BF407729B9F8CCBE3379D471367DE881E6EC741A4130C78A90FF24C7C3899129038851069BC68B9EB533354AAB155F829F6AEC9EC9D82B20B4927EECC243F014EC846D59D5C8F3517F96873511967408128A1705B834F81C4F1169EA500A66EB21682A09CE44CE4C9541FD506A6AF12CA3634733E4661681871717A560685794685DA121565671B50FE866B0A565B0A9728A97C6AEC4442C498C54D77184C44D919083921204334CB058FC5EA4765C0478104770B743A5093E842C013769F16B02A46083872C58D3D678DCE87A3799381DF117D0F357998C853606692ECC1F087C0883CA575D9159BE882045E60DDBA38ED3BC8660121FB8EB2D6049A5843A2D2A53BD529881799487B30438B4A585B2E77768E87D060C0D676283431A55BA9C129F036751835299D78CD2D85748C246F8915927B1C9A1194BAC1A103B5A1BB69370C685B15AA264C436683ABA9F4A03C49DACC5A1D3CD5C133599EB16006850BAC4108239144CE682B7301EB220A363032FB608137786898375366B002719580EC7F7733BB2C3DE27974FEB56C72AA61252A2D63CB63D380F1FE3142439AD1151B543591AB0915B514B3E97EBA17CCAA73FF0A3459393BAE20B1D8A8961C0615B180DECE602335A11F7617EBCE0A3A0B3AD1A78A3C8C682976388851285D83BA9E358AF22A14039CA015FE1B42F8A3EB454578504153817455045166F24D6DF0071E884AF76ECBBFA430FC31D1F77405F4B404B538725F561884EDA"""), + xeh("3349557DA70FF69886ED032A91D8FC23BE9E5245406670679A6E92AED870D369") + ), + new EncapsulateTestCase( + xeh(""" +ECEC377523150E39B8E5A4B85F8237A685630EA7A3443A9249D4B90E1BA3438CB095AB5555706EACB3A61D5143029856C7E80B0D9156BDE63AB4632605F6009450B1CFB6B81A58A43687C4DB56BF087A75DF047237E9A9B79408A8369CA3AA1731A7190FF3C11A7699E3F83A1F655B3E2C252D732BEED0703A642BA3500859AC70C51C3DE886C26BAA47EB221074F97FB74957F9C61A02405D2E2B95FE198C2AA24AB3D649A3B6803C3636C03B3E199AC07D103960577738CC833CD42CFF97C55FB4BC577B70D1A8642ABB77A1530ED0F1405B2245347256C0D47005A634C9237420574130F607BE82CD00D81E15562AB8461F681159737ABDA7441F7871AE7B28401A6BAB14412A5BE5A4BDA22A46425B8B51964A673278B873C4F61DD8CC5A7DD3B89E11652C677E052643A32139AB971B5B0061D600440495B96AA3113725640F6A91DA0B4B651630EED446BE53C6C6365BDD2BA0F757CEFE05C1231B666404199937736E6A5FB3466BC4590767C2BFB2041DCF254886466288BB45F8E91BBA876B9C093BE2616BB3D2B516526495E74BD19B1E9C36543697ACDA981687111FD05A1B9F2255E8809152138B983790EFE836DD7A68A8A150513699969015BD65B05D364FBC851E11B506C607BE0CD116910C94A3E3258AD263683462F5826B85B4BB1DD2917B4034AD25210AC26F2355B05681015C9A2BF622BD28431CF2868ED213124F124C7C6797C34952870CCEA4970AF909BE10A57BC7AC37A536B7DE2A8B0C4459A6223B4EB781C2462ED3AA135015754BE56F2B501AFE68022C81C16D40726B8C77B0845209FC4B77B64FF08609C0567390F4C9A8187A15C719FC5C9C01433CA77809D3F9195D8BAA94B24CFD909D6374B8DCD2355D1723400AB552F264C938B4E1E8033BE2A0B6FBA03729B38FA39F285AC01A136C07D10DEF390BEA5688C41B155D81174662AE48766D1791C60F1606BDF9177D995D9167B755908A68E7A7CEE4AF53A42EDB486C8D119FED00BFA643ABEB12666E2CC2295B8336122E7D9601F4DA405B7666EA276A172026264C23863665E2C21FF72A6CE4186016D88F167A358889AC1F8B028CB4622CF07474181BBA6BC5D331088B88A1C185B28B90CBDDD54D88D4A911DB638EF236D6D06EE968B8E5FC11F2D9AEF14A3248EC921FF0ACA4BB1369F7B5B3991ED6B16C3A918FD9397BA4E454FD209567D97C8BFB47558B6AC7726D6C83768E0A64B034C0EB36C8BFB0BB86C52B51FB7DE503C390B97B00A4534206B267C42333B4C05BC90C7FD25609548B2E7087E792BA21E360038A6218872F94035E5F13149CB440B302A591817EB0E229AFF03CE9005535978F930622DD422722C059E0BB855143053F348B23D5ABBD49B7DE9478EBB63380E75F9054922AB65F4E897D02F9AF641CC6A34957B91A7969A1270E4264451053267137ECAB8C8C8B9B76354A63E1ADFDCA087E54A67F8A2DE4AC6A636348017C6203B4A27322167C2ACC85F63335E8AE4D1909DD1C3DD228C0E3B84470446EDDE572F7924DD409764FD98F43A20E5AC15AE9202BC1AB58BADB3D06B6B77E81ADF763836398BBC45433015B6523652751B8292AC51230440C112C6317A66F24C4BF927C7EB8C186C9DA10E1BC25A4DF1CCA9B6C3407955972448DEBDB284B"""), + xeh("6F1694589DFFCE022DC4DF1852FA49A41C6E8AB9F7887E70DDAEF4232B045DFE") + ), + new EncapsulateTestCase( + xeh(""" +48E11D1B0572F2892B8F81A8BE330B16C7353B5C319A34874F959409E6A41A71585BF36AEB651869AA87D400C6AF32B7F8270BB9D5C53BC3B600F493904AB000149FAFA1B090B544EA0101EE940EFE878DD64739CBD78D317A09A45775B2AB9E0383C75D049083BA64019658B4F44573C1B7C0B3A59495606D9162438B1A0A000C3AA5834AD5BBD11893598052E5B543E209215E41B8D49C4107F5658F7685CE53459F21452AC66F0D2398B6971A5A23A056444947220E95454A404C7213686E58A42E346CC0C44759504B2FA07198D742B1BE01A66C2BC64498CBCF6482DAC99DE7DA703EC1441D08C4A701BF84FC956B11411AD610146C59DA6454A8B3B742D91DE3C09A5317A9DADC23ED0A922AF339C090060B869B55FB3AA1C603C40868337687EBB27E37B804EA834D4D0084B21307DB0A64F69B7B49B5B0D237AC428ABDFACC01D1012A04008CFDD336A06B9728A036B6C60430A8CE887C4B006AA7E7C54834E2934F8400D030AA63E61FEE96C22FD49685A7C3DC2287EC2964CAC78B40340200C3AA6C8A67BDD30FB7605F0205CC0CA043A4574235B342FCE51195873F7FD99077CB31229B91D5923B67D391B457198125B7F198BC7CE58FD6B96BC35CC3D0281957B4110A011262B1C4CC0445722CB5E8C102408593CE6445C4584E373AC890187986A49414643CCB2861742466939C347CF021D1C19D36398A82C64D1FBA4C44B56CF384C04A1944449258700A66B1E2C9185A5E8B17772538B33B038B877353DC251952DBB899F04A6C677247D4CF4E4A5D2B22313A33A6D49237E7C04C61B2B0026531583C6CF6332C4C7853B7A8C6A4A5783D1B79FC5725F9C7157600747C0203E313CE91976CE44CC4E0D67DFA830448999357F076F2D41EE6FBA68C53C9AE5C025DF867E3060F3CF164218142D6C2B5B526BCE6789DBCBC5765846565575AB154C545FC3A81AB8FA1353B703B72B011A0405588FC0B8C20D13ACE9A93F6B28EA1C05CC686CB0AE722662A9ED902AE87D48B8A9667CBC0BD75742CEF313F1649C42C760796C979369736CFF05516A72BA36849D2E213AA497A6E7774EB9A896AF0A13387ADE8F594DEB482D9FB9E4C740360B5089CD101E5450C837C8214247243417C05ACB9D319809D33168E707BD1168709F7829B584053B554D95557DC032683D885AB406E205B6F495C23EB673E05651ED9DCB87C4967987B7B78EB349F4AABD35C7242079FB30607ED82A0503173A1B785CC36A2181892114003E2D33D17AA3B0A5CA47974B8F1C93B35107DA3900A87792433F154C643B34519941CC60710F07A71E4AE09A7539E72B9235A07D5DB53C048493B4AC8B9F0A3696892A0164DCE38B7F8E711506A9220A5C6C61AC2EF3942D3984907E59DC703ADBD93B6B509A156CC34B226188778BD191402DC94124CC7981151934F68733D131540056466437CE2B31C1320362AE5247C35CDA6E13E5D9BB89D0C8DCFB16BE8BC355A0C0C54E7ABAC12621ADB1EAF82B3D1E915315A3B7F3C98F6CC117BC3C850258059737171478E3AAA7FE5D7B5CD218CB428153C07AF80667C096C96656C85B8B0BD1F606A7CEA963717A18AE642E9E8A853D938C66651EE31034CAEC7DA6097A3C35BA420022324EC00CF53B53E9EBADC6FEB57C9B5BF5F53DA"""), + xeh("D8EF97421196B1A91448B2BA7E2B4D4B035B91DD85AE4E57E8FE3F0B0D524AE7") + ), + new EncapsulateTestCase( + xeh(""" +AE742E0C4761E7731F98A96F57374EB4E321E1D33E3133C031355AFA974E82F50E7EB36084471D94490150188B34A113E300B2CB65BB44E6940124BFE3E21FBB4B01A7640817567949286922A22A8EF654D8465CA39722AE9A4D0054906F52C79428716971ABA0703C2A3C497DF73D0D0C8AF3BC36D12C80AC2701D8C4689E05645B2017B7EC830F8CC3C3419B1B14AA890B2A8B274C5316185B26473456A196D8C836352B437A4EB0E924E9D5776B528DE1BB433B7C703F302EDE284C9B22A6A502A7FD6B17AB5546B52C86DE883C80F74A9A7302E7270B73C521FCC51EB7E02BCC68CB257A1FD6EA63C195610AB8A8AEF2486E18AA081056B5F474FEBCBAA48560325C06DDBCB79EFA10589A62D9D54268062CC8E3693373066E57C876558FF3180C632269E77A96F305175F3A2F9833BDA9C43BAF62500C202D0DBA91B28CC6473703960785C8711604C9CC04A98BD19904189A6D62A159E6A83F25907EDCF457A080C70627C6F5B0612AE84D4317261BE728B786A111B74478044B7CF192DC6490475C9AE1E5C0FF97B812E0094A63AD818C5BE5304AE8981B52867912787114A14088261CF0747732548EE105927DB086088B89DA4773F3C4CCA0E44431D98A8EAB89C1D6C1D26109EA32CE99473E509B9D478614D26B06387B89D64C6785A50DB4C78FEB65786550647EA30C9029884DD34FC9227596B091E91766F8389A82B01623D7721F2069911128C309602F047F44825EF6A12BEDC72880AA3BB91504904276E3E9583228A7896570676B8DA28723EE17553A156AD5884AF0E1066E518D19951F98079F2244009369157E1915B4FC99254C4691D4A64A0AB0129BB235B00552C5B606220E45683341086F2DB3ACC16C8DB563259C6C8E6A360B9CBA54D048335E455FB406415D147122903325B341727C76ECD2C16D33188055534196C071F6B6806B9E057B5597158E036C3CA90174A83B965F8C3CA7562A3A24AE99298A10791D38FA3E5F30B5CE3A8438E6708A156FD51C055EFB5C65759D76B1BEBC231896095F213148AF839B4DEAA03C9628D0C943B0F14770A9A223FA3CF05C7EA983BB64501885A919678001E9219AEBFA71E5D3CB5BE585E7B939194C87C1EBA5BD56A953645D28C21F0E45686C9AC96F820A3AC26F69F705EC920392601E55FC1ED2B9BDC3C6BA00179F9DC687C2C01C29EC05D8BC5A3145C1F936CB8B20CB2015233E01184AE68BB0F96728C27521118466A5CE602CC4419881DEA62381D7870C14209B6A874FBB498472B3420A3A2A4203938863C7610DF73325B5C12EA5D2CEC78610F7237C4453536D7180EE7425C9DA6C43604DC6A074E2B203A0FC6B44679879AC2D94427746041809D84820379D14168BB0E816FD241598195CA1C447C2EA5D5B455A28E66527088E24163C6DE46D36DC1753CAB7451A6ACF09ABBAA1223E7A3B07E801F84071A7A3ADE760C7A2A12F4D12734530538D2179EA204ADD3A40222467649B4245942E80B50EFAF60B83E4591951101D025B05CC1EEFEA996BF1C015A6CDC9325EACBC349592B881CB3C3DA8C096127953F0B9697561DCDA6BA3D566FF3C14BF718ADFA47877A12E390A6CD0544D9524AFA37069C8ABA24F918FDD15986F9B1C6471A5C7A495588F79B71FCDBD7376406E5DC064"""), + xeh("132E7CDAB9CD5199FF0937C266D50BC50BE764AD027DE45C858E3C2F79B7F07A") + ), + new EncapsulateTestCase( + xeh(""" +11A62A8896CFDF943396BB8F58D9CE2C8A4DD07ABB736CA309614224E13CBC2A4EECE6A9E134B65625BF7332A0B978921F4B9B689736C7A90CD77120FB33124BC272EE9B656952980077BA0A2108AA34355C391118E2ADB2A1A6A61498DA2B3E7A6B3477890A6EB74CA66161979B1C44D10ECA94CC26C93B43E42FC68A93B85AAF0F9381DF309291E2160CA19615031576D1448AE4A36DB5A7EFA99542DA5F633C4A75470F9369AFF4D20FD2D96B62348745A46C81053A17FCA3FB927871E88E996C3555B696CDCB7639E13E1148397F4845364A7CCD245DB28577C678B061555A8F97C7DC4C861201C69106CA2F375E94B597BBB09067F4C730606D2AF3B6FDB98C14CA1A339B3D23174AB19C0849836C33720C9A04821F59B929D72421D7583E9919531327B296BD2325B5CB172FB7E620647091A99A053E20907588950E303237FA68F57B1A305233B6E931F22AB46769C4690420A94C3C234B564DEB3052C4ADB3B08A1F455E2B1B8132E6232E42CE33904146AB6FFB693158AC411DB0C49CA3990498BBBEC8BB06812A31E67761FC26AA861E328906D5B873CD2A8C92778260BC84B50703EAC6BB10432BC0115AF9FB60C8F02D90D6A2CFF80A69FC0E23A3068868A7A522CF96876FD1170BC8552E45EB65656740CF2AB106A553CC61112B659E6862346F64359FC6B58FAA70386B955DE918C5B641F9EAA2BE559A5BEBC40E113BB6B63058A80C1FE1664A81873BE506F8A795D9A8B4318342FEAA2A28C7ABAF1C624D5A8DCA352906D037B883AF54295328180EEB06C910A0B7945A14371C885EAC006E24B6A8F95936763B54C89BEB2379DE061AD5D0A65D8398310A5B8844A81F2C8C77E71F974BB0297ABB1C02442385621D607BD3138E063AC36D728ADE7AA6A90BBA32DC2FEC1498F3D68DA3290C17618E35DBC43262B009357CF6F79B04004316E82076961DE4B47F2E5229A9008D4CE902D9F26E5011A4B044AB0FDC668DBB6813479ECA3B0B18E028B1622A9F6B899420899FC7246CA86C00E7C4E1434365067544D02C44C840EF34CDEA6C3063BB64F18B05EE379A18F125514A6A94A95AAD315A55F0ACC567BBD0705B0AF70643F318A7C70EEE059F52C7A67353C89AB55BB091705F3059C93B7EFB305C7716A86F1363E977827C57713622236A365014B87E030BCCB3696F42E6365201CDDB5778951736BD92A4D78BBF3AC4939D3772C0D58F3F895DFD124AEF4B6C454140C002568AC4298062C1C755B99B5113F0AA2DC742077B3B6BAE714742C04789FA3BC12B83A9248092A0452451A7ACA25504EAB21073744EA7826260AB03C84D22066D2199A72FDBC6F818613FC16E45F00B1EDB2F07ACB5E653731F8B701BF0833A258F12B648CCE74A0DA79DD4CC08B2209042F478E897677871538B90BB0C954312574F90A0B189897AC05C5A2E345D91574C6051766DAC73B7B38A3414714C24B175C302CB095F79DCC430438069541D6E9835EAD22789900C2E56ADC602559D595906C8B5AE01A03572183283533C64064290BEEB0A73B9E2137A50C05C1BC635710C3A4525E9C87054CBBE986B49ECC2706C2AC3AC1A474CCA723208CCB6AA1BB7C5851B390DFA3B0E09B6AE60159D231D59DAD26BF5AD617218FD68D6157E4A276122133E14BA4208"""), + xeh("E15BD4603F0EB64E32B3F1D1FA8EF6CC25D673A1D0BB659CEFBA2C153724C1E1") + ), + new EncapsulateTestCase( + xeh(""" +E65223F4AB1C53267449A616AA32393E441F346887329AC4B9D006F61A25BCC3779C740EED0BBDEF0A371B95171C70C60F2387265469A8E7C612353FC51968AA43C04D1685EB27364E26065EDA53D2879D36552E51EA01BD818DD57319DFB127F2A578CD48BB6080C5AFE13ABA7808B5894893BB414A532C5223B91EB1CD2392333190054DFB4722F5B548E570FA19C7C485790AC4913892249E63BB324C620D835E5B8C922924791B08937F139CCBEB2D5C9A72F344888BA37B8CD7B06349A310BB71B06A3EACC1236AB03A5FF9B923FC5FADE54C5A1A2E803424CF9C42E5043305127F3EFC956D97946E6BB02EB913D6D21695A0A88708B6CC5611FEC61932774E462C18F4726FE992A301B74DE2F56E9F791E90992C3C109860474FBD6C5EB81CBFEC4A0C7F154E5C2375A2A379A83B4DA4C6796102B20C553F015AC5AC49785138B2460925BA3B156EA337D31214EB942EAA27062EC07328080927DCCA3CFAC51A243645D5055EE0C644428C4715032DB2757AF2AE25D727C78B08D7B59D8841B9D26139C3717FFED92E09FC5286BC1E1D290366E183FD2B5562859FC9C321B73132635A532DC3541096657225082CB37DDED92C8C480B5CA68F93AB53168B1FF2F08D8265AA8035753C96897DD06793A145EFDBBBC4518E0C87AA90A895E6955E5B62929999143CB16B09E26433A1C0D761051AC3776EB126A8C890940632B4C50DA7FC181439A11B483554E208D6FAA627B11DC6BB5073DA156D2A4A08832D2590873672066B9A35C65515B4CB5602753B26C9C865716A6BC3C059272F0DF54DB6395F59012ACF2A783BBB03CBBC3A95F65E04A0BA76149A8DC4A305901418324885D44780F65E17E4C6AAD08355A59C21558B0D206C73F59B5FE49F8C5B86A6747DD9E8CB9D560B22B51B5A6AA82277B676F04399570402818A97881EAE8A245E1B75FA1AC50BB0A952E319E523A292316DE3E5C4AA271265B79D37795AA3596CAAB1072F3775D06502880359D73C5EE0C782ECD04ABCB1255B8A5051CA51EC6C17EC955BB6E715659B4CCC4C74484313C4F5149A288178C49F99586AF54710BA549C09CAC0CDC76D15183C8748146A07C72049108E86C0447B371B844C3715A914E3853F4184337381320A02F94BA1D9EBBDB0033D377254E4EA51AF455A775CB8E85336A761864239426A449FFCB967B82461F6F5A21D7A36DB8B54A5AA3AEB2297C30463064C8AFA12908D4B2D1E5B0F1A23B1D55A5E96886B96C39E10C6A68008B0527703EA2799F42B5098C4178F47490983793DF4CE2B0A2D2B56719256206493C395C54292E516D4F8A5C906736C89810BE0846B8BA654C86A355B56736B9144853286D65E61413F7DD26D1D2ACF6728BF6B028F912602CD132E3D6603DCBAB4CF65B0E961A8B597A0810B9F78A14F0DFAA108811CF22C394F21BFC56155A67B85722C755351576B0AB614B7C9C2278DBAE211E33839B55383C5744E6270C92D65BA82590AC613BF1493768E7ACE60A14644C9A02FB30BB1A6B42A6B69A142BF670C48EE03077BA7A2964020D528C51CB17B0245AF11C4A8EB0785ACC738E4F0CF0FFB838748314CA51C81331DE2596345B44F44BC516EF123CD8997E1FBC93AD95C0A9CB71D46C5535A99B75122E5E710DA961BD873E66DDD"""), + xeh("D176C0836015362D1DEFFC1901127B5C41C14AA518BFEE6C62F2EAEA1F226AB5") + ), + new EncapsulateTestCase( + xeh(""" +6453B4019A8E77C7607ACC6DF337097A9A10EA4836DBFC7C796A4E73A236069C2005C2BA2D5843AE7A008A337876182C44B92E66EB5146826B246CC7C3F44D40B0C88A98C11B873A29D7A4C7336512E00413EB519AA39025AC463C7CC289270A680B88A7FB9CFF592FD65626E831A019EA9E4C9BB57BD34B8D28B8855616FCF15FD6138947CA36D863510E6B3D4B22B8F812249913143F7CADBF15AF991C7E36C1A610879D9240398A1A1224837F904C65F0C1527BCCCE8459B594739F4BC243D2360CAC320AFEB5B2F5A310C90B42D3EC369F64C0FD2118D0359DBC3141F602CA8D7507EF830F1E47682068ABF22593563A071653ACAFF19506B5630F2B6401B78953B152C7A78D33216695B7778F9467FA239E4ED089A1E6BCDB682C4EC1B7CF407B37B0882777B12436063AC0C47CB7A58BB7CF34C5CDEC291BF1EB851DDCBE42535E0639580B191CDBA9AB22F0243D1334048964968941E7140C44A1658FE20C8AA023D2CB133D5B06FFD99FFD4751EBEA170F9C30BAD8CA39C64C7FF357F0FA2585BB13645682DAE24518517545175E38D5276FC442FB2143FFD2A7B61903CD72583FC64DDFA654081A4533457D36A366BA538B6772C5FF11674F0A702340C542357B80B2C206BBAF2CF6406F339436A7A1050792AA674C2E9C9B7986404C94CEEFC343E0781155D8B737978BFAE3C8CA64723D0656E9B89D23568AC6658F0732C332096A217CC6FA3A09FEB16552F5C982CA6B540C3AC96C8D0AD576820CC46DD60EC82BA0CFC14073424902578AFEBB44C321A4A6B7AF9709B1D9F05EC9BB6B928C936B670543E1B05E649FA7C2B3B9FB441C976FDCEB889FF63019F26EB2326F36F82231A68F230C9BF384710E11CCA858970A33445FF05CC4399DC28B285857168DD388F0B95B7E3B1699830950022FBA81984AA1B1540959EC1469DC696D7BB9A3C42153540B24A350CFCCBC33E5D9136824500319ADEE626BEE22A53FF8CCE2FB195D38257DDB8C305949D720342EB58AF72236F2275F98D335DE35A0C0C66BA752BEAAC32D113AA43DA092C4888D1750A59BEC4EB14A94A84C9947660891457B52F1BC3EF33C951A1DE64ACAEEC99F7795B8C94A0320F40D0ED92EB7FA346E042453995F2394B714A372E6B678C0BB4E04670B347C156794672FCA87966B26F0EBBD2B8304C9B6560459019ED95539C7C0C20999971521F8F7537B13937AEAB1E23736186C672AF0B084D4C5C3E1887BDC0BB281B7DB924BFDD9034C6456C427B9643C89FEBA3440947DD6B0B4BDD54C38215371E1A74E543A6073CB46118DE3B2BD1154AC536652BD2666F5F710C03CB6ACE948FB61692FA3A3E2EC4E3AD971884412640342BBB4C09D1C11856825D79A8E5249243062033E379DD1EA6526676A2492520BC55A4533CEC47C54CDAC7483500C0751BA84F0CBB020CFAD07B6F4E893CAE78DA0C7082F7A9C78D2BAA064C33D20644431BEDCB9B493D05C13104B88870361433490927B015261B63B1ABF2B59777359F74BC2597238DE6729669383E8188C0DFA7235D935657B936101BA4DA9CB90F1AED0F06C03700574B99159FC3E59EB3258A9BD5F47439B45A30163309A6A29CDBBC017840C5655E3E8FAFDBCA14293B91C07EEAB7E6C066A6B8BA7EC5FAEC0350B9C887B18"""), + xeh("4E302EB2BB5392782E7820868DEDB61F5A6AE558CA307A01ECDE4970E43EB448") + ), + new EncapsulateTestCase( + xeh(""" +409471E1024944D5203F82C62D1CA67E96567F3A525F6AA22683C4D537BA87DCA66864C88F292630484CE6C2592BE194A59B9642B0C0C1C4771DF87710F11FC8898573BB874965B774C3BCF30920312BC3C1945876AC6CC1221C9019677087951EF43031373BE34492CC5638D530A4D01C86F9B70296162950D92B5D97724BC1B7E9056C78D16290F3BEA459AC21395FD8A60EA8551B5D935510557CC36CC5C42605A4459CD7CC603408C3AB2380F7F00F44EB0DE7457E6F40B8DA2042F34C18554606E8A274FC8B6842F299C1E80068F11870907D8D44269BB7789AF0C8465B72CE64B5431A885A00B0C200102C811E8ADB7893502277FB87213AA89051852E896B3A170A33CA8F44A7367756944760B1D3C37318AB76EACBB47BA15DBD83CF8151BD2E3672934702C3A21886B27BC3506DFA8CCDB77C818734A18230868092186431221E3020157374ADD138C8F3C69D7709BF60C5A06BA3E410AF156B2175020EBD7603AE10C76DB7C2CE066A98A0AD4131781CC30311B38A78CB809BA48136009C36144B47AA2052E59F16E0216561BB42062817C67D81C96223C37DA9332B261152ED90350BB2BBEDBC438641CC082C8E4A4181628253734CB262061E40143BA11BB5AB75A89270636B330E922C5298068C85C1352FA5A133C3900A762F57B831A907AC37A6C9CBA9C915290E10A447A8B454A0F735DDB8852D79B0FCEB207C25568F44CE9568305A9362ED584D77123A3716A667CA2952CACFD7382303A69A817B17D895441D0A9AE1F71ECE1277C0432A7FA2A63C81A545910B4B212F1D983DC634313BC4B3B1B39190438D47B16747FAB48DE4777911B8D3FB65FAC68CA096919267783B0497868A9F95E89A1A3B2861A3BC89CB77F6976463CC7B1CA6CB8D447AA65463174A384217CFD41B4B80B7AA4072B10BCCBFA73C53E45684C542B031288C1192AFB1077B4E2B560E248169C6B741904304B06D23C86C9434AD64C67D92FB872D28BF9F745F2CF210D6D0C9C72176A3242447E06925718FE6530E2B5018833831819C23D3402BF9DC22FA7B1B754C6CD5A5C610275352D8B0A04159713C26422C688ED70B14209DA8EC23E8A2B285D61B8C5993739707386B4A084B22F70BA9EE3073644521E9B60D77755C30B36180B6B6A64A94ACEA2AFAA784C53C0C78E79203F36E98016CD1D109E17952A49021572B5F43857FA401BA617146E09450C8F392E423AF9FA294B7E2C2D772784B157FF591A4A13919C573713312291BC02F0F0C93721796477608E8E69FC64262D404C95DB98E548A767A184047A92C8FD8AED972945E676D946AA0DF5A88C7A13D03E501D228482FF97D62E27529372CCA9681F0758C2B500BB5D691D1734859B93E8E177605729337B39860E256D61C75BD462A6607692BF74A4CCC346240058B766502E740AF864531301226EBC3B8B5B1378846190AAD61C9BEF1362537606DEAA531EF97582DD1551E7A5F960B8DEA7A1815272145B25C7D175CDB568A68F05058F255B5B586866278F3AA56568179DF4B848FE535132B7C52D3AA3829686EA7CB6FA1BF07099F055416B8041AA9E2522CD23FE29981B06B6556432ABEF02E0780BEAE777D26FC062D94F1BC4C683AD2B92303D532101461FC0B8115556C3D2F2B855D1009704611"""), + xeh("7B334E045896C00F90D811489D491E8D72C4E3A22ED831C019FD4BD967B7A802") + ), + new EncapsulateTestCase( + xeh(""" +D0F1B584A87CBA7409D8B98B49B1332ACA1545B29FA2D42BC537CF959C6182305C95E06F5040B447D00737B0BBBFD9AB0A6062FAE209B24959EB83C2F0C5A2D8AB36161B90E2A92C5939059F8B9586F071FB1B26121604D5252D136705D33911703B91DDD85ECF80A7A1741C29FCB06F321E8BDB8166EA8C899B8064B69D77927C0B503989101F1A6941F4DAB06BAC9973378C2E6B3B19D9506B2C9A6BC29A51582C8B47B46306C1B35A438A097B07405645FC66C2660F4C14457A41B91907CB2864338C09C0CBAA7A877A9543F775950487DCB8CD8A105822B93882271A17B6936912A55FB4109B45B09BB14EAC2134E0D7471DE891CA984FD7B194B1529EBDA3CE0C24C1A9A170D76145215C8CA7217A138C9FB7DA8385E8A0C56B5342DA66F9FAB03AACA4E3A1BC5495C7AB0AB0E451A22D480B00FB29CE641C46E7A5EF16867101A26911B0A49140F70B8684845850DB8E15CB7BF842CE712480B19343077674D8A7B7C47A5E1170A629E53ADDD10F4BB35A601A843B49391D7337D7B3B592182F3A1636E4A7CEA14676A0DC508423B94B115041EA5F925BA0F2FA8536AB11E6D451321450CDFA076EAA3577D605A7E0B354754B92F1B411487FD8122E8DAC14D8464EC4331DC746B5693451B52878923649144182C1F03DC4281A7991C60F4A4076117B50C21670809832F3A67DC82E448A49AA3A2002B1A8667CC947253015A6A88FFC133554746256A103D11C7BC98013264D5EFC15A0B2825B37C356A96F0A5B701B4CBABF57640F2A92796C5663570B30FAC65BB79ACB59CE5C4CC7757920496B85CF938992EB32048360559745368854EC7A85A8E862A973AD50D67938265D3541161BE9C4097323F5E77EB8F66887A89FB7DA1A2585A4DD52782AD221B515A1D37778B5911AC7C90FA7722FD5A9484486A6210157188ACB617413516955F5EB91D2691E1E38CC2D10638330029D033005A88606E6A941962F3FAC506FDA5211609138E503E3382BD71640364066A2C27780898AFC1CCA9509C23F022AA77546017B1943360FAE24A54A0B965BAA7966F45AA7F3BAA7C6271CD28D4E0263BCCBBFE4FBCDFFE05269B048E948BF2EEA1E3C1825FBB3AA8F182B2B7BA52877B2304434DCD561BF365BCDC6AE0960211BA14EE1F9C8CBEA3750472A02271BA7E79C4FE6C9019B25470962315C4F50332414F46233A354928980A7752D7A07215EC24133446521DA5E4C50B615AC4E78F07B6EEA141AE146FF5BC2C63167483CCAD311B847996339AA50B2C237B4486E3B538C75B14969676465F106B9069A6F627938690139F011F5FA7D1832B96A0309FC85920E142C9C57CF64852E4564334281BA63068C5666A71B194319E99FB024AD33F879D08C16743B34038AAD20D2C84CB7440EE04C1AF4B944227FE94B5D666C3E51523248D913B9A3693DD1147AD7064696CE5B613DFAE1B83A207742264E878C7804D603BDD71E56C5CA7F887158E805161C959F072CBFF82DAE020C80135A8D1890F1A9A839032B0D69B9A7A97785DA5C201685C683844DDC99F4A97E00A063E15122AF22C27430328EA1435ACB07ACDA0A3B6B784EB19E30E08353CA26118AC4D5C4A218A262C4BA135AAC24F1EE7C5EA0E13C86749E5E72541CA6CAA1E1C05174B08745437FEED0B9"""), + xeh("947AFE33934E8150B06BDD1EAE40CF82EA99C0C0106B101283EA382EDAD94A8E") + ), + new EncapsulateTestCase( + xeh(""" +28C938C98060954AA557102D5BF39C17444A811156ADB2554562C5ADE5666704171AA3B19964449E1C12E721A30299307EC7ABC2CBBC82010E3ADC6DFEB2C497DABBDAC973021C6535773C127B3793792EBC717D392BBFD4906D4F21C62FD6C565935DA98550A2A310488956799AB9743B94446658FC97A9E1C3B263C23022132D33D2789295C994B6A441000F7FBA45C83A920739A17312AA97B1625FE5118ACB1552B647FA91C93C11182D9B9AFBFCB1A0D1412A7BCF92FC2E1A197EE4E728BB1812B88A87729C6E117A45E4E0ACAB2BC4E4A214DBF3BB4528316718C477329DFB1229AF9BCF0A00317FF526B8E4828CA797B354A0BD304FFFFC3E16C86A49355A54A0005CB1CE532CBA6A19267451ABC9C645A3F49FB075922BA931B1F139F8C627113B5358E02E81E71C231A41C1D647840B5AA96937B22926D6477E5B3A5D1C00485BD91FE5679CEEF18670223E670879EB3B02D03958A7751C007564EDC37DC0524790C8A0035AB30AC310F8419897597721D6B4EA87300453CFE981440FF0C18A323A0159B47A9C262545359F5031EF8B24A0080BDF0B55E1606355B88FC57803A3E25AB5ABA59582054E184FD97CC3E4635BC77AB797A748677B52BA76A16A9564BA218655A0070F20BD52B0A8C512A947534BBDC99D38621C655970B209C6DC8A0033105060133B600367E62366030810062387BDD120CEA00424C4C307E64EED5A3685F7B78E51138E02C4FAF51AE359499E2A97BF3799E216377EC3581AC81C12CC8B41AB95EA98C6D0500BBC3960AC05A2292789844602CA7528B2B91EAAB7A5F21399E13927C58BB030F492102B4361DBB4B3023961117099A7648EB11B2BF25703972CF778B5D8AC087BA59BC5122DBA63AD03EABC02031EF60CC765A0478F2C15DF31165903CE56680C2A62CF7FA8459D26C2D3C346617C51042351B321BEDBDC751D9080E0F64D2673C17055BF5DA53D74A0088357C1BDB8589AF5505C40CEEFD7140B95780BDC9B31482C75F5C6F395264A54C2A54B3EB6454C879510BCFB42DCD9548C3A53996030CE76A8A2435316CC227B591FEA7A0C12405D27936A0326A66A6CAF0B271BB64337D9DCB2E2471DDC632F3E0300F92C04B288191F0856C59376FD755729F195C264824657725E221BD017350982BB982078CA7A6783C64C5EF462F329BF6BDAC685D1BE483AA78B7BA7F2A0BD0C0C3A24341C9AF09C72D82674B0849BB70BD4861E5FEC25375223F5E4A4E20095F330C43A3AB23B633A0DA04553F69043A0B6AF862A94835AD284C31F82C23E80C2A488872E4B314636094C70A5F7614B1174AE46C11F45661256D566C6801985A2A91990889999631FB5BD4072C884B85BA79521BB2C7A729CA3CA8C18F5EB340EB84B00CB991D17933B3212293828BE1734F21B775BE289F77CA45846B3B6F029D6C610A0738F61B5C80BC808A8A506BD1022940AC755A7A4765A1C4A36B42DA453AA4B516F78B2C48CB94500401FDC654C1BA5C0D58FCE894E455667B25269A429671B668114181F06060842D16980F7A772480F3EE46D58C01682AA538DF1813CF95B67D9156D945E2FD84A7003CBCF265CDC12AA7148B7AA55C66F44A82E4BCF7D8C7B1ECF22E1BD7033C0588FEB6A1D553CF8BC477D94FF875323943762AB1B"""), + xeh("DC8510F45528D6981E59C1AA6B743BB844377D7339E359036929F0EEC54FE63C") + ), + new EncapsulateTestCase( + xeh(""" +4A6C1F1A816FB66471E6C18CE6126CD02BA76C730E721572DC730566496B3AC28F92A15F4C534C48578C18B443F24681BA2B3C3B390669A288EF7676C9A6B0970340F567C90407617B28A9A03274D8288006288B0A5B686FFCBACB273536941CD06927BCE109BF2330CF65A3CD0A2706EB33150A88504484FE182BC3C78CC5A7711845C3A277C763DCBDF16B19F1001727D5677687ABCF4B32CD161350EBA4206B2E1A65848528B7E1A90E04165BEE054F43793C23B0660FE7AF3E5964DC7C275458040AFC05EEC71A57E67C2BB794CE2680E7C4170FDB67F0F36DBA809F724B805BE66EEC38181FF1B0E9F94F7903661ABB17FD9BC0B0B19BCE2560E2C2C764F4863BCC40B5FC10B6513483A827C1668CCA8AA0B68039C8ACBE81B639E55AAACF2C761D78A77C2651573471434A14949943D945BC0ED2187DB442E41B901DBA0B14580710870B81B78D21996AFDDC6ACD1473673414E5C7C35EE60EDE3579223A7A2A436667CC51DD366DEAF615CAA4CAA073B60718B1E5B62ABF50BEBF4844EADC2ADA98CEAA8CAEBF187C2F26882673307A13CF83904607A8865A65592866499505051F10A4DE52893E07BABEEBAA4272B14EA974B5114101385AF1A011A488BA25179A118B312D8AC86FB58592D328941A3A0DEA6102C86F1E237DDB321615297A2BB660D5E0705A6672FD08A5CF212AC9B5B7A1306C87952B1C11B7D4E7C5B5FCB7030725C2A14AED641D78453E9FE5C6E6280D2CA57832FBB091C4418303CB4AA32DCC3C211DFC8A9BB429E750B2251149727ACBB112607EAB9B7744173D795B06D10EF8B1AC1AE54DA30A05188B0164B6B6E9223E93D377259163D62530CE9A0584F82E59534AC3E061B1B48BAAAA9DE1F8BEC150A63EB579DC528EDF977E7E421743F6A4C5DB61DD31334D3C63ED7755529064D67A4BA3780BC7C87731B86509738C1F7215275ACFC6E3B651FA91539B2B10111452570639E966766B64477C3F1E255390840FB9635500F2B513281E9D8B5BCCEB360F05913591899C1CBF95D23CB8D714A007990BB344C3A62446A80945D0CA84D3727CC8C39E0553A13B7050C12A1FB8BE6567930E0B6ABF6C484FD340CE916596B36BDC4085595CB2CF088467B0BA7F915A4E9581E7269C9A234F1A004A8BD0A2D7654018E55D6861B4067A29F6425FF1F5A00A804E3B3461DAAB9265D15BD530AC10686FE11038E772BC1CC46DB5C401FA76C1EE70165FB7C67C5025C2515E4182B46B92194FF361E252CCC43B060F50A64C79750BD162A586C5A63071D6E93DABA8BD525548F444C621A77E3EC583218788E3A7113DE38EB2ECCEBB0CAD737BAD9C21B39DB255458B8D6EE70C250CACC74A3A19C342B052A0FA5B92399013EEEC1BEEBC8E02F80C137030BA0A5DC8C3028B550925367BC732CE0E09570AB1AF01B7CACBB78A89BCC8C674449B932B98487AF0257928E64AD06967B38B30A0620FF9D49D2D63C2E7847E5B26046B457A7BB37CF012A7F18AAE0CAA41AEF72937B35AFDAB0174688B0724B25D67563536950081931A3ABE89B59297F701F246A6462B6016EA4EFD42A15C984E7157B5B4A335064809BD7739BAA23519098233C7454E241B23C4644A2AA1EB16E456E23567C4C3C6662ABFE76F52FE97F07F1298BDB70F62A5650A"""), + xeh("62A2DA94F109C0DEF56DFB275B1A0EEABF82AF8C6CDFFA94085AA93015BC1821") + ), + new EncapsulateTestCase( + xeh(""" +36C053F748B3A0655C3BA86303E099538971AB05BB4B2167D84B4F8BE79CCE515F28A90A5AD5CBC97B84CE10A39BB59AD2FB4AED7CAD205200A3C688AA32AE73F552A33B7DF1BA197F16CFA853C7FF24C1DD586ADE74CB0982449AB9815A63672C32420C1812326554C7219CA7698324115615C41D2E74A0138A42356232D7218549684CD9800F1A8413F3D952E78C915AD56FB0D1CC76D48F2ABCC0E6D79C67198D53B3B6FA57A4E9140D3C4286C97C7CBE48C3FCC81C6CD1540B12A077BC54F6F46711C844B46559194B5597A815827307E0E58AD7C4CFDDE826FC3594002A88C83760B56331A61C542C7B4487A851D7FC4D6A4072B7FA7C77647F8F252337252B1C9709517A7E217B26F26984D8D0AF75C9C1012977A3996D855A86C47266224C2167E585C9687C0FC5259E5BA10FA23DC4A2C163E74EFDA01956965A5DCA57BCCA2EBD4606B810882A337CB33347820C937E821E75A5BFBCC75BD1E37D81342F8248366945C0AA2B98F6E228A3AC6EF9CC28208470A3FA56C2F51AF83418E3D13212BC2C64304B4EC55001BC3620635C989CC4E4ECA06A453C8E5689BE8CA010C4026FE201EFAA271C2A772563CE7147932DFB7256F28975E2829D454BB2CC64AF8684B9ECAE285A93EC2212AF4CB65E484461D2B2121B15B37AC9446A8308437B887271564BC8143A8AF1F912BAC58E06AA8E03764FDD823180E30D47056A6D217ABA6533AF4399BCC798AB59AB0880913E14895526AD2F06A6D6536A0DE701D7DB9B2EAC7466FB85AC0020D961B39B88A8DFFC3FAC57524170B70490876F3A6FB16020EFBBA26E17C012AC4280C46E7F643CC334BCC302BF3BAC10A3891FF0F2BB81D29D8E421A71272C0F2439AAF29916461DC24B4899325FF005C0E30085AAAC7BF21B58B114BB0025305C8A1DADE9A1811329792713C5236B44B52AB8791856C535DC8B0E4DD0753689BFE0636DB99697B074BD2D3A8C4AE69929F00B8B256617FCAA96C980E8A629BDA58CF6A76DA49A004055CD4BE21E2C02B5533A7FBBC4525A95167175480A7B09BAC2BAA47A03D4872620C191287932029C9B53737A69148B7F483C607148DB23594DDB2F149ACA20F13AE693C2265A71E911A4D22ACB1ECCCC4C96B1A2C0CD45A5AC25533AF6829919D93770E42BEAD230BF8739B48C9990ECAD9E679C501137C49019C2F857C9D08FD533B01D50AC6BF2398655A1CBABC670299ABF46B95913A845151DE2796666BA6824237AF61789857CCAF0AB0F4B430FE966C85818B11E469CA2D7B705833813B8A775C77138F91700C64BCC6360231B1540F77113A33DA08189E454465474947EAA7F6731613BF9AD6BCC6D7DD1B62E1A3AA67C647A62712BC9CF67FBB690205E6E6997FDA7719EB9994D199505342D42FB3C6AB1936825534980768102619D79B9F197CB05C16A9922B4AD752C4926539AE184756114601A6ED90443D2869D0FDBAC6F447D91F37FD4E6649A90B70C73182B6162375610E9166AC76656A9B9242DA02CEAEB970A1803BD570F48B7B7557928CC4AC5D494BCC9386078183675D760322A91A1FAB770198A437C052EF366F6C905062010AC09AAD9594F581036A7E11B0D6C3B40BBBBC340CBF6D130BFB4E7CE4696BDB01ABE0436AC41B279FD576FE86BE94D213F70"""), + xeh("F374D3C7172C308D7AC5AB1F1CE5BB9785B98AFCBF4E9120B42EA83BD3BB1867") + ), + new EncapsulateTestCase( + xeh(""" +75F91DC864B819E71CE8CA50A7BB41AE94818BAB31B7F888ACE44071D2795361CA2B2666704721B02558212AB41A300B6D80B332A50448E36786D101A68A94D42325F718CCC4EB3521424C35E02A0A1A7A3514696C547E1918982B1066A3CB633E2B1D23280CDB333AA7B3C4BE7C18AEC44678D649C8774A4C552E45948801681F883165EB2C5E9D43CF38628E8C934C5F30819D4287AE4A51A797BDB0769534169E293C3A76A76361D79DEDA8068FAC187EF6B647C148E919141F02564B0AC4996B27794915A2D1C669DA50DD9B6E9BB57612CBC83765AA962068B8477D703848DEA456592A89B3CC321C3B86C55AB980BACD2F2605395BCF9E965B95D59DD608A8B8B85F66C8822F5B2DEDD36D3F97BC1503686F74991093A5799A146B434C7C2A6C573B3AD8C44FC517C92D042D623A7414D56DC45454CD08919FDB8D79A7316A4C14AA9961DA76C9DDC4CC6CDB37B474835E9A86563212F2B3908875588E2484BE8C4A49E3BC5EC609FB4BCD52D62AFB1B713B556CDDCC8BBD3B322E1766C627A0410A3D5E0B6F3E499272FCAFEAC90CDD100AB5D686F22023F8413F64521D19E38EBAB1CA6E31CC10278184F50843DA5CB1BB5164DBAB23374065B1043B1A7B1A241DDBD4BC6EA9057CC1A995644AE73231348414414C7EBC58BCB9B538A091434DC9010904BAB0613FA640C0A903BBE57A100B08A44A70507436C366268E7531C84A977B9EA2263E770E98306537B505A01284F653C066BA2F9FBC6CB3740258892076C01FA5CBBC8BE97FF0830BC746BA27555305D17A931371D04873CE2B89F5694BEF68515E7552EE03BB8E0517622768E6022DFD1044CA86A715930530E504D8031574087572974915885CD0351AF3610A5154559F688492579BB723A22F791B089C2CE3A383C09CBEFDC151DC266DCD54C196F25F0EE34092109C6AA6CAA76373E9125E143B2D0EA0874E4A35F06961DD812E60700F598926FAA7C1F7CA579CE9AEF3557F74E2039059258A001FC7F3B4A4ECAC6303672F12B9CC366E448124A27CA6FC43C6157A378535817B8B0C981809ECD54D92F135D0126480804EFFE40134E6C2190B95BC7C5E6A72B6487A6A454239DFE10AA99614AFA6A8F0E12FA86007CE464AED4063025B213D8597D412C9617AB62D9592D4320D7F97A6AC4092DCB311C21636358172C43B5626642336A96C1466BC30426DFAD5C0DEA50F715B19827B1935C79CFA1C9CA1F799F3954EB1C0720D134CF9A3122263B995E9268C3A1BE18A7112ECA0C4914F2659734A31A5D5708F3A145E6801C18761A280465C2D4600B9D968B3CA61EF9C7687FB1597499597ABADA930AEA4666DF40029F645A601984646144DB4CB68B3466CD7DA154C027536886A390234CA792FF6AA5C7CA258831AC1B0FAAFC21890BFE522A7685837A550CB343B79B2955C4ABF4939792133AB0D4A77C909BE0F0233AA80AC6B6AAB0F8102F374982C6BA88563ACF7254760263D7EC8C302F656BC227B3B558BBB444365A2CD95B421DA5914417C50E84311C6A2218A49169866518C201622F10970D75D38815787355A0C6126EBF189AB30321C15898AB117F6183C47174DAAB7BB8F96C3F4F239B642516A48F015E838A3DBAA500DE409C13F28FCCE5F266A98ABCB2D92E1BE99E438BF"""), + xeh("DD252F728FC9553CFEE90924565E984C8E1462CDE58AD8C4ED8DFCE98A7F39B9") + ), + new EncapsulateTestCase( + xeh(""" +19E628A96B033E4358CFA8C3C4A642D7127C16A50BEEE5C57A25476D8BB86D019DAD84C613D96A389802EED2031B1A07D478612DB405BBE9BB42A4BF9E7AA91CF2950D00013C4CB7A9B0CF88A87B19E41995EA9EB09660746B1A81A2C74F0BBC28287851CCAE8CB8118ABAA627F44289A9C355DB863095B397D1C449C20AA60B5F1EF94F9002B212C733D81C5A92631CD3B661B11056C9026E84A34E19836411A76AA53089071194E2C9696B31BE8351CB735521A42CB83C52C421724F2FB76D245BB5571358314A2967604084F64AD30911600B33AC9B236DB66487058F35611D0894051F31C032972A03A1CA5822317F953F91A74885E21766824F0FB601C593BC64253E7C36639462721C232D32A076EE245B9A7BC96C0A70ACEA36F8F41E1242AB2D00593BDA4C550018B1345D0806A3D1E8C7A8CC29790127370754A24A73E3A4B08DEC3A88C04C2022235E55CDCAF80938B579B63123E306603C781FF3ACA1105076AA2BBA1D966BC28BB3F3A7340D210D7E7A1735B01E749C0AE990775E2306AEB80229B918542608B7E281B6BB696E1C82342BA196D15EBEF20D541CC57CA928A9DB41E972CC1CD333BC7A64952247FCBC578860191FA67971A29E40C06B81CB5A765C7B26522C19A63C40EC31EBECCF7DF44CDB8B4E7BC805D42A28ACAC3EB2684ABDF46DB7E4C5B01A770B4C0D79D7190B97461BB75CD4A78574677CE26BC30CC25215B1C20C290A1575790C86AEBDEC7993CC94CAE23D5FA2871A184E721886BC920CAC11607FE96878971F161B788E5653698A9F8981339E581969C1B61A6073C02CC3822A2A2D0A6F5BABCA0D57175B86942CFAC2B0FC9F1684324A4139CB1342D7A6B26643A923FA14988173E58A82B67532C6AB89C0D5AA1CB47E44703FD7AA6816501023229B1E76833D7948F0743BE373BCD361130899010727CDACD4347B3A6645541BC7173361860953E61F5824BA2ECB94101383DA6A95CB4591C1BAAAB1B221F43B91D7985A173A0FDA756FE9B38ED1EA4F2A428E34F352A37A45EA83998B66C4E60B40650A87FF5185DCB0055B9C011378442462C285D18A0DBA658DC5B17D1620CE566C86879F38754CC8C1BA014827B444CCF8E9029A7763318CBFE0220DBED60F6720C6F96B4E70C712B58091BE3A6C1C4639D1ABAB09674D2E653DEC768D728BA593AA3C61B17DE17A07B3E85558F38DBF848D65AB3A1AC183A62AAD4CB18344E71BE4C97FEB59001F4ACA46342AAC389B22C47C2A216D9AB50B1A02405DA01494C44184363C31F5C39AC90507D94093F882E6891E24571BF39932DC5482554C12AF6A5F0B3AB4CBD276D6D850894CB4F414196D511731D23C8E039282F6C11D089BEBFB91F0A766935B3ED66458842B4C757585FA6657947529294930C886A50689CA5DF1AA39B8346A14150F051E5462A99E56CA383BA5ABD455F00AA9BBBA660FCCA2C5A8A74299581C274B89E4756552570A33514CB46CD7A3AED34A2DA42C49DE1A8645D64AF3D644BE586068A1B5804965BB7A6134CC8DACD82FF2E954625C92B0D9763E22CCF7450A8FA70F5793400D2832A03A5A75D404D1E2822DA607F6F9C4FB510858978372C621AA72399A34B9E2618F97EAB82B56D93E51FD73A90A78E2AC85826B8E6335330DEB8C644A29A1"""), + xeh("297ECD18E2880A596F572B66458410A0D827851EFA55F1C9CC513F7991F0DA0A") + ) + }; + + static EncapsulateTestCase[] encap1024TestCases = new EncapsulateTestCase[] { + new EncapsulateTestCase( + xeh(""" +307A4CEA4148219B958EA0B7886659235A4D1980B192610847D86EF32739F94C3B446C4D81D89B8B422A9D079C88B11ACAF321B014294E18B296E52F3F744CF9634A4FB01DB0D99EF20A633A552E76A0585C6109F018768B763AF3678B4780089C1342B96907A29A1C11521C744C2797D0BF2B9CCDCA614672B45076773F458A31EF869BE1EB2EFEB50D0E37495DC5CA55E07528934F6293C4168027D0E53D07FACC6630CB08197E53FB193A171135DC8AD9979402A71B6926BCDCDC47B93401910A5FCC1A813B682B09BA7A72D2486D6C799516465C14729B26949B0B7CBC7C640F267FED80B162C51FD8E09227C101D505A8FAE8A2D7054E28A78BA8750DECF9057C83979F7ABB084945648006C5B28804F34E73B238111A65A1F500B1CC606A848F2859070BEBA7573179F36149CF5801BF89A1C38CC278415528D03BDB943F96280C8CC52042D9B91FAA9D6EA7BCBB7AB1897A3266966F78393426C76D8A49578B98B159EBB46EE0A883A270D8057CD0231C86906A91DBBADE6B2469581E2BCA2FEA8389F7C74BCD70961EA5B934FBCF9A6590BF86B8DB548854D9A3FB30110433BD7A1B659CA8568085639237B3BDC37B7FA716D482A25B54106B3A8F54D3AA99B5123DA96066904592F3A54EE23A7981AB608A2F4413CC658946C6D7780EA765644B3CC06C70034AB4EB351912E7715B56755D09021571BF340AB92598A24E811893195B96A1629F8041F58658431561FC0AB15292B913EC473F04479BC145CD4C563A286235646CD305A9BE1014E2C7B130C33EB77CC4A0D9786BD6BC2A954BF3005778F8917CE13789BBB962807858B67731572B6D3C9B4B5206FAC9A7C8961698D88324A915186899B29923F08442A3D386BD416BCC9A100164C930EC35EAFB6AB35851B6C8CE6377366A175F3D75298C518D44898933F53DEE617145093379C4659F68583B2B28122666BEC57838991FF16C368DD22C36E780C91A3582E25E19794C6BF2AB42458A8DD7705DE2C2AA20C054E84B3EF35032798626C248263253A71A11943571340A978CD0A602E47DEE540A8814BA06F31414797CDF6049582361BBABA387A83D89913FE4C0C112B95621A4BDA8123A14D1A842FB57B83A4FBAF33A8E552238A596AAE7A150D75DA648BC44644977BA1F87A4C68A8C4BD245B7D00721F7D64E822B085B901312EC37A8169802160CCE1160F010BE8CBCACE8E7B005D7839234A707868309D03784B4273B1C8A160133ED298184704625F29CFA086D13263EE5899123C596BA788E5C54A8E9BA829B8A9D904BC4BC0BBEA76BC53FF811214598472C9C202B73EFF035DC09703AF7BF1BABAAC73193CB46117A7C9492A43FC95789A924C5912787B2E2090EBBCFD3796221F06DEBF9CF70E056B8B9161D6347F47335F3E1776DA4BB87C15CC826146FF0249A413B45AA93A805196EA453114B524E310AEDAA46E3B99642368782566D049A726D6CCA910993AED621D0149EA588A9ABD909DBB69AA22829D9B83ADA2209A6C2659F2169D668B9314842C6E22A74958B4C25BBDCD293D99CB609D866749A485DFB56024883CF5465DBA0363206587F45597F89002FB8607232138E03B2A894525F265370054B48863614472B95D0A2303442E378B0DD1C75ACBAB971A9A8D1281C79613ACEC6933C377B3C578C2A61A1EC181B101297A37CC5197B2942F6A0E4704C0EC63540481B9F159DC255B59BB55DF496AE54217B7689BD51DBA0383A3D72D852FFCA76DF05B66EECCBD47BC53040817628C71E361D6AF889084916B408A466C96E7086C4A60A10FCF7537BB94AFBCC7D437590919C28650C4F2368259226A9BFDA3A3A0BA1B5087D9D76442FD786C6F81C68C0360D7194D7072C4533AEA86C2D1F8C0A27696066F6CFD11003F797270B32389713CFFA093D991B63844C385E72277F166F5A3934D6BB89A4788DE28321DEFC7457AB484BD30986DC1DAB3008CD7B22F69702FABB9A1045407DA4791C3590FF599D81D688CFA7CC12A68C50F51A1009411B44850F9015DC84A93B17C7A207552C661EA9838E31B95EAD546248E56BE7A5130505268771199880A141771A9E47ACFED590CB3AA7CB7C5F74911D8912C29D6233F4D53BC64139E2F55BE75507DD77868E384AEC581F3F411DB1A742972D3EBFD3315C84A5AD63A0E75C8BCA3E3041E05D9067AFF3B1244F763E7983"""), + xeh("59C5154C04AE43AAFF32700F081700389D54BEC4C37C088B1C53F66212B12C72") + ), + new EncapsulateTestCase( + xeh(""" +16E08D929596ABD2BA47558090531AA277B00DC8337AF578F3A18B3DA8738CA434ED41B537ACCC58182310352331A43A0CA85C606823C824602085B2338142BE48A00E068289310559E9155C6A991CF457F098C61C6B79C584B24C883296B03F9D100489C546ACB28B2DB181BF7B4EC80140F1ABA4130512BA2A0F96C9453DFC479BA1CA9689629779AD731B159A61582CF67989266EFF84455D191032486242E6A9CCA6314B788A3783A0D003A4BE1AC50700611DA61476962E48E38AA5250CB4E60E44B52F00C5233D0A72E3D010D65ACF50CA1704CAB0EBA28D084387DA4BC8BAF7BF3212954652577CE52CD0E9768B3CC606000FEAEC499CB13AC1CBCA0F5B6A0BC7B8B9C140DB83174448050D72C51F18BF1A570FD6314ED91A4DACA6C231404250704A86561F5861785F4B47A15420975225300C621EC11FB6F04C8613982CD16AC85A8EAF62B07FB16A2BAB515D84941AB7AC45DC58D43ACA35697DC711BF8D7BBB41B95BF48716A1BC462F332DB93B67CF858D694B66D9899069EB795B4C1E407ACC74493CC5908B21441838702A3ED0683AE0599CB487A2AC154727A1CFB30104A9B0715698D5E51417832AC67139EF752BA77B7C27217472C62AB8099B4EE2A1D6D98A37EA56058A94D8B86FBFD17972E46A496B2530232F821B68D306AC78BA8D719C6DF278AC79E6036CE55D4E3995CC772E4538BC99E5A5AFF866AA733E6A15A4C7D61ABE8A315E908B588566DBF922C17B6ECB773B59D15416935EB8197FE751A4A5C49AD6FA5D087489F299B20E6721DCC297990751A57489C3A9CB59745FA51191A37873A166C84AF394D280982FA2171183345FF5BC17077B5432236108C6537CB68465C08EA6C98D4B1B606B73BD2A6036B16922B712B68553CAE23630B926276762E3D55DBC1A2FA1CB1372C9460B7727E2CA7382F0B696D005E07AA6C2C763225C30D846710D2286244BC2C751A5BB5CB71F24C75B40C3D1DC0369506D78D39BE3564358764A074567C51BB81B1090ACB301AB95864406B500CD04A2517C582601057328C8467847B4A3248A4BB63251317A9AF93475063CA34D382C4AEC93164011882A6AEE1771EFC99E84E1B68217281B123672999431BB1D4DAA180E9202372C8CD7150FBE3166718AC3746CB0E020AB0A349F88E21D319394676919CB08B29203A6EAC112B63178C7B8C29CC28C4C085A7D6660B12BC64B10A00C038F80076AF0769FB6D42240CA010843AA33B5C534A1C3391928ACF90132D0598E35BFAB062F771696C93696A351C5322C6648CB539660902526202AB34BED4ABC9DA427A1602ED5278897785A9375110A87529D74B951750649DC2B03C0642755132734B808897B1494C98F87376F223207C267A9D5961BC6472B3B8EBBE9ACB9A79A3E2A3FFF428282BB1B79525B7DD265A9986D362566E93886B106C7DBA07FD1C78CC24008852B152822120E73807D8B17486067FAA964330BA67027A84E2BA8A91801D46A059DDA37EDD31875600794E3588AD44331741CEB3990908A57A7C1CA8D7AA3D9864F8E501E9B5603C1FA8ED23327BEB22B08BA26E79C90928B756F96771FD7244B346CB18415CD3CC5BD845E394BCB5C6399F96338534182F015947EF7230A0AB825382957F8950B31CF94F31C0867255A597D9501A76DC2BB7AE455D8296953C51C7BA03A3A0A769207082F45A5100CB49C86317B1650B5898BEBAC512960830A37022CDCBBABCA0AA6DAB3E452A12C1040D54C1BBC372F1997C0DF75BE5D1C88C1618F1833B223D02E2B0980FC187D93A75B57E0487D2CC36AFC1838519378E5634502106AA7B3923830C9B9BA6717694E340B7B51CD63917FF9770635F42F212085458A45BFA09265F074036545FB39CCD08522135AA522670A640B3AA37782D9C7794DACAC86D651B030B33F14464B9CAAE3E883E9582F16558B03D77EFC01AF01E2327CAC368268A4A7141F375C833AD3B4369533FA727FE051C33A1ACAEE8832E32986067468EAD91D79A90058F608F97A1226CBC26339540778B3C1B0421E88458CF69C8DC73287A36D80B57F7FB5B787B66C22658863DB1F60985156BC28BDA25C56C5BD35812020880DCCE46546965817DCC3F1667496F12589065EC68853863C1C581B7F378C82ECEB88D1AB88CFD7DE4C88E0E556D945755EE2558034EC6FFEFAFC68E26128BD7625563BF279"""), + xeh("2E2C821791D3EA49D0AF380B97AA24532F6109D85360A751BB8B4C048C48D26F") + ), + new EncapsulateTestCase( + xeh(""" +54570A4B2AB131F9139EC171AC5ABD140863A6A0C5C13C8AF54094E95620E4866BCB8483EBF0B21FF9987B44650951750EF0BB76334235651CFA85153451B1975380513552FDC693124617F395121DA27F86AC80AE363707CC3F264CBA1B703DA67348BE45BDB4293C69E31EA73B0DFC35083F2493185B108E09467B2BCD44AB17D7BBC41F73057FBA8C2732730EF110E740AE75178890746FE149C8898B467CE116F68743A7B35453720BC5D9261946CEF3D9931A4C5F2F271041F0C4BA277778D56EF9DCA3E8CC2A4937BD9A276D173258B70C0BD9A0C695732CED11079D816E9D00A1C44A095F746D4EF14C53C64399964884977D503961A48C14E02A4B7055A74A31C5C55AA503C9927F017A194917F3AA13B33BB8FC86126A8B33EAE53CC2631C15C39FFE2615877084FE0C94BD5013A9CB467FA66E780A46EC5BA392D3C7B6579F63F2656796622AE9428D128BC546B33B26C697392B57A240338117107ABB0C146B2F789FB1A4552A4747C520B161C6A356F1368F2ABF7340BFC8031535876A185C11BFF5176B474B3812BE1E7603085453BD5B289CA97F20B82D88E30064B39872ECBC35E447E8431D5A61B25220CABA58594E96CAE054A791736B51E42F3FCC1F2F7CB8C86C9B67FB5FD53C93ABF3123D11CF5AE491B25703AD386839F4B0370C3AFF50903724C592141B88EBC6F61732F1DB038B15528F1389FC574634071CFF89B39D5A3F50D5B8E6E932C434C9BEF450E42765EE1486C3FB1221A3B3FC42C5ACA709602BBAB9A9BDE4A9716CDA0370B767D1E29128A5560164ACF0D03EC60833AEE125040B5A5D45827C1A2E2B3CACA923BD51134E216921656579F2773C4F0002A285A9EA975670F02399626D65135119754F01F09E204C305C880E93816516B0CCF996076AC93540144231F54ECD27C7C3DBA3DE988E8BC1838F68550ED8BA14D35E14586516BCCF459A3E63C9C69366A5A2992302092790341E7FE08FCA4B77906C839FE929635B89971512EB73456462BA9DB473770B9689446E4D69848E21670CD76F04896456E7BCB4352B086979DBF4905F656C1D67169D71933FD8B827EA5D0B5B00E0C3476BE53F56D11FE47C1BCB5727C51198381916572257D9E5A811E6601191477F45B2244BAB96943B16B28074B7129337333BE218DC114DF16A83C4C1B76A28223489384CAA096097A26B0C17E1E6686D52214F756A12F3C5E08985843909DDC1C4FB99CBB552C9D2594B85C796856C48A3D99A2B93510425A90B4AAA035150DD1394174429B6A394EE495E060812C6044678CA6F5DE9AAD4C11CB4060225F07F004969FFE991B7442176E00D7AD4C6C266435764CAECC34DEE027ED1CC4B80BCA242495378F0097B797C9A0C3F49D7BC2961A41D751728915166730DAE7A588C550F64F06CEA7A868640157F05C69C781682967CD4720040060782500C97593FD5715CD84A05AA10958FB482C38C7DA01A910C5B0C055BC2252B6FDC659A94F36422285F2CD477E350575C4AB3048C0F2AF83116BCA3EF65B0FB73C77747C3D585AAA478945288CDB0853C14D04DAD16052B71C02AF9A3CE254095C26736E6235CD6B0C340812DEB282249AAC87C7E35639E31A5943F61CE43728332B9280495CC9268825AA923DD5155BCE616B3675EAA5891FFA7A6BBA07F14196001253427E8BC4C609318940EF31030C5C9965A26B7B5A2440EF56BCCB424DC75350AA0129E05C83C19856CD93BC9928A8D674381E6B79EBB0319DA1BC7F427DBC1830FF1CCC468B5E68B23AAD73526D16DFDFA30D8CB3559296E35449F36B280B191587A692DBCD610D75342DB7A919F8ABB1E12BA44B185B7560AF79200427150D34601EA5A929025855B34B3067A01BB0B9564C186B2820917D5BC444B30755BAB812C89D201AB6D376135F2220F37AC35876B6012975731077F464ACBEB7A1E7764AD8502A68C9616B09C33FC6688166E1E3170CF6534C0212731049A31D4353BF80A99390064953419E9CD1DECA6F3007D31298DD335B69B971E4F5261F4888318A6A0C0E2AD79C19A827436E87886E29768AB261863243EB5D101A11922B2558D8F53BBCFC1BDD652CA6B10C123C41575F609630C660DD9205E571B276A36C64C770CF3B2D362064F0C94E2BBA158F235F27464280CA9026DE7D64D513C6120035933D3067D03AAFB1021A78860771BC04B4652"""), + xeh("5729B2AF60A4A5EE3BA6D7F255D7D2437812579942FF2C6F48611669135DD695") + ), + new EncapsulateTestCase( + xeh(""" +6914CE520C02BF6687BEB9330C704296E40E350303EB356AFFE66FE8C11A83102472EBC96B6634E76C19B89A5E3E4078AC751480B66288120A0D9B69D78387CFA44F32C08BB7768B292BCC03141D77871F5405ACD1403564A27EEA55298AA0544460CB1C8AB9E4C006EC2A1FB5B48F39745D66FA899C456DE0CA4A5CC4B2E4979820F635B5A286ADB3B8AEA97855504935E21C37E226DAEB41D2B1778EB84F764651B66ACF2E7B44FDD43E037400B50C97485047B06BB5B3D1A16FE95AAB462305933A3C730EB43CB6D5C10D9DC25FE0F8085A689C0C611700F894CAF593BA4833466BAC987211BD548C81A2BBDFABB5CCA192FEAB0E1AF3774F851A646281D1841681A40A1FC34EBC8BBD731BBAE927C403BA9E2993588B885008317965F9967D249EAEB85C650C18251AC22930A6A68366F72037B2250CD9B5A568766842A812C3C7BF7106CCFB122007808A84236C2E5A88BB111EAE388F3756B2410776C6D745F770208F5B8BDC087F16F86D52098B7EFC2416A786772124D41187546BB8681672951960C6148591713C19783186A189806CA9D6EC3BC0BCB49404362B82B311E8C970107C9B7A3D6D526BC59C48BE93C699C79167C63A45289AF1773BA21A9A2F99C6A982034914B55A301C27C73D27B50AF02B35B6307DE2F24B1453064F847308836604C56C1ADB3306114AEBA38331A56E6C126445EAA258E25FB692A761EB62FB1BCC88AC79E5EC8CB583CD8ED799D00516B1021958333394B30166718EA0A600CC37403115516768BA1F110F4F27042D589E719350931735023604BC6B0412B67423826EB91711ADB11AE8067C688B080CCC3939142CFE33C9D58710FDEC082A88903E9238D3276316018D38A841930C919A2493A06051CD9CCEF8E46D62F61AAE1A8600A291B55C35EFA8974F1CBE0DA10005A68659904E13631BBD92AE617ACB7618223931C989EB45C5C88FCD74715DD17AA86704C57A2A2561533B562FA7E5B45BF7212682900E70CB2C8227BEC67CB1D7536B405EB6424CF2F5A5593AB77D579156750B78148C33E79BD9E798BA162FA3332A6A7AC354CA3818C174CA0B354B4C13564111DAB79A0BB95FFBA8A71355558A303FF4E9333A708DCA860915B19EC026B7C4022635E404228776931683467337372B7FF7665E9DF38CD11921594C899AA3B55852B76FBCAD0159254B91B06C412DBB5C998A283314A673FDE81009A6C27F733554914B3582C31D3B2B7FA80B9BE6157122ADCC891B21E43AD0343CB014455BD00DFC2C5A671A86A884A5757336D267ABB2F61E18A68CEBD24E09311AA6621B09E4437CB8C6FFF7A0930771D48AC952E317DCE9A5C1261DD83287D7B950ABEBA6C5300105188DD4B4A992840FE996AE2C3B20D7BA00B11AB9396C73A5DC5477FC0141171F6BB05D4806CC9B244A7AF264D84956FFB8A67384CC522BB1335737D5A680ACD3AD478191638A92A0E7292672A75982AAA8A93E321CAB0DCC616A4B9C344735BF6521FC86B0AA3CB1568A9EF7B19AFFE9C352B5B84BD7B66B07C7378B23B601B88C43B794E25DA22083AAFC52682B2CA90302453AA595C6B43E24A84FF07BF298CE2FF1CB22C6BAC6511784AB4FD5AB1A3B376684867951AA4C78986E04A639E8770A77BBA187F08F7E910AAC433FB5461D374C7022693594FB0E25E52882D310495B1340820AA5FA13E187B6335460C37B0DC1848D7CD6C85711CD292994184481560837820A2B9E3A09B34ACCD1E296BE3816B26764DE9B0B16ECA200B21B9E338014FC5F99A8323C657061C59683DA62B22A370313BF5150476DE36B09912283544E2DB6398B1168BC6A33A257605DB863D3C4A6F190488C402D07C754245C804AF6CE9E2589904666AA335B09C35B78731E14739EE2829AFDC991EFEA87BCB3529EFB1677D5378E59B31167792C89449F2A7BDBE01C8B2883C9B880E626AB1837836BD9216118302690148308A944B1B20D92089E113DF5845AD2F489DEB51DD4D4906E93AB9D027D89261C0317561710A033F55B6D19756967159D70870446A48E6B1B26E05258210918C38DC5985D832556FF6872ECB2BDC1A009F8071DA7992F3249AF49C675DB4502F3D235A63C6321B56DE227AC0AE436E44723FF293FC2979DFEF64B9686A3E28597D5954DCF3594F10EB4D23B649636B79B831AD8AEE1E86B66A18D9A3E3F249BC38D79AE"""), + xeh("FE8AD6E3F3EF1FD1890FB7FF75A8CD9B2A04CAFA7ACEAA99D06D116B81039DEE") + ), + new EncapsulateTestCase( + xeh(""" +DF970CC655479D5361B2C99F4E6A60F9D15D9941A36F126062564EEFC3C75871437C021BCE4314A243236FA06A1657B68526652AC65AB05712A1381084254D048670AA24A995096D139236D6A7AEC6A830A4CC259EBA039B6A6E451A0B29D0B4D5FB5FD365B2D81C0D54FBBCFEE19993FA70FB5C92B29C95F0065629D84760272076BC11C3B72B96BC15B3651093DC440F6876E8A27834560B61B8A041499172045ABB4223F0D1AFC71616E8B6958653A08CA776B8916849C81A45A8BCE158B055B69E2F7487D4962FE31061B4B60034567E85496503108CB70167AC4BCFE402A50763941A15A3AB8CBA7DCC220D707ADBE4983A16C3484536EFC860833A527A7388CCB89693FC21906B932BD21584B046677AB9C4E0A54325CD3DD5A78E17CBC3D8CECEDC096CE167E9048C35973F359B7E9B729F95535408919958790427B1CA951080C9A45AA451CADCFAC9FB5804F8CABA9F88C09412ADA0FC2553B5921BE60FA01505BBBA2C33A22B73A69EAFB530AA090ED1734D7561C25299AE954ABA49A0464480B731198A68F9583CF0663322A1A493B6E2A2A2B06CB18B84C701E4AC73E91765FA72641B86249C5817511565023B6719252268585F2B077A3588C0291B36D9CEC74A1DF4FB33A4B95DE0FC7EB1746FD4E17401133F583954B9C947AE6A9AB443CC99924913646F70B29387293459F6317919C177F87EC01CA9E3210455EA25429ACCD4020CF4E43F98999D3739979CE39DECC5361F152B330255444A05F13406F6742BB51156A07854BB0A91C0B45C0F1678FE034BB7B2558232C14F83C822A22C7AAB6934661682E23CADB26D9D9284B519A4595954BC56CBDD0062BF657898B24C80F3010B849E20B269BBC68A538749A6F06DA2D62BC7FA8A25074629D12D22C6517BD4A20D8531B26BB13D2C9B2AE1639243B803D30455A1C0E4CCB5E3C206F4A6BB5C65B3205C56BFA678AC4189CD108DA5C654F4DA7EA30B0D7B23985EE80EECC2297CDBCB6A2A6B3A3C474181BB42F9150CE57FBC6C8ECCE43990F8C31F5579C71C7DC9615D47506666D05BC59339052BB090078E58858780671A65A14CEA22018661B9945A0D0EA2679388C308460AA9367CCC97CE6EA3960AA04BDD28B1B98158E02BAD3EBC3A97F2BB3A1319FB6178B99B42016826F4814960355722B8CE3338BAE0E97084613DBE41064D0A6F3082CFE25A18978975AFC04D0E1C9CCB0C1DF5C9054B22912844077DBAC39E40CC18C87179D420AC782D40E3AB5294C5B5E786814918D048835BC5333F421B366B26568C20E832AEB0410605C3B78394CB1CF5108F5C7538630C8EE4A611412F75F1691133A93EF744D36ACDCE302516735B09B05776049DEEE674F894580A55B792CB4ECC5916D0E3042D3231C8E70DAE111AF3A386ABE5A251FB9F18B6AAB4D79CF16BC884BC0993266C35CB267A9AAD057CBAE4ACC071123CD8D35C86A7C23A6771FC5799CF29ACD8F08E6C0B719E3173162418CD6B008C52A29EC5A701C97ADC906BA4852F7590353B190E96BB8A6C67AB9245CF45BC7DA31B5888B5B6FD77912E81A9CB522946D77305303B6F28B6A89469E734B5FFC4009C341114768EF8C0489E66C7EA3106F224A9AB4B0E147911757521BF39587BF211D9DB8F9BDC9EC21B881AC727810B4D1303A38938A70AB3248BC547B3783F68A84C5C77053726B808825FE17BB8D5672D77E4A178AB3C8EFA8AAEE419A09BB31CD40692A4BA273A137530CEB7198C5F38CD960049BE317AA924ACBAE241FAC48AB540C6CF7A4E58CA5AD3076DD7FAC09DDB1B49DA3D5FC751AE812A416B098CD712ECB99CD0567AAC9BB48DE700120584FD09A201D49A77D16132527F5C0138868C18FEC89B3D593EFA912FF66C79A2832A1B0234F5F0B67091ADFBC507913A41A5C22FFED19109AA9EC0F99395685682F6934010056543AA88738F1D88ABB1BAA21D35585F5534EF6241D81476FF33B434B4C335323C77318156F75370E1403C390242E6C7A75A9D800C0CFD84AE2AD52B9A0A492D441131B68C27DCAAEA93C2E3E2C661E054D8228B03243539649B861927947C76500910A5EA0164D43865B62BB1B30D032334EAF296ABBA4780DA5F12EBABFD021C3FF3A164B0745C09328D5BA0F6127807824E2A7C8012201510C3368067847C71C50A9D8DE22AC182D1644E25A39ABFCE37DB3224F725F065"""), + xeh("0AA3B1F8FFA63F89F949DA18B6D8570BC5811F85A4BFB293E9D411ACD43C3227") + ), + new EncapsulateTestCase( + xeh(""" +8FB403D0105FD0EBAFD6505968774504C7823474A1C26280A178BFD33368E14491C100CF58379A55575D753B75456196B5257D2B4BCBEB586EB0397BDC20B798DB6F12A8245FE80DAD6026DCC76EEC5B6DD6F9B5EEAC5211D408CE0553B11394F1440220F03FBBF4158A1C31F4735BB2296AF336C4869713BDD14D686940EC57CDAEFAB8FEBA2FEDD2C51AE61B4D67C5FA6B444FFA2E150788F1D4A12CC7875EF70711A38207C840C2A0337BC3CF42EC1F81464F731C5F460820CD473532983EA710846279B000586140A9B8F2B873C200B8F8D55D1A422F2668103FA8169DB77EA5957C4FA9A72259B60DC27EA16BCD31A051BB528246F05DE7B22398EA32C2230FB520A0D600CD8C049DF9BA6A5C665961344974385FA55525AE340342757BE2831807C552881C13BA133CB9BA2394453818D579787A6CFA356FA560BBDED6182A676126494D98A80161A4987B126DF67633E7433BCEF68690A12DE679512507AC1B9186367139213A3023418C69D0C67DF320C2CC88BB7045543C3380E4A953A03E63854FB986BDC898111F6A7A8FCC74A4F3971F21850E9770CC07CB0C5122CE8B2F873813AC558D9D4474C80084F0A924B3E2B7F4F4137EF5007F0C5605658DED4677A314A44D783C2E3222683B4DBEEC349FABA4430AAFD49160B6C91F2AF4092EF63EBEBA1937705F18A387A6307A733773206B8F2D4052D4C36D2F557FC0E226266116CE41B59233363ECB728C0343C0648AB1045CB03A1C225B89FA488114A060AAF48A68CB7B20A3C55A71ACDD7742DD05AA8495815646353DB21D4A7235450076CB94041D94A5D0245BBFA3598E870FF0E30FB81213B6F9916B78AEF3D43574CC07C9B5CF257A92876C49ECD73B5AC24DEC0BB25FBA54B29CC4A410AD40B5C6FAA398CFB82D2401878C79AF021CA0653A0FDA4B6474F942F93700ABA364AE3611B7666EDE2A8B2EBBA701AA61387500D674A9A9FB0351F06A5CB699EF73457A8ACE9E8B63184768363C50AC000220F2CB708AA27522149975BC951553EFD5B577D507279346E5D00F2EB31EF1DC1EECB59007027E65D28F0D10B7484654241984010B224F174EA69B1C36A302BC20B3244B030B231FA5532A4B206D3B3398E9EBB773B9CD9821BA688C06BABAB29DFB6AA2D427A258693BD1AB13276990B1775AC94B6BDA89F8866AA3A94003B3985086232A4A61CEEA8B1B711609B3285AD158BAE4C21581AA1541CEC7101AB7541098EC7093E442B21296ED172540972F52C04EAF6581EE942C6ADB287A2AC956D84B7F726158D8637962A40986B1F2AA1AD6762C08412F67D1A7F69B6F0F87AB022B1A48F4727CEC2277D1B157932B860A156DE79FEADB99DA7CA0D0B7A4A9D0B3686A100505369C47AD5DF8661CDBA888FC4C7EB1CBF9555548D87755C3232BC3467727AC4625B49145BBD95537585018A7FBA2A8834ED587CCA5F44884C87BF5B5AF8857A188B77A36A01B16F28934E38C9513B5A44926FF41212B13629E2986B8458AE3E9975BBC40C69214068BB78C127FFD4A664DB90BFC068B67106A43F1BC7B094E6048A529B974EF615517ABA2ACA75C97093487C2A265330EE5454985C6435FB989E100B5C9B80DB0A49421D6A75E1632F4B03F5AD96515039D8291C67A15902FE1C027133939183EA0434AD25B45CCBC0C69162CFC1CB527E392B1756E64561F4442BC5814098F33AC673614A8DA326F8818718603110836AB31778536A9C47BA820960CF181CA829A9911792D67DB209E9A66CAC38BC57A4CBD4AA3D07C3447F72D4231A69326AF512314D9AC918DA0BE19B624E5446180166D05F607B1EABC04B2A442DB33C71B66CAD3AA8E559662284807A69EB0469E8B321C73900A74C4A66D40B3CF382D53A12FFA26B9C8888516633E9F292052FA231404483FA41E42A9AC72312838BC7E17027C5EA055967497F3C9988D5A6C4076913DAA9D33C11D4335C850121A93C25A89E3AC0612087943A35E23204EEB12921675AEAB244BB53EA24C969DFC2A0F99BF925666C9A69F123A756104CFBCC88C5A2C8AD7A21956272E22F58035C140BDA371DDE7329D6728E2A05A150719C2D578FC511DD3361DF765C83BF2B04BA7546E0CB5C28C211489C96265335FB5BF6B3C3779E3CFF1C77379E336F3481CEF55F2F61A3CD1F98B88F29760A2BBCCFA7BC9270DCD07F290CEB1D75B0F5941"""), + xeh("2429F93D29E48EB6A25ABBA3EE2F3423CDDDD0ECF4B2090C6CA5BF4883F4F3BA") + ), + new EncapsulateTestCase( + xeh(""" +FDE545438A542588554452B13FB2092F3113D0DB9541437B6ABB3A02A713871AA479A1B6F5C20F208226A0028B5A680AE845335DBC9B9C3B91E833C8FEECC89F0CCCBE4216949684E094A96A469EA2B09F5EC49A352084CADA99EAC591661A1A2C468CCDCC4C374310E78BB0FA38803B1B1B078C9BF0D9280323067BE76B1BD3912901695FE1C4AF4A1BC38661AF797F9D7B9D8EF091EA3A0A53210C57A706ACE6A33F09083B728F767B51520BBA7BEB364817B820DAA55877CCBA3CBFEDF60E48FC8A0B5BC6D223CF56C3392021A6DE432F4B4A3E58ECBF462376BB62933D6815FD085653D5C3A267C150697BCDACC54E336D7024662BCA1782E531DC339851B33A0778A779544F4B081C05998787916A802436DA982B79164C5A5823D11AA271187E8F90790CE95C1E474E2861960F756F3191267E0158C1150608B5CA7AF09C23579608386822ACB02D559974FC6FED8558CFA6383ED0B5FCA318648699DBB7195F24A000E6A99FF8B4DCD0C3C7B84E59F7CA21979F646B4D8E7A61289605FB027DDD3A10CAB301B9918C365714E1391C42185874980328C04900AA9967627660C6ADA737260D74A1CEA5578A254FF0F203DFD6C832E86EFDB25A08AC5609DBBB469A7125A7C1C8644223AA51EBF9C98DFB64FE530FBF47210BB3C142360EA864AEB447459C6B361757AECFCA733CA2C5EA485B0AC065E2951F145CCA4FB6951579B4A19CB042A3B34419CF29B99A6E579945EC357C7C7BCD7578175BBD51444C1DC9A7AA54574A32623D2C90146B44F2547EE9930282F25447207B03C04EF6AC1294B9BAC6C36AE1666401E318B730020A832ED789199CA8445239B765D48610C6B25DC4C592DA7906C130A6E356C066534388651A0B4F495C39962C9F20DB1224B40AE0642091115BFCA34B5455568E97B0D45B74592905E02BBEB8FC1E2D1C49051242AD000D69009B12A206B988B8CB26A91DBC6305777234FC22142AC85B828D1E8B9E589800214173E858497B964E6DD98997576F5F4B9C68090563F1B004D38643E2872B196B1F607AAB3C22D73324DDD49CE4214F13065405767348A20BC82329EAE2283FB65ED1EB939CF25A7B1762E9686DD3576602073112141ED315300BE6B75F860884E0718C7596FC39172AD9BA4EB837393C49DCA98AD8CC15B849965C017CECDAC67161A7DE6863698C8A64E23A19402E977539E834887954867A29CD2F46B0FBD6240D89141FD8C9ED390099D905C5101B63B30D4D61AF14965FAC227470B38642064412747BDDD2063A942EB0F02843156C1D637D2D8C6C5161CC3A21A69C6220B39CA03BE975B81921C56C140422A8791A9CA2A9AFEC49353B65AC2440C31E2084FACC6F7F23A027A682CAAC402A69675305363BA85947BA5275B6868660B654D91264870FCBE39BD2E68B9048C29732A3A7306AEAEA8A08BB65E5E078105424A3B8803EF9C62CD65D8A65CE6D528A1A818E1BAAA4139CB451F5A20C135F8A231E843531CD700A2E69BFFF186DFF49108562361F353A8E5A23C900043034BA6B9C6CDF2A7C67847F78E0955F7C49EA94785AD3495CF4562EC86F72E22B562382B82B392DBACC1F536C18C20086A879B82C291F45CCB4C24221836383D03997C43EDFE165A1A046405A193E0ACDD08B122AF6925DB303491BCB87DAA36CAAB91197BA64A9A9E3C4A760174129B080FD18339E07ACAF00CAA118A84360AF0333755B869694D07BD108AF4A094C51A9165CCA9ABA36C2E3E43FE4DBBDDF257E08D03B333773D5E051F8101B8EC7B80FD1AF5E9C053FC71C0A1C785954C3AA4C33FFC95AF6CA3B248B5F050AC11B3998C51C8A294544CA4A60DC47529EE1A3849314AAA62A05D3557827AF57FCA1DF9435C4014669B9142DB620AF044C195B6BF046582C52BE435473C74A34CBE751599412B96480678B668B238DF373302076856BA63AB627CB21F3707BA18B999A3A27DBC727EAA8E0497FC3854A4A926905D0968E3886FFFC4F6A2B4273993282635B9BA013B4B8C91E7A47AA624F8262A14C42B4B8A36027573D4790BCF5D386B9181FA0F357230A2185747875970C668142E3673087AA02A5B7AA058C7527B1C0A1C9B05C912D49D1BC8FF629FA77CFEDD1A7F6EA52F9BB49A82B38C022C52C87C346482D42A797BD3A972E19DC352C66A0A315C04CEDAE314DC0D335EEADEA8ED3B75EA17EB388"""), + xeh("B65043CD3672CF9AE2CACC94F923CEF63B5127ABC63C2A5AE6C064B8C6FE7C57") + ), + new EncapsulateTestCase( + xeh(""" +E7104DFD284FC4B28110B06282BA8EB859CD60F8934CBA78B1F1653CD4A9613B4BCD5C32A3B30EF863A448D3A17FFC5908438800C5CE12475F3D5445761CCB25541FAE3653A8B8776256C7F5384481772ED0E3C4E512988E605E1C75A85606AA574442888B87F0A77C08824FDFF2B5FDEA4834112BF77C011F7855AA065ADEC66F505A72EE45300E2C9B18588E2F6B57B1C2B26F491166AA9D89D9BC2ED26DD311A81E4232FCC720CA8A788D5A00DB696763256F58B2B68BC32653C71F84088383473F19A76ADE5CB5B6BB466561AE7294770F9148E9E44B2FA1A23B1B99CEC1327F60A002728F21CB9D25AA79F526CCB4EC1531864AA550C72336509FB3061717BADFB2682EB59053333CEC75BD6E244F002D0BC2B1C8008737AB62CD42D2BDF9CA2FECE31DCF836264F84F76569A16046761885C163CCCE986122A11C8911C9257B88FA2CB792BE55FC14048BB995F11606E4C3C82B3113D99B451686ABB1F129E22D63EB14C6C3EC2479BD0243F57876175B138BB0D42313A28C67F1134733F76977BA87B5A11523953947B684282905F2AE90F5BE1CFB0088539313A9FE2A3AC9729C2FB5FBCF492C5ACC90A74C934B1A29AC19D2E20CE74436742A1415A9A0A4CE3756C199AF7593A7685C02F19768C6A1F4859B04B0186C63580916915053404054929F8B417F6A3919882C8D31B220F1817DCE08267DB0EAF61301C2844CA4556F813279D122C43A8820560A09A18AE2807163547B9A3E22F83E14AC4DC3FE69A25FD5C2CACB6A67905C9C754565EB5B17AF089C4653302AA830375B9CF0BB6D43904DD8277D50BBF4D43ADE05918ECFA74DD432CFBD829C4F9838DD76EB75813DCF397E3507FC9C6BD69C2B220644D3EB8839769CFCED608F98874EBAC4367A11274317297DBB424B95B9062ACB4C83CC5E879E6688447F26C0D2BA3763406318BCDA3228CEB0641C7250DAC193A8713744A6ABE5F6C106DC4049CDB49FB946DDB7A08D2D73556648F4CB82E2AE989ED61677B805F3A61344A14A2F3DC3964A90E4B83CC22AA8E7CD532BAB55880F212751C4CFB93AC14F564AFAA723FF6B31990A88DD32A557AA86EC2ABC114745C8038F4C1C924258B5BF02134605923E865539425F10424319131B0CB17D72C2981A944FCE3CD85A2509E93BE3AB5A65E53380772A56D74945D60C57A112FD87A2EB7989CC14A973CD05590495122811A6D8992C0064C77A78C7E390C43FB695726B7582C96C50A8EC5B4081CAAB6E9B64870166326A8ADA4731030290CD444B9E28149E06BACC7A79C5E7B24BAC292B7F92C7AD720F957013E1B118B3A40095C705DB33DE334ADD011CF3DCCBACCABA3B12A6FB5962E01C7C8D83912D9F98ACF8B1BA073B25AEA0C177074E7EB08CFF3CC7D7709E723340BCC00B014A0B313008DE52533B72393D70B3EC767A8B6CBAB61B8B7A9C86B263A1528A9FE366D60104C0D320CEFB76A688B407C0742F8BA4AB8007A3651C0F26B81E92746DB701837B575AB00A6B6D56FC5C12C956685ED0AC3F0C6A5870935298640E5070A8B74AD540CBCF273705C68115A828F72B09C83551714D67455EB46DC0BC14145CC38F5C1DF675A3677ADD28C69F0D462B1F1A0ACE8AA30B877382280F903B7DF9503E4C5048F4368B2A58565552EFB106E9AACC75562C31E3A3FE7790EC9269987C627EFF798A9A0484F215A3968525A0915C4B4AA7A8170EFB1466936A8B8440DAD499CB2F94373CC91F62673B59A90C728A818247513445D5AE25D85AAAB0036135DB5BD74D106AC557E0E8754D1E071B5B62FFF7575847B47905BBDCD5958A7A86852C34DD01286CBD50F0CA4628E31C5EBA531DBC02C9DE1BCD82C218C2CCA87A42A28D98ACFD1103F80AA9073C127381B4584C923492960537A28B868F214251E328FF44CC984972949003916B76D89D472B97013A52141FBAB0939B03D8D57364A387FFFB4A59D7B5D586680D7F54DC27AA7BAC39580103C74621E6D8970176AB2965ACBF453A7217A3C21769449E9AAE851090B52390642C467C9A233501110F059EF4A1A02BB06CBE1084A08C85AEA6237DCA55E2698D177716E662E2DC711D475C2EC9745BB061A90432C6463BA827BC32E0B0FA6B015324C9B574078AD823ECAB9010D0BC640C0A20E17317B2A30AE8AAC4C94695EAFDEB2BDD14D78D1CA07CEB411455C0EF10D23FB50CA"""), + xeh("6C8C075658F4257D42010EDFB1D7EA290D3344EE6E4C43DA799366985AD52243") + ), + new EncapsulateTestCase( + xeh(""" +F1E27E473692D70B178B466FB72CABA716C2468B308C0689615A0077215741D70A633734F0140F4479BAC081370D3565D24A4D0D7AA189F1C28792BAFFE9928436B9C0215FC655253D645B3B84C237212A7868131AA623DCD8BC2ED65A2E082C4EE29A978B0C458C9E5BD656ADFC68BF64291C387886493D12825B8363932AD17B8752BB49B63D074A508AB3CDB7341ACDC5AB76B8C5F9C93FD4EB74CD9891BAA467DDB28E1733A4260A2A4D496A3F705E318A042AAC818E408DC7A9BA20520E3A4CA237C1C581598D839B67822CAEE8C04E7BA6219ABB23D9455917B84CC5C94BF8594A2D1127601BC3E76B54155B1AD8C5754D13B564906E3688C3DCB9B963B7295310341EB0A36917919D289C2A1B001CC4360285A40DE87978FC532A242422829BF8079D71F347EDC072B9884A5D26C84E07B72E529DA1FCC8E57C1C2BC30685D12635B3A136755A70224D79FA7AB1124A69701DFF4AB135508014FB4BCF044218D4918790455923039AF9591087A5ACAC37363097C41B4153D375C933C488C216C5CC1AC56134F9B3567519CA21496A4CA06AFB84C0DC2743673AA94B15867EEC0945398376DC6981C6A9BFBA78D9950E27E16D3852A63CB08BDCE1C99172B4181654BF5A90496C764B6B96A25331E84162F902009BB4B76D8BC41C08AB7FA8B1C4657AB51CAD6FCC324E4BC70979AEE6125F2BF916FE8C3F4F5A72A695A6F8E34084728B0FF59CE1FB5161D8AF07CAB498D23475869F746563DAFB49B64103EAE0CE8A17BFDF1853E743262593C327608B27614F32C1ADCCC9B638029F7F9377B302248017747AB5553833ADE94A3846D309D5BB9872C89AC4E7831D9A3A3FDA26A42747E96AA6EE375FD407585E964CC4D6821323C7874986A1192FC0C62099A764A4554B8D89B9D9585A339072E9D677ED3475181197EA28BF6D84A3DE367D7529AE481133D1618007D5832E0A13B7028BCF5CAA36F4861DD22DAA497167E171CAF912B9FC8056016520ACCE1F68397246097A5755F8462FAE3413408264BDD915BB253A6229C26B14426F439D9AB79C39B11A7F51B9376A300C7530744B754713A50D71BDC299B9C0C7B266CC41F31AB512D0BCF5AC9BEE85BEA109734E7861646A7160BC3A27AA5CA3F87128468F3266B2B156210AF79D03890386A9AC0CB71BA3B41937960E575494F60B0704960518399199CA227D48B99ABC8E85C1795DA67C0D331B40CA8E448A934A38CB24D0730E181A7B30366335958D5993385871DE69C97B22A1DDC6BE8C5242BFD93073893D2B498627B76B6D39ACD7405B64C16E60E190CF45B5EB12735572AEF8F99E37CC3C1492979D3718BD363EABD56E1E416ADF9CB106F3540ECB4ABB052D57C728A558AB52FC4FB9C078374919F29558481C3ACB782959E2C41AC05B8701217E7BBF945B970298A694FCB0E12490A6C5665E267A8AA1A5F060CC0A08093E816EF9644720024FD0ABC5C30C39EA095FC5426E732C2490B288FB38AA6A3517D16BAE8F38BFB091BD70260BE1D80B2694B3651316484C1E97B714A67A0416179F2C582E25F770EDE422453607ACA79C1EF217C2418840609FEDF914D083595C10CC4CA70D40A8BAC5470DFE4638DD86A03DD428CC305569963CF620931B40245FF3098DB6C6A1870D5D7B838C976D0D0B462F441B2D79BED3A488697A191C20C0A8281CA8A39D61E69A0767CE753A02EE8987414AA3BB99BAB032CF451BAC1075162CD1097B00AF6A4A82F8112F28861BF0A6AA22733DB462BD15F95A211161ABC0C5B5330FE4D63854F3C0F074C077D06AC2839F06913FBAF33F7F91A948A19D01D6110AE54025CA068D1B0D7CC66A6EE0BA83E377FD2313EF44C87A58354D841B0158C8010B6EEC2898A9A0778072149452C2B6A628256C257FC224C0B767DCB3710071A71B43015D994ADCACCBF7B3A234C11FB2B56E75E4154DBB473978BC25758EEDB5319AECCEEF44AD82C3584F8378437763C3055C4A84AB71815EE5E360AE0A363286936486C69976AF602885769C1CBE21229B9C350562AAD4A91BE145AB3B090B9031175EF96CD275CDC68444BF890CAC56241159C55A474647A4257A978470BC97D28549F21590EAEC25D9603ECB5909D375CAA56B076DE917B8C7251C92B34563BB56AA6C3749113A837B5F6B5496259F5EB94195E2AADEDA453309F91EC2AACB59E01FBAB4B8F8"""), + xeh("BD990171C3252230BE21FA7F186A121686187B77C234C37CA5122A7AC77E318B") + ), + new EncapsulateTestCase( + xeh(""" +1909B5ED6C0D8D3C301F144373956424139AFF46757A070167BAA70BE7BC375A6D43E18FB0EB4A69B49A2D951E9265BC159A282B724F3477A2DFC89378CB9FE6CA8CBF55BE9976CEC668402D7A3D2E4CA2AF6A1E479621DB16A3187461036513C84ABE5BB228484023760266DE5CA11F1A8C63EA77F6E45F35D4CAB24443B51B851DD2C58EAAB9D426C90064AF14F8BD8984CDBB84C7E2208C5AA2C7E3A222249943985CC1F199BBAC9B8719849E5D539986D8B063A363B76953D22A508CEB03C46A04F19769E327A774A063B1D412B7B43D5651051E547487F2293EE2B78849BD36D2A54E966F8B386BC735152DC34E1A12772F67506B6474A2C57AC0A8CF53122949D52828D69E8A7A326F18599BDCA23C8C8E3B28624F26609DA18044411A9866C3A7D7083F09707A70192CEA40B936BCE696112AC92582428F30A800876BA7BB40560561AC5996A4B11639BDF00DD67A52F85C6BAB54055C2352121591260B656C43B2C2E89A891C97F39B7921794CB5A552C05A2D8E8BAEC89250666734C2DB73EAE68484DA254969918B10914CF4274C2C27319412360433ED27C810712F4E3145B5265D1EDA7B6917CFFCA61CC087926CB116020C7C49D1A8A723C197CB44118B3861A0773D52C6CE25A9E2C66BCFB6C5BEB43185EAC855D1A99C0A2FD5A348BB0C579DC23C7E777AA57249008497C7332EAD85C491A89B76427835983E00F5856B1443A60C83C714B122369A97C356C0755FE1F249C8D56F0D9897680CAC247A7EFA8386744B607BD7C195B52C07001384C17EE70AA04393C081EB43C7F912F3D786C7E63DF043A277329AE2C90A0E721C5713A47417A9ED1370C2761C1C029630C26DD215028EBA6CEF5239C25383F6370863F622BC055517946EC0D2C4CD909182CB51C817A04C53B4309B14507069303245B4B55B47226970D269D87340DD5A864A85A62CE3115AB7A972C813FD18C9AA0B582E79C228468292A8A133CA5C53A4C842233FFFDA7DD0002444C51B2009654067C7AA34BA17B7368745C1719572A2C66D6D894B92049EBDF629C7C5A2D1EA82C7791B7840729DFC7975C2C18F3B319B45AFD1E0BB0C527D3FE8BB7E95A7DF958EF9268ACDCA208053ABEA894928DA891788177185B362EC3364F93D4B602167942603412CCB595DA8910B748A2EC022C3EDA8437781BEC4A913D2C56043A1BD6A5B2A858A8F7742A82986509891A9EDA7859D3A99FD78A11335910D830FBA1B13823154ADF8984DB9066B6735704196D49C8771B870C05504EA110E252B4DEC2743F1F39142B6BC5B635110CB37925A3CB0AA83858A54294B29054805B969A6352925CC53017235CD75DB70C86198EAE30AE8F933412C0504DAAFE7516BC9D7A780E04290891E5594819F08C2ECF083711A85E1A679235441976B03E37B0B0DAC6BC8456497220F2D4B927688021FF90F2E00A64DA33D3C878462529B98CB709B01BDA6D27FCAF7899BE90853BC6C8652137851C3C7FB40CB3647AD8B7B081B46C8A2587086426D48819AC1AE43C429954BB5F7F2227FD8058C18AD81203462C055ADD5045BF48CE22271C5A67E20ACC0EC93B182684E2B230C0E44C0688A2BA0A6BFB7D10C476B24719700C70A7EDEC0C6879345AA781B6B415FCFE4373F78BB33CC62A659B8286154073193894B6D8AE85284033082186478FC763231154518B1A8A59B1CBBB56A50A8F9C38223C5BFDA5C310A1C30F2569C4E179D4039331293CC18870E1D1B90E0008B29008FECF00152748FA9248B7D64491455044D86C6C3565AB4618233A2154BD277DD5067B2E6784DA94876D1BEC361869493542C470D7E58A7B6F9236E200D66CB16D70A6273E40C8C69C033CA8EBD7A2E5ACA69A5E0CAD2C352D0F36BC8A0B90A29B604EA0DD6A77FE9505E717A721849A0B435C08C66AA44E202015CAC90D364D1D83F21E5177A100A9E7855A5C5C0A4B46B388C58D256088E455D59016A4DF337C8A69827A399E2E9BCAAA7B11CE6440A7536D0BC544CDA12392340504088B8EC6CB737C3B1C0A11F9B83C049759D74BA44507C6881B1F98167720C0B35A095DB1A7659B52E38803935241766237E073B1D2C52BB5F4152AD80625E7C52352AA4EBD89820F4AD1DDC3944784A239A9F71B243AB50C1700BA6FE82A501B275DC3391EE30C022997F00F09D0F5FC8A9F5B02358F99511C32A582B24C0"""), + xeh("135056EAAD8A28DEB1BE77EEA30CDEBC7B3DD89D1444DBAE145F39898256ADB3") + ), + new EncapsulateTestCase( + xeh(""" +11068DF3FB0ED1514D8B2B8F424C03B75995406482FC8AA24BA003886711E921832222367CB2C2EE87617A30A270B447D4A1BAA3377B83FAC80A7C8D779669C49C461B311DDA442FF10C9F2B9057225423BD119C68E34FA7A92DA2D36C58014A9076C391A451EBA75B5C92A2F14853845838D0DB502629B796703523C29575B4A5094C1BE329066BFB7AB6E17FD0163BE4E60E9D676FB970C68AE416897174D4577E0AA8BE0D234FBC80279FD724AD5925FAE2B478816CB07C165A335F1B27B030E7BA5CA40F610B0E07C82FA134812D9A4E083836B158231DEB7568B73A9B3C60780266BB550A36C7288A9387D1E4C904D79296088047F34F4E72A23A1720B7543FADC3821C6442F4B501E6894A6E25231437AAA7A04329A8CC6AC729B185781B8BC4D9142063E55A0F053FFF57CF93C5851C86714E872840A264E316C37CF90CE60960EC2B0F4D18418AC96E202C07EA61B2B1E6A430DC5DD1A18926E0BD88351B56434E26CB10268468D67B2D04FB2AE7C43C032675A2C88A3E704A7D110B4A544975616D694C9E6E243E3D546217471B14711505B945E87C0D39170E3AA71A0663062CF07FFD0C3952D526B662CAFCE429A35839D667C7F0090965CB1F87642D2A8C28A0A57B4FF539CBC3195A0B063F3966CDF41FB4D9451A84970B6B93E006342247BF5DF06B041A6A2B019C3FF93DFD39502E198F5587B358B39B640C7A71C43A31D711E9E5434B75AABC436531542F90730EC7FA6B72A3613BAA4C0579A245B06B979B22623C93D5CB6437D17A7E3302BA1CA5EA0533F02B1D481573C1C3AB05424900F1613B379707433D7089A316F52012B646B9A24A90F87584C36C1F58B891F5482B757F758A03E53B38F282C2700502984ABE9F1C2BA00376091021DB8A1ED27B01AB11B7F404B2C5FC9E0F8943BE434FA4135A4714507FA628F4027D0DBA912E0B3B096C057BE77506FB8BCF5A8EE6DA96CF335BE8C0555EE446DCB96DC2567348433E98D46C83319E3FE1624AF07AD838241C5CBC3C78C8493214447C8AD0D40DBF319057531FC456CFDEF999F9F280234A03C7437786B1469D705655D01EDE1A72BD0981978815086A0DE74B059BE879199A67C67BBCAAAA87201A1910F39B5D35670A9790DB3B5EFC798BD9EC46F2FA1E993110F180203BD1A7D3506B87325DDDD695211440F60CC1C5B7A947F42DB94ABF0C8C3B203A7038682DA9840BC8B50C4343A4D49AB89DE916CE72835AD4C7298B68BDB417EE999EFE7B20C6C99A0B36BACE2C35D7388DCECA369768463051B377CB57BC0B155B969EFAD615BF7B3AA1189702A7494CCBADB0266224FB5BA75189766771BD1B54FE1139E6C607C95A2DCC2462515C4C1981C931C6628202A1BAD941AB7667F89BBE94118568F0C5CC59914AB113AA4C9DC2787F92BA2E9DD7363D99CB7EF6AD2EB5C1B992670B5541B1BA9368E7986D4628AE96836018934FD100670260ED931BF9A47652B85C44F988B559A48B2007361A3E4FA88AB8CCCF94939D5F419861FCC617250C38DCBA082CA50035A196880540E50A0E1BB363E81B1FD158DCA79DFFFACEB2494712F28A52249A103C5FCF888D275A8BA3768BA0599F5FE1CF632B07F4120570EC5A3EF96CD3031A3425A0CF3A7E408337412288575C1A414A271149A2B115825D409A1C478980CCBB4B4B1C2AF675DB141A3CD12B0860318EC340B7D3C2C0521C57D5675864243AA55C517BAFDA7187A174C109CC1C65BA42AB5288EA23CBA8C286EF98479BBA0396106999C220CFD043C60C4B9610ACF0086AE9D883A0A89BDA5AB9993C1DDF82610B0A1C6D75093B207A72037E77E76CCB282F2A0C7A9149941F3A149EA18CA519C1800B392F48C3DB358EF1179498CC2DA8EB48180A99F1BA280012A324AC8DF3FC8B3D6859A0B4334980157994502C80C0AAD301F6E9311AE9C132889A3C26501678CFED55427F94B05B57404B4BACC7607E19E873D1902163B25C06BB3CEBBA5D403456C2CA26CBE27240ABC8B6A85E50762FFBCA34FF96C1525B2A35435A7CCA663B37C202931CC16039EBAB2D6E45BE1002023BE959F2568D4FDCADD8A1B6EDE529AB088D79DAB407D4791AB43FE5087E4A9CCEBFE02C0C44C3FA925B7294A92E928C29663D2854210D405ECA2C2E5032A3058C6FB2B381F5597FE98855CD09B73DDFB831B56551306BA4591ECF403545BA"""), + xeh("54E7B2E3305950EA570F823FE36A7999E419BB36181B5514860BED41F418EE77") + ), + new EncapsulateTestCase( + xeh(""" +4F4504922C38F9871EEABAB438D03555F272E9F9493F005F5F8CAF8A620F362A1D1B90A66289111D03929118CAF31B0AD9ECBB203017A02711BAD26B02310379C117F6F58257F6C6ED5A14BB32760D5A9EA062A9C106064D703BC9E378DF498B347075A7F6515787C500472BFACA0729A4590D39C291DCAB327C10BDCC6B1837883BC90B379B3C32F56C30F78C2A347EE0452FFE4878E2280608265931CC7E123768B0F93EB0081D642B4DC756210952541BB3BE08352CB983911F3B944671B759A16FB28C3883020892865E903045C84BA1E5E54159604AC058056C6153F738745140CB8B5ABE3318809651790EDC20CA5380CC76568DA5915C5AB8272748B42446EFAB58852C619332A08F537C28E93EC676345E0A2666708CB5D5281F981D3B8A19180565704808963B4015DC9B8C06905DA43680402E6B5888F2EC7448AA6578787EBF42329D060998E74B09C13D1C432A17F56D18BC624F02AC7ECB6235C42A24B42639FC490D07A635360932C71E25720EF59340F21836B74AB8F31C2CAC035AEFEA846210AD665A5D64616861F1CA3B963A2C10C662F7AC66298751AB3CE6A64C59770568B4B234129550702375D722AE4BBA5FD0899C84A834E7B7938627C9285912D346099423BA37B25364B67258A121650E895660C8E014A5B08D38B7AEC29175B424C234D2B87C791B60159AE753CB61D240DDD2814F1A7EB69A79AC37634850CBFBE2CCE6E918D1CCC70E13707732A6AB11329A3336D8E221531335BED560A468092CF690D1B8791F58993BEA001186AF5E48A2BE0B3D17656A3ED98BC3628C9F863A2C88C90AF25A11AB41FE7CADBB3C1013B59A115AB83F9003BE28759A3148706B891D9770961AC53D4C8B6CE5788ECA3F4A4A47D7F5165DC7B94B358591348BAD7B8CDA482B26F650DA1765A0911527260703E2CCC703A69F10331095BD3AB167DB52A3EC16B69F233862EA11AA9118FF539071A05066388A6DFA10BA4819D31A03B3980677CC6B888263D74007057C6C3C272464497A58681816C3C59E05064D147F62D5C848B8919C97C3BAC20A43CB58F8CA98EAB48B221851F634459B7AC514161A1C490B8B576A0FB2497A65006EA78F9ED50763A19F8D2C99D546642A68B6C2A49FFF919687E67EF0ECBCE23266114982FDF15F572A9519EC12CB90BDB3516E85E01106B9BA456738F4206F5F0C314156307F4CADC8983A91F730219C322A1602714849CD1B7DF5D02C24758DA6DA8FC8600CA2C1CF7294B1F6598D9E844625C29F589006C0875F3FB33EB357B7AAF0607BB31743153B98D64A8FC56DE56714D71303E9F6A3ED228961E607D6D6C0D4776828B7574A8CA28D837D24470E56F3A6CB6A4A90F5A9BA8A3F60576857E1C7AA52A16E1A84F7421EDF46C312BC83EE0776A9819DFA8B66FF2BB907A96F4D6228FF34ABC68248C1990C2484CBBC70745B045C602C1552B952FE8B4D24D027E1C65B3704945E507D09A9A6AA7000C1607A27591F606AC1D2C5CB55BBA149A15C4B261894EC9A9AB9C3DE446C1832744CF6BBBF949D54498319504BABACB8DFB15F90F66DA9E0B7F8B7A42A7B09C5E19DF58CAD8641C2DFAC77412B49D17A0C02341C6FB78DF00809903835518392D0288907184F126A69BA77863C84C1813835926311EA705433298D77AACA4DFC30CA218DAE405732841605840625E57D7CC3AEFCBA637CF8077ACBB9CBA0744E462D02F406ACB24E9A3C5CC5048337390E4EAA295F6831161CC7FED8938EC6287C8C08DCB0AAE66340C4A380B5B816B8110F3D190EB97C8457DCCB410739C48B8132A32C0CF59028962A8BD1B03F0229C908BE9D22C9AE65880E110977508595F6754776B4203AB1633870C4EACF7B3689A8D43F4C213FA839B7C0281D242452455A31F396BBBDC41D9C4C5F99960ECA0537DCDA3FC6405B139241EFFB20CFA05A739A43EBD39E2A516A6D136F78F43CC5E24C2335CBBBD7335DB820A235129F10C62D13C5013732214012B00C1383E670D5D37484850D2EA49E9E835A750C63BFCB2357E472A4406C6DD2990349987707CAAA1030D4206460848F3C988179E31A4334AEE89511AE4297A668A154270D963C7EB930CD3C35290C9585F428690F88721443757D793D9DF912680C21923138D119B777530A3FBB406E110F408199CFAE822AF8B67807B0181714C1EB366D2750DBA3CEE603"""), + xeh("F2C864FFBDC366EB96BC5F5FDE0D4B3348A07E861D9EBA90E70896F7FFCBD55E") + ), + new EncapsulateTestCase( + xeh(""" +44DB8BD3C4B5FE45CD408B054B878343261AB8F812BC75A953C8617582B10D789F7114A00E0166EBEBA0BA149370639BCF020197F82080BCBB9BDB49D15493114698079B7021C55CC275612D843FBFEB0F2B86CB659C6EED1CC5661B711621320A85B307C96F66C4C35C3081410045AF4B898C2C14B645AF9E0C9CFC03BE42DA4DB3A759E77B7D6894BF380991C3D4CB0D5B2CFFAAA08DF0085B8555228CA8E18672880C4F96E555F879C2CD6740960B94B6A60BE7557D2E230083D757DF76506311BEBF28C5496C00F338594AF41AA15566B24B004E60956AD09CCDB034B7C35BC5D550F52828007C1F85503AD86A9C811C440E6600B16CCD51EC098AE298042C128494A203D20BDB4789C4314C8D14543C9553954C9FC34C40912862500B2F3A5929471382D3531FC9767CAE6937D6E37D6AE18FE5B858BA968927201912782C6D436851C80E7AB0782FC5AC1D9C2F8CAC0D6C29148E220EB30909B2A43A4322B90E741C90C19AD52CBC1527CCC883209952A5A7C68E3E580BD987338BDC75FA84CDCAC3A0990246A7050E1022AF89C7165E45B32ED995A8C4B7FB28999E4CC2C79250DAB67119AC2C6B5B195526439E17A913F3BE3BE896E8023AE6A78AC00244B8EB2891CB5634955F908424C4B77BFDDA017D3B71909320CC53C4D4196E0C39701F8839711BCAE59BAB4B4908F5121B931777E17B331AFA5E955B5CD5840A734A41E35CC016C01407B02039B5064E97C24F4B9197091DE6AB22D0FC0459033EF7816D12596CCEDA120F534CE74571A4E668F5C1488C1503BC0354161BB651F673DA9019C9A83D9D97381E72CCBB1628F8F9A42039CFA07B1D67A1AC37407319360883539E7E060D32469CB9D87DE784439D2B453B77C158045F4BE5A96F090603963A18574FC027C0A0597D6A30B9235ACF5FD49619F47F7E8833D5D719B9F95825571B32C17B0B4AAE2DDB7EC0B14413E73EFA105EA308AAAAC76C2A257DD4A36407468802703787C4AF27D21EDD08108534AE994A1805AB5E6235B88AE7C6997374E50C1077F7702F809B092368F43A9CB2AB539FA104F5B23A4E69B9D46C4452208E3DCA58CC1045955784C82099EFB01ADB86CFEEFBA1EF3A43F16B7CDAE28A3E74C24B6648B8F20AB88088974B75BCC79E692C57501783F57434B7C2BCDE20B2E7129857EC9FC95452BACC9D96D89CB892C78CA07E790906A6FAB62CE170B63443CBC9BAD6F48B383050FB788270392F396C8CB8A73D4912115C41869D54AE1AE6173A34B6C3C91A5F6C39DA659268456E0B51389D7B05D4367C9F5C6CBD371E84EA9BEEB4C09DF9205296B9E947BD4E086A97760CCCDBA94A2108D02CC6544028E05A2FED297F32491042241EFC36A24F634DF3626A217ABA75882A050B7569318E8E00AE8A267EC0207CE9E8A524E1CE8F8CA117B0C77A680231F773B756152878363A9C38D93423C0378A60C8AAF8063BBD1484A3F37D055215A4403AB3C80DC9223D91165BC2D077C71A49093548D4A32922633258844193759D4DF26E1CE367C3229FECA492A9E7669ED4158CC08D9FF0C24027AE9759A517DACA6CD58090D5673C753101987B8914BD8B71C552D96DD093257A9313CBB757AE42860790AC70A593ED65A492078B6043B7B2AC4CC7D85A7145C6EE210C26D60906A5571AAC3EE71333155055381281A584A66C090252A3CA70D9AF09063F3DCC9BBF020715126122602AC9F9930D59669647CE64F356DA97A5C1740BB283781C2A10CB161BAB6B709CF9AC7C7911A23A9F4D6507537C497F3BA5CFE52AE9E34B1D9922669520DA2662BAA0282B33C5029145CC34B0FA9CCF201C6491E12646DB1D1548C0FBF6C7925C9670F4ABC84AB289958A26A9310ABA90CF8C41B39B7DC96673724CBF4BCC7754A71E3158B35214A8706652E11621635C5B6AEBAF64365497518D5D1B6635178E318569D23C50C3683CEEF593498037457C4494F03C7E92C055BABEB96C70EBBA20658787C1B27D6CBAB485741712F9169E3265E376A0241A36C0B2303F8865E6AA9D89213CA1F874E758A569E4055D70BB1B512C0845B933E470B1D9730B5024F520C8F2221B9D49836405525EC3864065BCA04A6AFDA11CC59A9BC28479D9D0B42B1B733E186D50B603CEDA34E8D283AB0939005B06815FD3531BAD6AA926F931C478F71A699A17741447FAAF6CF360D4C64098E9F1"""), + xeh("EF29D988D373C381541AC8723EB67C68CEDFB9DEC0FF2B40CDC763378B380C12") + ), + new EncapsulateTestCase( + xeh(""" +E2C18353FB0F024A0E05FC7F0F14B49A9A36CB49CE7EB963A2C20A5228B0B6ECA4AF63A1F7B1B8260B64D2F2C0718397F4F402A0946C9DE5B0F083B57903418C30BD7CC321574531B2163DDDF23A69B04B1D393C5916280DC11485FAC369D0AD1C85656D4A6A7BA480FA5ACC1788AC37C9706C26A357D7821D636078FC2204530C3D3358DA002F3136CF033443C519B6C505D00FE92B04A305A890267B238882EA9010554A1671862BE8097B67B8E8A37E8F0A5C96F94FBE296162AB1FA456785550AEE6B05A80554606B76714AA91C5E7B747A2005900077874CBD91970111C800C49CF05A4332570863929497AD6617D1B5614F2670390574F554C7D337417C792FF8953143638F60A7BF9517890D56D02039AD30392DEB045D8CC4994274E5CF83B702784637C6D53284F4F14C15335A86A642427E589AA454C6FB9707155BE23745FEAD04EC1CB07DA341F7FF1B6D17C315BC3282634A39C9104392B1D12222E8D091AAC69CD5A72276B01BE22FC3C634B41AB613DDC602EAAA00A72478D713C7A0F895880224CA8489E6860868A7B72CF876FDDB230C55C0523342C5F42B0A533A8FEB798D3104145E27D29CC96D54301D5B07274F700B9201555430D8EB961AA7C3307B0B56B479BCB6147D9035D786A58E7199F6BC9335918204A345826446A50801603EAC992E93FB104B834D7220B1494FAA2CB1A59650B00AAB00AA15F6909DFA969DED0B540648830360ED052661557280683084B93B746E27D916A05C96CB73964A4AE15CEBF4C84A1528506A69D2FC27A2A16CF270A09654A8B566651D097C61079A859171BDFD35262116479742DF74C0845D596FB83984F27811FF81CEEE0C37D618B93321A7DF0C0D22124CF521D92715EA7DBA1DD6112E9152CE2E15FED4769805A5857896EDAE13854648AC9DC26B770109372929FA511B573685D7951ACF21BDEBBC97D384D454B5625059A7EB8034FB4533F55B897B77930F3911F2808F54944CFB96BC0CC5AEDB8960A9C024984CDE756441C6381B3E38909DB3E85A36408C5414B471A68093B188134B3F54C751061093C4DEEF54891039AD71A74134806C7F102CDE67432D37DDDB4ABF33987A2AA47634C80260B5A246758102C864B2B40613C42425313855897FCC835C7C587B007C94760AF26A1531CEC874B9C492F4AA4C97567D6A61C21EB00FC52B1E0F24E9D680F8FE38B82243FD0B562C0DC86E2024593562B4AF4A682ACBE720813859B92A9C20DEEE4B4FFA1A1B17A24C394455077450B4C2CCE67A0E5C4016C746FF508A1DF89A5BE2A2A7B866ACA0A72A603843949909CD16DA542068604A380741C32E986366749CDD461A4362401CB8243613A2C442983B52C681A3CFC362FEDB337910668C5732906C41637778BFA619D502640545715F709C31B506534C0216790779EFC053B4A7789662B989A75C6580754A92588A30617E960C714171C8310A2802092261A85A5C882D407AE263A119B3E68E3BE158BB0325C30026BAB21D30B09637A54FA0A4B980DF807048F139223D33CCF206FC68672113A55E2084B6700B396F68873636DD8E5479BC0CA3E47B52329BD7F20681D5C2208AC0DE2123D50F6023A4472B0300CB3F8865BF7B49374AF01B002C4087BDAF4CAAE4336AA3A78E3856DC408B04E9AAAE77C464351C97938CAE829171BF724A8779C7FE20E5FC254D0BC283B773C2DFC83D28C3E854140A81267C2D2C67F361DFAF623D817B1655CA8A626A8A91BB088F539576C8795CC8A53044FF547B328377F4D17273AC323E6481CBFA058CCC456741057F1F668CAC51F34D666AEDCC176382037C674B4793104A4BF6B336E3D59A1C43958FD827493CB956C046025737B7FC0A3C2098BAB916E397191BEF5CC13F3BA0FD98F7A25BE0CCB113EE081B9AC808E2C728801C70CFBB2BD9A34469C064EA07952BA0D579380F7E782D0D5C6E1C26F3E17619CD47D4BA88C61600721BC2AB3C50F591988CCD77AFD3C43655272565401AD0778671939636C8BC24C794FB73EFFB99232503A0B50030A672CC8C2C0FDD5CD43B131DF0C9B9F867039E2A2B41B3CFB1A82C983AC54E002388692AD885C676AC2D7D0C5645B06A2684E9463AAAFEBC6C07709DC68078F7BCA36F5584579C3E3261D319A58392518ED507ED54ABFCA95CCDDB6C74949DCA48D01DBE3525A0BD91AC78428D5A930A5"""), + xeh("3D6441A62F1998E2B5B9B1E73A9A5022FD005778204977F66F7A5FCEAF17E30E") + ), + new EncapsulateTestCase( + xeh(""" +53EA0623859BC606082104996B5CC3FF292846658A17D60CEFF78B4EE37FD693876084A46A9A8337B61079705D2269BFE7486161E3370FC7492B92C666A889962B7450B15993C027051B8F0ABBAC66EB2024F6CBB63868D6389F39E580E05A357E5179367A48D5E00F03503C0E4C11EF5758B05C8B61AA51B3019C5CB017DEE224685035651703D0C5877414846C30A20DFC25B6E8AA76D98AC95534D1CA8A7E9177C57B2B46A0237B8B678BF889221C64C1882B7196AEFCB8056E0CAB1AFB0E50D467F09A9733960C4BDB5AEA3C9F0447B8A7198AF5D6A9DFA6785ADA30456B843F84CEDFC6761CE507B85A3715C3CC53409972D28E8F2A1E9EDC9DC3A368E2257A57373C967CCCF8002B5AC3C762E8C3B9B607C7451A9DD28F06472F3B4503C1A31A276727958210810716F53A8578FC76CFDAA35CB757BF069CC8429A9DB9C4F5B1602315882F11C83C260720A11FD6D01FB94171588539C5328E951B1E7F5605B4557F5A476430456A33572B60161A43A18A3780516D232F8B87B5E821081B109A39DAA7D74396B8213B37D314DE258B3FF0934FB27C276A913A337051E038EEE78542D78C8A04051A76A3BCA319BBDB99D3FA87FC9A03AADB8D0561B77C394D2F60A84B096D873BAAE7342378D8513E8B8B13DC6AC9E285966CB2E53521E4928465841ED7CA8F76B56BAC958E011C6CB751A4F7D788DC73CDE1F67A24EA9CAC41A0676C11B3D618386465C7557FB0BBB7A3441497764C9D898313A2ADF59983E0B2031BF7364EF0C25E347D2EF1111F29B8509085264C9D366970FE8CC19293AE8407602A21001391A51C609C7184C8FC0267E683C6FB83B0EE66B6EC1C930B1A5D60C108EDB646841415EDC5CCAE32CD8581BC48E58E8598285A4B31F805A56E395556B120B2DA591D3985B4D7C50ACB1D5DD12617343F9FBC9854250500C03725B010D45361C3DC745648CF337774AFE704EECAB4DEB9746104566C8CB0DC512A06E198CF04A8DF13AB6966AF12D552F3B6BA72A266625749D6AA30D1DC9DE8DC26870C317C9C26324A265787635E2CAC1922057916A425872C48E29C39AA4C06E24A462161C20ACFA6B458F56012B3A828300570F9EB92ABB3400691C8E76BBC1D3B36E6254E771130B555A68CA05A3A8112051CB10A2A3B0F547A11E53D803970E671B0E85C146BE1AB47F63AC46439F1C7AF41326DAAC72AB1274CC6D0AA3291C0C2843229B820E3C7B0B3B600EE72AF71671FA875CBA59782221781F3338F45B1466D60C31F6189F2D29C1F427D440B3560C11CEBBA7B0E298D2B270FB6D21DDEB30990271F15A3947B464802062851984AF1DCCC5A7083FE7C81A454A03AA9674D98CCDE10A76B3C696802347E519156F977CDA5923D73656A0081A26320C6CA7E1AD7A12362176D9A18AA75356E147FE3278C911070D2D61111B87FBBCCA67B991E5915196994034CC83246C024F27C1C62353E79290C26552DD52A57F19ACE5C006BF7774CD6C07BAED7696D61C51C8108C42237D8F4846BD4891AC44605D93F8EC03DE607456555365212C35D59B7FB267BE713CA43502BF3045CC2400C11A571C8468093F499C7E46D34C9A75602782BA606AE67A5D3C50D31CA5FD6E3B963FB7650DC5BB312BC35F67650E4B12B780D4B6680F640372A99C90433A7AA388AE8043DC5E9AB6105CC6FD91E61F35CBA99CA39E979256A1700AA9373AC14F282B71ECC419417984AC34677F0A83386B91028B4B7ACAC22C57908AA9F04F878E7B6420132A47AB5A1BF5A30116A6E59B6157E4228BFF499CEB59A09276B5D398B6A8677E725725D5C54809097833CA7E6136EC994AEFFE00C87F6845F20BF76C2A348E08C3895277AA082B84202229B7698924B4D5684E8C8AB81B34B87CA28D3E95FFF82B5DDA9BA9172076D937B6D02745DB7C1F77B3B3C795872CA728EC36029DA80353310D4A50CDDAB29E1381FC20AC97F48920A445F566C390206C6183666B2523B6A43BFC3E077CC0C422C1C91176C50B34C419AB4C97D640F1FB913B760685B64126725C7527A313A454D5F683B23828965067943E12BF633411B7B8C71F648E4FCCBD2A1262FD350A66CCAF2FB1D9CD66515C52E1BDB1478726426C84022F60A6DC61F7CA2B33A60957BC50B4E248DA86071FDF8080E7801F81199A9FB0C5888643D8192ABA9DA4D73869D884AA2A7E0727231D4FD"""), + xeh("637B7A1B57EB76C50417601EB71269E050008F415DF974C07BEF46CEFD08368E") + ), + new EncapsulateTestCase( + xeh(""" +51F74568AA5F4A54B2F4C9CFBC7666B7075A9D65A016416A49F16EC0CA716B75A3D80609FAAB06DFE69661706013A0C5FB7AB0340CC1BA72C2D7E1635B33B0EC3B29FEB369CEF671BFB907B3A2219B1554151A62B43638C635219F86B792B18527D8CFF00BB24853A5A6B81C9BB77790B25BA8A71A7CF7231A9007EB8B50F586139279CACCACCA4C7C64EDEAA194768D6A33BDFC42218EB279FD111E1C9633307AA30830B161D93F13973BDBB3772FA57309E36880816F97DB8E7E6411CC569A578A5C6F62AA33C2354CDC15D2065451E1ACC212ADBDE104F094378ED8882BFA416B1C55BBBC20C1E5AC89892B0CBA2B54516937E781F7A4A9B1802876598FF95832F6478ABEA33362A40EE28AA957E74540129D6FF3BCC0114A4AC8A40AD30BBDDA2BFD2BC5A6CB4DE5978F9AAB64CC8659A5765AB11AC3A654A247165253C81065359E070921188A312805417FA149D335ABE8404293329C73DA1E2E43CBF9B22B0D84339F792C9FC97006345FE6DB931AD71F897878B4318073B9A64400B5B4D0C4D6FB57E8B511743859D8E873B9C5052578282F9A6362172014089F2993BA7FCC2444FB185EF055D9D6A0EB564D5E4667E537AC9B49AD1241950140B188F4C88CD6A241BC42122A3DD7720E6E6B214D2721BDFB9358E7026F1A024132CBD0BB0EDFD83552F271B151099CE55D783C88B29A578B2943E3809A68D268DF746557435B5EE1597CCB58446403B98C88DF38399CE58BCDA1CD00462B9D933A83546526BB9E5C887050F5109090600CE84072DBAFAED20D137A7D129ACCDF1712C94098267148C0B1A301DC618D684152C817F27B3E8AF83F91951347C633C7921804D853A2E66C948143DF1B3C15B201EEA56E764273CF50AA58B45E71950FFD32C69B079564C48B08A43857E09FC33B8222A3852A055E3E4CA7B72B190E6C8B557AAB84D7BD138CA148330B75AB5FEAB8419A55938771053A5B09261CB0D4A42575E72F8F505D77F0896780CCF589376D5A651E4008CF600972008540A0896F80C17BFC78E16B64956677CBF864683735A279B966A4A906B1972AE4875BFC81EEFB75248B72E3A3768EB56D2DC3C04921011F4A92FDCC8EC9347353FA0055CAB83B7465D221B877A70B59715A6075799C19C8818595E6D478D659C7F9155A841B28EC751866CA3C2A829D43467E12563F5A4154947581D4B4ACD827B3315B44B3E31BEE0C04E9C03D1A186AAA7438EA9AA15FCA83D26B79A2093CC4505051B31F3D563832F397C8671516648AE92108A8E149392209A04816EFA1207CF854FA655538C161F6561274E5154D89A223665FC285B6D3A45A2F38278DA7B5055BAF8B1A052196C2547C3BACE09CFBA1299071635510ADDE3898C4C20E4F8034B454BFCD0CA262812D43C4A8660A5B2CA42E2FFA7AAB513DFCBC437077609596A45FE8BF330741A88A5FFD20AE19B58C3B19774A047F563AC6CF0A205A2A4C1D6641F93AB4C0F39E6BB51032F0A12B8A45E900954BB3A4379129E44918998A50454050607101BDE2975E66C0AE2436664B15850294FBC985B638C8303767DB7A10A8A74D5AEA0EE2B6105112525890C6D5A8CD1712A2913B73C386C450F7286F4A8ED7284AD9F36A22494E51D43950526B19766E388AAD84A39391399628F9C251D4C784AC2AD0424FC57BBEC391A549D59E5638A8056929203BB8F9A44A27117B28BA2670508680D55B82B4CA8E523BEF1AC4CFE83511B920309A735C62CDD5151338C50D104950C9273263E8250488135240A949958090F06BD46B5AAA3035CF9B7308C09952B66AB5999EC6E6BE7A027964249D63D1817F430737C96F54B391EB44640959277B56B495C49F482B829F97B94FF8B4F0E347A9B6BB83E9AC6617000694AF0C7AA13A273BE2981286ABC62444AA16FC043CE4B1B4F50437C9503F815772A8BFBF6B229D48B75D94BC02219E0F71BA020C37169B42CDC1A88081B7846C3636F3598630B314D809AAD1B7F3D335B41468C019C2C061240BE39325D34DDE9C24FD29CB3ED62F815C248F4B6E8D3908FA3B9C8AB1534AE49176652DB909059402128F18C0C9E52DED217C7CA864E378CB59711B0C764B96F13EC5E3766297C9B303806C685F4A861878CA8415D60B057814E554B04F49C3DF9AAC26A5CDCEC91B59F32BED063E299ACD431F8B781FBC1AB90AE6AD004FFA864E0E16AB57"""), + xeh("B5C84B4535CC622A5D6B93229BCE68789D3014D500D3263B6E0F54359D20ECE8") + ), + new EncapsulateTestCase( + xeh(""" +10971ED51709D256CAD9B57F0E48850C4B803642732C89A84439CD31C6B0F045915090168F8952B3382BF1186A56D2CBC102898F112FD91A2BE5AB0391A67C3C5255CEC88FACF3B6ABD427E3A410ED22C2C6C173F4894E9BF20CA3713CF0E8506846507BC762047715A7A37DA3A5730D8A1556560609E4CCB61298C4B2BEC374B534D0B266C427088816E843B118FA9CB27B9D1F549480F98F7F4B5AE71BA376B0B9180A157D8128D2286C4B5BC54F8590852B5CDDC5C11E6B4B36EC7CD6081D45A9C50272643CF0569A9A237581AD36D0705C004091F7C46D9073739226EFBCBAD5B551680C86E4290C3CA1AA756851A380ACFC033FBDAAC5B82C364DB075633A9A10B8137A05B29863AD1DA1CAEF5ACD2D75A9643B495EBBC184038B58B9A95998AA95B672A2D15CB78B0A00E386F433425C469A7677B8569CAC8F5A3A035C777B4570BAE1898FD379ABA62C960024E55645CA6625327457A37A92FBD68C76E79528D3B9E3E8917F93B5774B9A7DC44AE416006D8955895B6C611814C99432F683C67C09C354B97DA3CB0DB93841991B764C9A08EB26B9BFA96EBB39027D6399AD2688AC047360A7989BAC587FBA7DA76153360298A3D67FE73C983E4563F67207E1B835B7DC7CC9CC3372E12DB6EC759B86A684702D2B6CC805726DCB04AEFBDA224C02405635040EF60FD799A906116410A6C5EFD587BF1778CEDA4CB0152A272B89E43017B40C9B974600F03908EC397556E8AA7271828C049F895753E7BA96569A280CA15F5A82CC1F6121B6F7AEB214C726B1C64F7A958DB7459D4A30E4599A71FAB28D5196288A443D6C35C4AA27DF674EF6B4B72FC6485A31410457C182304538424A7501A7D62086910ABE0C54CC752B5E8E87039E64233EF5B837C3B50286172DE5C9CEB92C9A0BBDE4E7B14A0419DC6AA03F655592D25DF4A6191EDB8545351B2D89A7FA89826988657763A93EB71F8832B159E690B95C04DF37A2C9024451A18088A1C801B40A601AAAA6EB692E229817D8A390BB2474A95A7131C84D1745272A289C84BC2742CA1097A610D8A90F2C609651AAF5D0414C3C3FB3D37AD8CA382C9980A52539BFF73FCDE029FEAB0F184A7EDE4C7142478253C84EA5D7B6DB963ABC39A6B5BC29D43BAA24B4B26C7C53DE096E85E945310A484F591AAEAB48BEF98353C17EEB457E7D0719247A62EA85400B23491CB65932200F74EAAD3DF7184A54654C7B6DC931B574A2A55C7679F15C5944191A58D2A5B24674FD80452B22ABB7305501D9A156D0C48C656A35540FCBD43F14F531557BB9E8A3A710C000AF227FC6878AD28A708A34320191A236B38E64F3C4E705555DFC1FA3A144D8E6A122F7C5F557462579765A017AAF4A814E6B1201CC4E8D0757C378198A5798D3A59186A54FF158A451C42564B4659E0A35BE734600210A68F8A64E3951E849CB1062BCD6335970005B1B69C3A4845226A2C0834C1A467C6A799609CB870C7370C39265C0015BCE968419EC7C58464CB518550338B6807A97528FB34D1011A67F15B06C1BCD7B5909047136702C9AE604B927F28B8918CDC6F07A5D60B38BF7CFF2EAAE3C075D1579A30A76093B7A6DB44AB21A722F818861480129ED03B1FEFCC2607B5A1D5BA6ECB91B75B9810F991DC55823333A927AC13C3C297EBE02A27B949F47CC70A2266FDC76B5B55468A6B98D33955BAB3418F2D3C1D206C29EBB05E97811EC140307F9347255381AE152113C2ED2A7C1812A93FBC67ABFC1C1233B864AFC4B34B9CD30358990F51477911D6C68338A9857335B9152C5302F32BD5602A9ED97892F14951F111CA2B607DC46CFE6297D0A41BEE369CB3EB941FC2701104713A1784D6DE88948032AC78251328A8C58311848EA02008669B4BC811D6232A859756B306F24607DFD812DE89A0A6A00304FE795DD1C4A55366E615957855ABE11D97C7BE95A43A757948C5F4C046E9DF6A70674541B20010837307443444C27AD36C431F1F372EA659EB0693447FA5C40E8A38A7472D4A1BB0180433585B0CEF74650733CD90094199ABDFC1392E24C6D1C74408D00AE27F05D1729433A90AD9BD22F1B6C8155F68BAD1307811770A749A85F060E74625893462CCD946E2C1B79B6CB3CEF971899AB29F4328CE29313E4794C3463AEA46106D9CB82B5EC39D83D27C4CB3B69DAFA2E955D002E61C3E7BB247A76042FFEEE7E"""), + xeh("FCB46FB66E388182DF6149F60DBD0FCA88D1BB1A9866A2C97B84848531230B48") + ), + new EncapsulateTestCase( + xeh(""" +54B452960A93BBC12032E0507F7B83F112BA14CAC4A733700AF288D6DC0918C2B3D1625F475083E7967ED8A708B2B147D50658E1881DA6501D6AC6B7EF5AA4EAA5A7AB85844E3994E44A5431145A873834EB88A177400E95ABA99FCBA079914074209E06E17CED04636AB4ABD7824B98DB2A35215D5FEC091D5428B2928B809AA94C57694B2B65DE050817D6AD7326687E9A68695151F60A9B1502789AB8017760A6F3E7029B5074CBA929765B5C1DA8217C1105535699FC59195ED3A0E8799C66E3264F692C8DA198082860793446FD0536EA0301F5104AA689CC0263633F7A436621864099AF9C108D882043467B4888922D2254CFE8F937DCE040AC5B8641102959A90539F5177E21AF7AEBAEA2D9731AC87150A52068A71C183B8F4BE312A033719EA12E2CB8A197C1BA28B093E50437FF9779F0377BF5698557B9A45BBB7C8ED1AED0D982D71993F80CC5E7F16330D142BD0AC602F42DF89391156CCF1621AEAEB95701933A3CA82487E057FD186199BB5F4E2341D91A1D5B753B53E3719F65CBF0B3AE33153461459708B6B6E1131C9573C7B0CBCDF3A1C8ADA919D09C020FE6648221CE7AD35AB37C16010A3CAB1251B5930EC69C1728CA45E6639E97626A09469A6E204386E6A458D35E58ABCBE5C279BF79BA85021DEA6B6DE6E9A802198B969560F2C8C99328C5427207623C03E68181851401BDD615E2263761DAA3D0D16324FCAC9FF98E85ECA88FE668526501AF4C135F259277202E96D56F91C07D86692C91FC14187B99F1847EF11AB06CC019EA89AA88E114C034608C03A77280BC1B96307F81531009278193BBD1F5ADD812B278796309102CC2CAA9CF8C127472C4C63B47015CB852798379C73D0C4517E985ADC6F60E49053CB2B5BEDE0230A9E9A138C44178489EC5D5C2F069B737A143D6802454647C1B8C0837B43A89C879A0656CF087C733B7A1A7D153E092AAF193B6334A729B2B9F64D311090B29BDBBC5F1CA5E054461EEF72CAB14580B505BED3543ED15B02E33AD2A63B6EF980C407998AA5C357705B047D1848B4CB551845D3FE9A2BD491AD8E60308D880D6C56607F4AD24616845F092FCAC559CDCAA6FB16F2BB19475B700BC16C8FA8526055333EF389F6983C105E879FB4738166A1705BB625412B847553C462145A13175C60820783998150C40A2F673A3117FE1778A0A4A75F37BAC7D8A6C9690870D6874D2650182FC51C003698FD164BF5314FE3A4FA291BDD9EC3920F5A656000BA05A8F6CB020EE4701E8D8AB8BFC8DBA31887E65C7E403BFB036BCCF3C281ECABDAEC3984FB87D1C97C1F1112F8252C31A986941A50107D40EC6CC67E6E20F446C598832061BA21212E37943359B6B005621BB275235AAD581985168C468E15BF6C56C9AB65C7574B44FD83A32ABA5CA9831A6769135FA9916E3729361CF0D1142610C9A98363ED6642B853461C062C7D0B9B5F70694C8D4C2F073AE788A9CCA13446CD6BE40C82478E338C5DC34CCFB538451B6F94877A4B56B5AE6B3136B9BAFA1CCCC4902585907331C1F4811602716A5EAC209953B75A3B30EFD1B4E42F716B37A2F79E2C8ED062B1F79976C010EDFE4838929589A90B0A0ABB3E41CC8AA974C4C1308C4E12FE2D24162738A3811070D796701929C12E9A94FA96A823B6903498C4862732D48122D0265B0E571F0B4C43C62015F422753B2A562A80D68F19E2637581AD77592B67AC785B923AACD631A0B53D375E911797C0B76C79C53161015DFA7A67D1485C21A5B039A609F7386F8AC339B962472907D48F753314155C78A3DCF2010B1880C48196C0CD3B38B79BA9243CCB4AB5DF9D4569EC11F2F88525082B1C2224573C94FE3D24927B7AFF7E44B27755A0DA4C8053A7B8876AF4F809C22205B710B43C4D8B046CBB562B2BEED1C27CE736BDEA5317B658139509E4737C52A77186666947F7796D4261FAA8B9767814B7D096856A272BF6572B4998D2F6128D3FC6AA0FB2B66486A578B984C8835D1223D9E446AE6752D355A0FA09379F108ADD50683AD57AE731942C4F9C938464EB95C4D08264456F565E5981625FC75260496D05610CEBA5A751560059C38A8E2809609BAC2C853B819A781F61A7AF0C6FD728D9DB2C5623521D762440568272DD8831A4AA1B2F4CC8016BC53964CD7D3262D93710C56033B0F515A7B9E0AD3D6CBF0049DF4E55FD931257F"""), + xeh("4CED177C0A454052BCBD682B39BEA31D0D219A73184BC00C100964C25BD106D3") + ), + new EncapsulateTestCase( + xeh(""" +C701BA88063589288E73E4BE1AB28C6E3ABB70AAA03F656AE87B38A9EC947786A41D722EC63C0E9E8C1DDA078E28608D11E84219E35239D8030C212F34CC284EEC748D34C6CAB04A7F3C15A5DBA8C74C8666167CA4508EB47774A7C3BCD6589306FC6365D74018D2082DE1753A854EC6FA7813431D31C6A3FA711E03F042E6251E2E27787BEC65AA8CA47FEB5662599083E6944F442716342DF25AA551C36643EC3B9598184431405C8C8EB4AC8360E1789A06B2D13232E831C39A005881273B0086591760AE8A20913D942314F45BA5094AAAA05444469D12C20566B0C008CB2C5FB90257929DCB648E0D616001095309E00FE19235DD29B1EFC2A80E1402E851CD19D2BE9B4001ED214E418C156BB6BB85C0744C3B81AFEA59BBF055C8046386B576BDD009CB412D13B3918B19A658C690726BC93D4928F1B2A7C386320D41BE98C1AECFB75288B94511113B902489FFF157DEF97D762A5302B89AD18546F5C9262C06C98F62632681859D132F756A7008B76CD92C760BB12EB276BC5611B5A1F20A22982AB7616F8802136F54815D66BDF87859C7A79F29769AB4CA735181557AEB9D76468D8855302D4A5E9CC171DC6000C7363789C3A76E59905EF5686C31C765541131E62120399B16CAB27A4677C8E36150E728CE747D2C2B305CB780250CBB1282044B5443DB128695F4A6637102ED3469E3548592D3BE83FB30FDCAB034C1499F69ABDD174E82041FA4CB9B25773BAFCB071BAC2394B6B9E3D5446289A8E08339D91BC12E84ABEE2BA51A563E1DD154E075CC33409609835A8345C86EF96B31F28E3B42ACEAB464380413F475B00CA904E958CB260B186E3C5CFC6068914638AE831D8AA78BEE7B65B9233F8950783973C4971AB0C3BC9F7A7A5176083B4B9B1C045157738C460F77A6D9311A3591789DB0BDE85C3A863594DE182D789A7244E05FA05965A4294FDEB2AF843CAB9F273687E3487C4756B0D441303C9C8B6284733652F074B087288F6BB08AEFA990517C08E9E984A4029FA1C420FCB19FAA78B61C35B4DBA021889826108A1A95A6816DCAA08D535C77959C7EB20209307996592E94DA842A52C329E3625CECC6A8624EDDF7B77C2264933B7B263499AD0930F539C0F24A14A157A56AA469891403BEA0A3531CCFF5A217282652B027513C05D03FE142DD14BD85755507473AC91767C69CBDDDA71CAF8A12A611C0F7F50CEBE87BE9D88514611A9516A6433B8FCBA54527FA10532A808E57979E73C8EB444DB3404D4888370A419E1AB04760617AA0E66BB2E715FB17036D300D9F3480D691450BF0571F875EDFA668D68B16D426668A68BE91F1337AD15577375477045633984AEE80824A08C486F25443E61B47658D03A21A51B085C656664B8345C1149CF690A9B99543B9E98CD090CC4B57C5A1D7BDE6E256E2059B20752E44331486515083DA5A99697A47A342BCD9679C77C6A243896B05CDED231919D0448994ACEC094E082A7434C9A3F6B97F21056CD827AB2648613B3B95CA065E1B3CC3740BC7F4F156650A722FF26D70E5276F53267CCCA11513A719624A2F1BB99677B845A436C9AA3A2D1202F1094F9040813B26BA6DA05E904206DC33A665959228B62BD9391133AB21B79967AF31CA0C727B464A8737535973042831FB06A0B89CA65B6DF8F3983037957DC838CFE0C65D7791D3148A3FB59656472BFBBC8AFC7C6EBBCB6BD83B6760643425FA72FE343DEE61187A73C98B9000E2577990F9109A8B1DAF30BF384227D45BB8BD4CABFA4A9CB20B0B81152BB46281A68445F7F78AA56545B59C75E9852912870373B1CCBB14396EDC70C2C00896762A129B775B4B9168C97F9A259FC22219DDB0CAD614C4F06030140A1F335B033AA2A1753CA5E2A2ACBBA83A3CD65978686FDB8959B4F39CF41B98EFD2048241B69B27AFBD142FD5046AF69AA3EBF67ED1632C4683B88C6BB7B388B4A4D7178A8ABEDF1523A6816F10C40065056DC9393D21F76A48EB7C122331900406D960A4D46C9EF12429B8E4C45C4032F089458818C759584947F6415D1468A6436E764CC86E725A936000B242155CA0A9B884B69490CBD223C76FBA954319161748706CE5A31FB067C20663F443B885E4C5C1A421D589777AA4C13555432AF00B27571D8217B09AD4BC9732C8ED10BB8841315539DA5DD99F9A7FACC71557853FA10547CF7B89E98345"""), + xeh("F594FE1E810814496BC73A1523FA1E0FF207AD5F5F0FD4B232C25EB9F6EB5B1C") + ), + new EncapsulateTestCase( + xeh(""" +24155F435909068A815A6853C9F17BD928B0B7891B83F4447C2C5213760678D74FDA8C793C071002040EF4D81BCF676483B85D2AC796F964C9B4F8B7EF77656FA2976BFA65B9E6AFB7811903E114D3060A1A967A1465C512D2C1513863A548A787279E81674FFD45BCBD7C398D567F22D7291F50324D45C9A2FB26DE3A7A7CB875058979FCF4BF19A03A8A721F17E514773A83FA0A939393ADE55CC7176AC984CB43C7092DC2D0A55DEA11F3E41B879B5B52984BE72158B08BC0EDF25866563A56D4B98DF9528FFB28BF345C4D136EA84791DAE11ED324AB279C6C8983AF725818829CCE05770AC3837A2C92AE2B1812D143032C72A32C94C2A06882ECE2CB73C0C41EDA64B607BDBFD9258E03A013B9CB3BBC5C40FB10CE413B11897E81D32585240851E487877C4D5274C6CCD45CDE88978994CF463111A20BBA9905A6114899BDBAAB1053541BB3502D9779DCB48FC8E523FA260F8582B6B8F30232342848492DAB73197EC492407ACDB52844033C9ACBC79C366A4583D98585942B05281328659506D714FF856A9C2B5F370B5136F896BCB87A23331AD0A7610FB69515E84A0A302407FB9949ECCFD91550A8618049A48BA2F4096567A0D383BDEDC705645C4025E0B139C22E6A16023062901B8A2B6B515DC8E06A4D5514489229D926521942BE150B96F2486CB34B09D7E7237A440588C357CE061DFDE1362DF1C2E58C1E1D72235E922B61EB2163D906B5E051BC58497C7CAAF5363724985D0FB3BAE964A86AB36EC46AA3D7AA290B428744623A3DF900DE975E3AFCCCA539837BD897F12CC555D684E34BBB3CD7041FCB2004A687B5E6A3E801CFE9C8C2815C2AC4783042A23736137447337D9221116A62C0E1D8C191B53E22C92A71A15D9D22505FA5BE17221A7236392C0348562216BCB037D4880A6D1236D3626E1B354142B5C897C646BD62CE000C27C53991A1C69176D03A16A61FCA51067C596CF01B89933A258B43C22F489AC70C1D8658B2C0FB2D3A6924A704302F33C25BDB556E97780747CF652C80E87B23479AB2C8119DFCEC47265A4F7D524E50294C826AC4C7B39C3C0782763A1A6ABABB9E14903720A9380939FDC9A99C6766C9D8B2828881BAFA555A35022A23A6F57CCA446319E71780AFB3767E9311D5C990F1E4ABDFF51A0E7238AA98AC412C05356583B05C170BF793CE770F79F81E99F78FD46310EEE27F614226F42367319C81C98A1FE2B2C09F886ED827610C8621B079A5A51863BB69ABC01C4A75051B50D83D1AF85B89F6918313AE5AB0999035088813102BEA06CBCB14656928DCD53A30255B4931017BBC4682CBA54378CB7E118A275728B83A4BD2586D271A8F64C06562248CCAD9A1FFB8265512712D0B707424B015157788318C7086BD964490A11A35FA43BED6ECC533E07D2A6ACC806990072A7DC0322573D6B88E29A7B47CC42508C7CCE64AD436AAE0160309E6922B655FD3B96FEC22CFC7349A746A0012D60A88C17D7934246EA0290369B3F7783FB177534F300BBED06EDCA87786D5175B93239B115254D676C921C1E5C3BA42737AD51B4BA30B1E65A8B59EB6A45C34950E9AABB7E5CD2F556485036BEF93CEAFBA97E83408D61C6FEEB908873B7FCBE93D7E386F2563CB4A80A671A1155762A02968622CE9163284777A3B4AF4B8858392BDEB9446BF59CEDEB689C609859C9B47561A8B39A19F7B36896DE82AF89BC41CE6C54791A78D6258534AB7090C502CE0A6F70CB3DB442A9DCA58E766A2E72286B42BB431B4740B125C73D43F49C1994761A57E3291CE95A2F4B88B3DA31CA994685A75B71CC622B3C2BEF60C222696C031789EFA1A3DBDA576EC1B802C261D1F44A5E4B973AB73946E41159D622BD8A0833396517DD2C51904AB67F05BF5FCBF9B47BF05A18DA600C1AA411B60901096838A5CBB8EA236A0D4C7109BF65EF8E6B2507651F2FAA61ACA225744A1B56354CB945065D6ACFD3697B8D331C0929A59AAA06570B0FD3B02135006DD198A92D4037301BEC0B328725533FC385B2E03033ABC4E1CD4975E438B19D902C3E3435019A42F664C063A5A5E31932ABAC10420A10A89B54582138CE812A473945952460F541B9CE51C9A23C5CC6BA0896249F097218210A329956057E6BE66DB1BD139A791FCB95B3603F12BC19E2876617520522AE31D827CAE8422FAE85C30AF33DBAA77967001910F"""), + xeh("ACDF91D5B4F2047AB9C7A8C2F4809FF69B9D480334C501E6BC66D535D309B100") + ), + new EncapsulateTestCase( + xeh(""" +FE456F478002570478BED88055B4567135B19DB8CF52A56E41824984A8BEDB64467D7A0A45654153C8645C5054C0E35C2C75877633BA83AB25857CBE5EA998FC6C79D983B5B1A984FCBB14CBEB483587BC5D952A4BF422344A70C4BB8E9162CB31D2411637526514920CBBACA6A911FB80662096B85194B308B881189813D171CDF6463893CC58EC512DDBFA31920CB1F33AC72C15BE64A3BBD114B27185455DBCCE9BC67AFDF6C8A393CD8A427A73E052FAC64AC22B5DAA7481E7D017B8E14BD84690D9054BCF2557E942BC7248AFAE57911FC64732C450EC3C1CCA599B96DB685EB704764CA7EED07F9BAC7103F38356F86FB9639665C35A576B8627CA6DF0F138FD198405B6371AB1BBB7EC4175F739B408B281D28BCA369AC0F1971A374A97E9097FEC3A5ADA6C2C7714B5CA0958E4848C9CCCB5172F1A6B7F2BDBB37EA346D1C9AC0C31A5822218F9D3544DB6464E605029073DF5F030939C8B7CF84A714904DDF56E63F04B2240376820417FF320BED27D8C385841C54222097742E23B972A6B7491524B88538A07988FFB9861D0B693CC80BDF6BE9B645193C06EF8132813E715A2D72C55140A1A9C54163B2780414A5996489326CF52112640B08166FB9F9461BA19661F1F47B8270396A0A6C8218B636E8496CDAB3639338D50D0919BB7610AD1BF9FF76D7D0B1F0E241E61A6377CD83D430118DC222452426A9259709D91BB46444793741AEC8998F876553B7770E9CC1E3FC749DF81AA4461BF5E6CC1622980968878ABF113CA67B7646A0463604D90353C635C2F2E330F71949E2E21806091319B328731B298E99127777808153652C9C763AB386ED7F6CFEFF10034090D134A642A218D277B6B00511F35A25BB3DA1F299C22B4A3889D10B3754C52D3F1B1373840A973793EC4A5DBE76D2C29626F1BB469722BBB99B003ECAA85545CBC313AEFFA6006F0AB7A857AEA991F9BDBB92E3B75DC300D1C656B2324CCE8DA2FD95C9F510676A8D6AAE77535BE3A9ADF8B1C974293FCCA05DDB31AE1CC81768CA90D00A4A7F8191C127F6B8CA010B46F3C05A808D9911A626B80365E6AE6BCB428BF3EC8710557485DDAC34583B43BF55D257089EC997F857B94752B8BFE7942689A5397F71944343088D6A9A2BA4936B2AAB663857B87278C3293491A75C861987C187655F13FC2A28749E3891E8C236B1B675E250639E5461BFC94F6B7CAB6D8077E4CB8719420DFD4951F76CC6288229EF49C8B8821C3D497CD860C58A619C9294689B5029F5B2D0BC95C370A8C7FA3C521A695C829A9A1F8012D479E38DB4CFE650550664CC9E0B631E2682AABC81A601A62EA16548584A571CE417508AABC4F1970407ACC47B449890598621EA7623530409EC49AEEDA8AED0336DE4BC4D4F9163A3C82C12A2C5D86B24FE56235CCCD26F5AE517367523AC739C6B69E977E3FF2A854F8040DC4B97FB3A29967005D373E0D91166A679A517822F7AA59BD4B00185AA25E0929091ACEA1FA4ED7F7BF7E463005D59403010539465D5D918C1CE22C55A50C749C6B02A360345A0A0790970717986AE9A020564D82DC851AE815D5FC76FDEC1411D01C56166773D7067FB29CF842BA9E8136F755631ECA53D49B7B2B296D65E63D29F96931C02E2AC013C016BB05EA6817F19E1286C3C2B9A803276FB58A916C838E923932895C9961BB3A4BA6ABD52880B86B391035764C4B953684AD13C5918ADA13AFBC42D4B6B1D523B39C380AB8390E6984179A5863AD488897258CBEF615D53281AF99239D4A59AEE6ABD6EA9F72B88E34D544F25A18FB9A45B0BA7906367ADBFBBE3BC467EE7BA3520360DF56040E730C2ADB162F78BA49EA4E2D1969839BA16B2AC991CA439D337CED7153A6E80877B73F6A16A22FE196F5F833ED7C0133505EF9E323C00355D2405B8CA01FAB6B780385121DAB8544C2C609C708193B969701728BE36F5F972C0C402D2E230370175971A601C0560A22789262E539AFB55B4EDA9F8DAC1C63FB77B91B2E77F17D98C0297FB17919CB23E4D45BA538523047A17690C245E009B031469F6CCB30980649A14211997A823C092C98452517A2BFBCBAA0B43478AC399FA9B58FB96687CBBEF715AC3855C493665735192A718965D3825325F151D3A325318A667492B7F6324FB28DE4A16F77BBA3884809A3445D53289ABBBA26997E95B89029457749E9B70D"""), + xeh("696EF6079C573B67BA3531CC69730216A3A8136EB6F647481382A5CD93C6B7AF") + ), + new EncapsulateTestCase( + xeh(""" +FD1B79ACFC0D6D79464A3A59A5E18DA6D54C7E272B77703A22610C75FAC3675B89E350047C80C6F5B6023A455C88A44B0327BBB6F40E1D502861F77E7F2732742C88DCFBB539464E3189A5B21ACA30474E3758AA8BD2259987B8390698FD52378DD505D964350AA30B26AA925D83B6C3CB069113A2A3133FC2C19714A042C3056C774805262595CD2504FDE7A82D19878AE208E8173D9A855D39173D027B05CBAC4DE7408A4C0A4427109D60571D98D1738FA09B1D80BE859B34F3268F31A6CC472846C6E5C50F2A3E22CC8E81C78DA627CB2F474CE1EA0B6C02C7F9135129056D05F62D9B36BA466B9806F4ACF09302B135906AF7BFB43020A68444D22168388C8944BA60E7E803458B10D3B061F0652E08607CC2214CFCD2BC0B1B2148BA14691635C40492A4464230F7B6C9AC0366D813249B37FF57AD8533C752C0CE2B765D0319B84F204B9960B8C553721E5C1B93178621D4A16B8C5D2BEC6A91018F80861BC92CB44B25AC1B8C937793892A989D8FF465623666B1E467340984F45A1A591453D894C0E27876F851C664E19C3DBB3F62D7C7B9AC5C4D201FD3C0B3F7597D56A34CABC65F5E62898B0358A803B8A8651E8526C010184EDC0A1008F047E082BC63F0236FB93A9E70750255A28065A32B582CBADB3178F4B146A47893C62AF7CC63DF404715182013F13A11249CE5513D242A2E8B33C4B1B730B59A1B121181BB39449CC021C97C7B6F187966522C4DABA78BF231B945806B590C5638B1767280C29A070C0619A74A6D3D65C704DA99018418266A2AB1D2861B80700F67C6C845744A51220C4743E2A6639F188C95871B44D586F05A1EDEEAB382D123FF731042C29D50096155EB59906A7BDD2881D94081BC330CC3A71D3C1391485109CBD8026744AB57632D0EB35087B11EBDDC24222B4ECB435586C7226B11644AB9A243291CAC62CF3EF90B7991014CB7906D9B455A023FC94C7DC935221C4B2A58398F803801BD2A1BD5B40C17B529FABBC5F3219419DCC911E70FA0397AB407BD73258002594EEBECB45218154196A07A53AEA0ECC56F25AC5184CC39DAB2399B555851B933B45971C85CD3299819A27F756848C33C4E67B6449796B99A914AC8083719D752F06580D328087510AF7A5122F95A02A30190CE72482BF04FA37306A28836AB7A6AB11A2A311C1D9591630FD827431A54C2C738C5AC9CFC67BAC2480763E2CAA1C81E52C9455E305438BAC378D8A4A05168D72C39FEA242DBC794BD11B504E4630487142AE867903C4872F0B9A8F1572403A51940CCEF99618958A71569A8E32992F881B6084354548046F1E4186E11707CA72103DC7292A7858EC77D24BA225819B9574470C467033E35C3FC8A8CF955CD82565576EA576F5C43E0682C50D0260A30043CD40010B2B70C60A86F242EF193C4D3B837F33771DCA999253278D2CA2B9B88473DFC7565F282EED3739967345F90AB34A902F393A2389A557C815591665D63652F43C321ABF0712A012DFA6C04EF86A67F95A16B784E3BA18CB13215EA09CC2B5238F9391BB6A5C6DDA2C6F670A1E58329A8544C1E2C3E5D2A478057A5E46A26982911CC599D83A5A18D918FAECC86217A165C052344A38ECD885AA0E4CBC7D4742C99B1700578D454ABD5C83F587CA48A3A219D72B55F1934BAF1249ED25110177B6B126E0E1379111BCAFFF719D65B5570681164A80AE5E71D677586625020F605103513A0CC94A6632220A5687D89EC887956CC3F6575DF735C738222FF7AC70D468860420D0E53C192FBB31C8B834FD10EBB4B38C1517BC6E60BCC7A5831741DE067274B637060D4CFB3A82624B4207D94355EA3BB562AA9C5B9C04E2182C45955A06C5C7DEC5AD78BC9FAC6A87637BCB14AAC3CA76D5695196937CA34A36F183C599645CD67F33E060C6BB784227C735773534B4D501D25584C0F412A1A697C041C59EB85472ECC1B780C509E3417C9890722E57003A1B5AEEB11A764A6248C724F8770400747F04675C2F54BB1A983C59573EB8C64B39A3F552B79F5D365FC461A0414CA2BCA1DAC961C2E3A0A72109D79E26A59C1B659C4A45E9C8C2882CF6E26B67764244E3BC739349EFA0B9DB47B2152634240CB7A44A0A2B9CC70D557B6849A9976118DD8E74CB7896915368BFD120E31C4A261683DE548D0D6BF829F1E94FCF9E53757DC7EC8255975E848CD84360CBEF3FD"""), + xeh("B2180DB6D5A468155A4C45C90495F8875538F05B8B8587644B4A668CC8936447") + ), + new EncapsulateTestCase( + xeh(""" +5AE08BEC33AF8C2967C72B389BF868211B80B3F3621279CB84739860479BE408929695B043BBC623B13B7313494111C07EACCBAEDA248DF4BFD4E480526958FB9811FF98CCC755231045C744D29A6A3103012A3C61613C3305C0A424C8F483362B5150A045888AB09E39F08FCC81B79005C1B3B0BA5FAC23BF438048C675122ACE4CA672D4D6540F9064AA9766937017B147CB05111C0706A5B549498899423B1000A27B648F0BAB03307F8E492D582723BB20B044E91CE259C611F71B7BB57E90D4A249D02A7892B4589A63EB591CC559A3477766776505689820601B9CBD75AFC344C43FD9C9FF55AA4C791DC0188B17177032796E07368CEA357874882F32948EE0B63D589C808F833AD2566E22FB02C77AA78767B194731EBF5728F1A858C6C85102B70C56B96D32428364EA7A904A7EC4F2517AFB2AAC817AED1A53D701CF16168AC2E45730D57F93C12B9CDB38D602025B1C53E4A1CEB4EBBDC9403DAAA368BBDC9BD9858BB0B53945948CC3DBBD7B2B41A97B847447402C5624D30CA0738912BA19780BC5C81A7B9E26C3C2E155CF5C1A58D26413988267738B848F20681B823E9828BE7A6A8799A1360C2298F448BFCB5C422ADB3D6CE32D8FFC1A2E52244DB9C994416F15C3B5433319C04559E3C3B895B1B322232A69029AFEF53500AC5C87A4606F5268BFAA26FD99B45C456D96E1B248BC8D2D79CBC9435D3A8B962E91A81FC76B1670ADFD12B3FF044078A72BC36C8A435B966DBA5C0CC97B71635206CCCCE2972B80C818DC43325830A02C6482CB5B2079B5AB6AC50C24E95D16C8259945AAE9D45CC66B1F125B70915C5F222670E54A5B8CCBA4F973BFCBD763BF2BCACFF5AD51A9255481925C893C630B38678A355EF40A39F56570D961846A2E6CD827CC1BA4B3813B6B956CF4AA26D7E9CCE1721E04B9A5B8D4910CDC484134730B639B57B39CB5F69663EC7490B339C61B4EE4AA83393ABEBC60868B945CFDE98933296793F74466320615F03DC4222F69461DBEA4458E2B6E1573CFF4F610F78C3AB609036641007EE369BBE382ECDC888EF97C1E1812B87964EC19B04DF5194B4049DFD2A87B63034F7A02C3BB731CB67F7282B8DCB131146570AFB993661B059797799CEB7D081CA13421BE41B32ADE2404B0519A00B88A0E088E29F846F5B738113B31C680BB96AA736CEC1138CC5F5D9C67CBAC9B29E1C1226812E1BAA39F151BDFF15037E30E1D3B9CF86423131A4FBAD95FA0585015485B5DB755E0F45D129841EB7614D6C7AFF6194061DB727B299A30238E8B716C72400828B377D46B3F2AE9119EF72AB410C97CD4B31EF77A610242D3ACB17CC2B335C5B2DCB3759A4255921096087CA0ED428AE6703CB15A9D9D8A5E0D64B85534AEB4F2076130848CB450EE55954AE61F40CC25932851A2D80FA3601C74906F1A5360A69120A5FCB4793326F0C8222969A40FC16D46F1CDB318BA511C72AB516A4F31CE67204938E68EB4F16202F42D9E095F1714BF2719C7E571498CE304DA997FEF45549B5BB9F3834209096ABB39C686E4B2C9C796BA69B368417A45970178E9801221944EAB90656B623B53903554AF1F0C7644D79B2BC186C0EA5C791795F99A0B9C29346CF9639EA892935878E6F2AAB73CCEC7201D38A26305A286BB1970BCE86033A14D3677AFEFC81757A69C07299164790473055F10A8279357BBEB31C173B87B62293BF963C453988B390B3697A3CDE4EBBA5CF1B08F78CAC7498DFBB6407D6220C376A4799AA3A8871D0270870B9495499C88C98A5762F7CCB6FB0CA10046F06C06864345CF4C5B40B11181A973E473ABB9786FF307C65CB7048FEA4885041E65E0013422BCCFB65BE8CC9CFBB4448A645FD3F81779AAB29ACA1648708F249C8B3F9CBF55C736F5746854D89A923C1CFFA781D26C241616CD01D7B372F568B50BCA58D88D01FCBB23931DE6DA2D688A6751158971A5B19C6B46C3B761D8385238F8B9831266B09B16B5559B5EB82F64B7133AD36C5497C9BBA4AC9DCC094C3673691207D3587C97197F5CF7C1DDAB6A9F1383211639F3C57BFFF3B01709974C79C9C51B2E29E91770911A52281F030531239CB049BBCD841B1D764C49E0E8492AD383A093925AA818FC0CCEA049271F307C51F3C97A7AB5A81B43B52A6BCE2CEDB2D0E706D280DDE4A0991FCAF55CD36AC05F3593F3C797A9DCFD0FD0E0"""), + xeh("ACA147DD83685FDC5BE522178384DDB0C8714D0F818A5A20CD1AAA71730D8E36") + ), + new EncapsulateTestCase( + xeh(""" +9EBAA37C34B6F0C92BC7E98A0C56689C989E33E9126DAA3D94C95C6D60639DDCC008E4220F8C6348E44738C1AC50521A926B9BCD42511A33C1A704871C11A962E062B9625169A842F8D15CF3F3A0A2411017860C88A22D01262666F6895390AF652204ED9CB0F7589A63C23ECA851C25B527D242AC8D310B3199AF5EF7C54472739E17A6986ACAEE76B0B262C5BFB051343580E60150250865397B4C498B465B6C62E1C3A4B89B756871313AC1C4034509803C59103AA4B9A50CFC7C7EE0A34EAA417009538570C197D04C60CFB41578E274AF9ABED10B4BB7B71A4B925DDCF5432940934B222A36BC80E96C1094E5C264364660012514444ADE22A6121C30C4F037FAD29C2819350700A10C9861FEA471BD05C3D31A2EEA2A9CEFABCCF0B4AB9C33C19FF126B017370073561857084A83ABFA5B3550C2A93B785A4223AC57F4B6FCA0B4D12422B509CA45B63775FBCA4E785972E775E2989D844A4308B786F230CE990010541868C2C21B3D311E6AB14C4D417B37D10DEEBBA6309686896017F08C224DC806AE87658A0B00ECABC2A9F66029873C6C3446914C5A967441BB4AC6900575FA52238636707C69097E19C30ED66A9F28762056585C5738A6F51ADE3603B963476213B78EF65AB6CA7F612134E82A6BECF48D4DB4AD7958787A377483F0A8BAA76B06243DA4F61CF803807C17837A6293D144637BD3A92039282DA86485B005767519C9C0A0B513CA5325866DB3AA67638A2C0117FC80C4845ABADCA92C529C539431363A9A58E6A25CE6A42AB8E5CAD3865AC1B69E77B2B48DD5CFEDABAC79257D15269D72B1CE90265556DA687D894D15F11B1268692E22AD8313877FA8629F3BA224F8C5A98AA31FA58FDD05101C3705496516970B200F984B67EB497DB9AACBD6922EC84C73DB42EC0BA4D1D11859DC356765C82947B4953ACFAECB5969D34A4A8A44BA53346023517C2474A301AE7177A0253904186A5527772CD7845A4129A90B292051765772C09EF585A5BBC976F1F9B24C7AA4478B04B47398491785D9B9B9376B89D6C90320831117949A72406BE6076B4268A356E615A2168C9EEA37B2165B143304B9C51B3CC97AE3A6B0DDB185825C8B7AB073B5086B7D215D4C953F7BC9863339A045DBA784F5489FA51096234DD08B7C457B1C326B8F73672881562310E90B43FA7A37B7550696422A1B32A2615D4E8C5B3C3C61C4479A15D94F210A165311BB4C95060FB8287BC526C212B1EE0470C5497480DA396B2C39B9BB413E267583C249911029DF9B7822327764C16FA67307EFA499F0A7CADCE8B1732C91D284B505D59A444B41ED738C09A40F335C7F7050B80DAC9E5609C000473E440840D1799A86705276761E8CAC3474C1836AA9C6B4D732118AC515EC2A4DFCACB7929776501EF02415A0638819582F6AA2853DD189CF7900F834671718221933C2962B3FE598BC2EB0245C229B2ECA5B1A1A2F94BC6E278875570BCB92C043493267F7DB06C887BD66E38CDEECBCD0A998FFC094376119E4A961020C8BA05B15FE06062FD4892DC0C023AC6B2806BF863ACD85A120A0701435305A65E91D5D908B0BDBBCCBD518BC9481A5920BB4900468A893589128845BC95294A0DC5918274C4FDE2A0B18467699D637AF4CB62DBA3735E33DFE25AE1493501A590DFD0342506B748EFA5590BB689D18A50B2151C9E9B559B346E8E530A14A1CBE5AA2843431CA32AEDEEC4E9081B50A3BA764B1B0EDCC99B17B3FCB3046E6C2C1B1966F2F481E4E1CBFA4E7546E0A9E6ADB649D59151209942B92B019E8394416C19004CEF1E9235BE0228E6B2CE3603A37966BBF51CA366A3F2D18B931E4B3A827887FB3147331A746E713F60040F3277CEBC2BDB7251E84EBA5012A10CCE965E4A9963151698AF1492CF51372C37AD0D78F817B466A26372F3213873802EE26558C9ACD0F511B3F9138EDCA56FCCB36392ACE11411EB2936CCE03A0F2F347E2332E14E85B8652984D09CCEFEB8963E2A5EF845888576EE1B36EF362274D292F10355163BCBD51A7AD7B284BC4A10C3370A1391003289016F22310FD3C4CFB31CF88A42685103F3813393C1A12915981C11A616FBB8DD6905712F387D279C24B17230D32B018E14902CA1BB0561CCB73A0E2F4C8DAD9969745A1D238250B76FAA9FE97E3E08E3BCBB6E860DC8EC5EF30B92C5648EDF353871C148883FC"""), + xeh("B974689F6F36C7AB262C8B97D5469ACD3BCAA3A3454F611FF0B304FE1DF6C66E") + ), + new EncapsulateTestCase( + xeh(""" +A6902B0559182B341E3A6ABE0B646DCC84B39881948CA396CA782A65D6221589333E98A88A9C320D83A10422948B64A0DA1C4ED165B0144B22190656F1DAAE36A5641A4863A3985AE9D08456629C153A596289C01BD2912FC3603EF7ADD1EBAE1A745675F316ED0A6D4CB5C5A431C2871B939B5648D1018911D752BF08B40CC571D863B33C9043E3B2C73C67CB9A4C8087F28D7D37B9B66B638CC66796C146135C2A743AB94FC693473089E6D32492842D8D114C9A92C6721818CD0530C91A09FD7C3A124B7E98DB056C77049008A112AB61D03A8C38738B96F64D4E530E5345958EA38F19517B7293B6D2DA11BAD668988820CE8479C3B5A832C708FE09481CAA7ABDAC2E8658544067810AA31D88A52F66459B3E0A5AA8EBCBA1B5C9B8776FAAF59CFCAC69A1CC8EF166615998AE88968FABC67D67C7675B94CEF447667FF53D2B3890943303BC88C5B3DB08BA75187B6CBC97503E9A563745824A533C59A71B66D5CC21972B843BE0C0768970571796AB992B39F43F2CD8017B5517A91235474A821C541B526B0404212C194238B18AA5B8A175E4A59417D119EF8A385B7458980335842BB318214E55794C635692736B6708863A066462EEF41ED66771EAC578E029642954111C0B20F9BA3B8646456DA39873B89F6449324CBAB5ED017CC1C72E1ED4322D55B2030A8E0B390E54384449096A2DE676BEA01F03A458160341B7C743719B89A158120B790AE8E1AB4468467C4507F7CB659EB8C16A77315E553AB287836C4472EA1075C7A1C84DB4CABDD5CEB2CB5638D75FE3567659443B38B2B21C422DF97A14A8A633C2279DDB056302AB0FA83905C846AB57D2120EA1CC92195320B5B873B406CB44B73FB02160200460431581979967FC16233333A8EB7D48A120F451B3FAE9BAF6318E384B6D42B36D5B38188D849652935494C4BBBDFA22A562A27BFAB60B3455E775912D27698AA30F76CC291107629E3627EB443D0F00AA3F220877010876B485F57495C9E80DC4F3AFD6118E1849ABA06919968163CC9CB358DA03B3550198A2C43F476954F1557058C05EF828D8EB982340C9BC6A5AC1A27977402B2242A40D89072C1270DD8772008A505D4604831C1924B97C980B01788107472800EFD807FAFA1ED3466548D698CAB76B820667D630C7D03447820BB8815BBCB8DCC11752788782CA3BFC51DB9BA0D16198132A0ACDA7BD7A6531A8AAB9C8AC2770030C512740CE62CB60F79F8087CC9177B56E6A4B8155B854993E2BCB78AA849E72398590B24E87A31097AA54ACA80A9CEB29BBC5B24CBB7DA084B76B5C522F73185A05A8024629F8A6AE304CC7FE88258C94A396912A16B491DD0843D8A82BBA86843F458E91261588D7AFE89A1D7EA9786DD13C4111CF89EAB9118A7EA39A72408C8F1EA2C77765C12881192A33C552D61A76424783E5C48C881E9A541B8F6157EC138AD5E93AA925194FA37644F397A98C60DBE786983C8B2CB6C76C73CCD0371CF0CA85998C65D1F76DD5E545991A00567A48EE69A537921379923D7676401A06A81D68BD9FC4C2A28B4B72C966576BC6DA870BE8C415F94174F8137B3EE4793786652EAC97D6C91DBA4749CE4B69DB82209B24C5FAA0C4A0CAA71A39BA51E7A6F19381219900E6F8AF06F0B224326EFC2C8560A95AF8296D2B87353360A5AD3B6DCDD95377B0B201EA7A6E475D5D563A373554E83982A35503E1C179324276F6147B698C32AD24AAEFE0B2B1FA911444808C6A25CBA21B4BB008F49C0CA8D209E2BA02E3B164DA41793C212F9C5B2E0EB00CE7146284C0B26FF940268318EB330C6F0100ADD43FBF0615D2EBC27B0819CDEB6A327C590DC83D678AA4BA910E509B4EBCDCBF3B74CA581A2B55F46154D17F9AEB3A09D5C30356A75AA2859BC11DFE866E3C463C96826613880470A1CE8276B033C1810BD645B5278C25F81B678228F4D20FA3726C5715311DA4BE1F1C0752DB6D16D889D27313C4046E05FC161E889DFDE2255F434C8008AB12167F3B6A15D74B4791B293C902CCC6F4C98A75344864C35E6B189C8C116735C7636A6F0AF653DB17CBE0E3CA7C677CF9604CFADA8031611321DBC90308BCF7F93AFE1B02B0C9826A4139C4B2097CD061BCCCC5B3C562BB13A30CDBB318CB9457C1B9A69236B820AC0717EB65554D8CBB46EC883E0392B79C92DB8D07FCD393633C020FE2C469A32D"""), + xeh("7B93EBA796CAD98FDBCEAF0B8F3BFF196C1F89125B2AA88F623A91DC6AEE3771") + ) + }; + + static DecapsulateTestCase[] decap512TestCases = new DecapsulateTestCase[] { + new DecapsulateTestCase( + xeh(""" +69F9CBFD1237BA161CF6E6C18F488FC6E39AB4A5C9E6C22EA4E3AD8F267A9C442010D32E61F83E6BFA5C58706145376DBB849528F68007C822B33A95B84904DCD2708D0340C8B808BCD3AAD0E48B85849583A1B4E5945DD9514A7F6461E057B7ECF61957E97CF62815F9C32294B326E1A1C4E360B9498BA80F8CA91532B171D0AEFC4849FA53BC617932E208A677C6044A6600B8D8B83F26A747B18CFB78BEAFC551AD52B7CA6CB88F3B5D9CE2AF6C67956C478CEF491F59E0191B3BBE929B94B666C176138B00F49724341EE2E164B94C053C185A51F93E00F36861613A7FD72FEBD23A8B96A260234239C9628F995DC13807B43A69468167CB1A8F9DD07EE3B33238F63096EBC49D5051C4B65963D74A4766C226F0B94F1862C2124C8C749748C0BC4DC14CB34906B81C5524FB8100798542DC6CC2AA0A708575EABCC11F96A9E61C017A96A7CE93C42091737113AE783C0AE8755E594111EDFABFD86C3212C612A7B62AFD3C7A5C78B2F07344B789C2B2DBB5F4448BE97BBA4233C0039C0FE84300F9B03AC99497E6D46B6E95308FF84790F612CF186EC16811E80C179316A63B25703F60B842B61907E62894E736647B3C09DA6FEC5932782B36E0635085A3949E694D7E17CBA3D9064330438C071B5836A770C55F6213CC1425845DE5A334D75D3E5058C7809FDA4BCD78191DA9797325E6236C2650FC604EE43A83CEB34980084403A33259857907799A9D2A713A633B5C904727F61E42520991D655705CB6BC1B74AF60713EF8712F14086869BE8EB297D228B325A0609FD615EAB7081540A61A82ABF43B7DF98A595BE11F416B41E1EB75BB57977C25C64E97437D88CA5FDA6159D668F6BAB8157555B5D54C0F47CBCD16843B1A0A0F0210EE310313967F3D516499018FDF3114772470A1889CC06CB6B6690AC31ABCFAF4BC707684545B000B580CCBFCBCE9FA70AAEA0BBD9110992A7C6C06CB368527FD229090757E6FE75705FA592A7608F050C6F88703CC28CB000C1D7E77B897B72C62BCC7AEA21A57729483D2211832BED612430C983103C69E8C072C0EA7898F2283BEC48C5AC81984D4A5A83619735A842BD172C0D1B39F43588AF170458BA9EE7492EAAA94EA53A4D38498ECBB98A5F407E7C97B4E166E397192C216033014B878E938075C6C1F10A0065ABC3163722F1A2EFFEC8D6E3A0C4F7174FC16B79FB5186A75168F81A56AA48A20A04BDDF182C6E179C3F69061555EF7396DD0B7499601A6EB3A96A9A22D04F1168DB56355B07600A20370637B645976BBD97B6D6288A0D3036360472E3AC71D566DB8FBB1B1D76CB755CD0D68BDBFC048EBA2525EEA9DD5B144FB3B60FBC34239320CBC069B35AB16B8756536FB33E8A6AF1DD42C79F48AD120AE4B159D3D8C319060CCE569C3F6035365585D34413795A6A18EC5136AB13C90E3AF14C0B8A464C86B9073222B56B3F7328AEA798155325911250EF016D72802E3878AA50540CC983956971D6EFA352C02554DC760A5A91358EA56370884FD5B3F85B70E83E4697DEB1705169E9C60A74528CF15281CB1B1C457D467B5F93A60373D10E0CF6A837AA3C9596A72BEC29B2D7E58653D533061D381D51759752217EB46CAC7807C4AD38B611644ACF0A3F26B6B084AB47A83BF0D696F8A4768FC35BCA6BC7903B2A237C27749F5510C863869E6AE56BB2AFE4771C9221874F50F5B14BAAD5993B49238FD0A0C9F79B7B4584E41301F7A885C9F91819BEA00D512581730539FB37E59E86A6D19CA25F0A811C9B428BA8614AA4F94807BC031CBCC183F3BF07FE2C1A6EBA80D5A706EE0DAB27E231458025D84A7A9B0230501116C290A6BB50626D97B939850942828390B0A2001B7853AD1AE9B011B2DB36CAEEA73A2328E3C56485B491C299115A017C907AB54317260A593A0D7BA6D06615D6E2CA84B860EFF3CCB597211BFE36BDEF8069AFA36C5A73392722650E4957DCA597ACBA5605B63C163CFA94B64DDD62301A4332083361972589DB0599A694DD4547A5EE9196577C22ED427AC89BB8BA3753EB76C41F2C1129C8A77D6805FA719B1B6CA11B740A78A3D41B5330526AB87D58D5925315A1485EDC647C1604EB38138DE637AD2C6CA5BE44E1008B2C0867B229CCC36619E2758C4C2029EAEB26E7A803FCA305A59CD585E117D698ECE011CC3FCE54D2E114545A21AC5BE6771AB8F13122FAD295E745A503B142F91AEF7BDE99998845FDA043555C9C1EE535BE125E5DCE5D266667E723E67B6BA891C16CBA174098A3F351778B0888C9590A9090CD404"""), + xeh(""" +161CD259FEAA7EC6B286498A9A6F69F8B262A2E2093D0FBD76D5DC1C9FDE0DEDB36581004CB48112F852E7F87F649E8A42CD9E0349E7DABDF0A9AC1B521C37EA5241370A8AB2911CC79902C95D28224FA8896AD715209ECDD5D784E91DD9D0BE916B4565F4D5669AEE0DEF931E9768294EEC5258DE8391ECE271E7E4CFD9D23A79FAC3A8E0DB5DDD6E0107235688BBDF7BC5D5632F206C63A0C9564F30965CA58C69FF92D25A4F93A09EAB9B9085947E078A23E4D9C13B8A56E73E18DF42D6949FAF5921F2E373D450C8C09D07B152A97C245447429481D498BEB7256BC47F68F9922B0B1C62D9C23F9F733DD73792CFC7B43CBCEA277D51B2B8AD4A4F522F642CAD5C5DEB21F3627F8AF4D3E5BC9E91D4CB2F124B5BD7C2F4A050CA755BDB8056609663FB9511C9AD83B5039088CC01F0DD54353B0DD7433F0C6CEE0D075959810DEC5416522BB1F1F65547A0C2E9CC9BC17F8D39D29309EBE79F21331B75E12AF2E93F03F74F7F87D360F1DAF86CED736092A211A8158859C42E223CFE2E6E553437D80576CFD1944E97EEFF9B49E5ECCFC678EE165268DFE3D3596B4B86204A81C6063B0CDCE619FDBB96DF7DE6E0BD5270B4D59C4DC508476E7F0708F98C7A4F6645C49D06100C760C599528D1B8BBFE628191CC083C8D225A093F9F17E35574986F86BAA46898B589F3CB7DB46A45F3EDD4FAC20808F4CD0249DA693F8FABFBD4E10C02C65BA8C8610FA8C6DF3DBAEB6763DD482AF41558B1E15CC9C7A72E071685AC19A051F19245B9F77C3038A54E2958623EB8105955609E27D67CF72EC5C4A8E9B9C2924A9E2298508BABA13CF111FDFB062C9607AC1AAA6C637310A8894BF0B96F0C19136186B618DFFB275528BED1CC2715DEF412F77A3CF96645733B048A78474320D1A380F5EEDBDA21FA0125C91D3C37C54BF3752A1F8471C81FCAE2D3EDA966E14E66F223B054D79848FF9411D634024A098970ADE6A88B5F9069F760584DC4CFFFCEA8ECE11BB5566BD2360AB707DF2D21B67488D931F020069176423E6944490CB385E70B358A25346BAFCDD06D402FF24D6C1E5F61A85D""") + ), + new DecapsulateTestCase( + xeh(""" +69F9CBFD1237BA161CF6E6C18F488FC6E39AB4A5C9E6C22EA4E3AD8F267A9C442010D32E61F83E6BFA5C58706145376DBB849528F68007C822B33A95B84904DCD2708D0340C8B808BCD3AAD0E48B85849583A1B4E5945DD9514A7F6461E057B7ECF61957E97CF62815F9C32294B326E1A1C4E360B9498BA80F8CA91532B171D0AEFC4849FA53BC617932E208A677C6044A6600B8D8B83F26A747B18CFB78BEAFC551AD52B7CA6CB88F3B5D9CE2AF6C67956C478CEF491F59E0191B3BBE929B94B666C176138B00F49724341EE2E164B94C053C185A51F93E00F36861613A7FD72FEBD23A8B96A260234239C9628F995DC13807B43A69468167CB1A8F9DD07EE3B33238F63096EBC49D5051C4B65963D74A4766C226F0B94F1862C2124C8C749748C0BC4DC14CB34906B81C5524FB8100798542DC6CC2AA0A708575EABCC11F96A9E61C017A96A7CE93C42091737113AE783C0AE8755E594111EDFABFD86C3212C612A7B62AFD3C7A5C78B2F07344B789C2B2DBB5F4448BE97BBA4233C0039C0FE84300F9B03AC99497E6D46B6E95308FF84790F612CF186EC16811E80C179316A63B25703F60B842B61907E62894E736647B3C09DA6FEC5932782B36E0635085A3949E694D7E17CBA3D9064330438C071B5836A770C55F6213CC1425845DE5A334D75D3E5058C7809FDA4BCD78191DA9797325E6236C2650FC604EE43A83CEB34980084403A33259857907799A9D2A713A633B5C904727F61E42520991D655705CB6BC1B74AF60713EF8712F14086869BE8EB297D228B325A0609FD615EAB7081540A61A82ABF43B7DF98A595BE11F416B41E1EB75BB57977C25C64E97437D88CA5FDA6159D668F6BAB8157555B5D54C0F47CBCD16843B1A0A0F0210EE310313967F3D516499018FDF3114772470A1889CC06CB6B6690AC31ABCFAF4BC707684545B000B580CCBFCBCE9FA70AAEA0BBD9110992A7C6C06CB368527FD229090757E6FE75705FA592A7608F050C6F88703CC28CB000C1D7E77B897B72C62BCC7AEA21A57729483D2211832BED612430C983103C69E8C072C0EA7898F2283BEC48C5AC81984D4A5A83619735A842BD172C0D1B39F43588AF170458BA9EE7492EAAA94EA53A4D38498ECBB98A5F407E7C97B4E166E397192C216033014B878E938075C6C1F10A0065ABC3163722F1A2EFFEC8D6E3A0C4F7174FC16B79FB5186A75168F81A56AA48A20A04BDDF182C6E179C3F69061555EF7396DD0B7499601A6EB3A96A9A22D04F1168DB56355B07600A20370637B645976BBD97B6D6288A0D3036360472E3AC71D566DB8FBB1B1D76CB755CD0D68BDBFC048EBA2525EEA9DD5B144FB3B60FBC34239320CBC069B35AB16B8756536FB33E8A6AF1DD42C79F48AD120AE4B159D3D8C319060CCE569C3F6035365585D34413795A6A18EC5136AB13C90E3AF14C0B8A464C86B9073222B56B3F7328AEA798155325911250EF016D72802E3878AA50540CC983956971D6EFA352C02554DC760A5A91358EA56370884FD5B3F85B70E83E4697DEB1705169E9C60A74528CF15281CB1B1C457D467B5F93A60373D10E0CF6A837AA3C9596A72BEC29B2D7E58653D533061D381D51759752217EB46CAC7807C4AD38B611644ACF0A3F26B6B084AB47A83BF0D696F8A4768FC35BCA6BC7903B2A237C27749F5510C863869E6AE56BB2AFE4771C9221874F50F5B14BAAD5993B49238FD0A0C9F79B7B4584E41301F7A885C9F91819BEA00D512581730539FB37E59E86A6D19CA25F0A811C9B428BA8614AA4F94807BC031CBCC183F3BF07FE2C1A6EBA80D5A706EE0DAB27E231458025D84A7A9B0230501116C290A6BB50626D97B939850942828390B0A2001B7853AD1AE9B011B2DB36CAEEA73A2328E3C56485B491C299115A017C907AB54317260A593A0D7BA6D06615D6E2CA84B860EFF3CCB597211BFE36BDEF8069AFA36C5A73392722650E4957DCA597ACBA5605B63C163CFA94B64DDD62301A4332083361972589DB0599A694DD4547A5EE9196577C22ED427AC89BB8BA3753EB76C41F2C1129C8A77D6805FA719B1B6CA11B740A78A3D41B5330526AB87D58D5925315A1485EDC647C1604EB38138DE637AD2C6CA5BE44E1008B2C0867B229CCC36619E2758C4C2029EAEB26E7A803FCA305A59CD585E117D698ECE011CC3FCE54D2E114545A21AC5BE6771AB8F13122FAD295E745A503B142F91AEF7BDE99998845FDA043555C9C1EE535BE125E5DCE5D266667E723E67B6BA891C16CBA174098A3F351778B0888C9590A9090CD404"""), + xeh(""" +5C26D456C6C7B0E8DF0B125E5D5428FE393655127A5E05BDD1BCAC14C47493783097B6185058FA700555DD8AF10F0F979A39A603826FFEB0B44E9487539F3F1A07C673E96640DDF754C8B98CD83473568B49D095F682C1ACF0E160AB93EB41A16A57D53B419620D351C837315080D530845CF8D63CFCCDB6E9DFBE220A2C14221AA392E6337FA364DF0D2E0398F15AC3DC822B5DD7217081107A45C8CB8EACA51E034117962AEE7EC0EE212FA67A5D4B07D355A0981E4285116ECF5CA9FAB6E3105E4DE4AEC5E32938A1EB91E65CE7B39C3B9829AA1E72B8092C3622E519EE092FAC8106D6597CEB941C763288723CB55044A36D4181052A78B424B0DE1B0260F624A8D3B317095371EE9BEEA9272250D598AC63C2138D23F99087777A902EBA2163171A07546B72FCE7F86EE3B1DC1B8EAC85440B8D241742C3771F91BF981909E4F3E2505C594761259ED3AADA6AA09181B99037A395D66E6EE4BBEF97DE6BA36C53A1808CBA50938038C151603105BD6A4199EA44BF4B08961672598CB708F896E03CD9B8F8AD89DECFBE6BE0EF0006B7BD2F4AA6EB21C0218EDE601D46924CF391AE3A44E43D96EBE84A630937C3409EF0710970C27E3ADD4E64DC64E83942ABEA9CCF498EF1FE72B254043D2775A37E0B5DDD3F596EA131E0734AFA9D0223F4CD9D1AB7304CA979AD37F717BEDC3A9526F8FC94433FE4614F82E709456F39BEE7BACC84E5A70114AF1C2AC8B9B3FAA81C8F35F5A5D24189E1A457F58166473F5F1DF0170AAB5E4AC8FC719F945CCBE6F2FED24B23321D95C4C850B278B8C4EA02E3098D5A599AA3D842CF889B7F284AC5E6E66386D63F2C860B997966B4DF2C32288A50045012B7362727B856AF4F8258509B563758752FFBB1040F3C2AD8B0DED64FC15C95C1A16DE0DAE6625A9EFFCE190FC7F3261D844C114913C6B1152A258A37761B81879B59C37A1DFAC07C3E934510B45DA44C2581A79DAFBF00FABB207306269D9B74B93F4367B3BA22CCC51B362DE16E49D9FDBF8CFF84F6CE6892CA2245D34CEB9C8759E702832B66A572DE9F3016A38F7328700F96B2E947""") + ), + new DecapsulateTestCase( + xeh(""" +69F9CBFD1237BA161CF6E6C18F488FC6E39AB4A5C9E6C22EA4E3AD8F267A9C442010D32E61F83E6BFA5C58706145376DBB849528F68007C822B33A95B84904DCD2708D0340C8B808BCD3AAD0E48B85849583A1B4E5945DD9514A7F6461E057B7ECF61957E97CF62815F9C32294B326E1A1C4E360B9498BA80F8CA91532B171D0AEFC4849FA53BC617932E208A677C6044A6600B8D8B83F26A747B18CFB78BEAFC551AD52B7CA6CB88F3B5D9CE2AF6C67956C478CEF491F59E0191B3BBE929B94B666C176138B00F49724341EE2E164B94C053C185A51F93E00F36861613A7FD72FEBD23A8B96A260234239C9628F995DC13807B43A69468167CB1A8F9DD07EE3B33238F63096EBC49D5051C4B65963D74A4766C226F0B94F1862C2124C8C749748C0BC4DC14CB34906B81C5524FB8100798542DC6CC2AA0A708575EABCC11F96A9E61C017A96A7CE93C42091737113AE783C0AE8755E594111EDFABFD86C3212C612A7B62AFD3C7A5C78B2F07344B789C2B2DBB5F4448BE97BBA4233C0039C0FE84300F9B03AC99497E6D46B6E95308FF84790F612CF186EC16811E80C179316A63B25703F60B842B61907E62894E736647B3C09DA6FEC5932782B36E0635085A3949E694D7E17CBA3D9064330438C071B5836A770C55F6213CC1425845DE5A334D75D3E5058C7809FDA4BCD78191DA9797325E6236C2650FC604EE43A83CEB34980084403A33259857907799A9D2A713A633B5C904727F61E42520991D655705CB6BC1B74AF60713EF8712F14086869BE8EB297D228B325A0609FD615EAB7081540A61A82ABF43B7DF98A595BE11F416B41E1EB75BB57977C25C64E97437D88CA5FDA6159D668F6BAB8157555B5D54C0F47CBCD16843B1A0A0F0210EE310313967F3D516499018FDF3114772470A1889CC06CB6B6690AC31ABCFAF4BC707684545B000B580CCBFCBCE9FA70AAEA0BBD9110992A7C6C06CB368527FD229090757E6FE75705FA592A7608F050C6F88703CC28CB000C1D7E77B897B72C62BCC7AEA21A57729483D2211832BED612430C983103C69E8C072C0EA7898F2283BEC48C5AC81984D4A5A83619735A842BD172C0D1B39F43588AF170458BA9EE7492EAAA94EA53A4D38498ECBB98A5F407E7C97B4E166E397192C216033014B878E938075C6C1F10A0065ABC3163722F1A2EFFEC8D6E3A0C4F7174FC16B79FB5186A75168F81A56AA48A20A04BDDF182C6E179C3F69061555EF7396DD0B7499601A6EB3A96A9A22D04F1168DB56355B07600A20370637B645976BBD97B6D6288A0D3036360472E3AC71D566DB8FBB1B1D76CB755CD0D68BDBFC048EBA2525EEA9DD5B144FB3B60FBC34239320CBC069B35AB16B8756536FB33E8A6AF1DD42C79F48AD120AE4B159D3D8C319060CCE569C3F6035365585D34413795A6A18EC5136AB13C90E3AF14C0B8A464C86B9073222B56B3F7328AEA798155325911250EF016D72802E3878AA50540CC983956971D6EFA352C02554DC760A5A91358EA56370884FD5B3F85B70E83E4697DEB1705169E9C60A74528CF15281CB1B1C457D467B5F93A60373D10E0CF6A837AA3C9596A72BEC29B2D7E58653D533061D381D51759752217EB46CAC7807C4AD38B611644ACF0A3F26B6B084AB47A83BF0D696F8A4768FC35BCA6BC7903B2A237C27749F5510C863869E6AE56BB2AFE4771C9221874F50F5B14BAAD5993B49238FD0A0C9F79B7B4584E41301F7A885C9F91819BEA00D512581730539FB37E59E86A6D19CA25F0A811C9B428BA8614AA4F94807BC031CBCC183F3BF07FE2C1A6EBA80D5A706EE0DAB27E231458025D84A7A9B0230501116C290A6BB50626D97B939850942828390B0A2001B7853AD1AE9B011B2DB36CAEEA73A2328E3C56485B491C299115A017C907AB54317260A593A0D7BA6D06615D6E2CA84B860EFF3CCB597211BFE36BDEF8069AFA36C5A73392722650E4957DCA597ACBA5605B63C163CFA94B64DDD62301A4332083361972589DB0599A694DD4547A5EE9196577C22ED427AC89BB8BA3753EB76C41F2C1129C8A77D6805FA719B1B6CA11B740A78A3D41B5330526AB87D58D5925315A1485EDC647C1604EB38138DE637AD2C6CA5BE44E1008B2C0867B229CCC36619E2758C4C2029EAEB26E7A803FCA305A59CD585E117D698ECE011CC3FCE54D2E114545A21AC5BE6771AB8F13122FAD295E745A503B142F91AEF7BDE99998845FDA043555C9C1EE535BE125E5DCE5D266667E723E67B6BA891C16CBA174098A3F351778B0888C9590A9090CD404"""), + xeh(""" +79E255908B83DAD198AA6EA7219D5C170DA8548B172A2C28D53EB890914E16A6CE4405E8867112D35228DAC037743E25D26D720742C95935218ABBD93B4EB1C145794697EE761EA567BD561C6F5C076A48A34485539C49D23784606432B4913640644CDEE799961E5332E9502E683FEE98C9E1D071D8976E7F652EEE92E736D598F3B4D7217C0ED30FFA7DE590BBADCC0574A7280E502694A13A4E1D5D8837633A2EABDC97F36722D772A380595859134B9ACE346360860F8E60EACAB4AA3F9CF1DA73B5813F773008E0153B1BA0A5940DBC5C9E71E9A46BB4EA04AA9757E8E1AD0209C86334D05FCB611F3A00C7D983C7B9C160B7807CED18E5BC64A52462F4F9438199C2E4C6E9E70EDE2614913BE6D0C28894319B7B646444B5C86FCE61297EC11B21D216AC79159801ED3181667B15A7F30873BFD5727802E7B6588BDD04A5F7CFCD47043E600B4B3A0227E924E2CB92E514547BE4C1236C7AB2139F986AB956C704485DE570841F5857108D2AA57C535B3D44D0535208D501A9B56FFCBE8FDE32B375B90A5578EE44940E1E1888C21A4045D0338149D4C80CEF47BA25558E1842116E1E25499714163C0EE9A95A87A27CA2A61C4BD8D28BB04DE34EFB6E44FA7026B158883019B89AC4A5B5CA8F347A3FE892EE3949BD40D0614B9923052ED174FFBA720F516B6FD1317754A95520C66E3907B32A1648B344C34B3FA2ACEA2C8410DEEB40483529AC7D83351D888E968E457644CD76B8CAA55FC25BA1359F4A50119B1E69242DCE30E93983E50285DC0592537C6202F2E3C9878067A1777EA6A4E5ACC31614AE52787454FEEF503B82492828A736BF22E3278CF2ECAC1D0E11EC67815046CB4A66A8F48D04D4FB3C91CE7C251B37A8F3FB62A37489FFE63BDE22BAA18D4AA5BCCC0D8C709786B6C94D268382B649598A7A6785582CB2C02A2E9BECE29AC919785CCD026ADB6C9D8E85C3332DA956DC20B8470F8DD78B47E19B49BA5B27326D4937E93CC3453BB67EAFE42CAB03A70960DF236C04C344CA7177FD1E72E7E0A2C10D14F0C054337BD14152D4AFE9BB6243260E696EEE1327""") + ), + new DecapsulateTestCase( + xeh(""" +69F9CBFD1237BA161CF6E6C18F488FC6E39AB4A5C9E6C22EA4E3AD8F267A9C442010D32E61F83E6BFA5C58706145376DBB849528F68007C822B33A95B84904DCD2708D0340C8B808BCD3AAD0E48B85849583A1B4E5945DD9514A7F6461E057B7ECF61957E97CF62815F9C32294B326E1A1C4E360B9498BA80F8CA91532B171D0AEFC4849FA53BC617932E208A677C6044A6600B8D8B83F26A747B18CFB78BEAFC551AD52B7CA6CB88F3B5D9CE2AF6C67956C478CEF491F59E0191B3BBE929B94B666C176138B00F49724341EE2E164B94C053C185A51F93E00F36861613A7FD72FEBD23A8B96A260234239C9628F995DC13807B43A69468167CB1A8F9DD07EE3B33238F63096EBC49D5051C4B65963D74A4766C226F0B94F1862C2124C8C749748C0BC4DC14CB34906B81C5524FB8100798542DC6CC2AA0A708575EABCC11F96A9E61C017A96A7CE93C42091737113AE783C0AE8755E594111EDFABFD86C3212C612A7B62AFD3C7A5C78B2F07344B789C2B2DBB5F4448BE97BBA4233C0039C0FE84300F9B03AC99497E6D46B6E95308FF84790F612CF186EC16811E80C179316A63B25703F60B842B61907E62894E736647B3C09DA6FEC5932782B36E0635085A3949E694D7E17CBA3D9064330438C071B5836A770C55F6213CC1425845DE5A334D75D3E5058C7809FDA4BCD78191DA9797325E6236C2650FC604EE43A83CEB34980084403A33259857907799A9D2A713A633B5C904727F61E42520991D655705CB6BC1B74AF60713EF8712F14086869BE8EB297D228B325A0609FD615EAB7081540A61A82ABF43B7DF98A595BE11F416B41E1EB75BB57977C25C64E97437D88CA5FDA6159D668F6BAB8157555B5D54C0F47CBCD16843B1A0A0F0210EE310313967F3D516499018FDF3114772470A1889CC06CB6B6690AC31ABCFAF4BC707684545B000B580CCBFCBCE9FA70AAEA0BBD9110992A7C6C06CB368527FD229090757E6FE75705FA592A7608F050C6F88703CC28CB000C1D7E77B897B72C62BCC7AEA21A57729483D2211832BED612430C983103C69E8C072C0EA7898F2283BEC48C5AC81984D4A5A83619735A842BD172C0D1B39F43588AF170458BA9EE7492EAAA94EA53A4D38498ECBB98A5F407E7C97B4E166E397192C216033014B878E938075C6C1F10A0065ABC3163722F1A2EFFEC8D6E3A0C4F7174FC16B79FB5186A75168F81A56AA48A20A04BDDF182C6E179C3F69061555EF7396DD0B7499601A6EB3A96A9A22D04F1168DB56355B07600A20370637B645976BBD97B6D6288A0D3036360472E3AC71D566DB8FBB1B1D76CB755CD0D68BDBFC048EBA2525EEA9DD5B144FB3B60FBC34239320CBC069B35AB16B8756536FB33E8A6AF1DD42C79F48AD120AE4B159D3D8C319060CCE569C3F6035365585D34413795A6A18EC5136AB13C90E3AF14C0B8A464C86B9073222B56B3F7328AEA798155325911250EF016D72802E3878AA50540CC983956971D6EFA352C02554DC760A5A91358EA56370884FD5B3F85B70E83E4697DEB1705169E9C60A74528CF15281CB1B1C457D467B5F93A60373D10E0CF6A837AA3C9596A72BEC29B2D7E58653D533061D381D51759752217EB46CAC7807C4AD38B611644ACF0A3F26B6B084AB47A83BF0D696F8A4768FC35BCA6BC7903B2A237C27749F5510C863869E6AE56BB2AFE4771C9221874F50F5B14BAAD5993B49238FD0A0C9F79B7B4584E41301F7A885C9F91819BEA00D512581730539FB37E59E86A6D19CA25F0A811C9B428BA8614AA4F94807BC031CBCC183F3BF07FE2C1A6EBA80D5A706EE0DAB27E231458025D84A7A9B0230501116C290A6BB50626D97B939850942828390B0A2001B7853AD1AE9B011B2DB36CAEEA73A2328E3C56485B491C299115A017C907AB54317260A593A0D7BA6D06615D6E2CA84B860EFF3CCB597211BFE36BDEF8069AFA36C5A73392722650E4957DCA597ACBA5605B63C163CFA94B64DDD62301A4332083361972589DB0599A694DD4547A5EE9196577C22ED427AC89BB8BA3753EB76C41F2C1129C8A77D6805FA719B1B6CA11B740A78A3D41B5330526AB87D58D5925315A1485EDC647C1604EB38138DE637AD2C6CA5BE44E1008B2C0867B229CCC36619E2758C4C2029EAEB26E7A803FCA305A59CD585E117D698ECE011CC3FCE54D2E114545A21AC5BE6771AB8F13122FAD295E745A503B142F91AEF7BDE99998845FDA043555C9C1EE535BE125E5DCE5D266667E723E67B6BA891C16CBA174098A3F351778B0888C9590A9090CD404"""), + xeh(""" +D980E3002A28401678E1641E9E7A34D12CB2B4C9D986C7DB0FAB941AA83E43F42C44368138ED65B7A917B22ABA2DB0FBE44E5E9E7A3DAC3301379F7152585C8C7195031774CBEC61D8E1E093D694970B5377DC94CEDC53B6D3802BAF1C6F9152E05DCF66C1643528155C78118DFB00646B90726C75131DC934DCBB706ADBEC64E07F0D113BF71D4205D8E47DE67B9E01B224B82CA24405AE5591BBB1307D44E405E3866B1BB51ECE5985EE95D54568A81E7F285596DCAEBDC807EE6C8322EF2100EB38D10327DF92BC10A74A2D44842AA02AE9101A24736949D116CEC81F30C3092AAD941FC7F4BA10670CC0894A2F81E3155B9081004B4ADFB6532A1458F727F418D3F8F228E7425ACB7A4E4A3653529D1B9F72E57B8AB5852E35D0093B548FCC354A590C256B50BCADC30B55B5E05A3231611C93D5E34775741374F3E703B6E6362B35A68E33D859918D93EC03633220C61E1B81ED7AB1A5E46D4E640A9DE4E5A19FD11F0C24C556FE8D91F2358E7E78033A3C9FBF68C99DBA351F8F866CFF14E990C29E4A47579376606EB85A9D07D0BFD835C7670A5F4F2D4EA62B2BB13528A27BA3420095B852E3B73AB38E3CD068E276D8BD7A0B85BEFA48FEB72EBFC5240408B069FBC28F48B3A8E6556D7C601ADF98F0E9D64108F0BFE3C3B56C800D76E6DB14736809CEC22FA811EE92EA7950421B22F613E1349D259CF877075D476798C66FF58DBED013675BF6C5D3704528FBBE91486D7E956F785F73EDB6EB42861694F5C27E318C7B481377770125D99F236875D5B26CC8ED9859393BA2D8531E25FD6E2B3560BBC13176EBA638C72626C32D0250AB7F7EFFE661B18A641F75AE279C39771C7F23EAD50CD3AE461BB0EAACDDAD4F9C6436EDA5F2348F0ED4CD9514310AAE609B539368F53EA787ACD630080B832221B1CEF67FEB63CD2DDBA25282B020A3CB418130AD96D66EBAC09F09CB35BE0539B44924CEE15C6DBEAEE04C5BE5B9C43535FCA64B32BB204497AF175513375971B15F107F88980F0C0EB15D34762C98198A94EDCA385F32FD82CE7F6FB36F12B742C1755417A8D3F7D8A9""") + ), + new DecapsulateTestCase( + xeh(""" +69F9CBFD1237BA161CF6E6C18F488FC6E39AB4A5C9E6C22EA4E3AD8F267A9C442010D32E61F83E6BFA5C58706145376DBB849528F68007C822B33A95B84904DCD2708D0340C8B808BCD3AAD0E48B85849583A1B4E5945DD9514A7F6461E057B7ECF61957E97CF62815F9C32294B326E1A1C4E360B9498BA80F8CA91532B171D0AEFC4849FA53BC617932E208A677C6044A6600B8D8B83F26A747B18CFB78BEAFC551AD52B7CA6CB88F3B5D9CE2AF6C67956C478CEF491F59E0191B3BBE929B94B666C176138B00F49724341EE2E164B94C053C185A51F93E00F36861613A7FD72FEBD23A8B96A260234239C9628F995DC13807B43A69468167CB1A8F9DD07EE3B33238F63096EBC49D5051C4B65963D74A4766C226F0B94F1862C2124C8C749748C0BC4DC14CB34906B81C5524FB8100798542DC6CC2AA0A708575EABCC11F96A9E61C017A96A7CE93C42091737113AE783C0AE8755E594111EDFABFD86C3212C612A7B62AFD3C7A5C78B2F07344B789C2B2DBB5F4448BE97BBA4233C0039C0FE84300F9B03AC99497E6D46B6E95308FF84790F612CF186EC16811E80C179316A63B25703F60B842B61907E62894E736647B3C09DA6FEC5932782B36E0635085A3949E694D7E17CBA3D9064330438C071B5836A770C55F6213CC1425845DE5A334D75D3E5058C7809FDA4BCD78191DA9797325E6236C2650FC604EE43A83CEB34980084403A33259857907799A9D2A713A633B5C904727F61E42520991D655705CB6BC1B74AF60713EF8712F14086869BE8EB297D228B325A0609FD615EAB7081540A61A82ABF43B7DF98A595BE11F416B41E1EB75BB57977C25C64E97437D88CA5FDA6159D668F6BAB8157555B5D54C0F47CBCD16843B1A0A0F0210EE310313967F3D516499018FDF3114772470A1889CC06CB6B6690AC31ABCFAF4BC707684545B000B580CCBFCBCE9FA70AAEA0BBD9110992A7C6C06CB368527FD229090757E6FE75705FA592A7608F050C6F88703CC28CB000C1D7E77B897B72C62BCC7AEA21A57729483D2211832BED612430C983103C69E8C072C0EA7898F2283BEC48C5AC81984D4A5A83619735A842BD172C0D1B39F43588AF170458BA9EE7492EAAA94EA53A4D38498ECBB98A5F407E7C97B4E166E397192C216033014B878E938075C6C1F10A0065ABC3163722F1A2EFFEC8D6E3A0C4F7174FC16B79FB5186A75168F81A56AA48A20A04BDDF182C6E179C3F69061555EF7396DD0B7499601A6EB3A96A9A22D04F1168DB56355B07600A20370637B645976BBD97B6D6288A0D3036360472E3AC71D566DB8FBB1B1D76CB755CD0D68BDBFC048EBA2525EEA9DD5B144FB3B60FBC34239320CBC069B35AB16B8756536FB33E8A6AF1DD42C79F48AD120AE4B159D3D8C319060CCE569C3F6035365585D34413795A6A18EC5136AB13C90E3AF14C0B8A464C86B9073222B56B3F7328AEA798155325911250EF016D72802E3878AA50540CC983956971D6EFA352C02554DC760A5A91358EA56370884FD5B3F85B70E83E4697DEB1705169E9C60A74528CF15281CB1B1C457D467B5F93A60373D10E0CF6A837AA3C9596A72BEC29B2D7E58653D533061D381D51759752217EB46CAC7807C4AD38B611644ACF0A3F26B6B084AB47A83BF0D696F8A4768FC35BCA6BC7903B2A237C27749F5510C863869E6AE56BB2AFE4771C9221874F50F5B14BAAD5993B49238FD0A0C9F79B7B4584E41301F7A885C9F91819BEA00D512581730539FB37E59E86A6D19CA25F0A811C9B428BA8614AA4F94807BC031CBCC183F3BF07FE2C1A6EBA80D5A706EE0DAB27E231458025D84A7A9B0230501116C290A6BB50626D97B939850942828390B0A2001B7853AD1AE9B011B2DB36CAEEA73A2328E3C56485B491C299115A017C907AB54317260A593A0D7BA6D06615D6E2CA84B860EFF3CCB597211BFE36BDEF8069AFA36C5A73392722650E4957DCA597ACBA5605B63C163CFA94B64DDD62301A4332083361972589DB0599A694DD4547A5EE9196577C22ED427AC89BB8BA3753EB76C41F2C1129C8A77D6805FA719B1B6CA11B740A78A3D41B5330526AB87D58D5925315A1485EDC647C1604EB38138DE637AD2C6CA5BE44E1008B2C0867B229CCC36619E2758C4C2029EAEB26E7A803FCA305A59CD585E117D698ECE011CC3FCE54D2E114545A21AC5BE6771AB8F13122FAD295E745A503B142F91AEF7BDE99998845FDA043555C9C1EE535BE125E5DCE5D266667E723E67B6BA891C16CBA174098A3F351778B0888C9590A9090CD404"""), + xeh(""" +E1E906D018CCDE68680DF762DE4612106E918C29FF5D576D8FEF01D5241B666C26CB7B2F80793146AEEB9308511D9BA264A9A05D6621425730A50479B889F8C6E5AF66CFC9A3123D3B7335C06C8CD2F867484240E8B6C19EFBD3C15C33CFD10EA482D1897A516D07E39C3C1AA866C10655736F18689ECE7359D91E6EF5CEE957930258CD890C09EE1714150347A18DC97AD955B60750624755135AC81AFF8352B701EC5FF50AD925ADA003A617AE64DBFD305038E1E40108C6F12CCDD7738A83C9F7A76164F670ED4756097426700E51BA02EE36BF12FF22A316790F2C2FE7216C12F03023D87E2ADB99683229E77D6B1938EACF10D8686CEE46127CD7652A33FC05414FE370A159C516D250F7D345BAE5E1C9628A65FA9F5ED9E39FA10A316620A2D760C5DC128A5C6137F193226D18B5E013E300A41B1F2D1B47D90E3DF8B4FD71A794FAE0404570261477B32DC80CEA32F2DE743ACF7EBDD41EDBB0119EAF7F872A50A5F4C92A8B85DF792DBAC764C3A9A5A5C12D9E3913356C7F5463BEE9BD2A739FD485493B1C0DEEF716E129ED1E085F146E0D70A7E58D924F576F948BEBEF7842ED831FFD58B4656F91686B4D0F832DD3A4E6FA9F11A4870E9602E0DF0EF4FE9312EC4C7EC216D3EEDCA2076D0F0B5C9FE139145222347E816EBDC1AA70CBEB5D65954427A3DF6A78BEA86C410462596950AB8798F9BACE51A46A544C1BD17A86C2995E3BC82A7F965401A599103B0896E1B9EBA540614CE8F218DC7290103A6044E87069286E5BB18CBD89EF562B6AE1C7353F64D8CED183FA8D05D6B6A6633751EF342D839562733CDC1977684317EBC71378EC02B298671F76EEDCC3041E943A76ED9E0C496B798E10B59BAE17A195544C05CD1FA6A161358EA1D4DC7DF454220D79B235C24720021174C1BF47859CA30BCB57FC19CAD92ABF24C051D48B3D9D46779F910D26AAB4543DB2A0044BEDD491E1D72D8FDF361B50F1FD10AF4668D78F56FDC7E96CA16DCCD9BE8C1819DECAEBBECE41C09093DD508191562D6510307FA4685144D9679E84F58929D79E693DA041B12B76F629912B1E49""") + ), + new DecapsulateTestCase( + xeh(""" +69F9CBFD1237BA161CF6E6C18F488FC6E39AB4A5C9E6C22EA4E3AD8F267A9C442010D32E61F83E6BFA5C58706145376DBB849528F68007C822B33A95B84904DCD2708D0340C8B808BCD3AAD0E48B85849583A1B4E5945DD9514A7F6461E057B7ECF61957E97CF62815F9C32294B326E1A1C4E360B9498BA80F8CA91532B171D0AEFC4849FA53BC617932E208A677C6044A6600B8D8B83F26A747B18CFB78BEAFC551AD52B7CA6CB88F3B5D9CE2AF6C67956C478CEF491F59E0191B3BBE929B94B666C176138B00F49724341EE2E164B94C053C185A51F93E00F36861613A7FD72FEBD23A8B96A260234239C9628F995DC13807B43A69468167CB1A8F9DD07EE3B33238F63096EBC49D5051C4B65963D74A4766C226F0B94F1862C2124C8C749748C0BC4DC14CB34906B81C5524FB8100798542DC6CC2AA0A708575EABCC11F96A9E61C017A96A7CE93C42091737113AE783C0AE8755E594111EDFABFD86C3212C612A7B62AFD3C7A5C78B2F07344B789C2B2DBB5F4448BE97BBA4233C0039C0FE84300F9B03AC99497E6D46B6E95308FF84790F612CF186EC16811E80C179316A63B25703F60B842B61907E62894E736647B3C09DA6FEC5932782B36E0635085A3949E694D7E17CBA3D9064330438C071B5836A770C55F6213CC1425845DE5A334D75D3E5058C7809FDA4BCD78191DA9797325E6236C2650FC604EE43A83CEB34980084403A33259857907799A9D2A713A633B5C904727F61E42520991D655705CB6BC1B74AF60713EF8712F14086869BE8EB297D228B325A0609FD615EAB7081540A61A82ABF43B7DF98A595BE11F416B41E1EB75BB57977C25C64E97437D88CA5FDA6159D668F6BAB8157555B5D54C0F47CBCD16843B1A0A0F0210EE310313967F3D516499018FDF3114772470A1889CC06CB6B6690AC31ABCFAF4BC707684545B000B580CCBFCBCE9FA70AAEA0BBD9110992A7C6C06CB368527FD229090757E6FE75705FA592A7608F050C6F88703CC28CB000C1D7E77B897B72C62BCC7AEA21A57729483D2211832BED612430C983103C69E8C072C0EA7898F2283BEC48C5AC81984D4A5A83619735A842BD172C0D1B39F43588AF170458BA9EE7492EAAA94EA53A4D38498ECBB98A5F407E7C97B4E166E397192C216033014B878E938075C6C1F10A0065ABC3163722F1A2EFFEC8D6E3A0C4F7174FC16B79FB5186A75168F81A56AA48A20A04BDDF182C6E179C3F69061555EF7396DD0B7499601A6EB3A96A9A22D04F1168DB56355B07600A20370637B645976BBD97B6D6288A0D3036360472E3AC71D566DB8FBB1B1D76CB755CD0D68BDBFC048EBA2525EEA9DD5B144FB3B60FBC34239320CBC069B35AB16B8756536FB33E8A6AF1DD42C79F48AD120AE4B159D3D8C319060CCE569C3F6035365585D34413795A6A18EC5136AB13C90E3AF14C0B8A464C86B9073222B56B3F7328AEA798155325911250EF016D72802E3878AA50540CC983956971D6EFA352C02554DC760A5A91358EA56370884FD5B3F85B70E83E4697DEB1705169E9C60A74528CF15281CB1B1C457D467B5F93A60373D10E0CF6A837AA3C9596A72BEC29B2D7E58653D533061D381D51759752217EB46CAC7807C4AD38B611644ACF0A3F26B6B084AB47A83BF0D696F8A4768FC35BCA6BC7903B2A237C27749F5510C863869E6AE56BB2AFE4771C9221874F50F5B14BAAD5993B49238FD0A0C9F79B7B4584E41301F7A885C9F91819BEA00D512581730539FB37E59E86A6D19CA25F0A811C9B428BA8614AA4F94807BC031CBCC183F3BF07FE2C1A6EBA80D5A706EE0DAB27E231458025D84A7A9B0230501116C290A6BB50626D97B939850942828390B0A2001B7853AD1AE9B011B2DB36CAEEA73A2328E3C56485B491C299115A017C907AB54317260A593A0D7BA6D06615D6E2CA84B860EFF3CCB597211BFE36BDEF8069AFA36C5A73392722650E4957DCA597ACBA5605B63C163CFA94B64DDD62301A4332083361972589DB0599A694DD4547A5EE9196577C22ED427AC89BB8BA3753EB76C41F2C1129C8A77D6805FA719B1B6CA11B740A78A3D41B5330526AB87D58D5925315A1485EDC647C1604EB38138DE637AD2C6CA5BE44E1008B2C0867B229CCC36619E2758C4C2029EAEB26E7A803FCA305A59CD585E117D698ECE011CC3FCE54D2E114545A21AC5BE6771AB8F13122FAD295E745A503B142F91AEF7BDE99998845FDA043555C9C1EE535BE125E5DCE5D266667E723E67B6BA891C16CBA174098A3F351778B0888C9590A9090CD404"""), + xeh(""" +3EAE23CC5F424EDC10108FCAE8EA3AC2BE8E90EB6AFC438B5A7DCD8E149AEBA25F0D5B25052C030F8157CC5BFB876A62F6A85B6C1C954F7C0F99EF4E3AE4B48C1CA9AF035543ECA1069B067057FEFB1E50FE0374F4162F0628F1D383A8B111EA9DE854EF33FB79488AA81E75712E5B9B6485290F0956B0574A6A9E1B4D677A832A85717CF7FF5A9E23B205C4FBD4ED7C2F7C5D91F46CD6A1EDB692750A4C1B11DB15C5643C7572FF9B765713C5C97C05BC2B861997CC6CC2C4D82CC62A32EA361630454756138C015D5501E362BC4E2B03A7AD679293658E45CF155B1C4F165954D594871CBF556CFAD2C3E6EB238DA3FF3A8140C5FCB74A278ED495DD14849D4C874C3E1F6E56EE657238F4E927FAE4588F1628DECE45C625AE0A6137868B9E86CFE29CCB4483CCA6FEE905F084B2B03A84DA421417CA5087B19654C803CF072B3C9E37A70B24E30E2F52B1DFCB6817ED05D38BB6FC7558B9B96AFA0CDBE708025D8D0454B90767753524CEEF8372150480BD104F1B7E659AD28EB155842CA81A55E81B707DAAF2F42A0B1CCE0B3BFF23F5ACF984ED20B0970ECF973DD0D5E33D34FBFD1672BFFF6725B5F1F869945FC67C5D01F3ED1CD8CD43A2008181AF7F65B0922D4BC634670AAD8A23A698AC3675EB3452DCE23D7E1A130964CCF4E26A9CD3D424A54ED7861E2D807F9C98E434A78695EFAC8BC86C69CD5911A2F52B5DAF50866151C5D00FAFCAB6219A9BA675413B4BB28619CFFACA38B9ABD1C3647BCE412336C02044EAA752B79248EBA1A7AED403801DAE5377CD55F517432B677A75DE4D4B504EBBF6453E319BB6EDACE30EE44810332CC84CBFFEE2B20548EEEEE1CA131AD87CCC284B3677E7F632D69F776060005439DE5648E466AF68C6616C63144451126D10311798A9B311064301BFAC1E4641830B1FAF4963F14A740529C360A73A351B6D330364BCCD2B012CD2B571ED243BF63F2FC1F1963604923B397A57680290D413FE7413B2C6C01D5BD6A0E314A644ECB10C69418251F48D3C3941211CEDB083F6FCDE24C5F5832034780B539D3FB1493C631F0C10F2F50262FA""") + ), + new DecapsulateTestCase( + xeh(""" +69F9CBFD1237BA161CF6E6C18F488FC6E39AB4A5C9E6C22EA4E3AD8F267A9C442010D32E61F83E6BFA5C58706145376DBB849528F68007C822B33A95B84904DCD2708D0340C8B808BCD3AAD0E48B85849583A1B4E5945DD9514A7F6461E057B7ECF61957E97CF62815F9C32294B326E1A1C4E360B9498BA80F8CA91532B171D0AEFC4849FA53BC617932E208A677C6044A6600B8D8B83F26A747B18CFB78BEAFC551AD52B7CA6CB88F3B5D9CE2AF6C67956C478CEF491F59E0191B3BBE929B94B666C176138B00F49724341EE2E164B94C053C185A51F93E00F36861613A7FD72FEBD23A8B96A260234239C9628F995DC13807B43A69468167CB1A8F9DD07EE3B33238F63096EBC49D5051C4B65963D74A4766C226F0B94F1862C2124C8C749748C0BC4DC14CB34906B81C5524FB8100798542DC6CC2AA0A708575EABCC11F96A9E61C017A96A7CE93C42091737113AE783C0AE8755E594111EDFABFD86C3212C612A7B62AFD3C7A5C78B2F07344B789C2B2DBB5F4448BE97BBA4233C0039C0FE84300F9B03AC99497E6D46B6E95308FF84790F612CF186EC16811E80C179316A63B25703F60B842B61907E62894E736647B3C09DA6FEC5932782B36E0635085A3949E694D7E17CBA3D9064330438C071B5836A770C55F6213CC1425845DE5A334D75D3E5058C7809FDA4BCD78191DA9797325E6236C2650FC604EE43A83CEB34980084403A33259857907799A9D2A713A633B5C904727F61E42520991D655705CB6BC1B74AF60713EF8712F14086869BE8EB297D228B325A0609FD615EAB7081540A61A82ABF43B7DF98A595BE11F416B41E1EB75BB57977C25C64E97437D88CA5FDA6159D668F6BAB8157555B5D54C0F47CBCD16843B1A0A0F0210EE310313967F3D516499018FDF3114772470A1889CC06CB6B6690AC31ABCFAF4BC707684545B000B580CCBFCBCE9FA70AAEA0BBD9110992A7C6C06CB368527FD229090757E6FE75705FA592A7608F050C6F88703CC28CB000C1D7E77B897B72C62BCC7AEA21A57729483D2211832BED612430C983103C69E8C072C0EA7898F2283BEC48C5AC81984D4A5A83619735A842BD172C0D1B39F43588AF170458BA9EE7492EAAA94EA53A4D38498ECBB98A5F407E7C97B4E166E397192C216033014B878E938075C6C1F10A0065ABC3163722F1A2EFFEC8D6E3A0C4F7174FC16B79FB5186A75168F81A56AA48A20A04BDDF182C6E179C3F69061555EF7396DD0B7499601A6EB3A96A9A22D04F1168DB56355B07600A20370637B645976BBD97B6D6288A0D3036360472E3AC71D566DB8FBB1B1D76CB755CD0D68BDBFC048EBA2525EEA9DD5B144FB3B60FBC34239320CBC069B35AB16B8756536FB33E8A6AF1DD42C79F48AD120AE4B159D3D8C319060CCE569C3F6035365585D34413795A6A18EC5136AB13C90E3AF14C0B8A464C86B9073222B56B3F7328AEA798155325911250EF016D72802E3878AA50540CC983956971D6EFA352C02554DC760A5A91358EA56370884FD5B3F85B70E83E4697DEB1705169E9C60A74528CF15281CB1B1C457D467B5F93A60373D10E0CF6A837AA3C9596A72BEC29B2D7E58653D533061D381D51759752217EB46CAC7807C4AD38B611644ACF0A3F26B6B084AB47A83BF0D696F8A4768FC35BCA6BC7903B2A237C27749F5510C863869E6AE56BB2AFE4771C9221874F50F5B14BAAD5993B49238FD0A0C9F79B7B4584E41301F7A885C9F91819BEA00D512581730539FB37E59E86A6D19CA25F0A811C9B428BA8614AA4F94807BC031CBCC183F3BF07FE2C1A6EBA80D5A706EE0DAB27E231458025D84A7A9B0230501116C290A6BB50626D97B939850942828390B0A2001B7853AD1AE9B011B2DB36CAEEA73A2328E3C56485B491C299115A017C907AB54317260A593A0D7BA6D06615D6E2CA84B860EFF3CCB597211BFE36BDEF8069AFA36C5A73392722650E4957DCA597ACBA5605B63C163CFA94B64DDD62301A4332083361972589DB0599A694DD4547A5EE9196577C22ED427AC89BB8BA3753EB76C41F2C1129C8A77D6805FA719B1B6CA11B740A78A3D41B5330526AB87D58D5925315A1485EDC647C1604EB38138DE637AD2C6CA5BE44E1008B2C0867B229CCC36619E2758C4C2029EAEB26E7A803FCA305A59CD585E117D698ECE011CC3FCE54D2E114545A21AC5BE6771AB8F13122FAD295E745A503B142F91AEF7BDE99998845FDA043555C9C1EE535BE125E5DCE5D266667E723E67B6BA891C16CBA174098A3F351778B0888C9590A9090CD404"""), + xeh(""" +B3B6B84D9A33C59758CBEEF8EA26540D4E3D4A45BDC623CA1D0AC05D8E780D2DA1FAB26A0E250527FB0B9BD56B2A0686BD0FD310164A17244374B82FC9A93FC0AC6067929C4718B2054C7AA4AF1FDBC9EBCC55A787F7C0B98A8E6181E5604E8F7108B181AD1385422EB747286FF72BD1EF650AB88865BFC37EA5536A220C29ACE17F8AA82A77F92E0A031E526171C44BD5FA1E7946CD063B1A7E113FAEAF92015CB3CCFBDD9C5E0329CD3DBD1B8CA90EC226ACC27716615B5998E0F5A5BFBA347FDD3DD851682B8968858F4A73FE5FD952CE7FF597185855E4B7F76F44BC1B24DB7C8C3A37217DBDF0BA7168D91B59DE9EA219195D29A5C67327D51D4E05131119C81722794D825B9F01DDA93C74B176545E32E638243891EE09E2AC1A9693C83D4BEFACCF25C81554802FC422C75812E18BCCF4D3CF208BE6EB16FB4E82C4ECE33C838A0B3D3EA4C027F41B4027643D9E4B6A7EFBD8D42A65B29786F4A00C16ED4492F4E945469C6E03A9A297AD9763333A2B9725DB5C6F8DF1CA7B0E77F5E6364FB6E8E528578350A04E4E4617E72E5FD67FE029AE2D738D8DFE24730D9D737D8E30ADCB602102FE2D99B915C9B04CDA463D444ED9C6E6A71BCAAFE503BF1D15270DEF8B9D7AA5557177EDEAD75E2FB01A4635A46D2F95DEA6314DE4965EBA8358210F79E64933AB4B6600856124363A47C6063433BB670266AA8FB968D947AD96D97C4003A50B0D1119E3A73E00363AE5EE85B5815A5BD944280031F0DC9B98F1F5C589F259A486BFE26EE1446D937EEDAE41275AB72E0CD15EAA6368F59686DE08E147CE2F5978B366D0A4F98ACD7D4004D1D0A4897A0DF5B1AF9F811BBAC64952D10E36A3EF78D379EF0E95DCD2D804C07AD8D1A8882FE1F2FF188F31B886BB597FF16F4D597EB337319AB4E81565EE4AC0A9BB3B6C3184C9C66511D7313555EF703194A747D0857DD27F92A6DE12DB311828B684FF3F1D848D5E92E0EFD7BC6B3EA7039296D587A075781880039A7C0DD6DB66EDEE3A22F7F2EF02B267429F6BEE16F214A59EB96CA79EC5065784445ED2FB631BADF6645991736BE7ED""") + ), + new DecapsulateTestCase( + xeh(""" +69F9CBFD1237BA161CF6E6C18F488FC6E39AB4A5C9E6C22EA4E3AD8F267A9C442010D32E61F83E6BFA5C58706145376DBB849528F68007C822B33A95B84904DCD2708D0340C8B808BCD3AAD0E48B85849583A1B4E5945DD9514A7F6461E057B7ECF61957E97CF62815F9C32294B326E1A1C4E360B9498BA80F8CA91532B171D0AEFC4849FA53BC617932E208A677C6044A6600B8D8B83F26A747B18CFB78BEAFC551AD52B7CA6CB88F3B5D9CE2AF6C67956C478CEF491F59E0191B3BBE929B94B666C176138B00F49724341EE2E164B94C053C185A51F93E00F36861613A7FD72FEBD23A8B96A260234239C9628F995DC13807B43A69468167CB1A8F9DD07EE3B33238F63096EBC49D5051C4B65963D74A4766C226F0B94F1862C2124C8C749748C0BC4DC14CB34906B81C5524FB8100798542DC6CC2AA0A708575EABCC11F96A9E61C017A96A7CE93C42091737113AE783C0AE8755E594111EDFABFD86C3212C612A7B62AFD3C7A5C78B2F07344B789C2B2DBB5F4448BE97BBA4233C0039C0FE84300F9B03AC99497E6D46B6E95308FF84790F612CF186EC16811E80C179316A63B25703F60B842B61907E62894E736647B3C09DA6FEC5932782B36E0635085A3949E694D7E17CBA3D9064330438C071B5836A770C55F6213CC1425845DE5A334D75D3E5058C7809FDA4BCD78191DA9797325E6236C2650FC604EE43A83CEB34980084403A33259857907799A9D2A713A633B5C904727F61E42520991D655705CB6BC1B74AF60713EF8712F14086869BE8EB297D228B325A0609FD615EAB7081540A61A82ABF43B7DF98A595BE11F416B41E1EB75BB57977C25C64E97437D88CA5FDA6159D668F6BAB8157555B5D54C0F47CBCD16843B1A0A0F0210EE310313967F3D516499018FDF3114772470A1889CC06CB6B6690AC31ABCFAF4BC707684545B000B580CCBFCBCE9FA70AAEA0BBD9110992A7C6C06CB368527FD229090757E6FE75705FA592A7608F050C6F88703CC28CB000C1D7E77B897B72C62BCC7AEA21A57729483D2211832BED612430C983103C69E8C072C0EA7898F2283BEC48C5AC81984D4A5A83619735A842BD172C0D1B39F43588AF170458BA9EE7492EAAA94EA53A4D38498ECBB98A5F407E7C97B4E166E397192C216033014B878E938075C6C1F10A0065ABC3163722F1A2EFFEC8D6E3A0C4F7174FC16B79FB5186A75168F81A56AA48A20A04BDDF182C6E179C3F69061555EF7396DD0B7499601A6EB3A96A9A22D04F1168DB56355B07600A20370637B645976BBD97B6D6288A0D3036360472E3AC71D566DB8FBB1B1D76CB755CD0D68BDBFC048EBA2525EEA9DD5B144FB3B60FBC34239320CBC069B35AB16B8756536FB33E8A6AF1DD42C79F48AD120AE4B159D3D8C319060CCE569C3F6035365585D34413795A6A18EC5136AB13C90E3AF14C0B8A464C86B9073222B56B3F7328AEA798155325911250EF016D72802E3878AA50540CC983956971D6EFA352C02554DC760A5A91358EA56370884FD5B3F85B70E83E4697DEB1705169E9C60A74528CF15281CB1B1C457D467B5F93A60373D10E0CF6A837AA3C9596A72BEC29B2D7E58653D533061D381D51759752217EB46CAC7807C4AD38B611644ACF0A3F26B6B084AB47A83BF0D696F8A4768FC35BCA6BC7903B2A237C27749F5510C863869E6AE56BB2AFE4771C9221874F50F5B14BAAD5993B49238FD0A0C9F79B7B4584E41301F7A885C9F91819BEA00D512581730539FB37E59E86A6D19CA25F0A811C9B428BA8614AA4F94807BC031CBCC183F3BF07FE2C1A6EBA80D5A706EE0DAB27E231458025D84A7A9B0230501116C290A6BB50626D97B939850942828390B0A2001B7853AD1AE9B011B2DB36CAEEA73A2328E3C56485B491C299115A017C907AB54317260A593A0D7BA6D06615D6E2CA84B860EFF3CCB597211BFE36BDEF8069AFA36C5A73392722650E4957DCA597ACBA5605B63C163CFA94B64DDD62301A4332083361972589DB0599A694DD4547A5EE9196577C22ED427AC89BB8BA3753EB76C41F2C1129C8A77D6805FA719B1B6CA11B740A78A3D41B5330526AB87D58D5925315A1485EDC647C1604EB38138DE637AD2C6CA5BE44E1008B2C0867B229CCC36619E2758C4C2029EAEB26E7A803FCA305A59CD585E117D698ECE011CC3FCE54D2E114545A21AC5BE6771AB8F13122FAD295E745A503B142F91AEF7BDE99998845FDA043555C9C1EE535BE125E5DCE5D266667E723E67B6BA891C16CBA174098A3F351778B0888C9590A9090CD404"""), + xeh(""" +FA42A8B407B527A8CD9351560BA4DA60756B27FEF326BC549B3A4429B2E58EAF22B3A36AE554B416DCE209E8CC708846312992DCDD43AB177347363F81578B94F451F1D046233BEEC6B42C9E0D55F3D741A55F7C564C4A9D5ECF6B067723E4403A17CBCFAA00E2F8D2EDFE1E236AE861011A5DB659042AA23BEB01A0471D178DB91039EEE5FC7EE85AC6FF3845959E5001C61CD1756EC681C97F4A70887884157D664A505ED7E4E1F4598EBF8BCDC0BEDE7FC0A89B3E14237187CED97BB0C0E54D21F4DF47BC8FC3F863978DBB673835D17931B7819535C1ACCD8706F8726BB0A0DE20BB824560AE5BAAE2F0BF0E3E676FF74C681474534C857837E7040C33B7F031AD9900A29DCB71BC305DB0ABF92CEB5DD2EB8E644F23AC0BFD8DCD2B44101FD7CB8A287318979BAE754661FFB13097B2A52B50236094693A754DC97CFAB550877A4D8C6CBA8B4A2E3D719ABF0EB13D40976B9E3F6C433DB1E16D794466D2C023988528AD0336CE43636DD50FA6A5E899578EACEFACA5FFC5B6FCC8C53E21503B83ABEDF2174FE08B4B960476934C5D6021829AB7AA7767492FAFBEE492A08524FBED46E8D0451C6BE1BE02B55653326735B0D8CCE951A5CF534E3547731EE36EB9BA38E0AE253B8CEC35001EECE0058E634A11F59FD6F21C1A3882E291F59B1FE3EC7F55315E0A65F9D011210462A8CAFC9779208452FD4F3B64FF456EA8588D2CB394A9169F1392646880A1C63721A2277FDA432FC6EBB61FF87AD473FF41D831DD95111CF0A1D69F001A008C3FD00B46F5342EDB8DADC818E6470D21C915F3E91992806E5B18DB314F9592E0EC8B8F0DEAF92DC89C194449A2539BE7C6A1B01B6F3DC496CF33CA25825B66971880652BC6E4FBD901A286C50D625F0F682B0B4CC769EB00940C45ADE947844175A3BBE8DB92BA6DAE5BE456CEA41384BB29A8C9D4E08F1375D4865A69A59619724900DDFAE48A2D12975C789E76104AE114F30ED4F836E46BCD8CA7520F4838651225894595C4F7BEFD7ED41EAF6F395EDE40F988CBDA7E08122A61E552801C7F3E84039FFF17E3534610D3434B996312""") + ), + new DecapsulateTestCase( + xeh(""" +69F9CBFD1237BA161CF6E6C18F488FC6E39AB4A5C9E6C22EA4E3AD8F267A9C442010D32E61F83E6BFA5C58706145376DBB849528F68007C822B33A95B84904DCD2708D0340C8B808BCD3AAD0E48B85849583A1B4E5945DD9514A7F6461E057B7ECF61957E97CF62815F9C32294B326E1A1C4E360B9498BA80F8CA91532B171D0AEFC4849FA53BC617932E208A677C6044A6600B8D8B83F26A747B18CFB78BEAFC551AD52B7CA6CB88F3B5D9CE2AF6C67956C478CEF491F59E0191B3BBE929B94B666C176138B00F49724341EE2E164B94C053C185A51F93E00F36861613A7FD72FEBD23A8B96A260234239C9628F995DC13807B43A69468167CB1A8F9DD07EE3B33238F63096EBC49D5051C4B65963D74A4766C226F0B94F1862C2124C8C749748C0BC4DC14CB34906B81C5524FB8100798542DC6CC2AA0A708575EABCC11F96A9E61C017A96A7CE93C42091737113AE783C0AE8755E594111EDFABFD86C3212C612A7B62AFD3C7A5C78B2F07344B789C2B2DBB5F4448BE97BBA4233C0039C0FE84300F9B03AC99497E6D46B6E95308FF84790F612CF186EC16811E80C179316A63B25703F60B842B61907E62894E736647B3C09DA6FEC5932782B36E0635085A3949E694D7E17CBA3D9064330438C071B5836A770C55F6213CC1425845DE5A334D75D3E5058C7809FDA4BCD78191DA9797325E6236C2650FC604EE43A83CEB34980084403A33259857907799A9D2A713A633B5C904727F61E42520991D655705CB6BC1B74AF60713EF8712F14086869BE8EB297D228B325A0609FD615EAB7081540A61A82ABF43B7DF98A595BE11F416B41E1EB75BB57977C25C64E97437D88CA5FDA6159D668F6BAB8157555B5D54C0F47CBCD16843B1A0A0F0210EE310313967F3D516499018FDF3114772470A1889CC06CB6B6690AC31ABCFAF4BC707684545B000B580CCBFCBCE9FA70AAEA0BBD9110992A7C6C06CB368527FD229090757E6FE75705FA592A7608F050C6F88703CC28CB000C1D7E77B897B72C62BCC7AEA21A57729483D2211832BED612430C983103C69E8C072C0EA7898F2283BEC48C5AC81984D4A5A83619735A842BD172C0D1B39F43588AF170458BA9EE7492EAAA94EA53A4D38498ECBB98A5F407E7C97B4E166E397192C216033014B878E938075C6C1F10A0065ABC3163722F1A2EFFEC8D6E3A0C4F7174FC16B79FB5186A75168F81A56AA48A20A04BDDF182C6E179C3F69061555EF7396DD0B7499601A6EB3A96A9A22D04F1168DB56355B07600A20370637B645976BBD97B6D6288A0D3036360472E3AC71D566DB8FBB1B1D76CB755CD0D68BDBFC048EBA2525EEA9DD5B144FB3B60FBC34239320CBC069B35AB16B8756536FB33E8A6AF1DD42C79F48AD120AE4B159D3D8C319060CCE569C3F6035365585D34413795A6A18EC5136AB13C90E3AF14C0B8A464C86B9073222B56B3F7328AEA798155325911250EF016D72802E3878AA50540CC983956971D6EFA352C02554DC760A5A91358EA56370884FD5B3F85B70E83E4697DEB1705169E9C60A74528CF15281CB1B1C457D467B5F93A60373D10E0CF6A837AA3C9596A72BEC29B2D7E58653D533061D381D51759752217EB46CAC7807C4AD38B611644ACF0A3F26B6B084AB47A83BF0D696F8A4768FC35BCA6BC7903B2A237C27749F5510C863869E6AE56BB2AFE4771C9221874F50F5B14BAAD5993B49238FD0A0C9F79B7B4584E41301F7A885C9F91819BEA00D512581730539FB37E59E86A6D19CA25F0A811C9B428BA8614AA4F94807BC031CBCC183F3BF07FE2C1A6EBA80D5A706EE0DAB27E231458025D84A7A9B0230501116C290A6BB50626D97B939850942828390B0A2001B7853AD1AE9B011B2DB36CAEEA73A2328E3C56485B491C299115A017C907AB54317260A593A0D7BA6D06615D6E2CA84B860EFF3CCB597211BFE36BDEF8069AFA36C5A73392722650E4957DCA597ACBA5605B63C163CFA94B64DDD62301A4332083361972589DB0599A694DD4547A5EE9196577C22ED427AC89BB8BA3753EB76C41F2C1129C8A77D6805FA719B1B6CA11B740A78A3D41B5330526AB87D58D5925315A1485EDC647C1604EB38138DE637AD2C6CA5BE44E1008B2C0867B229CCC36619E2758C4C2029EAEB26E7A803FCA305A59CD585E117D698ECE011CC3FCE54D2E114545A21AC5BE6771AB8F13122FAD295E745A503B142F91AEF7BDE99998845FDA043555C9C1EE535BE125E5DCE5D266667E723E67B6BA891C16CBA174098A3F351778B0888C9590A9090CD404"""), + xeh(""" +9F972164967C0CD03A3DD68714FE0B4EE0EDF9ACF63AA068C10FA947F8A03264B4309EE61C8C9B0C03C5FEDFC7B77AA862DDEFEFE394FB09A2396097452585ACD0CE510324A03F36904AF07B765575DCB3B1A84131C352EF14C2572E39DDBC8118875ECFD7EF7D2E41D9C9BE858FF08DBFABF8A80BCF18FDA8735F440D9B8FCAE0E67C5BF0171B99800BBF0F3EADF76F9FD69BB0734F1356C53EA9CD64E86C14C084BC3B1FEF040E5FA939F8F0D5171AD02628AFD8B02DB7D7B5C3B32F1A8EF3AD4116ADD4502414163C14D49EC73E5F4B25C5BAAB82C73401975F2119C569E1F2873DA202F32BDFB76F9AF49F22604D1B1BB173DDF6ED70D82B360C13822F5F9BC4C4D5F2391E4FB6BCB723A56666087A55E033E50202EFBBE7DAAF96AC541C855AA4154E37CDA55B1BEAB005554947F781512E2873B5CD8B118EE0932DB2FF427A15BD114D7DA79C7D899FD820A0222DF90D8E85CEAD8A1BD96A88D6D58C0A4FBDE3AA55DFA1E4B12AE6964DEDE20FE337E4BA5EE8B67CE1ADAE9851D021A56B999DED62D0E4471CD928E9AA4AEEC5C878199149D82C3CF4FCB68F63DF27842C37E52182A7E3B332F24948F3646874326B4FDF215524A1095A224F6EB02355974A6DE9746824A3954B700903292DA43D5DD51DD9D8E98E63DD01C357E4913855190049E0F1A8D9725B095ADAC4885FE832E0BEE82BF3DC355668093B475FFCF7D92228FDEDF0451C441B345372D6EE58408462E2C3BF22A095E5E23A159397FC959C126CAF936A3E64552003FEB2B963AF7F915885445EB25B934D659900DD0506A5FCB7168392824945AABFCCD01D9EA8A2256FC8E7AAF0C4243025A9F47F295F9D2713D5257D626057E904E34B8C0530A11DF2D15AE6BF1ADA6971B233B5DFB59EF8B9EB813E7E52794883BD6D676119B5B86333CBE6427F97ED719C432127805A9790837A1EB04B82907A59CED1286164A9F02716CDAAEE48799599CB09F5CA8BDE83CE8278382776CC3246EB2C0EA91C1A9D0CD7406B419A22CD6115018B9641405F9F44E13D2CD6AB457825326FC5CDE85C94DF86097BFB5204530FE8""") + ), + new DecapsulateTestCase( + xeh(""" +69F9CBFD1237BA161CF6E6C18F488FC6E39AB4A5C9E6C22EA4E3AD8F267A9C442010D32E61F83E6BFA5C58706145376DBB849528F68007C822B33A95B84904DCD2708D0340C8B808BCD3AAD0E48B85849583A1B4E5945DD9514A7F6461E057B7ECF61957E97CF62815F9C32294B326E1A1C4E360B9498BA80F8CA91532B171D0AEFC4849FA53BC617932E208A677C6044A6600B8D8B83F26A747B18CFB78BEAFC551AD52B7CA6CB88F3B5D9CE2AF6C67956C478CEF491F59E0191B3BBE929B94B666C176138B00F49724341EE2E164B94C053C185A51F93E00F36861613A7FD72FEBD23A8B96A260234239C9628F995DC13807B43A69468167CB1A8F9DD07EE3B33238F63096EBC49D5051C4B65963D74A4766C226F0B94F1862C2124C8C749748C0BC4DC14CB34906B81C5524FB8100798542DC6CC2AA0A708575EABCC11F96A9E61C017A96A7CE93C42091737113AE783C0AE8755E594111EDFABFD86C3212C612A7B62AFD3C7A5C78B2F07344B789C2B2DBB5F4448BE97BBA4233C0039C0FE84300F9B03AC99497E6D46B6E95308FF84790F612CF186EC16811E80C179316A63B25703F60B842B61907E62894E736647B3C09DA6FEC5932782B36E0635085A3949E694D7E17CBA3D9064330438C071B5836A770C55F6213CC1425845DE5A334D75D3E5058C7809FDA4BCD78191DA9797325E6236C2650FC604EE43A83CEB34980084403A33259857907799A9D2A713A633B5C904727F61E42520991D655705CB6BC1B74AF60713EF8712F14086869BE8EB297D228B325A0609FD615EAB7081540A61A82ABF43B7DF98A595BE11F416B41E1EB75BB57977C25C64E97437D88CA5FDA6159D668F6BAB8157555B5D54C0F47CBCD16843B1A0A0F0210EE310313967F3D516499018FDF3114772470A1889CC06CB6B6690AC31ABCFAF4BC707684545B000B580CCBFCBCE9FA70AAEA0BBD9110992A7C6C06CB368527FD229090757E6FE75705FA592A7608F050C6F88703CC28CB000C1D7E77B897B72C62BCC7AEA21A57729483D2211832BED612430C983103C69E8C072C0EA7898F2283BEC48C5AC81984D4A5A83619735A842BD172C0D1B39F43588AF170458BA9EE7492EAAA94EA53A4D38498ECBB98A5F407E7C97B4E166E397192C216033014B878E938075C6C1F10A0065ABC3163722F1A2EFFEC8D6E3A0C4F7174FC16B79FB5186A75168F81A56AA48A20A04BDDF182C6E179C3F69061555EF7396DD0B7499601A6EB3A96A9A22D04F1168DB56355B07600A20370637B645976BBD97B6D6288A0D3036360472E3AC71D566DB8FBB1B1D76CB755CD0D68BDBFC048EBA2525EEA9DD5B144FB3B60FBC34239320CBC069B35AB16B8756536FB33E8A6AF1DD42C79F48AD120AE4B159D3D8C319060CCE569C3F6035365585D34413795A6A18EC5136AB13C90E3AF14C0B8A464C86B9073222B56B3F7328AEA798155325911250EF016D72802E3878AA50540CC983956971D6EFA352C02554DC760A5A91358EA56370884FD5B3F85B70E83E4697DEB1705169E9C60A74528CF15281CB1B1C457D467B5F93A60373D10E0CF6A837AA3C9596A72BEC29B2D7E58653D533061D381D51759752217EB46CAC7807C4AD38B611644ACF0A3F26B6B084AB47A83BF0D696F8A4768FC35BCA6BC7903B2A237C27749F5510C863869E6AE56BB2AFE4771C9221874F50F5B14BAAD5993B49238FD0A0C9F79B7B4584E41301F7A885C9F91819BEA00D512581730539FB37E59E86A6D19CA25F0A811C9B428BA8614AA4F94807BC031CBCC183F3BF07FE2C1A6EBA80D5A706EE0DAB27E231458025D84A7A9B0230501116C290A6BB50626D97B939850942828390B0A2001B7853AD1AE9B011B2DB36CAEEA73A2328E3C56485B491C299115A017C907AB54317260A593A0D7BA6D06615D6E2CA84B860EFF3CCB597211BFE36BDEF8069AFA36C5A73392722650E4957DCA597ACBA5605B63C163CFA94B64DDD62301A4332083361972589DB0599A694DD4547A5EE9196577C22ED427AC89BB8BA3753EB76C41F2C1129C8A77D6805FA719B1B6CA11B740A78A3D41B5330526AB87D58D5925315A1485EDC647C1604EB38138DE637AD2C6CA5BE44E1008B2C0867B229CCC36619E2758C4C2029EAEB26E7A803FCA305A59CD585E117D698ECE011CC3FCE54D2E114545A21AC5BE6771AB8F13122FAD295E745A503B142F91AEF7BDE99998845FDA043555C9C1EE535BE125E5DCE5D266667E723E67B6BA891C16CBA174098A3F351778B0888C9590A9090CD404"""), + xeh(""" +082411FFADCEE22B6C33277C32130E4C77CCB1849A2E7BDCE47EB519CAAACAAAA8DF129C5D876EAA7495ADED159D27F525EDD5F1F86B7A4FD50AC0B1F7B07C23F726D96F82D17818EEE6F032D0AEAD04D0F56EC244218905FD779268B259E29BAEF8BC66B42F47DC5BBFEA06620F38E0F373BA3F598CA7244A9F5B6823CA293BDACDD6D7B2E49BB2D00D1811C0F7FB2736876699D3F115C1D5AC58EBCFF10F514D863A56901F3DEE1328ACEF5D37DFEF841392BB29A88324CB51820A0CB30A4C222F7450F321B6617EEE7E722004AEBB5A52ABC3A984B8A142F0193EB90654FF86B8799EF7BDC01BBCD7C151587557334E01B833E950260C5E126C2BBF35EC030BBACFEF2812819A20960A9CA4E8D4836A7282F8F99AAC18BC02F6275582C7D1E6197938F67A80FB2363BF77A96355FA9E0AB19883CEA65A3010795E4A48A8B22FD04EC4578DA4452DC1B851C03A93AB147F3A34981515B75AB80D10A96570C2BF9ACB2E1662CF86E077EA455ED1B130D59CCA1F603A3471C408A342C42BE1AF6BA3E096E78CCF36CFCF6705078800E4E968FF372CE836AF5090E2442CF73E565146C69CBC0F55DB89BE1179CDF24DB6DD2C73371B00BD8CEC89FBBFAB3537DD0F50156FFA2D604BD135B91728DC93AAF31EBB51BCA15C02270D93051FBC0CF006C57F6BDDF5B8E60866E7A051358C4D0363ECB9A5EC3B6C745C41A3EFA2887B6B5AD8DC68E3C3FA17291D3D044D7085C6E2D3EB12FC3536CA8A6BEAC7B55BC2DD77B6F102C577B988E03AD963FF34CE4DFAF5194A05F12606D8E62FA7E20329E6630177BD60BCE780E014A856207A2745E5A22801A680CDBF0653EFC71F263E795AD7C495A90B7A5BECE0CC3F879B411A39A4346C677F53094298C0B2596DA1B136A32415E68A249161217414CC0F5F4D40614E162A3A757BDA41A80FCD17202AE062832D971FFD0A2F66D5EE94A26B1B78582E9F79F65A20D94EAC98DCC54D62B191DA89108126143E810AF6F8345723C69C009C481837FCED2408A8E37C96A248D7DDEFC7BBF73A5A91BFC10163813D22B0B26D5C6E380CCFCD6598844913""") + ) + }; + + static DecapsulateTestCase[] decap768TestCases = new DecapsulateTestCase[] { + new DecapsulateTestCase( + xeh(""" +1E4AC87B1A692A529FDBBAB93374C57D110B10F2B1DDEBAC0D196B7BA631B8E9293028A8F379888C422DC8D32BBF226010C2C1EC73189080456B0564B258B0F23131BC79C8E8C11CEF3938B243C5CE9C0EDD37C8F9D29877DBBB615B9B5AC3C948487E467196A9143EFBC7CEDB64B45D4ACDA2666CBC2804F2C8662E128F6A9969EC15BC0B9351F6F96346AA7ABC743A14FA030E37A2E7597BDDFC5A22F9CEDAF8614832527210B26F024C7F6C0DCF551E97A4858764C321D1834AD51D75BB246D277237B7BD41DC4362D063F4298292272D01011780B79856B296C4E946658B79603197C9B2A99EC66ACB06CE2F69B5A5A61E9BD06AD443CEB0C74ED65345A903B614E81368AAC2B3D2A79CA8CCAA1C3B88FB82A36632860B3F7950833FD0212EC96EDE4AB6F5A0BDA3EC6060A658F9457F6CC87C6B620C1A1451987486E496612A101D0E9C20577C571EDB5282608BF4E1AC926C0DB1C82A504A799D89885CA6252BD5B1C183AF701392A407C05B848C2A3016C40613F02A449B3C7926DA067A533116506840097510460BBFD36073DCB0BFA009B36A9123EAA68F835F74A01B00D2097835964DF521CE9210789C30B7F06E5844B444C53322396E4799BAF6A88AF7315860D0192D48C2C0DA6B5BA64325543ACDF5900E8BC477AB05820072D463AFFED097E062BD78C99D12B385131A241B708865B4190AF69EA0A64DB71448A60829369C7555198E438C9ABC310BC70101913BB12FAA5BEEF975841617C847CD6B336F877987753822020B92C4CC97055C9B1E0B128BF11F505005B6AB0E627795A20609EFA991E598B80F37B1C6A1C3A1E9AEE7028F77570AB2139128A00108C50EB305CDB8F9A603A6B078413F6F9B14C6D82B5199CE59D887902A281A027B717495FE12672A127BBF9B256C43720D7C160B281C12757DA135B1933352BE4AB67E40248AFC318E2370C3B8208E695BDF337459B9ACBFE5B487F76E9B4B4001D6CF90CA8C699A174D42972DC733F33389FDF59A1DABA81D834955027334185AD02C76CF294846CA9294BA0ED66741DDEC791CAB34196AC5657C5A78321B56C33306B5102397A5C09C3508F76B48282459F81D0C72A43F737BC2F12F45422628B67DB51AC1424276A6C08C3F7615665BBB8E928148A270F991BCF365A90F87C30687B68809C91F231813B866BEA82E30374D80AA0C02973437498A53B14BF6B6CA1ED76AB8A20D54A083F4A26B7C038D81967640C20BF4431E71DACCE8577B21240E494C31F2D877DAF4924FD39D82D6167FBCC1F9C5A259F843E30987CCC4BCE7493A2404B5E44387F707425781B743FB555685584E2557CC038B1A9B3F4043121F5472EB2B96E5941FEC011CEEA50791636C6ABC26C1377EE3B5146FC7C85CB335B1E795EEC2033EE44B9AA90685245EF7B4436C000E66BC8BCBF1CDB803AC1421B1FDB266D5291C8310373A8A3CE9562AB197953871AB99F382CC5AA9C0F273D1DCA55D2712853871E1A83CB3B85450F76D3F3C42BAB5505F7212FDB6B8B7F6029972A8F3751E4C94C1108B02D6AC79F8D938F05A1B2C229B14B42B31B01A364017E59578C6B033833774CB9B570F9086B722903B375446B495D8A29BF80751877A80FB724A0210C3E1692F397C2F1DDC2E6BA17AF81B92ACFABEF5F7573CB493D184027B718238C89A3549B8905B28A83362867C082D3019D3CA70700731CEB73E8472C1A3A093361C5FEA6A7D40955D07A41B64E50081A361B604CC518447C8E25765AB7D68B243275207AF8CA6564A4CB1E94199DBA1878C59BEC809AB48B2F211BADC6A1998D9C7227C1303F469D46A9C7E5303F98ABA67569AE8227C16BA1FB3244466A25E7F823671810CC26206FEB29C7E2A1A91959EEB03A98252A4F7412674EB9A4B277E1F2595FCA64033B41B40330812E9735B7C607501CD8183A22AFC3392553744F33C4D202526945C6D78A60E201A16987A6FA59D94464B56506556784824A07058F57320E76C825B9347F2936F4A0E5CDAA18CF8833945AE312A36B5F5A3810AAC82381FDAE4CB9C6831D8EB8ABAB850416443D739086B1C326FC2A3975704E396A59680C3B5F360F5480D2B62169CD94CA71B37BC5878BA2985E068BA050B2CE50726D4B4451B77AAA8676EAE094982210192197B1E92A27F59868B78867887B9A70C32AF84630AA908814379E6519150BA16439B5E2B0603D06AA6674557F5B0983E5CB6A97596069B01BB3128C416680657204FD07640392E16B19F337A99A304844E1AA474E9C799062971F672268960F5A82F950070BBE9C2A71950A3785BDF0B8440255ED63928D257845168B1ECCC4191325AA76645719B28EBD89302DC6723C786DF5217B243099CA78238E57E64692F206B177ABC259660395CD7860FB35A16F6B2FE6548C85AB66330C517FA74CDF3CB49D26B1181901AF775A1E180813B6A24C456829B5C38104ECE43C76A437A6A33B6FC6C5E65C8A89466C1425485B29B9E1854368AFCA353E143D0A90A6C6C9E7FDB62A606856B5614F12B64B796020C3534C3605CFDC73B86714F411850228A28B8F4B49E663416C84F7E381F6AF1071343BF9D39B45439240CC03897295FEA080B14BB2D8119A880E164495C61BEBC7139C11857C85E1750338D6343913706A507C9566464CD2837CF914D1A3C35E89B235C6AB7ED078BED234757C02EF6993D4A273CB8150528DA4D76708177E9425546C83E147039766603B30DA6268F4598A53194240A2832A3D67533B5056F9AAAC61B4B17B9A2693AA0D58891E6CC56CDD772410900C405AF20B903797C64876915C37B8487A1449CE924CD345C29A36E08238F7A157CC7E516AB5BA73C8063F726BB5A0A0319E57127438C7FC601C99CCAAE4C1A83726FDCB5045ED1A82A985EA995396D77272C66CE493289F6110910F37C2741CE47026A6F8261999C6482572B1693912EF12EEBEA7ACF9234FB409F2A6090E6B0BFD895469D0B2A921BB723F87A33EA5465AB90F514B67698C0768B6CA498B022C512FA0875F054AA2265867E31C0E522651E024A07D60DD9F633166921F4126BC2B6AA01CC15A09B85BFF8218C5AAE95BC1FFB26AE5A137670F04910CA9D7241B6660C394C5455917746A26682FB71A432EA9530E839BDEB07433004F45A0DDAA0B24E3A566A540815F281E3FC259AC6CBC0ACB8D62268B603BC676AB415C474BB94873E4487AE31A4E3845C79901550890EE8784EEF904FEE62BA8C5F952C68413052E0A7E3388BB8FF0AD602AE3EA14D9DF6DD5E4CC6A381A41DA5C137ECC49DF587E178EAF47702EC623780691A3233F69F12BD9C9B9637C51378AD71A831055277254CC63C5AD4CB76B4AB82E5FCA135E8D26A6B3A89FA5B6F"""), + xeh(""" +74A26C7D27146A22C7EAB420134E973799CEC1DA2DF61AE0FA7905A3A47485A063076BFA22D6E4FE5059DE0A32E38F11ABD63F990E91BD0E3A5BC6E710DFE5DC0F6D4A18147EBC2E2D9B179374D83692C53EFBD45F28A2A928C2494F903576C410EB1773895EBEADB119960EEBDA9C3C710795A6D9B781FC58B30D08107F4E20944A382AFB079F31D21724F2C26E6A53412F0A908BE7586F2B3D6D7C1DEA0270E98AA209244BD88ED68AAE01432342BA5F49E015CB476B5B78D15EA77A354CC9E9FD07137D8760BE42FD4746C62C02028E7B405DDC95DF3D021921CFEDDB3D961B957ECA302A263DAB2DC117BEB3E79EFACFCF936DFC09FC0D19C358D724FA381EA06CA067C384E944302C3907AB15A1DA4B41352692ADD59B061541F07EFF25EC42F46E1A0E370CAD06FF3FD997D4D2C5648AF762231B382D0593401936CBA21551A2AE30D8E8EFFCF43916B83138BB5E610364429879FA9CDD5B7D3CF2FEABAA1DC8D50CE69402E21103E795DF7074D1FCF65F8A4E18986D5417780602C63BE5A044863384BD3D8FFB685EAC567ED8349DCF2CEB702B7375B145729998049D13E2CD466CF2231B9D3A20018EE908F8514A6C6A89DF7232F91FCD84B81EBC8BC539E9A37A4324755564BE1BF4FA1FB4571E0ABBC9B52F9D090C33BE599DE6C8532C7CB7EC8B4E2D3C07505280E99923865903FFD18BC13B9C8164AA1EAE84E38D3F57FDB8801785F105A6A8574BD2FE9BF305848E525330BC2D24F0257E47A4950F433A9233E8CDEBA81DBAE7D8C1A06D01F70DE6EF663207D84952827BAB3D451CBEA0990007FBDB4240FE899A706F7C1563E05C70BE9D575189EF83E0CF76195F6652491CCE04F1CE2092170A92E0DD7301246A4C44FC0B4EE6AAA63FC7027840ABD2EC25F654589738CD38B9E10B975CFB6C1D2EB4DA97736998F84FDDDD810D72DA3C5AB13507420DDBFAA4F7750C1FAE9C7DFB30F40A12AEA689FC78DA900020E3ABB32A364D5C6B3C7544A1B5734A41E95C8314B448CD0B738D829AF772A8F81C51ADBA2D85F326C8F5D6961CF12D44A9BEDEA00D1DF5B48F429B1CE0C15EA5F5BC10B017247BA2C6BE922B0563B8E9698677CB6C45CCF2081BF84219D2904C11FF92199F8AEFAD62D8608E200802C5A07202CC820E9E520E31BF36A83002ECA4018B0B3A398801562AA86C77AB0D50A8FBC3768B0A643B97E7F9072168DE29B8175999C9AA48D301A3F0303172E9C7D4F16329D5CA9D42397C3982E10C9DA42DE88BD6C2AB91C1E71E778E58BB8F801F207A88A9B47F9C687AFBBA34EDA6D2899E4FA0008AA2B539711753DC7C07F614E814F683D6C037562AE1FBBE6D7D5FA54B7A6D9451E11B01AACCC3BF2ED64742DD100E0EAB2DF6CCCF937B6D5981ECA0E01F3245CF26A72AD1ADF066C8F5430D72F509963A657D85E554C14E26E8BEC5D5F3AB998C9B29F16B04747D80749B30E51FD2A7F690C22F9986AAF6358D6FAB8DED54971B32641DE2B258590EEAA6BF1F32324A7C4C983F49466D86""") + ), + new DecapsulateTestCase( + xeh(""" +1E4AC87B1A692A529FDBBAB93374C57D110B10F2B1DDEBAC0D196B7BA631B8E9293028A8F379888C422DC8D32BBF226010C2C1EC73189080456B0564B258B0F23131BC79C8E8C11CEF3938B243C5CE9C0EDD37C8F9D29877DBBB615B9B5AC3C948487E467196A9143EFBC7CEDB64B45D4ACDA2666CBC2804F2C8662E128F6A9969EC15BC0B9351F6F96346AA7ABC743A14FA030E37A2E7597BDDFC5A22F9CEDAF8614832527210B26F024C7F6C0DCF551E97A4858764C321D1834AD51D75BB246D277237B7BD41DC4362D063F4298292272D01011780B79856B296C4E946658B79603197C9B2A99EC66ACB06CE2F69B5A5A61E9BD06AD443CEB0C74ED65345A903B614E81368AAC2B3D2A79CA8CCAA1C3B88FB82A36632860B3F7950833FD0212EC96EDE4AB6F5A0BDA3EC6060A658F9457F6CC87C6B620C1A1451987486E496612A101D0E9C20577C571EDB5282608BF4E1AC926C0DB1C82A504A799D89885CA6252BD5B1C183AF701392A407C05B848C2A3016C40613F02A449B3C7926DA067A533116506840097510460BBFD36073DCB0BFA009B36A9123EAA68F835F74A01B00D2097835964DF521CE9210789C30B7F06E5844B444C53322396E4799BAF6A88AF7315860D0192D48C2C0DA6B5BA64325543ACDF5900E8BC477AB05820072D463AFFED097E062BD78C99D12B385131A241B708865B4190AF69EA0A64DB71448A60829369C7555198E438C9ABC310BC70101913BB12FAA5BEEF975841617C847CD6B336F877987753822020B92C4CC97055C9B1E0B128BF11F505005B6AB0E627795A20609EFA991E598B80F37B1C6A1C3A1E9AEE7028F77570AB2139128A00108C50EB305CDB8F9A603A6B078413F6F9B14C6D82B5199CE59D887902A281A027B717495FE12672A127BBF9B256C43720D7C160B281C12757DA135B1933352BE4AB67E40248AFC318E2370C3B8208E695BDF337459B9ACBFE5B487F76E9B4B4001D6CF90CA8C699A174D42972DC733F33389FDF59A1DABA81D834955027334185AD02C76CF294846CA9294BA0ED66741DDEC791CAB34196AC5657C5A78321B56C33306B5102397A5C09C3508F76B48282459F81D0C72A43F737BC2F12F45422628B67DB51AC1424276A6C08C3F7615665BBB8E928148A270F991BCF365A90F87C30687B68809C91F231813B866BEA82E30374D80AA0C02973437498A53B14BF6B6CA1ED76AB8A20D54A083F4A26B7C038D81967640C20BF4431E71DACCE8577B21240E494C31F2D877DAF4924FD39D82D6167FBCC1F9C5A259F843E30987CCC4BCE7493A2404B5E44387F707425781B743FB555685584E2557CC038B1A9B3F4043121F5472EB2B96E5941FEC011CEEA50791636C6ABC26C1377EE3B5146FC7C85CB335B1E795EEC2033EE44B9AA90685245EF7B4436C000E66BC8BCBF1CDB803AC1421B1FDB266D5291C8310373A8A3CE9562AB197953871AB99F382CC5AA9C0F273D1DCA55D2712853871E1A83CB3B85450F76D3F3C42BAB5505F7212FDB6B8B7F6029972A8F3751E4C94C1108B02D6AC79F8D938F05A1B2C229B14B42B31B01A364017E59578C6B033833774CB9B570F9086B722903B375446B495D8A29BF80751877A80FB724A0210C3E1692F397C2F1DDC2E6BA17AF81B92ACFABEF5F7573CB493D184027B718238C89A3549B8905B28A83362867C082D3019D3CA70700731CEB73E8472C1A3A093361C5FEA6A7D40955D07A41B64E50081A361B604CC518447C8E25765AB7D68B243275207AF8CA6564A4CB1E94199DBA1878C59BEC809AB48B2F211BADC6A1998D9C7227C1303F469D46A9C7E5303F98ABA67569AE8227C16BA1FB3244466A25E7F823671810CC26206FEB29C7E2A1A91959EEB03A98252A4F7412674EB9A4B277E1F2595FCA64033B41B40330812E9735B7C607501CD8183A22AFC3392553744F33C4D202526945C6D78A60E201A16987A6FA59D94464B56506556784824A07058F57320E76C825B9347F2936F4A0E5CDAA18CF8833945AE312A36B5F5A3810AAC82381FDAE4CB9C6831D8EB8ABAB850416443D739086B1C326FC2A3975704E396A59680C3B5F360F5480D2B62169CD94CA71B37BC5878BA2985E068BA050B2CE50726D4B4451B77AAA8676EAE094982210192197B1E92A27F59868B78867887B9A70C32AF84630AA908814379E6519150BA16439B5E2B0603D06AA6674557F5B0983E5CB6A97596069B01BB3128C416680657204FD07640392E16B19F337A99A304844E1AA474E9C799062971F672268960F5A82F950070BBE9C2A71950A3785BDF0B8440255ED63928D257845168B1ECCC4191325AA76645719B28EBD89302DC6723C786DF5217B243099CA78238E57E64692F206B177ABC259660395CD7860FB35A16F6B2FE6548C85AB66330C517FA74CDF3CB49D26B1181901AF775A1E180813B6A24C456829B5C38104ECE43C76A437A6A33B6FC6C5E65C8A89466C1425485B29B9E1854368AFCA353E143D0A90A6C6C9E7FDB62A606856B5614F12B64B796020C3534C3605CFDC73B86714F411850228A28B8F4B49E663416C84F7E381F6AF1071343BF9D39B45439240CC03897295FEA080B14BB2D8119A880E164495C61BEBC7139C11857C85E1750338D6343913706A507C9566464CD2837CF914D1A3C35E89B235C6AB7ED078BED234757C02EF6993D4A273CB8150528DA4D76708177E9425546C83E147039766603B30DA6268F4598A53194240A2832A3D67533B5056F9AAAC61B4B17B9A2693AA0D58891E6CC56CDD772410900C405AF20B903797C64876915C37B8487A1449CE924CD345C29A36E08238F7A157CC7E516AB5BA73C8063F726BB5A0A0319E57127438C7FC601C99CCAAE4C1A83726FDCB5045ED1A82A985EA995396D77272C66CE493289F6110910F37C2741CE47026A6F8261999C6482572B1693912EF12EEBEA7ACF9234FB409F2A6090E6B0BFD895469D0B2A921BB723F87A33EA5465AB90F514B67698C0768B6CA498B022C512FA0875F054AA2265867E31C0E522651E024A07D60DD9F633166921F4126BC2B6AA01CC15A09B85BFF8218C5AAE95BC1FFB26AE5A137670F04910CA9D7241B6660C394C5455917746A26682FB71A432EA9530E839BDEB07433004F45A0DDAA0B24E3A566A540815F281E3FC259AC6CBC0ACB8D62268B603BC676AB415C474BB94873E4487AE31A4E3845C79901550890EE8784EEF904FEE62BA8C5F952C68413052E0A7E3388BB8FF0AD602AE3EA14D9DF6DD5E4CC6A381A41DA5C137ECC49DF587E178EAF47702EC623780691A3233F69F12BD9C9B9637C51378AD71A831055277254CC63C5AD4CB76B4AB82E5FCA135E8D26A6B3A89FA5B6F"""), + xeh(""" +39EFB90089F1DC32A54370B3EEDF2B12880DC7D657F0404E41F7DAAA73E7F06CB90BBEEC7544160768EC3B56681D057AE1DB58F0123286D3A8CDD0B414CF9894FDA1CFF3A37CF67B82C5C7AD3427F2F2B393978B94E524F33334E4A98AFFEA8D7514D6E12E85086E58A0C078EBA64435441F3E3702EA27EEA984E46893BB886572491F22AE09F8D50774B4DDD5CF478CB0B2D070437E86645EF62AA83599093732F81A75D1D5DE15C31EC81AC4D67852FDE089D580B71E3DB07C71394424E0936BF74D0C9405BD3DFB60B920E7EFA38C72D5912BBD301BD3F3709CBEEEB7BFD0767B77A8639913E8C228FBB7E3E13C423BF05AC65B7E75F29C9048F161AF1B4B41C495ADB53FECC57FED0DCF792050A2A586C33AA4A7F6BCDA9068EA295FB692BDCA756FCC47CA0A8C84DB5DCB6A616605F3D3A34C4D23EC14942492C07EF123C8D084DF21F3B2141D277FA16E3CF4D5A3AB8D78CE8370F411DF737647A2D6123120AEE1CCF7DEFC35A5408FA6013E94703E8E04C50BADCBBF2E1FF0FB82DB4AAC595B9EAA9E370C9C6175CEF20B1D0B8A4309AB91918451E6C8A6DF04AE468D446FD9E83F9252F145A2B44A19E7B27DA56044717DB5A6ED5F6E5CDD90208ABC324290292B1F2E84FB69F5989D9921DCB4F058DCAF7B99DF71B26BD1090E457767954B8ACC84FDDFD663D64027528077B3C9E370600942E4C1175B487FBF25E267474B5238576010CCCE3315CEDD5634658B2028F3FB9959D77FA23756DB4878697C9BC491DBD68986B9073D187F2A9E72C943D94C97DA865CFD9C23508105637FED62E56E745555909A49D23B86E620D48FD55A92CC2266C38B857F5DF9BB683D60B084819CF04F5BB8CBED05AC6F48C518EDB5B222F5E6DCBB438182A7BA3B2279E5856828CBE9BDA6009A70D20DA082D2FFBD092EDAD4B272E46D215B8ECC26222499F024327A391CEB007789757FF8FA8267429F0534F305F75709DCC4229803EA8E612F55890C5FDF8252794D5C9C4058C2258A5599BA858A02F89A6FDB35C4F2364A4C6B326A31F7D04F62C2FAFE51D280CD7A4CAB66404FDFD033EADD07974BCAA7F0CB7401B9484DAF9F325B6BA53FBF41219384B264F24AA8D65281693295E6F71FCA885F808026829A3FC32DC9603F0CED36F0B58A296B44ADDA3AAF10638C31F354D1A5AC34E77D4D0154C9546709E920258F73E039FBC223EE74A270840165F64E3051B10B5E63F9ACCF5D1EF40E43F5823B15F8C25CAFCE698A64F9AE316D3905B8E510C56CF7544CA94719735A640F2B8C3A2B828A04E0568863937595E5B9DADA33533D9D676AA657FE69152E93159A00C5962F4DFF9C901A9AB32DB28B93F4BA780E44A2F73878AA76E112E3490205AF83000EFD889FCEEA5E87AE9AE01EE1CCF6BA0461A8D8654B7702C09BB41C4F61A00D05F031B244EDED8D1CAC7916BEB9AA67A3880F4C3516A8D8204932EA00EFB3AA20369FB6BE404843C7411E88428568AB9A39124EAD115298D49C998651E5EF613A6819336683""") + ), + new DecapsulateTestCase( + xeh(""" +1E4AC87B1A692A529FDBBAB93374C57D110B10F2B1DDEBAC0D196B7BA631B8E9293028A8F379888C422DC8D32BBF226010C2C1EC73189080456B0564B258B0F23131BC79C8E8C11CEF3938B243C5CE9C0EDD37C8F9D29877DBBB615B9B5AC3C948487E467196A9143EFBC7CEDB64B45D4ACDA2666CBC2804F2C8662E128F6A9969EC15BC0B9351F6F96346AA7ABC743A14FA030E37A2E7597BDDFC5A22F9CEDAF8614832527210B26F024C7F6C0DCF551E97A4858764C321D1834AD51D75BB246D277237B7BD41DC4362D063F4298292272D01011780B79856B296C4E946658B79603197C9B2A99EC66ACB06CE2F69B5A5A61E9BD06AD443CEB0C74ED65345A903B614E81368AAC2B3D2A79CA8CCAA1C3B88FB82A36632860B3F7950833FD0212EC96EDE4AB6F5A0BDA3EC6060A658F9457F6CC87C6B620C1A1451987486E496612A101D0E9C20577C571EDB5282608BF4E1AC926C0DB1C82A504A799D89885CA6252BD5B1C183AF701392A407C05B848C2A3016C40613F02A449B3C7926DA067A533116506840097510460BBFD36073DCB0BFA009B36A9123EAA68F835F74A01B00D2097835964DF521CE9210789C30B7F06E5844B444C53322396E4799BAF6A88AF7315860D0192D48C2C0DA6B5BA64325543ACDF5900E8BC477AB05820072D463AFFED097E062BD78C99D12B385131A241B708865B4190AF69EA0A64DB71448A60829369C7555198E438C9ABC310BC70101913BB12FAA5BEEF975841617C847CD6B336F877987753822020B92C4CC97055C9B1E0B128BF11F505005B6AB0E627795A20609EFA991E598B80F37B1C6A1C3A1E9AEE7028F77570AB2139128A00108C50EB305CDB8F9A603A6B078413F6F9B14C6D82B5199CE59D887902A281A027B717495FE12672A127BBF9B256C43720D7C160B281C12757DA135B1933352BE4AB67E40248AFC318E2370C3B8208E695BDF337459B9ACBFE5B487F76E9B4B4001D6CF90CA8C699A174D42972DC733F33389FDF59A1DABA81D834955027334185AD02C76CF294846CA9294BA0ED66741DDEC791CAB34196AC5657C5A78321B56C33306B5102397A5C09C3508F76B48282459F81D0C72A43F737BC2F12F45422628B67DB51AC1424276A6C08C3F7615665BBB8E928148A270F991BCF365A90F87C30687B68809C91F231813B866BEA82E30374D80AA0C02973437498A53B14BF6B6CA1ED76AB8A20D54A083F4A26B7C038D81967640C20BF4431E71DACCE8577B21240E494C31F2D877DAF4924FD39D82D6167FBCC1F9C5A259F843E30987CCC4BCE7493A2404B5E44387F707425781B743FB555685584E2557CC038B1A9B3F4043121F5472EB2B96E5941FEC011CEEA50791636C6ABC26C1377EE3B5146FC7C85CB335B1E795EEC2033EE44B9AA90685245EF7B4436C000E66BC8BCBF1CDB803AC1421B1FDB266D5291C8310373A8A3CE9562AB197953871AB99F382CC5AA9C0F273D1DCA55D2712853871E1A83CB3B85450F76D3F3C42BAB5505F7212FDB6B8B7F6029972A8F3751E4C94C1108B02D6AC79F8D938F05A1B2C229B14B42B31B01A364017E59578C6B033833774CB9B570F9086B722903B375446B495D8A29BF80751877A80FB724A0210C3E1692F397C2F1DDC2E6BA17AF81B92ACFABEF5F7573CB493D184027B718238C89A3549B8905B28A83362867C082D3019D3CA70700731CEB73E8472C1A3A093361C5FEA6A7D40955D07A41B64E50081A361B604CC518447C8E25765AB7D68B243275207AF8CA6564A4CB1E94199DBA1878C59BEC809AB48B2F211BADC6A1998D9C7227C1303F469D46A9C7E5303F98ABA67569AE8227C16BA1FB3244466A25E7F823671810CC26206FEB29C7E2A1A91959EEB03A98252A4F7412674EB9A4B277E1F2595FCA64033B41B40330812E9735B7C607501CD8183A22AFC3392553744F33C4D202526945C6D78A60E201A16987A6FA59D94464B56506556784824A07058F57320E76C825B9347F2936F4A0E5CDAA18CF8833945AE312A36B5F5A3810AAC82381FDAE4CB9C6831D8EB8ABAB850416443D739086B1C326FC2A3975704E396A59680C3B5F360F5480D2B62169CD94CA71B37BC5878BA2985E068BA050B2CE50726D4B4451B77AAA8676EAE094982210192197B1E92A27F59868B78867887B9A70C32AF84630AA908814379E6519150BA16439B5E2B0603D06AA6674557F5B0983E5CB6A97596069B01BB3128C416680657204FD07640392E16B19F337A99A304844E1AA474E9C799062971F672268960F5A82F950070BBE9C2A71950A3785BDF0B8440255ED63928D257845168B1ECCC4191325AA76645719B28EBD89302DC6723C786DF5217B243099CA78238E57E64692F206B177ABC259660395CD7860FB35A16F6B2FE6548C85AB66330C517FA74CDF3CB49D26B1181901AF775A1E180813B6A24C456829B5C38104ECE43C76A437A6A33B6FC6C5E65C8A89466C1425485B29B9E1854368AFCA353E143D0A90A6C6C9E7FDB62A606856B5614F12B64B796020C3534C3605CFDC73B86714F411850228A28B8F4B49E663416C84F7E381F6AF1071343BF9D39B45439240CC03897295FEA080B14BB2D8119A880E164495C61BEBC7139C11857C85E1750338D6343913706A507C9566464CD2837CF914D1A3C35E89B235C6AB7ED078BED234757C02EF6993D4A273CB8150528DA4D76708177E9425546C83E147039766603B30DA6268F4598A53194240A2832A3D67533B5056F9AAAC61B4B17B9A2693AA0D58891E6CC56CDD772410900C405AF20B903797C64876915C37B8487A1449CE924CD345C29A36E08238F7A157CC7E516AB5BA73C8063F726BB5A0A0319E57127438C7FC601C99CCAAE4C1A83726FDCB5045ED1A82A985EA995396D77272C66CE493289F6110910F37C2741CE47026A6F8261999C6482572B1693912EF12EEBEA7ACF9234FB409F2A6090E6B0BFD895469D0B2A921BB723F87A33EA5465AB90F514B67698C0768B6CA498B022C512FA0875F054AA2265867E31C0E522651E024A07D60DD9F633166921F4126BC2B6AA01CC15A09B85BFF8218C5AAE95BC1FFB26AE5A137670F04910CA9D7241B6660C394C5455917746A26682FB71A432EA9530E839BDEB07433004F45A0DDAA0B24E3A566A540815F281E3FC259AC6CBC0ACB8D62268B603BC676AB415C474BB94873E4487AE31A4E3845C79901550890EE8784EEF904FEE62BA8C5F952C68413052E0A7E3388BB8FF0AD602AE3EA14D9DF6DD5E4CC6A381A41DA5C137ECC49DF587E178EAF47702EC623780691A3233F69F12BD9C9B9637C51378AD71A831055277254CC63C5AD4CB76B4AB82E5FCA135E8D26A6B3A89FA5B6F"""), + xeh(""" +A5C81C76C24305E1CE5D8135D41523682E9EE6D7B40AD41DF1F37C9B17DCE78076019A6B0B7C95C9BE7AF29507B2D5A6987C8EE3259190855243E6E56F5620608C52D96FAB103A8700FBA1A87DCA6078118A0871762C9534C0C0C3978C91C3A01F0F608DCF757815438FE8957C8A859183B1B6721A0865BEBC799D4E5C0E7BD3EAE4858E6AB6A2E7658ED80D4ED158B036B93FA03AFA6AE3136CF3D693C911BCC75905E5B0CB2865B9E9884522A77777613E53111D5A1C7D3DAB734CEB03657AE0C89763E99471054776BAE7D51B0E73A5BB35AEC30FF6BC93684916FEF1162586452F426653E2CA844D5744307FF9AEB287A6447783B21A0E939C81421D631F5DCB452E51ED34E3DAD1CF504E0A3B0F4711A8DC6499D1691D109569336CE1558A4C0A464E2087EA8F9E3B18F747EF61F4576AEB42B17CADB7F0FD84DA8E3A6F471D95EDFA65BE9E6C9F6AE756A22A4F1A5C543C26BA7BAD88E16D5F5B7E12E2D4CA34B3A64D17F87CCFC4FF8C5E4F53752A077C68721E8CC817F9FF24876170FF2AF89FA95855A5B1DE347C07FDDBCFE7264AA5ED6401491561D831538F852B0ED7B9E8EBAFFC060284F22D2BAEE56FA9F6D01432A115A2D6A64C38AE0A50BA362FB57B53E3E855B83CE8C42274045599F65FA6A8921D85F94ED230B516712DB6FD2FF28B3A3371D9BE058AE75C2FA591B7EC3C3DAA1F7642BC26C324C08090607E6662154DB37CF747967A1F9FC29089F570EBE60EEEF89FD24481028C85AEF1DC3B09F22CD3691BBBB821C7A8A0F35AD12BE1DD199B977048F3D48C16BB2CA94CECB8928770D5BB329A0327E0B286FAA1C65281031A31C84F2EDC9C04D475ED4E128E51EFA97D0148CBA6C95F674C589F301C265BED708E9AD8DA3C5CECBDEEED35EF1E253132BA89920D786B88230B013BCF2DC92D6B157AFA8DA8592CD0743D4982BE60D7C2D5C472AB9FA7F4CC3D12B0EBAF0ABE555C75805426844DD9428643F84406A1B8D6FAEDFD8AE6E73A72772A2159ACABD972AEB6F7DE091AC5FDD7F49A3DC6641CDF62446B4B04A31F73B80A62F80A404A8CB18CE3E65480EF7B52BF0091117E5D08EAE1B0AABB72E6DFFFF76F6E44BBD7EA570D6604BC2E74318BAFA315A38861AA1B21AFB2A53F2614F1D640075984AE62E2FCA1D1B4DB369F15705CE7D4DF8AE98264501051C0DEF21D645D49625AF02CA428D9F0C2CD9FBAEEAB97E8E9151662B6992B4C99AB1B925D08920363373F76D3FDF0828CAA69C8B1BDC6F521DF641CF1C8A4E7EF0C23289A4E2CF18ACEBBE4C1E68369BD5235120142ECDD1A73811E2E533A647D7AEE16DAA03B683639DCF1E1F1E71CFAED48F69AEC3E831733DA19CEBEC1DDBF71CBAE0800F2F6D64A096EC495D62F4344F7AA5621B322353A795AA099EA3A070272D053D4653A20CF210EAAF12CAE6023D8E5118DF04B384A44D1EDB91C44989EF7EE57F2BF81A24BDC76807DA967EE6525410C5C485067EFC3D39A9AD42CC753BAA59A1FD28AF35C00D18A406A28FC79BA""") + ), + new DecapsulateTestCase( + xeh(""" +1E4AC87B1A692A529FDBBAB93374C57D110B10F2B1DDEBAC0D196B7BA631B8E9293028A8F379888C422DC8D32BBF226010C2C1EC73189080456B0564B258B0F23131BC79C8E8C11CEF3938B243C5CE9C0EDD37C8F9D29877DBBB615B9B5AC3C948487E467196A9143EFBC7CEDB64B45D4ACDA2666CBC2804F2C8662E128F6A9969EC15BC0B9351F6F96346AA7ABC743A14FA030E37A2E7597BDDFC5A22F9CEDAF8614832527210B26F024C7F6C0DCF551E97A4858764C321D1834AD51D75BB246D277237B7BD41DC4362D063F4298292272D01011780B79856B296C4E946658B79603197C9B2A99EC66ACB06CE2F69B5A5A61E9BD06AD443CEB0C74ED65345A903B614E81368AAC2B3D2A79CA8CCAA1C3B88FB82A36632860B3F7950833FD0212EC96EDE4AB6F5A0BDA3EC6060A658F9457F6CC87C6B620C1A1451987486E496612A101D0E9C20577C571EDB5282608BF4E1AC926C0DB1C82A504A799D89885CA6252BD5B1C183AF701392A407C05B848C2A3016C40613F02A449B3C7926DA067A533116506840097510460BBFD36073DCB0BFA009B36A9123EAA68F835F74A01B00D2097835964DF521CE9210789C30B7F06E5844B444C53322396E4799BAF6A88AF7315860D0192D48C2C0DA6B5BA64325543ACDF5900E8BC477AB05820072D463AFFED097E062BD78C99D12B385131A241B708865B4190AF69EA0A64DB71448A60829369C7555198E438C9ABC310BC70101913BB12FAA5BEEF975841617C847CD6B336F877987753822020B92C4CC97055C9B1E0B128BF11F505005B6AB0E627795A20609EFA991E598B80F37B1C6A1C3A1E9AEE7028F77570AB2139128A00108C50EB305CDB8F9A603A6B078413F6F9B14C6D82B5199CE59D887902A281A027B717495FE12672A127BBF9B256C43720D7C160B281C12757DA135B1933352BE4AB67E40248AFC318E2370C3B8208E695BDF337459B9ACBFE5B487F76E9B4B4001D6CF90CA8C699A174D42972DC733F33389FDF59A1DABA81D834955027334185AD02C76CF294846CA9294BA0ED66741DDEC791CAB34196AC5657C5A78321B56C33306B5102397A5C09C3508F76B48282459F81D0C72A43F737BC2F12F45422628B67DB51AC1424276A6C08C3F7615665BBB8E928148A270F991BCF365A90F87C30687B68809C91F231813B866BEA82E30374D80AA0C02973437498A53B14BF6B6CA1ED76AB8A20D54A083F4A26B7C038D81967640C20BF4431E71DACCE8577B21240E494C31F2D877DAF4924FD39D82D6167FBCC1F9C5A259F843E30987CCC4BCE7493A2404B5E44387F707425781B743FB555685584E2557CC038B1A9B3F4043121F5472EB2B96E5941FEC011CEEA50791636C6ABC26C1377EE3B5146FC7C85CB335B1E795EEC2033EE44B9AA90685245EF7B4436C000E66BC8BCBF1CDB803AC1421B1FDB266D5291C8310373A8A3CE9562AB197953871AB99F382CC5AA9C0F273D1DCA55D2712853871E1A83CB3B85450F76D3F3C42BAB5505F7212FDB6B8B7F6029972A8F3751E4C94C1108B02D6AC79F8D938F05A1B2C229B14B42B31B01A364017E59578C6B033833774CB9B570F9086B722903B375446B495D8A29BF80751877A80FB724A0210C3E1692F397C2F1DDC2E6BA17AF81B92ACFABEF5F7573CB493D184027B718238C89A3549B8905B28A83362867C082D3019D3CA70700731CEB73E8472C1A3A093361C5FEA6A7D40955D07A41B64E50081A361B604CC518447C8E25765AB7D68B243275207AF8CA6564A4CB1E94199DBA1878C59BEC809AB48B2F211BADC6A1998D9C7227C1303F469D46A9C7E5303F98ABA67569AE8227C16BA1FB3244466A25E7F823671810CC26206FEB29C7E2A1A91959EEB03A98252A4F7412674EB9A4B277E1F2595FCA64033B41B40330812E9735B7C607501CD8183A22AFC3392553744F33C4D202526945C6D78A60E201A16987A6FA59D94464B56506556784824A07058F57320E76C825B9347F2936F4A0E5CDAA18CF8833945AE312A36B5F5A3810AAC82381FDAE4CB9C6831D8EB8ABAB850416443D739086B1C326FC2A3975704E396A59680C3B5F360F5480D2B62169CD94CA71B37BC5878BA2985E068BA050B2CE50726D4B4451B77AAA8676EAE094982210192197B1E92A27F59868B78867887B9A70C32AF84630AA908814379E6519150BA16439B5E2B0603D06AA6674557F5B0983E5CB6A97596069B01BB3128C416680657204FD07640392E16B19F337A99A304844E1AA474E9C799062971F672268960F5A82F950070BBE9C2A71950A3785BDF0B8440255ED63928D257845168B1ECCC4191325AA76645719B28EBD89302DC6723C786DF5217B243099CA78238E57E64692F206B177ABC259660395CD7860FB35A16F6B2FE6548C85AB66330C517FA74CDF3CB49D26B1181901AF775A1E180813B6A24C456829B5C38104ECE43C76A437A6A33B6FC6C5E65C8A89466C1425485B29B9E1854368AFCA353E143D0A90A6C6C9E7FDB62A606856B5614F12B64B796020C3534C3605CFDC73B86714F411850228A28B8F4B49E663416C84F7E381F6AF1071343BF9D39B45439240CC03897295FEA080B14BB2D8119A880E164495C61BEBC7139C11857C85E1750338D6343913706A507C9566464CD2837CF914D1A3C35E89B235C6AB7ED078BED234757C02EF6993D4A273CB8150528DA4D76708177E9425546C83E147039766603B30DA6268F4598A53194240A2832A3D67533B5056F9AAAC61B4B17B9A2693AA0D58891E6CC56CDD772410900C405AF20B903797C64876915C37B8487A1449CE924CD345C29A36E08238F7A157CC7E516AB5BA73C8063F726BB5A0A0319E57127438C7FC601C99CCAAE4C1A83726FDCB5045ED1A82A985EA995396D77272C66CE493289F6110910F37C2741CE47026A6F8261999C6482572B1693912EF12EEBEA7ACF9234FB409F2A6090E6B0BFD895469D0B2A921BB723F87A33EA5465AB90F514B67698C0768B6CA498B022C512FA0875F054AA2265867E31C0E522651E024A07D60DD9F633166921F4126BC2B6AA01CC15A09B85BFF8218C5AAE95BC1FFB26AE5A137670F04910CA9D7241B6660C394C5455917746A26682FB71A432EA9530E839BDEB07433004F45A0DDAA0B24E3A566A540815F281E3FC259AC6CBC0ACB8D62268B603BC676AB415C474BB94873E4487AE31A4E3845C79901550890EE8784EEF904FEE62BA8C5F952C68413052E0A7E3388BB8FF0AD602AE3EA14D9DF6DD5E4CC6A381A41DA5C137ECC49DF587E178EAF47702EC623780691A3233F69F12BD9C9B9637C51378AD71A831055277254CC63C5AD4CB76B4AB82E5FCA135E8D26A6B3A89FA5B6F"""), + xeh(""" +0BAF0F6E91ECAE3199F4921631891A14C13B418B53384992DA3A8DADA7DEFFB9E1E5F559D27344B60BE81ECD01CAB1E316573D571ED46F59248F4023DB0282207E730549CDB60E793E4CD17AC6F2800E2D1FFB83477A6FE1D73992682123EA730C63269DB13088D6DA46D086CCEA2176398EAC663270B8B2F337A55E19F4C500DE066B5441794C2D0CCADFE5ABDE7D93FD7D6468BC4F925633366D9316788B90B110A4D99485E7E578537A267744FB266A4F243FA02E3A81DA67ED477923B36B37BE21DDA21EB51DCA1F0CE41652145F4C542B2E5C922617033608246BBE2B5250A368804ABDB2EF6C31C491CE3DD852AEABF6EEF1530F4C99286B4B595D57CF3A99580B59AAA2C55E080B5230EA19CF2701D21A37FEFD6F9709657A21ADD063ECBC197B5AD068BE502A2E090D83F4156B671E46617BE6D6A17D0425FAC565C4A0E48966E9D900CB2C2B0D296E0BAA9D6C5E0514CD78834053058A97D3DDF81529079858737440812670E818C9891681D350ECEC93DAE389D534A5C78F01811917061CAC0003D2BEA390EB63FA0FE9BABCD7FF302D4B66567B2BFA67B20F962847D010AA4193CBE9F8CC1B14F8B237C22675B298A8376DFB6037BF7CEA36BDEAD5B505111F67730824B4964815D00F63EE98B9BEA0F2F47CC007D5606ED7F967CB15CCD4AFBC99881CFD297BDC2A509ED3CB320DF58DC4A5BCD1CB100B9D6418CB8E0F40DEF293DA2370CA729B0FAB071FA6AEB0F3F5D1925AB2DF732F98DDBFF23D5411E4921A1C506F2F93251E822C4CF83998B000FE65ED386F5745B1D4D91AD9F98B45E713C8D944409E9D354F42FDB9749A5107C8831562E683498C55E1475E552AC10858AB9867BF8003FB88B3B09F6E8AD8E94CE82E342B1780D68EC8565FC0684AB6C798BF09FA65BE62C37A0862ABFE99D7DBE1431B4CFE007B7EC7930B14F6D161BDCAAE2217D69D9FDBB4F882B9F464F8642ACD9BA018B93A8E3A965194ACCD96E661CF0CF4A2662076E20E8BC319693F1953DAB93FEB9BCAD666832DF42F250FADBCFAF742D68642021BD6FFD97720C3E5AB86D82CE8B14C0289DBF51B50C13CFCEC12A3922DCD2DE8473329AEB23580B22F9C36B4F06D6579751BE0593120F808F0E145D94D1DDBBE1D489B744CF6C35964C3DD96D95FB693543C69766877DA80BDE8ACDF62C366D0A4A553187461F671376F7E70F554965D57760CDF5C6F6366E33B3BFB550CC1F93D98D250F90D7D36BC01581C49417546BF6BBA9D10D41C0A008855F321547BDD5A6CFA2A2516F71415B5BC2D5FA1B9B79FDC7F2B78AA113375EC1717F0F273BD8CBEF59139518A4E8A67DB4D071257000336BB07497F72FAAC2C1FC0F553B2EBA53475F466A2B36AFE0B72B4342E995C544E6E14FF7D327F80E7AC6F65190045F380B5978F50E33272484626266125A39DA08B46256624CE34223BB17299B8B8162753812F2644C9A13C51430B02ABD188DD1A4547C920BA27CDAF145BDEBC6F45EEE3F2F55553010F7B35AC63A3C7C61C""") + ), + new DecapsulateTestCase( + xeh(""" +1E4AC87B1A692A529FDBBAB93374C57D110B10F2B1DDEBAC0D196B7BA631B8E9293028A8F379888C422DC8D32BBF226010C2C1EC73189080456B0564B258B0F23131BC79C8E8C11CEF3938B243C5CE9C0EDD37C8F9D29877DBBB615B9B5AC3C948487E467196A9143EFBC7CEDB64B45D4ACDA2666CBC2804F2C8662E128F6A9969EC15BC0B9351F6F96346AA7ABC743A14FA030E37A2E7597BDDFC5A22F9CEDAF8614832527210B26F024C7F6C0DCF551E97A4858764C321D1834AD51D75BB246D277237B7BD41DC4362D063F4298292272D01011780B79856B296C4E946658B79603197C9B2A99EC66ACB06CE2F69B5A5A61E9BD06AD443CEB0C74ED65345A903B614E81368AAC2B3D2A79CA8CCAA1C3B88FB82A36632860B3F7950833FD0212EC96EDE4AB6F5A0BDA3EC6060A658F9457F6CC87C6B620C1A1451987486E496612A101D0E9C20577C571EDB5282608BF4E1AC926C0DB1C82A504A799D89885CA6252BD5B1C183AF701392A407C05B848C2A3016C40613F02A449B3C7926DA067A533116506840097510460BBFD36073DCB0BFA009B36A9123EAA68F835F74A01B00D2097835964DF521CE9210789C30B7F06E5844B444C53322396E4799BAF6A88AF7315860D0192D48C2C0DA6B5BA64325543ACDF5900E8BC477AB05820072D463AFFED097E062BD78C99D12B385131A241B708865B4190AF69EA0A64DB71448A60829369C7555198E438C9ABC310BC70101913BB12FAA5BEEF975841617C847CD6B336F877987753822020B92C4CC97055C9B1E0B128BF11F505005B6AB0E627795A20609EFA991E598B80F37B1C6A1C3A1E9AEE7028F77570AB2139128A00108C50EB305CDB8F9A603A6B078413F6F9B14C6D82B5199CE59D887902A281A027B717495FE12672A127BBF9B256C43720D7C160B281C12757DA135B1933352BE4AB67E40248AFC318E2370C3B8208E695BDF337459B9ACBFE5B487F76E9B4B4001D6CF90CA8C699A174D42972DC733F33389FDF59A1DABA81D834955027334185AD02C76CF294846CA9294BA0ED66741DDEC791CAB34196AC5657C5A78321B56C33306B5102397A5C09C3508F76B48282459F81D0C72A43F737BC2F12F45422628B67DB51AC1424276A6C08C3F7615665BBB8E928148A270F991BCF365A90F87C30687B68809C91F231813B866BEA82E30374D80AA0C02973437498A53B14BF6B6CA1ED76AB8A20D54A083F4A26B7C038D81967640C20BF4431E71DACCE8577B21240E494C31F2D877DAF4924FD39D82D6167FBCC1F9C5A259F843E30987CCC4BCE7493A2404B5E44387F707425781B743FB555685584E2557CC038B1A9B3F4043121F5472EB2B96E5941FEC011CEEA50791636C6ABC26C1377EE3B5146FC7C85CB335B1E795EEC2033EE44B9AA90685245EF7B4436C000E66BC8BCBF1CDB803AC1421B1FDB266D5291C8310373A8A3CE9562AB197953871AB99F382CC5AA9C0F273D1DCA55D2712853871E1A83CB3B85450F76D3F3C42BAB5505F7212FDB6B8B7F6029972A8F3751E4C94C1108B02D6AC79F8D938F05A1B2C229B14B42B31B01A364017E59578C6B033833774CB9B570F9086B722903B375446B495D8A29BF80751877A80FB724A0210C3E1692F397C2F1DDC2E6BA17AF81B92ACFABEF5F7573CB493D184027B718238C89A3549B8905B28A83362867C082D3019D3CA70700731CEB73E8472C1A3A093361C5FEA6A7D40955D07A41B64E50081A361B604CC518447C8E25765AB7D68B243275207AF8CA6564A4CB1E94199DBA1878C59BEC809AB48B2F211BADC6A1998D9C7227C1303F469D46A9C7E5303F98ABA67569AE8227C16BA1FB3244466A25E7F823671810CC26206FEB29C7E2A1A91959EEB03A98252A4F7412674EB9A4B277E1F2595FCA64033B41B40330812E9735B7C607501CD8183A22AFC3392553744F33C4D202526945C6D78A60E201A16987A6FA59D94464B56506556784824A07058F57320E76C825B9347F2936F4A0E5CDAA18CF8833945AE312A36B5F5A3810AAC82381FDAE4CB9C6831D8EB8ABAB850416443D739086B1C326FC2A3975704E396A59680C3B5F360F5480D2B62169CD94CA71B37BC5878BA2985E068BA050B2CE50726D4B4451B77AAA8676EAE094982210192197B1E92A27F59868B78867887B9A70C32AF84630AA908814379E6519150BA16439B5E2B0603D06AA6674557F5B0983E5CB6A97596069B01BB3128C416680657204FD07640392E16B19F337A99A304844E1AA474E9C799062971F672268960F5A82F950070BBE9C2A71950A3785BDF0B8440255ED63928D257845168B1ECCC4191325AA76645719B28EBD89302DC6723C786DF5217B243099CA78238E57E64692F206B177ABC259660395CD7860FB35A16F6B2FE6548C85AB66330C517FA74CDF3CB49D26B1181901AF775A1E180813B6A24C456829B5C38104ECE43C76A437A6A33B6FC6C5E65C8A89466C1425485B29B9E1854368AFCA353E143D0A90A6C6C9E7FDB62A606856B5614F12B64B796020C3534C3605CFDC73B86714F411850228A28B8F4B49E663416C84F7E381F6AF1071343BF9D39B45439240CC03897295FEA080B14BB2D8119A880E164495C61BEBC7139C11857C85E1750338D6343913706A507C9566464CD2837CF914D1A3C35E89B235C6AB7ED078BED234757C02EF6993D4A273CB8150528DA4D76708177E9425546C83E147039766603B30DA6268F4598A53194240A2832A3D67533B5056F9AAAC61B4B17B9A2693AA0D58891E6CC56CDD772410900C405AF20B903797C64876915C37B8487A1449CE924CD345C29A36E08238F7A157CC7E516AB5BA73C8063F726BB5A0A0319E57127438C7FC601C99CCAAE4C1A83726FDCB5045ED1A82A985EA995396D77272C66CE493289F6110910F37C2741CE47026A6F8261999C6482572B1693912EF12EEBEA7ACF9234FB409F2A6090E6B0BFD895469D0B2A921BB723F87A33EA5465AB90F514B67698C0768B6CA498B022C512FA0875F054AA2265867E31C0E522651E024A07D60DD9F633166921F4126BC2B6AA01CC15A09B85BFF8218C5AAE95BC1FFB26AE5A137670F04910CA9D7241B6660C394C5455917746A26682FB71A432EA9530E839BDEB07433004F45A0DDAA0B24E3A566A540815F281E3FC259AC6CBC0ACB8D62268B603BC676AB415C474BB94873E4487AE31A4E3845C79901550890EE8784EEF904FEE62BA8C5F952C68413052E0A7E3388BB8FF0AD602AE3EA14D9DF6DD5E4CC6A381A41DA5C137ECC49DF587E178EAF47702EC623780691A3233F69F12BD9C9B9637C51378AD71A831055277254CC63C5AD4CB76B4AB82E5FCA135E8D26A6B3A89FA5B6F"""), + xeh(""" +2513DE1E55ED0E862614587FE47F308C90A1F426470CA1293BDDF7B9DDD6C368DC152F45C71354904ED48E15A1CB449B4C45D0F201ED5C7D3A047A72F080265D66C47D39469097EEEABBAA3B07ED1F1AEAB80C7D24552FA8889C674A5D4840289DE6B0FA9A222E693708D1F252DFE8B993956883C07067C1C0844EF0BEB49F63534D21D471D6B727FFC59477F9E89E5BEB2AF0CBEB052F003414DA4070008753CFC0C6D0FA9D1C15388FE5886EADD3474F28E4682C0E01784A037DC3799330EA380767B0D0B6EDFC9730E04D1039548A6F83889098522EBAB684DA6FE26A4A6891D86D40FCD9A24F743D74B23B1596810727C81BB3F9F3BADFAE9997949EE0E24987FA182A00D73DCEADF667E90E5AE76A1F83A91FCEA78C96269F0C9501F1D4CE682506A7EA89302A1480E18CDC1F6D57B5312EAF808895B20897E9A782F916CD75B4981DA1381F14EB1EC248B27F0E6966A0CD75414A735928B2120615D88FA57AF5C40E61750F0A0F8E605747E7C32D5A23F14124969C072E949C8475E3108D689D2D20797FE14618811E9A497FD26B9E71355852D4B36340B61695E3745F8D07644AC6E2C18B3FC276D4D19DB69A7CF26086F172E2BCE1618A740A0C739FD504F72C2A72ADB5564BC85DAB4C9CE790D78D14D3BD242DF04106D96CE7C3B392CCED9B99DF359FD51F306CBCBD5B46B8487CD7B7EDD3C5C02965C84630DA1B6B8B317FE55F7C79E05CDAC9E863023DAF470E9C3FB8C01FDF3AEDF2193BFA69A806E2E70151ABCF96D31CF6A317C059CA8C7D456A8E5EBAA6C1283A319F188AAA80D8301E321754E5FB4E0B25594B01BC5F82FF25B064C766424D658459EFD7A20B65DB181811E6D5A4BD153F7066BD7757D2D417D21F83D7C4CB6A0703A42032F0FD198D9D8B0F91B359FBE908432C3286E1EF9D601702157EFBAB68E0E7136BFC90D26BD8A9A7018DE4C4BF05CE465F917D20A4F221A4EE78813A1E8A117C8470929701CCC201A85E7F18B6BC96FE80B1E074661525D3FD0CE2565AB11155DAFE4D3410328D6DBB4DD99A84FE96283D32322522B88B3AA2A11C0324B1D5556EF408D37B0DF802D163FE38D7C38916A26810BD175D22762353C3175DC6040C899E07A339CD4DDBD4D5549E02C0D691263936A9F63111412B60AA9F57486334E40B2BC1B8EAA487A094E45C3F77F72EA741CE225ECBE2B5E4A1FC080070A658FDF9E2B388722855267B30D94B63C3ED35D475B7EB22E3D2462ABA9CF2A86B738EBB270AB29708A2614A557E33A620B507286E5D4CA57E2CEEDB9965FF1C3E1777F980CDFB1445BBE0B6ACBA0216980F962FBFABE265B3ADFE8641088287468827AE601B6A165DEED39C0E8773BF2046BBF63634BDBCAF98358D25FDE475781733DDE8C6D6383D13B6D48FF1B65E2FF13AAA9CCCFC3C626935C5270F9E23A71A87CF2BD793CB175D23EA5FBD82C18A1822428C32DB9E31B94BE3144ABB00F5ACAAA431C17386719C3FF47C38720B1AB01889DAD877BADC9FC716F648FC8B551F""") + ), + new DecapsulateTestCase( + xeh(""" +1E4AC87B1A692A529FDBBAB93374C57D110B10F2B1DDEBAC0D196B7BA631B8E9293028A8F379888C422DC8D32BBF226010C2C1EC73189080456B0564B258B0F23131BC79C8E8C11CEF3938B243C5CE9C0EDD37C8F9D29877DBBB615B9B5AC3C948487E467196A9143EFBC7CEDB64B45D4ACDA2666CBC2804F2C8662E128F6A9969EC15BC0B9351F6F96346AA7ABC743A14FA030E37A2E7597BDDFC5A22F9CEDAF8614832527210B26F024C7F6C0DCF551E97A4858764C321D1834AD51D75BB246D277237B7BD41DC4362D063F4298292272D01011780B79856B296C4E946658B79603197C9B2A99EC66ACB06CE2F69B5A5A61E9BD06AD443CEB0C74ED65345A903B614E81368AAC2B3D2A79CA8CCAA1C3B88FB82A36632860B3F7950833FD0212EC96EDE4AB6F5A0BDA3EC6060A658F9457F6CC87C6B620C1A1451987486E496612A101D0E9C20577C571EDB5282608BF4E1AC926C0DB1C82A504A799D89885CA6252BD5B1C183AF701392A407C05B848C2A3016C40613F02A449B3C7926DA067A533116506840097510460BBFD36073DCB0BFA009B36A9123EAA68F835F74A01B00D2097835964DF521CE9210789C30B7F06E5844B444C53322396E4799BAF6A88AF7315860D0192D48C2C0DA6B5BA64325543ACDF5900E8BC477AB05820072D463AFFED097E062BD78C99D12B385131A241B708865B4190AF69EA0A64DB71448A60829369C7555198E438C9ABC310BC70101913BB12FAA5BEEF975841617C847CD6B336F877987753822020B92C4CC97055C9B1E0B128BF11F505005B6AB0E627795A20609EFA991E598B80F37B1C6A1C3A1E9AEE7028F77570AB2139128A00108C50EB305CDB8F9A603A6B078413F6F9B14C6D82B5199CE59D887902A281A027B717495FE12672A127BBF9B256C43720D7C160B281C12757DA135B1933352BE4AB67E40248AFC318E2370C3B8208E695BDF337459B9ACBFE5B487F76E9B4B4001D6CF90CA8C699A174D42972DC733F33389FDF59A1DABA81D834955027334185AD02C76CF294846CA9294BA0ED66741DDEC791CAB34196AC5657C5A78321B56C33306B5102397A5C09C3508F76B48282459F81D0C72A43F737BC2F12F45422628B67DB51AC1424276A6C08C3F7615665BBB8E928148A270F991BCF365A90F87C30687B68809C91F231813B866BEA82E30374D80AA0C02973437498A53B14BF6B6CA1ED76AB8A20D54A083F4A26B7C038D81967640C20BF4431E71DACCE8577B21240E494C31F2D877DAF4924FD39D82D6167FBCC1F9C5A259F843E30987CCC4BCE7493A2404B5E44387F707425781B743FB555685584E2557CC038B1A9B3F4043121F5472EB2B96E5941FEC011CEEA50791636C6ABC26C1377EE3B5146FC7C85CB335B1E795EEC2033EE44B9AA90685245EF7B4436C000E66BC8BCBF1CDB803AC1421B1FDB266D5291C8310373A8A3CE9562AB197953871AB99F382CC5AA9C0F273D1DCA55D2712853871E1A83CB3B85450F76D3F3C42BAB5505F7212FDB6B8B7F6029972A8F3751E4C94C1108B02D6AC79F8D938F05A1B2C229B14B42B31B01A364017E59578C6B033833774CB9B570F9086B722903B375446B495D8A29BF80751877A80FB724A0210C3E1692F397C2F1DDC2E6BA17AF81B92ACFABEF5F7573CB493D184027B718238C89A3549B8905B28A83362867C082D3019D3CA70700731CEB73E8472C1A3A093361C5FEA6A7D40955D07A41B64E50081A361B604CC518447C8E25765AB7D68B243275207AF8CA6564A4CB1E94199DBA1878C59BEC809AB48B2F211BADC6A1998D9C7227C1303F469D46A9C7E5303F98ABA67569AE8227C16BA1FB3244466A25E7F823671810CC26206FEB29C7E2A1A91959EEB03A98252A4F7412674EB9A4B277E1F2595FCA64033B41B40330812E9735B7C607501CD8183A22AFC3392553744F33C4D202526945C6D78A60E201A16987A6FA59D94464B56506556784824A07058F57320E76C825B9347F2936F4A0E5CDAA18CF8833945AE312A36B5F5A3810AAC82381FDAE4CB9C6831D8EB8ABAB850416443D739086B1C326FC2A3975704E396A59680C3B5F360F5480D2B62169CD94CA71B37BC5878BA2985E068BA050B2CE50726D4B4451B77AAA8676EAE094982210192197B1E92A27F59868B78867887B9A70C32AF84630AA908814379E6519150BA16439B5E2B0603D06AA6674557F5B0983E5CB6A97596069B01BB3128C416680657204FD07640392E16B19F337A99A304844E1AA474E9C799062971F672268960F5A82F950070BBE9C2A71950A3785BDF0B8440255ED63928D257845168B1ECCC4191325AA76645719B28EBD89302DC6723C786DF5217B243099CA78238E57E64692F206B177ABC259660395CD7860FB35A16F6B2FE6548C85AB66330C517FA74CDF3CB49D26B1181901AF775A1E180813B6A24C456829B5C38104ECE43C76A437A6A33B6FC6C5E65C8A89466C1425485B29B9E1854368AFCA353E143D0A90A6C6C9E7FDB62A606856B5614F12B64B796020C3534C3605CFDC73B86714F411850228A28B8F4B49E663416C84F7E381F6AF1071343BF9D39B45439240CC03897295FEA080B14BB2D8119A880E164495C61BEBC7139C11857C85E1750338D6343913706A507C9566464CD2837CF914D1A3C35E89B235C6AB7ED078BED234757C02EF6993D4A273CB8150528DA4D76708177E9425546C83E147039766603B30DA6268F4598A53194240A2832A3D67533B5056F9AAAC61B4B17B9A2693AA0D58891E6CC56CDD772410900C405AF20B903797C64876915C37B8487A1449CE924CD345C29A36E08238F7A157CC7E516AB5BA73C8063F726BB5A0A0319E57127438C7FC601C99CCAAE4C1A83726FDCB5045ED1A82A985EA995396D77272C66CE493289F6110910F37C2741CE47026A6F8261999C6482572B1693912EF12EEBEA7ACF9234FB409F2A6090E6B0BFD895469D0B2A921BB723F87A33EA5465AB90F514B67698C0768B6CA498B022C512FA0875F054AA2265867E31C0E522651E024A07D60DD9F633166921F4126BC2B6AA01CC15A09B85BFF8218C5AAE95BC1FFB26AE5A137670F04910CA9D7241B6660C394C5455917746A26682FB71A432EA9530E839BDEB07433004F45A0DDAA0B24E3A566A540815F281E3FC259AC6CBC0ACB8D62268B603BC676AB415C474BB94873E4487AE31A4E3845C79901550890EE8784EEF904FEE62BA8C5F952C68413052E0A7E3388BB8FF0AD602AE3EA14D9DF6DD5E4CC6A381A41DA5C137ECC49DF587E178EAF47702EC623780691A3233F69F12BD9C9B9637C51378AD71A831055277254CC63C5AD4CB76B4AB82E5FCA135E8D26A6B3A89FA5B6F"""), + xeh(""" +8A4336FDDB3F55D16ADBBE54C6EF0DB27F20679393D86EA4590CB6F5F09BC4EB76181A13C9826FBD2A7174BE8A11F13759EE23DA15337A4C5612480E0A843CC6D04F3A902E144EFDC0AC118BF8553B984E758E6D7ED1373B20A5726271C5F4B542FCCD6379671CE37A5D0128F55539B9A855172CA2DA3BB6823484A87DC2333F56CBADF4A694A5DAE341A0E3FBB3D852929FBAFBF4A5C12CD3494CDF910010A0FAFBC09B375BABFFDEACCD12E6E7BD347CBFBD0C84CDABB5004CA11DDC6D14C1BD700FE3EB2371E3293F7185E2A065532C3B6529E60240E7AB6456139D66745F17B94FDF2C54B13EE4DEBF1B77099718804BAEAAACD2BC60A190487CDC76AF2EEB906E4C9F2664A30FAFB65013B8CA393793B650CAC4A93377A6511D739C2136CEC59E1BD14584989A591E1F3B7F6D7237AEDB556880810FABDB1D7F8250B61A2D16A3337DA65AEA644D7E2226BE5F24CBE01C8A33A4CCA06F6F646A3F5453FE2D9FDEA8D8613F491BCF2AEA950DB1D9B43C7C3F86FA2F4A51CB44EB9761363C38723852925247D92E37FC694D2CB00248023D5448CDE2867125250B17388440C188F7E500CEF7747A101E0BF2521E2C8A2D04F42D834C0274ECBC73E94612CCDB1C4B908BAF63C09C945AD4645912A0666E9844A1614B7F34415C1842F9B1C7DAF7EE4459A8724B7050F6B5833341691019149F351A7F11AE2416DCD5B36F18B1A4B82CC3E924114CFC126CA309E319D497A594B0AB2AFB58C19DEF3BC3AD885B29AEAC81F346A19683B8577F4A1E0F30BDC85A3814CD1196E6B29E55E5C0E4E028872477CB675B2408E136D15E54C85E8A468423CB795D9348BFCC975B4EC20A23991E6E9EF91D676983AC26B66C71548FB46C4BF06E280D7C55E7B8DB90743A8F893F95AEB4DED1DC65C5E0B61FBAD9DA0DDAC274591AA6CF23C79C09414356584F0BE02CE9B500A3EE6BD4FA0119783F50E800ED36D3A4445934DCFD87A31AF3ABC02CAC39C4B28068EECC6D16B6FA187A073BA143209C0F38AFE100BC700D461B1B364ED298AAFDFC716FA6E3870E6258B66645091FCF9413EDF6BC79B75132A46D1DFBBCE3CE9B0558EF003929CC6E3D57BC4FD3092EEAC4ED71B7B7FC70D0E65901DC9196928C5B8CF4A63C62797727C192CF1CE4315120A57D4C8CFD03143AF8754432EEBADCADBCD26C2E3A14BB43A951AFDC19EE67AAEC5DE0722E9D11E3627AD1B624ADF0FB6FD2A6733B2B1B1411DD14EE87AD3BCBBCAD2EB4A38EA00575BFA99332400083FC519C3733F6EDCCAAF71D09A7164E18A9E9587A8D9B9A46563FD3F14BFA2F2B8EBD9FDEAAEF466E591F502151E43A7E1123273E5E0574814B20253A17917D7BDF8370BC50461AC8D86127DC527B8290FE386F1AC1E6E9D7B493BB7FEDEC9E5A82DC1402DEAE71B18AB4B658E43F707259039EB9978D4FB0D62839A0DD8E3A1183CE330D57BC7927F7CCF06BA10A0478B7E2EC818195171AFF75C29B283E759F4D2F5D55F0FFC35E0581D98E582107BF64A6D80603""") + ), + new DecapsulateTestCase( + xeh(""" +1E4AC87B1A692A529FDBBAB93374C57D110B10F2B1DDEBAC0D196B7BA631B8E9293028A8F379888C422DC8D32BBF226010C2C1EC73189080456B0564B258B0F23131BC79C8E8C11CEF3938B243C5CE9C0EDD37C8F9D29877DBBB615B9B5AC3C948487E467196A9143EFBC7CEDB64B45D4ACDA2666CBC2804F2C8662E128F6A9969EC15BC0B9351F6F96346AA7ABC743A14FA030E37A2E7597BDDFC5A22F9CEDAF8614832527210B26F024C7F6C0DCF551E97A4858764C321D1834AD51D75BB246D277237B7BD41DC4362D063F4298292272D01011780B79856B296C4E946658B79603197C9B2A99EC66ACB06CE2F69B5A5A61E9BD06AD443CEB0C74ED65345A903B614E81368AAC2B3D2A79CA8CCAA1C3B88FB82A36632860B3F7950833FD0212EC96EDE4AB6F5A0BDA3EC6060A658F9457F6CC87C6B620C1A1451987486E496612A101D0E9C20577C571EDB5282608BF4E1AC926C0DB1C82A504A799D89885CA6252BD5B1C183AF701392A407C05B848C2A3016C40613F02A449B3C7926DA067A533116506840097510460BBFD36073DCB0BFA009B36A9123EAA68F835F74A01B00D2097835964DF521CE9210789C30B7F06E5844B444C53322396E4799BAF6A88AF7315860D0192D48C2C0DA6B5BA64325543ACDF5900E8BC477AB05820072D463AFFED097E062BD78C99D12B385131A241B708865B4190AF69EA0A64DB71448A60829369C7555198E438C9ABC310BC70101913BB12FAA5BEEF975841617C847CD6B336F877987753822020B92C4CC97055C9B1E0B128BF11F505005B6AB0E627795A20609EFA991E598B80F37B1C6A1C3A1E9AEE7028F77570AB2139128A00108C50EB305CDB8F9A603A6B078413F6F9B14C6D82B5199CE59D887902A281A027B717495FE12672A127BBF9B256C43720D7C160B281C12757DA135B1933352BE4AB67E40248AFC318E2370C3B8208E695BDF337459B9ACBFE5B487F76E9B4B4001D6CF90CA8C699A174D42972DC733F33389FDF59A1DABA81D834955027334185AD02C76CF294846CA9294BA0ED66741DDEC791CAB34196AC5657C5A78321B56C33306B5102397A5C09C3508F76B48282459F81D0C72A43F737BC2F12F45422628B67DB51AC1424276A6C08C3F7615665BBB8E928148A270F991BCF365A90F87C30687B68809C91F231813B866BEA82E30374D80AA0C02973437498A53B14BF6B6CA1ED76AB8A20D54A083F4A26B7C038D81967640C20BF4431E71DACCE8577B21240E494C31F2D877DAF4924FD39D82D6167FBCC1F9C5A259F843E30987CCC4BCE7493A2404B5E44387F707425781B743FB555685584E2557CC038B1A9B3F4043121F5472EB2B96E5941FEC011CEEA50791636C6ABC26C1377EE3B5146FC7C85CB335B1E795EEC2033EE44B9AA90685245EF7B4436C000E66BC8BCBF1CDB803AC1421B1FDB266D5291C8310373A8A3CE9562AB197953871AB99F382CC5AA9C0F273D1DCA55D2712853871E1A83CB3B85450F76D3F3C42BAB5505F7212FDB6B8B7F6029972A8F3751E4C94C1108B02D6AC79F8D938F05A1B2C229B14B42B31B01A364017E59578C6B033833774CB9B570F9086B722903B375446B495D8A29BF80751877A80FB724A0210C3E1692F397C2F1DDC2E6BA17AF81B92ACFABEF5F7573CB493D184027B718238C89A3549B8905B28A83362867C082D3019D3CA70700731CEB73E8472C1A3A093361C5FEA6A7D40955D07A41B64E50081A361B604CC518447C8E25765AB7D68B243275207AF8CA6564A4CB1E94199DBA1878C59BEC809AB48B2F211BADC6A1998D9C7227C1303F469D46A9C7E5303F98ABA67569AE8227C16BA1FB3244466A25E7F823671810CC26206FEB29C7E2A1A91959EEB03A98252A4F7412674EB9A4B277E1F2595FCA64033B41B40330812E9735B7C607501CD8183A22AFC3392553744F33C4D202526945C6D78A60E201A16987A6FA59D94464B56506556784824A07058F57320E76C825B9347F2936F4A0E5CDAA18CF8833945AE312A36B5F5A3810AAC82381FDAE4CB9C6831D8EB8ABAB850416443D739086B1C326FC2A3975704E396A59680C3B5F360F5480D2B62169CD94CA71B37BC5878BA2985E068BA050B2CE50726D4B4451B77AAA8676EAE094982210192197B1E92A27F59868B78867887B9A70C32AF84630AA908814379E6519150BA16439B5E2B0603D06AA6674557F5B0983E5CB6A97596069B01BB3128C416680657204FD07640392E16B19F337A99A304844E1AA474E9C799062971F672268960F5A82F950070BBE9C2A71950A3785BDF0B8440255ED63928D257845168B1ECCC4191325AA76645719B28EBD89302DC6723C786DF5217B243099CA78238E57E64692F206B177ABC259660395CD7860FB35A16F6B2FE6548C85AB66330C517FA74CDF3CB49D26B1181901AF775A1E180813B6A24C456829B5C38104ECE43C76A437A6A33B6FC6C5E65C8A89466C1425485B29B9E1854368AFCA353E143D0A90A6C6C9E7FDB62A606856B5614F12B64B796020C3534C3605CFDC73B86714F411850228A28B8F4B49E663416C84F7E381F6AF1071343BF9D39B45439240CC03897295FEA080B14BB2D8119A880E164495C61BEBC7139C11857C85E1750338D6343913706A507C9566464CD2837CF914D1A3C35E89B235C6AB7ED078BED234757C02EF6993D4A273CB8150528DA4D76708177E9425546C83E147039766603B30DA6268F4598A53194240A2832A3D67533B5056F9AAAC61B4B17B9A2693AA0D58891E6CC56CDD772410900C405AF20B903797C64876915C37B8487A1449CE924CD345C29A36E08238F7A157CC7E516AB5BA73C8063F726BB5A0A0319E57127438C7FC601C99CCAAE4C1A83726FDCB5045ED1A82A985EA995396D77272C66CE493289F6110910F37C2741CE47026A6F8261999C6482572B1693912EF12EEBEA7ACF9234FB409F2A6090E6B0BFD895469D0B2A921BB723F87A33EA5465AB90F514B67698C0768B6CA498B022C512FA0875F054AA2265867E31C0E522651E024A07D60DD9F633166921F4126BC2B6AA01CC15A09B85BFF8218C5AAE95BC1FFB26AE5A137670F04910CA9D7241B6660C394C5455917746A26682FB71A432EA9530E839BDEB07433004F45A0DDAA0B24E3A566A540815F281E3FC259AC6CBC0ACB8D62268B603BC676AB415C474BB94873E4487AE31A4E3845C79901550890EE8784EEF904FEE62BA8C5F952C68413052E0A7E3388BB8FF0AD602AE3EA14D9DF6DD5E4CC6A381A41DA5C137ECC49DF587E178EAF47702EC623780691A3233F69F12BD9C9B9637C51378AD71A831055277254CC63C5AD4CB76B4AB82E5FCA135E8D26A6B3A89FA5B6F"""), + xeh(""" +6095A951753A644DD898D69138B4E521A704DCFAAD44EB53E284F836A469349C5B9279248AFC57AC93FA34A643DE02B724615CF5865927FED60A6B41E4AB15B4DA3599F13D2C1996C6D6989443BE6FB81F5BA03BDD53462BE5812A3E177876A102B0EBDFCB16DE7B29B5123A79DD82E5CD47ABA02759FAF5401E3BF03144A90AE957EC04DB9864ADE1C5A700CEC7872CCB64FF931984DDC3FB8D4971D761E5544130278C75A1B04E641E070A747789A71E09409C155C7D341D5F828A575EE74439155930DF22FD7716185BDF917472432A30A6762C9FE1A254442F755804D295B1698B47A67BBFDE178200F9CC3D4C705F4AC1B00C372D468E16ED3CBAAA862A2574A9574A7280878BB82DA7BD1B2A58943456838F2E6AA9F6EF1827C5B24FA09DE07E9B3153B0F44A4F2AEA7610F9CCA92565740E7295BA3AC5764A20A44D4E1862E55B1DF7913B279F438B3B34E0C22FD90E06497F7DCF8D62352447C2B8C51C214796194CDF66D5001278D0D55F82FA31DAA72BA6CDA34E60D696ED79C7056BFE97265F3D1BC07719B745ADD4A83404D91A184E629FC24AE236CF6AFAE46295D24B431D819E366F51E1BB2B44B1FB7A3060091DEA1D416268CA550EE4E41FCA1F387E941DBE4EBAE222D3CF625632D1A61414038FD437BFA20005EBC404ADCDE2DC10DB741A3B7534C40822520C4703FDFB6B380F7DB72B725B330D0C20DF256BBDDC31E0EA20E636A9FAE310185A5081923BAFE041AC6FCD4E73F5F7237142B74681F637996D28C3FDE6052243269D19316C56993722EADF19A985E579ED559F971E69EB5125937EBC80ECD15A4F80D7067905A4D39C6220EFE43883CF22E9A366F8911E21D0491B8FF61FD07B733E707A08DB400E438DAA00D481C5AC62064CF47AFE3AB08027B3890E8C8835CEAF8128F9D887A6CB7FDE879D9611C01281A0F02DE0E969C9131F8512138036EC1967DCA45AA30BE8C5B1008113E17A91D9F8E9995C07C0B13A45668C96356F09C3E08FE4C7DF5F7230E0C93EEF08E8958B55E213718C516E624B57765257D21696A3458FFBA11DE708C4EE9AF2EDC5F37458DEC8B985076882D3F4DEB00BFD8E7EA4D57BAEAEC6BABC0E28C15419CCD785CF6ACEC96D1111CDD1DA9A151F59A7366B64A53F0497D3B5A8ECB60D7C220E99126CDE82938C7E131BD841300AE461A1817703ED5B0510B47F2C2980F1E11CFBECB524B295C42187F15B0C9F6B0EB1E70B3EC43ED955528B1E42E2BCB31F3A1CFB5E9C807E8D366E9227A87784748B277D6C885B1385C6C691B3DBD7841DD89721B3A8BF96EBA99C53D4BB3B41DB9409B992BCC2D8FC53E70723CA1FDC1341A3E608D7F62F2322C6A9BA1316639690A22AECEE364B4F13949A0310FBA1A0E35DDA5FF840DABAC55041B0931D9EBEC89B78DD930512340B4B5D0877AF546FF0F342FB76B647D604EE2E20207924F39907D6E72DD4A9A1ED0B6D7364CCE69981F56CBDEDD51CBAF6FDDB36E327AD65D4FE283D253E6BF3C7969FFF1F34DCC742""") + ), + new DecapsulateTestCase( + xeh(""" +1E4AC87B1A692A529FDBBAB93374C57D110B10F2B1DDEBAC0D196B7BA631B8E9293028A8F379888C422DC8D32BBF226010C2C1EC73189080456B0564B258B0F23131BC79C8E8C11CEF3938B243C5CE9C0EDD37C8F9D29877DBBB615B9B5AC3C948487E467196A9143EFBC7CEDB64B45D4ACDA2666CBC2804F2C8662E128F6A9969EC15BC0B9351F6F96346AA7ABC743A14FA030E37A2E7597BDDFC5A22F9CEDAF8614832527210B26F024C7F6C0DCF551E97A4858764C321D1834AD51D75BB246D277237B7BD41DC4362D063F4298292272D01011780B79856B296C4E946658B79603197C9B2A99EC66ACB06CE2F69B5A5A61E9BD06AD443CEB0C74ED65345A903B614E81368AAC2B3D2A79CA8CCAA1C3B88FB82A36632860B3F7950833FD0212EC96EDE4AB6F5A0BDA3EC6060A658F9457F6CC87C6B620C1A1451987486E496612A101D0E9C20577C571EDB5282608BF4E1AC926C0DB1C82A504A799D89885CA6252BD5B1C183AF701392A407C05B848C2A3016C40613F02A449B3C7926DA067A533116506840097510460BBFD36073DCB0BFA009B36A9123EAA68F835F74A01B00D2097835964DF521CE9210789C30B7F06E5844B444C53322396E4799BAF6A88AF7315860D0192D48C2C0DA6B5BA64325543ACDF5900E8BC477AB05820072D463AFFED097E062BD78C99D12B385131A241B708865B4190AF69EA0A64DB71448A60829369C7555198E438C9ABC310BC70101913BB12FAA5BEEF975841617C847CD6B336F877987753822020B92C4CC97055C9B1E0B128BF11F505005B6AB0E627795A20609EFA991E598B80F37B1C6A1C3A1E9AEE7028F77570AB2139128A00108C50EB305CDB8F9A603A6B078413F6F9B14C6D82B5199CE59D887902A281A027B717495FE12672A127BBF9B256C43720D7C160B281C12757DA135B1933352BE4AB67E40248AFC318E2370C3B8208E695BDF337459B9ACBFE5B487F76E9B4B4001D6CF90CA8C699A174D42972DC733F33389FDF59A1DABA81D834955027334185AD02C76CF294846CA9294BA0ED66741DDEC791CAB34196AC5657C5A78321B56C33306B5102397A5C09C3508F76B48282459F81D0C72A43F737BC2F12F45422628B67DB51AC1424276A6C08C3F7615665BBB8E928148A270F991BCF365A90F87C30687B68809C91F231813B866BEA82E30374D80AA0C02973437498A53B14BF6B6CA1ED76AB8A20D54A083F4A26B7C038D81967640C20BF4431E71DACCE8577B21240E494C31F2D877DAF4924FD39D82D6167FBCC1F9C5A259F843E30987CCC4BCE7493A2404B5E44387F707425781B743FB555685584E2557CC038B1A9B3F4043121F5472EB2B96E5941FEC011CEEA50791636C6ABC26C1377EE3B5146FC7C85CB335B1E795EEC2033EE44B9AA90685245EF7B4436C000E66BC8BCBF1CDB803AC1421B1FDB266D5291C8310373A8A3CE9562AB197953871AB99F382CC5AA9C0F273D1DCA55D2712853871E1A83CB3B85450F76D3F3C42BAB5505F7212FDB6B8B7F6029972A8F3751E4C94C1108B02D6AC79F8D938F05A1B2C229B14B42B31B01A364017E59578C6B033833774CB9B570F9086B722903B375446B495D8A29BF80751877A80FB724A0210C3E1692F397C2F1DDC2E6BA17AF81B92ACFABEF5F7573CB493D184027B718238C89A3549B8905B28A83362867C082D3019D3CA70700731CEB73E8472C1A3A093361C5FEA6A7D40955D07A41B64E50081A361B604CC518447C8E25765AB7D68B243275207AF8CA6564A4CB1E94199DBA1878C59BEC809AB48B2F211BADC6A1998D9C7227C1303F469D46A9C7E5303F98ABA67569AE8227C16BA1FB3244466A25E7F823671810CC26206FEB29C7E2A1A91959EEB03A98252A4F7412674EB9A4B277E1F2595FCA64033B41B40330812E9735B7C607501CD8183A22AFC3392553744F33C4D202526945C6D78A60E201A16987A6FA59D94464B56506556784824A07058F57320E76C825B9347F2936F4A0E5CDAA18CF8833945AE312A36B5F5A3810AAC82381FDAE4CB9C6831D8EB8ABAB850416443D739086B1C326FC2A3975704E396A59680C3B5F360F5480D2B62169CD94CA71B37BC5878BA2985E068BA050B2CE50726D4B4451B77AAA8676EAE094982210192197B1E92A27F59868B78867887B9A70C32AF84630AA908814379E6519150BA16439B5E2B0603D06AA6674557F5B0983E5CB6A97596069B01BB3128C416680657204FD07640392E16B19F337A99A304844E1AA474E9C799062971F672268960F5A82F950070BBE9C2A71950A3785BDF0B8440255ED63928D257845168B1ECCC4191325AA76645719B28EBD89302DC6723C786DF5217B243099CA78238E57E64692F206B177ABC259660395CD7860FB35A16F6B2FE6548C85AB66330C517FA74CDF3CB49D26B1181901AF775A1E180813B6A24C456829B5C38104ECE43C76A437A6A33B6FC6C5E65C8A89466C1425485B29B9E1854368AFCA353E143D0A90A6C6C9E7FDB62A606856B5614F12B64B796020C3534C3605CFDC73B86714F411850228A28B8F4B49E663416C84F7E381F6AF1071343BF9D39B45439240CC03897295FEA080B14BB2D8119A880E164495C61BEBC7139C11857C85E1750338D6343913706A507C9566464CD2837CF914D1A3C35E89B235C6AB7ED078BED234757C02EF6993D4A273CB8150528DA4D76708177E9425546C83E147039766603B30DA6268F4598A53194240A2832A3D67533B5056F9AAAC61B4B17B9A2693AA0D58891E6CC56CDD772410900C405AF20B903797C64876915C37B8487A1449CE924CD345C29A36E08238F7A157CC7E516AB5BA73C8063F726BB5A0A0319E57127438C7FC601C99CCAAE4C1A83726FDCB5045ED1A82A985EA995396D77272C66CE493289F6110910F37C2741CE47026A6F8261999C6482572B1693912EF12EEBEA7ACF9234FB409F2A6090E6B0BFD895469D0B2A921BB723F87A33EA5465AB90F514B67698C0768B6CA498B022C512FA0875F054AA2265867E31C0E522651E024A07D60DD9F633166921F4126BC2B6AA01CC15A09B85BFF8218C5AAE95BC1FFB26AE5A137670F04910CA9D7241B6660C394C5455917746A26682FB71A432EA9530E839BDEB07433004F45A0DDAA0B24E3A566A540815F281E3FC259AC6CBC0ACB8D62268B603BC676AB415C474BB94873E4487AE31A4E3845C79901550890EE8784EEF904FEE62BA8C5F952C68413052E0A7E3388BB8FF0AD602AE3EA14D9DF6DD5E4CC6A381A41DA5C137ECC49DF587E178EAF47702EC623780691A3233F69F12BD9C9B9637C51378AD71A831055277254CC63C5AD4CB76B4AB82E5FCA135E8D26A6B3A89FA5B6F"""), + xeh(""" +2AACD2E6B884BE6A3DDD80155BDCA80EBAF0E2BF714312BBA30D5B367F2D95AC7BEC3965AB05AFA370A42A512B5EFE4B0DEFF3E163AF186B725BCAFD2AFB2BD2A0DBAB74C2BF9362E27D69B6B4B5AA6500EBC9316EA4112745F1C6E98F2DEF9132C7C0BFFEAAFAF994C89B96D3F436B875178963FBC18D2E06ECAF3871787C1AE93B3210896837EC1DA87F0FD8F14AB7C5CB2531E90F415FEBDA378E5492E1DEC8243FE2E8A7BAA6FB6A034D9C524E99D848A804F150915BFD66067C8603B5DB0FE29E27D3F6CA629E96BF3E9C77A5919701EC19646C69A73DFAAB0ABA28FE3E9EAAEB475A441B9B0D62B259DC6B77DEC964AB57D5D776988D54E6246C526F1E8EFDF454E7F0DDAED5363CE02B279CD3B554C251793C3A616C07A7BABA8062919A2B46C64C152BC887A27E382254EA6D50CCC0702B7BC0994BAC09B7891FA64A773AE0B4FBF8204C13A4950FC2C4DF60CEFED7582FD9FBB8C83442517BA0E3B60D9A04FBB24ABCECB303E3FDD37F1037741FD2489F632192A6B9C122A7344CB781A0F61D5011EB0251A842AD4838F9B8D52E21A783F0D839E8BA221CCDD6B968A2B5FD21B8458BF53C9C8076AC0C52C0F53097ED1C25C9F6F12407772D6743EB8E0CE8B1A926F0FDD0DB00482D9590675E56D4509CB5E5F32FC3B4A2DAB2BA080F9A7CDD0B611742A8F83CEE1B091E629D2A0371FDB5A64412B5FA63716961527640D02885C4A09B04A3A6F5EC01A9E0DBB8FC4DDD9E05BDB240AC4878F0D41461C4661777417D6150422FEAB6A39F156CADB5F5D3BEBE417BABCEFF5AAD1B7A624FC23ABE28B2AB2E8273E8F44636A60CDAD9236DCB02FCF87722C899AA321C564B25BC33B4976BC9603BB8B8AB18B5B04625981FB38B2A42722CE2358FC0BA99EF4B122C7B70BB347D0D482DA30638EF8B9C1D9121D83BCDBBEB2A608617054F4B3FDD33E9A08F8DF999A98E715DBF04F8EFACF123BBEB37B9038E9AD906E3C570BB398C10E6D36647A2B0B2731FD39F726171EFC7321BC67D936F7989EA58336E549A34B73F097E3EA2C25887EC6A2E9FED5D2CFF475E99F392162D959DE1C4A4DAD3C96542756AEC3367F7B2515F2225BF7B704B780A6D0B279B8B4EE4879A9BBB2F3303216CBADEA00D229C03E3E2843892FA8E5B0A600D0E3EBDD14FA229819CE9C10B8D5F393DE0119A5B509B80D56B06783447F931177123824910C9BFDE9A29FBA0252E69A90B3E717832866115C06EA73B033EC3B0D45DFDB69A76B484DB0BE7A81215B3817E1C02F9A5DEE8967B147DF9F63C93A6E396DE4251A5A706DFDE9670B8B2F6C4C3E2509142256FDDA905C125FBBB294EB29A3B4D9BE3B67762AFC049B96B3F41B8C31BC5D7B522DCD1AD12B252370A8A57E42F6A9AC26FF784B374DA4B86FFDB65CC753CD049F1A21CF832447E1DF7BA7D0D11E403FC18BC545501E16568595AEB6BD7811C214CF2FB1CDFB07BB32321F536E3896B6EF4D16130ADD71B271CD1027E35538D9E475A3A53DFEA430C151DF7D516CD0D9B""") + ), + new DecapsulateTestCase( + xeh(""" +1E4AC87B1A692A529FDBBAB93374C57D110B10F2B1DDEBAC0D196B7BA631B8E9293028A8F379888C422DC8D32BBF226010C2C1EC73189080456B0564B258B0F23131BC79C8E8C11CEF3938B243C5CE9C0EDD37C8F9D29877DBBB615B9B5AC3C948487E467196A9143EFBC7CEDB64B45D4ACDA2666CBC2804F2C8662E128F6A9969EC15BC0B9351F6F96346AA7ABC743A14FA030E37A2E7597BDDFC5A22F9CEDAF8614832527210B26F024C7F6C0DCF551E97A4858764C321D1834AD51D75BB246D277237B7BD41DC4362D063F4298292272D01011780B79856B296C4E946658B79603197C9B2A99EC66ACB06CE2F69B5A5A61E9BD06AD443CEB0C74ED65345A903B614E81368AAC2B3D2A79CA8CCAA1C3B88FB82A36632860B3F7950833FD0212EC96EDE4AB6F5A0BDA3EC6060A658F9457F6CC87C6B620C1A1451987486E496612A101D0E9C20577C571EDB5282608BF4E1AC926C0DB1C82A504A799D89885CA6252BD5B1C183AF701392A407C05B848C2A3016C40613F02A449B3C7926DA067A533116506840097510460BBFD36073DCB0BFA009B36A9123EAA68F835F74A01B00D2097835964DF521CE9210789C30B7F06E5844B444C53322396E4799BAF6A88AF7315860D0192D48C2C0DA6B5BA64325543ACDF5900E8BC477AB05820072D463AFFED097E062BD78C99D12B385131A241B708865B4190AF69EA0A64DB71448A60829369C7555198E438C9ABC310BC70101913BB12FAA5BEEF975841617C847CD6B336F877987753822020B92C4CC97055C9B1E0B128BF11F505005B6AB0E627795A20609EFA991E598B80F37B1C6A1C3A1E9AEE7028F77570AB2139128A00108C50EB305CDB8F9A603A6B078413F6F9B14C6D82B5199CE59D887902A281A027B717495FE12672A127BBF9B256C43720D7C160B281C12757DA135B1933352BE4AB67E40248AFC318E2370C3B8208E695BDF337459B9ACBFE5B487F76E9B4B4001D6CF90CA8C699A174D42972DC733F33389FDF59A1DABA81D834955027334185AD02C76CF294846CA9294BA0ED66741DDEC791CAB34196AC5657C5A78321B56C33306B5102397A5C09C3508F76B48282459F81D0C72A43F737BC2F12F45422628B67DB51AC1424276A6C08C3F7615665BBB8E928148A270F991BCF365A90F87C30687B68809C91F231813B866BEA82E30374D80AA0C02973437498A53B14BF6B6CA1ED76AB8A20D54A083F4A26B7C038D81967640C20BF4431E71DACCE8577B21240E494C31F2D877DAF4924FD39D82D6167FBCC1F9C5A259F843E30987CCC4BCE7493A2404B5E44387F707425781B743FB555685584E2557CC038B1A9B3F4043121F5472EB2B96E5941FEC011CEEA50791636C6ABC26C1377EE3B5146FC7C85CB335B1E795EEC2033EE44B9AA90685245EF7B4436C000E66BC8BCBF1CDB803AC1421B1FDB266D5291C8310373A8A3CE9562AB197953871AB99F382CC5AA9C0F273D1DCA55D2712853871E1A83CB3B85450F76D3F3C42BAB5505F7212FDB6B8B7F6029972A8F3751E4C94C1108B02D6AC79F8D938F05A1B2C229B14B42B31B01A364017E59578C6B033833774CB9B570F9086B722903B375446B495D8A29BF80751877A80FB724A0210C3E1692F397C2F1DDC2E6BA17AF81B92ACFABEF5F7573CB493D184027B718238C89A3549B8905B28A83362867C082D3019D3CA70700731CEB73E8472C1A3A093361C5FEA6A7D40955D07A41B64E50081A361B604CC518447C8E25765AB7D68B243275207AF8CA6564A4CB1E94199DBA1878C59BEC809AB48B2F211BADC6A1998D9C7227C1303F469D46A9C7E5303F98ABA67569AE8227C16BA1FB3244466A25E7F823671810CC26206FEB29C7E2A1A91959EEB03A98252A4F7412674EB9A4B277E1F2595FCA64033B41B40330812E9735B7C607501CD8183A22AFC3392553744F33C4D202526945C6D78A60E201A16987A6FA59D94464B56506556784824A07058F57320E76C825B9347F2936F4A0E5CDAA18CF8833945AE312A36B5F5A3810AAC82381FDAE4CB9C6831D8EB8ABAB850416443D739086B1C326FC2A3975704E396A59680C3B5F360F5480D2B62169CD94CA71B37BC5878BA2985E068BA050B2CE50726D4B4451B77AAA8676EAE094982210192197B1E92A27F59868B78867887B9A70C32AF84630AA908814379E6519150BA16439B5E2B0603D06AA6674557F5B0983E5CB6A97596069B01BB3128C416680657204FD07640392E16B19F337A99A304844E1AA474E9C799062971F672268960F5A82F950070BBE9C2A71950A3785BDF0B8440255ED63928D257845168B1ECCC4191325AA76645719B28EBD89302DC6723C786DF5217B243099CA78238E57E64692F206B177ABC259660395CD7860FB35A16F6B2FE6548C85AB66330C517FA74CDF3CB49D26B1181901AF775A1E180813B6A24C456829B5C38104ECE43C76A437A6A33B6FC6C5E65C8A89466C1425485B29B9E1854368AFCA353E143D0A90A6C6C9E7FDB62A606856B5614F12B64B796020C3534C3605CFDC73B86714F411850228A28B8F4B49E663416C84F7E381F6AF1071343BF9D39B45439240CC03897295FEA080B14BB2D8119A880E164495C61BEBC7139C11857C85E1750338D6343913706A507C9566464CD2837CF914D1A3C35E89B235C6AB7ED078BED234757C02EF6993D4A273CB8150528DA4D76708177E9425546C83E147039766603B30DA6268F4598A53194240A2832A3D67533B5056F9AAAC61B4B17B9A2693AA0D58891E6CC56CDD772410900C405AF20B903797C64876915C37B8487A1449CE924CD345C29A36E08238F7A157CC7E516AB5BA73C8063F726BB5A0A0319E57127438C7FC601C99CCAAE4C1A83726FDCB5045ED1A82A985EA995396D77272C66CE493289F6110910F37C2741CE47026A6F8261999C6482572B1693912EF12EEBEA7ACF9234FB409F2A6090E6B0BFD895469D0B2A921BB723F87A33EA5465AB90F514B67698C0768B6CA498B022C512FA0875F054AA2265867E31C0E522651E024A07D60DD9F633166921F4126BC2B6AA01CC15A09B85BFF8218C5AAE95BC1FFB26AE5A137670F04910CA9D7241B6660C394C5455917746A26682FB71A432EA9530E839BDEB07433004F45A0DDAA0B24E3A566A540815F281E3FC259AC6CBC0ACB8D62268B603BC676AB415C474BB94873E4487AE31A4E3845C79901550890EE8784EEF904FEE62BA8C5F952C68413052E0A7E3388BB8FF0AD602AE3EA14D9DF6DD5E4CC6A381A41DA5C137ECC49DF587E178EAF47702EC623780691A3233F69F12BD9C9B9637C51378AD71A831055277254CC63C5AD4CB76B4AB82E5FCA135E8D26A6B3A89FA5B6F"""), + xeh(""" +8FFBC80E4662864D6F373DC8837AA91B3CC26B68124ABD73DAD025A1D1C18829DCF077D303579E5F39F4BE101BB9E355DFB5323882EACB3D184E6812C03A7BEBE25166D55F821A00F80B8D2BAB1A7EEC83D384AFDF30F6BBC9960C4662067EF7E200E37268B9F5348FF484642799258B45E541101A21FDD6FBFAA2374A28FAA97204953B95BBD1BB519785210DA7C8A09D071D8AFC9B29F2C3C2909A4C53671408B8083BCF5AE03D45C0CFBA399F44D24A06321BB74F6863B7D4BF0BFE73C8AF8EE1DDA45212E3F9C853D4D0E16F8EBDB8581C4ADEEE833D81A9E0A9E8587E9C19E689E6DF715564BCE27CFA73BA16226A77CE44DC496992F41AB918643C6D86A8B26ABA6F94F3502D22DD94FE55483F67C635B307745D33F17133293639118E70CE42C6DB7332D4862C73D5B84415454AD51F89B5559B5C85D6B6ED47B6958F21FBC2ADF8C8A9D43FD2E1B0C02418D227B83F85CBC3A81C719E8602781AE71E15E6D714919E52FCCCFD9A68B4751825BFBB53B7940B15B546158DBBC612E602F660B9E0FF439E0156C4C8792346014BA1B4838C7425AB34744DE51D854CBBA58B7E67E014122518036CE1541A1675AFEAE4F29A5318602ABBD0A1540F33176C984E306098DBD08E822ABB55F9FF38D9E31EA4695150F2CB60BC2EB5F4780CBEBB210CF48662C454C7A42360F306FB03617C998AD8A9297D6B71A71285F7AE8DFB336FA922540C92DC71F777D3B4D11D87B8D082FA8A00DF647CF7FEB27403D3CF50D829EEE3575A01E2CCA57849B11B14F001BE180DD5FA13C03B98EDEA6358C5AB30A526027CB45E33E646B37988CC84B979CC5CFC3BFDA05BD2C7B8CB1B11AFEE007E20FCCF8D0F764F4A6D2F6A8B74281800CBDCBBCF0DF1EC9D27E6A94968604D9EFD37928B6856C48F0108155595D03231DFC22DC0C8EE614090F37E0828B48A4DD371C677B5DBA95E417F12C9A396875FB05623F7A544AEAE41A0AA536FB8D767BA2E14752C84E147149F655AE7B903CAA591AE00267ADD3EA816612AB0B9A5FB263C70C4367062F7794274C75AC66F706AE93699859D55B2E4960E9D538F38A2FAEE366B80DC78BB673A9E1B057D711F9DDB3770947E6DD7BCFB425B96670506758AEA39A5ECB33A1B76B822AF903787DA3B61A7B9263C0FAE1B729B1A2E16FEB50C32A8728181D4E8A9F8376C39F6AABC2C022306B05E494CF9B6ADEEEC95887440508981D6A74707FCEFA24B9F0DC3AABC984E9C44174E6DFB51FCF4588C57F9659A8E7A6FAEAFBAE7ABE4600444936B3763463D4AE411DDC1C98585E0DE58867251079BE72075973275141801B98F7B9397C096A56B8CD83CFBD374E182F7DCC9A7C764DBBF4D7576A1CC9239848E7295D29CF034A1A7AE33A386C3DDC24A535168ED23D7ADE9433B50DC5694C969F4C546EF2293CD842F4B62B6B7435F597CF5C1733884E0A6AA47FA31887DEDC6C402D8ED013E49E5CAD7718CCEFEE0E6A041715CC9ADD79965413049ABCE88636AA7543EE2601F162838EF6B""") + ), + new DecapsulateTestCase( + xeh(""" +1E4AC87B1A692A529FDBBAB93374C57D110B10F2B1DDEBAC0D196B7BA631B8E9293028A8F379888C422DC8D32BBF226010C2C1EC73189080456B0564B258B0F23131BC79C8E8C11CEF3938B243C5CE9C0EDD37C8F9D29877DBBB615B9B5AC3C948487E467196A9143EFBC7CEDB64B45D4ACDA2666CBC2804F2C8662E128F6A9969EC15BC0B9351F6F96346AA7ABC743A14FA030E37A2E7597BDDFC5A22F9CEDAF8614832527210B26F024C7F6C0DCF551E97A4858764C321D1834AD51D75BB246D277237B7BD41DC4362D063F4298292272D01011780B79856B296C4E946658B79603197C9B2A99EC66ACB06CE2F69B5A5A61E9BD06AD443CEB0C74ED65345A903B614E81368AAC2B3D2A79CA8CCAA1C3B88FB82A36632860B3F7950833FD0212EC96EDE4AB6F5A0BDA3EC6060A658F9457F6CC87C6B620C1A1451987486E496612A101D0E9C20577C571EDB5282608BF4E1AC926C0DB1C82A504A799D89885CA6252BD5B1C183AF701392A407C05B848C2A3016C40613F02A449B3C7926DA067A533116506840097510460BBFD36073DCB0BFA009B36A9123EAA68F835F74A01B00D2097835964DF521CE9210789C30B7F06E5844B444C53322396E4799BAF6A88AF7315860D0192D48C2C0DA6B5BA64325543ACDF5900E8BC477AB05820072D463AFFED097E062BD78C99D12B385131A241B708865B4190AF69EA0A64DB71448A60829369C7555198E438C9ABC310BC70101913BB12FAA5BEEF975841617C847CD6B336F877987753822020B92C4CC97055C9B1E0B128BF11F505005B6AB0E627795A20609EFA991E598B80F37B1C6A1C3A1E9AEE7028F77570AB2139128A00108C50EB305CDB8F9A603A6B078413F6F9B14C6D82B5199CE59D887902A281A027B717495FE12672A127BBF9B256C43720D7C160B281C12757DA135B1933352BE4AB67E40248AFC318E2370C3B8208E695BDF337459B9ACBFE5B487F76E9B4B4001D6CF90CA8C699A174D42972DC733F33389FDF59A1DABA81D834955027334185AD02C76CF294846CA9294BA0ED66741DDEC791CAB34196AC5657C5A78321B56C33306B5102397A5C09C3508F76B48282459F81D0C72A43F737BC2F12F45422628B67DB51AC1424276A6C08C3F7615665BBB8E928148A270F991BCF365A90F87C30687B68809C91F231813B866BEA82E30374D80AA0C02973437498A53B14BF6B6CA1ED76AB8A20D54A083F4A26B7C038D81967640C20BF4431E71DACCE8577B21240E494C31F2D877DAF4924FD39D82D6167FBCC1F9C5A259F843E30987CCC4BCE7493A2404B5E44387F707425781B743FB555685584E2557CC038B1A9B3F4043121F5472EB2B96E5941FEC011CEEA50791636C6ABC26C1377EE3B5146FC7C85CB335B1E795EEC2033EE44B9AA90685245EF7B4436C000E66BC8BCBF1CDB803AC1421B1FDB266D5291C8310373A8A3CE9562AB197953871AB99F382CC5AA9C0F273D1DCA55D2712853871E1A83CB3B85450F76D3F3C42BAB5505F7212FDB6B8B7F6029972A8F3751E4C94C1108B02D6AC79F8D938F05A1B2C229B14B42B31B01A364017E59578C6B033833774CB9B570F9086B722903B375446B495D8A29BF80751877A80FB724A0210C3E1692F397C2F1DDC2E6BA17AF81B92ACFABEF5F7573CB493D184027B718238C89A3549B8905B28A83362867C082D3019D3CA70700731CEB73E8472C1A3A093361C5FEA6A7D40955D07A41B64E50081A361B604CC518447C8E25765AB7D68B243275207AF8CA6564A4CB1E94199DBA1878C59BEC809AB48B2F211BADC6A1998D9C7227C1303F469D46A9C7E5303F98ABA67569AE8227C16BA1FB3244466A25E7F823671810CC26206FEB29C7E2A1A91959EEB03A98252A4F7412674EB9A4B277E1F2595FCA64033B41B40330812E9735B7C607501CD8183A22AFC3392553744F33C4D202526945C6D78A60E201A16987A6FA59D94464B56506556784824A07058F57320E76C825B9347F2936F4A0E5CDAA18CF8833945AE312A36B5F5A3810AAC82381FDAE4CB9C6831D8EB8ABAB850416443D739086B1C326FC2A3975704E396A59680C3B5F360F5480D2B62169CD94CA71B37BC5878BA2985E068BA050B2CE50726D4B4451B77AAA8676EAE094982210192197B1E92A27F59868B78867887B9A70C32AF84630AA908814379E6519150BA16439B5E2B0603D06AA6674557F5B0983E5CB6A97596069B01BB3128C416680657204FD07640392E16B19F337A99A304844E1AA474E9C799062971F672268960F5A82F950070BBE9C2A71950A3785BDF0B8440255ED63928D257845168B1ECCC4191325AA76645719B28EBD89302DC6723C786DF5217B243099CA78238E57E64692F206B177ABC259660395CD7860FB35A16F6B2FE6548C85AB66330C517FA74CDF3CB49D26B1181901AF775A1E180813B6A24C456829B5C38104ECE43C76A437A6A33B6FC6C5E65C8A89466C1425485B29B9E1854368AFCA353E143D0A90A6C6C9E7FDB62A606856B5614F12B64B796020C3534C3605CFDC73B86714F411850228A28B8F4B49E663416C84F7E381F6AF1071343BF9D39B45439240CC03897295FEA080B14BB2D8119A880E164495C61BEBC7139C11857C85E1750338D6343913706A507C9566464CD2837CF914D1A3C35E89B235C6AB7ED078BED234757C02EF6993D4A273CB8150528DA4D76708177E9425546C83E147039766603B30DA6268F4598A53194240A2832A3D67533B5056F9AAAC61B4B17B9A2693AA0D58891E6CC56CDD772410900C405AF20B903797C64876915C37B8487A1449CE924CD345C29A36E08238F7A157CC7E516AB5BA73C8063F726BB5A0A0319E57127438C7FC601C99CCAAE4C1A83726FDCB5045ED1A82A985EA995396D77272C66CE493289F6110910F37C2741CE47026A6F8261999C6482572B1693912EF12EEBEA7ACF9234FB409F2A6090E6B0BFD895469D0B2A921BB723F87A33EA5465AB90F514B67698C0768B6CA498B022C512FA0875F054AA2265867E31C0E522651E024A07D60DD9F633166921F4126BC2B6AA01CC15A09B85BFF8218C5AAE95BC1FFB26AE5A137670F04910CA9D7241B6660C394C5455917746A26682FB71A432EA9530E839BDEB07433004F45A0DDAA0B24E3A566A540815F281E3FC259AC6CBC0ACB8D62268B603BC676AB415C474BB94873E4487AE31A4E3845C79901550890EE8784EEF904FEE62BA8C5F952C68413052E0A7E3388BB8FF0AD602AE3EA14D9DF6DD5E4CC6A381A41DA5C137ECC49DF587E178EAF47702EC623780691A3233F69F12BD9C9B9637C51378AD71A831055277254CC63C5AD4CB76B4AB82E5FCA135E8D26A6B3A89FA5B6F"""), + xeh(""" +17976BAC62F66CEF2B6F947C121079B6F2E9350C137E738BFD884FF2BA6E211640A30FBF2695EDF7046E1F5234AB1C8A9B0E8A3FF88EF18C1E5512D5F69E4A36CC9362F00920481E5460B1FB0C2B9FF0CD0D95718966AF7EC1F76B8DA93F6AB179A5DE70DEE34C579E284AE8504ED96E1A85898076F69AAFEC1357533EBB636FBA2372204DAB87C47AF27D4D9EB1B4FF4286D6A9FA7FD506C9FEBA596D2047DB765C1EBF1F7921867D394487F6BE926E6B0323058CB591195436ECC805C8B88615C7A03833AABF490337063DFEED698F7DA8DD589A794C956C2BF8D8CA4AE18B0A7767693802BD6DD53F543E105EC526C1D1D00AC9C0B606BD9B3A1D52CB8C56F8535ECADD8239308F2FE7E1D7BFAC5848B547B4579AFC13A0B2BEDEFA46322F92E2B73980695369C5F48D37F9345F20C7820DB6DE09D5E8313B73ED705B33646FB14CC4D40D65290A4C27360FBBD080E61A16BB15E9560A097E4AEC16F8B8030FAE1D47E024F10C33E6A1C56AEB8EC2F6AD6EF4B8FF04C67307B23E470FB3E5BCB6F533F955C36FDB46516A07DFF2956130AD0924158CC2A083378FB9AE32DE89CF774D82C2FC70DA48536372299C61927A5AE67E55E792B64FE61F06EFFC1F216CC9D739ADBF3B2190E1D080E00F169F145FE32AF7EC7CBA1D76FA6839D5FD2068E1DFFF557755FF2F4271204A5468C79C7BB8D00FAD63938F12D53B243B3FF866556913EB57AD2AE034F8B62B1A1B9DA2B1D45800B4CEF1E1943A0C92F0EF2EE924F80CF67EBD3D0199D45ED4DCC00140829A0992DB43616CC468508B852EB822066A05CC91D6BC2B47E5622B774F8128ECBBB94CADD15588B36A71E9FD97B05D69E8BAF00D30A3D3C00E663E00AFC9F5E1BAC8534ED5F6E5AB47D7EFDF6537753408299A9E8D5F5AE0FE36A9EC41C6DC9F78A891BFA9C8E90AA1A457A0C01AF70CBC9E55B68A5D8CC5CD3BD6886AE11FF510C6ED0EB2F5C081B25989518BA217BC1C153864E5BB312EF0D43D6DA4A0FDE44F1157CD238E8D70BEB420BD310F8E5DB9D74EF4EC9980CBA74358FC77C5D4FAE3036E176647D78C73900C79BFBF0BC545ABF7CBB4DC7F6041D4FA3B66E4D4655E24B11DC30B0061C452A605CE73362F2A3F052370D873FC68DFFCD3999FDEDB45DD9F2A02B4699BCF1FC5F888B019B5028465F30AEFAD946D481285D1122EA78F3BD8B1982558C38FA3DF0F058B12EEBB11F4C7809F6334EA1D7FE0B529C0BC9C67044648178D2AE9232E4E88DD6D0016D8A590B7703F1A017A4A2671BBB24FA97ADE1B61C489AFE9B3E63CF4CCC42168C98880921C2C0EA7D24DB6DD676B77F7B6C0525C8D0578C7F5A20DBF2F82873904D7CF2522CE6360397B254B18C3059A4BEA169A44D9BA17CFDA1827EABECD269FD391CBC0D49D71FA81AC16F9A0DED9E72A58D1BC2262979D8D7E531D1C46A8F107BDA18A1D2CCD17334183DD3E79D905ACA7DAD348BC6D5CE124A1397EB3B89BE7580720B5DD00BD3A63DAD813E0E967EFEDF17F3D960E70A4F83F""") + ) + }; + + static DecapsulateTestCase[] decap1024TestCases = new DecapsulateTestCase[] { + new DecapsulateTestCase( + xeh(""" +8445C336F3518B298163DCBB6357597983CA2E873DCB49610CF52F14DBCB947C1F3EE9266967276B0C576CF7C30EE6B93DEA5118676CBEE1B1D4794206FB369ABA41167B4393855C84EBA8F32373C05BAE7631C802744AADB6C2DE41250C494315230B52826C34587CB21B183B49B2A5AC04921AC6BFAC1B24A4B37A93A4B168CCE7591BE6111F476260F2762959F5C1640118C2423772E2AD03DC7168A38C6DD39F5F7254264280C8BC10B914168070472FA880ACB8601A8A0837F25FE194687CD68B7DE2340F036DAD891D38D1B0CE9C2633355CF57B50B896036FCA260D2669F85BAC79714FDAFB41EF80B8C30264C31386AE60B05FAA542A26B41EB85F67068F088034FF67AA2E815AAB8BCA6BF71F70ECC3CBCBC45EF701FCD542BD21C7B09568F369C669F396473844FBA14957F51974D852B978014603A210C019036287008994F21255B25099AD82AA132438963B2C0A47CDF5F32BA46B76C7A6559F18BFD555B762E487B6AC992FE20E283CA0B3F6164496955995C3B28A57BBC29826F06FB38B253470AF631BC46C3A8F9CE824321985DD01C05F69B824F916633B40654C75AAEB9385576FFDE2990A6B0A3BE829D6D84E34F1780589C79204C63C798F55D23187E461D48C21E5C047E535B19F458BBA1345B9E41E0CB4A9C2D8C40B490A3BABC553B3026B1672D28CBC8B498A3A99579A832FEAE74610F0B6250CC333E9493EB1621ED34AA4AB175F2CA231152509ACB6AC86B20F6B39108439E5EC12D465A0FEF35003E14277A21812146B2544716D6AB82D1B0726C27A98D589EBDACC4C54BA77B2498F217E14E34E66025A2A143A992520A61C0672CC9CCED7C9450C683E90A3E4651DB623A6DB39AC26125B7FC1986D7B0493B8B72DE7707DC20BBDD43713156AF7D9430EF45399663C2202739168692DD657545B056D9C92385A7F414B34B90C7960D57B35BA7DDE7B81FCA0119D741B12780926018FE4C8030BF038E18B4FA33743D0D3C846417E9D5915C246315938B1E233614501D026959551258B233230D428B181B132F1D0B026067BA816999BC0CD6B547E548B63C9EAA091BAC493DC598DBC2B0E146A2591C2A8C009DD5170AAE027C541A1B5E66E45C65612984C46770493EC896EF25AA9305E9F06692CD0B2F06962E205BEBE113A34EBB1A4830A9B3749641BB935007B23B24BFE576956254D7A35AA496AC446C67A7FEC85A60057E8580617BCB3FAD15C76440FED54CC789394FEA24452CC6B0585B7EB0A88BBA9500D9800E6241AFEB523B55A96A535151D1049573206E59C7FEB070966823634F77D5F1291755A243119621AF8084AB7AC1E22A0568C6201417CBE3655D8A08DD5B513884C98D5A493FD49382EA41860F133CCD601E885966426A2B1F23D42D82E24582D99725192C21777467B1457B1DD429A0C41A5C3D704CEA06278C59941B438C62727097809B4530DBE837EA396B6D31077FAD3733053989A8442AAC4255CB163B8CA2F27501EA967305695ABD659AA02C83EE60BB574203E9937AE1C621C8ECB5CC1D21D556960B5B9161EA96FFFEBAC72E1B8A6154FC4D88B56C04741F090CBB156A737C9E6A22BA8AC704BC304F8E17E5EA845FDE59FBF788CCE0B97C8761F89A242F3052583C6844A632031C964A6C4A85A128A28619BA1BB3D1BEA4B49841FC847614A066841F52ED0EB8AE0B8B096E92B8195405815B231266F36B18C1A53333DAB95D2A9A374B5478A4A41FB8759957C9AB22CAE545AB544BA8DD05B83F3A613A2437ADB073A9635CB4BBC965FB454CF27B298A40CD0DA3B8F9CA99D8CB4286C5EB476416796070BA535AAA58CDB451CD6DB5CBB0CA20F0C71DE97C30DA97EC7906D06B4B939396028C46BA0E7A865BC8308A3810F1212006339F7BC169B1666FDF475911BBC8AAAB41755C9A8AABFA23C0E37F84FE46999E030494B9298EF9934E8A649C0A5CCE2B22F31809AFED23955D87881D99FC1D352896CAC9055BEA0D016CCBA7805A3A50E221630379BD01135221CAD5D9517C8CC42637B9FC0718E9A9BB4945C72D8D11D3D659D83A3C419509AF5B470DD89B7F3ACCF5F35CFC322115FD66A5CD2875651326F9B3168913BE5B9C87AE0B025EC7A2F4A072750946AC61170A7826D9704C5A23A1C0A2325146C3BC1858826C6B39279C2DA7438A370ED8A0AA5169E3BEC29ED88478732758D454143E227F8595883297842E6AF133B17E4811B0F5713AC73B7E347423EB92822D2306FA14500A7207A0672672046544ACC4EA9C16ED7421A069E0D737A98628519C6A29A424A868B46D9A0CC7C6C9DDD8B8BCBF422C8F48A73143D5ABB66BC55499418430802BAC544463CC7319D17998F29411365766D04C847F3129D9077B7D8339BFB96A6739C3F6B74A8F05F9138AB2FE37ACB57634D1820B50176F5A0B6BC2940F1D5938F1936B5F95828B92EB72973C1590AEB7A552CECA10B00C303B7C75D402071A79E2C810AF7C745E3336712492A42043F2903A37C6434CEE20B1D159B057699FF9C1D3BD68029839A08F43E6C1C819913532F911DD370C7021488E11CB504CB9C70570FFF35B4B4601191DC1AD9E6ADC5FA9618798D7CC860C87A939E4CCF8533632268CF1A51AFF0CB811C5545CB1656E65269477430699CCDEA3800630B78CD5810334CCF02E013F3B80244E70ACDB060BBE7A553B063456B2EA807473413165CE57DD563473CFBC90618ADE1F0B888AA48E722BB2751858FE19687442A48E7CA0D2A29CD51BFD8F78C17B9660BFB54A470B2AE9A955C6AB8D6E5CC92AC8ED3C185DAA8BC29F0578EBB812B97C9E5A848A6384DE4E75A31470B53066A8D027BA44B21749C0492465F9072B28376C4E290B30C1863F9E5B79996083422BD8C272C10ECC6EB9A0A8225B31AA0A66E35B9C0B9A79582BA20A3C04CD29914F083A0158288BA4D6EB62D87264B912BCA39732FBDE536A377AD02B8C835D4A2F4E7B1CE115D0C860BEAA7955A49AD689586A89A2B9F9B10D1595D2FC065AD018A7D56C614471F8E946FE8AB49E8226591119FCADB4F9A861631378736B6688B782D58E97E4572753A9664B6B8536812B25911AA76A242375433192738EEE762F6B84315BB3436231E0A9B277ED28AE0050728346457E13405062DB2804B8DA60BB5C793D4CC0E101CBA2D9182FD7124FF52BF4CA28292AC26D678088953971DBA0B6FEC2C9659353291C70C5B9245A0CA253304AFD3C95102BEA66875C6201680B4BDA38687B648C28EB37478E3BC00CA8A3CC27204642B42B68FCBE7B21A366D0668A5029A7DEEF94CDD6A95D7EA8931673BF7112D4042107B1B8B9700C974F9C4E83A8FACD89BFE0CA3CC4C2FCE80A03D3576C222A792B72B1F070AB7F6B6F2B5CA2AF5054AFA70A896990159B45D1003E2A05648675E596016F1B71DD0F7BDA7E2097FC73B3A143D12C726020AC34958AD7062B92B9ABF3CA6BE5AE29F57135E625A367971837E6363D1532094E022A23467CF932E1F89B5B0803C1EC99B585A78B5865096746F32258214ECB38065C97F455E155ACC2DD005A9C76BED59CDA73837D303504E6C976A606A2BE7BBEC5948B91A349E8936688CC0279754B743ABC58666B19B6C3260051F19206BB962BB6633EB0048E32BAACC5B020D02C86CA9770AD469DB54A106AC73A35B8057422B3DB202C5A5B4E3D535F0FC99326C4B8B7B16F1CB5AF96803FA8C195FC0BCEDDAAF012A51728B76489082373C91E92C87ACCA795160782E3B0DD643544BB96ABC2708D49B759CF057AA223BAFD96A330BAF39810FE8671B4343C297DA1E1969C996216AB5106DA668941B160D4477017136CBCA5B5A8D44C4A8B1CF3EF79785E5AA25C3A1AD6C24FD140F79207DE5A499F8A1534FFA804AA7B3889CBE25C0414704AA57897F17862364ECA56258007248813912B836497F0359C2F7238A05D305A0EA152E72B44417A868134E91B3CA7931232FD4C25F8C2A492A339CDC0A138967211451F2562678FA14080A34436C42B07865AC036A81E97A7787A938025CAF813450368BED0C94B1857604526405D27A1C1ABC81B5B6EC13C71930A97D9232CF7021EF87A4D155328E62B583A83B4AF21F9F5750F8575150424F63B899D71CAD267C09E4467146E16E9B6C653F008C311375E2E006D4076A546B82F5314222F7C654317E79EC6035B73FAF491757E61C828326D53044541C4D4537ABD3EA1E67998C3382974CA78AE1B1960E4A9226B0219AB070F0D7AA66D76F9316ADB80C54D6499771B471E8168D47BCAA08324AB6BA92C3A70275F24FA4DC10E251633FB98D162BB5537202C6A553CE7841C4D40B873B85CA03A0A1E1CFADE6BA5180AB1323CCBA9A3E9C53D37575AB1FD9E7316C6FEECB0A14DF6F2DA56C2F56F55A89635CFCFDA47927AF1F0A47B2D4E4E61634B1B51D37A3A307A972420DE1B7A481B83E583B6AF16F63CB00C6"""), + xeh(""" +0C681B4AA81F26ADFB645EC24B3752F6B32C68645AA5E7A999B62036A53DC5CB060A473C08E5DA5C0F5AF0E5170C6597E50EC08060F99B0C00EE9BDDAD7E7D25A22B226F90149B4CE887C72FB60AFF2144EA2A72383B3118F922D032A16F554289902A14CF7755512BB1186BAFAFFE794D2B6CDE90109E6582D39CE0C96197484B3FA07FC91D394FC8D88E7FC4BE002E2DB56F0C4D9D3FBDA274536A0B86ABC6E39BDA52931AEBB8F1084C5C1F7CB3177788B7F331B7074361163491D428E78BCBB57B630841AA987333377CF09569CFD14CC2A11C501BDF82C93DE05BEA20060DE89C686B824571CEF94AB3FDAFA8512619813669D4F53637FEFA4D028CB233E56930E2235F7E6034CA94B143B77AD4A68756E8A9184DBA61A89F91EDFB51A39211402473A5F89145736B2BF8569C705B0CDB8980A447E4E1EAAD3E7E0578F5F86B8D03C9DAFE875E339B4423845616799EDCE05F31B92664C5A59253A60E9D89548A300C1ADB6D190A775C5EE6E8A89B6E779B034C3400A625F4BBEDBF919C45B2BCD14C669248FC43C3EF47E100758942E75E8ED6075A96D70D4EBD2B61358224DDA1EC4C19C2A92898176FEB3C02EDCB9908BAE49BD94AF028EDF8CFC2E5F2E0BD375006986AD49E717548E746FEF49C868BCEA2790AA97E04061B75605CB39EFD463D7B3D68BA574434FF7BE8E2B84BFC47E67E9CD15F3ED450C61AFBA79A20B0B6F287777C72F4AD248174F1959477AA7A7C97F122C50447C7484F382BC47D81FCC9C7E892C8839D37B35394B53E6B2B1895ABB0DE8C98F2633DC4413A8D5735DFC9A64026B6F34779D6AC8AD99CC31AA898C2E7057F3DB8A1A8A98527A79E43552F28D1023E1F6A6B84855CF5E6DF889BA269F048946E84021C65C5A93B007B07741C1EE176C73949110F548EF4332DCDD491D2CEFD0248883F5E9525BC91F30AF17CF5A98DD44EF9A71F99BB732985BA10A723EF476FCF966DA9456B24978E33050D0EC90D3CE46378851C9ECFCFD36C895D44E9E506993082523D26185766B23568CB95E64108F89D1014747C67B6F3C8767BE5FC341227DE9488861C5FE811409F80957D07522A72CF6AB0378D0F2F28AF548185C3936777994466A019D33B18A54F380A33892AB4D4BD507B5A61D0D358341AC92F07B43B8F6AFC6991BB6A1EAC23CA6F73E91F2464BD119098D7E768E77ECE53FB899BEB42265ECF7B271F66546282D472C36239006BB0ABABCCA24550BAA0A601348C810FF5F9EE504BF7155DEE4141A11605A4F3509AC9CAEF6624D21DE332D5D50828B52E92885D3B90553B14463AFB1EDCCD3B569B5A7F00BB66769DADAC23AD8BB5D73A6F390E6FC2F6F8EE3CF4009A5C3E1EF60E8F040672D262E6490379BBC70495DFF237BECD9952CD7EDEB6D1DFC360B3FC8B0AF480FFE024AEEFCD4E9CE95D9B469C9A70E5110DA0BAC124FC3741DCF49116261796504D5F490B433C33C40EDCE2B75151DA256A868A5E35F86226B8151C91934CCC3DACA391DECCA745375660B6EC41AE5D810838CBEEFFA12557884412357B1008363D32B237AA1DD8E2D9C6367ADA09B2C95060206CEC3EED391FDC5DBEF6F08BDF0408E585AE5EBC8E9745D44FECA975ABBC140BB37B8ADD16FCC2956910DC72BB3F02E9A130C9A84F9CCB74D134CDF40AFCBA2009C8F0040239BC99220EF64C4DCCDE2E2E5C9B68602FBE8EF4C98B3468C79DF4E078511BFB8AA3DA09597A02511E7C21A7CF66A93843A94868F19E8552552E3ACDF6CB810634DB97CBC4BB569709DAD4845645446FA8D289FC59307B801E60CE2A91E06E9C22C16E2E59BDE38A416BB1B4AC5457438FDC5D64450A89ECB832C1BB279DBF59334681776AC00409846D09D6F687772E340850AB8673384215E12C8D0F531C451E58493E0EE415AD594DF38C34408C7ED9F0C392F1534604EAC3D9C15465A9A46632214B536990D78078E5BD7EAE2013FFF8FDD8B275C89D97C9353DF3C42A28E814D8468E2B48DB0976D88F5EECEFEAFB8F7F4AF291A728F6249ECF5622339269AA945329E919F8B441C83D5507F30DF0FD2B13FF806F522DAA11AF676A513C149C70F0D6E99A880450A54E0417FE3C1E513E9D920E30A8B42891267A2DC50AD81F98044920C099DF22C73998A25C581A5178C72B17AC875BC68548A0FB0CBEE38F05017B12433343A658F1980C8124EA6DD81F""") + ), + new DecapsulateTestCase( + xeh(""" +8445C336F3518B298163DCBB6357597983CA2E873DCB49610CF52F14DBCB947C1F3EE9266967276B0C576CF7C30EE6B93DEA5118676CBEE1B1D4794206FB369ABA41167B4393855C84EBA8F32373C05BAE7631C802744AADB6C2DE41250C494315230B52826C34587CB21B183B49B2A5AC04921AC6BFAC1B24A4B37A93A4B168CCE7591BE6111F476260F2762959F5C1640118C2423772E2AD03DC7168A38C6DD39F5F7254264280C8BC10B914168070472FA880ACB8601A8A0837F25FE194687CD68B7DE2340F036DAD891D38D1B0CE9C2633355CF57B50B896036FCA260D2669F85BAC79714FDAFB41EF80B8C30264C31386AE60B05FAA542A26B41EB85F67068F088034FF67AA2E815AAB8BCA6BF71F70ECC3CBCBC45EF701FCD542BD21C7B09568F369C669F396473844FBA14957F51974D852B978014603A210C019036287008994F21255B25099AD82AA132438963B2C0A47CDF5F32BA46B76C7A6559F18BFD555B762E487B6AC992FE20E283CA0B3F6164496955995C3B28A57BBC29826F06FB38B253470AF631BC46C3A8F9CE824321985DD01C05F69B824F916633B40654C75AAEB9385576FFDE2990A6B0A3BE829D6D84E34F1780589C79204C63C798F55D23187E461D48C21E5C047E535B19F458BBA1345B9E41E0CB4A9C2D8C40B490A3BABC553B3026B1672D28CBC8B498A3A99579A832FEAE74610F0B6250CC333E9493EB1621ED34AA4AB175F2CA231152509ACB6AC86B20F6B39108439E5EC12D465A0FEF35003E14277A21812146B2544716D6AB82D1B0726C27A98D589EBDACC4C54BA77B2498F217E14E34E66025A2A143A992520A61C0672CC9CCED7C9450C683E90A3E4651DB623A6DB39AC26125B7FC1986D7B0493B8B72DE7707DC20BBDD43713156AF7D9430EF45399663C2202739168692DD657545B056D9C92385A7F414B34B90C7960D57B35BA7DDE7B81FCA0119D741B12780926018FE4C8030BF038E18B4FA33743D0D3C846417E9D5915C246315938B1E233614501D026959551258B233230D428B181B132F1D0B026067BA816999BC0CD6B547E548B63C9EAA091BAC493DC598DBC2B0E146A2591C2A8C009DD5170AAE027C541A1B5E66E45C65612984C46770493EC896EF25AA9305E9F06692CD0B2F06962E205BEBE113A34EBB1A4830A9B3749641BB935007B23B24BFE576956254D7A35AA496AC446C67A7FEC85A60057E8580617BCB3FAD15C76440FED54CC789394FEA24452CC6B0585B7EB0A88BBA9500D9800E6241AFEB523B55A96A535151D1049573206E59C7FEB070966823634F77D5F1291755A243119621AF8084AB7AC1E22A0568C6201417CBE3655D8A08DD5B513884C98D5A493FD49382EA41860F133CCD601E885966426A2B1F23D42D82E24582D99725192C21777467B1457B1DD429A0C41A5C3D704CEA06278C59941B438C62727097809B4530DBE837EA396B6D31077FAD3733053989A8442AAC4255CB163B8CA2F27501EA967305695ABD659AA02C83EE60BB574203E9937AE1C621C8ECB5CC1D21D556960B5B9161EA96FFFEBAC72E1B8A6154FC4D88B56C04741F090CBB156A737C9E6A22BA8AC704BC304F8E17E5EA845FDE59FBF788CCE0B97C8761F89A242F3052583C6844A632031C964A6C4A85A128A28619BA1BB3D1BEA4B49841FC847614A066841F52ED0EB8AE0B8B096E92B8195405815B231266F36B18C1A53333DAB95D2A9A374B5478A4A41FB8759957C9AB22CAE545AB544BA8DD05B83F3A613A2437ADB073A9635CB4BBC965FB454CF27B298A40CD0DA3B8F9CA99D8CB4286C5EB476416796070BA535AAA58CDB451CD6DB5CBB0CA20F0C71DE97C30DA97EC7906D06B4B939396028C46BA0E7A865BC8308A3810F1212006339F7BC169B1666FDF475911BBC8AAAB41755C9A8AABFA23C0E37F84FE46999E030494B9298EF9934E8A649C0A5CCE2B22F31809AFED23955D87881D99FC1D352896CAC9055BEA0D016CCBA7805A3A50E221630379BD01135221CAD5D9517C8CC42637B9FC0718E9A9BB4945C72D8D11D3D659D83A3C419509AF5B470DD89B7F3ACCF5F35CFC322115FD66A5CD2875651326F9B3168913BE5B9C87AE0B025EC7A2F4A072750946AC61170A7826D9704C5A23A1C0A2325146C3BC1858826C6B39279C2DA7438A370ED8A0AA5169E3BEC29ED88478732758D454143E227F8595883297842E6AF133B17E4811B0F5713AC73B7E347423EB92822D2306FA14500A7207A0672672046544ACC4EA9C16ED7421A069E0D737A98628519C6A29A424A868B46D9A0CC7C6C9DDD8B8BCBF422C8F48A73143D5ABB66BC55499418430802BAC544463CC7319D17998F29411365766D04C847F3129D9077B7D8339BFB96A6739C3F6B74A8F05F9138AB2FE37ACB57634D1820B50176F5A0B6BC2940F1D5938F1936B5F95828B92EB72973C1590AEB7A552CECA10B00C303B7C75D402071A79E2C810AF7C745E3336712492A42043F2903A37C6434CEE20B1D159B057699FF9C1D3BD68029839A08F43E6C1C819913532F911DD370C7021488E11CB504CB9C70570FFF35B4B4601191DC1AD9E6ADC5FA9618798D7CC860C87A939E4CCF8533632268CF1A51AFF0CB811C5545CB1656E65269477430699CCDEA3800630B78CD5810334CCF02E013F3B80244E70ACDB060BBE7A553B063456B2EA807473413165CE57DD563473CFBC90618ADE1F0B888AA48E722BB2751858FE19687442A48E7CA0D2A29CD51BFD8F78C17B9660BFB54A470B2AE9A955C6AB8D6E5CC92AC8ED3C185DAA8BC29F0578EBB812B97C9E5A848A6384DE4E75A31470B53066A8D027BA44B21749C0492465F9072B28376C4E290B30C1863F9E5B79996083422BD8C272C10ECC6EB9A0A8225B31AA0A66E35B9C0B9A79582BA20A3C04CD29914F083A0158288BA4D6EB62D87264B912BCA39732FBDE536A377AD02B8C835D4A2F4E7B1CE115D0C860BEAA7955A49AD689586A89A2B9F9B10D1595D2FC065AD018A7D56C614471F8E946FE8AB49E8226591119FCADB4F9A861631378736B6688B782D58E97E4572753A9664B6B8536812B25911AA76A242375433192738EEE762F6B84315BB3436231E0A9B277ED28AE0050728346457E13405062DB2804B8DA60BB5C793D4CC0E101CBA2D9182FD7124FF52BF4CA28292AC26D678088953971DBA0B6FEC2C9659353291C70C5B9245A0CA253304AFD3C95102BEA66875C6201680B4BDA38687B648C28EB37478E3BC00CA8A3CC27204642B42B68FCBE7B21A366D0668A5029A7DEEF94CDD6A95D7EA8931673BF7112D4042107B1B8B9700C974F9C4E83A8FACD89BFE0CA3CC4C2FCE80A03D3576C222A792B72B1F070AB7F6B6F2B5CA2AF5054AFA70A896990159B45D1003E2A05648675E596016F1B71DD0F7BDA7E2097FC73B3A143D12C726020AC34958AD7062B92B9ABF3CA6BE5AE29F57135E625A367971837E6363D1532094E022A23467CF932E1F89B5B0803C1EC99B585A78B5865096746F32258214ECB38065C97F455E155ACC2DD005A9C76BED59CDA73837D303504E6C976A606A2BE7BBEC5948B91A349E8936688CC0279754B743ABC58666B19B6C3260051F19206BB962BB6633EB0048E32BAACC5B020D02C86CA9770AD469DB54A106AC73A35B8057422B3DB202C5A5B4E3D535F0FC99326C4B8B7B16F1CB5AF96803FA8C195FC0BCEDDAAF012A51728B76489082373C91E92C87ACCA795160782E3B0DD643544BB96ABC2708D49B759CF057AA223BAFD96A330BAF39810FE8671B4343C297DA1E1969C996216AB5106DA668941B160D4477017136CBCA5B5A8D44C4A8B1CF3EF79785E5AA25C3A1AD6C24FD140F79207DE5A499F8A1534FFA804AA7B3889CBE25C0414704AA57897F17862364ECA56258007248813912B836497F0359C2F7238A05D305A0EA152E72B44417A868134E91B3CA7931232FD4C25F8C2A492A339CDC0A138967211451F2562678FA14080A34436C42B07865AC036A81E97A7787A938025CAF813450368BED0C94B1857604526405D27A1C1ABC81B5B6EC13C71930A97D9232CF7021EF87A4D155328E62B583A83B4AF21F9F5750F8575150424F63B899D71CAD267C09E4467146E16E9B6C653F008C311375E2E006D4076A546B82F5314222F7C654317E79EC6035B73FAF491757E61C828326D53044541C4D4537ABD3EA1E67998C3382974CA78AE1B1960E4A9226B0219AB070F0D7AA66D76F9316ADB80C54D6499771B471E8168D47BCAA08324AB6BA92C3A70275F24FA4DC10E251633FB98D162BB5537202C6A553CE7841C4D40B873B85CA03A0A1E1CFADE6BA5180AB1323CCBA9A3E9C53D37575AB1FD9E7316C6FEECB0A14DF6F2DA56C2F56F55A89635CFCFDA47927AF1F0A47B2D4E4E61634B1B51D37A3A307A972420DE1B7A481B83E583B6AF16F63CB00C6"""), + xeh(""" +4F90106FF7C3DC4E47417F31AB56B1C5E426C1ECD5878AAD2B705E75062DA5FA6F4D18B704C941C6C6D941FD21191A69210BC39E24950D9F851B6DE8CE30023DC7536439104D42245F3E04E6AA6763F8AC97ADBD04CC69547BCE0BF290FFB5D12946301174AF1B0868C14D4293FA9DCC5B23F809B02CC78DEFE7F27935B9B681E531FC21CCB2AF8EF6144D8498E63E0EE48AF8D4CEF7AC1F669AC740B06F79DDB58E794F2FC2CA832E05A0374C18A4F2CC78343EEA064ABC5F468F4DD11E0B6E8FA1D18A221D8241450C05EB9EDF90D9D7F666AC82E7FD44AF9328E0BC6004D5B114E80E9B980D18E081D771DFCB2ACFD40142A2EB33234F75733EAB7D8EE8A5A6F796681A4A8AF85CCE86971B821D4AD8371049E94E280B77B15D111A42AEADFC08D4F804BD78885443E81A393DF7C8754C460915846E09A0596587460038F55D06EC21434A1C2DF44D0C16706E8D2B83F0E7833976EF05BF1D9F0DDC9A37597E401B817C2BEC8E02EB9DF7591E239F25F8648E7F2F4F673093BD9CB703DA32B353F58514C6AB55748B194E52F153D52F5F33FE95C5F9F65EA97BA721E8DDF333B64D233A867A12701E00C5D8A9B5AE344F3D847C27C079DCC9C3B40EC4604A9F041E7987E8B930C658B9A132DE4E422C0E27553A2A0EAB8C859EB0E5677E83272725C5C1652E61B9BBF5C9C59BC2357A4D1DB9C607F34DC1BA074B84DFC69E4097A7AD2BA9A58000027296AD39FC1CE218A5EEC7ADFA8AA3B9100B0B603CFC83C152589E12E6BD9EE10C49131A701D315DFEC38E018328916F9FFAA7305CFB66781707D2D1020EB782F9F003DB4E46B87D693F62E8BDE170141FF71F26DDF5310C00C9163655F5217DD2C8B0466AC89DB55BD7FB3B0964BC9009E9686185117DCB50D6D0297753CF7F1217E819EE60E3F0FAEC4A5AF0C2EA83CCDE15CF045C6961DE8FF6235C9D93BA4C89B7A82A7471FCFB0B8EAD54D56E8A1DE21B3933AC5B4A0689EEF3598926E17BBB16AEC61EC30A2CCC0E0323EC282887C108C3A4E83E3666493D8653D0E92443808C79D770BFF48A49E65AE089FEC790BBA4C66354EF67A334C1EA5C6C5707B6928EBD1BDB6A940FA242C6EBD7F3E71272421C9082841A6CAD2894BB8AC85F105D8BBC9E6F0A3DF0D7C46F6E2F4CAB904ED157AFA85D4A852220A9636E1E8821643A9E4028D87A430432F09354B3973182385CF5ABFC8F84982BEE0BCBF5D18637399163A09EB45711E07C4458498C76979107CF91B3FC590EA4AD715D656D5E56DC32146580101C952E02ED7017960D54CAACCC70607196980ADBDAEA420A52C0559ED23C9514F8CA7AB7F3BAAFD2FAB58960A64128D5A50E9AD8DB7D23A90CE64C1BC349D118D3603358377F84FF5A64457FA1CF41B27094BCA72360BD429415B9EF9ACCB7A5D7B9E5F5FDCA8FCFA4592E91D7E5120DF7E3C6675AF2211BB94D856A5D2285FBBB36984A1345590930B13232565D54812A9345324C232653190323CC67C840E478D09E6DDBCF999F7AA3B556F80332E67ACA41EC0661088D7696BB64E9A98A0749FAA9854D9B48754023BACAF3C8081A46157C6453BDC89341D3092F3B5337874CE5DE559A56A2FFB7F401F6E28EECAF4FDE5B60DEA73D6B2182EF68E07A8297F3C959E17139B5DEDC72C7A0E103AFF866E89D1F62A1F6B97B61BC059BDE5A2A06087EF783A441F23DD191C692D03C097FF9EE831F7715C6E508BF475E79A8353E84B06A9356045C8FD09FBA35879069B9A3F478FBD051143C13D753BC45F3040E85985EFD6B149EFA9455A18E2894E6EA0BE58F451FF1156F93CC7117B5D091E9DD50D41BFCCD44F2C4EB7812AEFD13C8B68D7F0103BB6CA38D233B6AADD01845B7E44D13C1CB1577D6C4354B063991344787F8C0BE667A7440B98917AD64CC2EF2BC82EFC3398B3B1B238540756CE9FC5EDD26CC20E761D592A1A0530AA8BEFCFE8DADBAC99A417CA0827F4983FF5BE656669F2B5F985FF6B16C44BBEA131D1FCC70FC53BF31EF225D1F5D41863B51B57EA65C6164F7531AE492EFA64161B7DABA3EF4586F3459BE8A962367DC276597B98E91FF594EFE8849BAD4CF91B9E5F244CF03CA9615BE128E96958533544A56E735994B92E4EF0D5FAB54B78EC66641C7463F225D261C144F00A0270741D7A511994833635A8A9B670CBFBEF239BF83327E247943B205DA68DB94E3F3""") + ), + new DecapsulateTestCase( + xeh(""" +8445C336F3518B298163DCBB6357597983CA2E873DCB49610CF52F14DBCB947C1F3EE9266967276B0C576CF7C30EE6B93DEA5118676CBEE1B1D4794206FB369ABA41167B4393855C84EBA8F32373C05BAE7631C802744AADB6C2DE41250C494315230B52826C34587CB21B183B49B2A5AC04921AC6BFAC1B24A4B37A93A4B168CCE7591BE6111F476260F2762959F5C1640118C2423772E2AD03DC7168A38C6DD39F5F7254264280C8BC10B914168070472FA880ACB8601A8A0837F25FE194687CD68B7DE2340F036DAD891D38D1B0CE9C2633355CF57B50B896036FCA260D2669F85BAC79714FDAFB41EF80B8C30264C31386AE60B05FAA542A26B41EB85F67068F088034FF67AA2E815AAB8BCA6BF71F70ECC3CBCBC45EF701FCD542BD21C7B09568F369C669F396473844FBA14957F51974D852B978014603A210C019036287008994F21255B25099AD82AA132438963B2C0A47CDF5F32BA46B76C7A6559F18BFD555B762E487B6AC992FE20E283CA0B3F6164496955995C3B28A57BBC29826F06FB38B253470AF631BC46C3A8F9CE824321985DD01C05F69B824F916633B40654C75AAEB9385576FFDE2990A6B0A3BE829D6D84E34F1780589C79204C63C798F55D23187E461D48C21E5C047E535B19F458BBA1345B9E41E0CB4A9C2D8C40B490A3BABC553B3026B1672D28CBC8B498A3A99579A832FEAE74610F0B6250CC333E9493EB1621ED34AA4AB175F2CA231152509ACB6AC86B20F6B39108439E5EC12D465A0FEF35003E14277A21812146B2544716D6AB82D1B0726C27A98D589EBDACC4C54BA77B2498F217E14E34E66025A2A143A992520A61C0672CC9CCED7C9450C683E90A3E4651DB623A6DB39AC26125B7FC1986D7B0493B8B72DE7707DC20BBDD43713156AF7D9430EF45399663C2202739168692DD657545B056D9C92385A7F414B34B90C7960D57B35BA7DDE7B81FCA0119D741B12780926018FE4C8030BF038E18B4FA33743D0D3C846417E9D5915C246315938B1E233614501D026959551258B233230D428B181B132F1D0B026067BA816999BC0CD6B547E548B63C9EAA091BAC493DC598DBC2B0E146A2591C2A8C009DD5170AAE027C541A1B5E66E45C65612984C46770493EC896EF25AA9305E9F06692CD0B2F06962E205BEBE113A34EBB1A4830A9B3749641BB935007B23B24BFE576956254D7A35AA496AC446C67A7FEC85A60057E8580617BCB3FAD15C76440FED54CC789394FEA24452CC6B0585B7EB0A88BBA9500D9800E6241AFEB523B55A96A535151D1049573206E59C7FEB070966823634F77D5F1291755A243119621AF8084AB7AC1E22A0568C6201417CBE3655D8A08DD5B513884C98D5A493FD49382EA41860F133CCD601E885966426A2B1F23D42D82E24582D99725192C21777467B1457B1DD429A0C41A5C3D704CEA06278C59941B438C62727097809B4530DBE837EA396B6D31077FAD3733053989A8442AAC4255CB163B8CA2F27501EA967305695ABD659AA02C83EE60BB574203E9937AE1C621C8ECB5CC1D21D556960B5B9161EA96FFFEBAC72E1B8A6154FC4D88B56C04741F090CBB156A737C9E6A22BA8AC704BC304F8E17E5EA845FDE59FBF788CCE0B97C8761F89A242F3052583C6844A632031C964A6C4A85A128A28619BA1BB3D1BEA4B49841FC847614A066841F52ED0EB8AE0B8B096E92B8195405815B231266F36B18C1A53333DAB95D2A9A374B5478A4A41FB8759957C9AB22CAE545AB544BA8DD05B83F3A613A2437ADB073A9635CB4BBC965FB454CF27B298A40CD0DA3B8F9CA99D8CB4286C5EB476416796070BA535AAA58CDB451CD6DB5CBB0CA20F0C71DE97C30DA97EC7906D06B4B939396028C46BA0E7A865BC8308A3810F1212006339F7BC169B1666FDF475911BBC8AAAB41755C9A8AABFA23C0E37F84FE46999E030494B9298EF9934E8A649C0A5CCE2B22F31809AFED23955D87881D99FC1D352896CAC9055BEA0D016CCBA7805A3A50E221630379BD01135221CAD5D9517C8CC42637B9FC0718E9A9BB4945C72D8D11D3D659D83A3C419509AF5B470DD89B7F3ACCF5F35CFC322115FD66A5CD2875651326F9B3168913BE5B9C87AE0B025EC7A2F4A072750946AC61170A7826D9704C5A23A1C0A2325146C3BC1858826C6B39279C2DA7438A370ED8A0AA5169E3BEC29ED88478732758D454143E227F8595883297842E6AF133B17E4811B0F5713AC73B7E347423EB92822D2306FA14500A7207A0672672046544ACC4EA9C16ED7421A069E0D737A98628519C6A29A424A868B46D9A0CC7C6C9DDD8B8BCBF422C8F48A73143D5ABB66BC55499418430802BAC544463CC7319D17998F29411365766D04C847F3129D9077B7D8339BFB96A6739C3F6B74A8F05F9138AB2FE37ACB57634D1820B50176F5A0B6BC2940F1D5938F1936B5F95828B92EB72973C1590AEB7A552CECA10B00C303B7C75D402071A79E2C810AF7C745E3336712492A42043F2903A37C6434CEE20B1D159B057699FF9C1D3BD68029839A08F43E6C1C819913532F911DD370C7021488E11CB504CB9C70570FFF35B4B4601191DC1AD9E6ADC5FA9618798D7CC860C87A939E4CCF8533632268CF1A51AFF0CB811C5545CB1656E65269477430699CCDEA3800630B78CD5810334CCF02E013F3B80244E70ACDB060BBE7A553B063456B2EA807473413165CE57DD563473CFBC90618ADE1F0B888AA48E722BB2751858FE19687442A48E7CA0D2A29CD51BFD8F78C17B9660BFB54A470B2AE9A955C6AB8D6E5CC92AC8ED3C185DAA8BC29F0578EBB812B97C9E5A848A6384DE4E75A31470B53066A8D027BA44B21749C0492465F9072B28376C4E290B30C1863F9E5B79996083422BD8C272C10ECC6EB9A0A8225B31AA0A66E35B9C0B9A79582BA20A3C04CD29914F083A0158288BA4D6EB62D87264B912BCA39732FBDE536A377AD02B8C835D4A2F4E7B1CE115D0C860BEAA7955A49AD689586A89A2B9F9B10D1595D2FC065AD018A7D56C614471F8E946FE8AB49E8226591119FCADB4F9A861631378736B6688B782D58E97E4572753A9664B6B8536812B25911AA76A242375433192738EEE762F6B84315BB3436231E0A9B277ED28AE0050728346457E13405062DB2804B8DA60BB5C793D4CC0E101CBA2D9182FD7124FF52BF4CA28292AC26D678088953971DBA0B6FEC2C9659353291C70C5B9245A0CA253304AFD3C95102BEA66875C6201680B4BDA38687B648C28EB37478E3BC00CA8A3CC27204642B42B68FCBE7B21A366D0668A5029A7DEEF94CDD6A95D7EA8931673BF7112D4042107B1B8B9700C974F9C4E83A8FACD89BFE0CA3CC4C2FCE80A03D3576C222A792B72B1F070AB7F6B6F2B5CA2AF5054AFA70A896990159B45D1003E2A05648675E596016F1B71DD0F7BDA7E2097FC73B3A143D12C726020AC34958AD7062B92B9ABF3CA6BE5AE29F57135E625A367971837E6363D1532094E022A23467CF932E1F89B5B0803C1EC99B585A78B5865096746F32258214ECB38065C97F455E155ACC2DD005A9C76BED59CDA73837D303504E6C976A606A2BE7BBEC5948B91A349E8936688CC0279754B743ABC58666B19B6C3260051F19206BB962BB6633EB0048E32BAACC5B020D02C86CA9770AD469DB54A106AC73A35B8057422B3DB202C5A5B4E3D535F0FC99326C4B8B7B16F1CB5AF96803FA8C195FC0BCEDDAAF012A51728B76489082373C91E92C87ACCA795160782E3B0DD643544BB96ABC2708D49B759CF057AA223BAFD96A330BAF39810FE8671B4343C297DA1E1969C996216AB5106DA668941B160D4477017136CBCA5B5A8D44C4A8B1CF3EF79785E5AA25C3A1AD6C24FD140F79207DE5A499F8A1534FFA804AA7B3889CBE25C0414704AA57897F17862364ECA56258007248813912B836497F0359C2F7238A05D305A0EA152E72B44417A868134E91B3CA7931232FD4C25F8C2A492A339CDC0A138967211451F2562678FA14080A34436C42B07865AC036A81E97A7787A938025CAF813450368BED0C94B1857604526405D27A1C1ABC81B5B6EC13C71930A97D9232CF7021EF87A4D155328E62B583A83B4AF21F9F5750F8575150424F63B899D71CAD267C09E4467146E16E9B6C653F008C311375E2E006D4076A546B82F5314222F7C654317E79EC6035B73FAF491757E61C828326D53044541C4D4537ABD3EA1E67998C3382974CA78AE1B1960E4A9226B0219AB070F0D7AA66D76F9316ADB80C54D6499771B471E8168D47BCAA08324AB6BA92C3A70275F24FA4DC10E251633FB98D162BB5537202C6A553CE7841C4D40B873B85CA03A0A1E1CFADE6BA5180AB1323CCBA9A3E9C53D37575AB1FD9E7316C6FEECB0A14DF6F2DA56C2F56F55A89635CFCFDA47927AF1F0A47B2D4E4E61634B1B51D37A3A307A972420DE1B7A481B83E583B6AF16F63CB00C6"""), + xeh(""" +26CC4F22E035BC00687D557655C46B6E1C447ACB824204FEF7582EB8DBC704D7CE72B0A5FFE54FB89BD7B779B5B1DD1573010B227473FDEFFFB74DF7DCC1E6B48B554563C6C23004AE2CB1996943821F480E91081F1A6765E08A8AAB7F203E95DEEA49A1129A676DCB21540D2AAE1B21223DDDF1453150483176F3EA3580CE631FC85508690D8DDCBC9513A4A5951A440232223FB2ED9E0E5A8ACFEE113D22548B8E98131EE1F45A33656F079870A146F12819BFDDF8792C3C9AC3BBEA3A92B8606FF2B7296DB9D9782C8E788AF4C961840041735DE456A35E5536D861CA118D67408E84D8BB9128B65F2C11C7147EAC928599979EF195A7979CFC48277CF1FDF4B0CAAEB3F8A172A3CA25A3A8C39AAB4495A70E0AFD3861C41A8C01FAD1E9D81281CAE1C33572BA4BCA9A5294000FFD040545B021AF583F56434ACCD4CB7B788517243B09737D355ECE53273FC0C492F251FA02E47EA846121DFF00CBF2767D4DEB25F705591D26FB1B6F839A58EBA4572745A618CB2EBE02CC0CB1C62AA9F0EFB794C385BC47E440BEB38BA742C7357A97CF33098E2EA4D823BD0B9699FB1EBFA806D64FAB18E106D4A97B23A889355C7A2635A9D3BB330A1B8EE5E707DC32C20CACFED68C8DE783562488A64400A4528EF568D833D73E456A9AC22431B2C22441EF5BCE3E77CCEC99D2D1C092ED8A28D686214313F683D4A020FA714459C36A257DDFF7B19B7ED05A16FCACA2570279A11E1439D07F2F23B88411404749C37836585182F31AD65CFEADCFEC3FA905CD4BFE2B6ECAE99D469F3EFC55615D45D19360EBB7C68C73ABD4562EEDA283776C887E70A971176DDC10FC399EAD6B9E247353C25289C0836C626E5376326FE5630C3098436556D61F5C75DA6057008A6E1D50B4F270FCB86F868D5F235428B4D7E13010D20175D4CF0759F56422CF955A721792DEB8EC887E5225F6E52CDFF40B8BD3FEE4DEBC7B363574FD1F3CC113A3B4281F4E8DC3AEBE4B67500ACB50B5DB1BB64F0634B19D4612F597DE2B4CAEEE8A3258DDF8436ACADF3677B46E7E5CF41071DEAD3FBCE2A73388E19AC0C7748E10E3F586E2EB844ADFC079EC0A2CD8C9BAC8E859460DCDAB688AAAA179882B91111A604F75198F55B17C79AD4BE3FDB493B59775ED449BF938B594D87A1C9F721D1C39868591496E62BDBF5CC2947DD81B65ED8CA0BAF0A64E924B5F4FFA88BE86C3594EA7472B822D2D84CDBFC7A2C5039FEC6EBB14FAE2D5D7E9CAF1C2B8788E7354BB6A12C4EA1ABDF0811417586F01553AFD9D8B1EA233066023BC45FA4BC064E7D289AE9DDAF1F985E4BAA86C55BA1F1866E010C55E166C3AA29A682A81195819B7165DF6CC72045D143135EDABA08ACF9DD9FCB8CE732F9CDF1A99C772A2EDAB78647132C33B80E7F03C84A044491B311BC6F3571E7935C6EDFB283BC59F29DD5CCFF9DD6A9640139B173E64F2755F6BBD977F15AF1524827DCE4C2FDF1EBB7C35F0F34800E5A07FC83821FA6CD41695B322F0909D55251372DB8B3CB147FBBF6264BF764B1A20BFA41EFB84D109D4E374564C760AAB66EE823970EE7BFC1D9DB860840BC4767E4A46F1855526A7D902D4FA954C7F337C7C1205FD4AAA70D7F5D904F1D0CF1DBFB63675991B26B590260714920A7249E75D21199D8C002BD702C5398C45A359965D367FA15A73B83197DB3BF3AE9E987479CD81283419E557F993884EA4F17996CCA39FBA8941EDD70FC86E3A46C84C656F77E9DFA5DB31D8761A8FC1D5A2FE9C1CF67DDA1408A212951A5A1D5E9260BF367FD824ECBE8534AA5C63F3E9E2EE4EC53CB42663A79706088A846614B10EDB58B45BF063ACEF64DBB5ED8808588B51A80EC327B95DB34A2107FA96776F1DD0340C7918D0B846883EED35F5730D67165D4A51DC50533458F045E1266CE5C1CA6A30D931DA81732A876987482F2DB58694C574731E92CE6F9083A5EAD8143F244A8DF04C6DE1B2B07ED86D5593CAFC2A7B3E819C03C70B7B32AC0D576AC2E2E5843A39E4D36EFACBCE679307A1998F9C9DED50BF39CD29A529A82F26B5B4538F9CBBD547B9E4D5F7F31B555A8FCA1F9ABDEF3483640DE77D558735C15A588D944F9D76B06E417B1DA873F38A21321CDACE8D4BDDC49EBA4165D40820BA19A437D65B337B8C037041631D09F8ADD1400524F4A3BC33F9213AC7926548B9C43A4BC0148807D9""") + ), + new DecapsulateTestCase( + xeh(""" +8445C336F3518B298163DCBB6357597983CA2E873DCB49610CF52F14DBCB947C1F3EE9266967276B0C576CF7C30EE6B93DEA5118676CBEE1B1D4794206FB369ABA41167B4393855C84EBA8F32373C05BAE7631C802744AADB6C2DE41250C494315230B52826C34587CB21B183B49B2A5AC04921AC6BFAC1B24A4B37A93A4B168CCE7591BE6111F476260F2762959F5C1640118C2423772E2AD03DC7168A38C6DD39F5F7254264280C8BC10B914168070472FA880ACB8601A8A0837F25FE194687CD68B7DE2340F036DAD891D38D1B0CE9C2633355CF57B50B896036FCA260D2669F85BAC79714FDAFB41EF80B8C30264C31386AE60B05FAA542A26B41EB85F67068F088034FF67AA2E815AAB8BCA6BF71F70ECC3CBCBC45EF701FCD542BD21C7B09568F369C669F396473844FBA14957F51974D852B978014603A210C019036287008994F21255B25099AD82AA132438963B2C0A47CDF5F32BA46B76C7A6559F18BFD555B762E487B6AC992FE20E283CA0B3F6164496955995C3B28A57BBC29826F06FB38B253470AF631BC46C3A8F9CE824321985DD01C05F69B824F916633B40654C75AAEB9385576FFDE2990A6B0A3BE829D6D84E34F1780589C79204C63C798F55D23187E461D48C21E5C047E535B19F458BBA1345B9E41E0CB4A9C2D8C40B490A3BABC553B3026B1672D28CBC8B498A3A99579A832FEAE74610F0B6250CC333E9493EB1621ED34AA4AB175F2CA231152509ACB6AC86B20F6B39108439E5EC12D465A0FEF35003E14277A21812146B2544716D6AB82D1B0726C27A98D589EBDACC4C54BA77B2498F217E14E34E66025A2A143A992520A61C0672CC9CCED7C9450C683E90A3E4651DB623A6DB39AC26125B7FC1986D7B0493B8B72DE7707DC20BBDD43713156AF7D9430EF45399663C2202739168692DD657545B056D9C92385A7F414B34B90C7960D57B35BA7DDE7B81FCA0119D741B12780926018FE4C8030BF038E18B4FA33743D0D3C846417E9D5915C246315938B1E233614501D026959551258B233230D428B181B132F1D0B026067BA816999BC0CD6B547E548B63C9EAA091BAC493DC598DBC2B0E146A2591C2A8C009DD5170AAE027C541A1B5E66E45C65612984C46770493EC896EF25AA9305E9F06692CD0B2F06962E205BEBE113A34EBB1A4830A9B3749641BB935007B23B24BFE576956254D7A35AA496AC446C67A7FEC85A60057E8580617BCB3FAD15C76440FED54CC789394FEA24452CC6B0585B7EB0A88BBA9500D9800E6241AFEB523B55A96A535151D1049573206E59C7FEB070966823634F77D5F1291755A243119621AF8084AB7AC1E22A0568C6201417CBE3655D8A08DD5B513884C98D5A493FD49382EA41860F133CCD601E885966426A2B1F23D42D82E24582D99725192C21777467B1457B1DD429A0C41A5C3D704CEA06278C59941B438C62727097809B4530DBE837EA396B6D31077FAD3733053989A8442AAC4255CB163B8CA2F27501EA967305695ABD659AA02C83EE60BB574203E9937AE1C621C8ECB5CC1D21D556960B5B9161EA96FFFEBAC72E1B8A6154FC4D88B56C04741F090CBB156A737C9E6A22BA8AC704BC304F8E17E5EA845FDE59FBF788CCE0B97C8761F89A242F3052583C6844A632031C964A6C4A85A128A28619BA1BB3D1BEA4B49841FC847614A066841F52ED0EB8AE0B8B096E92B8195405815B231266F36B18C1A53333DAB95D2A9A374B5478A4A41FB8759957C9AB22CAE545AB544BA8DD05B83F3A613A2437ADB073A9635CB4BBC965FB454CF27B298A40CD0DA3B8F9CA99D8CB4286C5EB476416796070BA535AAA58CDB451CD6DB5CBB0CA20F0C71DE97C30DA97EC7906D06B4B939396028C46BA0E7A865BC8308A3810F1212006339F7BC169B1666FDF475911BBC8AAAB41755C9A8AABFA23C0E37F84FE46999E030494B9298EF9934E8A649C0A5CCE2B22F31809AFED23955D87881D99FC1D352896CAC9055BEA0D016CCBA7805A3A50E221630379BD01135221CAD5D9517C8CC42637B9FC0718E9A9BB4945C72D8D11D3D659D83A3C419509AF5B470DD89B7F3ACCF5F35CFC322115FD66A5CD2875651326F9B3168913BE5B9C87AE0B025EC7A2F4A072750946AC61170A7826D9704C5A23A1C0A2325146C3BC1858826C6B39279C2DA7438A370ED8A0AA5169E3BEC29ED88478732758D454143E227F8595883297842E6AF133B17E4811B0F5713AC73B7E347423EB92822D2306FA14500A7207A0672672046544ACC4EA9C16ED7421A069E0D737A98628519C6A29A424A868B46D9A0CC7C6C9DDD8B8BCBF422C8F48A73143D5ABB66BC55499418430802BAC544463CC7319D17998F29411365766D04C847F3129D9077B7D8339BFB96A6739C3F6B74A8F05F9138AB2FE37ACB57634D1820B50176F5A0B6BC2940F1D5938F1936B5F95828B92EB72973C1590AEB7A552CECA10B00C303B7C75D402071A79E2C810AF7C745E3336712492A42043F2903A37C6434CEE20B1D159B057699FF9C1D3BD68029839A08F43E6C1C819913532F911DD370C7021488E11CB504CB9C70570FFF35B4B4601191DC1AD9E6ADC5FA9618798D7CC860C87A939E4CCF8533632268CF1A51AFF0CB811C5545CB1656E65269477430699CCDEA3800630B78CD5810334CCF02E013F3B80244E70ACDB060BBE7A553B063456B2EA807473413165CE57DD563473CFBC90618ADE1F0B888AA48E722BB2751858FE19687442A48E7CA0D2A29CD51BFD8F78C17B9660BFB54A470B2AE9A955C6AB8D6E5CC92AC8ED3C185DAA8BC29F0578EBB812B97C9E5A848A6384DE4E75A31470B53066A8D027BA44B21749C0492465F9072B28376C4E290B30C1863F9E5B79996083422BD8C272C10ECC6EB9A0A8225B31AA0A66E35B9C0B9A79582BA20A3C04CD29914F083A0158288BA4D6EB62D87264B912BCA39732FBDE536A377AD02B8C835D4A2F4E7B1CE115D0C860BEAA7955A49AD689586A89A2B9F9B10D1595D2FC065AD018A7D56C614471F8E946FE8AB49E8226591119FCADB4F9A861631378736B6688B782D58E97E4572753A9664B6B8536812B25911AA76A242375433192738EEE762F6B84315BB3436231E0A9B277ED28AE0050728346457E13405062DB2804B8DA60BB5C793D4CC0E101CBA2D9182FD7124FF52BF4CA28292AC26D678088953971DBA0B6FEC2C9659353291C70C5B9245A0CA253304AFD3C95102BEA66875C6201680B4BDA38687B648C28EB37478E3BC00CA8A3CC27204642B42B68FCBE7B21A366D0668A5029A7DEEF94CDD6A95D7EA8931673BF7112D4042107B1B8B9700C974F9C4E83A8FACD89BFE0CA3CC4C2FCE80A03D3576C222A792B72B1F070AB7F6B6F2B5CA2AF5054AFA70A896990159B45D1003E2A05648675E596016F1B71DD0F7BDA7E2097FC73B3A143D12C726020AC34958AD7062B92B9ABF3CA6BE5AE29F57135E625A367971837E6363D1532094E022A23467CF932E1F89B5B0803C1EC99B585A78B5865096746F32258214ECB38065C97F455E155ACC2DD005A9C76BED59CDA73837D303504E6C976A606A2BE7BBEC5948B91A349E8936688CC0279754B743ABC58666B19B6C3260051F19206BB962BB6633EB0048E32BAACC5B020D02C86CA9770AD469DB54A106AC73A35B8057422B3DB202C5A5B4E3D535F0FC99326C4B8B7B16F1CB5AF96803FA8C195FC0BCEDDAAF012A51728B76489082373C91E92C87ACCA795160782E3B0DD643544BB96ABC2708D49B759CF057AA223BAFD96A330BAF39810FE8671B4343C297DA1E1969C996216AB5106DA668941B160D4477017136CBCA5B5A8D44C4A8B1CF3EF79785E5AA25C3A1AD6C24FD140F79207DE5A499F8A1534FFA804AA7B3889CBE25C0414704AA57897F17862364ECA56258007248813912B836497F0359C2F7238A05D305A0EA152E72B44417A868134E91B3CA7931232FD4C25F8C2A492A339CDC0A138967211451F2562678FA14080A34436C42B07865AC036A81E97A7787A938025CAF813450368BED0C94B1857604526405D27A1C1ABC81B5B6EC13C71930A97D9232CF7021EF87A4D155328E62B583A83B4AF21F9F5750F8575150424F63B899D71CAD267C09E4467146E16E9B6C653F008C311375E2E006D4076A546B82F5314222F7C654317E79EC6035B73FAF491757E61C828326D53044541C4D4537ABD3EA1E67998C3382974CA78AE1B1960E4A9226B0219AB070F0D7AA66D76F9316ADB80C54D6499771B471E8168D47BCAA08324AB6BA92C3A70275F24FA4DC10E251633FB98D162BB5537202C6A553CE7841C4D40B873B85CA03A0A1E1CFADE6BA5180AB1323CCBA9A3E9C53D37575AB1FD9E7316C6FEECB0A14DF6F2DA56C2F56F55A89635CFCFDA47927AF1F0A47B2D4E4E61634B1B51D37A3A307A972420DE1B7A481B83E583B6AF16F63CB00C6"""), + xeh(""" +B36564F2BBECFE4DD315E84612BD765E3F2E84F5D8D86FC0708F72FCAF284A0850708CE6E11D0BE154C00F930D18C0A8D8071B612556238A64B679A083B2FC1A204079EE19A4095E71E0EED695B3CA764F4F4E5D7366430A8933F0356DB074C2D68048E046481E5481E4F5A2F365EA9C4C7A6BEA51CDBF1BF31366F863327126DDD101F8220034FB4A3C68232C5CC84229EB1E35F19AC2016A8E4805A87797F940B72A472F129FF5B751964AEEC96847B0BCA5D7F391CA9053380DE83CBC31F341599FEFE36A1CD83B30A1B7CB588874CCC5F443F73ADFA2CE7E7271A5726272A7E5FC721E85D9755D672F5B2A0EAC8065D2C3835B7F0B2F7C77A27AAC438E345BAA378A572AA676632434737FA59A7E197135BD6AF2619A828AAC865D7F34AFB771BB55B5B7E93B9489AE98C694EAA26C6A86F41D0C53522DA4D90F2AB267675BABFBE963C4C68534A24D1EAEA2BE97702E28CABE5FD080DA6B3C432EB0E55F9FE8C1C0422A44F57002A1F96E6D53E8AB9539E909346D150082DF69F54D27017B9A7633B7BD9F7E6274B1F97D7CB4BF5FC2E34E77ECA1317E7854304C75C388CCD1386C694E93CADC856E136C2C0EE7E113A125C79443C5D1A80A9698BF58248B0903A45961603D1EA0E89E3C0650EA3E82368A6C477CCD1B0180542401BB1DE70E25F64A5DE41D62D0467353EE488E1F692EB60778452B53088473B084D0819B725268AAE752FC8CB56384C7AF9D319CAAEC958FC3EAEF57E0F35F1BFE1BABAA2C64A2D9813EE16F22A94C1C00B29EE82F11C47224A9C5424E647B9883918C9CF2CAF51B7FA825121C5D13ECEB5F66E4EA11526E0C37DBCD464C5BA78A36A31A62B2DECC7DF51C24843EC2325C74A771A7D73D35BF2AC4578932A6C2A7323375A2B7679188CFE804E5EFF4A04B7E14F8851770048F076B32BA4F19F4530364C0529EC3FB2D0DDABDC85DE2257F4DF05686AB498FDBEAE3A1439627DD8885E4C8744156C2B155BD2F965AF0F2017F163A6016C274E8532CA43C784B7AD4747A58253EDFB739D68E376D7ED246E5474454F463F4212090DF4F4D7F88C097B18180B05F2E89EEBB834B9BB6DD9E5F6036ECDD5908CA4962609C208A557A36B7FBC72158A6D86322F4303434F6AFFB34527E47E0599DDC88EAD31814646A81188E79E1B6D562E01FE1EF148FE8825758CFA5BD7B738E3BECDDDCA4C59093CA24581E531667DBA2C295B565951445E410FBC99D795887BD48AB87D6D413B64957993CD7525A0A0A5D393CA1EDF7788E4DFACDFA7B394B6163BB948C9C6779BDDCC8F26BC073BEAD0FC87236704A0DC0D89DEB4F8174E91D249C4DCD9260BC7C86CFB35B985813E1689D83083949927303741550CB782E256E79800F41B5C7D981D68E60978E5190A2C51C812DCC3952AA34212625834B2F8CF8CE8019AD6CE8F00FF910CCCF0CAF5A3596AF8DF947EFDE954F361665458F77787E528937BC52C59950746C783D8C5216570E6F0A944E6BD661F23C7A9AF3C602DF851EA2E5627186A6CCBCC470E07B290E4F754D5A8D6BAD8C34F39B4BA838CB467681B0173C33FA51ABE122BAE3DC06660950CFA5C228CDBA2F5EEF2613D2850DF9B5FEBE7333BE93F90E4DEE219AD18425DEE4006FA3009666C83DF7EDFB2EA4F99902C694248F9D51C7B6FBE53780EB218732C11368C33449D051489FDB01B1A1064FB06DED747ADE38F7A12DCDAA92D64DB4C2C43DFE53068A77339E1479C8C93192793B1C752FA7FB23B57DB5B428622D27CBF608CD7406FDB543FF3BD26FD7ED7269427C6B93491BE6724D071F58AF434FDAD2F0FAD5730A60F3EEF94C59CBC5884F36274C4CD984303EEAAD17E1785914DC804BBAF35406995E3D56094F0FDD71C7650A6C37393C0EF4C167CD2FBC28EB4EDD34B5383CA3D1B89D7BADB0270065B5AE2D461E6DEE53291230ED3CC3B616A7E8A86A4265A98C10A44066301470BBCDB257F35489BA5DCA320A390AF23CEF6ABA8B291538D9C4E965969087E394EDA44C060E28220BF72AB98F1C055159892DFF079D283C52997DCFDC2FD8291FFDF322809BE3CDC113DE9D495EA5F9FA5DDE5052192CA6F26BD510433B197131A7E954AEC5E58F0A341D7E4602BAE46BB1987B5C1D845E6AE5569DC2AFE0C7984DDD9B0B184CD6ABC0AADF5E13E0F110E8876D572200DD837FEF193278119B861C196C7522""") + ), + new DecapsulateTestCase( + xeh(""" +8445C336F3518B298163DCBB6357597983CA2E873DCB49610CF52F14DBCB947C1F3EE9266967276B0C576CF7C30EE6B93DEA5118676CBEE1B1D4794206FB369ABA41167B4393855C84EBA8F32373C05BAE7631C802744AADB6C2DE41250C494315230B52826C34587CB21B183B49B2A5AC04921AC6BFAC1B24A4B37A93A4B168CCE7591BE6111F476260F2762959F5C1640118C2423772E2AD03DC7168A38C6DD39F5F7254264280C8BC10B914168070472FA880ACB8601A8A0837F25FE194687CD68B7DE2340F036DAD891D38D1B0CE9C2633355CF57B50B896036FCA260D2669F85BAC79714FDAFB41EF80B8C30264C31386AE60B05FAA542A26B41EB85F67068F088034FF67AA2E815AAB8BCA6BF71F70ECC3CBCBC45EF701FCD542BD21C7B09568F369C669F396473844FBA14957F51974D852B978014603A210C019036287008994F21255B25099AD82AA132438963B2C0A47CDF5F32BA46B76C7A6559F18BFD555B762E487B6AC992FE20E283CA0B3F6164496955995C3B28A57BBC29826F06FB38B253470AF631BC46C3A8F9CE824321985DD01C05F69B824F916633B40654C75AAEB9385576FFDE2990A6B0A3BE829D6D84E34F1780589C79204C63C798F55D23187E461D48C21E5C047E535B19F458BBA1345B9E41E0CB4A9C2D8C40B490A3BABC553B3026B1672D28CBC8B498A3A99579A832FEAE74610F0B6250CC333E9493EB1621ED34AA4AB175F2CA231152509ACB6AC86B20F6B39108439E5EC12D465A0FEF35003E14277A21812146B2544716D6AB82D1B0726C27A98D589EBDACC4C54BA77B2498F217E14E34E66025A2A143A992520A61C0672CC9CCED7C9450C683E90A3E4651DB623A6DB39AC26125B7FC1986D7B0493B8B72DE7707DC20BBDD43713156AF7D9430EF45399663C2202739168692DD657545B056D9C92385A7F414B34B90C7960D57B35BA7DDE7B81FCA0119D741B12780926018FE4C8030BF038E18B4FA33743D0D3C846417E9D5915C246315938B1E233614501D026959551258B233230D428B181B132F1D0B026067BA816999BC0CD6B547E548B63C9EAA091BAC493DC598DBC2B0E146A2591C2A8C009DD5170AAE027C541A1B5E66E45C65612984C46770493EC896EF25AA9305E9F06692CD0B2F06962E205BEBE113A34EBB1A4830A9B3749641BB935007B23B24BFE576956254D7A35AA496AC446C67A7FEC85A60057E8580617BCB3FAD15C76440FED54CC789394FEA24452CC6B0585B7EB0A88BBA9500D9800E6241AFEB523B55A96A535151D1049573206E59C7FEB070966823634F77D5F1291755A243119621AF8084AB7AC1E22A0568C6201417CBE3655D8A08DD5B513884C98D5A493FD49382EA41860F133CCD601E885966426A2B1F23D42D82E24582D99725192C21777467B1457B1DD429A0C41A5C3D704CEA06278C59941B438C62727097809B4530DBE837EA396B6D31077FAD3733053989A8442AAC4255CB163B8CA2F27501EA967305695ABD659AA02C83EE60BB574203E9937AE1C621C8ECB5CC1D21D556960B5B9161EA96FFFEBAC72E1B8A6154FC4D88B56C04741F090CBB156A737C9E6A22BA8AC704BC304F8E17E5EA845FDE59FBF788CCE0B97C8761F89A242F3052583C6844A632031C964A6C4A85A128A28619BA1BB3D1BEA4B49841FC847614A066841F52ED0EB8AE0B8B096E92B8195405815B231266F36B18C1A53333DAB95D2A9A374B5478A4A41FB8759957C9AB22CAE545AB544BA8DD05B83F3A613A2437ADB073A9635CB4BBC965FB454CF27B298A40CD0DA3B8F9CA99D8CB4286C5EB476416796070BA535AAA58CDB451CD6DB5CBB0CA20F0C71DE97C30DA97EC7906D06B4B939396028C46BA0E7A865BC8308A3810F1212006339F7BC169B1666FDF475911BBC8AAAB41755C9A8AABFA23C0E37F84FE46999E030494B9298EF9934E8A649C0A5CCE2B22F31809AFED23955D87881D99FC1D352896CAC9055BEA0D016CCBA7805A3A50E221630379BD01135221CAD5D9517C8CC42637B9FC0718E9A9BB4945C72D8D11D3D659D83A3C419509AF5B470DD89B7F3ACCF5F35CFC322115FD66A5CD2875651326F9B3168913BE5B9C87AE0B025EC7A2F4A072750946AC61170A7826D9704C5A23A1C0A2325146C3BC1858826C6B39279C2DA7438A370ED8A0AA5169E3BEC29ED88478732758D454143E227F8595883297842E6AF133B17E4811B0F5713AC73B7E347423EB92822D2306FA14500A7207A0672672046544ACC4EA9C16ED7421A069E0D737A98628519C6A29A424A868B46D9A0CC7C6C9DDD8B8BCBF422C8F48A73143D5ABB66BC55499418430802BAC544463CC7319D17998F29411365766D04C847F3129D9077B7D8339BFB96A6739C3F6B74A8F05F9138AB2FE37ACB57634D1820B50176F5A0B6BC2940F1D5938F1936B5F95828B92EB72973C1590AEB7A552CECA10B00C303B7C75D402071A79E2C810AF7C745E3336712492A42043F2903A37C6434CEE20B1D159B057699FF9C1D3BD68029839A08F43E6C1C819913532F911DD370C7021488E11CB504CB9C70570FFF35B4B4601191DC1AD9E6ADC5FA9618798D7CC860C87A939E4CCF8533632268CF1A51AFF0CB811C5545CB1656E65269477430699CCDEA3800630B78CD5810334CCF02E013F3B80244E70ACDB060BBE7A553B063456B2EA807473413165CE57DD563473CFBC90618ADE1F0B888AA48E722BB2751858FE19687442A48E7CA0D2A29CD51BFD8F78C17B9660BFB54A470B2AE9A955C6AB8D6E5CC92AC8ED3C185DAA8BC29F0578EBB812B97C9E5A848A6384DE4E75A31470B53066A8D027BA44B21749C0492465F9072B28376C4E290B30C1863F9E5B79996083422BD8C272C10ECC6EB9A0A8225B31AA0A66E35B9C0B9A79582BA20A3C04CD29914F083A0158288BA4D6EB62D87264B912BCA39732FBDE536A377AD02B8C835D4A2F4E7B1CE115D0C860BEAA7955A49AD689586A89A2B9F9B10D1595D2FC065AD018A7D56C614471F8E946FE8AB49E8226591119FCADB4F9A861631378736B6688B782D58E97E4572753A9664B6B8536812B25911AA76A242375433192738EEE762F6B84315BB3436231E0A9B277ED28AE0050728346457E13405062DB2804B8DA60BB5C793D4CC0E101CBA2D9182FD7124FF52BF4CA28292AC26D678088953971DBA0B6FEC2C9659353291C70C5B9245A0CA253304AFD3C95102BEA66875C6201680B4BDA38687B648C28EB37478E3BC00CA8A3CC27204642B42B68FCBE7B21A366D0668A5029A7DEEF94CDD6A95D7EA8931673BF7112D4042107B1B8B9700C974F9C4E83A8FACD89BFE0CA3CC4C2FCE80A03D3576C222A792B72B1F070AB7F6B6F2B5CA2AF5054AFA70A896990159B45D1003E2A05648675E596016F1B71DD0F7BDA7E2097FC73B3A143D12C726020AC34958AD7062B92B9ABF3CA6BE5AE29F57135E625A367971837E6363D1532094E022A23467CF932E1F89B5B0803C1EC99B585A78B5865096746F32258214ECB38065C97F455E155ACC2DD005A9C76BED59CDA73837D303504E6C976A606A2BE7BBEC5948B91A349E8936688CC0279754B743ABC58666B19B6C3260051F19206BB962BB6633EB0048E32BAACC5B020D02C86CA9770AD469DB54A106AC73A35B8057422B3DB202C5A5B4E3D535F0FC99326C4B8B7B16F1CB5AF96803FA8C195FC0BCEDDAAF012A51728B76489082373C91E92C87ACCA795160782E3B0DD643544BB96ABC2708D49B759CF057AA223BAFD96A330BAF39810FE8671B4343C297DA1E1969C996216AB5106DA668941B160D4477017136CBCA5B5A8D44C4A8B1CF3EF79785E5AA25C3A1AD6C24FD140F79207DE5A499F8A1534FFA804AA7B3889CBE25C0414704AA57897F17862364ECA56258007248813912B836497F0359C2F7238A05D305A0EA152E72B44417A868134E91B3CA7931232FD4C25F8C2A492A339CDC0A138967211451F2562678FA14080A34436C42B07865AC036A81E97A7787A938025CAF813450368BED0C94B1857604526405D27A1C1ABC81B5B6EC13C71930A97D9232CF7021EF87A4D155328E62B583A83B4AF21F9F5750F8575150424F63B899D71CAD267C09E4467146E16E9B6C653F008C311375E2E006D4076A546B82F5314222F7C654317E79EC6035B73FAF491757E61C828326D53044541C4D4537ABD3EA1E67998C3382974CA78AE1B1960E4A9226B0219AB070F0D7AA66D76F9316ADB80C54D6499771B471E8168D47BCAA08324AB6BA92C3A70275F24FA4DC10E251633FB98D162BB5537202C6A553CE7841C4D40B873B85CA03A0A1E1CFADE6BA5180AB1323CCBA9A3E9C53D37575AB1FD9E7316C6FEECB0A14DF6F2DA56C2F56F55A89635CFCFDA47927AF1F0A47B2D4E4E61634B1B51D37A3A307A972420DE1B7A481B83E583B6AF16F63CB00C6"""), + xeh(""" +4B30E5256A941008BAD9BD14060445AD208769EDEA1C5B6E4ED506FB334A2378520B5EDC9217D626E1377839A18F2D21C0CC8902622E4AB79E83DEC449FFFD45A4CBF3AC253142D935DD310B5E4C5D591A9BD61795F8ABF00AA04EBAF96195B6CC7D7C3910FD7D75E25A9D0D79FA453178B06FC6B1E99F189CDA90276D6B69FBEA28D68CC82707A46CBEAB819239BE69BA76D749E27CAC9E5FFE88064B9972DB77C49679D6DDC6E6B03DAA0DDF0106B1A61141DF827E96AC542DC90A69CB316EB4F78C611C0155F9138F527006121DA16DB46531ADEC2FF599378A819CFBE3B079C9FE7E368B91A9E40F97A3E79A4F1F05574CE2AC3A525C206D9E55CE16D42D2F0F4863F896E808FE168B34A102BB81BD607BD02CCFFBA5C189497502A55F3E601F8F61B40A5202BAF9AC87D058E67B9E1CDEA0E4B02FF2DEED7477609A9AE2116512C42079D87AD74B05622E02979EF0A0F1D6375D93576EB6553FB1AC70ABDACBFBDB18735E949EC6D1667E978547A5CEAF2F4DCA6FF5D8346A960CE6925BF2B3F316238D6BC8ACBE67BC1AACD5A9A5D130A3D3B39C3BD7C1B06227A59BF4723AE9656D9922D9228A3404D4856E39702DFDC01C6E8CB6000E0779364BAD4F021BCFD7288CE7049D544E8423B2890C3083FDDB9BC720AC4C6A1A4EEA6BA1927B307E6CB72131B6B831AAD036A50A54608D106EDACD83EBDF104AA80C917314D295E903FDF36CD04EB786CF93AFF1279C2172002F7EE92DFAB3A99BF42C2BE7B7D0EDDD38029AB5AE18F5CFF8A2F1D2EA2EC7F34770FBA8A8BEEB0E1FF6F1C1A036F1BD84030004696BF4FB4161F252436C0401AEC911CBF1D7530D9D801B1B9B3A682329AE2F6930191E48189CD40706256B864D6F016597B4AA86FEE4F0E2362D8BCC743E98531EB2B335DE2DD299F231FAA808F6BC7D8F13DE8EAA30C5698D64E508D3534935B9941C2E40A458BEA82DAE4151ECF6DCD40320E1009BD9FBEE248F4EB6DB4437482BDFD83FDAF8367CC1845E64A23A310F904D5FAAD67241AA7748764C26EC881788D1EE0A39944071E5ACB656AB8CEA285C282545030EBBE6FB595E296E1EA37D7AE529B96CAECED11331D80C92D3DACDD7DC93237D815A9C6CEB9209C0BF3548ED1AD691929B2C1035E80A21477747E313049DEAD43A40B0960A96BF3C3E9BADEBC3B4D424FE7DC4DE5CE7788E31AEA3EC8965740D424CEB66D4A5678260051BFEFF09A3CB24C1AB7782AFBFEDE5EE1ED4EB14AD2A13142E8201CD1B52CE064F05ACFB019E21A73D84A80E30FAA48ABEFECA970BBF17FFA6F3A90AEF80EFA31C494E721231289143416AB9621737FC016380E6079EC6CD962BF7CC0750582EB218F869CE117D399DEF9AA66F7D2F07FD22BEB9E50B94CA5FC758C9DD4D2984A156748C52307731FC78F8539F8264BAD6DD56C0C23937A9A850E66BA298C3D39105ECACA9A573D887C9A4FE33D487F2126097B165594E1F8106C937758AB6EE75EDF39D2BCDE78AB611A034A72FDBEE67A80F3315571AB4DB94C56A19EFB63B8E7708566412F73D4974B160183FB5B6C44C8CED990B29C57BBEEAC5EABDCB11CCED9A17322B6EF197121B4094D7EA4A1B4EC44A68B447FE4C8119A6A33BFB66EA6844DB5B6094119AD1DE89449DE922B9A0D1253EA18C62418EB87330C6B33EEE02D4486F62A4D31CA24F098BE2F187CA6019025AD6E1C2FE69800D8BFA2C646F9FC6BCB3D369A78310084FF163D2065631C41748E7E3B25E8F2C9EDA2E107AA2046FE3F5DCC0A9A39FCE41813C8F1946C3AC07A22A6A56C4AFC626E68FF8CBC4982C1E60C3A9F288D1C4F2B8D7187EF2FAE30B77C4DD73499C2B3793B24014CFFEF6D80063DD1C1F3AC7F14FB61E5E81F850AB865BA873404BEB898FF7A2DCFA3B955DDB161B5781AFE8EF127BA2C8BFDBC2FB1C7D80FC650420214314023F6F65C17FC48927BBAE88D48D2E1976119C2F8310232942DD4C3AD4518D1E4DA9DD588691837122F5E5DE0FF1FA685DE134DFD1348CE3B5BE60B18BBF474074829E7D81AE087F149259122D47B728F369D1D8455EE571F715788C254F2EF438034BFF0A11F2F008E19B370BBEEE135A00DBE7F3C2970208F5F5D0E2765C395CA81B2FD80FC384AD046564229C759315B6CFFAD03A56996556E7714DABDE28F7A9BB5DE2C05B1F3596AF66C747D9A9313673F19AD4BAC6EAA7""") + ), + new DecapsulateTestCase( + xeh(""" +8445C336F3518B298163DCBB6357597983CA2E873DCB49610CF52F14DBCB947C1F3EE9266967276B0C576CF7C30EE6B93DEA5118676CBEE1B1D4794206FB369ABA41167B4393855C84EBA8F32373C05BAE7631C802744AADB6C2DE41250C494315230B52826C34587CB21B183B49B2A5AC04921AC6BFAC1B24A4B37A93A4B168CCE7591BE6111F476260F2762959F5C1640118C2423772E2AD03DC7168A38C6DD39F5F7254264280C8BC10B914168070472FA880ACB8601A8A0837F25FE194687CD68B7DE2340F036DAD891D38D1B0CE9C2633355CF57B50B896036FCA260D2669F85BAC79714FDAFB41EF80B8C30264C31386AE60B05FAA542A26B41EB85F67068F088034FF67AA2E815AAB8BCA6BF71F70ECC3CBCBC45EF701FCD542BD21C7B09568F369C669F396473844FBA14957F51974D852B978014603A210C019036287008994F21255B25099AD82AA132438963B2C0A47CDF5F32BA46B76C7A6559F18BFD555B762E487B6AC992FE20E283CA0B3F6164496955995C3B28A57BBC29826F06FB38B253470AF631BC46C3A8F9CE824321985DD01C05F69B824F916633B40654C75AAEB9385576FFDE2990A6B0A3BE829D6D84E34F1780589C79204C63C798F55D23187E461D48C21E5C047E535B19F458BBA1345B9E41E0CB4A9C2D8C40B490A3BABC553B3026B1672D28CBC8B498A3A99579A832FEAE74610F0B6250CC333E9493EB1621ED34AA4AB175F2CA231152509ACB6AC86B20F6B39108439E5EC12D465A0FEF35003E14277A21812146B2544716D6AB82D1B0726C27A98D589EBDACC4C54BA77B2498F217E14E34E66025A2A143A992520A61C0672CC9CCED7C9450C683E90A3E4651DB623A6DB39AC26125B7FC1986D7B0493B8B72DE7707DC20BBDD43713156AF7D9430EF45399663C2202739168692DD657545B056D9C92385A7F414B34B90C7960D57B35BA7DDE7B81FCA0119D741B12780926018FE4C8030BF038E18B4FA33743D0D3C846417E9D5915C246315938B1E233614501D026959551258B233230D428B181B132F1D0B026067BA816999BC0CD6B547E548B63C9EAA091BAC493DC598DBC2B0E146A2591C2A8C009DD5170AAE027C541A1B5E66E45C65612984C46770493EC896EF25AA9305E9F06692CD0B2F06962E205BEBE113A34EBB1A4830A9B3749641BB935007B23B24BFE576956254D7A35AA496AC446C67A7FEC85A60057E8580617BCB3FAD15C76440FED54CC789394FEA24452CC6B0585B7EB0A88BBA9500D9800E6241AFEB523B55A96A535151D1049573206E59C7FEB070966823634F77D5F1291755A243119621AF8084AB7AC1E22A0568C6201417CBE3655D8A08DD5B513884C98D5A493FD49382EA41860F133CCD601E885966426A2B1F23D42D82E24582D99725192C21777467B1457B1DD429A0C41A5C3D704CEA06278C59941B438C62727097809B4530DBE837EA396B6D31077FAD3733053989A8442AAC4255CB163B8CA2F27501EA967305695ABD659AA02C83EE60BB574203E9937AE1C621C8ECB5CC1D21D556960B5B9161EA96FFFEBAC72E1B8A6154FC4D88B56C04741F090CBB156A737C9E6A22BA8AC704BC304F8E17E5EA845FDE59FBF788CCE0B97C8761F89A242F3052583C6844A632031C964A6C4A85A128A28619BA1BB3D1BEA4B49841FC847614A066841F52ED0EB8AE0B8B096E92B8195405815B231266F36B18C1A53333DAB95D2A9A374B5478A4A41FB8759957C9AB22CAE545AB544BA8DD05B83F3A613A2437ADB073A9635CB4BBC965FB454CF27B298A40CD0DA3B8F9CA99D8CB4286C5EB476416796070BA535AAA58CDB451CD6DB5CBB0CA20F0C71DE97C30DA97EC7906D06B4B939396028C46BA0E7A865BC8308A3810F1212006339F7BC169B1666FDF475911BBC8AAAB41755C9A8AABFA23C0E37F84FE46999E030494B9298EF9934E8A649C0A5CCE2B22F31809AFED23955D87881D99FC1D352896CAC9055BEA0D016CCBA7805A3A50E221630379BD01135221CAD5D9517C8CC42637B9FC0718E9A9BB4945C72D8D11D3D659D83A3C419509AF5B470DD89B7F3ACCF5F35CFC322115FD66A5CD2875651326F9B3168913BE5B9C87AE0B025EC7A2F4A072750946AC61170A7826D9704C5A23A1C0A2325146C3BC1858826C6B39279C2DA7438A370ED8A0AA5169E3BEC29ED88478732758D454143E227F8595883297842E6AF133B17E4811B0F5713AC73B7E347423EB92822D2306FA14500A7207A0672672046544ACC4EA9C16ED7421A069E0D737A98628519C6A29A424A868B46D9A0CC7C6C9DDD8B8BCBF422C8F48A73143D5ABB66BC55499418430802BAC544463CC7319D17998F29411365766D04C847F3129D9077B7D8339BFB96A6739C3F6B74A8F05F9138AB2FE37ACB57634D1820B50176F5A0B6BC2940F1D5938F1936B5F95828B92EB72973C1590AEB7A552CECA10B00C303B7C75D402071A79E2C810AF7C745E3336712492A42043F2903A37C6434CEE20B1D159B057699FF9C1D3BD68029839A08F43E6C1C819913532F911DD370C7021488E11CB504CB9C70570FFF35B4B4601191DC1AD9E6ADC5FA9618798D7CC860C87A939E4CCF8533632268CF1A51AFF0CB811C5545CB1656E65269477430699CCDEA3800630B78CD5810334CCF02E013F3B80244E70ACDB060BBE7A553B063456B2EA807473413165CE57DD563473CFBC90618ADE1F0B888AA48E722BB2751858FE19687442A48E7CA0D2A29CD51BFD8F78C17B9660BFB54A470B2AE9A955C6AB8D6E5CC92AC8ED3C185DAA8BC29F0578EBB812B97C9E5A848A6384DE4E75A31470B53066A8D027BA44B21749C0492465F9072B28376C4E290B30C1863F9E5B79996083422BD8C272C10ECC6EB9A0A8225B31AA0A66E35B9C0B9A79582BA20A3C04CD29914F083A0158288BA4D6EB62D87264B912BCA39732FBDE536A377AD02B8C835D4A2F4E7B1CE115D0C860BEAA7955A49AD689586A89A2B9F9B10D1595D2FC065AD018A7D56C614471F8E946FE8AB49E8226591119FCADB4F9A861631378736B6688B782D58E97E4572753A9664B6B8536812B25911AA76A242375433192738EEE762F6B84315BB3436231E0A9B277ED28AE0050728346457E13405062DB2804B8DA60BB5C793D4CC0E101CBA2D9182FD7124FF52BF4CA28292AC26D678088953971DBA0B6FEC2C9659353291C70C5B9245A0CA253304AFD3C95102BEA66875C6201680B4BDA38687B648C28EB37478E3BC00CA8A3CC27204642B42B68FCBE7B21A366D0668A5029A7DEEF94CDD6A95D7EA8931673BF7112D4042107B1B8B9700C974F9C4E83A8FACD89BFE0CA3CC4C2FCE80A03D3576C222A792B72B1F070AB7F6B6F2B5CA2AF5054AFA70A896990159B45D1003E2A05648675E596016F1B71DD0F7BDA7E2097FC73B3A143D12C726020AC34958AD7062B92B9ABF3CA6BE5AE29F57135E625A367971837E6363D1532094E022A23467CF932E1F89B5B0803C1EC99B585A78B5865096746F32258214ECB38065C97F455E155ACC2DD005A9C76BED59CDA73837D303504E6C976A606A2BE7BBEC5948B91A349E8936688CC0279754B743ABC58666B19B6C3260051F19206BB962BB6633EB0048E32BAACC5B020D02C86CA9770AD469DB54A106AC73A35B8057422B3DB202C5A5B4E3D535F0FC99326C4B8B7B16F1CB5AF96803FA8C195FC0BCEDDAAF012A51728B76489082373C91E92C87ACCA795160782E3B0DD643544BB96ABC2708D49B759CF057AA223BAFD96A330BAF39810FE8671B4343C297DA1E1969C996216AB5106DA668941B160D4477017136CBCA5B5A8D44C4A8B1CF3EF79785E5AA25C3A1AD6C24FD140F79207DE5A499F8A1534FFA804AA7B3889CBE25C0414704AA57897F17862364ECA56258007248813912B836497F0359C2F7238A05D305A0EA152E72B44417A868134E91B3CA7931232FD4C25F8C2A492A339CDC0A138967211451F2562678FA14080A34436C42B07865AC036A81E97A7787A938025CAF813450368BED0C94B1857604526405D27A1C1ABC81B5B6EC13C71930A97D9232CF7021EF87A4D155328E62B583A83B4AF21F9F5750F8575150424F63B899D71CAD267C09E4467146E16E9B6C653F008C311375E2E006D4076A546B82F5314222F7C654317E79EC6035B73FAF491757E61C828326D53044541C4D4537ABD3EA1E67998C3382974CA78AE1B1960E4A9226B0219AB070F0D7AA66D76F9316ADB80C54D6499771B471E8168D47BCAA08324AB6BA92C3A70275F24FA4DC10E251633FB98D162BB5537202C6A553CE7841C4D40B873B85CA03A0A1E1CFADE6BA5180AB1323CCBA9A3E9C53D37575AB1FD9E7316C6FEECB0A14DF6F2DA56C2F56F55A89635CFCFDA47927AF1F0A47B2D4E4E61634B1B51D37A3A307A972420DE1B7A481B83E583B6AF16F63CB00C6"""), + xeh(""" +CA9564B54F15561C8238E6CFD88137EBD4D277FD5D64BAFC33D6E575947F0FF9F93E3B0A4023DDB6FE480D7D6A2B9ABCD6E6E011EF37C0699A6D60D9AB4B05BC685B0A9AF7D3BD999C7AC1CDF017E6AF1DCF0313759CBB21539D7774C31D7ED8C039AC34D0C6A5F7590A3DFE193D73FA96B3458A364DE1555284D85A2BAE7BA9E57ABA00134E6B09C09777F2F1D7125AF858D81D14C71E34E8F668468997334B72E002920FD3FAD8D588355343FA949F1CC0BC263C7F7A7FEA6AD708DB756AF983B16A593EC224F7D69208938A4526400E326CBED532A777301DDEB5E539CFCE60DB8A022AFC52204C71710C204968FD1457919EB71CA15522AD56ED6B60404D62D1DAD0D06E4A2AD6BC746B28859A77226B774BF56BF7F019F2837F51509E9EBE9EB069DA27401CD1D7BF2A74CBE8341A7F213D061619F4E5F52984FE47066D910F1146CCD8DB48210FA2518D6B9FADFF16ED9D389292C07C8A7021F32BCD538AB06A6D5ADB13D7A96F65A4062A17E26B301CC8AD420732126D7CB801DD489AFF2D717D07A2748B4B01D162D228D5F1533CD5FEE8DFF8F032DFB270B61095785E44CEBBD4EA27158362D2A27582CE78594D4D7428B6AD958A9F1604EBA76A8CC0530E1001AC97E5ACC5EE670D5DC6A78AA45300A2BD5F0802CDEE564FA640A19FB554383A4E4CCF2E5BB3A41879C9428CBDB8DE1F4D3FDEFC18C2A8BAE42C096244279E57B307614C843B341BCCF530F6B187121DD83A9A160A3579C3188A98FE2F49A85A2705B9F76DEF04D5D04676D8319F243DFC99A5F90771B34D2A45EFF92C0CA8E4B542B8ED4C2AFBC92C26F8DD20B26B15F9E719AF22F571EE5B9573D5BD1931138D6315C5104BF80AECF830548E98AB23DFA44E5A23C6CF57740926D1E146937AF8D220684919FD89082E260286AB66F66F8A1B81BEE07A85907D07FCCFB9A1002CDD47A33535C9FC0938E3CDDED04D3FABE6326CBF5643373BAE1151704220E49E177C4D0C6168647E5976670DB7F6D0C12F169955E31F553A53A76093DA2A9A0C589F9AFDCCAAD9EC5449ACC01E12A70BCEB389AC104407415782AF2EA3C73D9EB2797CE6D3C005061C5059AB625DD7D273D4D92D1F4EB411A4033492F19921F60D0317AF286866B865E33B6235F0E3528228CF9DB242124F0A6375D50CAB3851DD2A3A022C1E636E332C90D97FBBFC2CF0B971AB1A89014BC2D942FDF015555431ACB3E7A6F258B816BA84892A1DFE3780A0E0C2E6C06149218E70D60D62573BB51856716C0DDA63A983C4008982E842E655E5767DD203DB3490E1E6BDBEC16350296D879F017BA695FC1CB3BBE516B741A67CA6CE09314AE27F718DF68DE698198289B457884FFF1E439F30D9117D19ED7E466084BD5A73E26B5E1567B148D4C7ACD1368B1CE2709B3AF233679E61914202D0DCFC81EF3ACC250DCEA602103C7E529FD6F31A186927E790E3DEE09DCE87DF694ADA7A3B7BB3BEC64456EE983E25DC6CA1CBCD752D72ABE6FDA2FC81A46F81E83AA9738D528C6FA3E69C453346D0C9A0734DF36BB7650D1D2AFA8A5C4C5A936D41258BD4193DA74FFB180CFF582A32D6F6ACB93836E009E8C880592BE61532215F1F6FA50E8FFBB82208A94D8510F70DC6633DC04F9D94C6AC46EDDD4EB36873E064CBBE65D343957CA7B75024EEBB56F589C3DD2253D68D12DC892ABB1FA4BF033B9B732E89A8B89541F04C6462F62F13B09C6705B31036294F1AC38EDC0C2298D7C6F4374C3B5C368D10DA8D371383CBFB4491126A83D1F75DF44F29BCD39349A9BF6526D14B339FCB440647A5FAB63A370089DF162DDBCEAC8966648DDAD6669E1EADC1C8A33E9B7378693E229C6B715F2F0AE54A67455E79FF8970F23E655E7A540D28958E2E102DC99B5CE5772D00831671CC6F7024BBAE8B04173E439054C96AB3BE918C40C5A8D42A9122CA29C56044D340420D2EAAEB738EEF70331D488169FE91B521835297D7326CA272B2614144EAA0B7A75CC7F3849138255B8A1D7DB875BC7C25D28EE5941DE89BF7B063046CA0CFF31A99D7B1846E01B519137B67647F024B3F6DC70045B6950EC6ADBD68F43F67464858D515D6E3EC5F99D9F1C849831BEB4224FEDB01236712E1D715F6A752D0682169A0E83F064FD6F081F338837FE654BCE7C8CAAA8CA90C8505945D9BB3EA58661102FF0ED3F0DE30C4013122D8CF08E0""") + ), + new DecapsulateTestCase( + xeh(""" +8445C336F3518B298163DCBB6357597983CA2E873DCB49610CF52F14DBCB947C1F3EE9266967276B0C576CF7C30EE6B93DEA5118676CBEE1B1D4794206FB369ABA41167B4393855C84EBA8F32373C05BAE7631C802744AADB6C2DE41250C494315230B52826C34587CB21B183B49B2A5AC04921AC6BFAC1B24A4B37A93A4B168CCE7591BE6111F476260F2762959F5C1640118C2423772E2AD03DC7168A38C6DD39F5F7254264280C8BC10B914168070472FA880ACB8601A8A0837F25FE194687CD68B7DE2340F036DAD891D38D1B0CE9C2633355CF57B50B896036FCA260D2669F85BAC79714FDAFB41EF80B8C30264C31386AE60B05FAA542A26B41EB85F67068F088034FF67AA2E815AAB8BCA6BF71F70ECC3CBCBC45EF701FCD542BD21C7B09568F369C669F396473844FBA14957F51974D852B978014603A210C019036287008994F21255B25099AD82AA132438963B2C0A47CDF5F32BA46B76C7A6559F18BFD555B762E487B6AC992FE20E283CA0B3F6164496955995C3B28A57BBC29826F06FB38B253470AF631BC46C3A8F9CE824321985DD01C05F69B824F916633B40654C75AAEB9385576FFDE2990A6B0A3BE829D6D84E34F1780589C79204C63C798F55D23187E461D48C21E5C047E535B19F458BBA1345B9E41E0CB4A9C2D8C40B490A3BABC553B3026B1672D28CBC8B498A3A99579A832FEAE74610F0B6250CC333E9493EB1621ED34AA4AB175F2CA231152509ACB6AC86B20F6B39108439E5EC12D465A0FEF35003E14277A21812146B2544716D6AB82D1B0726C27A98D589EBDACC4C54BA77B2498F217E14E34E66025A2A143A992520A61C0672CC9CCED7C9450C683E90A3E4651DB623A6DB39AC26125B7FC1986D7B0493B8B72DE7707DC20BBDD43713156AF7D9430EF45399663C2202739168692DD657545B056D9C92385A7F414B34B90C7960D57B35BA7DDE7B81FCA0119D741B12780926018FE4C8030BF038E18B4FA33743D0D3C846417E9D5915C246315938B1E233614501D026959551258B233230D428B181B132F1D0B026067BA816999BC0CD6B547E548B63C9EAA091BAC493DC598DBC2B0E146A2591C2A8C009DD5170AAE027C541A1B5E66E45C65612984C46770493EC896EF25AA9305E9F06692CD0B2F06962E205BEBE113A34EBB1A4830A9B3749641BB935007B23B24BFE576956254D7A35AA496AC446C67A7FEC85A60057E8580617BCB3FAD15C76440FED54CC789394FEA24452CC6B0585B7EB0A88BBA9500D9800E6241AFEB523B55A96A535151D1049573206E59C7FEB070966823634F77D5F1291755A243119621AF8084AB7AC1E22A0568C6201417CBE3655D8A08DD5B513884C98D5A493FD49382EA41860F133CCD601E885966426A2B1F23D42D82E24582D99725192C21777467B1457B1DD429A0C41A5C3D704CEA06278C59941B438C62727097809B4530DBE837EA396B6D31077FAD3733053989A8442AAC4255CB163B8CA2F27501EA967305695ABD659AA02C83EE60BB574203E9937AE1C621C8ECB5CC1D21D556960B5B9161EA96FFFEBAC72E1B8A6154FC4D88B56C04741F090CBB156A737C9E6A22BA8AC704BC304F8E17E5EA845FDE59FBF788CCE0B97C8761F89A242F3052583C6844A632031C964A6C4A85A128A28619BA1BB3D1BEA4B49841FC847614A066841F52ED0EB8AE0B8B096E92B8195405815B231266F36B18C1A53333DAB95D2A9A374B5478A4A41FB8759957C9AB22CAE545AB544BA8DD05B83F3A613A2437ADB073A9635CB4BBC965FB454CF27B298A40CD0DA3B8F9CA99D8CB4286C5EB476416796070BA535AAA58CDB451CD6DB5CBB0CA20F0C71DE97C30DA97EC7906D06B4B939396028C46BA0E7A865BC8308A3810F1212006339F7BC169B1666FDF475911BBC8AAAB41755C9A8AABFA23C0E37F84FE46999E030494B9298EF9934E8A649C0A5CCE2B22F31809AFED23955D87881D99FC1D352896CAC9055BEA0D016CCBA7805A3A50E221630379BD01135221CAD5D9517C8CC42637B9FC0718E9A9BB4945C72D8D11D3D659D83A3C419509AF5B470DD89B7F3ACCF5F35CFC322115FD66A5CD2875651326F9B3168913BE5B9C87AE0B025EC7A2F4A072750946AC61170A7826D9704C5A23A1C0A2325146C3BC1858826C6B39279C2DA7438A370ED8A0AA5169E3BEC29ED88478732758D454143E227F8595883297842E6AF133B17E4811B0F5713AC73B7E347423EB92822D2306FA14500A7207A0672672046544ACC4EA9C16ED7421A069E0D737A98628519C6A29A424A868B46D9A0CC7C6C9DDD8B8BCBF422C8F48A73143D5ABB66BC55499418430802BAC544463CC7319D17998F29411365766D04C847F3129D9077B7D8339BFB96A6739C3F6B74A8F05F9138AB2FE37ACB57634D1820B50176F5A0B6BC2940F1D5938F1936B5F95828B92EB72973C1590AEB7A552CECA10B00C303B7C75D402071A79E2C810AF7C745E3336712492A42043F2903A37C6434CEE20B1D159B057699FF9C1D3BD68029839A08F43E6C1C819913532F911DD370C7021488E11CB504CB9C70570FFF35B4B4601191DC1AD9E6ADC5FA9618798D7CC860C87A939E4CCF8533632268CF1A51AFF0CB811C5545CB1656E65269477430699CCDEA3800630B78CD5810334CCF02E013F3B80244E70ACDB060BBE7A553B063456B2EA807473413165CE57DD563473CFBC90618ADE1F0B888AA48E722BB2751858FE19687442A48E7CA0D2A29CD51BFD8F78C17B9660BFB54A470B2AE9A955C6AB8D6E5CC92AC8ED3C185DAA8BC29F0578EBB812B97C9E5A848A6384DE4E75A31470B53066A8D027BA44B21749C0492465F9072B28376C4E290B30C1863F9E5B79996083422BD8C272C10ECC6EB9A0A8225B31AA0A66E35B9C0B9A79582BA20A3C04CD29914F083A0158288BA4D6EB62D87264B912BCA39732FBDE536A377AD02B8C835D4A2F4E7B1CE115D0C860BEAA7955A49AD689586A89A2B9F9B10D1595D2FC065AD018A7D56C614471F8E946FE8AB49E8226591119FCADB4F9A861631378736B6688B782D58E97E4572753A9664B6B8536812B25911AA76A242375433192738EEE762F6B84315BB3436231E0A9B277ED28AE0050728346457E13405062DB2804B8DA60BB5C793D4CC0E101CBA2D9182FD7124FF52BF4CA28292AC26D678088953971DBA0B6FEC2C9659353291C70C5B9245A0CA253304AFD3C95102BEA66875C6201680B4BDA38687B648C28EB37478E3BC00CA8A3CC27204642B42B68FCBE7B21A366D0668A5029A7DEEF94CDD6A95D7EA8931673BF7112D4042107B1B8B9700C974F9C4E83A8FACD89BFE0CA3CC4C2FCE80A03D3576C222A792B72B1F070AB7F6B6F2B5CA2AF5054AFA70A896990159B45D1003E2A05648675E596016F1B71DD0F7BDA7E2097FC73B3A143D12C726020AC34958AD7062B92B9ABF3CA6BE5AE29F57135E625A367971837E6363D1532094E022A23467CF932E1F89B5B0803C1EC99B585A78B5865096746F32258214ECB38065C97F455E155ACC2DD005A9C76BED59CDA73837D303504E6C976A606A2BE7BBEC5948B91A349E8936688CC0279754B743ABC58666B19B6C3260051F19206BB962BB6633EB0048E32BAACC5B020D02C86CA9770AD469DB54A106AC73A35B8057422B3DB202C5A5B4E3D535F0FC99326C4B8B7B16F1CB5AF96803FA8C195FC0BCEDDAAF012A51728B76489082373C91E92C87ACCA795160782E3B0DD643544BB96ABC2708D49B759CF057AA223BAFD96A330BAF39810FE8671B4343C297DA1E1969C996216AB5106DA668941B160D4477017136CBCA5B5A8D44C4A8B1CF3EF79785E5AA25C3A1AD6C24FD140F79207DE5A499F8A1534FFA804AA7B3889CBE25C0414704AA57897F17862364ECA56258007248813912B836497F0359C2F7238A05D305A0EA152E72B44417A868134E91B3CA7931232FD4C25F8C2A492A339CDC0A138967211451F2562678FA14080A34436C42B07865AC036A81E97A7787A938025CAF813450368BED0C94B1857604526405D27A1C1ABC81B5B6EC13C71930A97D9232CF7021EF87A4D155328E62B583A83B4AF21F9F5750F8575150424F63B899D71CAD267C09E4467146E16E9B6C653F008C311375E2E006D4076A546B82F5314222F7C654317E79EC6035B73FAF491757E61C828326D53044541C4D4537ABD3EA1E67998C3382974CA78AE1B1960E4A9226B0219AB070F0D7AA66D76F9316ADB80C54D6499771B471E8168D47BCAA08324AB6BA92C3A70275F24FA4DC10E251633FB98D162BB5537202C6A553CE7841C4D40B873B85CA03A0A1E1CFADE6BA5180AB1323CCBA9A3E9C53D37575AB1FD9E7316C6FEECB0A14DF6F2DA56C2F56F55A89635CFCFDA47927AF1F0A47B2D4E4E61634B1B51D37A3A307A972420DE1B7A481B83E583B6AF16F63CB00C6"""), + xeh(""" +C18D7D95DB69D4FE1E6DB385024D83C01F4790E2BFD25DB3F5DD5A208ABE06551BE0936A84091F081308471E82AC9ED6BAA90824D5525701AE0B638003C21D5EBBCBC17FCA8F522BE4F9FE5ECF38BB66131578163D50994E532D0776B187498C5A85AFF617D4550345F3855F968A8964B4F3CACCFFEC82C92BC8617C78C98E10C91AB505A92CEFE0AD6C8B66406AEA4C3FBC5275047B3E983AD42BCD31838A39B92E1C61E9E62443DF3A45044819D9E289B5514D4F74E08FC3914C0B66D2352CF8B1FABB4AC9B0748A43547BECD29D447D01083803D34E8B7EC89B4F0D78B88AEB33E308989BED2D7A78E1C06A11F3BE808F0B9D9712C80D63DA10475849DDF6CB0DBB1007FCDEDCA3C4220386B78D9EC6E380B4F57731D964470B42CF7D4B4E6D98A12A9021121C8BACC4B132A274941DA57D824FCB60B83565F5CE05D140653DD4C70F385B55D485D24935F3631AC63FA12FF50BCF4E431EE4074B2A05A2A97354C7B4169B13EB225F1727F8424F7CA6317A04C355FE785248E67E053C4D4BDBBC47DC7760AC71DFA2502FBAD1180F2B095425198A26BD5A0F7DFAB70524B8F076E7C7F215B0536B0023F8A9F7784809FF4DA245C2EAC5F9E0AB85D987C5B6FEBDB3DF197347BDFB8D5F1547FD2A59D4B434FA7ECF8D8535903D3892868BA0632F194AD6E4D5A3B30E5A6B92F829642DD4A3031358F9F0D9D46530602A35CE455F0E360C14A754828972D85561AA835D87275AC510856D26192EA319FEB45709346929DA5C5919510CB2A482CBB0F1CB4BF6FCC0343F6DBDFDE734919EF335356ABE82F80786EF0CA22E5B03A05963E7051E1FA7EA4BC3141B5746D264BE1A32CCCD39DFF8F9E5E2AB4C5F51CEFEDE3C1CD118351F9A8ED30649D407FD31F6C4BDA3AF44888ADFC3D118BBD04412FF810A7E106EC32F7524E4750DC5F35A9C55541421B5E412E57BAF24622627F02633F524FF854F71011580598C5CE01190258310BB12D7DB5F95E9EBE5F72C97E89287C2F9007A9332EC51DEF1AA2F2CADA9A8A547C3508B4D294364EAFC858B98C60C5469CC7C3CE3ED659B5A54E889FEFAF825FC777AA74A8896C9447704CA7300FC5DF5810681E3ABE083C1285B3B97EFB0E21F78F45409D00B2E1680DA79439734190AFF0D68E062970F8F6B0F1E84A559B09ACD9938913FC26484DF2125FB6D7FC2E3F0DCBD72D9E5DEDBE7E44CE7D895CC9CF6945BDE0C52F92340F9FAD3009BC90D4C2D3DEF7C1F10A862F9D71681537FE4E2716912DAAB8C9DCBD81A083220F68B05F7502F3911B1B6E3B26DA14EF646DCE67852FAB6145BBE7E21725C21CBB2849C63D01AEAD932F8EE9345D8666786AF06AD0C89B08495A6EA95992301E2D8B6A14426971C7B31626BC93BBE76CF3DB9487B5BFC5BAF298F1A92FC3BE276983E53701F9A550E2961E6E2F07317381364719BF3FC741E2A5A0664D8873120D0C11287E92DB12126332D43F35407C01F7F85DF7916B651EE4A30D602E71227733EC9252EC8346361DEFC23397CEAD0C23AF44C77A4C97242C7FA9065BF0C81983AF3E516C1B8FFF3DD5A6C43B6ED5AD8BB3327A09B6B459168F3E497DCB65FE7593E8AB429B8EB2B31F76DF08A6A8F35EC4CA994037493A8C04A73D8191D682542FCBE16E657D3E477A7D25A1D650450E94FAF485CB76FE7110BAA902D74C335FEE1546D076163B5540D8495E16E909E1D28C15BFB421756B921778A784E16207BAD407B64B9CD83AFB0A602374DE06F5C836F4A1ADFD495012DA8D3FA4B829F735B31BAA6364A2AC11BD18E40628DCF82238D86B0B5EE9DF6D179103E1D12F5191475FE3008A5382CC24648CBB24F2298758823B7F93DF10B380C3179F07DC3277021E9EEA2BE5CED646260165B57A18C26E259F83576938828D4C7617623006682CAA613AAB770791874B55E2D0BB32DDB628919B42C09BB7DAE1FBEE8661CC13F8B6A47CF5D6085A2AED796E305738B508599673DCD03AFC267023814FB1DF7EB928D5762BBAB4515921D81C6CAF551DC6EA16C1D31125B99299ADE63FBFB9BC1CE46331394CE472DE6DCEFB2BF9B3828B0110246419C47D2A1FEF16097B943A310C0664A92A155C8273402E83CB94D7E733E4527E7525E9BAB219B69676804C1F67088184038668D55AC4F6E04CEC0EED4B05DE649A9C2064F241AAF9732B09B0EE4E5BB2C0386E45FBD44""") + ), + new DecapsulateTestCase( + xeh(""" +8445C336F3518B298163DCBB6357597983CA2E873DCB49610CF52F14DBCB947C1F3EE9266967276B0C576CF7C30EE6B93DEA5118676CBEE1B1D4794206FB369ABA41167B4393855C84EBA8F32373C05BAE7631C802744AADB6C2DE41250C494315230B52826C34587CB21B183B49B2A5AC04921AC6BFAC1B24A4B37A93A4B168CCE7591BE6111F476260F2762959F5C1640118C2423772E2AD03DC7168A38C6DD39F5F7254264280C8BC10B914168070472FA880ACB8601A8A0837F25FE194687CD68B7DE2340F036DAD891D38D1B0CE9C2633355CF57B50B896036FCA260D2669F85BAC79714FDAFB41EF80B8C30264C31386AE60B05FAA542A26B41EB85F67068F088034FF67AA2E815AAB8BCA6BF71F70ECC3CBCBC45EF701FCD542BD21C7B09568F369C669F396473844FBA14957F51974D852B978014603A210C019036287008994F21255B25099AD82AA132438963B2C0A47CDF5F32BA46B76C7A6559F18BFD555B762E487B6AC992FE20E283CA0B3F6164496955995C3B28A57BBC29826F06FB38B253470AF631BC46C3A8F9CE824321985DD01C05F69B824F916633B40654C75AAEB9385576FFDE2990A6B0A3BE829D6D84E34F1780589C79204C63C798F55D23187E461D48C21E5C047E535B19F458BBA1345B9E41E0CB4A9C2D8C40B490A3BABC553B3026B1672D28CBC8B498A3A99579A832FEAE74610F0B6250CC333E9493EB1621ED34AA4AB175F2CA231152509ACB6AC86B20F6B39108439E5EC12D465A0FEF35003E14277A21812146B2544716D6AB82D1B0726C27A98D589EBDACC4C54BA77B2498F217E14E34E66025A2A143A992520A61C0672CC9CCED7C9450C683E90A3E4651DB623A6DB39AC26125B7FC1986D7B0493B8B72DE7707DC20BBDD43713156AF7D9430EF45399663C2202739168692DD657545B056D9C92385A7F414B34B90C7960D57B35BA7DDE7B81FCA0119D741B12780926018FE4C8030BF038E18B4FA33743D0D3C846417E9D5915C246315938B1E233614501D026959551258B233230D428B181B132F1D0B026067BA816999BC0CD6B547E548B63C9EAA091BAC493DC598DBC2B0E146A2591C2A8C009DD5170AAE027C541A1B5E66E45C65612984C46770493EC896EF25AA9305E9F06692CD0B2F06962E205BEBE113A34EBB1A4830A9B3749641BB935007B23B24BFE576956254D7A35AA496AC446C67A7FEC85A60057E8580617BCB3FAD15C76440FED54CC789394FEA24452CC6B0585B7EB0A88BBA9500D9800E6241AFEB523B55A96A535151D1049573206E59C7FEB070966823634F77D5F1291755A243119621AF8084AB7AC1E22A0568C6201417CBE3655D8A08DD5B513884C98D5A493FD49382EA41860F133CCD601E885966426A2B1F23D42D82E24582D99725192C21777467B1457B1DD429A0C41A5C3D704CEA06278C59941B438C62727097809B4530DBE837EA396B6D31077FAD3733053989A8442AAC4255CB163B8CA2F27501EA967305695ABD659AA02C83EE60BB574203E9937AE1C621C8ECB5CC1D21D556960B5B9161EA96FFFEBAC72E1B8A6154FC4D88B56C04741F090CBB156A737C9E6A22BA8AC704BC304F8E17E5EA845FDE59FBF788CCE0B97C8761F89A242F3052583C6844A632031C964A6C4A85A128A28619BA1BB3D1BEA4B49841FC847614A066841F52ED0EB8AE0B8B096E92B8195405815B231266F36B18C1A53333DAB95D2A9A374B5478A4A41FB8759957C9AB22CAE545AB544BA8DD05B83F3A613A2437ADB073A9635CB4BBC965FB454CF27B298A40CD0DA3B8F9CA99D8CB4286C5EB476416796070BA535AAA58CDB451CD6DB5CBB0CA20F0C71DE97C30DA97EC7906D06B4B939396028C46BA0E7A865BC8308A3810F1212006339F7BC169B1666FDF475911BBC8AAAB41755C9A8AABFA23C0E37F84FE46999E030494B9298EF9934E8A649C0A5CCE2B22F31809AFED23955D87881D99FC1D352896CAC9055BEA0D016CCBA7805A3A50E221630379BD01135221CAD5D9517C8CC42637B9FC0718E9A9BB4945C72D8D11D3D659D83A3C419509AF5B470DD89B7F3ACCF5F35CFC322115FD66A5CD2875651326F9B3168913BE5B9C87AE0B025EC7A2F4A072750946AC61170A7826D9704C5A23A1C0A2325146C3BC1858826C6B39279C2DA7438A370ED8A0AA5169E3BEC29ED88478732758D454143E227F8595883297842E6AF133B17E4811B0F5713AC73B7E347423EB92822D2306FA14500A7207A0672672046544ACC4EA9C16ED7421A069E0D737A98628519C6A29A424A868B46D9A0CC7C6C9DDD8B8BCBF422C8F48A73143D5ABB66BC55499418430802BAC544463CC7319D17998F29411365766D04C847F3129D9077B7D8339BFB96A6739C3F6B74A8F05F9138AB2FE37ACB57634D1820B50176F5A0B6BC2940F1D5938F1936B5F95828B92EB72973C1590AEB7A552CECA10B00C303B7C75D402071A79E2C810AF7C745E3336712492A42043F2903A37C6434CEE20B1D159B057699FF9C1D3BD68029839A08F43E6C1C819913532F911DD370C7021488E11CB504CB9C70570FFF35B4B4601191DC1AD9E6ADC5FA9618798D7CC860C87A939E4CCF8533632268CF1A51AFF0CB811C5545CB1656E65269477430699CCDEA3800630B78CD5810334CCF02E013F3B80244E70ACDB060BBE7A553B063456B2EA807473413165CE57DD563473CFBC90618ADE1F0B888AA48E722BB2751858FE19687442A48E7CA0D2A29CD51BFD8F78C17B9660BFB54A470B2AE9A955C6AB8D6E5CC92AC8ED3C185DAA8BC29F0578EBB812B97C9E5A848A6384DE4E75A31470B53066A8D027BA44B21749C0492465F9072B28376C4E290B30C1863F9E5B79996083422BD8C272C10ECC6EB9A0A8225B31AA0A66E35B9C0B9A79582BA20A3C04CD29914F083A0158288BA4D6EB62D87264B912BCA39732FBDE536A377AD02B8C835D4A2F4E7B1CE115D0C860BEAA7955A49AD689586A89A2B9F9B10D1595D2FC065AD018A7D56C614471F8E946FE8AB49E8226591119FCADB4F9A861631378736B6688B782D58E97E4572753A9664B6B8536812B25911AA76A242375433192738EEE762F6B84315BB3436231E0A9B277ED28AE0050728346457E13405062DB2804B8DA60BB5C793D4CC0E101CBA2D9182FD7124FF52BF4CA28292AC26D678088953971DBA0B6FEC2C9659353291C70C5B9245A0CA253304AFD3C95102BEA66875C6201680B4BDA38687B648C28EB37478E3BC00CA8A3CC27204642B42B68FCBE7B21A366D0668A5029A7DEEF94CDD6A95D7EA8931673BF7112D4042107B1B8B9700C974F9C4E83A8FACD89BFE0CA3CC4C2FCE80A03D3576C222A792B72B1F070AB7F6B6F2B5CA2AF5054AFA70A896990159B45D1003E2A05648675E596016F1B71DD0F7BDA7E2097FC73B3A143D12C726020AC34958AD7062B92B9ABF3CA6BE5AE29F57135E625A367971837E6363D1532094E022A23467CF932E1F89B5B0803C1EC99B585A78B5865096746F32258214ECB38065C97F455E155ACC2DD005A9C76BED59CDA73837D303504E6C976A606A2BE7BBEC5948B91A349E8936688CC0279754B743ABC58666B19B6C3260051F19206BB962BB6633EB0048E32BAACC5B020D02C86CA9770AD469DB54A106AC73A35B8057422B3DB202C5A5B4E3D535F0FC99326C4B8B7B16F1CB5AF96803FA8C195FC0BCEDDAAF012A51728B76489082373C91E92C87ACCA795160782E3B0DD643544BB96ABC2708D49B759CF057AA223BAFD96A330BAF39810FE8671B4343C297DA1E1969C996216AB5106DA668941B160D4477017136CBCA5B5A8D44C4A8B1CF3EF79785E5AA25C3A1AD6C24FD140F79207DE5A499F8A1534FFA804AA7B3889CBE25C0414704AA57897F17862364ECA56258007248813912B836497F0359C2F7238A05D305A0EA152E72B44417A868134E91B3CA7931232FD4C25F8C2A492A339CDC0A138967211451F2562678FA14080A34436C42B07865AC036A81E97A7787A938025CAF813450368BED0C94B1857604526405D27A1C1ABC81B5B6EC13C71930A97D9232CF7021EF87A4D155328E62B583A83B4AF21F9F5750F8575150424F63B899D71CAD267C09E4467146E16E9B6C653F008C311375E2E006D4076A546B82F5314222F7C654317E79EC6035B73FAF491757E61C828326D53044541C4D4537ABD3EA1E67998C3382974CA78AE1B1960E4A9226B0219AB070F0D7AA66D76F9316ADB80C54D6499771B471E8168D47BCAA08324AB6BA92C3A70275F24FA4DC10E251633FB98D162BB5537202C6A553CE7841C4D40B873B85CA03A0A1E1CFADE6BA5180AB1323CCBA9A3E9C53D37575AB1FD9E7316C6FEECB0A14DF6F2DA56C2F56F55A89635CFCFDA47927AF1F0A47B2D4E4E61634B1B51D37A3A307A972420DE1B7A481B83E583B6AF16F63CB00C6"""), + xeh(""" +E7B361D043C4A0B3A780121E9648DCF38DFC10ED5E47EE4DB5523C1EE1F53552640C89D9D7EFB9DFAA8EBAC7AF137A850AE41A0FF8F8CE31FDFD3E671555180EE46AB58322FE4E5F525146F9D4CDD1D1CA01413C5AC7259E1A2604A5951755F47D1761ED16B26D3DCFF79A263BC38852007BD3F381FC3B79B46A4B372918AF3117180726117BDB33C063BF5EE5D69CB48D267929CEDC890B743DEA43205EAD46FFA69D9B30C1AA5F146CBA3B0B7C4D4A50FA8D120777F1661430DA1B9D1C1DB4E10C5C3C2436D381EB13DDCC61EEB3F9AB46B60D2FB714929139E9C27F8730684EE17B077BDC003500027FAC94DA80870B382EFE41BAAD902A491C29DC95A8F80BB075A4E61C8F100FA738BED869B48F897ABC9CCE08917B5073229A94F3790947FC1AB6C2DEB5B012D60EC156A8A041DE151EED8884EC616089CB08EAEE37C006F5BBD10ACE9596A34FB09345A14FC4EA674E4A74699BA5240FF1282ED1E64360BDC9F7336051A33DD48809CF0011BEB3CE8C681588AB29F5F26175A8A6FD7884CB96CE3964FF10A67FC4A4E14CA516162C16D8127CBC45BCF7C88C89C8602032298B53C19FD099809814BE0504BCFD2407F48F2F24C5ACB89DB4F54A018DD586D871C58CC0D998FB4B0E5F5DAC631BE8367DDE88ED711F069FC8A80EBB573A7DA12AD8F13A4CA1E8A22D9EB53C55B80F700C58E6EADE6CDEB35C262EB42C903AD854F843547B79464524833A05E3FDC46092E41D8E339E7662D1209D338B8A02994D15A10439C1DC02A5B0EDEA58AF197866F43269A57C747DF389EC597F523211770E9C7E4CEFC5E43EEF791897EE43CA6146F3F757B66B9E7592E728565325D1740A1736CD0E678BBAA043F4C355FDE27094F74FAE27AD8C270930DF637C652BC1957F958DB013C146F2A4C5F451AB58A55C2B638A82755C11991B049E82F8D3CD3E7D3571FD5A83B60280E92031B610FADAC9E5F61DA469DC4C51381C970E03F09CA560E5D69D9B32AD6C1DDB6FBE9F8FC0551A909187AD65AFDC067EC6AA01AD684AE4C4F2E1F64046083D3EB347A6B6B23BBBF14668B9650D9364A6A7666593DB86FEB59628A91169F8AE24F67680789D316338B2F27766A83957831D98C88C837215AE3BD49767ADCADE758320ACE76D7F39E2970EDD19657F0EC12583164C325F0A000D065036BA2522F960C87F9852F30BC6BB5419CD8C0A1F9757BD358E748CB244A5E677AB9F9319A43A9BAC847A566052CA42C1C1DB36A0D97F144BED3BC5F11A5C8BEF7A74A4CC67748F1DF53F8B4714E0A04256B36A814B08B78A9737757E3F1347F9E5535DF1AC98B08ACC1409278B925F3B6C7863BC0969520FC6183E216B4E8E449B0FB999F1C65567AE2064774454EFDA67E1749FB24A91B55DFFE7DB75C4E24E8EF2389214EC3E95972CD53234CDAF8958D651A7A95802E65499A8A7811A65ABBA90129D5EC4247D8183316EF818E79BE839BB3379E4B8F4EE9438BFE310105C91F8703AE94D8F9D53096E2341E74E0237DB2665F16954B9713DD9638B05970A9A96261586B04F9FF369028DCC43D35B51F95E69B0323A1CEACC4A5E2EF640CDAF3407BF5F5E14C9042FF299786BC55965EB7C8BB161487FCD7911BDC2FBB65100F2200E16C690F801EA6615F9130EB99DF816B188B06E9A3105B78212B76609DF190FF102CCC451746CBAD16464E8E2F647B75777F664DE86F5089C37E3A54A6AA8B456CB98B42DEB5529C06DA45C2D2A13060BE56A061CE210ECD307FF5AD5BE39CDD8D27B4A3403323D4F53BE35FB4E31670F73CCE74CF73CFBB29A5FC2EECB5F852CA911942066D826404B77251BE5BC5980D0A6E0DB4D753D86490D4250536DACF05D82064A28324B49AD4AD202CD0FC939BB7A3CD9FB1E3E196348EF336DCDBE4BC831DF5847070D0B2BE1C4910FE1C69F58C6A7A2E7FEBD51BE1D0E050D5D721D7537A0325E7ED30AECA75A2A81BBD86EBF91CAFE4483D2729271ABDBB65C2CD9973627D2820DC7ADE3E26CA2F466EB117B2BA98EC868DC728ABC6907D49E2495504133FAA7F8758FD23076D1A65A91C75512F89EE4E2F3E480D6ECB0EE90793F4F93FFB75DF58A7072C91D5A1D9EF0C3B1DDAE79EF576E6A276F78CDC24664897F07B3A20691601EAD2F499C50589BDBCEC74FCADED1A8AFDFC061C2712ED599D48A3ACB3D86515D664D0CF3FA349A1910CB""") + ), + new DecapsulateTestCase( + xeh(""" +8445C336F3518B298163DCBB6357597983CA2E873DCB49610CF52F14DBCB947C1F3EE9266967276B0C576CF7C30EE6B93DEA5118676CBEE1B1D4794206FB369ABA41167B4393855C84EBA8F32373C05BAE7631C802744AADB6C2DE41250C494315230B52826C34587CB21B183B49B2A5AC04921AC6BFAC1B24A4B37A93A4B168CCE7591BE6111F476260F2762959F5C1640118C2423772E2AD03DC7168A38C6DD39F5F7254264280C8BC10B914168070472FA880ACB8601A8A0837F25FE194687CD68B7DE2340F036DAD891D38D1B0CE9C2633355CF57B50B896036FCA260D2669F85BAC79714FDAFB41EF80B8C30264C31386AE60B05FAA542A26B41EB85F67068F088034FF67AA2E815AAB8BCA6BF71F70ECC3CBCBC45EF701FCD542BD21C7B09568F369C669F396473844FBA14957F51974D852B978014603A210C019036287008994F21255B25099AD82AA132438963B2C0A47CDF5F32BA46B76C7A6559F18BFD555B762E487B6AC992FE20E283CA0B3F6164496955995C3B28A57BBC29826F06FB38B253470AF631BC46C3A8F9CE824321985DD01C05F69B824F916633B40654C75AAEB9385576FFDE2990A6B0A3BE829D6D84E34F1780589C79204C63C798F55D23187E461D48C21E5C047E535B19F458BBA1345B9E41E0CB4A9C2D8C40B490A3BABC553B3026B1672D28CBC8B498A3A99579A832FEAE74610F0B6250CC333E9493EB1621ED34AA4AB175F2CA231152509ACB6AC86B20F6B39108439E5EC12D465A0FEF35003E14277A21812146B2544716D6AB82D1B0726C27A98D589EBDACC4C54BA77B2498F217E14E34E66025A2A143A992520A61C0672CC9CCED7C9450C683E90A3E4651DB623A6DB39AC26125B7FC1986D7B0493B8B72DE7707DC20BBDD43713156AF7D9430EF45399663C2202739168692DD657545B056D9C92385A7F414B34B90C7960D57B35BA7DDE7B81FCA0119D741B12780926018FE4C8030BF038E18B4FA33743D0D3C846417E9D5915C246315938B1E233614501D026959551258B233230D428B181B132F1D0B026067BA816999BC0CD6B547E548B63C9EAA091BAC493DC598DBC2B0E146A2591C2A8C009DD5170AAE027C541A1B5E66E45C65612984C46770493EC896EF25AA9305E9F06692CD0B2F06962E205BEBE113A34EBB1A4830A9B3749641BB935007B23B24BFE576956254D7A35AA496AC446C67A7FEC85A60057E8580617BCB3FAD15C76440FED54CC789394FEA24452CC6B0585B7EB0A88BBA9500D9800E6241AFEB523B55A96A535151D1049573206E59C7FEB070966823634F77D5F1291755A243119621AF8084AB7AC1E22A0568C6201417CBE3655D8A08DD5B513884C98D5A493FD49382EA41860F133CCD601E885966426A2B1F23D42D82E24582D99725192C21777467B1457B1DD429A0C41A5C3D704CEA06278C59941B438C62727097809B4530DBE837EA396B6D31077FAD3733053989A8442AAC4255CB163B8CA2F27501EA967305695ABD659AA02C83EE60BB574203E9937AE1C621C8ECB5CC1D21D556960B5B9161EA96FFFEBAC72E1B8A6154FC4D88B56C04741F090CBB156A737C9E6A22BA8AC704BC304F8E17E5EA845FDE59FBF788CCE0B97C8761F89A242F3052583C6844A632031C964A6C4A85A128A28619BA1BB3D1BEA4B49841FC847614A066841F52ED0EB8AE0B8B096E92B8195405815B231266F36B18C1A53333DAB95D2A9A374B5478A4A41FB8759957C9AB22CAE545AB544BA8DD05B83F3A613A2437ADB073A9635CB4BBC965FB454CF27B298A40CD0DA3B8F9CA99D8CB4286C5EB476416796070BA535AAA58CDB451CD6DB5CBB0CA20F0C71DE97C30DA97EC7906D06B4B939396028C46BA0E7A865BC8308A3810F1212006339F7BC169B1666FDF475911BBC8AAAB41755C9A8AABFA23C0E37F84FE46999E030494B9298EF9934E8A649C0A5CCE2B22F31809AFED23955D87881D99FC1D352896CAC9055BEA0D016CCBA7805A3A50E221630379BD01135221CAD5D9517C8CC42637B9FC0718E9A9BB4945C72D8D11D3D659D83A3C419509AF5B470DD89B7F3ACCF5F35CFC322115FD66A5CD2875651326F9B3168913BE5B9C87AE0B025EC7A2F4A072750946AC61170A7826D9704C5A23A1C0A2325146C3BC1858826C6B39279C2DA7438A370ED8A0AA5169E3BEC29ED88478732758D454143E227F8595883297842E6AF133B17E4811B0F5713AC73B7E347423EB92822D2306FA14500A7207A0672672046544ACC4EA9C16ED7421A069E0D737A98628519C6A29A424A868B46D9A0CC7C6C9DDD8B8BCBF422C8F48A73143D5ABB66BC55499418430802BAC544463CC7319D17998F29411365766D04C847F3129D9077B7D8339BFB96A6739C3F6B74A8F05F9138AB2FE37ACB57634D1820B50176F5A0B6BC2940F1D5938F1936B5F95828B92EB72973C1590AEB7A552CECA10B00C303B7C75D402071A79E2C810AF7C745E3336712492A42043F2903A37C6434CEE20B1D159B057699FF9C1D3BD68029839A08F43E6C1C819913532F911DD370C7021488E11CB504CB9C70570FFF35B4B4601191DC1AD9E6ADC5FA9618798D7CC860C87A939E4CCF8533632268CF1A51AFF0CB811C5545CB1656E65269477430699CCDEA3800630B78CD5810334CCF02E013F3B80244E70ACDB060BBE7A553B063456B2EA807473413165CE57DD563473CFBC90618ADE1F0B888AA48E722BB2751858FE19687442A48E7CA0D2A29CD51BFD8F78C17B9660BFB54A470B2AE9A955C6AB8D6E5CC92AC8ED3C185DAA8BC29F0578EBB812B97C9E5A848A6384DE4E75A31470B53066A8D027BA44B21749C0492465F9072B28376C4E290B30C1863F9E5B79996083422BD8C272C10ECC6EB9A0A8225B31AA0A66E35B9C0B9A79582BA20A3C04CD29914F083A0158288BA4D6EB62D87264B912BCA39732FBDE536A377AD02B8C835D4A2F4E7B1CE115D0C860BEAA7955A49AD689586A89A2B9F9B10D1595D2FC065AD018A7D56C614471F8E946FE8AB49E8226591119FCADB4F9A861631378736B6688B782D58E97E4572753A9664B6B8536812B25911AA76A242375433192738EEE762F6B84315BB3436231E0A9B277ED28AE0050728346457E13405062DB2804B8DA60BB5C793D4CC0E101CBA2D9182FD7124FF52BF4CA28292AC26D678088953971DBA0B6FEC2C9659353291C70C5B9245A0CA253304AFD3C95102BEA66875C6201680B4BDA38687B648C28EB37478E3BC00CA8A3CC27204642B42B68FCBE7B21A366D0668A5029A7DEEF94CDD6A95D7EA8931673BF7112D4042107B1B8B9700C974F9C4E83A8FACD89BFE0CA3CC4C2FCE80A03D3576C222A792B72B1F070AB7F6B6F2B5CA2AF5054AFA70A896990159B45D1003E2A05648675E596016F1B71DD0F7BDA7E2097FC73B3A143D12C726020AC34958AD7062B92B9ABF3CA6BE5AE29F57135E625A367971837E6363D1532094E022A23467CF932E1F89B5B0803C1EC99B585A78B5865096746F32258214ECB38065C97F455E155ACC2DD005A9C76BED59CDA73837D303504E6C976A606A2BE7BBEC5948B91A349E8936688CC0279754B743ABC58666B19B6C3260051F19206BB962BB6633EB0048E32BAACC5B020D02C86CA9770AD469DB54A106AC73A35B8057422B3DB202C5A5B4E3D535F0FC99326C4B8B7B16F1CB5AF96803FA8C195FC0BCEDDAAF012A51728B76489082373C91E92C87ACCA795160782E3B0DD643544BB96ABC2708D49B759CF057AA223BAFD96A330BAF39810FE8671B4343C297DA1E1969C996216AB5106DA668941B160D4477017136CBCA5B5A8D44C4A8B1CF3EF79785E5AA25C3A1AD6C24FD140F79207DE5A499F8A1534FFA804AA7B3889CBE25C0414704AA57897F17862364ECA56258007248813912B836497F0359C2F7238A05D305A0EA152E72B44417A868134E91B3CA7931232FD4C25F8C2A492A339CDC0A138967211451F2562678FA14080A34436C42B07865AC036A81E97A7787A938025CAF813450368BED0C94B1857604526405D27A1C1ABC81B5B6EC13C71930A97D9232CF7021EF87A4D155328E62B583A83B4AF21F9F5750F8575150424F63B899D71CAD267C09E4467146E16E9B6C653F008C311375E2E006D4076A546B82F5314222F7C654317E79EC6035B73FAF491757E61C828326D53044541C4D4537ABD3EA1E67998C3382974CA78AE1B1960E4A9226B0219AB070F0D7AA66D76F9316ADB80C54D6499771B471E8168D47BCAA08324AB6BA92C3A70275F24FA4DC10E251633FB98D162BB5537202C6A553CE7841C4D40B873B85CA03A0A1E1CFADE6BA5180AB1323CCBA9A3E9C53D37575AB1FD9E7316C6FEECB0A14DF6F2DA56C2F56F55A89635CFCFDA47927AF1F0A47B2D4E4E61634B1B51D37A3A307A972420DE1B7A481B83E583B6AF16F63CB00C6"""), + xeh(""" +EDD3FAB8AEB1240FB31B836CD1603E1F904BD1F87318DCB02A7DE18B4044385CDB51E343787E583CB043EE23899658420F9DEDB23CAB2BCD1013F573C0C7978521596631F6590105CB7B281AB1591B7056BE068DF838E0B1679F3B88D95208EF4B3019625EEA7704CE79F33AF339AB883B0C48B3C4413921F43AF2515A85023B5D98D06E619238C8D033FB7DD19611CC60CF395A03B0681913B299531B13728B278D353FA093C633710B65000772DD6D7CA59C85DB62196DCCE1B75559ECD3FB42DDD8E57EB4CF3B4E35B57EA3D6063221B81F1B802DD7D76DE308CB0A738C3B5833E9F4427AF3C3D79B521E7E665B052B9A365DCDFE5A688B06EDCDFA2143C938F852E32D6B49808CFFD01A8655B767034F8C638E8AF94BF3EB9EA39AED1D2D22E181888DD608BF9392FD73822303A41996F41D51A924FA6EF76A9C82709A21BEF1DD004693EC9468B335F9BD1FD94D5E6D89D570FC6D23B7F5CAD2975F418B8C4A0EB82EA2A3C979B1C15B0FB0A23F844764DDD49A8B89C0D4BC8C311BB43725EE9BAACC4796F58C0F1180A4F6AFEF45178659B35A74FF34A8E93A64FA4CD003269EC67C5BD528E015B2311B5E2D33472638CD65FC7D5127335EDA862BDEA05F4290EF9B370BE69DC89E7D71DD2522E669700D5D02D8DCD75FE2AD9EDC307225D61C7805CE1EBBC806A08BD360F86FD27B599582B22C57DDE77B08F7537482FB5D75BDB9F3F4EA07DFB0711C25AD1950058EAAA2E17D8F676BE6B72B1687383D8E0DD60A8277F6FDA202D6F8957EE21308AE81ABF72A89924DB44238B262D2FCE733E12E5413C31FDEF94860D5BB0FB0AEDCB1EFA8F87CCC76189FA5D8157FB4FB14652DC188157B2B746B596FE6F2FEB197DE139B80922C2EC14B58E743E3335893ABF85B99BC4566FA1BEED449658C5993CD08BF78F7DBFF808F611D6EB8F0BD7977E854BC195D711C03EA532403547B6ABEAE827481BB5D53C867710215835260097B6CA730FC722A74E230434B08F38EB1ABAF555CD4CC6CB9310E32F93E0ACAC1E915A4B57E0774B013BE7DD435B5C6AF6018944349841F84E8C28260149F266C99FC05E0DB8D5A63DE362CDE45F5BDFB6F30D55A84ACA22E8640A1287DA51714F2C8D4B184A5F671E0E907134E34D875C9A4709ECE3B7FE15713A0DD972505298C18A9D35956149EC9AF45C475016D7C8B5CBFFE2108882B86FFD380A79892BA1909489E016CF9933705E2FA72ACC8569501553401C397648DC47948935C0197D6F162464DE42BA537611CCB67A988030ABF6081946FDD1ED8C6B23691EA160E8543735894839F13C270B3E1F68607A7EECE09AF06A34F4FC9096D4EFFE4905BE56F3EB397C13472F6621F3EE45A59C8001ABF9302E036BEDEB2E0EC92A03FFE0DF52262621728C6791C4E7D8C226D17A04B6E7EB2FF8586585D639B449C85224EEC67E30537ABE85C8F7E2306DB80E968D8585CED3A9E21622BBC38D43A7D79E2457C67307CC208064D3568C476ED79359CD0A4B0BECA02FA702661056E187A51C2D154638F9000DF856ABB82CFE12C47543E46FFDBADD2DC69EBB3FF444E7E1E95235541015E6CC7A0429C82EBD6942C6420AD598C08080DCEC800509C142ED5A642951F491E748B5436148B90ACCBEC35D0D85FAF4E472ED3F1A089113808D3ECDF77EEF3E089FA5A1635B90EF99034AAA49D4D13058EAA5A8797E37C59CEB86C7CCFE1F574E1086DB9BE744BDE5067AD5D6C450FADFF2338DB110736FBBD86B41B29C29D3899CE60E9BEDF775416541350AAA9BD9B5D57573C542375BB0297912863C86AAE39D153CCB29F1811CDE58978951CE8EEFA6F9D10121AD1FB89F02AF8E96AC08DD10E3274E8CA79D910667166797468D3D3BD6D7EF5F2C6FC4F110268A2716CB273F29BBC347050BD98BDD88F30A96E7A9E840A55087F42A09B03D04E612640BA4D86BE87DA6D20ED0ECCCA2523EE7C4E9D2A96E7378BF71308850832769417EB6250FC768B0EDF92FD45216A235435A3E32AE5B22BF913027D81B0D5508D2AF88120A50206DD7837B79C45B21DB4FE59D23F4AB051BF012B13F6EE5B34C83C8D8CC9BB35266D0EF3834F52CE6CC5BCB7C5989198465A9E9DEE1A1F262FAB26FE0D0964E624869DF2607858815418F85A1F503BE5217794CED29D02E19D40C4BC8E65C46FE3815C1E548976649D4332B1841EA03022""") + ), + new DecapsulateTestCase( + xeh(""" +8445C336F3518B298163DCBB6357597983CA2E873DCB49610CF52F14DBCB947C1F3EE9266967276B0C576CF7C30EE6B93DEA5118676CBEE1B1D4794206FB369ABA41167B4393855C84EBA8F32373C05BAE7631C802744AADB6C2DE41250C494315230B52826C34587CB21B183B49B2A5AC04921AC6BFAC1B24A4B37A93A4B168CCE7591BE6111F476260F2762959F5C1640118C2423772E2AD03DC7168A38C6DD39F5F7254264280C8BC10B914168070472FA880ACB8601A8A0837F25FE194687CD68B7DE2340F036DAD891D38D1B0CE9C2633355CF57B50B896036FCA260D2669F85BAC79714FDAFB41EF80B8C30264C31386AE60B05FAA542A26B41EB85F67068F088034FF67AA2E815AAB8BCA6BF71F70ECC3CBCBC45EF701FCD542BD21C7B09568F369C669F396473844FBA14957F51974D852B978014603A210C019036287008994F21255B25099AD82AA132438963B2C0A47CDF5F32BA46B76C7A6559F18BFD555B762E487B6AC992FE20E283CA0B3F6164496955995C3B28A57BBC29826F06FB38B253470AF631BC46C3A8F9CE824321985DD01C05F69B824F916633B40654C75AAEB9385576FFDE2990A6B0A3BE829D6D84E34F1780589C79204C63C798F55D23187E461D48C21E5C047E535B19F458BBA1345B9E41E0CB4A9C2D8C40B490A3BABC553B3026B1672D28CBC8B498A3A99579A832FEAE74610F0B6250CC333E9493EB1621ED34AA4AB175F2CA231152509ACB6AC86B20F6B39108439E5EC12D465A0FEF35003E14277A21812146B2544716D6AB82D1B0726C27A98D589EBDACC4C54BA77B2498F217E14E34E66025A2A143A992520A61C0672CC9CCED7C9450C683E90A3E4651DB623A6DB39AC26125B7FC1986D7B0493B8B72DE7707DC20BBDD43713156AF7D9430EF45399663C2202739168692DD657545B056D9C92385A7F414B34B90C7960D57B35BA7DDE7B81FCA0119D741B12780926018FE4C8030BF038E18B4FA33743D0D3C846417E9D5915C246315938B1E233614501D026959551258B233230D428B181B132F1D0B026067BA816999BC0CD6B547E548B63C9EAA091BAC493DC598DBC2B0E146A2591C2A8C009DD5170AAE027C541A1B5E66E45C65612984C46770493EC896EF25AA9305E9F06692CD0B2F06962E205BEBE113A34EBB1A4830A9B3749641BB935007B23B24BFE576956254D7A35AA496AC446C67A7FEC85A60057E8580617BCB3FAD15C76440FED54CC789394FEA24452CC6B0585B7EB0A88BBA9500D9800E6241AFEB523B55A96A535151D1049573206E59C7FEB070966823634F77D5F1291755A243119621AF8084AB7AC1E22A0568C6201417CBE3655D8A08DD5B513884C98D5A493FD49382EA41860F133CCD601E885966426A2B1F23D42D82E24582D99725192C21777467B1457B1DD429A0C41A5C3D704CEA06278C59941B438C62727097809B4530DBE837EA396B6D31077FAD3733053989A8442AAC4255CB163B8CA2F27501EA967305695ABD659AA02C83EE60BB574203E9937AE1C621C8ECB5CC1D21D556960B5B9161EA96FFFEBAC72E1B8A6154FC4D88B56C04741F090CBB156A737C9E6A22BA8AC704BC304F8E17E5EA845FDE59FBF788CCE0B97C8761F89A242F3052583C6844A632031C964A6C4A85A128A28619BA1BB3D1BEA4B49841FC847614A066841F52ED0EB8AE0B8B096E92B8195405815B231266F36B18C1A53333DAB95D2A9A374B5478A4A41FB8759957C9AB22CAE545AB544BA8DD05B83F3A613A2437ADB073A9635CB4BBC965FB454CF27B298A40CD0DA3B8F9CA99D8CB4286C5EB476416796070BA535AAA58CDB451CD6DB5CBB0CA20F0C71DE97C30DA97EC7906D06B4B939396028C46BA0E7A865BC8308A3810F1212006339F7BC169B1666FDF475911BBC8AAAB41755C9A8AABFA23C0E37F84FE46999E030494B9298EF9934E8A649C0A5CCE2B22F31809AFED23955D87881D99FC1D352896CAC9055BEA0D016CCBA7805A3A50E221630379BD01135221CAD5D9517C8CC42637B9FC0718E9A9BB4945C72D8D11D3D659D83A3C419509AF5B470DD89B7F3ACCF5F35CFC322115FD66A5CD2875651326F9B3168913BE5B9C87AE0B025EC7A2F4A072750946AC61170A7826D9704C5A23A1C0A2325146C3BC1858826C6B39279C2DA7438A370ED8A0AA5169E3BEC29ED88478732758D454143E227F8595883297842E6AF133B17E4811B0F5713AC73B7E347423EB92822D2306FA14500A7207A0672672046544ACC4EA9C16ED7421A069E0D737A98628519C6A29A424A868B46D9A0CC7C6C9DDD8B8BCBF422C8F48A73143D5ABB66BC55499418430802BAC544463CC7319D17998F29411365766D04C847F3129D9077B7D8339BFB96A6739C3F6B74A8F05F9138AB2FE37ACB57634D1820B50176F5A0B6BC2940F1D5938F1936B5F95828B92EB72973C1590AEB7A552CECA10B00C303B7C75D402071A79E2C810AF7C745E3336712492A42043F2903A37C6434CEE20B1D159B057699FF9C1D3BD68029839A08F43E6C1C819913532F911DD370C7021488E11CB504CB9C70570FFF35B4B4601191DC1AD9E6ADC5FA9618798D7CC860C87A939E4CCF8533632268CF1A51AFF0CB811C5545CB1656E65269477430699CCDEA3800630B78CD5810334CCF02E013F3B80244E70ACDB060BBE7A553B063456B2EA807473413165CE57DD563473CFBC90618ADE1F0B888AA48E722BB2751858FE19687442A48E7CA0D2A29CD51BFD8F78C17B9660BFB54A470B2AE9A955C6AB8D6E5CC92AC8ED3C185DAA8BC29F0578EBB812B97C9E5A848A6384DE4E75A31470B53066A8D027BA44B21749C0492465F9072B28376C4E290B30C1863F9E5B79996083422BD8C272C10ECC6EB9A0A8225B31AA0A66E35B9C0B9A79582BA20A3C04CD29914F083A0158288BA4D6EB62D87264B912BCA39732FBDE536A377AD02B8C835D4A2F4E7B1CE115D0C860BEAA7955A49AD689586A89A2B9F9B10D1595D2FC065AD018A7D56C614471F8E946FE8AB49E8226591119FCADB4F9A861631378736B6688B782D58E97E4572753A9664B6B8536812B25911AA76A242375433192738EEE762F6B84315BB3436231E0A9B277ED28AE0050728346457E13405062DB2804B8DA60BB5C793D4CC0E101CBA2D9182FD7124FF52BF4CA28292AC26D678088953971DBA0B6FEC2C9659353291C70C5B9245A0CA253304AFD3C95102BEA66875C6201680B4BDA38687B648C28EB37478E3BC00CA8A3CC27204642B42B68FCBE7B21A366D0668A5029A7DEEF94CDD6A95D7EA8931673BF7112D4042107B1B8B9700C974F9C4E83A8FACD89BFE0CA3CC4C2FCE80A03D3576C222A792B72B1F070AB7F6B6F2B5CA2AF5054AFA70A896990159B45D1003E2A05648675E596016F1B71DD0F7BDA7E2097FC73B3A143D12C726020AC34958AD7062B92B9ABF3CA6BE5AE29F57135E625A367971837E6363D1532094E022A23467CF932E1F89B5B0803C1EC99B585A78B5865096746F32258214ECB38065C97F455E155ACC2DD005A9C76BED59CDA73837D303504E6C976A606A2BE7BBEC5948B91A349E8936688CC0279754B743ABC58666B19B6C3260051F19206BB962BB6633EB0048E32BAACC5B020D02C86CA9770AD469DB54A106AC73A35B8057422B3DB202C5A5B4E3D535F0FC99326C4B8B7B16F1CB5AF96803FA8C195FC0BCEDDAAF012A51728B76489082373C91E92C87ACCA795160782E3B0DD643544BB96ABC2708D49B759CF057AA223BAFD96A330BAF39810FE8671B4343C297DA1E1969C996216AB5106DA668941B160D4477017136CBCA5B5A8D44C4A8B1CF3EF79785E5AA25C3A1AD6C24FD140F79207DE5A499F8A1534FFA804AA7B3889CBE25C0414704AA57897F17862364ECA56258007248813912B836497F0359C2F7238A05D305A0EA152E72B44417A868134E91B3CA7931232FD4C25F8C2A492A339CDC0A138967211451F2562678FA14080A34436C42B07865AC036A81E97A7787A938025CAF813450368BED0C94B1857604526405D27A1C1ABC81B5B6EC13C71930A97D9232CF7021EF87A4D155328E62B583A83B4AF21F9F5750F8575150424F63B899D71CAD267C09E4467146E16E9B6C653F008C311375E2E006D4076A546B82F5314222F7C654317E79EC6035B73FAF491757E61C828326D53044541C4D4537ABD3EA1E67998C3382974CA78AE1B1960E4A9226B0219AB070F0D7AA66D76F9316ADB80C54D6499771B471E8168D47BCAA08324AB6BA92C3A70275F24FA4DC10E251633FB98D162BB5537202C6A553CE7841C4D40B873B85CA03A0A1E1CFADE6BA5180AB1323CCBA9A3E9C53D37575AB1FD9E7316C6FEECB0A14DF6F2DA56C2F56F55A89635CFCFDA47927AF1F0A47B2D4E4E61634B1B51D37A3A307A972420DE1B7A481B83E583B6AF16F63CB00C6"""), + xeh(""" +C72FA15560FEE6B014E73F5F93C307F74EF9C49AA8F7DF578C002AF20419040D6AB6AC46F78FB03F56A9C5C95902D8CBCE34D79853EDF0C319AF5469E32D0B9FC3C41628970E0B3A6C408B509C74DFA218BD23FA7A11DEA2D2277B3522BEF6606E3415D0DD51556440CC1AF59CAE6F23368BCAC3E1509503368354D1E3EC9E91F8B2D377DCC323D578DEB222585E43F97A6D1855B576297F3EC39F5F9EA1B2F72A0E701DB35D633DBCC5FFF76A2D39AE9DF2A3F6326B7671A4C0BB7177897DFF4FAF9FE5CFBCC94966BD298EA2627CF19C1CA866E5927C6E41970F544479D9A6D814AB72E2963F959CBEF37BF905BE98D8C8F3C25FAD3983F71D0C0D27D9FF17E4B34C2F8664406151E92ECA980F6CBE8F8926638398C9BCE9C69A92A30CE82F28CB4FE4110EAC40437BD64D38412030FB8DB3A4242672807737E707E59A0ACFA782127EFCB7BCEC39DFEC55C3109F958E86E0D381C4E9E9FE43110517778C08A140CF440F209011768EE34E5742ECC1E4CED045922D698A29E5557A29C237885D8559F110E4B540FE1298B97920EDF59BC8EBCA11EB91F471B6647864B384AE5A6BB494942BB1F537301B39EDD6F664E4A7877C173614B09D981401D5AA98A8BA4BF1992DD7B7A65BCE7E87FCDFC7B29AB69ADDC9036D71BB9BC08F4E7D9A57B784911CEE7D0EE5A559332981B6475290FB4410D8BA1F00FFC4850031708EB6A83AF524447F491CC25F23FBED71476FBA5C64BCD50D88A3ACD2BE1DF461B11F6D537B2929D073FCFB9E2545E1B097A12F52C411B2AF6C20A27ECD1C084568F4A76A87A4A79F7711012CBEDA777D913CC6B15E6C4E9BCE2C773991946CB9CEFB7F105B15FD2CD3E721E6C1DF69B66BEDF2157ACAD45458FD8C9C1AF910394A13C300696BBBB5B1E1145076BC6B9E3D30A680EA29B6370618B47AF77108EDE6BFCEBFBCFEDDD27FD9F0DA6D289060095C4E309DC3D26DCBFB9E8AF34E12BDD335FAC434663D4D802C8B04AC884352D27739C4DF22F3D7DB38084BAE2C0A15485DF4E356DF2FFBB5BBACA78D0B4886909C4482A6366991776B788C0941437BF858DD83AAA50104D725171C09B7DB521AA65CCCA3CDAFB2E61CDEF66B55D80E201DF44654E7B1FFCA29EFC1E44A8CBA406C8DAC6207C0BD5DA964FBE137ACCD84405A94F5F51D82CE701DD16774BA5F0A7A2BED7F9BB9A4F25C3095D1F8980721A7ECBCE957825A9BE9F4F818E56D35909A3F9DE5487DA0011EBCF9F4D768B72D236042175ED599D731AAFCD45D3D837FB8B64304ED7F22A8C3949BFA25B83A8C05FE9748F63A38201B460E16FFE4329C8464C9BF07D45DF2BA9AE7A84DCFC4CAB7BE42CBD360F61051CD56F68A71FE9E78231986832C9564D02B973EA2D3FCDBAEC374612C1B74DD483F08BAC30F6C9306E7092CC8FE1D20B937AFA4BC605ED4398A8B81A470870E97EA7D51562111D04BF9D09D9BC07533FCDA1E8DA2F2823AD621DB169C99FB112E44FDEFD597B61160815A1776139B685DA9DF6B4C22F6FF6CA3CC46B3264E456E98FF1F301122C88D42928403ED0E0E5F49BB0B450429980ACEFA1A80DA26638B5D2310FCADB0836223CB0894E6FA014D351AE052A70AB5F515641F153509FFB90B8DE495B946AB8C7D7CFEF56D3C66DC871F1D3A38494EF6AB82066E96B9F2782D6B5931B78B7117C389D155759CBC1690897DA66E50D0865209887552C8A6035B8F6911760F8D0A450FB926096721D962877FBFD87D92C37C71836B8BB9FCE92B4637785DC8E8C1D379081C14C73872E676A1C854F1BB68649BD552B48D12F62B17E9A48CCAF63885899C7B781DC3A6D7DE7DA28E286C9FD644D3521F0320B7ECA8FD0AAFFFFF90DAEC85BA80868A2EC69CC73AE00AE29FF5BA37D94510CA19E1EDAA64F30CD79A58B42FC9A6402CE31AF54BAE84DFED8D0C76142A347542265B794A0AEF4A08B4B5DFCADBD56757ECD98F175D80B44121257964293F300FF750107C1B72463D4634EBEDF4705F76C908844763D0D6813FFBE5411FBBFE16C08F32BD1BB3FB8EA5C5339A1B0194DA543E64C1F8065CE526D2754EF95A287DDC97B790FF34EA37863BB166BF0BD99E3A961BC91C1A4F84B63700C9EF5D8D31CEC9E1AE33C554BE638D5C1217CD2DBA13CC143F969DCBF285407A9B608F859812E7F668D4538BE179D11ED767A6971A2AA9CBB545EA01998E""") + ) + }; +} From 21e0fb8648d61f041a04d44ad6c46fc5efd86261 Mon Sep 17 00:00:00 2001 From: Chris Plummer <cjplummer@openjdk.org> Date: Fri, 22 Nov 2024 17:26:37 +0000 Subject: [PATCH 188/311] 8343529: serviceability/sa/ClhsdbWhere.java fails AssertionFailure: Corrupted constant pool 8307318: Test serviceability/sa/ClhsdbCDSJstackPrintAll.java failed: ArrayIndexOutOfBoundsException Reviewed-by: kevinw, amenkov --- .../sa/ClhsdbCDSJstackPrintAll.java | 6 ++++- .../serviceability/sa/ClhsdbLauncher.java | 22 +++++++++++++------ .../jtreg/serviceability/sa/ClhsdbWhere.java | 6 ++++- 3 files changed, 25 insertions(+), 9 deletions(-) diff --git a/test/hotspot/jtreg/serviceability/sa/ClhsdbCDSJstackPrintAll.java b/test/hotspot/jtreg/serviceability/sa/ClhsdbCDSJstackPrintAll.java index 3fe60de2364..4d01f9a26c8 100644 --- a/test/hotspot/jtreg/serviceability/sa/ClhsdbCDSJstackPrintAll.java +++ b/test/hotspot/jtreg/serviceability/sa/ClhsdbCDSJstackPrintAll.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -51,6 +51,10 @@ public static void main(String[] args) throws Exception { CDSTestUtils.createArchiveAndCheck(opts); ClhsdbLauncher test = new ClhsdbLauncher(); + // This test could possibly cause some unexpected SA exceptions because one + // or more threads are active during the stack trace. Ignore them. The threads + // we care about should still be present in the output. + test.ignoreExceptions(); theApp = LingeredApp.startApp( "-XX:+UnlockDiagnosticVMOptions", "-XX:SharedArchiveFile=" + sharedArchiveName, diff --git a/test/hotspot/jtreg/serviceability/sa/ClhsdbLauncher.java b/test/hotspot/jtreg/serviceability/sa/ClhsdbLauncher.java index 849ec2eb109..8ac67c366cd 100644 --- a/test/hotspot/jtreg/serviceability/sa/ClhsdbLauncher.java +++ b/test/hotspot/jtreg/serviceability/sa/ClhsdbLauncher.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -41,9 +41,15 @@ public class ClhsdbLauncher { private Process toolProcess; + private boolean ignoreExceptions; public ClhsdbLauncher() { toolProcess = null; + ignoreExceptions = false; + } + + public void ignoreExceptions() { + ignoreExceptions = true; } /** @@ -147,12 +153,14 @@ private String runCmd(List<String> commands, // -Xcheck:jni might be set via TEST_VM_OPTS. Make sure there are no warnings. oa.shouldNotMatch("^WARNING: JNI local refs:.*$"); oa.shouldNotMatch("^WARNING in native method:.*$"); - // This will detect most SA failures, including during the attach. - oa.shouldNotMatch("^sun.jvm.hotspot.debugger.DebuggerException:.*$"); - oa.shouldNotMatch("sun.jvm.hotspot.utilities.AssertionFailure"); - // This will detect unexpected exceptions, like NPEs and asserts, that are caught - // by sun.jvm.hotspot.CommandProcessor. - oa.shouldNotMatch("^Error: .*$"); + if (!ignoreExceptions) { + // This will detect most SA failures, including during the attach. + oa.shouldNotMatch("^sun.jvm.hotspot.debugger.DebuggerException:.*$"); + oa.shouldNotMatch("sun.jvm.hotspot.utilities.AssertionFailure"); + // This will detect unexpected exceptions, like NPEs and asserts, that are caught + // by sun.jvm.hotspot.CommandProcessor. + oa.shouldNotMatch("^Error: .*$"); + } String[] parts = output.split("hsdb>"); for (String cmd : commands) { diff --git a/test/hotspot/jtreg/serviceability/sa/ClhsdbWhere.java b/test/hotspot/jtreg/serviceability/sa/ClhsdbWhere.java index f3dab6dd976..547034463d7 100644 --- a/test/hotspot/jtreg/serviceability/sa/ClhsdbWhere.java +++ b/test/hotspot/jtreg/serviceability/sa/ClhsdbWhere.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -45,6 +45,10 @@ public static void main(String[] args) throws Exception { LingeredApp theApp = null; try { ClhsdbLauncher test = new ClhsdbLauncher(); + // This test could possibly cause some unexpected SA exceptions because one + // or more threads are active during the stack trace. Ignore them. The threads + // we care about should still be present in the output. + test.ignoreExceptions(); theApp = LingeredApp.startApp(); System.out.println("Started LingeredApp with pid " + theApp.getPid()); From 8b98f958dc1afedc02b9d9c98089d6cb1ca3a5b7 Mon Sep 17 00:00:00 2001 From: Ben Perez <bperez@openjdk.org> Date: Fri, 22 Nov 2024 17:48:08 +0000 Subject: [PATCH 189/311] 8298387: Implement JEP 497: Quantum-Resistant Module-Lattice-Based Digital Signature Algorithm Reviewed-by: jnimeh --- .../security/spec/NamedParameterSpec.java | 18 +- .../classes/sun/security/provider/ML_DSA.java | 1252 +++++++++++++++++ .../sun/security/provider/ML_DSA_Impls.java | 212 +++ .../sun/security/provider/SunEntries.java | 20 +- .../classes/sun/security/util/KnownOIDs.java | 5 +- .../internalProjection.json | 555 ++++++++ .../internalProjection.json | 507 +++++++ .../internalProjection.json | 396 ++++++ .../security/provider/all/Deterministic.java | 3 +- .../openjdk/bench/java/security/MLDSA.java | 833 +++++++++++ 10 files changed, 3789 insertions(+), 12 deletions(-) create mode 100644 src/java.base/share/classes/sun/security/provider/ML_DSA.java create mode 100644 src/java.base/share/classes/sun/security/provider/ML_DSA_Impls.java create mode 100644 test/jdk/sun/security/provider/acvp/data/ML-DSA-keyGen-FIPS204/internalProjection.json create mode 100644 test/jdk/sun/security/provider/acvp/data/ML-DSA-sigGen-FIPS204/internalProjection.json create mode 100644 test/jdk/sun/security/provider/acvp/data/ML-DSA-sigVer-FIPS204/internalProjection.json create mode 100644 test/micro/org/openjdk/bench/java/security/MLDSA.java diff --git a/src/java.base/share/classes/java/security/spec/NamedParameterSpec.java b/src/java.base/share/classes/java/security/spec/NamedParameterSpec.java index 1e36fe3befe..48a177f8c1c 100644 --- a/src/java.base/share/classes/java/security/spec/NamedParameterSpec.java +++ b/src/java.base/share/classes/java/security/spec/NamedParameterSpec.java @@ -69,28 +69,28 @@ public class NamedParameterSpec implements AlgorithmParameterSpec { = new NamedParameterSpec("Ed448"); /** - * The ML-KEM-512 parameters + * The ML-DSA-44 parameters * * @since 24 */ - public static final NamedParameterSpec ML_KEM_512 - = new NamedParameterSpec("ML-KEM-512"); + public static final NamedParameterSpec ML_DSA_44 + = new NamedParameterSpec("ML-DSA-44"); /** - * The ML-KEM-768 parameters + * The ML-DSA-65 parameters * * @since 24 */ - public static final NamedParameterSpec ML_KEM_768 - = new NamedParameterSpec("ML-KEM-768"); + public static final NamedParameterSpec ML_DSA_65 + = new NamedParameterSpec("ML-DSA-65"); /** - * The ML-KEM-1024 parameters + * The ML-DSA-87 parameters * * @since 24 */ - public static final NamedParameterSpec ML_KEM_1024 - = new NamedParameterSpec("ML-KEM-1024"); + public static final NamedParameterSpec ML_DSA_87 + = new NamedParameterSpec("ML-DSA-87"); private final String name; diff --git a/src/java.base/share/classes/sun/security/provider/ML_DSA.java b/src/java.base/share/classes/sun/security/provider/ML_DSA.java new file mode 100644 index 00000000000..33ce8d5f52d --- /dev/null +++ b/src/java.base/share/classes/sun/security/provider/ML_DSA.java @@ -0,0 +1,1252 @@ +/* + * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package sun.security.provider; + +import jdk.internal.vm.annotation.IntrinsicCandidate; +import sun.security.provider.SHA3.SHAKE128; +import sun.security.provider.SHA3.SHAKE256; + +import java.security.MessageDigest; +import java.security.InvalidKeyException; +import java.security.SignatureException; +import java.util.Arrays; + +public class ML_DSA { + // Security level constants + static final int ML_DSA_44 = 2; + static final int ML_DSA_65 = 3; + static final int ML_DSA_87 = 5; + + // Constants from FIPS 204 that do not depend on security level + private static final int ML_DSA_D = 13; + private static final int ML_DSA_Q = 8380417; + private static final int ML_DSA_N = 256; + private static final int SHAKE256_BLOCK_SIZE = 136; // the block length for SHAKE256 + + private final int A_SEED_LEN = 32; + private final int S1S2_SEED_LEN = 64; + private final int K_LEN = 32; + private final int TR_LEN = 64; + private final int MU_LEN = 64; + private final int MASK_SEED_LEN = 64; + private static final int D_MASK = (1 << ML_DSA_D) - 1; + private final int T0_COEFF_SIZE = 13; + + private static final int MONT_R_BITS = 32; + private static final long MONT_R = 4294967296L; // 1 << MONT_R_BITS + private static final int MONT_Q = 8380417; + private static final int MONT_R_SQUARE_MOD_Q = 2365951; + private static final int MONT_Q_INV_MOD_R = 58728449; + private static final int MONT_R_MOD_Q = 4193792; + // toMont((ML_DSA_N)^-1 (mod ML_DSA_Q)) + private static final int MONT_DIM_INVERSE = 16382; + + // Zeta values for NTT with montgomery factor precomputed + private static final int[] MONT_ZETAS_FOR_NTT = new int[]{ + 25847, -2608894, -518909, 237124, -777960, -876248, 466468, 1826347, + 2353451, -359251, -2091905, 3119733, -2884855, 3111497, 2680103, 2725464, + 1024112, -1079900, 3585928, -549488, -1119584, 2619752, -2108549, -2118186, + -3859737, -1399561, -3277672, 1757237, -19422, 4010497, 280005, 2706023, + 95776, 3077325, 3530437, -1661693, -3592148, -2537516, 3915439, -3861115, + -3043716, 3574422, -2867647, 3539968, -300467, 2348700, -539299, -1699267, + -1643818, 3505694, -3821735, 3507263, -2140649, -1600420, 3699596, 811944, + 531354, 954230, 3881043, 3900724, -2556880, 2071892, -2797779, -3930395, + -1528703, -3677745, -3041255, -1452451, 3475950, 2176455, -1585221, -1257611, + 1939314, -4083598, -1000202, -3190144, -3157330, -3632928, 126922, 3412210, + -983419, 2147896, 2715295, -2967645, -3693493, -411027, -2477047, -671102, + -1228525, -22981, -1308169, -381987, 1349076, 1852771, -1430430, -3343383, + 264944, 508951, 3097992, 44288, -1100098, 904516, 3958618, -3724342, + -8578, 1653064, -3249728, 2389356, -210977, 759969, -1316856, 189548, + -3553272, 3159746, -1851402, -2409325, -177440, 1315589, 1341330, 1285669, + -1584928, -812732, -1439742, -3019102, -3881060, -3628969, 3839961, 2091667, + 3407706, 2316500, 3817976, -3342478, 2244091, -2446433, -3562462, 266997, + 2434439, -1235728, 3513181, -3520352, -3759364, -1197226, -3193378, 900702, + 1859098, 909542, 819034, 495491, -1613174, -43260, -522500, -655327, + -3122442, 2031748, 3207046, -3556995, -525098, -768622, -3595838, 342297, + 286988, -2437823, 4108315, 3437287, -3342277, 1735879, 203044, 2842341, + 2691481, -2590150, 1265009, 4055324, 1247620, 2486353, 1595974, -3767016, + 1250494, 2635921, -3548272, -2994039, 1869119, 1903435, -1050970, -1333058, + 1237275, -3318210, -1430225, -451100, 1312455, 3306115, -1962642, -1279661, + 1917081, -2546312, -1374803, 1500165, 777191, 2235880, 3406031, -542412, + -2831860, -1671176, -1846953, -2584293, -3724270, 594136, -3776993, -2013608, + 2432395, 2454455, -164721, 1957272, 3369112, 185531, -1207385, -3183426, + 162844, 1616392, 3014001, 810149, 1652634, -3694233, -1799107, -3038916, + 3523897, 3866901, 269760, 2213111, -975884, 1717735, 472078, -426683, + 1723600, -1803090, 1910376, -1667432, -1104333, -260646, -3833893, -2939036, + -2235985, -420899, -2286327, 183443, -976891, 1612842, -3545687, -554416, + 3919660, -48306, -1362209, 3937738, 1400424, -846154, 1976782 + }; + private static final int[] MONT_ZETAS_FOR_INVERSE_NTT = new int[]{ + -1976782, 846154, -1400424, -3937738, 1362209, 48306, -3919660, 554416, + 3545687, -1612842, 976891, -183443, 2286327, 420899, 2235985, 2939036, + 3833893, 260646, 1104333, 1667432, -1910376, 1803090, -1723600, 426683, + -472078, -1717735, 975884, -2213111, -269760, -3866901, -3523897, 3038916, + 1799107, 3694233, -1652634, -810149, -3014001, -1616392, -162844, 3183426, + 1207385, -185531, -3369112, -1957272, 164721, -2454455, -2432395, 2013608, + 3776993, -594136, 3724270, 2584293, 1846953, 1671176, 2831860, 542412, + -3406031, -2235880, -777191, -1500165, 1374803, 2546312, -1917081, 1279661, + 1962642, -3306115, -1312455, 451100, 1430225, 3318210, -1237275, 1333058, + 1050970, -1903435, -1869119, 2994039, 3548272, -2635921, -1250494, 3767016, + -1595974, -2486353, -1247620, -4055324, -1265009, 2590150, -2691481, -2842341, + -203044, -1735879, 3342277, -3437287, -4108315, 2437823, -286988, -342297, + 3595838, 768622, 525098, 3556995, -3207046, -2031748, 3122442, 655327, + 522500, 43260, 1613174, -495491, -819034, -909542, -1859098, -900702, + 3193378, 1197226, 3759364, 3520352, -3513181, 1235728, -2434439, -266997, + 3562462, 2446433, -2244091, 3342478, -3817976, -2316500, -3407706, -2091667, + -3839961, 3628969, 3881060, 3019102, 1439742, 812732, 1584928, -1285669, + -1341330, -1315589, 177440, 2409325, 1851402, -3159746, 3553272, -189548, + 1316856, -759969, 210977, -2389356, 3249728, -1653064, 8578, 3724342, + -3958618, -904516, 1100098, -44288, -3097992, -508951, -264944, 3343383, + 1430430, -1852771, -1349076, 381987, 1308169, 22981, 1228525, 671102, + 2477047, 411027, 3693493, 2967645, -2715295, -2147896, 983419, -3412210, + -126922, 3632928, 3157330, 3190144, 1000202, 4083598, -1939314, 1257611, + 1585221, -2176455, -3475950, 1452451, 3041255, 3677745, 1528703, 3930395, + 2797779, -2071892, 2556880, -3900724, -3881043, -954230, -531354, -811944, + -3699596, 1600420, 2140649, -3507263, 3821735, -3505694, 1643818, 1699267, + 539299, -2348700, 300467, -3539968, 2867647, -3574422, 3043716, 3861115, + -3915439, 2537516, 3592148, 1661693, -3530437, -3077325, -95776, -2706023, + -280005, -4010497, 19422, -1757237, 3277672, 1399561, 3859737, 2118186, + 2108549, -2619752, 1119584, 549488, -3585928, 1079900, -1024112, -2725464, + -2680103, -3111497, 2884855, -3119733, 2091905, 359251, -2353451, -1826347, + -466468, 876248, 777960, -237124, 518909, 2608894, -25847 + }; + + // Constants defined for each security level + private final int level; + private final int tau; + private final int lambda; + private final int gamma1; + private final int gamma2; + private final int mlDsa_k; + private final int mlDsa_l; + private final int eta; + private final int beta; + private final int omega; + + // Second-class constants derived from above values + // log_2(gamma1) + private final int gamma1Bits; + // mlDsa_l * (eta + 1) * 256 / 8 + private final int s1PackedLength; + // mlDsa_k * (eta + 1) * 256 / 8 + private final int s2PackedLength; + // mlDsa_k * ML_DSA_D * 256 / 8 + private final int t0PackedLength; + // log_2(eta) + 1 + private final int s1s2CoeffSize; + // rho_size + t1_size + private final int publicKeyLength; + // c_tilde_size + z_size + h_size + private final int signatureLength; + // mlDsa_k * log_2((q-1)/(2*gamma2) - 1) * 256 / 8 + private final int wCoeffSize; + + public ML_DSA(int security_level) { + switch (security_level) { + case ML_DSA_44: + level = 2; + tau = 39; + lambda = 128; + gamma1 = 1 << 17; + gamma1Bits = 17; + gamma2 = (ML_DSA_Q - 1) / 88; + mlDsa_k = 4; + mlDsa_l = 4; + eta = 2; + beta = 78; + omega = 80; + publicKeyLength = 1312; + signatureLength = 2420; + s1PackedLength = 384; + s2PackedLength = 384; + t0PackedLength = 1664; + s1s2CoeffSize = 3; + wCoeffSize = 6; + break; + case ML_DSA_65: + level = 3; + tau = 49; + lambda = 192; + gamma1 = 1 << 19; + gamma2 = (ML_DSA_Q - 1) / 32; + mlDsa_k = 6; + mlDsa_l = 5; + eta = 4; + beta = 196; + omega = 55; + publicKeyLength = 1952; + signatureLength = 3293; + s1PackedLength = 640; + s2PackedLength = 768; + t0PackedLength = 2496; + s1s2CoeffSize = 4; + wCoeffSize = 4; + gamma1Bits = 19; + break; + case ML_DSA_87: + level = 4; + tau = 60; + lambda = 256; + gamma1 = 1 << 19; + gamma1Bits = 19; + gamma2 = (ML_DSA_Q - 1) / 32; + mlDsa_k = 8; + mlDsa_l = 7; + eta = 2; + beta = 120; + omega = 75; + publicKeyLength = 2592; + signatureLength = 4595; + s1PackedLength = 672; + s2PackedLength = 768; + t0PackedLength = 3328; + s1s2CoeffSize = 3; + wCoeffSize = 4; + break; + default: + throw new IllegalArgumentException("Wrong security level"); + } + } + + public record ML_DSA_PrivateKey(byte[] rho, byte[] k, byte[] tr, + int[][] s1, int[][] s2, int[][] t0) { + void destroy() { + Arrays.fill(k, (byte)0); + for (var b : s1) { + Arrays.fill(b, (byte) 0); + } + for (var b : s2) { + Arrays.fill(b, (byte) 0); + } + for (var b : t0) { + Arrays.fill(b, (byte) 0); + } + } + } + + public record ML_DSA_PublicKey(byte[] rho, int[][] t1) { + } + + public record ML_DSA_KeyPair(ML_DSA_PrivateKey privateKey, + ML_DSA_PublicKey publicKey) { + } + + public record ML_DSA_Signature(byte[] commitmentHash, + int[][] response, boolean[][] hint) { + } + + /* + Key validity checks + */ + public Object checkPublicKey(byte[] pk) throws InvalidKeyException { + int pk_size = 32 + (mlDsa_k * 32 * (23 - ML_DSA_D)); + if (pk.length != pk_size) { + throw new InvalidKeyException("Incorrect public key size"); + } + return null; + } + + public Object checkPrivateKey(byte[] sk) throws InvalidKeyException { + int eta_bits = eta == 4 ? 4 : 3; + + //SK size is 128 + 32 * ((l + k) * bitlen(2*eta) + d*k) + int sk_size = 128 + 32 * ((mlDsa_l + mlDsa_k) * eta_bits + ML_DSA_D * mlDsa_k); + if (sk.length != sk_size) { + throw new InvalidKeyException("Incorrect private key size"); + } + return null; + } + + //Internal functions in Section 6 of specification + public ML_DSA_KeyPair generateKeyPairInternal(byte[] randomBytes) { + //Initialize hash functions + var hash = new SHAKE256(0); + var crHash = new SHAKE256(TR_LEN); + + //Expand seed + hash.update(randomBytes); + hash.update((byte)mlDsa_k); + hash.update((byte)mlDsa_l); + byte[] rho = hash.squeeze(A_SEED_LEN); + byte[] rhoPrime = hash.squeeze(S1S2_SEED_LEN); + byte[] k = hash.squeeze(K_LEN); + hash.reset(); + + //Sample A + int[][][] keygenA = generateA(rho); //A is in NTT domain + + //Sample S1 and S2 + int[][] s1 = new int[mlDsa_l][ML_DSA_N]; + int[][] s2 = new int[mlDsa_k][ML_DSA_N]; + //hash is reset before being used in sampleS1S2 + sampleS1S2(s1, s2, hash, rhoPrime); + + //Compute t and tr + mlDsaVectorNtt(s1); //s1 now in NTT domain + int[][] As1 = new int[mlDsa_k][ML_DSA_N]; + matrixVectorPointwiseMultiply(As1, keygenA, s1); + mlDsaVectorInverseNtt(s1); //take s1 out of NTT domain + + mlDsaVectorInverseNtt(As1); + int[][] t = vectorAddPos(As1, s2); + int[][] t0 = new int[mlDsa_k][ML_DSA_N]; + int[][] t1 = new int[mlDsa_k][ML_DSA_N]; + power2Round(t, t0, t1); + + //Encode PK and SK + ML_DSA_PublicKey pk = new ML_DSA_PublicKey(rho, t1); + byte[] publicKeyBytes = pkEncode(pk); + crHash.update(publicKeyBytes); + byte[] tr = crHash.digest(); + ML_DSA_PrivateKey sk = new ML_DSA_PrivateKey(rho, k, tr, s1, s2, t0); + + return new ML_DSA_KeyPair(sk, pk); + } + + public ML_DSA_Signature signInternal(byte[] message, byte[] rnd, byte[] skBytes) { + //Decode private key and initialize hash function + ML_DSA_PrivateKey sk = skDecode(skBytes); + var hash = new SHAKE256(0); + + //Do some NTTs + mlDsaVectorNtt(sk.s1()); + mlDsaVectorNtt(sk.s2()); + mlDsaVectorNtt(sk.t0()); + int[][][] aHat = generateA(sk.rho()); + + //Compute mu + hash.update(sk.tr()); + hash.update(message); + byte[] mu = hash.squeeze(MU_LEN); + hash.reset(); + + //Compute rho' + hash.update(sk.k()); + hash.update(rnd); + hash.update(mu); + byte[] rhoDoublePrime = hash.squeeze(MASK_SEED_LEN); + hash.reset(); + + //Initialize vectors used in loop + int[][] z = new int[mlDsa_l][ML_DSA_N]; + boolean[][] h = new boolean[mlDsa_k][ML_DSA_N]; + byte[] commitmentHash = new byte[lambda/4]; + int[][] y = new int[mlDsa_l][ML_DSA_N]; + int[][] yy = new int[mlDsa_l][ML_DSA_N]; + int[][] w = new int[mlDsa_k][ML_DSA_N]; + int[][] w0 = new int[mlDsa_k][ML_DSA_N]; + int[][] w1 = new int[mlDsa_k][ML_DSA_N]; + int[][] w_ct0 = new int[mlDsa_k][ML_DSA_N]; + int[] c = new int[ML_DSA_N]; + int[][] cs1 = new int[mlDsa_l][ML_DSA_N]; + int[][] cs2 = new int[mlDsa_k][ML_DSA_N]; + int[][] ct0 = new int[mlDsa_k][ML_DSA_N]; + + int kappa = 0; + while (true) { + expandMask(y, rhoDoublePrime, kappa); + + //Save non-ntt version of y for later use + for (int i = 0; i < y.length; i++) { + System.arraycopy(y[i], 0, yy[i], 0, ML_DSA_N); + } + + //Compute w and w1 + mlDsaVectorNtt(y); //y is now in NTT domain + matrixVectorPointwiseMultiply(w, aHat, y); + mlDsaVectorInverseNtt(w); //w is now in normal domain + decompose(w, w0, w1); + //mlDsaVectorInverseNtt(y); + + //Get commitment hash + hash.update(mu); + hash.update(simpleBitPack(wCoeffSize, w1)); + commitmentHash = hash.squeeze(lambda/4); + hash.reset(); + + //Get z and r0 + sampleInBall(c, commitmentHash); + mlDsaNtt(c); //c is now in NTT domain + nttConstMultiply(cs1, c, sk.s1()); + nttConstMultiply(cs2, c, sk.s2()); + mlDsaVectorInverseNtt(cs1); + mlDsaVectorInverseNtt(cs2); + z = vectorAdd(z, yy, cs1); + + //w0 = w0 - cs2 (this is r0 in the spec) + vectorSub(w0, cs2, false); + + //Update z and h + kappa += mlDsa_l; + if (vectorNormBound(z, gamma1 - beta) || + vectorNormBound(w0, gamma2 - beta)) { + continue; + } else { + nttConstMultiply(ct0, c, sk.t0()); + mlDsaVectorInverseNtt(ct0); + w = vectorSub(w, cs2, false); + int hint_weight = makeHint(h, w, vectorAdd(w_ct0, w, ct0)); + if (vectorNormBound(ct0, gamma2) || (hint_weight > omega)) { + continue; + } + } + sk.destroy(); + return new ML_DSA_Signature(commitmentHash, z, h); + } + } + + public boolean verifyInternal(byte[] pkBytes, byte[] message, byte[] sigBytes) + throws SignatureException { + //Decode sig and initialize hash + ML_DSA_Signature sig = sigDecode(sigBytes); + var hash = new SHAKE256(0); + + //Decode pk + ML_DSA_PublicKey pk = pkDecode(pkBytes); + + //Expand A + int[][][] aHat = generateA(pk.rho()); + + //Generate tr + hash.update(pkBytes); + byte[] tr = hash.squeeze(TR_LEN); + hash.reset(); + + //Generate mu + hash.update(tr); + hash.update(message); + byte[] mu = hash.squeeze(MU_LEN); + hash.reset(); + + //Get verifiers challenge + int[] cHat = new int[ML_DSA_N]; + sampleInBall(cHat, sig.commitmentHash()); + mlDsaNtt(cHat); + + //Compute response norm and put it in NTT domain + boolean zNorm = vectorNormBound(sig.response(), gamma1 - beta); + mlDsaVectorNtt(sig.response()); + + //Reconstruct signer's commitment + int[][] aHatZ = new int[mlDsa_k][ML_DSA_N]; + matrixVectorPointwiseMultiply(aHatZ, aHat, sig.response()); + + int[][] t1Hat = vectorConstMul(1 << ML_DSA_D, pk.t1()); + mlDsaVectorNtt(t1Hat); + + int[][] ct1 = new int[mlDsa_k][ML_DSA_N]; + nttConstMultiply(ct1, cHat, t1Hat); + + int[][] wApprox = vectorSub(aHatZ, ct1, true); + mlDsaVectorInverseNtt(wApprox); + int[][] w1Prime = useHint(sig.hint(), wApprox); + + //Hash signer's commitment + hash.update(mu); + hash.update(simpleBitPack(wCoeffSize, w1Prime)); + byte[] cTildePrime = hash.squeeze(lambda/4); + + //Check verify conditions + boolean hashEq = MessageDigest.isEqual(sig.commitmentHash(), cTildePrime); + return !zNorm && hashEq; + } + + /* + Data conversion functions in Section 7.1 of specification + */ + + // Bit-pack the t1 and w1 vector into a byte array. + // The coefficients of the polynomials in the vector should be + // nonnegative and less than 2^bitsPerCoeff . + public byte[] simpleBitPack(int bitsPerCoeff, int[][] vector) { + byte[] result = new byte[(mlDsa_k * ML_DSA_N * bitsPerCoeff) / 8]; + int acc = 0; + int shift = 0; + int i = 0; + for (int[] poly : vector) { + for (int m = 0; m < ML_DSA_N; m++) { + acc += (poly[m] << shift); + shift += bitsPerCoeff; + while (shift >= 8) { + result[i++] = (byte) acc; + acc >>= 8; + shift -= 8; + } + } + } // Shift must now be 0 so we have all output bits + return result; + } + + public void bitPack(int[][] vector, int bitsPerCoeff, int maxValue, + byte[] output, int offset) { + int vecLen = vector.length; + int acc = 0; + int shift = 0; + for (int[] poly : vector) { + for (int m = 0; m < ML_DSA_N; m++) { + acc += (maxValue - poly[m]) << shift; + shift += bitsPerCoeff; + while (shift >= 8) { + output[offset++] = (byte) acc; + acc >>= 8; + shift -= 8; + } + } + } + } + + //This is simpleBitUnpack from FIPS 204. Since it is only called on the + //vector t1 we can optimize for that case + public int[][] t1Unpack(byte[] v) { + int[][] t1 = new int[mlDsa_k][ML_DSA_N]; + for (int i = 0; i < mlDsa_k; i++) { + for (int j = 0; j < ML_DSA_N / 4; j++) { + int tOffset = j*4; + int vOffset = (i*320) + (j*5); + t1[i][tOffset] = (v[vOffset] & 0xFF) + + ((v[vOffset+1] << 8) & 0x3FF); + t1[i][tOffset+1] = ((v[vOffset+1] >> 2) & 0x3F) + + ((v[vOffset+2] << 6) & 0x3FF); + t1[i][tOffset+2] = ((v[vOffset+2] >> 4) & 0xF) + + ((v[vOffset+3] << 4) & 0x3FF); + t1[i][tOffset+3] = ((v[vOffset+3] >> 6) & 0x3) + + ((v[vOffset+4] << 2) & 0x3FF); + } + } + return t1; + } + + public int[][] bitUnpack(int[][] result, byte[] v, int offset, int dim, + int maxValue, int bitsPerCoeff) { + + switch (bitsPerCoeff) { + case 3 -> { bitUnpackGeneral(result, v, offset, dim, maxValue, 3); } + case 4 -> { bitUnpackGeneral(result, v, offset, dim, maxValue, 4); } + case 13 -> { bitUnpackGeneral(result, v, offset, dim, maxValue, 13); } + case 18 -> { bitUnpack18(result, v, offset, dim, maxValue); } + case 20 -> { bitUnpack20(result, v, offset, dim, maxValue); } + default -> throw new RuntimeException( + "Wrong bitsPerCoeff value in bitUnpack (" + bitsPerCoeff + ")."); + } + return result; + } + public void bitUnpackGeneral(int[][] result, + byte[] v, int offset, int dim, int maxValue, int bitsPerCoeff) { + + int mask = (1 << bitsPerCoeff) - 1; + int top = 0; + int shift = 0; + int acc = 0; + for (int i = 0; i < dim; i++) { + for (int j = 0; j < ML_DSA_N; j++) { + while (top - shift < bitsPerCoeff) { + acc += ((v[offset++] & 0xff) << top); + top += 8; + } + result[i][j] = maxValue - ((acc >> shift) & mask); + shift += bitsPerCoeff; + while (shift >= 8) { + top -= 8; + shift -= 8; + acc >>>= 8; + } + } + } + } + public void bitUnpack18(int [][] result, byte[] v, int offset, + int dim, int maxValue) { + + int vIndex = offset; + for (int i = 0; i < dim; i++) { + for (int j = 0; j < ML_DSA_N; j += 4) { + result[i][j] = maxValue - ((v[vIndex] & 0xff) + + ((v[vIndex + 1] & 0xff) << 8) + + ((v[vIndex + 2] & 0x3) << 16)); + result[i][j + 1] = maxValue - (((v[vIndex + 2] >> 2) & 0x3f) + + ((v[vIndex + 3] & 0xff) << 6) + + ((v[vIndex + 4] & 0xf) << 14)); + result[i][j + 2] = maxValue - (((v[vIndex + 4] >> 4) & 0xf) + + ((v[vIndex + 5] & 0xff) << 4) + + ((v[vIndex + 6] & 0x3f) << 12)); + result[i][j + 3] = maxValue - (((v[vIndex + 6] >> 6) & 0x3) + + ((v[vIndex + 7] & 0xff) << 2) + + ((v[vIndex + 8] & 0xff) << 10)); + vIndex += 9; + } + } + } + + public void bitUnpack20(int[][] result, byte[] v, int offset, + int dim, int maxValue) { + int vIndex = offset; + + for (int i = 0; i < dim; i++) { + for (int j = 0; j < ML_DSA_N; j += 2) { + result[i][j] = maxValue - ((v[vIndex] & 0xff) + + ((v[vIndex + 1] & 0xff) << 8) + + ((v[vIndex + 2] & 0xf) << 16)); + result[i][j + 1] = maxValue - (((v[vIndex + 2] >> 4) & 0xf) + + ((v[vIndex + 3] & 0xff) << 4) + + ((v[vIndex + 4] & 0xff) << 12)); + vIndex += 5; + } + } + } + + private void hintBitPack(boolean[][] h, byte[] buffer, int offset) { + int idx = 0; + for (int i = 0; i < mlDsa_k; i++) { + for (int j = 0; j < ML_DSA_N; j++) { + if (h[i][j]) { + buffer[offset + idx] = (byte)j; + idx++; + } + } + buffer[offset + omega + i] = (byte)idx; + } + } + + private boolean[][] hintBitUnpack(byte[] y, int offset) { + boolean[][] h = new boolean[mlDsa_k][ML_DSA_N]; + int idx = 0; + for (int i = 0; i < mlDsa_k; i++) { + int j = y[offset + omega + i]; + if (j < idx || j > omega) { + return null; + } + int first = idx; + while (idx < j) { + if (idx > first) { + if ((y[offset + idx - 1] & 0xff) >= (y[offset + idx] & 0xff)) { + return null; + } + } + int hintIndex = y[offset + idx] & 0xff; + h[i][hintIndex] = true; + idx++; + } + } + + while (idx < omega) { + if (y[offset + idx] != 0) { + return null; + } + idx++; + } + return h; + } + + /* + Encoding functions as specified in Section 7.2 of the specification + */ + + public byte[] pkEncode(ML_DSA_PublicKey key) { + byte[] t1Packed = simpleBitPack(10, key.t1); + byte[] publicKeyBytes = new byte[A_SEED_LEN + t1Packed.length]; + System.arraycopy(key.rho, 0, publicKeyBytes, 0, A_SEED_LEN); + System.arraycopy(t1Packed, 0, publicKeyBytes, A_SEED_LEN, t1Packed.length); + + return publicKeyBytes; + } + + public ML_DSA_PublicKey pkDecode(byte[] pk) { + byte[] rho = Arrays.copyOfRange(pk, 0, A_SEED_LEN); + byte[] v = Arrays.copyOfRange(pk, A_SEED_LEN, pk.length); + int[][] t1 = t1Unpack(v); + return new ML_DSA_PublicKey(rho, t1); + } + + public byte[] skEncode(ML_DSA_PrivateKey key) { + + byte[] skBytes = new byte[A_SEED_LEN + K_LEN + key.tr.length + + s1PackedLength + s2PackedLength + t0PackedLength]; + + int pos = 0; + System.arraycopy(key.rho, 0, skBytes, pos, A_SEED_LEN); + pos += A_SEED_LEN; + System.arraycopy(key.k, 0, skBytes, pos, K_LEN); + pos += K_LEN; + System.arraycopy(key.tr, 0, skBytes, pos, TR_LEN); + pos += TR_LEN; + + bitPack(key.s1, s1s2CoeffSize, eta, skBytes, pos); + pos += s1PackedLength; + bitPack(key.s2, s1s2CoeffSize, eta, skBytes, pos); + pos += s2PackedLength; + bitPack(key.t0, T0_COEFF_SIZE, 1 << 12, skBytes, pos); + + return skBytes; + } + + public ML_DSA_PrivateKey skDecode(byte[] sk) { + byte[] rho = new byte[A_SEED_LEN]; + System.arraycopy(sk, 0, rho, 0, A_SEED_LEN); + + byte[] k = new byte[K_LEN]; + System.arraycopy(sk, A_SEED_LEN, k, 0, K_LEN); + + byte[] tr = new byte[TR_LEN]; + System.arraycopy(sk, A_SEED_LEN + K_LEN, tr, 0, TR_LEN); + + //Parse s1 + int start = A_SEED_LEN + K_LEN + TR_LEN; + int end = start + (32 * mlDsa_l * s1s2CoeffSize); + int[][] s1 = new int[mlDsa_l][ML_DSA_N]; + bitUnpack(s1, sk, start, mlDsa_l, eta, s1s2CoeffSize); + + //Parse s2 + start = end; + end += 32 * s1s2CoeffSize * mlDsa_k; + int[][] s2 = new int[mlDsa_k][ML_DSA_N]; + bitUnpack(s2, sk, start, mlDsa_k, eta, s1s2CoeffSize); + + //Parse t0 + start = end; + int[][] t0 = new int[mlDsa_k][ML_DSA_N]; + bitUnpack(t0, sk, start, mlDsa_k, 1 << 12, T0_COEFF_SIZE); + + return new ML_DSA_PrivateKey(rho, k, tr, s1, s2, t0); + } + + public byte[] sigEncode(ML_DSA_Signature sig) { + int cSize = lambda / 4; + int zSize = mlDsa_l * 32 * (1 + gamma1Bits); + + byte[] sigBytes = new byte[cSize + zSize + omega + mlDsa_k]; + + System.arraycopy(sig.commitmentHash, 0, sigBytes, 0, cSize); + bitPack(sig.response, gamma1Bits + 1, gamma1, sigBytes, cSize); + hintBitPack(sig.hint, sigBytes, cSize + zSize); + + return sigBytes; + } + + public ML_DSA_Signature sigDecode(byte[] sig) throws SignatureException { + + int cSize = lambda / 4; + int zSize = mlDsa_l * 32 * (1 + gamma1Bits); + + int sigLen = cSize + zSize + omega + mlDsa_k; + if (sig.length != sigLen) { + throw new SignatureException("Incorrect signature length"); + } + + //Decode cTilde + byte[] cTilde = Arrays.copyOfRange(sig, 0, lambda/4); + + //Decode z + int start = cSize; + int end = start + zSize; + int[][] z = new int[mlDsa_l][ML_DSA_N]; + bitUnpack(z, sig, start, mlDsa_l, gamma1, gamma1Bits + 1); + + //Decode h + start = end; + boolean[][] h = hintBitUnpack(sig, start); + if (h == null) { + throw new SignatureException("Invalid hints encoding"); + } + + return new ML_DSA_Signature(cTilde, z, h); + } + + /* + Auxiliary functions defined in Section 7.3 of specification + */ + + private class Shake256Slicer { + SHAKE256 xof; + byte[] block; + int byteOffset; + int current; + int bitsInCurrent; + int bitsPerCall; + int bitMask; + + Shake256Slicer(SHAKE256 xof, int bitsPerCall) { + this.xof = xof; + //BitsPerCall can only be 4 (when called from sampleS1S2), + //or 8 (when called from sampleInBall) + this.bitsPerCall = bitsPerCall; + bitMask = (1 << bitsPerCall) - 1; + current = 0; + byteOffset = SHAKE256_BLOCK_SIZE; + bitsInCurrent = 0; + block = new byte[SHAKE256_BLOCK_SIZE]; + } + + void reset() { + xof.reset(); + current = 0; + byteOffset = SHAKE256_BLOCK_SIZE; + bitsInCurrent = 0; + } + + int squeezeBits() { + while (bitsInCurrent < bitsPerCall) { + if (byteOffset == SHAKE256_BLOCK_SIZE) { + xof.squeeze(block, 0, SHAKE256_BLOCK_SIZE); + byteOffset = 0; + } + current += ((block[byteOffset++] & 0xff) << bitsInCurrent); + bitsInCurrent += 8; + } + int result = current & bitMask; + current >>= bitsPerCall; + bitsInCurrent -= bitsPerCall; + return result; + } + } + + private void sampleInBall(int[] c, byte[] rho) { + var xof = new SHAKE256(0); + Shake256Slicer slicer = new Shake256Slicer(xof, 8); + xof.update(rho); + + long parity = 0; + for (int i = 0; i < 8; i++) { + long sample = slicer.squeezeBits(); + parity |= sample << 8 * i; + } + + Arrays.fill(c, 0); + + int k = 8; + for (int i = 256 - tau; i < 256; i++) { + //Get random index < i + int j = slicer.squeezeBits(); + while (j > i) { + j = slicer.squeezeBits(); + } + + //Swap c[i] and c[j], set c[j] based on parity + c[i] = c[j]; + c[j] = (int) (1 - 2 * (parity & 1)); + parity >>= 1; + } + } + + int[][][] generateA(byte[] seed) { + int blockSize = 168; // the size of one block of SHAKE128 output + var xof = new SHAKE128(0); + byte[] xofSeed = new byte[A_SEED_LEN + 2]; + System.arraycopy(seed, 0, xofSeed, 0, A_SEED_LEN); + int[][][] a = new int[mlDsa_k][mlDsa_l][]; + + for (int i = 0; i < mlDsa_k; i++) { + for (int j = 0; j < mlDsa_l; j++) { + xofSeed[A_SEED_LEN] = (byte) j; + xofSeed[A_SEED_LEN + 1] = (byte) i; + xof.reset(); + xof.update(xofSeed); + + byte[] rawAij = new byte[blockSize]; + int[] aij = new int[ML_DSA_N]; + int ofs = 0; + int rawOfs = blockSize; + int tmp; + while (ofs < ML_DSA_N) { + if (rawOfs == blockSize) { + // works because 3 divides blockSize (=168) + xof.squeeze(rawAij, 0, blockSize); + rawOfs = 0; + } + tmp = (rawAij[rawOfs] & 0xFF) + + ((rawAij[rawOfs + 1] & 0xFF) << 8) + + ((rawAij[rawOfs + 2] & 0x7F) << 16); + rawOfs += 3; + if (tmp < ML_DSA_Q) { + aij[ofs] = tmp; + ofs++; + } + } + a[i][j] = aij; + } + } + return a; + } + + private void sampleS1S2(int[][] s1, int[][] s2, SHAKE256 xof, byte[] rhoPrime) { + byte[] seed = new byte[S1S2_SEED_LEN + 2]; + System.arraycopy(rhoPrime, 0, seed, 0, S1S2_SEED_LEN); + + Shake256Slicer slicer = new Shake256Slicer(xof, 4); + for (int i = 0; i < mlDsa_l; i++) { + seed[S1S2_SEED_LEN] = (byte) i; + seed[S1S2_SEED_LEN + 1] = 0; + slicer.reset(); + xof.update(seed); + if (eta == 2) { + for (int j = 0; j < ML_DSA_N; j++) { + int sample; + do { + sample = slicer.squeezeBits(); + } while (sample > 14); + // 2 - sample mod 5 + s1[i][j] = eta - sample + (205 * sample >> 10) * 5; + } + } else { // eta == 4 + for (int j = 0; j < ML_DSA_N; j++) { + int sample; + do { + sample = slicer.squeezeBits(); + } while (sample > 2 * eta); + s1[i][j] = eta - sample; + } + } + } + for (int i = 0; i < mlDsa_k; i++) { + seed[S1S2_SEED_LEN] = (byte) (mlDsa_l + i); + seed[S1S2_SEED_LEN + 1] = 0; + slicer.reset(); + xof.update(seed); + if (eta == 2) { + for (int j = 0; j < ML_DSA_N; j++) { + int sample; + do { + sample = slicer.squeezeBits(); + } while (sample > 14); + s2[i][j] = eta - sample + (205 * sample >> 10) * 5; + } + } else { + for (int j = 0; j < ML_DSA_N; j++) { + int sample; + do { + sample = slicer.squeezeBits(); + } while (sample > 2 * eta); + s2[i][j] = eta - sample; + } + } + } + } + + private void expandMask(int[][] result, byte[] rho, int mu) { + var xof = new SHAKE256(0); + + int c = 1 + gamma1Bits; + byte[] v = new byte[mlDsa_l * 32 * c]; + for (int r = 0; r < mlDsa_l; r++) { + int a = mu + r; + byte[] n = {(byte) a, (byte) (a >> 8)}; + + xof.update(rho); + xof.update(n); + xof.squeeze(v, r * 32 * c, 32 * c); + xof.reset(); + } + bitUnpack(result, v, 0, mlDsa_l, gamma1, c); + } + + /* + Auxiliary functions defined in section 7.4 of specification + */ + + private void power2Round(int[][] input, int[][] lowPart, int[][] highPart) { + for (int i = 0; i < mlDsa_k; i++) { + for (int m = 0; m < ML_DSA_N; m++) { + int rplus = input[i][m]; + int r0 = input[i][m] & D_MASK; + int r00 = (1 << (ML_DSA_D - 1)) - r0 ; // 2^d/2 - r+ + r0 -= (r00 >> 31) & (1 << ML_DSA_D); //0 if r+ < 2^d/2 + lowPart[i][m] = r0; + highPart[i][m] = (rplus - r0) >> ML_DSA_D; + } + } + } + + private void decompose(int[][] input, int[][] lowPart, int[][] highPart) { + int multiplier = (gamma2 == 95232 ? 22 : 8); + for (int i = 0; i < mlDsa_k; i++) { + ML_DSA.mlDsaDecomposePoly(input[i], lowPart[i], + highPart[i], gamma2 * 2, multiplier); + } + } + + private int[][] highBits(int[][] input) { + int[][] lowPart = new int[mlDsa_k][ML_DSA_N]; + int[][] highPart = new int[mlDsa_k][ML_DSA_N]; + decompose(input, lowPart, highPart); + return highPart; + } + + //Creates the hint polynomial and returns its hamming weight + private int makeHint(boolean[][] res, int[][] z, int[][] r) { + int hammingWeight = 0; + int[][] r1 = highBits(r); + int[][] v1 = highBits(z); + for (int i = 0; i < mlDsa_k; i++) { + for (int j = 0; j < ML_DSA_N; j++) { + if (r1[i][j] != v1[i][j]) { + res[i][j] = true; + hammingWeight++; + } else { + res[i][j] = false; + } + } + } + return hammingWeight; + } + + private int[][] useHint(boolean[][] h, int[][] r) { + int m = (ML_DSA_Q - 1) / (2*gamma2); + int[][] lowPart = new int[mlDsa_k][ML_DSA_N]; + int[][] highPart = new int[mlDsa_k][ML_DSA_N]; + decompose(r, lowPart, highPart); + + for (int i = 0; i < mlDsa_k; i++) { + for (int j = 0; j < ML_DSA_N; j++) { + if (h[i][j]) { + highPart[i][j] += lowPart[i][j] > 0 ? 1 : -1; + } + highPart[i][j] = ((highPart[i][j] % m) + m) % m; + } + } + return highPart; + } + + /* + NTT functions as specified in Section 7.5 of specification + */ + + public static int[] mlDsaNtt(int[] coeffs) { + implMlDsaAlmostNttJava(coeffs); + implMlDsaMontMulByConstantJava(coeffs, MONT_R_MOD_Q); + return coeffs; + } + + static void implMlDsaAlmostNttJava(int[] coeffs) { + int dimension = ML_DSA_N; + int m = 0; + for (int l = dimension / 2; l > 0; l /= 2) { + for (int s = 0; s < dimension; s += 2 * l) { + for (int j = s; j < s + l; j++) { + int tmp = montMul(MONT_ZETAS_FOR_NTT[m], coeffs[j + l]); + coeffs[j + l] = coeffs[j] - tmp; + coeffs[j] = coeffs[j] + tmp; + } + m++; + } + } + } + + public static int[] mlDsaInverseNtt(int[] coeffs) { + implMlDsaAlmostInverseNttJava(coeffs); + implMlDsaMontMulByConstantJava(coeffs, MONT_DIM_INVERSE); + return coeffs; + } + + static void implMlDsaAlmostInverseNttJava(int[] coeffs) { + int dimension = ML_DSA_N; + int m = 0; + for (int l = 1; l < dimension; l *= 2) { + for (int s = 0; s < dimension; s += 2 * l) { + for (int j = s; j < s + l; j++) { + int tmp = coeffs[j]; + coeffs[j] = (tmp + coeffs[j + l]); + coeffs[j + l] = montMul(tmp - coeffs[j + l], + MONT_ZETAS_FOR_INVERSE_NTT[m]); + } + m++; + } + } + } + + void mlDsaVectorNtt(int[][] vector) { + for (int[] ints : vector) { + mlDsaNtt(ints); + } + } + + void mlDsaVectorInverseNtt(int[][] vector) { + for (int[] ints : vector) { + mlDsaInverseNtt(ints); + } + } + + //Todo + public static void mlDsaNttMultiply(int[] res, int[] coeffs1, int[] coeffs2) { + implMlDsaNttMultJava(res, coeffs1, coeffs2); + } + + static void implMlDsaNttMultJava(int[] product, int[] coeffs1, int[] coeffs2) { + for (int i = 0; i < ML_DSA_N; i++) { + product[i] = montMul(coeffs1[i], toMont(coeffs2[i])); + } + } + + public static void montMulByConstant(int[] coeffs, int constant) { + implMlDsaMontMulByConstantJava(coeffs, constant); + } + + static void implMlDsaMontMulByConstantJava(int[] coeffs, int constant) { + for (int i = 0; i < ML_DSA_N; i++) { + coeffs[i] = montMul((coeffs[i]), constant); + } + } + + public static void mlDsaDecomposePoly(int[] input, int[] lowPart, int[] highPart, + int twoGamma2, int multiplier) { + implMlDsaDecomposePoly(input, lowPart, highPart, twoGamma2, multiplier); + } + + @IntrinsicCandidate + static void implMlDsaDecomposePoly(int[] input, int[] lowPart, int[] highPart, + int twoGamma2, int multiplier) { + decomposePolyJava(input, lowPart, highPart, twoGamma2, multiplier); + } + + static void decomposePolyJava(int[] input, int[] lowPart, int[] highPart, + int twoGamma2, int multiplier) { + for (int m = 0; m < ML_DSA_N; m++) { + int rplus = input[m]; + rplus = rplus - ((rplus + 5373807) >> 23) * ML_DSA_Q; + rplus = rplus + ((rplus >> 31) & ML_DSA_Q); + int r0 = rplus - ((rplus * multiplier) >> 22) * twoGamma2; + r0 -= (((twoGamma2 - r0) >> 22) & twoGamma2); + r0 -= (((twoGamma2 / 2 - r0) >> 31) & twoGamma2); + int r1 = rplus - r0 - (ML_DSA_Q - 1); + r1 = (r1 | (-r1)) >> 31; + r0 += ~r1; + r1 = r1 & ((rplus - r0) / twoGamma2); + lowPart[m] = r0; + highPart[m] = r1; + } + } + + private void matrixVectorPointwiseMultiply(int[][] res, int[][][] matrix, + int[][] vector) { + + int resulti[] = new int[ML_DSA_N]; + int[] product = new int[ML_DSA_N]; + for (int i = 0; i < mlDsa_k; i++) { + for (int m = 0; m < ML_DSA_N; m++) { + resulti[m] = 0; + } + for (int j = 0; j < mlDsa_l; j++) { + mlDsaNttMultiply(product, matrix[i][j], vector[j]); + for (int m = 0; m < ML_DSA_N; m++) { + resulti[m] += product[m]; + } + } + for (int m = 0; m < ML_DSA_N; m++) { + res[i][m] = montMul(resulti[m], MONT_R_MOD_Q); + } + } + } + + private void nttConstMultiply(int[][] res, int[] a, int[][] b) { + for (int i = 0; i < b.length; i++) { + mlDsaNttMultiply(res[i], a, b[i]); + } + } + + private int[][] vectorConstMul(int c, int[][] vec) { + int[][] res = new int[vec.length][vec[0].length]; + for (int i = 0; i < vec.length; i++) { + for (int j = 0; j < vec[0].length; j++) { + res[i][j] = montMul(c, toMont(vec[i][j])); + } + } + return res; // -q < res[i][j] < q + } + + // Adds two vectors of polynomials + // The coefficients in the input should be between -MONT_Q and MONT_Q . + // The coefficients in the output will be nonnegative and less than MONT_Q + int[][] vectorAddPos(int[][] vec1, int[][] vec2) { + int dim = vec1.length; + int[][] result = new int[dim][ML_DSA_N]; + for (int i = 0; i < dim; i++) { + for (int m = 0; m < ML_DSA_N; m++) { + int r = vec1[i][m] + vec2[i][m]; // -2 * MONT_Q < r < 2 * MONT_Q + r += (((r >> 31) & (2 * MONT_Q)) - MONT_Q); // -MONT_Q < r < MONT_Q + r += ((r >> 31) & MONT_Q); // 0 <= r < MONT_Q + result[i][m] = r; + } + } + return result; + } + + int[][] vectorAdd(int[][] result, int[][] vec1, int[][] vec2) { + for (int i = 0; i < result.length; i++) { + for (int j = 0; j < ML_DSA_N; j++) { + int tmp = vec1[i][j] + vec2[i][j]; + result[i][j] = tmp; + } + } + return result; + } + + int[][] vectorSub(int[][] vec1, int[][] vec2, boolean needsAdjustment) { + int dim = vec1.length; + for (int i = 0; i < dim; i++) { + for (int j = 0; j < ML_DSA_N; j++) { + int tmp = vec1[i][j] - vec2[i][j]; + if (needsAdjustment) { + if (tmp <= -ML_DSA_Q) { + tmp += ML_DSA_Q; + } else if (tmp >= ML_DSA_Q) { + tmp -= ML_DSA_Q; + } + } + vec1[i][j] = tmp; + } + } + return vec1; + } + + //Precondition: 2^-31 <= r1 <= 2^31 - 5 * 2^20, and bound < q - 5234431 + //Computes whether the infinity norm of a vector is >= bound + boolean vectorNormBound(int[][] vec, int bound) { + boolean res = false; + for (int i = 0; i < vec.length; i++) { + for (int j = 0; j < ML_DSA_N; j++) { + int r1 = vec[i][j]; + r1 = r1 - ((r1 + (5 << 20)) >> 23) * ML_DSA_Q; + r1 = r1 - ((r1 >> 31) & r1) * 2; + res |= (r1 >= bound); + } + } + return res; + } + + // precondition: -2^31 * MONT_Q <= a, b < 2^31, -2^31 < a * b < 2^31 * MONT_Q + // computes a * b * 2^-32 mod MONT_Q + // the result is greater than -MONT_Q and less than MONT_Q + private static int montMul(int b, int c) { + long a = (long) b * (long) c; + int aHigh = (int) (a >> MONT_R_BITS); + int aLow = (int) a; + int m = MONT_Q_INV_MOD_R * aLow; // signed low product + + // subtract signed high product + return (aHigh - (int) (((long)m * MONT_Q) >> MONT_R_BITS)); + } + + static int toMont(int a) { + return montMul(a, MONT_R_SQUARE_MOD_Q); + } +} diff --git a/src/java.base/share/classes/sun/security/provider/ML_DSA_Impls.java b/src/java.base/share/classes/sun/security/provider/ML_DSA_Impls.java new file mode 100644 index 00000000000..3213b1e5a5e --- /dev/null +++ b/src/java.base/share/classes/sun/security/provider/ML_DSA_Impls.java @@ -0,0 +1,212 @@ +/* + * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package sun.security.provider; + +import sun.security.jca.JCAUtil; +import java.security.*; +import java.security.SecureRandom; +import java.util.Arrays; + +public class ML_DSA_Impls { + + public enum Version { + DRAFT, FINAL + } + + // This implementation works in FIPS 204 final. If for some reason + // (for example, interop with an old version, or running an old test), + // set the version to an older one. The following VM option is required: + // + // --add-exports java.base/sun.security.provider=ALL-UNNAMED + public static Version version = Version.DRAFT; + + static int name2int(String name) { + if (name.endsWith("44")) { + return 2; + } else if (name.endsWith("65")) { + return 3; + } else if (name.endsWith("87")) { + return 5; + } else { + // should not happen + throw new ProviderException("Unknown name " + name); + } + } + + public sealed static class KPG + extends NamedKeyPairGenerator permits KPG2, KPG3, KPG5 { + + public KPG() { + // ML-DSA-65 is default + super("ML-DSA", "ML-DSA-65", "ML-DSA-44", "ML-DSA-87"); + } + + public KPG(String pname) { + super("ML-DSA", pname); + } + + @Override + protected byte[][] implGenerateKeyPair(String name, SecureRandom sr) { + byte[] seed = new byte[32]; + var r = sr != null ? sr : JCAUtil.getDefSecureRandom(); + r.nextBytes(seed); + ML_DSA mlDsa = new ML_DSA(name2int(name)); + ML_DSA.ML_DSA_KeyPair kp = mlDsa.generateKeyPairInternal(seed); + try { + return new byte[][]{ + mlDsa.pkEncode(kp.publicKey()), + mlDsa.skEncode(kp.privateKey()) + }; + } finally { + kp.privateKey().destroy(); + Arrays.fill(seed, (byte)0); + } + } + } + + public final static class KPG2 extends KPG { + public KPG2() { + super("ML-DSA-44"); + } + } + + public final static class KPG3 extends KPG { + public KPG3() { + super("ML-DSA-65"); + } + } + + public final static class KPG5 extends KPG { + public KPG5() { + super("ML-DSA-87"); + } + } + + public sealed static class KF extends NamedKeyFactory permits KF2, KF3, KF5 { + public KF() { + super("ML-DSA", "ML-DSA-44", "ML-DSA-65", "ML-DSA-87"); + } + public KF(String name) { + super("ML-DSA", name); + } + } + + public final static class KF2 extends KF { + public KF2() { + super("ML-DSA-44"); + } + } + + public final static class KF3 extends KF { + public KF3() { + super("ML-DSA-65"); + } + } + + public final static class KF5 extends KF { + public KF5() { + super("ML-DSA-87"); + } + } + + public sealed static class SIG extends NamedSignature permits SIG2, SIG3, SIG5 { + public SIG() { + super("ML-DSA", "ML-DSA-44", "ML-DSA-65", "ML-DSA-87"); + } + public SIG(String name) { + super("ML-DSA", name); + } + + @Override + protected byte[] implSign(String name, byte[] skBytes, + Object sk2, byte[] msg, SecureRandom sr) { + var size = name2int(name); + var r = sr != null ? sr : JCAUtil.getDefSecureRandom(); + byte[] rnd = new byte[32]; + r.nextBytes(rnd); + var mlDsa = new ML_DSA(size); + if (version == Version.FINAL) { + // FIPS 204 Algorithm 2 ML-DSA.Sign prepend {0, len(ctx)} + // to message before passing it to Sign_internal. + var m = new byte[msg.length + 2]; + System.arraycopy(msg, 0, m, 2, msg.length); // len(ctx) = 0 + msg = m; + } + ML_DSA.ML_DSA_Signature sig = mlDsa.signInternal(msg, rnd, skBytes); + return mlDsa.sigEncode(sig); + } + + @Override + protected boolean implVerify(String name, byte[] pkBytes, + Object pk2, byte[] msg, byte[] sigBytes) + throws SignatureException { + var size = name2int(name); + var mlDsa = new ML_DSA(size); + if (version == Version.FINAL) { + // FIPS 204 Algorithm 3 ML-DSA.Verify prepend {0, len(ctx)} + // to message before passing it to Verify_internal. + var m = new byte[msg.length + 2]; + System.arraycopy(msg, 0, m, 2, msg.length); // len(ctx) = 0 + msg = m; + } + return mlDsa.verifyInternal(pkBytes, msg, sigBytes); + } + + @Override + protected Object implCheckPublicKey(String name, byte[] pk) + throws InvalidKeyException { + + ML_DSA mlDsa = new ML_DSA(name2int(name)); + return mlDsa.checkPublicKey(pk); + } + + @Override + protected Object implCheckPrivateKey(String name, byte[] sk) + throws InvalidKeyException { + + ML_DSA mlDsa = new ML_DSA(name2int(name)); + return mlDsa.checkPrivateKey(sk); + } + } + + public final static class SIG2 extends SIG { + public SIG2() { + super("ML-DSA-44"); + } + } + + public final static class SIG3 extends SIG { + public SIG3() { + super("ML-DSA-65"); + } + } + + public final static class SIG5 extends SIG { + public SIG5() { + super("ML-DSA-87"); + } + } +} diff --git a/src/java.base/share/classes/sun/security/provider/SunEntries.java b/src/java.base/share/classes/sun/security/provider/SunEntries.java index e597a5fa4f4..36278ae445f 100644 --- a/src/java.base/share/classes/sun/security/provider/SunEntries.java +++ b/src/java.base/share/classes/sun/security/provider/SunEntries.java @@ -187,20 +187,33 @@ public final class SunEntries { attrs.clear(); attrs.put("ImplementedIn", "Software"); addWithAlias(p, "Signature", "HSS/LMS", "sun.security.provider.HSS", attrs); + + add(p, "Signature", "ML-DSA", "sun.security.provider.ML_DSA_Impls$SIG", attrs); + addWithAlias(p, "Signature", "ML-DSA-44", "sun.security.provider.ML_DSA_Impls$SIG2", attrs); + addWithAlias(p, "Signature", "ML-DSA-65", "sun.security.provider.ML_DSA_Impls$SIG3", attrs); + addWithAlias(p, "Signature", "ML-DSA-87", "sun.security.provider.ML_DSA_Impls$SIG5", attrs); + /* * Key Pair Generator engines */ attrs.clear(); attrs.put("ImplementedIn", "Software"); - attrs.put("KeySize", "2048"); // for DSA KPG and APG only String dsaKPGImplClass = "sun.security.provider.DSAKeyPairGenerator$"; dsaKPGImplClass += (useLegacyDSA? "Legacy" : "Current"); + attrs.put("KeySize", "2048"); addWithAlias(p, "KeyPairGenerator", "DSA", dsaKPGImplClass, attrs); + attrs.remove("KeySize"); + + add(p, "KeyPairGenerator", "ML-DSA", "sun.security.provider.ML_DSA_Impls$KPG", attrs); + addWithAlias(p, "KeyPairGenerator", "ML-DSA-44", "sun.security.provider.ML_DSA_Impls$KPG2", attrs); + addWithAlias(p, "KeyPairGenerator", "ML-DSA-65", "sun.security.provider.ML_DSA_Impls$KPG3", attrs); + addWithAlias(p, "KeyPairGenerator", "ML-DSA-87", "sun.security.provider.ML_DSA_Impls$KPG5", attrs); /* * Algorithm Parameter Generator engines */ + attrs.put("KeySize", "2048"); addWithAlias(p, "AlgorithmParameterGenerator", "DSA", "sun.security.provider.DSAParameterGenerator", attrs); attrs.remove("KeySize"); @@ -219,6 +232,11 @@ public final class SunEntries { addWithAlias(p, "KeyFactory", "HSS/LMS", "sun.security.provider.HSS$KeyFactoryImpl", attrs); + add(p, "KeyFactory", "ML-DSA", "sun.security.provider.ML_DSA_Impls$KF", attrs); + addWithAlias(p, "KeyFactory", "ML-DSA-44", "sun.security.provider.ML_DSA_Impls$KF2", attrs); + addWithAlias(p, "KeyFactory", "ML-DSA-65", "sun.security.provider.ML_DSA_Impls$KF3", attrs); + addWithAlias(p, "KeyFactory", "ML-DSA-87", "sun.security.provider.ML_DSA_Impls$KF5", attrs); + /* * Digest engines */ diff --git a/src/java.base/share/classes/sun/security/util/KnownOIDs.java b/src/java.base/share/classes/sun/security/util/KnownOIDs.java index 19e482b63c2..223dddb7f61 100644 --- a/src/java.base/share/classes/sun/security/util/KnownOIDs.java +++ b/src/java.base/share/classes/sun/security/util/KnownOIDs.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -178,6 +178,9 @@ public enum KnownOIDs { SHA3_256withRSA("2.16.840.1.101.3.4.3.14", "SHA3-256withRSA"), SHA3_384withRSA("2.16.840.1.101.3.4.3.15", "SHA3-384withRSA"), SHA3_512withRSA("2.16.840.1.101.3.4.3.16", "SHA3-512withRSA"), + ML_DSA_44("2.16.840.1.101.3.4.3.17", "ML-DSA-44"), + ML_DSA_65("2.16.840.1.101.3.4.3.18", "ML-DSA-65"), + ML_DSA_87("2.16.840.1.101.3.4.3.19", "ML-DSA-87"), // kems 2.16.840.1.101.3.4.4.* ML_KEM_512("2.16.840.1.101.3.4.4.1", "ML-KEM-512"), diff --git a/test/jdk/sun/security/provider/acvp/data/ML-DSA-keyGen-FIPS204/internalProjection.json b/test/jdk/sun/security/provider/acvp/data/ML-DSA-keyGen-FIPS204/internalProjection.json new file mode 100644 index 00000000000..1fcb409227f --- /dev/null +++ b/test/jdk/sun/security/provider/acvp/data/ML-DSA-keyGen-FIPS204/internalProjection.json @@ -0,0 +1,555 @@ +{ + "vsId": 42, + "algorithm": "ML-DSA", + "mode": "keyGen", + "revision": "FIPS204", + "isSample": false, + "testGroups": [ + { + "tgId": 1, + "testType": "AFT", + "parameterSet": "ML-DSA-44", + "tests": [ + { + "tcId": 1, + "deferred": false, + "seed": "93EF2E6EF1FB08999D142ABE0295482370D3F43BDB254A78E2B0D5168ECA065F", + "pk": "BC5FF810EB089048B8AB3020A7BD3B16C0E0CA3D6B97E4646C2CCAE0BBF19EF7230A19D75ADBDED52DB855E252A719FCBD147BA67B2FAD14ED0E68FDFE8C65BADEACB0911193ADFA8794D78F8E3D662A1C49DA819FD959E7F078F203C456F8B6E7C9415898E541C73032DBD619EAF60F8D64F8683DA99ECA51220B0ACA28464099F547C02777BD37D84A59BD37ED7A8A92633C75D07C793FE7252B584ABF6A15EE14507E5E193F89864D09AC8727A6D0421F0C19F0E2FBFC213D3FBD70F4F9762CECFF231E9C8A7628D3F8B0857B032D32DE62FF8ECBF4008289BF34403665F81A081AD5A85A282F99BAB9E5385AFBCCCF44B74C0196C7545527EC3026DA1280C4EB37D09CFE3EC4B4910B62EB9815A425C6590FC4AD3FBB225752CC1FC5693F187E7DEC4EEFBEB6B91BD91C5E2EA6A91D14D097BE203FBA0BF937C97507DC007C4CAA9B0785892966FF15900924E579D4FBA02BDA87555F073DAE00513E70809ABBC711FBA2E7649577C42AFDC24BF7413E51268AD6DB6113B7D9191AF9D061DBDED5D630877650C124F11BC4BDC3FDC6A900F63126F921E838AD0C2275A3389A39BD99A134504550101CD3E95E6D1496BE7DE6627DF4FD6C28BBF40B30EFA9B5C3D5C85AB14A65C02D6D4781FF13D328608554B6D15ED91289A6D55AAC0C38E37706F7355E9A4FDA615B875926BFE5A59D9EF273BF94A07CFA573178F0E004B6E1EF0A8349E9BCC01981F2460F0A2743C28D1E138FFB765E7E3397B7913335D402FE91806AA8FC819253AF32692FA651E867F5907EF46F00625A030EC904EDAB21426D59119D2CAA43BD935DEC0A550C61EE4B279C1CA3A79C79A66E3F2D2FADB00F59A3A438AA44570106073017FA1C8757500109720D125BBA231A0C36350C78086DFDC8D613AECA88C4CCAEB4A44D13ADB3C717D65C82A351B9B6EABF6A10F4B4E9623E3A95B4D40A12A818AC6B3822DB82FB05DC4202648B4454689AEB69EA325F03E35DEFA54708481420C6D697BB912FCA0D3F192EF297DFE77FF36B2103F1AD1AEECED1C814C2CD7EF16BCE476AD04F941AFC79E3295474A41062518C0037860934F0E5E652F72749A698632A0991F613F5CB96CA1178F974F2C4AA0CE63DC24E364C92A643B90A5F85A62FD4D8D2B193D29B18BEDE2653FC5D3F24F5B2C018DBBCB6EF00F305BF93666BD47FEA9193BC233DB39121442E938DA5DD07EE6E879C5B9DFF41ECEE5E0589AE6175FF5EC6F6D2629F56B18B4DE66FCB13DF0400A797C92270F69BDEBDDCB88C4248919B56CDA70B8AC4F9429C292DA94D6478280764FE2386FC38CB0931458839EF4E7DE8F0689D99805988C7F96111852C8929E5A540D3B78D712DECC396FEF3EC34402184E4FD29F363EA80F6FC50BA9A11351ACEEA8FE68D541E1AA5848D9F6E61DFB62B2F23BC5081E82F76226E03284982EC48481209B1A7D4C8797E44BFA870B22004DB74BD7D478D5B3614D2B1DA7502B398EB9DA80D06461E90E03060446AB4A8238432BFAF752F391791214F1E6B63590D536060D1C245307BC5C1BAC4AAA099D36BB6DCBC973CF2E69F2734D0F29AEEC4567B99A16BC17C6CDDACEFE49927FB14E7D98DD4263519469CCA3DB4679A68CEEDA955592210FC49AA5FBE934CC73D84E4BA5478002D6890989068EF8FC98C2532B83BF3CB9EF02893C2152426B9D1A94734DFB4F91135143C9EED18FD51AE875D07A23775606A734FBA98C063B4A1622E7FF21AA7E652A3D6C19FE0DC6761B7D35302BF214D3079F76051082A875929920DC3B3CB43211A23A43A50332FAF1AC2191E717125F63E2586C4D86DCA6BCD3D038F9D3A7B66CBC7DF34", + "sk": "BC5FF810EB089048B8AB3020A7BD3B16C0E0CA3D6B97E4646C2CCAE0BBF19EF7BA2B57C446556EE2B72C78B96BB7A8503DE40AFB54184E3B5463C21AF7485323DF98F0160AE5D137512725F89D563BC9A189D31D20B3B3C8FFAAF5E486E79051F6F3605CCA2569FDB46B3318D23842CE40D6438613F68B455B0D3BCA0E050D4D119988A2C4801B9084E0B048C928092230902406499840655A268ADA3290DA4808228190C81461DC166A21478E08B221E308681A024414C665E1987190C6690C1544C9A011CC347183404500124D91080083368412854CCC0041099070189500A2B2859426410B00410AB980C0C6100C3329A3A6281C26101A374913358A0B292E82A2708B38499404809B2610A4803004370C48B26004172E194964C8C4641A966010836D2038224906081BB72001484DE110490838444C168E04B22C0991508336065C028C8A38051AB58182C00951127222100D04082AA4841058085208260A02B62D8A120E14221048440A1423915040900A2792A4B060088411C4402263462ADAA690C1B230501000A0B46C53B45013058D02310E08201091C84C22A750C2A67092464163168C8400110B81901383712185301B1846A310841443408098250C272C944241A2884502130544B644522292D080504BA60484367009B24D19A88424934994A28049B448912864A1C8654B82859330066312661037014A408018189044C40D4B2881A20640D4302C1B964CE1B260442841D8306524090464008963C224C0004992165223C129422691D038318328284C28611AB28880262D0C19525B22608A9228A21890D94252CB408E9B16064BC805E0066C49C225D422691411691C34900C858D1C8449631085083489581666A038680BA250E08461C1266EC9146AC0C03184182EDC16521418910A392C83A68D12296292A66008A510D9C84D2448248398241A4442080848C8962DA110206024519C3011DBC804112251180468E2244E10C40D18372911B78443848D54407064807021B04D0026620045251B838484807019B0040AC928CA80051B214ED4B0498C966CD0962548327254120509988C8A326DC0043163C861C8C2689BB48C5BC02DC3A88D1B166CD8964198340244142CD386440A188A1A46921AB7084C342421910D9A962DCB242292860898A050DA446A19B1058B206E24C481C99840221932110569D3949108A771DBC07002B82883B449A0448A0BB4106102481CA611E3206640B47003B6046048215B21833988DB674A61E7C208DEBE8DAE4119AFB02661A69ABC8BDD245B5D0FB1A26701C9B9C9A8F7D9FCD4C287FF3D608CF258282A1EB29F9304E89C14F3E1CE5612891C602934526006C99B4AA2399BF494BCF8DF61D6DF4C69BC93E02D4995E2F76E9FDA4EF67EB7256CA89A3F38FEB2E9DF6A010DC1C15002FBD456FAE884821A34166B0658A2412595718E149BBC6E220AEE268D4D8218C25F6A957DE5B26CEA7B14CB320D89E1699AD9F2B389C67EF93386A2C65F2C32233367D76AE4AB2ABBD422E98E493DCC3CC5DAF689B65CC4BC3FA51C9C59EEAF0755170C2495804D02A607C5BF887CD86A0389F28FC9725EF46003F13B0187684BEAB1F24A29F5319601F309C91D2A333D1B88DF205A5120C4CFDC2238124E4E2B47D0B5E66A654FE4CCCB078F07CBD455D15D3EEC7DA274D24A2E571884DE41C3A9A4FDB3F6098A172C30968039BD0E4EB3E2FB6D6EEED39E0B6362D54E7B88959869DDD5D873D9652401A29F27A28EA66D32CCB0EF3BF4600F7557EE8D54BF1DAD18F45DDCD4C9ED57B13E445BF122A43F53940389BF8714FFAC721E59317E4B70500AD0D1B9A627054D3193208C774E0B20ED041A8C055E75EECD3738F007158FADDFCA5F43562D636A5ACF3A3983D3CFEBCA10B813F9F6526519199A0313CD1DE13F06AD5386E1E120795FD267B7F42019D84DF6CD1BF91930FCA7AFD52E80700F4CF5CDC38A5F7A5749791C2FDFFC4A10753C24DB19E8EB651C5B363200F0B5D169947026E9F74F012DC7C5B339DD49D261CA1D37F8F28346E61978054F45AEE436DCCBE7BFAFE07CE9A8B83C90A2686FA95402850925C8582BC9B734E4ECA1F7B20B086F129F277A5CBDAA963C92717EF70EC19BF3DBC6DA203AD90F3B13BBC22FBD980BB1B9D3A34452B3357021CE3613584E0936BF1D09420937815E11CC5D5DDB4BF1D830C4F83F30E515921C784D87BB20C09E3C64BDCE9AB1C69FD307EFE359C7F938566C9F2517B063385167E247F31081119BAC6B55A0BDD71425510FFA2ABDFA888376A37F20C2480152BB361634520007C5B34BF22817CB2E67AC1A82670B71F196C89F23BA314B16A948499304EF5C03DCF58E52BE314863E723C56D3AEB340BFF18ABFA20DC03442030230533D9129B83ED22C351F2328172E363447444AE5C6902B792799F544450787119612E9BB4130A33A2A5962AC09D577D6DDC881FE6616126D8A0A7DF2B2253BC8EC4E35386EA5511F0F15887145B6C23AB3D403339E404073ED9C6A896A2F9EC70C44BD2AEC10FC4360E87636BE155B6A67B7EDF38CF73004813C9E7D2C654C2530A71E5F8C10942FB6D8841535AB1DA43E8CB0BB89E78EC91F8DE1531A03665CCD5A75BDA0ED0E59864EEEF51A83FA553AF662AEE00D1F8367B4D5DDDC345544C6BD514F888E6033C255DB650DA734AD33A3CF84BD3F06FA1A7CA02E4B8E993AE7AE63420A46BA8A3813D1E9D2966BB8560D71C62A044EA94179F4EB1B6ED60719D51E0EEF6CD079152F6BE488EC91911C6D3F1D1173C541F9D25BF342FCAA3FF46C18F2A0441D83BDE3546A9826C3496E06F2F2B0EEB9D5BE8739F83A42D3B300E70EE84DFFFB20764A060212F058C8A5FFA9A34E928D6A7E07708FE5393E3017CE470EB9658A74E4951E6FA4854C9E9C28988812E4418A2E832580B4A270372BC69676889D0CC43240EDABC1D3114D8F35AB2E9EA953082E9536279ACB3BE16D3A205F46CB67B221496935AC04292BBFB9A61C0A03EF4C9B6820495F3D80E4A6FB7E1C69903FA226E023E95BA416DF2E5E4541E15DCC000B5E65C9720DAF696012FA2A6CF758ED6D225A3E4FEE45AC5FB48707FAE133D592CFD2E8C43C2126F652BEE9BAB43A1A10BE2411A6794B26CB55CC217EB7B0B146D23F7922D3222AE5EE8C6D38E8399BA51C681B83816FCF74438825920F9CE8A202A8F6D942DA86238FB4C9F2198EA8DFF81C17286E018DF4B7FE3884D1759E4C59BB52617AED4E78E4E7C4E9A36E4E996D32391A34A0DAAAB6B540815A34D20407AEF81949BE67B906950D89BE9F085E99EB5872695173B3EFACAE9455D2B2CD4F710B872CF662B736216B1BBFB1F5F3D486C7B4B875612333F8E4BA933DC79F0EDFD7BAADE2C16F2146A496F79C42A4D6B5239A30DD3C48BEB092CA0750010F69ED4B92320147DBBE208F6E8EB1CF247D21A3A3B01DF58C0AA62944DA0EF0450E8CE48AA137E7E1516C1D5C86EEA17FDFAC1690746E7267045A3E90596BDB75D50B6DD5C34E5C8D89DC6F2F1D24440E57B4759B8625F72BC4A7B10D519D331F9C400AAE1E50D480CAAE5A1C0FA99D77924CF8DFE56CD7092E7B9" + }, + { + "tcId": 2, + "deferred": false, + "seed": "D6A5D2325B94CA1B993A0151E24AB95B396F415831DC14A08404820AE58A2AD1", + "pk": "EB7D0B421F280C78141464ED90C7CBF20D0E34F5DDCCB7464E7209C109B1F3A7C19946647A330D65E7C2A4626515306060BA6D293ABC2505D2FD8C2BEB94A5E3F410C45F997FCC70A48BDDAB67EBE3D4DFFC2884CA63B9E4061D1C5D0520464A0C4FA59544EC3230FFFA002349E4DF045D3C52F9ECB0B7F6ABDC52E8366FE6077C858C3E29B7CBB6AED2CB68279885964C5598D642B07DDE597A1404FF7F67F301B2C3BAC1C841926DA3B2A43493D399D0A85F868DDB1DF6802A3E487C0E4AF65E6DC82865EAC02DE8AEB7273D0A7A2472E6B59337AE95F824CA107734EF25B325CC123DD3945C706446E3C549045E3476670D8D673A9178D2A80F72F36FB01B513463A5E8EFC7985280140A43E2BCA8728B5F943A34553E12E2C29F4F04856BE5D6CE0DE8CF2A9560CE2B96AB3042AA8DFAFF5AEE292049A8AF15A2290968476A1F69DE8F32363DFA2F6E8CDDD6330881777C9F6C8AC41B549EEFAAC017BF60C3461F3FDEC8A2BBC971F8F7E3F57E82B66317DECCAE3F67641DEDAF0FE4F6144E6D6ACC8A4EAFDE1FC3046CCA680E1CF4A695E477AC91436866145E13C885488DF5E33363A9E3727390291F6E7678ADA974CAF1220621EF292FF7B62D6178E3EA43552478E1F2F626DBB0F893FA777DB7948F14AE60C418C12CC67B1CFEBC45A5752DF0E1420F69FCC4469D77942D484554F5EAC70E43229C2DD7363B46B58204ACB208B857735860CBD22270C787CA7072555FD8AA218BD258B976A529C9DE8DED6E24265F5D5DE9C43762A74E1810656058609766DDAD25FBD72B8E8C1ED058E1F124D8DD85F04A2437302CA6CF5250FA29849D54BB077ABD356D0769ED1AEED8A2535C3C6CD15FD8EF66F12DD381D62B1909235EEF975FEB1C40B7F8EB8D8A0B4A129918719993E813681D43AB52F8FEB68028DBEBEAD015AAC4EC989BF1563BAD3D7E2EDFF0D8BA6A5EF1BAE0D11BF5F1FDC2CEB4EA464A21D53E6287F56675B8E7FD881E4005CDDAC618B57423B6F6FE8CE8E57D6370A15ABF168B8A1EEB044C0D05D9DCCF1C9D6DAC6E8FD155C49CD1B509F450518A724D18AC502C869D6055CDCD280423FE8CAEAEFE572C0D12D31BC3A75BF4DA4A2A3753731CFF7216E2AF2E1DCEA6E2FDCDD9293B1E256B1A50B11F2E59B0CC701E433FDB7DA4A266746EBF395CA233A5A4C4F3C3782018DB5D1E338C7F92846953D24658D15F92B656F42A4A1C5CA46ABB6666E1B415798D33BB0930C6C3411FFA4E3ADD1C3289479913586F2C516E35426A76DDD5FC78332011F436D0B7D278E7082824EE4CACF42E13A84C39B2894FA8A2B97A579F22B35A601E49977AF381DC47231889532EFD3A890E207BD1F6A32CFD46546D33B0E80DF177D851A09D727A681969B97AC4D06EA17CA878E264ACA0A343F86444383D1DD18176AD6FF52B6172888F71CEC1F21F091581B0AF7A0AF7E84A4D24636BCF4D47BB53DC19E19FBD42468CA1B1AA85C48EB886F272836193F65A13A5002DBC6C37D74217B8DF0B0D02E4932C949EBEC293BF7AF4EE88A4C8A9509529353EE35EFD12B3B8B49EF6C70C71FC14DB7E716E72A5AFC550721DAA26F5201E6C7DB1DBA04CA89B0BCA48127D007982FE304780B8FC024681CFE373A879ADED69BFCF9BE8E0BF936DF636F74CC1B0722A61B2D9F1661245386B4CB7897084EF8D154E2AA05FC909FF699C4B1F563476DD93909B8EFEB20F875A90708B84E9373B39D34041179055752E31682714F30653DE5D9E0DE9D13738E00CE99B91DD2286FE3A675DBE7D4AB9F13124D5991097A5D2EED97DF2CB39F82909DADD36C72F734D0022D9301B42FC386DF483AA2443AEBA", + "sk": "EB7D0B421F280C78141464ED90C7CBF20D0E34F5DDCCB7464E7209C109B1F3A778BB75F600752B1F5E36CD984C52A42319B2C26D05FFC9906A5FAE6EA550CC712A1DE8F8854EB8E3DF5E36EA60369427D39CC2CE622FBA3654DBB125207AE448262E499F9C216575393AA8EAF8BC8B845F3510A492A8158460295046E7257531821684649489D04021194606032860D1A689DB100A50202611402C201744214981A11224C9882023B19180B048E3906D1A0144C31685249561C03052438631414470E34022A448098A2040028061A43041CA848421084E4084410BC35199340C90C0118BA8401CB78461244002B509402029C18604C424429B24720A0422C3C0700448501BA200D2168E12148E6490098A18428A466924483222996043284804C11198463151A408A4A861D31605DB8851A2040288B80C50B605202188502882043688421424DC800501A96C19336CE0426C02194EC3C6294B8885900665D84688C2123018B43013166D5300720A4968E0C22424411014856C8A3428984064CBB868989611C2A0088A288A89960548440D0A908D02328E9C14926410400348102311815B36688A9060594464228230C01470D208840BA160C3344E8A16640AB420D006121325802344505A24410015880A030E80988D60C60824C50DA20828142969034848CA984503B5040BC66904278EC8A6415C0084A1106D21134D2493854A46494B02658BA409C44221E2B20561443113481290148CC1284249C43091104122032AA3802CA2386C819484829431133045583649444086092706D8382183144A14298988842D1AA2714CC005E0B26C60204041A07008C2648132729914001A368D12C82052A42980242C9C1825C4C820C28801C3342CE3263010B604C4200952401109295049A22CCB0064C0C680CB189041B269E20420A1486AC4126E61226100392C1B371004030902056C0CC391111289543641D2A48812A92C82A00C4CA46819202652068C802688DCC485D9B28C931865C086851A072663A4240B176920128450C04408B80D1B198490123023426242B808140001512250D3280619140AA044641C418A92300914065109012013125298382CE3A44808300D4426426210010423320B2501CB9630591660804621844402DB9480C1A26448C690A0260123B900A3A0881A82210A424A1C377012A281DC8048502464989401CC020901B848C23022C3B44D60246AD3182A1430321905308A32321017521B492E00C0889A043F9965001E620A4774CEA00A5ED582E80D386F8C90D481B5B078A1C88F4AD8D1530BAB2BA08EF807674CF1680898E5A9B675B606D20634492E3F89C547C80A98D461CCB8A141189017166846778A62C4B55EED13D7E4DF1DA69413D4D24761B1438D94ABE3D86EC049B8877E5A85DC47D95478345D3ECB6093FF46D1061A6B054DC2AA2770878C236ECE4067B2BE4EEA132CB66ACE9BC3B07824B450A80104E644C57006A6ABE36B31E3BBD99BFBA8DC4487FBBD5161DB7E6F425F17E9E48290414E9989C174AB03864F53E18CF3034A62E2DF49AEC61AD291F0266F66D2E47DD89597F1354B0628D71A376A91C80C2A58AF83D9D96DB8430DE3474EF2490CD9D9EDC43EDBAF8E4B2486A4BDF207A026465ABF2E801972028ABFB891383538DE67E49871AF6BDDBDB3414833D3D556377D57F673387C496EDA35A6FB932657EDD54CE4A6A208750036E3EE66B2CC5ADA490B272E6108CEE4D55DF40EDCBC551D399A6399D7FB4386ADF1A026B32F5D0999206077A29AF7AA363FD28753E0A251002E7D130E2A311B4F2EB87F9B4D3507A06AB5203C4A5DCA9778ADD29FF0DDAFC0B6666CC7DE112436AADAF6E23A5BDE29C4D967400EE165E162F4508B1B9B348A8E39A776D4C17571E746C14210C100246F6E88DCB0335121786F63C9398241F164715C262565E5E83B762401659C03236FCE692C49BC021851B299ADF0A5569AC4B37AD08BF37222188E9E0214DD882D8D4E20E99F4F37C1B8BD71B853FBADA6F79F144FB8213D3070B5674821DA6C0F6AD69C40D37DFAACADDBB79DB5EAAF11FB5E1CC59843DE671CAA2573D918FF146E9EC3A0317E8E81DC341439A516B0D43D6B1424B520E40B7E0706DA7F41CC4E4FA78698C83B3994F63507162533E4FA95F2E3305A78662D2519FE4DCA125A466868ED723BE984FC9007F523E3B57FE4DDD0D90D7B62314BAAAE78CB758C58B13CC1E137895A1460A5B7C2BAB639F58378166F7AD95C83729E320CF8968EEFF4DDD2ED2805DCD2C0245C0EA55B45DC0F50A275DF3A04619ACD5FE15758EDFAAA0C404C102E06AC0B99F5FC623D8A8E90EAFB305FAF0FBFE9B111CCFDFF028EBE871217F2DA0560BEB4DF17D42844B998F9B729B2CFFC340805C00C8329BEA4C59AC517575ED579F6A658594C8E74F0697D9DBE65CAB408C8F9F8DD50A202BB7F1F43B711AE59D8467793231929225EA4CB0A0AECC44D1C83DCE4CD3AD8C82B2E5CBBBE3C9ED9623F099F719FBB9D183D97FCF74C37ED6C1D3C9582E9030DC758D6EEEEE85228DB8BCE9F5EEA677391D124F404DD3231EC24B94AF9F62ED98B9DC912AB28BC4B9A76422F325D34D022668E48EF35F5EAA6F41EA9F0DF5B0D65442E8EB747D38BCC7F611766B3C770AD55192BAC8AE72F64B10F0FFFF026A89EE6657EC2857FBAABE2A6B76ECDEA53E069346869E800E43FC80FE915D070FA21234F50E92561538DD98086AE91515334BE5C0222B584060251316F75AFC064248A40E340DE80DF4C51FBE87CA18A6EDD34A45326CED1731BF44214FDD6D3EE1D257743A2E8738CAA8FEF6754F872B85EECD6519C101BD1ADBF1D84519FF4FEA87B5E6575E395F87A7DF7C45B8C1E854D712C3D73F2314D014BCC5DA3C703A058BFDC6A6D5E04B290C280328E93C40A3F27F167C5E0AEF523105066D38DDB4E7D6644AC801714FA2DD38B26D94D43BA606AFFADB0013ED5979150BE632D8C0BB2DBBB33022B095CD47EBA3BC0C152F8F9D6D8B800CDC424D6E9F9970329866D6B8A527C866C10CC8DC838A4360FE7E3243BCCFE16871A9129D8CA6FAEC779984F704335DFA1EA06BA330BB6178BFC835E63B41EF86D2866779DBC0D09922B4CDCC4489F9964E6114C094C70A92037020D56DB6D76477C5F74AD45C7FEB713BBF4AF218AED20D2FDE1B237005A97B2AC8BFDB0E4795005197932AFC0F93A7404928BD61F9989C27D9AE6EB67CC47CEF3F69883557115DA47DCAF63A76BE3353583D96DDE5982D91D5C15517B43D2EDCF63F7E7B6C8339B11CA09083B4A7EBB949F69ECEDD4A9E2258C44304AD1EC0996D1916893BFF788E97F3BC5E6640E1273A34DC0CBD0D71CDE2C793AE4813E096C0E1396004C0D5658E321153E5D27255ADD883F5849CF9F3F05833D387E813AC1D9B1B29249BA046136C2A3F3D00A1E8BF1626AE3760A5EABF781394DE154315043F7109A995C10F2C0A486CF81C84132C3D5CC02F87D3BC50965E4B088B4AAFA52B3386AE7F6CB5CD967B40F2B54177FF9AE38CC9AC4F8E6478E94F8697382FBF22D0BA389D24A0FD13EC48613409C7AA6E14FFAEEC9C7302175E73E559910" + }, + { + "tcId": 3, + "deferred": false, + "seed": "8A5E79B82DC81553BBE821EE367F0ADFA54F59A3E8A71CA626F873F638636DD7", + "pk": "B8DA2BE5527FE7006B0B4B5B4D90FAF13696C1140701F142E38A7798CCE6B3BB49A293AF090BD3D65EAABA535E8F7F1B73F93FF9B6B651CD42ECDE51904BFD1FCA2E301CCD8D171968E656FB3EEE14F7E2F2EEC4C8D6D66A073DD3E7E56D34B31A07D73F8A5A2002DFD412391F8E5008A96325365BAD17E7F48780F5C500D0E84B6658BA53E70BF7046FDE7515123EBA61E6207380D1296337EF8392CEE6C423F63AB79935F709104B966477A5E73298DBCFABB746F48B8462EECE2E5282C548F49A43DF33BFD5EB150B79732F26B5A9396E5A83092939272EF4C965E293DEFD1B595F1526EC9C276CA444D823CF9D7D154BAABBE5E9BE7BD3FD7E5E406D6585DD6C57D52911AD52B855A3B85F7BA070CAC6AA2673991A86A866B3CA0C2DAC40D59A986D9BB06B3900456EE931B528610805C568B889F815F91AE0420981F6A3620DE77341487B8C9358261ED5218473DC2D14421B8964C2C6A8D84E72BB60FD8AD658B9F8A4AF9651F44E5D11F22155D80D8CDA88E33AF0E2E4E7EC12CD9DF71C1DBA6B275A8F897BF184CA1C0016B6B41E62E5F551E90ACA7A4075187B856C7B01393917F695BC033EB35A91F2E6DB877966D85CD0ED99C8CD96CABADEF069977F3B08C0DE647F458FA032C6FAEC523FEB5B5D6A0EAA34A541D8CC015AB698B6C0B5A6D312B45CE5F1868BBB8F9E54B2ED1DC039B72CCCBB828B3299FE381453C4DEDD63CB800AA9E2484EE34C6A97F636E2A3D33EF0F8FCB13704CCA940D4D1B1BA4201C74A4D4694381E0C8827F2683296DC8A194AD8DD58FF4059BE3D50637DD20026E38222900E4F09A2E3291E0651EF1A405BC88B46BBFFA0C367879D7711B661D6AA0ADD9A23B45442BB83D68E4AF3F77AAFDD2CED9BC2E571DA147F8104AFC933A661A6AD6F4CF53AB687158FA1231BB151B163FCB79EC996506EC5E0D7112ABF3F30E2CA7249006D9878E1B44D93030DA9B90567FBEA8036E5A81AD541F9DD65EC39CDCD81DAB7AF9706A0D68B4C22DC73797F4A5B5483FFCC7CAED4A7B60225833786115748B20B0D7C99FEAB95C5A222D6EE59D7FE44960DB17A0E64460D11B3538284827C8FC1538186FB32A2EFBAA005D052D3226CEE46BDD1A2EE3E8BCCE9711349FD17549ABC566263D232D229FEF5D75389B4892AE4A43AD933F4C51B2A1975794903477048D18BB4B95FD8F5A085579BCF79BAD56323D72C3E426F1C006E9723B27D738C2A36F458153801FBA831DFF85CD1F28E9ADD4A47F019E4C8AEEE5ADFAFC545F7330C6E63ED73584EB63657E6E721A981DC293B68DCA16D43640F3C27ABA5F65E78816A8EB840BC07F12CF5E349CFA21455E7CBCEE6CF58A06C63ED5FE33C8537C9F358114E75A5F2059896F4A3A6923373F76DAED2170B63EFC59EF772E509A61D939864F2FE61817D5F0E48170DFC62BBDAFA50F21CC54E68A3AB1B3D8F5F043EB40FA27DD59447728D07AA38766824CD44E4249A75A609DCFE1B5A1482AFBB54C6ED69027261E4B405D801E06F5C8E51E0B28E67925EF919EB960A63E47417C5427001365470CFCAF2EB2DC52383B3025B36F53FD8996C89507D08338953D52F335888609D2AB7E6ABB402EF6CA91D41FEF1681AD90ECDFCCD67635B104E8EEBD8DE18BFBD45007F6F902CC581EE42C4ADECDAFE9EA46ECF29D764F7AB9778FB08F8CB737DF9BEEDC33CA27C40E41580D9F602A7C9C21F5FA1D2CF048FAA99EDED4E45C431BF302F6398E878730F9A1FEF92D65D15615B42D52935F8EFDC88DB2F468AAB03D2A4B2EF1729B755D5E47EA318DFB99F136F173B465B665B3D16CAC577A0E09B1B604CEE0FD3FE72720F01FD5B", + "sk": "B8DA2BE5527FE7006B0B4B5B4D90FAF13696C1140701F142E38A7798CCE6B3BB96BBBA1E6D12FFFD30F9A9C2589D5FD180D8DD5E08E5202C7C11BC2FE76A1B208E092FCD18D1F821048509579B8C6846CA5E79E7C37C316C63680E49971CC591F379D2F2C23BD456BDDDEF5DE5BF759679C028894EA834B7A4586D6F942306F7E3102DD210400A138E88C4691CA4292403110C356522892C4820010B446AD9422C23C469614430138411CA466112B32C4C1882C2B80D0A9808CCA60180904D8BA03010C364181972DA362113396240068500080C1A328920316CA0B22851B68008330920C74DE00251583225493270D3868C191550C0320411094424C148222282A4940888280041C88804B96951A42554088D19A28058287060084E1B142E18070142480103028DC04652C3B84D110689CA163024002999426900C8451A252DE2082881826090C2655C44329B46665C180411240AA2A029E3068591A225138984E3001059A02D90128C90A828188910141744D426692330602399200238449014659244104C80708C908563329282086698386C214612030351922465539861A3464923374C40A024CB302011A06191900959C08C98426082428908204C1BB865D8987054844922C9409892040A832D2497254CA48D9A149164A40111864D9A2420482200A3363221C2300C178600B40411344E14A0111CA0414A8628212570420229D040291AC824501208602265CB0445D8B2111923621226694A48459B200DE3860182B004D0A0881BC20949306522403190388EE14028114102093465C41000DA182140A825238484133329140540248281E4B0091A43005402421A3986D04244D8B66154249011A1510936500C150C5880645B1669E3226A141782C3C631A41208A2060850988861986DC828665A322250C061203144042624DB364DD42421429631C08469100205DCB06C8A926981024140A0418B08886330409AB6498B0871E14890D9126A81344122479113024509044EE0968D0012859C380164024099C24540340E12C90910B441219825048581232430118829D9B228A3405244402EDAB6899AB408C9C890628480DB988803B488000865C992280342629CC231A1086C0BB82482189064B82118148803172540B430642811A1306610A70DC4828C8AC4491A322414042291B2011A4446C3987148246911246688908D58302C51B00DDA0261644049DAC201908240CA284D14434D41C82D6338309B866063C22C4F95BD47990D818D83D34D9E2413EEA5D4CE2063803CD299EC3DB1940FA7C362AEEE74D070A0CE30B49DA164FB45FA28C20B5BE74843D2F0BBABEEA745C6C2A88D78850C9DE6BEACE80BC467F82A79D189F7B01A7C602F719BE9FB3AABE740B4F8D070B7EF8D43201AFF4EF853A8D47A172C7E49809CEA38C9A66564F86EF038C8B249047E62F1850A9606AF632FF357F9E23F427DE017978EE1C1C1FB8B0CF5B1DCEC63CD8491F7377C77FA3F39BD882451241D172540CA7CB4E68D7662D381EA574ADC69F817865B094CE2D363F1E20B3EEDA731E25761EB3E4586A1B1610FDE20596C289657D9E0D5294CAD3058C7FEE81DC7D7E0E4475A6013312179B4937C4DD42D443C00B0F4B5B8D08548463A9E1E6ECC55127504E22C97FCDE23B06CAB37A1641FE7418AF904A6FFC432DE4631AC47EF61B57993F928C0F37414BDA2D9148B92B187260D482D9E6F22D367814E604BDA54582E67A47216DE32780D53AC49FF9418F4DE6306CBAA77E27E8FBA6FBFAF434F2A5046747F4DA99EC4CAC04957760EFCC3E2D0C8177437EDB18A02446497CB3984986E0596ABA332BB9ED7066477C7F72F205243E27A4F2BA03D35A813087D544003CB044B66B8FED49E4AAD43FE1C485EE402B288016632349997B7918AC7B5ADC35D8B37E73DAE39C4FEA2AB1C272208730CA52508D5FCD1ACADD0CF6ACC9DB0A52887ECED72BAA737C104F0F113D579EEC6D30F7BCA85348A6E5CD188346B65775C17F7AB26B8DC98A04CCB70EC4ADEE998C183B28664EE588DC56D0E979EB9DD0FC924543442E420FF82A89BC9AB5F4746326D930ABA8B255D14218F3DBD6E73BD175E4DF17419EAA96AEC8AED6E177E7DE0872930FB6C6676F3AA1428496A8166E932A8E5652BA5DA33ECDE76A06E850FFD7732C26D1255C21B96E0C7753200D4B3BADA9B44947CC80365F5FEA14C27D150258D0092E433B806B6F113B6C99AE58D1D1A810E4D0C1053C2F7064D7188DCE620B2CD2E237959FB0C535DAF42077E792EEED6FA140A8C7B94CC263624AA42640439792DA2F9EDD6E7F0D3A8CE9A1B27E788B8CE7F766FA078EC5170564CD7030C51C5DF95E98575881F48BAAE04348DCE9C226DAE0DFBC65CD3A966A2468D588C26EEA83AC20DA0180B6973D1E93A58BA1D52B59F86872D41353D5A02830C48D93757DCEECEC1C3CBD493B8298EDB5EDF0E0BA8EDB3740337A7BBB29E4E0BA3217B650211A93DD6DEEDCDA76AFE119817D3A1244C01CE8C5F5DC3E093CCDB0092F2C61DAC20D62E0E2B178950C09B3DE26B9FE54A4A8C3CC8CD5DB06E2BBEDF305BE910132CC11668591BBD93F4DB3EB142FA655DB1DD175208D39F200BF07006D50C84333FE0A0958C472A391F65003CE642FD282A592EC1FD02870A90C2A3D1A4409B818DAA8059FED19A6FC3DEE29D3CD7AF8A14050967202CF6F19A82384645BF182315A5544361BE84D477A36AF3448885BC09AD975CBD1094DAA8AEAF9E315563ED5B2A24C551C771E0C3399EF9B94A08EC4C55A1D9CC6DCDD01D7D00C7D44B7B7C8840263D6C85AC5D632ACDA4B919EEA53929CE86D7538772DE028408E555C2417180869A061F6137F6E8B95127A25ABEE16FE1484E6C139CABC5553DA4FC024E89B259359656B2F29EE21A0CF159DE30EF7690E27716167292CA76509A48B3A19639B30647778A6262760BB276EEE3BBA8F4CC4EA47F705B85A7EF0936FA8CD6329D223B60F32EA7CAAA5F271E65C1E04D884983D57A271E39F907CC5162A48CEBFCF0DB08399A6EF2A39CBBFACD2A266EB88FA699530572EB06002A0A42AD05608B592B83BECB526D650ACCE51B1862DBB5B4F62D489C02FAA95F6EFD55BB3C8D522317EF28ABCEF7A418824B9BE8AAA28533F93FF075E512E0460156B4F6EFF87CE7C021C18D4C7307CA35F6BBAE5D5C0EC7D2BE496FA3B1E523EEA57BF97F15549F541CE042631BE5162CB27DF5E82D892A7AB96AD48304D4893D8C6B0C2ACE3216F026C9F25EC16166207C1A3166C4A3B1BA89B62A8456EC4F7886D2C7CF6A262F2DBD3C6F82337142D4EC52DD419EE9FDFC42BB9BDD99CA169AEBD68A38E0F6A32D47FA94CEBA5DF11D0218EAD68D40AD2BF597FD2FA7E01428246170DCDE96215E27B4598B53EF6C51A7A7418E47FE378AEDA2CB16A42F663432C23C514AE25B52FECCAF7516715269FA5831FAE49E935643F552521D1579DB8F066F929485D1451CEB659306F7E0BAA1FB1ED36B00D180E838FAFCD42A1697A70C849E3E9B81F5864EF290F27A5C9C4064854B9CDC30119A028A5A631A3FCDC5BCF30DA8EBDEDFBCD9D9A52207C8B3F5109EA0479F" + }, + { + "tcId": 4, + "deferred": false, + "seed": "6137CAB1DBF57A5CFCD0079BA87FAF2C7141EBB92DABBD45FD8B478D24AB8946", + "pk": "0A8EF5018588CFB167C4B2E537A7B1E27B7E45391678942515986E2344D0101D116A9201D6CCCB5360C8C603D8ADB7F0141C25FE7253A77913E3AED199FF230ADC79187E9ABFCD5E08BB7C66BCC1BC310A3607F1736520C26C0630226C1AB0227EE8B9C9F657FA1EA090DAF837C91BB0C4BC3DAFFE1ADE030F1138605613C2BEE98A945DBF68AEBE54577D9C33AB99FB8151246585C4A3221CA1EB9717E8B685CE184D6820AAABB578AD384AEBF528E9E3D82D624E5ACDCBC3C68365CCC5D1499DD939E70ADBCE17B65C9B81A13428C1D8D20BDB1082103516186AB6922CD12D2C6686055AA97489A50CCD1F7351116FE06E6FC4F4C1B8A89F5D4E9B17C16351B6AEEE0A23E87F9CB009A1078C192659C49B7C99B1C7C74EE61BC4A80AE2FD5203AD0CEE5B54AD9C46411EC466CAE10BBDEDF6C2937E33D2E548EB6AF9DE3B0E427EDDCA94EBB0263A7273E37F53610062CFF9B3D079966F0C0BEC254CBC946DB18B91E7DA2A9DD0551A1D68FEB9A29D7A3233A51D5734262294E65C5BF32E2CEF75C26D693DE0A5A3BBB5DBC6DBF861E05E17962889D57A3AD0E21C1733FB0D01CD102F38337DADA0E6F612BC1C686D19B89FAD583D580F088248A672670E8948FE00794C17A47BAAA69B8142F7BD5F8823DDF05FD2A8F113FEAD12483C3CAF1D5217529450047AF883C1F63EF9DE56C41B7BB135FF040DAA9DE92905FA33AB2A18DBB01ACD22D862EFF06CD30DA86447578FE01CCE6BDD79F4AC7F0B0F0A7F1559D1CDF558BFC1124E77BF3358D8DBC465BCFDF67C5198A374E14CAED306489E6AB16AFB37BCF477C0A4E256AE502B25A28659ED776B55581440C466C586C3C3F95EA97852B6E334036986487BAA1B470228D817A64BDE3C1FEFFFA1BBB24E6A4216E7B06A2AF20D3F5AA3392DAC5D3D69C75D110706C90279FD2ECD68A2E5F9E7F20601D176CA30CDB09D982B239C55798BFE7F3DC9DEAFC2C5A7BAC89F25876BCCBA09C0E74D63F63819B2E5D3DADD7AE806B1B4A498348124D1BD6AE50CB6F32F12CE1667FF49D84ED9C7204D710984778E675664565C6A0613AFAA47A8E5925934C0D834BAF464E65F209AB782B87E2018D33BC686528337D180B7AE8BC95BAD170FEC9BCB878CA1D87E1B7980D0EE3F293AF7E4FBFC3FC6A46E7E69F879B396F41102B4546808389F22D20A472D5CB7C5E42FE6A6A4C0ACE61FB01BB6E85BD11CDA18381BA81684ED73D9491DF1B7EFE73A95CD8637AB28953CD0AB07BAA3770A372D664E60BB9765D8FAD605D7FFF0445AF8D4A9107324BC4DCBB8C4428CE7EA3DDE72B3F6E0FE3DD70EDEA33D8B794FF5EA1AE63633DD55626BBFF79978544CD15330F391985E02168D0D9031568484B724B313A1494EE3727E6AB0711F8AF74A1882737AE9873AC1F2A7C8F9A79876C2B49FCC217D6F1585B26C85843D1C7F4C295B7377EEFF1EC814ADC3F9067B2D3892E5CBEEE5D704BB5EF70A5561A751DBBD6C8B1C5169A9FC72819484D6F40533181F2853BF1696B080708940C936B1327EAA593FC27CE0ECB8936443920F818C393F7A27913EB9B5F8E1EC722D159ABCBFB04E6650C9D8E2A91FFFBEE965167D829F598EF1CE3D48AED0F5EF6AA70BDCC775CF00A901AFAEB2E0CF1AE0A6E41E8ECCE9D64722DA713135C193A8A91D2514B1C542BC0D86DD7D1623A1CCCA548142D5F93AA2B5BD35E0D3322D126E245C802E9E508AE531F7828B55ED6FA81F8236F3D97F7AD05ABA04C6FDFD98CF974E7A738090B2875742E84202F803316DC71B8364655062D67C62980E17396FAFA25E95BE5BB611D5DADC3E418AC4B2D471F3A0F8FF7DE57D1154A56D", + "sk": "0A8EF5018588CFB167C4B2E537A7B1E27B7E45391678942515986E2344D0101DB66137ECD5C61F7FEE7356B01237421B366F4E40ABC87E91E8A99B0C90858E55000F395D2BE88DDE694C04D10B5407A5754993ED3C59D8E530754D66108BCCBCBF3C3BF6E965DB72595249B482547BE56E8D79DC375851EB3F6A18544585146E0C42720BB55163800DA33851213264CC94118A104003150453880D034431244150D9C4710BB12599B244C928288248304B0628C0086D19254E0149310A0341222225999604D3004490362C21915001176511442D6032460CB000D4A8288B822CA29648402806CC3832E236011B230E040272C2B4691AB291132605E1A80093A048DC220604140C49460D002226DB1060C342498A3266CC36201834018B461262A8709B288C942652E4080C838884C220419B38290B147023C84D4318880AC9051434801CA200A2C82D89B64D0C488589828419C761C044510381054320329006109BA88C8084314124310CA04823A2305C988D21474C59040588A004D2388ACA420D0AA368D32092E38201E43811542271924666C4A441022181D3028D0C366609B590894409D04802591249D2B884081644C9283092266A9392285204440C234649C221E2C04190C8105AA62800438813C8011803894B30726240116124682226325880258102928AC6854C4811E1980523C868E3480024026180B27112414548028CE4100CE186281A85050B498083B4890383652445611BB880148491CA1485638249CAC48C9A46268A14884C3645E2984501384499164C13224D831092C9B0700B0101A1184E8B326C1C49865A328221441293A40D02056609B44DD2A245E4C62C501841131011D0A22154000A0C880509448C0432720142682448209A26824A42024C144421C848142766CCB02D04C065441265CA882D23B880810464092831D3962D64220C00C9851CA561D4420544983114862892340801498D21B128A4368448B48C18900450B6490939490497894AA25101464A91B20C0C232E93440A9B804548886153B830044831DBC469A4C4519004504CA86920108D60286CCBB045DA3688C82029A384292211060BC244D4248562082A49A221D1184413B109E2C6108B0408138001E44471103000CC120A00234E90322661A028D216710A498543884063486DD0000C8990690C9248D284008204611B4649644050D9286818091151A66C80264608144DD44088049220E2C611492868D48210DB042124C0404C1723C8FB9AE08581D3EB7AB76CF8C3E81B6A07B3CB9122962BD278FF1ADFC7B64A9BE0F847C2567BAED7F0E9CC8C847F81131152B065E571B57300917845264B0F74A4F1307445A0CC7D959DC701556841916A686F6B018BA13DC71B024FC78BDBF7A3C7A8AED43147B4E2848D0A3EEF92BA31543C805D0A1A7856E0CDCDC5E16C5520FCF39811A473D687A129158533BFF01C2E0D224E074AC452F292BE137715CDB8E2642797146DA5454E04D61D24113D658FCB42309E181B33D57ACAF78D9B56FA9C33A77DE2BDAA227B2FB815EB39FFF8B5EF175E786E94F2A6F66C0D3B68BB4B8A28998E1150BE49FD46773D7C067751BDD27EB7294CD5F746D8251DA046F325062218EDEF9AB1B0B15730B97584D096A09175801088DB9C258FCF490399C5A7B61D3B61E94BB41059C543C904A3112CC158DC3EE7DBA410038CB92D02CB13B55E21CE176E9F7CCBACF60B37C633A5C29C049442050DDD4029A1FCCDD30CB21A740D134536E350ADA4CC4684EA4C0A5C2E141A7A377190F817AF1F88C7DC2A068CC86C4B58415DC621CCD4B7EAACCFCDEFBAC22CAD45592356505A80283B86E8A92BD2307F7F854A5291D3DB4DDF4A4F367B819CB21102B6E310231BBFD1FBCD5BFEAF30EFAB540C5C37F0D5528A21E09526F9BC1AE6D1EAE4E24B8A7F79480943DFD794623AEA0393BB227FAB291DB470DDD0798B223E60B5D712B1842699EA167ED89CD62C091DE95D95BCF4CAE6C066C538F280CA8ECF7F4B38C8A44E90A25CB0A0E463E28B7B26682F1F2E1573E2E829F00086F75E4F53396127A60ABE16AF1679DE3099FEFE542889C4293E6E915CC2595049E438DB70ADA6587F041A9AE4B23E4D63605B56FB835C219DCBD2D76FD92AB4B123F997B8A790986C24A80A797F998D2BD663C167104DCD4CF0FAE750813C371F35F1CD138FE57EDABCC63C044300699D4506A28962FF0A6A66FEDB79E3F841AD58CE1C3B085162BC500C3E11FAB50AB0D1B02A98FC032E46AFE3DC20BF8A27D44E5FCD177123AAF3730A414699CC9D405B216D4CC6987100F2619946254F23D4E8E6417B32D0622C6BCEF586A44856EA72BB10035ED9BC8F54FA0BF6E6B7B56EE903D123D764674690CF92083B0265F0B71D6552F4130D8C086B079FDB62E9A390BA6824E611418592B51A5114BCA7601A9EB7302B35889533F2DDF8AE6EE315446C33DCD79CDF102285164DDBF3DC1DC14407D4CA7D594D397716D1A421AD444837A891D45FE2BDD58DF86B24724AE9C06070DEA7B13B6108154306BEA4810DC59719BEF6D189DFA4974AC39E64C6B37D3F2DC7621CB64DA44E514097B1F81DB5876C22C8B8917047EB32DFCE40DA9E45C67B50BB40B48665AE46FC306093EADCF46D6DFCA58A3026341F22BED8218E4EF3567844F2E100608F78A7BEF7780DE849B5BB6BE654AF024FC3566EF46CDDE83535C2CC539930BBD71F10163A7D9BE0DFD5712F93298E7F4377F749A847F2661EE8C34D18C59EB96DC49915907CDD4C691DB88D5E4CA3955B37AD6ABE539F17FFC0F7F306EE1EA809CCFFEDE766D756B6BE6B9CFC9B8549B0A385DF1F84D4661BD1E3028CF47C55E80F0CC33D316DFFA893B5D23B8DEB75A2232B124606FFB6E955608CDCE69E9B6EEEE660AD9AB3FB5F246342AD634848922716CC8DA15CCA183D7B17A76FC2F4F4B27102134F16AD98BEF6D13E2EF43C0E76ABDC5B5C57F23919FD3A2648C3315D0B6496EBD5715E7EA516803035D47C6998CBD102B28829AC2E9EAC2B739B71EAD831790E8E94555C5C05D34F9004C48A9AE1C48853F6ED1F659FA34EC6BFC116A37789198B64B063EA07D45DAB701FBEDEA33197143FD94D6B994002AE87D68836F7F4366DF3F10467514C36AD8D447B65FBB42715920ABC5C92C1CF329D245EDCE007E8F682A6EB30558FF3E03E6A5882900AAA3BB53899DE10E190299450E3187662074402CA9B5E8CB0F975E2B7A617C8C913C516F90A72DC5C3229783E1D4D6CB371976C52D4C998FE8FE8F376AFD83D7DBC2DD34E6603C9331452C4DC61EC8187082422E18C5B92F6B31E9F6F6F6991FF48BA8199BDEB3BF03379A5C5AC609A9111405C9E30AF475458F7F1F949E3002DC40287BE3BA70F5F9BBB2F0308F462DDA59E3D083BDF28446ED29EEB760C75494DFEA1E4241E76E60B4861503E281C898C0F44C7CE9ECB45BA41DEF7EAC785A6CA9073F639D7435A8EFDC6744CBA2F3772CE3E3383AB8EED5D0000698C002B269C9268C459B53DE9128A70A5549628A026FB80576F5FD99665A400A693AB05531177EF58FF962B961CF6ABA2C53782DDECD67ADF29142B3D6F34" + }, + { + "tcId": 5, + "deferred": false, + "seed": "B9E2F48349350D30A5342783C915A608C905E0DA4BEBE2067FB62C714207C62B", + "pk": "F9D6A3AF1217A15071BE92BE929BC3E6997BB8A2B75E7EBFF3E7E27735D8625ADBC63933DF6244EE6272759636370731F21C2892D94695A7DEF28F5C17CAC25FB09B253E2AE787630CBCB8EB255EC2F3E4F8C5BD48B75C50C829CEA6C289535DD500843CBFED5600D1764CF8E624E9CBFB4731FADD11C063E521610BBC656B4E19678611C32FE3F583D8FEC7D7A9155DCB999FD4DCDCC47CF45C35ABBE829795C31194662EC28EC54DA469188EE1A8520FDB60A2CCAE5460E0BF5FD999764C21FA1C501AAB111666118F356DFE4F92C05DD73F143225389DF6839E11F7FF7112B22F4B5A04913280B4B151B532A4CA71981F79E1134C353760A8CB4605018C6B69741E5431296213544F26D3951D3AA1299550C0AC23DDD5422DAD7A0C43CEBACF6750FE211C3F10958ED0BC70E50425D40BF9F4436147ABA3B8304199AA01ACDBBBF026E3312991F06D9B151A4321A46426D1349861F31B0223015E676CEF53EA4174BAB7C210D5F9E9B51E7FEC4F7D66D1F2BE83F5F6CC69D34CE995C6F8441D93674A1EE1CDF38D0B8242AB68BA53E44F9CED5B93177CC2EF428CC767B5F647AB314E7BD575D73DE09C428EB7AFA05F6EA8BA44C10D41FCBC8B404ECFE6395732E151568621657230013B8DD20279E87DC0F76CE8E3783E25699544D134F95B0EBC40B90B566724521D564AC5783BB9654F5CC699D0E05AD90A43792778D6D6E302CC1F6129BB83D2AC12A7824D70A55A9978657AD734ADE602C72730E0074A329172C8D0A8EE6B727650763BD48F6D03BD6ED5004360143DB51B3E32A35E27BD7DA81EC6446365379DD9076865908A413A05674F185465629917775EE1F113225CA8E3F09249C3A9E6C9E8C011D4F760EA6678B0E64FE0FE8CEFDB0294C538D684167A972AFF40B83105296D6454A86DBFBE4A4552E6E13730ABEC31A9888107429CD697B452BC87D3A16BE14CCAA682FEFECB57206748C8DA23B98198462749F10A57F4D0F3F417FF37F0A67190298B617DAAFE94A9DEB28606618421151FB5580EC58BD373879A254E28FD91E68C7C0FC20985A2C25BF169FBA1B8CD8EF48ABC8E18D322E666B39387652CFF9440DB5D29EA56A5F869E83D46FAC6D98FE196CEFA584BA6C82C0FCF6FE22A091B4D5E8E6AECAE31D75135DCD51F48DE296680CE2744325EB13ED7C2F27E3147DB37270A5566E9B95735E9CB267B46A9ECA3F64A0A04C1B0CC6AAE181E9A912797F2CA9E50396F33C84A5BCF10C8F36DFE6CE95DC6FF5E0C61A8C7219CD30FF27DE15E19DC6CB41B925FB31F41059B0B4A07A9B71ABA88C03A43E0680C782D0694A1E0E9C07D3451638172886997AF4BC2A3154D50D5A46719147BDD6E5E08CF1AC858BE26C5BADB66DFAF6DF09338EFD2713BB87820CCDB97C20539C5598CFB50FB0CD44630B6C92DDBE9A5B4DF85ADB25324A8CB1D589787FD1AB835DF3C3D5210DFD80241A547ADFDD53C212E9D2A58AEDEC473F9D75B47501829591D11E45BDE89646FC45C790F475BA5EADA393B45546B254460A9ACC0114B062A19CC693A4154B9855B1BBF01B0CB6179AFABA581AC3703365B1FBC47432218105221F2341014ADA6753A1B2C6B3C0B05B8B1418B2C1F7E130B0F71946D9079A6F50270453AEB750F64AA2C1DBE913C477E9262AC59A4D28A20DAFE13F14653E85C1DD0BE510468E05EE55836883FE4DA3FE7B7196EF5395C9522721204F033CD465667F918C0C067845946C0F6612721D201D809D01A394F4060D8F3CB0D2E68CCFC657EEDB4F1ED6774EE61B8FAF95F0813BAD1D4E84FFA49EA487F05925C7FC987877F389FBF2A048B67DD74C5021C9246AD0D", + "sk": "F9D6A3AF1217A15071BE92BE929BC3E6997BB8A2B75E7EBFF3E7E27735D8625AA49409355DF15BF003E59EC02A3CB3DDE25B5007618DD08E4199EDE29C2C8646931655E354CEA10B194F599F289A0D28799861F4E03270C94385C7DD3703382A5877CA5FA612C6B24A535A0A68AECC7DF043F29093D735229B8BD8E4E0A5669512A6001BB60C9B2249E23006E0280CD1940D13B5404A444813090C9CB48898C02CD2C020A0C6412002024A04454120602188514A8061C08424509091D90630D3A00DE2C26DCC249264126180188A413400E0C40D48824D41006210082940B8041435009B120162320ACB1468521805499471E3304992C844D20466040241D0C224D3440464A8916438825348094B444423000D18C72503A65189B68CC096891AC1084104211A060CC9464C4C90689C0482E2163212424CD41600DA34025B16260AB6892021048A36084944041AB3805BB29013476009C0814B440212C364D8486403810991008810C985DCA444C1342C589228D48649A3464A4C406D6234500C312104C160230370A4B42914116123872D4CB48888282511200D0A36115308204024215098400B312288B0648208821A4592504865D1364520B91089280AD3264289A64048B42C0B3301A3304CDB1828E3846990B8092240319A38318CA06D89C64923258892C28DA2484603176158904998120462C08D00931062C48C09390C524681022602D2345111120D4B4065200110D22629981245A3B22012910912A92D12868DA02651DA1081012690E2B80D18C64D1B8071023240DB982D540232A0987010394D9BC60CD846515C86255A324E1CC4216138684A8049E0380653B0519996300CB64CD3C6489814900BB04D50942113C30022306590B041181046C1C62182A0081BB721229044A03612441624CB30490B331051B261A2189150B60410489098806C241990C8864889104E10008D64462CA4107113358CCBB82C0CC52450400A58266902C48401018CD4100C50C28023146409369123C50D1C882042A62521A6044B3270609868E1442A0AB540CB20869C160A0B492009C86DA4B6051B3206DC06920BB32CC38608E1B04CE424848B38620A4869CB226492266623853082800118384C0CB34124900CD9C0801926201B174090880564406C98B4905182312137292430802397251931029B869103A32C5322124B188620474C89C48C10C32882A64D81486003A74118450493304601C72DA2900019352A092611649460D5116559D1F22734D48A42369CCD69DD533D31681CDDC2475DB9D6C47B5A0C69120726BF99B8CB301F13DB214C3AC2CFF521D8C4B5C0220723939D88460BC4CCD8F0AE19AC77AB0A53159119BAD1437E6523ADB59D2A4A607E365CAC070AB0A58BCA1B82C5C479A82CB9FCB3FB8FE40630F4E3258F32A0958340BB77F75B166C634E8B2A09154A03101EAE9FF029B676B6096D7B92410CAC845376A57B359C98A29674D662506EB5E59AB09D190A9E1B14B93CE758333F9768AD3149D0A8FBFF84612FE01026E4A9A73BEDB3F0679E65C0E41492AE7622A5BF3947F2B97FD7D9A04821A1C5A09B3FCC921B4790156DA8A7E1D6C6C1C7DD18C02EF391C12852294280C516A722F53544ACD24FACAD98975144548F47C0B1DFA82126B27CED004EF36DB69C3EC7E7AEEECA198925DB3CEA49A1FFAD0C9CADADFC88BCD1769B72C267A332F2EADE532572B9DDA5C877EC67AB18F4AF4F43F5A1C9943F30FED7D3DC818CD3DE31A67B1087CD5B090D7A6F9385F00B031528A529F151064212E943A985D87DA39AA8E34E91AE1BE6755BEE1F5289E01CA4729A7A93D4733AB91384AD738722D64EB1D3BE3E72CB069C68970A1E9268A58BA9ECC7C578514DEBDC4C8F25F6B092FF6207FCEEA8F21727A226FC45A089B30A7FF459732ECFB7D16300363ABAF4622DA67393465D31D1C83E4118024332AEC43A13C4FD64C2FA2F3A031C5C63B371BD1DC6079D1D0CDEB832F4B10FF5D449AEBFF92E1222277854A53636F688A6B93A22B2B311BD16D62741C56D6962F591AC01DFD2AF9FA59F24B4713745E326F3E593702852E69F0849199B821AF8806FE6A9E545FF011C7064A8CF7C234E1652262C3E7EAA0EB8A79AB0D25792C1EE706E157CFC07D1E6CC612506CFD5CF49B9EAC7DE770F9A1AD98784E2F097DE07F9E7A44AD1E0045962CB7FFF6CED8265A69177726652BAD9A7DDC78F807875D4FD0A88B6233157D715F3EB77BF275473D85E0639C9A5B78C987009DD8620E7A4E3C0C59BAE9FDAA7F5F04A657FBDEF7DE2E7FDF614CE60F7B67B8FD21D4F76C30DC41E828169EDD09B345E0ED441AA61F5808EA458CA111D930A9E9FD7A5A3FD5B977F951EDC959682FC1B0B93F1D3188D6469E128DD3DB283605D34E6D79AD2BB4A689CDDAB9965355B08B19A8046AA369C3DBF53B48BF0A41A9ECE797B31DDA1F4C3A54245D5D99173132C90064078D240B85C9CDBC6BC864254448844564BC09552162E4A5DE16D6515DB34535FB35F3ADAD71D9C95FB9CE07D194E902D596EF91520A0DBB692D7D495ECD1B3761AD973A361CA0F15D08B98F0606A876CEBA87BC0D09433DA0F839CB4B1FB48796B35622874A5F187EAD7E9169F03817B1C013E4F1AAC968B01E20AF86504FE1589368F606A05BAEBE5009FB5296737FE40F026C92C04B995A6F299FB7503ED49FF2C6E94C650F08BA76A3FF198432500F72622E41E5B6C5F6795787849FC480EF7B54698B0878B808E083B2042903DD9AAE12C7418AEE22798AC2E115721FE76DD7C8187AA18FE3895965F306B98D015AFBDA6DECFB3F90F3A4B2FECD757E0671C2D9879B1CF9A6193DD9467A5E32B716C68B4F54F8ED5B8A775EB826CA3B0C98DC0862E59540F922EA94D9DE3F1772D92554C6AD3F4D137E102EA6DC8C42D1A79FC7E15F03E92ADEDA5FE928F50DB5EB8DA04F54BF632531148A9B6D313A088A79CB107FFD0351AD24BF504ED12F6313B0CD00ED0652829DB691FBE106EE2DB3AA529855D429E3971E1E55DFBF6D73A0DEEEFCE501E51671B928FECB31600C3A9546BCB93ABBEC43303B565B6012B664D339DDFEA016A00E3855CBD9915A51A85EA82FF553C4B1409DF26D6E2958509F0B1B03667B78AEE5E2E5C3EAC20DB7771129F7F31D69EEA42631C3B5099839BDC6A6FD821396D975643A0FF68187AECB2E50022CAB078A3C0FDAE79C5328A674B76272DBDD1D2AC6A3A739EFA7093100ADB89BBE855724B1101E864C47849A25058DACAC3D2CDB42C107663FB03B93DF2BE908FF1796C82F0DF4139E9090ACB41D85FA7D209F24F41C5B89435D601904E1220B60CF96736A94B18CF168D6518E1D2BCEB5ECCE7E96BE14436716E0B273E2FBBC73BBD33B45C65468AE78F7C8DCD40870604FB0C49418A60FF8ECCE446B522CA3B623A9C239A746309F11EA3D5D569A92033572B68BDE7E6648BFF09235746585DA2A72BD7D24FF26FC70A1D0382C834E3C31BEDCA94D9ECB3A8FAC4F3DA824F5BF1D07B36B6E18EE3A0891FA64DC6B1B2967B2D0B6B0D756DFF9BC18410E88C2BF091938E23EE6D56FE9E273469B6418C3FC0FA709AACCEA48B63" + }, + { + "tcId": 6, + "deferred": false, + "seed": "2241FB7005D1B26A1735FFEA5186D08950B4B12CD4FF51BD263C6B8A2A2A18D0", + "pk": "B3218E745B2E6108AFBD6D915A1F2EAF1EE899E7E3E64BAE049F71C032C724A6F7050C48F25EF529F216D10C77EA74CD7A153FC1A1F4157D064A6681936D288DCB085C310B8B9134C8FCBCF9D7F6CB0D92DC58F4CE7B0BFB61E6D9FB12D395A83D0A457721BE62555E27F87E8084FC9D2B8F460AE51FDA5B49664439312290CEFAA906A0B9D253509E6C3437947C03AB2356668F4CA59AC7C78DC0ECFBED0C226E335DF8E4EB87548E8A775BB1E5AC92A30978F136B4D67FB71DD4C005CB4BF42B8CB7CBD5FCF475887959C131498EF72B1A52A80112BF6FD13AE2F2D6A657D25C3DC4D58431B8F8499C40CE89F528551337DF05C102DB12512657F48462F4A9D009AEDCF8A1F0EDAD1C0BD32BBCE18DD569FE04BF8E132B7301CC84CA4D0879DBDBACD03E524D147C2176158193FB98A4D4386D2B17963DF59B341D04491621D191214CFA2CCA6E0781FD70D37150693C4C1EB70DEDBE56DDC7CFEF279F0B54627FDB2756025C91691446A2AE336F0AF3F4B845D82A643C3901839074F5C48FFCB159F775CB26AEA03E0ECC8101A8E46563A56A75B797386BAC8E7B8507DFA201BEDFDDC3AAC6BAE10DD1D969A3EC65B4E26E6BDFAC613B4D634559A85E9CA7EB3FDB1BD3AF683D31E4BCE8AECCF5513C28526A2D1543311504B21DD8350BC3C349C5DB7CAF4627B9F41F656723012876D8E2C5D033771A9FC0E95E26F4C53326D527D2CCE21E05E4798885B569C48C1F815523A1E221F61242600A05EB86BCA6950A37965EE4D5C969825326098BF4E004B9EF89BAB0F72D4C93693DADDEA95374E64AAAF06A695234AB99C87FB8C0916CFAB816BC31ABF22AB0905E5DCF4FF4FB5A3294B1ABAD63B5B72B339E571C9DC2660DC462F01409848B4BB30A186F0A7A51BFE1153E98870D0FCE9ABD9F7931E39E7C16681CB6E1D42E444723D40BC8F461FE7599173BEAF23EBFB8FFF04C127CB6512398E440F9664BE694D84D2889C3C3EDFB6ED0C806026D80E4069F6BE6A59D66C165C9C19BD4D2B9424B7E513EBFF9A9FF282B94C5DEF162929147FD42AEA605A9370FF3DF01504A8E49D11D31F5918C970197CBB6C65019B7501296E69DA02129255B5F33A8CA4697D0D08FEEC2822672CA3DC5C04F803CCD5D38A838E1FE3BF211011F8E23F7FEFDC931A5E615C2D8F16732C04C82561809C0F52C83339C12A097666C13169FBC6CDF36D583364922DF573D4C6F57ACAE8C09A40767C6BB3762A577B111F8976620410EAEA204159E50F8AC96FDBA17002FB30F68A6BF8748C4BD4D67321109C79EC911A3E9639376207C77132348F558CD69E98FF998B6B71760F01F754A4601968D236A4AFD4927F1C07D4555758335769A614411D97E829C62F6A366D77BC562EE64ECC96BE33FCD1E75B5C61EA2AECE89B217D4302F76056803B69574590E8EB51B64E6B2EFC20631AE62E92AF25511DEB499D1748DDAC3D7DA5CBDD039D8114CBA4F4EC9E93F4119209792D8A815AB308E3BA61D0547A4296FE796E3A4F48D1CB564140AA23B71A51CC7EF2B13AE57C744F08D2599B78627DE15CB87174415EC2F64B70C4DE11868B534F66F688F4C2B34CD552947F86B4DB152AD5F4AD60229B60595C14D0A64D7A573079F825E85071298660AD63FCE58430D4C928DA012926ABF7C61382DBF19EA7FF36D2F085275877EFCEB6D7FD4B0A6AFA1CA72F7D18AE564FB7E23AFB99548DAE13F8D9B16FB320213D43FB1DD9C43AE437C992E84A0B977DA3FBECBD27E14F6DDF291AA0513E2644E943B702C901CD1CDD10AE281E0B2781C44932A661AF243DDFD644075ACEE5773A9C9ACCA5DBC86CBB964B63D3194FA", + "sk": "B3218E745B2E6108AFBD6D915A1F2EAF1EE899E7E3E64BAE049F71C032C724A6A9DED371058E6A75D33E78EF116E27C74FB9BEA75F06E750109E9CADAE7199F0EF40C4ECC6AB8F422FFE18683D84668DC2FB3FBCC7D8FAC3D787167A31D81F25F057DF0EC2460F082D61E6CC2ED687A257809952EB1EA939B9355A1C952952EECB9805E31250113208C0909010048111345192268D203781A4B00151446AD2A48960A410CCA6842131112288305A182AA014804C2465241085C2902858164823154218058610B220402282C2166222891003140008282E54C29164442E9930049C08489A262698140C508028D990849B2410211686221444DC42898A14288BC491C2B65018A545884806D4B684A38049430072011430012411C1B43053420ED41821483631DBA200C23626E41406222369C306811AA82918980DE2406DA12664D8B4855C226220096ACA44651294891836420C92691CA2444894491B83904B302D91020A0AB9118AB80061C84D89460A2441481891419104312128925B88319A164C121251CCB00044064024396689402418473243048DE1C468E1188401A16D8C08810B0046E0480A64A290C14832C3B2080A1626A09869233204C39225221662480629800482109564D998302203450416801203312417315418111BC16D0800485A2670DC38701B183293B868C9A64C444090882400A492501B991082082D24422993420608255223022A59A84019B550D9441051886DC994410283045CA6890A414501C58004848090A4300A28865C448C0B29510347105A1886D4846C02C38812062C934452101192019624131250230524C408692031705242445438220A14312021045B26481B116E80469251C24521364CA100320B36801CB100C0340AD4B2299188718838710AB0501C23522182408A8611C3A2305A064484148A1CA210D228329CA46910480212136CD3A26119B32DE1985012448018B9811A8629A30464C43085C3B01152222D23A180A3B029D38229A0488044824514C46D802031034329CA1226D120309A1266CB188059200210466A221544998084448240C12000504044C8945088466918A20400436963046601A608CB229283486D5B366908C64960C061C8B8244238409A84100B301208944080184AA22071DBB66558B44402992919B62C61080C418649C03224D13812E192894C188498C031DA3065C32044841286A3420C0B293063408CC422001234019B206C019300D1224E90240D5A0D7FE8388ACE498B62BE6C71353A86AADD7988649F6B1DD161073E1DA402F798D8BD1B4676D4C444730BC8F020B8B2FB0D6FBF0C68014A70B38B565E4C98C941906B82996EEDFC8EE174BD0FFC4150CC6E4B8C9DD41FB85D4F824143DAD23611FADAC021B266BCCBA588FE5D7C7F593DBCF0C9B33864D52847E3EF978A6A297B936C0FB17A899B2CFD82A3677B542D35997F6AE3FBDC25AE3727BFBBBE81A4617391E1FC1D25172DAC3484B0E9381A522070CDE8F340F0E34566A48319E0C090847A2C5057A200C01DB41E52151E0C999394C74B17F9C9548D51176DE003B849561ACE743273BB7C96196074D522F27D518F63F1EE2B09479050B01B95A6CFB2539BF4A640FB559943E5763978D74D0832C1E1C6F2A4E4A800DE10D392F1B86D0C77B62FB09CAA4039080D135F1EC200F8D03C9AB26A67F6CD6BDA3E94CCF61332E7033E30440289E251F081089FF46162C6D37913FC1B17A0C8E775B2D321DC685603E25804C86B78F0215C43A0D9A3B287A22811203D4B4BA5D692AFD54BC3215328C2E08B0E76B4C4D9517474F9F6826EBB41800DECECE108E1E340E2CD127F24F00DDDEA5257E03166AFAF71073A532EA529A0F20ABDF40002B0B02FE9C1DB7BEF600D0362B7EE7EE121D4E0E9C7322F3BA6C97DBD8A2E9203CA6CF6029B586CBF73A9A9850ECDC45D7EF6CF512473841E9E1409777CA1199E2D704A3173B62A444F89538AAFF46296303ACA38B3EFDED76E13D6893BA213C393E9C977893799988AF637BCC365ABA22587A4079210E5BAEE023C6CB000080AE2F6A0562AE5DF3A8A0606151A3E8F5F343F5D2E9C6EB15630E26F486D352F6EEE4D8FD0E9CAB28C7DFD67156F1093FC573D1A23C23F8FD5DF923EF519AA204F67B43E3C33139A62584A01B40FAA8BC4BFA2D2C177FDB295E6EC3FB7CBA29BD104F086A7CED1360ABB6717F417C4F612604B6FA730E61958E8B0B738821D1DDE6EEC9934CE165D115F474268D8950F6F661BBFBF4DD28CFE0658E39855DE27421917AFC1BF24701C0AA42B05E824B32CE9F19AA161CF14331F1C515229A8EF742FBB27BB5AADA0DA92BAB57F3FCA6016896AC9609183AA9C61D2FF6A53EE48AABD331A7DD50C2E5874391EB5F2FA6DD239C0177E08AB652059AE0525B82CF6C2F6F6F79870C9ED72778A3777F10BFE0A295BF8721A1EB3701865615CD5157F750E7723EE402B96DB5C5F3A1AA053BFC1E09246401C8D571F4B3BF7A44243DD62EA2B2079C2EF81041C0A97D698DFAD638F1B6E424F87CEE1262BDB0DC922F4CEA2445C380D7DDFBFAA4149C1A00839479FF8A1F88C9D86EDB40E67DFDBF0314E9C778EEBA7BF2CEE97FECF2455E0BCCB80052D24CD741ADF2DF7FA46DFD36A25682F0FAA0377502CF6AEB9688C9EFE8C34D571F6ABF439A4BD5BB8AC268FDBAA8A1833A35211339245D80B3E224D86917764238A6D693E444AB427FBEB474DE84F6CDDC8758E5EAEF44C351C813AEF15EF1ED7E5C67EFE376AF86B00448C07B69FA4805B77F17D00CEB33F5DFC0934FD5B63347B901B750727B020B6EB095091D4DF0E746571DF50BD4CCA89BA02E73C23B1520DC7383ECF7C6B46A38782F8A91FD52FDD3A91FCB341BD4998A9F71613C3ABC3EA4496CCF4177050E7A6DE906D7527EC728898378A2FE9C34B80059933AB2220657B6AA279DA0F819A8FAAB2A9F3C1C2C79A0808DB819DCFB01DD870491941DF819F543CF8FD5192919663C562158B4F764B7F683BE7C6CF6504F90697EDFBDBDE35D31BC037AB25CAF0B599D0630E5C185BFF748B6B4A807499908A926F8F7D85CFEBE0BACA91D3E306909FA608D5674E6DFD1ECDC709D5D5BF3AAAA59E99C4A1EE4214C0D086DCB7F1C820894EF90D3D9F5EBB5C4A394646DA1D79EAD22A2DB539E58C6A07E120C9000F0FF5BB4EAF5CA692EAA9D35BB1F5FBF3C5007E0A87084CF9EA23A2EFE439CB466FBD83582921DD1962E53E1DBBFB3BD1A7895805CAE1ABEDE64FFD844DBDCFA5094B96722FF4E76C9674D6CBFA3FDF35F0E54E2C9C81AFBC54B6A36CCD53605DC56F2A8E952F006170BCDADDC99BD8176EE78F083A4B545F70C956F233A102E8D09B5A6A910B893C0954996E126644CF2212E61809CD6028D868238CFBDF8180EFB2F12C20A754A557C63E2D76B4DB1070F1C29C9CBC7CA61FDD7E9EC7C7E606F3418E6C41D717BB31291CEA44BFB1AD5620C1A19AD5C81208CEE9F30B82A8E1B93D58FF39A0FA6BDDE894959DEB217D73E27AB1349AB22A3FF0255684EF4E2B63309AEE5C8EA3F97F50FCBBE5440C1B0A90588248B12392B1B4FC6444A568F9F2726CAF95ED" + }, + { + "tcId": 7, + "deferred": false, + "seed": "32BA0BCE82AC978E5932BD14B1AC1A9319BA20412538191E2C7B1E0BD1D01CBE", + "pk": "88D5035BAB5978F65EBFB276B69D110BC0036C20481FF9CFD52CC4686715BFD36EF295B8A90B4BC5FE763C981FC81C99AD256ED42638119125131C214BA262D158D0CC33D6687EF24BE355F2AD25D7BCD89ACDD766E4AC27F8358ABE5679A87E729B12950C17054E46CA9C0F43DA38D1156730EEE32DA5A3B7C1994DA41EBD8ADCD9C22BF4133B0A27CED066D13B62EAE06739EE48400FA4445FE768686074F4E61D05C9F9909027EF0B2ADED325F160C27A621A9124C2D526A1F73055399D27FD732024325044E2CE25E1BFF188A6B0343ECC709A18153EC3E06A4E33285D19843FCC32B4FBDC6024DF3EEDB880F468F6FB54B1B0128F2B85B1421B2361AFB59C6D548B307ED2CB2E9E00FF319AE6EC325371CB842EDD92407296049434E391DB770FA2660EA8691A67E400FB9C1EF402A220454F24CCDD28798C17EA2ED65CD76F7828687F535D960301456A7E937DEEF64E3FCD86DEE79BA27CBA562995E0984F96C8B64A5354DF6D7FDF71B70EBCDA7EC8EBECC26072F9C14EC748620C2493450A8A705FD9E8A7E747717EF48B80C119878CDF646434D193F25F12AA6BA94AC20BE5FAE1AB45EB7A169C2428A9D6364BC36F532B769DCEE7AC6A89EA6134D374CFAE436E9229D48136FF69B70FE1B061299B85E7EB3F527AAC6F8F8377A1568645D6BD76CD1EEB493BDEB404E9304B0D51332241E4C5E53E269DD7DCDE8D7F044DDFB7F5B4BD34BFFE05AACF68BD1C618E9F7982439521230DD97CEB4E10879DA82C93BABD0CF1084EC50C0025A918250D3E2FE026A06EAEC446D234C9DA1FF6A61685436FAB70D10D18C10D2FE03126362606CA49C6D4A4449B4AFE615FF4245C6E7CB1B5FF3E3CE6B1C8899292E1BC56686A5AB29475F4BBA57F1583D310C24B20305B7F367D93672052120E19D40630563212009602DDD18BAC6F747D1EC665B3EC3780005D3D41BCC4FB10AE0D2F71DABD94C220F7BDE1716CBFC26CEA2D874B80A36554BE6ADC5EB434959F55046FDABB5C57BA9A4E1EC5D1A1A7542165DF85FDD7D2B555C56C688829EFEB94248141F7620FC43D1F58B0297E0A68022BD731AA2F2DCB582897492364820077139CD6EB7964233B17CAE6369EDAAEF313C18BE59E847D238BEE14332A47826989F3E762EA3AE5905831AB0AFD435C552DBD4E72C7A3A3585F65EBE033A276C2A8B80DB69735BB5128127631C212BD58972341DD2E7346097DFCA3B51AC12ED994065CD9B97E26F1E32C97E7857971168AFC67844FC86DFA1EE3C38881FEE38A62D532D4A64C7018BFB613892D2D8EB799485BFE89E9B27E6CCAD6E1A21DB2D7EDD9EE2D34B9358FF3E60685218EADCDB2D70870843B11D99897F51F4B6E363229E5A10D093FCA34BA31300DB3C6BD8758D35306F05A9C4D8DDF78261A9A13468BA20EB9A24DB2BC51DB3CA5D382606958835C7E3984401F12D85EB00D1A6696AC2FCC96D4D4CABF6D644BB856CFACEE277325B9900AD611B5710D1607FE59E7B543148E6D28B1920464271865C07731B29354C2BFCA83485B020EE120448F79369692C4AE00FD7D80D663E8E5DF22D85ABB1F89DE27B8CEC5396CEB4BBFBDA56B65481FDFAB69CC0AA7FC3BB2CE8E2823481FBE8AA17FD80E5BA38C2637B1EDFD7046F5A578AC8BCD629E80F428EA736D551BB7D9E5767B215E8BBD562DD0D480E385E3767B91751D22061CA10B9BE65405FDAE73BBA685DFC4EF3803C1F8A63C8BCD9D41FFC2DC5B3FADC7FF866F08611D4E5CFAC7F1ADAF12ED1A41C6E486795E7632AAAECC5CA694D89476BAD99F43724017E2F6D7DF30A586FD377EBEE64261500A204083EAFDA04BCF2079C4", + "sk": "88D5035BAB5978F65EBFB276B69D110BC0036C20481FF9CFD52CC4686715BFD3FB2117E09D4FDECFED8D98CD3B8193C2DF09EC7592716C83CDA0FCAC143D92A8FEF25AA1F31D861D633143A027DD118B77C76806168F2DF713ED0F7B252D24BD3BFD17F352AA63CDEF541C389A0AC8DD94A6EBE2BADB5128D8A8B4BDDBD1DE511B218520C12840A05100B108E312308928411BA00003248AC140918A1069233172810672202521E3A85088224C240248E0A68100B56CA44401C83280D33085E334128044525126010B8050029284DA200511B2515106624AC6105CC2601CA469A4B62911950409276089426D010564614205D9A80C8C462258B02911426644000048A2480339011BA48D61002D5C342A8490701CA785089090A0C2608022819BB48C91A84D1331489B38611B8931110089129861043751E444628C48425A46421B87014228081040120AC02C1BA0089210284A22124BC069111584D34886109960CB360CC8322880C4715B482212372A143551C410500CA04C5B122A9AA42CD8062509C0409B164012B9110812045B446D0A986C622462C29020901001CB208A1A38885A24620C29915A022DD184458A0830629888DB906019B18410114084C20419A44844C4604446454AA4641119601A262E88127061826D5B069013314D19C4012203214C848409826458388E48A68062844544044011846D88442E14226C0B056D01142CA4360554160C12264DD100260CA58402454023152022278851C60CDA8061203749C40848D1A421011461E4428910132E53422ED9C22953124DA2A63100A0494CA46059140D09B38D4C1011931828E200446220020A38511C419064A82512848CD2A60483B045DC845003200DD2A86C0BA94009A32004238E0A0702CA3228140449DA060A23218661328193C60408A76CC8102508C87092200A49A2891A902058120580C20CC1942823915083C4110AB80CD940811BB22D03A26C910611D2425224090A21C62510984524458E13384E52964183121199144E60164A02A05121A52520A90824498503C640C942028402924430215300521B264A1448859324520B1831D3B689A0A42804332E23098011380E143944CA36114386041B076E14294421336561308E0C034D1432920385891A478A0206804B128D5A26700BC00854B80893B0615120082413862393481A070CDC3602800008D9429011C0640AA58403338910179288004119406D0A238D0445101CB28453142CE014266B9AB221D7004AEB423FE90019F0B877A77C97038E602E5F27588CC5E8F4E291EA281621AE6D5FD8B69DCF726EFE8A8D4EB70ABA722F29BA62DD2B95178D3F085965C951ACA56A8A2721151E6193CB347215F6636F85F8A58E50C88783369E0EE6A2C9396BBA3B68EE376A16F7669B94556195146917ECF64408E3B75208BACCCF2E9CA220934E4C3E94F212C78F61959D3F4AA3D97FE5F3A193124F03EC3C772DE668E57B834236BA3F1B3FB4189B92BB61B1D2BC98AA6DA3F9042A9EB270C2BC1CE1E79A3FD41BCA404D3023C6F595E564BF9CE85C4A919BCA776A94B5E30CAD0549FD2585CCCE139B20AC082704453279C2701CF275E967E6C81B57A071C09F5FDF3CEA16ED0DCA1F5983B79312E670B2F1EF546C24C42A67DB45160632A94C3D68E477260D02717E77DDA29CB4FA599FECB9B8A39504A12349F96C0A91434A7F5D507BDC893732D1957179C258E898847D44AF121235E5A01D8A9A2EF8A98DFF59E89905CF0E71BB59672254F351B85EF9FA5907AA688B7A260E09AC81199B14EA55A9D759482983EA94C5CACAD0B5BDB4D94367E3E6623AD7DA0441E9B695C1EF05A8D23466985CB88AB02E775280D954F49797DB6406C614E87C0E4DB0C932311451670898DECA67193EC2F9EE61E03234D3B06E27CD431965250DF402F85E9D3A5F5FA6ABF021B503173172D4FAF32A6C3B0A0610CC4E23B5D51E1A5F1ED2DC8750B50C6356C973777A74E062259BA12A55FA9A27533A79428BCF9A4026CC240B6F114CA92F345B8F55AB2B47933C0D8C2E77268319465576A217DDF9EBC3734DC7B5AD17DE4F64C99AA7D2BD308B28BA898B873DCD964D83682CF78D63D4DE1EA86F7ABBFD2194E1F43D58742A6B2698D286E4EFC0A06E8A11B65ABE781F7FB7D81A9612814C30F56895C1FB7C0C3E5C86046473114CC199C88C1017E3715E833CA40AC0D82216C29F7C2EF1BBEC2FBB9BC919E9E1DECAA0F1405CECCDB4DD2A52317B5588F2B23A799DF80952248B266A6E64C763A59B582B95ADCCEDDF942F7FB2918D002F5F67B598D6CE559A683E9367276D6ACE12467D83558C1FEE296C96B06329FC2812292F54E5A02BA47CDA2D845DFD0AA8D23D88A44B369E84D4EC0B1F7574B75A0DB17F358FB838880B3F4F3F1E3039707E3A1E3FFABD65E8E0AD7C8BCC035255E6A5FB19811DAB9217C4A52EC5B7D1F16EF52352EA13C68BF02944E1D12FFE662FD76A0340EB972854DA8FB6C2D1F742C39FE5937D01F8683895C01784A73DFB1AA14F4638079374E4A73F9E232AA123E89F86A71370F381D502BD496E656626805DF278FF5C5F2C77C2606E9A86D88923673F8A8BC1998410B4C4BFF2C2AE689C62547C101354B69B992D47020A82CB8DA28C8AA4BBE6C8047BF6877E61B6CF185D3A1D8686CBC42F7B81D3B4B7B160D2F25CE82EBE0D532A4FA55E42D84ADECD88B52A3442C0EE00F4BC8AEFF861C085FE1583D47E28F9C57DCFBBE640CEDF33EB3145553E5FAB89FBA6620A12020350C88BBAE49392D14ADB29CE430A2E42050590C2630DCA206876B8060CAD150968F10A482D9620B2C3FCEFCB08CCE9298240FD657CF1C11AF6758714AA332165E1C7898C77A0D865A6D0956916551E184F40A25F53AD56F40150D077D8FE162392A4CAB6C44B9334592709BFCBBE739E9B42557348B4C33F7CEA34B2C118FADD5C39A89A21CDF074A7F4B3E697476E38BBAA9068094D218149605C2B71E3BA2F92F03E429748E92F7A95AAAEAF4921CFDFE6ED2D5AFA4E10207E9DCAB695C7218A1D318048570EB68103E645C98541345451C2A333417C268B9F5A83B634E28A77CA7B4E6227115E49832C75C90284919AE2062CD3DF2C5CA0902651F28CA05E2FF21409B7AC1A46062FC76B9C933AACCCFAA53E7384D4FC4918B74A0E2CBEC7E06AB530EAE9D7988B72C737E71262E393AAC3586B86E81D33FEB1B2EF57752BEC6CB314ADFB95FBED5AFE23234D32DC53B315629D426B0F9EC740E29E85C691A709C033C3AC2B6ED6D0D0A3E0EBD15A3306841AF0BA50FF06BA5BA2648F707242325BF13B80477B3D9EC1628EB760BF95AF66F86C42CA50845F8CD54AA4ED1A8CA41F925A4D5F40BE63D39A48B7FFD47F858D91FBAA41A320D7505906CA613FD36810E99389310EED132E8D79A5E735A63CD4622BEC3E654FD7242DF1CDF3B55F9CD593B581DDAE4FC4F85463268428C1CBD6D4E451F0E6B1FC136375436D6226EB900C4E581DF8EEBF1026D0F451EA8D31545DA04E6B91B9D6FF5D69881E44321FBF7B71F90079BDAB93C456FA3812AA3819518EA589F9B59CA8347C197A64FE21CE29F9E5" + }, + { + "tcId": 8, + "deferred": false, + "seed": "0BE86B084CD4B31D855EBDED6DE39326516D4BA6770B76B1D4398FB2C9C75196", + "pk": "12BF77F8CC6192D2F75C2BFB9E76EF8D9E4E47ACAB1A8086CFCF213A8E38A4C3EF2650674118F16577B118BA4D6C68451309F3AEBAB28689A9B150411915DFA25339A76C2F78DA91E3CF11DB3D0B1BA7954E48B73B3C79B8943DD8A8AECCA0C2FD7210E4607B5CB442CDD4A5CF0502C5281253866572F5C031B8C7B664D024AFC1F4275139047F77705AD356F1F0B1518DB009668E777F982F12A2E2CBF94818C5666DFE39C86281681EDFAFFC427E1F94276356BE021FF111CDDCC1A9760E2C63EFF65D71AC360484ABF6296982CA325F5D3DE84389C579DD3679E3570E327E5F371EFBB2E4344107C4A020C3417E93B61ADB58328B8C3300FEBC5370ABF679887FAA00B2972E4CAC37FCA8091B5A4D82DEE628CB077E198C2D310F5AEC2B8BEFAAC088EA450B268C7975B97876F2506A736911F48A569CBA650245224EDA137930E333394A3E1765C9E44CEBA54328A1BCEC797021596F3825193CF09A75E20162081EFD2AF3E138EF0006C0FC7FFD30FF871F835E29F5BE766ABDE9279C63C66BDEB9305EA464B079921DDDDCA6499F24135AA1590566EC44BF2A4FE58E0F8B6924B5FA1538464758C84951DE0055DCC6BA47B6AA3A7AE762DA8513FF86C111F4A322BB9070F8F4325D81750B96E2932326792216C3EF4646E65219E3FFE6A94712615155D935C584032C73048022D620861BE26DCF836608EDA0B41EF3E5E36CB3E2C6E70FD18C36FC2F7CCACEC8A811FEAE3210E34E2A50DB516D652AA6242D29AE0E6F8211C031D0AB827DF1AFF74AAE842497C8A70F7980D447B7C2199EEF6E316A5F21FAAB102B01C2021B79D36578F5EA3854E499EA8C09EB7AB853E94C182E1859A2C9A4C4AAA306B3C4BF8FF4A51DFBDF86099D446F007DB6693241B7B4AB274A23D60343D508F8C3D2BFA3E21ADE4DF9DB242055D544858CD9EB01E2FC3712CD64A7553D0219970B449187BEA4578A0F4FEFF662A732A378BC64D725C862EDC3A48B7F8D54EAF6365A59FA9D48B92B126399693E610E768B97E9A79C7B27FC2F7C36C88FA5A96FDEDFD09EA5C69081EF50180FA987262132D76A9EBB6CB7281EA3BEF56BB5EF32608880FC58270033380A48A8481264D89094BD551D9A426B9E05B1484B9D1E0774534227A5B7A7A0540834FD43C6CC631531EC2BA5FC5F47FEE839157DF4DB54EBF42EAC44B6DEE1B2F5DCC679C94050D7D4ECA9E823195A7051CEF88CB93F574259F35E4EEFFBC0D6FCB9BED07CE09BBE62718D7D835EF761B2DD703AFF3EA55CE8FEDA4968FE17E13BBD4F273F585B62AB54D926B82E6F68C724BF6BCD657D519A072A1FD5F902B97643D7CE941438469E1629A62131C95F557F8EBE6EC0C5705F40157BA2D1A939D767AF2C0BBCB94FFE7AAF0C6E03E0EAF2F1F16044E00B071508ADFA77D9F7448C0C34B807575C07DC5FA58C9C9662E1129538D7269A52232E30FE645EC20B6B096FBA3B8A98DCBCF009D1E49F2B890CF40B8CB976155BFE06B41F6B2DEEE2DA860969509F49E248D7B2A3854A3E62A4D01A09B655B960F5C768DCF597CD553FA5F1B708EDB92C608827F16C56C7454DC9AA6DA7C5894010E777B43E17E402AA54287EAC468EC6546DB1E12D126BE971B968F7D6A4D2E301AA88208BB9162B1165AC9CD95482A5D2778068D44803C6B7EC58BD3A43F1DA720125747B83EA9E7DD1C416E56DFF82B36E034CC9D4263D80F8226C57B1FF6A869131376863277111F283751FCAFFD4F81F13936FC90D3CE1AE7018B54FFAD0A153B1581E96D0FFEE35E3482B464CF3949D08066FE404C883E8E984CDBA58ED30B81D907112DE004E5AF5876D2625E53DC256", + "sk": "12BF77F8CC6192D2F75C2BFB9E76EF8D9E4E47ACAB1A8086CFCF213A8E38A4C31A184EB1DFFE79685CF26FBF0DD4D9A75670F64F0DD28E678BF346FD275B33849B1636AB26002B46002131E8A4358E8514C57DA7CDB74E81A0E129120BCF89EB39287AED75BAD79BEE2285BCB67F2C75D3CD6785C840073138041A822408FB4F222784224412A18071013451D3262A21944D83B4480CA46D243802C8A83099C8248024920A96400CA0911C034E4A021218A370D40612944466D33288CA9044811206E04460118071192448D0426C10287219476910066552928963246000157211998D033146D1306810930DE240044A80419B844D21922492B028812441231545E1906491282158048C832861E3C68413952D14122909200E50020C0BA8902204300C890D229111C9224801190E5B409212466A00873049905199242D983850030988D21489C2A621CAA62C0C146D00B63012A93102B329CA922900A22414450E249164C9A00C82181020C245D486414A1040D4C4511C392A08838D193368D4080E53424908A72DD092094A042409B371C8A06C0C28501045825A28054136289B26421438810C070961164E49008D81C090A1A240C116464A802DCC244A942001E2260922B544A0200DD90824530442C102921B178D1331884012290A9541C4B01099401109092021B1100C800D9934299818710B19091A098D0CB2018B4422CB4228D82410CAA430D4A42D1449415AA405D44426A33066D90640033728C81252C8C88104050098148C1CC2899C02909208221883511A176418C4205C48051CA208822221E3008913802DCB2231933040CB000D9A460C03C371213121D18604538450403471C2822958926944C0059392310CC50919236C1425062012711392711136200A35901211129C024040107083A2284C96810B1900A148821B452C19346DD8061220B948091540019048A2222D8B488910B981DA42301B9241223932C9164163A810011761C98445539200DBB071944042D42260E1904C08216D5A105018046A618625CAA444223692C3B6000A108A4B047053C49044225289947010336A1421011317909BB485933290003286004325C9868819C47150C24D12492208265012308D8924880AC6600C0811DCB0908046228C464D04B8108A9070892011902030D2B44CC146200B232019450E51227214915114B58D81344D523092490012821010D9226A1C8610014100A0366CA0066500930C0939288910705C268A734B52C1E7258FBC0280557B30182A565D0606DEE96C8629D801C6C7638C89EBF8D6EE3FDF2E097A3CE63B844690FDCD74537E7970594405976CF07227702CA1E498A824D80A3B7D417DA4638004D8356BB6F4E83D130AC217DF4D5A8C3F1DCD0714AE049CC853A232166B18EE9EDF939AB6388469C7CEF34F36A41201E168A1B3685A4FE758E19E11B6B900C5E9ACE8EDED8C69A7A1394D4289819221F43D28988255442D833EDBEBFD92ADA840A4998DFCE7551605B68B0D5AB0E42869ED71433451F9613A4E9817CD706DBA1D43F8B09F67681C16667DB0CE1FEA42EE0055EBD1495772E68A00EFB36A82E29A0865E88837CA4857053B25725FAE7E2A145FEB5818F257042573F3D838C7DB4B9A9F7BD50EDCA258EE1D9ABE0370908CDFA843895361F93DB3EF2D4531FA3EC9E6CE49F78648CCE2B0204795EFEA3B14F4469CEC7E1F34FE69B2F746378C7F79ACAD7757918A784D18B7C4D44176D4C890C44B072D4BFD8E0BD4CA23352AA4247007C9D31BE4CCBCD29ED22E5BD42C13F9DC8F2813746108DF4B5FE1062F8F81A79B0972FC0AB95990AF9BD2419FC37D21CEF6785C90FA5F9E13A5F929015AB6E81BD5AAFCC93E06D7CC8F5FC08341CD6219955524C2DB93409346C6D51E3575D48A54807E292F574743A0683FCF58AE003B547EBCEF9E0D46B96121F258CD8AA4C942146C2159A13190327D3C7CD163366A18F2A2448D52EDE4E29EEE9EC6422554F7C04DB7D2228493EBAF971F7F33B4BE8A532B54FC30229071B05E8CF2EB08A67E41C1827155C74A2F3C71391C86A339F3541D2918B6A9129A95AD093661A2A2DC2A438AEB9B68A51AE2133A538639AA8505CEE801EA0F0F29776857F05B9C8908B0A257110C4FA63089AF8773C886AAFF9002FF0C81D1BCA7B86A354E9B8F5AF6A8515FD1DDD26DA450D6209990DA99394C29BF3E7EDD96AFDF4D8FC931DAA2E20E908F4F0325D11696B7759DC58F1208D04E0F01CC2EBF394CF97429784A7C399B00A7EDBC9E9FE47D6752C622F3404A986F40D73B7C4A7195905453E20540AD3EA3F340F9F4673F313A8FB886922E88FF6A53815DEE2BC26EA39DDE3692C343E26421FA220D052980051C67659686C53220F6C83330802575E5DA2D8620A1E9A4F9DAC0968B9DCBF8D5B9E9D4FF34889F43141AD7E0FE512C0C772944134EAC745B85BF14449AEE250169DF5FB73D7D3D48E815A68C8D7F8C3044D30A950A6DA8DB44BECF3CE73019BB7EB137252459CCA91B1EF3F21E30B42309FBA2B9807E475B9B31A4BFEB6500D3008E8EB5B7F9C7FDEFF5D43A9A1182C0FDB5E35DC627AB39649EC04A74DF65FAC7150411F3580BAD2329E07FA113EEEC08E830E6D7F6B30B561AA4461AE7AF8D09C3D34A4CB4275A57D63F18A6F2E89BBEEDA4A8880863B6270A62D188079013D2021EBDD2794502ED834A54E2A1D23D025E394F4A93B45A812AC4130DE5DAC831D7FE556399A490A1A855805B366163131539FD8AC79BBE593E40B4856BD311FCDD7100E1A60B4DF68B2C186E0B2969E68FD52070B4369E5BB43AFBCDBD55E729FD092380E365799B714748BD0CE18BEE4E702AA9AA6632C23238304F108C7657BB373305896E741F34C5AD15E7E599482F62A83556FF503ABA90721AE746F6F7737569DE661CDC6EC6E3E165187CC20866B6F749069A1C47B72A9ECFDBDDDECEBAB977CB766015449D5940B5F49150F74B43F0D14A1BF6A06EE22EFAE98009D232FB7C4EF0A1A7C8B9F14BE723D709AA66822333EBAE458D534CC3F65FD879E60C7EC24F3B320AA395BB2C3C5DE32558E60889316420F866D58D0E0AD6BC81B4FB6A54D1F04351F0AF1899D788BDC43F69DCF8189DE2CE0DA497D561662E25805C15B1FD36774AE9296513B3C04CF2825AD26D5117A024F15F25C3EA0A53979AA02BDF42FC4A2CD1BE6F76E9CDAB8AE1320FAD6418A03F6BA2E9BF7B7A78DB14B0A3A08803383A7A41151893F95E77BC007EA51AB7B10B218F3FA533EEC43D978636826A7C1EC7485B038FB628706EB53E212775E759FCE34A03049A2DD1830EADEF1DFC5AB36EB6CD164D487A865D99D56C057566FB643FA5EED6AEF2F6733C94262748CB0F3FF5565789374CC7E415D1B9843242F1F41E6F8A3E55C4BE0921C28AF977214AB05FC208E06B8A3993723BF17E32D46764E51D3E275B6A5876F8BB2BEE1B0EF512698DCE7D3E2264BA02B6825B174F08B43C1FCFD75DFF1C1029B8D1148838CAF0BA097E927C7E36A36734F7C8839B22A11DEB58A760EB761DBD0EF4CC5BFEBFE23149256F504ECC70AD6D47B11834AF0F38A0E4DEC01E354DC53F678EF2" + }, + { + "tcId": 9, + "deferred": false, + "seed": "68E203AD881ECE7B354F6A760C87CE3C2F7A62EF1E12C71DC2A965517F0E196D", + "pk": "19770BB1D4A3BF4A824BDC06B70430A7DB2618559FC20B03A973B5ACB24D06A1BE8EFA3847139CA8A01B00619D72F5047468678CCAC0B440DF18D256F267EDF378932591D561112D96C3C3F558E589807A6E3186896E47FCA7852DB1588DCCB3A8A48C22AB259F8F293D8DA8F5C5585E6619805CE93F409D894E75E232D7F59665A17DE0647A613B25EFE1437B8B917913997AFEEC8C02214F63331CE248FB4E09347098AEAD4ABFE52612625B5A7D4AFA110D00BE29DFE1ED4628383DF24C7D70F938B694A83EBF42C837A3BA38A16149820F569BA1A9050B3FFE8668A1DFDF9955986A33B5A6C04602A5E5E8F4052AC0359EDC3AD9E60B085F89F7ED0FDF8011A36F98C244F08D1EFFBE51F0FD11B9E5E121C7573E6E051940633B5C3DD3FFC5C585686AE52699503EB318DDECEBB2F77A9CA4925696CAD99A3E01E7E73BC44135DDC658451AF96695FBE67595A38FF0D552FCE0A2AB2C83DE74908A140E5BEE8F44AEF13DF065D5B7E49EC0335F0FA627A60DCD217991B60D96841DEF80F16E5387629DEAD646B7D107BD919B061B0BDA78EFF04A1D8DD73D17A68869959EE42EC6FF7C2B4A079767CF79BD14CE7664CBA0105D02E7E4A281F47E5462B4679980009B0CC12D6F19EEB806D433EA7125E63599D0D952D8689A8AE31D17335588D5EBC4B66B8847FC20838FC019E06BD2D87183BF21FC6AB3028BE3A715D6F4740F941804E5C62734724986FC63ECC307AE6D1737B1B7F5B83220882CEF048CBD6C74A5683B96F3B435C55AB722CFA2D74CAE584495F3C407D7F2C6051AB8736B56AA134B1D84A45A61342A05DBFED3F1FD11C25CEE2A141E1732FC1E4F7BE0AFFE6FAF8139E1A410706CCACCE20029DB74D1FA5656724E27DDA80D822DC1C14102D2F85D90553F6E86F7FA8B3509CF27C49DA58732113514EB8B4E76028DB8AC0A515646282E610FB3917B44EE07128338536A59305AFF30C9A20C9B97679091E1AD527AE99DC7942914FEE882D274451AF2EA3A41320CB369EA4381E93ACA63C6A53E1F1CB89EE6F2923BBAA9497775E3CAF9598FC2957B31E9655C7D371ACC677AF69929F7A573F27AF7CEBB688D58C1F96995A5835AF956D65C9B39E919BBA88EF4CE75A739A0C5232C9BF8D3AAA416349EF8D276BCEE375579AC841895B8B8DD4ECF41B9829333B04F6A6BE7ED6C96F718FDC7F4BA5EB1EAD2493443F4710B9A68DB0B173FE18071FC0D99A9495074849F38F350F3C7D2D11499064006AF1D33B07A120817F24D2197BD8654DB9F28FFE7942C56D4F06C0C77789A7E9604D61948ADA160FF1D493B506504EBAABF2304A2C200297FC3E8EDBE807A3DDAFCFE89BE4D138ADB49630F05A08D3164631D642F38AEC2CD0DD4488129A1565B1465B121298D24EE8024C1510B60750564014FC781C83FF37B107D00B4D5EB92647063AB48A45469AD7D3F58ABA499E851B95D36AF945335B0D7712A09C15B21D7D64708C21C34B9406E00F3FB841558E617C83A700CB89397620CBE61DC8925E5D0A9DCFA433594503B29AEC67C90FDF907BAA581E75D3FA508C4901324185109820228447B364DA78AC8A8B29CEC23151CB7B85014A816E216C52AA07BDA3880045BE280C61F2D94756B4697B9A1701BA76BA044BB86D1CDB74D31243F05C266795628DFB9FCA60E5F33D16D4FF1E3D75AAE2AA3BA273B8F609B1CE2440027313C84AE90A72F1B150FB0ECBBC00FC440DD3A8BAF0942C1B7E28D24B25905EA0A710E8EE4A9C4C2CF85A9A6A599A3E1729C0F62220E435F9662804C3E59A47D05E74C604AD37846CA58F30E542F2DDF75F42D199D0129C7074F8E88451ADDF0", + "sk": "19770BB1D4A3BF4A824BDC06B70430A7DB2618559FC20B03A973B5ACB24D06A127667D52E65FFDC8360D8716E35BF950772BCE4204481B0A2361EC96ED49D5F7F62C1FDF0128C858FE0FB20A40A0808A96D7801A790D7CB775CEDB703A417CB2E5BAC05DF0B07001CE4D6EFBD725CD60149AEA7BE5DF023915B21A2ACFFDBB6200230DC112885B340A51B24102C44988000E64028D59847081308C19212603B48C9A8420C4382004B20910254D12C64111291211246641A4891A2644A3B22C99404C84308522394C082446E2148EA4100D42062A5310261C4409130591C9C665044769A4006964846C0311204A84900B168824078423018DD1C0040A924D0213501C066E11B150CC886950C42823876D212068C4140620A8251205281BA61192124CC22212C8328DA34070C0A08412A92520159150302198920D2448608C22248B8448482240A2200C5A104E83262553468202814C211681910066D9068182B85018025119804901B664A39020D9308410428809A30CDB306A8C842118264E02368522042209254A4B8000D236010014125BB4111CA5295C860C040881D88008924028D11406E004699A2665CA06619A440E91022519134A21B789DC364A5AC0048AC2881BB02921078208899153B8611B921001A4280A40048C120C89B480C2C0714A8880803088949449511244648884CB3002DB344514039110434424C001C0A46DD44448E32846991031D98841C4169153142C02222A1AA1445B804D4A30481B1441644611CCB66823033011922D01A90848142C41308D23A70964465099A231CC824C43821120C649081600093581E3184ED3487058A62CC238225C002E21804804966990048992C26164222214C590A0C2240A15229280809B2206542852611492DC081221257209042DD3920D00158193C685C38868890004921670D0806D41201211246E04B160DB042081022690C84500A33051184CCBA86002B7200231100C94710C1162D38869C92670C0488243263002022A0C022210067101336004452203421214A76541142E801262D184815C480A532492C92071212109183889D9004A20210510390958108A91363049266E02A48D093260D2062448204C609290D944325924518B366622056489C2911B1489DB8051C2424910072019A89021265040062D44120A4B144951C205C81060128665101880A0827064C240CA028153B03020137024A1858910041C4031081752D2C48513292CCB406214C19199DB455C6DD1078A85E13A1C3F8D6F923ADBC92D29E31C2D12EDBF1FEE6C5674BC7239629893B477E559B1E31465C866DFC9DA4DAA756C91CE68626D2FE671A1D6FCE2984AC74230EA4B4C8A65DB0EDEDC29D522DC8B22D9768D0999C3729B21DBB2C7F914A581D0AB3C2E3DF2B9E199C43E2643962571735D2D193BCCD5C0D7FDA8CF045AF9C841845E548DDC3C610726C8F5370101039F46B7784878CD80C0173CA7408BA2783FE1657A48777201EF3F2A5876F32A9CC518961F02720E8233D98204219CD28681EB74CE793550F765F0D6A6599086C6C5C8D0B6F65119C071CE3C90DA97CA6E9DFC07A9E37F6EA3F5229DF74A52779E806E128D3CE8506C3F6EB4D6954D11220887A7BB0D306B49D3250CC719943BA1CABAAEC9D48F1DDB5812CEC8FF2315762D31DAFA2948423CCCE5DA6D504A37D1188C7B82144EC11DBCCA06027E8C1090FE59B7C822C59D1091AE4D9F19F93968B7B24662FB45646C81AEE953526283EB2937059D8213CCDFDB0DBE0828C890EC0F8A6909F2FAA64FD3781A56590CA0B19969ED93A6BC1889C07459888D73A8398F2635EFCF0B2FDE1189019DEB47E75D5B592B9ECFF329B09F03E898FA157C6A99CE2657F8BE6F6FBDAE5076EEA6223ECFACA2C7204C5A7C7FFB06885B78DAC63AFAEC102B20AD0E0617D0DB10165886B1F423F07696CDBBDBF384A6780863EEACD3099241B0C30F1155C5618F5824A51F860DF97CB16F19A0B478408A9ED61A7A38F67822C3992EFB46F72702604DECBBB516FE63D9E2C356F8A4C782F1B860737B2C98FB6389D34E72189FF0F93BBB068ACE2F90725A11ECFA791480B1E4D8CE931684F3936CB1CBBF5C47F454AD012C46B02A823DCE7BA163FCBB96E1CA355DBCC53EDC897470356BA487CB3F4C6AF9B2AE41BB9269A1F3CD4C08A74723E352528A19D3AEDE6AA193B41CAE219698221BDD08EF25761328F317D31A379EFB59EEB725069F014E07F5ABE1E4630A8FE051E323BAA38BFE984A99651659D352785003D2464CA48BC6511E5F9696879AEFE26C6F67E014FE291EDBDD84CB61C1DAE67F7DECFF30C2900672D142A527C41D5BA5BABF296C657351FC0517DB415E420D0A93F3B3ACE798840D4327D68BF6DBF459E2D16A789E8D77E64876F511EDF5EA330A75BDAA8F82EC33BA25AD4B64F097D1F16588D5CEB4163B8790AD4BCBB2AFB3B504CDBE936993651D95BACA39C8C64D96549B47547F1DB7EA53EA2DB1EBA552B2A5BCEFA82F0EAB20F95E452CEE39C96A089F793A2510DBB6359C99277F90484C47FCEE8C331DAC2640F593C0F8EB07E373ABAC3832828701D99B722982E7BCB4FCB40B78D9681A8266C2719C4103B39CB18037ED7026580C8143EE9E311A9428D680A0E0E3670BBD25CEBDFD6177516087D0673D73A436E5033B30ADB5874EE1DE38E017E158F6745D7447745E55D18CD653C834D629D7644F3DCDCBD8C85E18511D5ADA4AB9EBC764FB078AEE56C4895483B1A0A6D597BFE89E1CFFCD456F0CD994156E8A8933D577843C714CBCC6713D13FB9C4DB8E91EC971C5BA4E90112C105D7F8C3E9C4F1EEB2CC529D0A564A41426B13E89CDAB85965B86E0E9EA45EC9428536A4446B349AAE57ACC10CF1FB4B8A9E7092D6EB0E41D357629A9220CB9B970D5932E82023D83FB716DDB7CF7EEBE5D2CC88E1ECA2B4F278E8F7C670DC7ECD03B7168D20DE000290A83D97E9CE8B36BD6176089D6E47B00384378040FC70882BAF995B0A34160AE8255877E00A395017EACF408CAFC6FEAC79130C102B9F2EBFA357048E182AD11355A1A5CBA8EA7D7ED46481081778C423910F4510DA794508CE5BCBCE545F141C935CE696B547F4D262544EA0528B5327D7AAB12FF4C323D343E9A9790A4EB638F3FD06B53534CE8CCE022C7F848BB000D51295491495C4475A95CC10E7AAD59BE8BD0BD3F3CED728880245EDA454B4EF1B3B47C7058609549AE35D206C0E2323E18325B43486DF7AED112A2DBD17C2C1FDBAB64FE8CD5DAB4D31119EF146A0E4032E795D63734B3F90DFD86AA60661C0437DDAAE70CFBE37A74A4640747537C2DA404821E36626B62FAFBF875289E04E3A05A46461F60C574F0573F0E4810F43B486B06EA79A4E361ACABE0924677FE7F92E9279E7D4534DE32681BD605CB7E05AF40067C8323570D2AC4CFBCC7EE4C60B8CC2C96AD5C64605770EECC5A31506C106A97ECCF39D51B21AD772D64AED697A9A4F1C58E80A0A9C1C46A937CE2E3A504DD1672035D6546A896461376302D825CD115E7CF062D3DD4B5A25CCD25123FAE3D3EC59B8E0E1E453031CCA69320C00EE9A7817A01E4220BBE" + }, + { + "tcId": 10, + "deferred": false, + "seed": "F09E23ABE72DF75EE36DC1C952F56564FA4213A987A0656FF758F3991BF4E1B3", + "pk": "A7DFDEA74451C4CF87EA6233AE41C923055CDD85ED442FA912340D2F874F25ACC6AF867D21A200FEF83B993B4467B1F0B85F78505E04252E6BE367EEBA96AA5A383F3B82064954EC279714389DF85D2EB0B045D86D683B112A2A2BA0EFE003BAE26E42C6A7B3850E120E2C21F20DF331CDC18ACB55ED13D3437715F5515AECA0C9BE309EF6B5C2C76C83DAD4CCBA7171FCFC4ACE6F99DBF1CCB16080974157870646E27F3308BB2B6CAAB100C45A2B91E503F4AA74B82DD986C6B74F3B05E0DAF1E56AFFE17A253327F0BCFD4F3E8218C0E4F214B3603F93B1334F6B7F38FC6BCD7B9EAC364EA5ED73E7AE79781AB759991D0314CC2885D6E3DB3E4732B6317C5B6340A74639C53979B8F1CAE222A2F011520B13BD212241D0A7DF191D281D9B4D7DCD67A0B7F7BCC88B35C13119D67788DA711BFEB79B786BD77D3BF0A4631156EDAC812A77DC5FD0AE5B9F7BF8468FFFF04FD7256072C667A75C5BC983DEE7A208009E36CBD338AC5F7203BB6ACE2950ED17B1D2C5BB4449B1DA397E77BBC849893AE1340F3ED4DFC4CDF8CC37E5ED9D1FEE4F784E5040E5D4D5384ADEBE45EDDB64F4BDD0BBBE1CB19491CAEDC92F39EBE1691FCBBF6CA42F8918F6F55509BDBBDE603B4E39DE4D2A577C895F6FC09347B8C7635AD6A08B9F537104771AB1848230A72B5EB8875E7A2F5B1B83E3D3428B879D872002B5BF59E8EF1E3FDA75B2DE1B5D72AF6466731C4892F3D129E9FF1D3A6C5BE6DEF1A24C50B432981EC213DA5BFA8370A13C0BD06707126B4D08B6D945D818EB437BD29523A8ED95172FB9D644C4FE4E82CFA9DED35C26A0050262D679BEC360D3C995E11E0EEBC91E2D0F8EC05E6C01749245A04B2AF93A12D1CFC51E6B44CE15D71463CAABF53085E94263ADC3E8F631BD916A2773017B9CCAEA46ABC65F112670658E3A4A27F2DA0FD44E6E0CCD8ACC967C5A8216A0DF9B390189E3FBC3AA7C7D7BDBF994E93A901AC07DC912853269246420CDD9E42C453D46373C52E96ABAE9A00935B8FA935324D039299821576B5ABFF44C8409798AE18CB74000DE3DC19BC76E97F94BD212DB980A7E991C835E39DD3E262F14B6724DB0E05783EEA7B0E671EF233AFB7634D94D0FE721540EFCEEE3FC8CCA0F22B9B968056F99268BC58168F35698014144EC4C4C97E79B6C46AD8F8610159261595E7DB5348057DDBEA726AECC05859CF1962D0260594A00F2FD5E7DEBE7B5EFFDC6D71E8366FE17E9D0E845B8E98A8A4CB1DB51205CA28444D0E2D9EE86ED0F0F236A7A17026463A4E4B154B07E3AA32E4793C028F069C35A019E7A95C079260BC354CD2A2DDD5B75A1D09F96A335DF72E4FF986032E50B7924448EDE8895EFE636B65E2FDB1646831993C521DE019DE51788AEA4E65AD058DED635F94286B198095B5CCAB33B4C7C63093CB24FB705B6475F2C30E8F1A3AE5C445A500CD4467C95E2FF52F793E76E2C4704A4FFD0909181CFCEE87140ACE05338654483EE2D275874190765187B592EE9CE95D46DB4F3A4B86AD0ADC9A851B6A0E32A16C2B3BB206864CED0919596CBFFE2BA045D749936D14F0B5C57894A4271BDA0C9D4966D9D7B82C65397B425DE86781A78C8EB2ACD4299520835AF46AFA76CABB251A9CDD3D70705A28A33187B73F9AF84DB5E46D0C158CE57DF198C990F271597F51AC056008FB226891D66A66769500C16CE71227960F05CE4110E9A3DC397E727ECED0F37A291012B7AF59749700352F5D9368D4A055EDC9D1204DEE266E7103DEFA0F24EB3C3AE05A5B640A88DC5C71B790A8DBC97167A35EEA719536854142C09793D9112560050F67B457F6EF16AD550905A", + "sk": "A7DFDEA74451C4CF87EA6233AE41C923055CDD85ED442FA912340D2F874F25ACF5988CCB4FDCDF38F0C3612FD8EC68184A108B98D6AF0DCF04BA253D531DF1E5DC51829A30A5D0C78F58D2B9CCE6D4448A8788A68262984F2FB5D67739ED70D932F4FA61194B2ED7C2579E33CA3E4D5CA2F9B34C960ED4F53900CAA7D6198C211A06890AA424944042494271CA96310B4864110512E1000A092646A0387240C22D44868D8A2811233009C3C46409836584369114C9905C2285E1240420B991041165031600D922881389088988314AB87181400100442ED0884419470260A68509B78143A68118B645142529012304E1A42C48362A89406919A98013410AD4884D20270A89A00100412C09370421B088224584CCC62CDA9890589429D8442DE38429004502DC8284614260A0A449629250000564CB965192162C1437816496645246291B17100193654A06689A16308B044C1A98640C1949C9A60120C029D34248239809D4140010017103938023350E0CC91110A311CC948013206ED914459A04648A029212A72948262C228461DBB08802A00523A804E11684223591131931449209DCA68903120254A64841100008B261CA0630822446940641111681C1280DC4A284CA3472C4A08DA0284818A36C41A48C23B940DCA0490AB58C0C195188462264182810040E09826D13434AD0126A83C828D0462A229310E2304ACC108AC9C269213725083906CC0632DBC625C84404E2B06C80A688A026511344805C48600AA3292009851486502414111A948111A8308A8600C9468621263021A96C14032AE1C6809C20829C0291A4B0615822299332051AC1052180699C020E9B042C4B224CA4128182A03004C451991211E2A644D3B46D010992E3800C02054824B44001310154C0888CC0444214854024615134022037225A26450B318DD4360164067260B625220928621864D2382081064AC03090649820C8009113110A13A47020B064E3A40C0CC9855384005C4271942860CC062C0C1622E082854424494CB00104186ECB46651220455404024A3680A1284AC0166C183212024189D3026E504044243348211272C2888C119481E242859A8030D0184D403492A13030090130408870409288201705D9C09120A009238324DA04254BC671D8484801916519046613200219268A599289928870203670E1C64444428D02096212398500432624C1119C16411926054920269CC6008892690C102A0A846449B42C0131061B81908775E23EA2126EBB71325D654C031F1FFBDDA43F012EB01708059BA2B7A5F6F039D05142CCF73D20D925F73138CE91B8DD34AAC7F033135CE1465D2B386BB1BF4576645C728244A87663E1B33542C8EB560835C65E6FE833E4C14DE4F2CDD738C29D42332CBA5FCDC6BB23417F5EDB77AB6951122A5D68AC3E6D8B6267ED26B73D45E82C720D382025D176CAEE9FB343BC98E8A44378F92A687B99DB7061627DFA3E226E2940F5A83A8575E6C644828E5504C042932357F3AFA1F850551465D8F5A3D582434AFA13038699EEF6684001F0B736CB48A1DB1DE5998974D5B8B1478687D432822AF8C3B0F6CB2369BAC2D6796524A8E87214A93C9C952B36D21D3EAA283FD4E56421AD0E94762CD8FAF6010E63108CE2656C2F3BBDBDF21F3C39BB0EE4392F4F72D8C7F864BB054CF787EB0E9EAA54EAB1CE7306590904B78090D61778B27B7E45BA078B49474A017441D4E4FF9C4B722B423D35778B97187C505B1CB8DF644F5220023645F06AF755787B20ABACE3C8E89E8A47AFBA5431CAB8AB282F23020FE82C6CE569A1064BBD981BA71C309B6004CF79B2B5506D3428735DF01DF5FA01E36603D9941A9D1B41C85F20F9C341D7BED9CBC798FCFA4599D7126DBA60861CDFFBAA2BB41F7A93805A6833DB711100726DEB65DBC1807769B6CD056848FDE5506F4DD1F7875814B5C1710FB52EAEBE4485F5D9F04CE8E45CAFB4A5A57EA141702DC161A26B93E29FBB8F851670847CC9652B71EE58B6F15538BE0E2711F47B2F090550F2BBB225CFC24439904D70451044EE0A43A464F1B7D8585C07D8C23446727CE490E8F00E6905F734637146ADFB0C0D7521EF49CFCEFE26C9E5BCD52994FC2ADD14E1FF5EB35613EF09754DCD7C442C3D8CE94B1B54542250C37A9CD1BC4923AD391922E728E41C2918A5C3FD3CE863EE93E653219438E9A3CC4FF6AE3A143A01C315A02D0A48BD370EB4F8D4135BE517CEEFA3B170B18BDD3493612F548EE98B570560ECE0ADC80A38A91E552EB94FD4A10ABA93E70C1A89B71508D013B3E998D26C9E10A3868AAF56ECCF41C67AE7384C0D65BBFBC1BABCBB66BD28B66F1788E9EDEE262224CBBFA1A1A37CEF8367C120EAEF2C15BF7671F08AA6A7602470905FB16A76E4C6A8973F9052FB9C64B099E30B196DC961F0338CB3CE2C6A6950996D0029C2B10069D27A9B5A0CC04AAC59E4A34F3D80F9A1DAB54823429A5BB43EBF7A987EAD9E4B4C0BD0BAA8774E3662E5C3F4136ECA28C062986EEB4C81263347BFA13CD4CDB9BDCFD718635C57E29D4CB9D3F236B91885B6BD5F2EE49C4652CAC647C07FB4AA54E650EC235A5D34EAD7B3F7A7233B0976E5D5A22FD583D0903BB7AE10F9B1DFEA26A0B8DF10E0CF1EECDA99A4C91D31356975F8E51C0CA16EC56883BED25DA08FB6637A71DAA297E827427E29AB8996D9C7FD1ECB3810D6F860C634A2063890C0B8859004E253E7932726CDF16EE2091379D01F9990012FD22E95589CB2F88272BBA855D7F76677EE52FD12E6F5157359DF06E6AF3EF28D2B2AB897892536C7B14D56AF49D02FBF16A02CE1E56294691EFD6B5A59C9295771854560D6A7DB4A4425F1E3EC07293BB94366A9701001FBD5B46DE69F6BB0782D5CB5C7AFD4B6E5402C704AB7ED7EF1D2C7EE1E3E09970733C1CD8C086AE3AF2835101F5FC25885B6FD00F8AAB08679A2F33CC591AB96984A1809467E2393AE6DA4FE5D93E9CA77E5847FBB81F779691442BECBF6D0B9A2E33CD70870617385C3A6580D6E14C3ED7B800C12B8403689DE0DF6A242EB198969D7B943E5B94867389D96904EED0A973F7BFCA95A83D6C8E372BB1F6FC17B5B833DC81FC175452CA55AE33564664096D6C553C1BF3692A5A018117A3413A13F71ADCB490116BF83B4F16E23055E68270B6E5C03F9F2055C6BB0373934A16C45695C76DE7C741500D25F590D0C46B24AA0948D7DD57B4C5D50B5C720737366D6D491DBD18C5939A45E1A9382E7111A467BD89AB60E011AFDEC391B297D82C1C6BB1055AC7F9B4BB4D9D326352AF799B2F798F04DB9A8D2EECC3FCD578A20C6966E83D2A0601E29A172DF3B125F1F9112B5F378253C38C032DFEBE100569984ECDB80CC31DC7A310CCC80CA9257F39B315584F79D63F0000023D2BD47A807CCDFAD45470A6495D5BE3E5F4DC800D4F429225301B0DB5C24400C72BBFC81219B57E18DAEE6793D414E9058C9972E43E6FE823ADBB8CA86957E5DC17B6331792879AC0DB171AC5D6937E9CE8A5C1CB62E9B97CCB2072B622E61F20112C13C2E4AC0A5687EA974F621DC8D7BA3C0E6321BAEF498BE626ED7FF5D0AE541903AD9B204" + }, + { + "tcId": 11, + "deferred": false, + "seed": "F4476E8F0B3DD9319238639F50C78B3FE1BF404EF184AEA2D9E60D3028FFADF7", + "pk": "6C395EAF8BED18645113C013B8B55899A2DC27E31E4A246CEF8098E76F55E02F7F194F429456244129C03AB673F90EC9BE818AC236E107D7833E8499FF3532B9590731A3922F4EFC47BC9E14F7E2C09FE74C79FC775F2C577A59FDBAB4E94416F073E6B40DE447543AD64C3588690AB0A7CDD6D482084C6330EFDF6F9F64CDE8A7A501E555BC64FE08AC7E1AA0ECB9660EE9FB5CC3054644B02FAEC869098BAE6D524946620F0670EC876949BE7F35632431DE473BE80BDB81A8938C8B7EF396A60E42CA5C2861DB5D787334EF4BB00C9E72645AD1F372D9EA3CDB2B66526C8239E6E2D2B6B908963E3AD436B65B45EF86DB50C86D12C71F9BFC44DECA4BDE71A0940BBCA89206B225A24F23EEE96831535CC0B0873E4CC04E5999227051744F1A6B709AD21DC4512C2FC7C52ECC7E765FF51B7A09C80ABEE5412D8D69BDFCB532CCD050B24C7CE50D8CA8F778EAFF3AF167FE836767D3997FA72B3F9B09B2097E21229CF33600D35950D6E7CE143BCD2BAB17BC64F009B43856A22498019FB688E132476B97A8B19B7F94A162617344775573D8FBA23CCF721AE457D643B924F1B73D0EEB1EA467B25739BA2BEDA963C97F63219F14F1709F54A257FC123036DF5502DD04F8B5F08B927701C5356200023EEB7C3806690B950980C0CFA308595415D296336F3876B435CD0C4A001E1BF09082C8F4A96B87F7DB0A744EE39927385C0BB846C249D4CFFE4AB61864328DA610FC856193E75C3715CB35BBBE9C23F0FF9695FB65523C9CD5F718E505B2AB991154648103DD70645A1EFE8972DD80B5F7D4522CBD4A0AA2BBAA45B328B693AF88F0AE2F6B2BCE6BF27AE95581FB00FEEE342709B34E6BD0E2E65E63A8520AA260D601984E9AF702CE338FCF6D7704D712202B6DA7EB96C1C9C848C40FCCB3ED55B9F4004D7D6C57CD301B0362C36FAF5F52AA7A0AA6B78232EAE801A67B567470647744CD4F8E26903FCB14D59DF6D3EF057518EBB0DA849B4A743D6146C14C4587AD5E7A393C658EC91EBE970D23305FE9A151FCDD8B7C332A26612D349301ED291E8DF0A01099A0121EAEEDA07FBBEDF015DAD5F5655542A59F1E0F2582C78F8372EAE3D22F8CED5EDF73207843AEEAFB34E3DB9409A000D2D5E5C3CE34983791B3ED407F85124E5625C88E2C74FAB18D53D18C3652B37721683DCFF834FBCFD6AD7158F6AF0BCF9E4F41C29929BD3917403A679EB04F24B8A759C9C16A7763557CD23EA3DCC409EAE49DE1E473544EFFF60425679EDD7094340750FF060F2C25CADE96F5091A080E634CA1FA414B7C7C06D1B35B28E2F7D2A8131E43A8BAFA16FB4EE1FB7AE762AAF69EDE9FD79EBC831F88AA59683A296C0C0645CF0783468C70903B9B9BED2164B6CE5E8B118893D45878D7085BC2F140B39588847C0BC24B280C206CB3F8B2E40C27A4947AC92EB97BEE5422A7EE96180EBD311F6D061014225F410F91048267FFA13FB2B40EFDA99D2C15CFD345966FEC37CC1744E32D99DF751847E07D69D890847F53BA3953601810DDA13102D98519E586410CAE7033F8A5D3077E045C186ED50C399C32C81744A921FC38AC49AA5D07E5F016AD3C48E5BA637A6755861CB75A4F6F6CD08EF3FC2F2A16FB5F73EBEE9B74DC7108463740CE3C5D043EB63A82590BDA9FB796B08E52F4056710DEDB65324B05461AE395E888BF81E16FBD44D9091EFC03D1D3793878597562EA59CBF4CB8E1BFF6212CF2FBAE2722ABF478516F64FC3D5EA10179645D2ADA0F668EDA3678B0E4EC1F80024FF2D962EE5747B84A42154DC07CC85219F16752F571FEF4386DBC60961E8B8D7EB723EE1F1E5F1E1EAFF185E", + "sk": "6C395EAF8BED18645113C013B8B55899A2DC27E31E4A246CEF8098E76F55E02F1C5509910FD8171187717DC7FB4F8DABD29CDBD28C23D7809EF6B58A4371C8D7E7007D0271B40F27F9E379D6B87D17F2402D64EF2CB877B44B67CC0DB31E60B617376DA349AFFC07B219D7B4BF9791AAF289E81F03CDB8020485AD0AD92993D8D0A6852403281100221A25625C400262188AC34662CA100D80A42464486A1CC184A4042A132150CC202252960C1CB84C1A2566A028325B206D0B87901A048C1AA07103429252264E12032991A24882360E223891C1946008B1284CA84D08314A5C84701BA50413B88D1C1008202466A11042118170111911C2242421432912B641539209239948C43868C0166920C64DA04645134390D2183210170DE0100401829012158883065062261190848924C26121270654320A1A090D00A2250B053018A210C410895BA6898022615A048600158C03180EC312600341851C174A0A42018198484B0409C40891A33411082952910626C29005D12232DC38602336245B1621C4302EC9988418140158C6900C872159B2895A062651228E19092D0CC04008408620448E14C269103840DC260860008553860982405289022AD4186900A305C11672023624CC404D01450698A0410B184923492D00320988A82864808D5C802DDC06051C86695C326CDB464459922C11378E1CA771C4926C94B441949240994401983228019620D8C6606116111B9049102986510008DBC069E380041B080EC4148ED4884D24990DE41488DC34850C32508C300D10B080D9C645C9C469222412D8A660233830101224DA4450C196491C227151A82001298622A7614C845013A42C6042058A924104A52C084831CA8061E3365111059052C88DDBA48CA0464221044D883481A0A200C3380E13986151C62C2348928C024561222511C24820160DD4205019856CC3208949B469C0188864383211165240849010B150A4386919A96563B020032009C8C62454009289A00583B66482A46442A09119B76C0AC28DE4948563329152482108178CE1067159144E92382D9BC24101B920608820DA067018C16484386A0C1460D4320111199218078A89802858C001D290111C070122468CD1084861266ED202219318664C428A9C942023B81013308801B32454245209152608B30D9A48080BB960024311A296281B476C483289042824D2C0481AA6105A826421269020902D09165019A1241A852418141102328882349221B800DCC5B10C552CE0DA12866C8FAF547502643B8A02A98FA05EC5CEA052F3BF14B035B89DADCF5CDE85716C2673374E6BE9E8C08DCF4190C5A6AFC0FC9F786F80ABDB5CC0D78DD48201566462C7ADB0AC4CA23DAE66014DF5417CFE62DD7F82DFB10E96A3A0686B115E2447639E43F153B6D05A38DA088A280FF10E7837636A57454D2BDDC54E877CD4B527AC664308C1699A614B6C6E4920026BE5469505A3E30491B8387F2802895F0EBAB983F8339632CA1EB603C2F54130A21D8568E72144FD764336570D719B0731FE709C2CDDFD06598F451EA2BCE3CF5A07F6FA4B508A69EBEA1C892E88557D6CDB0BA6BE9165016043AC6A376786741AC3DC33F73DF74DD62BAAA41BE09B18C1FA3C30478EE0A748F7EF4093BEC0ED3BB579B2634EE0BA6E4D31BF8EC0B7D400338B979A9862B8BA3EFC81155AEA703023372A686DDBF98E1707D63071E47578EF65930084995869106CAF96D3559D193EB6CCC7593596C2DBE3E428FC95965D4EFB7F26A5F8CE601EB2FD0B8AB722C748DC3A1F732E882D9ED645FFD1204EBD73320168209850E4719FEDA0F5E0EA1AC258CD49444D168928D2910DDD35AA376A417A579C0BE8E0E1BF3578CC7448BB0C277B0E147E6E579EFD21CA05C2C2A4DFCFC384D88157A80336F545AF1460F5B36EF41B98F4188226FBE2FE483A8E4CE1DDC10B16A4E93BC994883D3DD5A8EC5BB64D6CF68982EE40DED10611392154A961A4C7A961CAAFC1290324D6D53B3364EE6990D4B4ECEF7295C30B2A004F15C1AD3EE6DDDC8A3A5FF0D9B7A99A35198ED1FA480DF3FB2E136A368D67D24294D4BB4203D8606C0433B1956D38296A891555802BA4F6A518181FE1F9167479C3DF67CCFCDD574E631C874604B86B8A775802A247135A7C15F924BA3924E40BBF41912B1B24E08B499A666810945DEFB9FE33CE2449B17AF3C9276C732CF15C6EAF5A41E9B494EF366A7E7AC6FEEB4333D798748E8539DEF358FCEB1B4182924049C8B05BDB346CACC92E83E84A7BBEA97D4BCA0E9F237794FD150FD8F1A9B94D2A23DCFB207159BCCCF985B01A8F9D0EBF6C9AEAD77BA0433ECFF81FCEE4536CB54478B630676CF8EB7FC4C31B376220C5E6C49C782D7466BA5E7233364E59B92E3252FAA07C528FA507A4C204E79D9C4D8BA011B825961335A778C6B86909AF2F848CE290D07104FF340BF4AD6920CF89623CAE4AE4F53F21EAABA0BD91BA38563AC16BD8EAA42546524000C2DF03CF50AFE84ACB0F2705AD911F896F4E52E7C8F0D3699FD506EE24608A377C8332DA17F94C9473571EC00E48BF68E6AF36901C922D6C2D7E3CC48099056EF2B7015ACA61BBDC02E4E8B8C1F4CCC51DB1CE4BBBF23A097A45BD93E4968FEB79EDC4117B5A5E38E962C1DD737BFCE6BBF66760DA004A009558F73B5A0C6269CE6DA2EC3F49B350A3D0DE04B08E84DB4D2C1D9FA74240E9F0EBBF8027F69FDCB184045240FA2D212BACA4B15551C6C3F990A2D4AB05770CBD97DE23A0F0D625FDB623261E430989602245B0B7C6299751EA2FF5CC3642E11FE9D3D911F893189F7ABCA9C5837383DB16611C39A37D882EE24DE730435AC2123C96DAD7847A0176ADDF49BDFBA9725D0A3E50D5574772E1A9B131A299B4416D86C6D976DB45547F8C5F4404EB824EAC91C475354A2518B30D050081EBE8F86AEDAE639B0FB1854DA56B5859DCDAB0209E6ECA00A5405B14882B115FD8612CB39FF5C7F79DC3BBA02A62E1A1FA3F6F5C0B67EE0416B9C3C55777375CA6CA321E990308C01DEA20C966B148773487804324A916F14DA4BA3AC7DE2CC3CB88CE6FE7BF1408563EFF695A0A2C6F6CA392C3D3DAEEB45ADCAA6E7DBEAD25E9B5FC71D1EAE07B35E72FD32E569A3B783DC3DF1F957DA596EDAE1550D7559BE71E8AC1BB02AA7EDB0A44D3B0C0F796AABA6C009E793350E4A46F82AF02A58050909B27CA9F4D37E515193BD7E794A595018D52AAD56D03055124EBCD1DCE89EF6EC705D98AC7DED9C1611C580AE7247BEB0A8E0A23D888D517196410968F7A93DBFD36183B405A8FF26E8D04D90B22747A95BCA43554CE12B4D1E8B0AC6397B100762826EE25AFF2133A6B8612A82665E6C3B20A6AB65186949B4AF63FEBC9D09E83D2DF49102DE25571C1C453B03419F9AA06C59BCD12419493554A77DD57F8A2FD73CF8CE6B4E6CE056EBF6BEBFA867C303269C7A48386B3530F3D2982DB0983BC5208DBF1AF9047CC7C75D3A29B4904ECE54E52265A51EF0BF1DA09BC9DF56470ADD9F84AEE5DA5C2C0F6F73E545370FE919CBF13040FE562B564C84D43EFD09CD4A86D57A01645006058944E5CB4701E6DDEC2" + }, + { + "tcId": 12, + "deferred": false, + "seed": "130A45A87F380C72BA709CF5A432BF768E1D875A30C860FF8B74BC56A7C8A042", + "pk": "9F256B88122D75E988235D6AC427FE3D896EB08948FF95ACB7A50A3D892C2314A1C5BA8E04EA3D0F352049E24FD868C3E715385F6D4FB8F0ED9F42D6812B1ECB357BD6C5AD5115B87F6D41DF39922E7C98D58E5968A72BD420236D5B9AAD031B7433FFA6DC3CAFD5DE7F6FC2367CC8B9B9BB20FC1EA84B17AE79DB3C8C7F5A5618313DB8C3D42B45066E93B608A2D16F61E04F4216857E2C1FD237ABDAD2B027253F7BF372F4F692841AAB16D2FD320CE27781017B3B37C6BC242748B1B004309B3859445C8250C210FBF8DDD40549DD456A9612B4FED4D6A472A4CDA4514A1F10BDB366BED07C02C0CFD016DCAAFCA20F0D23D5735D431349E29DE31F2145FE90BB753B937823587C1E7CE62EE4F7D5E6D54D39AB3F8FF8E0EC72A49B5558CEA637C0E13CDFA4243A9F631EB3169FE395E7CE3D6EB20F38A9D72CD1120B920B551DF84063737A7787FB1A02B7D1C95BE34CEA9EB938BF6DB6155D8B5F6F5877214507561D41455FB91D431C49112C35E4F4AF5E320A3A1DC27350EDE5444A36C78788AD341B71BBB5DBEE67D7E3591759F96179235BC259640E796BF2B0BD1AC7B2A4342B1BCBFF0FC3443B113E72ED6D4C81285889F492E07755F181291526153CC0433648FDC99D296034C39C90D6401F60C4BF0FD75718CBBD8EA0DEC9810B7297F9B020411AFA0297F30C535542142769AFCACD7DF0C82B44223B2C07D9B8D01B6B8A0322CF26D4EDCAF9F0D1B4A39B41F831F1331BB9590074B4C3C457B196780577D673463FDD50B096DE197CF7E7C829C074B724B2BAD84D1A199269EAD5132FE1B0E995913513151A83CC6D7D9D9B3D0AAED432502D92579E70DC5B26C2DA124BB7730481AF4E4B0D03913CC48219A299DB782B0F149C54EEFB2E7029347F01B4061CDAEBDA4315352B466117945AC389F8CAE9F1ABDA7AF6D06C0DED532C450E50B1B8B7169A1EF9243C9A940714057C064A24C5E565750E8F95BCE35315C3AAA1DC00F34336EB5DE4FC191534CE624D6EE718537748A64CF893D0302BEC7F37CF50C6BBE2B4CA109E80DFA2B0160207407AEA0773C353D58EE7CD1149319D1254846C4235169D4173E2063470D58C363843AC28E2795D97FB5F684063ED2E35086F2691E60D82A0A98084FA90D2F8728FBF0FDA0575FA7F9233573E445030C4EAABDC055AD0AFC6DC4E490E86FE20EED7936FBB5C8EEFB33378D5D68AF4E03FEA06A759801F331FA357DC2C56BB498764940811C7A114EEA6783B181A87896DB9F5CE44F1779437A8F06F33040D1378CD5A6B4E155D95C1E866DB3FD48476C0C0E19A9AFF3DC131B8F8C89893295A0877FA7DCB186F00A4326DC0460F931819CED17E0EB0AEC37609A52C1FA290B00635DB18D22B1B6C909F2BEB231D22B75F7227DD37A8E8DAAB863765F643C1C568163114D338C409D775EDD3C1BE181C80A992B1D1872B874FBA52849B756DA852D391900F147EBAB5AB555A5E9BEDC3773C371717FA18C09651D9E88EE9422F2953BA56BF6DDC9A52BC286C84559CC39DE4DBEB6A2971504DBDF09BAF301BD9660A491BAE4B7019F20B40D73613F982DF356C584ED555FC6E79B75E8ED50475401B0B1F4FD2DA5851B32276D81ABD0C45C6ED1A44B1E57AA25E3B1D79219052BBCD5A990BF252CCF1AFEEF926F7BDC0105BDEAEDB5B3C9020142280E86D2388E323E7087689C0F831C3723DFEF7319647CC9AEDCB4059AE574DBDFB7ACCBA9144A73A039E23650668848A0BF3EB960DD89573C7A0107CC723A8237763AA18ECE34DD26CB77F1A5859CBEECB9E9A38E1265F611D7FD4F6985C9E29460486E0A2D05F3CB6651FE6D34AABCC13", + "sk": "9F256B88122D75E988235D6AC427FE3D896EB08948FF95ACB7A50A3D892C2314D7B62A6BFEA6D3859D52D9E096B609AAD8BB46BCADB81CB2598549651A77127529453228DF894FA3E83B2E00C70242514AD3DE776DCC3A52948E254FF5E80F5FBDD58FDB1AE63793E332F520D44333481F8CB0F70ADC8A8529DF06389BE84DC75C369104052E09274819322DD906404A92250C152412456EC91224042404D834805BC40559420409C69194322664C82441960D2002420AA631DC12840395494A1444A0480E0C10821A12024302411BB12D1B482498162C1C444E194521E1308464342623498061882D4B340088B0081C208A2113855318605A2070D9A6006314801A132461320103B265A3407218127194A86102108E8CB0110C1568630672E2C081241290E446685CB2692200254C4252891444123988C11684212348191284112730D4B88441C8655C1090D442465B207010327020132C24292A84424CD8866C99164A1A293209278D4284288236691C378EE0A88C11200C0320518B96302427611B946594080E02390061902059065164188D12B26C0B272E91962058304601264592B42554444A24114292C045E400320022521CA07192028A64B468D086601B326D14900062062E01B0690CA4650B31610A42124A866D9216410A903109370A888688611889C3366819B971CB940C0144251AC00D19390614B41042448621947102952542940980A049213425D208520BA651E00841C8A811E0041040088210434222972D832470C14210002542A4B24914270DD488680A37489294055CC46453304A09B345CC8640543222DC1890A2322603116C04B930C21206D2342CC340861A02881931442443698418815328691B084204B9441046894A4426C8301002B74D0307690CA32CE0B64002000AD2122242B48490480191262D824005D1464CD1946521998818C72D199865012070A0A28D0CB184D186494334891BB56863C46488306D108049A1224090180EA3444508A700D04851E3406290C648A2164D493689A1048C08046DA114314C308E1A272489842D9122041A3422D31884443805139485CB86688A220DCBC030888648000170E316410A39615A384908B96D0AC38D24B59150366CE20006C328514C344819394659B02460144E14B080E020901241091345041A484DE02686CB8620D838690AB124CA246A194080DB286901C9491997090A080A90A8240CC9401C496510A80492222ACC362024288D24994CEC6E9BD02A0EEC00AC1F6FAAA0A5E59B3AD6D721FD88F05CEAF09C770D8CD7D29CBD845E2DAC16FBC72415DF6FA055F335588659F9DFF7F1C6EDC444E08EC7B62A59695C392738349AAC209B855E84CD5BAB98811E4F728550190C5751C1E4CE70D4795F692ACB1460FAC5852BFB14A52DFE75ABFDFA0F444CA860C77CF84A324646298B19AD7C2B967203534C5976A10EF6947AA67AED44342D448ABED06D52F53A19D325D613BB765B2FEE469B4B7793F4AA47C50F9B737B875DF641164524583A5F656B671CA99034395A1AC133400DB425237A20C21088006701D21D3C0567C8470763A773125D518525F87A0F70A6A9A55B52D7D8EA539FE1DF29A297B83C354A7DE6A9BAC2060C4C72CD11FD2177D7DDF65F8CD7CED7A95EE85EFADAA3B236DD3FDCA5106F1CAD4C528AFEFB87EF14BE8E7092086BEAA44DD8F090D0FB4E21B3B7A23810D4ADA76188A2D8F55F37C2731FC5A4758332036540B2F866D85DC897F3B0000C0AA5E6368EACAF358C515C005C2D7F5E971F5EB538A7B9CE2D202D76724E4BE869A8F0E5B9D888951DF989BDB004D470526AD2B795653073E65070B28B5041C55AE12C7BB7C332ECDC8D05569E8F62E340D497B6EC687294D87FD871A338EE54A72265AA591FC3E55C34F1E0AB7668964C137EC4DE8CC3FD6753E431D748A30AA09C0670B8A467D5CDC689FAB400AE2E5513AE279E43A35B6F79F839AB1D5EE6F88740A794028FF0B6D3D866F3BFE611211F3423BBB28DF54E000042CA0A3EC2A0B5CAA2A570AE830800608E62BCE1D54C94CC2D7AB7718779CE09B8598753661AFC9851A1E08B2FCBBC729D2E8C598F5A145C8D4EF1AB73CCD13F8F220DCD63C06DE02171113278FE5A9B9B73A1B046BCC7AEC817664853A0AE57647F59794EB5A193F00F96FC4A3FCED0AF132F586626EC803F9BA5919BE3667801B0F7C6BC1F8679F2C32929CC013C59C9F9A1C04EF52A0F8B1E68F0D66C7EEA1C59F9521111BCF4CD6351AB7928488856AF77132495AB887F8F235FAB1E15860C2BA8354AA91C49096C262687C1EA866E0D1D23A298D97FA1A950C3A9A9DD5483321AD49E0A6797648361E7A37B16F71D95CE1FCED2F46B8946EA164875B2C42AA4AA529FE50301FCCC283B753A58A8AE65345B5010325AB9F5184EFF37C46737CA9062F108044966E981528B43847E368D52566D41BFF57982847511696B498CDDE34E663D0A0895AF4E52398706748DD8D433C51E8C2E2B03899931889E5080E1511EA78AE0891CE0E3509E3AAD5853E00D6FEE95951300CC7368E392CE4109A032F4F6DF555CB321F16DD7DDA5F80ED1C32C22CC53CA56DFF33B153F2A687C8DA2C5E5DC87D294E45C47F5ACFD713ACBAADC399D1C1563F516CBD5DD736B77C161548659E3A695E6CD85B05EAE9B5CABCED4A1FBCD551759EB0F5E022247EA9877CE88875D9F66FEC1292E05544F59C221053264F7BC209F1128952CF7D17ECFF7438CD2CF8AA27F5AFFCF8E8C198FF49256978AF48592C2D39E895B8DB728B4FB4D89D3C5CDC388B3D75075F9482B43C0A6F77205F17F03F1B76774C36B26E555A555EB7CE1E1C458E8BF8445C19F6911C581E8DB7D2B4F39EEB604295B4AA0A37816C815F42EB9284F536C3777EA4C2B7C3D3D44E8F7F222C8E9BCCCA6AB7A0050551510DE4B6470193C4B5CE91C0845233EA3A666BA39C8089257E7E6C6184C29E75C9A5C1F9F807DBB118D521FAC705F224CD40E5B2BCAFAB3E31BAAB7C4A3B5409049184CBCD20BFDC66F12AB4E40A316E5B4960F70DC105ECB99C6AB56D79906BD72CE119E4E31672D7F7025E4BA548D458BB8AB782158304FD5A95B4AFA5EE20377F137E320DCB333E7FE1F13E4971B8E99F2A3995101E9EEE3950AA1E0A898052376B0CDB28A7935820A082CF52CB4A6A5765A7AF9DCDB7E15B70F1310A467F34B0B5EAB49A54114CB446A7EE038B84015877A305DC97EC70086637F38679B94CDF4F52E93D20D1520182C20FABCB9B73341C0023615D59B18C857BE6206BD10ABEB2D9794E4806C6EFD39D2FBBC15047ADC873525837275B4B9EB0863F103858BCE9ABFE9FE950EC911BB685D768CE07C72E7D7BEFFECBB0EA219F13B0C5EEF74ADA957394AC961B7B365FCBBA9E53DC6F7DC4683052A6EDFB44BFE42A69C4C16E3E95B61BBADF9BB294DE9D8798AB62654EB0DDA5C1DD714EE69E483748BECC6329A6C9709429D7DC7EACDB21B2EF7B8FBEAB834AD755CAFE804DEA4729ED64F8B8DC0D5F76C4554362599ECA9759183E4B52635B09D33B871E1AF49B323E32A1C6C465C6AA9294A30BB6984E188051C148F90FD6948A0" + }, + { + "tcId": 13, + "deferred": false, + "seed": "3D00709DA8D78B889875F40AAAC1635D2BBAF0BB7F37F6C4ABCB7220A5808F67", + "pk": "C978D4F3B96E78540AFBACEC073B62B2C94FA53EC08D49663274298A806D704B1ED86941A4FD8C65EC64BCA35BD1254033AB9B9F83FD10406E77D73A6DD23DE5AAB469308E43BB96E205B65008BCFD9B6D83837F96CF8FD82C9E3D0D3FBEC2142D0FC75E6723583FFCC4B19CBEE9A6431001C892871858663F1F4F2FF3E3EC36F099448C153F4ADF4CAF6ADC24C7C5058B9B3092575A37390771657D3D471B9BE02EA2C0B50A6493B78D0361DCFB877FB026D59C136DE1E1DC14E65ED16C1726ED311DB5E02601AE6E03AAA8E008725A9364A9762B1D12B35B5772A9E001D76B3F0EA3D3D9A016844B1436B967FB0448CE481305DF3A50235852FF620FDBF0897172135B8C528C449E4C7E49D6F84AE71613F30FC75DE26C6869A5D0B98371B92A9755BF2752162028B25DE982AED49EF9D5E4050BC4B2633CF537AD76FDCE838091947B451D16512B6B370DB983F86837F93416AC87DDCCB2926358FE01FED867FAA2DF6BB7C001B367B56FD5C6925AD63F06696C78981DAECD4E90AAA51B2B2A809425E5EF1A884061AB0034689357D84BA0E6282B770B1ED5D5122B6C43B446355ED8350BC3B6183B4A96FAFD1994B0E1D52FB337679D4693779226C4B7AA79AF2882E58D74C906040DF08C36415F330F56BC8E35E9210ABAD998183C6F8A324B30BCB4499382EB96FD595ADC129C68FE0855E584FE716104F663AB2194F7683A62E217ADC22455408CFD0419D157EFF8AA816DBF6A0AC519391DB6FD2B95869B1A1D763EDEACFABC4F086750C26C781DDE6EF3B19424DAE49289C3F2FD7AD08698C05D0D121B6779D77CCA6A00AF1E37B6CAAF3663260EB06EA77CC4C775820724E8A4CE66BDBB446B61CE7C195AF164468B111016A8BF2B43247EE076CB7F27FDC3CE9A97E506C7AAC8F16F675969086F38AF49A165717C694612F3CA4BC9D3DCC5C7CA499CC92CD76CD535DAAEA822E532A9231BB965646E2FD080DE1346A132F4DBDD7C7201CA26735978F5685EF35B7441FBF37996C7059F56AC93E07BE51B66D270423C6F6577AF624A6BF257F2CDF558C0F6D488EFE24B9EBE7265D2ECCEF3034F9D26CDDCC2861AC97F156E814E44FB859EF4FE39CCB96DC25848E1CF9174E38CCB69492ED2E4F2313DC76B0E169C47246499C0B01252F6A00C7258ACBEF3351D131D5F6C83EAF2B51FFAFC2A0D274317F635FC159DC095898BF0BB95A6B32D6FE6A0C6DE158ACC5A6DEB222B94B74C3E4C0AF15266BB455A5F5BFB8E60533771267E0BAF8982226578667D80DD16253069F5CAC2335D80ECCFDDC1E37A79256AE37077F452AC28B8C4602C5C4DA09E0EBBCE8069800C597977B5A67A36DC00C3AD0B53D77F1D19B64752DB3866858D5B4084E99FF28D2A834A77863816F569E2C929947E92B354D1229B62604DBC83730E1AD9DAD41E7E6B8016B77742514855B75D2512B9C88C7E3348B5047D0B816503439BA38A0910B1A0E14E2D95CDC1EE0FE8FE2A80E5F6EF6BFD4409760FA8707C44832A1EB0061F6F43A615461E331275E1038E73D78FC141F87D5112BFA2A1A4452DE08A8ED6F6FEE57F99C7DB5D1E4AEF0DCF68CC28D0122B312720FD91B50B40655557D4D6908B43284C4390820457F4CE5D21C82224AF09D56D4ECF2BEFCD658AB0044DE320E609D826E57209955355F03C8F41F2A2B91CB50460CA398EF778B3B1A83760322A6E675065E80B72556A80B774E1CC11EAD767AF196B8F8A87B4D5482CE88BD218C0AC6614558E3E81FB1664AE4C99C680DA41423368395B9972B0819FC0B4639E6704E4C8241A500308B5319E971972D1952A54DAD62547FC263489E2E6D61F02C1", + "sk": "C978D4F3B96E78540AFBACEC073B62B2C94FA53EC08D49663274298A806D704B64D929D9BF74F1242AF230B6A21911E89084290C4CA9B72C13C5824A6324C9515F2D8EC8EF5521FEB0F6D63388FDB8F04865596B97351014A825D9074E0D1A411698EF5A6B19194A18F9DD2E61651F8AD2C2981627EFD486EA75220666F4EA53E0860044B2404B3885C3462E50A83108142C9AB049DC02852138480035710C290102236A89C2401CC928A0942824082618868053164AD3228D4C10461812050AC628933489A4B80151904DC0082613C0005BB26119260ADC383224052A028868A2841100150DD0328251A23002B68D9A826CDAB2090A4266DA26640CB10583C84993484890862D1C0611C0222D0B14889384710B262ED9A6411C0331A0C280611066130288E4326AE298658B926993928D59B07118164C1A404E0B192CD108682182441A036C4404881947324A14081481850B104C10904CC2A61188402C03B36D19366890364DC4382481C829D34225A0B08D14165221386DA448681A070644B8301BA125D3086A58C20409135221B60512A288A2063254C84D53402914C8691BB25008B66C9AA42052C231083425D30409D3101013446E2224294CA60118C410D040724C060019C56D9A08729CB228E2966DDC1062620284D4160E23B760A2B2208B400C52B61108382D1C04800BB88D49184A1A4009E3060A60209004C45002B62941425219276418C7400C34220017290C26015CA08953182D0B2948181428022186924070DA26101B468E12292E2294100CC44C20C96C543631220180042491A436099A046E61140AE4326A9CC82CE2248E8B884C9C264CA3024D1924820C30691A050102B26818168E12222D880488C0C22CDA00649412811CB32144489114380100A509210990C8B000A400421BA8881099718C462AE0B00802352183120DCAA088123850822489C3826118B185D9342A51A20451260218268ADC282DC0A6090A232683B449420491041689C3A42403820880460A481826D3B4519B905199480DA0A471DCB6910CA4649C02840838028A080E1A030281986DCC12882334669B342C1AA52808469212110D033764C0242CE126328B208803252EC4088D1A190811186E0BB1014128648A4040E018329A840102A70011A269E44261448489A2306EE11490E2B00D5A0666D0064AC01692DCA65109B948C89424640640CCC44153A6240C248D5822528314519A8680200306248145CC1462A34682D920326ECE3A61DED4ECEFCB1BDEC41B15E8656E2F2AFA8158B7E27DD27CB0FA892E3F773322A0AA29DF9434A5B04D92F1AD4D6F31E6A1D6B7BFE54E72552929C886518BD5F6B4C7F473807C1C2AC8AF14D75C3790D6308496A5A81318B386DC2CA818D1D74B11AEC0DCA16041AB31D61DB7E65146F35ADFEB0C0585E116A8BD65747C58E1578CD5D8D404AB666BFFCB57BC015D841A16A126B66034E1D44C8B1339EEC30B0122948E66E8DB060DFBBBCA8B12E8531967820A8C35BDA3C945D3954895F6E67724C88900A0F93F667947626FF19CE2CFBC956A8DFF62BC4DF97CD136341264BA2B181AA0F1EA4E3C520662085F77523D42A6C9395A06476A46E8E275C0331222C49F852FDC634EBF7AC24F077C7B0557F3DCE457C24E1CD981EC86C149A91950D716D596381C4719D63DC9DC5A775667665426EBAB1D5E7AB3643074818951C25D43F79E82D8BDC4940455920394B42F9E95871BBFE837AC878D9DB48AA976A609EC33A9B9512A81FB87F7C502B676076E2CD70FC9DA795E274F3D0CE12259EC555C3ABEACEF09AAC80F4F8C41E077E39AFF7B5D97AF8C5B61F701AFDA28101343C8ED11123221358507AAEEBB6025CCCBD49CF41D0BE26DB1A95A8C5CE60E625493ACD6C39F035B9A4A200604B94CBB827164B6CCA42CBEABF46B975F9B9D57849D46A986F645D2D530A6DC5611CF92D92AF4C93350ACDDE4785F6902416AF43305D65B949CD7D29AAD6C9B7A3DE28A8983BA4E7A9123287ABFA00F7CACB6FE0C868C4492B264FCB58CECE465A736BFBC1E0403A1CB4D2BC36FD0880234DA2F90C8FEF5F0E12E47DA3EF05A15BA5DE31F67DC929421499DF52DBF00D604238F8C179D578162C65AA4F980460165ECB8D08F53FC319C51A715E4D8EFEE21B8B37AC76ADB189837D8A0C090A847AF3B0E78F2D4F2AFA2714B64F75E076E95EAEFF03FAE2C9A7C319D754873D3A3EC115D9DD5625B25EADF0D00EA12DB8988CDC167AC480D62AFAA5A301478304CE6187B4CA7292C0D4743BB000E3057E1DC899506EFBBC25966BD04EAAB8B6116BE3348DF1D3D6C2948A2656AE5DAFDAB604E38872436C5605B280308F8F8746626272CC9712161E5CF095DB53862FF1F38B40FAB69B81821F911073D4A098A7C6EDFE8632C55A9008D50CC1595835304BFDCFB43F515A00DBD0FDC0ACD5138B5732C50EBACE2867278DF1482EF3FF77F6BE06924DCC636FD51D72F3ACA4677B2119A14FA2E3B2A08C528B9F0A191934DB195D92D9EC305222E79B976A577788DDCFB030D47820310AA23F4B37AFB03E2460F4E278CBFCB30C9AC95DF06D21EBA32FD11D52A1AE8ABA6CDA337172FC863818ADCBD25B0E64C96B38A5C706BAB2C25FA45A616114C0C896E09D0A9F8BD5B959AC4E16043720CD3966858BD7EE6CC29745F6592B63A06772DB2C98E9373A215C642AAE4FFD6E84CB47F7B8E19D6B355F35AAB5BBFCBF16DEB73C2679A1A1502F9F6116300D54BAF65948627EFE620803A4F2D895899F24ED5A5B5A0EF8901DE2725EAFCC41F0064363B249A6F405663F550CA82A6DC5C5D04C4EC425EA7F27BA9C3B5C135F1EBFBA4BC0FF8D7C5E7B429005E5494C83FAA5C63CB73BDA47928DB74917F5117DA9E2B939984677EE84B944E0346072357610B0F2374D12910C8BA428628D500A6A57F3E3AB4752FA5FC4221DE5C332C70E53E8C48ADAFEFFA66DE27176290FD0E553ABAB1733D8CE618106D5C80B37B8D3068A8B9420ED1DBFBF7AB681A4FD077A5CFF186A44BA908D268C627F1A16BFC2A89782BC2933A0894FCB09A6DAE2B99192CA6934317F79EE65E33808267306919EC2AE15D7F8D98DC1B0CB34DCF0EC6AD5A8E6F23372E24E1788B0411347685F0A4E552C5B906C9CE64C0489E0A6EC183620DD4F0207637952F89F2E6336AB38A357DD66D14EB984D8084AA389A41E0EA910043B139EDE4D6646C9FB57919CD1398D417BA48B7B91385D377AD145F547EEC67C535CEE758D8286E8B8000ADC600D1C037FA2F2ABDD6FBF614DD626A759C9C4CBDB87076A38F3895504C606BE4014D57D7F2BAAFBD7ED7378F338EA58B2BD638EEF8ECC136EC311FC34E2E1333792C410667561F96AD2702CD43EAB97E7A8F5E686FF12AF8DC264F8D0CF66AC0B1E9E0BB5C30FAA7532F18DE7F75E80BC04651ABEDE5F0AE0E6AB17546B34FA9850EBDC4932FEAE13C25460343DEA53C1A0AA5BECD55D9610C7B79AC4FDA3C05594C3E220E455B2EDDBCFD433546B50902A77DCB6577F07BC871D4DB3F909696452644236C72AECF1B7F8518D9BA7F8AA0EA7EAF020D0358770C0792B3A07838C58F4845E475C7D0" + }, + { + "tcId": 14, + "deferred": false, + "seed": "530D229A951CE81973289F186CF9CBB284D9A0A0888EB818D6B9D78648E074D5", + "pk": "0BE9F87E9D22D6F112A39CC531350A306340AD84F313CE18F456F135A5C0DBA3B853E2313ECD0BE07350AE8AAF22B5B7F10FE05CDC62C00F3DA4B71907F73315F8BC47526AB332F78AB20195ABCA73682E053F4E13F18036BE2EF3C8B01BDF1F21510169D447A9FE87E70BEF56CE60168DE1C9312002CC9E3B680ACC2E13F0D5FBDA44370DC9276EFF999890E7643B3B0BE8A24D7175753FDB1E31CEBDB69EDC8A9F2BF176365694FCC4DEEF0C8B0B1DA3020CAA1A767F20A9F36669CD82D471328AAD31B2FC325901371B36AE637C180871813AA481EDA4FC0C7E2C0598F93E96D907C72FFD87A62F79C02D6FE60837707AC7F52BD3A49770115084E958730F42CA8098B87171E8579511175FB616A73C86D723D5A7EA67F35F1F6088A2D7CE48FA57975328D238BCACB26BDB0CCCB372A79D96F9C09C8A5727C93B36C7C3A2B2476D01D5077190004AC89967AD1973614F337975FEFF7D7704E14B61265377D37432400359F5BB2EFAB22B4F65ACD86C4C4CCF94FCF73C9FBEF68BDBA59562BEED19871A849DF1DD7F4A6B910CD5AF39D4A9FE78A2ED6A93790A578D774475E52498FB175E3240D6C5F02AD7F3D527450AC5748E7CC5E8D3E28BB189BF59F2177BC05E939B81610DD8BB6E895351469F3BF0A6116D993F4107C93B7DFEFDC35D182ABDC6D22769B9A1C2191E99A72D595FE5D9A93F96E99D9A913A52B0BE91C6D4EBC74ECDCC92EE580D84FA62397236427F7C057E963D662CCA4025928EFC272B5850AB0C13BAB34591AFD81B407752CEBA1C3D7D49786004872C51BF73CC11A92C3905F5FB96046FF0D153D43DC1D3D9CDA6884DD2BB37EFB86D9DB6E58F2882A16E2A254BFF02A2624EAFCBA3488E1B5F5322D2FC54AC7767D418D2B5D7CBCF7F20D6F77F118C6D00D10D7349A57296488D16C4A5C19D2D4CBA1B9C89B3C76D647614D3F2242F6A2BA5F8C602CC63B69F22BB104FDB6F7EC567685A5BDC55A95F347E1E54223E32C4616AE47A6CCC3F4FBD2DF3A3A97417C0BA457228E0AD36E2FFD7F8AEF3F089DD2ECD4382467BE0A9D5A47D85CF7F8FA82CA75652D923D4FC73FB4D9D39DD9EFAE2453A4FF3750B07EB8C0E1DE2DB8EA85E6690D060C21DB933B2F2364E5282190906FE5515720B9A93E26B2B25C66C5BF8B2B3027E5DA94BEE09B5CB8FF7403F9A7A65AED0D8422440F704CA74E439B06A25236964C3072943B17F82BEB48770FCF31EB366F29900066F95BE6E285E5B79F375414B6282DDC91A2EBA913976E9897F90059317BE155110D44C0B5A986D98D866C2EEB767F18F5FE4BB4510895FE4483A4B6EC9DB706BB7DB77E544D9CA9545FEFFF39AA4519C55873873A9C438CB345A542F989C5C7DA8DF169CEE4C9396105FFD5C9126E128657F3DCFEE744BD24BE2E104B4F541E74B980C0CE198C0C49770B66D8C56590FC9D9480BC069F0D673EC3097ED1A383942EA1E995134924074A4A2C328751A93F9923BC22E2CFE15FA4601A9D268EB53B155E35F57365DAACE0450C7B3F26D397E9D05ECCCE3916953465871B494D3A6FF94C9479D5734327A698E5E743EF37A5CE4CC6EDA1D659F416B2CA2F002DEDF6EF3117CE6235AB3B419C130540DA42F110875B12AAA18427334CB9B6C5767701B365C688ABB7F9F6F70EA29F7A44DC9E4B74F1625FC4382B60859FCA7C54F210429DDD95033886AA1DBE4D44A9C58AF2572BFE9984E73B9841A3D306FCC5338BBBCA1248EB5441A1C0372920223AE484E96BCCE5A419CAE46A031B545FA29B3817C6C1962168CF0B102CDEBCCA79D2AA1841588D2D2C322E2A2870B8737A351EA147E25FD819C7287627A9A", + "sk": "0BE9F87E9D22D6F112A39CC531350A306340AD84F313CE18F456F135A5C0DBA303A61DF0BA0157FCBE4718531ED771978D263E0828E642D25C92F8C5CC96F7D6EC769BEDE7FB414B8BAFB3214D62DFBB2ACA9695256DBF80BCA6E85E94C9CCAE4FAD63FB4AB9CBDF660FC6003C794CFBF02F86536880C5BD68EB5F72C198B98F0B9200198328E2246002224D501412E1340C0290305C48625A20301094015B406258168009292D93466540286D5928445A382D8230119A0405238000D14688633472C4C00954164A9AA4454100251CA76C1C398A08368C1B1412CA120A4A260C1339511B4071D902309816269AC02003962591368D9A468D5A121021C35051448AA0B089C3062CC8000E24241102A6302224659A10724926218CB81159360848B268D844229396001028821CB1011A047114A884E0A430124928901226E3425121030901091209321113068819158E00970D640000D0126CD8B271D1380C1A8329C8484442023180042513B701194962DA40815244284A482E13306922158403A48913024213087209404A63248D04A069C8046D13330CDB9429618890592025C920404224090A3880DA006501C6900800828C9040C0C4219010490C496C22C30014152C08156688C68901A431C3C06141088E60C28C0AB841033061C0A2919BC48C1A074441280E181090CC322800005202A708D44431592212DB242452081019420164026D93A26C4844220B1289DCB25000458824148D8B044ADA16600114729B48041AC96114C56162262D13462D9110214A044008180C51A2099B002562B44481340888C06C9340510A308E1AC3311329219CB09008186289320E4B94285080811CA22519168E1A428C114321189205A2A08961242D1849848922110B108908276AD03248188804D0348908A088DC088E511089C2326962860D03982084265103B868D2062060402AE48890CAC25190B43189488DD42030E1248421A000CAC82099208214C67018B22948106E00385261C621042869E408621211461C40725292205444849A004063125198B2206112859AA0089B240C83A01024414299044D210484C80862411490CB0829590080DB080622392E9BB27184A050E1B080C2140E11C42803444294B4601B073123A1808A326A248160640032423489C132020A14844A10125A062E9486310B04209BB4491C268D4AA28418A78D0484911B18811A47245BB281411080C016080407910112108C4860D0A20102198C211330353C77F4FA51B59E01AD4CEBF0E0A3CB5817C8D3540E554BAA1905BE97C6DD0F8D109BCCED7F0B95B8292F64DC47031E73CD56B8EC0FB415F1C271CE3F21BFD27317ACC974185FA816DEC34A1135E5D86D0B44D83F33D41BA320AC9B1870E0D7C91FB8C88EA6AD1FCFC2334AB0B023B7E86A8D5CFA53021CF33A84D9766C3F8FAC0C3ABE0EF6329E2B809BE7EC6A801832052313EBB604BCB4C73913506AFFDFE7D248D057B66DDA6E00D986322FED8AA3434012AC2C56694A5D81767F307372D85D3349A32AD7A41D0CADA7ED4D1A5E2487865E94CCF97D27D2F1397E613B78E57DBA3A051FE026AA8BA16493B639227BA467F307826C9EBA07C9D63D2BCF652B063703BBE4899F7E620641C3462C3CD8ACCFE4EA59470882413E4B2A156D70FC7B963099506991700CFEDEA0E196670EFA1D268013D214D21EFAAADCE3545511CE827957B4717B23767D2383D47897A009B61BBECB9D9FDC8BE188C08CCC7A3E4A4780CEDFA1D22501715FC206C245514F742337F5312CC9696331CC0338644D03FAA23E18FD3581C5B9C1EAEC31471B74345999057AD35A74BC1745A196CEB5BAC9C49E64FEE7FC5755375A594DE9895B15FC1248625497E9C4A5C8DEE57E488FF682204B97CD750A5DDEB47CDE2581F5091B3E20AFD9C2D6FB85A454BE79054380FBEF569B7ABB08E8DD53EDA5AB1D878667770A35FD41F2532F92BC0022FD38359FCC4D21E3A492D045EBB2D0B00683369934F76CCB35485AE2788D5309EF24C87B8910E75120AA6AA9A76A75083AAF0CD64993F8B892984C6B26EAA78A772648918DB8EA4EB00357F9A87BFC500164B247A78ED13F7955588AA504EB3A81243C5AF252C2F0279F05166047B6B476C2AD0897A39052E6FE3E8A4A2FD3F6DF1C4DB335F432426590D28183FF469B9025D7E1E176FE63ECA2A5B18DA48A5007AFA11A04B88AEE65246961DC14F9BC3D821193A8FA0C7122303FECBBD6C1CD668CCF9B38EC2DD1098B53FCD43E68538FD9FBBEE399EB5B69B3EDE9FDE03D813E20DEE209AB044A79A09217C316C4A5298EA2255D8739D04EAB0F6714154B8E1035707285F1A9B9791A1D3B230F5A09B41C3E2059EDA5616C120403EA9EF0E15A728DE056EF00E8AFC261D083283B431285D945614E3B78436ACE4B103815CAD8FBD86750E7A021D978F639BE399DB7FCFA45D244BC469010CE0D67136A369EF5ED52AA6EDF7FA98345A9D9F28FFBF681D1496D349570970AA1BD4B3632010924F8AE0AA4A3ED5F6712CFC272C4E8AF8F6E77FC7C176863F488CDAF4A770DF7A248485FA731BB2E209C2CF6191C93EC9FCAB45D620116DC0B1BD6490B7B2E405A3ABC4312C5C8BC910DAE9A4C4FC70FFCAC5D9368F4F802785BAC0708ECAF3F8980E21A4D7C6574484364D28082F67AEC77BD36AC76303DC8DD0B7ADD0936BD528E04A0D480D735091EB361A5DB3F3F49D7CF5AF418B77DA7FB618CA12D67F1EA38956AF81E4350B0EAD041D3197092A99C2EA260CFD494D19410934B0CB9F47998E8A549A40406635917572B7B591F30CCB30F181C78217CA879414B95413FA38EF730A0A04DA02953B22E93A5F12DA6BEC17140C824A2F40EF8165C9E66B48DB26AE45642191774FE4753417F05F74983360B1797724DD201EF293D2BC04160B8FB638E47CE55BBD6EA2520407F2CB1175FF5DDE1205BDB0A75A0C4B7F1017AA2C032FD427DBA6CC4F448F8506EE48549BC23179AB4F8E53E86ED1BCC6F0A785D31059E79D581AA67E637AFC8781B0ECD69F3CCD225EFDBF0AEE458BF03D30DBCCFC77A06EE928EF5448AF78E9BDFEACEDD20850CCAA15EC3067AA48AB1338ED4F83705052DEF70E1FDFE8F23C3C2E1378A8F9DD3BF5F1D9B44E227E96D41FCF54AD0A7008AF31AAD2979ED7CAD2FA386473C77CE6779CCBE34D6137C1BD6375F1F2890816E43A4BF15B9CD968D4D774B5B0859C709494C171B48A8322E233682251E93A77E0C9A60215B53616C7F51CE9DEA0C58D8477334D055892F90DDE0516F61FE065BC25690435CA8F6CAFE850D1B0DD659FA01AF0A795A95BDE40030873B2AB78229DA43411F6BA8EA33C70D5B4BF5DE05285399194FB2AB4E95B6DB3A8A3DBC02F9F8C2550116670010958F69627DD6D0D76BBBBCA897F42962BFDAD0514AA053F45D4F3FA1088FF0B57D9F8587565740CE29A4E7C10960C8C21CEB9035DE1C4964495C6257191161AB4911AC49648DEE4FFBF30D5239A454667D139C7A8B4794774DD9410030FBF0A75D636834A39D41FDA3B39E025A247190B4B113A024C62F9B9A54E36459A050D6D7730047CEEB3E6CA74D45671D5E22ECC3" + }, + { + "tcId": 15, + "deferred": false, + "seed": "2FAD994FA583FCF6B858B58ABFD4B42FFA64D552ECDCA55878EB62A0BCC17280", + "pk": "EF4A349F3CA0CDAE99BFC29C75DCDEAC5C0543FB2D6A2E05AD41223713DE2DB80395B221099FBF9C1A8C17E4D01FF19D578A3D5DA2B1381546968198A34E64639ACC8DFF2B806E2D4784662802DF0292391A40B48CF382E7CCF55DF43FA06C2857EF61E82A4EC79B02D1A732BC6951445F74244EA7D9F14CB715C4C434D5083A228F734507A5D0C5C83E54FD711CEB0D124D37406D5B75DAD51AB6DDA66D8A1FA9F4EFA6E3B1C46C4070D514EA46E4D21D5C4F7D4AD3ADA7F069F2C71FAB92B2A9E88FAF219ED4FBB5CDBE82ED767D687168C6D7643E742C65AE62E0E93898F4EF6ED8D5D368AB5748EE940B397CA5A706949C6CB762993C96D726EE442C91EC8B89E38931BCBF4C294B8ECB222AE419C35B4E63587C35874316C941F20B549FB2E5B9F1E83C8FC19D14007F59221536422E116891AAF4F74785A70B8394113D497F77FCB2DFFD05931731C6B7B70CD2193F087B74D02F76FA52090B5464930791A3B2B01B4A6A756670101DBCD798E5C68D3AA00F5BDB7DAAB46B8871B6117541715F85554F76DEACC02178670967D2152F5500FF343FDC9E110193161DDE7553312115DECAC29E934D46C3D7E3BC4422863BD7F80ADFA4C601E328A04C6EB10D8BD3288FA0AACB67B475F7DCAE3B36F5C51A1987AF89EE82A9CD1F91DFE4197520DD7B1D7DFB4A0D73607EE20157AE2BD70E1E5916CA6A7CD5ED8E8A5864409C1D82C9A469E2370530EAC606AF7904573AACBA0242D34AF884CF4EBAF3ED6C3EC3BE274D5F9252D73ACAFF9A7900CB72FB0ECA12783FA6FB82DC8CA8BE2FF2315D537764A175EEEF1C521A5EEB857C0DEC2F8886F3A11D841EF72292AC18BA1372BD474FDC153A33A13A4F88E9F53F541B49FBC89618CAADCFED7B837B61DEB8CC2832189E966EFDA2CBC5B67C1BE0D1CBE2C5CC3AD6A0C0386F009FA37440C3C6B9A2E38FB38D8CD36C5898AF9650B609BB5C17F006F306A23D24C9487C423E9264D5F9BD592DC57A6B7F55394B8FBFC7B5554D091AEDA0C810E74640E81067437E5738F88917DAFAAA9764AE5DFE741CFE65AB6370F0FFFF4B41472F12B075205DC1879EB6719D69F43CB18A04E5E71E5776F1987BD5B6F8A09F9E34F08B95E75E406B6081B2D9D28C78E3C512F52C27228EC1DF21EE3DA5EB4556E892D6975C52D3D5C356B2DD3E7F3FA4A3FCA1959BA6D55A2F8599933B61B78A97B14CDDEB792483DFC32EC4D7C4E87F0258104A9CE53ABDBB4EB68B144B31D8AF2118B4BDC717DB70C30AE7CD1899AB621292CE06B10C7F8DA18C038AAF4EEA3391D4B979A2BFA82DAFB40DF9538C4ED406CC9259625606A7AC12E7114374358C2260282400EAD169F7C28949429C4972E9A550E1854A48EBA87269BAC149FB410980C77AE49B7ADBDBDEE36D014F19652FDBF3A8F80258F99D638E79D10C02F501E7A36E6EA03D4853336D188A744E403EB775235AB6E173373AF151E6D7D1026CB570F44303A4C65E2C5FFEA0E8DBA8073932120CF52AA92A913E8EF08E0652C99B9239782FE7332D108F461B16D2D8708C994EE15A2AB66F34249A67585B91EB27435C9850FE3C67C061F56B78458D37B2C77124EB9C174F3E845C67F6D483DF9E6690C26F172F586E31D1E2ED17A8DDBC500AE766369A15726C666C6437773A2C22F806FCCCD4392DC82DCEFA6452A0EEFC9CADF6D98E041C4C4410FD5E9CDE5740D291E254B1F1C80A39BD1B372A6CA71E315C4109F5B2F82D957B5BF806A6367E993A3558454768DEA69934F830D27477C3A44055A542F7CF0FD1113A9DCE618D22701C60AFFEF378CCA4EA6FF5C5242241F18C88BCDAD77856828175AC96E1", + "sk": "EF4A349F3CA0CDAE99BFC29C75DCDEAC5C0543FB2D6A2E05AD41223713DE2DB83344D92FA9003D0A2BB89C66DDE0A2D2643976E86F9DF03B88D6A3D86245243CEB0D6C13BB02421CED2306B68A2E3F38565BCA435BF88E2DF253A05F40518A7F14FBFB3A0E455668E852862AA54DDDCCC841A20DA649AC3DBDFB05BF9FDEAD6BCA882480041112349244B46013C67124C90059908C232470204824022926D02688C430044A3641491649E3963002230522154422C74C82A47051B48D03B47004C984C02262C9B08D1C21664C30492395600803658890490B39910A1461A1A42524148A01878844368DA2C2115A987009848461B248A3968514424604396A13381118270D932032C0A86152322E22343214C48D82B024DB304C02B40108837193B82C03992CD120628A3281C0A48924200AD8382E18206193906C421030DCA88004008D9AB68D83C04818164DC1C620C1286621B48401482890B42D92907121B670E1040C60322EE1B69114178E53A041A3163104C50549B2651B05464B28910A208681B28554204923B3891C14250895091AB48580822D6292880C37841C38101C26611BC160DCA630E4800912280A2235695AA849231966CB12515B0060192026CC142619066E22B20811387049948443A624C0A491084029D448611AB44981B881231850894088194546148848A2244003028A08280CE2B03019336E14270523322E1405645A4291C8946D03C328518081082564D4220952B20C63388E5B1621038120E0844520C6440242688C84000B24521BC5084494618BC44C43364A5800891CA250D8B4894A304409B988490426D9B00CCC846050921121C92C18C250C406622191441C405253204D0A2528A4800C8C040801096911B96DC3446E401031104084100850D822091A21614CA03000C88443B02443124942B6846004818840400496498B920010146019A2015C460A0AA52C9B8090DB820800951098B4301221688A14081485844422521C4680C9324941A470643831230840201031A1323224340201334E090910DBA648C816252417102009811AB180C8260104314CC3442663A84C211606A3042E10234618093114864CD42608D8A671D222088B344512A8318A36668A262C5246602343225A2466012649234861C9C6851B0530DBC2505B186851240493A80454B2245C08084844508C964DE4C80C4B22849C4849204790DB8831121069DBC444C238488942848C100D8238441C077192064A02227061FEC3F15580F6044A49D7F992DA568F3C4ED4997293CB8B6AEA2B83A1CEBACD46455754559FB4618F3E08D63316DB0569263D35968F0938EE15196F2AF8B2128443FB2254269695AD9D92686A4A2B3F93872145600C1765C0EC479267A24058FAC9F7E0DC0D810CD780E1047A54FC388C97F84230C277F775556A07161328D7993EE28E418F4C29EF0940EFEC7060FD6BB16F75E433A6F90CC3C4031D991854D54F906C21835AB673390745628F3099DDF6AB5C6D6D3D345BF0566B5A1ABDF15F9D1678817D2678594D56C14B9BBD745DFF9FC352610E8B7B6F58D6087583FDC40B6110291885CF2B01707D4737BF6BBD9216D8C04E314FC8CCC719DF819D6DE97E7CADE9F3830FB92C5D1B5CFDC2DFE96218D08968A3BECA9C8843B13BA3E921AA5DCD4547F5DCF9AD10DD2A2AEA30BF2436F95591DA07CA04876F5B0AD00567AE9EB65E0866F0952D9BF9D813772F46482C4354EF3F735286E79EB70A963FA511D45D8CE07D5CB83133B2C85DA7CCA0DDAAA056EA1BA1B94F3A866ABD801232D8408B2616D35E05DDAAB76C72CC08EAF0FB277DA53BE76C4A8D3A91E13DBE99A5F7D2598C2F15C76643F85091BE549D37F0DDC876754EEE50F2E20B6D0D7EB9A4B0294099216FCF0EEF9E7FF2076A5D8C3ED0977B2BCE37EDFB1CFAA7A250F238F65540A675C3564498F1DFBAB6E238DB07E888145FA4314DCF25DD070956FEE9E92EC13ACE4976F1614AE0EE5CB649D4BD91B0EA96A6D3B46D4184F240337D46CE3052B93E8AD8187D20FD11090C3584F2324343879C02FBCA34CCC36ED99D29791A7F89BF5C0C311F28E36FD8239FFAD0763546F4C09A2C085C6227CE4D06B33EB5A90B261CE90419199032DF0163E76795269C79202BCB0E6CB33F06B6BDADD48B54ED69CDCB1491D97106CE6C9AD47B7C82C2B8E82A6EBB9796C4A578F87CE5F574EA3F9E27222A816D50466550F5A87CBC499BB41BC7105D7324E4CE482FCC6A11A7CD8B10696808F1FE8D687BFC2C235840C6BC9BC306CAD75998F71016D3632F090ADB270587CE4301FE6813C63F2139352747577FD6B0A5CE15E0CC7B46392C16EF6FB39FE1F7EEAD1CD4E4FA930B60F676A5F2512E82E6BED63D5F4A3910B03E4C2CF55EA5DC42024FE460E2A5953B81EFE8BD8693445596E228DD4EFF7603E361DC7ED19FC81AAB6DEA4E50971D8BD011E6C13C2B3BBF6AC5733451954D1F044D640E535DC50E8E8F779B52A7180120A7107A989BCB77BB0BDA57CD638F84BE75DC9ED9C63D327F3131232D73A5BB5C3FE20BCB63305090D349E2A773B865FD11BCB3209F024B42E9B2ADC9AE36FAD88156CBF190538C947C6F4F571ED54655C47B4C47FFE5D8C6CA393E82223E48433C75E9061D016A42A62114C17739828A1FAB4AFE2E348F2494D952B74E9707FB0BB74EE3BAF621E7792916F9E5C3486DB188925C049035C711E193FA0090578AD5E47F0634ABBCEDC1CC7CC32B72D437D159A88FE76E66F900257F0E59D107CE9D79CCE91AF2B47CF061F96CD0C12F35985166FAB3E2F4A25FF3DBAB35FF7E30859A5390DB06B68E6F0EC3CFDD2286B356827E8E362D60F1F7687010A7F3188E8BC8A67C4B9BBCA16CDC3DCE5A269A252C6A149B58901DC16125E5982D78163D6799814E6694FD39E307CC42F43F81451EA8F13704C5F44ACDD2A11BA9288580A8698D75600193B33088165072E0EEC47E29A898BCFE9C03DA583C060BA5E7A4627307B24F4644EA18F42CB0EEF06212942BC497CA6B4B622FEA0C92A59C59B32FDD027EFD7988983D04B49F9BDBE96225CB09AF9BFEFC879686FB4B1CC2B99088325250945350D8BC98FC0C38651E15FAC03059FF843402DD836B6177C1D5DE74F5E67F8DFCAB03BD4512D141AE64B47EB2BF750E2F2C0A778F25F3B1B85EE2AB8693E1B8EFDBB9304D48291540EA31FE511BED3AE070D1A0D3F0AA9102DC476B8501DD273A0C234B1024EE3D09031F2F0C4741982693334647FFA5A9006EC4718AE7BC3B0C472284D435CC59C1E5A25780DD29169C83D95919ADE93E87535C9D5A7CAC1A011E7561CB8E05587860EF873A54DC65630A4DF344E384BAA1194634DB98B9837CE00A682D3827931BAB676AE17EEA73AC025DFA58D9526BF6711D231EFD593306C9D59B20BA97F9BF9D021116252AA312F1AC21383AA05F689111EC02773C27E97A4283A15EBA9A1D270A798D72D1E41C4539EC0D89BB3575F11374499ED04ED6666C99D68B03AF9FE0F79F841E719057FE1AB2F1988465A1A086B92BC4C2890A395C17A473ACB7DDDBF3EC1BA641FE41326F5A3AB47D31E5BD14CFF3DD3C901BB1CB71C0" + }, + { + "tcId": 16, + "deferred": false, + "seed": "64C00833C31B906FE4F7CABA5D0E2E26A81310F20EDDB3E1913F44B89771C783", + "pk": "03C5682D25BBB5C22AC191A5351E048846E52CB0E8E54AEF243C14AD0E69D7A57BA7654320DAF1B4B1A10E816BE13569212FAC21AB2D6E60C68CE7E41EE4CA5CF437519089AE7FCD879B4B9BF5A60C66BD09B74800363A04F0EDEE88BC9EB69F6C01AE3BC10D2CC6B625CDF34288372F01C031E506657EB519C31B0815961454E12DC426E486B7EC88F2FC90833F4416FAD525417DE49237F0A7EEC8F9AC9B0D0778078153E9FB3E7D95AA1C07732DB861474F4A34614747A282A8A875A713367221153EF0F77359172A5F07D47E71C8BE7168B854AA091EC8CF8DCB0EF888143FD78BD76777107070E36D157BDCE52CEBB89530682C50CFA74F0F3482DE20FD562420E55FB3F3896793D4CC68A23520734902030D1D1234C25D768083E82F3A75D29C63AFF7AE102EF4BC02115D0B370CA98C5167AF69E68EE2E71C0F6B8E680032C4ABF001755ACA26D92BF06BFF8F2678611DB13F283BCF4D74275692FF493A5FC639A4DBD8B47BEAE8585D27577ECD2705E0CBDFC9D778EACB3A200E6D72730AE6E6F9D3A53CF8A1794B979C8C8969778C6CA07B65A01D607613236C762F4C54AD222BEA5378CCFFE8DD95984814AA9517FD9D01E3356C265F740926E0DE6FFCFC50BCAF8307B243FE030B4BBEF4CD1816731B54F53B87CAF3580E43A762391F8652B650E981FD0ACDB32F8C10A9966935FA82B2AD99DEAA6FEC117AD15978B5C950BACFD1AE3AB68F36C4F983717D6FB4CBB5513DAD2F842EDB910576205F8A1851B097B4723B0A21315C7E16C2DE11A59626B651C49AEBFD198CF8FD9C81C781E93EE959D4A8EE3E4B4428121E29625B217D403FE70203791F835D6FAB8B32AB190B0A53075B17132E366AE270622B0D9CA492B23323538B39BA45A7BA47DF6009333B7C668C145C9CBECA0DFAD7BA07682AAE3068F79A2B3EDD897C5723F56B33EF04C9D06C5A7AE3518482698C69EA6E263C63281A0E723F955D39870222993C1717FD8574867320497E0E385FDDDAED6A32CFCFE356E133181007F8507BCB233F08EDB2ECE783765A7BBCA2676B3A4BEDC7140234215878BCABCE3263492C9E6D5F4A323B40344C077B38EBD282D326B54BBBD222B9AFCD2438EA594CB850FA4D97A5C14A9552ACAD740854ED288BEB288401A458152F2C1471C434BEAEB470230166306691AD6972B249D0AF06E131507BF8B9F798B55302D95CE98C2AB7A67DA55217F4F5530763BF50C3389EE6AFFA281414FD34B85A3F29E43322C8EC44BB26E664D71D5DF8B91859C4F174685899B3A9082574D03C2952BB65486F5D770235CA476E85F8F966FA67F3323DC10A66A9BC00D37FD2C93752FD49F4FC6BD8D45F371552ED38FC257C04F58825A086EB23B1017221DD0847AD0D552BB5B773903063825E541DD7395E160FA0A00288509B97EFF2E9F0C12B1B2C74643E2D08E67036A1683C77E83D3BAFF79D8D8DA4D2AF890E6D698FB18376B0720E1C5FEAA6EDD7441EA9D618BE89650858FF357EA575728EEFAB6E048EDBD54F4E5585AE0C322468C12DDDA309E0B8901ADE7E10164CE31898189F99F03B112C5761EB856B39C8DA6C22A4CBA38421889C4F874D27B98D8509082775E3E32E304EEE79E23A68608B2DC1208512CF1644E0DC3F5F4B6DDC83E971D0E4F23DD22BF15DF80F2337B9D344A157E97BDF504A5F128EFA7FA910C3B10D2D17D8C18C8FFBAFBB0F8F0ECB1B16B8C480766669C7D26F0D69BCAE6C448A27F85B6F797C096E04413026F9BB2BA647D5460FCE9607340A577526420B12DB4299AC409927A059EBBA3F9B27175513900174EF0C0D39E2DA96B96C46B1BFF2A46ABD682FE438", + "sk": "03C5682D25BBB5C22AC191A5351E048846E52CB0E8E54AEF243C14AD0E69D7A58DDA19A592F17A74AC79AE162AA423B4D6DCF620B92DE7EA28D7CAA414693CDBCCBE7693DB544164D7726E8BFEA3F7C321F2C03AB1D2553C59E6EE3615F9E6BB2EF8B5A71196FF404444F00C1957A9E8C873C917CE469FE85BA5AB43D679EB9B6410891330891AC164D3880019047104854021036E1848269B305248844C12B6918AC4901409319912921CC82C8C42688B9449C99221CAB02958B48C9A148C6332718810461C240613190DDAA06158A684DA48448214601B12120BA9699B466EA1986198B86019A0811800650C396D51B685C1828C012146E310605146465B485152928DA2207113B30501B42919118A089925E28604E40812480826004185D04241144924E4449120058223139288102E1B138690222C222708C4C248CB860DD30062D9208512A291C814041C000581A02101B33018456682B8302000499048709430720C4426DBA08043929009162EC486640AC211DB120808036E82042A19432C9C92259A9421640222D3929040808DA1A88582828049186519194E02B9206296251B45800249514C20700118204916048A3012098441041660DC382CA1084D203849444224A02885A4B4004C188D41A82153C08C22226510C07194A40112B12DCB980D84A44D61328C4A142492A0909994651837904928862309809092205B360A18A70420B800A0C6291035425CC06D824870D0141223284511A68063044608C5255A024EE1C651CC308E21C18C59B48DD9924D52262061360D539431DCB4901233710C908983306A5102915816081C85440CC2455016604900620310824B120A13823044380901B68C44049293A230623006A0C480014669CCA2041025859C806882B0115AB66910A3210A2732A32622184066E4B02589300C201440400004100881804206DC048911C24002A861C2B29121800920C02D202972A4C230233785000531993021DAA6609AC06522906D20004D1A930C01B761E3349291C070E01600D21609C0428824085153429248046224024C50388A00C60C62C26803040961A664024811DB242282806411430D891211012770191746049105C2048D621691E09829E0909188467062484D89C280511284CB2605D0481220402C614466A108488936881C222220240ED1946D50980998C66804C34814292503B68C00904510498A82862C9CC28D20421209370913302C4A108A5C1011040482941044CC6AF62A29C0BB4C651C550568C2B7E30973A1EBFBED2BE867AAAE59FEEE532DBDE00A4D7E787507E2FFCEA98386A4F068FC0E5365AC4ADAD080BFF8D689CE2218B0FA34273D329AFFED0EA373D504C43A939E217E1AA6CB6488A2D2864FF4CE1401DE8A810EDD25E2F211118801D963B6114B2B7D53B60D3C4BC7B536D15881091540F2144D874A95BD1F0F04D3425308E3E0EB10382C1486C1FF829BDFB39D722A77BABEF4E9E26D9BE8113BE96EEDAB8B5BF7C59E71F6A801BF1564902D71574D66DC66E1EF857B082E574C52426F71EDB4CD16F14D812EAD67171D232D0DFA455DD732EDB1E4CCC7CFEE165250631E8657E315DE287EE92572431B4DC359CA109029B562152977B08C3A36FA205F151CA4B7FF65DCD94B53D17A1EEC5573707168B8CAE56AF54BF73A512501A130FFDED992C88860DDAC46052EEADCAF6304C361908209C1127C38453F8727CDD27D396150E5597378E6A7965433A08D777AB39E1237D77AA4EC0905744CD25BBA566C4562BC55AC98FDD04250B77644AD5A52519A066C156DA7A2B3A031EBE2A372771C5E615AE0F05B78A7F2C76756D40427B210D1B745E561EA01AE315271393E26EECF7314427AD500AEF0F4D122668B15E4263811EF7EE32D3AF2BEB92A9111079343DCCDA12F80F9B2A8E0DF681EBAFE963B811298F848F52DF1FCE28CB0BC588F2454E07FBC08C4EE76EFE3A37E0AEBE457517121FB09AB15B7E3884A236E783363B27007EAA3AC074D3C9A956ABBA45BA8F35E36483A0004DD57B89082D0C5478E785D8ACB40FB979809B289AC722509D231960456B74D8022F8DC8666EF3E5E6AD54561AA4EFFC29A8C3AD5FF4FC8DF2E23E795EE43AC324D9CE606608FAB471390BB65151B66A1FDF4E699A133F452D9286309B131F7592AB446CC5C4D6DA2DFF31174BCD6A987AF1C573E9C29F93619E4FBB4318F6112FA43AA2A2D69B46AA076F59515729701BFA4BD991B3EF479544170ABE0BDD7B8667452E40104C81977395DA7F1DE198658FCDE46AFEFF92FB2DD42B549B464B77699D55079F76DD04388C1792683D89B2BA5516FD7070E504D927B88742723A51B8A8D06173BC7F069C6C0057E887D0ED60EC9EC608703C75B5BBD0BCAD1D588B48630871B2F8134EE8D826EE7981A3CA96006A12D580E5CD3DFA0E03BF853EFD7F1B61E4A9B5D2F61237BF2645592B2AE7C78D218082E72145DF841160E91895D80D47DF474FAD501B55DA75E45A4E2ACEF6F94F944174800A117CCADBBE5C1EF8A7AA1D5E7F116C5D634F816C742AAAD7C346B91C8CC8110EE8AE2CF4C44D6629F0D00141CD58B94E46EAEC58BB86939814F4DBF63DF95F86C5FFF7BED383B75DC26C7FE7A20EA084959503B6DD11EBBEDB8FEAA8E0F486B6B390C343E2032D30E98D519EE372379CC28B62ECAED5F4AD3C60514D56C5C29E728BF99212FCA97E2ADBCAEA3B2BC4927B91C2CE5BF0634D0D14E7FA08C5F372B72B9EA9A8D2A7A913A25C9E0997076D4AD064EABF0574665C09BAB7177D9AE77E9D1854FCD3011AD78A9E13405188D9B91CB5914F5D6B0EAB170FEE77AE61C215E73666A2D52B32AEF97A1808E22F09D4AECA4D80CF4B0E901036ABBE5EA0964584B52DB4B0E0C5A6E71E461A2C8B2B24155961C1B4DFBF1EB42036CD70CB6C16B4F85C53BBE696BEF4CB3D21DBD5BA62B49A95FB33DE679725D4781D6E2B12DBFAD7CEDFEB971BD8F2211CB5FDF5B4FAD7F684E61BAEBC5C134AE3F56CCDE44183183160B57891C487C59A7F95577D035C442F95EF655794095AC49A3F92E4AE67F9F7CD0FC36986D288B22340FE7C7EBF7265C98F70136D21EDB2D95A054138168591473C510818D3872190A3EFE397400D11702FF8F38A7B0292FD043DBAF6332188516A36FD46529A049CB3B97C706C0CEB4419100E66D32FFB0212CEC721ADE99B95F8E873CEBF0E47DE58E26FD06846545B546836EF0C2AAB40254A50ED445F0A886777368158847AA30791467083D6575437ED85933C865163335B5F4FC610908F446984680B8B9F2512F73A8531ECF81F9F4B42AC6137ACA06249657510769A273C3A2F2C0A6A7F65BF7A0E9C3DE9660446CE0D930CD10C946966E0877BCCB014C89FD7759F513BE8B3B618DC4F933524F4AFEE166D74AEAA1453839D3BF4095F85253382B26DF060FE9C1737CA02B8D018BECA3CCFF06F72E373696DD5CABB97EE2D329B0CF0661ABB843ECF7D3248627D4BECD58C06A348396AF84455D6BF39340AAF12760235BB13AC3333D6A2F89E9940F1C0A6C23B5D94EE5644A3A1F9C953CC47E2F76373FBD27FF569795F2928C59DB86F5BE69" + }, + { + "tcId": 17, + "deferred": false, + "seed": "16CBFEFA6448D329CCC9A68DAE478FDFC02D73C0F1DED9F6A87423A52208296E", + "pk": "71BA1F2972BC412818D4C9B94D6E40EB98741BB33CED307707ED1627BBCF8CFE1330A73B6E9C56AE0D878B9982B3BD187C051C8CED3469EA0EA4F18E70DC9FFE3800B48575EE12B01B082A01B9871BFD8091889C00635FF810B6DDEB4505FA8ECFB32039A6A73B1612B7E3E02DAC00476B5C7AB32861529AAF3A8D7899BFF3CDE63C8AD082312EBD856CC2739D6736A39B13C971DA277980C73848FF99D72C8738E0D36E961D48C56F21F692CC72D5ABB690CE9440A078CBD2CD789F884CC45D0792C10D567649067812206AF64241915FB1EADE7A92668E636C34D0BA4B9746A2A5546FF85F9908B200B76A40DE0B53ABFC7EED5841DCC7AF41431FE59287F69F11C22E71A2E2D86E8062249A3774FA206445AEE3BDF33CAE5B9F28CEB78EF887D9178171E9B5ACF243CF2AD3E85E0143EE13CF9C20A4FCCA0AD53F8AE39FDDB58613164EE6D5C6C83D83738C06F327EAA2BC84553897F11622FB2FFF96ADB1CF3C154BEC26C42344B13834761EA5DAA6F7659DFB86C9B25725E8E9FAF6103709A415F3466DF43565B85A7211FA4495B808C4F1C5BBF7A789C20DF5890F2BBB3E0E4D959D24D864218B950DCEE4F56391566B57B794156DECEFA42140B82C4945267072B62E2CB494F872162F4D066D4DAA87BB15A114A38CBED20609201BC2733E1475CF09C189689B5EC2BF040BEF6F16851A9D3B058A4B0A1A98A25D74120725C7763C6BE74CC931E057143F4870C751B102387E403AA6E0B384B4E9151FB8FBBC1241FA0656E785F97D27A4258D015F301F41222207426F386CE4E7A919C4B4F29552FF323E9C85CDD11DDF3397F46AE8F66049DBD2C61B20603E3B77D898416FE0AFE87BB16FB39C17DCA8B3F69DCD223B35B807BAB02F039EDFDBF05ABD1D28BC54B33CE357BDB72B06F35D40D9EC9C81FCE5624CA7C13DD81985AB5DC422767B2FB3ED6EDFBB4CC76A35E1793C7ACDFC2B80FCD5D98D98E3298559046C776B130ACD7636A4D357D8766E58160491EA73ABC015857253403284126D09B770C557D8F9427205F16E7D4964BBCCCBFD2812649CAFDDB34823665C4635FC3D4BA0D9A070B195D8D3DEE77D2147E8B1FFFD155FB536018D08A63097960F1FA341FACA7CFD273FD8B13B4A967DD7340F3B1FD93DC5D1BA7E0BE530C263F6930BC3DE5EE4E6D2A7A14CD38D3D86FE63416715B825C5682EA7C8E227630BFFCDD18D8B84048D385F54A657DA77C520BC24B0A40D3D0EFAA5BD6E31D699B8CC0AC97D3DF3D30CF0794FCC470FF96B43D5DDF282ACE2ED4201356B492C74E09F3908B5A5A5D42E7F4630BA516FF29C6A5D968F215D017097A246CC85D6A5B008BE68BB049DB543B8CD9BFF7E3A160C37DFA3AEF8C2C702DD9EB0FAF580040024392758C004A5DBCA829A071956ACB219EBC33E50109F6F0A2D582C89D74B0A2B929D569DD8EAA9881DBA877C45C6186A98293D9CE56CED0E4E1013CC293917A1851123677E1206D1D051B3790396B6A5BED83B359078A9D58B576422544279D3B93F4016051F6D7A62BD3C3693E10D1207AF92B72C348EEF81502D308E34059CA3548012021B684C13A734953B9ECFAC69874550B79EB388CE5236DC28FAFE05F548958C6BC1E4DCFE4F87C8CA3BB468AA28389C72003BFD5822755F28B75B4C9B097CF98D61C0CA959C775375BDDC31CDC5E9AF7633DC3CEC431E5FD8A7CFDF20401DB1906FF7BE9654F1D5040BA50B7D955953FDAC1AECB3AC2CEEC8065723C232F5C3BBD96F55C4DEB9B84812BBEFE549D5DC450198BD20D90782F0C6F3153AD6272DDFED0AEA91FE43A7A78AACAA0736A29892ED01950BC0A2FA17D19539A5", + "sk": "71BA1F2972BC412818D4C9B94D6E40EB98741BB33CED307707ED1627BBCF8CFE063F07E542AC493E2086888356684C25B2437F7AB2271751BB0310B2CC46723C06469293E5C9AD9B7899530B9F9489708943B5892821A46E186DB790F95CD769ACD9A0387EC1045DF0C4D254F1CFA3C69CE31FB553523C1018D6DF6C75322CAB9A28306292004C380002C385D4448A908629944249611612CC320A1B8368A02051C0828C93B460A00052A0C68813926561A20113446E1B9304D8B2088396609B42455A4265A0328920066ACC447098080503B13101942143400612842114196408C09022C7710B35901C47849AB68D53A66C20488E1B952D80344E8B38824B360E19A3481139281BB3011CB8514C826C5CC40D212469C3C24510A6881040241CB31084C081D4808140848090266D4C328260C42504C985E1080589B865E31692C80461D3105211028C5C166C24A24059A0488C9424889831DBA660E2160608062ED0828500A511098964E3206D91428DA0143180224C60B8049142111930480B144D52068A213769041586E1C04D9948050198885822015A0085D1B881A4C291DCC40D00112954806D94100623B8811A3800C0144E5C188612A06180A2089A366948B2840C46500449720C1744D2148951484D04870D11123242C83140186AC1B8840B920919330D1A0652633081934060601271DB140EC44850DB884D60286C14028608050503836910041283006CD01884A0320D41884964148083B02DD012885B3871DA364D54006603B601DA040E90487102C72C02B64C034325A3186EDA202408C410200440D1A06DC1402C0182482144044A066EC8108842188EE4B2401A09250C016824188EE2A6050A90241A344C0907301AA98008352DDB102C23B970421425A4C64CD00229CAB8881401318906724C346523A840A08611602801E016050CC125A12011A28445C22610C2088623A729D02425C482095CB6219BA0506148280C2765C84601008564DB824D5980891C884D24C60D9B308C93B2248BC868C3800C12478D8C340182422DDB001004B008E1124C0B828513B78D1C41006236281A2772E2B881499409D2924D10434A0B386C09952509382ACCA62C41B0651881098CA03090446D4B06901B150081A62484840819306C00C2918B4486C94288631652D8A44C1A81246328404A328C48C46051282EDA0809A1C48DE1022692B82113245213490E0321480B3169D326405282005A1885810228984080DB2000D82E82D2713294679D8DBF3EEFC4DE8D7C6B6898759DAA0ECBF083FACE0BD58B98F855C4F1A8EC9D79B22BAECA6BBA2D2C863732A12115AA2CDB06F43D2F5D59D4B477B15FBF0374333C4D5D4942AF2180AA5D651A8CE9F3568A24D9B78D2E02A14F85E7A112A2D4D1DDE95F08E4293FA2A32524CC7E1754DC23406DE33FE808A31A8E60880FB8973F38C8642A02879C34E90300E86A91F7E803F92178D7C5676AF246C89B09A59566D91F6EBD4F2CE86C5E2F18230D44C6FD3FA358F68D21BB01C88362756B13742BEDD36D077F0D0839450C9C3398CB04B26C54CD61553E8A253B9F94E9B16AC4A79CC931743181D364BD999716F0328924187153E9F5E25E8F7E05666D6F70F012E8A5A8534A406363D297E768AA84221792002A4E2D04A46D1FEE446134AA4CC06DC7E2CD7605C660291E24859F123B332D41803843E059007FEE960B19224190F27111BBE3C411CC0885B4D5EEB369973ABB511C8584DC4F5E811CAD7745D9DC88707891ED2E8A597A493C8CC1A964BBAFF9FC808CBB0FAF6079D29832EC18888926497C52DFDA34C83A2D1178A3CA27C7F1CF04913BED288B2DB7581A8C4EE24784747488F6BE84FB24F595F82FC0E7B05CB01241BBA23B19EDB5162EE2645B29AD48CF2F64D813F0303CECB0C94CD7EF8ABB6BF64838F949749F15A0EB899678A5671B2925E4005AD0644AE486234B720A0752284122D1CB8839D279FB571D9973482B67DCAB15EDDB6DF57E36998ECE43C4C067314CDAD1834CC70A209BAD00518C549E9C03B4D76FCB0F235EBFB694EC90D5123B8F025BBD1A323C6097AB0FAD3476742C0531A5F66ED13DBBADE8AD4888FEB8896E37FBC01149D40CE6811D8E386EE419580C20BF1544FA524C2DB22C9DD116B752F42887752FDF863A860420D029C309AFFD0FC9163375E48E8EE7D69B64098F932B205D63E86FFC3048DCD3375798CEB11A2821A92B6405E32D0C9C692C0C51FA1757B4EF12E8931E26B77CC7893B0385BBDB637C1649B696DBD5CC7D6D62B3BF19A7AC858E12DCA1FD34D8AD98C95BB203C4DCBD20D5A1AE7DD6D96CEB23E3F0484532040C74486A2C4C69C65949D970846D315D4D5295C674DA72679269A6234BE374E3826DC11DB198007848245DFAA3C939A89D34F6E1EF688164ECD9D9B7D5909239D46677E18DF479C9FC825E8D3876D05FAB6CF70125460D524A5F3A45525241FD610B53D8BCF110687B9AFABA47AAA61934DA03C272659BF7EAE1716F3CE5D7F6BC6B72B0C4E8A8E9C5A3EA6B104D94DBA6B06D029253106A3F2771604002A8EF7998C785B23845579B1F22060E1114C1331D88F172EF11ED81C1DFDA7F27B7DA86AC5967A459B2DFAC327D11EBB1FCC29E503A5F0EB16E368267862EDBBC2E060287E672E1CF718B31A439BAF4FFFE9FEA3A0AC759D6593D19EEAEFEB6A2B4B715CD4FB7D04BA8BEACDEC78BA158F46200EE31BF9E93EDC79C1937B20235C9222C6C73614569F6EA24ECE185A1ED3AD12291BF20FBB42C64E39C854F0D3B72F27EF6C560BBADC074AFAC043D32486E9761E81F2EBE147C224DA94B8F5F5E8096E4CBD95B892531F4C4924A30831224C7AFF3092DB1104FB247FD18D6F1795C961F43C325290F734179DC7A98296E5A3AF11E0607DD086E04F61D20BC661762D39526BC3AD16257E1B100DC7E97D3992AB446FF18F7C6658C6107E5656533FB9E1D74C53E1217A06511874317D2C46808B6422B183A9A110B40AAA5D43212DD760C912A2A2EC804926BEEF9F474A70E484B2C97E1F6E2E47D40A32ACB802D14B56583516B4C4BFE58FDEEE47AD7435E98556FAD15A65D34338C0F28E7039258E00BAE42C8FECD35B3FB261B5384C2C4384A2190397AC362F378542F82A8600573EB73928081C7C6E99E59939E3BACC2153D3B4E979F7D47A5B6919B644AED9C0D8528947AC8A7FC442AD49BE14574B12AEB461AE4B28E45724E97506ADD725BAB31E94A37920F40A55198DBB56C407A9B7772235CA1C8A14F41E6F63F62C006D1BD34C42AFC675DA85E12C0F9989B7FCD4627C5ABD6834EA6C5B6F0069ECB352C303DA403FF48853FA999CBEB2190FC6472654095410F89FA9D7D41AD6327C0F509365864F0E7C6329A1C87222D603924228C2857C456643C27443AEB7D7E30D3FC9C9C0668C243D5B292ADCCF8C871751E7440D896C82583F1F0B1A701499A2F7EF685B00E98C3CCBC54472B6D7C89A59B6BDC2CECDDCFEA3B43E192494F6334B1CE6D173F909761C2F4DCFF0E31D17B164B032F12560578B64DBE3F4B919E5899C9EA6F21FB3C4EA445C0667190A6A900926EF15ABA288356ED8742" + }, + { + "tcId": 18, + "deferred": false, + "seed": "EA945C93BA680770398A958B46DB716AC3D58C0AC3AB49DA134DF31504FA510B", + "pk": "CA6D125A791A8607FF94FAF838CC140B7F163C3D5219BDB9BA4CB5DC8DFC3D2F11EC2A045BC422458C32E131434082E0C05B9FA0B5F1E0C52D1FC0899D5BB32D020491041844972B680109CAABA456B8C4744FF7BA2E2239FB5C4C231A30D194ABB3EDB34F769ABADE12EEBE1CF4086ADA3859263C4BEC5D21952F659BD2D717A2D39ACE454795A0DA6B91D6DE7948027F698A38332520E4D88CD74891D342B977CEF86AD063B6C53346EF4669526DE5DA27B71F54E58F54FB9CD9CF9DC86522D46A13C6CB4D7774969F249D1EEF6791150EE05D2404341BC066631052D0A92839F77C07E4FFC447E110D2A3649B4BF7E8588F24DC509922D4CC5467142BB2A3D350B56BB00A23B28C6769BD09F8F6C77BFBA63639D0D9678D94DE66F8A14C22FDC1B9B33D14769AE034203C1F98E94A403D18BB22ABDD84959D63407B87C73E721985DB756E00C3E8305F9C0E23E9D7D8003D010589A283156AF7DC48F05C8A5A814E484D95C5B53006E86F009A6D36720781D79BF460C6461918B417601A9D88DD84D5A26B71C1DF418184D2017C88D1AB6931A49215988B65838207C2111A3BE980C5809C2CFF100D3D8495A7F8D3CDC0D1DF183A56DA568460EDE3631258559B010B2208C8F134924A3CA02FE42463F8D352D0EC3797332442D85D30BD5989FACF7A2E8CD0018E5AA4ADBD902AAFA223C9FD5E4BFC647E806C96F0AEC74578A74DAAEC99E9C3748F388E3A99DD30608E3C5B7382021BC6926D3317240538DF1198BE444D67DE7DFD26EAB0312EBB8F24FAFD464E09CC2F28E08D792FE9E422663B4CA3726194D881A9929246FF957C858D58CA2B2381F5DC275969E907088EC047F6CB1EC8DA1B76DB6396A9C197FC7A8017F233DD0ADF884188FC127BD74BAFA5E138F5B6DD8A1354BCB82DB68890CCBF6F4400A96D7EFA3AFBE7CCD034377532B084B4CE473E0F8F12A5F1E9031984CD109A81FA2BC1C04932D0360FCC0F1293617A6AA9AA6142C8AA8A9EC7E872F0C15250E36A5830C63A0BB8921D3599A7352A6E38E77715FCD2F2C6167A0DF4FF33CC32AB96F2422DC33F83C45E2CC815124CD36B5ED28F142FE79299AB930CB6210C4A1F7754FC98FC3233EA0C92CAFFAFD36E58A4E64475573FA9057BE3EA35DA188FDFCDDC26628DE6C8059739C145BE59119782E93BE98F3E42704A827D3536E28ABE4DF62758E4674ECAC17594F079B1CD653257842F02D5DD70A62B0F84759BB0CF06A19CC2B0FD177C06FB2A020242FCE4DC8242DABE161BC5C1D95F5748BBCE96F07D4B2D8A80C1144ADD0F057A9E3CFD5947D2F1E8C29E1C206BF049788A52D9DBB6F72A344944A12CC80909EBE2CC00BFEF5273036EAE707CEBD6F57249CF40E2EF698393395FCE381094D042026989E2598969FCB343C05227B914CEC73021833701C8AD8937C77AD611E265582E6CF59819C56B0F29174B9080BD8E3B57B7C2D594CE1B432C2AA010C3B55A9D0EDF6A364CB629FC0E4AFF80439F15184E987128242DDA1425C7E18FABAFCF458259192C7CEFADBDB723E63E704719BDDCA69BABA98DB8187583E841025A900E53B35F2B2AD2CB260014A886A84760CA74828F56FD044E300DD273D95DC2B654C3E0437E30134DCE1FF9F02D6D8191955AEFAFFF588357573CC17279778BA6DE661721C02639D0810F416D2A284986029D11C54D225980FF3ED3B6603F4B73264328357568D72C8875F34A4194A7B556662A2820144EF89E38DB837D5B539F87765F98D0E902AB12594B076852A0EC716184EB8F1A589B06C374CC8C6715DA7AC6823F0670C78D9D3F7D921AEA718BC8B3894116B2404E623975C0ED", + "sk": "CA6D125A791A8607FF94FAF838CC140B7F163C3D5219BDB9BA4CB5DC8DFC3D2F7CF3CE2F74A2AD14A279908CBAD4D566CE574785BEA782A9A838666FD20D0CC66F55DA7573AE47774CF62F0FFF40BB0A9FF42767685B979C2BC3987046E74E7854A9D4BFC9E7ABA2E749FE766C8BA10BB7A21D46C27C0E0CAEE22A599B914D79CBA2698C446684402C58344C022230C4A0094A406222A04882062912B98D22390E53A0691A3425819889D9146D5AC871192251C34406A084055C428E9BB44C51B6259940710B00314C086A5C008814890858342664227009062E04318A483809E3286D4A342C18364C540031D4A09120B2601A31700BA52D21A98518C14C90809063346654225021028DE0B66D43C600084361DC14610C1302528609823252109284C81206C8464289B81122B70918472D93386211292000C3440C37040C344123178512433114856C00A404C1264883C470D84812E2906544023222076824A05164C6895BA0084C203091300E134310200341D0486200472DE2028210056ECC408802292DD0467108424C02926550147054C6458488510B384C438681CB180C1C8345D9942D6240898C80401CC82D19B30012C100D94850103044CA26700B242CE3A6881C27712186688A3409CB482552402E49286D5382852187490B402D03444543A66913C58DDC92881384218A0230D8A00D63146C02207104A76DE23431DA346993246D20936C930251141720A228061047711B27111A475111354C1036688B869113A960211220C10088090970A3A64999024A92124861C670181208D9004193A2054988645044610B95100B982C0A9650914261C4104A981471532692D13864400020D04688CC0882194902D9182E23309114B7905182645CC061218289A4482009402542C06D1C4582D0168294B861040610891026E1A2611C040048063123870184961164A860C420529C0660208108D220201A054D98480C59286A40B481C10451D1B60C14990824206E94B67058A080DB1661D3902C41160DD4A08C9A302500B02D1C398E49104A129364880032103064894624141951A3A02C40A2690909458936015C220C12325211214653404984380990C864C9360A84B84CC3424AD0300AD016040A21821B28808A2269811000D2B08461C44CE006315B328DD21640C38645C3B42821B9205C322524362DDA144901A54893106AD9902D11044E520886221368C9B26581168E0A18481B128A2433255B8268E4103111A985FE04042BE50A23E0F03008ADE937C006A04241C5464002866C62DD202B2B7B299400A245D4E1E6E4A9482C432DFB3E3D28E36ED1A3A354B420757A22BFD2AC8848630E24F775BFDF16932E0B1D9CE8743FAA82126D0E28FDC52EBB345CED07B2DC0E36D672A81E3B909FE06D5ABD9AC08FEFC23D7AE91AAE6524B3B032941E35F6DF6BD9661049E4F7648CC64351B0781CAB885000E34F1A1B84EB001CA87766C8C8E403D7F3724F0163EB46E1ACEBD9764637A814D67A61888436C3FE080DEAC3CB020CF15DF367358D1A51F0E0657F6C1434568B4F49BE12982651B92BB2B68CE4A97B9B9F48E40092F8E4B5ADD32A760D98B47C063E050644426FC8C3A6D967FAA9F718180237849D5114C09EBD481764F18B31564ABFB66C3A2BF567DD4C4CE98D226C374AFCE873BD0E7A0D98BEF4837628C5FD978729F1A5A1DB98FC40272005A324F16007276885947994837C3832B18BA4D70AA15AE39786346C177DE5C09F4D7C0F572799F9630B071D95BFBB8734911E1BC44385D09F35B51264C2E71F220D96C86DA0C38B43D91FE511D983124AE39F59B78EEE058B75027794963102107C9E50F193B60DD11690DB8EC84ED9A78E1B13AE8DCAFD878EE0AFCA6096290A0465C9371C1D9C9134E6EE476B5D3E44706DB11D2AF07DDEF54AE381455A452DD746AE86783944D2886F59100BE51B7ABE4F503A402F25F21FFFAD63C7344D7FFC40CDCB38AA27046943945DD773E2288DB5FE4FB0F0682C423AF0837CF66F896BA6E72469B3222DCC117ACB9F345AA0F903D11C8F574DD3DC324F5C74BE0E155A4B856DB8CA5499E064F6EE21088FA2FC56C4C14FA15C3464CC5A129FB8B6B4A0B0D9A60F29D35928F35695D33919B91853D2FB8EAFC5E36789B8079115140F151FF55886D315E53B094C12898A4E1C97F39914930AD96A107A95702DB6546746C8E661C24B289E53057AF78F5D7941C145B9E38C64563ADDC80E95E27362A3AB93B85EB9EE8880467D6EE72440E114976001BAC4032BB9323EC6AF70B77F03764BDAE26FE824B402BE79290EE99E81F9DE4419A4DE016D925D9835DBDD9467F731C9E54F604FE9A101836137F7E2E786BB5A46A7494B75F5225024860770552C59446B021BB6968D6B6F9DD9F15C50E22BFEC54976C94980D4E21B19DAA740F35A6D13A42878833171F7B9F33ABDBE78CEF9B8F92A92A7D9B96A4284FBE923BE691090D185BF42B5D1CCFE707ABD2C9F14A55E8AA5E69BD4A0BA8F6249BE11B65D712BF61B98BEE99D1D3F190C76F7B7C448C133ADD6D8FBAE27E0239255F6047167E84C54F9753EC2DA7C53E089974DD49868B6A2F467216E01C29DC2BAB531C8158AAAB9137C55520C1223A1F804C1A9AB1E3CA5A9C380646C8F48DDC70578125E5502BC7F441A416866696332CAE434FB78349509E592F7A799A22C0604942D469BDB65951B09B94CA50989C172672161E77A1BCECE09930E485C1BDEA9CC435AC84CEE3CEE4EE6E47046E1068FAF8F2EEA2562AEC2118FBE748CEF8BFA43799BECB81C514AA4E1115750400EFB12CF1A7F47D25B3DC1AC5F3FDD9DE82FE0054716086E7788FD83153FAF1D9241BFCBC46A8B200C2F35B5B13453F8F73D52025C62FC7BE837C291B6BDB73584D4D704D6A742B9EC772C36AD7263278ABAD4F4F17AB801378E7DC7E5DE8E852B1F07D00B7A47D1527313753A2695A88980F5870C1D54934D0D7588350B180012DF40C57DB2AEED587929EFA6C1CF8AA82F1C51581B89A87226DDEFB73BD581210DFE3CBCB6AA1117C018920C809C0B7F70D034B8AA0BCACFD689C247027B5CC166109EE063557AF7B70FAE195350836137828B060A82568269336D2890D9F7C6200FD1D7E6EDF87DE48DB19A942B2F15119C01EF58951CFFC15DFC40C16C695FBF14B9AB602EB8F7799320BBBCE2FDA218BED11C4D102ACC0B29782917DF52430E95D07C859977C1DC0763B13305AAEB4169FE4D57962A55295904A12E7D169E0AC5B0FC7048546A6F1E0D2D0FF2CAEA2878F41445AAE5EA4BC0921DD8FCEEB400A25277FF127AE7FD57F23FDB465108DF387E20DD628D565BEEF6C34BD8DE36C33F7944120E08871BABE9A96589D69409C66BD4BE9EFC9359650BB0AD6773D5EF9C91910C7846C4F3D45153F68059E9FCAEFD86A3195417016841231EFAF86DC68E26CF7C3B34C4026C78FD146E8582B36F5F458ED59FD4EFD5ACD0D861AC54E81E49285140E511F24F8B3753EDB2C1FCED62AE755369919713C556178131B84F857EE1B8F37DA67DB958358FD628FA396410D1865B9DA8C9AC772A5D6172E7CF225AA5CCF60B6EFBF0A1BEAAAF" + }, + { + "tcId": 19, + "deferred": false, + "seed": "F7AD0FDBD2F83B60C726521BCC0923122D1257181BF03C25516FDE98C709F781", + "pk": "08C583FE51538CD926528D3F9E09CB7D0F90FCFF247002D162983C5C34B92C17E4EB81467C60AD40730626E412DC0A7FD215E75945BB223F17311A5B72BD0AC75F487512B45D9673E7F659D6D31867FED1C258C51EC7CE9BAEA7E6716BD33967CFA0A8538A96FC37A1515F726CA4CB1124A110ED9AD4C7380963739AADEB3C62832211FFCCF84EDC129E068C9BE4001A29A4ADED360936E858E4A401ACF4A55F087891BE2B64A8DB64C19323FB527EBBF61C577419301B7AC70DFF901169DE9EF367326E83EF4E13706499A56EA10443DF02FA4C55441FDCBD946DA8A81C5CBD320069F24EB931716C57FD0AF6DCCF49BA437297192D6149954CC1DB661C874C5C81F2FF5842A89D094CD4E18899EAC122DE246DEE7728282005AB3019EEE47B3AC0066CC136458AB5E89458500C1937C56FECA6D52D7C626519FFC40DE49D89A7655E7D6612FE7CD6D72C36B93AC7C7D75DA5FDE8D80E339F96BD6895B07B87DCC5C15377381B8AC3304AE7CB51DA169982A297450499955E816C557857F2D4891960C4ED5C54F931B9E9462680DAB045CA2ED5BE81427326DBF390BA5B9CCDD147470C1319707495212D791D2535ACAFD4BF78D4550A2BAE409E10DFA388227BCEC4CA3837B46266BAA53CB19DE9A3D7EC1F354B648C57D0877290D09F92CA61BD3811C2CDF9EE870918EFBCC5750DBA2510B601AF593245FA4DAC6F89502E6DCCA5D4BFB36628D88975938CF1C3658E4F72DE501917428D62994715C83FEFF5A714878555EA5FA7547F5061BD6DD148041AAEF04334463910D3E82090D2EE6BF80781C3C3E2049424C9D1D3F9CB98CDF1DB9168734CC4CEDD241F5C1F26AD69BD979E69D2825370E36C1BA31E1DE8B150B16201967528F5BC096B1A43A06F716A2862D107391222EC9C4A546F1DF3FCAF3F5A0B8B40B0726E80E4CDFBE174899BDD50BEE334DBDF77F0A91A9DF6900BAD7CC26E7AA8E362A6385AE373C44B0945F5C0B2E60BB55991C14D22F5518D200ED43815525CA42F8331913C9C8F532ECEC1F1A2A8DC1A7B38AE15B8BC99BCB542B866333B234CCB125612CA99E285A447E7DAEEAFE79812F3E3B372CE0855B9969428EFC911E2A332336FF43CE8F661B1FD4BAC83F56842E716B7F149BB39B4D22EF5D54592D551AE15F98DFB9EE27DF3192874DFCF8A42D5795A636C83C4B0EB828894EF8C783FDF28FFBA780ED18601DECAFDE64C824FFDFF2E40DC5590E7098FB74B226A5C556F0B2BB68C3628587154F42A7E80A80A430532129D642316CB975E9501B0E2933377D04FF576C922E1CC06B3A5CE6EA7E1B611DEA65FEB2B092B81C86F00B99FE676FF7DDFC549789901B87CF2BC775CD5A226C3724D7FC14CCECE36131BB53CFBD4B1606C8F57A5DFE39C4B946C40CE3B36F6CA43FA043DDBABDF56B03CB12ED1D3E929E7F15FDA92615277421BC0E7DDC4392B2CF5AF79193B3C26FCA0EE4CA7E34D89CD99AF85D053346D4247ED68226A1C82B32344C1DE2BA4B71AAD24FDB3A4004820F450DB8766815554774A3372C1CB97B5C365C0E78CA06B143022FD54C7BEE72CFA7FC2F4EBE218BE84CA503DA9067F36D76839F5E4386A95CDB65221A5FC5D39A4AFC65325C8E17E1FC22FB73E97B5B0E341ED24AFA1A50629E7C5829F8ED47EE13D25EB6472B6A4C795716688AAC6097215E423F8D8C7A017E10257E96237D2BF97EECBE02F68F95999AB255B5FE8A7399A294183DBC38B69139F1612943E88146CA41231E80F5598757650C7C64F5F686851DC64D8E073523DEBFB4AEAC5B9CFFD6F92FDB356E178749397E08235A99C52958A3D99FCAA18FDEE9F5C49AA3D3C9F", + "sk": "08C583FE51538CD926528D3F9E09CB7D0F90FCFF247002D162983C5C34B92C174E00263334CA00EEF5603917486011A91A03BECD6D1218C9AACA13A58D65024247646E4A2289A28C38896950E8278F9EB1E8E3AE1E8C07C748AAB114333B716E7E95843F237086C307225C1177CC0D2928EB2B4F1F81B6479CEBCD693B92FB6E19106000434083248C62404C12022C89024EC38604502204C8444EC1883004256E12352084342550246DE3B880D8824C4A16051B89448080052400680A25602337848A448083C4681A4888CA263211A0208C268923246E5C3682604482A1B22001016CDC128CA0C26CD2A67012262D9C084114024018376454140910306CC2464EC2426A91922813382422996C633844199681182512DB1672A4088E489490A0C429CC46212146655312510411915442211B032E10142EA0108502B324940826C24251013911C822701A1249D230642409608AC66DA2A86012027124934D011760029605C43821C1048E42320D803081A29688028870D38009E186489A426D0BA62D120566122152D9380C40140A62063204965000B985131025C2102D18A07098308099160214B425CB340A62C88080046D5110048C228A00934C48044A8B48219C02280438006440520C41268926694C3664C1A46C5A22460AA54C520032C89051C1A064224430228344D938800184288922881AA7910AC930E4149009C409D3826520C81002A4319146240CA400C3246EC1962C820490143850113549E49069CC106A04052283B28942C86C1CC151980244C4442E14066052B429C8A09081060C9CA80D8C422042200D0A9188810069CB243260361104326491068220220CCB3441DBC06CCC92505AB271E22212D428301C3390C99481CB06721A0266D48471414802191072611610003682402222DA00520C914D89328E4102094A380453000CA1006123A14D11C03121339054C64C4A269264366213C661E0946111B88D88802D82C66103106EC0400143482C20A4900B011049462D0AC9705904004924248C2622913092D332826320669BC62054C211A3B4401129055244320890211CC54524C485030971CBC62554A240D4A005D838260213804180115B2849612011C9402DC8B851D1304008368D20A02582A421DB342E14181102462E23126510C9091C804999248C61820D54C44D59C08403160DCA10420B140ACA400E4112419C22885A1689C01202A3264219A40D0348044804690025662322929232690C4069D792697207DC3A6B716F6F82572DFE0FF9F05C53FE3215DAFB1CDED3575DBB95839694837C86E2056F91C27C7D15F7337E89B7ECDCDCEC4B3D982CE8C1780E8C9F9BE11FA9A5F51440775D8120A60ECC8C0B5F6F683E02AECA449F98418F39DB4399E1EDB2C4475706B2B79F270E3BCA18725BA3D8BC834651D29C1B2CD688FE7AF80818C4D9106ABF2E82C3B1C3F09C30C8314559FF0B368950D50FA2D3069D31062263F61D9B934D0C9098F0F66923ECA1D20F5E06DA4DC4B7CFBF74D035CEC73466D1596BA89254579DD536CAFF93EB4C0549AA55364F586395408E8723DE82962B8C802266A0643D9D50D8AFAC6708814AC67F24790904CC71E728B030CA43B39EABF450D6232ABB7217E6193093A95AB2F5EB4223C319ADBA0BAEC5D1501E702DA6FF2B0729C06B24D98E268A22EB28A3258C6EC03190132D7012696B81BF0B1C921C6F1889801458C343B2786A3797D9913A67CC171D89B93B521A18452F7299B97D10399E02A91BA56FE1AFAA92F5C418996C1A29EE8A1B5B6F664B6D41DD69939EFE31DD082D4DF59D428C95266683061B26BDE28198AD135662DF0BF5BB401B51D17E576C1A1960942B74CA70AA5D332BD238FEF557D39CB4B7EAB02631314DBB91367ABF476D2E3BC2DEED1A05654338F889FB7F1C4D08320638A6B1FC61C25B95FBA474ED1B2758F69521C602C123AF1C9D331657696D1AA5C55FE671C069CB2CA18683C2F7A5A35DDA52E3E71C0BF77EED74CA7398E52876673162B88D63690754DAF9BE8DB9220AB35A72397CC60276870E7DE8853ED89BCC0E555247AAE1BB22236EEDD9E5C8A973E46767CB3AFE20884A554E7C522A45B599FBB7F1C4F84609F5489C7A798A0FB79C4B8963A0C05B686DFBEB324AAC5BC97BD46D4149502C36D767F57CAEAB2DBACCCDD7F31F0ABB0EFF7978EDA13EC1D0E2D1BFADF503984FBF23BB56C68E3C7C759136A12A1E62A4D11E3A08A76685D082CA5C9803CAF1AC032B9FA90E16FD55416F189C2B13C2414EA222CB5DEA142D41E7B2BC499B7891124D75F8DF559850C9368BFA41979892DA46F22ABD2916884915CF1856B4A5EB3CC00E4CFFC36A48D04C8F4BAD2118188F06F76D9E58A2313C513555C33D883FAEECFCA01330D740148E03B6E21A35AC08B85F788B5373E9E5727C6673DDBA5995D0A30D7863E435CD58BFDDF22C5BB2D270BBD74116A32849BC6C9AAFA7A26AA4F0B0D37801FDABE99320F0F33A025093692C76CF06242C41A189715C239E2F72FA59A46D9951ABF6B115A1ED0E517107B89F0EA49D7C70E69DE121E53347FA9B1F42480B99456DB5862315459921203D93EDBC5613FE2B7EDC756B67457917ED21EB46D8B7D35B0CEB9C9451D6E9BBA9290A96AE6D7AA14C3AF93EA28DF817DEF78007D1963FDD20737C1D503D47E94A0514E8D06BBB78D195F5C2376D3EF02E823465F94B07B09D3F67D1C89F38910777672C554A9ECB6F5B24179CF92A725DA4A80770E46C4D9BCE5855210996A3957E2CD2B25F5A13FAB9E87B8FF886355AC4EAAADD10F0CB5DD75C52A0E65563FB26F4E0E5CF52D2E07C666088090BF866A58B75D8DAE3772F47ED298B0CB49806783C6A057BCB5EDE6E27F84DE01ED80BC1469A07A9B314723F33E9D871CC294738DB9786F77DC4F0D8E23CB15448140B21AFB5C2E6D97C077FA45DC39CB281BBAA7D315B606E0AFA64E0B02D939904AF11534335C0FBB18D523B448F0B162F7CE993A3095C49AC63663F42705851FA5CC43D70D919EB4313B00C0D8B14958C02C674EF7F9FF48A164BD82984E784F3B3D65DDDE52206646B400037630F7A7C36EF61D3039BE92FB4EA9DFBF0040C307395ED490009E2EEE43FCC9BB05A648EC4551D1A44F901E0AF85F4E3731BB1CE60C4C374AE440C9E05E4818ACE6FB50E70ED1D413E6C89399487C06472AD15DD9D2BBD7B9E1961CA94A7E15DCF772BF9172CDF7B9E9A67164661B579BEB88DAC9FE577F24195B3AFA624DE80D021742CB6C91764BD9B7653CE2F7FD162F2DCE33792285FC554F2235273B0646CD8326090747D4F87B8D4E24872F44E8055B4E5E938086F04E1AF47937C4BB4A56F9DCFCE9ACC1803056DAEE856B24AE45BDD89189F08EB4C908F1C4A6E22B3C04FEF78442733BE2AA609297D8A15E42A2201EB18A87723B92514801A37FFD3B4D36481EC2550DC6A620186413EEE403505A66BB725E65838C6FBDA562F4AA3DE364E237B9FE50915D3056054D613039AD3208E700AD81A745D5480611206A8E45D5B13BC664C724ADB73C981E8788C07B2A9A822883EDCCCC179F376F113642354DD6F11B45A6E317DFB215B" + }, + { + "tcId": 20, + "deferred": false, + "seed": "B0C02139AEF99336D87001D936CF8DFE30459D268074B69720B15BB7939F3D4B", + "pk": "763FB831AFE969385A5E604268724FC10E9384AD30D00638C68CEA2D8C5DF9B9ABDCAF2AF8E16F7272A96A8A6EEB6C41EF400C05688A73129FE2DEC50ADC3C7763BF670381824A474E2EC5B06C5549530CA5C216E06A5D0BDBA341983705703E9AC306B796223991E8D35AA0856184D0EF5C44C6B3BAC268C0D952F571BBA2852BB93255459EFE2AAADF2B24D35407353E718528A331F8700BF722B6F51B833DB1F715D358455E916684593438071798E17EF48CE1FC777F5D2D308C22B2B3CD4805773494C863AC6D447C8361ECBA576F0348459946C7227FC8905A59700113827D88524BD68BFA2ECA81F9CCCD0EA759B2173FC6D1A6EEE3FAE3D9601411387B8C39DFB3BEBCE4D6A7FA5C08E61606B4B85F21067A6572EF6CE91D39F7F2D24157006B434361592EDEEBFF2277C4FBBBF11B30229009765B8D24F274D7DA88CB8E4A89D6F77F8901359E504EE2F04214F8D6B560705DFC9E7936D5FF1236B2D1C83459C0B5B6283E34BEECAFA84A80262F206D331231458F9E38EDF6D5AD5D2ED1ED84642A14265384CC302F72961D11A58C7DF22CBAE52A4ADA704EAE6FE9477CEEC185223D82673323A91385F5575B30A0BBBF6F24BEF7A62F737FB6B88BBC89B9D6429119671B74ECEA5B98BA0597510D3CCA0A853688425257F9017F0777C02E40D6F2DFAD9AF305049161283D90F183826C5FBAEB8586A2C766CE4FAD6D3D565B4CD459A76A2CF23D8565D493BB09035B2C44CB7D62AD772658DF463112E747221D6AA3846B207F839BE7EEE2E2B2FBC2A851D666943583E36B2565A6C80AECF1AE6F9A0999943BDD7DE253769E5C5195C24B1E88D67DB38C5378A10239A7DB6205BEA44847AB1CBD3954D0C6D70E26CA139FBB7AD7AEF6899CA7B57009B778DA2937EA4A3340B8C389C2B251A0EC3C9AA697AD5320F9FD41F799714E067EE46FA9534D531532D7D62A06106920751737A52D64610E181AF8DFC424541FEAD333BFFDA949CCA8D19BE372CC14DADB16EDF4E65B336ED1C7507DCCE4A1762B0CC2EC69AC3DC0E7AB12A837FC227A8911EDACDA112750C295026666A7EEFABDF8190B355928C328E3BFF06F10406915C358B579A19C55A07AE2FB071434B69BFA88A92C52CD795C97FFF514CAE1C4D0D244FEF3D26A2D2D62C931E8DE8698D7EBC93533C37F365B640B91C0B85CF55075DB6267F5A980806C39E096A39AB4D86C380CE94F5EFD7E1C44F1F77085CDFC0460062D4579999C9E395CD8338D6AFDF963E7DA6A097350A39FACA19BC824A614A84080373A27B550C4EB321CA88291201DD9B79FF69B89FD50FD34FA80FE7D6D3F5F9DA98CD2E8A151A5B35C7C6A132123FFFB76935AD5D6EE9DBD99C2D5E394E540FD3A7B76439CF442807FDC4FA8FB4A1F5FEF9EB09588807C80A9573E54E6678639B45EF7AE51F7311463E9F345F08D4594CA94DF334C29E69662558DA177F9D4329F25E191832C979FDCA310DF96AC66F922AFAFC38467FAEB7D6B57A2CE46FD272998C17B78C69F62E16F72B44500532E886F10ED712796F179DFEBB634CF88E7AE99BC4405E69D89AAEB42C9BD25FCFBC8E4E88189CDEE12A87EA48B204F7FA2615430F8F642683FCC22061560D241B1D1D3B746A487DD2E17A81AB89EBB01BA9AA3DB992CD0DD68392576E65E933A3C1C9E6B561575D073C3759BDF001B7C4B96A15E419F982CD8E846E383D3FC2DA80605731A0A65AE905D6D979A1931A174D2CA5CF073677C862AD63810F945ECA3551F63426E03CF049882DB09C067BC0A8AF25672FB30F0E79ED5A1A3FB0983AF62915752315159D10D3AB86C282A5DD123170783E00A15A939A4", + "sk": "763FB831AFE969385A5E604268724FC10E9384AD30D00638C68CEA2D8C5DF9B935D82EE28F88A1D59D0F78740D34116061454F7A1A4258B2EBA2AB3A8EE9AAC87EB6ABBFC89154E8249F601F6A3212EC53FE82DB06C9FE7777B725DD75D8EBA3FEA86EC5B270EB3C5DBEE5D4C5DF89E46F42A4482D8EB94176A47FFDB279D67EA2C00D1214604C142EC1082598045150284882C6649C3280E4B04D09C60511A49093286D93200460202C9B8441D2C865E026869816458292908BA4905046809C302E544642C3422A9C906C64362C1C070A1A1428A224680A030890B449A13481C8402118122888360C9096280BB3819B067163342010880911832598C40DA40090C1240081940DCA124A54120898284000860D140730D9489282B48C04C1508C0822C428461B338D23002490808019398460A240800005DB925002146211440610A628904632A09861DC303142924800072CD9368A992882C8863004095252A6301C92454C4072101320120060E28004A0C4601143109014051B164524326C6206321A035110382E10414C82B88451386A0843315C224E4210410A4991A0882C80428DE3344D0B030252286820477021C811D2426C59264C0BC54CD9309183082998368D08856921424200424040366282800019C6851287704A428604476959909151B408D9880421C930DA346948844C1AB54D0BC9000B05291BC250D8C44824296C12038C04100A84C010A0080A8926880C25051C390923C08C94182293240E1CA541DA027212C4452305025920525418480805820313724B888583322048106198465144B86183C050D0340200450258A6454BC26903B80D81104E001501204425E3340001064CC98220103941949884C21681D29829A1B26184324608C66158304204173122B12554B410E2348D8430121A010AD1169083220A0310264A8890434221532244D1C86122998D62306D61462022A40062360EDB380082A621D4267080C441C9B48143A244A2187091B86044448A51240A19C251191310D4128E62128E6288850AC48DDAC00C1011710B402482A4019C046E80485013400891000A0814054B02051A476E91A87080B024194448E0802521426888066CC82829E28208CA26308A041210845103A02C529611019245D4128491246A14B59009352C14350C132460144666D924225186844AB630C342484BB0651CA2610AC04023158E09402C23B2508C04261042666104492393044A3292A0844892442A032762B40570BBC2ED9CE35E4E6903960A5DFA7800993F5438ADD1671D7D3848B9743709A9774C85BC528B2F0F619998B7FC107A4D4AE40270E5F55C889A2A0AEC5AD97C118A6BE6336C1A93D545FDEAAA791D4DB90DCF2317D2E6F013C12B027E38AACDA013E4F1C660D25E43402E89CB69F72E47617C2BD4AAC1D0151930CEA563066C3261F767587E07AC68FF4485726AE42B210220452A9C399F684E1B9B228F6BA15DA5F02401CCD4858E2F502B367C5E79EEB28C6D63DCC2AEEE547FB67AC7D947125FB162133BC836C1B931A454BEE47242AA8BEB8A85AB41B4184BDEAD20458AE8734074798D86795C8AFF512927D22CEB52B86B8006B1706035116C4508B35FAA86DC4E6EC735AD9DFC4EF993A79AB8759974270EB82D78A0A80114F92A0A8A2806620FAEF97669C75ED51E5E0BA4E1753C6CCF75FBC0F7CB42F866EDDEF10AA07B85983B6E49F630501311A8FB986DC978C2DF9DB275FD67834FF915BBCF5B3E30A6942FA2C7F062EBFA5C4AF36E22D57251E8E79C9941E09803F98B4EA46D556BF7809D9AF4C86B8B3A7CA6BAB3A0E48AD77A5F01E7D20765417D3C6561E6693F061B58C137E95B977553549AE66A16EA02D87A906B993F9B8394E6AD3E7A4182B35A70345421858484BEC0813B6104CA50C09FBA0F291565B50E28766F91C44C1D989162A8DEB1E95BB0BA0912D6C506A6DEBAE47A4E939F0F47E88EDD14F8A35253D8337C2769325F81F1C73D1E22B54D8133E4223ECDC3FB4BBDC0450C8E007E7DE2ACF075E5D9332247B6BDE0058EF4E56EDF59AC3C8BBB88BF7F6CC48D85A04F796EDA1CC91D08F839339950E82BC5D04FBF27AF8D0F858B4356B728E56FCFE4F04C2F7672E0EC5E6237F73382E9E8004AB6680423729CC9C51366465B4C324C18ACB245382AF26F26E4430746E98328DCFB24148486452F284856920B162F932BDC25A86ACDDD3D5A1422A0EBB94FE948FB58F2BA856C945BB20BA07E0BCBDE5740631B3F6E9C72B14ED7F79DECA30AF6D55573157CA59907340392B6E62143E41FA3DE63EB14B61631AE846F80A9A7707B9C2CA22A741F8B9CB6A2FFFD432BF2BCAA059AD23D35B6BB47CAC39CAECEAA917370BB89D33814C31FECE827889A7D758C031DE16F58B4277A04455A7F515BCD34630AA0A4CC253B5741E99A27F251313177D52CDDA8182FAFE6B32F4B820C8EA34413937C9FCDAEA67D16A7C2EDA61BA1B8B7266D48C8E8408F299C3526B57198FAED1855C2645BE3F678846491C5C440654E705EC349BDFF04AE935196E97EE9946C3983A4822E0566724C24501CCDDD6D9D4BAF8EB9D065E5F280F8F04CBB7B3E8C76757FA760701F28776BB86EDC0E85903AB4CCEAC8DD89482903FE6137675742D4382C4C4CF66FF51A89787502E6F60E5E622063C71E7CF1EB365E6BF0C25DCBA8ED29561E325BDC64E528DC961242B4DF790C6C28BC7217B54ECC4915FB29873905ECB8E9E82D4349D4BD8813134F2930E0F3E79F3AA10613D535FE717EEE3DF66C1E829876E8EBD5BC624720A00F2EC10B369929A9E6F1EBE7C88C7D4AE413DB05BCEDDFD74D24E4DA4237B17703C6A48825521E75CC0F37EA656DCD1B10D2000B2B04A884C64620D607B1099D08A745738F90AF19C1635C5517674B317A609ACE877382A34F6604EA3EF08148280D1F78B1D2CC538671C71C6AAFC538FAB60D95977B1DBC2C4320BAE64E595403F7B54CC81C4483A69B6B515CBA264335531705AA70EEB88B49D14D3B8EE588C6E32F68F96B7B5219C39BBF1FB45E9617CDAFCC8380AB86E2669812A2C39E5C3001B0BA98847E8BF01B8203618CD92F45926DCB22D50E2751D5E3271D0E7F159505E4FB7AA9BE30A82DF405B4C0EA3778E1B75634FF4356E42409E36BA15425AB7ABD650D855340D203705D07C33250A4AF67B2DF4F2A41E48957C98362D6F55C202ECA584EF1511577EDE1368D6E79EB3DF014FEF9064C082E7709B06D23914A08EF375A2B63DBB0DA0FC780B66509AAB62B9B47156E479DD268989624389A098BC36E65E4E43DF5A804735A32FC3D91FBC5F29AD6869992BC02860BA35833D6782C39496404419350B54D8A176CA742CE6D4BE5440E94B00E16B2319321D3BE09D7A65D40C0940FBB789156AE56E41E686A0B31ECA83FD48BFCAE60BD670C262E454073C0F3E074566B5A9B7AA61F26FE7DB58755BD63FD821E7D282EA7779D548ACDE1EED0F2D4EB49DB8C23939E2C925DAC5180C3CEDB532EE049816C129697EDA8616C1ABBDFF14952F7968003C212C4848E5B91A19F1B8C41509B2A95E548FDF81AEEBD2BE401DE92E61A3A818AEB92690540903F" + }, + { + "tcId": 21, + "deferred": false, + "seed": "9E5E467662A57A5A45824B882101553E95DAF19EC097B6310ABE3935C24CF284", + "pk": "1FD64A86C2E0D9EE3093A00C0E6720BE47731447998DD55FC6A39553939B777FC7911DD947565A75C3287ABB7942631AD87C6FFF760DFEBCFCEE14E7BFD65B32E722CC3047FEF7A8F99C454195840788211DCC2030828BDB355CEE813D4A9D7125D00E35B676366E04A31A2643DAFCC1C25FA4CD8A898D9F47F14990AB4076DFBDA212051C8C480FFEAC099247EEAA1D84C5BC53CAD03C343FE912A6EE3D6BB0281178753EC6627CA8A28F2E1D2EB4FDEDED453ED83B15A26D1C88D9BF8A62B9AF8C62B5149EEB239369F1432457EF30D8F0A9151BD89AE270FAF53AE69DE47D90A76931164DC0242FB52ECA46D62E096BFA42FBFB2F6168F390917B31E750E2A20F7175E27D5D4BA25536CCE167473A68080110C11CBAF5BB0275003A552FD922E6A8F9B1D31AF1BC5F8D5A6CBDF6211FB48A936081AC3A155047EE28735668C61A3AA2F336914137D8646C2406D24EB9B825C1691611CD8AA3DB2C8D35D3069A002B39C5DB8906536F8AAB76A5794187E6319278262DE1115B7612E52387A1CD8D2BD7441897E4B91811BA486557E477ABC4B74D222A45D70B6CCE829111BA8FB994E148B1211BFFE473172F5A2EF1018139BD10B2627EA1F3A15518EDC7D53E46B6A9A731E523D7FE923BAE33604408AF9CE5A671509ECEE80F7E38E6BBA2001EF73F41397B9CAEC556050EC6FDC403C71FD690A9E043588542D0509917A6A4B2754994A3A42346D1F63762E72DB5DA042DB3477F2C11081220B4C257B413FF52AEECE4F418A0B9113ED6C5B28C734C5F174E2D8D7ADCD1061756AD3D77331691ECCDE82F0AA4E869C322DCA08CFA9F4763003F4DC3367FB7A1432C4B3AC127C84809045FACD6DBC8F5059C04D52FBD5BAB1C695AA5C61D1484DB572C88DB0AB41EE63850ADDC79359C9CCC6E211483C11208EA2D94CBAAA8AC1B3EF0FCE07ED0F9CA944CBE4D39F2D7460E12FF544B094D5939FB5ABE5E3096BC367F3C293DEC6CB1EEDB4C4C24121A3027D60AFB7C7A171C18E954BD2D5961CF7EB547888F9C3A4002AC82E09AB02E56CB7DB36673E74E77500C6A6D30DA50A1B054C3FD8BAA0C8180E1A50914DE26A7D4515DBD51E6C4C804D39E244B7D94705B7C1E210E1B651F17F87757DF7169616991C010E69D7204314890893CD9258E7672C2C5CE34464C188DD22E8E3B8B1A11DF40D32917D7CA89F6B254BB0BC6042D73AF18C92A1F6B02B68CF59A1E2EB4AA4F646DA63F29FF89DE07BC52C723AB61898A8B247CD51888688768695C2A0B25D89FFBB2E056DAF6F465215444E856C49E0849253DE4CC6B4C5D0CBE2D57D7CAA589892B9A228AE8157546997D4341742FC7E6CE226DEC98FC18F25A60D347331E29FE524D8EAE3219B739C84498A98AA7D5FCFCF3E8A9F6335FD242867CDEDE024EC7D0C662BA136FD317E6D06D197B2FE1DAB09E395758DA72EA4291CB5DECD4B68BB68EF7F910BE2879A43A8F3D48F61E6ED640E1614732125009EB226680AB0BAE65C282A5E56ED17729D53CB9BA17612CC68416A2B23C243967263AFE1C171381D82ABE28D2CC519F3FC52A140D3507EE92442232D488CC906BED2A399730DBD3E459480B79C3E4A5ABB98EFC72838A530AE82B80571A6C37482BA39DBA11201625485A16F48166F3CF61F719F6E67D4D29DFC769F88926E5133F8ECB1029BB8DC1B349398AFEECB8B893A01C152A75BB700D44ECED0A8C5A77983169ACE8B341C4AECD426891AB4240B246E4E7F5BA79B3736AC8037086492E038124D516A821C96F1609FCBE302FCB7BF897165F1CBBECB7CA1395790BBAEC1CBEB30B211933556DBF238C0FD7E24B6489477CE2CB05", + "sk": "1FD64A86C2E0D9EE3093A00C0E6720BE47731447998DD55FC6A39553939B777F56FFF5F2ADDDD78A3E2BB4C5A4DA9067271817DB907906D2554CCA567DB41268D22F13499DAD6DF046717288E48EF9D4C6D3BF5AF14F53E0531C57889404188EDE2ECD98974286206E0343314B528021B667436B73DDCFE8E87AC5F085A4941682B26853860563B86D0CA8400394418B088A9A803112C08501C701133902DB488A1BC731CB482552908994467082028D52B02C0BB86092020121C69153B04954188D8B46811C897199082C5A020684A4211246241A892022266810406D0805651412001B104C99A88C92C0305C1441DC0688A48069C3949042842823090AD1148862406654224421B109142910831851D9100698060A543022D3C06DA04411CC340413B05012413251B20D9B46860216490131811BA34D51B2519C98018B2848D3320523459083B07104C94811808020972CE41641003686938221599060A1A6048C886D244200E236114928494C308D1AC6806482690B96491AC30088188D19138DA4188D18344421918D8320714B04400B406824219059C830E14461E0080154A849029849C024115C1268232480C334244CB08DDA40518C0664131869433448C14000190145DB1026E3049091262413088DA01852E1401209A089903490D8284604B7110AA360198760E222804282852082309C046198327150103261000808C544C8B625434464E00008D8440E61980D889888D0286D6410304438510A1684CAB045DC322A21928D1C240840022402C42C9916724390710013291C8248D804265344218A44049A169010800424A60D022988D9824421360A998471A4368053160C203608C8B465194341094601D3268011340C1C40228906869A38681B338491842CC9426E04992D10074D22109149C229DCC600000889E24688E398058B38244B828DD91470DCB06081802119049110449111903118348D19486C0992311AC04461400C11144964428413866C21806CE2C004E0B44413836111370A1C114689168880306861288D54147180062C19096A50B40013447188C088CC38301AC940044029032621C4A42882186824A110C9346494966C08A245C9840442428C8C3405D32210DB200E9BC28DC1966818414C5A482E08040E4AC810118511149849DBC46D99B229181189199581CCA29053126E440826D8106DD4486AD908260A34814B904D88C05118184808459004B5091C4465D2B83090469091B0112399705DE3EB78E228DEE7F70D7299EEBD0AD40428FE8E4B14E5B573837033F825FC13CE5CB416F30FF882459FD3FA3EA6C4281C3C85C2E9FDCC7D0C31D39B8027EF4D2DD054B580684DB2E5EA26DF1C0BE11D9C531104AFCE61DB9B71EDF512B3EB8D2D36970503686682897D25369E1C663B0E0608A53B841FF1A6005DDDD3402D499990DB2EAC2D0FE1725D1437208391D84405C8C01C1DA8D50228FE96F4304680AA4B22453F67369AAF971FAE95A9B2F693F2283014F6C33B282420F8557D81DFB26E1CD9D15ACC9BC33224C015C4258041A108D6E14B64D97EF69EBE0C9763D44508F2849EF9FFDF043301BCA68F77E56BC1780B6B9CD58A2A550389261864E2854E3A78AED80938832A8AA14A68E8B59F53E6BA4569D39A63FB4256A50E4B5411E1AD2C5FA6DE66F87B8569697D9C1E4746FAB1DDCE6F152F2BE32FB8BBFAAF8BB1CCB14081E5415633E7294226623737B33528D66003AE0EBFFFA9E361B9828FAA39CF68744B442DDAA2976290755D7B7CC878446DCB11C59A5F66A38BA6B88697809E437BAACA2898CDA27BAEB33BA2D1930F859E2EFC28E82AD1A407177D35C3A8F76E4FECE7D8EB1C5D686D189EDE5BA8630EA309289F1B1E1CF294DBA76FF182D981D501E5DEB931CA103C3F56A9FAE857260FD8345994A0D2704BBDB5AD73385E3963F7A4C7694C35B1513FE8D4F001BB661D28996DACAFAEFF590C3A8A4478BD828105775CEA545062C14BE01FB52F4CF39F6EF90C7F6E3FF40ADA9FF4BCF325B74707A38AC8CCB3F4F3337B2F42380B8A111FDB72F8CAE96E373FEA8FD8B34A823FB5E2D6EEE425625504D985D873DDE7F7289BC6078E2A11E5E9A90D004412C44692B8827B8C1B9D6FBC37698CF2E6528C3BE794C2B343062E55D20DE220715A4859D0EFAAB0308ADEB3D6D0AADA3B9B83E790F36513BBE4CA857241BE78D98DBCF4FBC50AAF971650724781C50B993D24A8F4F9109D82FA7A208982FD6A924C6A1047A233C0BCC59038225BD872B63BF5B698347F7256047D7A0A0EC533F0EF8FBDEB67B909E00F120E1FC36E70685C99484AD1CC5816E63EA40467001485C52BE6B0B8FD38B5D5929DEFA9EDCA9ED6D699D40BA4B4D1818B71809E26E1D3BAD6A8FEC83D38E93D6584A45A5A3C74C7DB19F461C4D3A1C0ABE6C3E1953128508E8E4E1FC9A22AE185B557D8973C727095B1D90144F86ADD903C8293ED633E092B38E19F14A488EC1EA141FFD1F1E1F14328209A449E40AF2255447F173A6E39AF85902C029C33685D50E6EBDECC5BBAFBEB88D4B8D432832990D653FD63E4FA6E288CB94C8ABF06A96FABB2A6981ED1134CB5E20C65EAE52B0ECDB62B5A4C2DDB2535EB6522661CEFB5C510ABDDC11406B520C8B9D93703AC241A91078D9256631A9EE567AB7518D10C6CC5A651D7B762F4D607EFC780D121DF1441EE5C72C763F40086DA2C85778484F30167FFED8596C118E76A0FF1386113C5558DBFBD8DD79C898E6DE18537C0E026B2498478B13EFE1D521FCF982E18380C9CB2F684633457169F615CF9D9B0970F034B2FE0AFEC705499244B9ECB1052A48C0679C9D38A94851C0B3832894E833D712537EF9616F4AA245BDBCB7ED4B83FB02C34C4D28F267A2207FF9073EE2A76864154C8769BC2CC21E18452FE8953F5383F7D03B8A9BA9BB79CE31FD16F361254519B4FF065AAEA21A0C00EB9886BE1FAC0A9B11DC2BF6A7ABB94B75D884C9EA00F35FA1DFF62A3D8E50BF540D3C3FDD8C0EF8EEA531C28913A6AE19AFC4B1A8DE1EC52C939DAE8FBE784445465E8FAA1AC810665AE3AF82C82F18713E0EE56CB74AB2F4BFAD6ADBB2FFCFEAE2ABFC3A0BEE65C271C3C825DF01DE8DF618342D4F614FE005B98344E43AC02F9493FEDF6B4966BCF2B5907E4A71DE891D5C2256F08E79853986505E99ADFBACE9B60538F1C013E72E4946A18CFECFABE38AE16F05C5A4D22989F3C83C5FC66C6176D2B26D5EE1542A25E189A8954F24D6871A46301BB4896F614FA6B7AA536D30ED024D726C87F95EF9AD28F5B9FFBF08D9C2583A32A2146141B53185F70E34B9EEA5FDB967BE995AD54F8BF31DABC5AC06F7C6B523838BD49E69B5859FF6163F5C6F3D52ABF90533A38E2D7DCADEA0E05BC1484B720EB2534D6B3FD4EBC96937BA9211A9EF55BE30504544BE33A4FEB14843905C68F03A6A03C7B948AE195A951A5A63329BD691C73C613BB9CBFA1BD25341E91F8CC94B4D2B7C1DD4B8F6FBE5E00C91A068A453989D9EC3D144707DF6CAD210484DDA0F4FCB6AA1B3979248911469E9747D06877C9621218A383F81C8A1EC1D2601C9145273FD4F9737481CDE2F3E2" + }, + { + "tcId": 22, + "deferred": false, + "seed": "E13C0B6585FE12EB64086B34B49D5E074EBE3A3688EDEEBB26A737C0E5F73F44", + "pk": "34CF8D42A986CEB086B210D348C30F0DFE538760501F0FFDD2D235E615E5253DAC75D4E29691D11EDE6003ABB4D18FA0384B21DF71489ED36530A0EC48B33205C2F393713D6FB8261499CA51007823D6233B77CFD8713A096D4C468E6415017617E36CB55EDC838A58AB36D56B2D4CC0621980C4E0D4637B3A6E3EBA245EEBDBC29B99327232C279F5777A2EFB8A74D492812C6E9E620D725E6AE4961C20AA7C84F4784F6FED36FAF3696898668D3DB7BDE29D024B008236A58F5A9ADF320C3E5428D2482233A5E202A31450698FE8F4CA36604F0A026163313FAC89A925E85B09EEF12B2F2BA87197B3E8F5F6E46CA201CCE21B7DEFADADD13EF45B36683D9B6F8E0AB717A17A9082EAB98BF09EF8F71DF601A4BFBE04F84F7EC82A9BFD1F0DC4FBEF540D59B245364CD6566C5B5E6D735282DDAEA74F66B589A574EE3CE5B79AB6B5A6FBB434E685A724D41FB463C4323629AD788E842F38AA6AAC8A5218EE204D2602C410730A535484BE7B7667E3BA8168FC5C0D354D8B74B583545E73A59132C729607F73F1298B2FCD75B1DA1A29EABC19157566DEDBF4C46F33ECD31D10B403917D856781796FC83046E2F06C702B803014867D15323756350CDF06C4FA6E9247ABD204CBEB4830553363249FC79355E422D50EEC8E0E153EAD339181859E8FCF504CCDF3BE063A2D33898A5409173A86A4D20638063593D03E8746EF26EFCD4356EDE61BAA087157081C3A49A4A93A666A174C0D776D57F792D0908D4D36A46036FA0623D6D4F98389782D9AEFDD61CF23E044F62B73C124091862F2737232FED252A36B0005FE7129975C225957F3E576BA0FF70458C169F54A0BCAA3E0A797A3727DA6865F5C8AF06FB67F3DE4B8D004592B67575D304A328126D51FFF766D4660ED110E911F6FF56CB45D8A7BC187748FDDDB58772BE7F4666AF1A21188AAA0D8DD351FE52C8F98BB4800160884AD064F89062AC122BD3EBD03FB3C16C12F8DFAE0B0321752892061541B95275AFA789584728E39DF5510122D9DCC7F3B44C9F711579608BCC76A95F54AAF9C5B58B1854FA5332FED297961F65587BAF92BEB65404C85E78C077CEBC3488CA8A1B73BDD041CA3D546910DB7B2CF04FED3B3A5154F416EA7152B3D3AD0BE22A1270D9DCD13A87BF8E45726E2199B858A8D27EA1150D88F652220564DA7A88EE65D1B8994859AED54912D92BD1B3AB3269350A910854302E3AA5F22D5E1269731DE82BD3853F1F9716FB6495374A012693DE42AFE190BB1A5E5158FE6EA8855FC0C0CF839505002B070A0C3F21798F017A3B6E063EF7042841670A9DA96C3B30F47DD02D6F8907E19F72700B81306D088D0765DB3E75C2E21C6BC6C0D592EDB1CAE257BA989CC1D7EFD52D43EA0B2D4C6BA4FE3C1C88921916DB894C7D3CDDC0F5523EE399A06565074137B43705DC6D4E6B1A714921EBE241ECC8307734CC6BC902AD2FEC1144E1F009B64351E2486F9D144BEA0DFCE30A0AE2670A43A4311DE9A1AE77651E65107DDC22DD964E2CD86CDE6D93FD04F7A2245768B163FBA24554B2ED476A31D28864805C957E6AA4CB8E17A36EEAC614DD7DDBDE3E65F9F91072E459A6B6AFA60CC96C5E512F563B641297E5355F758EF0C8048231324CB9AA9315FE78EA1A9306907BBAEDBABCB1E6CF0C7054C2DA82F9B3DEA56A3F8550035FBE4618C01F7BECA085CCE8A0B61F4DB47E521B62C0C1A2E57D608B974A0597ED27FCBE7D97225B67DE6A6BBED4AB12E0FA5B23B0B445280FB4B1DAFCE2F7FBCAD405B58F73B1A6E7FCCA7A0B9ABB0622F136F5E1EB56ED541462D618ECD3CE6F94070E14A663ECDB68ADA26E482", + "sk": "34CF8D42A986CEB086B210D348C30F0DFE538760501F0FFDD2D235E615E5253DD1CF3728449166DE18D01AF13AB89C79E9FF693A38DF975F7817EEFDB3BDD311C6F76104B8BF45649DDF285DA5B0DD590A4F52C69DA871025C4845CBAD89317766C08E753AAB26E1596D77990656793263EBBE8303F0170C1DEA8D31BDF45173500685D2866052B60C5240621B9521888289504441D9202504948808356C22915083088423B0118482080AB42881B8011A4949244381824440D1241250A801D124425C040D5C0011C8260620B62140064E03C504019051D8C64D580024A022905C34210C148910336CD0306181C24023852CE4C05014956540024ACB8629A49005A20840E1A24553C85024992C01258C93C2209A02664324888C443299028E22256652124A0C894118C710E4364200852809453211404414A66999224220348E0A01869C440523094D8A92648BB60C649070E3024518314C1248814426001412715B362DC8B64580240820314AD9B26053B8289A442E9B44848CB049A3382C04498C5B40461BB9518884290136260880651C108A8C3651C032320216886224251CB8116186680B1461CA081259088A59420444222442A0600C39094C886D5C38504C30721C3081041891D4A8049AB08D8C3620E44442C8B4280C442C43A48DD81052CB14645820845CC021824649CA180A0025100AA32C1397014906041B296EC10226243605109429130388919671C006480004125398519C840DE21026209369A2005084164E41A608D1A649E3C469E1926C0C098911032E23924C84204203B15180B8019A80715A3252A2408011412D08C7719B108C581486088824A4886C1416601888459A988C5A30851A04461C3386580281440808D4303188240648428A1A102C933450E32801023406E24405A39650DB9424882006E2245120A1440C186DD1380120042C0A9749C906305218889226880BC78D6202090CA961CB4868D03480D0B03189868591026522953108053023038604859014266659828919420E144101893860E2102A0A288E10B4204C404259381011188AD11045CBA029DAA244003642138705038331E2280850420D94384C4C40894B12240C48818A320418820C21853109091104B1208CB60C8842891C1861C32840CB945060800C0C2810884209C11862192761991848E13848034886CB386E21B08DC2282119C564D9C4318326211A485249122E88422A0CB97091C42D90C00C81A66C9948029AC4101CC760D5A0943FC50ECC76C5E3BBE12B3777C398511FB8C3BBF1472B4A93003ACD253867C6B605316781DC6720DD064BD8FB864900F9FFE46E8570704B47E9D5A6E822DE39F2AFB7C401DDDF305F643F0F67D20E6D873CA22051F55E8F4B5D2CB58DE4866B7821761CB9B739715F2488FEE912A41455285D7BACD08A9F7C047975FB5321E50590A64A0F97741D19198E5702A119CD3A121369CA612ECFC6025BFF69D38DBD4DC73B17BD5E9B02F5592525FC32A0509D42BBE7C498408201B67117512C3C73E285C8006592A57DC7D231DD345C9868F76BE3C1F64E8B2B3A312441AC94CC805BE229BDD53A8FEC70D0958267C6524C4E21E27468B525BFF03F6EB31EFEC6320E266168717C46BD3FCA9D6130D99EEF3CEFA5036973346B514D2611E034CE7BE51D6B234731125BA27AE21E63F8F90DA49445431579397111B78528919BFE9512400F6372E76E2B741E60FE5D1DBDB05F088BA8702F15731988B451DD979E67531BAA49A0C3EFEF08BF8A90396C9F0649F88B37DEA5AF0EE488D703D8EBEAB262F367384CE63B02C5C98D6A541426754E6C1FB92C4E4092A23D31B2DB6194C4056B32AD88C886A8CB997529D32A2821D3AC8030531C02B82EC568F739FD817247407F06E222CEED6B53F1886D94FFA9BDDCA1714E649F4EE985D6B3B0E9DBDF8DFBF5D61CE9134F3F2F8C71DB0AFDF006ABDA46474F0E2DAED2D0631B107ED8F9BF7C9E7C1FB104306DBADFCF8EA3AE03AC6A4A6409839FC46EE6DEB7C23210583CE341CF5BD73F7F1EA61F24CCE3957C1C901F378C8E3C3E3555D8060176A268CA3CB8A9BC02CF0D2A09B963CE1A3B2CCE9C5D10DA86991D56097B8F5E0B5E1D4480C61CE329C67ACB4802CAE0D69053EBE30BAB6A56063E106EF136B535353DAA060FE5F54470CF33816B675C4DE6EF93034BAB55A295FE925C31EDC5547E7538A7FEF4624C4D763074B2E1EF55AF67994944125E69AB5D6149BA453F745BA4D9C5896FE3E09E1B89964F4F790611EBB47214AE0CF847F3F04EA2A7B827DACC4807E360F89AB09F5EFD39ADB63A608273262ACFE1509BC4F6D64291F1C55F0524BD9D103096A79282A92A5D9063E3A3429DEC83EBDAD180E9A766A2D5DCCF47E5CE633318BC491C9DC777128362669F221DE38A87893F3991239E5D634210060A85182E236B8C42E75A2E4F3CF86D3B4F4C1AF40834BF20FE30B708868DCCA8C91105A4A90652787A5CFD212ACA30E5D52433AFB523C9B9333BC834411A6B641616CEB4E63671894F02A7D8C806B45BDFC814FD59580FE0B903DAB7401EFC9F22A46B19210A21BBDEA61E36E59C664E5B13131A0F9158F4EA6C1D511C8807F4D84484CF5D42DF76916A17C95374EAA01BF78A617BB3BDCD5968AE10358726188D8B4956151270F38D9E8099F65F916844B1581D556D8CAD57BE3F4DB4E826CB0EA08091DE0A04EA6E22F581EF80B0AB2061015E4D076D55974BCDE373EC71D3C06B30443C45D7D8A20B27741669C45C2D50C78FDBE619CF4B73A1C39BF3E405360E52811558B92F5C967D7560E1885B52F5F9DFA8CDDB6CFEAE6C8877973DE446FBBFE92D3CF9EE72DF44D6F46F0D325F7B853AE1CF45A9D59FCCAC5CA51619CBA3BB43A9B37BFCACBA2502994C9B3CE6730C0B0780D41FB0CC0B1468E4151EFD0EF2F7B9777B1CF7334245D25F19AB27B2B403474BAF7ED21FA4989E5D11FC8983A5299039B0D539F1A16A935B1005C807CAF252FECCE675F413C1AA37620CC9A033416DC9EC88330B19EB3A2C72D8E10853742CC29560CCBD79DD0CD53899AACAFE61B0BAB975B2A41B4E94940089B7E56645D826D764A6D2EBC25741A96171CD82092369D5D883777F2DA6BE88B648F22E48EBBA07AF9A6CCBF5D12AB564F1BA87AF129BE62E9BDBC26560356D665B6BCFC0A4F0A3D526589331FF5E9319612288B1BC27101910F7DE014B4870153F2149712AC612B9F72419E4C11AF0BF32C8B72387BD81BEA4E797532B8C4940835C347295A160657717166CC57EABC188003D78B81FC81C22A1C04C386FA075927037B32C173F85B1B827C7012E291FF315BD9CA0E733510C49CA55F8B27B460074F3FB509713548A1A7FE238C39B710B4EC0D016962A74BD428F419184497B74F37910F060897201C072DFCE766DAC229F923CE33ABBAFCE57D1D5689A6E801903D75FC004A826280C10D7D5E12F0F15878E2FA82A442E3BCC527A3B9A3B7D11F2250D0EF7CEAD5A7DEED507975B555AB9E086036E1E1F5516B79763DD2F57585FEDBDE751C72BBB4BE09B653AA1D5C68B87BCA899EB3E160B66EB35CC19BF3D5229AD7122A0C9F231" + }, + { + "tcId": 23, + "deferred": false, + "seed": "CCA8DE2D58EDCB32ED7EA7F60926658AF64330AFC8398010232F9910DFBD85CC", + "pk": "F9D5C3CFFBAAE5CA0E0E3630C5C68025B3AB7B3ADFA544503FB8C5F64396FF244C128645896985C4B899BB730245354A7C77DB450EACC3DFA7D3BB3EB80401F2500382A95D400576F2EFC9339C2CE7F5635E04C764A9DC3FA214FF275A76015F03C3EC3C33B42F20180DFF8E1DCBFA2F9D1246E10C80D62C50F62F9903EC19D871CAA6087A76B091B6BC2AB8A7D7A68B37E535CB50C5CB90CC8FBECD6E943981566C4D619E3FA973E009144F085CBCED1074FE864D9CF562FBEAD83FB8367057D3C7AA17CDBF3DEE2E0191D904E0AFD850948054E60CA3371987239B1788C25349E37C6348A713FC0BEF6E28613704741B258B1102D33EBE513769E878999421F82A02BA0EAA98C64DFD35C7BA9E92203F58562E3A72FE2332F51681E927248E4DF1984D1919477B7206B2709BF67E3806C508838375C2ECCA7B59EC8D3FF0666BE56BE2C58F5CEC5530CE02F4C5A4302FBB48C87655DC717E8845C25D78C063E11FEA6ACBA8FB44E26AE15A002B072A8B9204F283A47BEC85629D2487ECBA65020B29095C2CD5A1CAD78157CB3390358D56BEA88417F2619A28F3BE37039E08D5AFE4AF5DF8035977D96240E86B7149FE275C1392FBCF336DC2859B40AF357C687447872E2B21890A629B59FF0B0324029C963FDAD39865A8D624F9796E3771F2562E85A193CF1C989FE42366B79B23FB14EA2B124F3A564C38406E126792C3D0E16C5B1A3F7908780513A2F41B1191950F7FF5CE0AC00ADF6B39FACD4C5C6DE7C3A7271CD3DE5FDFC1E7B1A87B14EC10E8C9E08D861340E8D32BD72575FA9AB69B6CB0945D60515282322DBE868C71C2F5AA797F13ED1E850EF671EC0E6812C3CC009556AE2E7940508B99C5A6423CE8B824C24C25A7BF9D7137935BE95401605EC60DDAC167187786C2088AEBE36A9563D33452266C074B418391EB1A61197C3D48D7C268CA58C7BDC2211BF3E4E783ABC76BAEB35B7B874908510748A85E6EEDE69E483C91CE2D3431A29133E5982EE3100094F7F8646A9182E58AA075F6565D2A3C52E8E95F1FC6B8472939C7EB26ED92C96A7213A3849E81D6CD90566DD3C74ED9A0CC5ABF67D6EF4C1D478A3CE21869D5CE44FE06552C014A9200553E4736250E3E35502CB8CADB7231F7D9D81A5A428B631C2272D0137DF177140B18C0658190C486344EE46A2B1D252736DA159C446A69652DEFAF455AA6AEF32760BCAE23E1DE86C16C77A3CA002CE938E45BD75921E69FFE60D4FBA80A65F50BE7A73670B2F0A050F6476BE5F166812B8183375FCBF3318C8D4C8097F21ECD1651ECECBEE56B4374E08A3D6EE94D244EC2FB685DA13C69F3CB961F0DC18BA1F1B5ADE394109A2D23757D2D704A3481185F30E7D193E463878BF21CF91460A82B4C5DCCAB6FB6491C1E77CC8713B1FB5E6B0F415913F984B717F00D7F5DE88EE310D5D3DAAFDF3BDA8F9C5B710CEEEA2ABA1E7DE3D923AFF883DEB41501A1FAEA0A3D47BE627600BA9D097688C98B8D6379083129B4E85C5475E924BC2D74E8BCC25CA57AF9BFA461302264584C470124AE33E73DFBC2AA1DA875D95458FC641792D0424ABF2CB76BD08CFDD55697331CFBFA16EFD5FD1F1D3F2CBB7A58BBAF23E5C715A637FBC0B6203C25A5516D074DB2C2CB89C9B3E7EE87294017D69CCF28B8CDC76425021C748DADF5953A93AAAD9429AA985C2D3A68455950B9E2542728D3272D25C7952DDE7024DBEAC49BA72760EE4252CBD40F1ECF48AD74CA320656351EF5C22831782BC260B042F9C0E103E501635DDE0CD8947459716658D34C4C8A09781B217EC2201057F9538D0235310209D26789F519FB5E605A21B97092B00B", + "sk": "F9D5C3CFFBAAE5CA0E0E3630C5C68025B3AB7B3ADFA544503FB8C5F64396FF2488BD265D6142AE32C61B844AE63FA741242CFD8502CE79547C31B6B17137F568CC17CE8EE384E104E052F66DE7A8A83C29A85FEE0639608AC3C3B54719460D311C92E32837508EE3DE3240CE74CB83D9C100A6402CF9BBA5B61F6FD4073654A0122990D80870D2B8801C4652898641A0963058346298928419220C600625C132441C0269D3306451226C03171142A465D4844141006DE1486823B3491C873163226A93347010A38121C725C83231A2C04514B72402B56054320244206DDAC44153382189806CD228468C8201D4A88DA1A265CC1848CB085221B485E28409D8A6300B476284340924C549A4062D130870090804C84821943460184204C0946D033232591886E38430C316114844724300664AC0240826250B19410423861CB02C0BC68CDA180609184C5C22455A240201214D402422D8C628E3C449033870D9066D6400301835840CA961112808D4B00564102C91286A60342A02374860A26C1A93089B406148C008E0428002B72401B00011C220A1480243B6405932468CC42061B88C82C610E32680039889D9308D5904010A932C1BC86823A90D24092103384DC8240E213008D92869A3348D9B06509AA004102265C3244C54140104170011050C890641230011C02464D2446E910402034086A116241B9410D242001C874542B824A032001B4626CC480ACA862D4BA68D0AA0500B446480302C1B824CCB882CDA426914B98C09010D5C0408E3268D08C6304994688CC49004306948B43080021002A18153800514354E21302ECBA88C11911004158490048189269092A26C21318D4CB64408B42558A061DC801189B23103A704241548A304480B1786C2C4698A248D1003848108050A054A03228224230DA02880212225034728990260443491C8120580307021372863C871C9082A9218128328610A858C08187181964C58406EA1242448403251326192A0504320900A20810B464DA09201D0247109136D24309009026A51C20508B220A4A66009A97162946519C664D998810CC60824902142100044985090C829124825C116694CC2290C042A9818489948840A41618C30418C921089C06D08326D09A75101224C1432469A9628D1089149284299224C1C452A9B364A14428A58206409A10C5C30460AA6241B032C12432683268051008892208C11C64140328500C99103C4314030091CA171DB080E182830C2A28001333AAE251458DABF79947B70FC6F01786875E7AAF7CD53625A4024C1F56989B53367E1D26C8737FF1BE2692B8EB4CDED688482DA39C89CD4446DA66065AEB1FF70BE9506322BCEDABCEE2939229D70228A665E666DAB61FBD49CF10F658889A910FBB35F9E36EE5A6180CEF522125C01BF577A0E07E15015BA420796791A53FF4FEB50550A562D32E383D05CCAC6CDB346A240EE00FD54236791A61D18AB3844E809C6F17CF7CC78F45E13A26C2A0FCDA30E77A131F02AEAF1A5D4D4A22BA808058A94A307E07D97CE5C627BBA7E10D52C4CE53C0866BBD224807D948676385F0A4717991185A37A4D4EB652B0B922B7B2A814036BAA7F60AC44A072687FD891FBDDE181BCCBAAB95642716347DF66928B37E291FE72BCCF43B6DC9248D51D461FEB43083C5E764FE12B31247F321307A3AE0C70376FA98A0FF6B4E046E28340B5FE9F9CAE7D87DB9634C97C0DB606522142E7FD42EBE2FD81638C84FF498C7C682DA4C49E723C39CD4AAC506A091319DD80C27934FDA672E7DF0370FB399ADF95C8371B05AEEF0835E0AB045845965E050C8CDB8D7A1A07D04E65ACB0EC08CD1C105D327CF2AE2872968456654481C1A9FA954217C6A318D72A43EA22ECE5E765E185BAFE650DD5F2B37CF6007AC9E7D3508D56EB969B9AA637164A6F9CCB02BDBD1F36A2D265A5E880871D5A1A1AC9A4A3ACF23C42495C5607475DD2E12855ADE46B2E82A94BA12CD4ED5F670926F47A4C91D033E58441DB64BD0338CBD623D03A6E95ADE4718A86815B7E078391237B0ADC075F200356A3CAF0A27F6954C6905547583875EEE63BC18E31A855B1338B991EAFC262DF85D6189B11CC44CD46422EDCD9FE939C5C7C67C47492C04A67B1E7BD790AE05AB0A23185616130F49FAC229DB1058DF1BC7E0D24057AA4FDD9CC75D7A1332D0C4ADAD6BB4C781508BA7A86E45B932FCDF39908DACCC208B649A74E110FA9E264856FA9C1458F29036B384A4C66602AB45DF54D630F3AAD3864F1DD1A93C0DEA21CDF6D18F41FB1F7AD7C5069F65ECA5531D0895BC9B336793794034E7F144ED23729F4E88150C3C79740133854D4C5BFD4DE141CCED820AD5E51A9C6A67B5484EC867C289F20ED3BF829CA39DE0E6BD876023625335803E88B02EE9ABE67FAAF4B7699DF3AB028A3B8208AC8603A9A4C915D40D9E968F9EA3EC5742F37AD4A22191B9AC9EBD0435CD571C9E3C9F389960A4225E5EF1B710840E86ECFCB754AA0E43DBAAAF713FCEB82E34C15F8BBAE1B3165FBE5EBB89C6DE51A78CD2D245A7B2120D9F3F399BAE67C601BCF45AB4EFE873F33A25B759EB1D9FE6BAEE9C64AAA65FEEF0931AC0A2BD6CB9C71A58E6DFD46760AA741E8BE8BE0CD00693319A9C8D515DBE5D6C2AF10DE65223D6481B56B8F29E5BB65DA25C6C7DE823700DF2634EE2B3FC862C461044524A64C3CDA3CAB95C06E289DA5A34C305B7469AE106CF6351DF49375814CC1FF5F782DD65B5AECCF0C3DB348F32293CA680912657AD2C4DDC4A68111DEB8CC62B1613A59D3D88B88E41E0FDA6741013C857BEAA61D9B4437D3B9FAD6F4FE3AB0C5EA4FF951C2EE9AC894565A07A27D97BCAAF451AA8D8A9B658850519B492FFC027FE3112B820EDBCF0EB337427A3E4C5D95A178E15BC704F21F5F5AA38A3057F55A7CE0E186A8F5F56009B5EB5753F33F5C7083158C98D797E5A0F907F10EEB2C9A22610538F6725FF158461716048ECECE1F73A098EE82DE3FBB05D17B4AD47C55FAD587880E01EB2C5EC42FB6070113F53AF383316AE2348BAEFC36C6A96BDB7CCF4FAC2B83A364A350C2687C6584886246F6C39C434889D28B694DB5182C353BD1442AE0148C18C9E35297D82E1782E9CF96F4A1CE8467C947B99C95E58A519FD005D7C0A937DEED2E54FCD95F9F56CD3206DDED6CA502F54BE7F27D8B3F192B1C1D1C5CCD7F4EC072C99DD43AE966CB7A192161797E5DB55FAD9555B65FFB9476782F834E3BC7B888841A4AB3A277064FF846B1E525E41F15F424D76907ABD8D69956E38B929DDB378A9A6144EB969745D9034DCB50B98325BA5EF3BEFE8CA06BF3993D80C1EDB8F109BFD30B599D41D74075722B766E8F63AC2B225CF07FDE46CF61031E0FE7699A4D0945D92D096169051BB61A125F37FAD5302D92AF00DED5A7DF80C6444A564F9C04514561C98C062E04A862FABC02772F9278138558E48E66F05A5A5A4FD5C6A08DB584F75C0915C60757E90F16FCD63A542C2BD0201CB71495869D1F01162049A661ECE29EAEB95E6484B430C7ED3301A87435A579F726A5514CE69DC346EDBA1376FB87CEBF0CCFD01504126438F37E29DBCC" + }, + { + "tcId": 24, + "deferred": false, + "seed": "7D80938B0E94C0C67513186B04F7E2A5CD3BBF9F3F47EE074B7FD6F74DB4F857", + "pk": "2A1414FF284FB46FCC0F38A48AE290BE1834688A53E4A841B23B3DCA32172A0CB1B1FA0FCF04EC7FE28F223C26CA4F1DC556B30FD7B206F69F50134AF7123BCA43000234EA3A7065E15880CCDEAA549CF2699E6C1492633AAAFFE4549B382B6C06FA08CBDE376F72C6257D17B0B57007FF5FDBC4012762ECF1E9667ACCA2EBC8DF142E7865861A5F653AB2EF87BA70A2B224A6FA780BCC8BCDC436F5768EB3557E8168445BB17E698B299ACCD8ED2EFBC6BBC83846FD4676CD6FED03593D16D1D482F6CF4D612A839B741873B1C595796A602A9C40A01316C89B5CA167D1CC587DC4772BD5026C5DFF68E8479594948ED931F774DC510C7AA218F2708AB4FFC46BB630C6AC267BAADEC685A6CAEDC27B5E42A4F3BEE7FFBE0DA3CA66B311761BD20BBBB15DB3F012AE57AEC6B2BEC1616FC897C4C22D124C69FF81BE4C275F45422EA12A137E475F1501102B5BE1C3D5F99D2A5730E2F98FCA507D3A91B8D56F3F3FBA7D19C66A7DC9EA93B43C29DA4071F1FFDA2DBDF74B2EF839F26A45F9A6B464DA3833DF5A823171B8809E220E76B96CB4E41DDC6BE7B645EF14A47B39E20D0896BD700BA4DC1411477C90E7C8D83C748022EC87590D946C4CC958B59494AA0D3C401F3DA28B0BEE31505E10B6AEC4C3E2C08AFD49236112F3827BD9BB37B1E94F408B8771525EB2621E04C25E7D26547FE00EBC1E0647FB465737F8776E92B378E2D486C8A3E222799F7017DD8052179E1C19853236D3FD69977C33BABB3A6E7ADC30DCEC686D323BC74E429C8780CFB35FDA7970297A2779C954C66DCF02B332010E90F6B91D1AFA2FBF55AA329CABFEC4141967D0B935A7AD132F845A1003C45855443A17B983B0254EDF514F82A0459AAD1AC5B5040EDBABB0632EC3A5E8EABA1BD7C06840CC63433B9AA5CCBD3293B6DDCAD1309A68D1AF613A59AB039BECDE97774FA0052915EC8689B5A090A6EF353104D9884BB4B7F74A4310D2FB66581E2C00480C6C0F1E923ADC96803FCC9E2C99B79663029573071456119AE65BACBB00EE99E079653BA5B3092DC7E4ACFF720FAAA5D6A9A7101454DCF755C2CC15AF4F256B5E8FEB26C698C29109678FF5A17F9FAF7414B6829C366545710F16E114C680FCE900B050F0F874EB29AD7F365ABF8ED0B1E4D31FAB1062A4787C65D4E0DBFADB04C78DA2F47BAFBA22C7E86B91E7D079BEA7FE69D26913F4742D8BCCBBEDCDDE93E93F5C15F9F260CD92FF8514AF36E111089A579207E0A86FFFC29BAC3B80E944D2054A91D32544636BF7F0110B400D5C13B94FEBEEB052DDA90C1CB8BE5095F1EC21A1DDCBBC5733EB89178DC5C3998C64BFE9E6CBC560CC76BF1783F6E0D018CCEA1B2ACF1D7FDADD44A8D3AC9673826FC168E2C099C144D33CB4A9804771FA8D5D5699AA4345AA6B56DF022D95D2F8A2768AE3EAABE346E0CF1BB1213BB4ABFF96614F524D1CFEA5C60872DCE1D4FDC80A30EAC2C72423DC781358037A9DA9696CDF5E7EA37C038BF44107EF2C22BEB958AE44F34C05A38D69B6CC345C80E743A2CE79805990A02939711E3BD20201EE06FFF039BC38E267AA9840ECDB121F4670AFF83033C1199FBDEA0DA08900C97FE05D0CEC1536EF05CB4C61A6C9ACDE3252F29FE04ABD05E1AE18666DBA373B3F0820C93162CFB209CFEC1362C0053C0964E622BF1F156E9189C54F69A0C5C8749FA9C703B4B7237E8FF5F72AFBC8ABF192B9FDF659E11039ABC816D18F15247820D9852CAEA70041D8DB16C564AEB78405C70E5A3BE4C30327E307B9AD99686F5E52D1834DF9C55529B99EE182D6CE91E7419D1345364FBCA7810EB0E6FCBFEBC10456B67E59DC", + "sk": "2A1414FF284FB46FCC0F38A48AE290BE1834688A53E4A841B23B3DCA32172A0CCBB81FCFC2235A32ED4CA1AEBD96C34D3CCC3A8A919D4E96AF879B3CBD48015CBF7B5C0FE804B106845AC34F7FC8B0FAAD1A6001601397893EC3A94B69A1F50FCCAEA41DB6543C8AA64AE5D312924024B3B826767F2B137E8F24CBBB69370C8311816008804D4C1610C19669624204C44480DA008E90226A8A0089E09231E046315432608C228082C20483280C1A244D8A886059106C1C4410D32652C4B2641C204C9A366523426E0143601A120E0A9588200822E2A49099C251E02450E2C888428888E20631092826498661DC184924428501889190488D0A256D50A641DC1425D4C6200A328E4408860B1965DC32681AC94143846D1395840C992193468A19B8415C3644D0284818A27001953014888509C60924484011308C1306229800110C037202954501A0410B392458269018A785DC4290210271CA1488610461C4882D00A31104B085E4220E9936469906010133305AB690C484510AC249983242E3C844A4028D0A174A998271181532118708D23664D0284A444691E1164502B069091106DC3481430030230485000304929080DB360AA2B63103886D2480640C4901221668A126488006219C30099148255BC26959484163066E8A162D9CC89122892D53C280429021422084DA008AC3324EC9162C1015715B92689444000C858CC996800C014161C00C5C841022B3496120092385059B949189462022C9048326318CC6290C99659A225101C66D420490D43460122382499449484610A1C22104824401114AC8068C5A948CD2B82CA1066012406959084D5C402E440425129665A42432990241D41820C4C62940342900036802126D91105260826DC84052D3400A59088852B0059AC060C226400A244920188008C40CCAC49163448218B5409B484951960C8C02901818325B024D9C4602D3B68014070ED1A86962408001274413362DE32650034046542290104364E21451443880CB266D1CA80421838C4B980959204C221921C4A268DB186501C85011279220B6200417418BC46C1A318D43A29108204021178612328A5AC8245180284B38719A408ACA30260819899A3666431664C34004C03070131788C2302DA3167282A6642238042013624C005049C88C62A4451146001C43825A9408A0C08111312891402C24092EC130910434214C286E8BB420041426114286C38889D4C82C4310022031655244454996690908423D4E7D0670BFAEB283C64B53E45D84F5A6AB4E596A7EFAB48F63982D92C41D5EB16136FB78EAF16E178A675BCF7366B38F61A0DE5488F28DC1628CE97F92474ED0A5220C092CAF7148574459269B09CF4DD51CEA4D47FC967934FF9E72046C247D3384BD0A1EDBDB2E9F500BD26DCC814EA2E662EBAC54276517FDAB8143E49DA25270791185F4C58D7930D56E24DE452EC09D2F702C4258C9D092B014C502009A5C9BA06047D4E1055BFEFD31CF8B48526C2415E9B7AAAE5C109448B1F3B9F778CD3E081864F885496C53D4BC9D89DC61C96AC0992B93F996E1E2B3CBD19BBBA7EE4C62D57EA8C67366D62671B8BACE3F8A5E5E0F6935B001DBFEC4C8395160F38FF99F19E5C73B10CD485A365E873B17987361AC9FA1A980A05E16780BA4CC72B031881A13AA3A2737465D17E28B7E7F78AF30E19D7C361755AE31F78B49478D24CA1220693D559380283D34F16C9003825E07A55EA050A72CE5576B9EA862507F556EEBB2F3C3EB6D37CA24411D8A0E041E1FEDF68B5A9F4754C42087A537C6ECC180D394EFBE4D68AE746B60F69C23E116AD1E53AA1402671ADDBE531D58F65C862659CCC7519160753E89FE0D8CD13965946AEB680ABC153EFC40786381202E7A2F9FD03A8FC83879C1DD11C7A36A40F9D887FE2EDEE83F345373C88EF751365C143AD427E517773CD69B035565B3BE7BE9C39192ACE33DACAD81A30B819C73E828D49CC025C7603A829F306405B87961AAB64AC270A027DD8C2AEE328B6C9B8343AC25BBEBFFE625ABDADFBEDD4693CE2B511D75AD5B67E02D9695C08F2E4473E1DB01D7B2FD3DD3E38E28AAAD3837C6DB3DE1D6D0C1A511B48A0FBCFE01F1739B7B54C50FE12D7860B1E6F12A30A126B6656625482C5395D682D087459DC1310A9E3830A22859E685B24A6F57E1DBC60C9E0B8C27AE92B39BE9ED4F4B6E6887ECE3116EB131AA7C5CEE57BD56C767AE88C78F921CB8424AC4F94762804E0E965B4A3512CB36524A3ABAF8C1AFF95B278A717AD31A85431C25DCECC6FF65E1F42816EFB5E773F5562082FFEA46C367527FC10B591C355AF9D9F29A41732B9206A2873BD551EA04E7EA00E36341EC942395A5FD7293C40A03C144250EEB20746D19BFCA7B2AA30283AC3BDF41ED84B3320B3E1B398F4FB669F6EC7E679B56FC7885E7D69D32D0FABEC6F24BEDFB9FD4A7FD90804ADD519FBE3771765F09D10E273D0FB43197A3215D8EDFDF6605FE0FC3597C7732B0A85AEC400CDF03D2919DAC7905BFCFB4294F682B28FD89921827ECC7FA0A3AAA2DBDBF7B447353329765C85F4FF169F7D661E05BBC151A50819C6A0A01BA09EE1D4580C0F5B06D352961F92D01D242CC33E0ABCC2958C6794A5A49B92AD4E0AC54F0C2CDAC09B8F06C2478F1DD506FD15A29779693F722A368F74A8880577A1470B7DAF91B8072097A8100B6A987F5C6C303810376B4382AAC2DBC29AA0E751F82DCBC88A71052B3E4A3C8DB44B7BAF2AAC864D801F5712F7E26B0BF07F7B8D4E76D4F43B113BEB5A7044BBDD6CA3D8900364E9A5848566A033355DC36C03A06731F58F3B1B5CAB7C80A31ED4730AE4607098092C21E4DEFA2F549988D45235738803DFAF6C58464DA5B6F951E4E28EB2C5CAC890393631A51872E1E741AE1B8E0B2B729A2A7B09BFBF38834A28CA33346A1C74A401A266CDB64BA1460BBF539AA37F3B49FFA35B796C3AFF079CD7533D92B4DF10331D9E37EB29B13134675BF4624D511FFAF336EE40192B8C181A221699E7DDD1E4E8751808831EA49D1FD827C85B2929D6CC8043D5ED9A3D51CD01DEBDEAD39CECF204EF7F946625250BC45C51DF7130598CDC501C3F96C44AFCF1CCD9A21FAF7EEEE6857D320064C64AB318BF2F652340CC5965D1FD19689E0FD5B973CA88A728F7F65876DE19EC5DA17B12D93567838ACDB25724EEA33464C16B164AF4ED4A7CCFBD5BDF2E2B09435553D85981790797AB8F28A250DA12094A3855D6F0582557D102EE5C12D26D78630EE9494815E1AB766E991C67BBBFBD8230F98E4D94828DE2B071E5CB3FD97950448B845C00821E8F7266B429E9CC28958452FED371B8A1BB86D873B54D8C4771F1C671D5BA0689C1F02E51830276A2010FA34BB12EAEC927ED01E815A83109F5E325C0B71A539835393CF8CDD3FB1E7544748F87A0266EA56D8EC96D2F08D7CB51C930600A9CA7550879EEBECAD44BE65FB99C550887C4D338B5E465C89DA83BE02052F151FEE499CCFDC313A98DBFCEDAA1D3843F3F54A29CCD57802032DAEF35FB318F592C08397FBC2F8C94E1616676FA17D3A544AFE1B5260C04BFEF15C8A22F8CFD77CC26A483E" + }, + { + "tcId": 25, + "deferred": false, + "seed": "CD52A8ED3FCAF1F0D0DFB7394D3ADF9DF810203199E62356E56B7217F786B29B", + "pk": "8F02456FA5266891FD000117992C1F8E6ED9A3415B7A48A478858302C379C4DE3A3B33F4715C1B228160A25FFFC7E5F451D166EE93D7AF6F3646B50E0E87196E352A22566DA11E9479B50B05343E202D4A8117AEAC5D7126A1E60D20EF0C3119562594EDB8B3AC853F995C64C84F965B415CC57E39310CFE8A2129BA5EA09765A5790F92B7AFF0B1BD92DCA72E224F034B5023787C183AF0947F33F57E4BD856B94B223136DB7F29104C39DDCBD3761414C9D7088301DC30080E68D02444C7D249545A2F2E89A01F7282B1885F658D3AC6D075ED83D43341B7921D3CFCB0F8BBDE671788451ED02E0147221637311AF653D9266BC8F653CEE8775711ABD0691978B298D2F972376A270E969B97538C379E4AE9B920876EFD22548F13917E524211F32AC670EEE163498D18A5CEE0373645F926321D8BF4BB75A05FCEC36613C15BD9BDB332561994492E5584A5050240665E5CB9E3F2E34D39047F30E15D63D99F084F7E04C0297C37C0C5FB93557298FEAD1F1D64AE73A4118DF853807BA43D94471BE77C8BAD8A08A1E4E206C5311CBD87FD763D07229137C961F6E05F3224686F1E468F124B74041CEF75D0818BE1B9C3E5EE11385225D2F4844A33F4E9388E477CB583E2745DAA1EE7FF4E4D32D8DAAAA90D8F6C37B293926B73FDA2B850DA5809B94E265572F5EBD38F0829A7A32D3A35AA7824AE0B513B25B27DF4311B09998816534C1C2131B90A7189A7A65EB50BBCC6DB352999C1785BB713D901F214C0B4DD6DF7867C7994FC7BD3BD71CC4BB64307B30A79B176C386EDD40C0DCA724CCF51B5042D0DC046DFA81205BF2AA6832E8CE56D6A8BB50078D04F234C3535DEF4E08ADAE1C35E25A8BB51A22509FE412662E3F28122FB7EC5AF8C400C4541CA8E532D8A83F295E3BFD12DD8D954EE47DEFBB5CF2ED53629D532A405D25F4E32F8678AEC96DA81ED79027CCDE34FA4514BEFA6E58F9498DC9FA7B7A091CA69587E4D250271D39013FD8F25CEA402C34E7FD5A2DA47B232D85455C12F7526E0B2B6CFDE7EE245BA9C402965D042C49807D5BCB2EE0E616CD66B7E189324532C2C4E1D3A9366C08F44EC8A63E7C535DE0D7AD5B1DF77E7028EFDCDF6EC2B5D2042F0BC62564F71BFEEF3FFCB21EDBCD64F6D3FE805002F0A4DEE90B7D81085C28D762B7DF72018C70E6C4E7E46C64AC984FB4A18D318BC275D3D145230C78C5DE27AE20A75678C184E051624C64765445016C8637D8E11A21E8062226AB9994F0036F5C658AFE744081EA051EEE6B3F25AF1ACE9F6461A3ED133213F341E58A2CAA3F3165872A961533F7906B967B85B79C24BA5152CE9AA1EE710B58B510E89BA860F6653BD307A2E169BC83C556C978DC420FD5A303D3939AD5C76B2311FB4D689AF7AF7704773CFEC0112462A44BA31BAACA36319C5092FD9262D36721846BD9E1C5F4F6540AF165843ADE58DB3498F65BE4C5849AF5867B8F60B54D8ED92176FE82AE83439C874C06A8DD487AF54673F1B97F44420821DE6761E02B6E2BA79DDE743722ADF634D7EFCDE5D5931C1E255293D64C4B3DAAFC420D28819E9ADF7617B6FCCC3AF3EE5F0BB765194A6E4E73182A8422E25C28458063A5E0625595C95D4DAEF94A98848E5042CF6EC7448D81956FB91FAF6EBE7C2040B9C509F6CB7AD5B573ECF184BA92C06D4DA0F68F564EC4DBCC029B08517F233FB6EADD7C0B06AC7E7E6C4287DD26837E65ADB668A30F69DFB15D50B4EB7324071EA9664954A23E94B6D0D2759B78941ADFA1786188A1D23104303199AF735F3508DB1A59070966F0694025C4F72306AB813E925C658CE8358609E119850B16390490EB1", + "sk": "8F02456FA5266891FD000117992C1F8E6ED9A3415B7A48A478858302C379C4DEDB8B14F36094926DAE586A7D31F7EBDAC45D7BA30C05C997B1C7F16E327E30FE4ACD9CB1F9621B83991AC2847F9BEE656DA1E6E2DE20E3E14BA58B032FF45A6B5DBF1C515C9A36F13638CC94C7F2B7850F2C95101CED9F0D267BCCF4469CC95EE12812C2C261D1324290B2280C341009204DE2281180922C8246040A148994324944C02D52A824E3A071201248DAA02801A14993968C0C460D591421632031E432480C15500CC34414C588DBA83053C411DBB600C3C82541128DD0362664385143A42580060A0045311AC90018080840B444823260CC84091204450B88651C4644D4180D20414CE3902180104C0AA88108868461B06918347219354112A948C2128159402D9B9841123430103984E1069018446AA22229CC2680A2106102420E81462A41189263248010A809140442D8802001A10942140462342240A891128209C488718C966C1188244A34851A38510BA104432429E01670801490CAA4455C440104318E98C0851B8305C0B848032491DBC44944148613444104B96423394C98146E1044291A0029C2205000B540D9866599460E93240DD8120E213250434460213030508229CB1609C30021813201CB446113A5889922725992600394500BA02890100ADC321081A2414CB6618226618B0241E32652C8265018308E0CC96C1B03041918495A183119B389D2066A99280E08264143C809A2344D002705DB088990884404372DA3B44D0C89419CA41063064513B07009342C53A28D81B2911A81284C181261387223C14CC034520A406092182014064E84220D0C142852B8850829898C3625A21881489449D23246D2006D19C88014498A1C4146A138251185859B424D12032999284923971154208223420A40B4608B8028141889E2088CC1B64523A1312038011399899C28204928701101481A49254A24810C8164D2983023016E49A61008A18C1BA3691009001C206A19313020B66110302D0C860D81429008058A24A40110C529E00251C386405B4461D0A40D02B288E3B88540C05159020EA4389009284C14998C83200102374800434D51B2241B022904C248118688082128611480002421C89068141126D8A44C114720A3328A4200920C1148CB40848A86708CC48114280953C26C04284CC9222E1C4044E4B81020064008364ACA4841C9029220428DA3306A22112A43A890C3B24C01426E1341690286642338086D493E042528BE94F6031DB0767E76297C47022819855114386CF4DB2FDE01D20A02BF72D6FD241E69D4E2CDC853ADEB7E3BE0579C7935A49799A2F470375C9C1032A5BAFBB23E6C3B578A0A0568185C073D1A786846C547F3D229BD6B6627A9D0937E8D5C16E661F0F57160AB89CEB89956E67938AF286EAD65B398D3184E41613F1FAAE14703ADA37E76FF5EFCA5BF5FD13564ED42E4FA6890B15D13CA9514CDF1AF816E63E28E4604E500CC55EFBC01512B9CD3D0529FCB80E17D3ADB8D61A2045B44EBD82B4EDFAD53281B3C43A22B2C2B48675AB94656ACB842EC18A45892B7E9E7C88A641218CA9D59633C451B45C561A838CED0BE3B683225C03BD1A8BF3E3551B2E1EC4F0E8CE6B019339A3F3F8FB8513F4AC9AFB2D09FF438160E786F28F6521AACDB1EEFF18303D711B9CD1BBDE1AB39FEEC90C97B39234A9A01F8D83DF69718AEA9C4BF308EA01ECA7175021919D1C9F9170EA25DF51C5175E0E3254E0722CDAEBC4C0A8D39A00497FFB2BA4EE08CD6C032657AFC914176D3C22B55EEDBDC83830522915D2F2F6D0C5067F25248623D8E359570E0410E071ED54E17E366DB5409B62B567BFD267669DDC532BB70A53D27F4FFAFF51A27F8836C744AC96CE0D0EA469DDFEDC360A8D53CDFA474B7B64A5691B245647B843190FF3CEEA9E8FCC8ADDB4DF38E45E0C1F6E1BE1479517E31FAAFF8AA745C90F75C3E36EC728EE82CECD125A05265D4DBA8EFF9CCABA4C38E8AE02F1B7C4F784A6360BBA4715408BB6B8B44964DBC692594395E386F23F717A1DF7F4CF9CF1B5B3992DBE21CEF3152BBE1DD77B60AD7AC235A1CF24132461E7AA1D72586881043501F52FA8CCC4F0D6A1814B789876185BE2FE5F067E62D93343F8EC977937D1E100E48C21FD60080A568E8F6D954B98D8E9D8754517C79DF0AF61BB09426FEC169F1C4A8418EF53E343EF9C410078A395AB98252BB5A3CDDB79AE26BF92B1AF47EDA3FADA7D422ACBCE2EB4A40BE6FD1A5BC2C1D90A0F0F9F09BD5358685FBB5ECF7189E4DD9B427EC152C4B1A2C0D4A33131CD0326EE8A1A884F910869BD60571EBFB7214546C015444998396EE4C216C99CB7E84278582D0029E499791DC03829AD2990132B24F8EDADEE09B38B4D3701EF228FBAABF19B5744E47AC933ECAD85BAC10B49F6BA0A1B16821CE8C5791978AB14B1B0C2FD3E44B43F3DB49A5B63DC1D16D74E94FF111088F3BEFABEAF1CB5D1BD86147CAB37B068F6D99C5E86D178D6A860586FF97ECAE105D1103C0FB6A860CD17D6DEDE0B02AA943536A5EAE551D5AAAEFB4FA950118998C8080121F4B411ED3C29ED90197643DAB10BC1BD51B2350ABD71132FD23A64158DF8F9E064E6642A2DD76313D477DF17F1923FD394F95199AFE19423091183DF668666BABA8334312B670D240D5EF0D1B3A8A197539A3C5FE7F16B88C7911ED0FB35F48FED2A8DE84F4E75F6116849362C05B2F03A885C1A3838C78714FD37E3A0625FDA5C0D5D77E4FDABF3EE38BA993326E3505657A160FE8287B8CEE808687FF15B897CFAE347584515E2D78932740C82FBF42214E34BFE29DDD842CE89E1E775769A302B84FD839D68F595BE46A30F7AB09F35A5B8AEB43428C1453F71DC01A0C202E092F125ECBD2E9BAB434675E7CC21073530FE1FB63FD48BCE72A017DCE1856E26F33B040B16CFC2ACA88E3D0EF89BC9CA83E1CE78431BD6FF547866A9DE18E12C5E82C3DB4603D43318CF9A0AF5C10983097CD7F5005576F5BDDCD9F3E828636CF898CF54916AFB4B787B199FBA2454D9B57BF7C92341D2690F799DD3DCA7E5A9DF3317B51C8D503007EC5A234748E8AB670E6D9A2D98A53FE26FA6A653CC373BFAFAD1015AEA7CB952692443BF04AFAE3CBF6FD9DA5190BBE02D3AAE57FA0D986FE596E0F72F4E04CA7D7C508778C7FE7F8E3D2117D1ACA8304D99D3C404692591BFB48519A8F7F74F583BC11400A1B40D8E7441CC7DA6669909A79760A1E381FB6838A81460F4493E0769779D38287AE5BCA0834FBD21D7C1AFC421901A05550D8524B37745FABFADEFF0B6B3E5B342E975077A4B8F11FA1F60A22C6A59A61443FEF3B17BACFDD29AD2E6D3A8563E6BD8F33B9B041BED520DA17844BB4AFE9EECA45464D931013ED46B428C0ED5E705DCA043345BEE4612E7E9EA1C82FA41D9732A40DE8630250FB578312B546366E64739CE06B9C7A56FE76620D3A295F66B5CA2C378B54D2F2FDC9D57A5AAB3EAF2EDE57A76033670BF5D96BCCA0A4D0D4EA27F1290A316039B57231570B3504D3C4381BF89C15E2E74005F6D643D7BCD9B9D8250D9DCFE470292B36F37DD077853B5266" + } + ] + }, + { + "tgId": 2, + "testType": "AFT", + "parameterSet": "ML-DSA-65", + "tests": [ + { + "tcId": 26, + "deferred": false, + "seed": "70CEFB9AED5B68E018B079DA8284B9D5CAD5499ED9C265FF73588005D85C225C", + "pk": "D2FD03F3A1B7F635AF9F34D580A98F524C735BD5BA2355DC6E035BD21765580CBB111923F194A7CC8A7BB2EBC5C0E71AA637CC800E6103B850A539B2A39E1B6D713E5DB8314C9AE1F8BF8A38F06AFB9D73B161B0FFE3A4891706AE26D54FFB496DF8DC0F1983509500C9ABBD28E59B3FCDABBDADABD45EC31499378BDE849E7C1F19B7044D67E05106D7136D95380D5605D4465D877557065DF0A75D3C28542F40FEED42EC7E280637B083D988BCA5F6394E02396C4676184FB63318DAFAF5BBDDE00E308FE84019C2340A3F3E1C0865624970711283356AE14BD6B94D1C9AE188DE1A8A2CA824A8EAE2FE6AFB38D83A2D99996AB21FE3E84C0BE6B6DA08879B677374FA7C691B13D40FA9D4CC26B2288D5A8C9A43724381004D61B0D57FF400314C8E30EE796AF10F7EE21BF13D08180465ABC72EDDB080C6A07184E3EEDC47C19AA7F09D1F3309E183A2BD9B0573DDE474A81BA4F78D0C523D0C04F90060FD571A35C037E079C5E210D7390DF568F2E2F03CE44420C82F3FE69EB9B48EE90962D6B0F24440648F71EDB241EE6566FC1A64CABF66BE6FECBCB1387C82A7BC202D9E367998E2A291AF0CD1570677FE8D63A3285A2EA6EB29AF9DC1AEC1C36C4706B12BAA20839692F286A6E0321468F7479345C4D52FBDB2F06725B554B89E2492612681ACEBC6C7BADA9225818DBC35D64C22C48BFF80A730D0716DFAC99DFD5B8992611D0C93EE90BDB260022AFE25D913E06EFFB59CB1F8A60CBFA5AB2F459A16F467E989525E0A37EBE56E833FDE55DB9D1530ADCF45846DF281E47CAA1E0A27EFDE2107D354CEA0F6A454692F04CD838EBDD46E191E5D9C11839A2C3F488A4FC7CD265A7B5D32B08CBDBFAB9D2CCD76222C8EE37DDCBD2AA063ED861473A6454CAEA377850B1A2B9DDBBCB374FAB5B12F351C8E5888872E5CD1F60A4FAE1FF837D192C22BEB41EE6FA392FCDF4550FF46B5CE906D017EF3077DF132300D8BBFA9BB03C75E79E2F04C284AD06A44399649C3E2A2A8D1EFE9B7A4E0C271047AB75908BFF7DF9E30ECA547745BAE23A86FF9A8B58C2538B88B866401076902DC5F0BD761687B49EAFE36D350CBEDFDD36C121CF23786BFCF7E47076496EAB6BBDA774049C2EBABE2DE99C4C24F2DB73684015B373977496760CF9AC23D8B623133DB2DE10D73FA6AD1C6DAC8434F28C6E251CE7293CFF3F3B61EFCB5A435123670F29846A13DF3EE712604461F1BAB8F4EBC836DE058978AE734396A98081B35CC98188A86949C99270D4709854C5B35B17F48A373134C814CC8A0F3E2FA807F2A918530907864778282D75E03A41B2504EED816A417A3AC6BA16080C39B7310192002A728F7F20395009A9E16767CE1971F5DE7D229A50613369E4382045A8E81901F4DBA8102F3D413FE35B326A874F233B719A7137600D35D33AEB6B7259624083AA968730C8F78292AD28F14EEABE660835984FE69EF23DEC8C327C0EB0B882D587E1EC433DA85C9FD1E0A34994DEA240C854452D18C30F496E49EC904B602E0F5062EDCDA03280A53B4313574CC2C0D5471BC9613BDFD6641F5BD127BAB5B5EB3D499A33114048220E819F8EE12CA922C8F17D9C9F51AD5BD6883B10E6AA2483BA49DC547DA7686151344F4E9099B38E430B5226B059832CF03DB48FB02DBA4E61593DC4576360491890E53EC0E6AC73CF32B25D823B38456E286505A541E5AEEE96B1914F5F76687CE2B0160227ABED77993594BCD831366206D75714082F1C46F1F4439AC81A57AF31C81C555307A070FFA94E0479B784BBD88A60CD4C7CFD94E6AFE02F6B21F72AF0DCD6609D40C965C14E5F2389183E53DE930F7DE1D44215CF49144844E8B87F78A7F132AEFE22BE80B4E3A05EE3A68CCF609EF44047402E4493046E6F9C767FF8A75E28B3CE077FDE7E7EED313B5BF7E460127CA8182E9BC794C0DFA730FB920080575A751B5CAEC85A109B4422BA266743F0D032BDA8F1CA6248CDB917530DF1302A5F8C18DC642D52478C98C12A3F16EF2B62B4F59EA1BB58DE7B65B3C7153CE6DA5E4950746F80E087A0E3586D097791BF36DEF865D68591D39D0903773EEA962147F34704138B54DF7924CDD8C333DB5E1A409CCB2B34E2C3C8C7FDD3FD8D012CBF382AAA85E83A12F235A2D147D035B7B28B34B6F57949F322482A7D4D3B15045C420D5ADDC7F0E69B4DC1CBA58B01D872480B06A260D827D891B13C4C5CA50C748DE3C771BE61E9AA170165CB01F4BF5DA27A7791D3AD3F6267B4CB4E61B28FA1708418D932DFC4161880C5D3B17A9663A9061FA8F1804315850FE4E7306C882B38227E867F80872CDC1944D472615EA4900EF7D270B881D4130F56C5CC980D92A47ADA6657EB6F37A385D2D8CC993E1442EB05281853636991E34AADC68954D04E7ADEF76BF880F059B0CBB55D915A4B123E2F1339A073CBFBC409BEFF6400AE096D5AE18EC42CFFAD5B4980FA35BF03413ADB5D7E6876AC355D1C9ED70CA2B973954D12B3CDD76AC6835DB96003ED8C4E288B71FD77DBAA7635720E12AE0A317DE808C664E317F55275791F3245CA4FE5D4D41077FC150A6E403D5A208E46EADBE8F2CFB8AF472F4A0CEAC015219478E6B86C958CF86525B7485C1734C7EF00E90683FFF5DBD0A7D413A855021026A1B32013A4616CBCD3700ACBC705BE3EFBA625C69A025267BCE9D135E3F5B5CC8C43956407E84B6663103E29C242035551AE797F56C6374BE0C798C0CF398F1ED", + "sk": "D2FD03F3A1B7F635AF9F34D580A98F524C735BD5BA2355DC6E035BD21765580CE38D1C14F6467C35A9F380D27DE61F7C75031569EA2EC8260EEE9105261B7FE160C91344B0C6764C204E5B8D424650BEC06B9E2E625AF07E23F4950CA24FB4D6EC2C8B3A717C9311EB87279FE25E311F48B8256501F6463412B50DBC89A869BA2241112648400738730212442544575483725033356258423201621183610245665648356120845260685045655512724747212125402221428117650306426152134325243382121135623332074786223150837084264345645148311486246686743371366726014707721161588558387183806701657870647785600288534846622583548804744012574371077544387121142208887223588746148553716773822822741403577328718380781434875207647401607561060861322146156542670820841073130361028650452612166833552584735354526517106000385777812426804146432667410603554128333725230677821516317300087526584634638808846451112405321011181864782241003855754210468343733880078343787413576232688065864853483551585074460588700772013100875488142084166115605685115808058863018286131417220168171786585310622852822615043142885431780580115045688233663636406515244767064536422686750635413347851217808387655142313887566205174085281417213812608124414575018287101002132557042172427861117005304772132030216744315771455710541665741524024371512055116783678252533566424613702232740007068187175780286801721004275522864253158176308640831143305382735303723568704541157314123164326663562151508210302338172127102314227577283771627506887214187313030150715862866288868603270146172271385381703388681378810486573016523140830756821032312850065081630675766511601417121255564811411328826207476424482324775326081758115637483551478685666681732021367522746683445700666477204722285687124702480702542301257137367536005268153335820613732408717615224260185343116457761761566876606554781033631421832160155580423842031312343625273082812547513544126735001001838574424013036127812626811887435120627127515610222281118141666638208675561240065461127440345858781007852572885722222550840041260836462878467805022820771360751443687864313877737355412700540708286880045383432281006435486766501775761275438162403343453887216614704841431466587845820225457315213203024880801371255432720568652468040616835054533737272220680825508472867422361680075518121784448115645071105815511010471621075861187800527264521743234076486730776364875131638468745363842354661048363385214842038251103357468016433402070353221275733465833387438517503660880258758088316360182132261568741110331413053416726535501334808710264868845271442358803557705484287055888683862521827261177885176773005771117851106563570287401340012653451205467518807033356622620070232687726311133333814170622861514731302546511761580741613737061400548877756777665316726666887643583104875706764700436358605203442736486123721610624208608323540355557300610365342714158662558016531018261135468246132583477050060156021168545303687336418886334252015833423288568177555148481201581385041471835707545554552827313602123268321382587028585344867273428418220883610214161712415748852510260736761266172132360325411011226660161632642605186351585131425384566627833354507646508025434157357825430282384745701567517747803152750000947BCA93C27D584E2C66EAC9C7640C1CA217EEF66DABBCB260B4C34300FA051357820F57392544982FD11057DE233E6D2DD84972A7E47D4DBA99BC30CF8F2AD5A2C0243195ED2730FFA92D227D153095972D4B3447FFAC45A23EB41CBC87CDD1250A8A478B0F7A1D5B39AA2206E48645584FE7BF7A13168F482765E57BB924AC6D9A11369F4A6AFFCD169B7D75129B35D5134A31761BB8355AEEED27E201A06313013E307A01A73AEA7955C0578C8C5E5A1A2D2FA4593FACD904C62040BDB9F329933536BF8D81C4256BAAE8723FD4DC66BB5E7F9CA49031A193ECECBB5DC390EC6D5513C79A052B3FD43612FB7375315D8091F79BAB1318F17854561BC93AE0E5CD6D131E562C8114810C939AE563AA10B47CE4484317F34ABD02D0CCAD58DD29BCF657BBD9254B01CA9726091938ED32054B37DD617240F4434C1A4A8711AA3A399A8A5388330B7059ECCBB6B1B9CF7187ADF10B0C9171D3C0F6E2D460A419247672E3B9FEA2C95910BF2FB6A5D61F257453B07AFB64B0BA2758BCD735751F2D53515E236FE8A5B4393B80BF06DF97BDC6380087E6AA8DDE6E098111A7343FCDD1E903708E637EBF28323CDA6B9405810EDCFB3691149ECF224C50F8DF92A94AA4770A0E91466194BB0E27BF1CABF16ADFD351220033F76F5925557BCF9634E9461359621D80B4BBAD7E2A6E432DC43B126CA42AB88AA88F0A84AF58029C99A0248F0C454071F35B831FED1254D6F4E2720485786215F7C7F0C4ED15FA853CD3AA07259B39240A82135C2923A72B876FABB3F0F2C09613DE39D459A07C14E7BA437D8041491FCEC1433404BAD1DA9EE9471E17CB691B2A353710C9FFA4E5178112027764EB7DE809C3E1F1FA4178A5D4DC9EE27857EFF26B91711FC144D5A775B8B50D5DB939BA3207680C242FC821947F934C8DAEE203563D28606BE624A32901932DAE85712AF6C8016026927E9B8129574BE3CB1E95332B052707AC8AA8F435E88B7E568D4987C6AC0E902B0609A02D91B3F5FD3FD901DDD0DB9873BD7C71ED921D4577A78C4FCC9BF075203D38F5E76E74F277484E057B6189004131B0C9B1A155294D1CD3D5208E266901D7D314FACCE7E2AA584583A11E4D7C21B94A32E508EDDBBD7A65AA86B4FDFA6BC285D4CFF53926C7173FBE1F89CC303234B878C6B8101F58AC8D3E5E1BF5AB6B26297CC97B95954AABDB25BE008A3F47E56487B00D3DEDA890D92C83957FEAC6B8291AF65959E1D1FCA3BD196E9FC9E67E0607094822E5B4191DB96824B9F03F2EF57F5238BA7E1E84ED55B7DFF3D6C2C1273692A9A19272166130DB89FC67DC94DB614E3E82BA3A3512B012D51FB486B5A3150B78E724E2A12DE07D8671FBA2DA7FD5D147208FC3AF653E6520FC40871AF2177E65CBD0EAF304217B367A665F224CAEDFE93006AC1E14BCD67A88D171F3D8F3E358A71926BA3E5C239A531263EC9437BF2A033B8B55B2C0CB6E7E97316E22DF77CAD910D20EECE1C50910A5CC32ADAB09377550F92D5BB1F4C07F4A2822338E2CFF5348DF77CF8EF8E6657DED1E0CE058E3CCFBF39B3F166E303D33C3556C9AC8ECB3DF7C74AB36D0F2794441BA9808827B578FB5C29E494E21539AD3AB2B41BF161D7F69589D4524C54C89B486F75D252F541CC63B9E706D64A1289A2306C595363CB6FBEF0A1B5B17AB5B1794BF27036F64EAF0BD430DD58D80010CCDADA4A5A3A1E41A6FBF129D73779A37AE5C8D6841A9993C51E364E04FAC8E25A4E6872F6C860FA265C1C4426AD9C21D26DA8C278546ADCD831F2B8B26D4E1F670623D95C8362DA662D1FF0AB687503F328DE095810EDE12B49EAD1533519558C1E940B46E4EDB027BE9DA2039B25DCF7357E19E5416AE268C14FB3A8BABCB3D23F70CC9D59681C5D833AC22E653D86E22CE822540755D8D243C15213D076C6B26436DDC07C7E001347B0CB8783DFEFEDF275FEC4792686734007F0FF8540811C2AFE6CA151420532FA5526A1074C3D789F2932DE42E3ACFBF94760F426D96CF033FA49E2F458F9A9C2E71DACFE009DD9C3F3C8AB3282D6F383B981C82D6364F0E4BDB2AF6A95BA61F474150CAD7233F8903DF972DBB0328C0CB9D0CCBEF883D2E6ADD180ECA1B662FC1D2DBBDDB3634219E1EFF38B1E52875356C03EADE942055F483504BBBCB4302A417CF6D328ED793B1A3C0969B7B3418F50AB39F83C5666C90E38356F7F9D494A6DCB63D67C34E3D14A4E15596497926C8568D8EC3DBD9C2E82C385BCFB8D9674863BD4FBF1757DB447BF804AE950147C91FBF9AA17891044CCAA73B45528597462CED751D015EBBA9E2B7CDCBE6DC05AA9EAE0C86848A3475BB1C5744F5903EE4A842A469CC181271F245AD70D02A4837863B296B4ADB4E8D03D82B64AA11DD31CDF21EDF1DFE3276C4DBC877E35B15FB2835EC3A1C453168A38CA8E563CF3E9A00736CD5CFBD2841D10F94AD55799C2927E5461B28BAC5174D0CE3F8F7CD7609FBC8DA0C38CC21695CEDAD12F8D2E64951A8996E510D6D52797C5BA0EB4AFA6BF2CC43DA09DE3179E899BD7188B32A98A499D372F3707CED479B0981CB50C0C0539CF7E3100B720E466652A4F499C2BA3A17F5232268730B962BC572C0DE96E8C9E28F7E3532C2224196AA9E27688DD050D7CB7854FB3C35F9C62EFB10DA84833F29BB1BE5EF3B533638EEF743D8119DDC290BDF08B6F0F9E4E1E13446C53ED69805DA26908A15DF1C48E009EC1253BD5A5898EBB5121CC24904C8B10E24E680E565985076FDA11D13FFDFA4DB28AC9F0AEA2F81FD7ED4DCA8D3B2E3848B4D6046F6E0DE3A4F683F25E0605E84B36F483C404EF899CB3FCCBE8CB2A6F0A7E10B1948CD4F93F181555F661D31D426808BBF9F66FD60D649269CA3FE991B22428C37AD2A08680F747CC0360CCD373DC6A9F43A66470E014E72B3D8C38E020442D8AAB974E6049374145B04CB7F3044AAC1EFDAB2A18BB464D4F2F2D8143974C95EEE856D59EC00288ED43FF5CC8803006C995514A2CC9CA622B61BCD75EC51C202A917105B4A4BED1B80146831DCED07EFD2ED25739F54096911B150D3077CCD731A0361682725D53803F8FCEAA83919291EDB4493EC84CCE1D0F82A679236EAD1002AE8018CAC9FDBD246FF093D803C0DE3326A57907B0DD6B01D081458C75728C600829928890A56AAAFEFCF7423B70A6D86B415B8358DD044ABEE00B9C9795FC8F61A64686DF5F876A8F33061599AE830F7EB4C4BFF875F4A936C403C5D160DE5D33CAEE40FB718DDA4478AC6F51C59C2155254BD77671118411E2609D000306FC9507004A31E8957EA40C2564B83C3ABB71A87C11BD18D7891C449DBBE79B4A4FB048307CE0E812B2C68ECAB77FD1111526AB0817306CEBCB0497C552431CE15E4AB52283F679480D69DDDE1F2579CFDBE0BCA95FC5B2DB0C5CC76A31950F5116AAE5F02D46710E4257A75FDEDF2F47CE37C203E7F24D3C9179713C5D807C296149A75CCB444F0C6F6ABDD2DBB2985FE267482858A1E" + }, + { + "tcId": 27, + "deferred": false, + "seed": "4B4B71C5A1BC1074F2167A1D68729CDB9E16ABA3651FF02A0A0F4C883CAAC827", + "pk": "F8D4945A92CE46DD24D751DA02F068482C69B0DBF0501634C4A247E1ECF98B270474C81AA0D8F45C0E8B5D02751E797D101904586782EA09F4E3A567C2BF5146DFBE766BCF8D0E4EF46016C6ED7B167490FD2F8E9C53CB42660331B1B62810D21477F5C9301D6D054FB076E77F35C1942AAE874669E0957A031223861EB563AD723781105567445B5422B179E4828A4306079C4D42B793A1358B05D02D4565E4AFA2D1CD32B6E7A4224D3A86E8AB79E1DC33A11D99411636F939C3AD0D39351CD057FC6BDB32ECA7427CA0842F70B416DB14518796F68C66E3CD04720DA02B32A3430E0E027F48974602EBAAED0F1FB5763A914CD6DB7C4ECDFBE076B0348DA1AE1F67C63EACA5DD8C27AD54900779952239539DFEA22BE70D54661BFD973D1342F71F6A97CE798EFFF852FD789DA56C867C1FD2317C8174CA0E0787DE99F77D264655A36B1D8589B4C4C1743E742C31AD19539CBF8366EC188DD606392D727A53C3BC4111CE2CD330FA0E484F19324AA5FD577DBB055A3BA6F2E964371C0D4B9150E4EB9155DB871B6A3F321DB2B3EB9E679ADCA62EA6F7DB5C4471F470D42D6C161CC1A43870E7BF845CFA696D71629C21D53A4DE22AE73C39837222077ABD8A1AFDFAB6B4DC5A2D68BAF6EC95621BAFE7257071A62F07848180FE4BDC29CE7CAF2911564BE1DB7DA45EE58852D0457456D19979CE66F3821C30539965E4C3A1691DCBB4AD0E7AA133185D2486860D4A5FBD260585241772B5976EB449A72494637DB59CEF54567F7FED5B0ED618C9527C28C38BA362621CCEDA11A00DEBB824D31C7D5B3599077B9FF736C3245F1F3DCCA6D8D74BA96B195B51CDC1C68E29E5EAD59CDADF5A05B924B2A790F80CFD8B8B17AE1FAD36ADFD77B078C5A535A5293696C7259AB0305C589B2986B6A841F21CF8686D6B186EA538C29C7654A6AD74DAEDCE943627BF5D497CD7611DDD900EFEBE11F9E611F416B0694B621D4EE741CF21759C92BA8BFAC90ED9D274A9EED59774CABDE532D7644D048B83CA97BFDAEF30F0B2400A1BB647C7BC9E60F57451915A0B531E29D21C2007AAEC522F4129A7C251D7FFFAB20BCD5B0563ED78814A3B2047A375DD9A919A3E8FAA0EDFF63E0307EC9CD14FAB372E965324CBF541D99EB498CD093B188B1CB79DD6ADACC1C9E306483BE70C1BDDD1F67B0B86DAF8FD905F7BB6239138A73300C58EE30B6D48244803A5FFA9936B0A06B16EEB2A880FF2FBDDA1A0813006C96ED0B6A30B5D10528CF5AFD45BEAA82369BD8254A1A7250048252EEEA523DCEC9FFF069006B2F9A8653103D47ECF79BDAD2572A11871C018646505164837DCF91C2E22CC55B344990BDFF2D50363FE34A19C5CB46CF0C193175248EC50978F2CEE4E83ED2B7BBFDE4471859017D3418CF3D3822BCCEA6B8D30CF11FF008569D9F0BF462CE6D73F8C119E3D3AB30A68D467CC60A907661FA1DD47FF3977847BE38ABADD7D4B4E1B127EAA131BF3B0B1FAFC57165B69A48500753B9DC141B9819CCD9B4CACFBDFE4E05CA5CDFEA912602CFF1EE04FD2914780E713176AB4383F3CEDAF2C0B5E6B640D3B5905EC8EA9630BD3672A18135701E4140627E98F1BDC78B05D9F2224C59AB3951A0653E6729B7B4BB0035FC964C15086FCE0C6AD85155B940C1AA13428F1E6C20FF95661D283F2ABE3D43C072B169D68C740E67E3CD9D44D80BBF1D455204D3B56F06D9CD266A2A928C918F737A9E475BE20F26D97A3C0B7194D6043CABCB8BD14BB4BFA94D13C0D9BDD4E6B062D4685D22F3DD7A2EA64FAB53A0E06E0E425FD487E333AC6669017492AC45FBB9E2313F6BCBC6E484A5965E9412FABAD6A6FD03675CE1C70158B33E17CD18FB44392F06753D565FBAB2D4CB09A85EDC20C9C12276557B03DC41B7042A0D7FCB5D236BEC4B907F6FCFAC62C3A07BD92EA85740F1A501591FB8D930A527FCACA427A61256F6591DC1F3CBAF19CF3F9B5AB5AAEC97A95BD5D9056F5E463BD86EE03D1CD5A14312DCCC3345958DE85488D1DB2C54D3393B8BBF90C1411A9A8B3BCF9A13305FC5AF52818FCC4039D5C8C6ED87D8C01A089982ECB6FEB7AD09A79603ACEED01CF453B4620CD36E73B76B91924D9BE973C8BA8B5B360998A182F9A4FEF5563A0C5505B18110723A268CA4543039979231FB082A639658B9F5468E1BD16F96A158E0F39A160109A7CF244CAD177B2B1F41806279296E7D6622425B75A1320E7E3CEB2DEBD1F739B29A8A3BEF23D5DD2712A82E320450AACD8E9EEE78A7D019AA09E42CD9923702086829308ADF09C0D0A88B58B2F7C4534F75631AF1A5B0B68552F402481F9A96B6A6A0A14E93E2772EC72D286AAF2CC9EC6450E80F42673A2DFD25C0E0D5831DA8ABD631966DC0688C38D602AAFE8BBAB8FF5FB9003BFE2E45A74A1261598AF634F896CD8F4C04C5FAA6442A788121CE8163A085B4E66308FF572CF005E960C8A21A82552AE6DD1ADDFE08CA37B82DFFF782609F03DC16E0B862398C9FA09DFA4D35510F4BA7E77C0233CF923E4792FAD9C5D7A05FA174438537740EC822B2670BF1F244280A5A7080B21CED5646F5077CB39F23555A112FA1E1458BC45C491D5092B763AB7D291B8C07BBEA2E39982CA19DFF6E4EEF17557E8EF101D808FFB6ED73DAECEB77C4CFA2E391CEA50F1A75801C2D34407AAAC4B5138B4632A710A40F39BA7ED36454E0B054E00BAFC027D01303273DD2289E7666D98C3B602CFAD31B7680E6B1572", + "sk": "F8D4945A92CE46DD24D751DA02F068482C69B0DBF0501634C4A247E1ECF98B27B870452948D3FD91DFABBA184B7778E2223C610196918C5AC471FFE27C45C216906A32E421BA0C8EB43BDE774C8151020BB33E6DD3CCB67E07FF1508A591C40F29C4F4E03C0761DAFAA6C4E4D7515D3D044F7E5D9B6F76C3523F07B86B966BC2050273654131572050232540265501410321121824027783508650550741845227675205140764772006807238701150672363522380823186775485346122741232101846044762034061346508846856004508217531847506553422270003465001318843366570722341256676412710345762503442766148802031700065838665810155802123526425443477780225517686668627385732838374183830578328430875075738806006057215372237255330206645686206532007402436187730431525465867647825811554786647043104375540063472868467521138444506855840850622072745156652883730438734305732524737387063014705036441133615604518408815122131125202504810267182170514218811002085201254838156820201088584847214346753735887361787368723385680274880675716073083468858754024781441460451718621650764072470876430018540463314037653043260254403334013420554376741651526887384367232437772872571236432846113158844048402448026234443446356631655624571084504437148135030305335563616217056075630605830233420552628432373442580105268442188606664005688153573261574404273251112701374300315715427425557365723036707713333154501238558575528577180345582234204444027511078611230842318434676756513328416871728302630727767221615188778420705148760282006015420340813653580172668162025543061257714607056886527838253463775286557467874302385541175163873125403136883123024782644056005776454050450463856458231030266773238561883245373725805362358236861886558048054373517006153723263352805784612747766872528551515675467320836133213785558662842164780507124010780705382731865322261671658563251820625605486727154222632331845371780377110620406316868745534211605053684662067164782272500355338031585232841457166288521403104854878437265654262373837268281560786012704588254043617732675622047062353066104016602755704578677260376636082632526506057173816361868253348168171755151062823522066020418818632307513542804243556317063765822868038468506613448543036820231730106212347485234367884828616827033357121850832050360848747865116708334325478114764064545882530235517784101378158280387668200424153038757453662564868561401622005841426338428326845853813752150205647048731768316114171432031210530176405308626212315625877622410617144857321075301351544462610553051243543667566675865335022131344837646363774338358017020828322812301042686502414653278867536671246033825211786357550517555870412326345585188457210000315518722276643085112001162624655523063655320741885067301234547663482785273242871867433610317833314257358238168035870421442233173234774652833582072540045143452135211450447284405865524301678168533008608553068110010402510031273465112253237686727627477608688360860655175382170833104267041778753258183846702848155552758183213003518102058824468267721170670211086383333614167717873621734000234476376137205763060645015200727731656541667312526120835206388554240354487387761200858280506664805026810157822733523020574251831872646604616365770712618804337567105781AA2BBE68AEE92FFD1BE88D01DD90EBC8D1A9F5DA65FB482FA23E92A0BFFAB2416637956B1A4F7D0E392B910710069FD0E18EB26E6CA741ED0915FC9FCE0C0EBCCA45C7BE24649829B0AC3A43C4CC2E4CCECC827FD3191515DF2A120359341577BAF0BC05F8358D518A57ED3033A73B8230E8B23F627F6145AFB0ED0742146C61A21AA6CE40AC75928F007F39E2696383FA48C75694F106E623B6F41E070D0E985E9D542BA2B5F53A47B00CB6472F9D03C3DBDD1C113B08128105F6FCB281C302C0410C32234E0E9F279AE96F3CEB0B0A490443A8CD46BDE80AEF7B1BF7DF48F98215B2F556D0EB916695417DD643C93AD1D703CB238418C6199F7FB4936CAB6490072A245577FECAFA7507A2ABBF3E2D185D9DCA22CEAA93662168F43ECE8421B7A9A5A2226227F22BB497615426881EB9BAFAEB7E14A177AC6102425791A1511FA9BCF2B3E453CA701D0C8AC45714541A0478353173A6EE57078F1059517910BCCCF0C9842483CC8E5D35166AC13BDD7D9C760819752AC40CC61528F4A93749BF5711216101CB0EC79B6E0BB92D4F9042DA176E6C175EA1B2738B7A6355551AF4C11AEB5BA92ECDF28E521E1730598E480A6EC130C65388FAFAF5BD3F43F566D0206A6CEFFDC01AEFBF52B46BCCABCE80AF453D1CE840B3157D4B1D15DDBF0E864939A5C411B471A9077E5785ED9928EE1C05E0BAE9D4FB8C9B0B7A814A23784B04F63BB5A533AEF4C186217A24302E706AF88D4F9E85B71CE427D19C149E01AC698EBBE6B5CEA2E3A43DF2976CEBEA3C96424D2FDA27DC3DCD7A36990CE7B9547F247039E83194E34B3DCD90D65D3641AD5B90C4114D0441FA46FAC16A9F0691B36B39012F2361EE0B87C23FC454B21205AE0D7E6D9C162061924C2513C369CA744DD2DDCF9C0C314413D4898311080757309D5AAD1A3761A3223B60F66B0E392F821597A011188BF35B25002C298F01D6A5463D3176E1C7FD0FF1A70E112ADF9230E9FCC9C423E310E67C35860A09CC4D3DFC4EC0B16AF467373FAA59D0E326D82B6054382476A1D47CEFD2709EC829E3B29AE0C09E6B41DD540CEC37F0032C949B9298ADE79306E376C6184FBF7440C14D217B1A557886CA79AF8625DCB9142126A70FAD6F813F3A5625F2E138E625D38B399E20AD05D682552180FEEE5C1E370F2B6E6D5720AD313B98BFD466468C727DC1F2F1CD141DC7CCE3592A46FB3C63302932B832F309AE30E6714AB952AB84D76A59306D05E1251171F8C7F8B7B2ABED123D47428741A8583EE5B8E973950B4F5C754DA4679F3A06EB18115C3049DE8E232AFB65747C0AEEAF5716FE5B89AD6ACE90F8CC4E137A8D9C65CC3A98C7FBAED0E7451A8F623890538DA9A7B821D8CD9F49A1AAC810EDDD7EE00AA8CF342F0491A50E617DCD535242D54F0EE8392D1B8BF7D69C81FA335FDF4AE163A1BB7024EE883DBFF9A1CE154F4316D6063DC7283F151C4ECF5A9E8D1C25D0238CAB9A925788FFF6BD68519713694B231A07E826CFB6F3910428E3219116782E07E132228B558CD380591866C028E1F3BD2327BF7C61FCACAC8485EB43213C20922252B2931861E077712CBB5701876BCF66FAF1CF6582D4F4EB87CF82C1B7807A255E73DED3A7FEF23139DE96AE800C2922246A54F3F3A6EBA2C8E8388DBDB41A4131A69280924F6D7C13952ADF9F6131C1D6AE6A3A085F8FD5E4A45C2951A8D65C345CC067B13CA32B1A6C28A6359C48DFC119FF7AE92054169DAC29119508F17FFB0BC925E357AF70B85C214DB0368E1425AC878978C346485CFEEB9935BD94D203E271C2EE9EFFC63C54B6D05C15EAFE0D0D562C458B0C7EB0D84CC123FBC30EAAB78B47F9CB11AD7ACB54221F56998177D85EBC62DEEA042E411707FA78C545445372461BF5D4C9E4B5778BDE3C9DB02F697965D2CD2A10BE66AA9DBEE728B52A9117C53A5A2D90D59F86D8A601436CA41D4A99E3C2E66261E37A3A5B7D4DD21CDD46EB4C62268520FFBBCAA8BF3DE714652CBF83E7E2CD57FEF6ABF8946392A33D984FE1CB1A08FE5DD088F974499B704D94F0646C7977DCD7A75E8012CA35E39CA7EE7AE1C0C27013A32DEE29CD141379DA504CFF6ED8853959840E829170D2D15A265CD9A8BA48718848473090F40C1BF3DD4159267324BF9858400091FCE515D541F6608D395DEE9C5F673375E443F104339F444C4819A630232EA7D413CD8A3556E60D7D20ED42E45CBE335AA1EC684CEBE7B32C5BF4F68F969932961930247E2A9F279F5C587120879F3F61025D6B6DC617C9FCA4AE8034B00C8DFD6797061A36C12979E85F4AA7C9F7E57FAE4AA44DB1AF6306E982A723B6F58E9008B4BCF4A948FB131D08AFEA9B4BD093CE76F8F6366ADF4EBA4E31FC5EE6DF22E1FF1370C81937D29007A9138904F569B95A38C5DE1BF03711C9D41FC0E72744426EC510E600D1231C99C7FCBD91EEAAAAD1EE8A27544D0AE7871B4B881D80DEFE22F3188C250AB8760277BE2295157BE5F33201233B53E2348661384134E6A9BD89E8F85B2F4E217368FC86161F491413C8959DB67AA5D51DED0854FA779AD305E3A6895542CD84DA2E8F4739585F7AF91DFDDCB35F7E8C6F90D1EB810D8ABD36334AA02E84A4CB0DF03961F5AADC0CFD45A7F59678B06204CE0613F040F3DAFCFF3D59C56B655A3D3A0359340A0F91AB9AB1A17621A1A57AF588C31385D44667E9258E5870756AEF7AD2E2B3E3364BAEC218E0D6BE14EA5139FD672755F7942F4BF9E023ACF94B1E15C58298E29B958276F0C4F04631D41D99559E7A7483AA39252647D8600D33A4C8624D9A663AFA8C927808072A4C6A63B92A76F76A79176261D9050E890D52CA68279AF0B09B443C001A4092531BB8E251F7ADCABF4E49DD1616F42528CD67283F2C52479D7DFF2F383AD7EED58C1621E4DAD50AC9C9FA5096ADB9EAE77B19122ACA00D48E967050303C93D90976A3DDD5B3BA4A816CF0019B508DB2E65CC47B187C78432E41DC9BAE328EC529DC3F6C6BE048CA843832EC04348421113A02B60B35CA66132059D4D5EC297E9B92E8AA3130E30DAAD74EE7E021541F0B3FFA72DF618969D18B7C6936242555FFF1161D85C033BBB934894825BE9271EAC5A445363743F81C46315F547995D6925FE76BE6B7145D022AD1A015C0B8101FE30A81D363B2BCD627BF178FF12023F1BD82665393A49BFCC5AA1F1C4FA318736A301D00DD5D015A14640B91E104C814056892DE7C624240C06A3C5AC14E565FE5FC6170BF315913CA6F5BCBABEB9C110803E12D81CCBEF3C48B0DBBEC02F8616227CCEDCE48437D801861964934B149CCF34FDF7D60D29FFB46854CE5F3929AE9B6C051C6825399B9EC10A9BAD1586D2E75DAAC68BA2527B021E3153F419B0AC23A961799F016A37572C91EF790635A1D7B7E7968AA570B5897C6CF03395B5FD2022114BA84DF417F8F105810384BAA41EEF2A5B0C7C3E320237BC67DC36809CEE73AC388FC9A0873B2AB63B638AD364F28B1B7D002EF2CF5C" + }, + { + "tcId": 28, + "deferred": false, + "seed": "FB27DBBB4ED8F4F7D2700283C2B092866694246932EEACEE72DB730EFD172576", + "pk": "0FB4B45D59D6BA35576D1F75ECF682E5C901372E65678E959DD61F6652AE3F0533A0BE6A3BEF98F0A550CFCD43CB1CB9ECC3F4F7DB656C9FAE8122A0A88DFA6262F3B11454457167C1DA30042867A37B26AD62D594591BDFDB36B833DC83E4B8109CC2EC0D4126D24B2BEA48781FBFDAD7659F1D8E60987B9722DA54627EB895226B360C61FE3F2A10A69CEFABA3219AFACAFF22FF5BC7B564B01A65BD698AED8A7AB78812EA6960C2B766783ABFB85613B069A7CC173425F701B62238FEA489407ED3F2ABBF538B1184996CC7B9AF15FB5754928F552AF73696B18FEE24038A1E9A11DF0C78ED6814CEF3671D60DC38D483DAA6A6822FB4381FC036C805C8D2B7151BC6A6B12466211C0E1EE663BF4EE737F4D942881E9675FD7D87709B5F473054834599DFA499306B3E727EA6FCB7990E0ADF348321DCBFF6FA886C5846B1D05F5E08C6C4BAE416FBC7ABC1867082834616E3B4757616E9B7E04E2013B534258015E06A114192F48E3C5F0E6A48775EC05F554D69843684FFDA6A2FAB8F2138817596115832AF77A10E43A4FFE98DDE79A9F80C0710E5450B681D620BCE626FD0932B4D9D87BE222B7D0D8FD010172F3C5BC2353F44C08470871E38EB3DCAA19C92D3D028D61662C54EAF7ECA32C0D48F4AE0B2FCB0F517000A8BC96A76648347687815254ED5905A1B4A2ED4E43364B48886FDD5B86F90659AA03B2AD85B54D3E85E3380FA2E050120F555FBE241B86E481E020BD0AC3445CCE71D9F8FF56A7475B073F1F388454B3605EA18A5E183831C948241DA34EA3E1112BC706102854423A4DC16D9D3A79BACE600F8098AA60744E1C7FE18A047BC7646DA4A569E0A8C41D0587053A22209371E4BDF5A7CE8241D97670BD81E7FC61069292BBAE13D8F729B7F5C2ED3E90BCAF55DCDE5B20EF92E1E7A159B6205E7ABF72571F02505526928DB09F65562D628443925E7DED9586393DDEB4E59874077CDD4F7FD4CE68D2CD311DE78B245872AD56078CF3DE1D88FDCF541AF7D6CC69A1C96C2E5763BE310BF77283A820359CDEE43B53B2F004F2FA2F1725BFA6116AB9A8F37FF4011106D1E65C6A3828AF1E92671953C26ACAACBC48031D7E9919DA915B9E5D89556FA82E9498A0BA980892B9B9427B848D095A0BAF3857B6D6969E99CCC337EC6E166B1E1F55237BECDA10256C8D97A38B21986AE06DA7C80A17F84BC448F9539BF3630D7D01E12E80B616F5F98C47170DF5E16450D393CC4542FCA66359D48B1C29D4C997C6FEC087540AB588663F5824A4F09E5871A78E06C18D3A708CBCD7B4A957BB69818D38BE03888BBD62738DEBA58E3A6DB3FFE477A5EE262297F96C26ACF7CC419CB7F3EE8D09E47AC1B134B6AAC3191F7F586B507F58FF9AFD67FCA0C10E7676ECEEC78132EAAD0F8B91588C62658ABDBA03C9FBB0630B2E9603E5A93F9A04A3E07A09FA0B3AC4861D368ADB53E8FCA932F997952AFC5DA4058C48AE6F9B634B624E50D2DB8E3CFA23FE41C2B88C3C588FB22066A0894893D4FCD55FFEA4352F8A27D7714A18309B7997CE71EF16ADA021FC52F3652561A1D6518559C250CF1E35D109B04408C998E457F06F73349CB8BECA963EA4DD65826141A59FE60F1DE7F8D8A67F5873A7696E206E4EEA9FAD9FE00C97A07F7D7DAFF316CF85BC1A465F61A381B2EDB3EB4053B8F134B75DF5C6D133E7CF38AE416D24D4AC66AE61DB1F682A6B42B26A421E7497FADA9A97717D2A9D7B028FACF01CE14F3F834D84264E688BB7C0305EF9EF28D5A0A491B0C4AC763FADC1E260790E0EF2A70E6BC78A6D3A136E0EFA5D86C9C0993F3E91F5AE6DA55BEC8425F1838298F63601B4E9E71AA12C07D2FB6C0CC5661BEC9A0D929FAFD8AEB545B729C7BFF035E67EA7377D2162622018F54F780289FA8BF24F9FC2E85D06DDACEB91D064D4DDD3969FC213AF6292EF7FCBADA5CB3D5D1B5833CAEF100EC657056B69324F2E5C3ADB519120193157505F5A0C1044C0034C03A664CEDC465C79BC2B915B749AD0DC2E88DEB3FD6BFA8EE42631F22938D735186CAF7F273D9C8361851028362F54A9CD50536E31BF835D13DD4435911CF01B1A8E27339033690C35C311760DAB34E391FDDB690156FA47B169043E6D5E1AB721619CA3B8095194B7802A7FDEA8DCAB9F43BCFD1F5893EB4F58EDF1C0B9DDD0BD4615FC1EAEA46C68BB84697DF3787775E4DF560B1A43FBC7A33A3E084ED97E59C000529CDC1F97EB92E9DB331EB207BA478E3457D1648084D267C0603135B8DACAF2C15B42299DA433C0E5225C934DADA9B701751ABACF9FC47D90CEE43A2FA47F6D05D169623B369A7133D0F73922B2EB869E91B5737FC3A2DE03A3A92DA98A253C022B4466DC591772D39E04CB1E4F176C1A282BA15E912E2E5C8D81E00F92A2FB8BBB16D6B7733A785F620BF52557B3C3E87EBF625B4FB0B7B65101053532EA099A1B0264DB218EFC19BA207203089CDA1FC2B32BC416C454A4BB977FC3528E423A3553ABE4C48DCF662BA7F5B7E1B2A4E2DB9A388EBB0E39BC229AF71ECBF2F40727D6CD39C2FCE2464AAADEAECD47BD08FB1FA5B6627D274E3D31C078FFA3C3ED29980941CEEF8853704262B23DFE88780FD9CF259EFEEAB01255F0CD354A473848798CC5C1CDE63AEC6AF2EF078777CB67A4BADE7C3D5F345111FC73261B55E8E257EC5824CC829B5F5EE31D4ED03A16590396E2FC381A7923E81E3F582252EB19A7D61ECFBD72F0C3C16FC79", + "sk": "0FB4B45D59D6BA35576D1F75ECF682E5C901372E65678E959DD61F6652AE3F05E8F6C5312F27292980146AED5BD4CDCCCF105C59DC052E9A5604839CFBE13920A93E9DAD0A618E59915ED8D751E04CD99BC661E5EC654FB33C82AD84ECA806453B9145C9335E1A95D987D85954A8DB9BDA8280BA76402E489AFC07D90DF7567C36560273017280466156464484345270285178305711250242618355037451272805831334710075688556205675635811344085746515547468075008004432316642077378448408234860066117021246184447148263433760087826350221845428303755534425555717783464144721524485283480133537526651561143130746043842062162336620037333860708821510700458474260707108783552112553517880140325080003741440347208756274083066034241155117413308076178401187304037688762030146873725228304172627873352187338032728273353058572467830523107526832557771072150587632044015331378888724574122703235400051288424471463017425114740686283126323770788487586151073237435056574117185656340627503508855871406032154132457173517406070365623071357215822006317662446377112741371334240268625017522547202654825346782030134741711776706347452824240741863480127103262631840235133582166006304237018151562258370018144006703338563061314556680178581266374583457127838148005138183311168871835130403368588740370785287432187408630065074371213480444706406001571542517601870046628537585864013505382654286745611688562826411460181216012170130671033666664050228621047288450184107351840765645803278162817607642382073553002556568788426586683475530285773666151835665516303380616363227666858618761871385373345822418160086702271023726638411777186012145217307263853282062146678035810787254502315346844448377284120122775352576074324353408540721484446660113184477760757722801866776724528834717535547588852626733700730625755854828563408352458634703417047181611758852002888110270451664011082677250413015718850326577835815683880356606382152683807252371042722116282841206422056134168747282480661425448572771268256417857244404004266015646767320855751075500451662804257710454343255256810735615778555006233143718626653125262772466865157188155020522535172225206165001848253325225481217513861451643867711572822836715814443656054847322127382261373454384541346144146522301347070057540552088832373200502381445727625633138630426301227580101874474535184582276070136541128502418006160228766041816107568722737402742376833648820075260766071780446008477251682432221347088684304624471851307716637632473404150070457208081263267878825854610503616057514005155454106025132382716413517273075776773481460567806534468274677273732307402176400528254003850741282758634420707000148538120762573172316826678588360778452648825333124015705775726667545085706211188383356315880631315705723620874123576711420723155615800885213201562654580242880636273014718214588481101167063874558732715713124774232421012565602130506631727226611188335482535363622858870107022383508628013502852406025771446035382361661005267412153785415157213823542604756172745743260401151135822128877563768657521545878000334705788040273517532403014046181623871830487143472731360310027464080371511476477842670552846448716276586070267871218265501785588404888023122544554862135404377441518C06B6969446A99968141308658E13180DBDD324D01DF12295072B0689AD24B8D909F5B912FD4484F8715495095E72DA498D11E17C8FA5179C034D020D13333D45F044FE079EBB5CAAB5AE07027DFE0B451C647A7CEF0F2D7A516278D0146904E6BC5F9A019946F64F3A69C8739B47FBF768BDC2D10AE0DFB3EE486115C3D29D0390E9A6F0C66F32D20EC247C23A95324346E87E5064A651255FCC49092B4C7E7C1FF85C6BD646F40ED3A8C0BEC3EEEC4357DD01EA975523E50A5E1F1357B0BF59087F056A70AA4757348F5FAFFF7BC3388DA206D92ABC9A373472E188B55F03A2F5B2243A3C2FF86A3934AD1C63EE4D31EC38B980F22141FE77B29CEDB621B6E7689343BB29699FEBEF26346177BE01999A5A1A916987138E7B84EFD5A8EAB3B995C6E4202354B659A391EE0305DCC82347C50CAFE8C3D25D5BCB25648CC4CCAAAE062FFB75041874FD14302B3189C8EF04500EB3B9E6AB7E021647C79E1FA19BE67D1826D3B96F3E6D49C6EB5859F8EFB241B8E583005536A8235C5358A64E894847194A3EC4CB7BB6D445C66C08AD99D4BE4243FECBB6F340E175CC9373FB62ABF024CD913F03BEC9E8D28F7C8587E1C3A7620A83C3D4C31DDDAEEE9E1C965823A2F143F1F295B4A9665715EB2FC4A82AE0E16ADD7F58986E68A720783D14D0C48E92467B3DECED57A169CE42E9281B180F791C3A9A84D936BB4CBEA671510899F35A4AC0EE2F8547C2685913069FFD11CA7DDA5349D545BD5705BB5FB3E233F11A6A6B21DC638A4410FFB2420B123CF8503FF4FB53A19DD70974D90231B90914F92E52A38B13800C194427204D3AF3DF2436AD50F85DC6EED13BE12870FCB051023505363E848BAF4D01594BC35A9C35DD23A4986ECE378A425EFCE6CC49C65F5D829D4A7AC4AC54C3C4766928315F23400836DA42717ACCF7061CF91BBBE8C47127F5A8DBE151B37FABF6477718B11C3FF2CAE39246CF44520C92411A2D9B365570462F2545364A6CEE318330123FA3389E732BBD135E74C6CDDE764AD713A40F19EEB1315492378130247187C9444D7E5AB0E56BEDD59ECBA7D27AC32618E1DD23D1452664D465B968D86E53DD0D9B50ABCF572BC1A2B072C1FB6A6B2B4DFE7A8261E5D074897EE0ABD4E82C53624CBC3F94879323A4A7DEF36E80E579F824129D379515BD42F67F68D2A0D0D212D102B19D2D1BB4365C0F5DD6F6FA2F32010A9CA755599992C68FC61E4528A68A38F6ED6E70B45E1604221C27060F6336062F6F85A846E9586D8D9950C0517905C23BB99384092E333985D1E8F51F9A1AA6ED855B4288674D02A04E15E8485C086F952B746351755F31BAFD9BB9D0BA02D7D23E0915B8A1C5C2E8372FD6965EDFE496ED5A2859440B1851F2822F1C199C041E863A9D23AC3E03D510507BA8B4FB7ADB6F85D421B0ADE9B3B6606C9571E49EDE3ED93CC85A23E4EDA6D014B9F93E6B38FF145C8B10BCF6D019E8BDAD78B8FC0C70FDA4B21CE9652CAD055EE62C195CB2031847490633F9BB81D1F2B81E9FDE6F8101CC0E633676D5CC8B0431B917AE43248BB2749CF38561F409EA1D509BCEDC177601ACEBD99DDA198F4E4F215AB890CE8CD9AE75384D27EE7C3460DAEB72BD2BA90FDF270FC05C52DA014BF09F1C30DEF071E1750E5F9218F57DEBA0C90192D582B25A63B18F84E4E06C741AE8E125753F5FBF4E5CF08D64F6BC8A155B1BF4A6CF1A252A8F6167833D3895468B438EC98548A3AEDFCF0A3A31CF1E0D4E442B6FC59C86C10287631B134CDC1832D83AC335F04D10306C75C1A45AF63B48BF8EB03F89CA6E0DA78BE299F98891922A977E6EA182A5AE7B544D2666CD0F3CF2387FF3C5E4FAC94C220BF532394269304FC8A57FF17FDDE31B6D233A0EEAFA3614DFCAAC06BD6CBEF6EE74248DFE9C6B7A5A0F284A0CD4EDECAF3DE0B4589D2408F851C2036812C7D46B15F67E8C9713ADCDC1F1B2B82ED7DA48AEF24DF9B400BB32FE89AE95608D7164C377279F779CC1E8FA6D6DDF67A264D112CF7E0733FC450AA97B286EEDB959A57BB82AFA333D1F0CF965087815023B51B1E41D035E29AA99C90CAE7E16B0E7C03E52700CFE574A165460732537C413C701E69700BA941A9386FE8F71FCCEE6D3C10F832439B754B8BDFD49E3052C0AB1DFA70111A4558B86CB6054A4DCE74F81990850ACF6FC778DDF25D395527577D9D0CC34C72029AA9627D3649565F9013F6DD2E586824BA63C18D778F6E9D8AB85682DBDD723315AC9DCC02DE0E8789F64F1DB1A7F011CE71B028BD8DD3D1DB7C2496E67838649DF2CC4E4DDD1F5F3308DFE57DD1A5074C45F0346043BFA4D949AA2CAC83221D27ADA31EBD5A4F458A54D128BC7B20F410BB6C19F1652B84D05D5C173261D701D5EB7053769BA9C62362CFC52FFBBB536B1C21C497732C6894F8FECCF35C513A14EAD53C3A067585C1E021ECC3F023DF543F624DEFED6168C92C43B0858AF64DA72240C0BAED28C53C59340AE604DCE4E4E2B316FAA0B04A39800DEFB5DC91611754B00FC9D028BEB2732568EA481FEBBC3324E21D2C9A3F8990DD20E39806D90FD50F1D19D34CFB18ACEB5B7D8810B57F79753D372D0E7F4E14A6BFD4882A351083FF53DF1505A5973CF63CB015A38CC8F595AC862EC9FBCF3A3F7CAC508E6A48535AE97A56468B874AF26711CF989756757F8D3F31CB1A22E5A06B86AC8CA86D4ACDF5815F52B6E3F34CF728F1C735ECB35DBBF9B0FB14932D3B1816BBA6FB3DE65C1F537C0A36579EEB49F34A82881FCA14C2D6D8F2C7F9D9DAA879C8BC0CD3169489F44303A90434E8FAA1387885286B5F837769DCAD8F8B654C85C6FFFE02ACBB7C2881A7E3A3B2466E3F12EC79138A3FFB47C7758DC2F7A6AD0C76A7BE44604CC264F8CCD1027812AE9B47C94B70C27DF3F208231879B72947F61F98AED252698ABFF431C37170BCDB9D5894FC0F580F7260720C389CEC04D82F5CF60A6D3501554065DA790BEEF3F18A2F05625D0FA18FA51F0FE8D1C0583933FC814006EA9D3C8D94465E5EF36C65F9333B08C63CD0220B98313A465F5B25F406CE4906E74BC44D3F7A98211A0440A8BFF2ACC2F6FDD48DA95A02F110D809A0304A756BF23EEB96E2E72FDCB5DFCEBD2FBBB293736064C39C45209001FA2E4576ECBE80BB7B69B99BBB8DAB7BC45A1D39F8C52EEBDACBAA68650C20424B6D77FB03B39698DDE6B33860A485CD2DFA29EE384B7318E8DB0A8A1BE5BD032F75DAE98C5F3993DA601BC00FD13BDB70460635D4DAB8C59E1A1B74CD5564501214893C915081957EF886A68198AA776C29BE1EB747CAA6F68DA72543A5AB3107F46D6259F932F616F3ABF7414516D59418B14E95BCDB1D5703131CA20BDC8C429532212068437A90E8F992DEBF36CD1412EC24E9029D83C0DD6C6C049F9134F45968BB94C9F8004EED39378FA089241DC3084E253D42A0B9B91C5367E6BE1F1B35C37699ADC1DDF545A1DCAE0F0D002F21A32279DFC1DBE455CF17A7FFFD3EF781E727AC" + }, + { + "tcId": 29, + "deferred": false, + "seed": "334ADAD056F76D74941FD87E5263E449D97C06D748A82018D0C794154C20A870", + "pk": "05F90F8FD12BE86F4F09A59E0A0873933B75A7C33C76BA4CBCE5A2216610D5A228E9CFF23DC094B0D3690EE5B3DC55F243F2FEC1DB1046CEB35578AC48F680F9F9F8E20B4C96C67FEEBA4918C4D7AE555CB82338D92A2F2A97B722F09107FF5DDD88C86007FD3187E8EF195B678F1765644D5FAA99773F0188DAAFD9DA6BA2598D440F2639BF2C0A3729078CA78907C54E332EC2AA6D9E79698BC72D082787D7FF28929CCF6FAC633B2EFDC7DD0B82078DC8CBEE7709512583EB2BDD9177C4691D4AFAB887A739B396B308B7004BE2C7E9D83404D185DAC00168869F5882FF81C9C65FA6AB987C0B356C56F3E8ADC931E780F2255C39E2D40C0D741D4266B1460344737457D5DD07889B30B640BE49615EA8FF6CEFB05A17AB44DB8DEBB3E883E8682158F566561FD4FA8027A04A0153ACC065EEEBDFF09138F621025527079E7FFA9010FD95C8791CA36377B60E2F92383841E15C8A8BA07F2BD34F78D9D2E6825DC476687AA780B642B26A08C33CAB33860DDD1858DF04A94C2405F94EAC54A005AE53B7573CE87860FDF4A59F0E96FD87B451A2A897D8E9EFE4294949E8D663669D8474DD5FD5580A366CE9A282A5357DD7B96A66DF961484072EF21552CBAE892BEE96330FD3A2C55008D71D23A4F0579BCBEBA343C65C3D565B77474C178DF9A97B451A4EEB90041DB4B50BAA022037E1E60D98F4109B9FA51275A7662BABBD7C6F791F54EA56752E20284B56CBB853368A2F54C02778BDFC742E8FD566ECBC97596388F9F823CA2EED4CFCB83084749165B17425A8719F4822CFEB3040EB3C8611E1322799D5247FD27D403C74A80FA0A672FB1CBC62443A222DC7A1E783E5BCBFDEEE18A8D880C65B9E827493C318478A6573533C4C36A6387CE1CB01CA70985B39088AA76F4C13A774DA5B86599DCE9FE1A87D2A48AADE42DC5F1849AB42C8877B5936FF2E53D860B54918B02617FC78CBD03765EA6D9F554C8A6DE18D7AEDCED60BEC084BF93419B7B5FF489457CE976625236CB16C26686C3BBC5BBF2E1D37C69D70976A7A3B332DEA756B3B84FEF984BCE70637FC376A8F4A02EC317D4E67A3F259141AFC2B061D48015294497C276D87459894A80B2C7B9C46D988E6550567EC4F3035E23E1921818D2A4D060552AB0088A27C9A022DB688BE947C231A99F22D6D0B225FFE5CEE23A5E89789F5AE58F4C50603B37A0624A96270B849E867366D8D82E02445773DF5648A15C857C6B04AEB21AB4A04A0552E9F30CC253B2FE7CE0071D3335976BB702B11716420B43AB11639589E5D5A3E7477B95E598208AA46DD30E1606F30DA0C616DE7A3CC31653545894FA958E8DDC026EA1A8A8B807EA45297A04AD11EC7FB3EF4DA1377BC6C36CD3E0BA08FC90B4B80C541BA6A5B7D2D91E299D4AA9D854EA59F45E0D76F8090127E8E834F3A652AF71F18935A58DBDD18E9384EAB5E2E10D78CD57BD4EBCDD45BD2125F2E0896BCE153B5F84437E076145B61C050F3A45C1C311FD8D880F38D65E89C4302FB3DC58C6DC1F58B0C52B73C00A421261AB5B9EB317C79E2F885ED5734F638C8EED36081404A048C26219B04E526FBC1D1A5058685AF88028247D6ACB43FEE3F546CE2BBE4BA456E6868CACC2557C07ACA318E1C8F70AF0C9F55AED0515905E775F5921B3AC8EEB5137182F487ACA7DFEE88E77954A94DE3AD78C518B438915FCED9160A4CACE1D7A005FD60BD34E1B328321C22F58E70741117ABC5F819722742187C9D3DD19BC3B7726DC3E81DA040CEEE823157A14470E9C0A04DFEA594A05DFBD1E256BB1524FCB591786379FCECC7545A875483D4B2E58383DA1807F5222CEE95E21BC52316A886590F55BECB6F2D5F8184330C82BB50427BD6DEC0C5E164ABDCA44F77E80231FABFE8BF02012FD377536BABF6C7638FAD14870C97F1AB0D4273DC9C4BA426169B659278A5BAC8B63E4318A0E85C4B22403F13C9E74B03633FFADD939FBA9EA3D746B37E4BCA503370DC6ECB7EAB6537E16EC64DAA24C1ACDD2F98531C594CE745C70CF3ACAFEFFA1D36CC062D4FAAA76AFE291B8FF281FFD546F500786DA4E05E7ADE2D37CD519BD78819F27ED9B9A950ED2D0129253DA2B7F3F660281C9B0183E5F753FE96D123DBC27FF6F56FA5465B8BC9F48CE4AA4963D17FCFB50FE546164F901B04ABD909B78108ED8C5DDC8BCAEAE0669B740E0F7DCC833FDD91A789603FA9A2EE551A387F944C3A032F231EF0E7CA775905CC5ABC8755886BA211E698211ECD3B04B959BDBF431A454A08558D4CBFF01D177901671831E2A0E9838E7D9D0CDF1C6C8827E97CD341DEDCC53097C9BFBCF0B4347E398E1132C5CD5A505D45F6F5D944073716672A2B0BB6C41C8AD65F843B1738FADC6018B4C8D6D5B2E2E331B8FC41E98A91A0F43DA608F49AC0126561625D21147BB3D5A9120BA264A703D5E37494FD4AB883DCA023A73DF9AFFB4A3930B5ACA133CE57920207D3D1642365EE718C430B51AD7D4FCAA294B1F42D8BDD7F08C5B8FEF631EE7F18904EB84F867B7407F93DA884128EA3E4E1E9144ED351F40FB460FD511AAEF20ECBF20398C701717409289AB22C2518BD464D28D76D9420AF9C9E91734E36F355544A80E50BE0D3A36556620D9D217946CEE219C990807EC0D1F2AC904CF661F6906D58D8A8F500C3D54F1966A8557F8224415F17279FF93489AAC8E8C09BABE490C6F34688EF162133B19B55FABA9E3AE1E2573E51966CA827E3DAD50FF9", + "sk": "05F90F8FD12BE86F4F09A59E0A0873933B75A7C33C76BA4CBCE5A2216610D5A2B3B647FE6B2D597C0BB64BF8EC612AFE415BF8C6EE9C1C89BCC07825BB4E0635E279D6F8DC3E90FDE70867F7176F78C7375112D6738CCFA4081C0A267427E6456A9CC1B62D301B2E61490266CFDE8BFA6105E0A538AB1C1D0AB74430B33713623581386483755445243753473438078511606051368073160115738012354521300214633143005060458451614181317625600850828658142078641844516326445870256686653680383537701272643265207087826247876408370160122140768874166087151412676620180320686408856302667266662275523315434588681761074568070028312208584121154004344663581510807865182675883813108000025672850572778605381322036260037871137460676071517771314675682566577436544573460506504832281442435167233455724534277207215216360738167150836460874031736450610842824275257455405400364275587451282130682375546268016543663485208367258707108220164027637784307552716318515481724518532741014070576523654860028123444648726543434463586358076328861862385412143118625642628126672617763635717788356608737358238865854478487075717624743613147755325577155202642662650113374865061032648163018768724404227837151260534245414730837040272670625518524816844173752604713612421427581014835327884216357004103827372624624825607613685321838718783121783201546220877332618523484033418836504550354845557501255723257746365364533724770053004852604007145007653484371135700033413050162143608712741065021721558584332535787122020613285457067071122166270825871245825500252511451404363724313586561623662725341448326850605637645520652710734061103603553721504585707324281583008610265170617622430557127532416631412258328838374307302264678282601782132034871337644843401462742842107215876302171452753735780621218157840378626106652400582488562616865716354530113688531563273150642540215680704544160562010462168227847102043537372863606227863485764564280612335786655251320053243774704426146103767351675004061227771882487418563217101228257228474177206416048740843757752314642706176054186108442840481072688807888245121437337668018848605137653166518641703180318156612602033260572357615555665686231008127660607683820542312302436523202472348222103574847503136060448373050426708734310818546100012558051246608155643310633872255780650310786552541215201745381263325165137452788463576343674204721826037356042184745266584825467165112106006355167510788781105623465658773756883868012110284321513014454716525175616611768137427681534886023486205351442728858581666752868236430175106745042638321062083108321702340453041130612457481178582752050626158025384055005352376672458346427221748425807137606753806442562318172647335860725474830371583802351251766113664310376562367167407343086650862744558342510760512033105786441765808007204600605264376872847174351175438301566013163416683413510128707207468874177221405114514851318225231514632664730885425005816216567873025118726014288180357621523872378502177300555886517581515484033478831137167558052224442144782845268072021678508733840333135173515826820635274207417088856814547057513727206644577603710446785322314856685424538803253760515563520538716116405141054573465220348762101770782046356737660564646108A71710BB56C4A58168EDB0C30F9ABA6528629B1651EC7F3D4FE010447640C0C2463FC2632093713C10EF12918F6716BEC6AC202B2DD43B2637A4BB8EECF09091A92FC1B9F1081128E4DA97706698A51AEC985B77FA207BBE267EA379FCC692A53EFBD31773E886C3637A229EDE8DA0CDD2AE15AE92D780700C84AB8B6EC9C0B337C52BCE50FA59D420FB4246E1E62264C0EAE5D22AAEC278FE76F27EE4F43165E6F28678B613BB2B482E36470569AAEDF12B0F6A1E8D63761668120810A035FD8AF1BEC04BCECE6CDB44A97176F4E1F5A8AFBEA4F4C08B6C42CDC167F933777F012D11BBDC6A6BF83E1C7CAECE6069181B7CD884F482FD02FEA80CC499ECCAA88B46847020E6154B30DD124FCB9ACDCFC1B458B21F2DFBBB4192ACE07E445DBC9024401ECAAA68BBC1FBB615BE93CFBD2CC1C395FDC0F31E7054324F37E00506DFBEAFCADA9EEF08E082F130396A22F0A1B82854B097FA713126BA0309BBDEC3BEEE33042044D9FE6A20D72948E54421739E3B5DF5F07DCDD343EB4947873E77E1D092357781F35E8771714A168897FE3C458D16621462F3D2130D661E83CA346BDE9B68F238B264B5EDBE0EDFCE0FE7AC1F6D51DAFAE7C15FDCE3CF6ABFF710CE4CF52D7340C6C6C5FCBFE3ADEB72987B53CAF3C8462DF45649028E57BD96FD918156A42DF582F2D404004E4B4C589C2214937200B4E8AFEE6FB4A00EB88E4827D39ABB8741FA6B2A65632F76BF3F242FD2455FB6FF3CD06D09B4548BBC0FDF4E3399D5926C62C2C962C708FA6A58A546A1C27D5A4F067F7CD0D6BBD4032493A68C6CFC5D050D779E9F389F8DB5A522FB052D2967DCFC2F99A911AB8F7BABF73944696B334A3F3DFEB250BBF6E79E95ADDA9F8A1678712D752F4A0F2028C6871BEF429D9C6784C7739FA8CFEC41ACDB06496D8F7D013693DCB1000E8B8269A3AD0685D7E611F9D0E268D5C0BEE1DB5E0C103AF2B416C6207E498A4B15A3F6FEF22E1691BA30E296790414C4CD257501DD5AC4236D338E092B32170120ECE4A9699FAB32BA0447B32DD4957684793A77B53B7088545BCE9D2351391C6F68D4F5B7AFE553ABE675C716B66B3733D20C87EB5E334829B0BA1EFAAA6B909F9FC2D24517B38FCA6F0EA0093583C0925B0627C5536CCB9891C801C2B5CBA522A8F8F036D45B4022DF9763186D34D2D137BD4D1D865BB5C49D7F5A73B2DAAC7299723A36C723367083E76D2AFB0B74CF90EB9DBEE3B39D756A69299AE2042F37B087BCEED9CE935FFC25344E5D9EB9337A9EF17637A200567FE6C3E6BAA5A69E8E340726D60AE730CF963CDFD0AD05745A145E9FE92D80546D7AB67602A09B777581A1C8C7DE45A6ABD1DF2AE9F5489059C40EF605661C75B5D526BA9A928B41FFC93C36ACBAFEF9EE13DE5660790E44BE35D8C797EB9831724C86A069BC4153E44CEEA0746B04B9821B24CDA4A98FC7A42C8BA35E7A191B937D4752619CEDCB00D21CFB9AC21F2C933669AB073CF8F3B51B6D5791BC979C7B7BEC9D49CFE66CECC937C5045B21CB6FC234C29FA963328B174C8537D204D79CCF2250CBAA5AF3A8BB1014105178A8B98A4EF49E09BF837452D6D2AEABF589674C893BEE8BBD01EC13417CCC95B7A07C6139B5EA1F069EB7FCA0BF92F3744DBF1E24D469FA24767D2C0E7028CCD6AEE3807A2D3459AE84E9E5516F50CA3C42669F70A61CA3427919E3D3C4F865176FC08C68FDD7A48EFAAF92828C29AF85F050B45F03511BC0BBAF555627A12C53550BBCA665884239D3B68F419214FCE906A47B036F3C5DDB300B1E58A545B71C74733AF367D6DE5519FD56775B84DBC99ABBF3F135FDE98052CAB7B42825C3D76B5D3E0F6BB0C04FF8CF2FB3888F3350C4BA6027254E124D1E9871DE84AC5289A465688C4BD68A2D187D461BBC4535F824CCBA09DBA5B7FE5EBF9F7F97A85E31D5898D13D770DCFD92FA3B7872EC42853760416AAEF34C0CA96763D8B38694827248B062948A42821B841E623089709B55A9A26E7C985CE42B5F1DB99136D057069D582E2AF5AD2A18827C6EE2B5342D2A1DAEAF1FB1E0220B95E850CC04F5806FFC11B304F842683CA1B65A02E76FD0A2320819B27E43E50D7F75F4CC3988C087FCF409DCC6BD92DC9B8C72A67890FDF4919A2A0E4BBF932C7806D25B5E728DE08B26AF413F0D74BC7CAC88FDA1B54B6C4FB584FDA5D7D6A9E2F24C4548BF3F7A3F173845AAD914A3A78BAEA5877841329694A3402600C5183A1E773010F7351FB0E57062D715DAFF483EF5E85965ABD16973DFFA3558ED9B50ADF802C495A223A3A19B82C1CC1AF654C2690E46FB629FB5E13A8DBA83A176338A298057EB7FD674B43446D0BC50070A420AB426A1DDA272148CC2D1253AA827298D6D402CFB1D89652E3993E42D52DDA92F7A171EAE4B652CB65D0F6D55B54D7CC5E2108E6D5C85DAC4D5FD8E05E3CA6A060AA0AF6BBE310F61CD874C16AF5992609909543AED87019D72D07781CC8A42DA9F0D680035A7703309E191A044031480D19B8A6A6CCCFF7AE2AD1804651FAE4A2971C28D03863F5960F31DFE57831653F09A7BBA185FD036DFE22C594D63342588422F1836F965150750C94F27B77085E49DC02E750275F6EE30EDA4A0CC30725884F8B563B9F7DC7F6B3C27F46298F8AED120F634755D1CE1CD2E2E5E3EBAE4BB5BC3527C6DD97DEED0FFB644053EDE8454BD55C3307A12DA90AC6940361C310C081F13BEDCF3EDDE165162E4E20B6E33201E3EB4E7D9307D5AE918F0015158A500E4E3EF914999EF073E34CAE6A1C483B84372E29E600ECD1CB69115119BCED399ACFBD65DC3049BE0377CB27A1670A76B8C162F7167B8ED59EFAE205BDB393374B8AA7D23010D475DA30331F5D63AC67D2E1AF8161CFEA4260ADAF702464837CEA071AED36A217A029F59E7F38BA9E1C1DDCEF91DC436F5F685AA0C2A1BF3F30EAB6B6E2F7D2E4E43ED72FB8782AB5B7DD91657613081D04959FD045AF83330EE67DE3D388B7B20787A5768D1BDD982F5B7615986172387CBB65DC3D6EBB1F08F9E05EA69415383F51BDB25A21ED4F8DABCF3BA769630FE0A421DD644B1971F56709BA1BEC4F69BDF336977122129EA64310792F7A48BBB12CDDAE504A179E3094964A8835B360ECAEEB01A834C383A1E726290BB2031242952FEB5A4C3A02C9106A66905DD6BC931DC245DCC48995BC1BE9F0264148D13A92C16FADEA763BB62DC71454FDF1170DBD696C34C3AED4D20DA0983C7ACFBEC2A87E0C45C2A1CD2445564B400105CCF9964EAA5B64CEE57412B70C0EEE991DC9E868F1BE1C254DD006E814ED5412B5BC7EB5F60D3881A4D36D5DEE5216DB93F2258F42F96E21B58B547FF72F93DD3D5228C2C17771ED77FABCBBAC14D2775C098A1CD66028A0E448BD33DF3189B10D9D7520B0E3ACA333B5F8551A3554CF140D2EEFD6E30CC1E900B5A2906D11CB8CCB35FBCEB3776573E86B9DCCC6B8DAC94959BF1969804CBD7990F664B517995093886D4606BB0" + }, + { + "tcId": 30, + "deferred": false, + "seed": "06C016CB8566F5B81F8457F56175AE77DD05C35EB37B687EAE89147DD7ED008D", + "pk": "CD136BA844EF8BD51AEE2DB3103524DBA4AA971E5521D273DBFD2D69F0EF2CC3AF64CA232E59C2E1F4EC56A8C2AA886F2D5266B72B1717E9F83EB353089EBD02636BE7E2629D9128819E0E3B47C28F05AB0F06805BCCA20FE0BF1CA4DD2DABA5B9012D0D828A9F752074C5C40BA640237BF00E137DAB33468B4073B7DFDB9BB3F512E092916F137C77FA23152B1C1C6C0E7204DB7B0D0263401BE8474A54F00B6E8BBC5E596ADDD254FAA848224FA50551433BC786D063368ACD6D412D94B34C5E6067651F0356A30CAECAC274FF0C1A87117F589C41E6C7D62822F0DF036DA4A646406CD44780C0CE6A6C960D7523241861A9AFB5434F3C6A36F8C317FA267D0F1A25C1E4E5B62318D19C7DF5F2AF5A269205B638119D3479C692C611DF51D2D4CA3E68306FA2C8564532AEAB82F5AD8EBB33668028AB8CD97E8859EFAC229199B507995B1F96B3AC5683D00F3B44729A9710084B1069663552F64BCBC1EFF043F53FB1A689C6EC82FF5A0FE1C91978C52140B048B4A656FD535143D9E970172B28AD4B2D41E28EF62618D7C6E7B9504DE18F3F845A3FF291EFFC26564B2FA62E8D73788004E47899925B63712F211E707048BA59A9FBDB2079BA8C0E35CCDCE7009BB57E425C734A9A2430B32647603293D6E769E6BEB0448AF3AD30B6309AFAC2AC80E1BB5285B233A87BEEE427A02D983AA02D6261E92C7771DD297CE29C1597481E4D8B2BEFE04915DCF2A2F2391424BA449BC7F741B2AA0E8653F92B8A03310EE8D79E060212DFBDDE4D17BAD0F78C84F21DDE401B94318748994771D60C0C572C51FCCF8BC6F45F5D5556A827E8AE043127D7F2C948B45CCB5D9BE71AA6B02AF82DC2702BCBA3C8B970B0C6BDE654CEBC291EED77E1691852555E3C01E8F6F28537F1F20A9A175FDF01C333806011955B4DAE11D9EC8DFA9277C77F03172754EED071BE138D240785580F653CA8A21CE95C10152D9F82C1F50FDE555496EF081CA858BF719AB9BD245847EC23B6CD76175F94D26A72BFD150EF152D7D5C975EADC946472F2DD7A8EA557F9A197CD420928593F1A971A95C99FAF383B2786C3453892573F936FD4E58344E3577B062DDE2F58413787759A861AF09E94AD4EA06B37F818893093C76290FF0C96183412F0ABD94217D830BC21827D0F6B18747A8A31812364A8FB9988CD10CAC3BBB2A649C4D5614ABC022143716BA5351ACD138B2A06957F5CE978FEB935933119E2FB0A8965D0EC3C14ADBC82D37904E4AFEEC034CEE4031A3BA4EB3B1FD6033B45B4C35A5D309AC256DD9DDA40963C69BE485653EA7EDEBB8CFA20B422AA14DF1D5D91194490D8905740C8165F911D6A311C5CCD3B6E07CF46F0A9C57DBF4DC4A5382AD40460CEAC5F6EA9CE7C79F8B7064239123A5563D2C33C1C122F5B221CCDACF9D577576213267D6AF351F601B7D4C22B7956F363A42910D90A99CC77D4C858918007FE70865A6256C0A2C82821883627F2FE31798EB532D24317AF4818BDE315B82AE5ACD3E9B468F2AFB40EABEE4E05891D4A09709A409B0DB9A5A80F30906D99E9B67AECCFC8862B3E499B7CF7B77A2E79734B93724FDB0C35983DDDEF4B7476BA43EF8CCDD6E1E09B538E777E71BCF9ECFB6D26ED0846D58D2552BF2525242839D8DB26F82D9C6404695E1AAAD195D3D0F4E6F9795CCA693554DA5EFA82B3C773A04A526D4086CD1AEBBE609D55DD4A0CD49C2D5DBE590EB66B9B061639C524F01CCEAFB110361AE8C9D819220337F38B6512C68DA333CC2325EBD47C0BBACC9BA651D7F60B6E7AF1B8A04D3F64F4FA011EC5A15493A08F823AB7878684D9D6C1B23CCFD136EEE2203F6E7585F97E36E4DBBE652B4184BF6E761475C0AFFFA4A92E0FB139BD8D736AEBC10448FCD535598188B2DDB4D4DBF6D2662F769A9F55412B50D5ABE76339FE3E162FDCF3501AD9182C250AB14AB6ED95666D757BAE8486FC0633193CE3D3A3EC9BC8F29259BA6E8AC0F699037A172CBD5034DF788C3B9114C9A605A1F19D63ABE13DB3F4255BD1C7205E9A352825FF340D794C70FE5A641BDB47573C5C884A575D768F6AC5049083387B348C77BA6D11F506CED5FB296D23899DC35E3C13EB984B1B8874C8A5C333720162E4EEC1A43C77535A885C43DB98BAF15F0F07BF2C74858E3BED6EBEB210EEAFBCB2D771F8815B567DB720ECB17A1C675C1B014C365197D4ED8AD420D10F103D5069C83D0D2E39852AC777E0EDF6681EF4A048B3AD6F4B6134B7150E8B29D1B1B0FB69112E99185E513A7A05E470A5384956E6196B2D8B1018F7C2F876ACDC83763C390DC4A057073EBB972B89FFEF171459652B00DB20F0058FD0CCB8161FB0EDBC881B84ADBA66EC0FC5826A4128F45BB1ED48B5F6D7CC8D8418C43B444F60E7C9D8C2C1F04A3D86516AFFA6E418A4660ACB13390B44E7B17B7C63DAF2460F4C00E9EFCC531F2C1FD31E63336BCE51B89BD1E6B867ABEA8EDDB837D23B3B16FCCA05CDD2924E2A35802F55BD8AFBC8B96C50E55FAC219FBA35DD618F31C81ACFEDA2EEC25350898046106815713BAB9210D2A05A1B478170AFE4B3778E051375D021831371B16402F9BF9E137D55E4FEA29AA18C3AF0760F6C9C647D472EEA663B41FDF52F3832C8CE454E451B6E4DA179DD5DE087ADCE8DE05F2A5D5961ECCD6E362F76329A27AE77210D2330EC2AF69E5898805C8402CC41F2EDD9A2DF411FB8FC7EF0C7B590A1D751223C6D770B8E180635C3A7EE8", + "sk": "CD136BA844EF8BD51AEE2DB3103524DBA4AA971E5521D273DBFD2D69F0EF2CC396F5787D5293F0AA21C1EF4982D6D92B03578807EE3B173529E67CDBC4592C01FE4C422355C1791E28132FFE128EE7400A82DDE9DC6C4A9A4446552457FC67014618934EC838799C91EC12872C9A7B41B56AE1B4F2D84E0A1C45E63613CF23B8143058026560631877225541240870755028612211601113257620730333171113133326014734054530822257254625481781338656606531637062386428216843125583177381435215743200728750178828264283858572338340174666155423803410245053881552033512106268217163576701115100151420758458254007203647278565678136022872018662578473315183258324430858168453864072542224242317055776525374818573571728183430228822052531150150563757546718458310706857665406856725636865568642212311532331480501803576035710033308324482566338724804414110081242517212343043345322274804530744840017770682328836674404578040172026160252354482574075878623707433412042010420315324686631430437621117246135145667012805637822015676733372011026256612787756404678851224687705061484330880505326284055581054124668286658020382004078761776361161527740048635207170416215413243527764483287008340567823406070005843544321560087377528537112747351413323761711545608265808303065815242428578631040654613162778428574137416806766647656885762514121044168162303486044752838523570078420858537671500835356333734424688301521706686448255386087425664222682810214243348461332478264228721251287155070578654184140476811887216103058536107683826460515064853244078875520430770825153374152041800752886860880705277852311445620558643661375387135831547560175412405304476660057527456133616354524282235243658540065376850627062681617338104541451788220635858838672766573864142370366455786746353087604586187606056712725063187712712448173850448611574436042456606878057101783345634527487132824126777640311332086444211084406665723663416404615362244124732217810466715618067505057624817681836341825188410360207772465666127650130242187521306645231253000028638486005737424660746138014572216528038511631376771854823406270830132667674806184712737536564845562848003181411682763004664515632264310472672641657307765353303431853146262328068560152456358001505514157483485470687546573587047517328521130710682881183360163073041784613833175275612544847536060656800117884142016825672787262425284372054865151236484576661230323038363486585601502573856284167732206132578258425346636431584100337878378274840833177664013564252244411184708104348334304276470112213147701405086214104113215886548778307185000683785205742088186133061432162674560501614305005453476872274532448663370472187828212621133266066680423603181222832354734806782474407505641561545776848377668885033003456617755578432240766407055388340333658406402462202510811201771475150833626185035600871018847510308042575856566110553231327801543061080331388054232227503550601672838252561463072541831582337012688050512015154818313653303778611543867346215811512217107581100031233816616052755553316276881007300046414722210544405685155425152663633145137786125875381612221375311321043307001662685838057425460185646272147556360106708043553528546214161058211015442016678886740618868527873410028761B9B238BADA333C6E82897B4A54AB928D97C4A87932DAEB797FA5D677E173B5BDDB92434B1676FF7B965AB309CA58ACCBF0A6CFAA4B0C0C917677C9414FA1E9230BE5F75CF5C63129C70C2046214904DA3C43B4DFDEC7562261C2856D1F86724673F89D790BB11B55623F5426106D2D5625CEA933459A75DC1A8DAA87D6000330112EEB17537734ADB71B349190A2A70FACB2F42CEDA5681691B6CA9DBA1B48A4AA72C1C7235BECF0170B8CBEA2833B25C064F320D8912FD8B5B30E4ADF2CB9AB32BD6D2A63DF5118B12C37460FF7E8F9D9830C51E36C7E725B1A8E1F52A94985BF1E5BE49DF468D46249F5C9B664A1BE2CA6444F8873A76813078E4DB1F05DFF8A8A66759F94FC117EA2B6415ADE0982B73C9BB8EC1116DAB7670F46518CBB729CC8EDFDF8DDE4E7DCC960F15E4B417F655A5FE1B69A1AF0DAE73EFF122A5E52907932CBA3930322622B00E35766E0D5C55F1B7995F5729C857EB80F2F109C3393F7251D45AF89D038A0F303A4C273A4FC38CAD50D3BADF909C4B8748C760D6688FCBDDEA1A1836FC133EE714874628E4611959291DCD686FB40693D398214B2C5CE4A0C88A2D9E6C1521F4FE425ADC889B8E237E90DB6D4DE8899CFB85EF1B61A31EE0C68F6D59E1CBC52EA02B4FB66C05FAE0B4E78A492B883A15806EC911F58ED3FE072E779DF0251771FCA6354B4972B21F5BEA540875EE1A72D2D8A3A9A1707D6B0F562CE6D045C9D925F88A709BE8C1933AE1EC9603F497A5013B4BA550C024C1DB116783FF1053A6BECA7393E4313F407316571C113004572F4A39346F2A67279218DFBF61BC7C7BD1052A3E38014F926496E5CC895C6412CBAA59771A01B5480027FE3431C6A09BD2DB91F62C35B19F0A92451167516E041F49DB672D99D71E1EC63B59A0BD8414EAFF6C351C4F7FC9B73DFB508C1A3C198F9DBE0155F57E89CA8546845BFD8D4BA6953BD5AC46C7C652911583D2ACD204B24B2A9850D6944A5B89A4FECAEF23387BB845E5ED9630F72E3A54B2DB5E6FB991AA77A4C2714AD041F6B88E5E013651488ACB4F74E327FCC55CA05491E8919701D597D1510C5B47460B9163B736713DF60DB65EFEF3E022C326ABA7D3A48ABF958F630F15EC8ED234BC829D7BB4F1E7F4FF512627713205B6451804E3167FE01B99BA0BADFB77C203046C750216852A4E7EAF44F97E24A5DC16245E738B5BC153B39F040488EDB47609FA698AE5F8F86BAA6B051BE56063C9EC478ACB41FB247A7349B9E8B1AA1B1E8F3351D2849AB1080E75BEB8C68E4CDA3F482C6F8FAB0AB67A916DFD2A98F5F22473D55FE31508A73A14A1035161714FB6D813EF94E25D1AC9F8FBFA3641C45F5AA2083AF05E31A458F8ADBA3A23E9C260D9EB3DD99FF4E6A5AC63A529D0F09BF70C9FC9E4092510655AAC4F6C07BDDB7B6BB4113E66F843C0826BCEADE05C0F06CF3E93959B9F0256E3EC12CD2B5D45527F1A99C2D51AEB9FF19E9B0C4B33EBC7F689127C5074A39D5CF78E7F5433279DC235749EB8A1242CF4534643137796DEE5B74647087282241FD91F01613606517F852ACB9B6E7FFD2B64DB930F7459A47A4FB74EF9280768E7C427129BC6C488459C023B06CCC997FCAB04BFC0A012BBA03FCF13A38C225366B948C8874E5E958AC64E68DF8EF055D071AE59ADF52ED94E2F83EEB207D9630FE28FEE8E78B41B1B46A1673E6EEE92FFD61C9ABF92C5507B183DCC30A239D3998D7BC2ED70E6A2024D18D26191F47EBFFD7B5535A871A9071481725EDA4312C59207B90188146F6F22D0C25DED8F0FBEEC69C2F7438891451C366F1014F4410EA91491B77569EEBB61C9BB500150F42C3586B37C39836D7CAA54CE6CADD9880EDEF79EAAB352131AB1A9A9E61732F74B20B5B438411EC812EBCF717A07CBE0FCC2C5D70BB46A741E0DD7E2B97297310AD0281CFD683565B40D7DB04C47D34ECEF6FF88965B4D858564533E3A6E6744E84BA84B250880FEB8E88E748ADB8B545AA0255FFC70574CE9ACACE6FA948D4307EEA22F4B21711DA0276A64365F00F23A15827D16DD172B33CD1500D59F6A093E787FB38ED23E3AD1F2CC5D2FA18043FBDEE30108D1E9D2BCF53488BCBE02E7979DB238B079E88D90175E922127A7C6CD6B72B87AF752522CE2C0D6E766416CFB97930AAAD9FCE7F6BE37B3BBD1E6D4F6759265974B5AB9F6BCC1BAFE0F3D9810067E2F1ABBDDF421A21A22CDA9AC3123BC479FF33DABFDD5C6F49E139FB05B0B7A5DD024B2725996FB0AF19DB7FB1462B7C551CC2A7DEBE3CFEB95170381A407849D0E0CC9E11089EC05E2E898EB2456044BEF899F24629B311363521208B1EBA36F8A619DE49FC20AC474FACB7AB2318491F72E26C7FB9E0C387DA35DD7869D82134A9C61919C16790ED81F07FDE26C56E5ADC9E0803B260CD0B85391293DEBDA809F61B781C79C252E03EA43026521BC435E47842D24B711CB5F75C6E12E2B10BE53E09EBDB5759291F4887350FF986A16862DEBD9F262C8FBE71E2F106781F8DC94BD7E3F89DE77893B3853146F1FC5265870F713557CE2E514B92AB652BAE9E758F4ADCB8399EF0BACD87231BE1A84FFD58F4B6CCA555EFCE7F70C6E18D1CE8380EEC6DC8D34A41383B97A7B2694E8FBB09AE1EA9976CB1423418A9C13603AA67D167C7DE85481CE58EF553D9C3781A795B6022C1C00B119256547091F4B5A334016DDEA662540AB95882C608BF370513E1D041463AFBA71AA2086EA700061474FDEB1229A50E89BC1294CAA0F892E93C2257925AF7F18F9D28EA8D8419AD1121A6D8097E048C82FBD885EC3EB14E90DC59FB365C30C12C427CC9205E56CC1FE60CB6758E351440F4EDEEFCC35BDF6BCEDF4A4E2C1C68A70ED0FFEAF5A03D4DB22DEDCEE8DA1F7B6B37046EC3279DC9573E128F51BFE42285D8E64CE98836D6C80F470C64048CBDE71C10DA83556803DA4671323739FC4BA80278F2959D1C43E59105C3A398B8DC626FD58377373CEBB033FE1211F05583EE5F4AE3283780C682056BC77C7855AC186C1703B8F5CA6BD50735C1C5369EC4E180BD5430A5E33108E1547914D3C0B7EDB6AD734EB3022355F9327A23BFD535124AEDD1CC9A36BA514E91785B36695795462F5C4BA58660313B1023B075812239A12320787C5C6721304651BA9F269F1E5656A875C8EEA9E782EB912D52EB43F622A6D770F3201CDF2A5C20CE6A1D1945C5A93CC6C65A2A7627E42622B7954625D0CF8EC441C16B04DF7602F52CAD75BEE96403BBBAEA1B102A60D4AA3FCF4D5F8208A30E821EA585A130EA928E74BFCDC435BDE8AE646841BFA7A535FEA5FE89510B96B33C7A3002C442E311A45A1147F705E1E73962DA730CACF5C94A10286EFBD3A7CAB12AC574ACEBB4DF64253F387FBE4036F9330DC3670AF3D5C5E5D39E9D527859CA6CB8CC47833BAC8A07F80CAF9DB40D927CF6B2F88D4F8FE74E0DC4200854045B4E7BEAA849D23A7FAC82CC7DE0FDDABF825B720777A4FC2B4FD7BD65549F156A8AE" + }, + { + "tcId": 31, + "deferred": false, + "seed": "AF5A2ECF442AF8C0371F89C499ABC337021992F221C1D3A66B551DEC917F1B1A", + "pk": "CD40501C8F6E1240FFF9B675CBF9F802F93CA9016083A7702216C49F56FA13802B4AAFE16A2BC444D2F77A328CF9839DA78E4138842050AF64AD2D071B941A5C525C66A5CB33C4061626386EB5BD8586A4A7D3598BCFA9367D58BF650006F07754F6820D7B43B312E6A4B7A3C19E870D34D80372F54BC43EB93BF58AB87ADE1ADDB21F3DBB7CE2C3A6A39A89D3E1EA741A6C74D8ACE6BF37E97578DA064195161D174602AE8EAB65C8DE1D33896F3FA4A3181A5D6E75B5B718D3D8E36F39C54361FDE078E2286759A322BA97AFD217B72517B3F1397CE10960726700173783865AC596B47B6B8BBDB8D6B64D4CF8CB7ACD5C58DA9AD194D15E849D96CC51268C288EAA6133B8567607215778012FE046BAFCD663D2FDB47101C02326A475C2DC8DFBAB87790A11CE0B672F41E102980E7039E07B52267DC7B7F46AA07CDB42B65BF9E7580C16C05E50AD305CB0E4D68EBD4B92980EBC978E67CC115422391489E1C067BDF627F78F512C77DA348BF38BCFB89CA9053317D3C7B3CD1FBFC2793A367D367EF412454863B00C6782EB813A59B0E46F4D653F2711E225807D59D5398A12D57653193B951B25AED9811A983734C5521F068C1DBE1E008088A81C88A7FDE81D8A44A219C987CECF76E1A1849443E17F07C2B56A6CDC36FF4D9F30F4AEA525853532710E21EC5DC16C24D1276C11B36C328A5D4AF570D6C9DC7820258A71E1D5EE4B0548B49AEC9C21CCB5C2FADC7C9BAD23D8DC8B746FFB82CD78E327BEA707968C82FFF2DB878AC9810015A9D88493DD6FEE55A5FB18A35B595D7A4833EDC7114ED47DD87D5CD236533B60D732CF6A24D27ED0B68DC9136B276CEB4FC918A87C1B410CEF13D062763C54735C267694D07E6BA17D66F88CA7A3B082492BA8F4AFFAA66945F7B5AB62BC5777C443DB0E7F84F2E6756087A5634EA81DB361A78409386F569F898FD257C9307C9FCABC5BA0E391A012DA3E65101492A7FA9D5CADA36F0D613C1CA3C1BB57E9F6165C06934EC1859D13A1C3888178087106C6F4F1FC46A10FD4A9F1E5D83165C97B7D1D71A9E09B1D8101058739499342FA5291112409B93953B989FA7E68B733AACF0927EFD4302572052CF508D3FD9AA1EFFE53B4D57B22CA8E9ED9F0C06102F47BA853AD5E4E01501B6E77E31F2010F7813F339F01BD0F43C3F300B15D36AD32CFD7AFE8C786185AC8773E0F30A8CEA310D24B7CD068872FAB88120A24448637182F477AE10473BD3653FE453002CBAE148AF0C6C4DD1034AD15843AD2A83795090B1C738DF100BA32199D0CC01D3FF7844C524973B652156257BEDC07A533C0F1083827B24C3D77DF19F07249C8523F7DD350E75EF3509B99B77ADFF5CDDBBA4FDFF0BC89A3F2AD2C2EE8137B0EF847B4B879EDD39E299CC205E5E79995D80DC8D67EFB93AE3D6318C2FF67F8C31EB39818ABD6B3FA0F2C6D6646E9795D5727458EA5918FFA9A62E7528028403EE1F34213588411E691672DC1989EE929F69FFC1A87EB72219577E24D3F31E8013CACF03F8600490C84CF2348E10D4B1DA72573A9F4AD9156B3FFAF41B104FED8204E64A51353F47904B42DBC4311520E3951A45E2C1373F206D558E0AA127C400CDED08D087734E52FAD8366D786622A62A617A3A6CE792618837C635F60C45608110F191912D3584FF51D84C35340B9B5B3B9C94D6234E17E7B3A0FC76B48B34DB6409B0353B4245E21A15253D03EE89FC1C25DA0AB260ECF9994FA14EE59EE88048C12CEAF3E28D1E0208BC09F4E173FDCF0CB4D985913D093B6A37A3B1AF4989948B979446E89D24B121F4EE30A3BD9611D698B1B4B9F652724BC80B2AAB623727574485377C20E9621F3F5BEABA3943B61D4938238509A327EC910C4C91DDBF0B4A648B1F621DEA766217BD65AD8A628A39F28071B741CB1276620A2C55D975B1C2C56F6E81BB57B284AD1D6985A204478FF3A4E849F5B0FEE7B428C058D1D393C90F436D772FC7B8F9B9DCF2052E275F917E888FCB7E2916D48FC51E93AF143CCF0BE2ABBC05BF10577D769AC2706177D5919F5AF6DE12E99B3D9F09952230B036E3BEF89B20B235B9E250A02D4CDB9D14551ECDD5C5B0669EE409EE6654A9223F24C8A1FC4BE88C993F8BF25D783C79087BC66C00EC0664F33051B18BC2873B997B15A38A2C7E8B904C00170B5E9874DA8F50B76490D0F1649134107BD2ACD3717B5D5474B49BDE361DED36EB52A0132BCF5EDAFC82AD33618B77F3A382BC32624D39A6732522E4CCC05BFEC4B8A0AF5AC143C3A403BD5F14BFA86A71A85EDF5EEFFBD081C99C221355D5A1657A45370C5815ED7799BE3308A774746878309180DA20792943ACD1D30137DB52DC46E39563E1370C4EB09577FF3D58D1DB81DE0C7241DD1AB6254362FDE4850719D5B57B237882CAEFDA260CE190536AEED81503F2D7713D62C8E6DCC668EF5E8EF6DA38BD71C2E0E2B93D66E1406A8930D36376832A1621B1BA35A7CD1F572AE2A795FAB0787ABC98EA6BD6089D9F02EC071205B603F988BCA2E327D70259F08C6D57DB635B740BDEE9DB47658426ACA91A2A40EC65FE7171B1D8053F05883EC08C8484E599B2EF851C330471F78C0A8819154BE4770401B7A309ACEC2C412F3DAB3C89EAE5DB44B9D4AFF661D47AAEF05E63DDC8C4AD2BCD6A7F32C6685D69D97D28DB01EDA78B988B974D275CA566ED69ADDF84F34E5A7CD4E57A95E19E73ACBDCE88C33242A932F2945F2096ED0688D31", + "sk": "CD40501C8F6E1240FFF9B675CBF9F802F93CA9016083A7702216C49F56FA138013C48B3CEC2477128AA4F1138D64C065E4AE6F90825B8883A318E3C0E57D79608872D8B10C822DAA41CFF163BD1BDBF8F00E9422BAB08E519A346A00559FE33C1937B0006E751D8E89206D6BC60CF86C989CEDC6A650A9D8CDD7A885A5D5959750448826460188004101125111186074620576284254126602486514650254327504054426658404637850147516850678005764401755744635128034716451535421171000447534622142286762007017285656210134675821180311780513280388413616213558436053280311820410525136513060540160781021887535516157262345448444784701867043127643363865707424667300015652134858161472800247384008538765723005036486454028675180110070100585227018422187630788540325626225188813123884672141516606825703365081484622675274186476437010486026151361553084613341471802783747425386776481227074016862284216366468674776440845680570115565427708841053204705545428355530152603721866522350763826432546480520011000217246455705043270634768453003815312660206530127032003278361545060180436455308127725487262482742654007210440273753502818225888755041314584755808333558051776484568406766162183053205233717482617042441680463342553134108652603646478047082474478071810434283471763142724425102083470712525401031116854048436637142716444771867644085821750556353854203622388308758477100636263240477537720385175337344211355475034614513544055425640506651668811324364614815740531827808364780478544043850587041437810503082400163542252323515405157863646838612144458502587220415731546766633753238104428464045120204231781335071761541014428403711427277077374826708330641275013578628428874500743644104623670603744818368054481625408140001614207775166058635432827321472400672317435015252346535680281888151477005612260638815080663703827487130616081186003343810854681567106141615804734621383114175553858354054073406806336125653830065280187374320341007765836446711861021424842660758755784704122132480132102238862510143518701447661211335031546207621450714706100313847443215510114355878185523877811720703570726544284774414545134241257007847220580113313158613736252646822524660278672558356438724635513883380417860673588850524465417657131258443717224832306011153434405086734832734238855846814657087130365072151474425107710001447436647300443625157617824024324281003277361345864124855547568664642638575406011371083735120870107051813268152180133151542028272641804564120630702784343172240455064040414206576102854172281178857284212558163858228783344551685467747877225614622512371447002823523287806683488140720812213887102060221860281611143315388888484862187875060500504384547208612234821708336400356848478172006063423822373324570772060541305847652773286164648028265165301157086073527525123782386608802465083320180637434353766062137470236812473248565115246843013483416800782261353501433487770254236463403451508568564101825531344410267156466015063128101007831428421211188415154723111285433565758007356644774022346717041065367152658860424264228021125381712078461548403462250318848437146704741046774408631383441511034835475844544150855632038827538235253151753601010467407471214815105021732547307206305612530887784636307521185FEF35B7E37D1212C06AD85C4AB401622C11D1DCB7BA0A9F7552B03D3F263D4A66A0986F2EEC297734A9D60561FB3C8129C37A3BA600C75F4365911F47D8DE507165F9C6C79DB19992779F091115BE1569F4237446174C11B193532C716BFD2AB84BAE3852ACEC911DDD3C0895040BFD0587F898B70E09E71E1C8CF9BBE4580F17AB55CCEF554ED6745F46455862B00EAC4F3CA7EB66FBCAE117D94003C1DF2A43CB4BD00A4CBBFD252B0B6956A61893F022F0709000ABF488D366A1FF501C32E1F3EB787728672ACE02A5F6D2A40D734592A8BBCF5EC8111DB6DF677A6D0E01006EB862FF074377799C7560E983FEB4C382F89DEDAF21D5B2A39EAFABDEA4C3693B63D0D1B121886E5C3EDBC109FC0D412A548567CF467EF10830098EFD8A010038236B05DEB89D1D36664FDA3476C5EB93D71BE938250D307E5D9B42DD6EF72188A2FE5B408518DCE4A36EC95C4C1E23E73827DBF9AEFCB93C8B5DF3D281EEB9BBFEC3B29C29AF773433F3DD11ECD5CC94C0E9B58F96315BB12DC9C7F43FD1A148F1F95BF7F10ECDCA26EC30515249869E2C73B976499E14628090203FCDEEBF7ED6B91F6BC99A8B346421E991BC5B2E938D73D04B93413B870DFD517E6DA6EB8A94EAC931B83A68BB40482AD982ABD87DDF0F32EEE6699FBF7679205006B6D103432C9AC032FB18AC75A1AED57F37E28F3188D143340666677A1F9F6F5F7FFBF777D593BBBE243999F24172D2F74305F082DE10517528C0DE33F4DF1D4CE360EBBDC1FE3EFBAAC2E2E573D2AAE42F0535DF07B6A2808A5960A911D6F04B87B15731BF08A394DF18A7E2A9F9738305DAC46C5C0B8054F8B06E9C4F846A0E49B8D194DDACFE9478D0D08074B7C27E5FB13E9A8B6A7AC3C85717E39870825AAA1853DE322A904455A9C42DA9D8D6C0254C943E5978899C6CD910E7FFA2F666DF2864CF0CF668AE1CA8B062ABE1DA95132721921ABE689DA865DD04EBC092BF2AA2FFF57DA38DDE2FD9DF29E48D2049C61D7E506D9E5B0026900B80A9559FC6745A794F5264794EAA738A56829350EA9ADE450C2786CC6D51D74A8F8C8FA724B4458CBD35C71D02FF49E09997D6CF57E3E0B3EA3EDBAD9AA594D69355A501B09873B433997FB9FB03EDF9ACEF14486C491D4543B6D22C20F5B82DCB757AA7CE5A58B6644F45DB334622FAE70D4BB957CF1365BF1DF8457AC1A6116D50179B9F4DE05367B0313463982AA2177F9E66986EC007A6EFBBCBF6A7DBBDA21536246EE27A125C40F42399A56935AB1D52CD64B66D79DBF26AF291EEE29FB7D2FE6B07DFC2768B62756671AFF32BF43AC85A36E62BDE7F8364FFAC0BB74E43B4620C18E308C6694EE8F6656ECF25157BE214C498DD7EEC3CE6C8CDEC15F90DA71BFDAF7E35FF79C10CF28BD2B4E6CC5B006D8892BB49F3A1AF40ED845AF81F7EE9D26D6199DD628F0A1A0965760FE30E6C3B00C3ADD14C6484664D640933ABEEDF8AFD38E4BAC598353ED16CF66ABE9A27156A16743036D0FDADA91563013CB4577F691075FD5827796531D3C3B4219E904C08418F3B05D699550F9B6A42A2274A07D3BB00A1C127869BA20DA27B494904737EA8D06C75C26C74E745680BBF20713CF7DF7F800CB9393A6EA984AB452D8472AA18FB9B77E1EA98E2B949E78E7DD5B136DB996FE57493669A063275131A7C1207E7110E4620569C51B5DA00E6ABFC839F3A301B65F6EE92EA148F631FECCDABB60E6C64A3D1A03AD1FF48F540D0212E6F49C283E19B805040FF74EF6982FAE0FB8BC3B4BC123405EC37DF7A76A7F90522017702DC629A4D4CDC38EEC96B786B7E1C7A8BD559D28CA2782618F771A02D6AE77C64B0340F1205F2AD0AB202AEF7BA2908DEF8FBE78848AAF2A7FF551FA952D0BC58581A9C95C7A2BFAB8DA745DE41A694425BEB6DF3652DEB5325D0A42E5F2795BAEEF5B76261A1DD5C836843B50BFF75F53CBE0094AF351990E3B3AEC21A7EB5341EB652EF5EA8D8E6DB9EA862E1807531ECD0C0BE38A51282B8FC579D8FCBAC82E49691FAD4B45364F280D7BAD3902E745A16A94929870DE881207DBF076691A7AE81A66BA6CED9FB349A466935BB34028EF6C30A03C0E68AB4C39C129FFA85379152013245388984808C56185C779510ED716006F4B014778A5706D4B8D02496EF7C47D3CAF14C980BDD48BE3D37AFE25BE1B6D18E131D88FC1043AECB1CAC973707F61CA8610A107793C796F87F40F67AD15A6B2E84CE6C8E6C58EA2113FFBA3EE77D357322AEEEA80BE8E6B2FD7F52C8689AAEBEC7203C56F6DDDE1B2E29AA4CC6034A9F2DD07DA138B21285F075FE2FFC8329F5E8BE9D82F4762CBB746CC7F327FD21720B74FD3DAC57B8786299F49C6C602C7956ADF6BF661594CC5E90F4DA73AD1305FB1B554DD4DA00AED39BF0EE6FFADB87F427095E10EBB336B7036FA99FFC21CDA513AC77DB20998DCC3156AB73991A158E9136A688B70C85048F09EC38B6691FC708B53B9B6E520AC55A48F7D50F3C863EEEE841D984C75444105937FFD6B3ADB67B48E7342323856C636DE826209FA66411AC5605EC7F7F255FBF88B236AB77B2763F25155265411C74271B5B8A5B835A019CFF0BC55233EF268AAB76B4E9859538E90E818E6F660CDC4AE93906DA2A5E80DF4B1D5E0FF92243BE91418D5E3FDCE6B50D2727948D2559994C2C40A5FC27CDDC97D1EA18194DD3974325E8650DE63DB2977B824D7354F5C90E91A2950E69F4F628535D2C7BC994FA6F175B31B7EDB3CAE4D259BF6477EECEEAD8178D6C67D44D6C4DE1EC3E5C09AE82B40C65E181F0A70F10199322A7CB53FF2BADF4FD53733E5760B2770AC53EC62E25A9B82C3B14DA51F746D6AE4CF7713AE33ADD9ADC97DDE11552AE2D9A75455F97CEEF197DAF5F83DAD6B96E22773E4B0A1EE2C4916E9C07C0931DDBDBB251F3135C979AC8B81BC76AA46BF932EBBEAE2303E35E723B7C90C48B61811B210001564D4B9A58D18C46E58B33D70251699500854BDA27C1F58DF5FF692B138C1E8A42504D83369BEEF19CF466DC78A9FB69FDD283BED6E70E89693A083E577F628C099AE38065D38FC2FA9CE5AF0289AD653A3C4658CD7A65784F9935CA396451990CC56064933D7A52A5A047BF87C551A842F5BFC0D29F21DA27C40771B86C310B7345B5A9E29F99960E795500947958ABC2A22A166AFCF6F60A4564E5B00E3955318AF13E10F79268992D58A73C3C17D739B2B1F3ABEEB1EDC560C2E25C846C31BB644D4E3F24A07E7FB23506DB4D8FBDBFCFF61FEB010A02C004F33B39D99EB602035B190950E5F0AFF31DB5B603B1D578E054AF0CDC324E2D4AC1753EE363AC120BB50B70FCA0E7A9A30569A701C7723CEE90B3E25299D35EC97EE34A8794D730BA79F249D7366BEA5B6AFEC2B3071343198B3077A3290957F89DA865C1013D80A3B1CE9A09B282F989218DF94F15F675A65DAB79840EFE887AC9A15CC16F1C075E6C7941812A77CC8938BC46FD8621DCF20310FEE350EBF4C07DFE758" + }, + { + "tcId": 32, + "deferred": false, + "seed": "D85D7C2928288CD0B90D7269619F8D8B4EB3541F7E084CDE0E39CEFFECE9AF80", + "pk": "C105520234769BC75FD0F4ACD281DCB4B43E2406041E50BABC04ECA333DA1B18AF77A88253C8892F6EBFECE56F0433C3E0D5500CB944BDCF554EEFFFCDF172CE264916F22B21D87FF3ECB966F0BA2D34A36C726537ABFBE2EAF279D740B4AFC1D4AF798EE5212C7B6AD63E0B14A10AD15C405F2C159CD98FB38DF453448473CB86634080F983B1309134427B95C48CE4D80933A4E8C20969AE50D31B087C3AF9E2E5F189B5E92221C7A699B2874BA12319FD27F1A96BFCB603752C24B89E02EA863C80E5D5B906F5AD17F8812FC928BFB27C168D87348287C6112BF1C48569C719C20586BD825FC4C8CC214C8B8ACEBE8C305255B078035919D22683A3CFCA6CC1B02EA3327DA2483791EBCAC9F1884CA45F16FC2086169856819AC7F73EE4BF3D1FB334AB587942021FACE990AC71EC9C938AD8F9DA7873BB98C195FA477E6D66815264068B2267800E7036E955DFCA260102D9DD90849A603F2504CC142E3C0FE2744BBF908674370FEF10374554D090C039E78558F178412F65C59336E8D5351AD74D4BEB2E82C1423AB672B58E9D27B3DB4A39CA733BC6F556AD171B5302A9D93A194296AE78F4B3591D85CCFA3E75BDC7D59A080CC9C42004C3DFAA70492F2019213B72837234783A11F1CB88D6A0E35C1CE3D4B8AAD793FB0E16F10B32DB641DF8452583C8059270FAA562A0A94D250304FA03F6C445EC45F6F5EE7E1CA89881108503FE71182466833FD09E6229AC09CF285E86D2F755DDD58E6E0B4250898ABDE89C802B7F1D8960D74FB9912D156B81A4E9C9D3DC052DCA9045E0B666A85AD6F334E4EE090014C3B2D23E902757DBF78FC382AEDC9F2EA122A582CA90907C1BB3987AC70E353FD45A3F819931E53FA1ABB705F2D143065CE7BE38AB8144DFE1248B9B69C2367D377BE5588DACBE8B572540A0E6585EFC801E4B03786AAD9592064459DFCCC3583132DB9A8A500A87684981B121B6635D5DF056539DFB063BAF1B3486A4CF80AF43E828B8C1A1B41C9822475048C91281D206E056BDC06B1B8865ED92FA5286F6BBC00014A4F3F28A2C47A609AA667174BD0EC308876F0043193F68E3067279AE809CAE4DF6029CE44F836AD611B27DC35DA4295F1126903E681F5A97239F08A2594768A91D01374C403243283EA763F4D23C530CC383A6E532D70F9B02C64847394C44285C20591DDC84EA24581DA5D98FB248BFAE3E66E20233893F89D50320E74473A1045E0C2A540F0797456C6C121B3D2F5BB94809C0FEBE8FFAB8D9FEC020ED5979685B9191BF509592F1C1D98D3EAAFB0FC551AEBCD53DAAEF10B997A46C593C0BCB3605F58B8847AA9DCA8A04F3CD980825F8B61055253C4DE89D225F7907D9D0D3E9D5BA1E3AB13C3E3AD89BA579B28F7D11FF0C757DBB8C1653C1C28F39649CB19AD2CAD524FFBC21FBBE58A4CFC367BCA0863175567BFA73A681948C462AA0D7146307988E3903C9971A81BEABBEF66AD382B69EA297B80422B480F0872CC00BAB0FACCBA788941D4374FDFDD56419B6031A1DB23A5A4A7BB0B363366AC5DF5A75A72BD9DD57069074E3AADE3D154ADD4743225564BABE2E68B1E0028392E23A3A4B8E1ADEBF4661F64191DC9F46DA8FCD5B769C06B8349C1C25090A29EA254D9CB9537662D339108D5B8C7D5D2B81524ABDCA3B2C5F18EB38F2751062CB30FAD5886D287E968CE885AC1631380DB84A304C5ABD351F78261E2A4F42A9A175B87752485C984936831A7B8012746FBDDCFBFA2BDC0DB4FCD0B79F7E652E5D402AA7B640EEAF8D607AB02021DBD0920EE6188ACE856EB0298F6C2DDEFC46B4D5A38D4B8AB9EF29065499A0A83D5F319C634E281F54C7519235AEF1DB1963D436E0173CA7A7FAE1B54303067D95D33EA9A25A94A490C55634CF4628061A864FA25E6E22E2E6FD7D733B0D1996C4E47190BBAF6E4578A81B7A1704CFA07951F61D8023AB3F1C5E173785F974D53ACF35B3C66A99634D2DC3A8C404247A51134D41A2161C4A3D0E4251B0579A9FDF7B3A7FED59637BD9F8A68AC98BD5B1009BAF290EF5117D6FAF7C8DD87BFC21FA226A9B0126F35BE6694D507695FDDBC48528C104DFB00662DE32E79E0C132FF9C08FB5EE336C98A93F7115171B6C2B3269E3AF5690241A66645E96799ABB45BA96CA3F558E293681A28066504F3B70943C99A465925906FA7CF3B820988DB0356AEEC8C9132BA78D212A33576524812CE85DCA2817B3364D68670EE07329980CDA3E39D88A8ED2199D55F5558CF7B817739E618D9405BE4B8427A3793D8DDF359F19A9FF09B2E2BEC22CA7DB34F2B22D88DF8CC728F5DFD167294CD22B144788C97CCB5D93361E6B74B072191BDFF77A6FA78F3220A47924A3D04948FFEB146838006F58239496E4EAF29C66ADFCE9724090FACBDE3951C053F42F34F764EC61A1D3A8A113CE2D5209A071BEA934101A571797F5C1C0194B9C1FC3B6599AC9C4790D83F55BC1875347F3607BAFAFC4DF2701DC07B68030A693BE88DF3C0372707318402801BB20CE414795D7F250053D0AC39C75FB68EF64EB419FF859D89A3C86C879CFECE9BAE38941F2307C920F1AE48C3DF72487AAE2BC63FBC20F165DD1C22091392D43EABAE0A6C4FDB3824E48548310526AD7A74E4EE6D73BEEBF13EDB38A59D7232E14A3778DF9DE871596C32F0546A16FBA37C16295B69EE997641791C7F3D5777F09AF55EA3F65314D27785810371470FA5617CF2AE06818318A0277474984", + "sk": "C105520234769BC75FD0F4ACD281DCB4B43E2406041E50BABC04ECA333DA1B18EF9BC3E4CA859E29C9AE87D9F6ABCAA84A84B20DE0894F37538E4133F557BE79C5075909BBDE7F5D579760FC0E58AB046E437DE6407CFED9CE5DD4D5E29AB04DAA70EB9EBB4D9F8AF32E0F7827F8D21BF738584C05D72BF4849F86A939718E8758445758814405066377236336162422838141762541276638856732360636423606651537874070450512230825442745831855684586351301333083575603024146601761737864228634768611208800655885828450737877205363001110217403351766632673281486707612045613182023667776367266083085712334830625737734852167672546845358411430645183583205065515383430563752021515024067500252010305132523852061423631568837802262668835487215855713274656266553465801348565243281764238745587354847434233833785336228853521530475450885388486887835421722800658106572655224626170632788231534531055663633012723460285353506035756252730815271414513036013604238484541566535734773380388840006280582113173886805271424366177715072681663764401431567346132851240273782202733172167802164088384310178216148840587511022757608251252064470305511284744230376254058476377274278086212488134263172827505611528825772601057638282760062084248067366371506358270582646651731160837361726605566053122200085235782558202084671262280830376814326676177807216075382173587246317674115285874745625236467814027788077336464042438520155042207346565724471747218387263118251375556767004053380182005875423780068363181661642242542646383023783342543587832154174778867365514222838388050642140134550860437148533084783344668707368431437015074670186306765104170870588047846213541524414736145150241215537864250374007845472700883417116237873657100750277242403235832704882353311545437405684075044150771571660005121055388384687305874147352600277663431646864700661301872840663534130204184605151861678802848543043027112104621511332255801120370470314425616558471472110733484223773623516535806637808681554467580118184582804154876801541184062762533732181015884585322680581165844687268617606655544276240638067611886232388527868508066182130307666322465628720528384531681113858304217150642806020144620080026852272610816183175145551704480131107232330465767126775852210875576883641346622737681600741174706303221251408630641587163003138713755442054141327080413822046600263640713611635310468722133311135012064031401143771510032260820885658416866680820730365314128654311255766615845301470057467310803472744450477206372254274621747370402131043815278774511034112778031445315048801015187323248127122555821044371482802710874843188101116516365815731456515676384256760350158471615247286366525363544813275860301445876074135438836883327838320860533654243487313251171802278742026065607171267878685588702652134688634745721733478005842454053488684540346456381110877324404284677613573082782065301706732632677347535583500558363725728148105342685468251370277036362661674818553152823343661441735136803538852043417412770322111347850373120404206488162576682561408525683855506861223536747512321018852123356208573123754682321451266335483743432708612575374514747037003725505244127842514108713422352781075135017606254307364886354437140385584416227381884E738DF38784D80AFE74520CBE851F26E4100D19105EB33B399D0F6165349133CE404E2030F5CAC75974179AFABD7E4D86FDE3830B6B1BE3E413814A2A06DE211380DC4FCA05B008125D64A4443FF3663725BC63345E388CFEDC27F2EE4C8F8085870C29E360B3A695C984A30C63511E479ABA406A782A2EEFFB4B6D787F867C45D1F6EBED522C852AE8FA4A561906B019A62E654DEA793EA955C6DA7ECF03261947EEF8FBA2C47BFD27A3314B46FA227D0D2798CDC22BEFAC39CD11BF0DB030A68A9CB8C33E7890BCA2AF77CFED475871FA7617E98C86A5FF711B1A4F6A68D2D29423AB4A9C7C9844F93E90F3118DD81198708A1AF8017B7B8178EE2117AFE34A2847A97592B9BA517A1A54FE7CF4BA360B62A1DAEA0FA6ACCCC1E588C46129F8F0BE8123C8215DCA2091E8227746F62C7FBD2E0C4EEF88497C185CC912436F45A64724175EEE4FEC4605B792E336E3D457BF1891C79C9737153C9339544D59BE170FC0508D96002A7C70E2A2E826F59EB661EE644F1FDC88469D851A9A5114787EA6C29A3C583A3F15D32FC93E0FD8D725D2257B8151CC001E681A51E05E26BD4FB60E39E2EDC1F6CA39E7E55F8FE1B24CB959B44A55268932E7DC18B5D80E97182AE3E1042BCC32CB57FA5648DD6C8053AF7FB0CD6FBA70BEE596D9141AC92D626FE36186772D75537BD37FF20BF97881DDB831E9B3D1CCFE9BFA5B8E5A52DD3703E5E11459C17DB76DC12BFA716458E1F0245C9B177E341E3FC113AE2B827544BAABBA5DDEFE017CB3098BA6448AD135FB0AF73B42090FBC3968E9802BBBE9C6162BCE1F76CD5516FD323B415ECF937E97CA231A64B7E587E33402947A9D51CFF658FB63B529FAFCE3A6A5CCCD13DBC3A24C08F6ED0D2B218571340C716C4130925D9D0307645633CFC52E6C38FC41215D367F414C5C123B1AA87DEE2D91E5980BE6B2D1FC9F46AABDECD0A7C189803E287CDEED22C683ABF3D4A9E1925B2561BD880CDB1B92E2A1C6AA4C33EA39A06FE4F358B73A87E935713745FB8632CB52DA1E46DC009BED11FBADB6B917026134529A72340B2BFFEC7184B0EE9E5CE7558AF7EED869C884448DC3F7FE694F1529EC766EA9B5E212FA217AB0D6CA1F6F99B4DBC7F62DECACE5FF9F9197EA29CB99D3ACD62AD709ADB2399CAB425AD994DA40CA7BE048BBA952E7E0C9E41EEBED32E0A4DE84DEECFCDCCAC70F270FEA91BD399D24A9E0EA318888C3D059C7230F5E8BCB616EF8D372F34345F478250512E313A828143B4596892F19818DAD08BA3CE4F8A57FB343EE0B7A750FB19F7C598609B6EB01EC54C571A907411D72D5E04EBE8FA14574622764D7B1C087FEC221F1ABA307F8E9316DB1D5E843526657639E60FBB7A8A1707656F1E6FFD50D0A2B6C900462A2A93235151B6D3EB32F75798147D69CB2D55D48C48F68DA83B578A8DCAE89C480520DF326CDE6C92367D373E473FBFFDC81054E8BDC470690B1DF0935A77F004231476FF2D6A47DB802593AF5CD584ECA26AEF41E6D8C94C552481790F6EBD50D48C142F575E3B5CB5B3B9C01EE818BBABDC9324E5E88A842AD90743771E4B542D468F7623EF77BC0F330A71CE2F5F093E3EE3B4F0DFAA56088DDF128AE9953B0A5AA1264DFCAF098E43C77D5A2C4BAEA68CB34507BAB46C516B06F7DD0E9FAEC5BAEF6000FF918E53D15E4D8FE7828720F8608BF2DD2BDDE7062F4ED9DA5C547EE0DC2B1F4B9035E1643D5A9868ED871DF630A007E1AB95B8A2D42ECB35C6059E162B7E2A04CAE5BF1911C1D01508B96413E4DCBA4CA62BEF8AE8613434621EAD3A9C5EA09F170EC59F7E276B669E4E133DB5A3E49EE89C98D3223DDC2FD36C2F14C03D51300991D3EB9AE3E432C6119AE978302BE54052BC4871EEBF247A79EF131E39ADE8020C61BB07D065672FC3CD14F91DF7B3D48340456EA9FC42C3D5C0AAFDD3F04AF870629698E9AD9F5CD9EC8F3086B937A6DEC7619AE58B32295037DA9DEA0DAF9EFD6867DC2E045BB8C38CEA5A9E2F32E1129D29FA3C44590F0D25D84B851760EDBE3EBDF02263B5B1AB4A3556CA3A66483A2D415F261E03CE40620BADA221305CB7E811EAF8FEAB983EF9463F41D23DA60B7D737677F7AAD8831C81BEFAE0088322C9481B841E0268FE919397B2C48BC6D4828B375675EEB0BD41CBE839C9225D92DA70958DF89269316F263100671FCA80218EC06BA6BE4DF202AE0AB204C2E3C06CBD25F160EC690FAAE53D977752713DE3C6140F828AE24E1157BC6F5552E306B08CE3B3445694A7CDFFD491AC58A2DE5C0544369B9BF6FEFD1010633BD19691935BA21E31A2BDE9E11EC2ABD52EE99EF84E792CE7D5756925A58ADCD522932E8C3DF4A7BDC1E6D45F0D32907082DDBBF5FA15D1AB759F6B1E5622592D6F867F0E680672434341A653C9B435551AB55A1990061A8E4FF56700E76FC3FD715FA2CDA54D5DCE687CA17ED530B13F8E100306AB9A5DFD3655C3359BA4C20933632CA2A00004D0B8A6C4167B46949355C1379FA6C34F5D7A2AC4D3C3357C3B1C14D7D7D66B520C80A39CA5494F2B32F9F94063B1F6BB20CBDDDA4BC56F6599C343035492299D28D0889D3D794424C224DFE4BF48D414151662942D8269879DCAEE5E924819985CC88F49F1D9BBA5829579E823F0B95BA75BEE15A828EF9B77AC2D08352477AD23D8EDD2A0BF64F2EE58083B2EBCDEF0DFF4ADC99C2A809786DC4E1E12E6CB6A6BA15589CC627A11C784A944D255B8EA82D48089451FA1DE1E8FDCE437E97F8EBE4D3418CD830705D1B134038D95B8AF89E0B851364C8A75874FB98E1914783556D1A81D767E5A346A7EFF827392A0CA0680A48BAFE20394FE98AB290374776D1CD314127164338C2DC78FF219EF6DB244BB73CFDB3A2272DABA26016A6A82BE03A50E970CAF008326A51976D717C121B22D2196582DDE1CE8F226D53BC95572DE85B5590806AF84589B7D608E6485AE2DF98538074A56D5B15406DC95C08DBBC27FBF6534668D77386EDF9A079F79A6BEA49791E55E53391B2D6A21A394BA1FA6FA9955A500D702624C8A26992CC1454C5118814F959A3BCE54E308353C2252106A4679635A1692E160EB5C5C028EF93538D082D77946DB74C0175FB07CC7D2E98C77E674562DCF316C7FE27DB9B95CDD3AA13857CCD3107CE654EC46B39143A411D4A30AC43CC3203E8C1702CF30FC879D1647C565A0E3F204D87CBD8A3DD7EAE4D3339023B995B85204E8EEE81106B8A51F00C8D8178DAFA786BAF1F4D236784A9C9B3C02976605A820B9615D1BE26E8F43421E49AB558B07B4A05353571CD088B8CDF1F7077209486B9A3176F5C934A5A3EB79D2E60FCB687DF8BE0325681BC48ABA956D006BC0022D6DF92B14456087DB752C4FA8DC5D3A7ED18EC9A5678F43AC498D1BA6C68F1E4BEECAAA3DAD0B6D5BD678474A21CC8CD4E188FD229243D08D7F853F79E4EC4DD73599F826DF9BE380A60A896DC2490918792D76B7A7761452A8C839DEB25B09BB87CA360E" + }, + { + "tcId": 33, + "deferred": false, + "seed": "62E511A6731C2FA10DFB5F68A538CCDC1BC578C16E7EFFF458A82627438E78F2", + "pk": "EF51EF72F1C3E29FA159F3AD631E7BCD3C593D3386F4EBA484DAAAAFC94C774D810D2C97E964D54DA11C0B0E1525D2AA06A90B4FCD30ED22106FDC449A3405398F7F7D3C48D5B8CE2BC01AE8080D7530F7B37BDDC656F530C58EF169451340B9E77F1D6524CACF35436605D4BBE69DF7041209DFB7EC91250D5F81E8E18D1668C46163191F96C81A82989633577880AF1E16A4F46A7EDE15AFC9CE8123F8881351422F69B3EB258897CEFF699742871F2C2A9680CF8E9ECF81AF1B5350203C7C6893D02808208092E2976ADB732C9D4F48B919D61580F19EA0DD6BB86DDD200CEE38D631BE40936D869C50D9F2D44537B1C4A6E42407C427B41FA05B65A12386C67C0589E2741D580EEFC484B46AA6C5F7A588722F6F6A61509E92BE36992DA24182D50A4344FDCB8214A1DCE582C1763FE83605B3C05AA678868CBAE21F168E10D585B83A0D815ED9C4E82AF259DE6C0334C6BA3613B4D909FE6425204CB344EEC4370F171173BF4280D817BD3A60D8C6787A0567A28E08B931CEDB65E236AF33EEC1F40D8F5626649A9F7D94AA3A92A735B33BA79F755B7F0D5E85242F71BCBAC7BF03EDC47A7170C62E007F2C0FBF62738A4C2B4D4DA2A3EA1D297EA7F0C2035ED2D73689389C8E2A8016BF17838144983FA4DBDF402380E2DBB34DCEFE65FC0FD8A66439794ECEDFAAA71D767AFFE9D9B5DE20B5F6EBD276B474547537861F4B09BF224CC0244EFFC27F77380E90D9ADCC9F51554566F9C40096E4F922EE4AD9E0AA1E3DB8B1F1067B68CAC4B5BE9EC9B055194D9223F2CDD7C1CF244CF6DAFB0BA08505D009B0D9878B555681E32D47D056139D415366AA5B7DAB20333AECD22E661204F6AC710FD8489E24CF4E665ED1CC4CB6B38A690EB5B44EBA1F664C7F3EF4058A07B903CAF36EB5D53FFECC16D217623984F3AB54696AF2F68B3780260EEBA27FBA1C968B8AF0CDD8E3D53FA9D307CFE3B7885972BB129876CB12FAB77918EAA6D4DE61E4038C3791B9D56FD46C7EC08F2CA37AFE5E88B95A55FAAA3A0A014BA87CAE8ED39BE46D9E3D59D25C48A08AA1120167B6D03E7B829DBE1F53B3C626ABD9D971CB096424D66053DF2252E01A53D6DCE5670A0BDBB79CCE9982EC044E8F2EFDDC47E90AA819FC6D53C63BE6231278F15BF5BB295C775C72E77F26D4E24D8EBC88988C08AB1E4A89D62EA91A1C3C66C102736854B2A04DC4CABB39330960A34122C9620DF3FA99A1326A2B6E56EEE28708E6C1E51DD1B442AC0B78EAB11A887348EE2ABE3F1541FED4B7663FA46B6C17FBE2DEB0D2F0EDBEFED39C07D16495FEAB5FEA1B07ED6FF827BD0D34F2063745755CB0009660A2099D9CEA2DB9AE6B59DB696CFB7082FC585046C03A4861F798638CE6761DE09F4112C52B4DF752A34507469FAF20C302E33AE7E9CCCAC61123AC80E2B7368D68E21B14AC237AE3705A4E039EF57D6A93220C644C74EA59B565BEC30777AC494CA92887B1D460F1D6B0CC153201948076C94847453F9AFB845E56E6D8D5D6D4C80A1D90032246989F06FD556D4FD8268A1221E1825EFF23049724A686C50F9322A2778D85CC368E80402464A578C98810A3BB7C73FD347ACCC742AA20C096CCA8A9AA971225D78F3A5031B828AE7E537BC77B3F956648F29D4198CCEC25D05F2CEB0FF38792B727BC0567FD1820C8FA0D4C15B3935597090E91B961BC2DC4898F184581CDEE606A0A8F23BECCE52192DE1CC9F2047B5D28BBD8082DCD7679C923344697B737BF564A2AA5372BA50D245E80B3CAEB8B615767B7B395240D844711B025398A4C2E35837B5805BC97E4C36E8D8ED45F57FB4CA404F484446304E5A548309FF4F024CDCC27E89D38E1E4E131928DB431D0150FABFB2ED4A928B167D1E296E68AA860EEE76104718B00340872994B369C368410B30D427175184F5242107CE1B8DE0AB862796D637ABAB7BF5E62A4730C8810E3CBE109A6ED835D66F9D5C192632CC1F2CA69F675DEBF82B3F464DE1E5A22EF221A87B6D8412296AABFFC87E86C1EC25BEA15F0B193D5B8D5EE58FDE46EE76DB19F6EFACECDED8DBABB62DC0D7C1B7B4CCCCFC5D6BAEF0369C16959C7EE04AE41283A187D8BB83255CC0081EC18AFFD608002610B168EC1FEA21806835C183BB37853B3F19C5121AE3670648E162048F248BD669EC2E9F90869264B7629DA97F8A48985D59B5E317B5D41DF7BA781564ACE32673E4ED2C267429BFC26C03DAE87BF1AD04E600B8EF12881D00AB2BEBB88BE9B80DB3A59AD91BAF9567D3F02D38A84F01AC9DF8A6E6733499448CE8891A7DE203660F064CC3C3BD9505FA9B0D4471693A72AE18E35F52E218629BD7A92A3811EABC1B3CBC78F36F1209CE73D536E9BA3539AB3D6070F493DEA35C9921BAD86CF5CFF9283CA21260D01B5293A85982CC7B257B007DCB366AB842BB2F827AE1ADDE271A3FB87B801C47F3B350E46F15AA15D76C12637286BE088EADB07A66139FBBF4ED10FE023D758E55C2C8D890097125F4608EAF88B33AB5D72EDD4479059A2813CD074A0E34CDD75D13084BED9E7A006371EA1E797BD57DCC737710DB399FF2D7C40B05577EF13B8FA0A04496276BF54E1E6D1C3F9868DB83F854D22B4CA511348C1C138BB095AF9D9295FA9ACF1E34FC3E153E0DC5E3FE6C26732B91BECE623D0C0A75EE15F3EE55725B544B88BE6D7D29FD77C18E063696AB7DB9C7D9C7728FE418E0CE81BE10AEC7F2650E270B60557CB36A88D18F4", + "sk": "EF51EF72F1C3E29FA159F3AD631E7BCD3C593D3386F4EBA484DAAAAFC94C774D8543967E2BB6AD85E15A3179E43AB6210B92C397EF2A36304015F31F60DC83520B3E2E2C7B7E3A652EC0B51BBD31658BFAA01BEB6CE0DD16703E8306F1421CABBC2EEFD701D60E5F2072A86796AC63A284748DE25B6786D7576C9591BED5250D1121664437027712683823110134744782325716701825326106281417512402562610760774070343722070662367530147028781502758603157256305388552722426744506877140170222115755788830108151370532112385248757273210600417046550866454217847036112165217026334580616264266850007412410034322610722874412460415117243752444301602835170505851723667537487687808834221236561731042711113664647265734388234256740808277021024657346336844647180827423804866772028353351361670188658044347366350218124262267334435473855537211130380776088281881551766412145021645553875408724137851647668330658315135038267670382522043487733486060561457458043303027081056283277024535724768402670634777386227288035465267040734338784170132363651088253345304861706644881714370321243303456008237433072503686580630655646152582141715035716673665747140801705080317547517185862266481747431722632188065665210410582248202410334706237247575063208513068542270135344480624807537048480257675722323868828523667548614484014178247848124228773143444620546765572057224808221064011331533864761613330733788818550157340764213234637215043534188225246248281740085824730061387131717516063000018352515166156772488565363385310845267712035500857213573868153280775421661767877171368115267572412817754047622165670213137627105670022861852722630553286872248723225586151310467404677764356827417400515120767731720865132638665281483360808157072283037470672371102636515325400318878128348651077203370773663621888364417646737251134728117508742145812273038200087512187114012422063043160048858500181257281883384253120871138472364018411544174868763812527841472624285482785457751546051004821681781406613433481252758641876587085482852562232237523732553411565212412604250652414531618530613526624881737841718756787780272121431872321183822088511353210454732244658312661582133328744116472840474843221621543832313310685346707326357765544520442308307863180375243803077277353233600485441327804771085561221300415863220114516267846385655746223526784608523021285328004700858523753543662754344646814246060073571775452627175168743175130112638655838615286783432204861821730783716411812363468715234157311333307828807358242827006155513883707261038435330521613355045286071466437258168088086533315463186611606788828853586717026080606737676270286022426073737051117462454068011642116863107044530477611414484156003044801451425172355417510241275561626552532775433703464354358238878657601860456477867740546616006031482073282787538313203724131644133801723168488715667283314218312128313170507635704084481126205514816851386454877547178307011008511063001268188821288520661657308875484062782067558134202582486678183064415640006521703113811861612754566427581001647120348066328787758180026152053480046235012435117513720852020136141848740456316226257681303354467224068344155288562637885645005055251476280088665121557083876761876614184437734187175A705DE4CE30DD419A30FBF87F172F493F6346DD3FA5C18C5F5506F4DA575F7E76A12F54D1483FBB94D05AFA2EAB6115DEA5AD6C86943D11B5F914174530AD081E5B99D3630652BC23534C4DCB5774AFD15445075AFF50D97A93C7C83D80AE7DFA051EF731E3DA1960CABCAB92596054E42B6D3AB9D4324F147F3737792EA623A4047091F692A02F11B46C992509087B4BCAF1A3A5B961E52FB08C28331A26A7933BE9F5285A6F49F617B504F31D822F8A7716CDC23B1D3742DCB3C5E039A9DC0C049EDFBB1A615DE470B035A0CC7E15B6F1EB7A92F031541358234E70495C375152ECFFB86F158172A0C63C490CCCE17318386A5EE54319281EE85E53B6FB44DB01412AE8E8172FA3A09A4907B7D8AF2202801CAA448330E8CB0FD28048BF01201ACD838C30FBFDF7D01626574287D93078A0CD752800B761DC4FFD79E997BB1179C67624A0BF3B2441C9E266C78C07E99F788C55A4694005F8505191EA20B3A6C41D2E6AF4ED78B9B48141F498425257E015805244D88AD9F7E7803EEFF88EB2C74D940C7F4F93BB99CB6B582C0940D412787081003CB9BE3F3D2974FB0C5211B8C7746F8C66D0F5DB018BC8B5DBB4C5863C10247083B3701904FD7A498EA1011EC87A31D3F22E3637965DD63F564717C737CB9EAE48B00EF49F3EE4D875712DEAD9634078FCF28FF19C3DCFBCE7CEA5744DBB1BEFC10CD4B01A3E818C244EB1330F7BD35C2F18AF7789A2040C09F040505CB5036630A7F3EDA0962B2D5DC590AFF47D6F1B39C4073F5CBF139D865D531828C8FBF5C0D5A2366AED1610974BA8651D152E2DB71D5FA7BCAEB56B9C0A73C1ADDCD35DA6828FDF652F6E92A1A0307A3F274A9DD3639402774BB62AF2CDA387854450E34589F1DE919852DE1E7FF90C58743E29EA4402E64E30F75C8329A5EF95F66960904B245AAD166BA02D685589930C4128A95612826BD06999A967F9147B18D3E966C3A9071F709671B9CB6847EDE93AE225C70DFBB4623CDC0066DD7D13788CA2EE4ACDCD857B8803C01CB90DBB650B324AB2BDEA62304BEDE414B4422F7610F113EBF9B7E137681F209AD1774EC5D6389EB46C736D1503DFA228B7FDF5E69BEDA7901F61F2024D9699A28E3B3AF085EFF26C17B962D6B340CAA2EA1FA927F273D676667A1A873B60607E7CE4EE1739D334321FFDEA839B9B9DF69D621BF1DBDA580777084614623500E3315A570ABC6722CFBB1E20B32FD410680D87A789648E00A129FAB4BA628C060DA271877425034A52E2DBDE5720A333C3CBAE2AFF7638D3005553CE6C69456E835E23B98EDF88D5037BECAD644EBC0413B77D942A73B47C87A399E18144323CDD51ED50038485D144344F56089ABA4ED70B8DA96A630D71EB80CA91D410764A030AC66BF04CE2A837A345747B1BC355B751A591B95974D2C7065D14C8DB475ABD6061A9FF3FFA4701119DE5075CDFF32DE15150222DD9F6EEEF8197E73FD6EA63C778DC9341FA9F312945DC20E8E24C607512C501921B7740179F2ED8DE976AE0D6F8EE5D821A3668CC9ADA6ABFAE60816BAB6E67DD74AB8D3C271F0BE15C583A561ACA92A7CB63F2BF60C0DEE6DC87ECB3C0C1BD5F16956C8A937646595822DAB1CE09B1E194C77735A50F8AF265C630D20D8612A3080B2FB41EAD3977D177AEF12C2498DF63EDBC91A1BC2929283F7C66ACA5CC4B03D9A410043B8003419E1CC5D09293D526D79304ED589AD6EC522D10CEF80FE742CABC90A82A209EC4B0BDC1E202928BE4A6DEFD6EB37CABF3574DCDF357CAB6AF07B22416E82722C5023E96CB6B518754ABD8DFEF198474A37AFAD1900755BB1DE56249D3C5BE147954670C91C4BD940FEEAF275D87C04D2934BC71214A96BC3502448156F5B4F3DED83ED55149DEF3CF1B39F43BECFA1ECECE545111A996C8B6F46066F759C8F307C7ACAA31A1823F27CFB8A0FBC4E5A11D6AB0A180E78AE4FA0DE073200DF8717D08021B72F1ED67089000F5694E518FE3C286610E0C18CA312883F5BD806CB6EA30F4BAF513FE183FE3109C43BD5BCB42EFA5FA0A5D6FF7EDE6CFF61DA65BCC6EC78BA9A35FC2B05BC4D3255A19C79332F80AB35177352A6DBA730C6071099F3DD56D510A129E6DE2D38AD6895C5B917E22CC6763CEA81E8B2A88172AAADAE3600A911D34A0AAB6DDA0374DC776FF50CAF62801E2DAEFFD58453B27E2A367F24106E35D1625936D31E3C26AEFB9354D70417CF264BD5B394D5DDCDE1F90C20CBEAF24323BDE3078395CFA5D9AA74F1E97BD4628B190F480D717823786C3EA5B6C0F54ADBB0B2DAC9CE7B1CDC6EE67B036F16CAFA4D25F6C74592E535302F8F3FFE3B91476BF588CAB45580CD0EB2C421183805DF21D51BAA4D6607E40469A5509AACC29605F64C1E48D4FF1E91674E52CE9A6D5043380580EE746CECFFA49B6DED160B70B3C62C43A233D6F584E554EA5D791EFDFF310A7F5225E7873B26BC5283495CB1C3C2BF64D868B85D463ECFDD28B6682F2DF7E57840F535D95153F6AFC2BD713228D1E9FE546B9C65D665CB01603C9FA03BCC4F8292C81F7195FB9453BA15980BF464CE57999547175981ADA808847786ED93460A43627BFE051F15F871B38D02C9CA224AF4F90E0EECCD4B2DE7E7AFC950C2F770AC94ECED9C18B05DA5B7067D6A984624F800982F89E6E0385DB626203F958392B16E9A86FEBCBE65231E8F3EF03AC7DEECD07543C8F8BFE409C3CD0EB88CC39223366CBAEB968EADACEEF97C5C7FD24C3BA4D97C898734C767029BDAFB3B11419CEA7E2E4F913B85333990B5B0F794E86342797D8ABF0F4742895A0D93D03E43DC03722FE38858E00976981C555DB0B708B3089D344851CA1CC42C7F9DB437E6F2750F21FB4243557F70A591354621E43712A047CE2F8951483719CE639A50C951E1E7326A7F089D47E0EE2BA28BEA4204D8478237CE7DE9482FFC1A8B7D3A56D4022D159C5099A69DBA88C71DE62275BE5B1707B4567930C6C3AB019585998F5A1F167737265DF9F1677B9AC771AD5A1E3F460394FDC249918C1911668D7464786293AE2D81D41C27EB0242984F922AD5596BE51C31BEBA3B9C474ECA02A440A2B4E9F4767719A92632285D176FACA6D06DAB7EF77B8FA4BA88168A9802912B3B2B3326FD1CE0A1C960CB5A197143F547B657038140C79B7CCF828D81A9C1D4FBC7F03FBDD2F6EDBB163FE0DB9BB9B68ED9389372F0D767FA985C573461A5F246AD3BA30BB6C90BC205C763677CA8871BA4682939F64180AFA9CACADF68EC838B56E6A71A952C8769299C4CF572B205BAE167DF5FC183553C152085B54FD5173BBBEEB615BE96E737C5C1A52FE068C71C433B512C5FFFF769DC2132F94FD7E1F1ED296A061C63F8BDD401B76E602247A109179EBE7F47E7755A21BAAA0F3E5118A3440CFE071B1A3D998423BEF4BBC48E2C172F1BFF8A5FE505016C9270BA787604D29DB56EC0B953DA5AC54FAF7505FA30516A3F060E3894DEB7C5ED8175493DB7E246D87467C2021C" + }, + { + "tcId": 34, + "deferred": false, + "seed": "BC4EF6C46CB18061966CD872D2CB9826B0220173E42F11B451DFF93C0577CDF5", + "pk": "172044F0965950FBA5280238696E84E25AC1A1911FCE85C13FEDCBA82879572CA7CF41D9BC636574F8629CED228AE8F626FEF7328FF39DF8079AB8C24840B1241920B4849E57981DDB978AB5B4437EF87198E91E20AAC7278EF115FEADC43E58F9C0F135E7833D289A4F33738FEE0DCEA8B50DB3F0521C1C3C76987A7C82C0AF3C38C59AE1A888B9397258CC71340AD2886D98207ACA566A30605C4E2E545161A9BCE5488870FE6C48C13B0F47E5661A7409A6C5A568988C9814FD2862FC5B1A690841478F579BA587598558C2C07E988614B7D8628FF00798F57CC1440A0C5163156D490F3A3390D4498881BB67A58964B73826446965AA930537B55A701F4F635A67FE975838B59962DCE9E020C77352929FD327D0106CC0160B3AC5F63252F85C151C889D096C942939ED146A04A44C9F2395CAB0F4399E1F603FD0E3E5D4E7FC1DB51343425D8CAD80076FAB19E3DD33A007903D12CAAC1673FCC06C401E8315D9603CEC9D3C7F0FBDB3D00CC2B23E10DF63A9E4B2D3E0CCFEDDC5DA1C2207A7EA9A0B81D4878A7CABA63E494A67466A401D1988270F6DE08608C304EF6316B74B39BA6EF4D5BF3B66E297B275B81DA2DF24FA1129D88785D558C3F79C235C8243F0FEA80018DC6AB8F375EB17A778E349A87C7B5DE5666D17E41154BAD3C5B00E5B07CBF9F46CCF1759FCA574BE7257F1160F65E9695EFF1FF32F92C386489AC19B3322F30214AE8B008E342E21ED559A035299CB6733CC34B2C2732BC3A3A5B5C5E4370CD940FAB60D9110071DFFC23831D984A446FAB028907A71A423E5D22A073F069A2539195F1CFDDAB21E3B163D2A1A3B16C749C181E3E68EA90E1C2E98D64661E0830BE2E2C967C0EDF86FE3E0021C6B217367C8D0F3CD28B8BDADB49329DE289EB3746BA459AD8B783155FF8C151ED791DBB33BC6EBE60E6985D98AB003F613674890E1FB72CF2FBB11EE24C2C3CE6148A152A4B0F44DD890AE262D53B0A5FB18C748BE880B432CBEC5616FC0AB592B9732B69E6A7C4EC149AE75CD286D133E812D94C262E273D7D6053007DE2609A40109EF7759045C601774DF800222897974438D6CE98884FA79C99B205F00C743452710BFF448AE9CF00401C99BB75DA90E7D99877282D1CD6C9165F372ABACFFB6474E94E7C9DFADC925B7D7F14F2AE043A0B8A75124C2152DC45310FE37036874F466E088FD22384C798A486E1878E784DA4C4BD790C972CF118A64F176FE8A8F6E565EE26A293A4593FC80B685AB615CA5BBA86BC046C413D9937D544E9AF7F23C717796416C56401A0E68043F0ADA7F4C6C9E2C257F36580B2A63F9A6D8961EA4DB955739DAA153152B8D6C2DBACC52B24BE9692DEC785509A23C01E1969C1A6E2225CD3B28F93439174C104A24A6258C813E74C46FD95947D8AF64D93461B6AA50136C799C140097C7D8B24EAEB87BA50E73FCC8DFE9447C228DC6438574E21A23BD082146A0E617A439BF81A9118FF3094B8D794C72EC7ACEE9E60C24E151BFCA9D51CE368904AEE0C608DF45FCA8C2C536A4F0F1038F280D06A15CA43FA836DD54F2A2235C1AB14621F8F57F10ED45814249653F1DE0FDADBDAB1E95FB502DBE85D05047E7CAA8C4C6892B421F2678C8868F852A51F0E5BDF82F776DD1FD40DCC4404DB2CF4625597FD5FB69F10806866334853F0B40FCDCF64A02641226BB7BF4F33CF8449CA1921380091F5255DA7968333EBABC8F9A84F6F8C84041AD2FA7EB9C80F95D874A860ED43980D7597E4789F8A69424DA042351EA9D5B19E5C128F8C5DC505AFAE0956D913193D1453EA24FB0D8AB64584718A61B447EFCE208312C475D2074928DB96FEE1BB910D06DD6CC3F474F4335EEE418BECCA71138A3B435787B4CDF209325865676EE3DAE6AADE50AB8A075C4EC28DAFD308F53028A5944272A9D2A6F199F08FAB81689786F08312EE0AF4AF1FCB0AE0B693627C1254AF89BA8C1F2613B1D5D46C0FA308AF2372248797CF2B3AF9CCDFEE69DC21B09BB390D4B2AFA00EE51B83065ED83E4BF1E60C9CD0B79E5C7EEE4390B28144FD2FFBF03FDC97A4AA39361B9EC50A2AE3BF8C931947DE3675849361608E171BAC9772296BB218DE9505544B50D8BADBE77959219A611325A3F6093549362F07C40FEAEF71B25A9A7F928A001B1180BAD6B4C57BEC8822888EF44BE1EEEC17600FFB00305C877379815BFB09CFD4744B4CAF48DB5E4859A476C198B4118B48AFE8176948E837BB8E54289F995C4900B0E8CEC41A6550876BFD950E5E3F346791C4AD110F6D6C728E5E58EE33E47E57848C7DB6CAC53DE450CBB9E1A679D2C74E0FC8A01E0D2D9AAE47855BD6C1864AF95EC834D229809ED6D3096113C199C156A80D10EEFC8FA3B41BBD23E5BE9E618A379160FFD6578D158B9E04790248737A43FC8999D25D549F67E194D992E63E51DE388654C3B5956626443BEACD55F433AA07B010FAFE318B5763BCBA9FDCC17C88945FA5358FB0DB345EDE62FCAC8D70E59E3E326C41944F26E6E9414AE356F7011AF46C21CF051982F56E1269BA3286BA4AB4142253E75FE6F38EF6E43A708D7F12E18CCBFB88B31B2DC2E3604AE8067A29ECC47BA2A7EAEC61C20A286FF7C2ECFBAFB722120992FFD8DE17DDCF8120A77F5AB9BF66E0ADD0AD97444EC43322950FA02D746D4182D649A6407D5ADEE07D215566860364DF3F554F784F30390B1B4D942148525F7F5B253BBEBF71EFC2DA6944BDDE76BFFF42B", + "sk": "172044F0965950FBA5280238696E84E25AC1A1911FCE85C13FEDCBA82879572C29C756D826F40EBE63389844B3856FD107649DDC3AB99121F9B5F658A25B2BE42D2B0D0AF78FE1A314C90B3A426395967DD3BAE3D5D1029DBDE410038E39BBFAA7E20FE03217656BFA7930D08F4BC65E22EA8FD2054D1CCAEB3071650956921C8818383516546652345845348341062226750117678070784570688375188710570177501547154781433305500441388730375103588405375867617654308866302441600407576855334525682615663181476154841163774257413648636855878347220644304842024115888285246226138068538618624402515488050667520351648113356388605656772231715728008745145588726836117405018742345584424117700018427422172663251250586644286578757304668042003246205338202634818086486123301785675071012243767856118835760130687363568514152268258478147501550424740841243831124168575576778672513600028474115545671848450525620062025268211708511303805861272607274170036384165863223506451565485030532523838221603121287121258746072176713758303632550312407040655188220360357083342722457032075015106782627515768051832500124057822141806717818130204348522116668168451131021286034235335052683755014564880081527078434626244324244510065258144513486042326238540065740028287018174303318278605860268612373017402063473525711430312023244056812545442844100520001864131458455054357850851616055356500742453276075824111777566866705768584830046800321427826811111278128707133771780512815062885416415722083566437861458372806671084678275584322766418754517617566503460016327270648231052836222025133383052468854188306714172464176800512243177780687715053575280724703280270467263745336412286256741502851718788040761600037416853226678306578787264856847665327562026070278647542104163834357747751682268186422832211685401007454675858764182640437071260473443336570828403305146626232784033300107168103446217346137550463081382500454211446123826604371182686275337146882401545335814524011776880487111118424037210424342370242086353287448665040282354413775244701060055434041608100180153521065422144718432411453616532145776130503005125174035851250505745133537151673466754538347058334505557141046336117404485764114821312541582861414507838063640842508474877435530016238621821578103225262201873646007042385113361266433360344375647126042186828638601077581056113382282548525480625002560854472737373661454043588228486646342684336122607353740480842165545624654407006382410124026814128213476402880362710601084361726087002868561358056824863415583231157101337220888846877801156782588770147556680432713113728653328533633450458645337136485473234337704500632556522004715764426011055020800404283451041078541112463436778348678102033630286016710360132806074553635343634681186558240305064843460704424377205042621258166181681515748037366075414103086201016510622332567241352646460736353614088313652185275227160484630482480168165272140537778813161341883025552377040525524854466625216273363852012381002677764353275847134654001617637546856066738302850036854362132481856731425248733072822146707717830226726020857302425511116774864817318644468555074138657504402057020263158005116668616551570538040051435731622821807634486281403783750583701308338531138562104F2255924EC380D004EA05A4303E25E0C1778839405DCF83B74FD2754CF15FDAA6DFA98B2637DCA46E9DADFA726EA4AC153EC7DC0CA42E86F26D03494E5206BD4408DF6E7C499B5919869C447963748E4446F2F0C38AC7DF52BCD04070490846041583216B2D157DE1051B4E55FF75DC6A03BC20895978E3D6FA56F43CC5C7CB645D97C028894A25FD2BA8592BBE355E903162615150CD05416835570F12F5A5C9229AA1A9D7DA3E4D2DA4B3F80979B944A30004EAD2A590228A828C878F5176AC162892F11369811C7A5877771A00C47EDF2473A4C01B760FC2598F505B942C92CE8483CA8A3050D63522B7D669B3BE2C3CB85A3BC7E618935E6B72290E2570F719EFF0FCDA400DB8A7BBCB6BD66BE529B200FFDACA580C0CDE827AE11F2D920D2AB1A55900067A4E3C0464C80F12A7BA1A0F7E8C796BB391995A439EDA1F11ACA434A24BED01DC28CCF448791190EFB864A094D564B3D23005A492D0D2F1D6845472984C8C0822822C9E978F85F9E36E38BCE8FF48E3B485C7D6888BFAD21A453DF01BE666A4BA5AF49A1922BB368EDE947E12D4AE08237912699731F33AAF445C8482DFE2AB567F7B3B256956A800CEA10765BA7F10D5168AE9053C2A341DBB59290437DE92C05A93036857A19207821AD6693DB7552F22229CA392566E4A019BCC21F76AD18EFA19150681B4EEE85D1292AABA0A6792D1514D4A550FAAADE32DA084DBC9AD9384B11D482B10F8FA1858A9E558383D5ECFFD75238DEF0C09C9CBEA14871A310FB813E6792897B5054FA56371DA801EDF8AB1EB122BF4A2F01A1511490A48B8339BA9C6DE477750F5FEB46ABC9E3DADC5C667847030D4A8CB532B89ADABE7F2809AC03C4C88B09313901B6F358B3F9EE0E48428469884974A726EA63B675E51AF76D4ED98F2108CCDE6C639473BB9979AB51DF674D1A65F889B41D9B18DABFB776BCCF4791DBC901A24FD9EBC2FB2C9452589CBB629E681393C019E35F5D6BDCBBCACAC054BA8656DB830F1881FFBCA556B0C6AC73CA5416ABD5AA4816F5BD277DF79D984A06CBE50E4E0AF9B9B150099AFDDBBC907580B09745FD335E006CA7F61934B890BEAF2B94F52F99BEFE94811B2827006042254CD2D8075A0B34FDA4B31E7420DF4D96DB803C0A62FD802952CFD8E1BD3048540D1918E52666E185A21564BFC9CB42AFBA374979B139555A8909DC7BF49C4B4BE6842C3D692C67188C169E10AC30D5C988165C33DFD7DC21269D276F1D3FA22C10C9012A5C8A0C8423C4838A62302094CF3A213C5721087AA6C43E589C3B0FFF04FDF91CAEFD1498FDCEC993ACB4659935D5D90BB5A709704774181FE001EE1E05A9DBA1251115A79173B1C33895EA761F0C5B6DD42BB06E96765D8C242D457A986118FAF8CE1F089EF1CF293518E066410EB04AD8EAFFBD0A59209E2053B7FF0C2E221A6F27CF8F05022BD91B0AAE3C01ED28B41732A4D89CD55F7D491F4E431C40A83752D470AEBB54EF96A630576E8DA05EAF5218F8C09A8D1F3C80A90DC77F15B3B44CCCED6149ECEB7569EB5ADD3873D2A23133BD723F71A2AA7B0D3E2EE1CC75493DC0361477AFD5E6658E9787CF117243CE7C17DD8B4FCAF65B3107AE60CA15A8C5FE7A9745E27EB4674A6B55539B445843A2870AB67BF2AC6F80FDC5B53929447C6C0A4B42DE8BC3CD22783A17B5AB083B4649452913DE9E9B5321E86544BD771ADAD0BBB5417213E3FA62D80E92548A4AA7518E2462B08EB141B98FF44D6B4D7CCB1CEA4552B75AC71C1F4D10CEFB20A6C703559F26899DC2693FB287574455EF767BDAD3D668EA8477B4E5FF4E263C3C7F50151487480D7A6C271412ABB763748E342CAAE563A2B2B421E067B275F709CC452D011B2AF96985275C1CB1945172CD2019388894D7C450D5A1DB83A80771456D9D0CF16FE983086090DDFCECD8BE9F6AE66CA936FBBC0FEEF1F73DD2C19F4ED1F1F2855906A2EE18A100B79F1C3FAC6FBF990982B0139664C08BFCA09277370F2639C5260862AC4C7D03B7F4E48EAB9DF4E9050F67A50FC665B1022B00B0E7635D9462EDF1D602E04808DE10A0C123DC21C4F8BA28A94DC1B1EF5F070F70AD18B6BECC8F9A529903502AA982E974A6D17FA57A52BA878508713E7BBDF882C2FA50FCD0EA27F54E1A5FAC2D4101AB0D6F3FC3251D922AB2E3F90F8D61598EB15C77869B32F96D364B70B609D9630E8EE18D71A4A05A0767DD2632ACE2342F037BCC0D85ABCA48F10E3839A8D727BA55A7ADAAC526F63A60775743E06D61AF9B9C20A3F10DE2B8BCD545C3296274751AEAB66B7A0883CAB9B07D48A24CC567AD135BDFCA30B61C47AE969509F34126EAC2FFA5F2DD08984A23430B7ABE4FB7DCD8A6EDFF1BEC22E7801ACAA855FA5F3DEE21EB1FCBF9204DD2586F6F78F775B26856ECAE89C80EC645372C7B21036591CC20CCC96F92E16E1C36D4A0D80F8ADF3D8BA6D2536FA67A5F9FCFFCF291C29200F9592D3EA56F85ADB431D481F4297085FFDB8F669E523EB96BEF366DE05D2DC8FC0485977FFBD719DC5CBF4BFCB3CD191AF4BAE90696DBF52BB25D164DE472A64C57002D434A1C29BD379D72A4CD86C1380BB8132BAE06620DC219C8E35D0B042CAE54B32358F68554E34D55275CBE89E9526D5285818D5D9907B52AA21F34ADA8C74576C46CF25794CDFE19AB419AC44F3B05D0A40068945F7564B17012499D0602B4A1774002D18E4F7DFCAF3E6CB035776704457632913826B64C71018C4949E7B97C4A31E042CAD3D25AC3B47E540D3D0DC6491BC021FC56328E6300462D8820EF3D9BF7A40FE779218A0CEE30390A183F571CC592FEF2ABDBD47B3A72F1E779815C0787FAD9A4D5F817C20E1CFC2799783F09DCBABC4A4692538F5B8A8F71172A738F947B899FD431B6C82673F78FB88D528649E8FC794A1D3A89E7C3DB3075C2C3AD5CA00539BEB10C4FD6169A05836A3FD524405BACE465D0AAAE4CE9DF3836701CD7914382C27E73CAA08F1B252A4B7EAEC1C861CFB443B28ACC5FFD0058E0E9BA4864979C7EE56A42E0070CD18B74340D92A83DB40276B1AB57F84B6ABFCDCAFE227C08415700B6163B7D57EF45FFD23BC0DCE56F1CA8FB58E52BA415A58B87A46078F44EC0EEC9482E4E032D61512BA21ACEFA846B408856D64A1D868EA98CF4C518EF6D0F9CADF76F13FF1A90EF4B42B49ACC0FB61EBA9D88A51D6F9143C3713C91D623D173EC0BE6DCD11B02B2B7EF08ADCC1C7A78E262441D6D919E3E3AAB0B61C7ACD6C5EF95908FB789D44EB01E505F9709CA1D47C9AFBCD88806038DA554B6CD3CDBF274A8E0292D9B451ABE590D7F7B8B32EBC60848AA5C0528A8DD435498EE46AA7E89F72AEE8D96A590B5FA434FA4159E190C4A668912C80803CADBA8970D57EBB2FA73828F955754F81F2A3B5144F891F886E74D3F2604B0E6A2537F491B786A50EDBC03CC756C89D59C7A29E372AAB728FCD082A872CFF573D0E8D0C6C60BCA9B21627651BFEF05975499BBC05B2" + }, + { + "tcId": 35, + "deferred": false, + "seed": "135DF872744277E90019BD1E904DCBED63741D863E82388B61A2B069E509B25A", + "pk": "60F19C2888D3332957F177B055ED15294B33E36071D56CAFB5318FED1C8C590596037B30546386F06E9FDAB6AE2E88BD93633E9C27EE046CF437994D9FCEA1BCBED601082DA3973209A408440CDEC12AF383AA23DB274E7393884CB7AA4672AFCE26A95511BA62CF43EBFC7945800D79CFEBE0C41FCFB7A7F1B11DBD5D530BA969A56399E76EF1E8244DD225204AA140C71C90400D0E6A99593B346BBE05EAF414AE396F169911754E3A631D9C28644319BD4BA952B7E935AEBBF0AC81326A8FD03EED551623BECFA9637898091FCF12FFDA8CC2636C1699909804FBC6050617F4E0454A45DBEDF647FCFC47F678730DE0FC9B7793B88125DD22DA136105A23FCD1E7B581CC9C8D62204472BC2A8F8690543812A157AB1D3F7C3A8380BF7724ED623B938318CC45D1D8B907C460E1516192BE22678A7B508477EC3FFE1C2F085146CB921012010F82AF16ED8E8A4185D4C77A21C1A6DD6B56E0721CA1F701B92B04C9429C460E04C02E07345D6305205E21DAD975783669E4EC89521FAB64BDB3A31EB76B18C33F81CF39D5AA9BF1B19F819EFCD38AA04EA3DE374A6E155F8457768DCC6B7E14D2700AC4248710D527A60CDA5A2DC3CBD0E74EB82625A1642CB80B7310A230392148A4812CA7A64EC7DC9ACAB74C592A1CEBD7E4DE2B05953B3500AE2586B4357A511340821EAB6C8F2DFE6576487C93C47B4B2B76EE0C96552EB31A5C4415EC909F74C5BA9513A10EA8B54ED292D8D76AA92CC131BE5F3FB10DE22D5480D88499EDF7C3B265B96DD9CD13A8964C6D642A10371D69F6F1948C203AF1E321CE53C48AE77A06E2DE4B4CC942E9563E94B75BF4284E7EBA1BB3850CFC2F1E9AC42D7AFD4BF6D7F99E621EF640AD2BEBA85DB0721CF550AB3E2BB3346B36C9D13E34D7C9FF5FAC1EC257DC2B38122855C5A762CDB08FC3DE4D546F2FAD9B51A3F6D5D11AEC965BF60B834175DC3DE02431B2A82C528689BA90C735DDAD72BD930939EA04E750E33BD3F94F47D4F39A60E0EC2B30BE74CF49CA04B100F470B8AC60BC47522064F540F9A5D0F57D19452C02F0BD526D17E86942DBFEF921D82F343835288974D4DAFF657D0D53A08D1530ED85A50F8683A98D98B402C67FE58879687A39F05192A082C830365D577EF0545D4D1BC183A2EF070D817CA4CB941562B4487B4BDCCABE417567C6C5DFBD09F512E34CF996A3C73A5D2E1ADF8EE94B255ED8EAB9FFC7CC5B1CD8D213474BB1213E47F6F7B040C77517C58CBB8E77F5165C590691971EB4587FA441410BBDA483AE2E92000D2C96869EA239131039B672D125034926D0B31CC481EF36CDECEC45E3258791C520A185249ADC4E1C946A9214FA6D29F264A07FC039737DC0A4B0FAECB74A8B539AD875C9BB2D6EED2DEE6B69CE2E12E1E92F3F0EADA8A64AF5933BEF893C0D9AB0E4A19B18A9EB56F7079D7D730C1695BEAE4821CBB97E3D5752BBEBF6666194695BE5E1FAD0ABFCC280FDFA1FE2BB45F371F642C93EBA3A0D7FA69FCD30AF866B1360A8FF6707C54504EAF05AF44D2F41670033460009A8C7156B24EAFDB2BEF3A2FBA97AB039518EB8950BB8E9D07D5138AF47F43058EFD57AC450E7CAF54C275121BDAC4C2AA70CF6422F7910B01D058CB4806D28C55C69FA3FE7801DBB2C62BFB86D7A0925136C4055FFDEA8F47FE22332F09A580CE44DA4311CF51EA68495D69079A5C9C8FB442E7681A021A32EB88AE12EBD16F91753C54A56435E5F244F0C2CA4103DFF9AEE7E780FB423BF148C9026EC9E649AA80CFC411310C3440B5AB6FA3605867751790EA9A54E053C81970B3CC5CFF5FC000261616524768F7E06034B55053EF0B7B24C52ABA0F4A40C56E7BB72857C893AA25BF97761819A2EC8B9319C8B8F55A8042879795D06971EDB9A63D85D2E5839CB704D66497508A8628AD4A7B8C862F965DACC4D9BE011EEB5C46CDB6A2AC03C6AB7C72DA20889E6EE48B9D6E84E2ECDBCABA5BBB7CEF9DDB7B97286185283809E6D6AEE4189AC17BA586A274E5DA9FDF56C0C86ABBEE67525D27B15E08CB949F8F38FCA263271B5BCF92121269EF692AD7DD182B917E50DEDAB1B8C5A42621DBFC682B2767A4C91E1DE942A660D3D1F4E998FAF32F652C68C09D4C6D278FA8DE215F6EDF6E254AC8E9A8A09DC43E93ADBBF8D9A6D5BDFF52A0F9A57CBF07B2F1C2690B2D4D1B92012A0062CB0D39C5F51E1357A3A9F2B3F063A194BD68D09412DFBEBB39A19E0B6994392F9925D1C7554456D0D633549616D56536B4F6AE1F0C6F2991899DA65BC1B8F2913F05B88ACBBAE77F7BE27302EB04789E605724884525219327477E4BFBC964207408DF867A12C8554216DC7F0EDE2A74F3450F09719965593AB620804F6160D493437BF2647B17AD8E9087FB9ECAC796362B20C47AA45F5F0EE2A3320D844E78AE6DF61597E05B25B4EB804161678C180C70978B5DB16F0532C524FE4644507A178A31D84BC823241390F2906E2A5007D9364CCD5E332E65595488F65CE00C15C33B5A7E0D2AEB23BF53C953858130287B021AF19FD83ACEC0160129166B7CD39305B32029423C9EB7C1C86FBAEB08302E8E98783DDC23DC2C88A916F061A17A436208D565B2F29D31F38881CA031EE00FFDBA53D5F27B1CFBF8959138D3935AA2340CF37F8F1519849A087DA12C3D0E025E33EDC19022911C7F78F49B1D3FEE3F87250E38EAB61B2E607173F880B9534B370ADEB83BF9AFF3CAFD9BEA06878E66DABF", + "sk": "60F19C2888D3332957F177B055ED15294B33E36071D56CAFB5318FED1C8C59059776BF0982F58C5BF8760131D784CBC59C83506E9C37073A735B862A90A1351FFDF2CBF21F6C592F36C142E7372741317808CED0E64E75242A8CA167DDA0931C12067EE31EC05CB5D76762ACCB588D97F885DA913EDB932FD9EFC597E31C8FE7483732182417476267842312383478154743246465608704018564385702145640032387477480015217732076670716666467833626011865105780352472546415744556138516780087816437287418113876478510168466361118214334241670114075453510780284573135100347550388577701188017176163033247283666855118737431883475501656605683610738528276807102471644770484440320781171351481611644187385155343613247758636820584746160088566426010428203244046441730233448316034754248183573334761217257455360176028465830788381643240768766280464653231063260878410470574307373316874208716171123303817623837725475353711451040420210541882572050248682047242423200011856287765407446474167417575752066354152702022122578670844232737845641088335275415401011387716361864551521567112453813325131754308472287050122011151372646414852012325538044287833806555000572835360174353656765502258874142856141381211338024426087777686324317468856134168305145721077050524706654710068461234873625832256211720256300534682510444126505380610114274108128652105757116102101610027146353055681174423780414631814766604742016505380053811753008368165204378032838721314303164347700288275788623102537480584471452714476335173848668614437618187610552480265653710132536135642551212270583780386871528154403781704407403277421066170314475687213210526636380221070102627478732365161434256612014823302523866118448752603774022243324574346365536516014470447434451828251230234262820774158573160724435457606050617288264125822135802242853578238058441418124730762135158784477176721846631804675433384776456172658806162800784657603315350128042358401711706737852082571514521858816256047683653501611414232632543716484572216533733465564646410787800711631308540481036537622137273362580821460630373846686536351643184220531260100470718632847612280013042337373536221652732260400271713866033384882613587553853154040621820351770001324430483350066467206672766355051513856777165413015284625031416666867715458402036710374272215323506650536575663454041153038824213555822740826103470534308818637830853622438247348816776304148463123075133283488484062036787547713120366474014578455581134567708113412242521388135757240176263555784173124460318616660500408413380503574433416272072522707577581862022240481421307758281540872888122804243684675014071523047532418622155330485380820231333301134246558278003026512810705606767804263084124781578616637246768362221215416245532858754872782888871325412358451314080488111481442478110611135071715543656513067667176448838086323467381317537420507301435855664835265066015501051842518277816662454485756187478822648427083443138015222802362876282417008521324004255156877406860744830428285413554573067703281106187011234434728360065728454415716563261413046158800686358771553030874538582228413307033286145140814246244015884017253404030718260532684216764132301055016015132773621625305843836355723257172476645626154671D230BFB6EDE64D1F4CE65CDFCBA4F8B6167127DAA9CD1A3251479BF6BFD0CBEA010D6D3EECD927DD933C6784BE30834AD1DB0AD5B2E416D86836615051F434DB116D8388EA6DD7F7BCBF7D28A72489CA067DBD3F478010F9E1CE759D5B1AF7A5FAF197533023B7C05E835256D849C1CEBEBF17844F39E36D0ECAC807874050C8456855F01EC40AEAB3884D384E2A12F0EDA8AA841E8E0B1C5BF11E2BB6A29E8444BD802C1F460405AA21E7717EF90739E3F7661BC8F0EF1C66208E66DA244292995889158F64819551F4174038EF3C2D60B98EEB43C53BA96056542A215055432FAFBE0E7A812F0F685E24E66ADD8CF09DAEB92445DC2FBB144176866DDFD663238E81F668AD55B4411AACDC07811BA48163C49056F7B442BE8533D9E3A2B83A057F6A996B6267CBB9433FC85A4DDDA41806DD8E067765C29721E6D5A1BB34A80333C199E00C2E3563F9F77185CD100B4A2FF5F1F97ADE70F1928CF198E1298E35161CDCCA9B9A832F4413B732FCD271FAAFBACBBC9664C43FB4C24206365E7FE7C5E30D12FFFF90A3064BCCD44BC8C59735CB95CE2A91D88C0A635E419FD0BAC0270800109644EEA88C36FD78393B42384CA9B58EF61B3BA9EA7EBE3FCEE044054FC1BD24FA70C71243DA12B338AC7461C39661CA4F2C7E9529AE53937800BEA814BBB2324AD2C05785920AF96834B994FFA29F8674F30E2DC5E502E74296E8B5B731B53DB9AFC4497C2A7856D23E28AE1E78D957BC73E8EFA29AB3664A3FC27F5D9BAD4317EE47EF6CD1B6077236600C2767F7BE560AB260D07C6FE184F7B9D928242D269C655D7B896B859CF410C2C61BD5E6E5C34531EFC22ABD9B02E21887BF37AEC7B4B7B1C7AC9BAFD050CE93E6586916BA766F4AE1EA035B0CEEE4BC362CF87AAF83577427C8F76BF36D631B72ACA5575F48D293F451F66F11FCE6F725C6D2DAD3C7045C2CD74875E122F14B3D988E207FAFC198CEC59FBBCE70C6AB11E686B5775CF08673DDBBD296AC617326D3BD9B1DAEE12896671CB0546A7F6A74ED11456EFF0A74391136A5866F61A5D3FC6498CAA1ABADEB900A0C9C36931A4A25987F25E31E2A72388D84CA70102409168C348AEB13833BAD91281CFF1D4C76A4D2F0747448E8F5525763543E2731C97D506F826232C55C1B85C661F5FC726EF9C2E8667D9FCE4D3386081657629CC1658D3BA4559CC0F0290215BCBA010CFA280B87D23BC79FA094B3CB4A08157A69E3BB41B009DD5354D2EF5C0C617A72853533A24322AC5C85BE8C31C3C8BE7A71065978006D5867A3968DB01AF0165B12A557D3B0BF8B44321F948F367A5E3A5BFC9F190F26FB35527DE4C06EC155607E377789E2203FF48A04F837BBAE45E2E4A4F049E181E2249F59F38B151C3F66765130DCEAD1436BDAAB9A4B813E6B2D418CCEDC699F126321E429CE9837B9D00FD9413AE3EFD9649AD2F58D0BE9A1682D9105769C111886B68EB0DBB6B16AB16C9578D3952D24C03C8E6E43347121FC1510952228FE16CF87EFC1B0E6CD47A01752DF9AC81479C7434EAADB137433256ECD2D9DFF8C49A68E758AC3594A0C06B84A19393935C4F6A894B0E90D7166F2F65734568CB3F837A406A8CAEBF9922E5327D5FA2D2BB98D63EB7359E75FB836F5D392B25D32997DADF301F8154F320DCF941D309C78D09722E17AF06055EC65F2F9DD341BE705134C83BA04DD32064CAA6ED894EDE02B81CB33FD86056B40F303CC4B236EED3BE34D4555C8F51E8BC20866EC97BBD57FB754956A1E52F371E4287886AF8152347589BCE15267BC603E9E707A83D14B0AEBA6E94205BFD62F743CC4D6C401FE1E1CA130872083A039F7D3B52CAC89A56EECF96BB3244C4CAEAB615E2A45814ED80A153EBE5BE67DE0F87EC8D48A404120D2DFE26395AB2FAD1A1194C89A0AAFE42EA15B64AC806AF8BAE70E770E73491E55122303D0F0A258086033E6716E58F18519C13B13E07B4567B8057C06F68C6650BD7225DE1F8AFC79C0159CE5161652A10BED61895AC2495777CB165912C0E24331A21B6F4604E8D6F689E06A1EE856968E419FD01E8E36BD3A071F21F9B4B778859C0C524DEA1E1F8EFF0D92DE8EC7BF8FC5DA396046CE9966C198B0B1968EF2776C43278A0416DC2904167CE9DABDE13D82676A8AA9579564356774AE62F4A7D86B43AEE8EC84B3FD55445F1C84DFFBE038C0D5899AC1BFA5CC258AFA4FEC802737F6CAA0BCDA4143729F233E4AFCA6B243CD21B44906A5EF8F2A45698E91C23B0F3BD7BB03548BBDEFE24900B400F5DF27822C2434471F460DF2118108AC3AD2D7CF5D5D824014546D29D4FC258088B2EE8601729BE1F2C8509446FA37FEA4BA7D057216A14758C88E75D7D72B625C50B18BAED848BC23B28B775007963C010B1710243A455CF3F4F2D90363D4E50339B990C449ED1A26E95F997CEEEAEF283FC98D59C172F0CC9127B564AA488E3B18330EB1F945EE48475FF1968E0C2DAEF0F582EB5D0184A983159A894687674ACCCA811C570B5452492E8C79C21F8373E379C5B189948ADA6099A3465003F8A1A3F8D89565A09189E8A9F86186EB786C4491C728542ACB5B333B0FE345FFBCD9E0069619B04502A06ECBA06D6C3D9BE70025346A4E879C55BF000B9FB374716DD20F41B91BE43059AC0EE454D11BE599FDE39386EB72B6E195365D061DCB06AFF60543117F7742EC0B0402F398FF1E3AA7777400108C2230F266F27D3BC29C547FCD0C57EC098CECBBD10E12CBC26BF290909A62E6D359A823EDFB728E714ED8EA40ED58FEBFE6CE2316D8F294CE3C9EA68F08091659A99B3C12F4249D931ABD465F8BA18205F57C46BEBB5F245D1F9F29C64F3791292A8F9DF9C6473418AE055351962795185DD60555BC277C8A7155172408F0B99B78D43896CF17755FF5200A7DAF16112A93BDAED173A2BD934021C22F25AC6B761FEC2B992BD8E28F1246670472AC2A2A76B2E15F336F211E99912520728FA86C130951A26D456C47D5C51B8322208A0944704A815975DE32074DDEADF567B9346DF1FB066F687354828D5BD41A0E3FD2C38EBBA74010BE647EB75E866CAC2C8289B3A097832EF0B2FED44F6AF239A7556027C41E7CD42B18DDF709E75E94360C0B404060CE057FBCF1B6100E2D9516A91B7F7546305A447C2647F76F588ABD7EF3CD823CB6042B59160B8BB1F14BE18AF1134C8959A84E25C1B5C22D1BAA419D547107791E1CFEFDD112C9488A9A57DDA15FBF312DB3A122F70BCC5BEAEEFC35732070465309D2888B65848DC47464AD50ACBF88DA25384240BF2E3D4FF2EE4B59E85FC47F7127814EA1C014B127B1F09BF09FFAFE7E748EA504B6EFD20180329582ABE04EBE4E20C7C508C32B2DCA0BE8E01E80F21693EBF250E1FE7237BF04C58E5EC60116BE1E6BE90655D5EECDA10D59858A678A7B137F82618A913096D3C479145D361FAF0E926F2D9C87CADF302A950DAA88B4F9CDFA66B1D111C3C9B80259187E78B2C0DC3ED3D6DAADAEDBD1865" + }, + { + "tcId": 36, + "deferred": false, + "seed": "AEF72BA72607B5D3E49C579752BE9CB9FA67A01B2E8B654EE92177BBA596066E", + "pk": "A5BDF0F8455F85CC9F37DA908E52A9F70DAC2C1473306439E4F3051E897673F5CF4217CB02FC3BBE5E08E9A257D0B22F3CE939D6E809C88560A0847C8A51AD8C6FF596A8708CDA9CE65190FFE3D24B457FB29C88F670803DBDF7042F8A07A2CECF2E8711F639E561B84AA9357A6C403174E942A05919B4533E28BA1F4A9724C1455A82FAD68762CA8EA8EE25A024961D1991B2E4A5587D2F48A61B00B348B059A44A41E44498DBCB2026AB577083A10EC5A527E27047C3ADABDE815555D16CD092ED86C26863145C296C9523DE0286328BCC16FFC27D7A2E5BED590D20B77B51FC2D5646DDCD385F79D03E63AC83B7522F01FD1A9B5A7307B5D6783006E935465DA875DF5D53CE648B0F570F5646E607CA5D226E2FE06451CEF35E687056AABFA25834F69275634D2E223B2814848EBA21EDDD175C895F66EDEB9A59F4D303C873236FDB5C5551DAC07F5693117C93827201B56109C398A490136D67501EEFE48BA2DCC0E0DCA3E7BB099182AEB71A5833A258985035D8B19AFC76B622DAF4F5A441387F069A6CA00F4077D22E666E32A9953B34384B950FF2A9F4759AAFFC066BAB54D6988CFB35636F2568E76ECD41BC6823054C733DCEE6AB65870DE742A4D61AF0FCD5ABD5210C40463FAA984A27C9E731DD994657274E3FCF55C436B8A956FE21203CBCE1EC1BA965A8E43F5580F9AA4DBBDAB65564DBCD86B1B28FE0033CE376049223B08BBBAC9857B5104CECC681A8003C40295B69E0EA73ACD0252DFF155AD4340BB95B9DDB0AFC97F2CCA3FC70052B2FF327CB4FE8AA6BDA893BA30D2BE86B2430F7A99DFE1634B98AB67327D50C366369AFACB1C842FFD41273DB7510E07CCF8C062AEE290095B3ED299EEEBC585C2BF2DCCC9FC3FED5CB80BCF8A6576E67EE732979D3D82D0619AA0F0280CDF50601AB7A6E3E3A0F62F24A704E6252293D0F2C343B2CBB4F3E988B6309A287EB4A3943290B9C82F6EA93768DFE50A8D51313443CE3444E4B99790964B7282C49CB98CE2C28C254B0D508677DC2E2F44DE41EA0428A5EBC125E7CFB3034247BFFEB234DF2910B7DBA0F4DF808C1EDB42E9234A1BE15735F0928F05880EF8FF25E7C03393A2EDEE2828B374AE0BAF1A63D266FEE71DB913FE4B404DE35E28E1584AE938F9578C5B06799DA2EC43803980F77850F4A557892DAFA4708EB4D933510770C40DB4DCB7BA4F8D9138D78A2799662990FBD6142CEE38B7CFE9F7D39ED50B4327FF111ECA523714A06C642AFB2406299362D16472CC49B9D01A6E0A38880B447F3903AEEFBF5A920145143D559E623CCD860432121B5B0161A43D8FB8280AC4E7320A412E36053F78FEB287EF0AF32E1FE5A1C1E9BDB6497E7A4EF9FB4F0A2A9983F40F66C5DB8AD972E422E2098CDA4955812C09E649842636B6CBEB0E29A50260078E3505B1235471DF74E2E737588078D8641AF48C1AC39CF05632F80C99836B0935CC15FD80F3FE9E941E68C3FDDC8DF1CD641722288A20EFCBB09620F0376414F34E380E13CB09B43B105B3A22A4F54518CF28CD644830BCB267D18793542026A1258F8E3EC4920FF798152E054444183CA5621222006AA18DD9E42619BFE90F35634967CBED9DE93722D38D8011A5EFCA178C6314A43F12798F150FA2AA9BC9C2BAEA30008BD61E1BF257144B67A704BD43823B3E06F6E251819CEEB264383CAEB49B1D7180AEB56DCC735A09C0EACB926BB4407F4AD016346BB9F68624087A22F50D5EF91521F3CA8A68906E56761C37A5F001B0B2120CE86D1FDD86A2F795086C1E63300EF953DC5F94264350762780F703F89100653A83F9E80E3327D6886F85A6FB4A68C22C114DD54DA899008347F08C7ED6064DA26DFC8F9250DB0D33263BB5ABC997A949D845AF963F3CD51CF4240B6C2EF3AF3D0BFA3938BB5F48F0562A06CA59B662D726317A8C02AB28395C3EF958E06816CA972792C6FBC051123C1564E65C9FE5E13A8E91621773694FCCFD4692D4D35A27F6E2412B49804CE472672692C636F3DC22A2A6FC050CF9895AF34A33851AC37AC2E7A2E42D401088F119BE6D66BF6AD4B7C9BE4B65937C34137924B5F9B789D93F598C5162C500C09E8EC2E4CCB47CFD919FEE8671239A3159534FFD44711F515286F4C5F043C02B94727832F41862ABAD03EB0A2DAFD8CA9B766AE254B1568B75CB65D8491B488DFFBC6E5DAAB4F6B2910A18B0139AF77F10137026116DB1C75BB206CEA39C2EEE4A760A37187DCFC9A3BFB67A7688190D5B408B8F93404F22BCE4DCB1EB2443EA95A12495F9881E303AB7491056C1BEF4EE4DE242FB2ABA8FFC4210D9290A291549804F308D1F1E79453B8EEF08B7E94F306C9350263C2C3FDF9288E6B77B74308548BCDCAACD999B72998E6F43B037AA19746C92964EC170D8F4C45C9E276CFB38090287A1FEA8C2A3DE69F246F66BD1EE6D99BEF25D817136AFF0518584C04103EB4BAA1B0C13A09F53A5470CA0D3BF811F78524F8BB1059A6AE908959015917EE1D6C458067B0238125ECCC3870465FC8DD6FCE667DAC35C3395F2F99D9412478F69286176F842C12480AC3C1F10E17327FF41A9C9F3CA25B1DF71746E38D495AA39278EDF66784200E41939ACA3A5C6B30133FD34648CBE9E05D7F8203C4ED349F61B06898DFB59472A50C5065FFA3EBDCEA251B37FDDBBB1638B7B7ABC392DEFD6D8C2A623B5F8C6B2AF21837E4DBFA31049262A89C6DFB0DF74D4236C231CAB14926955BD861", + "sk": "A5BDF0F8455F85CC9F37DA908E52A9F70DAC2C1473306439E4F3051E897673F586D92ED7533389C0202DF540751374583C97B825C4370216AF4AB36DDE304D43D0DACA16C3F5087918EB0AC74D767F421FE3D1FBC7EAA3AACCBD5CB5D09F333CF4B78F53C71C613696DCF9DCAEF19B3C1EE2EFAF0D828521A6CE01FFA7F61A9348527342744071064226038054116606320141710221271257486326667037121338804027786413333762444565247120260711112481538554528818355348570835703121724850217680085831247330511727221071532777537181252433162511266101870334182868555603545033287523215207404240325534605842331807636112112578123748213488427847140378435253062845364733136513038331863665164167881816537665065848863257260565026575136330876105673463618643727206285030703671806436818322112274163527184354571804314504110461483305276281527585556577604221866560252247227633024375431035511576001826578516576032642038878266403868054841663872067833221181722456668288121320355140013335216064378035186542241363324612723361344715333431546685723672037350475440828822807350518723244126165140441743684004218174044766245273324152220377505024108077250427538553813160114380427476282474087652860170448374247256182540047212386666433380053013860147850648461451277375447570165767818683367627182818503143056367684131733603212447465727282433537555073853150367373683784851317615160568487055012186553755658442635833444503161210303854541265435850086145313831714057147057120854520605228538737665130427538038232223511606506354232283180315487066067657113311376130525682787352874263703354678684763224515801735756766354734254556702053117703010838153428847256422882168222781354461343605223116617002218761072342227774472342364510245075075620557536146654153377441306448752117273127761641170377382766582167256065853886542021656228353632167205880115560215680560306250271500428858201477207883872516256244502862366650053734802237606638246801357641266043847685428523576470862427772605087355417711178011230254130776185056386880131707363610348377857813822161177008735870862408816363434033522876874245827032130687514032517084000404550331071880041411855515353347350748833163660475436163376714460516374334807032470377016148566161642212524742565118144158720586251383718220750427038855211255848338323237278850416582248665388024224073714504355652603153613411853445800308877122483607514485078628638685574852023328770115826675755280543602581333212557321868322175661562521048051805784217422803480451341517247206525267651220578854840124507450130330783180120225057375467878261257470561528834570641813282421264533224140164101541355026886165283383701241282521170736675535341222832655883108544384278163414862621416360817830726530353375153418874861316345662582058367316632462543274165056545780126454850320726117724140462523727278438211532634765078536860488641558502057617183425565211328306367418664731407825108631866633714182740052163310713218483574715351876351327521183865501355706182848758085863563015436623450348571177625576370888877313167468486714351112267202247833152524060633413850751063367135630834183838550563386607380546701865460634035501871746162676710175335260356668310562162041187655378322137251758003287138288249A1A4563679824EA12950B80F31653B5EF7BEBC201E938EAE950102A93B46E11F5123313957EBACE11D440BDC9459D1B9CDD345863D81F2FED1C4B534D0F17E0908F1FDE10C037FAFAC1E0FC865B74D15D41E1211EC7AA0EF69F87FD0F8F9CC42B0E0E827570776232D4ED86A84D1F7A2201B2F29B6BEC81A3238DA71A1AC6667AF0A3F35124133C5F3F10D7F5FAEB27DDFE82B59C85D4EE7340F84787D4EA738D16861E4E66238C4873957D0EDDCA68F884B726E10AF47E431DC904EE034F9F491208466EB6168FE6B399E5ED34E118A77DEA15BFD11DE8A531C8C25F4F73F8A35282E32094F291308B6EF60DBF7B54CA3B0F5386AD179DA593BB9C2B7A2461C2B7C1713231A1769F03FC1B2C7C152AF80809453EB6E97C8B4149A04626C93E150EF3DCC298C13A439CDB871893CF3456B9A59FDCDD6E5A873BAE7E5C778C99605EC7B01339D8882DEE88B7DE879BF3AC89910C00F99EF2E8DCFA2EB7D8FA6B5555685EA2B5350BF55633C0AEB1F244C1026E62C82A5685757D3446B756D9ACF6C049A18EC4C9359B4DB246D9B455016821EF4C598BBF834DD6FF82A494531BB5E0A533F225D068A1AC496AE8D28F08DA00DCB8209BD40CBB0CFED32241FFA1C33275A2565D1CC24D3A6BAAB228C2D8764680A105A834B36C18A9D522D0A25EB34FE00B32193DC9F976B0A23CB220A6799E4D596EFD98A71EBE0454E25E93E233191D14A78B5DB29D4CFA2435CE41B13404A2324517F0EFD5B59F714889C66DB5327045DA45C38E3DC4D8AA433E1962F9313AECA58B3122B437F0CA17B09414EFD52EEC5E2F94DE8CA5079CC79F1A11E7F968844F8DA1CCA85D9AF2759A3FD75A9EC44BE6857B403C88E69F1A9A66764CE7F92E622D963E8ADE4BD4973D739FB946ECEDD9BD829D5BCF02FB87E25DECD98C8EC507EB5FCEE4A0AAF62970A6C4F4D66FB4BF7FF735391A27DF24B848E93B4E1CEDC8B77497A8EDB73A3C9AA8B4EBD9443235261C2DCBDF5606DE190C35AD76494DDA71E9DD8EB70DEB2649CB944A60F50F38C4B6EC1E64E12F029D1E0A2D619E4E783BE3AE5A06FC4A355511F177411CBE64395AF69F744773572B5073FC1BEB8797D0508204B3658EF87C62D94EB85E991D2C7A4CD02DF7D64B6587102D4FA321D961AF7116CB37E62CF3B1AD0C3FFD9D9401F175A359D69DB9E86EE9A4255F1574BFBE38A18E94BF0536125045C20921D10CEFF864A3A583C5CFAEDC1151CDBC4C31043A8763AB3714F942DA758D352CB03AD534EBC81764D21285B10E0E0AFC28CFE72A84103444A2D1DD6CE6D7964FCB66242F08B36623800E34510DA71F518C941EB8452C1BD29D0F6A575C7551D2A208CB579F05E9F94AAB26AFE4C7484E86CD05B41BC669B7A1EA0DB9E9F581528D5C29B0A684766E7881E46625AF5D0A37BA1D50BF3F90FE08697B20C7A205362943282350E1747A7B91CD9D0358F2101F5759D81533FF5B83190BFF33443F6C73A0D3CA0BABCB4A7DE4832DD9DCF2A144690F6DAF40431C7F9FE41944E4D168474700C8AF6EE39668FE2ADA2F8B9F015314EB7C230EC3C21229EB886D37F17F9457233C055A7F4504999521EF38CC8B4183088B52CD9A8246107C46108586D8AC5EBACA4072D8639AEA5743086B46553E10A6803BD86B494CE06D7FE6AEA812946D6B939A315F7E200A7DFE2571CAAF009C909FCB75938E421CD542507F50DE26F813B41D10E67E4B5756E8412E272715764C1C097D27434E2D2CCCE49E6A4477CE65008EBB1365865ABD4F709129E7E045368E8DDB80ECB4180EBF5705F53551E2250978C21874FCE6069D4A5A51C2DD54A2D61E189AAC9247DDD58DFAE54EDB816A5895959E1BDE574B0316363658B71CA5A3B859212799DC9D1B1EE75A8163D16263D7024D03F76FFAA106E7CABDA18B5F943F39B420486E45FEA2714914421C79D4315BDADC6FC2A77DA76D2099C28D59D865850152588F33837A06E33323263ADFC75705C1EF5E0E6703999E3DAFB419BA86ED5CE3486D6655D6E320C3D43D98E4FCCD31E28CC2F51B524414562AE41647F16EF6AA763E354952B44AD5E5576BAC79C2DDA9BC2361A08BC24697F6A129CE30999A3453B3ADDA3410DEC30CA11EDF278B47A6E6F92B0C6670E118EF97138C2D6BFAC34B20B11175260994BD93D41FD44B7BBD5EED310B3C13880D095B1A73887288BABA953ED922A46A42450D377DC23495707A35510EA3D0AB741BE55E1107A439F136BC7E1D03B75E733FD6AA3236F379C7825FD5401D1217003C11C422CA7DB8A8AE40CDFFA642F76544CFF87385E7E45FAE6E68347D45A2E32FE15A25DB579642B488C05D3BBF597DE46CE67DB5EED0EC59641ED85281D5E2CAFB15A43744B3B60DBBCEE50990DA608DA0652AAE2EB1CABABB36FE42C414DB0689112A37DF8CBE831B236967497F4FA17AC452B2BD8935211FB423D415FA916058E45CF7AD447F3F19660EA9A069C447D14603B23BE2C6722A581661798A1D9348EE1CBE235243645B20A6F0584621F460D3BAB447520372F041684942C76C7CB510DE9258BCAEFEF8FF3B7C3AAB4D9C4F3FDC9952F1E4B3A232EBBA94FEA8DFE75500FD89221B7339A3C61CF0B44CC36CC17E5339137A5FC7265438D76ADBA37465E9E30E858B5C9B4B162B4769EE7EC9A2D2090B1D5CF77A86FDF7F7AB76B15988703454FF678AFF7E7D221F2A3A5E984739C214BED903A842B4DA9F29E26E820A2D70EF0217C544A930A8C2150FF41D6F1450DF4BA0C81AD2F6AEB54BD5F82612B11DD9717112F424DF4C3F27006B37A51407B133110D0C827640468B287B8D41ABB6693D7A041892DDE1D494CE08ED493C59C68E207A281F953EDD91B978D31F459DDD6BB9AC2CE212C5BF3B15457287E4B95347A1AFB976733BC848A709900A08FCAA732F6558BD818920509933E915EC76CFAB7EE55821C56804FF8322C246CD2D14B66241D0D88F1670124B5E48FC5744E4DF74F5EA51CE9FEE5C5ABD4523D88B98B12E0BEF3EC7CA3AAE48B7C3C311A8840D593F74134CC0D4D6244051AE18C44E5308B3A997711735B438AA4D2409481DA436A84664D64BE7F941DCA6C4DB2724E7F1FED95D4FCAB4960ECCF7A478B6F6AB5C7674E01867D6DCD3BBA6D51747C19B94A4F0039226B658BEE299F23388FB5E7A71493EF7C2016754D020825616B2F4810FC765A67876F979E73DFF831F0ABE6569AFEB611CA67997253730B44979FFBF105F0A06D6FB360BE8877C111D6D0FDB5D2578BD95B34F4408D7D894B8B211FF1F753FF3290E54A9D05C6A5CFBFCBA0C9501FB4441A4B9362B1537C589BB27A17113EF54B068B28FB6F74474D6FC5AE8AA7B66B156FAF6AE9954F52518EBC897172971BCEEFAEADA9B43E4DE8B074EF0D7B47800930D076C6592E859C722960D32355A63DB0ED8138BAF10DB3C235293944153C60F09739DF20B96F76A0171C11B8A704AD44B035EB9366567F9B429AA2DE76FA9C12D285B53EDD61AAA85459EB7951D" + }, + { + "tcId": 37, + "deferred": false, + "seed": "16759CE55C6741D02EFAFEF5D7521BC0D2B3ADB55088F61F0028656AC970C70E", + "pk": "CF27EDD0B90ECE6104CBC5AB296C0301DAB751FE1C6F0648469E74231A5CB309168B20B154BAF03E312224727FFD0F08E7775B2B9FBFDAA283E0D6DD20B3F8F0EFC52B971F2203B8973D0AFEF578DAD5875142780C13728B3E658F87C1FE077B39C9CD7B7F84F28948250D51D5C3875E58A74DFA7F795C2B0957C6F699127DBD0C2265EC4F9CF0DC6C3D725936B3078ACD64B7C6835D5D21FCB9CADAB91A3DB704958FF70D33C1FF00396FA561A1BC4B4B0D069A71D287FCB1CB90B369C96D88987FD3147ED2838C7C15BE066768C48955F3E1166C62A5E3BD3B66151B0291E3E6438A682606E15C04BA8F56BEBAAB1E7008391765BF0D55C4C9C7E535AE9E01FB3EBC261FAC00B483A77537231C532F453E6B6F1F4D0313612B907005C3DCA1B733CFE377D4D9AB990DABD1B85C3EC423992CF77667D685C318912CDD91BF31350708FE8F401031E57E06878CBD155BF260AB5910757335E98026B22141460CD14CEC795EB5389D025B48C0F2D9C1B19A41D730B508F0C23DF59A93C64A7A2EB32658080F546479955C410399390E2273AB80F87F28AC0892D059E46C338177ADDED57900EB14D554A0F807284CA2B1495E6DAFB461054B0E6E14E7FF9313D1EE9FF83A32DDED566836CCD22B72D6DC6E52A58C7E56ECFAF68133A8B6CFA5F754653EA2F0C5AE9D26C10631B747BB4A452A54BA96F59D339EA45DCBBC0ED32028BF612753AABEE62D59A59D1660F88E6D9E2F1679C7E4196075260D45C9C3058961F0BE3BE6F61D26C30AB6517BECBC07FCC4B06B98E7B5FD9D14EC59E7CF89A4C7E1014BD3D157F0EF8DC37139683F21AB04E9AC8C3525554957294009796B80F0E1C05FBD63B3B1ACEE497DFA493F2559379B3F9A5D94D739BA9AD4214F746F4103F64B0DA83F779D2C404CCDBE4672177956F6600DE124F820E799F69EF86EA372F49780EDEDBD17604606971E8A41BEE1770A85B7DFEA6E6B8B2810E41D8ABB894A506E0880079E093978F11F9FEDEF1CDB4CFC370CA5BA9CE0DE73811CDDB1E7B2BE7840C3378A84ED126CBFC75C209984ABE1360DE2139ACC0363979EE99449B50BEFF8B48AFBAFB27C9458C9A914F3A7607A8E8707B3D2B1615097BB80F07D83BAB83BD863D46020F49BF08F343DAEE8F320AC9424D36BBB91F3D7A8D00579B07BB7C53BC700CF771A420ABF7C656F9CDD5134B2B0C6FB53C8F93BC5C4A475C11AB043C1B0A50FA5B9FA29D5A1E684F50FE9E2E48B8BE54D7DDA7B94EF28274EF5B88C3433D60E027383ABDA44DBD1E0CA737B48AAABE9F98984D30F2DFD50B678741993B8A5B483A2C56E038046B64705E23621BB23870514AF33B36911F97D45DF2D47DB94A4CBFCDA78240C77E9F7B99710E5A59A9EC2F5C89DA2E9C927CB40C58E562CB0AC1971F92A5BC1EB371DA6BD1541662EC4F0F78FF3702CCD723D1B4FC3AFDD757B75BB44A5F4DEDB9A63A15FE399B6E59928CDFB3342AB4AEE2F4DB0DFD48C5969F7409A69DE1CA6939D9121D119AB00B16F934707D83728916086E22F1E09B80A30E3DDA76D1F76DCBF9706B3CD4A3554671D9092E891D14FFD74DF0CB8835951D0233BC1068D6D1BD766E487144DB791DD5A72CDFB5A39F0C5DB47141706925FFF615A2605CE1B63792D35197CB9CA7E518F27E65CB32617BF91A07D5D14C186A4CFB7E36ABDC8C71D4245B2D70F20B6412D478B36E72CBC2E1D44B23AB09C5B89C4725CFA3CE27C79FC2F7451DDF529183FE7C1E230097DD5AEC1F23D3A817ECE30F843BE07FE76DB36FA3447362197E69575719E80588E93E4A57C11FF8AA1D8657E54B1425B6150FFE3BFBEF5BDDD58B867CEBD10DB74B4249A0B650E3AC3A65F828582FFC7332F945E82241CFA3D25D731C01FC7601E2F5874983F2D9E9D5AA781287AE5FB25F8D9BCF73EF5576CC46AFB1076B95382D89875CC30BECC32719098B5BB95FCBD22601930D5A76660B67870F269965F6115E1771D558631002E7388C4761AD4C18DFC07C3B93E7D11257099900A9B6ECA8086970B9CD7F0EA9C1FDF0E37ED7F18F79A81EFC726780F544F4E4F6C49956EF2A70F56152F030BC73C0EE7C57AE991F7E3362115A029FB411CDE0308F2B1ADD50590D7B6110F161BCEC333C5F70A52F6EC186FDE7331A5C2EA232F91C7CAA5308E79E85993FE7FBC06930FF98AA4356170AE3BB262B22C24F3971B3092AE0C4EF033B752B17DB8AF26F660C775EEC805880E12F0F87D5E1965AABFB1D235D5DE332B177427650E0162C7599217184FAADED2CA7946F3033BD6DBD59D9B2758386F463D187D97F2CD436E789415EB50D4A567B623A45B3ED8E1E8E03242E7B85CB501C04BA6244AC3010F7FC8047DF6F46D2B86662CE0C3C6F3AEEAA5D8AB02FBDA8039EE7385C4F139D47F70C5623B2D434A138BD4DCB5B7C40965512CE283CD83B63DD9B1739B19172537C6C50CA6B212117EB2B9F26A94151D473C865E5D860B272872E9113C8399A5A150376CE51EE643918EB0357EB4E785E8BA5FF3259831D63195BF1E21FA81F36D213D7C8BB52B4D9DC17D1C592518B6B97D0BFDC160CCB1C44CC624BECC28B49E294F206073185EB1414A4B80B18B376BC1CA498A9873E76A225DD2E8F8535FC267E40BD627F6ACC8F94B8A70563E55823775C4C58EE180E3AB69E42164E3778E389DC4A4689132CF41BC3816437B97AF05C126D658386DD57159CF61124448FD580F539DDF48FC22B46B103790705A63E0", + "sk": "CF27EDD0B90ECE6104CBC5AB296C0301DAB751FE1C6F0648469E74231A5CB309D14E7CEDDC2A30311AA8FA8F33273747D84A4F0D8EE7E194564633AA61E52915D5D8E2DBAFDE6D3F5D79C3B28AD634EF193197738F18E4A676CFC57CD89CD0AA6F0E234E1EF9628DAA5784D6E88DD9BD172917508BD299439586A2C69EC9EE37516408456805453875186164354434762851144032503062044733174535345336243074007370072077081545713763660866431727740068416380203118388213565687636452870788087330528072715111223815614114023416424628572273654761365202371732860200885645176752622184560057533370811066568577508011873252658610003344817466632285818231285557473165208431105636756216358276868345764816338628113787615730106550304583831526218881611205302483650721835183030737847070762778474055733402548878760487075428407073405005144801723170186433372802720438860108856746505547118015547131122453566773381342522407281545850801183484018184666083467106168381252845568124004675454602314541338432622742687024545623154163133642142284145826740831864111748641572426058870067085812666034786330234235402238130001884155852477742051765281745785073343582078116414130602308708382046610771844771422553017257116530515834771623210643083653453123174273203072120652165461603377577853268801105230325786774860038401255212558785474148811005612536620386306604704351810446347070743027613512061524183212465467663737220484528055077682744477361738537607035114778361715572673801101334710201843154010635705268423258373218118673778880168467346108724815012616873216832455740487844547741518240111500865103473675713041381803575311157872410255701424078321127582473648431113027582351430662278746751035665641182434584325772861215525770615370625335026857551177161702753358126622760777226647078220754285585438101185067104306615265684566031171156370644844601446724773223546111143485217226474815348070603068162168730827730621315400104575240651321414881564033855112770221780800225157528348444266604837745836675662685500716522842326213800620274755378763818201620041432256675142301443166263778606832838270748825315058517802584084457456813426874047456608883514726678781223637518532315712014762086217806235541401078781766415284331567726815303634475775271858640741021524306284275220610644874785084105424161267563884428838216142316446781311233544824647208842466574102173038377413542118331143367050032021043212425764087110600105282382455268312103048345414288052540078876487667764823025775566311214818185543787576556256857315236518510021215252482803706248475668860228066666672561867742220301027605488000438235713416236536151436128508016780048467212168013085034575086368465731676561760082315388865064664006463851448257676647715152480874332803114601541422802066821101585027654741377572383658717163467081225212357315441278864346071400588203756538864216143433263515106785455401547748303686407408160384157550870668870806518373802647386257117430103643478524250667688677831215028557767150786248416665782857323615017621284673503646038567228556675312835873622053521367101744308644383425387466430243221642874703241566431377885506752554645704356662457447386007618112165350121803204124113324380005611435572303115406311786186209CE53C40AFB0F90429725B870E47031CEA4209326358FDAE2531B5CE92A42C724AD1D1CFF79DB6D07F0215E6ABF1DB5F9303B27CFFC420580A0A8612C08E1F54005EF429BC8378F59DBF6A3FAFEAFA03D9C41EDBBC0DAD976D8E103CBB49A9DD674BAE19E45D44D87BCC9D83E8B6C9D99E4EC4406B744718F49DFBB12932775C82161C63ED883BE33FDC9F724B44F2CC2544CF1851237D53303B82A6C8E2381A7B92345530A7740A6A456DF5245388726AC8C568C075D849EA225C42187D25F435DA2543E3842D46F747400AC1D566CB1763133EAA110B66A72E025082B70845813A7AD6D4D39F017C9E8CB006C11A73C369DA6E1E20B6282ECD8D0553CFDC39621890EE0110F0A0CEC2FD1220C7DFACB8DDE955E336C9536DBDFF7600A64E59B113C28C86CE93B035C75E204F0FDEB7362F598475DA64251CEBD14B95600B39269C6C5FE67462ABF76B26363946B3DE38F6A3A53C261990A5E147CB12D093016342E57CA38E28736ED4F331EE1A75129386DC2A2D8C49FE616BFC5A321B5650FE51B38EA51776D1EEBC454AAA446B1C2EE18C10690AAA7889EF9C2C25FDE8E988EDFB39273A0D180653488C1C541308305ABB2E8C430EB68AFABF503DD082D8EAE81E196781A735D990CC89E024DD22901C5A3C382960D25B076BD38E01FBFE7173997760ADFD97D94C49BBB4848DD24666AFE02AE5D592CFD8354ECDC74C1C3BD713355D733E7BF531031491F869D01037AE0336E979F263D7D1217EE11554B90BFE16A103CECE88C19FC1D9B5987BD0557AC9D09F07B0CE6C01D2FBDBEC726FA5C7712E60F70F1AD4C566733CCCFD650DF6ED846727D7C3D6C8412843ABEC36750D8296776123A10A1FAAD44EE0F19DEACF8C7233C8E456D3964E0DF8603FE8BC04F73A261E1F37EBD5DB516645F4C800186A10FEE9D9271B68A0B27EA99BD19ED87E91519F795C6A1A5F7FE26D0B07D9B618CD7153E8B302FBDD7010A03A58817D00F4B9BB5BF8D9F9FBFC5FFB3FADA79F1FFDA8A028F85FEC0A6B74019EE18CB7AFD4EFCFBB259AA3104545A64B1B6F226A72065E053FDDD950096E8A7FAFF0125B4AA880B78C84D02F00421A72942C7D7E36F3D346B4434703FE26D063DC65BA0A9F15CD05021AEFDB4A5FF916FF20BFEB723F90BE1517D49C16DF4C919E9F46C54A508A9D564CC781C2271DC08086ED0265F60AE93D8BDD7D1A6AAB191F3A91A13D7F513A136385D94C83E770972FF7D4602BFB1A95DFC204CC0024CD5AD7EAD3B5D464EFDEE19A01D57AD19EF3E47BE36CDF2913C145B77A144C9457841F5A855FAEB9470BDC69641EDF4A800F20BF88BC5307DE87C5A0CDB7114ED6F18D7638ECF577A406110B2C343C6404C5A4A1E235C50E48C81F60AE78A351080122107DEB5B3E296919881EF977A12F3D5DB6ADDEC4A89E31DC7FCD81F217E31674072C5E199C43A7BACA72D697A3093766BAB7C2DADC817BB26257D032AF358DFBE2CBCFA8C2B87A530323D9EFF5709C2AC3358657A51C13C0F8B55BF17CCB04A29359380208CE79F80DC384EDE6B501CA27E290E51B02321AC77DABA35F297A552E21AD4231298F58C91E56FEFCA7C66D27BBA45ACDBF7B63DC48BFA63A0753C47822B39D11D60F4734B81E7FC8895E1ADF2B7C4A4574EE9C0F4A829806A4A99841E6F836DBB8D6CB007014005140D2C39DA195E9429A23B889ACC8223104125C68DE0E79CE6886BC06ACE7479CC99B3CDA6F568FD8A02329055EC10DAFA1AE57E09EB6D54A9EE3444B73F38D2E6B8224F7D7B2C80C490C28FAFDB2E22A83BAD4D75658DF39F4372C0B9F1C50D284642C303E5D7F54DFD50B5D097E2F1DF300D7B8706461445438FDF83CE2BE35E17CE5DA9E86A843AA24072F2B20C5377841DCA8A45DEB6ACED51B9C95FBB93B2E4D80274142DD1A20139B7E1DA43748F1DECAB315FECD77F74ABC890E6443917052F428FD8A41FC938343A3DB5D89338F2AF43B84E83D7AF389156F88D06FC97658B37B9A6BFB6238108BAA40E9C6ED8A348E2ED58FAF6EE3D3833E4F0AA517CEC9F7D83F5DDF46F88DBDEA230F761544E1A10E0E69517E47F94D7230C0C60371E2A99897EB97D7BA3D8B6931FBE0B3849265C65F1E2B8BD120645BB724A0EA60C2CBB6FE46287387610F139CF5FCB6B0BBB32A44BA4C3B705903DD54CF0EE1933F4D7257FDC4331D7ADA07FBA0B9179FAF1FE3C8F4F9B654BC6719AB70F9B36799476EF0C4449F1CAEBBAB550F52041F88F0F4F32A0697FCD0A28B73E26A4D8FBDA826A680C37B3006B059363062AA7B04D561D38170B831C47D656AF0EB7BC00E25CC423FE75DD89BF7527BFF04CA793CFAD973706D5ACB8C4362B4ECB3DEAA59E9ACD999137131A1A324FB43D88D9A9670067507FB95FCD80B29E675093145442BB9499428CE0CD635D997924AC4C38C5A21C452E5A399AA1BA6CA0050A0E13CD6C612E9E7282BA21C4DBA82F4C65D6A6E0A5D616AE2608C804D463BE286F73526E70719EA9DCB16790B31A6AB7087DC60DBC370078BD1C56219CD548BFF20163B8568056EC6DDB1EACAC12C873DCEA792BE7B6CFC7D792FD57808FCACC0C32684DE298E6EB382C0CC03D6E6AEFF28EAA92F028757D27C4809614AE4372293CE517CFAFB94D6C49EE963D2B887CE13EE6994E56BF47C7927058D1FF0DE5C7DDE04F6148F8B0694FB6D99DCC4F84417EF371F76638B4BAF8B83CD7810116DA648B202DDD928C91B0DF5E9D4D1D830AFDA050397AC882E315F809374C7FCF31D9D011F367F0AFE7B0D05FD0330C3EBBF0B5003635D007461B155911D26F93CFE7822B509B7149771979FABC066E73B5B959187FD903C4E0960A5C748358F7CD0A86D44F58B53CB53B37C47558E1253440250D0CEDF6E19F9EB8C341DCA787E05E1E7BE7FE2DC244E2B5F915BE5EF2CC789DD77F8816D1D29CDFF437F4D6C76BB0F99D395B66EBAC0F8BC4414260B5AB7AA5C430B330A4B325A725B709DE25BAD74D3A08F6F7F76C76001AA207C54A83EDDC4368A0585EFA3C5439CCF0BDF11F8874FF7A196A1703004714015D28DB1BF8A626CEA8E9439A0919FE802B5CA19F3A4C1BE83F0ED3EBEE4A03A3A438DE157EED40FBD96C379CCFDAB89FA5FBFE123F10D552CBCB3CDC055AC854E52D5198BE1C745A79ACC57660C22105A786C8E1349CCBD5A7A76F115A7DD98F16308661E2AB3842AB455D11BC3D16658CFF8C4E128E36BC8912461F883B29164E984F8808DE92AC0AAB4CC3C8D966B365312A6B525E421780FE0434FACD08E09FC65CC84B8B21E42FA7115BB5A1FE4CF3FF75133BFF1A437BF2087F7E31C7D7C3782BB75419DB512DFFA88297B50C4BB234435A301489A066FBF12A6581F634EA9E219C3805CBB63F9ECF1A47BD4A1E5731CDDB28CF8C0C40F8FFC2CF7290503A22F4B118A7ABDF6E5FC44C6DFAAB37C8E3304A10D601AADA7228029397B58DF0443C155AA2AFCD634E505BE5B1CBA8EAE7373C5A933E429CE58F8C520897A98D6FB3D4A" + }, + { + "tcId": 38, + "deferred": false, + "seed": "1A1520478204D8CA028FB48EFD49367A562F66452E43B305118C85B4444675A8", + "pk": "842770BC8569EF9B4564D078EEB6270114392348DE1AA90FF94B56976D15AB3E1836BE3233AF866B20CC02AAA8D87FCD7FEE1326D80FF94E2DE3A72AE84AF0FD92016765BF45634B405DECC316B73502E31674F8FEE147801679DBE2FAC60774795788B5125266762E8BCB71AB672119CCBED4EE4C5DC5429D98A6A6AA102A79F245752044F2C74992B08329D30A6B51A12A9B5B36CD00DDDFDB5DAEE56EEF87CF31CFB0BFBF4C51F1150DF8209A85231B9F3A22E12F64F27AFACBAA0141207D452C53E0CCDBC6CC09F3B4A2F1264500668971383AE96441FE2C4ED0DCAA91ED7C2452F1826EFEB2421BB1B336C7707B6BF68F8BC603CA56883E437B5075DEDE9B50C094A51C6E47B3D06FB25F5369480AE7BEE9C3D9635D684E563C50329E1D32A6CAB3AA491B53E6D48BEA9C140C14BE3AC917475ED7FDA2593883B6EB71C950651F2A82D16F446B58CAE9709C700C2AB622D824A425785DA8799FBF875CFFBB5F55AF583378D624DF7B21A97A241130C0F18EA8B4921FC70542CE3DB20E6730FDF6629566E2656F84B4C96E6F021270A248E31E9B718B08B47D2C42558793E148FF4548A09A091592F6A57D8D0242A8C2B0EB3EFA26E477D9B530D091EB884B2B720D9DE025D9C0D0E4CE5961CF59C550BF62FCD7BD659A3631159C2F0FF4DB34E64A2C3E13B6D48EF5E420444B95655A0EECCF6A8E898305D6C9C117F4EDB5772415C0A005A1CA40BE58FBA18059BB10E25E2F483E3B58B2C59EA4794A07B493555AD4A555FC253C8019AF81DB432AB4624A59C4004A9BDEE75C91CC41A20401965BABC0C55992F87F538F9ABB80EA4C91CCC954A3E2BFCDFFBE8D22B9754C8535F0F642810B2DD2ED3ECBB2BDEC3243E6D1CE1B489BF6C0BE50B8316D0045FFF424F49961157BF6853E1F902A3B118DD650C529C603E9438463204F7DA7F489CE50F7A77157346AFFE9BE973DCA0AE076B2DF85AADB46DDDB57302F92C28BB77890A0F50B9D74E12AFBE40FB386D08B394AF62AD94C0538AA7A77A7422167604E9AA9CC7C08B443A25F850B093AAE707D883FCCAD208B7D991A9C0465BEFEA4865B6A267427A7F2D02861EDD8BD6E72962EAA6D2578FD45A27036F5E9EB6631EF5ABE2084AAC7AFE8930DF7834F4B13DCCEFAF45A632E7783852CFE5FFFF87ED126155D3EE0D40CA5F2E76E1BF47FA91BC450602584301A7E8B20E78DA1290AA8700BC6F0863053D0558A35DA679286CC974BAD7337FF1B8BD169CDD3C15A17ACC02201D536869C6FB56AD8D3CC0E3BC86816E94A7C07F220D03A12C86B77C13FE2F03F455A5EB3339FC709DB02F89DED1D43967495C75DE8FB8A4F37F458159842FD69C3E1AFF691C3FDBA87027603D5B99B2ECAF26752A115B0AD623CB527A82F6AEEA016F75FA381B2325C7BC4370357C2D53FC27BD2DBB6B81FE1522533016861F1DEB34B78F3F76E12D30F4C674FFD86EF1607309ABB3F015A9E81E4E292F41EF0FDD97E81565C546E4A8A2336408A1E6F7A7BF878F352338E18A428FAC3CFC7DF4F9013678CDBCEB12FDBDA4FAC1144DFD42CFEC6EBD951555698732835B701B6895C0383CE71B07ADF320893C7CF3A50F3D067EB9BFE93F4994388DDD99928EFF959C6C1A78B3474F8311938F6D8E488BB45CC72FECAA84224E5A9D9693FCD8486F78385B81DC192B2126E8729DFA640CEFF389CBD01304801B56B23E3CD64F32982EC8AEAF6D1BF875B97A07CE44F342FD351188E9798E59EAF1BB3F80B710D732992323780EDEF912CD529391ADB9C4C7900A3B5D34CAD48C14C49AC3CE951EA8DB4E944E8DDD5E83BB2EE3444B165C56FB6DA01F5CA9BE7A7D2FF84B085D8939B3B17C6DDB32D117E1B0AFF70C9B6C7FC29264A709A92B216B8C62C29434C876A12F7F44F1D27D58F7A5F7707B6CE80A538D05C40FD23572B9AA2DF9C6C271296E0A6D9078F42BAEF55C62809E8FD044C898873EDD2299216571F832DDB7C5DF718C4270ADBACF6D5EB3C5390418F561A2ECB4CF28E24A082387CC373C3A59CE2FB294E1E547BE587E65D8045A1AD8F58936FB2BB7776CDC4794E40A11DBB22B9EE9FB06AEF118FB9A72A7B710C1AEB4761034BF4AF7042989B600B4EC8D6DCE81184B2D6FC27FD97BA2ECA40EA85FE3006566BE60CE8674CEEB9493323AB6561FEABE98373FD7B45674C8161B16F147001B1A2FF74DC51A0A15AC87F3CE086BA134BC3579FEB31625C07F698533BADD414E9A8CD0DBD21E0678E2ECD7356609FFD4E96ED65C3BB6E917C6911477986665BC9D3BC2FFD480B5624C143E09FFCF5EA8433411DE214990BB6A452391C1586C37D6AFF7941B686D564AEBBAEC3F704E4EF03968999EFE95493368853458A40266CB1B1F1C3E0249D816CFF02C42980A73CAFCD929AA9536D8AF31B5F9AFD0E323C3E174AEBA0EA50F9DB0FC04E270EDC19249D65AF12A09F133A02913388B386AA897A7D4F4BDCD3F90B3282FB48DB6EBBFB21257644DF17C58E57A150E36F78F802CB0F05FCA557D5A77821CC74A0B5D9F76E0D5A9B63AEAFFA3869EF79CF2F2A139CB07E245E9A5AE90037FBCE24CE4B076D4795224C2AA886E423785E0E9B014D4A7FFB688BDA6219DE7CCE223762EBC9A48830A4B935D0F4D9768F84F7247E896015063AAAFC1A613F575458043420E2E5650043D230F06B6A78D093B660A26573A645C1BDC900A01B8CFF95BCF5A2DB23A69A69179681F550E04C324A48BC52E92DA43EE0", + "sk": "842770BC8569EF9B4564D078EEB6270114392348DE1AA90FF94B56976D15AB3E71C7A10C110A218599985787FF89F74BC94F14CEED203C92F76B5D67C5B8B6796B86718BE88A979951E9AF1ECC344FB99232411F87888F3FBE77FEFB6626DCF784DB0C7EC04A3261153E64729255E5CE6B894CBB1085A600E4BB0B03317F8886231702201058730723376188778513655812720172542417247143646428467073443314821558505445472081234686830274636170123228128315700625348670708056866251602156687542664438717868470378622443800377346336674542226381071034445030257183710411707658015133175365315628308222508432565388880836567878400317604235388313286765740235347182434457158814480762440746180380258134310686500677042318457626156280488882282674122811574762127248672012054076701118281460302420147013883802514645737522146600613056240136251846755266808132084387728784208687387732824316004177161457846583175562587327431712865534241213236603884536300716533078315626426655820641212230038185751644338668423426326635871105864138063716425330034814786417767388845064650681757471566615121140773133884856204744373720784387445647085255465817762845160020133010878367040062383084562467661733017263525738783274220670582858510453422721212564255311404704722055575627231518700445822334550788684185480667112556485545130470664356488815156248663062318887582478736241505814413368843465478500161842054157741700704620375746677448687646640465602446038662064506232040688488545875504681671327453411777175183001230743263842058632518307126387382745311055143874741412652558685470007145300836667478266765746720400414877053756562543853638554022055767416327752773186204257730441432226483061516523786268418417712485468645471672265731856455178786356443681803602068235327538110083351515556343615860803101225335447663035673464647078555401071381357720555132331165637465300650732644127750530363550200566217756741351568334658823132266106657664531167085175005811475037652261325817387606338288620565380266463665550880676743051820742216586384231472841757814014150130847064753035562530164461378674013218167481421451275114210804288236311323672003873724375163251155154108303660515386682522367768687520216231844201453516302058387034720361772125260457738774237645072531304857314868085873347454730385585338757726430656643873504153136638132646508716410685703137771500478115462036447706678642871630833317150172751226273671655845870784214880067160103258382278756008163457685251154205335015838270738631741007511261313311742713137207824551084847527852768414008530840523524707832357752407838621837744764534808245473201313077736628712454463573282036047606177628356273553851122846857773665077638871445056113471408877065460343677241566065401740402885336200350816455438826025210267242615477370212156817586755010774300244226438052721318725583862702644650137844613448618726312407205277538504854674606264472087585650666470602431007157683533714105566221537353610384157440670683218006615808544110058801184806484305030012037257405731613708843171027163255001108804531421323638770136218052673025686322362266664828487564412206143775215655602403825841434121722386033731087561201120571426628221551541811228681254526288715703202548412644DDC673FE876BF31B6D62AA38B221921675EBFCA9AA50D8C0717D3FF935281266A40B58D839659D70D618AF9961C2F09DFEF7FFFD9DC74FABDCBA2BECC333FEB52599A3F8B570E6DDA5FD6FE6502B04C560A1CD59AE5C67EFED02291FE2A2B190C226EFB19D5871371D5DE58883D163437507226F54E01AA46AD228F395AB023F66A866AE5DA63D9DF0B66314B5223802B27DF610449449A29851565467C348740D53D1ED8E4E0C36A4F422079704C39702CA65AB322A370379733AC070C30BADB277E629CAE8175504EC40F52C12D6C6B2B0CD641158CFF4526973827AD68D7729E26A56DFAFF82831D8EECC3DC1B296E2956C7F7848CD3C70FD67F4AC16405AAAB4D4C78A1FCF2646D7F763D6F295F0D35095C4A3A2E83A86CA83D9E24EA38EE2C8667804AA73D369C5FA0EB148ABD763D5E04E16D7179343FDE380715F87B2F5C1D96CA406D412E0371B9C5662BFAC94821D3FB1246FCB77A7FA9232C9F3972B0484DAF748CE475AC1FB2339686348B6BC674FB7ED3E4E6A6C92A480C839D153BE71AA61B23DC004E22D7D1C6E1BB696565DEA94CD434E458D3580E1847DA39BB228D13822695850C73464EE3E88C9209ACB603F2097504FFE662B0B20B8B27138DD27E0B338A37045A93DA327D7EC4F28BBEC8415CD0A5BE2D0A95C67DE588A539521C11FE14346FD714F4B51F07CB6E7CF466F8B1D979A2362E08F1F49F5621D6AC52917151E61ABADB7E2BFC10A6CC96664CC0335BDAE35DF198CC44ED61B282B69C7A1B3FB71DEE7B3E053B7193170A768601978DD4A8DB92805E3C8778AD770CB7D94098E4EB999C16F4FE59552A3073C194251179A81BF3BDFB6547DA36D70F46FAF467BB216DA5074E8FE7AB595D495A20FC5A0210D6D0D660DA3F716EA06BE4C56CFF576CCC2328EDAA460E37103A7B03ED2A867B1A454A9C667C1D01F132F2348ACD9B8A7C4B18FB1A2C64C2EB54E3EC265C864B922AC2B1AAB30E7125E5F6EC16F37D63C720BB320C40B12A39E4259C9FDA98C37ECEB212714055E0BE07F85E39FC4679B9F7DD1FF402E7E6F97CACB1D2548E8C469C0EB5C25A98693AA70813BBA53B351463FFFD5801AF39E58F8490665D4133EF03FE83ED3B6AAB0E2BECF0BA18A66B6401308FDF1720D03005A94B4C2E319BD76AC95ABABACF9B26EA783A231B444CECBC8C55CE98A038983BE9439158FEACC518CD113C27DE1F901E43BC060D7A32AF33224639DC2A2A0CCC60B31721F44961DD64B81E1EC48852D0CC0A784B23179EF02BFE135790AB578B473F95EBA1679E48679C0EF848DAEEFFDA4C1310F0BC23E4AB154DE62FA80727341622E0E77062F52D4586BDF4AF660D067727EBB7B050FECB835F2C6AB3D2C8D758AA6EC45AC79845C62F92759306FD1D9B97411A1907BE21EF244651A9B22F196E59F21567F9988C8021B85B7C981E60105F725AF1089719F039F6EB31FDE133E783F085CD5683C22EE3E70A5C0593C500CEF37888797874DF0A3DF2440F1F8898253D477CB53431DD42DDD25DB96CD6193AF62C6E3B69EB0C73BC449BD7CED979451937249C05502BD32CE73818794484190D3570D3C3495A46144884E1D0683266EEE8857ABA5853BBB5A0F222815EEF93B2F471D2054727238F19383D29827FF65A093E1EFB0B14141CE90391E8A6CB166F200B6C763DC6FE3E5A1BEEA03DE341277465F89D78FC1399BC92D4EA0D5D62CEBCF1876BF37A137B8229CF0183C835FE9DFA73B7239E6342D0078A247908EAF1252A1065A60CFCEB37492E9F524CC408607EA865B361DA0AD206E2C9D4D4CCDFF50F9F63D3706C9163B1055693EF2D9BDE961BA85994C304047EECA80646FD81F8FD46CC44863457DAA860EFDE929A491989C80E6ADFC794850EEF0A0C01D343974C407DD514CC66050BD439F9053F663C4B4CC486F3F11973C161E532E5D8E9AEE1CEFDE8E5CBE1A80D1D8C436544AEED490A664FD8F91B6FBA3077334637FEA2E549E64281F306178F9E1A8F56ECD758F95F94DC952E38D78F92837B99472A13F677E6B5AF3EF6A6CE2E9AA54C622941CF98F938D79B78355F3AC80CFCD0647C0C1E1DBB4B04F5688E1D5E0F4D30655C85515DFCB1C49EA1DD2D7FD441B7845E60369A9D73FF79DB6C183CE9AF44265B450F076E73D089D8AC083D237CDBA4A715D33F03E8EAD25B4120148B36C63F2296D9DB09D017C946A265CDCAD3263E72DEB0473ECED20E9E3FDE02CD2DEFC2A166978EE2B01E4EC75F1A32E96B24958F1DA8F0A3193F6E0200F4AFD59ED941909EF3D5D041B1D1AA1B1ED79280A82604AAC11F8EA04EB14EB8B0D4A06FAF2FC99D2A5CCBC5A759500CF648A1A67A60F10CC7CD0B6B5A4BCCBC7622D9ECD7FF83E1599343A22085BB4A11DA0446B22C668078D5211F5DE6EAD9272165A631BBA60FCABFEDE47AAEC562970DC24F7946C279BC0E9312DC6B74BFD311E24C18FBD011D59853967DB754B17FF0AF52F6F1B602EB0DF2C2880E47EC87DCA35AA46F7E6604D2BFCBF71166EF6160ED38C70AC14AEB97E39FB97692B118A6E18B692FF6AB91D196A4E718C60C2558CB5CB658AD4E5FFBD90278B3169512B5EB12FCBF21563249699C8F2DF7BEE98264901605C1820E1DAC4D6D626F4C5CC06A05CD6DFCB538B06C0634F5E147F555CC54BA7AF371F70978FA3501F069C481F43933A979822D2A79104C1DEAAA9363A520475E2CCF6321F0F123E3AFCFFEE327A0F59883C17FC1D3EB5FE330AF9E981A3B895A78FB31FABC1091575E189705B0B27B04E05EB9EA6D05A6AA7C6D32436AD27AD9F4096DFC6EBB2E85D4449E308835A4B49349EF96B0AC82CCC6730E1429AF80DD8D5E0B84BF3F841ED609E898F906E1B09753FA0E0A5AF43952C84B400D6EF09F7CFB78C430D6BAB17FFCECCA98DEBC078236FB65944AE95B34CA33D7AB27DBAABF52ECB3123A8278C2142FF7DC357FB491D7BDDCD3CA4284D949D1EFE905F02A01DD44620A9A0112CB78214057F6F0711755814EE3C596EFD7230824BDBAB540445010AD16DDF5FA0EFC4B5D90F2AC2F57CB1F88515A9977724C643737B472619278BC747BCE1877C041FA8BD3027B56D7F4C826B75681BB146E2D42C4E8F205EE779929D74C419B1A309B9B53A2F7100355894CBE365561FF62FE3F0F0E9079B37BFC52E1198DD26471B7A6450AF9FA64DC9A070612C1650C9805D3F7336BEEF26FBE686A9A5314E0EBBE82E5F80C6D596D145B9B3840063A7FBC04D3A2945B483CA721B90CA75DBC79191A1FCDEDDDB499A96A0737556A2B6EF536653632A92FAE2C6106F069FF829F2CCF8FCE667AE7D617C9F245AAA18B60A57103F6AEB0E225971AEBF3D9A5D63866502DB16CCE4326C5B544B604145EE44522988614A6F92AC10FDA5D064413EED3B14CD9D410BA73FD59599C59475201044982DC6617AF7A00010F99614272B18CACF644BE0126C1840ADD2ABC4D20CBF39212379BE93C6AF8B1978E69C41C514FF528B6E3BAEDE9E8817C479EAD" + }, + { + "tcId": 39, + "deferred": false, + "seed": "C2B63699D7C013E2D0C3A6A5D79CB60122B8C8574694975F4D703D75035DDD6D", + "pk": "919F02200622095E1406B0D36B1A90A3702302AD0637553809B0A3B8FD3B1DCD170667CD085153D0943CD38A3D1DBF3D912FF53FBE702635789C4DAE8F6BC6750483D1554E30AB38AC6C796B7E838B39CEE22570048BA090BDAD7A851C95BBE48A564FEF34D9F72C88BD7223ADD4FFB1577F0A24FD5DE75289710830695932FC0F619A7E0E41B26436E26F277C8C1A6320460444EE13363A353C003B8D4DEC547FB6B5D054382927984E791C9A718566AA78C04C744FC587AD18F55157D269554A5EBC1FE0A876FA2B1ED8BAA686625A99DE374B93B300EA39571116A9F7C82AA6B96CFD98F8891CCD2B7B8854C3EC1145D9A069F0BCF0D34F9DBCDE3DB51B2E87AAFED50E92F8D4DED20C5F7986BC99C0A0780ACA994D56D867A10890BE4A89548BE3E790FE52951AF0860FE66B8665802D9DA9AAF1F32B2E37CB3CA788A11F842C851AD20DBA6EBCD90CD27377FE75D3972A07FBB99CAB3ED4EF317B6A43DF763A70A5F6C23B5C5EE6E0F104EFB6C57B338FACAE6C0C437EFC90D5BA12C0146CA119284686D863B5B35470E620025AD064673C0CEE9839D9E047B78450C4882BBD36FA17E4DDE53AFCCA9527EE9F3B1A5A99C65128EC41F3ECE1B3782C20AB53F2860F472C31D04206AE73E8C9A43AE565DF540CDFAC9B7B267723D324678D11BC421F3D724CD2439762CA45E0E66E06DF3FD2D218CB2B35848806881266E3AF9685FB1487D81B39EA53A90F449693F7D4C942255B3621AF43B46E928E0CCC4052432D1066AFB4D03C6BC118740A2056044896A2C6460D0FEFD7E5C9E19B2426BC4423DE45F9F698BD5A803178AADE9AABF9D3E9A01377C299820C4F61A2341FA1BC5321FF5E80F9D1A99D7475C8B78B851DA80167AB21B815D4EE09FD51A2C7FE400914D2FCB2455AA43B96154B27D6164D0A48AE97F5AF447444A15F0228D31C2655241C98AAC48719EEED2DFE0A766C6E199699DB26CA099BF1943359D8AE608576D33937992A268CF6490755D79C1B6A14F494C2CAD7FA3908F9222C786E4776AB984BB7F77B0C892D806C867EFBDA69FF21BF473223067FF55913BC844C2CA71790428BC00EEE3D60F1ADD02ED9E27C631D3FFC6AB6A0D381DB59A82BD9C0FB751AA0AA3E12399C0B04195A852EA5294C27A31D9080B0565812F829A8E9F4D112E29ACC735152FBE32DB5A47A9B519B01D392BB1DA7C9A856E3CD9B1F9F462F8990C7668F289F7B03FA92F443BF11A4494E18582B0A778548D193810EFFCB0DDBCBE9DD02683B9A9BB231187D5955E04AF986A3448DE0A377887E987F7BAEB025EB273739EB77E88DB7B7855444C6CCF9F6343F30AD4D53D7B2A4923265292DB0D1D0BF85AB199D7A6FE544541B66544CBEBA4518BA5F47A7264FF66CFA2BA8874135B4EB23E094A61A1D3AFC3CE418CA9CF97A4B08C512C6C1B6B50FD6B393C278405AA5091B54F12B576FE0499369E90BA685EA7D5AF915485F5A93A721A342D999C985FC32C6E2D1E43D4CE319A8C907874B807182B5E0F0794338E851B21543ECDE72080FA348FF7CB9855819F905880C9DE0081B149B9D74169D0881C37E89E4874E6D8D665BAC4DEC61D3200F4C7B88CAD336449E0B2FF4E46961685645347280BE9EC144ECFB60441A3249CE8C9444ED17BDA3803F075660AD88296DB499C54C17934DFB76E1B1557D03BB14106960A0F2357832B314478F694EAE1829D53CF696A7200AA667D488C85D4CD25A4669ABB2F69B3CAA7382F99A1A73E75C48994D00CE8A9E844E4A9D74301F8138A765B48980BA5605221C3646867A19A02D3060AED73858BBB4DB5B21FD9C03BC670A61774CD447F55DA763001D56B5121FA9AF4AB04E7CABA5A34FA17A40A696E11C40FCD4C9091A61006D7A0790F0384ABCB8EC3A00C882BFA11058CFF423E43E0645D20F5603D116BB3DDEAC4FC27165D7D5387EA0EAA963BA3FCD28BBDA753053607C9D76BB2977E7E15695A4E922F348522C3DF49D789281BD70A39DB9718AA259997A3A5C9C7BDD7FBDE7078792CE4909CA2EFB7ED0FCBAAE72C48AE021C0952E5EF7E569A2E12DF64974A2C0AF1DCCD4DD9CC1576E1F630CD8F8E60BD5566DE711BC40EEA8358C025984DAFCDE3838FD0348AC1D5D7F4513F20AC862EF322AC22C2E1D6D238631C5048522C1C5464BA55F9FF4C1DC8132CA7C3245D540374ED191CA00CC43BAE8FC824E18D83E481374E43FB19C9EB861F9CCAFB005C009525D5024C47100580D5EC7919DDB28972B0988B4B0B408A75537B424318C0E706BA8A4EDB0A13730D6232FB1A5555AE54760CDDE6E1344476774507E414690DA8443FCCEA1C1EBD5C47A96FE2C1FCB69E7D377E359C43F2571256E7ADB761483F3D814D96C1AE16B242E91BF78AF86F8EC9485B5A1762ACE803C64305C57D0897F4A059778A1E9D6CF18352BACFC47C57ACBB1AE6E04E27E83C0FE3875F5E245F04E983DB085A3710FCA645533B87F8E3ECF3A1A01B8FB88FDA78F4F20CBAC99F71CE4C50A829112DD9A5C27F4191145A514FA8894467704CF58CE847D5212E5A0ABC0C2A54C8CA4416C3B99FD5DDE80FE85276F166E017BA7B73DBC33CA68D681694C93A495FE42A5C463C7F0F920AEA1209A5CBFBE2D1CA7F5C2A00DD79E5C4F511031B5F4503565D5F3A7FA9BE4FE244CAB01E9A3F0D432A58A8FF902C7EC52D6D5956D57DE83642E4CB86299406C408A69EDEFB75C73526CB5DA5DC9C726CAF4A67841E2EE89EE84B2", + "sk": "919F02200622095E1406B0D36B1A90A3702302AD0637553809B0A3B8FD3B1DCDD6098D72264E7D6D4D2526269ECD818BFAD40D6E450F1CAED968E46DD015BF860C64F11F1C8B68B0A93E3A587B4A7B668405275BA0E02F7A9B9ED5C2A3A07D58638B2F079D879E4A963A71E48AA6A1AD48A53FB6975BE80A87EDA3DC2C45E3E2535347252511162373444883864234312171761112443113274541262551337205657337562142564641810327758354632066283246026032660562804546204201032100470857008704485318757233871080537100440075887712430860310035716105637805207148726226407183117674134077685281072455240143304525435254517217271628230002881303005708644321451536774560055002568231011653601844825336871747306308225147337254564776486761652475071243277768387525351423682277653676710247471164822022210263745461742764530838303826607831325346722787012407686084857676626567311027633317684127048724810304183188573153261558525367337033801513347178210115184560288328727438522687047476323872420601657314862574234236007814048147752447545347484058034681872780107524724278612143027328675538021258766156243708623415106424264857207356713470438274025516222771841842254336038556352053512561056210538731218660581146781731417410102603685057454531087820334516527768741004147848406586028810822338421580355365452504827026415403608881208676827215416335512862313241750784333244556575172312606561322356524231667412531172858170544156587437378562074674811724802217158383553162701447171412448374380216533350052350232168585430430038546666427434215210776566432862887475236726102445460355684288760664335323010118554183206073738163224141810160528738375535763352866840268340018558752747872223772826467564754525856800736608302314355680585125466035281342871425278510600680607610868737872577318456358351064687712720078162564728847764466144165122526208337786674382106466856735504105256432573426072255878810568204077874201326268870137766250031860247320056725710627478252872153077206662734770617680505174037136271378240535272306826168630171048300027443113217376461110152053250267224762485262338638447582146463383730585507550657233653638216033427160072055538301436882311630532018878501457673434108006610310811853163472486135380248156020871742778818010634356287622737627032567085008145130063600135307373066250323073525614304006334526265375820448468046114113141828615350121800562146785177371376766480605223276434131846634530460107814758043353551835534481112537700631102252224444448644311222281052385284857636008820160843864850064545034076558382755214271046680842130583103778217641677217787005862414285106751001024270630427040075517615787225164836210742813206221343126760806276705656662837772503318234073411728338565231372213525857540671013027723486135138826824336244204230151581264235632588644223333771521856662577177028188663150465003874131033684300235477368611231125344672380206712007222430300558053788063326274337621554730280578778138875722058258442357632740701132645843862338815650446440677274306103004233323287706324404276838811203068132048447336288350384168670840521354057564146760626677354826831558367781860451050315725567188201475818213440704580241507306186380161351432371542176271552136705726572162781943A096ADF0AF810187F7FFBE7E1889300AA1174F9E6D0A86989C07D14BEBA934B88A1C1BF040A0F417BFC476AB1F88F58608609DE882E23EAA30B70720422BB19F8FA49F47AAB5FFAEBC8943FF6D379F0FE8B6F8D3501621A2C550BCCAB4DFDA85773097690AA34B1D5629CC72BAF11DAFC173B3EF79BF07E7F227876BEE79911241664D127C56B89E0CF0F0CE2682616BA0E0712FB4BD025C744812CB0EFCCA37BD57B0CA6E732B2E507921F6B763F398E0418AED1257A75DA7BBA0BC52D3179CC3D35079702DC9E4A96A384D7D6C0056F0EB8B0C5974EDD43EA0ACFBE53C5F7198C4F7DDB2B5D07544BAAED6E8DC14FD14CD723B4E90EE80649EDDB402375DF04111BDACC8BA98775E2806773B311BC4D104801590C17AA20046CDD6F28A44536E6174EED2D0AD4041B5617AA9395712031F1227646AFEABE17C43EEC78154EF0D5E890EC372CF314079E80C6C680529422C82E4E74C8BB35BE3AD04C4FF6045067E3C2E4FC1055E68C8BA0FC55F21DE15F50E46EE5A455865B48A41B44205A01ED6509994BD7FC9A0237323EE302ACEA0152355BD7EBA6350FE80314C9B6D30FEB4B5AF6AC0DF133733C5345A5B2EB5DB77A401F4135EC523F95F13D109B42C4FC3B8C824BD0D11BE7A6B5A74B70E24605914E4AE44FBFF0F14AC56E75A8347DFCED9B1CC22E2F6CFC1A72F444653AF7ABD1170774DE8BCA0F7D8B80390CB8ACA45EF671CC467A674B3C1B212F41F029E492FAEED1749AF0E57F3F513DA2A43DDD5A39DE2396C3EE779507A3E7C99BB1B101260B60354553C8142225AC393F633E1880EF686D3DE4AB903BABCAAA27109949BE89045D4FE4341EF15B833FB0C1DF7B49BDC3C949687305952B4BA446059D168C4218DA3748D88713A49A14467D38C668987B461EAD58934B0FB8ED1B92019E10E511A1A2B302A880570DF72B3903780B281C17DFBA7B9D1448A81219A5212E228B58B9EE6B73A28ABA81006AB7C31BCC56D3E7C9C5E8F1E1FE1D62FB61E1B26121456A909B9516D01230F4B841189FBE50DF83937057F038E4CBE75D347EF024CDBE00BD73F9680A36B7BB26640C49570F6DB11AA917145D14C56091D0585FD6D42DB68B8BB5EBCA9B555364737C8AD68DD72BE29608324E651766B1A6936F8C8B42D902ED712E3EDC6F6B5E5A07D4C2B65033958C4102A0B5A6251C27E2CB6DB3A0F246E0D7AE6EF8BC1027E91B705A674F9690A73CC2D5396726C977E15DAE96859A01F1CF0133138F043403CBBFDF079FEE2C0E345C598258BB03BC9D77DB0C5743D56F702D9031FB3254BEF6A141FC529F09F1FFCE797A5D343FAAB8854DB3B88EA42DFD2AF8F463CBD6F7733A221C528634FF3BCEAC7DADA963FE6BFC671527AE0D117ACF1127580B55E5C4B9FD980528242341283D20BFC220FB3F89B5710AACC60F9353FD31FFCDCFCA6F5B1CC594E9F8FD0F3E9349CEAE2B25955A7B5EFF5606D0E54ABA830B29BB257AD63C94962F167F32C174B3FF9BCD0DB1B97ED070A3C81519F65DA57E526DED042488C0DDC4B4746754564A0022592DA6F25023F086BEA4A9ABF5023BBD53F193C949A455F1EA061A8DA38D93FCF0A41781E46E91CEEB1287A7A9CFBCEB62C38792FBB967268365E9D6469FC18FE2D2E0CA4C5DA62A0FE4B8E58A7AD31F2617E5377EA66768AC3AF8AA6973F36747320CEDDD50B687B314E4345105248F2B9B1B9451C909B7197556225A56030833FEA15F1B9A088450D8DDFDBBF073481F50795F5CB9CA2B8E1BA02A02657718D823EB37499824CB0830FC6368AD6793EA27D171E7F1351AA04D86652E738140B707B17C7548F9800EF75B2640DA5DDDB88D34E9AB788239F37E6E4D5F7BDEDA86A1A35514C022C24107248D15C2B07E1CFCC7C2F239BE83C585F7485DF3D893E99A7D6A8A6C4E58F5F8D049571BD45506C6B64B02BCD3F778A652DBD5745CDF4415C524E29BE7E00AD3AF934366C3E90B7C7E987F6DF87498525206027AB905ED56CAC425C3F89F676B1CDD1E1E44ECA7E0E2868B58A81ED88AF0673DE18E22C2C58B4540D03A51D5740A5AC058DB3BD115A45AD77EB66AAD1AFD01BDF61E7A81946F0B52AE30ACF0FF545A4574F6B8383C041BCDF1B358C2E40AF9A98B31996D5EB214F047355C59DDF6CDC74E1ECC931BA3814E2854AEC822EF6B9F7B22FBA347E340A629CF0E49AD22513BB390F88BEB7993F240D8A0B6DAB823ED3F13A05B392B22712B20332E876D14C51FD09F2158833F9A7DC653605CF7E77AF15BAC2D1FE6455DDC105AB28FEC90B142297984F0398D5D5C6678977850A87CA0977B94D0E8DD2FE094EC00CA615A13E7CA73EE2632EF460BC06F3480E214263F8C3D22AC12153BF2D5670C87DF4548521F1FF527CBF044C01156B3FED897059D5EC24659F50210BA483D0828CE8E4BBF64E06739B04AE712E89439EE16EF5056082C45DCDCFDF008A4CB806749036A05209101FACD435E456A0339862485335B7C0AD0EE13312E18EC8E9FEEEA48B8C2F1BC07FF9911255C0B1A9836DF57B14A8AE166B3624CBC71C4B9F5BA0652C4029CE365AA6EA990B032957B26D02932C2325A3A956051D5BCEF413B0DE3FB94E89797855270D27A2381BA1039942F59A2675E4E645B672FEC30AB3B73F2495C27A47EE3EBC400ABB1CB54FF15F934FE8B791FE3F3A228424222B88D8E676F8158A5F39034417249EF1CF70CB94B7FCCAC8303DC229E6187B2E1B0B04701D9DFBD4ADA26F766EF6A89AD54906A608A973D5F72C189A2BAB4993862FDD7B54E24E8E249E6F0336207B754396D1E508943DA1329BA186A366376F653A0CA2D4092228E1D82B094F7D96CABB71673533F51CECA70263744D54E945FA027F2577343DCDE29ED6B1820AC47BB5BE66A9018A5BA9277598267390B5B63423C6C8D6211F037E841AFFB719B35275826B98DC9A06EB64195376161AAF7E34E1767367F42E25457CF6843A6D5263F62124A7C76B8898A90578FA477883776E799B822D5F595F2F7169B76FA211C48B7A8169AD4C7EBCA7D967A7B48E77DB51D3FAA346753970D50E5DF88A65AD8E319666A553A68F4CB529BE3585400211BBC4496DBE5B0BC75A7C5079FBB3DBB6946D911361D69679AF4BCFC8296928A4D5FE3FE21BF0D0EE246259331BC7C1558FBCFD53741B4680D80AA34F67E1011BCD4B27A7B9C6FA6A90FBD916EECAAA000AB00FFF4A933273EEBBC587AEF3C7B2E172EF16087F6ADEF740FD12C30FF23D2E78D9FD36C74739C86AB3F1258C8C04D66DC611092EB653A7661B28B2785AA6A9A9EEED2E33D857926DE535FF13A6A8750E6013AFEC7A25CB85D35CFE4C39B79E767CB6A0406ED3DB06B5942B9BF364E1A1BB13E69DEB759A0D0FB49830886D5DFAF405741C073FE3D6DD3AFD4D4F8282B6C04C89ABD1BAB8A2E67E1BA0005861A5D06AB2BFC4B674A0985C4145075FA34A69036EB7C23333E986963590BDDC8A849606A173AB3002DFEB4268D26391D55ACB0FD16191AD78" + }, + { + "tcId": 40, + "deferred": false, + "seed": "821ACBFE29F941CD0F02D6BDC0112688B212D5C925AC08FAACC248E7510CF88F", + "pk": "FD5109D8F14AB2D879B5147687B0F8B89FF635D61BE11E0F7542BA19D611758B17B5A84B76C1B3E7ED0C4C857A0C27F3DDABA85382A3B84768185346EDB47C3DEF01B18C78A91BF46B2D8BE7DDBEA67AA746CA879FD71BAF265AE6F3A9C977C055C678365FC92BF8AA042D197A5F9BED4FCB58AEA2B65FECDBDD93E2AB456510A65332E08233C0672E9213B7124820567264C5D12A5A996A595440AB364F4AED75B98A77838C8E4E98CB0F53BB9D44115BB69F02957725BC11050CFDF0930F82E45EAC8F709FC805683CD81DAB07A6B6FD3E44EA3251BB67D0EDBC895CC9A3794D240815B8618EE49EAA29D7FBC6013DADBFF2A48837B4084BD6E8A7D522058F5BDC77F378B3F76D483FB4C9D99856843C639B3ED99AE06537630E7ADFCEE1A7D3D9E44E4464F79F9ACFE32C384744DEED50057FE32028C9B2A7B84086EBE6545E619521DFCB6FC02B90F00ED8769497531AA39477C3AF9DC8E2BF9C51FD329ADEDC1725F760FF5E28B5400D917AC413EDA735B58B26FA7E0C6E07749B1A5D087325EDC2F08ED9F9ED5A98E388AF03B44860930904A907A66E00D09CBF98C0921248036F48323EC5A42166BCAF893195DBEAABE232AF704BC64BFB10E43FAB2874602D8641CC997FE3C074924B6CAC536D6536C87AC0F8F658FC3F99DC98CBD835520BB3441B55CCF3CE7F263451CA1B3CBCF45D12C3B889728EB7E401C1C2458528DAF2C40E90101A3B423A4E1B8609E74C60C9B7595CEB8F35FE51AF78122D9C487BD89A03DF414746D0F2009E852A3360AA422D035715E5713F7CE28D7D8DB37C40BD86EF6CD55C0589B6E52CF9C7643ABE4096EE53CD1C1EF65E1F9C7286452191ADDA05F133BFB18378B5D898201F7EF9FD77CF76A4A81B8A732B316CA1C2682BF25C4FF2F500F55FBD60EC6DCB48282984FCA4054E8A3DBF5E0834B312B2C867ECD962F27846FBD1B5FAAD67FB4B17C20BFB0211D96039515F9B0BA6691E8493F122236F9F52325AD5B1E30C3301C0D3F60DA86B77BD81B4823CB636ACB3DD28052A278737D2E5B07B5E9363B2395B51F1210AA53F627F58109B695516E2A8CF756E5FF531DCC0C51F3FC5BB95B28B2EF1676F15C6827A4CB2520C719A90BA2AB409B31E74B99771CEBF87AFF0BFE549BBED6B678ED0B331C154D42FD7F6A7F07B99AB0460FAF7803FCFE336CAD1D3FD5760025DE4C2727D386306EED3B3D5D17D9851A5744EC70B3A0F29A76A180C46D2D49F50E9D8D1046F2BBECA53543A0C3646FD736E39175A2D66E142B0A94927F2A937846A1C44CF00F55CC9B9D62D4F25AF4F87A25B8BC932259823F3CD59F3F09ADAFD033F1802293EE5CDD49E70D8DDE9FDA65C0EA4063D4F5F0810671635885B49C16601F531C7FABDDE3A63611DED6ECF67D621F2CFD48488DA31D0FD102001D44AB947AD5296635C45D853624BAF09A5BA447CFB8C874ED98EAC7B867BA6CC10A4675E6C2F5F54EEDCD52D500DA4E15C338B1E12CAC96B0E52D483A17F9D1F90C4DD385CF00DC0AC12DB97EA1FF33C3DF6DE8BCC81E70C6C153C2BCBFC6001A815D17ECC8C61C24DE9933BECC9C9F18A790564174BAE2599F93E5BB1216FC2674FB34CF153FFA690962BEE4E9080EDD9B49E3EADE139075AAF1A187531F51D05F7BAD888C1E717BC4B368FCB12ABAFEE6B29FE72132ED8173C4FE6F711405381D3E2049A627F4DE50353CE804CE5EEA3F3C94008156E7042BB252CFB13F512B1A5F28A10CC70686B22E9759C4C8A62E021F8366A4173A0D3BCDF8B550EEB9EE396BBE86D0A851B77B2B404658AB1A8B3D69DBAAF61CC7D539FA05193A6F70C2956B0D2B3757157F54AEF2D70DBD8B0D48D70FAD4D88B11465375B7CB6178F3DA79268079DF5110F668168C6E9BD362525EDB99B80F87FFBAD11E8D88935162251F7B4DF2578DE0532551FCC2AA0A23993C6BC289AC0215CF664FEE314BB4C21354F8B69BC920FBF0B8BB2DC499D3E4BF583B9F2EB574A5AB25205FDA5FE123B09A777B10E945F508A22BEF885746B6F4CA38CE73D2B4E843A3CAC214146C71925EFD237E09707B138A252D6396D8E9188BB08ACC33720C7DD7A87613E55C903C436BAB24C9D5B74B7948EEC3C44B337201643E4CAF2FEFF9B6AA4A553D1A6678592C630D11D357348E14A8DA3B6C274464F96AE6554AC76BD4340361E7A599207CB88B7517679CFBA163AEDA592CA982AA4E3E37DB705ED5E26592CF91DC803C4BF9A8B6058CCD426BA80B4BE2FFE8D0B2B5A9BBD1CF149F4EF6BCDAB30F7A4A9FD2F6D0C2C9887EC40B41A33E4AA0FA37FB61E9A1736A78E75B0E5B668F648420FB37885BBDCBBCF7898B77159083BA58918F7F190A7AD04F6F941FD99A09338920E9522D9F41F9C8807FF02C0350D0A91CEB260CC8F4690B2E9D5A6FD3A4032AA09AB96A7B4C02B3AFB62407546B0C584E142C93BF127405A17548FFAA23832887ADEE53B90117163D8D5CCAA96FAB1FAD4DB883688D376B3D582363D9816CC85E16A5BE1167F25883184FC078EAB9A0C09A5172C0F557BC314686F961FAAA93BE14B8C239AD5925B2B9CE7C2D507141C4705671E7105190B54AC4008D8D845435A9F68164E7DEAD5893406DD21898E4F6AB7CC23EDA1D768E427F2349F329FE8A838A03DD7DED95657D82D05F6753B6E3800C2CE345B1D33AC488534171FDD124360ED5EB4B62061D61B89D95EE2D3D9D5F8792FE679ABD0ADDC5B1100A5D56FF8C8393F6698CA302", + "sk": "FD5109D8F14AB2D879B5147687B0F8B89FF635D61BE11E0F7542BA19D611758B37F4413E6607D0819662237E4F7746006787833B1F0BE10734308C1E564C8FED69592AABE7289459A5882BECBEA41861C798A02A0F36DA0AA1D00BEDE17B87FDE6DE5DB5083B879955B99177B83F46383E2E5048700863247F8B00DDA1432F9475845411106010802403124423006207171123637626358064004744217668563237888426103620752544733884730188200687105834153425720865281708118271854426277451381137237063130331623234106723431860347548763207658577260187146861448155686826455003173682641840333567008330412485633328752625476441625800267213531873672382311441364125312140451047067036187188453426367824516587741606322451571174808077083645343475863427745255815618608637822668140778022078564357408860015574881153222705772820283282645138703666837082845457545642483327554486635104572840030702644546883155868854848727734687116530122331273316185560038723621705252685722207460533380311867184216400552714105740853578622762727822013200126021044283211375323117003650187002088603640345838844504335503120832113026778216041020078002871175114780338718740318457762655342324868368435104511507781314186715333714808404824660120450275541327480357767864878521734380425386623801541346774823118010158808603360723632020412452027121234068688716164441521887108240101786315371520841447607250516005315365686168717574678054651203116875838316668026521024171872707164174688353341467360173172577764432418112331306083318608605402151567381436862124117738672361158226325887710338805385437741854660070530741053300731051058032536663754782277723523405535684511367423724838044746436665367216702401504057760861543160842185113378015224425623321268204241475232123052525186526436170475223506404246556168704551444551388733525384672264531670007310781725425740047878568634613747664237017616081148818153324800302322626514831370370752655505652444514474570366145827603375858080460822137114012511117868251538483208262330710570084046510350650067607452046145226203135104263664202836618344162630317470784727848257402470148421118752145271066152161743850236604061501516023741745433718841304847033226752765102660665216844000747725857377655737286628628855470800115846468544603448604421136682275115820474718124475360816350707076840045427737648741006206344653466760485601222162728263052643450841137207405423267533600508015253620825076388520610231453565801282615681627051432685018612236467086817638250582501884472046848272635753014406331123268541531386173156646817565463500686735817646042771537270561435557563865543005755720030384235037845153625183357188765067524510541785723483746082513261716357675385520117254805854813722260257761547732624410547504153484802545113081035450188274886618452447827427357657813402550236060754048666817727427460350022175101303701227746503115654701150825304136500402467436180731888868347168086754418454456816581305381780810850606827744730528684184014655603763554220413703356318438650383817117084323856267162872086718276068621466341542271674584731366742432452022720723523885440383735736758540137861645710336031513401537787442784487630878114247615133473366832843613332177588724308575184307203156767071BD4D1A723FECDFDE655FF7613698836154D8F6C5B46E3CC037A90876BAFEC493D244CB2B771BCE1BC5AAF7D9F8A75D94A2E9C6746DAA9058ED347D992A707C5D654D696521403D04BFC933DDD819C17A97BB4685A827F2FA843ACB0DE979BD88FF69CE5E62BC74BB3B0917EEF8C603269990CDC67E4AC99A6645412A1C2326FC2D13CB588740F71E9012AC9A07EF086670BD981722F8A7103CB68C33933F6132E78803316C85F6AB3AA8BBEF2A33A19000031CBD73C643E226C156E5CEA88BD3743B3B0FE16452FD7BC84380CAA4DEFD3AC5D38DB01F74B9AEC1E3C368A77B9FC8DF87A1C909A7E10B9369DF94460B8567C38B75267EBE99CB7E07EE626772BF70E721B00050D350BAA16B0AE07FAAAE61716FAE72B10922673534E83950769A5AAAFD95D3DBE428E66C7148508D2CA2914AB6DC20F0BF7AE92FF51577093AA98FD383A5E62791AF20206690BB1231736CD5449ACE93061E2A71FCFB4CE9752188A4A86302C6799B882E44545FE4667023FDEF2C13939B373E2A85030D23DE62FC85F3AB765699E898D3F06794193695BB0495684A4AFAA4C9D63843CED531BC122EBBC3D9983319968FE57D037699C3722545D5AA32FC648CCE93EC746C020607513559820FD9F4178FEAE2620BA278613A0832A3068BB65A445ED00D0623DC6B668983A5FCED6D8BDA41164E8ACCA99DE3CCFF3C4A6D5CBD019F53F6B70C97FDCED46ECB1D6D969B16191DA7FB093A0200AB28055A045AA9B544A543C96AF75EF9950E36B9D661999929DCBC2D697CFC6A3540B56EA3E4F4187B8D892447B63D80B75035D8E594BC8D7D8FB55694DADE5463804985B3718FCB59A946BB3B66D6BB38257D0430E18605399C6F460CD33FD9E4353CE5F7DABAB57EAF388310B828BB008F1F8850626680D2BDF2D1D7FE348B18CCDCB1430A689954CFD60A683438000C1295711F7196F9CD524243813388702248346794DE6AA4CEAE1CAE5E1AE474F4CCA0CE754B8021464522E4A845C1FAD51F775EF7375DB6A21004DDFC8FBCE0DB93DC275494E937424C4C3EE97063650930794917F57BFDA70D2CA74B1BA7235BA947C587B1C9D86AC4CB9C8DDBEF333DC988894FCB2615B3562FE939A5D171257726B6C789ADBA53DDE401D5168418FA6C1CBB65DA20308DF78EF6A719C059EF43A5E01CF6B2EE5259EAC541CBA7B6321E5B592ACC42F6E5278785AACA977E2658145258EAFE96A544A648E709B48EE39646F1B1F1040CAC64ABA7B6A69DE4866832FA041C36252843F20FB4679744D6DBC09C8260A3CEC898ED2D8C33CC790D2D7798824F0A05A1299C4D7F2A4EBE7496956A5C7A033340DE8A044619D48013BE1E4B43213B3689C2267D4541853314E807EA6A1C69485CF57B80A106246F10242E3C96093C960EC0F9C0159A45B9007B7A8141A1834B8B328F44BA0A1FCFF7208B476988686BE639362CB120465D1AA9A6054F596270E5A3088329A91A070A6A9B8D86489DA8AB6FD21F21B163D0DBE579C2DD5F102DFE9FDCBD9EEA6EB32A236360EC67CC685495DF8ECD4E0DA5AD27E9F313E3123828A3A7F54D793B1227214759A72AEB0D64FD2E9A134BAF89ADE482ED7CC5DB0C9593C63219CF38CAADEE0C0D297C9201F7F25680F0EDEAF516A4914B2A4606234528FDB99E5F5C0CD2A881CC1B670EBD170360877E7FA4D884A67EC0E3D6A4D3CDD304C4633A1E6DE168AF86FE586895EA49E390C0A9A92662EAD24E05EFC92C048372EFBD3AF11B87809C0D7EFA38C24C7E082DB4B542468EFCA41F88CC7C999FFE3C6568586C39F3750745F0D3F551620C227109DF9155437A87A04E08A4FEAA648E9288299E47C351E34AA509EB4F772C78E33ED4E36858E4055E7E3AF5A958E96E69E93BD86DFE5DA8D1A3AAF0769DD87558024F2B26C6C6C42224760D12B52832326B7A1F70CCD530B9951CB3B7A499C35043789E79EC68CD8EE1FD56CA5F22A5D54FAB7F0689F1B9584FAB8AAB9842A3A30C8780132F14AAB121CB09F0B4941A882FA8BF4935BCC7F2F698D93FE10F2393FA96B9F957296B24669DDE4B600927BF5A469C0001F0B1D8F1DF0E6B208EAF552D52F15FD1A80B1B4831E65057641FF84E9CB6811980DD38C4B26B11265B4E71CC306DED99E3D48209545DDEA12328A1A99972AE9C849718A2E1D4E356BA7E93409F9BA01BFEB6AE78DA17DF50924E428926A844580DBADB3439D98C6B89818907EBD7B7EB11DCE48478CABE0A49DBE5918BC45DB4B88FC045D1985B918789F9ECC59DB72F2256382841AD1317805DC32E60CE2096562BEEF9482EDB130FED0B00335AF2A8EC79380349E1564C3A382418550623E7A87A7CAAC056EA6B44FBFEE65C93890FA3AECCDCDDD24469D418FEABC03543BEE545F9FD977D77FD44352553D32A365AAB23E0916F18775E3DC4D41163794884596AAE4251F7527725C98483C72786D46EB2A11992B40DD0C69AC7092067B3EB63A179A5C61446FBDCA3B21BB919032B97962B7E218C2DC34409EBBD5BB360F2B212669CD16F45F5AF4EFA777627DA59B6E2AA0EEBCF2DF02D1954B16BC0B5A718BB95C1A905400C5E0EC0F326C8ACAB20DDB69525FEBCDD32067CC74DAEF2E79511F10CABEBB69F11AB14612B38190F8C02C4526ED189793D059CE759D56B00505774AAEA728C79CD8D2588919500EFDCB2CF7F870C999EE2B5CA16CAD7CD92C50DA46274A1946A0D8B3EF4FB6D498339F2C7793267C92B0AA4A73CF40C362416B487A83A9CAF3F7C6772AD70DDCC5A9D1FFF56B5E37B821FC398DCB15E60E1FC0D8E6DD569E315C5B12187FF345D749D66967F3E7EC97117330894138DA444597DF7B5F7A014431C253C8D19F9E8E6D143F406B6E9518F18EB3E3A3B72CEF48F2AA245CFBC1F1219B4508BCA6EFE40F80357A1CF1C9D061955A746318A75969EA691C83B5219A9354E0FD92ED1302314944BF62EB3E75EC9640E2CD6E0A7C955EFCF41DC0F90D25C855FC9F54ECDC4CDB40AA95E7E53F8DD2DD6CC33F2703E8DC4C09C6781DF792E6DD945FE0EA4FA760FE35380236138F6B49C99DD5D6FDED1151D5C461DAF39717916CDE27834BAB0A5E3D5C0C5FDCDAFFC3E372F5335DF494288D5176786CA73DBB2B58FD519B10531A2C9D6D390F7D4EF4D9C4F8D0C6F36B68E3B502E2D0F4C97D027CF8629E2239B3ECCA9547EA8D9E8A357602319CE01B0B76D2F5CC5B4A3A906762554A37F0B8FE5B4DF29D434D98822C9D3CA495A103D1096DD042D6BAD442BE6D7A5882AC7B79C9B588F10CEA4EDA495ADDF22A8A52F49D21ECFE6FEDC77A459368C18819BCB9380A0C115A5280CFEA7136EA7359A78392C27049A55FFF75FD69F70D08E2FDAE617DDF1E43749D9BD0DCE026FC0B8722DB70AD47FB3ADF73C1BDAC24A27A596739F7AB09B92A6005226FF18ABD52AA5131BC9F86C786D87576BD3D8291A471D4F40EF51B214069D7B0096744BD9856C499641140EFEA44192F40ED4CBDF2C562E30881532543471258282" + }, + { + "tcId": 41, + "deferred": false, + "seed": "19B20AEC7AED1C129B55D7A5143192A3CF43BB55069017D695581B74006788C5", + "pk": "C1876C7591D9FE2918AF831763B053D7CED29634CAF7C28E44CA8DDFE79B741612FD62C3049C2B665EE8EF14D040867275020733F0E2673A1AFF38F32C07C4F0792A7BA4777256077FDC933F991ADAE12D5C0C79299769DC28F2445FF043D563DCBCDB9E8F3B238C441CC329E13925A779F9A3B65552EA2793F99A95577745BD8CF86DAD4373B22A7FDCDC1BA31543C649C4B6B7C8E60795AAA4C4A9627D97B5C8A04BE0EECAB50E02F59139751DEE11A401FD23F3A0B47837EA00CC146D668992DD97AFEF17751A01449B0850E3AB1838A512015737199483769E060CFF8B66793CCE1FB3E4EA781C6D09D12231775AD1D98CAA9B1EAFB9390D67D76EA3026113396B8DD311516577ADB15A77CF47C2082B7982B07687C2C88A6BDA5F9E5FD7F2AF932D947DA6FD42A219E297E65486B5187330E4C465DDA55DDBCD1823D7349D9305691C3EDCA07DD547E46AF919C780BB03C670359EBE80CD4FC98DDAF6449677FA7C045CBED1C04BE230690177AC880286407E301219D305DBB3FBEB56B0AE253AF69ECEB2FB19FB66302C828D375328CE26B8EF9FB97BC95B35D9F0294E157A98F50AF78A451AC533529E98196987D2D0E63C6F9857750AB8CE1503814C87FDAA84B0D345C477BD8E87A09DBB0C176573B5369A083C852EF8B49D4F30E6082E619CD0E10A141B161832E94B14D6B0150CF32A8054DFEC80C2500F230D4FCF86236D72C02EDBA3CDFD83B28EB7A282D4CCDFA1E1E5438F54D15704E76C92352FF2F28BB112372E5B532AEE918DCEF2585E3163520A08182CDFE1A3D35F8F4039105AD2BD4400C6F8EBFBCA9FE312F7D95019912E2945890AB754881AD378AD92D00498EEB82113897D555DFB6EA7A49B8D7115DAE705C2C7BE0D5BD7C79A19636884686B9173AC7EC14310D08361BE6ACFC6FDA240A73722B6704CC3D2BC0F0C0C040E44D11E185A21FF149F8AF17D2E056A3C3B5A06FFFB6E8BD3650E538AF954024C4E0B55B23941FF945513A64453A0BA9A4D3DF118C31263A06A3DFA7E258862FB8BD066179117F878662746872C7AB66F2264E4765EBB0DD19CB31F55163D8BD964D3B359A0A79D4695D4E0A1D6106CFF71ACA80FA61841BE0783D3CBDF843C65EF755A7891C0C40C98E6DAD9F565E51FFCDD4E982173903ABFE03BA08BF60E5F14D3C88E00A2D882253D88CE6860EEA90A9E4C2AA2EDC6AB0424493C1A79B5B6A3F73089F4A64D0B2E55B7BA0415A53960B870BBA5799323DD2D00199E2FCBA9547A9C2B823F753408FF143BDDB72B3C1E6696EB3C6C3CA2984453B1916FF4DFD6B3B43477C42CBF433C752D0749FA7D13E53363E6A22D085EBB93AAF260D610EA9694AC2DF8BD0E7DD543FEF57685E381630EE414FFD89269CE6F0D9D1B1E32EB744120325F092596DDF8CCCD53FCA530440EE9000EDC1D9708D0359A2B8C20008639F164A7DEEF0E1F83FAE0C6D06AB8A4E82CA74ED9AB0144A93F681BBB54356567E24D8F8A8C013D1E879F666EC62B94F2617C85CD57323A72FF71AB92E322C339AAE371AE06BB79AAA775C3E52B9480619D6D32335C8BB45EBFD11F8A5C5CA339B69E0F3FCED6A857EF3435732919568F1212DD9D02CE7F3FC1B22ADEEB3BE460D19235DD54C85AD0DB8165F30AA209F34D043A9D9DD186003EB29BA7DFF1ECAFEDD36767A7A389C685C4D3ADA09626C652C7985F237D69C31DB93A8CC116BBAE071DFAF8466908A9975C29D8CDDC236BA5EB447EF045AD83CCFC8FF9663D027A8138C6133A20D9AF2F89B2C183811B8A6868D5701C9466C54C78DEBF571A18DB524A7AE18C935B624446A8B94F25060D695949D7AC47DE11475C427B3BC987CFF890932E8BD341E51D0DD8B178D5C4F40C35B9B2E2F2AE493029C6C63867EFE1D7CB4B02C53C5646A9EEAE87E6FDE7C073BCC7F0A79B4F7E25383185292D735F0DE85B4F3FE9FBFDD21268CCB903640CC081E19BEE7184D3C2338C83E2259E59D8606357F325D5867265A2DE3FC8BD88AD8EB2D4AEA4E89CD08283DBF1E7C5A7E97E3AB43D9A385F162CE3AB3CCAC6F86AF9C45FCF60D997C3A6DCF610DD4C6978A3BD071BE03C0495DB413D5D2ECDFCAB95865F0CF0C732AAA3ED403DD9901B1DBFB603FE933F994F6C0B5A7FA6788AF95F676F20AFA37D7590C31D10AE2B0FA71239499737C004E7436B1539ECD7E442AFC74EE027398AE51D87128BEDC2C2F1E8DA5FC017A748D6D51428853B71B4F8D07A593AB61FDA4C401CEF4AD4A202E957DC207B20E15F5923CABD23E5FDFB19C66EBB92E1A8226F546A3637CF69054CD173614E5B69462BBD53FE82386BBD5AF6B807DB21B6FEC62AC9B6FE7F6D1BD777B2940B43516CDBFBAE26722F6A88552544C656CAC0C1726A3E5EE30BFC1E140D40EBF234BFBF07AE5B3FAD3ACEE3F8A134CAC9B9EC925E8763F21E85A113C6E59F5CCA70EEDDC2540BED7C92817B22D464CF0B13CB824684728E1FD84E497E4D8B1968F9103E5B820D97BDCE02BBE71CE0D6A8C26769ABFE48ED47BFAD693EB992632B6B934B54EC903A5C35CD8845F0E43A0E856BB8ECD9CEB4EB70010BEF602C7EC170BDDEB6A1CE2474E3323EB133BE60E1A23C0AA0A88DAFDB69B4C492981A53EE45F006F687951F13E6399C0D3953F134B5015A62817F8F631F22F029EE3167D9CBDF890CC68818FD12DFFE4BE01B4BB04325C36770E85ACEAB462A919B5A2CBE9F6198F9E3C8D8F253818C5C1B6B3472DF05C8", + "sk": "C1876C7591D9FE2918AF831763B053D7CED29634CAF7C28E44CA8DDFE79B74160D9539D135C3137993C93CB7E9DB32D97BED2F47CD513927BEAEA3EA4DE8DB3BB6F69EFBE8BC30B741160501F042738BE204496408E7B322B4F8810CE5F0A1B4F5853BD042BDC71BD3F713995F90D2997BE98853A3E0B05ECA0C2CD529C62D1D31142720430162555220261408757487051805486321463505328548138872674635348656038584807581556616567024781108748714006466586518105002840004152155071684402283301625468608582682871478285880112418701887856542813261486851086715532015038018055506582001004343174024123728627110402632383478155035530668058030807805254735026344715438314074570828778555510310503127760081644038768664440013167025735144760220153688771326556654136677416836236681275767825505783518026507108541306761822164356817775213250763580875702357583307542021077861788684686144273011537008501712324033761721553654884040484566604226000214651473588064077132555143158421687651533365271426802716634284747711533266322568582853708027003861221727624188548224553846320154218535004558846614210714725845776845035032840301165860462661558567062356487726862640113066862340546354378052445185333237853473826544553735144445868050241350888774173617075453531720267316818175415433376853422836031112605825812128668124221221813720163332878132662740616835058334581511783268088514555323113603245767313468456805542257754161745144715584644762635222801770257403571224173224101775575421637641653561651523472523353220007246647685422882100323788035807815471744883353670332227331383575023847310756871261578822337587022523242818335102643211010036128440207207414604308060212184302087706651107415366331635141330688886357276684550512668846326170485080755401433066163136305042535141770172143571578534537566273505072131666672802302137400258356111170004050122176802185713363384107338013714068046336638073677671825887712654440634342104756450234366074785063373770138355536602834482336117841811656443744500552574381774725612554820152456181136173480528377444617573837506101566008482616254362626412148541878576272451278865273175261065121480628166312811217332443874218160274773587204140232054516151580731416010517360222140016312345165580552765116138228663835802871501003418662168472077781187768025576001388352286135461575165005568123188068230433318746647171256317558746767878042633203465265747801218226257524465703521066601441767437260017503655584555626781625645828607216813374401208635875826640523026864485803177516421032408802243351517420170357837500517573422583060107563784043772507424567258253886871303426754383234648741138366371401462647365832748247554435886122467742424232347324855363843371303526333082723501448384560734138412613126277377455378767072466561765062756763081555387882428742444264545182347872215788716415115613725675021506301847681043752187440344541180617014583366082216418784124548587567538635417676816656583151701337688684365852214350536148165082118684731162728603020045865388212864485217252720226467655245757761056558883368818036647577235233732437782724674158151572615477036118545377305340788610187136740007740123076210307123022813564872374047362802876653816510510783134134880883380826444C8103AAD8657AA9B63770DC7A193DBFA1E0118E192420247B0444A7F836CA9CDC3A0980662EBFD520D15D923C37ABC4C3FC417AE01F017B157B85CA4AC48B3A5FBF10BD5E1F3BD2CE7E7477F4D47CB502DA2BF1D75FC48CBA9CC78781E33A3076A96F7D482609820FB1A1EA91EA2C423DA8C5E9ECC59F34BB5D58CA360DFCB4E4A10ACB046AC8A0C2F093FEF48DAB309A7645EE2FF18D88CB14737400C44B2EFD12D8C03579A5E0FE1B260F691B9A9D001FAE92D5C04A46D0232751D51B4945B86609AB60D80A9B04F573318062929CDB4EA895013B78D88B6379C1FBA2E729C7BE337DDDC9ED90FDB05595D48E12CC38732E00FB97735476D423EBFCD8B91D7D17D9C9F23FC65EDAE2281BC482EFAC37B48B23B9D1FBE8B8AEC1533844536F1B61BC8AD5C0DB80DF89B3DB99EBAF8014A8050F721123B45A913DD533C8C9A5789F2D6BEBD95CBA04555E36779C2F1D0F562E5C8597970C009A815FBA3F86D76BA778365365BB5D897B67076C9B826EA46578DE54285A6DC36BD9EB85F0B282376CAC0EC1ED7E22B05CF123792CCD02EBA13BC9079C62528075652685B70E291A659B578CFF8EC7858CBF990929A639F20455F3CF14A6E9FC8DAFADC9415B3B20C8B26B5775F66DD90851653B30C382D3FCBF8C823EB5F6FCF70C0357F71EBC54BDE2055615A1A1CFDF3A92888C5831A3AD66B5CB128397210804C3DED05CBEBC4B9F982CD5AC73154EB629E8EAEA4F5239E7A4F6A4628469169FFB74FDD8CD475F395E95C8F6CC451E46AFC3977BBE7EE3D2ACFC1C29C197752863C0ECD61060C90F3837A276DA89A7496435923C2B89786724FAE94EB1F585E8EA4CD6B0B8127B241A889BA2FD60CB8AE279F77BA7EABEC33EDB596D6EDDEDF252800F448C2FE0DEB52C00B2C59DFECDF7761ADAE9FF8B7908A5B441A70B451E136473FAA2310C59733200D238C75AA10FFBF9189580C53EA961A72FCD49EF3F7A7834FB0E0FB5101F0DC77819319223D1BE54CE05321D70BEB5347227EB13C2EF4BCB75DAE62B80BBC3F89FB40D83A0BA7DB94AFC86C469EF7EAF8843C508C465D90F850F85203A978134C4240479EA0E241F805161E7C0B28B2E960EB281270A26FD00B0FCC8942125B0E73474B186BBF1B2A22BA5CA4EE34BDABC5CC9729B25F02AEB9BC4FB18F11053DE96BBE76611B1AA5D3C8D1E256481BE19B03CD3FDFC9BE306F35ADF8B229CA3E2470D65DDC3F3774C453AC9F049D4E81AC955283B8C85B5F52F13A5B9AE74B08BBEEEB7FF9C7DB6F0DC10A8E18B5DE83725FA5B1A6E5A009753C694078CB88E8A2E95DBA4C5AEF8C041B8AADB984F533CEA6B560807CA8FAC3E16000DE18C94D0346BB6B6E01A739685207BADC4C641201C159BB256E56216CCA2DD471F34E97891785CF7E6BEDD14C92FE0160EF1B25DA80FF86739568F006E778AEAC09EBF4FB56D2DC914D549FC91CAE30C1F044AF84F2F814C3BD9EEA0FD43E04FB7C5ADAEEE456414DED08A0270B1C418AA964C31C0D9326618DB93BB2885A7F734DB1CFBD903D5A2ACA03185B3406E015DE23AEF3DF47F4394C6C406D63EDE57EFD3D00555592FF3454608E00D5B04B276D8D52E8533FA59D8DF4DA27AEB1A4D6E54FF340C9AB6F79DF17057517B7E50CAC46E99C2433A3F14CCF5A398AD94C433826D0497DE022529C0731FC5D567A2B63CB8473B1DD8EB40EE86143562E6A549CB58A94FBEC6E75E71ECDB0321D4E5FD2CFB9E8BE3E7B6A9CFB42FC42CF3D8A8FFF70E2E31A9D4DF35D6AA73AAF44A0E9FA0C49F1AD3A624B88DBBB2CE5754850914FE76938D2FA56298E56DBF447BC1DA818B2CBE6DBA78A240A070FC43A9C776562864A6846A4929C94B4F1138ABCD75DA0945C9AE6F1EA9468249DFF202F2E338B9BE3CE4CA099315346ADA893A49B969D26ECB3A05913DA9FFC13327CEB3DF6F0D1CD855282CB64CFBD0F695ECA2D4C24AB18FE07A79F2A129CFCDCEF608835AD2F56001E7B73DB415A132EB72D0E752E08849CF5F663A841D25792E3073A4A2634D9B41C3F9C73464F4694D116EC073C67C507C05FF3EF5FF1441D2396FC4583C8709C89E2EC6CB688B3713934E76B95E8C10CD2F3B9D0F298D2B66380C547D992894DA2554CE583743490A6792FF5490CA64868DFCD95C4D3AE21130DF4B00FC50CEA9AAA2277B76CE9F7CBF8778C30591A81F2FDB4F16C614FAD89600135B8084BC2494A119470C6D622B4B6DD534D086074874202F9772C190C301987A0BADD318C2152697E8397D4EEF55547C672F35985E3F298881BE917043C8B3E9679AEF3A65EA7E641F3805ACDB18E716493B597DADC3021293C234B5F3B548E82250FA5A2872357D961486CB95081829BB567AA3B352B64C0FB4F7072055FD8AAE50F855C9AE69A1850BEEF309A41D1B91A5E181E5020FC73DD5A90AE7271186F470E20D2093F44E128E044E5F7B516D746818B18A8D4E155B0CC322DEC548324B0241F4038C29E6CBA77C80228AC9291D1E5046F7AA321548AECD85847EAB71996E3AAF47738D06010DD373DC12FE362B599EC7B060120AF6435301B6324B7B99771300C7DFD369F7983D1054C1C45D37C8063C73765CC399CDF2C7ACCFF7A3B6F80C0110748BCA149DB1C7503E47CFBA8C4D44A9466D1DC0F3758932BB4F960AD5A67CA4EFE34F5D946220BEB96C787D88F87587D3C09DC4F6DE6CF1A91E463BD48398AECD75ABFDDB9DA29839D78260DB74FCD26D6918600C74C4218096D1BCF7054D7DB853379B88235AC069EEBA3BE170D9D5742E085B468D3ACB79FBA3972E46AD34CF645A979D3AB0E93E1B69F16B4C1225C048F5E5CB06AE5E9D84C59DDD9AFA1BA1291F3E02CB46DEE9B22EE622393E58AD1CD6EC3A9EF39BC5CB2252C17EFEE60F2A139EB84BD7E9131D70CDF35983D81252927FCD3CEAA9A6256CDBD0BB4A310945E7A6EBE10EE50AE002B281797313E621013D1F9E9537A51A9C32D89FD4C830D47E6F87F84B9C600861FB7191A73EBF28F9CCB83D031CCAFAB2EBAF1F4B67B651128CF35F70F8315D03E9AC420B730C7C7EB1C16623B89B89015E59A57EE9E4AA835436725459AB6EC1C3509384E1E44C50B86251EFA538C3050032DC9BED5245CF7708DC6C07382CA7B5664ECE3AA5C357492A1CFB76D49D4CAA23D237BDF1EA3F8EF35D2C893BC45329027AE33D9F63E9845BA7DE22DFE6A7222D1329060C4C8181D92C6B399E71ABA66FFBD4C29CED409B8E083012ABF3A8A1A9CD64F97E972CAFA4CA3861F5F73D891155F7DC9B49FDFCEA857981590E424752F9D80BACB50CE48AC3B8C8F25062DD793AD88B89E94A93A4A38753DCD1EE3FCAE78D680638C0B181A99F08EBA730BC90805E56C9C89BBCD093E1C8D9737FCFA8B1958D1C5E022072A04CEBF6CD3552CB1805A598EE9FF199144A5C4CEE2DFC1D318965DDEEFE9D2668281263143D9C38F4681A72096CD7DA420305ED6D5AC10B021D8CEFA981B0015099F5E5725B8D735455EC2FF2B8ADAF" + }, + { + "tcId": 42, + "deferred": false, + "seed": "12FB6DF663126191038F413001776E0791E024B1129DB3084A1CDB809404B555", + "pk": "8DB98D451A84D7C9FDB7E2BD7628EC0EFE6BA51499BA12BF981EF380195E1D8BB3E4B6E7AC1320C295DD121AE504385663CDEE9BBDC461D9AF9B74A36F30E52598E024FDC912F1D51924E3BA090D5E131218F69A80C44D920AA8B3569B36505F4D50F161A5DEB45E736CF04E61D6AC17948F496BDFCE3E9968861D267CE87D3233D12E0FC6A4DB86895F7D1F436483AC051DEF1E5A4738342B95890C90176FB8EF27029026E333E944A88D08DEE0340580A08DCC4A6ECAB4761279D76CA4DED5AA147D656DAA41EDE66F4C838F0A04E2A7B8E18E4413BECF01CE5415A17B6F39A5B7996A84D4158CB664AC36EB09980FDDD8323B2207384F60A63BAA446C0CA5A8982EDF24DD4DED8F07181000A22F9FED786FD3252749DFE193301414174CA01BDFD362D25985A6CBDB315026F813E3220FE8DC1E35EFE3F07772BA54861933B9CA9F8F68BCECE60F9F28148395C1605890D5F2B3E859EB7EAA3CDC66C58C9782AB8D67BA6EC271F454DD8EF82854D2CE61B5A513AB8FAE77A081D4A5B34CCE0100D31DAAED0852B9E77C904EED16AEA439B46BB2BCF42FD3ADDF320B4F1CA1737B8D7D3F7496C7C77107F2BFF1C907BB145CC2FC7F92CC3A3A4289CFD836AA2B7490393563E2848F0783EE4814BEB9F1FE75B5371BC9944029FF463361F65EB6654B588F9816FAE2083A4614DE3AF064D65A1254B4252C8B02F1919CFA11F7E523F51C99EF17CEFB5EB1F692FCDA240C3A0C504F2527A477A41BB2894AE3F3117E96FE3880D3447E1110FEBEE17CE73F1BA7956F397023E6CE4CFD8D3E1E84868C94C0737ED138FD7EF28A7D6E0A047215A3490A031C2E7085EA975FB16D129B7A70521AA45E9300355B930916D40FAB7E197244CAFDAB36C55CACCDD9EB203F48CBAB6DA41A29D686AA198576BA05F4575145DEBC8322DFBCE5A1D0899913DBE93F96033DDD73E8CFA20D92CC1E9869C217586E78FE30351EB421CCAC154089EDA5E4716E1BB022F264E76385AF044FB2EDD00D351B0FDC49B10ED29510FADEC7D7BCB72EDBE46650198C7B221335B354A7F6623842FAE558380FB0EFEDEAA161D0AC5CEDF64CD3FB1C709DB76C8C046CB5337438A72F283476687D26987B2C6C205F9B39BC2DB90EF13CD5440993F802BFC120F6062F8B62344231A268128B4AA66EB6A30EF98CB94CBD50667D9BE107A04C54631570584FD0132EC1F3AE8F115C54CA0849C05258CE87E6343BECC597087369594D1B847CDE8AB9D7D3EE1911953FEC22A2473064AE8BC3F406D81AED4C546C8E0DEC5327F2CF883DB613D5353837C823C005420E2114468B6B29B862FC6D0946964DE31D2490A14D5022ED160288F1C1B08DC9852FA66FD00138FDFBF6A1297B90152580AB8EB3E7374B627F32233E513FC9329A5062B3B376C5A3BD11E82979A0310E6BAB7A66E6A8CBF829E46C69BA03A9827EE64E0077DA863E7B046EE8521020166108EFE63D089A598E1930748A6446E4E817EC5450A07A01D49C767EBDC711F89B07C63B2140052C42AC2EB6243A4386E4E8FBE98F17F28C3C452AD376A2BF51C5E305904A1357D1F1B12EEE2D782F91DBE7891C7255872F43C697E8FD6CDC923FC866223812C568EEC14530BFFB2987E45F44E0F792B234718307275546DDA727789F918EF4897A6B586F9A614187FA19CB3AA3EAE11FDCF108F69581082882AAF9A85744BBC451263AE2E71A2E9EE1413403444FBC4CF5ED48E73211835DD7F2EB21545F4749CDD8FD83EF61A836AFB24FE46DA4A70E8241E81080D6AFA07CD3BEF47DD96A17E079EBCD81231D0D6496BD46438CB6342B7B7934A42F375A47B64B9CE0C08E21C5050204E576E552002FC90C86E92CD46A8E038A647B3635639DFDECDE6CC2628BAF8680529E9669EB28D02F1DD514943A034374C14A603327DA8F83A196FF531DEB4D642513977742745222F18DE817FE9BD55C4DC0810B56F516B673498F7EBEBC49BFF7C73305932E8F86DD79512EB52767154734816624DA121A925DE9A2CFD9104CD2C67F1CC2ED5413ED2C56AB5634DCA211DDBB333C8EBAFAE42771D9F4BFFED56D4C0B1C6683BFF51D0CC804E1E2F6B288C78CF292E0840D60462130DE3224AE058533B510D70CD9D5ECA048AA7472C5DF3CD8CA66FEE21194798237CFB506EE058319764FBC09F21B46850459CB581AE2417992351339F5F253895CC4251670192824A76F8FB63D926EFB1A070E0CDCFCA3B6D91E4564E085AEE5034A10FA2DF175E0B4EF2AC9BB6CE88DC16BEAB87A5A73350D5B7C964D005FABC58BA0C6CA62A7C127A49B8F01B6EB8AA51D3C102591E7A96029A248E4C65529613F177DF501C88DE3938C378EB4C71BAFB61624C15B8A14AB6C5B0840E0BEF1F6BE9FE4D469AD7189B3FD79B2AF4E9FB2D019F98E57E56D33EE4F32F2D21D8C11FB3190E3DE9DBBE9B5C96044D92E684B16C8A2AC216CBAEF735B2C72690F7692392904CEDE6BF8591833D4007C7732E7C0D70FAB6179D13CA6F77ECF27E689F7A6D4702D9BB293F3DCF7761DC6405CE43E32E73D8BBBC46C9EE7DF606BB4DECA8B197BCFC79D6494793C6DB02BDB2F14C3B81AB1D5F7E5F9E07AFF50B64CF2D82254D8E7658D3909BBC27522AB2B6A31394E925C84B665A4A030D5B1399902C0E31E27733E1761E460095FEE4E811C98A8FF6CBB37A27329B9DF33DF55A22E52DD17DFF78643675E913640FB6EBF88430487D1DA2CDB6148076F0EE6C84393D5", + "sk": "8DB98D451A84D7C9FDB7E2BD7628EC0EFE6BA51499BA12BF981EF380195E1D8BBDB2D29E491867090B9E965A697B5E5AE1CF087CE91425ABBE0CE0A5AF62653F1AC1EF5C1FEE6B7F332FF0876353BF37596D0FD0BD5144B2D28DF122762C53B0E688BBABC6FF40CA6B59885C172D7B8B03DF7E9EB847FC64437129BE6491FC9F17844745181084765356218212331443581827422547478716583235137304142402455774301672220067702281740345182635367206821152585408456654052728583200823033372154310824870472281817357366180438076076674475812436718415054614482424484278483046206360807771787771054735117481860335283427845150441828024348673056854648847118566408478657304738565734805614324307071342515464763053856836203744407720261127508640865603645571763504615240651218232156110531767574417578488131402811708672300570030415207614860486716278605250054542784421203140032858080104483743443502057255687503365145364325545780515742727205012463332228222545378481253257774532743251224012706856360000657410838731676482345513625233382538338360685487381801863581234163171801118480454512304805870580353572172486653225874875432158856321508853750572842660701771844633807757246836606614711553870048011642387468317806408144712357547215517244347457800162502560134340120227860884181180845236075730547174351241070547148484732728430350804426817052716534122672621650022564668418360272021232568277144644726668188641422271467488778515871817362810073182218026675237214022420675082370102767463268407376823612174601552176822253665808322107310413688206233547728348046326336582588831571550353146288604673611722768507738570106650282730540010814825386303560441675734048647887803531221650516815166201144723144731234257121763440850075481006600576245770066430232611184655640121061423732475158340280276165264230773851076665813040613203748418653067610885602255487480571513758574384651854415626417420543166747785171622576046385374026360446536560323364081514531124255163224126611340585256771327070023233175712863557000643568748470265527880027314325564436741673163013613563057262677350520653061006868115275687721800851442668541753630261381875745384251303754538638404618280501713206120252623514460810823423805714323631500120804284855515134331476516481847486650288541442660882611657005023631346640283306348184686066537312548854776538144604140728572838456414638133171874875422240152881130760145071162647006611762068256704854336802543356764210411586424602276003305764112061322443824572765215233587274448602602032341352101470571466720431168327107605723515030588630603022537525532211385730001520137417308382054521477265701811070771684871876723563513581351236548745640701728104731485470714068785004725608360521461771588538108418144581302136103731866083078237762606701124574620400076086186400026430204242416313181665824713128874033465213378736357151255754782458148571410206886244328708502561842137167528742821045110640483861757763044035404758481557643071506274125252625457522422851864812233285804123447364523664267670644684325263185521744116250655620038007410050478715435430444716138012661608280614268743443256531360686636133112133285152162217110212444684675883403052787004876652088607383057786732820085417285882C942ADDEFD289558DF68F84C5D3EEABC4272F5977AD513D3A8539D23950C631FB6FEC0A49A32EA5EE0B732A751FFA8281CF1C1D4A278E6F9C87F64D6D7DF0AF6DE3521AF8623512F6E27D4EFE4A716FB72F483FC9811832A56BC22612C7DAA2779EC83276AC46D188158D448FFC8316E526CE5194A2F2AFE14DC009EC89C712C705017E68EA63E9FD3FF5EDDF24AFC4533190A999F2E3909B93B0144CECCE997B32EEF929D73635EEC938BDA1660F58D15E5D9241C6061FA2DC43BC8E282081E324975DDE1B84C32C1031987B8252E1B2D3047EBAF0206691348A5FEDCB7988BA0D967D7FA8610CF7DE3B08A8BB536D2A80C75D74DBDC6DC1383A74B936E5E342E3F425E64660D230779C1BA1AAE18001BFD14EE3EFD849FDD81A561CA83F31531DCD1777AF16A8A7E37280D2C9D7989198AA342F845BE6F3FDC99FF6E4A2CD7E5DEF8D44CF72CFE0FE7A659ECA1816919613B8BF2255B77565CA0E332E18959EF7C4E3912F98BCC325AA4341C079A04C0B62050C9405F4E87C52C829C84AD60CB904B99B45653D5BC9B7CC96B4A8EB2BD62282F2B58A2FCDD4F48031B355B2C5D4D940B3E5EF791277D27E4D9E91EE5C1DD53C5F2C0F77D0CD693B80A97D7AAA4CA942D34879430BB0A5B354B51B3D61B47CB9C53339BA44BA39F617E28BAD34125090052479A275F9C9F787FE355C4B8E965EFA9EC3122CE4ABEF743361422AFB61D4136D5D83EC2476A17682B3E16FBFC14348B2A3618713F78BB39F23843A5FD50906920185AD1692597DF722B6C8EAE0324C615FB051474185ED261C1FEAD15086C88FD18A99226AB93DCE1A11C289B91B6DF0D7466B1AA26880FAD838B520EE9EB1753479FB5E9D17440336302A2E3B12A5602EAE3D561ECF7580B4308852BE844FBD025E598D3E4501DA5F0E4E8059AB05388505374F5EF6BF6D587AD79EDCE255211F91878B4CA75465884C75801995B4F21A2AC32E38DE736FD4D1C9C165F4C5FCC8F9392B768206084F4508ADE4AF5AB87DEA58B42F82AA64B03E32CBB5DEF948A14B6D93881EDFA5890291018F7BA6CC7148398823CD8840075A3335B5E0B1C164750CBC43D852C4D1778F258BCF6898E363E368B4DCB4863DF4667FA505557C35EF6150E74862FFEEF1C42779E870FEF08C55C1B7DFD433CAD4A6AD2DF25A90E840C07D5695AF96120BB6A41D48D4121E05FE703B1F5C8343BE403BF30868B215A36B9E79141409A0AD19E087E39AFAC1102A7D7A2411B4D435E4D731E6CB826F727508B0E7B360BD2AB2A778087FC0D6C2FBBB171EBF7A0CC40DA389836E895A6E0AEBD0BC0101D1E10BD7FF82DFA214631B38688BCF620F7188F33BBDF17CA3FDE11C60D4A68F62C2FAEB9082514944C93E31C69BA1446F4DA0390C250DBD21336667657326246A4CEEAB541803F7810FCC2A9136A186319E8A164D25EFE0CF08D98EEDEDE98BC226826F3AEDF19F5837818514E15960757F5B705FDD106E061BD6777A000169961D5800E5CFB63F81AFE396861CF87271C767DB3F023EA090270D46E4566533590CC29553316C3BA34655CBA17EAF8227C14A87019324D843641D3AA9E08BEFA9CBDFE9E43693E10E3CE2989AD595B1C279B971CB03B02644C8D205AD9AC00E52C9D66042875ED8A8340CE37CE026AF25B8ED1EB503AB1F29EEDCEC95C1053AE4CDEC7987E1AECF5FBB61ABCCD1AB81C38A674067B1D3D1DBB587BE58F0ED4F390F329ECF85EECF686FE7FAF7B065D14AE1AC5805611EBB4E24C609ADD608864FB88339A7C50135BF3B9FD149AABC7B812D9DD9902884ADA215039D1CC6DD687207BA91A9EC8FC2C18C15F2A841E2C7539AFC58C2F998B8D6F683B786F8A0859808150129BE0E57F7FCB39D102BA7346527F6C24DDD21B021835B32E094591087D20E0CA859159E033BD06C7ED6B76D56E49BB8DB788FEF5C3649197DFA25572301076AE65F3CFE0F135B8784614B65C458FF7EC6D386F10B673B5D17E5A2CE710835E5504902484DBF2D4C99B66821F94329F6159DC50B5F9611356F47FF4CA62C0BA7EA6CFF3953F68B3A2C4161D63C74AD4BED2EC2B7B57C81166016141F8684C26B7F7B7A6D136F1DC6669DB16215AEB0664B322E339AD8ADEAEB2631A18E423BD66ADB9DA0D7E29210A82F41EF96654032378DE32083A9DF91D237A69F7895D2AD7EE5695E498D7DA5FCB33ED831361A3AB049D36D605E3FBD7F019651467D06E9D8F14975EAB9E1D30296FAADEFDFC435BE54A23774D2D34284DDE0632AE5BC3EC76CE59675494522AEB4242F296B32D1E8F71B9255D7424CABF83377F94417CB6BE226FE2E42B020EC0132BE43E0D0F0A346A8451AC76122A44A15DD801573C704E0FEB63E9E5C2A7242A1BE0D3BAF8C887C05E032A4E5CF49C462DE9FADF951085420FD67A5E31AD9AB33B8FCE6C22C5E3CFE8B87BD3A13CB921CA861315C7714F96CEBAE615B179A62AEF869E81A3A5A16AA6C5A7EB6A7025BD47D1E734818A539AB8AABB6FD1D14F2D92A22A9977C9DAEA678DAD360EC2B7E8BF72A5EF72556251356937F6F515329887914D81B66FA071C538152D75208B58BD381139F5626F5373A6A319EEC4C79A37F759F27CB2CB76D18CCF5185370D3058C9B9571845554BD64D87D5999CDA335E3F93AEA99588F2BAFBFC9DBA476B06ED3A57D8D913C46FB9734A4B5FF97ACADDF5F6E08C9273F712639633A04C7E7B7CEF00876AD865F2895680A808EBBE6E8AF85EB2FACA81C33E4AE8097A9A003DF4161640CC96506F42227DE85E93177100AC01F05A6E5701FB8841DFA529B35507442480B00088C5C60026AA77DEF2B81EA411C88EA6770C5F849528EAE68F1D83E2462AFCFA372241A988E0738514AEE3F32723EC78EFD8C04ADE28291C309B2217D251C19BDF9E051394414E49AF076CF8A5DF9BE6A4C7825839F1805D3DA89EB2071B9E2486FBEEBF1A5967F1AC58A072901B82DBA4D6090E4A40020590351837EEF6CF6E4CC678F3FAA67BE1E16740E7FDA873BE73C71ADD485001D002CB3DF4FEF3ED277D130BF66D8C4106491448C10B8C402DD50C95CFA53CD8EB375D64E5E7500C66932B33E0A1A1433B8FC80D0EDB37004A2F64A3207512CA591123313DBD5C0C5D99475595F2CAFEE7E9BB138E518E679264D977E2320CFC59F467D889B5B4D3756D532C61BEAE3199EE83D905A440BA311D8F8B7529CC0350BEAFB908BFD7BDD542F6FFA460D2116008F16F0471157C117982506D82E13A703EB53544A8783484526D8251628E1020DADD2F502A5E70FA9E90BDF1CB9899F79B2F24BD5D09DFB876B1845515D947F8DCA2EAA40820556D16BD93382DD3283D98BC11CCE2418C43A35E07AB307766206C0F137254FE736F15821E3AA07EAE299A33C31C896C2569BD39D2A0736ECB396FA4AF9799180C693B342A56D7255659F75022E37D301041297377C228A367A8672D0FAFF459A0DA9C40BFF60ECE85782E991F0682DFA73099A87AE293860B143EC788148" + }, + { + "tcId": 43, + "deferred": false, + "seed": "2D6ECBAAE0E5A784B543BE58A0650680AE813A01C7E0C9FE65ECB32A304DD218", + "pk": "1C2B6801785DCC358FCBD37F578673850CAD84EFBB28ECD828783DA9EDF6503BFCA2420ACE9FBA45D4F39487658C0AF41E5C876C107B772C7366B70DF124C15DE0029FA1F002EA566AF04441D7C7E33DFAB7936F19F34A73AEAF42026E4A7245D6FBA3C21F26EDD80652442522019A72E586BEF8C655AF4B3E6C6AE8B8678A81AE39E3A4D756AF595E15AA8C4ADEDCC4E5BA4F8EB4AB5BCEFAAAEF15A629FBECF7BDC657910A62E5E02E3FA3F1D7FC4D94EE56F252B53020E325C25129C5C4501FDED83D071C59FE6454AEB1271161DD062D0308D1C515360E3DE60C383074944762EA6464C175F7A9D317CBEB83A8238FBC383F02E299EA185C37F259EB4BBE3A9B26353BCA9A1D877007A48B1BE4ACF21AF2B6D1B27EDD5C3DC2A77A17C6EC0A9988F2DF6EF5087FB15D482439D26CF63256ECEC16BEBC92A65A112C2A277DAB80A0FC49A18873F9F62E48E44BE451C161D5DF260EB14EC62083485CF28AE98FABB0008FEB12B0387AA1BA88E70CA703F8E2DA0F7DE8F08419FCBD0A5C120081E0F57A91857D476DAB4BBF70B3BFB7695B48486F3E8ED074B258B930C092F73D749E2671A9163F631B9EAD06D631BD8325B4DCB40BEDD67D9CCE14963C5D4B2EAD21EBEEBB441936039F99BB12E5629D5959DFA5627335757A6FA6A2482DEF787BFB173BABC595DF3D03477F8CA89B82923799BD5A94329CF9B1B950260CAF3152441B51B576C5CA9213E8AE2B34858BD4BFCC5642FD4A65C1F38F5444BD0FAC0C24E6D9AB20791FD3AE3298CFFA4B1F2C113CCACE75ECF9A83015C83ED7C6B20FA037E83529D8182A16070C6AF08652AC7F4190BCB569A7BA00BAEE9FCA16D9B0485FAFB55F048EACCB80D72B34299C9820C0D3E06EA8B08F844D296C180D7F86AFEA7355BC0B48C58A65C55F7582EBFE9D23FEA305B645F31EB1BC7C158F3D14D74101973FA0975202CCC83CC962B2852A409E6C757427E9309746BEA177FA23FF5DAC5ABCC5F85A8D87861104B41B04AEF79C31C907F9774C06C2A4CF36C2E17829149743455E419E672F744C3A75DF01D6239E4492E643CCCEF324FFDC0E42E531E28D98E9EB41A5906BC6EC0C4B41ED82CA86262F768D89A3C8860C18F1B42356ADC9C1DEC2A311DBA00F7E24688642E75C1325D4F72619535302B520660EB56BBF4E7CC7F35EE8261D3AD2174EF0F5B5AAAF9F664B61AE18C5368F080A9238B6D4F4047836C9D784B95B84BDE8AA165B3FA5E582A2F24AEFC50F1DAB9FBF666E4ECC858599568FBD3CF90EF6F23365951A00F808AD1B8B6EC09084C97268330A5E24F4F8F5C73D5C365A5F88D1287C5E37076BF79D3CA40EED1FAD9DFAC8B7A954CD58BFB24C200704E19844BB47F5CEDB184AF2939341D28229F63EAE74D1AA2D14550474247FA3922D2C24E40A5F3A765B3E41F0126DF8A494F8C8EEF43F05E8AEBB1FC899013BC21B764C33CF4EDE643055DE39AE5394C570646828AD265FCDF37E0CD152DD07ACBA5C28E57BC8D82D871C49C457DC3CECE1758EA883E0E13166E4B82262492136FC221A15B9725647B10663ABF3A3B589A73226D8CDC97B7CA86CEAB4AD973D83F85190CF0F50938C1E11D3796FF3BC839308C3E8D96AE71239CE9C189F7F00DB181A95A5F59D371B3F238F456D736AF7A948D9CDEC9AD6DAAED77E47AAA925D9EA0B0B4007E6FE9078CF127729AD03FA43789F38D7277262502D17580A2586453B1C38A24C7F5C59D96500FF01BF04224A9A868264189DA9CF4F3508B145EF402D217CE991419B68E5A82E00BC46DA3149E392D042E785817A41E33C823F4C6D2551D5EB03E9EA862CD175D58FFD1B5D7BFD1C7AC8C6A505D937A36C89A60702B7F64345D13D82BD29C86302AACD1B1835186C5F3F56B9E44E085106CC96907A332F0FDBEA742A6715BFED95D606C9F05B5F37F8F51BB049BA47DBD5EBB80739817EAF3F09810B00D9702A91077D60A09E7E70562EA84492B9DADFE4B8DC957727FA2296A97D24CA5F065F17DEB081395DCF58033AFC2F424A0CCC3220C477CCD627AB4E1D7104477D799833E2AC49AAE6D055C97D32391F7C138DAA8CA142D33CC035E4FABC57F3D1B0D8F93468D08BA33BE80C820EA5B3445B4E07E584B42DC27DD24FE42DA51B410ADC3D8AD3B8FE21C573858EFC0B6E709F91D86F6360C5B7F1F98A4B7D0F606DB60BE93CEAEE79A2112A93D0D6581A58ABE136FC6A87A6FF3D993020A6E5BBC682BB2175C5E6AC38708BE21A501E515CDF4D87B0D1C57ECF232936A78C525FE54557695ECBFD0B8751BC299F0B8A98979960939A1C88F3553A98A30021D27C72C9B25D274D642D50E0B438A65A68C6A2FFCB3D0E7CEFE9F0F5722E033F7358D7710D18A1BCDB12E4D01E3E8A580EF1A830DA29207ACBC45FD589270A9A82D7E090406C60DF24886E62F3055CF4E9E2D03400475D226228DCFCBF396868B1E79F91ADAAD9542CAFF5FE3483D51FFEF8CB247F2E90F489D0066E40BAD3D00222047BCC934FCBB4084D5D6B0397C93DECFBDD0D22CCB2A04ABA3DDCF8E6BDC4BF271EF1B55F808AB58CFBE7B8D27D334F0CFB0E2A8E3926AF6B584BF746DD8E7106EB4D0272B234A48707A9731159BA9F772D1BB885A8BE43CC527EA6F304D1CC25A41F876D393838C13D3FE8E7B1232DD59C553977D86D2F0634C9061CCCEC779862398D13753F046CBC1C6BBCB2184D3B93EF6307D094600520A13C9A61CF8F24B966F33A4E1D4A63129B", + "sk": "1C2B6801785DCC358FCBD37F578673850CAD84EFBB28ECD828783DA9EDF6503B2A3D818FA1632E882FB4B102891F36847D725EFB265104C96C6249D614CE2DA2FD15B9A2915A14F0F18067A2EBC07177869430C6A3900FFDAD11EEA8256258954C53CDC5092E082B959CAD36E830534AE598CB9A40805DA6AFE3A33C781B67682304811862666262674883630257466336654176127111610188405651882248835621772103713057301461408544446057187771006674605835060402676635418131476413436003120645277455515485670383644331501872624770716378003605043343662173545134662807012482221028367326430336535664448056113574018581120523841166041143840318651156482606328312581566713531544126481316674737206548863641151137443513805664368650232741372866237083842038500867032145440548358704527308541843850274876810732814453828163568433334252171168355156128245552322375020411688726150257732451832171850113208171275024208763087043620431368784852342633345325381082054768367221670638442265455241150542031786524420340504232434554630307202834160338843770683236510173416158055663006632524311202770074186756864725651225115207874172102767108723215410126544502265753858458031284223785244845208708477813813164616574044334063467141642437824662515130780320530524304615455323331052410022757028285822155463465307887721528548442757207157143662703603322523164328585723017213078884661343736471304300711110210007661410452167826762283616602211111814737670478671581647376618273266215607470650400468274107273140772805621181485466005826678168630861123665356648222147531357331816374484742736281012353528830064601303473326670343601815332320656614136537004121661334847127484167341210426215347444665228633775855605113481362562501604066143748138675085214380117534354518528803214733100542576016451870144542343240477121026665084103270221073287781215258026275727484778353836573535212634148130745855242442608642460711873814258078850618877672413774513172426032072356862074508810306014067080867427757824824028824108174406026218102520624880108734712762825145441131055432206348270026562148550718452404551485343104823587357361075363067777608700730787068538524620734084330357617168267260432467052780270082138751130213247302351083133755083746701327633651771612817385522241687365428627888010160240244451556860642616888021741676615122361567710825223512105410650126041326541401456171026106665284806160355012356447348246653058504148285820087475110160353520303780551734644523605167821608646410237607101761118786078003148446280063422132668120564163088754007557568310505200680472867527162330302442631523115778167707572822871262554364140832017606753138334338852737720140605628627473251125862002613337020675245162661260861007155034720455157108418561023828220700355382181424101273721445815451858423724440784253713785183511880022873741854405034651712631638575532026648282103088505253625664346403781263188161174460770820772032382661577887440223154505470856385852111666161268622021383012686823504876281517266854274311810301526324508130485562286633448201880388745815358336710062432506786440757406072140568841501477456514813456204417571574122527482775515235688833535654757407187843821823872746421510747450775537360482055485647333021465B68C4EC5CBD1447A46D08AAE37528E592C1BABBCC9F5FE65F159E1C54AD88B07A7C424748C63C42101D44A8CBC87510BE76B9F61F3314BEA466B2F7AD9C7831DD8F077ECF863AD498AEC0735DBD6D0A86F2DBE80487C08E0E15D4F7CA9DC09822E3A541D65A07BB3BF9C39AB410EF2C0A2F707985F8DC2A72C9269912A3282D6D0480D37927959BAE33003B5A03A2F82850BD15266F977EDEDFFAABC2B0BC9BA8C550B5D7519806A574BB1402812D52D6133845DF5EC6172352C2FF5D258D3D5858A2EA5EE606A40CB2D76F461980816BF6A536A79D1667AE5422346BDADBE2F6C70FC143AA30F4C154E22E5DCFCD641CE01EEEE50F42AD9BA102FE9D8A186190A495FA807A5CA7552B8827D90FF2FE48F8F195391E358754A3B032D155286A324CA507F16A815706A3A5A1F127E134BC5B5143659E4601212A46651A4C7F8823AF02BE5E3E04F41F47259C66B131850A7D9B0DBD3A415E078625127DE9F1D602DBA207C0720F3F96A44D86D60802ED16271AFEEC041FA8AABF92209A4D9E53B311956E46550E4326A5C50CCA7AEAEB692176DBBA39C51272036B38FF92182A22C4758D1B865C1BBFB342C1F9407BABEE19DBFE046E122E18CF7A25FEC6A28CE4C33C121ECD9316E9AF0016A16BCCC46CF6329D878F48990351829BE43228F200656D57813FFAC51DC487A86F6858FCDC46910024AEACBBA199DDC66963D914E970EBD38F18EFE709BA2691DDC8CC272095302BB2D25657C32BC64915575B173085D920AEDDFC37177B5FE4F38ABCE426EC46E0723E00982FBE5C7E8E5A4F26540E37DC39E022DE7A08F13B3E9F88D05C30C8970899E2C3FB898CFBBA00AB8DF919FA51CDA3E8193F52B8390D7C274C7F5A344EE42312B823DB36BCCAD37C4B213011F0310DC9BA72B851658DDD5741731F21A6CE7F9059872CCB9ED69F732B7410033D8B5ACBD66B33928E3A7D7D5A28E3245E883A2AD84F7C2409AFF0402E982BC95719C10BD187A454DEFC7D3693AC537ADA62BE47D6681667CE11F9AFCBD8031F92085400BC086CB4B61FA363096DF205CAD59F6859667A9BF44888A0BEE5D4B63C4E95AA59F02C2AA9BDD02519E1758ACE89AEF92F32789656E071BCB10767F2727C309107847DE2A0C06360DAABB356C35086E4C95AC668F0F4760F636754879CED6A1D569FB11E5EFA2802E8B1C8C3935F6C5C097B96EA478143C2D2EA5C1E64FE19E03F180B70F4EA91FA327AE0BA6F4C3179570C62C10A7AF043BE2419959F53A31EDBFA1E091029F96EA203BF98E6798D96727DB60909C09A9339FE71CE9E4DA0BE641F0E8E53B43277EBFBD0682459DC028C6F7C042C1CDEAE9DAC9511E6EDE9B4927454EF9BD651B233606B644BC2DA0B29500B0890D64CEA0EEC968146C5E5FE395087BB4884F0206455290BA892B0D929632D098C33C8D6E27022578249C9DC0C207409799801ECABD7CE84729884E8714A19A05B9C7C8E6D203400ADEAFB0CA2669C8241914F85186EA0B50AB4FF646C5D386FCC3F4178EE18BF5AACAF6B1ECF1F5F894ADE5FB8F5EA336BF88548102EB3C897AF6CBDFC7A6F6667E075475359840328BD9131D2D17FEC3A9034D3C7766110EA3118161A42D3B61AB5AADC71352BCD0B5A1DA9CB741F70A6ED9EFB8ABD5229697852AC27C189CCE811A9025BDDDA939167BA717F1C3EADED18D9FA05C2828673AF274488F154B63FFBD853AFA274E182D83D37C97C7090BB9F2DAF9B37862F846C46E55BE02AC19D23AC0760E2B657C0B1B134FFF3C6753F96EE8B2CFF394B0F5B50CB77E8F7614664FB3F0EA8BA85D45582A71F3CAC0DFBEEF6848C63A270DE0D2696AC4FE1EEAA781349B02614DB517807CF4D2B0AC80FFBF0160CACB94F2C700D57E156774D85B52F5245DA4DD8E4FBD2B9DD1B9256FB65D538582CA08C20C289C5AF404349B12E5B3A431F53194E894A45F7AC68FE4A0BA8FECEFF0749ADA4A9B87D52563572F1B0594C62586BF28A821DE955696AC76565861F6F44A167534232C3EDDCD921F5D939284DA288A8233193B231905C76CA822B72FB04C21B4D7011D4DFF88544C1408FFB8159A597E7C4184BF2AB570C9CD7C0B8682EE942B864A52F4B71C6A79121E16C40DA0AB4718FD859598A4F52790835A5D87018339C221DCCB8011796CA373C9DB8EE2926046B0BC01C4CC6BD84E824CAF382EBB9D2BE3F8366100116F0234CB3C53CB418BED8B8A530CFB64832C78E6FCDC31D830E894DA330737C0D14EADA335E7BBA9E270751BBC0D72A137F3496D3F4057428F00C5E8A6782ECAE0E48C3B0D1220F2738AC092793C18FD30478B57BDBD2C4C9462A37B1639163BDAD2D9A11C36467AE1906DFF0F3C5A7134D09168DF7811FB2418C43D576CCC191F0343373CE73432735B178BB122A9A65AE84B27EE42707895C6412A4970628DF736082D11D2022C08C2759BB086547148C885128882C0D716DB047A5821BC1BBEE85E4AB3C5B8B40A5D673CE74357A475D47E96EC40337FA16C6B2FC3F09EE71E7FD4458712112412F6549775D0F66DA948E34BDC30FAA8BE5241D57C48DAE353CA3191AEE310A055850A266E04BB78982D0432D84531B0B20A2B3D238C2EE1556468A193A9A032657226AC726D9757641829615989251393CE0171AB29F94C1D583ADFE35EF8B9859B67364DFD3EDE5DA27CF277680C65C0589CD7F715727017F02F14CD9622468DF17D5697AC895AE8D46CCB1FB0DA103AE57A97F316BD0179B297061F6286C07294C55458144C6AA2E1932388362559F28289B0361EC79A8D81E6C77E7EF0D3327A85ACCAA082862BF5D99DFE89243125A9BD7BB2FBA35DB442E41E1DB8563F54AE40D444974307F410CDE68CA0BA9B923F82D5F181C141F3160A0450F57454FE6DE530F8661D49E1A87883003C5D1B83E0F21004E2648970E3807DF2B865BB961242943733938ADDD5D219B7FBDBAC5ACF5EF250A67A0923E8908C265876E56907F71FF287A6C16F21F61424D72F58CC468D399045F32083A17736A99A263E976E14492A6791E1EAD4D568AC062168A7E85F115CDC302B567E66A6FA7BE6FC6D6F7D4E8751603079A64EF9E46B9EB1DD50D94D0D85CEF2F7BFC58B5BCC193555D4B83D454CFBC2F910FF7D6E22E9A27BAE8A95A229D79C64BBCA7F563DA32246BD8C7B1D5022E0EDCFF163B03E4A3CBF2ED74409FA652D82311A753CFAFF4D9EA50BF7D91212E60B23424C90EDBAE25F0202D71CB566D6C4E5106C6D618B8E49ADD7156561D11963D2A1DD17A7C2C00145FB0AC9673788D8AC7886470719E405BFCE819A7083DE2D841FE616078208EF2AF75B38A20C61573A4094A6826DC2AE481A2E3391260BB9F01075258B7EAE81E2CBE387FFC018EA827BCFBC92CD49ED433DAFCF00CE55812FF8FDB0F566DDA8C6F7942CF7A9E07E2BCEDF02D2AAF40A66D0A55912F32A1F1D5C5071DCB5EB86CFC576791FBB66B5F0D38C9D2F2E31F86965ACFE661A9954F3FA8E9652988D0D2BF72" + }, + { + "tcId": 44, + "deferred": false, + "seed": "3199830796190C3968520DAD86A85B677558A22257E43459AC684B68CE336DA7", + "pk": "525654293354C2A1B9A2A76C9A4908CF2361EFB2312F8751932347FCB8153A473CF3EA6AEBDEE745DFF2CBE7A31EDC4221052D97347909F0567ABF97ACA00EC5FB1D9044A346866B1D7F99084C55E01687D6482390FF78468628D011FF6435C1A0FA157A895AE77B1745E49EC365F051A461980C4A22715FBDEA55972D41FB6549BC5085E175042CF5554C03D4179095625449D7EA256949E94469DC1E1BC3D5D91F2DCEF107EB8F17EFDA721EC1D1B0F6BDD2DA9F4B628B4D467584A1DC37F33D4BA326A6E783C562548EED4891DDB715072A7105CD1F65D4E5CF147896E3D16AFC221CBE3ABBB3633709A91293DA31A0C351C9974731FC48D72BB69BA69A76F06EF17E3DE3818570809848DA31EDE05D9BA734F898F38058C8726B8E08A22CB0F07482E4E96CD9AF73C9A04A16E3DCAF2DF45DD49EB0AA4B0F263D071141C0AA08CFC61CAFF95AB9AA4D66C20FCEF62F2E4D7A85EC0E4996AB14DB4130BCFED9C9465BC93D8C424D1904A732E5A198D183B7184E0BE2123A135139DBFE7721B5863B30F8A99FBC5221F1863CD22BCC710632B300C8A667C702E091807A3BA8DF2A96A072C991673851B0F30E0570A68BE0D1AAD7910E68C40C240A6F151B559A970A1F10A81A91FEAA8226389C9378B178BDC69A4DE7AEB439007741EEBB06F2C57BBD01D80114659939715C42E7CBABBEC944E40129E4C626A53CB1AEEA0D4C1EF556A9CDD6411010227CCCD4BBFCF634B2B59FC7F51E42AF50339ED2BD88F7D7840CF2A26CB5F64B1CDD1D7671687400219F4291FA480134E3BA5CBC8DDBC463E552F8F92268962D97154BFFD77C061EF9C14D343F49EA0BA241124DD41211E1B75F6C0623CB0822E5FAF8CE10BC07E9AE9441BD50F4AC7D79846FADA78C9793A55BBCDECDD98CE0A669665E33E0A8A142CB338D05CCC9F776A04DF80A95AA00775D52803EF71A57732657EAB19493C212F9EC961EFB24302F32A489624CEBF07F23DD09412045A413C67FA16592C8BAC0C98A5D5476EFCA9B6BFBB38E87D301579F8D8AD6DAF8B2C6B9DD026C19C931C42FF9155DE9D0959F30E04463F264FFC1589A9DBAE3D96E247925892C230A6200D446FDD0010BABC17BE23EB98183ED8E333EE2837B43895E5378D3BE60136696C2CD55DEC42AB817844E77E430964BA68E700B766BF046655954BCB9685929C018B0B3C7747B8CC37F1141AA9A3B190E46578FE93DA3B44BB48F339C861FD4F97BA0B0B4852F839785C542E4151D9944E26A131D5C248EA31C9F41B158F8DA5E025F3AEF3D2A15386BC095FEFB360E4818BD76446D5F0A72FD4954E5329523202D7C05EFAB170D185B2BF0D32BDB32F33A7460DFBC4ABDD929FFA5FA21340A5EA68DFE1DB724E0E9FF2E734FA6A11E5FFD61F086C90ACC6EDADFE8DF68946901C5CCFB5A74CB6B9CE8C490709B0834605FBD161839568FA1413571BC7B350F78F48D23F67122FB629DE30A85C594620B92284766F9F2664C7DD414F2933E0E62C0DA5E48A8C82E34D66C559D9BCA52A06E55E42817F4B5AC06ADBFD3B06433442216E47FBDEDA317C50E2107E8D6592C0BDB963DD4DF016102C8BD78C5134E9E120D0462606EB5E3822D00D235AD9C7A8CF169610C65AAD5480C45E2D9D95C80ADCACBAF5857F86FE4CB5DE389ED1803B05FFE13F724B02FEAD70E900F3AED263624AF0EEF24DDAEF803AABB07EA37366323B6C306E77B81B00B3A5823611C803A62C9287A09035834BEE86ACFDA3EE3A3FC69AE707A74C37CC597AFAFEDDC3490E4F19CF0195217DF1BCD3E24D1BE5787C6A08369EC6867593388E2CC5677A10CE6D9AF6C0FDD970F0D484F041C5A4C2697F92E52DEF895ADB8194A11711F055FB06C5B9137D446AFB847E562A1F5DDFC6F17DB54DC8FCB33C600EC7BD5045F8EED910D2D19D14B422EA6C1F31D3AA272C2D6E4635F38AB155FAB5C8595F5A1ABD240150C1D20DA320A7702A499BB3F51AE6DC74240BFED48D152FD628E7B2854F894718D3B5A94A887B12BFAF7456C418A83356F5D0ECD7EF4955CE1079D4781BA21044E64E71CE375B5AB6977D09957DAAB44CB2B349670B11C3F740E85518124332EB859718719E4C3A7EC3EF474C0F4EAFD0C104C1753396E8DF1090E4E42A4900665BA62434D8F1D3E3DF25569950E401205A3A8649853EB34DD026D35CCA312C5D05842D2744B643728053A93EAA878AF045632C4DA0986AEC5F4E5E0F93DAD38911A8307622A2EE9FBB93EE62B7F2D90B222AB0D23211E71227A2152D6DC2E536EA0F8118464A9C8F9B1D85D6C10BABEA6FDB2262595687ADD404C4C15C4C2189BFB7660C5CBA279EB6FD85A4C5276005C7EC5B3765D299783E926124597132D7EB623D665CEA1DB454578985E785022F680BD1439AAFA60E90694CB720EEDEB301B9E948E424B5D5B4E6D976B6E3BF31029F346024DE71AC2C2B42105FFB6054226FEE8A80C2471C052C3C07D6A4CF749135E03A0B263576F9F19BF7FAD0FA16F39A3A8C4335B0039A197C12465C9C9D6E5D5964186FB6FD7E7EC615F1DA758F207ACAF8B219B256CDC6B5200B64FCB9CAEF6540E2B4D5F382C9D8682B72F3D359650D74E69038527A215221980B30AC3C066F2198F781D1D318B53F0B0EF5A8FDCA5D1B1D6D978CFA7D8681E2BDCE2B0D494A30D7092DF7536B1EAF0ADC98E00D9FC718CE797240CF4E3AE2B8AAA87AF2FAB32922E4A87CD267FA2B6F1CA38F4F5ECBDFF0C879E12", + "sk": "525654293354C2A1B9A2A76C9A4908CF2361EFB2312F8751932347FCB8153A47AB123CECA94687F65EC4FD6FC892101A78F01026F29E0135AF71EE700E7C2CBC73CF903B7B4888927C0F819C0CA2EDCBD907067803377984AA4FF3E17734478A57E2B35B766399418F75C7975ACD04F60063F2F0BFCA26E50F070B0A1A195353724566837267013523843061217340448208603377516427785068105543815455713385838378638182068387137202878174761230078700864648646024855062224860686668854027226160574716084705654107343266361631364842553385601555588856047580535034530370012175508353073724842155863748067168114848882320522407062271240544578230102367855236538671440435531266463107672883753384543572436706682450834316033375243560363701823084801423101304218866444185862300771604518682156827233004524227545010242832663758743810826325221807752832476605018480872813137847777000653666127557527716638486160042404864166636102870313548832240045178714184303667865718102217306530807425665255147226317774324026116685410151810861754650667058078686427182806416042711402016888435813707675336867138675385874877012367321122252527373105272488877008643087733704347456662422460586083063645404228215715050611018103186084667757203763065215143246526035450665527055616815808787430678265678120245012578311308256263333860323880466256476062110526427163351471203052665006541664736828465247818142306281443835837182183652107651602852387576021550653670563332605536365174537158126383246523487401623134168384464856206204768217870623261824124585771546525528033177675181171075524844712203858364348868366630338263454740137745641040281333252087128027252246866743284811231073882131764045468851375840422556572064517855348352776346620056667224700385762102065606267611202427345130114347574537103157673262766574536203507836868203424662260332464514814176307376835282323336537583824722072737215563716516622534570868515740510531360567302685310330081808880645123531722346410845162360657713551527237544415554545544676603556376177653716885147033372853404163258617884540527813328211514033674414257460047837602245324068143272035585220146643616441718725600482680403063464864523457642605402244220645225704532847633875702715808568343465273572577521166715627587343885578373673372766332716633554116600462443030006236252146783520750515425417144815346847112732253776133677705301441278410464448741113474825577724608565567664387072414188665482012132181145627744672156457615822101260650685316686216446276142280271565741485500215068572175027842512176043780617184765347663010028034833058116425222513618208124855666167843357777361347708737016118061814685808301052444558752468101207730047385746728811752708526513738756226634713860484428284725564228166015837222131614501433104081222168277767128212721462486143511455718342443083388355003610147772667647654723627762544342374672085384358876058841431863634132804448410306706760647544551074056854262848837436080043515363533205588831716267387132602472322688526176687873184770211636173375004366841185377208728801202224543227412038046055442545283515488671645386881814722167054187675850246200624520546261410308840183184005181485267722758628353566744521701762386445637465210013676767755BF422E848963E128A6250E1EA8CD6994A61AC9A0145EDF10B3F305466E0ED49A068336C98B0567F9FB23C5A87F7ACAF7F22A9CDECE4215215B168AFAB7821266C858A92579D96BA48BC94A120657B5C60BA282A2BCA3349C13C2E56D7BBDA2D0DBB6072FDEA7A1D8FBC9B9D965E9C8DAFB3DD8EBF78BBC57AE218800125A80765173C6C95FB23FFF90C87F7F090758A1DAC96DA7537B8CE57B1E313312CB26799A65E9AAF0387D2CA3DD5E348918B7CA888E0BCCF9136E55EE70903A2DBBCE3476AEF4CF338E7CAC5FE067E23699FAE85A9EFD9E68242949786AB2A2EA82EAF8053E20953A1EF07BB9E22D7847D9BDB6A06A09948038BA5448337264179180AAC89158B68A6CC91507E552AC1DAE3619FD2FA2E0CFA0C2489B3C9AB4FACF1EC5BDFD188BEC71782AA4C3C6B0C6097AE93C7EA5920A832F6536CF5E81D1A222B9B936D5B57BF539014AFB8ED19B076D5C3EC355D06A7B56523273AB4231A4DAC8942D5DDFD58A73F968CCE3A8BDDC5D4F703CAAEBBB910C264EC2079FF75F9417A97502C91DDC2FF5625A3C535C04C8F95FB0B557B6335299DAD717D21A9973433C5B11AF908BF9B88E4B1941EC12E9BCB9F2B2331B7F08B2EB04FC30CD0A99ED2CBBD3DB18E32CB5C160FA885EDF8188FA8716C0FA9232FECFD3EA34330A61465D4E10C25497BBDBEE15070C3EA66E172EADD1DC7686CC32418CC26AF4B2D61259672B51D6E86DEAF4208F6822FDF28D4F3706D92FC66EBFF9E6AFD36D2D18F25292E8175ECACB7465FC04E674ECCE3A62ABECF9C2D1A52171FB411FDCC893C43C6CFA94B1731F21278378EB94ECD9774054F2D6DC682A07980C87F6C37D3C0822FA30334B90DA764856BC84CFE131172E75639935E9FDC42027907FA20363B0A32C7A29588C003DF13DB2AE9C7BD6682B743B7919DE78F8E819376C1D9E64FD1EA0750C335F56E9326E94107DF6E441EC38507755D3C48301B616782A1F4ABDC98BC8585A18C29E80A32DB88EBC3959DDEEB53638F6D58B58888EE0FE37AC86148BE1DEFBBF3E5FF194F9538044036B95639DD219592F0433D695C074CE6E9710FF9C0B1D6891ABF1396B5CF34BDECE6B3F559B1D813CDAA5DF038A949AED51DFF2C2E821C643032FE6DD6A74803E2E2DED13D446BC969AF4A0BB2B973D5CC54E2AEF9896EE166D807B0E41353D6DA28D8F5FC2F3D991CE68AAC6DC75663323080D5688FC6C6DBA56C033896F0581BB8E9F0E9E3AD561490FE9B8702D9FD32B652C7E7B74B74A489B981DCB598B6DC38A7CD69C8F429D1B2B0C827D8AA31860842758AA1720D87B23074DD0B70601FE0C2AB6B72BC4FC836C81EFD49B94AAF378AA828CB90242448101732633D0E68DB2573588809CB76A80066109F6805445F3880A4CF143D02384A5198E84796EB9E3EDEE3C64DE761DAC094B05A4D8981CB54B72C317E4ED791C49159A4E4E8C21F869FCF320F90C0E67B0BC2BA193E29E5018213C1AE8E9D256D8740C5103DCBA8EAB450A6E259B334E3448CEFEFF100D03104F810A7CC5D085FA80F054E4AE67AB242545A818E4EA1F3586945C3A4D242EE5ABE14DB6EA38F50407A88DA116D6D3BAD935A32817B4A24119E9A103FD7E6FD5D5E020EEBBA1390E5151FF456669E4C14EA8E7F343769E7510AA68D624553ABFC6EF2F839AEB4D6D5E1FB57510D3D7A7F0EE969CCB11FB023EF279FAEAEC6CF377B524D206C5BF4E529C315E6F23D9AA4D8229F3AC1A0D77B26F3530C80EB77A55F45AB9FFB9FFA8B8EC28F733BC500BD684D49DA1FF31EDCD20C24231086BEC40E937C2AC1F2D4C9EF4D4274E9F15A6F961820699B40D0DBF4D11149E5696652A75D571C61E8ACB9EA96B5EE185ACFB344C9DE2EAF7F956F0569766EEA44AB42F0A2982F0957F5C70DEB7248F6EE23D322669E2FB3520CE9FC98BF79636F5156D9678BEF7B19F916A8ED1F7EF9D34FF853923CBA360B10086A64BE6BD6B52A90EC48D763C5E00A9BC0822836E594AAD9BF91D0945638B6C6A961DF953F69C4DD75799C7B73CA6864746EC3402BD341CB14EACB6343FBBD244BDFE1EC43BD6A5A0B1D3FE2D896A04FE8419DF95A691020BF61D214E4736EEAF25EC01304E6CC167D8EF969B8E2ED2BA6F5328EF83903C73ADD97CC6CE4BCA6DB63615932D3D0865EF837E335BF54AB3CADFD6EB4A7AB5FB441644AE5748CCE75157F669863CC89930393083D8BBAA83735DE31812E471B9858E267C7E646C3F204250F8D4280494ACB87D82052B0BE33002806912DBF10597CF46D78E8C64E648A0BC8A756D8F09D1927B73385E8E8E960CA2F3679ED81B0461706F4864043D5DF4E5CA59CEF9A484513C86E2FF44C496498EC88C0CC8BBFEC45C9A9E233730C4336A8D4DA876BE797B57635A6CC532DDC701A688AB712C8380CD169FEB3CBCC1004637BCC616B7D300400B6C55B0134FA2D6B96A8AEE0A54FF88895E9A16FFE4EBCD308C7E112E0FD81E64C08239BB95D52EF32266668E4F0F39EFD341B159DE7C8EE179A223D398BA70A07B774C04FF711EC50B94631BE472232731808291AEBFCF6894632B1C1AB119243043AC5D0C054B60883D2083564133FA82F3A46FB59F86334BE0C6E79E201DB85D35432BD1793ED3B28DA8F65C7970DCB9FC6EA0902E9B83C4C8AE86BEFE01D3D5DFBCAB946F017CB2CF63AAF8B65BB26C8D6A5A73C9DAEFF2FD482839916D9D60D3919607CB99A7434574F05FCF15F4F4F03293F3EF2F5C493CF867A4114F134043C5A5CC26F8875B6170C787FDE2247DE3AD7E80610F6CC09F58B66F6DAD4354795D49F994535B4424244F18FC65881F9DDA7900F7066B3CEE542575F13C9B0E3E236E0813F2D7580AAF8F9E564A3AED65DC17F0A6EAF79F4015ACC811F5D2145E51F72A1680957A97D36050028DA3D3FFE4FCFBC223CA4907BDCED64101577E2418821D77EFB9D868FC824D7BE13A28CF1EBA4418BDBBBAEADB54B3E162DEDA47FE29C993488D2B5E41B390BB4895A49717BABDFC798474E852CD8B573E960B44E85A2174FDA806F97A991BF9CFA8260D0EA441A032DD91A24C2AD52F3B8064226B22C73DCCAAD5DAAE55E5FD30FC31A43B022D997E14E71D3DE8A8E1F4027324E22E2A7616FEC4E0ACDEDDC12C04A56B65F0C00A95B8C1DE9B61F7C589D0D8F158E5C9C65439376E5E935CD7B149DC883FC602370D38676571CA764E6E5A2467EF5E775336BCEE1450E0F978BFA4A0B4CF5A72C259FDFB18E54425ED83E6DE7086C5A175729E38DDE3B46E751AF79BDAF0325EDD7CA791F4F760FA7279A7C17CACA8DC172E47362F90097EB36A8CF14DA378670639D239BCDA3A8BAF29B12803CB26891E4B0B24BC61066A490078046F000324E5186C39EFABA39C5EC4AA8E9BE23BBAD6D7ECAF24A5BC0EA0DCDCD90E17EB7B90AE56D12420786F07C8F2EF7944442AD36E2ABCD1E66E694D6B949EC2C5DBE99832271F3A70782CE889A55D93F78BD4F5FD19C580F456E684644DDE65A045D6D64BD99" + }, + { + "tcId": 45, + "deferred": false, + "seed": "E788F93DB12EB4DB91993C6636C009D06D503D5331125A2AD635354AF49ED3A5", + "pk": "370D66BF2921162F6025F1784F8CA45A58E6E72EFB8006078785BC023D8CDAAC29339D545F3F03DB0EFCC2AD356020BF1DB8178B123AB7222FF4041955E4E9338DE146932623EB6517BD73687A51A67623F79A36735AD64D63641D2AD2A040E8CE85DABF03D47DC9A3E98CB8098FB22F84C370D240AE0DDD46369D02ABA059E31DDFD5F56FCFB2CB7066B488C73AF6958DCDEFE66FE5CEB0FCBF298CF576C48F3A1DF542B5343EBC8F2E80CFE4A2D31DE6913EE5962A889DBB22067FB377606CC1AC663787C04BA8C2BBD0273D38D71D18BB7AB435544535A60271B3B2045636DEC30B0727C3C527F00DED0F08D372BC985F3C8FC12E1A46FCE031D8A2B5FC93EDADD15EE8431435A7C6797AA343D33B57AFDAFD870A643D927EA85C01CB43AD709B72F1909DF60499B75B0A29445CDBD1211EDA6666695052E4A80BA3A4B22C33B40BEB3CAB8100017807E5FE4EA49E3FE419EC2A86A39631638C0122728897254A58A4571E31B46583A8E37AEDC5C437E27728B1F14CB7493E5698959B6909FFE54A0293A754E34B335703DA5D99D6B146F4C7118A27AB8E1F9DDA161F03DCA0C6408DA273D5517683E5E1F7B3C2F29AEF73F75F5E60CCEB99AC5327F168A283E590E637D33D6535001492DA965AE977212056569F2456C8F9596DA43989D9162DB32D8B2B989000ED4B3B9F87D1251F5FC9EA71780740761711E74D7EFAB8D007B81E848CD2493117D3DCFC2BEDE8F85592D8265AC04B95282A06EC534E056ED8CBE73DBC07522E1E03E160227CA1AB5CB3F08D7BAA56D03F9B7C12DDC71B69EDE3F6181FE721A75DC0931C11F75D08754BB461F4A2C6CD584AB8419B7BFCB7EF2E39D8A4C1292AE9528FEF05C1F5D6C7F57AD50EF626B32EB916501E6FBB5F9A854095D28F8F6CCDC3C8B0D56D6BEABCF8578FA38FD947445C8A486A8AA17CC5012C64B21709EEDDB0C4D5955FCCC688A9838DEDBB005B7D73FB63480B296F23282D32C01601758632EF62045E9DB865BCBBD026F5E560A8B3A7784EF75B37F03D2A588B53B76DE01553F78477731FC4FA2759CA49D03004A722825118A931E9E0B360B2AD76293F52CB80A0311790CEB79EB2ADEB151052A4B8C220140BDB45699C12824D1416EBD2A1A18A16EA70035E69D2902873423AF69E7A7385F1245BF06D1683CE862441914D77DA427C210311EF8A703CC2BFFDC70FF7BBF310ED56EF30EC8D9125755AF03D2809557C89B32CCBBECB40110E0B786567D8531216EAB5CCB8C96DDCF03A3CD7E0E5D6104239D38B8DEA3131716238B2429CC6E02CE3DC8AF757D852AF7CE141E70A0BE92AE640ACC586FE960A440C4089A515A6979345D087C9A31B7F6594782EB57FACF3ABC51FE40D5CD0328CD90A4C840C058313B97E3C330BE1273C27F4F96BCFC066A3476F7D89B5B1609718A1CB91C3580CD215DD9EAA4A95564F42D6D6909C52759B030BFE18EB47A7B9FD72E1AC05C946C372B01CFA06682B48358F48E0D76F9DA3CDF60BDD53B9A09A641E12CD593B6593A62702A1FC7925447B1D7AADA5C8EA884E1D2A9510BC2337728EF44D66411E112B71B2C203C1F7746F918CF4F29033293BE45AD2B4A7518C3055778FBFBEF015E57777BE7A8F6AD535C0985E174AB4BD96CB78F322C2EADDBAB2CAA52C8989C1F3F03F230EEC98B52AC6A0A2DE8C7EB09D0E1B81834B686DD3D9AC1920EF6D817F429B3C314240487B0C527D4FE754A3E0D42D8167AF4B05283437A76D164731B51894F4C3879CE88645F389DCCF109BAE5ECE09193EA6C35DE193F6C68BE0827E38F4FE434A06E761B8B669B22896B9BF891F2F0A339FA0938CC231C37A223D44FC2E44EA78398F452D32BE8314802971ADCACFA737B2B90CF1B8FD3387D4D774C7BCA754BBE8A06C6425B24A0F08152FCBBD0044063BD419F6286B26CC3104416CD3D34FB06A7494D1FEC445589E56E2FD976E96912F72D377E4BBBFC482803694045EC116F4D5CE28AE3D453100F2F2ECB8057F47D41DA549FEDD18C27D79499CCC62A503F4B91E44EE4471D13B89A3630A4B622151EA3AFE335F19ED80FFF32267A32A2FEF8B49E60C9437B7405A35412292B74D3C38C825DA7D27EFC433167AD46AF0E341E8309CE6A95881DE1C8A67A9373E712E95B1EF948AFE624E66588060CA6A4197335E6BA537520DB6869B6BB114E718519BB72FF3F913074EF5FC9CF8C115104E514B22E37A871C48AED07FF93656FC99C3F1F1BEAF5EE12CD9D86A8FC6EAB7CAE5CDF5BE07699B0E801B9B83947C6D78254DA8E77B82330585EA02B42F87329A76CD09703DD0A24E01B1B63ED00926B4F4E9DF2277256A06EEFB77BB04DE09DD8B19237D40F141304BA7DE9F9EBACEBA0A86B0A73310E138E02F0FA284AD4F47B2F7A4F18F0A166E24025201F5449F1BCBEAB76A18832F27CC5650F9B3AF19C9FBB8EDE9C5561E43FA39503155C865BB9FA2D97FB64E8675CB8540E10480A85AD854AB01C94909C07A4A8DC2122ACFEE00450E5455B7BE692DB87A94CE0F367B3E6E40687E50D427116A9DE98B1FEB0AD0042FED0482CC695EE6ABAF5EBA5FB10DC46820643F4C40226197096714135716F74A10888B2CABBC27EF3D4C4A51E18EFF63771B43C5833B3C7577340D9E729CF730702F2AFF7BA8C0C3812028AA36A112686DAFCDE36D5132D4EE31203623224127DF3E69372C45D7B9E0370A3EFCB9577BE0952AF2E4C2856C0C156858A12AD1E6C54E51E4", + "sk": "370D66BF2921162F6025F1784F8CA45A58E6E72EFB8006078785BC023D8CDAACB6D6FB5A7F5B3C55D1B7B4D99FF4A4E464226FEDA9E8C986B4E5F41A37EDB84F87FBD62731259FE7266BF78C8C1622425EF797EFA30EC80432808B12AC45919A2C30DFA9968D2FA70B94C03CE2FE4CB15E52A9B0AFEC74FAA276A5A6C3913558165301232343767500140645258743061342542321447425681352486528374628548377702443573345023511515432272262636387653371116077564331128261673582164376865470573778011771888324265183248748526461364218768355482805103865333082167526282242560783314370341456383857383578161652306885528655175662755151047138555553146534343846644604080124474864542472815033627744112223432243010282717120330873340070542331872402377068660004410221333432814123760781816702355556354318770785856176381340622240247180674627437023487887142122356311528327715685414266201482028121764321760138877428245535571814667284614438305271345087160060677013335670831368663514625548365687250184502508737813417187476721462666327610566282504268562450465824881154630675748446771056374112326181781302812218455007821574286647628015822857841575474420251404400700360143301022535255431143253062813825455084682005502132778411085234725034175400186665763287222312538538408377111638782350433570758668635031106555035670557521681012082802587051366781137117633440736821514153673831736211187582851663268227614710433747764655121055850228627771006367547345372746630418234207825131867834621675040540865400710271240446255678587535712646677663862756162648235733574803251637433612543243468478708540037560522713432554677321560753633540782667588111844775721082267830084100184201347637783057758451023428802706114581247815517568146814871862414358208702618046381513554368158677108340188165884412034464317538338522232138722036733523471141710411066612126271743047838718830351623801480688837684510742872845350422860251052626017351858365885606700612771843631480036820157031348205867520520487765402767737510616772508510833486814641587451664151854305857511507587221816184780048357254801883803628823755313454274573606336453016746307562240318134330413451401315522363547183446584200387332666582654003115726104061523538637014810542557514371810386337213708847727654658851037453520630457682353101720774353267248527376013051436822206685057775611555457025261832548641805611352714453114181682076074007865877368448848734003148417023366531156644485347310062806883886101206088240403774741141888061787233830058632806617875630436082502522148484676107601474733117287574076826454801581084362107263126264670065123516671432478772264052013128365223266326033557830542056876118774244531751804203463628628086531048064586012217077568726234013258648566632205661202682265777756507302764142182572022616275154047553442287404117336235135884581014567433756542883011752430774456756024433362318460726861231472815238026480165521125855780525541506454870715826252784875538606765743657652331856072572662706465271157248031452273677063333062566472476428010820161672272014834502781064534320058730853758777214125800834724680368831480488687653825566260382261818011441503256800555554122412786818455524643670578000882636824433184045576563440255AFA30ABB273C678163F2E011A3AC11D88762AE6242B03E2CFBD09C41F274AFED4E7B529A15CD5D36CECB76A7296FD7EBD5B56C185AEC70357C401FEAE5F89AF063AC7333ECF31BE378348FE5A5022A54F3A202BC48676BB6EA1B284E85D76EA61CF1C09A97584756145D383D3495A2EF5718D2A4DEFC2C8F46AF896B41D399BD324987CFEB50CEFE71170D668EBD607969325C3C342411B647BE4CD2D77653EE3F5F9C0685BE270ED0299EF45E119CE37FAF027EA64B0D54603C59566CA9708087A67B2D43CD438848C4A3A0485FE9F9DB87522F3E552A2C91A18BFE6685D335D48FC9A633301C126D4098310B4B24E1B142377FDFF5B9E55404FE682E8743A36BDE3AE2DF8698E8BA14EA9CB895BE64D9AA061E2ADF95692AE3C28E90A30F65662A33DDDBA2598CF925C5EB9A76D7388BB43108FAA4208565D77EC00ACDF271FF2A3D017CEC9DC5893A655EB6E438714AA9B05AEE119FBF4E18147C2D21357BB68686165ED35550862CDA47A9B374B7F7AA5913A4B502DD3113A85B5A125CED5E88F384A4862A9BFCC42B74F52DD34871C27C03C90F288A43BE6AB6EDB01CAA1E99B311330950E28893D355978FDE12BCC2261CCA37078D4C74ABB70E46F82D5062BCCC4DA6176183B4DCCEBB601D2C8BE0953754652CCE06E599DDC35C3C717BA398882922333D52F70D9021C57EFFAAFC163474707749105460B9061320CF20E7E53686B306C2963FB84DEA297D2B4C4192F1497F369D52460705F25A1C9D1CF428A59020261B100A444FD057F2CA21A5401B178F3795C6D95260673EEC3216A93C128E7B50A6E7C70D2FDAB027D4E192FE36BC45D738CF0A08BA7922FABB19EC4A755C8B22B57C66215C6CCAE9421E93719EDF47929E4999538241D144C68947B5D9CE9D382F797D0C993760F0E42DA8051E8C1709DCD8BCA4534EBAD89C67187E704E22636893E910D10C125A873224BFA48ABA7D753DB4677F2AB120BFA18F8F0493A396128F6426D2A4265FF5B14D0A287834CF4581F6B978C66F306688BA4FCF67FCBA53FF05A6E98F7E288DDCA4A1DFC43A1492F3587D450099693ECD43BAA35DD7AA59513E515C1EAD179C6004D9FBAF3787EED000374BDFF6B72789ED74191B821B595DFAA5D359DA953E26E9B572A040E4CE2172C4B73AD0FD3CC21F2B099B7DC203472BFD8DFD40C8AD841D81A1AE0A7677A666CA8BE53681152E682A18EB6C804F4605630A1429A58C0293B880F455C4342EED532E240D27861D084C14D32469CBC8C62F997C24C8E43D675673C8713CE03F460DE306DD194AF165E021F049541793C97343B1716CA0BF9B5AE4D330985B3EAA44C60F706326208C8BFC2889351656DE62F647AD6B40D6ADDEB7345BFBDCCC14099F34A77D09DBDFD65E2D9CB09F24EF14CAB57AFFA9C5FE48C483F63212821CD2C8C9FA1046594646881D40A66656AD9E0534E3EBDAEBE1DC3FE5A6F96BF5FADA52A7F730411635B3F696448A96EE1C5ED717D13978D6EE381065AA9D3C8A2E3508BA76001427ADEB8E9C706E030AE2C41E64AAB319C767546AFC2DDB7E1E5AC0F51EF6D235C6FCF2401F9DE246C80261E2469F26B8F77973F22460398DACA28FB963AD5FC4715999DA55FB88864E72BEE8415B441521930A00C08577B609CC1240723E565B06541522075446BDFDFA6E21A45CCA5297032F0DB06024B59F347BA50F2787112131ACC9A67F41E81A8F4562BBBDE74381F3142F43759600BA69887F5E80E0488BB1DE61E1169088DDBB188D2464722469C9D9339019FDF3D1421390A156B33F73E23CF9C2E1E8139CDC12172433D7E5B62AB55A88E34BE956CC62AC6E469C4DADDC4A3BEFA5B3D7EF2B061C541A6C8ECCF2137CFD0EF24D0052646492014BF6A604BD3B8E3491497EBC008C68033A48EB54673DD28ABF05137C408EC9051853BCDC392F6AEC82F8EC5CF285B7F8EB7EDA1DD96EDF0B264880232EF5F659EABB78ED48DE3BF7FB439D3B1BC92DCDC1F53EDE8957C8FB244483FEF72CA1F18F458CC5F1B8A15DA992AE5E69C364B59D69E2BDF82B25DD56AF4E34546DD732882E83530952AA7ADD397BB69FB4A5091DE23E60EE3F2FABD5D81370AD1A16DCE0D4660A5488925BBDE4E7F3C989026D8788659EAA0CEAAA8EC16261F255DF7298906D9418B92DBCB4D1471A4BC7C6842321794E3CCF1DD5EB2E3D13A47E5489223BC1A9630AE2B881A160650CBC38E7198494A58FF65F2099B81B44251DEB1D4DA99EC3658366FDCF918919741A4C2A0A91844F4B97F3C135392A9E0D41AE6C189D0D93D4E0F6826D142D2160B9CFE60B7EEB0AA148BBBAA4DA7669C72990F8BEAFBC6ABA9AB11D3083E2C337D3BA6778BF7009F444C122AEF14F6C8C1D800619D22045C88E80FE1E80C505FEBB6670A79802E85E96CBC73E15982DA42BF530FA5500DD321D8BF5EEA7E02B578A16C099ECFB47ACDCBA485436FF5D13009F51E53BE19F457187CE214C7E4D1C4BA0AC68CB54D3471F5B1CA714B5ED52BAA5EF9FE75E9758D1C92BE75B821692BEB24B8025D2BCC2D54F46CE8F0EF4BD81D35BBEE670592184F63C6D87E458F442718C7D5E85BE6F0C1EB0D9EA0238A33040D4D8CB0CB0DEA36931D1D932840893743AA426DF8B9222E80338C15883DF42DE0AA6B837A9BB7ED65F570ECD05DDE4294A4AD23D39588B218ACF34419F3FA581E22B4879093E4B35DD2ED116690A96AF422F10C511C49393FA25B61FAD39A14AA33564EACC82C8F65A5D0227657118527D66F942CBECE1C776E252644B8A97E5A564038E3670C31F3BFE93366BCEB27648A904152FC907E6BE8B6A91103CD55C8000BEBB60545276D595CC738B4A2B1F9E30693FE9D6796DCEE7709FD2458A38856E579347C560F8DE440F2888F38FEE3C905BE51303807F2957932F96A3ADE5CA77E5616A44B510B9686500CD8E97950AFA67680E236A0B5258A13DBF0E096ECD086C74FB5476E2EC7BA929DEFE11DC8F4BFA2DBF21158EF72ABCF0675B29709AB9FCBD2755633BD274AA3D5426EEF9B1F712308E7CAD98CCF4704F1D49CF5E189FFE80B4E17F950A1A4D14FB6CB6B0C0D910BD527F35498A1379C9D034A15AE852BD20395D4302358B3E09ED64724432ACE05DF83C3573D71BC5C168C4CE160ED2B7A79684AE20662651F988AADAE591159A1400FF9B91E13279764CE8C14F293A0346FBD8EC833BB9D6A4DA4260DC221401A4AF80CD8B71420551BA188AD8DE6D9723F49433A7AFB855747530246A4D1128B28A85A6F16B7584D4AED3809F9A2BC0064B5237823FCD1EDDC92C5F24A168AD3CECDA772D8A9740FFA20FF91612B1E13F905B2A81EC4A2C69D088DF89F2F20E59523667109F3664056BDA4A5D70718302E509DA989106B1AD7370C4A9527AA79D2BF8226ED487FB44A5B872DE95581E491B241667C01C4AF5B639BA1B496A2191A23DE453C15F9EEE2EBFC4FCC3D6098E31C9C33BF8908D4A21CBD14302E0F0AEA458DF776D75E929487A623A2FEC1" + }, + { + "tcId": 46, + "deferred": false, + "seed": "03D86B249CF84472E3B78B12110E2C09C7428FAB65D362760D0800914696D411", + "pk": "8848322A566CA6F4AEB022CC41ACE242F84AFD48EC429FF2A107FDC381DBB63AD301F719FE8E5784BBC4F7952B43182748481EF5F9AC848D277C819E86827DE234CE3D1D90CBCBEF2725971CF3A559CA903896566ED66E4B452A1080B7E825179882563CD73AAB0FE07452DCCAFC27FBDE1A94D750E27C2A67F1B47397C50BF0B53E1C2CDC2DC13B333E9BE0399F271287E4C9BA16FA122C418B7AC8DBD5769CE792A66475ACB94CC55D70BD7CD91A62FAC1E59139EE46072A7F76766AE4A1AC3C52A0C689ECC001849F5F6CE436B29FB5552FA5F3BDBD662A85EF86228EFF2EE4C9B0CC0FE78F8DA5A70231D6594430A70C878DF82AF33F1EC8C979FCC8777E00E77C457300461CB93E9D33ACA87102F0B217D36556D9BA2C2A23A736628357831128B5BA6B649109972B42B15C563B51CADEDE4CF3D9FDE08B456F7A9F2EF28F3A7F18D5F3CF4BBB6BDCCC98F801391D78FF0511A09DC07CCA1A81E63B08C0EB738E1F942387946D3B3BC7A0F658AE2FF83310988BFD4ADEE4129C68DD665D12211211C2D9582F80AC92CE3F943B61C6C45B935D38B27D3C1C2ED6DDA42FE43D5DF6E5F6BBBDA654C35DC259114D288C9359FD41AE8C2233AF33D991BD283310BFC261CA0C45288DACF1319A70E93A221ECA835A6CB1FEA3EF0CD1837C0C20C51C3C8A6E81A2FA638355EE80B61354F50A061EF5DC9E3F3D41B37BB08CD9BDBFE42A0BB909BC24EDC022CA57FDFA2AC70ABBFA851E2A2FC73E72E06DBD0A73CCAA91F399C72879DFB993F17408C9D8E5B60A6E74C61DDE19893512E63DB8CB69AF370A8D0A91EB39334900EBAA892BC6DAE48D97073553B4A479475EC1AFA797345C6743BD395D95A16B2E8D494BFB306B83D67222B09CA917334406EE4A021D318F364405D74AC23859899B6C758762369A63EA6EC3C9236FC91578C6601ED2ED93F0873026E792C010E187C54FA1CFC58BF88939D295539566DC50600B4182D5013C262889AA964FD15ECC00DCFDF57B2F7513A623A405E31811481937FA6D4DEADD7402CF84D050E4FEA37F5B86DFAE2370B1BFC8B9E6DFAB3859A6AD8712558E782E5D5C41206A007D19D20071E925EE25E8F10A9F04B09F03A4E1AA017A7779CB13AC5D67AD0E45F32C216F60897DE2B77B2741920EA73DA07ADA1CB1E3AB5C7FF0841C8B4D3B369DBCD7E5E705DB112D0BBAA7549ABA02AD762460BF2A80D39918B99B5A0D8CF7BEC174C94490C3FA100C19595786AB729C05E0E02538983A145E4DE6CC10936CDF2ADF465401A15492A9C0834D5A61F41099BDD7E92E27CAE2377D44F61E52C5FCC46F58981A1FEBA332B1F19118362EF2D12D12CE80BF017A1AE2753C20A9AE0E8BF4ECC5568D741BC64C3F783CD1397400DDB3DA525A3338F1A725EA5759A4A2B0B4D3B0895EE07D534154FA16D77A3AA3B205A8CF06274957C4190D47FB9108EBDE24ED0CD544086C3ECABCEC0DEBFBC368C0AB67D065ECEE9CD671784DCB4DD769A944E44D9B951AB3F4A890C215C1B9C9B962687A576A0BB15357CB5F250EDBAF7AD5EDC3FCDA793425AD3516AAB5AD9A01F5EB036C1B6DF02EF51516BBA767E1071178CE25D8591BCB5276D59233F91EDEF0E217F39AEEB605F6422EA5D0F47CA2034C4AD449C87DB3C42A5F2DEE9F111455DDD988A7EB4C285711AF467CF8BE4832DEEC585F2CDF7F68DCB3CD25339451283E618A6A3FD8095DB07B8F5B5DF79E8055CC8EC3C2B55E0B23E18CAA12A991086C7C6B87A0713B4268A72A9C3A2DB6B07514C6B7EB0449F20B096F88A754638E55E9ABAD72343C92DCA03FD2C4DF16BB2CBB1963C8B9F48704CAEAA22359468BA67D58FF29E38D783999218888650D6B414A41417D239E6FDFF8E382F107BF4FEB81744E074A51531C38B6DACEE427547E17BFD2C2E4F4596071CAAB4ECB31CE7769F5EDBA651F6CC4380A8A1711E3BB12A3D8A061A11F669246713D29442F0AD39629722ABC838CCB51BF80E9C440C2E2EC88D93076253F56C61816FB725739B4E44427FA7ECBB415B6E5675B6AAF736D592C28308CE432D117F388536C83F90CA8FB66F1DD543AFD147289DA0C8DBA45FBEC3499DB3EE000B26B49B0FEEE4044F231D5AA9C71405FBD754BB43659E3B59980FFAA3E0D78B8E067CDA206D7809D76650E4672EF4DB8C74E6244E82EFA9AC02502E3734FC188F434D3ACD65CB7F9B988B1D69B1FFFB69D88EF2EB1F2B70A2D165B0EC78CAE92447EE5376B0AC4363B98689076123F2DE26DE1928ED2C4182C3180056694CD6C8949A85FF3B1E24EF12614151EFC76D8652F04017ACE8E91D57D059D826CFFB93F3EE6A0405D9A4CDA1BAC97D906A14537F3F4E62DF70739B94442884C0C0694B438083B5009646BFD58B73FDEA8E9C97B18ACBC3693C07CB6C750353F8E8B704B2D01346619ADAC4A9B05FA4A478C7B8F2F6FCDCD6F9766E059E9545BC566E2ACF6961B29BA91BE7C425B1EFCCFD2F8ABB9E3B9FEFBA2A4371F8F9BB20448E9F2BDC6B5B0DD4CBBF04B30A6F819FA271635FA5CCB6F5FC1C3A70E40E31E2FA23A640AAC6B4C56BC07B948710E66284E483A2AC418313126D8E79CE9D31A2B657BC5E5D7260019E101F04CCD200B29DFEC7CF888CCE69C11E70115E36E62D94BFEBF99C2B37427AE66E576A9A7D66CE0BACDAB0836343FFE0C5AD719E503A07952FAA8A08BA3380AAD12C1B16918719B8035109B932C17129B881015F976CB27854279888BB5A7", + "sk": "8848322A566CA6F4AEB022CC41ACE242F84AFD48EC429FF2A107FDC381DBB63A8B9205612461E15A894899F582B63CE137E1A2F6449844C6E1AB07FFA975AF9257EEF1899B521DC105390DBE918F8858644D8B4BE502F657606AB402E005A1E646FAB4CCE2A201FACA5D3F8073585D77E8DAEEBBF03327BE684DA62F446FB8BF11333781374634823864042432083342054315306250442250826183726662656836707207736660161824455431866318670240311553240312347115152581385651705245784026155414134588730150508327407213452331305655400268516817024258565182057835868833071380163376245221257278005855363453284531033783707576026861505718742866514771740874438446244726810142022470677257603785402032470565871511738035371647503025642426405205382454702086852403683351111368612567430634780474174484634822170721682005744765345483340267364815826771864626134365402244150866005531353283300630053128674405643208648637486012828554178631542254248251856301082170407214768471150867840383624825684364366438030362238282104043061255215621210686101367563532532562306760522550345502415700162084747110886865313326700027831108836087336210727177214467302222658180777371060148146602645888401352857182336671315855802221313438166008560261203061705863553051286285235608241467031187205708420581371001823637854571517586144832155022232600160485088873722360483602837746658646860177715055875558150641212362263864175584814328466146518265263274857302328063567642227558860841183338043285138556553222668166416277534867861727330746664576480024537803586435081208274002737517430415402722305805887888006778232512782523462685012826525455106007263311385032752711256051815357843176702263215670485563168666680358667680544184345338385515177482431554648487165220470888673712742761144130066376423527701312468340042581563652578411642814866606020050483618642353848611076208376042661087664224038705704184504657206570044150271443252440031002705772661801304248550017226385876682044215363807531016374814725644264133280774048845453460315230256666151016313714182805604006003275203431342570007274782878487383272346602306120123182336428852143161760614620647282877803338426417217267534810317714120637715587447884238722162264175700647268123018833033454700328881216065721525378787614880383841413262040530202264523768288244748401630013064582441506825281343376027562685201588256074212735338587526201851804705483838426483651360202665338765886456254245744670566111870525780254234553032810841267361136718675661103883076155035127073645528165635100567720655217755421301357108034726505744587147310040141010805646522087147007255714057158741217277422625282364731745870783664616160434555775443743502840544863386473378018153247320635606807438754156737641371466713704031817403002217663388070881274501471075834867805472376776326800354057684821603313825840027201144475741126230724105836354806407505613633022136647710632508145086447881758420157178754808160145254472146725788070481561266847405464138405113446032102601304210208730306401431145205104734535487474140772264560342348655301266821517162211403658702262776371234537788132058858823145524452147323040308527184140733703820531813674657553835474053654050304073176263545064447138716350737634B643A171F66CDF58DDC280697C53B4E42A4BEAA9754E6BE2BA3A38995D758B1139FD3553664E16C952BAF99035D4E2D089E48D5AD9CC29E4D2B41B6A413D7807F5321F52B06C51480F368B2EDA86074AEB9E30427BE5CF548FE5042AA154DD0DEE531E37AAF546BDBAED6F7BF1226FD5395449897E9935770991B81D23C884DFB0834B1493781662514C3F1D666185ED811847CF1C0042EAA330F42139C94928BCFD81914E52F29BF32E9EF9276B381D6D17FB6E487CF8CAFC1FA8988394161595DF71D66D504B4AA20B17EC08848D59BC328EDDD2CE0B618790CBC344AE2721DA47092A438AB33B41A490475323593968858B61EF2C0E9FEA7D67243AE69EA6561ED8F586C3EF625B0E560A7F908AC491F6F76D68E73DB4718346F5A3DCE4C3BDEC93C1CE41C1A86DE45AFDF43E73B5A3226367DB267C39D75D80F831033C0932E537A8A8B27B1C82190990B9A949AF6A2B9CF6595D35862BE8BFD084C117494B56CB00C671AA902A6A7179577C0B9C4D615F7E1E2058820A12B131BCB96BE297F14407FCC7F99AEA65F1E4F2557F6B946A55754B594C1DE5758D76B541B568FDAC78F3C6ABC68EDFFF0BE8CCD2DF86E536F1ECFEFF0160459EE05F55BE0BF6CCCEF37DF0AA22A2C01A28A0FBAFC4ABC22A07A2B60907C6523E891F18C264EB0A0589762622F664B7B6B65D9ADA3DE8B1D3A417F88B9A821CE7D5D321FA2A64D4B2017CBA63FD177D5A866D537BA28E1D0A22DA42B471A5D4CA50C9CCF42494FA002A35D4B9B3931DB7B4D30D1C6FAF0FDF7F3980A20D1D5861207FE143222415FDB586A410FED5B40DDD57B5208B804261880E25DE41A4880A19F7F6D49589CE530961FE2E28827621F561515133DC1FB9E2BB61DD7183EF2CBE906E292C0C7D61E04A0D61623C897258F4BBD645B30D2DB836C75481AA3313C12660F8DC1ACC7EE159D6799B587C85992BBBD1A7794068D7980BE486426156A19B9096EA4ABF36E4E8B524D474CA60AE27B9DFF771C64F0AB2844372E6DAA50DF760E5A56F6A0BDFDAF7224B48692CFC811ACE083F19CECFBB9A72C309CAB467DF8B79D2F34860C7C056E8C55514A53975D407B4000119EEF0D0C8EB05524EF006886764580F697C849B8B2D2E4E1DB15992EE072BF4B5252AA1542ED4CC9E714C0EE6A447B838D233355228BF4E427790D8A46132C50D3E340018A9A3999CE187777DB336FAED69D7259AF20E104E9D13F4F89AFE3D60E449C8075001365EA6A5B150706B94828106776831D8335078F1D590F6EABFE3A01C351DA0C8AABF324AEC14BFB0729AF86EEB4C646D293C3F5F3520554540451573A93BB05BB3D70771240652751356A52429A866AEC7396BBA9D71AA078221902DC1ABFF960DA9583C58D4806D65D509BE5743C9D42AC7C8F7611226368A49D60F8E24DE73FC614EEF55D705DBFEC254B6579E207322426687E3B1C5C0A05A869CAFDDE8C4F06E799010DB17FDE4815008E9DDBF7DD9A3C63ED11866DCC739C6C97B2EC58B94900657F3D881BB9761D8F64469C68A5791311ECF13AC0D22877D4D2E6629E5C4D4640DDC30CE904C5FACA5356C72FAC8ABFC421E18642A1A7CEA716D9A4A93E115D749E16C79F29CF637A5A6A17577DA4FA5184FE7AF22A88203B77818B24FB77715DC2B44A59FC2B4EBB58289BC308F8C0B8718C8E40A87A6E6B5133CCFD2D846AC98E02EF3B210FD2E6E1CE8306BCCCB4BD9C345F4BE59E931B8A30E3F9F82549C0084F72CB13D6C645FBE61C81319BF98474B386B7799D561E53771AED22AE04FA425D3F61027FD710D897CC4E6894973146A6FB2E485EA3C127EC6794554B4282F399DE9897E1C70F2886D4A3F487220B00E85572A4E291B99691AEF60E10D4DC1515D3259F8E74144087D4C5EC5B0CCA2812C27E3DF2746C1A015644FC5B21008227B29328109922DC95128E9B646ECB9468374594C748DE019C492BB0B6444743ABD20A08EFAF84892B578FCD389DFE25F0F6BC20AA8993759AC87A0920D7A43B34CC43CD7FCA8A2CE25BC8FA3D246869E3D965D98CEF0F3FC39A5A62239D803B7E311BCFCB9D9C6C484516AC3E65038DAA2806D4D0D4073EA623A60F7F68B66C97511C1E15AD5F72ADBAB64F772C4A3F4E161E0BE0386D7EFC60D497F664400DF69924028764A92A26959F3FCAA30923D3F3D219C91F0831A1F6F02B24931D57D5CA427D8E2C02D4E4E6D4EA3EFEC061CFC72941DEDDCF09FEE339E3A208E286D9E0B8E4F9CB900D9F36C013ADC673DB1F69D6CE170197FBE60EE4E28E9DC66BD1423E80B78A10BD0119BD59C1C2D4EEE1CDBF028BD9D0C459CA885D83ED2BA145CF9CA5917F6F276B4DD4C9DD4E1A0D4545D2C66492B75A42DA066BE5D5B40A28F023F49AC263A45FB430DDE7C55CB78882BD689DE65C36AF223925EB14F26CFFB6CD082CF6AEDA6371DE32C5276D3070F89EC7342E94ADA62DFC11BA4A0B05FB6537F36BBB02630643332F121C93089F26DE6EAA4886E4C1BBE25E2D0660A1DB2582A6F586C1EF875A406143194E2783BA9BCBA4BE28E643887D14A13652CB8ECDBE9E7DA4A73D05C926486AC2518DEC9C82409F20679EF33E48AA0A44BA2FA9FA2B26A8922D5EB846C96B32392C46AB9F7930ED7A0B0D121FF874DDDC303DFC57D278760180B9692579BBE0A079B8AD5A41FAFEF9A8DB95BEC8C5BB0512479D2E810096C729AEE88741F85A308ABA9D5D1AEE42564C1EA76D41BA78AC1B05D5C604D3860EF722D0EBD73FF6DC894F54FDB8E4205BCFD05D199544BFE6AC3136DB83FE2794C5376BDFB6EB1C886A03CB2939F31761B0EF1ED877FF28E5C9F2FBCF7D1DC24079B4790825410F3319C76425CB9E8C385DCC2917AB8A9A743B8BCAED7DCA410563565B553A4D89EC927DCA4A4B8C1085EEEC5C53F5D43F99C1737587276012E5DE24C8C012600907737C487C472117BD48F726CA8D4E876AE35DE494E63D0D844C53CEE75AF13111251E338D057D5A88DC3132126F597DEEC69C149220CACB942B07746200CC72758412FAF7A22C0F73389615BD5FB87590C4F42BB451E48A21BBAAAEB12B427748F4FB02382D105FA962B180D1901307B1F03DB38C8A0AD97A8CF615C0A9C18FA3A6C10E1B7E0A83777A9BA648D25B0051BE791A05BD7CCF713942F17EEE24042B0FF47AAAEC674D0C9876BCD3AC11580DB1245691DBD8DFE791AD40A1860F485933C477ADAFC3EDD030624DB77DA7E01E7F81417E394B3629C687A464DEECB42C1ABE5EF245A717FDA612A85663CD9684A58B3124CEBD1CC5CBA3A2A8A48B168FAC6760375B8A62BA4CD7BB4F177CEC05ADFC9CE35908D78DEBE63E3BAF803F2A0079528BB4B2F782128C0AD576092140C94A980045F998D89350278BB6867806228F8B0A8617A6CAAF54ED3C70337963B986C68EEBDE477790BD316E572D823D2032D065891EF8560BACD14F910D3279501F97342A6120EC2FD8A4F130DF18C0880304697662F66877BD07AD2E79ACB4CFE4F039" + }, + { + "tcId": 47, + "deferred": false, + "seed": "B9446E8F78C8B7B2ACD335B10F0B8FE1B34007A1D827EB5517710569E060AFC7", + "pk": "940F3A043905CD31A66A0B5E776022C026B8CC8C9DF839951EC3038ACEEEF9F203EAEFC937D6D289CDDFBE4D5B104ABAE3BD76989357408C69922BF39217134DF5C806D34574A1AB61ACC99A82F51852F173E0BD61E50552CBF5A8AACF06588470F649ADC715E3C7CBC646E168B4BF0468043679AA7363144CD6F751578BE3EE5F74C96107189ED1759929DC3107C1CA5F14FD14F3CB31503FF08C8E79875FD529AE80A1421C0643DEFAA35D6889FA5B6E018ECAC896447BA6F5095929B4A5CB636B4C9E0875D5B02DE68CE6DD54B24156952E081ADF436F064795C4D099A9C17F5CEFE19B8EE8406F1BF40AEC03A15D243F870E2FA2B0AA54EDFF17D2189D240725354C2A680F3E3F7F937D2190A2076B6437F5DD6983699F2F87CFE04AEEBB22A88132611FE673EAE978F01BBE3959AA3F4E9891EE9CF6D6031436C8CAF9FAAAC52E037BB69BA454C6D1A7F1472D85C66F978A2784C79E792D1B8B0155D85A7FE1F9B049F012690A2362A82F4CD9E913DCB0EBD67D68595B0D17D085AF96BC64F84E069C9CB9572A7864CA1DCAD25AE60F37889D416A8867D4DEBC7D1AF997AD04EEEAB9BEEB027ADED41D0ED3B46FDDA94584C0F787802B7A9192D8AB1547A15BBDA48E7EC65AF00152E4A385F755D6C156B4A5443A145F84268A55437EDE5A732CD7C3B2A6A728EC698E975758A1B65906307991AD8CEDCAF9ECA859DE2A7635EFAE365647B4AED61B28C24BF4662F7FEA3F14B8E373E4F3E4ED51FEDD1D39A2B70460BE3E7D213FC51357C80E292B9649AAF7B464332FAB8595BC1F87BAF2056574AC9C73168E13DB1FBFBF29820EFB08E5CC9465BF31431A96C91364CDEF8A7A53AC440FC40BD990F327DB60E980499B7314CF5A63D95FE20BAF80D001BE16ADE597188CAB8CD217877521E9815F274D8FEDFBF8AE11D36BC42B8F1D2F1C7F4397FF4087B73E00AAF4E9FDA6F9499AA469220B153DAB01512ABCC6F5DAC0C54356ED2ED0A1A260F3F8BA1F67D047CCD333A26C5137BA76DF6A45BDD731366A04BCA2F80F7B011BAEF941E91835EE218AF34357F47A48C6D5B47DCC282BC53B1465D5775FAF773807634A647701BDAF3455E1536FE96CEC471A090D5FA7B737AFB670CB0E2CDB5EFDF5757CB52669AE1907D991A187E87F19DD5F2751CAE3205FDF832B312FB44225B7D9285328011B5E081CD0261E255B4C74A1AA551305CEC1703CFC5CA1E55A3D1E4002410A5935DEA3B3F33EA0B9E17793CE6D171E70D954634DDC50D6B06A499F25AC5959F282E12D8B9C28A00C58371A56A4500B2C507F57BFE85FDE137F82929FB9B813B205F72FEAF23B9457B746E8C70EBA61C80772FA8DCC94AFC0AEB59426043CBFDD6CF69F97DA634D884BEEEAD96F24963E9DCCC71FEAD90938956140AE0C486AD185FED8266C515037A1FDCFA2E211FE52E0E45436215F123D8137DE4A679B19922C9A6C1860BB7430D0950BEEB635C0937EDFC5966D1AEB418C2E52AC41D134B43CB9A4A3305C4C669892F65978006FB56EE2F8A7566F2841BA1FECCBABDC49BB92BA7E06842F6C7B24427923802EABDF84CAF5B3E77DA7F1207F8B0497D17EC1B5E3527AF0539C64277918EAF8FBA7457833CA80AE2A8E001CA9BF08DBDBDC19CDF82F4230B494B07594B8AB32710E794605F93ADB877FCBA8B4BD3A89D907A92F1FA309727754A42EE1DA7EBACFCE46D07181D4B7F7D20028646AB680CF108BFC3A43834BF955483866759C7A34105B4A34F92DF2190BE8E5272D0DAF80E8C5DFE361B66D75A7D8783DB9BDB92DEAB2BC703D13950EC2ACFA686F97AC0E04B1E69E5DF49E54AAFE615A493E96BFBCB008385116FEED54A2B984930886A514521EFECE22F449EBD0F18BFED1970A86E7F4D96EAFD11F135A9BD8320A12AEF389BBA46B0DEFC101C3A90A99F00E6D5CB28298BC35DDB62A1629374353EAA79830BA5B051DBA82FEB251444B3044B432E675792DCC8E464BC40958C2BAB862208486647AA879B8AD7A71F48D63C3BD0B38BAD9EDFFFD1A28FC3221F67B26A2A36A40BDEB3D01E0F4AD90B26C5CC9AD0D80E24D5D354D5AACAFAE1000AD21E4F60D994891621B19214F92657006E01EB4B28B94F804A7BAD9A120226CC03CD634731CCD5D7610218FF40735F7964C6E2E4C119A590786E693820DD75F6BDD58CD6A1B8857645C3C23B52C96694462832ECBFD27FFEEEC6284C4C27B1FD95B7252857BFAAF2E5C34F51A4055DA5C9A2C8E941FDEAFABF87074713DDFD9443AAB31270CEE2801588E7B89F3329F3B9E9F398738FB0EB0F50E337BE42000B5876E84F623C258C4BAD7D1E536528E8BEF4AC6F6869AE9738AD76BCF8FDDDBEE023A5A836020DE542CD56877DC97CD33586A637FC6C1406ED18333A32995E14D79DEFF1E258B7FBE76461680C9F5D7CD79165944EA50C29087F46AC6392C1CB8C3FF9DA336D4787E81C3662C384A603EC6BDE0089A5D48136D08DFAC460ACAA0BFB0770D85ED2F859CF3D2F1E4C82D5C5E8D6F9BD5F1538E21FA15ED28407AECD7E78633734118CC4C5EEEC2E2D01FE75E1B7D9BD0D149B13B57FF5246655ED2259544BEC5D06639BF6180BB8DAADCB49ECF1C0732D530D0817337C4FDEEC4DBB99F0DF41ACCFA48ECA5C5B8E48CEC321C8A1187B3E2018211CAFA625209296D77F6EF6F14DA8388FEB69C11A912619F514DD8BCD5CF0AC64E7FF3C97FDF06B6620D18A0F95FFFF5DA533BFB61DED91BE2DF2B", + "sk": "940F3A043905CD31A66A0B5E776022C026B8CC8C9DF839951EC3038ACEEEF9F24A60ECA34FC68FC31F37093DD96AA4B9F3D5830C6F16E5218B03461992816F1E6C46ED2183EC938F9BACE6D938995AB55B79D7718E0A65ED1CE086775CC7EC0B9D8ED16CA18D454DFD93287074F1753CF1A106D43832069924E934B69A056D6D176426004013076575326430863137681154388472321482327058660264144318587126616777245665846085207077377620134715340864342265500652186150467601565650873175644064416834227733720173774587668873453654245237887584735816803431317252007518455862453438544280565558788488641766433715102273116838853016286781356764553350815576130623142120288320447330858634146116010314662770062074375774867186530144058337264066324211032656066333521814241564325222500443323140011323440703778825861335111403817102184704327185386633608142215442067221665320752283741503126550045540138523388552553756710758782221066048054785368634370510608715285855830261461583231884206487168348502251624181358250452363431358088283280220684850274887682136732878487628835676427436605335002250861670280661746364663333746081501851137351028871688754020075563164387882072231828620163852404354634175131783368268806428070410450722647813676878073455762434565702154475408122163541077486410856021580604143745384424577785383320062585216722084220844048307024134432474888345716725321201005120225816884018256740445853733442120313688418144003171551700522688612013631552624366072347843226703122460417203012430812021833811420720661868774436374256462732481621436813002757624755522350808162680011825038722214273025248005052317717234810061288158327831563165021287226153061841412807135642600053623232871172234266585054154037728672161210616458710643372418828532614851034330455673523587742236477452251870078026584337870552270745526756623860278447626062284834315340427146171232766872568061730756050724247027148476041120506552842756071205358731326167423273744026237525138835086634357501537604145556133481414804060470432652463216123837200443812665470481367442016456162841127017802443686606775850025538847122687372785518286573566563606242666874533554403325385363656115174748320261462840552772623674410481265030724763256241631486648346756261368748180167401048541280737780881841151540185080052416176233736633170701131856087368601514425225057047273141367358256783768616620301431740016335013544305727222457250283187257250743134642552508353067725664027065305156731547334833675272822335860257083672157731427677103643242465216121111244014577786563871520155270585467046042052457113044834347701052060663740758787647888206363867766446811488063441365214110100556377588423480631304107844013871142521788152386654530207028734623080264311677371668465072078164640706288825415386285222822305247408773601071322560410302142821481811133677651772473201332288815205035613301832085104746827523346476715450002575314316042733172642714440446820038280042757635636678707806871714311068015364432431546245667366443671858840683530203154356038363103684425222575835848370481228786854711047404557132636566284507601070068815183715138065502835833765443038333301854266005471082640210720634670243202468375243858240881712734844607240223EE143A505C81AE49370E4B4215ECC3A31B3D08AB2504AAAD76952654536312F6B2298A20A48791A9236B32BB68004CE49F169A4A91C189FA677AD10A25604A4BCAA38BAA0E572421A79CB1F82E3543A285C5BC6BF25EAB82287027C386D543242119C74576C1126E284DCF1E25717306223CD0AA9F6AD025842709572D1A1A2D656AE4388B6F3F491A0EA231798A70A3A0FE3A7F0C97E74251068D009CD0088B8B9026EC8FB19F181F0838BC4FB5C7196127D97D91108D5C7AE2893C85C32023175DC204D0C000261B382FA078DBB3F0745902A445FD5A32A7CD12AD7AB014F5DF7B9D504FDA8EB8A00DFE5DD832348FDF7A6298AF21A8D9730DDE60964EC8FA10B3140D409278C238A78DEBEAC947E740547530AF8A98C24E6A2474F1BEE79E762D710CE68ADF282FC8110FC099041B5A0CFC307176FB9FA214C3D42A7F2BBBBB27FEDE0EB37C71D84811DC34C83ACE1A41D078B936205CF5B726230109A099B75ABF9152824E04C352A9085BED558C7C894D886DAFB46C3BBCFC2A74AB8B4407E514767D90692F94862B2F7100FE76CB36F52C3BB2C7920A76F642799C213B80A6561A6980D611D2887A0531CBB412DEA4BE23D41F515BB8AE38C77D93BD603F9AE2E55B5F0DC6F4B2E217C98F6F2F03F9952F43BE49E6A7EF8129A265EB342AF271D2B3CEABC86729E962200FAAE9EAA62D04C64ED91E0B3D8F8300A7C24719A9F64AA35804D2B5FAF7F3F617963BB8199B2B842FF5317D43F32B04052CE5F3B7DF5DE8E2FCCD0B183FA767A3779307D8DC95ACD2E36F4A99945E12C0098B2FFBAAB97B08AAAF9B30D2531906506EB5194564C74468385A83D0D4291EFBDBCEE7A3E781DBB81C3F876957DC169C19E376D76F7E4AA0663FB3E332410ACECCB0457E076F25CBB2436A89D5BF25C376392E719B2B49AD2EF20FE5F51595217239E0E3C7D40BA0EA3F3BDAAFE29E283B9A2B93BBEF4977E2574082E8BEA041DE33244DC52D71376FD051BB790DD94899C80466C2216879166FA46766B7D23899916FB8100ABF1A1ADEF0FDBE68DE44774E13E1104432503C0CCF39BE4444E3564A4740A101DD654F76DDEB32C510077186709684EF6EA61B325B8FAB6E039C95D6C19BF09CBCF7F6014E1FE85920AAF974C164D8079E3CA16707BCD5DA704F0A66A48EAB2853225A795DEB51D45632AB38A07F093308545A7EE29FC0309B48A177DCADE869484814652B70073AD0CBDA32D2965E26E2BD2AE66FBD91FC11E9B5D71969953981D020AB89EF3CFC3D902CE078ABF948260035F9583C34F1650E647992A7FC4B3814EBC58723349901171EFC1629C0C2DDD338891C48A19810779C2941ACBEF58361B3A84DFA71D80373DA5358990B65922E17ED7066E4153CB637FB56605684A94284A907C92A2D717243B731FA6F3895E8BE09B7EA23A023C6692E8F2DB4872213EBA4B402D764D2DCA50A3F2AD278F33493E9AB83777F971476A1CBE9F7A448E3E9D9E47D55D8A7F04B1A380ACE616DDEF3625EFDBA9A625B19715D38EAA295185B7199D81700A9BA454A07C912187BC269C7BD8D499E14557BF206A33381996038E27A28D19EA9672574B017799A27582421CAB69B6F187CDE5AF2526266EC10EBAC90E4554143ABA9FA448ABB8CBD380903EB2249E124F2FBD230E6A91342972B3C01F81D7993A5A1BD25C4E0F564CD4597A18E828F536CCEDBF66DC85F343949B1DC2A50D58FFEB67949E596AF43E1E00E13C3BFA84FEC72E364E88509B8F95E0E9C0341F3A3DA99C947BE21DA56DE9ACF630DDBB190CCA9312142640556962599A52FFAE981E3FB372C0A2B99EF2CB3B86CA9AF186939CF277F32D503A5E6554ECD0259C52B348A7E107DE4ECFAA35D86A62F98AA403F911491C1B393F4CE1333D517A731E106E191C66C7ACFC13EDAC66E9E2C5C3AA261FFFC6CE688BD711BC748376E25286923E55322E6483D96DAB4765AE5D91DFB477EF5A5B61FBF78F248A92D03B18A7FC247615405701C08E5147700F41A35CABE1D1A592582A2BF2067653D7C925146776C0BFC84A4EAD67619C0196A0293B94AB5FC30900C25D341E819F443C2BFC9CF7D4C3960C6C7E6C33F656B3B512752A55FEE1DB2B4FD799DF192FEB8B775E141A0B263A24710AA98FD860C18D490C55D9A44A92E1ED5FB9BCA06562F2D1611E35559C2DFEE0AE1DDB8D724A36CD16CF728B2652C92CD8619B96AE1EF21B2D2C692CF02F9BB43FA0E4C87E001A3D6F1B7177EB43028F88FC024005FB095958BB35DBA11E72D800A971B1FEC05548BDEEFA046947449209964328C1B95607AABA6DCCEBAA3B9A4A175760F65990E36F0299604545311179B3A0FA7A3695053EA99B5164A22E1DA59DA3964D76DBF5D46193055CFE1408BA943B86C0B7CDD2CE95EEFFA95EED74EA018D42D891D7ECBE5C8DAA52C04510253F8CCBEFF351274CDA464F51D4762B68E36C783041063128878D9820AADABB2BEC4FFDEAF61685D9C0FD2CA6626F8E3BA66678BBB3B46ED7FD3A9B4EBF623E37D90BB6FBBA31C9823E8D7379EE6A42C4AF6C15D183666195F509F3A23D14ECC4FAA4A35B55D122D4F0BAD9E0DB8DCA918CB2D13E96B5E2EB2AAEEA1788614BEDEB39691B072A094EE22A6DFEE43BA77A46A9F341C9A95640C26E7596CB6F0D0889F75789FC54E31FEDE42BE11D09F6EC514BB5570568D395751CE5D4764AC64F4709C919967AA7E04FEB19CABF739E1B240CFCB302321E3D012A2231D0DC0D1038F84BED48ED94BC06F65A3F437C9D8FB2961E49B292698618F55D06360C8661DDCB990C68D1F47BE15640BF059B7D7EC8317548E20C83961418C38B4EB278C9D86671AF17D2A2E22A2BE605FCE1E496B5B1DC08A0D4E7B956CA5A28116CF83FCE69190B1559DA0C19A40ABF85D5030E0E979C3B8E174B42D0F2709E28EA9579332E47045733C15A63DD2026C6540654C5B481DF921B2C4FA9729B817A3282AEB9568A6AF7DE57D73ABF0A04347A96263C97B575EDA6E1E17B2CAF8B1374FEF9BE11042813B4D64DBED1DCE9D452CC0E17F67D51022B8AF47D32494188868933BF44B956B9660A9103E2AC233F907CDF2ADCA9CA51318148B325BD29AA508D9A6F121CFD6BF37835F9EF9E3D9523F53BE11687A2F19DA1580BB868038A1CB0119585AD8A2AEDF39C8B3B7130FC5FB02EEE22279EC7ED7192B4FB87FE60CD64700CD4CFFDC4ADC518C216DB78C77D8E78E2A8509636B9790AF99616BFC5CF3394EE1E044F4DA0E22D50495B887C6B2A07102828E8CA08323B3071972286022AB78A794E3CE3A31897A2DD60D26C952F51AF92DFED277FB671CDEDA5667887CDCFCE78103037742274A82DC620B37DF769EB2332D95E3AD6E2B38EDA6E9530FA7803BF52A32A1907A880E18E7B5CF7FA751751D24A59CED3C08CF90305FD55F19C6C902BA7AF6F02464C1F84A67FD85F81183866C544F080425FEC22CB6304296E00F41B69F2ADDB5AE7F286D39EDF19DFB02161BD6D5AF66D2D" + }, + { + "tcId": 48, + "deferred": false, + "seed": "910E96CAE3F7DF10E0686DCAD2D6CF8E0DD9ED69F3661F0799DF91CD6C494986", + "pk": "EA95D53403E54CAC9521C5635E9F335F75DA4CA76005562E75F666BA598DF28DB7EFFE2546EAB9785D75DA10F4FABF8BC5A3BA57B8510AD8825E296F6D1ACBD0350B05DFB4E58A120B6D001DD51732740BFFE855ADF7B48AE537BB790DEE364A702310323EBE2883609D8219E85AC252EE56FF58C5D6579323EBEF4D3EA265D1E65B446AF2436C3164B0B984DF75B63DAD2D3CECC1F41BB23560ED67842CB76723DFF07717DD3D9516580F94514B1FB3450D88F507F1BF07A3766A6E52C93F972F052BA165BC8D7A06A7C96A0FEF43EBCA6FE4BBB0D236832B70DD54F4BCFD007A09D4E1024817EC0AA397E9A88E4BD740D6588B30B6A994701DD970AAC571E66CD86B3C9B9A524F144D80A96565EA9BF9096721787D5E484A7CFC24FD04D7384455905DF6BC6E3F526481A38648F0EE49335EC0B9C067AA8071E0BD4DF9F23960754CA894342673CEE8A3F5A6C26DBC476C42715E23D222F3F8365F69F2571E777B4AA51126303A1E90AB3F9A445DF08FD853F64ED4A737BDEF71AEE8E54454F8AF5680C0B996F7EB4E3D3F01B95CF449E1301FDD80B4D3D238E7DA61F7BE64E26623EDAFED874581CE54C35C4FC6B302B565A8A1EAB844D086001B74DBCDD14424721BC36828EBF3C3B70A8FA289C11F0B1559988D4993B696E1C6FE6E62C97F4239E305524157540E9F472E979F9640B26FC6F79E69DB22928E76813E46A1B056A938730C1F4C0D5D5C763ED3B78FA56073D2A41C639F4AEEC923FD761844882615AC1EBF3DEC850E33B7D00EBDC62E2BBB0729CC465ACE1C8A50B4B35B4CB6C51CA9016EA38A79B65EBA47A955D41DA2F23460D822BAF79E08658253C019F1E393C0392389E527FA0C446CAA5B93EAF129C5EE2E0FA36D08D763042AF0A9CFB0FCFE6A36DAB0A78EEEE90AD2D5F63F3EEA6357EB073F9F912AF9BE8E04D86F4A34B9D7A351FBDA890AA01EB34DFE519195043B116AF01D47A45E5FFDD73D799CE1B9A5E584DF247B5B4F1128861F43A322AD193D94EE12741817A6324E0E8F747D20B20BD5922B1A1B3BCA25C7F910275DC3A93932CA5B6257E7476EB35DF4DA8B5545A6073D308CA77822A72CD72E2C3E82CF108DCB05F50AB61DFB879BF731AA258877628DF11ECE67758390946519D566AF6BBD45D621E53BFED5D874CF1D22AB489AC8DEB3F8943F9927AEAA68CC4381CC919D25CC10C2F4938496D9C787FE032F956419D8463ED1385A0D1C96D3510CED99AB14E14CA9AAE0FFB645AA8AA0D09C19A4CC4A6F83468148403AA88C2655ACC1C95F93FBC192DEEDD77A7046F97824B1E412FD8E70A71514892FE27B53118E4D3362878DC31EC6343D3595CD0BEE06D9BCCB6E96E8F5DB7CE8A8F31B24F989C4CEA43E55B3D2AB85ADD1907C5543551FDA44AAB69DA22483C2BE0000D3C49D00AB453F30F5E2453F8C02B20A398BCD082B6254FD6B923F1EBE56AF4195A336246EEAE1E92B8AA72FC6E355A0A1FA1A982363BB4C73C6102CA1393267A0A9DDC14CF5AA12F3A070FAA3C1865ADD1080836C2BAEAA598FA3F522133E7213B9BD4CDA65F0B98C377432A28F6FF093B6FB769B4E9777ECCB333A9977BC3C1C2B8D95D2A44CBECD962981948F1667EE8D64DA1989A8266056B632F5F7DA9018F290C98D6B546F98DD220DF299901AF1C0C8A2155230D7D46061BE46795A5982963FF1A6D507E256EDB08DF304E8F9358A32ED22B8BAE3B06154FB5DA7C4C0E448509A0B61CBD6E4E585823890BB1E2B44DDA6A8822C762F6E8BF07529C4F5A7690C24DF96C5586FE5131CE825937A5E5C8D90AD3848919D937EAC19FF862E5E4ED51C7EEEEE626D601CCBBD055F68C03BED53D67EB8B1668E06CF7ACBBBAAFB7855964B6C7BE342E63C9DF5B935338BA29FC651F8E029499B6F8E12971326AB7A0B836ACB9B0C67EC72900AF728C55755596894C8C9E0923799A5B7D0F37372CA168044292A1263CAB005323DB3747CBB1F6C08341320DE056418B32C9BBDD9DCDA8842251ABA76DA423D40DBB390A62F696FD3F1E063BB0ADC562326F2884C0CE745740C1CA4C3824349C175F75BE9C3DDF418894FCA12C0121D428DC9DF635A7DE5D6C1DB6D359A07F02456B01DABCBF49B505243A0E295F3BD03CD70209C2323131D9A300E7C626E8A30013716EE6564E11E349D53404C2001F1B77744839154D52CBF3D1045D71446B4B0E7C4E3ECFF88385C35A0764AAE46296B9EA80197D74DA2BBEB8A430E90AE1C341059663F51B58D756290858B054AD60D0CAD93AEF729824F81B9809D6C0F3E8C15CDB5C79F5361C33CEC09FF86195888F214B7CF69A19E9B3D3A91C09FE6EB43C970A1C6262180B9A0D599629F12A61702F03C0CA5A45F8518DB4481C721155791368CDBF786D1A7CCA77BEFD436F836B5BBD548F079FC87A3509D12179EB3DFF109EB6EEF56D21F70A3982B24C3661DB64310412DEDD44F6AAFC252A2CD4F8DB9BBEF12E0FABA2381C18B5A43C9A16EBDFA9F9C2A4FF5912E46FA2599FD16A318EB62A971A03890C8DA8B9360065D11FD848857568D08E8E5813B159CE3FF0FEA253593625F82B5BA5794C015BE84AABB34409E937C51DD3F6565932561571AECFAE711B61A9AE5CC1D12AEDA3659669A481A433137BD5EC3DB59AAC18004DB0F96E708E06990C35856DC612B24BA27D4D837B3E8196A2536D5E388D8E51C6FB25D54043D0D2DD5FB1F827B451B7846511E5F51B6F48C3EC08FE39A677E2C8E", + "sk": "EA95D53403E54CAC9521C5635E9F335F75DA4CA76005562E75F666BA598DF28D24492CAB5EE1A838CCB870B738CD2BF15845081EC92FE655EDDC3DAABBD70463345E717BF4E9B77E4E42C41EE081FB7609E529306FAD0D010253818BED6F5C36E80F0CF2E1CDFC3644B0FBAAA332C91B8E9BAC48542587DDCE3B89B85AC95B67205358448251106374330761616370840427403060131555776484032685263315404265627140818478237330461730266886678220206757852370307812313186670777525377243410283855032620382282420030862325482173385126618006425080660754150507021155510527010400031730580268480057432412702246646585006018341365521716483413675564656536487671660142316774020375316380713786272377283742823337111220565020523286660270378010320780454435727328225012270684854752384080330327232568564232334624785300247078327824557671535222210477505366750273350760622046230230260051216004274018134720587804852011513328437632380487348538761062461618530322680868132352785267226346453636340478012526081750131434530007670441442545000101046220634032432113214835787158680732862056026304846838602761436702478386234638586703304407840415284465247473208178635703585423748148856167002814048306441188623612783876688861220036258078151885032812826481381533241417755607323112011074124487501132778203584733520654651330088421647830628846050045765114501255050401362864274111122784215666102828748217571715050331524203557710257341457213042182483316853151265470516218556873288758186361667570271538733143722872641133534773365442068318176733601261602087128454576104402730785325228074080124728136803212012176421321531125876743834555426446750774328825708846140833734063225565260787734461625334052344861774220588771408021810607471156332580632280701173562858681586364176474502351131460358610510860814212667307781071767853607451544703521337335512585050362481526644627232206577243115336803784153432761563147764470542241266534771730877768307535531184023433563146435118336554118553322683875347873514134711335415277733516356657622323524047003022507454625047621173572485725784623060878303721555357201478557707263311371545530238434748271222817073038030533437284816784301801712411264351214303745068324677180701387874004318531672172357360350653266358643677401786781602256310774310423523102138875113656455771583275031265507486382852658323110101755161235083527248117325406547684577540263666157667871418616544150267046727347840767160533104681104207400671472835332830774825088686527066365754634711824660710703543823161528234747317210601368642418361673115730670838723373875628051373556788162537260577837888028732672353482401052021665413247585302187633005427258870173180733401656355241728775560065687277881464582763237044678011865760682717142166374624528785211470160157277740506621763080770285055044428134504455441747414021514780758088166611667254100231637072441607706077511335806828544374880608121171511770560080601164106110827266126106183135415882627445120836107122852801612426738230306530455072677400205525856874676132831248508378511646237882435637476882748587424351284047403241180001573406464365334575336777303464222072838174364367877848211517701774258316522054107175211473552828834313110583621807140335000560AA86F8697754821BB4793B67A97B27699FC1124FD3CC779CCE56FD068D0A004D91A5A8BBC7C8517437AD5FA4114658257B24FD6CF7D1E7D4D0394DBCE171425087C232DEC09410FFE82C67427A4D97845CF0922C29BF38D3E6E31E8758A43839569925EB3D9834C352C2D2124EE24F5CF61207FD6BEDCC70E1D665D12BEBC188F3A1E6AE462464BCBF05587BD0B5E960A9D20DB52C7326DD7BEEC6D2B20BF82B9D551475B32A77AA5540D2C15D44C948A2F0EA266F6EF1F619659B0C4ECFE94D45045941FB3E3D4940A0B7412B2152AFD4796104D0CEFE9B5EEDB94ECF11B0F31956E2EC3AA935BEDBBA75AE3878667DF71006587AE20D9310A2E4D32A9ADF94C7995EBB2D72E1EAA238EEF912458918099AC43D157EF4B4480F8C87EF8F8A14B083F85CF46F795EB40EDF4CEF2661566D605CC62AB1BD197CF13596777429D7E7AB5835D736AB302CCFD90E5A0A56342F27496F7FD30064B1CCFAB8C3A052353339DF7D25C05601B8B7BB86D0B43BB4E1851636FF4471C26478460FD4F90230F3882AD8D5770B366B8A2055ABA7045DF54915850B48C4C191DDEBB20F0178B950F711757599C73B31024344EE04EC84E57B818F3C77C939698E895FE92BCFA7B2A8E6F271C39718C9CD91A278EC554A3746ED04063964FF384DE5D9E53D8D018D99F974F022A8820B1AB4F2155FA7CA8D8D454058AA179FE01CF8808B33EA1CE9FA5F57F59EAD79E60F374A5AC959F35A22A336F505061D75497E374DDF66889B6D72D5AD04E73A7BE7DC43EFCEBD248140B0A57E31152EF1AF3E6EB4A203B6292A867ECCDC211DC0D42B67D7FACC9156D159CDDD0CA254D338AD67093232D10E94B5D6DA4492704D9A35501FE279B2B6836978C0520B643323D9E0FE1830B2EEAD1BA1ACBD76DE53C8F4539EA793415E2059582406601BA40A2981EC3B5CC4EC5328F6F636FEC2751870923788D0F8331313B0566C859E01FFE88335DBD0BA67F5A6F73B41BC9E501272C7D2B6DC0047E3C7796B0E716C1D5E2D9601E84876B9A94E91FA7A48883FD3829786162BBAE86B4F6E0B97EC079BEF8C57FD43444D2602D3A9C5DF317C870C34D8B530C92B905A8B192F0CF1CB31F67CFE717775652D3EB6BFD7F3736CC3B956BAC5EEB82B73A29D6BC8FC64375F4CE18A066DD7E8AD4DE9B051DFCD749232AF775A24597BAFB20CF25BD08EDC60D9A5030BDC28E600EFA01701C9F19EB20755F17FF66A3BBCE48CC727F7D0B51FA1652EE2A9B8CCFCBBCFFF80EA6F6CF977A757A1F079CDD91094E4BDE475DF195DDFAC60D47101E459EA750A9B6668F66B7832B1F96EDA29FFEEFBB4F4B988CAB6E0000377B19820B0A12D0650A60DF4606D92372376134D184E5E7F94688AE41C3E7067F191BA295C1CB0F283BDC5BB02D6B77DBDD22B36D7028AB787EC423F026C5615F4BDF04859EB68BB550797756F148ABB10AABFA479271B202AB399A3D5B6B269C3B04B6E6B8282F38155AABF1B5DB61513DE96993C82F7F4528894EFBD76F99ADDCE4CF7C6BE8F73C341EE5BE2E9F6298BE4E1A00D9751D65A5414B760CA2BA96D26A7B2E77884280647BDD9E6ABA0DDDF1E84AB104C34D0FC10DE4D634C18BA991932DD0BAF307BAD274EAE729CE4E642A070A9C0F5B5343816D3DFD78EAC59A8A36CFD5CCFBE250F5F6294FD58587BECE6C9255C2A419B7614A08097AEA3851324C533003874849CAE7606F190090299C473D3C367E2A11D61363C7BE70A0A9E8553E572B926BA73ABA9E149890E61A07088406EFF8A352189F6D68FABDE060E3F3592B9F729D83272D62A02C933A2D425B71D9EC5839E53AEA96CC7761064DC37DD434B6AA283FACF03A5230F54AB0A6FBF7858E1434EB58D989318FC7270E0C76ACF28EA8B6697408668B1F556DE9A53ABDB587E7F8D7816418EFB92AF93E8EFDE2F0843208B604E483E7BA28565E4ECE92A54501639CC754F0D5BF5BCEA727AD2AD5030FCCBADC4BF27A16057B3F948C45924968D9F69F0FC150944E4D541416CC46AAC433325AD2788A944A607E001CCD824C3A1BDB3F5E0F5FA93A864A7C7B0C2F95B99A5E64944F07C4AE95F9EAB462E90487EA2FD02218BED373536E1E92EB7B9F48F6027941A289E2A63CC9CE55083D93514D5EB734F9CDD5045E4A910B824BC105858E6B4B2A964A5303A9593E26824D5956C18B5E7CD5E926DF580043C54B3862DA98CB9D84A68954E96026EB0B9C9CB21C6F04E783E759E49B7FF5E33CBA7B10DBDB4DBD84ADB01D725625B86B60B8819B23ABFB84F8540A953A53E9002896F00636D96928F5D6462DF2F1E5E3BADDD3E7EE5F9BED9ED8E29499AA327083CF6E3C6759F34F61B3BE3EBF6629646B6D7370667A36BC53056B1C045A5D460AA6603DDE5C0E80B864EA6550D2529F9DE9202A8731D21518E489D90B16F89D1C31734CBD18DE5F1F31872593AB9037F3DD87EF3E91877961D075532305BAB20FF22ECFF44DE46CD7E4CC5E19DD5C101AB28487DDC6EC920DB72A30EF983E8F4D009569F2864B35B113D050032CDFBAB343086BA92D2BF00D7CAC698BB5D436070566604D793E945C98420354077FFF14D5D4B7366AE9FFB7B3F6E8B240A82E85853C73FA6165975A4C11108678E1E30B82B5F6346B283C41964FEA6D525D66B46C2BD259137CC02B4EE78532A1B76409F95498655F6A28C4EB4CB280E6F78019D2D5C70BEBF9BE1943FDA6897EC6B56ECF64622B520AC230BF261F60C2E66CCB7BE18A0B16BA0A08B6F8468F2A0797AFC66BE782A6F6684760CB189A287F74996DC6A2EBB0B17FED11641D89819761D3C0E4E13F165BB6AFC6706FB4C9D27AD6ECA1F8F8FB4C919D88ACED483DFF586203904EFC7741ED28771317645FA2FB2507391A663F6E58ADA8E219C9B379F4DF03DC578CD0AFBE62B65BD18943C81B9B7276F47E81351BCA38770A57894B2F54AFC746155111E928A7A65E7B4620C976BAB3BD48401327300680153C2664D303B5365C0F967D39BD92DFB53583ABD16838110DCCA3FA0BAD45F485F686D1003D62C3F7E86D87E908F3CFD77223AF4D4F6EFC817F14EE85617ADD35C630879FD6EA0E20645316C26FB4B9E66AB6FCAF5CEAA95302E3258EEBA216082A033843D592F9D9B655A5509390C63B02E904DC2EFD9C1A4F9B782BC6AF1F7AE315C0E7E25A5A8DFE3FF2745504BEAE8D41EF908C45F3FA6F2E40262C88278E89B02B3C8415C2C8CAA76F687EF30014C2C9ADEE89E46B06383F4FA33E66FC80B7C505972D8164F6B651A4D037A5FB2ADAE708F4FDCEDD202F9D114F4F78BD2507274E87FA4701BAB73390650D02E254729C33DC1378E9C97BFCDB32D2755046E1FD63CC0504B8117F82E7C1CC796DE16126AA3F50A9AF0373A819B01EB63FF834EDB711DE4E877EF2F1D46AA1B7E0EB0DF171AD0FC1F2CD0B6B029CA782FB259C5F860428478DD9E2270A0B9A05260DB661CFBD0E80E75F06020221115BA18B0D6B455040050B23BB87D9DB5F87877E7ED688" + }, + { + "tcId": 49, + "deferred": false, + "seed": "D0632A6EDAFFE0A71E94E62A5135066E6F7ABF8065774A2596B6BA2F7F138BB8", + "pk": "CA806CF2D4690C7BB3AC7CC12320888B62C8202262BC7F8766EB6D7A3A067A74348698A5CDE30D2256E33639E45307470DFB674E427A6A441012D80ADE3CF8133B307E29842FFBA09E7D04C123ABDB4CD41F27291E5A6ED55827769503EE1112AC884873EA789644C70B424A6056038E2A0D785EE036DA2DA53B724CC1FEF74831897636ACC26947129B21ABDADAE0D105B07FA4C1CA63651D23355419307E8C44EE19373AFD8CB061F1B1E8406627482A1BA2E2DABE2E5A0CABDAC7D2A7025A8BFDDA46D9ACB02AD4C9466FA203059CD5673C2018923A9304890E3A92DFFE7ED3592CB07E0B23181B20927F96F0E85E4FD59EFFBD51FEF48909E36F153DD128C001B59F164EC759C9D8D07B1DF6252F1B8DA19B9E9019FC5B2164A88A4B4C34DA7A8DB6B96E653750BA8039A34D5699ADD2B5DCF3C191F4C10F4F3F772074B4B726E65E783AA34E3B09079CBE2E68F0F52C647EAC333FDEEC274DC4E123E078D47FD52D01961E2BBBE62A1472311BA4AF5481D92659594812A4A1D841CC35A3CEED21F5D69C7F1C4603CD4E1E94B9FDB5FBE2EBF720D5481FC0A095FB987D2F2B0C5E54E9509B87EFE228A21E547A28AD9784477D275A8959AB2013BD8C8702153FD2B1870F02BEB1D1B25B2CA038AEE8E93A6BC6E5154624C6A734736124C3DF027D3259F5F89C51B18F4C3772795B1E31C7C566FF6F2D8BE4BDBF75F6FA4FB5EE4D9243A73F6D7C6DEC8D4E0E5189D50D0E419FDCFA07F03246B00C9D866E87DDFF61BA2B7FF863B7B120520C67BC5EB4690249EF688065D94AEA220EB3E3A11AD5BA7A29D9F262CC28A2E24668834DD679A87C1A0A3F36F905DCD7829A772B1308FFD56D021E58A81B60BF95276EBF04B1C1D6308559FAD1E80F39627D82DA5B0D23CA64BAEDEE87EFDD8C34BBA8CCEC047843C84AF46C435AEC0B23F9471C73A78456734A715ACE1AF64BD69FF7ACB6129B1C78608D5C64BF7CCCA2F9696ED1C64369007541D7D76DCFFCEB8D2E4F911DEFADBDF740A4048B0006EFDE5A73B73D553505B7286211B85F64C7B9CBBA721652B8473B4086C95FA7D0743EC2F9CC5C887A727DC2C7321BDCCDB028644ED73EAB821BE8F951A26A516779FCD5F68EC495C9EF78660683F08A85A610CFDECFC58CF49A79A3B9E3B5FF9E403BE51C274DAFCDD07E2051B44849C2ACEB79CCBF64BD6741B58FC4B6BCFD23B4496918E9BAC4FD4FEA6EEC1ABAC8757C6A972D3909BD94169DB5EDB540225550B600BD347EB3EFA51A5F6171321A6F1AFD6FA0A7AAEC65A612DBFC300AA4A1921CAC1D77EEAC226CA0F8993D1929F4E0F0E85FA38D436C035F49D85D1A802F4DDA9E4DA98BAC92A0FA7D5C2BCB1EB89F3394226766E4AA513928DC910311B086B19611A58F6A9A2B494E67E22BD10DDB62E6DBD775E7269270E2A0270D60191C8B2C8FC511D6CEEEBEC5ABA95375412E14BDE0906F2007EE4A61EF0E535FB22E6DA4FEB9BABDDF775E0394997574AF4750ACC98DB4C7979B90D9DAA0F35EA877D4D868F828340D1E38C767F413E89DE0645E1E2241A79FAB882DBDF87A04B279703435E3528CED89479D163917C1F990DDBA9B625509EE7B8AC53C38060BDA1EE697A6F237C5AD3E3347A7C6F4450A363F171901165C2DA96393FA31A057B1C1964607D923E5E4C658177D5BC0B05A6CC0DE1BDFFF0F1D0DA1F1C8752D3AFEDA44129507ECB0A8FB52114F5ED6F0CD1BB486AF44A3D74C8F88A2AD42A1B72FDBA3D6BBD2943153B55A9C8A4DFFFBE8E0B0794E60C9B64D7D716C58634F7AEC6D33CF50E604048A2FC28E9C03C7A77511D7EF20482FD11F815852906B0B9F4A40D45FBB972CA67149CADB90F9BD3EA69E42291BB1562464BFE78AA39240CB24B0BBB8D76BCC8057A3697A2B5DC71C8E9AAFCE7EA04A0498B365520621B1CD4B38C5BC3B2CEE7FD7599FB79D67269BDC4E5E2ED33F9C90D6EE42C9829845D7E6D6E861EE870119E99095777327297927A552D2D3D8D850D3E4B63C8934FF69ABAF1A69B408DD2C630B3B7AF05C1F0E22DC7E90C4A31F585FB9D9E4DEB4E9607CB49C47E6D8DCEC439AEBD1EDF4CB0075B1164A3F29C33DC9D0D59ED5763AD8B1646D0F655A00B6918A90A417989F9AA44B5CDD08CF1BE46874218E1247A263E64DC1228B540E70CE9F0FA70EDC4B5D02CDC450AF18F6B586FB850848E09682C5B6ADFB680A6262F90856FEAE11843B277EA039786313A1AE260DB0062AFAE786B61D4A4C3B30B8194379BD44436879EDFD61FFACAA894498CC26E2F7D823F0AE7687ECC67930799DC402BF4F95DB72001F508D7DA37EAAAB0C2C553A53E7587ACC342167F62EA39C37B3E61A5D7AB113CC38F8B7525768A67BEC285F0ABE9BA6A9957C77A45602BF82F1059E55AE9B9FB126D24E3003D4B21C9CEE851527A324A6F48FAF80387D09B59CAB3643925EC74FEC4374EC3E63853E741638EE27D829CE5DC11B8120279EA9605061513C6A69796FE9CB8DCFA0EC70EEEDDD70927703FA4C64BC723B94D358371310ABB486F086ABAADA7B78B1C0C55D88EF497EF7B10071D8AE72E2E28078D04ABF04581FC9D4FEE6AAAC4637E6F9F6F65AAB1BEC7526CC1BE743A0EA8481AA9E069A9CCB7DC1575345305FBBE7338C1D82BC10A1B64E69EEF7EAE67C5819A3B49BA603F7477F19B217AFEC4BC32DADD26255E2F917806ADF9E64F769AF70AE5691B26070A6C65732530D93AE6D1CCBDC77AE37C494B51775", + "sk": "CA806CF2D4690C7BB3AC7CC12320888B62C8202262BC7F8766EB6D7A3A067A7482939DE8E5383E4A4D7CCA79A9B7B5F621A461B2A1894E53315103F03C391E0A38F615C6BA1E541A423565FC34907D84917BEB652AA4C7C89B35EA83F793FB3869705E5DEDC1D7D34ECBB4D95C1D35DD6B40DE0CECA740A4E31A27A3B9B98B004167782002506841243131365280841862554703104113155456536303543617108241084365386764253004844717327286064008824375547612437003687713635685066644742221774873358808665720400037071175028268662180577204401046247407058352323335075052670824212300407483106303227830177854464331616047542826861670237417840476056071515848278403033816884841214314076440461221508580035331828782618221062670850105785181770543082612856215036712840812726467805080064220170772536041034233473660817847175128245640505226614302508264364233558221033502567126054184687247511388085075262104876576227676324033577673623810188261171678788152746506166666437714701318570634332258550030740802413325435742263763045437462580115223212302255580103400865160557838787133716521241880267285308440147661876354467437784576735016345306611633062308811754584122563375147088373865225564243753521041540308730534446822385070861372114166326555121551770304536258008600364651176054363425836546104588565084542687503166017467336054565181617671174833865845685463658560857723333778762132475402167621010761623608348147038670132886240342442203328236027687753446546143324435782630665465553071476465625052657022353521572181631224342003132015665731086200251034727642342042768724157205803313336582551523358281602585074476178580187227145207635537012102513281730837422237248644518856730446206270316046650705818616665454358454738580353684110371157587563500822416111325582357584873627108128414201573148520755163811133056706316481086737445764287175387115416137177806484511265720218435445723261765302547621018234141462250030101638825222058372031833322338705318630036282520683874156368725686845163013242685832845523211553403620674105511622738815740862134023810117557426767760474585642644381655073854814045378307374382347381682033386078518685732885231765713423524881768718425148633644633286058714086311531058034818681263601377352475382525127272081155327226706655400072010405570087661815758158316283675713547420087156758728037757338135282288202782248501716018427204542088117607023584376282157782581470415233186584826507805762724272460033571412651326634402130004312645872667823075287652008020443487546340027782053437118628753610138356363183678428866266814623572045615003787625306877435726552077775273853857342148168433307612655423471126126802170023576688573236778627018467128804074385508720177344051461510855273367027750453251260135356145844210610652605165255220226672777165242368018647605284032071386241066412541114087584161112462346880726742547517663078120246705222743787525124154100750480507431087464341512207843441744722418777548374068250520572687713551245737701746245167380432348183857040811300514238606167175033186851181631382615450327661753468814784210764752450808523060630255288500182478823571263715802420751310703278612077507052483158216127060610280280340534522742587786314172781347215116342513C16B0A1B5B614ED286BE55E5CC1777A2680709F20FB7C0BE8326186386A4F081761EA493C531A8A89B64AC384C313F63EF47D643A8E614A9D8D00EC276D1FC7D84034EA545B2FD2BDADF7F90D0BF68EC519E47A35F14510BFC78314E51AE02001C503E723A4B6CBDF23A73D7E0150A27CD344520027639033E28C34E7E6413827C4F8213F09BABD184118676D5E1361B056F3CF3D5E0CBDAE14AB817EB1C8C4F9A94B65900259F62B3E099DA04A73CB7A671DD3814FD163472983BC8656C8BCBF2DC6EC110827656B37ADD2B79E3B7FBCA07D40DA224F67A06EED7E57B0226434017DC436754C5A9464C687BDFD74E5EF2ADFA208F44F18A40E36EFFB2271C634F1FEB5DDE90C929EF2106368C73A7672217BD86489E0F17B5EE32A61AF1950DF50E15E3E0DB1293E0D02F9DAA92999AB5BD13EC2AE956BA90C226FD88CBC6BF31FA87B403AD68D166F60B25E539B769ADC1A80918218DF163062A8671F090CF07686490C4AEEB58D396CD41C2111316444FB56200FC8B902A2EDE74F410C30153B8EF03552470F1C00852C564EAF18CA6D5DE6386F2077837388D3EC51894D90C2F86601E4CE8D6A974962189C43AF8C9F682573C794669379FE22EFAD679E4CC797DAAD13E7F41EA7990D62074DF58E69F0F33AD8A1C77EB95FD8253C692E3009239B5664FD4B86ACAF7403591C3FC2AC97FD750F09786A430351079FC257DC7884A45F9B418EEECCAE1D5F63759E3C9D61443EFCCFD751AC19A9959455AF7A49433032F8CC4F5678F65E9D6FA74761B9B9A1252928D760113DBED52CAA13DBD0B1B9D63D7F97C4A71A417BB8C823853236ED58721F903D8F3B8BA4142D9E4D3D95B59756B9A7D5FD0484AE286CCDAF3BD033F9B743F5DB8592253848FDC1E2DAE0FC717D056D8D36FE91B3B15C1165E018BEEFD0A28C43BBBB5D95A82CFC1FA2782F2593DCD3F982143E7AE80F70363AEDF228A7D847B185CDA5AA435BEF32D2E4033C34D3C164F0CDCB98DC36BB52A2C8E12E3E3B3D08DDB265528C7F4743E34CB72CB663EF69E086E6D46002138E35B2130FF2CD40D9854D674F98805B0041123CA280589EB45F066E7048A2A6E612E81AB1FA93BEB0FE673A9092C6F72856B696CCBFB6558A39209C92C800FA0ECE324091B88E67FF414AAADF439322E4DD3D6EA72924E4960FB7A4D9357BE2EC4C3279BB9BBF39AF61F0E390C6DE1F94A4786689C0CBC2E9ABBF3DC6D0D3538BD872B882284231CB76C5AD72560CA2FF6B7BF99639459E2861500A34384862856D6AAA944737ACB263294264209E02501D97FDE1307C45D733C4D35B4EA5EBF63A6CD16A8D0D3294CD4C678AC133BC2B6315E53F4E823F3FC259FA2696AF74E1EDE6C36A5452BC5A339068320123A24D097A379EAB362619070A62033949204024915836AE207E0855C28512DAEC08E70A931C69D96AA565C55B4917CEFA3D16F6505A77CD6DA985B4D2276658A0DC6055F5BB0463C6B8A521AA8F7DF7D9CC08BBA26D85670C888FC2B2DBDBB0D42A1B15067865E0991FB0CFEF9CFB7531769B5B3311845ADF229DD808243927BE8604495F7FEFC90021D1B5CE27D372DD9ACE488C83D99EDA25A84C794FBF626BECFEA5E3B1B360D520264910496C4922A59EFAA779CC9F5491000AB2A5043E18718FBFAC21BD187CCCA87199F63C29BD1F402DC1115F07CF993C9C46AC89F394D96A58F68D9682384AE586BA5E6F575837270B8F00062EE4A072AF52C5915B770C30C372BA591120DC8B0EB63CA29660AB16FC95D8F5F804479786B68D0BE9DC758775921EAA7B1A4DB99DD6FFEF29AF98DCD566210EFB33CF062C2555F0495BC654FC4952AA72E4B5C9793917440D63D5F5C4ECB0F901BCFA5F3309D57ACB366396B88EA9DDF1B9A07F649D5C0ED5B945FA4BEAA1F01A900F5B3FB64FCFA7D087A41CA397895EC045BF595C2B4DCF5488506A3C7EE9C4B588AB0E49FCBC7547EA2A8F867813321658A6240F12A1C2E47B1960BF1BA97FEE40A82B0AA13146BA443A891EAF7E885E82089A5EC21D75760BA5B0197DF5306B3438D3FA2B799C6E171B6D9BE22377704AC307B54A6EC6FD1FC98C57BD4A8B2E5CD5777799E3B86FA8F0D0A683EEE2167BF15C064DB860794D93ED601C425598F5A4D5B354CF0B8367AD742144B1CE70DB908A466F4312FFD7FD55FDF8F820398BAEA18ADF3B14710325B93877EBF94A8F68BD5A57D899D12FFBCD261373D2940D78A940D936F9B2F88599491928A9D54735F676516330E6D3E9F284FE32001BD5A72C0C0B29E2471D77FB31351CBA2D41AB5EC5513C568EE993457BCD6950D259E41E0682763F057D3C2234075C6380D65221E6E475AEEE13CB9DAC1D789B0BE04941985146149F3BAEA4F49053CF915721D53E4969B9E5EDC83342A2328FA0FC758E806C8B9507464E9BEB51379B650F6548F26930B7AEC18FB76FC3CC6E74C21A01D3CB206E2381EB61D9203C3BDA62B8BC2AE048FF6B3484E0EBE49D3689F51061A02D31AE18D0F3090598E4E0DA7079914B8BF4D9826B2ED5CD4FE1DEF48D63ADC7D66FDE0215A74A333F13F743EEF7CF61F6403CF927EEAE489A978F0EF1FE039E1AA74EBDE3434412474F4C9EF6F5A0F1D765624E7C7F5ADCE07434F8744D966B685139258006DB7107F7B0995C923E19A1A778639DA3B596F4ED950B4FDC87057DDD5BE1D59A6E52BB6BB5E3FCEF06ED76171DE35D7342E1143A7FF257CDDB98194934ECF249468FA77339BCE39223C299840D7F9A584A3C9E791399874235B3F1C0551486FAC4BD434A4AE8F04F011A849F2C8343900F0F9BDD9F9F8B80A7E6D9D1B127ACF0A37170415A2146B03BFCFAB50AA890EA64BE874D4A67AF2799FCFBD7772B5FED6CC2E6646845B007545EB24B12F7C5EF5F9B2AB7B4AC774B30E8FFDEBBDA4CD07CEF7023F20EEBEFC5D32D138F7DA6AC5C55D9896F618E274CC0BA43F058917667894F99BD0CA6E25912D6848AB545449D1A86BFDEB77929CC9E21FEFA8315AF65FEC0A4596F95BC3011A9F461A67E65464D36A7F7FAA07C487CFD2FCCEB9DA28745B4A7543C5EF49835914B25493A43DE0DDF4ECADB68EB4DBEB7EFA3DCEE7765D07DF439BB632F9723877DF94BFA7EF26936610F41B07D56026C91933F019C923CF98C255AA95748E99475B77F21F787D3606A3676A215785728734A7446B0A54EAADF962EDFD0C11F31187F84F2629069CDC97F99885A5F0B8A52FAF7B9171B40AC47B14E00D6C708A109F03C7E7130B1747BB5243C73D18BED9F97FB2F2D0449A0A9F4D4348B0291C47F2CE493209A7EFD0487D19A41383FC7C6CC8989F641918078ED90D2154E3CC3D4D0627FC86DEE37196EE9469D5446AC97A1A491E3FECFB656A4A3FB198FEA6D3CAF6C9FC09F79935589FDA995C90AE9D78BFD33954D0F78D322EDCA54E3C4F78F9B99B9C60CEF18C611ABEEBE7892D3CEAF5D6954F7C599BE6F283E9C1F60EA8509D8EA192EFE792E389D2E2F0180B92631226" + }, + { + "tcId": 50, + "deferred": false, + "seed": "74C0714236873EE53E7F8F65B1159ACCB1994B4E9D3E8FF194CC87D7116BC0B4", + "pk": "10EE0CD7D3E3C3D54FDC1B5367B8EF0DB5A20C92946B3471D8AFF7026C8D7406ACC5943341CC53C189A843AEA7399002EEFA251842F86CE14D00D974B4208734A416A048806AA9BE9D7B5B9EAC0C6CD7A3C163801253DCC0CCDD9AC2B4A663992B9E2B7EF3E2E8B1D93E4B677D1B36E8388A919E5B3A2F90E4EE69CE88735B8B105E98299ED5A9AC192479052030E6C56CF1FB2E5A822B3300950EB73A8FA59918C5468E3EFFA4A410E44FF78750D7B209F0BF48EC6E3062B76690489E1AE93A278D4FF6EF799079A8B42863688BC71154A32818CD76131FC400F2EC7AC3DE5C2954DF90AA3324756C8F31404A9094CFDFE98FF12D1F052C94C68026A214D0825A9E009A53AC5B8AC30777E05254E0C966160397FFFB0436A2CDF4FBE10B373349524AA455BF3A1A90AE05D9EF25843C8E9AEADB5FF113ED03BDAFC1EF32E3EE3F073C0FE0906D4331E2F18EDCD335F094CB3AB30214E3AD3A919BC1470685E514F86AE2008172226495349F4A9E55C3303072497571C1F4A2A28328E7D83E2B392943A5ED46095F55CB28A38BCEA6B801C1328031889A252851093FDF0B888E2E35C0CA28B5D204955BB6A41DF6AB0256B985D59FAA55880379B080DC7C1B856642985198F4B693AFB943B6C9463EC255013265C586371774AEC9E3251817ABAF21580D50A849328A828E5CAB4C9DF78C177FBA51527791437AFBB01B2D7E88824BB7A138AC8741606270EA33EA27AFFF8B3EB0F0732F60A8D179B95A513CDC9A8072C202CF4A5DC2DDFA51BA3BD186F6299C3F7AF805993808F3AF31E43BAFCD1A53A494E0D6B2B230FD9EA2E647614E50694B9FB19A810A83DE294C6BE35D3053CF2B16591E57A76B0D67C97B1BD8AED950BFC5F8526F571C72E6646F2B9FC09C9070E4A761FD82D723FDC96110A3D50D2B58CAF753DE0C8E55F32C80932662A8C17AC9B219456AA9649629CDB604322676C3E3BDA5EABA95F4F0DA031DAB5ADF92D8AD4190EEF2742CF42B26EF53A310C15D792DDB795114505222D05C21AA2567BB52E0C20A7251A672267D3B1F6728F5A0C00E957A534BA80D996379BF00BE4A725F2822643803F1F6780785B0583E0D41A67831E9B664C4E843C8BBBBE525C10FA7A7D5D3F082BC9CE72046EFE9C40EABDDE491C1346395412845B3E94EB9AA0E54381BFAFDB8186D59CF00E9EEECA5C369FF92930B569215FD7733BEA2B7BD8DD511C12EDE27ED5BF1A28080737C73557007890FB77BC5942433E8AF06234BFDCE21FC132C27A754709AA5B8640EB2C24D5F2D3E6DA9B9584317F27FE2BB5F74F95F512CB81BCCB2A0D70333B52415A39129759D6FC97954D0CF9DB5DE9F091784BA15D360B2FCB7F0F43F07FFEC2C3161C5C80C9586BA6323714391FD388A5DAFD74B436CA9455A5A025DD79D8F35632536C1E4B1BF67A3AD009878D1C067635AA9AB6989EAA3B8D788887ED3A968155CABF5BAECC99BA50F5257E9F712DCAD05EA58412B05ED7B484F54C04FE9F235E5E65AEBF23A55F60953F165C0820A9B2FFBFCF3FC6DE3DD30C1A82731705146E8F9D32B61E4AA16279AAEAC2E04957025C3C8D8AF4064924DEFCE4CA07E6F76BC56833A83B3CA4B9AC61527577C1BEF69312FE3C61A09954B0CB6261BB1272A736E66577F3DC268C026898961886EE7822056149C35CF6F96FED8885342D12A22AEC7B669A4700D19DBA1C275FDDA86EECF0393840EA0510F6BB5033C05914CE4B1F44615C12347A45405CD323738C2BE21385DEA60ADE73CA54D52F14203616471E0D0B3C1895BB7013FB7E549347D4F8AD066E20F8AC282B8EA89B83014303D2D9FEDFF90E3FDCE51124F167C9D32235E8126679D8033567FA1E5E41985CC108E5AAAF363BC677F961C30C1C34E7A866243E0FCF79271571BFB713D86F28F61C5AD2999FE7259F15EBC0622607553AF79AF73F01E8CB369CF6716B91F46444E6E5392AAFB8DEDAE015A50DB6C032EE026BB1C33C5D26B7B6656F6EEAF7C099172BDCD632F03BFAFC76F8C2A81EA19BD8981901B4C4304912B0D4CB25A27B3562956FE094422570B08089F1E28D87F46057D4F4ADE163E9045159D0967AD8377792C4FEF17A25F11E36B21DC0347A70D7BC79DAF4BAD4A6A153FD403F601AE7BB3E78B597521633500532B75A046CB78183C5E1EB84E3AA84D09EDEEEA0354B9DB64E9B5634E2AFA4FD66D08028538D1756826CD9D467DF890AE16A9AF40E4399BED757EB5D47B21B16D271E58DBAFDF8A98B669EE8FCD42108C746AA70A050E950828E4FEA76F3ECC3CECECB99CDA5CAB069A66E216CF977C623035346574198B607CD9E4582FD7F4FBE32DA87F7681451252D9440A33BC7021E41280DBF732DD2EF73CE59131F972903EE6E46D61B1E7CED204CB149D8429BF4B05E25E28685B021ACA8BD5F70D8FC737EC696DCF647577CD3ECD2CAD3116D9EBF7177F6AAB6EE5980822E57AFCA971D4057D141F1F55B82BB8F420A064B6E7C71077BBB137C0DED97B2AFA2A4988CD3951D2447DBD3D5079920CF75E569191EE46AB04393617B188EE9F2FE6F0E256C8C95266732007A1CF3F2A388CAEFD375BA4B78FC8CE538FC3E70151E94706A111B8A26F5076C4832D8B6691012081EA71AC204F3E318DFB7590A873E0E70362807693A30B7F251E9F363E494428BCAAD217FB9D035E4195C2D0DAA0B598B426B7EAF237F88965B4A4D674056AE40F5EE78ECE6A862144AB77F48F5B37486075D2", + "sk": "10EE0CD7D3E3C3D54FDC1B5367B8EF0DB5A20C92946B3471D8AFF7026C8D7406B9EF82C67AD72D44F22E10F89E426CCFB2811A8E07750EC2935A1F9444FF4131CB48A42D748BF952B8690AD6524023F73316D90AD774123DCC5319ED02F202FBFA1F1D197EFDD905014C177FDAEE49DCBC747225D2FB3CEA3ADB8E2F10F5755F31436765238773811321733542255302236533175246241780115462104128007273467573581348025535202227888706643664845147473688287871520557661451418514328878413038641373366831185718407742631304024076022441684115028005630816212057231680771587242263888473502112263046460617144852151674704418681846542541312625882506057864440533060357780443856681154777055701564087151872280855644718015658280312863677851147420664002785211407513254877075818406464328248013813154001322331624050147360555283035458016011331203524038706005326522546840872070671102851110243378174102083335884817020806875402760403831201100510876353316634888227144764415084733285837346265644801676051255766352818487278123042115281377854803730378374471578305031582424347547435583025488480537442240264682550287888171205276633203648543708665200471783114087658344004102353745875558615862028665386814251361853842784661712201842436134335654038651468851708818528563106713814084732620424444237602114074526706512504115573852618086623748284154003702757757885036608640844880578740408271280183246214564565328110404504021103016366323280028504148533853428165340303521887433431373146283407730451035150720684600438720240345177513074482742355148418025323238586232103826864137218026215613418453320312007670683531321512305778830220658672678877563067006255872600208024500124245128464104281008478520046576600633618564710588403104531170654438824562483140304830274223077451374414444447124376042865584403545752862327612288316107336565543304420625625012177810618312506023087408115701507637225608287258644060687666174638270058500353333121758648835266567510606053434880354021738386588676806063236654101672728166185228385412582015006285747468822340712803265176441520244078283446424774241033356353475612312701617237258760886425214443261704054342328120028688506282815074881887174845040542014534164721023455783006371746652275687272147487705001375251724275752155608832577703522335257124614767107557731356735056633724055282726761568051586048862533873550710632478825084814164307166347670722803851310738410137755085005608733655557485423453372808253002062253267038441144230483053567613201418323534713125770348632334075865343351277534834615026336638362833351283363448556373502072322478778438815815664723328454262752274860247747123500500630273565256443614682104088854483626725222523065686710162472081316104233804041537588555546274842073138881460052176546281423571573185338586307437833408755217507062427213105610460654803111545817106235831580136240252415456220148378568237665852106565412111146242167358174564532174715154103728681582144676477318056841602550434801435838750170373643147742013068813731813005134634107011047674042315218355460415773452841407821547664873708810126218821246161302682282412113460675813240713848158403046611047337524175380380808012270778466665852652317643364873677411852533564414508451220153F0E1707371B65F20CAB5D5EBD4E8E11B4E4F5D822E845589D4DEF994F5257DD296A7A8B7A99B416B8A67923C9C493A9E4D235D76686F0A80C3B1D922147A744D5094C44F262C209CAE25B9424FFC972DC73F836FB02178023FA1C32F80C9738BE0B43A1D592EC849D675B7294D2F44CFE4C1075D945B06C11A2DC643477A1E4AF420C3599D3500CCF5CD9BE91602F3A3DA09678E49E076642697D5AF3BEADB383BF51FF2CB2E2C2B64175524E1F55113A4920AF070BDA6AC714CC7F10DBAA72879B73234B693B2A929FD8637A13A93A8CCDE2C5B3E5003BC9224FE8F0A0480C8BD9D12FF50B4DFBDC0EE6EB93038017377F024B2439A5E1F4C918818F3A775C63B8BD67F4D532C0EFB323CEA9B2F4860619000DF98E5092ED4E55B5D56D658A7F92FE58CA2751A17C91B82043A9167E891015CB90B1AEC900BF74770D7F442D102119F26DB95E31E70E8B3D31604F8D3F3E74E6B0936F5AD20AACCDDD7A70396F0167419BCBA7CE8B32334D2EB0688755838A03713A9C47798E4B1757734021FC6288E516492B37BF2A046E56419A1910564A564D642F14DEF38D81C4B963DAC9D23B3960E549DAD867F4280567033314CDEA6092AFC9D9A42AEA5E551EDFC4AFFD3542671EDC7740CBCAFA2299C3111287115CA755C7F9F14BAD648427A5D8DC9F687262EEA0E594D29B0B9AA6405219400C0FA2B6B8AECABFF90B0906CBC77A22926EDFB96AE021E20F930D307479D1831956EEBB08F4444A63597B3B3B2788C8D05CD519CB40BA1F74D6B8A8F6E71B809393A47522A8AA8220D0B1042CE95A744E81B65BB048B6ABF484F1747923D394BE5DA2C34F0BD81A28A2B0DCD1589EAA9F88F2451EB22B5A4C7906E818E0D8ED383749A87740F9261FB122F3E89DDE0D1CADF056D40D293574C0D8BEF6C7AE7FF2155B5098A2C83960F77E778CA8602F0EB6C019529D01B73EFEBD4F97FC855E4D11B2B8F0C791772A72931A4617535DFBF99F5FDC39CE1964D7D6F42192EE5A2F58685D18062E50AE46DC5C65D3561D4D09615111EEBE6D3ACD0B7E197255CA4BDE22464DA1C05C1601D72954E7AA5412541EEC3F43C3DA5956FB65C3CC0128AEB685C00D8B6C0A4155C1AA505D0C93AACE11BD702CA0E7FFA2B21E840DD71165D5E734738419D8A01549B4D1EC3194C6CC3243D67054C4AE559BE3039ED73BF7E9594051C30E32B31FE7B83577384336BA458201CE23414CB2DDA8E99F660B287B391F023DE4BA97F6FA87F7C2E98DF43DBF31A852EA4AC420DA3597EBECAE663A35949241C987AE63F2E0EE3A051C1F03C402FE17101680E21163886860B9763066EB9E2708865C97D9D2E06C938153BDEAC0C4BD252C5A9EAD82A5B2E757405E2538774E4E17C403C0FA87D92275C995B09345E288179C36815EE2FECCB138F5647275E4F87540A913DC6EF4C280F09549CF05A6FE2040F402C81BCA531D51A3BDCCB5552B48D4162B64F59C65E12B5B2DB7A6ACA488E5BEA8637ED36D5D1A774F8820274FEE0899CDF9BB802BF37311E398F2516DE4D4129B2A7043B39D10E0ABABD0EC17EA263F174CED22937C3DCD184531A79CD1A96F3CDEE3D1156E65623B1723F666FCB1B0DE4C0FE5303C99BCFFB31E583434E09BDD74932C1C77B1BA299087F584CF2C58C573413F84D98E499F89B50CBE9B261B0FE913F2B4C9C79C8177B749617F91ABDB62F1A7EE394FBB5CF355BAFBC6CE1E0CBC2D536C56CA0C72CC618132679DF48CF13C5C769487825F8755F616D62261B68B3BCC9837C5ECD952109FE184FD8AFD3DAAFA61C873E460C4362CBDA2D1A240BB919FD44914DF357D4BFA3943077B3FC3D052C98F325A1D0428E528A4BD88BC1E2B453AB657D514C0C38DAE4E628830881E73CE0FF6EE2D1112692D26DBEC1E66A7ADC56010BD25F9F6A7DEB15C2D9D8EE5CD0AE8FFC88F1175F5FA7380B8D1B81F0A70FCAF97B0DDE29257FA9729F5C423D8B532B3EBCAC59974DC03F487BF29CCC5D7ACD904D656DBCBB79989767A198E0EBEDA8F96840A7AB61ED3DB3C863B742B6A7EF8FE2D3F01530D554578C18E174F8A8C49F0A2B66D246346BD9D8122087714AD87FC884C42714BE251D28FB2CA0AE72AE94B340BB6EE71364F9E6D4A56F302DDF19D068E4ED6ED57D2BC913852902026E41B8AD643899FC77FC4ECF764F66EA6280D71C4B3A4BC8CD08BB218A22F5254B819626E5F809D9334A2F84AF3960B52849B7534705EC80075859CA6565EFBAA5594869242801B602B3A0D25E749439035D8EF7CAF3E24B40C7D4A666F83B0945232C192F60FA1341122C772FF83A9F41CE6EDBDBB4880C2A67F340A3163A28F1450499381B211458CB711723EB29C6470AFABAAD2B0BE532291A17CC537CCB4F8ECB9263A2AE4850C6C51C9F0195A284A90A22BBAA60C111B561D00FC0D3A9E82FD49A932E516DEA0C20E3F48F2D02DCFCDBDBE046384CE410BD650EAF21252484FC22A8E5DC4157AE37C91380F74ADE3170F70515AFD3143394BAA087532C523A2F33DB97AF8DCA20DEDF113633371974E23FD5E16B5FC5CD6A9FBB5201D0B5C55E2FAAC5AF3DF589C1A8F3F30CB4566CCAFC4E1E29618E03E936A1AB09AF052D0ED3D382DA96DDF004D59201AABA01A9809BDF5BEFC65C18FED60F885003827EC4B285C108FC5EC86CC54F400AB14B8424163857C8BDE700BB1351E1C8D9F4CA2CDF4071E5AF5623895C5E027C71B69CD0F50DE48ADE15E59F3FB5159B588F8D707BB6F78E178013D04E0B57F4601D7E473AD99C19A1077D6220AB78EC6A29F79B6F7A100A5B722343246C0F5998D77EB22DB6FDA2C14A143BEAD0BB9153F5B46E02E7527AC77B712B31785EF66DA524BD680097D1E4BF448951968D83817BA6AC22E08F337032944B070E0DE17D58E0CE99A55BC758F43BF743B1E978BBACFFFD698D85C356481CBD10C272DD6EE2DFCA53913AFB41E0B5EACB693ABEB5F10F6D9F4475A73184D208698E7D89D7623466EF4AB8332B753A4419FB459E29B67F392D008A2B64B97FDC17EBD81AF4B54F5ABA6E9B66583267472DDE96F20E5767D25FE0954A2EE9DF8F6D71FE8D31EFC6D0321EFB677C2BCC9EFAC39F517C66660B0D616FF28BED9CEEFFFB72C6222EAB8F8B85788422E0D450C1F8FC81478A6AE1523AB9C5002E0D46D83480D7885C43C990AAEE60B1697CA9153FA1EA89FD1655C5BB7EFBC097F1323B3D9373BE36842BAE4DFD30A215CA0386520B6FE10C18DCACA30E22048775434D95436D37D58BD521F7AB1CA8179744F236AF8DB5C49EFE51E54BAD9D254533D086B31C2752D1BA51AC37478728E22051A70AB190B860049D379A2A605F36BDFEFCDD7349FB8A84A1DDB132AF28F87F17A01D32CA508C1384537C79A6DC538E1C412BFDAC18A556F630DE3858D292A89A0BBFBF179AD4403F746A62D02707AE7F4570CB3A40B065B987A3D92D3D8327B1230DFC0B1263D66EE896A58FEB52E96CB87565C9A1D5185F907FF852BFFAD7ADFAC" + } + ] + }, + { + "tgId": 3, + "testType": "AFT", + "parameterSet": "ML-DSA-87", + "tests": [ + { + "tcId": 51, + "deferred": false, + "seed": "38359FBCD79582CFFE609E137EE2EFE8A8DBCBAD18BA92BB433AB4F09B49299D", + "pk": "6924BB4257A7B9AFF095C30BB35C6AE4198263120F8039AA4E78E174A786CE008301E666F59D3EC5044DE456788FDE19EB39677B5F9FE14150DA463A706F3BAF715B95336B2D685A7CD7880713E4587BF7D857BF7E315696B8D0D9D49E142918BF0974E7F43237D4BE3AD394599E3D39BB7649932553447E5D5ACC3499930176ECD3A844A425F50D0511C9226C4B9A24F2A011CD88D32308E0312A0C87CC34A995823C65F4F0F98E50C37788CE38DC28FB8B9BFAAFA904B541EE712F6A041E0611374F6BF17EAC0BD56F3B6BF336DA9242070C2469A20C4D1616149A6159252011D299F93F986D875DD30B38A22549174570138C2BB3AA9CBEA91974F3D89BF5AE32BE9E58B854A2F8E86FF76780C03490F467DB0651C20B1DF60EB97A3C99D9BD664BE6A5E4C8A8AD4CC36390D7004E4BB421DAED654C357DA4D68498933EC71777AD64C2AE013C73EB457C68EF9A745ADEEB4FDFC879E774D03FAF6B14AAB10752E24B52D0F2D94D540A1EBE10F597E514442D6C13C2E2498E8AF3017C52DB233A90717DF25B4D072B7D88EE8731D16824C95D1FB983C449DEB466276060FEE4C7EE381451F232C29C7C3220850C61D1C3C00DB1CD9726A02A56609F3A65D3D164604588CD9B431412F1ADD914C5C2DABBC90467C0C4EA5F76E24AA618765F8B0636D7B065E1F4E6F622EAE17152458C766586772D363FA99214F472B0DB8A1E49D82D0278F2958B0AAA1586DB134BDFD2438742495007E2FE5B60E246399226947A12EA17631CAA534687CB75C060B4797EAB8277CC4F8A7A20387606EFE2DBD3E736249277D90FCAB992A8C99E85AB03EB4CAC5D88553958528AF92974718135F1D0C793EB000EA0AEC3EC1858FDD18688D1DA27278DEBF2CA8110BA4A204F7930E1C8CEECAFB73F75DDB34C5C55968A7933058426B55D039F7292AC43F64584F6DF187A1D6B003F514CC13B26C2F348195AA321DE6A27EC11348DE50D825A2964C631992E4B0B425B1BEB4F9600E3ADC4431CF2E88B4223D2DB663C3CE70EF85DDD56A9BAF138A9D7EDD894131C3A8F41A04EF9F86752B72181FABB37C86B877E61D60EED95EEFFABE6376E14ACA817C5F41961AF8A7849BAC094917B2D132276B6B3486AFF950D23D4AADC24CE98A5269E1C69917960A31EE09A527C358175CAA0CB1B018E9526D93534EADBACB52B273D735E22DD0D5C28FA3E47CFE90B5215AE24F146C3464BFEAF01D28DAA553C1E94428A104A9D78AEC762591E8879F76851CFB4648566721B0CAC1F14FE16149A9D8210CC8F2F50DEF7B46C843BE93BD8D55602493350AB560EA5BA17716423BE0EB8360AB109D8FB18BFEA040847B7335145D4F200D19CF6FE7BAC917F426C9B3D39A9CA4329818F240E7DA382761072F4A6505EA8E76C1E446FEB6625E38DDBCD3CDA81E83BF768F3E01D9D263B367303AE156C0B7183364A1E7941A09298A3ADF7BD231E6114B9DCE7952B113F78163138B9266F843F1ED97D9C2B163A6E8BD4C1AB4E179367C5AC96CECF5050FE821FDFA44E9E680B61C6018932DF717811459AF2542E2CDE77178C2E9880F011E405EAFA59C8CBBED76E5A1941104B1B9D3A60491C954755E02E894103F1F4977475E9EA36609FD67C9DE318EDA2370DCCDBB9CEF7AE6360905EC220838C9769823441CDD0DA8EF0ABE5F2D1D76E2FE08FEF53DE1D6166AB1A92B1AC093E5ABF7658C4B57287F2D1FD7B82DEDAF8D5A4FBAC4B35D58231694E162497578ABD7AA7C8FE7B3541A7F18E54E8B7F08764C5E68449DF655901549832D628FA63D2B2C5A150933994A9863317AD40D778D9D2C05C7898850B90173223C7A0AF890FD7E66221B6F06318B2ED5E199CB424885AB841E7A4726FABA2F9BB53BC3236434C35FBBE4B1A0F93F50C37896C29F8E302AD31ED3331D620E3B629455101A1F1CC7BA5E46E68ED4A8CCC87B4DC75BC0162B6330F833FBA2575DFAF5B5F28BC54FF2BA81E7A47313C15482B605E66BB38C6198F1392104080FBE78B86B1BC9A6FB881F5C7820147E6BA14B81ACCF20CAE96641094C216902EA5C125F6C935A150D7C9ACC5D9E2E5D90E38C0503AA9426017C76AAFCD5261B506274EC13A9679FB09796027A4BB759D928279B94D841A097393BF7E5BD69A496CC3DECD2B0F07F83392AADE33DC51B2A84F6A07635DC0EF57A9AD5959B6A50B7BA509AD5B11FAD26B419F9F1E3F9C7329B5A953D7CC87B2DE210611CF52A639EF2B3908012CB88E1D6F57625079CB103D6C98101A11BD2233B65602CA3049BD320520419F76B061E3598DE38152C88767D1A24FBD02BB10C38EACAE317DE6BB287B4D2CAE5DA0214965D8773778626E9B972859D8482B8D0547E4F56DFF87681D5BC5120F613FBBD91E1F14E6DEFE672E2A7EABCBBB9B11082C5E700AA0B1F7C1785FCED19A93AFE7C59FA2519BCDEB494C3D13B2125F385323B816C68F8F5628C7C2ABFD0278A337073DA74D16099698C4B114E8A8CE344E0A15D0FC7ED497B001D53D4C96DC3954D3B4B956CB9D2A272C51F1559B22904B40CC8531E40CC412C68CB6EEA4A4090B38E2797329985467E818A524D3228EACAE7825D3DAD2EAA422FDC77AED71A205DA7838D945E7FEC37E4DCA67E504CE35E5B045F56F1E8D7529EBD6F1AF7B6E939E2B7AB4027D37A5135D172DA1AF9CA2F728A6F37DE60DD23D97D11E75AB1FD51F8E9A1397E5822159DB583802B32EEBB4567ECE3746D1AE33314785643DD2A0741E7F1BF2D261F22124E8DDD08C640A48B54717517C21CD325328BC239CA028B2630D063C8CC20BE9BDB48502DADDE73FFED5963816533E020AED1208536255B1CCE985433127FF4F04D5B1E2F2108704B8B966588C0156AFC2AE192986FBEC443BAEF6CB85A6F29C7792405A24114710AE1C746444FDF5FB659E5E346826207B8C54463A0617CE17FF33E40F931FE576715C932EF29FD76B04A69B58E0303D8EF25678C8B70AF12E9045591C04E8B77106940415177E868593A09C7E14619A4B332F9ADC3A658B86017F32656C5429C115E110037A8CC7E544677D2DD239A59D54D0F3C7460EC15208346BA56DF5086C5DBCC41E0C95FCB6861C2C0C32AAF3454EFEE2FFBA214B430EF248A59B32444D8D0D3DB87C9D4B1536D157728EE7585EF532776A003A023C0AB0E9FF557108C390684D565A665063266AE6670ED53B0FAF8FF67829BB737825B153A9338CBE3DF1A462849B93A81F84ED07BE6D6240003274737F618DCB26E48252CE4204DD3139FF6876F43B305D835620FEDF79AA67433DC25287320E9917967B70B2D866D17B698BFFF2B3AB9514949E58B57C68A45412C1FC421C768BF5EE8A10C8AEF56926F51EC62C11569F31AA517868E5CAD89E958066EB9EDD7271B31CB4B1D6CE211225AEB5B57F749719DA07ECBEFE03881DDE3D81E4135F2DC81AF779776C1B8057162A6C982FBB4DA6A9AD284AB10C70022044F46D400BF6AD7182D197789983BE99227979A1334BA149D869BA1C4088123435BF978541356DAF171F33ADB1C97907A0FB5845074A85D26F546135AED0F91BE4539C12BF9411E4B556F687D069DB6B21FE2B7F321887448CEA55DB19FBB8B0482A55AEC16738D74CD265093836BE99D4FB53E9B014B037CDBFE9", + "sk": "6924BB4257A7B9AFF095C30BB35C6AE4198263120F8039AA4E78E174A786CE003B9AC2C1422A1AE802DDD7464D3F32729A3C7DE894D506ACAD25CEB372EA3149C98780DCD1314BAA29B9B807754C47DE5DCA954064F28528B815FE27B79AC506B3AD7629D2C971AB8F282E0C6E7E5548EE0E113242B7A0E064A6DBCE30C5619B19800889A04404B50013C088C1302962124CD3B4910A352C43123119996522185202C38523440D90244A1A30224428618106291897680A200908326A44A44C4490218A16689AA8511AA52C62468D04C340D3862860A46013187084948C63C04404A92820082043162A23292D1AB12948B60921883100C53000C48CD98268E1304C6332450C328618083191980D10B8709B302264040893A48C21C9700C35715B000D143122CC98102104809B28641C308021307118335024254408178CC00848844490489830CA440009195119230C52200E4906321C154E194885132549A3000408156D20410CDA4252C1348C00316943822464946D1C81110196214B0200CA2884CC466451186A181000A4982160B06803946C94485180404692222C23446998264D1C01085202208AA6080A316193400E9CC81181322E21158484C24100227254226258069248484411270404C011928245A1C68CE33266C138725A86010CC99084340858A86080C070D026629B302A04296904108D0BB904504628504824D04805A24802C3208CA014004138214B240104B5494200000C2428124084A220449B069063C0888C14214912105416242087445010850CB564DB2441D042299A168A21B44C13B77010C085190269CC40611C4846980625601446E4226224272262242944C62D08318420322104B4610A3812D92844A40820CCA8290B21310A3429032140C1A26C8A161252A664A3B251042951C4049163B02D1444308C40660C400C01A52C09942D62C61103985019104D19A828D38640C0306554A671E0B4859B8610043669D0462918A371402249004385CB4028893666412269A42851D98029140721DA80911B26505BA0609942715088491023095A902122278E43B2700CC94CA402709240100A397002360E113041D8402D1B246DC392614C868D21B800D3242212C82112998509160C5AA22409344210A22403428CC0B28D12B66963340DCCB065A112114A3869CC148158440954A6800CA805C4388A8406019B322D831290090260A1288858104124400219344818A04D001062132250E338219A962153088051260199C4281BB97104978404052CA0C210D3428181424D61846C5A30491BC224C02028CA922D4A90100427864C962109194514822C11A69113B80403187001A2515214495A0230CB302C94102C00498609A025C2124C1B026940A444411662022528DCA22D0016425830665B8624D42448DB260C4C088501904921244154068402434A244205401448CA4484C0420C9826049CA205D1C2511301861CA150D902500C39868C0031220548D31081124805D1086962382C0A23709B4472E3486E22967014336CD8902903004963208A039125088921C0820C994032C2344E4B9869098044E4046994200999246D09A96001292DC842288A3402E408700C236E0A054964442A82C800024831CB90501C056812122CD0800C594861CBA6099CC08142B80024418A94204042144D19466218050924336AD400611248328A047293B46962C27141A68944963162304683426C00192209464D8B0649E1B070424431C180659C002411A83113212C4B46281B180D884270D1B00D90C845DAC248591426224400C2944150C804180000CBA62419021010890C18222162A881C89248D3942082067209A8900C498A41862819C5809A184D14102E2212520008120C334563C63010934C60C631DC400E98825060022AD22240E4062DDB320ECA324ED4182408C3284AC268E28040A1C86451C265CB166023094C820468D9222E1C499242242100370EC812726408250A202A58240459164C08173000460512904003072152C0641C836D9C322E11158A1035885AA08DD9804803B64C0110651086401101420AC164DB224D64B25102360D93463114B668638429C8102494300819370214824588284054A8299014126136120B098CA49828C292454C006063C481C03625CA882D244030D3A82DC9C825D2844800329250A271D3440D223460121312868C5F8620794A050E20D0E1011786240EA664F2F69BB1B7E30EC66B1A4A0BE59B79F2198AD9804483E475E53B3C49CB0CE5EF92912AF440F23B995813D11B59F798E93C9D13539817C7AC68CAD1AA1AC27656BD0C4797E9C8EC17784C1A327A9DFEAF4D6191EECDAFE049B733FE39D5EB4000936FEEFCF82928E9F94CFD5CF4C1E3DEB1433A47F6D328B5E83DD156D0182DC692347591AA6F732CFBE982935FD1846CACF4CB8515C55AB85EE5AD44CB09D3269E2E6D11780961FD131D5E6FBF89849F47F2B71D8283FF25385E52B07DBB266C674CEE3D0B5DF5A56D8BDCDCFAAEE6A248E71DB1345AFC597CA830A1A35B4396EF4C1ADF9ED01BCE9B6EB637FA24AA160B9076BAE30559F8B29DEDB3D25B79064AB0CF8B8D70ADDDEB8B174248D5AEA4D18DE43B8938CDD2ACBA5477BD4AACC3CE595E5D269FE675210D23152B04710F368428794A75F49B683ED20DD647515777955A8CB38A36AFCD2CE0ACEC4F0DFE807702D1EB3BDE72E9E085AA4E09EB1B0947413852EC3C0AC52F06CB959C85394EB3748119EDBE6C80D2D8F792CE0D915E4F4B151EFB135E7F4DC97D858141C57F70417B43A6A126956978D78EFB9F037243B4CB41DF968B7EE5B52087F05AA9FE487BD16C0347CF1335760BD2398AD54DDA00A5AAC446D80B1C7998C602192ADAFCB809D14EE328641BA3AA00F8D29C3A848ACBDC1946BC0D35E0BE0F8F7E3DA3F68D9FA9768F5CF275534A0ECA9E60FCEA38F1E042C316143A767B33ACCAD8C8D66C70C75FD1F0B2586B653AD4AF54E56EF06933EAD31DE365D110B9C4A2A98BCBA165CAFE386F887C72156EB14FF0DAD665616CE3CE65C1904F2C1747B2EC2B5C9D6776BCD79E5AC64B7933BDDEDEDDBBC725BFDBCCDE2FB375AE2BE3537BDF89BF4C25F83A49D6A6A8D0761CF39D620C53ED837D198255CF5B910A6DB57877DF92D8BB6E9C526B8C4EC93100DEE0500A210C984583E1538160EDAC2C6F866E7F5D99D7B1B81582F5D0EBBF2786E3F556013BA9B6F656EB798838EA0579201A95D56BBC3BCDB9511AFBD4D81288896F87108C077F1A81A3BD297BB124A80086890242995E03CF42A0C21E272A9AFA1DC103463D2AB494F7D017686D31894DD2F6EBB0C3CB6223EC79C65D45C1B0D4EF1961F16D653FCF25977B651EC51A13AE8D4A3472EE71969A7A936F5DBBB9396A46D97642358CAF4894C9A6DF84A59C5962A6990A76F0614890169F001870D49CF2E75008CC4A5D85E72DE2D6CF3FA71852253522FE8B0E423CB417A38EB78C8763C3720C04E67FF88979EBA09E34538BB523B99B8E34167412F77AEA894D83ACF946FC054D0AF47295E51ED83F7486940A4D41C04AD7EBEE610BF1D03FA54071D51A1509E4F49163A25081BE8790D087F5F4F05C88550FCA9BF99C9BE5953D51DD0845C93E41EEEF62E0794B2927C4F5ED9BD3E34EA9200A79DDEB4B2D8F305FE05F827C7E2ED186341CB5D1152FC80104E0E13683D941294C778417164B684A976E56E78DA4D17C3C73229314870B85C455C23B830B9A28A3D8C0B566426DC169F326ABCE2EFFF39E9B199AE5C1292B6F2EF37AF1DEA9272C8D5423DF8A5632F991E14DCA2514788B62BE164828E9ACB893DDA602A5E2FB9EFCBEFD95ABFB82D2B02D49CC53084A49AB1BEC23E5B4C8E714CB03405F1BCF7E11BB59729DDC0B7BEFB291276DCEDACAAD39A2F01C7DC98B9E065EAFED1CC8CE3E848080A2FC5B98C9F6BF5040273342F0312F8B9844594A503DD3E6AF1C9E35C1032A4A8A5E7BF33A82F35E16EDF8C60C90021D8C0BA4C386245DFEF09448431D8C00D1E26EE4D8C77DAA1A705ED4792ACB4EA27C1566FB56683C43BF67842E67534CB3F9677C8AB9D0EEE7827CDEFC223AC948B880B5F1CE9537272932002C1A4DD218F527166EBFB2B2FA2BF37246ECDFDFA72B6DA11C30D1C7D248AD64818F691D59B755DAF71BED9AB5FB52E03622A900D66B4C6384169BDF9EB61C02DF45FB76B1A26F34E938B190861745C021FA876200C7FC8E222DDBFAD8BE781B185424AAAFC65862DB132BEC6D18837A1F58A876C99E63F51420B83F459675612F7ACF80B4EB1DD0721CAA1B4970DA608679C6383E817FE16B66B19181EDFC39270C7E917B1F10EB7A011997E967853B78E00CFD58D224D933CC5A995532DCD4E532E4030515F4A05B331D575DDAC29BAB069F09AF0D173373DB1EC2B6366BB371008A2386FD88BE77F5ED5E198CBE88DF24BC6E393FEBC10C470A72D47C0F834653C9AE800E893C6BA68EA28A838FCBB69C3E964A5FAFC2067DD406B257C98DD3979EC7C7ECBE96A33D85515DA2CB6AA5E1FFF204AF62DD4119A0E48C04A3F2B38660F52964D8D4AEE146A9C53C31906DAD0FD90B5D83B3E31B690A4C4935249981BE1F1A85EC6E0FEE4C88F2D89E2969AB8CBBEB501916558D29EA7C3ECF1C9EF1A04350633B4CDA737DFB151CB5E7361173F3AEDDDF527D73F2F9D5B6213AA68F883E9A2633785EC6BE642A9FD0F21A42F6B9DAABDCD1E6ADBEF64841B59686EAE3EC88EEF0A9CBC12BC012622DF2DD93A86229044AF2F260D2183F51E833EE92D98F0251E3F85FAB74CE367B8B7AA63D3CF8C8BF4D78358BAE0A0241E210AC69353087CC7331357EB4450F9509CFE595F54032EE057754A8EDD746CB9282E768DC6B830C5B4A219343AD124EDB3BBC42505566A7038C959BC35585B6055F1968DA243F778F4E46DB462ABEB93B81243C31EB59622EDF81F06CCC61D2A6EA73E109C387915F277BCF1FC11105BBA70293C0FAB5C065F23BAA19290A302F08091107A4B1D568852622098383427760EF8F2928625BDDA5F514C5ADE959891EF2959F248A3532BF9D30E714059EBDEC958708F8A83C268BEF2682D603CA886347E198FD68233999C77D30D7455DE6BCFD0144277062B304BEF0E34C5A9D8D780D29EC2321E07340771C46360483ADCAF12D5B79FDBFE2856ACE8859F6B12414B3F7E8BB5813498960F34FDC64FC848579CAF9DCCF19B4FB825ED5716DCCCD6872CBDE3831D67384942CD8A9EC4BBFEF5706B8F9F05FE1E8FE69D3EA6A8621C22144177B1C1259E1A79DFDF89728887BEF1A70482556831B672440E13FE3E3FC8204A02EA1EFF19D95253887285BFBEA16A0F219EFBCEC30A8AE86589A5703103A8A393FA6F6B657704AC677C14CD10D3D62D13FBD378C2DDA325B61B85952D51293871E1FCDC948C77BEAE9A6F0E87CE1A8051C8F8087685C12624BDF58380ED66F55B43DDD6D362173A5BD389859C17D95ECE3AB732639FFE451CD103EE4854DB2F39614F658BAA384BC9948D0714EB48A887143E7A1FA4B690C22B492A70C612B59FFD2D6B3B5E99C2003E2C359B1E62DCB620C7A246A7B9B3246131556F2F3D513A23C6A9FD2280ED686D767CCD01754EB4C99692F2B380C36081344C1D35EE1949736B6976F4852CFBE64FABCF11B9AFB828576B4F9787AA7D03E84598A7143EF7311FAF2970E23ED4C173F985D6450165AE3E241A18234E74FF3DDB921A5300B1C4FB6E432E698F53F66E38C07BCD6E77605DF4624D579076292DE1CE6FC6F0081A38BD92D39B24B73BAC1C52BD68E9181D3DCD0AC7534DB48901E5984F9902557BFA231B2EA28C3183262A1B2221F7426EA88A5816093A5CAE2CD5D59A9390FC93A2956944B064CF013BCDB67FB423D1328D2C6D7BA329013FA2D30EFD69FDCA1A95EA6D06C7363534B2F3F7DAAFA296EAA09B3668E9CF82D9BA959B32F3CAD3C10C6EA48611554539C37DF6BCA3385EAD3FCFF96D372B42393B73C8DAAAA31506EE0527B7FB3E593DCCCA57C8FBBD4A3C7F8A53899869132FBC3E4050607BBFE29C675E3945E74A31CD531BA7AEB2E2F0CD990B8F983A90DFEA0568F0677EA9563F7C479DE968940CF242992692865CFDA89FA078BBEF49CE4575BDFB380366011C8435F12B42D9AB99AB6A31912C4354149D723101D1365A65E7CC68D82E30517773902FB38DDA2B324E7208E987ED287D092E7662A430241BFCA552D314127E38C8597A89519D4F1E62A79465AD5F4EAA3FA77CD98326D2F92CE9852055CECCF62D63CB9D7F198AE085E4D45C8E48FCFFE593AD652D9154167BF3E6195810A445AE158F1F9A6793363AFC1F22CA882FEED3A5F5727CA76477C5F23F0FC8700CDC6A5BCB2B20B4F9266351D304A96A82BF5F314AF685C1C707C92E3E847B7047D689C70B25E5501CAEC9919626F4A0FC81586AF1EC88889B423387D5D95482618A650E80B53B07CACE3228940602E3DB47466CE9BCCB6E4D8AA61C8912583E810B3B2E7E9CB48BD403ECF08D28C70AE0B620859C1F09B61131404C3D5BFFCD860E0F42AB299006230B2876D77DDA91C8C62BD93A844E4B344E3255EEA531C6C458D04ABDB0FAEF2D1C0B4C55F570A5A51023F4D4EFFF59F9ABE17922FE732CA71BCD434AD7710B84CD4AC9F2507A06826562AD7F647826F9DBBE4EDD23F124369DB8526FC2B4D52F0741415F972BEF6A935BD812A56C8221B7DEF0F5106BC01E913E3D43DB86C2BB4C7E0762663C6DE788721C2AA07F8954887E2142F2E914A099EFC0AEE1339210D3E53DA3ECF88624B1119BE34010B886C80F51D1850838F2150E72B042AF32899C0D3D7B02A57F8CF263A369562E4E945A31282A502A95EE9BB0316C6861006DAC17F936F54C4C7" + }, + { + "tcId": 52, + "deferred": false, + "seed": "29B4987C62218C19C77D695EB904AFFAA1BFEF6A52F138604CDAB1534E66DC10", + "pk": "4E130489218BC6CD1A9DF06B2586365F4362D8A007563DD1BF7D77F29663CB459F1B080DCCA1E39FA04CC66B9DCD4A6CDD2FDC25B96E87D778C068A41D7D4AB8FFA0E156AEF370568021A0F56EC60853AA4579F7C7151A31A7A8E5257D791D06ED11CB264B658467E82EC5EFEEB6FA224577EEB84D4453C82D821B87771FE57B10526B6B003E94F9CC812731C08A4B9FFCE90A06AD3134BDA3CF4E7E46DA7BC775B95116E96B53817CDA3FD3BC4D6F612C52BC2EEEE4153159B6D223E7A7B20EAF926C822DD064375FD26CEE2DA8DBA4665409D5A4F38BA2464D393FA00258379038331E4FCE0115988C634A95656888EB26E95049435440F42006C3515C7BCF4EBD138792B163ED11ECB45719D9B7821D6F7768B631D67DC614CF595C42FD2255252152C38190A5E41BC5868839EFD2E12DD73AFB61E8719C0ABC10679249DA931B4BBA405A46C3C112A4004A8E3A273965DB3AEBD8CA5D2BD12584160CB21369B1C5163D111DDBFC040CECDAE8B580B038B0D476211B05414A04B72AEA2FF2BE302422CA22F77CC5E4B576BDB838FBCDE65606F841030C2EBEB821619EE7C3C60C82BCBC3D55B0150A72A95EB2363121B925414138674A0619E128EC73EE4A9868D257F79F27658657CB72D9987FD03826C38DE6509F97B25144E4D0FAB4F40A3C152CCEDD908C50F8EB12E775CF512337BE1DB1AE9B320541EFC0DBC70ADC7C50494295C11D5770D6AECEAE9EEDDA468AE90800474D80B5BAA4CFDFA0A56F3C120C8A2397F31C429F915D1E748539C2A60BF05FA043E93D503FFFFD538D5B22BC0FE8498DCF20EDEBFB9FB973CB00EFFB3B65DE718292D783A16BF01301AD2EE546D48C0F44A05323EB15137C0527CB1A55775A6BE5B0F3862BD8EDDB3CD54F9AFABC42916DB1473DCDF9FB115A64F8EE011F2CA6D11528384B3757711ACA40979C23E65DF41F8D4B2D593C1351B713AF8421970D9ACD3F7E7ABFC764B8CD985159A78205F20C7A478CD987A18325F20D30C33B172E94A7C8F3B097A0627EFB6DDF787973F4B410EBF38E3215B59A4C218FCB5973A378D9A2CEE29986A61B841069BAC816147D0D8DB1BFC8E7E0FE811B589484F19FFD03890861703A27A0C9D451048C925C40C888410044F7420FC25B6B79F99E1055BE964968C354C917F3F981F7B67D1AB451E127CB50E5A1B8C3F179C3FF2175DE548D1137297555BE12489E6F3CF2831DD0E45F2E4151011DBCFB8D55AB280C0F0B5A81B492A33C674BE15221A990B800D9CD5DA9048FDB938633A3BA965398D8FF1AB77F301ADF74FB7AF818E4ECF587416D1CF1BD0F50A65D5EE7EE34E1B6388A3FFF8063B12551BE96AD882EA8D4DEBD9E7DEB05990221114784E7D1092FC01F7BEE9EABD72D3F49E572BF79C771F3E912935C2C71F61BF53EEED86D4FE1D85D702E0CD0D322A92C39935C9ECDC838242C3C97B708A40CC8311F72127FA66F6B63F640C1499F1C70AF48179629E404ABDD56518268BDF1B55F3A6A61E4836B881CFE7B64A9663402FF2DDA2997BE6A557580477ADDC419D5932324306F4BBD3E014CDD8D8FC9102D1431BD895B0809F8BF9214932E915FA0CD1A67A00DFBAC207189D9DCC0A5E1842B92233B8336F19868F29EBD31064EA8227E157942ECBB4C05D40926B4497F277394A7625DE21518C1CF3880F6E23A0A18918BC441A8E7A2E63DE4A37EC35E559FC5FB0CC0E016CC7FE06752866DFB1117B07B635663F39974FD138700545F6B64B2AE401EF894DE97FBCCD34ACBD5CA3AB9A63864E2B0B5B12306065268BF0427478CA944BCF25B2AD50BA6D6481AD0D40EADF2977F12D028421AFF4556B7C450BD8BEEBC697005FC656051E8EBEB7F288361DA5F91AED8F578DF23BB964C68107E0FD6B4C022779F84D78B31F2D152B07D1DA564D425484A0A5F223C4EDE705CAA2652179FBC9A65BA065039E2D531B80645FF9F54FB131F697FA80277B743F33588636A771CD9DDBD0511FAB5F1642A02E043AAC57618887534FBE5EFD1441028BA58D68A390A3DF8EBCBAE896170BAF3E352DB8C2857DD5EFA25E2695C157234115D136631CA96CACF71D6DAD9138B86366FF62C30064EF467ED753D8560E47EBAB157E5EFE8115907092BFC06DA6F33FF14AD29573D61EFB73651AB2B515E67E9215DDF86BC52D2DBF2A4206AEFC55411784D8A44291AC7EE56E9D124E1E69B0C5DC4E418D88D3AEEC568DC2CAB4D812B124C7CD91FA8613AB0A5CFCD6F668075DC4069AAA37DC3C7EA67C184E02B5BB33D604C983CCB9ECEE5D4B6AF74E6F44932937425B18438F3D5F358BDCA002F8E0596EF63BB934A91B0DBB69D9B3830A5CF6E1DFEC05629AEBF50F31D2EBBD9ED0894617878F1B9ED88F0F718D765CEF17A06DC288484062533681506E440A3C0E84C90119859C0978D612F0C062BE8FC5FEF3A4759C9E6193C66B56FCCFFBB6D44C713B748BD4C4A4FABB9DA38468CB4300437E5258C383EF438323F23CFC1D6C77304EAB8629A8910CDBB91C3B5C6EB81DABD2240B62E0D3C60C25554150F33387461C514A258DD2FBC1EE8E39DA5BAA6AB3E26AAD009EB78906B488E41ED03EFEDE7D7F8E67605D3C3131F4FE41C79F9C146B6BF51C56734BBE8961421DED7C16A44730093AE312563B6D98305DF2EA0527E797DCB46330690ADACA60C4A240CC42F770375EC7A49800FC573D94E168B053DE9B5B485A530BE485EE5291301D8A70F1FAAE35B49274BF0739E0E5DE495FFD791B6A3C5DB7D81BD7EBA6DD2D9E326DF27F2DC957943B5BCCCF7A616B41B2DCF2269B9AAC96CC06337FECCAD0A870F0DF3F1F1E99E45869ABD22282EE80603DACADC28288B4D3BCD5FDB39C176EE3E92592310B3A7D42B58AA477D832E113D696BDC4E2A5946410803F24203EE93C13BF380F4C84E2C62722F75851E54B0718FF23DFFC937BD3D1D2D787673E60BD218C102B572C874EE3F5971EF7F24EA5EF2A093B6813718E526806F270F7712117AD6BA1A91D1A3CA817F66B0F354BE66DA05A2EF3B9D05685C107C74E09EA8BBFDD182A1C7A6AB9191224E4BA13AF29076652B79419E11060A0BCC68EF8F97598888C12BA214AB25FFE68298A959B0CC755F00D6FF2688E20451728C51AC2FC96F53115591845AC9E330AED88A7387B5F73A136E598041F7E81BA18321A0E620F088A8A882C691E9D8F99E4C00AC849B3057069F9A5A0024E3015D613B773AEA1E1581AA57FFC246E5EAC3DA2A84A4E48B60BCFA9EC42686ED217469CDEC1912ECD07A5BAB69FE67BE98515D200022B408ACB03E2E927E3A77E4DFF29AAAE0D1DE55779FBE73FFD37FDCE0A3FEACB64DF225FA31324C3E276BCD4753A2594032FCD27256ED4F34DD2BA992C3AAEFCC89F89D9B46635321368F2DB71A3F9612BEFDB641A6B33DC3D8AA317476BC805959261426F7331DEAA84B8C6BD2142B3077BA40A9284B6DBE7D6C92DE0A99D0C1BA619946BFE2537BC7AA29BA4347AD4FF2F5EBB554E740E49744E3200B7562CAEBB9FF565990B6C79E917884F162973DA858811C0A8D2799F65AA7B3CC8AFEAB97204EAEB83EBFBC6A688E48E7FCCDFF21987AD436DF23C16E27F9715F7660884E553421292862B5CDB5A246B13E75F5677DB14EB5802441A3F01F", + "sk": "4E130489218BC6CD1A9DF06B2586365F4362D8A007563DD1BF7D77F29663CB45F5A174EAF47F9C8BB723ECAE888081EF19773FD058691588480FE23247C9886F403733B8A4D5923E737E3EC5A5BC019D015672BF421BDB6A830CE2F9D229B6D2275C41BB2F14A0B5632D21945070EE1653E97CC251C8CDFCF4068211CB6A24D68A1290123730C4B87141040164442E24B4251B05251A248C94166EE33450844251234085591286DC08915CB870C2326A2497109186095CB2101BB2485C445261344C591012D9286023950DC0266220C70100108413A869C2322942C62520202182948908153153166CCBA0000944501AA90412318851427254B66002222A209130182344931629C80689E1B82101426D52242C1C13855322229B22916290909244308A2861E0A4518B222813111218098100076A1921419302908824621832280C898CD434000A800C22238CC8981181046D13899048024E0386204342699C44650CC2895A882559A06812316C1127680A394648B651DC384882102DC2364A02A12C5BC02C24A50118912160A64D20219100164620400150321011A2808A360E94124C1A1525C2C88C43248CD0266109076498B401C1484E04A010620201DCB0818C066624170222151251327291800024272E2009450AB9101400668410260CA25000828198348854060E9B36321C87040093444A300DDB84899A484A1B474513805053B840A38431412429CBC248CB3646A1340E18A269C9926D48128E04183049C8448C92800A46450CA05102184D19150108B8315A060813446A5B48655494411001689A448800305012070152442CD83080C0A22581226A194500489250CB82851394484A1051C3046D89124D02922C2313400AB14CA3B4241B228AA012204C0401A144898C4271641226C8028A884600E10445C808699A00804A3001DB102618B40D0C3204DC8665D898499B140964844161862D10808510016C22000DE0A830C418044CC049923485C03671A3022103A16DE0207112A7640815208AA4044C164EA12066D98001233730C3182220460410346890B42454424444B89042C888DCC29090106D13464C98C66443048582362D620009D0962812C02C88B00C5BA805A2C8619A84694008321B87644228011BA74D081761D4228E82006A5A420E5CB86101B6055B32668800318010901BA631C0401101443010450111A728843426DC90648C306481300A1289681CB92122472E21482A242705E312401B994114808C4B40104C1681584488A24672D3021121444552425108172C4A902188120221A02841822D58224420C500E00030129844E04231D31226CA960D0B4909CC480181262613248D98182C18448CD39200A3C46888102223136423238081A22C582009DC90445A148EC93291E1463122C981A02462181384DBC285E100905A10655B262982B09180C600E0986059306D18190614276D0C24851110200429894B2288C01080A2160A48B08C62304EC0446D4114211C3392A102891C23260B1209D8340422C224D4368D041451539021E1C2608A841114132920B90D984292C4361203909093C84493009221156523257092106E14C3701AA470E146209096280B342D18078D1A373110831083102DA20470822010430860501610D1447288906DDA94245226281025000C334143A04993386624A75182082844C2300BC47121356D0A300EC24240D4024A80302591B860A3042291A08113940C883800D4B670801268620648D848064806602423509A346222433183A6210C04484130844994805838049324286300020CA485C9C05162B28499166D98108183B681C0340961B28541348044064AD8320941022D0A352C983664C288695208850AA01000A22D1C137001A50081928509838891347111222D43862CDB24728CC4645A288A1C826854B04191024003486824346D24336C5C266A8104280BA4501347911122280C4301192124503840CA20315A488A04B8509BC26421450DA1340C634072DA288224C28404006620B729E2A6258094250C4265521040C32882DA1286022586884690D9288C02403123A861C930711828688C0866C90206582088A4A445201560521832C092600A09519404042302219B0620D1C02801122D2089600AB604642051CCA42C51164C21110563C23188C20544444563144A6130888B3860A118904C3852EBFE4A5235C8D8FDACBF1F0546D7E244B119225B648A9D6F84949F1097FF2A302FFD636B8ADCA5B833657227F6432C2409C7BB078696CBF666B7BFA550E7DD1EDF40119D51EBEFA2862A773F05427480464D6279581BC7E8829DEF05EDAFEDBA3894960E2F9C2700C52EC53BA72C8467097E08805A4C23106F3559C1CCE2AA70C23DF45DEAAFA26500E17E93C2A9FA71062E3DD628EC4065F78E192CEE47AF2C01FDC3A495EF01FAAB25C9AEFE9431154CEDBCABA4D2E9793291F52F8AB834129044E3C69DA4F726CB6909DF7FFFD4B7B48C1DE143CCB63E84276CC00595C1DFDA1FF6B134DA457C2B66E893EB6561DE33F96F8426E0E2791A278286A6C5B5155AC2E3B90821828C3546E451945863C0E9E2853F7B44C296C454F991D091B65221C1324809A8F683DA113DE0FF641C9141D68B888E816602F165B46777F1157C4D6C4656A5E99BD0EE46F89047B0C4A509AB2C3BED7A175E45815C16F9065F49C7261959FA0F9CF4B6A5A5742AD6C4D768F7B7AF02E453DABE24AE382DD50458A1D20E4D9F30E98404061F927F26A5B6A677B2957FE4C973B42F2A1A9F61A7C4DBFC4FA590130EBE23E0921760EF05F25D6C7A61E2B0D636FB21537298EEB279D38FD4B85744CEE35D168590C53AC9AF082A1B0C7A46EBE5828C6B98BD89F562C1145DC5A54B4ED8F7997D0E48CF90D56B9569D3A4C4847769BA3D1ED526724ADFAB7229E5CECAB2D08E7FA9B096669D063CA3FD42D2153FEA0E703E23178233435AB81E7588C9BAE343FBFDBE77AEF158DBDCE8E1A4C3A69CDC67F3EA1D4C923118310930CD2B83BF534EBA764635D12E5FC86EBF2560D12DB4B24E4434C9135E4CB7631E0B8AD570C54584BA92B27B54A502FDF57896EEF6054D55E2B15769B53784C8D024EF9B10CF583D99CB4155BB4E3E9B2C28D382952C062F6319D26D7DCB0E946767D13B11CB870265BF829A93DE55E17AE7AC5D706CD0484E62DDE8DC2B16CFE5063EB8327460C516921C312F2C47BE9E71AF239EDC87FB8EB3F2D712609B615FA634CF9991DD10C1897654D5534A537A193741AEE36EA98D768349BE367F63E21EEC6D6A5086C7490E6F6AB0D7776CBA761A28FB5C3FB1DCBB4A5A90F6A8147C80D5254C8870725FEC69C93285A5A974917A7F3E6C7EA58416B814FDFED39AE3AB71A62B0CBB0427EA697DF596784EFD9D650990DFBFD2B5AED08AE76A243497ABAEC5591150616BBA7D7DDAE4D522067062D98FCDDEB0360C2099F13CFC66D001B18C4D1A8CAF7AB4C8F12D9E931F641AECD1F894BBBD3A62E7EC18CDC02C2580625B5334E32E565D4FD9CB7EDC25E9ED12D0DEFFE81E94F62AD696BD3F2BD17585E9E3D87AF16C9EECF24CF61F53669918666F8585A4E2BC34F6205F5DE856BFC767C4D0E2B67622416CCF8CB89A619B65D9B0D002D457C5388314DA854C4CA94EC466B97C8A55DC08C73F7FF0DA6D898B7A77062F9150E322FBE3339C62AA192DEAB57816A27EEA7C9BCA609E79AB10C88B0137811BCE51E17298487C287074A0D1FDB59813BB535AC57FA6DE8178C6CEBA4E6130063DCA5D7E256D173C11E31BC072BA6A70582B3146113DF433F93D74A2A72CF55482A1030DFA0C2C6A0AFDF5E9837D22F7CE89C9A4D81FAF4EEAC6262701B011CAABAD823B5CED6918627F66B1A07C3E5944D53E161AF56478F7598530BFAC4317BB363D4B2B04BC3D0CD938527437C2F88DAE1D447033A315EA49B2ECF62EC6BF95711A57B7B6C0AB04FD6706FC3553A7B726F30C06347F4CF35D989F57AD779DB038280BE50125B9A8AC1A2C84F9B8C7A650A3EA1533F575CA029709E943DD9E1F2ACE7757143A8CB9FBA11025D49CA9CECE240D1B63140C30CE7D0EB2311E5BD9CD7EAA3FE81E93607D14D5D329FD28FDB0E62FB87D448C3C1F85B42FAEE0DC60993EBCFA8D848903E55E2E987D34467400B8F50741EB573BB9FD41A0A5BA61EC07EBDB2675912DE28FECB52A40494245EA078A754C1B9641F4F2B6D7512944A83E8D1A70B7F3E62A13E9C456152F163BA359752A91A8F833373D6CA24EE0901657636FB2DA1E9E0C16A789ED447036002098B7D9D66EF633047792E9CB8C8CD45DA05EB5ED49377F060CB67CC33AD0D609741D0B3DF408F584D83910FDBCED95724714F4334E8C6AAFF680D5AD60C5A1402A97641DC8FA7B1531DEAFD369EFEA623F475694B04E8E5F52FAC99D8BA2D928E60C4D8AF2A68683FE7EE6D82021E35B895D57BF7F4BED6E2DE8B0D1DD0D0662068D4A9674AA65121489ABF8DEF5F2A9F1E2D36A8AAFF54C56E2E6217C7C9DB4B750207C5AA367A25401C7A3C7ADA45E1BF4E3D777D1306755FC0D69830F3BF262B83E727E5415992D6BDECD7EBC6DCE31FCB1EE0B54DDFAF20B522608870C9A0B1C9DA746DAA1E13A451FDD6192EE7E4514B8B99BAE4FA2107CEE404A7BA585FA7E1F1529E66DFC6435A1C26D3CF0CA13836F0B44E8947833F8DCD0DC2FA60C9E6303BB78E1C6E72A3615F9B3719E9F6A0D2F043DBC9AD7BFA803DA6FF03BA5B366B50EA314E42AEFAB8D2861462982115C2C7D6248EC74F7289A3151EEBD3DA0F43B89E9B5C50FBD0955DD803A3109EE451F96F5DBF1F9B42CA04724779F0FBE9D1C672F6BC478E919A07A486732817EC3741F231E9ED25715FB86EA804DC1B23BBF148E20DA21E6301EDAFF8813F5A97BD9F196E40BCCC824281F7C7F0F4A5D396BD2D3AC94A99B0BF24BD7888276A52543B0435091B4E94328164576AE7A572D2C4693DEED54F583D85C783BCD540A1240C40B68AD8DEEAA7255387029653228EC60AF145C2ECDD26A1D0B267695ACDDD490495CCC87BC1013C065357569790FC44001EFCAC9DD18BDF6EF505BF5C4FC555DCFB2A098108A1C06A3400C10248480C8B3836B26CE19BA22EE4C087C687559B6B6EFCBDA275926CF10F151DA7B2A0EC4DC214EAAAB6F93043437B32E0CE139EA665E2CBAFEBE56D6F1B98BC82FB299C381076BD1E1B0564F39FF03795794374269B3321C8E2E9BC6EE8D03084C3BF949E26B759E5A71CCBCE856FD0CE5FE7F0531178B2C80E2F913D777CDF265CA351FD1EEAF2650A2C8A52ADEFE7EFDA688556AC442D9D4EF43AFB177987831AD7ECA98C3042581F2389EBB972BB11C8D6845C8159FFFF7B2B7AD2E77F6FD4FE21E00A528F1C243D84B4793ECD4BE3F94E59B2B0435518B9BE6BD0633E310F254B822A66EAA384D7AC066C4F273254F3A2C00CFCC43C3A52FEFFB2B51CE1564A0CE3682727BBE58D9455533269FCE603C7F6872A6C07BB290C0B8AA95134D55B8D551AD77F071985EDE813578564EADA5632B9AE931EEB24D6966DC6863DD2DEAB2E3D0F4CB3AE862AFEF5B6D4C9288B1B3079C395924C67B03C415E7A8070A6839996C5BAC53E427A61A7EA100CC10F3ABF7D311845DCA174FFD06C3F05B88CD2FF32E9E44659D7E80F40EC56172C68BC5293820886BC47E8339CBBAD03383D099888E668AD95A905373D30CDDF91756C9C7C89F6DCD6E0BC9E9C4ED9A876F1568B49B6CCE9C520110BB205E307ABF68A8FEA783D1FF4BDE01F57A6B1224E9C83FBEA507BF14F77BC27BA0806D48F8A0FA1CC1DC0EEED7FEE5FCBEA5FB609D76413329F54685CEE7E4FDD309114F71F864A26F05A672315150823110947291991437C60902AE0767BBD42C57D6C97F5CCEC62207C8123E750945BA0BB444C894A98DB610ACC5703121CF8A93C7CA9CCDA90EA0938304651EB84D2534F2E67960064F81A41ACFE3560066DEDC1D7F954C01CEC3A8083975829149FFD8A54E3EAB95A076361EB7561EFAA8E678987F381F662B59A49579D9A2453AE756C133EB4460E72218696DF703DCE965AC32CD144C83819076D6D82D8B5451E0FBC384EA3A2C5675F2042F48D1D1A914B384DD0727CCFDF0A07218B3BA7BD10A55A550679C12244059D2DE9F76A4B1855733725EDB2981CF956D22223833FD43B9669BA21B38FE2C6BF49484BB4FE9E5CCD5F883E856DF05525D9E3BC452B73E6CB6DB583E3641D215019D0C48EAAC8C03D646CE537800AE96457CF187D3CD456D13AE4B657FACC6D9F78581F209E94CBD19B6768FBE0F558AB7E2D4938A0D2D92C6C8BCA7A01D7500286756E87C9A55F10BF60E23F7D6039E17CC6340445E297FBB213730455D0A7B33B852E4829D31BFE5DC6AF3CB5916176E4D125863A49592A306B9ED9CDBA4E2F40A4C8F3C85943C10BA10B688DDF847FA2212E374C64148BF6D1D856768696C6C8F04D213065A453530CA6964377687CCB2AF180ECA47260A493C8427CD418E91D38C50FA9ABF904E419A612881CD595821657C95729FDF8D1D965E80D8F8F82C6009A8BFEBA81ACF69503B873F92E557DCA50F87187BFDAE231D0164CA86E58025F51B0BCC8051D9A88313A619B87BAAF7B16EC52808CA8CF9856CB09A58B71FD67FDB4B3A0B88536DC3EE689101CC39F7F0418E3CEA104C62E83DA5631998DE88562499C4D18A98A1DEAB254C74334C325C11EDA989F98548674C19CA942AA95CEBBAC2A593BE1A1595B702B701DD42E89C8E65DFF6E104053815FE2D7D0908CC2698D2B6C26FE981025691A1680727A0D65C37B0D87EAE23CDA4E6EE98F7A981B9CF44B6B2752AD2337E02CEE156BF8968174FBF7EB0574BB62434D69EDE82D49BE6DADB3510026559B7" + }, + { + "tcId": 53, + "deferred": false, + "seed": "9B54B9C91E0201251489E07D1442A42D0BF32189D0C0CA8A2D4871DB25F531FF", + "pk": "9C17C88109B6927D423D887BC2FC24A5C4405C8E736C1C9D9A799C5CC09DAC3BE947BB391590EBCFB93BC00F569874F69780502C80C4EDC87DC9378294EC3D62F584E70AA18C0F1139DAE97590D0C89CF57803A26FD82F264F2CF2A184B2DA47F44E22306B95879CB3A036C918B6166E1408E59D35E2177F6CBD05EBE6F1230FED71A3CA9CA73F3333070A1DF3FFCBBFF32F82EE2ED47285D8F05809240ED1F91873D3D817AF74CAA85BF78EF02EE9B36FF3BEADFEFC436001A219770927C1756A8FCD265721CC8CCD367C7B19A40DBA1C9DEE9611863BED506F42203AEA72EF21026307AF0602437BD5A8E7B1B1F1DED44C4A009E785BD170BC98C839753F076BF7ACFCF3DB89FACDDBE5F5CDDFF76931C0966CD935102FA75A967C67222D5F8DDF2412F0CEDFA4C9FD94C6C58F26BA4954D872229BEA543107613C71994652F9268EBF81862CE4DA0D172233D358823229618803AE54608871866DCE80B988BC82F702A8C16C9A6E58B465C39197432152297524CCB00338067CC08DA6E2AAC288AA9B3AC40493A454ACC7786D6A2F261E86F4FC6A341896C2E1B7EB46AD1E4F35D970B5B4FF1AE8F514F6C78BF27A40EC941DEC16C95D9D91F869B578BF37E5164EE77DB6D38F7E65D9E703C6323750C24C6B41BCA787AD02208421D3DB8D7090FD3D154D9561B9638BC20BD55EABDFBD0F772D590EADA34FADD191F4FCD80C4B0A9EBE8A069270B89FDC2F0C54C5E9D835951E76E4255B9AD8DEA2092E806D7C62BCD7800E175C93420D7D8E3806F2B6F325171A80C34F0EC7AE7C48CF4664BF07675B8C617FB7944795070E7B47EA9BE7509BEC0514439E9DE57E4C6A2A64303176D1BC37632DE696CA7A3785943E299A1B152AC93D1FC8EBD3A451FE780098A13A72F4EFB4A41131549038C38815687150DA19FB3DD1CB611B9196135606169090D426B33C0B267CCB630172BBBAA67ED2817227DBE6FCDE76CFEA14A17A36B034977559C9E8AA525052CBCDCB66E3410DF8D321F3992B02C3CA8FEF477F2E22ACD2B31A89D194CCFCB4C41F8FAB34128EDFF327C80022CB9E15FD41ADEEE69F227CFFD706312AEE2C824FD281D62C31C98B2306D08A39DEE41BFD1CC702E55EA718A0C265E116BE6B87678927373592B6438B7FD490B2810132579BDDCA4FBBCC0764DD245F6D4DDB97943F52A0FCD190C71744C2E6352F4D0D2121ABAB3870994E21D617A96D77C195436B291ECD15E9CD29C6E05617526FCD8F853C8CEF29CEC0549073D4AFF72CB975D3B6F4EC0BB0CEBA04E35E69E702D5E1C671424EDD6A6835E0E9FC9FCD7FF16B90B039BC1B1295F88F724AFC6DF5F70C22A6E7CD16315F5B7DBABEE28B7651EB16293E2F4998A4F4640EA6EFB4C0E8F51B7DF809CD8F53A4C18F4F4EEBDB18F3CE2DD37F12E0931A46B296158A82D6F4980ED9FC9316BFD7C519688C0C4BD22DDE4EED750EA96898481D7790B95907F3D7E9323EC42B59342A52616E288717B8DE4D5550DE95560EF33FAEB2E2A4D9641FD0630F487DB670B9490D8F91F4E2E9DDB7B6B2ED9DABAE448622DC60A5F869C96E12F1B26A77B42FD6F513E9F8C0D53BCB5610EFBAE271B754C735787E9FFC5FE8778E967D713C2C3CFBBAF59B2262F1C4B8C0499EA77CD587A5296A819955781AC371C20E66471CAE28C6B098A6D25216F5CC3F52A258EFD3E22B010DFB5971B5EB004ADEB9D34375B157EBDFD3331B6A9D56D8DADA55AC152C3AE497A36269F44F3180C47EB8C315BC3F3A0C8AA1CC062C487BD917FC3988AA468C63856277620F576CD6B70BA66D3F9377CF20452DD3E7A8890FFCF309D7E5FDE1B2ADB2BB6E96ED3E8F2CD1F075D82599B92F74602A87FE5506E25E2307FA48D0C171E61BE15E10C3EE42398D078EB42049D44B0A343915F3A99547E2E27DA86B6D0B88F9529613412FF6D6AD459F30C1BBAD521E99869F1F01EE7540407D645A7B6ABF590DBF180A85076CF838D89F0BD53CA96759CCD3F11726257FF862A565217B82068BEA4BE94215F0DB4775558FC6D97B7D4F3254A4D733E6604A003C804BD380D6046469E310AB9B07CFBB605A32DF6E1B15734F8C2580D792AE5AD45C13C37D90D893218FB7BC6A449161C0B91B2FE8197C81929EC8823942A2EA8F7C04A307249CD3295B6B529CC87041B6866E9F358B5EF30486D7CE9BB297FE73B2A0BF7FE5D4F7C56281DFF8CA46B5F1DA6A14A15EBE6F6D7DFC4327834E655CE52C310B6DD6D72A9D948A930A11FAA6E57A08A6FB873341A3F1211D0396884C07F785BF4531839AA77EEE2D5BD8D1B767602C01F6CA35FDB0F6A3967C367F88762FFF45A67A4E75C16F744B6E6FBECEDB03B346EBB18B1A35D0F2CF387277CE01F8068DC250E19F0E37FE36783C0D4FF4A1292577DE8F3E81CD769B2D22EAE286E75756ECF31E56B00A57DB2C17750909ED9959946C86E25112ACFAC5F526A331B5E49DECEDAF38EEFD5D5368A8539E49A0766C22CF5F713E6EE058E9BE157805A521FECC934987809B9C5190EBD0E709D1B2EBDB06F925F3203131171ABFE76684849C0A82EC8D66ACD60A24794BD39C18782506BC7F9F7DC6B1BC7EB2D70A3FD7AEF3DB81568C5F6513161D8DCF0B9383DD97207C186572449F7B55806FB564723729394C85291E01C5EC803D8FD2D702BD9F84BAC47E6E659A3FD90D04B4F53A01DEF302898D4EC430BEB2936C70B976355DC2A68D798EDE02F534872E369582E8B4DF771AA3FB15C2602F2487A21EE9DCA0C2ABA12ECBAB2C8B49939180C3E305336EACFDC339F502EC730B55E0FE4227415EDD151811D018FB34839DCDB684C9C8453F681916316DADB8BBB025A6B66DB0C6315C73D0654113CE37FAE29DA59A893C4C7F001DE15F0AE4B59C211EE59808021DC7CCFC2BC8B2C15214B783FC55E8C50A19ABEEC8093D82C3E12058B7023AE561384D9B28307EC60D004BE81512B0D03F02388FCC2878832C1F881251BBD73D3245336E12653445B6CD704A796A284A7A7F1F7F37DD9D22C2B2BE0D3C497E2F25CB95933D154199A32D4971965BE442C914ED7C42F28D33BBB61684AC719EA5F4D7FF7202E3D476519B3CA236A143B1DD22B34F479C0519531BBFF5E1E1D8330B231D588AEFB2BABEE0A1BED4A1D775C5BD5177A8CFDAF83E5B4CE662418D4A13FE34D3875E9EA15BAA45033CFD746673AB16FDE39F31BEF02051CFF7DC335C6B9DD8CBD17CA9B652F01AF2E3044FC3B1F15378A967F023DAB2AFC2CFA577B82DA875E1FAB014728BD7A8948859EE9619EE02DFC85859D28DAD6B8B2AA72F7973D6709D1DCB0C625084771F3EAA12D4B6D091E6E5026845F0C30FEED6BBACD4A9B5D623CA247CD6622D1E18590E5EF3FE9A094263E886E567BD1AFE24D7E263C5B2CDCF03D1FFE2DE85D7C81A7634066B30E0FF49B71234DB9441017954CB05B8BB72C11710A55041C737AD29A58B9EC6E2CD871B56976C389133F45EA4A6C39545AD15BAFD9863A333637F7AAD613BB82E61652A00BF90DB3FA1B4205198A42151DE6A3500F0A770AF589AB63C01299A28F94B9395D652866BDE7505BAD85DBB2B9D56E43D02F679F94B4F0DCDCAEC1487E18B89F96BA1F1890BCEA47E60FB0165092BA684F8381625F83C86FA90F006", + "sk": "9C17C88109B6927D423D887BC2FC24A5C4405C8E736C1C9D9A799C5CC09DAC3B0AC8866103C621D3464AF8A7E67C30C8FA7F66580CDABDB9E6848E611578D0E85F99D936F0B17CDDAD87C4107D0642F26EABDDE9732CE11AE78FACD7532C2868A1A29A6B5A0CDD35F4EA2F536DEB14A7146F4E94F723B69B976F4688FE8B5D22A0B281D1426D18144D1A066403A98808390E010241D32428233764A3C220190322C8C0405A9265C8B82813B789C9089211082AE4B464D018300031644A928812A52DC2280108C58559A86111270912080D4B384621B144994268C0062999228D01A511A2C46882928C24B70D81168ECA0465D920289442329CA00924356059348EC4C46D23C52123A425CA10921441240B424E02C94C6094318C082908260440046249304A21154002180DD282294CB051211406DB2480DA08012125661B96641819125B9649C9406C180004090380CA1210D0444EC2A271D822694B2091DB8251E0A00D0C9788D044091BB020C3C04024C7251849450AC84001164D1BA96960A691C2B2288284818BB44404B90C9C4206D8063198926098846589240800098209B349A0286CA3C428C1145198222919266109A208081152E082895CC06423A641C408721126321431122231700B15868A16426480311B156E023702DB4491A130804114200A119098142519A1519814264B422C0A878DD9386402B33080B25104B785D2120D11C44864A88DE2868D1C2090CA940D0C15500A188011870513988D94A265CB164D1486418B168C88002D14C680A39069989431514866C44286A304302449048C962C0312806124456312806182098B300699A65002942D08C44124C96C000546C2B6098C0025531872CC108C13A0458482080A972554C2886342859C3049CC18929AA82013220AC0282694367049A60850C850A0B22C60B220A4388D1A128008346190366C0094700A0912C8302C41B66859B669D4C2814226699A2404542442A3245203115123234801B2001AB24843B0615806890AB66811B5641230841AB88DDB280A2437645A262164340508075200B7689B988DCA164810B9440B8490E0A41011880494184013B500440060181469540050030864C40062512030C42200C9828900496CDC96404126051B87245036495006029116449A105213A62C528224214690D4364D24014044B628D8264AD0A26C82288AD4C66920A36C49A40440068E63B405141168E0264008884419158C19C62994966110868041C43108458949B030A102851990041A166A8AB631C33085DA1672E2028E119711E128810C8388D21200CA164419C52544468D1134615C946DC0485154808C9C045153040E09380D110248D814880B88719CC60C64142812854801938DD894890284258312698BA828C2A690D4264504B57120468D21462E410241A3C0082030028B442C02264849024D530065CA24465904460A290E11A460D0A020D1140D130185D4B829494684989081DB2290D9B011C4460209182C63484E4314001CA24450B20CE0C48C09C98C8AA28011B06058C20914B9208C384CA0A49124271223112C63807102B31048866DE0882D03488C61A4895C241143282541409118286D54261191B82CD82069A4A229E4304153A20D08C1400182694A440948222D6304066434212490648006418AA40DD094690043819216649408486094715CA24D61248018B8814194200AC650E1468A4CA65192822844140D4B2006CCC84D1C3460D04069208641C4C66DDA904880A2111BB44CC4926DA1B0080C11724C204C93406111494258948920388C89982504A68813412699B6458C148060288A032402A442658AA82C1AC5412288705C882114A78C0A447241402C88180012B48C4BA8640A934CE184400A984DE13070E08404230900CA326249846400378492B08141A629C20621DB162409B74DD9A28D1A8208A3388483B60C8A824D20B48C4BC82C8100640BC4850A054E84B04CC1204C503851131305CBA210040002CCB660DAA8084AA091121121612401D016920CC950849804DC803081A465C986301803321BA1681AC904D9062C042149CB480EA11088D00802E01086D9346C22850C9B420A122948DB0089CB3088D9940891343294C8051B940420226010849114A58CD9341101355020C361A31682630231CC3881DBA809149349038948134210A304094A2688956D861BEC7549AE8CB7B5AACD88780F7B1D1597FA1BE27973CE28C4C0E9F35194AD0E2DF62E622B75E06E7E21AF5FDF3E4908FBA7D0B657FCE0A512FBF13D3C83F16CD3BE385BA075CEE26E68A28502C3C097539430E8F19916B44E53AA7742910B719CF4969D5EE2D246F5CA207AEFEB037E7CCD592094DDB72621C5937813A5B324ED4544200460F4EA7744DECC6D182A604C142D6212EB6F9F90B1AEA0F89EC07D9C083EBE1FD78D3C4C2282E1D5BA47064E8DFE71ED9A7FD7C0F95481F3CF0610CEA3FAD5C4E73789C70AF963A1DFA6DA9DF610BB98630EB4419399AFD1412E0693E33BD24381050FF62883D65150AB1DD0C67F443E5FD247412DB729D2E58453C770F934C475B89B458111DC6268F1CA0E9D143E7F0570D22AB5B7BD9446BFC7DEA9F06383FE1A0BD9E644CAF2B91AC44BFD37DEDAB4237990A3AD448715940001EA30E7219172B64D86E85C1FCA8DFA922B61819BB4BB68FFD44970FFD9CBD6BD2F09FB12E5265A5B0F919F6D4D6D06534FFE792CDF6882DA5D4557B51AAAF3A80A8CEA69E8678E66D1F47592BFF128EAAEBF38C70E8FF7AD31035DA28AF239FE245D2FDD4F853029A65399D5E6B6F4F4CA2D862B62AAEC8EFCC4B05DDCB351DFAAF1F7E7ADD9AF9FF44D2E2A384368200217F48DA0DF5013BECD2462D4BED2359FE44D9612EC6505A76071E116AB5F0F1DE88288DBE97A8B0EA32B9A6FC53695972A8F6B33542457C30C553DE91B118B15A6DB2D3F56FB0CCA91DF79741AF737E88A88A69424F7192EAFB981DF8256989189D75E0C7183E3ADA99CED3913ED35DF5AB82C8FD07D7B67DAB7EF443DF51D82FE87F8CAE103713F88E9B73F649B1D3C8589B71F06517B18502CB230EC27150C072D985A98790DBE1F83BD59421D19CC9E23D845C50CEA8515690944950809CF95FA636AB3509AFA1A7ACD2F6C346CD76362D15907764749F3E16C8BC84186E1FC9FA120F49859F7E4E6C75F7CE19C9C129C72A7CA129D10AD8EB9650DDB304F5F02FD7257DD8D71B97BD9ED47B9111236E3B706AE4800401B77E1E5A541E44DC1D686234884A5F910AAF16C8D23E593A307DA8F1180095D7A707566E9CBB125751499D748A7E1A78108B93DCFC165D2906A1DD9AAE8C5BCFCFD1D5879A8E30B6FC3EE38F470428E8455162261E7FB6F8D5BE329C0FD494492C296DC8A78128478F88BD6E1B2CBBD731ADB947300A82DE410B27C87180032AFBADEFF276BFDC0072179E36053A3F4C031FC2F94116938EF7B2A02CDED2C4C101AC0CBF0F0404BF9246F1E4B71EE2EA0569BA6478C4929DE40C56B075432203D8CD2C0EFAE663001CCB0947CA073C0301A3896793F7FDD0248F7CB4CDB184408FFA24AC8016716A7C40572731CC95DF6954A94BD2E507FCF71A8E250124E29313ACD6AED2EBBCB36ED59F102F706D5E1B79DC3D956F46997B4172C7FE20F550CFA0F1508312CAD73AAE7AC30BADFDE7D2A8B2ACEEA2FC564354276AB61A8F2D6A3CE5D43A5E6496894B66E72DA30370692421D267F04430397C3B9293F7EB11C107C2D2BB007EAB932BF25CA65D050CD061D3653BC1B25B5AFDAD7A9EA9352718CB9584615D8670CC61D7C165D778EB2766930470AC115F488C3767A6B80D987EBEA29839642720275E20602ADD280FFEF51005BE2AFFA3F69BCDC69C7C40FBDB9F8AB2C57E8745A9CA2124FFC3E088B5564C088B71847A2AA574A4251C1F5ED3F02E22A85BFB1AD2B137477439D4BAA4DAB63644A44C0CB121478A2D91E2B7B9D6CD02968EEADCB51BC5450ACAAA81EF9C1A05B475DF46C4D6603C371D6AE3A1E777A789E7205EF7AC574753F60493B81F8E0AD527A6A561F5C1723EB7E9AC1D82658C00F1CC538DD8E5552366FC9A34D0EEE1EEB9C4228C58D2D7132E3599686930BE56B9A59097B2238AC49FF4F6A9F893FBA76F511C6A6126686C0BB6CB946B0D3CF7DAFAC886BEC911564332E773C10ADFFAD490B94EC6545DF90CD12695E79936A7CE77E66C3F2781F6606874BD2E1379A8610B0BEEEF465334A455DC2887D8B35066B496856A5500AE079178EDD320A7AD2F0D350B0B3E78EA658787AD5F4CDD224340E93A06996904F9D5EA21219B871E21DD3BF7BD3BAD750048702059C86584B0E8B4EFB144503609D021C1DBD98F04C84BCE4304C834BB502CBA56A6AAFEAE643F76FBE439033D13F5FC93D8D852710C3CCA4E2507CAE51BB8779C622AE8197CAB5E51C9D11BD38BE4145CE12BFDA8F8B9ADAD8D8033D38143C92ACA69D5F72ADACB8D6BD10D427726D0F51AB7114A174E5187B8F9D114C2F4FB768EA80F74A49CCC642F5DBB7CEF2DAC669E250451CB9AD8EB2A7631E6884934E2A25FD710F3E47726D7709BC89800C6376158917026C299CDF76976624AB877136A19ECEBBBC1C36DE60EBB3CCBD43508EE6CCA750960543C16A0EA3676CAD076DC3464517FBB3B2D929AB2FA80FC0B31BF2026E4FFDBD2C20D2DBB8FA09BD88CB4B3CC124CE260BEDA345EE0232B2034AAE1E1918365878D4A0BA98CD4D7011014FF7569CDE130389A7D59E860AEF59BEB4F4D3259C1B092E68FF8AF679327F4181F6476D54D933B7EA376B1D4C0564D204CBE631C4AD3DB45F3A7CB894AB139BDEEFBAFB6EDDEF0DF6F7FD5EF140882E21CE59AC45417686DF7CA38AC90A7B44DDBE0F085CC397B3B65E6D2524CB2A6D4AE4BC69911CFE84465C9D6B697D28D84C8C28EF60ED5BC34B0EABDAE529CFF3C00F0C706584C48B565CC060A80F6DDB0DAD0799B8907E94B0C29A4E7A8D6CF0C5750DA5EB717B30341352E6046420C7A226A1935BB7F0D25E4067E30B527A55BF410B4335063ABC9BC76A5D885882AF728AD934BC7E55553B9ECA69D97311EB3CFB1DBC28891D3DBD954084E911DCBEEC1056C502385C8EDA9B4ABB93E623132084C5950FCD44725BDB70C9B9187A30DF477E128F143D870A7F02E5D2F20A3F1B034FA05475F58D98A6D8C22FFC0ED3792A1A2DDF00F62CC03CA04060BCA60EBB9CC27C2BB6636BBA116CFD03BB196D85DEEFFE0C2D6359129FE1877F723EA225FEB1E995A34B9A3A75D1E6C0786590E159CDD62B39D084AA5BD2EBC4456E694054922D4FBCBD5335F7F8448ACA08E650D296D45F3511365B5304F1359EEC32E4616C166F938F2F36C790BD577402C4A605149A4B4F8E1A101E97E22AEACFA89273B3C1824B42B0019AFE8C4ED8B7F6A265573E11AF026464BFB2C78532C0AC303EB5D36D88CC33F528E56310300D52481BBB27B7F8C523DC036B2D1A36C002B98BF5F58B4254D097DF7912D4189287A14D7AC1A30691BCB53FB9E86056852075B7278E4A50F76EBABC11761BFC5D2A86B5995B1CAAFCCE5F5B3BA2C195B692743B637E424AD4072C4B5DC6BE4A3DE4E041E72C64FFB9AF9C66353C5BB2A3967830B9CFC9AE5C632A14BB32797BCEC4A595D8761524026F13D237B165CA4240D4972287ABE72AC7F419F37E99047F17D5D9DB57C508AA0730D6D9D2049E19B1EB3C7EFEF2EE719047A777FD281A0960C09BD79443C5891AD8BCB1ED643B9A9F1E66FB5C7EC6DB926CD73DDFF4D39B15E386AD92170C4F678A7BD7FD6EFD600FE082A64AD91E2EDC675DF911B531074660096E85C66005318A3B85CF7E1C5D269C5BAE4096C9E05145C01C9A6294A50B3D4707A93254B0CDAFAB7B0ED1CA6CCB3DDC1FAA5304055C41095C503DD79F86A499F292C473C3B975DBBE53216C85D42E3E5A819E1A947639131CA18CA7831091D64FECA2713B8BA5577BB6B7FFAB6D376856A4D38856651EBF90929784436EE1F09EC9C99A2BE601294AC1C7ADBBC0EB050BC3F728D5D0F3D4831BA4DEE0E4674EBA6C2D26944029B8BBF90891C37A69DE342EC829625544A82C3FD8F61DBC40ECCC6527E06C26868B33BA362FE4E85FD8F76132E9065F6FA1DE7FC0CBB92A3306534AE9FA01256B24ECC2C63854D3F46284D0EFFEE19CE5B7998DD8DCEB38FEFEF074EF35A3748A9E44AB4F75F656FD08866DDC4F58252B25A0232180E8DB2CE8D346A558B03DD71B19D81E5B23BA688099DDAE1D10BF52932FD2EBD360E653BD4C3A254FA4B71F2859757FB024B14356BC00DD2877AF29BB57ACD812C22119F8CB62BA81C946C36B0D4CBE3A1B4810FFB27A47096108AAD74A5A0413D2A1B85286569853AC230BE9E34C78C84FE0F6269685878AA1246A55F37842584EE302301941B9A6CFB8BB4ABFBF3DAE55AD8ABF6CD6CD7B2C881DF7D5DC264A5F61584A990A8D1CCCE1C0CC05881B4358494283964EEFA16E9A47586FB9ECE3B39777DC6C1DE6931C5448C0AE2D6C51924D7F6BFBCBAF485F0F22FA2228A162C13240EB64C050F2EC800E937FA97C77E2854693A4CC83E1773EBA74CAD800F4AC6CE461C9693005BE0B3C288EF1898900466318B96AD247139E5E8D8CCCAEDD20719275E102F50F1CA019692642092CBCB21210EAE0DB708D96E50FF249E6918A628B7834BE30349EDBA515A46B0229E6E7AB1A88C25A7F6A3BDFA84EAAFCB52AA1A143FB09DF7CBF6E39FE1B813AD64FA786155C298D9483C2F9B39CF46F936AF6B95E3BA82356D7C99EDEE47CA00C3DF9A80E8DE0F246C5DE4FEB6C55B457A59CD82AFF7A60E3100D409E3EEBF2E695DD3D047CE2B35D3820AA8D4D7692C299C00B78EE7BA40DE61560CDE3FA77BE3AE68E" + }, + { + "tcId": 54, + "deferred": false, + "seed": "A5B67695D7DBBD6A7B25146E30DC3F577240AED2E4E20158D1E24143698D1178", + "pk": "E7DF05EB34DCC34DCF645BD3E04C7B55D12FB65E508F4B2FFD3EAC19A060BF01B627A36252963C5562CE2AEDC3FC4916914049A29F8C76CD6C52BAAF00A7A4EC403786746B5B4496F0288F9E3F8C6A9927FCB787B53860FD3C5604CB0C0BDC8E62FDDF2B331260AE7F949B77769407A49DC31B2DC7301A39092E0D33C511B7A51AF129C482989ADD0097F5A66E9D5AE2E477A0BADB20105E1629E8AB6730D5BC3E889C7802AFE8439DE26DBE2D7F4A58ED8C9566202690719E286E92CBE0C7CF65749EE602B6E31DE6E6CED9A84AF50790611D383202CE6D01A83032842084163182FFD6B6E901EC74D36AAAC5896BE92833EBB7E3EB266D11A342E0297CC492833DC8B850123AD4C33C60924C402FADF0D392166B3620F906189187BA9D761EEC3226C43F698F2D5F6310357355166FCBDB45EECF917D0E3D0766C5EBC748B58DB09B515529DD320957374CEEB807A2BB38C9511C2CD0AE6462162E2CD28E1513B87973561D5BB9E3FF260F64F9EB2E1B9A1FDBCBE4C9134E3745000ED804C2A3A55D769C6FCBE947D9557E5EC2EB08E9D416FD7345EA46547649E936A51CE643D9518B595AF4E2BD75ECE8D2E04D4A0840C8E8516E25A797C0E9A93FE8B8D31DD314BD271410C85A0CB6755C1FAF225D0CB4B8672CFD6459E65B4F071A9C5A802646F1660F8FC24BA57199DE9257AFEE8C8BA7D6256BDE7E6EF090B5DF3A549856D95C0FAF20CAAA31D07A980A76E638B122BCA0EBDA0820B9779C5524F8A6D2048B4285DEE77A755DF9142E03BD78D2DD07F62894D169F21BFD8798F5F5FB0CF73D7D14BE1536749C0EFB447C253F1ACF93081DBD309BDF7C3DE11A1414A00914A82C0EA649232470B3714E39378FAF4C7178384BF7EBD5E793645EB4D11DDCF00454E62F95C7C6338C8AEE320754DA40AA48F8FA227C5C22775F0D665DB438B7950F7E5CB69743888C5A41331D78605BC5069E273DA0083603578D43D696F54EC21BB61394C5DE4115F1D3531105C5D3047BB102452871CBAC4D78DFB3AFEC545999EBC8BEE5F818DFE0AC009FC62D4B752CCA004EAF4B07FDA82B3DBD3AFA9C65E43EC7AD116BB3BA07F14B2074E34DAB889FF6B9A48541ABBF8B556BD5E16F0AE9BD303AB1224234A0938EFF04D524F146DB003A684C781569C3014D7714A124AB667CEB521A3F6AC60FBA8F5CB620311F4899D922596423EEEB10E8BF9D8CD3CA609469CED630436DF478D959368D0F175E88E5A563556B3628DC43A2D0AE9BDE3431DCD968C1F2A5C7BBA792F86CEC0E3BCC0DF797C128AA551B1383505DD6ECDBE11B086F11DA4A933D9AD88DDBC444DAD18DE114AB44D5512A5341C089A496DE50157232F67438F8B99650436DDC8C4837E2FBA469180C84F2B36D0B4C85BB9E38862306719DB53DE9F30689BA76B42BBD0881084E0C8732023E1C83B41AB9132A7D64332618B7E6E4B084AC61AF78035CACE0FD16D1E586F79FF97810111CD7C73215655ACE992EF34EA6EEBB64F2A392612DFFA868E8430905DCDDE0A3C16B33DAA6A75DBC5FD6421EA72DE15325E05C07FA81E6D71C49CC41489F1BA0B9B95CBCB8A8A8C7A84F47F8823C6C3D3A57FAC5565B805E6E61B1F5E46CADCCBF8F2A33A3C1535FAC6862E996592CB6DED121F5CED4DC2FD06079BCF23747991DCA6ABE74519F59A39DDEF6E3802411FAEA858FC6C7CF7D90351A17C7CE3DFDB3F870C21CAE3149E04B0BD138233DA4EF3FCC1714683181300A01EF5AF0BEC3AD30160F11BD031F950DAC48DC43618A08D3BAB7E36190951F0E4F2892AC5FADCD872C4D1E2E878D65051138AEA899108E16199F9B3D134271B52E316AF09B7578C5ED66BE73DB9D0E68A0553CAE44F68E3E13DC3497680E742204B8F44996C916522C86B44F313DDB26B73B8B049D6FA8EB13784B2E4062FF47FB3CE7CC046C3BE30BE98E242960D7C81B68ACB705A2714DC73916F41156E43015B69C0687C336963DEFD66F56DB93C58F3CB2F075579FEDD47E1185AC5A7586A038C2135EAE0F2F86C6F8F6AFB6650A351ACB622ADFBF2B1D991A12EB7EE3C2DACA56AB6B200E64E0D1F81CC98D0181102477B87D4BF3CDE84EB42C2BA59BBDFDE06C9BE229FE207D9865C941D9D3FD239EDD161FCD62FE98C096435A01F56A5FB73A703778044480B706AA6D0B70CA8DDA70FAA87E63B718CC92A00765AF46BF3983D6D0B4A6B134F4E4D7BE7AE06792429DEF01D28D61B17207956786C0B008262DD4C6A759F497A8DDBCD821DDE864458EF445B4A9E836200525149982BF2A76CC10B8D571187A9E63C36221AF169F6B61E561783F90DBC461D53A05F54E4F0BA20C5F25B85170E680843E484494497F65001722DAF1083C96D7689CE83BC727B27A9E162D32872D1732F64816FA45AAABA864A47D46492A5BEBD45D4E7D5EE5AF5163CFED4B439A03AE80FED99D5977745B56AF125DB2FCED60CB48C4F3FA1B8C7ADB43229BF9CFABD05BCEA82B4B0CC543C45310D2E11ECA9998FD2250C1430F6AA44824484F857FF95BD99550259A8D680D471131ACE5E8C56F5DF7150B2A25144387CEE08FE6237F72618076554BF662504B565204BABA2698EB4F2F7FAF673057FDBDFF119F8BB6B1D394B28A4D87148C1AC976C842E563CFA16C0B7900B162B084A23775F7E961C25A7C50990BB10EC2C46A986B991758DC28EBE9572C1795CBAE8BDB623C7314EF4BE3DFC62E827E3A1E61DD4F9B245D1916AE9A2802311685189DBDBA7ADA866BD2F81B4B5FA49FF8D16C3BCBA223B94D3C52832BED1BBD87753944B3AAF1108FBF3DBAF9367F5FE18E958AE66F1EFDC9A71E7CFBB81F4E88AD8E37E97A407967B3EA89ADFD6FD9D2CD95A6500B39777EF946904A15241399D596BEAF23E41BCCEFCAC92795CDC8B7F6E5E2657BDEFB3FA24349D0E10B03B6AB6C24A5D8260E227755713C3E57D1B5AFCE8F1067D1EF1D93232D59A545EDA53C1FF692668985FABEA4192A6C4B11AB02CF89B64B564958AC4D237C1B739217008201897F93352AAC793A7A1C7511B5ABFA83B0C040922069D71CB1071516333112730AAC7210F3C74B2D45D80B6530147C24E2D9893D5CA662405D70F5D91D5CEF7AE93BA7025B2FD907A86125E68E50A01F34458F318444C643D0DD307CE5B59F12E4B54382D9EED313DC725CA4C553F56A1CC943A5FEE6A5EFEADAFC2ADE956C6FA6FDC0468BB0513DD7301B87F8276029C677FBF38D0A7AEEE19B8423A7DD9A2FF85AD6FEE2978044EB0A31CAC6B74F20F8F379E1E46BC1414837AE5780F31D21AF710914A559D5744457D2F831EFB1ACB39DB7B3E4B126357266DBA8776BCBC8AD39C8E7D7EC6574541CC669DD38AA5C8F61D90DED5F84D662CE2E7292305304D139E65997020579D6CC60C24356223DA1E1AB33C51BDD14A619F8AF8F646DBCD319AECA9AD9C0292FCAB1BD5393122D2C9E23DF817C9971BB81E3887D25D9652BC0BC34D3E11B87226F08C997052D2A3E96FE7BD4C70EDB0837049C51A50C77EDBAEBB842847EA248B1356B1647C7E1ABE36E992B5757723F1116848C52EDC61E21A274A27A94E25037BB0E949C7BF6E01757E283CFB9DDB647989BB473631D7D2B6A421E0BA8F24CE4CFDDC175D69846535879872D99FCB91DF3", + "sk": "E7DF05EB34DCC34DCF645BD3E04C7B55D12FB65E508F4B2FFD3EAC19A060BF014AF666446690104A56370BD7F6719BF71E367577A2A1848656792C8BFB5AE2E1CAAF65980284F4E23A19D6DC9A160480283E3072E9FDA05C6B1F920D405C7C96F4D0D1E111C9CF5715903931D93ADD0A029C126C3EA29CC48B1BE330CD6866568CC43142162101C46D6444860189451CA730C2186C83162511290DC3242858B4400C9030D4904913440688402DD9860501142462061082108E94A0651A374D0C1801A3167051248062C6451B332419C3684B4069121804C4283161223240202D90226C9A2608DB4421E2280A23B98C22472521A124D2A850E48665A1402860944D60382298348622816CD2882120226DDA048490442E8CA01198B00C03B901CA282258968011056948347011468C1911008B204293280861A465C24011C49861A3342058184119A1504B28698A360EA09230D9C0911CB12549226198928D84A288123612948468992212E4364941A40812C26194142162222E4B202D44344013312E420425A2A0805C82684A100CD9C2891A452D8C04691A436520144513C85102A0100B076042B26CE10484C9020260385053342D0C428853B86404486691820DA1302E58186261322D13C44992B0499A442CC3202E53B4890AB14CE19050DB400CE4922423C58901934413C389432620C2A2309A1849218909220541093989DA968409498A4C2471E4260A6432261323201B016602243261366402323000C6890018481CB60DC2480A2206068A10451A2441D0240EC104281A892D83907049084E1997058046921CA8611389290A20322180610A022D5902062311612417709C926DDA06516022000A098553168220274DC2C689C822280C152C1086011385510B996804029262000180C0841A0024D408710999281C902DD2062E00B68CE010921A050201826D52388C232829A148728BA24021859000030422C009144244CAA0441A030993186EC8226CCA106600160E522890E04812A3282EDB9484D0B21013B56D19325210474501327111142102068018C288D1189251268DC2464ED002524A98258940920A280400A00C8A465109B041D02066D40805100208D0B85091386D24418D0840040A448994444C8318318188898946284806414A484C93864CA11489041664C430229A4061D814865C4681211749D1800403956141426D23456ACA203012944D8C480058A28D23C404C8360C2384294C80681A2400A2C81103070518B0205410328B246819C625D4168A92C4601A32218318049B382841B611A3A00148402C19B284020306128529A198090CC78D98C45181882848169141B48CE4160514874D649281D1B804E432020CB201C086009B045053301181B641A2A24C22B40101455082168DC884706046660AB1015C2090DB1872C4347122902962180C89A65043881104386C50148A02828480104183B28402317154B6304AA43118890011404E23476023182E94426683A6481C0670522082E4A82D54A2419422720B1562121086DCC62912114CE3A070D01260A4B62D23114AD8B24D032668D14649642610DC8280DA286882244922048113934D998408CA268A90106C50880100B82522904943006E10298182B641481460901605E0B86D92B04101949102C460A39070E2B291A384209318640A8700C4948590268214C749A1086C110924A12041E0202E43124CA4008092960C139930C33664894281191880530444082949DA92298A088980B021DA126A88C44C22808521A1250C103213026190260D0B29405B488852B22C0080400025846384415A908D1B314D93380A10B1301B398241120D0B0650E2420ED88689C8A0858142841C382412328203C261DC406822910D9A424E94108988082823936512C8916020220126259B84200C05845A344D1C316203946101908192324694462DE0125041320021C970D40065124522608670A4280A4BB02D82C8299B122919B14184A82922C02464C00124060A89148A01C80820C620E4184282B68DC0A86D61A461A3240090826110203042266521444EC2B610C1B48D838411E4266E5002884040491935320BB24CDAA011E1A64522B251C3868164B82CA0B0504092499C80819B348859925183C28D14B48021B5506032410AA16C004209C0062CC2A290E430011C090A214968D4162C0A1085123244C7F415C457066B406B020246804A5CFB387AF746CDE5026AA81A7110CAC17CD438C4054028B3EA5C703646EF389AE1D9A81D6BA2E708F058E4A7A5BDE33563F88B33A72941DCB16794220455B1DA8169E387D521C0A8D2F2D08B030B500193A27E2140EB59D11B2C9115379B45FA7630DEB827E6B0850626819DEF3A85E9479C2B1434E3C39ABA253E56BD1C500772D90A2402BD89A525CBCE62E45F7D213A59E0C61BC98DB7283E3711E449AC5DA6CBDA9E140FE91112EF9728DB78535269F77F38028BF65B9CEF282EBB8ED0D6D16C23F78C2FE6A1B9D6BE06A7D42D003991536BDBA3C9F28221A993D487678DB5747DD4ECA2EF7D0CA9D8CC235192A3666DA395EB597E37B16C5F32F68E2F557DB7C77F0101DE84843A12925D6C3D76F0412B9DA765967D4B2917013CEA751F38EAB0FAC3D8ACFFCC272AC82ABFA37DC339FA4A6D3D36560196B1F3DD59BFC5E078B998C2BDAAE167C4C80FEB38ECD4D7CB9ED838ABBD6D7A093D9B3EA10AE51B6C1C54F84082D1EF05AC2E0841784AAF4F6FC997E43E3FECD50BB333703382048F5C415886AAF3C95A5C1351938B496E8FE0B10F1808BEB61921B0916097BF09BF64D1B263FFA7031AAAA99269C0C5CCBDA0ABCB9D341E87BCE1F3FB0FE594AB152CBEFC3EF60925F95D1112B8078EB30E616C22E05BA9CD77CD5A67301AAAB35157232E7C9DE936FA6D43722CAC883EE29E52EC8D7F4B95CC17E2EE860FA4591550C1E01CC78577B337BD1D8BFE84DD8B95982EED0E023703F242602645672886BC03C4AD2FF64815C916EBE6A33A282E440D9012E70A630DCA4CEE5C65AF2A880B54CBDB44923FBC20B2F5FEAF1C2D9092308E930C3B044F2784902D8AB7A3F65536226180C75B33B236BE642C00F00C94108FAAC067D4E1DE83203CFCF316849EED95DB2ED332A645BCCBF648FC93C895FDBDD4368E4089A5C07BA22B17EC08548925F53B73D021C5CD2A5D0656AA67762C16CB6D5413A6F7168C527E85688FFB064659C7A048D7D7EA0263C275E0E1B3260789A58060895A8B907B2FC200EE8F559443FBF7434D42C35D6E2208FCED553FA75EB4029B95E2C0B3BA401240F2050E3888D9738A5C9F3557243C39D1C133FEBBCB9E08B2D8E7247A2EB1065F4415170D74E74817AED0E26303D38890A8F733D4627ABF548834F74DAFE9468AA3A31045B540449549C617CD8E674E608169EA321B6BA7925DA5CC3AF9FBA32B3C6F73E41C8DC1A8F2F59FC7A266E0009EA2A478C9015FD7DCC160AC6E25A36502F0575A28B6FB60ACB4AEE2B4DD8BD6B058CE9F230E541D6E0EF35A403252736012AB28AD15FD5034D3D388E627EF590840B486FC7665E4360CFDB03FBB01C9C65F2E6788D7E0145598DDA606A24E69C6A6542702FBD214085961532211713D71CFF0AC5BA3AAA2E97B11C7A9929BFE7E050393E126E94E8746ABEE2FC812356A4A442D3B9B18FAC0AC475A3F10A0E614866B113A457293BBDAAF7A5E69D438C411660A99672BBB8D8C1EC1C25138F5003F3CDCA247C34D56E6B6A3A36F9DDA05E64961D4893B51537D61C78044B3C29691F907EAD4E24508F75FA50162B00F0C599E461FA88BC622D6F1DB60163C19B4D1CFBD773D29DF49BEEFCE2E13748AEA33DD426C2EDEBC38F7E3DD6F1140FC79D5B42A96262E8028F8515D2C2B698B5670E658D9D7A1807507DA6F55902CA9745631E0FA7A85842A7D834A236708E09B390A4EB06E43B2978120A8D8EB31351EE66085D11990780E2641A8825C9D55684E1DCB887AF400F70C2006CD6760D5154DC0F3071750B3E547889D4B9A8617A94345BD754082726C381EA0494409A12CB1B1F38DAFDD05C2AB37505C3AA2584CE613866F3540931E341F5CD65A25ACE0B3B0204A09B1B094A8A502A92B7D4006657309611D601CDFEFAC3D748B27030351E5841E4E4C26D7EE937322BA7B33CE13960C3ABB665D14D7329AEBA2F5793AC65CE83D3CEAED892E402178B448654E367823E62F858F2AFE39795CB33DE23688F97793D94D45DF6868CB401E8278CF88149505D9439C9D9102DB9FA43205DC9C9EE056ACCFF52E240E00144C4B39987BE1F7C1D4BD1EC8CC0548D55121CED6ECF8F3E8AEC28762AEDCA7AF154806950ABC2E62C2FB91EE9518F847E4E4923A92EC23A5D67930DB82BCC8AC9F75028E071A226AA2E04A384698FA19A7E05CB1D1F96BD2EE8E3D2DF43BBB071BFB916C22E2A7874372BEF00898B5A49E1BFE2F670259AE8531DB29A717D26E45C3E70CDC7EAC1FD9B4B299ACA741AFBE1E9FED276AFA2BE5A26F7915EAD4160DB608E4927D7EF20B27ED2EA11D0778A784C16771BCB8DA8309162BF023B0F1084ECE6E1F9B54C7FB02534A721F9790392B3CC1BC4A45D55AE8BF40D041451C97CB68B0CD5AC0F99FE8C5B29B8067A0B831A4C1F01CD36B3736C3DBB36EF1375DBDEA234AF41C697C9B1DB05896EE7F7C5DFCFCE2D50236972A57DCA809796D911A174E2D3E9919DA93A324AC4BC87C0A6E9E7E67068D9908BA87DD5C501F46A712F8DF069451C6CB0202BFA81BE9C7EB139BBAE81BC34A057FB48BA38D0A17BE7D41E5DCC429C89543EE5E907B18BC6BC605EDE5061CE12D98D8C1C7675851D3DA2304A2C9666BFEC43C52BB16921DA67DB8D6BFE253FF14921588B596D470FE7B0FADA80C495B54B134A22F88B3E2928C82D63A06CEFC4FBA8205DD726C5F6F69212BCABC83DD0E30B15A20F3958ADD691BA2587A54D5927339786309A7E547F3173DCB861FC697E7904158BF9EEF3F9326B39562670E73F59FA2B9D851FDF775580CD2A0613F07C837095E71BD65EF43290DC39F202B16993E0A78DDBEE6C2D18C561729354E0B820E7375284CAF9B684B252415CECD9F472B3E57A552CBBD9544048DD45781BCE46C3438837AE9648F76CD428854A52FDC237B4CE44D9DCA477A91514932D2634E8E7888D3AEF0440952674632F1ECA2A51D0E7412A25EF12DA34AB2A3C00C0EE546B34450CBEF5B5B420E3D9D27DD8C17FF907CBF57042BA694BC8259395787857AB435F5813102D862E2BA6F653F01776BC2E0F0FD7060FB36C1AFCC21A64624360D19BA9EBB8E3E780CAD1785ABBD8843D472BB30D91173422360336FF44195765B755790280D8D29FEE9729F5444A3BF960B487F0B351E0A3D340FA4EC6E6900F91BB980144273757662CDB2F21C976D1607095848323C9AA30F6AEC830F9B4E568CE46F2B56147DBE0C676A81A8C5BF36AC0A8A21FCCC19E3C44F1AB7D73B2901FD68B1D475D9F492B540F7BF903B643BB536BD26C858EE493502B01DED2AA4C2564C561C0E87049631919E5BBA3CDD2A805A0F79BA9F40B2C8DEE61DCAA4975935052EACC9663DD1E4FB3A9B62C84922016F791EA8CE13789BE56DEB2AB36D187427C860A4E7507D0A8ABB54D52EAD11BF3835578D52C775DAA5112D2392D0C991ED55913139AA026CAB18472458EF7BE5C29992F6A6727D5800980439AD002C1D5D78FDBAB8D7C10B3F9F370D7B152013B128AB2A9E896A1C7E91292B78D3EA1C5E74CF23638EFA30251A5335AACD939B2A562192165AB3CD509FA7855318A52F9A312DC17A52BFF12CE382D878725C5742AEE4B7B34C80E587A05E4D19EDBD180C661CC89953D32B18F19DD0608DD65D415AA9B51B08687F61E73A8F204E55BF61FFDD5EF25C5EFD9A5332E9D81D70383FDF6A137E5B0F816E003079E266A89E40CE0BC721470142DC86E23646F9C14233332369CF3AD37C879C64C905DCB3430A2921FD9421560F2CF8FF0A819F5299938660432BB60CADB0A626761236294FD3E6BBE5D75265E20821BA874679417D92A17078F8A869733AD88F15329982FE21EA39FF935F1E458A8874EBCF16B79CF400E2A252E5D05F61B1C1B1238BD48E256D65F1786B4E2969816C0FBD38A1269AD423D33EEF3E46093555129F4F1E8B79631270F562E1B8C396B5E8CFE71096A174237C8DCEFB2A577495E777FF7BDF8177B4C2397ED36113769A39BB41EB7710DE471FD2D36324D3A3F8320E4F1BF34DF5108520C4D61B0FE7DD7CF5E396757B1FEB791043A6188BC5DCFF3522D80A5AE3D7C1E65B7B419B86A3853F7089F93B7C42976F252C23F0262A681C8C3BDD6FF91E36DCBAD1BF28416F4B7A458538B778F645C22EE027998E09B5824F3057453F2BCA68066615286D430589EAC58BA8F0BFA78263B37E0C3EAB69BC8E8C1E5DACAA84FADC7FADB2D23BC8A24B949FC23CB65668A8D562F03C7DC70BD3C5BA42D83907199B026A2A09758268122CAB97E4C892344F4AAFD0E46356D6FA535C8A89A90ACA4A72E24E27998D16EE58716BC7BACCFD99BC293D029BC976C54230A321184B529D588EE131274102C74A22FAF4AFD3453BF40FC475970D4D6C0AEBD9D219EF8E57FB0B5F9C82B09838D8E24B7B30943027BDE7FB5C9CAAB2C8B1939CC7870F4EBF0B6B68261027B282FD7E6A200601D3E039E6771B8F2CD009A466145AB437A6243F73B1036C786F9F6038D0190C29570830A3B67D418A78311487795E5B47ADDA457D89626D03EF3150A20C6AAD1761E3DD47B51F5BAC74134454EDE11F443CCCB5F8161EB366D4DD6ED93F78D92FFC147F9F793510D799C927630939DD0C2BC565737BC1DEFCBDE3DBD246955B1BE65319673C2745C88618C78D6BBFDE1D4D400D" + }, + { + "tcId": 55, + "deferred": false, + "seed": "1B87631F6ECC4BC8FFD14B2792F3D1691A46C22A26BBC98DEB2554D7FD2522AB", + "pk": "B689F9AC3F5C158C92A7E8B562670CA310EE4CA3CDB9D9D7F1CA5C754179312F05DBC4579BA8280C83DD2D58FF98104B3FCF0996EFFDD337220B411A7AE227E0938991890F8E7495057295E2D7FB7B8CF1F39C6C59AEC37FE6FB87311D39BAC27EAC5351B11BF84EF91FB0BBEE3E35B26578AB0E38FFDCE479A2972A4DF2D001778C393E64CEA03373328EEF17AA3D0FE7A9C366CD3440501358229177701B96E7B669CC1EE3B4CE04DF63281FAD18FF66EE0DCFA087EE942408064235E4FDDD7D97D8D83E3EE430EE24A11ED96B2AECB9069D9CAC9D2530780499A99F16721E4DAA25F96FD0DC511C597BD071576A5E6E7F911AE6EC7F18FDC9048720E629C419B3B86B09352B4515CE915FF36C997342BF2A194785BAFFC4001C248566050BEF62D089EFE99AC5C6F0DAA2BFEE64070B5E9C04F2312CA8E89C5C04D34A9562BADCE42432A88C27799F297FCC0DE87AC67D62E95668FF38D6E533CAF5B5B54278B5646BCE6D0A82ACEA726E017C42032F8B09AB7DFAF0897E77EB1BF671721F21EE487F5F1BFE267DD47DE4FE32EAB7BF5B2E0E0D20D8570C3A079AC3AEC06E686EA22F3FB5474CDC726517D8A85E42862E0F607B9F0977D4153C90BB7C29A29B8A0552E6D3B8C0EED949945BD4816A73CFD89D59FCB1D2B41050812065E4D7302BB78865439B9EB9B43ACB92E435027A151492AFD484E0D726B01E967854D24C5A889013513C614126E3EC8B6955E32EE4040A467FFDA26C349E0DB3A9D5A0B2AED925E7E8387B0A387FE1C5307200E254236B90D7202655FC3C06C3B4B7BE97CF96EC48A247F550CFF02EB276A841D013DE1315BB2AE74B8B7D05EBEE272895651D99747E437ADA14D73AC327A311F1AEAB23B04F9391D662BF71B04A3D943A90DD88C4926EBF16E4A3D11C9B7CA61F82F5A6EED8BB27EF576558B336599E6A7C4D4E9CF57B8222F82E370258E356BF4CE670B1F8F3EC6226A4A9B66827A75750B58E8C9E5088733CDE9B578AD555C2C9BD5348A285147368EAAA71A8B31FF7E70FFE682683B4E471E54988D242B76CDE527012C7B0B07A83428B40087E297068C60A07C66C49E447D06BB9A669C331570418A4AE6E80A3606B5CFD9097091E5518C3CB835B72A81362A2665864162BD4A72DDF1668515873FCF144D3FFB8D5F0BAA4B66F7FD69F74DE0712458A8F393AF2AC74C6D6F3CAF95593AACD1ACB4367A196E455B94D45E2C411433CFDFA0DF743F709B9CBC27EA3617E288D598F3B56831B3EBB23A93A539FB4112CD03A2FED70A8FC10236F4B716E0BD41465FA958A149184328531F255D9C67474C87D547829385899C3AD7E832C5E6C659E402D2E06F2587C5497E2FCBE8A8E26186F2697CA30183811E39FD5D15B8CF0EED21171B1284740B2D5B8D32D0FFA061D16536ECCA222BBA35C1E7509867F240F72F1784CEB2CF15D0E38D4B9F30058A2EF721F65C303999A614B12766126D78FBF0A69CAAACC462CAD5082273B89B2A72067047253ED7818C0D4B72AFB1D256C37CD4BC2B6172BC68C96DC2C068D9533F97B86BEF6DA7317C217D27B2175491718D08078621CFAC83EA62C9599795E156BE08B5F03D0735C2B8048F777AF9154F534A2890C07F83CFDD9CF8468B79940C0077D39B7D8AC914BA4B561C848147471C0A60A93A29B4DC10ED4FCA90C2832BB159FB02D27B340A0FE663B1472A04CFF2939763034A19EA164180586FC4EB65FB5269324591474ECDDC7949EFC8CE1AD9BC748E5818404E63E44866EEC341E26B0A2B9AFC20ABA61744BD0306A8F9929622CBD81B73C81A8736B49528CE0977005FE82D640EC6034FF3C48B5FED6AE260B99A4A57EBE358172D82A90EADB4D1C316C3E01AD35EFC26F0391FD349990B333C347B27378F78DACB57788D264564E022D732D8632E174B66F91E4147F534F3B5485FDCA75E97F91E2D2C7FB11270000AC0605C947A300E2D3D30F5B35B51712CD369E6E6EB0B8893764E635CA8E65886746150C3AA300CF1F69800DE062DE2E64648533FAA6623ED0D59285AEE2E5518EBE278260A6D3B4DADB9543721E89D7722440BC7549C396DF1A56EEFEE0689D710090A84FE0AB06EFD61DEAF590F5E78D6810097DA74E2FB0852759D03D6023004CC6B5DDE3767FA7695D4E3F1DFACA0904557585C11D6198C2ED3CFDAB074C6D20A622722366ADDCFEAEE60CA40238182E92AB4EC629171216203885F307E1A5EBA8021EDF344D1298064D6992632871F33405C1E3C1067C47DE6EE1E5047FF7D2E03A803B2228FF640E1510D250A7AAF25F4B865697EABC300041370350C2E919F8014DB1B7162718AC693CC0ADE07691C2D967787C816670BA35F9753FB1D30954AC64CAAF4308B56DB027B75FEAEA74CF0B410CE18585685CEDE880ED4180AD470B0BA03F81C62F896BCC1CD19B7D0C506F9517A5A891AD03D062FF5F5CCFED5A6E96F20769692FD5C53C466091F2422A89110BBFB5C26993AE1A5B9506AB0C5349307D05CB3296D66ECED8B478A81BC6FDC6840F62615D6CA202B09731F5712C0D68216F1BBBC569405F349044E05012AA45618B41FE9304D3ABC6E28D1F680835AD46120B7A642116FD7CC91AB87A5F7585365C0FD25BF729494BFE12A9C5BF0E885067CF4B5CDFFF2F52C8F0A39F376E33067BDB64E34608ACF07E16673DAD6D5D33E7265FB88D4F0070388D92DC012C1E51C53638C5DCF7E5A254608987A25333CC8B9B7214843F88179769ACB4B544A744DD69297CD2D8095882D835A4FB3026FB6F821C664E544B37D543B3CA16F49418765897974F0F90F4DD909486684E0CB7F18A55FC8CEA86C5083CC5463F803DEFAFE52218F00478034A9CD4B83746026DF96BA4ED018F9827763359A1D200EDB0730546911A97B60D481C099C0A85EB039BC63F94E271CE865978446E5A5E5FE681F1A7079FCF3D3CAE2583535FDBFDA03BF965D928F0914D3E80A1F53879D3B1AF6381CE65B74F0D43433D0A99E4EA8B8A6E9A78BDD50FDA1A40BD4D10967F4748732AB7532A7D155CC6AA9479832924677096D8FED679462E5FB2B3B70673181409FB79A155BFF1B02EE64B6E68ABE957EB842F7525BD6CA82839BFB365FF23E8F42F37C12071F4A97691AFAB9696A2CFFA97956BCA8E514A4165C00A6AADC7AB61249C5DA346BDD2173974568756D99AE3B9A30ACB15A52B98F71E17B58DF2F9FD2D8D8C11BB83C402DDC816209000865571148430EE351DBBA27C19090BEEF78148CCD9E3A3F5783395EE6ED8EBD1489DDC8570DD798E92336F104D61BA205EAE82E190C9E899CF338B8C45A12C8958E4B53B47496F6118351E348A892E14B9FA1E54467239970497D7F208DB6E112F5E4E57194F9DB93E39AF2E9F35514817A4C4AFA2A543E7F25D759151C5EB3F56EA2A5C2BB352538B45984B06B239E053A0A6598BEEDEB1ABD97BDB21F4BDCE8627CFA0522D78581304D30DC5781CBA5A913EC0F5B4EC9E53FEFAE2F739807911E422193A492B479F100CD9829CAA7E62BD53A997F6533C04328284B2A16B269FE758E8EDDEEF76E1F4ABA2E9ED27C3D630CA83F3792DDBFCE6A41517B8494BD449F602037B67A1B742CBC09C3C13CD441337F0D20E6957BA4A3E64993661ED46573792DC663B62A6", + "sk": "B689F9AC3F5C158C92A7E8B562670CA310EE4CA3CDB9D9D7F1CA5C754179312F965B3B86DDCC8A3BD84B23A843FFA28A75C1EFC4C51BD35E9C5AA8C6C6533FAB87ED5E5E7FB72A5297E5A8D2C6B87FE1A07A4613F21BE746F8D357FE8B60DC395576CD911592CBEBF452C434EE7B7F9EEF354B0355CAD920C35D9DAF50085136D28640DA401050140CC9162619900C59C63110A34DC1120E09808148180E1C123154248493188A040670CAA43140C64DDC140811428582402D49460EDA2486829460009431A340881C224108B03022B58852322C9446445C140053160DA492814BA62521066A90360564480E1A2950C218614904490A87215384046228519040284A2431CB06416422881347711B024854B84D4804410AB005C1320082084C4B244A1926251C302ADB10328C00856040208CA0098C3210C3A48593C280A3900048808522864051B02419411220488CC4448DDB022DC4964C1B30122193440CC125D106209C2491C4328544B8884AC8100B986920C6658148010A208A92069180406D23C84022023204174D22B271D904241BC3900CA104D2046922840419254A80224C02996002459082444880182022474558B650C3866492445144B62402B00DC8C89051320D4336714BA82408347118110C992002E0048C1041259426054C466453A030D2003119192554840CA0846C8C12464A904920B70860322642142899340EE3326DD2A440519284612289949844DCA44C0C971092A4008B40664B2231D184601AC58CDB406A52B88819B9851CC92449426600B869C4404AD81409831449D3A424842265003100C1043014356C24C9010C176CE4120AE0046684B05152802D5846295482505316911340621B466E10484AE1308CD1982153B860A3C2000018601908888C4804CB1860133286E1A02508332D43308554443058168C1BC5241CB26D18C1892396699CC00153144AE2B0509CA66561C610E4840C44342259146422052241240E04940050B28809A021C0C88C2347724C486D0C054E8B220C08483180C4081B91080A81811BB52CDB326C8B82680C318E60128A00938C20A96862A849223930D9B2488B844DDB1882C41001938401CBB850CC146A03398604B4680B828C99101184288008842DC3A065C49860C3080020164E10410DC8A2841BB14900410A1BC5881430414A886D8426710C1500CB466480382D53B62CA0C024A08284E0C208A00642DB100A14C39192B009A4927180340A03886C2141098A166548122EC326665108068C1266E1B2009032728118658194859B20040B81456242821C82100BA549DA306E44C6111BA548541071D4C0089A402DE0C42183C66023B68181248E98824010388D54426260C089139588CA120284422D8A1812CB14251B4126C1820D9AB8459AA4688A90018BC80D99A2888014305BC00422450610C011C2148D1019260B240159386410319008C380A2388222C708C82032CC406510192160462E22A9248A849100B510D8362524353184848D84A40C1CA6400AC22CA0188D92A42D123709D9322DD33025480250842805A448000B318C1B9228C8100A19315289A84823C90C1C1164940024D90802D99221920468A240892322109446689022110320700A055214B560003970213806CA8040C0B2844C3231D1466901264E9AC28CC3108CD842898CC8415190214402890B93249C264C03A70D21C08CD3C0810CB68D4C3450918488A3C86022447282868911984DD1380C1301910B372013848112A2414A007024326E10416991B86424064C41382893B8641A3165203171DA14291AB905CC060A180960C2C4510924708096040AC82C0B23400B8741C02425D11648D2001124093003412D4A8420D09644DB424D52422809942C10A82DE2A031A2328CA33252231302222026C42400502685519080DC46890A0446241046D9240822426981C28589306C0AC37193848D013092D4B26D10A92100085083364918C10DE3942919B3500B132813046823016C18144121948D90C68501B8844C904DD91864D9228AC9A604181441C4362A13917023174A6400885084051B162A14332D93200C90468D12B19182447199248408188058C86D5CC68463B6050C816D1BC93023A189DB0481DCC648493265834064C11048190629143904CA068DC132018418308296250301508AB64998A628241606C3484D9044482664C6C6B124A2857AE26A5B0547C8D17FD20BDDA77BBA851BFF1E2A3D6F2449A3D7661C42E5F7FE82D17697172DDF3CFB1E3BF29831D5483B46825D43539C4F159D3EA9CA18BAC04196CCFE47BAB835111D405BF52F5CAF365F6E1FC3E6B5AC52CA6F9D04A2DD1B2A9E0A5268790AD507254B22E62F3952282041954DE4CE98460CB4CE67E8CEC031CD430D1E825D39389BE8E1288382C1C1475EFB6EA7A3773B9A25D3A99794B1D073D121B65F5AF9D0733620B5A30DADB57985AAB262E87CC6B1D54EC13213F78791760C9413E273B7215A654A9BB4C0482C291433BD76AFFC47A2AA962B7DE542DE840B99CE6428BFED4B95205E72C0021527E1C5D3E810D91CAFD3C86AA4BD0A40EA7DDC80E1AFDB978EEDEAFF5307AAB7E6FAF6FA25CE431CB75D08099D83D4763B6214E48371AA9AA59E1CB39049CB8665AFE3FA792C5356F9D757019DEE92E18A6CBC33B0407D18427794C8752CABA14C54613AD42B7F17A7C2D6F76FE7891B138B047E8004FBF4DE4EFEAB8CF2148CBF623B41EB4EFEC749236C52138AD9150CA2160A24F9672059E6C50BB1E282722B2A46668638A37601E3291C59C97940D15F916B59871339FB26DE864C6451FA615EEE6FC615BC0FC0BBE440DD431FB61C4A89C381DB8C65C2FC41D3483CC89E16E34BA6EA4D564B053D834504F9BCC93EEF3C6E84F046029BB639BD681D66F58B30EF1CAF54B46F87B9029472B297277774DB9E491A29953E356AF1DDFD874418B04D649B64BBFD74A8723B451ADFF707F95F6EF897A563DFA14673B2870FA588DEA8FF1A66480686B24D918E7D24A70F48C061AEF8E546E71119FBC46838B3F58A908C247A06FBC8F54553700934C6C6189E27319975328E092AA66C228464D21D3AD3DFE4533B7539FBD05D26B245D21DF4401EE265F9300CBA6614A670D8D07D2BDD9B58EEAB9314BD0D8B669DB1736EC4B15714C11EFC6CDBA9022CFEE95F88DCB1C9B94CB9286D4CAC2265BD8AF5067E86190F3CBB14CB37766363C205F5BF5EAE9C53C7F3C8471FE7C8F2ED4E54B2B46530232D4879E8B151D0900B37BD78DC9E3E6E82BCF874B131A4CCA2FA669745EE1875CA3036CE3388102E975BAED3DE91FF7ECD36DBE1A1B9F6E8F015222F173D14758616BE86C322B45C79F7937210199B30FCBA68A92F6715D078DFA45CFE6908AE66611B7854E468C837715907C4C67942F729DFC9DD8ECD36CCCFC80C08483D8B045BB23279696C6279A1AA9A1954BA3C2EB4078368C5CF38E735D6F2233258DEE2DED0DF254E4D29F8E62709F9842349D2C9F5C0FAE386A8007F76BE0E6289C2E44742D80855B198290888C82123141ED6DC69CD9883E932E0473BCB64E83BA3F0DC1E093A64F912FB71154911539775FE594BF9BCA2331D4651EAA5DEC5651EFF2D96758138100768BAA50BB969D4F8BEA490DE88325BCF7EE32960FB59ED0CDDC5E2759404E18EB0D3B5DBDEB0DB7F3F83F5EB30C385083B60AFE529E9934F5BE43DD962FFFCD48D2FB362D8B2FFC91BE657ABE6F4D26CE63B7C10025BC3F22CA472D34E410093C388238C901482960C74D9C616ADD05ECA6DBE268875C59F6C086EBA2E1DBD9A7FCF6288A423719EABEA8CA57C83F2DC11CA0927E2F294EE55D4E61DB87377682130D88C9F30F8863BA646AFDE045168D16BA07EFD56BC30D51F3D53E99200F86C2A9EBD506DD7CB43612119F56E546AFE24306A406483BADD2ACA212918F42847E58191DA91889AB58256DD3A482248917E144CDCDF37F5DDD84D365CF048B7165536791E2EB0FED48DF9F3407C79CC7E9FD5CB2498D1E9332C9FF687FF9F0099F78553CCA3F02DC9BDD3520118DC7026248CB69C70D13A48B04AFA134CA4B1F1AB074D5ED7B36AFF20EE54683D593F6C06F6D643AEA6084BBB0AE9008502502CF8A6CE986A48CB82E20FC64E5C81351E217653162F62BCEF020DE2F3D5596D7E3C1750A3BDDBB7353EACF11B27FCB566A404A8EAE3FA66B1E5A8DBF95A69FF822ED5CBCEC9604070650A72F69F8AAA81213F6F9BDA507DB2032620E2C587DB8DA486FF4680284423046814E030C62EBFEE80DEEB1D760D838AA963C3321DAF041DF16CC206E43BAF0CC1095115233707567D6C905E01BE0074657F0AA9C9697FD9D8E87BEF5C9BCFC77BD2D4A4476AD3497E359EA9BD2BDE4614D9CD03085F7C473E3698F98CA9DD4127DC2BB41C547D5ADB304F38EC348767C7605F0F01DC475D4D4D00A4337C0795B1EC50282282EA3C30BC2F9288B79FB7F5F433122BF2B2B1935C8B747CC2FF3F41A85AF9FC3E7CED7DC8AB0F3D9482890A09E990B7B57443EE62EC587CE3A6EBDC78D9AA327C35E1FBE16959D031176B522B5BED9A18FEF91A0690832CF87CB560FEC9EF1163F34EF7A0A96B6C48904F15BC28F8D753D125BF55955C5D4B52EA7A35171C812A135C5A0AEBF21B53CE9371DE75A77EB5F8EDDE3C900DECCFECB184D78461460C192233E66C50A46FB89BBA14AA02C434445239CBCF8A92914EF5A9ED12C7706615CC8B0DF0C596830B1C40C7C8364CD0B803C20737C779F9D25F35514AFD207BEECFC82F10B0C8F22E1B3D86C91F2A5DAC2E63CF6DF5003DEF1DD74439B2A0349904FFB4B05A4AFDA774578C70F409B3CC6328B1D87AF729A60F2455349D48420368C22692DB5D0D9BD313142AD2FBAC6FEE29EAF2974E66EFA51BA6A52349C3B451AC2FCF38E3B5073213426724F2238AF8932297B6900E5F1C62F518122792813E5FA5ECEEF796AF07F8DC316FF3D81461B1CD352DDD9F962A3B46DCEA26FA83D0D1AFC09B7468A194BED369EEFF11DB12237F0E9A69EF7E5F1DAD3DAA42335ABC804CC18291E1128CC6111E605922CC7B136DA254D674B1D717C642194E7E41827AB76CDA5B9881FA9115DFADEC0FD0ABCA1F00C8D93496F8EA2FEEE3E9677F0CB05608C4F3A6A42BA2A694ACA9AA045E88734FC818965D95812B613A24638757AD8E9037A4A5AF89B2ABFF94C500DFB98E5CF43DC41C9A988194EC689D8972F74F65064BB9CD20B16B8AEBE6C258EF9F128281F6DFE1F0A6453D5D16DC11949E7049AF3F55B22620DE1E75A5AF95030E4F2386AF4697490FFAECDCE76BA131D61FF45BEF33DF3AAC63FC355EBB1B24AAEBB0E31FF057ED0CDC9ABB146D99A7276FBF686B9B1DBE51533F12436CF3CFF995BDCDEE6D5660B3E4D5D37FCF633D6FB28318D2A847ACFB4F8AFBDC8396B7172D2F21D17A666C08A66F37A79CE711AE936FF9BF807C3DA758D416030D5BCC38633129C4DE4EF4C763B2D9FACAB758942B827BDDC9DBECA273269B330E5BD41CE84566A1B2D39DF36EB89780EBCAF7A7BEF02DAF9A343F7FFAD821FAAF0138E6D73F7621BB699FF0809AE312D168A449E8748B455B01F2EED9F894A4F47C4D84C7E7FFB382FE90B7BD13737A01FDC8F3A8C1C692961267E9E0238CD70887739B28774882064812EC9C431B59572BD177B3B0C21D352782FCEB70255650ED77FCB9C4D8C65808558852BB57ECB9093C835491028BA284C6B97D9A4D2F1C0530E3169C2628C16AFDF0826EBC9E4405FCBA358134CBC596C89017E76351BB213D2677575E6820019CB6EDE7852FA932151D7A72BD7232EDB1F019F45254D2C49258895DD6EECEBC1C1406FA927BBCD8FB1F03A016505F63A5CAEA9E301ED9101B10C72F27247442FEFC7576FE89E218B9D5D9CE59A54F562A4BA435A35873177CCECFC477B782870C4E34D95759315FEDF52B9364E9FB4B9757AD1F777EB55DA8A3F5FDF2363F795981364D028C3C3A39A41B13EFD20C4E0D776FA1D4B5A3AF641E5C4C5CB5C4B807CDC39B8C246D9182445EA95F8552DFD97D5EE22221C155998856E33E4EB5A438A7A62213276DF3830DA45A0F5C7ECE630290C8BED32F6CB5B899FD85B36BC3F60670993F6428A445B330B81092144A7167BD9B7929991176D4EE46FBC683546D268E1006120738E5933228131FA464C9A415D15F79A1C184BCDE8C9B766B0822A5951E3EC815B5ACE734535277CBA2BAE71EDDB24E58DDF971B6D757B77EA1B97793F501226D02CA95A8FE15D4B31897654CC0F934B5F8DBD37AD33A05170CAFF4CB31B1CA19B3C3C6C14E9B4211CB64C75D42C4A538FF1CB982178B7A9BF8E073886312086896AC4C0DCDB345418BEC5D1AA64B29CCEE1984536E27F50D62997FF9E46F0EB0D1FB74F456E8553228DF4CCD20E6760C79F88FA9EC924D0D04F13500EA3B99F3DDD1BEE0BA0EB4207EC4C8628419A434ECF5BA680CFF2750AEDDDDC2D1DBE375E77E5D133C833848CD35AAF2987898C0A03B93EBE86ECA1AC8568613288485C8BD9F49251527369B066152F34A4B6AE4FB46B0240F48A2ACEDFFB5553620BFA82C83AB61179014D224C57063375077E3770ED0C34478108D619D8E297E1EB29D48BE286A74980154C488BE7960D56F22BCC1D5FDFD992D5FF1F44D97534DD9C5A3D4A9F8D9359716815996BDADA33637AC3DCA3460FF446E51CD05CDE9671EA6BA24378CB83EF1F4EA2AB8CEF6D50767C79B8E1199CC823E20AD3AFACFC8DE12AA149FCA7D0912C719444BE6F68187BB166A46BBF7E953ED1ECBB3B607E8F8F851F27FA4CD603705BCA0C6532574AEB3B5CC61636D468E785AAAD1520004D408FF1BF1FDB5361F6E8D1C91B6F6B42C4362E50A0474E1452380" + }, + { + "tcId": 56, + "deferred": false, + "seed": "5C3E3EF0278EA9197F30C4DD9C4C06425C05401253E77DFB3E1D5315CB00915B", + "pk": "7E83C905A40C4CE71D44578ABFCE6A7AB1978527F0057F03112D8567FED36093A4B1D6FC48D27FE2A3AF6FF6845B999A74A457349428C7F042ED012B9AE0C11733E6F8BA8CED9D41BE522BBAEA8C37BF24DE1C2D025E3B148213D573FCAE27A8E14BC4758430F9CAA5D1B808A88BE38761C0D2C4FE040210783A147F2BD6D81565E72D7E1C1E7451F550AD6880B5BFC38940FEE73ABC4E0B8A68065F0B8B9DD4F4AA9E171E50626277ECA42E71DE8A2D364572F7D37A498F451702992703A86DF74F1417BD5CC752E6D4DB90B11C6786A85EF82BDC80C3B53AEC20DC571A2EC1C36C242FDB30D527F6D483072A0700B57BD31728F7365522D6A288FB78160723AC2F89C6AE609EE194CCB75C49AA533FF6FF6D070383CF326C42D400A70D31FD15D835FE9B278F53BA6E4FAC9710D1D03D32FDC47A3203EC23A34420714BA70D683BFE891118350D91B56CF9FB95533FD4F8024BCAD4E2AAEB0BFD729BF5746BE9BE6FDD6025A209AD606F49F8987998600BDDFA807C3DADCED192F1767B58C1C037579C9AD0D8148CB7B125DC66697A0C9690F86DAFA2478AAE0D2F9BD9069F77B2EBB4C372C1116BEA7488337B5372960C0192715FFEA7051DFAEA0E86E43F534EFE805E16BA45469370C50C15CD48CACBF0565514550167E7FBBB86D777B006F1E13CD1025E4A7327FF7F999A26DF2718D5551C30ED776EE9BB36F497B4B845D40F411BF7DD622EFCFFC6D0E581B05AD660417F3C5709261AECC043B2BB10AD07A605228225B647141D06294F246ABA4B66CAEAE4B97E72290FEA8AF0E3888694AE54BF29A9F587F0817201BABEAEE17B32A8E1057B48AF5D9A29D4AB9E479F105E95DEE4C855BF4410E5FB7D2AB55EA4E55331B7B3DC1B31A9AA99813FE42CB602ED0A979BA9F684E545C44E9185A176F25CF89AD2303088F80B726CA30D326F46E37ADFD11B10037655D4B84F10B7618AE37C3494D29B0BFE308183E652EEF324BFBBA27FA0EAEFE1DC21B8709A51B1E253E597D6FEF829DDB5B1DE50BEA95E862C7B61991975AD3AA56DB6BF405742D0EFECCE68F9D304AC4A162E031DAA216854845BD8ACE7917385C8C6BDD8B91577BEA5BA5527821F8294E631DC5F6EC6FF91804FC9B9C48334FFBBF667438563E0EB92CB6DDADF2AE8834194CA5600F7297CA00F0EF247065E02D991543E58C4FA424D20484FF85C0EF98A881E96F327DF5662ABB6462B4A5E1AED2D87244A1030C80A5145B6DEEA9B5F6539DA2237C7CB913AF4F24701B4DE514C6BC9D82DF6BB0EA9727D2BF8CAF3F79FB45B89B9F9EE6C7822957C650EADD34DE288A3BA14CF632510314F8304706EBC27214E37B5E9356408FD8F30C1B7E9AA7699D4ABF460D82A6AE6BA3AE6997C596C368A5FAB46BA4D106120560B5E7F87007A3EAC7CF822C414C4F480F3ADA0721C979BED1D39451C9845C23FDBA4809A35D23512750760493BF1E9C0FAB92E09D4DC3C2B757EAD5C3C039610427267B0B60B3B7F258E110332F88EBC474C7750E4531F8C19C8F2DCECBDD9CAC2645C18AC7A8B7AEAA1D79BFC79BF73CDF5BA09AA0762EE739B503384F3C8194AE739AD48076174D3193CAADAA9A5B1F4ECA6E948B3CE0B46AAA6138689796089137C70DAD610C88605068EF8FA29AA47B8F680FC2B663443913233BCF5263BC9081A50A39B8A31D7C5905D281A10B40550B3D38DA910C731200DC6146D44BE24FEC8A09AA2EFD512D1E417DDCBEEA76F83371DDE60F6F5324C38E9E4A9D26636C5C3AB5E2441EDCA559ADDFF294EB07C77DFD26104C67BD4F73CE2F068F72578DCB83D5B5BECC01CFC4A4A424C24DAE233AD0B48B8277083EF5FAE224D372E52C5628BE386F647A811CA7C564C8EE4CADD91C1A63DEF5553542D1DA7B9557C4407481F4150D381515F560FC2AD136D9276B1AC7B4AB9C08D911347BAFB5561A6F6B55E8509462425B37A8E96D122B5FC5718ADBAEDD87DFAEC689EDB28AF8A0CCD2CB5A97300DD6716579C9B9A15436BCB3DC4A917144FB0285804A8BEA421D9C39C4653196190FC5B45F2CCC55401744EB7A2525042120C900CF3EB6D7A8E685F44749D47A704C47F96B49E95C216A0C5E4E4CE5A0E15E798FFAE9CF8912FD985734E3910E82CACA9494EA7D6AE4904CBB3ABDB02B3D51C18178A308FC058D28F0AFCCD14D0F488B82CB3B0DF13CBA10B1F6A5FB93F557281815275BA3969AB0F685BE6CDFF611B08F14FE31D3A569C25A4A92FC946FF8C803F9A7D3249C7AC9BD08D06C631C79DD06BFAC714E4CF8D0096A985A80F3AFB7271AB976E2E1E3494F03203C7234DB5552BE5A58B46BE553FFB6DE465E01E6C66B019073666CE1D9BBB9952CBD44E93CFF7E2CA83C5C12CFB63B0198116581EE8BB3F9ED569B5BF2BBE7BD0B3A6A71A5616144C8EBD7C8D56FCEA92E4732811ECFE8BD075FB5490D46F30FD381D2574710CDFCCD62733406F788A29D32DB7A63E4F7735035D49BDD302596A2DA212886ED1F394FD70E4AF7E94CB50A43301827382F6DC651F895BBA5C6583A5704737954736F54CF7D3AB3FE8CBDF64AD8705F7553F672FF47B4E9E47784D65E97011B4630101317D55BC680BE0C687E1005892861AAE665274A78EBE97BE2524C94FA37715F3755831B49BF2BBBB1589D5859C34C663751CE53BEF8ED43C551879BA0EF952B94AECAE204AA097EB577644CBBA015F00A40136C7B819A0348270A89EA4A9428BEDE241B67DDF0332CF32182B20F551C82E366C95C42891353219147A1FE908AD18835B69CFEE9B8913D30E9A651E15AF091A2FF4316465B410A41597C8FBC32ADA0A6925714D68C9E72561DD67DC8793B15E7776BC92F3E545215BC3104BDC06D8F2FBDF4A4E79E74522EA0EAF37C3B716D592E50C97FDC2FABE637738272B633CAE325D9474EC4232FB8DD3777BC687D55A81CA8DE116674615534C3B1B6F79BF472C64EA729FCCECB8C30EA3937D1EA8412C5CEA57B5CD2D8621A5AD4CCA52C24339F4110517D287AD4DD6A9B2C77A60F2BEEC6502B1347C021E4221ED89CBC77A02B76764C7800BABB59B6AF7A5285F60BA88DC08D10317711C93E677403676170E05574409C79EB948C3F80F7B613E4D6C29E6FD81D8CC8BE62C6DE83FEBB801F7FA7E557F9CBC99C2BA8E33E8CD9A75F82E4DC604FD765230520E66FE375D22F732864BA892CDD4F76948DB7341407F0DA5B122654F955A1E5A65D43CA269FF3499374F5DE5692B425628948B91EB42DD35306666E6677581EC6F6683962F959273DE0C963A5BCF89679FBCBE517E5DF25868097820A2F0E52B78A27ECA47429985DC3962D99749F0C9AAA1458FEEBE8AB691EE7A3D68727CAEFA85E935057A1FD37B5A8A2D32C86227E85D2D385BA4D01B4C51911D7B98118E5634D3F2B41EF296B978FAB20880C7A165A534A38218BA366AD83893E1045E1EB03155612FB9ABDEB6FEED1B7A5AC81F26783491F0A89C71638853E22D0B0C26BE7B0909EA33D2AB9D47EF4CC6B4B4C6EF0E61CF108162C0B250FEA52ED6174F81AC2BCADFE444C60906334A7787F68DC2FE1DEDDFE0E9DD32C5EF156063132F130EDDA0C6F6FC7ACC1ACB9128F6EA3951CAA132F68F3CF69C42DC4604B359F40AC8D7FC6152C33E2DE529BB3E29", + "sk": "7E83C905A40C4CE71D44578ABFCE6A7AB1978527F0057F03112D8567FED360937FD1E64E1BD8E8E9ACA63A1587322108D5FD639C9693E7AE0C24729A3792C655C3306686F2684A6AAF99F90F3A79D38DF3BB3C6956B38F223E1DE0C628B87AE5093A25DA52B4BFEE1B33A931CA2477EC2AC3BBD94A97055E1A453FDAC9BEBC19C126094C100C9BB49120386513C66D13A54D0491484924100AB52801459012B0010AC22192B625D0A00DA4983122A34563080CD2864D1AA44CD140325300888C262952922C21234D10044D5026122494458484645A38012341214B104E4BB06112908C4B90501C26120901291C141263322D44269010A268DB226E20A690A0124611C2041407620331211A470A50068813A6081106614C988548C24C11000119362C0C969114192151A88C8A804520166811B0610B4120C4B84410368C22C66403A1800C35800B366D98340412328E49226211B0441B21001A190149224249123001488462B6040C0280211712934624A2109201144583C44520073220A851522628E1080A5C264514B184DB480AC0088EC04850A0922180820191022004468C88B2890B36919C48619C4005042350C804050B196119270E5A4085D4B851CC94248936659342201CC34010900182B640D1B4290402291A948D92848988969009392A91B869C890701B334AD02450C1A29048B26123490E0B200A812289491665E42425E19051993290D4824D09B731E03692CBB8908A90251216724BA285020022A4006013837119032E4A1622D0444E62268D0B370208C485D9B02123C240112024882840C8B02984988181386221C644E3A648C8123201312D5AA6441A434EA33090C9266288B2850A12040890400A862D0A03129A4062A3C2694BA425A1040199268E21C46412344400C68148A81163268251A21123930589208EE1328E0C1246649260202281134161548881DCA28043460820C3301C39010C46665312060A046909004002015004426524493218A94410162464246C19392241A40D0A261014C00CCA068080A489938000C1468210354A82462210026C131729A0B2501C278A4BC2650A39080228281338424126061A2725E4483019228E0B02429C400102988181088C92008AC3306E40366E04B4718B280E58282689960959202924869003404199126242C6440A359123B20C91B285C8168D622631634881C9A2440C4330E2A844C02248591024840265A0302A02182E9100711020718B1631E4964980C420C02866D8C6811B06050A98819826308C14668CA4280A24091C876524014954B28891C8109BA861E2306414C7291B2726124125648849029169E29871592681D8C48450480C41368D1A44421C142DC43292CCB28563080C99205244B431249688DB3642A4C800DA30042207811A1889C03824C1B48D2321245A126059208DDA240514392662807103370C40C091C3488610112DE1B2100A3384E4822010324D11084E20A52D50A871E1C471E1184621A84C408224023580CA180D8CA46511A71004358211974D61008108308042265289A6910B2781C2A8651A27410C44649224515188651C20805A0229994042A2108A022708D01670580620A3B231A2182C1002650BA12C01387162848140202889386521872D5A86500A066A03A58551C8488A8465E49411548249192749E2A208DB066120178ECB3020DA4082233981191948E1C48404B40D108710D1864088208D8984915A3441E4C668023681E1A02981C489C0B6700A2988DA226D5A180400C25022044A88980D9CB048113228C9966110A12590C65119A821D9B4601AB98118A52D239445C00832C24865433408112631D916861903501C31515C36424BB405A4240423244612474C408088E280010AB210421249993668E04261629481E20250012669E34085C1364894B0888A1642D03669DA047263144C09224C92862D91900961C44013148122004588464022A7051C146AC4400C4436698CA468D4087149A8300408320838701C98641A880403854D84B8010C208E1B342ADB324D42B621A3B629D0268E21A725242060D1C891C40262CB268D1C89318BB60C09450220900120A8110122651BA880198744E0086CDA484592B80953B850D8A68CDC2885A0A449E12869523221D304824C164594A04C203522DA80611B81801015241BA821A2C2285BB2456094280A1706F4F0365F55F2BE8949D5203EF1028AD89E2DA16C4168B028F367D8FCCF890C765E5C2EB32FCB2929D16755C766B50BCACDCC1827555BFDDF1BACE70F6C8B1AF5D462B60394554125321CF87626152CF5F8485F3F0EE9F6B3D931438FF408C3152304E84E6520ED35381404A49B64C293DE829FF71F275F86820E20E978EB0AAB289A1EDA6B775F95476B15BFB7EACD51017EC4525B36798E9C4CE58B1B495C035F961A00F14DC562F704B76CCE278DAF1E0E52BF4EB9164BEFA385C17DC4274320C7448A4002537925C7C4A3A6F21D8DAB362858FA41870C6B9960CC295571476FCB24F2AE5054DA00DD41009577D61F11622F92F9F5F1C6F02FEA6E973B254A202DEE4AD4FE676E0F1B590EEE5E4D5CBD9A2FC2C1D6528840854D8617600F184C0AB59D5EFEECFC8584C101B66C84C3F87836BF7BBE88EC92FB051800FCC93B105B41D60D7BC3FC322FEB2789F1BA946F20865ABB4A1BB506282A69666075BB813D254839CA5545F6345B24FB87255FBC6952444F836D4FC69D0F5C1851445B9F0C473E67DD7D237FE167D7C9B74341D851E92E3AD9CB9FF33F9157B79152B5AA5922F4EA93540C8B798DCCAFACD157F5DF97113957205F3F96FD74F4D7B0CDAF9A8BB933C37322BAE53F46607B29BEAF09635E572CB6D9F6353DAA787B8C4D593A2941D45A6004B9CD4C8769911A13525B64E8C5978C198C8808F15236F0E8B1B2DBDE6647E8B0D9FD48A4E36E1E5D9B02DA044C47BE711FC4717B850105F9E73B334FCD2071ECC2DC2C1DFF3B5E0668860EB25CEFC8F9285462DB6671CA572DAB0B9C8CCC1C30D0226582511F0D8E3E6943276014091272C9F87D62F8A688659A50E929E0C3A8F6A0037ED12ACA7A6656E4C8F0C77562795BD4CAA8FA2CB9D4ABAFE7A8F07BCBF3B31F3350BCDE58BCE638994508E5C8BEB7E25FB42DE3EEAE234FD12B7E2B388F10C604D36737EFE96DBFA4ED1406C4626998CAE8BE592058EB09B58662B366CF6B079CC14D8700F5EB1850952AB6A1F33A1DBB02B7799D535FC21193ABBECE2AB3C1542F4091C5D45E7272DD11FBD6F3F836D90B1153CC0CC1241B75A373FEDEC25E826E3C9CD4725A8B9BF07792D5640F16F1F0EA0341374AD6CED8D0A4309CBD6A8C41E8704F7812ED3441F8AEC9AA3509BA788F98E04F5DA6EBAEF3F0F21C15E2D6AAAE85028C8B46D4D91718413EF4D2FA536EB32CC22626DA5F2B47FFEC60D021AF9D5AA4240D0F585F2B3E84540EF4AC604917DEE3D871A1BF91C71803A4FCB102C1508B82FAA8762FC3A302B03FD941F575DA3140C793C84B715E4157AB305D33580D463C1759D61BA72CDDF830662D37AE61BB401CA7F67F838522434C53D70A30785690593489B7AD6DE0B07AB116F72AA115A1289F3CF2375839FDB8D0B0A6B97C5BA7F8B427F398DB15FB4E2CE60F7D4F854BEC87D7BE03E133EFC3F2EF7A41C0789114451BA731170409074C8FFB5215418C4C1F53A6DFBD73765143A9880D5B6EDAC970A57C294BFAB08903F337329934160DD8E0964B51C7AE278817B43AFC5642CBD4BB2F78FBCD3A22976A1756805497B5DA22C288CB6810E772A61208DD2846DA977E25BE46AED080354DF881106885AE297977E4840D557248C1CF73B8C637693C3B42A2F9F54566AD851B9BEA3626C7FFDA65401D731DFABE20543305F70176A3AC14B724682BD1787E930181FC3F13AC48FAF7563C26272E7AAE34B5CF530482BA36E9BB5ADA0FC5104E6F94AF5E496F9D38099D89D2589C83E5B2BEFF5C638B86A15359B48A41548B848AAFF320779AF8AC3B88B3ED71F7934323CB6E90D5BE36310E8291AAF090FBD93E154D43CCE896E669985D8DF91EED305409E292D9622DC28C0E3DCC6D2886E6D938D4A6877BE7403E0CC855A45218532B25B335469C20C47A5D25810DED94FA0FF238160EC4E271CD746E9D2C70E5632B2DA1290F8BA2A10E2680BA001228584326814C7C338770F483BF4A2DBE3101A52ECB16927252C2A391B32A24574B4B630F6550CE1690807D7383B24378EFB03386259E666AB0AFA71C53D3DD2CA5B0952F7695D1B66B091BC23CE1115DECE076DED2D12AB0110876C27670CAC62195285DDD229E41165706CEBCC41A5E6BAE4C7DBA625575965198B6661B3E5BF5AEEB7531B1EEAE07798E1BC65B53CEC5F01566A0042BF943E9C79AA6B55AF98732E5C84DC8631155E23B5FC5409BDD46B91FE3541F375314E4C0A0FC172BB3A7418911BEF933C5136E90574BFEBFEB839F0631781205918F5E942F9F26EF336302E1D2703A86F900449075B0C50C21CCB144CE02CA278BD0179ECD9F3BA61EA97ADE4A1E338EB905FB45CCBCAC4A6235CAAD8EBE97ECBF6B7D90A05EA10376DDE8FF931781B239038A1C026557BD50BE562626A5F1877236E8618D7505CD73BD32AE6447EE3D058231C3C5B60E703C9AF21353631345A7D401B74EC894F1DBEA23ED32B1FBDDFA1E12226719C58FEB4E7790F7B4D329F72CBEB1AF9149100355EF3FE317F3262D53D1D50971B53574040390DBDDA3FB3A8FCA81D833454D3025CABB2729B84D1358003DCA4FD88EEBC8317DD4F73666271B9F74763B2530FF7948451FA1A3BCD67D8798DBACEE3FE4C7FD017F523263D2C0A4ADE6BE9901489C4C230687E89FB079C52DA5EE5FF6224DEF88DBC52655BFF36D00ED2EF944BABA692CC95935ACD610B5F5D178D202778B7FA7F7D1E93810879FF10018EA10EDAA6435C1CB44E8DEEF08C095CB456183E262585D9DB2691FFD801F78C293A378EF8B818793701F8282469CCD8AF52C7849ACE0DD55B6117E93AF8CB7D385D618A3880095F3AA75837775ACC7E580031F5DF23CD3FEED158DDDAC8D1927F3F583BB56E37E60198DA73133AF222D346B6C1832BA8E78A1EFFE22CFB7B26E069E197D72A88F1D2EB3A6BE7D965054D74033CCB7BB7A1C7886B10B7F21C7205938172444529DEA76585D79C8CC779BE23884A206DA8BB54792C7133D5A7FB82991B4C912B0469DA9D7A4DA41F745939C237229D3D8EE31E1CF642734AB95D2906728B8404A9E8D7CC7EA7064BC2DBB35E7B3BC85BB54118765FDB66CC543776FD6D36C1192FB351BC177AC038C6573918F46FB6642D9DEB08EDA8D8AB84D963FA4274BF6B2D2E6ACC216FE379056BC5BFE68C217FED4678D711A8B16275EDE204D0C9E7B50875EF31A75880908C466F46B870E5022E015B71E16290A2CAE99761DCEDAC9A485D224D711261F32B35BEE7A76F5DBEEBAA6804AD6E27F1E214FA839C6AFFBE6AB73907D2472CB5F6A1A12AC28A6F2A37D6EA2E6FCDA312B5EEA3F830F1BA742CBFA517B28EB7336D96B208E72819AF82E9D6E3B00C4B6F2E7CDAC5AA3B5E2509B8E963CDCDBE118D71577D810F5ED946AFAC62257BCAC3F6043AB5D6A022D9E161363575C17DE278353B4F891F74C92D1261304D9594C4ACDD9C516A80685300A23864B9065C42C388F91E43941D7242E61F5924D069CC065B53652D13C3CC37362B93982DA0C954F57CF00A287DA54A28D347B2E3E0B30E555E14CCFAE6871CF9AAE3A9E18DAC84CB59EBC4AE3056017B6E70D000A756EEEAE8A44AA706DD8A1E14FEDCDAC101AC8AE90E0DB8B640ADEABA76E8B45EAAF648DE53C63B323D67FE5BD9BF979405229327B364073957EF733EAD46A0BACE00CCBDEFFDA62E50CFAF19648279CC04BD9EED6877B0BE78542DE7073C86372CBE407C05CAF3D264E8BAE22B74A3B9E59FB0269512D481DD3F44F08ABD0129FF336E7C1E464BC2A11EC50685F3AFD0E00E6CA0C99FD1646EC59E313835C929FD4BA95F6B0CD1CD737F22047355F61582B508A8EEB2F3466E37A04856FCB46B289D461274DA1764F1B4165DF1CA0F74C42FE780A96350133C502744F566BA027A5E7D40EB37CE5E810C80AF2329A410317CCAC602910FF51CE61A37CFA056DF2D89514ED3DBEDE62625E4B25DB654FBDF1851674D7DE0CA3549B9B1DBE6F46448BB4011AC09E27B80E3A225B2020F2D6144449AE0B832A6B5D44DC64A495E66BBC6D837298F0C9DF6E8EB0BD4DE699CE17C8112E4EBE988CB6609F21DC4CC71AB5F41CD95BB5AB56970F4BB663C0DD47621F2B0F22DB700ECFB029F24E1C879570F7BB42BFE66470D13F283C591B172DA62B4ED80E1508C1FE545651DD9D3942C26EC580CD2E59F298345C150A88AFFC87645DD0272ABEEC35C244CC981E489A93655F1EBD125F7273E2DC2990C0050FDCAD84DF8D8983BD68E5BF237DAECC5ED9D182B9886D70F602FBB6F6CA966C952EF4C386E2EFE91AFF326EB056E05F17F7A08FC8E93135F41C7D69E463F0519E0FB89B86136CB557D321B25E73034AFAB218F8D5B04465A3421EB91C88790A0107BD39DE71CBA1F9F2BEFFF0E3F64D146C52BB9AAB4279CDC2AFA34A376161F335B7D283F163108AD93A2E3FF2215126BDA53C05A0F0CACED1D6D5338FCF5ED6017153B458F126EE7D7B3D47B33EBE84A56B0755C0A5B12D9C822336C35906A95049D106C71A4067BD78DBE14EAA94925FEA88CC0693F35358CC3F4C52C98C8DF7F01F120D2FBDDDF6ACBCCB7EE08B8D334E00D9FB725538AD6747A7C6D62B0DDAA19A29EBF40381FB20B8D06E76703CD97905EEBADEC69F4FFF29D34D7AFC51FBE040B75860FF10A15FD30ADFC0781DF7626828B08BDED220EFFB" + }, + { + "tcId": 57, + "deferred": false, + "seed": "E3B2350AF8A1817D936FB7435C4C0CC758F79FF4696C46E4642670C5A78B30EE", + "pk": "ACFAB5CCDBEF80DAC19069D509D3566EA4330AF00F35877E668230EE94D457101C42488C6F1A2D1C64EB30539F25231207BF67714530E1CA918716CA2DA13641617C283E30673144B5BC85202152F70A41ED9C72BB49F4BA7292715D446CB040CA1A1152A8E77E24865855234131483440E272DC217F789AF13AD77DBE65DEB2300568EF26C729F7A2862C5BA15E58471414A3DCB37A7C39E64A33328AEC25EC03B62F7F5583760161A2109A93CB4F76CB0A9C19C42AAC905028AEC29E8287493F88FDCAEA9F46F6FCD36BEAA4DBA41933747D10640A0F4B129CE215D6CA1E041DE8B7A1E791B7FD19D0FB8F975580E828ECB0052F11E2D2800B0EF8AEADF8605F04F8CE1E1AAB8A817403D45C554D03B56E7711C5A10A8353C0D7249620A4C2454515B4A61D10603494FF26521B93177460FF497B98F170A7E7F12EEC8831052D0852580D3227257827749E9BCA234EAAD2E13589132997A410FD9B4B5753E5E6A48FDCAA4DC1EC7D7679767160D90B7842A17B01084303203C257D4DB439944AD0CBA4F916EBCE4428EC5E8EF6A06B30B162CEB539F9EA80DE510996BB857D169F9705B362E097DCB529BD20EA815D55E0DE2A117084C29FDD27E6C48796C162E2EFC4FAE9E53ACDCB235B795C671B2D72B34A5CBB7493D02FB84BE4229BFB4F668E5DCA4F65F7370B9AD2D19B89E2EB2D33DCFD904EEFDFCCFE640942799677156A3072D5BDE13A927C34B4509924C78AB56661B37D9A269DA60A4941E0BD9930915B4EFC5D7783C0D111B172632AE105C8B79EC3C540CAB50BDD214E9EDA38058463E10EC3DA5D2553B3F823D12515DE2321247E570B9A4769E90451F16527C5EFA6EDEDB8CCD23A7EE53ADC0D6CA0E289486BE0A1E1246FBECF67968FB50F93C5C018F21AF32EFF9A34EDC42F2CFDDD60CE0D41214999903304470798BE4D2AA0E4579374E97CE363427AC8FE4B40BC2DF55DF1089DE653FDE138D1B9549CF0D4B9CB5C53C74769D7524B0E9695045E3A4484C7817EF4A653DCEAF454F035E7E424EFDB45ABD91B78028E53A1B6DB3A8DA27F60BD5E0504899A955A0501D581FC471FD5560DB991774A39E202103041993A7274AF5B7FD0084E8D87F6351DF5626AF931D9644C544D134FBE29BB49F23BCC552596056AC4D260D52676D8352A17575130C245E43443EECC0109D29B1FDC3EA1F42C4DE1C603D4C1C67E871F706BDBC388648D416BC38699E6CD89BB0794FEA545A5150D2B4960B6CA483EBF71083295FC9F104BF804E700E3CC855F1F379701BE232ED6DAA4642D9FE83901D8B76388ECAE976F08B80CE021744CA29603923E1E6EC4A907BFEF119B9979D282D3D989509C91F254FFDE6F3339B0A69136FCB45CDD650889981547CCE33DB5A12D6702F9D88C16496C9D623C460EDC58666ECB3014ABB54CCCB326F7A6C405E5DA27E06FC2D02EE8F785B968AE2F05836D74ACB9086EDC3414D192ED69341F8249E8AA300EF050B8370B8ADBC5353F6C90E7726B41367E0954B3B409A644FF8D04E56539928C8C676DCE1810EB9B17F209C0A1E02F8D27BEC5BA5C516644DFB80DF016EA59245F730EAC356F37393A2A014FB6E1369384BE9A7CA34AD85348021BD9B2BB488DD6966052DC377676B7906AA7640B9A7E0B246BD0D6A49BD9CD8C6DB4628C5EC1CAF0D154A702D3CD838FA69163102E4A41605D847751404C0F6A75BA3A4E88612140AFEECFC4835BA4B8972B3BEE3CC22A52877FE08AD7A4ED7001144F2D5E4D27F59D310BB4C77EE606F5F4A5918408C64DF84ACE033668E43FFF6CC05A994B1A8F68CED63CAEBF95F3C30E71AF35CFEA31B9A36834698EAFB54F4B9EF83D8C597491F858BC89218CBBE22E7720FE2DC057276028BAAEF3E260560E0ADEA89C59E67E7A5B6860EE069A50CD10081C87C9FFC5B1012E9F79B15C924B7FCF1CB17FDAE8B79C4E176478173429B92C916F34C0D139F11010AE39D34B5116D9CD02E232597C3CF8FC740B8EA0F8243FB2923DE5ED7131F028435424DFDDAD4A46FCBB33A2ED42FBAC77FA36F2816678F2787F5AE11C64431410E63861B972C87599C1815368CB1C6AE9B956766F78621FA0D0B6214FEFE093C6DB2554C70AA472F6B332E1A5DB4068AA73ACDF50588C0B95DA328A862388F6E3C4191406F38FF5F526ABE35396CBF57BF6254218671472FF46BB4AF7905CFDCC948D61E4D72FE8D09418EA27C67095D608315EFABFED54B95B3CFED9BBCD55A13DC2ED0AF7C014BBA0B2239D511257B28975640CAF13C1AEBC2EC7F77AEEEB9617D6E5DA22AFA50CC6092F1D1DB34EBC2B873621B4DB9EA05FC497B799B0FC136D107ADCA22502F7BA903B3486DF8ACB9FEFD436A30D6E5488E6819167719D22ECCC383C146B72E6C6BDA12A6B7879BC9DAA5DCC85E78CD072B87B13C7914A249BA9C0F0DA96518B7BE227E5BF5789401C32C9FE5801206352B3FBF4E684549076AD1F10D4ABB782FE2DC75EAAE70D7B1F0FF1691BFEB248019FB45DEF28DCE655F1F4D9BDB083C8A7FF9C820D0C95F6480BF9F134AD7E7322E5E5D9CD8E77D02B106312189424E7E33BF8FE5EAC286E38F38D3C2DFF15A2CCA7A2EF382CC7180A39EA0962EDDAF7831EE8D91642D847108CCC7683E293B181E504293EF9738AE06A54A97E2CAD6DA5B2F1323D4B988CB92DEAE70B0027C58C31CE520C88C6E162AC21BDF5F30F8E2CF40881544FD7E4BE982E471E70D19AA51A0E564C49BB8B216993D6BE1C148FCF1AE1763FE1EAF4D05202425007FBD68F7FA81541FC8EA87CC13B93D404BADA2CC10DBE8996E9A694465BC91613C1E4F49FB61E8A7B75B954264537A935409AFD7FBFA00EA14798B8C2CCD0748801F5DCE2A61EDD9496E7508DB5C321D88D18979AA281C64202F945EF1F9855D0C867320B5E2913EBB84761338E7D990FB77B3351B1C433AC5A7C03E58B68842533D36DF772ABC7B9C20C9893951DF56821EF1C49C240F00AF16B5A9D1041E96AD648C5FEA9FE4CCE57A058858191153F181D9634E2969BDE6D86BECE6E1BA52A3D9BB29FCF5F85312EF2C28C9100E8BA0CEB4063DF7B54D3B4D52F90B055A1D6CADC626DDAF48F4E0B647C0DBD5A07C8F197F13C69D05158E134A6893E01ECB1D1AD019B5172CA938AF7699F5E459F65F807CFC9B2B21F4151CDF0FFE2FE786BADA75CFEFDE1A17D3B2C56B5A16DE8267E163045D71F540AB7508B8E89A6B825C416E54BE002984743DE2CF344A0E8292F18A533A9588A05102F40534F34A030B9E6BBF8A01695D9BD60153AF79CCE2CBA83167A256D56BCB87A088069EEFD87098F162DF64318A33D4618554C49E7F23EB4BEB0DDAA3F03D1FEE20A2C6E95CFECD06BDF650755725870048578CA2440194B8E1084E7BF06141D1F522E080308CB9B84C09AD7E5CF72A059E4AF8761425EB74D0C8EB536C7465678416E9E94F0C2093E9EB693D5BCB78836272486793BB4BCCEC65B45186EDF4A6743F1D2726533A8ACC0132DD55DA3031834FDF5B9E18B6F5F24020FEB4D77BBAB0C0695E0FABD4909E5DC525CCCBB455B3FBDA6AA900F062CD64730C27BCD5935E6C3A5191BB50D5EA974D366A14DBABDA87CC826B6BE346388A488777696E52860E6AA85383DFA8D354061AF381EB1", + "sk": "ACFAB5CCDBEF80DAC19069D509D3566EA4330AF00F35877E668230EE94D45710588C61A2D2102D4454B6B8E789B753FEEA928AFAEC16993C07F775DD0C20127B45D6F35DC9989A44EFA13013F86054BC0A09A307B909F7052AD59029C184D87AD0189BA7ACE7A66BAAAECB99361E393F00770F54A5ED4BA262B231C1DC79F67008846904046918106E14476109A52DE4488053346291022502212883348C11290DC3C84558B42991A6201036808AB4209384044236821AC41042004812162891A24860C685A09448DAC071D22050C8449140364ED4A804812088D2A4891CC450E1B86C9A3080C838324A000599B8649C12441800326420415B1868004728C292402101621341300016224046025480311B158C11838090348940344C0829864BB80C599444DB060E42C8709B122EC80252DA242610192E59A23103138E23C03052B46C08132208042D5C402D194046980481114790982682C49091A09804E042300C8824D308684938841A0104D1302EA1122C4C008989281204B7511AA76818372E2012802315840A87691B1085D99020D0B22DDC04490349292141269AB66044968512A34D013769CB2080D0B66DC434698B246EDC440EC23801922485E412008A122D1A497104174A61C64419286264080AA3B64C0045111296804B363014806102871002312588388542000D8C906501050A89A68C8406851448811B0562198608D902606018009906420381096240115440068A0210C92884D830420436219BB22C8A4452A09805D8428E58C40D54183110042D1947200131321A335088268AD2804919C8214BC04DA11405A0300A919629A04051DB925110C748504860C09650048205480265DB2424992226DA966C09B98C09174551424000060A1C2109D12628591410E3B4904B1809642029CAC849E4168ACC424E03456A22180513822C813261CC922C21254923B39101B349E236851AC650CA2840A0348DD21045D3C241DC886803928D6008266398201195700884481C1646DC48218AB22D43164663420C58423108A58962946C1C016DD4422A10336113A86C224210E0021212B00D0B358610A421C23631CCB0614922524A1685539001014669821265E0A869A124122122814A486A91406D1312445A466A080046139008C322889CA04863966814892DCA08042141614C2844A482440445120417458948705C08501B062000204CC1C86552B83119372124402281280148A68C94C42C2404300429012348899092051324625400709A108E21944D408029841282A2884150248484820D214109D2B80594266094C670C4806DE4962D9A240C18B9315094700134496298495C164203C92112014C9014469A342D61404EA4C28DA3B648D2984DC91620D9B0801009869C90410B8825C31832D2388DE0222151B068849400D214089CB21124086641A83182A224E4A04412B4689A04801410889B980CA3C4815AC0115B86685C444E23C5640CB231D4C80004C98521432108344458440100068D133411A2C81154062511C9281AA8885B1282583402CAC68D1A838941260089A41084A48902088421B30118C68813116A44022688028D1B409010846C12284C414252420881231624D8C8501900110144508406481291081102211B878DD2184192C4019180681CA004402024911468932024234062A24464121004E3946C19A931E4468640C4059BC2504C404A01A8089A321102A94491380D0026640412111A2212890212122325A4348A23B321C8A424512821D806681008084BC865C12692DA00609B34061836060B809111A94C13092504420219261012290122228EC91400143989C4048453928D11268252045052309094245012147222350C18B22D228430044281920452144052133789C8228E0C204504B344D3C83101A131002466A490041A494610296A610212C896494906700833868CA6514200624C424E932089139865DA140A501245014711C308648BC20043404C0B49325922462291014426240B264A90422121110A10840DC23482014249982640212171114045134610919620182310CB340123952013C511C38230A0144488209201233258C831113184E4106501940059061193080222A78922A42CC124711048214CC605C3284E1B471104998901C04CC3926CCB2068D890859AC44DA29089884892D2B46C0B180620C571238490FDE05088FB395717595EA65C813DF854DFA8AEDE97C0F8DC701BE92C6C79873B0FF5BE6B0CFAF8464A45D2BA5F1D2110B599D7F81608ADB80FB5A2CC5CD7092C5FE4EF02F6AD15902E03A5FD6D39BB6B4E3D79E52C23AE1A3CF269E1F501FAFCEE6AF25C5CA0C47043C67D79C421E081CC89C6B28602174B27E86C5D1A3E1876C2F53F7C3FC53A2405D6035ABBDA69AC32174D18746907E86DCC25B949C998FBB6759163EF9D4AF56539A86E21A8BA90D7A36A92043ACB02A205A23F40B7BBF7A00D6E6EB96CABCCDE88992F1EA76DD79900BB0BA99A562AA8BB9BA85A5F9B43FCA8F5E9C98B93D1A69DA7C2056FDD455B45E4DCF2E4BD359AB127424933ADE5EC8578F4E7262D2BBA50BB96CB5F8C00DF7DD90297E696AEB1BB7E8F3F16260CEBE3C1D61A16E1C92B286AFFFBA544AB264B8140BF77F720AED373F4C730D66E6F03D18CC26F1319F489FDC69F9993ACD0E4B0DF6E8B60EB06039880622A21E407449F30CB25CA14D4A409F1AE4419D87FF5927F932BDA8CDF972D7E6851BCA99444BF90E604877B865D9BDB9DE70D66219DBF4E9D5328B411D801F75C655DAB68B00A573FFD1C7E3D6F60EA042120242BC737B9684F3B9575324C72EF5CDBF236E6ED6E36464757396349CDB9ECD7F2827624687F6657071DAE514A27E6386837DFD290172F6F0EB41F237E19662293ABD847CDA90D1F83B231A1F10229A05F11CC6CE6A26712A5DD5042CB4E87394FD46D09225A4BC2BE61302461C432D3CC5A8726000A1A5618747DEA42D2261CD7B0659E05E1BFB90B7B796A31503EB4D73703A4DB8EBB852C270AE75C9CC8828B36C9172E6AA87C25116CDA489854D478C1D635D18E678CA822EA5B9C84EF2647F83705BB39584FB28C0074F805D6AFA08FEAE60D3C503F3124579D3B4E6DA94DD8AB0246416F036A99D7D5E4D042D3F5CF1E1852154B7D54B2B44018FB2515E6A78B09D7BE1CA294348D43348CF84666E99B8AB0A157D96B3618ACC41DCD53631966A2C86C4312447C66F71CA4B43142D46F6F45CF255731665A130D659B11A18173EEEDF4FF7546391AA8EF0E88033365FE8203E45B4A1F9DE544CC1DD6FFF4C467F2E78DCCF966FC3A7D9C37441D870C01B5A0D395C06395D15861B09396C1A523066AE76A2141652ED9E4594F8B4755135D9AAF4EF0B3A3256B18A78CB726DCE49E98AFA5DFCDD7C424007A1E1E66708B82B5AFFDC8F49CDAEED382FCD8056CDC4FF2DB11D5188C2C17B8286BA12F02E46D11346D2E31E2665D2B75872ADEA0A57731226B3962F152AAECD13526F8DFB912C63FAF7750E3C764F03A1011BCD546A6EB4E27E7C1B002B3044E50F3806317C9B8B610B91135E00C6E3A5937A0A6E964DBB3EC9332256D19553125A4A698E03E6ACC934B004C9926C0D6FDC79AA333534989300A5F207FF439ACE49F7E81E4A4BBA2924602FBAF3B335217BE6422C45C3B8EC631A88A9F71D20CC650E068C50F3046D88AFFD7CF983BA68EFDAB1762D0E32EC722142D5BB6347CE84F2E05DCBA3C6772CCB887F7F90AC4B070DC92D52C6BC717BA95EFE12BCEE3232250770FCD7488A2E75962B6F8A21D4BB83C03A59A3869285387013D4B8D7198E8889A108A42FB2EF83529D934D1D47B4EADDF9A87F45FF75C0560BDB637BE1D10129886964D2E127C7F204E8840390D89C6616FF17DA2D681B5C6C3A58BC8E741416F4A38764BF1DEDDCC392BFD82B7F50137F8D6898901A2E1B9A2BB9FE3BBC66F464B9A48A3DFC2D78A0DB91B57DFA09920664642B6FF95AFBBB3D75FA02DE3AA35703DDE0F9ED297B82E8533139A82CE6915926B704C4674ABD62318909456A4A2C9144FDE0427372B5AB67A1A2629D4365F57CFCB295BCB077B91EEB7955C6A0F5484D2D7D023BC51DEEA0B506D453C58DB34C59D883E7FC6114D38BCF367CEB384B23EB9E0DFCA82072B2A6552F8CF045D49F4F1647359FCDD137AE02F00135E5E44949E6B44A8745CE5AA7B3F06DBC894A67548550B68EE4DECC21AE41A9E06D980734920AD3B5CDD4AB69F8615663A9FC0E4597061471B234B0D04EFB5D74CA1957C1F6F59348AB738C737F38E7423F6283DFC1E9892052C09DBCADDDE2EB0D3C3996A737346CB09FEBB61EF3D3D3D0DCA6D33866E0CABC54FECFBE3EBE661205AB52DFF8C3386B19B1A4A69E8423FF31919764B4FFA08FD66DBF7BF5303B1C9F01A95895DBFC8B561E57702B07DC9C32E582FEBB3F4E258D3466301E7EA0B0E08D6ECBB5A9C3CD50B42A07C5A89C828179FE709AF72ACF0D40C90F05CA7D1215CD5A644B684F34EA37F8D6784A2224546833003DA12535B62DF56B2CF5192B271BDB5FA888FBE73DA5FE30F216E834034E8E718FF4843BD74AE1E97A09234D3B7E4762B3879BB3538F8FDDD921C8BFC3C1DC9820A375BD4782D89B443E621F165C23B0D49ECB82B32E1D569A525487BA9F91E2EEFF3C24E98D3DE8E36F0D48CDA2DDBFD15CD9A9572151FC66C9244FE994F52A832A5A30AEE67D0296455A3AB6273A1CF434C830CA4058EB440352596F81476D60D28F4CC9DB7146903990BE339D8CC169768BE36F8DC43B65A0E9C50B1A79FC131B794FB8D6910BAB8B92D5644A934DFFC58FBE8DC24F2B2BE897B2CB5E2FD75C01ECCD920A21E8B7F83BF778C1DB56DED43A74D6B8C0FD1ED4F4C897C82968EDD13C31EDC86AF48A5BFCBCC30E97298EB782047625E2B125164B795017B8EB2F992BC20D39577A6F3EDEC96671906FD94DCF62518A18B4832F52BAE51342E300ECEEC4DEB7DBE314F2FE65A238DFC0D140A702DF93C3EC4FCF2B2F357ABBD78686CC650D934E8EA18011FA7BEB993AE2223FC75F64898C4C32FB487A827E5B19F818BA0190107F2DCEBF3B56D5DFB9352A04DF74F2E652D1E11BC45E419E9AC5CB55E876F5235229DE599A509C49B28BEE7F353F6AFEEAB9662D1473B6D7F3374E7A6B13A8D0C88BBDF32D2B065296ABD3A757D0022DD4CA53FC9DC8C8FC0A8A63749603BBD46190C72F9BA7A4F326C61A532706360E555D275F996F021144EEBF7EC044BF95C134073F927C0F6575B85939DEEED3370F1B123E230245E69CB6A7F16E139ABC2ECB98AE42EC1F61FD081CED3E9E1F8280735CC7BD81C73C3D66C21CE5C3592EF8391060B41EDC80FB107DF455041082ADD0DBBF5BA6E61E533AB60304D6C36AA9DEFAEB1D5F5853E119D853A0237FFD212E45F5EC95634B6580253A7924AFD59F3309B6F6E010CCA0919E7D2DB088316226D0D9171574A4476AFDAA129C442AAA16E35D5AF3E4738C4015EF996F999843BBAC69175AC26BEB89FC27DF75256F35DE4F661CF2D53A3DFC55423D162C199A7C1D9F51062E39793E74DCC9B471EDBC70EEBE20E644F5E0BE39730A3CB1086C72F9A1C2A2268E3BA67E71ACABE15188120FBD0B7EF2C1038B3D3B39BFD648B27B06F966D5B2D46FA6E867446B8E8B32BE5C585333E36CA7694F70E345B5EEC2A9C1867FA5B0B95B14DC811AD8951CF82A6D80D7CF9E62AFE36DB9694128C578D561131BBC3B3C4379CF2ED7FEA106B2C7F4EDE9F2E80E68F92C93769D36A1D1BDE344E69F6F42304BD78A2DB3AAF3F768471E75731947278394BE15015B424A44BF5B734A63441A9FD07E74BF057E5049077CEB07C3AE573AD9CED8B1AEE7E9DFC3357396BCD32E520690D9DF368E2EA4CAB79328F827882EB0DC864C8319A63A6B3170549DD11AB5521516953A1B66E07FF37E038433BD044279D1427934085171CD641D9F8049DDE8D0FFA459377C43B71A9D578D1EC458205F42058EFBAAB03CF9445384983ABBFDC4BD358ECC5EDC56CF8584D5D495D75D2ACA74073C9218F5264DCCF6E08C49DD4652327EAECD35C08A918A572A6C54481AB765F820AB0C46169BAA3017D2096FA420B6A03F81C4C759B53E80E792C438DF5EA6D147708113F36E911B56334E36268B57C3E0700123BEFC78FA5C73192EE03EAC66B225DEE28752AD43ED299AD73606B2E62BDB589E8B95E7A066D250B128FC0649363D7304D8B140D41A85618919F1B0C547B23E9762368E95FF305B16944F3AD25142D035C20EE3264B1D859F8B8CB675FDD1F343CAB8D832812A0313AEC6A1C35E24BDD700CFFE45C7C498A867B5E24CE67AA977559AE5149EA4CBB7A421958439D0134020D2FD4DA4893AA7A1095B194B71EC7603E5CC28160C5A9A808DC337AB6006288CD5570474BA78C7C9736898BF531A9AFED78617181F1EA6E33FC3F4DAFC049CF13C2F9CFB71686A7038DD43AD235E894633944EE722DF168BAF9A5D167932F4E8B2FC556D62E58407A39EE3E666CC112A38AE7F3DA55C930F3DB2CAAF599D2AD19A5F903D8CB614AD31BDCEDFAB67BC6CBB67492B9267C59AC05E4295A8CC2570FEA32ED8901ED9424FCA18D3A7E9D60CE7F0C49D0DA9671985F53822BF517CB408F061247418DFC9DCCAB5FAFEF0DF0A196477BC9713D745C3A8276E6EE5373FCAD8A13F9D410DE705F504A6FF232C0641934161D0441CD33260C77396324B644384AD560DBE219E684AB60E610F98E48EC4DD5F473388E6C7F1C6DE2A53445C117650967496749CDB013F9581FE384A893C259CD05F015C6643871402EFC6B0DF5C1DD7CE912037006330259191F50546301E992918CB4DC22C36538FDA1B3B369BFFEEF8DEC7FDEFBC498E001D18A" + }, + { + "tcId": 58, + "deferred": false, + "seed": "75E70362235CC7CC4A08053BD887CDCC4E3D88F77E1C7DACAC972A9AF83C0CB2", + "pk": "CD40B5E59137D2D9A6EACB9777C320CF811D7B43E0047ED9BA8531A251780D96603A9F1803E43FFFD3748DF1F1CD131490C539CBD0E9DB5F23BBE7B8C6C33E4678F4CA674374D7605F33F122C314638D11F21A0C810011A87F0E1D04D259A6079BC86571F5E9ED491AF727BE0659A15D9B028D4FAEB61EE093BCAA0DB72374978A6AF78E04D2D3C15B9432DFF6F3359744517D05F5BAB7070A11310DAFAB230F91E7E8B0F8AD23CC722B4E5A5E546A7D3251E4CEAF11395F15F50CFBD6BD0F5D637B1451B5386572C3B1C2E978D0005A30DC34E0CA8588E078E9E5EA8DF2AABAD9ED35782904939D14976F624D5195310F842F252C5F7A26440FA9F2C54A4D03180A514D2C215AEBD528B760D4938A0D85D6D8AA300F7D294E7C325F92FDFBA5CB5FA4320A48BCCB8616216C53470670EC8424F47149D853BDEC6F108CFC6E537ED942FE437C3D47EF70436C97A4341840AC4D6B3177A9D88333AD0B3AFC336695D8D6BEE13D0F97E87A66E5DE08C918A6D553F8F49C1E71BE5C9831308E9ADF503807606F2DC14BF46C377C6C98E780808BE91096C8B67A6D97A2555B6194BA9594D3E415CB96302A602D20B328FEB424C12ADE11626C27CC7A19BFB8308CAE0425C9340D5679BD2A7B9E7874E4DC03A323C395F204C2D1FFA0441C62E42494A13D2B59E59F8CABCA87A139989C2E38EB5C36B0CA169E4AE719ED92523E30DCD272B992C8B859ED4059029E8851C607C606673334D6CFBA44E501D596E8823A2E637D3E75EFEDB8CE122462D94075C4A0479695BB7AB98A2815A115226D93ECB20D92484EEA686A3F580225DA87780B2314CBD7B90F38589EB04706BAC8FC90824420802C87E612719DB951CCCEAA4BCA5BD77BC781FFEB29CADFDD9E91202A7CCCFD7B25DBBB91BAFB361597A3C560CE89F2E1AA884897328D2ABD7C41871197841A29F69A86316CED244125AFCB946BC968C191D91FEAB8498D58A5E5617B32BFC82C53D2E3BAB3ED5410F10F188CDDB8FCB9ED9FA20E598432482103A7583A86CAF8572F295F712CA91C0F453FE77B0175AF20DE1492EFA7289E07FA4CF907FDBD91B9AF460C6DF8F70E1B48439030CFFAB1E5D19913AC756157EE709BB9BA9EF982A679872BC077B1E61D9F08A9E7B6900DCCD71C6F0ED71A86FC6937FAF47CEA0B65E94DC215532487E634411B8870C418339B063345948BE07D3A3DEDCAAACC9C65EFE292AF924E08A78B93870CF0DE7F87FAC477F54382D597CBEC10CE7D86E68C7C7BA61CD9258A3104729CB1180AB988EA39A1C0DE6BBAEC8D544226C738693EA743E1B677F44C3322592EB0CA8350152C385F48FF8B2BB747B9EB2AB710527ECC053DB826630FEC5BCF6F42BB8AEF9611D532CD073BE341565458E47FBDF214C3006457B0D1A18187124047160D7B87BDB1790786A4A53767BC440C5DAF372854CF8C55C03CD556B98FA4E50AA37B038F32A1B76BC70E17E1BB065A03BD33C3B22AB1E4C353526B1D4B01A1F15C33DFD9DD1D30CCC638306A81E395E7F74C5CB8E47229E6E601DC19DECE6E7B366568E28AB8271EB4CEF5B81F651AD0D9D1C8D12BD5F043AB584183827144E47F64B44B5C32D154427BCFBD25F52D797B218FD44F0F41A0EB1091213FD77771E2DAE9A4413FA499212D0A2C24C39EDA4960A46B9999BD5DB0E59615C16683AE8D92934F81C4E3B1B5E3651CD088A2FA008D632A8735651ED452F882032E9AF465F5B7E339B0145B34D0CD011BD7ACE3F5CEDAFC60D14F028EC9931FDB033C1F5F38E3E9BC8160D30B5DBB61B423850DEB38139162CC2E98010F486E0B78E5AB525DD13A1155F5653BE40AB16BF2EC096E962D40F52AC47F283612E8ABF3D747F597250CD511795C784B5DD52E521EAD85792FA1FCF03A6B2D1BD256A1E1DCB832A96F2A5B3830AB8CDEA95E8F0EAA3427C443DC99511EDF971E7AD0C0B629F480BB6A4273F66FE617C63657353BCDB5E2DFD533B6FBBAE9A35828019355E3E09C44930B172C7CE28AEF9C72865086443A0C1C235C6954705BF0E5CBE6F45F7DD02C4DC2A6EF9DB288C7C325C962A27EAF3A8B3677C0207FE66D75C1E58E847569E2FBACC6A1EFCB92D728CB6EF42EC66AA447C458BFD75F3790F46D044067AECA98BBE26472EBA5660171EF4C40F18F56D1CD42C9ACB36E342E78EFD65CA3D2E7E1047701456BD9599644F7B334AA7A64B5C44318661D328270D29F7B16994A1E1139A2B52925DA5C07ADA48489AC79E8630D5E72D03B33637EF0B81A54472F634E3494844D25D8B63F5BC0A32E7296E408E55B68E283432922D82426F3EEB0B1B35681A254A2E803BF6A7D140C8B4CB5A6919960BC0E787593D34BD7E5774D9B4321B61FD2A2DF794FEAE88950CF7BBE223C0117B8C369BA854D02645C9489AE8EF9A7504CE29DC5C45939AD19C9168A5561ECA1131D52443A4457FC203854618727EA00B52DE2F7B19AFCFFA01716951A5EF5140D53E88C84C707D6CD2B1F71270C940946499FA8E7FAE15F5BCB6CFFAF3CADA3F3BD908BF5E1B73694771F65BDAB6D4EB429E83769A1A727A6C7003DA53F747B4BEA711026381CFEF0D9CA7DEAB34192952CDA3DD0B49229105B7AD22C09C75BA2B42ACE26A0877793CE2369BBF5A72BFA44384373B73C88EAC04024DDFD96D98BCAD23FFAF41EB009FC8F0210F2B3C9A95C384B1645F3BF1F6ACF5EDAE1F3AE5E68E5FF4062F6934758F0C60C6F78B8839ACC5EE0A0FF31A4A57979184BB651D62C2F77083682049D55C3C75B01AF4D29E43BB8A14ACB5E843B75ED0BE125E7DDD092DAD5ED09343695474BFA32488FEB31DEEE31AF6B6528C6D34FEDB52239FA5D834A2E5823DA2F024A7547D21E88A94DF8381EFB72C0550F1DCC9141CE1D4947A7CB0AEC57C10B4E995377E96AACC0CF03D720175A92B0D1C222D4E0652E86063A5F31EB9CD9049AC0A94982EC0AC281F34768D1AB5943F27AB87AF8FB8192BBA4E540467016F1E821C433F80D7A320EBCA0425F11F2166512CE5A4B68311305710C8AA3F1B9F18E7F3B49347F8009318F92017CD47478E73DE4C1D7666729F969CE9E401EFDEE454EDDF217C791BCABE7B1674A3FF1191D93FEE46A27AE116F08F1AC575E88A76D115D8C966ACD63BED57DCCDAE0AFBAB7C63B47277AFB200FC4693815D53F529B85819966A92AA9CBBA95397F57265F2132DC6156F2FC64F3E7E5D47F579AA01EEAFFBCB30A25E6BA8B01F0E375847252C95B33E0D1983C0161B5836A6B0F21E9452F4E0E1972098643CCAACA2CBD7430D3FA6543EC473AF5E911F0A5562F7DDEFD57FE4C22B8E742718E1F0E4C84845743F502D5A837882DC3C581EF315E16B4F46B0F3900839FB5F773E4F01BD504DDA48C110C8BB2765CA294CCFA39EFEC4005649B44B169472A5F7E27DC345D3A6457A35EC012F0DEB86381686FC294F7F57F1689E3B8F7CE1542BB3277E07954B7FCA5C5F903852E053D5D2A3BAF7E728545C8E63F6A773A694A5A12AAE8C30B99C706B84C51304508AA149EE74B659829BD7A11DF53239D6729DFDAD18F77006D282E3726208324C779E0F27BBB97465A56FE09F7134306F0F627A71918DFD4B17F0CC72684AE843A498A00BC259827AAA8A15079459D20C517D92FF1F78638", + "sk": "CD40B5E59137D2D9A6EACB9777C320CF811D7B43E0047ED9BA8531A251780D96DB67272B3329CF77EB15BF675572262FB945B85E6463A8B20CC8C2685A461A728E66AD389C34337138FBA18110FC95592D207D224F2B617C765B22BA604DBCFEDD53E9C98E5C450860FD37B00B3C2D4FC66072B312A89FBE4F1BE957C22337735430314C306C83C221928048549269E132621A87708C386D080029648610CBC068584801091300E200725300929BB488D4421004A669E08890E22290021631881842D4302E03105201B92C122045D326011A936C4A10010043022338659B365153882510C68108198522B90410120CA2C8205A142484822C12284024450EE3062D08B78082866889402A1BB821E1400099424141406109252480B690D912850B368A24A92C11C3056244819CA62861484A53B00019A67103A68901382DCB066E88B02020B7311BB3659BC20C9B1205D0324A48A049D9A27123122CE28224D9B490633648C41060D2824054108223A5510044514000110149850A21129C482C042512108784092442CA8081D9488E1B13021A098298040D90269052202D11B728DB36891C044C03226C81C26124C011C3084A1A120DC342125AB045C9C6291B30114CA60111B32C2307819B0612E31841140229C83230929841DA060D93184160C891A0200D513069E0A409DA98416346701C4261C2C604E3081118C0456146100127716336101B914402B00D144488D8944D121228234270544072114524103105CB28504A9684192368E0360892C628D0A271D204009B2220A32620418890D0128612279023A76049920184B62884407191B60561182584A2101A069264845114A104231268D2C4292205129248051C042C1A286480B4241AC8719A1209C9861189168D53A80D14148413A08461180EA012251388080A9350599228D2A2201BA008221509433492924412CA82441C144DC0008849120A52C86510A65159800860004A23B940518408E2906DE2989124249181A80023824963482A412065A3040503906C9338920C37050A058924450E13494DCB4221E1104A59A650CC420CDCA88DA4269112334660180A0422648C189080069004368513044494881021916804A645C40448E2C030102946823246142081D32601D238684AC640189740C3122C4C0441018584C2446CC400100C25712243901C4486221610CB468D1B2008E29250E4B864E3C6814000300CC151D3A4101AC04CA31486CAB8018B909198C44D82B800C9C20D88063099246D1B356D49B00804064D4A3686994228E12280C2C4681A244D180328CCA06CC4288AD83804144951599670C01645E1906C9432252416411C30111CA14894048E9BA208C1980409C649CCB620232652D93460CB08044A1624E04668E3C20C23258C50282E54326AE146045B245002176E13300093362D9A064ECC44080B44310BA3501B430D53168943240A018525A3362A20318012874893C265D29221E42466D3008A1931129028680B2444C49828C1046C92B86DC9A889080831D016480B322A88823011490562200989066891B24020A048D4046C981646C9B64D23A429CC0490D08200A382841A450859148ACB805009C645493061CB126C41286A024980D8262054B64CC13086E2100D648021148524642646D0448889306A11426119C47051A445440001C2B86CCC388058126C928031080202CC340A62C8691CC73143B681113062DAC40580300118844188288D611064108680198421C82050102592144568C8802110C4100A039224412422A94102240684443262100DD3B84881988CA020805A46651893919A108081A02D01076298124E21B161143070400830044891D1C221C2060A60A6658B84800901255C24850B396058A4884B961062B01111247009078411844962A2454C844D81302E80142D00133043C01018866850320DD0284AD9824554A6240B94258C302C004849D134868918008B847122470A5888800BC884141640C3144E13336422448A9A8651A0A4648BC04DA2120894C0441C918C8A042ED8064D5B1800940822C2C40DD8A4900398694A86901C440212470C122950A0940414203181288444486E82884920B22D139371101188DB080E0C328A10A8300B274D88940843886899A281C82012C9482C0B154A4A1689E29864A0382CC4203124A4009A068622B405D20809C304417D180ED93D26C5171687CD43FBF6BA795D1C7C15936B549B680CF2EBE9FB44C51D62DD547CD205659A2CF3BFF3D9AFE85044DA2EFC2BE70E056EC313F7B7FBA589265226BC8A24B7B112CF7B967AF99CB71A120B479F611BC3D000E4B38D802E2533F9886A6AFE8DD383581DF8FF83DA2F308D687EA7982DEE7F81DAC574B1F7E3DD2CB010ECF084CAF4E3AD55744CF59A7BC4F380DE877837974EE1489900865C33DC3CAA99E08A6FFC03ECD8EBA4356CB5D23D9612F0A4992FF216A006ABCAED535B5DB40445F5AAFC3680EA522D260B86BC75ECF87346421243D63B889B08E52E0C1C9C1C783E4DF09E61CADC7ECE41D317BFD4F2F6FEF777E681E4E6690B08830E5F1F4EE92959C1981E4CB746D1632C00096EBA57C8D0C9C77FA74BACA4AF7C1C117E7918286BF2D4CFBB387385D928180176B3BD05E2768247F586B4E817C6783B4EB7AE95AC792BA57C707A61B47506D99C36FDC5618BD8D2C718F278A3E9D52E14C224F779BFA8AF2B0F596E93A76D2A21DF4F766753FB34F2594ABCEE60AF2D8B08DC387A8BC1A36C6D0A08316780848457F4792A1A93FD50FB1902E94EB7AD5DABFB0B5C2EAF0C778799E72E6E13BB8EC2A117E90D0A5C9E09BF3A5AE930DA3998FD3E1247955F0502D316EDEE0E957E9DBE71E9DC1372185E89782FD984C4BB9DE1962B9CAC63D8EEB6708C69964C9EF5AAF7C3D4BB6D993977A760F29D46217FB7FEEE11443C561DD4480D48C3F4FF1987772C108A2178BA9E0756FBA4FCF0FEFAD74D93D1B40A04B82C922EDB9BA2A2EE3C3B0C81184B7C29709E6887084F3DECDF2CE555200947E9C5904949EF41A30576B8A387E2B82748DB73EB7852929E6A8BADB3F446EF4947C099638B213E55F39AA3587C5C8EEC9B2CD26F9048CFE58CA82EF70A96B8C81143E57C2E822BE4FB35EE6AC3C37A1FE6ED44CBC6A753E379832E1D912775743B62C6C96BC97D41C2F8714DD2E970687AFC42BE03557CBA071289B81F46A3AB7FF15A207960D83174DB95911DCEA1AF71F2063939D1E1AB0A9006BF623DA4AC74EBD66906D50BAA1F09D96203EC2872EB6FF36B5C8E8A3256FDACF66EB73361AFD4B4BBCF7110DD81A7075D78D6F1A4F92B4FFAAE9C32CEBC29679BB276447790C9F4A3172503475B241C5E02CC9C4DE0C44F802637829A61BEE95F587223A406B37EB60D7FDDB4B86EFBFD88159E28251F56BB37CB440F7ACC87F5324B5202B0029BEA90D6B1EA5FD25FB271A8D8133C95EEAE95BBAFDE9F2EB4BD1A0C659CA2988359708ED9235DEBE98734C867E2D120DEB050D1F2A3FD2EE73649116218BFCA6A135EC3A62F8211C77372388820D4EBDD2B77608FBDED173FC49FDEAAC54E91E5CC0BC5D809A1CBB6572F2C1F2F81D78A270BEE14E6090005AA59B897100AE1F9BC36AE83D369AB66313850D3D8A99EC8A93E7315BC90CA19C502E69A2D982642D85C5C8F80854CB1D04B74A9FD4EA1E9D1FC43733B2FA5C0C4E8A093E97D228DD5F89EAD0DF4B44E5E6B4629043427537A87BF19003736260D26BB4ABF49D703AA372E997A7F82EF15526CE44AAC8AF9CC079E8B13CCE250BF5D081EFE74C212D9F84C6FFBF7353BB91947029AB9872A5243CE69E42EBA244840C2F593AFC47AF3DD28160DD5676081F3FB67958E0C5453685748DE3CD3D20F4EB48E50F62B917D6E1DAFB4F803D0D4FAD19B844498CA838846FB1320E4B2CB7A1E3961ACC126B0D0224EFA0F871C760371A1E0FAD6B90461A8FD3F32836BCA0EAFA91219154ECAA950DF2B895C263B27B0C0F8DC45C172B1EB6459586E2F8D3F0E17C176130E94033B43808E0B7E7DBD771732E96A6CAB939BF50B955FC44F27568A065CEAB2B0FE06CF4BA6C4E2ECDD097492724FAE6EA18209EDEB8AD419D3DF0757C493E3A6E2758C118A42D823D29A04E7A2A700DB1D71A3C86ACFBB95B917B7715E393C9E4FF8C0C9924E55E944B565819FF7080AAC7BD5F87890950C02B6ECAD7E3DDCE2AF9FB4DDCC101B16B934DE4917315EA1B4F8F6BDF01C8948109EBDE1EC8165DB27AB305B8599D0F7A29961AC85E0C6F330E02B8FD037CB33A1361BE467E7C028778B8B373CAB5D9C8E0C2D55ABCCF6B39C92CCB3AE854317A9E8E91057D68087CA7D3B68F2D62353E923B87506F59C412E8CB90EACC7F6B9A3D1A1CC8D13ED4A5B35B7D6C2A4DC7FD630194119E61439A33FDF0B196FAAEEFA671AA935653181711E21A6A3B6AF02B809CF4E445CF9E5C8F9009066219E0CA4CD808669ED204BB3D1C7F69BF95400431535A0DA03FAD81253FA9B24FAD1C6FB553A8781A2C01F42846B9B25897EBD90870DA0068CDC86B0A56CE04498A6D4A3AA4C00AAD5A4FAD8A2CA3C50632DF3B43168A1A5FD6367208D751EFF65D5FA552AF4E5171BA74B1F83945F28096E1C5E997993118AD44296E740083580360DF0ADED3AE265A269A76457B6FC0F7A677200E123D8DCBC4724481F63E6EB7C8FC375D9E726ED2313E82F9C24C79F9901FC4FA87E366C67CF7CC0C1C058E37F12DFDEFBA637046EA26D86CBA5FA7B0A31DBAA3FBBE71EFD20F14AAC9CC24854BA24AA1F3BFDE1B4D9793CFAEA5D0B16AB624F0FE6A2E190EA517C5ADF6F61206E6170ECA282471AD375D0695F986D2C923346C2CA3E9DD95DA2257227FD0CC0AFB29E8E94571A2906708D45CBFC61F7B050137AB738259C34478C733E54B9AD2C6FD0B4E8A84B19EEBB8C22C4BA69AD028B1E06FAF8454AC0D20AFC3683F20B798223DDFF36606DA5CB70F82C7C8615515E982E1375DBA9B69334EA175F82F5DFB6F3F5E48BD5CB097A6DD0B93E4D438D28085C4AA54EDC4D3B365AE1E486661091CF1080A1DC3B7BCC44A56461622BD489D8BC7BD386265876EA9A8D44810B39595DFA3B5368640976F813AB802E3502357954E9FD38F7A01AF24B4901EA68368EBCD72367F8909E52779D13733EB343D9FC6E87D7757C662D7B41094CD882BB81D850D4919F26AC15BAE31F29853B8EE18F035ADD3A78DF5218C7D7F21BCE4AB2A7AC948E9828FAB018AA8D3221391ADC9A11C846ACA90F755391F8BF64370DE4355244DBB9B2B25135C75782F8106BA0FD0A1E5369D0CF473794257D4A5C2C31E65590CAC03F1501CC0F333C0D07358E08CC6C26477CD83AD3B3850447CDE75A9CE082E414AB1970CAC756F85DE6C4FF9B3EF977A7FAD9598F492B2CE4F7A4381EE6C090282BAFACCBC2D1C3EF987C0BD3E5900330F384E6C79A63628E8AE0424C605ED96A623080D6669483C77C04622DA1B86BFE2AAEA01F63F67E6868B4B1296B7A619050CA400B025BE282D415EFF74097C2B5933ABD9D0CCA6DAC48D2A0DE10A0A73F0885A978C5D1ECF61BB4132B8BD836B6063CD8362ECF2F078A50540EF38D7773F821D0947AF56A457349E59996DF23ADA9638108F297AC2F3D4E5E6ACB13B5BC0DC14CAC6BF06449A265F8681ACCFDD8C117F22A33A59CF29B4E746522EF91CC31A8B14BEBB980951AAF7B5CDF6B991D40486E9CB98F84FE7233518DED040561737C35E14ED5A7820243A3E828C6656DADCFCEEA3B96CCB0F4C791BED1269C6297CC6FD334102A37577C960E97C5AEC11E5B2C5772EACF3782D1F3EBBA987668D822406D9D22FA542918E76BA5D7FDB471077C924D0830F56D9A0A777B8FBA8E273EA670AAE201D7BC2285C78A7DD8AB1620F3488620C95F09316FA13AD0306A47740D25A9BF457A48DA5B504ADBD4C8EDE1396ABA8D8C915E3A55723BD64027EFB6B81787099F06E25AAA1A034F4F0535B6378A205C238DA6CBAC1AC7A672AE2570F37337A0FC8036A4D21F05D00CDE03E5758F57895939A4B7FF96FDA5B2A2B339BA109D0BB44F23E0A786A8664486C5FC5FC159BB988683DDF03879FEBD137AE92802CFFEE0262382350D9A745CA7C56E607D3980948AAB2AE8CDF0B560DD2E8B24DB149FCB63869710FFF439B9827B0D2D3A3D5B41C5F2ACF9B3437FCFD162FFCD26CD6FC6C0ED7EE53D27C61664AABE706E49D8D6DF790B5D43E9080AC62ED1025BFC5F205CE1FF6513F57D491C6AD0407F55C20B00F130DBDF49709785DBF1EFDE8B68B8340662048391E8C9D9A0244B62564481DE0E55FBD863076C051DB3D7D9C80560D8AFABF6E539A07A0D524F2E85F4130EDCB91F98EE4D286C38AE7DB6AC285A0CDF3C242F8A135CDA62DDF3FA2E5EA7BE1892FE9A0573C438B130966CE9B9EA94BBF73DE63760A45DA17FE69B913D736594EBA6ECE11259749E36D00A1429D6E09FAD4FB4DD3C5D1969013FF128CA3F235FEA0F43FCC8FBF1A7F48AD7C606A2A147D49BC1D8888F97DB44960C80F32B46024E05F4D346CCDDE189058F9F167E8EEDA366804DF647965C5535E24F1DA228A6D51CB73BF2D6BEC546A3C0B58EC2D5B9EAA034168485D144B8BAC206648EBBE89A235E8EAAB34DC0907896FD6A9D7469680FDCFAB4BF00840D58D3DDF91CD7C10A4183D097EAAED94D693B6911AAC624BE14863C23F0BCAD72FD3869AC4E14DDABC3ABBCAD1D7EEE9DB9E383C6DCD1FD0A2EEB4DAB2FEB2959C879AF1570271222DD74F57A9494895E01EBC38D557D7C9B67F485D5F4125ACF9A1ECDD9E22BFF830DD869AB3064609953A9665A33FC53C37ECA61B1B72364C80207DB9245FA75BBD460890CFAF3452850B61528B23276F6258AE93C641A1B" + }, + { + "tcId": 59, + "deferred": false, + "seed": "45CCECBAFEAC42F2D9166A879175A6D6263C3F7F9B5F39F27A1578C859CECF89", + "pk": "90393A79C0426134DF89DA80C733C58FA4FB87CA9CD0789211DE1E664F31BA756809063B7ED14F8401B21255D6A7B6872DD473407966AF226EFB110054B3EC01F7DCEEA3DAF2E71CDA93F08E6BEF1729455A1943A85360E3641502C97168F621304573F7E87333E7BDEFB3426C4205DF894D2E57F9FE7CCDBFEC5F34E18B7A12E8D3F5B0634780E06E9F60266C680C658F5A4D36AA27AF28438B53D15F277BACC9C8086EDCE8C30712C33D9E1D0226F7B618EC50DEC58DC44C6C1D58B95761666BF8D3CEA00CB4F0FB89866B244AF1C442FBF74872AAADBCAA326929D26CC57BDAFDD8E096ED1683D196323C38CB8A778C10E786FBFD42FFF507527EAAE2C4E002485C00F9CF1C564D11E6D703CC7ABC9FDE9B356A78EA11AE47FFCE443739CD396708F2E356265E9937EA88CCC72D11B5B163CC8376D3D9CB276185C2E54995686B858FE51C1F77D4F19BC7B6CD6748840632B5D402F2B483FFBC38A2E13623128018E6EE4C69C8104F24E2E0328AE686E1CC16BE4086F8E5BA323D242693E4D6BC86BE3E70F25D54D1DEC44400C181F6796D6A6B373ED37E684FA97B59908A4D4DCE9FCF77DE11F13A674B38C9757B458F43A69CBAD899EC4BA0C25281FFD1CB07497BA154AF58B8A8FA6F63DEFC4B8CB3980158A108E744A93109C6E54F69B38BCD851BEFDD4D3DE6B3EF1FBCE494F6FFDB5752608099DBFC9C17B09BC7443D15ED8750E3BEC0080D8ED4CCFA609D61CFC85717AF1C117FC4C0A6899DB99B5BD5293F6AB51D15A0323EE6049F21D4EE8B601B3D28A95F4E3A42E868480219795B11B7C3054F16E3C7F7457817791BD9AB310E6FA876E747BA3F6AF9E80AD06014A6D2F6B8D4529A0633B4D4C2C8664FB7A8F873DBD6B49D481D813B71D6FF5ACEAF851DBBF0E7BBEB23C276A58BB56826FAB8A74C3F7CC37DA538C5E698624C15A5E4CFB27CC3B57258CC86A5D54FE6903CE22178BF84A005A9B36AC5CF79AE5020E3D5A7E509A2B733B859FC21425746C39A36F696B752D7B7D65B32392E5B2C9636B2C2FA8C1D01E75278F687F122C294D9052A1C7F35AFE484AD5DC503B71F247B819EE60957770244D1E3654C600C79EC7CA4DA2A8D01469DE4822FDB1192A354D093782ED30D54004E624B51109B575090408177C1711AC17E779AABD1878FF6AB812BA7B616192A76FE6E310E3714643202753C780B1F83FEE484E8FFF7C8ED7CD6AA424C8C8ECEF1B1149CE636A13E9C2CDF78DCA062BB11AE3559FD627C5C78DB450D62E1C990560AC5A699985A9F0BCBF47328B68463FE60C32F1B5FC613F2E964DC1C803C1B057659F62F7A1081DF280BFB4CB7C15E2E5FE51EF46777DF704D619C01838A45A0B3A87905FBB909054A86390BA48578E42A49FDB247EBB239691FCDDD1A517B932C43C80785986CEEA1254FFC3782E9CBF427C1371858A7DD5A181398746B924FE26D85587BB2A9F6AA4485CFF37319B53D87AE34775FD2A9E3C2144870BC6DA316757A7B91B9750CF6FD370CD01F21681913117A04A7984A0A2699F586BA2D14909EA7D65EB3B2FCE05B5D53A482FCED56CBEBC3C967D88A9C9364EE93A9719E78F941DA9C91CE2B53BF861D1BF75BA002D28D7DA218AEF50D6E457A8C366A301275E5A4D8059977233417E1BD6A0921FED5DEB24417F1CD384AF00B3AAB654C61D353B4F01AACD13F47AC18164894649E261742B71F6D8222F24E7CECBCDA74B6A0E38F85BA6CA8305BCF27331295D27A4C6A005EAA38C23D29370AA37C053D71D03B58F7D7DD73AB04E19B6D0EB217C066CB675CAC07EBBAC2C3736E1FB379E5EB175C9361AD9478ADF2D5EC5C92026FA31B00540DA61DCF8C5283FE58704BA7C3D4D60F055C155A1A82C6FAE19AD4E95738B461A6D11A49D21E94A101AA40F8D4D90583EC98D2B41DAF1AD18BD3A6E41514E313CA810B8523A256E59817665A0C489D1555D382A2E5BA182802759DF12A56DB7B9451479E5A197D7CD7F61F5AF735622B4A7A3A633B16700B97208FAC2CE6EC8156500D40B28631F77621C00EA6DDA7580E4CE8E0E36D581AFCA211B369ACCA07C814C32D89054C70853189AEF7EB9AEC25F5928C70EB0FB4B7266EF39847C13CEC1615615AB6D4333A8C0274BE5B517528E68AA31F7AC2A8C312FD8A97CD52A01428AEF3C871838641164E5BBB83F9A7DB2A93B4CBB20C0E8C79291EC7A443463CD288DBDB559292FCCDA4C8CB21465EB50D1708999876D03F10368DC38EAEE4B3D544D905AC614EB7395C05DF986284BEBEF6106AE92A0969B49B645F6D859E0C22BAB4F0418D4481EF5FD272D700077C029B22DF3A2656883EB8321D3FA8EF586EF5A4C7553B990CE2BE6E8085776F87132AF4A2837A467CBF0FD52B726EDD8EB3CD3732F0A5478071FC98985375CC392B9007B88EF91D0EEE47D958ECDDBD3EE6D247335F651DB7052B06089ABDF1C7C53C467865DC009EA908CDFA799F8B6FC90CA6FBB7C57CD71DAABB94BB896AC501597298DD91E6DE37123819BF60F51704BAD0E53EE91EE8605502DCBCE921666D349029AEE37E4A351EDECA78D62F2C9F24720C2EF3B6CCD7A71EDCA01CCC0499A1BE59B69895DB80CC97CCC7E18D5534858EB33F6C9AF4E097FBDFC2D1CB8A8594508FB2F4CE77C0F7659166DBED42C4EA1C509BD565FE73D480C107AA937DA52EFF47632EA8CF47B8010DE6CADE97619A4B4E9DABA5D58AA126000BDA1CF9D201F6DCC49FB9EBC480EDAE5A9E18FD6375438D0AB21B90BCB8B37F4315BCFA34077BDE114447224D23C8D38BE4FC49AD43D9F4A8780198A1C39F767E199A7A6D808761CAA04274BDDB3CED0C56994AB555886F8B04E7A86D8E0329EFE153C2467C86D8C1AF6A8B968517FA59A197F840F642F94E282CD29ADEFC892710E23A26342DA5671FE3186D6E2A23A08BD7FC8207C490544D3ABF54B28B828D17B587DADB2F184AF2DFECA9BF5938ED222B48A44F0D22E8BFB3CC790FF04739AC85F830F9DCB538848B98A272682DD7B843C732380CD02CE32819DFD9C1499D7504E84E96F18EE41F41BD15CAF1D43F34FCEA37D1D801F4C9FD07C45FF9002ABF824B2C3C1AA33839304CBCBF2DC972186D9DE1D2AE73FDFBC0343379473632D3EB29DA537A918027A340CC7EE214B60FEBC384183FD988F2A2ABD79F01AE72898DCD3E43F7BD4656FCBD0E37FB8E055C3C481E666AC0D6E604E985564C79457195F3D12480D7F0AAF89DD4CF0A1922B4716F044AADFC79D44441AC0D23EB6B576EAF5AECC6478AD82B3E05398A06B4222F5416E153766EEBAD5013F54188823CCA0CDB128ECC2BBCD982856FF80C81BD0E2D980B57A7CDF5E3E42B713D5A6ABC45C9E24DE97B65015D1803832C412E3250B1BB9D581D19C8D3E42C992AF8AAC4CC48C7951048B701C815C78F56C33DC8A52D11F6D66642C9E29EADF97217606F3CA209F9C9550EB5F0C81276E455DE699D7EEE328089B7C2394A3F014394FBA7C9A02DF915921D33264A2F0C436DDDA7D84499B2871B53C653098B64FE8C4AF9602ECCF194A0D125C6DB6B6F171E2100DADB638EE2DE4233F56BB9BA88537CDD4E015D9DBEB2BB1B30D69912517A61C817165B8EDC34B5F03F3C9CF03EC6F4EFE0BC2B73788202675144D4D97EA292", + "sk": "90393A79C0426134DF89DA80C733C58FA4FB87CA9CD0789211DE1E664F31BA75B72D6E6F95CD49032D373F9BECA5810CAFA20CB56FC17B18BA507904403D2CF5CFAC3C3FD6A484D144B1F5DECB41B23AAF9744D52FCD9F8E51AD2CE89629609168C1376CCBFEB0EF1A9489F451A239EFB729A02244C3D7C4EB0DA857CCC7BDE880348D0882618A0649A22249DA104622A401D41864E2B20C4C16204926244B202C9900426216461B9588D1B6049414110B80908A04422428420B4491804440DC4420C2462220B051E386450930428292018BC02C9C106824246844068A02B98D4CC684493070E3164A04312992B88C1C158E08C3489C308A9C1028C0B64508888C61802C0B93494B923044A489083022DB948D5A002924077209332922495094B86863482643C00D52240953006E1C329044842D9C10521985452044259AC40154422221384459922980002218270A200208D2C68C6008601B024C0C9329C1385110B429428441D8B26093A244E4420A18B78C8006888824820C1612094742D3A860C3180143B04DC9260618A30801982C19040C0B4964D2340819364A132961E3268C0CC3200AA01050445013046DCB4491DC42701398812421284190500A956D22808DC2120C0213904040020391889A82881006321BC168D8004E08C34509B4514CC411CCC0881C1944498651404211430004E3328612A069E41211D826115C1005443249C986010A258C98104E24A7250C09009B2211019080A30811C9C84C804600A014668A308C4C360AA1A28409A501402862202984C04851618409E1B8858B168012390E1A812CE02832193121440248541891A1025099244488942101A2255B286611108C843205913684008511A294690AB080DBC23193C24553A6899896299898091B381191A26408912D0B29009BB2509024095B3869E19400C40602DAC02CA2960DD3448048460C84A66121092181B631A4864C82326182B2100992849C101054482DDA964963A820C42424E23004A1328A5C124D8B0826DB126923904101828598068812077204B864D8002983940490B464CC086D1108440947705A32852221899498215B388C4420105A0482839025C9361100840CC1428E84C628E2808450404D08467009A200E0B66958806C248510042246001264A0320804A785A246608B260E5C1830E39631C1B2812082805C38602319289A146801A3019338091C0392C11011D9A601109020DB224491445080A22D248910C1B67018B08419B1299416899A828821354C13C93050448540982CA11029E1942D582288C932804338085904301A238418466844121123078C8440814AB2916232101C475219C48C11042E0425855B80291A1542C2866D410225903670C8264809252648426582C84113394A23258D620031E40208CA8805D048018A30910A3921DC426909116C0B0380210741DB286A118130DA12891A978C1326020C2171602292A1341211158480240C0938851B062E9C846D492408924291A4468C9C4851893806DCB6290A046012447158C668031040581466E1A87063840C08A381228925E00648A01641140912D3006DC116055B46801C450463424010004AD2262C0315729B424D48868019342E04198D98A26D18083193A64101304C01268D502822E1264D1A8771D1361203392A9C428DC2000D00A941E0140124A821111172C8040D8C96600A440884068218428EA42212628248109664E0382DCA1881A180641B429088122610438CC10681222762D3B02913086193B08D2016265880440318119A3012623830029065A182846012805388901C143203256984181222A98D03298C00246D0AA96D63800C0CA5311AC868CC18124A162A52264C000892C304420BA40812184403156ED1984113904CC2A8081C38800C826C58B04904312000B87103344649382C48C050CC440122949189B40C18326EA4306E422092198601924085D9944D94B2695C328959800008C18821B3649C421019448D1A0882D0344C40040AA00204A1840D983652D4004E4C228EE32620243089A3C4610A26320935810114281B45601845086142491CC748A0184D432285E2388499469204962991C62514992923A761601022E32489D2862921A805C004715A402D2044881B21610825710C464E604400A2184923476E19C80C0A449021300054C205042868CAB290CA00317DEB52658BE9EA23E8D1D8AE6C5AB563D01DA20C5577A3695168A3DBC27E610B3529921FF3EEB2A866379379BA3689271BBBB1261CAF2736BD9BAE1F12A5E9F344E853B71C6119628427B790C8C7A1113B896B75A9A7B539E92D8D29156DF366BEFE74DE978BE2670CB07EDBDB6BA156AF6C26C5CAD55A4B44B61517511FA3B74A42FCD70207E532C68C8124E0665CB221AC3EFF05213ADE3C37B8F5A59AD00C46A5E8B11614008FA57AACC54B07E886B7CE9A4813DF22B5C1C64BD933BB76A95ACCE5787DD24816BC7AE25764FA2C83144D6FB8585F5E8895E86EE5650031AB9674F65CC012CE26B950A221795DE8F46B5DC78B9D9CDB4472C257204F32379A823B00C20F92243962FF94E5C4AEC8ED84D442F1F23ACE5D5C5850D0ACFCF7B1F56AF108E6483DCD1334338C5514D2808FF1BC34204C1740FA434BA8A4EE20C2D2A27589FBBF68D889A616FD6DA0C32FA36D666FD79E426BC54E1BDF06FA0470DEFFC93D75973D6A925FA4E5002AB614FFE1E9D5110A2DC3EA5E6096CFF0D46CB5B3B444CF67D3213BF7A139C41F70DFCB57E3490B84CFC51FEE7132FC86C3C44C193AA9ACA24A96A860D5D273DB96F35DB99491CD23227BB51105B3672BA3044457642CF680BAEE402784D2A73682BC28239BFDA08B24E4B542D5B5931F4B8CF4CA0A15A3F4012D9C0BD5FBD893543A4271DFE87E77C706186645783DC23A5BA180559C66DCD151F518B05A98EF3C64804869A46CBF41702A3E403C94B948D2E41510871FE7A159290BA88692473223266D462856CBC9280B12777CE80C8013655F6760F5715865986C688A336EFCB92E20D40F7BAC3BAEAE5DBD417627E3E2EB7D0D8E7D413BF703BC30D4E3D594C6FAB695F93B2CFECF0EFFE92D646083B6BD124141CDE5236E89579E8C76BBDF9681D80D19061147432075B4C755E1102BBD53A2E9E2136C2B02BFBA33F26CE1D39A3385BAAD5A5F8AD0F9647DC9B2E78434AE8663C7E9E14797472B4A646C8FF18470272BA12E7FEA3AD96E4E1F486569F26C60FDF7C2B4D3AA0756381AC8346636021322184D6B0B2DF793917041D152C025317A6E52134C955E21B623FC15AE57BB77B5A1824448AD18C30212390E68AF28E06A287141751C708F8F2CD6BD46FDB940EAE5F4376D8F946B9FBC8D31D1689C0EE560A8CCC84205173307B5EA39A502A9DBAA861B2CF90EFC3BEF7E3A74159ED7E5993CEC4F565626FB84059C358F2110AB4928454C4692195ACDA560267CB505B69E5F53844DCCEFA5D64CEDA4DCFC3F92A63D163184592641C2BE726FBB32E8754A83315039422681D2F902080D02EFB2D3D2A5A79822132126B1FC849641B6D2D0E56A42B32BE25C4F3CC52C7C17B18B039E51E889214A86FF898C94956327BC3A265FAAD1E1068C7C16A3C870FA03CF3FEDA3FDD9131DF340350F80E7F0CDF4B7210E971879E3E2928B57DCD40CFBFE85B147275EBD6924511EB293966BA6E42B67DD97F0F761E2C0F1B58081E0F040C5B832967B6508DB8B7786B238C598CABB104441B52D270F1F5FF333C3441337E925F259F2347A53D50CEC83065760A4E5AE4DAB5AC16A402D80C8E429FF2A90F7B5D3DA698D82DE8BD76616345B53967FFA2BC2882E4EE25C881382A4D619614F6870532EEDDB8FEFCA9A19FC809F5C6758AF8902D1E60092637AF30237A66C92FD30627AA51AFDE86B581E14D86E79B50162B7443AAEF8E4A2B3872E26FF579B09740E25CA0D674B229D96A8EF0A3FB87E8CD75AEF7706750A67C6F5A7639CDE9178CF37885FE9774191CE41A22F57660D335BA8D1AD5928103827C7FDB74655B0B7B3D3CC859A26FFF60AF0DB79F3EAE481A0472E803D59EBF3BA2C85A5B995C2CE3F0C04A7E2676A7C01C10EA1BA0A351383FDAFACD11F3F5403831704196974A4643AA6B0B57DF54B8ECCD1B1814BE540A063C7187B573D0DD528B6596224D0A9BCF5701EB056A345112A7C393A797D1C1590280EE7C6764258C4B151559FD0719094AE037C4B62350D949FDF23B7B294990033EB17C9F70E0FB465DD2F78279B7C1C313D3FCE7BBEA597CE11C5A47ADCF5865CBAD0400D0CCF8F7E0FF59F5389799D08FAE155083C2DEAE21EE6E5E72521A09C5BA7149F188F46E20ECBA23E982B7E0D28C92908B2213C6882DACC7F056D3C285FB8D6BF6EEE57AAC0E36F8EE51AF5653FBB1D358E06BD804115C0DFC572ACEE647B223A2FEED76BE581E439EDFBDF324356F7401841B3E1E192D7D3D8E19D83F757A20FA7DD4AFECD1867AF33340FA43537F7BC0F80235C1CF9A9837C94D7BBBC0E820AFFA4EA36BF685A82EEE6BCC662F94E5EFEA083802B9A24D3E9422DE0DCE4CCC298E4329B02A3956363C88E555816510E7B642A421AB4F768D347DBD05A5B1A903860078F105A7F0AD52DFE7FAB396FBFF271BCB5F7ECF387263CD0114299ECB39559066B78958B130CE25F1B9A75887F188C43E746FAF865B4DF3EBDA1304C70815AD16FE0DBC96F6BB61D659C7E80D7A46F6B1F070409829F69DEF6C1D87CAA1DC71273034D8C3C22A4694D2992D9D1B83A71DBAD8CF0A6C2B4ECA9DCD53A827A5D879B8279DC3A52E0B879293C07FF2E1DF21043E919E2449B58D75A3634E008F6D10624A3CF532F73BD41FA73571771A8278FAF79A85EFF2A2936D31BF878D304F1736F6851EE824B87B23FE9D2FAE453BFFC27757ECB335BFCB8B0B79C349DE2726AC7D3AD77C509A87BB58ED8D49CFDCF27CB80F2F9A6284BD43602568A095245C787F63BE998315F6FA0D2F7ED4F138F07706F4C9D41D9A5CBC83E649BD140BAAA55D15B87D40769A96C5E9BD9B21B786D37BB9A4D6897F80C8B89C3F3AB69D419C7DE651643CA76AD5342FED2864F3DCDAEDD6374DB3E8D044E10FF48BFEA1D5247D2E1FC075255901710801EA98404B2E0A009EB8639D1D2BF09FAC2E7163CDDBBA6C277380E786C076B762A3DEDFAB38497248BE093FD03C1259C7B770CA5532B9F0A44B6AAD5176B8D0B04993B5B76699891ED7328D340D2EAA4659D0C4A3D90505836FE0C7B7D424D2037F04DA135B91C6291FEB6B4CC190D21465863223D9CDD4D11FD8CA128377399D093768FBEB45E3228167F457E28C88886D4A5DE85E0509C0E18DF91BD71051605A51C218DB2DDCF7616FE7E61B94137D59ED68414C3012C67E0007110DA0DB233DCC71336FBF40FE2A73DF2A51639EE5546BA7EFBC8242C3093A6B6D5D96194501B72FB66B2E47806F666B1F6CECD83B8C3ED04FE14A36F218CA8B67FE20FA0C113C33328FF34EB87403E705257281543797F2EE63C7E23985F5D1147302A4316A5337650ED4F5AD31552490E1EA77A361A0E4017C51297F0883DA971E34AA452D05A44D3AB141D652D25DF3711D40A61167D8034C40E638EBA994F62769FA890D38B624076AB1260E718CCF228A338D255D24890A5701D6A80F8F944AC6AB6289D1E7D10196A173CFEA4D4FB6ED1249C11B1E7E6FEAA15544350520858314D3E0341FCD1612D6388E0079B385B2ACDD20A227A18985C27061217E2CEBE13D70F849F2512EA1F71E987BC4040002A54021B311DBB4A0F326355933A8B51E43A1B51906AA48D02B379154A47B9081F5652F418D39F4C8D8E055CE0AA5A5FFC9F6B9217D4F11D96B3859A28CCB7A4A9A4AA5D84185130C56FEFD6CE70B8F28182ED42244F8DDDD036CA93E81B31C82FD8567B2B927BD1FFC413CA02A58133475025C0D5113DCE589A0C159B0CA4475011B45C849D4D62ED00F1F81FF207C04F9CA3B8EE0308A498DBC81215A819BED2049AF1915023E72256209C924D99486BE97F6070D11CEEBF425951AC1025A885D96719D92D821C451CAA37B8FC816FDF716214AF207839FD0386E332DEBA3A94D1C583805003729872B5A9E9F1E1129C26408484BA267B48AC341DA546512E790BE48C05450F7462518BE0EF47A8D876072D4235BD7B6A4CA27A4343E6F0CBE6D5A39C9F460E1AA92F8A7097B60AD4BAE9B98DFC435ADBA536DCC0D413109644DD9D9F4AAC0A64FF68E820C36B0D151C3E51D9D98BBEF1A5740699E508205530C49FF5AABB0E0A99B8DB59E036E251F1966F86751F5A8735BA1A796DB720989ACA697FD883377DB331BBAC2736DCADD0F582F5323E3634785D777E6D41D73810934B78039D60259FCCA4B51BA231B8DD07824D5B3964EBC618618492A3E97D060FA4E2564180A1A91975C35F82E251B39650983441C7EBB4EC326B0C2958BF1DEAB2EFF0C959B9963A4F54DF3879C0683DE30C36E86C910A60CA95908434A45B5F76C5DB263BF5DF46F6D408BCCEB3A9F402FA12DFA99D756749F8CA0EA717F0F9233BAA282077BF46E93C81F4F66CA456E7B40E671848B0FDD01DD3390648870FB0AD807023B70A4626EA005771DD1095E306CC3A133D6FF7D645D2E71771FDC98A65281F0ECAEC106B9E6CA4CA473958CD65CC3875759D0222634E341008556409F022D0842A99E556B818EB631B99890FF37047F2ED2D3FC2E07B5DC6B72DB6C2F4E19636AD4C81E857F22FE40383DEC6BBA6D9118B78BA911498427CA29EA4F3E14C6E41205F1A89364CA6BDD12BEE4EF87DD7CA83890223C034B082EB6B2CB91E5ED225F6AF0D75D6BDF3DE95B55FDF6F0242B140EF5D45194A8FA13813DFE7BDEF8208939C90F71D1D68C080221748A28E" + }, + { + "tcId": 60, + "deferred": false, + "seed": "4A74BED90EF52CF135555B622A50D1A4F5C53D97D3176A1B184CE55380DE6FDA", + "pk": "B98AA05F5BA470BE6BD49954D496A45AE4710FE024C61B16C8600672106310AF6125285BCED3A9A3EE9B63F6A6732A555ECFDAA74437C0FAED714CFBF9690AD19A5D9B9E51A87B897CB2CA597AC944B1BB3657FD93DD44224A276E14C32AE838EC55213490B2F9F53B7412107A1D05D6758D487FA15F6DBF7F549F8103349D89B5872520245520879B0717984ED29684D4DA55E84E7280C297B4C7F3DBB90A7FBE7316ED6B1E075490A227095C4D18F50063781BB8A123B6407D41DDD071EC1D18607E6B5D7913289289146566F94A7C0FED3EB2B712B8DEA3DCC4CA3BD088ECD2B78971D823D661D8A1102BC9AE5164A56543FD4E2EE9C2F1ACE76A2B7285E2F23C0E6E66E5EF400E5C2DE9A6C1FCF6E4D60C714F5AD92F28D2A3209D4685C14C83380E69DA9DDFF1892D2F9BB9C9E0EB98E8E7E3E33BBE3D8A7999DF481F4B7D4857A016048D7B7BE2D44FDDE58DF6139FC8A1D0349407853D45D18630A3C3F7033961C06E5A0DFE4C449ADD2D4F66BE3BB19F39120535C9761353C5F5E695001B081CA27E1A862415C19323060BD436863669F6C1C75AE0CF896DD76D3CA157C070BE86D5B80BCB3CE5023B810F69BA4E3D54EBF2E53B92741E0E1E3086958FA66172112635A60EF6734D8BFF84A2782333586D66429437622F5CE059B210256BA414A887EF5E90CCECE0D6E9E2B294ABE6EA63BD9C26D20E4AAC170E5594A2E83A96A24BAD2F69E706E15E7B1BEE6AC92C7CF1B9AF28BF06E1EDCC572740374F4DE8DE26C06DA968F0D79C4454B12D28F2109FACDF8E1E0F8802026AC78B599929040984297F41DDA28AEFF18C3DB837E01F3D12E3752427A9068812D75C2A97263146D60DCB8333BCE02552126D5BEAE37F50BAA8FB23DE4BAC3C7BAB3C21415C1EFFA6E62E9A3DBA18F8302939A02E82B8284D104367F02FD4F484F98A0C8A2CC95D108E9EDDBDAFBD53F5D7D65C6CCA72163EBE58EC15BBEE65B9B65E3A5D240898C866960DDFB7A381DE17FDDB9226129060B5951CC83430F806A960D14F5935FA4371959B04E77EC978B09D08449D6DC2C3FD8DA655F4709198BAC7F2F42C4CF6C8EFC6B8C4EE37ADBC51F56C36D719CECABD5C3A1D63D08E6EEC48EA920D5A3FF93C2C716A76E89A4EB7946D935D859DBC99CFBD4DD7E2A36E8624B83384F7707467E336C10CB05D407A2D97EAC3E1A632C7348E8DED1EFB9DF72B4697C44F10B11111728E4304BD417FC174E85A69E8A1800FDE4FDE40071E2E06F725F11FDA67D67E682DBC3EE5DC866A0F7553F9E386AB08D2C67CBD4A6F33183F7C6631EB9818CE4620CF08BA747C61082AC71D5F1D055D91BD0C2FA96707CAE162614688E37B40CC707FE6C9EEC8CC415DDEA6E68B6F49C137B6EEC2F51B4E9D0E6A2AB2B92F7530E146F8BDE6D4CB559AAE7F8FAE27468E04ECBE4F85ADE29CCF20FFDE24F04C4DDD8C2A1E164769AA0B5A6A98498266A1BEFAE8073EB9C4EBA183AA71D6C98AB4F9D74614D259853E029710C5BA64D74C866EAFAA2AEEE577BACEA272FB76C40741853FE0552A79C6191BC40CB6CCF914E0B85AF88DF9553EDF1DF6DF7EB72275DCE3A568C4EE85E9731E44F470F00B2B95630357011C5084381B1FA5D0A55EE8D4299D17394083BA42E33778274F171A3CBDF9E0537031A272F04B283BC8F1B99CE201D9AF085A2CADA6078C7DEB922CF313065BE6FB3ED204F603ADB18395292680ACB6492DDD602EAD772FA22250FCA54542E3D68ACB4263DE0D2D442359321C200B798505E809E6B219FB2698871AA2A698544BC1C79BD6E18F8A8AF0B64AE7196D5640D0A1ABAEDA9B00CDBAA4BA177BE7FF03B0719BD489AFDBCEDD091AB69AD1BB66EDDBE03AB71179AAC1B766F14EC1B7F27B4FE46F2273E4D5EAA63DC3B83427423CA032D2BE29F057A9FCBCE8A747E59D6A5E20982B91D63C85A460E82AD028D93DAAB42DE00DA48CC0D4BE3AE85602C6CEF78BE9C238C368438144691A40D6A5A4A6E1DD19931B4D21FB779A03E86792BC63451352604BC177A8BD0DF71404DE42F5E35E6FCF96503277D09A552ECCC611A2A053887475EAA290ACD2B1F84878651552A796491E0A6E5C8270049F45D3DB482D4ABE5F91D89D5E97D985EE27BACE55AD9FFFC4DB7696567E86E8BDD799C5ABEDA6705561320EBEE7D0D3FC4203E30376406EBBE0297FEDA3E1BBCA5CB6CE1D1021CAF67BB9EEA84DF563D82B012CBC8D24D1FBF9BA366DFC1758B98AF3A3F68D0C0BFEDF4E76EC3C8D1D56B94CEA7E24991A44D094CE30A4B724A29645046196DD122727C26C96920131CCAEC02D3B45E513DA8BBD993DE91CFC10EA98A3362123FCDFFE536179F7063CD83F42D7047228C0CFCDEE216CD560BC5913D734A10286E05BBEA15CB293956F72BBA3A268303B43B6ACF89C20695A4786B01A5B8392BB975A25A6BDEC91BAA13F812567184AC8F3C0B7057A6409C0350BA92D75AE3030E2324F2BD82F09B32B7A38EE611A7B583052CE2C967192D7980F8FF7C8D826CC004CCE8ACB1AADC7E141BD2095330B7CDCFE6E3B0A7ED0A66DA4B00592B3BBCEC6414E293587E970ED78986461958EFF17F33C5B0D7A87437CFFFFC0EAC405499F12F6F4C54642325EA2FAA4E1FDF03FC9C8F26496F003289E4ACB9770DB201C92E5E437E4C0255C302648C38175C553ADC0F77AD76379D046B11E839772095805C6948FB219B9C26EE0D70EFA301F8096DDCFDFD0651FDB69F55D75F2C236EE5EAACEB2E5AE020C41B51F6329094F7B5A42C41197A574E4656B7E0D7B7108E6B3EE10BF44AE7D27E846F14EED09EC3576226098E1F4CF4FD5101334731411A1E3F438C9EA9350318331F917E0276521AD2C584D4F9AE1378512068AF29F497E4EA609B1FE0506432BEE5DCE18F7E7B83D0E5A9127F6071AB16196973AFE681FF9311D23B1CEB000E3E74D7FC7AE3B9F849A1052A87D3B6B28873337EE3A2094D42A27509E206C5DA5DF4FABED451F444C6E9699C6D4381445423928589CE9380FA8BA0EA486A8C97C5112086A4F7E5A19988CD01DE1702CC0C23ABEDD443BFBFAE11BD6BDE59D81B7A5749F4D246C7690A2656198A3371096C0AD58BB9011E1DFBB234453507EA439C5E967999DAFB04D3F030FBAA6005600BF39316A356F2C2A1FCF3365E2CD543C6F79CAED18EB04FC3BF02D2A43E69ABB3D58305C430E8482DF659994DED02814DA9FA99633979F281E218386CA9647B633672CA3232766D671779991E43BA9E8841302BDD269AEE2A6D99D658EAD444F1AE5D0BCE4BF4EEE91E03F1C2E29AD5B9F859A36EAD0BB8CB4D01A49AF7AB54CC9941DE0FB5DFA1EBDEE2C1EDEA77CB83606D77560A41BCBE9C2D43D0282D850164C4B6F2AF3F9F9AFBD7B53805D7BFBD8FAF8331864F805BF7B1ECFB72EBEEED31FD1877DC4682314730F86671A39275BC094CAFF3E9CBE4661B7400F3090AB9B638A9FF77B9DC7A5E43F4D03F2C322DAE8F44CB5CDFE794F385DA446C62AD9CB0833A7878A89968C01F9E67B3914D543B65FEF59290D107B5EDF2BAC0E8635B0BAB6A9D3FDB9A267E8C4A735EB1EAD8328030A77B497EB19787034FA2FB26CC80C9BC6AD0E63A83156BE42BD0A658F693D4D1BF4F85A3EECB4843CC7D58FA3CFEFA7C8DE", + "sk": "B98AA05F5BA470BE6BD49954D496A45AE4710FE024C61B16C8600672106310AF0DEA5466C45F3BB6D76E10FDE27C71282CC6E74D56AFA21CDB31A104662DA91A615553612DB8AD8F6D8CF8DC8246BD5970A2E14DA5EFBCD145FA638CA1945F5657B4CBFA716DA133C1D582C9562302A69C19C0DDF2925111FDEB189762B5259590B82141362452462ED9448821203110C0914C3632609010CA408210372260C209D822488C2042A13031E410684A460923C10CC0346590346218334D103462C8384C840272C832721C2372C0C4289B109298449019A631D146840BA9651AB284C14466C946069BB869E406445434106420658BA220A00081D418901886448AB82C40382903C5216334858C848848168E188451C1000159144551101040064520984544066019B98518292ACB185122089224C22D1CB16D44346EE1C66DC2022DDAB2080C894902374C11428042902C09314D0C212610930C8288041C3525E29084D1004890203221332218180058128D1BA56D222106242106CB46608CA068D0902DC2486EDCA6305B10405298410C178CD1A20991284C0BC8691BC14800A4848222298246840C4952D1448008442644028990A64C0C096D9A0481224471DC807150164400420620070840464A22244C82845109258EE1880D54265223324050242A5A4621122940A3A249D8A44C13C44103232A59924D61206A23362812A6440495211210865420406418491032411C082C03051118498018A76C9B220D03230C242820C4A81048206520426000074A0A150C22B14509430DDB008C60367081884013110618820801174A1185448C2840E3443193B060DCB4904486658C9291E1862952100A0CC248021560E1348522C6914C184D642281E0006C11212109424003234451408102A44041288E60262A01022E50C460E3406C124042D2488C8A00888B182EE19820E3481158A6600B464850B045981291D0882C0A4668C3208AA1384514286C18486D0A090D0C2765DC322D14A51122A644194845A00085DC908DA4202E18B7501BB481DCB6414A2282119085DCA64940A884444422E4326940802503C1600A008A4BA205A2262E1440600248645340825184208A14020929080049268442320B3131C10652CA981090462018A8444C4280022552DC462009325182C41091064C502031594881022904C4884148241114B60C08C568E38885D1B829D9C8601146129A0806514280E018200B2424410821C316400AC3681B235084B4840B014123B468083722DC928108129288327123862C180986CC22059B1480A4A830014624DA30080B33044148221BA148A148111C12118A068482C268242410E03682032765928224C2164201B160019968990268A2C028D1488E13422E03085263188422263289C48CDC428A03033119416512A5910205840882848438601A010E22A4281B254142A09192866419384D99C06C8032020BB780521652609881DBA8311825010A858008860C012708041148034620028111944410894200A1202464A009E00424101330E2303092A8640A460513202604B6480A962842C40960308A8C382602A408D23020CA06861B420C51B8288B100D62A830A2280143C4289C842819038D5432442385500A10901105614448519832820AB42C10490E5B360413498ED3482C8024699A3831A34468D4300464C4088AC4609436641BA70454A005A1C264D9126A5382281C062C0C226D18C36054C271898210DB808489204024A48962C03199367200B97193068110A08008A4281AA1249186119B40909814920B8571044485120685628420A2209194964D90324511A80C11C02490926900A8442023610B85858BA6004C142A14476604032460B24558380D0AC91144C80410834522387201374012460E031720C148321044051B364C8AB40D59064C82042ADC424CD1324E18287023162E832246E1A0241A3632A1182E50168263C06953B2511838800A8545C21269E3847124154563322E91020DD10469CC180523218203042D041865D20492840851DB026918462E0AA48C0C100A5CC688003311020422D4004603104EA12828DB028614110114242500C951214232E2384C14214EA446024830108A024E9940250921912489659A400613822C40C2096148420BB524E4A468E4A42812C860D32629E2464E2336900397011B80500A0165D4004C79598BA1392FFDC71C568B23C0F83C7E8B9B0A0A1FDD95163EE61894F5A05160F60DD59B40B17610366DBA74DE90016F765146B645EB2066870201C7123382F81B63D9C0700AD3FE71C0C920A8BB05E1A518B64F2F14801839ACAEC7D93FEB0019DD04E20562228D27B2807DE75432BD152AB4A8BF948AEEDCACBF55DB2BD53712ED63F99ED7DFD3D964E73687598D3E8F3874FA2D96C4C78067F6561580B5C725165EA7C6639D1041AEE5DF55BA3F8A78644DE76FF75854B5B1A3D087BA2DAAB0473AD6B3470CE0A411E4D2D804DA6B3A1DE69A87709A8312D56D74F8ECB01300E87BE085DE012148CD4FAB16765D7597890C3418034F43FA86325E2B8A883E84A315C68F6A849B863B7DF98F12D2C1C3142A7D5E425B25CBB9D761536AB1F0B149609D00A676DA927B96FB535E7F4BAC62243E29F97451FD7B04DD77DF10205EADDA73759BE70C2BB6A77778BF87A498C19A90B984BD0BEF97BA41CC4B12B915EEBB0494639B778F6AFED1857ECDECC70744EBDBB713E27AA8E87C67A0C45335B9DD700CF964A0316BC86AC91136BEF4530502A514F5D09AA73B2D94401412AB868BFA9FC7DA00D0F14245D952EA61838A7E47FD508BACC077F33C5D63EE1EBAEF84F3DEA9B7178C658FD5D30836C6AFC26234D68902716325280ACDD60FE4CE7E2B0CFB7A977A446D33EDACB8D799FEE0B71F7AF5E857DAE2373E903FCF846CB701DEAFC0E2CADEB666C13B77FDAE6807741E8AA2525D84722D07371F5CBC62574479780DFAC890ADDB7992A6930164DE9ECD36A5324D10100CB949CC20AD8092BE87315F5ECD9F1FDB1510ED1E2D073EF11A46CE93BDA2EEECA21BF2E273D2DA6E0605B2B29226982E62559E41B97A79EC72E3F35C5F847D13969AFD932C9056FD9CD9D75FE2122AC2DFA155264B8351A53868E097DEEC787B7C9DA89ED0A5F7CFF484565347954885535BC5461DC99EF622A8E261FEEB199FC4DA9D5CACD40D10015F1121D41AE315FF43407991256A74AC34FD25AF729AEBA375FCE2B8C6D92DE71240469DAEBCB0F258AC84292A3C6A3746841C5D498C5C0D490A29D4C1A29AE7A58BF9EE38DD76F91DFB357F06D9E56ED9E6F489C3E18A10785349A92126C236F5795EC6D755F6F0B36AE0FBA1B9548219ED544DF5CFDE3094B222063E416C8EA42B1DF7A1747627AE479E026205FBA28247904FCEBF44D8C06D276C163368ED2A289DE6751E3868A8BADBE0A0ECC38A85148CB0D4085B14D8760C4F928DC5802D02D55681CAA1BD468404D925B6EEF482F760C5B46FCB8F01F5114766F591E813D69FE0D51F58950B84FC2BACF7CC12B07703DD927D322F62CE7A8D903B3EF1785895F9D8643CAEFDD7449CA5B3EBD05713A202B403BA684BB7E3AC3CCE1DF7CC50819E97467827DBADA606B284D9EF2075666EB6D5E4E0315E8FCA999A12B9F1168913D34EC21FF7CFE51D161A4803371BF3F22D1983091B29B4B25D5D57D4B0045E35259B4281798D365D82F678D8A2CB8B59FA0578D183C6EEEF5426B831B89560E6F580BC2535BD184F301965EC3180156388E4729AAB4219F4782C94627FFCDEDEDD99DEB0B2CEBC9183A1A9181552BCDE74879C22A74710DBEF84CA97E1E7AB3F55C107A869662C14549B411D2E3FC3801AD44A2D4C372BAEE122462E87A1AE73C2DCF94771619F1BE13609998B9DCFA4BE1A0B5A587EFAEF65343DA0E6F0C9AC6A92D5C07EFC32806816894540DA7B75AEC207E415F350BE6D9F9D33FEF566CDD6C3F79A9071DCC18FD5F7E75CC978AB838499A7E6DC3B774261A38C01713C167893AEED2CD2A35DAEA944F497BD35722953C8CD1C82C1687AAF59C8130BFE0B2D4E7F4975DB8C0F73B17A067E4D51AEFA87A3760F91D4B468A68D7FEC98A17D0CAA58C2B30FE28F7D3DE71ACCE60024C19A1D64E97519BF5ADB6D90143FD404DF6CCD0204D05FD8AD074BF4DC841CD9D9B9C02B59E273E8BF2BA451648AB8AAEDB8A4A9E5EE5B4027804169205085F59526019DC7F1D375D40AAB078C007D674E27079A3E41EFDE7FC9CCBE11E5BCC8A3F541E20F1B2C32C4344B4580D995FB46FF8EE92E552D706EFA3E39144E48625619F0A37C39510437A1397664899216472F49D11626DA0A8B9571E330BD55DD7DA37D44ABD03328E6DBC06A7B79AC2F6A70243013E83321D0FBA0428173508D1BDCF9D2303E46D507501121844314D1B33A899A85FC8DCD0E4DADF4ECEE61C3F3AE97A2BAD70DF14B5461B091D3847A63A9236CF0E0F8026ED02C45333B314C421A2ED66E1699D844B9682145AB4FFE0A2C7F49BDBC3116513900A665B230A0A39C42078F7932AE0BDA22B58AA96E27B7F5F608497823FB58319EF4B2ACF7E3676ACE2CD1D7A1D6C9DA161320AD8B2BA1507C3B19F226E7E8496817B3DD84953B6AD645161F6585E5F8B866B12AD6B60C25FE0E653BC5E5FC4F925286668373E5D22521CDB20FD6D76CAA1C52BF1590C55D7FC0D7AD3199238D8DE9FE93857779B3C719648F9A27FA461F61200A0796036B43AF9ACA5242DBD7858AF7394F09D3B2D71EC7174DA5AF7361876416E222527B09F723F5BA70AF96123853E6EE151511202B6DE6C88847478D059C5EDF6261C2A2689890DB128603F0CE1B1929A968AFC747F52F62B5A1DDBC458AA366871197A94BC84FD22E26506B94BCAF8E229960B4A058B90927AC0D749BDD733E6D37D1BB83FF1799588A9031995A03396883FBE7788549C8F9D3F92BC4A50881FE6345FDA1C71F281BD70BD6B12ECA40828C34283C34AC72EBFC77A496E214878F29BC314121C2005E42D5277DCFB69F35C6D3C1F7BA065CFB2A18B32C00042A5F9B8E997202C8B35669BBD0ACB761939FEED5D4D323DF7FB9545BFE5321E38FAEB18C0DD2ED061BAAA890C992F3D0CC505F656488C2DBD4933169B9B57924AA5C334B58E7AB232B556C58DEDE837685D394DC404337B693D8520D41C2F277717E38190A20DD13F520AB64965EFD8A10040855798E97B9CF0BAB8B93FCFE1AE5B22582CED7858AE9159863EFC6A868C9F4D828B3FB5BF1A581F2282609D2796E771EAF96F48A2E42DE7EE66EA7A19E19886768444A10541909E296D6A7F5D1F025205DAF70979BF58F5197DC4B9F2E1FAF62175F14828259FCC16DEF9536AB559DFD7E61A4411C0EE1BC926CF41433BA6C008FEFD258D9DF032C476C7BF4A739810FDAC69847DDDFACFB46D3478F9AB34D92B7B3EDB6C7F009F8B71E99EEE78723B89CEF33F6521CE6F48B87EA2CF147EFB309C2BE1072A0392798789EEDC1F4E4A176DD68047ADC0D162C3FF71513E7FD5B2E38218705F0F00C7CE2CFCFF2B7E6D4A2DBE506E5F935099DF85E5695F0377F32D1DE93247C6D4AAAFF294B34374D527D492B5D9A30328010232913AF86739E9314874F4BAF10EAD6D5972B7C3855800EF2F10EFF5E56E4F9200B0CD7048D5B8BB69E90C3890CBEBA8E1A3C1AF9A8307308A5A10F305024FD422751B09910266C9A0FB0D81913337C2DC465B602B66572AA82C9FFBDBF34244C2A0C6D5BA00D9C4355221E0D5203AA28E5B494434EF45759815168CCB81016735F0B94DC6D8FDFA434900DFB80A8C2AADEF9AA73D47FD68E8B90B01CF2C2FAC9FF5ECE3D9CA6C70CE3771FCEFBB0A337F09790181F2122E8C5FA5B4FBF3C3559007FF5690987485E10EBEF40F252C4D9857D6E0DB2547BF0406557FD917B58D4A71A1EA69417F5E328863775F2B8692B11B68157891F84E0445E16AB94CEF77276D48CEB70A1AC4AEF4C7098733470563F1A1039D49B2B9DFC18364ECBD665809BE39B11B9E12762195C11B738D1CB69F09BF48C6F703E76A1FCB0B11D99ED4E319007C1C66ABC7AC664C9BA3CA8D4C9A20CC53A0173B6C740A70630ECB972F8952B48BF199E132A7648A25E27C00D7B9220F961ABCFF6F3A77B68E503A1AFC043DED5AF9F19B3FC8177CFC28E31902BDA123D1EDE5C892738751145B4D94767A2181FE4DB7F24C86C13CAB82420CD08BB5BADE24D5278F80A4DD7807D8C50B8B1601DD384CA1F46895D55B69516EFFF67061837D33A27675AD7A50CB89064506841FEB35EB363192256784F21598B3D883646D22D6A95AC355C8397C97350011BBD81DCE7DCBF5FE5C3231597643E3FFEDC213AEEFBA6D11B525A7AD49896919EF497757457D19729F41B74ECFCCDFB8694C0000CCD5A91239A67984C73279CF9D82D220BCEFB796E9E0A5D6008F75E5D03EEBA99A6B935BE749C2EE00B84A01258AF84585989F80B1F10D99053CA685181EF33B879148E23ACAAF5C41644D3E964C0C429488112C2133BA871D9A57E330CC7FEEDC46EFBF7413C52651717253B48EE6D91D8F24888DDB3008FE90F38D66CE819BAF939768206B04CE53DF2E7895C8D391786762DEEA768A4FABD4B49CD2858E0E7BABEA35724056049DB8225EDDCDF51149AEBDB714ED8CAA43C3EFE989625F732267E8BA56C1B16EDE1F9763B1E33307E96C3D7642DC4F666077A634E15A1314582EA6DE272EB28EA6ABCA7B57E84CB7FE6CB11672E52B8EFC875C0BEBE2181D216E09F2F9487B0A9E6A2F1D0F9DACB5CC2E6C1E19009ECA080879D5A7864E472B34B686DB7340953B607947CCC5E97EC686B747A9D19A29C3CDE7FBE56B78CCE04FF027C97EC85208DC2AEF53BFCD4EDF3EE1067CE9AEDC8" + }, + { + "tcId": 61, + "deferred": false, + "seed": "779C11F3F4D148FC911E188946C09E67EAA04DF670B6E0B6A96B661FD84E8994", + "pk": "620362188E854286566CC1DA5EC6AEAD3E5DF99AD6983669FCA4AF7174832F57EE66EF9F649D16EE8747A2D91CF0C6ECBCD7CE3B1559F864189045E2F251064D890F431855DBED63AC0C74EFF29C88D8CCBF3E8AA3ED7A3FD574D5A0AD7B7C59769B0F67BE603EBF37342C7540AED84809F4792FA42C865ADCC4FC51349E8A5FE54681B3EE84B7BA7D29C1A5D16364C30E966CD307B2AF7B2CCF6E5CD817BE45E2AFEC0E6AAD11433B59EF2A1E292DEFF179255F784EF841F6AA6B69B733C1D1C79A33953AE6119D7F63C1AEDB95D7E359493FFF919EC41B76C615192EF1161C4C8D936F7269ADC4512FF0191FCC6B9ED142D70BD7B411D1401CE1D2CBA37CCFCB465166512FB5292F434E2846D9164C2E903036284D0C27345D4E220908A7980318204162F00AD9B9F3E32A2F679CD83A561732F7601CCECD030462888E13FDE4A6E4890F277F6F949A13592DAA87C9A411C222AFB38DD901B87D2FCABF9E21AC6182ADAB425685AA9728350F608D890A0137047311C5E81932D5925FA21C0701D4ED3156AF0C88341434010DAA0C544EB8151322044DDB2AFB31613E817583B3E68D6F7F97C63D6566A2C6BF7A9C55CED36903E9CF8087A2D43D495340A880F9C009FDBB66EB831154FCB39C81DBA120E0F97D312696493B0A61A495A77052EB20CFD65309E96E802318FE469E37DDC6B321D7613F60BFC6B7F668C6E13D0AF585B870D27480835AF9D70AFC0F1915431987130DEA79D1AD60DD1D7180CD7B42634847CF782C2C8E9C9069559C5B5BC6734078BD6485444657965C68D2B453039E7F928BECEC1852079917EE1B1B268ABBF29218A9035DF83CE5002CB2B7E0A63CEBD08F488B40C9013C0F1291E12F20747F326472A60F6494E7E1D8369A4B43C3C1F66816395205F1566593AA8491F3202E79CD633688F81D3EB2D299A97FC8F8C392B0D9493C2CB4A49B1453F4390089B08A9B13E45035BD7A2ABC486F7FAC3B66EF963FBCBB21F514B1AF3D239F4D8ED7978BC89C73377495B3EB21B374887E29C915B8E24F93536B194B5145691F55962993D4A4849D8D3102E18DFE4C14882408813B623461F8501B29901CE4457EE2E5809DAC8F44BD8AFB435017E9A9135479263D3F3175DFD8852CBDFD4CD5B83A752787E212AABB691880BB3549C9D67B0748111BE8E87DED3B77CEBEC42480FDE9C8EE9063A06AB2A221B9D750511C74F7C634A40D0EC5A8173DEED4BCD836F77C6D2A7C813032D26CAA346955C5885D1E867878CBF8C08BD20DF9B0A5ACEA83EE438A7869ED52C16F3157D7C8C74FD3B6587F220A0B4E03BBC497E9AF5E9EFFB76AC7726991DA18E8189B3692EA97120161E7F6F7367B565985CDD992E6F378901272FD74C516A4E6A416FA872CDF76F18FEA2E07A614B364BDDA76514F2C6087A5A2F066909365591ABAB3999A2CE216F54FB84EE5410C6E4A35B946B8A4714D052E036BF69D8B17B63E30E1F9CEBBA5A169DAB785CA0E5A5F3CD22EF42C78803F87AF3A8B3F94E86302FCD170AE49F7CF56C2EC86873038717D2762D12F15CBFFD37889FDA773D5929D2E0D9EBD5BBFC48FC18CAA1FBA3710416790FF52AEA2266AB40D451B419504B125656EB5E3873A424F5CD46A0A11933DA8D71256FA9C6B05C7B8C8B16D869F07553AF33495ABD2B6C752AAC5CD3C9367CEEFB9C2CCDD81F6E5D68A23213DDD8D63E21E2DA9FD77C621A500451C6E5467275B2F68D9EDDC54E50A85D2CC0D4EAE55FA61C7D2C76E0641B230EC4437AD5BE19D6C9D23C6C9F854225894EF6F8DB7D4F0EDE60D239873B85153C938A4A6E9D187027C46B7E0AF04BC0E5FC91A92DFFEDF4C898883C7C2D3E6CCD467EFB826CC5094D0145B436380302566CE1FD2AFEBFA76696F25A4E579DB4D1C78DBDF6333077D687D74034672045CD9F192375F75D3B09C117BCA028FC45875A9F00078E9CDC8C54FD5DE2260DA41F500E31559AE42286E7364993EABB5AEC1D95AA03ECFE51269303E08DE7FBA7AD0D22247AE591CC7F02D234B68E290E5347BCF5BFE705CAAADD17C46F3AEF8F7300B52EA533C833CE5F878135EE57EAE7092022B9F5E07B245C24936CFD7D0AE6DE720F050FD8BE70DD460C4605FD9EF7A13BFC39A20345986B1B902F8C769A303E40D386398809C1FD139FA70503BE765DC9DCA0F9A55CAEAA9F414BEFD2E431F016EFDE2B358DDBDB9F194D9D9E306750C3416136110221C2931DD42BB93746362934A180A2DF308C7D2A6E0FD575942DAD441B862DBC9510B6916AA3DA181CB649BDBD335E43B35947E63503E13C85F33A6303C081E072CBC6B94CF8A99D6CE500ECA92B6118AE6B1787D44A6D15BEC81D0443FF56A48CB99BBAE77771CA27446BD0E2386E0750E2B506A6036DB1EC3ACCD62BEBF489ABFA41B48D160850DBA0762DC59C50CB12E987AD0CAB87D98D14796A93EC2AB551988257493C2B4DD2F9EE2EEF9C379883A81941DB034979671E0643AC03D3E787B90780C80CE271D8846BAA0C74C62B9A66B9967111A9194168BBE31169D9143CDCD2101CA8CE136BD80920ABAE16E0E9FFCBFBF50BB8F797827F17C8EC861D4426CEB4BA499E19AD2979D62E57FF43FEDC52240DDA68A7DBF10DD2A561A5CA1930128609353BC556E9208FEBFA49C5522843B2C4CB45BCCA91543BFEDFB1B9122304D86126074E0E5CA4410A291A62594D6C963D84A526BF6BA283EC7B2F2CC84FD678F77BF6425C4C05A63F8C5E254262ED597ED4188608CC9B94560E708976A4C55D4B6C7FCD9D6C81126C1FF08EB87A0CEEF192CCCE37F828894C125AB9BE842EC70CBDCC032F020DB1E7A4F174807DC874100C4CACBF898825AEB954D0F9A41351B652BD3BB25A15E4FAA2A5ACBBF82A037D6AA3D841016E2DA7C4ADD3DC90020F644297209D7EB4C97DB0860ED5878DB8A54AFDFDAAB380D93174C09A5E6D1503E8253D10A4C3D10E1F9D0A161DBF9C17C11CE861549499ED93D3BC7680708062F64520F285B7FA460008BC25465666E1DA2C4BA092DFE329BE01D13E490F13D6B6D0373168BBB49A18E4C1E72EA64B6BCB79DD36F4BDF825F990CC4D4DD78051224945FBEB810C6526FEC4D3CD1D9DF883187ABF1523852C3FB9F9196A4C0A4D94B77F1C49EBFA35576D4E5FE3612ECA937F69122651024BEF58A8646716D83E5C0213B76657D72305BF58A312CA327B9C5E630B6602013D045EDD86E9D029BB35B03D96F89F30A10B32563CCFA19D691C9A9850899D923D527ACF2F5F4FA9349A23CC4AF3E3AB52501DF3591C193B7899169E495ED5E0A60F9E59BDF3CDBB2278351DBE8B9C511C67E2CA5FCADBE5F20148B32AF131E5D9EE2827206327E80AE9A873D9C618470231274357085A74FA9BBF966BFAED80FD230BE766705232BB099EA35D7CB619D2F5558F1B8FFDCE7BEBE733003BF055CE1AD5F4C6CD84C45F537CCFFCE2DEF26AED060F0F2B23E291E2F700BFB52061BAEE5045A6E71114D73084315CA5B848F6D9B38E30C854D0E6848601E166336F937E3B6DFB568B488B4C4A0CAFCCB27C56ED305E045B24BCC32309221B1FFA9FC70EB5280DE841B642B128118B93E90281C4A2287C4894C56131452EE812AA3EFBDE1EF3643A8706FE7364190FB2597A852F9A10E", + "sk": "620362188E854286566CC1DA5EC6AEAD3E5DF99AD6983669FCA4AF7174832F578BB2B26CD59B63A1775D194E504D4D1B294977AB824677238BBA02A1533E887B983852ABDB4444A3E036E00EF0F61EB834C9DBE6E824E4A96D0971E372230667D1AABF891050A9F30FB7AC5279E270A4BE0FA7EB6F2C357968524BCB3A4236B08196491C348D1A2709E1C04C0C2505E0960503A22C88004E80C685942429532048CAC424A32012589871A002861B27210BB42C09892110168E4B260A20362511462154880818204A08099042A064E4B84C1B864041340A22200E0CC34DA0C8511BA92D10294550A6858BB46921990404150520154A2137884CB8110A420203B1881BA69190B8819900655A822519A245A136201C36050C173104424C51144963844C24B30C1125000829688C302A48106CD1C86C0AB12D8C260C00B9482103611A818112474D1B33241440821C373184246EC48630C030321134895B468988A60523471012130AD20232133420CC9860DB3650E2C241D98284D8160103C18D0A9305224024D8322D19900C60428E83926419082600A34809086E540429222102C838009AC0500B1864DBB2700B36295B08620A246484060A203066D294411A490CDAB420A39000D226461C208513C88519C441CA486918B24412934C0CA08118972CD8388A1B421110C01149242D0817864C440222A70424264D89208151400A1113855C14910081652004311CC240C98264E4A42CD4488024A84C22126D61883042C648D94420118521A33286441688E2068A941008811025D0A07064A4858B26018A964D80B80CCA1250C1C280E0046ADB2452001448141064C498601A030581442D53822909B131524808C1C4405A9450DB266A01184551A08CD322521A46015B100E9142110C2485D0B68C82166C192149C0204A89408803413202A91089B621A43262449441242788C0384441C85141A62142B04562968914086D0B128E10086162A2640C433040208D1A150203B8200982694416889236711BA791DA086E14A08D02881101234E030262613084E1966018A3109C062188846DD024209A008684B68C5B224C90C80108008840142903B63019106001354A13886D10402A58A220A1C02C130122D8288A0396109832461CB808C9A00CD82640D188241882808AB470218251C8000E8B0485E2A22590A6694C384411914041246CD138904CA66C9892298034320C1284412850229541E2A829093111E2862011A0101998692414918A362ADA860D0B370A1A104AC310481C22295B48668C3021D390104AB82D0A2012003245913241DA4412CBA4301C062AC08691C1B410E408411090688BB6088B281120150ED09605DC120ED8062C64A881DAC0018030611BC88CC93070D3424524398ECB84301B252010865089C84C61A84DD2B26D08066E221425C1B2811C904019905101278523038813278651C26402094DE0B46CD334222413501B102844360E4CB8859148800B277049004AD1B4450A310A8A04311A487121860C90444888146C2492510232914B486D22091289C88D5C204CA4862D00932140A82C20162519088D10388458224EE4C869C8C29120A528D3247109234824B541E284609A208C8818621C122C1838601B310C21A224C2443109A7011B461223A26122B76021865022C50580122C0A16650138114A3472CB206502C924110132820046C90649E1B87149446583C60C20178EC9B845CB44014B802C0C31601049801A1460C0186684A42509162950A42C21214E03040ED340248B080D9B944804A68124094862300A1CC185123424C33804A30688E4964112A70901836411230DD2A800A33660DC082A1A21290B242D834268D9084E13B645CC88248128060CB72C10B9685C1821C200818BB009E096254BA05108C5814236600104041996311409124B148C1B85452200922128284CC04D5B2684E34030910421E0C46C622612C442065B9621E3202E033446DA246DA0B05181923121A70199342A8CB6411C2951A1B8094B162C01134CE4440998B260D298241A11511845621A26064C4840182511E4A06D09170C23806448084CD3224292140280A60541242890122603836548369240486514056893C8108BA6910A909001132082140A1A200DCAA201214772149668A1266003364C1B340213C32D988420A0A824A2C8451B014A5A1622D80204AB1CB8E3E604B577A19923EAF947A1C22E67A7819853ADDABD3BCB54881E30AFE6815B99D88335631B7BAB8CC301B3150BF509F4971976DB4011FDCAA8B597F01F430AEA64761C3CB0EB40A42DDC87700A9A09E0069B6D6521813AF0A753B3D7C213E270B518FCA4C264E1BCEB736723765A8E31055FABF358131BE0827E125766DE4710F315629D514678F425F6FA9FFD962AC6B11104A068B1B370C1A367C16733B7B44BCE22B58F10F103A9AB05401D7E34CC04ACF6A12563F273D03E9F994B4E692DFF11FA1CEC32B4798DB0EDC43BD389FA10BD580409AC1D1A7CFD1F377382C5AB8BE2D6BAFD61D9A0C8B726D30756E25960B78014E64CEA31C5D050F92EDB367B7D67C459BAB1178ED64F263184AEA6BD69B712C6C9C056250BCDD8EBEB3F87A51A6B68744D0FE4869CC1381BF3CAB5E772B21893F239C248D76C56D58EE3C10FC49B24234608BBF929A24B185F850EB9E2E83D31DD614B80A35300562B29EFFD92587CC5CD9C52DF658B16260491F99B2CE74D8F19930E00685FF4EFF28E86039827BDC6E22F92742CC6C4D38AB574C6AD4E46018AC99355C6027FA721EFAB7549FADCFEDB5FC7AE3D0A1B86E65A2863E72A414533CFAA47F2225BD2901D48FBEC15420D408DEA83CDA7748AD3669D60194774109A4094C206C0F259A9FC5CC399CA32DB346D0ECF3BD5572A66521564EBDC5406AF642C8F746659D2070D7D333135A915AC586A1E017B5015AB43BE34CB26E520E9E74D6CC8F1D4F28DE97A7E26AE1442DF637AB256A24648A48AA7A5C9376042AB53C3FE776DE659D86594A343C2FB7C5747AEFE7E1CB0257BED195252F1D99D3CD9C4C9908348B93F875CFC4FB28F865CA2AF8BC595E3F57FDFD1D3DD5055D148888EC7ECA58373D40D7531F621EDFD857776A370ACD540970B64BAF4F30E2CEA3CBCB058A525AED3B9177EEEE490F007A6DA0B977411FD4DE96A891EDDABFC7DDABBB32EEF587326DEA9DCEF5EF9B4878AD0B326C465CADC5D822F207B748879DEA3BE7E949721EDF58E301118BD1EF215C24729082B29537AD23A5FB8AF20AD8F44F7619D99D6FB97EBF6D859DF8A48F76190A71582E0F927BCF4126BA09A56D9869963704939174392D88498027813DBA518E3A2A9E0177EE919C65A0233D7D5EE910B883832253846E7324C1FA3EBD375F005F286FE024EEBE9FD6ED6D30AF0A12D12936839CB9C06A39A2C92B1E7368F042F136EEA4BC8DBE85C9174269F44CDCDD890775BC9060ADA08149B7BF7B908CCBB8C463D6B6010792662F9518B65C666C9BC10BCD7E2157BD7D1F79358F4AA3F680A1E5BF243463FEF1D8DCA0D2A2414BA77B83A0AF696C9614999A9CCEB11A816701248ACFB268816388BD9525F2EFB96B0FB39547CF773A2CEB8FFE43F3F5BC26C6AF86A43314C4BADFE000CCA62EFD2FF28EADDB6C351F81C9AE719B4798091C3DAD70E8CEFB6074694381399E39817FF8D6586BFBDCEC4FD0EE57D4CDD1886344CED1877CE042C29C8BC318F28C11A9F785567695B3511A43A3500A4BFB596C4ECF42EF5052E52731271BCBFC2BADA445F77E932BB438377075AFC2462B58DDD9AE5EECC3F1C5D40B3DA1E212AD06643D7F4348407ACEF56441A66E03AC1F2828AF1A33A632D313ABDD0A7023A692579DBD9F308F604756C902DC340969EB395ECDDCEBD2455422CB099BDADA927A32F47FB1C3CD15B05434EB069A944BDA9FCC7076CCA52D91C2B54B9C5B453D18B9319746CF263DF160A9C19DF0E9B4FFC9DA665351E13EEB1CC3F8E9AA1F7BEA9B660A4A2B3E12424EBC68DBBB9D258599AAA00CC307A798DDED3437D6E02534319B2A40BFF442DA21E3A348423C90AAAF605EA626582412D088129FEAB971A287BE84FCF238410194D980B6F1FCAF520775FC39A38DCF4AE42CBC22BAB92D071D5F95DD3FDC641A508497D2C85400420368FDE2AC466B949F4F83BF7C3F2F6B6928F0DAD2C646B14E1EFBFAC24FB12A566981DA4B61FB1A20C52CBF7DB65156A898E096256AD638E7BA4D5D8810556EBAD83212A0CCC2B6499F769E5725FE1A9843002BCB84136218DA86EEA319992C806AF2D434C9192D31DEBD9E3FB8BA5F0823BD7E6C162A76DF7DC9927F651BA5AE9A6A3171464949C286EC060662FC3E8243FE5E3FD679C9DA1F0C6D7DA8FB8284392C0D947DD9541A36655385DEB72B836482291AE46A0D2E0C4F072549602186FE67EFA0F8FDBC25ECA5FCE9ED067AF4A56C60B758D4252ECDF09A2A125DB91CB8B66E7F7C124BABAAD2718732B36BB3D58AAFD1A890B2834B864D864F1073903052EA8BA2B9F3BD43DA456831919AB474EEFD0198FEF6D156B81E780DA803E9DAE22DE8BDCEF44810CDC4B071922B3D6A994A4925D7B0883F8A3CFE36AADA3A42496BFC9B9B2FDFDA2CF081A4890FA1D2B694518A675FDB38197E0409798E0F4A1F677C51C8E443E8559B366FE6C52F2254047539157C3638B691C58AC057121DDEA73F4361FAC7C62DE745DF555F4F46C15DAC3F77B8BEF4DD51A6F845667BEFF02D8E80B8C1CC97BDCD870A640C81C02618B9D167C1C48F1D235B8B4CC6F851CDC4C786E2031BAB1189C498A3410BED4C18405ACD863B92E2462FA3B6D56CA4CE4CCBA3275CAED86DF80396D52A6784A14297AAE4A5A6BCF4F55B12D64E1129A3297ACAEDE6B8991045543255F7B71917A798E81822AFAF294DE2D7F31CA0DBC3664194B3EFE7AFE2F97F5CF63D2DC7D5974D6C7C3634947054C36423D6C720EB7D2BCDFB9B020694D133F8E1E8C5C7177BD235CCF8D9CCBD9D172B76CEE1682B548A438B3E3F82DB42018D5152E0C3064275ADF5E4B14949B8DA9762B87A8BE6F1542C6BD5300C940268DF6BAE1B5B0C780B87DF291EBB582CD76AF544C71E15B299745DE59AE228FFC4C4F00B0C56BD74DA6404BE10639369C778A2FCD5E908E9E6866DD7FCDC37DA28CDEE66777BA6CDAB1AD38DF12C5A0044308837106C3E96BFA336A2EA633C88D270BB1C0610BA11A742AEF1C8B4649A5A4EF83EF7341A4BE76240B099AEBECF601C021EFA19C34CDF55159E33D0252FBF657C680BB810B51AB191B83E6446A5CB4EDB960C931112A539A7D5F6E64ACB438D98C7C1EA1914A82272F617442B80E9B37B0769BF6D7603EB5864D01B8DB6A8CED4B5DFA0EEF5F76E994662D4654DE3434CDE020B9B2CDE38B289C36263452B8C87197EDA09E2D5CC7567EF7D89253153631F384A300944261300317226F4F1E3120F3D721AA8C1E7C023316EEF66BD3B565FF54253D098896DF69B224BB1F276EF5A518A83CB6AA341C23022B5EFEFA05F5378620D0F088DDAFB9686868904D83A219FB12E6DDD1F65283A653FB9F5EEF7BF9A7AC7E39671D129E70363962752CDEAA6D05370DB9C622C4F6E7B22F44E25251F2A739C1644F2A9B1AF280BF235C2B6894F0485893ECD449C41A1788096574F773671D72FA5DD3DAB0E61EFAD5F536642B892D506A8AAEFFACE924D5008E985B3A84A781110EECEC8EB950B1E6BC8FD77F7A41E244E9BF48DFFC86178BB3B3FF62056E3E8AFD168D2907AE21944D35DD6DEA1F6CADED78C3FB4326DA30D51891E1D8C6C8F1047FCB21BBD141AB5A010D1ED5D3F0BA21A7DD39B4098C2FDA2E00A1C2B5F2B04962458DB855A310382DD4FEC536F1651D1C8752C138108368914F78398C3D185A49CD741A495815DAD06F29CD650B22FBADA0687C47414E72DF4EF0958E56FEE546D02E9B86200035253C02E22E2FE581B22D9273DECB45A33297C77819801FE7F3CA86C00CBCB6D75E1D7C97A527B56F345E0B919DD4C60E3F27DE490DF7FEE4F1C7A5CDDFEBBE24C8FC94EC9DF0644C3CABD184C112192D8165405AF437459CCA354DEF38A4E3B7D32C1246FA2B3DDF544A38F7FEBB3E28F325F00E2214C3494A26560C2F3C6D259A55EDA0D3ED8DCAFAB71CC001C676EAE836637BFE635FF4E5089F3171BEA34C21714CC1F52E18AAFD5F1E5C624E4B395826FD27AA950485CC6A4CE05CAFD975B2BF28D19FFF3930C5BE6A3BFE6166F37B63FBDAC712CE89B8182AC33DACE19E1B3F5C406B2A16411405AA4065014F49452904B54FCF4DC1F9FDE55F6932D8C8C69745F7A93592372E85266E6CCA7D2C3D01F6171451D8F39174235BA81C999793B34580C7FBB7F65ADF8F925F1B6FD6B00BF67602246FDE6F56E00FA177FFBA87EC072ED48569DC2E891EEB9D83C4882D53168FB0EB46DE6B062F9A483E4D0D883CB396D1BB2A95CE845FD33BC0ADD48F5231D73F8217205D14ED7F56F91ABE9E955A0664B957E1522A98E8ABFFB21BF293BFC7BC798025D8B380B3196E394D952ABD9FBECEDF1B24D21CFD135F7EC4F94545E69A574F62CC39F722ABFC08B4794B8B58D4653C58F76700B8DC741A3C2B37775EF52916C1AB6081309E2786269A96D1DB34F6FB31F71E40451756005A494E9658E3324AB05B4D21E6C38DE8FE99B38F46D7F5B7D9F2696BB433053C0F0A3DDB2F8240A35D708C3AA813F9CF92C090BA34A4C3BC16F039479DDA7726989CEE74B0E318B2BE904874E99A186FC2C7D74B9F5B2813941EFFADE242B1AFDA573FA2BFAA4484BB8B76858576BBEE52E49283A21EDEB92CED51071BE899FA1FA9F8ECE8A9EC2074832EE0900C2C431C101986403188AE9578DB5B26426CF2D23BF451507B" + }, + { + "tcId": 62, + "deferred": false, + "seed": "A94A73CDD32CF203AC75E89A6BE1AA55AEE0F2E45C8923F6D4954C611ACEC3F5", + "pk": "7B27025581C883B14108CFBC024B80559ECF926FFDB3856CA0A0F42D28B4225DF7C1680CEF51A4E68B41F0ADA6AA79E229C0D8EFAD838209E2A39B824A6C19C180785B8B793952431A4BCC45C36B37A9A7AF8BB92D0994933A7F5D6E733EB1DA94DF2E33A6B03D8DB42DC83EC95603DD9BCEC090B170C410D06F8A7AF8EABA00CCCA7A042CAA7F7085380A402F72CB26657CB9C3CAF878699CE620719A5B0A0CCF78255E4BEB0A30BB82872F0AFFB5625E165FC9D7A88B67759CCB8A72B6546DDD1DADFFE168AD985773ACBACA465180A0EE002B49C507571990941F9F57E366F0B8D2C6E72A40F5C100A23D8D6D887216A5620AADA2B82A1FA996862C4FB7383AEC9D8BB8BE0905232E9BE89291341B7ACA12B9364DA8B8D5FB50DC937750BDB1581F8B83C3E19278A00620465FF893346B20EB0EC8F1CB335E65ED0E152B08F8AFB1790775E069B251B1E88C63A8979722CD50AA16B883AF0BBD8B361334D263BB0C5D9582273D79B3CCA93FF2022FE1CDACA9C6AAA2C6355730FBFD657B0E82DB02E50A5EB9D830FBB9F706D2B2061B4733025C7C94B1ED50655848F0F58EFB9DD023F8C871B26F2C3C098FED8D60BEC5995B87DAF867D5549F27D2C62EA13B894176B11FEE4A0BD96B5B18262496D7F0055F9F3551C5A91FD728B08ED5757B00504BB0C10D3C776835983B8F406F066863900D8001F6D37BA6626F95AA8874712ED06E22D2DC0354B395353789AD700F9ACE628DD2E53A7E98FF3ED8DB4B625AB45AE9AB07E827A524D8B458BDA8CD3004A5D56391050B2C8E22B2993CE57592A7FA9E93F891C3DC1EC6DA769548F03175B7ECF6E3D50EA48920645D9C766138643BB8C73B2399610727FBE42F02D43B397FA07CEA23C5CA1D8D81E6FBB64E5E69A6433F37C493599DC0C96B6AB82623710A5C90BEFB870888C2197286A5014A0B38343517769412930973DFED9A5975ECB36E3642392B423124CABD33425CAF4B2F4E8BA75956CD30B4DB8CF2F378B946DDF455471E55A86E1D5643298F963CC6E2352292D281405BFD188217F4D0974393921605D94D27BDBE78FF93CE3DC0C21B212E741AA540D3639E36DA03D2C3711F2735C439D0FC5B1EB3FC920387A043EAFF4FE1C632F27D6D0E62C1987CAA6DAF11F2197F31F67B8F0EF625C700562D711586AB764E7C600EA9F8C06397683493C0FBEAAC512E41B478A30532D8D16ED092AA928608449548980FBC9AA50AE734C0E2759D9183E762DDFDD249EE6E8B4E392836FD49BDD46908667E62B367E221FAFCB297692DED3545C3AD530B2F0D6345C1D4AA87460F9CF38E05EC751364B7AA21FEF507198234C2FA189D22E5F9397628EC7FB67714912657964E6249D3FDFC24F7E0D63E2D45B1663D7C23E5B08395540CA9CC0261126B03BEE0EAE396424D774D978048CEDCEED475DF2A5DA43586AD7F0935EFC144B23C429C7F01EDF72BF4E8D1E45D19BE12B999C7F980691E23D70A5A4A0F517B8B324B125CD0071D815129A4929738882B8B5813433FEF88C58F0AEFA1AB98C1C9A29E2FD2596C9F8D2C9C7C2EA83F0CEB1DB39F914E47CA6E6D56CBD5745CF478B9B66BA527D2E36AC5DA0DF93B19818917827CF4E92E300B4ADDE59A5601BEE7CA34A189D54898576D9235DB2D5C73A083C735E87C202F2F5B7BAE6B82AF1D41561398EE17F11BBB4DA28C944011573A4E6E43C16E9550F8EA2BA407C79AF3B0E4F115625B3D822A1730361E9323F8FBE76313BA4941BE9E937D9A193E5A3BC5F1A240C60651E30FA7E0A45E557D95CC4912A6707B557F5351B6366E0C114D3FFF7385C3E90015B55D3112D7525ABBF3D773B04ED3C48995439E3A15CEB7CE577AFFFD5857CEB6EED8FFA2AE9D957F902065647E85C9AD65F54D7D88C4D3BD6107FBA1FF01139F5990625582F92CAFDA90C258990E1F40B123B798DEE01CB5BDD8E74DB0C724C93E4E65E41972E13D0D358EEB86FFCE72FCC3FC93B699F9190E222FFDE951879E3AFF4EC95552054813E8328C28C40778A3BDE116EB931747E0FB0906E2C73F9C96FD963AD300C79FBB542CB31CD8B66C6E63BA290B075CBB6E1E4EBC5AD67CB74BB07F6BABE718F00F010E8BED75F9B98E75ACF081F5DE101D233B002D37A9730FB2FF808C24D7F25A97E4B2FC73E7874DDB2EA3B573A7F7561D7DDBF1F3184457D79E8F94655A90FCE94F661C4DB9D1F14B9FA336F4DF3129E3C76AA6BE419BBF15414870CDFB257A4E2D8233CF8921DD1F69BF6F0A40803CC6E679F0C9BDC4957AE758C8669AB33F2D80E661CB66E36A9AA294AE55A450078A2A5B0EB44C8E03420F241D377F32DD22A65C86191DA857972F68D70C46394500D23AE922D13B2F7B4BFEB5EE21FE28503848422E43F1610261F42FDEEED6F7D67D80754881D755FA81E83D503703259F6CDEA6E1DC5B2FD951702ABADB305A51CC37227038F71F853A53C180BBE28CCBFD5919161826C3DFA0556685B36D7BF451E6AEF92A15F1176C040EC22B469E11AE7E3A1F371C71F49B33A583B9B9082DED6B6CE1B9983B557A458CB9E5B81A7682CC19921E7F297DE94FB9A6CDCFA40A134A1B3E282C3FE9E78982A9006FF4D49964352519B782FDC0DCD4116B8EE67E024021B8C556E2727F25C74E37B92E9540D81F6243DE033D8DB8DFEB0561A7BE63485D05661EFBD17C5C222077FEA20801271164B2DA8943593A4B65D79145DA0A9FA18229564D9F331CACC42295B09FD366F378F48A248B90FD3AC940024705252416C6498527546280CBD6B29BF073E2F458F6A1A57953DCF815C8B2EFC9A34700C9D82BE140176008950E22D814A0576C7A23F4D1EC0CB7E32CDCED7DBEF19C167C7CFBAEBE341B3889A7E90BE6B39708D7EA31E7916829D90C6EE0522EA36D7F892C14E089062C9EA8AFC3361B965FCFC27DC8525BB96B7D51428FD8F493A0A0D8E2B30E6DDCBCCAC1E927E6CF939C1B913CAECD4048D9D21B067A100F0BBD5C0BEE8E08A5462AD325041DA1DB8A4B7D7B6943227D970D8EFEB9ED5DBCFF08F93E16AC81CB544ABE1E97D7DD3E61F4F2761BE9ECDA5E6FC10DD0A9C89E9CBBBD88B25A51BAE63ACE11BEAA575D4E1BE03E084581E880E082A62FC7D48A3569FC17DE7AC1271C3E624A00B3FE59A06803B2869EAF89076463063B56384E3676C8D998B8A337FEAB096479B3AB8455248599EBB7D7B4A48AAA941F42957ACAEC111F987A68EDFDC3018857BFDDF6259ACF4582227ED9385B4BF57A15CFD9FA6F2FECE6C2755353EF4380B59D6B04597EEF66C42B829429C00A4D9283EE0AEFDDFC53DBE21383C42008CDDA8615B0D70C35FF8EE905925E201E1F7A1C4ADC176A49FDD119832634DB677C9C389722EA64C290E6B6D34529E1CFAEBFF34BC7660C9B94A35A30BF7CDC52F05CAA78B6B7F2854BFB0988F5DF23BD9CC6EF86602A371525326631C54CF73A9FB78D750B223C8AEEE95B072B021D761082E7C14418163C80EFFE990F18A63C3FB6ED7116971A488BE3E3A2BD9B81A6F48F7D0E13E218B4FDD8B66FBDFCAF2AF84ABAAAF6764506243F83C3E0963A170BE980987F8CD15157453D856D3C200EC2E520959AD657BBEF60A1EBDFE7709269CC44546F39664C98299983BA3190DE946FED23EA32A5EC", + "sk": "7B27025581C883B14108CFBC024B80559ECF926FFDB3856CA0A0F42D28B4225D480D800452AD18AA0D1D9CFECD4042C822A6D44C7DBF8A48E407403131619B7C3D984C3FD15A93E61F09726EC8D3354B81BBEA86FF3F4487CCB772392210C6D501D69726A9EEE9D235BCCD637B449DB415B0CD254B61D9EC523C8C90D1CBFD6CD0382CC44246C3A40599A66512B82084A06D1CC01020206DC910640A400C00408D12A64C90C2450A964D0345709036001C36000AA34D2340291A17458A3049A0B000CC0045D4366D2399408CB0315BC84848B885C0A64043C245E0140C5832819B824C63405053462699A20C033648600086D2004E509810A1104EDB462A242749C908445C44011B9244E4383192C2281BA348A4C48150160A819264639491D3C285121212030226E314282122091A197199262911C64980027198480112968C2233010C19841390044A22911A8988183184D006521C348E1B36044316490285458C02121A446062020A1A97444B4212DBA20018040D01B18DCC1681A0142C0B4192224964190012A1B46009B70CC3120083B220A126521BB9114846864B80218B06655990109B02018B121008879188300A6122415A00085848515034640A99484C446CD828894C082DD4980D0B10514082010B2400A49681C9902481308C1B37528A3892A0048851B85112322CCA162A0B386121456D0BA8458936459000241C87299C804C833040914085638440E1128C1C07505C20649336240833710C1866C9082808268D13B3519A026DD29668C9B864E2A24C8C364D8B00850C1224C0324D1C25302445044C14824C463010100819226C530208000852C9840514404E5428811805011B865004197050A44093442E1AA48902B90901277053044202C2711A146A50A42553202489284100080990B650640490A2B081E0B60193822024B76D01944D80A85162382D000328C04671DC1064501831D9160D21066A19474622B46121B670DB806D9424600CB73044B0711946690BC324DC220548484483308E8BA2816192085A008C582632DB1482C02611122085DC400108108CE1921052325188445248A68C19444411A22D24A96D00B06009A98022B60C1C2405E4480E5AC44458200D832628D304211322608AB42C609800180446E1922920344621B36522884D9B046AD9106D920049CBC42DC4B8818A9650C4200619284142204424104A98164508B66501B6619C1629CBC82511B08C9A9068640446110291444091DAC06004B92082C62D48327162A641A3444120422D04420C8A9209E0A00C8A041152820823051118372C1C0609A23082228870A3C24C5C1651CC242D644246A198510A4586DBA008119485D1464851344C50B21123A34C4C122913480D09176103480E1B334952062880200049C281C1248624382A04414CA1B02400C3418208490230114A364290220852C285C430911C388A99C289214340A30029819425DCB28092A03091B821DB244C22A20811C449C1186C0B1090DB162508C64000C20CA0B48921B271200488E330318804064132090216899A08112349256290248C928DC1B630A29211213641643804143491088804E4A42D92C460CC126D409030820690838424C2406D90A00451B2010BB584DA02280C22045CC889D4309203B6910AB148DB340883280119C6104A824CCBA00C12280A89982C1229491427061927020A9661C3B82154462190180550866D63148620B80908070D52364A6428290A11010A9304230585A3088493386418344D1A464ED2006140028A21B79088320D1B2581224246E3C68DE00092034928A3362C603289C14821C406881388895BA24944024110954560404613128A81404AC2266D59425192A60C21144AA0364AC328660B838D5C98251B464A5B2242144224A2200858040211B32C981488A3404C41964C0014044C286623902441068C21156AA1B07019B38C5A242D98962DD90004D4462E1C1431C11021122609411602D30446212164038801CB88609BA849A0042299C26898B6491110721AA84514470580184E111725D490701C376A1B04510445840B1106248721222549C4C26CDBA465C048801213210A04860C396A00B885180932501604C008054C364821C4119A16640B10001A858C491205CCC64C4CB2091C037103A94DA0A66CD23086029128448644CC28209A28418B282601396967AC06D55A323D137EC2E28C52F87921D3A6471C639B5056B58AD10D8961F464CB2BDF687FFA2E57C9A5323D2AF8990FDEA1DBABC7D0AA56F1BD9904D707A86A9A92C93B081C7EF23EC6EE3723EA6A53D183B3DC49B36B965DB4D62D88D88AD2A3F7E5509D23B0389E86A4E1F4B970D0E04C0E997EBB3B708967FECD1AE6E0EF71555E4EF519613B00AB50F08F90D36FB3766FC166C948415EDE215C2E8E8D596B0F5FE6018ED5EFB2D9DB07A564B30A556859B5839F0EA495AC41D497FB4F25C0ED4D8B426A89E137E7B9256E5A87708070786A89885B9E029F2BCD382E2E319CFCFB08A78F2D3C6DF07BB586F5F2F925DB887C7C2529AB8EE9969D436557BB1489C41FB119CA34A15E77F89259EB7C7D3C0DC8764DF2FED95F40749A7EF900A33B214FD5A92F9A175AA263BD002D7144BE306E4548B05076CD73CF0C22713735A2FE9CDFE7FF48115CFB6C64D9CCDA0981EAEEDDDE51372C7D49D4E5FEF4C41749228591182FDD67F9F0A416B0E9CA2B7F44455330360F8881FBA353DCF3412E832FD094025314149144B1CA88EEE470CF3B66570B0D9785470521B707C8A61577717ADC490B5FB13537AD02588E56041CFA17E086EAB73BC7C36D8EF488FAF357C118AC99E0AAA862F33773F140643D7B1E92B8BC0900E8C1E28E03E810E8F3CDF47977A5C147C434EF371FE83A11556D7D3C24CE5D90370821176073F3EB25EA4205E96E698EEA65ABB0110CAE96DA29560C62E8CFE713AA5D7B7A98586246DCBAD86A420D1C28B97AE1E9C4D1E8C6439885AD906DE2474BDA0B629D01E12C4045D343521F983909871F90073B7E2146A3A86945BB83F6693BD0A38BA209BE3FB4B193CE4A5BBEDB38A5F3C7A21F259C594952F25BEEB1A992348A94A07B579A32D167CC4C4F788A74AE9214E6910FDDC79892C97FA6A00FEA091A463F13E45707C19DAC54C67EFDFF9DE2687DEBD02462308E50F1F3AF266FF82D279F8975DF99FADA5AEA5514243B942BFE05A7AAB1579B469CA92BD222EAA2B547B7099A0218F5F43FBB0D54B11D7E8B5373306B2FC6469F694F3EECA3912BAC0026A40F2A3D9A76D76A9F3B06380C687EBD7980F901D2F5CDAD534C0D2745231155D6D51E8AB7D822EB0AF875716A0C63DA747BAD741DF19474372D7239EE17AC7A5AE3C92B5EA98DE85508065DA483D4D4FDB90329124A2BD27D77F1FCA072A83C85D31C75ACA462F39A4B82B13D49963B518C843CE2B2EEF0AF96ED23898040C9FFB7273FE3A02C5858163700E1423BF5DFCF27F0FAE92081D2E6A642F49102E60FD45C5A2BE668868820DF66F6D3E5DA79B40EEE9F1F7959AE72364EF382901D8AFA5BEC757ED80522DE6CF70E0EA970C54D044F1B16495CDF6B38D70751ACE52F9976D6EA2E47AD672310B7B71A75C1C78546FDE138F4533D8DB9A7DBE2E08F7E745A52B3913F12359DE7F7E37A6172C97F612EC3C0FFA2BA55DF61EC06243BC499AC5C7F7CA63727705C43D356C79B67497646AA7C8672AD3CB8B241A16DE6FE53C6E723475DB2A5230EEC5C233DAE829811293D1820A0B827CCE1960DC978F72B2DE4B58802DD15F396555EE4CEDD9932CFDCEA3F113E86BAC39945E996830651595017B5069DB589013DAF4916498C98042D0B807B490BEF1783C4A5A4AB135EA2D2C0DADD7B6121785201004A38D94C73B3EBED2FB3F0A26BCFB33951F89C968521D58A307DC13CE40D1188ABB84C93942580BBD8D821748915257DE1D7381321E6BE8567F0AD583DB4FF40095D45F2F09C6FB0574C198E8DC6695AC75FC1D96102D43BCB32B8D95937B7A0EFFB573A00C26B68FC52A5958E0A00D23CBAC22352929BC5488A29D974743FBCE01C2EF7169B58D23C5ADBB8CCD424686BC1D42B653CE8F149C48455F97245FA41CC97FCB39D812FD61CEBAC99B8087CA86A99008B644F262517F42712D9DAB06B0EE8C069397A80AD678E72B7766C29A3407D2406F22DAC4CDD02F83ED60EA03AA6FF891F6F06514E2D321CA475EE4025FF331F6B12F09BEEF84AA9B1E5D822CD9501310B85588798296B14BBDBE2DD65140343D20C6F6B385922EC47EBD8293B41E0B22F08201B81AC4E05C7D1F09EB994B1EAFF70F731FE66A5A49BFC6F69A9B054BD7CB410B893894192EFE02E9D0CBCD75B751D95139B6754FB856AEFE7C65305D8277E986C89C90EEF6845416E8A6BB8DD5D2CAE4EB6DFE3FCA1A0143E0AA10E247DA7233905983094C4FA6E924452FF3D8C1C074EFA187597160C864F7366169A892CBA66215707AB59917C9B2395A052CFE64EF65BB10DF9E44B4E5994C46CB8453420E232FE7CBF1CC5CDEEBB6B7C56803AC8A97AE5B7C1EF5007A09ABCED41387EA53102C85B3421D5BBAD46FE31C8F8942877BDF3430A7B9A41FAD7ADA3B2071D4D0FF83E8FAC35C26A20ED01486C8F4EA46673FB9456EF5281689BBDEEEA2411AA12380033045831417F6DAE4DD21329D73F7330B13DC60A9B970E60D7673FC65C93664B0A625F93A8350DFFEED09C8E601335363000CF31E7F41953B696141B7EFC19C0BFE1BF0873CF394984CDA52535A1E544D5D814C0399199CBDC6F8033DE07A413100F3A76B0C45D9C972C0D554AC7C404BBDF94A85A40A3AFD60DC6DE689A3B23BFF358615E940C8D243077291968035A19C576F6B3EE2A6F615A97C2B54693A586594D218DB114D7CF90665283F67B01E12D61E516781C1930BB669B53CA20D248E84F23096684FBD9733B7C0CC48A9BFFA93B4393FF5D9D2B4CC7DAEE10D8D4101D73506A6538099537A58E0C08D94AE83749271B54D27C72C889FBE32126D6EF46BFE19DF20026E1B9757000059578D33ED7B5DEF0B95D193405843C91D417FC377DEED6A60BDFA2FC20CAC04B0FB1E3CA4794D36E56FE48B363CDF2D65C891BCF8087D511936E9255FB51E0CA64D4D034CDEFF97FE7C0D4E2DD4456435BE3B50834BB3D15EA0216CD4DF2C6032FB9A83E077C5F1C912B3F5363CE67DFB373D1821F4958B89C9B268EA05AFB3AC7E9E150C5B7F0CA030130A5F03C7BBB7FE10B03721F8688B4735255A7D72B8C8A90C25F2DB9158A18A01E13AC040458DC671EBC19EE75C6D5903BA569A0DF90B986799C546947E9B94648424B742389550CA2B2F803DFCBEEB664E3AA5523BE7E14147515CC1BBBC24610A7284A6128EAC0CBF1F4472A46E4ADD7D9F4A7CF7EEC0C03578AE620DBD121F774AD46F4B5DF2155CB4BDACB1BE64A674AA7F066308468800788E4D5F4E84AE1FE5784D92883D1EAE3E66E5297554DE94B3FCB6EA3C273FDFFF08D770048BBE5D4AE753468CE61F7ACF85450C7FA93C2F828F1A888BAAEA301F5A8D3BC84D5CB3122812304226FF83F1F358DE1F73F22C48B76EEBD4B01EC34B51FC09277A70AF10CB58BA9243A3EDB5946CFCAD46E2926C717EB13AED5B90DDFE0C3DE6BEBE9511E925FED1D38CAD55826E30CED1CFBB2A652043EAB1653FC1CDF32CF5FFA2F8A4CA591B3C70517530B08ED7D663EA064AD65EFDC9947291958D5C778C29E80CD3EDEC15EBAC272993014B00A20363720F0B4241EBEEE394C3F35FF5E9C7FEA8B004DC9E53E2207B526644873D3D88CB91FECECDE2CF5809F78AB54583FD62ADFFD83FC406E40F6047D8DE85AAC6743FE2F7461D52B88FC647FB1D82150256BBB32E9DE4FC271D98C1EB5E1E3E660234FF2C182C4FD2AA64325AB09DDD1035B055B5886BB953EAECBB75826543A911E1D2D9B1674F4286ED25A5BA05D27BD50DE219A0C6E029E4DBF691471571AD689284CF9DC1E2EA170326A1B949D73392FDE52D3D7D3CC56518F652CC93F75FA4CB4DFCD52CCAF7A64505D1D8D0E83593A2AB7F083CB09AD48257F21885A9FCD2719C95701583839D6765E6CEF7428F9A0362A6D77191F6921E1E09E69F7CB8AD9E277A31FAF37B21407DDEC4B0F67872D15353AB9466B1A927EA0DC814D4A3E0649BB0813CB817EB80F2D6EB85E49CC14F9AA8A37513DA248CDA02A0A77F340DE1B939798CDC6D7C7069EEE4E2A8A8120EB1EE55AD3823D3AEB93FE55BA2126DDABDDFCA8B6A6DFF07562080166D257BEFEDF864A917DC3A875BA2B673C0E4BB33122E28A03955337082CA6350165FC16F23B404C57B971737361D6D91AE847050A18D4E70E452C9ADBD816426101A6D3DFB1EB8CF2105869B42F5718D1B8F27CDF7B42007D4942BDBAB9EBF1DFF9D92456F610F0F18A43823B2481EA8313DAC3703F342C3CC17B68AE8719B8DFD80FC544522D973EDD78D5E2EB4589665E8863103EBC554446F5054F634B01DB6C735103BF85706F45A41809C97D0C1EC449D000509B0B6C9ACE95F91E2D1FF102FC54DEEEA476726C06E198C4EB2E5E8A342C75A53C4FE727BDD039352B6E3F0139FCFCAF4F3F44B3B4751A76993F1F3C9DCCF74934FCDCDED4CD7305652ED1DB6DD60277D17EDD982B73161B144B224B6406ADE4975CC0539BAF45B3394538F0E4C368B9598E0530B4D8F5120215F64BBF2BEB922BF9F7A1422B8D5B642E6A217BD65FD68C444375BC4DD5E7471E8540C79ED21BD42E9885FB54C2FB49DB1683548B60EF7EA8D2DEE9A91506E49C51FC31121A33AA06699BDEE221634819AE6F8155B8A1F1D93E1D1F1064E5C158973C657886A115B83D2B3CD348C2813F667859046E322065FB634AA1C8185130354A137A" + }, + { + "tcId": 63, + "deferred": false, + "seed": "86CB0744A2F973D562DB3B2C47E234F02C0ED60D2EC27326407492F6A6913BAB", + "pk": "28949C37E29B1E305E3F94BFEF5E260CB29B04E683F0F1E3E2EDC22AFDB5FC6D979DE7A021924CB86D8AB86B1D64859F825CBBC99BF298B6B87E02872C489AF9B032DBE33210DF467ED148AB524A89C77A8AFA461FC57F3BD206D6BA67DD825022D12CBA8CAA79400ECC22D8D347C8CF58F0630C3C84DD051999E51944E040AD9262A60436941C3A0DDE60EFE0AABBE4AD77F8BA18366772755FC672B4E4B022E4B7E64CD3F7426890FA203FF42B439F3DB0CC90EB3146FEA0C3B5F1D4F1CECEFDF87871B04F40FCA90F3FA1C9133000C254FDE2343FB85623B75B100CD435C5BFF5E7E8490E00BE7717898DBA816BD0F3E8A7A439AD2948C9E5C829D3B1F1AEB4763FA27C90C9ED7E1EF1722CE12B1783AA64DA0384B1EDC211DB94BFB75DC689E71FCAF7878BFE16D6D867771054C080C70BA5A7EB6FE2BF34BBCB1BC26C64240A9976355336BFE99FBBB471C8DDFE0D204EB81F7B2956C8073DFB5F8A5C41DA87086F071D7C0E8490EA0AD194127B2A1E28C7BD8661DC0514BEA6861DD3B3C24CBB625128D2DCAA737EF012B4088D8BDD7D98E3F548E4445D7E753C9D3AAB45A217F0832C0EA598DC22EE9A0503BE209D020E3877724B3277EA9906957DC07E1E834DB4A4B6A335D48863D411560C5D2B54C81347B96780FB0EFE9FA6A1D5B88EB9016763EFCDF929F027B7A12C3963B07F01E87762272F958E066DD1ADB38FED33710FD6E5E75DF098ACB3D18923F710D1AADF8906D1602E3928A2197925B971E1F6469090B932E2BA6A3A2D7D73B513042D1247770BD516E7537238E12FDC86BEE336ACC7DB555DF40B80BB59CE44DE6F5F45594F91F9A8A91146F9F30BEEC6DCDD98623E145CD3DB94E3017E73B0B77803D8D2401527CE2830EE2CD7C577601676965C9113912E554710D8EBBD66E5C9F66236F10FC068E5469DD4316AC852D2B7E7E74198F8490A299F9945D19FD66947E00BCC27D18182B556183B92DC42965DF100E1DEFA542178AB65BEDABE24E668E9E354FD616A2962E89AE02951AA8F7CE98BDBE19FB9E346D02A4353AC6102A5D2DBB8600FB25FE08830CF28BC7A18113C98BD151B8FF4882C0FB6EC1C03E7AD142424F65B7A1526A907DE28DE378A2AAE7378E9B5B5D3AAC8312AB8D9A7D13DD96064C59727335EC0946B770F28C3DD4D80C46A014552F0EA2886311FD4B2B66B37D3D7D1587552BC52B11D57E78070E306D5AE16C73B8B574E90CC8B3793B68C8B2614043035A19BBAE46C338D14991C344BEC13F64C29DCB9F942BB36393C5E6642EE1F6AC97A530374EC7646AB23292FB0BF817078892BC4B14426B73213CDB2CAF3B8B33413C92D09D343A53A0FD29DFE241BB0AF15E1CEAAD5B6FC6E89FD4C0CB7D720178531D48D2B3D9397A7C1EB5BECF8566DACA5D7828F10CB9E9ADB6580FE49C574855E287805983CEFC751A2ED29DE334AA5DD15A73A6561EE82F39F5EF3479DBF324AD94317F2B363E53B2B1A4C5C4BBE954EF7C5A5550F0770B056EF847AC587B56D074033CDA9CFBDB9B3C482AD69BC46E2FDFB8392F801486BF80BB58CEAF972437E237EE4D2D40381920F3AAAEA382AA6CBEF990EE1111DF2381773057B5F48E38417DA2D67456B4A9C414A245463F9C9C25DE136CCE83E0E5157ABA9C4864F02230966F3B3D66D21289E41ECBB0BD9E27FE6C42E540FFA552ECDFF62F6434FA3D4A76ABEA34DBF780E597505B86FD6EB4FC71D6E3E880483A7D8A148172D159BBCDB13B4DD613414DC366D6E68BBC2DF8ECF874965666BDC8064696401C0BA1F5394B0BCD4C15644CF2339CC7DC02123C9947998CE4106E0E3F95895DF08BB4E343587CDE72C07CAB0EF6C45E7759CDC2102248F56205E4F9E09A6552FD4A3351D6DE431B4A5825DDE7F102E82B379429162EF057FA564F24CFDDE233E9AA94A93E67CD4E716D667CAA1E98BE971E7F46267A81DF798FA537C1470BBF40C6F0F14B4E2EB5378DC68406AD9C5A40F8E8100E141AC728B2AC51654898F8E3A7B91513FBAF32C6670C294C3F45B45F88BD8AC8B3B031AABB5E8B127B5C7FE6B136F0D61BDCDDF36DFB72C8BF60026FC137D0DE670084D4F9E99A7482791D5EC0D9FFF4BD381B66062B15BB0176EEE004EC7EC97FDB5B712F8694226CE1D60E7D79E1394046A1252EE30DD15F223505F1360C7ADC789E4DD225F4E11D72B5791BC622C43163F3FC669BDA7A7A680D58D88FCB49D05177AD1103C65C1CDDCDC2DAEB29D8834CBC6A89F04AB592FD79DA9E377192CB88EB7151DC554270E4B401CFB3F38EDFCB04C23D12A96302FCF04B2B7751E1637E146DFB116C7DC5DC7A7CCFE56E0202CADBCA4065596BFAE3A2431C6485D3AF3B727C921B5800CE77873E3E72A1C4A03D54AD3B51ABA5B1284FAC0DC80AB5889A9878B1981DF24938944B6C2D570AF90AA661B7F06342BDA8B6E67B70503D12D462F0783C900F5500FE2F8167F27977C742B29A96BF82DDA9728F173F572422625285848ED21FED7A77B89B88286639907E58D28DE09A44B989EA8883B2A492367B1DBC2925465D8EA2B3338B5FAEDACFA0E17EA560496E10EF78828765BAA8B97106D155BE46CE0535B81FED4504AA9DBCE8C01DD09943E6552B4A9A21C870AA4F0CBAD2C3A049F9ACC37915DF05CE5D3DF0665C2C79CBA877F814B8CFB49CAA89D1FD415100B8491DEE50DA1E26D13DA1EA3B886E8FCB44238536A41B4A48FBEC56CFB38E3A2E17056D63D3EB1CD3CA53F32FCD7FDE8182024F66F57B14F8FAB506A6CBC56FBF9A5E58843ACA387F1C2C50BBED57E3110B85B3D2A688B02609D7655DC6AE40EC94DEBD77434DA62E1184519F53DF6639ACC67E61D326DF1820095C03186B100EB387D77D81BBCDBCB83070A9ADA3B3BD5105D1C2C3D9B667741A7A3E126B34C3C90555ED867A3A53C61575A51EDF66CE3EC527509343ED637AC719637EC68C6D7C2FB9D4BDF58A3E16E74608957F553C193AE7A1077879361DF738DB9DC997028942D4AC711B0A14C6BAB05E5C07170E1D0393810EC9F3044A38629E65BC179866692A221B5A651937B3475EFED417DDA8FD06AF7F2555427697077A20D50F4283E31C70BDA469300A76D8A8F5756AB47D46030485BC553FB69B12CB6EA71E69C88910A86D91A039A3C5D1D29C9A1D728B508395ED7C3ED98218097DF7A65CB3E19D136620BC2A933C3C951E81C707E2DED2490451380EB0370A41E46A043467DFD7EC6B37748626ABB9A61356C95816BB24C29A4C64D6A7B4EA3997F635DEA05E400396E8B50DCFBF47859B842E1215D398F8339D8CF09DA11F9B93FB480690930EE204B18FA572AD409A16D69DA195C4BED44BB790E4BAF2A0CA406198A4E9C176D6A8A85F479E2250E0E623CED7EC8DE37E99716F2BED4F1E25A1F5C49FD6A4CC84B956EC82468777E08564E15DDE40548488ACBEBEFEECF8D6501A392FA0E126924063EF9D0285C5571D09E294959A5F1153B44EE45FFCBA5378AF7F2CC40AD35EE2EC6FBB31E3FC8EE7C89A6E07FC1B1A7FD602ECE50D139CB0BBEA22F95396C52352D0BADA3278305F1AEDE214C9C8CD9E0D8CFC81D9FA5ED48118D7A4D34F8DA18ABAAAF51D1B9A01A1FF5DC3D7E4294D3534AA3D121E938E3E8371014DD11379E88839720", + "sk": "28949C37E29B1E305E3F94BFEF5E260CB29B04E683F0F1E3E2EDC22AFDB5FC6D73B1B651557BB7138A45C55436FA0CB57DF632FC44F7E6947B2262A553675388D926CE1CF7D3C24A6125124973E6B13743F9D8337CD50156BB82556E328CA6E8D007D9A8AA09D94A21CFF8A1A2EE4EC48F31E967819633C9AA7AA697482ECFB453C48451146A1B420443C028932621DC988C4B3665D83431593886A4406D014872D1C66D40260D14278C5184848A9291904464CA1089C9304A1C432A10822D49447252420D1A322420224058160D0AC26008950C12A171883070220052DA200800398851388994360A11269221B72DC1342AD41446810606DAA4691316094BA44424262A08C110D812240C4500CC424250A60119918D53027119462961C68159A42DE33230D4360EDA0632222550143981D10405941040C20046002984D24050220746C42240023730E3A425D1C2040C3166C02430E01620440040C0C681C12825233209E3C00C50124CA42086C28211C8268884082914B16DDAB00CC0B28410846499981090224424802501A589194291E228290C05049A948990422224060EA3148DE4A2609C924D4B885102834C8C28025336022315111CB84591164164129118226E90B44921980DCAB6219BA43062366A044740D32005091486209925DBB00053428112A711DB1432C1240222936584347111172E53188924A7090A210C1BC32CA2224413C6059CA485990891C13229D8380441004924989052868851C88C2029201C252C4B440912B350A03404933280584682C49689A300095CC01010288AD4360C5BA050A2204CD3C641A04682E2267220058800084E032412230702233080D1860020834D0949115C4445D09881C236088482855BA628123650CBC88D0AA150940051E4B44004C62DD290095C880588A62918377003078D1C826D4AA67080804D63B66903A5918B0864501652D024464114682180690C17629A1021D4321014980814A37018C4659146660113015BC04023A26950008C08A18DC8140504A024091928E1960D032744891662C044324C442A8106265B08844B4208D84829DBA46C1C3160582029D1468DD2121013976D243332D4B6291845648A940090C4081C330A4B2011802885E1464C4CB688081861D8B88184846CE20226D1306440C86009416191122E649831200350E2C42C0A40214C3412E1202024022C41366E04202620414509C50582400DCB3851109550133491211022D240311217440A49909CA08014116D10082002408011920D23178601846C401292028591D9862984C8691B8650C1488C0930090B846150380E9C06229B4692DAA24000A36419404200056CDA104991C289111604908830804290CAC2059C2029220171630485C1145059347203C7009398450A0902E3064E22172614336541042550364518A150602628DBC00D53326A12272923854C9CA00CD44460E1B808CCB440E2A44948160009172DA3246A0C95300415100043424B8810D8368412436A63B4651BB32D14B14188C65110A08D1C2970D2B2115026499194691B128CD898604038680C09710C42480C078D4902008B100C02A351C8400480222A24422E8246888C26248B2832CC380400042C894449C9C20C02082E13C53153326A0B484942488D1903712386041335484C028101C4298B90016230094A00854834320003920CA201C108846144414C20201B1505D0B6045AA28018898494088084040E52280242140E40304583A400492280A1824C02B30D1028018A4652D8C690D22842A12226534410083362032672D300821992319BB24D19A60CE434704C128119067013422A4B06929232865AA424A1B02D02B66D4C06651C00100A026E902680CA286698C09010A9651A0390E3488148B4601B058CCC482C0B256692162401C66023016D1B46510A360484944123148EC4922C12084541463099067080A8108334219A0042889221D4244293B67002342420190C601805DAA431E498641131915B44418C886101A62001045190B461CAB68851C428211772503222D1B251C922059BB488833286001522A03809020466511451200672099464D808328C28869488659006488BA22D132650CC8205C944680C3590434002098850021770082771C23802A4468952360A231302501805E4084C21B14C2195501B4866128590890850D242621C002D170F4C880BEE2D7949D532833B199A8F1AABD2EBAB8DC6ED79D3CE9791B5FCC90E1440B2FCA080974B7F46CF160E36997EFA2879798E2B9763936D73CD08214CEAB7BEC430C10E250703613D29BF5D54903F114E5C9EEB0CA35CF0EA999D0FEDC7DDBDEF4076DCB97F8E4DF850BC4453F5934CB47B1951EACC8065CDFC3A02C137B0EFE379FB104EC91B4667A13C0D49043F14C02B1F493412EC2820DDE3DD9F77F62A2F73BAFAD1978706551B9908AF53751BC8B8979B3AA02BAA9BB37A9EB42DAF7FD7AD5D02295B9FF04A2A80DA3071FCDF2BF58A2B8083799DF87118689F7A34751D5039729F87DEF79E20D649665CEED960D2CA982A29FFD7A5D430AC8B1BBAB0982CEB99BF2A24038F67F4D224A794DC1DADB0D958544FEBBC073A30FF627F06259A093EE35F1E184C6CCCC51CC86E0B1933447BBBB13F1275963AFBEF220E5BF134C8062E10AD74CBE5CF5C22D4B61C7B7FFD66D959742E0CEBE90C74AC7ACB8B47CE737F6C44FB06D6BA5B7AF82D3C0031CA35C31876BF7376BC8FC59E8E74C76DDE4EAD1B648BF5E2CE28603FA017F8F0FA7F7070BAB8AA3486963B56724418F805D13E24D3B3898FEF6D4974CBB316CD41AC7B66E7377C1282FB01764F148B8E1E715B519970F842415B9FA682621D0A9A918459A480D863886B005CEC83AD809AB5909E433326BD19C92D15048A67F654C8B5DAA2015ADF5EA08704B4A20ACAD70B472005124087EBBA4C264055A2817EFD0A2CFD4CD446CD873A9BA85D9361532DDC0C1CC422C67CA3DA904C001D5254D9B2830FC1A2C54D8A9FF470D98E14EF47D51E74B1F633B9F52706DA39D6FA0EB8D8CC52375A9DEE93FABBA13BF4B808D6F27B5EADB29ABDE6E3CEE6D4703BAD39F5BF4833A3CB98B0D8D99C1B2CD4D5DA4F6C5A7C6AE64E75512471B8AE4D8E266C55854CCC37EDFCB6B361EBDD6492037252325FC694594F3031ECBFABAC41694F91178FBB7A1D93594EF83BBC94CD3E5EC1348335397BE29D7950B00424A79E47F8678CE690522E45AD670350E41439C62C4E6E722BD354804E178C5B4F226CA42D8C8E81B32C1948051AB5326AA03E72EEE8114C88372FF05CB7E5CC1D1D6829C520AA6D4462367247879C7107D619D66F9F3D01BE81BDE3ED85E87EE8710D2CCE5CC4F9E4C52758A3C819EB7D0672781EDB86AF310CDC4789C79659F9424380F42918DC60528F1EAE3DE5AD34E69D06414B5CC50B311E3C07AFDCE85BA3CA993843A18550D42FC6C39DDB61B9872226D5CE2D5CE57E427953FF303606A38CC4AE3B5B6A0886C27AF4AEB630F9BBED6A0E0688F532BFD0D727FB1357F2C8DF4FE36E3E33255BC6E74E4FEAEA7D6F99E249F9D2082C595C961438A53A8138EC8F4C7DE974208278467CB58240F4E48274C702EF2C6EEB718447F61F91E4AD08FA0C1E435A01F3E3D6EC6D7FEF96996B6ACF37632E4BDD02AD3230B6FDF302E8F93442A4693525DDDD43EA90E03DA3FDC054916614DB8CE66435DF03A2B3CDC14415143C53F387BDD0BE8150CC06C323D67480F56BF519308A7FFB993135100679C512B6D23CF99FCBCD9D998604E061D242CD7459FF389371FEE1236FCF1E85204F30B2DA3EB220CC19A2455568DC7F6637DEA11139CEC3C1D595B24B456F1261F27608008CE3B1F9E8905BF445CF3FDC68DDDAB5664394328113169EC75EAAF0B739E7F3ED08C9CFF6D5FA167ED85AEF78FF13743AAA84921DE09302DDD8D1A99705E809FB13B26F8D90652EB7A0C70623132FFD32614A7E268A5FE1CF298D8D1406FEEF6056BD42718F8256AC663FEB926F61393E12944A1644A9804513D38EDC72072A8FDFE3E0ABCD45A4681891CDACCA1EF58EFC8BF58D182B3FC7A8D61A103CE517E5ABB983E1B58DE0F07EB24ACA29725A5278CC7C06AB253A55E14C6AEC438FE8B9F5606EF06FD44A098ECBFB76355FE8D2932F72ACD219AB56F50364620B381A9AE940F7A3F6E416706278EDC9526B8783E9B9D75C523BACEBF472FC1C1741D7801ACBB3793ED9E8A7308018BAE285C2B36A3830C98F312349286F713247B4E3AAB8B089DFDE8DD3D5DF17CF3E58B06A6838EB37E5F10D6D6CA986CEEA61A73D5BB7950460774572E71BCE0DF3B5A4DBFEA69AB598FFD56E20A8318645AC33C9E53430D54A542430634B2ECD0D9343DFACEC4F2C84EC9241D1E92ACA6CCA673465AE958EEB1BD55A9B6B927F8E97CB1516E7783185E0F36A6B8AABD9653777A80DB0A8EE56875A77CC4D77D647DDE9367B0BAD8D6153E475BCE3ED8AE97C8C58F60EAA37E01BC298243BE90DE8DC8612678F3B821EB6A866276D5041172BFA9A20C2E562C1E3B3BD21A3D22BC6F276EC19E4AC85A8CD731181A3EEDC1EA692917F8DE7608F6E0DDDEC449A9C16892D27288A1710CC5142CFFD329C4CD1A4506E0706699954D0E7A8C310567900FDB0AA1012AB331AC52F46B81CDEF42B5D494309E588F775ECECCCB96925A504C9EE4D7655720C0FB1EAA63DD14A0E2EE2E37DA3D3FDE0BAFAE83C1303BBAD5991BF21CC6FEB6DA598CCA5BE15773B85A50A0BCF9502EE2B9202CA541F03371C94E1A645FFAF98BF4841CE59E1CD806E7151D9F3D568083385C2FF041D656E328EE76FA41B8DB0D60DD8A067AD012940C85A843DEC6888397258F1D4A75EC8ED9BC9D60D121E69A9AAD8F334C8ABF6942F89DC2DC8826D2904BF5B331155A9E3BBAEDD4F1A2EF1143C7651351FD7D8F473155B85B2B21BB05DE74CDAED6EBEBB8BCC2A3BF8FC30F6B89E50F160C7FC11B099C3B6DEBE53E2C6A5C0D96F3CDBC8AE448119F5D1B27E3083C82190CE1C1967B27A207634FC93986A5D9A18018991BB18CBE679FB9868E0138C4CDEC51DAF819DFD579D8726808B4A1FA6436FBEF11B4BF81FF2C1A80C8302FE90B564F87651E1F42E30C4A32A1F5546680A8FC6B3C18CFE217A86ADD3E96D0B84A9811932996C30127BD5BEAEC298966FC87ED2D280EBFB55055ACD4FB781ED3480DDF6402292D0DC41F5CF5552C35393EFD69015980494F11A9F63FAC77362555F8BDA8E9319E72B35CC0F13CB9A87D3F850FE89499B649AC97AFC97D0B1412F651895F19610245A5F9691FF5FB4E0E192BF59FBFAC4EBC77DFA81BC0BB32921C25F45E07BAB1924A5B0D7E41108C89B964C7C19EAD8D6C90E5FD77F206DB344CAE717F14C5FB8ACA5293C5C6718E1F3F9C92146DEFAB65EF3310DEC708707B2B2BA0F4670C10FB653F2F8C54A9B906DE06D2A93E36F0CE6DEC71FAEAD4C7663F160194DC2DF78D6E042FCEA0F100180A5DFB19205AF4CB8E88B22F2771806C222CB88F3C92B72CCF36D331DD803AD7080FE334CEEE9B04B9DEE66E3BE9AFB17475F8EBF168986CCD9BF4E1EC2C06998F9A26CAE3FE52B12F0331EC3C4CF85C91176228BCB56D0CC52C8C1D60AD6EF34ECD6DBA58B85F1AD69CB2F9484AC7D4446DA446487249BBC646832C57085622E25925017CF725C55F2BCC3DC155BC8064A1A6A9581584B883D3CEDCEE272728980888880CF6A23181F00E2E4182C5A191DB684518E1728E6FC9EF5FCE1523B8CE68DD790411CFBB8E58F4052727FF6CCF640DB939DBF955C84C95774449D4EBCABCA9A6637A807181F1CEE17C621CD5C29C59C155DB17DB49E838547CFE72171CE48FB1AE3B1DA964A95D5BD62F74A0C46528A4DB898854A064B7FA8E29AADF19233C3851AD0EC0074FEC5BA61AE34FF7C474E402622CBDAD9B70AD96559EE37C89163C271DBAED2D721A42F33965E70DBE0E6BF55E9A24D5F675874EEC48F417778838A0DF29BA2CA927F478063F667C7CCF1A449C48F7B14E23B54D16C3B0A284EEEC1AABC7D9A7E6DD880A980F8F73D47E4705FF2BF775D86C4578C77738D36F4E7E0885F16AC7E7384284D78CA36708B50943F0866E7438CA56134E286417E94B36234CBCD2E279BF974198EA375833C6AD770D6CAA76D10C7AC0E07886584A89BBD6E0E2F9801C1A429F7B48A3996B34D9192551A0AEF46CE8CF84BE877946DD751CCE1716E47A7A88B88B8F77BA7280B7DCAB62DF14BE6BE4B90EFFEBDBD3555CDA85AD90185C68F0C38BA2E036C685231C6CFA1B3BDF42426A2AF8F5CFAE4C998B330D4F7D4EA0D2F9F21D27BC13BC2127DFF9ACCF107B2A04CCB1FF1C85D26ECF8B897366C213B8C796454BAEE61CCF0CFFD49047A10C6E6F417764327F37A2756F6BD70E856CF3A16800D47EDE41CF7FBCFA107AA61F5CB95BC555F5ABC9839EB4DC6A6EFBF44D6727BBB6C5644EF183264082DFAA31E554E4EE9B7D3CB4B96A817430AA90257CBBD2A2AEC5202BC83CE146F2FDD7FBB0073D872BC8C9B6E52AC946EF26E20021147DCFA2550DD9FA380F854DE101795D1D05DF8A9C247318F3FA5F726A36697F1843F1F44B57D70ECD52D86ED3C5AFB7B2616925608263230B0DBADFFF5B661C8952CA48653101244F940F2C17D9E155B26E3075EA9F3D06A75A4254A628B2A15B269A1D1455B02D44BD064B5EE90ED4BA37E9A92FCE4C26D96615C726C6B604A964C9D0E498ED8D18BD3EDAE8194246F25BD618C2A53C6C88F7744CBCCCF4966BEF5BB4D2E5C03089C561F823605B2072C620F85A0E8907DCE2DD78451DD343406BB23B6AB74573C1E6F040B67940FBAFB3A4D1BB59E8E698570E0B4BFA523AA269C6C7A3908369078996189D29B9D" + }, + { + "tcId": 64, + "deferred": false, + "seed": "23BB289CC934CEB1993640DF1015693EA499786882A987414FD320489FB549DB", + "pk": "766DF1B59D8EEB563419919FBA3949609FFF99BDE51C494DC43E6AFBC7E1DA38AA9AC55571BFCC03E47C9D28AECF1C995AB14E20718C5913DB899939D5E05196AE807A2E01356A5BCD39DAA2B6097DB0A1E59BE749F147675B8E483116CE553F964C7676B6BF4876472FB095308B3F19C585DFC11C4755898BF2D2860A50B96DB8731D7A0BA1A9B9926EFFD6D351DBD3DF4E9593861DA889B4DE05F1BC908891AEE2CF827D2BFFE673237364FB80DAC1FF57EFA9C64953D04010F331C50A3A7304669D7C1FE09A45ED7822E7B16C0FA25BF50B5F45088DF18BB925E7F81228C00707AF7CE831C4303CB207AEF57A8117202EB2054199CB940522C51F10C0EDC37F7CAF4811C1D2191DE97CBF9A588B5AC18D44FA75C18978CF2A992C64D645D015204A54F62F080F2B3725C3C5B41383667BB11DAA5F58010778D875CDE5BF1DA1C7801E3DA73C9C586677D520392421621B3EB73D5673BD677A695FE158BC9B055F8F0DBCF0D6DA00FE4AB482ECED484D3B2F9BA25A7B75777E3B8E8F0AC5BE1916E144817CE53344691129AC8C1BB358D2B3FD648E879C2373EB7A945E887FC7A68D4A6A8BE8D1213590F696CD7F07A46F75304AB6F9653C6B8C3E7A4644C7183F43FE594AEAF139ED97FE8F578D752BE0A2AEC39D6FA474E8BE9C536289664E97879C2046965F2B35C5C3EE5F50E0EC537DC92F4622F8FC845AD4AAE6F3F1C1CD0F079B3C1B918ABF9DCAB771157C19445CC35149884748E9E7F5653DB0A3FEB4B6A22F7EDD4C091073B4DFA96C5567AD040DCFD03D8F8C06F7C8ADB09224B28ECF2965729DB669DAF4ACC6DA9BB53EC28F3BC40FE690FE61747D7194D878B5326C320E53E9DB8E5E31250BA43AA7B0FD09B2C88D5522527778B1AD9706551CBE64E95D005E23E3B4189412FC048CBA553D186D9C9BD52E04301E5B399140922690BABD55A89E91A89CCF125499F97509475847938601781DFF91E2C5728F63117AB5E46B0058CF23CD4DF0F850F8CBD50F9EC40351703AEDD1EE23A49285CB9040CCD83DFCC7CA64B3602D0EC606D765D73EAA65AF7483AF174EC680CF99172C60E449CB1B109D2A732910900507797237A38B14AC61AFF346E262E1F7BF5C290694C22082ACD5E21EEB0BA17D2E6DCE5B5144566C3C5D185437FF9150AF8356D22DC4CC368A66C1CD8D11609C50C28B82754EB07C6559723204E65553C93D5AD6F628B0EA65B97186A69419281F7C4E648ABFFAE38193ADA329082F0698CA091CEE2CA63DE821B5F33CB2AC74C85045FB5F7EC6B86409C705CBCA2594E4B5D1F6E9E295DC72D5BFE6CCD9590B069047346200B7E18B6F254794EDB8069FF880ACFB3FB970F4DF373D27FE784E34513C2DD0E6C700277B03D35A20167D346E247EF756E17F2997F8E8DDD86581917A78C0407C80A9AEF504069B24F52CC929B15DBCA631944F3E16C1DA45F3C55EEB697C00CCF24660B05B6DAF33E00F6EC513E2065E0090B8B16CF12E461432E6A3B21754C7F96CE7E4930C86114E2A7D7A809DAFF959BC73EFFEF4242484FFCFDC4E8A45447507BC639021BBD2B02426928BE4A37CB22D8FAB32E55B97EF5EACA5F3BB9E03C6B2E0DD9220731B6124E71773ABB62985074E1288AA955E86E7C4A9394C8E7744A5EC19B0FA9400E3C6C8F07F006034B44C31BA2FCB2C0B774B7DB59857CB2F9F82222D64055A2A2CA653CEA909B97C010BA0FFC434B4775FAA02F626EB0887CAD810C6081572AF088454D09FF2AFD96EF89DD8D466C4E3CD28972A652BD1034B65BE0E6628CCA3D9FC4518BBD8D03740AFCDBF46F4266572972666F7F5B12D4D2E379ED2DD5E1F95316AB0A7C7C807AD6904119B4168DFA2FBF3B9BBCEC239F72A1F5FB44340111C9824A1DD907722A75AC04B2ACFDD3D37BA1FDE4819F0D0FBAB61D0A72B664C8D8B0981B16E2AD0C64C2431930230F47D03C04501C29707B5FF66F8BE9819FDACD64E3ECA6BF66535E5D39998EB47B5AC726EB6EE4FE7414CC5BED56CF0C9D2F15CCE8898E5BBD9D6D9340C0C0365B76DFAB83470B22F94B53DDD079B1658801B21D14C9A2CA1632119ACFA93F741DEF70F6FE8B5ACF456AE19FD603B7D5A4609E34F9ECA9C3019B8D44C0C8A68CB7A2C9D06A9EF7314ECE97EAEC6441ECC1D4269737DB6F1870ECACCB822DF0F8FF694D8557DE50ADD38F8DD46E45035396C6306F32C665B6FF31ACB5B2A3736275C8371EAB26D221BD49F878FE270292540B7331C89D9BB0E9867A3B71AE6A7E532029EB6BB3A1702BC9E2D6F99C6D822B3DD079EF0D74F903848AA4948BAEFE05F575B606BF5C80156916C0AF0BF00D74D357A0876DABB37D2D9F5BFDE94FC9B91E65C29C1884D30573B14598AA23D969539E5DFF0A8F5F8B9D37D2EB6B07985660B0C4AFE72D94DF2B8CE9C91DF195CB13730478E4ACD65B65CF31BC6AC75545DBBDA223FABFFD0206CBBFCEE5DFDE78D2113CF2D7A823DF4D94BC6AB7853434F36F39628348A4F7EDA5B18307E6CBD69F3A5B4C0D10AB16B470A7E7D558CBD6C63C6495FAC0FF8166BF9A058EC0917F3F0B0A629AF76207D2DAD92B57CC3E559F572E5C5EA9529CC4F33FA61D4C9D027F4B862ED7E128D27C6AFA6F86C98E3A515917136087495FD441B5D54C3A7A1480F91125A2C0A71CA5E5C8AA3F015CBA22D3558C1A996B00FF50A58CE99E61E281C086082C9C8CE06704BB686AFD8F1DD5EC0AE94D93E273ECA098CC65E3664DF09E0BE3AD8A577CA5ACF31285C26EA0DC6B07D113E761D321EDB5EEB426D883E94467633D8B1E7EAC425423F2C86461D9C7635263EA5877F12BD8173DF6AAFE2E8E659BB39B17C999BC651062D7C14DE96C24EA46DC15C708B122CF079DDF3C85AA7F8116B9A59E77A5B1D16CD50DB43DE5C19DAA22F9C58796C1C60CE186405F277C3B3A32BB47EBEF753B6DE1C1DA31DF20DBD5D125A1C253D6A708243B50BEA40F5EC6A43D71F4BA01C80015B6AFC6396A3A5C9A30B555660700A92EA0476A52E6B15EE1E444264055F64F84719D42A5D854D91082117112C8840E6DAB690DA578AC625F845BF87047EB5CC21296E1F54E79B9A87B3F0440C2B277DBE20B2C5D4CAF803AC926F82A780BB5509073C3854296FA62101D444A6386E338CE310DBCF85171D8C243D71F993D21CCB7753F5CE23CCBA53DD589236F8947ED0A26E6CEF3536C75F10AFCF687E9FD0EF121AEE911062756379ABD985C2E99DEC3C204D98C58AA69DEF3FA1382DE4AC87F7E28308E872ED7826F01A365584E59A0D345F81E0EBDC45178C00BD18BDA8D5B905BE17DDB8AEC470BC1205B1DF09F21F39D9A9DAF1E04FD1FB62810B173B85FC5134AE99E44FF43B244FF07A15BE0CD15078800D60B1FDEC8964B10F9B56C4A14FDF7FE531CD2BBDD4BF17AB7B4353D00D7BE9194A13D0A313C0A166CD387134910A1707A642A229FFA05023DB92429ED54766D20FAC4DFC07C6DCE8EE38D9A7189F4364A8932E3BEA62F8A8F22473A066A1904108291541FA0F716E586BEE112EB37ECF7DB06246395A581EBC30A2E54BCBC8B097FBD50F1004337878814E932F7C8296EB90DC265B8519A3D420BE636472BA55B8E099C2C1AA6DFDA96C32A44717D52C9AE852DBD0E8E684AB00ED7C744CB881", + "sk": "766DF1B59D8EEB563419919FBA3949609FFF99BDE51C494DC43E6AFBC7E1DA382A55F39CC1DD6472202739B17FD8F6119F6EE2416E3751DEA7ACA6511201476F3A9CEAFDA8CEAF174A63524979B737ABEC12554BD7DF8E35D8141310EA89D9667F769E56FC0E0F92C9D656BFAAA28856C11339DAB43DB3057CEEDF836365F0F0C8124E8BB880DA00880C304EA0445120B10C83908D5B282A40B6511A33061C023283488C58106E1C058D03C22DDAA661C1883083C291C13420183622620011E1A20103C228084425C1A80D51182A8C24060BA54400B504C4124699088422063159921153B68918060298C26090080C8CB871A416429A102613C6450349824CA22003A3455346841C45448A24098B80211209248032669B4200C242061496804AC0906402460C246103422064066002460EA2B830DA06410892858B228800C70823239022088511276AA2486D1B1506811432122591E416515AB010C8B065111122D480915280508C92204818115884040210490006691B026659C8492011315C446E00B110D3124A51C66422210ACAC64C5B320504B72152B428D32260C4084253B431E3B60C49088C44481052221194220124A22D009085D9C625E2A84C21915053264920A3881C040599824D4C3030898865541424544422A4005111C16C09474C1936621C262E1BA64C0A1409202821A2A689CA340A234762CB04881C07058194505B2022C286508822916080480A1984228888A4466411916C248330A0280C62A24DDC82515A446621B32908C6499926482312124CA41113464851282C5B400591384021A36CA4A20990926462C04D48322C9918811244851101610CB910538225E3328ECB282E63344ADBA86124B349DB242A1B1185DBB049C0C28859B0054B20108A444890182C00B70C0138020013812200109200859B9048D1189123A005D49430D9C824D2280E2086304398000BA8301AA78DE2902098884DCB9401D04690202688DC066141388C02B18CA2040CA4964059C0710AA65004B38450422680189001904C6280845B826114B39109474A9A062ADA044CD9062CC2A80DA320008BB46D58087111360490242002220DC34664D9A22012012C83A60C01806152448204054ECAA00D23A86D2227011344094B2444E0262D99B045239570909451C44429D4062A09A72C50B84DD88660103330A314419CA825E2404CD808488C16099220894C48119C9009813692A4B68C214961431468D480201985485B160000C1656386688B302214054C80484E92C48922A72580B051D2366A921680023450512689893441D32891C328720C3025D3A2411B23828398310CB10120822CD3067152088A64A268E21250E230281BC111500011CA046E24A84849B041C3165199B06C44A00580C88002378E04A649930860CB0825A2986CC4C68CD8324153C03160B40C49266D50086920B680C0908DE21201C9126ECB4825A04892849828DCA810A3120652B64188104209236CD924294928011A32814A26200C08644A809122202A02008D84987144348C201144C8B8902240321C311103C0011A248010B08084186CD83890E2142D59066862220C63222503834198A080D0186122136943264802C0899898054A4226190206CA164C0A12604AB86D43404E0315229332054C0486E000658C987022857163081080160824C74512904D128505CA4884CB88716432101B4212E3B83098B60C94B45008050C08386420487288420063A0601322420B144019B6708AA08CA0348AD48608E00692C1A8850A92885A4426CB447260423221A091A3B471CC388C43A608C43460A3B44949C62C80B8711002904AC088A042321B872402070A99C041A4C4840CB5680C8588D0B46818104960A24CD4448858824108155193C88C09124260A251D420291A0810202810E3085123174D91A8319CC028C3A0900B1650142406E4380458082A83040813401082403119B62052A69014A364C120694000104C806C00A4085A90880C218152167000897019264D63342E0A470522994418C4401B8725CB168199B8211B964D91142D0A440483C4449BB08842426222B2010BA444613069A3186514B52101B26D11146591388AD134105B364C011891A386012110621935208BC27122A22851222404172408C32851289204952400B36D22B12919165221254AD3068A4882041C200019A650D7C1BEF09D1A5AB2F21E912D5DDEBEFFEDAF5E953791304B0D2B2BDA83AC05A83C57F672EEE2E73BE9022E63C64697BE5638B79142BFB576C0E7C4035365354E5D394A8AD64B33A9435619CEE98991E8B1E97D508E295A394FB4EE32CA9A0DE12ADADEEF508F07F2B48A5ABA6453604CDEFD5425D6303616B847D00B5D3910466F3DC420E0F4F6D5FD1E0AEF8F5848DF0FA693C3DA60383235807EC330665AC6DDCBE3918B8A46EE5A59A387B5015BEF1299FC869E7D1D30AC835B3C1F2E727F21DDBAD92650A8121538AA8A4FCADE6A13E3CECF4363C2754B3DA76DFBD4CC95917A1B1D1363329E8F11A2902640EC318144205C7758A984C596A40BA5C8DCDBCCBD717464ED2B69A65EC8D5D8EFADBA48AF762802DC0A36F89EAAC39B2E31EA348524B956A5DA78DB04E281E14AADA9B89714F8FF2E781321C8C4620A165EC37FB157208B256672DE198635BEF161FDF89B607F1727C75D9D45D70A8FF94413A93405D06C6D0D822E4FAC5137596803032A06A15BE32CAF1DDB14A7751EC712825DF6019289222D2BFF84FE8771D4680291E7BBFBD3F31242CF086504D015313914D6E6E9489648C08D7AD621DAA70237DC32C11C959BCBA0547B67F77FFF0590F7231A8026434CEB71159A31DAB3B9836CDF74C499343F9695D79D33557C13BB07A0E889D668121BEA0F0794B5319ED4B1DB298ED191C69160B339B66DEA5545BFAB625255636E5BF492E67DE4D33AADB56F924AFA84D91E8A1E6DE385714779F632F031DDD60569C5D035260EB1A0A995D3346CEB0B511DC87B13A1D73FFFF1169942E3D788C759CB3668A32013B95C5D498F4E05F26EBA9A444797458244CCF499427D4B0B457C7E7A5CB2F27ED58698E0C16F89DEA4903C7CC7419BA70AFBA2914F4ACE876A81D29BEAA27DF75E82F941D1538A631397CC9593ED423AC62D147BDFBD50E305CB3A03B4A8A0010A1CEAE0A4813F6BDF59F3EDF3364229C8F524553717D5AED1F9282B73FC37216B591C7F762FE3423C5D363F3AE6D32C06E192B135D7EE100714F5682CDB123B6EA8AE5D03642A435B6F2483D67ED91A58A3F1EDD98F342F819BF373E77BA3C5CEF082A7D58DD103B0BEFCD2F102BDC2738F6471FAA24E4DA7AEB86CD0A64E227482BC864A7D2CB9976CCC38BF1EFBBA872244EE2C9C366BF161CD5EA83E652C85C007A29ACC0D8783507256E9EA53C513612DF7A1857C12BFE64B106848688C70C05A06148B41E16B240AB2222A770BBAF3643564D5C10055AD40460A4028D03369982524D6DC3C3A0FBAEA763528EB3CAD5022F37126B72F1C239D801D4B002FABB90AE9804888F42ABC2601F18AF8BF9D319D0A8576ADFADB7E47DBB837FCFDBDAFF6AB5D16B55DA2EB56201F66BBE9E0BD78EEEB2037EB708BDE7999E2A3529DFCE57A7DA0DF50913C06A425CB665467280D2442473018214698E73FAD8C94C4CDFD01F20516B9D4C644DB04AFE2806E1767AEC74FCBCFDBDDDA474808AF96B92A2814AFB46307A06E15FB5C0254579776AFE8C7A86B3DEAFD5EE14D42E44A2A89C53BDBBF6A85F97B4DE490D1B3612F4BDAC78FC40C97AE572C5E333C202556B682D106C5E7FD814CEB696CD94E7D2F75C5DBE95D5F30672FECCACF629504C8D7B2E15505A241189A687D715686D5EF6F48B00C139D6346BC8FFDA65AD6EA7F2DEA62C91B87FF00A94DBAF52808B51F1D3E4646997D3FA2A1BDFA49ED5119B7FD5E6A3C2BAE019D5C2D52B8F4DD733B3D452D71B5D6E13019F8DC0832228B836A34517E29EEDFFA7E440B87B0A1D1A85773ED178EDF20614733F846644D9D87B2929AFC75AAADC84A8EE46CFA64117265B7CCB4987F3B9218D47DC9586D47AFBFAA700CFEA59AB29C6253A2C85D8B03DB1610761D3827B79AFA0ED64F6E4258622B717D06FBAD64589D00213FF42629368871618A1A76CBA764ED9AC529E790F6F19937478D0AD8B00F47191F5D3228922AB1CEA8F89E713E9BFF2F0A2999E765AA79F01CF93CB519929DA9A9F52534396D8BED4F997BB73ECCE290FBB34EF73EE344D7674FE7CCA81B9C3E59C087C68D0B5AA7B30D7204A8E5DFDE41FE6810B8AA73C8D3B589832C0AC61A8B5B6DCA3636C19CA8D0361BE98EDF9868AB622F504860F98EBD2AEDB1C4C21BD5E082BA30C0CF2887F2D3C379B4F1B19588EDF9881D1A01A6448D9740EE5A13782BBAA843522E82199B84FA92E12A58E440E03C17098C327DE35F91466CBD7DC9643130D91548038EC7AAAA490E25F88F2B4A50A9F32BD29AF4735D3DCE745016FA1F75A3BA7AE337DC25B5162D8EFA78CC119C57E065292C84D5A54908C14803011D82AA40678FAABA0C79D4B3981C20E0F0A7D890612A9BD8FCDDB59BE33549A6FF8E00DA5786EE8E94CD12B2163BBFAF8994B98FB8B10F96E17DF10FB24E55CA7F9E24873AB7D6A3442391B6E24B67E40E3DA4B63D558D9D79E1068473D97BBB3B842BD76EB96A3260C1F537D2E9CB6F0FFEFE3DF8677763ECDF4026159A407EA96A6DD8CC7662E3D773BA23C67E93CCF73710792A8B8E715B6F2DDF783C7F9E8F70F5D588311C37DB02B6E4BCC2D63013540ADA9C053A27E2165C872B21F867C64BAE5592C9D1601F7635A99258A2A41B94A6A1461FC2FFB1C9708387C89664E218429A1B2BC3449FF4B8BB04EE22F92383B9214C6DABC3BE103A4220E0BC93189C9672C006568C2A02C424974323EAD572A5DEE85DCF8EC343DA23071651380E5ED3F0CD03EFF650D789CB339ADC67AFDBFE0BCE8E4584A8FDB9A4D24C1137EEB55E53361C3910073DFDBFBEA44002E44B5EAE15B147B4A90EF0CD1D886DF73803AA55A6F37E9FB32F7ECEEEE495CB44A2965F0108052D1762819D04E1CA28E0A5240AE5D77B0EA36D42E49C741B09A5D9C74860A9AE013CE42C55B5BCF9988CF9A7E231F6784AF6805E5B79271402857F2D18CF59D69921AB8DF6C936F98A737CE7B1839521272477EE3F54164FDCB3BF4B6CCFAD5DF9ACE602809AF8D096BAEB9EA02A901EA7C9DACB20FDDBA38AE3898A0CB277A7170F6CEFA70864EB6571F96E5DEADCBD03BEDE4F3053F66C2BBFC01B99F05156EF302A29028C57479219E18CC73C29D4C12D70C9B99F0FD9F1C9CC7CE8B1FD4F9D0FF82B703A2C93EBB3E3E3D13A28A4D0722EF63E8BC6D67938621544140E7CA6345F88548607D737CCA54E308ADA3D17E8AD01E27159312035E0254682588F4073F829A262A1C37F8E9AD94F30C1079CCFDBF9655110D689887575A783E0FB5D3E1807F62CA14D7383C56A37695115ECC8A18D3E6E197C714AF1F0784900F8025A37867F7042E3533571FFB13FBF132F90BBE6EEB31F759E8C6B03396B5771191E415BF3EBB8F9E55F2514DDFFA7758B4842BD76E5DAC567BC7D440ADCBFB356FE1280D51351F9B12B3281F47592B4327EF74873C70483243FC12952BEDD44C4D5ACC10A7F513024B4D9811E91C1D6E0A5A015A719944AC8734EBAECA8EA22FF55C9B5FF8199DF6163F9D3955A96E9C5097311E197F4CA413B5909DE94AA2A59F681808CFD75E887747F7D539086DD980C34330515D50BAF6F7D234B99F18AB0EE6A427FB956BD747DF06B3D7078915BBAA02410EAF0EC06BE06E8BD8E39F5C0BFD43DBA1E0D8736C0E27439B43757BFDB16B46428FB3C06F7C949EE7C418815A4BDDE5688830745ED66F25C0658BE197CB157FB49DD9F490ECCC0A8D1B395435E9477767F00FB257C73B5225BDD008464F5F8B63E0760988C05E1B6BDE4B407357E3B269FFA93A75BE609F16E12130FEF601BE2B5BA2A0F34724D9B62786F1ECCE5948DE70DA662DB9DEEB037E398B19525775FFE9E07AD70507DCE5E1A0A732BDD1BD3CBE810E10E6FB46E5624BEF6AC2B4B98D4D711EAE84EB0AAAB0584A413088622CD9BA87468244C4248FC50127CE87B2016DA3C883993A16BE50E4F1639F0669EAA9DBD5B396465FA174EDC3795AB341CC27DC61E21BD724564E6AE371619F8684499E02AB62F81A5379877EDE16267C974CEB7359E4F0D951FF9FD551279899E3D88113E5F9E7CE9B3090B1AAD78C59964D9CCF80AA77E2B31BA06C8987639DC79BD927DD45DD883315696D5C67304B48C71FC7B4CF39F22F5CD3B36605111109057A1E040FE401920A237DC12EEC2B3DF5A906865F4A74A8581FC4C1CA0CA38E4C6242E5B07ED99DC57C47719F6427ED8B2AA53327D49F7E54D1155D9623053CC638A2526803EE6CE115309130DEE2A8C18925976C956AE5878B7EB82C5FC9B802A43F82E4E9019FBC644EB80209767D6D13D4AA3A6F4CF95142830B8A483E2CF474BF63421FCF9BF44F7D9FAD4F0C2C0A78B4B45AB3735D1EE0BDAE8201F2C3E40088942C20426057B4711E3A4E0CF672D52524BF283AACA49649B1F2501A155592C7FE39CE1912A1085D5709B38DFEE74EB7A8A48C1EC7D21FF37B8C6EA209D6534B6328F1A99A1AD3198894C807E4AC30F6F85E4D472EC7D58111F71037248CD833B929DF928B6A0C645578621E262A8535B4D6232E30F6A591577AFBC2CA4AFF9C6E9AEA99527E285777763D7DE120C62C37A605B02A45CC96FDD211C2E5D00719BC8061D295F060E7D85E5D09E11B959B13EC3049EEF03B479A21C4A5984EB75780A26ACD84405C1DD3ACB9CE822E7822836802B4CBF68918C213A513F41E5BFEDF1" + }, + { + "tcId": 65, + "deferred": false, + "seed": "F53C24BA9D2E6C4C35249377D1F653B2E8F7ED655292EAAA86A5720F46A9FAF6", + "pk": "C2385FF5B4D2AF60F6ECE79D62127B6BD35E7DCD732C94E86FA4412B4073753E55B13A23955D57A3FA27210CEAA2089B6B046CACD2F629C3A5B63E705F8FCFBA3D06DCEC47E3F643BD5FC5CB09E1630B5B00E28F84A8FC47D224F0F1A70FE496B0B75C234FAF16A386600CBFFB3177664915A7D1F5CE3FB7EA7A6771563CB00ACD2304AFD0B6E479CB3E054E794D8A32D35AF3E0D7AF2151ACBB8D4259E756B60EE1950F18E0FB40A914E42C1C62845949ADA186A3210429B8C38CB97002FB160676A72DB53E333D32423ABBFD6476D0885D9773E8A910DF792C50272B609DB4F8352F5C8FAA0D9C5628134A068ACEFBFF1ABF7CD5BDDBEABFEF7961B62B82380F1B8DC0C5A35B31D46E99ED6D95802349E4A7D1421A5D1E92A7EED88BEA564D5C1F2BEF62549FAE3A0FD128A2D097BE3A0C07165AA67CF0BE37DD21F9A8E0CAAA03A5232DF6E989DCC85783C1018D40E2FF19FF47298E10EC513F6D3061EDA08E182C1F322FFDE8F177A8F8A9BC5CA7917443A971C0B1E2A1BC975383B70277E132D6A5790510DAE885CC68D1B663DF26DD885187CB87142B1FB39A3E772E7C3EE3469AA9287C0EF2D1D4E4E009926A7BC7AE64779A7B30B9DEDA83230E28D196650DFB24BA8B876438E1A3034407C3AA88118EF17BC9B429A737FF98A9F8F2FC7EE49921A298EC8AA9E53E68489E75AD9AE6C478883C163EB62C002EE44E255D229FFB8C8CF64226D5E63EE312BE2635BCC35E725D5DD9D89533ED5FEB70E9FD05D23A4180785003E8E10D1A1A2B4BC347BB38F5657C96F822CC87DD803AFBA9FB1573F769D6F22706447C3EC0417C4E4F965952712DDA63945DFCB36C9BE20FD17B03939473AA8AB3EFAF165777DA74FA4B43031C1E2C3AB64B58EAFFD7BBFAD33FD09AD64B7B1338B87E4DA87375A32F1CC0C8F6C47C4BD303DDB75ACC74854861B920DE39897C2F7006C88FB2A67DF694899D0B035F8FDB04D5F8F26C901679172BE20BE761BD6BBC48D0611B9CEBD5C678F03366BCCBA33C272280B0293ACD0AAE04D86922D4016F011D0A9E9E7CB9CE0C254A6AB7CDFD644DA87BC8D868F4974CE5F404D896DD823CD44C60AE112CE6049757F0FC1BB427298D5C5183ECBBF4933A6DA01E1439B23729FAC858D12CBF2488BFB206B5169A0CC5869E18A2A4F00109643DC1898BE04DFD97A2C3B03B72925230FC5C56DEB6B1B9427ADC8F35F76CA0442BE4990803FBF2CB7277AAA475CC781F5B55B582F8AA5EF20C35D678FADE39B266D490B88481E9B7DC2400C33A4078A57B0E64A177E8275FD1ABCCBC7A7737644335B70A92EBB7126D1621143753C62473F19AC1F6C2E3EFCC90DD8353A61C1A459EBA92888100327D7D15CA5014BEE26E1899102052E39FA36E0397751859AF2742D2092D8547CFAA72A855208844C1CFF732DB881EBD9DA1A3BA485FD88C7756BD6C60A318B3B307BC6CF86BA321C67575D9521DFFF1334C630CD0FF87E9A317E0DFF3608680A16B35A67630ABE437F808E9F3D495DAEB8561F98F6E24A27C32DE6F3908A8BE72DB5BDEDD48E4C4B66F59FECB678689CB30BBD139C76EDEC7AB02FE746DD3D7F1FB180A5AA401B4E5291DC41DDB07F3035B9206AFFE0154081F22C8B9B1D33005C31C4070ABA946B4E85B2CE3D0ABA48E3B1F0944BE97080A6B0FD28B24686535E5F38FD90F11B7B6432E8DCF0C9F2728A8257E47A357CC24B4CD19F5570EC45BFD58FBB078382EE8824C181C8ABE78F1F16B39425600C5253F46A07B9D14F7D4E8B3C762AE9A38923DD422482733D25EC63B07880C51B602849B75D8C2C6DFDB81ADE1360C3A977419FF87B6249AFD11CD6FBF4C6EE7CEB3F82FEE038D313BFD07ADDA2888E7FCE44E7D382FE484DD1FCDB3247C9548D06043A0050B6370382FA972B80984B7E0DD2D096AE1D7C50307091E7A2B647E1136ADD0F75DE7596A7BD3DED6DD24E0A5017B5E875983AF1764D046DA4241CC678FABB2457C271212194F970434D893924FF3F4C41A4E58EF2BEFAABC1C264AE028197EFE52CFED818515A380D52C68EDDC680AC71D0855C024CDF4995E30B90DC161F28627694A0E010AC5480CEBFD281403AEA84C8286ED36315412924E1DBCBF220EABED8C0740F15588F072560E68B282644A023C817CC329EA436CB1257B7667C1AF8BE26B467DFE45CF68DCE933379928C6FC832E731D25B9D66AF5659FE701DC66B4EADE812F3C907E140EC23C5C06A707377749C0E448B7E4A6BE686EF9E07D7B313505A5E5235F4857E085583500C1CD83AD311668DF5D969703CF866875B74621279F5E1A9D940EDAD8063E6ACF290CF6418C3544ED1C1E9CBEA386FCE8D93690499FCD13D8FC53A6522BDE20B1E87BBF9FCA5E2B56D9E5B6D0AAC167BA43FCAFBCB5C65D3992526596ADFC708F9AE5D37F7567F60F7DB56BF23A0C3246C8E00C856D4912A0C9FE2314AACEC37EFBA21B4BF6CF684B1E06DC447C1D1C86B14DE72EF7EBA190F5D3B957A8666BE27712867443E78C194557D2BFABF475498C9AF9D5892BD7AC30E8A08660DF8203CE47E59A083ABA27C1635146D376472F663F2552FEF0F8BC36D7E63524AF82C985AB73AD44B269D3C19A12440578E55B3A10BA641CF1B9D6136540DB65B0A6CFC6D0466CF3C3736226845BB8A5788DF4AB4A96CBCE8F407D5D22D9F74C2F31644EC31498929E119D33316FE73EAC7B1441048A950F3E2B41334D79707D55114B4F5A6DF9FA6D2C699C3F6654EBB518CA8004F1DAB63CB356270ECD50BE3BC2F8452D91E3E241145EBD6F0D14E7BF95CE3B3DBB397877BEB356683BCC22F51767A1CA35436EAA5B8BF5B2BC14D5460AE1B9B6C8D9020D07C683AEE4AFBAD19E7340592AEEF4D61D17CB79288B958F2BC5FCF03C25E0FD2E5D0689F9F7D60E7D86779FD0EDC0F832F6009DC47910EFF56829C49264766854A33B10E3D5C18792D93529FA952B140EC72A876892031E1F927B30010E57FB56E2705ACC3EDEA9F98352F618B1E0E1F87CCD544FC76032B9740A1731E85E7B2348E688F8F548277B43B3A1F2071109A8FDD5B763C4110F2ED8734525D0151D6BA64C13AAB2192DBA00A1A26BF1AACF18AE3B1937EEAFBB50D7E3B730FFBC6F416DB7E47C6542891333652024A9B624F4765E7606B01A23210399D118EFF5E4EBF8DCA44CFC6CE37F83CA8F1EB2B22231DE01428C0F1CC73FBBC55A56F29C44CFC0E496481E2B2A0F5552CFFB4A275819769FBA6F1E3C15201DF78E58F993052B9831B71B70B9C2AE265B68B8FE8BDA95C0048DC0D3523A45CD5EB90463C0A2CEDC2CB20EEA3D84B814B5E5C7C5CD9ADA8B4DA4C07511A339323C30BFFD7DE9E0AE0D596B638F41DD47DFCFCF9424C41EF2D11A7A86293F0285BA6E9BE442D1C38BE1DEB2260F6457FDFC57B5EA8EE0A215A954D8D366C04818AC1DCCD367BBCEEA01553092711E9B6C2423513E4E5A15F497685FD22F02E40EEFDB890298ADC4F1A4137415F8DC0D7036CA2A8A9EBE2C1193C8DAFB209EAABF8E9B479E4F8487465450C4423665C51BBD51BA8E38F3DFB144D59A7D2339CB5E5E837695AAD09081F80524D77947982FDD5F9B3CB2605F3BAD6E9C1B4F21DDCBF9895BE62F46E8B3415786CEA7D7DADB9E48BDDA35C459A5E1", + "sk": "C2385FF5B4D2AF60F6ECE79D62127B6BD35E7DCD732C94E86FA4412B4073753ED54505441C3C70B3B7D89DAB317BA68655A52A93FAD9A042184C3ADA17DD2F4AAA36AB503D0F81ADC4DE1DE655304A8F14F5EB687DAC6325539D906C83FEA1EB81F82D91C3387AE16815E04696C47BDC3CA909F33C18723AD614C12A206C10D31C350E8B8805C912721C8504012184090552441210A092112412309C1066E4C6400B234CA2C2841A2191D142244396848016095CA65021946823217109410A1C49854348909818488CA021A44882CCC86504284621A4052383519A062E02364919112A988290A1240C420610E43651CC366EE3862C21B18419230E09398848942D54242CD1A04581A8248B448C0B950408354C0142104800409B12521947241420281A134D4414525BB06412207249102559368A500412020205814608D9C8288AB2649CB20449948D482691593252C0A6841A468618997010224A9AC429E1866C22170D14A844CB06625C466D1A054043360E0A278891409111862D4C44005CC268C2228D49460D181970604431D0C84D62B8900940061BA42500922504B100024291A420521319449C0200E3824808060081268EA0C828C2301049126224A5902192249180518104301B025144800801264219C94440B6049B269220A0611B139000222988B8300308021947301085410CA9301C24062490500B2769C9203163466C5000288B0452DA28411AC2051A9744D28660A3326982328EE3B6288C828060B22190326263408803424202882082B684A0C050138040A2A6806242200434468C2841119808D428709A469004426E01900D92B08083320A0A3240D3106221C360A43202D01232039521182206D3362463A229083420242486210084D9880D4AC601232045D3323210C210242362532062A4324C8BA0681448465248416098480B10854C882808854101224E49C421CA086A12B67002B265A0A88C5B202D01048ED8A28403460400C10941A66083C4501B200418460420276A5036111A956162888CD9A08523C70090C48D59864109220E11868C14824450A8248C220A60B09012244D53C01140B650A0A24D0BA28192106C00311042A65143026211150DA4B689248944A02084A1980DCA4648D8482509B9089A466DC8428DC89608D0886CC0104D9B466DD1B0240CB80D821486C1047243A46853840453C8608292009910284A120DC4028CCC321108899113B30542006AA0C2208330629A864CA446501C4232E22025C3242548922D91360688A86C60484AD8246919946902B1614B8205590268C1B22C1B931023150481C68D5A260DDA2244821086E41400A3B80553346562B62111C90888A2481A364EC44410D210825318128B2829A0340609424E8B164949920C9A92449A06284A180A980045E1C450A4384891C63024B96C91207049248C61802D23A331D3326113244948344D4C261021A124CA14280C1012103066948004C11848A1868109926D93469021156AA3A4100038851A99901A089219008923C1912430518CB600131921E3906D4322624BC04C51466A1A014A2034894942641839121CB291E4306A5A08861A05611A82414BA48D0A0281CB86904A2686D83841CA080A1B09059A9631E022829C308D08054A832685CCA6045338891BB06021B00418001223A921CA204EC0000890028C8B063140A8459136080C23840AC691CAB64412134500A42D21945111422519445053C425C20260D83001C99084C2224A0401011CA20CE00244DA0629E18469532086A4886D0382502288018A1200C9B07194040558B60D19442C4C9689E13865533602C4A24824122D19888850460C1819881036480A001193286408968082A04013372A20220282B26DDA3866E4442604B800D230620B0649C948728CB251E2406E03B58D0A02044184011A9980202571DA9291A0B67098B08C99C24DC8925009457011C444644026513880D48011D2B061E128660024915A00896086450B431102C084C3288102252911B24D842005A49669C0B4250AB56821904024156611C40964C0845C308913458143145013406D61C885D1A06490462DE010881C9824441010194221D802711AA65053084AC1966C8C228910236862086A13C43051B06C99104D022601183781D8109023868420272EA3B424C0340940048E40B685A486640C3344D0228D0CC10915C8D6BA68F9FD41BCC8679EC985AB5D74557F6F6D035539B339C408F2C24981BD5C4FD018955077A79C3FD94EEB1220DE199AB168B00F2EE837275D9CC54ACEBEB0613C81004681574F9943AE9850AEC08A1EDB44859E22D383A7DCDF3811ADBE6FCB0C896483F61AFBE41EE57E253EB9A42EDD4740192CF21B0708E94054CB14392E4157A5A88EB7930C7B104A6C348B028CDA9ACB2E2EF34BF66240D4B21F57E759A45EF39B60B19F7C1F9851251A46C13B973AD63EA39117CB223BC943A56D12E792233DAF0729AE2A58C56917359D2A6712A0063E87A8D424D28E2C0E3E4593A0A8DE46580DE0F74FF9B05453A34871581784160949C9AC9ACA19E18EB3143889EBFE0A2379194F8CA251AA26BF3750BB69703BF138A7FB44D4A19251FA9EA697927EB8621513E1753B10A1EC869EB486036EA73B0978FCA3017F933F027AE44461324D989F47E64B7AF616C89EDB7DBE101EB6EDB517B4F342A6FA89C3813DF0F51DF5522667425C694E6B2B872CF884B31706AA8C2B24FD6BEBDB2022C86660C7300EFDD92BCC2AF803B5D77A257000957217486444E016379DFDE75DA83DEE46B84B1F86F43B02BB0B22F46F1540F10B8C465C4412618EB64AC8235DFC7F695D22B0B7B3AB557DBAE7D5AF0DF012E595215E2A1418E7145F357BF57413DF34FD078E639B52963258113A3C560C90BBFF7BBE70E3B5589220E211A6CA8045C9571437CC9B3C24DFB14B48695E2053B88B1FF2B7ACFE1880B4D336BBFA6734747C2A6B7C460D24C3E6219A2B0AF769F794B7F239A4CA0936162903CB0DA57072466E610480BF09CC57D8ACA4A1CE8AF298D2E42AF44E380D94190E20A61BDA4CDB1E123A03DAC37A73F89B843FEDA27EE7EACBD49EE30E74A25A49D93A1972A237C95E1D8F4243BFBDBB0F9C50E03C16B37B01FAB3D0DD3BFBE2CF3CFAAEF7295BE80B120958946E02461EFCBBE668AE52DB638A7ED808B6778AD7D11EE66A705F32E232D39A0B9D73AD33AEC4799C791B7033C5949295A3AE385F7075943136685BFD59F9F1F1DC61026ACC54E65661DE4DC996B53CB612370833037A15D746880FB78CBE5BF2519280E7308C15009E0D6313D43A8DE343B51BE5C5D736CCD71C536FFF1B2BE1CBB8F4F873B580A9165A78B617C845FEB074F86A2C666CFBCA2C5582F99B7E5B2E11B7FF253D33151D02DBD056A06CAB4B43345A0CFFC2B8852D837216C36B6E9BD5307EC23DAE29719A896FEDC2A2196B426AC19667F562C3D2D97497FCC78FD50449AB975A8D65CF3F143963D4DD7B296F06113CF2E91A9054AEE8BE010E76B33B8864FF0748931577F53640207C6D335BC928080A3FDD2C0F8823FE89C53F7BD5C468DB531260D9DAED51091A5B8070B884C1DFDDAD50AB49ED6E6EA101339FC9A528D95D5AD49D8975756A3A4518D7DA8E3262CB1BE9B8533FB9FE16CA796AB247405727FB32182FA127A659CB40C810861CB048E6EE8442D6D3E9D8767B559C9180533FE3E86813707139DA97CE17457851BEA7DDAA2A32836922D29FAD031E7C9B1F9CF42621D2FC6FC785ED1585A13BB5AB8F2D119BC0A6381E29241E8B54F28479F17CC84E778AF97DC779BFB14DCF22CEB3FF7992BA5CAA89A3171A7D766178B75F66F12B6107E046F5FCC977BAEA650D6FF52DF4B2BAB3EA66BC560075A09CD8FE7081039D97F63C3FF478771747879CB4A4EC68807B4A7B70A21811C59CFA0332349F1A490BC727C4319B8004D40864C82BA3CD5C0788DBD9D7918C9309A70121B7854A4401FF8F283809C6647FE5E1C125569D537B50232E29E13BD97ABC77C083627813983F0CD96C3E79523298C872B19AD6FBA2A7754F89B8B64864FB798C80263B9138F1508157C37344137B87F3B996649D954A8BBE42A7D161E1474BEC1BEBB09AA11955D3447DA3101924DB9D0A2C499A579B140F5346C45F9BB621D78C95450FC70F245A65BA12D42AF7DAC59DB5C637D0DC8FD262D1D07BBEF45289552FC3BC2E9454BB5B3094AA778DEF3ED14175A8AAF783C115760B36D1F7AFF8FE083EDEB2495CFD65E1E363532215779DA1DED3996365B76E183E824E46DEA3D8D5CDBEEFEF60588EBB7B9E16E3B2D36EC34B463639C96200A34B5A8D31FF36661CF5E1D5E5F940EBE6012466A1842DADD06E1CD2987E0EBC10CBB7EB0AEDC00E93CA0DA7EB1E856C11BE2D6213113E3B5D52B7D5573BB8510EF41A71869A3B63A419492557EEA47E33FD67EEF605D0A77C05801B453D7765EBE207CE58FEDA0ACB4F7EF1E55E2A30C5560B1E22313B8ACEFB9BB15700CE1F60F99C87AB22269746B11EE963123E98071FEA8E5F0D28A5B960C62BC86B6A34DB2D21C82FE86473D2CF319C385B30283443486EB78CC6F6FCB70AA31988A4F6F328F83E862E1FC9DECE5D674689222C8B180CDF1D87A454C92F3DCAD346BA6FFCF56C70182EB2094BA136E4557920051AB41638277EDB2010AC169CC7AD6C326B8E73176A2D2904AE9F480A3FEC9A44F1A6552E78501F2B29D078D52F82EB54E2862D0CDFA0C5D13F166472EF24303899048911FFC3A736D45EB9202A18868999C0DB5653765A5E13801932753C3ACBA638C700B53FCB4CD1097D7D60C243F60232626F8FAB697ACF0E14158DA4C622DB29D52AE0E67F2EC9D1934C09DA91AC92205FAA39C08AB2CA18D5DD411B4451BEAB2A0A7433B7216C443904C157DA05B360265CC1DD8DD396DF03D47AEBC3CCE621CE5C0A55D128362719B1451B1246AFE01F548CC041F233A7E048AFE518C6BB90368FDF0562BCCB228A3E7315BBD1052BB42526DC233B9683955A13EFDEF5C16F18ABA2F6E073E9B1C77A60614CD39319E70D0F15F677D21AA806A68127BDFEBC6054CD6A46E12EF046DACA347E3B490DDB5F905AB786321CB587C771AD65BD4DF0C763E0E5950BB45F494D131F0F9F713E7DE8A1A38C6B0A41196CB8A5A2194E54284E295827485F79FF3D6AD5175373F09B1C9149B202FB0F4698672BA956A9342793C201B16E5BBED7B9FB67548335EBF045CB6A7D0C1CDBE524B79B6CC94EF46191FB43031AA212210EAD6184BA77883AB9DE9816D133D39D9E78CCC4927F647C703681961E26AC75293328C8C309ED3C4E1736FE30255944427E84979708D58432ECA8E6A4AFB1A2B6E49B5FDFBB03B4892909CD5272783330EDFD4FA333CD931925BBE58D2BD91DAFD8F78CC458BD2F4DEAACFD08E1B3B2BDDB6BB2AA1838BC18088E860473FD3DBB337FEB1E4B473ADC1CF470CF3E6C37B80814A1250A3A49E27B4E8BF39DE69DE5B15460347963C6ED8777BD9FF2D10CB4B5AB5C359165D8D5D32B98956C0B357BC4AD66D44F6F806EAD2C983FF682605EC53137CF7EB4F9962B2CD012025C25F7E1DDCA033237AF3F00B773130458BCF37541B140E6E61AB7EABB9596758DE62C089326AD8DC30A3BBA2DA22AB72DE3220934E10AA0DC70E7EE1F2876BB8A368ADC58F820839982BDBC1BFDF8C1DEF02F1602918D6DF4360FD8D2F3FEC610373271924296D666BAA4C90811D85E8BF06DF9583B42D77AF82BE9ADC7C6326A95E4B865A1586BC5C6BAB186F3C9247F5E8D9FE965A80D50EEC366D10059E0C1D8D6CAD7C4843263B3337A75748A9CE4595C433B3021DFFDF31E45D87AF5025A9D1084943A74F2E3794F0FF83729EE840ABA02D0EDF2E79F5897D177607EA587DB4F24A6E0C4751C8316809EEBE26527B94F25DFC7F6B8B54F4E9F5F296915BF2A8ACB20D8DB55C7B2F852019202EABE8EFFF3BD09F303A321F6C77F784637B82CC850C41028BF4D016020EDFC4F2038AF41C8EF4A22684C38338386B1B8F825A6038033AAC64D17D1EFCC3C739056E4DC66744F883616A5A24BB18AB58990617B9362F2D06CBAC7D4DFA2A728EF2388815782FDCCBA7D3AC321FE53E52B7DDFB3034C4FAC11824D823508793424A610A5462844818C928E8899F0A33E3A5C2C0E666E02E04B4FF1F7481F7BF2977072AEF7A3CD28706898007F7E3F65844128BD753873FFA555BAC0B0D04DB052BFC7825BBBE7E17EC92DDB203AE71BF85349F26194506D95F2EF54E1C6B007ED5D784BAE91B4B3AB4AEEF1933BC3E799D02F09944D20A066739B91C3018BF9BE763195BF5D934567D1F2CD6A4F639296574B06E0FD867D93DD1D7BE642A8E3A06187619240DE0AFD0681AA84E517EC1C74CFD9B3603BF8EE427D0E0B67D365C2E8E20717FD02F4ADFF1E4AE5DB91BF73D691AE1C3C4379C08B58172CAD372FA57D7BEE1CD37330B602744A793158EB421EC88B574B5AA3A64FC21B482D562648603E2067D136DBE20993A2B21F2F163A53EFCF19DDA105D9A24AFA4C916565DB7D5B462F0B48025A4FF8A7851555DA65DE6CB4D57C4AE1E786EA621870E9A6A2B37E09BDFB7CD29104D4BE15D71251E2A2032CFDFB67DA87EF99C23D4699D9804852B5F0793043AB691085A35CF4C8E93CA53E59CA4898B2005FDE559B7F5E7DAF6ACA3FFA45369373ECB89E3678AAC8E7F49F23A0EF032570D93BD21ED5F09F6CE77C21D5FE74796DEBC64CBCD156F27AB394BDED0F330757B4225A4A3074B65D4DC89027BC441EB6BB08D3C299D58CECDB15992D849C583EE935E34711833D35C8B57CEFFF60D84A8977415DCFE05D66D982529B95D5B13B18AE6FCAA86C75CB1CBB207A3210E683F1F50BFF5D" + }, + { + "tcId": 66, + "deferred": false, + "seed": "C8D0778FC6359E5FA663FC32E9DD1E53F26671B46C7750DC50CE69617A36D2E1", + "pk": "176C08BC68F3336165D67633E09DAC0322DBDF16F4C3E40455F2608A517B964397B289F9D4641D75BED239638D5292DD04BB9A264A8A9DDA6C256589EA35BBFD41C3E4DCDDBA3963BDD7DAD6E7D7701A6EF8D79A12239CC77EF52BA01D236C9ED0A09E26729988F7AA137FABD14EB0B24BA5D900628830115913FD55EBEBB1D4BB3286D9D0C9141481D3700959D415E3F1DBB222F968BF66DF0DD0239FCF22DF99D4A90F4464CD25D31A5A34DFC5B7BD06A2A7EB7A6317EBD6275003DBCC5803C13C461D98C7E2F8032051ABB67FAD382429F050E7C7662FD2287CC5C90AC807B1E3CB48B40FDBF2A2849F72887FA28F8890890B93D9F8747BB3D12A5EA03ED29CEBB36C49560626112A6F91A7451F13DB5B3F199043C9EE3CC29F2A359C87D457E87EADA7C16ED28A38ECD7A9B3E8DCA5222828A5BA5ACE01D80D416DDA5A86A6C6D765A3F699FC403583B89BA0D246C63B059C8F438EC00F6832B977A6E6075BD147E11FCA34026D6BA629D6848E80740B9972C695B183C836AC198AC8242DD6E1C2AFFA7414ED108768F210EDD47CA00CB37F77B725E53A0AE784145CBB4EFD62C92B69CA844B577DA4C4191EDCA87433C8A58169EE98CCF5BECD03106AB77B161D8D2D57D2953E6DB40172C52634C6BE81BFC10F10F0756D2D5879C25425644AC52B9C3C2B6760A635E45BC8D7853597451B113123F61F15D2CC28E5435BCC2DCF4307D1CF8641F344AB3FE26AABA75D93719A061F86D62827E648213DA604CDED56F9112FA02BEF09A700D5BD96AD48A2E76C8F4E23B23AA103C878BD2EA6DDDFB99C9CDD359A0BDF3DC5867025B97573F9236F5ACBECC1781035B4D4BE20B8DB36200D988C4F8D25A9F12F103FAA96214D1BED02733867FC2660340E145FBAE0D7F1DA8F96B82379ED215EA99C27DD25BEFD851A8A24DBD1FAD992CB6DECB0D79BEB70AE4CCA034BF3AAB421534FA7EDD20F850187F58C7E74A6A9479F224DFD152DD7CD0E3FF8E0394F1C2162B7BBFC1884BF1ED6B30988525EEF1BA9B7F0DEB42F1FE9F8529BF4CDF8EAA0A8A7F73FD682195646C89B47409A164D16F18DD5020E1039ED264B25C3950F38E2185E387F1FCD736B34F8394900FE90FC706F89FE9066CE511A2ADA019C9CC96486B3F648DA4C162C4FC6573E01B4B5452AC528657B2CA570E7719AC5D22B461CB6722C8BF8D9AC15640AE7187873ADCDB5C529359C32FE3A0CEEE27243386AE644A18A14ACC3E583561A51393898147CA7BCB0B5A1BDD624888981BEDA682791D422A5B0408F7CFDA10849124A56C3831B12219D979D2945A6299756C14C019E04A27E88CCE860B55688161364A1D4C4AFBD8F2C68FB1E7E5E55E5BE50A47E3D5B9B3A034B9338B2B571184333518A19DFCF5958E5486BD2834D9055CEC1A1981637BDA2460E6F2737CD752B20D4AFD4C10A55B4C80C330F8A5B88A298C235A046CCBA61A276966D848AF1DF48F8DF3F732BA52980BC5E496CB0E61A92C20FE7BCD9E3F3D39478FE9FFEC11C970EDD761A4B704780B7A437854C318192FC4BF602DD384BDFF3DAD78CA56F32246B5183D267F21E5594398854CA3CF56C472FAD2B33DD4D303BF14B0034466CD46AFA4C91636BBFF29BDAB9E6FA6DE92A5EBA2B53DCE92EC6CD55175756AD9DF520884439BED4D6DE233DEBE6DEEA790CC51AFB20AD228A6FE7105C534AF48BF943532316EBD8C7E3880B785614111A2129BB63DCAAC40A2E9F5F5196D56EFD7C977E3A3FE938F9F812BB5A404BF9CA0ED121E92A3AD145480C31FC408A363B1C8A578F0CC03896A298BA5A2A2BC1CB04B9B6402301346AED5D431CDECF7D3D1B6749A63468767AA5A463955BF04717DC35DD63EFAF6D6F5212A744E21F4E68D807910A8B2F4EBE90399CC91B85914E8C4FB95FBDC3FDD3E448C2A9E6664BB2A1EB9D5006F4CF8EA5C8A1785EEEFC46B7C18687A36BE0B8044989EA24D034FAF9FAC8AD1903DADB16AFB6E695802825F40125E87A51DE61E63E123B838D512A821BC6534B7D6D8EE300ED51D051B2F3E5B564973B92F961D296510BC9FCB907C024191CD652B22CABE1E6EACE1E38E5C9A4B88548B1D3187F4B3C9E2504F828E10ABFC2468727B90F018FC3EEC69B11AB8752CD7B79A233CAE01E5DF47D4E696FF2C6019A754CCB5821EB0B2071D8C09A15C7539159A46CE7424F7B32D37D24697382124DE0489C891C27B0EB27BEE7CEB43577B0B19637BB1C21837936C7E721BA0718A2F855473A8626B61722B1A254731269B906A67CE68228E9DD38F8EA09733914F8D748E909999F2E38C50308DB6217B5178B51B0786C8FAF468FA9973770984200DF7F7C798DEFD00D207FD646EEB833D1F58697ACE409D5F238B2EF191F4E4D307BBC7D563E26EEFFEAFF72EC348624D4BEF5ECAEBB72166FCD28C66A78127DBC5FCC0953F402C88BC18213D50CC5A39C309445ADD6420D9048EB7897B061570DC94C10D985568A427BA55CE067BF120328EF29C2D07C21D1D14E2D26690A55F52805C561F48AB496EF194FFD957D4F1247D73D47DD839B4C58E87966589B88ED55136B43489E038FB0466B812F810426722D3F27B3636F17EB97601A4090F9A6ABA3C771FCC8273749DB6FD1CBB34BB0526417EDF0D0532DAD39A4D42B974A1D6683C1DEBD68CA87074257DF68BFD763CFE0324B6DF92B7A9E6984776C4994B8E0B9485C869B2BF65C7CF35427A929F7A9309BDB64655A5F03B69090296F172530DF9E9E3B40FFD133138901FB70B446BD868CC97104C63A08BBDECDAE86FFB6A5FAE67AD1C9CD907D99F1D64F74B117699AEACF58B191D1B882911A0AEE60EAE4AD5DAFA80D7E69D470A69961544573339665D0309C1B6320633CE6B8B9C7470E7B7299EF8C30082BFE9D917F44978E366A6C69C67021E1C77DFCABA356F322689A73A5F18EBBFDC484F1A319854915D1B4BB34841411760B925BE2255F6CB2EF607BCE343E8BF8CE32BFFB7C6501A8CB2E300FBC7821A67C8869416BDBBA57EA4CC34C246ED9CC7BA00C929C53D830E23B6AE78C63FD01FE88897B68FCEE0EA0F43997C5937DFB070970FA8BEE130DE98E4746656EE7108D414C7380B7B16BE6B14128D5FABD602F58C308BBAEB3CAF0CC0A32304F95BA0716B9B86FE2FE8CA47019D187157290D2BC7EB024354EA3085CC9AA3CD5093474A03122E224FA85563A7A0311D6F6D52997388E582C92872A02F8236D3E3B7AD23886EBA538A9D6F4C044EEE43342CDD983537E1EE4AA695FEB706D00C267DC96BD0B58380B88F72950C006ADD3DF8E6AF886334128B8F36DCBB214151FD44C5E9093C0FEBF90E2150CB14ED76AB66E39CFF756248D57B8273070D0AB53A53E812910B5F4AE28CB7B0EC687878F0338177C472C387FDB5A5434DC97417108494C192C5A2B9C81795AB648C8C5301A356A721F3C8394441C24E415809C5C913CE55654CE957C5EDB311F386C09813042DEA14CC634886603B34B9F5C88A6F6B22F2047A29FEC04355BCB8DF6375598F0654D35F18A07426FA7FBE1BDEE98CE84B977F1915BD48F79C50296A88AC76D8DE9D8848495773D8F2C5356F053EE297E649AEE43B01F684E6131D0DDA5F016D7115D0625F4E26CFBDD0EEE09810976FC3B3BC93E0DAD1F", + "sk": "176C08BC68F3336165D67633E09DAC0322DBDF16F4C3E40455F2608A517B9643407C924EAB89568C8759675DCA08CC7B483734454E675D5624D163386CF511D6866D58601579DFBC2962D0DB3061381D276F0C11231DC2F231A8EC570699F8AD3305A0C0311D4AAB7EC90E8A9760235B08673DCCDA8A2DFAA85B4B7B14C8038F0C00841B4942D026466334910CC94191488A80003081346892820008432E081288C4122D0B423099064CCC1210C14211D022261B97601A8028C0086D20B16464161204232E18834122B3048A840102276149820812A76CE4C025D0144E8C38218A168A48C841018964CC283101C529A1968159220D20887124385023B14DE0828019A0850A924DA10828122586D8826019824CC2842801C86811092C08438453106C14198A01C9640036464C280ADA466AC320855846051322610A00729C306482B451D3264D43140D8C3444142041CCB649D420298116118806251C2849C09421DBA240C482810C492CC9A685210444D2869160C66412866C00164D10C608531884441631DA280C53202023C22CC0984010826D9324089B368E044042A1C884D41665CB482804178D11120163A2519C488E9C408C63209008446062207149380A2384118B34491412411A091098C22CDCA6310342219B465263240C110190D0885099C20112B82CCC3009CA948D22C18C61240C090171D8344694B62D63860D13B789D9369218128264C40843249160282C98B04984066122A23192408D22B22D18C624622091130290A1A200480470A1868008109022363111C84CE0B60509458E83282E60482E0C403102A1645B4049240921C49031C2466490B86C92A861D922516430911C37920AC944641264E32888602485532844A3280103C00863184CD34090121229983070124888DC424E5B8620A3A84C40280D10058899A268A0B06513B904D3C68911335009026D4AC8300C429144106002B32164B230E2A2450B259010A911A494091442604AC80D0C22710B3191E0322013B86D4AC40C04C57154969161949108B82014213204004D0A4126E1068541A0709B1091A31032C8146859B248530290D89824082646D2144C42A005A3B2501C806C80B828CCA825D1C42C113044CA02490228100A484D91B670D33869214710DAB8489AA83018428804C965644872111582184188A4206110412C00821020226A23C5841A336A10A0419A148110484E013980C3862D91468480108D41262A52B40881000ACC38518CA8210982709AB251C1C241D0A2890BB06824A04919B865A02622CA34900C392E0C496E54142181C04C183129624442093032121384DB946D80148911414454C0009A482194947041488413B66443B2605248265CB03058282DC83444044400E3960CD38000C4B804E13026411865CC282AD4B288182040D4A8408B449143C285024191C9908593209123A28C40146801472DCC986541989194B6705044005110621B328E1021321225459302815300511C374810A5010032258C448C23B28954A6800A2941CB82450A23259322110AA151A4841014C2491882840B272E0B2992E4A428DCA06C5C186CA2484414C38041022014C46499966508026EE106304C984810326292482064162C10308610946C22484D21056A8B382A5C80880AC990C3222C09028E8B9230E200264842801C291210123209A02019204C190280204322E12086CB128A58120598264A08278C1C25818A281109894DE430250B4011E1C46C404860584251C3B42CD81622513806244904C23811D3282DE12400014801D0100603962451B8614C886D03A844D1B26C2420519BA641A214921419820B27858342520C804599082E40827062C42113A020882631244621C82848190268D048496382849B90045B08211430664488245C103080420963126612252D43B08C519641D12884A49671894820D4A010431402140805A0960D13B98004A68D1CA5408C48425A98490B494DC426308C864C9B8884C3002250066A43A2849A0892C2226D02384C02C03019A9251BB26541C001DBB810E284240A17200190904B9204082945901222D9366559A2818CB42119B7284A06411C133004128EDC2671D03842DB384D0836660AC210CA402A4204041A202CDA404282B46DA23042A0480293488012137061B265D33041DAB4644CB681CA0201D4223283A871C1862909337172F739B7890830723B9ADBC0CD918254BC4E2C6DDD7B63BE13F32F5DEDEA0CA7D38F05DFABBCBFA3924BFA10E921255B06FA33050F311A3A12B3107CCF4CC7A9F12B62F93B668B3E7AD97B456C993CA037D5B71E8DA18B406C5DAC22E5A1678834B647276EC041C68BB17D997C729D27D049896211CCCC79EAF8A0E47C7CFCB081FA414A3645C0279EF465738A3CAC519FC72C918298B2F9005B740F89D7142AD3437C54C67A379B7BC9BCC513B3BC99B1F358089E711CA4F988BC5332BD98B1FDC95F44D124A5AEC8AAF99700B67BAF5F76B33859EB52F4B474E8991BAFAA566070F2B5329BFD634E718E5F99522493F43D61093D86F0A0EEFA2141549146196F9D05C778C8BA7DE2E27E9ED31AD1CCD1C6FAB2FE999D22A51BAC9E3FFD876D76540E421EF893FD4207B55D7CE9B4E67B930F02B972918886039688BB9790A5AA82112E86D4F5E6C5E50147938723914FE7D5D57327990B53655CAEBEBA41C849ADD5E6C08A6E0BCB03BB4001FD71244F8DFD440D6A2E39F32C9CC41A0A9DE17BCB4FA90E9D038E3036FE1BDD38B83477C581D32F017C4AC0182186D1391138423EEE405B7E263A62E793B09B78EEAB7723CBE9B16006F87432AF2684612E79D045A03E5E2EA748E03D09E9D14DFDDB182B175E10F8072019928B37A05B2BFE9E041BDF35D4A8EBE5D14272F928FB458A6A6360090BC3503EBCAD26F2E513CB751AA3726719DFEB146458C0ABE1CE896F27DCD6788BAB2B8EC39FEC0E24AA4B87FAD919125B1B90F1A247C7841B101B9D8532FDBCB3B4CAC0FC30403083FA67754E2E53F204A37E6E59A03FAC21EEF88930D36C3A88005E30BD2150EB22D90A46F6F1F17738243F26C893ECC437876B20AC447702BEF884CE00A916811A0B690E65124C4A90E8BE4FC064A2A7363F51F0D497F6F48D2BDAEFD43DA3E8BBE1FEE6B81482FC121475642580A6BE74D274EEB1010C1021D3CB9F887A0F9163292D80067FFC3EA45DF606AD2734D4FBD2A7BC94577584A000C144C5D7095A261A4A5743701F284271EFC1B836EBAA9020A315B941F70B8F8BA8DB2F7E326A9FBB60089B739EDB09637153AB4168DC958FA1FEA52DF8FCA1DEF7DBB2383CF402D2C535460EB45FF67BE55981BFD7D24691A2FC98B68E5450A610526A1EC6B5B65C7C7FA99999DC09B5A96A5DE21C1BC917D949D39B5682C4012057DAA773E2D5F0ACD9D2767A05D75300A83A55D8596E9B32EB372FADC58202003A1EC2EB483D41D4E48BDEB31BE9953D6A4323346A8F4A93E4045EE4D958C1CD1C4D81A77700A9822661E6FFE3FD2BFFA2AB8680176425F93BF2D6218F739A043287DAA557743078039D735EEAA2A664E30B1962A338437C24174719FC599A975417C54649548BCBC7E5BAB1F9E85F1C4D188E2E55C8A2C49EE24B6836402074ECFD06EB5E0BEF8E56DF71C2E916189B8CA9EB037B75CC193A11C37D94A22797D37056B2CFBDA7D9C6868A0C1880CCEC923B2408C122B567CD8CF49312382FC6B20DFD1A382BB624BDBCB8311E1CFE4BDCD93F148B81AED26D1A4C121551F1C3C6DA706235546CC019CA9DBFE4AB857EA45797DAD8F41BFD753402D43172B7AFC4E39A500CE7D927301B30A0317046F44111AA38CCC9A0E331202B896CD70AE69E289893642FC318990D738EDBD0240E648D5F470C81E3F6CF6664A8DD271242FDA885502C78A38CF3C7DC2FF99B658D57C8E840FEACCE406FBA15C21DE8BA1BFD9F8E50CCFC2225562ECB7CD5F4735136D2BF4CF2122C3F395B4458FC82661927D911F7D91B4CAF2A7D9B772E8AB7FD499E11551082E604F9D90E46E242FFFC5814F164E83307ABADF982BF97BF8504902D78C0FCAA889CF85B15B4E973636CDD92CE8E9FF5E7C6AD98DBF171ED629506B851B9915EC32019E8FD1AD6D7E1B31882761309EB5D44CDD89BD7BED85777AA4BA1DAB9021EDD72B6C7E428A80AD736F3EBC2494F6E3B3222A0BB32982234154BE0DC90FBE1CC576704803D9B8E91AB3E6A7E74CB94F2BF6A708E7D1BCBB24EE4F654A49FA6BA0DFB473E6594991D71942CED454B0E456147CB713EA500788EBB4D1B64F408D508617160B0ACC39FE2693D3CF16DD6BB88FC99D2A0BA06D70A9D66FB50862E768B42182BCC8F770510278CD7037BC26C5C9F04C560C004C0735718AEECDD15C1609D2BDADC6B57AAB41D573FEE8AA42E6D47F0CB63E86E276AC802D1C04FCA01A7D3B0E6C338C80FECD79B7D09910DCEA7CC993AB80EBA57DC66BD8946EDD4FA70BB4454E0938724FB2721EFF9C29F65B83B87AC0B3356E5F1BC96464A20A841B89235CCA15503FE324877A3658F00AF4BED8BD6A30149741D1580361A1460ADF64B576DE7700B2658F79462D1A0D83C2D74D5406B98F672AB9EC349AEE128FE8C3D7C7B95594FF538B4F1AC31634233BA2F319D9685D09F740C3B39B53C9ECC8F1440A66FA8DBC2BF47FC6FD4FA1BF49B157B234CC62275DCBD35A2518E752618A0E8FCF01E35C9914EA77497AEE217BE8D5560371015436304971AF556E0372616FFEEBA76F5816D33532773A67FBFAC503DC8D4BACCF893B035EC84FF7E57E2091B39817C4DC8FF77EA9207D6962A893BF36B28BE6B40C6F9DC4092535947F8CD4E0A39113E6331378CEA0C5B2A684349FBCCEB4010F9CA25360FE555B576B919DC2E50E6EFEAA97197FCCB491138B0EE6AD3A03570D3B22BD6C849969683D05BEBB536F91E6FA6519129E47A5D4DD32ECF8E33C78ACB6E2DFC8EC749641D21420CAEC7F173F8DE363A359BD30EB99518BF4190BDB75F6D7A736ED3A37264AEE6D3B44F01D9858E5DE5B38249A84E1E97FE9FF19D1717ECBFB05D75A427C1A05FF3C25E7DE9D41ECDF4A20BC63FF578C1C2803FD9914EB08F8D401BFB67CFFC1BA97AAD168E014D3280336075A1EB18086223DAFC81C45E1F8AFC071908317660348376C7E73445A165F601801B854109C648146439DF89ED4D50178E1E540779DC1F09E5446DF5E63C4B6506DF371772F055EEE761E20984F8E4C2336F82EFDC17BAF6D65450A695C9E35E3001B6620AE8B599FD276B2A6E72DBBD0F1656D97316D95A5230568208F85E11862DBE03D057F36915B797C04219F3B69E323509C34B8F8CD08003E4D79FF2CBCFBF356D1BAA8145297EAA7E3649AC3B4FB2E8141D0A120618748C2A9DD5E7C00B35508C470CCDBF167AEA475EAEC0C23D215F229A61898BA0C283B01079AEBA4967CB611CBA95E1F573101857A17DA2348C16B6E85AFF162F6D2AB893A6ACFB625CF5BDDD53D4170938E19AC93B217D0B2B81E647CC7D1DC3D67EEF85028887F6C7006FAAC2871B05983B0BA5581B744A6D3712CD39081B93530AB7CFC7176DB8C00ABFA0A758CD8307A99F110ACEDA66FD2924DF4241291FF0EE923DC36B87F2F319EFB0E1E7428D8FF2214265B7C299F73BCBC6F5991651D39A5ED54701B2A4BA1347331EC839BB5B7718DA95A8192CFF78EBDB359FECE727DFD4A8086390ADFE800BD6F128D3CD69C7A7FA9844F6CD47DFF423F98732A5EB303EF0F91B49F8F778891CF0D75BFEA4548E7C0D49CC12E68EA199667B821534FFE1646A14D904A42F3FDE71E64A19D2E008722DF6104E98A0EC766B71AD7F5A601C3C2F1C46BC8C6CA8702ABD3C54ACBC43A1B245CED4B761A0C10DD94EC0179E484FEF0A952B7FFBDD797BBF864675C55743B89BA50D671ED8A3CB0EF9FD30412BC1CA9E5399E42BD6EDBB9EAD74109BB4BFB6DF7BACA771A258E34AD80C3284047A88B69881F01F16C8FF3B819C39784C1501191F5797C37B011C12D195EBC0AF9AF97E2F712772779CBEC502FA1AA9EF66CB29574FEF386935977A4F905A1340A2BD2E57780411D35F4B39B332CFE1510EE7F4EEED19A8C405B719C5FCA2F662B137F4F95CF94DE58E77129131429304829F551A7125433B16EC0119FEA0C51C856B7D15FB2DA4468FC156E6254ABFA113904A35F31A4BA58B5968A658E3DD5C5A71155C6E16C805830DB8D2BE6B428F522E886BFE0939D404C0DB26CF80633CEEA58C42DC087C7378E30AD1C1B02CA74C06525579A548380D960F96A5D02EC88527CC7213F87171C0522D7A4876B42F3AE3319EC030FAB20FA2B84D3792895B62F8A3E7D7ADB2D997AEDB5E84F8E6ADD7DB64A3970A125E6227D70A2B006C768AB5CBA0B2812736654B50511CD477226DBD990CF68C9BF3FDAC5193D06EBF3FAFB6CD64CF56EA80C8A19258D8C02989C614595498B99A271BF0D9AD7991D0BD9BA50D8565BFD9C2FC0F524A8FB95798B0D4AF2D9BF51AF1B3B2E40AE2F126A7E34A3BF4FF0D228EE33C822DCBA41FF43060A034733F57FFBA9B95526BDB5B9BE4FD502415E8C1C521E81EB29B3F4352C1F1CEDBD5F8F6C7F8EFB52D1F8379938C4453227D9F588C41B5694B4F2ABF010B94EB6D77FFEC56A789A5790EB263BB459A84C2D015491F22011E48C1440E3C793406835144585433885947299714CDFEB915F1BFF37CEDB75C4B55F166CFB6DC7EF1E69BA5E2E03AC9A10F0F700A660AFF7440FEAB669E95B1874969901E007B39BC1D65C1746AE3A2BECF3C10E00BAC5C8B4BAE07AD4EA55EAC579FCA4C3D194264BF4C660368C75057168401A1EEF2B52ABCB9B11E53143D645FD4360A0FCAF7D0D30C22EF231347158EF56205CFE44F58304352DB" + }, + { + "tcId": 67, + "deferred": false, + "seed": "B401635BE8E33FA0D248F6F5E6E599741501A0F077AB827926E7DEA4E8A672C3", + "pk": "BCDEC84918CF157BB271A99A7CBC870E1F7D04D3B20B42FAEC33B1D41B550C0A9989F10AD3B8E4BB17FD9FF154B01A9E41501DCE6797720D2CDDBFDE8E0BA6CEF823FC5E62849ADE35BD996504D3220A24FEAE1EAF3D9BDA425DF010D11649D98B93FBC7513B8C782C0DB9D7E897440FC3C3B5B8186D57AB54290F1BB8FF3CE929CA5681849B51D6F1CC7E4136340DBDB90BC10D787DC7AFC342FCB93F8D332F779C41838A7A4E1D1AD3E5CA921BAD38B35D98B5A3AB78B0633657916CDAAAD41B63D783D98A0A0370839CE9914138A63B8F9B53871CCCFD73D0DFFB6473A6D73FA9B48035DB8AD4C96765BC014F460C84A29350EB8C1D43D43EC70B4D507B0E2F2EAAD653E81FA8077B5147A20D1DC828A90D8CEEEDF13EBCC64C74D51745D059295B532BB43E3E910188D1D57A6947EB94EB4F330C3AC8EE5C78E8BB1FE98406DC8346BE031FE55FB7AD2D37242A8290AA2F38A08E4B16B6688C6B341EF1DA0D8166B704DB0F363F254A4B113063E73372FAE0939A354B79AC67593E9325FD6C2451510244899B35A473751C5AE00AA919C937291B10744696ECB71BC34CF25C40DF84BF66D4D80CBC292005C5BBDEF16FBDFC329E7C7124CB759B8444053F69BE74B16C2345120D3D407993842807B1831AC96679FDEE72593C8C7BE3DEA2B5456F135CB536F3105101812492BC5CD9C8AD7ED2470C16F36CF46BB985429EB04B7288C2C468BD2FBCACE2CB73D660124B09AACE9F521CB97654871C89C169803FE8E62CD61FA35373F2ECE922D5D688E34A1D2F4A55E89E57BCCD0CEACCBCFF07BB663219DFA695C9B53632D6B0B9F0545AA8190584E11A2011991217CD46F798075EC26D3A0E6429A5E6BA022C191AC882CBCB57492031F85F22E2BAA0A5032E377354107BA33B70BFF808BA93730C42BE10D29C877F439243E0231C8DEA5066080547E5BC45A2D2B5FFD4B702A69835E8D86573712B6F518062DA75ECF6857BDE01E27C6198F79C68516B9226B91FB3DD7F6FA604667D9A5CBC9EF5E5AAFFFBBA7611203119EC994201AA9DA9FCD94865EEEAC6D65927E4DB04D7A4D115B119DE1F77BD8525A61605E21B3CFB4287182A429E14370615A2CEF9A2AC23784FDC58E929EAC095A421881B7413C78FF20E7BBDE5C2B0802F2DE80BAA8A78372FAF4E2FF881EE7903584073F6895C28B4B8DA913EFC0A9BC9EFCF113EA6C3710FEC2308F93440D5A9478431E82F3AE9527DA3500E7E44937A637F70F70BD4AA8E3C6B662CA326579C6167E3452EAED83A7AE98592120431C8C568F5723E8BC924FC0E9CF48617B29216FD15E0531E52FC36B4642F2EA7B50C307081139D4ADE79449DE300E20CE01B3CE1F115C8AC6EAD4CECF5DFBC6F34BF30EC76133894326C248DC33EB904D58BE3ED563640CACC4D03BCB72FCAED20BF63EEF0D2C48F6C4C39AADCDA8565B6F9F6E88A822214EC63C7D0425869F524EFD9B2AF0683E9D642410E797D8D929D3810F91804EDAA7DB074D1E06BA6A8608331AED4335C42B92AB16BAA9C5AA5366375EE302636C77B5B0628DB56DEAD05A76F35BCFD4F6566A156754A72F3ACF3EF0187476E00A2723A6105836C08675C9F896AC6353D15BE1EF3959036205E27A61BA4C072DF5E4FADDCAABFA950373060F8ECBB1223E9B1FA22F440BD423148E9940D8C43372120BEC7FEA4C8F0A9A7767E59B136BB458BE963E32951D87C9B31EDAFE66A2F6BB2E7FBA140939664D300C0380FCD15205C888DB991B7AD4CEA8DDA0283037443A5B166F0DACE0B9C5C4E935C10AE408D2F4250C15DAF3B2351CAD4D37A49B56DF652B501114BA06A3F88514A8BE2E450DB895A1A59127ADA2E3DCC7C061EF9CDB4B426EA13AD00FFCCB120C45B144FC86BEB397B390AE86FFD007B20FCD271EC56E010EC34EF2E916AC5D3F2EE8438AE34CFB53264F8BB4B060A4B5661FB707FFF2730D356A6A7344488DA60610FEF59DF33CBFDBCA271349826481049A77D9FEA09BB8D59136A918ADDAEC78AD7E673AEB7D5912B15241B7E886829F95DE8B391BA11F245FA1B106594500CAC933E438B78B0C7DE70ACA34B8F37A25CC40C419A1E626F1E0FE2BFBB62EC6717502FC5E469A6D5FC9FD866C17BFEAA175183F582CD5F6ECE90C0BCABD52C726B2BFA29D6651B5E7770FD12E1D12B9B99AE76DA076EA418F55F34F961C433CE7F1F35D954D04CADCD5AA2AB3C22A782892E5B2DC274FD009C3F59F157C3033358C2306C9822D6CBE8DD36E8D1D8FA228CD11BAC928575AE2EB50504BCBBEA36E383C1AE31A83510D344A1213AD37543F38E5009788671F4CFDB0659ACB773E470050BDCFA86035CEF439C68CCC8268938584066111BBE9DC495F694BBF77EB465903BA6EAA5B6D35FE009D4D5D268A4375820D18F19C5B0AAB94FDBCDA6DEAADA71CB09C2B6BE67B124F100BBC120B3FD20AEDB07DA8DBBDB8B2D0867D860C82BBD97F31F1EC668A55B8FA925994406AAEA47942650F0C5EA7623A46BFF43EFC24334EAC6441F240E6285839019B8FD8B0EF77A548534C6EA2676EEFA0521C58FC906C73AD1AA9B1626F136A6F19B8D4DBFA964BE0D717EF21AEAE8DF1D0882ED1FE087F4600916B2C37C9EDD2C088D7867C472D03B955FD575BC640F9C793AC3784A59CAFE0BF802AE9A618671B4BBC5606C2A2CA70F2129AA05A3CD81F11132ECA59D5026024ED99164D65439869647996A65127BB78B46C38F8112D883F08FD2D62A5A80DF9E099835836EAE4068C282E422209290DBFCF7CACF1BB029E92E5E8B5C7FA1734088E72634A6C9302A1E50EB7B13F66414E539DAA46FD15C4F494AF9BDC78DF2887CFFBBB5D9DAAD21690B02CDFF0D08C46F15A1A40C4A53BBECAB3E5914A6D5B5FFC1231183D5F05794C6A9BB8DFE2A75ADCE776BAFAA5C6EFA15E77D0296A7B12293562FCD6B78456EFF224E3B14CD69B5A92411D9B31C3B385FD660793776A622B04F8B034D864381278942C55AFB18F7A4C181620F6837EC8D240F25A0DFF45D873107E2A005715E84EC11DF91DD11E99DB729C62F424EA39F27775404E2BB0E4EF42A1053FAD6D12C531304201D0017C08CC906266D07319B3EC91DE81FB9480D3BEE6C168628E5B8D817B91A7216D46DDEC6AABA84F9474249D5927B1B5D3F4C6A91AB147F820A58CD0202A8CD6AFF75F51F9995268CC2CB3DD55A210008B667EEDB1057B067B26F4D4F11AD58C82F1DB8D4981093955C5E6C3274495AA80E9410369DA8503354F23E783CAF4E5C0D66CC2D6B632E8C45FC8EF4C5D64B6B3FAD03EB35A07D1A06593ED51CCF07FCFCD29EE195CDCC55548B8B125CF00F76167E9941FE06C57A022869425F6F5C4BE87B8DAA3C73926BF52C47B6FC324A7C69CCF9C3550167DD3309E8CB90C4E1070F9375128BD9D94B3781F5103034980017CDFE3622952EB3F303A8D233FD68F7CE52875DF1D2D35C62F96C487DB09C93F36DD86DB4618F62F6511A942B0BE2819DC2411BD0A50069E3DEDBFAEF8204F711BCAB3252650F6E97C1F347ADC1FD54DCF4B54B5D4E495C451A069B83CBE84084CB7B26C2254AC5560B712C7490192B418C21C1AC73CF45B6037E3816568709E83C8BDE8DD5C25C5C6CEB7C4C3458053A3514ADC5B9796D1C8BB0788A", + "sk": "BCDEC84918CF157BB271A99A7CBC870E1F7D04D3B20B42FAEC33B1D41B550C0A7834E890B7C74613013A6F22A3FB4FD211718E21EE7F2599640977E85E317B9A1BFC39D0774A06F948BC46B114979737FC2BF0A69E043BD9A59E1BCBA7D22FA4FF93970C8D0918561C28B8B12445158AFBDE2CC362AF25A6197519DFA2E4991D901011D2A02993320C4CA06520326A22348D0095644B364A54822489002C22162940C2902495644C3026CC982C0215665B964D48A04104804813152DA21431509601E28290C0C004C3806C091772D4C82C1098280823711A45721C0590549840DB96800C878010A86108104C02A30102B064D1321211C0911985510313810B108DD0444810995163302A4C344C102692E212601910514C480902200A1A46301C9781CB967058443123138010400C894648803886242230D4264811082944480A10A86421852C50B225212751E140054C1642D4388ED1340D13447013B86C19250E2126615BA664C386040C999024042D64B025C3C0651C319220C84503A19048B088118444C32069D9409002950CD844624320920B142C10442CA2188103A60D09B37058C26C22933024950923A5511C3225C414621A08650C016488944804C84861484A8B144041B04918444E9C96605A004013374213362CC830000A35914AA44C24834C1C17665418894CB84D0A440A0217500A478ECC046012288C1320051317429202000AC26008A801C9442C191949C4221059B82148442220B8681B144A101390C9C26C20293201912D04374C2489884A864900C86DC2924008074862286912364ECC8624C324250444204802486344325A06659BC4641C274212424651B26C243684E12068C1B224193001A2C08C03C370C3468E432064CCC20802872523292A0B999108184CC2882403190043000650C44C54004820268ACA204608460C12822119353040B02091164AE0065184800C90925043C270C9926454B8859B88000A2101121400090608628604CB1602C3C82508398EC0C24400498411885013136294928C61B8600C022ACA4020DB4069DA08864A3469A088250B0240CC96040CB10D0A9825A18400523442400060D4C8708B04101C350D42A2451B30009C140284C66C0CA064833850D848208A162A81A260C190894A020550B861810225111052923688A0B8311207425B929104146E5C266204A52D89921080228188828088040581026688840019338CE0340A4C0202240140D3308CA20266C8348120B968189425091410CC922058961159B42D51C08183306003928DC9261282964C8BA08189488D1B44704818051936821B010693046E22450082C80549347148323089926154348E24C44423B640518471A39811504446E210261BA92059A229010781E2286CA18204D00070E4182D0048614028528B80700A094A48C640C89891DA06248C221124846C412846A386914B1052D932420BB691431669C098881C3992CC44698A8831482046D98689134770DC9648984805E2188A02226A5330861B8791D3C4610233908802505A34518B248480B64D01454D82A0000B3591E4366D943624A0249201380E8484680A9441034688E1B2498B920C89045008093260444112C40D1882698AA46C8BA22C112091919244C1206D9AA4215BA47053108502070C5B164CA4A66D11366108328A02B869232602C11680D0822D083522D93684184424D93402D3A6459428495B2480081881E034498C4232C21810001664939270C8468A0381711425121CA4019BC288A240849A88642097041804000A4061A28890801092D3825112208A0B2432C8B42D81143222492802048161864D83064C21472E22408A0B3072E4860018A70C0AA90D1385699988308C2048E41472E3942809497104B56114A72099C870542825D9126249C861CC3482C2B6614B18449B2488D4104EE414484C0082093921D82660A4B80DCCA2840C239151384D0235722025511490015182214B066920234CDB3692C0964C14C0410335819C406684C4909A44600BA80803C86864140623A42824471013208D201549403890E2B289D4A0215B82650AA025599684999441CA208403373223B77058A89008158D9392041C280011C89001851001254D8A368EE4A65164B06C8B488960A24D43404622C601C9A860C000220A2140130706C2340E6034248414918B0480182109194341027756188942B1D56A02D7BA54F49175E97242D7C7D88F8B76362F6E00626D5C43CA00F79BB798C716CACE203B87156417A1FB7C8329A79265384F842A03C67B6033CE4569AAF56CE5ED620C311C8747966BDB91381BB3612E14CD3BDA295F0F60629B22CEEA9902AC68C12303F7F6C6515540176509404B164CB26B20FEA5DC505E79EE5E340A9001E58BF1CF1895D64554BA65A5AE5B6854D0E3FB55F882E8F4E0F19CD4FE65BE4950FD1B469C285F3A8EC333E386D5E0E4EF77BADC6A7D708D43BA1DB88D6A65EE2AAFED1FBCAF25DA02E1BC70762EE598140F8D5707CD4617424B3BD7EA31BF8905E5CFCEC6DC9CD5A304E160A2F572674B8CEC6643319D8C8CB5D0AF800B88C39F58AE0EB98C422BC56DEBC63E21489C8B08E5BDE780D935E5CFF895991ECE3B1E3ED0A7C73023063F620DFDC19AF60CDD2AC586A77FF592ED2213E18A00591ACABD334D159112221B4937CFEFB52F6E629CE8BF43A0E68F5A6FC04D91249F4866BCE3D7552EAFD5D4A670F5646065CB63D6DD0CD169549070E7067DFE219291097F9A80013896E8CE9A98C8FDCC57952081469E7D6176447CBBA056EA5F7AE02D4F2EB01C344777CAC8179C65650FED7D69BCB3157DD3C374BFA535DAA86C546F7011E24F9706FC7C1BD2696C38426C7EB8B60FA37EB067C7F779ED8AE09BA85EFD5D6CF15CDACCBEB2D3576A9119B69272A369A0944627BF1ED78C9BD1FD755A0CD1C3A35A0844F5E838EFDA89A69D3142D98B493B9FA013BEAEE7711E51CBDD7D6BCEABAC57DF965C87D204B4AB7166CE5E0A223670A6E1A0F2C004A830B0458A92006FAD8CD67B5587B7158527F6A8E3910CBDC864E3BE2434BA8F57D992EF33FA37464F51AFAD86DD8E9BAFBF6D515069CDEAE1A7E2E8E74AA3E9A6781F23652EB966C13DC55ACECC623B2D2DD6D0E5B4F4008AADDA7FBF552BF631AEE4811705981ADB520C7409876BC7C6967939557AB479C75220C035EE4B1C7FE1A799D1407A2FB00CDA0FADD3939182426BC85BFE28FD6B14DCF74680D356E2D405DE7203B6620FC5CB75BF3466B6B121CB10755544895491911F4246EC926B4CBC41E6E32E0FD77C375AD6880CDE407B5D598EF1E100C859076038DFAC70AD8327B36EC9AE1BA43339FFCECEC16922CB2B8A68A6D65B62F3A2D8B549EF3E7B1937FCB779863D520AC99E09DE7DB053C91923ECA1C24272991573E2252CB5448E07A55A59207F7A6134B25032933723CD9DA9066D937DE127809EBC609AE0C0F24C6FA8DED0F1D828AFB99B99FB392C247C2611356CBEE8803D93E315B5A51E3075DBED3E19A239A695C5E5AB5390F8FF93043E07EC86A40D5536014644FF07B8615BE29B3E05687AC45561D942DFBED128B23C0CDFA00C2CD5A31C2380247695B8E54E851B0701FA343F264AF65570AAA31D649EACD650634E96B7DE543F412B44B5C50B8A6876CDE9DAF9F8489DD40196F28812E73F984200102B883452EF326CB15C30560404309EB5BBDAD0F597ECA72E315A0D68172C28F0CAED2CD9395E0526B009CF272CF44F5B0225E5C031267A1D21127C793F5FE43C1F21088D6821BA3629D9ABF69862A58329BB4734520C5CFFCEF5CEACA0AB27129CC6C38EB476DC689AC55E70A73448FA082B520D60E1AC4ED624DA8DC0C4DC388221C77E5BED4C4EC6CEA078276FC7A0C896B825F87B5ECE931A06E313AFD6837FDDE0A1EE4FB20E19E31F83E6DEAF585E4145C007B70BFB1F349353D3C4682CDE4AA15F74CA68DEFAAB2F73390FEF3701286B3D6098577C2796D53F0A72BCEB07767561B8CD74394015E0557DD0A08832E56E294236D70C984DA72618AF1C4168A43C29DA42EE5FF22D194139754C14BFC9E3DB998C8ADAEE2BA207881BB3988DBE11FE2F66A243ACAE8E4EAF497969426D92FA8A4345F01E2590620EB5D66F65B1A2602F7DCF30173A3BEA40E52528DB7D4415517BD3F21AF15DA3AE1E4D14C12BD9FAA1C290A4C6ED54D2EA7109F44D4ED6A1DDA63A1B98B7EABEAC083EA3FFE1818F03F5E5647FDF858E16A72107F46F85219EF35F831AEE7A27A4731A1D24976CEB930A0F8A325C23EA3F3333490E8F68157C6B731DEFED42F82811A50967E2779B5065F988C391D0AFF5C690DC89C73FC193AB994A80BD9373FFEF654F49517B81536F92C7C811935F3D34EF94D61C1F28477C3B89420D5EB1FD39DF402982FB267190E0118E612D384C7690052477E255BC83D604AB9B4B43C716E8533AF82F942CF273C9823AABB3BF1281601FEB7C86FDAC680DFFB8A7B1318E72F4BE9FA0CBFDD83BF073006C7A9A80181202C924C79505E9D9C82C81F52C7526AFBF982877D7F7DFB2576E1D330538DE0236E24A73739E8FAB92303FA99628E463DCD0D8CF300A234EAF7D00F3325AE876D27DE643E708213FA83C4E845D8B622DEB03C344084E3623DD3B7AFC424FB46BA1C81E4BC297B6EFBDC0AD025A727354DE74609ECB22EC5E92A8364469EE3B3E8D9630DB1F0C053B96CF2D38D72B798E769A56E003DC1B9217D912861E986AD4CFD2E25F0E25A59A60BC19130B45E3E5600D483D9A8B1C9C0836C4ADE168D30B8A590A22178A755496C1BB4D439786BC813CCF5402C2DA9D0649BFCE8CED93B8C15A3A9C4B34EB22B8C244AA39E5ADC3EC51E9218699F195231B698F46FFA11C6022B76EEB5FB6CEBEE1EF2D55B780969629674251A2E401F7071C948CA1541E2A8E1CB8949A9C610565E345D98A28819A8D8C1A6E950FDAF2B41C1D798A6EFDDC807BA931F2804EC61231B09EC32D9E752D3AEA3F8DE889F17C8E4698EBB7C491DC74721A0C52A4C821994334F7D97E31546BF7612C2B6FA368231A98DC64E9D4E491E241B8B5FA6E4FA8D9A30D4729AAE430C6D1AE358374ECEA58E07E697F0B8E0D093FE9E1D036ABA07F2D55FE9D030238C0DB6EEAC21DE6E03028E1AB991F74A754C2149630FB402C025C1840412ED11BD53BDEF26FAC36B0F03F48B55CF15773F8B083436BACF90B1F3587A782D4E4C50C7324C2BF2173016892C4D17B4E9A4BB8DE1146BFA8F6E9810B3C1DF090FC61C242E097A631B5CC6D468A9DACDFFDC660D32CE702DE2A87C8ED1613D8AF09A028B2B4A716388B0533A41F6322622115C1E751581F06F1A71CADCAD7337C8881455E3C2B3725C8A82805E6EFFC0BD89A0ED3C73A05E5EAE505D5BE604330CE88B17FE43F17262F3EEB06F7E62879E94A861614400A4675A18D08C02F888F397E90C5CCA7A5BFF3957970864E68B611EC6C957FB78D799DAAC8A0B917DD94B4BCDF3152E2B739A24816A08013D7B263CC85FE4AA35393C54E85CF5F2E98F557CAC073A381019D288201A7E8C93CBB5A3CF605C80C4FBCE566371A3239B691EBC0C67584B934AA243303D1A0AAF7648CB00E75E3CD8DA7D8AA71E41C0F8CBEC1ADDF27326A9D5C4A0A4E851F8552EA8EC9C9949363C56B33A745E94B48522748250B498D447D3E1ED82193B48AC2ACAB3F87655FC3FE6DA0A6C4D9E75278A21938DA66A09053492BD4FC29E3743DE3056AD202F3455E9BA37F43EE0B74BE2642A537F3B4CDCFD2682949F6A2F869DD4562268B50766C676D01D1CC425B206753FE2EAFD9C45E54A37BCA002D2D2599ADF13B43740F6C0F912BDC68B087EC427CE4FD7CC87B4C0064FC7BDB59CD9F17CAB3289131219A0CCB59851264FB44CE4D6DCDD4C85C9015499BCB74F68929D6E6191A196900B9B662A80811E613C405241A73C98B84E2853709A508CFD5B954527CAA7AD15B3EE77DD79E581F19EC284B54E56F45EC62EE6E997FE8F6C2501F12B544DAC253771FA65531A48BDC4671F3FA8FEF9C06B0A964832802778205E8A24D6FF3498703D737A49FC3A945B5C84F9810D354385E03BEB38269AF76A9C57501D2FD3BB5AE83E6CAEB143C44AC46B3129FD3DE7935B73F6EBCD42212143F3CDA752E5453EF3BA8E13F08D6E881094B86C8269FC2257E2CFB06C82E4CFE65A91FCD70273FF08F461D4B2ADB79279443C885F209301C4693A74EA1E1E13C4EDDA1230160134276B0B0740CF8E75CCD61FF4C2948DEF15763CD2EE5FFC79B12115EEEE71DEBFF1A028AFFAB0DDE512D8C540E9F3326A86C7057A0A59B800010919A8171500EA71ABE779B7452E40FD8D31194F7D9044DF97B2AB6629A13328686358698B5A04D1CC3B38A46BF63C10A08D924D93B8EC49E1936E2C8CE86AA65AE2275B05AA57BCD6A8B641739A9FB5D941CD53033F4168FF830D04A6197378880092B6827DF9B1C8D5C397C00FB6E7F151DD93778BFDCFB1CD4BBC797A4D3E7BE4401BBE012D102AC8D8540E874D44C641834F66CA534BE7A5747CAC2ADDF4DA703FAA6BD79712E8B7C501D88F4076B2020E8E99CF95A0EA0D0B92E8A779B9AF6F00F306D78E397AA2DCFF603CE47C4AE7758731B20CE5E424EDF63C6DC99BD3C86037E46D64025A8D6CA7535E3D202B60E335F38E62FC4A041760254FB88E9E9FECC2C9F7EF7B2B9896FCADED7E614EE57D3D0E5E4A64BD649B614BE554838E38170E0748E5FC5850E6D9C805AE59928A732B01595DEF14C7B80A7D371CE80238F0448D7E43E37BB7CEC15304950E778CAE35D946317F796B5A8FDB5D85FF17E4D29042D934EC51C37CCEB4045077D212AF9E039F0E9399F75FA5407726FE2168F50CF6380566AA47B6CDE62" + }, + { + "tcId": 68, + "deferred": false, + "seed": "BF2846DEA3C6081ACAF75BF64AFAFEDDF8BD15F91767993B2512551457A429ED", + "pk": "471888CD25618D5B2ED4DA93481BCF9A1F4A4E1B781556328FDAFDF8807D1273E9D304793916EF99F55AA44E7393B5B29F8C8F3208162C338DEE1D78EC15A6B53567C948686D7E6C9ADF72D7FCFD252C0B0BAE33FF0CD980E10F65D91520BBDE49B41BE7F40F250DB70CEA064E0D553E3878E10DDE3A4FA97374A3717C5CF1CC691182D6B6030A6C7CCBE9A06B26937D07A83190768BCA23EE0D53FDCE3C6B8074ECE6B7AE0DAE5FFEA2DA18A34F7683B5099A50C32B53A7F564FF33E961153B915AB9FABC9E99DCE6B9D9EEFAB3801E4FA1C0C65335F18D45E9E947C1D95C41ACD02E3E64427FF751959A430A59CD8FF7D3540DAAACD99A668FB4FE3DC6194E52BE226FD2258DD487E8B3DA7326A1E56F0E33BCC84666BDFD9BDDE4CD9B3A2713DAD664188C811C6381126D4C4449EFE45D071818D63F7E2B61ACEF9AB8E70C643BB14B223CE465E9F06308CA83C49B69924E555F5AA6F2DC0A919B86A69B7DAEB2E4F1E1985E15790A09D8D34A81CD5135BEFA07606C17DE9E53A1B66AEBD2542D5DB491DDC8702C85781933A07C7C5E27FE9D7AE6767289D9F98B1F525448B47933C114B7873DC989093F7256389EE428E7F704C3A254842F51DBBC882967DB8AFB3582BBE75DDC260C52C0EE7E46A6B407164FBB09048DE13183A787D99E7ABCF6E485708E5263A4F568A2C4CE1AA7AE0613A50B87C5EBCBCAD91D2D5ED44E1575E8C71C55042DD445AEEAF81957DA823C175A331D41D57548A9ACD0872AEA3AF4EC7262C4E14597CBFACB123614170D8C9ACEB4A93581ABEFD24CFF5AB03844E2E95FA48F265D58EE0076EA9F44579C5D440D07A77B0F94B117B9217311ECF2DFB8BC3EEE5686EAC9F8E4150148BB5A824C379EE7E5FC383CB5D964E564826BB4DF824954D350ADC37CBFCD4CB3AF4061E778885BDDC7C77CD52E2FCF9C76656E96D432A57149DF48EC694ED04B45BD58B2616099E7997C3B7FEFA18A88E6EAD6020D959E1427B796DC14AC603F8B49AA90E1FA56A6097C97F21F327431B1590063B7C10635BAD500EDB5E6EF985F1B321203E5CBE358F8A4549CF16793091436DF517F308CEC8A80DF728DD32D8A76F7C586479AE7437B4374073C0D76C60E111EC28BAB200453BB85DA6DBE5776EFDBFD22F4F7D165314C269EA33CC0A6A14891974220B2531238B896ADC75E5AE33658AEEB3BC4F4954B44B585EBD1DF92302458FBADD906F4A69E0F0013C385935BECFD97C8BB21A127E34843BBE4D7C82C9EF7F91456C0451828620A151F4CA0260879280C14A27B0DAF873E6F9D27CE1EF9B8E50F5BF896027B415427E633C4F2D04B2B921E1F0B85E34AF2F6D1CA6063AB1F4098941330A1E2A960C885EC1B1E36876C725561CBB991B37CABE41442F439EAC01CC76153C98AB1D927C53BA0869C6244A48D2A235F325932BE12A804756346285E2591FC0EA0C5A923EB22DCD3769C22EEE39F01C211F7FA67FB1B042D21B895B54D07997E72E24DF13C35219B79CBFF013A9DAC527B230A66C50FDEAC820CD1BF82307B7E364A2DEC1360D9C4DEE5EE3330530D501D35833208F8CFC2C7966347FD4B145F7A457DEC7B07EBB60EB8116DD848BC10FE8654ADC7F0BE98642379363AD172B8A472243350BF2C5AC80208143A21768DC4CF30AD65AE2A1B887BBFE47B225B3194138A079430C1106A5D5FAD56F10CBF0945E681BA31335B40A424E1FD7DF2405628FD133BA601A9A8BEC494969865E391D18A3F2C93AF707B9D3FA2C1D909C75C0C109F4166CA1D5EDF1210A5F3A426DE8C328C6089B40E21292688B546A5017B9AB038A153B311330C7054E0BA34652353F99FC5E0C4F196F34D10EFDB967F3B08E01AB74C2A1FEC819FAB8A5EB71DA9AAB90A0C1F35EE13B1FA41EC0F8850E127E8D3A02B25FA68D5ADE727C23C02BBA161FEB29F7C6B12C887EAB6EE13B96921A1838091D7BE76394E7B00FB61F93C29D3D8E108F2A510784BD2FFB788060475F09B96736E2802D9C0FF4BA636C7AA1402B4061C9B7CE8B8017A17DFCC571BB4122583D7164FD93D58B4E204B7938D8A29D923CF59AD96483D4EB15D8272D9A5049A6464BEAD51881E27982313A4EAD2B59CE76CA107279E1406459F966F548C401273ED78E0D7A39603CE8833DFFE05CCDD7F8BD077938BDF1EFA0E9C04581AE267904C0E071F14CB7C03C47C123EAC045D023867D5417A2D79AE49D967A13B645644BDA1CB4C27475D20E0ECB22AE89A6F742FAECB1E46543B7723C782E5093A5E905924AAA37D9469C0E06A64AB77AC655E7BFC7C6D91BC4CB9A7333640827288DE99D6F0C903B4BCCC0B3B095874D7A435759F7244E08C5387B349DAFCFF6F855595660E81F691F073C33C9D9B21DD9EBCB6DCB86333540B6DBAD58AFA0DB6BC25E396FC1D54F74B57C5CB127468F655DC8FA27BE4C5F0B47DAC99DA66454CBB3D2E76796A4199370B63CAD67F8F4620610CF6B31C8C4E05FA696C3670799D7141A1CF67BBB1BBE3BF8EDE42D0C76125B7DDE298CA1413EBA6A767B3AEDAF89666A882C5D255EE76FCC79CD41021DAFF368BA3A20FF217B76E4E3A7CF9D487820AD6AC4A2A9B9599CA6F5223DD4016DEEA12E08E48E877199B281E453C4F4B6933A5B2F86461AF01A59EB1E38704C95C46A5D9C54AC66348EE19BA3BC8858F000E18B58F350DBC1414928B3F7475497EB7015AF29CBB257899615D73DE8AC220E424846F54665635DFC4BE1A8EB017870BBA1464D799B89E268A8A26861A6B038B7748CEE50BF093CB832E97E40BB978E93D8085457376BF43D1B299BD9E34DDEEC0B6DE0FCE5E0A8DA14C1E22EF0EF0F677651505E2C4E4555D04CE7FBAB8BE12FF143244E58D8BECFFBBD84F1CE3F55B521A2DE728C86B2DC3E30A9400EF325FC6526AC56C81E09093BD9BB93CBDAC6D1309A777EFCA27EF9D33B144EECC641BBDE8A4CB63B3411571BB023663E893F2020B28C98A33027D976C82A2578EF9D684C88C7ABFF2CC4C3E19817E3E8CE37478F32CFE2ED494BF0DE24E051823F8842C86D5EC5A0C9EB87C961935CB63DC5B8A4CB62B726F3C3F8416B67A638D4D7EC476305C9FAA38B1D2D89A61C68011878797A5C5E1A52205719D1327C9F26CF632F0365C586B6DD76282EB1223ACA24D41907543A17AC4B17674493039CD2E5B3C8BC15B2CB2A0F4F79EFE3575764F166CDC5351AEB71C328138D8824E558B87033B0E15B2A14566084FD1D72F375D38712EFA9238F6A3B799B5F6D92034CA1C298BE6CF526CEBB371B2240A13D0D8D6515360CD88E2AEA4DA1DE424DFC7EF79247A526E3D52C09464BE70731D2D7D409E64E4F1C45037AC85B8B3A40B53AE7A5CA4F3527ADAF66D509BE5714C94F49C205763577675452952D34992D4AC89426128C73F46108A3425BAB0E55291FA05DEAC792E91B5983BF1374F99E27946B676A5D7422579910C6EFDDFE80199B86578B40875BF7562BDACC7A9601F55D22206AD785A73F00E8EAEB70E53A5643805B1E173ECACF8FD1A70F3CF38504B4B021EEC915D8B1B2A835EDD6F6A22F06CF33C2C96529FBB54A3BA47FCC8C2E7EE9089DE5DA246A143661488DFEBBFB63CC8D2857462F55F009FFA917A63FA87D046C3F922CA3F9C1B650EB9657763DD91F4", + "sk": "471888CD25618D5B2ED4DA93481BCF9A1F4A4E1B781556328FDAFDF8807D1273A8F45A2EC134BF040EF6F32ECA6ABE19C0E70D5AB5AF5D284AD01EE26877180F80C71A31A5F3CD8B5AD5039D4CC8F5EB6C313B5E2D5236E04F2D67DB709263EDF3F7168AAD880C3EB854DBBA92BEB2B1F841BE9047F3DFB0D1DC975F36CA9CE1DB169101180E002369C93685921824E33246C346201A26511AA56DA49069003402119224A4082E04C7480BA66C61100EE1A04104C58460822102854C8B226D9426714A0824C8422112B26582284023873000947049460C2397090391708822621C41111212444C008019A205D1B44D842471A21825CC386C1342100117840B446A042006911042C2406682C845412625092560DC20254804511AC1919C2060582431DBB03011400A80347218878498024D19B38C1C388E92984991281019996D19399019B448DA986C08916113886420196A42C46DA2404889C03083C210E23408624484531061A2A68D81A48D99C88818B40D0A27428C1626E2A62800475108C309883885E112311CC39109910C59383110338E6432904346821A10924CB844244740CA3825010891A3B8819AA2499C90401C12310AA0480025605B1464DC34091C21810A116293104EE2986DE430868228625232059236881B017112071241A0109488204AC81002A128249820643850804622E2B28018B7442222665C303288986D818241CC904983C690A0980544A6281AA688140012138488E2A03163B8251184701B142604B13109A25013188402C38DDB24255AA64519338ED89628034665631420C3A050510429D414098C302ACBB4845C225289824C94C2691B268821458014B21162B00853C42410112500A8285B384181900CD0008E89184C1CA085DA244603170C81426491B0400C93685C90454BC081C08691019020501625C4244004437144062D2211324C34229B06666386610245621B4252D8128102478C903211DC3086113502C93025D2B42C1CC38413A12C01B84901238DCBC84D02B048D20449C43604D2C6254AC28C91280EC3364C00018862A49154444CC84289CB840D941804083788A1404A1C058D1B47845BA48524188D102011589880211441C3421153B0101BC92180866C0B300D12C94449406CA0A691DA14820B0532D4B08103913054404E504882519604842270839409C996490416668B88405BC240A22692C2882DCC808964B24D00180553380AC288319BB844E09684C3488E0A480CCA1692E042311A138042A86543360521B1001B2891E4422AA318855A804D5C268264221010450D21B88018A1445B864C03300A5282841927248A048D91848819A48D0C1140129981D0248964C63189068152044A5028252327309AA88523347080B48983300E88160080A66D0A9590C3481062940D49A289E0B270010260902801D8906092A86D50B04CA2B40C9B90611BC6089A4084200391D8C61009328619230D13C15050246E59189019B2481AC090E300818B944554907058B6008A26214C3264D9008184A611A0B28022104E64962D9BA86851B28051B46850382D23C27012B14449024A84A491A3C089882241CB8440A006711B38250CB83110A540CC4632C4180DA4004601316402280823B54540B0899292711C178D58A010129225D3B26D01948523336113012001058A4A8445D236315A44802124414B428210998954406E1029411CC90949B4701C1384184992E2924C090489800026CC28229B882CCA0289D0824401498AE1C8080A92045C240680020A81368E91088A1CB7601B856902092C1923518002642194888BC0711294308914100018684AB66463220D5236285C384D1C85641345900B492964204219170D9B3032D0A25104209219222848A2841C2304CCB2311C941021403089A485401269D0064E0B485080024421244D0208704922498A828D1CC810130144149371113746988605D91840C28664C1986889202CE01640048730224024220188CAA08422090E81088659B4700B212188B46800301124882D0206722125250A196510122A089501E1900420100851362A092345A4882183A46DA004909B380E42900C11C40CDB365152006A49A8911C964D214130130092E0B665DA960DA0080614282D9830650A23510B3801924001CC080E90264E23469283964193848052C845593244C984682028421449615F92CAE0C5784CCC5560F4488F89C5A8234F2D32A8E68C5D1380EFFEF6C6C3F320328F0E3955484A42BFEBFEF943FD69D962F5F6A78A253EAFC70495F96743FC5E93F127C180F1EF7E7A7DE4221F637EF2325328DFC314C96A98F66FEF266E5E3C126258B88352A244D3ABDE3844D006C32CF335FC8C2FA63F90885DA39F57B54E96D6C7D002B08427C7543F84C415CD0B9C35BAC084A84EA5667905AD532B9B96DF94972DC41F50D05211D49522F3205CF7BD9B9F43BC24320464B22B6A7590D2B494BF8C9679B36CB3817F2AA0F14070712F4D69E2A878F32EA8417200B15861014B686B2838FAA7EDA182CA8FA5352C8A9D86217C1E64ED566169925A64D0F9FFA46F681FFEEC859618FAF0217A4150D762F4297240EDB382EF9AC482642EB18CFAE0C2B6C63FAC6B13A0CC2EF187AFBCA2DE9499D8F03B7808CD4CBA3C01871CD18C770DD07E18EC4087CF88FCC75F57D5A7B48488CDF11D05BA4FB5B990EBEFF7D0FE336F6A09B47BBC587223CBE9C0C289D4D822CB6603D9D72585D9BC1B26690D773921442AE98437F669EC1E5D163F8755F01B79B64C49A4749CB92AD35CEE90AAFDA8D4D98C56F2B2C5C23DBE4008ADE3C2CE2B58936C991C1EA0ED68192024A3070B23BF1912BF125C7EAA82DB74BF70443CBAB50313237702F004AC5C9097534E7809025205F52427B5D943BCEE4B5372AB0EC4A7D5F56225FB2945E5FEE0670CD4701D4E83F876B4E35DAEDEC6010EE8050704D4F652DF7AFD0F76CA4C8AE495598CED4DA6F831D25304B0C3F8DAE68EE4587315ABA35F0AB0C57E5F8B1FC28861B94EFFD86A4138874F8859990003A7CD06C78B658F98D4C527A51449064A18EA036AD3F12A12232B279DFAA066A2A6BB855A9BF1719223E98AE78CB16B0C2BB6F01BA01A5EACBD180A5F55486D97C7C004327F70F053211BD2AE5FE5624600E6BEA4A7C3091F7D55BD0A08707D00A48BC4FBD1F5E0186B28FD8BEFABAAA378C500F0F7AAFF5AE10D7CACB3881DB61E0F25D06D4521AEAD68E0123B06C8EB36F1E1F4DAA89FE87FCDC965EE3A3914ADF98AEE505652881A23005B15D4495DECEE29FEA75E8416A73070157DA6CD4F8A112122A342AF5C1CD7175FF9878A328BB94897A79BD38161242B939B8677A161289A6501C7E404F2D26569B5203AD21D2E41E515A2B44719A7C51AF3CFC2DD19E939A6E820093A88E675FB08AFC3D681F7862F3C7E04FF3EBC47C6A8937FD5318F21E393794EB650ADEA8721869F12FC2C36BD031DA7A0F3602E143227696B6944B882A1D7F24BE6C92A8CED148002EB07A89BD4ACBC7CCCD61D79389D8959108B5FD4FC6EB6335F320D796537C4AF1D2653889757762F2FC640B546D58F30CDF6CF19849478FAA2A4CC9497B08B4198545924CD469A92DEDF4617FCE963A12F7E8DC470751A350A700B6388D07ED6968D73C92789C859BF8F5B636D62C047953774C68577E0202E526B75CD4B8C040C7ED79CD71746B644BDFBA2A3D97059D4C10F4305EE36EB5EC0FB2D4395B3AD76F267737E494AD99B0BE9D04864C08B2F59643A3887F08BA8D1262CAE59AC5EC8BD6699FF8CDEE37B62DAACC40953C1B11F11801B46598C5465FD466B48E5259F39308C1C0CC6E03570BD73C167418C10E4776AC7A88BDC0DF6CFC0A4374DBD8C46255D21760A05F2424DC7B1C5289498E434AEE87CB819E7CC121AEEECA145DD5F296AE3E9C4BEC1CA869247DA963A32D892808D5E21C5AEBE225FB47BDC71668C7671D7AD3E97F3C2C7D9F6922B723BB4A1C192F2574E4AAA172935BC5CC8D3B8FE9DE0FD6495EA954A572BF8F99A773899BC4D0860C6EE0F7124D2E8BD80552196A972B92EF0DD02C1B7B93ACE16CC072B3459CCFE7AEB8EEED6B6189A5F6FA2801C529DE277BD70C0A74A256473A24B9BCC9F70C50247A8BCCE4FD65E6CD3B0AA3EF08748075B6F5CAE090DBB0455A95C1A01F0C4132EDCC96943F6A055FFBBF014139B44E775378C8306779AD387BB578D0F6C87A17E50211241945C07BC688A4DAD2F1C67727A8318B4312AF75829DAE2642A199E2519427C0C589128F82A873318ABAF65840240881943A09D04CA3775A5491D8602D631F4A8202C5C58EBD478F54104378328630B2DBB94FAF7346F023DC13BC99E0098474BE922C50A0C373412A3C0C5CC33448560A35E98A8BA8CB9AD6555A96F9E5FE5634DBD12C6EBA9609598262C87361775A4F89EC1876DBC29B382CC3F114E1DD2193FDF18D63E8CC187F5EA984F6B7BB02E8FB6C56B8EB0F27A0E7416F68E8CB2D102D1548126EC80220DA3FF32131BFB793325301DB1BA905B64F3878FC7FF8C6880012FA168C59D901AAF36F15621DA4355E1FE9CE11EF061393CD78BF04BE8BB124A11093E5A7E083A62FF826971DFAC64E455C4AD8AF54D156C34F09DF10EDBA38F9418D6502F781421E8F5D6768C958D1FE86F3FFAFE7A338E69BEEF52E7A12A301384F98BF0F399C4A2CDF1DBC73A24F849FE3039F1021D30266D9AE86A5199D3A27971BA33AA0E1068D1198E76B410E9C5E2C360E07EFD930906C859BA5672E40F80830B555C44350AE5EABBB93CC4A9BA2CD46419AE8FDEFF49E145B403356E5614F988A96031DB41CCEF5061FC616B31E44C08965CFCE685B1F8395EDBB32991CD550700A569475224F173F180EFFE1067B3640E27E9B95529407171769C4B13A502D8FD1380F7C2451ED37724A9746EA2E6ABE1BA232D3C50CD85F5E65CE03CFCD63A1030EEBBECB0D37F98C54B3400EA4075535F56CAE74F9ADB282E54FEF53AE317DCD4C14C1018D16C5EC858888536654D22FB3FEAD4EF8BA3A766C037D950663646367099231211953627C838CE4468AAEF91595879188CEC0B5CAB9E642A74FB4BC9423A265016F8159455BAEC314CBA926F8D4BA27113E5DFC32B0188241EACD32EE8271E146E3D820A44565702982F7FE378682903C2934EA5607D03823A13DD441C76BF385053F044F8FB46C53B3B4DC84F8AE503BD085BC8A04A3881710728CF95862C3F587F5C36E5A938F935188A3E6E6435DB64FB3ABBD6521255A77DECA3131090866969FD379E88D188852430EF637B0C92EE924D632C4BFBE21125B5083009F32771209A146CA19D7AF7345F4A40641E1E1313D348B48137A9A292D6DDEA5FF827F1D5E9C30DCD09A22A03E61A18613FC55C428454BC0EE898D1B81077DD99EE00B9C24DCE5B800B434673E826169EF0B13E11E01551E4BADE5F8C23A37F69A7E66EA174F2716F5C2D8DE74067E1C72984663C2B9A85B34C2D266CFB0700DDBA3C3C33B8BD6348CC3422BB0066DFA0DD49C0A2529A095004C06C58C1512A0E303A29751B759507DB6B768BE9E0C812CCCDA432185042E6D293086A0F6CF1990C7ED3B70C0BECA4A583892272ED984DE09EF53F0BB7415EE51B1C78B69E85F317E47CDA68C558BD3303DAF307DC50F86EB29B8A1FF022EFB9BCA38D7F886766D1AF006389A31C633395DE0B16A45B02BFEF191DD0BCB72B4C3E334E7CB3CFACDE61D61BF58F8BB68D0DC480030FB0A2A5B4462CC21AC937499C3E9584B8684FE30A1B46ADAA1DC1D1747299FC67CF7F8BA46D622EC599123BB470404044A6FDF12208FF47518B13A08529817EAC984BA850E0C797BD360F8F8194600B6F61E270B588546000486FEF61F7C1BA4EE4B61E11385E200E67B2D8D3B6368A01ACCF917A530388F463CCEFFE2CE19A50573B6E5FE1CE2DE99C5FE23E78CE56127889951658DBF3C9B1CE3E9491C24ED4E6FC49B40CB0827A42CFA9DB9AB43837CFBF4189731F978CAEC3E9378C9FCD6E820B969DB94FC81C494772E41C7CADECEB5774D9CA07AF3747137A8C38706979EF7989679D72157D7E933F873B8A5788E75B47AA85DB93F4493B6335347921E492A7A008DEFDE2A8AEABC44536A68D3FD8370B7F7A7BB81F9B1237CE8E4B04EA49C8DF6F68377DE8B7A8D84D2C34B33255BA1994420A7ADDD191A8650E7F63B797B1E8CFAC5EEAA687F7F3776DE10297BEE34C884211AC44390EDAEAD160E4B47E49CE6D40D4DBF38FAD09F32179D7C88C66375777740375D790B1EC716456FB1FBA1D5CE5652AD54A2B7AD5E9D62D01739052D29973808EAAFBAE24A190716437210B3957EDA9C6946EAA9C322B371D30DFA5567D3D374310ACBCAE642EBAC96112F820C4A82C6D59158BDB81AF44C648DBA1AC84DBFA3AAAB9BB64D7B264B13CF3232FB1271C421F590FF449648ECB56325AD339DA594E0795882A95DE0A942A639D3A466D715C0EFC1B81ACA240039BD7BE62C19A924CCB07130467BF4505E1D2495A54B2EDA7A064A989D9145EA9242FC885A9706EA11C880EA099D3EB563099960D045D78100CD6A9B888E22DA1FC29A3FB4AE0A67C3AA8D6B88268D232867E2B6BC940A0B908C413B4A0B85508F5DCCFFB05AB383EA69521DD0F9543F78789F1E35F4A4B7648C735DF12AE6664FDC7F8B99E5F66E913A26622BB0F6BF658796AD22653A23EE8AD8C3ADB7B07D244827EEE2445156116E503258C47EEAE8701C4BA4313406D62FBCA964DA4D2A4B130F7433A8CC1BCCC0B8C4D37F2176E31DC885A07339A103BCBB26EE30F2D7BA66CBD6B8C675F04109965D08E6B0DBC6D9F5E4F77882D2D66C5B7536F313BEB188AD0B6748012180BA65B07A733FAC0858EC5C32BB8" + }, + { + "tcId": 69, + "deferred": false, + "seed": "12B78D9B1A0645B5744CA179DC53994C83B561F77E63C32BFA617CA75AEEA7E6", + "pk": "66396D198882B62CAD6E4A38BB6CBDAF1E27E8549F315C1A3DCE47327DBE0EE648FFE9D9C06DE86AAF547C8EEF2A52B7BF95AADE081C03F75E7E072CF6B22845C52139A10FA2ADE1B394284A21B19FB930EE6BF8DF7F5E8A3E2D3A631205E7CF8D0F8CA673E8376515B77DE4E876E5D45EC152335693BE63ADF11759BD686AE75ABA00295539174B9FC74B69FB7DD1DCFE6A989EEC66AFC30562C8E2ED0418B11356A91231BDA058A18DF1F11DF076CDD5B3D56C96A260FE22AE77C674CD34329F1FB4BE1D9EE13C1B0BB5BACA1DF12BC15AE1A5B9B939C26F08C5FAB9B72EC9E43C3C48E12C7F317F4AD712DF76D31873CAAE61C1358BE84443AA8F74CE06F67371AD4105A0F78E907113ECD4D823C6AA18857D7F5650B030A5E5580D6E37BF97AFA96D797809BB538AFCAA5C1DD6E5DC3F015BB2D7BCD5EF24B62DC34A76FD591309458B1B883CBB48477A9D58F00256C6B285849B4A59ED11BDB568142A06E44FAD490E970757E02505E8255CD0D11161F2CC467C4707F1D4CC7193BF081EBA912064AB1C37026E6C9760DA69D545A89A6F47DDA8DD68174D18AE9947DD9A2EBCB0A785CA3D7ED4087F27400F374DFA167A35E75E529D4E7C4D06B882A114561D26E83A7A000223BBD184CD3D0CA98195568C5788B3B95C246F24A28878244265E7F94EC43BE4C3B81ADD6557EF609BF2761EC1B9F14F87208883A25CE2E80809A17BFFA93D894CA65A22CD85600EE6D9C00D4D07A99BD0A219A4677B689FE953449915AD1F3788A682004DC51470A1D25214496EBAC6DEF10663C616608A3077EC9722B6089B22A6C725D118F80180614CFEE11263ADCA8867C07EB210E64243357F8C41DF170368E8E1718D782CE4FB109D7E7872FA3B242C560FD723B36315D715CE96300F450819455A0003835239F2ED79E02B4B9630BA24798159126271506F3EF3550AB035FFB963749077C537FF6420A4CBB3E09BABF7B020931D9AB34E10E42306E40DB39C1D5927BE05DF34D707E3D953DC333D01B06836B4A543867BCC216F32C3C4663F7AFF2C06FC1DA5BEB90DDC4AA33C4868B920D59512B1181C9C45341CB6F76F66A867841A4073D0FB2E0E1CF5D9725258BFF96EC3F673ECDD216BA10F8DFBE52529C8E8AC80DA471D5468DF34E211A68B3A6FCCED3FB756F59B155552828D2F4988220292C53CB3BC1277075FEE413A8F35E349054EE31389703DEBC6153A61939419FB03A347D7A20E72E742BF878A71C1E6690CABD9BD80ABD79588B9814A5C3D43FC5D6225F124EC25EAB48DAC33825050A6EF0AA9FF3A958CD71792D2D93F5C72D85CE79FECCA5FF77E72CE9093472B6478786888C39B22B5A8FD6578774E5BAE085ADCEC6B0FD7E65479A95BD9FBC5C10DAB4718F2CCB3179FB8FB4C3412BA3F123ADC9EE98DC5C4D64550FE00780F3F0775899587C1BC8C3543B8D3478D307A18A5C90C6B7FF46ADC031152B6E1547168C2C598663EB233F52B28439EAE306DF3BEEF57F4C0DB45894AF4F2BC1FDAB69A2D46B75148DA829EFAB49A07030775FED3085ADA7F3D56B6AA9A732C9F5604905ABF9A45D244B10C2C11383CB6F09A5E576E992526FF3CC0BD73941350B31DE9C8FEA826DD980504BBAC2077BD7B11AEC2DCB9CE3094F95E716CD6C6D0B541083B7F28317A65BA7F2C3FEA438F22E61A1325DD8A736E8C45098D6EE00B97789766C233387F43F43185080F51A55D20D3F07AAE1BF460C577EEDA3B27275060EDBD06019B9122D017AF5E69F4118B6AE2D8FE342D654874A46DEF2413EBF1FE4490E56612C8DB050BBA92F520C620DAF77506EBD5718F9C7D16816F4949288A9CB33F6C5268F9F4F9EC77631EEFF1F67316CBA59A0060E6B3AD6DCA2234F17ECF9CDEA719B5CF0E71EC06B16C6BEEDC0DC6EC4FC855F0D6F6B415E97640F0B6220FBCF6A2AE9215215DE029BAEAA3CC272AA37B89077BC7E7F79213B6E6ECEB4839438E410D3013B4382093CCB74C02ADE6278DD3AAEAADC8583DC7CF1DE0E46D01D6FA3C4CC2871D8C447DB6D6ED19E54F21619147B5F4F1572B4EEEFC439E63F55788C8FDFD65BB517F3EA69D368B2ACFC89A2C8AD317EDD58132B167F28CC05DB2D4BB959208B3FA284129E831CC98FEFC8CFFE3B0A93E3B23C7D164CF17B8375AD27052214C0C4BE98A8A5EAD5B58E169717938AD889E207418959B86734C31757628794220FE487B3222711EB859A17175D9F89264B52E2200489206C47CC96EE85127C93DB91EDAFCD71DE5F6D00031A685B5375C3C4AD0BD2C7DC43C338371AF943502DC9DDEFD080C798BCA7A4FA680505677CC38F2B3CD703196F224FBDD0CB5DE7CFEFDA481DDE2C6B42EF0A0C2765579A185681C88B4A8533E18B2AEB47E727101F6DCF58457F7BFEA5BA4D5FDEAB4B8D7CFD5AC619FDD94360E9960C5AFEF4B21F5449F5F974D2DFF521D2ADC721F8431E2C944C44ED8B66ED3BFFB679DF0866D20CFECCECC4B1AA6F6247D833EA7DDE92A857AB2A179A14AD8D296CE145073980C9C204EB1A8C235CE08E421517D3722FEEE717048014129E2F793B3BFF60EC8D5E413553564925140284C5779B8B30213F282D3A50ED3702C55DF71DC7800232DBFACA8EC126A0202510CDC6289327714071D8B30557F62DC7AC9E1CBBFBE4E300049079D298D44BD8A391AB033512360760A2A045C35B43EAC71DA9761C5BB4D3808FF35FA00C8A538AECF6B84BAA7ABADC51049F7F6390AC2FFD8C40DAA73600F8C243B1F2B497DA29F623235B88412DBCD721F6F8A598E31F8700D6C40590B9E191ECE668BD4C304AB4A8B21A7967CA80C01BA542FF455BA3771BF0766E1A86DE16CB03081718581E0705CCDBF01C12E4C1AAD8B0B25B5558F9A182B6981D4B32B13BDA26ED8EF813906EB171DEE95B27CC6DBBDD776F19826A0A32195CE7F54FD04B5E7DFA7BAD009DAEDF7DA531A1C85E37FDBF65C633A10FC7671D5CA85BCEEC6E17FE57E7DACFFC8663D3952C41238BB0ED95A77F7981BF23CF2B816DEF8A75B3344955C452B416E5A0C087DC913920BDFBEBBA499BEB547C7D1C06029F31C959A1EE1B16C9AADFC7CDCD41C5B8CE23C5E2FA99C78E6BB6D615BEE75B7453ABCCD5BD961E776196D7D5A07431DF4C0926A514388A8BDFA2DF581EF16A7B575357433CA0A09D28E9158802FF21B6C86CDF65697678EB72E809D3706BF37DBA403345FD7DCE699E9A9243181305E615BA50ED867B5401C12E6277D24FF7C167B317699292EDFD4E95EF132E34972D9E55BA4E84CA3761221800D0532A1A38278A079DACB541C1CC56E00C1A7CCCF0BB1B746251B649954766C2A980DEC096BC570B6A4BE8B78D17C1EDBF3CA372B4FBB610FDABA25901A38B577CEB2F627650C80DDC5C255AEC4A5AE07D361CD88717079A883A67ADA8F2B00CA7F9546EBA4279513F66DC7312117B6A80BC01F0C268205AB6FFA8D90A75BE3463D77B98D183A113D382BED583A88642FBCB2CB0211141E64F992679392122F4AC5F80CD8A5DFB86DB5A7EAC05796EED172F666903E909819FEB2AE99550D2F32B5649C9F18E09CD3BC8E8CD08F2C35BE7FBF37F8684E89F0DD02C60EC8A4B271956EF1AFA0CF20BD8CECEF167E42545E062A73D8D94DC8E34D816980681567", + "sk": "66396D198882B62CAD6E4A38BB6CBDAF1E27E8549F315C1A3DCE47327DBE0EE67F3C35F1FCC838A55E60B917C1D420F5D6D41D601A05A3E98F46FD2530A8D929CE70C2D4B69E48CF1755A2C9786E88125B5D1378361DEBD87E61513BFEEBAD447208E14897188019D65B9A54D8BD72F07B0C7A7C855ED506BC1B6FC033BDD3770148045098444C22101AC860E416290AC008932271440209E3982962026643080961C4058A4089031322C1262EE1C248102949CC4226D4B488042251CA466100092D13154522C43003132592A4200B01610C328D22C1681905860897682340210A1572910008CC066C211881224384102941C420280A324D93B08CDBB44DC92208C83269C3B8004BC2440911494CB209E4A221A3482103A6480131604934894C126A18178A1C2045448084D9342002286610B050632090C9164E80B848A14049223804D9A48C0C228A633661094410E0B08CA1A0601002868B104603192AE0904C0AC08804A2090A299023390E19B90451C071E0C4901B0152C2442A83B88591267098101124B46851220011B88D011226C3A4841948209B3072603268D8C2201B43891C97200B3109882264C2C22D9B06691C1828820045602049E4082514820848B261D20461DA8664401824A222858A9625A116496216889148800CB664494842DC2690CA9030D8064E5C820008194E24856104072862026D4C8061C91644CA864D1100904CB00CA1A290A324300C462A004406E2B645888821A2061224A484D336880C208A822868D9162192861102130201114549286A04268DE34432CC984123482C80209201336A189248E100258B2065E000601AC304C1884C083966C3982D04C66D1B1202E3B2518448651C00801CA62D19B70994248AE046120BA9701C240A5C204944189204B16C81344808A0301821929B840D020791CBB8295C323221B04803064994208562086408C5640B182521854CC820010818020093519990016140052223008838515348424414501C078CCAB8311C260E21C48124338E5C087012054D8C962459B06D4148118484849BC42D13B77144C668E3C421D882655404044B486CE3C22400338640C49012C5408A28214B364EE20002A14491A10008A1C671D0202201296A881021D3987088A8604B2491D1126A512411D10644D39284C0220914498AD3C8001007640C327109914D119984413645D8144D9BC211CAC870223382DAB491538270C9248219422A83C82C8C964C9C006540102218B0489C00600C4448023830E212100014618BC0695BC828A21029C2884582964C13147009C411D9B29020A781D4020824026991A20810C660993824C28871C0088D589685C2C848D8A481CC1089C196215C4230E3B841DC40504C48460949284A4689C83206D93485580012D3144008472024341292308EC1A631CBA82144B65081884C63046AE4B6810B20661C490E9B3611E0308021131202220490A800DA86690B020018C788521872442292A21628002845C2222C19306560A0409A40641324492303911C069213464A0A09128A082E81960C8AA06DDA304D0C854D5C222423330508932CC036311BC12852286C1B1751D3226AE2A2298A36285412311CA44804B484233989D1209060282ED092700B0321843482180331532888018120E1142C90B08C5AA09100B02504344ED93005CB12094822889B22044B4468003761944604904410E0B8012331850A2624601644201911210230CA2845A2B068D3466482884C1A888CA44865E31641DC12044444081AC080049104D222894C164209130C22072183366463B8084BB84051B46423964D4A122E1BB98442A665A4B22892248E9B048193C29098148952B090D818045BC870A1280C240404DCA231C28248CA488501B34C62120D8A3429132530E39064A3226E64C49122456C524611C0368264B20C80C091CBA8080C4480D4385282A609C80425C1082C0AA15142B2701BC381CB026DE02232081032E0264463000024C88C02A46C6226609A048D52B800018701C194411993508248500B48296232858B104C1AC57198484C03404264044920C8411940909AC22510A79100B3094C00728092240208515996085B362A228651E392318326481B382D23092E8126008A463241A82CA1462060A60988362E11348008B42D1CA324C8904C1BA54C20280821C684A11042D912881A282A1A405C88893D0D875D4B138F7D713B73367EEE0B0BA8973A1F3755C4AC11764B147CD19B397DC47BD99B7E2DE1455B607362610ED43F2532AC40377F3A637778DE4ED4ECF200E6DB54F07A761527A7EBCD2CFE22051E07CBA0DF8B953DFBEA83054AE29CBB6F6E8A85CD4303E2186CCF0C4F2B979EACCC437DBDAC0ECD89B9D97A548D40B699FCBDF8F03565303C88D23F63D4E79AA5AD78BDE673E5655309F6D57A485860FF4D9F9724AED4B0DD4A2F41257CC8ED3B28B4C232B346343BA371ECD712757CB516B1DF171D22682D77F71A5024DC31209EBF41DA1C408DACB133F9B8256B9022F59B439EDD5209F5735307865CBE687E0392C705C80CF7D31FD4E817B12488110A675233FE76105C040F720324AE3DA7E18719BB171981F3209CD7DECFAF201ABFD28D7E8D6533CD66E3B3B54C7B6854E5056057117A99D413B3C419E3C2A22DA0FBAF3FA0C87C2BBD849D9971DEA51A6A022DC4BBF16F8E08C7F2FB5EC892B18838CCF4416A38E3BBB39DEADC270C338BA467B45B531C98AF14B920E46CE50AC0C15F08C70DAD4A79E7322D76451F82F9A4C4F2D42846C5282D08A0A74E4B1E2F6F31848F1D47BABCE24EB0A435F4F4344C8C44EA295E62C909EB39773BCCFE1196E85191F34B414451F99180645B1ACAC43E8DCE346F574873187A84814108CEE348A0217780D89DA03FA80A9808B97455944B3F80765F6E74B8302308F18BA36587188A3C24D39C928DB1AC883E7D260E50B7F8B36C2D1FCEB0D581BCB57087BF5C1FE018917B09DA8F04C99A371BCC80514FD78E262A0C7C70B212D714730380B108732693FA8F80332798485AF1A988BD430B05AF2B82CFA761CC34F00AEB64CA3279EFAB0CDE1BBF50B6D6431497E7417797A1A7E58459D30073A5163ABB6504FE960733D6789D469D0A344BB719FB7454F60FD7648AA6BA34014545DA6F386CC4915279D549ABC4EF263B68DCBB9BF1A4FEFF5E729834394F2B82B95DA66A352752F20367836D01FD2D0F12D29195DACFC0151D5D5796357741A8EB32299964F9FB7077299A6343B69752E8C9B7D07DBAC9C88C91BD64D0DD16A8435F5FD9F6D809DA47C4C73F47E1A1DC203D4B134D8620C8C4784D216C7E0F650874978EA4A781B054FD3BB383DADCECEC7FFE4F83677A38A8B351520898F29EFB26E64F63113C68C97814E140A7183C5875AE4339A6CD08988E44B9746B6445D6A9112F26DD834E0E26808CB1BF7DE16FEE63C95AC8B57BA335F34AC183C12DF9F02AFF1D785309A40CE9E103BC996237DE8100D1B9904E358D56451D72F5EAD3035CD315261AC8D6B3733515656CF02123155BAC2C9C5F22AD411D5339D7D027D9B3A040E3F7E5FD0B6D9FA119D19F172C2109E43858B609F975B8BBDB64BD2DF89EC26A1FF793BBAF8AD331587A23F3C91D1EF1D4D3859BD31F48888AA2E2821E00567C12B4F3AE880E3A5D36D64811681D8D5F2A64CD9E7B0C82F2FDFCFF190D323DCC96C76816675BB9683485755BF92F1B4E58165779D583D5DE05A172EE3EA77CD632F4F96A5ACA618A4215806AC625822A67870EF4ADDFDF7953EBDE41D7C092A3FA3840AF0678578CA1CFBD570A93EC1AD52DDD876B7D45DB23414143398D14A534FB6D3EBB2EB66A67B9402EC31DE21FD064BCF30187531169BEC5641BD6D5AB835B62146A36CAE06B4CC0A2CB9740497981A915A0F4C47DC39D5E3D15C6EF289EBB5A1A8B5F151AD3AC441DD2638117692F42561DD19E89528A915FD8380980E69F46B1700CFDA67CA516B5A480BC617973603441B6CEFD8806F03D90046703259669500BC8D3FA1CA07E4A68A6A63593627DB52462C16C340CF4D5DC365CD30E616B887BC1CFEC39B6D14F84B89766F41A9EDA5E5BC73557E27365067A59D3E971B93430749896EDD778A81BACB6C60ACC0B9F892AED912718D51B06426E2F2EB8474C9476815081AE71DDCE4234E2021B56337A3A8A0F2F5C02A9024A6E94D2362F17FADEDCBC7AC6F7623DCCC3D971CBC1FBFF347C86052E3DB823055A73769834D360030A059EAA0A24531BACBCF681FD29AB2EE5572F0DBDE188374306E9C13684B7363DF8F8CD26D1600143424C06BC9A5423EBA825BA610BFA0476F94336DE1BD92CCCAB73407D6C2257ECC9A62ED558CE08F73D46CD7D6D69DB8FB0B31D0CACBA5188F87052A0A832AAB76E9FBF360DB1534F4D43860A80007738870F6250B2ED025C6F1E3C0FF5A574CC789BA63C4B6F952ECF2332A74D9F1E585AF38F73F7ECFF37CE90B8562D50F42608734430F370763DD631E7078ED2016FE17E9968D43C409044B86008852E284FF5D262D05A960976A790F9223FFBF78C4A2F347689222CF4C30CBD83138BEFB46075EE28EF109C9CBBD1A5E9F83FEF060DD98415428E0137CD302F7DD9DE430D031BBA25A641667691CF8E64DC471D5A2E2095E7BB2CA6589CEDC60F2C72E5D7C310D4FA63F3DEF1981245B308CEA4EABAF747D4DC37F77B1E532145DB7451C64B877875E8297BABD554E6F14C17B80E68336BA24ABB7D0FA5D02DBAFB105711429654EA1D31BE03165E7DF097B91D55A0A4DE087231405EB9713A225E3AFD7A607939AF07E17A804FB034183D7A2F68BF203B46D3EFE7EDD0527F698F8B5E31E736DDBF68288CB9F71F1A649448D960178105DE170AA141EB6BB24F33A93FA3DE87E0B7B3ED1C21F309BA7E7FCAF181D1FA278575E3B464C9A8F235ADD708F47DC6981BCED1A5FCDE85F5BE97233B8B08D794F34EC4E7656640B86F12396B05D9A3E73138D9F9401413584275BDD2FEF2794B63BA90F5AFEA42FF703266C19827550A162270979270A57824378A0B6A7D33973CD6A7C973AAD16112A9B65C110920F91022D9D1863D81CFBA5261BBB88491BB6A30DC5C1AF54E280EF97B718961A707494B52BB01626E9AEEA4514B3F3D4CF39956861BC7D566198909A6C7B4B673683974919BCCD022F8B69602C066FF1F400AC4B1477B860052DA996ED38A5EA25B6394F8C966D312048139D7795E0A02327C51FB9332E12AAA170B8FD9E812698F73EB22497857A6D6C91923A934F90FB05ADF11808951D8533E27EB57A734FEDBDA1DCE135E937B3081F6944DF3CED2238158C24EA96CD547ED5DF59FBDAB0DC99F9EC67BA1B29A7FB949D79BF2D40CB375A1511FF9935436373CE4CB6AF1721E824DDAFB17C233B254CFDE6979500F69A746E5ABAB4E9893A51A34675F422827CD23D8F47FBF1BF760326E44B53049059628E7406ACA5FB7E036C7CBEF9D536EBD13B6B5FF0084B16D98A88ECA76299196CF51C305EDA8AAB1C656EB18FBC6949EEF6E177BF53BE1371543E3B969A14AFFA7352179AF4686AE78936615ABDFC59BAFE63785D9B707C31CB863B8EC41F6846A19068C6BCBFE53C231DA97EB9E93D014DC7AC91E57F89B2AD96C2EDBC41DA01ABC1850B762740CF0D41E32D1865B9B240210F5B66767882170F4B70D890D3D26243D3FF816D564FD30A052FA9F81C221BC314733FDEA7E443B8659442CBF240F7AB1B8DCE657DC283659990B0511B4C45AF9275AE5AF97E3B0F29C7F9D5BF4695C06C017F6624E39E0FF68E857810CAA85C7D867E6CA49D34FC3564BAFB5CBCD33A8631701AC896E59BFFBF5FB12E877B81E7C019A409DDDD132019B3DA666AEF32CC6E900DD5C1EC750BA1F935274D1B99210CCC50F1424B42C159BFCD68B8F38D12CCD2C096FDE4970A12C251644FA891876C7E56010BFBD29022648F4F0287C1A50113DB285CD99B921876868F5674E9A00D1E6F8C63AD88D1295EE57DE3095050AE2B922F9A04E961C7A0F8D43AA957A00DD2AF966DB68F3DF14CC0FE573D0DB5B1ACA3EE7E95955F3D5892F9E20F9C16E9BDE2EA60F9E8A95964FD1472CD6118F55F5E31D765A89A79F52D89C7720058793DC269F0E93B9105CA4969C83B567C57A911CA26BB73CEE638E359F020B891EF2CB39350714717240B7ADA74B41FFCAD3DE206CB48BCC3D4AD693A6D9A8970EA2F9E2B22800840DEDBF5F7A58F9160FCD4F1444C28E74BF6798565D60470E1DDF64E48678FA187B92CA62E9AD6EB234A398B686041CB907E135D9D8AD429DB298B77CD0139AB42FE38D94EA1A26663238D351564129127D34AB7964C107F28E593AD4FFDA0A095B5614EF9C6E19BFE1B5437B6CB370E17D10E6D34343921553D672D2E6D614C56B45907CE9743E6472CE6BD959FF2AAEFE2AFFF082EECC211FFFC125E7142504EB398B8D34BB0F849CCAD124274D0F8ACDCB1D54D99DB85468CD19C96BB1B383C8079D5FB0267CFD7BCF0916F586F2554706F6F547961FA9B897721C8B6FFBD63F2E1FEE53A8DCDA34208D859D3A00B197D90CCFB6C9B7DD0CB419AA37D7DF9034074BF56256F899637389FEB731F67004C1861A8294D3EB2D8485BD9299A544D25A6841BE00C9F0E01ABC2F224A8F9282B97D948AFA3145FD063BD4B0AD7AD6C691569F19D053A85CE7BC604495BA5183992B97D9D52FA9A4E9949D3C4440404B1970FED773C298E5E198480418ED96F34D944416A7C89BB6AE2B8705E73F1EB098502EAE317916BBAC6FEE466A26077B662DE8C49FE740D3369B976E7F3AB087A3C36874E2DEF2C048DB247DDA6A2A0FEAF2BDDD7D064149280CD18D81866C2E31B9C04EADBC7D086AFA9ED63127CFA5EC4E1F2035A2ED03" + }, + { + "tcId": 70, + "deferred": false, + "seed": "BE8D7347BCA4E0611DEA6C735700DD86180C4B95CBE7FB27491F00C9445D8A3E", + "pk": "1088DFE7FD4348B1FE1AD142203AF10AEEB09381A1FEEA779EB4B292AB3FDF4400BFDFD81A7683D69E63112A0C53BBF404C0AFFFD0401EFA99346A90900A50025B74DBBDFCA7D6D3D3158732A2F7123241D3078B6529A6E170EC0EA0EA99A12FE37D209DE360D5F6D985D0F3A64D4B6BE15D17E1F7171D3569CD4CC271F8A4B8630F0954854D18D36B347D2EF4DA30729383BB5C89AFF73CB5AFA6557143C4233C4F5F178B4D118215BCE7FA19C6CE32F1B73C9DC6E20C7B2E49198BBF5A0DE3F6F4773EA9825F8F5EA1E80744ECF76F831D5A3CDB8292E7D5B6042F5B86ECB6388FAF6E706EF81745158CCF6E8A84A417D6AEF91DA5942ADB6EB8EADFA8EBA0E21A4CBC05DD9FAD44847B518A6F1560E30E6926E45E852A43A3A8275665EE0BDB0216B77AF4086281459FB912F3B692EDBAF4AD46E336E5ADBF9EE98214BFD1596F18D71B9EC1B394FAD799014D0014D340F67989CE35C574BD8DCDAD3C8C932B69A207BE31C074B84C6BA95B4667E07FF002930F32FECAB85B1CEC07B0E5017E93536E65E71223BBDD3174DBDFD3649BDA2A850966A4D5407DD6B5CC2B6EE5C0266CA77F3FC750B3191CA67A049A127644784652ED02EA37BBAE4530B00FFC20F7538ABD09157B986B4619539E99C0775CFF5FC22D4D2A605A68816D8CC7C214111B0EDB53A0F1913F609C78B8294968FC47782BB0B5CF60E82BAB42D5EC98F18F3DACB954ADA096E12FAF74F68624A1B656065175B420CAA238579102F5454EBBBA8391FCB059C1AC64B7466A69AF6A2C3B3479939F22B774CDD41950F1872874F874C83D6129C3DEBF1746A35BDC51A3086331596C242A05A34860C07426E97D5ED9FA43B7E0B2AAF7546323517795326A84BBC3DFD7B2AF2A60ECD55F0C17214C76B68120BA3CACF063DCA7286174228D2C6D918BD1B69D5FF80422E9C7BBE2C53B9C4C6BDDE5A484C7AD19EEE4E04E5C5331B33C350A84D96E60A317DBF9D9EB9FBA32BC1F1074CF4E55C6ED35993A005675C1ECDA984A06FA93F16CC4BDB6FDE74E936DF0AA09934BA66E1A096ED6DB1B0438073FDC59E3C5033381D8268A9125766CBC7864D6583362727D11324A1E4C103DE210873D5FD1216FD72C443201C6B179DA770DF8BB6C8D65E517CDF2F23732F52659EB45A711DEDF5A0E67B9F20A28EBBA2C0E4F3EA21EAD329C6B2888E93E6C3A2A630B8AEB40F31D7250D5367D3C74C36D1C68F3A537AC3351820BDA795F112EA80BAA1D2217B65405957C52434262C10CB556C0B1DEEC1059A6EA4266DE19C05C07DCCD06DB1150D24690355D6B2AB11BF4872768C339A4445AF61DF7DEBAD342A617A8C3DAD91172EC87D12D14BF2FBCEFEB7914C5806E0403874EF87C2C3C31B71A419134AEB3B57315B19EE5CB661C7DF9370E476789B493BF8B0187481A34D8EEABB828D2CF0C014E8877C050D288324ED8ADDD7B888CE3F6795F4526646ED176A7252C58C61449B7B339D96225BB5ED2B78ED0646B0A6AAB394FD8A199150763699809BF58D5FCFEAD0199C8D6C68C3800474D4871EFD1D4CA94D4890D2D1181AB759CB914925AE6EC91A6ECF11D237BFFBC352C280AB2A7184798C0BD4579149DDF67DD1A242AA2B1D3111CF32C23D64DF2BD617CDD003427C11F968628DA45D912E4B7468D6EEB3B99702F2991E6BAB9528DB72C13179383D41CB6A89D06B6FE014400668E6FCD7FAD91AA8B1D1ED618892C1C490BCEF17AFB653FB5CAE9FB09942E14ADF650824CC83E34A43982AF55908C20445391CBD8EA1BFB96F87E518908209C1D173E80B71E7417DF0DD98849D907C99FFD83FBA09C113138A51133D3C246A11169B149820CB37EB619F5D37983B6C6B6DCBC48CBFC8B728AD9934B29E9669D2CD5F427E22AE1168557F80782F7F01E4E5C2295D3A04E771DF0031B4F6974A63F9F709566A01CF9428F791AE2277DBD58213B13B91AC09330729F9B3F2F74391AE2A42B3C85D1713B6BA7DFF0677C7AE4168FC2B4C09F3253CFBBE2F6B044818A650026EA3D9CC6702DE4DEADB688F52C8774E91F31D7466D4FD5669366C1CF7D5686FAF6BDBBB03B5BA479AAB69BF6E5FF369CEA5765AB55C84B4F96D8993A6E913FD9B7CCDBE4830BEF447F66EE983A6305B03F6014E4DD0BCDE87C30EC7DDD3E0CBEB22996736E97E7AD0C94B825CCC7C489DB3C271D84B118FF68F59254604F12D22141E333AF6BE5621C5FF8A7C1D8AAD98E6EE69EC17A520F6370B070B48A804EA4DA8FDB492ACD53979A61266F93E296E89C4E3C6D7109B83E3BE77F81631B1E9A07B14C9D5CA2C511D640D2DF07E9E66D022D2A71E2371C9F0BB9379476AAD6A76A61E9282BCCE1F13322420F85EB96D29846A172D916181357683612A39C94D9FBAE611DED9E8AC2EA4CB91E2EB37494B58E33A9A661F5CDB89E7286320EE03D46138D5C62EA17382C3FAD1FDE6A3249F235FE65D4F1F62BA26510726E2E1ECDE0A156A01BF88142C4651A0CAE7D01E9987CE9BDD691EBD2B90877B29A10824AED9FA751753378204E866C755B665B17F9C8CA44A1B1D482C7B9D7533C1C96891C9F1D98FE727A286C722F3CC0737E90AFB95BB75B8A4BE465C61AD94A8D11E5969EE5C594057452EC61ED6C5B21E4CABFE07CC00DF5F734F69C747E79970DC20726F7C845E68B4C4C4F38743D716933772714C600740A9D7528030C4E7DEAAC03EA018A2304ABE5881F10C6D54A53F5203E7B65FC15FFBD40FDBABCF4F0C6FDE7E1A69E8659657FDE45E633A9E9837BE399CBDB6F06E531D62F5B5F9047D88B2C93E0603754B7D2A2CD6C51975A205F80C5FB0AFA7FC745D7F09FDB010963FB077A1DBCD1304A98256FB8C55FD86CA2CB9FB5321881D723A11CA9043C3ED48909274820127DD7DAC77B0BA8C29048962C77E10D9544159E0E9CB80CACE205AFACD6F38A680411AE55D55BE0AAE59F1A355ACB60CCE7E37BC3D8EB96FD8A8BE3E41CE80BC561A16957F7BAC93BE401F896EA0A76B56D8F34998C051AD8440950C3DE11583D7751BC29F1C5C5EF72D1244CCE46932077BE58F56BE3885618BD33265CDB2FE482AAD6FFB1F1E709ECEB145E05EC3092951C2C9C8DDAD869AF09DACB5DC161E4836147CE63ED46CCCD5E453084BA229066202073F1D2A275D4689A187F1271CF31096A1BE5B5138D45F88D385D0B0EF2B43B18ACEDCCF8890FFEA8E00DB74F0BF5E11EC8DA5C4D293A3BC5D957C5495D12B1F8CC2D131DC9E74679BC3C969CB50B06E9FB4979A81A02BA1F2CAECC2F5452BC37EC370FD00516E71A949B3D39D9E36381E061E7694F467290726E35DF4A7D86FBF5DC59F29255C0C2174A8AA5DE8189AA00C3F00B173438CCF7D19002162B608F79BD3CD68C345732B914EFE4EEE05C6951867BCF3E0663BD9EEB8B543D9548E8DA9643D3A691A1599409850528DAD2955E6A2BD84A7615FA3E4A58DAE63F35DAEC6B6A0000714ACF78C3939D97836E623CAABCD5ECFC71B8C20AF2ACA289160765C9AC91BF9C64B624337107A9B890738AB3CC92A1A5FE53C5F9741CADB323A310A7376070E941D35E0D7FBCCDC1C45D5BD65ADA152CB38FC786F230A71C47EB5E47D6E25AE74D0615F6F3CC0A27154F43300F6B6993B6613AF45C36C302C2327B7F496AB0", + "sk": "1088DFE7FD4348B1FE1AD142203AF10AEEB09381A1FEEA779EB4B292AB3FDF44FD2ACD1FF283A37368D3B17D6A7B80562452A6D0EC2BD04D0FB88621954FDFD96735F21331D6E77E8B6C8B93F7FB809353C07FFD5C703C7051EAF4EF1BA870BC6E0AA204BCAEAA3E31FB6C1AB0BB8C91FCBF6F63FD3473AA2A9C5E53D03D36C20B328091420E21954124350C83302102B96054B065092930118085041790C22080A3186592142844B26C42B6090133265BA44C4A106243266A44863040A45020B56501486013B52D14436AE120059316625A32494324641B3949601284D93268098024189705632280D39864DA482091C82CC8A620039581E3A62DA3126DA1207103B230184470934264900650902490E2964D23C8105B36305B304C003190221571C4B26943064A18155153040D58240444404ACB0642E4928DE2368121030E09162284468509070594466A2409661A412AA1208244308DC240649A4432549040212084D88601C4888883045061A02914095248C0119B106A882851CC086421358E14A661DCB42DC0B824134092A404060438091122698882042182481187101A1444090730CC8245A444100C022508152EE40820C0144512294D040649E1443101A704C116211B424A09B4481CB66114A145038791113331023331D338308B12329B000292428414B94C4B426D0805060239681A83501406488A262DA3C8001B036C0B94098C344C440832D2386ECA384A18426D09458E19468619A98C04105003312921002ED4401283069148B28911A56CA0084E49324D9040691210261BC36823302C084742A214802023881C3526C1128D98A6509C96311A9484644486E2A064C9160E94888004226849202A1CA11114820093368CC1C66D5A848C49228922C830DA18450A006E52B4215A848822B48409966554444ED432694CB02CDA362144246EA3C440624031841880E11012C3366580A4111C25020344620A164509470C22328C9BB02144288D89B00840024C50442A12C44002C48880344C11016E1130480AA2815CC84D92188E20252A5A344091343099A22100192018C58C1441218C824918208A1988299AC4490402284A025004064514B505DC18849CC40043282564262D0AC3085C1646A0B02508189212220D9C16200C33620B818C8C480110A50D0C336E4C88291A948521410164920D9486240C4808DBA44198A6844C106A0C984D21A98C82260AC3269212C550CCB48144022A00062049A861890611CAB6700B326411345203802961326A1429081A3090DA302513238C83380553320403172D8806514B86901BA6484A242153986CC098300CC4700226919BC411C4484E1C0960020361818230A2082D80048C01B500C138651BB5280B116288961192422652C88510411014C86109320C19486A1A21240418081C096918466D032168D4962D0AC08100B631C90848CA1069C2C608D94281CC208160203160442060A4000B326824318603410AD88469CC082004C685C4C68D92240960484219408C01324C64B489D9C26809890C1A224A1134601206694B2692044889E416629286910B838814422E244970092169DAA840220584D148011C220A12B4480A217220416AA1C86912044C0446704AA69150140491C0690890655B380141904408C7044004460A47868B480159406164207223312C59B4308CB2480C0971D08228582421C41825DC1462D0C085E3360E11B36802170A1C0529A4181261206098B84504456D0AB460210572C4C860A2920001942903A691E13261E004918416890BC24D61C62922426D13454E833412CC444E0B344841024DD4920451306E5B006C20016210322D48288418355104492C60004ACBB48022A864923620233892482409228445E2B660CCB2518BC68813C1442193089B828C53248C49362C1B854DD3B26923822C4A220CC8B60D13C9095A4831199009C944305AA84949022504B72810068662201044924480A6411108295A164D18068CD1448CD4A46521014203A00C1014041AA7659088284A006DA38425091346003930A4B66964446662324942468421494A5B00846224450236810989480298709A903199A02C40369019B380C2B2610A300C02454010378419256E41946D010488E3B64808848C0A1042180665D93405C1441014132C11C04D5C4268D4104C403690DC860964184691228D1C3468D20170A507FDB4E85D7F3A939B1F58FA6E23A8E76C8D110E2CE9D794F066C0ECA93CEC62369E8AE09D91EEC5237B52090045BD6A9B9D90D7C4D9709E43C83302885194AF378EEAAD715716F44A31BFE4694EED6581FBB187165E925114196CFE661ECE9F29B0F3FE4F591776A072C4908768773E8FDDAF33D7628C00490B2E42751BCB3D0CE4F94BA23D889C022CC94E7CF002AE28FD037BD0EA5B52BC24A8E781A37E7E3C656ACC219E429E504792A9DDA870FD4E410A83CCF7B58B8C98834CCEFFF71FB9B744948AF5A67F25C1D61B823585E6CE1A80D7827DBF142CD11771BE47EC2C625575D1841220B579C307C59D5C94AC4C83CF5FB060E473F13C4DC8AF10B795B2C0F96EEAF8EC24992BD40CB166EE55EBE75DACD55CF7EAFB3295AB88B3E92E499460929B728AE6C2CE9335124D34A2181E5E3CE485807F0D82845DD8B8097E63B3AAEEA170A9A33AB83D710D4B8D761CFAB70ACD863DD82E6C6E882C1CBA9FD25AEF905F3E4FE2F90A34D970284BE657D93090481B541B2E5844BF13A491239AC03FFE9628BEC0D29A31B6F4A7186BED829D85C15A4510D80D3BE6E21913221CE6E4B556B0EDDE23DE1573563DF9262373C2713D4A9553C6752F37E7F31AB495AF86B86B4F3B58075DCB2B0DE5E90455CA7608678D102BCBA5067AEB49A0F6F149A14F0F69B6E47CE388F5FF2526C714CC698CE76E4CE6661B6AF65725208DC2C03677D4D96267F440122FB85EE1E6365A03C81AE161FA6393F4B3D8617A5654F56CA5F679AA8AC433E7C1B753908AB22BB2831FC00AA9BF9F98AC985BE604A155DEA2CEC22EF7A6F152ECD49BEF30300BFD4DFF5BF834131229B4263C3E8E37277365B3078994330BF6951B2ECF80815FF69F2507946D3B22809B1C7FF75D48FA911CD6A13F8763C69D72585A01F4C3ACBC4E0CD4C067B262780475F886B9505033B219BC5D06EC5F6AA4FDD610BAEF4A313300BAE8A58A6CE7723C84942582688081A7051E5522C539DE8DE21F910BA8409A84A079117D9B85D856455B752C9125055605B4F45197B88B92F95C36844E0487F1EE7CE2FB57CF0B7CBB07930440DE8117BED892CCB06818201AE6959F9A1258DA6FB32538F6D4C7C68636039EEBFEF06D8FC56B71764807B928333AFD5232B2E3D699F9B1436E3A1E086986D3759446D8CEABB56FABB4399C9CA347D3A2DDF5BE3F13F8F388B47608C01AD4E1335F5231E3BE21A57455B6169928D9B55FC3D0802781126A9E4CC183A4BC9DE0AECEDBE90CFF67301A7CD6DAC07DAEDECF4F639A4E71EF0C35FAF29B1090BE4BDE8C2C60632D62440BEB8368F03A6576DB06E2931273F355F94F2649A35306BB1981351085D38AA9CB1723D8C535BB9267FDE6C526B69C00D89D1CE44AE51125872E612A418975403BBFA35C0D4FC507F3E810EBB1B3710A670CB27D749F1445C310C353E59244C5BDD89D7D8B9F5EFED87DE0E331E687117C439EB4249034ED6CC1F0F8C1DD1DF36977BDBFC1068C850B85DFA7F960C626CE0BD34E6B37AEBE1B267C44CDE42EB2C86957135E3BE09E8865F42ECC25BEFB39396A7782723F42F211CBE18A37E5443256B3A3DEE4C6E436B7995832D62A450B15ECF775848C6B7DD8295F8BE723A885232C9F784A99DCF65035CAA2A143528B96D94FE9347A84FEEC81017080AF833965F716F08C5B834A95A0EBD96315FBFDA08F84F42A53392F40E4B4EE85B4C0782CD74E489D0C2B398BA43CD2EB1F202C4DF1D923428DFD9816D01B51D4DC0D93E7E4AC0336F058F1D122B500A4D2647F99A373816DE2E82DFC9D1AC7C50CE69ED1C0CA96E5B158635EA75232A1210C78A83E6201CB07EAAFE48A64CDB8E62AB122F9FAB90EE073CF65C8E977F67D9B5422F8847D8B53E917915963B4FD595F920BDE01A4DC6A990ACBB5FD6D539A35C8D1A9885CC227D175C7148C166D9BC428E64EA2E8024C02D3A1C41DA20056A3177C5FE2EF228A8BC89FAF9307F6830DEE32FF753620199B990129F2CACE1841439504BA08C46FD49BC52355C0DE4F52160DFF1CAE29404A9633ACF497634D47ABC680CD24FF360B32FC7EA3B49FAEE6BE85A9C983E8490D75561C3A12436BEA48D07A1E44DFDA08B4D11AD497A8B0176766A8E596715646E44995DDB5BFE8CDB0540CA9E79D50FB78D2BB403401D7AFF234A35D820333C0C114A6F3598BA35A894EDFD495722A233D00F9879DA4DCD9BB22766E8A31A017F2BA4F50D65C70D6FD25EBAC7A79C60C41E132A833C0A46F17ED241CBB80B2E2568959B707ACE990174EB94ACEA580B1EB7A4F4FB379AD58EE1AED4A3557382EA56B77DAEE6B7E82620E08EAE12DF1EEE4F32AB402E759D5544241E541B8C8EFD16323BE507747C80311BD92383E91E0C50BD6BB663D3CFFF1F65EE004C7093DF7CBF18A3D8CA1539716EC3892086BF9F07F1D1165564E19A53B3CEAA42AA703B5A65DC6D56C781F4D6E1FF5C7C183C268677415D8ADF29461C7D64083B8897365C90CB6FB0663877A1F74972E56FB2D1EE8E4E639963AD4661EE0DC9B96A39211326B2AA31D2A5601820780D3FBF98C0AA9B7BF9AC628934F27BBACE9F207C855D23F4D70D2D5ACA4B811E8162B1CE8E88CDB6E2A90131E7A147D30B79A2C753C3D01CAC80185B20DA14E23AC7802DA5A4F9950B4AF1E346E0E021777FBC7784309E18D2260516CD018B8FD66B042B1EDE8C9D6B8526CC0BF6150BB8F6C3C85905DEC69A971B7442479FC06AA17F417D12BFAAA674817469BF682918B51F2D5B7503F5B356624FEC0EA777FA7DAF55B343A0267BE6BF4FC58615B52E8A23370B2B6DB1722130F6E1316A2D1804E401CB1D62F2AEB5C3EF08EBD4F535DEDC1585AB2C7F9861B65B30FCDF25AD1DB9DD0F1FEA0B073288D5FAFA0BA4473A5C57004B3AF12FEE605BF2AAA44E19C13D3E05D8513797C0FCCC7C71A56DD232C4CD1CEFEE6D26A17ADFDEB206FDB9E450359D3AA61BB8B98059C6D8EFB18430B048F1F0353F5DD41F5DC4C91267D7C9E24CAA329C3A314544B044DFA5E8ECFBFBA48F3B115ED6F1D6B6E4CAB9E31EEB452ECAC61624A0B6982AFECEEE7EF4E17BEF17EC35BDDAF762D3C563D42E39BE18B1305632E46E87BEF197E1CA9A39D09944D8C93FB1B4D9F739AD3B967F0F16EC63FB35E582FEF7A1E3B2E225E2137BC6F2651797AFB60D01AE4D0EF1457C25C5596788F15AE5EDB62020795F9B24A3022DD9489ACEE2C3E393119CDCA6FE0A3052A1005690EC207C31C19741F7661898DC47B1F7D77157474A2C00D5C47E603CE59C5846272277C7D4C31A2046BCB2ABBA6C0E10DEAB577CF71D9F0C96CDF553EE1EC8230ED7B200946DCBF6151DE73F0A2B811C35B00BB24C7173BA4C9125A440C6193665D855415BCA4007CC33CD00767CA96846DF15A8F485DEED0A21D011259AED3E1623DE0EDAD0E4BC516AF208EA242560627F8C36178FBEC5B05DCF2B5FD3BB72A4D993996A03B6CADD20DC3CDB8EC4219CF454020C4B8EF1B8BDD401ADD90FBC229D1BD3AE5728AA2BF7CA5E3630E63D8A14FA42B20E9B0F412623C371C6B7CCD60DF4B979A541FD21CABEF1C9D56975848126795BA1CFA451448762550C6423A114EEC6151198ADF1D5DA22C8C43EFD81DF965F8463569899068FD168598D168199737786B8C70F4BF4062AEC00FFBDB3FE78CC056FF1F0E6F0E6EA6E7DED51105485A39F60B697BF8C0DDCE72F754C5584F31153FDCEC4AA664F535F7926A89A5F1EF06EF9DA943A2C6DA79D4DC1753C42E032CCAE7510E37DA6AD20E3BE46CBF901834C78482D539B531218F83669565451443ADF15EE2B98A90A344DDE8D373964E69785139A5A7A285C3964DF177C823A67B2601938AEA360231A2A368B2A238E3D15A265249591B7D64BE7AF7598FB92202177C3CADECD5244F3C2DC503B6C63E74C27A3F6CEF73D216C4789B7DFF9962140313330157C5C90B0F62665A7B386988CC6924397807E1F2E28CA147C2028EF79D55889162686D8BC9C0391C1169515024FC5E1825E60EDAD1DDCD6E52684F79D25BC15249E01605EBB68DF71935B643ABF034FAB9202111D23813686AA284AB1276C089056E29534660FA2401EC2CF950E90BD84A742E83DB963DCD83868C98CFCBCA330E7D3AE30FC5FFEBB2A986EA6DBFD0E11E938DD3A3E19A6D6FF277B9D2CE0F556EF725560A0BE782D3F4F6DDBDE8C1EBA97F1ABDD9790DBBD40FFBCAABCD2065C0B25788EBB3C9C6D0C467C6D18455D3DD36B90B0EF0A0A3784C658E6377E93E27ABF4220426C90530E7FC078EA863A507F2D35FD10495819490BC4456FC6EF09F74A6FDB590D00EEE79C2B28268CE62822D73B94FA35B15E2419EDE1DCC6370FF6A43EE2CD3DDE1FEFE9C79B4E6324070F6539D395238B6E74F0E45303F526C1E0C21D1C60D5FE89C722E973C9228C8396322D77D9D5CFACD112D3036F8D6C9C36B4D163131E9A0DC2AC69E33000669704B6EF7B53F035398BE08AB7308B77E1590160CB2236DF3A14C59B3554F460C56B83BF1A2C6DB094F01A42E371F2DB19034358C6B62D3B028D415325315181D6FC7AD306103FC2E9CF9E1DC3587FEF8FE45606099155B0C23739DBDD123CB0EA801962AF5745ECD047717CA8922EF9FEAB11A45397B70C4149DD64BE94B75F0772AB38D623A6DE8D26D5209DA6F683A" + }, + { + "tcId": 71, + "deferred": false, + "seed": "E4CA0A81DB7A44E5F3DAE5B9770DC89F15F02126C3077642B67B361B7A75A9E4", + "pk": "BB9BBE6194399CDDD376902F1EDCEB65AEFEC308889936C76CC219AEAA403F5AFAF5C7E1BD67EAD28E19515D528596C1BF06C666294A896F79C09F1D21EBC70114085BDCF824D71D95EE4947E1E3EA0997FFCB4463CE552D31F0359555242B134B4455F3DCC906C4316DF185DDF332D24F7984B531C8977CD997BB0DE517AF11DE8AFE89150839AFD4A927F3CB5722E8C01F3DC10A558901689E7D7976580BAAD1FBDD9E390F40B045CD83BAEA0B8D8E254499E1BDAF0B69F9FE108819CA35DF692BBA250A2E381F795E25E244A2B6B47EBFAD304365E692B58BA89C187006C68CDE179621A43E5E54628C080F15591B0C1F312DA3300C4B760552CA99AA294BA7CB0923294CB53C22909876E568D125214936DD978D0E846C4DCAF5E014232672E0C5FC33985D32B9785D754D797AD9D5A5C45730F5244BBB470F765E194EF081FBA4470BD80F8CE9698F0D4BAF0B4AFEB8BC20E90A7E4F7E4EBF8B9DF483A3FA7C723B982493C7288D47CB4752285C8EE1766EFAA450A5F7EEE1347BC2302815989A7F218A08163776876177D584121E2A47F778B516CCE9418A9F55E26C8C02E4A063B5B08CC7E65DA00AED0DE22361925FE57A06AA3AF9C9C380A1699947279CAD5616CC515C677CCAB310547653797D2CD344FB5E4A1500BDA741CB36174B17618088AAF50867066203DD4B5C4488767950D9DB333D38482C31C0ED75080AB4381429E4F22996BD79C16DA38B473B677BAC22A0543BFFEA798AACF9792D879654CD01F4471D447D31B5B65F98FA56C113E19AF22861E557A1431E6963BAA47237F618DDD85A295BBC1D21AFB59404333119F816C787D0AF0A1D72E461D1376812D02C5951AD7C5656A1A6E163ECF6A80461C5636FF561BFFD0FFBD2EF0A3E7121885F474CC04D34BDC5C677C031932EA22D64306B5DC4D7E09B3E6F1034CA50E3ECB3C8D18B07B2954E7648DEEE772AA689630EBE0DF871B4DBC69BA812B9F9B7E7990FAC1EC61A85189A01EC81A0FA6431153EFFB49FE7A6403A63FCA28F9AE70E50D02109E9176DC51ECB0ADF4E85C55EC558F6F81C3588A21DB82F26FAB0C2A3F4193F41C2B31401019A491332331A37F2E4CC465A3B92D23CFA7D7087C548508884B53C191E5E6C31927F3F87FE67BF100850C036ED5C3D0608B4C31B6549353672A1DF0F45F68EAA6B4151264C7E6D8CC2A6259DA6847BAF0C3D8132001B094137701AB4D24DF93E3A0DFDBD9D6F276146AD21DCA259F23B4ECBBAE815A850EA004B8C692B77EFAA3346D5AA55E960E9BB23A270A4651058425811AAA77702A74BC60A8BCFB1808E15A022203AA2337D5A3A4815DF05CBD4C2D7C49949D750D745E5180FE7B3B5734445E8D9CA7B3BBA4AB3EE400D2CAF1E51AE5068DA38C7368CB2F99807B02E61766BBBD9A923CB75BEDCC7406B5C97ECB6CEC70D1E92BB949B9CDBCE4D94E4D63950ED163AF96CB8761DCEDB8199150BB3B8D9A28C2EA3C0A13B55BAAFA4DC2B4BF9A697C5769215394EFDADD3CD91387AD25819E6C673B9E2421F8B22465B91E62539706579AECA5F61EFD0442BD8D230BF28A45E133A3A84E670F645CB9EC726E84798DE434E3BD79743970070BE5D96BC7C59050050E51BDEDEB74204C546722C62180BE677BE5F348ECE3F1CA8754E56B4866362B3F85DA70039ECD2713279ECCC903F8912492A320265922AE7154782904DBB5CEAA41BF42A612FBC7778BEA414B72D304C0F9AB839AC3F9844002EC0936A5AB70B5598C7A2335E6B0827B4DB3FC9434AB37CD12DDF8B45B0742155D1278B823F95712C9F437DFEB37977C96A61FF58BCBAB7DDBB45591D7CDCE17FDFB4793543163DAE9EA3560860DDC797FD3A9F9FFE1089485DDF004A2E5D3420A10AC4D6332022C18BFC0B4B762555BDA20020AFA3CBB33179E6ECCF71864C200466A28D39DE24FEE24DFBF05C931B215490621DE320F5A5F8221EF5F4F085BC873C0FCF60E0DA9C30D29CF2375A98046FE90262C881961855E7945428CD255E9B3266D34844365A10F04E533C489978D055CC749082BB49B92A574F5BD93DF9751CBB7CE3B065819E0E46ABEB2BC1E01BF31F69D4D04C752D57A4AE5FD2548042383C2B3BF4D9951F575FEE99205B52215F4FD67285A47F13E27C0FF48D924E3E24061983CBB94CE39EE6FB94DE8E8FEC2CDB43D7B88592B9C1DF4C1FDDE728322E27C99BACEE3C2B40F4996F27565A454735EF4977FB116921393E964FE2F06913ABED35849782282688B2D4A05EA0B068BB24EAA04D31B0DF024CC845FF9EF6AA358957170000BEEE474BA05C98DE6A3A7B25C3AE90FF347E231841773B20C81013A6CCE8BA8B0C048CC24CDEAB59BA03776C151756C9F7D7F26801C5DE1D0A89ECF3730A7C0B960B8D458B7724B0B6C9BBE5ADE5232FFDA9BFE770E3A44F25A030D6E7437A43645C32B3715A72C44A5691DAB8A22D8F3743E5B286DD8463ABF24FAEF72D69AC2A13662BCA8BB70DC801327E5E6BB0A491564B03A33E1EF4BD468B8645338A3B0963DAF439637E4F703B6C753A5CFF812D74C909FC5A5C3C74D128EC21134AD835DA5071662846DE039D0125EB8DB4F5756B70144AA660EF354F60207ECBF4E71F78159F303DB891D0B553C8410260C8EFE95A5253CA0E6DA8F8E242BE336C15B3DBB784CCEB89410FEC3DA3E11F3D08F32556D64CF9908EE93A7CFB4A2464B8A91A845BF17E40DB9C4AD057D900FEEA19BAB0001C62203922108091940FA46CA09DFAE5AE61C49737A1A927914830261F214C97AD1BC95D3D7ACF2CC18504A768A6CA528049CF80D15D1F75A14542403BC1842B944628FB145F86CC2287E2CA2C474E9FE18DE39730C2CD48AF092A28A8E10EBFE68E0D339087BD81E3A6A13209BC84BED40CE38C3E8DD9ADA8E7AE603BC0FFF18224C2623BF1553070B6B8D247ADC9E3DBCE2059F9483656BD0C7BA2073CBAD822D8210DF3CDECD4C8CFD0E31E4AB8DAABD954C2563236917BC3B69D7FD0233A6727662D74B1DACC59902A4422DB75D49BC542C5BA53639591ED5E08A74AA80A52969C7D3B0DB9E974642734A22050887265CA80FB9D04FE6D67C8C009443386EC676C9DC3A0C6A3DE7F5068E0BB21255AC5B56CB0BAA51EF66BEE9BE3D55E836B4CE8AD55137934A65B53CE2C4D9877D31BABA7BAF9DEF94E13BCFFF1D419867F2CACF758A72C96F02F6CDF0D9E392A331ED4A712CB0904EB9E3D6E2F71740EA439F50E7E53AF0CF650680F9DFD52F6E013BAEBBC7601E1322656B0FBF8857B68BE154C3ECFA043491D3893F78CB9737A45FAE9083B99A650037108C8790B4F5C37AEEC831B1552519942DE4ABD523850D32B55F4ACAB3CD9E589067875BE6ACA634348C361281B48C59A37909C23CFBB11868169306B775ADB7A9952CBA481E0AF03181F6C0479C433DDB38DCF3F76A1F57BD79CD1DDC5345C0BC9E4B9322D0A65E9CA2ABC2CF988AEB047843E65C46B94570440B66F0272F182D2203DB65B3A62710AEFD4C1FF9D540DF3F83B04EFDDCAE5F66DD9B6E1137D6E0A6B3BBF44A995AFC1BB78D66E9CB70198D4EF8D43A35D2281CEB56712327F5CDC8A105D7C3A54172C5EA0627390785B7C47C0378B7B102EBC78356A64AADEE13048F0CA0E83359D1A5D94", + "sk": "BB9BBE6194399CDDD376902F1EDCEB65AEFEC308889936C76CC219AEAA403F5AB2A9D6678985CF8786F69F522175BD04F4CD743E00045D3D4946EE206845D21DA867F2611FF3003BAFB007C16E69CFB635423A3A162E27876374ABF58E3E14D326F06FAD2505E77263BFA84A72031CC9AC22D96945D266C21CE1C43E993EB953042722C398881B106153423299A8480846525828211A150024B46C14A130C2A66024A62453004412172D02B2080C16628806311C42099434801318862106515B226182A605D43489232705194668413229D4A82D102852520260D2324083C02981C4301AC509032724E3A4314A0245131345DA8270CAC671DC4265C9822019972160004161186820841013994D63208C124592D988640BC06420186E54B68940B651E0203089C6001823100915415A404D443231E20026E44072CBB2098016700317681CA924540491CA804512288AA1368943080AC4A2909494481AC7640B144D180906501005D2A2081401218B184401481020840C02A25114C63014359013010961B46C03C97081428823861103998CCA346904827111C921C444251C312503432D042665C2142E59442E8A848508B909D10880943866991808A4020E5404464302219A2621038421A0842D10B040A2A4050AB700C49410D9344964B42403C08484246043306648B2492401895C0470C8B061190680E2084C00466860108CDBC04102041010A4048142519930415C068160089143866C49A031E4A4610C264409C628C8C40CCCC66CE3A29002898818C98182C0491B276A0B832C03A22C64306A010272CA428E18048AA3980108A26D8C98285AC208A1C691A33026A3928CA4304164C89122B96C8802489BC680C4060654404051A0080145051A396A1106311A46420B08054BA088CA88480800049912306198710328246194609234719C288D18334A014704841211A4C82DE4282589A68042462D18028ECAA8454C82211A28881C900008449200306024C53122A1850BA97090C02C4B344E8A80640134128324858A086863024022467040945114234D52308103381008B30DD3400D999465E1246D2438901932001B08401B433251C80CA0864C901862A2301151122918874D19266C03C88824022011122CA1A42809A4305AC60492244520986D12C50884262EC2324124134AD3002D60322224181261188112242C0A3168E4088D4012841B016E88C40014A00C04032C08018D58400203B24D0C93048CC8288A866508108114235100B6901B347014C204A1C62D5B10250A4071841671E0128EE3308E138128E4846091364A1922119C966401944420954C61C4911383108904642231220498690401280A9384C9422E0413721B1420819220E42832D8B0014B444623B2640AB88518046662444CDC2670D3328208B66D1319440CC1100A183011171100092584164C82A60823C6610213610A992022858521072C244465C0B81111829119B36549A649D4A83122392024348544384CDAC29108A788A438311813001B070AC9188D23B700D1881183A60C93346188420C52126CCC866553826D22104124A820D1204D0C9870C8442210C110A1246D940480E19881D320490C48444B26681444620C060080326888304D14C9701A198C81384A52C09111236D129621A23072DAB04C0CB825242826D4348C8320905C32925C1882C1C48CDAA6290813800A0410D12425A40822CB926C024302D1027291382421314654182E11996D24118408878060B40C02152C1B2331D2A0501B080D002929DB16000040109942624B88701287615A368E0BA0718C080A61380522346564264004242DD3424911154E11A84C03923040C030C42049CC902D0947011A0349109080124910110948194260C2C24121A50D20858089A4891B3402194930CC902951B88100B640E1104012B36821116ED4366890A421A04651042001C18665C040802116610280409C0821E02044193311842081D3288823438A14B90144C640D8A82122858C94B66913444A1911721B232EC042464336490881695B4050DB164AA28850CCB48812072D09B731A3B084E0C22914B82C59488E0A3801DBB82C19166D08A28D08B668532252122632D1B4800A408CC43251024760A08010910028499845491486D4B050008544DB8888C8420C83B46C22C16014413100C90424296DA0020218384D5A2250304FAA14081992194671A66FA05EFB40A6AE3511B1B259FC17FD2F928978BE51A64EB05E5DDB644C47F9CBEB76168F5CB9E54DD51F898D296E6AF042D12F59BF6FED3069EA304F979C28AF642EDF92518D765FCB5F34FC8354803FCCAE0651AF15779E7CC672DA376509430F14C659ADE2BC8075B0056DC26A74B3C90F9E772447E134269210EA86D1387FA10CA354C03437F9DF2A77962709CBE8770CE88279C88EBCF0349C0BFB121E018D1F46AAABBDF2DF379171F7526A295C65FED8A1280FDA9EA8F5D4998EE93AADBBD76FB16F5CE48E7CAEF9C41C19CBEB3880CF6EEACC849E46A752A23C646BA788554BCD3D218A76D88A01B991AD57178B24D724D0CE12F3A70ECBEBB531206D81CC2DD8265D673DC6C5B492AA576E1027F7AA88FFE6420651CC96536103CDA90607B38B8A840A963C5FAAAC63A8CC58CA57EBF204E80A6770A39F7A8E094ED5BC4DDB86A31120F7A968F23C1E151D2479631E6A9D011671F664A59D9BB1A0192115DFD813B0CDD61BAB1B6F7660F680971C4B55DA6EB791774C64DCBC8B8F0FBB3C57618E29DF5DE4023A7D9B6CF678CBD0107B62F5A05C131F5672B5693C23CC4DB4054B92DB2B3CFB59AE81328A6F265C49A302D92A8A4BDD8C8A832758FBCD76940E85566531A946D2027EE7865F23B06A51E80EAB7777DEEF62B1CCF6E7FA3ECA6CA495C88357FB45894578D6BAFEDBE6B0F6A8AB672CD13AADD9006101C9E98738819073393C11A383DEF2A4884B8136253D3383E4FC13A9D90483DE15D4DD12D85F3A03769FB77F23CBEA1DFE0AA49843578C032D881320C6DD3091D82D106FD26C54EF7D21F539EFD3BFA928FA8D6C74351BAB5FD6DE02CB02EF09848BBEBE76D2F4FDB2A484A7CF0C6A2484BE8F56EA052A1E02F4D7D19B0020BBF3958455E2960D4A7EC5B7C3BD93AE5F716D7976CA10E4E442762E7070920C9CA2E767FA613FDE222A1C42E135165BE4852EFFA36EC20DEA6609ECBA9D57EB47DC8738A24753AB72657F4B61A2317D7FFFB55F395094C12CDE5786E13F565AEF078B62A1B19BC4DB01FD4C4806CAFF88B4FBA065230A6028F03507B99611B5A9888D64EA6EC5EA6757FFDADC5F3F0538D7C34E5A69DD305B96CD03A1904E9320E28BD71FAD85C99ACBB30527DAA2926E88ADE20CC255EFA7F4597746DBF433EBCCB94C7A27552B7075D7574EF0B9C3F7CC932AE97F827CA09E8F4F109D9D48D70D39F10F1334CD583EF43012FAB8D325BBACA1AC63D0672E41D300CEFBE29C30DFFD952F5C70CF9FA0E2FB1F954499A7412A0ED2E5F3C9373C2EF3C2774A72A3D649356979EAB8E70483305F1CDDF9B5ABC0FE0739EF3487D3FDBCF3CCCC0FE4D6E30001278973577EA567227CF6E86116E796120DD561C56CEE924F330BCBFE336793D45B310B4ECF4D59B7BD35BDF0EBC9693BE646D6E6FF663E87F32CAC11E2BCA4DE5915EFC42FB1B390B1092F703894A795A2982999F0FFC55F1958FDBCDEF309DB3869307A72434CBBF0F8EAE903301B9B62A7785754E10C7F352D886DDD1AD381B1D7C4194A413B887688A6E800B36A75CE4E2ECDB587C99CC7C1D62D69D82E0569D5ACB77F8EE771C170C1377C56EB297BB7B8511C15ECFAD5E30EF7BA659B7EF754FC9A82CE1EC7186E251D7B2CD49909DE53CC4032270B2E8B8779E6392949F83D9FF8B9F76F80F5C85C8D1D9B5D88BB4F1107AAD0E6AD1BF75AAAE13E666691FBE698CEEFBDBA8888EDFB6E918CD3AA718C6A40316C8BEE208DA05C16920182618C0431237E7BC6AEFFF8A003DF6254290488D91FCF027DBB45FC2C6EC752C9DDD9435D8C343C1052A5DCA889C8B7B5705DCFFB21A421ECC2346798883D4A38594228184B85231113B94476472E972D8E1E41B224BB1BC50DC9ADE64CA386D2E2E86EA39F164519EF36558AB08E12CE2100020E325F6EFEB62D6154C2D95EE780254C8B4FA85D02DDDD85572A9E498363C4B59AF5F65D307B6E85A91ED3F1319F5E36FDAA20B31B6DD07A7E32FA65FDCBA46BC573AE8720E728BD15B1046BAAE89FA243208F51EEA38A627DB10D086E69F4D41522C42AEB53E5C71CD10D683A362D155193D998CF296D404DFEE6BE9315D329980FD414293292F9CE857321EC51DC255F47D55594C378B7D200CCB47DC13A21962C51799806AFA87988FBAB95B1CD2DB023B6B3FE148F600D927A7F4F3701632A784532661DDB474C682C670844CB96EC569BF96187B62A869644E17393B5F52998689F41D562FD4F1DD4847566C9683D5B1E6EAD5495B94709F11E393B758D63CF05DF6A041168D153044E4F24D49210D1092C3914C4B61E410359F7311E80D79DC9169209B7201A759B50C956534E5147873ECF46812032CC5EC50D58218E92C2B4466DDB89EF5FC7795D2B6A85D159E3F5BD1A2758DA5D4F9046F50FA96A43FDF09A6883C29821DBD5BE66FBFEFEF1D667996DB4594967A1C786C03CF85B130C89946F85CD156CFF490883120A9CBA6E64C2F9279EFB006FDFFAE654D6C289364184DE60B6F2424F3D473597D2987BED78FE47220BB72A8D81D8BCC850C4DF510CABCC0CF1937D1D39768E9E21D645C356FA2D16D16987FB18C14B8D24D5D5EAC9068719B38D418CBF64774FB15F32C473BADAB5218159F6BDA323A209C699B8EF093F34B60F022009F09B2E8AEFA824178C5F8DA0E49125170D47AEFCC010837623394B396356B053405784F232DB4A6ABA2B94D821D2CE665DBE354C8F69F632551F6DC897607398A32A5B9120A044B79F7FE2776C8EB3D3CE28A13D654E58F45E5508995576F3EE3896859DB85ECFA2E1AFA06B7B455BE1048D4214F87D82C0758484230A76C27241661C08F024C2D9EE1168A8D4AE74F297DA8EA70B21A0CB8CE6CF0441A937B2F844F4E61F1AA566929972DA86FAAC9986E08578BC29C4DEAF9327BE415DB29926300C1FF3D63A4AE745275BE7F3857C2C83CFD209C4ADE1EA3215FFF40BA37E9DD31E919CF1988A5028FDFB0BB42A4C0E5CE1AE608C92E2049954DF006182932415BD872F067930FDF8ECC7AFAAB7F96429A0B516AC86B6624FFA59FB11000E804DFE0803BC3C33E77CEAD6E4C87A7BC9A9DBED7ADBC60D14A17E6369E391585EC51297D1BA15A3521B7A84E09268EF44FD7072778963E6AFEB58C07843A63514F43FA56DD7B130A991DB5412B32BC3950EF4B4BFD99D72D119B5C75C1BD676D3BE15D3AF8CED24B0401D25CDE43C259B93A4298D556FD5896971595C6139960F94DCE6B0CDC00AD70DE34EBC6CBCFAF97FEA0692F8FD154E69C3D84E0D41F4D834602AF91033F7995B599A33B1142C81C71D4C2D27407A353B91AF878303B4779F38F9E679EDF5F8FA13318B899E443B398BAB9DBC14922CAD6633CE263C5AED77848359D60E8D1B96E605BBF8164488F9071268D69FE47C0B6C26963CB56541B8F15709D49EEC66B44D638B5628D075F2385ECEA51C9FA43D1D9A51A4FD9DE4E6A8A2B2F68A09293CD1D7F52FAAE9D6D0BC87034ACF0014CE0543A2C2003F07130BFA9C0B29C7974D6C9BBC45A7995BAA62A780F7A1A168720A12509F1876F641612E70688A6E4B4C87666EAC6C838528FB409D808B36AADFC5999563B5D3AD57DC12504C0EDA94DD2F043D6E33E21D7478B298554239A9FE8361F445C2515930C1D896EE0381FC14127BB072F9FD50EAD1C6CAB24E7F8A493D92B63D30E5048BD8878A27598A51E294244BFC8C33D5C0CBC2507311438546A8D001408EBD119001D6553DBB7E78F03DAB8FC785BCD199564512A47B6F020A5E57C494F7EB73F76498ECE66C799DF38ABD4DB146C988E1C0A3FD6055AD305CFAC490E18AA791243B7A92AD3B1D8CC314871094E9111583157BF9F02BB1823B0EF0341F4A11EF810CDC887FED3705F9DC0DC24FBADB842B5509D6324D468EB9255BB0015CEF339FD2C649684F8CFCEFB90FA3E8212331E22D976FDDB86359077684DC3398D81C139A8FEFA2808FC74B7C0A56439FC9DD2567D9FDC273781C9CAD88ADC6CBD707E97DB4B989CAA4E3DB3A2CD7E419E2939041410DAB36621DCF04FA9DE5D8AA38450C44ED40CCCDE3358D770ED5C358523CB2B667986D11CCBF1F6975C8BD7BEFA496BC9670C205E725DFB4F3F28A54790740D7D56CF20282795AC1FB768E9937547306334B37CCCDA4CF158B5CA0DE2EBD75D9E40D6B664B9EFF37E943BE1E7215A70C0EB3BEE3DC576C8196EB71D97DD62F58AD25C02FFA64270F63EF90581A736BB9FE4AF4334090E471B2FBCC38ED35D8F430764A4113B736E22AF6B7AD1489F1EF2C8BC52F8D4F0A2D06CFB9412DBDF67715CCA91B3877E9681B7209178D06FCF3130067B02ABC7F9DD59A65668E259B1DB1BF68C2CBACF5B36B3645D83B4A76743C33181D93C93926CD6AE28EB4A09B1DB597BC4A9E394650104F7974AC21147900E038EA8B41BB2ABF78290B0475FD8BC6948B24B5803B0F35BB76CDC9F432D5B82A251CB185653FCF87DC68FD9EB9D1C7F84338766D8230B0CB50061702D057E308D00C3A31EBD9561BEDECF00288E3B5CF7A01CEB999F3AAEB33FFA551F3917AD20AD24BC3E54C728EEC590F8EA355D00E1A54FAE5FABF85311915644469FB3ACC0AC1DC843F6F84FB0BEC6FF513F3F1D286996AD82ED9AD86BD51A28E447196BC9B05CDFB004BF2AA19425FFF47" + }, + { + "tcId": 72, + "deferred": false, + "seed": "7B4BB05212C7AEB83E3C04F8C9FFDE0526EC4E22E29EA84260A89292AF1E4DE4", + "pk": "8909FE1147B96BB2A75C0A0A84719553B7C4D0CCB7912B824EE84F4FF444333644454CCF3B324CB3CB63B33BB9993989DECCC7E365DC5BA6BFB2CA61B49BE2AE657A20053EECE5F192374812B2DFB718D6DC45B46336AA5A230D6D30ADD86039FFA5B1E84AC2C0448E6BE453992287DD29E478EB0256552CDF84AEEEFDDB281138DE2047CCDA934FA337A9EB9D2F257D554C9E8163593302DFF2B21ABF8B7FBC319D3DB37B8A2E372235EB43A865661858A61B679F3FF11E6A03DDB1DF3FAECA1C4098686298E1070A1A5944D7BE4663312C7459DAD3F214370DD2B56F12FFE8AEEC8EE26E6E993D8341ADD70313D5E6010A771684CC81CCAF37D7A7A5FBA2CEEBD6B0F80D2A4AF55164B4188A5273CACC9053555413D8741B405D21D0601805E69300546AA837F968802C2CC2AA8CF4F0340B82001FA5BA71958FA5BEEC7A94AE095F02FC54758D2AB1401B78DC1E10910C97C5DD6F0D3076B5A09AF8A9724240A263DD2D54C16C4733551D9C70D89948B58E99C8BCCB03BB0C3CB5422169608FC8ED9FFF0E66D2109A024218D168D0952723699D3A42C082A2DDA76DDD835818C627B57A972AA51B1DC268F7181BD112AC73E436EFFEA1616794815CB1A37D6EADB92A1009F84A508E16EF9080D76DB153B6852F874EAA47DE5C338ABC83CFF5F2A99648A82C44CDFA1A50B11B3C9FBFC1CE38EB770A3531ECAF373C0F437C9941E7D0EB0D042F1EFC0B55F8EC97C785EA3B153505BAE1B52D97DB48F2D2E7D7E70E934F2C0F9943E3F9869DCCEEBFF0CEE6D1DEF7E4DD610A0835728BAC3C827B8FB92208F5B9DE25E43D93A6EAC1887F032AF66CBB5ACF6142C11DAC310F2EEEBD7FA25CB0C0F8F940E19D43AD7F5270A26365A01FF200027E173D566B5E77D98FFC1134F0628D241EF306EF8364120FBEC93F92E06058B2BD70ADECBDB9AC63EE0BF8A45F52CD80D753620D7089D6CC313FA5A759EA6BAF840271374BA5230487A928535F47843D3BAFCF39424E62693BE9712332D312B831019F8AF6F68FE5D0088DC979C9B3995ADD0B607C399CF0B8F651A057A96ED323A7EB597B51AF3AFCB9B99420456244D436E81A01B4F2ECE5B87D63EC7FE6B505FC34CA5D7373B204124AB9ADE3B290EAFE5AA73704902A2E3A404F71BCBA92F0675AFD825F10A10B4D51DA642ED0A9667C2A16CAA2BC77CAB7AE9E20D114DA7FFAF501D3D1783A58029877A86C8EECABD2E18D6CA58AD5F0961A1CBFD8A51BDB49EC3FE4EE5E796132E5671701305A650F75B4A8BABE4803C5727332D1B123508A60FD6D1961B267B4E4A418F4D1F2D95581280693AD13882433DC685B8D60C78414EDBD6A5946D571FE2D897B094C77FB5FCA27A9FEE9B6215886776F3843F681BA3A69453835BD4919D870AD573E19808C55A77642681189BAB4B2652F52FD6894F70FE1B63F31EDF0A1D3E805FF4AD806DD627504870EF04C1365B1CAEEA148A3193252927C8011A3976E5254815035132D7EEE8F3010C8DB2486336365CB7850D4E608E68974ECCA90000EA4EA4D146571D2720F79BE23C538161E5B558FF5FA40E63728B2279B1EE255D8EE65E2CC373285043CBAD5BD7A9BE42F6C282FDECE15C6CC49BBFD29E38F40993F8A17456DD3145FB717AB10353DEC3236F3F44FC80F853943B57AA08E8C543C35276D637D07F59CF67CD4453828542CBD0CCC0CA7A2CCFBD0276E70C119C37F9118962F0298AEB4663C9A1106234B4C55FF6517E775B275788263E24FE6AAEEE46E5D082C5336EED7A75ED3293BB670B49E705AB5E9EA0EE336EC8882E7FB1376B18EA60400BC9F66C112802859C8AC80C33B1309B829DA0D4C558D4D44449C02537593B456E842CAE22D546CA071A1E7D141D7808C1984E9FE431C62F259957469DADA36DF63D0E5C9BAE0620F09B2A3181CB08BB0E0BF4E6CCD34E8DB992DD8499A2AF80027FC34ADBA843F7AECC46D4D4FFC025A55B6188CD8E24496AB28F94896BD8049DB9EB991AAFCAB2EEFB31151724A19C7587773E3BA238137AF041139F0428892D255E361D375BD5FB318C4A39F524CBAE368033CB88B616DDC4B2C61A5BCBCE68F7719FDAD95655E759513CA1E6AF4D92AA96EB15E9080DBFB4CBC50399717B5EAE40E6927D574A8144B24D721CD2D1633BB276335846E2E86B2E6C843EC53A779B7A1E9CF5D94B710E824B321BA89C502D03BFA73B6B76BE8E330BF90EBC6059004F9BC8F2656F0CDA2B3B2018319B70E0024AB7E1095C22DB13F49E42DD3D9AC800D7307CEB9517567E0A4668BF4A0CACFBF1DD9C1C86D13721A026E2F4B290173B05F60093042A1B081A94A830E028B2AF8A31BB7FF432758F54B63B34E49BA2F15A7DA3638BA0F5BDBB2527BF49B2284D51DEEE54FAD5244CB85DE2AB6FD689339E6F89A20F803093E0D4D186EB60B5D8E92DED4A8A095066997943A3A419589965EA3661191FD10DD3F6F068459AC38C44598C09B4BE609174EFA39768439EB72773CEDEE9C433DF521CD530C26C08075A13FECB913A70C658AA12E065565EB15B6BE0BB52A57C5E4996BEFB524845147F836A492C46D95A8041FB6197BCD33FA9CD1C70EA3CE12ACFA92F31876DFE3CA83BF500A47CB4CD9DAF60F411603BC7A218BD0B8502D25B66039737C3B82C7F5B4FFD12FE8DFBEA60559A0317CD489FC63086A8DEC42CE55F282C264CCE3F52EA88C6DC173D8507AFD1B99350F89BC59FCAC65AB8EB136F67CDCDD0559A8E8F6E919F827C393C70A6D010F19362A3EB88FF30BC48EE9791386B5833018703C36886D0A943E8699CF2072037507DCD197E072F356C2839ABE1DB04DF7CAE9ACF98029231BCF574CAECCB78F65BB8FBC7F3C88CDC1F3E256850BBC89722CE402E424D7D0D3268B4628E93220129B715A962F3D72B08FA532EC208FDA8273BA045820B3DE9E76EE42968E8A386DE4082AC71E5F18724D7EEF285EBE1A39F6FBBD923C589840B20C07FC2E0C56DB3B521471588F8F499A71DA654ECACA5289901E02337F0E93E230621340D1F86F1DE12883C356AAC5E68131763413886DC46C754E163F53DF1164F3C266B6D468179FCC130AC5331D997CF82277AE746A9276788520073F7DB46F13877215B7DC9423452CE9E815D836C6CC0F04DE3DDB088ABA39F8F2CED319111DDED7FFFD95CB1A1081E25CA2ACF3FBB7E80BAA8B12148E1E6911351BDEB116D0AD319670ADB8E51C7D533E1CC899C47A809368B94A841D0B21A5FBFB5868654658CF6C0AB08D7069320E864DBB8DCB9057BCA35DB465E21E474CDB26833C8BC10B0B2279B8F73DE7449ABD2A7EB34DC01D30D5DFFCB9B3FE320F500734534A3BB22B4FFA1A309462ACA7F4DEA20E112A50F5FCF222B85139D908AC13F0E8C66353269344A344043ADDD5B78D25172B02E11673457547DFD6D4FCE567E52D2341D837B384087357950914441AB621C7F1865D26DAFBC209C90FD4390B87D9046FDF5BB44E98414383306504F0FF35687B2CBB29DE04E7E191AE48FDD50E74B83C7590ED2270BDDD7FA9A6E12E28F4A5286AE07D7AE1DFBADFA9127C7665902098BC3CBF12AC9F3F826EC48C9A22AE3E76D8596A1E98BB6342211B4EA25DBB92F274B542B01DFD20A6E96A69ADC103D951C72AD75A32DFCC55", + "sk": "8909FE1147B96BB2A75C0A0A84719553B7C4D0CCB7912B824EE84F4FF444333601E8A88ECD7C376304233D07CB229E18A0F8F5242BAD485115B0D4FE59F52EC045E19C137A08767D4F88F17884897464E9BA4CAEEBB414FB0761690875C322A3E134C4E894BBFDF177CA6C3B36A364B9FDF0AD02C9775A612EE58D32CEADA1E31C036440A83119042A89B0644A180C203069C046840892092148124C1009111608512266E3B88C00C5096014044C328989021291440104B2210B040E0B9390D0B64521888908A72D110821D2B448A214696446469A222154300C59A04400B64550126A004446DCA42C08A825CA40821B0869A30484C0363118998823C308A43206D104115A2420A1B840D48680544406E4462213B584641230CAB244C9301098929100860801267294904CD1923001896083445049842DCCA62CC02649E0106D62A200D490651C9471CC980C08155044A68C08B38D98C4295B208A1C9060DCA2251219621AB851E3C29114B90052A0255A4291A0423061A62400B96958A000209224E4008811886C12366C1C411203822421C98549C06864B004631826D2062C53C668D84000D2484492A46912970861128A5200055AA2001390811B036959486E5B940DE0044A94487112369123A4449AC465C8228E50008D8A440C514625D2262EC384255910329AA8110099890B073141186DDC002AC4C0901120321184804C382152160D10954942400E52B4400B290A60C60113028DC81692D8B624414830D9040D80982CE1981010B46D104800532800E1148209100692104C4204290B401114B628CCA28591A6295C424003436901B3605C404698C401D1489082B248018545013802C4C0304AB2045B386104292541426221356160B84904338921400880148421020A8B220199C64D08936D5A9668C1241104170A03C404E132811B2842C1B24C20350900428812B9115802299320711A469291140C1940459B060C4BC61109B38111B22942324111322C4C288903130A01C10C12C72141A06D22112A4C94906396505196700C12410CC06548A60C9C164053C45004110DD0881161280A113702D9A06C20C22C90C290612028591040943842604432083292023585D202020C4271E00642A01284E2946040040998480A09B36914094100278D02164D4A42908006884A220A22228D441250594484030382A2364E43247119988104834D11C19064306C8A8451D44030C24470209069C0382DC1304C60207193320E24848101388D92244AC2108E94B42580A82C543860E31204DCB644A48605643489CBA021D1226CA0202644127019A900903432DC4866DC224C492666D0060414384CA04040543805D9B090A21862221984E2300541149224222ED8128E0B304D1C816C999221898601CB48891A934CE0964162C645033484242891520806E3301001850108A064138911991251D1363019094610B8710B4465CAC04818C2301CB4702407898AB608A0126080408A49860418228E1C1001E2124CC8B40C1A8509E23628983809C0C47152968123940C10484E8C060A01222250486422476DCBB40D8A460D5B400200952960482560A6010CA56041406053284E8018651C496851948852C268A2B281228411D2C07011114D1C153004C141C8302C01B629232231CB283291324A13A9504AA4218A068D839064123528D8346522024648109000407298841194847042028DC2C8200C006DC3288D4C4062484601A3B06D08B5881829261AC1848C362660244208062024C3215A366CD2220C2229220918728940288B0891E4282ED1268D99A6718196691B986952128C4438208124294386815CA84C112824D93629CA802183C06C21004A20174613830050A608023026E2344800A48901388201A96C0B1409C3281101236E19312C5A46058A2068DB98901BC489DAA4005C2206889441A206659806901C10629A26481C2820D2228819400C19086C639664DBB05114426AD3248DA0462941382D829690A23661A3002DE40672DB082E410885D408691C26220B2342D81489A222869BC8289BA470043129A0B829E4947052966D0299654422291249510BC824E3A881C84492D996815096308C164CC116421AA61198A2444BA000A0C6904BC02DC23405A0108D20206521424EDB14440100481CA70461062623B1845B866110816188B228113484020671A426690CB7CE0406096708570A60CA36F9EC4F06EE56DC910BC6A50F8396656C7E0E92BA130C46B7C0A0E6C93545004D161412A9C88AE285DA2D9C60803900F24C95368B9456608065D9742A1BF2AA1A55A4DA1395A8FA4A17CA371A289AD8D096ABB7C376193D5BF84D5F88B131EE9377B11A77996BF37B8914DDB60AFE56846D386903026BCF2E196094B3D1856888CAFB2971FBA819C13D9FE079F9F2E02865B99F95BE311CD9DC448E51BB106C263725CA163F92A4CE0293CBDC12DEA0E49FF5244432A2D0996C2C35DA3355CFB2C6EB81E346D78DF235C64FA911F1157B6C4F0FF2EBA91D047E7FDB9908D7846E17FD1330CA271C0EBBDA6897B6A49E13DC9BE2E9115C8F3AA1802C5A6EE67CAAE5ECD8FFADFB9D126BD16AC7FA6AE5E9E2757177C1FCAD8B98EACAD20C5D7C7D9760F1624F227F35FE8B0EA0ABCC09A27BD0C98DEF908EA7EA19215E99DEE4BB71F94C1DD9EEE76137B88B2B9B331BE4ADFC417B57124DADC6BB25FDF6DA925C0B1E38A54D06AA317F9FE9C9475F79CE2293FB6AD9A1FB5DE2A0DE7F83A82657321A85DEFF62D533C05268EE059DFF288D9A2F600242D5C54D154646C005EF65D927D2B76BE7A8413CE0B818EF5558B204C18B734C6ECB75CC164B2E3787487FC1BE72CE3D6C5161B769EF8245131612B735F1FD87CDF915E365D56FF3F124AF6A565FCF3CA82B64C25AAFE3864AFE380E9FD2245331C1B59A4D62D3820BB441CDEE09E938FBED8CEEB13D2B54AD7C4FF1C9889A18BDF8842535F2837B011F9CF7253919A64F153AA00B44B343949FC8829E855E76980A357993A73EFC718A04DD59B5E062DDB30013868CA4AD30CE8F24912A7DCD2D6CA69394C229C6E09A2279F2329CEA517C1575CA61BBBCA6CFC3C4F926DC9A0923DC859A8C01FA4B1BB60C5C6BF384ACCBF366A877E91EC85A20967586FADFA542BBF0AFDBC65BD34B84E3D65DAF38B3DF497E8FBD03369EEC861575C2E4144B36CD77E23F1BDA693D45FE1C201EA08A3CB4C3517F85D24170D7AE3D2172B9175BA3A38194AAD0A82C32426B6A306906CED1BAA59C48F26F5C1D1979C47A5B495DA33FA4A359657DF97052EF48E39095FB59D7040833D67A0DF9EBC02872E905D6A6277224426D47B409674819181993C7207DA14A11DD151E4855D3C8F310D13019C60B6A1F1DAF1DC3D2E60E0BEA448D2A2C9A6E7BAECA8CAFAFC7484246C036238BF6FE2C5F817DEBA88DF00D10CCEED9EB4898A2C61616C073D5812C3C0ABC9BF0BFB9C7B7D4C8C1D13CB2224EA32071DDABBFFDE25117EF6058826CCEE53BBF25AE65FA181E60A8F9E41D0BCD99F21B5F3384A9644A6DF25BED6DA8087A29FF72C84D25B674BE4BF291DDE146DEE6AB46329CE70D2EDC8A39DE7C6263BCA03D8E09C3F7393D7ED7F4DCE3D44E867CA09E18ADE556047F72527AAE88FC99E2E02C0225075C88BEBB810210BE7CFE43921F1A509FDD72F7933F30B42607CCD44DA422863B77CB5049E466D49476644F0A26B8BEE0C30CA43AD756CC00EFB6A1A151C383C8213096A5F4695857F14777F9CFE6F4E425ED61CA6453A21CB0C9C4C3CFBE235703F6BFD3690437FDA24C030E0B0819836C08693E3FD605A2C1E1DBDA347B6CF30223C8499B5FF08793F7646610E7B683E4A9CC010AE1AD954DFEDF9FA0EEEE26BA0F24C2B88AA18A89C1441833AAD4FC205CC5D8410CDDC6D8E518E6FAB1CABEF217023E90F5383CA8F6C6EF373C907285553D4E39E268829E609D9324B393C7957CB832063863C9AB5BCF950C50B97A54CA45752126809DC9D65B889D1E0CD4CD5EDDC694EDE7BAE2374E9C695774CBB58167D870948D5F5EC047447852C44D21F66C1D289E9AA2AE3C06CAA69F35A5D5786BCC97F2934B88430F3D5E8B5091AE0EBAF0D3CF80BC4CCD15481D5C6B1FD0F3818E48525E2F9522B4163109B34C69F09860510875BAC0ED9CD0F38183CA9127CF3F5FBAF8913A2F0A4362B87896461686E43CA2DA5D58F12D44A964EF6DB0EAC5045448CF01923E30A49526439416E6471FBEB884B2B4A02F351CD6C5D9169DA9A19D7C08DF49F797F0BF8942B0DE603A72461B9A67F96F62C5024F644CEC1AE847AD75D6291F4B1B5272A38F89DA7B9B2FB44D77598CF959AD4E77FCAB290F2EC7E62A075850E1723BC1F78AF44F4F5F540419302924D27B20882A46010655C20EA9986375203E85BE0B7BDFBA844CF99448AEA3CCE916F3A8E77AA9DE340099AD924DFEC0F38F1AE9973F82CE58258AB7770BF850ACDC66F71B5F32FB159DDA18C31AE388339A74F59220069F4471C9FD55DFE359E2A6FF3EB874AE2E10288964914CA12179A4950AF63B7316DDA6C695C7050E0AA024D8074AB01C94CF663C45B69DCA8C469F0CE7764444008CBF0E8B6A0EFFC44DE1B6EDDB9E765F4E63DB6148E17A5D196F9B373ABE858D05E14BB282052B4EC190171D5220FC27DF1442BCD7F2AE89C06A9D2071297B42ACEEB9C29F386018009BBEAE7494254013DC1A7454D40720ADF575E2A4EC7719DEC804323818AFE5D24C76FEB187135BD4724E6F18A7474B873B4B4C2CF9593C0F2E27DCC68E4A993FD0ABBDF518F5B97BF1139CAEF1043BD3C7D9179EC1B6DE98DAA2BA247F2AE49D24CA571B6ED66B22CD07C126ECB37B24FF8CD5FA4CE282E482947E0A2988FEE08DD0EB3580DD21FD3D88D1D259C8CFE6F52AF9A1119662CCC750E21FA393A6BE619BB537D216F8448A473136303FB5007551A20273CDC07E058E02A643AB374538CDD5D62E86D7262AF04C2063C7836790910BD7752D4CA7A848B9AC4422D04A4A3F018785EA171A637BB55E7F63B9A4AB7B1FA038F09862D073CDF9DE0C1F1DC6CD644577F5DCCB31D160157BAD4BE7A0410966E98E845F1D8A8D36006C24056E076C2F46169DADA9E928C84277EAFF6CEE3B438E84427C4C95EEB264DE7E2E6C3BFCD5566C5F396FDFDA3E9E2405FBE3ADDCA4B4B4380150355AD3B42BDCE65FA1EE23C576BB4A4BAD816D54184C78F7273CF0227C79FE21CD4FA43E59F3BA5B73DB40E9568C852DDB9A431F788B7C402E7FDDF503858623B0E24024DE4A9D44852B16BA3F4008532E0030ADD805C896AED954858F4496418F60DDD790F4C486BA722FC0772D033678F9E8B6830FF6AEB194C102D8E81FBF4E5FC562EF8226371F384C51C6ACEB930C5F1DB967E394094E9CD59AC1332F6E93714DB498DA10804CF0F549D46050E9B1BEE7DC30F1DFC135CFCF6E9BB55A00EC42587CFE32B22C865388E2015B585F77EAD9CF1CA48E9432E46353C0DFD66271760099778CA61AE954561F76EA4EF58F11287C402A08D6E47289120606E5AEC3FBF24735E9E93647D967E61460858CFE2FD3EB7B7ACE18A5E9718AA8AA412C3D04FBACC721AE4F850BABDFED7F3DF60262C91EE63783811AE302367A5F10CC08DDDB58B7FE6A8D9F5A63F0B61D1D6D8F457222D8FCB61414551224242D82F56A95C6485993258496C43D5EDE518DC9D7D055A42C10BAB46F1B626953DE1472E52AB2A891251CBA71646A342DCF1CBC51C37F0D71F81FA4824AF714E8F2900CEF663525C82ED3720CA215AD8E6F01E6E56F4A25BC969BB455245809789ABF105B536EB2723F064446C0FFCD7F537EA1EF11B4F5FB55562B1CB57860F1F2EB5AD95BCB965635E7804045CCF4668CCF3AEC958F06CB1471B78E979A5351EE9B1379404E7A51CC4F2F3DF703027FB0C0ADBF85FF977DF5F992433C14244E4928324FBF9E527E83775A34635A2D673432588EB69D35773BEF5C6683A54D6338CBA404977F6D5EAB9D2A73FB4B93ED82D04AE0BD9F8CB820363B52CEFF4AB309ED8677130339435C565059588212D81066EB6AC462E0D0F8F11872C9E25460B45AAF5191FE0657999C54021032EE672DBEDAB378039BD67D22CBEB714B6DBAE11D3794CB44931585BC5FA02A72C5C6FB3E9A4BDABD16C24F7D314BF8DDE13BC838CA81FD964F8813149F700B0BC16C41492A8C7B1EC967327DB0AD6147CF64202B9291F1BB8DB6E31736B455E75F117F531CE39CC23043906C98B8684072BEE3350A54BB899E506EBC6FA310022A52C9FA6A0B3EA7068D01AB3B805A917B4E7146C7F6AE89DCD07C4FB4E618D564C25B6D7F272731174BD541A0AA7738FF167008B781577BCD98A3E84CC81B856CFF987AD3E9D843C14D72DC8320445031045CF9D25993C1F179764FC7102208BEE6ABB9F9A332A7A7DE13379A81D030FCAD6EFD94801FA480E5524EDE34524899FD40A4C02AD85F3DF4C7F68E6B7A66E1FD77C1B9AE0842AC3AFAA9430C57A3372072D6EBEF890CCB4987278E3AB9FA11D5EF0914B949CBA37D3F55735C550F56D1D3BF96B1C590137A91AAF14CB520794B63FF597A311790C9A0E704F836A5F89BECE8CE2B895C0E2647D5D4D2665F2AC7C95622F8B3B3E2143E81278070F18ADAF9B1ACB86A42DFFB6989856178B58CF65044905F57D58D21F1E282EDAA5F6472E62952AEE2E9E6A7526C26AF1D2E1CD05F5CB8AD57D9A2662A91F97BCEE97E43464A28B5359F66FF6880FEBC1512C66B289B318804899D517B4D2C6F224618324C940DFAB6601394141E4F66D5994FF5A5F71EDE3D6914FE8E435CAA500E809F258ED7A7029867DB1A364A8649346CC3D9CEC31B2A1CB3A2918FE6349856E037DE1EC177C168655D" + }, + { + "tcId": 73, + "deferred": false, + "seed": "31F5D7AB44ACD0072423A8E486EFF6D8E2EC8D9D25040D6209BE64FDD03A7664", + "pk": "C2008A4A1E8DFB167CB02028CB14384D00D006C3F495B89610105953FAD3E77543D2FF7D1B317F28D621ED31ADAAB6CF0443BCD8A32406E82FB4FEF87F8977878C27B6812FBAEB5D135333C20C8EA95BE99F8BE1153AAFDEA8578534DEA61D60644B8B94CAD58C78D4036581A2C3B64172B0F8D22F56EF6A7B8682B062D3D98299342781880AE568EEC5D0F30B9959FF26947FC040EB8A3C6688E33EAA162954422477DF6405361B3FC8A7B39A120972F78859B879F2C80EA81C97D048F8FED5A64114855FA72BCE11D1DADA55BC65DE976316A39B399581C5D55CC06A178ECC954F4D9D723668A9EF6416BCC88A9A215487F17A48BDF6A6763A7FF8B447E87C22D009FCB5F935D66B3F5BC2C1DFB4BF32906F12D3F82C7325CF3F53CB0E73BEF4F8919181C532E75BAEDCCD929B59119451564AA0EDD61C373D4C41AC14E739CAFD09F3AFDB8B50A8F9E4E27EAB64915725B199A32D94E573E6C9E85E1A05B06102C852564906376B1F9732D059FEB25F7A3DB4A0CA596FD49BD6F75B45AEC689207374AF4CEB82C3EF86A4F797661AB631857A902ADD3847C222D6F1B3D49B0043F0F34BEDF97F2E1984237DD115F34215FF1786941BBC42A5A80BD506D4392649C790A0FE68DF5FA9047501731BC408349D6459DA55BFAF10031D71B535D1A385BAC31B7033E315A7B4BA614A27F16FC375EB1A63A96E1C584D0710693C1442AD503C63062918F736FB8A32C68B475E46B4D27449B074150BD0B98F76A87F313F5A9F329DF1CDD180B28F5D94B100A438AA7EE4E46061C02F3B427F4D30ACE7BFB6CE65977F56F30154F2A2E489FE19F866F2BF70FC6CA1D54211398690BF62EC4C21B39C8BF13C654F596778514108D9D0EC8C90111C1A771288BE97D8099E893611B3F8820B5E169C4584246F7878288DF4FA658401ED2696CB1B69F69F3DA8C4CEACD56D33F405497CF9BA898E734F4FCF5CE5165847149E3963145859A9F9E49572A9227526921074737D444C9D56939BC22C00DDFF53007275BE52B4D3053AAA5E2B702ADB635BCAF0187C9143CD88DDC3F684E6313F840DFD666110D63B49BF1E56301C65E6DD242FC66C1FB8CE3F7C7D102FED86D50753D16D382900E6EF46EAE83A5C37C4B1B966777C6536E97EC39D74B4A1F66FE0063D41374498B1910E288C711C037306DEC815C1B3D33B28A6A151D9E7B04E08EA7DB2F829265B952CF705755CF56E9C0E38CF41DA796A621CD50048E05B2EA9903C3DBBB450CEC0EF28CD2C11831F09098001AC2AA565EDD47FAE33E3FB9456A0E5A1CA83D236B6E135C18A61BF0F90C632156B9E1579C56EEFDC8215B95052E10FA03A7DA37C2FAEB811C1003C3F475040A377C738EF8CD80E9BD2800067ACD32FBBCF14AF95EE119939BE55B9F6EF6239C173480EFA5E2BA4E10EAD1F7047EC2F342D853AAEFAA3DEA9FA6625ACF6BDE1AE1CF72421F44661083707D056298FE9399132EF319E76B2FE7D0307AB499E3CD42C472CB427B734D736C20C231DDB7F80F7232B42D72603B137B849A994BB1117AFEECEA2DF31C53B3AC7D7E060051DB3D92FC7D9C1DC173BBD1E7082D8F81BAAB54C6F96443926ADA027F9404ECF8FEDC79C214C766E441162C67BE2F15988B2B7E809B5D68173BF3CBC70E8E1959BCF3B876BBA0A7207A519C484AB07F4570F2491AE1B7E3C5E7D195887E977697FBE4807478CD5A0D181BEFC4DB81CC63FE2F1C5FC89A14F5FD48318A00EFFDB68F7779237440DCA768FCA85FEF5EF463B34AD1F7FD1363FD79CD0D1D6432D2EBAE0629D8B815D8DACA9118A12736E552BA8454F7FAEC4695AE475E5A31368E8417CC498C90FA7F23F5C230A43392A524CA5085ABFCA331553DEC1B311EF3D2F1D29D663260B06644496E1E47424EDB6E9F889DD58822131E2EC79DC037833F0DF0E65F1238B60347F9162DA336770567F4C7DC2DD06AFFA10678267A1EA2991E4506B7BF37D854480BEC70ED1D4997B351A56538632920A99D42FF569E1F474DD178E850F15D20E2BDF33355901B27354CD95D826BF2C21A624193B41D9FEEDCABC16514C4BA02B7E3A393D5AF73C8E012CE98FE6DA264976671A7B42E7A44D56F60AA010750BCD571442E02212A10E2CBF9A65AC8867D67C2382C474014D43A816E89148C8F43292F42D9BF36D5ABCDB4A33B70ED528F533E3296C2E8C2EC244D3BF7CACC8386672D32F81BDFC6F3DBE83530FF464160EB77B9F9FC0AE346BF5654D6495FCA822BFA30C5449F377B2B2F63B44CB8579EAEF0493EBFDF1C8E5E80AA530DCC1B998223371919E3FACC34FCF95022AC900E5F033082D7AAE215785D6A9DF921C63593F43C63E5C81DFC7CF42CCE0D805AC586375ADBDEC1064D16B1348D261C8F902BF4F0FF6C525D2AC37F384B3AB17B6159FBDA15899A2EB14C2E299B8145B2A52EB918CE77A29716CC168EA9B122607993AAFC496B28C456C64DD750A47186862DD36D8AF7F722B9E8565C5365C1F46F065861C6853D7C0CA82FA04A85B6A70C5197487509AB0904296B5E07149F33F663027DB06F7ADABDAB3994BB8A68F7BC943EF87846BF8CA68FFADD1BD50E51EE64CACA906C0BF0B39190E7ECC4745FAD9A27B06CD64F18DE7CD97DC12525ED54466C99E76E206DBD9C0B4D22F5F08F4FE0957FCC7915EDDE8F5E47EE620758977B49535FF4560F0DCE0EB0D992EE0C0DB587FB1E0CBC032C41CA5D2DF6A35CCA6D49CEF7FFF59D390F0A5EF2DC059ACD78AE65E1AF5ED672309C8AFCE6FE2F08B11F28076EB87ECACED71A6C65356AD2B6996402A69FF20713099088DB1504A43AE9725AF07A9F126433B755737B74CEB4D71EB610E5BA5C029676581B36F0C981C0D8D06C2F6B05205B29F9AF32AFBD23E00495D5FEF6E44050B01905EF2AF34B6EEFE5E17483450BAF54EF84590427FBD223A43E3CC3FD47C2AB86A4A1DCFFEE5A51B443B8C7395D31BFFF12697D1FC3B887D2CE4E2CE79C29002F11CCCD98E86501AE57B252675B1F88B8038CBAE8BF1D50EF5293FEF0B4AA790BBC92BD5D995BA7CE384236A59DC88962DB6364D9F27A20C969E6BC8AB636022E340E4C37BFC9105334DE64E745A9E606BD1B5D86277E0A4416B981BE9A77F2889F8AF7244FB8F973465858C4BF9244B306E610DB421F14971C3299C3C57D3F8B09212FA094485B6AC420DEF2E3A34AC7377CE18E03ED00CE575ED85B767D8787E098B7333F425E2336DA4FB1C78F3D4D4DE5BD4464B02488805FBC64907A45E37D0C596B88F989B5F9E5C307AB050526020003679BE079CF953CE9B7519D8C780BAC4EE8A44172BB74900E06F571ED9147C4D7F6C562A155AC6EDC157D62F4480E588250F49B7DD8B1C04A97AABE87486A0852DECD387EEB3E9837BF2035BD9F763507C9DF4DAED511A4ACB51DD47EF283DC43C64433090B89096539F5A506FB4FA53FF96E3ADBC74F582459ACDE4C9325589CC73330116B33FDFFE677B970844BD891E1B194F1F2F51F457D3E944430EFDA332A1E18DBA2C83F58989A3C491439BF5227C7EC2788663BC733FD5FE173AE87941687060D217AB5AF9FC10F119A177FBEAE000349FEF237DEF84C52FA1CAE6CF0F89639787BDEEB7528FD6514FAE29A06D347B2496AAD01CA951BA1B423C", + "sk": "C2008A4A1E8DFB167CB02028CB14384D00D006C3F495B89610105953FAD3E775A965DF6F74D379106E6393F7400957F1D5753F6C9EB1E8420D8F9AAE113830A0A153844DC529D49CFDB506F7A3E4A92A6F7B77271C17FB2942B1144CD5D82DB4B9BE60A655BDF10FA3F5ECA7F774E3B11F9676F5DEDB01B15423EE8E63BD9B1C61940551926C09477184942DA3B46999462A41C86144388E14C6115236600A366A42120A1CC8904C946142004A49204A23412019C869223028A296700C376403B911128528DC267222260E18466910B8519244850240280321020C146123258E1996209036201BA620400472DCB6654C44061B493122338E48A26558223024B88442C65063288203404650025263148209948412822551140CE31004D2B43118A40D0C0061C106011B3250D0202C58166509236AD3300C432289C38001D016080927480C83111B472520086A928820003751A4C484A09020CC4404D34232229771883849D3244042028022240848802D11A3699C284010854D04118D01C76DC0005013070554C40890064921A25120B6445188008B280DDA484DD0B2450C4190C896292145669B060651082A44A60DCAC06064883008226E5334120196518C8611213482838825D0B89121068C142205991282A42268CCA26D01130059284AE4A0041A818C143041E49669A4986C20B441CBA028CA80850B36529C001080040A94182DDC146108213100B550480292D318706302461019858B268E1B0386CB4482DA848D20249102B92C22902D9A90850B90655BC22C88C62D533861DC946C88368D208710884260A3246AE4C2289392889096211395440B0291C432060C13905924658B006C50C829012842031620A38090A22292D4148AE1C441E336620CA4088C922023A740D39284128710A106808BC8889B302ED498880B290A93820C22C1901B443190B205438891CC269244B48154A2209C82601C1480E31484211172090401C412621435216394000B2070D93226C4A24C61406221A2691C020022226ED1000812011221298EC1B80003804153364EC3C2814AA244590848DB42908020304B3681DB268113442850C224E2B84D5C104C449871E200661A877003364D102990D9184510A37194A8459A462E1C230D44304162004A62C841121169993426838449C32091DB026402302A5A148891204E5C0089C1862C1BB19004C1649B28080A985091942411939098A210D41889102766981492D8102220C20489446410148498324518C011A30629D9860188B28C60380D1A475004C0900092050084705304298C322159B8100A2045CC124E8C4831412401CC422CC03085D0C80109334CA3B08024462EA3486D59000E88440900134A58C2618CB88411B30921C72418135292164E49844C81166984C031C9C445A44420DC3641C49051233861228809C1102608094A8B14918A98290B160A82987049C83110462D93A808C28400583070E3C4292340320839800C078A14816DD3A66C41464012152E094828124609422065E4C800D32264C1986019906040488653064D00A741031022C3062C63008662920493C02C8830015C9869124161238624518028E3240EDA00250A9560208550604651830044C396510B024D4A984D89A08CD93232543208D012459B469112998C0808044CA8519436842033204C424161B461918809D9B8808A38448026449C8000092632E294000C2142C906015B986C13916849107058102E18438510190054288E54086089A23102334E21B485A4060E92320558100DDB962D2405704A0669A3B6618C32620CB7212009409CA430D2382514224E0CA1210444210C04485B108A2311641A178299002213A6651B88881931622005441AB34CCB2291D2006D202848C940899B82090AB03189828181086AE2042800262652860D9494891C22101200809830529C46800AA749E11291C808425B326C204424202980A2381118B829CB404ED2488981B2482409298390250047696244040C3929CC08001CB70C09450044906194900DC2B88CCA3628180545A4964021B961D3166D41984511066ACA144814222DE3882062222520976DDA304614006C5C828463482D24424448247022110282300DCA8280211701D230261BC2615B268424054414A84CA236441B819190B6411AB7311CA69124B5518CC40C09294914B870E348265A3024FCA93B3DA173B47E7A5AECA423DF1E771F6B210D4026CD835782F7C0502F779B4A30FF4732B447AAB972713634F2A5CCD9CAD1DACB157D0F8AD04A2FFFC043BFCF848458F964E1B8488300F2763F045F5774862315D314A8AC2DAF2A132421F0227734192BCD4AFE4756AB317CAE107B2891547B7F41C9523D5EF2CAA75ACB48A816EB7F371B5582FA1310F9A9EB6E77AC47A0B5182A5A9F8279599153D6E157D2602E65ACA3353D058AAD1FFD32B43AE51A11D309279F31AD00B6CCD1DCCF2D8B8A9C453F7DB22F9A11C45A42EB492AFDEA3E67382AB800F44BB853A26D5A15139D3B4D0F187AAA8FDDCABDFA5B53805A972788694EEC9CABC95683A97A7CABC1C724C738134B47A96BCE7202F0F319CA1D7A9D17D3695826BF15B3CA31E27047477E015C76FC99FB0182D955A04CF8F294E67431ACA9D168F4A32745A8F6BDFEE7EB35E2043048CBE1CB14632360AF375BCE61220FE6826D1903FB1AAA1E2B40E5810A74E85980A37046FF67A8EB28C7CD6B41CE833DB9373820869209603C81CCEEA03C3CD0836E3A65798B20E55949297FB2F2C613C9C584DBB783995BFEF772ED04604DFF8399FC81F1626306844026E0AC80FD6FAE2AFD470064383BD3C5C41DD6B4B8247A9DAE986979B651C927DC309B96BFE0B08B2CA1874E08E3231E55E619D68B7C7F86649B4CB6879938B8294C9FE3FFB1ED88885FAA3DFCCF3FEFBA69A804EC4B72A3E6CEF853B5CEA9014E9AFD963B18BEAD40DEF8EFA134659F4738E87BB2637AD40E9A8F330D01F4E6B34482065BFCADA0D8FEBD24ED280A65BF2B7C8D17241867DE8DF5D8A537658EDC0C568822CE6314AA61FDB322F1CD1720051ECFEE221922052D4B1329C8672C7178D00346E06AC0A192A805783DEEDA6EBA9852F071B544C9E11DA0D0C15A7DC4C14DA9CE3AF57FC20875DAC3EDE8418E8C59B935A4855D4E1B850FD2282704C35565C890FC3EC4968E0EC007DD5AC95912806804BA8F496E37F316E508A4F10842873EFB15CBC267D48830E3F22110AC751387FDB6FA2F097499AAACB155DFE928E17247F40BA4BFA362C80AB133F6DD1260A9D88A7B7284B5C9D4DB0B5792FDAB2E54400F7DEB0C40273D4FA1AE5D7D67D74ECA21BA9C463C7A7C96BADF827570B586D3592938F90C1A7BCB844B2D166651DBF7B4640C02DFF2B4FAB99741C694F0B4294CDA1035E70C46700CC9C359DB57F83635712B0D81EF964002CFF25F0DD2D57DB50D53120522D3D7969951BA053FC36FFE73BF28DF4A66D6316E5F82D97FA867635260778D797DC7AA6FC47D45ACA168F58BAEC6EA5E7D8B714D97F85C260528E4AF146478B2065F084B44A07D328BCC1C05C9475565AF74AC697E459D4B2CBF4ED533C79F04ED4ED43879F735E7D2B5EB2F9E095BDA1F12DF7A9A924B237C2DAB8B510C4D2F317C3DBF802ED7ADA23DCDEE73309D10BE5BF1AA397D1E9F3B8BCED866CAAAD95F12CB12C20590DBE96B2CFDB44F8F8FF240B2B18FC9AEC8921AA6344E08AF638F9EB8EDF4274747AD1D29041379C5D3B3695F6E4E76A747B1D8E1E4C1EB938830E35A0D7F0B9CB272DC43E0601E6A2E00BC4CCCBEA0DE00063E3493C8ED50616B00084476E1D144F7C3988D1E5DB81BDDF8474E591125E6156ADE0ADFC8E4C5D1E4061A044E419A5C4275B83E0203905B9F7FB95E979460BD478BAAAC8FA4F5F3EF043C67582C2F9FA959250B06DB851CD914A5BD3B3C89DCA914A24D694007E39E38C7BDC90798F0D2C86C6C9944095E094DF9A871190922F03ADBE4C8D2A0EB21FE4F7E461FF4CF3FE1C45779356E7E36877358136A1CB08A5CE83426DA7C8263A35ACA21E796C31AE64E6CB32A05008B55ACF66189F5A8AC673434363B45F475E336CD4947239DD9A127AC02436F67A5452FBFBCBA70700F52A01058CF5E300D9780F371415AEC2FF225F07A43F1F51A91FD615935EFD876BE31BE216714CB3B9C792982C29CB32F326D88746FB884B39EE76E60CD0FA83FE33CF14F83CE5F74E14F43B50D03C3E84FA81D9402E1F893A9FB85AADD403DD14C6035A0B5EE9BB98DD068E042F9619055FE80AF76500D38D7EA09249E78B020ECF83CB6E27BA6F409C40809285AF42944BB120002F98406392463EFBE072A99662C111B73C97EE1FBAEA1CA520B54F84FD2C501261C70B2E3C75DB6FF000C4562D16583473BFE99C250722EFEA75DD8DE29DC681D2AAB6DCC7BB865037B21A3179E0A5DC51E5702D48865F36FDA4E8A58DEFE7861251F1E50B6C95CDB4DBFD491A98BB918A5394D989DBCDFFBD34D722CDA9D8819D6CDEA4ADCC5D8E54B7E58B3FF316C1AD1B3BB7393590463F02FB7CDEFC5730253B6D1286A681A94C45025FF0BA2DAA47D2F7A22D97B7152A8B4B188ADACD0F657A4766E2B6A82FDD85582E11D27C0CFFDD271362BE6F07EECE5927EC20BB4B4B124FAFE95F65C0CDFFFD4606378D6A03485325F207727DF828AD10285A72CD009296D8921BC4F1F7749D105F769EABFA7A073C5C3293AA3781BF5D330A7B46D2E9F395645D996C5742CA24BAEA12B52884D354CC8A743CFB85D45029BB421FF8B06562F5F47465F1F39E6C4018C2432C82175F631C57E587012B2B35E2A61271B05D7891669C24CB02E186313A62EEAACC8ADC7B7BC08FA4EF773FBE95ECDA083F04046FDF4CEF88010CB45EAC2C4844B8246FA38AA30358DC0821D70BDA3CF5D32D17A37F708111A171744D65377017BEBF12ADA5A242DA8E602E21C7D5CE680E5BBB5EAFD621BC9D1C0CAA3534049EEF8EB9138369CB86ADBCD4AF9B5E3BFB62FC5C5EC09B54AB87D591A59106A230141085243D2922CDC2DAFB28A67E0D79BA46FF11CAA0D05D258880AE4F5A06C7609A61F70EBCDE82152E8F82F7100DEC3492A186B7C5AECA8F9156B1195A6D6D52F5B55A0A9A06B2796503DA41DF47DC49E2CA1319F212E72CF017BD5A36B7C8083D9B5A34546BB689C7119606779F3E720D6915E310B6282BF98FFB244035E5F2844FE0842498A019E7B8B5BA700B146BF36754D716E176E52C158E6C68EA09F973638D78E7223821F370D0D658885234A5833B3934A9DE8AB743777E0A77453D346066EEDC58D6FE6B13401A9A1D7B98FE7097841D48BB4448FE3D0F2E4272DD8A49C21B6521793BA492EC3A15FB51BD4891DD21AE69AE9F80E6BB6E2CF1BFDB6B74C8B0D45901DC5A63C3A71826CFFA19212F5416777D85FE9B1B815AC68B686B247815F43C3E0B094683A8750C9B51AFBC27816B6164ACA150176611C003C7D7953D03B2BDB77434EB2768CA4C212D1A9767DD5906AD1D6F5E4AB545AB0878619A538B6C317E2DC3770D24D3BC63ED31D53D5173F593B732F2BCBC08C92CCAF492AB76041EF3EE0FA77F5AE55ADC47B65911E00B3BDDD5EA3385483927A03764474224979399940E83A8A49C9B76AAC5C271ED87DFECAC18B4AFAA992B2CB1A04A6C4647C4828B4AC5E732BF7D56757EDCDC8D079883F4BC7B3F3A9AB775C8746DC376042B3AED720B913B007FA4C6E525C7EE033D9C9931769DCB844E8EFF509D3220C5240226707798C722C7B97F2C59FAFADDCD0ABD4C99335F4870D9A3D486A6D06D2A00C0FF61D9EC4085B71B90638EC2F4CF72B3B62CA92F4256A7320D848E43F7B8ACB62C04AE8E9CFC42D9C9B96442487461D71EFD90773562718988AE10E401D00199D35ECE065BC93257DBE1D38629C2CC35FE8342685E54503A75F15BB29E3283903C04B9F3CC1B02CB85F4DBC1B2BB30D08AEDC50F39ECF324AA74DBFDBD04BB87A36D31BD7BA9E70B9E7B90CA61FC5DEDD2CF1DE1868ED5E473E93E7E4557EF081C39628B13A1527D392306078C1189A0A1B6BCBE31B421C3588ADFA39E4EC6F6A16692E5BA669D3C4C67274D5206519D852A46998E492980206A01C6A1B533CBBE304DEF68FB87E423158956769016EDAA9C48AD9035958EC3AF95FC45981E329B7BEF0C5D11D7B80CB7C93465239FE69FB3A5A34EDD0BED53A93089D9E96A3AF7CC03E4F4B6690A843255202A72B93A1EFB195031947DD6A7B0FA9783731E690B513824754C7C685D7B8B61BBBFD800862D9129B72FB46BF7B310003C3D46C0F4B449C8B514A9D2DE61B0A8A9EF48BDC5AAABCB548636042C0D2D3F548332FED043A48F81BAFB4897B9C8BD16551D5908BFD185E9DEB2E66026959ADE4B9E0B3E9F04D38D011E77AE8F38C8AF8C845A05EB7D072933F3BEE00AD376962028674B7042651C91D4DC89290FEF1EB6AC780EDF600D23B8EF474045D14877607D74DFFDC2E9A7F661A5A94678CE458EF58CBE13DB5FDBE2F38CC6674A23F1DA4C7374D38D618B7E98B4B48909340DA000C0DB91FB691AF80CFE6B11944B72ED1442C142FCC6F412F258F6EC0B0B08A52BD097CA708B6A6A0A768B4AA802D50DB92ED6DF4E5ECB03B9E1F776BB4165BDB002F93AE34E8A8D28BC9F910903DF77E26D607F09891C4E7446EC76760C4B96FE3F72AD5BC0327AAAF4761A9A89C2C8E886CE9A74187FD55AB7C0E6948358BB7623849F35A4BBB487C17600235EC49B3BF86178127A3436F6580446A41A7BC4F1B352604539B90A444B603E98C20C75546D0D4F5715BE12610E44EF9AE6F600A7DB33FF2133F8695D12321D20285F4322984B0FA1819C4A0136035E134E81C43F9400736DCC8F3680E71E9FB90" + }, + { + "tcId": 74, + "deferred": false, + "seed": "2ACCB6888C3525515F10A2ABEA6D7A3B0CD43AE249F1F7CA93D1DDA58A6C825D", + "pk": "AB103F67F9038F77E3AEFC61F60F953D651B57734804C319AA1678B2E43CF2F7446001CE0A183DE5F05257D64D4495DDEBD5FC90DB67196FACA8155CE9EE2145A7A4F4CBB8E6F8B620649EE54D8BC9D680476C7165E32941B3648C86D916D8A1D738A678764AE76944DC953B8D94AF1B9535E14547F6BBB32882E43C7649638B65AF3D61995DD2D8753338E4551A5D3FDFDB7BB3AF3A251C4B05DF5ACD422FA56709A2EB698C80BEB9B83C2F7C0DBAB0639833C141A9338D03EDED1478C6F26052D3A07D6479D7D9D84C4CFF0B3E12720B766E7C805119FB5D31CE45590B52E7113F35E5EF11A5440B6567C97C81DA59A73A1040CD459B7689F6936687B964FC7886A9470711243E8338587DB7686B198AE9C7AAFE58FC0158514D6B2D51EF53C824D73DABDD5B30041EB914D4EC5EF290A3D8A55B628773C8F8B032B81A683D5850AF64753B142971B7E492153BBFB255187E54D98B887F08DE5AE72A89C55F13FE2D5A9B90B8020C5192C37CCDB325613BFAF29F44621CF82041BD335CD8DE84F2F9DF7BFB7241E7AA8579952F4FF6FDD9F7EC8EABC2F68F730CB648D00DDCB6D51ECE42409DCB3BE74DD78CCA1E392B6FC36B0675EA6549678DE83C2FDF4385C551625523CBDCAF7E13BF38B67EE2282EB27F827FB575F3C01A41ED95249452A58F5B3595A9CCEEFABC5591C873E7A726FC20FC3A34C1C665FAC9DB9445B34AD03CF4AA9F3F33BA8AC692B973AC8869D4CD25D4CB1AF9174305894AD3745046E1A536151AEFD1B2E8F6AAE6EE58756D7FAE3BDC18BBBFB750AE21C043A643310813D1C73C9D8BF31B9945C2AA43DDE3BFAB9EC891E2205DFE4CC7B375DCCA358CCA611ED274FB4DBAACD67DF7D2A7641EB04FDC5879E11B3FB7E7EB0A9324F665FBA610888CC8E471443CF83BFA95E06AF1F38A7F7A694E7D8B112DD215D34851022FD401D8551390DC00CA42557BD6C7643E6F1CFD137E2EE67FFEEA6867E2CB1956ABC5AB12E8DFCAD33FEBB318FDE62D8DDB0A5490CCCBE0A8728E74BC0891C94C0153AB15D06E93CFA99AAE2ECF7ABBB04BE51E613BB9B8E19AE454690A57276DBE1FCBFAF1052C05F0532C003A28132639BCD2EE8D453924D7A40E8CB23FD0D744ED49E1D402F4C05E739120EDAE70C937ECD9F2487B09FE332936104366025EA468F495776F17B58843766AE40D0BAF21306F4818F03329CC6414D65CD8BD1E360E61301FFEB702C571B7E35801AFFAD2DDC0CF7CE32A51B730223976E8DCBCC3DA88CCFB5BD7497263CD4BB742F2D46AEC17103E362AF1B86ADCAA662CCEDF940A009325CE2CC47E5B95B77FB23F35C188214AEC7B862569D4395B7E4CCA1F288EB7AB777E1AA7EBF0A9289BCF0F7FAD99D3529CCD6DA43FDEA0356CF1E9D0214FA068CCAA8762B6CC3DDB910ED8B1FD92702522CBD20CDF95C352624C2CA7C2DA5CB90FF964B5399BA9F0A67F4A7D062BEDA3DF4F7748058E104D97AE54BDB511A83DFC2A22934E782B3A695B2B7AC23A689021734936668BD8F752E638BA2877E35E99C3C3560EF6AC2BA8F3D8361E4DFF09EDA4196FC07D0949818B867A0721AA2E861E78CBF3BA63F52E72B9E75EB54F847CC8DF0BBAC4B1519881D6A9E3B0D3D609DC9B93CBC3569655DEAD9647732832BDBA23D7CDEF931A85B932C16FF7025E860199228E91AD9B7BEB70AECB0AFD677E0970E8C05612FF97BFAE7EBA53D6243B0EFFAF51C4EFDDB569441FED18018A90034B482416A3CB81E9CE8B7298BF8A2EAE1D58661360D2E89F3F91141F281618A9E0A598D51C4B16397D44C9E5C2DC5DC0457BC4749AC3E968EEABA9EC7876BC9E06E61764A200B2ACE50B0C4769B123A6468A8225ADFF3BB072BE044CF43E41A4D74E85E14F911BE15B950D09ADD90F01DEFC9E93F1ED782459635C0E857F77D11FA37BE582193EF0DBD16395487054854C2D3C5E9A3B30580E109873B1AA16EBE776425D33071BFC0F1BAD64DAC7EABF51C7EFCDB63C12C7B77E9BC78E8ED7F33A5E7462CE2EAA2249F0F3321B1C0EEC70C8C47D548200D531B68FA189DFF75E24174BA92BABF96919EBC584F0D35F5DDED81ADFFE82DC9803385CC3C645C3E871C9778145D45572E1DDF29BA88ADC365A2655F1C279A842317CDC42E284B213D366112966930EB6EAA58B555D43C7798853E84B6016F93EC8A0171E4BAA4E22D61491775E54E4A3EB24A618EC8C2AE256121AB12CC2BD08B2465B0F183F2E0645936B44B3D470E1D12F8872308A832F5419ABB76E78BE62B1BCAFA38867661957AB45CAA5C839BF949AF640DD0FBDF8A5F61AC689D21C4981E925DE139306092066977493B79670A5993DD3CD6BAA0E3EA035C1A53246EBEAD5A3F41AB2FC858198B84BE5304226F85D6A25DD002CDA5A06EB8193C377A905D180599C20BB3BB51FFEE1A459EC52203E81E495CE1259115205BFB9C528F929B0BE0885D8310F66933956A36A6D451E15D19EC52D5566B09F0B958651255B9E1F2AED5A71CFBE458C7D6A3723887CDA58A63DC0C768C1E6B63AF3CB8F1D0F2F22BF5FFE71111A42E0A0216E903958B5F6A02A6F6851B0E729F33628FC1D6829770D12823B17E57166F3FC6D803A138AA86CC1D10C9B704EDD7FFD328A88D1A1906C8451FDE1708D6F5E9766F026F38DB1E954A8B3FDC0C894BF4EA565F65A54A1F66B39ECDE5EC51FFF1210944A8D72DA94A9638A9ED895DF0AF096D9AFA8E98A234CACEEA1B370B5DCD46824DD6DD65FDDDE7E978659A52D9E236FF1E8196A145B31AFE40A01DE7272DB0FE2C84FD270CCE6D1E592CCC793C1446D5EC3F7620B9990381C8455AF18ABB60A8387B0BC84A2C8AE26AEB685DA301BFDAB4D41115E98A51CA921DFE3D551F778C37A8E308B02AB3684F4E91AF9B81AFA6691821FD2D36ADDA15FED1C4683AFA2140855C430985C1C41B272AD2D41570AB1043A7FA871350E27D90411AC43CEAF03631027522FA1C7F164E9A24789462C7BCA902ECB7462C4B1D5262F1184980D6AFF4BBE18A085693BB54AFCB2E95C1F24432CF4AD37BA682CCCA98C8447B698B14D06DB3F04BAC6BDFF61D9AEEA76BFB393BA5AD68AA5B5C784557EC67B51BBF3BD90E421528DDEBFCCDD52A9E0683803D89847E27E5BFF389F9E5A82BAD38C36EC56A73947631D2400C6102C9F764B81C06557B60922180754F9E728323AF15FFE62D74AC5E9E7D0F960E5ED4A66EDB2D38F775C6A41B08C43ABB3A9B561A61C908C1B2812736BFC9C6B4F60D1827E8DD66488AA1A0B570B2779AD3EABD0EAF112D06F8BEE241EA22D0FB770AE30431A3F1155D06715324281BEB83F8D6352BD11ABB05470984A91C09009AB0C4BB9AF268AA0CEEE8404D50EA18088BDB5B9D454FA747D48C843DA2268694AC4D858700707E2F01EE7895D550554441B83052969D9E6A8C7381932BA04AF70D277A0F90C7BBA0400ED0074448BE6012DAE3F2AEDAA20D0329B2B71D9F42694B69A5B77782532FDFC43F04E5850B7EB7C4421FA45C06AB0247A533FF8AA42A10AF60E01E19D1A0102EC6508DA62F044A05A27819BA6DD7E728FA7F57463E36DB3FCA730C15E08531FAD965B87B370533DD8200E3271BE939721F34B96FFC39D80765CE1FAD8949FD9460805B51C02310BB7E67A", + "sk": "AB103F67F9038F77E3AEFC61F60F953D651B57734804C319AA1678B2E43CF2F7D400BDB6C6487CF73211781219BDA2BB75DF877C94B708AD56A7838C6E8F93A03F4E076E48B75928B3477AC23A937794A4E46188574E1B75A34B3366C922159B403DC25FD105CC7D1BF6C121B4C9809AE0B7438C29E81CF41377958760C8E33D44463223246682C24CC13021D0A06CA2344AE1A8082307119CC6800B346D003791CC124008054A82202AE1004D42B600DBB828E1B8099AC4810A8209108769CA101018464AA4A40050C40502334822988501C04CA4204C04310114160A18822581C86C5AA01181342EA306455C209180828008872C1C4448033980E348689C260DE1004D92A22C42C061C426891407091C498402432A8B0061123668DCB8080A8964E03609908028018420810886C4446061144088302C8222050A3685489608200928801288230448931489624021A206101A4791E2C4450A0271409200C3968C03C44C51B804401844E1A28883822D90960DE0308610072251046502C4318C86901B338614C24114235144986543088A1A204018402D20401002C04060982818340093246004A6200A2462823090E4305251C2300205124848884C866D00233123A86D22232E11170E9A1044E32060521225191002D2C23141A06C19A910CC3040A0C04C21274642202450362921300C13B08922C405E41408448271D2322D6184800A255120A07150124CD810408A901159026120436411260DDA80258A828962921061B02C22A071809404990284C4466252868401C020219024A1868D04108A134152C2246998C48003250E4B066804367209813194445111002DA4069249B82101B32C52C66C103229CC366A11042E91B2810BC56564124AC9248858286C0346520AB6050917690B11820491214C2005D3A868133502912630C4086C081389D44642A3B84052100CD0969020188D8BA669210145C936682046458836306412050A484C54B2092238600A440821098603098AC9B230012601A21484A14046D0908DDA42114C86841B21890B1071D106891C2562D434029CA610D488400B300D440824080670A0C43043164010296418972C64B46460300E148131DC2284E4382C631892113829230024512664CA422A1306290A894450200C60A41020211121A5650C2311241065C4982100310144025000C549043100C1482453360A83406294106CE28891DC08255B0681123969E0B2311A030411C40D49388644B431831662E0062DD9A050A11241A3208480968D49340188888D110622A3200A0C990548286ACB3849D944660A81041C0766A2C28094942000862051A425E4180423116EA3946411016C04816D0C410EA234281B3692DA004D8B488C118331CC968410395003C224D2C020C2027210150ECC80484998651220218B300E63B448213690C9A4099CA22C13157001934C4B3472D0B06C5A3202C20882A40688249328CCA4500A2772C20472CC464062904D10C53163B4442397608BC44D22218C1BA54421042952A608A42402E4329164466C428228182684D036892236268B066D9912610A2206D0C0404818490BA28D121165512286D93868138768080411D8124A9318491C3381DB107041480D5A0404C82404022686C9A08482B4481928064C845009154218006518B231E4906119286D61B00050084511428494C4800C022989306ED1B4445CA66848A42424A584A298640CB90843C668102962E3368C5BB0500A4050433031A0269244202AA4122222A22404128E62346D93286153A84C9C42410A997149A24DD33831D3064D01906D9080645038511A377192126263322421244AA3026C12B2451AB96D183802132612223649D30410D9B628A1902022018C22262DDC224E1A82881A1106CCC65101195002B890DAC49020333193043190360A84066251A40101399008018E18218223022E4C942D01A6611C940921200649842D0C488E441085420448E1142063240809078223004901A900223941021992423648D3189224260152348E53022251C024598805C48291CA023241221210902018C5505BB24CA0820D239560E2A68D909669D31869A2C28D84442C13B961C390249B0885D93630E032721B424C11394C1B206043144E5A263009320A44022EC100658AA0651B176A1BC08D8C3425D9103252B401D9C24C52360ED4C645100692F07098AE41A05D93A1C684A6F85AE0C3005091536D975F58E54D87BDF53AA30AF6D208193913E3369AED4EF455E3B740B7078209EB3D94FD7326D66A8B0C93261D1AE17B84C1F92571C48CDF1197FBEF94DA93141A721132B8531F7BA05632C88D29260A3DD24FA18A3ADF458AD3ED969336F625CA4EF3AC10CFE394D8CF7AC01A42B9303F6B0EC1B6D921675C44C96E554DD6016EF83CBCA0D43F87F50F38E39B65EE5E2F371E1903E829D9B38D0465878A13774D98E98ADE50B44244C04C9AC0C99382B6CBEE6A5471D6051B1B507E12D8FA5AD2E75910CE1DF16EB223DEC48CAE8BEA1F6BCBC5CEA43B6F88F3220907D43430F3103A9DC71B99D372AE154B7F4E0D379CAEEB10E92FEC9C8B1759475A488183D3EDF3FF9B59D52A86ACC623E383D71DCB0C89151547E07F3D1B60022406D823FCD9C035F8CDD4B5D4577D31520404A1C4B1A0785B32FDAB02BDB35247031CA6EB0C1B8489689CDA38F2DD803E1B27D06D368D9F4886D33267D49DC5E5854A0BC0D76B8A152013681F24D774260A098E90C3476F59860F19A0CC0E88FEBFA673CF37E8E1D60928F014BD0BEF831C96C87ADFDDEB721CFF4926DADD97A967DEE812017D1C5ECF64B67E723C26878AEDA15711F06BDA9142F3E0B7BC5659331362BEFDB8861365154F5699B78ECF66108A9E7B689AE9177F0CCBED79051402B0666365E8BDAA3C781526AE71D00A6CF14B1AD10A3B369DBC67448476DE311EB5B66DA0520FDD4180F2FED7B5C8FC91999E09CDEB463E2CF65EDECD5255F5C9607706B9D0B066BA2D41008BF7447FF67787C3A35569A2D5E7D68DE2868F16923D61F8D0DA5C1BA5ED8AE24390D33857D4C2C08C91BF604525A0F677B0406A2D19CE949E0054F6B6EE0129E95561D62360758212316C09447F5AB159C1B327C7B90C5C32F09C4659DE7AD13702DEAA6DE5482F0EAB4FDB5B7BF570A4AD4D5726105C93560F6EE929FEA795ACDB4D3F1B98CEDCD2FC4053CBFFD8F5CF5F5A6DC1FC7BDAA5BE8C450E2EE64492A06450EFD221D228D0B824A564AB2D4FF899CE2C305B9CFAC7DF5E51C2EB65AA525B9BE9E430E607794022F0C027032E257007A576502C2920BA7A343CDAAE1B9E096D19959E80931B407CECD160DD330581590268CCA0CEDD1ACDEE0FA31B4080AC4DF0C5151383B3EB5B16C6000905F9FF28271FF7AD1AA6958CA868307DC40EF3C841F05A05E30EB923DA60BA5D8FD5ED3AB0DADEF52DD483407C96BA81C11A37E33B02FBC54EB54EE96BF1DAE0B2C8000E88C3AC653C722C93B35A983949E3C4A813831D54E9A08703B71993C13DE6A94D2E30129453E2E4D63CBDBA6744E1447481E76546EED9E83B0712CE3763CDEDD290E1F01BAE87BFDE6782B0800CA3E01683CD4D5F7926E8612C6FEC9A41B80D324E7EE054F8A56B29BDA0F9DE74E2C47C8D891B8D872E0936EEB5918CAD91EEE3D88DA6C1F1CBA76131C1538F6B0F9243331622F9A606B3EF3B3E034B77BC21ACB93063461FE91E83CEA487C6A21C2DBA19251E456F63615A41804CD99CE5CD363390827912CE79139762E72377EA7333BB81D4379956DCAF8806C7602365974448481E917FB5D453447B87E1BA456B6CB314ECB8815C918678DCBC1BE64E993C881802049A823131292E7695BBE6E743CBBAE9CF2BD1785AAEC2FE504DA418D90BB988FA6D3F1B6F9DD3B436AA466DF6B3CC0A9494B4EF308D8E3C017355AC0C4526845822B9ADFC2C2E15EA2C9BB3EE8B02B3E3CC327DDBF7BC98DEBCC2170ADAB1E9504307E7D7B777B46D8E6323F6B31C44A47DC6C25BDE2F6C4DA92A63CC4EB9B5881CEAAA535EF4531CCABC97D37933D401A09380DA609EB0D17C5857724192D01DA491E0E8E645DF8615C7285B7ADFE1959311CCF4AFB0E1187C3A83E6439F4007B689CF94A9AFD059E16B3521887FF6FB6F7162DB089D8729C128AFB65432985693F8F6F8FCCEF56FF9083C5E1843E1AFEFAA44892FFCD74A0B7DBC23321B3BCA93338961F95F4C700E5E4AE13FB45BC9458BCCA5B032C7C9884B3FB67CF59FD60CF1E9CA6563A52CC13C8D4C242BB8DB246635BA3A50624D50B1F54EC0E2F08FF9C725EFE752218F5BEBCA4C37BED12CFAD5B11601CF8BC57D5FCD3D44466BBBCF94D653512EE98F60965386A314B83957E8FBDB60123424A9F403BA489D0EEB202AF8FBD9D8D92C8F05880F60B6EE96369CE58CAE83827018E0ACB77C66755193525C80CCFFDE7DB5FF123FAB4CDA0DC97836B6712BCEAB0F4F7C4FA3F83425BD7528F51A4BDDCFAD5A66D1BF90D093FCD0EDE8FFF11DAD38BF851B2313F3100359785A0A77124C9A1E3F3992F16763881C4426BED570B96CCC534AFE4FE62C690C9CEEA653F737022A80B1E7C26CB3493AD4FA370AB6EA6A6A7B34B6494BC3A9A72739491684EAE5BFD22204939DB2D4C263C3692225327A9E00AEF5DE8F94AB7AFE69226E0DD7FE93E6331F2CD353FF55E06DA3AA647D0C1597EA2D31ED16B0200885824C3981AEB985A1D913212A48D6846BBE760631D3EC6238737E7A0A678CC3069917028D611664503E983AF9D2759DB89C298A638940486167111C39DA598782CBE48DD3EF3CB55A4BCB83C17C519666AE344F4010C80808247D6FE659643B9D12CD07C0282ED014147369D84F415B273D3A959836C01B4D7204FB7906B6271027E271B506ED489C8447B73B2FCE2019EBF11836D902027744CD0B5C3C2F1770EF816884281ABA2F758A740A2B1EDEF583B76C7DCAE57C46D09A45AF1D1D78CC4083C243BAFAF302DB0800E646EEFF1E63F0DBAAC2B4A7CACB018EB35CF8B06FB133129E6B8583ABD49B8A374B3654B0A5760B5103FB748D7723AD10066FDB16C35FF25DC0B37A1A8E650674644A38A17935272F8688CB9CCC6A2E7146E8895DE8BD18D018A5E4A70CE5A61172790A9B0C5817EBAF43078BB2FC26D202DFF4F61159E675F4F0089774BD22A5FA1BB66A83E762A7829A7D02E8A7918D786699A6681AF4D39F862F1D1731DF2214FC7D70F131F5A7412C6E00D7F63E2CDD5F3ACB0A828518CB55257EF7296F25E514D64841A4C27CD72B455F1CEA15F823A49627171B948EDB8BA8A7128CC9E1D9BE62A742CF4ED6CAD17AA5B3E31A61C5263ABFCF8714293379000BA4EC7D75D6363D4E08D1AA0E8976D319668C86366727F9FF004550AADD4AFD9E9F7000570AA12B72155FD303F073C06B550DCB7956E01C47620F72D6CD5D611C7FC252E7211E4AEE17F280CEE89B9F1FBB37279A85CE8FB3F9C81189D1589574014E0938E1E03979CB6071158BBEFA2755DB66FDE520BD38BB9256AA9EA8482AB1BA7BA2F723F26C2DDD7788A0C1B7E864D2329107DECD4F14C5C77077AB37A84461B85FE005BCCC49BBCD0659B5C193DA7E7EBF1EC4256A62472813E0F25A2B7BE0C7F305B6529BC4B0202C9535D38B99D27DA84E4B4BF4672819A44B79D7A22107AF80601B8814869D95E2B7F41C5C74ABEEFF67C3850162DE79F66CA805A0686976216A28DDD130871671A028F57BCC8CDCBDD44CC294200F980E8A1A3516D3E2FD7CEEAED42B585897CAB5967C53C5FB19541169FBEF9A6B748AD8087F215F3CC7D6336D0E70D1CA1732FD7F379DBB0785F33056D5463EBC13213A418014324C5583D2A79BD7C83B7F8CA752858DE7BC2BAEB315C8053499FBD4F1C76D862769AF953A3CA5B02A34CAB38D49A694CF7E7EEB1D14B13BE5F69D356F2FF5536C32E1B4EF7BEF1F8C70D62EB608811D4573A5787F5B31FB88728479398175AA14387623C973836A1791946B7C3B67DBF08E60E9E3A397549F3BDD095628E4E0B9601C795A925BA25C2DDAD9E92F4B114F2CDAD6377B674A991EDB6B17E9438AF7D3EAF61524E4CFD0D1CBFAF5DBB8E32BA2552CF016372273DD77C327B161F0D2BC9642007EBC98037A9BFA24C441E3E1CBB9E3A91AA3AC2FB19C0FD388472AF2C76FEDCF0879CC92BD1E75A3BF64BE4403801226E7F097B20BCAC08F580ACF09B9034B66807E9580A53D65FC2454AFC9FE6E52D39C29EB8E6E895AD2C5324DA8ACFCE100425783B3FAD39F62598D73B968605B098141D931228435622E2C3DF1B1A597AB163FB4BF480094ECAF884712E5E20226399369D4E5B5F612E6CF60489A48D4CEE551DECB1D91F100E7238DFB1F27ED04C1D2951384E96F1B7025DD0C1C3143830F8AFBA0CBCDA49118FC1A18FAE7E5BB3B0F0DF455366D3017F2548B2B7A1D20996408B194BA0F7A553B942B4AE572CCF76EF9B345547C1B2C5BD3377115E923157EC7DEE45CDE95F9B1895845D9B51494CBED188EF9AE6E6CF6275179D86F5077FA6A2E9F2BF5ABA69D9C1E937A75DE26C4C74525C8E64FF78062F508B6A2FA5FFFAFF9282953855D561724D1325F4C3A8BCFB2BFFA60EA0B0F7945CCAE9C3644E1FDD4896BBD03468268A2B8CBB5AC94AF36BFA7C1901CBBCF72F08BD9E3887215D37F0B7A89A7D07CFA92704915A104E5F179478CCDED737C1BCFB46E8D40F09919A9DEEA0858F4C2FB3613099773F6FCEEB9777393EFC9563FAF43C0410B9D66966B415A114A570F4255F6CBCAA3CE563B40E9E599C311D38A3429CE65A92283E03FA26525AAA3B71C7C897890075841717E708A2CCEC301D1D80F1062DEE01460C0A134944C33ED0AFB6048C3095FDC5FCA7F66A9B9B882" + }, + { + "tcId": 75, + "deferred": false, + "seed": "DFCC13CED6971EB1BF3243CB8EE883FEA9677D1E5DA8F3046CFA4305DFB79127", + "pk": "86EBA265F989E4500C8CB3E387CBE26508A4032AFB8E978D80EDED75AA4692D5C010151C22FC4A843F9EC4BD804908A705A154CF2A75A08DF94175AC8E1AF30AEF9AFDCBD3C4C6C265527FC557DBDF1E390F1B3112682AE1BC1AE0A45334FEAFED6D1A7FC508068CE2374188E40B4C03FE8C373551C5C1A8BD4C707AD00B6DF77808B06EE9F0464E75508C1DFDA68A543D6616B37F37FE2D1E43F94711F43A7CA806728B2C1B9DC5C3BF3FE86740CDE4BE46A95E99818CD277B12E75878FA1DA028A30040F643DDD97F5F7761056578FBA1C6AB256A803B5B73F4D1C35EDAF40370D4A82CA5AC8E7CA15C1CF77543D49292E4DDEB4CC67210839039C85FD09D9AA3B16707E91B02596240B26C9E835EDA8337DE7AAABE7D17F6CDCC29A5E1F896110265B7A4588683FE140371906917D32B2E7885DE8EAAD0035F4766D0D5433C86D8B909DAF5AFB02754AE3EC78C804B939D04FE775A777CC8BCC0AB91CE39724A2CB0449B3F2519EE086735694E2F266A3936FADF367A032C84808DD355F805DDCE286BAF7DD3BDC27DAB1714224016E1131C222187472E3F9B34637DFE6E5E5B2C9597A8C0AEB21532EEA8F9B1730A20FF975C7EE0FCE46513DF1C87C7A9ADF3B1525267F5FB9230A5E2DA4CAC0755C261AF59BE7F837550A1EF13F3927A1C19909D9A308438EEDCA0E01EBA5AC55B53A9E7DF7259A99D0F1DC5431CB9AB3EC47E0E70AD2EF0CFBA997647327A579E6A4DFC84DD4D49669F8431A401038A4C60FC5E6681F46F4CC13FF0264ADB54D1651050CCC13505E48314889F34F023B31F5AC55CF6DF0D6546486FEEB64542171DD2CE1B80A7BB0D21A1BD12B2E04106DC1D062D3A82BD92539E9AAB000B53CA1A9D22C8D3B28702CD9E0A0E4A6E1049EB64B08F47C409CAAEA917CFD656FDB1975E91B8D33168A3A3FE4F16D948677376129565C07FC961301A45B2120A6E05D0CF00FCD5EB40AFE2C45B4DFAA84CB428B1AC2379CE170A31C75F6C0E94CEE84AF08CF22EA3FD73CC31DB388F77D20764AC80E9D98F951E43443281F3922DBBD7667B436CEEE30311A9DD123A7596C46EE991C5367EACCBE4C0E0344147C065754F5B363020C9093BBDA21CEDD00B447E97C8FFE0616F976E5D9E2645633799E25419CAD1D5DBAEE26B160D3A7777C3CAAFD8993AE177C90D31FF8FAD80E92A6C0148623B3EB04F1CD67B15C0BD4C1A1838FAD512B9632D5A13503879D1E44093745B1574D236BEBC77D1AE82E02EA2924F83C942E7A11D83D77448B9939B0588D84F7E64727C73647AEC32776C2F867F49675F9807A68E4FA09B2268859F5B27AD89F7EA7F1C8FA1E62C3161D5A92C167D4B5A2E76CFFB8D74135EA212C51A4CCE21C909FA2F4B2CA63C6E193513D8C83D716307FD122E4A6482ABB12C25F57703D37D170C5DCA08D9D39498048D2BEE47DF26F64ACC6869D7705ECE719470C69B270BB2DCF12CC014DF399BB6818A1E8BCDD9769AAD420261F946B7B0E73CE859516B9342F0EC25808829E569895123AD2E98C8DAB005D8096B849497892A749A543601F846D87CD89BDF6710D5D564262DDBC5EFC069F33D9BDD8A0B04BCE9ED672038F1031937A97693B9A9933BD577935B00B3DD9249B369478F5561BAC68633577BF71C27895D0543B0BC67A068E0500F90DAF1F5F18011D04A506D3B9AFDE41F5988991A30A109DA4B2D4AAC5757A7429410A27CF63C1B5810074CFD5AFF6A4C4036DB6D4CD62CB75895291A3070D399C8F435CE0A2C266FB5285011172C444204F837C6992E2FF444EE28B22A2FB6B8193FE71D03843146099CAAA242CAC6F74ABD5FD87576A69EBAF3543C6774017B7A1FF5851660B62F54876EE54AF01FC9024BBEAE59A9283C1BBC3E92CDE19E73F34FA575803AAAB0DEE72B2088FB8E0920AED48DE6D5C12F8E9CC64E9E96F153243B997EACE87921188589167F43C660DDBA9DC067FD857AFFE6145C49EBB6FDBE9D4F6FCBE420BB5D4D315F5E2CA1D519FA65D71203ABABCD82A4167B9C8FED8A45141A2DAE15571A61E80169B234CFA1E29F352D0678A487B84BAC6DBA09EB8D66FBB7B3C1311C715192EAB0E5F51EE5C9E8FB30D102799C4E677942B957283EF9A6B5009C784975CF386318D7637AE8633752E8E54DCA2B83CA7E49CBC2FFD48AFDBC3D1098ADEFFD170E981DD89BC5996BF60DD58CFEE25C98B49C1CDADA7015406F001D8160F496131A7C7CEE245E969E44EBB91361F67F19A2F40A9414C401635A927A664B770F7BAEAAD8BC92F77C897CA3266CB1334F8F6BF07E327EF3BCDDF28552A3AF763CD526C7AAE3AE1AA021212FDD48A3FEDDD6044CAC2834C0B02015385C92CECF10DBEB46F85ECC09BAB13533E7AE1148CF63FE8CF943C563DCFB66A986B66C3A4D29D6CD59F8837B2FAF10AB55AE37C0BA03C82319C6517F1F21B2C1C9D28D328B8F8D1B2DBDD2F4E1D6106C1B96DF68818A0C16200C5A5112046197E8CCEF6987B49A9BD0D173CDFFF9B881134C572C781044F183E251EB3ACF77C98E2E09E5ABE94D560C6F240295F552192770D1E0CF08EF6573882C64DB14D4B7EC869F3505E764CA181B9898EE04CD824C93B36290B1AE286C2165B02D7A1C02CF6E3D4530317CC53164A34E675ED6FCAED968A67A975BDAF4717A8F934494235FF4BC29DD78E8610B3CBACF8776EB687D26482E7E54C4EEC6388F27BE203B582549A8AD3DE91396A613A061297CBEB572AB559E95F0CA078D9F0FE2C68983069C3722B771A7918CF81ADC6A4EB59220CF0FD2874EAEC19901940233ECE858767E85AB96C8CC5E2F671E1AD10BA56121683E92EEC5B394DA24E46DE8A0C8985DAC50ABFF991618E819A592CD3C6DBC29C433CC7A248D639CD3A172F2BD674E9D18818C78AD6E50CF09C56E7FEACEE93966BCB27AEA7D0E6D099452958EC60C5F0D1D227CA5B342004AF21B1B8C43A27CF11542A478BF3B5C87DE90E801E4C81C4EE131477B663196E03DA4A307C8E1D1716A36E1721A512748F01A595464C30FB90B1EE1F5394E8E31388BA5C7CC273A61A12ACCAA671DBFED51FC9E50EA536116C48E56FB8F8C2C28859D937A2248D4C1BEE872FF12A75A3E93A4A93840802B920ADF6AD2DBF1CDE092E2C8373FA22E6DE1E062E8D5C71413DA5DD48957BDEE89722DABC0B01464E22E3A5CDF0BFEAEA5879ED77CA5B34FB1925BB925A44C2D54BF9A00519DBC68E4591E08A7AF2547931D5403C42BD7A25C4A7C286D8D1A6D06608668E6890B222A8DF12DC7E06B891BF5B0AA145F1ADAEB9153A58F9FCF63154E18E08B6CC5FE09D7CCD659A12939A3F0986BE7AD5344D5306243F2E5E970A797A5B268A85FE721D5B9D447ADF725080E749B88F795BB2476D232BAE3B4539B5B9286DB664C547DD9A037F2DAF6034122F7F10AA8C72CA123F91909C4A1025B4F6DD88319D5BDACB85D3E1A9452668AFB8CA012B3BCC3DB180982951A287F8F376D59C573CD0262D598925E162365A79F05030D5C3C7854F19964CEF5B08BC0F1B542A8F87DCD29F6A07289F6F7138C31A6D70EAEB89BE30A63DFAAD20ED7366E0F71DBEA8B308E416321307D1B63FA54EDBB8691C2AD4B624D0781D5A6CF2118CB3C56A6D4C0F5544303DAA723AE181A787BD643E", + "sk": "86EBA265F989E4500C8CB3E387CBE26508A4032AFB8E978D80EDED75AA4692D56BEFF71C2EB5536183747EED21768A95B3CD546BAECDFD720956DF067C4F25B1B01B94DA624F662ECA6B0B7FB63829A85DC801976DCE9375ACBB16610E1F4C8410072775FCBEC4F0B34F7E9A81ADFFD2B8BC2B651CAE1D079D43DF246462AD649BA26DD10051C8242CC0B64C1C4064A326654198641317889C302AD11644241872238348C2B84C14080C892065C4204148044C10C88D0930901A25498C208154B60C1B26290BC59098028A493684DB060C4CA668C4C828CB08850C4451D2C62C0CA620E2804C62286CC2480C93880840368162964091020D23C348DC00525C466604B48C00C844C232449C366591002842960D20214C08080143A6710A9468C93892E00865609871A4C2905046720BB448E4B470232682DA466521229119415013490D19434A04B8050C020CC8108698060C4CC20C58422D533830A2C888E038711AB941DB242600892C000524C11411A3A870212224144290C9A83010046ED3C00C2237901C3169C9802481A0400A32700B25801A2548034068912820D9129102902CE2186ED2408908498899C4404A94202119082388459A4020C110649044609BA06192406560B22150324A91B48C02B210000448E0465210C344909401E21240019160C9208409C66503828882882C21475160068C99C200E0246C93B051A4229094082E92166D81A00810026411A64912315062364D604602194151188944C4282A400402801411D4B849C030495A00501C8004442812828460614045D8C424133806991686A0A42D033185500689C0A085204924194800183985D9C22512A710191704D82006D9408AC1928910170619B10150088E9AC8498036524B244D8A8221112140228269810251C92882992268C8804183942D0818894C068A040662DB3832DC346911C961E0120E40164522A08D829260042141A09051182500C1421053A664E1184C19A34000222D4822915AA0284B264012C111E0346D1B957010379023C9850C380DE4283011422614A6484A3452E142128206090C07820CB16513456224878C0993005B966CCB344818800003124A8002300302619890254C32902385001A3550083885930472C4288E10C900634204604409C80226D2442D60046243988422264422C49022B2600CA84D4B145104417061B61099A468A1440DE1368A994486401691D20281CA244420114899268190102812428D50165119404060B80C02434E0B3672A04461E0404912474211C024040592439464993282C1106D01144A002185142525224626A0B888E3C80DA02808DC848100912C0BB02902952119373041B68CC9280411195252146E64204213202DDBB40958340552C82003C80C5028281C928D0AA20510B345D438889284041A8649CA1689901808144712A2243104A611821468CC82209A04525C38501CC36DE1C46D11B161123209443890E112501C37705A4001D9444809C071D98088CC141203C92553404912C90084188E83A0219A902813394CCBB0001A296E8894718A1662223221E1B2852417412193711A86448118711CB40CA1A0310B038514154EE4168461100009B25012B94113C2290244842217411B440AD2923061002A20B390CA4204001582DB284D523224603891132801D3326C9B182DCCB450E4C024831211208384CA144D0C0741C8962D9BC631C01210CA20410C442A1C1126C92846E3B66C2021828BA29121016440142E1BA24C0148001BC38C0327261144260A010A033046DBC849E382810B0370DC208C0A9740D00028E0C06D61B28443180113B3690B394E001660249425A228251A81314B26850C32825A8260D0160D0982800B870821B94CA32460094348C2366248244C88821152044E2314040A353048C6840B976980381048088EC494646232808C34514A1220D2080C83384252262E13C211DA08648CC4890C4746D8C62512C56D64C870CB460011B4205398609294488BC809DA28848CA2681989044C443112B085E32680C234509C484A23258622472953B88444A468E11811032820D0080D8AC484138829E38410A498490C164291C8052285411A056118158ED4A430D04011224862A4868460144EA0004012B231A094802325125C164CCA8870043168C4A6851AB644D92808A4146213346A0381089234282241128192C6238102623B7DF4F576A60F0705211FF78F5BA73A020C3B5D126AE4D98FB954C361C73C0DFDB8B56A6666BEB0E11EDD0336DCA6E9A615259DCAD0FD54B00385AF5E6CF0835D2C8A20AC908793D65180777E45CD2C3397BF92CE8B121C94B3B4E410816938B434553F464F6A3F8EFCF1889553160A4E00BC90D7E0B455717633936C3EF7031EEC468053F036EF3F1B3156FBAED8E93B62132BC5C52D0478A12ACD5ED7FCD44B088588F21A416B76B3A1E05B4BD04A2EE2F210D812C67C4638587EB614E7956C3FEC3A128F41B03427624C98E2652CB37F6F6485B776C9587ECD1E24520DE64B2A9E925B950F89ED3FB37291F520B96D9AC760AB59B9933E48AA852106883D0683DCE40CBAA4EE8F04ED06C20E6F1EB8A71D843913BD8BA253524731ACB3761E94DC2C99AC1022F7713C45D85A46E7042B4699D2CCD9E6C3930EF9960BECC2C88259C89CBC9FBCA7279575D65341DE40CFB2DC3CD80590D46C5641E59DF726E68FEA6D145D0E385B4E03D98FED14E85A3ADC9A71A4C0F3852E160B1948D4FE1A2F77F417C7DAA829077B94BD8B9FE4695B063279E08445566A2E6C88716058A12D0DA5D0E619300C692B9F1622DB08385E745FDA142B21D73BA3FC12CD8D8E644B062DDCA01586597F2EAE88FB44F00C594987D12AD94A6FC54736C5FC582796F8F7E03621EE0A2C686F804BBA9C55A1AB856761683289AAAE5220FCE946F7C33F75898F01813DD1B96290B2A0D6E841A375A7CD816115147D729883731A9B84B55EE22F6D7CA10DA8CEB75C6D14C09C16C6C08E530FB5C02AE2872BD176FF90E7F7239836A74099737AC774C724ED445016827B6A7EF68CC805B0A6F42EBA2FF2D2B6A4FA44678D9D2187C394A479CA5B36011F434A2FD1A59B06EDA840F558943D90E727268448EAB601538E1D57BF18AE50A3A63D5105C4814FEA4F65C5A2BD5007B5A45995A762757B0B7EE043726881DBCA26CA06578B2E3DC06DE188153FEB80F0E798C34CF2E6230DB50072DBBE055EF4CB8F8E89F83FCC119138C531BB24F490C90DA49CF5CEBA383E5073502DA63E0EB6C07E611645EDD9BE7A8101C439A877AE8465445F17E0E665DC2E03A0459B67594DE4A2B4FB484616FD9DB0A5B593A50C4BDE3236E10D353D394C36811688BF41FA28226045B8CCC6E4D0F681B749FE0340D0AB52CF784383BE321A258048DE6971549B6549620E6A7B71D969E638ABF3A5E40CD19CCA7332B941D54661BF268C7799C37B32C639CD3C5B1CD2FE73B04282337945FEC5131FB8990B52EFEA62DC02E3408174B759E1DECF8A19398875E4DBC73BAD4369783FFED5B7CE954ADB3AED6D3DAA99746386EA51411EDE7D728CFF25BB33983950DD212D592C5C3E3FAE90E0115DB9351185065723CFA42EFE64242D105FAC50403DC35018E2E7BFABC7F868E4C7D34424BF42B14E42EE84CA911F5F3D466EC727D472BDC1D84BE1C7A4460A36966CCD8FEEC52AB551566AAD0F2C1B24AE259CD655B0AFBB2CC4BE38704499F9FEFFDE6AACFDC54F5FCD5123361C9C01C7BA5B52C128D6C3D596736CCC82E09CF7EB8FA06510E038ADB0F6C00234C3014C5D10DB6519EEC95DD9D19200930D9E5EC24F06D206399E492C10CA910A4A0CFAB970BD1BE66E2C1D9B705A1B7E3C01C443E54E0F10D9F890EF21C543138EA649759EAC899A32A3FAE1BCCA5F7522EB4D524C13AB36AE5EF2FAFE33545674CA0F70573FB0D674B14CA0CB873C33838558B7000692B288D70C09E3AD9E514D95B970911E2CC3C9A85179C2A39B8586640CF6F34D203DE9C10829DBE1BCCB34CF9C83D7344A73305DD9292CBF0160CA139FE5419CC012E69B741DCF35A3DE08822D27B9680C7E63F4FA0B824A7259E932BA573E172C81B46DC710B1F8161EC2D2B880D1748B5F08FF52FA8D6C94539A15EE5024E14712AE62B196675C7FB17C7802FB68F4C3C7888F9CE863EB82C3B9A840A9E1FE8BA0A440644A9262E7F924580F059EC0DD2CF948F4D77DC76FA360F6CBD022CE3502765AF333D79A4C2257AECB069116CE1DB6963A11401E93EEB8C54B03FECBFCC8C68B8E1C049B6D348FCBF52BA7FFB264C5EAD3D15D95EEE901DA2FB401FA0BFA8691B004A411D2925E479A05973B090AC060FCAC093AE9C42DB104420AAB012B55D5C67D26DBC5B8ABC65A189D4E7BB40DA12C121FC166BB1D73BC6625E87D42F8D633EF76F43E1F0BE4C6211C1922CED06685E895353FE67CD70219AC3BACD6EAD3C54B92985E5A12A805EB8FCDF31BDC1FED3C730D3D9D62C22E8F24A9D73D5895D92DB38D783F8EB736D809117B45C35EE8F40056D690637173785D1E14E0EA90FFA8C97864B63232D2AAED14C2415A00F84D954AF103014F676ADD1817AB83B851CC016311BF31333915ABBBD7EFD264CCF472FD99E86D535E1497885774D17F07D19E0CFDB00F7A6682E511052BE0BC1846D8DAB478977034D0CBC1DFC72FD7F68AB51C824FC88115DAAE9E203D5033294156FBFB6E0F400B7B8F0861DAF592D4936C483D5DBDC98B7A576CC9D26E54EAC4CF24FF91797D48AA1374772D7F0B9EC4AF5A76E231E2E847B7D91F8A6D89A78EB1F7A039C3F3E5C3714F2C62212382806D78424223B84615ED361C49AFDCBB92243555B0D777DFB8F00005232FA8C97916EDAD87AEB466EBCDA6150F0ACA969B2D21C2E5FE2D7C4177E622FEBCE6AACE0842386D29A17FAB242B3F926BD8700340CA7B4B5383200DE7C93A701CA22B9412AC2F1C2139B9D332FD585B8E6B1E0721090F64BF871A2D0C0B5E0A0391E2A0D1A9E9103BD08DE12749A6F6FF03D2597B1F3BF33819F9AB2EF83B0927445BD727F161279C6C2DD2B68C229BF233F8BCCDB4A61D866F2D4F705439F990A32A0BCE93360E798129D95F284B942ABD702081AB6D1813FBD52B58A421E96FC0A715EF134CB1297E2AB3C91E581E3CF97223481475D955DABF2D0B8BB5F134EC14D84F102C9C57CA4B90589C1C5250544C760EC6CE839AA85BC0681D744F716A0E08DA4C2201D3C7EC51492A0516C9CCA8F912B03CF60AEB07F4ADFCA22C43F234897A8F518271DA5AE07A8BC6CDA35A5A58FC991CCA18E59E4CDD1F15251823961E38A49815FE8C766B705DB01A92C7A13B7F68CE43F21F692EC29CD085E70CFF19C6CAE0D08B30A155855024BFC9D95C87A01666EAA44986ABCF2F9E146CE26D2C12BC816934D179D0FD0CC1E11B5BBCC03E56EB056B6196D4700C774752674861A402C1A94A0032C5642C68ABE913BDE12AAC92D335AC19326389CEC3C5BAD1735C0120B7EE10A0E34AF450A663856D5931F9195B5204CF22A426BD28A6E31234227F033F311BF0A826B7B4F6E216B63B3B184466AFFDE10DA3FD8EAAE99CF91BA078532A1ABD8680B50A5F4516E3DEF7CC3AD7BDAADF662EE3EEAF05F918A598F979A9512EB64BF3781DF8CD988403FF0570F21A6E09484950F6CEFA7AFAE4142058B39D715E0E4F620E026D187C5A3D8C05EA644F155AF31D6FDEB4313410AC7548C88B8CD9274D2B190F1B2ECCCBBD7DAC21C647038D2948DF2DC80AEA5E5923EBE72D9C726E6DE0A266A8E6B9AAC80E50C7D9AEF2E2E3919241A82739DDCD2CA4AFCF501E3500FD2EC421D9AEC0FB7A311ADAB51E213933791EA6F0557878056AE3AE35FC18428ADA90B518F7665F4E896EB78247B580DB4F2AA5FEF1483155E08683B90D8331EE8118FB4EC738A19243CFA72940FF692E736D0B5AE111350775F57A60CE87CBF19CC5677B1A3BE9E780D15E1D09160C4720713A4F74A362C99C85697586382BC54461B120D17977A09CE326803E055B1AA4FDD4BEE7CEC045BA9138A30E9B47DBED84040E983CA093159E1F3B58AD2E60E6664C801DD79A8C8E766F6FE79D72547BE2895C40A469C47E8AD31CF8F5BB5E79543830942289A5C099E89B2C723D8A72B2133C87A25F6257CA5E706EF1E46EA59EB42EEB9CD3D9AA7A20D0936F0EB8D4F8E51663434D8DAA10B5934638E49BF0B8208B7924BBF61A1AE8282AB13BFBC1A8F2DBC003B48F8A20EDEC06CE9914CE4EB1A5B916A36337E71C30AED4969987C3F56BF86F09E7353E194602161CC41705301E7CBC384EA3A15FAE91A17ED8E1B98AAA6669D3236885CC239F69DA39C2A7B358605FC2111E4B90C9674DDF9434832E0EE97171B78A2226C6099C0F5AE1F6E2A74B66F52EFA4C2CF3D0FF7B24DADA3A62790325C96B990DFADFD2AED3AB5535413C221D0C584A6D586BFDF0E13ACAB23EB2108D996EA4DD7E510C307040AF3110370D38CC72B91B72CAC1AE463F6BF174EE189CC125C9FABB1C59051DB1AD6443D93A8F83FD9E9C39A69C2D48A170BA0F2336C48D653A06BE3164636DDE839BBFD2AC9566F750B527CD911A17EAB10FAC460926DD0D49871E070BB84413A200C8EAD2E1C2F8642114EA9688540C57559DC1D3D325988E1C34E0D48F9E05F731C9104E83F39609293AA760A8D877856B68A08E99E6F5D31A4C19FB2C16B1415D1F6ED290C6C3889196ACB26018A68DE48316EDAD2FFDB783D87475EF0B3D23E91DC3CEB668BF71DC8616B32B7A308DAF553AC6C0B4BFAD25AB48166EA09D4BC36BDA8E34FF749A30278BF0479FBCCBC84DC6FF077D7776E4EB54F3A67D7CCAE3AA19C149B33658BB40751485229609E21E21BA6F0403E4AA5377" + } + ] + } + ] +} \ No newline at end of file diff --git a/test/jdk/sun/security/provider/acvp/data/ML-DSA-sigGen-FIPS204/internalProjection.json b/test/jdk/sun/security/provider/acvp/data/ML-DSA-sigGen-FIPS204/internalProjection.json new file mode 100644 index 00000000000..4088355c10e --- /dev/null +++ b/test/jdk/sun/security/provider/acvp/data/ML-DSA-sigGen-FIPS204/internalProjection.json @@ -0,0 +1,507 @@ +{ + "vsId": 42, + "algorithm": "ML-DSA", + "mode": "sigGen", + "revision": "FIPS204", + "isSample": true, + "testGroups": [ + { + "tgId": 1, + "testType": "AFT", + "parameterSet": "ML-DSA-44", + "deterministic": true, + "tests": [ + { + "tcId": 1, + "deferred": false, + "sk": "C1623CC91C677078CAC1FE857F7DC40809F390BA0D51BE7BFBAD9B55306FB2E1C5B3DE04C3E7FE3E3B24A41F45F5FDD3E73A72EAED3B3F57356483D7CC102953873F519C79E445456157FDE4EA5F64D613E5ECB8C6258484AFA36AC4D31AF313FC17A5835184087F04CBCB7AE63D41AB1685FA02D1A64F5D0F844F6FB5213DB1C0444190B48DDC04111AB824DC342C19164CCB242803018284C2416206650A280D2020900A83314CC62DE1824C128489E0844518A22D141628D19290D01805490010E284500CB409E11429D2220118A30D10B561249449C2201213B525CBA020DB148DC3280853B0498B34262045919A424910098C89200553A00C12430060C060E33869C4428CD984648C8009C3C844E1886520478060264601140EC1046ACC4045E444921921921AA15023074A022444903470C33250C9384D824249444042809060842811021660C242251C102EC034060BA74D81224C5C286C50A861009388534062A32671524268D42225D9106C08314C231385994608CCA265E222685C804904080013236994864C23A03014184DC0063114488C5AB0850922080A396DD29045242588890286CC18858886700B474CD02461DC86511B932CA38031033764092446811802503671E44624A41632C9868CC236700CC489038910601670428811414042A0A224D92831E344451A2548A30281C024701348224BA06003C38DE1184C59A64954A46810348D4B34815A00215C24018442685B088E920002DB42508A3071A39881811871E4A069A0180603203022C68C8212824A180561A4311402301494691840619A482919868051308414A30C01350D94362DCC220820368624280E623200531045A2388C1039498004465AA86C892682E2C601CA14652340704A246502882520B56508025124248EA42408018270D036804940211834681C862490241018239023406841384D1028718C4226D1B04099249214219140362C0B216689A268A23280014545A0320C89806492466DDA0802D0326E9BC808D2A249E0006D5A226A93B42020364E413669A1124C10A2901CC66D99B26C92442600004A1AC36C9C4221E2B66C58120409850420884D19A930D3347159128D024271C0140603A790D1806C00296D58B8011A29441A308124A58C82B070D2B60021270E48A809248709192585593462A4460C13160E8B844C4AC07154946D22235003244AD0808D83B644CB066289C250C8486811407242C409138268D0B66980B46D52097202586725A9DD16DFD951EFB6F6FE3231A2C471231B53057FD316DB0876691543D51B66FE1CD1ADF7A9A73C97CB74056DEB19AAAE8DAEC4EE2D512F19B5521DF260609A5F1DD23CA4EEBFECAEBC9CB0DD9D612D0AF491655C6B22A2AB52C6BDF09B8C05784D2BE8832EE184F7D7EEC0C15F06052258A5DD658C74DE50D9F351979A1B0E5D4C94832DEB34A09F08422C53BE60568F81F379B76F5C1F85A0E74434942DC524D85C26A8489C273643CDBE8662EE0D7EBE56C7E4AC93D84016D99C0C180D24B6B3A9234E60A01A83DD64446DE5DBF8AA770BDC66097BAD4261AC8878450653F21EC34CD3E6F1303C44A4D29C9E801D6E87DEF63D4D35F7516A992B788913829191A09E9526F8CBC361D6530EDA7EC9013AAC629177CCB744CAAA8ADAC376F0222B97997F273BF7098FC39A63B899CF35D2E9D397F0D2A49D320B03A9FFF21D98D307DFA94A328E04BEE9D58B77C53303779973495E3EDEE49BAB18E3634E23E363E1F46F087D8CFBBBA8A210661C6E790A6A6449E0CC2738DE05A034BFEDD377C0AB454D4F39FA6F4E91FDFCBE621D0AF8F84197B4762CAF6D5992643A16BE5626E52CC0ED24895F629B02D3CFC92E98BEFDB1DC80475FC9EA7A40EFBEF650355B03B76E7887BDBC2D4EF8FBCDD6D95E260FE6561F17C44E1E01F6712DD0E5F7EB89766AF3FC9370A7C168F64746FB8F744D146CA781C6C708A963EB90858930875223CA379428A71D8008C70264C87E420ECF17DC963D3D7E3C8F280A8716EB636FFB857E8AB92847CEAE7C77FD2970DA98D08E001AC9605BDD6A07885B330F04AF2DDDA3EE6E9314C012E3FB14358D67070014A728B6ED5006622052EB43B77EA3E5DDAA0BB1C1C6A973C8A455786A76A673B5F4BDD339258A7218F4A210F0BFA65B4A07EDBB199EE755B8F60CC001026107163EFCEFA41DF85065D46FBA9471513268517F06B5914F0C625F3C40DCFE428853BB58B10FC19C2685007AE56F42CD6730CB4A6283BA4AC4B40AD9D9B2FEA1C2916111C39BAF1430612E569227E2C6AEB11E0451AF81E308F3BD59CBE29D940E2CA1653F6D6C70CB1D3358392F2A97A34FB9BF05203FF507DA2041AFD85E4643A77CFA441963E282B7B2A5A2B8D293D036CB5143F3E01722E589840DFF12186B7D9799A3D74E99288FBCDB6D2CBAD2E5FD4B449AABE16A12924AEBD33AE5F61856EC66F44C0B09FAF4D0C20CD0C59D760368B335CDA9422C695653E06C0E839EA7FE946237B222F61F9F02B3AC916D030560B8ACD07A41E7D54C402FA7CF6983F09D3E46EE6A7F786FA39DC369E0EC4A30BF734C636DAE26D756AA781E40BD1530A0BDD4040AC17329DD6B90534491CB2AE4D179C2215CEB1F466E7D871D42FB21106834D72BBD656D836F09FDFF875B0029D9F3B50BE25BF05D6A2B0EE322E969247609E16D321CC928C3C7F9CAC3C9F53358D066EE23B52837FFDA6CE77D6235DA4FC06869BFFF3FBA209E8255EB6DE7DC40D0C89969DE0D33B5E54151378BD3021C2A8879BBACEF98AC7F542CEF27F8C639FDD3BF0A0194BCA92E46D6AB5C44C7CD960B1409A088304D807AE67442712E3F72171E06FBA8CE1CE2A6A15562F6BD6968D15339233C5BDD9A5A9796C1DF657F08BD90D1EB5126314B16324A63ED2E8486716B38DFDEC3B14BFE21B2D710BC4DF2ED5A45993DFA197E5B190BC11275E5D9B2BBDAD69E819E4FB4EC859B8C6D32D6F21A7CB35E62ABAC2892E0C6C76D6A416FE3E5CE80361204CDD30C584344C3E61BF91A239B626D8C57750CE0FC4BEAB5743F93083BA01FCF2A9B4CE04BB80AD8B3652C28F4A81D96ABF4716E8EB090817710AB2D052366391F1897C7512F221221B2EEAE39D36C24B919CEA2EA7EFC42CA4FD6FEF946BC241106F12FB82B12D947527723E32BF5029EF8E6C6EEC47C54FFA329D8832F43811EF85FF1B2133FB6240849D7435EA99DFA76EC12ACD6E7AD590889441FBAF7278F019849872D9F4A281764005CC34951CA11C2CD1CE31E51CD2C9EA8E4185274188718D56780DA3F7D234FF14422697B3B4B3936BB1607BB9F048A69A293C7C9DF377E380C9EF8B39990E6D7FFCD4FEAD58C1E5249EA58F9ACE95BEFC1A904B6BDC284577D8FB618278D1F132DE15E55A09FA1A558999298A02B3787C5E53B34EE7D017599CEAEFEF80AAE2953E1CEC97E880349C2AEDF507B3AC853EDD5C0D8081500DAA684A20CE3462E1338917748A2869C9708C5A282FB7D66CA0AADA519FC56874D158D8951BC66EDF57EAF987044C7349CAB7C91BEC1655F22006182084F1A65C356CA2AE8AEACE36D3C5EA966C23F047EA10F1681B679", + "message": "430B1F46E87DDE9A3D055A7D4D6AB1277B2DA6EDA642896412126391AA2B29AFD81C246EC839929F5C06749491DC4D81D58CC989D8500B6879E8807B1C3AA0B199EB599AEB86B344B77E3DB1AA034C938D80CB4BDCC29B31B710F57C7E491D99B71E97DD6FDA01A0D8A54C7481C2786F64FFC53AD358CF31C9C875ED278CEA03F2BF732372B19252BB9FA4ABF465FA2CFD1C08684D10582B410A8E012DBD407C5140D97CEE768C6D68124B2C84113B58C9A2AA67093B44CC3B6199FF1EFA6506CC28BD30BEC4CEA88411A491DD948DDB09ADFB92C40CA50E709840BC1F107E0CA428C111EC4505C5346E74AE4AB5647C1EB80F9C07092F8D39A975C4890317F9C0EF474110AB941949029BF39ADFB8E65CCAC0360A3EFCEB69D2BD805E4FC8D0620F8E039BC046DFEF1ADB03F5995FF62AD41352D479084EF3E302578B83332506918CFAD6E3BA701C94B0138DF0CF6C2948049274CE61EE0A64E756306273A02D68F3C405883F2F668820356812B2DA3A32B9FF23608DFA559183151221F83DCA18253FCA099FE24728F302C8B7808D7AF978299F3EB853A8BECDA46B8657598BE9ECE8A02DD4B25C593DDCB436B82335EF9C6A7B8426B701C66C9EBBFB3C8405A73881DAB57D1664F3AEC6F5BA19155D89A0A80B5D01C46BC79E1D4338A50B203397CD4B16ACD597A7C77C49917E9FE4B0D761065CB89C758498868B14BE2B6FF758745AFDC535EAA605C3F97648034D2A320264150278A7F1CB114B977C9D6BC1F29295CCCA16B23B7709D5608E4095E41D08B22AEC6289ED402414787062B0DA2387B6DEE76B32E42C51788B65E815E089BCF92D778F49A9707D37FCFBDF8CEF953A48A4201FA0173529BA360BFA6A77200F57FD5245146C2CD7FE8882670EE6878386D06036F0E1BA4B728CFB75806F05BA6409C514731B0BA8DA11015A63A8B5B5AB8C69703185191D12C5611F1407E8FFE3E50FC39C3310EF4091BC09FECC11D3AC107C696EE89F74CD6147830B4B3A971A0027747B62C528F6D858D1F9E67F59496C6B4E9E03FF0A598B26625B06C79863B5F07E265A40175E1A6D6EF3F900F3C4A28AD3E49D4D0B7E4ECEBB79244264474CCBFADA43FCD33F4FEBEB0F7E5928479F869D6A0FE52EB0CAC1232D7F674A057DEC4C2248934A40F5E2C9CBFDD53F71FC3BE06E48E13398ED426D8D3CC82118B7E8E5BDCA248380F4E64C427D1BF2384F60F6A07F01EE62AA1746CB143F26412547E7EF0E8FD1F2DC606F3643DEAF330D81CD6309465F9ED7F34D9B175FE1641D90212D4FFFB91CC300E7DFA0C555F7B35D2AF6A343D1467436EEC7AB95F2C34010FC99D66391377770A7DB8CD4D5C6BBF931092322741929F790E037318D6ADB74B4768C11F0E4674D18185DFB3D051725F93800CD38F58688AAC747F885908804D6CADAEDECB43131D75B18FBA2D4BED8D9BCC2156FB23F8F6378C622153EA8301300D0FCDEF1E2BB4E6F807784EA0171E95C372EC19B05A6C7B8DECE7080A057D29CE5A445A83410EB83B174590647424736A3B6967BCDF8A416A51202CE3F00E4D97DCC2C48A78D12CDA98E94A9BD6CCBE09DAF8085304F6911ECED3547DE9512461E16721322E4E6233BC7CA360A9004DA5AE064514603EFF0DF4E2D8EB04E9574C59F3AC14726C10100C688203F4960197CE696730AD7E558D7B939E3E6E7EAC4E70A7F6AAA80C1F1546E282B5CC7AA193213769B137C7F450AE5410817166F29F2E4E7E962932DF282A9F08A1DEF3E19C251F95611DDA9CFF4E2FED873439B45F8451B9AE06C6B2C698778BC4C742708BDB54CB35B686F0E7FC856CDBF977AFB663DFE44F7FCCE0E0555BE81EB28984BAFBD6FED3F0182F78A1396AF7B7081280864E5E4BFD7C52DA28BB5DE5FFA211678D13D41BF825F4B21BE1CBD29719ABA341E7B0C3F101CEDFE2F709E4DA4B5A6D0C021152AB546837024F4DCC4C45C132A038315A0F1D69AE768F70606D070169AE0818685C4BDB7341BFE15AA0455F535766FBEBB50875246A6DAE86C7B9F6F3A9FE01AB9928A99C13E6628431D41C1506381A63FAAB57BFB3B180F5D7FF59A434233EBC5A659B71CAE6970CC838D5FB638676216E3B16E8BA6C01349A7482AAF32ABD17DF7FAB8C69789F0194022BC4E62B6A6AAA4CDEF13B1E3BF5E1F4FA69F82B1EE3FDCC16DDE1106E3D2C41F6E661E33984DE7AD6021EAAD3E64D8C9CD7B5CB538AF88DB82FA048E5705EFDAC0EF479827EDCA0255BA60771A5EBC716C690CD3AC840FB6FF462063503D68C199050BFBD64533D94E093A47658822A25D54CBBFC689DFCBEB1DDD5BC6190B8F02C6FF3D001AC63729D35C8C50FAD3DCA2E67C5CCC6A8799420B159C7C5CACAB958B423964C489DAB1982A4E2222D700BA5AB772C4A11A44FF64018AF477D054217EAE28FB8E37595941FEE7AF87FD44960A144DB0CE2A44B33DC79B1EE31CAF80DAD620666D0ACEA76841EEE6CE81C6FF1F6D1027502EF89F1595065CDEC19B30E4B5314EFD64031B3B9DDFC6C95A4943247ADF7E4C93350C241ECA71260A454707B84017C5EB7AFFEB5DBB863A1CBDE0062C662308A2E824CDF6397863EF78F62319E2873B506F8A9EE82135B803025D962E609E006961EA3F7B67347518E70D9273893D79530F67CB678D6A8D28A0342BAF904BFC0A69AD575CDA4AB73AF22B52AE5D58372E0C26795CA96A16B8461AC61E6F68433ABCEFCBC16B857A89C475D1A322D34266539A17D485B8FA356EC3E154D37BAFC4CE75829FBE8BC823FAFF15A49F847C286F999A1F2C12B03E8F8A4C34A97588D91971279FFCB100EDB943E636F78ABFBAF88BCA5C55C935F6147E51BF798267E1350D2F5E3F74B339F6EFE86208C5BDE149C5B71056BEE748D06614AFEAF6DDA2A6EFFBB56B0880AF9B201B3C12055D292E3BB556240DD031C29A67BF244F59112BFB6865EEEC1DFE1CDB1E27F0A9E3372638FE4407099D0E54E9A188079C8BB9470BE6F63C83612D80BD60C21B251B64236E5CAF09A11C12F1A5E94F199DBC7C9E394C0B0E07A583E707E5241B8FB33E39BB26C31929F39316F4FDE206493566E17B51CE635420493176D8FD353206EF87F0994F039DF8F008AF602F50D7F9C0051B56227F3A2ED20B29611219FC4376234EB900093A81389ED00991272B739389F1F978A92A3E41F0A28985D697C01240875AC46A82B2FE94004CBD7B1E7594AE38A9DA0E84FE7E122482BB391538EB8E85AF9DC022CB32CC08FDA7A95165725EC29A0F824F97F0251BE636B57E0791A7F50EE190D45749472B29A674239AF95B373A40A6E0E09C674071186B125EF5AF72CB434AC0AA990341F063EBFE30963451491474B603733959A23A6D5B8A378F15A5A5B9CE4BA44BAEF6AA531AF5097ADE73F64AED0A541784119665F548FAEB447DE108AB74A74893017F0A1AF84AEF0730B555767B0CF6AE502E7693374D2E01C54C64E411AA93C96DC5FA010267B387299D4376FBB190E1C51A560871B559FC800D82ABD119A5732B50270BEDBCC8A636E7499149AE0E47F736FDB71EBF1995D1E8BDCB0EE96E732E8C2509F98717C3D174C78A4A2BE43DD89195408CD300505A219305809A1BFE7294BC2EECE6D98C768A8A1E0F74B665EE3D652AE8E008EBBB11F0D2148E4E5C93D7FE0190D27B3EBB7D2194BFBB624AF3A894CEF7AED571954D006824950A981F4ADA72BEAA0D820C5DD9BD519D39BB7915681F266DA66D49BDAB9E55879B953A7332F877DC5F5CC7BB3C9E1C1F2E41EB55EFC02A450B5142514F1E06D43E48FBF5DC80DF241169D5936432BFE9BE99DCB17293CF968A17F3111C884635EF2BEDFC87DBB80BF25EE9BF57B55CFE635FD99554F5FF2B4482D1948BD282FA282C48C0302348982E30A772BF14195CAC7FE39F836E6238EB1E1FD074E63B9AD0A8D37111087E47FE5D04B62DEB496353457BC76C53A2FC9D5AC9AE6A47F632E6D45E08786DA128464FF2266BFF92B5CD89176A19226F2EB14CDEB331C497F1836FB6C0A117ED6BAF95E9DB8254487B0DFA7301397AA29D95FF2065D851BD302B747AB47BA0AF408B51E4BBBF042ED1B2B604EEF4C266FE243261515778BC9451A8DFB025FA3212E868C3A078C7CFF65077DE94E50ED90A259FAFAEB398A94FF15C838EFA7F49904BEAFCCECD8C9ED4E014EA00C7AEF1D437DA306E8B7DFCE536912C169BAF0A3B78A643D6E210E5550E3B2BAF7EDFE01E721E3D05BAC1378EC1DFDEB2E2AC0F0BC368E0A8CC64F375DFEA2FC20CBDC515440FC2ABBBCEA3584E103BD686C5403EFE376D44F5242D35C9F9D35E1A869FFCB6657823EA0D4331ADD5CCFA99BD6EB3494A48ABBA7B7ABC32ACB8FF00512E1B0AD493F579898847E328C06FE05FE282F8D4AF48A1AAD0495AF1AC7354275A6D45AD5A7B3F6787F893EA558BC5D4ADDE1F0D265ABF73C86550D25C00821C3138B385448E3E02901E2E6EBC6A0F211CB6F22F8F865F0DF3893B987DD086B6674F5464ACE18B9F0EAE948667B2FC04FECEA3E2B7EA6B869D5F66D02D4DB124A59621B96E0DEFBF99A91AFA0CFD6D5A5968E62EF42B4C8908C3719BA0254929A9A183D50C566CE4FC970E047474490FFB07F576765AC5286B2E0FDBF1EC56A8AE8E6F560C69614FDF5C89BA53B8B7189E6388F7CDF7B819F78F3E6EA54C40865262BD2C8CE87284FEC36E2E73BDB8AA9CB5283272A90A6BBBFC3F7FED5F124E8BFD770B6254CDC695FBA0D8627315370E2CCDB89BCC84C96E20805AAF087F9E9BD1A189F4C6D66A6DC3FEF773788B3B57EF876CFEAE1F2C876CD239BE3B8A94F21350EDAE6C269698CC66BAF90B3641593F96399C71B2ECBE50F61B5D6F37D47DF702A9B9E47BED2824DEB19ADE7D7D8830A8F610088CF4BD0AD22A5A4FBA767D01987688BE710235A74129666FF7917B506A18E6B5D6166E8B682BE6B1946A4D4420926FF8CDF2488EABE71EFA7F2536B9DBEFBA08BB9E94086F55B1B991E18E6023E6952D4A563F2420A1536A1EDDE119E5779223CB712AB5C0BA4F0C176830FE523DD8603F1B316E128579E65454C2BE62C922C1DFE09DFB47D4497CC552AA9987A8BFE19C44E207397204686C718A0936145FC102B8A7111F74A421226AE016EDE658DE5DF9D3C28A247A87F2BC6FECF66CE7A6699880E0871CDB6F066D2CB3F9F625DC5E80751DBBC85982982E2EFAE3AB8F4F1EDA0D13C3B65FD2178E8AE4A712B521B7539785BB058176AB4396E6EFF2FD9052D4C6AF17DC30F50630233C3F05C62E151EECE13CE124E58A25F0F3AB65033ACAC9EA6E41CB3FA435D367DFEB0B9C9B37414CF32DC85A3C43087A578165C86D100E47DBA1FE7061111AAA961E67ED057C715974D3144912A58B6DB22D51BEDF6A8646D810190D91B61F0776DA00C8B0BAA7A83F4433F357E758F5AE8F278119908497E717A7AD25B09EA7C76B306A9A3AFCD9AE6B4F64016D5E80BD3FBE2F5EE673A7459B03AD9356148EA83461B66716346DBE85678C37C932EBC53B033A3F46DC28219880CFA8BB5E15F8862D345923BBC179FD763A0F943FC56BAB69F26C0C15D668BAD923D7AE6B35C07621768F9D972E2D6F46551D45E3FBBB577D13F01E8C1AFDBDD2F052E931C0529380F290FA1DE8BF5A11F82612943BAA2C0D086EBEC84069B271AC8656883F686C67B1808E27C860ECD1B95FF6CC6E6A5846DA29992CBA450081B8C37DD4911470EFF281FE94F10636A29B790E41EA6A342A5BE79CAF575FE9B0147F2EFE02874BC8A0E136A395B42E77D9F18CA4F61501E6C1805CDCDC10D0292593481F7E0F93281D0456EB51F6ABB7C379C028890F445D9FAC0D96AF68CDF6CC879A406CF2F0991916B33A72A193CF170B45AA079DB1BFD4B4126FA9AD3ED13FC98CE4C6C3C30923C8C53BCE1812B21BB644ED3A0CC0596C60032FFB1462DF5182528553AE865BF87FB7C7F61D1FD8E40D830B8D8F54924EDF934D1EBB88DA90BC59EEF1F6BF9FC2D17D8E9E0E39FFAD22EB84EFF39BAA70447B124E492D760E55D6301DCDFBCF9173FE293AC4D6CAF2E1964B32973067EC76BBECC65113C1FAB85375D92CE1436E1D1B205A88202B304264620B282E62CAAF5CFE1169EDAD9459B15BF0060C5744A17460F9FB164974CC55B3FFA71AAC13437BE58325E5E27E151C71D195F886F5630925D441A54695DF23F64C6BC3B0CA83F0E88D01BA4DC748A29F42AC2997C2A21EC258E430032C09E73E73AC2B21B55E1DFB2DBA281426620A0545D2507D1E96A3778C780FE77F1DA3B615E1B0D14DE8729229472E6619AB3B67CCAF21CFBFFD1F237E780927F147425B2142BF62CAD6B467A10F7B3DB922F095A0012EC179C4F8D5437AA8024F13A2A485E8890940DB69FB719B94B7D2629D277B593B94ECC744AA4CFF3D33D2250236C74DA057496BEFDB961B89BD6F44D581AD7A28524A6AF2253FD27530B7FF16FB5804FCA7E44BA2A3AB85FEDEED837DC130F533E8215B3AC3F584A2EC0E9B6194F97741EC050576E16349AD852DE8AAE2BF83CB1894107299F101AD5A2C05EC590B2CC698663C44FC0DC7F893F42BC5A2DECFF2FAF46CC1C00FA7294A0184A85CDDA2B1F38A89B1B17EC08555D082411A4CAEDED562C9FBBC1F512118EEC3BC931CC91636461151BDA454C4F029E01231BF170EBE17C526F3D8F705DC46560642B1AF36E3B401325A6CF59B88BCD4B3242D676FF4066E4252ADCA37786CBDB340DD81C5DD0540992F0B142C5A18D3BD1070719AF996E3C3768C3B234D303E6E9850B35C7AE52496C76106D7CAE4CF8ED01767B6DB5603F339FBAA019B08FA35E3DE1129A6A4D578264CF1FC8A1DBF218DD72B4865214DAA795A00505D4AE2B85E90F589065D65FC60CDD828007D4D3A4C084C7EC159C5D86817860CA03545FF74F17AD8570B2ADA55ECA12BFAB5C10067A086A34A57AAD8694C953137BBE901F8D3DEC27DB5DAD2AC96D56C312E25FE48BDC889373ED252B4F88D32DED6702B58D35A1FB40ABE2F2ABDE21CAA5FD0F67E7407A8", + "signature": "8C94308B9CAEA02AAFC29AB18EC01929A029D49F06F3BB4EA3110B1A9A415C77DF646A68302FFB4D853F8B9AFDD4D46B30ADA30213D763551A2FB98F690296DA77F08B3A1C2363EABE33DB1A891C331932EA22902277F44D68A0001D339C1108C3815A68DD0F7396119FB1DC888E10E3A95182E5A185E9CFB0F76CE84ABC199F7D58C7DE375F74EBC6B3338E3F6C51070336A1D513B3BF6FF4250313A52282D32DC616EA4B2B83A1861024AF9ABA17FE0159544800AEE0534511D9359415A66A6D79C2B3173B6281BFC3C96F07F944CEA0841DDEC3BA1ED9B337ECCBA219C675A13A1466463C128FF79E5C8F1BCE22220E1EBD1A071AEAA32E5506B553176309E1EF15AE7C15BD361EF6676046996132716B5391E9C0350C248A70A3552540963858FDDD3456FDA6707B99C120AFD925A47E4DA492DE65DD041E58A881A8E4125C3CAB474ED7D172F05FFAD0655FB7729AAC1C951AB05892198D713657936808A2E9795488F3F6E3183D0AB6B69B3484AC7B9F3C2AD65AAB9901992FAE9DC1E585D9CF7C71B4C7CEBB47EA07D534F9C869B114E3B0BF29ACC2CA60B91055E98643E7F16D3B4FB0477E3AF62C9BC5535565BAE2B8B276B33DFC50C3A14A62891435DB43DA2861154C654A4429ED865A373C28FF41F0C0ED11A1AB963838FF975EC9754C5FCAE3BAACB9ECDD920E365964DC321147A39653FE4B2F2D1EFBAF8D82B2198376C814FBCAEE96411B9E2D958D64AA731BBC1D6174D6EC139FDC73C9F3AB2886A92E0E82C700DD5A83F5EF0912ABE4CD30E0E3E9C8639C4B329B639DE189D8AAED2250F3BA74C381D6A4D333EDBEC2D1511B20A8144B42F0B5F674F4004F39CE1091BD431ABA3719D994893F4CF798F3CDFAEA9ED0AD5A3BF7DF0BF7E9E716CF2D3C72B17870780C724A0A0A2EED8E5CB4E8D15597DA311A4923BC8F6FDB64B9CCEF2C95BC026994ABA7C743F2FE83D5E771ACC2B6F8AEFCF6E1C7360767B9BF995778F95390C303C88FB81447EE993DDA266F031B9E4907811E3868F883AE4175D95C0B4C61092FDAFD2A41514408811828B3FF30150239C28C1E3E65631B178FA56D019BA08822C038F718BAA7A12FEF65C08A84E2E9D6E292774859574686AB024E2DAA6DEF1BED248EEAA02E0D28C73ECF803A250123636E6B8C642A10C3B8B3DA55706E17ED5EA96B80AA9D99E450513E16ACFE6A587896BF17254B4F420EED062775BD74CBC09ED7F925D10D34FBFB9EEBBEF6DC29ED87BDF01DD57EE8909BC0889BDA2AE430D8CF80E211EEA8C41DFCCE7DCD197352F60CAB92363FE4681DAA0C8F62ADD5FB1874151E1EBD8BC025A8341C46D335DED5293F012E7E9C2A8CA2234E1E5970E6C51C6711ED16494472205878ACCEEFC98850E3AEB99F10B6A07CC3A31CA742F1F93B4104496EEE8DBF0480AB395310ED09D8C7A117AD8A9F5C4A3050807A600613723555189F22ECB98F01ED8E69D113A03923B9C0C8889F094B30BC16792565F3CCF427EE9F0BF24AD436DB5C40E6FB66BC416009DF2F4D422A9C719585D47B95BF274063B64540B672A373073FF87291A62C7B9838446321B71356E7BB5EB096E9EB13B51A50EE891A2412E2117A5275DB0265889D74D9AB9FEE8AD1B039A0EF471F1410AAC97323E30DA2F91FF22D33DC9C8379211A404E32EB01786EA0CBD618821F710F093DD276F52A10416648E52879ED2A7FF6821EC49768D687984397D532C20B7050ADCB4330037D1EA1108B3A98ADFBB5457B05C8027E1E9433BCD89ACA8A84B802634C0759BA1AC6C144097E0EEB0A8E1A3A64E3E66A09D443E49ED53FA8FA8A295AEECB459D4CC32109EB999A4BC3CDD4D744EE7D9A73F07D763B8F80F4BFC63002CA3EAB87319EB69DF4A25FF1A7CDB72A74CDCD2E49B5A9D780ADDF902B9FC31F90AE788AFC954074E010B495885153DA0CDD15B26C6436D077A040165B6454A24B2E2162F9FF31B9C4B9199934A7A1FC78C68704B9BB784B0FA15A84AEA9E70D51000D7F335E450A026AA935533DF695F471739D9924D452B3C3D84DC597442A92E9A5C950C72B80138BD6154214720D8F19EA7E99328770A48069506F22869FC67129656E26E8E85242FB6E93B466B5277E8FB8B235A221A86A1191801B6B2EF236DCF910CE2FA399F8CEF28F148E977B762C8A828D57ED48C95711A479090255308196CD168B3C6C49777FF0E4D2319B1C44954E9A20C07E23F79CF1096DAF01ECEF4D47BA517554FCC1C6D139CD2F9F5754B61963DED55FA7638FE20041D4E689E6256A305AE0BF096EE9ADB9A76EBA46F5183575E8CF70CC6F69E5AD1DE54159E5339D818EDD92A2B9345AD759DB829C6BAB42398922788DAE97AF3F12A4354014F147A27E267495208978D736C632A5F0270C561353B27BE23CEAB57AD68D02F9AA94F301D3FCEF3E6E234BACE92F5D8BB1F975400D0D6B22F1347DB350CDBC71DB4519BBA4FB5C243A91BD0DA06C1155514E45184581815C7229AB66C921F2BC95655CED4A32D128FBB6B8BAFF83708CB49F69502D90BCEB6BD55DBDE19732098D1D1C1A26C74FE56DB0470C5E76BC6F4927A34D6BD84E57233E37127146295E5F19AABB77F9A6F90D702A58CB0EC0648AA54753AFE9140A9A60EF9814E43A916F07043819F09BA02A7A84525C34D3492C67ACA7C5489B72084CA7D1D5CF2A061394FAC77DCA111DAEBB9CF6C1B270A027F8D2EE04E0BB68D6BFA136640D04366864213F9EB3406A747B81EAD497416880A0CFF50F95784C044E58BC0839E6D36FCA9A45374A4059C812EC2B47AF8FC3A99540A62EF1C4B6D75FED8AFE7DCAF37832A02B3BC0339CF41A6F42733A584DA80A8CB328A5E6E59848DC23A0C0332F529853B138ABD0D3F2A8D2FEBC1D71E249E1FFED726E4664FC3020566BB769D4F3CBC8A735FC7309AFF545C3F87560BBE3D5016FC99CCBA9F5410030A86858F320DA5058DB5A188E68164E2349EE036B6904E5229920A7580206D3B75E89A8EED7ABF650D69494A13E83F37F841A4FB2A7F1BA538D40F84F25DBC0EC78DEC1B5F29F1A27198291365257819922F1A42104C721ABC95B2D610B0DB4576401E70B1760184DBC285EDDDD0788DEB108E824A21B8E98F0CD8A60557D183D16162F32C3D7C7353C3DC402A8B96EE8C5408A4D525517F76EF11238DA98E8069402FAA2A9A64350C4AE80F033A52209E66FC36F1802552292F706BB6B703C8E1FD66DF7DE25B4167EBF2E6F8189D8AE114460A1B0C0398CEE7BCE10D022833BEEFCA70D5BD174446CEA2C23DA0426303D45535C5F7E81838F93979DA4BFE71729373C426366787E899CA1ADB1C8D1E5EBED05315F646A798795ADBDDDE5EAFC1A4D6F7884929ADFE4E8EC0000000000000000000000000000000000001225333E" + }, + { + "tcId": 2, + "deferred": false, + "sk": "D9C4374117AAD1691D8CF8789E3E9544C379C5021B04E4BAEDF25FB2BF7225CC5530437B7D76D449CF4749DDDD18BED539BE7661D0803A4D7F379DFA3FB293A0B1A5F48C7818986FB379E41A921DF4726396F2DF788606A8C8C5B4E973968545A66B1467245A5A9140C7ADD5083090B658C7654630272C9A25C1CDAB4DB6521DD49641491664C1A06192B68420970153A825DB263249429018088C13289121236A0C022912276604194109360D52948812C93004209092142E22B52C24900DA086248C940D01A62D1B948D84A8300B868541902C00316D8A306203C47003B4440BA6201382515CA42489884403204A00338403B72498142A5888681C12611B116A18C16D5C8248A316815C1630898464C4320403A731892289602424A1464A490868E2B64101146E8B884012270A4A242C020522C320411028124A868C04358902B6259A244A8C008D0820882202320A3442E2308E9094900CA730C44046911261191708D0126A81308DA2204CA2165221134498063264046E23B461A1162A1383710323421C042A1C840D840886921070C0160E03198AD4A2811A484C53200919079080C49009400198A885583682931882A4184C530805D8C648E12272C3C80944348ECBC650523610D3A481D2244121412C8C028D52B4210A244C44B8641109099C440AC2380E9036082016645C30314220725C48440B3306A2C24CC0B689CB26801CC388D3306E1C9261223108E282680A1852639224E3322A093260C8C2842085485B240603830511850903246E61880509A851011500120592DAC8419B826D4832660C2121C3166882084221359059389020C20801824951808D101406010431938201CAA8858C44504B4680A3265022470ED028500CA60520928113232A409449103865DA808DE1208E40B401C844261B808501294651922403490452124090B48914294E21858500A565DC2012193584C02668544608DA82451346055BA808894090A346708C4410DC349049A86D110742242288DA388094364181188C4C086C09150E0BC4290C070083422841342D122508C40865C8B004121631C43430A044900C4822D8086EC918815420214C8821A49088CA320E209361C8B8605C04529228900045501C0829CB0646C0180A03232542004C11276E0B448D02A7110489005CA021881071D9A201D0028CA3B08C01252064102652946401116E8A002E0C05465A186D1418405C464C1A0732CCB820D28420C224710000628A1088DDBE8BE20BD3D9163E7CD8E081F70C5EA00959FDAC57B0D8DC10873C27E22EE17981C4E689700036D682BDBA68454F9B7C394C50CAC4DE6A8CC734850F95764B228134B9AF1E0BCE16A593EB6CFBE451620DBBBE3666E3B248FEB4E5306609AEAFC331E92965C0479F86FA1AD47F1C4A793B2904949ADC0B4FE939DBBCF05066CD0E230A8E485C26F41533BD744AC8E442CD1358991B0C11A90CA17697CA7130FBF44DDF626B7F4D2FEB954FDC64B1D3EC0B72AE26B90B5100C649BCC89172FCCE6558F28EC5B764DB91EBE971C7E881D879956210BE220D6607BD9EAE2C72C4B413D8DCEB01F386C0EB8A1F8EBCB4053B6BCC383303DA64635B9CE7892662F8680905429617EAE18C58DE9380FB69F558FA1B706733A1B7B324B92FCDAB07438F020F0449A70B8F602B5A9702C771B2B3A4A906B2D27CBD824AC5A207A2FFFF1FF1FAC38EB85DC30F3F17C799A1B8E71D7A69D1D5046C73AFC04DA3D1F6487D1CD41C4075E7A6BAA11048273A416B86578047057C6027F89E695C66A6880AC8053D5FC6360353F336F282281C32484840B3D7779A2B59DF42467C42100D382530A74613E147EF863FAC5CEE1522871427739EDD9E089C1327E10F39ABA9F27E66E074200DDCBD31C7CAEE7D4967D8DAF612AA0B5123A1FFD4F8EB379CB8097C3A49E7F45ED5872AC1A579F41D1A8B9AB4F1D0946A9AD6C2FF429385DBFAAF002E96D85DCC93978115CF1BBD5F69A54B3AEC88FA74EBB175ED930A5E47EF09138C0986811946388D4452AF4A07A1E8983333340F9FAF033A87C56855C8975471DEA335CE0E0A57D36E43E1FF5DAF699A5258DD22FBEA92C7F7D7DA258D250717A6EDC2082DDA972A36CFA6552F4397F502BA040145207F874D4E5B07222581646132A5CF5D5DE59F347056F5A52BD89C75B7EB3D48E2326C02AFA1822716A4B4D109F0DA405380BCAE4C7C673ABEB898DD21936195D3F3ADB1B3F042016ABFAB2670A977D1729A605F201DB816606DB7D73B1906C9C4A49C1687460E2093B51ED68F7C548F84C01372CB97FA557B2D7514355E4D0F77D22C0F245B6DEE89982F7C2DF3EE89AECAD428C9C6CE962BCF6DC898EA7AF0A0065EB4477771E97DD30DECF8F41B1B0BCB5DD84C20F502D894710F97B8E93A6ED694AC69A43B6E20F7FA885997D23DB912F1C5336EE2050A96EF1F4CBE9BB50F977C9035FDA05E063928069394C18393E988F715E64F02CE6C3A70AFD2403E3606721EBCA72E9D4A63E3E11707604587301CFC4D461EE07D337A9A1C74870B67457C22D9E4EFB60A5F6D405A184F972BA07CA8D702160BB598104B35F0C0DBC4105E3714A32A789C3C19E3CE8D19AB71FF69514F2CD7C488D6F999625405E9702C38EB3C5B50F53766BF51BA14015FFA2EDAF83B13CAA06060A30C9D3D44BDA226905C357384D027E05B3C0837C246629A070AECBE608E743E330ED18BA3F8DEB7F09F61808C527C5695C4F3FB8DD5F376EF656EC4AADBB21234E85C39CBB37910ED7A9E12D04AF813D3D87A7FCA55CE6F86A53C6432F9C99DD23AC297B217DE1079EE21F467EF700965A326C82CDC548084EBC5F9D0C3B48F75771ACC1C3C45A70388A0C65764829274062989F7A209B71D4051F26897C8FEB6AC847763463A0858B0B2F9CEC93454C35ECD5CCB9AB987B1957849E1EB610D2636FA7BBD08193A69227A34FF2BBAE787DE0F9EC719A3DD04018D3F4DAA2047C569C6B5BA52785FB44F24DC548BEFF25B3E51C24880469BB9D0749121C039BD7FB831D098B8DDF213023476DABCBBC778393F02B4077B57D392AFFA2215587D934025D148F435C1B49998C937BA3D0E7463C526D08DA8C67A2C305934E82B648D4A8CC3EC162E56A42575E944CB711C3AB0474EBECD829CA8E678C10782A284485F3D96A1DB852FEB36BC1748EAD20A342436FE63124C161183DB1BF5CDDC1436999764010C2F57E55BAE6788A7D653ABD03989A6F515DB7A76A77CF3E282E83FEBAA8326B9ADFA176685FFA1C6F9ECFEEF97953685EF2DBE311BA25E2D76F3950E005E4117585709447FEF5F1ED198B98DBA256B4BD2A430D7CDE4052A36D87905A8124AD317ED4DF338CBD1CF26BD02680944226BFAB3DE9149CF19C2519F639F9068825C0BEC1A7572C70B948BBCC290B95B0BF5106A8B2CA8FBF9CE34599E633EBA37254C250438218AB1D2A3EAA0C148AF2CBA48DCEDB11FA3B5D873BD161D24C65CF7DA109D1B8CA296071FF706E5666D66ED10E5B1FD78D2F993F76DA41EE8A9299D33C2ADC8303EC322449EEDA11FF245D03048E5701C7763D545EBCF540CC2CB0E3A06265F380C622FECEE4E", + "message": "8F69A33C4CB9627BF27401D4A1BC131D28AD0E2E5A317CE983BA2CC7465861A414FB72745E4DA31C0E04576DFE0D0EE834A1EE323D5A0901DD0189EFD6718049E2FFE1AFA548BE16E04B8963325AEB0CA90238C7A243A3F6AA17BC1D63836898688AC8E919B8EB6D689075E050B4189A1FEC723E0AE8D4AAE9FB6790B527A7552CDA174BF40BF91C4142B076ED8CF112A871450AD994737FD5BCF513D42DB01906636D42C6C10B64F74BD37D68A966DE0F3BBE6541AEB9991DDD0C0070F16715C01820546A014E66D786B8922E905DE2BC65053C42703227B7D8431427E3EBB0DD010DC58C2343147700D673D5707160F234E35BA24516CEDEAC77AE15C667AEFA8E029FF14F169FC0A781593E11D42E8659DA8E91E53EE0A1FF15A3C203BBF9591584A99FF8BACDC37541E126B8CDF3503AB2D1BFC0C37F38A298AB1DDA150288A8110C052469382A9A4F5565778339AB327DD80644A26B218ACE0830E56813CAA658A9F17826CD12B815612BE40906ABC89185EDDFA8E05102842CF27BF040FC7B396E7E2E023CB86AB7AE25F36DA6B6C0842126658E0315D6D8F4B5DF38CA663B55998ABFC72FE9B7EB7CE3BEB72AF73A0B2A45577C5215C42E465EECF4A4E69B6DDC1E65E0C1EBCA", + "signature": "3639297077C2F61950A09D4AE55408D1822CBA6133C788347C1881F8E02400B683B012EF2D9EEBDB65029BCC9EECAD9881BDD4FFBCE8FB50242D9081E2C8C791577C800986BD7A03A3817A06E4D6609E288B3849AEFA840EB7B69C589AACF26B6332DF4210F3AB0E8DF14F918848B907FE9B09CFB91F32871B0ACDE0ECAB8915A0621CEDB4A591B1A6EC4B4B9F83F432A9B576D9E5D40AA57D24D408135E72C77281515A3783C8F3397C9E7D26B4543A528BFC1FE91965142D52FFFD2A26470EB821435914D346EC8765539D39083D743320FEDDBE31E08EA0E4ECCF74B231934B5757D460E5B79D16758F4A56E59C166C7F9F1BF6C1DEAF5478E97C8F55000475D523456724390D94AE9F5C4B3F96E86F1932412D740D04D1851560476D50D7B97B080BBDBDB7A347197F2ECE6603B0296C8833B5DDB95BDE239245F1BF27A7584F5B9243D906E4880CDAE82E5A7F1A71A7DF8AF9FC41C0FB4B63CD356CF5F36F94D20592BA58D1FCA9D354B358AE5423D7D5FCCEB05B831024EDC7DB64D6C9E45454790F8B4239BEA02983C5827E4D08E8DF3F795D46CBDE5D4955A6AF2A6E0D101CDF43F43D7F5DCB829A5A79881EC903C1B8522CCA5D8D4722FE29B36BA0C571DADDBAAABFD48DAC4D2603D768A92D8ECFAD5264A9081A74A2F7FD635220EC8A95695F2264075DCC05F69084EB8336588CDBD58CA028E02A2756C8A3081E720F281172F43194D8ACAD2F61F2DD4F01C235694FC20921EDCAFB9AFAC8FFB1A234FF35E68AD90086CDEF922C47C84ABB31112C6AD6CFFE0DA11C1999483609EA98573217C28B512ABDBA6F7A7E69FB8944D0B0C4B9CE7AAB52BB558A5411671385FE36903D148D11DE00A9007929094C54ADE5E9BA60AEE35D5014C7293FAD0158D69FA08E2CCFFBE2AD99C66A2FD2382E6D1C355481248F53A5130EB4743DF24EC048196CE056A7EB032FBF6FD07D12C153D06BFAC06C1AB23147F8139DDE1C00F9A9C6347456C148245E3C94F2C012284190CC3EB04ED006AAC3DD2F08D6D0AD54EF507D7E80671F12A3E4DE2136B6ECF02EDD28E75B985F73841F600EEB64F8E5CC101756AD7794DC14D187237BC82CF6531583DE7B0F60275E63976296A0A02E67298C20FC64A1A8B1CCECAD1DFEAD996A47E9B6DA0079AEB435FA40A53A4C0D565AF713DCDC8D4F16CAB00263058A9CA1F276A39172FABE34FD75422E64F23B2715B395C73F2335B6E4EE7E5BA8E2DE18EFA39FF1B0CD8C0C6F5618C971213E94BF2B9B18E05BDFDFD9DFD88CE24B392BE1ECAB51B95C0BBD9513F881DA789C57B1EEC8C53EE9CD4FAD5E7526B1F1462AD88F180243774B91A9CB219D4CF9730E682E2C6C8EB160131D3AED3D3B3E64EF6A1AD7ADE7048A0CCCB67852971330A62223A89733E06615508029823D397EFE221B35896C18E9BB08140C464F8466190CFD8B0F09E6EF46BC14753974AFA2CE926EB6B02F4EB25CFAE70C77A865CCAE8FF2415C0D81A82F3807A4BF61F6EFA9BA4A16D14E3169C2ED86B50059880D07897A67C882E9B10450DE3978ECD78EE2A3C2B2BD51544FE65ABB7909FE439355530D44244052F2154279B6395E77FF1B288103357C5F83177794D517B0D8A368C9B008838AA4139F1BD10E3ECAD45748804F45122F3384A1A2D541BB8B9FE3C478EC0AFD81EF69FB2A42CC9059CBBEF42633139C342627A604AD07D09AB962E7C1CD2E1F1FBAA633E00AC1EECD29B5324DDA5F273154E7E9D0AD3F78C6AA08E92C77BBA7CF202B94377872146C60E9384830DA573CD7E3BE362267CB74BCDE63FA708E15F5933E27117037F6C35F91D03DA285222FD3F29C440DE820C89F6F37C250F82F0B20E69D728A680095B59AF058A06E46CA75B6BB1E2B0E14D2C9C4705A080B9B826E2F1F96CAC70A902894B416C68171B7388F4FD6BFC4BCF7A6745F3AC83B8A31F869C64F67C5600F35202D3F45E697F46DB1991AEA695443C79810796CF0C0150A83E24B2DA00DC72364CD34C2BF6A9F1EC4C39BE42F8A7E9DCC3BB6D0BB6198FC08C9743335262D996C489C460DA87FF75D4B75367C17A466AE08D24D736EA63A6B0087041426C03BC94BA143264086C94B4C8A3F6B7914CE40EB7FEB876CF16A2F12C66AE3EC3B57A93866F63E56666AC7B59D3C78536D77F73E9E9BEF9899EF390E8BDA6E2AD5CAC671153C348C804F65408309A08B2E78FE79F014ACD99766B383E5869F3A3562B4A312CEFB3D8F5B90FE769365E1640520C817B6A3A26734F406D104CB7AC9B6DCE371AE3D7D10E265EA370C0C78D0685F9BE4B3E9E097A334F53E47C016215719A5A25EAFCA799BD13F5B23C63CF372972F5588B8A125AAC58A0ADF961A6D0A2646F9520DF6699B67293ACE799C784CFF813CD508317ECF90726D638A13AFE574BAF3D2E9F39103DC199510AE4B28FED016993FB16CBA627C820F4B76227044F39AF0B8222E1D387C7005080E5CC216E22AFB8F591074938A3510AEF62D18D8CBC9978A8284DDEC00F7BD3C75F724540174416CFEF71D5BE602FEAAC4EDABCB72F7252471F4A3D01A5D1BD82F98A7BAF66CD6193E17499741810B68B1B066C827FF18763CC557946FE1B60C706606F7CE607047F18D93593A7859BD669642FA74EF569C31F811AFEA327962E02FED620011AC0B96C6CA3AD9120EF1C3DB3C9EC43E7C4E1A255C822EBDBD71080C103EAFF847973B30AD88C40CDEA8E19750BAD8E298D8B0569CF6D3F99DCA585B418355ED039B585F9F829DFD4460A748083ED38C6DD9A93C34447AF47B339C5621D908838469326D318C41ECF288B16C62040EC628DEA4C29DE18F6BD3793BE057B52BD0AE44EC5AB575383FCF35EA91E74ED011792C415934B16CE8D4E9C2416C1C79C1C8B09DC94E005DE0D9B8BFDD07552140D3EAC45EBBBE9E164BFA885940702281DC14142E236AB3307EED9A2F4A88AF5FB61D771ACC92B2306B08F5D8F740C3F10BFD5368A744BB6590AC29295085EC4DA93C508AE62AB59E2390C1EB5B2D5976C55DB166B9D1FCA8A91FCD234EA2B5895DC5228CA981C630195FB832938ED7BD73353EA9771ADD724BAB7AAB17CA622F4B9FFFD6878E7759DC98C0F5F57A5F59132AC552FF4575104CDAF00FC6B73F460AB4F3E06861EFDF5DB48345F35A00F5DFDEE36A49C2150547036544F0DBCA21FC5B41D36D4823B2917432366F97BC0B0AE524715293C6FFF6DC57FCC9A7806C7ACEA749193CA1FD24266CCF42402C565F488CDD0794CA7BE9A78E9DCF4A2BC2C83024C0C58876B2921A1A5203152E4F73757A9AA4E4E9EEF103273C44454D5069737892B4C8D1111E313637445D7C8292A1B4B7D8EC060B3B444D646B6D85888A969BA0DAE1F20000000000000000000000000000000000000000000D1B2A3B" + }, + { + "tcId": 3, + "deferred": false, + "sk": "B7682E0C424BE42ED48F21AB5AB57FD47BED455A6853B3C166D2AECE055EAAD23EA1D186FD4F24BF1F8D910CFABA719AAF8714606159023E27B81BFDE79B4C21F2E28722215C01B06BE6835163253464EFAA9CDD2150EC59085A32C2BD5D840DE568E12A825CAB4E5CC6CA768D632BD6780CB532522953FA3D774AEE03E2D76748206C49384D81406A9B82201334601346214CB0419C228089C88C5C16690A10022006715A308510102210B44C0A042A8802425B202064042D1BB2850B3292C93461634488D900111C092ED42884CC484D5440440A318AC0B08D1B024D04164DD9B44CE1B01124A72004A671E3106514A74581062C193786E04291600242CAC40C93124E981010A3226262982990806099C88418398019018A2140828C066D13B929C384659B82451405910B114058484A00210663942911358AC1420DC8A484D8344404908921C408123160809000494010CBC4911C041223384E14364D633806032720A006524924850A410693A804E4968CA284510492609482242214640AB20D89A44821294A8C246D511666048949D02685D38688A2100E0CB028DC3889C3C88913B540401012E3C48992081241A608E43425E31645603022E312691A824011412684286DD1A6811239825028692200249908401B124908056D0AC58111352A04A1909224095B34281A2408DC984DD300300222724C145182C8241AB040D1B849CBC26DDB9411D8020E0B2708A4266490A624C28085140726C342819842068A0092D91600CC224A21B20C53067100A37121C14C98B42021818C99004242086E8C964C03086D23017100004CD0B61049385191A6040941261B2891C396704C0646E03421A398010C3784C31248D1C44DA22029E0366E54846D230862608404C3A88CC34021C9A8605C94518B16309BA0499310891B87856394854A24918C228CE4388802434424346910A948C80288E0A68D613081E00269E0440A2187919A082809A165DBB24852080E2180711B16250A338802368004138CC018415A020591B8699B3250989611D406525B820D50B46DDC884809102EA0284D0300242031640C382042180D91925103C5291145109C98315CC80D60108C10220511B12CDC366492383183444DD1802521055153185141328499444C2390505494201B830DC3168A48A29064880019A18CD42208520644992245E2360AE404851C4648C2B8814C2822CB38218124084188884802409CA624C184699B360E58B64181046501E3E9D13414F71537E2AB58DE666A17ECB001FF8EAAB0141BEBDA328E8C7EC44F552DC00A1261A83DAB59F8CC4392EF5F14BD88386694EF93223BBA9EC78A67D5FC9A01AAFB16F4E1C80BA31229514DC1637CD43ECBDF85BDE63F6A2A17E6A1BEBEFA27EAFF596624B30DDF797120E52ED396371C1B143C27EA83BE66C9C2BAB70EB1FFA60CB818B9D159C0C7B02734A91200C2282403D316F6136B0BD3E6FFD328DAD5F257B316BB76D6B3317FC3D7808CA0A8C3A7BDE19A2988B994CC13C13D1E3C9790BA3239FF91081CA6F21AC9684D4189BCD387B0E70EFBCF09B8924C5D9385E1006CA7E153B7CE207B920671065FF7A9AFAEA91DC64484A857563C9E90D74237DC453A554D7ED88CAD9EA30F0A49E0B835560B4D7741FD1B96EB6EDC6BB7201DAF2499623683B672956FDD51E14EA62504421AEDAA2C3527BF7AE8DB52D35D673F5E45918C833FAC8482DB27001C766DA36B3E8B0B24616E749E38807F3E646761E4C998E04D53FC98B7D636871D5719EEAA6BE67D20565D7C120E210A67C12B03571B9BB450A710CF6986D961BAA5A9F92FB33E61D605CF0E4FF4C689D535DF5FEECC5D5BABBC22975256B9834143A5DCB903308B18D7503A2EA8CB8B8ECAFA6BE70BE6779B9FCBF3984830B72C513CB150C5529ABE6EEF29E24291756BE46DE9796714A940BCF0AD21721247EA5449946D987DF5E70326B15CBE2C439388E64480CE84EB9063A4213B58C7223FC06A5B618C3BFCA18A4E46205DD963CA8E2C86712D75A4582668E955D821AC4A7C136D7F31C7CA4E7B8AF187B2C6F4366CD11996BE298D71B9E6C3D6C9DC47826F58935CC8EC353C27B3827C3065165B3645032D3013036690D9232FBEA4FDF57D035D99FA9CDD8697BEBE97D2B9DA476BCFA7BF167A1FC66BB1C5F2348E86F3F61432600D231A593AF2FA3CEEDF7F4417CC0E75023054E21841DD19D53D3547D3481D76401E66FE238D68A5381F98E0F6C455B852CF09A1B17343336FE25DF426A0FD29CDC00F207402C7F96668881EECBE43A4C1DA9B86AC50FC6B3E2C74D244848FABF414BD7B3BAECDC750BF2E58033010B8944991D6CBE7E5468C168FEA69B167B566078673BB06A035BFDE64F66C50616E9B3419394E71F8AAAA636634F51F588D3E012A40E1C9A787044596C51A82D77EBAE4FEB448C919601A183E6A847E605CE142B5D56A0417F20356E7E1A35FE18E94188155E3867BBDC7CD04069D1DC4B3EB8C9AA64F7F955C7251667441E77D7C818A8F49496F1141E829C51074D3D38AF41FAF4C77A56D05296B034913A253536702A21B77DCD3137BA26C413461CDCD413296C9291F1CA056EC0DF02FB888654DC54192EA30631F8F9C8B4921A1DC2AFF4CA8C350DAB4234D9151078DB0EB340CC3754E48012E8C21C84B410FBAB3134DBEC37805E723E5C08F1AB371624AEC29A1885AAA7915497220DA11EADDFC7D9FCFD51D0765515C16273F978BE26CD6D7F8627587F82F3BF4EC25C4263DE24B3D4A0839F7AFF0C4D16A3DA89D1F23678FBC23F475B18B523F115CEC9D59928ACDC7772FB39B0F44A77E15C7D786317CFF38DFA9222FD53470AA15061EC8A9D6CFEFA5C32A60B29FD1265B10C78625B2634158C3131727688D7837AC25BCD90FA8EB272B7B3B232E8259FDE162813ABE082BB0BA76B62DECB230310DE5AD36BF3F1AF145660FBAC027D58D86B03E2E1B5ACCF81B6252B90E1B9E85FF41FCAF60E308E5FD114B63CC26262B4A5031E654B673B23464318FB55785C5B707D901E2BE7A3C7E2CC4BE5EAD3CCEA165A577680183A1E05A2FBAC4EABA9022F9A43A53CFC61E3236652842ACE2C8B4249523BF57D6404EA8B247B0058FF1AE98CDD79164B6445A80F31C427EE1BA04256F0833E752DEE5B5224317919242A7E8CFD0791637D3D3873768FACBA6DA65BD8B4177E6F634CBAD83A94F2CC6500A0A5829C9BDB3849FBCFD517A80CE0D8411948791D0E5927BD13EEC09C4FA2B2453D9CE1BA10769B067D8D92547E8BA2F6103D066792655BE8C05AF1628099D2617BF2BBC2324DC6E3E36C9F32597A13FC45C1E974B00FC53009716EAC9FF0FAC4C6B87DC59B4908631A6A21FD5E156D476E438872D93FE112AABAF99A6952959FD9FFD7C3C25E11AA011333FAED86DA99A6BCEF75E4F341BBDC0E181B5A2A22E9CA06BD4F9EDB955CC44F11C6D2E23378B94BAF0509DF55E8D05C4F8DE0B4FDA82AFE7450A0A3E5D8DE82368F1390D5696FF19D1C4F265EF051CAA0E68E336DAF98698FCE2472A6B580E1F30BFA7B385D8F4DBF063FA79E412756ED83668D5C3EFB0FF4A59FE6189D1B70EC45C7B", + "message": "5DE75924D05BBEF6B34CEB195AE3349EB621187051B1EF95A779B99A3E0F729994BD19C7D1172418BBD3E015B20699DD09D8BFB0A343F477AE2A3BF5737AC994619D1FF3C13E7676D1BCB446289DBFE36E2D1508A3D437B4B0DA06478DF6D4701909B272E9070B1FE06385DBF8A552B471C8EB48EAE39D141009FBCC5D57D95697ACEB7B5231AB5976FFEC41E947BEACA7639F664C6C1D058505A49561811ECDA46E23B651F918112F38B407E82219B49E5C4E7C247DC4BA633C746B42DB912B07D56302FC5C08F5E0C3E311268041F970E670F3AD26A207701F1359EEF9D4134ADB882A1C899B0E4FFBA2C68535D97796636417EEDC0790FF808C976B57F0838A694700F8D75DD4FE5ECFB4B6A188FCB77FB1DF7C5F7C91DC81017A5E9A6D1EAF59680D3291F74743E1776A6DE31101FAEA31D876A0DDF3777A91EF1EA0B575C83C97C7A283E7E958287F5A52F30B6E70201A1410355B47210B911A7A4F6FC23BC95D7951822115FE410ED2E7FEFE08940B3F8E63F13F26B6E949C498E62A66FA675850FB9F7AAFAF7D054F5C12306ACF2900A5B66A29931A5919CB31D19304916AE41869CE3294B0F5F88D845A7FCFB57B952BEABCD1DF7FC11E2D342AA5A70A8AA9DBE1E6E66555EA618849A95439864DF6D7789D8E3B46C6FE4F33877F127D4136D993061DAB530EC979F818A57E1052B5B33D22E941643DE2FF9239741F6459A0EE28658C3C0033FA62DFF37928C59189A7A7E36B1E305F3E1F421EDF4D71A96C71406A0F9AFA5C96A9411AA1A35D241D7186E5C8D0CAE15938FF869897DC3B7D8196D64DE202108D6FB436FF89983EA6DBB5BC88EE2A02488E4D12AA87CC4BDF41A339E10300D32E0FD4F3D3136FA64BA90D64E2BC7C20BA77DA4DB5311F616288496F2FE3E7B3409879050FE57A23DB0344CAE82ED329B0D31DC9B7406CA715E3D84E364BA98F73F693B6E62DF4D741928D21D934453BD67FBBD9725BAAD34E5F3204BDBBB569251DFE2D69A9A96BAD90256213BB0747E7950AEBB4CEAC7224FD5F8F99A16866F5A1DCE07C2CD1E06B70A81FCECED0AEEECBA62521AA0A01FD7B5A3A8A14DB55AFF331E469F5138DBB2B96BFD0AAEE7F38EAA375F71759268546D590BA8C0C022F78CABC4E089992409D3D7BD19048D30B15C796170BCD7AAF7FED0387542BF8A6674F197EF994FF81BB80C59208A572495DE4E584B36A7E9149B5E2081A4DC162CF8376029231EFFB4B4981895FC36562F51DD5158DC82ADE52ABB0E98F4BCB3C0A24566D07686732FA734CDD48D03DF99F7253E589CB8725F17E6BF964E96F9827CA5A9DBD04D448025EE014EE1B5DBDA514D3FEE4F20664C11371DCB16991DA883BF9A68EE30D727137D7902F4839635B1C63F6C4F7D42070E880CA774680DAEF105D277EB8D9090A98F6B813774D42DEE922314480EBE562775F68ED180B67EFEB077D8B174C7D4DA877B0DD3698CF506EE382AE6FC6F68EE93ECA3627B28248D3EEAC469EB0C26BD1A10A7779CEA142958F9F9A533BDE974E1B3CD9B74FEEB2EE29ACD7DB65E00D7ED6E94E5E44A925188285166570727FC687AC7EBE4042BAEF68BC23F4B9C51BA5040BC6BBA41FFA9AFB1AFA09DE1BAA4DA091A08086128A9CA5F27D3F4420327C8FF4801BBF2057282D05D1CBDE60E1E6FB6715EC41AA9A852686DCFC47279FCCE5D86ABF02A6B5B57DE22B2097B12381EEC567E4ED1855F9B482C174D6D40A5825687C02E1D0AB634C020497A44E07E8FBB2D05280C53562DB4C90AE0901B88179D06F9F991E33BF17E7A9227A30454430CB768F56842995081520158FC34BF5257EC8EA9338B3714126D6A95A3D77FB61207154F6DD0041BB03D84D8F75E6EE910460F22CA765A2206D6C56C6E498E063B08B76B1DDF98571F492F9DBD3DEAE7D9C8EF21EDBABED962331F06371364DFCB3216E24638A20F77FCDD894FCC5525DD0C8FC329494841EAFD93CFDF0053FCC27F5A1263C7F4599C186B35FCA9C6F5F2FE169B00275F15447AAA3A823E27E322CA2316B25823F3A79FFA785E9CBC953815FE06F376B6F5860C6A87CB9BE98690C9C2A93EFF1BF1050A01C72CD521BEF265D66BC4B8ACE5736215DE59290DA957175D704BBEFB0E81C2CF906C3A579BEAC3A0C945409DEE4A1E683A0DADB3C4AA7E0174710C72A33F1BBC62A6E6F3EB9C138C0CEDA817688BCE8CCE523A2A4E2566775015F3BF66C09E716CA929BCC6DCBA7427EBD93B21CE276820734331B078558C63ADD096004B67E618D9E58FF3FEF00183EAA293A1DA2520BC03FADEB6A74B52292DBBC6EE4E5ECA8F8B0556FED36C2B41F9D8FBDA8EAA1F74BED46F05E7712E20E463502A420B6CE67D125BE999EF906300C627C57C468C8DD608F9AB354791E6FEF0EE63DF3C1821AE78111B27E57DA88FA44D89581D11C2C72F565A3D0B5E8E2D83DF178810075E5F8FD29E1953BD2C6326B693C5CF6ACE086673D69A67A181062A6ED511E0CF36381358C2DB2A394B05E0C1EE9C54B89C68E10857463F71A842BDB8429EB31D250542F88E6BD3BF10BDCA160C0FF44EBE7D0D982F15C4892091B4A69A3AE7051BECD1D2DB132599F1101E2BCF60136CE947F339A3DEF9F6D81E1BA3F5D4CF2ED989861F7CED86B1A6A167291CACA74C45BA7B5969C09EA20C4EB061D4CC4B68392AC866AC591764A16D0A42710645988FE070314D0859A1F022789442381EA0E3E83F5245272CB5FBB861C3729EC484D2F299F37D2F50688D1D8DD91F131D03207CD1459B289B19E3ED609D70D6BF8E0B97A75F4B4F1DB52DCA7AD03100A36C45D2AA221CD01C8A51D5328AE47E3307EDCEE9B27F62E5DA9EEE15B7A2FCFF1678551BB3DEAD4CE54A16C22119BCA343822DCD20271BB1518688CF69B566A123F65C4787C1C525BAFF00CE20C46C536E47DB1E4410E572BFECDD7904583BF61847868D7D1AEB1EA071EE15A9CB9E3EFF8D17A5BB7EE8BA83C95272E065979904AA99CF036BE085ED869D3CCB694C025FBDEE9BE140A0A21689F95D90D8A54DAEA98EE5DDFDFCEE2908E65C210F347D26F35B95B34642939067CCF04A098ED3E2CE3C0FE66305BB5391E223E43119D38A33672FBC980BEAB96558D3A940700B3CCA9D3AD2CEA08E23082DBF30FC08E94B6640CA04BBAE80091ECE96F128B37141131FED2A5549CAFD7BEB5B180509880C49FC6CB1C11E4CB7C7901C89ADFA0E5335C43A74053347D3028B23085647993B5844FB2716B7154D93E25DAD1CCD889EF3B16FAE34D04145237378D66BD09A254D395736990204A5627F5446787B467B619EE8F06CE664BF7B94392B5C77BCE828D6186348EA2DECA1CC84999FCCD95C9EC55E28C8C2FB559C9020C6EEB661F708E40351D7E530BFB7B1C3683BF15FAC5B17D1CE7EC5CC3C27E04889A9E59E6534C08AEF6934747083CCEE84FF2345D519CABC7D2BA6B783D36C864C65C47CA636B28B71D6797717950D652659AFA8BE3CAE4E269BD527C0425168D04C097DE8F34834A7D1728367F148524366F9E53C4CC255D3BD6FEE7B5A6CF459E1685FE740CC203EDBF58082820B967A40822D36BB4A489BF0CEB51387009D5205056387C292D584309076956E56926283657BF7CF096F54E0128A265050DF528AEED9247E19EFCC79EC301A9F38BE7AE5057456631840EE39E191B25F4F7070BB15CE2CC18777F7CBEF100FE7993681D4E965D0C19A68591BAAABE601BBAB89FC27B3C5BA83545AD645F0DB716C98D5C7A37E0AD97C986EDB88B025D25E3DCCCA816C707F0E2542E44F4D69F943E1DBD08E344F88661B68A822C3EFD648AA23AFFA2F533879540BE2F670F4D53091AF68867E7C71EDB6E9E494E9D30A1839653422AA8AE34A525EFAA62D3F5FF00D91F5DDF80FBDDE464A8502AD9AC85EB21025C0E4E2C2877D50962C5AB8283BFC823FB221CC285F3629056D1260AAF87B556E556B4C723D44279A106EE4075BB79773588333B42065811D671016AF177105106203EFC36FDAB2F5E5EC8DE043902583C1782BFD8BB772353EBC5CF03A0D869E5F3797713B58EB7480CF7B92AACFC9C41040BC9E1F5447F9852B2C5B5F33B5517F28A01D5435C47E063B41D3B0F7605B07AC33FF6F05C6FF44EBB70FD6E1AFC2A32C9A0B1AC17044401B93D6439CE53C3B033CFF06688E1933CAEEC48A04999A01956096339B5E44AB3A57FD1F0ACA23A03114708BB16803C2CDA679061B8E9808A2E11DB0957D4F73C8A06E6C50D6DA43E4D008ACA23CE2A3213BA0DAD20D5BA8B44DE5D50E188039C112B8A40B250E7E815B1367375C5698B61BD915A70096815479916F455B9EF837300908C5A8BEFA5157EB688EA02245AD3B309D10C769CA1B8E5CCA2F5FC66CC3920759A203C3F6B8E9ED10CAB20FA143B0BF0BC8529A4E89AB0C99AF77E43E68B61A9E4176066C4708FFAB05F3652817FC42039E2F22DE2058CFA8701AFFA894F3143FDA27AD85C45D3AEB30CA9759537CA4AF2079317CE5F4B5EEFBCAB981E42065AD5CB8A4CC9B628CCFAC18D2E637CB73399CE3D90A9060F88EF438E8511CE6F403A0CF14C6B641830983C1EDDE73BA27E41BD678E834167C718F5B1E2E6C109199F756905FAF9F0005CC1D110CE277DA02675461AE70EB6A412EC455B6575F16A4DEC0565DBC8F387D84F9D3AE67AB35E511657D82B5606A4DB45CEEE81C94FFAFCB88B8185CFB67E4D7171EEB391E9E1DAC625B56FED22D86E8A34924740F94A3D50CBD05B8E2476CBC7C54D2F742F0FD7162E7A138D4AC788E710AA45824513BEA162E2A1C1F709413942BAB5AABF7E347A148D53B8EBA0336D91539766AF0E827BF8EFF36389ECA38232FF2D7E341A3AA710F590C78EB69156462BAE9B8B73386F38EAC4FA26456FA555E26E7DF679983FEF23DAE87DBA66BCEA19A9F991F864A17C23F7CD592ACAEADE0E82F4737B70F0243F94F015B59330B71E25F1304DB3D8D7E2F96669BD7F8313EF9E10EB1EDB0F0BD94745D03C83768A618AD9ADDEDA7C1E6E134F8B7BC96B84652C982B1D9242F8D2CF0ACAD146EA3185E2332904E84088CA2D7D60D3E2DAE411171726B5FB6C95B3DE961E62474CEC73226E55AE7D9C7C534E278927F5D669EE6D111E325D54F338E2A6A06493D6F1B7A556A94CC9512235498409EEA477597EFAB239380491C9CCBA1F00A0D1C5D758162E9F4F5464A1A64A22C32721AE57E246722A6B2E07E544A5FEB06AF86C580DAB2B9DFB5AA0F0251E6840EAD66FCB6B89F80C2AD38383B329F9EF4589BF0E8A0C9996EC19E1DA539CFDEFB2BB0F3D9544392A06F765A74218B7DC34F38D230D1AFCF9130410A4B4FE038F7AC59B6B062EE2D2ACCD288606AD9AFDBE95D9572B78B54D26166C7817E6F72F7E6C55DD1576720E4AB99CC26722107F7C278BAC2D82FBD0A3B0E1793C2D8B498F90A9172D17244A4107D9274958FE078FA8A5A33087BF278383F439C0B41523E0E51A662A9F2822CBBB34EDA97F5398EAA12D52506C2EAAF6D4B75639EF0676F482A69DF0E8A9BDFBF6105E32B6FB3ADA2E29C62A0AA687820B4ED35C2418DB1A67A3A5B92DC61368585CF7F3B1B644A8137A52CA21DD982760CAB7FB111558ED0310E9FBA34E5480F4E707A2CEE74DC24AE5717C06DE2B509E4807824707505FFFC5DBFF798E8D85F758A94C2D3770674DFE03627457B2DF10628A31D44BD89D3435D93E4F9BC14D47E6D4B9BD3BB2287ADBCE1FA58495D9032A9A3ADCD56CCB116787E060EA431C1EA9E60A30B609AA9C66064017EA05BC16392992B7DFF62EF1046FC7E64F8F811CE50AAB40AC122CBD5119D3045ED0812F6E30EF6B6001285427B643E3C6FCB6390A9FE76B342A462994F2B9074B56A848538DE205C98BBBCC75DF6BF23CC1AF0B201E5A0618D4BC5035B9F71BCE9D3493A97FA47607D65865A5FF3FF17A7CE28C0E87A57FE951C8F804EADC21F161CCB5D1E66F1E4DBE92C69D4358E0CCC13A12DBE87C9B530579189EF2359A9DF5A8FDE00CB2B58EBD748B23F884626A66EA39847917995EADC1839BFEDCC24AB6BF22A5C247B6FABE8CF382DB48148915167BB47F505C184EC027C3AC741BB0F6676B0D0E7781E19FB8D4D630E71ED4843010198DB9B122CC301D432856B393632369FA1C99BA252F086E317229486C034F1960087ED4606288A7C89DB0EA0DE94700785322249E901897611913AA74F8BBF412639DDB639CBD1C41374A3EC66A87451D9E4127F7627DFDE4E1701D7FC9DE13DC7754952F659EBA7B1A861B8DFC78D1379274530B976C66F9CC4002563837C852D83B3F3BBFD892F14DBF64C976C924E3C656B69131EC17B7905507F78F073A7E509157215C988D490685F8AF23F64ED338915E72B518E4305C9CD44C219876456E87C0C59C5D7524C86CAA161C745364A12890064CA9061056F37ED1BD56B5B09B1423775BF0FCC898AB1BBC283B23DB6E91A3D749125992FF1BB598260DCFE428D2524050C1F545FFDA18A63B052C0C8CA4DF8C3BDE83EE5474395135FCA2B05157C25548B0804D1EDE", + "signature": "CDBC27DDFC61E219B3448514C2DDD3D8A8199E8F4B49C7E4E73178708F40D30FD66E7873D6BF716588C97559C6C4998B2E43A58575F4854C6637784055A0C147AB1CC54787C73A49FB8BED952D2679DCA79EABB65926DEBC4C7D25D441C56ADF09C409C9FF12D2C43468CA67E45AD07E58CEAAB0F35ABB7F3D236DB2849DC0EAC34448643D7183055623A7B9BC8A08033D3B5939958E90DDDF6C9A7602A44F8516C78386905270FB047C354303AFA6E2A387A8832DC8B436BB178F713C70ECC12E98FEC4D5B28A3E072116B9D2F0BB95BED447861C56E6160170DA93030C32E41288C1C06794F7E6341DC4D6031051E51A18B1D7A9FD1A84A5DB0A1F1FFC93E0976F7077A83FEDB7B085CD366B67820EA9FE232C77B54BB368FC6A530DA21605249B3CEAD87C3E8B4CCCDC776F0092069679FA63DD91C802A368C5158718BFC115BBF9D45B7A87D4B03040A1E4DE2CD0343A318A04092EBFC0CA2BA1B94552DB961D42B1E638234617DBD18B4EBDA761CD35D12C30683428C83754D8FCA43DBCFD3B3D486D234A21D3563C8396E8AADFA89D1D79F01E6A139504441BEF37209F8D5C5495146A8A1951EBF17F7317D3594A54FAA220E3A73DD7EA3D193801C0640D6BCE9FD57F16C2F749B3E96B2071F5A36ED9D038F97616EFE62C383E69C3D70AAFC5FE4890D827D26CECFC0AE1C8BC96841652628D318F424F50915EC65E9DC9DC43E19C08CB4011818C53301CE8A292165DD6249A8D796B257481089780C8895995F7672F1B2124AE77D38E825F72EA07E0B7515AD8DC615735268A417C25944B33513BACD93C3502688130862E2307BA77BB74986819A152A3DE627401B268587FE1FD45B373CDDAB5C4D6B593D07A8421394D97C564F7F373C2D90DB689500E67D9C7FD52B14F7F1B20F27CD97BDB06E04E13D702B92B640F6E20DB82F0455DDB9C2420E7A51E063A00962C29B4273030A01EB60690C48660F552D41D7EC955B70379EE13E390D421F032EDFBCFD3E958085EFAA573E60A55961C2E390B50F85992864EE654007CA0DC6B2CC7485A558F5909C58D701F91895DCE90FDAB1069B87BAF2DDD822DCB61ED44DDEBA48BD257827F0D1045FC7B482F462ED3ADC794C2974EACACBE3577353586955ABF65538C942CE46A3B5C9A3255BE71DD5C8A572A86095BF4A1FC36BBD3E65E7AA536FDE6A31069BFFB676158664B1BB87144D3E129156E8A22CD757BEB1495A5C9740B0F0B271C920EDBDABB208BD544AE20B1813198605042A38B40969B0D6D044D4804061561ECF8AF816B7EF6B4ECA3AC0EDFA4C8699C76080CE3EAA5E2CABACE5FAA150E5D233BB694BAFF02D6825FCE4412725DDE05DB5F521B9E17DE3C719FCCFF0CE174F369C2DC497062991B157FB2FF36772C084A226D577E9E451BCE364E0EA32FAF6B366CD5E02C74D8907ED3DC54925EE10B3E97CC96DCDA7067DA790409F2B422616C65CF3CB26A7C6C8E9240C9235BA9B7A67BD21ADC729B102FCDF7329ECDB2EFF495122E265D0F749EE7414312532EEACF600C62A15A18172FECFA2BFA62BCA47CE794835EBE25557A61B61F6977BB7ACD04BDE30C2425F68785B3E227106FAD9E5ACB26BAD47FE1AD461EB2445560904CD6DEC4DB091BDE4CC2ABD72CAE258BE07CA0A8634C72DDF75A06B4AA84DD16F9E9FA2D2DA81B5553C598E10E9FFA7E80AEA8131C16775C1DF3E45950AFD77E9045A419A7B52D3F3B1C1309EEFC00B53060FDA34B95FA6347305DC91F477F4D99BF4A1BC5418CBEDB316FC83B090B0015BB6D0EB1AF1EB32EC962D2AC089D92BA915A8F5693D04876D2ABCDBDF675B8A871B837FAB190CC47D93C2E00DBEC028A26860DC39678B188C27E8E776C7C8C72CA22FEE2861725C7340D4B5B6D8D0FF63A5C439A1CC12137DBD14AA540C10EF6993CDB9D5F6D1C6A8980F48818AF7FF6DC75A2AA1987E689EB10BA40F2255BA2BFD9A36C629F02A8CBD4A862D9D6B0E6D7C25327CB87F47799ABED84BD3B4BA60422B5491FE512B0A689E49FC2D037B8D7B9FD5895C13A40C14525A6A1AFB1DB0A6747A3FA1E7CE023F290757BE19309154477176011100160232AF0C5BC2CD425AC5AED3955CD7E1A700FEB09ADE5BF281EDA1DE0FD91B072F78AB77EDDF7C7E47343B5184FE540DBDF6BD617719550B8658C29A276A704E500C379D03F60A2A977676F04B0249AF27FF58F09275AB99C1201702EC1B5AB7CE4F08096C561CE2AF0A373B2C797DE10C017D1D65821312989519173A8F901E9832C210729A48A58DE10E7F4F09453A02E656B629366846C5AF57CE17C889C1CF30FAAAF091EC80A831991519580F80770037F1775B534612F5B7D1FE5D161BD3E38CF00726779792C17E51ABD013D7A9989EB9A136EC7059B8BBD5E3013D03110326299134B2CC96CADC3995FAE8EAF9466D7E502AD3755058612C083685F9355DAAC4B43AD138C6CFCD100E463D17ACF63C830A899C2187E85C2BAC006D9CAD1276C2154FE264EC6E607E178BACB3290DEB1FA077FB3843DDC0FD44707096CC54BBB17F1238A975A536BC00BE8BD625C930147EEF5F110D5B2B3B3E303D44B57289A00D1E047314BD3A206B55AB72AC676C4B26D004E23E590396B52AE35E3ABAFF7E5C965404714D1ABE9D69CB6F780EBBE4027B8AFBCE253EA7D7503887262673AC0132A0E4689DD45553AEB1660A72D3AF71D85E94EE92E478BE68253B48F2CB40F88C35828274F04676CD22996D6A7F92175C733C06E0B71F077F0B7E122314B771A28786DE8D2DABC94F720BDA3980F0C97BA6849919F469A3C6B0FC12263B5BA87B8BB5F01BEC53A68E5A1CDE4749223CE118CD17EA6F2743B9ECA60DB616BF30C4FC3B15F3F43352D72B8094C47064EC5E6869BB45EF803B51DB512DE5AE26A90C3EDD184751F9179B14D8363B7EA74A27463EB85846EDF89D38CED01BE910883239B51D20C60664A70156C89D7031DD2BB0E51E1A520DCBFE8F5099490F3C1477BE812D0EA2AF032F1E628067998A671AF4AA84B694EC2C6193359E8B43404597F4C3900979EDC4CD7435E95A66DDFC704CB918CDA3541FE63355C1CAFB19E9277C7B843AE4FBA7B7AD8873BD54E4324714D80D906E8BDEB17272B722681A2BF2467CAB68C5DA699CD1EE5F1DF3849F7AA1F2321F6D34DA719E2A93860EEFD441F25442B01081511401648C778F3E081ADAF247FF8BA3F2DD2E70294B094D8C4F73292F0A28936273710E6BFAD532ECF02EACFB6572C0EAE5B5A258E12A112E1A22AC086938857D189DE0912313E53757B80A3A8C2D3D4DFE4060E1D23263A3C63727C95BBC4CDD0ECED0B1D334349858A96AADBE00F1A3D3F6B849AC4C5D4D5DADDE100000000000000000000000000000000000000000000000F202B39" + }, + { + "tcId": 4, + "deferred": false, + "sk": "ABCEC4A46E695FC6EBE64A191389F0D0AE180F911D5B824F4ED9111728FF4F9493EF3A7512DACF766D576898D33C4C8F4001B777EE5EC2E2DC1A8E3E181B43418AF45100B92A3835D02B9892E609B2AA8C6AF7661CE0BC8362AE0DA172A79E84FF4CDAD8607E4924FF41DB6EC28DCCD09B8D1F5657BA17C848BABC71BB242A50C44069A0200101914D130822C114288436508B0422D83004E23848032532CA902509A0009A848440004CC3304D04C0601CC84889340950B68918C81103410D631870DB444AE4224D8B96491B0224C2802904365290222D424626E0060613B12DE1187203B18442228144027159186C22092C012751083160DC48061045089AC444601609240224DA006623945149C200182232CA462A0BA16D22B2215028700AC108D1828C00B24014083221B5810C4501240225E44291984622C90826532650DBA8495B226294B049603050242382DC0429D2260254262CC3A868001546089168CC067184B86C518285DA221110402494149044B8102220299AB40190824D523050229668101072913411CCC625D2880D1B1951C3888C222509DA20322003209106028C188000B02D92421111B92DA10890A228700B4464A1B01153966800B925423860884688630800C3C2910BA9511A1902C2B229532052D9906DD9C080192400249589E004914180600022440908012435624C48864BB46123C900588869C1001251248960B64844322513C5318B909118A8691A850449B800A3B02598A2052293455342701B3722590860911248939221D9024E2042601439410937318346851A836D192751C93686111749A0B4649BB285CCC049C0C4611A066203C304A032248CB861A34408CB4852484866244610A1068909280C01810C028531232102E4442C0A988C19C54192187223B168D844862295405824408C322222C27110170A910668D438529B025212086458185208078DD388240C1092C2C60D549640031989093530988425D104524C146E62A06C5AA004CC126AC3284490268A43468021454460B249A390681A4745D2965188220E6032249AA6280A034A9CB6888B180CC1021012B70D0340480CB3444C0010011549E2B23094064504378441B2401AA3884AA885112229D2402550B0048C2621180872912851481842499020C9126D1A1289A4404C4A82710301228920449C48624006920813819CA670D0C808D938721A118A1BB589111150C3C6695386851A0204D2426D19116419A38152C861403A93CB8575520D2A3A7317CAE1963E2705B7596C8E5DBF0DAEAF8755DF38A5DF16297CFC84097B480D9729E4CC62170739A1A8A2057EA7FEFB06275344ADB6934E1C2DA7E7F3E831FA35E6A4B8D8DEF435235CE957DF5FA1D842962711443BEADE91070833C84264B45E2380B094202E079A0A7C6058A54E6F552F202760230F6D95F5EA873709BE4D7603AC010CFBADAFE229CADA1F2BC717F877856D8B930D0E215C4BA2212D66E21A2D1F09B1F1A9BC8C298CFD65B318FE91847279F204201203E0922E82BD298D9BF18B8FBCF72070F7C7C51D5480E60674341CF263FD179862F37D5665FE35ED0B2A86B7115C90093F5785309CD56C48BBC50570A0C2D066BD0ECCD3C86E2A6C8B098AFD9C0E235CEB920D58F0B913BFB633BFE21BB1668D9C45638F5CE9650CAAA83DB2D9B4B24B1F518B19226ABDA06239698A90F30A50AF69AE1D20FA00E3D88FF6F2C2466E45A39A1C946FB695888383CB6A59A7C8395082134A82DEA3DA7FE6D9E6F76C7E86A50CA04990C70DD5F9AF062ED14CC661F453BF309DA08056E19F2F7B34A15235230C15EC6859D7DCF0ED892DDFF4E5096B36B406A10CB35AA81F72827C5982E3C5BFBB989E062CB4A7F0F76B008AB8CA5EC1CEBDABCAA1E97809B44C5F49281415337978184811ADB8131D2DFA2477D27532E92409493D46C597A6886250593FD58D305D0760CE8F772337D42B0F7DBFC483A941E8CDF32CE3E97309C3C404B6E4101678F123438853FC8A71C835D1AD0C7712460DBE83C1ABC6BB0834C0271A6627E7DCB93EFC25F78417BBC801488E5A051455343757F6BFAF923867C45ED5BF37304B11E012EE63A3B8D84DCE7A15D5AB940D87FE1181EABA3C97BCA702F5DE4DF74848A99D2B1F34FE2B03633D6AAC900A09C278556172DF5D9CDE361A8ACD779465CBAF50DE5C8F4CA0D15DF3F74347C6DDF7D9B3E3E5E197BFE0AA170949FB42B78364A72B1B106156EC09A6E4EC72F3F814781D3CE7B7AA2B02E49CAA25AC36DAADE0FD570A61589553A0CAE582BA2894C82C0380A713B0B74924E006A6B341F21AE2AAEC2016D2687F1AB696337F5A268B3B6F3730F507D6122DC92CAB36107E864BB3EDEEA6FC1C5309A9B51582CDFCC1A899929AD7CDBECBCBF9D38121D58C3B3E6D9BE001B117E4A7F762816174B761EFCF291A1CC5DA354029962EB8B0F6166A9C9EAF26921D1777E621C50C41614300605B1EE2A0CC41BC666CE90A15733C69A82451FD41F23EFAA73A2482C4E3D476CCBBFB59B25140FFA0C1CECEABD3B036F2611C83AA834E6CFE03963941BDAD4AEFB11D01EC43293BCD22ECB8784EF5CE2A6042F200F1B9D6C595EF920C3CACD1C1C3CB61B6B46454A3B28A472AE0203038A5602CB9B001620C98BC09BC2DB5621C8DB085D88561058AEA691AFD199C6D4BB1511137ED2800722A81670B44FAC51DFA6683675BF34C52F6EB7EBA35D22C907A207AE5CE6C3C40AB0A26B88DAE777E10B4FC33AB38C308CA2532032A7F306E9ECA723B58119C3BE662817A1EAB6069FA05C3B0ED31060D5794121A83FBB152C7FC05BB753C9D29BC329E745D7C7D493372C26C0336AAB37B884FB41741B344EE4D247D6B5D049E5E322CC97EC6647EC7551824C6AA9CD249F49FE1652ECFD01C3E7EB026FDCE7320D21EC9E4D460E50D6440C7364A15AE3C107CE8EE1E8A33EBC9D2B5585B8F69771F687EB6940C21F45750079D68D3DD6CE1CD7CA8D91A64D093A25A96628169B675CDA9F14FADA4AF3D11B6524465B89DD4EF93A9A159F8DF2A134FEA301110EB77E1ECA51166D26CB036BF92F1655167BD32D12BE04A91FF0B3C52C69DE376856FAB9B4E14524E5858717ECBD0865719BF1DDEDDF8CC141396F9F0B4ED38B0CAADA08B64451AD8BD38557660CFEF46EC0059B4AEA6A7534A3DB767C537E60210A1AF84EC939413FD7EBBF14FE96D6EE82A0C632EDC63715C0C6654AA4FE298F43ED5B47AF7350C32C8D7F696F9A96B81E9832F486A66D9B304A6531139561FE5A967061BDFFA4793EA986C3A2693C21DAD4428FE98F168EB928FCBEB8FE0A611049C1F430CCD80F9181D276AFEDAEA40261FE1B038F5677AD507EB48B9768964BAEC928197AC26ACB1A89CDDAF51C4336B6F49985C13926E76AA7D69F5F0844F23E7B2B977565587718903B39173F7F18AF84264370BD61020F2A76ED281687419E334443159BF6A21533F41E030654F6876AABB21025B6D2312304FF8BEFFB7AD2E225BF79F1B6F8C33AA90D9DC18B369846FA06548E72EFB2EC4FD6BD833F1872DF9659F62AF040345CB5B8399A4836F7F5A9F920F0484009C1F6871D2", + "message": "22AA98C685E1552B525B4302C943037F668279C224B6270DCAF2B06C4F4AB1254C48DE253829FE6DFFA9CB6BB294F054711BAE3FBACFB900CFD1F0844E55D51EC6F697B998759B14C13392DDB6F7DEBA77FFC22468781CE402", + "signature": "0313B5DD1E344BF95EB5D825837F570922337633494F8F2EE3618AEB906DF766F5ADDCCB8EC1C5CC51AAE0B9FAD876FCFF5D6814357E8C63FE59FD72DB3CE4D1650660A0CF64339D8B7C6DDB7A7A3C8EC6C88F2F0F70B377D9D5E21F0D40E17573F07C94CDF844CB6794CE2CB8E4A11254FF0012D562DCF4D9FBBD18348D13E1B69395C69DCCBF618D7A38EA6A51B9F1F8CC70CD36D087682A558A1EA9BF9DE6ACE5B350B6EB977F435CC46FD43F155B29822D68D1CA9603BA43F1DB28BF4D3CE284523BB440D1E2C124CF92DC74F19B74CBC177DE9B08377B0E363401D23E97AE967E13AB77E9B7C7488E49B45E835136EC2874A24CC79059DE5B0A67C842F2E09B37B3039DC186427F760CE60790A9FB58AA388880EC720A783EFEB4E11ABD817A7EA884E5EFC279AD9E8AC2C58A41020C7468A749933348EBF78A0F0597B29B00A126050FA40F532B0F4411B733BAA5C80CA1B52828CB236268989EA2641431A359E6595F49B4FEABFA85ED4BA85443E2D7B82DC7523FF627D336DA1551897438100C20F0184A963D0B9AF7F7CC9FD64A2878D8FC5ADE2D0D928445EEBED286F2B280AF573EE62E70F698BA0C14381A5B4E001C53C49A77E9F181EC65B49E6CD8BBE30B5F309686F7DC80176F654771DF17FDF136D6C05498CC00C476E71608A39CB29A19A986297CB9C1E3FFB4BA08ED42AD12908287F018D49A0E1AE89A9BB3F932DF98CA91E691AB5F3BFADEA9A233350A9EDE63CFC45427CAD109468FCE4ABF7FDB83C6EC83865134380D3FFCA4D94C5604DD9DAFFAC204C14009FE06311B81310940C43FBFCF049F99F5DEEA649A333F6A3AE6232EC7CDE62C95338C23085D776B9B8F4454E03BD0FB28046618C33A7CCB409BE7BCBC0906B5A9424B41998A3A1E65E5EC667A14339E3BB44354047A2868D64B78FE5FAEDDDFFDE497368C3CC130D0821C1DEB2C43119195C6C4CFF1D5A778965FF97685DD93775837EA0852284C670DD418DC9FDC9C44DB7EDA60E58030D8FBDF86D48B98230E6AD19E97D21D7358510E20EE374B8486341302EFA590B96C1DC253226A12CAFDB3B4A31EE2270F764B74F17BF9C5681B6578777739FF767D4E094CE80AD9804261767097BDB163430332C428CB3CCD9AA881316B51556C718A95816797CD5C8A2A640B85DFDA520D1A0129F0E9DE772724EE8B74B4DF6793EBC0A801B6F77A2647CA2A5F564D336BC23ECF591327A8DC4214953D99EA3A9ED9943F07809B4C36A8BFF093721949A2AEF2CDD9687934849CA35BA1F38743AC663E48B39A2A32122B6951CF6F1BE17FA96628D8DEE8760CF7F2699045DF30484722601E7A45DEB277CBEB749F5CB4383C8643241158EF13D8723B9B00C98F8BC68C5F42DFC4A1B8D95F4652AEF67798A8B3C0C2AD40CB7A2B88A23650147E32CB605324A99370BDB640EDAC9CE57EC22689DD45D1922811584B01685615520DBB0FFBB028E43B77B54AF4A3EBC6B9F857E9100FD9C64028867999BB9C7FF05D37704D41C94CD63DFD1A7673F817931A4F2C42CE572B24FB5E779897FA4E6E2191524783C710A099D1A6BB9EAE47E849187432A2039BBE1D37D0E7C797907F99BDB8E7FB33C3B2FC9E06708312BEEEF2935D443F29B646FB5AD52C99EB71559571781A4C86250D262329FF3DAACA18A5E7B77C3CE593CF3A92B12B9AE86CA3AF05EBBBD75B6BEFC368982D96F2E5FBC128B6A8D65FDB0B0F7859689F0B6F0A3D1EFCBF1915DC61C7FEEBD077F71122E77775B4279F4F57ABA521BE4682DAA5B836B5B4D44CDB726DFF3AC9CDDA9F0D1CF4E79BC9E90DFF7562CF206E756C38E708BD30820A14C595288730F42C8ED99A7C1F2FA6CA9759CD31B8F28FD35B9E0980ACC3432F462CD9CB4C594AB63FD250DDD4877269056677EA7E3B0AACD4757AEBA398688423015D952D0CF67E5027BA4B6B376F6380B5823717D64513EFB35015FBD20FB2284E1E340C9B94F87CFBA24310325D7597AB34BACA6753215AB994390C2E5A82EEB06F338293E72C5D0FF786666FF2EE2D429461F1112551AD0928844D7698D3AB0C4054881A623525D728E514E12550AAB227389E5F0C2341A6AA34BAB5472BC9E465DC24E9910175B2B968F2E7883CD22CC07B3D203CFDCDD877CBB28368DBE668F561E3FA1C5D3391D4A408A71E0BF0C32C1FD6494DEF7678E58B829AB428509C33F2491725959485928B2E7FA96EC7AFF12BA3196087D3C83DC242E5EC95BF95C8581693FC0B744E758E1E85959AB63E9B4B0A4547BE5ABD7D29BF9DA2D192B4BCA491D1DC856EC80AD6C3C738FB775F95A217D76093852AEE0CC203DB1316C6253BB75CE2D92906B47A5B733E4A8B0C28B1283419249B5A05F6302CE110F85790EB46DED7109B0DAC58A4D25255B6950F3B2C3421140E4825B6AC968091EA7AE9790BC8D03F3F8F4C1BF1006E821E5DA2C65C542183F4230CEC934ACB81FEA94D959FB6A21C7AB20652C9B247EDEF72674FE915858795A9A00564F602136C364A6D9638CB1BBD8A705B90429D13A19DE93520229282D5122EE112A32A68E23577E358FB28EC45478D05F64513A9E814A5F1FC7CDE4D03EC51ED41D29ABBC0F60292E2F7D0AA4490C38B583329E2D5A1E61C73D6033CB73A7A4F75ABBB29A31E52CD1EEDC3DC4F0B9152FAE6B29DD1F9739456AC5B1890B3BB00415027C634F1E6374F310C95E680086862B8BDEA0833997746814FC602F97999A2309D4CC05362303F72BBE2EEAD04D566579A00A8265E238FC578FDB2A63C57250B5714F2C6485BC6247752853F75ABF066637645A5A6AC0E85459EC2E24D704ED7DA4BA0FD23748D1D853BCF84D4D00EB4B6DA6D036B8F29797882EF5400F2F7D6EFCDA0418CBC5752AE5431B59D2D518FD752467B7EE13F699CEE1581AA1A305B2ADACA12647FA8FF00B427F28AA33FC094A374521437E3B4A109113E1AD8AD23E2AEBD69EDECEDDFEF0B5AA0A484AE32BFB2B05F8F7F65077F5B35C99B61EC28060437D9CB982AFA28FFE8AD4C02BFBFB071CA8E9EEA15CCEED97D47BE2313E3C344793D40B45F709C8A2C639C09662A81F117839AB62135B6715FD57F7B0368C6EE1E3234655EAE94213D24D92989A46CBD5C7EF116243A085462C5454949D41D2D570AC810B54C727FA5E187D0D9F7FA7DB3682D99460F5077AED0A90D513C0D833E5F5A91A5A26CF47AD134C074D658AC0164ACBAAE8FAE161E00C7F8B043FFF46FC5C900C9ED14C44C98ADDEDCD5F3BB7038868F8460EE12472DE2A24BCD0A611D9E039D60000D131D242E3C436E808FCDD3E2F55667698D91929DA3A4F0F72D4B58636C6D9CC9D9EFF0141C233B3F4A53595F696B6F848AC2F7FE00000000000000000000000000000000000000000000000000000F1A2536" + }, + { + "tcId": 5, + "deferred": false, + "sk": "3820A7CA1DDF6D374E8053628E628D142C4305EC1F3F05C66908FD5A1720C7F02EDD55DC8D2252C7E3FB5C91BBA1C615E23C16AD39B4FF5BF62EC0E22F081573D22DFC983A88CDB217F422AE9FEA6F82BF0E72EA8E6193E9DEFA584C29A9873CD76741016481CCB01ADA6063BC8BE27A5887FABA7F701DAD4114DBF31357508E54982900B391C1A42822330C82485114330A14A3601BA310D2344D63368904368293100840B42991C2405C22290C492C52084208A788CC266682148180300E10C330928021E214499C904812A169A13009A4908518882420926919A44D2448612217821A358019B2891245619A342A2132665B362994220E942812CAB6300A9251C910295B160848486E9A90641A238D0CC52022B9318A3266A2B82902440463380A0C373022B22C0B3152D40410DB100011265150C245424622103792882691D8207221088C8C246623044E1845698AB8886192004A244C0CA46518206C8A342C12498A1034455B200D02184E98420D09A30DD94028CCC821200150E4B02981466821434880C46DD0480E14884152829052C08CA4B26DA2C401540850A3828CA0A248A33240044032231041A3C680D3042DC9884DD1302A93202A0C250A991408E3160548464C64A2319818122308865A926814B7219A2071C214640028509C806413996D99002C1008909B925018266AD4020453026001950500953113A385829820C43651C30004E010269824660B920109362E500889E0326C14378C181589DCB864993271A00260C1A425A3C8718B8829CC946558243080C204583465D1B01088A82422120219244A02388D1A295244446E10320514488C13814544427052129182308A1BA14C1AA3119A163200B53049322AA14061801885D822520BA091D02422222112D94409D944215C84811416641BC40940088A61C40DE0162120842CE19000E024654110721B364A511085E398719A448223016C12A12121C4240A346520A850A332815A2051A288500319421B2831D4346C24A06082140C0211889BB009C424001034525A482AD91252CA96090101611892604016040B91214BB66910024840C40D00828D081161A142310BA424522612C3328820300D18C705243505D4320E94C8841C406253364811A061214669589611132001D8A430400431DB18120294281CB0291C374564A88811824810236C01C2500A24094A842D9936688086284330719A280E04A24C091312D124718298100C297123324843368E17AE9DBEF07C60FC5C871DAC487C6EEA46F0FB8B88470DE3D6C3F2B75C615689DFAA98540F2A9D1A3F8448947B6AC7D535DE9F3019C60901BECBADC594124FB4C677CF4341088FF2085957DF9F3837121DF75F92D40EB77D6F4B0AF61B2577E432316D09DECD949F1A31EBB1E4B51E3D412B5CC66BC65D4B399EE83AE52F558994F5C0C9D15617E43E9AB83A34C16D097A3690677B35119EB33D80A88F1A8A77C2343A29EDBC9B3D77E52CCCDC1977E09BD3EC6C8E05085D23C063F785B518E49EC3BA8AA156F16C760DA4787259398A9D343E5B37602A5318DCEB6F27BDAB8C143FF882993E80FAEE6707B26263EAC39E22980BFD23C61ABADE42C22549D493B23BFB6449FE242EB61986E5AB99832B161EF32CFDFEF5221C2710F1D316D12B170F4C9EC71DDE912EC7572DC0B25BE911DD536CFE6C6EFE9B7ECAE861E5D3DD28E68FFC7BFAF7CB38810DD8DE12B23DFCE3A69337FC423BD82764263669295023F3BBE4E48DC7A3F17337C7BFAABA2F7B57459C3572881EA0BD39DA3C2CF160B6C032F81A6AB8FCD5B94A7F2014F0AE904B4346994CD4C54EE678E23AF95BEB21A3BA062E1A9DECC2A983475641A66550FB2892F732437302F19F1B80F034208F6E4250822868ECC32F43446028DBAF1A910B923ACD44CDBEF856098EC10171A53B89DEB2488F6D4CC4EBBD024668EC570C00E335CA9AC4C031A3BDE783B093DEADCB5D6DEC107CC35591AEC160549D7263D1D3B6CADEC6D6DD874CE9C73E61804173F07E4F20F5B7A5C3698799C30E9489D1805F3A5DD6C36C70D38A573CD425FB89A928061ACE86F065F04D2C14AF0B8C9D8CB4F7640DC5AFBA3EA426FDA628B72A4CC276BE9DF0844ADC526BE701BED18843F001A88570BAD4181BB66E37C35230E2DCE7DE953D1C4C8F7CB7C46E1C57FB7F32BE90F65ED059ABB9250B8D8046AB35CD9098A49F81B5957B830FA47184DC5D10B5176142C956098C7410F3EF6B0CC092CF5B0FBF73060FFC9FC612767B95D1FDF018216F8CBC1FDFCB5A97B21019C0694231C34783D519346BE304BF1217BC6BEB5B2126CA975725328ED5CD6542B8E41AEED52FC50D1F99C35C755E207BE22A7C5904A10204BF0B583F486CE7BFB5D6CEC33370CC02654A6837F4A88E6CBE64C1930DCA4905DAD35DDEE0F8D4BEBC17A04BCB086D3C44BCFB68394384AEDF39D27471C422371FDD80BC72FBAD6C392285EDDA04A0EF4CE9742C020DA2F528E183E634ABEAE41785EF3C69FC8527F7334B6C7278960364AADFA66D58D8F7AF4183ACF3323EBB3505BDB84FB4A76B2CE0B768CC8BBAAE17FC2B637DE77E107ED1C6314F94677A4462DC03B60DE122E5AB843893944E6902724A8C4CA0C00D88C3D08D6314B4B07DB39C4EA413BE9E0DA58270EF6A949AEE60804A78EDFB0D4FC989C02CD7E48D116DDA1E91E72FBCBC9E90172501871A7E444449EF65F639BFBA5D4F297FDBD2A6295B67499FD853B4E26A82B62975B07945CCF29BFED8BAD16E67D95B8A485B9756CABCC8C99A11A577C50FB6D39C49B53B309907213D9E60983EB820276B2416C8CF8CA98D9A9FDC6CF3F122A81901988DE195DDF69D9CC38B36BF74BE8D4DA4C1345A5FDBEECAC4DF62B2146AA5BBA74AF45D2B736BE08593466E85AAF96FAF3FE9E5E6FCEDF7E3C80D1D16BF761B73B5C5EEB5F01AEA31153A5618404AFDCF85C2FE38E370B844FF850E1EFBE759779211CA7C219E2425B2510C00A653D32A1238CF423067A309E5839200F6C5AF42BF7EAB25A685D9965037C61047155A7B33BCA049ABB15DD4E869B7C9E525B607861EFBF250C83F95ECF3593484FEF1D49FCA407088A3B1B9CB6EC4FBD9CF8F2C1A5C98E667A8027C38F51299B6442B6188963262B14BB71F6824189FE8E372C6BE319147B719FE723C6861DE89A95FB61BD23A61BA04A6751033C5372E840B29C6F04951D3FF7FC559A3387DE0D582FB059E43FC5C230B8352A563E05CAA7DDCE8E068E5910F490706E8E6F58C6AEC45C6BE781AEEE0FB9AD868036E5314C44D2BE4DF0D4E47278BA9FF6418317088AF48347602D58B8F4CE43324CC9A053FA1AFB622664E8DD5020E4A6333EC1418E57C26CC3C45EA61600DEEAC5A93854D39F60315E99357BA88F58BD6136E96DA043825C7C17BD246054DCB99438E24DBAEA048666F15158D71C1543C2A550B9D24C5A24A9B78BFDBCBD3495D25449DCD76E8BEC2A65513C8EA9E729D7E1AF990D323A6ECF88E206C94A685DD3A4A9BBA3DDF153B7D98912B130C2A1C1DAA0262ECD8E43B5B1AEC483BE373EDEE376A866D51A3A6662C0AB3A062CF645FEF874E97CCD2D6C5", + "message": "0B0F604B53752973C4A72EF940C3FBA910AA9AF2916D673D69C4AE4DE92A237F271E84921C309B59B92E795BD26C5C015EC5176155DDAE8FA17D7BEFCEE3A23E0201669CC55A6F270CF0D03FFC09BBE4B47D318B6926808EBB49EC8B57A849896E76648D51117E8F518088D66B69D88E09D298186C10B5678EB8AE43E9C0A794C63CA9D597C4B74C959E9C1E8E0F46698CD64CFF3C0FC6174CFC51095E142DED9F16E5B2D3656555D2D42832280164E0C10C5817AE47ABACEE7C3BFD198A21BDD1C420F2EF0776E5EEFA46E8BCB49388FA6B937FD1FEB2BF09D5B9494A534F19BDE4E7BB8A5E4C558C2A166006B481A7C5865069A3DEA2B880AA503B5C020F045A4D9C3E5C590E4AD5375E74B732695A11164B5A57AA665922431498A9218CEB9ECD92700E92BD11E0A8140938C4FB9543FA5DE8EDADD1EDBDAAD11A6AEFF2EA409638B2C7AD546EFE390729982304F35D7F889C0CCC81D67F5A1D6201BC4BE8D1AD2D3CB85815CB9669B56F845148DA0DD2D6B5D7C4986DD3F10BDC78EAD8B4A88B7AE1FE11C634355F60A43A55C88B37954CDA71F4744C8E2B4D7F8D4A2BF60EF0C44CDC7F7059AC48A94B10279921709827A3E1E7A46DD857616E6B737CDFAB71CBD47639245E392DC116614CA3F099B8F2092AD667DAC43B8501DEA9876E5E0B98B41733DA63A2517A49C169A95E583F18F2E1DAEB4425E307509CC6B0B376827F0BAAFC2FB2ABD4E4151A8DBDCB8C22C78F5DFEF0DD1743B047E58537866795D67E35358020CF75F0D2B80287D62AECD6D34D18494D01B4412B1CFF279CA69C18A263E7B862F514A7A64BF192586ECD460D22DD2280373A66ED987635761C3CC34A5BF6A370F9F8B16F98808767A2D9A1517544D869E674980758B15BA7844027D3593432101FBC51FA4709F4D041BE9FF31DB9B7430F1D7F8E06C22C4BF3F8798D50C92641CDBF0B2C88E88666029FC985FD4E9FFDCD779C7F7600D02AE8D9E3CE6FF76F0B449C41BDB785BBAC9CF58ED7ED1525D7C7E885C0D46ADD0F7CC3B14394235B9176B69A222567E6533870EA540F4DED9A1D78F2CB89E6C1DEBE67249ED8F31C87499E24DAB0434FB9B40EA695499C76A1618A37B1AAA5309A914B6574209A61DE0633F086EE4F2455299C70B981532A23DC453939D223BA3A25122AD498795624C727E973C052E69AC40AD465DF55ADBB20FEEE76BF2906EFA7B0D9D5EAE860FE02500E2E0F4A21CABCF963D91262EAFEE814BDF9775874D656F8BDE11DA29327E3E7C7C95395D0DDF766CF34005CE86592F6787D1044E5CA1962C4DF2719308B2D6335FAC77DF46092CD3D5D228E381BD7E5FB4D2EC18B19E18E4748F662AB34C3F2C33877BF4A8D43A63F9B5DC75861AABB42D34EF37EF19CADBA110A3807D1699B247BEFE3D61AB84941ACB227C79CA05180FD3415D0E76EB31B4DD903D78553F2C22563F9B22BB876E81EDAECA4B8FB9415E2BD5AC32CC08775A20E8F90A1681C9957DFC330B6343E58F841906EE3562ADD6AA53FA1EC4AA2E894AFE769116E29AF49D0FBE2D8FEBA215E470ECEA81B258977A0FFCB17666953C29B2F70559DA00610398A08E0A17D69705707569D6484C4203C06B17439E9D4D9DB8456682A79659DAB332DDF45C67E527304013A422E46F2989BCF033DB143676A4EA720D0DD75584298CBAA765CBB0B09EF267D503F2782A427459FD2A83676DEA43C01D288429A82527A69B1EB19DD3BA1AB7428220BA74F79A81377F7ABBC027D96903AF6ADB4644E9F5CE676FC4D3ABD977D6438F4743476F77F3DA6E822AE61E0AD38549BD21E0FAC1C963F1D47F9E6BA6019591DE22BCEE5D5C9CBC4106A369C04BDF633F41EB1D6821B1F43194CC14B02B753584A659EA46C49B983F592C83BD959690845E872B471A38381CF3B2E8F4DC157D9A60FF56EC63B1C66D2227A069CEE7E48DB0E0D5991F96740D364DF89B08BA67098652958A14516534103ADD9E457E6AFC4DE1AF332EF3ECF6897B3DC8E5D6980FC5E5D829D4326F6023F48CFC9D0D787416EE61A0BA3CFF5E7C69BC83B18928AD277AABBDE271EABF8269701E526960460EEF521E83CF7A61A3CAABBEE1F1C99402EF55FD438753790CF56034AEA3292828AE858B2D3B9C8D77FF4545FAE7B4F2AE1EB17B8198F4846A8F4A105CE250F900969696E477B2C46AE786481BCDF85715BD270F9C29BECF4579F2DFFFF7750E375113E33ECABFC52E4DA5405849FE5D5F4A17C1F0984A1479D561943CD1120037EE821A2B57A12D7F1797E64E38A4B71E2FB10207ACECB96B3F3ADFF82EDCB633E388FCF11C8D105C1F6EDD41B553B4B559C3199745F3B0EB7326B867FD4CEDF4E9ABA1FD6A10E1494847FB5DC83C91F7A2DD351CD1AFDF95865701FDC658A41ACCA58E574B67929EEFEB371589374285148EB09157AA9A67F2FD54FCAFC1248F6D84951AB1A676637E9CB76C17C282DB53B1BEFAD8019F51B0400DC1CB012B97575ED81C129636C38998A2E6FC5AB7F0BF1FFDDB588BDE4590A7A0F879FFFC1183A3C6CFB341FB518D0786A6473FF9614877B1B722AF4B2E1E9B5E0DE7C3DB004EFA16F5CBF07870D7208A93A9FCE0EEB598CC54F04B1BAAA992C02BB2D27217AB20A3381EBEFA04CCB1F23E59E4B0DEC700E069DB7620E22235A4C5F54522D96ED4785ADBA7FF95F2A7DB212D3DD05E58C560E5ABD0EC238B7ED01E54ECACA7D32F7C2A3309A437E68C3AC7A9BC51025409A2A1ED05F8DB0EBB647FEFE6222D6F74DD8E4034580B675DEBA4BBFADEFFEECFF4771A0C1CB0ADCC6E9B050B85D230F6B288AC3FC24880CCBDF9C6A6976D46797B75B8532411FD89BE027CD8C81547B24B535825695A35BCDA4E2E0A3A6BCEDB73DD10DD847C4A0AAE059A07F56B0ADC0401026648BA469C534CDF6E2CAB8F581A7233D2F15BB35DC990EFBFE688F9B9AC5AA5C9B3E95DA7B0122947DA03AB9DB58090FF14B736B9CAC65F966206AE7C84B971D83944D8AB61589A28058E14193751B685058E632E32EF1E8C94BF005A3A2EC5EE2CE2FF6C05A67D87E56998E952E4557250E8AB5A979ECB28B0EE41DEE07F919E67670D9CC4077DB0D90ACCFE17CF6AE69DE0C9DBCD3D552A7FB37383574692A267B0A8BDCAF3532AB47887FCC94AEC3461A9257322095F1024C880273222295107864903F3DC8FB353FBE51C4D89F30FEAA5A570979A38B0B4AC9A4AB6B7169984C576BC4AD6DA1719CD0D5ABA03BCBF1336DE48CBBE167E4293DADDE3997061469F200A391646C8FE712EBE087B448F7A7DE437186D38A4CFBFC2919FC888487B15C60E93373D076DF6A60452E62E05256AA66BD1FB771CADB331661DB4BFA47581A4367069FA20E9C6229F79D6680125D0464F7CFDCA1F5C46688D5816CD90862FDABAE753E56BAA1369AC1AD3530630998CEB4545C4404C8B9A65D5A43443624D62DCEC989AA2CB8B85414E06AAE6BC4E219C5A3FDDF8FCC75381F6A0F73F54A7A2B5BA0F546235E71B233EC107900D8116CCD398FB14F32CEC310AC089D6BEC40255A6A877C30B05355544D115E8F85E428087A5F3670D596E31D25F676B3C6FF444AA0FFE5011AE62D6FFF86E615EBE80622BB646A318BC65950889616DEC254DB332649788C07E46CE590C2362EE66BB33BD43807A1336B94198BECE586CBBE3136B5CC809F24DB5BC3069E9C1FDFE53C6D1DE29DF48A9000A7E89D6862A773832DE2151423D9D11D722D923233137DB6F34F8DFA4EEC134BC9EF5A70424D895638D1B09D95D98CFA17308908D65AF00259DFB5ECFEAC55DD7FAAEEAFD4E94EFB36698D2315D795A93B8BA6A3CA93F6B79F2E599149BFBFC6F5C5742A83C886BDD4539BCC128F30B370FFABBE724AA3F3D571785AA6234FD2359FB3468A06A8E74918EE6E87CB29178900B49891F565A80BFF302BAFD0D5C2C123973BA7B9B425973CB3D7F2AFF3059D272A7CE611F5CDDB5AFF3E2B4024FDF0E01D7AD1C63FB47D9BA986C341030B3E5C6CD3CDC6A3DF9D6901E76D31C141C37619F5BB316209FAF8428AF19236DD426D70EC81E77309D5D9AC33CF3AACC0259A19F91E4579AE49EEBA41CF79B9499CD1211AF1E6DCDC70383A35E0ABF7B53A1203AADCD3AE638862D35EC4E441100E8CDEC7F0E6D22845F6CDCDA801111C4C7F261189C7D67B981101C40F21D33D05E336F1C7443560238C72B34E47758927E37F972247F4457EA60B2546F6B5B7A91B151E8B3800CC1748587E0D5421A43648BBC5D87C591B01C229C8104CA87C0B7F0770ECABD1E2A858147B62F607A86E1C71EF73C036B18C01CA5C1BA8242BC4BB7414FC90C0A8372F860F2EE51DCC1E457135776C377F940400AC5309112E6742617FC226EDDF51E95CAB40CAB58CAE1E662DD78C6E253B373BE970129193DAC7DAE372CBEA847248C2E69273B7CFEE70BEE59DECF64126D44BACAB5F2813CFEE1EF89AA3FD6D030319CDCE94FA86E4E64998266082F8BF74877038ED888C16907A8DF99BB53809E54520E4B5B6AD44849A33EC3FA44A7B179350DB07524823FE8384413F0A7E1936D8CAAAFE1052C462778B36AB8A9A14BCCC0319CF6EE2AFF01EF5077A10BC0FD0DF76D9B806481BAD1F49EA013942F38BFE52FB194EF8ACB283B1462BFFE4AC618D6FEE7E25130EC71D68C81A9532A16520075EBC1E9C3FCDF5FFCC150F3815E8647F34DAA814935D0E1AB68EC6A1B14FC7566415CC11E0C14A9693B8711DE2D3F78EBC468269BC851D2ACDFF5E8A6388B73E33F20C0C7621C6B644649AB088DC191418292A698EFA4871224232A7788EFA2D69F9F9FBE80FB8E6B0106405F6406D00A6D6185EB521372CEDF51C2E0876C7A86A90F1F5DCC0EB3187DF8BC62736663F713A1D403665BD5AEFD6BCD3413FC63CD68B3C5C7FDE3AC4164FC3737C2703AAC85E6ECEB29E34A6ED70D4178402814B5207ED2AE12E9DE009D0DE6A0BABCBC4ED41D5C28B1943C4B61D8B1DBF4395F5BACE1E47ECF0EB9E21F9E7F663EAC3788E935A1AF73B19714ED91BCCCDBEDAF1C74155CF235A58485BCDFEA58A929ED1E959DC99345C36109E42A14438466B1F9E728801BCADD16B2D8F762E4BB8B3F01E531339DE79634F43117DF5C585D7D2FB4A5D3E82BC25FD92BB1298AC79211B3866CA1019666AFCB10BBEE1AB63263F2823A86DD3EC57E8632C9F4975155A01F22859EBC400F5A3B8302ADAA5892A320487AD077B144392528F100F0A222DDCE5636AD5962AC6D62A2382167EA977743CAA6BA2F140655DFDEF168BD620C73A47A8831DFD66DC6F2A9F47E0724081681BE62FD15C74846980683B729AF1757203F457FF12925B6B7BC81775A9E5C53862B07D4B93CB2E9FA896AF58D258384115F1C63779E4189832C29C8B142DFF30C00DCAD2328A63C92CD1E42B2A8D2E18542BA3A81686452C83AFD5F6955A708CC1DAE500718C6DB89ADCBEBF119C4707B931E685BAC00AA60E3B5F9F42FDA6EA90F5C77295E84A3AB05D69212C5368E24F18F43B450181884D7AE8BBC61E1603FDEB13797F9620AD6C2B863C495821F7F726BD5801A3D5A36F4609B595B7653799B3794E4A60090D71F5DE1AA5F0CF562F7E722C55AFB676395ED988A491A34B462B2D18AF517569531308B8190F0148CFAD463802AC62C6CB289FC0C95C207AADF82AA7399E0476B774D9B876829ED91EA3E5C40B504370D266B7B3C72DDE2CCB7F3AB8E820ECB5715289451D352D83DB67EEA889EBF9E8B012C8265376C841BAF6EDA4067A400D4C6FB00539F3839A8D0B29906F9923B9244132282E38242257C339A0D0BA8F05F75D41ADA51E29E33BF65F78981F04F397BD5F9580376A8D1C552363D6BE90EC83C2AF748CBB7783D6B26098C641777A260F5F60A712C7A7D1CE681CA1FF969B8F25B90F9A2B03F71E06A848DF3C5C8571C5626D5A1F123DD14A9F90B3958A7EFB3FD522C7E83F897CBA80B95099F1705E1CB22C7E91DB644880F7DAB480B29FC0F8E1D0ADBAA123F1E1FE36835ABEC924531065354B77DC1082DD690B316A7BF104140F6316C46E81E777F56EECE625EA030C1FFBA3A4D40745E77129230A69D76C226A80A8CD31720B08D9207F22F8F3068C169B41E7136F94B73047377A8AC0987490E4DA2B7619A760E3B61369BF762FA9A3ADCB014CFD0644AB1FE6D8D3EFBFEC893E98289DA93AE19D8DE41AB33FD717200B6949AD21B3290C77D5B1FA44EEC7D0C6A9978D50B40DF77823FF2613BC80D0E11DC2B790B332D5267851B6315AC08D0A2D6FC0A8F93DCD20DA6054894F84C88CE254057CD2FE36693F868D812DD1D978897597840CB336223F8A8EEA9C15AC05D3E40333391680C4F4CD5C2F600CAA684BF09EFC8A9B71E6883E9353C22B379BB6ED8ED83A2468287121207D9ABF61D2DD5116D3B163F262BD3D57A23EF2E6154BF6EEC1DF88B961C4505F7CFD2E23E0E0D245A9418292A5AE6E60F3852D78D19E1EACBE9F42A522FA57554308A1D01E31DDCFB7C38534F7B48E0384AAB4B81A93681ECE4C55BEB089092E757A4633B2F30BA83E470B3ABDEDF9135DF22E2B29CCD0893C54C329DA1B16C2FE4221F1C7EBF6B3D6DE84EA1DA57392762FD9C64C0771966B0E1FA9A6E286C23128DF317F704237B97A339A623C985BFD6A0C60DE48EBDD73A0610A22B02D0978E626B50171FC8390B80F37E5E536CC184259D4ECFFA958DEE1A27CF3D2EFC9B218809909B19D573EF86087A1C9BE161C54DD1279E022F98030669FC93A7BF03FB101A3FB5321F654D2B40EF8298844806BB66EC32F7AB3BC7BED2AA7F22AF20759B12A0E3F82D3C3A141F393DE746D5A0D91F32D8249F0DB0FE37D27E49795C648EC6D96E352115FE4F10D1F56C39FF9140E3E87F13AF3C6480D6150E1B7B4AE614A577D6E81694C19E468761039E970335FDE9945F6119F6ADC184C9F2A434C681D593F34D258F2A8847E02DA5EA2605A007B25031DCCBA8A8C50C77411D197E742D4B3994471AE84E2B612B09B2BBAA38C5E71C22A8E3DD1F284A681DDD45E962F9D061846EDB9713D4F925A9DAC0E32D2A4496F68C68448EDFA87FDE3ECD47411AF5DA95D8C48D5CED988AFD72BCB7A81896EB1496F468D4664A58EC3874BC6FF6A85692790BB405592DFAF53CBAC93884A842EB2D3DE9619843919CD9D68AD89DC7A84BE54C406B8208428066011807D722C2B34D4A279EE43BDEB967360D9BAE50F654B2A06B576B803544DCDDAD670CF8D2D7723929842C6AFC4093BBFBB75D1F5E03682500AA0A34FC66CE4409D08C726552ED5ABB0C646E89B35A659C67F6F398D6BE39D9725BB0322D458DE2A62E46B62013F2BAE5E60C3D41975C6A4C6231F4B0EA2827329279459840911891B0111FB4B1FE99FBB482FED56C7BFBA15882CE5E2FA2C73E0B682EADEE6F68E4E1A9CD92FDC2CF30902453A16622AAB1273407B985FA4B7DB40D87812F2A10183464F8173D22D5603C44586B107B4B82E94DD80E87AD49E9C0FAB5C3330B74E89F742CA1A5940F0F329F56DFD40C6869D0BA8CA412AF9C5116ADBB3C22080F93142C7778D52C4D75F1EABE13FE50877C26D7DB429E991506ECF1DDF30A00F9E0B355306B889F41BBFD1B4D27B67952E4A0B53D1BF8B2E84497F00826D84A913F02649D5145383163F3C3F586EDAD06F518B64D9B300C4540A67593B9F3358FF2A22AC4BD7E7B9AEE507D184E039ECA3BBA0B5C584D3359D7121BCCE01691E11C120925A7D8B100751E8ADE99D3676C7355BA4BE451920BC7D2AD6E8EF0A9693F16FBB570122FE5F5FFBDFA490B3C84809ACD898FC0F807C77937C7CEB6F03308D3E9C657F80730EF3A1CEC6959850FAA6C158F23B23D28ED53BD77531F1012DC1753CE1AD6E0A629E14BCCE9D56B74E09AD6EEC9DC4A5C92049D48AE21222AF706B1C4DE65AA814AEF5B7E1EDF2D8A9C5B98853A17199DDC3233C5583B95756F5A9C175FF7D0891010F5D36A268ED5C9F58433A69185931E11BCBEEECAA240C2C5A4ADB4E770109F3F16CFAA37AF98E1228FFA7C584B13F850FED0187FB836E0A01B19CF700849EFF09BE1A57DE41CE1D52EA6F182E0DDDF741DBD2150113B10CC3D9E44917E0FD9717D6D361A88060E202039AAD8F31E4E6FBB4D7FD1BB5D6DC20C3D83F23D120EC98FF4912F3D9AB18D8EECBD7EFD1CF9B19081B38CD959660E8C63A539939D0CEDA897F5ECDFDEE16ECA492B216BEA35A167178F4A0FB76175D160FE2EF97BD6BA0E296922CE60D91FCBB3343ADF477F8A92AEB56A471B0711CAC45DA8EEBD21FE83FA68EB74C8502C81C65506C92C4A3F19ECDC2B7A5AB47704DDFB2E8D5AE620CA0D67197699677EDA3FC4FB821BFFB5F2DB03D4DDEC0BEB13EF84EC372A5C56C1E712C8D23D1A2DB1BA077645C85689CA2258E9B1B807DCC6394680B72938E1B61AC3E8A5B9E84BB4B58CE5C8C2246A604C05701C026185CFB872BA78CEE33EAFD0486A22C6D5CF9264EC134DD79548F3CF5FAA67D8B1FE74F6AF7B897AB0A0D8CABD5E1B2829CFE66D58CE00E68C6F23FC35397FBBF96D2E63825C96BC3CEB22FCF9CA46C93538F8DF566145D06207533627B665E39DD284F4275051229F3CCE9E9E62EDDFA55BB2AB1D1D8E8E6145B3E38F35F90B89C15FE799EC14F7E415FCE4EFA72615EAD26C10C1FFA4FDBA2EE04C4845489C21BE45C478D8B2116C84AAC21B48BD4181FC28C7C21AC9CF95D8B04C0D817C8ED8083D9CF8B81213AA2E3B8BBF4AD66A7AFDCDC4C420945F5B3E8C8AEC5C4F98005A0CE1B3283F5FC0FCF8567A150E12639CA85D298CE8E4F9E0C53817D3009284A5A0BD5D3A07234AF751AD059E301076946DECFED43DB1176A2BBA4B8A571299FDE4AA3574B6C189A721674E004F259B00B26EF5AA90794FD622040B80CA6C5E9FBD44B3DB21290353878F4D8D87496E374B05E6A5B25742A885569DBA2501367EF4C549BD5CE6169914A7F1D311D52CCFBE2091F0DB436506F210C137C2180B89626F52B4192C67ED06C1F9175E44B9468E6FC2208A98DE577962D9B4C31D5B0DCF4017DB1BBB2F80512C89B9AADE69DBD584452D25CAC97A4A7E6F48BCB909907B93F5B8108EDAD38CF7FB541328C5E8AB867DDCADD6A1B5083869E68EBC785C80ACD260C715624360F2F3D78FC1B2A464FE0525059A3D5E04BCCD72D23BC680CF7B25C5CD2AD6A0BB8366DB24B671D5BB3C12554D37C7A662AF9B9DB61DC6C7DE288DF1976DE08743426CDD30AFFDA05A8390A8F3A4A94D7CCD33BDB229E32850A77B2256CC595BE515F9E6854463966D4DB7A946276F594AD4BDF0B9C59D4D38E211A4465AEE023CE6C062FDF4123ACDED834F672C1A724BC17D44DE9632A588E7EAA77F3183E09D2ED55099BB1AC8198C96EC7B1635139980D5CA4B8B3102375A2E08BC3BC754D9FE659C3FA403218BC8C00FA87A0FA6F096E336865DDF02BB05049CDC9680E99C4F567ACD25AA7CC76C182A8DFC174BF6FAAF4D2553A4207922C1EA10CA8DA3E35DFBBFB5F6919FD4088A3A8E48358CEF25576A3A6447980F1C716EB58E755196A672C378F6615E54E9A16CEBA33CEA918768961C244A561164B61754F679856575DDCB32C70447BB738E84CA590CB523C6553F13EAC77461A58A7D4E1CC1E36E7BC5E85860B0E6B67C70D398AC0BABE1F42426D9E7F12B5E362BF3BDBAC42C572730C5F4EEA957FD3F17050625BA9D9938380249290AAF31BAC", + "signature": "7C6B47263ADC85F69B12955F66743C08E52EA89E18EEF82D6ADFCF8CC1B1A13D386305F13956EF20C02C65C64BA0AE526CE9EAFFDCD44DBA07600C4563EDE57CC7BE708C057BB3716AE33D09FAEEBA0E9B71A8E24D03DB2ED26C85754A25856F054410E286BD70A176095540559340F1CCABD50EC5E89B36F97783D35EEF716A910E6ED934332083F0B49B9B7995489BAD905E86D54576447BA6254C382732320D1ADEC8B75C85EFD00217DBE6F386C0C02CE4822AD52B72AAD0FD00F74BDFE62F2182FA1AEAD069074255883B08434E20886923086D3083864DD22EA3469D56A8A7F4384DCBB04B819274399346544F08A14E5E5E7DE0788854702775DCD8C6A32CCC85C1CFD78D5D27BC651FEE0E3EF0082DAD5ED0399F33C179AC987A2B933268A07BECB62CFBF4425609161E1AF5E706CED78857F3D1561A4615A058635C6D4F73E60ADC5E5567528A63B60D26AD8C8607BF09F4C8C96A6183AFA07C63CC19C25EF43AF3A21FF390185B5EE30904988DDD853F7F3DD4E09F145385FE52358CE2C69E3B14F7A2872AB7455EDC06A5C448298813D7E0A2605EA911A03D6670D08631BA4E11EC4CF9959C38071A959DF07610C3DE964D82FA9C5C37821E4A3FF7E0EA642370DCC4EDA58F2CF264A8A87E21260B4C0B84C5D5CB5633AB0AF0A40F9E4BB3D5A05DCC5FEE2D6C1BE45EF44099F740D35E5A515C6CA1D578E1A0C57BCCCADCEF80FA42089C055F13FFA1CFA8163B0C338244EAD2F473831640ECBFC4F7E244BA5A00FB366C87646A8453F44BE68BF5EB96DEC1B1428AE0C224F82A0CE6FCBD5225F1C0EDB502344066B191B81069ECF87088A81F8CC6710976C65C9C12CD4FDC0964B77A7D79A055A907AAD424F6D0B951086C3583963D823A2F2244741277B15171AEA99A691AC76EAD489F25FA84A1EE6DBFEB3E1827E828B8A04A87B8174F5AD43D0B59D39E88321D301B6506724042FC1229F60BC0D3CB2E923AD72D4F6F1B416D6E83106B042055C9F92C79C97FEDF1DDEE892C080521FA69AB735F91F369595F5DB09F03CC917F4AC29EC03E893D3EF6D536923B9DDA78C04489F020C4EA18A144E2BBE1B5686A1D8C8864AFCDC681632BCA685F5F391F07192F51FC9A18F0A05ACB47F818A12F3BF654A892D396D3BC54BCB09D877FD0D98ABC76BBB3F184BCC3BB294D7BF6F548720C6B8BDDE604476A876E7789D6584B2BB9EFF13FE32113250B6B15EED1C6BD48F54D2353E15766CF4AD88921E66BB2B17AFD3D8C0CC18A2DA69443F3F4CA9109BDACAB0CDC704B835F6992B96D088BB3C7D86F072675EA1C259A4A11DB96B9557F60461F33C06264E3EF6A405BE4640710A36835AD44CDA5BE55F0720313A5BD39CAD155F33261076C1211930D23D2202E8DA8130505E1B18032A743F293111DB0ABEE58CBE2D5FF413CEBCFAA1BC10EEF60477B2ABE50D598247D00917F0FD2C9122DD7EED52403364B14640EBD6525DBEF7AF9EF7051D85C7F80BFF2CDBCB61E0708AF53B2FBA4B6D5D3751D07115E693D68F4C6A0E41270EFCE43D9A888E83A6006703BED0622F5CADB57F6DE5F3E5DB74AF934CDC70B31ECA0751540F255EE3D29DA18069330CCAC2E49BD2E85BAD2B43CD6F39F6601FCCB84A5F47B94BFCBED53536FC7DB0666E0D50A9A567D78C2F6FCA01D94923A6373743C00BE3FA1A1A62C24CEDB2440AD7645475DD6D7D7D616D30EE0E35E5912ED4055A895848094895329F07AE1E201568061E27ECCCBD78D564C38F1681E7AEBE51C02F563DCF77FDC4F32819FEDA21F0812067FAF1FDBA95ADAC178B92A4762551C669057A483453B49209A20A52DCB6F5266E1A8012580B65707BE63DD5619413B56644BA6B5036C68E2E66245BFF8D6A84D55B37A497EB16D01724BF3790931AC164DEA3CE1952912A938924F5D4DFCD5FE398E0727A79C0EA11DA7CF1DD406AF37D91638ED36D8C03404359BA719889C8DAD452A98AF1538CF1316CE669AB2468BA3CBDFB76470525214D177DD0BFFDDCAB4C82E2B1D1764CE850209E37EA76E8CAA553BFC42CE5D2DD483A34502E73B0F04F497B8AF26A188FB68902A8B2F5DD8387D71350C77E7FA50F541E45EF0F68D623298A88DCE27547F83150C2E679A5F8A3D28EF96C229253BBD5B60F2BD7845E354B3D7329179C1DF91626E7549FFECEE116AB6A7EFB4C8B49424B68BE363AAA794BCC68E751B3A3F203E5A9495B440649F9E3DE6A8AE4817CFB738875FFA75CEEB6ECFEC6EB555B65493234EFC90C5203C6312B7EC954B444D706F4A572342059B765DF362FD07C3B48150476D5DC08D3409A79BEE44634D0AA92C6B70EE7DAFCB38252D91EEC63164EF7555786437A7F8A282E56BCC13511D71142FFFE35E6F3219555766A0A08207B2DA4C894CF35206485C2B0EE6B28662A64A37C5C1A9D4C0B366CC6D99E92ADA28792CC10E5AF605FBFC638C0A657054A0E8760118307EDCC7384C9DF458C3C64150925B22EC3E1A1720BFC967ECB4EC5BFBC314852CC17A2269479F1AACD60DFCB1E415EB40136B7A6A027C782FE7D7F7C6D19507D8C2D0F6C250106DC0A72E4448D0585225F9E735A8F126FDEB81192DA13BD806DE1482AD570BF016DAE36928EE49D735F91F059EDD2750D785BB14A44019916BB8BBA2B4F818637BA312D54AC37257FC9E2853C086E95EEC0066782713C98C82F582C0431C531FEAB552E1C1AF0B82D6034F04C85171FBE7BC0818E8BE09C5033DB552FDDBBDF5DA0A048F920B7FA61B7D5B38D1C85F3CDF837D90F64D31FC5EE79209C45A4670849C70C82BA98A7EE2030DDFA50E6952BC73C71A8CC49BDFCB0F10C1304B291221D56895D47C9FFC80FA25DCD12B40C96EE3177E9B6B78A2D9F59D2C2481143D3C70605830E3634931A3027A8FA3FF22EAFDEBBEE16AEDE4D8712EACFB58EADE2E5DB35CF01BE532C2631A1EABF4B5F373E230BC8765737D1F1DD529F10D2FBA8882E62C74937DDF93CF6B769F84872F779D974AC8ED13A55A076790C032D8367AAC64C944426D661A87BB24A5E4861D0EE60D07A600D4D15404EE920573F2F5A3AF5D31209548624B52D1001D2477097A25A0D480C1A1A04E7E1FAF0754E4DF5EDBC0E5BFBF152F23B54B90C55A8900F4091BC9C7CEAA1C7200C017D5F99DFD5FF5D7DC33168C4BB834AF29F3F651C9657D3E1653A7DB02D7E61BC48A13EC743F3107240F53FEF424B864577BC4E6D78E8634AF636333063B366F0AF833949B0770B3E545C563E3B3354D87993940A47128185D74EBE823EE752375264143555E6D7F8897A7C2CFDAE2013641586A91AAB6BAC1D2F3FE292A4C51595B6A7985999CC0E0ECFE0B181E2E3046477D8B9AA5A6D6000000000000000000000000000000000000000000000000000E1B2A37" + }, + { + "tcId": 6, + "deferred": false, + "sk": "0672A2BA2653D9EFAADFB90DFBAC95F77BE8540FFAA866671AF76F7CE585A21A5EE3BC98E969B2DF5F910F15A109DC09B91579F8761F4145771C80666362EAFE59CE336D877D8C724953C5738F65F3E1C551C1FFD9DC7E627DBE0BCA5174F200E8CDCBB1D8B0F84569DDB324562C66B5692C9069EFF52A7E4ACA9E293B26C1BAC3162A43808DDC4248A286401248649AB208E020462106815128900A984C94988C4CA82090926888B44D4924495A426E83B6050038500BA38D00B96902436E9BA484D1B88CD8A42D043208CB4089E12032613210D144491148258B08694BB00CDB280003C70C98883041A40CC20612982402DA06498C362C822209643089A34624129690818270A3108554206DC2B66001426A212222198204D1248660A065D0482214372662384C809808248040C1A44C1A4692133430C88808DAA650D812920230518B244CE302300A114CC4246A4CC44523B044D0B80C633800CB062EA4304E103051CA084D1BA349DB4828D1464D9BC484D0042CC9B60103A64443941080C66999100181142403050293264C9B028E53180D8A16411BC0290C47259C482553A405538401CC8868012882E1980C42440208A32008836D042292882800608408040289820812D0B609D992248C022C0C482A13920D1400244B380081188C0A9328220808E1460682386120196059441151A80D8C12321A07881144116338255C340050A064C0266DA232308CC684A224710CC72D5B323111246D944011C2B87108054C48184E49A6910B451014816CA0480A222588E2203050A80551366E234820242932D2C40C9008081A9750221345A1304D14A088CB06111104095B928891A001C48848E4264C0BA2499B022523160100924DA006908AA481A312481C9281121842040152892846D0840513374419B9911B010D19912C42386559466D802428E3068A24952411C38D0A1491498400C082655C448C23476889308253300224186E08414202248210846594288C1BC1210A246693A8011C041204308C9C486A0C47460AB50D8B288C58162100354E4C024E14B05112C80D80C40CD1484A1A36720B372419440962048D48424E91028103B405134082184520DB4288E338019B460299B860D8106D13240AD0B08818996503022A00372012079082B04559A485D0266290822D0B324E218291212006C90270803681544092D034640903011A90510CA2085120229BA009D8120452028820315184804C5492000403810A4809FB030EB7ADE0094AF6D6A78EF4A30D8A22BD35A79B413822D86A8ABF9BBC04D838EC1F2150FD86A245498E76DF32DE661DE605C76757DA5FFDA3082DA464400EFB1393D92A3A53270E0F144D255B5825B05BC72C287634A16EDAB6AB4422CE3AB84E45DB798151B1697FBB7CBBF0FA370D1F57D887E5026226CDCFABB2D502F7A82E983B03BA41D643DA93BFA387620265DFA80DF45E82C74C14963392199609CC59065A7D4C26646A87C04C31B34B2A70E029C24EF993B30EB53EDECBB4FBD6FAD614C581B3C04A15AC777006B0293183CA9DCD587960E736F780B1BE219928BEAB8EF5DE4B8A03449F33A65B2B08DB13F4B7DA0B756153A322282AD8F8D8F64EBCC6D322D519D6CF1A8F684CE469B9B9269759944CD1A863E236C856441F6C2198B73999AF6EF8140C9D23095847D3DB2518113BA8C96D6871C4BEA7067C0BF6947FE69B3FE12081BF58DE113C2B487759511CCE1FA48D814FAB7F0AB1B1323827A8DA71454578F1046CFD395E3683C332DAA81867B112E8865B6E2405D5AD2E57E8EDD695C3DEC48A52BB39E590ECC8F32B5F80382F1D444CBAC5FC7378C4D8EDB275CAE3DEB4C298EF20E6E4E25DFD2996769361ECB2C86AC0D28287685219F60213722CD172A2A2ADE055B515955E2D982FFBC13C2EB17CBC96371EB69C35BFBDA0DED49E6DD63021F38BA0C7E30A655401B6B8A9796A675FBD5044E64F6289C69248AFBFA217B68A5499E605E1487A07CCD60EC743F053731CAB8A2EA92C4BCEB56560FE3F55B21FDD604E6AED8F2511F0562B6F1AEB40B70C116BCD8DB842E26EA0B325246F4B6580559F26D6817D6BB4FBAFE4B144B26DFBC52D45C3DE758999834A642E871AF54DA2C86D7D4E3DC6BA54F5ACCC8B6D74EF7AE1BBD0C82D76A8E837F47BD53B8DA621FFD51A05F17FA88CC3D7143DD4B36F0674548FB886ED228BCC53B33998C3094258ADC3E05E24C5A8BEEBC588ECF45178D246D20757C287FF45149371931C75A7C59955F5BD1834B6738DA57D4FD28CBB11ADBCC6A11692021D5AEC5D36D6A992E7321C9FEBEB0A8544ABD8DB5CDBFB40889219F893FB4F543C22CA29ACA96B8E4C48E3FDDD763D5AF7C4A69AE763926F6F687130CCF2A2EE5EA746C3F1AC9772306A01E378845F568D3D885D4C267708B2C352C45905C7523A3C390B89F3E034D4EDAD9327785975D7286B755CCC9D9D4874B5A9DBDF90544421D7C6B2CD2876C4301FA891A2836E1C078EB7E4C31837DE4B8A38D270024F121DA31F48021CA533ED61FAB4B5C08CF3CE5DD5300722CBC6D1A11D068C604967D525394E88A0920EBC56AEF47FF4807DC5245345CC7CC13F5BD929EDDC183D10F83E5AF32DB1F7D87B2B27110B4A6D0B3AB5252079D4FA1E5FB3D667189ACC70193C1CFD4D7E3FA9BC93CBB834DD3C8854EEEF5FB471D73B3A35689C8E04A1367FD191DCEA35A661D0AF567DDDEECFA8AC62C34DDEF14BF848B35C9D97BE3978B055CF895477902B40CC35F3A7DEE7900F5717073486E8C995192619F7BAEE5EABCA9B314B4D0F3F602CDEDC8084CE573A6C7BB59E4E0048EE367D7FC40419199E0B104DEB93B9E36BB510B8E40A00AB9AECE27D5FEBCAC6134A303CA9B07F332DB85A8A03A56995876A74699A8170EB695F77395341355AA8AECFD30443824F7BA6A07034AC1638F4C6B602C48A0F11EFCF4CF765F886DDF128D16518F2E7EF3B4E6BF799D0FA82C152832FEFE7BDA434EBBD1C81128ADD704A749D46B8D5A4BECCEB7AD6E4959F8F4F191002A43FA609299667292332BED76228613EB5AA536F15BF7C2DBD73A002B133E7E780DE1F0A3F49FFA1E32DEC1DC496A0080CE85130FF9622882A61CB392D3233AB3AE81458517ED1A65AE45C6577308FC98B31D74B008056B666E70423816151EF5881812AADAF241B299222AB9F6F0C0178196846958E2C1B4536E2110029F1E2D7B8796B049EF697EBECD35E467704AE9248836634194BCB51E4F8474FA7699A1125CCE9FB62F16BF5CE11E422DDE6323CA490086F2F9D41B7659943D455C90BC978726707CBAF0224613828281276672CBA3FD13CF37609CCB8027FB026A8211DF8E13252AFB9DF7F13423BD9477A0518D581326181498DFE98D30248DA71F1DEC92E7453DAB2CAA2DEC15E1F73A249D9A8DB45D503780C94DF2985E339612AE8D9AF07E96E3B54F233636E180867619700CEB0DA7C2362496013D14F904C30594D6DCC3FC5424AAB9A4605B34808E22C697DE85453D4E9E55E0B7C04E5CBBD8F3530676B09ED3A0D5870042940C900514D9361CB3E3C5FDD687FA90F51C0A21A0E27CB420CA68356807DD24F", + "message": "0C39B65F4C2094AC626652CD33CFE44EDB2667CF722443514CAB443DC398A8EA009277BE397E1C1E7ADCD1B24376AF0F19EA50E56C90D683F8EFDE693F0F8834199544E2DEFE392B0BD46048A83C412A14834C4BCDC180457456BC72AA28F2DB247AEE84A1C49266361DA7EDD54BD9B562889131EAADAE071AE5A671646F49B2C1359382F1A3B2A6B437F87CC99A2A1BC821E1F3DBB311B8FCDF28546A479E2F9970870066A2D6447B6CE4FB65ABE7423910B9039EE3234836F924C8E82E1299335E27B0DD642B812480D6FEFC47B121A710827DE1D18DC12064649224FBC4526AE14317CC8E53BC8E9BD42BA444AD9B8B48C3AC807D7A7675F43E3021BA1DF9AC7A42A9E23D696BBD03FB5C4702B55F95854C41F470CDAD8A255436F910C089F71C2E59A44221D78AB81D4E2B059CC92A3841E1431415DAD4E6EB0315F423DA512661E4CCE098D6678F560A4BA19475296A2A1DEB12AF5900FA3A3C188867E0C268EFBF7AC53455552DF4F36E16D50E23048C7DD4E64341E6DCAA0036EE045B82C42121B0B779B5E7FF032F549536ABFB702B1CE4EAA5E389A077F47B1B55595D4888A4C1D17F4E21706779C9CDE25DD1261C8B4761A40B69E2F22F069A264E79CDFD36F307D117FC737D88F50EC67CD07D8FA269CF265A7E7CAC93E97BC29EF95C88904AB2DB61C8865A6EBB23871576DBABC83920AA015D47E8CE699A9E57E139AB7D233C577B46C9C314D084A1674A152D87D2A3D8A5D9ABCDA22E212B8C9A2BF25D8AD22AA3627E6C12C684AD2BE917F094263982D396364F4DE0BAFAB2DB89997DAF8B7E3AA953C055776FDC29F8AE5C28D4071534A9A2E9090CD3F723D3E381A2ADA6D9463FC49B3C6D2B76803F5C21D8DDCE965D2C472389D2BEFF448F2D81EDEF1C851A863AF66B64417BCC2CBBC70C18875055D171BE32C06081362FFF7DE8F8A23B076839602E2368CEEB79E4EA53F42F440D167A902A23ED53E6691AD3332DF5B0160EBC3B5C9567CF619BE2201447EA500332ABDEA9B849C3A395F596F2C96ACD9AF8313E453277B9F4234874E791E9DCFF0C9D9DFA8FA9474C026DD34E5CF3AA10CAB1FD23EA5DA0D0A66E520096C6116944F2E5747A974BF55428A3D2475F6276490AADA25220F2F2111892DB9E9C75A5401BADBF69F31B77535044DC50B1E93849F19C0B6C5184F1B14F68960F9F469805F3843198AC68E51619F3D712A34279AEA27BE4357A99C44C456BD2D9319147285680922B98DBC4D6D2860515D1371D2141C7A1E76EEF8586AFC973713EB89C1F09A84AC064BB7644625224FF1F7316B9DD1091CEB151D1A040F7E60F202728F7862589E7F1FA32D39653383F90C67D96D9949967AF234592903CBB968E0D979B92B5C69D09EF4E767741F1F6E361DCFC8D751CB8C3BAAC4CC393D63F71AA1488491CA06CC20B0BF54C5C225B6F0825677C2C40A395E1B7322288A815E59AD2999D61FE09C95828CE18B2997AEDCED56CA8BCDA4343B1E948256AC5EBDA23A8E6D7102A4474CE23567084547F2ADD9DE77483398D81A9A9C7A573D7EDAF99536D31C3588BB649EFE1495CEDED788EBBFD5775842D91DAAA2F9BE08D63B06DB35E72CD0EE5DBF45DF9B0CA682BD944A733D6875A62F8C53A3FA9337F13429FACB288C73220C29285B2D87DF2CB1A54631AF3D0035C1F3B26A5EDD07760A63576A395827F3D5F9B03D9E47A9E1E6A271021942648B8424234080492BBC56C692C769B5DF32A75F7403C88469E54432A37A895E3CAD3AB110089ACF534A0D78C2083CFE149A2D0A5055EF9F4C943CBE1FD393292518CECFC57E4FFC4D07A563A30528A6A3540636A3BE770B7CF03F5004D7C6F8ADA08DEAAED0422AC0C0C8D7515C9F8BF44195D6DC30D9B3036DA007A910BD05DF06B032812CE8393AE2777D717A691D07E860C1EDA60F6DE31F0787097D0D483E3A51CA7997646503738CDBAEBCC21AE4B984B668FB4020C139D9F581EBACB7BE263A33955DD68C9ED9BD2DD6C0A7BD049972B624CB7E787DE7184023F33EC0A1539C4679D6B4677FB971D763BE17D989FDF8C0AC4E0B5A6CB40A49B5464610A110EBEE9A21BB0D6A2F043015EB2C8820DD966A13EFD18D32367834D41E8673E997B2803638A710580CA08DDB4D90E4E8EE584BCA2FB853A122274142130A1ABCDF7DA6C0056689195099CC3382AF6987BA47EE294353674E7295ACC1C070F1D8E4107AA7189F20CC818F1D86F6D646CEE911B304E2FECD5A14CF5F36331AA86E10C319C96E52996D4CC12810AD7C1DD1DBDFDC78DF029BFDE9E8F9B1FC7D9DA99FBB0304A8129EC58A82177EECB7330E715BB3C0B4482923C7B1EC0D1823FF643014C7D08A8F2D9F9090B0F83663AFC5E601E5FBE1DDBE678B9D93C5A23F564B8A4DD29C8D19106747959E72AFA4B16B879E3C6E7F79A212A144F9AAF665253F1360ACF7DF37642270656583E06FAC85389A3AD76E69BC2735B1C3E13B80CCBD298EE25C29F9F5C275AAD83BA0E7C47526253BB3125EBDF5CCD6E1C4F9D9CD4891167BB4E4D2AA644D5D362C6F790E2776BDBAF8D96DC3A543C72ED46E431FABD737B4BF0F4B32E12E0520E60401CCEBBB40180985948045C58B0017C3D8797E433A2E2C64B9679EC7409D59B3992053EEF2ACD7B152E5F564196876EA0A31CB6ED47F2455BBEE6827D96C6B99E46F3DF1FA21F593E842B26E83D843118F6833BC273E12C7224E00E840B0041544893C6C8A06523DEDE2ACE7365693BCC6A8D7DD81B01310CBB8084C5FD3868539F8B5179519CA6745B56C4A5EEE8F2A8A60CBC7453E1E0990D176446D97F34A2D0BD5C5712E2D82601D0B9FC9A3F2420C65E4532DB3810FBE3635B2AC3A84415535FE41208B907EB3E97AD63DDC4FD694127EF1E948801B5CF651119CE17BEAE3396C098A86548B67DDABADCEEDF60F57D2941815778AC14F78C78516F84C5F9749B433DB97A9283A94697419CF94248B6819D9310324977D47A133AE9F1FC141B56D6302817761BBD52B4A1EF808E0AC761426C99E0504ACB6B552F9550D55DE787C12A0409A9F9EE3674617D15E229AAA98BBF4FE49CDC81DA3AD110645132B332B6D2AA38B35320925135BDD225053D6594E78389909E596C63B85DCA8B3F6C3233A31A1F8F3E900E49DF83F649E592979C9CA4BE65E7D6D1F23A7744626972D52B07B7B89CD90238A5E871666F4CA6DAFCBF34FE15983AEA5BB7F9917736F7BA46F342F0C08F56D19AB9569FD23288EBCBEE7B5924B8C86EF77748F3AA9CF2FB884398F83772C9771958B6DD063162A3AAA42E6A3280FEDEEB7A628A07702950975CD135D6338FF959ADDA2296B3E85A024F63D4ED8A5859786E2BC76C2325F37B4D91EE8B64F30E781BF48ADA774C1641CFAD2D63A59E294B5D99C94108154E38B499E3CA2A29AF7CC77A8BB3A3B712376CD081715EA715305C18B51470D5F3A6A82E9189848311511E8B0ABACF856312AE3916FBBCF6664523684D3C7ACE08D2345A3907C9C07183CB3E68C5EC3899A95430E278A72701E2355A4AF606DD8F8750F7F3682FB84290B2BE23BED99CA06D5E54190A5558C927C369C00C512342EFFC41618CA6F8FE6E3A38D1714FC44BF5679C1A49CD8BC8B28499602E277DC8832F738225920709799DE6961E0B4EC12397E7891AA772627F66F494AF719C55D056DCBF10E8E3DDF1B6C1BB2F0B2FA61949D1CA7D4E1F60EF836B086FF8C03A5916A14EB2670AF56264D7390761E6EB6F638D6FACF56B72A48F271ADE4541C8EFC91D15F69E0AA6B97EC0E9C0C3EF169E4A4DB1C1AF04762B98ECBD0DC374224D98FDF7788435BC154E1FB06C970A914C34DE52678F61ECC1969A2C5B1FF4D82E2C80CB543B4B7C9DB541229CC50CC6C448DC029CA24ECE635233C401D3715671BC75785DCFD929377AF5B65EC43EF45A9B00CC766695A4A5DE9A2E6582F7936B9FE7DBBA6762C41453683146F4ACFD809847F866DDF559972FE0C093EE7C9FAB3CAB0BC2BF8DA19466A96BBF2DD4859E2D1CE122A3CF16AAAA9A4708F72BBEBE285E1B794B2B9C7A699B36F39F033277E8B7BEAC3BC70A572556EE5C070A309D9D0BC35F4B6E55ECC91CE9AD273B0098F64E1327C85CCAEBBE67E8A118669653495D2FA09C29C6FCDF870905B2C8BE0DF806C29D5E7AFACDAC5F89116A3474D2229C76E649F99EB9EC71A2C229764A477853D68C39B8F0BF4378993AE2B26E814A337CFC103760CE92FB564E3A3E4546996CC4D8B6BE069E99861DA9C731B543BFDC006FBDE3B33D2C8C4A3F5789466122616C98F52E5E4BA239E0C3758C5BDD3BAED8809F67A70504BA061409A9D87A499236230EF0F1985DA0D765E9B7F733A154E8300490F458847A89E7C6BBEB7A9ECA7B6CBFFC3124DEDC1093C02C808DA1CDCFF5237745C5FFF51F3F15CF746D3397916A45990070490CA74A55F34EA4BA9EB73A281F123035C005BF6C7B30852665860ED13A2B5808F81435A77A8504B58CBA45559BD3BAA663A571F108685E414FC4DBF8033075E30CD6FCD9B893DA32F7C8D5D971D5EB417F1201B00F65DEF4EEED3B55B7FC7E6194B72A861439B865558157E65D4C2F8A1A93F48192099B375D111370F830B34EAF3225A16006D4749494B9AB9D3B05015E34866A4A2D94B9588A8DE8AD4CF90F2CF422634E8DBFA0FE3FAF27C3F3C2EAF9C1BDF23FDF43D196732E1FA6D2B343BB7D9F5F26FFC31B26C64A8EFE2B2D86AA34BB618FB58CCB54486211A8E66648CEAE52F07A6C1EB5234DA7CCAA971AF984D6050D1A81F10E6D19CC44B5E668CE92F4251924B25DAF41D5E381C3FAE4208D18F710B5F93CF3C776A3D81C608B06CE6BC68FB8A8117CE7BA065675B88510F2E8A440EC363A5983DDC1352E446A482C593A490AD6093258E447EF52BFD189ACD11C87A8B75F08B5D166C1DA69602EAA5916474131E20F704DF84C3FEF2AE99F9B9E8F7315A143A07C7AEDE5797F503086DF7DA971244A61909C4AFB00842FBF4C3A59B991B58AD6C0B8667C449F0D97F34CC41FE935D9F55821299F780359E2F631858617437D4AFE67DE4A1AA382B93CC3FF596726F0D1C071FD0E00883E9E03811FC659495AF2A62B45DA079A66552F2928B6A25C6416F8DECF723623764441E5E581F9B2E36479A1B6CB3DE9B090E3343277CD7F84E80219793CAED4945DF782C4B72B498A62A1F5362745662F711A7E47CB816EC7069D10CA8314845AB0C9FC326C5BCA0E2AFFB4E6948522F8CD9C8DC008855E592AEF1F8239748916878ABC493E33CCFFDB86CC2ADB99B6251F493F0D2A0BE56D133B66395AA695F6298F7F4BAB41420CA9B8CCEDF2719590287928CF6BB3A506D6678B814076B7A774BE9B7029DF9F4719AAC1D012BBD49EBCA6AF124D0AB5C5FFA92B4A895CB76B88DEA9C7105136D78B76D92079A5B001B214DDF7E140861D86ACC260B72ABEF2CB3A75C2BC87B39A9D9052D4283B71C10AE275474E82A5FEA1654EC3ECD468DE4A015CEB67BAE3275C2C79863E2883D46FAE351F0908F42825DC7D9FAE0FC7171791FCAB10E16F3F027E5043AACBDB1F05FCD2B3EC7F6F46AD6DCCD6F9E6A6AC702451194788D14261219F794EA195F2B3778654BB373C68AB4333E224D161A1F89FE440BD8E968B518EEA28E81B89E04FF1A85B879E4B54650FA8DD1322D14B4A87", + "signature": "947B02936A53FABF0009C0ED2E82970B33714BD4F15DDF7BC3A895DCEB96F9304811F783F8CC627B5B80868E23EE36CB98E6A5F9AF020BC5DA891E898BFF4A5AE003268A74BA6088E920511F5EEA54A5338D03356EE19C79E7BEA43AF809BD763EDED9D639DB0CDC790BACEF8983CB91F1087682A4E707E94B7D00EA8EDF04B57D5117F84589FA045A7B4A75C62FF9A344035E8B771D66D82156E28EED855DE1861023D5C1CD356C225AE03EA0A11BB1231B784CE9BE0D54DD6C4EF3128C7E14928CC0DB36DA5F81CCEE1924064403E964D375B071FD36CE9595509DA0BFFFA4E4C2DE1DAE201A55EA124C86F9B963221631AF131D2C4DA034A7798817D2734AE44282DA3BF2803D4DF90B718329F31317E5D585E323DB512D2036B74812C11B219729214B485D05917C913E742402ACA2127782534EB2DF176C5C25C484ABEF24A969EA2EB524FCB54A7CAFF7E6F464D8E716689810A2A02EC899685A1E28C2FA215572D188D3F39184D09EB93AB30D507DEDA6D6049E5345F989E071D26D909170D7AB1BD6CC35AC198EC7C0B48FA5679D24912E9EAB38FE594F1FFF5F2D97ECC84D8C81B81B2AD476CA93E050E550887D017E55B2B5D15700542E90A4639F55A63EACB727CF1F6C76D1DC7B6C0FFCDCC1086B7D8EE1C6624DDEF545082B4A4BA6637F8B77214914693DEDEFA7E62F5342548C0264206C30B631486CF5522D3BFEC6936AA961719984B84C43C49F2399EFAC02020613E97E16640EDFBA2D74ADFF5357A064FA43BEF8CC7D03AE781859942111E4C14CFEC01C47DD9FFF9D3D97EF92B4AB04C571A0C58DCE3BF45CDC01A7E09F7C89C81BFC06B5A4A46C88FF95B7FAAF3576D53346D18A0C179E73C4DE8501FF6B49963E2683951FA7E55B49056CCB0BB6759494AFC8A14A1D5823074E0C17DC279540D29C2329635189397DB8EC9F8327958BB00DDBDA507E1B54C226E7C02A680FA84E935588A435AA1CC029EC15CBFFF5B3AEC29034332C917882709A95266ECFA14D4459D5F7C60AB739AB428CD967CAE7D1D925BA66365A522F4F9D559D3268913CE7F0F228ABC49D4CA872878D7902F7A202A58FFC7D54FD7AEF88E31FA605840E510C639D0D568D7BCB1A72268162576717A238CD3416E89B3A77163529A816D613928C2CA18D2B2C6728FD622432E54A9085185042034D4DC8EA8E9F100BA7629201636CB87B2E5DF1F95FDEB407DC330716AD0D6ECC93BE38E497E1B38B94DB5DB6A5C067C6D0E1345AFBD7D2AB9646B16C531A96D4B3EAC2E540D479118F448780E15A3C17FC34051B4137C8E52C84495CAB2CD93420FE657743180C93337E39306874F8D54DCE702D5729F82710ECA144F040DB9A0907A3CC4DE9A12DD3958047C157F826F9C054CAC044567CB71A727CC9FD94DD0A388DF0A167DB6F9F16FB00DFE96968C463CAD7617587E5698DE7AC658E954D94AD94A1A3E6A5FFDF9B7E49429C00212839005E29803DC4CC4FF778CC331DC060E69279263005685494F686838DA7930805AD839437056C62510081D276EF676739C0D689B2415D3EC4C0BF67BF52C9A2845E7361BEA53111D6DE6F5EF65A22A62396BDE531886D71B925D91AB1F916AAC97201CFC477B694E898AA52AFDB46787BB85F01917B06E34342D2977E78A5A82CDA3C93F34BF9A99F7AE9ACA24D4BFB2C57485934EDFB7123BAC3DB085DB5B0F2FECD29AA6BBA2EF2C2B04F66605678BEAF90F448B19ACD4918A337FC9ABC098FCC804AA1E37E22C9EF010A9FC40CA42CD270ABD9E56D31B12663A984513AFE3917F3982F32E42FA9D67BA2E5C149FC2E6562E7EBC24DE2E1C475D05028E69AEE688EEA60155346843F71F1F99B3D4BA69DF71ECC4AD75FAAE1921EB47EAC6C4B73F31220F1993665ABA88F5C504CD7F6D0789B1166E4CDE2CDFEB140356CA5FF1B5074661A90958E940B8A7F80CF298B8366D81C4EA232DB4A8A4153028F9BC9B9758BF1BF27B7A4887D48A09C453E3F81A8D7D92ED7DA35B3828463C4F2AC5BFBDADB70FED3E73BEE26CF0B973FC6C00922C2BFAFF53842BC71294122CDF7E057931E46790356856930EE6D653A70F68E107D86CC521232ACB62F86626DD626E1D5745EB26B91917D11E68A6BAB09B6BB0BAAC327A37504E3B10037871BC8D92466D2EF236552C1F3E80102F8FEB03BBCFC4C51039F17D5490FD61A6E5BCB4BEDA507013CEA1C810E933CC805E67C1AAC6DBD9D9B7204FB5560D691148F7369996B48D370F32739ABD5E1DAB98BDE86FDCCEEE4459E3396C8ED7137BF5326322AA7A41B2AB74CA5D76ED91DFB678C66874E7C6B4C6367A5BF256DDBA53BBA20AAC90C4855CF1C608774896A974DF5B1840A83B2FEDC619D707AE30B186F9FB75BEA7531035207AB889B92FEFA6D9802E6D44598F534390178F14E1F629629F6E120C1DC8F5C14C392C117A239E539A602E521360CCE81F3E70D94FE371A13B7A42CCDB29709428D3EDD96CAC31BA34B91BB2A92C9208B7C81AD8300905BADFB91DE8632C7E62C4D4E4C32616F712BC4A50858FDB651AB486B6D0D16A0BA10D128D539E3729F364E628A93DF73DB954C5D8A1CB6935E1D5D3AC2F905DF189736539298F7A20B3C705453CBB0E991ACE069DE62A2C89CB956E8E0110083C344D971C61101DBB2978E1831885EE7C27A6CDEE29402552D701663E5579F450C4788D46AD794217926CAB7EB351E93CC7D3771975A969A3A06E789EFB410FC829123BC00776E6940D8C15CC8773992C0FAB5CDC59EC4AC6A8889EE8087C26AD7702A8672F711859A179CDEDE22D1A77D8693395575ED4E023B903C6F14FF4A2191E49D4C21398E484B3189F50853B0B20B2BBAD0EBFB75528B4B6FD5C7B7B71CA9D4DF36E67ADDBD7305839E7FB2A25AC53AA1622F13B3B4C4E8CC8198269065717451CBE58B8DBB1F448C96D5940EB94460618036398172A2F22CCFE2B31DB2DB562EEA7415AEDB81D65EBADD8D2CF04C69D870C898D05353D8C5CCB2E37A6EA9EB3E5E9DF32175888E07F4472A80DBEC699210A1E6B8F4BC7968C3FCD9666AC9D1CC81C3428A26A3A94C96292F3A8341FB90350FC79DA7E0D947751C6E1E17770B980EC325E0E87D8A283F0BD853F221873853DB22213BFD7A7D621F64BFFD73115B48C4B06DC11F307538CC86B351CB23E199E15733A2B5E3E2360B42A203F632A8243B1557C64773D72EE1D3E3E25AE943AE3E9F984D116938D39005D4556B76A793AEAF0A6397691AF7386F509668B435DCF7B10A8B810FA55190D56DB430E0061026292D3E494C707C85E1ECFF151D1F243063646C7D8D909CA2B2BFD3DFEDFC08173649595D667C8598C5CBF10A37456575839BA2A3A7BBC0C2F6F9000000000000000000000000000000000000000E212E3D" + }, + { + "tcId": 7, + "deferred": false, + "sk": "A7DFE40E0A335C3B287EB94E97BB6875F589EFCF7FD841EC88F9D03248BF26C9EC8E7F8DC376270F7112B52DB67CEBFB8A5FCBEB0A2273FC3CB8FF1CA1DEB5C581335B8F6C53E0F8513C42D5AE82B193BCB8BBE9298446ED79D278DFEA201D0B2667E3806972F34278B83138432AAA10065DE34B24303A4E5BF1A5E3DB90825684A0205948885094459C3840C916061A284A8AA40CE0A828123369E2208254C66C91A06C64426AA1B44508418220379218170803406C5B384ED3224A48A2519A840DDC420294A82C14C105118070592009D00405C8B08DD2222920B8880A39511086805084910A098AC3A84C5824080912698A486401182C489804CC14051912250832855A202942382252B8880A814119032D1BA5214A448492366A91B84C1AA528513669DA240E14820C08A0244A444E83B48C22224212C985D014690422824B882913298918A1201293306400201806451C8051D2A870D1444D13268A1C376D84186024C6081A262D011621C3048E02A06C832446C2C20599826418B86459B0618B240422B58CE3080A0231229C244DD4C88448202202868063B68543A68D1A132E51862911B929918868D9C828D4320C0149498844105842269CC265D1165064A27049A029C12641D1403100262A51828DDC2401C14670D3C0484C962909A18CA4A485889410D00030C9808C8814501C234E91287218490248828D890005D4222D0BB26C21020018A00098248960A88D8B921062B251224282D8B02853A090A24268CC0651048940102229140988D1322A12C95023C68401068889B62819180E10468D03A7500028051286248B9880D3242C0B172111176D5C048991888C183388D2268DDC42450208300B302253148CCA888D89B665111482D1A029E428315B462952B221DB126A01B90C0A3361A3420D1A3528A232498898802011285C200EC3284EDB283120264550C04903298021004A1C347098360E11A04914390CD9046408100D09202904A52D524400D01488E4084823B4110B907103440C20425021085212994CD1A8290B4229DB1229D3360513256162340814B24450068002C20C22C98D4B968520962480402C51B26C0922424B8041984809E3346E24829024930C0A1348533440843004223826A2042C1C9484001860DA864D14331204118E030144E3240263C029E288291291019AB22183B29153222051380400A244D4066E19160E08183120388C14B88420152C19A02C22192E448468D3B048D310612181EF7DB8F0B9A7828845B0CEDCBA94F60B86C183E48327BF5CDF316E9A8F55571B452EF600C2A1AFC57A159F501016FCA48627C1FA9D7C3DDA58BB4D41EBBB6B7F9DCBA591719CC4B9ECAC146BF8788B48C911600FEAA5683EF2D12C45A3C14A0A5A62839944B427439881DBCE4481DA951B10D81FC7711D64CEB088DB4A70B5804ED577C30356BFDA58D5426DFDEACC6F7CAD7C30E718E7FFF4AE006BD98232417ACA13359A05F8B389FCBB29E9B670B28CD8AC24F3ED55F70D8BACDE3F144E79312D8298FE6AF01996E00C5E8D940A408D532CFBA872B461F538E0C7583A73D8C93E9889E251EBB4C7B1DCE6FE013DAB5AE565DC3EF4F4F5429930F1A6DED98A66932BE3B985E4DEF769609E5EEFE6EBFCB6FC56E9542FE4ED8A121ADFE9E19B8F9EBC4B9C1F4AEFB351C2D3840499D0D2227B157DB138EE62860F2963D6F3D6458F457057E4A03A72ECC52589B74E12F4EA37D8E0D9797EEDB246B88744602332EE0886AC9630D876BE34D9FFF286B5CB06498C60CE53A558CAC63DC5626DAEF14F702CA476E4C08A569DBEC1763DB6C5910B8D2352C6A648B2A6F27F9E248FA4C42FD48E7E9CBF37F318A8D4362C1B53741B41E4231680A6F91122520306325C2621EB87A1736FB79098006E83E17E7E22637688CEE4BA8A399EB1583CB8EC9DF3B8C284A230AB6622D73F590D19331783CC2C921EBAE23DC5605F4707CCC96A18924BC17952916A97408B4715FF3F9ACEF8FC4943BFF6C9F7F5E7DE18B93E679D49D04366A658AB913EA5209D22D72B62992383C7EAE704259B5932FC09F76A12FFAC12605D8715366167DBE45B272EE7EE27817128EC94E1C1299DA8F58E4206D477AAEB8BAA8634107E14059E75C90926189D3FC06C9D38799F3E00BCB87637EE24705551A797899C9EF7FA41F61342E9B2480508D9D3401EFBFD12776EAD4CEBB815F505E1347609AE7527C81AE892C841F0D21C7F97003D5F9F3843DBDB89A4E55E52BF915B92F0F2CF0345FBEDA99C322FE7BE34E0E08034078FADADFBF0661AE573EE9B664C9F05A8AD3F02B1866D24B8230D20FDFCD358BDD88AAA4C3E458CEBFCCAE2D65C64F6066C7495B571814F714545E6423D322848459DCCCC2120D8BA7CF672F37C5343085045FE3037070310E851508A0D5605249AF5D911560D308C81C7E2F2538A0A7EDD6DE341424ADD8249D628599953F857913F5767584A7420A669AF08AD060281D536C170F383C450CE8C61DCCD534AE64B91AFAEBA4742808733AA718A13BF0A55B1BD4AD618A932F84F8039754E1E316C560AFE646D98E928C28D39F5BF2F0D0E079C6BBCDBC5843A5FE72E99642B0E297F11AB5B9C629BB4601230F33837975AA2C81664825216D8821B79802C0C3812D1C0140AC676860C565E7775ADCD2D41865B23DC61BC5BFD3A80F56561DCE6F2A79D37E85629FA6EA952289FA3AAE5DA7D4E9238942684EA932F89AC0AEB15263AB2D5FA4D3D181851E38BB2B3B5702E6E8DA5CA981D2DF3A0A7371A75EC897A46205D9F05594DC169333158F929E3421220EFF6204BDFA75E41481A3E70BD4EC1D4502D902698C4FF7FA6D69CAC4A8F67EDB414FE5EFBEE8A6B695B218AF6FCCA45CF900550681B124CE36D2D9CBE8B2F179B4A4009281A559A6C5B30D4B6DEE9BDABEFFCA70446166CD353D8905641EF072F00571CEFBEEF7A296E7F49F5B112F6F0A6F1576468C75942609484DAA448F4508EAFBF2E9DFD2F83860831D6EAB17B8FA73E493E3D8B71530719209FD2D24637D6323FB03E3CAD1FD601F1FBC7B408D3AA6B90C053BAEAEDDDAFCBEDEB3CE0C6A70FB83AA450A9968CC458C18CC9571F74FFE1ECA182ACA2C4EA57A60BAA4D922AB6B006EEA433CF69448AE44A807846361F5E09D565D89410C3CACBC284DA15BA53860450E28843A662BD38E89C0AFF23ECB50B85C7069E44E211DF89CB12E6CC211036B0ED7EC5C098027A8C11EEF0898B785DE421C8212EC9CFEBDE72463F3856831FA209B8C21E63CADDBCFCE247F0D831373B7AAF82B676FE9C7E3CE70752AD0C45FBC3C11B157834103B74597644E095C386C6FDD7C9DB072EF20AC511DB9D4CDCEF85330E1372512336D5CC951A7424A8EF7FA4CFE956B6926DB9E1969747B814EC682659DC28A088A37B62D9E84485FB3B33B6F69BDAE3DA0C7D734713632B9926421B7941BB44D141AE72819281CC405F667772D68837B58156BEB2E2EDA6A51D9B9A5DD972E70F3F2B9DFE660884250CBF8E539EA6E637A693AA3B7E34467ABB697AAC4FB376048621F2DEBBD94E1DA4C9A1D2AD21DEB16A94BE1B0DBF0B5DA2C38B618CB3323D9F", + "message": "214BC54C508E63F77B261DC59588A87CF95C233C22A339E7158C47931C1EFEF775EB3C91A32C56E888214F9F68D7CD2525B23F695871CF5EDC6979A677EC19CBC5859C63ADCE2E38C67CAEF20116508F33BE8035E9C47D124EEA5FD1651D64371451B6B96601E4A6E8292ED6841E483C3ADFC3DB242D1D7B3F036492741661F45232104A528B6FF79AA4630740BD16B37CD3E7C711B76A259C0845D6F87E4A4B306E939AD1C41022A7D5938E52B98485D95D11BE629263E6CDE20F63AE16CC2E32B6C1C442EF108D92495A759D3707AB6CF3ECC5AD7C02F133D689E252A26C014A31C65A65F079C622BE3B648496BC57C462051B17175FF81126B5BBB5324CCEAEDE0B5A8ECC0D710F04DC0C751318E8913F149E701AE0568B5426736288CAFECAB1779C7F4E96D9007635F76DEB4D379918447F30167F257B8BA825A50EE845FC4AF7C34AB200D5BF45B5F0405BE2347ACC814BCDC648C274C24F8024561FB66676534F1FC8041B63114679D9F4E8CB0BCD7BC4C54FBB4F9A178B4FCE64E705BF8FE42826EE01F691479A8815E2DA00111DE40B5CDE464A9F7A3D21BE9562FD9A5C5CB3F4F9E8F0D8D8A20B9A5AC9D7394AE4316181621B43D8220FDEDACE345234E3DFBA134BF54E458DBEF98923C1891CFB8DC9B5317E3B16C740EF373666969C95BD1C53F435D7ADE792FF9E310A191246154064D0E8F20032AF4823A335D88D5C2A943CD4CF313CF2999E237F6EC50F63936D0FF3F2C729FAF0232671C94785B67E0CF71A7CA5B32434579711EDF155D5BAEDEBBB8F0C6922AEB9798356714931AF1070C49BCA507E289F005BE9D8B46AA67CE2137935C7EFD192E4CC24DBC434B381E9A15CFC529D0064F057FC3AB592869E5F1AA5FCB299B2CCC0ED6750E318F6FC969E6A3A08059788102CCE79BC92804B1D08F3BA30492054DB6401EA251191BED1B8CD35DEA3A653D5D546D2EE8D31C2D88D6275D6C7B463D449DDAF586D5E57FFBC07ED5558D87F7DCA82E4ADF49EB9135A578468907BD8A6228EB723241D58BAF3C78C46451D2F11CA0552A05A85620001D376C6194AC6494E337388EA49821C233F32579FBAE6D11E9DB257C426D99516A16DA63A7BFA261F2B012CEE4EAF7C5C16C6331B79A26E79B1421371E574505F61D699C6DF33EA734ED14129608260B1233C387638F7ED3A34866D656D74F06C2B8D70AE60A0994F3D6C1267DCA2001EA781E5D6E17BECD284F967788227E060381ECC60A10832091319F225C972349BFEF08D4DD5298BF7EE11B693AAAC682F91DCDA113EFE0F35CFBAFF6C73DAE43B8C1124EB57713C122F0A5FB03D02C4128565FFAEADC0AC23DBE5BF123CBA024DC2F3956EBEEE95918B87D2EB22EB1A8ECC3B267528A62F2280E3DAEC02C89A01F5829B5891914DAC", + "signature": "7D337573A06A3698B8631704D2D6A1E529B45BBE47236936D0BC13A6DA8E09ADAC5E60E2D0D2D5100ACE99EA411D50C77CAE43BDCB50B330412EFD99959E562100822C5F2B932F7D43EB8015878C49D182EB968F3B12313F6EDF5056FD9518FE09EA1CEF89411D126346924C0B4EEC9D7447083482C12D6B98F0EF74913E66A018319143A5DFBCC3C21D1AE52FA19FCFF12E4730E4510B90EE9F9727C240A145CF34A01A5BA058CFCD26611D7F729F742610AC81B94E931A47039027F81377C84CF225763F68A446B63D64A3D375E1EDF67C1EB3E997A43BA77F108CA3D16BCCDB6CC451308146348C33C9485F4320E8A7ECF3758128B929D4E8CE07B3E84999515A0E5CD7D7D6C5B3EE0E712966D91666AE5C2FE8E30F22A83A1A7DA0FFAE83531C30B3A0B49029239409F36D384C888AA82F86B6D00C0D6D02FB75BC49831489161BE918EF91AF79D031DACC7CFCEC51467F5FE59095C1E8FFFDA2970D4D5EF2B72D519AB0F9919BF046A19BA279F64A084627315938EC50A5B1ADE46A4A2E3D382BE747D895E0AC6926EB6ADBA0E845FA49903B83BB56520B809B034DC7A4B7F292CC7167C51969C2C8E78CFA42BD342B78104512AA4003C48FD059AE0735F78F4837802E6711B35BE35DE93B86D9EC82C9303B732CBE1B16BFC3E718C65288810A5510410CA87DA489A71DEA594F993C7B45FC00CA68BEECCA107FF4723339E15C49F7839725AE5643BFCDB2B98C443DCB6CDD5169465740FB9959F2B17B4BF31D0704FA48ECAB5BD0F4CAB954AB132D4BB0014E558083F1ADCC81B9B5ACC2987F57A3CB069187325D5F5BF5128185608C464CF9534755EDAA7404E35F6182BC83D016C8892E63A7ECA6406EB369FFA55AC37963946038E3F74D9E18F3F40FD190DD510B07D2FDD244D74342A2DF22CBA0835B5A5183A4A9ADE24D82D7C988723031FE07BAB95F4BF96CA393BD58E74CFF56F916B8D3835F833EE658C788E9AC56E408A5A4E98F05C2379F75A82514AD1A42D9A90742C7F92D982B9C789A862259953D9D88F1BBFB1BDB345E966577226C87C6AD8DEA26F75F0C3715225B5297FA7C5D375C1BD8B5D6DEFBBBEA757E6A504E83B0F2FB3A80CBE2FE526CE76D799135497C498A721AF6EA8443934E0D76266ADB52ABE212AE58D7F52458901AB3CFB8A1EBE9AFAD9203EEDC9D1BA66ECCA41D8C268541A83CB49243FFC534C9EE8E0279139989FAA602B668669AEEE6E00EDE80F60CD41929A6BE3800E53677056C7D0ED1AC4D80AD357D96B7B2C2F1B35EA9B9CA397D23A2928245F7A9A0BB4AE0569F16C4445EA9CEA3094364A40E8CB5D06E1F624DF1929782CC33FC322201525CD181CFCD4A5D4201693D0EB249E9967095F73A35F4ADCAB9279C93E0F62E533E121F3396767D409CA80447A4208BB1D83BF7688A007B5402B5F0BCE4ED4EF51847B9F036C3BE81EEC6A6FBC6980D5505BBEDB99FEA87140EEB4B3AEC965108B48C6C808414512F04B5DB3D27FF450D54D6CF5CEF9F9B80D60C0C9A2F2E33129411013599A1ADC3B7CEB410CD007E413B463C1E08EFD1AD51B08B21A08163080450812D6B020A299BD8BF3C8B5E6AA69BD5ACA973C625D995EAC71A81B31E75B4BE92A773E9C10E7686EAA978791E0A68C0C5371D6FD12DE5A370B09F90CF140B7D1B63E381919EF326D0F58A21F04BC24B5623713C0F42E56F4727278C1AACBA51CA553CA46F7B4A3651584897B5EB99BDAAB90966D971AAB0768C96CBAA0D87EEE1DC0E8578B2A8416157BB7BE74F1D815EDFBC169D2D848AD00CED03966DA2E6BD5F98B230D26C3979EAFB099A07CD5495E623238EB46C62F62B748CD97491F0CA8C9A91FFCF617649951C6C61EFBA868E240A2B754C4C920B025BC51278E5239A7EE1F1223F4B8574AAA9E8EECA6B65356820F8290D336EF57A7E6F84280BB7179C6B919B2D89450DEE63BB4DB6AC77BEBC00D0D4407B8D6018C3D878DD74D27D3C01F555B7768859E499EF742251CE86E7ADDF7745C4C2931FC872DAE54060CB6B930F9483D0634613DF19F9AC589C39A666E00F8627B234B95BD77A88C93572FAA2CB38374414E56BFCB9FE30E55F85F476D08C6C6680468F6E23378795435E6B974BEAF4EC6FBFC49A3C0F23277C29EA4822D36A081EE3AF75438A99811AFBF54BF9DEF686F26FAB9A8618F6AD361486209CA84ECDFC3960F47C61BA603E09BC3AD5048AA4D52842C3B9A9C79B49AF43AA952A972B86C485CAFCF2DAA0D0D1050F66E4D8DE1F1732D9C88C0837A83EC78F033C762E950E25BACC1DD6B89C1D4C05728D6EB03E7435523CFDDA3AED8FBB4E131A494D11C951D88490625800E35E594924D84864DB441CF17C5A5E70E0A338D2F5774FA6DD8E3DA2478D6860D032C54A95990FDF5BEC5083552A386A45A81245EB75ADF99A1A6163DFA3729308F310C8C212322F96B08BBDA9ECB239CDE74E75D324F61CBAF7F1A40657B86E83E896706624E51B3730680C574872AF46BD84D5761105CEDCAF29ADB1DC24A1C8B74E6F762292BC03FA07CEBBAA430648BA27E9023ED7C7A2B61BBF1620514CEB508742328AEE012939543D69E0D705BC57903A4E8183286CAD8579734FE35811285CAAEC8BC0EC14F126B10022E0EEE54766B221B6682854EE9B16E53EACB6BCDC989E47190275BF19B3D894C8AF56A4D34D61CC6C078A04B70A69DB3019A5BB0D3E349DD21C101AE2B42EA29950FA164FBB86871597F2E64A84BDD281F1B3538F51F01C0E87ED962640F18DD3C429CEE89B017AD485F188A3A1803D053E7D8F22A47B6A04D558ED17BF0101EB7E1D7D0FB1A1B6082D12398F500B2F65363912B8D8D94FF8F73F1246FDD4C3E6F7C4E372842301583AE8CBD5EA185FFA685E21AF074E3C2883774534D8B449A5DCB07C46F36FFCE4F56222073806CE59EE5BFED172E5A252D214ED2642207DF742AE7A62F8D9A4EDBE70182DC277E09F6826C8DE5B103AB17A892DAC844EE7B2019881DA549200B76AAFE5B9E92711BBC36A3EEDE9B24E44AB42883E2BC7B9109B70EDA772642317B50A4D307592120485F6C1C7B29A0271D571C7DF5F0438C8B725FA98AE2147556D38A295C373B627B732333A0961A45A20EED30B4AF3A95890A12E932B1BF934754A0994154C814E114E9D671306FA257AA8D2FAC90C5920D2E20FB35C5AF0259F7F69607C29075B8DF9B7DE0C4059D62BAF1660E05EFAEED41091D3B6323E32538CAC3D88225B9C683B69C415003CBB0A770A0530F2738FB14ADFBF48459AF82D5D43C7ED0F1E2131535C6266757B9398A6CADDE9EA000621252D373C4352767A7B939EA0ABB1B20E17717E8098B5B8BCC3D3DF152A2D3855565F606682889DE2E7EB00000000000000000000000000000000000011232F3E" + }, + { + "tcId": 8, + "deferred": false, + "sk": "55FDD4E2E182AC68535720F7EE49C2C48266568EA967FEA7CD50AC62663043EA16FCBC7BECCCFD1E71594F6608124EA79CAADB039A303FD25C820B2186E801CBB5E715431F30363F908858E6927537FB74E7EF9D094790AFF50F5E88AF6139E20933274A7D4F3EEFEFBD08ECC4AB77DBCD0CCCCC17BCA0357DB699BC2424F1A99A08128B20486334062116120441525C3001E206460BA77082262A18314D63106E5AA669D12229083746129584DB30001132049CA45058046E144021982228510681C1C831A39244212162CB200CCC444A200529D23860D8288441024D44188D1B39460BB391088010091790C222491B378619384000126A5B828C24B600D1C4091C3750E39681A24031C1A28104344060C8691AB88D01150C24375260C44114274152462ED3B29124278198244920838198C250C1906D1B0788114885533890624871C01291024902D104729A26521B2012D124051B146C4C382D23465261442423C451C1388508480D14428E9B304D239330CA266A2385050192040A826819030824069061A469512845A2044841122819A9688B34664B8471A3808C844031D030460A31018B102D98A249440821018281009585D80430133288DBC04C6132820AC645CA240018384EC1048A0CC72911294940262941205202B430638090081685432689C324821A0850212149814031C8485212028404106522240810450D001830431081E4281048B850008545D188108286658C04252445044A204584863113460851260DD0260923A7911C4761103861DC226423C96492C03110B40C22B3012023648A0480A302601001509AA86050180C442270D1184DC49231DA464619438C84226293C685E2260420084E53240C5AB605CCC44110B951898628DB96216006011A4045C84448108601621461C2106904140050284AA2946123834801C64D981068118409C9C8446186445006100A26264182714138720C43091CA90851A40518418090B610CB429103B724E1800C63060022908953244D0A094962B80894208D54A46C09C09064B084002205A38689182905E12065138551214648191362989881C42428C330618C386CCC186A89A0891C246E5B489108262CD1242D6086645122855B1441DA105083006109088613868921B5480CA131A420319446408A060C480008D09029CB06255B1852C496109B442508260158B60C924229DB248504A840D4326C443080E44810C9A260DB060E91841009468C5B2249232425B4DEEA430C8E4E98CCD4D270BD4B96248155DF82B14BDADB0241D93D57742771D73368AC1C839621783F161524178734CABF900B0AFF404E4242826FF4FDA48FC5D09CF0C54110C688430DE63F1A16560D4A4F36363C00C8865616B178243B4282879D0E90576D18C4ABCFC821CCF87DD19DF99D8C341C3A7E6AD9B1D936D83EC1C2756616439D59688709FA7C6ABB3783963F1DA6A5BD3F3C391A3D50B65EAA6C1547B3C8CBD9F3D9BBF2D828E18756A35933D217682E527F68E0935BE2EA5CB8F74DBA51EB3A9BD4DE3294B962E74D76BE40ADA71B8B5D30DAFDC34490A91D1A7302097EB7C1A9B75FD018CCB0FA8FE4AA8C95261C837922A08FFCEB669D7A4C4D97F5C657080FEA40933DB7EEE691FA496D015799B72A2C6D48BFD8D43A5AC1D4035AC92860D3C58E52134179D459A9E7D34A069E99C702A7E3683AE83B6EC19C322C5D794DC1977C7F8C75C3B1477AA4553E7CCB49D17A6DC6418ABE9EBB80D1329E4471DE21D2944B4041A6DEC0B3A7C38EE411946B9FB552DEEEB4C1BA2F6279BD1DF088C3F5B24412AF02F8F28FA8BE2C5D8098C8BFE4008F53448C28420CFF19DD3B9CDE0AFFE43293EED189CFBF2CBF141EC1DF9AFB5C3678B36DFED40868C8C73D0BFA7BB6B6C6141A9226FBD5DF9D8CF485EAC66803932D2487BE19E5F48F8D34E175D0A24EEE880B4C6EAA0E093691E7A6BFC912F89AE07A4613D1A5136EDDF15A3DAB94626C36143FE16558867BD43E5EAE022011B0DFE75610CA7B6F220AEB7BA46BE1A6F1CDE340EE5C6D915AFB49223CC34D183142AB7E82A922D6669E15BA4A316B9282FB6FE5A1F310B294910B04174A955F40D82CD5517437642E91C41451051F2D063E492AF13EFB411454F90BFF85BBB8B0666233CB19C2DAD4A192AAE440344A9CA97F26D504886030BCACDFE72C87EA5785AF2BC55C54C641BFE7861ED3F5AF1F1B430B63C872FADB6C5FE4B446C4823B7AB7BCCFB20652358611DFA20466A176CEB3CE1D7336C34889A6EE4BEB96563801AE9DADAB2DA8AD03A256FF5BFCDD8BF0F65AB942678391862DF6B3EC81385DE7721B6B650C8A3B6C59CDA6B2A799383309D4176DBD7F9A91952298600349690A6FA57B02196BB2483E57907FB8C027849228B884BC33D0D0B3D49C6FFD11EE219D6379592AFF909862ABA39C0B0E4B2CE259C4C77F51E7C7833A6FAC2FF2AB30F34A54522EEB3EE52F0DD3FFC1FC3E0EB51311CA66D47C4160918BE13CE1946F27F56A0AE6B647A1AC04E1148608C4D35E60E95DD3FC887C812710920004B55027EDFD5D77396BCE2E43D696574DB561E4FF9F475609898E32650E9A18B7E22692ADEF2848E1A0B26F3990A5CE03305EB6D90228D4735F97D008AD96C019C79186B1994D8210052C432FC145D280C6F8AFA51B7D52E1F0151E266EB86CCF02144C4073FC01C32DC69234250953718CE1CAB03DD64E5AE07B3BE21BD208B5A76E2A990987AF5DF07DE6AA059DA7AD6FD1186B99223EAF0E8096EE716705D0033E8BD8172A732DB465284850B41A7C3303116AB487D03999615CF0B43AB8070364B7E0A50364947C92F48422C4EA043D33A31248D4ED643BA3314B9F42C380A1319E18BF300B3F247F334DCD78D1E917553318DCCEEC91D1CEC4A9AAA0685EAA32BE2F214F7CBEE8CD3CC60AF330187F7F688AA009D453E21FB0D1879D39C6444FBEFD02C6547BB6EF70E61F7D3F0A3337C157ABBC4CB598B8A750ECDD2DDBC1DF4CE5E1CF6F2A7657BCE25377F46CAFFB9FC0DAB2D42C590DBABD7147DBF56C619479598F62FB5DD0769AB4F915990BB524385AB946C3266C95870F199073A81B172F23F7DCA7B2A9A9B3B6EDCF5DF718340EB4C10CA61FF4FB969F736028372795EF6AF711FE9AE752231C3F9C6CC789B6DB5EF2086D91FE6A22027C83B5719DC6FC87FFB8F0113DB674F4E23B4EBC7F984136C79EF8881E0478B8EDD289237044D7FC11188C753AFE34664C680902A2066A2BF8BD48ECD2ADC23389288ACB70117EF8031D332CFEAD3ABA3B3A8C8115762AA9E8F8B46DFF5D97B6441489CD8A5F53E0FEC9A105FA7AABE36F1219469717C510F5090BAFE13506BF7E82BD30E5CAAD3D64537B047268CE62C325B89184D55B92A5788B2D09C1E7F9B7E1D5708A0C2D47FF9C79CDDB958F7AB25FADB4078B1E4C45093B8674E1E605DCAD367D2CB72D7009B9FCA95C55B91081F0A689D7CC3A7616BCEB070D49DC25AAB7F7F53C0CEE24E12F97327DD511B21DCFC004B123B2D8BE604D1F57A490D7B2A7A6E3CC3270D41DA5E2C02FC1920BCA7F1C2689D20C4F0310081E3B3D7BA8D67489E00A285561", + "message": "E742D452F392CD3CE405908EB380CB0225A4725065AFCB0C91C5E4823471376E6424AB24D57FC4265B24DEF6CA73E28FE20468B6E26BCC9267AAD2B7B82960C3FB5A01960FAE078D5A54BB324232B6647C9DAB943533C865BABBD3DC0D1E7A1756212980D75F2C8E999DE9ABD1874E3A86DFD53340B6E424DAD9F53C3CA02B44FF8DB9906D3D4352D0EC4B1A57A33FAFF7107D38637AA410B196BD1BB1FD7AE4B7414E1037454A031839AEE4C796BA98F4A739B785E3854E9EF0D5B7415C8B7ED012B0123C335730C7021CE8C94200874EFE783D7C4BF768538A448E76120635217727C81D08976CE4B5027D4BD9D9E27E4BCA4791ADF6F8DACD1BD3A03BE5CA7F68C2A2247FD3184609EB7243D2366E5EE4C95CDD869DE41A4B47F021DE76CF27464F814837C648A7A7CE2F91104322BE3CB1160A0D10CFE90ADAEBC87BBF14387C8387F4F5AA10FBD469ED5587EEF537106CE0F3AF4CABCD4476F248C21D119523B680067B332A1CA4C657B9DE1360FD23ADE58C5538EFFC8902281FC7B5C12C22CC69E7EB18E5F6F8352B9E4935D06C96BAFD834934618D9E6B1F60292352D064A0EEAE80F7B721312FC1B6C58D68A96351431A8626CC117BE9DFA33A1625BAECF12CB1DE33BEDAD584A91546DC767D0E59764FDE3FC29052CCE23ED28CA5DA4507933C0A7702D9A1225A48B71FDE5D27B12FDFF16AC2802E3629E10D5FFC2FCC6135243A9E2F3E3867BAA0C0F0C77BAEEF9DCFBC723C7A2BCEDA39B53B415BC21A397F9A8C4DC580EC512DE4EE4E0870DF1C4FBABF4906E0CFB08863AF2A89949F8E0FF9385ACA3F588E05781C49DC563EE9E0C5D6FA512932B7F5568C1E0FF1C9492ECAA5465ABFE125B511723998C4071481BF1C53DECD59B440931AAC640D9F78B1B40EE46AC0A8FD18B4C8AADD734B0F03F02CAF6A7BFE3DAF100703BDFADA7DBB50ACE3D40A05AE6E87CEDC0B08C44796D7A63E8B5BC95D97E3EF706E1684E791D3B3A2BAE1E7A92FB70A33D896219E80751A41E16B506FF266C4BCB4346578BAA7732CA745BCB01988AADBCBBCC45C9FA3A5D38F3F8E04005AE777910032D992D5EF9DF2C0422548A980707050CAD9DE56BCE60EF74EAA4465EDE96B055999F81A2C9596A2B35C8AB3CBDDE9D26AED44527DEB9A2AF3BF6A853FA51DCCD913876A43DA3E0E2C5B42571101B7B930840B0AB64419E1043CF56AA3C2FEF5B39CB582971A5776F8FA9696CD9F67E9290E483E9BD1698E961E849A513608C3F20FF678EBE0C778C2A6DC1FD3AFFF89D646A1AB85F005AA14A0635E92191CD41A6A46CC283D2FCABACD2FA07B7E2FF97D17B36E0B222D39DC1EB61BAB8146F147579D02A87DA08AB4ACCEB32AE1C8CBBB0EE0D90A642BB76DEF4AC8C7E477888159824349EB075DF0BED236DA9B2826E67EFF220AC84AC99BE6EEB0DA904887E3A84E5208AF49BB31EAA1552EC79E5BA02458106B5A31D0AC8AF392A63947911400FE78F6C94B3F8E6B7C3B98F6548E7894EA22215C87E121441C53EED726AE26394C825517EF8A477A6DF33B5315C8DEE16ACCE76ECA60835390E65392B9FC5EB88EADBF336FE361D190ECBD0B35B22A6FE6A8D48466B5E70BB6C5FA515CD8672BFE70054038C5893E514E23B16C39198B37B06B21275C2994EDF7F9F921B320B39E29444E3D621F52C9FCE19049D403AFBF1C047C8B065543BF43A25817533A33DE6C866FE9D8A73B2CF7277CA0E8D78F4F104C5CE6FE2025992E26E49D4C49F0798278216453C00C78EA7BAC2BEE71E5273FA46044B4B5578EEBC2A9E42025A8A3526B11CEFFCFF47191109C56AE105CD70A04C3F4EC43E49346203347319D8986D15B3C4A49F02C02994D8798499DAF1E0ADB81A9AC79FE8EB55ABE2BD18EBE18A9E5F35D2F66B38CAD6F6EEBD29AEE054C05D6F0B5326CC5B86BB0FC7CDA720838593238A2FB24E0CC36DB193FB7FA66573B064497F771DB1D965953477FC28989AEA2CC004640524A6DE8270E8A5B12BFF87B3F63FBB7DA25337EE34E6E4EB45DE9A39BC9B95ED37A6A404ED2970F9C79A7C2953420732C496B855F19BBBC8ABCBABE1D26D5BA828EB060D7280046AB93979E0BF90B6F1C07CA70833BEC83DB41684F1842A23417B3BBA0A33D7AF7BAEEC14C9C96FDF30BD201C05AEC6D3D2F539D511FBB356DDF333409EC16411DC7255DF0791BD67892880A4DB082684BBCA8B7E55B421C17DF3B68720E907C1620B142C3382AE6E738F8943CD214A847A6439A682D62CF0AE8961B5F020E7126C5DD6258CA0E8F5711E5472A4C05ADFA9A6B8180B741F382090CD1C781F7CC7F23E041800F42B228C351AA21E4D916BA5D9C56CF8E9507065D729B7C3653A8BB062C0463BF0B97F13A1016BE4851F5A489081A2AB3D2AC2744008BA734ED38DA10F372D97EA0C278C709A23ABD4B07E91ACF6A6F2DB9AF7806820381845FFBDC4BD30A503A0F74F37748E3624BB2AA478210072FCA83AD1A43ACE9F2943AC1AB6CEDED67938AF921FF34F2DAD4F224EF7498BC450A67CA383A9DDA333073286A22B85570A11FE03F55119794BBE8B81EDF1966BCA5E363C15E8E8673C94E3396C9AEC28D110408DA5561296E2928C6C111A4826309F119E5456675AAF935A17E80C0BD82A9CAC2627D6FAEBEC9A928D33980A86ACDB35686306B57D466864A0320F21751FB0041BA0F4F1660774A519D3ADB304438C1709711B982EA84D1B193D026081A4663AE69C5E12C3E4A683FB356DCA618191B29290C5DB4AA6A069C3B8D61C8B7FDA779E1F34A5F62EB7DF5C563ECF1200D3FF499DD06C2BF44A2B4254318BC402EA3A047FDB3570EB40630CF1DF84D1E2BDF5449A1F65A9DEF76954B5814691C4C12BEB10A1C006189968F37A4B236D9EE0D39AC340852EC54AA64FE15E1A4433ED48153D23B2B648C8852F3E3AE485474AB2DFD58A7F0CE6691ED36818DEADC8973E6ED06AB841B0A915425D7B87E41E1E68B00BE2EB725C287FE575736F6E1AD2AAC61F02A3A00ABEB2C0FCDB35564E8446C776E980636D5D61740AB2F0736A021D82C1D66864E5DFA98C4648CFBD9C7AA865F6C97038656C9C8767898FB43B0919BC98C1D0F6FA4D90F711E5D009D4C8FD8A773B7C73CEA654A2CD52A276C6CB62265294869A052FA1634D3EDEBA1F69DA09F0568F9D2F6C511F6BD6169BA0DE25F09FFF63AED2FDD0F6D89BD01FC5B088D3EE5344FCCC0215B6436987D6167A0F2D5EA47A984DC86D45534BAF35129488F3BC2D05BFFB84A51A87A1774033244277D0F2B45EA43500F4034081711CAD67BAA9CB0A58E1D01013032EDD5EBC7095D4BCCBD28A5F32BEB685F7901BA7A839650023B0C908FF33B37D038162FB96EBA35C2919560267EE5A94035825938D168481D8E59813E20DD611E4E23D8D42C9DE1D2398CE3CCB3DE5CBC4BB16D555985F411EB5B56508C6F4E75621304DBA2F4F1A2D8B2BEC5793478E5AA0DAE6F52C43253FE7BC91D3FBA84F8525D002CC307CAFA20BF198BD8F28CB579960A1168A1D26340C8E26CEF1261F23E97B806E9F27BB51F16102527721BE0E8B930A1ACC38F0A63EA1F3FBCEA1031E441FEF4D3746EAA37B7D4F8AB354D5F079E56FF4446333C8B8B7B589CB36DF40EBC5A75D2237F3FB874E7E0FF1B96DE43BCF229DE1FED3FB6D01752B3271E1F98D4134114911BFAC8351E3186E90DA3DE2E7FBBD305C822FE6F06ED1D4774D7A66DCA0CBF740DC277C62FA641ECAFBCBE359A28FEC48D62E1D3B6215392C0F8DB601E35A6CBD978567E806168A9F5B4915A80DE405038C4A370D898ED6441F727985037A040163F14DA78378931D3B96BA486958AE8902C98BE75BD0AED53CFB609923C63615917EF0BC6D07CD183192DE3854133F701B9D4B499F958064ADAABF4080C4A019DF1E5B98C8CA265E031B8CEC355C8FFC3BE16DC3D01533ED17C9769365D023CE7F0384D40F7B6179612B5EC382982E244E2510B4831F2D53F26B142A33877961EF1F845370CE115CA5F0D2FD6926482BF3BA1AEF3212DDF36705A210D8076A4428C7F9CAC411DE590452C761028469947BEC31ADCBA229D8EA58755F2715AF6D51E581D2CAC4182557E6815BFBB84BDC54C9368764CC29AA9AB49EEC37364F85AEB3295E60CE6DB2639669F55CC49D7934BC8566AB5E207B33F29128868BCBC1DBDE1089317088EA3FE1D595376DAD3BDD156802F82B63CF4C5ADEF9A89D94493BA152F9F07A9E9CBF8D821F1D6CD602EC49B61AC4F7633EC810F3D01D4867B1F0F3021D70897593303CFA6B5A3BD0303AEC32105F854C3DBED373760DDEC9B9E8EC4AFDAD00FF2E5A05A0113522024B86F1AEE6F250AE3BF0AF1E6FB7DFA8E04E3F9D5C876731D9C33460FDC13CDCDD433B45A6BF17E98638C264DEDAC262BB03714E020F4576DCA85DFEEBD6D70E557DF9321A8AAC519C419CA20E33DA37C22047D4CF925AD67545D04300A42B22DAC098A912848302D830E06CE5BACCACEB6E9316F9B1DEEE271BC6AD9D74927CAE725CCAD0C596653731869E8071E23BF", + "signature": "39F0B36E2780F8D81EE231CF85B28930B0876F344B4EA32F8CEF086931EE1E6B9382AA19FB650AC81A2BFF86453BEFB33BF8F0FD8E0FDA5737D7C56E4D9427BD1E802930F500594396F98A2C574073FD570D30666F5C067EAA3C88610A52FB0F6826CD12BCE739EB685B3800B3B4E3833DD2886CBF4587CF0704B2E72B128E43183F5A5613E8A5342C123AA38FEDD3AAC513432A96AEAA598AB9DA0789B440A4F4AE37EC090144670E8E876D83A39E0569A1F38159B8128317216ABAE8C5988A396F2964B6BAC4521E1E35B4C1BE3A4AD1745F718A1C74B260F462567146394C5190A3B6F724BE2804C3E8BB3FE3587B09F22F3227A2E69B651F52A32F62693E212B502A5F7917D17BEBF20BB261D554C966418273C6BDFC51C8947BE2704116BFB1D1657D5D82E676DDE05A580F048F7E111A3D632205FA52911721CB22F937E6241E1248F1A6E10A71C34932DB75A4878BEDF3EA3E6EF5508E5CD691114192DD4C44E6620EABF1DEE4D09448680D84C6117773D240DDACE06A2D925920F61A0AF12B6E64DB0FEEB2274EA1238E22BE017579792F2EF95BB55F6A23D18CCE1D3AD209B6463370CFF1F8278E779A9A943B5779A99C971F8A3794CDB3B04773C9875D82D9B72C39368B1FD4FB0A661BCD31821ABDCF4CAFEE9FD959285FF15B9FF8211619638EF4EFA138E44E4EA9F1FADB550C13EAEE9828A34BA911D4027F38FC0B9D0A1E788A6B8648C63A9E4D6AF974F87170333BF82233C199598D7A7CA1F90816CFC72621DC36FE881F25BB86C67B9B59DBB02D78A1ED003193ABB5470A89C8F958FAD2D6491ED121AB9A02EF470099D42FA37174052E231D4D988707567F319D964B4F0551EAC4CAB4EE069EB8FAD6BBC4A9F1D98DD8BD73A5647F64D4535E8FAE71B53902C917A9D286E014474E4B126AB17C29DE31ABBD58CEB1C12669FC2EE50042CF30BA29F08E97FBEBB6059A458A90EA6613C7F76A5AAA9DDA66D266CE0514B0B0442694252AEA4ECEA14CF5C90A8BB60FDC56F865447BF29769F49E79751E8AEDA70CD78E29154D688558D1F831096C660FAEF3EB1850DA01F2E929A6432CFE9DBD342D1CC234551D6301B6B61819CC487EACDDEA62C2CB8766E2C7066698305CA924419C8E83CB1D68527E923700EF7C5A05DDB511DF15AF11F5BCBA557C815B95001E0F57E6A7B8798133ED1AAC2819B10A8E2E4BA69606BB148881A2C23D3EE0E981551E02EB1ECE320B6BC15AD1EB0EB2FF3FEAE63DB0AB4C2F315E54F047734833CD380DCA1ED68FF1838B09495083457B07D93B8607217913D678D409C1ADCA9C7F496FCDCE029F2F4D254CDFFBA036CEB59D15BB40B4215397DA55B5480EC2DCAA221D4CED195DC440BD0B84EE2BA5108F46B7E24148EFAA6C2AA728F6CFF1391B46C36DE741C7C546A0EC22776B9830C3165D2ADA141F97C05D03D93557BDB24012C336CDACCF8CA3630064460C12251ABC89AAD06478610B8A2BAE5380E65A2C449632EF9A79CD9AD8857BECA18552DB913C0C79CAAC8AB166A1ADD7DE272A796E72EA53E23582DD8A00F554849B9EB9D77390CA41B04F6A0C9BE3C3D0E94F9E3DC39BF1AAEE34E910204DE1A2B3A92557A67089B912B676F93884D4A6411B89740953E1F79ACE3407B2252DFDDBAB75276C10EDD534A9F398E51CE9E36469C1DF0526ECDB84B07308A0D5D5C520D028A8E30A193DF746F0402D160A4E9515CEBA20655979124B1D6F5EAD8892D9F1F92A0E1A1DB0B4BB90892F569194E088E98C0C5FB93A108F05507B29A595CDA161BF4D97680D6B0D4428D6A74B016509CED3B635B02183222B79598B6342A20DF2269E881C7B121889C0751462D76C5ADB628D26359D56F8876CF14A71D330D03361F63E90C85CBB275AA78C15293EDA0356E9DE2474ECE7C49419E15ECC5EB8233DC8377D88316AE846BD464D292B91FA8B3319A28EEF4D678F0DBC04687C7C59CD98B694BB15DB7E18F4599D4F2806D0D78E80984C4136EF605FBC268221E7608ACD24004CAD8F533DC1BDE1D3CBE0605A69E828AA13210A07001D60B8EE2DF19D5AB8D792F3899C39C9AA1B82F1FDF9222264F7C3EC8B756DEF951F20D1622B23CAE013DE6CC95B0F39721FD46A64B7134A602E0D9B6B19299A5521148AB61ACBB878686C2020663EDF3652CDB93CF4E24C8FD2AF8D0167573333A7DAFA1CDE08C253D523AF9F944680B97BD7BE2196870A754894334A029A870F8FB342E53BD3F080657A4C5A2DB603C9F0F3BB341AE936A2B9356A73DA67AB54AFAE131C8FB0CB73EA10832D2094D014C01107FDC06177FC3884E7F788384E8AC89C689B2A2BCE8D6852C8B5BE520671DBD8447E4D78049E1EE50663A609DA79725A3822DC899CC87224C115D129702C7573B45ED58188D422C510381BA3C77DB099B87C028C895DDC6F60C148CB1CBC60CF56C15455048AEC096CE78B0E70F8C8F1694CEB365DB8FDA1F01897247E632B30FEA0F888EB49D5487482B367ECB413856E8630841F811BB1AF14CD26DF29DFE7238AFF1D169804445A74BA5F9F96D9EED27BA70AA516C1BE7DC46C015704E1BFB42F0CC44456CAD7FFE48B62BB8BBFFE5C97027BDDBA1E83C027DEBE20A908486A351F077E627464F6BBEA0AFE9230FACED923DD9DF215AF123D8089B467FBDEF42C4174156687ECE49D87C0F9711592D2469BA2100A5286B086C2FBF47A60B864FC9628CD1977D7D8D72B411D2494BFDBB77543DF4B39664F7B22451B8C7244008A3D24DEEED0C9CA67DAD2D56F1987313B4AD33A72CB4973B6125257BE3295682A3D0418A2251D71510F858F65840149C8335BD999C55E51181914DAF055DA97746FA5A80A7019D9424EF0087F38EF1491A3861A19C87452E05BCDAA61CF148A84507B043AE4A42FBAE9359842B0CFE70FC17DA78A754E3D7A768469C170DE3AAD692101422C00C0F8315BEF3BBDF887E75E5DF7101317CA4F8C4D365B56A63A1D833B5D79BBA1812F3659C377BF9CB4A913CFA504E0CFDD1FEA0B87BABC132F81E9A2C7FE0C6E6D8467BE84EC5E21E0A46E4759A5267E6EEE4266A4EA8718F8D40A1594CADC835306F88E2100AC444379E9EFA4B3FA0E690550CAC00EE4633687DD1FFA748DA3882ACC6CBBB2EFDC0513A25B31361DDBECF5ACB3C488AAB788E63A48D556ADD74B607CDB8DE11C7448DED000E8665EB75BE788AAB14C3E958CC969FE353C0137924941951BEE553FA392DDD5D7FBFB8A2A8DB5FB0EE58D08FB5ADF617EAC526044962C599523981AC06B60E1A6A34ED97B80949DABB6C9D6D8F1F4FB11222632456068798995B5B9E4E9F1F4F8FF10161D2B5D636E9395A1B2D0EBFB1419202A2B383A424B578592A0B4C2CCCFE9EBEE000000000000000000000000000000000C1E2C40" + }, + { + "tcId": 9, + "deferred": false, + "sk": "382FE71D7DCA3DA9138076E84FD5601E999042CBEF87ED4A8B5200087B61564E433A8E49F18104C7A7158AB1D83044AAA46F6511B361326218771C3F99094F9624AD27D16068D01BC7BBCD0B5448338C2A81FB3F83B2799A81EE2610C5534CFAF09100FEB0913F2DE35DD5C21DE040A2E8B6FD99848AF401BE6EAC45DCDAB38AE1442E88B24C2233621A187061C4606390801B272A133450042331A4300994204D11464404242051C48DA14649DB4428C0084C84304DCB8244CCA84C13B39018150DE3C04122160400A6252384511A28221B136E2049715A04222112724B4889993210E3A42C02147004B06920110918352EC8B681614400E320324124321CB47083C60D0B970451B8101A3268E2A84951C06C20926824B448C9902922122101252C13B70099B02519A6410AA049149069089751C8006A1A233142168A620428D3C6900BA544A234251484605C48324B384E19296661286450A409DA162A9C10100306019088410A0006C9283020A44808C04920B78DE2886809A64C1A030ADA180DC1088962384D61842C91180D61A649033672C2A24DC2B02449260540006948226512C50C08C36D54224D244368418230D3402114285050366C4A446D989604CA90605A162ED2422241129048827013A2815C8025DC12264396499292281A042D8C800100262C93025192A288C2B29183080E12382262406D14436923112E521480A4187280304961863182224C92486C60B84808C30104280152084A1041520939664A328A99960C14430E1AB46C44C00801C60C128024A390104C0046048069E2C260D2360EC9C82963962D53C870203311021568E3222453466C410891E0883008266E5B386510A991A1B88454888152444118A81093004581122C10224E1BC909C04406A4A00414C401DC0286CBC645CBB889800885244945100871990804CB382512359244067011406550483240A009E0C20020244D82A20C81360514460E21C1494A442D9B343120C85004256502B59084B445542489C4A224122225643862D8B02584A005024828E1C625E03462E19221E03452DAC2219B38311C113293C80D612466C4024DC8026E240582630248D1140A51342960A82C2093891B496C519010E102654CB0251C096C4B18860B35421829658028696080296012250A417081222990A00950C041C0884448804D1A182820A82C22806D099501088670C9120803272DDB208C1BC92C62128ED98681CB067010C7498B386D9C8005F34E25F7A1DA3F630CCC7317F25ECDDF9ED98A9E07707DED49B04D35168D0ACD1EC48A4A92EE0A9B2AB5B84F7F3FD38F399E54FE65FE2EA64CDB121AEEB6EBA1C0D52580543B76E82C799F8ECDCEA58DEE9CF8E24C1B08C271B805BB729C7060608B6564F93CF8DFA6FDAB6F7B6F483E81C9F35E07C061F88585B86F7DD9E62CB027AA2DAE58ACB5C095B23661FABE88C717A46223395B94A972E3CCA2FD131EF052F7C8C75EA9B93784893E354BE0E4DB252C36AD03285A7FCB33A3D53269D20EEE2C3E6C0D74C91A2F1B35510AB2E7C4D12F0C564FE96090081A76B9163DFF22815EEC4B7AF398DCAF4AC6A39D31EB3C4674F7D007D6C04C95AC37C4E62182B0448CF3D10CC25823463A9808F97640E378BDB17EC0A2972F5F70812625EABBF6F1F93B566E36D2CB3FCFDDF94B3DEFC1AB168DAC4371398DE157EFA4B1998D2E19B4E9536038DECFB279770CF87FEB7C0904DDDFCBEC1721AC33D837AC7689676033D6D556DC70CDFCE1940CE25D69A961C6BCFB4E16CF42636B5DCE6C0F736DB467C39D0E4BBD0577F3535E7A47D3A80010A5A96CCDBA9C89CDF7894C43B19EEEE86D7B248E6FE89F84D73F76DDEBEDF18BF3AB9F5D0E69BDFB35AC1AEFD64E64488711C95D132029440D3573F1DE86EA10B9CB85241735112D992319FE5C28EFD072D2808BEBB97A75607F2BD0D62CA3223819F2FF26F047A5E1283C39317C1244CB95CA3C91C752DA2B1B36D185FF6B6FA6E779860DF82DF8450A2B131459E5C437B0FC44E49A9C613F8CCFFA188850E520E166F73BE0F978C8E770E88312F8DEB9FC4F93962AE579B2371484A6A7E09C68DAF0E00DE46749AB332791745294C3AD193FBC533E56A723D230BA35DCD4308728014FA998C4036066238B50D5A4381A1E46BB6CC2EB3C4AE4A43BA3712462D7A842598A1E5A7076320194C57BADC732197DF4A8A1E9455201AF865FCCAA674E2B427F7B3D35F9E66D1FB56CC690D61C7EAB983D3F31EE3066D0CAF61455B185902DB44CD2A85D6BA2D4B97DB516AE75CAFC855829E24160ABA921528CE718E10023D84EDAB83D42CA84E4E3B078218C44BFBA356F1815F927D61F2EF8C46C4B5521D0F8971D54E81BEE1FBE150F3B303D8668C9328B61D68ADF26AE20B4A38C4A0DD62A5B432ED1A3DB945003FFFD37870B5A514FED603B5EC54668FFD29D6DCB5A593DE0852CBBE4376B161BD7FCD8CCB8F60D453B68510E5705549E25149A1271A8093F6084759F47AA3B5D32ADAE32173B7B0DB4DEFF645D172BB02F5D2BB776906E1118167F3DCF7CB8C0AE2866344A59A9F6C3687CA3ECF74884E632CD63B6AA193DC56E087A67782B69699525C53A35DAB992F9BAB1CB098723BA2F1027E72BD20076AECCCA2BCEF8EE76ACD195380A34B934B44E642BAE00DA4C1ABF7174CF0C0A353F96F27CCC2B6281B7CBB29222E9F7067646F0D915AF86F90ECB3E9AF2B1D7FA2A233A5EC015C6268981942E0DB8E1F3667DBCE020907148E61B353D505A3077626E56B8FB108D90A5922E5259387CDCC49D03D1D47E3CEBE87A752C7562C219C25F502A8716722EF7CC7B4AF8C33DB33EFCF2B31A076DEB28A410B8162A9D3F1042E1AFCD5A9DA472393CEE28810C853DCD94F5590F2F5D9888ACDDF1FC78DC26221CFEB3EBA97D0AC4B2B2CABE0BA52E6D7BC29738837B7DFE5A2236AE31CF61A449186080519DE388F1211F6BC81663D2AC7A4BFAE83E9E64BE6EA7DAFCFA7C1DEEF73DC6F9F9714626B9F67F292DA66D19B6A5CB4DEF0E870AD09CADEE4DF12C873722521D191EDAB644CE9EF6AD93CBC951B8AE64F741B6497645E92A916605137CF73C5E30CCBAE5DBDECAF908C16543310C592529819C926885DD3C8DE66480FAF7DB079BAFB47BB99341EB9091AB9E9A0CA721A8144882154C3D4DF29427042F41810DF2BB8D59C5FCE38468AA8328A740068843F7E2C911990C9B2CC9C8E3597F03502ED2813587980918E69D4C482F040A8B7A09733BAB73E581E7DE74899A5EC59369EC1C112EEE0073E1320B189058ECF06DA8E1B74A7F4FAB3C77E2CB93066DA683BF9C6DBDF4E673F11F446DB7AADDCABCCB6AD68BFE43F5AB8EAA5F8C737AB144E33ADA994E5F38E1184A4CF2EF21734DB0CE019F114D02316703CC86BC12550C1CFB863C1249D9624591ABC9661DA47E2972231378F57D27F5C1A6B0ED2303DBCF69A8E98C6317929C6B092E1C0973AE4DEC65C3F3B59EBF6AFAA60C5121500EE6B4027480BBDFABBAD8FBA8ACF4A23AFDF667EF95B6B60DCA6A39C688BADB1DE6F3795DB7D4D31E882D001087E81A0B7846C7D0B383D6E85DD516E37409", + "message": "7EBAAFA6D04129716131907EAD0832AD490D09E97D865B4AFC5D6B0FFF4EDE6A52E961ED88DB60A325AFF2675DFCD6A87984884AFB8680DFA7378130E44F205398ED7B83B1AC32D2580570FD6603827E8E4F5E20A27758CE6D1299BAADB8A895AD586BDF7B64F8D7A52BC15455EEF240F22FE98CE4CEAC03CDF7E8A983D7FD1A59C5EC594474AE77DC43EE4E7B25C556BC1D91ABD2015B99B1AF5329DCD41B93793D791A44AF5D83DABB8E40675EB32120C57D9E6B7757D3E03008A2F788336B8355AD2E47E61B39BBFC2229D53BC9BA514BB20F3F9EE9266BC0015FE81980FDE5637B3018046DD3D4BC3D549EC394E190F1BB788619CFFF86C532B4B9F0F6F951C0ED691C59AB0CC438290E9D6FEC9E75BA4FDF12D2BED2CD988AC411310BFECBDAC48A61099CE0D0CE4B44EC9C97108A44E5C5EEC1D3154B4E72B8397CDB0F7D15AA358076E25B7F3EA1E6E80A214051C440EC4189137610450144641B1E71B5334F0DDCE9D5CA30274E0237E45B4D92D7D458ED9142CC23871E56411382CE40D9CA4358B417261C2E7E845637FD2E9B4357E7EA5F4A8076A7C2F40FF1F8AFABA5393512F690EABEBFB73811B974E57C2D473AC22E747A0EDD39E99FD6E5D3668F3DCA1C795CE27D1A155ED9595EAF9061CAF5C55F3EE97056AF6ED90E05D41E90926F69044746230C990118E4D0BE4C12F7A4AA0464F8FFA7CF64C07FEF171B2E43A917AAC2880675F929583E9040BA6FEEC8262002613AA91A2B8D4DBC1D36F23FA9248A2D3ADB1DC5AD669EA219D35DB17C9C25095AD7673445E59DA6CB2260C8FA57639D6BEC8AEE307BD9C96EEF00C93318DF7DFEED970DC1F61AC5C94D4086300D91199C90C95C1A24F7F1E4292A60AB67F30BA990D58C71002D3548A412276DBEF3984FAB312723880ED479080EEE2B636ADC75AD4423A6E0C5CEB7EDE528F871FAF21855C3164469B9EEB47B6D37CFE4222DCD0B9867B00BEE12C27590DD77C24FE640DDD34E9138E70D15F52E94F3874447CA5CEB48573ACFECA3554E2B76CEE4E31060BF132CED8AB953F0A280F7916810A107AB5BA66047FFF0003B1CF13BFEB77526265B98E54E76B891A89F3AC0ECDF71406674865A0936BC57F87B64424BFC8FDC41E471D951077C32B5AF960457E97CA05F3C378D94B60A9735E9EDCAA96E413FA391AA687FD07D9D021B1014CDF241E5460DB08D3B336DEB4CF0AACEA57E4DC6C464F698CFC2AD10CA72C102A25787E0B89249F63406A39A2A792B2DE04710C41DB36B55D2FA789004E593DECE9865771D8B16B5436A792FBAC9934852B1F55D518F9A07CFA56BCF488D61AE355D63BDC27DDED6A56154B8BA3AFA3EC9C01D6593C83C315527F5FC61BB169723346AB4075D09701789268EC1F02EC4A1CD8A5F2584E29F126B1ACBEEF660CBEF16A8E9FF9C0B542042EA76684F9D70F2E3F3C18606ADCB1D695112B129B301008EDD5E6121A8948E1165D350FF09647DCCF4A1F8605ACC750A0AA8319A6685153A7672B31A3DE785EB22E1D223D6271282AC18AEC83C760190799F082D7FB0F238F627271BE62AE5A36A34D65B5DEEAA12D6B14B59BD0C619D8D9A44238AEF1FF83C30118039E834F7716CD59E138E2ABEC2921D9FA92F6808A760031B2157103FD2EAE988AD6CA4F350F488261409FE91B5667A9A2EF1E226B8BFEDDEDB84ECF993E9A71220E0253D2C4B918C5521C7953FDFA00D50A32879FC0A68D2AAD13EE181DD47DB9E3D715574CB3D566BDF30209297B01A666DD7DBC5464F913599086AA2FC6C8541592CEFFA067B287EEDBF4C9B9D6CB23CE1DEED628935CB2D6B5CEFF3BC442B2BCBBEFE4AECFC455A3A64FA117CFD9289FC27E6289750005877DBF64CD562E2E7D1C99830F5AE63C70685B3898D420862A8C4569F2CFDF564EEF4F94FC34CDFEDED8854855F3A4E52C612258DB5EE4D702BBA98B450D070264FF86A440129DA2C126978DAB3341C4079A66F9C23445C5938FA799E78F157656208BA7C7BC7F936AF49D11148856BA55910A6A736D32E0974E50BFA608975E37AC0601FDA7551204EA66F524DD03F44F5DA28EED5D126C32794F1CCE747DC1E9B1FE287CA607F81FE7C795C96569E66B2F3413DA810035D472B7F5AF74F9CC70306A8EC36F1383617D0FFD92F6DEFA7EFE91C840EDF24430B197802979752FD55A8CA85FD8D4FCE774F1CCC540F77C02E16F1494DF170CD8BA57A86BFB086349D53E8A62E1DBDE03369757EADB0E985A038B31DCBEF513D4FF9A3BA6E8338EDCECA7C3E9417F9E133BC399F2EC0C72E60E809F79D55FE1A917CBE28FEF19D6D08A43F74DF496EA9305072C90AE3BA0D21A1AC0BF040920D3F5B8703C12A32A6864382E9CEE8D00CF4F93830623E76197F7F52309824B08B8E0D5DAF5662A36981D50880FD3A8D73D24430A1CB201A9D0BDE656593B37B8EC47F235B5CA251249A04507DDB81F8E5E4E5E414B3750AB168BA51A8873E6ED153E302F61F7159B658E316D6D183575D87ECA30185CF72C67543CDB658AA07B1DB220032DF80D287E769E3253C80F43570AA538EEF49F45316E176F1F9411F3C085257C6B8C708DA7B924B792389A7EC34C7F778E6100333E8B9FAE75A4D1A32E306AEE36D29FC6823399FF37CDD0D11C8D03F14740342B736C4EFB5302C141A86C857309A70BD74DB6C7C29C839F8D86F2A136F67A0FB3A3749542A9DD8D4A062672C75B67D3BDC3FA6B56F3E79008AEF8D8E04CC7781B23D0DAED64CFD1A91DBBAA2C9C4E765FE2FDFE6E8533848E51FA027B86AB05A0530F15C1B7B6BBB268F09A7865E202B1645F8B4267CB1A49A2929410823AA9B834101E9EFFEAAF6E406639AF7D2710E60A84B6205339B0719E05BC6724FC2892A017AF86D80D361A7FEE8C284CB84F5F09B90CAADD49CFD396E6AC36052F5CCC8E7667CC762A9F173F837A231D57584A3BB19671B8B71907E415A1672475ADFA11998F94F28B00903AC551E651A3F9485DC0ABA3297E561E0B5A5786BAD9EC8169CBD706AFA60AE764BFE01EC514623BAC6C4100F707C5E8A02F4B0D6265502AE4170AC3EF95B49ED1A2BAEF56F63D5667C9FC0AF4C0A8648FB6AC5444EC8A1FAF4715027AC9F5987735D1AF7C55AF4C838FE9FC84FF71F929758DD52E2BD4A34237350642C0E641B6710A66C9C1EA1D9BDA80198FCC56D45D67C3511BAC0971AC9B6166633B1713A969B8DBC3CF60FCD6998137AD713EA3ADA84169D49FBB7F5CDE362ABEB0B71D022D9ACE7FF48C9EC1A7E0C72B564FD2C620272A482941443838D0506E2294B760AC9DED5404D3C4D2898315D3E3A82D2E944D537817B9901AFEC343B95F2844CDC4AAC3836E7713739F4201B95C42FB7C99AF8667628C1B60115BCB185754148B3C7226DF14B6DE1AB4C6043329B176C9DB9B1D73B3814FEB89E84A4C91C84993752B7AD30CC707A71339E8A277A5586BA85CD090F799A6B75523A62C6DF1549D787BD8722D1F26BC2C150D6A38951F3014B83DE665B21F5D9D97F2237333CC10A4114796D56D13D643364306E7445F475729602A11F8BEB002BDDF30E579E26F2BE4AE87DC666974E24FEF2462120B6CD8E79D65A2E80542A9240D4EE1F616326AA528E2A1282EF49F0312174B67D40FFCB1370BAC5D1444D75FBFFB6B0887F4573A8C4622082E1FE349B2C73CDC92592F684769FA7D7CE6FB5AEADF38023E51DA4EE3EDB10368442B218919341FAFB22EE80DA96A52434B184D499A4C49317C62F6D6DC9EC1413D01A1CC3DC8853444E52718798EA158A12B72AF023079E5E76F41AE685494E947618C4AB3036ECDC74F7A043230A0BE116F2B617818A2C94C54CFAC964C73BEF969591A3CB2B7DC9CFAC7B4F9B64AB70BD7FAEC138E42908BC90D6ADFFBC88EF473CA8CE7BC960C4B3EFFCAB92E8259CFAFA85EDB7832B3E630D6D2CF031B8CB570E38C101A56B426C654464228D152ABCC6DEB888DFFD7FFDA974E60CCC2AF7531F38A813E263D9B20DCCB50229E7D8F379F81A280CEB90B64BA3657F1E50381B468D0A6608A4B5E107C4736FB4CAA10FF3045C05453EE12A9FB0B79845E077803C69CDCBF7CCF7D6FE6067ED152F67023CAA6095D1748414580232007AB3426FB2889E1BCDDDBA539A2D79CA523A2CD1B1314C87502909DA849BA9B11F9104772BBA27410018348832B0BFDA4F09AF02B351927F2B6D29D9CA9F330266EC035908C9D4023CDF2343B177F57903D37AB89D0F9E23EB0C4100BC6421235CE5FF2729C2ADCAC24D1151757D8C6D6DE53DEBC38FE866142D1BB593974F4D3198C03DE4625F41BE3D488575B25007C2D5970BB152BC1C23E48A88036C070BD38604C5844E4205F1EF3D7FAC0B4B9FB51F229BA322D3355E458C27685130FCBDF591C0520626E5703A2E85871A62AF0CF2DA3468C401644656CCAB33B2402074C59A0EBB57928F548B5FA4871A8B2AF0BFD9A871A5C257044C17E4967B70D0DFB59F1345526FE59B4BD92A1C06B15E3A6226A4821FD614D8DF612A3D2DDB2DB67BAA3878C68C16645CC747BA9B366677541171A9264B89EE18D9D169D341629393C5526C28B24CD4CFCACEA9C42DB2B1CAFD7F906FC17CCE16612B1261E62E2A700CE74DE73174D3A1E06AA31AA05044EC324F026CD39F7B13399D9D86EEB53A6DE84914719EE31AFFEB630F3D8F08B4FFB10016209C13BA2158ECCB4B74BF04EFA73222554FF5EC49709F7F8DC1D40005E91245F3A5E2A00B9F64678B2D8A9E6BF1D011900D9D12F7F3BB023D1E5985BF78F8D6132AF5C0B9C330F361EDE00473DC9EE7469478FEC02670E8659B643B92C5546C32FE7B0AD816A5080B5E3867DC209EA15AEB4B14E42AD58F34CED65ECB3B519A54BC25117EF8D392A85C2895B5A4B73CF93077E360A828570FFA02ABA84D6534F3EE0C935D97D1D1CFABBC0D82E48937797FAB31704588605082A950CAA23D6569AB793FDC31BBA561E729E80979DAB84ACD4EE6B2CFE06D2EE8C4183D33B9F894C6865D9CD405C7665E0150B2B649159BE684839BD12CF0091614E1F821046238DC9F538F769FCE51E9B8DEC0E98442CABD3A4296F1D4331A16D33CA356B11E3DC13937F814D3D6281A746F054606DC52B737AA40422471139867624CC8E9C559BD25C7C6D7F902677A84BA63E8CB817820048C1C0ADB6288000EF2163B51ADD4D758D1C87FFD574354B41CA5AC72228A7E9E9E75BE9DB18FED47C32E3C561C972A67D50A560017BE794AB9BB6B50CFC43D2F6D57E8D73CAD6227C896BCD18E0D7087F57C365FB9EBF5864DFA4A13B6B5DD7FFFCB648C1E1FE40B6A10EC0C45C74504CF2105AD443DFAD1E306F720B9CC37B4A30198D3123FA9FB2A7A9DB3BDD98D441B03E0EE6A8180989E76CBC71B0E8607C3A9E5D20B6008B010702FC5D59847AFCE122F3FD4FB5D89D3A3331AEFB96B593F724C04885B574A43B5EAC70B543BD191BB818768C67A10AD6E2D62AA4C65FA373A19116AD86A4F9A97064E0C0BF80106DE6654B4A3945983B7DDF3AAF1E14A04F6D3035542B0F710352AFC20FEC78B61D8548B9669F10B3D6E531AD07A84C493264DD49759D95A6AFDBEA5AED1C7D7D2AE6D2FB6747151CB6A5C2F9C1AF5CEDBD9CDE8D5993ACF080A0008BABC759A9DF035C648609E610F226ED128E2656A057862246B65C70774B68F54D68073393B85110285FB463DFE394D9DA0AE85985FD6882EF5B11FAEF2BAC18F9D9D9B5CBF0F80AE7AC4418EA658D68B14BAC135452DF271DD3348BC338BC6C789ED95D5C5625762E4CAC6514866613E6D533AB9814B7C337260BF16716478401689F4079644DF4F734281C16164D19C4ABA20ACCCDC517EF42C19A5B1CAA4658C27B61902ABF88EFF0795D2C971608B0570E016CA0568CCA3F7B38FD3DF5608154A33C1F0D70C2AD0EBB134A8F475A8BBEC8408D3B9B0BFE8A6F10FD6C979B13C3EC73F191B788A79B4D07AC45172950689584C909247DC8A4CDD686186DEA16676851B8A7C311439149B1A963B0CC60E5395B56ADF27C25A51BB4A2FB19E14CE66B6D11781E89B3EC22CB854A12D46970D1A009AAD071C479D9C731770D666CDF0BCC381A3D328542F6371FC6F5FF7C4D3BB06186C048B2A3774EAAA3CCBA1342927B498F2195213326C9E393153BC8846AFE2120B8FF4A455B59AF6E65BC0CE9CA3502BE73D74B6CD12A760A9E0E0D26BD105FD993DD879539CD666CF2025DACD481A122627594CAD7C4FE30948412C1C6A160C358E16B6B67653418A22321DF5B1A9EA0DFC3C82DE3B8CB0F48EEFA7DD6188023D1B8B7632270E63AA38873A2C4472F9EF1E8DA56D5328C00548DDC4D9FD79115C5F6168AA98099BA1AAD606FB92F8D253C9A55773E5629E84350F3BC3B00D803E83CC2516C6C29476018ACFF2ACF61584A175E67EB8952885772E6C2D7F9C2B79C8B2F2A77C73C8B0230F080DE716B2A13DBA5FDC8648F17573A2898E72B8850997B6085F98523F00516DC7A90B9C2701BDDFE505A6C330D1118AFABC731A1DEAB813AA0E17708122C0069FB61A02FF6D5EFDA990A23E1D42C520CF1975FF06F123E1AC0B0A86FE666F8843C406F5F1E1A36FBB7A0B41CC641EB49416D6F0AB03CAA6AC0CE3A3DD1977B4D16EA33CF75A37A6092003D097D0ED8FAEE89F761B40F7E600FD502887AD90BE4BA311B9F4CD9D348DF230A2EACBA3FC356B506ED8C357E228970A948FC4983AC3ED9C3ACC22FBFF56783A73231F7E0B91DFED20E754ACE7DDDDDCEFCCF3ACC76554C269D634DC228B38C284AA35C00487D7873C8CFE8E8657726FA845863719FCE5A9E32406E2191B791F76DA035A4C862176040DA9AC0F37E66FB84DF89CAAAE9D8804824725FEDB95E5380DC66CC72BBCA1E131E6B785EA2B2B4A05BDAE01B22C3D47CA85092802A8EAC42E963A62307476FCF94ED7EBE5538A8C6F28A6C65914CF48299D3BA2B89B3008D29CD874B79A72AB840815827566E50627C2C332B1BC60060BF2FDA320FB040FD14D52CA59B24E325B5783BA1BDA3B27415C9DBDAA01562466322706CDCD0307C3305DB08D2663C57F6D3307E1C73832F8CA712402C7402EFEE0F1BD77CDA08F5F6582540D34F1B2809F84EB2F540558EF9ED46D5C636C45856AE57FD9E4650359635BE72028D1CD37CD876E0DC598E360CAA1DCD1F9F2BB4CA27CDE012980080E91B1C7376622907BA6674F1EB9E80148E6A959EC74950A2B934D42B84D739F1DA528F5C6E1C90A238E5167041D4E9AE5352B74C89DAE368778A90170461ECC0D6B6C6C53CE36745A72F79AAA1C82D494BD89D719800A89127BC3FD55247C1A29FB8387F1E3576E0C45F4D327C0B24A75FE25EC6147C890F25E50AB3C43B94F451E5B5D67F8D3BAAAEA1FE211FCE8622600400F73C1398459EA7FC59D02582C2806D01023D84BB50E99AE9ACC217B7223EDAD956FE155152E7F35B2AEE1535885EC048C6E0C50D395B0F1C9D767048E9D2DA7F15BDE192C923F1C74ACE06600628602D1B0189FCADE0873880EE8544AF3E29314E2B5DF87BEB5A50ED72FDC093800B12CB2F870304289A73A65D7E2384EF3A388EA9F0013B2B5C92149E2538542D95FF020A23E976A7DB3E2C9913D87D6EFF12BB51EE298F1D2CFF18FDBAEF56B70CBA35EB9273F1E58A6CD38F1E682A759FDF8D8BFF60E7CBEA948E25DF0114BEBD4AF13E4E0D4E7C9EAAC2C5F579A1AB14E7FECF9E13F20DF873F8D0E090905D32C8F8C0033F5D8E9F1B9FF17EE04FE3656EB66F5E4777B60B047DAB9BDD883EAC31A6455D1719CB475D1715CA0D12762F94AE78CF3C8EE90E55E71D0AA4EBA6216A0E81566F7813E7759BED30860BF22178407783B9A8AAC30CB4D53AF140E33A47ABD60F33EE700C323277E751E5B32B221E4B9815FDCD400DC544DF845619FD733F164937144FC3D89D8186F8B898418459811B3E66796DE51D1373B248A9B3B9609FEA374784A33989FE9F5BB26D2148F7282E09C35E13295D90BBC7795DD72CDD4955E9D148BC779AEE9C7992BB85D8EAFD102FD690F2C679CB7003FC4E182678320738361C361747F49AC6149CF4CDA4B80581844F5EE4818BF61750047C35A4B10697892A80F07E946F357574527FD2D0187873BCE78EC99062C70CB4ABB72A104A770CD7ADBD20894E7BCE2874E45302DC0BCB9645EF28136F36E7B179BD003D5DFA68A572BEEBD40EB9AC1F9228C74A788671BBF4781AA31C7F8699813F32EA8B60414C3ECB894DC7B01E50924482E5C068F0BCA79BAD9F469770FBFCB3942D1A3E54250E87B3693329479217514A8D7B734D256C5D28EF854FC3F234BC671F5225B1DCC20E590D8E5D09C07B22EF0A89A5B863C2E652CC0B1623579541C63CE9C2C4F66BC43323D7000BBF2923F5B8A76933FAF950D2172C1D90F522301D9A0C22F470EB8673CDA0A1B494FD7EE9AC1B4597B2DBC26FEE33A08CDF91E3C59BA4F93E02D010FE3F1C1FCD694F05B7A8FD32D8E7CBC2934A25C481D9C58FED7E0AF3AAB527D6DEF43D53756F0C95B2B58A426F7F61D09F4FBE55D9AF053B92818ED9FEF1CB41FB5CA23AC85B0241900F73971558116C5809F565F71333713EF5BE87B0AC95364C9FAA80DBB9EA84B5A5790D20343141093F86942817D195ED8DF4A2DFC7F7090CA3DB46A92AABEEAE2D7DD8B9110F23A89E4FA7B5A1DA27D643BB879888A2238E221E2F67D9DF58E73C46023FB7E999059D3B81FB753B2AD333207873831AE42FAD8092AA04C0E4103B1CE0DCBD6B06CC2F0AB37CD1D10EC4C83428CDEF84041D12BF9ABEA5C80050A853CC73FFF3076BEE68078737F6EF483F486215118C640790D0CFB4C6E5243691FB73B1294E0D3A494A4A538B94FDD2746193D9FEA24C1C04F5B20D2D40B638CB932C35D953A9D31260B76DA878FD52EDED058D1DEFD9CE214D14C3112FAB00B7F2DC88F7EBCF79EEB1C9C8607D6919B8D32CC8416E2B981C141198DD9884DC3927EB0192B6361AB556EB3977E5E242E5E26BA60BD42892F46F3F2DF684D0D9FB41BE42C04F0C248938AC79F110075B42181DAE62801DF76AAB50AEDABF4361C0EC597F31245B0390CE2629DB933E450E09DD39E6A1B644B0FF672B52ACE2AF52780D3F6505551F52045028C4DEE6D1C6A34BCD5E95E9DE1BCE849643BD07E0E6FAF8B27504F859D73BDFC07FD2034595AAD85A9DD9AA5B3A72346D6F3C4B21C4CFFAD8247C8CAF0DD9A708E11450502BF3C28EEEDCB0E1D32D3EF1A3F6237E34C0E4D0222F496839B7374EBB7D786973E85392AA8FF2A9901D076DD4C65635286276698DD4388F867D1ED18650FEDA9B03C80A3B5BD0AB3A62A45ABECFD55898BDAFBA58137D4BE29EEE8B3B3D1C4467B63DBA1EFEF2C81CDE7CFB101B1E65084A0E92955690C8CDE6F93E23FD79B76DB475CD24DD92A7504510F8DC3B22EBCD0288B4E479F8DD835297B196531D2DC759364306EB6780FEF31C9E34142B55988F81312B310093F77CB89C6E819A7CD3450D0790CB7B5E33A3E5E51DF05A3BFEF63320CFF072D450D71E7239AB24E4D83A8E8E501A5BDBB041219E15517B15EEE237836672A761D36D11EC973BAF65320B368906392E2689A9936752563172B3A5ADD90066E01EB394C77E40D57553B883F446C42EBB9CCB47FA56816B06AAEB62C21C8F57F926420AB7C1D5E97E73F024C259011CD585C23D30F99D22197B569D67BF5965887AECF553A9B48DCA0C418778AAD65D4843221B8217D2D61BA5A46C4F9FF5B00B78CFA8B6496007A1444503DFB8D7CDE7A63D5D7F54EE5823A33EB3A155C20F0011304068CE0385A09170606FF6895A6955C211AEF5D13BB93866C9CF00A911A4A50A59133113A9C7DC53409097808A6D0DC44A7776B41A7A43818C77CB51F3E20107F080F6682D90399853104B8F3AC4DE8521048B22BCA58B5F7B5EB3E3503F638C1FD24568F23EC8C59A3359A5C9CED0305B1B81677E20EA35F9E896E665D3CBBCB6155E1B0539A0B26BF95396DB8548124519B71BEC19A17DFD4AA2A2E134BEFDCA352B01E1255A12377D811FAED7809C9B881B24C185F1D1273F405F5BE82FED08F26E6C11D39A604E88A1EDFAC8AD3DA9FE8B1111C7E038A14CE58B9598AAE96B7BE84C153A9B26993CECB1CE931E0CBAD5F7F6C18B68E14E83A6BCFA33AD2B3A707118D56803A1E55CAC8AA93EBC47F9EFB", + "signature": "626A3DE2BEF13592E52829D91DD5CCE8E679AB2384C317DD721C3D90C9FAC0DA9E07F5F329FADB83A1C3C1A06A6351AF25496EC7FFC232D060982FE36AB460A905E7E5BA6FD1D12F17E4C4C8D34F531EF6AEFEDF5F29E4F6D24A8C9BCE0F803B47777C78840CCF9AA4BB798D7429EC8D9BC547F24A203D565A012BF17903D75F021E2FD41B8128320C274B95BE21F795F0D13F1096E59D92B85AB447ABF603DA95488C8CD4EA2DB181D9B66626168B765A6D7E922AA9F2F79631CE32A6DEFD4151C4F0EAFD26B50FE8007518280A647B8C4BBFC48B75AAE50C20E988BA863EBD36465487C72385C16DCDC5EF409911FDC9FD9F1F69236E18813D7688B64F8735805AD8FF8494DA36F42133FDE81539CFD1C430DE02ED8B88D5B0DC2F411E7192759971E4AA68E5546F14CA4E3F43ADB3070A8EAC4AD82383FCA3F8FFD6A80E1984653968EAC57BF55BC14765D91101302AEA86B3FC599C100549F80B75ACEBEA040AEB4FA0C2B4EB4803BA549E0D873D99DBFF0C8992CACD6A2300B46F5F4F61FBE05EC6B203F6386F57F49223550406F6F4CD9E31C889A9ACE17D9A846F7590F8EF0A3FBD6E4E4E3D940EF78A9B0B2975A5B442F141DB9569F993C6398AB98A4C5C5B3BFAE5D00C53AEDB5C6376A7C72387481D72AD84F96F7DC59DDEBC41D062455CE042B573F62C98C0B580AF3DCA8155841FD66736706FAD04D9A518E96C0A1C92BFCB82A78A696ADC70A518B25DDB30EC97E8DF355F87C322008ACA4151E57274C2E219EFC811A538B8BA26DD44DDE9C429C8566C30AD085C1569EB163DE705612951F8C022656A2462F92344329FC40D59EA66C07D44145F54A8CAC1939A01F359F54932A9E8B691E0FC3D01894198ABA75E851DAF35CA562DD5340DE311F091E2C65CC294558FC1326856924533A46F754F90F51569472C9FBCE63991D95B43ED76453707DAB30717A874D17535C94D880164FE89B014016F1BFCB971F651178351885034DE97FE94021EAE46FD5624E2C501C133D56D359904F9E0F8A1ED887D975CFB4461923FBA3AE566A27198BCF6938A4C80596396A2BE7755AEA803F4CB7075DF5A7D70788713DCE543AE2280989166EBAE4E7DBAF3DD6C92FC4792F0F11DFBB9B4A465FF9AB96701D5795131D71285A74FB93EF20C8DDDC705EA1992C1CDA769D2F43C5EDE7214823CD8F2C7219C482A6B07E88C6DC3186E04FDE3254DA0E9767FA69836FC509F5A9D9CBA41B12F948F163B2FE487CC83BAA5986CF84D07D171EF9F6944B5DC9FA7866FA72E7CACD7B4345164E4731971C8A75D96E9EB0C61B4F1F3F32CEFB9453615929408411F118A6DE1A9FCBE4FCC71AB730CAB4BC28B61DB6029A788437BCFE5AEAA41CD90418F49766E20D91E0E29714019CCF304371CA4C498EE48C5584FBBF146B888E2C3926FB5BB12CBD0D1736BE74EB533A7C34C06349A26C3ED86DE52A37E4B8EA2C1108BBF3E6773267C5B5C3E50EA16D56B24DDB32FC7F9BBEE75DF88181AE97FCFDAE2CDCD5CCC2E141A9379820CDE613E9FEC61212D23763825D94FA1102BD7F7EB1929A2538731A7E753A7F6E6BE57172C9B8349D8EDD698D1DC25C55D7F06775C4B9534BDDCDFF33DE2F1E9BABE78DC320A202ECF94037801F42ED1344091A132A24B875535322FCA82282D9AE2C0E1E926A2E9E1A4D2BEB6A58B85D65A7847A57E6336C367F8C0812C055B18E8A0AA987599531DB98B8ACC58F5DF9D8E7357888594A188ECF9A805FD767A1CC04847BE22833994784B545C4895B18D06F157F3B75BCD922A8894E2D8E3D174A3C3657B4D4A7B7318A4864D7EA59478E49B0C8319375DED55F93DDC5A51C6048D028195D4DF04206678644A2A6A488F605228E4120FA97E271758657FFE34F0AC5044F8718C3E184EEEDEB62D0C29670250D491E1FC3E59246EE06D3CA31C167BA3FB52A77E1624E34652EBB1FA92DEB762FEFA87AF0CA5872AC6E2B6429ABFFFFA10A5F346F032F753B7075B7CB32E9E899D371C7AD8FC070D25D6C919FA478FFEB91EFB62BC331D0A975157653D07E3202452A05303C9616CE9A647FD4C97E1E0DBD9D8470ACF5D5DB77780A5D515FC7BA795A071B67F7F63D8A4C6E05BA2A7B31AE16EA31D8252562F44DBB447935A3EE504DD135AD6DAC43BB01EB0C5CBA939AE446FC260BDC488E3991D1BFA5102E262C4E31A034B8BA12C1E0AC599474DD98CC014F387B719AC06327BC5F157AB80D424BBD10769BBBF97964DEA127FC52F418DEF5DADCC93724A725CA47300A31F5B1D2D93AADF5FCD59D5F30BECCCBDF34AE458C50A5B54FEB305EF1C3F42556C2E97DA0327629DB5AC8532D6E4AFB22DA1687F536C17D7153D8791805061FBB31ADC0AC2F15FFD764E46DE3AC541B07C55BD67C7A5A972E0370620FE67449C58769D269E160C772C1DE53C46E880D5DA7D58EC100C6810B1C6A051F73B42F8682F166069E6D0D06D2A5894E4B6F74C42B31DCE09281EAE9B1DB21B521D6F910CB8BEBE8F7C09B137C7C1B7B185CFDD91E2A0D9503C35C99EBEEF4B3011A1E5996393FC21E972AA0E6F576A426141699AAA0487C686C1E14E74CC697F4E21591A75F5DEFB98B5D649EE2AAA85391D25FD8E2A20ADBA6523C26713165ED207CA3EDC7F0CBFD5468F4346A209D7A8EB2F63DFB6255F54C062BBF2C90631B539BED1A557A16225FC3DFAF9B6EF2BE10C0CB279644AFA74A03E66FF4FD965184B9571D4A8EB2357A4EEDBAB71275E3D5DD8635C53D29516E98F74B51051752AB7D1954156A906144EA4E54A11826254529835A80B6A3599953E012D4953F4B610A85AB55860C305787D00BD61179F369579EE1277406A3F55DE431E3E7EA8DE07FD4484DB4FF458CFDA28A2307334A41DB55E31CEFB5EFCCD922E475D06979E690144F77780BE1DF0667F746FD0B2F72F87399AC11B9417568D3691AFE1671E08FB2FF508A68AF6A3E0CAC6A9ABA02A4E8AFEC4B7F41CA03EAFC31CEAE5C523703FE41C1CCB6D021678EA00B6AD24AC63ED1F6880C4585E4E85BD975EC84417E8C4D4C2A4B6C10E11853C9DAD6F07BDD25387B66AC3DEFE166D6F85576DBEC76943B87E7C91293D51CB2542B63828571408F893CB541C8A69AD3054FA9EC6759A173E82B55D78CE64920548856A664E21844E97CB264F42E11754FE5B17AB60FA85897D65881207164AF2307376728D738EADD4F486BE0E5CD0F1FF2B080C8D966C28579DF5592AF1E2FF39EE0E318596B26CA5F48F789CA0712A7573BB6ADF3706D53E644B70056FEA3C7EA90D0D1621314047545C738E93A0BBBCC8CED0DBDEE2EAEB0709142630353D434C50657D888A909AA4B4B5CBD9F000061D2C2E39464854575964747D859BA2A5BBC1C3E0ED18415379808394AAB4CEE3F500162C434F" + }, + { + "tcId": 10, + "deferred": false, + "sk": "2EEE200F329D7A51E31290AA8C6581EE83A0B6F215ECAB93D0F0E4D0350B4548999ADCD8E8E40E7BAD4ABDA6B7194C206595C2747C4CE24E6EB6BDF0101CEB17716EE0336E6730404E8B6F8F1022F66C791D166DFF04E6A18CBC05966306B34745F4E213CD668E079A0DB2762FEA5A1CA548A026120289781B847A96A070F43F10280A08252564A48818052C6042280A4989199005CA826940382891820149121204024EA4240512974CC092859A122048B82812B881C9360D4B001090B60C0A398600A5100099710BB5201A196ED10612D800251A418E1B3321DC404D20C3404492055B1248102500080468C1B611D4C2100C94046442204B361189885022A08561208A23B64C43286413027121488900300212A33109B32102A561C4A80154185203010A00108D2230801B1760CA406283484E00B949022622001765CB020213B90D9C368A83A2915220465C82898BA09182203118B30112B240DB026880200610112919948884222AD0808503324A583231511646A14445A0A64598B80CA49230C9828D138685644864813669080460E2422C60204900B50113496604C06C631285E1C8295348614BB828E0182A634881D28881C1984444867089369208434A19A920182088182940A132514432688BB87113226D132051A33031C118220A450C9840518234010903929A1226D28691E3828DD2B26810094E039728D8402598243208938492468543962192982563322102A291A494318C306CD4004009874521B284D1885124274C0C410D61402D8B146283A689618808D9808464862921994C0A990454207014B3608A168D09150C9C38305AA68C14118A4C120A9AB03109122018328AD240492294650B23121847060A321061980583B8300BA08D633426D14260D1886513C6685B082E09B9601CA48D519861481248501431E1B811C41082D344249B424D1B310D99105084468DD832851B14864B102C221211DC908183167008A770C2440253388112C68423184952828DDC408C8B4884A11060CA8000DB2089C2805199900C1B044D22874802378602C040591484C0B221220790C4804C48068EA22006109489CCB60CA04226CAA46552003050B608A146914A007221C711D9088483103143C009E3086961204E239200C390611A3529D808421A422DA4208120A351CB080208495161144164B044D0A6400C4081124025C9B631501870942850034868E0B22DE3B86062486C0C336D0899305AB845003991109040B90DB8DA1A76D8382906AC6480001D09B8B836B9724779F5333E5CB7EAFBC9BE79ECAEEF30716D5B8198957F201320D88030EF5C82C56EDAC3E6E7CDD8D272EB421CAE9BD5F07FD96EBD3F21C0171EFA28612807DBDE1BC11587A52AF2DD2A9AB7F24267DA67ECC77585BDB335DD29E7941DF37995A7680E71C4E688B840A19455E569B5A777BA3137384E0FB6F2CD937FF55A389758E95A4F145416EFB0EFB094BAADFEC3F91EA5B9AEBA8F461F4B2A451ECAE68B50EBB69D358C12227E8995FFE00D9A3C6AB4E00B58AD99C9240B4D2AE6722AA144E27B6F91732C06A86072B69001AF41F30CECE4869C334EA78126A47FE2587BC76B587E25E61B1EF8CE536C0AD109033B14DB41B9F2F3E18D4F812428E9E9AB88E6DD01E8C2474F6F5B1BB1FCC3BD905F1B16034D9EC562E65F06C14F5BF497930D02565EC9A458BEAEAA5CEE6C93207AFA1C934961D1A0F6D726A4395D4730575BFB09F41B21FC5A816FF6503A0ED308D693EF4FBEB88C09CEF42B1B1982218C3BEF1E81B63DD0D9B1BFFEC50A5782D00B9EAF42DE3561E47F2EF9B3882665328D17567282D1B1B91FBDDE4B64A5876BDC61777FBEADE3144444577D591CA0CB5A665251DF22E055E25AD7543A21566285FD3D3C85E7A4849DA65A28658FF631DE44ACAD7B066E2D88944BEDAC4B220006B19F5F15805DF64F320AE38D05F0DAB0E95E02D1707C23279F3CEE21FBC0D921B334E2A41E7D07EAD955FE5D530F3EEE696248568282A4CB03C3E017FD959560DB0B2F2149F2B01FA4ABE1FD17C0321F38E77460C29E93D88CE4301B58A493C1B29C1B81C0C6B720ECF408EC4AC8BB744A79418531BDA100236268C257049D84598BE897D804FA13076BF9E426D700101D10460E1A97FF32974E1B981893C0022C1BEA990AD92C2C52409C05330FBA5EFFE835A2D57025BC8F22796EB42E6C3CCA9240E3B5E098873F45D5F2B290C93DCC1485481D3689C835EC613A5EF5C6EEBB21AF65403023EFF15867EA26E400FA648AC02C7BF4FA9EEA4FDA649DA80AFEE18A660C6C8F09FC45CC6D0C1941829488249052FE94E9E782C49174B680D7362E41AEAB16B797A05FB55E66A2A0DF069106B3E28F1CB7E90B5C0AD18936208AFE951DE9BDBC1EC66259C9D80C9623C68E95102EB6C597C955B37C510BF421FF5B38590564960AE172DA8605E01396992FB918EE2C107D5A13AA1F8601B775BD5B9226AE66F28FC62FF06FC2ACEE4ACEFE64C3234E4FD53B76CF0232D5C9D7802A040D4E529616F0F43F118CB678FFEC23BD92CA08B18617B4454CDBFEEC86E9CDCD80A8E918B73C3C3311D258C6E2F7ED1890FF0D4F28E935B41FEBD17A41048A35B9AA2F15D1D32864DDE6D8A82E65C17615C71F04A2750F5D9C5D62C24694DFFDF1C900733365272ABEAD17DB695B5285DD16AB83751AE3F63742C5F87806950EAB68E35DF9DB0FB4ACC7409BB896AFEA9C49DCECFB9C933AF12DCB7723777D0059460A02309E9794B04E7CEAEC0AB433311BCF42AC636B71BF73AE439EFC3C4B793287E7F2C8FADD81B2C2A9A09FA1C956DE94423BFC76F791AC88E9BF0EE9493BE031603BAF103BAE535B9A366DCD45EFD324A5087FA6D214772FEE650488F83EF201E9EBB8F60B86B40B2415BDF5AEB0E20EEA5153534F93EC093431850241F7BCD4DB2B5ED441FD8013F14566F6B4ABF725B3F966E0C3BFEAFB5D0C2B6D819887985CFF7DCD647E0B5ADA53D895D14F0361A8E83A7945A99A833EB3AF65D6C9F2FF811F5245A629BC646F3E31DD9D7810BD4404A1301D11D30DBEC2DE0163953760A6C5C7F033BDE8763DEF5D396BB141788D239B720590A79D73BD46EC7C3280BF852A451FAB4392630E071ACBCF86236F7C07ABA6C90BCAE4C18338308A08C1760879A8C2E0D561981B39A4694DBAD9AAB1E4A752F87CBE6BCC9B1BFBB314EF3671E95C654B619394123376DBD4823F5498991DE817B82FDAD2C06AC74CD2F0FE13897527ED8056CCF315C9983031A10E226A2FCBAE1FA327EFCE9F7241218ABCFF7F3934D45B82DB6124897DDAC45DC241CBB42569F926A6740ECD74A9EC6DACEE48CE955F9B3B296E779625A6514AC5D586BC407300572B3693C1272609DCE114A1484F09BD7201C285C2E8CB5C394B88A1FC9A0B72F491A7CB445B3D7F6D9585FA0AA6FF2B71E32678C8B94625B69B1F008F248DA1FE9480C653974BAB0153B78AA642F191522535138C326864C4C9FC895C092C1D05659F01EC7AE7FD50C9E30C7C2E4785E2EE1A7042D6A1AD17A73996B8ADCACE9888DCFA120C8DC527860734EAD355C47136CCBF738B3594860B795ADC28", + "message": "3F1B179FA452CFFC1F4776B275BC9DC61A4448989A5C74AA4F6A42748E49DF12AA62C5DA238BAB9F4309D563EAFD739B54E8957C0E91DB05F63B2A50F11205F5AB60B0E857F1AEAFC0562A76626AE579BA3387943E8B735A4B1CCBD23A6CF56D7F38CDCF772ECFDB7CD40781EC2622C10D65BCE780852D7930281726CC2B83C8D8179D842CF3DE761B071A6B04A383624398FEBE34CD841CBDF9C256A5EAE3973F0C256F89665A0B23F0B505A2EA73F37EBC11AFC2C3D4FD8626EB86FF0267D00DBC567796011E5548C08208CB0B43A880C1590CBBF0549683BC71A8BBA2CCA5F98011E592F3B5D7C8CCA0165A58BAF8CEA629CBA860511EA2E86B4CD9E721E8D7DC608504114EA98D016C0C0EF67EEF084B8FDD8BA4825A0615F7E09C42D935D9AF0DD847C2435D84B4702ABA573499C9088EB21CFB97E5B5A847476FD25EFE2C2763429048F797FDACD8238937024E5D66B3FB40055C3DF19E213E5941095CD8FA62BCA591007D03CFB879388983D6E7A189782F36F88EE409D490C5FA66B62510AD0D0EE9EFE6DFE23139944046C62EE639C0F82E6D850770A69577DF6034084DB97E4FB2BD206281A79CBBFFFF8A9E4B70252F6F03DE8FFDBFCB0A5267877FED3893CBE5119F0C6930FC0DFD82C63CB1E7DE66DF2141E184646151CA8A927DB49A3EC63B3B862AD60551B0E562F35E109594E4E43B192BFECF066B3C7612BAE0E170F0E1D7D246CCC3A2F94D3FB08BCF9DC7DC44735E258B1F9D0D8152EE79FF9EF095EEC3FCD872D9584361A44B9BDC88BE2AEF1158D1765EB4DEAF441F2407039E98DB8D148DC8B7EE9C44D5833FFE4C52A077F57D9E36CB220251C58F61759D18E4E449E72F29351F6CB08F9D996005A33EA695C21FE883E1C3BC3DC3E8239F2BE16FE445A18AF83639156521188EDF3F15ADB300A17F88C829EB72275F6F35D2D1A72B79A01A50F1A63741A8B1ACCC35E49D331DF670D30DE8855FF27C9F6D7BBD16CDE4C4C4DD48CAA971758D714E89DDEEC7CCEBF2E89F8CF03D7E631B9A18ACCF19FF35AA24AB6A1E10DF105FFE2603C30E16B7194AD615038FE96F4767DB8882D48C97514CEC057EE636C9FEA31BDAADC5CAF6239A805BB05081962A2A5054D9DDB47AD9D3C98D053A5199A687668425139998BCB466364F656B1AD9F13FCF7FDC50652841EE475D86AB89D0CFC01C6B5B876AF9D0312A43DCBBC71B2714B0C3226967A3D1E0AD7E9368EDDEA9120B2C8641EEA203F2E943F43708EE6CDBC6748A33E3DBEDA2AC492A6DEBB9751E7AE4AA33F6ED893AF7054454467E29D7EB7F2163FD24F7B5607C2E77DDFAF72E983AB532C6585AE8D78757DA904D1FDBC10768E3E70D582F17708B51D561C24EE0D5A26559EADF5463097155540F26EBCE03D89F49D7033AA00E1DA5ACBDF148DDABEAB739EDDF99A6B2BBEB48F83E3516380FC7AA9FFACA8DDB53388485061EF5B94E92443C24DDCA823E44A29116F346A22BB3DCE7022C3E2EF35ECAA91CE5F65D7C5EEC85D741ECEBAEACCB39F881391EE2A06BFD7B72173B171B7D11C8792F0A7D9A125011294296B157591A675649716F92234BF074F78EAEFDAE1AD79E4208C6338F42F2A9B105EC5C717301C638C63555AF0A81F63D0CDD04F9C22E2FF223CA5AE1A01C7FC61E9DA4412E80D493A7C0DD49CAC10C62A7D3ABC1B9C74EAA2D8AF248946EF8A37F1F7017E49D11B89EBEC111D85D7C1512EF4F99BFFEE68FB588DF3F39735169D1B5A647D71F52F76C6BC09F5703320DC92BBBE6D7CA592566483636957D235F5D18150B6A4641CED6276319244CD8EBBF74BC5DD3AF82E6C1118D19ED291ECF84E4EC2FEFF28286898E9659B01A37F4612460B34DA8444A4805FDEDCCCA5D6D8013335B4139101F28090517FACAEBBEFE59E44A969FE3B8402D690012AB908EA590249BD9354D456EF65331608478B2050F985C5903FDA5AF0D918E7F7E167C3A669B727DF0CE96B63D4D944493C5D2BCE97F2827CAF54103A18CA8CC0483BC8B98C42657349B8438C0274E4401463CB55E93023BA114FF8CF3A718740756DD8C92958BD07A304FECBACA3CCA8135AAB901AF23E1104E202395A08784873E03FCF2D07AAB003E6581741389C238942D7A2B9FB30B53CF5D0C408C0EDFB1C4FF448D745FAFB0D659B4BB76B16D5B61B0A38039488682907151802A815AF220F82680E523E838ADB47425369CC421DD36C2E60100A9EA7F29B05D985D644A7FEA573BD24B922396A481E33306AC41CEE9DD8ECCD9DD7833F8CC77477EDC2E97A72CE2DD930BBBC58FBFDE78DDE34CA1F8DC758CFCF2ABCD35CEDE0657B35583F9C016524D3AAA5E698BBF85AAAD01D7D3CFFAD4602858BD7E2F173D6A24504E448926DEBA1F70F3B0D5B454B02AFC4D0C482BA8019A0C209ED071BD2D5B341EE06FAFA7FB0D1FFE77FC6F6C49F78EEFEC44999E4330BDF33021EBD91DE8EF2042FE4C3F19E992A5E66FD9BF8E3D428AAA8FA51C7C761C2CAEC8908DB3066D50BBFDA98B82387E92611514605D6CBCC0AF9FE08B39AA1DEC89CE77987BF3BBFBCF362B4AFDF12A8A1ADEC69962A6FB26610C816F023D87E648A77DACC3997127AF770658921DCD300EE2C8C0916593067B3B31ED1B6B73D68EBE68CB22386DE39E57FFF6AD766193F99CDA751316A5B0729FE5307C107FAF6DB4CEF4B1C6CDE957DCD6361606A6606BAEFD9A1AE08A5DB21991F022C4BF758D16FD53D6CD41F637F5569D7357CA048F07F53C850CC56A07A4C2F3BD04DEAE79498EE10B366861EA82A7E04B9202750D4FF4017239BF1BF7088A3F2E2C79DED5A12F75CDD754840868754428BD7392E4F01F36E3B450A9BE5BB95FBA71C960C7D09DBF24E6662C86D8B5C3E37D76B16845B0F88C40AE7360545B3304DA5CBD2B58C29F6EDBD794E9AC779227B0FD198EBE3A172FF4B8896F0C9BFB7A4FD9FE6ADC73E097046FA25CDFEC45CA1E7FFC4FD582DDD8C79A9F3959A4DD7E3473D6F242B0A6AD4DEF109C12DEC994F2E313EA1930ED25CB401B82212E86150BB53BA88138AE3269157FC2A7A919E21CC068E0B9E934701B572AF0E20FC2CDB2B7452CC1E5545AC4CDD34EA0097CF531FD92E3FC38CC50E1FC8ED59272FF3D631FCC239E4AE0AFA46419863A166DAA2CBC63E24C26ED7EDAE476A194F8BFDD540D640DB3A8B294E0DF0AEAB7A735589E23CE524F534AC82D80CC51DFC08EAE4FD02E6F6E0BCDFA0FB23697EE1AFFA735566223A70EAD827DD31881A3C2471677F905B64E6AAE00467561FDD6C79B45016F1326D705A854877DD91D0B147071B00C5F8A600116487D39284F6334FF56F124951333F723D68465B765B32B396FC4C432D51E8C6A9782461EFADC2CB93EE38D4945833435E2E27E17CA98998F9B33057B1C73E2E43B6A184868DA05559B3050FF42C76D7440E1A5B803C8D4B0CBAFF9FF31C7E98FE2D011B3F87416889A81DF9F48643E943336430602C5B44C1D11BC7F62A0D67BCF9964815CA0AB83E7A87DB714F2C1872E5B9F0843B82846516E54A3F7FE311839F4910AEC6CF0D23F86BF2B0B05BB71B5B47E93B80F7060A350EE4D73EA09A6D489BDD064763CACEF5818B319CC973FBBC78E01A505A2F6C4F6812819E02A573AD8F7A345763943B623995B0634562479072D9E42437FCB2D02479DBAF2D088B31EE870F11047E965D04524D0CFF90B943B1BE969DE752249E8B48C609F14FC48692BFF40EA6095F1967DB766C8B4E18FA73DCFEF18F2DE1D295B51A63880E288ACED85B188B3D10A0B025BBD934BA43A5AC5E1829DA836EFDC88F4BC6BA0F4F23A4AB16DEF3B5488BF6C974EE1BBA51D17BD472C731DD35D5B74EDDD3C9177A3503D783968BCF8A1F2549F70069164C965304DE2434530B3841A2AE7DD47DC5FDD9DE046840B4D65A08A71A3D15778865CCA2418F154403183FD44B622982C64F771C87E18C09489493E378476B3B1C8D14C8009ABD3D1A51CF806189496A4D70FE857822049D3DCD4CFECC2F95D2A8A16D94DC6703B4C4EF3E8C7EB9D6859350131E1A03EC8A21E13F045F822C48EE3E3A481EECCA508F189954AC267E6CD19C80F8688410E2E97C71A6C792DD6E33EAB2FD16B82214588B923AF6C6069387F6A72CE06033913B50F0310112DC2143802AA2CA066388C96158AC154C33E9BD72C993B410FE5E9D7CF37A30EB85A127A7773ABFB416419A5B4DDECEC10E2EDB312C86C3F3C8BACADA66D057FDD40740176D137B1F1ADA098D978CDBB938F45D4B7814F2C5B894CAE249CA8E1FDF31E81997F7C55B7A43461F5C7C9893AD0494F4F0272FBC20D80F327EE55250F9560A301078BDCDE94D72A7D113ADC7C739D7AC2B8775D961F89245C5AEA8ECEB1732FA345FCD84A0C07C65F091B4B32DC4E117D24D782C404E8FDDFD6E9E65B3633985D6DB8CA841B9F9A3B3C617F1D69FB454045C5024AD09C5C1080F3EAA64202C08838B42E218F56422722536160F97ED3C08F285EF7BCD1119BDA59DB5EC6BC8E9DC1789B3CBCD469A4BCBE1CE237366A5B51B062D0A08201D4F0EAF6F8FBFFE53F35999763DA2470F2F9FE79BDA60285D052D65DABFBC43659DC76602DC662A3357BC3E4BD07BC32AE5B5E94D7DBDE4B5117BD5A9E3461021A569E200CD3CC518ED6559BF2539D8DAD74920DFEDE8DF8FD8333FA17F0798A17B5385A9569A640685D7365D3DBCE8411D44B17BF79B852B1348AB31335AE013B2877C1D8AF62F88C5186B7313F2C8736472FC5F2B4B38F761009F7623292EF14A4A4006305CC419A3ECC73082F63BB2CECE6A624C2A6DF29DBC6A4F0FD3658C58EE694FA58741DED54889994DC6A3DB4FAF5998B577EFA399E58D822B99623D76050736C17B5218671FDA3BCDF7E81B3E85D87200DB9150253ACB07AFA8FEAF74578125E1E26128116A7446C804DE54FD2D2B1A48E684F73AE91932A37372DB66A230AC4CD54869A0115895D2CC494E6D6E8B12845551B4F3DE0B3A4C114979F0471311434BB3784FAF7F9A9B88D536235543ECED732289B383E8005D98192FBBF41EA8026CA3A14B6895A6EF0548EBEE58C25530F56E0EFF157DF6ED0ED0D5565E9FD474B38EF5BA74D24B82219F317AD51F3E7D6F8E4BD8836B91525E162DB417C87E36B3C0FD874FB4BF4136926AA6D045033C94FD1EDCD69835A116357F341372148C4601CFD84BC36A8E5B2260B90CA797CD5A41362C44B4488399394AAA431A63A74B774E68025D7DCB1963911F2BDEEA60DFB24E87196FF38479D235C98E83F1FC419C87F708677F98C84F9C4848B255DEF2D92E3506A533D36E56DF81F6461AB5BBE9D171ADDD39FDE7552C5D4351DB59543C0FA939ADD6130E25D4326566FDF49CDFAA240BBA0B027257D2ECB83209329944E8F44AB785560DED2BA8EFBC55CA31E48F4C94749E4D205A50BEF3E3F039DEB3EECB213FE92C1C3E98A9F72B6CC316D6C0B87BE7F688000A2433E3A184A68722D44C7F6C90F2AD0B248AFC9E57448E3450888A875CB3006E27C232963740B985484E7FEB07775F4B4FD89AF6F627CC56CA1AF23E3BDF61443786D3F04DECD3CF71E2C6139B584F52B6B656CE0737F50BB270830B102B781E621B3356CA16019696A23EEB238ED74D160269A3EDD35F7ADD9E065F836A61A0CDF99272956555106A349166B2C299B8D0066581DC3608048DD8BC2F267BDB2808E1ADCD37A7538B9435E9E5D7ED4389BD2CCB6E926A927BC6DA19E8E0E946442A6943F65C56E5AB7507FC6EA1DEDEA7C1AD087CC005914CE80A241D42C88380A49BC4B6850536C5A99B6423B77A75FAF76CB17479EADFEF1FC90B832C8F36D92BA3E927C9D60473117267AFE4B115E39D50AC7991BF248DB38E8C99784848013B48D4CD6E034B93E643239E78936DAC6283DB748062220071473B0579FAC64510D033525D786778C53CEBC3BF95C4FE9406943E9D68E17EAB3245C57C00D0C206E3343D8201A2F6C278DD61D0CD42B71CB7064ACCDD38551DC554007F29E1929EBC81025CD1A5AA41510BC5CDFF340F42C4FF6DA37F8E97F5911F37ABF457DE3EAB6114DC858C0C14B9BA5B652DF63D0CFFF4D6F8103E0FD15D87D8EDCA53FBBC70E3B42C410F379BF77DD17F6FF57D7A0D01FFE0044F226F8D65DBCD1803928B29CB6AAB703A0EFFE4EB47329D9D373954F0F15CEF2577EB8F34665FFF2C774EB07F0CA72ED27AFE6EDF158C3AA193F3B5CAF99F52430A3662997DEB386DCF0A6781E42180ECF44E9043AFE95BDA84FD1F9EBDCE26EEC0A4A08D8423111B320EB87156BFAEB3827389108E12E7AAB3F6CC8EF67A7C877BCE3192E503608D6F1E5697941FC1418C16093A55A2ACF2378590F4B0702998A65C8127F13AC98BADEEB32B152F3054EB7D0F200322E40CE632CDAE8F0E6C22497BB6D464ACBE9B461C5D39AF9334F5342FF31C9273146D20F5D4BFC61F980B1862BE4A147474DE89A1A3278004F2CAE293CE2709748507C5DB48D98B484CE933DD3E925E1788F2470C91177ADA3869DF6FF81308DBE846F50C51AD66CBEB2AC91DF1C86EC22ADAA6C702F1CB7A141778BF957663060725A5AD6478E22FC959FE5C918EF1A11964E66B1910018DF4698543CD3015E9876AACE37988370135BFD7047FBFD3996B45EFAB6FFA70A4191F259B8A27EFA05E7E1C75285CF70910465589B41A9D29F51F7BBCE06457A3DFC540608157479B499B2F0CD9D8A8D6F2C01FC79E5079597FB6E2D1C3394B8D8AF65DD133F9D9300DF3DA3D740CD0E7E13EF62BE1D29A3DA6745A5A87558F23D89319BAB09A15F8FC01AA388E1FDDCA117A27426D142094A11E6B49E2C541A82C685D41D6E2520881534012774B4C01CE3D2FD8FDAB8C25E4F0AD1292974C4C141173CA219C07314314FDF94A05955E210DE13F0165C990227EEDDE23A52D7F4C8A181C996D0FAF6C313EB74BBEA4C2CEC0B7B01698C63C2E1D37313B637271DC49A7EED8542EE8BDF7C7D791F7BD59A029419616F9C8F478F060B855CDA73418D0AF090844FC0066DEA9DF8D4F3C9ED58CFED2A78B427B42B033C46485B767D75526DE8682D6AF0BE91169650BA4ACC4D54E0D357E993FAF358BEEE3F7F988381EDB31FBF174239A345130BAE1B0DEAF27BC5E1DFF86B29712CFFAB670D35D19DC5B25DA43D481336C0CCC2120427F30326FC74503548344B585C082A78F96F072510D50E1110EEF01617282CB681CD352A23607C3CF7AD9AC06FB52B38294DE8F87894D25C1D278678B048E3E3F4BA0D884154C5E16780BAE2322C389667A15EFB0B21718F56767EE942E4BCB190CDECA74C92DA8848F41AEA2328D29B10C95C6DFA74B0E162591B1BDC0ED6826ADD0B04C7495FC30E586FBC03D4E871915AF71866278F9CD1B4F1AC56E8E1B7B11DBF0C9A64F608E1C3958910829654057103BEC687A02AE9A568BE514187A3E27F3F9928EEE29519BDA0065179423A7242EDDD8CC337F0B7E7FB7CF90FC682C9E60253BD0997F34F9081FD785712E52262CD17C3508AE4D2FDA3BFE232269ABB185E635E659D405AB12E17A80AEE5BA7DDAF1FAA819A284A60B85B49F1A57DA72A0866B2B9C2D28178995E79D4458B58EDB187B0CDC5C37F111D20371FB8F410A7EBED95474859645FED6F451A396781EF7A02E6B52593189EADFB1226316FE8DF79B23CC67BD2EF973CD561DD612D0C3047698EA0D3895A28B4111938F0A0354E4DA7484697C85908A3BA3E80BCCCAFC73303C767BD3587C1F9D48FD4DB93517A561DAA10F53F330ED14CD65B4A54FC43E5F5CB421B8B6CF7B83D86CBD72A55791588D4B81094BDFE45E3F32A2C3FFE809F66FF310D66032AD6BAA5B33E79F1C476029A49D49CAAE427D8A81EB642B15EF0C544C9EECB7CAFD2A854BA79E4D7EE01A96CDE9EEF45E430EEFD8A16D5D22B751F981667F36DE2E139391980DAD22462BFF4896D277D89DCACBD5CAE5EE90BC2D5954C083AADF632D9051B782190ED4AABE8FFE195000A6BA05115EAA0BCE755B23B10C81DCF4BBED61E6D31E9292DC1A7FD6B453EBEFDE55D6AD8866CCD50473705A24F519548172D3D9F92E668D679D782B7F1041E5A558A625D65E679FC75B15499BFA304435FEE6F6498138848BAD0BFFF6942029BD0C5465395F5368692D6B21B2E22A638D6EBFAF3A0EF1F9BDEF8529C6D0BD328CC82BC66DCDB2F5AE20F53B8AF66400D6C2C0A3C6BCE1E8D2B222FC54F1896E58F61816E301365E12866C1BE7C4BBE0DBDA2B504F0628A4DF1EC7942BC58C0A4CED0046D73FEAF2231FB9FF61C0F7AA564EC1E10BD65B693CFF56DDF3596DDC85CDECDF7F123F9DCB27269A7F65A435ECCAFD89A211C829BC7F5916DDA61959AA296505F6D46543D863F2D3F007D8960634841CB317F5EAC3D3A3E4561801CDFB269257FBAA6A60E7A0A1980C9BFD6053BF2EEF7414704C7160A051355CF48A0C0F6FFD683C453513F8212364775B7424D9315A920DCD5B140A8440EF7E5908D4061F580022399509C0ED416F945705A19FDF8E65C8802B67701FA1D15F06013990C7BB8D0D0404679713222924DB33BC659FE58F82A99BB1AC551426A13C2CF316664AC8037B41755F110F6441C7BC9446430D7BF917AFDB8FBEF84E895388A68763E0E16F89FF630BDE9732852B70A4A3AD8A29D2A4670757AA4202DE5D53E653848FB26C6031D07CD010501F0785D1B1D69BED49DC3B07265D51A15A7C432C3EA63A0B0D228B4F8AD4060DBB8D54B94BAC7F2179829C8D9F9CE4F7BFCCB472EDCBED73B0D18E3108156FE659CAA40B45016E0EFF20F81C29EADC8B638364FACA6FC85F98A9BAA9BB7E5261AEC6786C18487B14B77ED2B62B762D6B8B39AF5A870EACD236CC53C016158DD1E71382475657C512EDEC0977320F1BEC79D0CF39403975210DCEC3ED5B58F", + "signature": "0E27A9CBDF2D81A93D2B091B79F926B66598283ECDACC0D1F1FC71EEDF8A8CFF01741193BC4A5AD7E14CAE78A658DE7655C93D50F88FFC5E4FC993B7D936F7B7E3A7A0BC50C84190D300032369A74367D1E2165307DA61D4255CB55B12448838C0783F61210E9E8003814366A50DCF6F7F504AE587598FCD32D00A026723A34F040E5ED07F849A6884C1E96D6F15590BEC3E3134C48FEEC6AA56A746C218C7B40D5CBF994FE3DC3EDBCF546DC46907B64B3A438785544F9E33C78772F568B206B43DAF1315B0A6CFDB4797C127AF6F47F605763EB9FB0547976FC486ADDA2597CC86CB461A3B1A2C02D600039C2F50AF91BF47DD8FBD791155FBDBF4709825C2B5D302F5648CA842D6B9021938B6569DB7ACADE0E7A13661BE3C50C15AB3A4E82193BA5A342AC17A24263EC52B02857BB78C3B7122362C22FF1787DD9C3686DA382CD8BC5C70B2F16C8917AE820371D813D8367176DC993F72AEDD28181E57C8E0CFEEE2C81BA538655D888875E7F6831B1B5178F3C2D3FBEA81C12AB19E507F2F4ECDCD91D1CBA519816B87F16CC48D8132DB8F042057E21C635CC5FE3BB7D695CAAAE0A2D35591614E9FE2D1C47FBBFCA82EC92E05182D392011A48BBFA4788298AFA2F5ED2A4B2E933776AB1FDEB35C6EA224A69DF604A2979E826D00134AE1C13A7F2A17A0B3AC498804F0EA2D545CE3E37092D672277C4CD051B652332CFB8D1DD8ED703080032E4A7776A19828903A857C574A954A93EFEB26B0CA40A6780F331EE5AA78EA847EF4A624AA0B37D90BC47964B114E8F570BCEA25308CFC4E13F478861851E08E70F8188E147C1F17A769C868FB37A10638CE2D95F8490D2B4145C302993459474AF385794E4097D1E6B3B8BCF29480B25CDC9E8127C07F701A03452FC6953A16E864D6DF32B2D746E173EA181F2939AEE6354A940454F946E9450751864BC74DAE264FABAFD2449D7E51598BBA2D1816B3E912767C1DB51601DA9515DEAB9D34AD7E5F4072AE029613CD5975786FA16A7443F628AFD31B5570DAC44EEC0D41E9F2740502A2B2B6742472CE59E900DF6EB15A3B8D37D05EE0EB56F1558A2318D40C6B7AFDA5CE952344C8D27ED5E22FB57A5B6629D2B901BAB796ACCCE5CDA605B5B9D276F082F495D65EC4E96A962B4D373DE2799F5F4AFD748B9C2495440FFABD7C76AC29F0EF930FAC787873D0DC93158325649821D6F5BCE89C0F46EC9EB43406EF0F2F63F5A9CB90E542D0A3BBB219D2D174377D60D845677126DD80B62464ED3DEAEE110018B29D0354662E1BDB4BF07BCEB8DCCB73F631385617C9A9944B9E6BE8FFEC492847554B1DE4EF5514E5E8E968F69C98133AEF51A75E0FEF2C60A1CB5F1F8CA4855C5F6CCB4ECBB696189948973EAB694004BD998D0FFF5E0B5270C71244D57011835CA161E18928D1F03F515E5A271E46093F2D43052B9266373D06D040C3C735665941B9BA15C9ED03D0941894D521B3518C970C0ADDE281A863F1B09076C9E7B377CAA8D5A3813D7E9316B3E8DAA28268D53DB57D2A1E4A64758B548CDEEB8DABBBDB81740386412B2D3CDAAD98B0E90F98CF39860A11C3016FDCB87D8F83155EBB4623E3F57D1CE98B25FE024DA73449441416EBAE515FA4CB1139C6975BF953605FB1B5CF9FF952E674CEC3FBE66AEAFB1E5D3EF0E3AF3FF9FBBE2E9DF971E8D6AA5A79C0C3A4D8F4D18313EBE0E00DC7D5C913A879C448AE8D31CFF3901F14FA7D1C1C1517BBAADCFD2F6144B2FFFD3440620594CC5DE9B96B3F509BF13F98098187353094EC60D93A57EED58CD91701451C86A7D96ACF611A57F212E27D2EBE0335FE030E391DEDFC2CDE76AEA4643BAF0F4545BDFA7206E14D4146FD203F9E0ECEDEFFAC0363E210C4777017927A4871AC70725A3FA8F593BB9AEA1B048E07BB6BDD718B27F2D375B6690BBA1FA85FE48E8D85CA3B35ACD83B568B286D19CE7C5E0356FD18C203C91485E2B921ED491E59EA5A85796EEAB8208A75A57E0CBA190BD93721022C0303463DEB4D149044FA1E220CE7B253AD5564191E1CF998535050EEB66823EFC455AC058325F1AEBB3EF0FECEEEA8A9DF5022411E04FFA1AD7FC67692E76AB3E9474D461C815A77E0B08CA7FA5940C18BAAE2A7C93C7501138A7E071EC321B4BCC684AEC1546195261F2D07676E8E4F36AC2355D44C8412DCA71BB769AA2B459F285819CC9F19E53DCE686E24600344A32BAE91AB109F01DBDEE0A86AFBEDB1689900659388F2D57FE151AC876620A4B270DE0F9AF057A06FC9A746377F94FBAB3BEB63A96ECC1D26B055102BA7781F7EBC57F48D1221DFF5AB33F9B954F89B1EE348E4809219572CD379B833D690249F70C22D28036A82EEF543926922365643A92FCD478171AEF25B31CBB010164326E680CD247B85B1417992ADFB613BABC7B0B19707D9331BA1328C9677E4DEDD041D2259BB4A296C338130A397E003C34AABF3142DC4DAE8F862A9A9D7A5B8D39647AD00EFFCEDFA93C8831551A4C5FE1A6A32397F8ADE69557EF57C88D3A7EB14F4E43789148A31BD2E8A39F89BDC2E02DEB4DC2B337CA72AB3E00462A1ECC7D212EB18B25E88EB05897A3F29839F840909552229718B725F9FA2F23A4BB802BD9835CB4E765F422A10336BCB804EF6E5042ED3CB9F52EDEC95B0728B117736A0722AC389BEC0A0E593CA4196B857A7B89F23B219E48AD233481BAFD9691A35D929BED17CB12CCABC4BB101B8B413ACA50F2CAF472BEF9D3FABDE8DBDCC9531F8FE67FDDA1CA3E9B790CE4B0A0643A58B48862EA3D6FAE5972CFDB0EB6BDCC9EC1245BE418B2CFCDF3CCA609A132542E68805BB2987A7962E54D95F370F7AA9C869EEDF525E6DD9465A0A1B2B93C033CEE24C849FB41F0313A98FE766546E430AA5AC928741D19D39FFA404D070D401B5C26FF44DC9C7F928D51AE42E1FAC8AEDF8EB71BC96F05C5886E47F8970F071358B534D073380AA2037C42F69982E89B3B76755F7E5E1DF981370467B7E0ADDD97C69B21E37CA263F2BEE9CB46EBEAFE7C02629D31DC040187DC375C72040F5A43B35FBF0676417DFFA21F7BEEA23D0545D9C6FA337976F0E62E25647F7A377A965EF2C5B7EBB6D074308F93BABA96A9AAE838C16EE7DB31A64A4E3F6C416EB9925A3AB70757BACD418983A9D0E23FB8AD69083A98137D640B440A68594C65788968D3D3092B319DA8560E6748190D8A07B76F70D0E3F44F4557BC2B604A37059F0A544F184198C4C22108315DA78F45AA217AA485691CDC82AE5B06EB6D787EFD0A366DB7F1B2C2F404F50757E88A9ACB7C3CCD4DDE3ECF1F310121D2E304771727E9AA0A3B8D2D6F9051537396B7475808D95A1C00B233336383B5D5E65788082839CAFB7BACAEBF900000000000000000000000014243044" + } + ] + }, + { + "tgId": 2, + "testType": "AFT", + "parameterSet": "ML-DSA-44", + "deterministic": false, + "tests": [ + { + "tcId": 11, + "deferred": false, + "sk": "5DFB07A2044B931675C78943EAC3C4C57B07778AD9AF2E87C470B9CC2C8DA1E375BCB3BCD19E7BB983C96366CCEA141EAE2207755224C8C6C61F908989CFF2F62798A68645779515D474DDA61F3341424EDA24796027344E36941474819A58442B74BF5060B840944AEFDEA7A4CFFCB39DE207FD9E6AC62E6D0DB2B4512E202600B53001A92DE2420242127124B728943086DA2230008765CC22911B058203468AA0322640B484C3142D88148C94924923150ECA88091894688238002141288CB8800209495AB4119B2805E44230CA2480A4062AD392051C036A22364A924452E2482819836888C63141905000438E23876019438150326981C051120608020882C4A68103A5908CB60090146601B1081225481A881143386023262E14450D9C928CA2461294A60588B0110AB028A442099C82801A806159B08D40A66D12C90CD91868A3842C02B62501402CD8204D1B35301110496344318AB2704B2428A04608C9068108C5044AB23008150424A2659B884119362EE2B829D9126441A63022B78C93386993300AC8B68523B18D01380A59A00964126E880822DB00080C08129942441B006808132653A2405A342598908C00342D939448C8224CE24429E20028142240482824224906CAC80C4C12801BA5411106481B277220073124108E9C94911B378251282E11064201346E8C222524346A19472123B60951B2311834458CB8201C190A19B76D1897480982049C128A410846241331D04246C3168051102E5148045CC2641A108ED9866490246893B44594304AE3120C54049003314062924D5CC8108AB8615C046AC8B085930005C306691B348E03840C50002C8C96900832680B908C02862D1838091CB2211B48045C1086D8345143848843B26512B68D03014519B88D92264E12128852B26421092649380524110A2238322331204A2442C4A24420100DA1A85123868481388E02004A1CB7244C060A1C264ECC22484C922DC0202DA11689C3448219A76DC49010018289D84422D99820C0884588220C90369090A405D38221D0A628003325A2C26CD81071D19650C334088B942D6188041BC82DE230642028241A345010256A64368109C145E33080C3A68CE0B610C3348DD1061188200A0AC8212081309C14619BC25022158D80A04189244120934001A60908252EC1C685001762413032DC066D48880884C8305B968D42B44CD03488D004021815525226308C462820944C211800D0B2481B170A09304C44C204475EF23331FF6673E26E6A32F294BEFBD5964FED987A42A235FC5B16086145C0B8A823FBC14F1C8CD03FD6EEC495283E035C0DCAE52E68F329DE7ADFD64FEE0B116D4A14E15394B31DF88BCA10D1C906AA82287C117499E9D8C77D17A95CCC14AFF9C205D26480A570B5770B048199CF3F0E1B91AB394B1F65D47F9298D096CA25C099BC67F4334263E36BD9E66B998A07DC1E181E05386E968F1CB0AB1E9A67D5D3301120378224881F651759EC7DBF45781EF8A84DADAFE613D6016966BD8844B6A617ACA1EEF673B774CC807B36DD02DD45216686037F9AC0B12F5726F251C57243E2C188F5ECC097E0B989B58A5D804ABFD720255577668EE304D01C50FE8B6D906853CF7A494FB47991F181B7420E74199C82E71A824BF8C6131DF4D1856F11E7040770724DE72C815AC0443F2E77EC22A128DB18E1183EE79682C43024C907466C354B1C7B0E0EF09F16487BD8A99C3A0A9EDBF00F15A5EB1C50D42736DB0763BD56BDFA81099ADECEE84AEA069C065B670314B9E48C6675A3CC693957DA1D21BACED87002FFF56F253A3DFC79A3F03A3F2B10519ACBC91AF5F1985B5C87964EC8008A3A6E8502A5F169326EC19568CFA8E885554D6A681F00DD26B324F49DD24D8106DAE64D1173DFFE4FA6225E6C6D5EE359CFF435A080868949B2ED0CC73B4206688D90041ABD51F6B9292EB6F079401E6E5994FBF56B72824CB6C72B127177DD89CC2F98B0931C98CE5E890D957B98E1EADCB7FF22C531409E1C8059470149EC81EF16326BB04EE23BA3C103120DA665DE8DB0A0BB75EF5CDAF4EE476E550238CDC1ACDD71A634ABCEA55C90FFF8E0A787BD2136914F23D87558C5F6BAAC546C24B1410202B944310EC4C9C687853605C8AEC9F1EF6B6752D39A15BFA247EF89FC0699A11AE45A75E509D454E989F2606EAB10F842E4AD57C6E365489414054F62200F3A1EC762DC5C8EFA1988475DE8C3D58C2B71BA11987C0AC642083BAC76FB50788C268FEE7BE2599B3458092A8BCB1F31948FE482DF9A545B638594D67A4406915CCDC7555747C04E72A548AB8FEE876B2582613CCABDA96CF14AAAF6716B790BFE4D9232D90370D60BBC184BA33BCF778316E34B11838D8F71FEEAC042F035B076EAC1C262FA9C32BC8D69B138B351318ED1F3449595115236F4CA7CBA2BA9E103F0F509AB916E48B8AF039BDCD51CABFACADCEE8E4984F561F97D17CBF1DE9A7A7BDAF326E6D8AD90E95BAF1545D3E24669D1C5F428E07E2C7110FF43598093E6F928A034C686BAE75A567AE4F520B44DACB495E5B2C6439E2E678E7C054FF7601488C6AE4A053699735510F9DBC34CD76A1994C0FE7412C0CE9515BF603A8EB5FC8ABCAC9F1510447358605DA133FDDEBDF22269EE1D468E2EE821621D2784C46DA83002A62694FAB1EFEC3B8D6F1B2CCE2A4EC428354E39A4F45C9665C1B855A50915BC4D3BD01F7FBA9020CDBDC2C8E5C6B06F144E6BEA8A2444E10ACDB205F315717C86FCF1FD6BA6E3FC86E3BA566B8FBE029A030C8C69E57C15AE1312252B36FB51A1615E3746920C0B715C1DA4DB04C108ED5C448070C10E636D92C21E188E710E7C10211EC2CFD6387A9B5C9EE8823DDD400C9617EFB125BA84454F64A68E2BBAF1EDB34F925F1A732A2A2268194C8A87517578CF3CC597FD7743CBAE3D9CB6455445F41B92EEF49DC432106A48ABE947BF2B924984235205A1923BD7782D9A15B4D9D345D069F1384D39EA497EC0E77A07881D1FA3ACE9C3FD6B5DF6B2B9AA9ABEF406D95E81E568DFEA204CEEED42A4D37BA882980DB4C8C3432813E96B110E54E6CD110A01364178C57D00C68DE77B4CE635578F56A9735AEF93F0D816E3448AA0A9F19C2E02D13C66DDE535FE81778DC246640323CC37226068CC7F79E86BD0EE1C6AC33CEB5195FAE42817944922696498828B689F6935F9BF3322A4320F4C26E48DDFAEBDF44D01AFA1FA3ECED3B05D02DB3BB423B85597B51F2564A75D4A8C90D4B685203209372600D54D985ACF293B0EAF69887818ADD1E1B7C5D7B75FFEB564E0680B4F467BDE0B117A4210860960B5E0221728687AE9EBBC6BD5954CE0AE57B145FFC27EB6A0D38E4616CEBE76CE595BA4961E9F80F0067ECD6E27B87D26B660A3AB52C1379ADD46F5B93975AA19F3E4A8954B253F0B4413F582106803D50F99B5B28B85772E783EEE216EAD2DCF9562941C50ABC5FA8E24B61486468AAA20DF15D172F6AC03AFDFCD5381BADB078B8EBB70915704B988E58F45D3D63112A5C128C649900F1D6966E398567DE348ACC0DEE42B8801194E99BB1AAF025A91E32CE6564D0510B910F22A27DECF9D2E", + "message": "B1344915CCD693416B37FEBD8DC7C7DB9F253E9DF53CEC514923AAA2676FBFA4CC04FC68F9E32F9E864C6895DB37E9FFEB80F0F6B86CB6AD9C42F8FC75198DD3CCDAF577C7B35B8F1BF60AABEA899442201FBBF4428C7EC17BC31B54724B9590F7531E6F790A1FA7743283372D3171B8966B470AAA8526EB4A6E81E65AD0C29F2D37DD5B412BAE682A66796877C82FFDA9762434EAC2C7D4AF609B2772490DEE9BFB005D2F1A2EBBA032CD7159D54BE596F33068BE5D9A2D940C7670E64E9AF7D7D33EC3AEC6F1D9DEE39284F05CE025D181760D40E5C2D9BEAE2420F40D9F32B7BDCD3AFB1C660D01714D813758DBB82C6B7E858052B5A50E39E015D3F24A2C64C9DDCC150D904F07F65FF68AD0129EC3F8123F3A03FC958AE2478C6C6E036167D85149F79FB03FAAB9897CE73F8855C54C83D753B104B513D56BC64C3B08917347351326D8EB47CF66F13FB90F6AF5A894C7750077A89CEB7722E2E680A59BF8438C523531EA8CC2834FFC4EF02D35B85146F2D601D500996A441064ADCA1F623F2FE7452247EF869D76D578420730888690B1A008DA282AD1757D2171293859C73F5520B5BB4803E7FAB02900D20FE765818EE624E7A194509D016B4BD7814EA0D54A51EE950A1476D587AA6F78C8D2E0C8F8F278D82E119044B6BFD0BED86FA420A2C8A4EFB05D7306BE52F932D8065DD1292346256E429DEE419EF37D1B352881DC477F25A40AEB3E17E61BCC00D2E2A93DECF300F0816821ED49F99B9B8BEDD91EFA04BBB09ABD1D2436A7D6648A383A3A8F09080E467BE10330BF62271074BEBD7F56390D1D3947F402476B626B52ACAB21AC104AAB59753311D9E9E2B2206BA10942B637E45CE69F54B467BCAEF3DC1AA215477B15C800358E1D6904D89CA96A031A55486C4FC168272613AB8E03507BDDC27E5C8A6FBB5F8B2286A5C50EC56860F6BFFF6EBADC2171D2EBD1278C5814C32E139E040961C319C3034870333B12F73B38E71814A9F1608365EB32D5238F6BF7D80021BDA398DED71317AB3CA4D7BE1DA74A1BC40C9B2E345BA7A23F9B2DDBAF85140AF9309E8653AC24AFD825BC2A072BCD02FE3EF00BE3F9515C29EB8AFBC3EFD1F9CFDFE9EBA94959B5177E2886B8D18DCA97F0CB807EE3EAE31B48CFAC613C2E00AB74FB95F664F3CABF6EEFCDDD6DA5F898EC38F2F07D6DCB75E0509D131924074C05F45DCA25B7CFE2BCFEECAF5FC36CE6E3C585437B069FD2C6BBAD33D686BD5B9E2CA0D98BDC5E717B6DF71D4091308E84739AD67FA679A6CEE9A683284B4FB31B2C408F52F0597D9C04EAF4AC6DBB6C3FD67F2539D887DFBCF3CAE459FA766661A48BFCFD6F640399D3AF0786359998CEFF7E9EB1B057A6293DFFB7F3F2514B0B702946068A6BBD7530D6917FB11DBBAABED7AA4681D78AEA9186692DDA3470652EB8A3F14456A5AAC420883B4237B0A72D912763B67AC4131A8A5D2F168296B912D3B661C4E83CE63A61C045EBA575EEB67FB070ED8239E51A67D9803CE00B856674E0B7266626DD0215E5EF5FDE7BF40B99102108FC2DF28BDCC8EAC63EFB20501F2466998088C7A0B96D1B75C4C2E252A0BF38015CA58ADA7938AE2EC7966F305BB421C0CD95CAD2127DAD87086CC38BF6B15DAD2C7C0441E5342E4B5AD91E66F423E2884DD903FE6C647D61E6700EA8830807E6FD64543E3C6E9AD193373690DE94F716154794FE975B1180BA40AF7F05C1829169FDFBEC3AF7CFE1D79B597EE438A296EF146A059971E3F9508E350B50716DECB51BC8802AE62A7F4C2E6F7B54620EF04C00F072AE37AC327E26D365761C104617AEE0F328EE97E086183D46A3621F23F3AC2760B8859A960EF16FC1C6B1978A7412DD7385029C7361A8F749CEBA23EDE79A170EA68459F52166F5C561F8887E620C00C64F06BD0ABBCDE5117ABCFD03B6D1BA4F30FA9675D82D7A430D584146BA7206CBBDD9BEA1EA47083DF932239CAA021DA33E43F168D8BE9F0EA8A852C40ADE439D58A805D474F89321626E33783C23EB601C4C25FE0F5E73C3AD339A7D696BAB2CAA5FBF96623AF0634100C74C814D424325BC30B60BEEFC183E680E645CD4222ABAB5C67E67111C4C0330EC0C77B22BBC98F7528C9566E171DD26A77F87F3942E0D3EFEAD0ADA3B7749C51DED5FDA3FE6E79658F1023068B962D058A2896512201E4CE7B6981252F0E855BCFE1F444236C930E49A13B37AF4F597C05DCA23CC05C43C32A2110817CB306BA47D245E50222E23C6556BD75D50EEF8BEB0DE835C8DD2E15C706670598F865071710469ECB3479EE026B19FE621AC99126B979E1BA1DDA8E6111297C10E4A77F552F809E90163564EFA243936B9F26E07287FA4077CA2697BED6A4F0A95990560E758D990B4C1920F9E1ABE0B589650611C2D5A13AA5F4E2B88BEAB9372F468B83091CD0A538A3582934F66CACDF23998FEC2FEFE5135F1B5622D1AE943255E05E48BFE912F4F241B2BAC499C14B058A3A8EEB9D1FA4D442E23FC5977A5602EDCEB7B7B2695E187B794F84B966315B1BBA5C04A72024A805FB19473B706B8137642ADB1C66CFD64F260BB1B7AADF6C296B35F30B9D7708A9D41E723FAD4E872AF73F88C26AB651BD57A21E28CE8C247D58E479F7968876FCED35D2B87D2DF144347033DF4CB50DE52D89841463F5DFB6D6FF6D9E82BBAB3B1EC58778AB8F36DBC6822EAE32FB6CB6730CB331C395C274AE7E37B409B7C6632E76DAA97B80F1E0CB47AA366A8E350EA36746592EC9B1E97F02F99D60021370B8993C680A102DC965D20B757F4177A81BA7B61D288EFC5ADED4C9A94A57B2C6BD2977E23640A669847EE81B1490BE38AC43E522C8D09A207B62A8B079A2484DED10063D7A13FBF0CA8EEDC2BF67BD8785335B8295AFE6B356E206224170E87231A772D218437BF7D68AC2AF93F1127184FA21521479E56FF22E80F61BC28B8D2E71B3D1D94281B695600C8B0FD8E1D7E811F4CCFE16E3F5795C24AA0A0167E305C28875C8FA9389B72F79086F6ECC16C88B0783A5815FB6F77CDC7CCC38D60E787BE9CBFFAA62EF959A5E5DCDEB6255C8E0D2E01FE05EFF9E78102BEA2914057D36E3D1B48507AB6B17640470FE3F17A8B6A5E04E53456C5D9E50F745DE06F9AEDF4BFCF31B0C6ED12133654CBC8DEF7F6609E122C2E4C933E6FCB0F3D8CCAE8CA0B10EDDAE8DB297C8B3231C89434A5F54D0128C83AA6FDE29AB70CDA43784545FEE9FF6ED444F888664DD22B2E2DF57CA653B6D210E6B40B7FC21FE06390CA5D5E60F58AB14C4903D438AEEFB17CA4B998706A0ED6A4A6F474B1BA1D48CCC1143C84A8D2E78DEC11618C76B6DA28BC39DF68AD24A407E10733DD189D5DAA904BEF88186EB6832145940F15B8ACD9D18D4F17C8D917B09D54F25F5609D3802077442390ABB60B51A741C5D4425BD46789E6EC1E7D22D56E7F34CE7A072B630A6951718C1363B8796D94EAAF8630D2226C67826CDEEA71E8D136F3642F79E692F04B05147E40CE0C53CA08EF0AA6A57399FDF3EDBD54566E66EFCCE16F0C447684F5552BA36B2060543FC13558D8D89E18637073EF6A874677A97F9FA0234B140061C7E344BED60971E358449ACD17E58E6D05BB2144D74BD89AE97A759143AD845B0270BE670B1E1E92B8C7B65FE16023F530E4D0CF7003D1854A50DCF49C29AB0EA47B2E3BDBBF52D58A9147A9D123EBC56F11BBEEBB29D731AB99275EF3A923FF708783CC269206ECD38CF947347D1E71AFCF9DBF291B95274855CEE2AC256183D97B26EF949A950CD1E40A51501F867A7BD383552DFC7B97771767BB9FD7D1DDDD4967BBF79A453324CABCA5B20D3FB0106DB97D033FCD40371E8ADACDBAD78D89BD5E90CF97E835518794FA3DB2B501F2357577655B9A3CDA3652DFCF96BAB9C5F957670E32E586E51FD89D7BA87689FD597088739D87E1246DC2B51ECD54292510A3B43CB25A62BDE914EC3CBFA99DEC70AC23C0DFC969AD941A6994A370F90B155D254563FAAA7D30673C0634753FD657588EC6603F8235E917365DD89325251B21B2FF80F544FE7384FF62FE52C4CA774128C895152CC75CA63BA8F81E0130C93B59F940B718802124DB8D07DFDC24BF2F7BD9C4EF61741AF2B6987566224F110641DB7783FAF31BECB8F78947BA123FB00E1B6D13360B16D07C3AAA336DDA1B65D4C2F21BD5CD4BE9EDFAFA7845972D60CCE3403EB5E5C833F64C5145DC08E7B36FCFDEE8730B944F5A23F9FF3F0D1DCE80863B558D8A35B2AA6527691DA50CE6FA39856265ADE60838CEC9EA9873991DB56FEAE8EEE2ECF43244965A13CC1D230E9172D82AD23D6A6E2A377A7F67F640BF3A363BC81A786D12B035A3185533704848528FB45958EBAAB303674FFFA568E7AEAF463D666B6021263183BEE81E7292877924CFDEEF6F8173A1347B99944333F48B36C8C5F8C16D226DA3C9DA5F4CE77F00E442D85C73E5780C3628D9838FCAFA5D1D3405F1936CBCFD2C52D4E88DA9C90DFF285E3E9112C03CBA58647E6B4EC077B1670816F57E2942816A6F342132649AA644D14F41ABC5264AFA70BCAE3D679B86F51AF2447052D078A0EA56390B372A1513BCD2EA466DCB5A4D86474FA1E26BC0A83F585C79AD6217BC96AF771F74D142BF5E91A92844C54E766BF2D3698C0E4F6176ADDC79E974A466FB2E0CBB42C53F59B0DCB032CD37561BD246ED52C812EAA36BB9E5B32AF39B0FC3775F9AE120BC59449B7B77B1BA1A5B60066C858368DD5AC8EEDCFE1F83F52C5362EDE893B7223ECB70BAA66DB29147B80437201FEF71B05FF251035F88CAFF42E82A4302D36098268B74F4183D4D19F13B87E98337157DA5EFBBF34F48CA4065D3E3BACC83833FEEBA57346D169F1BE6A04C29C82FD225A3F7C685124F537EC0E10AB85834BA3E654F19555CB9746B74CE43A2C78B21708C3BEF87C1E88F0810B4EDE18114E92A4313B4EAA05F60937E876DA2576332AEC38CCD425EFD511A39B9B4BD4CF3F2E2709A05F939E5FC597D4E851202C9C2C5713AD573F75AC5490DEECF9DB8DEE20399706B1929A4E89900C49C24465E0809566D9C2EF78C52DBB42F9E227EFD1E1A72CB710BD219330E69CC0049367978AB114D9AD7F955CF0B7B3D325CB35165000ED29DBE0A1956F1459583C697CD19E78B5174E4FD2CEC108A7C24280A78A3EC9397164F6003FD85319804E5655A879F663DD4563EF9982521FEC2079E8889497BE9201F6D7F2460A8B2DD96510E0E4C83C3B193C11FD6B4B684CE8563A5380F2E55F474A60B6317D0967615AD4FA9F08325ADD797B79E6F5DC72AD197F5F61EC88BE5FBFF9272319A494B608F347CE155667A59C3009A1450F306193CFE611CF705492A30FF56FE7F71D732CCEF6364E166CFF812ED2311B516FA5690F2A2727B1850F2985D48255E8C47E711502A4B4A970BDF70DC3447F8E2887824B58AC758E883F73BADFCED4640D546351BF33E8F1E0B1BB9FB5AFF0F8BA0954A8E6533D37C03048EBA6A55B3C5DACBDC44D39877D3078AE95E445BED12B1A503AFB2200CB18B08B46A1196A9F57AFD564811C030A445FCAE72E55E85B76FA050134B2EC23113ED04043DBCD0B6FCCEBDC9135CB202B84FDD74511F9E8F0CF226E14CA5C438C76AA5C3C2E9F32271009183EE92A995819DB90F66899BB9B0C7ED31DF41B68E52AC5BBDF2339F715E43FEEDD94F57F9230523033417E4222797F7625B526670EE6BD3468CCD9BA4A1ED264AACC250A82A488346B2A5F926F2E78A8ED8405F858EABB029F78142A74BD5A82D3DD70AB126CFA3BAD7F51B9E95CBC8CE75E77A4A1B6321B7747778CD035B3BCD448EF1BBB6FF75528A7AE9AF6224A16F4F450387A3EDBC2E92C0B19C222E35C1A57EC3363B1814786E1D37D792B37826139AFB381DE04C07C42CD3CA78E470C2527C63DB4BB40A4B7D2067F0F4805B658B298092F0873D095A0EEA45639299D60D2B58EE19034F942DECBF5AE9A616AF72375C12BB7DEDAA6A7DDF9A4837373D7B51960B30CE9CE73B3C10DE32A78639A9337D9BCF1527A43688BDB6EB8BD03DCAF10270DFC0E2F0D22C27E32224332734CA261974022F7EC176CB12BE6F13621F320365CFBB03D04CF29EFE93E91B029B7B26FFEEF06FCE57D12BE3902EE2712ABACC3D27CEA35ACA1509E4D0864FEC5A5B41A0E03E1DEC6F2A337215CDE555D66F84E3D6755DDC1C073D0CDCDEF88A4440B17684B8E0AF9DA2B284AABF610821E5C2C911942D0BD1C659C1EEBA8E21AFDE3277D5073B9839957703802FA276C82CC66A00A86977B8877DC051194514A633B34D362934E850C2717A0BE5924E86AADA33CF3454632C68A10AEF8B5BAA1083E9137D2920A25F969F540B95DF59916C4CACC455988F46317756CC937EF0177C0FEB3F23BBD3569E8967C49B95A3BF6D9D6D7C7227206E283739FC7741E9FE64EFA0389FC72FDAC81FEB7507B87E6B73CE0E7C7C54061D488A0653959B758AFF6F7D1900178D7C1AEAD0794568F92F8ACE98EDCCE86DE108A0502C4349C4999831DE00E808390BBBDB65EA360FBE98B74A9C59340EBBDD6F6521392348577FD407890301B0792728CCFB88C5DD472ADA73759BC999A02134DFB1622F61D8B7632AC77E3A980B2CE566F3D530F0BC21C7519BFB00BBAA9C85C39B0CDC5F8D1BA12B7882FE0F7C756E7556743525E5D0EC8EC1BD7D7AE3DCADC68DB60D7AA13CDB29FA15C0A9AF890F1875E39758621279A9877D9C69449C41392CAD988B8DE458EECD98385F79730B5E26C1162415D97326419B5FF92AA8C13374391DBBE736D98C07AD32D638BB44E677C71105CFB572496880C167715F9BFF6E711ABE5A832538C7E6DA8822DCA60302D159C6A82FA48FF8773E0C6FA173E13555B2DFBF47B7D08DBA3574446BC0A78D3008E441D1552150D9061254B2F3FC5A1EF3E38433340BB59A97FD51F468FE8A92BF629DCD0029393712F3536D6B24B88668AD6A4B3A4C93A6B141FA8E5863CD5980BFD7AB83C3CC5D2FBE80C7B167DC928CA95736580A52960E2090CD8768F593BB04D448B64530C0E3C2568CE3A2C6420F81F74DF6885D55078EF1B383B020854A636A78A9EC1384F74EBEB65F5A25FFD4147DA7EE40F6257C7E34CAC9270EA278B6E608A19B568D29E58DECADDAD33C59BADB9252993B316B0B1300793D69853A6B903396", + "rnd": "083457D40E250488A60E7634A01D430A60E8572BA88AEDC5544918813713A0B1", + "signature": "63A82320D4CE09C47AD127C5BB7F6C2DFF1529CDAF9F7456FFC2C6ED905117DCAD8C087AC0D89E0CE961C094FA9C2EDE279C65E699D1D17EA695988FA1C4983F7E1F18862AFEB2EC9D0F5B0C11B2AA0BDE957C40A15BFF97D7CBCF4E59DAE9D5A3C9F87DDDA5B9069D82CC1810208092BCBA1C4373F2A83E1915809E81D8D206EA78103F68663DBEB179B02883CDD333EEFE6D023917C6F2A46E5A5C4514F57DCA7B624AF4E7717BD71B5126E6DE2DC96524302C0804D7BE3ADA64AF116FC6E738EFA6E65E8790B40EB1B48364D215EFD61F7A44753A95506E52C99CE9B456DC938592F135EC501B3BCF82DA69A1DD44E8B3C1CB8DD513D0F3142C80822C31BF752014399F8179760FB67DB6581CF3E6935A9BE18B92C2DBF189AA4667FA804572AAB4E25EE9D1A7A0D7055CC6C76D1D663D350CB71AFAB1DBD0CB3A8BB71B0360A0A4DAD0E23A1EB5E459686A02946605600864B4EE0F3ACEFD407B6FF58D1EFF0C75AFC141C6241DF37602486BBA58BCBBFED351C268214B204EAF8A0C747F5FB7AA43FC5A77A181CDBAE131871FA81F76306CE084CD144ADB67FD658C35C0916C2BCF5B892958429B65DB347DD831C9B80D07D194606365DCB370484637184D5DE0AC77D09EE1D9B22D09D6F894967B43D97636E624A44AFF12FE3095D7CBA9A03ACAFC5257B82080F2D8AE3E18FC0DE09D017B03AD6BEEA4EC3840AC8542F8CF93108F8CFEF82264FCDD2CDD86975B3F8FDF1F582208268A76E6C9FEDF42908D5278A2BFBD3FD5D5DBAFDD5E2C2B9F2EDCC1C452963849CB34EC51008D1BF6DA50A0D19D82345B788C0540E17B25FFDCE8D4453BBE751EDA96A44C75FDD90081857DC0F8262A307B34CBECD1565869A314D64C09DC9D4A8026522FDFE4CB5B8B1105DAE0DB66C85BB4321DBE7684EB6B6F8587D8320C6DB38DEDD61896ED51AB0C7F428F19D255C6B0FDF58951E5CDB1969CD9A7934EFDB9C82E1E8D2A59C9F79DF1AA93E5071E3FAC7319FF68878CF249DCBDCD104616CCC1C1FBD785569F558710441B31CAE3167A4CD7DDD18626C54362962032E6B7A276056196FC22967E907C320A7AF58CE3F501C4CD318A707504F1C259E507A0D47D258E2F38E26A5341347A06B58BB0BF21DEE65F556AD488A736D4C65C82C673C060D7A6A0775CF8C39AA131FD64DBB17B72704B7D1D24BC5F84083BF8A647EBEDCFDDA09114267D77CFBF399BD92F3B2AA72BBCF7DE9D69BF90A4DE2CF824927DE2B8BDF46B109ED60851C59C448ECB443F00263C9C25F46274D17C294CEBF2537D8FEABD78EEBCBA7264A5B94508E0BF62EFC21E06E1E2FB1444C5AB6F847F522F8ABEED046D6DDCFFBCB8C81FD05D4D7F2E1BC99BEAF8C1AFE3E05B3690FEE4AA375A3DCB77577CCC6E3EBE8A987C6D7E896073C0CC0C482546B539B4FDF04EED8E87F85B00BE43A60B217E96883B91D7881AA0DD3EBF5B0D08D0854ED4278FC902E060EA16FBC254A508C86F7AE75493B8DDA086E9C1B217F5C91197836688CD2D0BB8E552D1137AA7EBD5D560538E9BB6B41D0690B06C66D1575B861C8A7D3A884CC9881AC3001F300DF34762798589F9EE5C92436153D8C732559B333D698F3EC5820E8AA5F2E5A769C2B47AFA275FE474AF8137C7019AF2E60CA75EDBE48F81A651CE6BABD3374C0772A8AC3677B10F547717C96750DA448BD9C7938C66CD6FB75D732DAC831ADCE9176D94856E1BF60838D09E6323A27B1609F9C121F498D2BB685818A00DE7BA6B2847C516149F356ECEF04F34EA483546FEEB12EA4077620430C39DBF47C05EED5ED587FFF592217CA95A2C3D1E6F6FF9FF209F8B30A99D56A3977A3317490B2B001F43CD8DDD1D8FC16A3FA9B4315462845B995D2AB76EA539C7F04C316C71D600E1AC4FD5C8C6343BC8055F1700B40EA2F1ABE94BE006013AA261F0720AB799D0FC6DB5E9A4C3C5A7F82D70D28E410DD164E3E461A46E81FBDCB810848BCEE06F883325646E1E2A693FA5DA7C25EB21C4EAB87DC787A2677CEB6A26E106FE78E118FF54713E00597BFA528C2AED069A126DE3746F0665E17580630F702FABC0F1CD7F57AA71F638D8AF37D3D9E0A7E9055DA3DF86483F25DEBA18CEF699EB8770C78584798AD8028BADC59D2AF9AEAE37EC939116105F9F64EF8278C64DED3FD433A7B8820916BEDC6B7A75698ADED3FDE88675428303573070A5A3851F9F21EAC780FA8AA4023E3911487D852A5377435A5FFF9C604B5D95B0968AE0ECF4431B103FA6BA71C4DC8173A2DE1F79DDB60D2D0C8E5655D09444291692992D99FC48F2160EC0ACE4C49207BBB76D7F2A85E18102B95A514588F59F162D33CED6180703EDC36C8B339488810D2EAE9625CEE383271C7172EED6B5486960E8991874B01353593D7070BDEB7A9F9229AB770EEB46378D57D956DF7A8640040298F700F4415BDD3A9615A465DB01282212CF1AEC4B0B8CB3B17E5EFA286C6C045B439C749FE1D45075D8E7A00FBE8448FCACAA153D69709D9FF2B97CDB26C0C379287CE64861ADD789D0C8939A1421B085D6234CE1A749DE3DCBE8E0615CB3BCDC6A81A5C49D9285745F1CA8A0641E32688341933482183E245C1F9CD28028C38A23181A445AA6EACCE20606E6F7F1DF706883CDA52F3F2B68DE26DD3771E950032CC7200C2023C82496508282CD3BC47FECE5D97CA1CE35744D03D7A428B7AF12B0CB8E657C0130F8A3A254976EC8F7DCCF3ABF31F4B0B3F7126FFC4877F3D1A066D26A232FA9992161225411ED7DDB93C35C6A377F30CF22AA392D5C4FEE4F73C9EF6ED3A0279714523B1918651E9B0FFA550F161053EE7801397B4C1849987C179E763ECC60A4E4C536B7E2663E4C726714B02EC3169E8407BA592B0EB846F3692DD44651EE084721CAC0FE1CCC302707EFE24664E05BDC69C83904ACB8CF97121C7E5C6DB27EA28E77BCDA55D2BCC1C5FCC552AB83BCE4238CA18062C2D23A8B800C8209C3A4CDDAF11616578A845566FC289A8E3C88F554C4926071DA89326BEB259A0E1F6D844EBF7B281F9FC3743A65499E7394634818E133FAC664FA0C88F101CEC3FED8792950BF6E4974849E1EBD27691BF5519B702E1AA4B3DBADAB5DFA34FB0ED9D4A9DF4B6B63CA7165E2A90827408C482D9DBC972468584F42376004E78BE067009E43304BEDC107A4E2A89CAF185C9BB7E9FD2CB92AEF363BD796F3604EDC08A7C545B83702D3CF808852103E013BFEA161AF250BCC72771D0C484DD55541723A210D683B998CDBAF3D9A5E71786F1CF47B862251B5163360879AC0202D334951545C5F71767C8F96A9D6E4F21F28434D7E96BBC5E3EFF3FD020C17233E7F99B0E3E8F5000000000000000000000000000000000000000000000000000000000000000000000617232E" + }, + { + "tcId": 12, + "deferred": false, + "sk": "5C3F57C82F4018917A01B668F23208C4BEEE1FF17B97DDAE5BA686EDF4086F541B3E7A058D88470895EB66727B848E72C2FE05AE7A5D4338647A6E0A09AE61F28B5D75DA59AAEBA7CBCFB6A17103BC3EF40CFFC9A66D85F1AA21D5CE22EEADDBDBEC46D482F2683C4A44AFC1E5C6B0E046D9167FA67376811D1475DBB28780D41A16089C467221404AC106925A026C52348C9B942194404148984141308513290ADC0451C0C0285B4469E1B64812110D82260D21096D13030A11197218970503144953900548464408292EC23606CAC2309A00461B428091264D40020E1B986520374E6018609CA04C4B248198368EE1C4252017065CA801C0903050A62D03150C1C808DD84652CC022A1136490882254A486DE3B42D83102403297123222681264A1937020B212454304982302CD1206C12126D1AA085A482401A415183920423870860048003114952222D0189280C42814B460A143288623489A2264C0BB98D0124489B0802130752114662233151830612139390241864CB10819C48290B358D00A32124842C11164EC3266A44C04C0147704A3030109011592440E4426E11922CD31625404660E2B611C2C000E4A4510A39448AC865C39005C0A285D4804C2422490B106E18387261A23022228E233042DC1080184046A2180218B009CAB82C030129D12868D1B85080A4680C312C833080034190A026721316040B4042DC0646D43880C8320010446A21C244C190081AA72548B68109000622A870C498311C110013266941941042B081DC266D84C80952A62C0A29664B02224C124223154A1A284D1C0666A1445290B245C30871431489191070A14200128510E2244253226892C86424B46842320DD1084550326D84440A2341288B36060B28705082000914415126641AB46D9C800041C28981105111B26412804820384A99188C1BB8850847401024251AA651D1C02944406904850454C691CCB605810220DC98690AC791C4C26D13A2890A2905CA400122C551040542028008641620581866D8000619B60861A831090390191711A2A6501BB748E1886112805062B409503204E40262DC180D9920311B3370498430C8242D14880982B62CA2384C028010C492415CA800E1B665032132DA842994446619228A58B210234440910231198369D9940D94422023418D93380E9836669AA2911CA90910026A58046C014508530810192611910228CB28200AC004124100C22852439690A3A48988B0649CC86C4434852E62EDCB4AEBD86940B877BCCBC6FBF83AA99A4C6BF23931786EDFB2C9938387EFC6D4F381053F4D6461C83F85E8E349D4A2411BCD5ED5C0E571238ABF9F7AC812CD9BE92D7347A8F9DF636D512B1D92D90453800C67EAD0E95A26515873E392E3D88390A708ED9E85C103AE695585697764CDFAE7B0A3E428B35BB8BCD09897DC00EFF423AD004239252B2AD7F99F8D0668CB25614E8693DE853B58832F2CC1610B34A395B5132AF970CE61B1652A4AD4EC2D6F50B494BE61F9F69804BAF1EDD421082E45478C3EB519D64A36CED075C9ABC6284A1669EBAC62269EFC414CADC894EE3BC547918D9E09F5D975DC44FF1D424AEDD9A542BAF18F2314785877C0D77BFB8B8571BE1F32FD55419243AC32827956E148C93EA58FF3367946A8624767247518CFA8B91D8E51CAD3F3CA037FD871CEBC048729D068FB28EAA0F54BA39AC7BC048687FE90DF0AB0C46CBD86F324CB9389BAB145992D501BA22B5B52BACEA72F5540053EF4AD4FE66420923BF42D4494F91744864020301CA0A81D007AA41B0D4312D3EEE795235ED6170361688997A8C7BE6B14C6EA8573F01FE220B7A324E345D4C0FCF47C5FAD14C9A6B3D4CE035BC8388D67D7EA8E41D73484A5FE705FB740F8DBA473B3C3CC71FA1C7B7D3ABEBB953CDC85627BE0C65B9CE9E1AF14CB734CCA3D754ECA01D2AC793F440E3CB1A107B8BD5A79C7A62C9551EFA3824C2228BCF7F5AECAAAADFD492FD881077BE153887FAF77A9A599260375896CEEEE679FE57D6F2EFE84E5C6475B5B5E89B68585EF297CC9225DA3AC6749A285D5ECB08DB79F737111CF3E12314AC4B2F58588CF18393B69A70C877DA7B7F61D06E21A4FD4175D7C4EABC45DF964CC9A85134F44C420DFD22352518074200F726623E1A6355D42A8AA8A3055F2DA37675C1BF0F0DC723C46AFC92B0C709C87BE871AC6A77D69991C594E858289C1D07AAF2D3D9D2E26880BFA9BE0BAC7D2ADCEC92E6F6A0EDD0B207EAC4B50351FF8784E618D78C01A2E2EA07C0739411BDA0AD6E1E1138E6438E15A77F9B1EF3C1531A647FC2239519D235536003EC161C590E2AE8572A5FB0514A305DCF31D4981878D1E98491E4792B27F574168B1837DC65BB54F6EED043B0FD5BC9F2B88A2DC4994F7AB6B9D2B49CA9DA86B4219355A8F48357139CBCB0A49E7F7B52317C5B41C28EA6A19378D74328E7B707E1E28917D61B13A4B640B4A4595260B81BA7484BA4BD7908F98066F9A73E99D6A69E156F2781B0DE8C0034C42331ED63AA2089197F713D817DBCBE3303C3997210B71DFF9010E1756DFD058A0F8E6A8441898D7D2D0D5F6F29249CAF9A0238BF830F07FA7F7D2358A3B16F6F8802069E9AF743EC8155CDBFABBB87ECB09CFB2532E64BBC298926F658EB1BD96956062ACA01FEFAA0B3739952FE8C48DA6557ADD22197F0C75B5A1163BC4EF95647FAD212744366756F6ECA10BA522E593C2CC9A531AB0CD148569ACE95E4504BADD4D8F3B640499556E5859317018F8CAA0A1E018D2762498504F03A0AFFE5E86907F66D0618EB084A5B95AA165C80369EA445C58CF1918D2195052F549683B1E95DEFAC344ED5DB485305748861356A5C8DD25434D2C44808776B63A86E10C8D6F459FD05951649945A933A29A0B4ACACD4E42C75D8D86D7A4030DB5CFF889C21B0D5D170DB897E52F7C3328FF54EC3013E4FC76351E0A1189DAEBA1B34E1FA713C2F8FF2D6534F0F9E6D6CDB3A2DB4C53DC74FC0A9EEE1500148360E25F6AA0AAB245EFE013FE2B535F6584612DEE494940E6171D1EE563780F5A8A137B034B52FF2B0AF8EBA81D98E6ADB4403057BA7CFA0DFB8EED0004F2129218A28F0498047B4066A483A80CD12CF63DE39F654E423E991684BC8B21A27A7560DA41E36684A52A4C15CBFD9A4274A6085AF2FE3F300B6AE9D47E258B59A9C0D84CF0F8B9408D29336F5275416D5BF56762FCF43AA19F3D49CA0BEC7D13764E1927C81165FF418EFFD1BDC79F634357C9E1010BDA4C2FD9C00CB50D63DE59A5DB9300BFDC1750D93FAD1EFCFD80DEA1BFCF6E166BF1BB5EAAC18850BC0A87362816841E99F200CF3E1F148AD952D19EC6EAD27506EB29A30F1B293E72C854A36F5772660D7212EED5D3C03BC8E2AA210735514B939396DB79A920B2F3A15B1944FBCEFCAE7BCA0B448BBD0B78A5F9683F7E3E204C48709B55AE14F85C5B329F944705683D7398646572B9BD6FF9AE15F35472B1CEA6462AF95FFCBADF998BA83CC7A5B33FB7ACCBE87F7E5DE5D2DF2014B6969ED60CD18375D8118E19EF52265876286DD9F30280AF2802B5E9CAB9F57F6279013E030712551E1BD5E7", + "message": "C21140CE91893B598D56C376B32C1924F76C22CDBCA81116A4CC916BAF80503E35367E65A4BEBB05799E0FFFB3E1A73E0198AD5233B5A94076E48C4D8EB4F89C5677575A6A1ABCA4BF558265E988FB30192020A71DA7B68D91E98061627A5BFC04F888AF12C15E2140CBFAE9423A2AF746EFC8EAB0FC95DF266A1CC93CFD6FB93FC5A0137F411FE10BD1A4B386DDF7ADB3BC5ED2349BC1A40C08F031A369F3E47E80C63AE7DDB4A5C1FC8572A1A1E7179BBF332FE2EE3A060087F033E6E1DE904445556EF4936CE6EC41C16FA1C12CFC3CD71381FA372AD4EFBBCE53C3A0E6826B2634CD9E24EFAF402D660CC229C2CEDBB4D4CD644AB77812F492E443AC14524D8398649008B110A578CCB1AF3DC881A01100D8F23406048BC4D54F3494270DDF154A8BAB62DFDC8DC6016B4F423CE843C7786AB9F468970E43C66FE43ED6A7E31BF3EC250C49197CBACC5ACC15485133B98D0B3B0B28D3026F97F47B5B965921CE81979470A2D1D3B476E2C76A07A63842CB7A97F87564B2885DC7DD1CCDF29C94C5D3BB8094FF342503B170DA5B5F377510494E33EEE6A13C18286FD6F7D765E6BD23C93F1B498B19AD86DE17A1CAB0CD9ED5F333D959B78F13D7CA1F18E1ABE2C811A50B2CD54A047C278CA575B513E24888B7A3B92DF8632FF615654D08403A2C53CCB5ADF8555678AC61D1BCE685283C1828581CD73694C75304812BC3B1DEF9498CFADE50FB70E1D47BEFC2C0B633784128FFE73A83B84EAA06A868362AF49C24927319FD6965170F929F90843FCDFC6DB856B74D028BBCA6F847B6128073740B74018DB2A03097E04DE9C5405E46F2BCBBE9AA9EFF10251F26BA2E014564F958E0EFCB318AB75662F4B75E28ABE3602649FB777ACC54FB3F33176AF6928B97AB127023BF6D3BB8336376F3FB50593791B1C18CDC100CC904AF396D42EABAD9E7B2AF81E27412E7D6D888869559AA79A05A55B16C73495B945398D1551190BBE90C4CA5C9FA91E6622D00266BA01C9C808E7ED3A6A3E53457787C745B7415D6FFF426B2F52B081F2DFC5451A7A1D310C8F3466AE88FB010BE42D0D119BFE3B77EA7C73FB0E58FC7F9676356B4A376284A95343E2B937EC634D79785F20186905309F51DC91EA6FC3172FE6656E4E856C7C3D3A04F36C073C5905E57E1C139F7CEB93B9CFA3DEB1E368375EC074357922E79462CF9554A8EA6EF5AB43CDC80A65F05AAAD7717CF0DEFCDF59AC5666320459A33626898FD7967B2B4CA4BDAEB2C1E3A536A649C2D62DBAEC5F7CEB1415AB9A58F27099EE1B2700F4AA57AABBCB4C4C44B07C11CC6D4C23C004A4B6E88B1572E75078FAFF06A4215872A71F09FDCF81165566399882FAD1FD7F90823C7F839BB951988B5C6291AAFA04A4B73F49936096D1366C16DED48FDBC55D80A19E25FD39D658AD6E66624CB17D086D02D6A75B004220627CBD7211FF06E1CEAF5327F261B79DD69493B2B743A31988E0C386CD840CE3D99097A4C7BCFD31112DA5FFDB05F93089943B57E41BB0FA11852F0F30180F749F2E3DFB92412201EC77DE783DB49EB7F0039EDCF8AC02078C39E5F9BED9B8EF95E3A469CDE934286123F3E6233D23F77EEDE8F8F795584387FBD4D6699335E06DF1B561BC1DA5D8FC966250EF9A0361004F8CF4CA26E14B55608763C220CED384E37026AE34470BE2A31FE8D0BDA40F5FA7072876CAC3DE2853A60319888C1C7F431E93A953080777F3BF8DF5099F0B6390EC4E3D3E26A3771989B64BCF0F923114E27FC917A04BF544669D6E3AE7A209F1C2292ACD2161C2D7AB49AEFD5BDE912DC8ECBBA8FD35CA071B5EAFE97B126338B397AD90B009F1AE28B64D6A5300A30676E95D5AEABD896FB9EAC7130FEB9DE8B4020DFEE5080726379666769573E1D271BFC5190B273AB18682A8C72039448F3CE2EE44D314B64BF26872157F1FF252A1F74C446ACADBA246E103AB43F98EA9BBD59697D693C9CE043FD3D6C981929A3DECC0AED2F064C37AC4D8ACD2BA7BD64F3B9701AA204F62A62F44CF9E46772F9DE665CFDFCDE552E730B826067FED48FF621D30A1207093AC907CC8434C0422EADF1CC0037B385C7C48322AC3FC0312E7981B9269520EBAA6693B182A519B196B7C120982C4D11B048692AFDB270CE7A89719EE656FAF0CE8AF84E4864CE30EF80D51C0D3BBA9F1867102186EE75A3B4DC1551D609326BD3CF5B53CC6678C16AEF19725524AA90DA47A818C2CEC029DDC5B4C125392008F32B41B8CB95E7C080D3EF46185368689D3B8AF6112696158726E8B426F994593631C6BE8D47CB653EB93F59E34850C679DABABA935739B9E9CEFF96FA267ABF2DD38F6819E24358F51D4E4BE080E387BDE3DBA0B9C12DC69ADFA0D1A0C0828D051FDAC7CF0EAA557B747BC01DD3998A9FA0577DB47FDF079A5E77C337BECC70DD6C1F790A832715618F2098C8C82411A3D8906C3160FA2499E44BF7230BE59B0C448842E53C622F0C89DDAEA378EBE6559ACF1C5AD9B566AE04B66DB3349E3E3EC410B4AE7AAB72F5EA45E6C6A8284F52FF2BC14A235F1DF937BC90AF581A5270A457CCC83EE5815B1940BAF6AE9D6B9566C5CE870EE39590D9F394FB078B35A43C956414BEB618CDB2CF2DB9F0F6ECCBB8983B8DBF8F05096B8A7E56B3332B46F9AAED9A69242DA1538D1613EC011B5749482F33D22F4F2A2FCE38EB576B5BC9E31ABB0B4E3514E7CB0DBD0EB934D7A476D6C20FFC0F61B5B63CD07D0CF9AF109BD048C4A6912E0B572C4233E40566FF4B45E4077CF7992BDE619D7D416B130D41A213203423E95ADD3E06953A401653B911E92006F1B3AFF07CE790EC0C4A5DC27C73FB5920113565EBF82FA68AA7C6F18A898CC9D68AB59D6C4145584F46D66EAC20E10608DE439DB2F691A7501C32C240DF33E3B80AE25E7A033764AFE75B7CA080C2BC6907D1BD6C44D3B8E830A1A4A6F540AAC377EE6FDD4B0ED99CB0E285AE7AD8F2C0D8B78089F65AA77ABFAA89DDD315926D09F77872839520885BB4C7EB4D7793BA7F78BB87ADB4BAEF60F3726C96345077CED3260D927139943E2E3EB149076D32161F12248D604130040AE3BD2A5FB6996511F3BAAAA9D9929C48E8EEE4BFFA44B09DCB4DCEB589C28ED0B66C03D6DC261D2270444B1ECFE26DE1DA1623CF00BB76E7930786D3BCD5553FD9798B4773765E0BBEE57A702B44A452208A8BDE01674A42B3774D3B32DB08EAB4776274348D6C65F424374AFE295EE043B8AEC4C00AB73BEDBFD4DFDC5330F52F789A8A24E70ACF4F4BE8B8A338028856298F62D038634F02875B3E5DBBB0DDDDDA8200B2B50AD21B7FFC235AB9C249FE329B8D300DCFB2794C3F2FB9254F4C6F4272658101BAF2B6C070A0EBDC9C41B61564AD0820204F4004026CA7C1928B1FE800F6FB795F63DFA4AD515D0FB77BB9E7F04CB16F346F396DDFE0659A966411CEAFA2585629A662161C3D8F59BD1FE567073E25A459CF8A584D2420C179FBE13CAA1A2E9DE2C02515F00A3EBFC78691FFA2DE9677A1BCE8DE403A174EBC53205AFC57E04E1E87459DB5C66042ADCA926472DC149A56DD948B694D24285EDBDC514DEC8A5AEB03DCB679EC553547512B6462752999A46E4686B2CB52FA3EBF890AFCA894D92FF5D99C76B8089D644657BB4763E7E7E6D9F9E1C5BA50C4A0526F8289B97B9F0D73C84A5D0F729D4F0C400290F24DAD4113C47847A14CF74036ACE85658A9A549E8AD941029FBAA51408311B290FB4C3BC5DB325FC587BB07D87358BAC4DED31EF3938C3F88731C46233DCE5C54D0B38F66AD352BC798DC74ED1D844541CE8E0FE06682448BB3E8FB07FAF7A1FBA8255DB99A8952EEB38475D817F2716E23401BDFCA05792E6C29F0FF23DF4C0EB58CDF8EF36982EA6ED9E5E0B0B1B4A3E81FE64606578887B350221C74C1C898652689CC96598E0A862236528C2D7E8F4564C0EC77B1353F5875E88173090CA42C720E2F40F908A90B5EF73B96E0FD9CD295258065F40A7356CAC69E039A687E5DCC338AC950246AE526E182248B091E14EB1BDB876A705FFCD7806564EECFECE01BC7A0FF1287EE71ACEBD654074BD6302A8DD286489A256C329C503E9617D0FC35896F623A49A1BEA223218FDD919828BFFB7CBFCC226A8B2ADA48B3459095CE7BB3E6A074962CA64C9FA9B22550477A5096CF2BE54BB01B29E3F966F0ED5D4BD647DF240CE8BF8E27610B7D3D936E234138A1A2DC6B155BD8F38833255308571CE646947388B3F138AC97FBA7880EB2161EBAF8457A321DDB53ACBFDAF73ABE5DB2054C468541FC31E61C0F89F0AE84B2632A5F12650922338D19B584E4D855BB20EC550DC116417ECC5E4E9C66ABF40931A4B34DF6DF4907130E5CC6BFC88F35B97534E5B8B657167856F1AF113542EAE0754D730E0E3055D10EC4182CB9D4BD0D5FD1A895D57F7E17C15C26341B16D727898094869D958B1DC9BB37356ED8D47C26CA270C69736109D310A39A4E1F8D45F987048E50E4D787DE11083689522864F67454A85CD0AE8E0FE46A751C692FD2F2C087973CCBF17A7283DD180270EE3E85BF037DF27F06811F4159425E4A0ABB290BA77791AE24FAF246276251CED06827C9BF272559DD9938194661C5E4C19AE62EE6D2D9160845E729D6D0183E9A66A31F2620E4F0EA10DD808D99F40B23C9173FA1EC3473874DEAA4180F69BB19C6B33B6CE9ADD8D9871B1B456064F2EAFF39408B32054EA10F08D3F9BE78052B22E1F18CDE0A5C09A271A63AD5828F21E363901595DDFBB840197746B67B4B2E55F0C8F085D64D904ED5692DBD8EBA874E8A740AA75B1CEBD277622B9AABDE0C9F63C8900ADEAC586D3771B1C9CD2FA24512F29587EB921E81D2CF322EBAC7C08632FAED3100994020FCF5397A9DBDA1AA90E6626B653E9950FA90A31FCD546371EB4E876EDA332C745EFBC684E3181176EEFF821E38ABD5B969C7642C0D9E1BC27A1C93AF3390AA13059B173BF802185EBDB1BDE816DD8D7FFEBBFE844731107537BE87FB77CF27ACE899FBC62BD474684CAC5E1E14538101170B7E5B3C93AD0061430F6D6A640A1CCFD23C98DEA48A7C163A17F43271B9472BF26082EBF77E2431DA6BB5508BA264A09090CD9AACF3778E6952BAB7DEDBCDF860F80DC8ABAC5FA0D644D21C18E669F5CFD30D3EB1A723FF292E98561EFB76AC88CE36F49834739ECF7F41D0F3A1BC01A9D9B3558755C797EDA6FD1F4A2E1F1815C5BDD5E813CE83289594793E11A5264DE3853E138B7246A31F0867B79C3363F880E199C709E52F17C6E1FA9B6AB6F50DB4BB7E921898F75E85DECD42E549098F2FE3F506B3DA08611756AB83D0CB82EC4A4D00A5C292DC75E84CA11246476E7264CB66EDA33F5AB5604124F50EDFAA26F1148954BC6D5A95D198460D", + "rnd": "D6D63A082F55F3F97ABF83514C80C64EE2ABE267EE9D3DDBAC95E82C02F47F73", + "signature": "500FBD0C82A2ED239A7FB6001F7FF85D631CFCC95ADD7112D6798A8C9074AE1E30FC71287097F72838B3C9138D45E725F5441731ACC95FC089B6DC7344410CA9C9825E93E8B793A072CDDD51E44B6219B03F0EE4E6D4AEFE227E433F2598CCAC766A1375604FC70B7D0700CD7062CFFCF8968371019FCFA37989A3C82B988872CD9C0673BD30C6DB85CF086AA7078716D541ED528EB99E11D630B448488E38914875B016E49AAF947A76F1242CFBC0B340544724E8CA8B108E2564414C0BBE6CF4699049A160079FA29E149FDD514A10043AE2D81087FD14F6071FB4EEB8C28D7773F1B262892EC36C5CDF89FED6BCFD3BE3C837FEDA2EEC2FCEA6BF034E6C056C9B993874E72F70E2C02DBEDA64B373FDF447DB182B0E916C2D86B72C62264E19555873567CB432A03CD352D73B790380A204C210126070D98ADD3C47208F9C589B31697A225B627539BF30D04EAB58D73FC0E90EFA57AEA118E19EE1AAE8D30DBD50C7FB798689DEDD4805D984FB1EADE5C7C61B69DE7BFFB7EBA9AC92578E5782368AE47CC56D3D2BCEDCBFA8200D3A3A47F274BCC4F9E8E82AF3463CA573204386EB6515290F7C2FC620F411BAC62922FC5020937D15A8DC2B6F5AA9BAC4C1FD8AF71C945ABE6826B30530CD1EA5301D41C36602125C740029188DE6194E7B1F939A4127ECCAE14F43BCEC068C64195C698331BC1DA6763B8ACF0BF55CE6E0C24ADC214469D0881D5DA1871ACF2F13D5CC213EC4A966DD3126347ADC4353DF27F3AEEBCB622B015A53E1F48D7CC136DF6CE5C78C4C0395EC527F00DBEC163AA8285A5D61E162D45665B3EE418F48546028EC57EC1C7CDE3AE686C7F63EA9CC284C8BB88CC70340CF8416302A8A984A3DFD6B71E58CE70712A28FBEF9BA1C74068D009FB89B431891987F9607C8615350C162C68AA3FB6A0AF7F86CB99F1DE4B2604545A7568472A43AC43F7309784B7CE5EA6C6445FA8EBDB130D8F585640F7130C293B2D0717451FD6D9831B24F79FA736070F85150BFF683C44CB82932B4056FAB59BA8CB4815A475ABD582AEC3F453E8A2CDC6BAD7296E0AF633809410FF490EC324ED0476C9093B23C8E9516FCCAA4DD420431499E769058F0E6B4EBAEFB396504C4ADD6F13DBE0738D08C0E151BEF076EE5DBFFB3EAA900062C83681A0369E382EC491C8DCAA92BCCFF615DAEE43FAD2050E0395CAC5429D1F5861CC55DFD0A589039A00338B47BADD08C88B70267D5FF44DD3210E042E9245E0DE60E2E4F7E94D442AE79BEF0DCCBF001F5BC12E53364FE31E7289FCB0A8490BCBD48D7AE55A7E73D20913BFCCA3C6C0E80C4A5785C1B49969F066517D6912FD442FB6C08C979D66024AF717B00881968B645977E62123AF073955E87FFFEAB6184016883514C3D54C223047565616BD16964C620D8E81439CF007E0C4828592AC60AFE4A6111EA5C8F7B12559021B6E40DC80D1A491CC4CB5452B13D5B0AF67D5BA39DA6C39BEDE362F900F552D070A5225ADEE1C7AE51D562DA1C2B323812C0ADD419C66F1651F1F9155E98CA7B43FBD61B5A9946D2C567B6BB6AA3A3649C7977DFA9A08780C1CCACA5258120EE558BD724F46C1DEADFA97598CCD7615CFE7289A8EF1A1914F5FCD91D33DD28D301EE4B925B32AE836644BC922A5889BD21262CDB56C7D2FBE952A3BF887C6557590405CE03EAB83EB7DE7570BB1C21AB894D03CB9E1DCA4E9B2FE86C837928F28DF73DD0143D0D01A3A997D1CFF01055F13E7D9F2B06E4AE94C60EDA1EC07AE3EEA92B07CD2D12D27B99B7F604C613E5E718B24FC476063776FB0452863BF9A89AF3930E8E39EF5BFC22689741C71799C9F9105AAC66F7B2D87FF3189C16E9B5846D54F7901708B436F36103757AEFF20992F29A2D534460EFA5FAAD29533BC9AF9C545A3BB4007D704964DF30C2191293F011972921D150576C175D19694DE37282559EFC6C40697169E5365E0685A1E6D87627E645E4349D50266ED451A2B2157D82E34136EB6A1604C134680425A26F0E6A5D6F7A70CE42A5D7F92CC28B224C4E732FA7F72357DAB8CB3F9F7FF9C4D8BAB76C60E8FA9D5D6ECAB93191F9A1C55FB3C69701E190A735C1737AC0E1C898AEF75093E9CFCCEF08AB6A9A05D6D7D70CEAB428CBD0DF463919A9585EB5C057F09A9187781B93D9703B1FBF50EB04E77956226070817FCFEB54269B1DD0168F4623A1B5A470F4508070DF49BDFD2A09A58597994D44009E2F618F38789F4E2D810A67ABCD85D3291025D3D32F601A7F94AC374B180E557C566C5024E438B75FCB6FD030D82C0FF3BEC1A3EF43DC52226A24665AAF95F0215891B51A032A2FA19DA0BB7D5C352F5D30E0995EFF3892A24951ECD0D60E380A93154B1E65231C82640CDABC1F543D783FC2CAA774176C97E2D7C37F4B597C6E976FADFF330E174E9EDEC798DE6040FD9C33C5873E7EE467705447A2B7463F70D0A8E94D85B4588B76C8BDAE112E37763258D5614CF31FED87D3A60F64E3BC2AF4C32B520D7A3FB0E29B8FA728C1E7DB497BB8125D92C08576AD1414BAAA27FB77D359F7A9F2CC9796924BFE61006593ED211514557DE045F566B7958B695CED35F61BEC34517D1948D6FC43202BAE4E47D37927DAADB9CF404E4310444D13CC5BB2555300085305CA20F41D7CA34E7998AB018F8D0C0BA641B9748A8E5C28349D452C793063BE377259793BA06A591B7E9B22BAAFE6C5527E697F0FA1822B1F7EE6E3B78E03F934D4E230BCCB93251E7FA8DA673493BBDFE91F0701D0551A2DD23784B14C0DB20481CEACACE8FDB33A113CA797F285459B5B916D64153575BE5635404006BC2B4BDE00AA446EDE1472E441309BC47B6B12803DD1DFB9197FD476789CDFF7F895A1036A0A784E0656BA680E1904D577944B3BB170A411FC99897E8C7B3158074B78C85ED0A666E7B849856E4EECDE042ACFB59FD8F3EBB6EFE357492C67EC0807F34750E0D87C05F54B94898C2B44899343D8E231BEBA65D487906608729752E30CB519C159D09AD388AEA97B95C260DE5BC926996FE15D01EAF808278FF726D8CCF1014279C7E497D9D0A2323C4627008CAF02B58A1B4B98D5284F06960046E645DE11ABB122EB74D4BB6ECBCFD57B52F8344B20C0139F63E40D4928BEF00246A5073047356E0D82D942EFDD513C7C4C923E0FCCD96F4FB46310B2E679E20E5A8AECC1F1F7CBCC9EE6D50D4C5BD34B63C4ED6B501E07CFC861DEBE01203C9308A0EAAAEAC3323A7376BCF0FEA404EA5C7E3DB216AE5B0B50740FC708DDB46AF0232074011A31485D636A6B7190919AA9B2BEC7CACEDEE5FDFF01151F34363D3E4E73819C9EBABDD2DAECF820393A4C657A7E86A7B8CFD2DAE3020611172B33383945576279A7A9BAC4DEE9EAEFF800000000001628364B" + }, + { + "tcId": 13, + "deferred": false, + "sk": "89EAFDA81C10DB1C89321D386CF95B1D71AD02FE23B6957C03F87455FDF391E4D343E0617C8DC51797179C4E03C7A313E052EF59E92C4E3298FE763BD19FBDF67F711002E8A3C87BB5094532D7DFADD24B0F81D7AA0415A3741F074CC5DEB048280FAC463222D466F245307F90463C8F32F892C6ABDAF408F24E77D491EBDE3008264960260900B32413A18521C02854A40D142831C1889144A64D4A262650A8119AB2610C112ED2A27190488A24296820420424C46102B81008446923C74948242563962C0A3050DA886CCCB8281B03080AB34992A040CC182E84A251892890C1A4300A194641162E09162021152A140981C2127204B86449C244A4088222374693A6091C2731CC0431E0B620831421403630CA282608960C2382011B9021DB008ED0120A0C28505406322314701A308D03934D522065421886029908430289D918209A8245138344D9120E61C03021066A11146924800D1B130C0346865CA88810C42963248612428E58428842104522C06503A748044700E1902908A60818214102234691C8905B408020406EE1803011B5645C382A629044C2C688DA268E1139655CB831A0142D9BA271E23809CA92509B182E4206211942512317720A212CE316804BA820D28209093644DA86480C404A428861E43440813851CB2808004161E096514C8621A2420490280A8488115C90018CC60C08A24449460DA220481C4382232028883642D4482221383183820D20196009C76D531872E13046DAB8201203515A34600C218E48344D0A338193328E48448E23038D12C601E026424330701B920523B72D030184C0384800A96859A241E4460A62C2819480208AC4486090415C12205A22200B0342CA1849C3C24100156C54263194202001284E9B364E89485110A4095B36719A3829C9C22DC3B49184C4110B068900876999944563300518298E5806814392014C464D54064A54044DD2C02C511672DC2029A0B8648804814A880890B46824070C42004514240CA134110C94240324880018601A9440402642D42692A1082A002904E2022C02434A101825C93280548604C4B02404832C08C191113624D1142084A284DA926D549089593249E3A645D31229E0400CC384285BB8448AC20060367018044D6132505B108C98164101C1401C310422324E4BB46998244E92426AC3884020457162A47199102C0BB54123053052B429D42431CAA82194C08148A040C99681E2927009918D0930021928264B9204CCC69096E43EE739A97CC8DE08ACC93A37FB78A79FE7F312523D3D126A16D6534E8E30B959F7C2FA43358521C469E17281ECB277BF2D64765EF3C880981C7E6EB0324906B21B146BD8ABE45D266A00D0DA92A4108339DE4AFDE39902651EE4854243E40F851F1DF40527602CD4BC0569F60661F9D7AF6A91BF095AE3AAEE25FCA7F4FF4A8BE0A17450724C185AA491AD34F5F711975F5F015352635571C973CFB584CBC14C3AA4A2BFD99FDF2A5D21AA89243BE26E129CB27A7648ED31B223D84B26C445498CAA5FB7C32017A6851FC630D358F19417A547DD7F02CE18DFE123527E9568576C0335527A98233A231C8C22FD4877863945035DCB68352F5B600C4C77985FC2DA58D6633D4335BA0A3A821CBD30ABFC841997407F197EB409A506D94626485FE82B54456D0B90B5EA914B229128FB7139B35AC473639EB6923C5923E4AFF31E2DD8B03EB7C6C71BF52C2817D623054207F9D90CE42E2E133F7B3C3B9D22EC26144D53B548E6B00638858F729D24547F1C2880D5FE830686932CC7EBBDAD53EAA5FB004A2F56B0F1AFE9815C53EEB5E36A4D8F71B3454B48089CD2EADF1CD1388F26BD360693CA5522AE019C9458505EF370DD8C92C3679F99C42F47660CB92A5D59D60036C070DEF762C5FCE7C1D3FAB61D9033500ECF16CC40FC1755A3DF254B8CA2CC15D159BEC2C5E41725F5315C9C172120CEE0D10CAC83DAF7BF577F01904A5FA170FDDD25496AE392C984E377164D1963FE4A1F8DE2335F62FCF5CA8B99E195BD20FB0FEF35E603E8D54F294D8FB348C27EA30FEAF3C983CB1DAD3F0F01A2EF2C56AD970E566410A2774EC0B7C840BDCBEFB66AF88A4F6499DCB77348F140124F5828EBBADA7738BD82B11F5CF2F5EF2D5D9D7CA358696D8F617D0A0B2D0642CAE5BC51C1EE97CA82C5A7B7BA47C116C547B9D1534EB9A31F77237D3EE80B80FF4F25C1ADA4CCD4AFF1AA7F160FBCE089A74F808EAE95A0AB8F1BDE8D6A7D8E4A1B9018D1DD85502E9C067F930C56602325BF65806B6ABB80B661E6E2C4F42C505A0BFB1BF032F878CD95E8047F4F99ADF11890A30FFEB5177E05B3EDB20436D0E4A67971E5AD3E89C97327CE8D607399A7DB3AD096CE0FDB5960DFCF4AA1B7AF16CB53B0019A1D8B54D5A5E1280AE3DD40A82CC4921B174D9E7AAF2F2373386405930847DAB5F7D37916BD0FC30F7B99EEFDB53AB3896BCDA41425354D658C9E2D1D073261AE06129224F3C24AA70CDF8310866F251416FB25CDAF6A4595E8C0372F4E1B4C71FF849469AA22A46239DE72EA0EEE058F34EA26B37EFF47E196DE20AEB8D6CA6165293036E583A22EB2E0DB7417C7DD1F8791EC983B6373180C80506513BACA28BB91A86DAF3A3ECC66DFAA13B37175AA2EA94A62B657ED51FD067237BD42311CC455EA30C9C049AF6E653121D0A564145B83B486554B53334DE3FFBC857723905EEAE772DDC921077DE070C12BE180CAFFE5F6617F63A9BF6F0953753C263062F823292210D91B9945C1C07E8FEA1E918DFF5B36621BC4FCF72B862ADA232327D7EBE8BB3054B862B15785D46E4888E30D58E047ECA68DE71C23BFDA1763790ED89D4647677A774AB9E5E0E07D9D4F13767BD31760CE24AB718AC9B2E28D45E090A4F6C54148A8F92CFBB7EE44206048571065C6FDA9997F353471295862380872357582E0082070F7D1FDC8A451C4F8EDA08BF5CA6A981A790681DA0ECED57CA18F5F240CDC96592D7EC9FDDFC764418C28A23B2B42FB2F118DF262B63C522F279D1E29868F3BC39A008779CEBAF929D944B2C5AD09BD0D90F09DD71F90DBE88E3320657333DDC2ABFCE4C6208B5E444812404E6AF048B92E2C5B1ECAD70BFE5FC62A645DD153307154EFBF9638540E83F09F67D5AA23273F250519FA85BBC0616A47829C8D7DC5310AD5F421BA7EACDDCDF3C8371944B8CC33039DCE698473096EDEE78681F1D95A3C977359F8BB29BD40D0AEFAB12FC50B90EE1998C8E393EC0D9F1317CADDE2135C4805F517DA6E761DC617D93D053EFB702DB318AE7D8022876157B7E2C6BBA2AC83D580806526EE14B5BD57CEA1097D871DF6934EF8D7F925ACBAC4A34744001F1DD9C0E3607C34E00F9D74C39DEBE0E646F6523F3A12ACBC41B48B873844D5317DCC665FCB3C8A3C3AD6FDB835C3DF8F23C6F4B04C863AADF82DF4C5035A46B2776C2D87178B91816C664A68B7E9BC6B0FCC8FB7FEE5C025E00777D9724F5D83D0F6B9EBEE89779069B278BEC3FE347796A7328C408647E374697D23D0FFAF8280B528ABFC4F5508C04AF3C98B1C8A5C3868B1C385EBAA910DF00B3847D4285E4701FD1124C3A8170A6D", + "message": "50DC983A4F0739C1F9AA61D27AA4C66876FF3CEEF36C94041AE506AB1858ECF2F523FC093721D2817CDBF0310309BA54CF7BDB80C191534CE5CF5B2189B69DE9DC65DB35F896E35280FE7F47B97AD475078F61B542C857D159F59F1A73527FFC23A9ACD77FC2E331301D491862AD4185EACE7408B3C093883C5BF7DCC7146FCA17E2F4FBFFBE447C981476D551932C50D1672FE31C96DF18A4AB96C43E7C46A6F39BAC8FFD13EC19B2919F92D83734D21F36580EBB6265C471F20EEBD8F60E38A74F0D86664B872A75EB45825B510AB3976EBB4CB4EDF6002213DB843D6105F714FAE3E3EACC41DA820DFBB16287D74C774C4DDDEE22338A33F853A7250938709CA80A329E82FFE54CA96EE87729F875BB018E76D2A1A01E2D8166EAB28D83F1F573DA5BFD924D06C2207F8F40600C99E20535A9FB2DE4770407C5EC88C105CC38AF4883C2DA7BF0AA8AA4B619A426F26DEFABB85ABCA13EF79D367983F89166D79933675279898DBE8F669D6CDB143A8148E41A27DD656C179BFD4B683980112810922EDEA73B5209D395BF28B8D9F4E89FB2040AB97669C7120E8DCC9261534F8F5646D0FDD9344DEFD39E462D7E2629CADEC98DD0A07E56632CB8DB8841DD71DBECA7DE03BFC7683FD4AA38CCCCF3CAEA160E70D22F3B3635498FC54274219A0B6A132049103FD84E9CBC0BD7B39FF2F1FA4FA9DCE9DCEF0DF0EF42971505FCE082EC6CBFE5C53ABFEA59AE1E4827248B27DA4770011CF8D7D3060E4BFFC2A74ADB54FFD82B19CB41C0ABF8E1B3C313FF3A415ABD4FD73481C497D9B107FA6AE33A62E25C275FCD81979747369EBC6EADB715456AA6E2ADBDB02637F99B63D807E1979D2270CA157FAC009FFD95E5A8FC907514E0024C7BD88452273DDF79823794DD1B47B8FF22CCF547B621BB3210D86416721D9B6DE4FDDF562293960BC762225A2FA5BD0C120392AF4DE7495A2FA7E6BE48A6DCA492C382D954CB03B57C432FFF7CEAD9F696ACBD4FC22D3167D633222648124FF6629E45089C53B9D05354DD7E4E1F8D51CD2ED1979D3E42D7CC1E2D0D9B560A59C17D1F093CA62567445B8D0405FD860341BE7C526C107481A881AFC1BBFE2BE059E27BD523CF0F4A813DA812C0EB597BE0E80CC737633B3D5343D94CF0A6A4ED6D4DF05E7866EC4D85B4B6A74EC7C581CEA0685FEB982E4940F43B101D95FE37E5F7DA856C271B4848F86065AD7C328F53F6E2EFDE89E447D25C8694AF3446E61A632480571977B08F46E9D0E001A6C789EB45637B189B0977319EE4D8AB8F31C841665443BB7A99595E087A935C7971415E3F3E660E2780B8673BD1B2D10E97C17C2C5972E825C82AAB71A3995371B30350B6E64350ADF59AD93C6984A444CB01A2CE04107CC1F744828F1404C25AF4D1BF76F69D0F398F813CD633E06A4BBABF7665F3484273794753F67DE02E32710D1CD3CF5E04416695164683F6094B3A00704336336710A48FD5FBDE75CFA5C7C0CC3D2BA54B2A02AC985A59E7034F42316B4C86F6F23D4A47791B8907EDFFF06F2E87454B7CA64CF63A2970B1581DAB5E02CC74C015F6471189A74C98203DD6090CB104AFAD45FEE00D9BED3A4ED3EFC5B4AA44C408FC213236F2917B875A922764BF8447E2600847907DBD37287E041A22D4F3B3643AC890F9E70FB68C8E5ECAD215B853ED1299A75DA9FED18D1B1A45A91E09E625653D1C12725A7C0766F08E4E4A5243C3AD382CBA1818A157DB035364171C7D1DAC1525597C00263F53C0764A55AC906F7E5CC69B27923B8A9699139899D0C8DC3BE4FADBC1C12073D3544C53A337F0EE9BED34DFF9B801A7F1E61A9D74FA93A0131A82469B2C5CB23CBF5329392C71B13688922C70DBF6BE2A95081D745C33277D867F14E927772E19A4BAF0762C3DF9038FFAA8211027932E6B6D125B7557F7B0C955772674403030B33C976F252997A86392CB54E4F0D2FDA6892958A7E2553C2916A0C3E55C965B4E8D12E22539B895C5BA3DCB9321C66A195C820B9B7FBDC51EBDA8DDBF5D62A05E5F75AA5AEB5A2995C5D765A874F9D2F35F2148FDF5BAC3386DCD7F624D5B9C20E63F8DF3BACA3AA480005642F633EC3C0B2B1AFA82879EED68652525FFA9961B195BDB6036DD1F7A1BCA8493A82C9D92F27E0CE376B67CC1A0C3D0D944556F0594FE6F93C5DFBB170F91B0FF483EB1393E697B6EAF2A1A89EFA03FF1F42E0CCCCACDD25966DBFB6EEDBC0E913F6B62E0B5C507512139D36657D56FC14DA8D31D22F06AAB1F66FF46BB9DA88391725E5E618D99C84C2FBC3479F1C06522B70B953FA0039DC9C36D4F8E5480DE6E4C57173A9178583D12BD268E346F8CB68D9A3C7B16D0E98A98F0D9E5D7DB09554B69E87D76F2BDF386AC0F898D36BA9D5227695DD629D735D58E2D4E6BDFE92247B3C5EE0CDFDDF6F812A5ED05BE18C63F45C4C1FD51091057F55C53E9B5052C991448A5FCF9E217E866AFE0392F2A32E11604710B83368F59C1E7EFF7C55CA7F3DF1D2FF1F9DD43B6D04534E063D23FE55319465DF90BB744399FD93C99E82E9A8F430C6E0F86FA5D616A163A7BC9F89B2488DFF4F73737EB8C3F77F33AA520E780AFA95C6D646E330D3D9530F64383B19213E2BACFAE4A39A079D37DB9079AF69B0D7DFF7A8BAF0643AFA24171D7655FBD30FAD49CBBF4FEAE24E71D6BB1E2AF7F06075CA240E18DE87E75C4ADF95D87973E2E9BB71AFDA26920405B189885B8734F3ACF5EFC9EEBCCB2EF9A5E5E1EEE8000B6F16A55FFBAD66658402CAE3FD718D423CBE7DE874D2F98F1B7D4D309C2616C0A58709E8D961B22ADE64ACE84BD69C36E6821805B8A58268FF7EC1BDD834DA30EB16BA99B873D444C4368E074BF90DED2B1575766701E75010B25CBDB686615C7BE8D159C3B75C6C087F07A005A32B5C2C883439915629CC607E4104DFDCB3CBE683BA67453A656F5F16CC80CE57DE61C72C8A7A4247E0364026842926AB72C4FFC5F7E414E278B6F28681718C79E2F4A777B042A1B391EE67CF49CDE167E5D09848FAB14C85D9777F3C3DE42647F599E465810C8C0B1DFA874469FE69E7E3206AB7C98203D76A38743C5DBFBE1922C1CDA3B5C488508851CB0E88B6BE5DB3CCEBEC0D5919C34DAA3A195D146CE9090FFB284C1DB4DF1C6800D34541719441D150CAA8B7292DEA09C17A93A4C8992500500A4B003F048794A32686F3CD0F14DDBE25BD91F9591A46288B224C63BF9E97C7125086720FF70E5C920033741294F3B707546730FC12A090BD003602D426A36A0B066202DBD5128CEE8E1BF9AB0338B135209A630892DD746362572283ECDAAE09DE874B4638E791C76FD3D99703F30422B9FFBED4BD488251A83BB376E9ECB267A30D9E175B7B24EF7F2051252F1C9F15CE0C709F3251077C9EA6B15DC710E7C0F908A3A308D23F2A8EF135C4B520F869997A97D1ADAB6056B096F99A95B3D0A4E", + "rnd": "6CE096FE72575F419023A95742CEAAD2448EE8839CFEEFD44D24638294CF9B2F", + "signature": "B8FBFEE9FF5B04AC57EFB8A7E0F76BFD78981BEE1F0B8E31D6C3914D0CB4750D5AE1AC7F9D9DE24CAA2A39E35F9172C63928E450650415D7F58673E4313EE8C22FAE0DA969C76822C112372D659D77386A49FC828482AAF77F51D8AD86419753BC7CF6BD49C51A108F50044C67692C96D1068A9ACB274808381A51690B008E760878E0BF7DA4715BFFAADC5CE05E0680C068C9BA3125E2B5CD9A3028EAD6D612854E1312382E4914D2CABF1DAA02BD1F376195E0EFB2A2F469B85B9EE42EA30E8B9F64FF75188B5B2C5DB13E23D040E16BA75A8A265FBA0FD5EF34977F6F5F3F557467E2840D62B474437613915691D90845ED8B14D891B1737B702B468F57B2127AB52D0E30176EDE5E344BE133929F9A852E2B733519E4272C878AF9223517C6118623B13BC862D349CF9560A39B8C339B2CB1051D295DB1FB7C3380EA7397D6EFD9608993F31068704EFB574102289DCD61DC17BD01C6F35B09F786C73CC695C4EE8400E06A66B6927D7ABA40561E2DAB073F6C25E69A02495476C60955CFE3489D5989E51F2F9566FA9638148A6680A0B17B15B682E829B44CFC5EEED2F4AB5170D2C45B9A7DF1DFFBEC2F2E603FA18FFE9D896A3555FEFF0C76E9D1E38F4BDC5EACEA8676FB9AE1E9F179ADDCC9FADF89CC323DF4D79C75456D54993CE4FEEF09E9ACFC499B9427F94992156D194B98D1E94E23D6A1D7389937D877A94CB4F192BECC54F88C26CE04EAC8F95B2D6752542C1B9C256D1F9EAAB42804151A3C06E6346343B11937A0B4BBBFB456C91631E323AE40F95C622E29A6AAFFB1460F0B26DE0BD144390934B4F9351BF5752E09D43B3197F40CFBB0E6993461767CFC2A2011009F8F0215C09FA727E6259594FA7C2C81748493BF7A96754ADE5B4EA7D79C88E88268A626F205E29CF52BF9E5D00FD0B912A5BDE4E040C84AA54D02DB95DD0763AFF0BEF9C791C85007431631C641EB75FD142771E9B17C737E6DE73DD50BBA8400EC8D444ED7765437F9659F612D9FB65590F2577150D82DAC01DAEC110D29FEF6C91FAC37956496ACA5D675C865799ABE5B2E38FD9BEEF3AD238A9AB067A9F6F35E8BD00103F46D2881A356688E63E5D4577E9840E90E63150410EA8F6B6DC53D6B2BF9CC1C17C33C1F29C33D77F5D363E7CA6CBBF2F93993DDEC69499523FF375E5C2FFD220A209F111F41BB36C8C1B88E2D60815C2E76DB7138B9E98E675050D42BA4EBCA9CE4FB75921818B1A88674010B91B851E89BD6563993C3C739219D9A4ECBC8ACAAF924D558936BDA419C4A833638EC6FEA4AD5868966E02D55472B1ED53509F18D3BD0A48BF233A4A2F95FDBD60BD2BB848A8B33BE76E357B268E5459E872AD572A2639BAAE21B40477A8114BAFD4F64072ECE59867785A6BD203E0EFAC7ECC002FDB8CA9B00E99BD97D602184AF64CB31FF5C0CCE3088C2B31F5AF581F9DB66B00D5338393EC94A7BBA026CF1B3E62DBF15EF7AC27345E8C89F70F57954A1F63129CBA3E93AF6DB16110BD702BEBCD44E5871540F28CB61AF300B464D6EAC0E96B0DD5544CB4946C1A4ADEBE6635FC0075C554CAD9C5DF51DB0250FFD5738B0FC5A2DDD8473C947C6F309220AB2342B84AF9A143EDCD190DEC46D06B93A36E30862F0315BD793E35BD3817B7987A2F3F82CC033D3CB9C562059D2FA3A22F1CF2A2324EAF07EAF810097A0C5E179E2D427FAACFCDE12ED675433B99EE73132F8831F5B848BDE3B26B80D89A44454BFCBEED7AEBBF72F3C523966A5365E53131E6F0EF5650C5AAE29B1C830BA1695DBD8C84445D9FC7EBA466A4F27B0C341CC61BEE266A5EF78D463B7296187E68BDE84B1D7A2D9BA743631A7C00DC50F077D10BDAB7A5B3E6B39181C123D80027968910BCF0A7CA61A5EB9451741524F30527FB98FF8080DE3EEC8338C9AA93E27E8F0B66021F1569F3A50F4460C6E81172EB7A3DFDCF62427DDC0B2A027C50C34C864964FDB442F080AA78CE75C1128CD89F1B156009DBC9BD4C90CB3E610B7A288CE1F9F8C12EFD8972EC67A81A9E3AB0D27373C6CF037816B0C7B90298CB0A47438F6A24E414A46960C645B33ECC00B687CF210A9E174C1A0E4AA4B930F508078FE2D10C31C0F2865527F8DDBE298CC8B208EF44046CED7BCFD77877877CCFE7DD2E87AA3B59F1278981B32AC349B3C985748F843D0D35BC9B54C5FE65BEAD70694D9533DAB3C806989373AC7A04D53DDEDDF21DB1507AF2F6F3187CC3995B549B0E939F1DC1DF83CB9BFE0FF3F6E9B1CE9F20213A37B7C5619F86A7A584ED93DA99CB13EA11DAEA9159CC5F8D33BCFD8C6EB63339AA8A6A401A0798D89C6A267FA9B3B63A8FA0F1A5E8B780EC519DE08A2F0337DDB4E91261BD1DDFD8D46052CFEAF04A1689DF9E6CC0167C1153A1429827C91B4BF4A3E473836D571697F592DC9535E8C423D491FF27FA209CE589BED4599ABBB4F4DC2B2D29EEE6B969CB27A446CC031AE1FAE583E2BAAA01DDF395A89CCFAC421E57B1A7B161100B2399803B25454B1BAF195E1D99CBF4DEB6B55937D46D9239C427DEDC47D415A6192964C966125A13B697874F2858BC8EC8C1ABD088E7267EF2428DEE0DD7D18613D7A386A110A3FC92122AA06F060075984BC593192B12F65936C2418F9546D461113667505F329CB2E01D72E262E943816DEFEC1CCAFB8B826D384AD4A6C804BD2C419BABDE30288425E7FE75D0A03FC934A46C8E78B1C8BB7BB7853F043CB25A77F920C6DF59D96FCE7450C2F74C780ACD9E2A6BDF6B292F0833DED5CA69B44E49B12EE58753627057AE5197838DE8874F3EC043B9EA842469DA41AAB790C24EAFA44AB663E658FDA278705425F8AAAEA30392AA2B6CB03AD2DE65DC01F92AE94C47B8F340D141A89592B2F3CF206634F7E7EB5BA19A712FADAE3F303F603041C118B69B6BC28992E51DE03AC6ACBB0F67F50519BB9628589C69EE2066A9209E2A7906164055261FA1C4F6B88208ACD35719A87B1D9592704620A1CB44205369370B733E55B438718DE5D5C937D0D7C6BFD0B1EDE5EB412B72A602B65B65B52A9489A9C682EF46C13490577EE75D608E5687152D30E3FD8395AEEBBBD8F87BA2C3A5B97E14CEB8BE9E1C0245CC06693891D0D98CDA6650B31F76CC0EBA3DADF4C24BED3753EBFA5E903CA52C5910553B21538A7E88BD84BEEF4F1C8CF4FAE5318D3CBCE0C3661B566F141A2857C55680209EC10DB3E373F700AD79F5CE17C079507A9D2A41796D1EBE6372791FBD1A5D02A4443D6E3DA564F02EAEA47B68478C5BE3280D41C581F79064F525C7B8185ADC4CAD8DAE0010A1521333E5A7B7D8E9295AB273C495D5F747D8688A6B0C6CCD1FE040A0C0F131B235E797B81ACB8C5DFE1E4F3F8F9FD0000000000000000000000000000000000000D1A293E" + }, + { + "tcId": 14, + "deferred": false, + "sk": "8D075246821D7EA00B94C71D0F38EC9D10E3833618967B6A3F4106C1BCE11ADE01189A151DDAF927ABC50845AAD8BDCCB784ADAC0AE98ABF74334A8B84C4410EE3395EB3EDC7707579E9669BFBA8B94BF92A6F21F0B98301CAB813376916F4325D4E625A4BEB70061131E4C49B51308088B5183F907372CAE4505C8618A0A7CB9A2489594492A0C850E2024E53C8400CC14D59042C894010D492844CA6200BC1010C38704C062500342D03B960D0B829E1902D590420124532A2B6455300019132858A2041C4A411A0B670D2100E24C845E3024D884042C9222D0A2710238151194346A39484E2303209196E9480088AC24863B820E1480A021464C43009E2302A82444E013004D91230C948322311724910641A084401B84011038052048C0144700C19048A240C1CC228DAB84C9C2232DC125162926141440A8B080DC406004816910A08860B99080AA950218749C22212A4444CD326425B4802C4860909188D24234120B64198442C50206C83845159142AD1A88C939469A1064608472CE128719A962100030EA2C2844318625BB0045C96101A27020B41481920911811494CA6891381615B084A0214250CA8686422880A934108A84114318413302021A08C02C8501090311A880CD43246C2320063802CE184401044500022248C3846018184A1440958C42821A43183B6849490700BC104941400A086491B088621C165D1400AD402261CB20023B02CCB9031E1825024478518100582268991C2519AB66914B40C8490811C112052486159866424C809199971A2B0614C3042A32632C1225020C0315B966521400DD3C689142250DC048810448D21257144A871229341113112CC40486032085AA40004068889068E9A28720AC149D3B2701A290C89B45100A644E0A48C60C26462426418931024900508274E08328622958558046008184961384C902888C13032A2B208C2488421A98D4AA0448CA41001030ADBB430D4A0695C122ECA986141B46D21C1899C324ED3803020148818434D11334C10463144104412852514322C040560E1A4302281900A8840A318841C166522164DD38284A0406210270E09B54D1BA29182120883C24D22B94C20488162105040C66523C908580882D03480124471A42605CB924182160A121131E38681200248243380A2185010B9459A947188346864B04C89A005044571C23801D8C68163C8404C202858C86D58208C0A2692148085E2A69104319202805062C8308B0289E14284DF5B9D1200801F9330A9C52EAF589FDEBB3943D768B4A2A73F38455E941B04AD502BD93D98B8F074A5206F1E51950B711724A31B8A5D5F93D1A62A60E3F69B6D79EE6465CB1792B991788C0DAE36D7A3E40564FCA01B1236E46250AEB52C61BB1E32BF69760B8BF91E1220307F9B4BDA5D36E782B47EEA703A636387CCFAE3A8A3434678FEA1534ADACE2B944F7649D0E271F520BBF249D7EB5334F3350D918F031E3786D6D544C2D2FD8B624D2CA3DF07FDEDB9D99EB3FC0144512274396E7EAE35E821787047F7E1139D8E432EC39737CF09A103AE25536097088FED5D1F99C00BB59B221EC99CC8E94329C4B99300DB5FE098397510D39BA9CF9C2D7B44FED381A9EFFCF476B3D46F9E07AFAAAD20F0F4C447B7B5F7E98E00594286977F68B1F16B62E5F0677BBEBFA7F4CA31CDF786424423DF47CC0FCA816A5EA563DA39A91617F1485DA0B3B48B33076C7B690471F9E232C63B85F746617A94576D14D1AC7FA2B0F4EA8D21B69BEE7838D836846228CCEF7EE6E447120BDE1C85BD260298DC883ACFEF197EEA08322EDD0FB9ABEE7A99784A64C2BAB8963D606863295492691AEE0C3A30A409577289CEC7CDD534C81A0E85AF6D09DEE2C2448411F1362A7CA8AD22CD3BACE899186F4E1441F007EE71ED53A0346DF06AF83A51899AA2AF09012363336AC70192BEF60DB21D16598712687E34D35CEA41C1FAC4C6FD077684627574ACEE398207E6272CB3B3F4D30DA8ADE34BE6485421AB0ED2889386724D52D01D9B398489E367811652D38556A4F93221E7ADC8E91DE765D52D18A6C57E090D67ABD7B210877354AC77317FD2B5E9F3F9A8221B008AEB1605AE9F1533979C01B255D398C7BB88FDDE165D2259989AFC39FAC51FCA6144F6F184905598A5515282F4DC86877F20C0730357997209A49BDFC2D683C7F783E4BE4C5C8C0BF760D9F465886FB96726202A972B6DF71339D3571AA24327248A67FAE26ECE002FD83180B54BEB6EA27A3EBACC4E58F85B698E9657789FFAD02E52D064DADB24C4573DCBEBE160D2F5424BDFCDDA0F1371863A1811D7AF30636B6BE554EB094C591F1238DECECF80114DF69CE5690AE12A8ADB99E149C079124D2D22A2D04EBE4556D9C933C677B8E2E2F949784B68A6B6A6EDCE89D5B46F064C8930E4EA0C7BCF8A0493DCA3A1E2B98BF80959D6DCA1D95A10C785505D406B08E1D4C5AD69189E3CC1B9C1C01735B5E977CEF1798BA8E56D3C341BF122C842AD16487A3A14785F8125C3437AD2D88AFBD6EA26C354EB4FFA8D0EA9D2F39446F3726AA4140564DAA8A1131DC2B06BDD85C80DBE94FD1934201A4AE8C7D184DFF38B35D7F0DFFCF28AB234313B666E25720E22F2A4224E3BE58F049FA17AE14D402B5BF6CFEF6A5FD39BB27A02D5541A475F3D3463D6B1C9DD2683A44C254D4C2765326322C9648B07784DC19CE4ACF2502A832EF41C17FDBBA8343AB0CDB442E7CA78CF755EF07369A454D35486C1199B0BA084551C5C8A34BD11FB3F96F0B9C8AB006562D1D35BE72BE6D1482EB09809965FAAFFB52EF603B6F6E7C0A1B54817AC49FD1AC4DF9E12261DB2032C139422ED2698B604604EC1F60486DD3324242114154BCD6A2FB1618B83056DCADFCCA91924E8A1E0AF120E56702DCDF8DB5D33869DB890A1A5291485C8B75F00A1BB731FC818134E6EA28A5BC1EF2DFD456642C1148782C6AE9512770A78692F05E4BE7E18CB6B9F1B4BC8CDD286CF2D0800AFBAF0924FD9D99B667BAB46BAC3C2460EF6F76F3FB0E8CD72A1D80FBAF5462D6749659B5A5E2CC75EDDFF0568FF13177257E29D8FD811A247BB3F5B234BA144D87FD84DF7320F997D098F72806AB8DA468B2240D4FA42D8E4BF786E619310BB680C059C0F4E307B99073691686A209756564991F95D0E87FEB1990F46868170175CE36BF7E41211C9DB9752EA68C629D367415F3B93E1D1B98117CC667BEF39D5A2613E540E00BDBECA5A7C6AC47D37BF91CAD1C1B0D24670D058D6E092B5458CD69FF46311A03545E6E87B732FD0AA36DB4DDC31AE9F24D2B56CBAEF3531DD75319A1ADE1D35E919161A0C323041D558ED600476149B0D260AF7B69DF0EF8E1229B8BDFBC6E30E1B5ABB0ADDF47E9A429DA3F89334A6C534D028E9A03E43C5E50C7FC4BC7F9AB095A00C2A6C0595435EE9FE191F80ABCBCFB66215815500E8831E51D78BA483B3CCF504A2FC6FD2052B8E541D0F25810B750BEC85A407CC915CE622B7BAA1BC8C192F6EAF3882660962FFC7F0419EC9A9A05F734F5C11AA3CF563311FCE4733EF5B2675EF0EF8B98BF4294E671C5E644493E98A1DD51F226F9D77DE8C389E", + "message": "0C6E73105341AEBDB88635ECEE0505AC5F28B7521E78658BD77C7D9091EADA31483F8692B3CDC65E961A5D340510983D2BCC56762EC2B7930126DE1A9F44D816BA3AFC86433178B59EE614D50C67B1B6961CD46901956B45C6C9C42B836544ABF0699BB7C62E5A0036570B9A077D5DC5526280E4EFC88056F1C3B59E32AF0DAA801C53692C03181601C43281EB5D087C68F6DB9010C4C743D3C7BADE455BC468D8F7F710FAC5BB2DF390A9B70B541EACA1FBF9F717E6A1772C4D2FE7300CA7AA7B3DD50A09AA7762EDF277B13CF49003AFEBEAEC0640A5AE0101BA7127A81F6A42E5AB9B57CD988CE80037BD95A378E7BE57905076E99026D82DD8A1365F6224AF0C55B5DB4E5A403C61D696677EDCD9A3F1D18ACDCF76979B86EAB10ED4EEBE979E3B717D1BD88FE15E20ED802BADC3DFE676251DF9C3EB7DD2D0B3DE3B9E5D4F57C21441BBC01916EF8390BBF46A6B3AC9EDAD323D1559B37D2C3D35EE7F64EFDCE1EB97E88CCC93A86233537669A91006A25DA08D39304259FDCE8753C27922D607259D7A72DD278D3A6B6E57B3B04BB490F868A13BF6017F6509C5B35ACE14D18A0627B55DA0FE0BFFDC843AB0A863C281E221D74AADDC2EDAFB1B71E8266ABFA61EFF1673CD96B2CFB34E1825DB7A807AAED9C48EBAEF8A1C9A82F453CEBE4DF5AA162A29DE715BA7B0913A37F9C95DEF6E3FA7735F6ABC4929F4E4293D6261ED8612EF386AEFBA554D24F87738B3117FAC31B62FACD3079A4F941898C6A8CBA80973EB0A490921246E534666040BDE418DABD1080B6A60711D38428B1428A8948AFD8316F59E2B7E3AC1990C4524D391202DC06F3C56A68C8AE1A974875BE6075F8C8BD79DFE6E4E1B0E5EB1F6EA53C6ADCAE7FA30082016D4211564EC468C997390F798EB805B0727F1775D6C7BAD9F4695BB14F5599857247658F906963F936BCB2CA48A995C68DEDC53C860458D2D1A1BFB2BD9F8649F34823248E93AE47BBAD8A2F9A8C8BB41C1940D59F8CCD957BF4234EA11F96B0EC4D56C45DB1EFDEB364C95399C4C6F4F050D2544062974A0C70E66E7261AC84F123F451717C04FE7D914826D6DA16526295A04D9487D4D0AEC83062A06D700B9BA02DB027299A90AE76EC154336124CE396DBE26D38251ED42B8B1C1CB36569B68B6CF916F9F93E881D85C9A6A8FC29E44D2615C72686F89944BA205812BE343092CE4F6FF69A09AC9318F430BE638E4BE32ECAF795FC84CACCEFB0F395C1A101C6781A37381D03181DBBB3BB51B588F5ADB629C3BFFAB8AD05877D09A2175856D445F637693BF21CF28AF25EA98A4239F9531AFE187557BCBF73733A2A0593000A6D45A3FF7258C8B4423917A7682078B1970F452762B419F9E5B9B1F4B65F2B9299B6CA0303D108983250DC9F4192692567F0892135A9B12748A7D07AF10B051ED86949C145E0A220307AC113DB5291B624A2FFBB7E040BE3881FE3B5F139130374B7E1E3588DC867AC0735319D39472C6DD1B4040E89C6CA4CA25F1E485E2765BC6E5D228F0F87D8A70E3544CE5885D73E3C1428AECF61C1DA70E2E0667F75E14BF38A1310755871FA52C3704BA13B3F82C59DBE4F636936816D97D771823B7A7E80E5F988189CCBEA639C0805E33F72586462A1E9E47231FD123BBD4142D5866AD9638B1383A3F56787A2C1A55658BD1AD92A5708A643D21C098D3C0E04439D25316E5EA05A4B72CB7B483DC68E3B7A4E49B194E00AB7D92803D56EF66F70BFB5795FE0D096F6DC7E0A61C07F6BE5E168839B8EB3F91675124EF59726B97D2D4BC799BC7FA3FDE9C8658DF68FDA182D9B0C28739CBC775F25CF84DE80BF31FC00E1AA979970ED80F7383B2B584C44A71D765668B58E1EE65F333D6D24F521F390D642D4712593F164EDF1BB92D682632CB9C3A2B2C2D243B62BCD2D72426EF8F3DDF1DAAF7150D119192B97D1D5021C60AFAF93EE15D182B0F245D206BD0A9085C380A4F2E302DC5DA1B8945593460BFDC3EA8CD2F4CC7472E4BDB25DBE82D1AD813B17D10FE04B2C8298AA9A44776EA49380999EB811B0EB61A4D32E3F6EE65C42D8DCF1EAAF8E5D7934F4A5A7E617C7EBE1BC94DF24866E2CF2808E4DC461873E42706C4F4A86502568B33E7FDDDDF22320F290E614AEC3451C4C70FFA3C63C73748385D84AF8DE82A2B98DE7DB7A7963702213F0E4FBB1D858B738291902DEF6AB19FA5741724544E385E1D6772C0C447589F272CCD78D6EDAC75A903DC208948FF513D7CEEEFD72A4D0C8726A9C9FA34775EB11976EFBBEE1B9363EE4FA25BBF85C6316DF43CA50AB99E1B8867F2811063F8A637DF0E0F31BE32B894F991C86995EE192ADA5E2D1D96912886207A20D4275D80180BF1AE9EF10BCC22593C9BE1243B0288C7A96DE410B2298EAD003C8A5411D09572EDA59876E0D348433DCFBF1FD5865C0574E6F8F2F205B189257FC5530F5F28FCBBB7AB9807FDADA260D71563B2B32CC58F9AB43ACC502A983EA0738D75A81A533272D3024CEC9F2820C5431D9DEF29990D3BFB29B35A6E8EBAF885A725CD67A3F4B352DB4C3A018BC367943BDFE490C347995BDD4B0E07854E1F3C4D786290B50022012EB3703368184637BBE0BCAEF746FD0AB68268C5F5E2054C7FA219D2FB2375F78DDBD6C15150DE451004EA8A9A9FDF674A5EB32AF8B0DC0574C183465E573BA56B564DD6AD48686AAC6076D2E87A0D02E9782A37C9E04EDBB2840AB9BA8BA687D6D205A8A2C9DF75957D0A478C8F8A7F7B3DD104DE127870FFEFA08DBEFDE7B7A7026272F98940BB7C094941504DCB5212C8B7A1424D893845FE31E2845C7EDFBE5B9458E19C4732DF1451684BBD6F30D224EA3CDDA6123C5A440F41BB20CFCE7195FFBF7E9E77FC059447558AE47C543FED02542AF074BE1A13F659994CC72769DC4CC812AE1ED578142C52642D4F519DA98D834738AABE5D116E9C74EF1132E7AC82DA351AFDCD704A8DD5AED2D089B06A49AB7EAED3EBB681E2107C8E2005EADB2434B600BCE6540C321B2460404022EB2B94F5FB0D0BE039DAF10051DAA365B135EE12F274DCFF3EA68CBAB4259073E261573186B71FCA37262BDCBB25FB99ECCF4AF0B32283425D1AAD1BD7430765B6AD254C738F35FC26A23576B6391AECC264FDBC8A472008AECAC1BBB4466D6C9DE216D611BDFDEA8BD438D42A320D1FD6616144AFA447CC83360A717AC1D15E7760A8C459F14D24A8AD60D214A43EB83B3C7C85A5E4CC45A66FC75EE1A697ECA64C7969EB495B53E607297BEAEE3C4A95EB1712AD78AAF1C9940DB544342BD2284BC050EFD4A4534E2AFD50D596DAB3240B930D78C037679C693E909CAA7DE357FF12C4A2605628F990D3E4DF475A0824A95FC21882D23B0F62B046FD9DE3210FDC97309EFE5D84CDAB904AFB47C94CAF3B2E80CC8CC0EE2FB0C3FFE424D389DBCE2CA8930943532A2C4ED87101EBD361956AD127BFF03B852B3AE25287B11C83014CE71A2BE21A0C553FBDC745196A9315879541578B28B646D4752450A869EA161E8B6C7FE8E92BAC28B2E7A78159A15E33FAF19B33A18DB86603140DC635072664499FBAC8C710783074F918E11D4AE882EA86B0904E60BD463446F9615B2022CAC8C4CB422448BAAA81E9935ED3EDADFC7569E758D2EF2815E1DE1181BAF91A0858EBCECA465EECD1DF827F77759E2546C7B45B76297AB6978F12A1101A992C016109FDF83375B0D1DF10D28886B72783EE2C1BE7FB7C1256E4023FF730CBE2B10A062F9D221472E29B56F23BD09B99CE09D1DBFC4B370890A71F0DA6584C28D24BA32320863154CA29661F030CB975F2A89743589E2E552E27B6CF76DE9B49BA5AFFF4468D42664D29792BA0652F477696EC41A10782D240E9B163ED7F7E4454068433542F0CDEEA394ADA706E3EDF8AA34EF523EF503F8D5324536B2D9F9804EA9ADF45BAEBC58C0F31F1461025653C1D908D18832EEEE6CAED3FF599ED1C2A91EB95D47BFD1A31677952DE36097B9219EC5949CA2AF0806E5B42D41C2C05621027508BB87E2977D9574273AE5C410CC25B219E502C51E1764E52A574F488A9ED013B77163DEE3A8BA9751C0B67CEC000B6C9A5D5F2634B9E66C9A7B9B4204E734EDB7D1D41C38B01F791B377F04840F50B599443FCF7C87E58B8D9C9EF321C5DEC0D54A7C3CC594B0CA2CDBAE2A457409297EBD07E3B80A38241EA9B0F98A3C44C951B4889D28CF72A137E7D9A4ABF4354E96193F668F30855DE7950C4845E8B206805A2E7AB29F32AE2397143D681FC91AE1F6D23C32D523802F4B3C6B7D96484C2541C4651F17356845723BB2B0B4A9140079DE8E34D74844CF3D81F80788206F49C4E21123C984B07517138B19E2BDB13343F39DF592111762F83E93D7AA8F690D55956E65EC57F417D41055FEAB3CFDD169A286F13DB4EF3357FD8BBD9C94856D023646E08F1AD5DAE4CBAA71447F5073EC306C3FEC6B43AC75FD80C222D8E38E819A6E0BB0EA11C5D2735C71516520D8BFBE9680131707604207CA90E0B84E314D0BD67548103282C07F56F3DB85A4409E617A711A208A681FA62BE36CD24539672806F5A5CF3A3A3FB0A09D8F27166DEB377325F1B56944017C34825A623", + "rnd": "18C6283BE2D43153FB5B50808C066E9EA643FCE4CE79381BC09A3A6B9BFD7A77", + "signature": "354B6997A217A97653D2A70A82150F2E8D2450C52277C117FCBECF8AA39DF59E0E1152C6E70DA27137DC9D29E906EEFEB76193D1ED977B33C00F54180127AD6DEB19F9C45749071DDAF8CCE1376742E1E7193212BB30EC6144ABC486DD17E5DCB0C7BB3720B2AF2EE48016ECB15CF203B0C7DB1380241796B2C7B33F7C7D84459AC022E90FAD4606F06A31955882FF85803F8B6F72E738D92D579C54ED5B1DB825056B02A9BB936C6E355AB1915F1E9FA0B28DBAF09A398EA5BB0069F73662B982D8B69F921311EA9C43743BAC9C2166E3A3A4E8073C18A367D16F2B8858E0A3E04A77A0F24E74180D220B7B4B1736957283D0933F845D249C1DC8F966358594DD9B4866004F7E3AD57E86E1EFEB25FA427234B561995E13A8B974286775E8B8F7F1E71B2975648597ABB15021ADC016A5F58E3B8A84328936BB90C93BEB7F921A56A033029CD67CBB4E5C2484121F5651C486B311E356BA423C2DD613ADF25E8CD54D89FFFD068C3FBF853914C76A3A8B35FDC27F461F46E1D22757EBA8B8B23F050792360F7743F8762D0D0AFAD4FFED7181EA6B910243C3451519A7B8E90D6D124E23D4E7DF5D0430FABE663C642124FBCCDF9B294320711249D37FBCD44EC1CBA6F97DE385B8F5B57BE3615A098F36416755EDE788A61E0124614B7BFDE270B7D278296860B20E8D83E768350E00E06DDC6F91303A3D8201973FB10505E2023E0D0D2E9FF9F33CB0E080521C4B0AB8BE6BD9B0E393A6CC4D96172A340BB110E58C7E19B9BD1901C3D8B24E6C4F35CD71B6F30453BE6F8348EDA88641820D4B1CA22E9B7FC873E07F7552EFA3142B698D4D3D3D297F6D79DF1317F1847C264C139EBA1D3978305D6C5770E9CEE52E259A2B4D716AD60A438FC402F7B12777D23160E42422B743E08ACA6C486AB096D599CA1611A4D8C60C3D7A7E6E23BEEAD5A0FB6906883923AFF4313AEAA7E6A35123BE5DDEDE4813EB8BD880064C452073A673CC23A23A0EFEE6E328EE788E82C5F85C49C7372DFE710685BC00F8236781ACAFF3FFEAB89E2AB9D7691DC5D569DF75CEC7416ED407DF7224452019A3906DE08DE7F0886F2ADE2CB40720952888EBFE5B689EC341F3F238B64F3858A1D6068B61F6F4EAAC2F675EFED7C7530321B29BB4FC4ABD0C27919950E83975C723AE40D156FA177D50DF2706D8F826047670EE1AE769346AB9C0158CAE1894FA131F7F8966A7223BBB465FACA490AF9B20103735656588D1EEE485C7291D9AEF2E22AB1E947B7542F1410C40DAEF74465F65156BC7E8B7C195F7334D045823F6EE6BC69A007AF0F2153DF473E6EC29604180BFCC7A22C2C725083F9D5C77D0333C6575EA5C25253013A7445DEA9FFBB7A85355A3653A78F7EFC7396E6848ECCE8EA5B4FB19D0D2A4F46FC061B4DDDAE428CEE9BEA1A05768342D74B9D73F4A6C8B627D24D1E389E51A29D81785E49D153FCFE855A3F16D4C205AE4E796DD30A84FF2AAC4338DD7B569F5B183F6FD85D85E144FF3E5154CACC5F1BF569A626F9C88D979D9D8CB1E0A4315CDED3D4C0A39C9A34BDFDC64D89CBB0DD39A28D1C3ECE8A44078953DD62BD90E99D42B5807CCC7BBD6319367829917B199ECB748E4FE8856C978025CC4B941E50F24DDD47B227A31CDAC96D387DC873136F0ACD24459D61BF927132CAAA3AE85F48CE9FCB5B4A55F49BFBBB69E1406C06459BD560183706DC52B3C8AA74040A52BC12BBF75734DBAF5084D08F6E65E2D2946BE8527C958F8BD541922BBFC99F2BC118B0139350A7E5FE2FA235FFD72E07232EC76C9C959F15AC4D42AF6C42C9E73F78AE910C8B08670104DEF9115415A0A8F790F8DD471958AB30DBBDA2033BC5F1F9A54D8A614696DD408CD1972F7690AAA0ED9FBA564B07AA0526679E2AC1C09E666DFBA6206285AE8A5A9D093DF9C8A881C8FEDF9E55C7CE6A8C9E5469A7E0A4E52A12C514EC3D7E33A6EB5CCDC3470E1C1F434D69D0780AD6CB1BAFFBDCB9749EF0E85E17E913D0BCA91FD01E60F21D7E3B75E9C79B5E9CA05F03685DD12E9672BF9E3C1CD86896D5AC4EA95E80AB1C3924E364361B82424BAAA04A5024C22F3569AE14B59FB3E1A859EA119AEC1415E42547FCABB2DDE1FFD96876BFBA1C7F349967272EF02DB1A3ACC389C8A01DF90B6CE90566D513EB99060C6994A7377FB0A9E2DD4C3A606952340713631A2F1391BB13D45CC9F9BEFBFE0BA4D09EDE1A1217FCD42D14C62E2C1793941418EBD9CBDAC461B998DA2B0D7FC9B4143857BA429C2ECF2E8BAE57C01B697F7AF974633057DBC314D30FC1A983C21D0863B1ECB7B149C38BB453A0BCEE146EA8BCFE3409DB22FB0BD6195FDA87AA53344236AE48CF6083818FC104A9DA37AA21A3FC3A50372354FCF44762438C209F248D67390E65A78BC6946CED0626DFF83904EE6CC88419B0F055F978FCC05F471E07583A6499C590353BB21D9AAB1B3C0CFE91DA8D8FC8837AF49727829B60EF4106A8C8FD2392BF18C0075AF1E0411B6A094402901FCDF23D830F6D3D544A7A610A571E0364274A782EF8B1545607B164AE772160523F56182CD1DEE1709DD999616A8A10BA81752C00B881E00355F437A659710CA1C6D67764CC0582AF29E7572FEBD8B242EC7B091C9ADD89350A9C94F5E1B1C799C8E5C88EFCEBC8FCA25A2BABCE39EA39F75655A5C6D311A09E3D93AD02D10B162B88A07564B3CCFB72136B9F7E7FCE7764B9CE5F0EDF5829C0D48E026830EDB5B724AEA05ED4BB1E47EFD44E7FD1FE18D4135A608115467B9C0BB4CF5C0AC555D0109E7C56FB7D1505E1557944F847D8480AD7F245F929198E433D855D5ED3C28934D6F7508A2261E82AFFF1CB2831C7F4637AFD52166D32EFCB7FAE0C66285101916CB7C9FAABF8C3FB48E6830DBBD19A10B332A59C23E49FD1DE2C232047C277846D43A52D2848DDF9A078219BBEE538CB5637124E90BA7D09CDF7F631A4070A12A1B39B35B0C0E0C1EF5D9D12719315FAC2DC2056E23D1ACFB4B115E332BADF39D8588300E98D7EA6C5D2801238B5B86704E43D455E6B588635AD34304B226BC5D29874AA3671E2D1693FF811A25CF56543AF7698F2D25F3C25075B3AF3B60D92BF8C1AF3BB3416BAD3763D6CBE297816F51ABCFC7F783A59C1BC5AFDD8B7D76611FDB34C374226AA8232468DA0078CE2472FB02BA697E973E277A836606AA57DCEC8B790BB711F3DE664129D57A4D559E87C9E8F0CB6E14396397A57D626295D1A58E2F18BE0053E0A3F670458E29F0C8D63C5C8295F7475E527ED53B4B1F651AFB0621292A323D62696C6E7B818A9C9DAABECEDFE81C33555F778D99BAC3DFE104070A20323E455657727C838485A4AAB6CED1ECFB0A0C0F1D2431325D6293A4A6D7E1F0F8000000000000000000000000141F3444" + }, + { + "tcId": 15, + "deferred": false, + "sk": "5E181F59421C79C6FFEF9B953B6D30204B3E4DA3D6819092AEC045B41F80C4C9D9D1738FD1721CA9F62CBD0D5964842B17D95060169E19CF5AE4E0403D5534CEDFC2F9F939D3E0E48FD4DA0F400EA0D6457342A994C79B2AEF4697CC4B85342A455EE819EDBF32793C274CAE68B4FAD56395E72964CFBC85EDD729867BB310578B24108CC80583160441066ED946690A23281A0701C2A248C112415BC81149249023A82CC34048CC122E09390CD19241C0904811110DD1444C1B017124272ADC10429B1226500892510046C126814BA0704AA0801A03201B86000A126948082499368A5248680AB03002B230630892011710634229A1184C49A04CA33821E2B62421A7451A395119180893180C80322521044A03267122026020252219B3809180510A464E11062D439690E23008E0A20DD0140C182328CB027119A0495C886C12194DCB84010C1412E4468C5A9864C24832CC00050A442818B24CE182804812310AB384D89604C02404CB266549A209A34490A0A00C58B20483B8504C942921024682B6291A298440C08DC9040C0040021103221B140A42020910040C5284114AC268A2A200A2C82CCC323019B10C0C2532E3808914A46D824608E4486C59C86C89268C241048C30249C90882CC248C532662E0C2885B08660BA36180B8401482611A092121C68C4BC84C0BA8458146201B476062288D63C63088B290D2C464600666122286D3022E20B3400B088C92B86D8286898B220E44468613228DE3A4854CA24CA1A0205324081B85281C90400C3242C0B00D021162D9380DD8A425C9C06504080059A42151445142A29108846514122DD1C28C5C32208394086200921A192403268522969162162C1A87899944088240680C363258042D64344C9C444AE31441A2A8448A48019BC200E09065DB184400376CA22801D4367200C98809C8504A165143B868E4862100290CD1B84C5340815B96085C102C6214691C110C844886D4822D4AB82D80A66093066A5A90318C008A10B76411B40909256A1BB0241A124AE2062C1223080C27325C244D949889E2300C611800920409E342680C8290DCC06599382D64142E501424A400299A268DC992810C452D8BB821C3A63098182A53167250022C8C422DDA164E9A3662A3B62903227024416EC444410C3888D43086114665D2308E1909640B254DC2B05052A04124B0881442460A1469D2388E9318849198919A944980022184A04D14218AD0B04D21C55003482618250ACCE3AAFD236D2AF576B6B63071C8636756BE3E914360417EC01FE7A83D91BE70599633DFEA09BF4CDD8AE78935ADA69A47E7FD0AA7925E715868C9EC5829E575730DA04D35F998ED0A8B6EE5A810A6FC079FFFEED7595B68FF6D9750751BE64816A43883EB316A289790785FA8418AB2DEBD8CBE8DF388222275143AEF538F36D33BB6751B011EAF366F6BC564B860BEA66AC1E8281ADEA5B3D8DD2656A6FB35352ABB713A14FEFA311D6642875F79D58C05914B668A28D6F2828C9A3A54A733B44B34FBEFDB7E2491990D7680B263BCCE65AEF902BB4EB22C36FF388F8C3EF1F96CC97932D65EBD3C9E2E950C42B294823C40F3E3FF4749A697DC4F680F7E7B94A8217D6A676D6BF0A4EF67F51CCF9CE52276E664D05664735E442708191177D4448D746728D596646D9C8B1D0A64F1D62C4C89A960D4EDB68B7BC1D1569A93C7D8645FBD122CE6BC279731129C9F4448527201F01759B4ADD1ADD8A675B8C84E8CCBD95154FC5FD76CCDB1B46ED7327E9089D52A964914A07A158033D6755B1DEAE8A796B756F1E0FFC54F08BD5EC96FAF05360C8DE66830D970C0ED8FA082E1D9E2FF5AEF2EBD07136D860A48E276DDA8C60FC46ED97964D27F6B0C47506D6E11616B7AE1DB89B06874D602F16B3882373E3B9DAF8EFCAB8C210CA8B4A02564EECE03CA1CBE0ABA78B3D3E24915D0C4BBA388D49F2BF8EDCD36742B7A5056DCAD76962CA05C3872528F90A9738240483DC8B3F1A0E3EB68DB87ECE64322545B0141CB5C1CA018D4E6E9529F1248C837E69FBDCE08FFE6F863D6BC254665EB79A2A71A5165A969944A98B4C4D1EF46B767869AF5547DD64C686706E3E3060958F4628F8062340031720593301BD155F99B3ADFF7B4BACE580C4608610B348B26BEB84162CC0CD1B8B98FD00C8DF89E2777C914A84E8F7725B78509581096457B8C28EF72E818AC92577EE3C3A3833DD076B1B392890B895244A2DAED9139BD76D683DEC7CF4D6AD6C32E72222E95F213A09AF903A98B8313AC747702F00830C8665109537B700A2E9D3832FFF9C405D937B4A4877E47D09DC08F583F6F09D629CEB0E26CAB114BFF591671A4C2F5BA1035FEDFC7741ABF2369FA275B9CE55FAD8EF00DC9AE5AAB8AA2ADB8DC8AD1AD9AE6BEF77B82CBC27C36E7B84A60C7D5265AAD26B567B336CBCDA50D0F5564E5288345E9DE3BF141B022F02172641EF29142B46ED1B7725E9F36A52CFF3C362B6F61305C15822D0BE476A226FE8DFBF5083CE07EE0661ADB64B8DED8707AA5743AD2733745E1A4E69A2E0FF897E5F37C0E1F88ADC8D34D2CB9A1D6F35B4BCB89E783DDD1340F2A2748791A9372CDE4632F5DD82CE73F2D0D2EBBF202C9997D2BC1C523553909F1D21DCDFEC14B37277FC5AB9D40E3B7EDEA01C99F5E1CEBEEE8DEAFF9F448315A3C6EB357DF81AEF1612AC7FE4594A087BF5BD3F1A27CB71A4637F7722D97D36DD12A467292AFD95F0F3731437491850847C0B61E553C38D257A87D4F5B302A06E65B6ED439559B022A7AEDB666E36803599DE6A79ACCFE0A42C3E5874398F7CEE63D62E2037EBD77E30588AE71F434B8FDAA771B3C32174DDCD5702417E184474BAB7D8EAF7A8C7FCA6D53E5ABAB7B5351F30A1B14C0314366ED508BB0D2B7E5307EAED993CB72A619935644FA9F376F47BA8721A1A83BBE723D54970A46179E8483ED6724B3FEE6D03CAB17945924F082D9045140CA42B1CECD700DA1BCB45D0F2D971F70A9DAE27DA83F722053FB18A4ACD25CF242FE0E5733B65B751CA44DB1EBCD1EC0159E7BF29A6762D287CBB1F813D45F7839478EC1FE1929316FDC10C6E84389115FB1942A610F22950A7262EA2878603D418589674FBC0C46E4E6355CF8D25823654C9AE4F6E973BE09FC668D1A08522B9907755DC9B4FC0745E7088D56A519860EA109A207FE1A4678AED210BCD79F8BE48D3B29622A66A5334E5373C4AF3F89DF199F71923E23F964BB1ADB0D5C57591309FCFBD1CF8EAF9706DE8AC1907B137D78D19764785889607F19D290C9F231BD992C2D16177EA9F1B7C45A06941E47B441C2BED87BFA54477FDEE1D5FA1C2FBAAA2285BBC25DDFC0397332330C7158244424B3BF60DE15697F3354BEFC7BA81542FE94AF3359D9864E07729F2A583E0B28C99F09508DD07A81CB60F7C14FCD948FD3D61A5D23641C38CAED49FCADA0DB2F027B2185B55E65EC9ED32830F1F509FB95F3E89F63653E86A9152EE5A7FDBE479922E3EF5644745F7FAE3FCB991C47689C7C62493DDD17EE4F62F7768C85F9E2DA9D0070D92DE0F9CEDA09BA6456EDFB0B261C49F7829B58A771527C9D4B40772338", + "message": "D1E02BD099A08DCFE55386407746102C4998B74CB6D2FC3828DABE3DF057656963B2AA25886F9F5979060705D083E6CC60DC4C9CA6816A7B05B43F38FA07D5ED5856C35D12710995355DCE204E01EC6812B944C644BEC02710BC969105D4B748275607BCEBF985A5A3905A66A87B389B45450DB24FFD436013AF579717AC2690C4779C879D32AE1F6B94C4881ED4D76853AD3E2C657BBFC4DDA5EF9A19F03A6719793A80E38B498472722D0EC12105034A708751144009FEF78012E7B6219298A386A923D721D8DAFE536C6E7AB644F08CA6BBAB88DDEEC39D12A1BC6548D7DFE1A7C5061192A9051C0F2E0203A610983C782F8E007340688CBBB68127F4EA2D5670158B4F8068BB35BB1EC9467A7E5393C8B150762D4FF63315867A4EDEC13AD9757D81FAA461EDC8A5BC5069737E1335045FE92FC3A3D3F20F2FB16E3161F10B883CC48DB357F3B2E0131901410662C6F5ABAFD0CDC215390A35519713CDDCBEBD916FD54408E1B330B6F2D9DDDE2761C6C53C0D20AF9DF8120995950B2368D2ECF6DF6967288C31B9CF806BBA2843A0CA5CBA7CA0C9B49DFBD6FED1399A83B021AD02207EF2BD8042DCD7D44C99CF11DACE2F8ED48A80EF165D5C25A9CE0D90A4CD048A391D6FFAEB8E0720B8CBFA58FBA79F472B287E26373B3EEDEDA90F49FD8FA047F1CBB879165AB652B1B72A554B4ACEB8170B204415F555F2978555A2E1B8D7E32046A2CA60B6524B6C931C8C2ED673434BF001D572C18E9395193068A623E5CD43582BBE8D1AA919E09205A389EA0BC8EEFBC6C7851B3C4C052FE40ACF33DD7236A576399E613E12B886F0AE0D93C37A23009C83961C72BA92CA20CB2C619FD14113374C652EC88A7F5CE3F7D6CE1626FB116C6F041F866EF1DB6867ECBD6E9B7EC67D23B9BE8B8F70A0A31C8B6396FA310D899BFD1E98BE36F10AF0BE392B22796E5B6CC8473384AC6A8E9DDEBC5FFCCC26A117E0E80AD933456BED4338FAFE3E81D9EA5F6321D2256A8308F7CB04A2DE4D29B83869A45359BAD0EA1A58EF30728669E25F3D49F6DFD981853B64940330864532696C84A7643828A95900ACA6EFBF6D8CCF342824809225BD10088C82642AEAC6FEDEF0E01238178761CA890596928DC7E6F82D1A4C4411594C96DF7BC08A74E30542387D875384FD4F756891EB7254F0844C0CD80DF009375B7733973566FCCA5B7577EA821214F3D13A0B567C6CD0802E15E2BD55CF587D2CBB8F9B4656375BCBE4FEBCF38206660961A8656E36F3EB137AED6DC2C8AF5A316B6C89791D5479A07A8C6F58E4FB1B83A48504298AE8994408B99BCFD8D5575456A1EE9D890B8F66D1EF57CF37F3CD16BD46982003B0D3590A1284ACBB4B90D15CA64CB111D8C93CA608DA5D42A3578D66561B68A7B4FBA25300765348356EAC4D99738F81346DD8AE3FD4FE53265A8066CDE229F7DD6BCF35CDE67FB1777C7A062D839D24BD5B4880134512833070398027CBC5AF74D9D136974CDC7DEDECF452582FC35FDAA83192919DD1AEA26682AA636C9D6CCED236F1E377CCEFEEDA1DE5F4B5EAB31A9CECC5379382AACAB4AE633BCA570BD1E80742E3DDFCC76E692614489C6351CABE74BB786F55D61519CEDF3F3A5814EF66815706B5728F5765358C6A98C49994ED9E94DF477153400EF8556C532CA3F690AC0C36F73E68535402EAC396E50D6E3B326BDD4EA59B73B84F451DC5E3594FF8224FA632D5C7597BE285E2E50B8F53161A50AC7C9B19E0523F0BBE98E435DAE4CFCF263824888CDFE7796786EEB2C40DDD02FBBE3E1EC74988CABB61A741F54A0BD198D09D3118150EEB9A6362681DFB6D65D9D980E5B6679FC36A3C9E9ACB82DCC9EE0BAE3173B7DC7BA3F586660CF2065AFC72C3D214FADD460111E8F491B2E020C96E5B235569D79DAC94E094ADA0D453312F4DACA3A638492F039A4B54881083893407E145388A491E67794D430D499B5C3D7DA1366955D050A15CDFB2F60425E123A1F73C3090AFD18315F87789EA8BE34C4159AEF2A72A2B4312D6E75CCD345FF0D62E982CE89D972C94DE9481146377433B7F2A6416B852392424CE28DB6662AA798CEC62CF1ECC6CBEC4AAFA645068E1FEC3C22FDED97DC290684BB40956F03FD8F8D17C447606FEAE093E937AE3A170D9D87ECCA53AA24B0830D9D61D7B75FD5825DD06C041B97D8F6869812485F2693E682F7F534964B5FE92BEFEF39666188A63196D4CE0D90957D11509F0A1DDC62ECC6C8393FF60729229E6994B114EA5725A22024C2136AAECC37EB3BBF6DFE52C090F423BD872AD65668F838AC5CDD685D100CF8609D03E0EA75C06ACC5D821AD715F18E7D3767229A90B1D5F455249CA2B7993188C568B22F715B14B9C567183EFC8DC0E9801FE65195CDD95F2352459A8A303375B10764E6EB1E9D2DB8C8686A110956AABF16E2EB0EF2902A4FAD3E0E88DD823DD1293843388000630AF54435F818FC6160DE680C6E049EE95A9D66EB719812FD0E50831D6AC779271340FFADEBFAC7A698BFA6ABDA808E5436930AA1A723B3FAA32020BFCF9511077A328CFC58D58C654F1E0F3592C62D2F1042A27BDEF369A04D4883685006B4A7E53961F7BFAE96D91ED99510C3F143269880C6843CF640DC3A3C9AFFBE9B4EE42ED336D5ECB5BFD6C6DF721FCF93ECD84832039EEAD37B1C0F4EAD6F756DB880F964A4A0D98B589C2FA157A812502AD7AC005D672C3848C38400613541DF782E87846FFA7B88E8A5A93FD733A6FF2C7083FF4EFD8C3015695F2039C23101CBF6E50EA73EC0AED6EAFDE9A74191A7E3BDC292471DD65D2D2EC330994273E68F507168EB9ABCFF12CB1D155AA96EE899F862ADA8C0524D6FC099543DD379E4004893162A3BA0566B7B62996B362DB682F1041336743F22669B948BE1186A75647", + "rnd": "0C58411DB0217112E2223B64145B2606A22C503408975A0C0D23EBF5373C1EB7", + "signature": "E1FBBD4D3C6891FECCB9DEAE43F70E39EFCC59174D2E0C10B2487173D1A841B0B43AD7D2D69F56C89EDAC95D35DB4C3E9DD43517CA38BD4E7222730CC2EFD153A2F3B1EECD54C3B96259085527BA7D84491EE50F1B55126D88DD69516BCEA2B611441FDD32537F08E82FD8C9314E88C671B6DD8CCEE4C209D7BBA6AE12D03FF088C4B24CDCF148FD9525285D5E6D38DA573F31019A7C7E15F0BD238C5DD3484168C888759ADE653DE6E728166383AC94536F4BE9F2F82AAD2219C39B49C99BA3845EAE1DFAD5F85AF6584FD846F110CD88C8957C91ADC93802EE271BB530F2252C427EF3A99F6F903478640DDCBE6EF02788E4B154A8AA9BDD335C60465B7C95F992BABD92A806A4F7DB7E79BFF19D6B1BCE91A204E5FCC06DBCC880413C38B17C3AE25D997EA90183BD109CC0E091DFDDFF704BC4B2DE7FD34AD57A416ED4E97708E3CF753390752B2EE4B50B35441518BE9FBD085BCDAE84158D42E5D15027BD3D4CC2064A49F0A0131922E29127D1A70A326EB081FD0D3B31F2EF033D51AA8E25DD6C697ABE66853987E842C26E47A5E966D4E1E28C389D0CAD11C779E3C5A2226A3FEC122BC43E14A159A1E96D7C2CA4E5E490F35C7E28245EFD69BEF49EB96553FE5EA8974443F017167AFCEA1B937262008DC0566C68FA83187A8122A9DB77F7D48C3F4F74F6346007F88C1978ABACD2E3AF8201AD5D7DE36581B36B99DBADB7D292151AFDDA904596605FC394F15E77BF5D42EBA7A3018B551031099F2B865876B4EC9DEAF4128689761EBA75E68024AC789E3E6520195DFC32CB3865483C9755C18C8F32E0EA82538D7D397FCBA5710A90EF1FB69449E5E2C69B4F394FEBB9B11CC8C0658789EBBAC6E1665BA51E134B48FC4FF90DB5FC56EF46ABEEE80659972CE772E4585AAAC14B84E75FFC701443BA9B117DF936947D632592488F7D9B66A30C7869AA14998F1E0E74A055F7176DDA9832A80AAAAA4788C4D16D9EB3AB26C1E68A1F64C4774EA5FCF4C85F056A786056A4C23B6776CBB6D320333A285E98323397111EF7921B6839E07138D2167093B392EA673B55CA5F06967053E726AB723ED03C08B9F20BB83B7C1317C4B0AEFCB7901B7AB6AB84BBEA02152D4B521523F4FA00A6BC5D12D478A12DFB0029C3A3F6532E62E0E50F7D06A4B384C0EF01906E153F5E8D4999B660F51DCA1523C158E398DA9AB146D20E0FBDBFC4F815C4E850B2E3FEBC082A5837ACDDD6BA233A9B24ACA1FFA3D2E56D7107843442278046984AD9CC683486C8A0F16B63E4ED0FDA2AF1850541DBA2232564C6696BA18C4ECB73EB84A3016ED1E69D84EAD3502F4E68998EA9FC3C59AA31D7B1FF134FDCD2E7BCF1FB4B99F576C8EEDEB710391BA08362E0A2CDFDD9C633B9884B24710BE34C857DE17B744157A44F711E38F763D0DE548FBCE0CAAD61772C75021B3227BA00CDDF108B036C2F7AC584D76C1B2C5781F75B90F8646DD29C587555A41340B72A1EE4F66C72F0D2BBC9193925BA22CCD671552FD3CA1579F7658A133AC2B585E89DB54AC612FAD32BE9356B81ADABF2DE0BE6228440B445E9AAADF522D5B55A325ECD1F52E20B1622058BA88753075ACA64C2FD771DFF85DD579B41AB451295627173FC0E34DC54CEB925E83FAE2FAF51981701B97E6F01BB4A240A82541D0A2941D9FD4CF6F93A571C874E2F238D0291510DB947C35E4E0C7EA91B66B69E390C7C5286B410CA91E652F3BC5798EA47FD63DC22BAABB3FC6795BE99B3535BD7A590216C97F24E11666670C080044E4C78CE25A793C034F2D3BD9713F3038F56C251F61D2D73A33E3A964AEE65CC3C6614FE6CEE803047599BE721A0FD18BF41190339CBAF8D6FE016B8D0162099BDE0C24963FEAFA9756077F1EC61CCE0CF410CE4CDDFC83284075D68953BEC6162B03756202F943BDAFA0DCD303B92C704B73994367E471C47F16CEB8697D97E52021444FD0D4EC1236930AE0ECD758457664BC08B2110E8AF421C8FE40FE9FC71EA3876B02E5791245ACACD5A2A106C02F66E7A44DD0C5535B19ACFE3D1D0DB39168089C3AEA1BC57F84D0647F07C5EFB1A88588E067F92BD80E4FD914CA38E1F89E91D4F1BBCA217D32A2741BD3C120E26B2FB6CD5132EEA33469E684FF1C425C95154700D0DC2C0764F76DEDAD0BD79587848EE34D9374008A867209D4844A8D56A1DDC15531DE2B6F4B978BD350AC03EDD4E2812360ACF40DC3BBD06AAD03F6F48515E4D773705C64663897A056CA4C8D85399027CF37D76503421F9DC64FB5B4FF53C4D15DD625D09A6B2E5323D6D354079DB0B0CD75EB52CBBC640C4AAFC81C9DAE43F85856DF0964CD40EADAC97D420D30DEA230F72EF1646120686A4141E3E5E3DFE308CB55896626BE46DC04CA6F9BC5307357B85207239528A7CCA53E1F07DA6D21905E3041B4622B2C598BDDE031B01FDF12086A8C9AF1155E1D9B725C3AAD8D5FA9378C9C69CE38C06E815CAAFA73B02A7A0338232E98685EA9C4037A50EDF7721E5B4CEA55732DAEB31FCD9EDE620111C7F5DD4D3804F1768496DF4BECA3D2B0E387A9B9BDE4B09A08FC435F0BFB720F20404DD92CCF4EA7EEEF685D019F3B7B872DDE13E07FA7CE3150A1C887DD70337E409C9ACF8EDEBAABF29CFB9211E2AF2CA7F81017A513EB400F42BDFC6935E7258949A0A985F2174316C4036541A64EC656DCA3A547D99B4E6B2D226A811B9DC0547762FFF262238452107BFB27BBBA14A6C1C3D5CD893BE510161AFBC0A1CA294B2E44A4A4911F0E911B4B95DAEA17659CBCDBCA5832992DDE4F764714DF49D00D447456BFB95F4C8C0E3AC081A32B2AB5947F4D3FED59BE524FC265417D58EB95692B3F4B500D3FEA9247831E4E576318059B36E799AD9EBFC0AF32C420C53B506167360730CDFD4CEEBAF9A0BC3B2622CF16EEDD4980FE778666F8D8A7D99907C1372E3331744A995EE7AB0B81799DCA2E1EBB3D085F019907B163FFFC2D98371F80B981F86166BEA20ECFF693865BE7576220B9FBDA4AE96C9C6E45F2DC779683BEC6C049956E97250100BE96C6B6B80C5612607A82D8829E11DEA33853BCE0E2025C755EB95D1E4E8CA133C5773AB011BB002D9B3A315F49DB216316AEABB4ED866F6C32C0F12C65B6D952E13FCEF58C30A28412A6F9E231597651162CD7C75EFEAEC60074DEBDDA88CBCA5A6DA5CFB8E8E739E9AEEE5731205EB46B802F138FA5807C45467255BF859A9CDF7300219E18F827C5773EA5A173AF76E4E15F38D87DD000C64B9D1124C5DD5E1BD88EA86D82B0F22010C2542444C5758595A99A0A9ABB7D7F31C253F4CE7EFF108334D545F6A7A8594AAD6DC03131B404B6573767C9BABC7C9F700000000000000000000000000000000000000000000000000000000000011182432" + }, + { + "tcId": 16, + "deferred": false, + "sk": "51CC34A2EDD9C92FEC31021A0CE432BE3E2649B1B3A5617049F2A6F050838EF2F54A00E61DE283C55E912503EEF3E7C47021BB0581D3FF3D89B8BF50429DA880404665CBDE6EACFD0D1206354AD32B5E2E9C4F819667E251E49A10CE9084CF757B92A2E66E3F23558F9B6694179B5E4C0514F8A3AE3D41B65848F91DACA82340113312A3B6515B36288A8829181522E4344C6230015246650C3672D0108E4AA88088842114A945C2B0912034890B42316142720A0824C382499196301CB80553166D5A16511402829A329120A109DA000DA148012116126110921211469A10014036691C20895840241399119A92714012481B88081C10118B20864388699120024CB08C840221A1186D1294455082818880701C170A18270680060220920960008113076E8BC284C1864C0B9129E4026D80A21021020024168011398C1C4224C8148088A0005A1850D8A2901C34462148725A42499306309CC46C92006A9CC644C82822D4344492324662482E50046C1B9905A1A6514C96498BA008534071D1C08091080D1CB64922172410376C23026992A28D8A460143480AE416521417669982218CA2488C448C51C4250AC20904218A441432D926641142721C977181C68521B8110C37691980840B2432A034281306008438044C0090CC38911AC81193908C11932023392A63020460C48D50904D9CA8455B90111090505A487200172598880C93B45109006E0233920805520382889B020DA4044860002E51000600174E09B8718CA0248BA010012921623832E3926824238E98C20503C5491091491235451911309B88685B8691094231E1B04DE11261E4364E02062919422023126620A2685A308061306A1B87600B854D5BC8701004311BC00CA2C664E4220518A72063C0311419505206458C204E93A021A0226A59921042268CCCB6859296288B3022230861140240CA122121B468492251641844D0104ADC428D13A485CBC468D1100CE33809592066A3082E9C46646228419C882909228CDB982198040600B0699A002ED4468180B8680205702406520BC06C990282828084120272C93684940624D2460A0B284D98422A82300ED93004CC12880295890AB06C52824424C045812289D310464A1245920831D32621E48071A0983014168643A00DC8925194384C40400044180100966C1BC48110B28453C4089422605442851333922041058040810C172D40464EE2986111904514B164538068E12250C2C02C1903505B284EEC2A75F8BB622AE9EADC725DBE4D0C43619B9477A7CE27F600A734FC5DC96960F41D36115BD187A3E169453A76590807A1DA57C02FB173055942356E879B178626D137DF4D74381384703B96E913B37C5033B47910D3B1AA949379E8FD38028A01AE41450368ED4794271901D3A70504E5CCCE06F1063EDA51C768B6E6923A52C6A9CF468CADBD9BF5EDDE5BF3921EB14FCF97A8D69EDB09813705F7AFC8B823E28FC07B36CF8174ABC7F74AEE00981BB7C6444F872AD8A40A4D8B20399930632A9080DD80A4FA9EB87EF9DAE46E62A3E1105F4138E53B251A9703E3E4BE30AD2EC3711989F28C9D3EE98AF38A2AA431F31C41BF572A3AB62E1EC6F4B0FEA14BBFC99DBAF2E1E96FC406F17DA2F6D72F9E8E2C8F84D104278D897B3861CAB275D7C690B14EB299AFD8A9508EBA54A87B81BCDFE1BEE783962B5794573A3C842B85E3F87454062784D32E6B301D5DD43EB702F886C9537D45BE6ED13D7DEF5AE4D692551B2B9E6D83AF896661E80E756CC207747D7ABFEFB51AFA6C0DC4D0AEB2E92218AA51063DB7ECEC4A320B41C564CCB53EF5DEF9EE596D7C9F7140E0048139A3732A365FA842A823642C7502A989C7D56A5C9CB8F7B81668C638B13AC602171169C2BD25BC2999809CEAC16FD304ED03AB6954F86F5E179CADFB96B1D1F9ADEEADB29191FB99C039AF2219678CBD02F6062CC4C9A512E622AF383E22D80EB9FFBF16F2A2D428DD80E0D6491A62B46E6210E67C2BC87BC67A169A9F488240C1D5F432F4494D8CD02819369F023663844B8A3B90C87D2DC2F7354C0DFA3421BEAEDCFFD719FEEF693CFCF8A01BF14C100E73D7D9551527DBB9511A8AAB01617BD11AD042EB86AF7E3DCAE54CEE4EF4DD8A51B06A88D1577F7001B510A0D9B59981C762FCB354A4028D5900BFF4B941D962D589244EA5CADE2F400EF3825997E38DCB8C1A514A20D63EB7E186784A4D1E61EFF36CE161A441A59B72B581425CDD8BB303179B2139912E4A9ADE76C2868D35BB26EC7FAB223C2BF6D2361E76B81E3E7BF7232AE801C5455B8E8B88DC7E0AC906A222D283EAF51492B3DB2EFCEB96EAAE2D9495C26384AFAB002DF0E0AF74843C9E414CE03C150AFFFF3E7847A8947FC4FA93EB6DBD6C321677865B4D7557393D04F00BE1CD7C1C67E575E0C41B462A60830DF831810DAEBC557D294E28D0036A89B6D4BAF21F479A83CE7AC225F0190237E46D787F3C8F7972A1B310BB47156F7E96E55D9656679EEC53504802B08F1FD89970BEF2EEAB6C11E91E6E6D76C6A13EC9971EF71A08145FE34AA1DBDDA7F20849277C1B03220DA3091AA295434D3ADF076A2EBE7613C663557C360333EF2F9C08944DDE14234C029ADDBF5DA20B814FD8D0491B3986E13CC3F26D6A6A523138217B68C5C2914B9826C68052347C83FC50D4E0BE90B49A92470E6C75B636D68F2EABE0F358F1F286416D7F5344AF210DB73C30A96B9AFCB46592E9302C3B6F6536A2AF40C1C07F0F637D07CD99B6586AF0655DBD37831BBB920B07B0C5E28556C603A0D7AE4F3B3CD9EE087D384BEBEF14950B89D1D53788DD45011777D8844801AB18E5E002006147A1BA95D301F551A3A4BAD14C68B1046E86A40F66ACCC50D8DB8D1DA0E62E6BC44840B5B093B45823C9D0B8E6D44DB7D9ED7A770B1525B53E9561BA4E027068230C64993D0CBBFD6C8525A1CC1A007BD583CA362FD00927421929FBF483432D31B84649A672C96F052F212667D2113742EC4B95D11D73222B37F990C978692C71B51DBD7CE39690D7DFD8A32D10D0A33A26D296E8608440E03D2380818B02FF5AC5380F106741D74E6BC031C8F822A4EE861E9F3D1058A18CE144FBAC9C00EFE7E25C9D9CE7548A86001A57111E5F497F28FBFD50CCAF31A2586B7D4C97AA1C1BCB130CFD43EEF5467F8A26300828F9FD3223906407FEBBEE15389E25856A211136142F273C5D4D06B29E66C2366282B5F592AA65C61D65A46E9610EDD7A5E09F661651BC77860221FFA9C2B9D3748FC4373B4E8DC8843DF1EEE283D5D5D7AD63D0314A3DE519453E15DB093EDD89976A87DAD3DD5C6941689FAF3E148EBAEAA8E102618D39BE3AB6B27D66D004202125A901499EB1382467E31188AE455F9F86C4196B06E695B637BF383B12E76350A4F75FA83AA07A249B879190081805D2570B4BF6270F0BACC1DB9E30F0C18312423F6D7C56E197A76D39DB33EA43165D52A24C14589C59D95D7692AB492A1081BDA3CCE2A07ECAB3F3E07F284B5F94A99CD359C34369AEA92BE90AA59CB25423707F48CB40F40D8DBF8D3F9D6FB550FB2FAEE63C8E1A10F3552C295BAA5B2C945558FFBE", + "message": "959D7C2BBFCC7DD27F7157B95B10DAAD3E9CFC3E239F471D39A2B2BAA7B2FB4BE7947C392A140B936EDD3F9EC4F78A5972046D62BD687312D6A640CB5FECAFBF0F1CB1E5694DB1ABFFB9A796B21EC3796D12A656720B689879E686DBC00A4D1673F2BC8871F76B195BDF6D2501ECF95D8200D6AD0222B1CCA522DDD5660C8A6CDFA882AC7B467A44C0A97923D70EBA56BBECE84A772DBEF59E37CEEB3C2BC2D4034534BB42B54A6A4B4DDBC1184F03740D190029E18DB11364C561C5B0C5929B6A9273DB82C76FBC16C9D8294122BAFFFD7FB0CEC72D677620B683B172603324771DE3D34F01F3BEE7C8564804D1CAE776D326E3E909B84D65C2DC758656846D11DDFB0C0A31D323639AD77F7ACC39FC2C0908F6CE45017229ED0522255658BF47D1153DCEF6F17FCAF429EA7CE13B6AE501CCDE15CC3E271AC902FBB19D188C845361B6371EFEF8E81EC30C6C1B3C2CE9B6BF3DE2DD12A9884D5BCCEFD99D8D019506B80D2521A43EAFBB2875C7747696F2D44F2B19228B0C6FDB59C33DA7A34639D3E192D31EBE05EB5605681F1864A61E09967DE4C7D576988B2BE3268F95B424478E2B1B95A0885233F2EE9924989BBF8052D25BC78EC8FFFC2773A61039DD459E8CB7B4232671DCF245738FD473C0FFD2F4606DDB52B0FF434E41077D7B97A781C30CE4986EB3E0C0ADAD788D0B4E3E2EF122A7E05E08AA714F22D706318AA0BD019B22B1EFF0F49B40CCE4FC224E66264839071B55A91CE6BDD389634F218C91AA9ADC71748667F83DFC897BEF6744D8852627BE1C4A58DE0C973756E93298CA47D3646727EC4C70F72466AD87297DF52A7295E7EBD4650E02045DC1F75E1CA4AA11A56C5D6F4B1B0E139281595AE26A582FB506D743DBED3FC1D672075B8489A5C0086994D524E0796C2BC7C1A4D0D876651C7BE8C264B37A39428150C48839DB53262A3359D074AA9EC83BF756268143263790945FDCCBEA3CC26449CF7E41A8221EE82613FFADF5B0DBC58D4FF03D9E8B51CE06315CFA3B4C3D3306C6258663568BE794C50D94F53DC1F0591818286FC92A6F56E2983309B3AD33A7F5EBB6A135DDA5776007C9FBA7B19E6465ADE980E528F17CC6BC41FC03479B8F083BA6DB26560701980D98BBA73612239437514F3C3CE39BC6DCF83CDF3E85F8C27131B9D4329BB7FC26BCC9C4B859BFF8213A88405E0039F57B0EC20E032854D75C7401F50B44CEBF91AE3D76D917D49E064008935D54377226C419015B48AA6332A3DB8DF8C53929CDE594957360BA95101D56AE8C877A3801F9BB446E9CA52643B0D693ADE5BC5DEE941AD78C386CE209889E016EEE1409368872B42327BDE8BD21CEDF42C31DAE1FC59CA091B1C173AEDE6C2B84634812901956CA93DC228A35AC884EAC1AC075B32265B600A5228D53059145B2F294466F7AFA0338D1D1847C9D45B43E15793F241E1E19AAB78D8A1C8F9C64609F277B60C763265AE594D23C0F6E8D2F3F1DF06AF1E5DA6EF50ED3A054E8CCA30D93EB2A75F35C05E33109F98C0EB88B2EDF055C4071F48A52F0532468098CEF8D5F4AC7FABB0F447930DBE66F2D5E48323BAAE1D85A03585BE5E68537D536BF187926EB57EBC7D8C0DDB643CA507039768BF99EC9A469B44AA2B3C194D0222F74A637E067D5D42CDA7385410E4DFA0FA67B555A05AA654F5A8DC02B17A14C451FC491C45F16B5CCE6FF492FF3C3410BCECB63E11642F3056B96F61CA1BA2B24A378054F59C9DA095C6C9CF8B0D0E550A962E643C6EFBD2413EA8E3A20113882F8F9FFD814EB6EB40E29D0D46707F0F9D0172DD93D231EA250193BC77EE9332D400300A0C9B668D73C2467E4920E3E4FB20C23533F7886F89AC98F7CC3AAD9750E63E3A556A205F46A6D52C31CB8", + "rnd": "A00DE2E63DD5328AF32D386C5E7CD56F9730B99F57A7BDE7A6B85CBA667181DF", + "signature": "9640EE42ADE56FFCC49FAB13703BAC5B0D9C58B19AB0AE29B0B7E981B1E05C38676F3FC9AFE2D0724191BEA5D4A38B07882F27CD9C1B4638387BCB9FF74212DFCB6B861C1A62FDED3C9593EF0EA6C4A39316D375441A3DDC39A373888F14074AD837042C3D14569D50B2F81DA5A2A1A3BDD620ED1E4BA20C2EEA971642B85453F8674F59E461D017D92CF56C6FCC1C8DD9F25432AAAFD08729CAD63DA236AE7DC734312AA12EDD4B31A45464D4D476B98CB8B8A967A0E38A0E06C7EC22174B4243B38966E94E215DDF8C6FD028FC176F04462B212A47EF0DAE506A3D033AEFF702E17400EA76C993947372A42FFB0DEB58661BF781F22B56712325754ED2D69883DA7BD88A2890AAE3B536B7D1AD67EC28C459F9D59BAAA128F746F0430BEF8CA808D818F95AB4C445A7A163277D7B1F4FF35417B827D7E0EA6DF253FC82331D779E3E8F9C0CD30FC544D6C990BF104936F0043E5F51C82D1735F6ABBF55A4D72571AFAE1040747A4BE6CC479A55A42E4E69255D40E5583865CBDAFC55B94DBE323498EB87DD86B54A1ADDA452BB533212782989490A2AF4135F73CBB334505DD763530F86018D03CADD69B299B67550CDE643D1D444E291484372F192720B8649AFAE2FF1421776B01707113AC99D5EBA17D07B563C5C25CBA4EA0E3BE6770AF2510F36CE9D4472FC37D9B0A1FA706E901966EEFC40BFC00A916B77D10404843205877F289261A26E05170FC1C78E07B83367C1381289F72903779303534FE00CF363EA8AB1A6D1D906EF9BD3AC9E521D78D43748E12BA793D427E8E17E906CC03C732D5FEEF7934A9394371613F4CD1FA4A065A8D5B992307419D51B5BC6103A7DCE98C9ABBBE6A636EA28FBFA58B27361CED9C912DFE19A3FBF0AC9CCBF72A23E304FAD36C169478B9AB102ADE1907627A45D62A76570C2B1FEFD0CA09AEDE82634A42B621047532B3C42E0B27CC793D387F328AEC86CABBD9818FB2CCDF89C8B1A30D6B3C50E50BA2F87DE053C82CE711677DE39A85D56B7ECC2BA7134E1AA3C2A515FED9B521A4E3589F7EEAB110E6050A6464212EBE2F035F6D90F9F1E34597554E9BA1A4FFA15782C4526DFE5581431D2549FB1FFC158C584CF3A38EE2FEC3418289F2BF5027136B4CED48886B1F91ACDDF9D0BE8DC16A00EDC82EDD763455D286F0485F83CB2AC72DB2BB625A49820BAAAA704E3E84252A1B687EA197A564CD7AADEC4EAD3F9E2BD266AC4E9288DE31EEF4D94DAADC70AB9985BCA7EA686BEE9DEBC3B2FB078F5F8ADB7592046B03CB2423B9DDFCB16E35A36CCF169AE415A7103C46221DF0CBF32044E623D919597D98948FC50E3C3026F31B8BAE1D86EBBF2EEC24D396C8CB2029E0585747ED9E77E4B59C572F149DA2A6A5A4DF578978048219B7440FE1950452A6B7C941A9F2DF02320FA033B84F1EE67CCCE3D30773D7C4C311516DB432F16DE3A941DE2DEA329DF8914294D726A8B73F01DED4DB46187818F0B42F91D210C4CA542632013CF1255D25C2D97098D742A270A87EEB68154453B1F74CE850EE3B500E22A11B6BC13796D53716B395BFB8DA722176C8B2D770793629055B2FDF71469917989C71229443004CCE15893CA5D87D39FA37C7A60C74B61227DABACFAE8EE20A202ED5EF2FF5DB395C29144DFCF93F90EF73CDE70AFDD0218284B6740AB0657B5A969D53357652ED38B051762610A4B644D9231F9A37E02DD41B2DE3ACBA28EFE65CBEFCA6B080596EBB2E886BE2439BD71BCC586FAEB364D0D7EE163E76DD91CFA6395C349EEBA139A72DD967F1DCF4230ACF7EE117E89930711FDB6B57FD0E4B6440E193EB9B34037DB27F41FC1A3A8D35F6C8371266CA24BE9EE7067E8D2B8425C3FA8248FD4F6CED856C4219ACAF949A032E6988A733C1C5980E83934A7802FABFF32A7CD073DC9C3AC35B8916E2F96A3DE64DA645B45F31A9EFFEAC5F9C93C53CE092EAB03AEC82E053DAEC11A0A7A688D1769BFB1A90967885A5B3FFCEFCB00DBD2202D4C9DB5DC6BE52FB36C891654C1EC3D1348B120C66B37FCCBF0F6D68EC0EC45B6902604A4CB5BDF75A20F10DF080662C9000673596BD97FBB2EAA329CC632847F48D9E9EB64A3BA9AE0CCCAB8554013369E6C880372366A99C5FF7197982BBC669015C170AB0319D4C473138593452C2658743E3196E33AA499E213C634FD887C2E82F65624D9A7D189B0109A14740695657B8FC2C3C16CF227F26742C4C1295440985B4BE4F00FFDD35CEDFC36264F43625A3492457C849217E29CD080434A856166F15B8E9B1F7CEEFC429F290425F1D50E56AB48510986B80656475F28BBDA522A14405EA6DD251C53A7A60F68737E985D23704B05275CCB2095A2AAD858D84F21822BF63814190BBABED0F6831C6FFC8EE0B1D882F1786C26ADA57030872C53B4E37E532255A3AC269BB136679475415A128719E10C2BE430CC8FA3286BA38479E50EA22E5D3DA70B8C594EC74543401A07DC32C4314F866B478071AAA1CEB7EB8A1209E030A0A68E3BBF39939749B630DFA40472DA7BAB6DE9531EC630AA70568C7C1DEFDEBE6BE7075BFC8587390B8E0944D782C73E7E19B524CE7E5C9CE7C82068ECEFF5A4FFA6964B3D66FFA0CFA05DFC2BA8055849290EB733C737C0BCA93B21114B4513F14CC37ACE178D0EF2A5B741927FDEF1A09363280437D067DB1D1F24D4FA7A11EEC885D887B636C996AFF78B49A16473651364301D0229458428D6AE652173EA168D7B408A5A58319A4D0723BF5594BDD43AA9DF91DAEB1F539E0EB3A86C5204521789A5193F95F9553AB591878FB6230552AC4F5788EA7E2DDFF3FBEE08736B095FCF1F6208D4C143BF54F2A7008065E658DA4FDB8A21B881F69AE1AF35BF1D4172518165120B246497EE3F210FC6CFE91509079C51DC906A6908E768A4D3D0E25F9BC97E1B929D06DA05F730030972D2779E0B52040A13E7C4689B55955D588B924BCDA63A858DB6968DF67F80519F36D0EFBEF87A1A51A8593D76FF0E3AC37831514C8FDD874A7F04E2DD00A075B24A7B697F586FA517589489DC6F319252C30790099B291141AE6044855C35B96EDBC7DCA8F03D3A2EE3758CE5B468ECF20FC4E91236D1A3C049058DBE145D40E026915B12AD0868A8B3849A119C1457AB618465CF87FDB7E882CB8E75E131A75E89E15D5DAE52F0F99A899AF471727D7800B388E819FC556B9AC34E2B118C9DAE26889BBF9DEEC987F1F32AF3652671C5C769973FDE50D6E75B65D61DDF6FD79D7F143510EE70F5F0358A3E327F5E996910E4020C262A464E7D91A5A7A9B4C6C9D1D6E0F135485A60808B9BB8CFE64B4C70757C808AAAAFB1CFD2D7EFF7FE10333C3E516F8489A6C5DC00000000000000000000000000000000000000000000000000121C2C37" + }, + { + "tcId": 17, + "deferred": false, + "sk": "5A25C63FC5580D85BFC0D88CB914F155246792E611740E5432FB5D7FAEBA2383BF9E966E154813361659008F074FBC0390750CEE16B3080071C944904395194ED5FD3D6CDC07A52347D911C5718D621633ADE794C97DB2314CD896EF2A09F2060A974995C9A32E855FAA188B92FC3C95FD3285C5D632530C5F62BCC88B11215B5A208162B88519296AC81488E1A4119904699A80694836280C08040A1624811240A49084DBB020D9B650403449A1C684009331834830E496489B44440C312DC80065511472810491208785D0324C20105263045054347059120D09A705D39830E48849418224C0386E80884D8B024088166D1A0750E4B84C18C12159366D0A37228C8225433829D2322A04C150DB283118454A82866CE3B2110BC44890A40D64B881924685D810461A486189800112252802146A53A6508C32090C468953C801E3223251B62DE2A84C122884E0220CD89804DB188D83144800378D100700014931832032134990A3A401DB024AE320090B8249CA345114B684E038880AC2650A212021350260C840218630219668128560422669E4420804499244C828599450C8A4455B2246494404220360880010DB126A08B20013820CCB00910244821BA488509631E2263102389103900D1330885B362D13C550E1A288A4468598020554382CC9966913B14DA4804C809281E00465E38401842845C4B21191A0881A878823050004A00D8B3489C38228130582C112691B496088067012A9910AB609180132810408131926D1202458903192A22408428159C25150B08DA4002483146423446810C28D0342511A2389224630D1808844902908432840328D4CA24D53288AC38048208871093606C9168DD92029A3468563242981266DD020640B192201C22459A449A3284E8C4809088788C91431132868E39624CCC84D99B80180C66D21C74061384A0A344D63B6281246041A080112080E9AA03083067002160992904C43462A080660081842D4342E10A2510AA565CC344C6302225A04611A38251B2466122041C81848A322640314800B4182E21229034871C1C404DA126614272913376C541661E2B60D1B468120349223276E222585C83041CA9410DA380282A640D3940402C6441A9448DA242DC2422682949121202EE3166C24B40C11226D0AA52CD280006288505B483062C485A2A630A20008A1346E48B8450BA52DE000055B0080C8900902A04D24C944D0C0801337411B370423834520B60460A884603204DDC45821BB9A2765BCAD98CE10F383A48EAE6541BBA2B1672D1502BAAF8B5F785006050F81DE1B7172843B00336E67075A7406AD10BA50C1F2EA0A475464F3DAF7C8F9E86E08DF93B36D52EBCED4378C3CFC390D768F081335674C9DAAB1FDFB65C69A57D4ACD4983DD8EAB25E81CFE2B8247EDAF1EB401052FA7ED0D5C34CAFE2B1FD6D2321865005A8A84F78C7EC76ADEE9780E0E411CF50B4E51AB91F72BAB048CAF5D8C146A519411797C95A9991D7F64955EE52EFE7686357F6D753F8E1C72976B44CD859EAF472BB9A36F5412EE3B8B1788AB4700A3E6F80CAEAF94A86D95030EFFB8EAF8BC7AC0409E397805D812FD13C88595994C634C7E27F508523DD90069706496E23D86A465F7B1529BF0E8B25159E12865C974228DA1A86C0F6CE07AFD99165FC16974308E1E29DDE745F23D48C52938DDAAC9CDD8495652211425E3910395EB1E1EB265BA8891C37E65057D59FE084B7D10C7183BB3899DE5232651E334C57DE7BAD7A749D1C530BDCC4B98A2F5D177FA639FA63506DBF8EABC22F0EEBA3CFF0B72AABFCDD475797509C3ECB7785D6D46085C1A919906C724520B3AA543BB95C255F61D78A1598804D813B8894FD14DFDB3DC2F62DE391AA7A0CBED7A7194053E1A6CAD33DD13DD25C4335CA2E21CB21233EC2E7391C5902AA15DD1079EB2A79E1D3BE6AE8D52DF61201CC53EE870DC4CC803D95F82FC751DAC5E5501A2198445650B699045BA4277B165B31F690244FA09468FE8FB9A39FD8E51A1AA4439F3D252404298539A15B5177583047F6963BCD0C81F5017AD60FD996C4298C91A5F13FADA828C84509F1D75E6A8C0F410922C67FB84A09299C50C520A5232A1FB975A3B640B8C7A766FDDF88C93C1001AED6BCD93F59389548B7A2794E14C3E3BD90347B88F4F1E3B38E8217429A736A1445037858A837A68E1663EB9605DB08DE5A5A3292D80A1A228C187377082977C32C5BBA5F35B07FB0C1162609D34A45E179538FD8D59BBD55BAE6DAB5F934D30FD465185CC46CB809DD0D2B9904CFC95D75ACC73C752B01214172441C4207CE5D39A2D6468D41DEB9788420D7DB0EDC0E77ADBB78C25EF7C5F135446D706410A6D9182203134164CD4085EC0FD1E99388671473727D8D337FC6643FF18CC9E05636278839446523E0FB5386C38B313D9B3AB44B0902B16A586A7F354767A2D8147A78CC99A636054B3B871176A63B628BF1C7B7F7D5F012791EE9DE6FDD4881CAB41BDD1AB0AAE1E0DF18989E9CBA459FB2B1AAF01DDA54C0A6C1E4DAC83B4990E048C9D193F9B3120E343AB245C850168B633265697BB3D8B7E12231E0001C3D1C53BBA27E39405694FD4ED247D3474EDF6842F31E365D044C32562233A728FB766FCD922D69E79ADE6379D9EBDBACFE0CDF45E64ADFA3862A4A28BF06BCD4D0016938D306BA07614532078858B7709751F946F59D6CEC4FAF2B86AE738C81BF444E1FAFCF4EC4F0321B1EF3EFEFAB3F0EAD135DEAA6F58C89180FF6234917E6731C352FED71659DA1FABEFDD9ECA6D6941B2E270D5A8F74E1944C48124C6AE366410056E173E54888C510FC6FAF75C56F8C20A2F9426C14EF6985091452AE672962D1E7579C825B869FD1E227A5A37A5496B8CD8EA204B4CA385D81F39662E51227CD248839BC405691BF6E702A8EE2D71670792BA463D90F875A221F5D156C39DF3725939FA1CEE78C824A9A9712FE3059C3345B38060805B069EF3F64A64BD25B32D011BFA885B0A5C71F0A355BB747993C329C235AB0230E2B951200EC6A674D7ED0CF4156620C351511018D0E3A884309A93648AE8E3A084A3D11938B4F748607D25354A301522E5B69EBDFA69C219C34F82DB9EE008981DBAA8B489584AFD28F24E146508D89780C08F798C8DD7703FA3ED0AAB87717DA52084F5755A431E1E7DF115766161A6D5D0479D7346CB20330EBB4D9F36AF99A605D084B5F279C144E4170606C64148E641F0EBF64B163D72A845DD47DAD6F9EFCC8C91D5E8CC35298E206F0ED82A819134DAB693E8B2E795F0C16E1CECC0809887F38ED25318DA2A1FE47F277B692F83EC15F7E05711422D85CD7417FEF0F0EDBBD7BFA978C9D8E9602496C0FF1B97939BC53B190F0CE0D6DF1694493512CB8446B01F7281BC7AD70686E44CB6BEC56CCBB4004924AC13C3698C808E53AF411C4FA1F848249661E07F0D171E20B10F3399C4C0BFD0324DA855F121CD1B043EF279E9781A0B6848618652FB4DFC55C618AE0D6E0E07A4DA2CAE185C1822FAD1E9C6A9FE01DD3D4AF54E00C2CB32A7A53ADA8342ED6A583B3386D8550B144713C39B9884AC9F5A7E2891317C71811D0FE", + "message": "B875BCE01C914651B9A9702999024A53E490CE42A80E8880514414076445A67190EEAF51B28F4FD1E15B4F4858DC64FFF69B4653E30E7667C76E706C6228AD09F2C906FD0241EE2AE3B1501E754FEEC1B0762F124E983A96ECB293A0BA3382327AC598479E157625AD95EC1DA563195A0E2A9FE55A28CE8A10A41279679BC0D0CFF6818FAAFDEC505C893A1D234A3BFE2BFA3C7A035228FC5443448B65D2AFE7B20F68E06245554BA5A337822423CE542F784C168373E037D6E4D4004892F3930B5E41F19F6A777711BFEDE389FEE029438C1D5966BA45F401084BD9BC670A9386C180044C11E14DD1B3D1C967E23F21BD916753257A558C638E0381B7492AE38854C5C9209DBAABE043D4BC47A98205890322E74B93E84C8BA1A207BDC190A66F1872E9E7C925DF79B2E70DC7E02D0595C04348EF9AFCFB3EAD92457D335EC7509B9C74AF18C6CC4B1181478F26F91DE6203B1B89E0410C8D2102AE9570F1FBFA7634C1FE1326D0DCCC2930A6891D415B28B66E2E593D855D9B88D5E9A399744228D1AC6755469C8F6974C6659FA715F7EB512EE53323CC229C1645B0B53A51938FCF4D9F142CAC579BA25125602173E0398A23F42C03127570C194019E3731BB99278712874E810E455AE845993DE43018E3E8E6F5EBBA16E2D5EE963AF2B284E8EA6244528CC3217119E0E61AF54A5F57CFF450BC1AA6FC6CD99F4B70F3272641033BE49C3CFF0D34A4019CE726F082205E8A6218F38723CEFE815299F8C672B5C70C0A776BBDE2320D44433D75FAED2B39433666DDEE4D0DB24F5A1E311A79E83E11E2131CBB6495F03F064195D61E589F83B371AEB1C6AA1F2632D053D2711486D81493538CAFECB4E517A3986D34E51FADF0A32EFFC153A5359FCBA8197A07E39FAFC9BC3E058F27E2706F046BDFBFF2DBE9CDD955B336A2D0D2581CD7CF25541C0F782D27C0097ACAF9E1356323778EBBA3773FCF23F217DDF07D47805A21C4A6D328E26E7B9552289CFD48CB13934D19D876F893CC2844F2E6A9BC133117C841AC49F7709167329C0A0BF767E5FD86AD907997226271EFCA9974D5AD315C3494652DC89941DD9370985B04BCF3DD66BB56EE7065AB2D6F75E2384E24D7CAF70EC8EA454BB9DC9C00DF4250D2E6D203E798AC77296BFC7EAA788276DDDE72B3E82DEB8FF6C5FE68CE18DC622AD8E7F859162D968AB225FA57E10A4A22ABB5DC416D28BADF2C1A152F372A4F655360B5C3A42293BBB32011E7CABB10DA2EA0F96742B58A8DAB9C7BA9E94AABC40DC412F1E478C2A51C1EF7F8B6657CA8C3FE79E3EE5C2A6652993B67C7AFDAAA19C74D4663D4D9A784E8C46C1BDC27E6044359C3F5C58B5A0B76C6BE20478DE18B12D5DE4B80EB1DC26FA87AB735DC18585CAE559166BDEEA599C74FF19C172D637CA2F8F58042B298EA29B3B331F3D2C5B75A3774F05D2E0BCA5E8E338407EC225CABAB08A2D0B3932245EE94C9B80327FAD3F98839890E27AA9AC533D6D5DED9BD7C6B351BCC98B1E370FDFF85D8A58F91650862E0AA9EC7E0C7D43B8197041F45746C6E47958D0235DA33D850EFEF7FD547CADAF5234D2AEBB3CAA8CECE8B17484DEF74587BD65C3FFD862ED58A7AAB70A3090DAE4D6D34E8C5EA1EF1CCFFBB080862CB9B5F22DF547927625836F0D5D1BC75CE8A9420AB198AD47B5A2AD56760DE64C55F4C67E57194A1CEF886BFBD404549C733609A6CCEC11703459473F5471FE917F3301A1A84A92E2500EE6C308D1A0FCE201D874AF658F67A66EB8FA0B9A2BD65B74CD7501469E4BBAA91C5C43C7DEFD5352D970485A164CB802E846864D9B6C6B3A9AE7CEF45FCB8210CEB5A2376A9EA54F4797068700E65C9C695102106C795ECE83BE66843C9AF9D007493062D92153FA56F2C6FA2AEEE8F16C0B8F49AB896A0F188B58CE890C420E913175E9E7B897F89AADA9D6787749EC8CEF808E998B117D33282B6119FEA7F0C93F7174DB65E0FC8A18C4BCF6AD2743EC72CD310D1B3E02A6415FC8B512016F6A9073AFCB366F4A108D99D78DB7BE82F0D0832B5E02914CEF3CAB3AB0017A13E05274B52018247F9E1B339E582D3F518C0FDA3F35F1B1DF45A3C7EFA5FD65542BE1F4CD194A82CB0FB91D0FE1E6E0A72C51381555A605D51F8DFFB2E32438AB2B157548C45BA2B4153FD54BC6C15D3556AB13DEA88079A13AB928BBFEA7FAE4F4E3D14F1C3742303FD0A5DF47309E3849EE5ADE092D8F0C549170169BE294BB0F1C7C5509A723B1892D0C379CCE32BACFB4AE93630A017138EAE64FF8CB5D4C18329D89EB5DECE871BDE81AAEC7E73AE168E1E92EACFDACA667B2F68FA57F6137BB0F84091413A1ADCD3050A6A7E8FBD165F5683C94F717B6A6AE0F0F9AB5B21E8EB297C3C8A0D6D11E7E15C4B4434476C28135678DEFEA42D34CB9FAF4C02BE30504F9EC6FCE62AB6CE62C7F49EB036098F3DFB698B723789EF7922B5C33B73AFD6FAFB7B3ED7A9237DE2EB168894A6578163EAC0B1942B4CCADC9DA60AA898B97850884407B76D7AFDADFEB7BE01668D1F2C5D5CF5EC005F3F0233AB51A6D17B99A918EF21C583DFC0E0ACB2F46A4EFD88EF4CDB233263913FAA0A8A972E5BA95FF2210CFFEE7C6C08818F597D3F09498DCAD9AD50306EBBB617DD9E318B604F3929F2FDB4DBC7629C9D0B91EE1AA81D483B16F77D95D351F0D6E8C650190913137D73265D5285A3C1574223825E929EDE2EB73A9F74CCAD4F4F4F3A7F89B9DEC08EF080B8874BFF76B66C494223A0401167500AF8C9A203FD2CADA852FB5A2DA18446239EA3062E38AF044278CAD9FDF8A136D9B75A6307B18F24BEB684AF7AF8E4141B2099E2474107645BD0539221EB632D01765312B5A067BC80EB47369D0BD5950BEBC46125A3AC2CC90F046E6D0F0F05EC21BA4F8EEFFFE081BE85F46ED1745F3FC1A231F1504FBCC6E101B581E87A06DFB507126B1457AD1DB5B17460720ECAC58557E816EFBBF4332664E69C1D963332E5677C9B39E596AAB920AC4583E22AC89ED2171CADEC4631A34B50AB02663D61F6F7429DD668979C73950236ED987F760FE8035BF7292A28045304D1810A40BB5699DD025839B0A22D0F45D7144B85A81CD1B5422294FAD4FA9BD6870AC4ACB96D178172419C48C42A26F0F2FE24C4DBDA0F952DC3ADD2D80B1E9FA1FEDAC81D0244FBD82660B8B2FF78F0F56D06F3993CD562D3E2AEFD69F0A8D3F94F483D1A1B5DF9F1BE01B03CE377DCC117C380DE18EFE93BF5E47AFB35BADAD69D9B2ADB3A07B8EEE50B89261057B85CAA3223CA7F70957A237722D44BDFFC4727C0949BD486F43A8DFF4FAD690DB217B9C6DA310101973137FF622E4145ED34B9F233C36F7123846425CB16A2CC7986A5631A3913B5395A84040DF80B585F5916F17AE293587BD3FFEEE73B5C1B3644F76D86A19E042533D5C61BEB4422734C602832D81171F32C05B93D39E90F219FEF521A7EA5C08149C98C538784808C3D27D04A7DBB259612EC2C61204EEFBF294DA06BD1609A1DABA6EEFDA883DF5866D98C28A9386F405B237A19C26C2738C734D766DDE766C94F7983EDFB80BA8D05EECD4786B6F400B47D533729EA972E93EA7E6210E547342013DE9D3824BDAE5AA403599ABA224696E74C241C86DC2E17BB12B92F153209486802A9FC8BE801A26FBE0618AEEAA5A3AE7742EE909D23BCDA2820255F1E19AB1C088560C6F40E2A3AB5B9AA99093FDC37194D2EDD2551EE6270F099123B572968A021EDC7DDBCFCA62013E18B862CCBC23361B747824B3DF64D3E83F0B44A4D964530C6D4011098D095B02963473BA1F3E14E5D89EE6E9866F6EFD8768D91564A7629C72720AD1090EAA5B61BB234E525B410820B94C4C00C57E68212A183764CCBDC972C605603645AF24DAE7BF04D780179F903DE22260D55277D24116B833754310BFFADE69EAE13602EBBD21534D50A937D24BBCA7DD7DB4413FF0417C489AD1FC4AFC5570C7F9DB5CD5BFA02526927823BD6F4305718E1D157B9663C63E1BC29BD247E5B57466A725412E35FA933FE793B68F981B26A44430B1D9E76F1F2C8B1BBA33550E262EA3558A79B9C5BEDEFF530572F2B9377CCF27561BE427BC219EFAF3E4C98282ED16A948CF97F5DBAA4CA5F19390BE277F0073C5E7FB4CD7FC15126F85600B84E0F696311A3837F0951F4158CC13D1340E8053F04E73897357C370F7988AEAEBA5721574C4CCA7D2F0C239616E949B7D1CAAEA605BB0F7067B6B0DC20B28C2CE70BFFD6780FDEEF8F0BFA13589F4DE55858C205B596BABA2D9A672A3B59882A207B3564CFA20F94D0633CBF753C0BCEE0EC36A9DDADA81D70CF7988A3AE53CCCA7050636D2ED28F02A0B25DB32A89A6230BD88F25539A71DFA393A131123482C1F0EAFEE32ED9B97B5CFD781E87C10471AA9BD83114BCB56F349146E84EEBFF18D1E5742FFA51BEE30AA4E2080AA571EA7CF01D114C54A66519F935EDBCC41F3E0682C4F8AB8061C8AC2485BB22CE68697F03AC6E2A059A96DE20B05B196B088F5F04D7720FF0ED295E4717E7EB8485C9544E58C4537F43DEF5D4E999AABF0FC30C7040A798BCB8D7C800ED6DE38F6AC7B95A1A292F14009FAC702FC7C7B62A4BB5FB77554B3F236E7887D9541FEF4E249CB04FD40AC5BF84C68BE6BC2B305EA1550C5D32B40677082E25EEEE99C72B932C5BF826577F58132D2C5CC34752946675721C4B837B7F94D7A75363D8ECB0224F2E0EC096D4147158E0AD349B4FAF8288C6DA49EA7BC13B1B8FFA6CF0B0F4DA60F712F7D41C2D50BC06C644B69B23D2144413CCC6101A6226E3DCC424D1771E2564CFBE21C4C69C93A15A04DDE71FF8531F3D68CE193E30B634BB9BB9C0F1160AA32CD59377F151ACE2E60541D096E27E958416E782C2523A63351315737F7AA79BD473C99D8ED83525EA916C7894EB47D10E383A98B2DF17F673214F27779773527ED5BBDDB38DCEBFAF9961D948AD85843A8D0BF3CC257190517D2B5C97E5BF4C6AB4261970825F192B07BE236F69749E7DE60C37E4DE07A5EF2C5F13A7F9C66DBDD143BD4C036B47C4EFD1D4CB60BDB190D2555D537C1EAD72731DDBCA2309FDDB89832D1A0571D34460B3028C79190C082A36B0F6A2F740FE5DC2BED6AFA778F25E4EE46CC5DBC7824BFF4BBC1C0B3431F38B729BFB5B296DEFF3F6CCF41F44AB701F98AE4A00939CD2AB51CC6530F1538FB2F5F352E811F6FC2E6C59779A2E9DCCB0ED0E5FC3E3E97EC5840C51269C5C4C6D6722BC105B5D2EF7712EEA126157B8A3F2028C3EC1F6D4B203AE463FEE6E5D566CD8F2E741BEB3794D21BAB89C8273CB4C4094FAB2B946590AFDCE0FD77C182CE78694D52205E387FD3FF80850DFB0D2BE1DBB069A45DD01AD14ED2445B0B846290A984C5432E808462F4090BAF46EF72214C08FC241367FD2E9070B0E2AB63DCFB3FCBED7D2E67EAD7E48D1C5B0EAB51FFB4FFCEE88F925C86F1F3BB096868F000540A5A98EF37210AE18BB67FFEFF225B8A195BAB6430F59A64CCA44F72DC539B0D0B4A2106DC19109B3319752CB153A6333DE5BC03FD1BAE2B5164F857BC3E0AF0D331529555896FD55F987FDF20EBC9C4FC0BB0E7547E3E5DEF86803BEE7033B2F896188B18A24EEECD10723B698DA1E1A0E6C7FFE0F396EBBC6B37A4683CE5D1C3E96CC2CD7AABC3FBA1EAFB69FAC9172AE878D442079C5568E5F5C4664A80A80BDC2632A4DCDA19CB09F78D590FC1B23F9DEEF8D4F1ADFA2C019F979476CDF32F33FB3BBD08B519E14DD5FFF1B867087D9A3B343DBFEC0707D33B69E6BB6790F9E945C0184F4C7AC21CB8C108B5CD577B8652FC07C7DC7504137B097387269A1EDEA5BF1FE28ED08642FC0A24E01A82DCBEE11D55766FAFA865A2A72FD2BDCE26DDB12348AA166C93A872777774DAA6BAAADC31555D77CFF1FE69364F227908BA738F0F96D52DB8F0466ACD3661AE019BE1C998DB7841A5DD47F8765306A2FE65B8D9157676987443B7B997035507EA64BC4CE210EEB1939905763F497170A9ED6E124E5C02CDD8D3DA879D0BDAAB538731E7C3B0906C87F73528445F7C5ECB54B571AEA88F2C5C8FFD828D66B8C8C149C5AB983CC56F5F1CCADD786F5DD65667EE45D49BF51932DA14992FEF7942D4AD879225D2B6B99A9A1DA3C1C1F671192D71F6A98D7648DBFB8E5EE65FF96CB08C9F7ED076F3C85E97C34AE4D114B1290AF9195C39CF642C680929AB15416DD4F274D6732F7C1236CE3078F192A0E525296437CDDE6F3563129E4C893A968F10C4ED95C639EA8D32B6E7CB7F3286CAA4826441A45222B2983B106DBCBEC92E89AFAB786D5577996B0889F080F77073705B0B4269203EBC3D4AFB3DC35595CCA778B2EFA5F715AFD4DD61D31E600D8378D3B3427B70A74C9F516F73054C66DCDBA8508E7AE957239D76C3107CCE1DACCE008A3A22616508073DD90D1AA32697EDDEA12C0CCB83F31DE5A3E078AE7A785E8A263BE454BB7CD45D5A0EEC650941673BCEE7366C26E43C6E8EEDEE4955513CC56223E49DD3BCC5D79823BFB061ACC39239DE0FB73DC0BE1AC9C80171547C8109CF5E01DCD39119CEAE743CE50EF636906F42B5E66AFC137400C82EED7B644BC508BEB6983D22D4EFB46AB35134CED2E8B58CE5A03199C875E64F0FA870CE3951C571A3D1EEEC1D54E2F770237209B31060AFBBB4C61136BC90A5744A87B7D7249E255AF7DF43986131BBB17846592B6A99876057F2C78710697325874D5F00A47FB68C9D744CA7D0F7BE8C4D31A03FB62CC1A9885C46EB1AC2DF447714901FBDF8E328761F483C331FCCAEEDE249FFADFA3A176D1D0987983CABE5B08FB79D969C7E97215E29F0343EB691E3DF27C6B88FC43EB226BC2C901476901F8C7AE9A1B07E05B9027F7228FC4E2949999C0EDCBB722B69694E14A227A9A0C042EC7257F02B8FEDF4723AAB2D98004B5E5439B536E30C0EC2D9DD406BFA3B3D2A9FB0FC89779DD35135BFB780FE43369E709C52D6CB6FF3E90BCF8DFED123A439BBA970CE9ECBFAA7107096E6E50A9267DC118FAE64F8C4107F8B456244E3C1DC96AC9B80BB02AFF04AC7CF9F7073745131C2D2A2F04AD6472A2BC14ECC357ED010075A595BD43AAEC48FE94B3FFE3C40DA0197B3B3E1E3F0F5E754E5B1748024130F9DBCC44E52D9869694E43BDC3E8F1182C34C6981EFADC42E97BEADB145696425176E8D5DD39D5DF135939FA81F8DA602A706EDE4592A6E1B0A97DBB0DABC3A248C5B59E491B889A120B2BC4DC8CEB6637F887D8F8DF07071432F165D3E7EB3E1E15866D5F1258B14866BD4D9ABB13A10E50A3F8EAE2B7CF3215B0A2CDD000D058C580F02DFAB7DAF071BBB0AE3A1DC5D4BE36D4B743049F05B46717EC492203176C87B881E85F44255A3CEE82BD849A2D9CEBF0D4183CE07E01D88D3FDD352C5F3D6E33D54B61BFAE0AECF42382A1DE42A7F421758241859F5D03E2A70E4F114E5F71249CC74222BD6173159DDB3D81E4809C8EEE838CD0610AFA176D1F20211F89CF6104865EDE36E3A50253A28F99757001C8306F9B1EC175AAFAA578066263C6B82D74B3F2E648CCFD8AA24E460C04A090738284E8D7B74415F66CA6AB346E475099AE943905E4844C18475262D66B17A151AC74AAB36066C1AEB9D66A95E545DC0424B123A5F13CE82C38493E79F2CECDD73C91794B4C754BD23A2B42CCB0846286CB55A438EEDDE225BFF629AC38FCD9FBA31B1A47CBA85AC9EA1283D462A72361F57775CCC970F256D944F3A63F36E4BDFFA574D4E657FD41216EA9E134BC69B39D68E21CBAD9A018EF009FC8E97B3894F3B790CC5AC1C9D8942FA56A89E156780DDD2277CAD7759071CF95AF2F9270C7D932C38A347791C0DFADF42F6912E784B0CF5B5A4312C7B642C543EC81A985885F0E7C7066074868386689928DB755B4BB1759B51BD0D656A329927DDFC926693F82E7BEC7A29C0984762B19686AE0D44223B5A813C50B47CD44130210CDDE647FF2FD6E8C97D871BF6C7A2617A39AB72CA34ABE2EA65C3CF074569F145B76FF9D42BD03210D778CE1E34E6F01FCBB24E3275E87CC7BA73DF61F7B0424B9550EDC7C22D2C77EDE8A2A163AD5E3535B6C787A596969537CBF1585820097A2A31BB931C25D68339E3C91C7DA483BBCC2781F13A6C7D50E3F9FDA8A0666BA7052055F7591A5CB7B7F1E412E78A9F2564A1BEB3C71EAA702914AD78ED9E751E06B0971CD9F85D8AEB591FE4DCA6759172EB3725746267AC4D2FFFB6A53800D7D6B0C96D1C0200ABC733263ECAE79028DB52B0FE665BDEC01DB31EEA9424BE0187DADC6CCF50E423D9AD715332856F6C0A83EB634998B2A32D88BE0025EA49489658B42A43AAACC6B60A97190F0C48DBC344C4ED7D546A4C0520077C179A2E60C6806F7B6122A0DF7168B7B3E4B7C334F4C5AA545B0FC8F5D4155CF47A2E2F6DCE8BD0C2414DA16DA92FFD464A4E615214819A36F7ECFC9742A0B9028059FF6EAEF2025619E7C69F0C924147A71BA69D27DD5E699CCE5FC0D1EABA07DCAE0FEA679461E0DB993F72EB26F557ADCE720CB885B08044570300E2DDEF495AA1C601F9FF1619285F22E86D92C09FDF429EC12414B992BFF9E97DAD8A4FFE71AD05BBC6D4AA4C9F96117228608A2DD4B09B32DC60E6606D8CD6943BA5BF39C14B48F7C095406A757B321A75171F869E25136CC41149CA94C641173F1FB7C1B0868937F72842F81D5F44163B7B26BEA415B3F3676FC05A833010039D6DC9B9816D859BD5C39C52188ACC847BCD0AA4D9EE7508D9493F46225F0B837A6B72E9E3BFE34620009D291E8D4CA6A5F2B98EC39A7F0047BD7974B3B5AC62ECBAEF65317287254BDE3F58EECCC642BDE2FBDEC1E84E59C0B45C6AE53F146F598BE5E4D00A89A1C17B6701E44FB494285EA3C81505EED29FBF6FBB1448A0B2D02398A360EEA151BB10D4A0BADE19206F60B385E1F492F23F56C3815C44B2962C21EFFD602404DBE485CCA7F81E296330CC0FC6EECCE4C02108D775CA85E777C8CCBED43159EC6F379252C6B4B3FB16CC9E0743BC7B62EB0611575C934C6E375C716BE324E5F1480FBC4241A7EAE178557AB238CD43E924BFE3BA3291FC2B89E3FAB1963C50817EC6D497A5A022CEB053E948CEC652321E079833B664C81CA751F27476AB3561AE49888AFF51F0CCF3AA2EFABE937D7C58715CCB9DFECB0751C3F9967D2668DF5EA7EC3C42AAA36AD33632816C19E090F87F9AEF8A84199A75CB2592CCD403362B8B14AF2465EBE350D75FB79940C28756B67A805C946A635710A22E9DF43232FDCBD23E91474762FFF773E4F760AB27F9C386FF16F101FDB9B5E67BD8DBEAC4BC57184478CC4AEDB591716E8214193D9C8B0A78B8FE9A06004AFADC24FCF46155F5F9109E47B3043C4FFDA1071238A4821B78DD4D30BAB567B68C2BC0873DA3328870CAC8AB49055857B973B3F1CC9C76BB5352A036F9D6B0C1CBE75D1B5BF5C3A1A2C3AEBF6FE56E290437177B77239DD9372C7CF144E55C2F7A2890B72E6C9EC0FF2B256A65BDD7D053F51C45F63AEA5C9E7B77EAC6B2DCD83E046D47C5C21E208D0DB661803C54BF1733A411BD8A23E77066794C9D1BCEA59CB596BA6CFF140816D9C01A125AC317C805069568699DC4CEDA36E9CA24FA4D27D8CC53441CC41DD90C8B4B5EF2B1A74043618768F68E5908DAC7310CED1492151F1CD402035B299C6F8BE6B296AF960B43C6DEB71F6C34ACCE569F46608D54F34DE1FE88CCEB17122896D52B3B276F6A0D919A4207D0071D9590FD1A6D523344A711EA0619939CDE18D6971689CA4DBB710C9893C20C0527E8082C69C92FF8BFBD5EF578E2E066A6255C5E1CF7EF15B1FAB64A6601E0939C9ACCE67049C23A66F38F05AF8C4871CB629A8465A8AFE4DE88663BF396EC4EB2FE71C154ABD930B9C1F6BCECCDAE1826A9E15240A3921E5C1182598A8BFC6DA06BC34D947F2BACB4EB2807B6FBF660D1E0B7FFF49CBA864C063070588E2BD1C9BDA8D32E8008DEA9D5EEFB29EE248C81EAD7A65DC61B594EF1DD9D5DC58293E641E5DB78884BB98705B60FE5F97819A38E35DB220223BF89216B7A498FE45FE5C4F49207D81AC7B609A87175947ABA6C172D32157868DAE3EDA3935001C33F872BA460B3E420D0C05B439ADD079D3CB4BB7C0CBF7B7B9A25B88628A8DB2309A4858902C13F75E813ECAD91029E836A165C6E731B67B5103E759029CC44CD7DFC56296071B389133E8774748BBA0FC5E2427D76491F6FDDE60AC65A52A46F8861395B125465BC93C2A7827B35AB1AF4DFE2DE3BDD2EA747688DD62E474BCAC102AA2FA6AEEFA8B07E4A94E056D85BCC290DA61D65623280D009F20D262ADE5797E94391674402760043AE0FAF87416A8AFC5925A362AA463B86EAB155B9041C5A3477A832E6C8822349701FB87E07CABB47B63A47389C0F9186782FC635CF8063567DB741FCB24136905E4F623BCCB3B6B0E715397772D7FBB9A4F537FF228198E25B8521CE7B926CFFA1BA0087B9367BA02EE8B75872CEDBAF85BD9F1F40D85A6ED72B724863D5A99E6DAC365E877167340478D77CE0601DDDCD95A41530DAABE8088809207A8028F665A7B8809CA93529D2CFE9ECB062F6D05BECC88CDC0F36262CC2F7CC9B4A03FE5587EFD73069BA9612702476F0D8AB0044A46A8E7E7E8E457EF8EA573F57A9F746EAB56B733B74C66B470B5A54B52F172A371", + "rnd": "C4702883C0128CFD006755AC065EABBF039FB341C0D88B1FEBEF3600AC717D87", + "signature": "9B656484360D584EBBC561E4228CFE751D8981F330905498F4FEC740B86A68947B0F03B26369B2C6F1736F71665CD908D0A9382921B44997341F21AF9CBE25F5CA6ED5E803E13E61EFDAA5CDB97582D8BC47AD25027CB9950E7BEF9DA9F91DB83271761AD7588B187864E2BEA2ECC03C1B0BE45DAB362AF7F6536ED797FB28347C449F0A281B00ECEBE777EBFF66C5CD098F36ABA40D79EC58F3F7BAEF75A704B64C9FD61880EBB79B09E66A6A3B50C1AF84E8AE60B5E071BEAD1BF5B4218389FD6F46EE6EF96C81C44F7A801F3DCEAA832C02771C9A5091A867851B6784E2F978AF4A37D509138D152040A9CF72EFA9FDD08345773F5825CFDFB288BCB26AFF31C85AA6E824C106ED1ECBCDA37FC4103B57FB7D917A8B479A74F78A691F57482A29E2A5422418BE919DCFC6C58287590D6EB21BA4A60292C7077A619CB429BE30B52A5DFA485949279BA0ADB334488FCEDA56E09A9270E847EA1D11FAD6C84EB415235511A5B4EBC734D1E56262D248B930BC9499EAE946C8E63B3D4050FC44043FC45DD43EB5F0E321D6B2D1360EDD25EEA1DD06FA0471A81587AE39A67AB6EAE3253307559BF3C4EF17004B3FB4BB19962091DF15B87FE2C3CF2A9C9936F14D5D7C8278A26DDB767430544ADB3CFB8D91009166242D74DF15D25C6C95AB8C567B9811F661F69B7D3CCB41CA9D35A96F965152DF666EC38852A8E188242860948E807B05D32B7D88E2C11D240B4DA6BC3F41960A410B17D980CB4079EB163D0646768799663C0832A901BFECE8114C09887A36A13471CD50312B7825131EB66B212F680D3E8625EFA9CEF441B8AFDACE6DC43010782B75D4244ECA653E167BA324D67264CD521D31F95CBFEE107CA75976EA4FAD7156F8D2877D41435860D4216AC622242F768DB85DB6831A12FD4C5E911F9B4785771C4AE378AC0E4FE59A47F14810A045BED620EBE88BA19A926BC8E8EB88646C0ADE577E0236C3F565F7D00F2C66415D2A66606C091DACAFD6600AEA16FC802C9EF260A9E502A47ED1D6A433C4E6CE89A15F253573760612281C3D7C69F3F0B69CF3DBCAA2952F56B859D45E9A8D95EAF99A262D9BF69951199BB7CB067E1B2B0E26DC5B76B8CF958143F52ACC814E27D2220EDA58ED509DF9FE832E5AC3CEA7DA4A96B1E1BF396611A23887296194C359163908AB988B6CC71EEDF00D994F065EB75EA5BBB56441D976C2300786F1E232EFAA9E7140D2C7028C1D26AE7B6783C960C515B82D3DB4C74237CAEC8F31DF9104FCC4B5FAC9FA7E5092354658AFAB5C95FD80BCC921E16D803831945C3A860C6A60669DD9F0BCF6FA1B647CF357F4697CB5531BC09C8982C00415D84EFA66B572DB38A98003623C04ADC0F06DC9E34679EC1B0AD7B746F2C8CAF9719343EC0263EF8BD2511134E585E871EF3ADB08C2262A335CB7CC43DC506925EAE3B8DE9B6BA14F23D401E84B781D8A7AA7374AFABDAE863DC67BDBB8E5F91145E143A37E5D30C3EBC36C3B48BC94DB0232B7C3A4B3F27835F3F1858890D3813E37D2DF8143072C09D6CF0540EE6D2258B1C1D6A669C9CBC69BB31FE2E59FE4F42D0CF7A6D8058A7C4C488BCC58D854486E0A2F304E73D8E9C0BF04A4977E6254D398BB9EBDD06D7A2E840BA37915F05EE6C5DAAD484ACDD582849A08327E50838679A130F8F836BBA4AB3E53679ED4ECFA29474CAB9DCADFBA5CF5A6CDBB869FF8D305936C8744CF32B64F069F48FEF319E31C3DCB336B44486CCE2EE80F144A85F2A2BCC570649B128AB1EC1585AD72C96BCCA3A9B9CA5AAAB395095CEF6EC61CDE3133DD1C5E563CB7D04BDBCB117BCA2F2E2D724B559D38D09107040385C27813224D865D11076E11EF327381C0501BCE48E70E1D8188BFD5ECEC7A40356320EED2994277D3CC1210E7489A1E5380EB0B8106C2F068D0ACF1F38D9A02F470662B6658A20F4DFCF5C4D8AE8BD6F9B19E02C1F0B598CDA7C76D244FBA63754766A6AD1A0C4C240AC0FBAF6F817D29E159B9BB408E1C8853E3DBEDF24EB570327F509A35450EE26141184664C09D1A38C57145AA62648FEAD40FD2A0BA38D04A2E2F0A36E657D1EBBEA4ECBE43C5051A7625FC2CD0C2FDEF6C405A0A928CA0378F7616A79BCC6E526ADA5BC056AE6C51A1B9EBAF6803298681BBC0F87233E334A317583A48A53D9D6306149798DF59885B1D483EE84DF599F431C1BCEEB2EBB0850F61DAE0FBBA6662C425557DF09FADD85A8F0FBA7396A6546173CC1CE5BF871B54BDE32E8D5C70379C3C77C2ACF9750E99E8C89946B77C7FBDF149ED8ABAD75109EB0F0B061D69530ABA0862D29F4755CD7D6DC39AD5DD4DE322CCC26B20D1632D7A87DA5AACC10A4854E15918F79FE5D5B25F5BCA4D6CFBD6F308057A9C5DBBDCA4A8F2CC302404E1E0531523889A1C1441FC4CBD349A0EB9D65DB02C2493E3A83B305757F9B030854D769DEE03CBEB116929476330941D14C2C7A6A7E46C050438C90CE6C90339D4BEAD07D26D9B7CD212F523ACEEE20B5EED6EC7FC4EA7984AC3EFDB259CC18D421E7E694EFBE045C386E8648F4BBB0A387C0C8AC135B470EE484169C8E5BB69FAA4266274E34E28C0E7C2C371CC924BBC0DE5A5F33E61067F9108A7490FAA80F5247AA8451A6C3341A32F699A071502E5C9D703A98BDF6CBB1848664DD5374202B45BC518CE2619529764A12EA1787F12F7542A06CC9500E279B701EC8B5417B2581CD27A3554C56B0688360A82D12732F0443D1B6DB26C3A01A06851C5F5334DB0AA432B769FF096ACBB6F0CF9EBEBBF86BA1E6E08FF0072D209708FB437EC6B274E45427FEDDF805C56B0D8C3B9DF591CFD3DABFDF3D49CD39E805183E0F44E3E62EA41D512E01AED7D9B46A8CDE19C4D0E9B52D602882B5D3712898C21F833C5B48DC0261B6D82179AC64E04FAC063977313BE58B86BEBBC4769DEF6F961AF175D28D904DD0D7FD06BA5B9C8167A7959945BAFA3CA6FDCDCD030F6CC89C03B5EB533EAB2477F3932C3C7C9E9D50523B2814C915E6F4536B09BD4645B7FD2B5A628EBC9F37FD73634BEA5640B1F88B604DBFB60A1F6850717A7F034E38B459A5C111340AB3140F48E9A9A37353720CEA905814F92833B430B19C02C70C2631A74EBAEA4D7F319DC07B5562493685AD2ED5C918B8EBBAAEFB5A052AF6A524BEDC0B51EA2829EC1C1223EB10DB589AF71192B2FE73FDB097299B6E42BFBF08719578358545A53272159977F7D2256243DFE9A68D5DE17A860F4737145E0E1A1DEFF0B7472B4FDF68F994C8A573E296FFF1FA82F2B3E5C62648390ACB6B7C2E3E901212A547177797EABD6EE0C1653636C759BAFC9F707122227476A6D83888F93959EA5AFB6BADADEF7F8000000000000000000000000000000000000000000000000000D182237" + }, + { + "tcId": 18, + "deferred": false, + "sk": "A38FC76EC369291C0C3F2B03F1B8B301701E47B4E85FAC27C29223F71C0A2CC9C5DE18967E2617B512611C1B6F8BF42EDBEF11C78FD21EC9E474DDB52038ED850D6B9CD00B8095A7431DB26F236973F1C7F2A3B5EE61DF9A84DED3AD817358E76B1601C6EC9113A9BD1E6A47CCB422B89720FD47FB1496AB2E6BFA8F19D259B1884049C4A480DC888C0A0289E0248E124810CCA288112685530271D4382C21836C0B492403378163024592A8881C93059232108326501C2110E1A8710A0846D2202C01086A08481011817124932409886053C2415B188C61B02CD3022013A40084C42CDB06014B200160B4210331851BA88098481204456948422D4AA8108428648B40455B36825830826292015C948009C42D5C382A449861CA34045BA644E032301B140D19C4651BB4084426314032095B38929B404C60220892986C19C005C9B44458C0281BC20193008E64340A20C74DC212281391652400909A882819C480C834819C08300C429091A890C2C2891B2910C9928CDAC46C11168A24894822374043904101204C940652C290480C4169A1164E53220A1AA90423008C1A256A1A498204800D1116881C244618B669E046646146694A168812B30083460C892800A4842DD8408C04944909102A53A2610BC00D89088D9A162D0A3221CAC049E0A22002278A00289223133111274E48028D0CA67113162410458521A72DE22830E314720141400140294988250CA22DC9102D00C24CD92665004244C336720A36321C29700B0661E480651947241B41640B1824103469C1C671C3224E93868554A60D21A3514BA8204832409044915B4610131932DC864D1B286E24952C12492519800C1CA170511292239550C9C82410380223C98863C44DC3988581106552124A09322DA424109024000CA8015032208446221492812131200C998D1120611C388984A22884082D8420699C904CE3146DD1169202416002C56C4148681BC44C4C00064930618C3860A0280ED14670C48250494844100990133906E3A840240844A43641C9244DD3840591982C8B28325A140D019304DA04720893099B141281108552340161224E44140EC2928812C484E34048C8B02502156113B5705B1480C4961158A22C10280D1B1521A226810326409232129918800B0489C9064602C570D40440A206200183659BB8249910320C050651484160C44C049729182945C32245D036089A148A24050E51222511B0490935801A012024841040A65111956C06912550D9135EB2E4CE029E8040CAD3BE1AA494C9826CAB5C3CC5AE8BEE5F49DC41C872944A93012FA8721EECB46EC703C6FC1796C3D208B240A5E58A02A49CBE783ECE50DEE4F0A89C7DE37A420A5755547C09FAABEECA90C3F27662A4E5E5BD113690AEE27C720F055444000F1776CB94D82AE1BC676019DAA8241F7F68A291F25AA4CD3DAB2F98B1A3F2DD8126F9C9AE35DEEAAD341B0A353D95C8782A85E075D0C263AD22C3970DE74B5F54A603BDB71C5598F9F64B2B744EA948729690ED7BAB65F890B8EA1AD27B3E888F251B76EDFEDCB69F2429608BB05D9935A0B489B7EABEB77EDF8EEC529E1EE7C3DFA4188D1085BE937A4164EACAAD4014F299DB16DA14105C16EE7BBC431F48AD9264CB70CB26AEC7A87534733C0B6A6EFF359A99EA24AEDA08AA525129D5849A04F1E220B31A530C1754A660EA205DBD7AED093521DEBBD89EE62AE8E04B99968668B462EB4C4C1F24225FA22B86047F9179719B00EA82D1ED05582FFD74BDA4F0E6F25B9BEC8052F61775F512E305530BAABF71C043DAF1346B775B6929B8ECEB05EF3F4A31E495B0F08C9E85E0A083F75A7D6D5327514FD36CEF1BC693185E1B7D14DDAE8B476D18279DD0902410C8883DD5A31F98A7C2043247ABF058F7486E3BA19011C92217675497F41F29EEB555FE192B1F27F466EC445F0ADA9C6641DF81246A2E5CBC46A3760F8B59542BB13089FE2632E40DA23239B9FEE05D3273BF5731E28A7155EB3C0079D8C7F8C014E666CF559A9593B7A78F1E0883FF5E0BB8C8DA9DB09579907E2AFD3A144A9883C2C0A28FAF2BC3CF105F327A497956A13D3212A2F2F88FE30B899C883929F091F1050F9119BA8245CED94072AA14B840C15FE4B83F62AC1C6CAB8232B6720FB2DBEC9FC5DC62983F6CB2B9E035365C7E9034976B4FF954610FA3F70F4AECC364C78FC73008552FF92E83AD2CA67D9982E94E1F6C6B68E7DB4E138414219AA3F34AEDB09B932AB9D3A665662DE72C7BA6F007E48B3B4848C08BE2A548956E2B9563443F677104209EF51D01A74476C689C05037EA8D92DED7FED1073A5D8A6899C6F55416F709C1731AD81CE463C532C5BF0F150F6AECFE2F7B67CBD680388CCD1D819BD9980F6EE76D04E3AD13CC2E0A0DA86559E0268FB1653748C9CED7AB3E80FA1554D3EDDC8F8ED836A89BC8F5656457427EC920AB97BFA4B74E34F3516B38AB0A5CAE3A66C9E76A9C1FF73CE81AEF9A40A2DDD5383161C716EEA5C115FAE2E6C85EB15A69EFBEC343C019720D634FD351B2898F21FD257C52BCDC31FAB05226CB40E8FAEA38117584392EF9B60423249199CDE0127B98FEE1430BFAD5878FC5CEE87997B4EF20425633FEE2F63C13A0BD85DC02BDF9157CDCD50DDA1C2E8CE54068410F42804E4A06A4823341DF13B48579F83CF40C3027A33B4D80C891BC5AF9061C837EC83D3CAD0EEBC308EA43BD19E079001CE2F1B05AE16C8D82163F87E4AA6B3C1EAAB04B252F161CECA2470116CC10B50037B0336D3126964E31B4F1E1FFB55577F99288BFF7B74596C6A480F17596C7A0DF2CA17F58AA102607936292392CF46E538B6A5C8854CEB839473BAD879BD14845BA9C520F99AE772551B66033501C9D82F2B211A3E225267614B06B51DA3C229EC8180DB3EDE1C1EFFC7FC9C367244FA55F3CED6622324786DA01E448662CA18055116B2BB59AF35B93BB6636DD127AF3D06F0812F66F5278AE70A4E7D556378DE4068DB6E30FBFFDB3B9896BC17190F9B59E0811608700774846846D0CDCE09C36E8372808754A650956F8904A048CEC4A8A86CAA6276793473CEF322B9C6EE737F2C01ED1EF88156DEADE1520B3945C0EF0787A894D1C58F376A13BDB58E366563612FC717AE9A92F0189AA67EE8E8DD609DE2A21EE7D42ADDF520B80410D28D02BD4143DABC6E45AD3C2201185FA25FCE489799820872F794F7833E8CC03F086C171B052E3D9FDCBC7122D6FA89E7528FC6AD45D01CC3004387BA3926B99EF745BC00B608426A9754A1D0FEC97855652CA350BEDE5E8741F2CC1C0CB0E6410FCC14256A74082BE0F7CA43DD3FCD59716D7CCF06C665E5F8DCDEFA86A4AEE1844FBDCF2805685CDAFE578922D59AAEEF9A650ECAC307285562156596D49800ECAB42581ABE6D58BE2B5E394B0C1539BB13E60DEBA7A0A7465F34C521FFD77FA5C638BB8700718CC7478DC8959C5346DB7CA9BA8E1C8523C087D3C157E91F133FD31D764E8B8C94788176CD62884D09BDB452F5B5ED2103A5F1FF393FDEC8951F339A9E82E6D7F5A90769CBEB95891F93D20E39B7A2E685154E61B772BC9E4A92C7EADFB00C7D7B902C2", + "message": "590C53BD0219BBCDA80BB6259B17629CF4A0741168696D95AF63F375677A6014F5CE9A667793A578157C3E0C1490480EE28CA305E7B27EF472CA50A791D149E717CAB6E425452898A55BC3E65EDF60FF0B8447B06178DFACB3C0ABA02B4BD3D8629DEB749054932A3D057DC65E31B41D6A7BF365AAAB84033F4639B96F669D2322211812FDCA7BFFEAF15CE67B1EF2ED791A06C86FF6FA7AAFE93F0B547D1B99EBF9E5501E2E387044635BA42634EC7F528D378AFF891D07723741353BBF624595831A689E447BB1A406528DFD6CB2F01E7BCBB7C3B11D066283959ADFDD7696F05811D8240BFA1E45FA3B1D8F808A07D12012B256539EA75C3F749862C0ABE023E10D87748311312D220A62587945D71BF85A8BBD9A78FDE0855C363C28404F5C9496D457A6FF2BACD04CCE507F2CB875B1C1A3100874BAB6642E73AEBD017AF15BE18432BA88DC9B6A9432542F610FF90AF43EA231AB3E18C98FDF839B964003A0FEB28E25C369F064D5BB478D834643B10F45FE041BEF0D70A9F52478417126DBC0D775A5C00850F243BE21B8AFC2BEB357C40CBD1CC37873574F2E135B3322F674F64F41F99B761C021AC7936265C0D8097FAB63679BD20F196F403725530C0B51841E6F9AC73303287458EED391E298875467683E747A9266EA092D9F9E915B089A2445FD472C70E7EAD8E22E38FA229CE0D5B6AF15A676CA1BB7C7381BEE00568726CDB47F785C0A167DE5EB44AE1EB142488E9EE7E22F68D9C575A4378765CFC327DC56AC65E46E739E92440E508F915BFEBF80BEC37D637D7A1963E6D0A9A8C1F33BD33F7AB002C84C616546ADE3F2285C74E02F26C3FEFA1CD15D67ACBAD504D8F1F143B7EDD0DFEFA782C278804ED78110A1A5AE81B3E57E8B2D4A8FF26FCF23DEC7FBBA7439FD198EB1DAA97D864A1BEC591C8AF9E39FEDACB7F0EBE96DA1812C3FFFCA6AC4DB2C2B9E9121A092357C1833FD93F0FB63DD91667E4F6528B81FD27A3BB202624FEAED0C855CC031532B065613A28D73FB68F2012DB9AEC839B0FB5253F4BD3BD22CD58B07EC6356DFBE1F2D179ED9B471256EF9EED58E2475F4F9E9B3A0F072581DF5ED56FF996A61E0D7BBDE23BC329AAEF243661558C7192C8AA157C537B77AFD50D3D174626469D50E479CA850FF9550AEEA576A6FA8F1C661B8640240702874642E23528349984AAED6BE4A8E7BE4EEA397355F2BDE2C732654BDFBAF17ACCC912B2335EE39E8E44983499B1C171B1FB4131AEC3CB99F8864118B6B2DE2CDF872DA61AA9A9902BE847118CA679185B2C0EBDD7D0F1EA7F3D5BECFF1F76D56624DB02CA1C9DC0A9291290AE3AC7546340383D983441BA89E7B2B86A52B94E78F55C53FADC58835996E2199B8BD221E5C63FA85DFFCAB278D5EF229FF7679B32AE1C806CBD1AA2F8862D52F6BA90791A52BFC1EDFBEC9575C901158F410986F9D8D42C04EC8495982DA44A95407B89FB6E63A98E617416DA216CF142A2C09CC0B2A372448BE77E0C3E335212C6B6E2BA53C84FEDDA49AD5B28B7EC6A90C3CB7FB7014C3335DDB3BE4173D80ECF3F920DC782167E4053D20ED6A8124FA5CF800632215258C4BA4C6A368031AC5883F33B07922A10DA0D91096A10ED7247EA4E73202082C27A999FF1A2F07BE16D3C1FB42A6A29E442A036C4E3DCF264ABEF5AA2719EE878482DA521766CC100D284E65C758961A29CB0120898DAE02FCB166E63F14E664398954D8C0CC6A454B8DFAFD3FCBD8B0A535BF0D7D2711D85A9A1F81AC189D07258D31A0093B50E9D97E479B65099D1C3312FEDD1C0CF16A295E1310B643C393285F07DCE70BC3A413DC1A6E913A366EABD5C56FABC5672C6918ACCDDF63C5F3EDD9D59C7848F1F982AAA383395B83D52BF3737B37B06DFEFC7F25D905464EB65F53CA151061611F51FD2018C363AC8FF2B1132D192547B7EFE6FEDA6743F6A3C367E6E5EA75873E208DA07E685CE4FA598D1CFBE9111D4639B58B97A082ACF27B8975A85E051C0FADFD3F366B806C7A7E9F5C1436722C390F44EB0685343B60C30CFFD5D76299B6A1536D164B2D8B24BC10CBDCE370FE7A5E4C0BF8BCBD621A138A63F6A5298A4A7B408435ED8B851B3DA7C4E74F4FEB2702A4FE61AC15F626885AA1D048C8CC80F71B2BCE97011F5DAEB80DB2E4EA75B55BACBE71AA8265A60E1C360CE834D34A5AA8D2C40447D3C116A8E412BB0542BE678A051B122729CAE02F166BC3350592CAC8B826A9DD3F60C7D199D34C45D62588F942EEC69D1312CF7BA243A89B92AF7C3057922ACBB8A978CBB9253AF9468273BE0755E582C3215BE2F26287B82C81F7D3CD92C74AE38F4F287089BF6EF5C2DE29FCD41C898349C31EDC0E5B08D2E95579942FBB24AB709324DF69CB864037F04D6A59A182FA8B0388B672BA77B32F913B0F00A5E60F49829D57171587D1799196850E37642465793A16CA6D2D0DEA3BF5F09DFFD1CD755CA2BDC6E774C51953249FC761EE2482D90FD2735B6BEB3F633F8BDAA0259E315EE6FD5CE6FD754BAE7136596D7129C6CF91C29E022C5C5AFFA4C45DBF738B897E0D398BB5F4149BAED5A0B8C6EAE3289C4B4E2CAF1C3E9772B350FB9923204E2AFC445099C6111EBE71BA41C4CF0D4F9F5D80E0C1B686C25DD352C613D20C68166487D33A82851D2B10E235DF9B6BC47A63CEA68C37B2B2D07FD31FE33D2FA1A799DD2F9387B36D030D187468574231F235044273B402F3931B5BEEF0892A44844A8D21CD5EFA7EA5425A8F2A45CD2C6DC4A90E81B3EB34BBAA8D8E0659AF5E9C43B93583AFF59C4386F55FE8BE9D20AA6148A0E8C7873E8010D1C2FA3E049BA2434DC865778EB56492D508F16C458C6D87CC0BF551A2EA0B1FAD1165592E198FE7CC2E4A0BA7776D3DF18AB1925D2E22361C295793836E7298D30DEEFBF3561C869B4F9B68C38AB0249E78C01482DF2C9C0C59B04BA02A3768960D95589B0CB6B29E33728ACB2F8FCC74F8BEBAD609A568668A07A908BBBA0ED966975357251C5D33971D284892271402B8065A3810CE2E61EC7EB869E949BB5BBA1CF34392857A53F7CBA5370655E4437093517716C8F659DBE5DCA06F54FF3C552E9D776B84960A7D710106280946C81E28BEE986108A58935EC82890F8C4F9D2CE414D1D036C2F7CD888A12189B8A30E6C98344ED10B967CBB7AD7B412E205122290E1AD5535B75D0CBA91A707130D367C3B72FDD71B62AFEFA353BAC93B376A2FA83497EE204ADF960B6A34BB85200F34A1F0494C35BB5728CFCD9F154E6876EE4D2D272242D76C85BF3392738B7FBC43680832B225B75CD057DAC58DCF9FC99EDDBF3B4263773DD3A26F04928BAF02955A6FB4170654AE886F8B9A7FAA0FF5C4C51E228D1417B31D203806D340CC5BF259709CC5638FBC004C4F5A16955D0CA943455FE6A15B05F73518A6C254FBD8CAA12FDCB7B938092405C4E91A0EE835C7FB5BCE1997FD22362755FE6DB3C1C5366A69FFCA240805125EF6E3C4912D4D33855A841A314333A0FA01BFBE4B671AE8887B485C1BBA218076005CCA9D1C37E71449D4CDAA4EB1B3C51A8445887B12BAC081E0C914617C59272E68E2F6F8BB7E47483A5D21DA6A69445DBD971349AEDEE252C2599B7E2F4FA6F6A814B7F51083B2988E375AF50D83DB7B4844B1234FCF4320D8067B6E17D67F95532E5E46E48CA16FBA6318F1FEBB593EC7B255AEE4FA25065A9C82B1F26DFCA72859B066C1A32D9DF2951D75D69DBC5AB86DDB137EA7EE04951FE912299404D8D8EF8FBB1612ACA3C5D356D2FEBA2644AFAB45F645D597B814C6786E46F37048681B30FCE26B06FE6421E8156002CA0E8E2F069ADC6CF308EB71271C1010C4AEE8B6D5C9C9B473B646226338DD822A3BE3897F0AA159FF3DE4F9B055224C21C759C6988A3EAE980D3AA8F3DCA9D7029CC7496932D81E748141137761C1AE5E3AFF0D10E01FF1844CBC572916DA40505B5B7204808621D56AA6B77CC3FB556563BECE1CFA335D0FCBC9EF53AE881A39BDD672B626121C081C07443E2EBD4E3C1005B13014FD26CE1299169C8F3DDDAEE4E63A1137656A15EFE31A210270A8E2667F918B37FF1FF7E7AA1C91270BEB372946AED7A0B4BCA191E93034F50E792E2A3EA87B7406F493BDDAC6F406FCFF1F1710307B9ED3200EFB05912C92DDD1AD9E228D262B034759C14DAAC0C3B7A62315C311C7BC1751B865D47EBB5FB6E0679B89ABAD1F14E329D7EC93F08B85E379C1F1E273456C3749D0AC3B0F2C1E46543D3546A6306814F8365733F4612265A0E3ABDAA60B1D9DE130DC16340D19800BE1F512F126C6249C97EE90E24E6826E6E04928AC2A274950266C6D5504ACE7C739825D870846EA0C5704CD556DC44E9E321AE0F4E1BA8D3E7C1B3710D27CA16543FEA79C075801C13E0A66B765C66B5E7D40D2A5122AC6E11F64E00A082816BEBC321CD922CCDE04C0F31FA79BACA25D253F39E93B5D985FD8C969E55DC2B55EB102640824919DB7290D03AA8A9EAA884A3DCCBD86C8C0213B406AC0830812C49DAA454635EC9AF2FCC0B1FB7ED3A04289ECED6F865208F7489AF5BE849A77DB09827D2BE1347538AD530F8FBF09BB30FFEE5AFBE31C461AD5267AAB2447460C5071053A039F31E4E8D18CCD6DDE1EC3451906CAA6C74C0EBD81CA12185D0939217C6EDECC004A05B901C3302B039C9F3993082E816789BE50D13B4EA4EAE5AB02B8D1097E58574E48883230869DE0F8CF6FFDFE090BF2F286EC36234F928DEB3149CD0CFC6C0F36921239745A0FAA86F48AE032D617F5CFC4CD758D8EE96082FC8C3F3123D583B0A1D316FFDBB7C0FC7AC50DB0148A78707BF1E17F1CB10AA812152B1A0B254B023AF5BD4E8870C0A64C923E9992739728A74B566FD7BDA65F229E6F9C5D0D8EB85E9F23ACB21FBCD160B83DC2102D4782B188279ADDAAA15DA1706E4441215F8A554EC6D9F548B0CEE5341A791B48CF90E2B1BDBC97E307257918F463EEA1057B32580ADFBE2A346F44BE7DE5D01B7596D35CE5479D91E2602E850429B8F58D6319EA9591DEA2EDC8F95B4D794436AA7E41AD587B041F66C7EAE982ABF32DCA9238C21B7B99B7432BD7EA660358CC4AB130F7568287C52535662E4822CEC4B3605EA6468EE7DB75972FDF402954CCF6320C5070A68D28387F5003570F4F730B1814BBD04FFF5601A19EE4AABF447539BD3E9795D9DDC71B2EF546E4E97D137CDA9F859F8E8A34CAA2294E6EA9572DC535ECD422CB4DAA9EB4495A83CAF92BEF0C8D02ED0AAA26926063E3847C7C65897811DE146D2009DC8D904AB41D952E85ADCAEA0EE0A6D713014142D429382FFEFE7818F87FD9B9F79BE294E2BD28D4A3370DBCAB7A6301910A5DEE2617A5BE227208DCF23865936A756471E137E170F0685979E85AA206DA6A515E12442F5B0DC4CCC32E183DFDB1F5174D803D6CE2696F325672B382EE3636F43035178981C2E5AF4D1A4ADF22BFCC2D6B49D83CCF9A87769BC6F241BD12E60E0D3BFCCADE616026BD0C0669DF0AF848B47095D545442F2CFFF6EAE2E9A3BC54832AEA1B07819D001F1E80FEC7876C86A8DBE579666A38F756044B7C6280443E0BCEF04B90A1239AEAFB407E3B86314B724D632DE2C82274757ABD2A1B88FC609CBC85F8D2DED30C08C84289DFAE72132F67045EE0E1FB91C6C32A64AD2C622C841F2DAE9A60B277AC430EDE59E937A0DF6A577EB4817FC96B1F5985557F5017A69B72164F517E86E5B9DF60AB66B0204880E3FD4409C8F7367C0018E798308CA4BA450A098021C2689B877C78B6466B38401E860BF4D1EBA57C977014E7226D355817F1D2E9606706EFF215F56D73CEED14FF090665E4BBAB17F36AE728B25BB17CEAEC84347F384924EBF0AF7D0399E67F98C642D3EA20459B255221AA8CF2DFA293F8065A4D86DB42DCF0852957D1691414741A91FD4475F147D2BA5B7A2615711A074F6DADFBF3B3583F185F118C6EE0AD9BD1A164F9A9E266B45641393382F54F97B6C5B117B0E5157F8BA627DBA69D13F48EFC1B6509D0CC01845EE10932E3E6403AB72A81D43C98ED066DCA75E3EB12374A6C1768358A4FE046865348D31CED551C0BC6B9D55D60A56551EF58B11387D8A6B4251F39034B0170FFDE34E2FD3EF6C67B896BC3B9EC6F8C506C808CC0E025BA35461112B3D0A6768972C1CDECF6D1D27B189139420DECC538D309A9C28BE3C1AC21D8CF1072DF0CC2ADD0A6B2A85F5A154217A3A1D2DC0D15218593DD68235A1874754C50E71593BC330B1E1B02E7BE66E612E5E5FC35226D28B725059B3FCDCCECA89A66C6402828FD9FD7F44A36CC478B2F1C36F047C10EDC12910F3D905C0AFF6852CF2E49960348D62DBE44FE80BAC76396F84ACD353E78C8AF5C4471FE2A5E1BF2CBF193AA2127670425863AD78C6FD5813CBABA26F2334363D96ABD6A4DFBB3F81B8AF09048A051B271C06982DBA21A19AEBEF9DD56377DBB81DB4A72D9D8C48E081579A689843F3698115E6FEFC43F24DD96421289BB0E9531791487D7E9C3CF2F58461AC6F8B0F1D0839965CCAE359663215C9CA7F4E64F30409E3A7510B932762A1E245AA2463A33EA066F0B3FD5D0B48A97911C39F94E7DA1BD0D32E4DBD7F2A4A4A17EE920FBB378D6A14263F1EE4DD11E51E7ACD71ACC9C0E7B9EF9B30A8B49D3FC2D23A1D3DC7F3DF354C6EA8B1D5B06E5EE6620C6A0D2C420BCFD7AF06C2A672DEF0E4A53B60DB8077378EC91BCCB7818EA1F35F276C30A777658E09486B16B4057A7569674F00524599689AB493B789D9101A2D86BBFD446A5BF44BB31119EFC2436CD34680A1A8CF8A0B24A09B036BB1412A625AE907725DBBFA18F7DFDC50CE1925C80F78CAF37265068E3E4B005464EC1B8F61E808F80B7C4C1184241DC608496FB0EF6847DCC09C4A53D102EE99DD7E3D05A5D49A2DCA152057459B8FCCC8E7812CE4DDC291E1B1640C05D31D2BD391AD13E0E6BD9966448EB20A399E34985036FE2EB23B7A821DEC536DF07258D72A90E3C0281D0FD5BFEF104854BFCE14D1FC883BE45664756D3BFDE683594564D706BA07A30694E862E28516A0E7BE1BC2E6C745D73FEDD49886D6BCF562B844F5B13002CB90FB99426F6BD23AFD0C43E8F3594B9E4B1607197598AEAFD747CEB4B003AD2B970F2C225580FD46F75A212576844D316CF5096E5BA9CABD1DEEC36CA2D9951E21BA6D308AB883548462C34055BC9E9AB4718E4521DEE6043FB6DAE8D571B9CAAA86E2052EF1A2FB4A3B3D41BE0A63F8D7A8EE5C943FA513CF9C323DA3DD8FB1B4715AC9B5664392CE1284D6F2B59071E48EB665336E4BF540A77B6294710DCF122FF75E7C58778E1E11CAD034F5BB4AFEC6BEB19CA1E1BBDFC7123CE451B488F2B9CCADF09F3893305307251A1BCC62D45FB4490A0078DEDDF7EDB4FBB7D11536D4EBF1588FAAB31FB8B21570CFA3BD8C1DE4C576FB6DEEBB253D9B42585BE26887E4CDC95870B9153B4467EF34040B93301D479A49AD2BA2B559D938BFEE6420A15984DB46ED99557F0F141700A4050E765B30BC7C93B20CB004B6E1D628144F6B7883490271EE60D9B42DFBB9EBB77C4BAF60D43DCFA92492875D255E6319ACFACE02C81040BDD73F6E8C15B844940D3A0554EFD51F1D6E30A389B0592DCF55D9E6404DF8E171908F45F34B3DD9C81C47A6531DC8E3934B1BFBA991E13D2D32A9B9FF8060EBB38D231DC3785A2959EA357AFD7650790FC976B139AC7EA4BE52CE5D7487C40D97452CA396C8AD09FC45A828369F9FEB801E41B38DF820E030B9E66082567F02026C0A8D61D097418CF4A95A9CAF6E94B340A3E389D669A1C28E842E1A2A0E95A034C79534432C3401DB89F799F37EB4E8009A90FC1F36DA014ED08E04992D16FC434E0B6446955DD19FF2C0A07AE0A31C98B737310AE8FE403BEBD9A10DC3F49C3A628A968B4DAF37DB9BD50D7705FD18718BD89DB9415ECDE496B1E5DD296D750047B6680924A86144F08269A6E2D6EDD1B6DA7B4904E3E0DA83CB33BEE4385DF58BE05DE3CECF5C0711929D322941AFCA70DA158762F0F0A5AA26C870AF82E79DB492F882A15EABCC51DE3A05898AF15C3BE341DBC6128874730F426A9BADD55B9826BD2A9DEBADB2A5EB99EB7573A4EC91642E74EE8FB471BD867E5F1151A7FBB9AF792E6782B05A58305B8A84360AF16E53CC43A99F0B114524AD4E4605F301662E21706503305DA7C813E99109966AD4B46504630E19EB2FDE31A7D058227C29FC842AA0EFA5C3582F51C37A2AEF76CC8DA678821D0DEA48C2500AD6887CF99B8E14807062F88B2CE71160F862BD7FE908305D51BE0A3E7D048D996AD2BA79904A2637AAD88F0CDB08268C5B8AEED66BCAED81020D33C1B5CF590F6FC39353637CFBD749194AD689326A958FC00DD603FD6D0E362DE68C117F40E5AF183F359DB64C5950E2D3C8C913AEE899553106A4F8179F092109AFC64CCA1CD203FA381AF3FAB0C6A2CE1B9C763F4FCDACD8EB8C22F999404A399867030C2F0E603EF8637C856240BD39AE8157E942C970B2C27BC88D110C5DA4A0563B7DF0415F7385B8F8B0807F44A40943F5E6F4EA8FC3D5035D7E71E5E7E113FCF4A6E4C67D94685CD3C28D45B61FEA4A6308ED71A1950D10346DE5C7C0597B7606468F3EEE7C4CE358968F8CE409713336424F63672A4383E5D332CA87C0F3535F615F2753209CB27C449BE528E2F377386D88C3ACDAE7557DE26F8B2EC937E48BA87FD780A9A0CF05EC4E4E8FB166455E6183BFA57F0BDF48DFC0F3FFA29EBA931B968F3851E8BC2D3E32B8AA20354EE65F2DCD83CAF02237A8396955DDFD48A4E86EB4F04CA48C3F078AA5A14387724926D1FCEB43A301D096DBDCDE17C3A7E3E3FC21A27E65B84C191126CCD0B9138507712985E13CA10A113365F4E095403E57866A570C79BA4057DE27E4BD1303FCD0CD6357F20F6A4E533E2C38B6001A30F5D3DFE4B5E4526AD91B854B7AF4383D7C1C050AC63602376B103B5EE4936BDD2992D8F5408018E5D8399E0436C55E8E8D10DC21ED43C3DEC92064CECA2A94772FBC10D972C54E484DF24E9A14DB57DFEF0589890A9B993A6C5BBA9ED866D826C3A2DF8E954D841699D6BD867E302A83BF4D35A2416819FF4AB61706EBE82F0B88CCCA4F5F171D14A7DAF1248AD3F07362A676F76250F38DE22EA5B2522BE19AFB486A7EB39D2A364497F344F60C2DE0686932CD732A43E34B7DDC794D51ACAB1FE720B8C468ECA563FA21B6343F0BCEA7E3040ED701722BF12ED790329E20664E3783F1CAD5D37C6809DEF5464502230E1F177DB7FAD293D8FB8E97D554BF32EF67FB465219DDCF50CC09A9A55B178FB6BCE4E1D10FDE497DE60B9895243871B374406DC4B8DFF2F0E87D86445079E49423CC1DC662B72FD5CFFF320CDEA7DE524E0A1F3FBBA372CAAB54882FA4197D1818773D028ABFCD837019682BAAAE5560AD3A5DDD91FD0B50CEA886304A9FFF282AECAB24188B8CABD7B12CB70441732194C2CF934197F4B39B458E176BA544ACC06C6D1DCFEA237CCD9F6596B096A65CBFE1E58F4CCF9497FA7B1E4BF85A4B4D47ED5DAA9E23137A421C52D63FFF3EB9918661A6F28", + "rnd": "42F161D9B99AD1545DCF338304DA9E05030313D59E7EE1E41B6D2429A4D3BCAF", + "signature": "7D3F29D5E2354EC9D7DC8CC01DE6165F9B97EE1D180B55253CACE1BAC314B175850A6A1B0F4AB10A6DF798E4377422D6BB5B10E28A28E3E301F9FB04A08F1CF0FA7C0C0196EB81B53398FBEF6BB1ABDB96F1CEF6AFED32600890B00F065F82C08D51AFC6D7D501A5FF81903022E3808327EE3A3FAF0A51BB6BF5BA833477317FFC72D18BE52EF8C92EDF4D114650C2911CF691FE75D9DFF178D8BC90067AD74D427766C87F3E655A6A1E3E520D1A936C53032E8288AD2F17D1E9620AF478F1243FC398B418EDBFB75694254FE934CD16389C8E08E913F7C27C08DC6C3DAE0462BCCBAE9663C2241C36DC521E707686EDE3A49C3F76A1F30E53980A2CCF83548D778DFAA8609F520D82245403A5268C8DD34ED1E60E8EE9E5F264AE40F1834BADB50FC61EDA3CE55F2B8A485CB52FC340F0E900CD2F9A05FC1D1334D5C68D09955C52AD0D42E41F301BC66F267E9CD17EF15E8F317D38EA551DBD91B083C10E30ED5FEDF363792493421281780B09C0E1BF66ACA4B089CDD312997C4D20C2331B8E5D96C299578341897744201DD36559AA94691D900B03EEB8EA9228AF32A2E2039AC43F14558DBC5D586B80366C5439D29C48AA81FFE7BBA14D89812BDC112CD37BA1CD0AD289684AB7F893B8815580C55FEA63384BDFDF8D2D8CF65A08647669F26ADDC1B40A200136CD544BBBD247DA65E2CFEF468E2047BEF6709B091F6372873C29AC7D35839207EB3815ED8AF763C93E20B68DE3D2F5938FF3343942CC66BDFBEDC036ABB965AEA65A828AF7A24ECDBA05CEB7D7C7F6E539A48510D7E8E2204EA819D88A1CF6A419FE1652F7A05E4A017403934991AFB3022466C578D27AAF85739D8759FFB846D097758170A1E09DF6CF8A3C8DDFA1D47C3C530D914086F3D04B9D1D379AB671BB97B2D85E97E35A0C7C25473672A963D11B8377D42D16FF2DEED857BEA16D4DE80F815BC9AE2AD276309CB32590863DA2FFB4794E0D736E45793B3EB6F5C0128E76948DBD51AEE0EE00093CA100E51A18702ACD7212461436E505F5A269EFF59AB9568ABD83CBD40550DB1DAD3C7F6BD05A9A922BF76CBB2E62B65A9F39D66AD00A1849A7354A5DB1C6C5F6897B8D35A56D1C4761E248FAC7496F183385FE332976CF670A2FF9D9051615B95376BE741AD6648EDC13A1A877505E92300471BCEF86242CCDEEB677D35CF6A65FC0A9D8C2A580A6EBAAB89E16CCAE06DC40A53959D60492844431037C6B314947444A0211E39DF43130F8255965409A537F8FAE179C0E9406B6672355AA3065C1756CBCEBB52634DC5DF4C6E73A4F880A1037A0A9387C1036354015736D7668E6EFD81321214E6F4B30A82D0664EC0148BA1DBCC772B00345C6CC917C6CEF5092B5C90B8DA75C3D0FC0CE6288880F3D9077467F0A93CCF96AF31AD93491BD775ABD7740F096D2F938DA0BFE8A4C731176413401406F48802497D23F39ED71E2A618A5796748AAC28B8962E9ECA0247A8D922382C3EC809EA4E47683280E3DBBE35984206CD89CBBA9F0DF7786B053EAD6DAE5B33CA60528054836245848F9D57D9E0892FC511552BF9835357E1B0CFF94A351B515A460C4E00B33B205330F7E51B62BE0264C0B54AE91FB4DE78A3437D8F9F709648EE510D2D173970130B48D271A45F974451C2226BB4EABBB8FAD9C52C194CFEC68CC83279AAD1DD651F5A9DB5DE16441D810FD47ADDFBCF107D977F361C415B6B7993AA7C93358D1BA3C3246EA982195D7F0BDB423891FFD24FC67DF21A210803A7E1A9920BB7BDCA0453F8D657C621508A8DD76B4710E7F4E9D52D1244FB2BA336A8CDF1A84A8DDC92A012B64035000DA2B614AB559117AFFC799EFF47C374C486D1F848C78F636E5DE663A578023E41A62DD94BF19D18C877F8928FE31BBDA84593E97D05172F49D9DE9F6596D2D477F43BBD58BE209DA6E992C26416153FD50D1CB9976DBB381FBD8CD30BCA0ACE9B911A59CA3BEEDF7C11CD2C83E74EAB21161BDD5DB654036D9831AE1C569AF5736610F889CB55865BA821C9EA5E53545F82AD8D7B2731010C1B5A10A6CCB626C87ADE983CA21872C87CA7FAD8E8DECF72E53911592AE9E9E006F3080EC8EA6316192DF0F78F73D95EB671D7C00F74B2D0EDB0E8754D5B2070321430FD18628A690590371D6A025BD1B54F6BD151350265573693E166BC7FF88B2F7A8E8F4202FE4D17A51C21EDB3EB11F7C9536DAF86268428DE3F093E0FBFE93D031B3B6852CE63F67DADD15947B7A28EAB9DDB01C592517126217E070FD724A64F44CADCD05B37C191D4E7F225A87171DF8D1AF8B26948B0A2E0B02FED18F1617C1CFC0DDC62EB5040BCE74951FAF6D6FDAB7BAC67BAEB7112FF4A76C6F8DE6619414B890D40250393E547AC6A5904A07B47EFAF0213A8DCE341527B7F1B050D066C0179B274EAFB2969C20737F57AC06D07D92DA4FB1B23BAF60AD6F2C9E91B0E1AE238DD98F163FFBC812DC67947C3FDF29213A820F26697AE5433F14EA5143C6B10DCCAD3EC7EB45B9DA0754BA94B9ADBDD319B93E92EC1D0E1ED9117E82F62BD4EB72A24ABBA7058CDB11D7D9CC14439823FC81DAE5EE5197DE8D84700A96E09336837B5A3B8D0B8270E4E58D64E4BB36B2C91D2D903F8B312BAB49562A0CB25E26412647F309D54B31B0718C679096DD3245012B825C27BD072C2DC265E1A67B03C367FE6E7564ED6416B14DC371F8C2DF47FEBD81FE93EE5DFB67AC2721224F6AD72C5B34C19BFB9B5F5BC61E5AD5420D8C608B62BB52F48E76DD465E946EB9716CBE9E9D64BE433F63ED7DAECE873B47BE1DBFD7008C90BEA1D1647A03D58DA652D5FE0E5C3C1BEE770F8EC7AB46138051F65715175D15FFCEFE4796B309336C108F4FD0A8838505F4AC6E422138CA8141C5970031170C49720BF5D3356185A466AF1D915A9EBDC8EFD77FBB1104BB103D1F1871FDAA46942BBB18D700F986E34C7764C36AC192E2229EECAB49967ADBDB90CD45CFDE7BB5BA97FAA86FC6A163EB3B3552DBC092F28A107CD729ACC7D176314DB68D24EFE393A4363F118F1CD6FFC53B6AE1E262C15CD4065C3AB94EACA62261CDD8E83B89C2E7F7B23D809E56AA45AB9E8C89D7D1969BF923F63A801073DD2E0C0A1FB95749D7C7A15270C4E90A2868005E4A1149A0D2E67AABDBC9CA822595AA6FE9E97601BC421D9917ABA0D753075F116E17FADDF3A60DAA9BBEB633B19E593D86F73A8DC152EC98440BBCEEBCCE3DCA5FFF3A9D789011A37E50B91837D6FC6725F027C603ACA3D0D0DB19BDDB15FEC86AC4020B0D434569ACAEC3C4C8D6DEDFFC040F1A1B2433435C5F769297A5B7C1E8EF11213036383F424548497C878E9EA5BFE2EBFC0C161A3040424C4D565A71A3A6A8B7C5F5F700000000000000000000000F203345" + }, + { + "tcId": 19, + "deferred": false, + "sk": "07E588E4638FEFE3F4972E3CB7A27F03306DD4DEA7629C8ECC9D527F5C766E5F8016D12D714E8A95330ABBDAB2883FDCC6DC786C5E0775960F7AB95C1933558FEB8A8CD030ABB7E359BEF703C14671B80F005BECB0E3D84888CE0350A7FC17DA3BBFD862D2833A1FB07A077AB02875F2E2048899CEE2B461BDBEA7EA687E9B94E03808621412A0480919C48D1A89712310915C3622A20244A3C46D414089D4A81050846512940C50028E5CA0510AB22DC3B4642204860A89494B480D62A08CD4864053846D52067091060C03022ACA0626CB98109938290846005902008AB44CC91032C20860C434451B240E120961D090855B90480B232AC8246A4CC240649801C44400103669CB161241428854A884D848664094051A82650AB66511B5499AA66181140CA038429832021A351103246ED0464511496E82340EE248408A22091949685C864488A02903363161121242B04189B2210317061A054C99362021A30122A220D43870939825494471E49469D0964452085158A44920A30922278A5B144D0485088882280B22480B228651B884031184D2B661A2021180A06400386ADB842C1AB16D92066EC21052628821584021648885018904C2A809E384401036840A00911C104CDBC680148548420801DC068E53186E028989C2443282B4500B154C01824C19336E8B04900C2621531286E2002D10C245C3C420114730CA0220594630098901989481A2144C1A398EDA8449C24409089104D2300AC1C885C2B051D4B0818430084B4891224451C116315C24921914280CB60D1B204A14A87100B191E3C08009178C02C98161442051960D43340521A15150181002B0409342440A206E24A12864980981468D4A360222410D1AB770593270131082E1988159324E884069D3386D4B94285A268A23C2441204885C3008CBB44408372E64B404D2A8241AB38C80C0049CB27009382E03234E89B6908894519B461153C28051886C8C988053480EC30249C9126112276E02056DC19050A0262413019014104D209860A1964DCA0649DAA4880285894324429C120588464403440D0BB70DA2A6605B208410B970A4064223160E848405CA40128C8205D106844B002A4002291A2405DA046290B80891A8110921451B110412C101091985234608E42864A338005AB4458942211A852C12157159262A802640934226234784C3406158B4095C0092DA206523000DDCA240C0922118A54414824D12C84504284A19A168C24492198140EE6026A4DD266730D5E6DAE34216874D8125074CED14BBA9ADFB6B48A203B0C24CBABB4962249543446443414EF7D6513E95344872E6EEA4396C4D64C723E58701024DCE31F63B68F8F1A5F2FBBEC1814EB35FC1B73792BD6352974D18AEEDBA8C630D4308A6FF6445ABE1A0761CD94CDF79D12D86D4B2E09115CBD564AD610C4236A042755161EFF35628C38BA4A5F32F981D3B20896E054FCF9FB0E84492756DB96CEADF00B08D0D22629725FD41B13E88F306FFCA4E494A4ED5AEF63AC0E57BAA87F141350A4B37135E6AB987F6D82633AC889D949ABCDCEA18B5A66B5B4569D744F18DE5E47557E23E5740875F18128A0E6A59FEC550EC006A823AF3395CF325917139D2640A1F022CEAE100F4DE50D374A33953F39353DD36C8E1A6DD9F3A61569DD096726C06D3FE04C60EE10AAFDE52E540843DBBEF5CADAD54A303CAD53F89E6B90EBBD1F1EEABF169C38086915CEEC09F49767F739DD8447F69B150AE7DA2D9D5CA17CB8F8E5D06DEF50FDF360EB21E7684B238FA7557307BDA6BD654CEDBC0196169EF9717772CC69E1EEF6AD0D3B17A1844C0E2C19F948AED7B6C54A8F5AA18F1F768FC13F0CCD9B43E4269F374421CD209AA19012D5A890AB9F60B81AA90A85B8366011DAF7FFB16A27B6A71633AF71A98972304C1D05A65F855A257F527F013D73C3FA430F240C5C43706912BA04320C83B9AFC88E82472BB84485CE1CDB3EDD9B4CADCF4340BA66B431F26D9DFEFF3D6DF4E0436010E27A8895B8294021F45A0439480E10DEAC618443229F897F41CE033FCAD55804B286ACE17CCEE330863FD38F2F765E53D2D63F5FE43CDEE04C417164064DEFDC7B0EA9B05180E344C40027CEC5DDD0B548E0180F496FC52C0689D9B6499B10577EABB091438461AE2CCCC6CDFD42002FB25DA23A82E48622013844ECC9123178912791A8E752BF89089EA659BBBD5D56CBA7B3A90E6190FD0556832B7E60CAB577A9F4CA2D30D3F9CE425988540F11DD17E306268A1A98BDDA8A63ED9CFDA3D3B6360E7E45AC261E1499A3E952895AF2B2D60655AF609B63614727917F5EFA954C728F3943CCDCB88EC4A6F540682C0AEA9338E8C767D26A7F56B6943BDDB177CDCAED01956507C9FA31A91449A5581E7FA19D195839BBFB16AE094A3AA0EEC4BE45E81A3252C9BD00DBE38D0CA548569B213C45648AFEBF62C9054940EBBF7DDD1893392A187C8A153B8A838AD9A3F53CB276CA2E5FA07009D4F71B5AAF4C898397E8349788E69ABB6253FAF6E2F09067CA6D559652DD55F84087ACC6AE475C120D6B094E65EAE63773C1DCC6873B3529B9FAD9BA59D3A89F57E661147DEE109E25B418257CC7A9A66533964D98B92AB49709942D9298A6EF217F332D1E24E1F09B4921F8B9F43C4CED620B06E6BF58B94E4FB0620DB5D49A963A87E566769769B49CAF56DE726048A17684E81A82AD8F20E1960408F1347C0CA759746663535139AFAF53DB854AB54795DA2AF5646A08D61366CAEA401BECA71ED91D04B9765763AA609F5901FBC2CFB5003FE3D47FAEF8000894B0FB49B19401E62EEF3A0B0D3A55EAFF384C46EBB20F2F08FE0E54B813295F71D20F0089F2EACF912AC6F5BE281DE643C75436A8E78392C25BE7F15BBDE3A718D8ABD86E6E3A23C6D386CD22267C7796ACCCF3B2EDE77F1D71FB21FA3BDA9D8497188EF5FDC40D545C738953A62E4A1D4EF216C2A87F200A68BBAABD88868BBDDE0BB7FDB294DA43DACEC25FDAC9EDBEA763542F8FCA4DA1A4FA606915FA8CC0BF7B10E9803DFF9ED8818A93FFAF1EF9AEB10CE5D3677466FFAE32056A1DEB60CEF20283A763F09C753C1F63A9A55F58851625C5FB96D36A7A9CA74159C455BE80F810F7C3A0E9401F2E0B5529669D19F7BF2B7E1990A6FBB57E06A3BDDD9185EC8C83517C15D2D5218D9D244488C69A9EEB8595500FC1630055CF7BE445F9E7FC0D06859B76607BB52AA0753E5FD64CC2DF3FF0C6F95089C48DF5799735D9F05D9ED48B95D1D035DCAE96903628205F34EB369BA14586AD6534B6443A07ED8078B4E02764A8D341D417FEC7642037466FAA2B16D5C9811547CA167A21AFA271C52E5B2B2D9FB186E4A6B713C1F9A3F027EF0ECCB169171180D823C98D29950DECAB3186F4B5A1E00DF70C9C9969C914D3148A914C3A2AB35753EB2C7B276DB6050595AE99BE821442661104260114B53A303F5E3EEC18F5E2A246AAFD310643F8FD54EBB277265860207273841532A9EC06BA360FEA7CA191E9F91107E5555E4BE205E0B7082C34065C8A1F538F1263F138EA04567C1F55AB7E777B3881A462FE2F7C191F3568F3F7FA747674634", + "message": "2F09A83481E7F53782813589CB28FFF955E387AB4C0BB4964CC6E863AAD637F31C36DCC162164012105D6639695599BCB8E7A0F31A9A060BCA0B4BC2FA0694E8BA9FDF65E5B8E0F5D6A14552177FA19788E2693EBEF193FC9BC179430B16B355AF7DB90BED229F21265FE4AD96A1CD444E56D9AE5B446673ABCD8785DA0654BA4FDCF3E4C4F0EE6290C48325653EC9224654495FD10331A3617DFCDB8430E6A98449EC60C4139898B6AAB18DE7C8F1A7A80CB5C1AFD8043B3CB8F85D89A50C42526AED56E6722EFC15F938D63F6E5B5ADA86809172391371A0D3D2F310AE92EF80F0FB4222CB2D299D28FAC349A40F0FAB080B1C948D324EAD0F21149BCC2410BD827A4E7D0762E6A2151FA587C180C1E86EC034BE5071FB3E794A84B1D03EBDCD8284CA66F77D6B3DCA6C068971C7F794D3E5DA89F192424DE146FA729FB00F1BA8164FB81595CD4849255092BEDC8574BC2462DF5966E3D13DDFFCC5C6B5621BFFC466F63BB4B936C434EFD5647F2DDD0BC12802CB0EE00F0D8B6CCECB927D39FBB412EBBA9035E5272DED3975F15CA9AEC75743EF5ECF11B020877199E063B26E64C7C029DBA4620417609B1F902F95FC06AE2F44EB9EC2753BC75FF339FC88C90DCAA48759B05DF79B2F8D20454C777F7BAA96682DBF38094E1AD9389CFE33A481E16C08AE10A79C175C0324A8109015FFFBF16DA109AA79D25397004C74549E533530D561767A6D183772D8380B5DE61A26ACF09C86DAB2B7CE7E297EBFD389353B2F05F6AA3BACEB8EF47CBB6247517C16C020FE89DA823B27809D2365FC0CB32E3A7F5CD9FCDB46AB79770915D9386BA28E7ACC87B76FBB8CDFF28681576405FE92959AB2F30B908CA8B6F8950F1A1A071E7ACA010B46C3D43250E58C67EE61710C1930F43F891C597CD7CD7B43EDDCC47FED70B9D61217C289D93C10640C6476313C82ECDF99F48E34A01423084DAE6E604A98CC6493AE8E050F8D341851FA90FBD6C8F15B3D0F17BAD44C84A11DD1170D54615E9C5F4CFA2EDD29EEB1AF638025B540D964BBC2C2A9352CB08DDC6C2FFD3EE37BD11F453CAF2CAD1EFFB84DE685DA610D4DCE56F1D0337EE19BFC27DBFB29A6FE96E95B87C28DA8BAAC93F52716C8ADB4B86858A33D79642DA708C958E75AB1F5DF64AE328F1A76A572936A356025E965550E36AD1E8662441BEAA139331B4D17C8564D002D02C3EE157729A0BE80184841FD743571794B2D64DC3452098C1C9C3329B5796E2B63C943A82669B3C721503DAAC550B881417ECFBC2B90CB06973CE0DD67E0D155F3064E2CB6B3F71AE9906D0059A0C8FD799B0987CF6231B1F5FA5B1E839D588F51964B8D4E311D4A059E1F5D42C100F25A647AC06F22EC3F939C5ED4FDFCB809EDAFC159922262F45B79A9BBA2C54D54CE581B3CA6463F12F0DEAFB02679C3AF59C1229015CF4B75A12106AE35DD1D434D854DC1AC12CA1040D629DE9703166228DE98BF089BD91C1AC74F70567FE919BC47B43DDBEC8DF2802B2BEEEB663CF0925C2E1EF6D98B02C228AD39054A3C6BC51444D4F4A8BF56FD8F99949D9C45C80054BB92EBAF2E001BA9E69A428B821ABFC98A302E3D454DEF19CE25DAA7ABA8C3F0C58764FB355045721139F6AE70CBB4743B494408B8C6DC208E20FF73732DE3DC49B256378EFB12CF38E703216E7E3ACD984ED48F850CA21CBFF3F7481F7E59145B642DAA994DC20FD8CA145BE29B1386681FF1CD413E41765DF085510BEB994D42E5BD8204A3ED8A1C16CEC682000C44440234B9CB9CF918E6314D87D8DE26A790965BEEDF58899CD9BD693B5727A7AB775D2F319229E39DD49CDA8D40C748855125EE29AB84A17434C7E3AF3ACEB5C1BE8E4E206477CC7EC0067381CCBD64BC6CA3090DE86639C67E94A95FA8A4A4471EA74AA484B4295B33D690E44A2008DD278B53DE15D4680932D2D58ED3005550EABDA2D59B8B48C0821FE151706B9854237D60FDF48E04C17DE62FCC75AC7A1428004FE3752C5A8789486D1A95E5F0619F4A3A4E147D513AA01701F612D208EF39773660CD379F5DCB747B46C9A5D87EDC419F7D9BB38B5F611D1A148926FC048F36BF6E64CDA33EC8D602A0DCB357BB2B8B1C0ED79725F8E59B2D70766734CD1557FA2061040AF94F7615C1AC71FA8F8E917CBEF3115C895720726FC6F3B5DD97AE11D643E54CA749102033217C19570AF4642B45CC7C272E3D06ADAC540970A9363EC6C80484F2BCC18A6F398AC75DCE1EC3CF635E14D674DADBC7D80969D47F59BEE8DAE776CEC4C88A59A2F0010A05DEB6152889C9681F18AD3ED248BA461A2D603B95CC3C8434EC592DC733EE2219AE1093508401E09453B5166CAABA1DF5518C91131BB9157106992A695EBBD42E1AE98D66B098A7BE73564EE2AD8BCD16C38B82071D3C023C7643E82BBF53EBA297C4F878D1E081D494AF4F1DF58BB5EFC5EABD495D6BF212615F47316C3C6DC374446D637B930180D5E073104F639BBD7555682D165FE60527730BD26157B408BF9E8191492A442E17D3A944711A856C32A88821452D61F6D5B78EBFC118547F24E42BD4D0CD65FE76AE5A7855BCBCB533CCEBB5D6D9EDEA73525FAE29BADC714CFF002DD0B8391D5D5FFA3318D5483566B77A9E8AA07F2512FB8D0AEBC35D70E1724E9EF1226DAD6A765556FE00E6015D4A72872BBEE49A9EF24F3E66A493B3B5F833FED7A680D83EA55C6E3A1D186239F4AF7F7613691570254472FAAC53C7E49074176220F60CCAE89A94D355BFE3654AEAB96B78432910961FCDB24AC0D93A2FC3FA017DAD24AD1BF8B93D79AB90F2F7BDBB858DF6A88A75940F44A427C2A1D70D7FE5B2DA220670466221CE9FA4A66371DA0D62B148AEA9ADDC9FB394F47D1988DC1E51F364D2CA1D37D5A552385134C3D998A5DC29B42CD1D916ADEC23A71C087306F0D9693D0A80E98C65747F82C3898CD73C11868D8ECCF8BB316E52B3AA9C4A25D4FBDAC09A15AA2C69B880248C0A85FF9FCD44662D4802CA9A0353B4AC5244E6990C8D48882BA58077B4D5909792BF8522FF05EF82E332614463EC3F9622E03F4918B74C8FA7FEA4BDC64960AA462E8643E9D68C918EFE50581DF087D06247C1147FD7C619026FF98B977D81338A7E35EABCA1DDE3F4BE21DED04EFFA18A3C3A487CEB297C1943E4C7BA8150AFDD20A71C92110C9C8F3EFFA854DF5DE636B30CE72D5E53329BC7FCC93E6C22F36775BD2D353554972368A6D01DC443160D2234DC74B7259A4EDC51E7A82F05350F1C6D97F56A096B8F819E52F9A20EEDAEA5F943A23110D40CB3983FA0E418C2BA9F732BB1F1BB0666D60D858C324EE71BF2CBC1F2BFD482481E89B17170419D062B8447892AE07A67EB0377B458F3966409AFE2821FED3FE6FD56916C23F2694DC2DD7FC8B2F1CBD54EE1DFFFBB809FB0F5D463DA8F60E4AA4DFA7AF6B5C949CA023234F7A38C396D8972E304978CE0784D46356CBC6C80F7D52255EC5E554732E6778B9CF8ECF62B4120461057BACDA2E6D94BFCFB2F418ECF2CE49AB87B8ED0823BBF642EC7519843309BFEFB4F24BABC0D68EC25C96DA5DCBA6449843A5CDD1F41607C748AAF4EC670C668D41D49337668D41458AD12E2B734EFDE1617080999701C44839A229121C09A37AC24D9CB997A618D44F64D3C86E316971BD10F60A8728DAEE9E2AED8F6180AA6E998C5CECB0AAF2678B17C271E0527317219AA2C6783D071F2A5D648A1D93EC01D6C41AD1489B0C6FD77E478E38053BF2B4FB135D928132B46DA577CD1AD9D5C2960A772C45281244E83547BAF174B4A21A7F53F356820C4DF060095AEFE4952F2938F2FCA7566218FE79DF9EDF232476F067B1BFF90EFB98F71E72B73100CEB7D416DE15EBB509CC2F4CF2521AF36C63274A5BAEAC7936074EEEA1B1128165E0CBFA923B964BB15C065E292F064A77A8DF953896E18AA266527461AD01101A487C089C92AC3C085FE14D394EDF887BB08BB2C13CC9D1F9588D3E779EAB92993FACF8B781FAF35B90D20278EAE32FA4CA130D4FAA5FC741339A878607DCDA625A381C7E74529EBDCB6D10F41B0593E0033654790DFCD15C1B7D1A20B8CEC8B1D61D8E7ED332EB2E9C1B3C7BABD2BE4DBB4054C09EB08FD8A6EFB15F812AC907D8CCD6D9534F206806E3398DD5783BCCDC9B4B71C6918EACF6D1CDF39AE211C59901F3E7AF9AE906B21B621D6D76AA64E34C3192E06219DCA476643C45E273690097048FED2F191E2E3BE3D07E23235B0E03E61E4B125CAD91E106B8A91732A5FBD04080D1B878D95A8CB54D0FABBDBB3F1D4388886F395117D63865F8739AE378E38C2BEE5278519C7E8D74737473CA46FF2C43FABB99780C2EE34A0A1547E80128B18375F4BA6B613E4411E745800B20427B405B9C0C3A66F22098CDD98FE09064C9F37F941CB24F87EFF6F5F06A3CC7A12399F5E84CCB2C212792B6F9E341353A12517247AC43EC61289857285B9E84E782A11AC51AB2B63C4B2BE809236820472F518EFF144A524E6F109B02F7674D0F9BEA520388548BA14086920E924B81B3AB5E8FA89E10C1E4A4A329A66406C2DD2A7A44A52BCB95BEFA2D1FE63F06E188C6FF19BA347789D09F8DCF1E1385DE607CC10573C448B2B518C41027F1616273C13D3C32773FAE2FFE18FDEE70AE831A551157A17AA2C5F33180F9E29787F98D6C4FCC96A03371C47280268A3BF43602B6B7BFFAFEDEC39DD3DC75E90410A024A329D2B6B139D2150C46703E4099CFB77A0E0347BCACB74EF68DD072488E0AE2CE67240BABA000BA0F6C97A61DBA1BB44EBE771F036E9BD7358E66C1F3D18193EC8DF85C4E1E75E11D06B64873ECDD5D4FC443CA21F760B6C3721A21912DB0B5B50B92EB175B889288990674255F594FBFF7EFB48736AF8F790FB7C6A0FE7A137ADBA7CD3C8D552F78CB00C176E9C67B48CB201B413B816CD8CF786C8AF15D996A8D5DEBCA920AD00320E01893784EE17C42C80E97E4A0C8C7726F475D585068E3A449C5CB42BE10C9B7FFE1F458DF3816D5C4EB6A313DA443292E88B2D487F302E46172A055B7312E324FC588E3E1F5FB122BE55B634D4516FA2B8273DC43098D88D5E64EDA4A32BB104EA78654AE7EABA26505EE057BD8CAB04CFA9872516CD9D62A37629DA8602809FAD74C080563F4B3F4D5492CEFA7B03873E73A623CA5F78ABF8BC89322A087AE32CDBD3C114EA7876CD52848F79951E2DA853E200E5AD7A8135D56ACEB51891D2E30C6418A8ACDB20748CD145E0AD80638A3F4BBCDA5EEF90F37C6DEF0BEC029E97643CFAF9A96CF310BC5FD43E6EFDA2C575BBB8B6293720065DC1159FEBDDD4610FB3DD5046D846F802E6117FF6EDB5910DDBE8C063AD4B428D40D1EF65F6F6CDDFCB2B248FAFA05D7B1C647579AD472EB17A95E1ABB32C3AD86CFFE636C115665B8A2D3D1C670CA3BD937390E823AF8C2708B17A5C51580C09488B9B525EF1EFAD4C99283A6E3662F5F23303C035826308524528B1C2B2F4B367AC52C90195F19733C66B86B7DF6C30623C0E460C74B59A549CE84F882373B720DF1ADB66C532007A1034EB1DB7A43A94B0D5366914938288B98E33966BA768B2893E5B1A01E13773785B9FF63E54E3D07EBA308C26405F3B34DD47FCA579D5AF2B29729A75B94FE1615CAA73CEB665018BD80F405793DCFBD9D1D350C298CF23CF6EACA3566EA98DFB8720023C380D072D0A95759CA41ED8CDC8091E464A69815EE6ACDBBD920B204EACE5756CA9C4E2F01A9A2B192E097C4A6A36618EF73AE0FD8CAB001BFD21C836AFA3A6206842032A9716812A660D0AE7C8D9DE5B41CFF25206DEAEADEE7A069BC5922738F044234891A35EE98CE7DB3A58EF9604BC8EC8D6DC97658C8B95CEF6000D11414762D65EDD9BE90AA6CEEA6B6A3942BD7107A9D7D46E9BC7A201E47BAE04B8775245749BAC070B65659D45785E088E6F117CFBB9846487BBFE8265E9004FA7EB464873F8A853396CC02D3C5C2A994908EBE4CB56F0FFBFC63E1DEFE573CC93A2F96F11A8117953DCD2EBB8442BC6D8ED68D9B694F1A15A58F18572FC300C57797267220387B2E2A178BCF74A57B14BB01A1FF2CB46060A1C73985BF31BCC98CA3610F67777F20C5AA4FC9AFBBDCEF14C798DC9C8D68D8969DF99F6930D879E13B8B41849FEC53EE3E8C858CF6FE9B6692C687BB9DF517E4F59F43CB5D6F423FDCC0AE473371DB5F447A91A55DCE35E1B4FCD8830856A1D9D275066B3B9858D021E35B3CD040536B4990024FDEEA69FC0A8F63B63F741337FD7E9786ED24EF56BA608FB7CA306118A307F72B8EAF486A0BE3901AFF1330A19B256D4169067340BB90EF175475EF9AAA52D97025BE5D6AB0009D5075AAE7A987E42DB9DB0B7B8C881CE9EC0A087AA94405C5E6CCC895C8DF484CE4830B5D957CF92FDF1F33A060399648BB872CA30CE5206BC3406492B7B34CED7B6BA512C0C86108AD056FC9AFD9064B6F704915BCB3A889A5DC26068596353ED8E379668505B8F49CE966B57EC637F946FA38ECE225C0F4D22A1889CCFDE203BADE9FE7D25D35A85D2B3B7DA88AB3CE65F2F477A9F00D78CB4BC3BAAE162FD8670F3032849DFC4B61E2DCFF9E9C3095E4B69FFCC64912FB111485CE98A78B3A2ADA19E920A88505EFCAC0CCEB2E8D510A5C5229404AA270F850DB0993DC1622AFB81E2BED4AF246EFE03778CA1B5BFC2E299ABECA2AE238F6073412EF64E627438AD8371ABB7AA50B2C543283A8782C73CA7E89F359BD77FF28E767E00D633412CB114247CFB6ACA39E0887A2E161ED6F242052A908E254CD1006C1681E3313A3F713E585D750941D2782E5BE8A9805FA4F762311173B36B097199863D3C42673B7023AE75C2CE5474179D43F92FBE6A86A952C44B6DAB6320B31B2BC97D", + "rnd": "ED1744006D7253B6BE926AB3C169C15D8A65115A84D309D2D4553CCABB267DCF", + "signature": "8FCC3725A592546EF0EA4CFCB8E5FEF136F3BCA5C28C4365ECD48643BA3CBDA36CFDF15A79B6AB5CA52F025913E430B24B7448BCE8766A711AF62675E92BA9B03E4917A38B8E8A5C01E8FB6D6FF2F2FA134D564C8BAD5D033D15F4B64ACCBB53925519677112951AC7F9F8289F533D678985074032E14C70E8C8EBA76BAC12A59E215E98962198E31517CA5AD82A80719BD5144EE7F2950A07AC70F05C41F41C11D2F051CDA2253F2A6FB4E38BF8EF917E6D59F49E855FA98096BCE99C350F558E98648FFFE14D11722777E04401598CF078601520ACC741BEDA15F0C2C0584F9C46DD594B584A1B0E01DA9B0F3AE639268A8442E9389DC89F13C1F46351D4E8AF79A9D2E2EAE51060ECEA7B8EE93B7E083A1C95747E9EFD156C948520E7E95E833B89D1F559AA173DD3352DE9C7E5EDF81481AFB65ED6C30E5631BF352F87000B1098B0125947CF07F76977E2D08E30D6707C9563DEA3CE0B96985AA3C369E9FCC6F850853E5D838A8FC6F00341FED92AFF216F41EB9F4F3C998A5CA98845A5BEBFDC82DAA9C6ADBCD79C0E3C06E52FCF89587F8D6A694361E196758543C962AD0BBC1373CF1A5A3E213FED1BE534F7F0105CE61457978C91E8027402CDA17843FEB76512906AC6CBE6204309049B3752AEF878D30E4B976351D44858B4ED4A18155690396CBE9A01CD1D3835E326524B9ECACC08481F38EA670FDC6C2A947745DA065EC5954A7545F5F7C460A9C4E8B2AE6F45FCD0461E427B895EEBE216F8A939831E888C596D03C3AD7D44AD88F8E6053D60F92C7F4831ECD1C08418CCE497B51D4B34E2E1DC77D0C08933827462BC81880E6136003D75A17A1AA73635B3523C6BE7871E6478EA14C6D6CD94027C7C8D400853D6EF34F96C7B56B2D578BD61CD46C256581B43795FD7268450EA0FEB8482493696893E0D85508C8D1E24C8AFE9F5746B69F616C8C8074ECBFA9DABB631B1DC71E00726FACFBA1ED77BC7B1A89916F6C365C3C66602134853D749369EC0328680A6BD1BAE1940BAC57C0F38E04F08E90A70556E0010BAC7E51C61C8A273D76F4C8599F775E2AE712398E4624CF0DD00B90CCE0A972AAB19BA661BEE350F2315BB978D27C4F4AE8891669A0ABCACA55E746E757CE247B21C8417BCDD240922A7CC20429CC38611916EC282CCDF018871FEB4A519E75CA7C2DD583660E372CFB52D05F6D2E343DBD23154834BCA5629F6A4933BD0C844D4BC94DE037BFA128CE3DF0A665A43D90AECE383AC0B9F902D5B3292E200759266578E7E3CAB484E76698118C882599D665DFB284324334B45EE120B8B3F13D3553B769B94F1DCC14D36BDF6AAEF0B39B09183F0CAC4720232D378EBBECCAE3E57F00CDCF3C67FB0737C717D88624248C6D81EEF0EE50697A79104D6965D55125ED667EAC00902EA4452FFEE293E691DAD2F9D25DB3CFDD7E09283604A641F8EAA26825547A37F7A54DA1CB1E0EA24057716C9C00DAD3D1F2CF4C448864B054EFD792E20E354D2741FF59D7CBF980285141BCE17996A1C3B2E1EBA7A2F110A95A8703177A9CE17B43F33E57F56FAD2EE56823422E03103558F15F4FEE87AD4A450F35F71F3D8F57954EEA5372F635A916A40BF5F3A077A9EDA4F05CB17A53D10F8852520D75B72288746CAECA7A21530BC4A0DF00F722CE6DF1487FCC3F5E5DFCB1B75B54C4A798A57FD56E68A16788DBBB5FF84478833D2A9257E32BD1A562E9AD1E84DE2EFF6E69E99D9E6EB7C8D99A26AF4D4997A6B75D787FA8680A48B0B93E278DBBED17219C271598B01CFD9B20B26E6F9AEB9BAA18D217927756DA90B6097BAA62B4FD817EACD175032EF5ADF01F66E421485E9291AFCAC659600A49D859D2A85CE26CC4D439DF1BD7D082DD8FC9D314EC51E23F87750BBBA86E502443DE00853C78FE7E2F0D9D0C65AD86C2D853A21FF2EAF41D69BAD4A596564AA91DA8FDB8218BA0560A1CD713DB3207EF34E2B93E3509848D48D85CD44E367C20C6AC29F21A262D409ED302708805E11E588F1D9F84EB5968DD9237C6539BFEEE2E0556A8554339E02544952BF483D2D677D0E6C11B5F1C376975CBBB38EEF8316EDFC0EF2EC95A97B6ADA113EE1EF5E1D76059E9DD90DF14D4B3D46A0882C510EA17FDA8B50059C0A4E608B9603C1BF00FAAFBCA27532D6ED03A3A6D1A52111C79BED5E50A3F289468B632E4BB3ECE19B3E311C7938551BF5A5DD0B017638B016A4E17CCA10E1E858DB155B5998C4EF9769F1FB8A4F502765D9CC45DA68D2E1AEFFF7288F8979C12F01706662C7936D20B19217558090C025761533019E1A2DAF200F68CA8F46BBB5C8C1E10DC8B94B23BFC8317335DC049D9EB3C8FCDBEA0C04E46167B244F2044AE49AE24C060332C9B6CD25A3EF4D6114E67ED25978904426649A3C5DDEBF63E809646B77E1124A75F1890D082E2B9CD0E5C27D2DB46C1711B5D89D74F65E5DBD84E3FCAA0035C76801AB84A7D0ECC6006A28CFF2EDB9032DA3FF73E38B24241345344176E4E0FD185C8471332559CD47923A8BAF047F868EB0141563E5D80779EFCD90EE2D191415C854240717497AEB4A52A0DA1F2B8577C2200FBFA34B4D470EA08007BF451DC6E918E4F3F80C6E61A20FE8129CE6328FD56B5B91340FEC24ACA21C6CE6869907330B0F4E3DEBB53CE58DA051B5251E7F707B1B67711BC8CB46E5E8F13C00D66232C3FCD42533DD10D27018513888F2147476D7609D9791AC88608029406ACD700F2D8489DF68369BD885AFC2E7345F2706BC331C51CCCCF2C424F0327E7BB6FD1487D49AF8C36B21951B761495D90C14A024094D8B614BBEB8F58F3FC8E4B4AA14364E553C9E40D5691297269D33C3AB28DAF3025A35D8F9930EEAE76CA7DD104C037B3B7FA98586A7D8DA255CFBCFBBAC90D30C5D83E52599AA22DD95B05AA5B123EA281D06806C4A747703FE2504D8BF88392DDB8979B11E57ED73646F910D7E57D457DF483D176E4FCC808B51F3AD990844F4E45C1E34282D7847F59055A6128B65F2B8B22F0361619E55DACA5E4E26AFABFB032C82CF3D05829F0FACC822A96E515834DD57EF359F93226C22E1E801EBE16A3BCABD6D8F4B78F15F41E879DA5F9DEB44B2976226B4DF771216509B31F60908AF3DAE76411AEEBFCAE9A956AE3AE98E414802471A82EE5E8C5691DE938DA98D1E0DA9E8815041067214F8913D9FEFF5201F320F388E5129D318AC55A9B99D585599E3B254A2515288CA335B4CAB4775D4BC5BE0FBC417FEA855217969427A4AD55318A882EA56C59C4E6CCCBFFF260E3EEB001B2834525F6A888B99AEB4B8B9CAE9F110202829334D6274BBD2DDE6E8F3050A2F454B4C5A65B6C0C3D5F7010D3A4B626D898FA3ABC5C7CAD2D4D7DFE1E60000000000000000000000000000000000111F2C3F" + }, + { + "tcId": 20, + "deferred": false, + "sk": "D6D7BB2389C3B486EF060EDA3263843F3ADD561DB9E36B222E0FA21CBE60477BC41567EE2E688929334FB690F9B9691C37E91A786AA5A721A2D53446A042BEC66765FE239067701B83B448486D32B941E3F8CF7B09560A83EF561EDD5DEABB4CCD9F6F72AAF267C5A34C797D21E19FB17994336E148F7911B36D6619F0885C819B44211A3620CB82304026010C2228DC024043C844D8B648CBB0119A4805C03231D4106A4102891A2961D2120CDB962CC49665C84210242691CB808D1294611A48704340811C9601D4128904A00CD14025C4444211484EC2184800C2711022441C150AC1B229242626219960C0984080120AA0284CE2000008294ED40880949450890482110411C9260C53808C8CA66499B24583B41020234C5B180D54442414938C600806C3C4494C144A623604C2106CE2A4641CC888A4A63189020A19C98549806CD8026484364291969119282014912D20301088400688064E10000A130310039611628480D8889019382E10B52D1B266A1C20215C16608C106C99448442840D5A1069E33841913440042042512425D22661A4028A894491891029894449DA92411C12129C168518066419494810C47109C8441198049BB0892142488B282D5C840C11C551C31422D2222508C92C9A900C09174483C6911312501007325B960D19388C8C068842046590B089A1A229628020CC36092207044C28691244620C3002C1C47081A40C62328A1C4081A4486692B80D1B082820B64998385262B605194711C31288CAC28599284908B689E310500147890215529CA60D13184241A6514012440B188A5C2441084851C138669434001BA65041324459382A5BC02C001062C818011428048C46041B8910904681220641D3C861031986C9160041802D43964D4BC24C030601E4468981101062926860C881D904680B169003998844842CCA160890208904364041244E140582224732E1382C1A126280985140144D494242E0C26408828858A869C9124641C6215CA46808B56CCB226504C44C83120101272E614428404000122711A4B48401C96C83424254988C84B488D8400AC92885D92202204301C4402062285008C050039881C9486DE226014A42018B0442221285C3060C188110E0A4310C058693B4440843669A248412203103A2519C020A0AA42850B204442240543262E3C24C0013120898511A018D92946CCA426811A1892132705C42225C808421354404B35020A168DB9224CCC64D52A891201806E66FAF50875D34BFF31BA21D11127E7BC0F3734B15538D3FAD3B8C9BAF8BF81D73AF0143D3F71139DE0814545B31D8BC812095ACB3191882E0EDDB738E80FD41655CDE17145F76B0ED5F7827C392ACEBE65119890AAA65C248C0EF8F8931927A18B5E32B5C5980562EFEE0CE8525A79B8FFD94CFDBBCEC6B60A692649313AB767A2BF49C17E67C93F2068F0DC65D7FE0EC784A3F66D7D3EDFEA614771AF2A3BF91CAF0A02031E5581178E8FB2443ACB381B057A1EB30CF58C9CEBEECB0C6653DC628B6540476C4BFE14FE988FB48AD41E7CACBEF5FED11411674B3EDCB52BF128B1D932AA2D73565047BD08588C189239D4A9B7CB39C1DEC758CA97249BD1B6560A7891EA98937C39568651EB95C00B7C9ACAD4682DDDD532E5C4B5317EC1E42BD0D6D629F293005B168D985DF96E5EEFD7DE7EC41AF1163D41A7C694BA9E4BD2581AFFD2BBD76982C9723D001C537E6E71B12781C20D7B1692DAAAAD9AFF5509300F313E289745F3D74B533280AA38882EBB67C6BF70B80BF7D4D251919C134130F73FB0638D2C09CC7EECB1612217E136B9579D0BB2D16B88BAF9508C6A7CC7AA00D86FAF63B696D865F06D18C29C0229D70AF2C8F013753393696C07105595456DFFE299A254FEDFBB39AF3EB74BA12BAF5E5E027AFA3AAC9962E0D5D2F47DEBAA7631BEC88D6CF8253E4051AD23665F1218D2C9CB3D6B5ECC05B657E24BCEE2562B0EBB02FC7B347374AF4A82BD0519BE333B5718F5E619583EF9D8042BE77984E9CE4AD377839CFBCC0526CC557C6E5622A34B18EAC4307D3387DE7018814F4573FBFFE57ECC0FD5866EA2A4CBC20087E6CAB7D2322EF2507A2778AB8E4CB91DBCECE30777E88103ED452AC7AEAD64DF62B04FFF2DED225DE94CB0F1CE60EF463FC092AA5AEC38C0EF412071C7937B290FF8C7AC03DF900C3FC37119FA3D7B669ECB071B6C469358F4A0FBB78D728EFB36809B52C46EDA4A6C17C70AD26CD5155A278C7F4CC404F8655B9255A343EC463F2FDDA23CC6D3DFF04911A457F2F5A0939F20DDA49790C9285EDF39CA662A384BF4CAAC1C8605337039CC1E209DBA5A3EA1C2BF65AF1C4E599E626C91EF6DDE56032BC3D65352C4C8754DC06C3EA7E3942D9E34EAE10DFA9E35F6848EFE5034226FFEBE43123E05E5B00AB3BFC5F0B17742581F622E63A64E00CB2056DF3DE16B64CBFA4458AEE2FA83A27913E65DCFF5ECAEBF8C0A79F31C2EDCAB50AA47FD9CEFAD6DC35A326EDE7FC46330185B195D6F132738730D553CA91FE4B2DB2353655D9DFB29D78121FA72827D1F222E7BF58BC8F96A8AB0988D8A9FDAE0999512BFADC6205AB4DD3EC37F6D578E5B5B91F30AA2DC4F96B03EAFE2B354F9A6769432B3A4B916EA5629AA9E313E486090818E20D34C0350AD4662F177EB5010F47CC68D8D435EA47F72A5D8739222B5ABD5537016114764CB18DEDD82A701892AE115B00B675AF3038E33169E918D0EA82167C481DF35B95B6E79F72D356F6EA7326F7EBEE215F6DDE2818DF300B4AB96548E1BBE731C62D90F4ED53B1721FC2EDC30D22900ED6DD15F341D6F905401082393941615E8D0BC240F8B71F2BACA80DE7C18E76DAB633AD5BC34F865EA5C7481685C6272AB4FB882A613B39462C2E64743A47C14AE43B18786B7700A790E8600717F37F5CF3CA9A3D784ABE8F7E4F805D7676DCFCA8F78F7C65ACBC564CBE5734CC1B52DB0BE6BCAFC9EDB80118D7E379D946196548AE787F8928FEEE83618BA7D15836376E235D7213DBE23237F6590A1224A42436F84645BD9B5D0812E0092665EE8BF6E1EF145D89FD0DE71D8AFE69CAE8D94953A7C17289951252BCA1E055E31B013A650376E20E388284EB33D8F951EC7D80E2D1C5AB1A06E7AC3F7EEB0F639EB1A1E5B6C63EE21AF5BC16CED82F13AD0A57674FF448008BD213FBAF56DAB8233D64313B4167423D378699F4320147AB1ADC424B2452869E6646248186AA0682178BA12173A1A28DE962EFC591EE490E7F505715155518DF03416F03706E2C457B14C970BE86E5AE238A56A42679BCB114E6C6C20FD7042385DE15BE862D0D523F82190E028B78B01826595D3C05B2791F00DD58A9DF665C4F56B2A21DF9FE13373469FECFE05C3257F0E55285D74CB52F2FB230728CC08A6C3A9BD8825FFC69E188A132FFC9A6C8669B0535392A03CD777A49F0A7B1094328303CE1B67F0F92BEFAC8462561D8877E9C56DF6EDE9B87F3C1BA43D50D489CE7AFD4036CA0B5CD5536AF269429E1FF8CA5E793DB233B00FE2FA5ECE573AD9BEF553B987371221C79F61EEF5AA5519CD7607EF05D9C07726A62130C610D3E789A92AF", + "message": "D7D7964C12AFB6C20C1C21C7DB1781478482158DB275D289785004548B57F76355A31FB4A3FEE01D3C63F4992A050DC60A0A31E68D1ED6F68C394AF3CCF22501B64CCCE9DE8C52B668A2AC886C5EC3C343D146B159AEAF228DFD40F5B449C0E8EB61F8EEC8519751BB8B943C4163F4CD2FFF3C8CDA1162AF3A953A76DD0D41FDDFEDEC612CF3C2805D21C2BB5DE9B7C7741E03F6469FD6D8C324E18AD1F5727E46F226F82B69EB33F5832CB1E926D31C1F0C6C508C88EF05E617CB1726B80389D2ACE13106D7D4E06E907F36A5BDF08E3C0843D57F452B28232DD0FF4959C375B9D16EDAB40F2463E1EB95B7B11332B7171471E92DBD5B418696402B3AB6CC03473049D87407A3ADF27092DB86B2BF64580BB5155D0AA503A9E2E257BD16D474C61B6970778BC2CD2ACFF4D3C0052368EDFE420E2A921FB1A1C06336D5CD7CE64453E0A91AAD629A1AE0A87DBC47C40D19B7253AFD18C7A7C5841DD926DCAED34CB11B84133C2013383F27F139E436BF9A891283A1C9975FD7F3E63BC09BDA41D2E261F2065E972C3BC60395789F9AACC0DE75001D80B5AEA321E3AA695CDA3CD59F91D491F69D108A300356773B81BB9E4F979AD7AFE063B7F3E9A46E225C3F1D7AD0F95A39FC57794DB0FEE36CA18CC652CDC59BF7B6A598EB0E8D4D165D3B2FE7C318C8470D6C1533928E55794EC58137BBCC5E8C26E193984168A5128A0BDB0678323222C3821E2C52C2D8493EDA54B4A0D8223842A819F63B8CCA2C9868F56BD89454A37A210FDE04A0343FD7CE250B943E7A7F76B39ACCD5AC44D36023CC8701B01863E5E8F21B5798EBDC75EEA27F5F2A4F64EFF61BF0F73A8B6C3C6776F07DA92E7A4D8536E3A36A7691A392066019803AD7134931302A66E81CCC9585CE2A8F6E7B4FBC009A0162AE20274556E0565702C235A17FEB257D364E1F3846518B9DD7FA725DB81B427079933556AD61B4085412E7106C0289E1D907D7430B7BF5E477D5A70AE8AA69EAD2A2A409CDFE850E912AB33B3602727F045B07210515121E9C0355336F4532074D1E13DF818E3DE029DD591E9991E7CD0816501BB2B708E68126970BDFAFECEA484CCD1ED07B955577BAD90EFC9444330E35E25B307B541A3CE35A17E3B59B02EC55B2DDC5F602EA72809706D245CADB3E7AC07AB1D83FFA2A9214D26507D50FC0AB53C77082AECFB094346F767EAD51B6C01EB9C45CAE401C226073C5B37EA6F00D857F96819B5C3484D660185C1D8B06DA85E4ADC61C462BEA480CDFE25487F44DCC9309B42B3CA4CC7FE1A2D92A642E4056193A72F3BDA18F33C2BD4029B366793943C14CCB5CF3C057A183BED55EAD054C0996BA002D918EE0D5101FFCFC6E029F7737D86A7B49ECD33AA0844B816444E2BA3C97B605F0711C2CC71449C7FBF726CE4039A390C089A04CBFF19EADBAA7EA5AE7F7F394D1DFB1DB682B04EA39932C3E3205294E9FCAB2302C87E5A24C8457CCFF835B273658D36988435A72B9CDD4A593EA311174E9DE421F29EDA549391EC29EBEB70E38BF2964179D377E0DD15A192C2FDB6A47F58AB69193E65FBCEB07BFC1674414E600D46E557907FFA070D60589AA9050F9DF2AE2D29E0E0C2E7FDD1F9CD8EEE3D7E4C3BD7FD44A71D85D55A0A014DF990AA398AF4A1BF8AABE5443A0EADF5CF510771A69449BF4918F75FECA49CC617120C7FEF9CEFF5AF14D07587466D9E6D6289E6D0185FF61099D66AEA50D45B216C9A97AD0B685947E78A068A5A492F73D1A0B10FCE32A1A9A98B47E627DD392B6ADFC065D1700E1389A502BA09AF9BE1BC82B799FFB5F12CF0792D198BE2FCEA440039E62ADC06993AA0C5CF5F9212C694C3C914C78D2B94B5FB41E81948C45F64625C1C7620B585A77F172B5AB718425136524032515CA02CA016D051AE1851CC107677E4640CF7140B76143D4834DCCBA396319A907FEAEA40807327C9811D9344638F93E3E5F777FCE0A24C36F0AD133EA9E2CBAB963FA01A6BDA5B84F404ADB24B2DF5581B758651ED30D01FF5461AEBF81BDE2EDFDE6268D7AF697C49553DB0C2417D0B991B5A78019B8A08A887B9C546A4DA21C57003B8298E6365FD97FD674978A7BF0B5190D23D93AED3969BE74B15570446CC77396A00886D29FD981BB07F10A48FD2DF1C4AFBA6A8FEDA043096A850FE09486C87FE087A9E27AC8C78E69278D7C7229FAC03604CB3447541D49EA009A6767EAE2956E7D72F7EE28C97AEFB1E30BE92E0A05ED77CB761B36FC537E970A4443B73F4D3277AB7D2FE738027BE76B43A79CE0F545DE1EA737150C19FAA1DF262A45615AF58BA7CA234FE30B1E038C2850F7F45EBD348AA51234D8DA42CECC12F25605070FBC3B9BFB9D29CF8330DB0FEF4FE7C7B4D27C2F4D71173026A2684D1F673BFA137B7738BEA8303A64D8162965FE7CAA1BEC792E50188387F5F9442BD78EA79959410E6CF903B32E00CD48D1F80C296BCE40DBC701943B22E7713B71D73107ADA90F358F6A4BEAF7B37BC28C3B6AF8316B1B5CDF3B50A98FD079B7E4FA66A9C359833BF13D95872B1F1718AA240B9B9E5636D880F46130E4017324F1760A0ECB25E797D6094E67449C51416C35AA03F46B2DEF0832CEAAF15A4540A5D9247C60834D54270007CC453F0A4F9E538B294118FE16F26B92197A0E97DDD594A64FECEF94F75FEC1BF281205B9B4B49B989381AD54B28106CF57BAD4043F288ECA0DA569858DCC344166426265F600DC6BB518A66C23581A5854770BAA4028019A87FBBA912040B149EDD0ACDCE95B465365143C30C306C5C84699D63F061212132F5BC13C64418FE1597962E92060F22AB611CC623B20E649382ED2B0320AB350C9CD3DDB85FC6521767761B94FFDF7294A0839B962DBE06D274728D9730668BB22B2E7178A3C22FFDB2F3E2B8E1D9050F845B69AC5D603A0E4B807B8EC4050B492EFC6E05EEF6EF0A30F9F768CC5153EF01519C3BB0BAAE9933606E93CD5FF6AA5CAE0A35C90761219619660CFA6D6EBA1348EDBAAF67F73931370C4F1886239705F1D53A0C6738EF0B4CA3A7F4E0D140B08719F0F6FB9C31E8179C01F76C6E39C15BEDCBAE1E412D39E4B64C99E050CE3803BC86C0E5F2F2BD84594E9471D3C1983C8844AF09446C0DD9D6E8EE59B542653172CB2E06764AA09CD5F28B4F060FCDA4A64F23B600ABCFEA8D372F928F9376E49E9B80A1663E8CABFBAFB513579B10067B7EED2C2603CDF36C944503F69B4C8A05E2EB17154823937B49BACD9E3B7FD33A262DDC1E7CC689B296EA89D208F5B57D544ED76E4A2CA95A0BA8ED8D8089561E170BEC51C9DF54B9596141F17D9E2437474D28919EEB45127FA6FDD180E214D8DB07702D2CFDCA7DE075598F3E2800087A6E70946232258838184E945C352FB3F1801A7EA79FA5B7E28AC4C4737D2BCD3A5906B0960658F68517CCD1B5AD07A439CD0D69F53B62801E069BBA28AAA004EA034264DA6980FFEA0FB9091FC3BE7E45EC6E138215D07CBDE119170643053E21EC95732B4D91A8E1907FC6B81F61381DA1FE2EE9C1F080776DB26C11628F69D6712981FBDC1F441B58D5739548EA6F4D2B7996ADDCB04A6D914F4B92AD00B703150EA28FAE639737AB0A990C5E11C6B844191219937FE514B8305F7357EF26F1E2D2A70EA3B3663E92292CC1C4039EF0C3A381D3F299D6BC1D454315A12961D7CC5E0FFD028A5BC5EC05B2693C025AFC46009DB9C7F250F2CFA998FE795243459368C41FFFE4F1605C49C5438BA566B644BD68E56FF540907E0FE2F3EAB80FB1483E0FA2B99FB9AEE50CAF0882CF01B19C83B789048C84A30A7DBFB893D66D0C5148128D57023AFC466D71F3994B0D3DC875C958C561FA5BCC67A5F39BFF1B57004953900CCA2666DC7CEAFEE8500AB0705BB8AE2D6E55A5D81E577E691679306B5944A4FB7E988124F7C71B06D27A24E50E0A143087B045EE4E0FA44B4A5DA397F0D16275F0BE7B6FE936DEB343F3E8C3A3C9C7BA10213DBBB995BAFA086A5AD57A5FFABB3EC7AED5C52552C56CFE830809ADB5A5331EF6EA8CA03C9F9440953BFB4AB2C7FCF170596EFAD9070CCA5CF6344E3A9DA556202C26F6ACAF201DD09E2D5E90C9F4B756444B5BFB544B1CE1394F5DBC64DEC2998B14A67E5336BBB46A4F2424ED04AC53F0B219603FE234D3A44AE36BD5871FC2514C947548A8095EAB9BDD891FC12C1CBA324383A114E62089EF265D94674F47D843E61A2166863435BB752502BEC3CBA777D225CEF7063766B5DCCFDC3F1920C0E047E28DD4948D58127BA74C4CD665BE039CAD881028202673EEB5F4DE47B162C172D92381CF44255B35F7172CAB556BD0AD23F07BE133B96B645C18B9E88D0A93D3F7A141356C278C296A43E28B8AD0066FDC6C514436B8141B59EDF6D04EC579D9A3B67B5CDAAC1A7435B29A47D5C45153E908AD07E3368A73FE1CE2869CC1DB058BB750DC23F0778A73347BC02B12373C7492922ACA0491F3929E4C52378EA9B072C6590C01C6E67C32780B742A1C114A6E1A1546724ECBE5C351A2096CAA037FA9A5DD3D5CA6568AD8047896E9554535A8B8FC3A0E53554F04B6B25750BE81AB0EF5C96F51B9036B552399C79ED09B76A8F3C8ED56127573152EF75F11ABAD72CC166685CBED2870A6524C83C66A7EFC16C303FE314DC2757B955D7A2AA9BEA2A760321CCCB23AACF2F93B1887F10972A92109CF4D55D2FF333238059A1A69E16BD474CFDD271E1F925153034DF5A8B39BF795938A29761C301044EAD2CDFD46FD880E30A4A4693EB593F8C471020F771D0AD3976067697A0419744766D3B38B15C5065D6DC5BE6E8EF6FBF4A47B36A457ABBE8558120B03E57CF66313F835B0889D3FA7A76722DB902BA96C6B4FF7FA7D87409B843B29546DAEC490A14E9A386266449B76B32C974643C1826778B2AA0D97B1AD319717CC39B55BD4FF691F51AD10E41DFA04922E3571339B08620AC882C4FAC09F484947833F9F08E262097ADFC9E47140356E075851F67ADF9A0BD8BE3D3608E4FE1B92822552690BEB802BEC1336143BC805B9CCDEBFBBDACB6DD6A8ABF4628EF68D15DE1F3946EE3BE5180CD1464C70B484B3A0C4FE7214F9B1BB6C41A4F1048DFD335FA7C8BF7BA67ECB50D3B48C87D9174C9DF8EF8B29EDBCA6DEB5ED6C0736EBC15DCD25880021AB9050285FD1A0907159AEAC28EF4E5A01852FC9E12736CEF4B0A4551CF832C5F8C5E83EE52A73EC70BFDC233BFBE7901679C6584DF9E694CE3552D2BD104F4D7DE9A70F8065D3C7DD7DC3C7BB0503468361656C46AFAFA0D469A3B8F25069338798293E426AF27CE50D07FD9ABBFD72EE44232644D7E6A628E97A72E1B8D4E57A5D82B978F18BA687A9432C56D7894EDB8471C635E3900A51A130CD117A2628395DD5230AD9F75F0B590AD4E1374859B68BEC07E10E424F818C926F5197FF927E24649E3040DAC88C52D578331297E4118264110CA44D9EFB0664E4A183B2E1D13DE7781C59DB1B9DF8AC2EAD3E55E57133F30378D1CF669D80F80C5B78C1388182B688F808180485DCE2DB0AEA1FF412C05C62BB336487C5DF81345E61F880D4B619CC3267A6CE96AF37DC5895451EB4566D54F895EF9A4FE9F09ED7AEB3BDB93B705009D44A7F1455F7ABCEB371B67D58E2111FB1BB440723A17DE7BA238E5A0690CA4BC27797688C05B4D9F6BEF066D758FA3D0DC44905BB13816CB30C1909D1A18CA4D78ED6531F1FE3FBC1001AA40D30F3D42D5FFB9334A1D999CAB788700075DA1062FD96CB2C289C09587EA795AC4C233B7C1A7FABB2EFA26E59037CBC293C796895C6F0306B6FEEAD0BAD82D610339C4674B1AC7ADE70D7522E023B1BD5A8B7DB55B7C8489398EC29945E1B8941D070941F5165E017CE205E0F83C95799830B2737C4A781C7BB98D991C449FFCEE6D5F759D49FE1CFEFA0FC3890042B717EEDDE5DEA7017C8CA68BE3235CFB7CB59EF13AE3BD586626911A7DB704B307ACB0E617C1558BDFA84332F5A014AE1967C6D84C17EF780DF6AF3B6A86A9BFBFAC3C07D16663439DEB091A5BBB5F05520BA12776C46F43B4825C8B04E366E8C2AEEE54B576A9BA8F3DACBB5B940A5A71A41ED16F6C6EADF0F18E8B20F2713A9654BE6615D0B970DD0083E5726045331D7D7D862E0D4D7104F4257EE786CB13231F1B90C717D7FF3A3CDEACED63A216706601FC059449A1F5857DEDCFE3ADBBBD61591486B5991F79832A77BF32F672E1E562953288847C2392466037417254B48DEFE3E6840BD2FB44749A007D444BE5A53F32486249AD553FA882889463EE1D3AE4F38EEC281117AAF77C25D9ABCC14DEF49B3F9F8F99816EC01EA5138DE2B0AA63BC49692ADA306EC1D7FBCB0C155E5DA61677148880F73E6CA9B6688FE982F34731EEFA19BAE57BBFC81086D7FE08767734FD10E607DC52B663241045F026D25ED3C9148BC58293276D2C64E3AD9180B9FC58B6CBD1C700567ACFAC5E1CD8DC2CF434798EB272DFEBC8F2AD0822DD860F822D1EDC53D6834D47D70EA56E5C1A1A3497B133A112D71B250A926504482D79650ABA26E310C4A5681A91998E04E65B57B1505046FB1A4C53F1ED188BEB57D9709CAA54B761CB94E7F82EBB5F2B1D12231E506C219E161F6F7198BEA5ACAD86D5E0C4AB171979A82D81FE5D0A79BDFCB082C529722DCA3537B16E3119F916D65539250D27CD94E847D299EBD34DD0CDA2B2A7BC8302B00AFDEC68ABF1B18AC77DC1AADB3760AF584F583C3238C821A06D6FF2A4B084A800046C7DC715D4407414C2B3F4EE3E2D955758413B02C4676BB38E8042359F9A21C6991964F606B080833F06A033D52EFDA228344AA66E992DD163DDD664D3B31B62E7DA1D3BDFCD8BA2E7A9ABE248DF8154E515E8AAFD0990A64544B39253683CDAF8E9036683E2C810DF47A00F4F7316276029CD009E045BFB30912EA7DE6AEA97A8EB555F06F18EB22676BF58F4D13763EC920D4E0FE5C64E481A5802A4EE878E90A4D076E6F2B97D77DCE6545294059893C38665F98B3C89523C51C06EF69F1CDB01ECFA69DB3772F7F6C94C7F288AA9DAC6F9340B52907DAF4A521E75B1743119557CED3DD06F9D0781C899F8EBD3B45AC771D337B87247FF1ADAC9683F04B090C22842DCE5714CAA30EC7DAA9F987A03BA5D7A62050341A849C2AF2D09DDE40F63299155D76EA841E3E84AFA1A91B1C9F7C346230423BA637E1A4B8DB330827BD6883C416261D700807E95CF66BFB28550525D9C49CA87AF7AF3B7BE7F28B079A7A1B9DD27122C556F9FFD9BD3355735D8BAB663BA3A2D906563638EB736907E0A68F4CDF59B4016C607C6776AED12DE827EF50FA6BAE2AC6FAF686728E25D26075878E603D9A4DDBA6D2E9CD69D3FCDCA8C61146C97D6834F08A7AA68FA73E4A49D049ABADD6AE38351978D3E31A50749D1619CC701C30BF333C36ECD382F41EA6CDE8B9479AF2C2938262F93C9C7127764D2984C5E418318A9146A09842BB9712B4705441C7C2C79ADFB1884EBA507ADCCF2E8E1A07D316222A810A628DA2440BB0B38D164EF6A5DC448C99FA3A5C0B9BA82E3B86C648C64286A2386D9E0B2779ABC3AAC6EC230B0AB55463CE159CC462EEA86EB41BF0CE5A7A793959015B31A75AAF97FEBFFA4416E3567794A240BCBFFC3AC8CFB3822843C269C03039EF612DE9060FD15CC19DB7782136443490C43AAA734863881AAD6A80F3C05CB2BC381A9BAB24677B6633459D51EA61ECA93782C573ED7109FCD90E6D8B388F063A09628223ED6B1289AE98E5525F61281AF5B983C696BB1FBA3D891637F029FE1897FDB3127BE162BA485C2E0D2C4785EF455DB536A79D37BC75FE0550255AE6DCA51199E5516E78AAF02B63CE7795B942D93C92D706A32A30E30580F48C53E5AC2BA6A2E68A5F2CD735BBDAD1CE1BC1F6F291A30B07118247F823457D45AD66CBFC32E9398BACD47D4799E888EB22542883C6A2F21EE2DE14DF2D925FDC74701D44C6F4224344BC9584C1EDE52661758A8221F2B6CBAA91F0542D7D4841593E357F0FEA60ACD64A757C6D9DAFD332425C75D3B81BA9F02D2F26A0F98EB939022271C11869BEEB5E3B3D9BA6F8D9B8914DBB3781447CAFF69778A94B0A118710236677676580FE93F71834CB9F87A5D872AB0B16CA5D6999D826996752E27670083B2E9EB22A3D58D201DEAE16881C31DFFB2E8081904C51052992A2D9D094D6C64A53BCB885D3A12C8DA616AE6FC36AC87238E7B93CBA5BF7E72486CB69E578178D1DD9F3E4A318E2E8BD3CEC44382AAF5D0BBF49AC64E32446A05C9DB689E9C9925AE79973C8D33181931E1FDFA29843C23C5552AF0B7175B64DBBB8D5997606DC1C8EDC7CECECB35E6E541ED99A72025932372C90C6E5213764855F7B31A0D6B2F7B951A5F176F968E518952CA9D93CAD37E9756F28FE966D33CEF2E65499760481C7B2D6203A42A8A7548E5C535406566CB415A8A45779AA9071DF341EA1BD7475E981AF30A9624C921AC7A2A926DF13031087120DEBED0277E37F8287D5C26EF6378333680967F3C62294915AF08D10F46609E010B4ACF81CE9B9979D296F26AC22933636D3790DF197C6BAE40AEC307A1CABF6FB6F90896EBA07E117598B8CDD789C4621082D9F5D054FA13D1BB224CBD0F128B64D9E4868B43F6473D712413804D6962EB7006C4561439AB7F93EAE1E7BB82A9BC491B30ECBFE22757201A19F079A7BC9D09F84FB8DEC4700AD1366D6B4D67578B249D3809F66CE3BFBF932A94447CB601462F4F031DCE59711537599391D6FA4ABE5E7D3FA902CC590B5D77284585322ADA0F4237B205D991CCE10CC2B5FF1D36CB601986A790008866F118E760265211FA1F92BF1DB5BAC7D514CFB98B335A2444E74EA7973C4A6CBE6FFD6CDDBEB69CAA87F60013522E0A17B0B2E20CCEE8546DE6A626B30CA9F02FA6014BBFC2889806CC886397B81AFB1E01A4412C6A12CFABAD3F5656CD6922FB8DC82E4D4C0BCBF1EF5C1F9E8401AD4D0CF42C3F958DE7D45E87CB8E8A8762EC26F7996557F8022DD3D6AA51F72E3378CDD0EE304559F3272D86354E399FD899AE16BCC78A7B2DEB24718988A5156A93D5F52E532110F2D3BF13D085E3369F6D6F5F7761B2097DFC340F41483DB24B0E1C2874C90D37F925787EC0F86751FA65B9B73AE02376BC5ACE3B9B1A366B42801C47D7ED9C5914AA4F9AD87E544C27CF2977B380325745F406112221E238B040ED25349F2123ED7D377D47696AB26BE05D7D42F6BC3FB550D7090189C65C1787044320C03C854C7C7E7FBFF7B82CFD079AE87E09BFC4940DE561246D906BECE764FF9667CA06D8DB7702CB503DAAC1FB7691E5B3438C869AAAFAC70550B37F39CFFD927A2863A980ABC186466F3F08BC7675210F95BCD50779BEDB6387849D0D492A9F4667387097A17B7028940059766E5E99FDC0C8546F33F9B2990B5AFC2BEA2A46B8B5671B0072E1D7FA1C19012C57D6CE83A087279FD344BD7248F38979659C31952CA15D2CD23A84E85827A3E16BFB9C94C461B82BBF735A1293ED4AF7DA2011CFFA7D27E47B92F568B2E7032D57415F93EB53A9876C3C024485C8BFC79337CF5B550B22CB8F77F87DF91467C1C7EFDB43B4EE2F998B76DB2D38B75C6400EE7D1AA8CB1D328514720AFD250E37694B0BE22CB0B610426826724DB7D00182F5A3075BD10CC3D208047B0E7201A1E918E518B8DF59A3F5C8EBA58EEF4A998F708D0ED6F7504E53B4C18664ABE93E0DA55188515F820FF479FEAC2F5088A38E6916E7B01F574AA136784AEF4E2DE4650AF60782D902A6683D1E2E31F184CC0FB0C482905E4903BCE45153F5EA3D02A8209DA42C885452FBA735F913043EF28A7E252C50C61502BF128FE72BFE5DAE36313270E41F3A24DD2558A55108264CDB8D5243887343DAA181B356AD2188445C86F139510A8FDCC1BD9FA4A0B68472793D18B442AA35377A837B63FBFBE26CC9F95BD57A9F89E44194FDBDAABE6E1CE5AF528F9E524DB86C6BD8DAEEC171BF7B3A530ED36A11CBCCA706905291A3435E6A356DBB5DA72D082F4F9C6B568B4835404F4E01BC872B1D1DED357F55D7AC0834217A19B70FBA7854CB5A953EE9A9EC85E63A3DAB778FD44F14BB081F81C389D4CB450067DE2B8A8CE9894C6B6A31C8E55501296170C37921E1E7D28A4751EE07B5FF70B29F31870F9BBE6EF0A1C636E7455F716FDB3FD43BF7AFA9652B163B4889EE2191291E44C660F491450F70C18B5D0DA072AA67F5D79099C0E407F8042D036E71734183E4F5D22BC7C10764C5C883A16D3F433EB6FB6173151E1416E238C5A8B9D539553CBA3CF3B16153674AB5A7E4FAFA30C9D5BD43BAC88E3E21F9838D2B28521A7DAD7E9B9E0928FBFAA639F153301D9A7F53FDFAD442E6C3D848361CAD6C09914C08E7F2956984B7D08186A19C5686681630E924C99E1365A0040522C0F97D8157C647D9A823DB5888B798F7B896D7DD6B07062AED516783D2802660C21D7F69794F386433E16F2C6BD6863121F5F5C674C7303052F6C0803A8BCB0750372F1EE8BAEDAE6D4CA4AB376921BDE1A21FAD9776A7F12C682466EDA5A0D89CA6859D8477D331A38D4D1CB86CA8776DBE25EB5457ADD5D4B386BBFC812BAA596D07DFE08F6C178D73F5355C7CA4B32410F809400A359486761CF08F50A598C299996D1FCC9855C775E599EC245BE1B4161CA229EE33E2CA27AC88D5238D630DE169A86E68D930C311F783FD0FBC22FEF2241CB3B38A2C31F7D5F8FD6B77BEF9D2A9A8574AE3D832C065B41A75EAA010A9E45CE28745B799B0E352410C0128C611F9D7AFCCCCD34F06A3F96B13ED254A16F50E844DD0F3AA5975242E32EED6C9C0C807AB24B715A8789AB38AE0010EE511852FE2CAF", + "rnd": "F32C3D559DC84BDA418EC707335B795E07AEB17FC6A08CBDC2B67FD9EE29C832", + "signature": "0848F20580F7078EAABA079A9ECEFCE67860B27E11B76B2C16910B55CD7D3B9D63EDD5C18C9249D4892888ED3F96CA3F1C8D9714923A1AA95277749950668BFF9CD1A0EFA53C921A714876E9479F749BA8CB3F5E14BA1D09DB5DE9B0EB57F1D59E9E3C93327CC5B43F1FDCB3FDD951A3053CE55D4FC309E224F77F1621321FA2D68D2414EED078352DF42E534A4F17594B6C3FCBD1E524E7CE5CB1DE4DF88CB759238112D65A77CCFA3B970FCA4D22F5B708B15D20397FE55388A6334E6621CF5C586EF363045E548A69492327C8EC60D9D16847C72FBBA85A321DB6B6AFD6B6F5705B2FB4D32EE3D841E8EB18F98000FE72E0602CFC34064949BEA876FD58501B15157F67D0435D11D8C1D51E0B40B9A899F154318D6407509D2BB87C0B2D11A140FD35094078B6484B62758E0E76E2AFEC7B3EB341C754B1C9318454702C181F3DF6DF162673585576E1CCD91E7F8273E9DC719C03887AEE86FFC80D42F723903B496B21FBB10872804D5D0586E9D2D486C9128AD3D291914F73E701D93EBB6DCD9DE2A84ACBA885ED1ADF64369C784EAD94EBD7F3A99DDCDBE6BA33E1A3E38712140AE37BECBD673551827A7239A3C3DC8C11337847CAA66B73DC49EA98CEC66492DB39666971B865ACCA012F9AC55B35CB3E9D09FB3D5B2FBD89165C62F350A14CC6ABC7C5242C76DC41C0BC4D6E7475F97DD0FE50A669C61584C982CF87C66F0FA9BBD295765A0F32E244998FAE798001E6177161BD2F403FCDEA314523263C4D15E914FBFF6F4910861A770D6848E3647B7B71BA018CBB503A7185CDE0D4844E40247AF141D034119B0CE8BDBF86525E6ACBEB530C2966DD37DC2AB1A14BE22A1169C904E2C90D18A16C113661B9D2339B3BCC9BE50E3A69559DC847FA9BF0E67D377267E26D3AC94CCB47BEC06BED307138AC1D5C69B31D299FA4A238F5B78FD5219EE4CE5FA7E5945EDFE4DA917DDBF5CB3BD95AFA3A3ED242A7EC78A3B9ACFB51C9712E40488136148B364127E2272486E32D380D1497E7A845C40A03496215FC6BC7DEE48F748123F22F8A1F0E34CF1C5B44FBE3098AD291CC47848501168A02430E27558EB9F5A9E36B1245DB490B2DD103E7473CD4CEFAEF0E6B2A2F2E27CD2A26B21F2D7EA9710E80AD5B5F8EF39DB220C569A15082626A7D1CFA2CF35549AF242D8357D57C86878CEBA84DAC5D5E9087E9DD2540E695B36409AF2A7E7C17E9C89B9CE5101F5B8FE9C6E644C1E8F3CD6299FEA0978D729C826287662FFED24D4455A0C563908D5FF36984F232ADD262A48E8E03AD50E7BDD998A2EDF1B0B95792F7B163B6FA7FD6827DC407AA812CD2A6EF5562D36C83560EDF50C34470DD28C0F363159A80373AA3802A8BF246A521B5A7192B287A69E94A50243EE9F76009924B7A04EBD2609DB51FA23B1F1A852794E4C749D8391EA335C4356BC566BD756AA9750E653753FA25F197E3872A6D7A465ECB57B20DBA7DF70AA098DE0C68554C8A0E48B4021CABC6FA83BB80E6B024B819A22B6648370063B5F3389007465D3C394F64E60AB253F7279395FADEC592EA0D527BA7DC29A8DAB9578F5065F3D52A7C01AC521C4CF45AA39545D045D83EC793EFACE7FC0EFDB7B45985682D1639AF4F2B1F4363F7B43E47802A77E7A64C53B2D2E97BA71BF15C2F8497046B37799C146FD06CC91D97275EBFB9B089B9431D314A211A8A021468AD8E3E72AD2BB4BA572F5A7FB1FA84A69FE2307A419564D985DE57BE86912F93110CA9E1589FBBE1DDA13E56552C225745536DA897C774B6A2F040FBB37C716BE81000668B5E15A9F39B914B998F1A711DAF7174E121A2C6EA0B2E1D3417D895903577EBAFA98A7B904800690827AD520011DD40A89B58557B1CEFD6C33316DCF5F22C4BB3ED9564BA249B7C5C0DB11553C52D53115EF02D1A9E0B28AAF26BC2B14EE0654CC1CC4FD01CB5106FCB7A7FA0592A5A391433E5D14F7F33550B95F9C520155FD60CCA64B05E9B2C94307A4265416FBD464697A150297770D0766CCF09FD83058914355D149B4C363CA922417E0ABAD4D045C9D44E55CBD23204B2F1B98DC49855AB6055836B1ACBFC14000C24F4C1479D554C2B2EA8C70A6F87081BE76BCFEE0EEACBCDC7057ED11BB34EC43C5F073EE0341D216C2F0E2A5ABC7CE03AE878F9C8505AB2E8A8A4B37EC3930F6E584CED25C4F4021CE5FDFA850B22F80B593C456D691C7E8C0335DC5C279F7F85A167DFCE85CA4B8D504B739A495578C06F8B10366DC55E734DA62DEFFCAC0FD03D45E696B58CD5FEC9D4B35C94D4168DC05AB84E5C24C622054544A31110CF3692A8F4403179A88FCCFC8DC63CBCBB486DE9963B172BDEFFB0750F8396756617126D75B3E4136DF937BDD2B8DCB99804F97DC6C48BD6895A7C98B8EF60441D70B112BDDB6998974F93868D4BF6EAE0A466AA2F52AD4CE63C11A27A2ED1AB712E879F0CCB8D29C2E959563E45D640133786F7D8CF687D28A540F4D76E52EA7CF415B570D7500DBF99A7CC80B22CE728B598C9327C392ACC31C3FB6F1A74D6C5BD4F82BDBD0551DA22D42914040CF7086B1C6B30292E932B6631B99110FC5EFAAF3EA59E6BE473A29DDF4E5F6A657E2E562DE99733A6BDFD180F0FD6A3E78CCEAA8AA3421C957503A781E75D3AB2F4C9C7FB27E19B033508F38DBC4835FE388D2103960946703880E827F89F1C4AE0ADC53D4A33C097D94724A7B732ED93C5DB1E5258B1CA94B9FEFD11511DFCB7BA984012BF84032EB29CB7A8DC46C89250B3F04E6428D585A8C403F458372CFEA7386955533AA3285B48A5FBC7C6FFD643D70D048AF0EDE756C51F49A37FF22A9F1F1420EE0C6A059E8C281C1A168534F5B7ABF12D80A108E159495FBED116CFE386176DB59397F21887FE342A609EDD7C2007098CE8C1E60B7249D3733BAB5D4CC8AB2794FB7CC3DEA8A0EFEF06310405C66AA9EC921F1694FE35A6A0E1D361E8B4C88A973F8073085E47CAFA2D661CA0867E1F3DB97CF62BD0B9FC7560AAB3095EF2DADB7C2E25A83F0ACB7635ABEB2139CF6021471B7658F65CC80B04039FB4291B8B5CDF42E7B9F156F3C2DC2F8E71B82832D16327DD5277031C91E3C56756D38528764328A9A6A4009033B436D24CAA14ED52B6898D466C3DF1FD23621842D7693DFA35D89B2DC441D1BD4D1AADCAD8DCECCC42394CF2977E383736177CA84A379C0E632BC3277E287F0B72C09A04264AAAD14599E0F6516C5FF6A4DA84FC9BA39CD172F3F5EEBFBC0EC8E7FC78AEC8416D01E3EC17A9A934549ED515DF1B520F18272C35567086888E9AB0B7CAD7DFF3F8171E2037444C5561636C6E6F7D9BA5AAB7BDC9E4E5F8F9031A2A363B49535F7377919CB1C0E1E3F4F7FCFD0412242947597A86B0B3CACCD80000000000000011283C49" + } + ] + }, + { + "tgId": 3, + "testType": "AFT", + "parameterSet": "ML-DSA-65", + "deterministic": true, + "tests": [ + { + "tcId": 21, + "deferred": false, + "sk": "3E935D3B7DB7EE991CE774FA5B93D9BE0D108BE397EE176568296EE7F28786007CAF1156280D770245611B2D346A65FFC735A3A2E15BB20C05143D9256691B2AB41D75A90BC5E8F3B30B6F5CD05FD18992924A5B59A65AF06C0F000E74A219DD3E7604B58331DB0A0AE901C29391794417DD110BC8AAF7F62CFEFB34E00E1D1273224608140352203374007875256171864715361476150443076135107682417565754553623586606381220842166273341313626571127738336004603326033470801750142613464376064342020345044224040084303114570820783867267616511300688505780160364878830103711055618008111745151375375768600743812137557362365733331614323120366135554251746566185186844142405008812716203287601083143716200564576635047520177022180063752520164642714415327778151052008642808573380026883457436064234122618236025563058541674201723048788640112813150654403774841424453305303221148753008688031332254082078242584840286177301607176788017121684433040173755555750683651813041566084354588662418642250064747473031812374021673282486827605038055324710254455817626100000230664826103172488176531134306846024723448311740230680042148850536837730552571345643370461544610780183773451078171180104582147807556873670047488518654385284874451381580620113757112803083074314684320237100037477766105712118241161456212245656034186154017004464176334326740402832764308766445851504060640576124400281353647323214821033857545523610774625068106122683180221678260362521201302863406712350682475271635857220571525343258836275054827741877621326432020580784710353875772868341878363051856158443044548840053168838728704486521268772477031031715632770125821827468281545148686412467356360106478786427517182848466386616460707311675654327102528646248552175050554380133130605483627138568443074022187057484232375461550120577463002814013083534021237475850308467047435262471236266305063408115274535542164420053544842843632328232763503405306865145032688402018882073027571768370605424427643718688264801531460682254320658441480417081480173221048303526715882527870543270488733275488344414828021760801815571212201813874340356543310486026422086826301213865460574551547165833464571331342333324361541770188154256776002570452822671053622286151572588871378618203862708670032872331727751130056133838855585607876011010676275632625203121158641326875854128131672382381020353185780015705112326025800226563074580444604700207600183643031776082661220866111632103107372146823046820244455412421580875043257154231387817356100882747432501152565307267161430120118507744308574866233700326827552338466067211465546257660701674221148284153310844242634735382144183225241003471575543715561843716168715856042071108301012801652345045255016735805665612203238088225555235253071116306808173433031610572882372184860154863135212681745772538311183131358541040558574735410488454426065881446470864680188026246287815664520033268207530852644720764714770741540141065754171222385408035558637684376620487744584745736533387425473434280735546766515087150306388383873763030720286231050777658256536078013373573731543008080540837532054265732725301403185681580340556182751534152216780045272761136256556858461150186753280004488820172321265430428278876741152805304254EF2D2B2351896FA881A5F6022A2BD420A3D39B3B3C4A138A6F299A621979031111515B402D9040361D5C6E2DB187204FADC47A8AF07382C437E85536EABD12B61F0E50679A42EB886FDD3ABF04BB7C16FE949AEB66B30B685A0CBECBA90EC1340CBB5FE2382A534BA58AFE4A8A293079D51D7EC7C9EC515697726C23AAB9815DAC184696FF52AE3C02FF716081FD07AB10B653C3D4B47C32BFB5392D0CD22D5B99264C5B58F65A5E52C8D799C17A0473A962A6842CFD255CEBC0F20E9ACD7EFBC8A7226EA998F014C3E71535A6D8ABBEA5E8487EF2A4516A4B8354B19C03B971230BFADAE6C80DD3D234564553E2493153FD09AAFB5F06DB57B388E000D149C8AE52CB42886141316AA57FBDCEB78F815E31630C8A557FC5F54CCE95E1CB5F25AE1B62D2A1F390444FCD77EB745785F5B36CBE1433E55521165BAC3B2B0046224EBAFB4C9E74E6343AD94AA37AE932BFC770803786687392B26CA7C47124E88B8B99713453FB22C210EB6EFABBF4F07D47C01543564F6D3C6233B913EC4553E8075C97A6DEE1CF8CFEA5C167DDA8258CA69FEEDD8D46C52F3A51055E890B2351CC3A1898CF6FDF51F85F01453E64B1E6CC83E28A6C22C8BED80FB7B4D27D475BA41B9DF56EFDF8FC4EDDCB453F65D836F3BC96E43F0AC0B5645B4F8D306D7272D54F86C90FBBE4CA897DF1F56748AE6D0B0DB3277A7385EE7561B570D270C9ACE06D2A0044BE7C8BD01F3CE08EC36561911F0155922432E9045486A602AA4F06A02C300F8A71504A134EAFFFC051F1D4D42D881E30FDD5DFAAFBF9E9BF745AE0F70FC26FD404FA797D9EAA76D9065C649785F5FBC134690C7D8BD6392D4EE99C488B9EE15DEF9227868A199EF358BF08EF8DDC5E45365217A4ADE0D36AF7B0D3D744C3EA3BB26B56B9CEB374710F758BC7AA68BB346EC2DB5B5E7FFDD5F0B4CE9F25F03E72A9E2F5DB15E3B4E922CE09A57E2580CBC287903703E165BD7F42D4274AAB820EB71E8420CD47F87624727E79AC507B093D22C9E6E761DF4A3082AECE1095D3A5F101EC019F2B84ACD4BDD1F5379CAC8D7B8808485C6ED1ACD5B1A245595108B4836004D6A6D61294C1C8EBAD65A0E742B98CCC7D1D2760536B6EBD19A88D17C3598E86E5A22C0EA07BE671DE3AEF096AAE6D3B71AADB38839ACFA559818EB43A3418576F3B42DCD0E128AA022234218E616169F0BA3847F0EF62FFF4EF7D4DE803682D40A5C3B7D8F4D5FA1444470F1B66DE187B50FE42698128AA93350C20E7D37F619537C220D78C5EBEF89CA0F11C7C7A93D83F28D83A17216ADC450E25F3EB00D9F365C9F5ED69DD08B68E0BC9780F34D150329E4906D30A04E47B6B6D508DF9A945ED83E39DBFF9B0C136486D01A91D11D37B5ADB8A23D305B70609F126588C8F77B6D0614DB5364CF36EBBE9AC59D4AFA18DF530AC5ED8B58D68D0CB7BF91D65B0F392AD4B408992549F8A8FBECAF25652F0F6C4AB6F32D5B147E8D85286EBF96A5D57B17A9899E854EB4544BFCE30362F7BBA0D2FE40102EDE08EE9F43D0709CFC89B8E33FD5F3815A771C56DB8D7C788C49EEFF53AABC5E341F184F92ADAA225122D2D95E3BF03A27DA0C104C6F44A3E6EAC0CBC2F2066D17AA74A584644EAE6E2B69C32EA116C91D8D6D59C9744FC22D38EE5CFD0910DD305788BCA661463AF04090B57215E702850E85AA1C66075B15B9C9D6E9325A634CB04A6C7271CEFD9DEFDA2D4292EF1535998E5A6E65C4E51DB49E27FE2986AF02F4BEAFBE174BD75E8998651E610958188820845AAEB239D2D152B2C2597D04D7614A4439F6048D2B361FD9C558F40CE0D2D86D7F76846EB81DFB4E833127C87095DC2AAD0D7CA4FFD189C5E24A0F9CDAD4A5598F3273514703ADB5D12E7966E51A856A688CB6E25CF8C724BD9EDDCF555B90C65E28E07022BDB2D7569CC46DF613EA1E7FC1D88B02594A464387DAEBD0462A5F9C8BB46D525F9BF8B3AF7FC0D0B84DF55B2AF9E3E82A1305726B1C6D60396FD086B01BE69F91C752C5D0A587540C919FA8EAE2F5D3D72A14AE9D5E0B4DD4C8EE8084342033C93A86052ADE3A2A68E4C7B5DD599C568C9935BE59AB38ABE3556FE81306358D5F13C1C50C8E5D32F230242CF52E30C43D88C50FA030CA5FDFA88DA869F31B29A95299ECE1E4CE8575B6A633120EA76B43F30E9517728708DE1E73A27699D451C143DBF335684A643F544756B94C546593972C3543EC65EF687CA3F07302E675FE0065C1526D1353D027778E2BD04EEA31D4009701AE7B2241E32E1F9427BF820CF55A465248993114A7145615384CFB4A237C0C37F5C2C1B3AF7A62867F0DA8E4614DE7BFF6F00034AE628E64DB9FD96528A788D98FBE61211D1F22E37B978873EE78A6E871C52653D1EE0E0174699FF71B0788E7561931AA70939FE1D585D733509303507801B87189CA17BA3060A4BE85F9ABE6CCE142F8E16451EB3C51A4333827641A9361BF679E665F0E0E11F657AB9277D5E3A9EBB8DA33BCA8D37259166DC8C68A7A692B570883276450A56D984B774A10AF0BA766971DB3755AB5EDE5BB8CD6292555208B37872EFA2E7E42746576F725CA9E9FF5A6903945CB08E715D4BF468AB847210E30CD8B289D2FB745726D76A5802A4C74DF544E835D61DFEF680846EBC5F715F071FA0CF2BC3AD0B0F016C9A67162B4F926C32EA6DC7C548E859B72AB73C7A29C4F06D609C3284C784E40CD460EC149BDC17E614603F26BEB2E8AE8A0CE21E00EA3D18CE1865BE6EB0B9E9C79C170049492418CE009BAFBACD4B8AE55537D8CD8839EB42FA6921282B32EFD2A76B1A965DE1BE3CB0001069D4D80D6715F8E173BC8BB972F23020E0BA2DDF3A2D390F11F1F5BE9F6134F4276CF63C5DD6A154E133D9E1126FE55C5113F5E3485AD051B4C613E32AD3BC0793B0D955FEE79B1392AE2EDF048753BAF82EB4B739746C075CF84729A90EF60685C3F7833BB0D00895924E5A8BCBCB7BAF41C78C3705C48C28559968C947BC6FBA0E9640F8845A45C5AAA018842FCA46A25D68DCCBDE8BADEBA341F8969A3C83337EF3A6383CFA4CF9B093F7C81CD8947059CC6DB350BE20E8080A32C356BB813A714557AE66E6DF110AFFB7B11D95A82F4714D09C945554DCEE53B3A06F0860BE89E7B19459CD061154B9F86ED770AC271D7272A8D0F40BAC2BE0F95064DF20246FF3AAF3100DAA75F68CAA6C532E1181D670D94A68639A4557D5FA10AB8A016EBB94B3B367058AF40541FEF88F497EDA040B6D927A3C1F034D6C2472F8A90EACAFB61242E96FFA47D1598D6107C1B4B6703E83067A817EFA9640A6A1277E59FDAD28DEB29A70E31EC82BFDDF96DFBF7756FB6D8368F9E340065997B55B00B22057E7014CA555FBE5563EEEDD4B039835F60F753E9810B5410ADF699515080104AEC812C3EC299928C66C498B0E26B1719C690BF5A42415A6F63A9278DFA430380A821BAD0A2F8377235A260A0BC9B33E49FB980EFD770BA97FFE16183D6B1C24D0D1C3F437A1", + "message": "E3D54DBA675DE7530D3854C8CDBD581C6E392F69CF9793D8C0BBAFEE7334C5878BF13B3BDCF1D993A47A7E8EDD4B6C3EC915A5E8FBF2071F112AAC41F08CCD8CC731143AFC223213212A5BD6B6A4026CFC9F7A41C08CB99F2B375D0E04FBBE00503533DFB869DE43566574B49232566E38B13CAF8C1EC1FA11CCA3DB66887996DFEE090D133B1D394F075F8286CA6CCE13C3977D929DEF5943461BD5A22D4BB5E8FB7EFE016932D02ECF4D7B7705412CA14508B13E61925EEC0B77460C4C089C83D687C8F70D141C75D6DF24FCDB64BB8C2721AAC9CE8C6FC4750C1686A7A70DF34957DCC0CE53C3F0D280CBD056D4F921FDEDB35AFCE5DBB348964AD105EEF5A1B07BD0D586B87ADA7CA7AFA93FB75AC0DE1C749C48BD6F192D6279482D3F9781290B88B095D73E728AFC186BFF0816C1DE78119D701FAD382C65ACC42B04D69412AEB255793839EFB9E5BBF6F69B7FDA27A44C04D3AA2FDC6101E9CEC6F75745F20E077EE23D652B7DE547A0FB0E3A153473BC824AC8A31A2C9493DE64B6D40185B60431B1B34EE32797CC77C45C71F4E04E849BF8DDFCF640B83130208DC2495C0CFC6C031B63B80FB45F47BFE3D25EC5B36C2700300D8223074C156C5D9887DE8C5A97BA36A84D7585CC065F20FE8DCE9E8EB814A1D5B7A3B7A3AB68D93EDBBBBF67BD70A0FC536C81C8D6E8B139C6B3B5EEAA3953464549CB38B78A15CE3D5BB4B798E6B142BC48C70C5BE61F82DB6E2EC03616999073574E6FB35D441B78DCAFF56B8CA8F473EC0543C9C69E93B97F95FCA58DAAED511F4440DB252EC18C90D2F97AD901716AD34EE103EAB0B7982994E21ED1AC4BD62ACE6DFE12C8C2CD092E7A7E37BD4E61B4CD51D980171F8D4253A4E7FCCABA0A513038276325372527621B0A3DFAECCD7CDFE98CB79C0662F5D0234AEEE9302438B778238BCA409D5908768779155D659E92D12CEEF3C2C954C3F1A4C2912E9EE994209B608A604D0CD87F79665A25E774E6DC1D8819B85852D9ADEB174C75D982DCE29FFDD24B7AAF5946A74C14A301AE09F1386AB17ACC341D6DAC040FA6527FCB8E095CD4F1651E47CE02E6ED76C085B2FABE9FF5A510E63E73EE386AC17D5C2C94C2D528B3A9C8902D10C1610BA70BA616C58D037F148E6332107DB9F64C579064F19481669C7888C21F0A3374194FF1A72FB6180DC01D29443BC52C318AB03843357A5A98B3D5CDDE9BC49D3ED29EF73CAF44A7849AC6DF4B2D353B6A562386BD480512108CA0ECD63BB3D3A0695679762F8254116D8049488BE6389FAC08916E6407944B1526BF03551504E40E6A3266D4E773E892EAC4DD5128374BA341EB4097E20A9BBD4E5EA26BE6FC325D9B71C232DCE1974928516EA2519974C82AEA5247627F802C6442B67FBC10E359672EEB9DFF768E9333A2166336FF0004DE5E7BCA55998C860FC1A86B75CBEB3FB5A5A2519D5227A6B5A7E0EE058FEE0CAE2B4AA75099FF098089F0261C443B13911CF3250CAE2F2906CB6454A20D0FFFE8C5AFB1DE7C5BA8CAAE00CD7C2D7219FC83FB158FD6D15EDC2924AB41C9B881566C538F5E38978C3182FBDD0C0C532A77A61E5B8E666B3C540DE976098D2BC68C0CDACF57E9BF1BDE8A7BFB13256BC69F2E386D8F458D303BAB781E537517AD7D0F0378D2F258B013AEA01C97A7E8CD2C3DEB203AA8D59084ACC2B09AD3C97EA613A2FBF297038B4E721665D512DDFE5C13F11DF4BDC0200BF610D57EA7232914752F75A544E01D5AE0DEFBC9E18695824058BDFCDDF4D5884840D2B55D6C2D6EDF475CA75F3EB4D0EDFAE99349684BC9C533EAD591085BD1D6D4E4F9B00A54C97244322D505AB52B2D4E0438C6AC5D2C3983BFB2359FB21174AC02156AE11EF233AF40A695854C84E620754419CF7ED9EA4FDACEFC8879B2EBC7B29CDF9C4CA2921E084486477C1452BC3BAF529DD92748E2B1B684B1103CF4C6EE11999E4121CFC7E2F3F6C7BB9C055F800DC46D78D9D94C3B20BD1B697411FF0B41E38173D2C9FF1CCA77B27384026ED2EE25223B0007D2930D700A20EC9159A66A4BBE0BD84DA52F006D7FAC6D59AB2BDE08FBCEB76A57FFEF59C077F9008A4A231FCC302E4DDAE9F3DAA55707C1EDCDE8042176DC7DC6377BEC58B236990AA6C5876D5A27942FFF7FD74B7DA1D2EC470CF71103A64FD2917AF4C45D4C59C13F58472AF408F9C5F907C7C6AE0F402B404AA40CF8D962EDEF7B7654EC8E36C645855BBECC1337EC18F0EA65933F4D07CEE15294139F479A16133D2BF412B5E46D5B06FB170F0C93DFB8AC3F7478002CA76B67A272A3224C8172CDD8A616A4C52F5FDE946CF5733583C53835EBC90DE3ECE34299D7E5434BF072F08A44905818EE9708815CED10E9043E88B6EF12BE72FC1169FF2F925C38E03B827CDE77740C7C2848AA3B09F555E2712B341E248772EFCF01B99CD5403642448B5243F35A3073A6DA7685AD42FECB05D46FC99F7D6B8EC56F39A7E7B3579FCD587E07C05BB7E1F5D49B9015375E09A9A14F2CDF049AC392139EAA3C2547426B8CBC0C4BA76C55014FCD3940FEA2631A75CD2FF5C22B8A65C9AF2DB1B831C30EDC8EB79B797E76D045EF0B8EFF8D41404F626DE8551FFA445885CA1E3C9BF05B5C39CD40E3B37CE3B58514BC70E2EA94CD694CA88C1F47AACF9B4FF6622C555AAB7C71EA210FAA9C0BF9089DC9C9DFA77C2C4A92F59BD7CD24EF4F8D5088DDBE22DE854F8966C017FB414464ED6B991E289F7E3FEA783831CCFB51E227A6DD4F5EF50963E80847FA6B350A2DCDA3C875D176342ED73BB42B416E58D1612C4D066F1207B6E16A955DCD557A9EA37A9F24CCB20E74AC4D6166ACEBCD7D651450E5D4AEA86DC89528DFEBE07B39A160160FEBBEE5B11122B4177FD04B0A49803E498F1BFFBA898BE3B26320966165E136F7F517FEA35EDF01D36831F9AB478CFF8241E01AD7570C26EA62439013F61D48797B92964903802AAAF356C6AF7645F5F4338C7EAD5AB2898C600123888AF42A2FE06FF03D81320FC08E7589E19887EC86CC1B08204C29E86CCF187B1240B81F7D375F3762CBC10F3BADCAD7431E59A4DC136440AA72628E17D2BCFF916DBC8A66B8A83A3C6400EA0CC57A82DB41BB28CEA9E9CECA1ED826719B9B62B6CED5B52FA518FE47274DC6E22E5F8398D42AB23572CD6623EC307FB7EF61892AE3196C48125605F4F09B9C0F0DBBFB9D9015D325C546CF3B1DC886AB0DEFE2C35CD39E2AFD13AEA74F787B410883EB72DB8CA7D225E6FE8143695BC0FE556C6CDDA493F92ED62A38E8F90CC4C713A4798984007A5CBF68F0CDCC01274C96A15C3C4355ADFC75F7DB0603918ED6CB4E4491A8569FB1A9AF32528F6E26B2303C7987E39015573521E024B2230BF1BB803BF2B358880F2840CC58ACE31E551C8E2A0F8349570741F8E93066C8F17608DE35AEC342415A4BFDD13A9757501F5246ECA49913D0F02EFF35F4B3D40DF97A64B0FD02709C0832C423543A850776ED9C0574C26CDAB8DB371F5F4B731E6F510BC09FCE3DBB58BBAE1074CCAC284D5F8068D2435E053A037E3ABDC957B74339EF0063D367F7556E49D2C7A7DE3616F5E8B703B7585F526E9306C59329A18E76B85303C31E3616831F2AA2B173CD0A43CDE76AE52EFB8CF3C381097D7A7598EC833A75E97AE4DD539C31B3E45216EF9C844008C28D12B12D3C7EA7FB89B3B5D20EF5C7636A8E83D6A9F8F7DF29C9716B7D92313048A7E14B9EDF77FEBA874B9410DCAEC4816D2FB57050696F5D4F0DB47C6183D447C5AFBCB948D09944F4271368542E377DEECD006779F6F7649B946E79BBF2E19AB4E93F142BB24E6D962F6648CD0BF1BE876F6F431E883105C3E86B973E30735A6FE17346ECBEED5D101EF0AAFBBB4C072BADAA2F4D517C272F2BD2190F5F8C87D961041A121D6B319EBC959AB0603096017BF7CBB74DBC74FB866358EF8C1AA5B9A10B2C524E822278627C0AC577AE9383C2A529054528E58D56699540E4931BC65A125EF4B459A7A5FC10E0324ACB641BA33C83A7E100CB00FFE0ABF6281F8942AE5490DCCA37BF464D0B061028E46E025FBD5F6DD6CA1BEBEE282B749FF5B002210916B9CDC4D903A95972FCECB9292A554AEBD821AB4CC50D5EA0A33A699FBF07F2CA520FC44D4A9581182290294A8FCC66DE3FB5B7F5EC5B267D1A0E6F84C27C02253649F5903389A0901797A7EC8B78AF12BF2B1CC22D291347A0F8D6EB2698AFCA7CB4C23EDF250A5B77E51EFFA3C675F1FA951D72467EDAF987D5B63DE4177535974BB2006AA9A8DD9E624108229B1C5735BB039CCE47162EB52DE88703A8BDB8ED409BC01DABADFD31EBB95CAD9026705DBAE5A2D06376320BCFAC17A7DAC957BFEE98480C7A111B5ED300447A21FE62448F62CCFF7DA68689A73A2EC70BD13130337EABF26A00BF86E52077EA00DA46FE7323780CF98B3E998BB30C3998017F4BEA455568FCD567086EC68ABC40113DB474C6C88B1C1C7588E7A8C8D2082D4C70DCB8FC3D8FBAC53CAE95286F13254253861567E4715B03E682E422C111169D96359EE18265C3CADBAB3AE61F03F86D096ADAE9A6C4820EBE3B61015995707695B42B67802FAC2D6FBB2B67801A3E48843EB83288AB52C29C1F112F9233860612BA015D4B7CABC19C6294F8871E2ECF6AF334DF9C8330971277E32CF1488F04B4B285AEEAA83BB81D54B6B8426439804B027822373AB99868EC068735C816521BD75DC19F79D2E2166B1A551C998318FE19F5079BAADB12732528BC8B522438AAD252C57D3899400913CD124D2DBE90A891D95900C0256D9DDBF939BADCF6E37E6783DA2A2BAAD872F6C8C11878ED6D5EE2988135A39F2DAC7CF127100C36D2D4E58B3A9B1D7341120FFCA0EED2E98E020A46F1AECBC809A21EF79E6DBCE76F96B6930107F078A5D4464CFEAC414CA41A5EE4F87CCD8868E7922A14C247885F0DA9E23A7604EDE703C2BE3633AF9CCC32B9E5F51CF51978F10A06F5D77C67927D80AE480E7E5E005401ED95467972ED87029029DA05DFBCF2F0B9D50441E8F15804B0A59D23CFC2E3C0FBFCB10B69AADF0B37C06DBF972E264C6CDE4142C04FFD9FA0AF2451F8BEC3FDE9723306085ECEFB17C591E691F9B4D4F796E293C0CD322F02B96938A5F7D1C8A7FEB94C031DE24E71020FF37E00590AE7CA48CA876AFCA2BE3723EAAD40FD27B90FE6EA039C9F3F6069FDBC70F16626A41678A31E8AD88DE9BCE8A25D43B86EBF80E5E426FE21606E67545FF8E55FA7D9802D65AFBDA79EF40DE924FD0DA7B5C8F6A2CF993FA6D27B2861C629CC9BD2E1E6AF04F88065614F7E24CDD19C88CF2D7D2B93B7408D898525E5141FF71D18DABAC186DCD432F3895A1027C92CF8613C80BD46E4758CA26C8CD92B74EEBC5FA5EDF9C9FEC54FEAC40F0944E3FA165E515A03DB57C205D383C04B2CBFF703939EF321DF8A49BC3F5B1409EA491062B7B9982277825B52C6CC8313BA05ABFFCDFA525445B1CFF773D28536A989D257967B50D7BEC4FDE5F338D2AE81BC8EC592BE93BDA0A7DD089057E675674E8B997B05D049CA3DBD60B7F3FB23BA5F4E5A48ED8535234E5C66C41B157C25B5D9EF5C8C0ED016D6B217F4B60BFD0DA223A5D40C2A403DE8268AD5E6207C54B217C2F009C5DD052266722DC21D4AD8314DE498692E3C77C9F8226A14F27D49E0DA1101E32E5B86BC0F0348A20A360A919EC863695D2EC318A61F654C9A1526AF1538F928DB76F9B14EF598F2551EE85D6E0429192C5F18D339DD5A280DD5B1A8F59EC1F2947996C7E190C87502FDF5004772224BBD1C4DD62A8DA1723EDB41176A9AF04B1F30D09050E73579364360DB4F98034FEC1B43E6E9E0226409E6AF1609FEB862D845994BC20E67010237B74DF1AB59EDF14B1623FDC990B87B929FB7E837B1ED905286A886F59B023F40B07A989EF7A99E974EBAEC49B45FEE1F405D11A641B2B150EBE854F7853F06026CB1287FD8BCEFB15D2AEA623D7C3ADAA00B35A105ABF2D8F9715BE65AFCC1381D29C5EF398F2B76FE1651348BAAC147CFAFF34778242B32A1620E0332EEC7AF5E750DFEC30A899452ADC530DD933A07748DD522AC20AE2B2889FAC3237D23C4472FC8C6B236D4A4D19F67264F54BB9B25318156B30EDF273BBF3598AF5B34BAD41585982F6039F6E488308B47EAEA5D21A91E5838F7D9CCC8F726EB2DB82D022BAF103AB2DD444489B94E8DDBA71E62AB6251DD5D5F69E44F377674A5C2B032150C32664C96C072867BB7A2DC29033E6BCCAEDDEA430E5E155DD0724FCBC0415B2AB6DFE68A2E59403B206BBE7F421FAAC53F66040C5CCCEB19F17BF000AEA7E775211E48AE04AB32B2EA470FF97707D9C073FE72A7B77D49FF8DEA36610C2A83306435861BE01DC4B20DBB8AA6CB780328DCFC2A32D74CABA83929CBC85E406E74EEDB727A2FB5BD9D304AF46225832858B295A17B9E710BD7B0B5D19DBBF4FD021EAF29F4D1B6BD7E78C8A3E3235B5D0BC687BD5B428D2318CF4330EC343566D42D17BE838EEEDF70F1E409C189DB1AE0A205D222C92A1ADD33B8E3B126AF62818A2DBE3E3C001098A986865C6B57D0B2F5579B97B6F101EB56FA839F8789F6774074185A8E0F383E9D8813CA1670D8B7586A3A1C27A3F5A3874C4E743EAE21BC519DCC430E281D2F73C23BAB948938A46FC24DA94647150DB72783AB3FAC01D834A8544F144779A51480643CB1ACCA0BF88D203F865664A5ECE18A88CE31B0D8FEEC585F9531329002D4FFABED01EF42AF52DDF08400C58D07E98046D77C7A142B513DA0EE795DD57EA43F4CE36C8F6D2862044945DC293C8D47D9F207B0344220E3177D6E17A4B39B22CCAE3C53D4E0DC87F70CBE9BF743CEACB8932DF8F84A527C9FB84C6CF5206EC2E43D1FF8E846DA06EBFFFB87BEC09C63E9633713768060ECA6259AAFE7C787F3947D5B94A6B80FF0A7A4785836F9A1396833347C13034040D1C6B1F83782AA6458328160FA04971DE04A16B6C031B2571DD131912CDF2515DD56983ED6EF3BBE5B3989E951BF0B99C5605C38181E96690487E87240059DE21BD220059E5D7E3C832FD4569BB7DF06437197CAC141E8FE5B369B542CBEED2F9025A030C54F0B5D2B1E79011CF2A0A0DB14312E352D07BC03E654AABAA95AFD30F1483B57BB1A74A0CDF8C9FDEBE4B0E156FE86BB1E21D861F8EBE0C4AB2B23E776EC01A281F6DA9BEC4C560668B4EEC71856E6CC41741DF2EBBD4E95B661EC24FE31B1DAABC9373CCBC82F3C13C31E478097259850221928C7AC6BB933A5631C896ACA87FB6F5E3EEF36EF5B9CE59F5676813A1A7E768FC9B8AD4A0A072672BA23CC21B21A95C9BBB1A40FDFEBD2D611B773DFA55F87E9AB1CE51CC42B0FE2FE15DA2D73F656CA56279AA16722ABAED5727519EA258794503F1808E4EBF056530B318B99A74886D05D042DF4D829C425C908B58162EE30A073D4BB7D27275B548E7A90E6D178DD27F67CD955270825FB96300C4645E4CD9C175C1185707D4D365955FCFD245A55D64EFB66308A47FC85592BFB755EB4AA8B78B541274E2C225DAD649C248E7F2792A56BFBEF704551588460B192DAFB9BF6798B7D4CECFA424AEAD675DCA081E60BBED670F9AB2316F5012E2290770D3323403DA5748BE6681565A713873A5386A6F1299F0E1EDB341FFF08325510A7F2FE5EB0302727D7355EE48ED5DF4316FD34833238690B91D47165CD4CC0454DA33B87569D38880AD92A92ABA0F24D99ED4CC977A2B4E37954FBE9B9320101C80A858122793062C7AC26E71BE2608DBD2A97CF4E884FD3255D008700FF3531C045750B2EAF7730BC9A51C675D94179DCFCE9EE63C1473D15B4319AA9EDFD19739CC05C5C3C8AA618FA9096C6648756F8AA74FD18A8CD81A2D248B856902B4D30182BFC2F392450F902973043EA0F5E6C872AD43A2D319F99F095808D83A8B02BD380D6C3F3DD227EAE2B4A4867713853D63CFF405621B1EEEEF00D5BA2FF254CDF97B4226334A9866A2B5BDF1F8E8AFDF1238DA9F48FC388A339F79D648CAA0A0A69D6F16E297663E5F4CF1AA95427E68D71E74C0A2FB6B689224BD9978F7A3A4505334774176FD87097D8AB454CABEE138F2CDFC6EF0F3DB14B09DD02E7FABE9F156654433B75B951AE3C196D670192004DC1924D1950AC597682EAD1C087ACB1461247DFAB3CD42279F9169B69B33435DB9D8994AC04B15D45007F0F98334AC5D783219B376D9ED7553F52CBADF159F69282050A4C843467AE7E4C4A142A61CCC4C48DC3AAC6B8E0A8D618E06C60DC924A943AF9000F896446CB62EF4E47AD6D1FBE2B8984A48ACD7C0519D6E87A33106E9A91C298808BF04E1267349334E6C2AC015A9F704B2DDB56D27A8B00D876AD00F62434095A6F7A5E9CD4B27FE09FF69019AE5F27330792CF9A1C07FBE98D23C4E615332A77DB5B6182D277DDFD7572DA75748DFB3B9315294EABE4B6D0FC3114B2AFF5537A6B05A7AA9ABB4930E17B7FD3D8F81AA2D674DB69AD967C8306FC3E1CA8BF78F446B26D8F2FD1AF6F7FD7E52867BCCC3B4DBD7227EA992DD995D77C4A2BC808C7A3E68FA433675F489BC503DB70115A824669E4B1861CDBD557A1F78F1A4B3582B2553AC23F12A4326EF943C56F847B8C679695614BBB1DDEA9CFB7D799CE42DF8B735FEB9DC119DBCA306DA4FA84A50F79905E5C2AC1F61241D88359EE6F62DC9D3E4A1593F41CC5F3C02241CE5EB62C28A547FCAADF1DD688F3DFBA870D9BED723B02B0B1CDB4C08D093C48977E0621930A668A5CD517A0EFFBE248B4AACF3009BAC0D47F49378F30A3D2C2800CD16B3C9464563DA4A7321082FAE95DE5645FCCBC5569E942B5F860A32F04082723E9E53F2D18099BEC5E23A916354198325FA8DAEAA3F6B7AB6AAD6EF12A03CBDC27B83C818F44", + "signature": "80A3AA584B532C5098947755BF88B40612446DC7D4CCA500DF34D9A91804FED988A4EC0F7124A5C42B7298D1784A5F6D364F7445E5F9090C0CA2C84902722A800B930AC58C45A46066A0D613DA411DF5511A5401183E2EB6B6C63486D3E2976D77D3319CAD88F01EC4429BB8C69036CF1BD891DAA369DCB525D33E9803485F666532CA7CA8321F983525E52AD2A3E363E30C7D7AC7ACC1F9A7EAEB76B7290B2DEE7C681C125AC33E9EB2B8EE080EFF7E8D3751E3C35FDB2CF58C2C9BF83DA0756A75BD92FDADF3E9F3E1637503C923802D7843787A6D947BAEB26FE64D0FCB52C2C29DDDCFAF2BFB4968E5938155F652145D00B410CAD920BCF74059908DFC0916637EE248E63C3EA0CDFBFE1B28388357206C6DBB8C0D9A23942938EB523A51774245567BE82401E8877048243D343E0D1F3F4503F8A4BE59BAAD3E76B7E2D1C2CB4234B62BAAA10642B903F5A644DF2B37E740DE63C82617C405B563BEE0008F70A33A59BCF17A38B0170F736D3D617469D39CC99E3FE9A49B94DD5E1ACD03877081658F4D0300CBD5E50B0AB094E4502BEEBBE4840CD5DE6FCB891203117980FFB033474E88AA07ED44A306115FB08440212D943C6E8896370D8FF97DD4E29ED631F05CD72B343698B8078DBA5523E471F20F4EE58ECDC30E3D4E0F0E130378B42E5521AE16088C18874703CB8A38D382FC89957F592C051749FAE68C14EA0B6E11677D65D7AFEA3516AB9B75D5F464B8E119E97ADC22CFC48729DFD3881AC6422A11E0FD883F44FDA7A7370F85FB80EED1A4D35AFD4597C173186BE56C94F275E4F2AAEA096AE8FFB8E5499DFF2A00AFAD19B40A0EE428EDBB3B64F34C4ED401BA5772D647DD20E4BCB393D053DFC6CBABE37D7544727DCD40A42E83AECC1BD8718D7B2F0A8B5E3E98A568F055A6EFD74E8D81851D745634AD5F7FFF96A5C832859F92A92E70249F38052CBAC2BE7DDD217786D5FEB80152DB1210421D53569B07346AFF582129AF9E35DE9C3A4CF2FBA7B6EFC9552503EA94A722F6F9A84E190C422883C71D60F4059F912CC773AEA6C52B2C5CDB496B056697F38F4EA2BEE6D5150E92650631DC3C35B7DDC063643F65726964575D34E0FBDBC3B144A829674BC26A21C3D7D873F70BFD2BE1F71D5BA2593C221DBD6A245045256738EE39251B1F433F4C8E0C1AEAC740952A677F72D11A0437A64188A5A8CE69A4BD56D98021B3DB19481D606BAA7263EC0ED9529B242A366B76C5EAC589BE4A3EE50B0A49852641F9102E2F63D75FE2C295D2CFF1554C77C742979F1DB719FD14D1FDD0303F5FBD3C96763CE56563D05EFF726FC1BDCC4C71257A8920A8D5777DEF74D2E175A7A2541AFCDB51249EE6010F19C9D428C774ECC455D23F7EB770B8F2AA09EB278A55AF0BE2EEF172FA12365E0D539C60FD5A5EDA381620C1775EB2F47146F1E2C5B854023C8711DDA05FF78E393D1273641CE6DA638006650439C5F32A45BE179B4CA0C4DA02D908BFAC72E47CE4A2E277991EFBDCF86BF28456A6FE93E671884EE309DDF746194369B49F76476830B242DCABB07203AC83CFF067ED83B74D201DFC633F63BB2039C82785C3A80AA6E79D303F02D134B141156C5ADC941F477E955C83B2EC1938DD6E491C1D5EB0E262F62589DB9F9BBB14856AB4AD10D450923ABE90E53D64667D87046B81CA2674A266A4F43C35A5DD0C8CA7BF90D9B8E7700970FED98BFC65D22F1D1AE7DA37709E291EDEBCE413A636FFD8FBC55D921E2C043401D68E837049C4469CB7542A3A4E3CAD8272301CF07EA827C7FC18766D43D5DE67C32CD0710963188A744B70D3EAB6950687EE42A9FBAD7FB7F1ABF8A623E0846CB9D3BF8FFE2C5B1D650E3086C809B08A01E0AB08AAD8808320B2E43F4EC80D71C1B1A9935C6755349AA3E723324FF334BB9BD2D6DEED275A1F779227BE29CF8D6302DE79776B2B59BC42837EBF82CFE344AEB2CCDBBCE412258ED39C321BF78E4D7F1350AD7070892C47A656A9579015FBC1EE340502E6592D0078293C79BF17F189F8D46AABE90C54FCBF3651A43B99A004D1FA260D7758413015EC3406B8D7E5C8A3C0D110F79A883CC13C2FE40047095A1E5D0DBF136A2D33FC04D1D5F7ABAC0D43FC083F87CEF760B4A278D90E1D5FE74E999A1A58BCE582B22807502A3135700688F8628FD12AE152A506038462F6A8B45E5CCB4440577374CB6032B75E9B92B8A4FBD2D080E2DBE7EF640370AAEDC4C75829201E17797A25EA8ECF81057F3F3BF50227ACA6B4039378BA480A07085598F249C890831A4A44A5D24AA33009A0DBBBFA5CE269F345876C7FF4B55D5ACA860DA86FFDE4EE9966C44A18A5C3A1FDAEEBE3BD0B3B9C2D92041BEE72990348993491C73BB4A813295422B4129595B359B3194010DF21F4D3FAD2CFEF725BD089AD68A2001B29D6DE815B9519850C99C5F0C8FF573B2553A4330DAF4CA5D4E98804EFD6B0D4642FE94D5835CEE0987209218E37921DEE6828F29C730AD5338B2C8550FED699D266E99651ABACA63DEACA113EF34378654EEE36D53846E5BC40C189073E85DF689612AC27215C7FF655F23273FA860CFDB866B7A40AC33A28A261BFF4434C3490292DBFE7DD54F54950ED3BAE86FB6C7B05AC2DB2D26946D0285BC571F4BADBC7944B9DC667133CD308B034B24BB5177306B73DBD7D506225ADBC8B12427E691F63D4DE76EA4C54434A57FE92FDAF6249D355D5E6F303BE70BC850520314755BC500E9C1AF6186FAC1522CF527158C491371D7596C3743A94E8ACA236600D6682EC7ACB87BEF47078722D8B7AC7EA48EEE37007E766214C0C27E97DA933913D33A02C522B26800C113336312D86E0FF38A67B09B344205062FBBF576532D22F027B79FE5CFCC50C3CE52CB6632190AF1406AC18C21183D61569E14981312744C15207124F410E8B769AE628CAFACF5CFA53421AC5E0F426D62A9BBCB8E275573941F876522085775C8B03CDCD3D67CBB50F4EFEDEC473DF28D2D881AE8CE3C1BF09F2CE9188035948C4A3693A05AFD3374EE58EAEDEFD90CD8C4FF0AE325AD8E78C38EA6EBF95D61CF46203DB6455176647D1A12CB7D7423E3871F42A8B13B1BB9C2C2D10FEC92C3F9E0B792C837C07C10AB815A359679DD22584E4EF1BE4C1DCB918A9B130C9A5E6023E6763FB8938D511DE761B7A4236015422D30C64BE39079EB5C66FD3E0BA97FE1FBB0F9F61CE878052C90435307112A2F83790DDD3C2A420ACB56C8E0D76753E3FEE5D73DFE901935A2313DCAC424200606E704F305E124A28FBC0E30E38AAF3F2ED11E27532C15664376741F70F59830D1ADBB56042F8C87DC2C989FBA6CD94AB7543D0EA696F74D1421F489F070C9A2C793CF48DB7BA4FC951CB47272E450017E3849BFF1308D3CF74D9515C04E889E424CF87D0B368DE99D9C31AA1A217DE12292040ABDF61AD972729B6B1892F72AA71A1803905B75CC61C87775BC4C721D94AD74E9916BE5758BAD7CB947CC9E250B42C9525829F070B0B0DF812B89A88ECB874E0C81F7B1FA95FDACF77C916CF8E72ECF00C319BF4093EB114465B321FD086B79832AB16F83E7253B031531288F70D94BD5C9531DB6AFD125A736B66EA40EDF68D020B49D2763B016B328D8959B08370C37CBCAAC5B12297C1F3320DD9885718B4B00DD6B10E2652A69360FC719B55723DBFA38749CFAFB440265DB48F5DA31A056A59428D3284F600E9CD497B1378451569BA3F8F1D32091642E65BB229A0E676E3A80B1E18C3A36C4D17F9901909DB8E5E2203E7DF5E02F152B1D302C31C91D8ECC3E13FBF864FADBA37AA645338597001F55C638E668A6E36794E83247DA88C84441EE126E43DEE6F3F1F201738E25E859118050647BEF46D042E14DBE46E2B189CA03245A7848FE104B08468220278E230FA454EF065BCB26CFB93B19B3B35A2C1D69E301300F50DFA168C54BCBF8673B63A7DC6AD7F56D33CACA83C1C77678777BC6239632917ADB4000D229E0ACBE4A8A243E6C57ADD4C728527A7051DFA5FC4B995A3FE3F3A6E5BB9A9D6FBEEE21CB1DFAD333F6C958C675126667F0C1CED9739F2499E79AEAEDA15DBA5C8C31986564E962FCF789608949F7FF91AD70B3431CB86D7F1A3E129BCEEA58BF56C5815C9E44B60DBF7D104B8C5D85CF05BFFD603A2F20843987A1A5B34B1182A014C5AA7F5EEF615F677AE07FD093E77CA4DE721B67760306C7565D5C764D2673E02B266921647BB5D16AC34644183BA29F3DEB5D494D063A41E7615F8DE9D8F300FFBC156B69D375D8C3881F873A98EA7F8759D5B287927D5F3EEE9A242831B7342CD495FAC2E76F25426D24BEE831557B622A3F7DA57759CB2DC91D107053CF2C3D81BF1F85D75FA9B8E6ABEBF976F9ADD4BB7F788F8592300F36AFBF1800DEC01FD44BE822CD2071E328C1F0E23F460EDF2ED9A6E6B68CBBC011A86439D8D110F56C57EF270D25C5B588BAF25684BF68CC02827A927F9902283D3F76DBF53E864C7B9E44A193D119B563385A603C3E89A3ADCC9B7B9257EA51F697E14F708419E3CAF455385585E461FBDC32C921D47BB7DC8991D01062E833A41535A6978A3E016585FA9C6E248676A7BB5BAD5070D149BC3C9DD1A5C5DB200000000000000000000000000000000000000040C12192024" + }, + { + "tcId": 22, + "deferred": false, + "sk": "F392F98C9CDF8480C41F34A3BA6EECDAB55B7A7413B28B05B6D8DA29B455DA20C13C7ADADE697C19BD95F4181D9BB87ABC896C07446CC52B62F7C2883B3CCC61927D373DA98BB6B1463FCBDBC7C3A676D25788AB26706412FD08C05B130F826130DC142EBFDD884EB8FADE304455EE978A72A3A123A69246EA506F92140A8AAC301826517220457575500718444602606702737036246348057773753653026737530327720617356636110021487182406485883783500307652062837008037623504275143575413277805241337630721014485311207126464251365722038703047777860484650222507051720537247120624820142650776607686280727735633154433151782223422704163680716278603431812174820280568464342510822713206812416037802546378526410045560675630237304285416623454261283085572045668858060866837604282874804876254654326261578215675122020866578445072761231803362336526243078878567202715767743383861568417748622625301333140772280730350454860126812584207355072774075606603733422242068425724752175886643765751536756230433665412301147080035348337144751803325188375752442131056834846104747661738815140077787317821773203565820682216027654224806146185675613323671341833128465031767087642306567758113743515665083376682071584772645080206870431383757154651308356136765831320760126350481621267663254431456810768528220808107371083873767157585238851353083212225832367378252330145547815686824158782844746478735016774465466740401333310057727005121237645614476264226362084266800020031025007113888434744843115873163067161007831303825424463365517676765688324200684513347206713426521057202461184363017881817403710703264672680236531845142531570466384473731728758138705644753855655816742241364617142126084780008354140654801776325821685208137803465245450505341523100083408734674154335414845701708522128274506836754076625206872353746311412316312855531504102358752662137808638173521823133750654348485071110586741851463345337506614254157164306768776078885708514685148238201860867238133581485532340048788405422353860218008258548436878687253828241261050821015817420278763365687765514675058675166754736381757223055720684127776321362551252532374142887160764038838183424628018841887374712515033240300045651318782786054437184283851251186686603270668845482075874631015013706514675820635143655714764714156053721845140813850420508700657763114833577580426428065023467825688868337142277613856181714827028778062057570322170260362422631028183028112073851046204428683517685558417500601725657238741370857627730181360274563088823835144601056210101460602232722700431633184040618846384113624585660727717184113675546163610607728213513133205278237138625783833077538572741625110451321533127067244638480483667304517823113154663264021760688615102244052321747321612302751435786674345144462326132726376720328244761422741627313648020611868614763040681674853246228406044610051800751763205151834303188718047635724013221728118711424128888062074420703056187033803211250204407771300451054423223354033358307300448270140765437102400745208838204164114740002455888478168313785353187171180330311056851418840303151441514865342313468076524833442066721446046807704220124510652483242431018436830414063580815564337474054060760627544438122721145213236126348660A82C6DE4E1250965D63B99CEFF0EE2BF66C76EA5BD2275E36469F4F48A5C59613823B26EE15F377DD9AAED3625E4C402D971B2B83296DE5A8D861CB951ECE6BB06F787AA4275345917288245199B56E7F3093180FEB6D09F62FEF524E49F685082481B42648D09F71E623477F4D9E98E79386C060311CE9C063717B3F69C36391B555ECF819637BF03B370EB3B47B8F56EFDDAC66893EEA7DBA70BD28F35D1223829F0FE82FCBE7B0D47EDE3C72D9454CD323271ACD902A883811175068522C068B9C4CF6A819E6A141737177FA90149BCDE0E38221CE7508D32BDF4CD9605EDD630C5AB530DD0F36AF49EA3FC26BC6C0743EEB48581460BBC7836BF163E819671E821CEE4DA76177343369B9E48C73AEB48AD198E958303449D6FA0707BA74BCB777F8E9EEF95B782BF00AFF9114DC954AA6A943EBBABB85A486902222AA990E5CB09323BE672F4E96A1F0F97302300EF6B953425DFB55E8B12740E91C0684D38530B65B9D9D4A48795DD27F166860115831266455A4D29A2A928A11D17F42F56D5344C9F50BCD5066EC1B469984FE4F8B538825A016A029BC3FD608488C78805C3EC39954CB1B9EE1182D416E7658E038ED6D76099E8D9BC68E0149520AF9CBC6BE7B03F85A39726298195C58DD5DD70987ED894DA457339C0C9AEE5B1062C0F24A99DCC9D4FA5E426335449DEB5FF6FA03652EE49AB4091B79E83AD0B0F62D0392AECB0AC4C5FB3DB71E057588D4F777F4D21E3E5AA059543780A80294751338CBBC7566298EA8F067A919869BB321A09736E9DBF1EF1B825CFAE09CE2A0B0660D04B2BD78A69B48073CDDA437BD3F21B00CEE21D1B87BF3D731083CAEDA4D0835C5828B036E6471E5739DC2A7F874F8E5E2D0F66D5B01183A1AAD731B11414B304AADE217028C2D68644551BB1762D5400800709F13DB2B28A5203F0634ECFF934DF3FF920896D26FDF4D4EF9808F835DACD59BB5C44ECE1BD80034437786334910F23F208309943A3189EC42115A05CC2EC8C779F6FD9621AFD581423C2A6AD702A5A9AB15D632D9071D2E104A551218F65A44AA075B02DF27077A91C91FC1A19DDBBF4F793513AE1CFA323E72B6A01FD84FE50A27D2C3F02AED8AEBFF2D1FDCB1A16108D5655BB77C8B1D982CDCF19F82ACEC7EFD6921ECD285CBB2E45C0DE0D585A8C932943BC21160F34D7BFB6CA14CB0DBBBC9F2775ACD252E5B1279CAB1A4119B816F79BF0E46BC648D2E0FA569AB23B10C2D58DDE59C0494A9166EB882D66F6CBDB186A611F4C668F6C964453D5AA9567C48DEDEBAA84D295E46B1CB7C60462C1A9606521664F49E4DAEFAEE15BCCA53CF8FB9A16A38449F000D597072607466C4D7A2144DC520451DAAFB2CEFE1BEBE13B873409B1ED34E995E34BE5C345D408A421CBE8789D267504C923F8AD9EFABD6729FD28C0AAF9D34219C9E9E03D604335CC3224655CCB4E4DA0B60044C10E25584D6F1C434BBCDDDC2F98B2FD6D18640140972FB1D00C1F29929DFEF2822E000D6334E80CE73F453E05A13A80AECA16754A85AF59869635CC9C8805543557DD7D5081ED8C5DC0D71FB935CF8D2896915B406055B349811677F5370F1DD9B179E88DA3D6D43CC3D83220F3C79DE3817A070879A0BBBD5B0500E87EC15A2974C38997A4EAAC9967EE2DE66FDEF9CA9D340AFC5D12AA0A3287D8C9DEE1DFE957346EA23E40DB7625E8584F2F2FB610DBCCF1244646E31ED89EC62CE8FD792EA52DF83879925205F13D79CFD590C291659047811D3F97F9D1164F6087CF5A53EE97C1D7237885ACAFF30A657127F6480CF0980DA55B5FBD5E70F7F4C621F02025B1CDDAF1DCAE5BB6A60E046AEDBFD07F9B45C833039DF8F8E5FBAF5F8F1C1D7C9A3312298B557D49423C814F58D8759B53BDCCF4C34B72BD105302D23A1DC342FEC033871BB3C049826790373BA6DD72CF0EE7FACD730E801B47863D7744DC7E5EB38833134CE433611F333CB89C8392689A2CFA95792237FCE981F4C03AE35D6D8739091A0653521F3CC03B4CFAC824B6D2FF13C91C754758827ABBC642053F293F79FB04542A76DD0A65365B0AEC5B4D74D0E73E57A6CC8B4E29200A3115886185BCD42AB969D392CE9375BBBEA8FBA59AC8C4332682ED331F23BC1EAA9835318B9DD58CAD9C34A73B921EF8CEE4C33639490BDA62E12717D553745463124D5D8D71EFCE17F73E5C8F01374DBC88D5E54FEFB9D9D26070DFB675E01BE95C83D82313AFEB303F82E9AC49408D5D92B6B435570A809E0C286BFB7C18215C719D3E24406C067F90F3C20CEECFF1571781D6355A48A46235C31720631F9C8E30EB9DA0C82F7F9E9F4C58DECF6C5B3A0B1D940747F27AC0478A9B6C1360A5CAD9DBAFF568BF06C5084521EC5182CF156C57F85DF79D98AFA0F3385F01A5BD1863CF836D132DEAB0F1D0DE0BC55B66040CDF41866436C9C4459FC1921ED90D3D07965CF48AF319BAEB13F0900337D77624BF0EEF80BC93DA74599CB74AA4F921AA1AD522187AFBC3135B69866C26B7F197E791D2873C7C520CC3D8B9DD248BCCA4082FC1AA98F2E851A814D4C39FDADAF5F7FADEBC2E6CEBD684C86D82AEA07B6237E320B75E873B763E1D5D36DBEBDA522B361A2705B2CDF78BA8C5019D2DF67C41EF22A872D71CFD91F437FBA0D89FDDA36E0EBF588EBABDED491FCA8C5D0AC5F6E14FCD7D6B132CB831D1EFAE21B51BA867589AFADAE45D77054C0EED8025A4D53B04282FEC01E5D23B148C12EEDB3A5972381987BFBDCC44B0A00B35A33A546F9B05E6D77891C6FB299185017653D5673A9738666D596C83224BEE68DB80BD3519764FB0B3BA7117F17EAC1CF2F7DD9A145DA4EFC006A5779E7D66E69F9958B3D16E10671C1A9D2EF491F2544FCA21688308DFF9F5DF029CBC75ED44F0F8D2ECFAC218C498D4C0638B97F8D514B9FCC2F3ED943595F489F564C34C2AAE9072419983A15389612328648ECE830010293A281CDDF9AAD3688B75DF17B10D8836EEC5BABED4918C4E325322C91BDE46655630F45F33D88D224BC3B6C3040C86076E82C1915EDD39A00C8D38EB064D3A50E410E5A35A8415DDB0C7C942DE119059CC1ACF2A375AD3549F3C6453F1CDFB8F491512865EE8FB5A04AF38DB4F772136954FE156C98C81450396653980096676364F53617CF6740631C6D80724187EBDAFB593B48F9643A748DCAABB7E8E247CA1AB65540FEFAA6FADCB31AFEED56E7AC7B4CCA250174CA4C37F7A457171FF7BFDC2C0F4A76F159157D46DAF95C7792F5CDC668175F857121A405B595338FB04F8ECE42FE7BC5B0AFA27380AD56FA7E168B9179F560F08BE04E6F1B1F09C90FC8A94A1C6D70E7A37294D16D11D73F4BE278A99057D349D6E9F0438F037A06AE3956E3EC8B33C8CBB04CAD6DE4D8FAFBDC37F192A3EE01A10A4C499F7BC6ABDFC383EACDFA09C5451BD99A21A79E2041330C8936D17FBB8BE322DD81358AB56D858EFF712E3626319C25235CBC357050022CAC0A6968CF5FB29E9", + "message": "DBB70175E063054DDA24BCFCAF671F820D674F1D09CA173D4A1440AAF50F1FC8FADC1810F390286AC101D60507DD285275C6F97C0D2B2CF3C7F50609CEC64EB029C3DAD8B9954807E35D4836BEDF32501D0E7143BF488CD5B4D1A53C980BC70A3794E4392E4560E609B9C49900E1C56D319E1495D085440DFD081D1A7C52C0A8F64917834C64EF32A441C9045689DDD2EC218F58B3BD534F18309E1D780528D3BD1B23DDB3B18FC1F7C85324D45C3E9B25961FA5257EC31927CA35DB25E6FAF7669D60952502680BC7B5D777D77B194D0CC40372FC8F711EB048E01BBD5676CE3F2A9FEEAA4B5F29081C34969C746208E6F2329CB53A22058C0AE0852B7127FC4C74EB3A8300403F60B8AD1F95FD2991CE0C8CE452C2432B6422EFEA8AC0E1B53BC994C606301473D7855EF86687287BF56B450D2762C5E03AF26A987317C4BFB013A6BD791EFD141AB34718A37D1DCFBB63014F7F92C9E2870DE503452E271E9D02768357E3DEF6BAC5A0F0444DEE1FF5AFC79B3562C12696FEA15815B7D9BAA38C66919D137F82FE36B140B960E02966FABA1EE9CBAA04941396D665DD2C6B0559502577541AB0CEB066E066553A2DD407354123DF14F4B1DDE6B8C34E3264161796F48DB5319B3CDDFDFDBF5CE17BCB5924984143839B4EDDDAA8F0568ECCAD253C48D00687F9A07785A67B62D28B86D70E511AE08A525F66FB15AFD112C184785F91E76852DAAA3E78CB96E20249F38979031712440DB723B022E1323818431B897DACC51400DB25635EEE41761089DC47E8EA56DD0DF60B56FC682D000E9D660D0CF38C263B716359F41F3B190D201950E140D67F50287C09D2008664341A829A074F9629DABD88BE69A6058900DE5782CC621A91376E5CA31C66E3C430CD00FAA83BF765A2E6B2FCD20EEEACCB996FB5C4B63235142BD5FFB4390F8CB95BCD5853D0226F931C38FE972FBD0D6E10DC2CF29D1FFD2653CACBAB8B81DBE44A2B8F1C5DBDA7C56252E4B35888DFF7808B3514F4D7E5EAE9B51078E8D2E600EC57200FB48EF946F021CA8209E7DC6443B37D7281C73C6A3B43AA570398E62CD5ED9A34ED23AAFEFDB7DB3141202D940C1411CEFFBCED878C0D325E8CF7FDCC520CA3377BE97855827D2E6F4EC8786EA1374E006539387924161D65782C7B2C262AF9BA8FCFCB5B1477083836129DA973AB8B082324F74BC6320646448DCC8AB56582EC72EB192D3F72255D85FFAC2B5C62F245B73191A9176BA5A9FC0ACD3AD48D37E23EFA0C65F0423AB5CD0EB76BDC035112C7A118ED47C0E67E510A6F7A28F26C3D6A882EAE74BAE6CF1FD969FEEAF6B36C85F62D40CAA26B6CA98120D612598F360CA2628F6FD608F4E1E290B32C90FF71E181D4B72978DFCD189D857DAFC7B2AF8C958EEA6894ED59AD56B9AA6F83092EFECF9EC4091BCC9B8CCA245C30B54B9B8DFF3636BEFD417F46DDD2F6136B983CFAB532FB623FAFC3CC4CE8A91434377F4DCD1607BF04E431", + "signature": "B6662CABCD010DBE21D9C8E04A2857E7C78EF2AE1D5D583D2E292257F5CF7ADFDA5AE6574FC79E58F254DE8E41D988D2EB72FFD336856AE6A0FA1BB06CB2A8A1BB588F1201B31E9E62996097FC84D41DB9A57112F3F02B2EBB572602F054551D313172B84E90E907EA6E293F1FF7446C5814CDFE2425D61F3DAD02BCC6262F816C73B87F68D2D4BC0EF41D3C659D9FCA7AE921547E442B3D0BB2620208D12932CA6F3232E98BFC2896B8FBBAA7524FAB1236298C6F743146C758AE32109CA3A1F77F96D18D7A87B608DEA8D1C83F705989D50EFC5BC2228D61C6533663B1FCE85669D0A02334831DE3F2A770D2077D4C79A5928B21596B464D7EF0ADFD463491458B1F151B2EB5A6BF87D5CD39C5CA162CB8B111336417910448CD63E074282E51E3DFF91342FEF98BFF2E40C055B57FB2BAEF5ABD42085AFD65E14B3C60A00985F3B4758C0DA6B43A8D54DFFEDC07A298F4CE70BFFB27967EC5D59B91A3F8DC79B9846AA5255B3199FA422694B9C5E6F1A1C8B494D1B2D6F093E6CEE2768B1195615DD350E9072E736911B67FC83BD6ADFA60F2DC9BAB479CC0BEB914A0E9F064ADCE261909A25DF629CD56BD3CBF8AB8107AF1E3DE33D772A4BD8100F83C91934FAAB8776CAD460CE912EE635672D3CD3B14210250BC3E742D34448F8EC576F502276549BFE3D46763875F701BCB01975FEE50157F16A652524BFA5BF6F69EF32AADC43430C7711029C88EACD391423693513127C0411E08D7B4952AD5075A09D1F14287E94B885A43A88EB3D602FD122CC1507EA88ACCBEAA3E939305C0092834F30D486FFF47D373A68B55A01934B2254FC911D122343BDAB0F2AB2278EC4CDD7D19565CFC62CC3D5937C12D313D77A5BA20A6708A43BD11480FB1C7598A55EE706E9AC6BAD2641A640B3B0DB06171E3E9CF2E4FFF16AC1719DD97CE3C21564C2410E9B03CC9792661C39677FA20757F53B859655052B6DC8923A172E1801FD2A5B309CE97B3DF50031130AB05C9A0A7E6985471BA8A92698AAB7F4CD35976AB007B4A43B8D51042514621CE3B8AE764E997C18C9E62E68C4340B03DC4C63C0C7472BAD4EE36FF470E1DB5F2CB6F136B51692A1836AE0B5A00CCBB7B81450BC51605EF4AB1717438DDB7C5F1543A59BBDB7A1C13980C227DC0A412B486481A24BBEEDCB379B1979EA058ADE841258A372AD0A25E5C0D11B87585119282E9EB471D1E944A07859B43A65396A3252F9DBDA5C5C5E52C38529EC4B9ABDBB936CD7146AA90A6E1B35864516CE15123C030853FFFCAC8E65FB30696A0D64C170A6D60918DB28B8DC763A7F31BF7F55D31C6C42BA2187E07BF8B25595435BCFF169EA715F31EB11DA382D6D1D1C20B747EE14F69C8F9D27C353EC651BE930C05AD02502AA296F01B11DFA4EAB1AB6B9E99A59561E8FDAC25DDB432890F9E383F54CD7FC530AAB05BC61500C5738B058F2DF8D789F51922A66B015BDA4420051C1E537390FC4F6C3F790329C963D907B67229CD75641F8B00D2AADE441D47763682686928AB0AF9D94736DA210B4D74259442D623058D3E8DC3B61731A9A3662182A47848B8CC7A8127826AAC45D2C03BE0B1D2697D7B2F85A774F891EB45AD17C58F532074AE1B70C3689401575C33D57CC2EC0C00B643109834D5A57D1B546DE93EBDCEBAD143D5C6AD7498335B45AAFF1AE6EEB4EEA739642A8F68E703E827DDA7EAF6FB674CE8638F50DBE7E4F1B2AA8B3300BAD6F802E3F0358F0BA8C1881104EAA8B4C9887B065EA7B0CDA8EF2354E2EC5B111750827CEA337DBC55FC88C6470FF87A8B7B50BAC4BC7CC5BBAAEDDC6BD1E9F22663602811AF94F49021C86F383E1C9E64C465D78F1C42427894012FDFBCF90916A3D38AE0095EAE52FD539FF857515EA396280099CB36167520B1EEA47AB0B1EBE680506ACD029B4DE61C7389500A5906BC56C30919BD753BABF4E6F822885F13476F1DEF4BD444C39CDF1AFA28558BA48A6F99CD0F065A18DA8281D94656D94736809EC626BCFFDDD1A777A1FA67C642D08FC30461AD69C1332FAB84B400161C3802F19E89C1E962D698C1AB1C8D61AC99987E3E7AC28A8FD42696928712A9E367CE28F48CC9D17D69463A81670E2AE088E0BE21E0A89EA9ABF1D1986DEDA702919A2C9C1CD6851B3356908FA62EC2DAC2817D5C6C874B8F6D5F92FE7617C9CC2C3C221AA2434E156FBFFE8B7C27646B93C866E2FCC1A32D2BFD859B432CC0EB4745B1145F482D03A2B22BD026BC6B37BC802D8621906DDE752AD414615296A403F9F1931EA80BD8B3928F25396166562E62C06B946853C17E30C93F67577B35E81E456952A4086907BB6049906D9E2F9D1927D0055AB0CBE11C0D82D899269D145255EC8F2DDA1FE481E3B15DE0A719391088C1647F330DA8AC990FF06CE0C957F8482C88127B2B82F68D115FFE880BBBE9D4C6DD2D9C872DD4B91A4B52C217848E38805B92507C9899484973EAC5A47C78A53A58E4219B86818DD90F5483CBBDA8B56E3A12739B7B287F29DB9ED987CE4E93079B577AB4FC421885E7951098B1B036AB3A93CD7F2FD65B75EFCB7007E8378D2BD18C13AF5CD6F8B0E5443A87649C2463BEDE2951FB7A963497668993A9ADB3690B9969596DA62549F0E5B597D3BCADA83E66F565E44A0C0B88DB3EFD076DD011141D8FE0348889F0455E3E1AD8FA47F5C8F28005C63FA4562C88AE0405A95069BCF1085909198826EEE7C86D379AAF244A7BACCE44F93D1611142421DB3C82860736016C36C89A3B6FC87509696C708C0DD2A1161F6748EA33D1989ED65D1DDB8878EF158BF1C1973060C00BC132E2407D1A4696C6CE911DD9BB4B231C961B7FB427E8577CB28960FB519C9F977B627B8A59400E72FBC12B1A207CFEF4C2D34592E0D2267D30BCA0AEA3E22C8B7A308B02652E726B2CA97179AD96C8165FE64F230E87923086431D55D1FE4208A987C61E9EA8F38CB56B7DC086A192FEEFA7AA0FE2B3975296B1EBF6604DA709B8A7169A3C610061A4E85EB42AE122A162275256DE631A54E7EC4E55DCFC3FC58FD0273333CD29731AA0E18FE0CEED334427EA9220F5E6401C68ED8B0A0BA69033CF6B9F1960DEF6BF9E5978AA7C1FD480AB685E44227A4B64651DA47AE3B27EB6029D59B2DFD1118A64A218FF7DA3779A1C0227A9E26F92DF3A7EE73382A807B71ECE108E5E46075981A2FF5152BBAE895C9B0CC66D86850DA85FA737E2F1AB80F8C2741190000793DBDF6C54482514704D09055F65F1730B05925CD1773D57849EEA88DE4A3DB8BBAF341BCAC5CCD3B56FE163249334861DF702729EF012659B8AAEE1E8D4E785767C3CB64D1319E23533164D6E789DF1501EB9A6FD7F0F14DCAB73875D4F2848EBA3329D6FD40F60C626406BAABB2B81C95DDB127D20F0FCA2422F74DC6BC3AA5256F3F9F5C80B81D1CE07D62712CA54662205B58E56B3E1684D69323B4E73D6C4F29D9F70F68D5FCC3D89965E5A1702523CCCBC08B3F6427A616C6DDE12C374643F3C7E97CF9483036835D4F928D00A673C6C22F16BE20AEA0E4DFDF88DD4172D4DA21D4200E3DAF7B3D7FDAA5659180BBB6CDA4AD79A9FCA6D5D2881826B40030314EEA07CD45539BD0BA04525DC79326B5AD649B343C23F2887226706D66899881B7CCB4CD46BAEB41E9D047E87AB8EDBE95E02672AFBEA25976319BF35C13C2C1BD042D3DFA527E69DE13C84DBE8410DDA13F38B3FAEB479ECA09F876095E5761ACF0144DD946D2DEB7BB70534E85BD2E23E1863DF685C7E873E9CE29930F3C2A8F78D77F16D4D34A91F1060B6F275DC9C57BFB49A6E5C547B9CA023E418BCAF73D8BAF604E91F5AE69F8CE08B36EC91CC920296577A83C32B07B56776E5311523C346D9590D57F036187AC1CAAB62A4ACABF360D6C4E49517E30726F26126AB405381E02F4C7CF794F8979D54E87B6FB082A8B8A0B1D0A26090A16F09E94D0CDD02886C6545F917D905A7EBDDD1EFA8E5C7763A32DECAA87ED7229C774DC4287B065D04218695B3142DB41AE748912797DDF08A4F8495334E15094B51B21734CAED59D5D2E6635DE144897575B5DD00D51F98715C220CEF67CB08FFA84AE2EB8491303D41F5EE405560930F93EF7A5D3420D203629AE0FEA310855EE7908C1346672C669025E49BA520C471FF6DF9D34FE3960A5A3957E5A007A636A457688AFECB68572B0F55EB90435578E1C75A30A18A17018A7B753E479C677995AD162E7D04AF4D4743A186031B37D9FE4FE23D274DE278FA30BC2C9EF5A5F1DBB431DDD23D8D908722350C3136D26382087BC7399C1CAA1ED4A5508AA0CD3FCD89A45119EAADB689B1D94B5F58DA23A650D52E5C77B739125E660D9836647D7371BC635690D77CF63500085A2FAE7C15ADA7654208FC88629307A2DF3916262523A61C177A7E1F8FBA729B6BCD401F8033302F83DCEF604B4C3F9A5F389C354AA4B938DD145B54A00994FCE1ECEAD40F8D819F232EFCC05FB812A764486D21295E56C4627BCD1F3EEE644DA4E32A8EA4EC4FD405B74BF49A238411AC85E15E4B6755E2EA566F2C38E858641B3486927C6428CB030D1E394A4D4F5B6B79BBF42343A74383A5C3F8FD2373C3FB2D31626ED8DE1C2B31637386CA00000000000000000000000000000000000C0F15191F26" + }, + { + "tcId": 23, + "deferred": false, + "sk": "9BA12496D2759ABB2CE2C3FDB3FB71FCDD7C315B4C7C5AE5C6B4B4F6A97D2335B07CFC9C4B33D9147B6231C6B33CD876DD71889FEAE5C8875128BF0D75F72E380A1C51E6D56CCF1BB2FF2453BB7F09EC9E1FAD76A07CC6A4CD012726CF9309E9EBEC279BA77B159B515A954FEC69758F40EC0C3B3836B661E1FED121F712889B77512258675704133806066748826547111521115868474531585416005713338105507070205662844057632638535166351741357313537883572686500540128261085411603366201318374814306288785181752828400800470585613434710704510035385872517651333585207787188184062530114384673018530063727426246401400773237530844578751387817248277471125878621454431146683341406818333868760704701502761143473707860535758187372162868573323826480416420733630025672348726538053525024423653243546423514553071340770645158747722387267847757250586600731582661356526504140404107264574637750025462020601372686055328846034067308301012344312705314305867783080470360821015418216663460502701754763838654027628220553546644844707313784544085501508364158844217135802560352218345288786203528513537552882486255033112148517000583211241325641064030340235323380524631220275268447538464445758352140612704781828086872330585810217000036008674504425701420181180377803350424765338285178682720218181012520214517830318082227120513518322554881166140214761423438151247072168382748504452500004758363227304767704161305584642720280148873012060716368664714384685145586365736257431288024173772381536807648611435052307322366547752204377446868057638617731102741825234125865523273560843152782032533880776282206451272477621267326281383315581785515642825006261045510323376338070785444022023713881268480640885038174347552814543067652828245641383354501751610445443231755333835224563515134301511513821681374734335016003216522571455880410230421326311811338146248236660357671633348772574361832403770183010531215541634647651601211557845444264232368206771167634647778401370320484608854756652513571656277447284614256054125825545667871576431852286416638036374180758183634577548265761215082800487735370570835434878138206660513012214466631044531375060518448334384743777234256478821032557054374186280115238364375612238562440815877116541472770062087278326687024403300345343640711805831336621255213741538544438567453332843754315440442730654367534363248630360146213140072646271447800025357255281341257570554320245275102060221620818717848621585406508157876043725614243441752316510561605237486301154208628170146326444636374671281028428888054302763653254651680624433732312785052851001186422542016363135628821440082566635447837137437567738250604600438461732334063187876327123582736038000542537210170133043240437625172228545888471831032816233708717083020220534823336673537346268102842456807765246230548276186624233334504072552008188226324457005707040616360473678536233682028686415232708258156535400766767114686043413232745516072208330587043436465427087756584440822673872786114734048782500067420780002787748322508678107138016507217573854055248812267683351608427542745123578836475638204547465316772773558376364227627315732325112263147154784743851852416083411402663045461736077851483201053723540300740062572041704370051846EC468CE48A91039F26B5E7756BFD4A483E0805A91A1A5F54C7AB9507CC918DA35CE125C51BBB93614253ED63D269380A50B1804345C810218E0DF6EEF453AB0CD7BEBDC8AAA364E3C458E6AB8DD9E21BB72B0A499AF42763E3DAF541E0558E5E3A154C4F800CBFBB451CA73A620B3748B04C7D535088254D6267A28291CAA541EBAC426BAEB242E19EED2786BC26A40841229F2934DEF2A73A5C6F3670E681F111A3A1732CDC2813DF8772596A7D6FFD5F717F2EFAFB6BAA793C345FD4ECDA18B9202309C27D00BCCA6E51FDACDD9832A630340DA5CB703F2D68CB1C17EF8242B3F3D60579616E6102B08ED094C1D0E725E2985A0525CCBA21704364E9031E086EF875BEBD0D31A922B91E9B95F6E57985EF2948D9A7638A1C0C76145CDD9577C5585B434A790D6A87809FF6339388938E2283FE1552535DC30C3F073B7C8BC80EF42553D30FBE79BFDE391D9B7F87BD1F809FB671F49F159E4C653654239EB1E94B757E9D81E2809EFD283BD9BDE81A2D316F66BAFEDA9D4A524BB270EE43451434F5F61D33C6DCA6CE3194A3017B5DBA255E905302091D5F341293D20B89F1E5F81D5731014AB1A5EB022609FD6018662EB2EBCF6F3F823DDCB86A5C82B9BBA5741E1909CD60C1AF239FE3B930D0E8786F6ED24A6A8A26E03A05B0BA51AC54F87F845D680A1FA09291405E758712C00B9C0C8D4D698CA82641040521FCB063D5FBE2271965AFC1F4995EF47E4E307D8CF97D9D22A6BFDABCB726132FA7BBF5258226B384B7C06160AF1D0CD8CDAA4F16F68D618F417FD3E78DC8B5611052D2F9E770878D7351D52FA00847A426C9CF845711318FDE114934323D02F2C5F37B9FD93E22BC9433142095BE1D6DE07C7009162F4BBF057466E04DBF98C4DF770A2DB27A5735A4733604247E2C3AA1AF38B4D9D267EFAF31D2A3162391AF0284813D1184217F93221342D28CDF90F85F94D2F66024D1FDDFE6B95774128548611196000DEF8681CDA4555B626CF2D77A2A638AF6FFD0DF73787B955DDF5B9F0A6487C60D09A466D2F97C985CD58E4A8154CDA4CBA831ED2E386854B8EE5523DDE4D0018BD17BF03F02BE38328DE99F9424C01E6F2BCF9DA3C75CCE87558B977F5CE91C9CD3FE49A1DE4A45B162D7C4EBB4204FFDFA5A6AF4CC2DC14B7423DD9C819876E42A75709E72B18689427324ED0621AEFCE11CC766858D46ED7F1783949A8C5618AA1ECDDF332F2B6C92E5EEA5D5E7DC87908547656B65E26D9FB5B2068EA5C39CFC01021CC11C0845A3797541301E6B6C998BFFD7EB03F8B3CD7189635FB13A4E42AC5249F4398CF221C7DBE68863A8E05D3FEE54B905A64A4CB6AD5B9856081AA953D2F51C049E183C47EEAAE60F980B29680675867405F605B5FE8E13C0D3C5955F801F941CEF618F62AC6739A92A818A0F6F2B1D8E259040D190F371577AFB2289D13389579452FD1027E4CDD2BAD5F78A4E6ED722A5984665FEE58FC209AA232B38F45392970F89ECFBC0690785D87A7E54E5DF49EBD9175F530FE091624B281AB66535197122765DF0378ED4814A3A4FD60490C82517C98631C51BF9C4F0AF9F597BCFCC1C25866D2E9038D02CE583AF9D564EC7A7AC4AB7ABEA8F86269B6DA84050070CFCA06862E03039AFABEDE496FFF556031F083255CD1C46F3F94119FDB8414A6E80CFF99EAF2C5BDE4794C119D5F4A8DEB2936C2C4E249E3DBA13C0D938322A91E860D4C4D8C17AB6DE6271ABC5E4F99CE6ED0D728585A985068A0A388A51759CEA3B29CAA0FEEC27A2DB3A252AB4A18E8E477004F5522D308329197229382969DE75AA3BB3C775AB0F74FCE5E1051DCD2C2624A8EBF1F447F7417BA2B5E85EA0CE6678AE6FE0B113CAF257C7BB73D1A5D91AC0529CF7DE38792CA229D1CC519368CA4DB063FA95031F4EB0A5A647E092F59CF39C9A255957DE2EE92AE1FCC4D041DAE51BB04C6B8E5BC52CD73F31AC745DD79F27908E054A2E3906A84113FD7FD4E764AB0F21C97617A82197D1A4EF7E73408B667FF71138BA727CC26A400E5E5BBCA922B104D588640484EE4867EDBCCBC45AFEA42AFCF277A63CE6661B57B00ACC1C2F76D8C203FF2123F9079EAED0B0602BB1788595A9198568006166C61806B5D6ED03761C874E9788FBF180880F9853EEBFE2A933AFA6BE7CBE917C5919F9F17777F55A29E7CCA1455E38EBBBEDC83BB062E914F4A4A2CF1E7E32362FE97831FF33926F1CD9E99C80AAA205AC365173D5DD94B8D8F3922FB192F277A09BB7A92A5166C2CDF7F18E7DE7189ED838F7850B306576D10FF014774588865CB5EE3B161E54529B8E45B2FA435E36846E80D46CEE9BA5413BA950A448662FCC5A8BC8E42AD3A75326747A9C02A6A6C676266B580CA91AA4E9F892EC00EA64065D38063881024F5A898451623FEB3746B2108A24096F2290F98C9DAF9A4DF9746EFD5B5D9FADBC67C9C06F920E5042050CDD3A1B500764E7936124B4C742677300DAB0B2C56BA69B7CECA73A6F97C961AF46648381064764F48A5D16CFC82D9766A35171CCAE17F18C82B81BF91847766FA1C361312B0E532092F9CBEEC51A55E460B67E47E91C90013501CBE9C00E1D84985D6161691E0AB8FB540207991B3DC4A8B444F319235F3B22D03640A98C5DA08DCC417E0FC232316511447752044FDDEA962915109466284D94F7965C37F5E9518826C1BA1A94371B28DE026962AF755AA44035126E6CBDDA35A746728D6BE15618180C3EB460404696D59ED13BBB60BC71298659ECDE17F0264971C5158264D9E9006C627CCB58AC9B5AA5AEAC12105EA17AE78C1D9AA9C479917149E5CEB8C22910305F5CCFC2AA90012D2B6DFEADA3FDDE35EF41CDE929B88F7395CC6CEB401392DFAFDEE51B30A53B67969DF6AFFEACFCF455825675CC2A6F6CCE9BE60D23CC0D6ACD35E9C833A3C82CE16ABCF9E0C56A2C18D1C1F9C159867C933B6179856B9050D5AAB4A547594FCA0CFAE4969CD0B50875AD6476D9EB70674434F36935378BB00B4E50711BC0BC375449CA9FE75C0871063E5BC55567D4E082BD0B07043F9477EFC5F8DEFA13CDA03D3EEA1DEBC996B88E9F60B4909A7B3BD2DAFF53CE6B6046AC2F1463ABF3BCEF4C112AC1E625DEFDFB28BC0E0D67061492B0F64B7C66B89CD1039EFFF0546EDFFC69D14F7CE61FEA845CE360D8ECD01D1643AD4C9ECD76125CFB693DA425D877B7CA327261A0CE4AE49057C622DCFF48C6062E0AF24FF8280AAC3F21010C05B789D8FA371F48F18A2144FD1F8423112DED4DB1035B2F5E39329E680BDEEF5A37B3155BAD91DAF7B0CD8346917859D7CEEFDCA7E7C6983E09D789AD7EC35F9848B639EB1F3A1B44D78521CDAF980D6F52FF981C30605E8F5C0991A479EBFD92DBBD6CEF2FE4B0C70015943D2F1A072FFC126CFE6740DEC7DBD9DF059FA1C03A51ED2EBC7B892FF0F0D34C2DBC4C1561788CFD18F0B4A3E2C0B3EB57215C26CF7E28C544EE7372D7841D349F261660A3AD42968D98D0648975D488C2", + "message": "5F8F32FE68B556ED1D2EB8D2BC20AA36DEC7900F8E5D4BD3715419B28771E5B0A080DEB2F3EA6CF415D40EDA46FCF8A439954471B7308D3E4226E9D5A96BC22B08FECEB4C5E3CC2239473F1C9B8DFA5A29C31D499CEEAF6E34A396BF0DA53B54F1AA674056216756DFE15F669FC2E1D8E6F67BE5BFB3D5703F25D62D3AAB0398AEDEDF7C65E051A4A8DDFC725EEE940BD0D06B103EEA32D027CC20A8C61034DC54BD5533CDB1A85107B9CFF283FC3C5FCD9C3D6F8857560311AC2E0E31585E77D0806F9A4E61A70D3FF36895ED447C55DB52002488045CC358A39475BFE8456F4FBC36005218B2CEC1C573E41BAFA7A622EDF776C8AD340680C1B3002F69D3B3D8844494EA9F42D2C9C9D2BC0BDD850BA3C4DE929C1DF49351219F95EA7B9794827FC1A1BB4A6A00809393BC41852820569D7BC6FD55339925FFDF55A0C2655C85144234FDDCA91E8BDCE8CFB7199330763F5750D71CA8C4B3BF7E6469F5DD68624BD6D5B69E5FAEEE53E3A61AE659A364484B7D2BC8A85BE9F8D35C8B97716E8202B610BDF878C1BD83187F7892BD861C09FCDA64606A185B93CD2F601C3107D35B38D76D75AD6023AFDD95E103EEB7283379BD9E44CABAD923856A599B719A18FA836749E5BA95C79B1F2F1B443CE1FD26CBD2B74A0156C381BC270B74FC42DFF8D91DE4ECDDF3053007A09B8E3C964B90DE55DE5193F218685327D8C0C6CE3BBABD57DA8772DB7CA9234A3D19BE16A895E7D14337FD9D50B4A556C75A9D287B44BA5AA4E52C3262218DDCEEE3A7BDBE1B8175E84113F515623C07BAD4FC0985112DE4D77D31290BD013562D12FF8CBC5F2BC463223AA82991D7D60E38037578BBEEED70631CEADFE49823EA3D87EC384B3FBD4974C474FF9D47F467110EA4F3FD94B5FF38D8FC1C75392896394671853FE71DDCF7730C70ED26485F395F180D2F5C31AE0C2C20691CB4BC81356225E6A72DC72A1CD3502E42C22B594118D131BA5EF95F2C18B3061139B047A24E32197F89780B91D36B28BB5EC6C03232A3CDFC5ECF687BA5701F3958FD87FC0C8D09825E8BE4E5CE9089C674049C38EC5E0FC1AD542F57B4770B6E5DDA215D319DBFFBFEAD9141647A508E271CF3B0DE7C137A5AB999CC88082FF0CD495F1F1FB1E367B57BB400D8697B4620B75FE467D9B8BDF9400E14047576B3AD6AABE0C0714686015B8A963A0DBB68CE9E41FFBBDD5A792920916538E4C33F12EF0E93D249E562B71BC1C252E1DD8AA646F8C7B489A2BCFE7D29A6D3FDA2C21DDD78179861AFC766F6885E9959F753C66462DAA6E01C8B06A6F581104B583F7A5B1B4935A4EF08219FA8D114A963F3FF3AF22C3D1C1E3927AEBC886AD0670FC89C08FD4DF68EB990A0F7C51A4439C32F5F51785B20DC82586940C35D80A91865C3154D6C925250B24D4C1A9E76A267711A0813E8CCD2DDE9748FA0464006DDBA963BBDABAADD377239442DFEC6F7E8098604645D63AEA080C1F749CAC589F77B4AE0955FABED757E6576966D539FE1BE5965D03882279B2C9B6899205C9DE8D0B1819DA8B5426E573CE785FEDA3BE95A18A667AD5AA8FCE7894BA11A44B266EB7571A93CF9FA64C1132AE07F0F24773C83DED2C2885D415ABD96A21A0381811D66952252786C39EB68EF0B9B03BA7E2B66A49BC6CFCD8097C321A932E5CDB11EC6E43A8E50DDE01EA5A28F08F5047C67C988E8B4A04701A0237330598ADE8EF8F801A07F2148B44E593B0ED16DA30BF37A341073C6A92066645BD7042C3A59B374FDAC00F7F69BDAFCAE5EC0AE65FCFB785C93E49102F5A5029876BC23B0FDB7FBBC376A9E834F0D19A276BC4E22FEDA18FAB529F15570AB674B844703B47D726AADE3AD4015F52D86843A01AD5DF086E07A71A0236765DE6A777F94B1D69253A424193FA9DF54899AD9915634DA23E6DF351E9608219684EC8C8C949E900718DB6FDCD144D0BBFE1079C1BAEC516BF60C1E24B8EE6DC380F55E0F65DD64025C937EA89FD12F0404ED0C03CBA18CE2FCF169F9A1EC9B96830FAD0149D4A90B13446347CE4E5C6005BF115385F1D22EF6A7E40EE87847BFDA4CF7FC3135C4164091F49DD08389E1005271E9AC76E27B0CDF360EEBEA9C08E233CA58305CB276A8BEC9686CDE0E2DB5CFF9858029F3A5A42759E4AC6DD40AF9617CDEB03FB1F9D7F112A01B87A265C4E27BBFF596695F127A97E1558A68BB5EE4EF0F44D20F318FEE1CE988051F3C09AF6E142932EFE970C1B0C07040E7F3DB9BA53BC4AB1433F7A4F1E480D920C23A07223D7E43570320B3BA590507D580D29CC3A8C85A442BECED5880350F9D2B1AB5C746C1B9909E446D9508D701204F2427F41E043A78024EE3F60EE19B71B5BC925A2557FAA8C7BAC7E3405C920FE3FB3A1BA7C559BD75DB1E4169804B6627AEF19AE6E41B8A40CFB977C1AF53208F4D775A48C220A756783F41E13B7780328992947D215C5B5682DEC76CB035B41C007CE1017EEFBA426EBC423F710C1E962528F7636F200C2E79D8377D621513BA7EB3EE5A0DA55B81F6039D2E8BD42EBA5B2A82C3F033CFEED6EFA7D970B1460CEACD13A0C67AC0A7EBE7963F0FE21D20B2A82EA922FD889253B5D4CE4D47698D43AC11A8F4E1638AD3A4C179C522A3ABBDF420DA3E89B9FB7608822904944CAD615C62B28EDB15D3826D33DCF9FF9BD5DFD8639AF4CAEAA55F9F8409B4E5F70681BB7861F88283218E15A4282E199BFA12360FFB9BCD68D9BE5A3411FCA4E8279562F595FAAE0CEED4FE675DA4A8FF94B180AE9D0C8C687650730F05715820F67248D02EAD4C7BC0D41C880444B94CCD60A66A1C9B5B6F6690A2E1766EE10B5D03AC16F175603A1B9D49F97CF3F91932E97DE67CB523A38839468EE7681909CE997BFE5EEB364B472220403EE4A9AC1F8A4A8F78AFA4D9010A0127C0A75D3CDD87DD269F19A47C78F696218F25AE8A61073644A4F791ABBF1B180267AE41DD44AF65EC6E0AB356CFEE86095B64F4190D69D60284A1EB42744C31536F736AFFFFF186833EBBF43709BBE6903A06F7F06E8776D2AE41CFCA33A3A86342BD11B67EC10F525563A1843C8443546C1EE61DAF7310802AE9C00F44DBE7E04030BC4D0F53AE2023A7647F08A0BC6F5013A61A84E994FE0A20092DE133FABAE3AA24F8F3946812396B0643721AA13417A2423F96CA8A6529B0E17766E88B2AEBD79AA9D4D31193533CE50E4EBDAEEC976F156D5DE5917D54F9CC0527BB4F1F795401210739A42D10A0242748DE5FF6B50932B507057EECF8A1E37800223378642DEDADB464F5CA251D73DCD28A1E3772CC285A33B34C6701B585FC03C94A847CF7B16616D1C3DD646669546D80A27E9DE6424AA7AF6F1694037E774259308E71E15D7408BC1EB517CF0AA2C9E16B802CC8553458BB66D96CBA233487DAAD6E093235D901CF46F31B9A060D88DBD0B7380652EFC73AC1A6BB5E434EB0394F1EDC937E9A99A3867EB71D6E19622137B009D36ED7F9890187CCCE7D884DFE118AB3682EC08CDA8BA6DD4B79C9C18E7438E6914DC1C403870A540B74244964CA31E730A7D7591E42569532DA8094559241F2C7EC182FF8BB5A3F88DFCE3020D8B8CC0D1F54CF67FFD3A97CBA7F5EC79333D9A545221C963E0685763E59F1EBD34FB2394727896CE638E909AE6DFF41D17EE1D0BA036F8AF11335A8C1B5A0E9DC58EAB9C12F46740493A8B5AD0EAA73AF462BDF43CE44BD0973688D9C8DFF8FED961758E1AF88FD5D249FFEC179FE5AA1D135C0448D80F4B0CB68492CA399A3916A2EAB684B44E407706CC3C2F48972BC9531353091F91B427FA32693906DCAE862F34AEBBAEFD30666523EA9C27354F2FCD99A6E810685B51965571E4B4B5AAE158636497B6F952FA0B73617AE35A8D7C272DFEA1CE06E983CC65A501F73BE9D69EDDE6A4A1764DCC4B74EF09EC27C74B677920AE8C49CF4F18160E04B5AE7EFA8D5D92BAA5E4E547CC8AFB9D55F1A9DA7A6AA06626673431889C9996BE0A473702450B960231A617DF4705B07B47DBA1BCCC0EFCD5713F88F394EC4BFCC49EC24B76D531A356A6796785D755F027C664D8966B5CDC82ADE776BEECA8AB0D9DB6ACF5E841BCB4381828DB8F7358A637D04D97598A8B3BC823B891F5EB6ECF54E6F9200C380813FC3210E68894A656796C9A5B780FF486E6A93DE055B8F658FEA17035D9C212D23BB5974E1161E4F6041E5AEC446D70D52CD2F21F1A33C9938032487D9ABA74C448EEB8F8D51169E8B848242F5C769B471F0AF04E965BB0F4AE7C6F7B4AAD4E283DA762DFA49FD01D21887ADB28781FEFBD931AD8E2A26BBBBE5D88B52E8B7133134CA76C6648EA39E3D2F102177F4237219E06CBD05174D503C9288EC9C3E0128A824A7ABF418DC45EEB3A67777F74D6EC52891EAE0BB56DC756ADF40D39151E3A68719C563E99BABCA4C785BF4C2BB1BD25C7EEE22A8B0C1E90B948FC3A691670E9A3A331320CA4416B492907C3FE70AF9A2E765F9607EE1BB2CE52D2DB15F5DDCF59BDCCCB5BEBAC2784FA0896BEECF38C24022046E5DAA7607E8D2DB8CBC65541CFC6A0F20CC3AC5EBD4560BF5E9A3FFC0BAE917B479D960ABFC99EF84A696CE5A95720FED90F3AC58D77D48BD5573A0D85681238AC0EA8F0B58A01378929C691C146068897C5642DE74D79E08E5B94B101182200FB3E2BBFEFC8B44D2D1203075862D77A184B25A7790D76D7CE88C979D73E599C212F04A8B01EC3CD6CED3B5E25487957C56BEF6AB4433FFFE6DBDEA396212A6870284FD1BAACD5F7A5D9FAB90D5DA39D3C5F9AF196D9C46100BF45861679A7679638BBC8E5B5A7606D863478B430BF2C61F52D3D88B0913BF12597620D337DEA52BEE9CC8A1592698D23B23815C596981152C99453FA16800545EE781F24841FBE5A3E5AD8D08F2B898127AF40A681DF9DB68681533C349109C29D19311BEAB4C2F2DE97A5345EA7E41CC0988B2042925F1F9409D947128CE1D38F278863385A19B2CF8338D0FF31B06FD865B9167488EA157C7965F4679286077894660F17BC7289BEFFA93CB7DB990A0E40D998945A77E536902FBAD3C8A278CFE0AC883BBEA0B20E5D70EC6E10B59C2449CD1A0B55F8252C91CDC87E70E72FEC175D6D67BD43CB5AE4EE9C7F9476F4589E2BBAF89E801D5E14458F8A0B96ECF9F080E5150E2A5004C5A89B735639621157C4056DD1106CFC727B921D5890F37051E2B906885C1CA3999C18FB8C9FC9B652D82AFF074EECA9976D612ADDE990DEA418031FEFC4E972B31CBCBDCA0469E3966FF6F97F9788650298DB71CEDFC04659D30FE673602659C19A869FB3EF4262EF3FFA9E3FFAB1A3FE7670061EBB0D49BC60AD0C774913910E26E4213B76DB72AEFA3CCC197CB6F6DF773F86F12480B5BBC2068F61E16D1C0C141AE6F1811B2E0D713AAF60B90BB2F00EEDD4651FB5191DE5A246A4D8F3E9999D85253FA705CD4B94A6A64D9E9B6E18BB6855CAF6B991494A8DF75E56C2A427883E0C27246E5854B8DB2EB0FE639BDD00AD678D1B61D799AC59ADFF6A8616B357A4B12A786EB612E5613CDE533D92E87D51D47D860BCC39687485EA814DC5F5A971EE915C193ED52AED98D7AB301E32342F3D207BC03546460D33B733E1008E48D80E716FD717BA82403DBB520246AC3BC9CB91CC0ECDB7E35E6863C3C11558A8EAE9E1DC49FBFFC0F92F397828A4AE7107785939B96932B9EACB6BC6D8B3A189B5D3F6B0C7A3A413054B25318792AEBA3F4C77629F1E8CE1AAA98FFE1EF50C2E60C11AD76EDDCD8EEAF858364ADD637AB97ACBE4D2124AC0AB559E85229F1B5D81701EEB1D6834FB215984E9DF3847392EB29D2A428DAE7FAC283F93C8FED86FD2377E8216922D46A51E628091F6F8EAF967740B0EFD84F002358D3ABEDA0993DA16D0D8233090A2CD9C27D78DA0A53962FE7DD282B276A30F91C2B734EAD2CCE5E03137205BD97739F6CD75A08491D4ECB22591A6FF840B5DF123FCA7DAA98B11C85C1F8591EB988024C206CDC4A4239E7A91DE75F49541FFB6D91BE4699C0C0D8B4A44A8204F7E90AB863C3183C2270D185643D6A7165C1D043FC5108C340650F38A8FFBB13BE4BE68858C50A2463F7BE998286FFD0F981B45F5E414FDE71637D6EE77B33E10A530C630D63F21A212E844C2F7A26BED4F7B4DCE0C566CBAEF4EB4BDF2B53E743EE13A845D3C7AD5E9525C50CFED35DAF5D993B6377CF1DFC5236D51151B046F4904A02D7D51B6E331754B0E3621DE4CAFC9D8F7247788DF0EA7E6141FAC4B24608282AE29D594CEC0C82DB05C0087AB377D0D504F64F1CBB2D9F3121087AB6F35A70ECDDD15C9AD2A185C16333BB901CA069BBB0B80CB6F505FB3F382CED72CDE60FC050241B1D32818D11AC4421B66CD85D0F7B479C021AC111F8EE8F1C60B2320585EA276879AFE4034DBA277806FEEACE548CA0A5D36CFAE7B99ECB0236CF4838254A20A13A2DEAAF201B09FD027BAFC3F0C5ECA9EB5850A58C6196645F051E57B82AF4B6C2DA9441358BFD2412864950022A07542601631A00E27BCE6E203B1D3F1B844CCBB2EEF71A12AA4E725188073004849A225D733C77C068B0D2AE53E0DA6F759A8E7A5486C529B29A3EDADA69924E7DC200158DB4B612C62039B321CDACE8294DBB1A56ADC685B0B0122A4F3DE0A264F47B00C903BD30B5E4281B0C75DAC5C48E18BB0BF642F8C2CA194AE56CF7EF3B4529FB9271774108C61198A6894FC9FAF896472D1CE78DF00E714045C5F7C77DCEA45B3ED5BE5AD545D8F3833206340A5E10DD3375BDE0A068D050CB4C87E0BA95CBACBE59280BD5CABCEAFC88F5C05E3D8DCDA6B15C487B62B467E093259230D47B79F36572972BB78F90BD384255CFB1E4F1DFB7B5360EBE1230F154C3645A7A233FDDC472432F6C845CE86B078D93A5BBA3F8800C5313593D66A8A103B01377FBC5C6D5FB8A55DC71EB0BC9904B24BAD2F505D6DB5640E914D84FC71FA058902578B72C47659AC07AD4D64C3D28328D2DC8425C4039EFB2F20E3B954BD0B0483848F2C2D9528214514510CB0932F7506E9B98D0E891D8183A907FCA7AEC068B9FDF7F3479A128C6982BED19512A4271D8B682525B5028B77D6B6301181B403E5F62F64BA3CF06F0EDF321114855839E9198E5BA2A65ED952B2204809215B9BA3C366FD5C9D409BD71ACB748E653DA82EBF617D2D57C74CE37BF20AD8D789DA53C086423D86F94A96ABA379F3425554BCF92F82FBBF5C2A15947455D7D7478A84BEC6E3B9FAA14E425D2C8971DCD157C1D9E210620E891AA4304CDEC54BA7B3352556C49A172EAF19919184CA005A526349918F9A7CBFEB83510AD899BAEFD3D1F689DC3F449153597C8D21FA1C7BAF18E689B51F89B9BEF196193B7A781B96B38B9145AF7338FCFEA109542BB1719C9C8540B551A35F733C394F7831900452C0B8D36BB90824699BDB587EFCF5E8410E4ACB8ECAEC5F96E74A5DD3DCD4C85720064A14028FE768041BA1A13A46CD8A0D2C4D09E724591ADCD5EB907038853D8C92C5BA7FF57D5B54B2B324073C7CD2EACE0C521254E9E5C0CA197FDB3C1AC73FA8EDA729A858098E6F5EC11A19D4F655C6DC9AFFC4E67A49EF62D80EFBCAA383DD3DDC22C2A9B7590C16F8CF23D52392186B95EF9E947D851079C35FA11595682DF4EF4D770EB16CBC3994326B8AB3B2C279149122D178BC7B53318406738290596449D797F61B3D0CC8B11750F8D841FDD9D333A5FECC67CC7733824BBE257D40E53B43CCA19C95ACCA8FFF393533AED57D423BE0C38584A81689248BC7F78CB7FA4C94A7BDBF3015B4072B83748E55ABBF4A334AED679D89E2F18BE1B249B3F61363C79AEF6E1FB09D1948610F77A9927AD6D57BEDA02BB1E77415DD7FDD3EFC683AFB1E20C08284B620EB091974FDF8CEFBCEE1461C210E81E86B61F2D5D1882261D60D60689E39C81B981EAEBD9A42E608A34155516E4E385B86BF0A4AA05E3F99B6B3B7E401724D1442A45A696A189765BCA3240111E9259DE161DADB4E0ACFF27818C631A8A2ABD752773A83DC29CD619A58556040A7B27CF56086BD499F8B8D283683377A21BE120374B8D4561AFE781F246AD987E828FB40306366B4BF4C0B4B909ECA91DC85F521ED5869A2F2AD58C74B6C959AC71DB6F11503F026DFFF6BDE6BD70363B5B38BCA0590A5AF2A1054209A36B41B2A671293F2805568400AB282F783C356DDE30E0F87C001D9B1B9716A7C4021928253622F2DD156B3C3038A077A5768AB8AC070BBD9467E9C9630754934186BDA122CEA503F5E274EAED746065CA81A2702B582E82A33CF6CB3917D451FF59B0909E6BF847E6B610DA89AFF98B3323E1385954EDF1175C0C1B158CB905BCFD9AE7FF9389ABB9FBC5194A45DEB0570C58F31D914F9941B0242717B243ABCF5A20676051978C16FFCAA8ED2EA23B8323CD58388860DD64FA39971F9FAB83A4B248EC8161D32565917B7E6EB4937B4743C6C236E75E1747A1C83377FD1D927D385D81A9EA7F4AE5034097A0A77E2D2EB1943D3128BC0134F2D600ABB929A5281C26EDE1C12CDC80F8EAF2E893091EA274EDA1A246AEA3263E43D6C60043CFF6282AAAC620A21B523783E0CBE33F78C89D00EF8920CD53C6EC0E83DD7E1303D9B6D5280BD2BBA26376C17099758F34C22054DA031C86CC50367C81C3059114A71C565B1702981D77040B0FEC1E89436ED1896E93BA202F11ED2BA4EF33A76F86AE8E23B8FD064C8FE894244C97BA7BDA6BB56B7517C236400F591E4F28050C2958A7A79964AF233CFF8655F1603F6A0C7ACCF440D0C82D5528876721434C163D86858B02C6F6A660F53B3E45185FC7777A629C3E4392AEE4A96D900B0F19783DCB6E5028B6E56E160A37D37FACD7C3B992773ABC8AE1ACD6AD41E7340CB198C9BBEA1CDC185AEEB51E2620F0695C2691A29CBCA8E23328E84B6882A59A8C3C2A273CDBD26965564F1F1DF0B2CAF83F30E782C049DBC00596BD85426EA90ED30ED8EAE8A88C0D1363E69868E8CAE56E8DD62CB36D9A15150FE567DF7DC93CE78706BA983885155C9AF05B5FF1D0EBFD9D020BAA9196D9C871236DBEE8A703BE458938D3C882719881BD49476386387DA3508780878271C0DA821BAA1E9719E437BEE6294D8E4E2483932D0257B44B8CCD8C55028B3B7D2BB3866216A7F52CAEBFA0FBAE120609F95213BC05AE24473C98C29F4A46D985336DF8305787A0374098DB279EF0E34E6DD79BDB106EEA24E4DEEAB6DF35C58AE73FEC926174E0942D242AF0D30825274FA1D510D1C0C41FFF59A4381CCE5C6B89AF30C41733EF42E76C9CD58DEA7E881706843BA04E3A170304C551B6C801CAF9B8DA52913D2DD4DC755E0BD7C723C4AA5B001D9855236401C1014507CCB84577749DB1AF29E318241D91C4B23BD80549CD1D6E0D793E966A8A7B755552F16D3A1146B0CC6D92C8C90E97D7EC8EEE7C365697F93AF257BE24691E41F2AD26BCF47D52A1B80F5BE1C658616537630088CB6E227B0EE6EB8DB2FEC0284E58202A73CF3AEC16BAEB59D2A6E0257F0ABDE5926D9A13D89A8B2F69695BA3682E87A77DE06FF54892F56581FB16991654F60EA22856D6FF9E0BE2C4837F0C1F6C54E840F67A75185F0DE9439AB1E37D4FB3E9757B0FBD17C89DF8568755567C390032DE93E9C93E6C89B2E66E9E9D96616919D9FB461F9F33", + "signature": "E2B72659B75C1F48D3ECCE4E6543C8C79DBA860CFFCBBEFB69AF338A4816ADBA6E6673112627712B5370954A29F9C896AF05012B290C6171DA9E894EA53A94F6C87D096F6DFDC0D77ED5BBD368E4F0CA642DCF6C89462C1E694F8B9C67F641CC2859EC7289A85FA82CC1984B5FE045DA7814CA6F693D144DA720D33F1619E74E9435DAEC3B4D64888CE2525FDB063FF6C4578A3C783B364C80CF09B10D2868DA846858E742E7F5E5845C49B4694E812C39D021CFBDEC8172A6F489C8D0A5D57241A8F676CBD02446725B6B2C0A51AEC4EE63339477F0D7B7DA74B7D343AC283B6BC38D79DE45FC28E20D4BAE6D7E9DB775E4801ACD3FA93E05818031BFD882905962BBAF1A6CB0543C68A6A1232E6BFC1B820C53DDB53CBD62A849FA24BF289589C860F32F35C42F0C04C24750A47307B07BC610E1B6D7BA61FA2DF526DD836A656FCE196A8FB708DAD7F85CCDFE288E2DF71F3BBF9C0CC6F48ECAAD507AEA35FFAEE1E7DBB53FA9617583EE72DEB3DBADA8208E19C584F034D75B50F0927DA9CF2793A1218298434C32726351A48428F94A19A7A286CD99141F97301024B6CB6823A199B3EC759ACC3A7CC20D43072A5E8112ABCDDA6A17C1D9DA1FEB4552B07575FCA4B697EB8165BD0DE2403AE19DE5CBD60FB21059010C3C4D2B0DCD918321DBD7F94D59E0B08825872083FF50847A3457ABB30C5C32E4DF9735553FECC558412A22D46A165AF38A07CE0E2E1F888A5DAA2F9D39870F008E38291208F7D2FE2D75BB4E5B6DBB16662A1DEFBE0C4145CF91BD2E66A670DA776993F60A4757CA5BA0C55BADBDB1C0BE86D290D3F00EE241243CBB9CDF5B3A93DAF95840C55320B931C6E3EC9389B117E7BBF23EB6192965AF97DFC89EA6D2580A9CA0C699A66E22FB7354F203FEFFDC4934251A8488A15C3491C3C6E5DAE8C828EE56D97723C83164AD15437B62F4B06133402A3F1A261D08F6091CC5C46C517DA95717FE632FCE49C659D93BE9417AD1507315915F1C48F20A66F5F08352C83E75775D27F76B1DD73961D50F289391FE376977817D12D7C9591FA2832AC84EB00A8286841812F8C120EBEF5FA71F79AC3CE6C77862D2121B4B21A33459566998CDFF4A0E614CD6CB72F5AA2643A3A61D8104CCFB041E94D433AC6D10352049B4C104005191284CC9B23942D90F3C53D05DF898394EEE9E041B735BBC85F20D454ADBC84D3769412F5E6B06303C503BF1C29E43F93AC993BCFC20250A38BD862E7348AEE4E693B1F99FAAD7B7E8D3F5AC1CF8A192D894AA3BDC356106F4C212954B25D86EDF4FE97ABA3030EB20A9DD48CAAB2955F830523745B0208EA35AE42AE06383F8CDAD8E66D5A988D95D1DCD310C9A6AC53DC448AA80B21B78C2CCF3E46B447EE9E9E0E090BB6DBC1AA4D5A6444283CCD5E01438CD92226A4FEFA67EBE63480AA072FAB17BFC0FB0E0901B5DADB7C29631B3E3022574889681478E02D5C81B7C676122A1E7AE441D16E090D5EE64A17033D0D0C6953324C5E476C652922FF1F1E47F833C3FB1705E5CAEC5B57AB93D192CDAF9CA712AC0BA70F36D71A37D366BD80A7BB3E382EA87EC5A1F6B281C01F8667C4100906D713B83DB6A50C8C527846EB728B173CEB9B6791845C7749AFFB6C72F362CF602D70452512C76DDE9D1E76988F3C6EB14B43EF02D1081E6FD446576CE727DE20F6B25214DAB404B4D77ED2DA703DFC0E4219D44CDE16F596025C9E90BC0B52649AE81E95990EAA115368A9C6B16F64099C8B928EA42168CFC544445847EC42FCFDE6095FFAECFEA31515FA4970B27649C81B49B4AEC86D1329EB1F5B5AD04851651BAE0236C267728F1B0B8939B0849D9CDA009535E066990C664F160F5B8387D93CCA6DC94C8AC8E5A161F0D4E71417F43775F7AAB83550BA7DF60AB7D58DA72205F6F52F98A5B73C6608EE34ED7758D15AE7360832F929B73E8041B35D4D428FFCA023781B26EB65C8D3A5394B8EDB1A23EF228850F32C19E8C8638F6E3E8D64BA7346AA7BE8356CD61C0648F19FF1E959951A2B92B635588FA51CFEDCE28FE0EFF9B00EE81675223A8EADE3476EDF74D688C57C68E78FE3557D97198D74648CB71FB218A056165590A03E4AE830E8DAE1FBDE2B65964A2A9DFDD75E7FEF4C11842DDD8DE5B7ED553940AD6C74EB10802F5607668192FA7138E385CA14C99DE873F48837FF593F5EAAC30FC7AEE7FD0CBAAE64447EFFBA244AA0DB2CF145030EA2CB6738D95DF990E8B6B981675ACF4C4CA0DA779BEF86116AEB5CA18010CCC8F971151C5B61E2C106C5DD38CB9F7122AC17222163EBEEF8FC9DB9FBFE8F9631996537DFB7B7080A466CE52EF5459315ADA3C8E8D748CE5BBC02D326D676247D8F6207AFCFF6B9877B4ED1082C283A27B8612EE26C9EC76415C14393ABF8FF2F8E54C62CD56AFAE745FA698EFAB0AE19C4F1BABBAB440B71DE8510B7B664A9B9F8F80C4DD125549C0546D4D42CC39022D1BB599BCE77D24B4AB8EB1392C7B0160C9BD376B3FCF822B3DB1DD6E61A3EA2C5369C7C1DDBE7238015196154B94201F935CDB203D8D82C29DB4846ECD7F99E8A8FAFA204C5C800D7A6D0E15791E197E86AF298116E2E4BBAA7365A51CE82AB819B2343B05DE001EAD2E0939F8D21CE2482F65686E5B1DB274DBD223E97F0D094CD4E69A198751CA2AEFA95C937EAF7A52245D560F9126EB4B9F5EE30A119584AABF46AF32D0507E1F7D78175A919CE7678B8A120E169D502B02D9802C02FAFBBD5437EBC4EC674E21DEFA246A471ED242326B523917DFE2E41C1D77AD867D64C09E711CECDCEA9028BA620FD799209A93BFCB7E36EEA2971F977E99326F2F54387752BD19EA29C90CA3C09D9A02740551EDA36D7687CEF24A6D35878B44235E8147D1B752C2BC56BDC86B41588522881E7A9E290B0B2D2B2EA2F56A3C770C7BC2C144F0CAC497C181B0823BC6BE8387FA22A448A9EA92BC4DF5F6CFC946705F20D4C1091CD96C67206DC804969225C0CB11A4A1B476EB557AFEE3AF5A18E763080E723A60359325053C16BADEE646244148DBED40C598A8DE738F5546CDE8ECF09FB14ECD37E7F9A5B622701D92147C32D324FF9525BFB30E85305D0A4EE82DE52BAD8AD6A5D66BECE7002C115B954DEF31F9DDC7E87AF4C37552CE4027606044AE792882750C8ADD98B6ACFBCA0C087ED65276884642FED7AA393B7ABB5C35EB7F3A4922D97EE16AFC0043A21495D1D1D269327F9DFA44195E205F6603234B067C20D09229772354041771CD1AFB30F11981B6027DA1B3A6F465300AC5C0E41FBDEF7D0DDB432DE67C814B76A7733C5A84637E56D7D620AB3B37EEB81DF16093B5612D784873F84E6AB6E28827625F1981AE31E3F78BC4F68F215F4145FFD9530DDA56FB1F67BFC6ACE5C647F0D3CCB2A8255449638A65E3F070FC200B7CEC52C370A86C02188B3F8BD809227F08021C1CFF8583DC561EC62CAF8C2CF878A25C8C62004E4803C15837F2A8FB76A2FF611CDB597B793363F9F1A02D2026E2A87FF4BAAD424D44B24BAAF7472E36ECCEB0AB87359AB317F880E5E112EAB060D8B1A6EAB5C135D5458E628F43F054C8CF2D19966319A9894135FFBDC0E5035A1D2B4418E466C8556DC71348A34082B07C6725B8963F97D2003BCC9E4208F4B28EBA007973C582E9FB315BA0AE288332B94495E2436CB94CB705C8763FFC696894CD2825ADF31FAEA196F6C23176FA6D2499944131F09F07A6F86B1518092B51DCCFF01969F669F5FF0F8E16FFFD044C2D2DCC0E76E7762C0A0109F7C9EEF834F1584220FAD95FB4CA00D649683D15454CE7E797B6F28F195878F5F42900EAE1C1B339489141D39EC56411AC205AF6B4E0D00A58AEA1B43BE74B5B5930ACC43BA774032E7E3868F4208C9420FD59D3CCE11AF933F964AF0A703F7D73A568C89AD1AA9297D82A606E94350C13819607711659F1972611AA5EDB0B061BE6E1C0FE17BED2D0A3AC80963DBA3A28F0ACFB9DF8852573B35EE8975364A9DBF85A32952488CE99CAFDAE4584ED43E00668E531C5CE7D69DB910CEC52DBAF374A73CA22CB194984F1BED01224372675B892A8FA7426BD2EABC723ABF439C15C1421357BB3296C5B4027A4E2873D5CDEB60176B299AA06A37A9E86B96C91EA0F4CE7A32D1A13F453526C38163291B7D1EB78A7C7509FD4AD09EE2B73EED7B48BD6B8864DFF71861165F7141DD3032EF27312753EEF75AA1CD075FA76756D54F1049B3FC7E2B6CCC5A40D8A77E38D1576CD95F9CC7CCF8083CBD348CA2C50DEEFF4D6BE391E49C8704AFFF70B0FD6C978B1688E000A254EDA045A682B27166645B17803AFE2E794545A7877909C584D3D8E58BB6B0BAE76B4700B9747AAF426266A65891516A276485EE9E0A570DA8AA36C5879B0E23C9D3B3165F46648ABFEBD65F1F82C6D8891D1FE47D51E777AAD299BFF8F5A636C30CFBBACDBE423FEA9D93250C6207121B0D7D2122C6D5E8F6877A6C05DDB2401E997FD18DFEA68993ECC9522E1D9FA0B2F4CA779B6B11EDD658A6AEC05CEADBE69CEC2792669F180558B235C295082EA9E20E65AF03638A50C000C657B8E919FD7E3F1F8265E99A2ACB9CDF93F4D72A615454F6D8EBBCC1D5D5E6CCD447579B2EF000000000000000000000000000000000A12161D2227" + }, + { + "tcId": 24, + "deferred": false, + "sk": "C76D6626F120F0DC3DC1A840BFA94FFA317233CE5DA1323B24005FB7EE273AAB58D8935C11BA583F58DC10BF321EE6A9C86C1290EC27382858306C4DDC149661245F19CAC304C002479EBA3FBE8203B10F8EB866F84C4BA964C33BE17DEB9A3F70D0BEBB6D69931B7A5C8D7F4F453D4B7583D6648A2D9CCCF3BA555790EB3BD1367456382700517316272745263777343070578043772431812488504440335421634222648265848838121837353786020831856580712415333215302208147066378168632077260742828733501307547176277560372528436054511866171224212737853618516810286575524353052360560431827317050484274631523727443076623201205630176106647063024526654105775786876227221382811315183175187688715152251718801634644008352335346173270831466732388742751781744268285136885233676618075730644567376260056046801283118368127378730400864858860423178431432174024128156430042136886878305255512578456815567452271245453668030586055385062026711530033343383475108202713263083330656287828016636402607650813442327778368023726478448081481213123878572853738681808620411477010631062247480543800734826263723435866084563460834818022430110577037880375342662814256421633255877085434152814408536434148614146707002044162035858310133662324605536663662033473105060631775853077483602002225412581468165821865661211467268147103283132171232547477287443230241240757844153615762424741301722062267472747003826503885544682608118155735313865325848302455485634756018273820137345741727418745261488050677330138546833853508746107616788711375147727451830073522165114147383877083481400123163777662262788355285502510077451133068444362310516824714022346257785811584806148226560441060227752554564772478727583156451406704238688634583166663607688238257518812813555154445780176360300350404665741672685880004215010272888675646851148358423071453520360300388050250721351241676211305457044364015801141683044422561272606177463587455738363783408862388284722643833723114756406862376370330214001874826214622708084084002025636767831375160242480502832474732411157747428683178362313332364104274857216211278653233102730780172388640555127240368788380054832243460744682438112304407528808054840554628757808453602377264441116235321564084234171882453426885776378241812475187760357460162405285166613408735655768736813085162678146372876548208588416884845602213600238752455130070756438507443718730864058241676520223100778537466617861873171267335652236024385153037355153660707083178885813007345133271161552764051576616612614573437834476747524844652344312488386640172186252053064230424402062806207278026457241843213823223578630525753080343552186870662772512780561337726815780880748104546146704251635867710255085600275752004733518051655028507656643504277361001831655542464863821714055377458781574581878347750535822404730758788652635060486802627610003565431211741182688234752636126335334361107773262121051470658880873527267780287051622324420455244182713745723520882604160088777146578781102532430655862124224627601834385720032400151863686860466774444313130150443305816566373132477054681352205101436236160183731116027810540738716405756418031728372050026377227020873522458211520648153707830512024387354646073575114450322344315407165806830058732AE7BFDD687A48F0383438F5D34FA545227619047718BB592AAA4511C13CB8B554321352A460C2EFF5C24A42C8A397E0BFF652AF19AE7C99F1EACDA43AB86B4F77A6ADE00B473C7F268E999E76BF3B5355B2309CD95776C48D7E25EFE74BB83173C3B81BEBCB724E1315EEBE3D5DD2BCC834E74E411ABA98F9F0323AB583B41E42ACE6205B48BAD7CF266F639DD2C82208AF0EA64FF0C1EE76E13309140A42B755C21B8AEFB23C4FC79AED0B81DBB4031886982D1D9D218E6AA8C547D117B8B2C477318268AF238687527D4E30D7414E10922F58D7C71ABA68ADDC54F34DF14F7A405CAD7E407DC42113EC1B4161FFAC3CE571C1828B287D55A0FCAFC14C2CF1A0645DC8116B55E34BD9CA049CDB60C27D914D676D0869D33E0DDBDBEB7F31DDF7BEEB59AC7D6A62F7F42DCDAC5C0B20D1E7BB4DB4589E21089E541766C4BDCCCA807C3825AF0EE7AACC7390F7A8B689A825F9AAEC2F644E24920E95FBFB117866D67387C0A46A730423A80CEFAC3D164A3AF5EE17D84FF2E7B783D1AC74362D483EDB69EDDA4365CEC01271172A08BA2C88FE98D47F52684CD7351ABE2958AF5D3EF796AEA4A5B5EDFBC9BF3081E4DADB42BCEE2A6477B7C599BB40051532EC96D0FFA2930BCF1D6B077F619C4247FF89842BE8B3D72E62C0A1B6702ABCA1C1656F2BA66EF804207EE0DE06E1E4299198ECDA8E5A96A245EE9B717D5A79F5478AE5B5BCCF8B8D3629EBCA8258A2F00D88A12A34FD0B0AA5EAD5A74783617E9109C8596F605DF1038702966175AD2367B5B9B1AD40B4D49ADD943FFFC22717BB13AFEBB8CBEB3A7B769A5BBEE0891E03916507A0FF8297C4A91F73A9D03774BD41ECA62701B0A1D15A20CD5B4E9C156A004047A0D1E57F593E6C5C3DE54FFB17A60912AF5A5659339CF9D6969D3AD72EFFCC3160D8B4039DD6143D8C77F0EDB668E44991E2819FB01935BA4DFB5D48E1D8601C8D4D8A17F7A6007C92D95565369A88E1E1CCF781766CE012605607A7F75030E3829CA5F0774BA2F5F57C62FFB9A7522FC152F64C4862CC0C9E49A10B0013F19205E3DE1BFFB88CD76228B101180429B2CD679872E53C573BAACE27610F291FA2C021B0E5D1814A23ED34BD3190E3F6A2B6CCFFEF42EE2F0B5C669B6D23E7BC699D8E785A8436A852D6E8503C8165C27362F246BC26546D5CDEBD5E5C9C268ADA0A3ABAE1D7CD250BFC59CBA4B500D9118356AB49316D7C24AF1E1673E4970834132C5134F2F1B59C45ADD894935211F8026C714B0DD6B2C2DB08D3FFA5A347A3206BFA8D9F8F49A332912FA4DDA18B1301D004BBD6DFAB19DA9FB4F851E6622F99F62FD6008DAD1C03353B619646CC869A8396914D7B7D0065CC4A3539CCB833CCD62507DEAAE15A3A49D1ED997E53A86EBCF08C64FA9F724CDFA0F4D24DC8890F77793DC962BCC4EC48E1C2DB60C88CBB23E5E9D046AEF98341EBD2D30260CE8B318894C1E276EB7849FD777271B6471E716642DF70BDEAB121B03CBF901A171127E448F7E34C161D015BC661063156B702A5B08FE53A1899DC650C37ABB75F8BC4F0E2F03E84D6A7A2E882DE68BB78022F771EC6433D540912358E185AF67DBFC36713707B4DC0FDD6FD2EC615BEC33BE08C8C9E9E436BEB31FFF5EACA3F2661E64A0AB24D0D8B80271C5C658F5D224F98DA322FC68A21D3E547F0F4EC78566C172BE2683993EE8AE09920A412B04905D54AEDB5D92CB257E113AB3D4C4C1CD47DADDC09A00417D2E4A9923E5BD8EDAF73E4B89831ECDA7BF8299AA149383082CF1B0AE388063E115836AD8B1DFB9E6A1C9D254F02DB05D5099D6994EA253605DACC9A5AB52324324AB3B645CEC06C6F57514D2D03A4DB3474EF58EB37C86D27D2598DC58CFD2371A18D0D5EF241F1E5F5B100FEDC33B5677CED61B3DD091C5AA1252B1E681CBFC124CBBDBF5CAA841235296009AA08CD067EEFB12E403027DB735AC59231D6E1C068D180ACA2F3C8BC0D2ED552BC4F0AC5B5A401F52C7D66BA6D7E50EA96E66CFBFAE392840870720D14A4698E05E741605BFBE7EECD1B03657A10B180E253D23AA6750F1EAA6328F40A6864A30D2082C8CBB4AD86113C205CFCFBB93BB80108D63BF2CF7432EB1632D37441A92FB5953813CD740715C2D14EBB2B6D569CECD0AA2F3D4D681AF6EB9CCDFCA85E72A3B8DCAD00960154D350FAD1046F4A1C3893B0AD1B261BF669650C62A0EC134DA899B0136CABBCEFB31D9DF32D51B929148836200F9D51AE7EFCCB7C113B2DC8891F0593A464CC9906DCD18436366DEE53E87BE3153A241742FDF35EAEF168961400E150246DA42F8BF9804DEBFD51DEB5B4FE1681E44FFF181CE44D71A6204BFAD321B3ECFDDABC3DEE87D2C33C7AA2AD6B9C78E034A1E19F255400FC032AB7AFA02A002B9603EF7CA090117108183C49D5436FFBC7B471754915F5D9CC154FBAE4A9A9F0928A50C06020181DA8ADFCF371EF51903ACD6FD56EDFE624FEE35A63BDE5CBCA7DC3308176E599E3B95D7F137E9DE519B417661AF3DF7568FD76A1D34A8EB21038A23B9C62E5E46DA52DEC95EBF680CF8BE166CB674D65682BEE3FE368F082DC4F368738F83E2D333EA1DEE7B2A6F815403897F5AD6C1E710BD46EEFD5D743B79EDF135B0451A18FD60070278D852C302D0D026C2F2BEDE0EBB9D016F9B817D90914F1E3F875259B80D1DF60C28AC231155377D3A2341C4AC4A871857263B0C2DA6FAD157DB9F85CE3ABCD6F769F46249BAB9753339B2076C23549A68F5F29F8A74BA874DA2806D7E4EC1F61BCA6E11C2E15EA64E8728D9B9ED08246A31DF3087F8394A9D925551F4601AC957DA056FAD48919B10951E5CE56217B11C6DC89C25F2DD06095A820BF63E4B53CF80EA8C836062822A59BD726A19BE405854E232BC0D6DF7F9315793B89E9E10D00E9C48698328B170B9A7F95B2ED96CF0CE99E0D1F18D1C73E6545C8E9F717F722A07286025AC8DBD6C2567E21DB5968BB4D7F33A49079B2D4C3956508E58D812F687A7E4FF07065BA76846E70FB42733C56D948559E50CBAA00E1503D1EF447117994EB8FF0BCACA06F91FF312351632CD6755D0703A7E3B0DA03C37B98159078DC9B8F4CF17659B0773F0501E2BF177F882FD017FE74CF9C34A6F013D44C7D2986E9CD29D444B98E26584942747EAA79949EF3C6724A218DA9D820E68C62B64293EB1468E5CEF3A9BA007D5345EE1E5251E7075B84EE3B060B1E9AF2843AE46B4681753322D7906A6E849368EBE27A3C98F9BA0FC74D3CB472D511A78B50BACA9850C4E59620B35318B8978F697D79439E2E2A30BC41C67F41BFAFC6B9F8D8C2D8FFE8EBDC3910EAD15F01CD2B1A9571C02AE0FA9189A50CAF1D6864AF684FF0C9F05E0E8830A49BFA0872C92EA8F6D9445258EDB6FDCB437601B4EFA9CBE3AC1390995FE8BDC1D54073B16DF60018E904F2D23E029CEC4A4DE94A356CB99A44F2F314B9030683CA19AB7402701E8C4225BD284BA1166C3B181701F9A47B6C999D69AA5AB0", + "message": "320D1B2976A4A4673900C7B75B23EDBC25B9AE867FBB79B55B29B3780EAE8C159A3AFAA47CF1D9E452CAA8EDDA3304BBAC47EFDCF96CE92DB1981A5088F731E1EDA1EA5FDE9A031595A8F268E92B4D75793C6F408F79B78599D93E80066F8C4432911828A87EF71C877F55B1F18207F01820C0153B647205CA93DDD6B78B94EB59E3EAF01B66953951ABA4027F811877B0F60C9A5AE6281D82348E3EB749C82C81D53309F9B7E624BB1BFC6382F43A58D1951F7FB716C08DEDE4A8028B50544D0F26F7B9DAEA0CD075C3B11B7315022A37198F0C96D752798E0EF406875CE86C367079841F717261A2B6570A8F4F9BE1EA305E73BC8BBD88AB162B4D4BAE86CCCD406A0FF6ED5A968D4C985460FD8FBA5B3FB40E29B6ACA07F70717A0700AD3A0BB7081E09F7219F3F8829692C3DF91C90334DF9E89284D65F7406188C9A1EB7B5C491591A20EDA9399DA1AE8C0C158588FE1426B763FE9D11223FF7A05A3DE036B67541C2811AA459045CE73096F89E6BA672CA7A546D2B0554DB35C547AD9585D14485AA812BFBC88F7B248E03F2EC57043F4DEFC2B27A3B20C2EE7CE334D428EAEB228350A3ABF4628C2DCFA84BC7435818F91CD67F70F3C7D54E2C205E55BC4ACCDACB354470FD5C246F32A542106EEE0EDB38F01FF5C4B657C7C1A00718D2BFD311B8BAB6523351E93CCB44274B8F96EE343830148F5C8594818777C1E798EFB45AF1D2A75D22470B4D7F7C7A5938DF3F8288A0088719C4E36018D9993F9E69B8469E5F2ACF1977D441B82E5340E5AD5B21B66051513553BA1BA1C1D5F788C47CD3BC60079300F6E3D9F13EDAD4DF8521EDD022031A3D74A6A5F32AC6FC51C67F920233C5079A2B44BA7B8EC6DCF9AD4667BD26BD07567E078267A1BF44B15E68B71AD38226EDDF138D2A599944F70D47B26F775BB97D9966845AB3E6AEB96E1414D3BDE94160B6DF19E03BA1BD0361354E5078B3C5733B740314E2DCCCF8F4C9CB179DA62D5C982B223CCEF5F29D7B673680DFA2823A2BB279EA45D98CD91BE7D52E3E386B98B62DF3FAEDF025B55F49EE6FB5E8DFC9F70A4F093EE3898B25102CF3AA52E669D6EC69BF6C79457BBBB7CECF65B1E948DA808025A242841FEC6073326BE16C2D1953209F31BA4A772FF24BC30376EB994398D4177FFFBCF78C9A79B7F1746D077AD146514A2DE0AF9800255F3A11BA661765A7D8E8E7FE5FA46BCD1269E278555186D4BDDD03FEEB70BDFF7E5F616259ACE39969CABE8D4F8F23544918516C977F84C09D6A6749B1CE719676378E82F9B4E563D67AF7D911233F2527B5CC5D0733360CE15A173F10B91360A3CFB08EB44A09157559A0CE8B661AB4A97803C52F156627C642CD02CA5BBC7648833F2CD7E99D2A7AFB736E5AFC4FAE5DE19ACD2F5CE3E3FC887852758411E8C7FBCADB1578964445332113F963AF3E944286DC448471125E55A46D2DE35E9C0F6DD10A3BE4F1E4BDDE51A16F4239A1F6A535D3202055990606C0065C542297D490553204A6E3CA16A7FC9A1D77191E5C01C1507A332C659FD6B11FAE088BBA796F18886195A2B8F5B0064D85F56FB7256F0FE70E9C06ED18B7C8A75ED97A1DF482908D2E3E8D6BE8D0EC8020451C687D10F829257F3D09FC47C7EF008B89E2312792A25EEDC71E9835674CA50235E0A6C832E7BBAB458725EE7BF65D26A0501C91835625C330B0F8B4D46A0762F7773D2415A0DCA573B47EB8658F9EBFD26D9F6EAE9D7A7304BC690F8D2F60C33F8A7D19B52F9340BFCB2FFDC92A7F9ABF85E3352E46ED7591F354A9E19B70A3B247E3E4295E45B6A2CEB59B120B6758654BAAFED2120B226FA778FAE5350E756741093083E4E56A84B64739695C1C09EE39DEEF11D7E5BB7866C90FC9C96CEA071FF82F145592443BBCD6B7CE848839B641C4522016945F711E86152820275A6E16BDF296D34AB38CFF06A63756DAFF7BF230F024DA00C4128F025F091F4341620E0EA883042BE731E82D21DBA6EE737D90346B6189697CBF41F7C2BA7C9CBA20E14D26CA578FB05E92798D57C0060951BDDCA5D96322AF35D80013B48A79AB7684E1E1B040315A350DCF84389E54C054AC4C3428123E01C2FD66FBB2C5BE2D16B22BAB805AB59DF205B71764E4AC9BD4B2D872B8905DA230623C65DD235FEC253468E53928722D1F04C486B46E63FE63441F11B1E3617E9765D4F388D4A2B68B6C86C8E20FE0F3C48A561A0FF5070455C43A7FDAEB58ACFD4BF51A1C37B7751ED37BBC73B9C29DC4FAFD0A8F5FC98C7FF02B404AC08A0728FA82A5ADA4EDC195E679D88187F58004844065F281A67FF0A2BE0AF94D5C97ACFD43683AC721045FEF8C36DEBA2E3EFA248DA65837046B62BD6CCEA84CB1211C5893B0C5F0A5922A989CF7ED093D5D706657AA6E79EF3FAD0959DF594B9CFBE779", + "signature": "84D8CFC8120CB598A6A1CED91FEAD8FFC224C59781A421E85F7A3309F74877B526A3A2576A41A17D71229A5864953B5591878A53BA64C10E88A4F77811D5641E03E445B7BC3AAD9526EC4ED3604A371D1170618F672520C76B18148D3895386C1B9ED1746E0977C32DA44425B4737668BAB427F516B4552F5F11EC62A824FFF1EE50F0F03E01E7412CDE699F8A135D9845C7F1C4D33B806527574920AF2381C4AFA8F7E0673D1D76F6D03BBB5C3BC027ADC84B7D34DFB4DAF2D9BAAA9AAD4D443B195F350DD83A96CA96DCFD2673AF4B3425FEF1928085FAFC728DAB0374CCB14FA411A5FA2F77308BD43D44DF732E0984F7076CCDF6C2C42D0876166CC47050983FEF8800160933B87733C0B766F013947382A3593DE93F604A9A5DDA9BA4EF09954EFC9A8E6C0D90454B7F5C79140206204091D82923054A5D7BC76BA2D8BB3B17A7BCD027209965E125CC8DA21C4EBDBB4E84C342735F4C15705261CD9055FB4FA98309B45C91B92DBE2872D6F95B83243F6F92533C8E52EDB05147AD030A7ED059A3D6E6645EACFFBE84387C88AF178EBBA7ACE86F8BED1F18C04B1DB3F81721CB005D92DAD11E3D03418D3319CFDC4FC31E41917D3B34B3ACC7DB8E4B1D77884F97AAE2D71B202623F95308609A890942936E0740F53A48D036CF3991047F98CAC74E8B753779AA1EC926CF23886E0F7088EC0F1FB6B0D3F8FE587BF56B00116E84FC8D50D663B542B096186CCDEE2C04CFEC253EB84CAA2CFCE5104B667EAA7ACC31FB1D91C16DABF1A5D60704F46AC26B2E6EE4F93817824714D472FDB8407B32622562757F2F845731F5525FDD975472829D1D98C47B8B2A74BA72756B807A0DF17F4095508D4944F4F5CA1447B056E952B0A49AC3FBEDEDB06967A27E452966A6EC426EBE72BCE9D73FEF60C2B7BE7427DA1890A56F2D88F744DCE406BBDFE360D7C08F71016D2A84607F655A862C0C9020550E1FB87C45B85FC1501EF062DBEC20A7256904F9D5309191536A8814E4DBCCA28C40F34897A49A98AFB645F3EF246E2CDF4DF43070E8E61377B6D70B146F955A4EFCC98BAEBC3F1C621810D796D7B1BA0E9A441E56DCCA92AF85CA2834AE49207ED3B36E10178A7DA4921AD35DCFE3C4FA522D138E015D2447A3DCD35A25772C3B1439C871745844E05D5A266AC1C7253935FC43B6EE1DA7988C0D1BCB775ACCD20DACF4CBAA0671171337BB71E7D95A625F1BB66E3298BD5B8130BACE336B34C3756F62A0932FACA9AC3BAECE59D77D79F85AC4582E527D3AD47D230B1AF26833EDF2968DE208553B3167D7185CF60B4B4C08A0587496B56D9133BBF3513C20EB29A334290C46FB8C4461E81DCAA82D2413F8522DD889A4189306AE720736C875EB797E794839DE3619DCB6AD8A548CE43EF71AA16559350CDDE6218D044A059A8BB4D9826503539306469BE45FDAF3917B0A3A6450DD11BE8EF9F59DB8BFF8A337155A63CD20910EF598B208C14A2774D2FC55301F9CD3C8FB73DC5C1D30CB072D7E098B92D6ACE1BA78B3A10168CA4E8C1D44D95052AB5C1A7439A99D98C50A924ECEEECABD1437E4DEA5E7BB83AA5A3FDE2C98E019749EE0AFCA2681EC2C799C69F581859B28D2D346EF2FB97102A69F030B6F53F21FD655EC0F5CB34B3D363586148C443167C6CA47DE98835DBA80A092B9410B26BD023DA9E053981898215FFA735599AD0DEE853D374D6BCF0A0171FA56459C4536A7D2FF8DE6EA0C362C157D594101F9A860B800E5307DA8411E0E1468BF025092CBD1C607D9780CA3DCF070F5D949BFDE60E0BCF8267AFB9E04D5C2CC339CDCB1876C818CFE60F89F78681A8E82D36F26FE6260AE1A9E74355C0049C84C39A0333C01E77D1AE8E87F6BC96B0EF90B825188F784859F5390989C212E5CC5B829FA184E5BCA76B0B402195F4EC532931C788416811A029F492CF5B2D633F06ACD8104155D947E88AC08CAE86DF2F64F79E3AF8C82B9FF3834875DF69F1D381971003E0771F64FB343FFAE807C9C0D4A0273EFC11AF203EADE2D9F2682C918E2662EF2D6AE1B6E8A397B3FB62130BD629E315C59D1F0EADCA1BAC8CB6F067F10F6B13D70F70C3881E8382F20026746C6175F14A2331FAD83ABF256734FF7A970495B1F6B5B1CB2505B621D406B944BB5CDCE22BD9E88FBFD41F8B49C794B0022A456493D411B1B8F59D6A52E7B9CA786814F215C39F0A4D53285FA10097C151293054632C326E210110CE3CD03B7432CE2B1133FDEAC806CAEFB45A37CFC12F98AD0BF76ACE2C347ABA12A77D5DFDF6658C2228304FCD265653894C6696AB17E8103A8E23C397DB684BF632FAFEBE420B3EC111C08BE7DF73A7F763A82F01B120D326A98E92EE34144CB6C7ED15472F2C860D25A6739D925734C2CB6EE02198E96DA851860489A5F9C056C5AA2B5A90D31E7E115F32EB8285339D96124D3830F60E2E91715BA1C12856C1E25B8C59AFBE7B446F43F1B4154F8F786935E5402DC55E7BCAAE8ABADE43435DBD01F78BB882418BE11FF1893D54B5A83D6220F4E86D7CAF49E1B2EDFD6CEB82DCAD8A982BACD2DB15A66E7D0FB4652A920C339DA25B19D37715ECCF886D900D785E5E77E9AF53589DC5E785B2D5279AAE870F86E4701125FC316EFEC0D5CBC411D5ADAC374124521469ECD10832AA4257E2D8906358BF2788654DEB5D9E70798571B965376250C33706E78441465CC2563A9D2F70DA579FF7C4C715296F72562DFD9951120AEBD94D4F08212647F08B4871B6C4E31CB869A8CE1301DF60F88A517356E56189D61ED484C32718A9D37B6BD1FAB1FA39AA1147735BABEFD166712AAA617516D8CE2A984D90C73565ABF5DB9A46346FBE7AC465C81934F5D92735D30594C71AE239B2FF5C2DB72920E7A59B487DB9E363C594E34D9F250D7FA3E8DF4F8A07FEABF07D7BE68D6E03333B6947B1EC087F16C1DE3B0C5596043D4DD62770605DD89F11360A10F2320170084EFE8DA7E10E128D0E90D25623324F8B32839A96690CB33F6FF05E584C860251AA02CE00825B9F775F24E75AA788F98FA5BB7400E31362534EF1E8D310FDC0272F4E84C820E799007AA5351717BE6B06711BF9DED0CC7F96A0AFF9DC4BAF7F1F2D19BED2F24A7DD8DD1A171649F19B134C0F27CC458AEB79274DC155A9E3A267E200EBD328C16AC4892EEDC748BF522C0964E003793C0A6283528CD09456476677FB152B6DD0EBD86A410231191D86A0C4C19027F79F4615C665A75E7350CBA43D5A43A609F9C4155B7D2991250A6AA4912532B2081AE7ED0E72CA8982A5E16FAF25D622E060FF7C7639A1401B39BBADDEF2D1BC3E600ADE38A5540015C6D99769175DA7948C1636FF28B8D739E65B0E3DD43D5F25853309CF5DA4722DB29184EDC0294BB966D023093BBB10FE6A9A17F8A37608FD3FEB1878C02068BFE295FB809DBA10046D57C50D1A5515A3F4099F98F8262DA6DA7E64C0A2B662DE9F58C7F0CBF6B95AFBF75708F3B70A73A7D30EEC7B2C897ED420275B1D3DA2B0D94D689E21166E3B42B942DA7566966C9C78BFA7C64A7D0CC3CE47213B2C1D3D0E75EE00AB186CEBF88BE2C1C042253F48E2642DF054EBECCD82A02DACF3CA849335AE09789A705D23C1B49ABA88BB60ECC05F70BF02B067470802447159456D4DBC7451E41D034306F3A40AA9280C63DC86D5ABE401B64B48293B49C3A4119A966F652CD00B32342CF603A3D02E8F829E97ABA53B035C3C72D2EAF8F9DBFBB83D61B5E13F721C719B3D6E963E68CD0A6FB792DEABFD08ED01ED50A407B4C3EA558BAD59A9EB0CF8D5501A75A11053DE46D2899323B2AEF99A6308D64ACDD681A256DEF931C7E5F488D8878950F0637D478BD665B9C8AD85816E3B8F9C586034E1DD2381BB2F8130CCAABEC2F43D455F5150F83F160F9E43DDD4247424ED273F31F07EA12099B0E5FC35998A6811C8CD1825F8A1687AF77836165DE0BA2438275DE291B65C90DA0CD5880F95C8C8CC0F256FD0B1A9F9209C659A031AACC5D0FE8B0DF5A4E9D9EFEF76ED7624E9ABD6361F0772ABE1CBD5F78FE6F872CE769A817F4F3195E65CCBC3FB2F9BA021023585EB4F43F471EF4307AF047142D79BDADC744EEAB4CFCF8FDC682462985F828A5CB69483076EF94D6C6634000BAC9B75529594261E3893F832DA297FA448EEB8D098166732671773CE215F777ED8B16C6511D47216BA200CB3082540D6323F9726BC4CBDC1A89D9698A49EFFC5B3928461746597F24991A5212547888DF1AA6F6BE3D1AB887190F3EECC6DC4E9B0B4E4672CED38B5DDBD3C00DF9461FD62637B3D7FCD361C41EEC7641024382C378F15BA8A14C1BE3E47C4301624C354EF8D10CD26E354385B7C477F355FFB8998E9AB2E2C0C2FB2E3E466A1971ADD49B31C6A6F1E9C0ED9348A337D995A08C65C1E58C950558A4139D3274872FEDACBBBF77B4EE9D2C54F9A6142AC8A2058C2EAD0606BB37A6B141CFD97C9780DDA16D54A5ECD9EAFC53576A00CCF909F3484B64E37AD1F63334F39B94EF033B647B68E1FBF3A0BFED69FD8877FC22C048D4C15A8282FC2B602D3B1021CA6B9A7E844B065C62B0CBD7FE328F9FB5DC23BCF50A11558290A8B5C1F642586C7A859194A0A7C2FDFE0F4352555C60637A86A6B1D800000000000000070C0F182430" + }, + { + "tcId": 25, + "deferred": false, + "sk": "05F78DFB8DD95ECCB19A4E223909896CC6A32086977EF3ED299269E51878BE84D29086725EBC30BAACD7C10F04AC9B3037B7407C63D36864E577A8FFBE89D9174A2ACC4183D106E7F478109F5ECC2160C0583253D7287E39F2BE1E1FF6DBC0127A322CA8E2BD20BA4419405CD8950831BAE2E4F854DCE2828025369A1FB3F07E77878741641453852638027541273502161744187110423466885282676035866631880680212377455761475822537381311428256306028053075841275812862151082114225553333632208035118820600216464008332253350051356421018671288648082042327826524064231463461787457445340458144872151441075521254341210228484201564136088803605035560122810660262424606074018703052055371555875382226471026530180032600112827753232300073074181386480534164225448647716638448527736082708564276203618062484286666008357240756656266712700838805173838263510506272540177577752234807311255185168734122463815356405123855254518275503443802574060346470206813526234734131654288881363708638820352751020216175724418860014818114623484543247618186431467841145500584206376100245427354377078068051005766127458621211151260165633001348137530712602370312371232020175626206103837672301778747622163741706566121434014071278363537881306583436007681866270754208381518840617617808075330388482526180736260681245127862565373032388826478887465858427858051220613172202211345601088467637001415045874412557332067277484377551504066843600063121066341371643283786784761068601064575354243720165161606071462467454388636873636233778021648671534367133507427605374074416722337133601751734478484212371667138687221813155227282016661347012087060844717657163652206587018728132833730304737025362757761315052144646422630627111723456313173844406042412780701303413724368817117576255854668574228750452553070204351788025621430144242371001323737372064343217801782040275037004610781844438384742255584167536370662184616027251211143638677564508151383860530708048252122840866600333828445206788217648545821445206684478670700853248527254603327501006210154518503008755220176074648684464420077608424316613061505360032376774670110586687775170411382701487278646233746321110574082140788743715263036142246810378474651821327267878687767558532332766770770556676145510857677602768584841218228625328357130763700187376638323351202458842267224561707545685515711742787471041306204421583620103716561184185104727138066730485156405743817162476012062163020146660802807525251031404783027088628746507335166655450455814243664167181412115564530746315868643783184442146216216845873256853767015455878677678280687482518218081546136488640838635431565180552472320787367186616811775854673275284425445068256835580334212418571666556783641407770327517431140237301214478304666154718470055040784840142143820856651337364886780162504570540561687240205801871073843068104004486611083157177770070276412274284501525030180108545680011733761885871352405735268564864488888408546532680830132441854774703851551130551311212088487888340480334438028463403314317118862855268314010187431362037387131230675578024177157366237440614241826465088416751852758868580542326571477612173575680005143247771436458011248538443205703184858134812623530080474087351382103253482864316815ED9377443018FCEB94C82DAFD2C91A64AA5FA118DFEF2C915FB5C1C06E09A9915755FDE25B00C2D6A8382A8F9BD031F4F9CB0CD25CC035F5D38EDFF23E27941C7F38A6E958A5D7569D234DBD2A94B296446F553CA82466AE1F49CE4863D68462FE22DD7CA41E3B5223878FA372DAB34237763BCC0B9BEAED3FD27AF301D4BF779178571DDC3EFCA493D98DC24DFE77536701B08DBB76E3759B237EA3A0F9496E8C7587288EF7192DEC95A60FC480B9E1F533592962DA075833478222BE8B378E63506364B78ACE0D27A5017D15D58C018EC843375A5B07887FD25E1C30C0075F944A9762E59C94359728B04C38E9997448263150BA6E69FE461EC1AEB5FA47AEAD3AE1848CA696060462D29F331C02F80D22D8E3BA79E63924D2D4D3BD901BD79076852FC0B02FBF48BE9F772FC3332BA583228E55EBE8EDA94884CCDF80D17654E27FECDD237C0EE61E8DD35B1CCE3C388DE759B1FB7C3D143A153DBC41D2FD2E9D0F754273C21C19F5F13A63A7DFC479FD64D5F5FD008DEF079292629032111D2B16AD8D61566A73DCF219397939669A3B219F648DF45D541E47FA70833A785045B71A606DD4DE82902DB7C1899D44FE0D2413F886374FD1C19EAC8132F37A3AD31F8BC6F9582D58A494DEE3372DBE3C32E10B18B787D8E4D3B6E9679EC94CA86BFC2B23B9B4F92C1BADB21D5E5A58A9ED0FAAC419B51C1993983B5A7F6694FBFD5F1AF15A10057C6AC46E7034072A1A5D26D63B67ADBD3771B7E78DE3BFB9F6D5CE594B285991BA243BA22B3B54453E6F5413A2CA1D9AE75FC1FEF7E31A7A3B7CB087CBCF3F08FC9C34B1670E7F6D5C32F165D3796D1C369E7C50E9A122C116A8279997B0578625912829142D95C43DEA2165E0D3F9313592C8982FC1E107052DE326109433DCFC45A1BF14846D1F8F146D154CD5AAF417449788DD7E6D470E7C70C7DF7D8A1B62A503B1D4188AAA5C32BEA44C9D849D3F8B5C91D1BF97F47D83DC0D063639F79B9F08DB24A13A06C1ECDBCF73CDAF7510CABA36B890BBF7DC241AFAF317C24026A6F6CDC8426D99C0F90A2F1944B797DD68B792AF00B15D0C78F8528F0E055FF01E73E455BD5162389E0FF178312AF5DABCBFCB28AA2C0091862A010484C0930E7D9B6D703399D40B4D83C996E4CC415525CC895EB460EADBEAA104D6251FADABAD74DCE9FBBEC08F9D0899BECB3D6FCD573FA9FB94D9D18C59C724F39F0157AD6C8C01449DD56F37110F68BCDE8C3F66CAAE7968A2FEF4B0B20A7CF41AD9D40266EAEAA0C21951ADB946B78A3ADF6E81AF6DA0ED92749B119936AC4C7B798DFAE058A5F509D90ECC08EDDC2ED7234D3BF28ACBC7235AA971E4A3744AC9D47221EF2730A18A5411C85B6AC8DFB2396AE770A5D1D960D7EDD4CA6D0F9FFF6AB257B22FD5DBB3835D05D060369F01C65E58E2C143AA4FAAA554928531B9BE2D0E2B6D9F0D32AD9C9A12DF38F72A21D2906AB17AA5934F08EF87B42E40E46DC1C35DCE85B0501F256DC439C2B3A332E37F3A4E400304A6ADDB09153A7FF7EB8760AF870C252EB258EB658512BD8EF92A89FCBB50CF6F76BEBC46C97AC9DDBAA7450CAB49B4190A8B39767F36597F89027EB3C09DDCFAFDAB286863890EF528EDD073AEABD6A7C9C3D04EBD1A3CA3197249E7DADC74CE737CA5CB5A3C010FDE6267AE82BF9B8AC6210EBDB68BC5597E10D98F6B5DEA2777512710C58694785F544E4D886CD8CBC8E6875BB61DA19BC7FCCD76547C4ED44A935FEDCA88155AC0E428EE506B1BDAB6F00063EC1EB0D3D91B6D9EDFB85E8F90C42D9B058EE1FE208A54A5A14E4983E9C06A7F549647EB8EEE92B3C9A0B54912DA9185C7AC272C2DD4615C07140772CCA6CC3044FC59F7271259491BC9469BC1DD07868D6463740387DFA7D2ADD1346D6BDA59435B84F6AFEB3BEF20B007F8CBAB2DF46BD171362B7F7AD541A645EE4E62A520324617DD097622EADD7DA6939812673AB6D8E5A25FCF00EDB519ED4877B13EB0E57E9AEFC8B63F22C0816E70CBCE0383D689706FDB45EFB6474A7F194D6603B745F4D85577F79387733EB0975D783D7DD3864BC89111E1273D6CF9122B43EDF7F6757E2CBCB6C8AA3C9923E3E6870F9FA92AC02DB2B52491A1EDABC9600CDD515C665DC88889762A2012332035055C896145EA883A5D4EC485BB24B1F659804B8F10FAFB1B4C619742EF4BC5EB665C48BE5F5C5093ABF4E9E6E43D8E4D7E15F7D38DA74B567E4017FDF540BCB9492CD35C2A3ACE4CE579282837A8B55ADA428C1D190BC77764A4E44369BF90F24CA2CF566F7394978F28E24689323FB8C5B2D688578A9E5A34305D0EFB970490CB172D6FE786F5565CE921D92A2573C302DC9CD0431F8ACC8E0F1A44B586257080347F933387385429199F4A53851076447C6D2114CAFDFDD13C92D8C300F26CFEBAE984D7A021E9B462D30D19618AA72C58FAFA0FF74CA67699992B502BA0EDA7C6CD2FECCE6B51D6C704308ADB4B86F2ADF28FC43F03807C5B7391B3163FDB66C6EB76A78799682BE26C536059BC179E8F89D87469A57899C1E18E03F16DD6B5AEF7420990DF22CF4D3E905E1B5B1027DAF56DBAC8E9E3A54BAFB28A8FA5A51CCCC0872AB53884563C0B7876F68A48F1F51B1AA350C93A23FAE59B6BE2F8088F58FB9FDD432C10FEB6C79F9422F0AC6DA4F8288A23D16546715EB6104CB0499E5FEB2225C97287C19BEF3279B3871D6AD522B30DD96BDFE4BACD75CB108BD622605FBC0BC6F2212D76D8B50E22F98E34B6C53F53AD9E48F11FCB77769537756D20BFFD1D775B42625E6E7C4EF65D7FB3EC718B5FC0094273B29487759E8010FC317CB0F9AF34836426A4BD2B79A3F48E0F38447D96DF0FCC545FB51DDD3C6B849FF33BE3F9A9EBDEE04B422B6E032E134B7772C6D3D4430C67BB2B1B0FED7C801F5A58F23E08E1735DB1AB32D66A66A7F60E2F98B811950CEAEF309D6A2476105E165A673A4F9F49A94FF751DDCAF839D58CA66A78FB5BBBDD80C5B87A6817D329E5747EB580A7B1670B3B7F52CB5FCD6AB51D48E7F0D91434F6ECD742DB8286C2134713E6FD638891DAFAE78DFB0550E76A8A54DBB1AD4434786084BF17BABE7711BC40943A6BE4D6F9886802A078B00937170AE765CB3F5F71BB792FE3F0DE18085C3F402079F491B14CF2DF6AAA588DDA39B69A5DD267C95465350B261064AAB109D1D8781B399F0E0885BF2C646452D54504BBF5D5322C6F4A3C25F4AD945EBF079CB58A84B9309C32EB6FC35E92F526179DAAAB3526382B8F02EE2AB9D102AEC8F250348228437DBDECBAC81776D4F4A0CB88E1F19CF6A10F48F72BACE1D21BB213014280B788D4760D8FA471F9C35A2509D3BD86C1F0E3E92A74417BBF01D1455B64DC6ACB49001442C55D1105874773ACEB0AC4839BFDB021E1B653BE09EED14DCB9216BE75F0E2B8E9BB3D2804864BB92A618926D568DE28952354A7CED0384A9D21203A68111929E0B0F34191162D722A01F8B55DEC3F9DDC9D0DFB3E", + "message": "C9ED9B897C34D7119115A0758332FE70D4A9E11FFB2D6A800AAE33F85FAC59E715AAD93BD79DC8D958079F3B5C2422F8FD1A1AF9406E8DA3297226440E30183051FC9AA52AFB8BEEA2228E88D193F231F2422977DDABE4AF4F0437628C6AFBE68F70CF4F56153A2691F7A4241EDCA760D4B3AE0A17A8A0214BF1BA65221DE64647AC6578F4C7E4A14C401F7DCC30A10A695A7F72B04393F4E9C4163AB68667B1757154BFE711BB54255F4DAA9D8AE6622C71EC8ACE5BB79C6B4C8AAF1B0A0099EBBD07B292CD7B55E44ECD68DFFF4173743145B71F536E7D23E78C63679FA2F3C72CAADEFD5A9471280CDD3DD8DB83F8AFF14FBEFDC8C5969B050D263EA462C28CA64362F7F165C3EF427FE5E90A83310DCB07C9612E9A0B8EA1D0631D84B4A7F1C7485B0C91C3B7BBB0EC98D353376B692BAAF24C5389D50250F3BBA82173DCDB52382176EC5CB8BD531DEA049C5B815D788491608FFA2AE8BF486849810AD89BF0352ED595E4EDBC0B81467D72944AB83C3CB2F90FCD10810EB65BDA18C43F9A9A5D98E714BE992B7DA02E9F7C389F1A22810DC0A473F8891C43932E0F6B5D3A21C3B611AF6C394AFC576C07572DC4A1E56B4576FE615E516F48544D099683EAA886CD41DA848567F70C2103C467D271919CC5935605C0EF05909635D431571E5A316E299E553EAAFE9C7CBF5063E2057D297F60B5DE1C17AF6B97192E840474CB7266A76D509A10FC7A71721D705A9DAAC5BAD8A52290C1D8DC7938663B24700F992FAB008CCB3801258245A0F5F329A4FE5553F4130DFB1D673338889B357FBF11681099FE9BFF18AEEBB31DAD290C1401D49CBBE38277AAC8A99C8BE4E6EDD8A0F3C901082A789A1037768AB7C3C704BF1C6E890D20B3DB6918C477350F4F25756BE1742DCB31705EA9DC975DE0C38C21D29B340C63438268F6CC399BD644EDCED36A7B50E8D65A507BEC51A31BD136525F4E7AFC1EF9E0E6325D032682EB4AFB7FB22F1716EC6F4C9852054429B5C5FAF3BC86213F6D800281913D5722F3A380307B59E1CC290EE66FB9699FFC627770B52619256C7B76D993FB4024D2DF0602F102A6A1257A200DE1F39DB54614FEC2B60F3728F59482D71C7E5BEC36F0D90D6FB0B4FA252E7FEC4F0FB9EF539257EFE87715ABEC75B2A5FCCBCFA5666F1C9BE2F0489E04E63ACBBB239EA8397FA2EC24C25C538BBBFEB74EB8E15FF93B0FEDB7F36FF67F7CB244CAA067EB2C005EDD2AC9E0765DD38E51E7C71AB72B056B230ECAA8985DCDB50439BA261A0DE57E68700C64655E1EB8608BCCC33480ECFFF1BB75D0AB69CEEA8F2E3E9515331A1EAAFB9BA32AF62798DF761267475DE343CFCF5A352C907A0314365B8CF6FD2E72F2142018C4BBCE4CF0A160266DE320EBBA359344A60D32CB135F5FF943173A3F9C7F4A68489E78621401425E5B8E6273309FA3313DCBF13D7C69B63C1EE34D3200BBB4CF57518A5E66D010984AAF34CA9B7DDC914A3AFB514FA1B9D3FCDF3324998D0D9058FEF10C30ED6B381C41DE363CB31C5107E7C00D4C0CCE485DBB4CD2092CD929E5717DB8CEE4790A48475E1DE9178E49B13C5173B6F301D5B7BFF1A9F8B3807A5FC84DCAFCCD8D585B77014EE285074E64448589A738F1323C7A865C3DD482499640A3F166F38E37C6F9ABA8263E4F3D1C2E7D7AFD16BB02B9B4BE8A055452071F278C32C3247DE2BF83A0633BABE7FA048BB18FDBA27022736615", + "signature": "2BF99640D1E8D1E76A3CFDE44072BB410AF19920F9FCA9F4EDCC534073063A5D196360CA825E70EF3574000607834DF6770604757CF5FB2E9F677530030988AE35E32C2AABA32FAB3E38B990CC1EDDE319E77E78A554161EF485FEFA16506826AFF3BBE5AF4A248A1ED0BE5049317E8148AD899E970A55191B2F31BEB20D0DFFFD774A5404026E95A04874429B59FE1FE29453AD21790F1F520657D657D175B8E4B8C497D2D271D904DAB7B93EE744B745BB50D310645FEBE6BA084686263F92A6550295822E84C3771010B4034602DAFE05447A858FB68A8B3F17B4539FE2A7839C7F2218888BB8FB8DFC54AAB71CC165B335C2F266984B1F402AC09F963016DCDF2FAB74E77D24B31CF35A36E2003228C0EDCD4E0639049C168E9A06D5646657D0580297C60F2F05318D039698482AE9F34501719251F82FE375D237D964221CD95CFADD4A3724A0C23DD3E860ACFC0637BA76159727F58E0220F31008E789E699C93593F2DBBEC88634AB2474B644699F90F56785F04044ED6FEBDFA8910A286919FE4A7B5AB253D578099152031E4EFC75094DCBDABCA8072443756B536E87B87114B354E4BA4452F540A9B197FAFA7C054085340F6358DFFE0FE4FA4C9ADDACF68C619A672E841117D1728EDEF147E797A9B3DEBD9D4469C71CBB684D134B18EF7ACBF66D52D2AB45CA47C7A1F7861E3EB59FE4CDA18A29C7C635E20CF68CF8C869A372866494C34F703E85B9F367E44D4AE42277BD8BF805DE61D988C848D6049DFF914B2CDCE4BA147127A9DEF6DD79BFEDAAC5AD4653C14D086A7CA154CED8860D12ECF86F351E558CB7C6542017E233005C1A7AF959D7E83CA03F3A07F1B9B7DCFE30D66D81B8D5C36C6BEB651D5A36E9330D2D585E36547F88A32241CF28014CC96A3E234ACDBA99ABB541FD370BFA65591EACE4D268D3EC17D86F4A37A359FB95CEC77A8BD4DEF36D23A46AA72906759A8F46D78CAC6D160F277E4C9E82F7BC3B48558E1607747D7BFBC8DE7E50BE365E62D003246F429E67340D1949C950957D7EEA52096B584192D935AB88E00F8AD54B0E1D7EABFACBE81E2C1282E9F5685F37A54EA44596516D9F5CC24AF26C88C91047E70A53CAB06A33D71B6E058ACF6FD7BB045FBA386F0E07BAC67A3EB256528680E4A0A31F91957FCE294C7EA84E7492CF8D265962164325A6536DC8AB542DED323FD2049930AFF783C466AFE9FE811716F6FE75ED28CAE3D768E7F73EE9C09547C40C3287ED5584AAB2BF801A3DA15CDB3D02A7267B131D22E6F1CCD23FBAD9D2446AB8B303E3B89D7331E8127E3BD909A6FFEDA8512057B86120D02F0AB0D8663AFF465451A4C8E29D8AAD0BEAF00B51C96C09A0568AFC3EB9C4FDB78E372669FDD78A296C6919602E4C9F60513E09F1F5D2BDC6D73AD9E48FB2A5DB13D6E935AE49DCFD455F017A41A0E70095A55DC012F15E94E438C266B081D25EA275FE2EDF7ED894779004063921AB3E84E44CD2638CF2EECA02BAB9978ECBD62D153FC4390A6F2117115508F355349603BF1DB25096D00C4E4B4296632F78C655BA6ABFFAA7B72292A1F71010D6743242E553D6326BB361364B44794164019ED114876FE166F331400EDBC665EA23AF4A178765731206A9F63950B3EB5B89922A565DFA8A23E47ACF14DA53D2AFAC6F5AA9FAA3DBE216E9AD2C07A32CC2A690B2CF1DE943000E87EB95D906C9E52FC103574C5C50548BD9EB8DEA4A0CD0BC3153A2193E30CB6385756FB0224F6392AB526CA21326B065C0C9C74F5203AC313B25F584491ED20C32F40A896F99088D07916D4F84396B67EEE7182B3600E418D353487083F58AEDEBAD6B9C73042748D2F3DF695A579611A41F4865329EE8E807F184ED2528AD1503A61B13D4EBF24D7A5371ABA6A053A4DDC63B0FE95462FAD2A62B9A23D50676D6F1B172F0E59DC0B77EA7C45E31CD89CB8B8BFB6AD07017B5E76D6798E08764B5BD293B27B48A392B382554EC877783099148E4C81401665AE7DAE8CB36716C56D0047BFCC5F57F5C6162ABF8700BB394CAC55D33E50FF43D20D2A1C27A1499ED068E40ABBF855213BCBABC2BBC71A3C7F8D11AED8CAB07C0BB8E5F10C5E46E726A353559265A0E511389C05760B4A6815EC4FD407486AEA685B37015BDB6E8DBEBA29636FD23DEF0BEAD64F38668244C56CD37517D586E08159F518512BA72CD86684768A42EDE0241C0EC6D286CF3DC133A64DFDB52E1E6C59743DA59FFBC28BF3C989A0B49248110871832DC53280A250D8C7704CF6D0A965BF74EB1E7610EF67C514C963DF6ADD4932CD7B6809F725FC65F32E5A8B7341C4587DB20A79F4BE0F42035B76FC1A7F8132A5C5D0CBBEA2E98006CC2847D11DEC848CEFEF19C29B45117859371166EFDFD9B1202BAF4183CCA16C2BCEDC391A01973B63AFE3389EB1E2520FA9C88063D038E9EC6F2A9429EAD33A559C79496A3DBC52E2CCF27DA58AD1A840207E7762A1F10F5ABF5F158B05FACA08CF40630E36E4044B69299835CB1EAB4DB06F33EEA1E1EE9692D427A04947FD1BA3D9A24C0C1ECC9CF203B25C11BC196AA12CAE8F8E1E2D37BD51002024F51BBB136EA9324B80B02A1D43B188A8334FAC96FE409CE4D056885D0AD5922F065772B895ABF623DFB4B0D956F68E65ADC37F34A10A1CCDA07A2603991F29598FD24D2C409FC1A3086892CD3EC9B22D7F01086BBBB12497A1B3EFE60E88F6E26FB4E2DE03B9FCC1856CB46B8D6617C8F6BB67993402A6AA24E9CC42A0E102BB46BF5D33F84A13355087B9B8B080FB8E82153ED8587F56A08226628178BEF5C7F139024B95D2854D8F37DE6068B4A717F4A8DB54E2CA731603E3AD6FFDE96E21A60A66B5F9F5F9B024116A999960D2893CF7CB3DF2781296E6B9D30FEB57842EDE5AFE2441AA32C8DFA2D3FA7BB1A3B0557AFA82B0D0ED8E088D587E4CC1CB6AB6C2FCD2826387FC289EF4E4B3D884A9D5DD354EC742D52962797AC5928A7419947699B10A46B69BE370AD481B2DCAD7ED5AECE4A7CF04032AC1445F6C867794ADA0FEF34E18FE0503A89619DA244E7FD4AEC38448147B49B8A312D3A6858BFC3AB91CE61ADD9456F4E231A55D0C134ACE6D43E142A40E0DD75D31C6EBEA609D2CEE42BF221B6B83176CB79AE6BF46181893DDF1527DBA791723752A78949E8767A194F6FA64C386D0B00F7EC3E22F2E059A37569B4B95ABE43A911D1AEBA678D9A15AB025B0171D48F17BDDC8501A04F907B9E6FD8DA942C728BF87A3EBCF82564ED11796E25FB861080A010DD2F0EE1CF8A7146520FF66F034479E2B8120E4A28FFCCCD0E4FA1E6A5E9E87A6B8B87DC8A3EF2D68D73F2317F294FC7A15A3A4E90564BABAB922B210878B64C20AC1F8BCB23756611BF042C201DA4D0697DB25E64C688572A3DC62C236555522127124608422BC9141BE17386F6423579697AF73CB0ED14513220AE13AA49A535AC241097190AE9B4AB6FB24E8200F75A7D3848A16DD3676E3E11BE281E04A9B642A1DB504948A56EA9A1C8D0A50F97F292560B12395A1B1138DEC127DE6679CBA8B849E33F888B1F595795321BDD543EAC2A28C4D89CFBC732E7CA6A7A04F66BFEBB4745D489A44FC4A5E255281AE35735D85DEE377AF98751BA4CB8835732DB983635B656F24FEB594F0C0EF5846B854BCED5EC137D8FC1471A41CE845D486E905BD247EE250E766A7F8624181263F2B184D07DF33614EF3BE0E0BBE3ECB0E3EEDE05AE25E2861269E0B0ABF9884A9DB377A360D9D3BF7E66EBCB490F02D0EB9B9F95CC59E7049C8F96F80D05B93AF90753930643422A047252B93FB9C0ACB4B88B0090AE098D1F103239C03D569DCDDD4D3E20EB00BED8F1C67F1F2D3A3A4F5F1E554B2E462564C6C1F4780007272ED5CBCCAAA46165B7978B206E3E099571DB7EAF27237B837884EBEC15DD26B40CB665CE45B29841B2DED76D9B0F1C9E3A0AEECE530A8A16F7FA1F45F9B9B7610A393D4580C5DB025B78B02261F5E4FB307AB6689934F3BFAC66ABF1C9FD202E07F20A1D82747E4ADA8EF9D5CBA6956434E94C9BEB21F32C74DA98F796C575B3B58F43B493D2D3568964580285CFEFB2E62B06588379EB296324ED06A7F1FD4F8790DF96D4A773E892AA0D9E17095D7329D9B31DB6FBE956D5061EF8611EBD39AF2E5903F2F36A75EF2BC9FBD833D8E8D2044D33B44B6B744FB66D0BBFD90CF7702567E92B9FF18A41582BEE4A15DE30290CB07A5E3528A9A27FE160617C351B8BB362A22C37F340F4C3B6FEA6289D7E4D637F6A1EB28A7D3C0EC52686D5A9AB790FBC2809F7F06F4871C4E3A24758975FB37C3D1733367024163EAA8F98CD93466FE9D53629E519176F349685F0E61D093801EC9A026648E72A13B8E4C05F906387553681D00719E572B06D304BD71DD1F5B36A45073127CAA88E68036BC26F9B6BF7265E86803373277BBC5BCA7762F7AFDA314949FEC84177FFBDC696A5497FB40C79E70E566E391F1BFC2B324D2B310A450D9807A5A72E0647DA940FA6BC3BFAAA4BAAB81245DBDD55942457B21DF8BD499A2E819A16BE59A6F7E6676CF3BCEDB9C646BE387279985182989FAAE983879BA0F0FD0ECDF712326A7385A7FC1B2C3F4F00000000000000000000000000000000000000000000000000040A10131A1E" + }, + { + "tcId": 26, + "deferred": false, + "sk": "A4ED7F80956F1A44672C9030C85547B54619A313032627687F1F158976A2D28907900F84E3B9D5336FB661CDDEB5DA32408DDCCD61859AC66D5E623EAF745E858C1D51E75C98A689342747AFA7C22CA287DDFF2B30EE9E945EFC4FF74BD00914687AC4136597D0DBA2AEBB464A55C00007A397971F11CF922E5108F20B895B7941207013811437764076602057327650014846512521051134044721728840471240468158620851514470636303001350088771812801531688000733466441861513742525412601875458731315486847771662050347316344525702707057377764035718082720307174511475224256283107861781131553717714042076114552115453832756862775232773050805741536122157711646367700242428287222761460706108640730202305048004271137750473622514020882603385871776073866148241884265850313425124232184264815577340717562333801724206311260451483381762216524703666716683462381156603313541080053820757730826678818322826883061861335148373782208061718105775375826777672423588433254824486101823767282154027254361868335678543353805617821481162730652045145287554024323481137013167450247203075702807580765272817733061138110138050742533065402722575387148728268663883012058511436440708755322742756705443143872727618411601186033417307153814781410058448267271130100732602686516231834311238647026760152547113031066482361633044416843658581330423061736710024767084324838453061881648523633073145626613485686817505362474214104803222606853556234224865753748040484665857228745563151400065331467076364034001854708148516718643014448254581642662324580472540817760016334875431813615733342068658625221436633877448827353301133165100217143140503533081867240242288376423706818517408834337781383674383187725187780523321864245136772216405236663621124437888768426042072813436208810360206554680333862732263101403067212832824174614502520062327687743605156465476282370734160232624636614258885304101344844586018105357847251401285316763376185064183603001641775527412116344815872823276550347785718752750352857227783051142305354808613116667716627278876620522410851068428786657414384410663404801846405041631402661336873256432535608683333558305507630406032814477633143263257074135750334036686836723317701210415018766018220628550711780864682005421263438423340416413353070086841488211041250620327222208657643663862137722367033353738671553527108308134351574435151103425678758048472876854021260323038826835101538487847208802126638654312684104325807876770077436312012363386725511475331337542627020144121211014663122140658514307281185501024006018177482712312474614161700446687886722647162278322132585863401702314217876006468328164146581047085401421760440321582542441117553056048835224066102526308431765121152602773303251363080350616883864358271348413640038283567734581504521116644336856306352571210550150067264084884453428240000533610751625013670107040138826466331222242287483473037278656425874000521127357382325247351023460401842120860208858010418511736611802200174883450035706425872070364332078257248857812267664537025601262182676445510008434415815140885773555147384536274812741577500878000523602141344148306644333741235746141117460853768768473488606543427458420223345786350554613242521843216282474064647007816386531203354608282C7D03FD47511B27620F8A1E8CADF4475E865E001C554F08A3C8357B8D71825BF62A6312D4984FC343B28C5C2BFB5A945C0EBB5394EB69054F3FFCDA20339C801412E8F06680CF79416D0EFFE1A4A7568279FBE35302106FB0A2C7A991FC66627A0915DCD8C344D056A59846FBB72DC0F407B60E25ED5B855A70694548E4F89D9CE64F56D41F1F905F485D5ECEDB38A3921EBFEC726FC9DB03608BD182DB7D8E07A674929C406CF7151AA2C04A3BE99AF5257AB2A178E07820A15C69302A78314E804EA86D2C2E16761CA9D4D781CB18E5DAE5B671E48E9BDB2DF6C75F07FA0F285256007A891A6F50C49535C19D838966BE3A6195D3AB635E038312F222D164522B744A1BDD080CBB76B0D3F3F864CBA93AE9A8FE4FF6856BAC2E5E7B7BE9ACF80BA79ABF25DDF14F84355FB4C43EB83A532863B46E6E6E64BB64CFAAE4170C2498A4E61E8B270F27559D38EB709F2ABB04AF4DA3A4093400D5D79D4EA004C7DB83461F3C10ADEA1D25CA002DF5F238E0C1450801A700D0DFAD0661CC10AB6BCFBAE0DB95DE9F80F59B7B28D9C02D11788AD52DEF7F4A10A0A3F6C7DE7655371C5C4148B6F8444D4BDAD3AF25708517E4530CC22C4790A9BBC34999A2B186B4C8AD6D522610A3FA43766C42BECC3F9D32ADB22FB75DBD152E7E1D8D39F35F3DCFE8CB2F51C5537E16D0D231F6BC75BB925F14C2295437EEB2DC6FB906206B4AEFAD0CEB91F33BBD3C0E773B61984B781C39ED2EA1AA55D039BDF859B93B5F5618F565F6011EFECA254E516F5EBA19DDAAD7120A11591E81941EC42801B37AC0C362FE593907CF0C99AC6479646EF6C7E4093C38DC132C288F1C0184036652A7DC583B2F9FA2330155014E3E8841F659F910E93ADC4CF082C87CE9D5DDBC89593A99B2E4AE6C43565FBBAF606AE69ABA8EE6EC61FBB22FBC715969F08DF203CB83CA8EE911410A56AE22145211637D5BD82260C7FE5CC6CFD9CE9AFC86F1F1A67A129556E3E989694454C57D5BB6B24F33F5D81386187B0BC6F33734E5EEB3A2E148DFEEB5D3A0D3B771F77A010948BA781BDD7F75DF23123D0165BB263D25271FF6FE747F4DC953AD2EDEE4807A698BD1F1229ECD00714E18EF445279FBB1BFBE0FD7F0F80255690718293D67D27919C482FFC5CAD430FA4011416D883C3C3AC9E4B3DDA28C3BC0DFBB2D2C03BBD196CCF7BB896B5F0A026CCC3D9A36A41BB9DBC8F7C4887CDC64E8C6ED97719B03686C1F1A2888778584CF7702E74AA4730E1B56EE347118EE07CECFBE43555C77CB20F2519576C6D67665F3DCA0A3C436FA52DDC964AA0CB9EBE79E8BD5A2A0EE66510F40E53DEEC226A987C5219FB639A07C52E58FE5236BB4613CE4CC53A721C55BA0D5125ED860E340D882B6F2B0F68AA1EE6D2C1ADB9925780C153F58B8047B7533FDAFCA8CD67EC95B6FBBA84E94806220ED4AF1A2861F4B3FD3122591706B8B3F5519FB51A7A63ABDB03B411746A6E2351C499DEB6E023913BA4E2682424752C17610EFF3296E7C71D09AFBFC4E9921FB13CE3169331B774B322B1925FA1DFBBEFD745825CF01B9EB0A03F760C4343AF3AB8EB8664D7D04298CAABAD39845132763ADBFBB42D7779724BCFBD8A387466C16A1A4CCD9B40569765EAEA58C2C74B0BF2D045C57C267CF9D57D4B1ED237793B45BB947BB83D9EDC3DA763EEA702DEB209591ECA2B3B53CEF1A2C2C09DF4F3CA377857EE30F81C17E098C37AA6A852E759FDE07390973B41322E6F45E552D98309B6EA13E1BB53A0D0F4F6577C0E94AE96DC0E9B5FF47F7C0E57970C49E103F4880A3E9F3DC694FF4DEC024C662F42D44EEC975C7440100F09AC08F5AF04287D77C409A261E735A109AEEC92127991CA582ABB9C38AAF556C0BD7891F1D3E9F76756ED0F8641418204F5BCA432A3E15C446198666F9CCCF6320964A19D1A992570908B826AC75C67E1D877A1EF3522AE5952874377CA0C0BF6083EB8D3550E00F019DC7A909802217A97C7C4564309543326567FD57722DEEB12A3A6F37063CC5882825893B636B6959DD2E6CE24B2F762D59E473429F40D05579A66FEF7BCD812867312ECEE3DFE08691D7DE66DB3C9F6F7B80013FF92F1986CBA42A31EDEC08E3D71DD8F104A1CA29FA8CB4A7D46434E572CC6DAC54D73CA6C86AD04B948C904A14196D00DFAB1CFBFD366A594E5C8A398C849CE8B1E88BF37C09C48C89B4264265A7447E86FBB8DAC8EB39894F80C18D8E405FF15069EA8DCA779662993DA4C0C60537448A39DA002BA14E56CF148783D6F9A97E166A2CCE8A01B67DBD891F7E75A70798FECD48CBAFB97558CF2643E4CDDDE7380E6BA2178677C9A8F1352E75718922C97B1399A84A602DFFC5086DB40091F825467833F1BCF99B7A8EB719654BA1C7D3C57AC0C1E2A21B6C16C548B6BB148A3C4624C648F27B168E534ED0198FBA6D8A335FDF8CECD1E762412BCFCAAF484738982CDCBE17A2A4515E9152AE926BABF7023806A7208560E6C14FA56B06A736C3AAD6AE686101B0A09AF7221F66919709F37837F1DD496E4567EA2A7983179E9E86E252B67DB29D1899AA33953F71FB4A0FF655637E4C125FEABE278F55DBBCA569EAF05C2CFC9926353CDBE609A3325BE0B9934344B6EF5BDC26A70CC1796F594F74CC858F38C2435D692226131BB627DF3DDC507E50C6CA9E8270FA43833844A6B973D078653C1B2CE63E5DD83E888292CDE058CD57E9FEBB432FC177F0E5D7AA96557D0B6763F8801E04CEDB88BD9DD73B72372E309E89F8230FF1DFC1AF767F564AB6218910C9D8101601EC2E108C04F72467CAD035B8288F370720CCD840E5294962B6B8C34C8393AA2E84BDEA310B0D8C32C41A57B40B64F1761901171F958FD17A469EF879F566FD1C786E8D40F47A1444095E831ED353A754604B570F7D87430507A0DF27FCFB4896B503CCE146F4000FE5F20E7E48560B053A64B2ACEAB204EC523C13FC73FC857799F92AAAD7F66A8CC5C89C5685A31C603700720550818CBE3ECE24C0CB47A9B90E0EEBB36053B75A56E68252E95DDA53B876187EE2B1F8E273B27D0A955BFFB67D76D291D4160A7BD3A516BAD136E15F0428E01705941C37619BC4347CA00C5E5B7606D5B52721DCB5C4D167EBAEB2D2F33443B073E7C9AED9700D5B382D5F61281BE2F245F6F7323F6F449C4488BB8F3253E1DF2FDB709DB2484C03BA27E53071BA7C7B510D607F0548454026F960DF5C97A727350E0DBF51E7691A2A2175B57D377CF206E1A38EFBE2A3E81E688684C69B9F7847736C58F0526BBDE9AF4EC377DC8DCA89B97BE3A29A30B820DCC0C6FC54420A5F7553C62A83F2540E5AD504CDB15955034B8A850283DEB9FC413FD746797CB846025BFCF721D03DE7EB576C083D0597304102084DEBE13C73BA3EC43F1110510C7E135735364C181990A18E501F9B60D249DF5A97E9BBC94BCAA322A778D112C4A26CDF73DB7A4B5C195D4DBD8BAE251827F38E652642D12729B1C8E69E8B1C2282DAF805746B1CD", + "message": "258FBC2A94EE48B415DDADDF470F14FF8DFC069CD949BB88812CD27B2BC3D9522E00F302C0B72533C9A612A251BCD292A291F3652695D318927CE1B922125B287FFF9B1AA2B79180622C32AC624E0463E5F48E86EB5952CA1A95BA51388760FC5374F0561FB8873018DEBF785FEDAE4CCD1A41820EAE9D7056BBD329E7A95F21A4919A109BD27D26779C3588C9A886EDBEA1FB97A8048DED858B299DDFFECD4D678820E5DB6CEEC8B1EA879C9C22FB7F59B227B4F7C6AAC577767D899B2F11FE39D1ABC527DFA0E656F25E53CA05630215C5CCF0FC071F124E48C57C5344BB103D51A1FF24114426A324BB16D8F80D3CF2D0CE573F4E50DBD1CFD66C05430A1109374CD84156D2E31C0C3F4DE2F1E225B5CAC05D56C4478929E356F7F46032E2719E07BB1EC207B32D241C87D87ABF28C7CBCD38267CB011F26A9B49090008389417C7A219A9F18203E6D907D63AF4C42C60F7FD99C7F9394021640F450A9A072BF2C1CC3EEC88BEC866FF1FB5F032567AE053A408342A56E3068EA168B9E902068EF808916EA58004FF31C31DDC3FCFC2CCC92E0DA09623FB523AE46C8CBEF92A1CFCF4C0F523430E60449E5825A81DEAFB2E26B3131F0383B8FEB4B1B4E1499E89E9C5FA2ACAF1F37C422CA41ADBF907EB984DD65D8314E2F71E8AE616C0518DE9B8331FB00983490483362802FBA242E4CB71056E3256BD097504AD13F577B36A2F9FBC1EDDD25D9DBC09B3401D58FBCC9DDC8E74BBBC897552FC826620060D3777455BF76EDFC059E5C02BBCCC0F05F86ACE1903AF2BB08A962BFE9E2C435EE8C580502351669AB7DF3D9F6B4720A0509BAEA97FEED3B8C769AC5D0997A097852C72DD6D5FA0A7144E08D667F21936F434953EC3C88B5BA2EDAFC4F87BE8BFB5A592847D15D5E5D972710A4A75A5772DA4D9F156563C17B1F0F242457A198658524B0D6A46DBCD26EB9400DF3C4C942FF53E1102411101B2FCCB58E3FBD16E725147960AD56C6CB6DB336857EF137C49D53D16E98CD7A0E856E2D6B391A95954ECEFF3B9956A6D0C279DD9E1FA5895D37EEA8C54255A6244002C7542789453B41463B084E7FB3361923C43EE1BA115CB254F47E55E6EB79C74DAB4C9CCFF486B8CF5830F23BA23C5CFEAC2DDF7D71EB5F54141C100E0AA9873D43F0AC1034C54193BC63A560A0C661047C508062A70B3E575CC185462A75230D91A3021330D95F3C807688B032AC15A9623A833DB718D04603ECE983F1D21A4513E80CC67FD34EFF8E377B775142344645872844BA46F5AE6971E68FD8ED640BFDE9F276E26B208A8F3D74ACB739C7EA6CB26165EE182F165EFF21905DCE3D02E432B1193CA108B6ED066CE95D549D9B12445E05E0583EBEF32F17EB121D80EC26C1F154C4DA2ECAC841BE1CC7224576EA43ADEEBA53C4D58785F36B6BC0F8AB23340B92CB87DEB0230869A52DC634F68A83BC1AB8A4102264CCDCA39A51C331F6DBE30C18C00A966E5692CA86399264399DBD3F02FF8706302462D62E4D16B5C2FFEEB02A7E8447C2CF1A3FBA5046C792FAE0B1079621D59C1D7AAD17CD6578964D1ADCF1256F2A4EB4D534C51313BAC17A9383B5BD02EDCCDFE59998D2FCA7F3EF52CE0B1842368EA66E0A83FEB581A7137004655957E91B25F5435BEDC0ACCF69238AA4CACE418F08ED0D961E13B2234187597FCC012769F798D969C13F6BB4042897B0D8C32E6CFFC06680B1E0A40F5F149B5974B0E7F0D45367E93B415F7F6DCF86C2131137DCD0DE30A3F1FBCD5F8214AB20BEC9738AEAAAC200900F4B2074688C8F3026140A354A22F83BC2ABA66407F87671C3E7EA4EC6F8272B6D16F3C66C76ADA231677A9B1CF496B3C241D2D1ED7DB703119CEB162EB097A0AF2729D0D6CA8DA57D83E1BEFB880EBEFE090F6E98D64296F7CA90EA1C2B26131676232BB394BCD1A06BA83004BEDDA287073154D3BE16C242DD65839C2E1125B3E66DC93A95C62F5DD31CAF9895646D5E2D183D40EA09843F5DB189B41AA4CD1B40C5792C2BCF9F44823EDD4246100457299E30EB2C66896F89F4FA250AB19CA06EF5B899CB96FC5E0369B773691E3447E68475A7552C10F96F44B3282D92AE49A246508A67EAEB9F4586074D6FE8A44D2D27C7B8FB4EF6BF701084B73641E41AA7275C1D6B517FBE3D60F64BEB9119F3FBE96A11AD45610E63CBDBD79929003BD1F2DE89DCA036973974FE5C5D5A8B5BF82DE0368DC60D75A138CD91E8A9233BBD439666ED1211EC2FE7D7BABB1247315DC480CC64CD8F7859BB9BFE8C668F112FA96EA48BD91088EA44F40D3E57314D3759F867BA52E52BE822400D9B0C2123F50601EC5F8E8B562C4B1F49F9779A99C926FABD8A74173195CE23173F4CC4098EED74C8E0FA74320772EBD1847AFA1B397F5A6F05A00179DEF2E6C3B092D9182CA3C4E382C4092396005D8BEDF6248C81D3AA0854F0AD43C1079CFA1E0A42650EC9D7B9077BEED377BF5FB2F3D2717BED04CDF2F7E7D1F45CCC6F71A780D2E5C3516E5F6211815FD691E036E4FA002079448AF0E005B67D2939CA88CBC57567F634BD0402EAB06805ADF8BE550B3E27452B372CF8C92A7055714A228986FDCF4045421321555BA06173CA0A761BEE635C541FC984C5BD3857DE696E9B21EBCFB87ECA437E9A7B54F4CBE2A601824EBEDFD5446556B64E1A88B0BD9CBA507C5419CB8CC4CACE48A0C9668FD2D045E9057B13BF0785F59B35338501B73B44CB749EC2EBEA97C9D29EECCA6AE1FB719F9A67E8E175D50B2705B6149E9D5D257B34487B547FD050FE5C998412AD0B4159C2225EECB67903FFE332CC3B86266C22FF7776334543C1E954AF5A89C4FE59C1F1AAB5097024E2AA7BC09831C9A5ADB713591106CD3304873BCF11A9138FB08B7485E123DD8F7C107E336659DAFDB866487E197589DE47D2DE8298EC3560EDE21A633F820BE6352CDE9AD51515D309C4BB4709F171CAFEB407ED1A02BC4AAB53588C2CD4C273BD527F8B4078925FCFF8954536E0B4366E474801F5B938A4B81F037764D5CBAF19F237CE37D00246C60DA652B76469BECABD51F873DC75E520A75B52BF585D664B4CB9A09F8EF3C03FCBDE6B9E595C1371C2CFC24C16EBC392C75D2BA04212947944BC0377DB718A7FAE0F6F9008AC7DD30B94C1FCC6BAF750217C0119736E4F3B7E744AD72F1F0694BC88F71E4BE51ED8669F0E814E12FD9F833286E2064708951DAB852774D4620A26100FB44A8A92B86E17507C036CE6F3ABCFAB91193CA4BC4D4198DEAD7CEFB71B01FE2506995F2ED3A02EBB0355E6B67A2294648B8D1C1445164D99B966588CC253D1EA1361163024372E2550E9D29AEB4234F5F9B20AECEC01862CC98365F1C57FA4D5E0C1F8BF189E169669F825DB43172D1F682DFC7729B2AC0C103ECE4ACD982D86C515A208519D23F62934AF981DA66B97DE2389F2F669EB92CA4A5C4C844FCB19903371AEAEFB32E210F2D1155576566C7B529A98A1CDBA36B450F3948F34F90A49F50E7412E6EA68BC3BB0B0A0AFE3BDDEDB718D5A150EAEA784859953FF1DD1B371C539243547FCDFF4ADB06C61CB49EA5783AD06BC8C1F3E32A95AD3CA6D69EC1D226BF9DE0562888839E6243CD150EF6953C158F9FEE5EDBF173997D08509EAD1ED4DC2AAA33E18DCA6F59269CE457C412B58C4483BC96AF5069D1C2E3F2F8DCC5FE2825DA21AB2280984C359DAE44C2367D6F002D64AB47F9B64B5656622517A5F7D5E1A78D4182B6BAA82E0490659CBF2724080A9ED39BDFCFB21BA362DC29C750C5034A04EA5A85799E01FF8B16ACD2EFB8328BEC686AFA20E591E7C7FC55BCA8BA1A3C388B785AB0F57208CEBBC5619AE3A0B799D1816B013BD67D440A7AECA7D0BA517846B68F70CB5D6ED46C36F663D6F242E8FD8C620C9383EE1BE9250D63467504B229378D2589B525348DFF852AF1676A18DE321DD46D7AAFD3DB1825F192FBD3F160E8CA400B201B1A61D0864257CA340F179F5F1967659AF4789846A4D086041441DCF4267681B83D4C8539086E276C21BDF677961015CE550E41C2C45D67A09AD8F56AC3ECF1058F366F2E35BAA9353A5CA40C7021DD09AC9FE0187C10EFAC7BBBF3B1A462C9C6C96699741AC16D3526BED3B30AE25B8E8A9ACD8CB2BB6C28AB89F0A3F0D0F40D10AFEFCCB067A37A2C93D3E8399A366B5FE4829870DA75B93249DBBE3C9AC9FAA70C4E414EBA720C323E6627759E7287472C3DB9CA9B1A5FF03E872374D6B893BA4887AB227E989D9D4D348B3965F7B96C5094F42D84432EB771BFE757105966C9A08D6C58DED7DC216B3D0ECAD2D0B025DF33CD3D813348B5E08AF95BBA08DB5BFE5D0A151C98A01ED27661CCF80F416A1AA260EBB56526AAA289F17FF5AE97CD0907D9143BCAC73F1F83A2A8DEEB3ED209EF0952D5E463D87145E0E4D8BFA1741E3FB737E14B5924F436D0183D98EF836DCA3F9623B50CC13EBB5F94EFBB76EF9BDF40CE6EAC9C49852D08E2A5A193D1DACFA04EAF3C545E0E25E37E94DF51FC1976BAD069CA530E19EED277141BE62239F47441B88F6555B0A998C1BAB53758A41CFD8CC4CDC54E1158DE15910408A6E79D33CC37F61917027E9D2F186466F704647B1CC1CEC06DC1AC37D1A668D44DD8B12621AC3CBD2039BF5A843A86FA492A847D6552E1570DBFE008F51652D65D03D8B613AD917B81CACDFD19DB7F4DC9A14E237CC6D7268FC5D3B228BD88ED36D8360488509C974E01433D78701CE07108C67D0489AE94076106B045DF7CC508466D35BCF156901E53AD2B5ADF8795751891A5839033A40EF3F5DFE0BBEBFB2C9D1C000691F902AE490D382EBC87FD40E76B30DAA963254674C7B6F304DA2C8BDBE8E1DCC87DE0486B4FE6B57A18D5A9E9E4BAE776D6147FF9C98372426EFD30C3B2479231E624A253A7B0BEE31E0FF739F862010AF03E227A12C3ED1F33EF1C0DC9D48A100FA24CE5C5D8B5F88F92BDB6A3A5328B0AFA983D57A1D3320A682B5CA94E75DCC69BDF2AED0C05887B791CE6F6F8885E4CC55C3FB050ABEFCD3AF2CA603172AC78B3AF2B047E506639498D0391A06DFD328B8E1BFAED8F76C6E4A93E733ED1097DAD8663F5BAEADBE1562D40C772D376786509323BF059FF17A5E6EF5A31BD668954766417E6633BBEC90B53ECA61BADD4037030A55A5EF4129D4958F6A8A5ECAA1AE7E220A87AE996AE8D9AE46B9C60FEDD98FF1E67807037970C92CFF9EA4B64F0BF8907198A6C038F9826CB968B1F301952E1F409DD6AA4EFFCAB157E792ED45830708ACD7A50BE8C08FCD12560344221104827BFA495604A57826A49F90B8B694B2BCACE4040627AA0989E3DB4FB7167F50E8A04982084FB3ECB0DDCCA5F24A7398620D19B37309A4DC0DF28909E16645F35A81EB3C5EF6BFD650571DAB03A7FC02FDCCA5FD09C9D2D3DCA888B8261433DE88D05DEE5D6165080A237D55ED718486AAAF1E2534CEC3A87048ADB40EB9F9DDACFB2C883EA6B20BE1EACBDD72432C7A6C97721FE1E0D9A5589C951F7D46F2C5F0FFA909FBE12E1CCF00161E741C4505681B0B018FFACD460528795CC3810BF7F94FF9B75884956798F21ABF36DEDDC1F95890894EFC15EAA6F19E9148C71EE9BF4CFD41EE3E5DF8A449FD95E5744793B9C223D26ACB44E691D7E5B68D49A19687F0237E7287841D3B0B4483E2A7C29CA81BDAFA5D96D9D2CB6FD9724B9903E8CDD03DA810EFBF94BC7179349E10566B5A314F81327F76C5A8346E222C408EA43FE29439132CDDE79D0D69C45C7217399205C2DA4D33DB521940C4EED74CA22645D5B6A549E8712D0B8CC50DC180067D13457ECE66D489F687DE218449D974620B3B5462FF3A7F00C439AEC73A53303AC51EB84BBEBD51AA48A5DFB8F93556BA540F5101CADB8BDB912D7BC87EC2AC67971AB99093C8616C4D1F3E7B06003E4FF22D99E6CAD7558EAF5C1410199EC97720E5C9278548E7EDE62BE9105A2B27A54D95673849CD5D60424ED97BB64798263F98A63DB58BD55965D3A4283797CD88C7CA67B1C4F90FC7237EA35AA24DB18A4420B827B3FF7FA5472C31499480EEF5A97BB967D1EC46E7B05A3D25212C75972D48A9269D67048132399E1BE0C02150A3D48717E4DEC2ED47458EB870A1EEE5381209B5D182DA2093AE46A4D99E3D4F12ADD71001BDB936FE8AA96797982F88EE67AA2E0F340E7AF498D5AE05C177F0BD2650A02ACD4CE23018F9E00DCEB9794C5C76418EFA65634E01ED5E9FF94FF86AA73641117BD554A9391874A75C7CD1E7759755B9D2A7F367621C0011F61B588D913C7AA0A0EEE3A2201426EDDCD56A020F54AB41CD899721D6E1F05F8774CD5FF6417CB68EE14C20D9234369C9CA59627B8796C37B4ECF1DE2F981ED0FBCD5737DF0B82637D599A61826909C978A2B68CEF01C5CF84B50BE77B49C1887544779BFEAE3F533286287E48F0ECC0D36C27F1209314726855E61E5EB5E9A5D7E3516E29DD369F94D72004742E246AD4699C64EE996BC7B2A079344ED32A528A9CAD6D5AC02970D0168A8B5BC713E28934F2880774418550AC2F534D06B61E627BCB8711AD9FC6F2A4D9301EBB74E1F3C73B05F28DCE5623BE1BFA871C14A947A947CFA806AAC43AE515D6CA65436BA6B66F62B0FDC8AA4A748DBB72D9AB087AA39561271A986229EC02BA3719CBB1798DD333248E4DDD0B6EEA4169D3B03C9F4DEF9616BDF97AE993F0FEDAD31834B6F78E23164B556A39AC1F209581F61AEADD8E504E81A808B1E97F79F987892A8F7FC35FED9B1A2E9D3E17BFC5AA64680DE98664FEA7B479567CBE307AF2A8516BE4CBF9EA030471428CF802FAFF85701AF96CA1D8F50F5A79AD63F20C5CBB954011BE4B1A7F627A8B5F5A0D022D27BA6FCB8D3587E8632A2FE5794C7E8FD09C9AFA3021B9F43BA82EF48A3B1F3E40F2FAE182DDF9558F7033773F5627906E159B794C4220219BF1A9878B175996A16F3CA1DDEDA56B16E63C504354E5E42FB90CE4D2C1AE7C93D8CE27480F3BCCC076CC253B574A7BFA6D3BFABEB3FA6A19F196C7E31A0D6E9477F828689FD951E0FB033DBEFED6C680F0FEDF2F43F48C0136C722601CC7C4B48B24121ECB6BF84D6B3DB240FBA1E014F7E3ABDFC1F9B98A16F4D39826BC1EAE44385FDFEBBD649BDDA129FC7EA3F50A5F481D3B7508EDEB04FDDB3006D6EE943930E3F0AB405D151F21E8AEE5BD87F225DA6E155158DE27290B2048D384BCC54F0EB905961AE4CE5E6E93543016F62445AFB5C39C3EA2F3367A0B8F0FBB83B37518C5DBE1CCA1DA9D0B54F34B15A1349A2F03563732DE14EA9BD238F481D9B262DF69D24A91534805ECF57A538D8F08B2FF11E96EE692DFEB106D3515A7C69386A781DB1D5434AC18713CCA12C92557D1E7DFBB15605AE3BA86267F3E6CBA42B6084478E460F092BA2649C8C94D66128FABA2D0EA7D9BCB20663B0DE6EED2623A061778DCB40373B8CA38B02B7A49F6940D6D11CEF549CE80212CE8D3A85CF2D774431343FA1FFDBC71C5334B1CEC4D4E0EB643E1AAD67D1A5B73FBB1BFE47EFD83CD17C798044A504FBBA5726429F41DDEA7B7265A76A48B0BAB4845704C771638977511092BF6C6DC9D574E6288C6A3B96BFD37FAB695F8DE20F28ECB27EDA70A07FB2ACDAD88DBDFB2DDF06E83ACFD3A136C5DF4811D34C242BF9206D579BA8DC6D20E8600B726C9F1B918EA573B9DB2F96444E17B6EDC15822B85D452CD99CBC847AA205EF79E574ED9625E33B6EDC793E5", + "signature": "0EECF0C5C5646C6C01CFCE8A4236C503F9C21F7A3FDF1B708851290611FCEC8D28234E40B9061C15212969D6BB647797B77E3CD2AE88051929E75E9A0D8EE4491E6E709DD1E43225C545CB3656C0F84520A56BFE0B3A26E2856A1661CC2BC5BD289FA800CE140070BE31080CA1245114624EA0C215E76C32921E54F83796F9CD9B5F0FC621AF39184C4857667414EAE4A2A7D18AFBE427B48441A99E9650344EBA609B879C42CF4DEB120FB5C44D542971182F83C87EAD8DF96ABBE1A7CDF1A75C538ADA01C1EF73E99F80B792F61A548D3A2154008B20AD71CE0C8AA42480D8CED5EE8099590057D15B339A8D22CB86E0E3FF8B9E902EF7603098B356CA6A3E8D8826B1B02376825B82420239F04AFC1088B16255EBF6030E183FF446745EDFC94B6DB334B4818F5421E58710703493859503559DE0AE797A4194E46AC916428FC84944B9F97BF2BE5DF2C3DC0E918F8AA58C73D92A052E59DA75AF1E3E30896AAECE657CC427857AC6EE80438C849B7D129726D27DE10043457BAC8B6CF88E91DF12ED3DD04B930ABCE64F4A140B551720FD7122C0C201D61F4856FD901673B59EDDAC1486563A7807CB94DA76A89E3B358A78BF8054D7657246200685FF47BECF5AC5852CF2AAB51CA8215CA1EDD6EB6B1B7CFC6D1E79E00692103FC124A48AEA58D21C1682761EC72712D2FAD386AD3153C1A07F40135F38D6E3BCA30F387DF057D4E26FE94E1B89FD1C63CAE97B0E0EB18D53C45F5A1C0332F35FEF2BCCF9192758BAC873D3C48506D23427332C89465C8A08516B1E0511C56DEFBDB891B15DE0A58771C31F398FB27BF63F3CBB9AC9713F75EDF32323DCA0D2CE330340B2B5946846AC0A0961CA3DF970B827C311F4E7D04A859BE995ED60092BB8FECC2B0C5498E9B0F88B4B70DCC50B6C01286494C91EA3390F162CEFCE4B83A5486AEA9FA866350A3A3EB411A601623F9D77585ADAA9DA360B0900EDF684095A9A581DE3949F85ABCBA9525398CD58A81E91AD655649FCD21CD40490A5892C0E8CE4709B1E8004223F8B842389306CD9640A3D32412B4DC53E3BF04FC39424156B3E797E7CA688AE6DA5A4113C8CBA7290315D6A6DEAFA09680857C18B696094FD67DEEDDF1D69A1A53F73696733CA54CF0BD144AF0873249CA50F897CC5B487247A1DD5AE8E7161BCE9C5723DCBCA44796CFCCB5D16B42A1EB3D2ECB6108DE4F2BE18AB41C287C6B4677E56802CD919EB1EE762306902C9D731EC5F0773F7CE7243BB6A9A832C4052F11E5E56D20BB6826AFCEDB7DBF9B4F72460BE0C45FFD628EF44F0BAF2CE179D9627E5CB1D10235D3AB21206EFD5E74A823DEEBAB0DA04BE8D9EAD7487BC96EDFB71737A15A27452792CDC237305E8537619930567AF51EA8E5848DFCAC9871C7B260695A340F03A48CCA700E60220A35A01B2E195BC3D73A5A8C6918567BAF8EC47B473DBB487F77CB37EC6E37D2D6F885208AAA845C5ECFBD2F128CF2D5A16C167D26B00CECB517E753A121CB4CA8EC8B3A5F735FE28BF6E0B988E03E6FC2DCE9569721E1A03D91760C0EC81B4C1DD31470DEEC860469DE3A74777B5A8148DB3E7BA6AF995BC8BC14F30C7567886CBBB1C6D40433D93D52D9D866D897727F55558CAD5871D461ED8756938048C877C9183AEFF67132CF8AE015F59BBD60DDA63B1C2DFEA4FB19ABA2019BB52A135935F73BA5FA359EEA99BCB8254B3A3D82BC2A8AABE2A653AD58B2F13609D762F2D7E89370BDD46E46E55B9B9217A5157BD696ECB992809D1DFB607F1E66B77E417CC0EF7F3CAC38705619BE39FA625EAE2615D9137C0F702A5206D95A2DFFD7ECBC308CC453CB29507B8582A1B200A33C24F6FCF9D3E37814D029DF14D9D7E8D6A98B36BB75A1FE45FEB1A61F212C03F28E9D45FFBCDA5796C2FB2B9BE9AA778BBAB82F9C2BC4DD45B64DDDB6FB1C71F57E11E49246606947A4863434C8CD23C0080F11B31DC7BC0FA92E45415C57314661C1ADC1358AA49EA4D69ABB9A230BCB0D85A8F2885D261584392656B15643323B270C68ADE3D7727B35FF8948B1501B8458FDBD59282E713072F0799C2EE69EBCBB441CC1200047A23DA61DDD7F73D59008D9A802DFF46490DA652B6EEB1BA3D3B38FA04FC2DF2235380B026AA69EE90DF21FC5045895581D27AE6A6D8F99215B116CEB03F9C667CE8DCA4B63F1B875A2B2686B30D1A59297CD7A491178E3A81C83B907A1C7850092C355E130C3C41BDE7839B115E8A51D729D252AC62CE03E8B9EA488338E6ABE1A1151FF037C94350FE5B89964069FFE68C238B901B72847385F937F148519C0653F932048D6B0E7B57092625A1B4BBD72DE1D16E7D96A509F39B3A9E50D1FFA7EFC5842DB79B8C15F2842502278F5125EBB082C5EF78BEC9E872DCAD120FBF2A3D544F15EB51E7C14155905C50503A3B12C24ACC6A37A051D54C6226E0FBCC5DBABEF1C0CD4A89463873379CD95B3708C5E56FCD03C71B3E5788AF19033DA37771AC10373544CC25696F0A342307EB92F58D95353F45B5B5791EB3EA3DAA88CF74B3331C21DD448D00A1DD026A0DA7443B0028D1E35A304B0D7DEF9B74C09C377A9A5B1439D64E7D22C687FE420E1E037D0C1AE5B2DD33093C1E130B5D8428AA2E430CB5FAB92B316439CC9E7593628D567D7055428B7E6326E7A004D0820C22C1CD015DF8F0082F2FF4D39A05A66382107C8467F00344639CD32F9A4BAF3DE73640F06344D64BBA6E4E830FFB98BB23C02D0DD9D1AF3B2E9224CFFA7B62CF7CD552DD26128DB065C1CA91083D7426195F9DB63061C20D9F8ED337437B4D69BD7AD9DD13349708FDE783E86BC1F81BD2A317F3B484DF3912A2FB97E8F5AC62D14ADEC7A7D1029FCA2DCD81EEE23CA87D66BF43E21273D57DA057B35D8FF70404C230989B15DBBF3B057367C005B5ABC61533C623D2D774546119AE87B2D5816B5E7D5039F2D1FA568E338D4EA9FE809126B46D2EC92EDAC8717FFA55D678BB94F0C061B0744F7006E8A0A703156E8884A81AC0D8BD86EA1BB7E682E43F99E2482EC27697293A00792676042A660598B8B54029E00D5F0C7D10B07E4275620C3D193D5323FAD46AFC4B8F4AC825618E872BC184AA97DDFD96BB395ECBA6C3D42580F4BB877E5AB7D96D985811B580417D6B006B1E6FCB3C14F84AFDCBC38D495674B8AA6976B036B5306EE593A0584A55DF7FF214C1C6930CAAE7AD69423CEEB46E95D0DE88317052C5C62B77C43CEA863AFFB22F0201E5C451BD9ACF2D8746346E776174BA21527EB5A32AF89F12F9E26A99F15AE8017FD9720E3CF71741C5D7A23DF373B0F229B89A1E1849D569E0461267267BFF654CCC010F135AD41EBFBC63A3BF4805405F3308095A90D4C541BD82BD62D8EFEDF4B9097AEF796C199521931156A3E7A59A7641F9A0D6542C05EF29CDAA28F5B733C7B30376C975FF08485C8CCE4393B5A8D3735A13FF6704544901B22FF2A239BE8EE2C8CC56175FC928E3676209A003DB9D7BE5DC0FA7C6B3A5CB92F2BB9EAAACFB740A8AB47A509D2BB76060196F26D54690794C5BFA48435B79C854E79A538F1A796F1D4323C016A72667E85DA2FB595E5F8B98E5BCB30FA0BD14EEA3055BC037B2D11B6C4C8522961ECF541E3F2A98185ED50E9EFA20516B0353B0DB96A6183AA9EA9C2C8CB7175158FAC07B08D5C01089B7E835D10ED00D7B3CA28C22FDBF1E0821297DF5EFEE9AB47BD245CC29ADE18C0D0529F9070A2F961D558012908E824B89D95474D0201612B474F7C2E4CF4D66AB165883089013A4A60DA26EBE8D7FF70AC279CB81A22229BB098FFC26EF456B49878913A354F66B8D8F730FCDF1FE01161E606FB890B9923ED849E6DAE68BB3364E6297B66682BA3CD3F0FA7EA4B41B8C96C70B16D606DE17BE72119251F6B64DC78A97924CADB77C228F4118F2C93CE007A4A60BCAC6950FD2526670A9ABCB6436F8239DDFEB8905B69E7CA52BD6FD1D3669B24689E4CF050C7760C0001B7875F76A195E043ACD6AEE609E76F1C800FD0ACFB96D93BCD5A0FFF5F979A96CC82A376DC443D694AB9D190A96EE34D6083702DA6FD73233AB5DC2CEFCBEF22B5B32F66565D0DC948297D83FD04E919CE4705C26506E896943C5B1CE8055434180CC62086FA39A12DE595949C40EE564E5010E22838ED76DA6CB72305F5A160B04777E10B24D7B502EDF16574484DF1872BB115FD6E91E0C0B0AE2FF35FF01F8016D8EFA6D5033E7EE3138769D88A96E20637AF1F435FAC584F94AF8F9C12E3DF67814EC28CB50C5C8C473EA39AEB6080E127FED93AF5CD75677003754C9E31120FEFDE2B23EC17520063884FA1CEE1D4C0FAF3EA7139CDA87C050CD26A349C55362401D311029BC2F21D29793FC8661DB90DC18D96079AFE00EF88B007DDA214BC8800BB7BD30C942CEBFBA0DEBF1E68E9903515C990C49D323A73A804B0EE4EF439BC5B67F298D63B9932C201634AF618DEB8C49DCA06A0FC865744501BF3804668F3331155CF61DB1DB6CDACDBA1119D3558F1A0BA05633AD518C563BCEE51937C0283F3516B812AB2CF2B80305F5DC15437811EEDCBA7D236E7E9AA8BA295A7E8412494E683F5985B920343891E4F44E585A6785E2E6000000000000000000000000000000000000000000000000060A0E12181F" + }, + { + "tcId": 27, + "deferred": false, + "sk": "C8C32C98B4C3329B1E9F9B8B0A06F728FEC8DFC05CD45B51C28273061A7C84B44D03DEAA1D3D423DEF8D01DF94252EAFEE18AFD0B714F246A2AA8B22919F4A64E8254BC8DA58D79694F68A8B33FC23190C4D19E3D686EC528B46E14D752CBE218D0E18B655AA5332AAFFF4EEB5CFFD2BA6A03F60DC018CD23EC259AA4325EFCE08852158642851628354014253336656040034734085244624702650458046023414141653265662553257528848144434538583171237621870046622542527580662760688425754461883673651187381743864383543514734285686547356774154037857147010824422821820372371434640278657362264124415854343344041688413722261224658655223800244426352431335075843223847830638802787087632058358458134612063704650052330674634702657828852755171178100888071574872500003761125174467551513406085034688414064261281865718534556361580681066615474883681774570757571780007105873237730643787603255741251882778647716627735424330287653567230817703068376113812788174132853265501737207541765673284844633087711520768836556152784146844502445608448350455765277306601008336883210200716413782342871820515037658772672513172866057305014605013778856128828263337372405472843534375648655082510264478061188683265047702226038855710017543066112306303885632257413744062041317752202814804005205448814280410780017846728458263376183744528251332866682020484544067715461251381023268133503550626017320763011688141043558378413875642643444584351184365058376728644264005672381788337041681643525641530354046426331448556436657662128333156784163856374755524078102415500647382668666204378324674242332458875560880870446801506724870770075377623558535018066536113077736557373140121445368728505234510843712443083486066118634707435307287834841377048724203643811402168118565240877002038527641833114558786071676284684057368570785252016484650654480760442014125342136012513131513754542527403415643546752574520100488478715505263884185412513443846738708103777317714028531710677723682545550823825506760431583105357435861166168085225017870015035876442236026623862112188700714876376877706235072035840614340577178021553082422411251301420001307586123370726600337582487275247806637312456726385287223783713615774466050881878126110710021758600135101147142066365521572708410557043546161410781630038172422202645550360675605422888073255353264416833160257185872065350608713265217047530036306438828400667786630573535515217683235415121861604404228766416241310412807607544783206736820630303115444301271607246665073637418272420826411083048741645574851556481310322648258642846872020371271453707105300457683437487543257460657574378450022804404154248422852870054400115704171748041775074284552866412884625787625020238334401546627850511538557453800533335000553567035164313872271652448031663187004542613853645488711616002127354808730021575550780772055654173636682015662428213111586672337018624237806607430261432561653583383546454223153687813363744535756030611834227116883466042873648850082482071801637617701364885353218608856781116835784815225000572468806855765577805768462876401546171442778806140835684815656874817750328776567238860658770156531530633503227851364168542031232554515285878430550188057083146685505544383510160372216041617018142A2055798CD4A9FAED4129F4762117C2F9FECB68F55285D58DF9B1D97319AC4966C0BCC41CD28E76896A2CA0C448C002E606702A1D2716B18F92F3D248C5E576EE28DA7A4928CD072E2E06960D642D78C34A55DB793D4C6C27D68E2E7C2E05F3E997DB884F02DD4E294C0A37EF6655A74F98B3D118D63C8975645DD28E326540E289BCC194695E2962EB6F573FA010D9AE6DBC9DF30344189F87FA5A12E7F096B409CF4905A15010DD6CEF55A88E3A39ED196CF05DC1FC8A5B706452F4E49A2D07DAECE812F69207EB3E4D86289E956731033D6F0B90E9442840DD8ED3D4D7298836D086D4F171C0AF60644B7EB187EA185FBA5D04D6C42BAEC690B6F1D68764FFFEF1C719F690A2BDC241EA2A145A7B9193CDD67C671D14A676173F352AA90886919A765B2D89F46E9C13F35243982F81CEF10680967CA1D5AF9331BF64951F1C48CE1E0A24918FB07573F3899E19D3BB2C386C943D2732F5D287996C78C67DD2031BD6C635D53C51DDFC4B71A27DFEC7A308E568F2805F667B1A85F6436413A186571F99CC842C9CF43146B588DD7B0283C5FD1D09CDE662B510BD85FEDD31E3DDC957583FD08A1F8EFCF2CEBE014652E64E558EAA832822D089A3D82911D671543FE6F31812A435C1741BC2AC8C5B33CE4E3F546B970733BA7384152FDDE245FDD7989E1CCC430D134E36049DB88A3817AAA482BAE3B53D9A448FC536AE8F2D01919588A00A2A2CD1F1F48710F5FCA8709286B4B7E3F14FEFAECFBC830D3DF005FCB6612B782AF5DBFE7C2436DB6385A0F2C929849785ECE26D52EC9CC70837FF75C7E6D280CC9B3A61C8618C2E047BE4DB9A6A89E22EA3AEB8E2953B5336A388E3837DF09BABC71D308298D735D37FF4EF3D0D65247B72DC04E1B7A61BFE131E4264DA5A46B664FF4C44279852214BBF4867FE3B8AA274ABAE01EFCD237DB8D41F71DB2B386F596799C670C042149E289FBC3FBE0045994A5263E710EC3591C770717F5D6E4362ACBF5A2C133E9896AE4B59553353CBB626F854149A25728C4113686F16D0A6EA7BC54C8DFFBC8D7AD3892AD37048912B09648814B415D74408AB3868D6B1114FBF9739517D8AF886316E19BFC66D55AC4F76C6814E96C6A8F846961CFF17C8D6A1FE362D071D5013B2349724BAFE710D990C8CB0C6438535C5AB62AD3948140C1DDE116B7E552E3677C001DDA26E3D8B53BA7506EA0069B90A26FCC35FF94272C1C90B3D910FDBA5FE8E2AFB5B955847CFA4DF8460CBDE80DEE5DDADC25C00418C126F7D0C5B8C1B9D8710CD3C995500AA245C63D9497F6279130B23347A95A9D5694B512D4BC088290620738CA448B08ED871DADBF1725D2348FC4DD6FB64003E044B67595F64D3514B4CBEE61E9E12F1163B56C105EE952616A331B263330B29DEFF153306EF9CF27C9B178F671E998C07DA69C9D38B750308A7D78ACCD69EB30E1F04D86417B76360805576DFB5BB9022EF9D6FF249EF9D66255A03535CAC6323B084C5550BDB703159F570F47196115BD67DE8BDAD32C9BB29B7C6FF96EDF4313B101E28ED28C37AD1DF54FA6147F3CCFE8A890A423B047A2613CEDCAF70C0FA123BF1377482C1EFAC44C483539F54D3D54BCCF3CDA71AB23A7E27417C317F5B1DE41E99CC1F695CEBDA3A2ABCBACBBC7E87BD1252DEA50853F4C47053E10AD30490FD3244B0AF23B7F869E13F96591A363E05574808FDD2536E7887C0F621600B2352E3660FC80B7DBD09C4D06375CA6AD8227D60E19FD9532BD932A15CE6A79EE821447D6DCD26367CFE447C3FF99A408C2EF4E1EE16C0B63EBF1101FDC0E66C5F5F4E99D277876C7B007F26AD220741967A0023342B09CADC11C0821B4E3B42F708422E36449C37D197D4652260A29BC9DA316009DFD9DCF2FAD8E7C66E0856B16E2DC625DF9EFEEB36D17E56A97E85BD00988581F28A742A85D6EFCBCA370FBAF39F1AC123922CA40EC5B180D40F5EF9EF892E66AAE5AFE52AA7E0DFE6181A0565CA6FC3FA284DA2DD4F6FE76C5F3C89C38F8C635AAE6B006829BCA1EFAE1C06E35446AF3D64009BDD36C17E5B12B5A03A64E6BC2E83BBF6E6C3785933564343950D229072F11092DDF65DD267C9685574D6D8AD15DA4B9C835164E95215045F7BCDC7315374289AF7EB80D538F6484F5BCEDDB3AAFAF69E1A74B177DE4FFC6A869B9BD98F7A3E7109C9DEB78898FE57BBBBEDA72678E7035EB555478BA70E405BF2D3D8563B3AC065627BE1F4419E716A62095E6A7C5A54B22327ADA84530EB5761287967E6D6135F523F01C20349E337AEE6AB7D57379C4E919CDABCC46326E09EE6A254C08440713FE744CEE9BD8773783F27C28F657F277FF4D96FD0A1E0842529D1A55D1120E0B0087DECC8244A655C43D33019A9BFD54ABB232739A6D21DB35D8DB48B8F854E82FEB295005F55D9626532A8611AF392B67B0191530FC64422E02F9B99BB0E337C663230B5D7C92CC34EC68ABD6D9A32657247D4F4E90139DE57CBB0CA2AD179F75E244AD5B4D6A4A21179D5F423A125F3A52DC6E7E99959F3E3DAEF1C56EA39ACCAEE0B4E0EF1549763CEC5E1A138CE4A2B1375A370E04259E67ACA9E833C2D969934F9A494E03F10F3B843C1A24615BBDCD322DCD2E633960393DFAAC490E69ED03E9DA0E748EE1C30683034389D6291D6DF8ABEEB363F5323A20B8E09715EF0B406963FBD178D5F46954B356BF20B90C670F7946516A7EBDF67381BF26E5AE7AB0BB69084B3663E980F2C0F8E5180AF4897C6A0DC2DD052417CA772DB1F48F1336B49345759677AB31980F037FC4B6EB7546942659C5BB685FB2C862C7CA37505BFD34DDF9AE301BD9296F98C24E110E410068916F98D5B1F320D7D29B125FA3601A77DEC33458BE0875ECF4049996544D2A5B35C628CEBAF0370A8F8502FD349A3C431D4D8ED56281184723B569EB08A904CDE35647929AE39E6A112365058D618CD44DA7685D331B7A16AF87D735C6766E47EB49F2D93E05E9F0936E923AADD01DE901B70555FA8E4E16970D4272B29CBC34C1E3B57ACD0366DA6B3D0BE72DB205F8BA635F0B32A3A38B44E257382665C354DD0182C0B3956042A87F6F98ADC5A2E1E7CE21A4E21C8750913DC0FC955F2E482D41DB96C35DFFA5417233179EA6245BC10B69050B4074847C89DC5E8AF80747E9B4A44AD7ACD06D6D051A3EB7B0CB3D8383950BE581DA314518C85B9E5E727FD3136C7A1E5B35DAB57F4B6331F565C66A9753743C93FA31E8BED38A489B16ED62FAF78FE5D69FDAF311A1CB7FA4AA4F0F1E56E3797802AC6F2885CD7A1D38B2C944C47F4F1D937EC11DED2DC2D8893A651D1144629781BF77E94DBAFAB247B4955408FD4983CF62F106D93D49738DBA52AED82FF67A984C749C04CC1383DE98C0AFC8457B9B134B18084549B12F7C50949FC2E5C136EF2CD2A05B81EE1DADCA5658873E65D09E0DE3F6CCF51DC6EC5157EAA10BE575101D83614A4B679B196D19F351B4727DC4B67C5E32843A4A2FB41AD38741847F", + "message": "7C29C0B8E2A111F457E2384845E7698DE4BC9BAEF093F15EB03828664AD31C387B247A525623282460D60290FC479A928024CF62571A57F77B17DB0AC572CB59723490DF79E9B1B31EF2C9488B6D758C43EDD9162D8F6C0B03F43B08D646172A1F8DFD71D4DD805A3AFCF1C4265BEBB71FB251DC9DEAE670A664BDF943ECB00FB7EFA37624953F94CA760013FF1270C1EE7FF58756CE19C204220713724AD03B10F1D6961CDA361539A8AAB6ADEA92AD782F441428C0018D85C0505BAA793C752DADFE92BFE8F033931D47575C9F83547DB18DAEC0FEE90E83967E0D0DC93281000755303F0F5F05DE041211CF842404CD5E24DDFA3C7C83DE3EA21EEECE37A52E16DC80A350B3A18E88EB3C81C74D25B56CDB446F6198DC88F981F2B1ED8DC94194D81CAAD971A9A3933E9319047C5F31530C7C98793A0633875A14FA5635CD1B0441FE267E79C1E874BEA968CB63E20E7C48E7BAA9CE8393FF9A239B5A1D613DA65F7DE78BDB793AC72566FDCD06CDAAF56E18B773737A82298902F7B4890EDABB766E990ED87C94005A2E2450AC1D0192D72468F81DB414F88CBF07707A95F549B7A9EA0760821AD710D52787730EE8917272497E5891656176F991F254A5D582B5975F95AF740421A3C18A82158AF11DB15C154F17ABE1163F997C64A3BD989A573D12642B9AEE87C1612A39A8A4FAF25E35AFED3F2DBFC8FC8A2F9DFBC683CDFA3227107C50526149557CD773DDA16E36782A278A93CD7F4D8FB47DFC37DC3E389D164913316A885C3A800DAD0C57B1082BD4D804BB6A117C3B41E7D8AE9CC9622AE3CA8EAA9A0B502FE3F5A449BA8E768D2C98013F681C68A5F4AD3CBBB83F302457679BCD3F35C4D6176DD8D2B670E87EA291EDCCEEB9917F98CDDF5EE1689DBBC85BBAA30D191F1965EFF8FA9B0073D30B1E2456FAF880110BA9E75E4E29C6106874D32944F49DC7E7E7C56ECB9D287F2C2E87A779052F9B84FF97AAE007012A5EC497C4809F0193C69E5B29940510A354C866505424D4FF3853C94687636543115A73DC407C47927EDBCC4E0567EF4E451F0E464A1385D2A0D740C7327F6E92EC6091845356C2620EB163D9F774D7781BFBC6F6F652A4A2DEC73203DF5643E1B4C3C3DCDF0B4A0B160598EFB56499D2DB1F1E76612356AF3D708F9D61D968A6A0193D9146B2983972271A4C02E2136E6593DC47FDE4FAF2540A8F7744BC3230529AD1C9D2FF65B7671B5A5B16AABACDE8D45A940ABA4171E21090AC6AFF54CD8230F7BCAFFC42C028E6023E55DD02E4B7F976998AB5614A5681C615BF8E9E6959B038188F71C75F6DE44A6B0498F2A9254F3B0968AE7DBB49872D775CB0A5725206D648862734F202DF470770AAD184F822C56400F16F30F8BE40C463CA3EB5ECBB15D51CEBCCEAB43BFAD7DE7679894B90419B65912D67DCF2335212E82EFDB6267EEA331C1439BE2AF62E584C222C1052AD91C7F5DB6AA649F230248A14AA6A532401A28ADCF822089140FCD3B1CF2358DC26939850DB2721750F1537424F6BF2020A1B4684ED79402917D1028C1B59076867DA809D6C5D3F47277755384C20624388EF0AD68BBFB6A63005AD1B6E48ED654E8362B2AF7BF114F2D144A420712FC4EC71D408BE55EBCA8C2F185E7132196B1B76AA7BE44EB55DF7C82C768943D649631E4D87B408DCF8FE470164D9E8DD1F48CEE7F6BA93E239F889119A4DEA118D93F1474E516139036D640EC788AEE708637A619BD1693BAB6C9EE9EE0C495C0D0F8912C0F14199AA69B960F53E4FD8E2771DE4AAF72117A5B2388FEA0CA3BDCD594D1760905F26482459BDE80EEDE3FC89F592CA16B65B27E9A21F1789BD0327A26EE2224C61D80AE8FA6053480048D15019A80FCB5F3B3C6F64C168690E4384AC05E856BF341531045D2952F2CA8BAA0B8926CC41AF2D8BC5A1576292DD67114D521DD4AB535A77E5E9BEF8EA01DDC7C65446D11F90D6CADA94AA1AACFB1BC3551353D09252FE515A465C1879071F6FBB035DADA0BD25A022B026AAA5B5BD420237FF097099CA2402E68E4530F97A003E50CF693D1DFB551DC4695C760138E88B8D11F3075DBF8A6D9BCB9B1242648C0C9DABDD9D49CF132B0766302437C0CD81A0889585869DE92E6CB30C31265C84F58E9437CEBA891422967AA546EEF720A8FCC16EC7591AA0D47998275DF1AAA5ACAD1E1C5868CA430F4FEFA0277262C69311FEDBCC083114AAEC9F99FD98631137A117A9B48B32A6D88E76F96DC58D741395BFC102E147C456D3A78A0FA3D186485D65B4E6755B53D301BD13CC88E75277AF3CCF1EAC6E9C56FE1F10DE05A796A14381551705234F65DD6E717E9EC275E38690B73973C9CAB27DB909C5C13041723BB18EFECAD808667643E87620191008E4D10F471AD153D27F1FF00D8AC6A8C5E59197AECA5AB496D8D10BC79C49D16DC7948C6AF62703D36059587F6EE038820A84C0F287D79C713B066E1DA5B32BD89E5FEEC248B34AA5841E8666CBF09C47EFB17BC82170CCB557D41D40CC87F2E6C0246F0B272733854CE162538DF34559473BA5979AEBFC0D6A16EA7B399687E672145A1149E382954815B41E7E37CC415057D7536E65FA1A35B8EFAABC7B9B0000E08B593496B01E8F14FC950632C659C0A7F7D59787C7FE6E8FA7FA0211A945ABBA5044918CE8482C6EDB366368A9DDB2F2BB66C146BB50251CE61DDEDD8D6A4A60FEAF0F794B7B0DB91C52D7ED1A54AC85D7907BF3A5A96A60BDDD08F60148C0B3237DBD56628982375A67F025B0E3F9EE13DF254E1D6DDDBB057203CEB267200C7788D01342C064FDDE996183646FD3C1ABBA5D2155383CF391FF16C78660D0BBEB549483A4A4A971017A8659616FBB1C3A8A2E83230B610C0C74B8EB32667765F3C2F31F8C0D4BDA3D812DB64448684AEB482DFEC5C37EDE742091EF7EE6F22E31CBA2C9B9A6656888F446A1E9D52D9E6437D22594A830958CACC6F175D4CE8423178B71E7CC81BD6DC2A7F6580A8A3A1207C34D6A1646BC3D89953A63D22A30EB9FAC74103FA527843D3BDA656D1F22E729C3A004B923D08C9CB18CF406FAA89D0D63782C7264D5A8C8078EE6D259EE168A415E7BC83E4F17D9E674154DF08CCB21ADBF5B35AC28883F6943083AA97210C6DAE492C6CA4ACCBFADD99AED15110B10C9904469B4F06ED32546130B0EC4B281622A5EFC9C94B1F2280F251AFCAE857C4E17FF5CF472F038E02E5B7B3CF5CFD2F3969B9B8D5A27C8EC38DCA4284F0280C24F01DD97A618FDC5EB57C45D9E2A05B44E69FE2E47CB50F596030C70B62437F2B91A67FB84205D95CAE259AB1D5FF0454C5B4D87F439DCB7FC62B704ADC7A84502E1BD8E6F52109BF0F36824834D574E07B9375E693AD477A9D74E94BC4E883206DCF875AEF7FE84B9B7C1C9B1858E4BF6735235FAAE21FA566C866ED7C952B1BC19A911984EC25AEE310D8A342AE32F46255E0E00444CB0EE90C37152EDB6C741F5F394B5D47154825279465F0F8B19DDD85B8D9194A7AFAE5FE609A245AD68786C9AC044C008A1B3EFA3A8F4FA0FD49A65B6FF562F33DCB63754BE76244326FB6E416EE3267F93D7B2BDC4705EE7021D5D2EE66BA8D7B9DA7EE6C354E05470B31406DCFD2C32C94C22A72DE90E5A9DFBA99ECA95F73A014A3E9B15EFCBB67FDFA6D3CAFBE3ABBB28C4DEA6AA21F87693D68F0A60331786DE02BFA9E85A8D2AC8524EE184EE738BB3FEFEAD7E19030AE883707DF67ED12E8757B86E6E5FBA26715DBFAE2BE0F90453868931629FDE97712E08A280FF8888007AC27DF2C7113C30604C5DB17538F026F17C7F07D2A94AD5AB367F9CEA87BDBA712363D11FF5CF0590030BE9B342A7ADA48C08BC42F923DE939DE79616CD346B3511F41CE695B3F939C101F687DE7292CC96691EF3F3CB653F4A67D2EE09C791F993C726D574440EABFBB00E5E6328FA70D69FDD5F2EFFFD37C9902AA45EF4E9D06059B0D8E3686C74C94CF2F0032ECF740B31E3F297F15343A0093EE0B8D7F8EDA1118D329D05A1B992755181429D410771E37B56E28AE2ED8C4DDE8422FFE91ACE348E443640578687C57D79DFDF917F8E60E0A2F1C6223056C373F58C297F0FEE3060D31DCF6851856D1D05BB38B1FF426BADA10FD84B2E08AC149F91DDF4A5CB38B290DED4EA3B02EF7A3DF42BDC6B6205D281CE4A48A1C13FA8080B6B4100AA123097A4140415EC7CEC57790D6EB0B4200AD3DD9FB7FBD056A5E3E9D7B7EF47F44A63DC908B6DD8B020854618F7662391DFC35A88F4F5750D282F81DDC50D0132707174914293E3655BD2942C09F88627C0AFE4B921B766BEF41E246FD23482B5B14F117E8EE340C47C7C405BB3692C4C9E541148C2B38281EF0274835860E19C2D48953545247BD1F7A76CA43956C069A17CCFB4D0B0FD478556A209B5376BE9207AB174D2CEC96E09E1F8C0FA07D8920B2ABAC3490216DEBC67030E9285B3EF6767AB11E8CC935C4019B7E68FB9AF8864358E6927D350CC8B9A40662A0987C1C8877AA9903CC89A93E1979ACFA279FCCD2E171A467B76E1103C4EB166273ED7B4878908B67DB77C4FD4E49DB46109DA4BA78D69E03B48518F302647B8186F787F4CFCD87CC5A45B98F7558ECD0612378306C9D69FBE23B06005CD5AD84F73A563B1A3C7988CE0157D2D2703ECA8575D8BFF972CBED32A231395655DDB2188BFFB413624639D361B3388A9C9E13645C563A87C610F6FE79AD50765CFA8149E27F7083A316EBA050860A69BA56D002A78640D71794980C83573A5DE69A697C2CF2E17C90BAFAAD3D421C6E1D8A55B3FB4700B666AE3CC3EC114E9DB428F27CE427E4101ADB49B84CA7855458841DD1F4FE76D9074D940102FC47EA633744C2A664E22B5C5AA2721017F3FAAF4FB033FBB1D508EB98E1D643406ABD4D69C030A2349408C80993D9F75271F913D7417DA995443377E6F73A7DBA24E034A9C4820117D1F0BD69C93FF55CFFD2D36F8078209F5711FBD1587435517291498926E7354558945F721D00A73014C06B2C9BF04B7E695B9109D769BC2172CA7A70700A1D5AFF6F5FCBE699FAE81BC34B0495A82BED01B983444224B4B860360C07F8C3035FC4F0C4B7DD4D37ECAFD32E8C121C677ED263338359E25BC4173D191E869ACB4A5F6D20FD16FE50454CDD269DF8CBE5795482A2B40D52BCE5FDEBA62D9274C9C67127580795BC01752740E606D849AFCD6ABB8340613C61A764B6B92863779622E40EE7A8994034E7D303F07EFA11ACB70419A53897ADD558CFE157CAA3D47917CFE0287500B3D70FE42AFE36853188BC815CFCEC9F56030C83E85C60401912C14A75A082DE2E0400F6348EAABA59312C51A7E3B6A5B39D606306A304B4DD3472C5B89FC65DDA54650392A02CC6761336FD114D848BD889DA4BFE6D32931793A6515510CD802E3D9F2C6F8F2F9DD96ED039462C587395C7E6861FF48B7980D492C23E0635464C7D1969C12A43BF0FFA3089E6B367AA65D4678A571A0D47A75056B34E3F8819F8B6ECBDD6BE580D423D902D3C22D9D787E0F1B6202DFD392AE028292795FCA0177CBCB09AFF8B579A87A854432827CF797E494ADF9F96A56777AD6215F284EA91D35563F25355D12BD155C6C364B0C8423E1BBC809E736CE0BF03E0C0B728F04E6BC8F3F07A0D952AC9D9530C77547B687E193EE2D3565AC755DDFFE880AB0524624E17E019466B7D0E8FD6E94AC2BEBEFC617BCC5D529C83A90D36D57A93BAA0C2ADCF360377C9E9D58C456FE9F3D49CA37A8C3B5BC7C231842B57D320310943FFC0ED2F5F622988ACC7842F8410BEF0E0671673E7BA61AFCD2EA83CF066A169BBD97098F4B4F3C9FE73F5CD779F502C584849D1AAB52D7059D1D4432C27FC9284FBBEE43D07493A38B139152ACB71A171D454FCF936656ABDBDA03DEF3C7B27891088F940C200AD454308001FEB2DFA0FC38FA74F85A30DF4FFA64DB48E7D40C158F058B58174F18BA482AC445A6A63FB54CC6C7D4C8089794E8AB5B38C41C7FF4C6A8A5F294EDC3FFCE3C01F2C5C7FB569CA06567C8D3BD34F82046DB4EE7F7491D890DA1FDDC55B12D90A7853D8FB52E86AA1FBC669C7ED349A2CEEA9EF18F76C23E817AF58101BC5CCB0346A607D6C60BE5CCDE5DB9889E040223FE98B17D31D64E8C1456C01353887D75EE3B82D66CA0679B1C2366C44E52D73B09D48A39D1BA3FC87D73772DA601EF442208DB763F0BF888D28338709FCB008B83671442CD9F7ECAB2C1E26428391E559306904FDE5BA21E1757D94F84F18A5FD8A067C556834AB257B9D2E1290FE0ABD3BD622A2AD92BEB2C6BC61852D58384A20B7409E4F212F630BB280A46CF89DD702B2508752D6A4DA94BB769797B6E7FC318B0B3ED50D7F8C5D8579526D536E4D43F93C055479D53BF6159BCEAD8CE87504EDF7DB35E1D03EC7B4F13802AAE0207A2414802BECEA39664110A54C37415EBD7BFD5D73E871587967F24EA34B7D06CAD805EEDB95F1023B7BC3A74A59A6C9F3A4737FA1BB087012E0162CFF15A539E86AFEE30144F320FBAF088C6884489F84F16458755561C9CB0723CEB6ECB134083C3B82E93BBB57FCE8D51374D38746BECD09A059AD6623EDE82EBCACE009C0C27D5FFFCAF76C9E91BDF5EB895FA1E9C3C0AEC0BD73B1582C067A45CA5D15E2D45E7316CD4B176D9DC7241B05922A682DF919B2D2DE2F45942D3AE254FA55C5D90B8DA3C7DFE2DD8381AEDCC9558566E8DF302022FEFE51F23AF6A018AAEF3C93FD608B0903376E193CB1C13021808ACD538D3426F9B3399686B6FF4DFC0A4552DEFE49D042BA76136719D62884D8B93A349C22E0320B823740DDB3794AD53312DA5608DABACF69767D76327BEA7A644A304A132F2D2FA8E7C8F4AFAC30E389A995C0A2F912E98447CB400FEAE35B3BE089F46CD48EC8E38D4F2BB44F1734C67D5125D7266AEE3E9D1E91F800ACF8038D43B6E10750DADF6CF70DE75176A2E9C340BCD2F6D87F976AFBCDAF5E35DA9B268D3AE1F0F8172A342CAF9602593A5ACDE03DDB482E80B825A7E91E8B0EFC1C8D00309BD170D9F12BF5017780A54F440A58BE4A5257AB67190C62DAF9332F3594303B419D44A38C3A8032E38599B49872D241AA44905CC851DDD0750D04815ED88711353DC2264C0302DAAF2FFD34E9716FDF8A81F7CCB5757913B380A68F153F62E0BA8335F8525CC3A20145C2416581612B9C29C0B1B941946B2624731FA50420716162C64AACFBF94B43B10E59E0AF3836A05B9335B0C44370CDD2E45BA817631FAFA2E0ADC801772F6F71860CC2623E1A802B370823D02442108E5C142B68CCC9CDD0BC2EB9B861D763C715D516540F19E70FB474E120F06BC19A6629E8DAF67556AC60D17C252A44901839143BE5EC76B834FF11DE13762EB23843D3FCF1FF9CEB41CB02DAC74ED6219288575FA294157E532BD877D1B711AF3B98CB0B4BD7286F88C6C00B6AD9E40D66F38525156A4AF35F2FD42A5F25A201C66DA4AB5C4D1517BD6CC9FD9764AE2756379D73C8D81CD044174860FEE5DC42B4576008F13A3504674E0D224A9F1AA780C3003B7856692676A5E581418C65BA9F049CA20C3EFA566315DA220E837639A899ED54A07B5741097C47FB90A81A41700BB5C0D8C3317E27A0A6CFA77292BE9186396BCDE5C654C565754DAD120719E571A4A14207CFD205BB4A66C02CB68EB9E50DA7B1FFC324AD07D8A8A54729621776FC5DF15CA39F3DEB6B810A735CAE0E1A84C6842E80D1CF95FDF5A6FDCD613C54DA1CCAB4994EBB81C632D192CA9AFD7FA662A865C6F193B7029A9B6F21041E3D13D50E5A1DA47D3D3C4B101488D2308954C801DBAE5029E866E869167BE7DCE6476A64FB245247A84E46B5F0D9FA9F7BB10756FDEA659788C032AC654CBB83F23BEA1F285DE190BBB5EC4135E8FA1B134DB5D1FFDA08C06682C2DCC51E0D848F8CAEEAF51DED21830730F6BACC2A4BACF7BA62D14B009116EF2D157F64A7ECBC971D50349712DDB0871D007B2FBF83A832416CFABA2B9CECD37207EB9DB8A017AC266A5FC28DFE64B52D0CD7FD7498F718B32804CF98D2F17D22C2957782DD83F4FDEFC8A6AC5B6A562C939D2D0A0FA6078F7E6B4C95159BEF010C1DF8448158BA29E1FD1AA076972E64A9D534B1F27930BADA08EB87BDE6FB0A691D4379DF0001D84F2F833050E18869F2FA7C00A6481E4F87C75483310949653D6B91FEF1116F25E5EB0A10C8C8723E9C1C80F75C2875FB0C448B3E25E7B359304C08C310148683E1D8391C432A8413057A7AF45289B1363EB203779550FE1F074D3B4CDB77B90700E3710D6EB4BD1FCC209F2406CAA67B98E44AC91B876762D597D0F03A404394AE81BEF8F54A1A898B2F0F0CC3D3B6D84D759D1F1C5788BFDC7657794E384ECB2D5307CD92F3E135F35720A44743D93D111F38791B60E7A64F51ECD6801DE0ABC356409D00D7F785EEB88FF3FDC801C94CD7972EE402217DF018958A79DFEE835B2E7C591D2604B83E2C8B3CEED7BED4DC66B66EA13BDA4FBF5DC3158035A279F57ECBBCACEE3FF346386ABE41D0DBB32E15B02C49D3F216DB19474D295AE0A8DADD1DBA9AECFA9C92F0429352B558F69AFC7070DE8D47032956A9978AC2F388DBBD63AAD776BFAE969EB990E72B7D74A0D2002CD3CC664E77E52", + "signature": "81D31B99FCF0F04C0B2292A8CF472AAE17A659C205B067FCDF9FB4158C42955886D10F4BE022BC564230D2CB21D9023DE837E9ACECE2AA7EFD77E8335367E9F43A4D4526F36F336293FD0D372E81669B04DFB4ADF2091D18C1B2649B751E1877BF3AE489862C22108B02242EFA218828F53B317CB6537B2794E9559D2F93E3BA9ECE302BA948DC7C6596FE4BABDC3CEFB7F750C8B4D041204AC0F185CCB264A76F81A1783FAB19EA236D41842D9DDFBD2028DB890A652FE07836FAA7312A287A920543B8C393000E03F82FB712391915D75DC5825D9494C6E64122202D002BF7AFC234B334B12C164911D63333A2060B8D44DEB4B7E1B3E24F8EF98C09872AE4BECEE4561316B16A90507B25A20769A7CC25DAE276BEF51364499020ACFF97E871AFBBD68854CDEA120840FA1BDC1AD62283159E19938BAE5B2CAC8A607EB2ACD1B77FCFACC7981E5DAEBA3986B2E918768204D2C0B61914FC6C14A5C36090E52084AE245D9C6082FB8C3B5FDBEEA0CB779A656C180A01C0F188C2B4C11010B562711C5A4F10CCC39BCF5F09509BAF83D98C61E3A35FD7F483342115D41D8DB382E7E5D161711B8F718A2730D73ED7EED07AE04313F3D29D7FD68A92A0706936565924473CFA0125CDB2A2E22238F28ABECFBC0BF8F5E6852E45F24A55E54B2F26C5B9D97A3FFD4CCB09AD244D2D0072C575CD59D01EAD49A55FC2AC8857375ED477BD9287AB0F03E83BB29F19A6C1FB8A6D4B510A55C57ADA1B108785A16C52C71549162B7ED916B8309EE880B9B203F8E24B16E3CB4C774353D9CC9AA100BA200F5D197640DF6E0C0FEB9361B6E59481CE285C3CF2A54489A48B568D115FDC3B182D8341AEC078BEB288F0916C651BAE7ECB5EF165686819CFF2516AA90FFE3FA621D24F43917C218319456D58B5EB1F00437CFDBB66266C15B85CF5C28B29B1C2877F551E5A0B3FDB4852AA17B83D93183E82280AE94DF3136A82BB09D21DA75C6228DFA56AC2E538050B1155DE4133B40EAF22C63DF128E5324B4DC3FDE208ED528D4772C1ECBA1D11107CC3B8258F2BFB9CAEBDDE1B808D1F909D834D3ABDB08A2129B15A81DD01B82CA4303902AAFC1FE21B7AEEFCA8AF1167205142C65B41A8124C8E2FB6978BCCEAEEB8C701A97A311B87C9F46F6B23F8547EA728D46DD907DDA37FB143A191E66906B9715E6FB4D027A6F2B4DC94A38DAFB229642310FBB0CB28BB8415A9AB0B16E78F9F77737D0BC377F6E39AC869743067A7CC49A0E6974D86346BD5F91BC3D747A659F35FC133B02907E0E0442F948E2124AA25209E61F5209680B2E2D8DDBDB1A7BF0B8F1D17726D21C8730875255A401C381157EFF65CECD067F05EE56A9CA6986601A0FFBB473228EE9A64EF04196A78D4B5EC68F9A4FD438DB71E9A8FA5D0AC28D35087ADDDB4341C25AF1A0148D50C5041C87A508BC0894F073505880A550C17079B255C3BA5F58447C51603A599AA7EE288299551D339611935C5EA7F07D51BA76A0A9873635CD7AB35F8EB5A25A2B4453A2EE917E7103FF62D9476AA1B0C64777F4D05AAA5240DBA6956E1E1DE3C0EC1774DB2742D5DF8A6BA8E287631AB41B948954C594A63B7156218EDF19680D863879D79A8E58A1D5F975A35D589805B734C6ACD3E23EA920C8C1A9D8389B739CC3EC34776D2E816CAD3D6AE89B29CAD96D707E7D31BA731749BFAD67FA376E743920E119C11E29421ED033A1E73F2F522EC23D097830FA05CD62C432C70B10B9843CE2D49A544664EBD22213EACBD40922F1C3EE99A3E393CDB38DAAE81027F64FCF273846A9A789A76A50C79FA50A436D84FFF7DAA38DDBD5D40370B02ECB6F202261C5B284419F06CF4947A319753B1132017F46890A129E13DFC62DE2AD552F0931036F5296BF394311A7347702EB998A8DD6643EAEACEAD0DAD94225623F8652BEF131B9D4B0A6F5E7F4ADE344AA1D99C764DD9F9BDE6CC040FDA976BEFF40F8F4B0C5E6B20497E209F08290006DA5DD81AA46C5A0DB7EE7241E2C11CC411E4953942E2BE4CA6A61FF7C21DF482C8737012879C2B3AC90DA6EFC2F27B8507D4393D1647C4331F307C41038755386C53218818A255C2632A6DCB9F589BA53ABDBB4F7A9684D8C622F0B5DBDD8BBA59F92F5AAAEC121939263810535AA0D61A67A344B7B98568C8567ADA14B09BD6E021B1F8A0CF9B6DA08F5A1D66CD1CA8B0641FB300F11E3C4B7236135F4B01E5A50416B9BF3B7D88317315D35FF88A1663965CC183E4E34E4130C3AAE8DB39F3491D85B38C68C1F818DA553FFEA24595F5897071C84EE46FAA74FE240225EE1E325D3070665EA89F70BFD998F080C330E4759B4E79018DAB231BEE7BC73C20117E77A76BBEEDA3578CC2B26F03591E314B0FD26DB529BB0E6D747058DEA808B45064B832F3B1008F675CA2A92B5D38B464C5CDE4E570029891F83975E063EDC4A9B1A731C36B5EDA5E8F5D7ACE5F0A9F9BCBCDA5549203A9268B156DBA17E38BDC3D964CF11373DC778A24FC27613D39E4ED6311AD3E307BFFB3A1E45FA8BD2268C0B674368FC583489473AB3D4CE941177A3EBB06E6273F3C90FC5734514C4D4284954F5ECC0853523DCC3681257C1EB15B3F7AB7FE42D70899418D43B0198C971F9B1C069A2B443DA2C8E463CE510EC8B40A366B4DE82E2A206D7812A9EEC1AEDF669A66AA4F76364DF2167FF1416DB7710EEBDA11B0E8065E8D8BACE915C5282E742E0F1969E8A2B3FE29DF8A9034A2C2172B234E39957E5BF6DD55EEC3C4EA1C694827CDE661870E4C858FE91AAFABEE9E28AC3469B156DF911E00E31B44C2DBB43FAA617DE7782E14566DF4A744D8255BB741EF9C5842DC5AA275C73A7BBC254CF6E9CD1ABEF1AB5427CAE5FC4867BFD1D55478C29510493BF720C03256FD7F10B9095BE2AD621D8C2A6A667EA12DB50A09A4CDF0EC604ECF6F73A371374059F00FE8F84BEB0EE5E45ED467F44479E7761A20A06ECCF795017D46D4F554E73F3B79B4BD7DBF44217938BAB271A50F40871C6AB4E3158B9BD4B12861E9865926D87D79508AA23C085B616938970924DCE2F403F0297420B3B8DD6EC376600B1787AE8756B5CC414EE213DFDA291C4C94E4C36C9530305BA904EC6C61EE75E5C4EBCF557DCA2F01643403B5F25611CFBF3DB4D64AD5FAD075DF9BC3C317E0E4E6BC398C6EA02C58F4CBDAEEE9C66BE30A0BBD3F23F2C9528A54C080129633AADDAC8CC27CBEC1CCDA9D6C6A5D6E1C15F9F59AD01BF1003913185BF93B398BE28269D04383A3EE314D69A07AE8BC1E036DA3430CF772EC00C1AEF7D7B73CBD2D296BF0064A53C75C24ADA36D60ABC93CB271EA846C950BE8A58126DACC14295629E08403DFD9479AADE091C5C71BD234DF9F35B411CA6107724BC00E6837EED6526AB76D3E1AE0EE47FECC134AF895235F5E5C42EA2FA02381550240ECFB60AE9A37D77FE8A057F28711D25C0BEA2550B32EE8E926E539C499ACC781F9C3675E2D6A0D81E10FA653635CBCDC6686A8B842718E327A50CFC15E68DCDEF46FB3137A6F867AA63F97F489745E735B1215669DE7388AAE461A01F9DF1EC3DB31B7588D2A18650C60FB08CFB59F11283321E208823597E9AE5384755B1D106ACAE8A1C3151E9AF98E252A10F068BAF2B6116D37BCE404910DF63DA5891B00F5C8968D1EA70E54F1BF8E495707197B086D0392EEDE6AD60C5D4B9B108467435C9E0ACAC31A7E590D6A36B22EF1582FDEE7CE7E378C089AB6B8588325AAF6063D075005AE65B09929F41DD70B45B53A50C53D779BD37923213AA91A2AE0CB6D979588EE8D0DCD15E89929526574A5F8AA538CAADDDDA257F15B1294E6C85A2BC8DC3FE08F0D87963341D630238F25516990A79E27F2564439EED4C359FA83C3B7519928EE4268836D8D45DDBF62E4A9A0DBEC3470261EC5CAE7D0791C0E976C287340724D88E676B79B33A035D93C5BDBBBCFC0B6BAB952DF2A1A975C8CF7380C98AD3428C795AD3DFF70E63B5792F993AB4642BAFE4EA0771BFA24020F0D17A65E2E6F4F77A0801AD4C59FF3BF6C8F837A9430BD76CA46EF919CE743F685570B95667EEA2BE078AC45C46A54FF51D89E01A3726B23B5158C914B7B7E6B33AD8242B32514F251873DEC8FDC8BA607D156440326D4B5A5C5D676D0098A73E2A25C84F09111493727FE5D04C8B1FB9554AC71A3101E4CF44328553A23DE7BA2AD3C2FA9E9539DC47A58CE3CEB6E51F20C87AC6B2B14CF803DDC55A2E4B5D37A322A49FA38BE1B8A562BA7D314FBFE2BC2F58B04A3722EBE4E90FA3AFE1E80E4A5602BAFB9EC70739F3C6CC223B790C603FDCD188CC5CB3853DE9161A2EFA4CF3553BE3E23C386C6AD5BCBB7C7E497C30A0BF906B6E35585A69E327ED95D25107911902A3024C8B404034450B19254CBD832DE3E6FD46B3C2C602C5CF5A93D8E966DB63D111938C3BCA92D98D40B6B023DCE484E6E958EE5B2EB5AC0275824391F54E424F4C46B7E572F263E3B727E680556AEF3579E1AD6A0A43E764BF519711B60CB41FB2B85E34BC970BB3F98DACE7C8C1CF3F7254DB18B5DB18AAD3BE4B098911484D323427F8897CBFE41508DB7D501818EE418690134485A7DBDF4177C82A8CFDBF00000000000000000000000000000000000000000000000070C10121920" + }, + { + "tcId": 28, + "deferred": false, + "sk": "8BE522B4E26631EBD3EE598B51CFB44CC1BCE4693E87BB76EF1B3DBFFC2762169025689CB13EC243DCDB536B5592EEBA1C9FF9D3162BA69C6C8445C55561A1BDD5DAA73A89A567873FEEA609BAF57AAC39B28C9EBF0DB477CFF938EA069ABAC4C134644525C179B81B69A61400FC131632F9389409EFB2DAD28347B6E9DBC50333478537234180110216703713666267407332042117167285231861686761441210671057343688833122224741016000006637280104670885810336860677835038360856671708501706307554348172486017384536610442118411464278512074201323472226152744306444283276447347407701534240455752818374185812151275332674783343510375328081677738151215483531374201701647010142025428074334717432007611874182847823042007734883110521200373123872310064376640658218187215811731015263781030348654333721768352476037106520857001157228053468718674413501266737641245546154041643241410501404202331467303823172738661537631326412120620535147074330475675267385001422576156865466315087754081624344371427068152314726807147108662880315204371650357351315826372165054702134004232425418802463830782403784381115563683351588142725828012118040033543738720206011440856443223582817212677271158874776566724605581535176600567745870103826357027573672874654377285231557526888232382155662024100070470030473727043681088635050714638852408071501850808072334837044106823681822708546272403308813276035006162706663335231815226264468284147368331351772564002623064338284502177258683770086532412113081781761102623530322278262028713438163458525017410602014725837473653188830358083120808408517263643700355801282287367867716818464087758327804282311206361315488554266670483253832715616163087472867038811365080210210237462345637776788467178451732482673618811867731483512036158155276111185373836686408334604023734277527830555045716275074072450108113304336412220335448801703313347077660185246467603160827384258610827786040227788358515276647106422642717356782036318301654248323637160122662488623837433257521667160846766448032050502541655122882873257375732786387202663327831411364154328330125623422884575626558307557713473653281565632108110853544346667326373177215875188880426237318478516556653371343073506220865321058770816713770387242752781203737258042510133435774100138260342867165785468418463736503584203606438045376454072080283716557465775044371518453200301088283116123715262003810840120273260615472300483880225411134203712750473122131553667405410661065824344668381608711445062248365838180162845050471728814083565587567605831314536481816873614238866537046728070145831458843035350778852054744668616084188465173248757877750305585700014307233313471722355344716426435421467416072887431031342617388642656086537070667614703030736144320532164032037145102411420812042582084583621280125835662622287314366231327281824842763423073663418856204041328103787818034738187202808802170064570017265628525011080747850142683771068084483578052255237768183672270141750243375737386806347814658588856114864068441442642086057430676653065800650578614485827138703358681848874801543363582130444225273015665625525034606073587464023021552772813060801271401248635688136384706617355687552587855202183037066184600586417823285581816200837FB03CD1DC103C479132483591620A98B17B885473B466814BC26F9F52D1AEDBB07645BFD9D05B02CF3D37CAEBCB8DCE34EF4185699343A4DC07D7EDBF603AF8D3F4C79EF169BDDF5A0647F9D71732FF65A8142780E5ED3EFDD4FF8D496EA676516529564718CB376D9A8C922E038D84995A29661A54184BD3A32D2B962B3DBC167524DE2C4B07765B6BC71CD4A5510C646EE0AB6892992E341EB0E54160A8939AAAC4C424BE9D7D1B4CC1FB50B5731950D19B96E5EBAB09398CE0E476AD189004829896E131F1C0231CFCB374895A47684F063B821FE0C8DCEE3B2BD5DCE499422AE0C668C267A65735F7A21106FB7A584CC2D89A097DBE549B3FB84AB8351B6A5F61ACA27B4C38C3755BF1ABE272030333F976296E482776FBAF8DAE13A0BCB7FB2992F74F178C4CDEACC841B74A1A7355F6E09B0F58F9DB2461E26CE24DE7F8FD744AECD3A6053C49C7F23C8F7F34B35DA5D60B16B81AC9C9FCC14A5DC5DDAACD10634929E6540A5AE3BBCF8BF7A04F1ED438CA536279B58FB02E1BD481D9CFB6189BEE8FED30D46AAEB34F7C4DF8781A38B2C40A7C7C27347DF54728AD8B91C4B09CF48ABC5B392DC723E95157F1BD0DE34A76ED0C89905F4333318267E4BA6EECB1FF87F8AB78AEFF5A494B7323B34A019440CDAD40165146370E23928BF831BF0DB4A498AD2FD15A15EFC1A56F656E8CB58E93CAF38EAC61F3E030EB00EB2F9627514349C583E1E2D93CDF6775DCB56517F92D89530D29A55DF17135AF8014C34645BBA8D9DB19F28064B55AF5520841E3DBEAB3FC4A4AEBDB1C431B2F7A83D4968F120DF098B808DCC94D29D26B8211E489B8EDBB87A4CEA0750296E802796D1647A97093F5988024F92FAA1E857AFCFD5E43021B0AA190DA6D581D654DEE6B9223A31BDF5CCFC54178AAE8F4F72B6D9B43D758F95DA0E4E6EDA271E2C03F1BEC31924B827D933BE6634AAB033AD507ABE2EF144A9629C2CADE0B491042AA23005A25B163990CAE9E3F03F2B994CD1CF70716C4B0D1472185AE2630DB3A5A6F154A60FB7340087C554011D95300323AB37681931724326309355E5E767BCEA044DBF1F2BD2645A62D68448C1E978FE1AEF1A178D743DAC130CF4912F16D113C229764562FB8EB2D8496C1891487FB9985208E2DAE8EFCA29DB5788D7A623856F14E41F3232B048C794500DD52836C45AB7CAE336BA311DE88E1F108242DAA925FCBF4801A7D5D400E9E98B15323E7AF30566FDFD118011D1A6C8F795BD263BF38CBD66EE93F0D7DA35C276EBB3C7A2A511AA852C35E31D0F7EA0620214618B92A48A50262107D875DB22A5E6B33B7189F6F6918E036FEA3E7A918F59046B9ADB01B074DAEB58A775E9CF56E5ECA2D521298B355A8FECF7F8EC1586AE72E3F8AF3578048D735D8D750A28EE0EDCA3E3FC303613177DC3F9DE2DD92C583AB35866EB46DB11A4EFEBACF3CA6B9F87CC6C7819CCA4A3E2B7D6C5E9A61FAB9185B91CB90631051CB64E61EAD02D98F4361CE57A5BB54A21FEFEDA318CE8F384464374C8F4FE706CE462A38A2A340ED573E5F703B418D1EE2F71539A1339FBF89A553D4E3D6E309FA50FA08F9A3CA504E8A0066E0AFBB5186E5B3E7418DB1F14E73FD481B984B50595BD937E5AF3F735BE67B2F8E3821EB5B28A4A60A27B382B2D4E84C20F6CAD8DF9A200F819A664B560086BFDE6E6C0F76A651E286C4B0DA27DF31CCCA6D2101501250F251EF1D034B256BDB4C75ACCDD7E4A31EB13A71CB44187314EF2576383BD8E8AF0594E9FECE0738544571D241F7C0EAE00D9EBEEE2B63BCDCE13037CFD515A63541D93B3592FA483CB4E4121893BA48608C109358DFBE317FC21724FFE6F862EB5687A76F56A5DAEB3AF226DA6E66EDD79294595A7BCB4A1FB4A54132B8CD7EE4FBE8658355DC420F08B4C9412CB0A4ACC24CA5E174316A8B5692CA8569ECDFCB37452A48ADE1956C52FDA1FB81F507CD8654A716AAD3C9D8416B99390A190BFAFDCE5D2F054952795E13639CC0D509557793E64C2FDBFE16B19F28A67FB0787229D5BBE5C7F85BFD2D257415C4E024D72E7F7598DB32E61F91FD68A8ADC38D558D2AB6C0F748E7D0EC81BC0B3ADCAE6F9D098A1F43C1450581C2B084DAA7850ED84C76812DD7EF285F6A530EF7DF815A4BC54947CBD146296D615F5147C38EB5CD2BA842F1261542B5D75A41370860E8EA881E2E88FEEB020AD954420AB03ADF14DCF24E62DDE75B19568F06D9D418AD71E881613CC755FF3D11BF3DB0C0DEF57AF0668FC38F3FC9256DFBE28BA606441837B5B0EFCFEC92E6F658908CB4326200175B7388411EAC613A3A75EF8A1F856F3BA32DC777C668228232CC04F4FE6E9089C8B3EB9B4A74A9D4740AC8F14B5FA73C43B3ECBF1D37B50F89855DF3E899A2B3D277E6C72D284E075C3FF09024C3E5FB3B7349656197A468E75047402ABAE724094CD92170F4809160190D1F3844A0200E42E80D27A1A67DE1E2B8F2E10FB0B076D7827C0116E6A2319D99CC38E53A14F4B31BD4B2BF694AFD629C0B12F41744905C24886F2A7D1C23B6E3141632E1F1088A85CD9F6AF9A005576593C9CF6CA4F94BBBFE860D4F1C2388EC112961636CCAEF5D84157F8001BD3C156BC93C5B2FAFCFBB67406201FDE2ED395A83117E2735373E07C0BBA838ED01246022DA61299F080588E58CFE32BA6B0FAE8BA9B4B7C3DAF383EC14335A4CCBB7B1F2CA795A06C02BE537FDB9DEE0B46D54408AE45FC77DD54EBD248623E403217DE8C67B1B3993B23E14C5043F310FD87410699FE704440EB35903ACAB6CCD515880244C184EE43BCA31EE2DEEA3A5454801EB3BCE0255E85F6EFA63877DF43116EB900523AC48F662E61F7971F00CC0EB44D1E6F33EAAE274B8A618B0C0A402DEA2BC835962EB45A60DBABF55744B890301AD6FB863E84513F7022D52C9ECD758261C58525BB806FEC444D7BDF7D02C25EF70F9CC429EC33C7516FC84281684F6A9D63909A6419EA190028F20E301A3230E5E7CA25E86509DE71962E7BD91025E18B194F07DA2D32424AA734E94D8AE3E6F2099802700F37DC29405D2B7BE4CBF35FD58EB6C8DC6EF969114CF45DFF7B12FEB37B16DA34D133A95A6309D1CF28CC96D8D3D581E95B2CF94E737A757A36FE40EB11AA0F3F913C1B7506C11F59E046082046C906F5F25F310DCA23442E8423BFA4C977295509D6C8B2FC30C282CB561C60D44177A1F73E01A8E5F267BCA5A5C652F09E16C35AFD2655AE0DC738D70571C4E48EF34DBE632346F804DFF6D565A542BCAD86D0F6E52FB7F9771E850A39786689E1DD8E463E75D64E41456DA22D44D1BEDD3629D0C93143A1D67718C2863CAB7B63A6823BA00A6BBAB6C6089982D780A944B7455148D7DF8976D31CD9D13FD39216182453CE38B140AD2B621A71390CBFBEFB55FD66B9CEDC8F68C9504C0F28DFE00315A591AE709DFE9511269917CB4A89F89DC1E4470A162F89C45561A362A7A02F5FB4A8D82317CF61B533243BA755418729", + "message": "F55B1A381D9258CAC6DD7B5A57899867FB659A56873F31F815716075DBDD56D6D0D1480AE1242A17485AD259BDA2533CBECE28A906271A3E65FB5D48AAA124993738FDAAC65736230FA07EA27D96F372B90A16FF778D0ECD7C0F62174839B8C7FC50F0B0150D47D5CE9F3715F5964DC712A681626821EA27E912B80D2D04C346B67439CB5E06193B6D7F2161B4F8E0341D8F1C0C7F6E3B351C4EB62E48B555EF00EC0DD5CA6A572FB201D1A4570676A04000C382F4C332C34A0436B535CB3C3F2378682A982034E01211CFB23285395204ECF985F478686817A5F6FF4B694082B3032990597A8C3A85B7FB5C2C49694103811F754DF0434D09C1A5245BBA980D6EFCFC9BC63DD42362477537C6712ABDC952BAE377AE7EAF9FF0CE2E9EEE82FBEFC1CE56063293BE659624CCA0E23DD7EF4412DDB587CF3C5302CE5AFB39BA8613151A04491901DC30706B46EBD1B26D4ACA67587595100AC51770080FC32ED0DC109D525088A2579D8873C6929554C30BDD1E2A0A9797B1676A8CEB719F64A336FDDC3F95BD4A68F472F00C4778745203E1A7736764CEB94F33109AF197C98D94BA3F07E857A5B251858ED850E7E578057E833A2CF95D7505C4973B709CEE834A40F32CF07AD1861CD46CC4DAD37DE66F8037DF1B14CD88E62F81B9DEC286BE4968ABCDCE54F83C5E9E4FFA8144A5877D75FDF75A38ECF60DC180E9B72F256BCEEE087F5AFA5C6D779117070ADB4A671839E8032E55AC52E806C82AC16FCE76A659D6CBABBEC066782C4C068AD4FCD5EC425885A5CBC5A4BAB43D1A60D499C497A2DC06B136A971BE8ECEF3FA6606252029FE5B33661883608702542F7EF44720466D91FA1CFEEB9D8CEBBE4E252CBC096D99551BB90A0534D723B02146FEA94D1C1926221092B97F1A143E6B4D5A8438239B2E2842633A6D90A18DD67D05B2CB560BA8A964E0A49BC1987FF47895D664F92E27F8C90059C5C38B02B42D7A179A09B70023BF7D664A94F7289B29FEF89356BB51959FBB82562F6827CA2A3892E934A9F271282C204BC3C6B34C57882EEB552DEDC0644B43FB28284FDFC82A1148447F2457E94EC0437CB5E0E3B6AB7F7E48F0F53C80D7695801DBC0E96F9C00A4A96AF8D60676DC4A6A6D97CEA344D7E911BE7CC9CEBBB23C562BCEC6992AB1148384278D94913DC4BAC4F73313BF83CFA2591420B18429D1F88D68443B960F61A1AB8E2713794225DF2D4EF88CAACABF6F095DA88C52C011AB3A07D7B71CF209BC84DEDD7FF2D8FF02A0727196D50CFF6520602D9FCBE57F890D19EB7845C6529EE5CD98AA2FDFCF37FD7472D1491FC5267F1D7E6E91EE891D880D5EC20FFC761344BAB59A327F829ECFBF8E550208976BDCFB75BCD996599B68CB29B27D9EF68BC975DAE08AA121F4D95805EB89F2E8B2BFDC61058740881E9B403C54745CF6D4AA1747EBBA56473D00FCFC62B5F5DBA4209E0E7473A0A311619437D2DF22F1D5BABAE064970850CD51D4A62A51E9B3D3121B766632B18F8B7CDEF40B249812A6274D4C69C9EEC096044026022B1FF055A05B6BF1C919230723A952589F540E77D7D24A413F542E7E0D3F7F55B8B335CF3693603210E979718E8CBDF76CCED68396DEB561EE27E9008D7BDB428BB293E1A1BF2675D8A4568D3339682854BCF9E8820A084C94D78E5D0938D66676ACAAF7B411B466B6588E9E2B4A387D84F23963E252EF36A948F25625DCCE664281D76BB6EC1B8E20DB3A7140B194872DB439D89F18E74E1861E3CF9FD442F1CACF4FBFD16532BECBD97CC9A007978D17922A68CE98369240A8D1E8AAE6679CA5DB79D83EAC1A571D0871D5AA28F6EA4A8EB60770E8CC43A78E6BEBBD4FC63CAE26F297F1E21BCE999A509BDCDD20AC938E38702215C398726ABA5A7AB3F26DA34DB3CBD58A7882FED91C33803FAE62E9E69FAFBD698962F2C7226A641AA7B6CED1DA8A400992333EF5DAAC77B55F94D51F74226AC03F7ED8F3D567BEB678D98694E9E0D483815D080A70FCE76255C82FE020DDF32D4BB7B1AE0EC1679B3DAEF2C20FCD7D8F74F6FC684FB678F02DE6B53D03FB656A9B9562666F49797EC658C0E8ED14480A0532DB85478FC2AD1E21F8883F2EF3FD97DFD757D883C1507C44F812639711256EF56BF6F8FC4A73EC3AEA3099F6C2BE6B2380FF3AB7007129D4829103AFE70851917E02EC5F2117DE110FD8F4EA25FED6FBC24BA063B7ECF7585519132884FC12DE1BBEF498B92D6E2062F1A4F7C97FEE96BA87ABFAE76C50729AA68C8F374102B3CFBD69139491836E4587D0085F92FFE2A94B6A87AFE29C84D289293D9CB4A733F90389C96198E2250F5BDC83F123FCC4E42844DF74FCB65986CBAB77B692CA210AC22B5B56E30BEE2BDE84663B22507E00E0D066D5B1F5245EDFAC6D860D0493C218A541A1FCA4B48F1A916921153933383284BA268C3AB003CD58FA979A08BC48A57C755688B0859AF7F21061F9F1B7DA44088ECA4D393E8DFCCA52823FAB812AF36212CD137741C14F0860CBC7ACCE1FDA39431C32AFABB84989CEC971D4A257BDD70EC71192148824C17AF8F18816CA94C457E1023E01012A245F28FF6582C9015153DD7662E4321B465B33B1D5DCA9B1CE2FF49EA3A811B5852AF5C42FCE7FF42BCECD31C798C3B8F685AB50B68654192357CEE577F5CF1F85A50F269C28A1F2ABEA382AF5CD089C146B9473C8965A945091ECD1C02BDF64F9C3FFD035D8238AF974E7111BA4AB10288F105659C9E2847544FEC0B29B6692FB53CEA0DD312B24C1ED3CAA1BCFD94E529F6C27BDDBB7C764DC0161FCE578361E02E0F5F3FDB095B6CD311190466177A5FBA62BD18595DC49C29E8EC7E1F2F3FFCDF17D477F4AF8CA3EAC53B7018A026BC942EED87704108027753DF67BD36221E9121B49CD40E8EA7FA2D6961604BE0095099A4413DC11E93B4A876834776D144269BBBF8A9875648702B589ED4CCBAFDD726DE8E8A58AA5D1A6E142A470EC342BC3E2E1B49C7203F283E99E81E38F1D8D2CD820AC98D8244A705BFD9B67E771A0366C7C6958DCB6921A81C0C9D5152DA37CAA8CE18D6B97404B399052051D7343B3739610329A37B8BAAD173018708400AE02B8DB2A2414CD7DAF038F94714031B1D83A5A15DBA53585B606A13814F04FC925C3454E251CEECEABECD8CFBD6FC04F504508C04E25724807004612E2796987D34D04318F82F7E1FBA83A4DEE3C86FD1884B17E77231629F5D5D11CFDE976E639C60B436DD9D302C380E3654E671ED81D44FC595FA34EDF90710A6384BB62DE0D89B50C14A44215DD1121C602A79A003955D860C88470EFD320E8AFEEB114E547E50CE967572DF5A5C4DED09222FF7821F91598A0A9C41A731D64429AE7D9BCE1B4E90120BBF94EED78098C9EE30C38628297C86DF59930E72CA561A61B6EAE517DB39F5A61FBB8C1838E3ADAAB46187F0B5D09962A39955343631B74BBD17BB2E338E5FC8C43BF8B2DF3A78BED744A481A1D789721928962AF2B9E2187E6B52A19274EF68F329C83F42A28B49C447FE284A25B71FC95D9322E752E28C7B4B656A743CF6C56CEEB758E742CFBC4B8D8DE5465D63D3D5D6EE993A4C47AA72BF82126ED6C7423D3475AE098CE6A7E6DD6F3EFD654BFD5DC4414B8F23F9E29CB0D5DDFAA689BABC7B5A925AB19817226DCD242EE46B588D7CB8E88183CD87C6D06FA1A40915A3F19E2368CDD97A16ACC2DF4CBBC0B30C6289D7004A8B48EFE4186BC4D844EA01BA78E4D1F0CDD2648D0363CA73A19032A537F68E0AC01CE6701426A03E071A109D42EE5BF358445907E1D05761B8F41AC8A9CBE2657754A8C4D83A3516EA465D5AD57367BC58DC712A5C055F68D1CEAA494D9A845474F610BAAAA4CFC96EB51D41493930534D58533E20575B980F4379A80393DBF797969405D6A514AC0A9171B79D6EBC5B66ADED19821BFB090BF76FBF50CA6AE07CAAAFF584A7013A71D54A2B60678F6F02DA726E7448A2379C28BCE7DF968154CCD22F1CDDBF25D91C616234539731B8DF4F55E21F37B29BC77DB4BA802D9BE419ADC292105EAE58CC81A636D479B550D33D057B7AAAF28F743F7B8C17E26AB2A846AE08E804E5D4BAC09D11C736DB32F9DC9CEAD0442AB7B6AAA70633692959A36D6DAFACAF2D7027E5BF9562A93A1B35AEE5313C1E2015E65AB805850DCA7A65FFCAF14200E1EF0DD8F8F05A11126EB02C13FDE38F496E5EBFB09E9E2B4920E619A67517FA4749ACD8B0857C7EC5A6E94630CE3EA0841C64D2EB895A9EB7CE5E757F2FB80BB4F0FA429E779BBE314A491B2D45F9A79655396E70CCEB319C3B405C33BDC91EC2169C3A75C4F5CD7AE5AFD6CAF6C9F81A9223484E7A12512B600794351693E1111401F74E1439C99D77E8932E069193DF7562C79EEA22C41DEA4EAF9E93456378CDDD6C8AA97D8D69C222614E203B6A1FA6377A7A0CAEFE709C90CB91939BCFE926B35970B13A06FFECD44DD8A360AEB5D0432A532E8A3C275E1DC4A07D6A3E100B04AEDEF14A52C09AA90438D65C8E6141490BD1ABCAFDD5925ACB040A91A8E11D242521C1F00EDC14D62E1C6FCE721921DF42164B4B34203660DEF02677A6B8C564075865B030936F472CEFFB3446714AE18BA14A6E45247C9AE1F2836E2341B61940A63FCCFAAD809C84906FA0CB1863625E59B96CC2161A4715606DB12FE3E79C90B64CB9D3A93B451E1C746F6B820B4FB3B3521ADE56DF9D50136635F29EA908FFDB32C6582715B06487B391A36A6A7B96505FD8ECE767C38CA4D0F9599FDCC1BE27C9C60D9190139C4F02461A5C42310CBFD5CF506720C9A13067F83AA1FF66CDCDFDF59B673B6C1FB0301DB118F3F49D1BAB49069A9FBC2D653D390DAFC3CC5CB35F0E50EF4CA808DC69F0134E3EEE697597FE7E5C2A2CDC5ED4E81F344879A0536BE0076D7A351A199530C77C0AF25D5C7D5629641FC8A3567BCB1456C1AE1D216C1E408C3AD6CBC1629E14DD834819F94EE0D255AB1C61BC7C324445F67CB7BA0E5AC424EB9C3D5FABC47081752F98B0011AD389581B8C20333C2878367795E31F99FD2C082B04126A3A61273C94E894BA7ABD8C6FD743FB76CC4FFFBEA78A1CFBBD266DB4432ACEA74350AC06F2EC832BD71FB09481A045F7A17F22F9AB65CAE6782A2928147BCA3B521E001D4BACE5FF499B1462709525D64E72201D5620B5537DF7A3E8DBCCC6EB822129B7768469D18C891A60B948DE2C12F4E4DB574C6C8BC586A1B57E727853FBCDBB4EB148DB234D8759B2AC8ADA2FAD225B5420C2B93D7FEAF051B7B768E64BC6EB83688B5E7E59059E1079DC66C5D8696CE758B42AE75123CA0FB72438DB97D39F1340B2891A19A4084BAA1A5149FAA785F09300B9DADA3C45F19568226151382ADB16617D5E59FFE8029F0513A7156F67D9859A13C2BEA574BE10E319F1B69740CDB176A962810B8AA6C368805EFA56E4AF69E908A205DC41CFC3FE69E4A6BB7B1F541DFE0A0EC1B29E3C199EF07538BC8AD7B0BD31B6A4DBAF70B83443A9C6C06268F597A6D1BC50171ABF56D18BB277F83203BB671DE404FBC4DFC66EE8DD4D92FB1AB2ED20FE8E9327CB15CB90908F37171D10E759BB8D1BE2C895604F87E2307AF7720AF99F0552FB15229B0FE7B45A3005E6CB0DC88A6D15AC7C364189A84A6615A344FABF4D0DD82EAFD42892C86EFEE6E9F7C248462E4C6CCA369CED819AE94B3DC856A3412A0DB90353E6C6D9DFE31913C3249195A3EDF9F84BE94AC6EB82969AF272AB8802BA0E8967EC342834B8A38163C90431844DB073DEB60B388710FF880EFB8283648CDCD75615D35451D8AE4711C1D7DB1AA59675061004EF8164AF3B4095F0E2FFC5433BA41ED72AC2C683D3959C9D265C302E0FEE7258B7C870F62D40961AE5AC43D3BEF8241B38A574F75EC7CD608781EFC16B7B9D36C3844B6FBF477CAFBA155B91061", + "signature": "B3AAA36B5B5A4676F1DFEAAE36203D94EC2E2092F4D46070C5C03089AFE6F991B0AEA0528999A8151E95DAA67815DAE9F7C21956CC4AB73395EB4B87F82FF033BA5BBBA94E238F7B6C184B5F2B1098ADA6FCAB8CA0206DBB3BF6548F932E522D5E17B2EBAB6B4A0A2AB6D25E86A071EB858832C2B8D4D718FAF28220A9801583DDAE046314A9A8D02EB15611E74994E87D555EA1BC1D10DB200A385AF09D1DF4A8D460189EE7FBCAC70862816A41B307F6DD179D990BF03C634E103E37CD9E254AA378602DECB325919E6C528F90D1EFA69E1815F481F22A3D0E58C9AC8018350304B887AB7F5509545E35334349C910C4B7CA7841288879CDEF8F222DAE22D5E18589DA715A5E35CDBCC9E79D3B6F6151B8F5972631EE4F015ACE124311355EC29CD3D4B9AD445E4B88BB961F9DE36DB01B1725AC1F0215DF909AC68362ED611E9EEC491BC6C01B3CA43C0C517267FA44C43FD4F195FBEB882E09BC2A0E13AA71706298AB6655408E8B8BAB108F772B6054EC543EA36E9382CAACE0EB62A5653B43C6868FA8AA6129F902310C6BB228941FCE346586A40B156E8572F6AD4E300F74F6FCBB9691C351B7F5E9BBDD8C6187085193DED352EF786AD96525E3B73DEA31E5468C8101190F57B9952B4D8CE57A3CB1A89A91C766785D6987E90BDB809A32B8EE7BD284C95F32173FBC55AF1EE56110DB65C2D6DA456659BF0B54184C348E6FAB7C397FF05A182ADD25345CC5B3B40FDDDB65F107F1A5227D93D6CC4AC4ADAC5720E5D3D801342FD06916229C61581F39A7FB0903F90FAE6F7DCED0F0804E003E584B51520A7A8E4232368D7B555F5A5F4AEDC83C408696CE2122CE6C8D42EEF94C6F6FABF71B34321B3C457016BC576F01B94410742B52A60634B6F57427F9B7508BF9DFF7665B8D8DF8D4F5A4EEA53F9A7DAF5BE52353DF441CD839B846FCE51338B74AB01149667AF5A74C42C6D9B324BE5338C69FF350292EE69DFD42D8D186247EFBC72423DE170753392F9EE3A851FF2C01E3E34C399163BC611785303DCDB61894E6E32DC4287C87782EB136D1B865A7563426D23FB354D373869F0F13A058B2F626951A2C5F4BAD5A14FEECD94A76DB50C69F434064682509E46C71D5076F00BC058A89CB669E253FEBC72AB42BCBAB6851B5DF111A06381609DF87972EDBA0F9A77EC972923AD6F49CE0F52F3309BA7E614DF4C3424473EBEF40EF15588D728F7609C4C2D4C691E54A09E6AD00DFAC07E69358A5C01EE4B9383CCCDF8E8B7E14DEE51D8B3B966F2C1BF547E1C58756FEC20278A8C4547250129516EE0EC1CBCFAA8C3154AE3AD9135D15B957174C1F380509065B035B1807FBF48196801831736B168E009E023616A73E7D709579676B0BF19AFF259BDA7F1313A46F15526B5D1048D853FF83A6BCB6F446F18BDA693D38A313C445FEB6C5979AC2CDBB750C536076D0E8E7EB728C3F01F9E4498671A34909959EB82A974BDC0AE784B6B514BB435D2FFA7B85416E56A4610BA354C3FC1118BE292B6799D4EAC3719AB8EF6040BE4C6BA12AACD9BDDA672452A04432FB09447C6A125F6FC27A589D3DA986152A0C3CCB72AB00ACA16885CE3A2E7F596706C7A81060A29A3DE21170BCFB1F6029C859489D58EC47B78717705795D5EE92C3504F4B0A5EB542D24C9F4A07F5FBFA1F5159F845997138296A18F9BE82B7E756E075F60D794243606BF1ED443B207816C854291CF3E2085957D52D6991345AB1150D46E62C6FE96F802D21D2A15D1266973FBF540570F0564C97CAF5F54CDC812FCD5C21C8654193376EFDCB5E7A9CB60BA929E00C933B685B9A789787212D1DF26C8E87347C923523190C89C7B20320AB9C1004B8148080954CDC8BC5D2EA91724C4284C21A289324EBC3F41438336144D8C8BAF5476A9AE92B522F88759F2774D9ECDC52960FE0C1A20B32451F4E51A1E73029572CDFC5E6E6F6CE2C0A712D4C4A74A26D7D8A14CDE65A4D277F8617A9A8BEE3F5EACAC1226B0C1D73609CFA4C937FD4B133ABDBF5357A771D80502A46B57A430F6BE8746F67448634BA215C7452011A62AA480C6F2464B1DB9F2096DE42C5E2EA1CC50A460D88B5F10692D29D9BFD03B8B8743CD0500C61BB7F7DA4CE336D25E68BD9A37841F5558C67AE45E3FF719F70E3CCEBB0128AB619C23AF8D82CC7E43041E7F6270DD8946987A090955B30C6152B2EDEF4269732C0D89817B9BDE594AE9E44945F947BA87C769F7F632AD3BE05CA6A749999027172230A8A36571534D151E0A0E3B99968C47F8FA9FC2FF4703789A15B363D40F57F2FF7CD3202D98E47ED13BBEFA9DE66BCC5979D7A57C91EF186DF2F2C8F02B474624E8F4729653414F6DEC7F763165164944BF7E9876686233AEFFA733426D63A3C4D31A4DFE5A6A4BA49CE45F0C9B0D85ADD85DACB28D4B75779F8A14B415F478E84D48A797F0C2AEFF842FBCDEBF9B03EA1A48760461DCF60592D8876BD967A1018FD85BEE5A31112628A0C6ABE9135C43757C2F1F70CF69C6E34BD5327E43838C33A2E01CF017EFFBE6C5CD676B7C2EB4462CB8EC2DF4810B759B5660F221EB8AAFD11E816E4EAE234AB54A4BA67F26C5787952A9CAA9504A4F26194355EDD7D7CC0755E70DF38F323603E1CC8738306A4FCDB7E6E9C5AC26F70EDC1D714D80ADD9628D1CB0F50751FBD7C4B4FB9987756248F7A5460B7BD30982CF3E60EEB075DA4C2054EFB0ECF972E67CB8350A1B8A836E285680BF8B59989E0CC9B0CDACABD8D4527940ECFE45E00300871992C69F23BCB4BB5F79295FD520E4E7D89C448F2FFA69AA40590A11F7F856FFBD486B53334B6537568D43039EE2FFCC2A0A840A4BCE03BA507DFFB7CFEF8762B8FA40E48390C94F4DC6B74960BF9B67801F7C461DD9DB9377EEC32753555BDA4BB5043021DC9C4FA543AA3F58CEBD08003069A8698CABD428C091F0B06220708EFBAF640975E09A58D6CEA83A719E49E9053BC67923951C4117108EEEB2C0818D988FD73697D14C2145734D6C65E0688F4FB65C8725D58BCE41C152D292BF9EEFA242AB204C77D7BEB511E62E893E255FD4DBB7C537E79B2DF6A445CBF67DAE85F6686807B356B7DC2AEE18F92ADBCB5D7CC4C80BD2CC2FBC2FB06436B1B088938BC7C7022357F51EBFD466AAE707D75186DF4D50390B1A3BD4FDADDDAE17D17EC36961799621BCED05C06C142094DC22D8AE2C70D8A2503FD7AA71E08E9726E1FC486B97AD3F2C490AACC6361CEF13400D34502E0CC7187BF226F35C09B784F5432FC44E0E6A913FE34A3E11EF957E668381AE4024FE33C264004E36DE439194DC5961EF2B8CCBCF0A2DCFD77366649CD20D73AC577898D593C1F769858CA8467E00C783597A49A70320BD6EF3EC56BF7F5BE745204D6EEE2C702860D6A4E8AD77F5B23EC389CA800CB4DFF1DFC22E29C1F4599EF131F5B993B8F9256795033309F8F3B73DDBB3280BEB2582D81FB9466CA18C5A028BD09F90C4A1A725C10E49856E07C2EA752FD019E7F4AF0CDE66B9A2FB9E22F4C962B81BBCCD218E916FCFD83A5CA2BDC582D0B2090F2172F581200BD0122FF6EE52BDB61EDE5DAE73542AB3C38E85B8F871AB1FF6C5FDE0EFB25ECA17C1D6F6777F5F9020B1826F0E309FB7476967A317A7D7BBD9E4EFE871E80A55F267D6FA3CD631250B594ABA0EC0D28619DAD9DF904F46098B5935298CD0B37EE80A58FEF57284A4CD061E093840C9D4CAA6DC3D2C1AD09AF739905A4CCB12CDA458BC9ED96774F49C5F9A1C43781C2A08BC99C0884BFD9C25545CF6B9F0F343EA84E8270C97BC47D706BC56B8E39B0DDA66D7A9E130E572586B9F1715AC35A4DA378E7B10CC998021593DBFD027001D2288DA1A6D72D9A66AC8930317E5154CDEA34C87980F16D1FC4EA87FDA2D47267CD5330B39FE941886FF642EAB1953CCA30ED21279365844C4F5043205D482485E45FCB6E52AD8B31A7076BC96FD88583B34720106DE1158FABD0A4F4422FEAA65B1C828A3D4918A36A99D34B99B052C7EDE5A9F6EDD59E1FBD2B2A025DF5457A9A3641EE8F65C13E7969911F5AD7C520F3C9F7357BFF13626262340429AEA5DE00798D73FB517185B259DD44BE7AECA1187D14F161C0D68FD44A272C38EE1686FF56F55202283714B763833EAC7654D3485509BEA34A669333AE9DB252DF82BCBB65E85ABCFDB0B23FC44BF4527E9C123AD4CFEF148F49178984BBE8DEEBE0BCD4564A333310F8BFC436810BE3BE1349371F35DEFB9A95AF245D92EB0DE9E44230C85ED86280493715F540ED2146EB903ECFBDC1AB2BD66BA8744B983EFF9437673A1D32DEFFFEBC94FF3E46D25B3565B71D7428C1C9E28FE9E191B79B490654762994D98EA1F75808914FA6D93A1CD216D17CAD2DCC519104244E2E9EC3E607A84142528FADACCCC6AE316A8BD0818413BAF7A90535EC2CDFADE973B1044FEB5568748C1EF7A1DF8A35597D2C8D86A159A0C9B88572569C50820D9C85C8FF52C072A81B8684C4EFC7900048FEFF31B4D4F144264EF77488CF854523303E418A5C42A1A0AC90AC5B6D4E84B51C9EC73E2ADA8EE053E81D629F5A5EE992B86B7984DBF7FA031A6BADD3D6191E266872B6E0F4154B7080BFF2F500000000000000000000000000000000000000000000000002040A10181F" + }, + { + "tcId": 29, + "deferred": false, + "sk": "0297C0FA60D16D4A0D17A019F55A3F08EDAE88B98ACC1C7DFEF6BD42ABC7F9B95BDFACCEE817B390524985E281177E1F58D0D332D88A53ECC69D36CD3F2CDB5DB5165C52C2CE37612A4CDD2B62BA83BD66684F96B835670FD22E8ED003408BF9D1F52D90CF1D2D3EAE66D7D85DE8FF119E46F27EB01A4A88666B02B2C5CD7ECC71475126233751606406113524782512715333860324438760638762734863482074003581724563351353138370627434260445637442177740371643224671617725441344250077330875181226586513706860871721017807300117550675284633706413607083013276585716370368050360711636355585577030632744062432341561238384284175207553145658474417404154724103855270733216724328004787058212163440458651245376828170458827746751653134524478840643478264478207475568815633525051308106624207867342115378165346422073070271412006802582227512715153203088321004847547556737460264581323568705360343334431146566351401314880877404717661204337656538731582228565331786427057033465157483413750216317745537626715720244052725853713888388134843772034588472347173687745730066205583284724450000625141552705674515631427087434751825444380103432251711865645505836042741704560123523466822474632315045847723202654748142365813273005127174240207784056454887672623315657661530444776343656142117642778181763467027344577108463016407222826446461136448285450720774714430371008081132006480153606526463888054500118888003781136213148822370121275828340188141732881861617164087530333608831350247480601478725271843745774177873867312067462502403637155718413362531502661247285480024810234235400373287583667573412665140207568763110311725216005676866080753252314482804083063666176263420837737160682227765684481183417033821367724774461317852010100623286300633771066431466481720800788057135404721823251208256681603522737022068184055137381511425223830770027241631858506536650561586474834248364664527764288258583362258253611711468120685118836063400130368635701515801213185810606620114471462062014451636631838874230368660332432366768312320537254065462521272660077350618508423570831123312654084175610472468372463383236355463060552050638703827717733247850374664833535811821007341633446035721564215452045174715401058443708781470787635660678122871062520772570612807708024277164210323003680110227842476577255318133076620664182015776421146370080642876232368544572781206873058413012137383478200823323051100107156883162232725863430855777107357615856648065557274370204175012652058202246626757621404800874450550038325336061484681482363078018181432130234117583142652832864715748075227663747166702378321453044770646634388835406301744345204662683538438062348531701370655844554268761343776785460263714566588627783555812231322607824008010540740805513544233266705274246487108817323774438713754288718083217056316548462085815377128322036330530628018007677542067157424064876784444558815064151587171085581181235145012554740075736440276116856220542332347645738730270817668064813705460748025865533377527104018483583800012175176185223246188313570514482238856512801400078072461421870713162071176227243553400204034625862157643623617203115234046563256232806750543822670848323427755448215870168576404750227120773663868780623554673551445E94254DE0F4BDB570C48E4A4B84D39B8B491B4B272EE7207E36529E757A3EA9B5276ACDFE4AEA3CC6A05CABA81A46731C132A2EBAAE20587477129304990899FA1D512C5CE65287A6F8C0B1C8C27B44C21E70BAF94607D74A425ECB282990C7C05C66413809E6FC4211DDCD4A3DBB34B55359C85CDA312B23FC57448C8886B74B9DE589433DF4647066A32C4ADAB91470151FA69CA74E696575AC9E666B94568C1932554DB63A48FA9A44E9A34B0FD6C006148ADF69409885A99E32AF63FEB3EE8B7E8E25D207BFDE31CF17C2257A6100112B0512BC42DE1D38A9A292723CFB7F4ADBFA97EC6DB138F916CB479BD30617C74872E5000DECDE34884086D2640BA4E26A21FE0FC02F13F029A317D2C28BCD5C88323BB73C41536393234015DAFC26AFCEE2C42D8641C0054C6F8BD69CCC8EE136DFC1432DBFF2FA5239E032DDEAEB6CE6741D24DD87ECAE126A7B54DB76E505F93A6352BF154259AB84E0B6B3268DB1EBA038849E3C1E1A638CBCCD8C255BBDCE05E5A12951BAE8EECB62C4D8F69F89AFD2E57A216BE5FE914E82FF2FDB8DC8180FF798979766F95E06DE29907EA2BBEB325E3794773E1A1647F196F2A0D35778B1AE8F34B02A9851D132A0B6C349B3718231BEFFAD69739BE1CA60F863A91CB312AB3D9C3EDBA8D2EB3DA894FCFD91ACD00F1211239CF8922C5F970352B754C92A1A69D3B0EB1B1207F1E02487EA2CA8D1FC41578566E6760B9F65A29B77ED07491D9AFCA386CAD30B940BE4237115B4B335B080B77956019FFE5407081981C1A62ABE21EB27E5A74318021DAC60F710B5C310EE59EF7C4065C5B97E44639A1736A644A32AD09535B94A9E26407BE3DADC4BF50D27576151BFC5A57179EDE6DE8BB2A8E83AA215FAA3EADA0993FF66F2569CB5446C73BF3C5451FD3A0498579D945F23A26980426A3B9E8AA23FD26F9651D1E06BA56DA1F85B7C4C9408A6F074062DCE52FBF9C6A8147F86B793D41C09E3FF4317D68DCF0BA7A1104B30A2930CD8E248D3DA02AA931F4A3A6E46E20BF4E9B3EF671E0D5CA23BEB7527DBF6E36D622356867A870EE5D36F1496357897772C89D1D2C11F8CAB88F26F7CA6C941190DDB06C57001B70534F1092E23D43AEEE40483E4D3C4286AB6F51E07AB71DD86008F5B0268D8F3507ACF6FAB2C2650F1B43EB4B3E32A959CA23B2C1EEF2646DEAA03A81042B20B9A03A0595C86C5D8D85DE2DC31900E983AE122DD679ADEA13AD7C1820EB1D35E2237EBFE5E00A5ABA5DCFEF82E52E8AF34993D30160FE3866856BCEF955EC731D99B1962181A31602FC7E6746F9869F747ABA49C1804D742D6B072CCFFDEFF827E9F66B533173743FAF5D88798698BC2466D0AFCE77BE660CED7B90B43E4C81ECD9FE5E3CF23B27AC363A964C1EB4D2B75A60D439B6CA95E2F9DDE270FD722D4E14199EA6A5EF69D2D59446E8F2C8BC072C1488FED4C7CCE0B547B70F629E70FF7EAC26A56DC35190019BC5A141F2850DA2FBB79C847C338350A72E556B349CD82C2562D93C273A62815F6E17CF7D731224F9B4F0CB1CA6FEBFA28707A26A37A1CD6CF8793E34FD55865969AE291A23929FBA90EA6645AF179D92D65198E30AD5D7FDDA597FC097A021DB3CB85E1196F76A17AE1C8B907056E7263924400105359DFE7099C4BF08425F68C513714114CE9BF6505D4AB1A4C31743C62E11AFDDE423C9C4394731B892373B156BF828978C17D833867AED249B609C4107A43158C2EF607789922B6F72AC827998F7738D662E9A15CA66A1200D7F6FC9D8523E4D40BC70D8DB762437800114A6BD2E58F841B53DB842D345969DC31A8003402E6C2BDBB8782CA5198170662662C3701AC0F6C7C9E35FCE3DB31D363C594C7E2C98206F280DBDA61503CEBC145F73EB541913007394767E8FA21548FEAE6F29E3CEDB09AD37200D082635B3D87CCB2DBA9E56E00A50C5592EF3574D7F49EBC1DB5CD33A1DC46E5A26D80203A3AE44D346283217C72299370B254345409122A187F099ED7734863615F91E083CECD1D74CA49F4CD8142361C2378289CFDFDFFC5B54E837E41DFC9204D4905956312214EF384EC9A0D907F07A143228E3B950FFD27B85B43A1A5DF06736D57F91EF4CE7533B5DE81B2CF21006855FE5448E0071D40CFA25FA76C9482E7E59D09FECAD3FDC45BC640D36EED01AFEC01FEFBCA2E7EC71F36689EDD0661465F97628E817A9517311C5BCE985F40299148BD7F6187590E72FC8D56960A0886D93510D660AB96805E160D202FFF3752D6A1AFB68A5F06624F9A2127EB5C008DD5C43B3C6B4095A40F035BC095941CE8F89905A3C6AC8FE51879D9B5AF24847A52E1A5AF4548F3A70EEB3369E84558C16450CD9D49D2AC5CC6E022721F1420B93ADBE9FFFE2E91926FFC4F4E443CA2523AE8E7A96F10349D5792EE079FBED9E1BF96E1CE5F02FBB5F41AD564EBA9EBBA08C74C96132304FC0895DA7E6E34B5C99D333B97C062F343B249CE8A42C916C1E473AC763D0643063AD226EB9ECB4A51BC7B8291D58F8C1E1D331375667F0F80B71543B052A7CBB8B95BC267620FAF7CEA80D8CECE430BF1E515144817CDAE07802F5BF8416E41A179AF840A27D7E0449D8E7AB71D6A361E56DD57289A8638C16A6BD4C6B946D60C75533D343567107E67D12D1C7FEC1628F9C75C7F81033766162C4E3AE0635801EB74DA2EE0FE14B3EA5385154AF110657E7080A21A5CC50FA7ABA75D6C68BC002ECA08BDF02CE3A2675066FCBC846917365B988FF162866F19299ACC1E79EA08E36742B31953ADB3F7E1D38AF6D8B2072B35EDF4789639694EF82B0323743CFA075D839BBFDD66B6B6753D5EFE3FBDB97FF00F7BCCACDE4BA8EE392C4996FFF9A27F5E7EA34AAAB868983F2BC2127A3083CF3229E15D0CA9628D6F9CFCA04567434452594B5047767AC031CDCE5C0745340543584724282BE058DA5306D986C8A20CCF9229D40221A66CEA47E3FBE5B85E5989F464128F7941E29DFD73BC85D470141DD8845344DBC8A66F45CCAEA192B0904F58AEF8D78F39C4CEB4E289B75F2401B8036853188083C60AD910FEBDDC8FD7EF70F007B4B7EADC1F24E72B97AB441DC9B20323BE021C61C4708075B571A30D7E8C9A08FED5DFBCBE215345ADEFE946F44C9BA0F19C3D4D0589495864BBA958AE84888AAE853A59E274A07FC2452B082B84153888A5C15A5896EAA0CFF52BFC525DECE99AA476C465D5B53D175108A996812E21BEB615DC5EBF7AF1F4CA7DE7BCFC49356DD08224D08363EB068DDB19AC2A4B37053C0C347925AF4B5CD05C35413AC450E344A149FD32CDF9E37B38AC4230ED4D04232A21942780665C97F6BD893E438558F8A1A4865A9CD7DC0100B5DE099B163A3640B8DAFA75468BC0A93FF75CE9F58430810345124A8D4FA546376E8E56DB2610129A845F5351A31142973810DDDE9CAF498C7660BBBF3386C3AD4EEF7C3B5DB7AAA2C406605B60DC8710B94153884CA47A99D64DA2DB26D658C9DC3AE5E6CEE", + "message": "DA2755DCE32D07B6D2C2DAD6BBF7CF5D4C26FF0C9B6FB9E064B51829A1ED51A712E26DF8047B487FF0755CBBA8FFB60DAC3C45E238608F48205A582BADF82C2E7E83D672057B9A9209386D2AB8D93BBDE0C522CD1BCF2AE95573749E0D51B85EA01494E3BD97D3CE0A61B26249E4BB94F9667D6556CC4313669409D94AA4F3BB9AB70F736D34245E2A789A5FE2917D5F4CBE43010C5215AF880118E1F5FD47A4C195F3C74307523C688AB76B7CCB157F75FFD79149B5508E7E527ABF718CE8E2E4162BF810F35E234F8CB65DE0930202C1896DDDE02BBBEC8D03BAA12AA1C91EE798FF7ECED608E3DDB7BD04A1DD9139F4A5613AABCF7AE495F9CE18D73BDA0C91583B72CCF6A722C319AD5B1051E65C1B91DD05AE5A77220BCC7576F9CBFC8A12CD55883AADCAD1AA109522F286B00B70C8E3D4C6EDDAE7E1752097C85233583BA0E1C05C5624FF65A3F3894158982B633EC92C24382AF48EB2DF5EAD30759E99D67B8BB1144939F4080DF0E1689AC0D4CDC73DF1CC2FB72B92D5A69019087294D5F2DB196CF82B7BBAF953F0568663596F78B5A309738BB294F7AA3FC5F3ED5BFD4768CCF3304C836B476458E14B233C156C8407636FDB3EBECF49B97C96C31F51353B79C378C6F47F1913E5B14A82DEB126D688133F9139C12C45BA24CC9C7E2C16A26329D463ECF59746F5A99C6B03896E851815EF36F499654E2764BB8BC60EBC821C4D0B4C363EEB7849332A9F1053A975B092AA3AAE33F06F760BA1D76DE07A1F48ADBEADFF1E17C34F9D69E409DC5AC83C296C402E042FDBFB0B6B4E023B15B318337B6A1CE69F1CD3D93FDD0FEB7AE259A41383939253C317DB949E3BEB9C8F7A79D083BFB46C50AC00D382C846B78FAAA7399ECB902CE8B73A1E89374B1DA65B0723C67B24899342DF13C07A0BFE3565CBEA5892F8979E404BA84847AF30BFC04D8EC77B1C5B9400CB97622E6D3360836639670BDDF4E9CF9FE3D6B98A5FDA42422DAD6C829B9E33F53686E2663D232162D3A78A7202EEFBFA4917BB8E89375279C96C9054C2570DC3D90DCCF0E418B69E6443C1B2540BAEBE022ED9A9620C030377C67FF4C186A59459DE7DB1ADFE2923C01D9B8D3AC940486052DB67EB67A257BE7AEE0D3C77BBFFD0FC7C94540F11DD96C5100463C27D65D3BB6B7D867590D573D1C1BEDCC0E8D122FE4FB82F1404CCD061DD7C3D15287F39CBCD2448DEFE1FB4ABA858DCE13F74414E1A8C41B730A1DFB45B859545811C2A9DA01C342A1F3C8B916F60B5E4802BE672C2BE31531DD9E7014E681A8AB1240B5E3D5C0D26E7040D4CE05F9017A32E1C760F466A8D7A68FAAD421B2E2D886BF0007858129DA2F6B92C4CACBC1786291D7C95A3F6A12483B750FAAF1DA03059F89C761641C0AAB21A05E78E1131B8F45C60BB5E8681086717B918BD4FBCFCA1BB5DDD740BE289D8DB1C24FE083B3DCF0E496B1941ECB7D51182F9CB9986CF3F04F0CA4E01C63EC879FD4A3D5619EA1085B1431FFC019286ACDF3B4AAB03D6265A7B18F24CC2815269681BD37263B44DCCA5CF6FAC2ABB1DE317118219A73095D1BDA10B66B6B55421F049B71E759DBE6154F1DB98A7E3FC877FA90217A242B21F39490F2116A2BE8067168F26439C8D1928255B5A50CE1ACCC222087536BC37806FFABA03B7E787B04C2C67C1B0BEAA871F39D3DAC2221AF44CC7089E520BADCFD840E5EE24AC53FCFF1E7D6AC26694CBC15B80E48B10C054E8DEB00AE387CEC9972A28448A6BE3A01D5EEA837703D2FCD1EB2521D444F900846F59074D715AEAA2F46E956365B7E67C5528841145C442E6FD7B3D7171BE05BF8BAA415260F645E2FBC93C46B9F94D2997929349B88C2FB1AC6743B73DE66B30B44E5DB3E07E0FE9713D9D7575EE4E40327A58DCEFBA0EE95E22D06FDFB720993EB134073A80A4F06F8303C7758DD37CD7236E5D80AAE2E9569834846E7F6C75051302486B2564A1D8D987D1A3648192A63EEF4C2D25AD41FAA02C9F227CC9F655A72CF7207ABBC66F9C822EEBDC89833757013776C11C310A22C226ECD33E5B0772AE2DE8B8E9A876650D4A57B863BCC6197261D7D06903D414AF0922312B7DE6D9E64F99509CAAB8D808DFC5F046BA2CE55817512535EDC2477D8462A1817E45D33B9D7390A11E30C3860CBE2C4B519812ABA3AF7050227759DF3B6FCD6D3EE5C60C1042DFCDD7880888A147AC47A282EC51D0DF664451E37D7C40672A27B965CDB805CECD3EEAE38A0AF4C2349FF39947659686D30B9ECBDADD80C9B06293FC4BD5E7A0E1E9E883D7A4EB05102CC1FE45F1C9BE23043BB458E6B8B6C1C187761004EEF59E398B1124B98B0EC0F7B29394418B38D8A3003ACB85D96CFA0C3C63B2ACFDC2BF5540D029A261243E06393253B2C3FE253A220DC7AE4BDE0AB4B386DECA15FA2A05465740B072FBB0C8E81663E320AE931A2DC7A627C805AD80819B9D12EC271D9D16736156195302C93490B4F85E8B4F5199CAF233974079A7AD590374C4E5589D0FC26F70FF2CE51FFB3E6742AD5BD9840F62F745C42D6085E46182FF73FD079BD2625338105FB39110B660F8C55D0830587671CC802AFF63FA7FCFB3BDF6D65B362CA0B68B31FB802E7870C3905B04B41440F549583EC87218DF6A0BE0E209807AF053CA121D704DC0C90A499D1742658BB096C776514C89F6B2D3FC7FBC4A38C10DDBD3C08F64AB076C9BA4C7BF24EBDCE9C82B1BCB8E55C4135976C878B95B6ED108C2031F4E53DBB19205A7109C50289C743818B90ACACFDEF20EE33F5C9A7142B5640F4D875122E0E5", + "signature": "583E9A28CB7C3FD65D84170B159188C12E7E77E0F39C678C2ADF349676BC5A4336041A2AF283D3A0F61BCEED4255E2A04749CABAE6811FC2471148869D81C708E4B56FFC353196CBE05205F737C91C80DB8FCA7C243DED5BC6113AFFA87E14E0DD0D3E7A70B2EECB847762F5521D372C51317C95B6EEA2785B552D9AB045E48C03321DD041053C328A0081D86323CB37683CBBCB3A68A2F850E5C7A4826E88B1AD51D6C1677DC2B081DDECC66A01D3D3CFE26531B4EF89528735A8CE75D4B710C0F3FF05FAC74C99585695BCAA1D1FEA42D6D5EF176B90649FA92D1F089FBB63882AB9CD539C88028B380E610421D3C09314AF44F6BAD1129107AD1B84624AEDA7F3BF3A7698C478EF5DD2639D9555E53F60F327CC66143438C589285006552FE249B3DE8F4768B9774591672541385018FB6683CF04C85CECA1A9FDB4F44EF31AD9B78B70296CACBB35A600C486202BB771C75E83E1A0429A31ABFB75558ACCF835FCB68FBA01F5B766F3BF18C23B3DDE511087E8AAE570979BBF17C8C1FD69953823B4FEC56EAC6AE11FC4292A40BA01717F3A6CD108BF94520955F978354D78347ECD4A0222D89D1D7D93ADAF7679AE101106AC49791B3D17B6391B85E55AD4A12ABBFAFCF1D50667B37E49CA69D3CE3AA6692F85420B246355ACB51848AD2EB94CBEEF5E32D455FCF42FE73562B5B149CCF01236BCBFAF656E85C1D9775217E51D4F650FED78D8BBF2B47C67BE41F69AB2C2B1904E86506A371602A8B84A50BA179781215C0B061522EA66AA7CCA390055D0A461805CAC87ED7AAD205777344B7573D76690B5B46AEC4665E36A9173D7732F5E67FA166BDDCD56685EA1A41D440E469B7B65D7869744B1776DCEA504B03F6057F9A2D916BBBE6A5032356F4C3D48A495455381292C52E78F8478A56FF0EE7B94B83F1EE690F7173729DED18DD712BDCE3CBD887771B1D87EE2946F1ABE293F3D7A7ED224F6969D31D2E1F71F4D45607D7EF59AD25A40B4A43EC95FF0C8691D4C41E97832F345CB50890865AE483A163966F5B45291556826DD061C30C8CEB552EF8BC2E987BF6C8F629370A72941893F549864389CBBDC3D38D9FE7AFF8682EA318BDE62A2D11E543051A88B01547728E30CE25784251B73B771EA65259E90C4A859828A65A87FECEAE332B9F51A986CABF15B622AFBFAA04C19678DD200BC0B338C29B65CB121B70DE6EF964360F2D54C4D34BF7270212452BECC9EFB2E225A6007B35C000D276D34AD19A966D49D98E140DEBE503215D716B243CC9387CE52DC10C5B40BC765C2E4D3CBCF8E1617A1F0133DF0C98D0AF71E18DB6362A6E4EA9E454E1D6D986D1DC50AA580DC7DD131E66EB543833FC42A575A84B652E63164BC3FF383040E6EFF2B7550C2AA0905FC7BB4258176585544DA49F48A844A13052B06676568244CC66660021FE78053CD4ED1118C05E517107F614294B97CD4ED6685D2FB44B8B01E538874186E6F8D27D1F8829243016B1D505D42204FDADD54BD985BD647EB79A1BAC18086FA8A3568343F58A8D46A6A35C28DF1575CCF1700160EDBAC0C66A406A26DE724E1CAD5AD52554CDE52EC6B5063918C4A137D758C08272E4C2ABD41B7EACA4C44A3A7CE60F8628F3B13CFABF50F16D02B375A7FAD7460C53A8008BE19D982E9794B060CAAB1AE6FDA80320EAB2E02708063F4721DBBD8B9FF951BB6129139E90E7C1754D4682D029DBFF5FA9E713330AFBD9DC2FD1148BB388F4F857B4E4C63FB107386DBCA20AE196CBAA995F522D6BA4D2645F724269CA1A5AD24D4F56804FDD9A305B30C46901B484CE8D23166A5036ED775CD192BD47D9AB6612CB6D9181C1472A1F11E02E7C82470E8C685E92F21996663B18F8738469D61D98336D7C53ED2670A8DC26C21BF0BB105F5C905D2AD7432681AE8EFE5D868ED0BE906474CDDE2BE7BF5B617463EF59BE4A210C3D5682AD4DE5C059F1136D2C455BE02AA1E276F135C5001388600FF2F6BC6DA8AD0B72D1F5301DA9A8410FDC410B54AD0BB2561B01D646214C867726D82D3919B4C76600DC065C5933F8C7D3C916C374A06D7F062889CECA4D0A98FE843F8BE1E724D88F6B6E8E066D7B660B0FEE10CE8E36C4E60269CFC3745AA960C8BD9F7AF8788C4CEA7C4BAD51A202162CED055B6B60F8CAF85ACE6F60851250B1BA0ABCF9DA2C7EA2BF074EAD9BF81D73ABEA3966D63D1E60809050B7249B7969AE420E40387C36C4757AEC7CB328466D118E3794903C33F230114AF1C0AEE0112197DF6624123146FB3CD30F6020378040A8546E20767B8537812D0941836A0651AC90E084ED6673BCBBF18348D0E4E52FAF06FD1A42DBB1EACA550553595A388BF27735E85FC4965E61CE82E96430F40EA3B35B874CBAAE2612A714BCE0DDCE94FB0F4D93DBD7F6B03C7099956710E5EFC5C996F8A7CFAD679B496044F5204056D594DE05B61CC143F834BDD5D8B9F89557FCC09702848EF9A391CC4C3F07F1CFAD203B172CD1F44E4EF08C35631DE23B8E0CEA4C4848663FDEA9C9ED8B97B5C7F9E94AF6A90E5079E40A791F1262BDBA96BFABDC30643E2C3159919EE5288FC75703FD0D03DAB0C36D0CF06F0450A5E6D710764085D0BEC8B26FEEA7E5C2665C7F514AEB5430F9C307E7D03B30401646A0D93561FADA21975D8BC4EE1F20329FFB4625B3A484CA08DA09C61B45E2BA9C88C29B14E9B650869EAFFDB7EA3697F4DCE2A72752B2459601E044B52F0DE99BBA5510128944C00357845F374D60E373CB35FC2868DB5B948EBF9BDD3C66C1740F00711965AD9549347CCB3B5221301159472AC8CE0B3186269FD1CE5CD0DD456222F10264B117BA250B391C840E51D8680BB622769ED264148649D3B954839AAB5B27546B8BB58A20BB52FC8772FACC04101148C99DE07B96BFE58CF2F04DD5541CA9D24873557902F0BADE63229CB8658E8E5F815719A73F29F81208D0EA8985BF2DD770177C4FA88CBABBD0C9181C0DDEF7CBCA5A6EF12367882621E64ED026A859C60D0B8690924EBBDE0C0E3562E10B63520D8C801A6814CB1AF9F03C3907FD9A7AB8567FDDBA869D7200E9284933A414FE681F04A45BC3D909267FE62FAE7A52F2F84D3C02A10AAD86A1C7A9686A2B7A81DEAE6A1289B7A0792BEB805A620A38F7610D9C3AD1CDE838DBED11A760F42A271020761BC41522EF370726A4683DB705C7CDB858AA8A8036DF1328AFAA0A4B31839DB7518164B11E6EFC15755D1E0D477EC004F5593CF7F862AD24295569E3D5095B8B0F1AD427C1CE7039DB9D881D5E6AA570144255939C22AE7EF4BBF9CE36FDEFE30E64ED373AAE944907F5BD02B70312F7150CDF487099468B19B94703358505F7A5DC9317B9B17C44685E5D609A0F5156A1D4EE517BB681CF5657AAC2A1A678687E9995F089CAD494A6C039774FE62AAD3D2BEDEF62681AD24884D1630909293B54C68D7CEBEE284EF9E70049748558DE03DA23B478566B42B8EB327DD8BDD473130F1D967BC0F6E4501DC64836EB877BA0AEBD241432C503E41DEC7B264E08006C006FCA366EAA277CC9F5FA6155C9E48E852B718A071082FEC580B4AA599CA7708AB4C1995B6DD0679264D8372B5CD0EDE9E40B6CC0C3DB14D00B2C7D2E9433F08C23ACB77F991A454A3D1D71379D08640FA5074EB5364A531587907607FACD9AD9036C8AF221650F01308F53B8D0E432E5529F435F40A40E66A5483115FF438107F88FE5F1D541C500F8B12C9DE69CD5B14C3FCC5B462153F9DD49974C34EB1C5604606E56C746BBA8D90E3DC4556DBC3BBC656A54E08ABD3FE1C39F24E99D3D022828F59B80C4DEC6EC1CFFAC05E388D3F62510AFABA69C5E3EDC898CC8BB842F3886A88AED03739C85DA459E8329D1AE249E26EB60BDD2EE30191099C96C397D88FAE9922C72A275BEC1C7734CAC893D906E976FC7C0AC8A090986EB4F5FD7E94F8B2694AFB4170CAD4F1896092A7F6EE01C300DA97538FD5FBBC6EC28D158D3AF40D3598753883156B0DF2143131C2751F2B26DB6FAE76773E55AED9D115E7FA60267DEDDA65F41CAC5FCB0CA296EAD1EC688C742DDDEC5292EBCD47B0570ABBDC2CB6EA301E58778E1C3352E393598470D2FD2C45BC3A611343ECFE61AD64E71033B6B7C053DC52AB1CB246682750E330560F15B3B2D83E63F33BF4EAF608393C1F5811B0D12244184F20EC0682D236F583CCA8C8D332318AFBC50C03873D68AC44CAE4C2826E966E35EDEEDF4B232DC4B3BA87F3478FADD0D8EE55B408AB929DDC85FAEC0AB503C2F8192DF7B719594C7706B98C593C598543565C27BD8A0A0CA7E802B86214889D8A08337C65BA31BA08BEF281FB69DED0B30AC13274E1D98FE3F2CADF6B6FF28334B338984516877D3070F379991A078E1D0D25CED600D2C52CC335711826066976251DD11AD21B1C852E05F3D9EB0D37E95F767108AD378770DFF10854754BDE53F8CDC14F6A48C66463053F8DE46B722EEFC6F2BC2495CB107F3ADB39BDB2AF497FA6AA2CCB4F9801964FC6B88C9656D76C0FBD9A436D1AB57D763A8B814D2957E6344312AC137B3B6FA74AAEA860186C02156CAFBD455E8B999AB52B70DD05112E5C94DF3352AAB3E2071C343F656E959FDB000000000000000000000000000000000000000000050B0E141922" + }, + { + "tcId": 30, + "deferred": false, + "sk": "7D9BACA9C8D5E302BF5CE4C85B7685388CECD82D72EC259976F4CB65C360D74B7AA8B23CA3C9D786FA3D949A9DFC1600C821B808F0BEB38F815D7688928159D7D9E9C1F80FBEAEB0718B4A27E5AE16AF325F2362539164D1B0F282131684089E9C61442C8C6EF03818E4FAB383498A91F1A6BA3D1138FA2E6863E7BFC37C768B80881102106834535885567854243344502211757522267523162088466534441253602763327188226627581385652565414151784380762722456634142628231458738808653824328765256787544665871806531822248171715644617852253306323676053473565268176586832213365052846420073311447520430470886788436502856868764754304758685773064126124086602270614670066264160503303628808800428371124331158623773024150040258466354242631322182837265206682145238541377758026231302173751556168744863422724538416543335044260014140700080223635662746130854042515087002685102861285410486525326637353184253282228015078475041117212844878141825033873150751831805782170351465068071671207478634401484255326350633185463351180560737581677164273148337620650506318728817625581311474587143474200631175767306836700454673165201446440552351405570370765020236227650155735776370575127458246010022264663462424423213765310260018843165528661703717074062347113507035301545373865105171508624854887346415101230182053334304844180245311205556878267210221681707671130563111227840346163445346756381740517462567744211002860288204613256541014522561605650738111510652486113003236284705828187520165420710141265210772323357340165116445210432428531411538578270768734622774714255868725625185866516828826288225225382481362346231732171642643803148671271817471106245053755183045102417242701340831385358686761031752488155811285174784301446783814603452746400881104301515340323411220606187382848113531273238682142164176684773160428640811770836021008816722262735542177425024011656734742220208177654327651838237731115676205078445837425763855715746545685101718301140056042410640767435220144420781045324711834710612775235483708256718366036056834856355047187872866251726612854101127341052403064311315244428128784365157205414785337848650728144772332137377841026231712784787072708207440534642352015738400562513805485583235012405755534737647887617687056613236528823413687622035830161327666432826703008462403420246788067276833355848330825352627051271045102466531806664112101702762667023185287441052104507353315241367611074381635451018347836601447556273501604602706013545264275427561702133764222721520838326555538771678808754764612652255384672763068833424642760475458348132214166041671261184323442617226644673580125123380608502007202213714484438825036152616448882228853238503436651346737426226137454116521806224384547167800842813436447366152212332813016632406320458758564571656076278257144143508780111883350040472187651326241722885506068843614384407717837823233334577603583138607157753607181603248844021525518610382536002436628707660830482135508327523234521413058137640267365080463880375267721714644672516818385618535542842438636753417412616738466876353522248666700120623351178721720464482820874272415685137628481655455861246778640761403677012083646508583110082074453101204426410178432288412156182720465184485112240375BF8365FEE3A6C811138E1CF73BF1D0EA525F2BDD4988CC157A976B949022FFBCA93B2664028F9D0ADE28005C84CA7CC39EBABEA9C92075734D9F83990353AF6D72693CBE38659C9305C804B8A75C8BB1C5FFB6C5A681155A2A65F85C8DD4A14C6B61C45D6D2BE9411C00A29DAFDCF3D9F1EC1E2EF75214043AC120DCA4F22AA7354AC2B6443FED11A086B22630C1B45B2A372FF2F1D0660C41087F5CF818FEC1FF96F18CD710FA09F66589010708CF8D299EEAC86E1E989C2DDD60A2F68DEDB62B0E6421D4DF285AA2A32F442E35688826E0A9EF9FC32C32F09A28419F37DE7747DF9C86B5A54A558D374FC1C083A46321E7237BF37491214F54973CE3BA8D7229370DFB27DC68F33EE68BBEE33DDB63B3AC4E4346D6D96A6A300F49ADAEF370C98AB1A44A4D5E98C1B19ED433AC13C5A099894CA3481A36820E5548A04C632B0995BA976A359DA6F029DE8443D7AB197037AAACFCF2F61D33B604DD3BB09B26523B103B0AAD0D2163F09294A48042E8D23599DF7095E009F393C4CF5F295C3F5E49F2AED1F29926653C48FCD8D93DC39422405C38EA9E28FF5ABBA4FB699D158DB7F70E30716DBC1627A27E6A93F594F6241869332D4F3CF41731B84C17DF195B7C7CA7E4563AC9EC1CDAB2D1E52E5C6D38B4C63C3901BD860C038A34284E71834247D1D3854AEF49E2BF6F67FFE4256869A41BD44B0FA2E0CFE0345EB3886BC4356AEE11A26838D4F2279AC13D6CAA53F110ACBB1F6764BBE47BF3C4E1F0B9B99B00B6B9E0C50053FB32174BE392321A3E0A69BDC874D3F3A42AEB79C4BAB2753713A5DECE419E2BDBCFCAC6CB741425A64CC7D3180E097B5285E0B7BCBF9B7D97DE81DF3227C2DDAA369C87BBF3F876AD8B81E9208C2EAE363C3A0434BAD92F49EE7B6B805BCA9CD6C0A2C3E21E5D5DD9AC4F427F62EFC96C13F6EE1EC761CAB24E61DD6F509D08E8E5AD4EDAEAEF0679340677882BCDFCB6928AE7C2052DE7116CDBBAC3551CE0DAD8AE909D795393CB8A6292C7FB2C16EE62B8B5F05CFD5553A7303919D563B7612E65EE69C97AE80D3E407A448C88D508191B98821F03F3823DA8793054FB0D051D9BD12D090E2CFCCA4DB20C6AD515E5E8658233C095781D5BB1D40BC47D3BDE5A6379CF03511B2A3C06A2C315730A0349F83512778A5123F7CA9FAFC44F73B1259090F8746F1AE868DF6D158636EED34B8FF85CE3C07F7378ED5A3E7577A6FAE7CD3EA0DE0EE3576C48008E2E4F8C417F3606BB1E9DF468E40FE74A3C69A672B758F1C3AC570E44E9A08936788B44A769B28DCABBD3266A82CDA0CB6D2014B73BEACB33801007C40BF92B647FAE6631648F7E91DA022993A9198153B7B3C31B487C863A639ED7AD4B235FF3D44E3AD573036902E3C41A53D34704237304D2E4D72A3F41DB6BEFCE9DA8945CF5A9AA2217A2B36DD2956C3F4C811B3D2A95E1FA88FF2ED95A0950CDB1A14DFC89ED6E996C854C1FF056A73D7BFD1E8F08EBA003E3E834C71598E42430B15BC0F1FFF6791D639BD40923A28FC4B72636AFF01EF4F01C4894BC78A3AC69BC595760BEE8A227DC88AD1E633401B4EA43BFB070ABA4DDE38FE0EE6BC4958F1E6481BF478A9AEA4EC2AE56993CFC33975C06B571450DA0026DE58B99B6D44F2AFEDE582920436230A6E81BF051BB54A41AE6E6C34BFAF1C7F03A44B85ACDDE1B44DEAAB8299905FB5AD961FF224C717E96DFEDEC50D5CEA646D2FFC5F7B6017EC540924D1C9FDB8013F2957F271C85027985FD4184F22E790F91CC7C44C1890AE83932483AF25FBC0A9C740BAE467E2CA24AA7E86C41A9250260B3A4F805D6421B8772691F172FB63939606D50D03F7C4AA09EBCC2E5289BF4B9EC64A1307869CB4EBAB5C0ABA222C86E21D6EF32B82B7409B10C67F7A7D54C850C277728C15230C56E3B0AA375440AC0B55DEFFAEDE52C2F84BA5FD49A5AADA5AF6C9EADC0E413006F4149081EA8B06A3590E55D55051AEE474E416C7C76F0C41C372B593A5A22CF9D520C59F98942B2870408FDBFA063FD14B6615EBDA85ACD3020382E696B84B4E6E6E28B1F6E279EA4C5AC3444E670F5B1F01ADC3331B4E13B1387A082251FE63E391E3AF0FFC8CD5A77D2B77DDC75066E04F9BA89B65E62F3F74B5EB53068449A3A59A3CB8351B5F8012FDC5B3F7ACB10AF933DD9FB5C094BF085FEF0B27D9B01AFDC95B3B96633C5082369F03BEFA13D53FFE31836D1E02ADEFFEC0CAA084050CD5CF34E1362D4BC422418536A4F5048639A0F168743459733CC11EE616D810DC92B266BCB0B78F32269BA68F264B669302E8FC2E35F998E2B0438EFA2FCA0B14F0B337701A4FD5057AE3F1105526EB726381C54D605D21E9A1887DA4F8AA09C3D4CD0E617BC072F4050E125763812D4621F1AD8001AA027546E472F8317E9F37C27BFD4380D4A5A8C77FB426C3F13E462E06B6D7C59C8DAE7EC747E4C08822569421C70EB62DB7C3F1EE9CAF7CE384ED0B58A122A2C0C669DC843CD21F63E01CEED8CF7C63918CC7CD04B80556561582A4CA24732956700D5AD7E65E1F7D770EC84C6A8B7F7737F4B597E305199C8DE6F73F3CEB730CBF6E87E53114D931024DCC1F3EFC56BAC8BCB374C92E2D687E735DA892726B2E7B30135D1CCDFFA0F81B8986A9E646B9D875487D960FE87360C625557CD5ED7FD45D18CFDA97B410CA62BAEEE3C90C9EC02525D74606EC7EC1169B250E8FF4B94DE08AA95150E52715C18DD6A03F2A399956F3308B8CE72A96D2F41E2CD901D4D507F336354AC24DA68CF8F83B69F12E54BAC40F9A7BCB1D1165E456DDE5C60F5BDA4F8C435550B492B14642A329C90732E6618CC73B5A32C71CF306BD89B074C8174912556C3FB05DBD4216B246239B096CB8928162E3544FC40EAF652CC91004686FDE0A3FDFD80BF2770DD4FB79A7029B0DA6B01C8DB069414B26A05C180CCDFFE049401A348990E0247B542C7CFCDE012F3D6840F406F7BE782DBCF4F6080BAFC7BBB201EF6087D38C211727C15ECA30F003AD52CD540D8BC4DB81375F44E0E092A06F9E9891F6AAA178FC39B3E2868284330B3D2508B486836D9F1F5AF0464AE1DD2D696AC0EFAA4D9DEF2E5CD28A5E1D42E813D3F16DB85BF565EDEAE869A88D082EF43A33F936533D151E0BD06457135FA0450AAC65438C729AAC8598399FE8AC0042E3220E936F88295E45BAF653F405B12B2FA9D386BBCE3B46137253E7C64BCE7E998DCB4916390FF7E2F074FB1754B60C3418DC6C5728E2FA364ACB2C8BF63525849F2CEC268DAB24CA73C429EC350DA2900583D9C8B2BD0AA7F5458B00DE9E44209946F70BEF1C7ECA26CF08DEF56CDBD6C1816D52A373F822321468770A6C5D8BE130E6C752D63A72688B786168480AF505D914C13EAE57905AE47E10CFBD62C2097A7482432CFE5500B804E3715411AAB787FDCEE2F644F38EE9A0784E88DEC94FB9599A68A0105577162A6FD575EDBFAB3D6DA5D2CA2F086A8D55A325F8EBDA84E79D96D794097E62413CA", + "message": "5870BB288AA6130708F7BBAD9FBDD6D41E249D620495ACFE90C61737B57DBA890213D4741718545CCD8B3FFFC2DB33C39AD631D5B5CC902DE4D340DF03E09248F67E89D28071AA50FA532E94C391D2D1A61B1847C6B1088BE555E5C2694EB0FC1F029095ACD9DEB21EF886BE577682CA96AA2EB3DCB24B871336AC5F23C8488011860B455B687BD4CEF5FA11381BC292B4098BB2CFC1822B48ECFD28AEADA71809BFDA190836D3215CFE755FDD9374115E5A0CCAE15240EBA0147C2F89D8D24454D7A5AC2D20ECC0D46C040FAD233FC51C870080F1FCEFAE6C073AF5F7A78D610E23831D5990985FDBFDC6D101ACF3DB0A74D71739E0", + "signature": "4795C93DA899DAAC44BB2F2CCF778D14AF2687E26D40A5A962084FB54F037362BE239723AFB994A15B17B6B779A80CA4C88FA1EB57DC4BF743734929201969C7DBCB295F9D5F994BBA406E24C4A0EEC73368785D9B2C8CA45CBD7AF0A772442692E69FB79AA17FDD80198870BDA0A1F0DD2C89D22BD6660E62802F0D5183A7A9CCF5136E6BB33AE991EEF920FD80EF911BB94AAFE0BE9CAB7C0AC60A8E763242C3E8B4099C7B8B1661E63F756A0B743CFED12484E70151E39CE81320A687286A3719ADF712D006AC81966286C1ADCBF874A359EF391B892D4A72FAA7BB43DC894D0BCD7B77BCFE845677DAC9252046C2578F15C5AFA19ADC9B5D5D6DAA9910F3DC0187F1B12F7F19ABC6ED9AE0CCEC15C76E6003D7F9040F2F6C61FB568C16FA69BFC87E228AB08092D2132E3F50D07FF7020B400601C603BE610F10F19F1014DF1C56D4953B9143BCE64809426F3643D37C99BF27582E4ED66ED8987CB16853148712F82C3E49A4B2C763C010E74347F816DE015F8568024C1B6272A4F0691CC4360ED0B4BB81B576F46A8AA38CDB39972C930CF0774CB5B59871EEE17821B30F58A25BB9702C1A4868CE50FC3C7102E23A75AA751556DE1BD3266084645C8F6AA90B2ED743FF39CBB951A64C5235F1255DA9117630C150E1870066D5DDE4721D2621417AEED53FC1EC5F89D5EC9BD7A6FF0C98E4A2006B0118B2848312ACF3E25AE401807B0CAB45BF54C186A85D096C71C4D14948547792C290212269D8ECFC79BC0FAA3D37F6364E3FE33B326C8135851B20A7D95FF10BCC765251ABD53F4B98B0FE2BB89FE5E15E06D130F35871B5492FFC3A1DDA21E7C6DF0392C714907B7CBB0C977880DE4BD44E3BD1C2B72729D071CC1FC0CC93870EC8996940C943C0209D3008B90F22A8597320B201100F131214CB43E6922168E574BB7C6E4F4A85CE11BFAF32256A649E5C95BFF1B83ECD8825CBE665C6FA98611EE7F4977512476010015DA2D3302F7CAD95FD70910974AC858006DBC3AD8F8995C99C8FCE87078CF218985CE6817336E501480B53F81C1058EE0F7BBDE9E212BB1B067FF34A3F8B55DAD9CD0DC963F8C8B835DE200C294EC402D01DEA0540F5CF92B55252EE651A4190714581ECF2C9617E4AED4BB0230C23AA16FA9502409B03E6A3FBA7D213BE13180EE2CF63B73D0809225F59D2FD14A12119F0A531D250BFF575DAD676F692E21604E2C83AF932BBB7DB4F3A4B15BCBB45CE3C52C622B14561A39BC6582BD2ED428FF05A50B57DD355469A5B36BD5CA04E731F688BFBBF30C450D35FA94E74F7E9172D7F66DBBDF13FA634F3BDC891CB49CD5B33DDE0FD7EC8C7E538ADE84B446781918DB26D363598DD54345FE4CF3673F69CF2A368EB3F6C6FC98E369D9A514F8359CCAA96C8E8B9565945D7C8894B6BFFBA4CB0FE2B1317C424A080A189A5AA8FC4F09E94CC90F3CD74626C519C2A99C39734F26E3FE99DB512896F881034580E2882914411AB3581D8DB80B46B4ED9B22FBAFFC29EC1DD88BCAAFF56A56DE5055245897764C3A45D511245C3523AD1DC7898DDBFFA290683412E8B7882514372240CD523908B0C92FB26AC669327F840A9496BAA63D1915D3D1D8BDBFE63BDCA662E1AA2F4BED11F07A4096A348598BB1E9A239B2DF0CC2C1A7D62F91A6D18B1175CFEC5B74D63154FF2141F82EE5C7DA9BBB4523001BCD174EEED70225F16C73F2F443079E9BEE77205D4928A05166CFBE014A2079661D8B609EB4E66F992EACC830D0FC61621D65E34DFE8EEFA5D782C56426E9EFEB253EB8233B08A3A6CA4AA8D3916CFFB7783C9ECAF0AA859CCCA99AA460DCC193D878D6643492C10101CE59809C5186E3459444C395B036390AFA2E75416EF6F04939710CF080790BF2C6E626BF9E872C7D13CF642E9D9C57EC8DC106721C04F13A8BAB6FD151C8416F523D4F2EC038A2525096EF495273976F3D1E7DCA57D5758A213FE5872F242A67F1C2065083B1BD0214642976155FCDD227265B6A4EB47E6C44F56179CF514CB6D0BD33349381CC4EE48CAA16318DD5DF500E7BDCBF5A46DD24D0A5D5DE106B0B3F66DD75D210379C47FB5CF11523CC42A77CD80423F41364D064427CD016565FE2F1F7F2192670FC6C17AB346DBC50EE30015D353239116BE68967C1ECCFB9632969B848C2C7A768CFA771C8557970D77EE918ADF6208C9D803B41B184814A3C99178E835D89BD47403764EDB366E6050D9B342B3B3D6409C577214BC7CAC261C989906A57A0B4BD9BC9778B1D74076CADD4ADC43C7E79F2A0CE5F2E81C36AFBC66B526D080B85E0372859D64C28DF6A7B60D3A066FD3DEB847DD2775A6636F4693F61361B9D84D19A40A0EFB2C8861D9B27E43BB504EA6B082AD62CB4FC1B6FC163AE7DAF8D6A54CE4E9D33B509D4D7936267A0D32389987DC33DE09ED37043816463DFB828BBBB3B6E4E5286C091A494ACE782507BE750537EE9F2E609AE4992B8FD53E0A38CCE7EF962B75F749B74103477AECF55497CA31741D70B1F207CBD694A8911653DCB4D1F919B728EB2C03177675136C11BC2B772C5E1C5F4BA0FE431BBF4C1755E8DBF54A6A111733E855925296C09DAE549E5AEC0B6E0D9DE07E077825941D970BBC9B7DA939DD2CBB373F75530CA30446F3DE199709A5E68BDE9D92C6A323933F214BD4F3826860A131F301DA7895F34EF35642926FBA61A8E1C17492C31D2D13C20DB60F9C6E90FC0152665A21100E034065A67E2E676C33DAF403218848859342991888DC47F12A2E7522B62B1845A123723639593543CAFCDE6D9FCB2547746C2A7DE5182FAFA8BE1C794E8E1C968B70C3BBD84899AAD7A2231706C108406A7BDD6931A70BE7441B57E70AC353B9E8127DED14FEEEA41124F0AB57C6A0A857E022BF717439A11919962445A480D18B2367AC9E483C3A0CA5C3AD667E7A1EEA7D50335950997959333169F8E76E07B051A89B1755AAED4C49E0532E9D0DF5C9AF99EDFEA49B83AF8147440CF93C4056551873EA11887DD9FCDEF04F7CF1F5EEC712B1E70124C6155975ED419F206F5C16C3D7CBB13321599A4DAB457848974B74087DCBBE990542FB6F7F36D22469E3F68EC189893452D6F4EB180E9A2D1D1F010524A1F501F8DE4C484B35E47E517E166D1F9394DC6CB394C1FB1DB6685F07ACD0D25AA4CA1E3BAE21588A5C9B4D229A4C399854EAB3AF379E3D4456102F021019A8097B06CCC6B6FF912158C3DDD27DE33AC093EE6EE76CA9F8A90C2AA8E07A61221FD9DDB6EF440D6DAB8FCC2138B396BA43DB70CDFC90031F424D4C917F4F4C04D6B7ED87FD103FD195F39C755500B8C4120CB62D3818680EFD3564D5626D6486FBF8CF96C3C179AE85E573D1CF858252DCAFDB03DDCA86FCC65DF85E5A10AB4C549E1289FA57EDB1B2899469701678810BC8E709563B4F99AC7943684F4C56056E26C788B3C8E87DEB10319D56A52B3D25CC491C6771496F4A94E5A67FA60777E899945E2F58C9D7D5759CE41733E6845D6247812B11336062C88FEE525C44EE8F73EB1A0BD66CC64330356C7F2DEA6D3465E2C6EF0505AC68502165F1701FD40E0D5F7DC41583C076A81E56775034124910BCEFF7DDE4A2FA0072D6A6BE8695A8440BCBCEE4A3FE9ABE0F0440A9090ADDC40915D2D33D88F1489888729BA0FD0433828257C44E0C4D46E9EC6C9586D5BA3B9D772ED20BAE620E8D4619E9C720632FC92E153D7068E67A6BEEE16A01731EDD5AA48DE29B083820DE5B1171BAF4E75262353CECF8E2C2174E530D4E3B84F12F2729CBEDB10B62902ED39156C32E2C68C7EEACD2DE88C50E9F6BC117707A0E931311EAC9F836CF4DBD7DC289ADCD4E8A536DD3C7C5DB082FEB4BAFB6B7A48FF9C129CE97FDEEE396502319F6CCEB8B5FA38478DF2C0619CC74E43BC22992A526968AFA9D147CF6A2828ACCCE98A97BB63AF3576670C5B61EB5EF7D30BE747E1668C6CF3226B5DFC8FEA39E9D1648003AF4EF2EA6DF3171F7C2230B9717939EC70E53CD9230BA1E77A1C07D4E6A3CA26455CA7B8B6096C49DDA4A9BFBB2E03C3B6F5D6EAF4C78B87FAFAA5B82C0CF7321F5B8B1D9FE67E765A2C073C844174A21E9E8E16656C0D3D888BE6EA17CD1827AAED796B716DB2B23473472A574BFDDCE1D9F92E179FFA2231E75D63DD2834C792211B4AF030FD4010DDFBA1109F1292C3063A65F612A6B40849717C6B35176A42FC5DE4EAF90943B398357AC5ADECB7E77F460732B712CB0EE509D880E2B6419C2E365EEB36477BBB110240F3B20A66CB39722E9986997642396316E7A23532B2D75389B4E39EA49DF5EE29FBB5EE6E0B4035CABC3ACBA0D85AA7214553A9E3ACA04C0C8B800495220A8E0BCE1D0EB6E650EA0FD8334FE24C5DB224F5CE49490F0EB8246183F844705CD75CFDA3CEC386BB2EEB63F14BA4BD86465C25C97DEECA55D14803EE1ACF6968D8820474F86554CF8A1DDA9209CD5162B158031020277870B55FB8BF5B7A961238546E8BC5FBEFCF4E004413AD9FF4671CBEFDC08EDDEA1690D37D29786157C2856D3A2D3D2AFA5CAA4AEA82A0906A4EBF88E661BAE0A1048687AA1A8ADAE0D1A1D4349526DD40A3A3C667791DBFC13344A6568B2B6BBC6DFF3F81C42638E8FE8F1396B8AA800000000000000091119252C30" + } + ] + }, + { + "tgId": 4, + "testType": "AFT", + "parameterSet": "ML-DSA-65", + "deterministic": false, + "tests": [ + { + "tcId": 31, + "deferred": false, + "sk": "F26BFE126886F48222944D0218FAC17CD8A9CC6D67A023FDC07AFFC2D025F77063850D880E98FEE502E017327000CCAF614573B35ADEFEBCACEEA4B2C4D045E5BBFD3E5A72E371AD83B9949877D8E656D46B47750F730F96DB430B186088675D9A9BD78E47B89D04A8517ED2220695339F99A97F353CE4204777209F5F3C9E9A36145401574860507528646172605420754860327385342468637173812671683261247114182615057736275035218250153147482443761885661805642701060601454260806825080836130504323487007071700251371508282572616708526344078860420317246480087023564146174601577402763164738350627261627545734633651436461226043402812034418826773340185803411658880488327105858342553420184612542803671084317600408546717156005015334313375713864377855754817560373128522078655376108487571366035681366668415564637026210230283502458880020644582413888322342250471101864560673682221874116058608726318512708483886888510055025777421323140476807225515610631221038627302812013748325386154650053487610488183585444624674383022656414177865641752561360547650014323816810630612516305044130875005020682155746118620515510824011381336483230055736240617515782114136421470776807676177550611440828783508730863530282010014818346523102542402254343533717020615574330102605824801246413810766734634885064804232266577168180432013101552227557210004388766284770777140720537417511766844783610352100540465561472670402210344101034833057232758245852070808220236281154780236723733444338510055030034813013645110633822278754202404504474305304442022826642474758611854325461062827108274513731884735151671470110708621625273668440118637450311343658011165286425181511705680573603763858611232338138748827471818765582660347616152406781640034572316373318502664436248256388610405472702422727847078630487284570634783763255664813062772284201074250421764772350506225034112667030542041601271786677051531312620325053837440266847414403520403044642750774706158448131432481174806885811767382276161844554785364411520181504100002583416222125488777048842577754016462488816570026628641240306053064402487875682123300581177266887150250351422720810352735363571360412047125557581638632134517633267041181107371612011428567810862424320113575346462405201656833030612075070574141743722304186150136731753671023874218020486623525477274573238860508882702372084466443612576614251217346482015461575031656475447648164446558064265327221087840315351520861404032643314331454634368744412177612085062851156277203858782712224671513811154003783615573428532137350476005672484601566762361451235432358283216038622103627640346688507300538731375011328652186416634871704724853186608633528582681770888456527704482222545720317647262504353844552114021364748768687305224554458346645480073287524354541473248736417484063513406154213148630574248474761110166377122661312870342501307676062158428731727603762678058825258617028588762036573081836105802145740112745128772630145484137806001264003744684057052707415622314023265542551602653216334446480452065344401128466756817275513821864603228721706850751311443512600213471838788638584557230388665682183120086147780868372104654758703458732422306605012887857774238665848557856306556175462287001853080307504270FCB87B223D24AE5DB1890421C3FF1D59B84B19E24D143699191C7E9A464842206BBA247E8C6B27BA26E68AD5A71D0361CD5C74CE50C2CEF19131EF5466237FFEF7FE6B5FD198238E1CA0B10130C629CC9191F5786F5CD628A42256CB6FC7D7095688AF1BC84351A47B4B382EF61FD65C9EC226F42B0A197C6AD8F0B015D0B1C7E01428956A9BB2DE9A97E57566F8F56686A1F4680CECEA873B691CF8BD63AB7373BAE8095BA7763E50D6839D0035BBFB91BA60721798FB2C802C603A08A12405E0B520EA41438FEAEFA562DC7892F4589F8D2B965EE54973A72C8D335C626198806413310310E32EFE6B39B5CFB1D133ADE01BCE94216CF4CD8F8643031DB8C247B57321CA1EFBB853637D0C575214FC77A5A684D50ABFE4E971998E066E5024DA02768AEDE13E83F05154A9992948427AA98C874251AF569423538944FAD893FC656E9CED806A85D9C33671022529368E7EC70C9EE974301C08CBE6AC5E88E637795CB2A215FFAA08EDDE40ACFAEE2A40D505CF58A66966315A68982403D81BFA89E37C9E421DA588BA7E422AC7446A1E61C822299DFC34ECFABE5CB626B96C8EA6C93BDBD2D5BD70C5F8267A84E007A7115E5BE5F12032A37CAB05D541E3DEA51A832EDE8D349AFDD5E6FCFC8346E3D47CF17FEA875E385DB98AC2DBE8B4F80537310DD94CD0B625E99785DB049A01F54BA1F42ADFECAE2411D32B2F846C88A30C76EA0A38B271B6ACA8236E61EBB84A9DC49E5C5BEE7E7D8DA2C1A1A0A31450E08FABBB1B1F05AAE300D8CDE735B47BBDB05CCC0C05336BE451731B6B777BE5CBAF98535F7E08FFCD8A449E1D436A4F059901F56F0130BD15D7511645406BF313CA1F2202A4A86A1D047FD58A3E877F1D5A7975D16D67B323C6287B9CCEEE989EE844A93E7EFD3BD9D8316DA377DF0BB9E261A271D50CB70167C30D192DAADE960EEA335EEC52E52D9539E1F95D9EB65E548F166099ED882C3072536A6CAA0521A5AA7C6472A0C04F80DA205D52187707DF5C2F2EA25FEF00CA7BF0D3B7F81E319E61CA2CC5A525A27B56AABAE4D535E5EC242D811A24D74576BF4B8A72FA5FAEC1A283B61D60287E1E2EC8C6AB04565FD5CD64263494E8034163355B4584CEFA0B6640851AE123E98FBDA923FCA38E38B384E2B954414B364FB8B08756048B75C78531D4A51299C49DEA4B368C1982FEAD4AB1AA5235A4A17FB0646F04047BF08048A11CF8958B6834B7FD0031306A39C8AE68C35365197C1E5797FC473EB19454486FEBAAEC5C2EE92CCC3AF3C743087D2D564B7DE9E596F3124BE908F3045A751A7D7E37E6C8C1FEF332632D0BBE05136A44587F545F5FF52FB80BF2BF0BF4302FCFECFE08EC51F229D7AC28E1754261BCE7B1534F7D3BB08D01151EBEECD954C24E703EEA391426B701795D06938599AA7DDCF92E44569BFA9D912A8E894851E3D053B3AD4329B76A50C0784D42F37C5F9006AC2A9D5DE5183FA3C65ECDB6CF3167A47A8F5C59BDD79B7C240697E15972850274FE41AD84D90DCB341611E766D212DC763CF94C8C4194CCA91B210328E4A3374E29D248112BB668A392C20D87910376B5001F3FFBBEC3E008BF2F46F7407383A80DDA082BDB8FE925E4F12B3792270E5A46B8C57B6E5A4B95584EF380ED4993EC529FF2AA39DD6DFE88FDEB6EDA0E8DA79566B07D37AECC6437259518F97E6C8612B3C35703BFF992153E660E2E2077A05F265FB5121DD79F0A33BC38EC8308E2A984CD3D8AC609306F7793D7DE08D845A42128264E5C177774E35D587C96B247054221785DB38DDC6FDBF7BF6F664BD63014C0BF942A83916CBF2C428541EDA2BBCBFCF935DEFCB363E164AA512DD5FA795331400B9BD03CE3D72D910562C381FE931E8C379E3023733AB9186E5DEF31E9F6257FB84774CE2823D44FC142CBEB598A68FD3948371A5D0C0964C6E1215D89F658E5504AD093BC8602BAD236249D7EAFB6A1A07CA7C74DAC307A700F2F8140C1086B21F2E1519C1D4694932A1C18CBED0D0E29DEFC525297937085E2630DC62C0C050C4FF270872BE7BB522DD6991B596FC29211725D9960B16A52EA91781923C03B719D09D6E7106DC57055C19EF876E5EC2317E7E423C971454072019E28E65C81ED527AF189BDFCF521C923407554ACBF6945D185443DAC1A1A088A68B517D5D990E11030DE4F7509E87A77B37CF20A78E2CD4894173C32A327355116B71851444265606A0A9A6D9461CC5DD83B527E4DBD6AEE033D661C3DE8C18297E5D131DBC8F696E947C95C71772B6244744D061E14453B9FB11734802DBA6F8179B80DACFEB6BADFD14E0576736F8010C53287A3D3931879EF273BBFCDB5DE5B88AF51FD8A8C8F0A5894E225DFE873FCC03CB1C9B57825F11175C87D0878B9E6156B401B2FBE30036BFC7DB1000271B7FF5D63A8095075EFBD34EE73DE6014952D15BC30230702D87C9A96D5E9F1F0F9262596AA58B7E41AD9A09EADB944B63FD98B347D11BD5297C3BE2823859F2F35A4E54E13688909C31A83E7DECE4BDF31039C72BA54A1202D172A6B8A2CE96DEDCA5B24F7B942C14E133DAA8AB8CBD24C1F0BBEB12797672672E22CE6C21237B2797D8E54CC8FC76C43B4752966A3A40944E72D373F0D3E84F9A3301EAE9EDA35444B1E49E66118206A56EB46D48D20954A779A1E74E3E3B2BD403D46B3351011CB6F8A8672B2F3D990314755776CE3237F0A50E771205309C05D9A78D36888A83BAD78E86EDF36A88DC71C5F11568390D0B59202E29EE11ECB9F568963E81770839FF239AD03156CC071E8B7401595ECEE6234AC34B711703D68C67A2883BE9C18AB7F1A1B2E5C90A2323CDF1ED49850B83938192F628C9EF65B779395EE3734C7A901F7473886D712D215416816C3016CC28383D4787B46F689DCE111DA4DB8AC10E84F66A5C2BDA1B3FC977F6A0F732EDA4F69B97551A4B8B261D6887194D3AFE7F4B87FB3D41AC6DCDB8FD39BE50F2F382BAA4D19C7450AB3A1AC4C63CF930AAA517A15D5C0D549FE03220071D369223E51296ECBF80DCD79FBDFB8DF62904D5A36200F29CC47E80C8615EF1B78DBB26A1AA7A66E4D9A51C972AC9C94EAB99514B5ADAE6251E8AA30A5E587424E3B7BCC42EBE7333D9210972653F8118B83ABE1BF7E9EE9CDAC28997D144C34DEA65B59512C732927DBA8207D5691984721B7279AFCDDE06A6BD2680EBB9B2E3CFEE9A66D73D0C0DED653708B090B823065F9707849E3B37D4125CA693E742E023F058ADC95079BB00C56BE0D2F078182EFAB3072B0FD09767B8A13C2805A7591B5B2E12475B5C824DBEB157930AB389F915FCCEC8F48647EE4B66AB6B536C22DE3E5EE4ABB42F8E0009AF04554F128ACA3CCE403BB01FDB7B5E2A72B82911C1FD06523FF90192141C689ECCB0BE61B4C6D770629590218A4011A68B86FF50D23039C9BCD4361F6980A60EF88D1440D304C5B4B52D6EDC29112DC3A8AF28589E8F62948EDB6BE76646D596606B9E705FEE3F144A07BC9ED1D400C", + "message": "885A0BDD8DE74BC711690AA614DDA532F4D8C7EA2C27855A578E6361CAAE2C0BF7E773B4900A3293121A6E0DD610107A7A65BD6E11F619FC0E9CE7BF7B5DE18076E1B725572097B247D8E0462494F63F4EDFBEAC2FA2ECAE0CCAD428BD796CF26092A1CD505F593911ED10FDA426C7E3C5A439E850421318AE0785B05AA99F58D6856DEB78BBE488C70EEE42BB9AB5927B2ED25CD14377CD7E1A8834E82148002FCB985AB9431297010B2BC70F9132373C6DD2A2A9CF246FE0262E8B53E693F3D6FED3EDD1F2004ED17C2CF5B257F4ADA5DC1A7C151FFE03B96A4DB991E4132D01DE1F033ED81357EAE7C1A8D2DDD92DDFC06F671394D2F60212C6E449EA359324FED38C84D36D15432E11E7150015804F97A3C677382CD46AA4D7ACEE5686FBCED7A9E85D29C48386E69F40693D9ADABEB43BD0E5036ACDE631B54957F4FCE26F7A24B0DAD4348A6789CAE106130620ED2FA0EA38F575F28783BC92B32B0C51C8A6546F5D88095F9F73C65BF6F251A2C469746445C588C3EA8139E433D4FE2DE4C0D358B6CA8A6294E6AFC1B96074C068EF67B158F1129CFE0A3AE7EB9D454F357FBB6AB3B9922B1BCD55586187CD24692482782334AC9F2B861248F6A530E93E11488784DDE5EA678AE505903E231053308C1B8784607E063F4898A4FAB601D3E69685972155F63F09FD84B2B3DF741FB642ACA603D0D596E0A8DAD424F4640F98B96FB242C695DC331F5759F75EAF191CBD985EC5998D5648C85EB631295F61567C1163F990DC4FA1714091261E5F3E5F0BFE8455BB8BAA1D69421F15374E73B07E78579D0E251A41EE1A5043AABF8BE773EE7F9D0FDFCFD3AE711FAB1D3DBCC2843BE5A946B24D8B9B94358B5F598E88ED3D53F310F8EC63229D4F5BB1B6D524A5AF9C39477925C7E29095FC43F171FECDD061F362627121752C236B792F1B3190797CD0575C584F30B556811961904509C98BCDE8659D2280F495A0C9557D3811AF5ED4377BC7599E4959FF85F2150ACDECC1F7672DE1EE4DB44C1FB5F7998AB5DB742F6C5D32CBC0F2FBC954EAD6CC134B9762DF331386DECA316947884B9A13ADEA5CBE2956644FA12A7BB3BFB97E1D93A70191AC38A0373258C2C2816DEA6EAF880D69F45FBA4C290F18D34BB8368CF4EBB472BA499CBB54501EE3A28E5FB9FDC66CF64572094719BBDB48F3F488513B6550E127E8341C7E53DCFDA7D40805580BC7D30A72F244CCDB5AEF661B0F304EC5B7AB93B8C5C49A776838B7D52374AA41630224D616F310E499ECADCE93E78B94D3CA48B347BC0EECAA2066022965C807BEF9029BC5228F005EDB74D4B14498CE3AE13BEB7C693B669EE9F9A6F46FC00EC05E132BB6C6760FB5C51C8323ACD6A3C75A72E9738966D125B9613B3145C67B5E988187E85F29ADCBAF74E33A611FFF252AEBBAEB1EA641E6FC8BDF7341BE2AA857E443ACFBCEB2155D081ACB4CCDB098D57CEF6F6FD342DB2D83B6123E0AD3C93F300811B8D5A11A5A29BE60816F69B29D1D7E158869D860F6FB829DE80D3E1B699C3AB6804EB6549178D9473338D6AF209E1F7D263C667AE6895F6E2933923471F199581F8A51BD9AA452EEE4BFE95669ACD07B41B00C03F55A40D10B50F8E467BD071C8F405CF119612D32405BD5275A6BBF2217F9F1790D29997B7B6B1EC8D7924AB9E644C129CEE87433291A2C8ED6BC3C2A19D076B177EE6050692ADA8E95574D6CE9ABE49795D8F28EAB69676E7903A656FAB32025FE3465CBDB5701C177209D9189A5917C1337DE39F575E5DDB93CA76BEB52AF32E8D7127B28F7CE7312E803904721AB216E92A8A9E609FC10AF8DC2AACA14A97BB0E4B234C7000EBBE0C442F185946B7CE7728095CD60169B0BD97B36B3AE3855D98925B29D9294EF277509FCA407EA2BC47659026A8204D6964FC65BEF3531E9C1E6F970BF2FF24075EA17D136ADEAD2356B6CE498F93CD2F9E5E190D209D93E473FAA8ED92096315BF1FCA655FEBC78E09965C97478296B75D39056604D3271916DCFF225CB6B9A34E15DC164B2A68A3B42DE057A6BAC1732CF5945BBCA12B8B36159FB89F7BBBE9FE034218F5B3BCF184C207306E6D2EA6959EAE0890A7B6802EC1DA082BED65BB6E4EB4D5615701CB0E350363314A4D101DBBA605371A38B2D8A37FF78EBB369825388AAB7D3C623B93E512D96A9F339EC968B352759AF3E8FA3211C39295B0110E6DF264E90678C11E2B903AF322E4FA77028D3ECC44F6279D63B1E60D8067241015FC4F89BAA156A78FA77BB2914CAC281F4409C9C0370ABD7C1F8A5D1040B59752CC4FDF0D19CB0C56FEF34FA3A3BCEE1F064E360E86DC55DB5C9375BDADA672E72F664E3ACB2E6D8A08409C8CD60A1F95380AB6C3ACB6B91A8A9A3B775504979B8025ADB3422619BD11E2B54FE6D075881ACAC24532031CCD299060E4EB7F7CBD80836D4B823A5FFA4FE8C6B983D2AAEB8F16F6C1C2281EFD713FFDA22069A5D8AC491291CBF49F118C946D50F08E0D1732814E81581906A3153940114BEC8EBD49C73790F9ED7CCD985EDAD8DB3426B151398EBF16EFAFE3DA0C7F38B22760576D4885273F5E40B140557107FCE0BF8461F248BC43FBF5CEEE76EF3A9EBD230956C7B98AC898A399E5C2AB0CBE9E5AB9471DF5E530C72F26C34DBFE2F83683EB622F9647AA06A267D789736312C90C9E59D77122A88538FD0F53916AF08B236935CDC5BB3CB490C8309E6A79B43E7A54A8A07E1BAFB9B937EAC2FC3ACED30641F337919D2DB54EC7F320EC51CD13C00B9E603DF6DD2690C75AF3707B7C93E91CF0278D743A18B4E6974B424081042B5B4E78CEB7FFF67980BBCBA5E29BE61335616D65E86F0E746D183DFD46B75C9300D60C519FD95A8A661FFC82AE75DD149491F99D1414F1579008A8027A6C998D3E7A2BBFA07AB53EFE817AE9C6AE8D052AA859D0348B0D2C85BCCC4508490BE0F9B3213B8AF7CCEE722E28213187146C5DA05B765D83306FA5A6B76D69276D16A2BC60DB1ADAB5762EA76374EAB2D34D2A357C756FBEAD6A9E3C16307DEB95E5A302E414D43E91CA15BB24FAFDCE9BBBE735590F0D002986D13509ACA4CB3153A26143867EBA727334897589457EAF97E8BB0BBF3F4846E69952CF46B1C6539B446A799D668476E2E4984753E6C2E9A08BCB72F86685CE1BFEAA1AF59D671B7BDD6C5C2F2F3B536BB36234FD644590A4486CADCD4220F7909998C8C9E03A451995AB997767320D3988C5296E1657B4C7740B2FE270A11766E3B3512C64EC20ECC04B55191D04AF784F2E7E5997EB53EAC53DB611171564EAB4A68C16AA5C57F72EB1497A427A053A1C4707D58BDC1D7FD9FB88CCE34F9E19C59793124ECBBF56F3FA35A55B3DE64DFA9950B53F2A7257B8CAD259A35BF1546694A838C80FC37D0C36F00E23C63ABC553C18D4A404BE6DC05B120238BB8DF408697B95EA4B7A137E04B9ED9842B2DADD1B15215009BDD23A927442133171C6149840D6A117C77A5D68EE61D6E90044AD3543AA71A28C59401CADB1B5D78C5C6690D69887500020B596C3EC530DFEE8543A29AF9DD856EB30D836A1388D012155316FC5C1547EC6D4D182D88DBD2176CDE64EC708D19DC66697FCF616E4F2386F51A98474BCCE92F122812B9EBD832DCE4D863AC56082FEC5E4729FF76FE9560D219610EAFFC4442114279BC063AAD937E466003B0F59F572848448F0EFA728CE418F4996BB12345DC13A2F65F5735A2D738F9E98A7A79C6B2CDBFD3412156B339D9143BDD85CB782FEB7E29BC5224E71B85B165AEAB65F954D21F372952305B3D5F48843F5127889DA794F073CD98D205E825717C9313825D538D050E6920C4DBF2F6552429D041F62DF8C12EC24DE1D72DA049160B4D34B56DAE10931EB69569C2B3C0AF6FFFA5323C7DC9C7C8EF0C642023C4FE89878EB3A6C524CF037E74F7BF891ECFB102FAF29FD39D9900DA7A927D131192AD55F2E18272B16AF14505DA17C9A14282897731B672547C6810255730161508588BC161CBA0582933B164F44F06AA2531AAA8921C691E6EB6BE81DA9BE51C563955E0C1EFD3ED2A1C949BD4E00B3AE9EBC13C4C6C4E5E394CB034B9CB75BECE8644FF89EF95E76EF715E17AA26B1FEB774C5059B3A39A38DFD057D641E43FFE0F3E40FFF6B2363C1BF0EF07873D09A487769D0A73CD0CC644F53C25D2025EE71C69B7AC0FA6611557C427C069DF2E1BF629D9A0CB5C67C7EA4FA658C78D0042B059E6B658FFCE60166967DB94F716EB4D04B3D2450F40031F10ACDD07777FBE9FBBB77FCB7C1FA9FC1EAF0C5F86D7962DAED0474BA0FE68D9B23277A9CA7FC676C6616B8E439A1D4BFF72437819B5518756A7873EF584012646C3659A6BA86E62272614D85EECD5350E3CD0A125AE9C17CCE25239E1EE9CDB39CA7B18CF2C88CF146826B6CC1E6AA8E1692C915F3BF1C1DB34C6F37883CB4EDCE0F7C995B69E3ACE30DC166F784C93D6CBBCAC3C79BC319310CE6E665700F17F962F18B240739D15690B1B6C85D1AAA32D4A79744AE50CF9A90A0954B4A4D94C499B4123EFC0204431F72285B5DA9E1922230A304D3A1BD852087261B7CF0D8B90D14623EBCDC6387BC6AF65BE5F011B6BC123C1306A1E8FBF2DF0B6F89B0AE05DE0E4B7F50ADA46E53A9B6BCADA0643BE6BFDC2B06A6C75883C2DC613AC7216317A40C4A2C0866983D32C9CE0A6CCEDF403626BB23B5B9DA586777C735E1911D77B1196C8FA4721D6B0FE0B0811FC00B9A1242CBD4A92431008BEE9E15D1982DE34AEDCA6858F193020B6447F6BA6637059DA8DE0F8468657B81C571378418CF57D77AE756C59932E052503D1EAFB2D60D26123EA0EFF55E324490019BD1E5624872F7B980736D27CC59BE04E29ABA1B8351531CE651424F810B5AB3ED558CAE5732D7C8BB46275033089FE32F86599D088D5728803C95103BA2FFB7C390205C4CED8B3C27B298EA79D3597B717DE280B32E541DA1D98BD27EFF7B443091339C74016112071CBB6C9B08F20C1F040FB6E73048F73CA45DBE0F9258D32F23E36BEF788F8134D9B10C2580B20F878B64C7D2AA68140D13050382A5FBC818E0FD4D08799783DBE2515F44561A31A7D053FB5A61C41C60EBE576FC5B63863905523FC269EFDB86CF2996B6D90FE28A016EE63C24CD6B20CFA6E8551E42F57918284438A44316C6802017CCE4DC07C43A954F50ECAE61598AE41570A66BA6D6E68B92E0D42D2F50BFC2DA8616E604E5178EB0C529EC04AB092855C3A3D6995AB62EB2F9B12F52EB5A693CE1497A71E0A7B9474FB65D05A9755400271879C9FCB413F088D6ACAE6ECE67122F8589FF194F6E4D6DC35D7EB6B789966F9E21527C98C27B4893C15EE5271A9D2503CD231BB3AE587AF652BF2F5C944A2591C5796B9C25ECB8A5B2B7A7E933C0827CDB4B01BF3825078CFEA2857B10FB4B693828E7AD19F04ECEE243D8A5E56998D83A4057DFB36DBABD16759C74AB9AF99B6D8D42CCA8CCCD232AB51CE2D22E029B1731060A86B8F68AF58069D7236983FF36BAD3E7F4A009404AEE98A9E8A03D804CCFEE3F8A20464175477CA20D0801B36EF5931FAE4F5AF560902ADCFA6BC2623276DF352CE2F4C9CA82375FA569E075BB9305AB127FF72BF50B127EFA10C3AC97221BED8DCD5664A0A58FA57B4000731F24EDCE0869945E545CF27357957F5A27A29FA5ECFF9A99611E14A6CE5B88E78E6A14697AEB4F36D7F8ED1866B782B55C5DF0F4378EDD238E58B947A06C573175593ADA5ACBA818A6D734BA1328F21A65B513158D0E40B9346F251303E60E1CB3004158D1E87A6F638E0278481182B37BBD3DBE791A31B6B20CB2C52B1B96A94F8CDBA5DC7DD793638C2FCEC4F2B5F734403E9A9F5D999EA61DC6A98BEDEB934CC76B0E18C703AA57CD1C02A8E7D478A63EA306BEE360BA8AE46CD0183F607F9ED8B6997B6C35D756ED8DF018248312FDEED8EC5D8A6C0360E66A4E9E5A97D5CD24372C0AD2678F2B00812AE6C1A0F5330B3AB0153DA3C5F4C17BD2FB60E7E80874C1B929B62E389EEE2A014060D4DCC965AF8642A05A9EED50D2390B067D5511D18BCBAE6A5AD2918D506FCC9126D70A86E968B5F9C9943070237488CFB5FF5DE6926737DF63A2CE55801C348B0F00D56AF8C0F5CB3BA448C39B020D2938119994EACB91FC31F347DF33E1AE1267CB7220ADC0D14F8438A2346379C2AB81F2472E2EAC467131733BDA007A03EDE8BC4D6DBD9F1B8F4FB831314CD36F6DCD585937CF96CEA5292FBFC9502107B579FF07C2E79003DB2A16C4ED417FA0F13C8BFB182F7DDCF08F250DB16A45A604A572B0EDC4ABF9C86088A5AC874DDA26E12A0EF635AD282ADCDC7ED1686453DFB35C3B1BA6821B4B7220B55798B9CCFE066615CE255960D09E677FEFE76BE915E04E56544BD09D06F8344F968DC6825CBC664D518A441E19B076FC3389137FC1B7332E2B06895443B7A002336311579A9B08F3673DA0590E696CED901444A70A67B2A7D5512D65BFCD7AF1E34277769E171088301DE7846F088F487C4921BEB98354BAE9AF6EAB2349114EB21F618DB1D926C1D2FE3A5F229C57340C40AEC11C2D0144D0394FC4D8E3866A7D0A10B64C8B992B0A4DDBCAD824E43974378EA9A38E58C2C5AE194AF4310FBEC9028416C5CB7B8AFA524F74FFD6F2E98443F5E8924F6CF110E671B816837D59B2DB91CB1E687D6A2020F9108F69B947662FDE718AC28A6ACDA27F43359BBBE362CEEEA91E691952C580AB2CAA3AA39039A753C276E0289174B02427CB42EADB4D935B2309E2FEC9F25561A3540F1AF1DA4A8620770986CDE1E89C1D330BB827240F2BC53C7DEABFC7DADBFDAE0A7A10CD6733736A1EEA69688790E4A2C694CE530FBDDE1FE8690DCDF03F5172FF4582DD3ED3D7DA0B36E1ED3BBD957BA8B0072C4EECF39D574FA13F0D7E9100C7A5262D0C9D52DDC11D4FF34B255F99981B4C9140291815629F6A91A198E74B3A3D128B572D86F54157455702662CB1D152C7F4C9CB4DEA207D5A938294251674426977E730EC6010065C8E034882BD32FD35C6AF6B8D93A509CC339D96FB9DD558AF95235FBF17197760475EE2E3FCA0E83A8E31FA7F13D78CC7964805E7705DBB70F73533A56D8B77C12E8F65107C90143975175959465FD4D8C8CD3A8EEA95EFBC7F6F8400EA5D51E79B40CEF8B04594D0C6F08D500A2AD08B462E02CF630311ED7815661170DB39F277538426EB2B06CB8C9D820C8367D1D57104EC145FC93B1F77BA13B711216E58FD00C7DC00518022425288AE1299A79BDC7732DF3427033F3F84887B4D491E153BA4A63AF3AE5CB3D4104B53087AA4003561002F36A9FDA33BCB8A5D0564329DA58128B6A9DCFCDCA6698921DA4EFAC9E19DEF7FE6C3A6646B4007F08AF31D6D322591F34485AE14E0F6F2DD0E58E343BC055022D174B347846D4C47F1DDC39946978ABD82B6DF31C0B0F4AA0B2AC1A797F9DE5E8C6404BCE324BA13C77ED5D590FE07D0007B4D8A63EC96D621966C3E7103B6C7A364975E678B38D041331E67972640776942BB4EC181C323C26C481BF4FB56E5D67CFBE1757112BBCA0F0C2700694269B26129C7F99D44AF560CDF7A4702EF5D6A2EC0E99002E8930AA4EC06211930A1E68F2ED448B104A7568BF46E141D60B6153D40310B38F8E1457278FE349B2B4A7AE397A7B8F48AAA5FDC1288E43E05839320A14C63AB858E26E7D8C35B64737904D89C19A103D6B689A3DC90C72FC92E35D452B8143023070D48BB9FBB045E3C6CE9A8BD5C4B67F5D8B58C96A282D6E27783D7B990E052BD95E86508F9BF7C064A8F239E0240A20D8DF3A876EDC8FF6241B54F270A98CB8077AAFE0E58E5E9813C6A5F91F52897B6AAD2426C60DA5883E6BDFEE330A8609A2118B699F75CEFD0501951464CD62040987FCF6B22ECA92E44F55B38C6499A8DA0AC78256930367A4D75491A089D8941F6C53CCB260136A93E1FCA3DD72D55A92359E3D6282705D54AF57C6985E74E0F2332661BF2BDD78472904C7F05817FC9DEDEF156ACAC746CE12F890D85A9398A9EDFBF46E7348814A080729C83E704C4030202CF61ECDEE2795D507AC28814F53CD0660A5572CBE1AE53338B8EFDCA31AA5B95AA9E765AF4DA04C9B3162677E41C018A5E18AF2F98ACA145CCD1B8F7431076A14A7C20F6C72E8EB9751B7892E41015447630EAA84B9601CB954D89739389D52BB91A97F96087CB38B0EAB59A78468346555C71284C2FBBD275818E92673FA42AB5E0D977667A90F75926C80768775D23DFE0B337B48B0C8281FE63F18F245F88F21E11C56A5337188425A348B24DD0E9830DB6B6C89648C7A633CA9D83251D0C6F7A453950D02196A77BCDFD52B2C65C9BF7269C30CEF3475762959BE9DE944212F5FB789A6CD0A9A9E775BBDDA03A4BCFB47C177730026AE2EFA62189DB8E2D37AB9D8CFE9611180E9DCC3329E636FD942F6767FBCBFDB082FA0EBB84DF37662AAFA204ADDE6B372C77D364F08564F19B2B00C131A8CCE9A04B5B69CD3D8FE1F2CCC89EE7D228A4E0A910C8B5AE0BDE53DBE904B13A32F33E99D6C6735BD03D409902FC63C8DD843FC1FB749C0B738701DEB5AD7AC07AF5B93C57B5565866EC1DBCD429250DBD197953D53C3FEC2F965F3D2EEA47EDEA14B237FA10D256E804FE3B50CBA1C2B420B8FD9B64E52D2DB35D2A1C4E6D65176E7875EBE93E661714C8BA696DAF7CB06B7B8C4F6F5C629AAE113876F96BA0CF6798F038622E3FBCF86CF7C77FDB4EEBD42387FF2CCCB06EA0D81A18EB5E740C803A34BC8B40E3E36AB90C1FCB0372B83A13D56D6830F99C458B8946119A66047CB2DAF293890FA990F020265905FA2A2E3BB34152F0BF5B2CC8359AFA74D38ADF6525C53D90E3FD65386E279C26548B2673BAF5253579A2780883777674E1FF17BC5CBD8110ADD920E886CCA33763B04FAC0FDC63FB472C22B6D5EB6A14E5FC05016EFFE6A42726502EE07C619C695DE3FD9C5C60E70076AC3361B846FDF80164E8690C8557BDDC0860C37471F35F847F2CD962164AD46E1DF44794802F971393526FC120D88ACD6FA29745551E7AF3D7E1E7EE018B63C4B999D510251D8E9FA61882ECF73776571AEAED7A1F9E07F3046CB20ECF4D2C163F56F8A72F95B85D2CA6D35D117F6089E0A73B3DA1A32BA23104A5DD7AAB468975945C57C166FE46289F1D3B403907BA4A2CAA05D691BA9BBEBA0E2DEBE0EC49E213861929BAB69AAD01DF6C3EEA6C3F3291BE56E5289D0BAD86027801AB57F7FB5C25AC683A4C08839F3E739D6811C1320FD933D8E79607CFFE4375B33A39DB757CD450AB9E4F1BC5974E8B306D09F0FBC5B23B86CD64DFACC14AB74611AFC22A6ED097691D86E44B60014DC742D90AA59987630C544A46143D6E22828A7BD6E505CE1967AF8A8328CE9FD113791D1AF3CD31C1E884D7E8784846F390BFB2DB3124C6D45DDCD7D75B7FE7E44CC29E5B310EE23555BCFBABDA1BE64F86E60310A2DC93B1D44E19D602877EE", + "rnd": "4E7A017C15039DC20051D2960E5E1559CC27ED46877CB98116199A0F4105FE32", + "signature": "B865B00B2118DBB00B701C6645655E8ACFA84EA792B448642E1832C3707C87CF09FBE772F1D4385BFBE5E6CFBBE26C10ED6EB865C887F86939439A9BF768BF039D73E3EA83BDF18503B5D1B39179A827B0D7805F98428BD87CEA6B06960C78B4B586FB0D5EDA9FAAC0256E38823562A307966117005AA42F1B6554A04875F85C2E3FAFA652471D4E98065482FC7DF49B2C40D0E7B98238DFBE853D16BF9992BB08C19259F9B575EA7A4A80093A64A92671857A508920D60FF6FBF38341C5590105633A426D602DAC064DD7A7F11A60215C35B7B9C00E9D8463988CF472CD6ACFB7F722B8C4C62702607A674880ACB3D6C6253E71175A05B392CAB4BB14CE86A598ABC788D0FF4D82775E4EA0FC36363CD0E97B78A6AE4DA8E98CA612772D56B582F82C0709BEAE46673BDD8042865CFA95BF5338CFEA606A6EF3163846AE83B25E5F5BD31C83F136729A8EA6274F994FA9045FA8A90FF854B871CF82E2B701E8F4AC04FE9E28491B9A25FF263E2CF75499E009FD0229FBF7E5E46044344B07D72214A9ACB4FF6102ABC1262BC2E1CD2491607AE7AAECF4C35175CFA4383AA86AF1E62ED06387CC594836467F41DFCA8FA0CA71280BFB1C2560C8995536F842747045591453745F260382E3DA50793FD7CA7627185DBDCEDDF69B2D3E151C7F97288A382A92B050F791F9587D77C64D8B5D40AA199D4966BE2D524F9610F2FA02ED23176369DB939350DA601EA66770952E0F23EDA68A73756EFF610E8D6A9F49345658544282453B5E73A322A03267C969B50734F2ECD4EC9055760D928610E94E0B1628D6AF1B27AB13829F7F8EF50D9E2996FC64B06AC8946114766DAD8DFFE634F47E9D8569966C6F6968218C5B8633611BF42B4FC0E78D0C029EAB85F22F16171980CC65F28445A11A083AA02977C2E8886ED270672E512AE89C6A26FCAD1EC72B9ECFA5A5EFC70FF0BAB28F114F4DA8170FE8B63C2E11BE7A35466E979A127EC0D20323D502730ABCE640A2441CDDABA326D6783D0192DBA9E93FE507C6A73767BE56E2776576EFEFF1CA179D83343E38C6A9C2FE725DDE807D21725E730872E2AB3D901161F455BCAD23A8433A413151FD221714310E4D0B6A1E1B2CACA499EEE805A164F291D5075E6B65A79C2BCAD917B122FE1AC4FBB410211BA0A1997A31307C01F0FED3B3143D28340FACF09337C4EF047480A290AE02B2F7D87B8C29A0AEAE2E92C9C5447D66C55C1D1E25885D1037FB5FCC80154F1D23B4F27B5BAC89BE1C363CFF8EA75873AC3F6333E86C53ECA55DBED5E1F1126B1278C729C9A84C4A1B7F15119301C80BE22FE9BEBA175945B2612B66DDCEDF9A2A4D5F24F902BBA68DA75D95972E28D6CB7017CA51ED5873AB03DD2E926C15642C9D6E6427FCE80FC38B34FEB3C15513A687C35B94EB83E4AB3E1876679270F5A98F18A65F57417655FDA9994E8FCC616C6C6006104026D6CD7AA0563D510725760005F5FD39E759249029F03D9F0067103FA0452114DF2440E8C6DB65E23956EB1BEEB2C34E5B20AC316A03A95436666268C3D8228F62EB5667B3B6BB857DD0737B69051E9F26EE023671CEADFACAF9497F1ADE587A693EEFFBFCD550EC208C235691E8E366D965B62BEC16A661CD5DE28793220D66F2645505B852412FAE7B9D9829BF615F7CBD59A7BC1D034E6A25529CFB486AF201DEB7EA95BA708A3159171674345309DB8150E67EBB30A7FF80CAC9AB1392500A83E63BBF7C42EB9453C2C9ACDA02BE538234AAA7DB5A7F588FC91B90EE2477F2B61CD1062A7EF1E6E4DC54B36D0E19933E981CB763A9E107E01DA9420F82CA793592A47C4B977FF2C88498DA95C43D232F42AF99480BF0A4F8B7C4949D1AE1D4FA8E1D1A8CD0F9ED00DA595EFD2B766F0B79D4490DB928EC44B5030A74CA42811A5B5AE522C7764DDFD9FD92F006E94B35A7EF0142DA7178C2F53074D07451B15565A9E0C57EA1B94C88EAE741B1F501C4D370727DAD2765F795AD414635800EC1949D037139DE26AFCF933D9A09C127FC6B36E518C6DE9492BA70827B681C2D18A40123B6C5F61737CB9DC6AA9CE17D168EBBDDD63C0760193C974933DB474AA89AF30E162938F6DB7865DE231F86169C9E2A302FC41F1BE5F36C5583FCD91E21CB8A6757D30A4BACDB67E7A61B0C8E217E0CCBF50EA642CDE3FC74C7F9FFBDA9A1E684BBC9A8F7CD3F1BD0DB63DDDF4EA479C235652C5DCBCA7BDD4E2F33E87172C18B5FF39099408D272FD0FB0D6A23B14300DFC64C02743E523608E973613DCAAC9D1D14B3A6240EC2F2293991F6906AE36C0469F30911348EC12DDBA6C3CA19BC695FCD16E5AEF2AD7C73251570B5D049A6C3A52FA3FC9ED54E54973AE789B0BFD6F8CC2644A9F85ACE0678D89EFC12B611C3DFAE3F945034B899BE99A732889F17D208DCD7EE959D1AC761DBA4864C14B0A35E4C7BBDA096FB8AB3226926C89E7CDA929EF130C692C92659E6F4652BF2156361C77DBEEF5A0623A06704990E198A13673054324BBBAA643692F243D67C1B4F95B928ACF1686F60C14487D6DD7F8801EF20939E03A1CA7D7432DCF595F1E9EDF2B29357A1D4C7DA33512C451A7C6604382D90C33079D95738E47189D8549E43D294E73D1CA7487B50D0ED7CC6F96BEEA76CCEB96D3792004EB3E5491635A67F6FFA1F1DF6A1F2FDEE77841780AE0809D292ED7B00F42D80911909B51C9A3AE54B7A6D7D29D2000522D4F876E25C0D6A1577221885FD3074F33BDCD96CDE80404A37E1609F26CFBE24A1FBF9762A1A2332E7A2D82DF9D20F083ADB353533590BB1F9543349369E21ECF594E27807A56350D62384DEADA789BE92F012C1F8A72D8BE079F8D7BD040BC5F22336116D6F37DBFBD2C744C3AE78ECB4E05A55B3FCC31B8CA6DBE8957244908F4ED1D3466C9E00C6CCAEFC954D857C655F7471E38088CF1EB8BEED8DC4FB3E36F3B8421F37318DA235369E923DD8EAA7A2290E14BF591E1D9827303BF3576975CC3AB34999701950ABF67FF6551ACA2DA07350E09CEE07EC37266BAAA534FD7B1A924EE7361AEB35CC5A5C067F77CE523357739DEC2D280CC9BF069EA77C36F90BC67F0F6624652D302BD77F07D357C84BC30CA35BAAAFEAF3A39E9ED463CD828BBC5DEFE62A4D5B95131798D36766049E7171E6BD44156B2976E4620199EBF42E14290DBF8A02304AE70D25429ED70CAD30C6A349F9900C465B77675F0BE9A9FEFAC85F19F73509F7B56D513217BEE6C3BE4A9A33DAC690B7A76F979ED580E5029E58D645344D61711907691FAFFF9FDE9713A1DF470E8BD6D0754008597DFB7474F248F4231B5E184E2D2DC540D0904F9569C4DAFB394B127D221E9A685B682E4723B96ABFF7E25679DD7A72F95F206B2956EE04114C1634041454B521AA6A4640E4F1787C50F34DBC57347C6ABD9BEF03807DAB200F77876F93FB242082C77EFB432DC6D4E9278C66A85A58C8D89AA8505F3A3D0BC34FCE94E00D16CB20E0F51A136E28A642B2B1301D5628CDF34EA73E74047DA586D91ADF07BC2C59B1916D9BA2D072E7A5564A27561F65CD907BB75A5125751BD9D4C7198AB03D382261CFD966EDF5B8F586FF981AB7FB67ED2552D92F84DC96892C52CF5FA0EAD0B33898FCD75084CFA5E9538B4438B57DD8AD0AE5357829BF9F6B2CBB979DD364232BA8A471E3F12F61C968D206D04E870399CCB183B694613CE9E07D13AFCFE4A6427F628FFC10F1084D1DFC0F3711BED7F18046AFFA136599AEF9D013A7C73AD2C19B5AB8C308134940330D1F935D10493E4F9034C5EAF724FFF3C595F71F139AE00CCD619339E6AFD53EA9D8C48F640509452AEB12C551581C5520E92974C71001F3A456B414FE9C102FF8BFB59C6EBBE652E7ACA7CE416E00660A2F4671B88F45892668CD49DFCBCDD666C6A78EB3E472EFBAA66D7AB7E9D9B260B58277202AFAE3CBF5305030C61967A8B8FAFEB6DAB6B6BF079040D85B154839CD990F3A28D22EBAAC6DA3F85388F0868770F507D299C4CADDD88CEB0096B462A37B7931B285B06139F2BC1D31C30C7F709A6374C6CBD3930D437F8085877298E16E9A592E6CA89EC2C072FE26E8AF8961CA0D15CCB0BA10B89D772C6C28CC705B1F5D68D4C81F0F67F53E5C70504B3212E61ACEB8325F1DC5FB0777AD854595040D947A1FDD057414A59A66F493BEF2A95BCDABC782F7E74A1C906B9ABD93DD4156DAA50F5D572CBA07074B9133E61B0E259E36BFCA21CEC682334D424F2E71C2E76F16F6B7301CA1A8E3E7B171DD9F901F011D0ABD2C4A22845CBF610724C40D23DBC628B127CB7E06F83C42F9512F21C58098082F5658D7E0DAC4240CE8FA942357A6D8E2C5CC16705557C4522D94CE5B228E6C3D8E749DFD47C74211419F6A0AF61697B124C46C98F86251E9676D392B76195F41F4825187FFAA87E34687C0C9BBB5ACA0D15654C22C599E78F9A6BACBE2458AC1E5DFC38191DBDB9EE29CB9445F5D6D838D2D3E722F98FCFA5FC0F0034A42196748247035AE373427ABD692B8B452C9D1F05CACFAB92DCEF224E353F42D658DBF273FAF62E027BE12CB40A499AF47195F68697F8CD21E4AA1A43D5A626F78878EA0C0F32C60C3CEDDED7CAFE00B729DBAC6EE00000000000000000000000000000000000000070B151B1E24" + }, + { + "tcId": 32, + "deferred": false, + "sk": "4B356EFACC4DD5A922AC920BCA97F614627E70D1113DD58FF8C2F55BF24E5AA3C148CC1CB67675F8F457D4ED920DAD8FB854A9AD09E0FE616A744E23D45E45BC5F8DF4FC0381D4A9D865F759F361A009261ADCEFE7C78DEE80E9B627556EB0B2352E6CE6D987BF73992FD092ACBFE6EE351C11082BE380B493BF321A8660027C05406536203032064231151715182716178673800600414418753148363223335420506127526046225030837316057147673868431724275585752248574253132523661010113085668648184277243067835844644801472070571816587386538544161307432778468131713726265087852658757520752313386347407367074584715861575437767878784535868162650573626135024544671607758477723276642840617755017232854033881315383541785622582806374126132752386086537128012000006548208558044862038626414617684320185004256010175047834771806343054777236287272288070858351333171828314873073217615222178255157881745605453287677136880126542180682522303646784670165365614232065362622032121443746660431140775616276352778167338778572820745007018081612114217566256162176650383572678730485851846658833475786787627118474343618375106870718513203463202187076400355377420412561315150785602328512513537262476324148263708705066606868613545823024158862863312016615830177318237468303422784337108343323175086560282712130213318840052774863888054426410546016340228664104685633035758301124326328755320220158455542883065558153634250023534112375185822557662164351675037453732745222134302783706411666065328751186018100511082853188845033583064431766262308530338783051271081615651457548706023836352868635277885570062748746102156161572384840401736057383334868700226647166360541035647828414733184137122425131560805374615838266572430558476580347572071818141160203660757565400034630624662777201412780361444884243612073152714246402267040420805378541711607716742836032052184848387218032463528086003648564616302784075458684786765467345830562386685702325714181765807351626662300642620568720287748524572416877642174833767010431224238302727288834036560623776765556356785886176565807352133544230771433787752261284727254333782147456835854230275258403707034351022828370144403341847144331064562541227001302877425200614836035388324363476585318468403614688467756833452756082774147282532276125162487361558658507561248747261455227658666231867004316685537134558815533087021453310846615433671736808160628536387605020657854750656336873450615464274830778238662550823366321065332288085087043086620127047235686307808214412516122623130701485680658160852165655665863725428476222121068785268177715682485328656703800540305854823573462621421641657781256653275155256648884570067845576657106113881567345533330614133108642811580348825560033156758030853667423854563546131124131862104085640740007355035364736837670760716867574382367051118688317326131487372805133321238013367004750640065763550608518184276773048385454574853204436270376835570081651568710683312165064732472516310430817783610268652176544704123372045303324240477433636684677547505637853216267372883736123134675833200443143220272468346287300460007326137141675202506337308855876770215832823772388874047305232865258076583872617214175267774137603113420063824541363042111881288657464167D9A4CE96EC1448F468F64B84F7CF38545C7A594F3C11D228395945D4A7E60179CBCC844674B6DA539DAC64869C68A416121A5AA39CFF632A92CCB5F0C1EB05CEB4008C5AFD414A3BC378284C9C22F3590B4B6C52C5435F6928C062EE208CB43031A051FEBB9551BA103A7A7BDAC3945EBB5D5C50E0E59E38E947DF9EFB3C276DF187CC5FAEB510111D6D05B0DBE8505D8A9D5998B40E7E22A90FE76125B82A4D2A7F270A9816B0C26A597637640028F578C42B9FCA8A6844B3C7784F7A4B7A2BB398648D82DC6604D445505DCAB3122D56BA4AA7A09033F0C1EF29F72D0650F510035D10929494EEA11F5C3EC9145AFE6B211EFBC2132F48AED852649821C7951D4F3292B4352B1FC8761DB9DD4C6DF2112AA49AF973467B01C3DA8129BEADF295CB91AC6951FA1352B3919128A970A3F64155BD77055C40E7E5247FCB6A7FFE72CDF204622C6AA112AAC8F7EBA4FCF9FD622BB08B05B3F9B487FA180FAB5B5CF08D49902E444AFC1A63A5EF431A8B9F64BB7C07A820ED3CB3FB658FC3B2E1BA0DF4C9405A6B6E7068DE5C4B95ED1C724121894674D9F0F8618C862ADD2A5F948DE5AE9041EEC61E7D1F392796DA1989133B4284604CCF2050B9C300325555695CE36187402DB3F6C86F05D3CE4C9B84A3B8B76153BE20193F4C915AF00FA557246AA2EE6C4152B596C56BDE1B92C84D401FCC3B7D5D3DC6A676A89045EA7B4C8E82E46E7E01F827136731BEC6A76C241C53FE4C2FFF44DF0D9D2C2323C4C1F587A181EE48A8ECCC6232FFCEE2784CA6D4C8F2AC24AEF2182DCD499B3173EACAD1A82BBE7436DB83E53F27725E2DD17FA3826878958FFBD0C41E5B6383A53DA19A26A5FD878D81E940C8FA1D601FC906E1DBE1674AC6760C1F8319A04161890FB0B6BA5774FD0E8CE7CBF7A03790A5D242C8161E62EFA781869CD1A9DFD0169ED7B85A0DC06974C2CD581614AC3995E0DC1B6C018ECFEB7FDAED8B1CB955F673CF44EB4B815180B1E1D191D205B3BFFB50B8DF52AEC2B5CA1328289D69D2F0E904397007851B75600B88D41DF116874E9205AC05BFEA7366953CAFD8861AA1FB882583C65664F296AC66C6A905A0F37010F48E9B499068295792AA79D4E1C3B3744BE71434C6C2428085392D63F184909324628FED618EFF1152F1CA7410567DD85269C9AC089330C3CE1F6ADCB04EAB6C70B3E347A8A8B8D9944354A97C2AEFF52857B9D32BFF6823476FE1A19C92A5E943355270570803AE28D838D086D178305AC620BECED241F0D0301BB11466F02E39D20B3DBA7838F1CFCC11E597A2895BAB4DB9442E0B22D49F0C26496D54C9A2072160B239EC0CF4AE8092BA4DD9A287857F5C1F5613D53F1058E1EC47A899AFEECAE9BDF07E3ED87D75A51B3573B952953489419BC885A678E10347E38865F2F80B9CFCC37B5C594D1FCEEDAAB09F2C111227BCE5201EB71AF5006A48D6C22E1A6DA3578EF697FD523896E67F291CBDFFBA3FED3B8CF85D60621D279B1E7D7D6BBE5A019B10BCF6715689985F4E87DA68F70412280A2886402F0C46E9ED1A790B9DE5C305E9B7220494C71BD046DF8812BCD87CF6F9062AA95631ED01CC2B2E86E0609B5F5741BFAAE62E16D7102D32C4D3B5CB74E915AFF992E81AFCC8042BC61B4C3DE2CF5E7B408660EA5A2135874AA7A9DB451AFD0B9A9B84E87062BFAE6A018C49543F170BF56A1E5A152E76C348F1E77C2D34C49A98A14324433859E0FCF6D64C115BF5A598C8A5DE444785CC40776AC1579CFC66E604637C6B33EF44D50C3C36DE75903352F60C4CC14732858E7980516987C8447FA634A31EA9B1629C3B161A0E110007E716BC57DCCE43524AF8E68164F153FFC7A4678588FA0EB80E53C8A552ABA108A7AD6A8DC68F551283CF95C7D8264812E8F91C9B058FC6DAA4EAB93B8D36ABB5B7588F30B2234A273AC2E04348FC6C40057A77B02F8AED5E3514746B26603C92BFD8FC5B7B224C8698D6DBD5E2BC7CC9913A7C6EC7407CE445A1441769E0103FE231CAFDFC24CD405D7DD150C07AFDC8F341C543071100457363143C1DAD7AAED5BFAFBC5382C0B724720F024B2361A75D1BC9BB390F68E9FA51DB9B3262F72A7B2504E4E97BC44775CF558BA2EACFEA9ED471D605F1FB74112D029A2F566A38826589193FA5EAFBF0A324184A8B10B3E67717C1035967D235184E95F9A9B9F54F3B0E9AC649318D8B640CAFF68EE0C1A63D741B2ED218BEB9DCF27C093FD1BC9AE842AFF1E22B35D0A84AEE3547B7AF1C283A265095C724FFF4205DDBD002EEEB8AD8BD84AB386CE6EF6FD63B1023670C251D686C0AA580BD763F6327025D4EC5530D77779358E116F77008FA0B2FD7602F4C0A2EDFFE4D11446B5FDE23386D77DEF764B26910BA4EAA2CE7B14894EFDE2A8FC3FDF7F61BC0EE1D6DB0A487D2041A49A25088BD7714BA64DD391A0B40EB348D5AD698842D8B357465C2B8E340A58D7E77C8979977D31B9F202E8EDE1A7940363CD49FADC9F320C6DE154AAE1B4C89A4A75E3E83EFD1DE458486F485D2E4E636330D5B3D845C8C1356CA6F4A3933BC007A6A8DA66601AFD67A408B11C80FEC1C7B9ECC4D269CBED39926152B6175198452AFE94F041C79BBFFFF1EE3A57C6BBA2B7892351F64A0D8ADE062594721C48126982AD36F992F993689959930F6222E661A9E4F4754F6046DF5DBC243C20571FD3B39EEB750CBAE08E26F9C35400FD945DFD00D8B8195D2D5FF65067A3E497B99888C1B3F5FED24B911B65378BFFABF5F215E00A5AE612E92E0F9FCDC8E0CF8E35E92D0CD7BFC1875F023E3BFDAA0A89DD0EA278ED9789FEB52A7EFE4241950A9CF740C2B9D0B8A046535B11D6C560D50DAC6F2FDEFF20F3B7075EF8EDD6F98E66FB225BC6EA792D2431ED63358A36D31BCF9799EA404D7DC1FFB45B01FCE1B8DCF09D2B9602FB62497581BBCD770DF7EDCAEEA31859DD94A1514DE00019423F6BB8B817195A4F2F8BCEEE02E414324FA419BF8AAF53CA03053F605746177BFA7BE7A7F2A4F61AA312A617B109F184DBDFBFF42CFC278E39974CC16D881EF507B2941FEACE11FCE5903BAD36E70B3F9AA91996251291F9CBA4477D93D1B2932B755B7A64BF080D4E50575713DC40C3026A9242DC3C7826551E126171BD7554B2BFB03715ACEECE88243BB476BF8D486ACA0F8F3C385D90B22E09F962FE4115E5A087AB17DE80F8016C86C7DFE7CFF349C12737622735A0CEB001C9A3714F95400FF64DE0B37F7CC0B34A511CAD367411034C75940625813B30654BBE491C5367F1D24DB2F469034FEE26FA3007C0FD2BBD81398885A199D741A47EC37B295C975B40180E2F5CA98D5918512A5B466ABDAC5DF30A3423F08B679AB7BB8378A20FD771F1DADC2ED644FF904CF7DF0BA013F44E928DCCD446B7D04CA9AF3830A842965A6B901682F531F003B06FF3FE017BC32FF6421066A7437818F51C1CF74D0DAC72ECC54812C0D08BAA9DFB0D61547910D2BDF58276E50394B3FDCA9D2FCDDC84BEBDA", + "message": "552444A7A40EFA95CF1A2DFF0256EAF7E47F0A5BDCAC6CC95E2B0D1830B0D5C01D818278882947B025613A53901A3B3D986E4B95B9F2B6D89DCCD0EBBF1FF7096EBE1A3D9383652F14C34E928409962E17CD3827B9437E37BF15FCED595C7474F3BE5D2649520AD19504D8382975ED99BA29473493EAC7CBE463909D54FB34EDFB770771A350585E01CC12800E639B4FB250E98E4970EBFB300076A2B10B9DA885E79BC4C4A0EAA3B791A47FE6F7CC5B0641A8F1A4BAD5963CCC118DF410F0A54BF878DBBEA1915B428D481F0628C7418E6BB2A2B0E9A1FEC35A6556FB2C3100B1ABA8AD395BC6B8E459DB45B998F1A2220DBA2511A150F4A6B236855A75B41DD202B8F7CBE94F4990C44301DD47B1FADFC0CBB04A030269A3739788A4577D285BB88C6A92D062EEBD0529140AF3673D3BDBDCD79D10D65F6C4AC82DD70C4EB9D84EF54484ECD5BB9769C021626FB46BA06E95F310557750FD1057688CFA587E268B83BE5F08ACD1CEEC2C1460D470C3B354272F8B75455B0D544D30BEA4A8C47E20F5D23267C0C89E206955B184A44A41150C35BED69F1C5EB5261FD04AF23742DD99051FB1D8BF8AE6062A92A41133741E7BB0DCEBA2182615840B264AAFA54BFBF9C2B81968BCC5E82061EFC531E3C14C6A7FF03D333CA0521E876E9EA7AA47F6EFC487D280DF9D6BED0F27426B459CF2A9CEF5F69B3AC0819539F80627B2F848A35B0ACED56B1A5F768C77F4BD358C178E95509FF2EB51FA935C3D9B3E14F76503E578F85C2B88FA6DE7E1ED3453DED3D5371B1F18FB2D1C5367FA5D6588475879AC479B08614EA9B5699B1F07A5618DBAA324866C71124B808159ABD53D630907E99296E19876F9BD87902A47AE9DAD12CF9BC9924E410C4329347F5A0C314593E2CDA552745D566DB6D4AE7D5574B501B4B70683F7ECD58FE50A3FEFE4AF92360D7FBC639F61CAD61FC17E23D1F14D6824640A9E6753139F3145B43E34762E35F87F6EA2DDD965BF566ED70B8B06D49949736512E58AB57C22993D04212145F6CC0A2AA58B96DB8976F0291DD036386E49D660796CFA3F2325FA39B963DBAF808CA741C4751E6FA9EDD20C25AEDB775B52A0E0D1A1D19E0DCE9FC4FB3FC95C8315D7F947928B0F2AA7014A0B070EC3EAF57982BF5FC45885EFD34F844916AB38DE143371C56CD5D4604096FA568EE01E240D12EB013A974848BFB4675F706A3DFCA19AE82CE7F8076483FAF70DA144A33AAFF4B454A7D978FC6058BE7339575A37A39B9B321BCD19C26692DAB294A8A17D28A0B7CAA1E1973DCC03F901BA6DF65EAC8BB643C2CBDB66BF56353E164400595A78E12FB607C25ADE5DFEF633D9189BD1F1F79502FCF509D06DD1643B759ACAFA2DDAD209C750A321B93FB7D5ABD491BB70B4B10FFB87344AEAF706ABE4131D15D3A1086AD30C85A30690893040F4C7747C494E93AF9E9C3644A5154CF3AAB1436FF7CA73490E04BF4761AD97BD79F00044FA5595568D0C9E145178D7CBCD05B42747AA30F50B6ED2DEA520BC3CB188BD7CE119F85ED98A1A27BF7EB7E0E264681EEA4845366CE25EF2B46FE0A7345D930959B93035239E708CE09CD76A61864D86C8F19A45911636124F1CFD4917FAC496E8186730EB300F848DD64DA3F4AD0FB1B9F8A2F9F47C21C1EA1B653323FE632E40CB177038067E6AEB8EC1B2D8212EB44F20487A2904620089A037699BFB124F8925C422625ED20172CCFE567DAA612285002E354EED5404EE79CF0B08F136E9E43F5D3943B3B57E5696677D09507A58AB3F5AD1E5F78FE75F08D617DC2897DA4A08A7F7030D61DFD2132CDDD4B40DC491AC349FCB80F28C376147A593889183733C3216150C04E0DF2652D783C648A7AD699F6EAC0B177C1FBC0307ED410525EBB0A31D5BBA2D311AE0ABE3FD11483A6835E699AD7C3317598DD1423D1EC08A094FE9CB01B1DC94024DEBDF22710AF0FE4126AECB0F74D47BA4CE384F2F7E05C0CE540702477C8FE3B2A82250AFBC28C62072BC2480585D56EB127D41C047AA6F3C8FDF9AD01170FE4A2F246DCBBF8E220FF996DAEE414FADEED713B87BDA12D716ED103EDF38BFB64CAB65D0064C2EFECAF91BD31EC05C4CCDBED28FC7BDA9B0002BB9F9BE591C2BCCB49B4B8D1D6CC167DB75248A1302D0E7CE98FB638C6BE7F6F3EE720D95DA401EA6E62190441B66BA361C33A59FA4EE9DC78F989A3AD1B3D52C8FA98426F7830E1BC42F01A09777673235353F4014859C72990519E85CE2D5E8C128BB8298F06B5B73B925416137CDA981F61CA79B97544B2B1C1663DE82D5E97063D76420E82952DCDAD869D0C88FB069F86B31CC464C998DDC6AC14248354C23F609F1E736A1EC27E9EDE730E22795DE59AC14CEF8DF7A54BF9BC2D4503CCAC2094BF85D6E09150C3929ACC0A058289F3F127F12F7556EEE675FF14CAE255195AE88890BC6D4F1D8BF0B2367CEE1B4B0E771FAA2D2794A9257BF325FE2D5185D907BA25408101039B4518C41E7C6AE9ABED321C783E21151DD921BD70EA5294B4D0B2D7C7B728308387D84E3CA2725729640050C206668BEF71EC78C1948B6393456690C3944DBC3DF412DEBA0086FA51F3420C4DF5EA1B71866C15636634A656924EC39CC44A7B705E46AC11D8124B974FEF063AE1F5D20903651E0FCE0A84A034B6DC4C2E4A30F98CFE43C7F31ED6947BD37DEAD4DB1D6E9AE1E70534086E921E9F30BEB6B77ACDC9DB160F647CEAEA6A42182CAC934F7575830399080AD492FDA834DDF940E684001A7E245082F19E7AEF00089B6C4A537D39FF9D3B8AD847FF6682561B55C96A5AA398E6E6BCAF75104F13E042D3F9800E4033C2AB3127990154D0FFF811ED8ECF52DC94EC4893B10CAACE6313D9ACD0668A67F8E498BD2738753F8A7DBC1FEEA237B9FFA4501A7649286B6868601E30DF4EBC18009FB6894280E4F6BEECD9681336D3321A8C2F12926888AB220FB82D7BEE67471423158569D47BD362BCEEC1C39D78109D8A2F4695C04B1615205DCE6457A39DAE9CF58B4760BC39C2C4E2ED8E9DCB8FCE1C851F8C05E419BE6CF6260E4E98459A7D5F8F1D463D12A9AB4C89E9F9830B466C0CFCAD3E0B0E2C12C1748365E51F4ECCD711A901EBDB19225D9704103C8FE1798BE35DE712618EF89109114644F742509A16797484C24F5AD3BFAF9A06BD1BE2CAC86D276FD8E350862DC42B35FCE1FD211ACD4862BC41E90ABDBFF5B205266524574326F4736B676EEC20C6AB5A1893B551AF2D12403A0DFF519ADB30423CA6E47F855E80975ED037EF88ACBA414AA598F047EEBC0AD4B9A5D3CE5343A346E788DB07F60FA183FD405B37F6F9EFD1CDA4EE7E8739C581FC6585001494AF2B6FE6828C9C0EEF94177771A43E074A3EA5E862F27F132D6A157716E593C90B7EF4993F412885CA20A75D91A493DAF9034B18C9100393B49F27AB12663F96E1A92C158F370A95576F08769633B2551537DD467C8562278483D039E67FF4D2973D8143F9B902D649C79E2B37981784D90E2B1738D6D472ED15DE921D546CE59A400EBDB88B53404F061D40F84F3D5315ED8E43659F12A5FB49DF5D0951EC6708967A74FB3D72674190A64B8CCFCCBC72D7F3F9BB758C14C509EB3AF2A4E0F5519A00B50BB03B19E749B8F1A3D7BFE674C1F1EA574DF1195B8635364759B10A925A233CA6318E74C24B47BC9EE79AFA303284A3AF734F84D6B6F69A24FD552F0647E93ED1E0190975A16DA6C2D7D052105A23AC78B7427B88F52CCF4AF4262FE21A846F39AB4463EF0D6AF1FED879F376318E4B2D47398AA712EA1653F816D0A35C7F4CCB4693AE9550F3B241F99E731B70B751C4C98C61575FA5DD59E9C4D2BFACFB8D5B95743D935314B9B890EA5CF0440018DAD67D9EE9DAE24F742701AA1AAC432C568EC71B9992284268764C399F29F45B93DF7F02C9421C12B10DCFBBA57D3FF4DA7986E49F93F859D946E105FD934D43E2A7274AA11D95DD7356BF81EBF189597C39DCEC7DD6F2BB2A20206F2F8F79609FABBD2EC6AC2EA755F4CB925F1279F9A610956703ECEF9FC5EDF6DFB4FBD24EE91EA455FB2F6A0190D0C96D76C8A910FFD55B01DE528F4401B85E20BDCF781F62425B083369DF011263C98320F158241EA49F2D1B34814426E7CFDA307C755A53EA5ECEFCC7C58F0276366FA6B62BC1928E9D2319CC09B11147D008F8E17758C360394CB2EAB2BBD7B8F914E5A29BF6F0B8CBA7C538BA9D3701B9AF73AD380B8B2C0232AD1C8A5E36626BD46930B2CAF753B630FCF284C5A2E6593D38E91E338D6255A86D834AA6F9C8AA4A0E6D73904EE29891E0C56DD0D46FC5F7B37416D0BC6A31DCC0F1BD8FE597066AD3593568DE1CB15FC9DAADCF3F16AA1B13304DF0238DA343C651ACF042526C9E84ACF78E8AD927F1744A5E5FAE083E7DF1FFE252358B17DAE7B042061E259A282A5BC76D849C0B0592738B4B588AF41857BB15DC8A96FA5C1A8C2A85DECA64FF85A6EAA210863907CC7CF92FE73257024620C083152FDF050DE7F3BDA3D7728B93627DAF8D4A39283E2B0C59ABF8441E49CE6D5155F862035667FC59BE7732C8D695183B5090D0B372167B7723257D0A41B234D6A04920BBADCE305DFDBB4EB9A22F8F18F295C07EA50D9A76B40FC196C5FA14FD30D4F855BE1AC1110F75B11C9D3F86F4CC42F466BF65BB98AEDED66EEF4FD3BEC7DBF929144B6BF6FC8FD460A639558A7EB0D6A9A8ECD92A0E1CA11A11CDA0D3E66745E2B9F5A592ECAD43888FC9A54FF8E82C8023BA161DCEA31EC9EE48943008542A5B895E629B30FA53CEFA97CD1CD68F62B5FDA93800B2CF311C80E69D407C3E204CE67BDF6B9E2A395BCAD8ED0FBFAFA07B99107E38A100D758B9F0C57A561EA7D7978CCC770AFBC67BE1D9118A27EB1D5650E36F1415C7C9A2F2DA5754A61B24DC6304EADCF5F16EF82483F07AB3CA3301556B858AFB0ADC8259B27869E3EB0FE243C5545AFC72B1E66E5A2EF25A23656B444B4FA5FD7891B75FE74FB7D7CD4253865A9E1925774CA51182F38CC23C79A97A4037364E863CE1EE89D23917C36951E6E12EC3DCDFBB7B718E3C2A5A80312220578B312F2934A52E7AF8D0F2BE234DBD4E1CF36E9A00F581566F833B5B5CD75AC4F73B1116AFF3E49D6DDDD53CD1D1016785B7679BF717929C57DF2D29328C58CE1DC49F34A532F5749", + "rnd": "85B786FE1E9AE0BA921D7E2C8E9045C8A6CA848DE6C6BC102F803D9BC0F8D534", + "signature": "9F1672E5E5E66EC6ADA46E71A9BC54AA7034BBF390BABA58DA6EF4422B22E73BED2C9C23B7E0F1CB9E54101557657901C0CBFAB5C4C73EF99628F9935630D2C85FD7550B3A622CD8314F865E11F402243DED0D2139CCF7FE451F1187F20E507325D7D93B83983EF5DB632548C895F44EF52726CA94A5E4E9B75E6443CFEF71D8497C04B59B8BBD58E621D42A565C0E2A09A26A886084BF56E61806EF228C4F079ED4CEEF9140E402AEFB9479ABDF7D88627CEAB9680BE9FDABA05E3186EE77E475C7366C89D3005A7D648314C773562F6C325185F1C5016A8C0B7D7B6E1F128328E0C70CE4EBE1123733E49F53ABAADA49B49935E567725C3A72DA5BA7A4DFB9F9C78B7723517DD56B012AD2F8115D6C404BDD14BCC9DD47018B5FBAC37AE86AE570643378DE4181066A5717337EB6D60B274A18E3285DD9E8D205B810042010D71749D737C8E74C43A2E64B0C0448FC290B2BCF8E19829E3DC045FB7486204792FE01B62DC839D59C9632DB89DB22B5F2B74F74170C2AB3240C96EE941F2635E93666DCCDCD7827D076F31F5ABA8DC0E07F9F1D02A348B42A15060A85550E4408C5D7C700D300D6747070753166CDD8D954A96BE7265326C20C34B3FA36518394BAD7BEB1D55213CAFD1A6133CF72AEFCD059CECFC36751EFE5CDC2F72A1EA96D90DF6E70F5E8D041C49977585B287A30673F33F44A635B8C4219C1539646B3781F6D555F578F37056C28E46647942B3C2EF7E7631AFC72EAACB40E46F574A7EF4179DF325C95A67034BDCE30A2C98CFCBBEE4C3AA5C021A0D08C3B05066BE382828C96ED893959E3380228AF2CF40A4971CBAC6E8C4A37BE304A6B18F37D28CE795143EDBBE5B047AFADA65A02F026261BC3B0C765E208B5EF0F57F83830D70D12F1B5F8BC94AB6608FC3EAA7917828270CA76E4FE43189F594990A186D03A929B2CF8DEF4E3CB5D567B3ED72037BB64B99DFE7062D6AB6FE0728304621D16C3DE1E914D405E8A29B76303D47948A1AD68A750CF62A41253764D0E19A1C8442B2B5F7EC5E64400C73884355F782D7222A4C939D32CAA4914CCBE9005A4B2322BE091F554998076379BD4135EC6F09FC22979AED087EA6D86C095EC5672351496D3BD6220C66F58D4BADB28FC087A5466DE7470F758B382DC447B4F5B922E8B0A7758CB8A40AF89C3BE4A7143F0CADE071386FD7249863DB3BDDA416BCB9AB8A9CC2B65ACD18B8D777C98E9A74698F42E8E9F367608E183BC4783F0C0AFF65B5EAEB1482EC2E70AA787A0C75897F931B1BB95FFB6713928AE1BAA99A0BF86EB391BF1B0883EDD309AA59664C895605979A8BA477F602F389250FBD527237B41048961FBA25422CC63618E392BD8CF8A1431C84C87B641D4BBA32C0817E30BCEE665C047B766A5FB4DE382F2AB7AE35E8660A81A5680D9BFF4AC410F42E8036B611CAD4DBCA7BDA54668D14F7BC44AF5027DCB057088C18C1A6F01E69157332B069FF4954BA2B122AD34ED90C8131B7A39672F2301A7CEE4C1723A9D49431E866D14A2C2B0A9EFBFA55A2A90430AB5B6D843392030214F23F87A69750EBF1FAF1A4D71EFC0E08E351AAEA9596980BE023D81335C76549100905A42415C11A6370A10C140451CD1CC131CCDF82B579BD29EB90801462329E95398A714DD8A21C06B5F05C2D1297B99DDDA113538C7A4BB7AC605CB94D6AC1036EE7D0C4261A4C13C81CC846664CCCDC013F594A1366F3955DF422B9E7E765214E438BF416AF13596521A4FFF4A018AB668E62BDFB3A5D76AC628065426849C45B30EAFBD0E37E393B7AB0C72F7C8652B60BE494EDE04D76559853D13A0E1B1FE0113BAE4711906F4145640CD68559BCD02D9E59F9AA51F105CA33D523F3CE83C2DFFF356AEF1CDA87D31B02924C874EE5621AC026D5BBF2474904111E772088A669332E8A5B76DC56A29E94AAA31E89AC38FE39B72EE3AD5D58DD088D4894C5D99C0CBDDF52B5BF783C509F1C7FB62E64D085E90A284F905D6302D60CFC454CBD28062A91A2B7E21A34C9638BEBA4575DD14F5AE084DCCB220A67496238D0C96D8C2BB1D4F9C99F4C859D35D5773CC72944E661AF31126F03270A99A5EB50E4B7B3AB75ABE629B250D0D09D02F4DAD8C58C51B84ED5D0A8401E12B1141F93E9FAD606194F21865DB3FA109692294581EBB9C3DDA1C800A6B75FAE6C0CA584ED5058E1FD905C3BD84CAE476D6B35BB55559A7CF057A58DB96D3CEDA7D9D537B9296C3AF25D41B1162653B922463A5E6F68B70050DDD8338143CAC4D2EE4068D12211B46FCEBC8EA0FDDA3F1CA12504522699FBF5868158B4E54D12A002866FB631DA6CEA0ACAF44DA55B0F2066A50AC81E676974E5B2A7A1E36A9637F1B20B7EDE190D0D250C5904DBA5A44FAC3313BF040A4988E02EE466A3564DA06129B93C4ABA9E34D322BC820DF2FD8A831A01D7AF52EE34F96A846692A9B47029A7EF4FE0585940B5B57BF3D33456B0D9A09EB762968951A53BF7E709C34FCA1791FF9A4D48A189CE48E2DFC4077478DFF02F575DA342CCBBB5A2A5D2E34515A263329683B49D2F19B3DDE67505E57C37397D7A19060BE71C41FBF9CB8FC3055C0329BD1E52DDB52B413684412B73648B7DD9D9AEFFB8C96896754050F22DA2400EAB963310B16D905EC10D6E4ECBC847A1DE3BCB478DE4537D41B9D018282ABA9DBFDD9508F16E55AFB3C24D530B61B6A364CF15EDA2328931EEE988D1FDF47AE1C4DDBAA9BF55DEDE2CBCCC118D95D05CF6B330B113A85B9492311359AB9F39E9E3E0D04CC2409978243B3A2641B13668B918B238CD42B1283468931BDC315601D283383AAFF6C9D271456C1950991959027B9E2DA8319714FC32445489268264D3362F4941079B5BC76CDE0412441468C88F7D83CFDA1EFC1856889FE0FE3EFA82CB4D6ED0632592095E3A18FD3F251459DA833E98BFBD9C2E2C813537B3BD5AF53B90C8A00D8029FEAAAC825C2C56163D57302B1A9F04DF73F5D7A85B7E4F8ED80A397B57DACFB0DFCECB1CA9E43132F1C96A14DFBF520B5D39DF85F8B9865D04C22BB6242E42C6D52C09ABF3DB1F114FC21CC444C9A532D61AB1B97C3D629C82920DC306F3FB8966C0F9305988F6D8BFDBD30F7737E4FD18C854B7F15CBB2EAF63F276290CE2E55FBE8F16919AB7842DC724F687BB779A2720EED9813BAFC7B237197F848ADCB3ECDFB951B856A97FFCE6AE8BA17D9B01920C30BF859EA4D465FB43D7EB43CD1C98106B75745E99F5D4F8A43E7AAB8AE4B6BB995DEB4B608BA92746ADF0C731D51AF1BC82FB06F60993792C109A13029E6E64D2C5587D1603101E0B71575E97A753CC265918376EB6FB9F5872F970AD8D7D020DF5542275456185DA9E744931E856D909F8BF056B27EFA16C65C63E48578C5C4A572B7EB2AB716814D81D149AC510DEFB7ECA501AAECEF031192BA47607E6A6D05D5B14CF5D8ED2A447780DA119E04A0F4749A5050D8EB79153BB83EA7726BD56FCE4EB4861BEBA0752D84C6243ABB85443059685A191BA7953ACB492BA4F9881BAB0F074A2677A7A8F9602AFF6F669F9CBB5546EB503A90AAF6FF29673B459B85473BF15BB18E27AA12615D54819DC2C5A431D59D428D1FC5083D8D1BF5BF3948ED5AED666E5F9167761988B2281FC2DB479A18F10DA9E6EBE10D39C911D5698D406B40EBA33CE2A747ACBBB40C20A33F717328B769916853541C7A7EBE77D1F959155B421D81BAF624FC845B355DA3AC2A24FBE4442E9804D1B2E2CFBA405DDE9FE23FAA3C3676C7FF8310A26A157A0BA94A95B9B010B591D6D20881695B055F72E923DD4D0619A5576B776D8B08FA784E6DA6E7F05278EF9AEAE6F21E2F549FEDBA9AF660F5E4E18400ED68F44F8EA99E2B27ED0BD477DEE84C610B44ED9391CA0DEAF57EFAC1CE73CF6A902C52FE193EF10DEB85A83F85E9383626C870EA0DD02E6FBC8CBEB374B35B89BDFE5BD56EF38070F0DC3AC9E1EDEAFCCCE86B9A93434A40D416DD0770549C879A6B21E9C05EEB0959E4AA99B673DFCEA9C4CD7C1FD896119DD4E7111301C758D2DD0808148E9AB6F052820E4F979B17FA7088E4B1FE0609D31899C149DFAA6F8328F38FED27701F0B756545EE90CD01AD11D3CBF4F85003A238335719235A5EAAA07663A209AEA2940C5F97635D204D1BA25FC622F985749923B700C400F4ED0759C590E77098591495E67E3AD5651E75339B4E62E8939DE526ABF8763847D6A99684AC2768835168DC314A9D0011C9564AC68BD5D6BAA7A229744473924031FA2C0062B63CCC023A4071553C76FBA2E95765F938EA499DCF04428EFD8D663F17703BDED8F11F074B5580BAB6D1A2B7C2C95C5711F24E6C55C1ACD2941B8AEB1952E19A13E709E314A2F91887E86A0236EAA958F100663A380CE6CBE51FFB2072F43EFF740541E406D043202D599ED84AE02F6A633DFA64EAA07218EAC7341B9F78B798477490E7D48FDBB1A4C7EA726B83158AC38520CDF3C375D44A983BBE84F08DA704DEF77A13E12E8F66354C7059FB064A63F556A94C145D161428453CBCA1FBF7BF7BCCEFD38A62842654C51AE2E6C0455C699AED1A75A4A7C00637515E90A4F1820E144DA76D859DA0BD00000000000000000000000000000000000000000000000000000000050A1112161B" + }, + { + "tcId": 33, + "deferred": false, + "sk": "7EE364807699DCC1B171EF7697AFCED47FA74C3CC62D4B31508EAB28B90107793070FFD9F6E4E291BB243BE3661BC9F10334479CF94774A0B2D675A73F5A4C5C075C9F7C5A1F3AD42C153C56FA4A0096A890599864ECF44FC624C5575190918DB25642ED0EF9365EA49A5029632118C25BC353706E19F434A8583BD9ACBD0178626601147662345815030478008075046508171453260236220048153835224142604887325381776704830327507654380330128270618302451660516244765741333130207313070867858507807615254770386856715356623153328254581510857670100338338686141455250877738467188887704720311330203443015486446845343178655717730001428303223328155126584302773635010182256823046347814368858354730260230366711132523132716425153604515350680254864267436045112488377013036752038266554881058615402702657132780142432558642687434253820320032625645616776664083467506808211330653258107106213685334576103762716781245634321500128817253316451130051671528140362504105881488821713800164607146755065760688160543718621280743848732865852361852678157240211185687334353142717336354856016556473555578538417875751725466400024472312366688150488313121146007075716200007543526658340838881844006842700380382834232164542533472368224663537845745583636860433041070136228234481082077622376620678303368354216702542236670423402146372033505166601564428731623280705832823840136715073314816446241024176301575660048145120002242205718584228161013056607171377283255048262750850470087823837566285237075677233111022786313266784264321756335042421018820142531537353876518327210142277368465045855620866345617148743510018587426055818361571771053546622747133880437506658800400650817630436845112035816557630731546347117666513114417878770806254317511355201412145708548274724223150662816375874674851136332818333128174125154886078744742041625344432056425844222146208617200344287485004528111731188210487761766531482710535114800375747226862172487445171767667343186738688770045607534423146814375745432858668588748588332230370718052424475505322657107224600116465087540243388272487388701300685464725060407631800010613288320137323600144156250620850600477468054146361047633736613384462871441060082280463885576440432605015573754765012538621135881787407501877658803558125662486844400022067141233122102411543275811304821687313488860712450456454001801541234272253552652434765676387646006677870715616345358670165803013031582207274773730634201754666740831773660418654874702240274475845567372635401346060747328622168870375260246247320060702436233653027566060646450257842042375205074664540708417681110785088274158666332216417622424863545485016433075815726043564810555761228231522762511451204451556864471566704511735785231715383542260410661531411210057514300825237321725212750487324046447443840450620273151357084571004013511177711381564442344141535447627261186303185871874205786881032782676020684387284222185037741614587614416625522070185831673532116061357246375475106587508107430740086076578283038120584722042318120441123375152344277185544807736712803347603368270841110223567487831516463256057743365018152751800783617504346275728047461447333167282520736423316276657786546632410750632726720403830616534533830701282386323333546C9DF2CD332FA871D86F93144FEA2AE57FA2990BCAC09486D2B22D7DF3E9A7325982FB8029BA0D7A3D4FA0ED9519FE9290CDC25F027B18C0A3FE9634F387A474E1963B8E03405892AC99BD13751C23717091F8CA86BA14A48E9C0DC4FC03EC919A30B42D1A713A3A36AF3DD4D1129A8DE229512366769B6207D0AF0F8A4FEC06AD053BBA0427A70172A0FDF762AC47FDFCA39F1E1487EB78B1E32A088D80E67AB460A2EF90B32F3644A040F44B7A015772954280DA3330079F6FC3D7AD06EB3EA99BD7D9ED0449F319532C81BD279706884A02CDAACBAFD9F795EFB6D4BDCAF2254CAAFC1982AA2006C4C9184BE762B8EEF1028EFAF9611BEEA88D42815718FD2518D0169B27E272F83DB8867AFC94CD48FD0F23ACF3A33C0007B434806DD4D17E395B6C8210680279A6CF25837CA1E02C18DC616F36965D7D35787003B86D69FC2F40403AA8D708E6D6B4F2D793DBDABBCDD6B1936ACDAB8B7E55C6A5276BC52FE931778CBD25EBA6DF7C3768F470530B360991FE2EBF08DD240AA47282648274B1FE2887A57036A45584E65A48E95D6A8DC80710EA79510208D2F5350EBD14093EDEAE1ECA343E8371274986287ABB067844E42F27019E3C5DED895B3CCDE36E1742CB82B5EE2AA67762E64F0023CE9A5F25A10D9678FCF53F053E2BE39839AEF21D4424BA244883EA47C27C95F849F29B6831B0313EBFC44935451E55060FFAFA92487EC348AEA470E07879C7C429919268AD7A75F4F3704CEFD875A77304C488833FA75AE023D5E0FCDF98FD85693F7D75CB0B4DEC7628343D58F24310832B6314F54544804312E2E72C0DFB46A670DDBDDE9AC09FC1B09EE131ED6D961711F87D919DCA30732F3CEE0595B4B13B3C8D22B195F00E2C989D27912451B42D3D5C3CB69F4C41115D00EDFF07295DB204B7630AC71E637A7AEDFF8D143C70B1A06C4B8EE578656FF954586883A557D418CA2F6E561907AA5D47A590CCB6C2DC9D3F928F341646F64DBE0139E1E2E10734A0DF4807955E8E270D9D6352519778AC9C3CC53245234853AC8DD461AC8F5A22728B3CD59789AEC8FB62076A8B637CCC46FED8C711472A1D1D45F4F4527C29267FDD816532BE1A9F9E8CB5B1FCD5B50B7E8A5F76B1A14EDE1DAAA046B67C4D8DD9A9AA7906B4B28A36E9CBF7E788A6B2056BE60779BDDE51A5E7915A50D8A3390DDE787AB78EA9A1DCE3A52339641AC0AF8737B3B338B14D253DC27AF803AC6D80DC314E4EBEBB767111479A6B882883A4EC2E2EAF286836712B2E449C9EB0E0B2798A75378C3AF26538803BDF2815B4CD6FE1E6F0D8D2DA72E3DFB92C17B8545CC37B1CF59325A9CD4BDEAE2854EC073693F4B500F2076333A1B900BCDED21853FA4D1FBC054BE37442ABF9AEDFE5165A6C01F7FBA84A8590BB5E4940890318CCBCEF319037E3C3EB0A422E4C50F179C6EB52338E0AFAA4D417D2885CA7AECA724C226374AC4A2A003913CD8A677BDBB45310D1311BF815293D8CF9A39900E8D1F6B151602DD709D385FF7D15FDFDBC1BC7C2E1DFCE0B5F9A447749D5EEFEF9FCA66DCC8E06E667251B55AAD86086F0DADEE1A0BD5504A0E107E7E0CE722AB6D69D7D6030DFCB6E95B28FC69EA5DADD5FB222F2CF4A38ABBD89EA88CC895AD9658D2062C32903B8ADA50C119637A0FE2FDCC3A98B10D5338134663AF375911E19C4209A0FB6AF7BFA380D148136208C2C39E0E3BFBAFAA0922165C4317AE9B7499BB8B775DDE37B9D2F67EA1DCDDBCFA4941D19738EF8E4DA1E67E6DE5EE0B5B191FB2583FE408825F8F024F696743F5F46CF8AA6A48551C92F75B6CFAB147C95F99B1EA3555F29F094F477B0BE91AEFB6A3987CC8B16118729C7ED1EC0AD39C186A9BEBEF82D001AD9AA335798687939B17034109D133D71F13FC513AEA33F732C510B474B3B5948A0AE4D8DD9D376EC0469CFEDDC13C663E089F8AAD8B0CCF5D9549F31339824C62753AB409AE438D54E807E37F7A74FD22C230CB844DF307BE133ED6530C470EF5207FACFF513A952BE80BA568FDF36C48F9E4D39A945DC48836A631D2F61ADB4957991AFC25684E5257F446901B915FA4E55BA8BB747C0198AC5DAFE8871408AAA5ECD140E7E58AD300596167F4DCAB543AC3119713A189CB8A4CDAAFF4E9DF83F78800A8D91BCBD76A5F387F17FC479ECB08964479AB14C0AB549977FB3F5858F6E9DE8B56A57151652A57B58D11A0317A6C3DA517F5A7F8E71CD950DC883BBFD517AFCFA75559A468E3BEBFF51EC1E59B1934AFE8C4F580019DC4373FD99D550D0620C98034EB54532CA3C5B3D3FFA4EC3263698DD34131F2BE2D0F8F2608C7EF6BFB32F1024962FA3A0A590FACA14A750329596C0D6A657D66A9015EE599BDDD2F301F77AAC32A7C562C2D3DA7474772388376E61272F3B70CF4977F28FE8642011C3D2A732E515596D3EAE27AAEB469BB1C287E4523720A0C92332A6F4BF6CA622E9682ABB61B5736DFED9F189EE094A7DDF92E029A55E4A27954CFCFD078B3FAE61CAEF824148517AC8DBA4C2DABE002F8A02DB2F642850EC455F2FC9F199097D172DD9AF098F2B6449C64219B212AF1D097DA737C3F5F483145148876FF4E9867F29C51CE1D9C724A788BF7E3AD0B6D6D1F43DEC58D7A1807B35B5F4B68B98DB7528775556380471DDB56A43B6BE6A85384DC72013413960BCB2168C5AC1F71462F972A6714055DC7C88D53BA9717DAD6A9C3D8D2F41364F6C12C08725FE600075E3820A7D4C01B13BD61324621077163D079EAD107C59A159116C24B3D327F655864D9E0E2F52FDB1360D687BD1A67EB0032CCDEA0AAF903DCBFA68A8C1D6656B7D00052738493D46FB12ED66D54BAE27EE728ECEDDA2F91C64A76E5618469EC9C2BCC038BB33979FC9241358B934A6FE9B23FEAED172F629202C88BDE5397916052616B5B9D4DD27B1BF1E70D92B6F608447AB3A7DCED2C05D5483475599B57685AA6CC7EBD786F9CBE404E340A59A5650FAED4BC83B27636703D27B88BEA09F007B38DFCCD4DA9119E0C48C66CEACB8D50CFA97A35309410BC948ADBA130E74A4A1958E29C6996778E062CFB9DCAA1B773F5AC14DBFDABC4F771998318EE23C67DC81C822CF6C8997E715D5B28F2D2391302EEC9B726974738B13029FBBDC2CFA54F20315F2FE241913A56066CEEC51E294E7A2D4D32A196714086B344D660C43C8ECE4516F2A2B2017E3E2CECFCF6AA5C0D15CE52A273C604909B9B736C73151FDB7081639E7DE33A5C1FE066290E6F43FEB4CBAD3F02D8A7B45679A77460829536A76A07E0C42753181FCC054946198497B1331C8DD2D903D75647CC2401B493B47D36D73A65168BE33E9EF03FAF53D8310890822C61B59FC421B9D3DF406F2E122BA8064C7718246410197891310BE633309D1BEDDD727755BC16986A871F2EEB9BACD463EE948581647EAC75CD912611A7B0F572FC67074C4D3EA066CCE7C932FE982D08224BF0B1C60AEFA9E89B897FC87FD0046A9EDF1306A024AF1E2C232", + "message": "47E8F6B19DE86B50E02FD0A43DA2661688E2523DBF67060812CC4AC61F45608F68ED30DAD053751DBE35667A37149D1677C8DF109A937078C3C70512062A8547A908B9DAB8DEDE68F2ECD02FDFC9CF17DF50F0A58C0A9721C8E9B8AFBC680A8F644644062C7D67686D6C1A32B539627C76C17B10B9E98EED0FE55820464CD40D1F8568414645D95A60AA8F1AF7A7072009FFFB90752915CD888A4C05D7C712FC8612D9BC596C7B7151F139CEB716775BEA2FE759485B1FF942C2ADC1B62B4B9A7946316E02F150F15944EB95225790364C023023618C43B781DCADAA5DD5B53D865C26484DC35E1A5249E58C13A0D5EF6D0B976C68D2F69F8E7E32600CA33B3ED0FF36F847FD42E36E99F5582BD236B33DBA4D9913853DBD546D458FA6CDB348A2115E495412A9BAA5AAF2A68F4B0CD40ED92EC0EBDE502E488A0BF1B8E78E613F85A438A6458C6B7A397764B48648605EFE77342EF3CD4649058EE17E24F41D0EA62CD7AB6BD2860D5CB3B9249934D76C8915AD049C076B5C4FA379CB9AC72DF39CFDE95DB4E974AB7CD1365E2A96EC7E5A7B4551E7B90C8F8A8C95DF7E03DF9211E3BA86B232E7CF6694BEA997F5E8E582F7CE79593ED656839C909BB9DA403A7BCE53137B6F7629F59F90BE0F8F2C1A274FBABE3E5A6065F736F5295BDC6FF753CD39C30F10343DB60CD3BAA4CD8C79C5EB7829D29308B4916323AFAD2D35C95A348C9C09F106A0788C51460EF2C81AE6A25791A5C92BDF6A42B515B0ACC90853E2AC6CE8721C1C7C1EF3FD7273F74779D45C773589AB07A0750F250E83BE6B89C4BA053A41EF421A8C1A51D0CC547A68C4996F1853CD0EE8E6AED8B536A9976FC3C9C7EE5F0C124474CA039794ED4E4DC55CB81A2D2F538CA865465333B7E48FB1E5BE1AA23FC47DB39D47A75AB64D2D010C6C1B39495482E46A2D2489C5E1BC725D4EE11B505A3277F26382B238F7D689CF19157357EDFFC7D96BFC713C6F1720F9DF518DD6FC1B21E07226481C5C50679F60F8DD01B551AEDBB8176C7B12E919AC9E0E885E76E9C8F61628A89BDB7FF1D877832588C3BF0867AF03C0C51237081AC2239B4E28DF238580A1C0BDB95EDF78DD7EB31A04DBD03A5DB03D996F4998D6E661FABAF8CE562B9E2A6494F96518ED9D2F0EAA0EEF7CBCDE941D7F0AC2B0E535BA23D14B7CA8EB29C10A8098AECE7A30475C1F2ECD9109334637A1BA80ECA8ABFC42C8E04835FA4E3C779FF8AF031535D7FFF66B5BE1788203198176F727A16102309BC30452303EC77A1045130C4CC7AD98E1214EABDB9806CC327874C1C94CBDB305FCCAC3CDB9214516367A7E4F3592F538C1735E15082C6686D20B5184DEB18AC46342DFBCE659558063B308FE8D9F3DCAF89F7BD6811747DB87A9270EA2A8CA3E790BEE735CEDD83C4AE02C5008ED30F919F42CA8F003D052B53CAABE959F618F0410ECBD9857BE24486BDA5169FD183168BDAD0338CE4F65C987CA1B1221A72431954E201F99B7C7F86477406999D98057BCE03DC4922452310B56501EB789C0AB44EB427E70ED48FB72965C21807120D7E9D39BE153691DD7CC900CE1B23A8FC198C0DABAB16A2B58C1912DB0FC1FC118380358464B596C1FA6F3E99B450A8CA0475940428959DB4219E73BBF88C3CBB52B52EB3FDAD61BD80364148CAD443FFD51B573C8D4ED6A2442331D66327083BA8096E08507DD56BB211530F47D1D75374E6D2F0B7E4C4C0BD7F31D30913DEE335991AA237C8D6A81C1F21421F942176063AEA420A3DC4C2AB95C12715E17AD36362937947ED9E5F28ED3E8CA760568EA657C473E73245D902628FC617FF854A9BC8B27612D7CDCAB", + "rnd": "11602F615BCF6431BEC3B08E74BACA93CA8175FF742F01D0CCB0A89AB00B2A82", + "signature": "0E4BD44FE24127C30D9E30F32AB073331CF6AEDB6148668A18AF62DCA855E738F0736AB2097BEC20459EA468DC4DAFF9C52CC1D94F1FA706F79B455D7B447399FF605F0B1CBC3AB40B1322CE90FB30AD884737DD6A82FF1F0CD61CBF8DB89E6E10E46E580EF5AD7BE311239933D7BA0E6F9DE039A159E931E4880C9C4C9CB973950947D735AAD39D50F5192CFDB0E7A5384A64B7F8B771AB0FF15E2F2113762414DB2A9D988503F6A7292A123659250B737BC6A299A89A8B48CB353F971CF6047EAAF675AB0BA52F4FA4151E3A0AAA4D1D45004C9A7CE3B5B860BCEE12B566261A2FEEF083B27B1CD38CF4D5B0DF6A9C7B07B2FA294BEFC824A4891EEBBD840939719706904627CA9C3903FC5C29637BD1B22E8CFD7C5AABEC5D2FA35DEEF8A6E4C818E99C2C6458C6DE29A601CBE065274D64FDCA1FD72DF6273282FD2D72CD4A930211CCA12144A387FAB2D3B27873B8202B8CB2FBDBC4E4C2855E30ECD28B69C344903D181FF10E75C74E248FA257348C3720E6A5EFCD153379DBFE1D6FFCA73D0165E0D62BFD522CDF7084006C0470B1287C6CA25781C7210C0301E7A46B5EF257E7B96CCB02482D19FB8D59958D9922AF98C91F6AFC82FC4D385D79383D761FE3038211818E36A024C69C901AC7F1C4C6BBEE1C46BD2DB4DD6E6EC1C9E68A90226E64186DBFE40983B4F18AF7E80D6CACE29B4E558FBC9EBDD2D21EA370E23DF594D191ADF49033456F9DF941E53D697A0B9CAACDEB58AB0EF47BB9193A12AE38170B02A1AC867ABDA12EA550776B7DD71D9E734EC85E1355D884056FDA1B25F33A14E7AE6DAB194FFFEE5E40F4C1F5870E79C591A99A9EEDCFAE8C3EC91B9985F7C642590DE7867AC6951B2E211F758449341D2C9D7A0EE1455682C618D67C6F51A098B100BDD56FFF9D5FE5340E4F9A88A05DC1FDBD937E8AEE25B2A5B7394963CE40BA95E23DACD462225C29D2FEC884EC329FFD813F5A763D56900DC1AE97E35A1BC7672BA06FDB60E5DF2648CAA37FDE7F04E771CB8ACFF92F206165CE310F6DE2EF4FC37E561556B8C0738E644A7BA1DACD7D781CF8124C9B72BC51418E0C21985F06BE369251B7635DA34EEF5373CC02D18A86980AE1C7D3F72C07638B5E7069A74190ED4817BB9ED9EFFAA6EBDA2ACDC40211BD9793A25FFA13E12D852901739BB0BC53F170E2662093AB144BBCE29E0ECF5F8A274BB74ED82DCBF834E36A4E5C0004C44DB58257158974FC6E6FF1531FA755240899FCA6CC91D4E10DA670CEB1574FF5710E321156F04411CAFA09E73444780758A632A85647C3059BB6CBB5D754A53FAE4F5EAFA338CF55EA698993CE337C4AC78586DCDE1849300F0F652B9FEFC4D4942F864A087FBF445F468D57CE5B7CEEE5F5C58AEB9C952AD9AF50D8950942B30250CE60D688E5DAACE03D5019D4A18E84E0D92BEF8E0C7A9C656E9B912CD73906176B5E74FC0C60BDC390EBE63E724EB4DE32CA9A3C6AC26D811A76810B0E98320360C0E1E0F5FA99B19B6EF03726095B3E446B413D4EDE02F8FA9F289D2A6BD6A91AC9833743AFF438C82BFD10F9CAF9E77EB30F9F96612A3FD9C003791EE61FF8D9577F175F58EC09F92D7BBD25B53D826184183341D67A2094448091BED1CB729F1913D9463FBACCB9E85DD38FE2F27094819D35D03C7D2E96B72C564D9DEC6B81A9C5B7CFE42F4A9BB89EF245AF79C3D9D9E26C12903BA9EC0B98BBCA1EDDF4BC10CFD07074ED5EF4A0F867CD399E76D48E350F9CE121FED258AAFD81D33D971FFEF9A1792C94963CD3072A629E2CF23A6B1E66FF5A9A19D990C200019680424F2588547755E7AF3CB68AAFA049DE0ADBC7856A7B287E19CC06BBEB2537967D39D99DF7307AEC3170C67E1558FC8326D89C980C54F2FBF901851DB45EE52EC9F1D51907A23B8198B867EB19AF26BB5B63DDFFD7EE6966C91926CA723710B72FB9D05245AFCA6A68444B65748DB1B0B3CB9578B5545FA11655A1676C5CF84E06A2FA2606C46AC3FC1C0D863769A6AFC7BE54D8FAA8480109FC254DBA80A1FAA8090A88428B4AFBE1F57F4E1337DA5ED48E309CEE901CFD528B6C564724E7C5421D637B236A31E1440F1F37EFBDBC869C3C8E3328F5C56EADF35C9078BE9DA901F1A177DF535DCF6FD5E0ABB5393ACFB25E3BC0D295E408D18E4D602D783F980AB852F2F9658A5EFA61236A801A667DEF28DD3FDAFEC1A60157C5852AAF22327D8BF906DDF302F05902869CADDFBD544C7C7B0646107E065A62AFE25636EE4A8AADA1D0C031D6270FAA70F1CB052D1C29F556E5BAA99BFDE2428A21E63330A02C58EBBDA54769D23CD343DDE94E6AA78CF8CCC11048813E7963D1DE3896E801498AB8C4F61A284DAE89E2375A9A2A8C7093AF62DC784DED4CF05B8FADB9F1E50E33C6D1B05124A9FCD4CFBD152636C0BE9DB0B2DE26A9647968E7907B4E95F1B05057CCB5B6D58FD94B2352FC37435F72EBBCC64D909469C519B321A6F8F1B850BA474522FBCECAF5B5BA8A9E3EC865BD54E2EF66C192FE44B133B247C7DEBD69880313487F2C3FF6D525CEEFE3B0BB3F9DC9150BA56A5EA21CCAD5F3D5CE1C9C3B8396DE42407E15DED163788BA20E8F690ED2A9D9452AD1EF449D868B72245D59E6FA9E6AB3782EFC77AE33480CF3FF8D4EB158D70BB7C6AA30AA4C038028AEC1E9DBD9D6D9657FDC304644AA3F40F9767719BFD21B66F4EA915D363FA0AA11BF5ED4D42602F6A70E51796565B5FC795C4655C3164247CCF89BBD26787C9CC31A323E496AA21E48F5895DC57DD97A57AF479DCE670BAFE18C15874A2A3EF2D11345064DE38839948566110DB93D4D53292B079FCE266A31597C09516394F3B358F0917D7CC9B6188BD4D2CD8748FE6EC138EBC3D098CF425696C40552697695679E88B174A43FDF4E05525ECAF7C6D783705B8ED4874BC47E63E5EB5B49DB6D9FACE5642138893378E8F54E219EAA87DAEF549A4C1CEC095EBBB02AE0735058F12E71DE6897931F569B684FCE0615D0E87979216B8CC0937C66475804CAC95021BB86500249CA9AA4A81E6C9DD3F8FA71515958A75E4A1940C715FC3C18D711479689C6596B50AB3C7A1CCF3789ABAE26EC79E0426FA75231B3590A1F6EAD7F0ACF73C772855CF8C34DBCEFE22047AB6002A24C25C133F1A3FF6D079071F4C93E6C43AD43F093D86270B4DC3637957B6FDEFE7EECB3C85608B863433F13CC1DA65A4E23A3E903104C2286F7B7DE45DC0A17FDF01CD6259A381EA138C48A5E20E13600057714C16688C21968014F803E26B4FA47E11B4215081FF9313FEEDA64B3994A427FD2630E2DC0ABA996A30DCE1D305CC7049FAD77DFF3405B98BFD9AFD9C289F16AA53DDCBC6F3C8A7BB41109570D982021079E8380506012EE058A8B5E39E9D7D20491308EEA7E3A2837E6C016859F7715530A70385AAED25D8A22E579F360FA837503F58D231066C86115E7B5E54D91D1EAD212E8B8E77294973E4A3CB0CD8D53C06D647ADFF20C8E64506D45D7466223D8C6E929EC1ED4F7F7BFD1FBE8718837E26734F62E51C06ABA6C4FA277EF51D32F25F2A1F33CA53D5CE2071C8B39ABCFB18BF6C44E8B2556CD75521D4F0003E7AA7E6FD5C773F3B42652B3FB6277E87D3B016DC440466277EAACCFAD53372ACCFE6D4AFA5D8D456363A626A57D1A795746E6179468CDFF4A3EAB0C0135A0ED5004C3C4FBC6C50BF353B9BAE85575AD679A3F4D59B6110D54202864AC69F599B086D4F4774AA15D758216297B0A15E53C1CC562827C59DFE76DF3A74CF3B85D7953E649D8F0E897435BE7CFAC9F5842B366D396F596C68B10A02BECDEDC709E35EE8D4210C145E08EDCD802CA1081CE6904492D37DC0826B331D2D922AC3DDFEAD268A79FDED44929B5CCC2AB7DF3FF59C13D181EAD0DA244E8E9D24A243CC927E58F16A4347B9EE33E161FBCBF4B96FAEC78B9CB0BAC84F1033A02D2D8CAC719F94F7A93F1828C2D55578F82797258386D31E7446E095762692B6EB37EB38C93D6E347CEEED1FDE0278C50CE11713CDF0C0368894FCFF8F16AE2734ABC691365D7752F0915EC7C8F7352C17DF1356A2EE6E144A71A9F2633861F6347D26C69067BAE8E4153FC11232B52B799C7FB0CD0FC74182E65EC621A3F1118F828E7A8DEB322EDE33DB49B2DE9FE1A410148F72FFF3BCBBCAFFF5F6CE8B33AD0E5283CEFB53440419646B491F79CFEC6D53EA5580A875EE8E5B84F26D8C4B2A6818FAFCEFE994D19EB85056748935E3F20D4987DCE2AB0A5EA7B4EB025CDF5224A2FB83EF491147B640480B7B29552006578DF97252DAA55B1D1574472036C209AFAA3D3F630AD47E1508E5172E110F84E4D88D9C0966F384DBDD5673F30F35DFFA40A931F11E183704449D516220B8BBA2218FB30E67EAAB0C8DC3515C96442B9E8AEC27C5D0F9B06A566CA1D87E7E42895974A969DC092927903FF84CFAB7ED09821064CF6DD286686CADB0C5A8CE5E26FD3568BF2B65387CAEF321ED8A9F3FD6141753B5666F440E56450B704CFBA26E624C07A026935536B6C24BD8D6F5410C866091D801784E568843AAB368B6B5D24E3014F5A7079D1DC225BA3B6D75B7998BCED368F969FEDF62C535AA2C2C96D8692BAF8000000000000000000000000000000000000000000070C11171D22" + }, + { + "tcId": 34, + "deferred": false, + "sk": "FFFB9B8C64D694FFB0640F612979044C8B0E26672E75558165EBA6B607605C5586F358A7A2518645B48CC22CEA3777092B60164C7E15FFD97B8EE349BFB0FE1AA4C7B0C9B23461EF3057A178047E40BFA3E459F2376725A898048B61C418531937048586CC5E929304BF6847BCBE69978E882B74E56FA5BF94B224DB42B18B9A16428501544334843886452530620371687734860803175307713284251732413615153576282806784101866501461673161068217650235404246158005721380284040447505503476241762442322231330548277714614852337603132404705456358725043604857012047121846588611055306042662150701330573155502847742888110856758566056761541886330378750630817387174320642165414371557561252014336343364341155080540441663771641272458612002538044410645537664472626561640005238302803401882713115757656673622178654385117456814573083608576785164751744756810671444825880321575437753271707468042831843416782507546821260704023758032418786060684214817564062813312384443117234321678673841310257672302128014055416745340281244803858215286537748011231236635483161225041100325255287046155167486002816383500464083066564155454357100730061017038432668414024638265360375707883823122713172786048600588888704308352707622758814524563744463614173771848204015825306865861106251158613461116372013326465637530033401765263461535718674481760407063840166044860132036878662313547843166485467204674200230386163831358405704807575731378347100514103365445841366575004703322728887758380528156408884471084522784872270678380342786366820228677574184786387821178761273241101274154517052415302463383656570448644848286071404180106541047855524840650877515426830755660062847280545224250870770537850865703516516168366127745651874346706752657006414701282605663011644810606400476201060283203867537367645085776162328536777271108751057444060314656114154135051127886480671143661638442700353053410084133718848332866125716312470566487116824140456504084257284250456876120701730481575213057674058321460281724837423213874043162400755240741810828012470505740012120886126041107131416730627102001588661326368036831864655434724281288458322325237731427458133765443537471106256330160448165051746005537353683803708758276100125820133246088826402507471752601140530475426711152118276431065228804668111676343351853145382385736642665501307652624833884132830544734531400810423661705826835625006484628706718017517618871422387832227673221267146265865708544112866173471255637676381855207465550242180613637500724050480288700767255625102801068432785608254043207800038248884301434631642057571135678185507171763670732556375064154454038500804681415744242631387508431165861826218274516840057460531026565317776771074673385067212506228177664378480281205715863565607336348716524020488745077002172825805248446850062252738165238545885243773264648708766208841514653436152322483164186501360426836413023513387214835747651350820558678387616355027071325053381163184172511000874757638885213124677630842176811541711617212762836561880015164805860452465458558708300121026462277236058401167040472313582024756567047488807204785004216712714615264381134011543024600283502803652478016380357617566644160180655345041233770871450588810722414814145742060370080318344AD02A3E27D78BC5BEB3454DC63407A9B76EA6599B86E9E66969386499884DF172FB72F22F46BE747300DA32EC2D997BE2F0E40A89C9F2C5D306E2DBFCAF00F386433395FC3DFFA4F6FD5C278BB212B81C0CB2AE047055C1BEA11344190F379D58EFBED3F3BCB76F74198CCDF5F541F1A5961A2D39447D959A07DA6381863DAC2961A764E49B058C1FD67A367A895C0FD79527EFFCB143D5FB4930F9405EBB4580ED3702A2A12900C81ECDD223E283311B89E3CA8326800E6499292008D44DDCA81D83686EA23ED1957A1E163A89AC412F71C66792705649C48695DD3484FCBA1DD0F736FE4BF4F6BDDD79BF429413780E6F94EAC54D90DD7285570FB16132C079694A8AD4817CC6D14EEA1133FFAEC74F6524EA08C7FE4BA1964ADE672419165B2120EF6CF055D153D2F257DB3BDE21A664754C8DB35A4A591233EA03050B98AC35AD58EC2C97447DE51BDE15CF376148204AAB0127A76E8B552E5C84E01F7B1E077F8F7D5222E0B98BE4C49C88FD8F4089942D18C1248A859ED52F9BB0560793D10CFC4749483B38EFEBCE4D4EA86FF78BB53E1C04C97D5D341DE3023DAF8D8257AE13B2B29F14C096D9879D2D37FE0508C1D033286558E3490DBEDC69ECA5FE021C673384AC6C481F630EC3760E1215E7EF9EDBDFD78C18EEAD543641E874E444DD67BBC471020826383815CE2F222326396C8ED1A6F86F03F0DDCDD97EB24F46D757205A1E196E1D17B1EE68246B9AE50DD2898B689B3C040079DACA928FC0983CA9A474586E14B7D91032A1ECC2189B800C2E12BBF0DEC27E0064DB2B0E27771986BBE84D54B01A693D7AAC76EBC25EBE721EF53DB1AC37E432362C76057E9040DEA3927FCDCF1C316E4460A42E9C4F62D4122C997E39F878190C0DE1116CF2E4CC119D31D2E39ED08EC5D36EA4D907C6D1C825CBBCC80693D75C67ED81DB126433248ACC362AB93EC24163363AAF27E2CE908C563DB6E5FFB32FE0022156E875A64576C0B4E518951A2033BF33965588AB936CC7D9B05B7C316AA3C452B3A090BEF095B27A428B4A8DD045529140B38A9340ACBC01C775D39376F1ADFB12EBF88FE1A444DCD1D65B1189728D94FC311FB67C6884E03A0C14095FBDAC8430C0905533236645116FEB83C74C8114A8CAA82A00CA2A7387420A02E6301E2FB17646C41771A88DDC1D2C51E89DACF18381EC255F92A479BF0D90AED7155D049F56870917816EBE1112470F210B0B071F2457EFCECEB977009EC6522D2D6E382775874181EFEABD27FDD06438591403D6FF514CBBB30219CF10612E884F9FC9DD3AE1509C564ACD10E7E7B7A5810A9CDC71A4AE9C248670CCC8DD92162A818DE9CEBC11FE0CB35776231180F8AE8D89B7C57B582C571AA3CF3BEAA6971B0BEE6C24DF1D8EB0BF8E0F534FFCE929E222C891F1015836DCF2FBE8E27B20D8195B293ABB8FEFA6B9CDDD14B4CFE9F7AFD552F00169CB5169C1C994872D22B9C1AC98B5E35CFC47420546D955615053BAB2F139795CF480E5EF3BA92B280DBA43EAE9A58AADF064BCAE3390B69BA6377EC3B6CC119348F0546828F14D9475DDD2C8BEC8F562927C8C8438992024ABF81B877372DB8599CCAB878D6C3B01F861D115B87AEA1DE682C1B19531A4495B1FD027B4790F89567ED515E2E5D7035A3C2B40AAB04DF48B004FB076FC665555F53F7D8FC217017FB5BCB8DE4B9B027F3C7EBA143B0DC4C130F33924A3E62DD65F080F292F586A3E45DB1FFE9ADCE24EEE5029E65B8167521F8A07FF0F8847217BCE3280BE2433F913005E4D662E6D3249B1E535AD68D485CBC8FE335ECCCED7E380218BFF18343CE4683069F4EC448416FB704056D109D7345AA4C18FB029124DC1102DE3CFD888E69D2401986412B881DEE1A83BD63D77C8F6836EDCBB8D746F2552D7826566E84DDDA54E47E238B857B294FA9E349ABDC92A21DD5AAF8B40C5BE54E447A65AFC4244342FD1AAFF6B73285011BA5E957B3850D010DF5C31E5DA6A9FA4E8F9FE2B10B7DCB15484BE1D3BA516A524C252F57F5A1FC0C1730E614A22AEAAFF82F4DCC8AA8E5EF0EF77AF6218ACBA3A618AA0A1B8E45587D6BE5D477DC64939195FD7D76CF124D20DCF9783C4472D95CF2631857A4038056CDB30DE3834C90665FE097B371D6095855FB690B112543DD3303630D7C0CB7A1B242B4A4AFA34DA788641B8E82E715B2FD3B6B53E3AEBDCA00C061043AB90CAF8D96F2D0013FF1F73C54890860459DCEBFB1E60E1ED7380C8989BBBB9EC3356C38F5D9DE87379FD91AEBBFD5F051A28842DF25D5F7F6ED237E81437DF66550C556A76986168F453E1420EAED1A94DC5E87576C08AF905804866F28E195F2C6B29AACA80E9B1FABB3AE68DCB9F37F0749862879CA30BCB1A7A68594DF96994A53A84A050F00D60742332BA996EC5311AB534341D2B5C7FE6A608D57D1F95571975F9D6863A0941E0AC69717889FD537BA8DB60A2A4BEB7E13F2055088858D973A22A20509B6AE750AAA201AD1F2798EDE5C289E51969FDFE68EEE3FF38A543A14FBBB8D3AC35D3D49AA14EFC815FBB65CB2BF22D4A5494089FAC8A7736E4322B532557E6A41D46EB6B562C353BEBDF3731B8BE9F4C878CC4AFDDC822B9B36D9898379B8BE77B7045A10793F19ACBF1C4BB6C081CB11A421885262A166EC034FA3D73D6E292025049AAA261E01228E74245A9B420E859D118E9E066C83D152DEEBF0CF4C14C2FABAD96A609A91BC63796C53C43F532FA0FA182727CF062B4BCE2ABBDB962FF9C7954576A2BC842F533EC41437F602CE4CBAAE0B55933F6E3DF5AEAD1540E32075CAE5E9C46E4688D407A5384A49B7CED5BD4D3ED5736A5905DAA75FD9D7D5501A6FD4FBD1EE2E4848C881AC3F5BC8FBCC918BD12813F8D5750B3FA0B35C2B4B293206BC2E19CCA0DC9CADD3CB4F662F7BCDE92BB365789CA0E06F3770603AC4115FC8A3BDC37B7A2FB26E31C8570A2E3569C2418C6C3538B00E28BD99909EBE0FE1628FCB31B142D6F14373FF2832FFA29C13F7DB1E1779B867B81AE010BB986654100F8033EDDBC3AB8D2CEE316E24BAFA6F56800B2F6873FD35E84721E251632193B75EC5AD3404CDC2A4BDBB9C73938938673CC34575F050D8C342F9592F9036572FF605081D38A1EB7916D1124116719193AD680BEA6D4D4B0F96B4DEF39B742C590B218F63473A3233CE5EE1C68D1338AB25CCA6AAA21B0F221D97023AD61C81E5EAEAF5BF673FF96580722A524569C9517EFB468E7437EAC93C353638E400DB7321F5377F1A6259C489E25E51762093459B1BAA6FC4581622D9C61E6DD70772E15DD045B903F10F6957A74FBD152E0421883A021601BC8D123C62531D152261622E05053B1E1E6BD79F47EBA34B5AF260BDBC77F7EC2D2FF61B24C5DD783A9A8453EFC5544A11E7268838CDCB54280E085599423F18043C1EB98BCDB433D73770AD976F638EB7FAFD60A19E6298FCE0FF78AA29E57FA0F593C6AF814EE69F0CAF1E6C434633A067814F7B11E", + "message": "B6DE40E2DF69637F160032C3D41D7C239D2C48D88696C365783D9D19A153B657D500BBA059B53CD348F7CA833CA1A178E05FE095185C64727E99971C3CAC76E1836F6476965D837DC16135EA0941FF1059D9C5183539C73A7652FDDC33FE347DE2D3C53CB2FB52A67716CFDF96DAC47C76CB1A702958B548AC1771E803FB949040CBC5CEBE75DB7449EF70EA827351E73B00D7C78E7549A7A183B28E6F9C95E8005153E8C2007D4D92A9E5730057CC5EA5E08499E394E294B487CE3BC36E1D2F6371414ED1F6C8C09ABB5C7109FD2F70BE75FC8CCBF95A42A025DE8AC01708EE1AEF712FC78AD4A16C50923ED782B993128E52CC5C371ED5A008D9A69835102CF933F4C39041FE114158C3EACEFB4B7ACB77BFD14402210EB20270C69C15FA303A613922FC850AD16097CE7E46D1D711CE76BB92654B8E3355F1489A125FA810D709BBA50D1AF08709251DD23577FFFB9D83254525D13AF607463CED0C13F77D6904F645CC7495F4BBE163A042957A92DE55AE0ADD1214CD4F881AA20EAB696DC66067AF0ADE504B8E02583A9F8A7F21E94B987580BDDDD1B300231DC023F6131B032AC1B763DD77CB2EC7BBE4C8CE73A6DAC605BF8470F1221F13E7551C7A55BD3C026EFE25FCAF5058FAF1AE00F0C7E879393A79B4501E7129E7B3132DCFC52076BBD58FB6EDE0153FB90FA2E21A09D2271524E19ACB78129224EB0512EF09679DD4C809C3EFFD9D1BD4452C62B09614EDC503373663F43EC4997FB48AFCE985E67253792EF7982B4D5B458E0A3DAB11D97501FB74F0DAF04DF7005C1A4BF861634F6A0EC1708AEFC1782810544236C5F699FF835D4CD5508014E9B8E65AA3756C99D14003A1AAD9F95F484A405B0537B0E7B7BDC165FA34906DB06C49834E0AC2696B597AE6ADAD57C1E8588165BE3180333C356466DFD8F34B27B04E019AE2B7C9AFFF8C866BED1C1C24A03DED7FB71EFF6DE46606D37268F7DFE5D3CAC97B612645001DDC30EE17A33B38D847D0D230FA7A187DFC08FDCACDDBBC7483905854FCE80DC0B0B29817EBE16E039E4044B4546863221E784A3306B1CF7547D9F8113ED6188B8427995D9D36F5463B047B9D51034E7BA1962B157491E74910354DE027AA0719DD95B7A2E405B9498DBEC5EEFAE0AB95BA20BC46F0F6203CC97D63567F830501F2757DFC99089C5DDC1B0B94CDB1C7738CCD632DABFA8F5A9150AA81629565995392A0C15337621D4D67407F51B28C74FEC6EBE41C58939337D033FB26EAC51D9B5C475A25C53978B280853F8DC72BC54CD16B28B200F69AEDC6878CAF159ED3A6CD467C77D9456AEE9EE412F28159BF5DE311C4BD6CEAE1D9BF346B2F2716979278C0E68689A85D9529949DE1CF5A2131B7B4C6AC304B67B3CD062037DB93823CC6E24DA28A7612A9BDF409D39EAEDFE06B46C3AA535E74C56371FD9B521B8A32683B90AF3A8D787A5E190AA510CB24CAA2735365C6EA775791872F03F171C3C89A1A9FC3798253BEAC8995CBB5064C9374EE0D16E4244D07FE09318D4B2504F4E4C0AB5D5E98B9AF89378A13F27661C2157B28F665A8894578FD5C3231DCF6379C874116C8610F9CE572BE6D69C5055A3B636A425CA17B26D774BF6D359E2247A5F4D8F7D19C257FBD8497E0CF60B9376B91D053249C2B757E13B3EEE1CC207C538DCE23FC70EC0CB68FDE8716F93A8B62A03A551A75D57417D467BDA9DC0E9C0BADD909EB1CD8A6E6EAC8F910424AE5D15CCBF0692C292C96BA3FD416D2F67F89EECA60DF0BE72E90A38144A26C2E57A97E90A05C978BD50EB814D34A6849682F6B653F99F36461FC2788F40138E5AB8D8A3D603B26EAEF2E6454436CE4561898837C8817BCE1E7DECBC64786B93A62FC81B7A181E1ECABF37DFC7BDA432DC26E0EAD3C9AE22D452BBF4227D2DD6C2ADF2E869AA7C52746BF166A45020DA621F39824F3E41991831C5F66A927ABC25DC3FE888164215B930291552B6549A591686AD3953B302968AFEBBB02582AD71542D08FA79E0F8BC72D60240D81406FD762BFD4FFC1052E52A62790F0E889F4279FD76CD42107513D69959A6983CF8F40DBA48C4D5177EDAEA5B1AFF04CF55CC8CAA7DD11814A7BEE0C2677AEB4D3045617DCE54551BECF7CE8ED1F9DF65D63E1434E3D8726A71CC1E9DD0C21F3D69CC54EA54EAFD6A016082F03B89D0C65CB18476A84509852FB658BBCE567C6FE7FA18B2B02C176AA4BC89ED6DA220DA87DCE45D31F737727F15167C4592269B5DE0925C545893410EB66DEFC778AA4632AE5DE4F1DA508A566D1B536D262112AC516607E85378D5C1E62782719DEF8A7883A276A4C2ECC3F88ABFDD3E65273648EF7DA70312C9D52502B7DE9E5905064A49C8946C69F219F8791AB238ADD879B4B5DB769429D431180EE0A6ECE53D133CE87B16EEEBEC246611D0E743E1E405A994C3DB6C31FEB560A770589E583BD9506E941CA3821E889147B892EF44E888577EFF18BE9D71D0F51EA90D648D6C1EA4B02C2C7A3B74A8BD7278DE02E3D409B4D4D5FA66D0898C8B1E48183ADC0B0A15BB76B34E9D6D2D6965F9482A0CEF4D36D3D96F8771CA2B737AC9D758DE1EB6CA92DAF2310AED8E345D7C310BFCF754F5A0F64982C59CE0ADB7CE3C2BA17AE5A6F5351151D4FE2D1D6C25146277E331A6E588D3C3B5AC0FA42CC73F37FAFA6961EEB8EF3E9E3A7E84B9FF3EC5311D74E6F627160ADCC45FD473BF8C5372E70C9AEA558FFCCA37DDFB83B08805807363B92AA21F079543B76EA5A9767C25F23531F4BF38A4C69F99153EAB5E9422F58DFA2BB255B819015A22FA569C534D0CA6D244AB0B0E6D9F6B705A3808EF76B1B5320CC378DCD489ECFFBDA634320FF34D378AC545E8379ABDA48F2A3205F107C92E88AC469A4431A79A9342992B33FAAA9C3E09E74FE04DEE535DCD0E8C14703256C1782CAA8F7B417215262625EE1B619DB65676335E9AA6B556D60585A3CCC0B9688736A58850E2B44D45DA86F335296342B248E5399ADDF81DB50B622F8EC7EFBD195B177EB4400F3BBFDE3C82C46A523835147BBC7DD2B39EA569D8602E641B726D4B5D876198672DF5531C5E7CAD878D6B80939A4A5CF876D289171B7E048ECC2CA9304BE7CDC8C8BEB60966499627CC854664BD20482B9D8735553A6115D40EC955E4946A0CC3D04DB3E265FA8FAC37C3782142135822114D9A48BBAE068C911BF3F5F5CDEB34A698880552596937DFE0F340EDA6F002BF5BA28FAEB35C5843063BCF225F9D2B1465D84216177DB3CD38FC18065992CCEB264592E90FAA8EDA9E1CC00D2670CBF8F9AA7073DB3904EE9B8F493236F65FD648F5932B9624BED64C2D4F1C5C4F5C822E4F0CB96915D0C971291DBE80CAF7ED391C5C82F2FA480653E989BBF27617A94DC9FD3EE388E295889615EE2B02CFC5D9419263F8AA4C1B8DE0425BBB596F971748C14080D13ECB70552D4F15D5E696353515520D2EE20F0A7E10125462FAA5E53BB411A8F4FAEEA3AF82EAA956999E0296BEA60F44C2DB5A6A357BCFD26B033FD695AF73E93CF3DB24A6DFFA4C794FF9DFF4BF762A8C7AEB380AD5E8C6134A7F8D272296837DF75634C09BCFAE0355402E41D32CEA9066F93C32E1E08328ABB0668E0D91B96E3BB311AA068185B72E19EB690161C3A10D8AC8EC04CF3118F03B521176CC2D40B93FB3A6DDE82B2FD5410213098363FDD1ED5A2AE2729DFF69EF9221B15AF8203CF4FC656F959E57B5AB5EA2BE9B08926D037C7EFC5A35B5A5234C6C4FD0CB33E3C0BE0225C1014E5C468518283312A65BD2028C8EEBE0EAF7123670E3FAAE3AC376E5D13154747F8FFB5ADD453CD7DB942056FE1B9EAAC991EF569A409149B723CA54F01EB6D6A2D01E1B39A572DA5DBC87022DA1C2051876F4880807448DAB3500501F8A8462A65E08C010A721CE19F75DDEDE3C7EB773E9DF84715D24AB903EC26B639CC1BB8B554EAC6945FEF7FB75D53CA2D4BC6DA063ECE1461FB7F4FA62060FAF2D33FF2400B39AAA2F2B50DB159439421F0D963E6198A78BF5CC3EEFF8CB84A6CA1D9FAF274BB07AFADF391B68E7024E97EDB5E6ACD9BCBCE3167FC12E85895846C9B227E2D12FD4F443081E459A92658D6D657213CB708C3572704710B4BE02FD7EB60B4C8FAC0D6FD9B22D55E23F636D8075EC9876D6FCD50EA79EDE8FAEB6606E00750DFFF5F349FDE8EAC8558ADD015ED6CF7B2E60FDF3B40B3282F60B48B48A72D0CF30C2344FE10AF974DAA0E0312A84E9D86340D33ECFB5C03445E454F75DB57935BC078648BF22BC01AFCDB9844F78674B02A679F3A89CC6C70AF3729D1CA93284353FB991CFEC8EDD348BDB968CDB37B88161A09049AE65759956254DFFE08D7B64365F8720F8ACA346B3921E02602D3041728DAA2496CA94B6EA8A7C9FD590D699DE06AA1B792B1F0BC53704332C5023C2C51390C727596AD07B005C07A8787DC7D53A6293FFF5550344D18DF1AB0FB7369225084358BBD4409A9", + "rnd": "25965E34B6213CB624122B9E2436180F8A707033C0D62863DBC7BE8DDEC08764", + "signature": "47ECFFB94A2E436540502BB70CD056830FEACF8476B23BC39B847F4F080ABDE68B5F5653BD68A2DE5040DC1CCC99200EC10FD517A98A94D17D885FAF6A8D9194C84A88B2945EFF16283002EFCA2264ABBA75B50F69EA91D97E30D667FD054B29FCCE242FEB2F6B9880451E73FC8E930A8F0CBD9B378D81CC47FEABA63F8715F4F8F9A98C7AB77A516992F1E89959AFF9BCD1735C08A8B6D36713E77455426535EC8DAF96C1544DA05B6E13B3CD5690A53EC790ED4BFB7688CCF7DF6A8EB17512D240489515E8BDCB538315BE4E8229C2989A186A5F1CE3170DA8BC21A4000E8277556DA295CFF428C37DCA79403D87BD6F8359C48825AFBF4931DD9ACE14EDC84349C087A2764AF38CF62C8064C837ED1D1B19FEB2413C94EF1CCDB1B0978C037527A02EE099E13139B7971421DC98B8FD66EB150FE122399CE9C4B543A2DCAA4647839CC108B6260FA55C7123BAEA4FC70FBA8739082D29BC6738DC6ABC2FB89FEFCAF67556160427465F1686C7456FB5E9E340936659174CB8E0D23E9FC8AE327DC6A613461E03E1F5C462ED8C82EC87FA9E4953B19C65D961A33A099367A3E706633967E26942F77D90FDFCCA0C4DF4B1D130DDA4FDED462E613D688D93E4D852111BD5D6AFC30F7BC80316757C2A04AB166E9EE0C4F8F77CCB2C7F82A4A97DF5CB36C0EEC79EDA0B70AE66AB4B5370AF89980D84E1F6C20A03E50E9D68031E80228A885DB9667777949503D6E77554F6D02A1699833709AA31CF3D179DC7D4B8A9C8CE937466CE57A6C44E28CB50FADBD4194B97CE5FF90B44C27BCF5553CD8B39D2D4AB2774F37AC16869AF138345E6BDF331ACBD3A500D1582EFBBF7B0DA8D08C1CC4EBE0C5CBAE5058207988B5C3E0ACF0707BD7B9DF284FFC955C0FE88531FC98EBB526D68DAB09BA8F4B487D2AF6E42FDFFC03E3E38022351596D4DAE196F506F80B93D7B5ECBE5FDD3011B6F76B8782F44BD2EAC24513CA393B3731103E5224D7D4896EEE1E6F3847BB16A37CC7945B7548C96143B0959D4D5843A8579616CD9F9317B17155953ABDFB1D55D08E49B6AB495A4F5F54E13BA4A53F63D19AC17C63802DC7107539E216DBFDF4C07E44C89F332A221ECBB549FBCFD8BAB122ADE7CE5AB77D7FF0C0226903549FF7DF2D383A628A3065DF5F0B32ABD5CF723F59A3AF6027463060C38A6BC3CCDC47C3A21A35C727AE5429BE29AEB2885A04A6AB378F5E524A7C933A32A0B0D730C9D0D2F409D5510FBBC25CBBB5F0ABD25A3B0DB0064D4E20380DE169E92AD73291F43B10A370E7DDDF9F0475F29E9629442B179F8988DEDB1C24F928BA68A159AF3A0576FFA3E2E5A8AF45B167E75838220614264285855B7D4DF9D94CAA1D24C3E7D776E747269373F7B53D43392275CA7B74680E26574C2920127E82E40344D7B3F15C40E2E1DB409EEF8BB82CB24C73D0CB0772F7D9036C4D80C57FC0B8C35E8F569CF98779958869D2980DD303118DF9E81302A7726B5D53469D3B7CBC062685FE0A1615AFF538A45F5655FB682678A7E10ADA2727E1F4D0E761B5465F28CC3ED7BA6CDF1F15DE8DDB102BFE23803B36D627904BBEB7AE8005BB9D094702C31282D08698BD82852E6F409CC7BFF31E6FA52238B797FF42AEA3CEE15180306FBAB44794A595E318ADF2C84544448BAAED3BC84BA4F50472921B4F182EFF63E0C8A7BA19A71134C34FF01C92269EF03301FD7A9376B2A8F62A341F424401457939F405962AEACB070EBCC0DF0E7F7C8F2EF103442CF7890E7AE9E8509A3C0FAE20C8A60942ECAA70A7440C9F4BB3D16743EF3ED158CA1E5D2FDBA6BD240F3E998F4D2E68E029C1AC9196EB1D39EEC9C8ECCB358375DE3F229B0F2FE2EF8BF1A0FACC87EA891E574C12D37B7FEDB0E493A47F2F16F4CAA3C311B65C6F80CFAE4ED95B699C51D9D98679750F5F13FAB6CC2BBCE994426A7C2CB7D3FB66EED156FE848C310C5FD021D5B005573EB470B19A1241F6B72D011BAD6F20E139F022020A909AFE86FEEDB7FE8DBD1BE5B155A52471A4219E663FF84D1F4DE453BE2C6F71B16C428177D3D052AE9748814FA43A2704CFD9C9D826B75D4DB8C8EEC46F2DA1D0A7E64B27383A6C9BA1202BAACD54477595496E85703E0874038F826E34D14EC213C52A5B74CF9BDE05ED66CB99707B1BF541C1E755A4F5EC1DF914CF321C01EFCC1230CF3ED1967173156DAFB0457C0009E193158637193FC52515B29D4649DBD99C9AE662ADC726603C07BC9921B004D2FB0085A6A8F8D9FD047309CD35B8336474DB5D49EF5AD04BC8F1AA0C51FD539C2F77B55D70F4D3321FA507DDE324114D15C6E1D51E44993A5E5AC824078DD7D1AB01BE99AADC1DCCCA2607307AA4188CB873238FE8AC5CF241017D3EC9E8278B9EEF2ED6006F6F061936F488428F1183B761420D4441A3787222D826E22D17B27454EE30A892EA37DE56C0F335321795A527B832B793730AF65C55F3687F31FB915096A1A58830832F997942BFB01E54D9CEA2A61A7818970006861BAF54A7269BB9124216AAD8454BA1594EA5B36728CE16936220C02B5C4437B119A9B6AAE6552A0AE12A197B2741ECE792BBFF943EAB78A20ADAEF9F250E496130346781346E74A49A94D868B162F9307426021A1EFFE602EC217B152D84BEF34D024DC163104F68ADCE293F7DB5689E4E461E204D89E4B73856F2A713EA301849D2EF5F6DFC194D6370E4504305BF7229AC18A93861BE303944D00EE369B50D2E7F7CFB5A688F54315814CAC12F66F15BA5D73BF2545EB4113EE3A53B66151778E1835C22A952B2ED43D0BA60F616EC60C5DA82DAC98715A3A790C214C44F3F6A3D871D528329A32E6F220F110D0DB7B24BC9121FD0221041939B0291F15D27CBDCF72D4197C3973270535E785DA375C432FEEFA7147787E0E2D1EDB2BEE0E1906F0C1386DABB811ED1ABD969C2044E0A6C2720DA89E2B079404BEA58A3B8EA510BFEC337520D0D1E7759FBADE3172360C9CB99C1DAB939FB545137267FFBED6476E1CA74B6B7A5AB66A50BDD983F11807AA55AD1CBCF33DF1462F3417F55069A12B48EB8BBABF2E83E383F3896D2E8A1CB909DD439701D0EA7EDD304B25CF4B3FFF04398026876FBAF56E8775D58F8EDC751B0579D4A20599EA783CD1C169D1EC4FEAEB3412F2BD54FBE532A89FDD4BBC148EE00A412AB046264B7B043278DFC461C299E53CBF9C8B7CCA2EBF7BE11794D1FE2CB925055C91CB86C9EDBAEC5CEA3B71634AEC5347E5FECEC28B2B06F53E395885AF814C93AF92CAE9EFCA64FD41F0CF6034C5ABC162D6891F7DF44A79C7EB84DFD1CA32062A655D656BC596135CA2F7EC32F40B958291FB9E294640E18BC28136F4CAB38074C22CD5B17AC4C6AA3780D90DF7840CA4A5D4531AE77590FAAE1368284B9E3B52DFE7AD7BCED4541A0510885A80206D28C326179E6F838279C0088BA9161E6AF2DED211292FF733A7BF513DEECB71790FBC660755F50CDF7B0597E93F97861BBB5DF9037CE148B7F4123DB7C564BF9679A974D2380D8F3E62AF75AC90AEB1F67EDC5C603F50CF6CDE1FD83A2ED8E50FB58728CF3FF34FE06F5B68C2E3E0CBFC810772EE75A886575AFB1FCC7FB5B97D9F5A95A303D2D8822A0E794B3B7387B68B5E6D70D0F8A2FA63060C331C8F4C45CB4562D6413D71C194A3948B1D91AAB1DAC7CA7BEAE0720F8229AEB800F2E1D0A8704F4B97EF566E18630AEBB43BAE2ACBF6BC3F2C00EBE4972C9DDE9706EE696C7B7F6E46E21F92777EA7D3F4CE1482A9B5827D74286139913BB6492F3DCC60739CA96629966176FDDBF912DFFD50184154A7239D9A5B622D54E3C7AF3B16E651394B5BE97E74647E18BAE674EC6CF19B82796A53EABC6FC9D53F36500959F47DD8AB863E58AAA6713282C1EE0FAC9F25424290F6F97A706CDF4F61378ADDC962E25B38D9A0F4841EE71C32C0373F5EB7EF42DFB7D410A4061D8FD11772A20A535E003D009704C1544F4F98C2AB1EB14B0231D233F33B3D657A5D5C32FF1717FF3D964CEECD75C74F9F48A03267478DA5572AF92FED9FA01190850E4BFB6BCDF29EC31D3F4777C88C67E54F5462E2A30D81DD1D1C7C2B60C05E0AE198724620BC3DFB7749DB76F78EC7144F11B3675990907E8E64DE0B46E7A259D85246A6EBF0808BEA0DBAD3161AC33DB37E9B0FCB49C2E94CF2EB0464DBAAB9E236BA0582CBDB20DE24797DDDECE88C3C6F5B4E727E7D3FD61FAA22D79B8BA3A3C6D2523ACBF2F793EA8EFD7FDCEC1E4BC3FBFE5B8D194AFACA9BC4F798659600B99E09292B8A8DC982BB7B13B20DA6F5927BF83DD6E5708E8E90964370F25678EB2CE004848A089D6E80C56A3EED8BBCD1B5B756DA0D58B2F51DBC17F2522C41ACCB3C44DD5FF372A11513FBD56FF4BFDA09DE229310CE11B6242E131E511D7BD363DF06EB5D5DBBB6F11A4E50CF04A312C268F8F7DCED62776B09B33BF53C21AD0421408A85D32F610F2AB5F1ED4B5AAB3EB94C0C033934CF00B81E26FE4D5C88E659DBBE4382ED672DAA7B5A3D75B1B957994F01E77CEAC5EC210F620FCD1E4161EC73DDAE876ACD089DEA7C04123160617DCEE9FB09222844838D92CEE1E5F4F5FAFE15E0EBFE0B627FB2BC62C5F3757679F70000000000000000000000000000000009171B202327" + }, + { + "tcId": 35, + "deferred": false, + "sk": "AC50013453260F4585C6EA277DC92C1BAE9767F10D55F70AF733ECA1A94D74AB2B4F4D0836465E14EEBD13FF668D400D449F6DFD1EE8D78EF3055537703E67B848336791E71753572E3145205BE0378CBCA2F2448D81031DB2C5431637303633588FF6763AB8C77FAB54D4F533ACC7F6F43A8C2BBB4CF8441B8D7E039093EF0E486268416313803435277715718842842031814624063570542021400577256631250145413038530528828633556808745586764161367743446128204864825143457565842736664446222644411078876557716700748667654054868715828331213853758586800442505352438110864650817455410400823431582285020003606168614216118432407271030312608232513448062155245652833230028203642312876324002341864264764118331370765727648657223518123283238765185774111858764307253554742341765460134533137202740524264160427380226823575772480224035366113474558326445558238850721242267575457116541381718235661476160844628536784782167584214476118044505510454722241134885017765801075147101746708457272086275704278572031461743722362746865615836350404223152140133107718842112313761812107172475111841845207522043641747185671130328806710001333126127542136561755605216204284750413877675075244024782010346403540433650403865870303148766787675078468008655566021623147366434823521624337237360751611703114802834456165882383122781763061451286868851842754876185050577525640086238413024435681336786365048078014256885338212427184647753440365833850173652484715701361153875252722233674086224052670765253464263347356527457558780227342108661308514542857143487374268245515681728283544508145761755085205342088846124045671356550484366373337764436783202230587256512181110058604500527815252350753043244332086874055255068386742101251033428855071542202250023771256311266735640420061061850708087548650082017557762368157755223537711260466262456533841316031057617481835516387716013570515228337824618030418465833404786218655545310022220027334826515826814310711105454727025430746556041470458568810630081208721000338874153526640432226374210186182473423777557242522637730681470515038080226817400664551252034323604142686152613430505445106307743076384666054751423506404247203865766038347743174356301845718547282125742531723020361878048308607073132355014710338744641867340001042788743383772381302353142064167570614753217318428344608064286432387237823750305086145716370403765210046814075887071656411846748408560132551048340174828233772476445175670634150246821208282415473684232004832728774654288130507568500745245315848276385117420253274062157884867163273454162616428833158038237808346537403325507566086277257237658860830632245627060758728527160327137527804421134172854341704485782547540344778323660373886720645023000101164345287077216162146244268036041147265620501685386264226308526602265514136674301517538486488427015867183204661775246120858066143353070806554266733301644812557350702505332658653605007422520565102387428244678574784501501203351325571323475587420700823841381602405306021245333587507633746460442605688037363342667548681217644137501267035118353333817344536501557285224532753564213718266143118557133125165445538438842570356146123104650370004253113065622728283618447105326238211407686635161813556034626037853D8FD7BEA286D7288E0C77CD00E3F1B007B0FA59B2F3C63526008EF5AAD11C4F85C0B501543CFADED6B2BF0830623F709506BC5B668F6009C5300DBDDE070C484C3BA01F8E67EBD6DBBC109166015D447F08353E5ACC43C3A1EF83C08CC2CBE09C82D2B5AAAE1187CDE5AFFA8384D40ED3A1E2B003CA4EDB06FE8C4D146273C9053F2918416E7F6CA5B5458B5182631463E4044F946FE7FB51F65C44596562FFBF7CD248AA0777024BCC3282AB508406AFE7A759D1C4B50EF0CA89C8984D2D01E54A4CE39553C6DAE03D1C8D967677F08B14838F94DB68DACCC70BFF2DE96299BB680349FB8FB52AF7B069598245183700C4E18B89EF53A42FE5C743F8212071F2BEC116DBAFCE1661B1412DE97138EEE028F0B353AFD5B51BD86D9BD9B03A811667923977A78F011B8A706AFFA8EF300E174067B1CF1DDB50B7614A8276630F76322148811F2A7F01D65C47212708DACEA61A07DC33A31E7DA2FC30DF1A2944058457AA6DC886085E97819CE338F6D8EBFFB25CBBA70FDBE98CDD5877AAD8202A7B4E0FBD0715F72B4EF0EEED7845B76C9FFB5AC14E3855F9F19CFD42A9A238CF5D6B3CA9358EAB01F3CF656CE3A1091239CCE0F687D416044BF8387215F570318B64E09203E69D4712E727BF046F75730B473662460B5A21A246BCF5425F358EABF4A2EEA6DF8063F83603FB803101F055C9917D962A5A21EC6AFA19A2ED00123F4F71AA44A65572ACCF1734C0B1B43FB5AF83B173D3C59A83FF02F6A4D4021E9A73D6986F58DB5DBD4B12EF54DD4AD802D005E2C9126BE799AA1227477182D032F900DE72E561F4A9420FDA941E6FDB3F230C1536A5D86DF9A86F6915F32AF9CBDA428290E82266814E71C2B9ACEDBA3AB99165B9555AF61E95D53E460E0C7A8A908F20517DB829830DC53AA63A0D0B0ACEE0B6CE9775FA6A55974239C3642F5FE5C07931F107B0B5B9E2A07C9D11752A07F66E67E41CBDB5150B286EA2254E52E2A274674F66F5E9F6904EF463259C7AB6939EC9F0A40A9B9CB6369F7B060EFBE2A9BD69C816E48A65C0371CFE3EC5F0DD0B52A8BD5DD1C0044E98F4655C5414BDAE985421282845BDA5125B07C21BBB81730BDDE377EFCC9E22BBDD0DDE9DBD5CD484DD8B67C28A2DD3A3990E439AF2A9E59A355CCF42D9A64257B03E87D3C2E16EE774B73B27E95A87ED0663E4F1E7269AAF76E381CD374BE6C05E6770F8DCA1A4A33BC9E72EB2CFE33DC2BB4440890373CAB60706A1BAB96956177043FDBD5171A7D8F5AF980B33C2E7C8AA3E17982D1A8F552F11C272D38D0FE67B7893A1E1C0B16886C06F2B2D829720A46FA0869726BB58E6AE3E1B96DCA2531A41569F7A67990C16616C77CBA5E610B7B70625F6D88239B957942253595A9943B6632C8061CF448CB3B83B7EAC9010516D50AC9272F0DCCD0F6170232E3BB9BB1C4BD6790239BFE916FCB86AB7B55309B79B241AD3925E2D86D99F713FD3F2B17D084B110F551B2913224E1BF21118D6DF9EB379A780E59EF4BA35468D4ED4293B7E260870DC05053F5AF7E6D202DFDAC46CEE2CC39BBA4A4D4634AE0C19E96DEF7E2E3615E1AA88CF9B854281685A31326D9729EB3E4CC0D529998B05899FBA81B4EF093EA345EC025420CB48B1645889F5A862C38E5D92B239030BA7BD89E646E552F49355897A9A49FE383A21FE673F0327CE509493CFDFC441F96228C941449C3D84AEA359F80BE4C61CFA2AD4C70023122050D36116535C2E1666433BD9CD99950C6EFA355E5D920649C588711CBE3CF4C37A77A358316E066D9106C8C6B470746CAAE4043EEDFF32C6B1E85FB29261707EFECB59A71433DC1B11AE4FC9584CC9F534BAF1ED4508CDDCE702C3EDBE3C85ED2369A412CBA339C6B2219B5ED0154A574FF21D667C2E8380DD0A7E507EB8C098EC7B106AE57861801FA61BE688061B44C0C858CE8BF7A5CAA6B694B048456662397BE8E5E65D273DC287D0D403FFECBEDFA9159BF04EDB508F2B9D8ED19431184B657D8A847B1696F7B5F87042CD81AB9A13F690886D550513F45FD86AD96F03E73F7A88A75D48D8B855CD4CD262A33749D4C16799A3CDAF956AE286B436C669B2D02B0E0D7F670D7B3CBD764D1752706DCD02DA8005CF36474126818392FEF8DB81817B7C04878157D4BAB0E6621C1FE0A33BF1CB90CD9C98416184D31E3AA67C59C9107647C1B2B3672E8587B88C72F1CE3653C8ED94EC22BF6658CE41A596C490C21F6D1D9CCC8D9751BED750130F5C3ACEF3BD75070993ECD4B1EA615355259053846CA5BD3402677521BD251FA2F5F220E83871A054D6AA74E3507B5DAABDB69AF04CD6ED0D3AD3CACE5737FC596813F82E54D8FC1E312D3135F1D39B2AB77B94F0F6D1E6B1C831887A9BAF777665EF844AFA5044537F9164F7F82E1B326480B23E33E79A869143BBDE54953F9926AEABB42396768CAA60B1B24C93312CF7D85405C658AECC5D77E39C6A3D3C469EB5DE892E538825F297EB9EC1D2836355D79BE1BFAB33B41F68AB4AEEEC71EEEB8FC5610572E897D6AD2149104B85D5ABC3098325B776417204B618B2F62C5246D746B7FF8E164DE3F5FB1471DB54A82A2919757D8FB5B176BD4FD8E6F851D4FF7B534059E6EC3272CB521D62781738086DBC146DD7F8F3DF81AC26683BC7B3DD6AE4E2D2FBB3CF98E7D96E4E8DA4E0A3F5871D51791286F800B8289A85A5A335653AC1E84B7A7CAEC09357EB5738866F3566702E9D1D0148D4E60A82BDD6B9CDCE58E8D2AC534C4E20E86FED638926697550D4EB76C93281FA8B834AD1BEA2ECDB7F35FACECD755E3D7BD0D1E6259A2875D4F925D7C0B4A7ED75DCD20F87E3E1D1420E2CE20B77FCA02C62F420E9BC2E4C15CE7206EE7C1EC4EDECE62A5763DD55F8F58E2FB664D537F194A2BB67F547E704BF14EE4C40B81DF3704CE35D350629ACB363756F7B8CEE271A2C20B35BA9E3464BC65B951C39785B767128DF2EAD058F0C5F09264A2F703274E694118F459C979E6C6E0CF5A6C372A62F3C7C8050385791F98C6BF7F10FA6ED3151B26FD15531352B4C8297632443F884704217EF2423C0D138868ABF8318D15651EBE0AB227BAD9626D5B3C38C7A0DF1123958DBA4DB5F91CED964E2550ACB03FC56EA411F68D2EE3EA830DD7E06801092C38C555ABB6681708A42C6255AFFA2D431C7EDF2E3CFFC34755CF64F462259EBDD132385C5289E06828A619679BDA71B4B25205CE10E2F0AE31A3641AF242EAB08859ED96A3A0DA5AAEF81D6D419A9CCF024920F3302BC8DC1AC15469C93313EAFAE5A68FDCB36B30DD4F66F6A7016703164B37114C7330ECE4DD273E18D59E9F298E2B712BD9696491B5881A22DD480BC41C31F7457874FDC998A2108578EB65F02728FB4065EB22BF57205B66048D6403A4B80ADB66B09D979C69837F52163465A18572A926D53168ECD4BD6A1D15651AB2FD061C689535578BAE68F71493BDBF26FD0D3AF678BD01052640A76F63C562B17A0717B5EA9C5FF40995AD4A8", + "message": "A680A3CC812A9E70C717D53932683E2C519E3C67349BC77160633DBB69F42FCC0F411EB3A6BE9AC60F3BA54CF5F6EBDF47E698F55B3DE8C4334A8B1BF1AEAC6D64CA301D488512E99398A41D5FFABBEB7F2E69156193973F5F6638B8A82E5FB4590547B1E26A0EB0FBF989F27D472B6C02334A50620572AB7B128856360DE31D8B22648B67BE1FC97FCC1AD33F1352E7BC6FC68C4BEAD6BD90AE6F01348D7C16CDC805CF2FE7DBC9C0953A39C30259EB13BDE4B324B1E590F194724288DF5FBA05DED698FE66A4A022EA3D317BC85203F1F7E1944882F4A3610436D388FDB4FDC7B60115054BE3F5512C35195446952868FB403CDD267007F4DBE4E25BF6CD5704927811F0BAFE3234BEBBB889E97F45E791CA5655B88F3FC7F2D0047D17B30DE5BE02D38C7DBA325196F46D6637FAC4E061FA0F03B2160665048EAAEC50C8282C21F083AD5FA6E2A0CD086BBEF543559DBC554640DF2ED642AF33325F5AFF5A01B363A98D978135A73BEE318858B69937EE05ECABCADC8FCA7D1B2E954E1D8FFF91C3748F7A43A3A900101D6FF9545DDEC8817DEAFEECC528F223D13B2A36B7595D2BDCB59461B86BF0EB988F0581EE4F5658CB0676ED2A6E7809F132AF9394989F22F0E8A3B3369387F4D7295B3D31E35680CEBECE577B4E138069CAF54060C714F3CD366544CF25179A5DF23C3EEEE2D4E6720F5BA98C6D59562D73D94D2DE5E713674A2005CAC9902A675BC4D5A540F34218232547DB7C3EED3C2F0E604F7FF522C7E17EE224EC0998573726CA5A96863BD329CC2308AEF5E62C44F2D361E7618E251F6B2B7BC66BE5462DF6D0636A322F036F48B10D1B41320CFAA890D250C64D0789358CC589AA1BDAD93E4AE101E1D5D5C424283569175BAC30B426E246BF8478D8D2453F07F427977D1A2476EE63C1218AD791D43E25DACE7594B9B14299F5FEB43845C3035FAD56F9665B44E6D040EA66697B3CBD39B01D95489FB44A20FED85F0B472E4D278B05144E0EEE437017154904D240715409FC6693EA8E65C1A507559EB4FDE58AEE38AAEC91C73617B080D60575EF28537613092DB93C5F35F2A5164405F3F1ED1ABFF3FA94E868122920CF4AC35866BB4C5B91A6EB0049E1323ED5FADA5F377FCB9A5DDCAA74AE08B9F42D021E9273C89FF0A43D73BD88789B9E6E42F022075722EDDD372006ABF09805637478E580A181C61CE1B75A6DA9D17EE25664460D1C69A6E89E33F48EBCD25B97E0665AF77EF5D389FE3F70FD0B8B102CAFC27E4B2FE5C9CE706475740AC45B52B465F9B9FD2DA5D4AF75F3E637164C13A7FE52172410FCDA20572524C983FFF125A714589FB82B01D9A25B2BBFE92595883FF709B581FAC9BD9972282F7F770BA1B2CF5DABD5539F0808981ED9B973928054A3418EA0A4F504BF2DF358330972C134E5337CA6E92C8086AA5976FF89EA8CCA5B39F1393F87E64B039501D425B2610E1E62A4005DDC8E947ACE288A4108552FC77DE56B81DF968A33D98378C1FB54D2E4B707DE19544841A57218D6111925860DC2CF7A8546C62540BE54A61E330793A53AA3668F63F197F86AB14705D748877FA1ABC88FF90D871E97410BEC40AC56BA1EAE5AA0A428B98B5F7492CDE4BD82CA40E6CA8AC2B15394440BB81C7DF66CFC7F2CC25913C8666B358B404DA2CC294F5D89E3ACA8D6E7E1086D690B94EE179FC134990E0CE05324937360A9925B02AD164C0A94962D31193BCF3966ECF9DF9635D3A9A47A409B681E79DADAF022B042D4560473854C736AD8144FA848719D6E4D51CC439DD7041BBF90E109980A2D8A7882D88A672CE70116467C7E5C5BF8FF8373E41DAD28C4ADE06C9F6C4E89B15592AB03417121E1316E796B6285E5885FFD30934A5FC0367CC44AAC485D567B82A90163E4BAF53017BD43DEE3A489F88DB5FDC3CA0C5B56F690BE37A2399E744C5D10EB7D723D5CC0FBA0A5B5B6C63AFBEDE5E7D2A3D893957ED62117B62BB762F894AADF85E5729CD066A39FF0D5CCB2D5EECEF0016DE107EF7063E5D92C279E3F958A827810E9BBD5E94084E08206E2BBFB44DDC9F7F8831623EF6FA1488510EB8322F6B787AD1ACB98E8F9F1F82BDFDF042D5F3D1221628B4209262AB553BEE3317C0B62E5E7E85B81F0EB5A84C6204A1924F5066841688F84DC9E70099BBC83427EB71875F804FA34C87F7BB0E768E1792FC672D70061E995815BEAE11D23006C9C41ECA8997ADF96CC07CA2BFD10DFC6808D2D9C2820846B5FB2EFD89BC63C92AA78C1C72F61075D629AF785CC4947703386A759B6ABE45D091B09A1D74231C48C96744480134D28E7E3480D7E8D866953C61BCD8AC9291FBD41DB7C89EF40ABA8751353B39A374F533223DFCAA29FE498939018EDDA3A9FEA28DFB863A05A0BC312AF1D721FFDE4DF09A7C56913479CFA3E1CE4FA04BD58938572B17F1658FAF78CF3123F9922B4788B1CAB32CE255CD95ECEBB9B5297B625EEB795D3766FFBB4D9938E7020FBC9F9B83691BBE3464B1A4627EE120DD48A1B63323A631C6CAE1DD78E791940A2004DE1C86FDDB21A57291BB140248CD34352ADCF132048AAC2271344D53A7066CC874C7BE5502637EA7653830DDE94C261ADC9E9800D2A4CC8C71996149D90AAAD2890D5E7EE810C3C2DDC3D6C1171DBBD28E166E51E8F5D5C3369675D6265C6B3BF957FBA51EB4313AE070F6A867F322E76F87A63446A42A74A27D33194BB433D47C3EC439F51B6A245AA4F6037A883069BFC19A6A20E77ACD91F0C088E89BDFE6847120A86CD2A8F9E1D71BB161CC6562F61BA52BAAC845ACD7311CAE155C0B765667DFEFEB268554FD3522768451FEAE9ED5D4E402365E54511BCEE237963F144DA003606B0448CB0FB761F91C96C8A61344444460491669C83AE433E1850C5F3E4F1D4CF801F2D32A353D2890269F355FB06743F56D535AED0B726DE762F03CDFF22FBBDC18668A8839B1C3A3F3654A98CBA6E1B1EC515DFAE9556E9C7B0CEBF8E11BF5613800F6A2292046CB4E44326A0ED8F45EF92DFBF790E3DD0F08A3B8708D11F835CF4971CFF5DADFD848FEDEC6546740338D690AD951C4BAB9C0EC8D09089FBA2D0A96C14F0C71B7F3F74DBC4B9DADFB85BCB100373EF2CC90988E31ADDED726053A7C644FFCFCE49D9049DC1E555338029A5BD02EA4F4997EE6CE4BF11F583DD36C119ED5A085E19CDFA52BD871A35EE47F41061CAA8216D94214D5DE89B442CC124DC1A437B75390788AA0BBCDDB83BCACD5A5521450112DB5C68D04265A177060E9B3F56FFBBA24A31A6CCBBFDC9FCF18FC38A134B3B5C64321AFE1DBF6BAE55650985DAAACB8D576DA05DA26645F65A868FAD13F6DD109476EA218D1210EB8F493200F42483813DD781F15BCFD34E53A7112DAAFAF78766FDAA5E2B0865D85EFC2D75B4989E6BB43AA80B7E440D3ED41629F2EB6EE7BCBEE799929037BCE5E20035690EA7647D9AFC9C92B7B66FFF8F3A96E8EE47D994653B1D1915386851CD5FC1EE439D796AFE173AC5024DF7DC01AECBF9898945A3EE780787126294D5C19FE0AF9270AE5B341F7133EBC70C6DC32F7CAA0D2AF1AD0E535EF2F8AD8A6F4B268D0FBABB0C7D59D9247A3753F74D6AFF359CD2DFFB4EAF9B6A9EED07345899A987E315776DF8CC4F8A0979A04878F24CF92C052319D209A28727B4D8CCE3E29D1B80CCEA9A642C3AC0EBB204F137C31E77BAEB16F5B42954CDB0DC9A338D3A3C0D6BD80B976A07E543FBD84226D75264C2E7660720F009F38C6454A14A7035992ED9DB449B8505DEC10C06FEA7B5B82151260A69276816E9AF73909D48C8F149FA80F7DFF9A48BCC508D7036D9B8671C019C6A3CBA301A26B8D5E82751566B3143E0B70FD2BABEBB62C499418FCEBE989BE2F4B3FA352AB18FCA99B760EE90EACEFF05985102FFF64F6471E4E2A9F0518C4915E1413A3048790811D1B00E20D4A97BEA7F204BE1B0C435ED2A7EA4BAA19B49C580C23965B97E26E432B2C32B3D8FEF889C4B8C9B51CAD71BA6F3AF6F5D3BC494DB4BAFC33218360BBC9DAB88DFDCE1DAED02F56530251130856B7DEF89E281DE3BA2071F69DC8A92B1BCC162FA5D8724E33952DF19FF37E36A19A0BDAAE7C77D00A6E66700C5133FE10F6567087C49252928D751608184210A08E47C1C6CA21623C9DF4483B04DBA8AB3619E2141EB4F96BC294DFEEB47DFEA6A184E7F9EF242AE87A9F3CBE0E25275D53DA8606F8B2256641B0FAE509ECDBDAA246603C28FC85BC10EAD6441B3B1CBD89D9CB805890FD01B100F664E04BC340D357E91AD2A1371F6AEEA7F5B3D6773825DB30DD3DAF328B6132DD601BE0AAC8D09A1A82633298BAB6F93F8B2C5E348E6112559B0493EAEDDA5C5D7B5BEE189A79C443F864E85A7B763571189D1CE7BEBE395E348B248D24927F6ACDAE0EE02801DCA8041CF2C7CF46D0BF91C87D6D451A0B8A4C162A7711C860EB2CA7A14C25C739860A51F1CA3875645EF23655858DAC026EFA34B76197D6F9F5D72B4D33A5D2F5E74DFB095788F5BEF387B24E1BCE481669DB471F1BAE877103A97ABFF778FC11404213DD9405DDA6195065E918EAA3709712B62FB713380B2B8F1F352F0F0F5970DB38BF4EEF392FFB0E3253A9A30022DEA9CEF6D26CFC790152BCCD35D8B44BA41F9C190D722A6619989CA39C395DD85C450DE35AB3690CF43631695542B887B1CE9D078B6C77EC8D19AA4B79E0BF32CC121FFE60661A31171785756EB78FC3D406945B7C29EA6C336E4964E4802479BB9010E5069C9E462A092175C8BB4AD68E9EDB9E5A7AC2DCF7168AFEBC344A488D4E30B98E1E52AF94FED64EF6E182CE5D05A93ED8A1C7EC49AEF3694C2334F04828575B79A7DC27CDA44022671C8BEA7FC711F1348270E499AA516A362053D5113D5B82CC02857EF6DDB159966196AB0939899008563D93AB235E0F26D2F58EFDD6840DB7851409572A4762262C07F7A9884D3BBF51BB954B1317E00BECA94E3FE7759E594023566548E1B3EB78A6B30359EBD02135767364DD4DEAEB894248EE32DADCEF0B4195586E6125C5106288FDF3695E3587811AC45499AAE58BB4D66EA6D45E01A4B67CB82167A2404AD80E782376906FB0FFC290DC81957809B6B010B1609D2EEABC7493D90F255A11F745FA11A4AC4BC597DF43F338BE194A45C746B1B43780C2101CCFB265F79033C5D99A9ADFCDC10D61C4E8F15F4F078C26F9C0AF691FEB81E0C9DF65A9BD9A80D0A342404A40341666BFC1AFC9719BFF827970007860D70819D4EB13D437BD2374B272EB3E89F5A70A49104017F566DBEDA39D66E10F33538E70DA4FE74E5F76FFD9A5304D79A32FD0511FBBC46588E424D25223AEAD0D19E2C064E1B9D5F819F4D4A590E99BAE3FD74C13EE292613E3628425EF58544B957A8ECBFBA98A7BE44F38D1D858EB784AB1AA87FA4277A8BEBC0E6C35CA3742D6AD0E8C51D65FEA5F465665C1E4DFF1DEB9E026AB2AF8A3F6E0924B93E9B24AA50AB6B85ABA222AD855A2F2E67E894107A255E814EC4D9D6559368401383002394CE45B35E7A424A20512E8C85DFD3D649383D3FBFB879955EC9FFEDED42FEB3E7B50E3ABFDE48B7641D3AC759389F558155821137E8D8A2080491A732A6685A1988C42534542CCC497427975B8199F0703294559D173CACDA428FECAB922C8BB59549F329108715AB20297494B2E598F03C3A5F321DF0627CEE36BB6AD7EC73E9BB4A411A8A2DAB91C6728D7AB99A10FEFAC498061647FFD6647E56BB18DC1DADA32E2FC3E393B4D540757A1CC7C7FB45F1D447F59A1717EB0D24AD3F02EB07408F5441B4DF02D242B9321D2E320DFB11BE59A61F1DAC02E5E30EC5B6D56E085DA3AC2AC3D8B99E98F364A29DFCFAF9D3DB83AE0A49AAEDB9171A6E7E9AC6A75CD01A282CE1D7946C64EFCA0B661AFF518D607C7CCAD878CCD90B9A6D260388BD7008B7FC4C863458FF79E2C177C7C4B287948123841765871675B3153094E647B141D22BCC87E60E830193305F8F418C20CA020C4A39FF423484843295B75993A94250B954E57C89A1CC5C8459990B9BA749CD89288F8A01FB2610491188DAE085EDC96B2AE9D6ED542A9CD43BFA6944CD95BA7098DF8173AE7AA22AD3D1B33DA0987FC3DDD93162B96569A902387C9D51E31BC5C57B7804B1A7445B4C8F53BDD39F0DB798BA28E85B80EC11E3321AF3D6EFBA268E87DCAE4F177D06C28CE3A6774CDC1D2B528D0B0AA94DA229C81C2FAD07E73036CA0AB0BC380926C53292A82216D9FF62C8FABE1FF0F1983799E6593D4338543406BC504C3EE62510ACFBFB42853B10225A73E65B1C36F31B56EFA25E1AD2C12DD52D5E27FC59D5AE56DA56E30CEF273C44741005662A6264E34DA614957BEB02DE0832AC7755966A784C867E9BD668FC0338D905D5A03607D9D67C92C44DFBDC59F1BA75EB2A741E79E6A59C313C3B5FDF6A61905844F4997D1DD6EC7310511DE9B8BAD636476764C8324ACA39B425B0C2EFA2156AE59414C8F1BD528E3D50C3B0DE5057ECFD4F8180CC76EC58BC8A3B706429C4D301FC3A0FA6D486C9E7303E1EA386C3EF9614EBB376176720A3BB9C77873ABF7C6F6637A240ED00E903F898339690145902C2AB24A5333A399E7AFDA7BE8AC18064D5AEB7DFC6B1413991E7B051069AA1635B0249BA23511D1E1768F12F3A7AEAA8E939313177B4040B6648F6515850076C2CE239756A699E06E02E94CABDA781873809A10D07CE459477B424C157FE4CAB33AED7BC0223B28B4738FFBD487BBF8A0A4E4FA5FC3B1B049E3B981DF5E53EDFEBDC467C328BD588AF9D4922D2E4CF10D119A796DD3888792B0A48D8AB6228905AD1A1188C91A4B1E42DDE84B4460EE614447F1D7699B18DF5D20DD73DBAB58E21FE68E1CAE35551371D2F8FC57D4C38E1859261F04A8EC3B26CFCE1E2DBCF14BCA401017FEF6CA6A66F68055C64F9F1B3EFB20CCE723223FFE7D1378AFBC1A0228CF3BF6E0028949261D4226E8DAA84A386DDA37CF2A1B0647001A784FF087A92D79207E89D7890932FFF6F239693008F553692765377B594DC5CE690BBC391D1F7B9028E3AD9DA1953F7F4A7358DC05692634790D9724CD92142C17791E48A23A7A5B057EA92F29CC76BE8A051D7D69ED4787546E63876A711EC202D75A1853C97457F0C2B94CE07AA2EC94F1A5DC5426F37191721226926B1DBECB89A9DCB91BB03FD171945D5ED8F9668505E2783FDA5BACA4132413F955C985200825D9E127E28779D5A6BFC39784C5861B7C6BE03DC6E1638AF49B932A15882167F4E39E7F820161D2A606BBBF37A8AEC73E1EDDFAED14FBB4596329445A2FEC527F0B30338CB42A5A56CD42B295BCFE2DEFED49F1EA906335271B33AC5BB89FF8C9417C35C69EB48800C88B404A12DF8D1F850CEA28A5A3EB3106C2314C2B12E21D9CD5653A1DA2ECD772978E8BA43BF95C7FD77E9AAD959EB6B643798B9BFA984716F4860C2BFCE6F3A797BE345AA184705DCD46B369F90222D19136F4A6847F30DBE92D28AC4729C68AD883AFC87047FD3810100B2B6430342D324345B371DC3B4786B4A29ECC806DD872279A2D2F5524D6FA6682BFB6B7808BCBF53CA4F238B272B0DF1DA52EE7AE92DFB1E2E4BBF0126EF837EC245EFC169459C1767B233D8A551C462D41B41D1EE69AD1ABDD4BDA4D32605FD28C8DCEC8EE10D1B23DCE49647B8F2ECEF93282CECAB479F317DA37661C0F34B497B91983DB4F6FC472E7D3509DF98604B1E64C7724E78B9601AA185DE554AA111EE75E0193E0B545B9A7A6565A8B9D30382CCAB61053ABE5BABD648095297C293E3DDC3B29CE217CAC6CDAC0DD4643762ABD87518DE84EFB1287DFC56D51B2947883ACADF1C7EDBF7E48AE6F5EBE7D9A72C1E257CDE4BCEADBDE03078DAFC54ADC398F4AD0C6381D0545463AC32AC9159F5D6522AC8EDDF7DE8D6429E4E304C473618A27D40CE7E7E48ED69BEC8B684FF7E7FA826438AC56615347C8AE2C9BDBD122C62B6AC10D89EFD95B48E53F4B1646124670CEE5F7399CF4F8D186D7B14FD7BBCB37A1AE624E58B9786B72495B5A24DE906F6C6397AC6A67D9DD1F56335834DD9230897FF4E681B2E4568251A166D20837BA2FF62D69FC44A79694E4013D0FFABD23A02D525C98C06589CD93E1020E6EC110934342F1F1326DEBCC8DB6E74CA1EA7353AFD59328CB0D72E81E9C6A2074244BDB4DEEFA6E10C375B07B2796434DA869FE117622BA9C5E823DB102C4B82E66F413FA34E51BD884D9C2902F775D3B23EAE35488976838460032FAD2F2EA9605EFF274D177388BBE76A8EE6B009C818D00A3ED5ACE0E5968F5616D70CA5F3DC82D90CC08DA4BD7D83E1286E0D12DB77DA3C52230B2C3A6ABFB5F2D4F00C9C0FD99CF98B81A355222D4A02E64AA54C812B07E4A9B4CD787C658D63E2C7EBC786C873145994067EBFE606F084A8A0F72397B9C0B8926582EDF68D92FF633B291DCEAA8742C9E33BEBC0770E37BA6F09F88DC61EF10995304FB5DD3DCFF23E37F53EAAF3B19984EAB5ABC94EC3B438CA345C853E9A3068C8C15C20C7B399E6B40E3BC36F84A3657ECB614E59D1578C707C90D7B5A74D72B8AE2F961717504B04059BA55024B55B0B122C8B0CE916F758743717FF9EEB4FB48BE825E0AF78AB576D3870C9AF01A7949076A0F701FDA1D30F468FC2A7B93D75645551CC4AEB82B2248D0A8BEA079E03F9BFB9DB61B409DDB56FCC312ACFE478C35BD14E05A154495101AB0ADB5643DB77BA918B3100D135A3566E9E35D3B4D097E5E12DE315BE8B4BEBDB32EAAC33230E0205DF9F7C5DA589B463C32D9F352D3396B70E7A51DE7C9A30088FA55AEA071A9B3E6B01E8664FF45C7FC19258BC537A818CD5B44DBF4C6D06C705CB52020876F61CE9F3B0AFC06B6C5C3A9E4B836136D3E1A76261FE3685321BB0A8D2BB51971D0D16BAF2275C29EF37B284447E88B770D787A39925830DD7DC1B0CD8AFA21EE17F1CD33BD20E5B844088E50B0D614D27895875DA32163AE1528D0183E169781CBE92A6CCB040C94C61D5AF60645F64DD9EED4228BFDC7325E9847C9B5BBD5AF0E94A6B723FEC15CB8034B7A63C2465CF295C403B5A61662905E6B9C60C4A81187BEC84CA2E8D3ADF299C892606790BA24A89E6DCD6D6DC6D149A0079CC3F680A5ABD1F48C6AF580F39171137CE7BC4055F85057454DBD69B344B7A879D73F63AD458A1CA7E6B284FFD3BB8AC7111B88E219EEDC2793C62FB879EB4EFFF554AF1C48248860AE5A34D487EB0B7D75E39E83A79DDE865BABD1CDEABB022B970CEAEF28F0AABFAF208FE86527D375841A737C16D5FCD043D80CF2E427912E42AA0C6B609F97E95FB569A47E125E68AEB5F58BE944D593685B7EC0DA0A6518C50DFAB380723B89A65CC0EC79653BC298E6FD4940662C4D5D9CD", + "rnd": "CE94E2121CF82C17F6D50FB575796DFC8AA8070A85839687A18B7DA4C68F2DA6", + "signature": "F04427816929E46976493FBB40085EC46FE0C543176193FB2AE8AEF24ED1C7E03A6B685C7BB038F71D8581653A0ADF0D0945CF2C02958F162D339029F9E56A11B4C89799F3A3D18CB7F580125FC4EF62395FB0B8268000C3472CE19C93E7EC24AADAC9BE4CA0D121E0B2438F15BA0868C2DDB17D3FBF49616E64DF6DC09A67483EB37954E0B307BF6EC092A83093D360734E98C00AAE8023887A4873FD575F22F935EA143A0536A9F2CD5979F667CE06AFAD2FA3C20F51E88F40F6AAE1EAF1A464777C653E3E2157D84D59FFE0A4DAB9F2A613CEFE0C2327CEADF3676D0B5FBCB022B9AB1B48934398464CA65270301B9DC0F4CAA8FFFB21238F49BE0C29E42592B36BE9EEC2B54031BCC53744EF077EAB0E163D262DC06D808E21A1039F0B9A11D533183D11174AE630006F6CBDA1CF67A97E36A5BAA3D8578514F5C87947E5B4B785A1F140439DEDB3653C9A20C4182B76561B6F0B06BD41AAD10A3A8B6FC3DCD7F78662ABB1836FAC4C75137113DE0E23E04B19AADA03728A420FFC77474D9798EAE2C8152D62FF959CD9AAEE2BC1B45476519351DD0B0E46CB55A4B294BC23615C1172C4FEDC5CEA8D56FBA40A67AB5A64694F9B9DC0E35E51C0335132295EFCBF10C4D20881FCED973803071B78DD3BB8F6E89BB481473EDC614B526350563FA3761E3B4D6F60C8D0AD1ECC6311F333F4EE9AF7F281F7F2D6BCA29628FEF039CCC29A152388153E6BCAECBD67E524EA48F3A8374F36BEA4E7E01E45F251EFC21FC41B1F8A111E5A14D180B3CBB4FF2DE7BE12D4CC0EE7D92124CCC694B3B02583180FCC449CB557653E9086A4E0B3ECFCC11DA2673BF0FC6F23CE2336F8277237FD9C7B6F6C82D24724EE80149DC60DBC85768553C581A856FAE2632ED9DCC9EE1E446211C45C8010BD0EFFF89877FE1DA6B1F2180A2389299DC75C61F52E86FF9C545681BA8581880F0B815EB3A627ED97F4B897B88D6928DF9D6456561335A02FD93C246387343E8AF02DF6C9D94F3D5A7CE92CC0F3F722C4F4DB1C274CA96EED6D88B16FAD7A01B64F1EA9B6338F844BF4F4EF85286BA0F63B5C2E2B0BF9D815F802D83CF7884A695325724A2B97500E049A6A19D5CA691DF339B0C8045B86B89F8CB24967F56B8C59EED7E28CAD5A3120418620F1E193294393E012458A4D57653A4A19FE4582528725CB0D30E48700CD2035E2B166AE521A9F2E729444CC4432345E6CF542055AF999D2402901BE8324C81CF16FC0FD2A2FEDBBA387B09178FE1F65A28B04FC0C87795AC94F3691E9F461742B71B122EFE83DC8F0BB03B5163D0145D4B298E1CC544319EF11D6BC15B085E1152C381E446C8F0753D11C92F064E1CFA292AC4FE923D4190B0D02C25577DC483D2A133683D85394231A6F9775F1C80CC356E1E8923E4F5E1A22E4C3D57B0007BC150023E04C754A867A5370324457784331EF8F2CDE3D955936B9661D483C7BFAB0CE946AC6170110D36FA4AAA6D2ACD7B4FBC2566582BAABB85C1323B9F69B3E3167BD086E7725B00C0F83857E2A328B75B25EA056149FA0C9C3B60B2F70F2F8E765DF45D0C49E951E42E11099EF572EEABC78ABDED2A8DDABED09E0DC222C3AFC11CBC57AAB2F47653FF371A1D255EDE5B1B16140C893C67995D5DC031FEF39FC5F7AC718B4F3BE4DFFD1B5261A1CD9B3A823513518A8FBCC7181226157475FDED57C1E4E323B898673B3D58265C982DA36B49463DE0EE4BF7E657D41F1B3E1AE7881E93BA7676DEBE3A8A394D5ED997E9116BA564A340233C8F0E3CFC31C5B19B47D4971B02D5C570351D1D50391A312F706FF21414BE3BCEC519FE8B678FAE02013677DC6B3DCF873406598BA7916FF90EFD816280B30DE43AFCFE845363C0094F60B4273C5CDE86AB29EB3EC52224EF4BCA5420FC288CAE4BFA4F0037BD403146304359730B6505B45AA99E724BCF1C0790D12A68FD34BA081FDFF18D8A034CB009CD23812BDD7000DC28BA7DF884F93D106AA74A7CD76ADB887B88B691D561D744305AA90684582B4F2C409B88DEC8F17424A85DDED0552BAD8D0EADC3C1543FC74552F2ABC81797314638A9AA63B70620E5D199732C02745658191E84662A9179F5EC54F829A20A214AB6E82FC550D5DB5CC6293C771751A3A79844D9E374D1FE88C9C1CF1917CE91D7E51FE0D1B6F91CC58C81579AF70B33CEC87BAA150CED7BAB34A2A30DE9AA380D3BC5C5DCDA6C08FA7D024A46FE83D1750E2EF108A823A058147AD3F08AE7C42EAEACD99D2760DD9A1EEB5F9F02F585668A0B170EA05F002D5A1DBA805657AB7F9C1B8AC6658A250417872830C79EBE65BA25DBCF872B370B589CD65D7B29B1775E1F20B757997F0ACF8336250FAA93D5B3A045C2D2D7202FC9A9A8B2E53F27DFBFDBB0281D5FA7EC24D31F88380867A6614215D12BD4D095B44019EC2B85253691D6FE38E9FA0AC6FAB58F372BF12158FBA322D0AB42FFA41084290AA765773D36047D00333ED9DE163E0233EDDC92562AC59800DAE6E08C93DC1DA54B8C8AAAFABF673D7045B3E31191D6B48B77626FE9D1267A94069B59EB5088E5FB913DA6AC08A370C07A6D33C1D36DFDB9321D771BA01B597992C02F3270C7B7F9E4F709485A6473061C70D63EC08AB9E972D4377BF43659565A0E3AFEB111ED5C3D73F745D7ACCFCE1AE9B0C4F913BF9D12AF2BFD9A2F13BFD8E350D6784E9FEB4747D6087F7BFEE63C826358BF7F1047DBC4F0C4F282801942C4415B05258F0947EE19AEB8F69E39DFE1D613C6B66B860C8D47B18A9E82F10D60506B3AF821244AA255D83EECA75485434F02FC4D950B118B01769B1861A9A0AB9AFAB49974FCBEE56413758065414E8C8F370C406353B6FB4F1B2AF55AC83C330166BA59C9386B5481FDC9FED546CBAE2941B02CAABA62E572AD4E131D8BA39D1B9541E4766BB8EFED6B6FF0E09DBBFBF02D490ACE4D423AEEC4597A52BAE780C19215B57467B50D6268C3BF8D24F08F205C1265A2627252C5F57088A706BFBCDC4519FFE9B16ECD2594D0ED2380741E6BA70D8B13ACFF0F439A773260C817031709CB0CB7A1180454987884F73A30374A7FFAA062B11B3A6245CCAF114010240E1D0FB268BCB80AEC821FBE4643FBCA1386CD51128CD2D679D2EA5CE1D25741849E68C7B379EBEE5F157AEA1115DD92522497D718CE9E53339F37A95E6855390F1D29D73387236F6FCC5ECF85E90EC3FD24F9542BE8783ACD7B57EA5720DBC247450AC437D3EB426B43DCB4F48C95F1304308C07329D098CC6BABC59B91C724E4805204A0F112457E7300AD7CB67BDD857F3AEC1DACF123D903405A61C8AAE90002F7C6FC2882DC0E4186C6BB3397C48F7B798D863A74F3875E442DB517DA3F411059E4F48931FE0952687BCE338000FD878A86E0DF10558E8E7A337CB9E84FFC02F611A9E34C0592241A322805AAF95F6EEF5C862F5FDFD631D190D0A34F0523218801A2E3E6E00F69F9A9C7A023E441EB03495FE1C2F2BBD24A8BD77EBC81456991952BB759B41C8F8EE839AB7C19AD860E9B4C662B64A25A54AC5EC46ACE968BFA4A09AFE586EA6BFFAEBB0FBD0C38090C787D7CC64A1CFBD09CDF59E162CBDA6734CF894954A470DC6E2751AF1A2D59C9B0B5E81819C86FCC4DE401D6021B382860F302284D5CA764972F3A06F7213EB814D352353D0792E96002A0565ECBCE3BE278192A4CE889FD413BFC3C25BF89C8E652A7B4BAA2D5708E3C285693E371D35B6B91E87D776E87D8353D90070711CCCB80486A07EBCE3888A07FC6B64E85DD9FEC55E930D3E75E60F58C8CC479851698D7FECAA8A9D41C010F5235B794FC232B860B9E1102EB0BF7B26E40F0B385B3227B81B1932E77DE9F3513A42D56E6E43D74A9D88DB50419FE1257B865F8CFE2BBA67CA84A59A4413A119CD326798F754D96B5F349E851F25693B29F297749615FCB4BAA0B92E439FFC68C7459822448667AFFB077201D8A698551A0FBC54F432D5574B64D6D2582FED442E39EB8CB7782B815466BD0AC1778B78B96CAED56602D834EA5273C1FF41631140FDC0AE35C30428813E74415D3F11D551D796780B8727E25687FA5C7BC43E1B0734721C2E8C03B9510249AB140A1AE77658645C1872EAEBBFEAFA86816A5018E2D1E80154BA4A0BC0921D5DBCA32870A8AF1190884A88C9373E151DD2CDD4825BBB6F1F61D494403689B87BCEBE92DB32965E4ACC610EA87850111B5262D945B5EE5C71C34C23515E445BB55832464B4F7118CAE3389BFEA314F4E47BC94DE93CE3FC354714097DF82A193866C5A66066F9D5B14DB26DCDFFD86B3FB67FC8A199724FE18F91328777F76463D1F93923F73CE2648282F2E1F236444C2A3B73EFFC29694DBE3CB28A3F183ECA714C29E85ACB35AB0DD478E581928AC3CC1EB65D5F49667A9D9BBA0B3ABB5D3FA046744643FD9D1B8E1EB1E7C062B394675654A1FE42B82492A089F30748048C3E0DF7DACAEBF95CD4D98882C91F6882C36C9E459962962FCA4B31465B6AF0AB6D97E5896F2E66D553AE9838BE152AF5DA4191E4960548E1C9D027C5D55D03F0A71CC5652D8C9AAE01196B011C2E334A7895A9C9424F55588EFEFF02223B6D72CDD30F3C4B6B96AFBBE2586D7D82959609181B344269717679D2FE000000000000000910171F2530" + }, + { + "tcId": 36, + "deferred": false, + "sk": "4C9C0B3462F8CD8E3D50117937B34A0F5B53D764FEECF4E318DB26417D0EE37E74D716BA37492557E9C7ED7A1527A441275F8F0F41C2F42A45EE7E621A0B5DDDF344E7F62C64E8BD19D8F9A90F33ABE2B6F838112C4F03B29A29A675418F1422561C07CDCCAFABC3A9AE362290B977292E15CD20DE856604A9AC6F6B31F607DF63714655458467444561266141472500520485522481048732358760657113161827474281068181564576512354452008102656877300242027487145266532423335122840154134185262623737324065381854374182615541621005053683573708528363557333253402356853835446527180775340833370247860722575064281822175631505345077204461474383685103476702113527056154155543713015151524686372714388603047568751442038506806054761854572400484848724568428113736062614111803556452364603074021646138227154278458021701736414710453662857508416636701808462628083687348006006743311187066057812376803381858163872268558423157284517867241054805370263847180662113222804302730048331043876800133561770110418620460445578647658344830875125006131327683000831130144074062568026783187205043264765777266664254403613847570154541142542373824771137668170742317132176085120766848366375652744454778727738682442604652416014861416713550055225040114421566321312557400251543546488705840256326635118752217244235487200080441887217514325350263384677788640616170351007445782528057580607506484537062533844115406538055883564081118353860271478083465256650444481468183523024301787565647661386728731243222466566177231476444128207458206634686845784445558307786564825568110867337816412187555304126306411343383088062377701740618438863408158885676217683108252670254155453342385158237116740672811248766806166232345863617552115564282022350208570775151353083880116481565214233673614270174263110463681326860003084103465502620423575327515528644086817075042376118334346512167726255867863456070533226665654150354527525143605776205124404468375123401431722742070161373465055421772501584878070827272117876580342254405060653360043688736426537437841022343020350303683672818331536887468142164777610374705554221388170086363442714571212528680766236703828574082705324570848366604765672711154223633200558463468241638854655764135502826441101747700207125870273273028832571656557315104312474667218277726484517610542728703525604466748383056881005551381083766432572038885887278400103054412360764716684305602046730457512147841221363462473412804067001513320745821735142140230403051068446566061766381218713655568847558051568184413586072821815486858012638221574837236180754278047660177782405357858381055383056234614415427653473443068583012611773142158467213431113545512057132760240758261527344460863285764546151334315432263545367700355176184421676366444683550353546838071437364443005384514428870261466008231503178843031543172600072805840526168532651386325425774702621672736880075202500338546647263666482835540855821776615537527804030556822868477215344541612202551311150788526824138547082026658838402857373812726147256150525865124720830678106258521136415154214104771817271716320431816261788720730056458610682663867625540720757246008137463272574363848874012064817848647203350144263605515551023610652710564526364001288712544072865678840304622B0733BBA616D7D5AD1E1A6D9C95E96D85A9368E9F7A4DD68461B62CBB2A339BE4AE3780EC3C2D2E3A004933646265273C66E2CAFB97A740F6FE7F4C77D65D8BE9F8ACAC1980850ACED4896D3160C48D0431DCFC73BE8BBE189F4A5418F92F4DEBF397CA654EA0D2DBEBE8FE3F53FE8FA50B3A08DB064C4C75E6D4A9F910CBFE2C7A096D09BB85B83E0BCEBB24730A5AC9E7673AFE0BC249411510083EA9B2670596ED9F211CABD3094799DB50CF6C964B6C21AE8829237F4E7032CC24F5C256BE473953670A6E6AE40BB8D014FD5D39CA9AF3AA6DB4B1417DD0250F116BC1D0D215BB63C92A7AACF10E872C99EA49FED9E7E0BBDB9A092CB6F9AFA3221C4BD1C21F9ED1902882F9BA2CBBC203ED4CB74150F179E0F17315949152AAE495F2FA99D2989E4039B68F01869CEADDE531464BDA43C63C43C256553D8362480BA056FBD2630A6C6459A6FD75920B4B58D8252F1AF8899E7E7FA73498658BB91D1C3FADE44E0DA39ED266C1F07EA05C3325607F63F52E06AC710753E2C1D698969B950A6FF864412AABAD169D4F5806DA10D15E9F831B4E1855ACCFFBCC3A05BFDD48EEC333EBCE7A63720C1A4875A74B17FA1744290C88FCA56560293B9B6413A973B3A2AEC483627D52B728CC7077FB1478B5F248A9007D1641089583AB28171D03B80D679FB050A882AA3CB87FEEE2E7E13EA4BBC1BA8E86B55B31D1EFF6502C640B1F3C30CDC2B444976230A0BBCA65F09249D6FB61A8B566375E82F9B981697DEBDD985E51DA77337BD91FC4199339A6D4EAFBF32548F03064553B399EA41B58A9660B9498A00F8AEF6471831D5DA93A02DCE2E5BB48D3195B3CC6C5F69817FB7FC20BED1A7E3C5DB80F7DC9FAA4D206F01AACAD5687B9DB01F9361F78A7E7DBBD45E657F57F67C6AAE06B58086F4E4A56CCCFF068694784BBA8F53EDB6EF8BD230CA06284BC9393F1B95EFB2C2E33BDCDA7192BE15823EC3F2DEC8CE95C514DCB51815D511BA4EFE5A78588DFB0601C5699972FF1148FC49E07AFCE96404A41AB478F1002834D6B173F339655E5DA4FCEAC1D53E302D2988FE1C3738017E7CF9FB6D2C546E813D874313F1B4AA132F24B9E47396470459C1C8FB0C526A0B614E3DD115045642BF3D93058B3AA53AD70C58725DDD2757ED7E53B77E69B09F5E2324818FB87BCA4A6C6A184B29E5049F3AF4CE47F328B7225AA47A96BC3F8F36846B916F2B940091940266F479ADA30E91B088AAA54F12E704D68E0E18B3C0DFA2F5BFFF816CEB2674EC6B1F73F07D818C5757C4010E247EE2E4536BB964BE5E3A936167152DF4568C30226B8E23FBE1777570FB95D4D5126433D91ACE47BD80F0D50F7591414C7D2DB7B43D794A81F54D7EE340C1ED628DC841DDC5003FD5B4577D33DB02E20423EA59CCC88D35655E28A952197BC4D6A6584EFCFD2594097716EFC9A9E37BE43FCFD66D7D4428BDD3D998A76590327207CB391271459678C7E2D90AB7DD43CA349F47AEA46B659FB762148102D871F9634D3B2AEEEC130890C42130A6C37BC4D7C0D3D71A4E56C915A500B54B8257D0BF45CB6EDCF4B91E2A78A9C72B071EAC33B5CE3059162D456D8F2595B9BE25905705ECAC733ACC9A2076EEFA113FA710609211D22416566D10CDD2993CDA1C888B32850738C8AAE0454C2C7685FDF5444F93442EE198975BAB0780ED2E38A5DC930FC1F7ED64691F246D29FFA32C5B1C6D0EA5E45002E9E3BDF3870FBC65F0A6F2F231F79C1441C1399AB35BEE1C948ECDF8038E045B87958624BC8CC5DE5CE8B5255BC9849563BC3670BBD880010D6E11DD02B5FD4E92CD38CA62083732F80DB497F2CC62DC6F63D19CFD9B59EA47ED15C49888EA5BEEA690369806D48D7FABF14CF5B166D374136FC314CB41F48DD75E8E54207ECCCA8BC8C3A8375A6EEFF7E0449561CDB2D455195ADC56EA7C0CEC2D3D979846574ED60FC2F8B802DD43E15F9EC2B70453051F0CEE47302EDFE72C9FB4B4C9C365B672CC4D600A61150E244FBCD054DAFB8A8AC8C8696A02A5E765A26E67249997792773EE58128342FAC7C28CE5CAAE1CC84299AA25E43700AC675F45FB765D024A4CC5937DCA5D2DB84861E9913C0DE96865ECF5D06EFEA667889CD52C449E67C88B78208C7ECAD4A94469852011FCB0CB6E842224130ED67838CC461E9530B09CC7C257D08A9A432B084C16D3863DFE31E03CACBC699EBFB1C135C0902881758E41E2F3E4F9A590911E1C3FA6468EA1464896121418643602ED8A93EFF6AACB8D27FA0B528714A9E62419D4347E6F5E6864B3298AD82207BDC32923F5B73B24BB26B8493D57966A7562B14FC82BAF9145A37DBF2AA0A2605034B268EDD25E10C74AFC7FBE86231032D1548686942C0B77A1649DA90B98EBC4B02E81FF43C07FAC77A4392E2D36A6A45776ED617C85C728BDAACB7C09A0C7FE04AA64FEA26AD5F88F7FD44E5AF23AB787A2D4F1EB63BE344253CD556E4E62251DAC0B16F825108F9051C37373A92962A4C7C6C963218F2DB69ACB6C0E168CEA66C453B9E36C337A9CF587D8A390448B38C0ED7467DEBC3B85ED07C59E6D546F614C1286C17F073760C5D46628A2BDCFA558F8995A1CD91586F5B50A7BCF75E09DE0A4D11A6BCDC62D5AE2E49906FBBD06739A6A9BD57D065971F4B94E1DFBF69099543212435FFD80F41277D065CBEADF4C7FC3834E0F6185F6AEF552849121734EECA8E89A77F21CBB5A737C68BEEF0C715C98F00131445A602265FEB3E9EFD9339D4BE800541AEE549B0090D44693D587DF5887942BF8F6B54B2B261E16E5A4E3EE5F5FC984FDA7E7F00F0B0B7FCF10AE19850B455A0431110D136B106951073D1C1F9FE1E869903C377D4B3C4EFD3D6013EE9EC9DFD79B7B2A17D18B1F6926F3AB598F01EBD3FE2021C62D6004E5ADDAD874E94D5C2929F90AAEE6B9DF07B5EF869B6A2C4B764CF6EB63995AE6D2FB46EB4E74A12672D73FD52ABEEE4C4CB0665280C4BA18283145C329F09D13FA223A208B5C1840306C59E61EBA6991457784A93A207477E2E060823D4455C2852B644F23386E593DA5639753155E3196EBB55003C42D79FF762F3B36D127E37B565B3FDDAF4586D0B53FD25D6B6CC6AE834B51818DC52F252513506D5CF74FA279362BBEB250D2002299EE160A937337CE0715B8BB82F8CF44BF7C90F744E935DE6EA054AADDA647C6D6F4D4D4300730B94C65546FF079A1636FD369AE09880C126517F58F58A1915DB9C260CE2C4E48A3EBCDE52BDE1D64FCFAB3BC89E65643D916A6A26736BFDC410C33E8B5923E7094AB98A62BA305E35A78B227951B806045B1C401369AC8006D77C5402E1738707218C385B8BF0358601FFD09A1CB3F0294DC8BA0C7A548948D6127919325B8B49CDAE0473FA89C211CCDB2D062E1634933A4B25E72E75236CD38A9E99FADDC594DDF9725EBD3D04F93D49B68814B85AF820B733F45106C4D99579EDC6B527FB8C791E476B76AF0F00609D3C2D97A8E9141B2C8AB7E8E5959", + "message": "E5B0471D62EE751F73E4AEA9533E3A792885AE91B975013162B6FB0F099E2186952E693682AEAFC7FBF383124A74F3D330D37ABAD5C7824FE7CACB11B57013F6F6F81E46116A4CA23F83593CC4E8FC2EC7B0801D94187FB4757BA1CF51EE4A543048FB46A2BB84B0F00FD3547CF8CB88991D00FFC5433EF23FC102961B3DB112D7D5348F70954BC8B04560D30BBE757811BC0C0301212A64D86CDCEE8334F650E2DE12F171DC44A6200121EFA8165F1BAF86CA118E94F0EAC6A56CB53C6CC9D13408EA6ADA24FFDCCD9A98F20BF00A4421185A4D052A59CD49ED1570B81141B9F32DE0B35B813409D4D03CE76239D7DC1625C67D25BDFE14BB45EB0E2DD3AC0982FA2CE3CD2169E8957F0A033F151334FC4343641BC3B31F10ADD4C569CA88DED47CFD756ED3205A8AE241D8DC0EC2900B55D9B6B280867F709AB7ED7BF3CBD658E71202A51E8AD5FAF6E5A14324BAC79B4FB935A1E1C6E67EA294F8A81A506F8484FD97D65DDFC48A7A977867042204936008CB634F5B557FE95F85E2144F926E4CA665294E27A31B1C84FC3645D0DE27770DF8ACBFBB2AEA26E5FE01FAE00F77CEBD37E24A7CA158B58A1E79467B64E7617FC324C6602C8389B0A5EF8058A53BFE42B2AAB73FA73A31BF0DEB3FB39ACCD57E59A01B0DBA8167EE22F1B7D317C2765E2DE0483A65BA20DE3180E19472ABA15CC3981A1C992B23FAE41DFAC8196340EE80B15F3C28981674BDB439DD7B4C0B1CB9D03757B1F6108C1C70D37C2FDD936A5E5DE17EC85B2DFAEFCC13A9B7406BB7992AA5ADCE9E4C6130279756920640D05EF11DE704A5475F7D05F6FD5740B3B4C7668270AEF15C7B44E5230FBBABFFE5C96BE96BF4321D1C9A539E2A1A91465337520192EC0A3B475C121A21C2E1B31C30108E9E93EA07C8F86F7AE938B88E5E06E5F16EC830F658097D56FCFB168B153DD7E3A8F04D3928C1C9C3E26244C4B30E15384DF6F0F413B97FEBCD13C892BC51DD2EFD6C9D743E33E85FBC44AFD7F44A69C58ED2DDF26BD54F46648B6D10208607923A390F1DD4A30A2BE95CCA63FFE4773B23E919C3E418680D897118495FD2BB86A8AEBB6C868DAEA895C10BD3E2D9B87DD5CCE2DC0DAF41F6A595AA824CA0EDF530AC3CB7614C0806C52772250F0DA234F464E94CC7EB33E4661DB88E9474CF08E61AE1850DACE1BE19AAC74194A7135E243FF61BA9D41012314A64420B22B08D6807CC236CC673EB809221D8FE652FCA60C3B045013810B33E4E4C819861513B82C6A6C3727321D484F853B9884E607DCBFCA45C5D33530FCB3E968D9BF8E4D34CA9265EE3FAC704200D785447DBF2D5DBE7797C359EE4A82489BE397841E2FD4D9B947A233C654579DAFA42DC779889780FCF7DF5316FE1244A9A484040DF1B5054CCE0656BE4AB646EADA47F09F3BFD1FE7A575D3251197BFAE608E8C9B3267F7A4BCF366A88F3672DB0464AEADB0A528212F3675E959B23034AED5F4BD814B5F88F5A134541E3F2E2B5F2CE751DC5E84553C0DE691F0ED55E14784E7BD61C207EBB67B0C34FA643F15D866C6AFA377C98693568F893715F3F1D62EB85D45069225DC8AD995E517BBCB971DA7F4EF3C1FFFE23CB403F7D4668010E14CA62FD633805BA5DBC377ABB3576A776D9DA614E322D4E8338886FDDBB84E4141A87F164304BB5E09C25EF4D815B54B01C39CB4D15289BBBC62DAEEDE65783AB85FC178926C4AFA5287677CEE914B0E77655343F306A1031101729E0F1DD5613F4D8623242CA055178FBB8265AACD3F00DA0CB3C6B7883E82E59542B1628A1E09DD17BBC05BE874192A0B7B3533F8A6543400893BEF3E5709468F0C90C98F130AF0B66E41216301533893050E918501F2361C4085851EC03B58ED235D4BBCBC3F0A1CBA35FADC7074960E4AAF79AFF679DC585D85BE2D17BAFC592D91E7976183427EBE87FEEE4A83920EB2ACC9BC94868F1AF4BD4FFEBDB894B9244550027348AB145C0E267584D1059D746BD5BC7410AE8DA46AD01CA79E8CE50D83BF5011166A88594DDD33043375C4C9E79D3A9DA23CE3957128EDC1045239313AA90A95CF751196636EB0F443FEDD58A110F9D7BE1FB68E551F962800FBB7FED176F300CE65EAD164E8AD58CB38B51740FEBCCC510AB83DB9C90BAA56768F10B77C3CF9162E475DED5AD2764D605760C9ECAE900C7F7B0E70192F15C3C82C476EEAC912A98F03FF9EC93BCC192846D8EEDF7282CDEDFB809ED6881A1DE6271916EB9E844936404C7F6C8E07F009E4F8234D0BFAE14322FD6F1258E9CB736C2CC13BC5FE206A25EADA53C5F0EB6A92E7C0538D8A02E854DCE9CEEE6F211A90356D796292F1B55BB0C70EE346201CBC5D718A046BB8C99633DEB7B37C1AECF9BD99E60DA7C81471C4CF3643992C23949D3B095C1AD83A2B6B113AA7637A1AF71AA80F69B4B9F766DDA4DCA5D434A76E762B3D97020791CD03AAB79F3EE21691751A88409AA9BFCAD21B53BC954DC622B069997A1B800192E8AA137484C982215161F39A5767D81FA55917139A8A67271F4C68B113780368B4EFA862B95513F92EFE36FC64E56F291AACF22EE8B672911CDCD9A8B2B11F986E587FC680E2BC97780FCA1D1B73F3F8E52B62230061B134A6395575FC9BF8F90B527068DE44447CDFF290A9EB28DA7242C634BBAA2AFADEC15E1AD56F8C9A08B9B535F5E646BF19E70C5E0B408282B11EC5028694B2AE414866AF8D6E2B892E0DD12C6DE9E937454CD96E586C434560EB7900F8BA97D9E6132FDF2D8C0BE34554CA4E85E36E3A1FCDBD1E7E98C16127843B994170EDE84C571FDC13F905025B480719DD6AC99C74BA81E6A2D430F5FF33D8228E672B5C7E97A95F8FE2E491A46FF2BF9EC0A4FFB6C9F07CCD5C8FF5B6AFBF089AA9625DF795DA725A806665274F4332D9F795BE3C62DBF0B522E2591A03DFE6481BE0E792CCA7247EE16292BAA5AFBFB5AA09868607147B90F52AAECA5963CD13111AD70EF8DCD37E2BC550EE7CE5DFD1ACA27DC0F30762E2EFE07FA025504432410FA085716C5827DA898D7A076B7174CAC41A9D960E22B190486B4104AE07B93F6859FE5AAAA5C74013DF15C8F33B5B31845E2D09739A9AFE0B201723984BA99F466D32C6A2F928F1241130A910CCC06F9EE95057970FACAB109143D396EB5154783685B39AEA1AD4B5C4092035BB9F5EF3BE0EF99021C5DC20DDA0CDCDDEB53D317654B01BB41DADD2E0796CDBDD78C16F11B25C1892CACCE6A177B887FDB52F30E4FDBE7CFE60A60A278C6AEEBC7DA88638BB830DF6123F24C1BE8C6A27C56F4B681959760F0A2A94B0423AC1FF9E952DD1D05D5D00874A4E73BD7728F5665C525E5A8D41AB8A56861883953050A2E248D771C07417BD95E56AF4F06580331855829B74D1D76CAFA244651AA67CA5436423075C1DBBDEEDD32C54BE4B2CAAFB233A11E594171540239F8C530580C24A19402D008B565267783F8BE727903F3E977AAB78B6CE83913382B26013571D5F138C4E7A6B3265CEA2C8B417A848D2D5FFAFAA12EFE5C667BA8842E12505302C57343FFA662EDE319D9B5E8D263E198673D765538364935386B4A93973F36A0155EA55C1CF46BD64F32D8773394D1C53C1C6E48F068616ACF60F412383C16F151E97DA4291DB4D68667BE99A118952C7D83D0AE31878A9302CE79D1CBF23D0DCB7990C8C14F480CCB9FD07BFC63394932BF04764AE26BE1B23FF4712A7F7657E2BAFDDA61C7EC82F91A909C683CD2F740A45141491FC7C854F190AED141275B3C39B7CE5B79ED83004D9511AABFD242EDC5B351DBB2909A8858534E4BEDCF8F2C3B5C3B7FBFBDF3F52DF3D9B95021A73FDB9BA1D153969975368E186CE2B0F4274F61CC67121D886784A4724C05D01770C031FCE2F7DF8E07C44E9C4824789A9F40DF8A67916871D77D98B0E19E5DC3D3D73CE57D503506DAC95DCF83F506FF348610AAC9A4EEACA5AE4C17FEB9576594D2914F23AD20AFEAA82F563E0E1F239496693903F296652660929D0020AF0A209BDDA3189B969EBF139C5F0A150D384C4C37ADC478017275AAEABA4BE0C387083A6C4B466B70CC442EB104640B10111ADE7EC3A7B7448CE7240E8867DACC7118006B1A272716CB10DF650804E896843351951852DB87735593725C3680ABAA36B6ECFA904363AFF6D19F2F2A99205A8045091285032704FBFB5E8AD70D9CB00E90A2244217CA3C641A1C7AE0836EB31E4A69D230B93AD9DA2F115A80C8CA134B80B2994D3EA4EA1839CCC0DD02340C56DF52A120E730C12AF062E601E27631DAF97C158FC49370EB8ABA617B65C93D15133DF7F9A50CC795425EE1AE9074D29B4825A63F4A2093D64C462CAEC60388D1117676B51179009FBB5FB0586ABD32B668277FEE9A4E8C8AF30973A5AC82F4F3B74B6CC22B3BC2C713418ED6AB86E0BFEBD931BAF6401C7D39A2F1D44013E149365BDF4A7D1E8F9AE2762EB7CCC62DE4DDB4B88DCC2A4E9696E9E0BBD6A43D42F85A9DD86ABE74A466FEE545D7B2661A5EC7797E55D9A4D3334A09F1C2F698C7BB056A33E08BAB57320E6770FE82E19FDAA3B26F6CF947628D7E631615A6B3CD6FE4C8B85241BD1036E5779D3C315197601E9875C408AC83BEBC749E9CE23CAAACA4A24F1942BD72197677187D051F011CFFF852515F721133E2FA0FB3D787ADFEF4A35C336E975971E9D53619DF66B8CC277523903B9F4F00D5BEB19B2E5BEEAD90F8E3BEEB299223888DF0AF72E6F193963E0FC6343EF7D861475C00BAE2FED984A900D1F94F0A373C57CE3277B14732BE6C7E2D35735691CADC0DF660CE7B57C06761BA19B0FF156C44398AD0C1B46F3DBDCF363ABF40E5631982F964777B75E29FF42C2185EF8EA2B9ED7659B9AA4DD6726DDC445DF6B593823F083FA2CE59BA92447B0F8BE1AA9914943174D468A222C29B32D13608261A04B7033088A236EA624AC15CCD0F72A43E124C8411B94A856F91E2D8B9BC0553A0481FFD86E9AB6018422E1FEE12B3A474EC8D3B5CC76223B4891934034F2D906AAF6E80B4E791CB4DA84B73DDFF0F89C5E528E64C6F030FC8D3E417B5F80964B60B1FFD9C788A9DD2DAAA5FD62BF799A1CF2C0DB4E39C89AC0BF93E8464A6F808229ED499B158F2F2DCCAE9F9B01AC212687B5BF0118754E0B8AEF46B7C799DC3A40FF1ED09011D2A1D1F3B377C415BFF64BBFD01699C17148BDE9ACE830F111802653B0B1A26CD667DC48D299BE0BE537D777B8E919F28DF1B0B14D7689AEFAA48D7173A95D876DF498FA0917B331FA0B5036972BA5AEF1A9FD0E4910617F51D56085CBB807356E6EA35E981B9C8AFFF9C1BEE5EB846B3A59298ADEBBF61153210595A2A32BBBBA36121B86E0082B24DBBA3F21C4A0677B1338F773B17B708A2A4E9036B166BA28E37386430F7E63509D3C4A3C704B91C13C57095D54AF2DBC552B054358B85125F6AF6D666193D21C964C12DF27D5A53F91F8EF128CA0D840D9E7E6D19AF99CB01B7212257B33BA2B69960E2CF007A44C0C904CF5786CA818C4D89A2BCF4BB2A46902E6DC11A1DFDEFE678F34C9AD297413A61D4D9E05C2F25E33D74B02B892E8DAD7CA198BB7E229EDEB0B4B6F064CAC23ACD452248D7C332C629403DBBDCA09A2EE3B06494D10E7F841DB0A48EF54E247A308DCB235D715DE03569CAFEA6BB8F5542AC3F8844F2C798687FB934A46730F33FE3776BF5DDDA2339A88799A6E804D6E548F62642635EA8F8C00137949689BC0370E7AB92759E39D281ECA29BC0586AB74ECB2D243364278F0AE09316ADA5254B225AFF52BC24B1761A59A68AEDB2D95317E439BCD4DF5D703A67B72614532C28778F4D9AAC819C8788020391D461F6C107A86AD9CD9CDB6FF4ACD458AC39791EEB7BECE473E1FC81BE0659B04E511D0FC0635F8E7217A36473C07BA9035A8EE1B352E3F271B7256736DCF171004F306F55D7B33A1A2C71CE6D5D9B9848335EAF775AFF7FC173E6749E7ABBE3E611C10F59C3DC610A063CB2D2A465572BC3E1F2C0D782C25E8A323139BD4056DF4372D2B5C75B29251E86FA1D5D09F4A42031DED19A2658E477D6B5ED018090005910DB980A785DA1B38CE72F663A353F2033B94E41B0EF1F0ADD2D24FDDDB206B66157934914D8D97F1F81894663C1A5FBB3CAB4864661B0A325ACE252DDC135162D9328DF30F2EBE84095A2609344B7C07F01BF12C9334A8936C43CFFC11A14C2E21C8A1B8125FC72DD7DBA91EBE66762ABA36CF1841733B8AEA9042D65C866FA268E47FAA66364ECF3432AFDEBF8333AF1A1C727143A512917317EE511F0B5087BA5891F21590373CB802CD5414BE92D8F151D1BD0E19FB0AD6854AAD62F6C20196C48D526C24F0FBD9808B4EAFE926CDB55147D10CF74C37BB0E17168C10CD33417D4D4B7C582A3932DEA45A51B608FD9BC6BE302A137ED40009AA966E33CA7DDADCF4B8E6C284738171F48BCB4C415594854A568E98104626240E00DBBBBB276A7F96930B9D72E61D4CD84A59A5080E1A8642195B34ED7170004659A8A1C059BC4E20C35A5BEBE6AE958B7C1980467C8DB6A29C1567759B32E0FEF774118BA8C8E1CA902185B4CD125780C0C020526EF7CA7B244A893B86EE52590F18FE3E2F664B9C6BFF3E46F8DAFD1550FE53ED9BF017E5B240F1E4655DC9DE788E9FBA37A88F24ADBC5276DD8CBC163EEE9950BCCAD7AED335E6BE9AF958BE761BC3B4F13C03EA4F10B8639EEB2BA8FF8CEDBE0C4FEA4C4390E64B92DE45662FE161F925BBA31C9C9590A7072B3FC971798CE05F78AFD814F970A448A08FDFC7CF9EDEA49D127C7D3D36BC17FF35C4453EEC12BE0D25BEC0069648382059D351A8A64CEF84F85D8C3AFD85377FEEAB31B8D4A273D1886E0C7E53ACFAAEB76AB26E2C06AA777D19D15FE4367B223D13B380F6EF9B1C317DBF50B45C9ED9BD707178A76483A23C38986FBEB55F47BEB0CAE286A82F28E369C2BFA8D6A005799005438E39E2F8064A3916187E76043D582754620879C2B3FFA29A6C99EC654EA0DE34B98CAFE6152CFAF06AE31885F43F59953BEEB657C4CEC02E100825014A93F920F47A3386FD634318604E81841DC29291AB270947D1D2AEFD139D5968455B3EFC67364896C0F4BC4536882A73BBE3BB79607A6C899060574D00F48BB9A889A09AB24D67C93BF30C07A099A8391FBFE19F4701E1E5E5F149DEFF7499CD0C6CEEDEC14A23AD82F27B5260527AEA3F56C19AC18816875861D4E5FAEACBA7556C6A2B83D78FD15AA3276D994A57CAD744B9BB2BEF29668862B6511B7E50AA50049CB81D522EF911ED79EAFEAEFA0EB2F0645B951BBBE224777DA2C0A1CEC49E160C83491ABB4B905ED6E7C14DEE061576F2EA42FEC06C87D5C2D89DBF47F8D53B38DCB50F85B5DAB74A558843B7F7501B62189A940FD6F2B182DEC095F2DAB46F2B89354E11779F9D7E52C5B32E1AB4937E9099FC57F0C47E1AC6872543590A0018A66E7C8ADEABFC14F294C4451D8809F413FF0CEACD1599F5C01CBD63A49003270AC0A624A8B77D9D74C96D8ABA3E3783FAC9E36C211AE95C9315424C3960DE602F8E83450BF4CDF76B3E05A6622D1B0258E6D482F032A59E15B22966BED8CB7A7FDFA7C540907ACF5CD39ED6A8FF1EBC8BF114F4EB5E4FC743C3D586C41ADAFA04AE9580D996F37DEBCFD13FF9E951EB38FD8189C2C0290560816C340E569F2E1398C00ADA57BA1D7AE7C50453A058A007E3DD5348FE92C4B97FD893B47E55A0D434E0529959DF1650CA785594D285492510B264076362F3FB6964B97E0AD7F33D59E6E8E98DC0BA47D4B6ABE28E3E1E2946AE9C61930ABB2DC9E06A1416FB17766AE3C2E0BE9FC3AD13F7021E80CDDBC378D069225E5E212CD79779417DCE4EE6D53CB069F186F9BFC0EABFB43782B54321D7D265E1ECB31B4DC477B84F9497C3BB49A146010DAB5B364B1F01796EF14F4FB8E60591FA207672C1679CD23FFAEFFC292328C204FC17ED7450026335DCB56149E84A7493FCDE62735B0D1588CF865D82475624529937F35A998ED892E9DDCE8D2591C65862338F478B6B4CFF72770328A55D03AB3286EBAE92D6C77C25EDDE980C880FC2BEF2DF4AF156E974E69631610AFE70C865CB152564754B418E80AE64D02395A3E81E271615797647AC4023EE1845FCD442AEBB923BE7D0E618F4B477AE95C50A7459B707D2C367216D411D356B543632F85CFAA53E0A0DAF1609E98C9AE398C9859F325E88F5314D53E9AC3986F6EFF2815F5B475F5A99B6A8300D0400CB1B098AA43C5B56B78253A449FFC7B0B5EF231DEA47B5FD136DB1EA89160B48D58743B16CEF761A0DDCD905486ABD1C844FCE4B45E9981EDC767A1A46592390979C0F070C4C00743A68F7726682639D780843BCA6A2E4D48E500", + "rnd": "EA45540D9AEA2A3DD8EBDB2BFC09862A1969390D1018123DD820C9DC984E3253", + "signature": "A22A89C00D6E3211AEB48FD45FDFBC9EE1E5C1FE3CF0AE851B266429C9D085605C9BD2361CFF8C6D9455A5448302570948B00072930D1992655DC657A928603C68178C940A0DAC267DE6162B9E8F895BAF05B12EF3338441D4AAD68A61EA2F94780CA7BA7112FABE08A437543FA928DE4B897745599C067ADF1F10759D3919176D945F0B54ECE94C35B92DD888D627142F0382216652DF44CC24E28A6F5A9EBDE059868F719BA64CF7FD290B066B97E289A5D02DBAC0FA579A054B25518C179DA36A54F06FF945732EB2F617D3AB6153A00C8FD6FE87332562EC5A5DF7C7316B23FF818C0EDD8607426181A223C4C57FC695B5380460D22379701A554E115A51504DEB525DD81C10542D20845D686B00D106A99FE084E3553563E83F6F347DD379C333C74A6382C85D5C2C8F07160F105B95DDEBBE14BEDD8B8E9B6D2E46872619D8766E48B16E8012D1C8EA5B16E2FADC171F9A473CCC4999F56BFEF3D22C24163AF4E58552DEBEEBBAD6F1275400CDCB1A08C0F97208ED171D03FB7DD2ED4AC807AD04B01622E675FB57A2358D3D6C0AE213B644FC058891148223C6189B515F43CF5D7584DFB9BA65DB5694D73B0EC10C3F410CEF61B3C5F048341FB494ECB6D90E5CFBC4DBEBA93356E5D4A75418605710F47137144E84367AEE294B8C0721A39275CD3D21A736D7DB332604BE5185DA6955401B2FC60651E018D0B758F555F2DA1FB6CC6662BCAA3B28E33941196849E80D94FF621CFAF603177CCF1AEC9F6885F60D4C677CD1C296F0FD89FAD5C876DA00A363E3997962125206A5B6918633F0DA734A946ECB352341755260FE338517DFB6662DB51DF421308DB0DA637DB2F227F6E21F842D448C373590A1D58729F55299F428B8E9A10835AD7AFF169CC663D2507EC3A14FBA46807CC0E08E8B455F7F76B02E26AA179A3DAB31596E4AE9461E51CE8F429AE0B40A06AE2DDFE24FC59C51BDDABABC119893CBF5A7A1F17BDB159AFED66E05E79F087C28A1AA34A134905320492AB5307989251DCB8D5E1D1841DA00E2C3B480201A167A248176E15AB3FAEA0976CD2398AD430B8A9DBDCF07B6885C3C35D67BE523C9E34D37C235D6DEEA649ADF62DBE944E2D682F50C30A271D2B824A31DC9A4391A14884CF73FD48719DBAADECEFC72CE1A4A089E39ECC48F180C1051110765C41A4B0D4816580D7F60B453843E48EA28030D1C5EB63CF674BF6B1BA5D9288CD8826843E9DE2C45E18E3D3559FA65D0176A07DA2A77E83B566C49B41C8BE7CC77BAC22EE97AF3331349DCB6F6B60096C49C9BD2436C5545562D33D0BF2867B3CA2DD59199F202F0C937D962A6FD99CE92D6C0E39153EBC43190C613374371CCD85B9F8938388DB56B86930F14ED33B8988ECB559B7155DE10C5A46AEC1E6644D2857A45976CFC0FD90BB593AAE17DDCEA09854FCC7D32747DA492FED24D6974CA28FBCCF691BF4A59790B180CF522DF38B759FEEB9D2B3CC0CC662B28A683904700474DC94AFDD132CB748B02CE36AD383ECB7562E7972F83686BE443709157F2BDB3B900A9D736823AC549F9DA8985A53E9483BAB074F32F509AB60D3B81DE2B4D5CEEDEEA66AA69CAEE4096FAF4A16ADFB74E1879CB293B7C52C907577355242D1290F3CD5462C636C3B344C830FF753AAB87356F4B88913F4DC9E5DAD1DB010B7DF30F7A652331045B15696D73E547CF9D0E2B10586AF107A8248874F52F21BC73E839CBB6D0F2C79B9C633FCFA6CC6A445F14F249B28A08E32829AF2759B8629BBEC789599A3F46587236E86161CBF0D1A6D33CA7F73AC791584906588DF949BF75ED9BE97CEC78E3466C83FDB323320BC5FF2A45C49C8179170ABB01DE3F0CF188846F5047618271A0BF6DE867D6862B9EF354B0C5BA1DE7686C9605B48ED492D439CF0C421EE76B843096D7589A4005D09EBB65BE1DA9B2309728074678F82B5635535EC80396E5C5F580533134E5DA1E678637C396D593036E4C441197A07EBFF79D39AB6477B971F72630626ED303D99985AFDDF64A780656D38762A73429682A76B61421E296B5538C695C713B129FFC82B9C942995A51C243DAA2FAB84FCB2C041A4365D1B04B01E6E0949BB178CC7BCC49A1264DEC0588CBCD517905F4BC2271F07D09DF2983885D706C5DE2EE070EF6DFAC271FB8D9D00FAC925DCE531311E12D2A4083F45E6DFAB1D5B1DD289D35B5F446227ABAF3F6A9BD61DF0B48FF435FFE45B601CDAF929FAF2321BBC6FFCA7B184D56E182519789BC76B305304E27379855FFEC7EC77B32F7135A7942136A6B0B611487687910854C13EABAABFD1AB0C8AB237B4EE784565D5232D6E11DBD79DC7FCFF86DE09ED6456CE8DAD0FC4FB9450B24050EE718F6C84DEB697638D5C355C5CFE4487D8E5090A86EEDF9D7177BF88DD10C2B35D6E3E3EF6B3EE54B767359F60F844675D6786734A793A156C01815245A37402BDD78CCD616501E98302729B21F64DDB4A176AB0565646A4594B349DE5238A3997367F1C92E91C9DDE52B95F827852550655064873C9BBB1589D43316B7E2914E9D0EE82B2D232890B8D5CC9A3D280569A6B79561C86D1DB23FBB5D43B20E1948A1AFA819E2D9A939CE1875F9EB23DAB6E6982A2F75974B2C238C73A294872F662483FC9545C759FA1B9F2086B5B7B6D849BA2698707638A6B9BEAF0F847419AEE4F14295982A0DC4B6B6C73FAB59F266A3E52FD9233F566490018677A9B6E1D57750F3E47C47B24112AE5A93A976FA487A947B90E2A80AB227071DFFE54A903C8315BCA36D710DC35FA98284363A52DA19EAD76D28F9F523FF2960255FCC301E3327BCE8B121976248C297F83256D80FDAC8D0DEE1C1694D5AD030EDDF3F71AF5734F407285709A9CA6A2DBA11121419B9C97C27569D9235C3543DDCE2FC4F3B558409677BF2DD8AF65292AD978D361C8C57C7C9A9302FC05F5CFBDEBBD9B13350655233CB873E745A2E42A376E006A63BDAB8E4A5E3D35622EAE4EB8DF76E5492FA18F88B9C6A703ABF8519E2F0BA67F65E6950AE6D77D5D283F98369230A07214734599BB689280DE4B374F83D266621D418607446B4CF3F1E8703B4EDACA87CB7DC54569127792CD06DB467BA6BE8A4FE724867365A3FDFAC22364C517447FB6775D96E86A25204285FAB23D8B00D6FD37342C27DC7C70517EE7353711F173976E4345D5725A1FBAE72CFA842430DD35E445776E0B34A328CE10A75B4860FC3D17691C4DBD4D7FD0EF81C4460B7455C479AEF8A536FD47CDFCF341010B093AA9447D47A392D4A8728B5D1BBCC6DC1A6F061CC94E0F6ACDBC43662058B8B9A1BABE2E1DECA6DFFB33A938305A02F00F2961365860495EBE77A8643BAD628AA0302723A5E523FDD7C1412C26BF9C72D8D72AD24313007A8AFE759B7D2133F0771E297D653B6A20DA69F9514FAA84024D09D930E9A447F21CE0328A8FB9E6CE543ABE67CF9249803C2C3D6E7EDB92676D8B012E52A73A5F1A1E69A78AC491432ADCAA1AC3CF799F0B3FC6FA693DBF1B7CFF3636898BDF504566ACAF0352E96311B43142CC3FFA1B0E1ACE1A437DE776E1BA29966E2166CEABB82781C3CE4C44219511689EC8C96CEACC797E9FCC850A31916470609BADA9FEF02A43021A0194A6ABBA004DF5C3998739C64CD14D8F693B7AC6CF8C83F6ED5CE4A85D7AD2EC1B02F906556AA16BDF9A451F13166B40A12C52FAC402245A21D3599A62DB7AE4B6CAD29EC42B661BB1C4B952133749A0D89323C5E3A48A602266E932203452308C53E1BCE8A7B687FD1CE5C7E69BE8156448A2927F65864E09DE0EF2883DFDA6207EAFE798976AD80770A3B231966575C80C21223FD902D98FA2836EB7F76CD6D31C77980B9DAFB7BE681289EE8F770F2ADF7F537D62E428FAB5E073A2D4FD15027C5D4549B6FAE55EEDA47365F87488AB6D1F478E9A00F12D314E373062152E35204E29B8B245CF3E963E3718514A81BC00D372DA494F4012EDED0C284E3CC37054927422FD5926CFB707170F6623F15690FF056828F6F1D4386864EDF1A60F7830D7FA0B6DB9E61118BBBD8DF84399983C2DBD6894D68D476BDB393D83AC0E8210D2530612FB28CEAD71F5DF0541F22620D1D906D9B94A29FEF80300BD65AC748CE80E5BA7B01E77825D25081946D0C95978A376304C1BDEC374D4CAFF791F02D8A63EAEB3645D8F8B479EFC0D6D765E0A5E53CEC2E759AEDA7AB28DEAB1D2D158F13CABBA08C94E94A630E54B24A04C6C625997AC410CEFA06C2EF45A02D03B2D15EBE3C3C331AFBBDC83090D6E5DB275C10440149535C37814E797D586F63D6416BE151EA062318006D1FCB78103FE80F98E23D1DD57CE17CE29625CF68D4A1EC3225D1CB510AA374D9CA499D408563ECEBCE08601F9E329F2518A5AA85B72D39B4398D19AE07E62DBB53290ECFA1165AC839CFAC723D1C52D76831120871F6479A35092981EF715266C6D3D611471898542502F37BFAA32C0974D83E0B39BB23BCF8EB3BC5BB7D4B0444089CDC16B20C5EE1FA02B8E20E55373ED43019FAB679644722550AB856C3EF86D2E411571A2167EA3D318B7AE65D075258D4FB4FAACBCCE9FB49505466A601069CA2D3072329B8636A6B929800000000000000000000000000000000000000000000000000050B1015191E" + }, + { + "tcId": 37, + "deferred": false, + "sk": "114DEDCFCF33524B571F702B41DC2F32D7B65265A0D3141A40D633C2A7E9E48D102275737F7D37B008B86EFA9F826310BCBAC5AB1920ACEDBBD3378851FABA8700918A14962FA51C22EB5D52CE2C19FE74CAB43CEE3217852743DD8A9CF52426C431F8D6716EF3E041E2AEDB0F977AE6DF5551A91B0DC2444F470B6B14F60F5100885008512157712481241131368052750581440637621005831354565162836235177243307721335676515826743524770817217147617007254782315321566073681362354088153817635437810828534816573041554214000735456845802233054731387232160026272750268377648802708423161845102881738563332404868213658328408088163131822167527116450254234733525652148817764721672160616281416043600208886885168543736317120658755625553633047604484012536522418477002414887422451287230207454813726407358208255567087838016134077128773740436206415000155466027285287842530855862007558715134313801638566085803654201053222888101011205184037384361668733461570174818858240048628425176473806066844874420630111521703670536114832246580470180743633063178026203801424346842868106022122631711503218553717274607167566850415222876841072036810556014307653658488017682424014707321824030506686626384404743307025401858824007865805261137578257461040268055248447340127327547271705850505681632152680843646123434768733821685430717055783532138158108001126007418640868383854046585483064472114463647476610745142036312016442812505448702684147444160017831655727151444502757041631250227884456736208708064671303871721632678148754674632843533743311243213707457810242316207433162273215450047631302151852732788260508140831456326323164744753524222432636724850748324732757162860821320843746821336622536847742576150623236830117366884530751507647011533885853352222757006608216026285246527523450661417722028821688010748044512258887355265364557777680708337228627172858584681844551034516175410281808687636578606580606127828414328470015300708776513375708317061185316251201760043240612211153026076857208257070826733676357020165314734524020175254434420147437586187774216068600318175670732447137781281426634062741751512886253026088010857016328465528870025468086820426362148456223534855345156305272578336180787077727763186145217076071105766125763537827022613717520856868050485270506441300761475468026402676003840671040405580733423438406286653112385300773013178861321131583026382152503333844062734814740784662427003007432233011266022583883246275810080646217663237485081535038268333035022827402483563821301774285323787534720363004845584271154051281863876575137533177168488520051882588161370733563146202871847182064101086485680786326405311634445153265167767075603558736883332424168281868424022147010483771861464420661546536243548843607064706002068658431217611431615265171124650170667883263701144262341206177553713236811537432152136473625635086442724338637160308668672786273464033810314718418453404637846725666534775872282606718433425222853746537820313575101258316682561254651243164644817711408075728065373668425277664743006047464337500271153856807078588556371335843018086420541715583634176377547083705152302000152413607516083812673384266346566651003607268100404214237073104803615614556170765431508404583561442732E9FE9CC117746C51BAA9A178A3AD727FEE4722E392381E2C23F55C343EABE6BFE43AFEDBF62519336E108768A64276F72FD9D4BAD7389540E6E4CC5CB36F03A47415CEE47B75B5B43CF1D5EB100CE8AE6CFC3649B7994FF4F3B47EB493D92C397709529AA51583C5E6CBF01B97A0256C68B4A03CC23A4EDAB61CC0141F38FD1A2C53DE584C598C3F4EF6F59105F00E2508A9A083FD60C0573300259464D8FD46E2E99E02C683DE0FFD4469E327D558ECF1A47454FB2301B35688217A554C158FCE9AA6C56444DE7BA782FB0B8E86273F3CBDA13B0624EDCE90C56D3E9EA264113EFE00CE91BB112D9EB65073F937EF848D09DB7B5ED0A5551246F950B345089DFF4C468947AA8C4321747B0F35058DE340078715F5564E157031113F28FFD3CA831DAC0EA3741A5BF53DBB7763BBF581E8103BDDD8FA4C4C9FF7ECEE5446A1D108620A465FAAEA61AC9C4FB7B365BD7C950102943298296077E4449F50EE3F2A2D68FF850F93FDDE68C1BC4632EBEF6737636AC583290193C2F797232AD7B857FDDD029ED99D7DA1355B88E83D1611911FC98AFF95E80F0C758E55750B8410A4A121DE796ADB8458F7B9BFECAC92BC10F6B3944B9697A9E261EEB3D309E3A6FCE6D3D7E20445A3EC664735A93673AB582930E3575E0DD9771B50F304E1383329C83C1A072670886615B069683BD20FC3A08F9F3302916671375BEBBAEFA5D0D75AEBB17BCE8856640A39C6C1C98BED73A8C0187BD3646AD6F7440286D94101157E542E86874957625861D1AD4A2CB31BB30D682851AACFE45961D1ED730DBFFC78ACA8E2676D88320412F392F18202DC2925F5AA2E305471F45E650DC97DC1875913E9BDC319224FF598BDA5CE6ED8AA75991BBAB8B51F60D363B36D80DBAD9A444333C4F1315F0E8BCCB5989B401190A09AFCD68097C78D1D73B8B6EA1734296C626E4423FD310B141876C710270B157817742F022ABF0EE300D68123CE823E3614792A7F0657245CD1A7B21B2917E2D494D69E9A754AC7D039B95621F55B3AFEF28DF681725E0836FA1069610E1867020A5756946529A54B19BA2F4C50F9788645DD0E50ED43A867F7DF5A9C4763634D19F493668758962F578D2309AD0A6411ED5A6888DB95DA07357D8C54CFC2498B7EA2F90DD10DA3C0F04A69D11D7FE6DE34958768CB53328C2590CEE35F28086562D23BF0B0889ACE8B9959E94A863F5F7922D55038E630DF3C337F4DB18F20C1626C932CF7E8BE4D139C9CD217B655A0B301EEBE9F9827FB21435B8076677DF8106701BBA664D94DAC760789E5488E0F7A9AA304F52E635DE8E1B6FA1E930B3401AD2B74A59F54A2A5D0C9817DC7E20D84889BD1AFC2A015E477C08E7FEC14CCECA11A3191E3FD6F5008ACA67CF258D0641ACDDF39CBBD4800622AF2679FAE52F1AAB556E4F2A09E8ED4AF09E00169FAA3AA4F219A8D071F2447E35583E64F84C7A1A0388832139485CE30EAB9A1B1BB9D2061EACE701C3331DD42F01EFB8D6454D6426B4A3DB73E4EB83CF4E5935CC5BA98AD6052DC749CAEE5026B891D26A03FB6C71A3821B681401ED694F60DB217BCD19B1BE17D594C8617E5A0EF55E1ADAD51C46C275B1C92EF64C10096AF53BD42D0FF057C4C209976DA771517BCD590237F03DA63E8E7FFD9665D625E519BB7C40D92F3A31C1921361CF6133800B258C01261D7325473A60FB5E785A097957327BD2B1E14DCDBAA06537DF14FA79C48A67E55F1DF5E2AA4AA426FBF57EB3EB0A9A82CE38CF71632A08823331793077ACA000204BF50A2B8B30F9B9E9DB9260F6407E4FAA36109007E1E7DF5F8D114192B9830042D09569869F77C49BF3890F039893F72F8A459E287FE962EEFDCBDC0432D4B12020DABC2CE5ECAE03D86D72DA61034D778D86A84B1213C3DFFC4AF00A16FC7F256AB9E0CB3D2DBB7170B50E880B9C419F9582ABC7EEA0BAA768E2370054097B11D769A3F96D54DF85E61B7DDBB792C3493DFB5E6F8B3749A9F936A05B15A4ADDC48CC999380B5A37B3F0EDF11B4BE590D7F524E8012871163EC10A890C4951318D2169ECE0E3976FCEFECD4B502E9710CB94F517239907E032C2775114F5AA13E47A378A080988679AD8566AEE08EF83EAC519A61E772F47E8D6D971B065BBD52C869A149B2A5A7D2E0253552BB1164D64696607AE231608549FDDCED725F0400010BF7D633B4C9BCCC70BAA39541228DCE60CCEDBFFF04AB2F2CD69610E85F14C4D3AA879C7FD9B49CB1B7C3DF439C9C2466C15B13BA8715240E51CE10ADD7B2748BBD0CC14ECAB64CA6E7A8A81397DA3136095134BBD2E384D7063F5BBEFF749612890F7533CBE37254BA963B6A5856A1FEAB3AAB61A9AFE9AD9DD1B51428BB7E6BB7130B7DC5F6CBE4537944756E9914F90F91AA34A5B11F1918AD74289595B73567C16E88E448B69DAB2750B9C5A93964A9650B3054736007F0453BAF61964D79509C17D231E0FE3E1BD04DD968BAF26E0F37B58774DE3940D92CB96FE0D6E6B676D3CE6C66A41987109C8B98D6B2798A71EBF39AA76119BCF94A69C02995B644BA3C4B076DD82393EDC47ACC09491478DEFEF4B8A5CE77D417050007141BA1D82EB56EB3191A76F16D78CE18C823D5AB1AD9DB9DF5374AC3343B848A7F88150AEE103F1ABFC559851B9367E1DC510456B965B2334CCEE09FDFDCD317ACF7A4925123C617ADA71F658C33A7C2619EEAE0D4305F782B4C6E540D753F6C53BD42A2501671D4B052FB736EE402A8E110EE5F889F13E3497892D427C7538B8ED51936D1448556126222A6EC3244A2DCAD1C1D4567D2F895BC805C133F04FA7B322102A718B9EDA77996CFE378F8EF64C0FF9BADE5CBDEF1B05E99A3219089905F3D124A154835CABD4D83545D0DC7662F4094E01CD7A8519200866A3E31A62070FBF566EFE037A834022FD9AA7A3D1DF8C88AA0A1380E92C4F9DA83BFC13FD033634B84522141257009FDEE776E04453B12FF46251E3B2FD0588AA58ACEB0207E915E9CA77A9A2A5D29ACB0F534313BDB7F6C36D9C27292A954D2F8FD03F4779CA2AF3C6703294801B30601147E79E94D7D8115077EED71BCB97783E910CF2C66FB717FA05DF861069796A9980689A0D1AF932B584CBBB87170CF281D81CC288967899A0C4B1104DAB494D1560844ACF1263C92CB570E0C705FDD1AF700BAC1DB29A6FCF434339863564F3CB9EE38CA7879827F984CE23A9BC065D7EA1BBB2EC5CC06EC8E9F53D267D0D1DB0398AA812E35A28796D66ED7C6608D58407FC1CF26433B40E0AAAE6333642325FC4A7C3901EB2076B2DC31CA6379AE8BCF628E38599F38C058FF606594DC5F9BEE89CEA4F08DAF4E8F706D284901FA371917EAC54D264A55BC8725AD3DC76D7A33E77AAFDDA1EB0D8E7E79726697A24083B1E606F7F7CDF6B4051B5FE0F31C9F265311780AC1A13B2A6823BB6FE82EB62A2DE97E64F67984006FA6D077635AAEBF555BFC86EF39E4B22C61D4E7F46578CB2070C18DC5E19E32426548EDEE1E4", + "message": "E621ECA9DC2B790A45992D6284E9BCEFA98109A1A4CA236344B0693AABD721AFC515382344DDC21F597B7EDEDAAF55987F9BBE7D50EE9D1E4431869E4BD285C3780712DA813B8B67FF599042E96894CB4FB50C309B99B7D7EFB95FCF44C179E9BD67476E7BA54D8CCB591707C68DD8A300CB60C4BC432BBF768D7FCFC756C1166056D0C10C9597AF79C874C6582D646F89262606D8D93F8E2953041254C75440206F342AFC61CA27D2389DFCD154127A9FD4961C96E2859581CC23D6BC69E717C4451B6AA804431F43BDE85D6EC15A4C2AC07C3CDF19853CD9DC2F40810DE4BB950CBD2CA13C3B1B1176361C1E5F71B00DA4E4A0257D248271BCA7E31F549679D907BDE07168F00E61A1BA039CF7F880C04F941787BEC253ED2F94914B9DBCCB7AD21317E032FFA1BC6B5FE8D111B1064EF281DC20104CED1E9D127109AC7AC1898B154DFD4773412CB527D3ABE1F000A09E3EC55E46578F1F105E53732B56E43F0AC9C11151A48DB8DF23779F6BFE7DF1869D6090BACB524D279FA1D42B204F2CC73FA95EE1863EFFCF802A99A4B6BEB2337E947B83AB7EB428A3988FA35D3809BC1C562AB1B06F1A18E43C39807BF1BF2E4531632A0B481E6A5B0F51A156E30CB9AA149575EDF865E2BE87CCCAE90F37F539E68769F1B3D0B2CC18A91552D9A0B107228FB2E6F815CD9B55DEDCFBEA820525A47BF79413DB39C67C6E03C601379C64C7B56B145C99B4DD1C7DCCED972F3B1B6F168A760478BC8DA40F80ADF3E91922CB742A259E753C2EF1FB0DD068DED5FD1CF6AF1A5968D8F2DA098998C8A6D92A4E35CC6D2D57121F31E3DFDC6B97972EA74954CD13675798E1577DB0946D12D1D87867000C7D4770C3C382B100B94958BA1E06DA78B2A3B536D8EB74C8D5E3B395E096B5EF514CAE24CC7FB71D8D70CCCC45867821A7B16F2E5752592C6B3D427A9F3F7186169D409727822921D10D883217E005185E52D4521DCB8D92E4D5A6F6A0882A16A3E4AC4A9FD7747C038CF9E4E53D021233E302C956156BC2E8DF6E9BFF2DADCAF16E7019F239FC611C2B67888D76725271A6244D521C8413FD9E849B3890A76B14865A579073B8573155E6DB2968606C7AA72CA799C2514CC5008DAB902DB7030690F1EEE2EDFA9E4DBD10A3694A148A4A14C8F094AEFB06753D458A11061541F94F253DF3AB814397C05595C8C68A0A8B9EB1A66EB0522CCEE5996430915EA252D96AF3559F29FCBA37A0E6DACAEB0EA2751C70A9671A63437BDD1DA73C7A37A72F5FB3D42C80A70E5B0D891396A7AB0240A0ABC905D2B18D3E20D6473857C8C0B47D8275EE4F4321E5757B19A7A264512556FE053BEC24B2D4A2246FA28D84D72731B5FAF9D0583FA6E6B52A85862F639078D5BD2EF0F26A787C46468FE9089BA001A0D605F4CAFA132DF62D569C2E1BE9B359AA2925D8C808BBEFC4CB6C6C9C140CC7B4A21816E923FFE206B8FA25674012B3FB861CA867B542EF1BDEEDFAF633AE277C046F2D9CAFDFC7D28D8D0BF7D6CDB2C662A04B3C88CB23CFB4C5C9EAD16F93C4F1FC35F3D8169CD1593133D912A3E1A7D8CB66C7731978396306B24BB02003C0661D9AB8758B92C868BE55010587D66611790BD430FAE28BB4AB7E6ADE0490AE323960E90AF321E4A097C255A52DE5E171915040CF35FAC607A5AB976F335F2A13FA2EEA6847F862BADA0A2BC1E9316042ED9D3E2FA3A86024C9300255DCBEABC2833ED68E27CF0ED07FE477951E8F37A801732DDE22AD52D0BC123756C8E29F529F495120D962B51B7C60DCF6791C360086CB377B104B0BD45FAFF0DCEA8A315CDAF0B25490BE7339EF3E292E82B17FACEF22E1F93E7A43529EE1DF4C9BA459A58F5FA7F9C9252268C476F5539DAAB63EFB8C814430C0BB82EA7C7AB32638B0E492C6D839EF7B38706611B9FAFC2DCE189505844C89EC6C67989775029688797E71F1816CC34B4480D80B309C2754195F7E103CA0B621D613329B8534FC107C96ADE14F158C4C29D1A63B6D60009E021DCB7113121F275FC0070DB9EC1DEABB456B303B2A72E5D091225BC716E2DE21EC87A21EB756E7C6E80BC1FB5CDE4C2C6D514F3E218B8AC0EA2969F9E6106B82026A97384A580D95A952C6B432CFF9FB1C41D88164E08C83BFEC76C5EC9119AFC0F4CA56D9686E45D3B41FAE0E4AAD60EE558AFFBF2B76CDC170A0B89DE149C800D4FEDF30E850A74197ADDAAE4DF460A514A6355A1983BED3FA3F2A0FAFDD818ECDFC02AA5275958BE41943EA4AC7009BB0687B62D896FCD7A932A57DDC8C5ADA9724754E8F110E8F080DF0165B67069FBD069C09B818B3434A92BB61049E99D52F9F515067BDA14C72337A8BD9476A6594AA1C7561897AE975DD0C315E80C38399CA5DC6CC9A4AD97CFD933202292056C41AE2C822339F8D651EEBB1971D4A06657DB5FA9E2E7F76723EA80017DF08618FA34FA88629004FC4FCF44C10BC1824FEAA110A8AAFFA13C269F123826489596AFC6EAF4249B0778740AA994142DF63612A65A039735EFD5391F137A1888F6E95368EF0207A4F634B4A7DE8AC4DA5B4A192AB11D31E8FF9EC8E2991ACFCC2052956E6E7F680F50D3B38BFC96C4A8B7C239E34638DB8C57C1D857016878A9C0B13E93338CAC953D5F639C9989BAD7E5DA4B11C4908D6EE5C8EB1B04A56EC4605D15A76EAA82F2E40E73D3A7C15542DCECFC702CD906D668AD4DC67F8093B1330B5DFEDC87B4D24A67FADB66E61C339F6AABA85691CFBE4BF23F237CDD5ADED9EAC9B3F4E4BD78855301EC9742C897D0BA93DA5F7D9BFCCF52D399F04A255C54922E3F8DECFE2334FB15F28E9F112F8C3F7DA229AF60F81A57A0E307E273AB45908BB86244C74E6CBD89C075B6447035EB8C73E57AECD04A9084553B5AD0BECB8BA8C30F470B08A3531D068FAB889EACDC3DE8A13F26EE538AFF7D5D7AA179B4097BFE44F15C73D42DA31C59306B4A0DD1DFDCD494C83789FDB45BCADF36567F7646EAE596708CB9128D7976B0EC17E6CA5C83C110F00AF46194B57E058651A729DD455842045A5590FDC49FBC991EB332615130DD704CBB9F3CF9E0C61DB6D72D361FDF9F4A582B8D51316DABAA215B858B8BCC6D8EDD39ACD4A29A3FD7B6D26B6039EDF4A43EBE2DCEBFAAA9F98041D729C87CE0124767140473DE0885EA3D0BEB573BEBF8855E087BDEA4E5E13E20A2AB201A14B2CDC2AC25D689F2473A0C73959BE81A32ECF743ED3FBDD4E38CFA8E661532825DD297D3717EC8FFD93B4829B39862DBCC96C7EDB277F75A91341AEED6532D8F63B00C0877B4A0FACAA9BBD49A5F190E7BC0D193A4964269DB1F9822699399951FD278CCA6EEACAE2A6C73F4D1D27A396684827FE84D61DC8CB2E71452DB674EAE9DA704887F82FE30C9D10672CF1CC223EB0DC0E24822C6E6F14C29ECDD680B72F6C3FE949E14645564B81B0458DDC8DCC3F1CAD6DA35728C4BA2ACD3D862F8D4E55F5097F99625B5D4AB27CABF12999E20024FC64CE0C2475BE83AC3DA48F08C72CA26E27BE8EF13B817C7AC8CDE748666772CD8FF7BAF0C41CC70D8B9EDDDAC47A49933A8F0154CDB3F31EBFD0403DCC0F4A1A7F538311C0DCFE29125CA52F9F3C4B090AB457B082F12112087ACCC245D96A30CD7C170F83544891408445EFC5FC988C938617373F179796630666086E3EAD584B6A2C38C8DE8F21EC97C81A8784186E823A00F231B59BFAB5DFED13763429099ECD73DE6B1BC7947949ECDA124D765119DC3C97484B25BF4997538F72096BD872DA67FDD6324BBFD2493E5774E491096F601CE10D9BE405CA4A11B6DA99DDB8A061BFA356E5B136BD4A322C51F0095A4D2E284FC10B3A317EBDE388690809047690477E3EDE3798B0DDEC47CD62C3AED27ABFE49D5348E7DFFE828E7E6214AA91008F149EDCD40C13C6A30AF21A2F004B61EA7DB39B0405A5E55A12EB4B5F53E8DF61FD630E10BDF77280A258EECD3A116DD9DEB5FC8AF3FDF223AE99CB7F9369FCF8BF54406D243FA0793E8F02F7C993F3DE6ADEC94FE09FB53ED033505D71B00FA550B7602EEFD7B7A705DD2AA93BC356FEF63D30A20F4DB020823045DBE7A55768383DBB2091EA1C9A80D89C91C0386E160F3702C81947E20CD7F2180B723880A26EEAE1AAD96635F90549E9F25988139A3CB8146847C55219E79586C7E321E36ACBF619D4D2ABCE239F4A8D6B61CAA15EBAFC2D56A34B9887BEB456A889D54393B44ABDFAE6CE976A0EB7B3E04C11CD3D3D109D27B498B588F0FFA26A16DDDA532ADA7D2E08DF6E5823E2EE58D38986601E6C8564296D6D3279C6D95426BB4CFC108769D372ECAAC374C69522CB2F4ECA53C82562D9EBDA93AEF01BB2A2E21FB904B9882153DA2943CE5F4F03011B2295797C37457451B698A9BDAE9C307823C4CA963DEDC4C7478B0E99B3908383505C8C4B2BC6A7E94F42A74DE99B6638DD82F0D3875278AFE1A442DE2FC4935EE5925814D40DFB139752E8B69DA66C8A693E5D47EF6916A971605927D93E3C38F844F35526CF763ACADF3C9EFBEA103ACC1C1C6CFC8CA3D9E77EE44A48C5F3D3F0E4A0ADE138A786AA5AD49242FD2856ABA2ECCD122D1D99F2D48DCD5620959E727F9C2340BBDDB8E92E9A192595AE744B3B6BDD6366528D07E069BEF191B54474F928F0727492167F503364BA24795B937E5E0B6409979B6F0E97D2D25C091D93543E9FF141F3AA47D0E7FB01C29C9FB33B1BFAAE4999B2981A32661ED9E6674C342756C32D97AE790C55FEBC30B5A275B5ACB9C35652BBAB02CD88EF6CB79CCEA32CB76411555FF4DE51000444B566A321D3D575B40A78EC8C68188D8B8DCA0D5943719659C4488B216DCECF3E47131B5A147C37C4F51115C3102959E08162AD203E4C58D0C0B79E0A9A6BC51F3BFCB5C1F90FEE3AEB4BA59B4257116253258D33EE0B3AFDD5146A03B722109BAC571A218CAC060F969B2B794A2EE52ABA552DAA077277561E416E001E84D617C5F0CA2782CCB880D094A66561593F431488878D3AD58B777F9CED442DD7A43C018DD28972FAB342E3678093E9F6F20C869BD7C2C1D8A497793C22350E9CE85027905C5465C6DFEC4B4865DE6D05B3A1D1FCE11527CBCD5EE1374F51E6FE8B4946ED989D98C40867B1FF8E8E3686CFC98E08339AE52F3EC02DF5186D2E91EBD9D79C653CCE41AA0596C645668CFB54FAA57DE3D1D763E5AC2A67DE42C99E2EF7651A8A8B81744771DA0BFDCBDB69270C38E20C5C8850F46227E7B116B38510939221CFB4088CDDB1DA6B22CCC50D93DB7D92C8DA32C11835CF92175E2521DDFDD7C3D96F44A59E00BD3F1EA086C3F43F45D7379082E8576C901459A68D9AF0F80CA990BA4DD9B3B5234AC38A2DA8492839A5F9161AEAA6687D2748F85AC14B80C94B48CFEC2EE53FED527A2951D593D80CB468D81BB94455787CE93218A1079D74145FC08156DDA27D14D05F3F1FE5665A6099625FBF9528", + "rnd": "769AD43EC0A091878262914F6754334016B7D6B3BB766AA52E45EFE75CA02988", + "signature": "8B686F08D2545A2012149FA7E45E86E7221630B84F3BFE343C19BBE61C0F22BAA58B26BE366D253D05689B75D888B639E72BED246C6F874204CF2184C13717FB2B815C8EE1C05DFB01AD6BE89943608DC10FF7DE6F52D4742464D96A6909A1539D71AB8E4768A0E5059196A3F499E312084DBBD77C060F2B1E6CA12F26EA8AD70DBC8593B88BB6220A14E93BC8C086EE0A36931A9CE9A4C482AC26142ED087A5CF157BED906ACBFA0E028CFE5035C8C22464518C45E737739367F04A9ECA0FDAD7D0F7B6FF0037DF6607793F981B85D7AF190764BD5CE9933EC48689E9709CBC7FA3FE52A9E8194E5CD2ADA8BAE6E4563514D71F7AE810AF25A8470CE9C6004B7F564391176F86F23AC757EBC462956FE1093E63DCF20D10E8270B2B15811EE2A273919F2A37046E60F11CEC9D0AA636675E40FD44F2D0A15F94756242E152412B821DC0574446C4BD4154C48F22885C9990981EBF81419411CC36BE2F7E7B65CB4DB6EA5EEF7017DB514F3777AA7B372F03970CA6C9B8A8B5F7DEB04DCA089E3D4C9014640AD7C0BC2CE8F2DF51BB3D1CFE5CE8E2D65DDD8C9422D6BE8B0A21399A28768762822AA38C2575D4331D6B37AF862E670A4D98CD652C1B4332835F567D610FD5CF9C24051226F636CD4EC469B11051DADCD9B56074F8056B97AE9651B68DD6B0D985AEA8E9D3C88218FE9A87FBB242538E177AC42EAD2BBBC3B59DBDDB013DF16BF7A113873349212296FC5D490DB9B001F6268F32F35F30C4848F06B52BAAF89DE287801168367D7DD16739EB087E08354819ECD9763A39EE09AD84593065F79E41DA8DEB2D8A140E7BB7919951BF0EEA30244F34F52E689FE6B67FEB838AB68DB2A4F4E9E5945481407D69A241ABA5479FDD23C32A85A6FD88E0A27867B2CA052CF41DD547FFB3ACCF5AA5636E8B0F122C803B5FF8D36EF4594A15C7E53594770EA4D55CD7FFF6A634DCEE4D408CDA2E1384673E6799E7B569C375D724D4B42C4D6B4C78DB18E21BC47EDFF13B3B7389508791D5D30333799DFAC04583C92EF50EDF33131312814A77C2E3B25A43B319603625C75067975769875EA52E98EBEB6244EDBBD7460D93E1F2AB3FB458E81F332865F7603E0DFFB4E78EFD3469C180DF7A1955D11AFD7E51D1851AD71D89BAA35F2CE875B55F661EC4F704F07452647FF73356A0EE8ED3548C99329D11E91165D91F2D1DF455BC252344D3AE1161A398DCEE93D8B553E290D0BFFC893B6093A8B93A9C5F2F392D421FEB2AEFEFF2408E7E93817689ACF8CD0D4C899F0E064984AF5C291794F44520F80AD49E31065A796F5F19E2BF8DB591ABCB57DBA6934EDDD42F6F939D323B076E66DEBB121953349F87D522D4817049425F53D3BE62A5947CFCF62CC5670A4635D970143A58464ED590419B71CF2D02D4A171A8D3B189526779760201F85C4CA10966B762A1F5C72C1D644FBFB6047A53442AE4DDA7AB2B3F439300D29A99FB59FD2C2748E0FC819EC4792FA2BE9BBA7F85E9AAE0F1E8AC96E47B97E3A84C8E462410F4829DC62E9AEC0E40570BB84ECDC4BBDAF2996858DE6032EFF038D54BFC27B262A2EE165B4D42084AD37AD5BFDF4E32C69CCE446AD5E34732863F9C4C2FE2C06D9216DFD6FD9D251121D7E96559E4B2A08321DD533D48CA3CC6E54FD011154B78467E38E44C32B62C77071DC92406DCD9981247786E4AE9EE2549FE68982DF2F154C31C37AB4BBC31341D6E2979959658547E3B2F92F6343D139D009A58A3AB6AA0FF60B2B8824FC4D1A7C6FE50665412D2BEDDB57BCC2913A371EF27F91ED71B65AFFE338AD00D63B966D2D05FB77634B90E83D335C0CD65F057E18A5981B6D48882EACA00AADF68062A9E1E62DD0183B2CE06837492663B247A847E4FA6D05E0A18727865C5E2BCB96D3DA03DE3F74BE3E5B55DC979363A05E32F8354D51B28F66DE631654312C57E075C74C032B965D3FCBB2CA183455AB93F3B8A402CA9B251B9C23838D1470F82ADEDDFFA7928181CCF5D920AEBED4224655FD6610DE63CC80721765C2D11C24B980B15B30ED586E3878222807BAAD08F755AB42174D3EAA7FD402CCA1805F5E11996877D7FF875A3E7FF0EFA9988CDE057C75A423349965E6AFC4A0F3CADB1072D94F56329E7E361488C19F938DD0AE0514726505264949C5217C086F107FCB5655E5B7790DF81E024529577528545A3A896532646B63FF705EF851DFBC7DEE381519CE9E6067BA26B76AC6D918E6995363F21D4EF66949679C57D7AEB3F6BBAC4418DD6245DB176A0931A108556C3977160673708B2970B32ECC8B331310A5A1965B8A96BC0305290B7A146CA156B464CA4855EB9E29628DD377F10BEE64FED78570F2F98AECED21B12F24D7F754367C801E199EA1B45707BAC61F3C4AAF8693F05E75A49A11DCCB909680A75FFFE97216BC9D4E738E0BEDD4D251BAE9AF42B0A081F92C235DF8610F8EC8D08A0D17A2CA9B504A46A3CE7352AE79C8819301CCF5E8F952AF894CD9C989D56850CBDFDFB639AB94E61677890ABB40C97005E416A60728EE0D81D715A46864B899EE21843B408A30BF4414E65FB373AF731CE0B876AEE6C545C032ED01604DC5273B4A3DF8D42E508D4D289E1D4315ED51EFAC329D7DFF0E8A9582EF59C312D0F0AEC1A1F3A4224E288096A1583E9AED1CA61FB1E9D44394B569AFC1559EF7FE1469132E23206BE0035C0DC03A148757A45732286F5BFE54316D7BBE9E845F9B438B55FB315CDCE57087DACDA1AE85F25CE513CD2D8310CB00A42668241F84E0C209120621FDC6ABB2C0D4423C750EB78F34608FB3B4110AE0DC510EC2A992F6F11F58D5A0B8A0B7372EC2F1BE1ADE52196BC2A35D90498A97206C29359E13373614E43C1027818D006E08D5AC4F4886C0C70ECE5C359D7C0713397689F7B546630C1ADF154AF80FC552910374F66954C9B5FBA1B2D54D3A020932F61D5D1F8B07962B34B16C1791C2E3653CA13BF03B9DC8DB65E579B1C96CD570158BCE89FCEF329D14F4A9860B6A58C7490437A6DD428BFF89B1335C6F6B4749796589D139628B144F4DBDAF0CE5A5FE4975912816723D6BB456F7F17E1A3CC1428736A8952348C8E96A73EE0E6AE09E5B493D0D86DCB715CA8BEA28A028E68BAD31478D8CFDE39333E49E3272C81EF74CD17BDB3CD03418ABE0869EB754FB27301B3EC69AF5A9F0DA7F63426B5C9D59E8E1AAFCA6A058A7CA6E79D8124CD2FBB10E5AF7FAD018E21B75AC6C4907050E7BE626B4530BAD0D1AD4C8FB4367A78A18348214959FF0C745BA895BB9A7014B11080938366192EB24594F0D94F13AE8DAEC64F5AFFEFFFA4B5617EC60EA72DEC4169D3328E50C3DC536F1414B863A09F270931B104DDF21BFFC6950C9B1090F1ECAF9E16ED8DB0586CD171130C64EF87EE80406C0EF971AF88049DFE568F0F1BF71A9E97CBDDABC6614FBA15012000BD7FA0F20286AC99B6963A70E8AD57ED624DE0F128D7FCBE418976384A7F2221DC5FA55B6436A651C7DF5AD36DBA5D7D5B49EE36FC5DB119553DE5417A54640AC090606B5B9BA68A0C0FFA5659E56D403C8E6D1D7D0DE1045AFFA395BA5635DFD2302DD1D3717947ECEE9DB99C01F6715BE60D721F0D3B8507E1210DEBF717D8F9E305C87DFB94BFAE5A7419E4A072FD3DC3203B6356E732C6A4E3105BEABC26EE0FE9F4ACBC4FD978D841E8ACDA6FB02BB49CBD802295B4033AEC2AC0DFFE375EF79FC12E568333D5F09F5F269FF4AF8D15C35EAF8728E0E5FC1276C0DE2B77D5EFAAEB105FBAB62EDBB7DBD769CE491D4CFC8AA53F3FFFD6F0C41C2901C0127B29FEF5B54BB4942BD7CC4DBFAFD6764D59896676025D4E46F189B7E00BB80A5E3D4DA4541B508AF29308718D5DF6D088A22D024D755DB240A9D814015C816F3EFBFBD3CECA28F5AE1835F9D54E6BE8F13B4ADDF233C0B10072ABC4A59C9967D799796DF4563D3966C0B6C163CEE446A7E2A4471440425EF3E60E016B75F7D182FDE99677CA596C91715781C24C23610E8D1B3CCE51A1A2D60398014C2A69F74B23B98E2E20F2F2873B30E2DE00B4546E55210F5C53869D2271743B17E08B1E0B6DEBAC6739BE53C7B2CC7E3300A8DE57D412B7BF37BD3FE24D68D5F7F54D5E205D8F932F70D9F9F7EA15AEED22E7ACD16D997148F58E2F296BD927C67B10009C7261465DF3C4B3615D4325D160E78A4611EF5C4EFCB58C29EBE0BAE2C4877D901677AEC22A6D3E9DAF353307994CEA257B40339E0A3588914851D7B3A395E9762DDA02FC807B8F8D2E5381E760BD5CD03BDA9C97ADC6DE66CF7BDBB7BB68150BF22742F6FE973EB4F6B07224B3DDEC0538121036E33573CE8F3C543E960B3C662AD885ED49907B9793A503B991DC44FC440B90125C6A781E6AD48472887A1A22CD8FD5D45E70CB1E8B4B180DAC613315B7577DEE42389F54B2D0DFC3A6E89164401BB191E8808D08FC2345E238C9B8421C78EEDC0D23C7CBC109316F1D6C7C2C5BBF8D80C920B55634B58015E070213491C5E7FE21740FAFC4CC28EA8EBBB94ED4F9AC93A40B85905669580BA341FFD1D0B036197AE358DF71B347EE0D2B88A1A9B3D7F10220396691B15D7E818390C1031A5156A2C4106E81A1D3FA1436444956720000000000000000000000000000000000080E141A2026" + }, + { + "tcId": 38, + "deferred": false, + "sk": "147499EBF2D0FB64F5DD8DF57AE3ADD860960C33C3960F988CA1F46EAEB4A0AFB0B75B76991704819E12F089F9DF04318BEEBE890516A798554929578BC2F2C5B0058ADFBC66F81B80F6BA118089A3791B33F607721A511601455D6DD453BA977A562645EE6BCFCADC7D5E143E4BF76D48A4CCB81103D3F4D07C10EC1C8B0FD935884166866250862020454372864262654460626454548686317544353276405038366361304583344115288575720274180235474763852833555776146403644047022177681210707322860078144551683008605273620217161704532313545782277646100805181300072646175154310008472211602835242887207546213166786334031861452853804422540646753767853018017757058030160163065781815702462285015403731806238804153264828336081083044475272570706216642062100478820744588251600082673774642671223668838663151762058640323638882680476620638441221045618360630840806306632866368340328241501632864868441816541245525476830353152031656046307423657440088356582101850428657815281377534578071181450152581485166812753385100607536264366788245023742535270538353264842041663577011733657511314673335300876022647565703322083071375867706684363504511048258701423161138512486412835285624242828187577376486543625166106317386687888551551248881286383445017536372386837806160385202423328237847172633151408588051452527033711528545544732362571524042287851465278661828304475647825261651151180785211475210158406110367140048511321780114188623230483447576831486262353106715150075887065240135663674464167605877075263510616812463865028142534070003181342068030427815667313870850071741186615081665456700875460484574856284863100544725600561881673840783488736282158034156774517326438501580401458058266286234827727677371748611255760836140125672303684220665533648117302570237526530702275541556035086508052334048722022462300765631775080787460872605288842887644878580707513658075121823073038218035607616217323847877824751563120331071530182421608362063855200138484456386070457421023448378824154187312181175018181388483326285506884031471356807851708513515014307214715332131846101782037728257088445255608814631501360637332013712078588056865473660661410266440573338715810032618622684721240618044387241161714252204354186357487478475414072052178750011481065704021112848020251083465833480767564467757605566487186334644465684324734655543355441480102272554233644385505247221265087123321421540831831203127024060401837368541205260884537545201763126081571150802567271388857337556114728451155007566521802581111131068115511013548313368242865542352466185265643200675216474566113231127711002414887254262640415433786273414381202837385028713426810673457828427585114338242863122262403603625625601003487274275842514631243647568210540663603243332503448746123078036582460301274166878308418610266471780676780487886814144762557180776804028250210014327548186380580424324654346705872285003757511131306404228612027418320132203784723420386736880833401810641170685761713221456743712250238435521002031362564401604273834308148676268741428842512846488003417344601866473661773314800117256733458722123850778886263153353014430840685618316173808012540752436315188338085036180517363111763148005572333063326152577664566671146486073177056550635655E24AD3C3D07FE57BC5F7CCBF87CF6608BA7F9D6FDE4C193EE362E0B9DB29514D7808BF29D852DEC88E4278C2F5D367E69DCB1BAB9F3833B8309BEB1D4BCE6F5C1D7F04F6236E54F5828A337EBA9C6D44627A5FC53F1B6261DD9911E1E49C14A5DA327C18A2A9408EDACADD24B61214BA8841E8FF69F974C58C27AA66B2C29A37EA1B8CD20BDF157042E273BCC97CF1B5889B43B8E05174B483480C243E6D94824C472D78DAD51DB97052E4677E63D59D0CAAF8B31049B386C5894C5C83DF28F9061490B06941AE20A50C4B84C03407011E3C1AA2B81F858B84E1FAEC3BBFB7283F97430F46A34DB1637F6ED51E62F5F40DCF6D919BD7EFD1382A1A7DEC7C8E0C86CD4241A6862AEA8999B9BC6BEE5CCD811137E2B6E33FB0498F49AA356A4C33257E3466E25E9329CA7B990CE8C8684C22E9379D45ABB976743D9D9388A5CD4FB5C9DF1F904C1ACB0CB536661505FA648BEFF10D4DDA0371211AF91581B6CFDE74CBC27C98517AD8B155C8709F5CDECE681EE06578623D22F6BB7FAC1C4C16A326342D47DA56AE8FF0BA9C7420425697B940DC61C1789E28553CFA34CF97B88F1AB72B685063CB9E94AC4AAD15ED712A9C78C20094E2763AA4F46BFA0D22206566B1C43C3D85EA3BE0B7C9FEBEB1CD2F6D9CE95A481EE55BE26B6F542DAB9D42A95E21971EBC8A5AAF2C5181A40D2F27C7E80D68E3DCE9795FFB32D89EABB15277A5FF720CB1BB9C0A09B7123FAD491E28F53C809ED72EBCB876587344F903CAD896A129F6D8A2D28BF14DC7C2ACD5F88829DAA9F5252CFF346805C3C36113D2C0B1F55E9B6E8A16992E88C40D798BF20EE1A6EAF7CFCF8BCC3D57F51019AE10C54966037F9C641D2D14544120658CDB654A36383E7E48D298A18DEF2F88B9167539131655CA123B58FB556ED06F962064D1CBCB908D0726B47DD1407D4F801657A30E0261103BD6727A54B9A61C4AF42955464AFCDE0B8D4BCDA320544D79493179A8FD67742F335E2C4C4DDFDB3B74F1ECC8B0A06A898E959E7E0505A0803D26CC367E2EEDE97B8E6F944B7CABAA11590D1D654ECA334AE7545EA4542B862C900ECB3ECE6014BDC22D24D69C7EE65AAE5DBCA5831EC29F5172DBBFBCAD66AE0E3D5C7FC7EE600B59EC235A71C9671418C0F677BB795F02CF7EF5FAFA83DE1B6A7EBBA349827569AD44545982925C1010097EF3A441E16BE02CC98C5181B20AFBE4A72748E39E36677574F0C30C228AE133719765621260164BECA96A37C14A1D3363B3EE0A2BC0B6689385537465DD0155D91EB85FA60EA7CDB701157E563B2C602A15759FC2BAC4DC3BD4EC6158D64E4C32AD3747C9685B7080B8CF5E8493D1259711A68DFF3E83AEE0956095B368BAAF2EE426BA3F738F4639D8F8DFD6887C07FD1BBB265DA3324252A59318017101B50DACBE7268AAD9F86A99923E040F4335C63E265152C25DD6E322DC3A57D947DB460472AD2EE893226A0CB88BAED78EDA4A327135F58B11AF0CFB0304D27770D5C28587715C5853E6FAEFF405D232DC045E6F68C65BD4A70697BF24BD548ED4E6B0F4A8E973B83B789A481291574561F5581FF902E9F92555FBDB2E270090DD8C381DB1A388B71DF72B6E3A5D9910AE634AB4155609D7EE50DBCAB2B02874802FEA2FEA46E0B5E2C82F6E985E73ACD1FAB2366241B3FB91F5FD9D9796E9EF61F25BA9A6F86830499887CB429292BC43E22AA3BB0B02BD685097289262977E4CA24D3EAD68968CA1FA1FC73AD6C6EBC350D4BED8E5B99F5C86B8A205B5F04E75527B848F973221C6A7B6FFCD2510C7A2AB90D133355C1E08095973941F956D6C4D0C8162D8A5903A72620F43037E0CEC559C9EBFA1F5C40F8224FEA02AD022C5A75CD99054C0074167307E8304F33AFAF7509EAE4DB6BB8E5ADE9F248D90152F961A198D0F75EE045FFBC0F379CF6CDD58DF946CC65B8F636BEABD39484CB91D416299873948616E85BCED2D0A59B98443BDD824DBC3E7622D73EF048EA184C480960A24FADD1CE2F52BF858682C49FFE86833A8F7032BAFEBA2C03C67F4791A3D05CC307AB556B53B72B19F069308A5B4818958832B80E11C76411098EA480E6E61FDBC7DED4B3BBE0C742387B4370AD64D8B57DCC60A95E6775BB979BC0914DD5BF274A573812C0258B6678A3A411196A965DC4C9EF486B07E3FFC70B09BEFAB779BD58EFCF11E4616F5F43891CA1F4FA0486646306B607D8FE902042A457ACE72D9895241971AD6A60E701175465BAF161A9A14F29AFD32D9AE5CA1987A87D530063AF20F6543215293C7311EE7F6490D042FA1376E7FB9CEAF97F465815E6F7D8DEE8B671A923131E8A945B9A824F2CE9EA0F094B44C5D96B78C1D30EE1D3835685D305573E675D967D8771CCDB1788A1CD3623110EDBC0D915C2929F6C2CAEFD3C5847BB7FDDA8378314CA9FF44CA81A853B4465945115297310836AB9A5F6597DCE5D86EFDA96C13245C7E6A93889DCB04D9BA1B8CB5AE482D529DECC965B4FA10E55FEC6D923A6006CCF7D1A63649A0AA85FA5232B69C1C716BC1C35B644CF1BEFEF42C2E662E749FDC5D10FB401910F677F47B4FC2762AECA1DCF501CCFE0F686E479931CF45B72C679A4C9773BB275E954CEDBE12982D28AA9022A951BF1EEAAA4E77C15C5474DB649EF1382ECF7440A87B122C0F34C834FD967F37D5BC8C98B10D528AD54101E669128D99B48C9AA9AB62D26D064D27A1FAADDAA79E007574BC56DC48BCB465A54269C7257CA84571022AB6130420899901C5F9F746FABACA4A06504860466AB7E3CE0477711A80E747545B695153310A58D493CC1A5B56FD1C83408F5C964CC88A134BBCABD79EAB21584B050BEDF3BA4F60C2F194EF8F955630054F576323C95EED1376810DE9127229247C70EEA636C4F4B6CF6BE2F4FFE77E488CED88064F8F3FAF918F12BF1079555C0ED58180F64A1734DD4EED69A10A81211486C133C4A67B9E24B3B2EECA4C3315BB191FB44ABFE8F15A02C19FD93AA19852CC9A1D894736BD3BABE33ABC47960499C978410C4528754952FCE51A735574AA8FCB7B87B74A797F69EC53A7D4EEB2A9A62464F22F109EF867F8B2D9C01A523C03E2577E94AD8C67416B9B2C815B47A81A780603834456D0AA4419DD39A63EF25F0E7316F961C4E335B1ED341E272433890AAEB231FC23A839A30AFBF0DED4E196817A5D36DB8129AD27A1B5DEDEFA133AECC4D2C832D35031F73F8E3783A5769F7C2627E58D72D969E36453A6462A339E91EF343370C4BE1B1315FA2D7D06355FA6F848610033F4B858DC29DF5D67874DA65300BD5F42B202D51660937AD5C9C247293EC8C441CC4FD5BF8B55C201E858A103D194F1697D5D614A912FF0145B6B9256C923170E27BD65F21AE0E86A55F642C6BCEB9F90B2515A98B2BFD903D23FA61E2539B9112D96CD9D2A15D21F12F488B8AB8A589C733443091A79E7EF84B9E8BBCFC6ABE4EC0178315A059443850D05CB04CC74863B77A9ADB43B3BBA7B58FFC63783869A", + "message": "F17E0B4F668B372D8EE6661B1913BC1ED8C42533A9F555EFDC0259E84CAEA24997F96958384DA4E33E670A7CD3D16F5452F9A48DF7B70E5BD7439C0B6E769599633AED89670E187D511CEBB7502C33780DC85EE14805838582D16751CBF6FF291F5BA8064A7D1CB1DBEC937A3D912C3E9567016D9FB4F50B41380684C0F46AE49628487D6AC8E00F36FD963D11C4BD8956274535DB965168D913CF2B8D53AE722AA43EFB1A8266DA9DDD04F11CCE1F106394D86F669489D5236300D1A37DEC3AEEB30B30D4211D2E96ABC9646B75CCD9E472A9798E9D2535D5131C38B1FD8666417066E8A703830C0D660C8BC95EE9409CB2CE29E42EAA559CB334582E2B95A33793C355B5688BB29C8DA839F2C1E9096B4A6346A1BDFA04C51B5133B61F9AB59FFF4DB368558A00F96FE7DF337070EDE7EB77C8E134A384462BAA3F688422836CDBA963AFD0F4E313457B444241306F5BBAB8D8A207914863FC835D389E4574B3292063E0CCA8A0C31AD0727D0681CA88E2DEAEF9D6AC8D3E892F5770B8FDE3B7F94BC40CB8523968B2AE4F94D0D29254F4153581FD6EFFED2C1B32051152726964424F99D6BF9E175FAB67D59ABA5ABB3468C32B6648F949E49ACB566999141A84E94E2A8EC7BDB8419BCAF6B7E487F8729C9E256CF653B36DDE609377DFB329A21FB922B2CC57D38E3022B9FC6627452D43361CC3B6393D0B01F7E59B4CE86355C65DDE29B53BA8B961DCA6345FB564C3FCDF5F4308F000FEE3D7EE7510356AD65618B2CBEB410DA37A25B3B73820E3F06DF6D0B7BFBA6E7829CA6BC3DF22DE1593DE5442A5D1BACC961FFE766829C84E9BCD98EF4AFEB5AB5B579CA50EA4C2789C1CE0006E7FBD05E61BB57565C9D0C66F7968A19B7A3173DFC3C163D7A0E84C94634039EF38C8036F336A7C72956F1DBB7346F6F056DCDC55CF3937822D385097270BD4E78B3AB67059F87757874319FB44900FF180739F3827C529EF395C68AAC203B5AF6A624C83377764F614041AF92870DF95E3129BDDBA3E49D7BDEEE8BDEF8B5CA23D416B2425F3041C505977719CE7DD211A57361EA6F3F0D58672773B93B5508C75B7E00592F9EC193142D0AB14CF49352A7B723F18D2591E47FD1D120D365E21058C41E61C079D8C964EF1001138D3A3848471F1D65519B79EFD0C2F8683682342E1E3E873CEB99C6D49943189F81B542DA3957559A003E875B4B4D5A30AD62B807BF82C8C014719FACB91D93E8E6C53D3B0395CAEE99E3A0E70E9BBE8B367FF23D2BFF54BEE046700445FF7DA11585E709D890A09F9FE4070431B9168475D59C26CEB96ECDCF05CBB4355AD290F7D2A015203450D296B0E69ACD23B4BBFAA55F18806583B5AB073E39734750768EC427E6751129D4EE1C9C527F19D50D3F4EFB85D151552FC915264A194EFF330355B4A220E3FAF63B3069E5855CDAD1515778627A63DC336658DA60076515580211AF49FB3654B7A175F9BD94CB78A3853DBF2EA6F154A2AFAFD8759BAC6C24EDFEA0FDF0501F10762F53CF167BE34ECE761C7389F356A31F9F9A0A46CAD705450039780A371991A13921FDA4644239BA2F4072B1B1251776BB3519E1B059A81D083358B59D6E0EE8CE34BF1ACD5E54A98BCA9062F40D8858FF157846026FE5F84CCB02C8EBC574BFA366BF398E169C238B1C41A641E4E80AFC448B122DB25F8D6E3D216981EFC5DD60D257DC0884AD7A37960851ED44357E3484A8B192D591FB32C7BE2B80C3C9937E3EEA77531C8FA5061DF7BFBD82552C68B23D4B73440C5B59AAE89829A3882F55C5E43270AE2061D01BF5AF30FBA62B6FD7DF08E31F5962616B15837E6FB0FBBD28BB63BDB50437BB106ACCA67DB67F2E6707DAAF4548012991E784D5EB723AD8AC1CE77AD48267B27E4E3B2072F458EFFB6EF0AA8997CA102648302CB6A6094B8B3FAAC6A67A8D57A254370F583761D2043B8BE4CDC61846D39DE561DA0A16A55D8357E4C66D2B8743CE6091DEADAE1BAA1A26CD5B56DEE3246133C201D", + "rnd": "E48C9BCEB01E1FBBE27BDF559C1A74E0BD0ABE1527E3F56DFA6AADF6EBAE2015", + "signature": "CFCC68B4D767A506E2DEE986887B7DF1FDE091C9A4DFEF8F5F8A23964DCA77617B74BA19DD5C36C94AC78530CAF58E70413B3B9749EBE02916F61A1D7EFE87603FF18F2A2CFF31DEF6FAA4A9EE4C143C913BA2F5C10C0A2A39925DEBE77FB16484FD50F6EA70EEBF86B82FDC6B10101B43AF3752C657AC891C87A4EC94371E723E33E8D71B2128B1266A475AD5E128D623CC00D0984975FD9D376581070B13C3260CB8D8DA1A2BD6488FC70C6FB810C78674F74142621916B3CE00A52163D3D0FB3E2499E4914385B4CEC89E51DE90BA4AB9F667E5833C32764DC84B236DC00F241885D6A5119131CCCA3DE0E89A8DBF03BDD280E1C942601FFAF64FB5E897590CF59A7021C19A448447EC367C40CABE30CF897A91E6D9310B627D5FFC15A25BB6B4D7691AED66E4007866ECB0F6DBB8254B4814F76258FE7540D1AA8DF378994AC2851DAEFD23400BFB52528F72A38759BF5F22E237EC2500F49D96B54DA86506E0056901C55D829E0BA59CC2E36ABEC64600828E1179D5651C92AA1BE877F7FE541BB894E2B5B2FA77FB7CABB7789C8B2E5C032745B09E4FB87E90F7A8EA7C90E058083C15A6A6561FBE9FE8D7E6B62A34CFB7B1E48D7C36D3EC448D7C9BC8319425E4E6FB7CAFAA121B926415C503F685D1AE2CB99DFCCAE2E3EA17749A37A9C22E4E02880D99FD34BD2DEDE4C4E4E43A58F6B93F99DFE62BA49701A6A773F78B8DBB1E4FE3C566CCEE17ACB2F5BDB3F8A618456F624D4278868719EE203FEAF6EEC3FEBEC8EABA4213BA1BB60270091DF6E20D6D81A586EAEAFB2674A39785BB56423EABBB237AD1C1527DB92D60D02E5A0ABD98AFF4A4EA66A809AA85EDAAA0940FC394591F40D9031D2FC2D60AD97F8E33BAB951A75C5C3752D54E45202832DDECFD3879FB28D9C040C4D5EF78CADFA9C6780DB94CF0BDB1D6ADCE3C6E331B6CFF6A96A597233CA6B881FF02899C0A3CEC78CC31CF6DC644BD4675FE1DCF623218F0BBC395CCF8FB202782B606D6F1F0F6CF55757DC478513B8DD63EE2FA31F2E4C9B4BACC2BF35263B67BB9298C398524C53F1FB3043193836177C1957A6E2E1CCD3B1128D090D82C069F5F4CE0DFD007A00654585759873F7EBC394EE005E00FF2F375953427FCEAEBBB3ADDCCE7D895992F8E21FE5CED0DA9C739E7F9ACD71DC37876D94F920F01ACF00DD424CC76B8761ADE563BFC079B47469673BDC3B8ACC68564C654700EB9B35A21A27C314865DBEC2037FC47EEB62C3659586566A1F436E7FE14B8DD66C87D3D54EFD5DE81F5EFC76C8018632A2247CA5DA307368FAC020330965430FAADB029C0AF6185F992DD2217CA92AB1E23B9F3D8CC671D4D9E9FF94C5D817C264C053B79AA5181234035E983EB7FCA98424D4CDF711052B59294E764425239D2CF4F29A9A093C354C444597F7A1BD7DE64C253B27FDF16456718F8690FFFB43743E0358926BE4947379BACA3CC2239D53945758E606098AAE26E71FBC7546976AA7F450B0A6785289CB263854EE2D57D43F785CBAE9E93E9521B2883259AC8F440DC51BD6185423320590EFEF05757D6284AF7B62A7C86812D68DB8B558615D8DDE08203416200FCB48B8576D1DF03BFB26DB9CE92555804C9C7A42B8010711ADA044C41FE38AE5CF56335F6B8A91AFEE10DF5D824099DE9B4ADE1AC3FB44CCEF6CB96ED96388309BEFDEAA93C6DA9553521E80E467FD498BD7D10E793B7DC94E685DB456682CDC053C8E5078C2CD27D836FC57116CE8A1DB7DA39D66BBF2AFD3C8D76C7AF9C972651B240E1CBD50157C79CEA885578A295B4CC3E668B9AE19A16BE6F5D4CABEDD972624A478C1C2FF3B74C6FB2A1C90B320110FE70E3840D0355D29FF8497BE7BF6396E19A3F7C3A07AAE04225FE2BDD824C271008DDE515D74EB71A1B918A5E7F2D4FB533422F56EA91353C24BBD6865294B2CF58868340032A05F1A81575A4EA6AAAE7660CBA27B0BD7735E8BBEF9E8F71B1B353569C0C9821EB370BFAC36A4526CBB6514F99833C4002D71000EF65A42F806D1BC0C814F6BEC14F9A20C8B0566D48059EB3BD1B3BB6E0551A6CE3EB4016083AB166537A2129C563FDA3A8CF6C4B1DD46A00BA54ECC3E8AC08D5CE26FA905F9280CD66FC4B7A3CEAAABAC03D0C6B7ABAB3C961340A50AB9254B815B571D750E2D2CB7F8E0EAAEBE3323FF99A514560532BA1192AD5B2698F49F03106734CD63E747E9A2789DB32976A65D1AD36D1C4059904CD81F567333CEBA530064CB31DB858D6BE26C3C95E4C783B9D07D831F9785B60FCB5FA117264A4B5E08319299F5A60407536B4C1C7CC32F3DBA3D1296D376F8C8A7E8C801163DE845D47C07920AF629EB4FFE047D7B941F6FF015861775E4D048C91C6B59F06B4E92ED72876B8024D5565914BD043EB19F73784E1C6813376D06B3CF86F43690F25446A1C208E6AEA4266DCFDA454E1E9A05807C57636F4A0ECD925E63EF140D1284C098FF340B9639BDE032CDDF6A3854E7875C3FD3F014F2790FC6C49E719BD77352A235E84FCE90652876121AAB57B96BD3B0D9CB147A66DA8C26A31B21AD560775D14F03CD378D616DDC683CA1E8724F523D42BCC3096AB40F4A9F4A3C1502AE7DBC72FE79366ECFFA7A864AB3AE7CB05884C905200CAB8416E37CB1C944B0D1969BD8579160EF306C02693ABD91297DB6DCFB7721EBDE3E3F35EE53F92B0F488B51453E72DF159BB6C381546160F3C6316D3A181B98AC13AA19060990AAA0395AC223BA4F10EAEFE5EAA3EF0BC0DF804419562FFB89145D4E52E0F3F85C9D2A25204B391ED52636D0212A7C46BB6B3D3541567F6198CD1E580BF4DB670AE6344480FA9D4BD9B587BE4569C109870E6D9742CAF5A36ACD71E9B1490B35DED60D19FED617D4ECDF1012A59CECAFFB040A9012813C0D8B4AF3CCD95951F484F35B14FA7FA7A07F0D7A827ACC5682CACEC4F712C22C0D3486E5F96D07E5113D076F64FA717F30992C9CE5050837AF38E339EAB57B7F5AD137CDE9993BAC44ADF5621767E8C8B235D2BEE00676668871CCDB32E5C651AF726F1DEC1AFA80D79DF5520D29165CDB2720B687AF54EE42C7A5D01C9E4F6512BFCB1A064DCE6CCE97898189BE1173E415847B3374C1819D7AFB262BEEB0361ACBE096B5A74B74B26B47EA1AA32BCC20B72271B8EEBD1E3B4E9BE53625257D879145719C96A2A437DE582D711B53B42DB0222267BA36B07F585DFE58B897E6AF40814A1446672225EC259C885373E501CC88931AF7F358FE861E875852A917A412F624CF6272DAF05F9ED9934215EE58D5BA3A245AC1BCA4F45ECD151AEF6320C1488F38F8337C40971DAC7C1A478737660B0B998010198409445259F2356EC3377692F1D9558CF7BE671A582D13FADA8115F6DDE62F9A6F1EFF22259513E5553F94770297FCC7FC3BC730951143642F72BD6A29A780A667E07DE2867A9DC44392CBA5EA363843AB31DA2AF05C01F04289D1A954E682B510D8143FDDE22590453F9331A94387C03AB5E08FEC0576BE350D1C9B5745BB5B6E70A5396E1EA20A771ED9B0A21D549D56588C7A4D69C9EFA38F96750CC98122DC6B4C763F56F76F6716E36802A5A1336BDBC0E6CFE9666F8EFC9289731B399BC7541D2E3EB4FB5EF8E05FE401AF1352B1947844F46F9D6057676C70A67E49D537B60F1E817699075EC4EFCE6CF944C53CEA223B897F30371719BE4DCB33BF105E50D5FE53D70B37B0ADB848094FA68A46A2528915E5A33C1B8517CD9B2C8BA6EE5631C4EC182EC9FE5D9E567D1435D60058495F46E19083519F8D2EB2B6B05CD646943BAAE4B700805E9550987D2DBA5F00178D9E24EE24DB8864D56A3A519617C7CC267428EAB18CDC7BEBFBDF57FAF2EEB5D0DFDD8705A701DC95089C82FF6F533029170E288CA340548BC889A10788743AFDC3A815D470286C15030348EB0318002B3934AB142EFC13F551289CA104848C794C08A2682A2CC25F635966DB64B0EE1A1C5AAA884E6B02675A8023441D3DF71D3809E877C9A9E2138AC31CEFEF674F31C3AAE3455137FBA0991BCBF9062FA3A62A6D7E949404C86D217101F8BBD641982A91D7745DE1CE5FFD7FE6D44772A45B486BC3DE7D95E4FB63F337DDD59DF0090B3ADE036387670200C6584C8ACDBA478C26969C6552F8F9862C29D9A6236207AD365CF5CA7885C9D098F4EB9778F9EB8C30E788879F7E0AEA49CA606E11847EE2291F05810CCA64A19C46BFF2D2D99BDA3C8363E77C9B876EA25D52C8686C072D15C81810F1D71C7D0B675313060DA465C30DCE80E179EF23BD960BC0AB14BAAD1EA734F347F28D1703A7418F67C9B22E0A3FE69AEFF2610EAE2C953BF3B4A54804E9625C4C719245C30BC3DA39637620CE63935B202EBC4FBD94F12B5BF75C6BF0C6F8D4AA7A0E97675DAC32D00DB4A4F3F8468D8849BE1D280551E6916BF701C5EF848804E327108029F43B9F0DB94BC30DFC31B1963EB311E11F1BB2D19E4174F0EC2649E71794BBF36B6173FC4117855666E331B8902B979FCF0C9C7EAC885CF7D7F0CF2CA6F2EA26946CD32ADBC307803077D1AB7FFE14D5FB7CD9D021F4C4E8CEB20556F7D82A1A50004687986293F50EF52818AA8ACED028690B0BECCDCDE0000000000000000000000000000000000000000050C11151B23" + }, + { + "tcId": 39, + "deferred": false, + "sk": "9F5162E3523C1AA02E0BAE9DFB89A07F9CA8DB95C744CA6CF4AAD160767AE9C3A7FF4F642FC967BC3C645A8429222036A60F9418D35186B92BE26D8EC1DE9365B8489584570228D715221BA610E28CD73CD6AD9F92AB0AAC5F233DC801251B5BCA81C6F1274F720753931DB35386BDB83304770C5D59FB0529197BE8CAA0ACA387233753335153502373823668407331780522135801287265818206102663321627422001644708740453145874055406070356747286183628143556131380408870743613613158834526165508443764526884066637552470454457715858830788630522116362416414674348455480808271820101757103287020485208432165417765652072520371778038622581461526738560767607156110380413816265647602512116821067767504121464101471602652516707464303212287564217220401867271473804274856353383410842447761351360033448273306781277487060174480120476175585474683434385612168448544350076445111388234530078685184742303062454024111684133072631684142642424032513234683705818514161371200132567065403824778040443048875204438035734540314170451878153826780523651885004247050874824876080448815623722882350142670173123078515025263600311580601766472753363352632236230284854082552027660582450683234818087211616050882222408474721813411211245086077707136513082664701568204704587512871443240561168866562637786511070552181001740580542005334630067857180664757117057642275526337602836372215788181145257302286480750253033100870803636442436821035163165445166282376808401832831368352638683323268445162873305004021014608037085351830370120033708724744207801631543852288563176277056403156745682857553837368808760662411465843763631130672651356853701846531622060638764416235876005228272540364422325524736806158188786536804518463474735077774250664710361806541855661633704208660770486728112800244324364082455362014470685880371441467443342342207315888888826112274156231156704245770462516574301747547107081162273125760474460634442456177231233613178551050310464101421571321715357848738430275181147051254808223806485726356583015020830312246836552725265007845075108628312046412477657533085058261020158358611545770032504083033532435288604848833143556505702287437838702275580675034484414405023252560383013665226382515322764338531638441115450246455184218361865818153863734213010544456635658417726302178240728355546862575463156621526546846460214218367840627263004066204368818557580710266153627535434531066607783456316348525873800051285045875465216768325515664128084036528642621508517018863283427315555232770862264700572077282540117046714486317372602837012651150501403786447627341337003236850464675558513037085061176725484686583807630561853635648858485275325552311416744508160182442540820026022655527378713308346320715345238501668581654103865684506466502040622186151106131748080800526143332417477461038455472020408114305228857185780573186418467757155210437312713002723273631828452132311526212064125712468556746435274535013131386534651741403134427383618512288432623162021500470253663680544117186274278311221223608370828823258355705753200640482378388831743724082527430335318865366601888553611668052028728420273484641778236138463714835516104061356603470663820711636568135472518724606428685354571437841814335520373150308335122F2C036F38164B2AF7118F95B49A8126F9AE2796159EAAB46DFC77ED71BE709BD3EBE789C23958F655F177486CA3F0BD71B2C370CB86600681601818791318CC90BEAFBB33F7780F2636753F5DB671C554BB895A590A3C34AD859EC92A5D3DD5BB18375F655362CEA25A099A6A40E055FC38E481F61D5AA40B8F8668A14AB0F46AEEA5415269D0004377688E78E91CAFE42E960CD01AEF79864DC84498D0768702D11B520DC55AAA1CD4C264F34D254ACCE07DBD852CAF2B0138B4768A41C9BD942B705664B76246CD27FC37734879EAE974CA79F788DFBD0F7B521EEFD00893305E1C9DC448B9A08734E9672C3260072A602E2B168A0C967D68BF3589CF14829C322461045C13038833F250FB6C150CC997531CA425C4239FFE82BF12FD68DBF7E077EA5E72852A76E207A76515C3489A53C4BAB49B7CAEA9A1F6698E602A4775484BDD0E5EB12853EDA4A3DFA3171B95939268EB08954B275AF38A365BA24B7324221A603B29AA914C32DA873136CEEFD1CD3C6C7C78BEE469BFAF5BCB6C141EAD154B4C39E0212D5E60A46D692475A2E8E21E7563294C7DA38FEF03DB2CB0B33AD3350A302A5ACDAE59C196F7AC3B2178513B6D2EEC8E6031B9CBE885571DCBED47F87E5D5F92371B95BEEB02C57FC2221F2D3CC7DAB82CE056A81669FCC765D84CAAF9EB74550A5FBA065188330AD7971E3366FC68AC93962DC42DF7B3FD975A54E3AEE7BDB3AFF8DD0549AEB7A869548FA2C1EC173BA23B398208166BFBFF877DE96867237ABFE6A6C1E326470C638CDD3A1CE19F6A233D3379044115C374E8C4B3B21C2D3EE087363C53278B07F4F4422F19526CAF41688DF07E0054FAB839F4055C5CF5D2DCC0E7D9C96D86C558138DFB8060201BB06DFCA64212BB7A05F1C72501EC7650EF79222B62C251B0BA6BDFF869E732CAE3438EA6376E4E83E35296540DBC15ECD7E7E27A5C927D22CBED981247B6D58081B8C90D404C4A7A6522903199BF189AAC6308AC0580ED1D187F15A892DB3D9AA59CDC7AA728173AA0879F692D9F79CA021AE1BA7B439BA8086E4D03C25728D128126052D45653B707C066E178C54121356A78E775BCCB7CC11421752CF5CD35318E261B9086D3432ECB0987C6CA0E741577F738B1B49EFC3049F2CEB4BF09010C020C5336D8237984854D2CA866C47DE1B8BBEF2F078E6660EEBADC43AA9F96ADC3F024F48F48ED83A1138D547F354ED39668F4806E5CCAA92428F831739BB5445C79537B03E8C447AF88914A56CA3F165663E0C45B6400700AF74E90CF48ED0AB7F61E2274BDD1B10EF3FA4A2DA3F558439465FFFDC71212954C50351B5ABBC54799DBC8E7ADA4C479A22DD95A454F0BB03F0A84E6F4F5177610CF67CB26D533CFC8CC6BABB68DA632AA0ADE67D3EAB54051C49E1AEFC070CDF6DFBC9C03B322E13EA2B574657CB236994B0D790D93543D38C5CA0C4326C850809C429CC4EE3CBFA325902BF1594A3920129D33C9511DD8E439E768FDEE1C5755EB871C1BF14D3DE1C13069ADD0199731BB9605AE914E3E4BEB3B0DC6D50EBFC2D00E00541234D5EC10DCFD9B5210F9F1E16E1BE473EEE318808D5AAA256F50BD440D07D5D9BA9076A5B31A35FDAD131ACF3E41FB935ECB1C8843D024E158589000498E9CCF857B7952D4FE10797907940739D4F3D9C07CEBD8BBEB4B28617C4D1EF1F49B8D36FC27B704F5DDF0B9EEBE7928BE31C09FB1CEBE9CCE00A2CFBD49011AEE1DE6CEC117B211226A40CC2861589FE90243EA1A9B288147780565F202FBB03E83A2EAD79A7EBAAD52C5C4A171D6041069DE143D350A7827216903F641214B8442FCAA849DA1EE66E5180F86209A9F94D73A7C4A1968C968A6E69612AFDB3FD38F362BCD7D4444AACD293815BAB5841FAE715C128F1BC34C363AAC54570E14405DF42748F08FF1E528FC73DADCA7E5783A350D075075713BAE715C8108FF350953333EBEE230430603B1846F7183A90D222043BD7E786FF672FB2C9CDCA738818602A00D04279D60B364F3EDFEBE8C279D58C5F3B789DD1FBE6410C40B9D45D58F57E757A94AE7D1CC4AA9DC6116C1585F3C529345ED47EDB569967A4D79174406EE0E0A7719ED69C3C67CD43963FCAF4C8CBC8ADDA7D5C8FD2D49D8B18519F38FE80B3A9641B99B07F61C874F72D38607CD3C8AE21B11DA9135E26BB9E586597A9F5DD49E23A359424D87ABA4B59C72F9640F7D29EDD9E05AFEC72ACB2F463CE7DE96C312A9A346314B41D166B8905CEAB296967D9C98EF4477C26E091A9FF2E6CF186D72A256849D2F0BB7CA16F57302C06A0FA51DE1A47646E5E06A036FC5BF11A9475607788F76B91B4EE8475227742560A03CF234EE3530CF50ADC58F232F27AB52C371087D81BE38B1D6868E557679EBBA3B5AA3D0F3115AF1AB8058451CE78123F299F4C3C86CE237F931A2DF611AACCE6E8E5B134A1F09B507DB54F71DDE544794A603F7EE17A7524F327408644174B3D7EC7D7441DFF422BFEFFE5976EE67AE80AEA88597EE0C0AF43A7DDFE5566344EAABA3A49CF1A9B15BD11872F64BBB992030D3F3D9E8E7AAA3BD9BD3DDB2CFF77930965172F86EA244C53253D4A630137F7B49DD7D00BB2D890287A75D4965D407CC3109F94F6C8BF308316673E12AB7E83AD9292CEA3B5F1AC1EB6FFF1BCA4F16863AE454366BCBA3893956CD6FBE0644A82042E464A13BDD4680C5EAB189582D3FCAF88AFD0DA02928E904D57C7522AAEAA3E89CE8E9E116B6AD0B71C66F3ED605E9D006AEF39FECDA3AB1F1A9A1E242664D61D156CF37B5EBD2A41C12BF602E270A0BD5099DACAC707393A71B1902BD19820FCCC5B1CB8A09D095E4B8266BC52209E0C52BD98491712DAAFFA8E247F2B9ACD254AFD3A0D2D89B1CA3F3012B7BD033E8D5A60D244BC53899F90A2D150C55BFF6195977047318A0385D52D941DFB5B5E9503BDE5BED2766ACB5DBA7B2C645B193083583C48EB4637EAF6CD6EF3209DB6E8B6B9FE64DE8F6E78E322922DCE38BA78FE2EE9DDD09DC9523D47C86090520FAF6D0D6529788F77CB750F7DC9AE7EAA4D533EBFC3BE2A65052660B65F8393B449880441695EA1308D867F4E98E36BB37D02A84D9E36A67A250739630765136ECD677F072E20E52B0FAD9342932682FE75A19A5F3892A1C1F7B5963DE8791CAC7B5570578667D44870B32566FAFAD8AF812D9B416993BEE1801D3F526DACEE2BB7B1C22311B18AF9B39B569D2C2BB21D8CE5F626F25080E248EF3B42C2D07BE06EC2C6087F167661124AB24BF06701ED462C3758A1A3AEBC28273DF3E8F4752CD2D82819A127778F6AF0FFFD8D4E5F39D207ACCB90564F70B47A8744E113585043FE4DB499096EDDF1313A8D186ECA61F3D6E93049235DC0C43DAD8CC9BDE021DCB273BF82DCCB487C7BEBDA9078A0122A1D72572D8DA87F0DF2145C9663D6D1F4BC3B9995EB39B249233F34C82A31A6566A68F500C79EDB0D8BC812656716324D74BC6160EA4FCFD1884ECEB0CA745CE12DC3", + "message": "666342529637B4EE440E7B6780137833E969A054400D8679636499630C7D05FC7FF8D7E06A3228E697C873E17D99859184AC2657D98B133E43AC84BE1E4CB6B7EFF90006A4FDDF0FC179E0534BCA26E823B7AFC335F5F580FE7BDD4A41E960771CBFABA381A948346F5B4CCE0C11B921F7C6A87EC4D2779B9C82AFED314E6B0E48EC6505EB1DAECB367395AC909202AE690F98ACF8A86481C597C02F747EA80408DD600FC023308F72A02728543C325DB1246CDA5373EBA8FB26291BAD206C5D9CE9E9C2EFB4D2D5E9EC20E45160A8EEB36D50E0DC45EEF19F50C393F8197C93847889FC2AE5CB0104481F42658BF9BFB9213529B4F0D626E614A8BBB6D71D082E866F4B1F610FE89704D1B26BD406480B796A1522AB19F4C3A95E3ACE6206D6FA8A166BD30538243757D4CDE49ACF444F771EBCAD179345F14250588547406CD2B64C3A1855BF2A35182DB5F00A361401E3820FCFD88C46C52FC0922F6E3C650DC5D81BAED128D186ED95395E5875B2D57FC7C2AC4D31AAD1FA0C41274617CB528B0E65BD0C94C9A62F5D00835D41D270E8D8473A8EF11B2A9627429ACE00E3ED19979F2AE69AAEC601519D685B40F93CA70F282A04E4EA2B394B58BA5BCAF7CDC65CC4577E798010024C1F791C5476EEE19D64C6CEAA49DEEE1DA466ABB01220CABABDD22FDADA0BD5F6D44EC3D949DDB2036A6EEAC287832EF43158845606D69AE252663128F14C0B4F88552D78D2207628BCB187AD021D20EEFB2127E55B5E4C01C695FABF066EB4F21BEDDFA8722915593EE0B452D861774C263797A63E273C68FE9FA2E77AB40970045F0E7969462693C7660C97C64AA1687C74740FDFB8522A6649EF98BCDDBF4B777A9D79C9F4C09A46775F9151A3B1EE385FC43AFF80EBA1D9D86D2AE16D0A27F75E3A7739D9C741AE748FCB5A2B02D473D106C704B7A9B2F2D65291356F0ED642BABC547725BF3E26C8F1A932DE772C6AA39AF0434DE1B3B2B29DF818EE0A9F1DC2AAD2576D770DC14A14E56B5B6490CF6B7F3F0F2C99ED8C13C1EF3381883BAE5C05976E4797EAE2A91DDD3A6EC774A1D079A029B9FC235A1919EE5759B7DE274F5332CF0660480CA9F80C4FF306A6021949EA60AF8A028FD59DCF8FA393DAB56DD04114CA8DEABBD950B3BB8CF8F8E8A991EB346D4CF89068FC5DF11B225C5DB49847EBEE4F94047D57ACA81B6A8C328FEAB200F08F4DB5BC2F635E92681285F8CF26182A87D25B92DCC3BA01B5C0CB5BEF592EA8552CDBB07273C1AA26E04112AD5DDB36E721E8185A551C6AFE2730F00D8473AA253355AA5D004C70EBB5E7F92EB928E5B1D9E0620453DBABD638B0BEE3AC5F0EDA6FCBD5428C0FC884ED6C3501F3A2AFE5139D6D934D1AF10898366CC8D05D57EAE9ECD0680EF84E4673AF1E45E3430DA4798F40044AF7C64034E33ADA563B340CB119450047287454A2B88A135A25ECD311C203046909042EED1791824DF0FEFEC3796AD0161F677D93AA0E4F25B457C56688CB5539F7851CE95C20AEA608FEB007B0C8B2EA535BDD173DFCEF26ED8A0DC5378B4BA006AE8B2C552372FC7FBA8F99343CB0C11DFCF2D46C5BE883B2710CCE1C2D619898E4446089D0E6452F4973257FA297FA582AF39823E4854A0F15FD3C68A146F2E00F3BCC3709EC119416B8F2A6F798AFAE756F622041A7D4B17B6A76E27B5BE73B191D18514670C78C14DACBB937C6798BDFB7C389810BFE278D12A7D079256EE272296C71248E6538F8E42C40CF62C3233AEF07E93D5A64858E3CE0ABA9C071401A9B1BFAEAB47AE6A100E3E6918D646DBE5090EA65887D8E2356259F750739DBCBBECD34D08274CBD96D72BBE888DCB4DB55B3E29B3CFEE7D0EC7C5E80545414BBCC6F6E4240C371332C2764704E7AA0B5A6F3C91BF5A73A2C0F7493F3A8F801D1E3096329925BCF1FCED843772BF7457F7006785526F7C42F99009D10E33F0C709F8F6793FA10BC1F49EF12BAD7D32DAC857633B468A0614A9C5E3A4E7A190FE1931B4B58A4CAF6A3BBE1F68741618DD34E1729F221A08BEBE70B5DF1B477004077541C65A77BC4AE695454F48B4956F94FEEC67B598636AF81F3D468795FF810D682D1985BDDC215928379574F0CDEBC74D651AC88D7C248EC77426A905631E2ACA4016A05CAD0A09B4E521CCF2326C35D65BFAB42A4B4D7ECD6622B7D5D63E59F497A76D03B21338193503CAFAF1F4FA3C0C7F43CD12B271BD1A527FD5233EC8B01CBEF72CA832559FB7C6DCBCFA992FE607EB14AEEE66A38ED4054617B2EFE011C", + "rnd": "3711CD61AE1E39F7801877C3683748BE454387655A043521F8219FA852DC0C1B", + "signature": "2D9A5C1DEA8F5ED462769BF45A1B5D281B31ED6F16CE8B547A9D81B7B12480E495AE568A8B18F5BEE87B80B574E66D0BCC8F6853739A949C6888D6449F21D6F61A9E8F19FA163A12B551B50140E3F49F5BAB5722AFD390153D9B5258F7041AE6C4BCD8888E0A056EA5B74340E4D69124B9349B13D9547975A79FEB60D5723B6BAEC2D338A0DA3915FD187F52195226A3807CEF8D57AF65736FFD81F10BD58A13F05BB1C28E4E97360BA67711CB534170AF855269901BA3F738C09DC6B002550140CC78433133CA7BDFFDFB9CB7EAC0F3AF757281AEA53C43FD5D09F4F4575A25416F050C8F357D2713723A4F365EC58998065C57EC0FCBA4603E446633D40E4404400C3EEBBACA13401D9A2633357C565D9DC774EC47455EE7FA4E3B6D05E8D4C32E3EF8A07566068D01DAB05D6A14B864E4CAD161ABEF192363573C1D3E38A7E32C62AF8D21967BC3D5DE317514E5A30891C1B207FCF996B9DF7064A9BF338BD2EE5B9547075431A84CFE4B7EBC3415F527606771D0298EEB6A7C155E4F5237C71B89AFCB7B8B71913D51EB20E304C27A646E053218CFE3E41DAECB93E84FB0576FCB66C84AF9E78467AA0206D36A1B3CE7BB83A6EB80F6FBF569B5E82BD59F1115E4EF608FA471FE3ED6E0E7FDAA0747EF0E3CF740A60F689981014F3AA57D40CA7F18805BF0D6471BEDF9FD04B50701CACE98F78EA999D4CA4DA767AFE53E7A228413CA8EA5C9B1BF1DA0AFC16A0B23C3BD9CB07D3EA28C137D64C86C9ED9FE8EAE3D2D88B225AA941D353DB5F9D9EE01E90E48F52C8108F5CFD8F12CF6347F5B301D5753786A26CC746F6A6DFACB3A125C4CC009B97462D0AFCAE11BD43C9856A38EE728DF44A995AB5E8D66FB1E12A3DCEB16C7CA4CFB38A4B7FED58773BA7A96E1D006D3F361CA0F7D17794F8FEE001FDFF62CCE4F00031397FDA5B817DF275A60E37F63ADEB4A2B3B3E46ADB3626800D393A4041FE43FAE1E72354C375FA712D3F8FBE2AF6D2E9D90113A00D4B15C7E4E8529AB1FE12B6F623A078C28BEADAB11753B3F3590FC1064B3BC7A461AC30899EB67F375754D2B4D2B0B41D4411917CCDB2DD198B540C8F0D17A12F832C4E202E3FEF328A129D40FCF43DCB3A9211D49E1D71471C273A8984A6B3A0C84FA98F63144FAD648B4D606EF2E1C1EF518D57FC4ABFB2C55098DC242079D40C1CD0890F01E747E4286E9152EF42EF2F4C2AD0FA5BF3F86BC8A1127AE74434E0283846530210E1716EB7D8381579C9AE937A5D21A3DBE23EE7E7A521925A20BE48E5AE3B00CB473D04AEB9846663F5A2B87F3EDE31030DBC4F65CF264FBF011CC7405C4D807DAE98DBE845FFA86871735815F6D045C137F3903FB581EFBD1AA6B989D2792A1816778FAB55DDF814106034BA25412FC43D773079FC855B8AA1C8F7CBE7545161A879730AC3C46230AE8A20A6180EFF36695D886CA575D298D9348AD934AC34F45735F9A790462332F1B22481E11EAB21AC84800F64E08C1087294A22A17ECFCABEF280DCA36CA2D10B32BE88F526B2E381E4EEB8F82C5EAF14A6D82756078A99416FA331CB1BAC71573375ED48303DB31BF34A2B96FA96E3EF3B5A09D0D4E037DAF2D6879C7296B399EA071F9B50DBD924218C67D30DB92C648E434C9803447C95A23FD28C2B299B50E7FF87DD575CB3D8ABF6996A21E756BBFF83E368C0CC747A75C47D55925C5761F304885FC8014C8D8FF15800A25C3DA35DA5FDE6100A1FF86DE814308BE22957A37AC9BDCE9EE89EA44D0CF48AAD3FC2632F03425FEC7ADB3EE2CA5EC6B3CBE344D6186BBE0A40EF8E52619679DE54C474CAAE2E09669D43B514AB48BE187810E58621A6B6270A785EE5C440F1A02C8758574E0779A9CC11307EDB501D8EEFBF1A3F3DA9D11994A7BBA4EE73CFD41B9F450AA774137ED4FF90ED00A5C841C06DAE8C90E98269FBB2643ED1408455C511006DC718FD3EFB88A8B41FC996165622387C1F3FEB27506B053F12056D19E21BAB7F1DE32F6170EDF2FF9F5B7870CD21223272BEDDF6E21D2A3F88B2689130659F9CD3654FA08F8B31914EA5F8D70D084E28480C5A690CE32F65F8EB562CCEA4330EB7A1102013F070559575BEA5854E7C3943CBF9892C428A1B3C8D15D9EED6EBD371EF2F207902D6826CA81ABE62A83814F322C240C3BA283A8D9A5F54120C39F058EFE366AFF3CB1E1C13C66DED5DCE1506428B5E601DAAE7B30607D7AA3EA67D2E885A4114542ED2063D84BBC61BD661B5ACFE1BA914507E0D655F6BFC752B2F93B997363A9DA6A837234670AD2E41B7B31A1C75FC0B99F66F6F4E9CE08AD54B9A0532B2932CB0EFD127AD24AC4BD36123C5F88F72D6ECC9E16DC2D9D6E8162CC6F3645D840A2F54D74AB1EBBDA5F465FA0DF47B027BB6C4EC0F51DBF4F16C8C9C197AC908886A516F0518080171FB9532495C66442B3F2920FB49AF74A23801B9E9D8C3DCCF85890100354C4F85C2F579336CF2193973EEA6B93FEE9B4A446756BFEED28B64F54E31F92627F206103E8062754932103DA2DBB120CC39CA8274E658FDBCF615876A9F76EFA745899E6E50EBA5555A148078AF22AD9C6A8F13B1E821F8B9203528D3509FB3B583668E3DEB5234B9A1456DAF8595C29F1DAC002F9CA6CB991AF8E6945CCCD9679EF77F449746815A05411C3406809CB39A64E3EA0026A36DEF5364535BE7094EC1B785738B9B6F468E66BA9BBA7DA652810103EAB853C51DB5754C6BA60128115CDEB89772EA0CF90F9299DF85F2816A0B2928711794FFD404E8890CCD4DBBB282AFCAB43652763181CAC8A795ACF1F5A454C343586AD7DEEA72ADB0E173027A329702D0A994C26DC6CC9E1FCEAD323F1E8FA1AF8F7D53D966B03F6C89BED6E5AA6D5933BA4F779CE6E49DF847DA5DB7233CB876CF828E09DFFFFF74B42E93E940CAE644B07809C0277053E9006C7630213CF9A3AD0B6209DBE5D2CA786EAFED7B71817E89A0158319F7D37D92FBEA14E479F89D76A433010928921336B3B1623210101522A45040B13F258A6711C0074229741EC4D0A32D7CF3D5316DB30C445D16EAD878DDC2F8093BDE9A50DD90423AF0CAA024C1F610F4F0E62776F530385D9FB78B5E955DF5089F447DA163584217C6661D8EEE5857A9BBCC885C8A3A0FE47DAD4C8F2D72C744357D8CF3626C3882A98F1E74FD94091DADC472D51EE377606CF1904CF5A79F4EA26D22361B05A6A74FD93E6493EA463BC6BDD096131D9B80FD637DB8C23D902DD00EEE3C685DF2CEC6242229C6E922AEFE5BC7C738D5F642163B5DD646287D2A998C459D13067D4567EF63D20593665BA9D6C2638A50D88CD89D74FF213792978D9F826AEC33836271B0729FC17782395E235DB12D8701633C200C07EADE539FFCC155B372288D42016FB3A8CF0FE101B32209AC441BC87353A07EB23B9E273E4E4FB7D778C8492D183B74DEEC030846B0BCCC56DAAFDA649E99BB21B12DDC610DED5F573B205B87ACDF5C4FDA43AADA1D39F0CF31B57C061320A030A58AF342B05B23651ECF8A529AC0455E2376956305F1A2DE87D6AAF854CA4198A18D88E791D94C0BA6C373D789C9D6CFDB05034B689B0143B8E50F4CAB95CD6A748C5FF0FD6781106D6ECB88B647AAFA713B15E082DDDC96ED2B05324FA8AA61A2217B1FFB25DCF7C61A01B984F080E2D91C2C41C94FDF9F2697765048386E57091C8E63724685A4FB0F13443272AAC3FF4EA189542788CF494CA615BDB2A45C16EE31A3D89805977837A55E9067DE47845EF3518B555E05E8F34466114D48936CBB6BDF0B6D825798A13299BCB96C8370752E0657E340FF4DF44B76CBE922532A61CF89D06E25C44CE63A111853D2961DC635070841E4D39DDD5D865E1DDB5B0B47AE7ED9707618A282CEEEB5F0D4FF78CC8E34738B108191772BFC0BA8548EB9580D45C6AFC7B0A5C514EFA0EB6316D813F48806B0091EF4316F86F93502D498C3A3AFC21ADA0A84C0220A888DEBB59FAE43A40F4E8B779496CBC36A8CAB83AD60513F31CF1324FC045ED4C5E41ABB94EDDD676EF8E325B4645BB8585EE4E5E25C78D17C18D02B1D296F352CFBB3AC8FE92C1C41DC6F59B01EBE4B69509A9A4ACE60D1C2131DB39061CB4FEF6E0A9FF942D13D98BE2A5F05FC6DD634066A3293BB0C0FEBE17A5B9939600385130E6CCA8BC83DFDFA75FFBC9EC6CC92E4B9C2BE4689069FD562EB585EA6ED3A10171DAB5F41B80888C00B2A7A18BC036C6922A7941403FC9FFA2A3EEC363CCF35CDF07A1DDAEAFC28C0DB9E75F2A4138383A582369DA10A713D2C2B218B8268159A961738AACF2CEDB45A8E219578B69A0379D5365023F6D1E4A5C062A8A1F13F900089A46AA7702287753C990338E2E9156308FB51A4FBCB6BB4F59E86A8BABE79FFFF7997825CA3788A66D2E34BB53A0289637B541A75FE84A4FDDCA6B176909FD0344B05D049C0BCAA846881B1CE020B0EF1A5E44844E222B4A345BE5659333991322F6186CC243095AE2D2084BEC7087C0CFBB427FE9528A266EEAED7C97B8F0F7C44B7C9F512100C9E5589178BBD0C1098C39C7AF6C3DD0196C62596C0E07141F263D8285EBF409155E6C72D0E2F3F94456979EBAC057A8AFD704112E40B8CEFD8695AFB9DFE7F2000000000000000000000000000912181C232A" + }, + { + "tcId": 40, + "deferred": false, + "sk": "5F4907DADD3BBF8744FBA19CB11CF2D3E9E2C1530A1659496E0585CC3E5CF7D53BA1B7CCE9D9C863A20A1B4B54F452133EF0DE4EF06A115B08F3B9956CADE9FA3E227BEFA2C465BAE9FBF760FF37C809511E8FA316E7FE64C881C2362FA1D7387670B4631ED3C9592F8A7419583EC55215A49AF5C56F838FED8A08EC158DB2F801735207762158061647336216358042330080005772680162715880838061517283545480743474267483032160575114205718322343526658361288166735684026734586875126348884637402542258373335223400073077546866381522137408051612887673065404740765023788370075068032225546076074267183056441464431726178328024212674736331660457607501178501812241742345680142015243018742572724614215486675664753460014521722602437104860704661405172244888522337034178213784781068521347004484322571052208601320055503134305170740034054142578420178647772626222748566181244653374447610470171715347843317336546461770852468010812014347580211088344154723061807035760720105553788353566421621454777480882322705382421322172853278807334756768684285820235326622800855281612345062024661837411834632443228065022228434680448107472816881835503386158083648400857813537524352536845061735203766185746835323827121277705251154576427636022547072742780823573725423164051301415640332474367414501471325701571843178630556031537364151572467834300054704035774805836231511178184361511325421822067643841837323167137718817610443646254585664667044561106313720110031720132104576770138733104270571573617808747155521154126484177630386438502203254602873064145336630763574364585361435014164676340450874747305672517211271471717117133623320027700710383674060325250125783024035515173263077310814763432341036611852855744318407035846230805306003048507476128427254121447744065803137373111118722334611350888831144634067012727424301332033220468004578122370804616245052023372467665372213544000788068446403578453644434155001047270060775658047271867222228815115126348072685777264033463064156668162833868042813430158188607152515824550520700517388306868582301307514718718836053244566802816888545522231446527762122767248661152560603852522716665085704617268013737703184134341218451720718140203365113543808813687400627840568187008357161034625363052765738767001337648876648575725582467541545038304512410836561375730120340817064641330114184786537654450622560840637172871566525143567106274456067871705863513742520082833856182771328428748763485823577478102545306378682526260876483662261233837220683758035136548706744613456610845218412746275831018871843737878157033866662716208076118163030611881773235760654781685722467125156520385527355473144660841188656653154523023832085784374801205264143158571108344404777478048346806504265152871251610402262281120435826858681325680315708148738781314766755406744125241670424624703710561887124818833134000143403180016788024656202435840484628811570377684270277514702166828520202085531476770354624275317668248334876310544357083451622484226685373028082231224466136260227655215521606383205160704341228208648356435276543820628834087221750786215453554306358715267015443364822617555473731322257861888825760273282874214121552865072648270314820405717862171340071676532448265341446085775164878F75ED5D97F994917909D08A0462F133B7131F17619A4683C9DB104AB6BBBBD94FDD3D6721B0F12575021288B1FE48D1D679C36FF45C259AFAD992EE6EA8F1F69CBB9E3DF54289F41E9D62B1BEDFAC4F13CD65C84218533D4D0F58AA78E01F0529E7B7FB9476F38FAC1301873F7394BF9537257D3A1258A264617FC2F109B94DC42B5391C0B6F724A121134D064E6091675DA25CF069F5E61931F73B80D73662E28969A642161CF7B8C27A8407F5CEC064B60285131C509FA525055D77EE8938B6D39DE1BC74513BA8889E53DD34CA1630F64C8C5E129FDB94EDB97551E8F637927F64159099F6DA61B73C10F22A9B6BB8E7AA556BD683954FAB2776FB63CB7B9E83F0FF3B5500579E47C1B8CD8C6E0FC9DBF87D73DCD08DDE28BEC7DF85205964452D7206C9A1E9D3C0707B882B46EAE2F2D74B28DC240B4153C53457CB45A6D114F16E83B930B10CA7A7933AB7183558268A00D4B9202AF6470FCD091E691E5219D85698D1869E35C565B668217B36543E99BE2A659BA095D531BE91D0551E7AB01A347CF00B0C0D90E6EE8F9DFC5DD11AA8CD0CC38F86A0D4618D76B3C3D2CECBBD9AEFEA563001A67D55A6C689FAF90A22C1A26FE69B2CCCEAE7E085246A758310F16BAD61B80E240EADB4510A1B1A007F6CAA3B79C0DBC0AF3FA605293842831A4D5A8CFEF3DD4E0D93DB39C406B988ABEE5BAEB88D566C645EA2A46B0E0301E3BE80ABCA972761780773C7BDD359BC4A5F6E6E860AA6981E8697B0809C2F8FDB308BF59EF7F376E9E9A2D8BB6CA004B6BDFF3734E3DE36FACD26900F060E15C0985E95D58703AA238CE7D3A05C7A9301FF9A755727A2C48E8952E22F6CF6D73BEE4128341FAE00CEC74164C8DF7DC2BBAE65C46BCC05C38CF91C62F6604D1DFA6822179A5686317C0DDB15A24E91B3E5A639B827FDF6FBAE555EB22D7830B8DCF6DB3F0BBCF56A3FC71B1D72E32C2789A4E6BCE4E2273C1FFBED160C334D33AEC3C196B6AD9B0C25760021FC7553DEBB1D2E24E1D46F083654A653C05AD0F2E6050D375645B98409B10FC118CE1636E852BD2C77A3A53D681B179D986D1679924FA7C587EEC39B70E014055656397FF612B79BDAC6C5B15BF854DF3F85CBD4386A5D9F3C6490D6C89D362C458953DD3A1337A13753E4324470C032F50E2E4DDE7F3E66C2E9F95035F2EDDD1B4CA84533B0FF1DAF61AD0F7099F8DE106F0786ACD1FCEDB7FA9BFFC8B026853FF4CF970744394C0667FE5447ECDCD99A25837838A8B9B0C55EC55A1FEC97506A30E207907FAE78453A59EF719952B7CF24E65A937E3A7875C9E3B79F13E179CBB1D01C462110286AF3C2985072AE94CE3094273B3613BA246693C9CBD5FBA4D13D5FDD4913E202159DF262E56183C822F8312CF933CF8120A9F6A080CE975B85A32A800C3AB3BF5D237E614F5DE8A953F619F262A9FA78B61FFF1C8D2C4CC4B71E83300EB12EE49EC00E2F89AC62E90DEB8B97DB4AA467AFBF5B0AFDED5FB8D654648D8AC3715157059E8FF9CC2E52349CE6A32A01AFAA2E54611B61901B7DD9BA4F3BF41F55A4D80DA4341AB90A84AF3D370F82923F11ED4A5275710F205FBA6ADAFE57A965DF94E54D4C5366729810100859F209B624A46FEB1E209EA02E0302DE4A5A992AC37356FC5D0AE541730F5FB1B51E39289BAF7CA375DC84BCB9B7C1E2C87C05689CAB4F8DE8D0AE4333D3D6F6653F7811A1A024024F99E70D89A2F944C81CECB1E3BF505C6ED4895121465529AAFF12FC6951D0C311B7D08C97A16C69B9BEE54A74A003AFE2A8A98BC48BC22429B2DA25B48B487F4BBD5F30D14FAEC3958645C1FFB1E71C3CC9FC65F97202C0F888EABC7AEA621243056941DE24F09F5FC534B8288C56C2514ABB5CF03C7E40E0676910E5F16B2561B9BB6D2CDEB3AEF95FA828578CE009A65CE79591245192A33210D713B6FD63D7DBD22E358441BEF29D8E7F7AEEBD7664AB2300358CF78B35AC56587B5B3B1C537308CB6C483393DA6AE47D6FCF665F4DD2F5252B0892EE3E12A40DFE3A38EA65BD40035BDCAAA733518D453F9780B657A11C9A606AD22FE771138919D03FC5B3AD1C925E045BA522D872B147328D9D111606417649AFC4A823BE4093143A96AA3AEEFEE8732026E5CC704267EB53AB00857F271B408DCD48C7284174AFB13ADB60FC1E5686E5318890AA32F54F449F07400E21ACD68976E9C98850EF9C68C5AE2E9210D0EB79BF9311F7A0490046E8631D2FCFF51FE898E5436A62B94F036E695F08C2CC2C179E3FF268B26836AE51FED6F1BBB3D986660457BD80D862D98C00CB840B3C3108500463FE10E20C21A32F936859792FED3D6A0927032B9929B15C783E78DC84BC931777A563A2E47123CBD38A5F7DAEEE8B0ED18AA8B72DB2767A5EE00C38D2CDBB5CF3197690EE1693FB26944DC24772FE009A661B2AFCCC4A1B4E4BE8A71D74F24E8CDC676044753BFCF423D05CA7929AEE13842FC81B82D6CD5D9675680ACA1D5B9A7C36C5F4FF85F1085647B81FCF38F3A686DED1E6AE5E9CD27433EC862C570342D48B827B52E478AF7148E90C1AE9ABE1C7CDB4B4AC14CC5E9A0F469DA306D24E49764A610AB8E2D2A15215F1E4AA0520170EBADAC390240DD4B01477C21CCF5467FB6E2458B1E76EB5B0822DE190C6BEA190CE8DDB8E359D80EB09EE3C90D75642362DDEF90A4784ACC5B7742EBC541A601E4DBA4DDBB527687249FF7DE44D4121844CDBC909A9E1C4800CC76630145BF961521C5D3AFCB6234380A81690656779FD6EDCB95B8E2BB92E16CCDA1D6D9BA1808BF803AB2C7E44A7A5219FF05AEE1F0E57DFA2A4E5F84E5B05700E7CA04D3A6F0F8D2465A8DC7593D7AD5F13B00091FB6A81C9B48A10EFBF6980729F64C5452485A8F94A023268AD707ACA872EB87BCFB5DE783283BA7C8596021675E7500AC298019F7FD0E8F451823BF6F7D8A73931B4574510914670E3827346DF29752724C6B594E68A967A41A01F0E1E3271D64F366AF0AA01661442497F0FDD4869F2B7FD84E3A960B7761B4902ED4316607022DCEC48CA00C3D154A4DA13DC2524A8FD56201BD641BFC3996C4E51383C9D2873ECB1B31F64B5DEEB0C1E30F5B3418D253190D940ACD891005B78AD52F4CAE6FAA8576A7B304A6CE063A5C883E306E87582FAD28EB7A7D2204DDB1885232CCD7AF4895E54B98B7E824A88AB1FE35C6E4BDBA05AC4A712F4E431B70DA1BCF8321F7A3E116C519B54A1BB014BF31BF3521B6F6D788C229AA2A4E4CEC92539259D4F518129633AFFC914A31D149E77CF81A525909F7FE919644BDB18030D31D65881E231CF4D2E0F8A5137BBCED6F5336B69DFCBBED4C02AB92F604A20BABE3F5F4960E109F7B17FAA751DC035D00D32C5B4A4296C2FCE3032D50F62CC1C65CE11E1733B51D0F0EB99EA0E46DABB54477AFE3BA0E604CBD3D9BCAD3C47ADE33373474A210F1B0D9085FC322B9C3FFFD2E983887D5EF0F28956E96DE322D4F6D4ADF6DF1D9DB35D3AFACE2430DA4", + "message": "CB606EAA2755E6C407B02BC3BC8CB09246AC6767C116E70383AA3BC920D9BE1ECA482E28E667F46C5CDEC21190FB11616A0A42586260BEFA8855111CC143A2C9C1BBBECDEE1B9D8805C9C78010705895C6FC0DC2A380D988151D4384F0F936235ED281E890D75E78CDE5D83BE8D317CCD90215F767009B43A34EA44D936B6EDD05AF53273C3297DBF474C33EC47DD7BA6AD6EF5ED63BD3B2F9BE1A27B353EC91249CB8C08E81A2C960EC323AB29502BE7658A07FFC927ABD70E2A9DFFBF8C827AF76D4C63B4D120A56ECF151F84394A39E161F7B7A9B08F863F40DA18CF9B5523D2B7E4738A0D495D31B1B048BDDB17D8336D9B14A05522EBE0C6610E3E62571F17D2EAAC118D977C76A81CDC9C605C904F087B26BA7CF6CD5405F12179CFF55E8E5CB90A7B66E0BE944591A72286E1D1F7EACE23C0E57BC0ED6602F23C2BB2085F4F638E42448B1D3C3C1C264DE42367083D5D3BD8449DE1EAFB5EF6741CFAA07BDF8B55FDFA1F4516A6785ED756CC3C5C871F36CC2DE7DA9551785199A1B3B49AE38D1A208FEE27642969B02F2343535CF89837D18583F8E9ABD5EC11837E8066A7822ABA1934E4BEF0CC5026C1867B4D99D508221A6C1D0E37335574AD1830898081B5AE80FD2200BA423DA292301D014A8929B3F810E86D20BBA74B35AF012E6EF256EE97C5C6C389003302C94DC9EE8E9B13AE46AF7BE7704D6457B0BB00FD5506E06C2E9B9C6E27705373F868BA8503680646AC56355F5E758A2423FE33EC743B6B83C2DD5684D1BFF47BFEDA6D0A718855F4A77538B08AB33975207E1E2BEC525E65633C1D595CBDCBD516C01287FABAA2421A103EC2A0DEBFE026A342AD850B3C016257B523CA6014D647D98F4A935028631BA3372853B0BD185FE7C9618403AEA60AA5E8132DCDE5514892835DE71FC7F014D6A133B146B75A6AD2E1BFB15D68CB37765A6B504D49CCE6E86F1B1B27FB41978ABEFCCEE61C65114850679ADC39A7AD9E85E2516F8AD3D37019DDABC892CB4A8C8BFAF51659BD68BBCADB111D4D00B60AD3ADE335CE2385B41328937510DC236174D7DCFFB2814C69282F930087E6A8BD52CCA4B63CBF6468EAB797962680EB5DEBA8F3E5BE08D788641FF5329C706BBACEBA05FC3A0F1A78CD9AF88A09B0891D522F70F391676758B8EEC5472831F3E331A146AF9E3D8D6C9C955D2551906739672D649053AD6C05699439C76BB70E1AB05A1A70E9E03AB6BFD490FD7CD0ECF2A630FE365CB44D5C22309FD8F43D313D92C9F64E831D6A5553B144A0F98E35F97D3DF4ACE490E4B6A8AD8E44459E67F4859A8BA2DA5A20AADDE2C7317AE5F9B074D5676C31C6C81E7CC0A8B3B848482AE2BF96E33EBADED49A3663BCAF51874151468C8DB95AB41C8DCA6DA93ECAD141AF7682F2374AF7016320B6F5D355D8DA79E77E9989E79175B1CE3E35CC4205512", + "rnd": "94D882E5E35BD20DF2078CA27853204705F51CAC298C776726A0EA6899449576", + "signature": "0A9D0D669B0D9112ED2BBF4F464BE80753D64C9D065514C8B401E5BC78E56E4EB2C365A3BD440D96602E04270F07CC9BD609BD966C07C1561E48193F897652A9086C83F544EF794CA205F43817E4504B819CEF546284941CFB518BAB745A600AB56D7ABF65E784521D4EC35851A96F4608311FD71C714FC628E59954B164CFD93F84F0D5A69D9E06BF73B6EC1C8B7F36B519913B1BE75A992B86D297A97EB13D734B4E58AC80600628554AC3313A6AEBE72C1760C1A6253B986B9CA1F2043F53A43E1A9D314377701D9512BAE6B587EB821F7E7D36E9EB941867E22E11BD54852DA0B3D8701F7F49DCA84658AE4B63BC1FDD559C30304038309A909B29F2704AE4E7242EBC06F35C709C084415F0B991EA7252BBD051E6F870BBD3D24959E8C124532F7C6B1264C7BA18550500078D62030A39AA4E48F31350C87897DF0CB584F969DBA8BB1697A6B9CBCBE819434919D90E6E997FD7D8EA4A2C4CD7EB655EE74FA8B012E166F7DBC757430E4D751AEDC1DF217BFACE42863331FB83D63A807D2CCF45CF39D19818C289F3EB7E1F752697986145ACE1EAA4947DB24718D48F069A4D57C952D6E8D9A4C260B29B6377765A8AB3317B8F7ED3F4939C9763B52750C066CB6D0859B045889463CA1FF62DACD9AAF6153532E4FE2A32255A3111DEEDC8631416CB928C6369184F6E61C8EDC09E28B6D382CA3EC31CD05823A6660900070E56B3166DB65E254C384CA4F91BB2D8F3B1103A67091F17A517865D4443DE85D940D9AA2A280C3C8460F3A3F435C4513ECEA54C0F0A1CB834988D0F0135DB45279DF57005B37D2D340FE96F5D16AA19FE574DD5DAE5E1A835E974E2A1FBE6FC6E816422E4C5719AB42E0D78897117680A29FDC3C3D247DDDA66B5CD1A7869362D579C5A12F8A5937714E6A8FF451AF971DFBA9C7F84BAFA24F5226C2DB44C0A0DC2AD7502B52AA097644DD9C89FDEC6BE25F5CDC99D6798AC79EE16297885A26F7BCCA399A17CEF1EEFAF0B6C44C5C43D405EFBBDC834F20D060018CE5DDDEBF8115AAE226A668DB4948251D92F965653296A45A98A63DB5071077FAEB313D81ADDE2B21DC86B71480FB92CDB38DCF610151D7005C8554FC50AF9B22DC9A58A30C5FA39DD78A0B0BEC362DE3B89D3BBBCD19B8817800AE4CE15B0D0DA4597A62B07065D3DB3CA3EB347D8892B1D0A83CD96CB9CF8560A3245BF506BA1D22D12020B04612662335FE1158846CF2FDE49DC210FA2BF1F4B09C4DF9BACA7735662246A50EAEBE0B87275A0A85777042600D7AD6C7FF6A0DE53446B82C086A3BD327474B101BA56BC24754188D827B8A6EABFD3F10968D7693B7EEA0847439890CCB20DB19A4D994BDF1620BAA7030854CB80081D76CB0612CAF672CD29FEE0185E0C1A843D55097ED538B54A9312CDB34CC55DB6534EAD8462A366B2221CB92A7D14C4026B8603ED5034072EF744FD00E389E75FAFE96BD8DA37F360E7145878E8D9FDE772084240079282E487C26F66B70DB0BDBC6B99ABE6A2C5748316A64DCB2F8156AB521C69BCDADE6E025ADCDD26C085AFC660DA4329AE005C5A64782B109D8690FE9D36AC008F77BFEBD4F4EBD0308669AB1DD0FBCC041B8292902545B7A5634DCF4E599EF86584E159016A22D5951BD133DB42F18FD36AFFEDD0618AB926906290E84921030F876750C2CF95323F7E585519335A9FD22E629C20FED1C281C9B4B86BDAF5F4F52D55B56CB375DE10CB923AC7E260C7502F98A4298DB20AA2454441E09015A45C3547EDD63BDF3FDBA673D4D0DA9B20A8EE451C38533F1AE456CEB478730FBC268CD3DCEFDEF7119C2F5DA22C2B4073BAC7CDE7861119D4DDB95867D9562FF64C0ECC96D7E347BE4ACF4FABCC22F59A086D5D4C811FB87B5E3D19727A01D33276F69FAFA41EB01D0514CE680D62A8A45E3480C3903FE3CC799F95FC530065659FFFFB1450284EDB571B47784391205BBF6E601419450F27EC59C0079F978491807AC6C98C979F81DABEF718DD42AD4F16F877820A7902C727DB4363059E4612E882EACA68F0F76E3B652ABFE3A0F23D87EF4FFD82253551AB49CA754EA6F544B6881F5B16D6EE81A0571471B59C229485A3ADA0545045F93F244703B4A943D5750DBD310A2034C2B93793FE4A3E840631B87A2A109E03FCF9E417E36608249B52052F1B29CF227A54C60EDA204EE971238E9704993D4EF1E6F97A7C49EDB9DDB21869D24302A8D4CD6B8FF5A92D7647130AE2E0B4A7766966437E03420AB875259C6A659123B29C5F76378718DCA937EACDBDE7E57084BD2A5617AE24C2D3CDA8DD85D528D855E9A1632A8B78530F29E198D264AFA437B9A80787F08AA3E2D2D1A95963B5E32103AD4F47FBEB64A123AFE5B1D373228EEA0F3FEF6AEAD3A39004F3344FB4F2DD586AE404DAE7B502E6C28A3274CE9C90F490AC11368848D1E8E020CF1AA2676B74006C9E14E20409D99ABAAC1E518A07915970D271D9CD06DDDDC2B83D770E1490BA9C50791B602B558B23EC5CB16343AC6CF024444D518E817B00294873D65ED20C792D5F8A4DF2DC08F9B7E1D7D2826E883B253DFF508527170E63667609A0BF39768AAA5C0459DA7DC0576CF4CFCB65288B6AC77273F27C65CD37183AD8C5842DBA3094691CAD4327DA9EB51687BC57E38CC4869C944486D8AD50904D7F8D8F619EBB48145D28BAAEA8AC88C9DD89380D0E3022F7EADD1CD9D4299C789BC5D9591764C251A2AF1C370BF14D854AC6CE7C19D2FC29D809C9037C6FBB0CD50FCFA9773EC94E4B16233940D6AE8FB36AD80E1CBB47F877A2255B1C652CFCFFB5577AF0471738A9AC7543C9AEF3E77BFA2A4F8C557383EE4FF34C78E1D238A7EA2BAB35BD1F59690264E8EEE9F380F56D77A86B9B6E5C7EDCC63709803808E96B4131B6041A4C5014C33BBFFD8557FE32FEA9F3B4B1A67E152CCB065C33689F03556C467058AAAF4D207C255BD425E2568377463F123A3D160CC2719183A04CE4AA4708EDD77C1A26E08634C6324E7F7698B025958E7253A5780663A9990E25366FAD5464E22B4DBB183E15307C32C6E66BEB1899200B0878EB1A383385285193776D99BEC6DADE00D3D166969FE209652BDC38BEA6EA9C1D6D16DD1775674330380F54D62216689E60C02B4B537321613E3D947707592613DDB998B320136F3414D995A7C1063CA236E153D684EAFFE4A5B26949FDD9748F839A3A00145AE76632DA8780FB1474540D90AA16490CAB6714B0AB16FD3D86AA56273555484A0E3E5D196D877CC9D02DB9C7BBD5B76ADC7CA32E163C9B0029227FFD6FEA513BEE70CABA1DEFE609E378D1300635938764A97C380BB3172B4070D83447B78405CB565F959F482B142C3A5E25D7EAF8CAA8DACF49ADD7868703C15ADE4F3EFAFC2C8B75584E3E7CDC65AA70594564EDEF5CB07C98F4779540B21B738BB5A179C4FA58FF46489D2FCBE27742DADC5A2594DD8C875FAEB24CCEE827C9BC1B5CB2E49CD99DA507049F66D18771FEF2C8E3DDFBDF47AD81771CA0C1C11CE1081DBCA0A90FC17F80C049F14E0A3A6FCBF0FCCEC6DE175DFC3F465D8971DD0FF00C52568445ECABC9D50AF72A4C5703D21470856B1F578902BA34B70CB834BC783D1315328B220C9C5B637186F660045497C1116CA617D10D9DB886BBC0FA75B33E9D2DA5D0AABBCEBAC26C6FC28C7FFBF8DAAC4EC85285D609A91D22C2BE664507712020E9E5F1E02EFB83CC888AD4E5BDC2929E0DC18B4EA975CF7EB5DA10A5D872CBDF3D4AA452E8D0BDF8F93611717D16B1DFCD6B17143D93D46493D499BD9BB1219501D3FAE66F38A135F7DB4EDDE555DB1D39EB3F42A48FA42BC2A92ECEA56323773373A965DFC9A126F81B33AC23C99C0A5B231C52515F72E3FA09178D07D9BBDDD2995DABDABB322C9FD0E36020140333A95CCA0B18B7A31DEA8582263A10B2B6E68FD0BB7B718DF255DDEFE6CC616B440D7BD8227AD434323E3125CEC8AF757488284F64A2E62C640117A26ACCA9E10EF6C5130E885CF6B5768B28AC62CFB27CFAC57E8C82DFEC7D5EFCC954CC6625FFDF1E689E02625E6ABFC2641029AECFDE5E47B5225DB092244620050B6B18B9314C5E166987C093F947F5EFB9F29179E74A64DA1D5D3F9F5482FF11A49832E1857FD5CE999ADC2495925E95AF58FB95BA5A009645CFECCA8E7AB4B6C461F20F63F105114AF646D0E1C47A026A9E9BD7141CEE954F24A653EBCC3F0F3C699A6ED3CFC1464E4480BA8A297EDE705553D8C7CC4F1287257B1603176E3B257897D8F4CCEA2253CAEF8638055FD5A8E86FCF24FE2DAA101B32F066A8451E04BAE5744EA2EDE845424ACC04B86BFBB9C5DA50042F1A84BBB0B1E379F4F843668329EB9F2806C6F6A652C8EDC7EE99D2079AE31D8C294DFD76E80DF11CBCB164127A483ABEB6D518D269CF4F592D1F52CB4DDAF26691C7A74A920A9CA7EE2156A871142C08B1EE002C76D4FF5894F5D8ACD64F04F010DAC069949449999458BABD1DCA779CFF07FD57FBA27CAFEAB66F4BF81B6A7FDAA593E4304E013BE783CFF8078C7D224EE2F9C24B4FB1579C8B700FF32E70A620393D999DADC707153458616C71762D33F35C89A1EB082136870A0E1D3D4C597AF1F80000000000000000000000000000000000000000070F12161A23" + } + ] + }, + { + "tgId": 5, + "testType": "AFT", + "parameterSet": "ML-DSA-87", + "deterministic": true, + "tests": [ + { + "tcId": 41, + "deferred": false, + "sk": "13FAAC5CAA1C92AF31DE6C25B147014BD7FE589A649FA0089AF0D606E4B869EC1E4519E3AEB57924B329B085EE7C80501241FEE198F3F41A94AEED9BFFCFC9F7250182F2FB7F56C145635D81FD4981B541AAF62A572520FE29FCC0AD050545BCD377EDA950D1DF476FD2B85C8C9E749807ECA53A51D6D0F4F42A339AA7C48181C83851A0A830D080651C3741E1A805D4324624272D21366D403652024250188488CA24804C842892360462109258844503326E13390E02928CA038044C348A52A46054082DCC329204822D5C9869E2246918914462A86560080A0C372010B9890CB92D63126D13986C21B02D20C52560340918C641A20872048684824026DCC26418165219223158928940A8408A3646491061E396690A2690CC042D41302119C06510872141400C83120D831205109905A42844DA06201AA30502150C04282521A430E03601CB804C1AA2618AB621610410649450E3C630C4226880343210C09021944589248118C7458B904402126250B400E2866800A2041BA68558080ECB228E59803192847159262A04216D13A00C0C452D518845834402C42846199345630069E2060E084528CB1271239484E2386E93446D1CA26D21C60561B228DC1406D19870DA9211CAB48DE1A20503376262B6014A284259948D80225010108C18354D13982912474DD3B8209A40120A398A88026A8B2280D99460E0A80491246D5B060D02012D13272D04154240860520948D9182215890688084115C0248C12012D0B68DE438666306258A884C9B0801DC087083445222404109252AC988851AB7491B899114244A8A043103408ADB3680593488410690DC084AA04830C9441198142E1B038124B06464209223B484A49631CB82648A9669A1C230C9A484A18420D9226A99A26513C168234404CB224940926C61066E83C8418332254AB48002067102007213A57123842908326E54828101920D83344A5020251B84718A182C64B064E31049E4C090243592A196308CB89109C3109336812399415402101C196153A68000022C8B10011018914318705AC20C1801665B341109836811B78998C6618C40910A430683204421284E41368C94202ADAA66541141213B9605B442901102499904C41342E24C28DC9082E11382E00018A9334455810009090316348610C2860D4262981280DDA10519C140C1B2308D29208C8464E10322E44A848633490810022501845DA420E24097162A04908194453C06144482622C42188320A01C00952046A1B25511BB185243809C2A86C603689608684448065D1226223C98DE400468CA0504800804A283044084A220640D800724A0062810425E2A22804C04C0A408E891089E0868DC2B4850C274843167291220C498061640488D1B605121721D1C231D4C2811B8271A4422A414212D9982589069110220C99886002B7219A1262D2C0219BC28412496A4B089022824011106603A749C1448063A65160380D84460CA4A28C9B162A09A388522426C3A25119A6802410860BB3888BC66C20A028D2A664A416721B05119CA42113932C1C86491CA30953380C92A67020C7244216280492714332221440406492514C448C8AB40188308611346560100CD0302D24B460A03870A0968920842924A88D58002010286EE1204C14286DD3402DDB38251C1381E4B465CBA645E082015A022CA01612C3322A14A36480124A01042A0895250C8440809051A1282524B86D08318AE0220E210692DB966C83124ADCA0692127065B1828C1882D133209434411C9462049C48481146C18956948C4480C492603080D18942000130901436118A60120474819111018A50023019022882818054213069191062509480E11456E8A00449914010020122092480B8320E4321210B429C290512139049BC411129890DA14661245048322049B442A942291C9A845CC408203C77181429223B670D924218BB08422392C4B2860A012905A807113462992C068CBB68D1C8064840482D9B82152202A1B0565018545D4462DC8B620D3404003C42051380AE3228541086C04C62C8B20051B091008A420E0906851B685083825E4428C504866CC98281B1171D2208E4C324E13424E02044984B20513B9059AC86500472E9220710A300CC13620DB8808803840188810A1A84D043582E404320B048061345208C5201B92401032121C426A231904949090CB9810B0D16BC03B32C91F22E9DC32FD1369B126053CEB625567AEBEA42D32F861AE27857C24814177623EE402427442714970674EA84BD573741F3ED9C297758E0666F718D5E61117BF138734FB56E3348CA54F05492294F52FC90C243BD836DE2D5B9797A189C7D38E6E35AD95E1533A32B5B589AB56941904BDE66124FA6CDFAB90C80A05A4EE8E50A5DE061DA6E11D3B40F218664631444651497AC3AC3E9A9114C9BA1E92D2FCEEEC9168E27296AF943472C8B4E251F753EF79F80948F2ED5BF690E0C0A074E8E0E4503410E8FAC6D8B022BCE3FAAD1C29681FE2223125F43FCE56DE461BA8264DC83CA1E690BA638E49052D0D05EC5176D12458159F2FABCA6556F15914598E014A4582C678C0F6ADD2F2AEAA330E816B0AC0BD5457948FA49FC4C954020070451143D8B4B4602BF9616BBD1D9F76B0EDD63F186BACCA0C0F861822E6AB56F771C6742106314D54EA9D0F1BDE66F4A504C6902D86B815F46F47E6D69A9DC16F290A8A9EFB06695670196D17E096543CFBB6927E25191B9538BDF5858B54EE4F69D35CFD511FAA422B6955F0EA87EBE5506DB4E7871C7FC5A2F974C736FF12AD545CE507AF4E430270E47EAD8663361CEFC3FFA2E3CD85982ADF648DE6F899056672D6CDC6841B1F2668CCEE9CC630AE9A91CEE7648AAABAFB09E4AC7ED0D7ED8165D851627A01919AF56FAD39CDFE838B5CF60E8FF5A2A7C91EE43F1AA3F81CC853B178E3481C32C2D6FD40B0EC924CC1887FC6DA4039FA0BA82D0A57472C9D6003BB3D819A0533D3FDBDE2CB06BE052AD7E56B92B431652D6D5991BBA6B564C15C1BAE95360A07DD76F0ECE8532376D0B71EB865933D3520EE7B3B35B7656ED684FBE914D01502EC4BD7FF39FADF06F6BB002B882213C4D42E6CA651BEEBA228BA93D825D618084917ABD3130C31B3B935A253D8D28BD45C5FAC4B05A42BD815B9CBFB6198DA4FAAB4DA6E9E95194E8084D66CD6B52BE2DE2A86DFEB25C254F59C4CB168185E00074E9CBF060639CA6ADDB7DE514CAFD5D1D3C74777C11957416932E8745C2B01AB7DEBE2E20FBA37476C0626140FCA24D3EF4F53148C51CA78C935C6C89233A6D4C57C317A19712A8040C1C4D3AAD221C1D375DB372FE07250FC3C1BEA8ECBA24D781492425702F35CEDE709AB063EC0804E71B8669B87DAD1563606E89EE0DD2A0B11B8836F5A2D375AC4B7F85FC5F80268FE26121210A4E1CD24BE3FF9E6D92A5437BF9019002140A42C317906D61D862200117FF0F8B8EE8D4C289C3950D083B5E5670D4ED32DA5C691F20CB648DDB715977ED6AC69F64DF8D5C99B4177E8B98876E7A5D29ED0C0F972CAE6256528233E15B13C69AB592C3AA260C77BA41BC608A57CAAE46AD240DDD5C2232E2297ECC90CE628DE5B83A551B06BB68FFCB152785B5AA6D1702DEAA8E92F704B0D31498692C537249D71DC6B1247948CC07413726DFAA43F53058807B77C4C73874EAA526EFDDFDD9116C98B0E2C5B7CAF9A25278761E2EC3B34B766877319243E138DFE6A3A03038D357516D9BF64955EB8B0A4975E026D0915BCB8637C769530458F242F65A68DCC78157CB30C4632938AC32781259BAA48F11B3949616E06C4D4E63F15B96E203D4B4A8110307D5CB3552810B9E1F3F4DA4209CF1BA98359F40E7055C7538ADD0AFB326E5F865B3F69E3D6C9F9F18358C0F6A47777B455B8CCE6C514CEB2235A7B376EF92482E2E86F42331511FB94A9038FF41FCFACBF353F3A43F3A79997167306DDC94A6D0628FC346B06166EE9D857D4B0C63990259AF271CDD8479F4B08633139663A1155340109B5FDAE255D1E4E21539C07249AECFE8E6AAC44A772B39596946BC8080D84453DBABF1E62843D179C1C38F1AEA5CF15BEC4A61810299632A2F3B9422DA99CB13C852B1CC6933DD52EA336A5A09D7D9F568CEDEF14CE1AECA48D92996CDB2CDA36A3C8E95F62DEE742CFF293037273E51F77BC208D5B345331E72C26BDCD0F51C9711BD899EE82128F834BB0B2A3DE473358F47EB2F98FBCEB2624A5D2697B86C7559FF40D14744C93AA2DD6570CC799C4B5669ECA0463AB0B4E1228032DC19A42E4F6C64D9EFB26E1B4E622AC06FD0C47B5A39123FF8F1085E4EADF768FBE9D5E12CBC5F380DBB414775E2836AB19CDEB19A0F653E7CCA9DE567D18020D19D24364E03C762EB54701E1893FFECA6D23A2163AA5CA9FC2DB681DD6E8AE2F42985C2D7E477225AC2F9C5274A5584E0FD90579B32D2143B89F9AD9576DF10A8E82D91C4987AF05F3E720D8557093A1DEC1D2699C2305651CAA0FD621EB48190751D74478381A499A61732B917E84B749A0465408014D249DC7D5C247AC0BF404B4311A25A55B2EC1301350B76E3F953EA2E67C90F1D5B9FC29BAAD30D07946AE1C2976A4FD32BEF26A2E93818913B36B237BE40EB7A907595B27E7BC80039683B3D28323F53B5521D244E3C87798478A8F9ACB55EC09E97BC5220F955057A889E7003B9DE288ACD5594AE65777F36D6C73FF5A17C7A8FAF039F60BC9E3EC54284384429C62EBCABCAE2E78F5B58DC7132994DFB16602A54B444B9A9C0FBA6F7AC3E357308CE2570743B8D2B5DE5F9FEA05A46307623E579195D6B5C946C47C57A14D5A6177636025FA555F700BD61FAE9822ED336AB21DA9E67F9E81CD815F2EB79F25AB194E8AFC564C43CB4CD8D681CD8F1BE41D9376668E45EA7E707EFE2E58BAF0CBC091DD427009B0716B819B857FE9841EC48248AA49EBCFAE706E5F8FC65076E6E871D6958EB1C7A357019950146CA8AB3821317C289C744450C293D3DB4B3006EDD727B5BFE7541F6817CF5467AF94232BAFE06E5AFB845C0216491DCEC3D603B32EA59AE651739D0E26138408A5E37A6E0BEBEE2956269A722AC36D7A3D2732486EAE6F8100C9A278988554895424EC080E282EAC6401129F51148DA16ACD7BFF0C1CAD9516F189AE1D1F4EC79110B942C026C6995A0AF85445AB9DADB1B2FBCA7BFCAAFE884AB6BA0717D3D7BAEF75D9A4507FDBBBBDBEA858EA7975118B94AF78E250F494205715B0EBC31755A38C1AA944F0D80452AD54639B2701462B2D82E522F8752110F44BD381E23C1EA52C15BF9A7DDEC0AB0AFE725B5993A0351737C1DB72989F48FB41AC479C777FD2E7808FDA72790640F9F741D643CCD0C1ADFDE90B9ACC84345E0B0739768ED8265455AF008BC09970B18D52D188AC387CC1DB7E47EF83A0108D39F7057BBC02E611DC34F9DE364B7ED9664A9C5C9D691DEF8E8FDE6C61484A097CF8A937FA55F353D439C380357BBD108933B6CC49CC5C5042D6E5FDF8F85BE9E4315E094EE569C5E3F38CBBED68948FC95226CE06ACF6D0C88408F3AC265B6B10BE10EF0467E011A5EF8F10026C7C54F8466E9E574FBAFF13FE9988E783BDCCD4B02BE46EECD77443F4CFE8969BF3551F2829FF2C0F8630DCF7B088C5BF1FDEAE2E81143D1573854D0D6D6F70FBB5ECB7C6E60F91B241E5543BD4F316C66A7F3C91491320587DA5CAA6345FC0D2240530BFC19AF88B43773FBB4A6369F540486BF74E3DC4DCDC4CD265C7C0D37213037CCCC1FA81D21EB4081C254C4096E044EB6BE48D07CCE2F460718164AE3B68B7298BB1B267FCC0AC3D0365437ED45C742A3FDD746910C1610E6CFEA9A17225DF2B577E790EB870F5A2190ECC166EBA09C171BD825D5E8EFFB3703746817908D299426DE95D605B368AF04D27B01FF5CAB91515096DE2986A0C575D14CF4224AA9523B661128740F19DF8072C917483746547EA422F8A3B40CB67FA87A7989A13C49262089A80B1E4113BB1EB9B469275D8BD336DE344318EB3310B3ACF8201A6F5F613CE0F2290AF5A8B9DD9A5B64AC8BB94AB56C36157C8EC8DBA4125321F30F753D489FA42C4881A3450DB8720892A8D3F52431B960A2404A748220A7305109A2E80EAD78B8D5C1F79D265B00C771129A2117DAFF0D24BDCEC32D53DF76A56CA24B6CFA0775F67614186D7513528FCBF2F7CC47D60C52580BE1797A62C17778DEE9FDC0B6D32585BD35C86276B363915D3D2E5A4BF58AA483891025522B572F4B635CBE94FF014ED19A017EFE0088CA05C54BBB6953BFCCD8D6F867769CFB02280ADE6C39BEE714EBBE252AE5AD84027F8F9C2CFF3FD01ECA4F051591B7FD9164C3C64386D177A74E17181CDD3C55C98AE89CC2C1A26B88D6FBD16DFB76742B631DD8F8D78B308D606B486071C30E81C25AEB864A822402CDDE0CF27FAE8B6CA16500775AD44733FEC8F10AE6677114A330E59FD52747B992113C53EC9A09AAC1C3646FC3760CA6024BF39B7DA597F8902CD605599779509E3F8CD8B03AB66C1993AD4B3317949578351B74055C7BAED3D7555B315765F1065414F39A7848DBACEA596C51D10BB0081381F7D5601DCD07D719BB9CA9A294E092376F6D4CC32B26A9A8FB5297CBE32CF4356EA70225CB302693A6DBD36C816AAD475815E9543F7DC8064C34870A799C32A6BF76D472797F1DCF908FC994604407B59C824AA76BAB6334CDDFE8D0227A383B0CFA2158CBC79DEFA98BC93A38DC0A0420C99B920BBA64DA16819A78F8BAD42355EFB42B4BF17C68AF75F7428B687334746245F7C5145B5272B9C504A9A0A3A985A9738BB1B42FAEEBDCE7E7962CF0AC6EC80F77CC5C9733E49DD1552812957E1FE30C4129A702E23DDEC09FD", + "message": "67D7F4FE3CC57FC8BE9A3D06BCA0FE4A39F39E3A6158D3E4ADA9CCBABEB542CA67CAC48167928336993C569AB5AE55BF95C8291AE1A1AB2B595C90C0FB19041435F3B411609412630D80DB0C832D413D69C8D3C3CA78BD1BDC24167AF590B67449DAC7F6ECBF87698BF3929FBC874F6FD68551B28E4EEEFDE9A0D0E7FE9E569F1F9893D39C17C3BA7A6211B875A7BCAD0C14194C30D60CDDAD640EAF7A02CC9DAC074779345B83F0D282899B2B9B61F8504BEACA3C02A76611C82F2007953D04FD3C54D7A00DF8F6DE554FD83D1EA5DC841645B706C9D900DEE7862D526245215AC6B9D178E60F9602F1931503864D97F582834DB797CAB60DCDBDAFA3FAE8726B525E8BB69B5E0763FC4ED17FE7CD9C9629273AD5B073B9516F6CD7EE729351C213FDD122E3C11DBC58FD2A501B267AA4AB21364BAA856823816E77B81B6061279FEDA6617247B86073E55B19973BC0E725F34ED4BAF0AFB95E436A9B2290A2B316C18CDC0D9F98F9F6F13C5A3FC767EC0A9A49BE1378E92BC9B3010B41AE52AF409AE0FE27CB816EB2614DA41C796D5F4FAC4A743FE34EF7C0B3A78E0E4A5B439659D4AC27B698550E89A1626FAADF71420F559DF2E808144707B5C02090F754C3BD4EFCEBAF6FA4493C5D48F895FE7674C81F069E1F00E455BF5C965BE2926BD19AF76E20533A6115F4BCF2CC5DD3A49E10A2B3FCC9EEBB2B6E4F25118599062F2AA6CC3A9D86167B1BD08DDB2C53A5E46E1BF4E8C1967866320BA66AB67CE581981F2003B812BA058B75924254EE3715BADB8E6B1B9E4F4AA9844D578CA2F0AD12E1C964685FBFFC87108711E022EA7F63330CA72AF86262838863780F4115138672643E6D9B48C782B8637E01D3D20CFD5C98A1B57720762037FFB12742B4EA8E89E4B32EE7DBFCD5C11E4A6E839A83398ABBC32BA39C6A25922649971D88A102D1019B560C96B820C44551E14509468196CEAFE3B7BC8F253ABFC59FFBC01A13008F77C91B19083A9E7BE733C1A5E558C64557389CA19249CAB77014D0569BAC7812862A610DC6EE074C844A055ADCAAD496F6976C932587BAD9D7E2080F8623C5ED8D9D4FB9EFBDDCC4CCC1284D22A2997824577A619905B0D6E451CAA3B2D30DAD9728FC7623F9ED71F80599D65D9F2AA285BAE393D05C15891472B2DD2ED5CA669785EC4D441F3308EB4BBDAE8FC449962EF9787C39A533847540965601D8BCB6B4299AA636589BFE371D3904E18BC9AAC9B3B6EB8B7E8F322C22A6E01E6B26244F9E39586F124AE4E504FBC9D860A61B20B4C127FD0C55EE810AB9803D810233E6126488A6E95F8ADBB3F8E06D113DE6A3E361209E0D36B326E042CE9D2698DEE469DA15464AFF82D5603434C07CCFC4D956A7D55FE79CC127AAD2A56B34EB10E8B85C3CD5163C4BB8C1083BCE5E5EF986AE028837809641A6AF2B8295B743DD9B03931E755673DBDEDE56F6294270532D685DAF1187137CD7D29248F21B290EB8317E3EB28B62E45E140F4AFC6D1438F81E9EBFC6FC0F1A4146AAD83AD1F0EE2952643E7B6872CB2823AB21A155C281ABCD19E20A52611C6FFAA724578A070935B1A0BFEFBF061101A81227187E14E96B016242DA269FC91253FD827A73743A4BC49FB63E2D830D0FF409AA1C73706D7C2297CBC552CED567DFED72CD15060A522F9B88EC910B03CD2794A9FC07A8FFC5CB97817DC769E64D8C474A305035A49D05B1C572363913A315932E391B62AF291DC203B9A40F04F40EBF26A4AE186056CEC45EB7D21D88CF50258DCB5EF40CB2ECF949B18C72626469978FBE0964C8A25E8C2D27149C2266748F2B06746E8C9E7E2F0977BBBFE3FBEC7353F583FD5F7C2B0139EA928AE1F67004706F6D4ED7BD8D13BC68E0F4A49877C0B2F692936BE5FF99544B2B19B23A97EA6B5F585ABC9E69E689EFE25E15804C650444C479E0DC63C9CA2AEC41A316039EC7F675F1FD7C0476707370CFAEC9C3418CCF30B5D85FE0E15056D6C015DA59F9BE9028D9C2D93434F99DD8C1BDB41FA1EB021BFD0FC12EF0D038CA32B0FE1449342D83CD6BAE43A8CC4077074FB1191A8887BF29238D27415D93880682017470A42872D6CFA729AA2B3F8B37038C83583E4C33256FB871A704527594596FE858777A93D3095767BCAD2FE295352C93D227E1766A59ECEB38FB7C2E3664D6DA0DD4C063975FAB3AB4B68D125AF16D233389D96A337DBC18DA11F37F430C1E49BF8AD30258601CAC9215F32771C6FC2B7BC03B55AE9664E0D719C3B40C3E4FA7DEFED8571CE8E46FDE8701975D94319DC5FFBE93B4FC4898E2EFEB3CCFFB3494AC50BBA364C22A3953F052F62E46D0C35692AF40D2FBF899A23C1A4721375F307E2FDE2E588830753F908FAD96EBD5FC360D742E2CB2C38A7E142C95376ACAE29DE8E1034207D1CBC1DBF2968677AECED152B1EC1AFC195F3320352953F2503227152444BAA74EE8F98F2B4512F7ABB43D7F87889CF1F8C12D9BAB91EFCA5AED21058E322CEB4E59DB4DDE13BE46FBDFB225F4AEDF7137B548503008002A36D7A3E98C0ED65ED9322D66FAD4A741125EA4ABBB26A2FDD7AD136590061E7BC0D5228555D1A59F8A6E4B97ABB61F4B1AD9564E84C000585DF8BB31AE61CD25C9D91D1A1FC21A69AD286CBC7E00F592DFC1C65E2BE755DDF041486F3B52C8F72ACA97A149FE0CE1378236D99EF099A668F6847659F7EF617B66192CA452ECE3010AAC18A65D8964381F561B48D044096DECC22736C902D7E23EFFD26245018D9D7EA9E2F907932A1EBB405BCFD29F7A397C71A5E08962ABEDA5203988A81F787B25EDE84A7D85DE92A2B19974EF7D0378877B82BD7CB28B67F45F7EE625CCD054B44B4CD51802B4FE2E219315CA9F4C24065F5578732DC671C3004D31830DB435C763143CA209D7DDF3F5EA42244E68429102F4D90297B7C987EEDFF0DFA7F31964B76432E1DE27FA38570F2BF64D5FA3F12DD9772618ED2B95F51AC90410350320E19084F1596F6B791AF1EFC24DBFA2B7E30015AB14FAF43B568C5149A1152A47D278B5F01786F242858C210D28812147646A1A3A7CD69996809B784BB2F0053CFE18446F060622FE3B9181AE9175D6CFD8033AA752296016E7BBF639842DD4073AB282FF50F94B9E116C63DDED805277D4FD7987F740EF8118946851A5336A9F6F6E2FE3ECABCC518B31E741AA79AB500D9C6DEFCC437569966EAB1D4BD6CFF8AD0E5698D15F1342ED46CB6DA986F0C4B2B427752C18ADC5070043FFEEBA98569E90C79A3D5E0434119A077A097D69DA6E9AD7E32C6E8875A893F6D69424DCF4C0D4EA12605E5E8A9853E4B58E5659FED6D724CBAF582A89A228F99BE89D88F55095D0627B40B29365863C57F82B9EA22FDE731D1A2D8A9037665213F2C410D4AADCE12CF888DD4AF53FF839E962F0F53BEC60F97133D131C2C8EB588AA7D25EC025B9E821DA8E8FD8E550EC5E4D5923BFDDBAC522D1FA64C503078618B52F452B57874285AFD3F6B182CA6C979734C94F040EBAEDFEB547683E98F4D13F12A252E8839317A827CD97A7C3D81962A25DF7D8C62B57812EAFEA9EEAAD7D6A9E755AE4CF3AF42CA2152F663C1BADA0E653EB165F6FB56D86212378C0B9BD5733D4C37178FFB58E7357487B98DEA35127AB58A804B13E61E6D3E385C96884EA91C744DF6CD44B3EFBEFC79ED19C406AA6ECE144A44F1E78B33046C33EB17E3BF61A17D849493D08F0FCF8232AF2922D96213647A47A05A9A08D28AADD3B3BF412F29063C9D78CDD3385BFA9F8BF06DCDA23FF79A5912D867EE1B0D526718EAFA6F0E231CE6C51959BDCD8D201838A50634F1C6BEBE2E4F5235FD01A6D27B90C58C12D8210692BF68FEA5B8A8651E64EFC1DFCE07EE670D473F29AFA63E080F7675F23E7D2866E5F2F9A525BB657E8BE5933FBED1E206C7BA9FF097EC95B91E14612E16F0F4082F70A1B01EB6219D47C716455F4C1C60948CF3228557E787A3186B4758AD35922AF28BDB328693BAED15487F7448D1796BB9DB5C931EFABB4BE436B2710EA280368A8E20C5782A7FE986417003236BE9CADC560B3D7C2CA92341536CF67D412E855B92D0229C45B1C518D8BFC82DFC9F413D3FB23D37EBD96AA0CD0B39EF88B23609AE0FC2BD16FA9E934329558759F05C8D4C8F3F8728335B659D3986E44508322E47121E592C9DBC6F49656B473EF7DA53FF8EF7BAE07D1BBC68EF4AC369D7F8BE60948F34444C0C443A100443EFC444E7FCF0BC4DB6A2C2C64662A538D1F68F4DB95B0B83DFD744ABCCBE5DA343621F0E182CB9E915B2097C186F1B98E7D8F297C347B60EC26D04B6D9C1FFC01EDB2551FB8D11D49E52956F69CDE0E49E2E7DCC8E7C8E78C41A9B2A01483BAB11733A0943A9B765A5811451C07A195D87060F157D114358E478FBA2F2B755A2A455E9831B77EA9D33FAEDC1C562E1CFBD8DE156FAEFF10AF655713E36FB508342D9B4A239D6DB786CF9F57E1C39AE65A7329E434AA88C68F82359E6F057873968F9FB63D898F24BC13C0F7748F92E404C6185CE24C98D4E4D8D4B3C129CB46C614E773A89EAD73CF0C30CD7E6C9F6435F7C83A4C3F877E034755EAFC5F30ECE03F6413F4C7DCCD01649B6ACA9C1C3AC3D112F216AB852A27DB3B846CAED86B76FB699AA7623548EADFE6D16AAF5A3ECCC298D5CAA7E84ADA0B75290FC6ACE736051924DAE8FC5BA6DC9AFEF65F369D054A4A18950E71901F4483A4BDDB2584DEDC31A04C5F8916DA2DE33B37078E5DAF3304344A8AC368A6668464FFD7898A18D10685BDE6D0097F95A3587717F6A3A8827B46653D56E461EF861D6908AB7D865B532DAB37E02A7A6A72A06F25572D83ED6DAA540FE56BFFB2BC9D104A74F135127ECE457991152DD0564BA955971E8C9767DDFAE190052A98A63C4C0DFBD1B51BF60643E4C5EBCA678CE5150F03A6EF09AB0B1C2A0D2C19C2B30A645C7DB9B56B5AACFB862837A38407070DA9C7DDA20B99CAC7B03D10C8F28D6B1C686FD26F9A8FDCEDA6B188D472BC593AD51EA62DCF73D32EED5444484853AD0EFCAA60DD42DD2C50F5AD15DEC7B71BF585581B9F9C68C7C94C154CC7E0D19ABC90508C8EB2DE93F0BE4295973C1F443A1B2419E20F3D5F883912BBD5CDEB938A4452FE0BF2361A9E3B2ADDFBF000DB07EA19B2735CDF0E8E5C7EC5CC7CCE1A9C3E869718272E54CD9875C21DCCBB06FEDE38A4E787D111DC6A253A4604B314FE47A9B6F6FEBA3F8F013A456DBB78B497C4CA7F90CC6145F47C96D266BE5507DEE27E968052CAC85EC87049CDC68D723D8CF89B0C91F67CDE2908C0C71808004A070CFA2EB6408F5FD6108749406FFD3D5DEB6FBEA00FEADDAC4CC0E22A9F6F50B9893CC4CAD028FBB73C1B7BD4292AEAEBEB668859BAD444D0C5FEDE3C469CF28C5C726B59E828C473C8787453BAA3AB2BFC29C691FCAC2CF496ADF3949CC42FB16F3677D456E614B1F88406E6C9DA7DB9937B00764D61C3D347C140FDDABDF8CE5E3E2D385C3FA6FD9F13F3BF8073B5D6AACD5294938DEF9C6ED414FDE4B3C5EC43865A7FB02787E50F94033CFE32A85BBE24B09FAA3B55B8BDDE60E325B691A350F2F128CF74FB5B6DFCD0E946AC7BCFB839B3765616DF35AF29F3AC82F4E2DF7D4AE87A016094719A07B5897105E2B08AE3D807960FED396CF38863E69662238541EE295C06B290404985444F4B28388DD942E51867216C734580B3F1D5BB204B05D4993D6F8ACDC8F16FB77B607FEDA67939A2B6AE285ADB2C98E7D37A81AF0101A5CE39CEB2C67CF99441C1FD980C2C542E7284BD21F1D30E68EF3606C65D3230B5146DAB41D4ECBD5FD89FFC68441BCFED9AD8B4E0B616127A7AA39E84DBD1343E2A41B4DB1AEE0627657438034E890C8EBAE19791705BF6C948C630DB1423D310A34BF151AA8ACF3269253BADDF5B40AB7EB3A7AFE2D7891B925F65EA206F4CA121175E8F348B4162917A68FA768928AEB0504A60C4F42802DA25DCECEC60ACD21FB236080AF1FCC9146BA30AD964416F4B524ACC416B5357206980305555CE3485425EB8F87401FB1D8CCC184C486B5B563242BA9531147D6A2E7C0BEC1A56E083F05344BF97A18D0CE0FE56E8BE869C746D4AAB365225D8871D4F99020DDB1CE2B5D7D2E5DFC8A0DE780CBA0A9B9ABAC87F19C73639965AC2382488387F06199A08F283794E1B8D3580E5CCADE811ABA6881908277624D5395021016DFE21C345B9A21B474043E187403E5B0ECFABE43991865A424BD33D233AC4BD30A3CE73DCF49B58CC4A3D2CE25C54FAB3480FFE0D51A43B71FDB7E1126E66856D263DDC3BF1A31DCDB935DECCF858FA2CE5AC89BF32E36D8009657F11691201290A243B5680E060D2CE30F1BF2444D67DC94A24708F8F9261945D1B5275ECFEAAF40311CED5C3770A1C194EC44501DD25B7F5FE67BCF62D1BF31119F8EA7DEC1CF536C1026A8E72C7B2E167BCAA8673AE5506CF6208F3E1B6057B5D488B29EB84D6F94AB8AF322B8657075B9EAD3297505AA521D601C21540EE71349614CACE0E7F14EF42D6CD5377DDD0241E34CF273A1171135A376B98C53B218503A908577C268F6DD46CA9C26DFF5942998851627474DE9E6B46F49DEDE85CEB993A52D01F6AAD6F96439C18B0DD5A4FD559812227BBC0567A28C1299626B171855AA0C74E2F9B1AAA781D34CA58C72C708AC49F5AE1453902A1FFBB8458E8B4786771780ACAD999F8DB036CF4C3F77AE345817EDA2AD8F7D2AA9228C994F6AEE512F7C2D2AB72F2099EC932D818E495CAC8507B06CDC6702944237DBCE338C20EDC84D958C14233C1884BA09A023BF5284F0B0157048B6AEB508415DF337A553F6435140D0CE5D5CAA77F9137B2C1AD5A02B13738772743F192E53E970DDB401983535CB096F7D98644797F487CFCD18F1B22BA7494D892C1E5AA05E66B1A4326C70E348350C97DBC26CB110AE8289C97CCAAB150020827B7D7AC7913B4FF515583677018949D39CD73BC7DBB90696D5EBDBAE6BD6FC78E3826C8218996F079A387A17456875952B268211891404E80F8360F042EA3D9F7F7BEF772E64FA1EE8B4EBE0A1162A46EC1E9899766BF4D3099AF712A847CC86291B3D6FBF51B3B3CFF87D7DE71E73069619480F6056AAACDB9ED8E228BA075622C2FF242CB050342DF8F02118D071D27D1FDCBFADFF49184F5A100F95E1BCB019864E58E0F02672C8F5FEB97EFA06FBAE6EC3D57A10EC712BE0144323292A2CB27F1B1FCC104140F556D09A6074F853AD4328B00E6F2F24A61A7932311BC999805F2E774DB44ED72ED244A945928B9512556EFCB2BA7BE0E668C41AE7601339F0162CEC0A1AA91C3FEB6A8A40158D7A3560924455B9AFBD4B3881F6C08EC2895C84CEC30CB0F5B499B4A66267C719785F94A9B9F96FCEBEE939AD0FCF42D0E65DC241698DED0EDF1A9BB4147898E6E83851499175105BADFE4CB00B9000404DC92EFB4EBF41D9A9262EDA550DBD0B99353D001F90AA05591100BB678634FDE4E0B1C174222C253870DA3B8A797CAEA9B446309DE5210F9A932D6AD48A4A7361A943C1BC66BFDF75CAF5409034A8768BD535B20996A728A26E28340191E03DB17A7032FFF883EF664FD7351DD37DC2D72F0CC4B80BEDD1DC33BA3046162F5D0003140DF78FA588A9FDBDF778836C6CAE7E5A20FEF030C57867B295712DED14474FB87A301C31214FFBB4F8D166498ED93B6E233A669CB88D441A38A0E5846EF68F5DB20245980CA184878BA8BE1992A0638B058CD3A3A501CACFC818D2B5D7876DB6EB08E9F26430FB06EE0B9E834D1C331B66CD0BCCAD7A66ABF4A9D8F7A872932A3C0B25C5BBCA480159711E0BADCF69A1107B286AB199B210CE95BCBC4244780C074C42B6BD43869F27BD666F9B2541B1561B4C207E9A667EB1E31942697FCEBFD0B920EF80CFBC5CABA6F528187403D7E8262C110458B5382BC376799032362CE57ED39F0D29D7822C408923C29242385CA9749FACA43EB4483E095851E89D24CAC7BA5AAC60815CB5C8C5331CFD66352BC8623D5700F49FD98FFF9E869D5AE173961138D76E00CED6DBA09144083437CC8FF5ACDA10BAEC0081C8BD2F5838666A093B412532C521753C4E11ED0521923D1EE6BEF3B4FABED7467B9C8F75FB24FD8D96759A6146B34EF951C4DF92228C2E58231A8D25E3F08ED5A27BF6041AD7011DB41F815FEA503973D4E7B5798489B261A0AA4D0C32A19D17C584B1702713D1174E542BE4EDCEF27016BFC78118445A63FC1D17FBEE5F71DFF46F1EDCD050239C68DDBDEEFDAE7EB8963B5BB4819186D45191C05AA049E50C4319936C8788AB72744912AF28BBF5CC77C835C35BB4F987DBA6657BC2A7E58B7CE69AF37AF680DC0EA7797B29528AC70D92F295C561E2EE0D0E530854AA19EDC43C01A383035F6A5DFB354E9306962EAECA25EC85B9B78E8A1DF6CA50EEC733F60C81BF812981337F784F8CE07D0C03D8B3E72BEE1FFA55FB92DD0446CEE29D8825CBAF1A6ED295E613FC700FA31167224D99338C4F59B1BB9C1E63CF77476BF84F2001D42E4161F7737B47C1A5F219F6AC8B8E3ADAECA827AFCD6BC0CA09615BCE15F1BD0803BDCBD41E68F781517907EF3DD8E8A33A1E30ED09D7EC1D3605DC72C9232EF9F92475743164E92D953177B98906DFE5E414E134EBB63C79220D4907869CB2D93280F60DBECCC81B532CA336510E2A7F1D631F7BFC517AFF223430F9804C4A4877D8B7A385ED48F390ED9666A56EBD62F6C943D0E52AB1EA247BFB07C05908E99358A51E6111486133F4A6BE3BAF6B2D4C01529925ED911CE728B4CE4E8CF8379BD216108BF964496269BE76379912E94A4984B890A4BBB9692107D56AAADAF27ADE475E98A566C0C9E33DD1970A3DFF0E2F79197F6315E320BEB5E2CA3E3C904B557075981118B363042BA687DC682F13D213974B1647FB43DF7FA168C9D4F599C5BDFF2941C111C6C43FC75E69C290601EBC9F23D665F944A9B75932DF7792CB8A005A7CC83DD071376DB11F9C950B38B270E06C907FAA102AC76722325934755F53F3650B42D0FF293FA37086241C00E99B9C03FCE21F8D7555CFA93D09A0EAEE3733A8A5E4C45E74DD5EBFFD2F75EA60942BE34412BC82FC9959CFA155DC87FFA0AFFC1E7CA5057EE016B9751C16DF25610F1981A08B8E3352254AFA433E9B86D3CC13FE9B5B7FBDAD83CFA0FFE511E44412DFF1636BCBB49E9769FC52B302AFC7A96A3DFB233831007CFD6C302CCABC119DAD45EE63303DFA1F11C39C702AAAE00FCDCA913371F158BE5493A9B5C3B06AF66C8D5DE2BF9563FB617D1490FF6510971203DD25B27E1AFB289DF894396B8C26548BD53B320203AAF053B19CFC815C5D37E3115FD6CF8231B88FE4C330545F131A01124BB2487A3363B3E534BFD38B1D5138F8887EA63776D78783AC45675ED598617077AEAD86206B9FF61E3669C93C3C3A3A8F39E7848A88C0F94878E5D359C22BAE891FC7478BC8227FF320B047D0DFFC8218C1110136FA803EF6395E52DB8326CE8E3AA928CE42FBA04B1E7F1AC7B73296CBC1567090B9E92238859A87686D8E623B780F0376B8537F41B1BB102CC8C480C0B6C069F562468D4E1FE111B24D51F63E9BD38C47F35D8C2B5BE2E737274229974CC4CA63BD0E1F0446F6C4448EDB2498F2376EE26BDD8581242703715AD434E425908D61EAF865FAC5E82578EEB0525F54320B6C264F37DA36B55C2308D4FC6C7FB2F4D12A88CAFD93953193B7CC46804A0C464740B4972A71B7EAB5F6098FF78BDD452540AC5BAA894C10CD69A992217B422C88CC7849B4D8357D86234449B452AB4D49EDB1D2769512CF8A797F5FFF4E1E0A3FBDE292D91722D71322F0BD48C68A3CC998D03F7581EA7B5F5150E7AF58A076D09D103E9F64E61A2D375461007210DB511EA89FC4EEA75FFC71F7BF31400E7783F12F69A1EB5B7228952E2CD1D6FD57109237BDC024780006C229EAD71EBF4B543647FDD9216D98DC78B43CFEAE12166CDEDDE09B52BDCBFF089B1F7427EAECC21CCAF3FD5A35EE72C3107DF0670891E1AE12C1FB81581F3A45480F1FE06BECE6A494074FF3C47F90C961E371E8014707AB0FD004D19166140AF7B1C9D6B7E4B6826601AE104CE18E17939CF77C2A31F711D5C7D5126F4CB642178CE542973466696FAC1A0858ED62E4F2741E47B83B97DCF4610B1E4E262E700A06FDBFC6709BB1D4AFA7C20EFB72E0D623389DCCB049054CBBB322E63B09176E2903DBCE49083B01EB07F140D498B793E149573D8CA91DD2BBF8DEABAD9CECA0F896A7B306C22F8A761A65CE2BC1358A6ED07327AA0FF4C0B6E2906882A12C50D61D021A1316646461013D8169C4B54C61614CC9EDB2CE0AB0BAC96B36908BA3ABDF92D11D96EBBB9A60DA780AA58B804DC6F91E54D82068FE2FB10EC1FED54B794836F54503135A7F91921E2BBC2A61C99B6A0BDC04FBD2D4E7E430F16B5D3C7F06243517452BB7D2D51340BAF550D260A26A2F3B5451AD7D4E3A70CAF63F92E25D137C9E9B1433CAA5502DA269211F58AF2720FE3F899282C2C02B78E66D3302C5B9DC04B98197D3685EC4E6D4603D79B357282932689C2928361022E79C197A470212A69AC2BFC7505366CBB2BAB8D2E31314FFD77A04E85076D76948E836CF2A87918D43208CD856FFA33740FCAFFF9F690B2E6B33F1D89F65C71", + "signature": "6AE10E0133138AE0D51C77B5667D4C9180E04D0935EB5F282E696BBE794C8B96EB6A21A232C9366518132BD8EDFA9AC38142BB9CDCBA77C729BC4D1127A13933DCD44630D3CC6D1CF0242355A0DE121D15D7D4618F501E509C4E0BA296BC956571AF19BA6C8C2A75110DB6ABC3E7C682E87EB280DC29066E5D45C5D318DC3F14396AD3EE29A772117429E28A7B423B54470508A48D67CB6395190855A0D92B30E71B34CF7F508658E7268A27E2545E6B79E48F7C69ACCB09DCABF5BC5CCDB8CA8CA8CAA2F2869773349C666583702F3BDF94C40204514DA2B43A91443B119EDB0B421100AA587CAF238A87F916281435AA6FBF00BF16AA7BAD080D60B35C53792C438CA39A4BDC72BD7CEFCCFD877F82AD557B176DD5C28E78563D1DE719EBEA1099718B0F4129A493C11CBB2378F989D18A97074A2E0F3338CCB9A8A36C1B3749E7A99E7A765C70E5D60386C71BD4CAB64BFDB815509166D5F55CB4A380C8CF24E6BBF61AF3FE7BA3529D84B11FCD6BA6E18B87121857B00A737B0F3D9665720C38BB54C09C8D3917C5AD646E3D01359724534BC1910AD174761D64AE6F796900655E0B13AA3EF2282DFDCFBFA5B0F6585D33455D7D86DC6BDD252B040B66EC6A03FDFB4C06E54C734145817A20C42E408E7571FFB9D6D258E585D5904BCD45D16CA6E44FDE9A25E06CD3645A302EF8F3589D897181450C178E4DA1663F2F5960B4755A0107CE43A265E6EB0C9C267929CFB1A93ED1881798E9B8A1D91CAC83E63537FE0182D022548B60CF0BA47B6A7F90CBE86E1E5D39101C0D2FB333A82E2E99E9E0C1AD46DF3FE876D144FCD3B1D78424C6C5CF0F6E0BCB447A6E9CC337481F5C14D4FB74D764FB38B8EAA511951A50F41A4CE248E13E4694704A0554853A0AAB9405E2C274A4FCF8B5928667DE041E668B17AC577173B0F4CE34363A7C2AC9C3E0A45A39A46F0248BF3D45DBA806A230DB1DC7B0BEE80EC18BA8F042BD6FEE173177FC0194124AEB21BB06FA079A1BC80758B347E4B129D69EC6E8416BD89062BACE16F2288076469237231B6FF4902FEAC3BA7D884DB747DA6371E792827017778E43708A421931115EAAD9E4CA316814904009F1CCD36763FC63038641BBC4F6F93235E16884F8A12F8D71621354B0AE4A9EED64DC5462917D4B35370AD9EC8057ECBE3A6221FE8C39B11444D4BFC380F1F4D5AD18091059AA5089E109181247DE78DFC231401A3D517E9DB655EBB914385BAC1B2888E3837FDB08A9E7AEC206406B848D045593BB837DFC41DC283CAA753D8CB64CEDA3041B2330BAEBA2F1450F646BE15E0B2A46578B1F54A73FA4DE57FA1D632F3FD410C0E8B17C11E197B7A17C522EAC6FBB78001DF9F96CC5F6116635D404AB454BF4450D536250B80E813C8F397E038590011C66C5164E05FBDE695482185F02C4B6B566BF3FA564E9232F40594AF96C96CAEF18CBEABB292BA546EED3A1AEC1476A8418B25DCE79F12D7B4F89303688539815E05F96BEB3B1818472C7E4DA7435652DEB5FA4277F2A810831F88098899FE2EEE35C1B0E6F74DF159D0631C5683C2D7B86390BCECC534CF69F3AF74FEE59EAB25B634333470A55CC49C28C7252B1CF4C293EF500589805FBE5CC056573A10F188A02D050AA34289A21D8B7D587C0A288114E47F346DA3772FCAC58CBAC669DA616C9976C56D87CC275AD463F2131DF95460A151123C964B01A2B908AEEEB7DB3E2FE12EBA46321D7A3FCAEBDEA0FE11B78605E3C8390486CA5D484E6C413847BCD8C6BA1B00BD2322BE537B173647BB63BEF929223C6AEA687F8ABCC4A8B81C44F0FE24588D2C40BF76590AF7157E2E4409804A28AFD25E36275C34A976D22213D457C162ED9274BF52E20842ABC94B2A1D6A4A3F9C2AC544060974DD687C2BB96AFDF8C27522C0C438E7E0DD4DAD7AD640A4B3ECF50CB6250C0A97FDDF15D8865421E490F84650144AC489AE7920C4941895D7B2F1911513E428127562F9446BB706FC06F07BC6C9922987A970D4FC21937BC09F072BEB132BDF8014281BE75BBE6F8C74E337EABAA16A064EBC956C188787CB34A83D5698438AD22CD4FC80781AA1B66E5A2AE0180B50B77FBC07EB6EA60246DAB074494CC9381F6011C2ECE64F97B2F5CDA92FE91B5533518A7DAC9828FB33ED428890A7FEBD0906095094576CFBA1048665782B07194839CB86719DC91EE8C2F64D4576605C2B55804299F314DE8571D0C58C78F071FE810B2FDCD3D7AF0C635303B6ED0774637B1E563855D54D2A1B0FEB5CBF84E693E512F59A13A20E5FBDB77510E3356CF211DB09CB471DD1043D9940DC1BB6A26CEFFCA03F48BABE03C15226EF29E0DEAB6108BDDEE6462884F8708E79709775AFFB39303D78BC51C8B9EAB5D91A56F8BD1518708EF243AED01A637F525E25F297E0FEDE03F3136EF23C4B33DC1D256CC92E3B6AE64C368542AAF553B1605C94C255012D605D1291098D1F0B855D137BE49D198CDD3EBA0A9D9E7519B8A5BFB4DC3F338219CEA7C97251166B5004CEEC23606421A8F9248359E5346594080FAD04EEC15C56FAC9D55EAF4C399B1FC8D68501B88002212FC0E36DCAF5016371696AEE5EBE4396C36137C535B13F09D490564D38D1E0FFDF13902F7678FD06EBF8E34E81BF712D918348728BE21965F5956EC8AB1F5A8D8276E6A72B4A69FB7C5AF658C5DEE4C8BE285ABAFFE0EF41529AD44B31EA310C3665F2EE61B5817C1191549DA070A2BD4BC790E283BF81C11EA05A6E4652823EB3FA05283E784C4143F4C029A6A7D485A1B892F7462CC26B1879B4668D133DCF6B9827D3A91E069B25DFC72EF00FBD6FBEE4970E26222D81874C748C746DC5564732CABCD0FD99983034E4F5523A43831ACC1E6F3989FDE186D4BD07E15CEECD8E68375A5EC130AD93C0837A27F5EC5810F6C87CFD8E37BE6117496F7C283AEA1DD30A5FE5AF6F8A94867A5A7B336B4070B1B5539608BE8D10BF765F6984FB2D0AF376A7DD4E5E25922078782B77C4E5D5E086669D265C6306CB40BA5755E6D83D93D33C89F548FABB20DABFE7086B9E658F4A8BC22C11C8A12A106C534EAEA38F46FFC84C2A4D96C5DFC31F6F21B3FA32F988FB86A38D7103ACBCE69C5D143C33D1186C1FCA80A13C642487D5B221DC76556249EC81E42AD4DFF51EF86F2ABC45274AACE72A79A7B985412A3E94C92CB824E3B54F328FD2F06B49DB12338284DCCB5E03D063CAB73B939FB59A569E4E693E53B446279281BEF3637B55FA1C77DB77A389F43CA7E00B8711B32F98C9FFB2FA30D66075DA836CB528CDAF3FCF65B6EE3C0355E05A46DD0DF6B3D71E8C705B6C14514A537627FFCAF805F8545A86865D9EC83B243BDD4A444D6E09A7F26F5C30D824C39C65E1596BD506F70E793CD5E703159736F7A7C1B1A08A88E348FE12D0D74A190EE4C8CF1E2FF44B9FF40A28DB611296835E251E8451068C1016A3EDA063242D1DF3DDADE57998C1FCBF7B9F988392916D4D405F82ED894AD693FEB4206E1131911E3617F5A5325701D01AACD591469026E10585C1A73ABDE7ECA706C97F48B125A8E101E55D0262334750AB98A8C4D33F98763684402C16BC7BEDF35AC349AB471E3EEFF92A79AE0F11F3CF17EA1406FB6DB669537CC0E46F0A7C42695C4595FA2F0E604F048357125EEB01AE824FFB63B70F10DA410EB93933398C13B485493E4DD5AC42744B00D2F81BDB3C7030C3DEA36BDA258AD26D4540D1FB83C7E651E31C0A2F7D06A328820D85321B24E4B798153885D80111D17811D5ABB97C69B24E3E82B44649CB8C5E828A3D532DC8EF2C317890BCDEB43571EEFD97780E68E03C1F751F5EB823D75965ED7714397112774934F465F61C25271F1AB2EE80BAAF7049D1E0C78EB59BBC3594202F002E883B7B579B98D0D4865ED783AA0ADC84A4A37E73C3CFDB5F464812AEFC6081EF899B5F4C9F903279E77D39B2DD0939329B3C5060990BF8E0BBA6CCFB6F7BECA77F48585F44F8CE7293D121335939E3AD785BC66AB2C9DC955941EE85DB9D2A4F404B3F45C7A68452E6AD108530A1FAB8E35C9EB0AC7F647DABE0E0D50358A007DB71B6D76B9922797F9CC377D675E70D9E166B750FF457A5D3D649153C81CC1B659ECF3656BD864FDDB3C430AD6FE44B21DF23D0827D56899D8F0544472298FF1E12FDA44466822409222063A8BC27A2C2DF44B1C4F56C47062E7D717705967F8C10E0F1A35B0C4F1EDB14B4E3A2ED44163651179FAADB643E602F2C92DC144FD96871AD3CD194BC83951F18C77B92518F8F3013BCBB49E57A4338FDCEE5000EFB89A3DC2177ABEB2DC34C094476A8844CF072A17FECC8E87F8C3D85B776972CDD5EA7F8ED6DF4A123197F78150A2E9CF2E3CF88617E82FBA29410168DC261EF9516AD01187ABA8E189D59DE5E243CB019E5B7C34F5BD158B5E11E9D7BC75BDFC71B040EBFAEEAEFB7639355AD3BDD27AB9DD799BEDFA24D2AC5566DE15F46CF601E08A702B133D391B0E236951AAB4BBA409C5B8C49EA0D1E2DD2EB9D6EC67F76D12571C002C1E3448FDFD0FD6D5C070E6B749E9C3E6A86DE347E34A72DD2B19C51F405B8A4F4DC04E7A7F3E0BFCB51EDD253EBCF47171E0F57E7DC04C0B1ED1054D06B7DD2E8E6FBEDBB16D086E1975676B0B3D34F3D290495051DD8EDB5C6FD727C8A460668FA7EDDBAA5AC776727EC2A155770B5C98297C45F192C5817C0942C62FD9FF9BBB5085F7B197AAF21173E1B2313FD94DAEFE9B76E068E8D6A46F25D6E81E09F34D0337F22086EB2F32D4917A6B5D685E3FB94D919BD8D513BAADC61643AFCFF3B1DDAE63FD0562C3F60228C951217142269183F4D9BF65F438D86739219161F9C6AEE0F65244E85758C0BF3B137B30536129FF7557E5C52F05AF64883FEDD419DF69DD8B9C9EA6D4A6B018CF676E91855B58B37120D84D3ED06C7173BC3BFC65FA01CA02A01E2893FEFC9E0E708506C84698BE652909F0F9793C443635A032CDEC61C5ABBC097997A62BF2894133BC991A19567C9F4549B30EF4C081FE2FC52724CEA974DC6CDCD4042D3118AFFA2A7EBAB82ACB14BE405FD6A764C8405CCCD0D1BE12410855BDF950747EB26E948C7FADFD2089D26824F7100FE574815B487865090CA8D8307D27276C8C5FE813A22636672026C72B81290AE9917FDD5A314029D02BC37EA1C39B592EECD57883952907C4A2A4203CFD6498C19328E55500BA395947B0CE523836ADD259F92C358026CA86169D73D17044AF5F4B7EB42348764488FFEB8D34237F17BA80D5AEE6F5DB8977898B2BEB745B065FC20DC567CB4090D65D82003B466C21921FCC13C6291CEF5B18E6F6F77B8E07FE9F803F40EB4A015A76E18C03B40CBB8C8095AAD7AE64B52D6A1AAA31EE00C5E4EBD04597377DFF1037A0B12D2585E8C2FF784659F3A57CEF7732CFE93DC4A7F11E5124273A656CA234AAA7503246EE53F430A79A0F9ADA4B6C0A5AD6DF6054883339C013FAA1B6BE863DADD11B5443B5E4686C5CA6CC2BC43415A116D2B908F8949FB594A470B2D6017FAD537F066B8F2BF20AD2F376B33633F90BCB9D262EB23B399E8CC8D7632E17B49C4792B2217BBC020635CE2ABE63B1039463C7D069B2B004D0CB650CB917311A049B97560768EC46A793F19FEC3ECBF9493AE80D16FE24F00953348E522E28B2668FE430454AAAD914C385490786CA7D98E6A1CB345ACD0A67A6B57A175D8A51C2B51F8763861B027D29181655D5548E2B15986DD3835404A9A282DE523A045E5DF42FF092144ED9392D589DE70678FBDCACCE10C956AE96987A266AD001EE70422549F7F27BD92748CC06E7D24483CE0B83C3F2067D522E789D849250E7F7588A2DB9BA9D5F439D9369F04CE59A12474CB5FDFB08C2AD9E0889CB0F2056A7170428778D3BEC8F9084072D6C0FAA922400D8239119E44BD7266A43C55A70CFE0984F60A482D08F9E77426AA875AB50748161B48390A43DFF04534054C2A2D5E4A84C804C03128A0D7134BD3AB8E0A2BC7753F458A38B9B244FB654F9DA3C2784CCE6958DE3DC806DDDD84A8D2AA24A8382AF4D11E52E1F47733FF61B79895A9AA426BD060B4761EE687F1134A23EEC3EA828134C4B8108A6C5B9E3AE6913E955299DFBCE6488FE32036662FFB0CD451A98D97A1538F5BC34D527ACB9CE6D1DFB5862FA889422FF32319E35AB53102E566C710D4884BC3357280112F2C694D957D26BD3372D99CDFD00CF55098238994610D18A247BBA60650EC3AD7FCDB208B15C4AFD35A25735844D66A929037EAE673D66159185E4B2B79B48746BD9F046BA5828595CC6820EB8A860EC9C458E7AB183489C3ADA179C40A386B1F33F2D41C8B1AA5D571D1E7088B0ED0372C95824E870D63A4B95D87222C121766B270A3F5523BB6B69284B676C81F20D0F37418FB0B40240414E95B7CCD6E110658CC41F343F4F56BAD2D31A495D6BB2E9141E374AA7B2B8EFFA3E41434B4C4E6385BD0000000000000000000000000000000000060D161A2228313A" + }, + { + "tcId": 42, + "deferred": false, + "sk": "6639A514256A8CA2D510FCACD916BDEC6245D3AC11A035B7C7095BA4DBB92C62A8D0C518807AD496B31228F96E1A2A23096EEABA09D37E615E24E5965E1073DD0192B175684B4F326189549EE36FE38AB2CB29380675306AF7FEB99B2BB8A07D5BDAA761EB9409F46E70EAE199F0B3A72568BF6964E6A58DDC6CC223FC89E27C104004C328694148109306900C0085913042D4B211E2922D60A80C91008512101118C04492344863824C81C20DC8200819C051640444C10470E42286618424149040C2344292161009400ED0203012B10991A404A4B24011A848191800DA128D83803003182C03A5201B4066D9462102442484880C09A20C1047689B140914B70C84B068D4282823885081128222326CA24882024150A4B04C44264059320498926924496950C0841910840C136E1AA10954A2889006864222665C026122304A20A36D12486181306992368509304A1416210B064EA3320403014D918885012051023701101411D33840E4206CC8A888582484444486D8A06C03C6499AA67140804518216024850001896522483222932D18052922344954900DA49890233351C434852025420B230122044D9A26604B266E8430011A2889C120240819461AB76503B50554B2605AB429091591E2122E1A320EE43808C8880D4AA264D3960042C06C24C92959C024A220208C942152B06513286D11B440DAB20104B84804A50D088650A4386049988488A28108490A81328442388EE440021BC811A1B204A1482E13B2842007501B288A24A9092109629BB465002966C44682D140459BA8400381108BC8051B826820466C40301111C77140C89112394444B60020992901178D624202549405D1320502872D02164598104249A0114A182ACB3802D0944552A441C11641C986255AB864D1184EE4B44D821224E3086A0CA30C5A18100BB3900C022C194780DC126264248801B9880A265110272C142025C4328659124423262D0BB590E28090A2385010042103876D61284618C38D08A10D922684D906501A33611B8468098830E3844C0A4424222640CC388A1C05110B460A24004C02132408067224C4611AA62409358AA4C6112322629C464E20964D580430CB388603B44C64C42C0000095A220DD206655040415A2864102510C4300E24A46DCCB28D89180D1407714AB8451413409B323011396C5882005890911293081122850BB94012050018C905C3248520B34D08964003852D8C220D109270D8464ADC34301424840CA480522282D1346D8CC810D4000C22850491B224D84688C084450AC30C1987111803618CA6644A384D09C8012092040301121A4722C1844823A1858AB24DCAA841A4160E8B34889C249280208849A0851C46290B1260D804604B4451C1C2911C0729013381E2C44019962062C28CE39220031824234202C24006C82264483466D2B630DC90880199054C242804424A5B0628D3866C1200896424492025050AC680192921E088812413204988448A368C20A36519006C00410E23304A18A04C0CB96C8A46210194105B82251B05840A15840A185059420E93C289D04611CB0242118100004606A4C28D1145114C186A922260093921A4941154C669534625898208C0080E4848061197411AA36CDAA80C0890655A2284DC380823A44CD04680011370C2840C8092249B1648C134801401445888215B4620A1A84D0BA04D4006061CA769D9380C1AB78D0019669212911C020E91A0909232515C224D243662113242CA081104A950E4C02020C069E3242E0C3109E4188518427261B84C840422A036605B1486120022D29881A3900542480613A54914228D4CC44D1B112994403112C6894C06665A384411499083904864C82D8B002DA3142CA2320261303044342CA2322E83464A923885C424690CC60C0926528844300416600C0741D0126244980888228CC214704B9069C1C84CE484440093449A226108850102C2212342282234650046698938660B371160840D58120C09102110B4451847480C434D1B33111C990459480D90260C0B464259B82C9A200D4416062139310BC38188120508806113396604318D8A928509372698380E21C925000384CC4228933031D2982C5332461BC10D5894451A47118490691B386083482D0A8921D8B82941928120156AD212414A90250C248202310DE1346950807101106864808004A5604488712216244FCA3DC070EAFADBB8E253BE1E85890557BA06F6FE596C9EFA6CADB19A6FF51D64B2F169E1FCAAA7761B8E4E94A6DDA9B390A96D7C0BD5AB3282F4F4E310FF1A7745741B15A80D1DB35B18090B1C35467939147179082650854D3481AC46C4D5F372ECACF58B439D2C8E9BE32AF5F647C4D1C8C06C5FBF01D95D35E4D7EB2D0D0FBA5B152CF08525006714C6A1DCC41281FEA9C16F1950B66DF989AD4671296C9BA6E565227A47EE10536BCCE94ED83E57092ADA82578FF23FE0C01268FEEDCC0953EEBEE12BE828BE36415712733E973D6A984747296AD5D24CB48002483869BEC1AB4AD0487BC6AA09CE9138577A5CFFAFE08119E3142803CE2C88D83CC9A102560B8A2BD01684F0C7FA1480421F4372F88CE04C3BDEB9A09FD541C17C67BF4D06781B6B8AB45A7C1DAF153B5CA37C1736A12B7999E05D213A2501AA67ECE2B92710749BBC902E550C33FD2A265CED7D3A88A961503E8C4A586867A9A2AC605849FCA19DDB92ACF22D481FE8A16B6BEA0E916119A83B8826B7B64EBDB9A8D7F5517A8812B9369EF1AF29818940FF4C1A41A8193BEE2685866B887E48DADC162929938202BBDA46D7FE090A185883192E45464E88026AD24C12B37FADFFC15956F0A2BC1AB5E4917EDC664D3B35E3C9E2CE2A73E9CF319AAE5A1EA8161B747989D2269B80E82086B677D417FACA39B64DE63AF8DEC028ED2713E7EA645A9367DBD8A4BF6E52BD45082712BD30A12D639DFF1069EB150941EB3204FB5F7D12C655F22594A70AABC428131168179AFD776579865A2BF65988276B9337B553EF75BCDB793B67FB602583A879747CE0169B72E2181C6BC1569A7353BF0476F7DCC04F7410F1C94C6C1E164E2ED651E90A3288EF61DC18B89BD8746C0491F680EAABDC51B68139E8EA42ED4CEC08CD60093D18EF38E26B1615789EE6206F8996B34EEC3773C098D61C0B4E4ACD835C98C16B0F3DD0A8145E1A74889297FDAF7FF20519A6184013E9773BACDE0705496D3B4103E5240759EDB954C9E77A05B20E4833F446F4CC447CF862778E97A388312D7AD5E0D2626B298BEAB7D27F5CA67EB73F3CDB03ED0239912590C787F9C3F4B04B170C6582DF1FA489C7F8FF48E78C3AB63EEB5CA0CAD4BA17AD57EB6181FABCE3D00D31602FC3ABDB1231EA961A5F64558D2678F963E603343FE35B4B97B60E102B95BCE07BA525F4122692A28F891A77A87F07C6444AE92C621875CCB9A973961C55D920BACE5050C42938B6FB81663DEA18FAE1625B13FA3225CC80FE23D557C35619214E140A55CE2ABE8BE2D82122BDD702B5263498B9C2957CD3B2D933F3C62A0696A0CC96D99BC106872F0E2B6E70BF9429530ED9B97E68C4ED660456D7A79E37622C0C854187985C9928850A15FCAEAB8D8D9A3A7CCA7C13C400458DB650B0B37C858F52B04FF135B6BAF86E4D91DBDFFBFD6CA957B3E1CBB1381AF4118D9FA13B70692030AB19C8D068ED620D8E7E150236B8B988C38B6D4002A3B4FD078F58B96A3C4A996A13F0C6190F783C6E6AADB8D69BA275D7045E1646C56C8024F8D1CDA3EBCDC42877674E480A070BC26C118504525595F034B4485CBB9C4C48E5B5AC4A250EE8A98A8D0448B5581F9AA1F92BCC10199A0A63AE5AAF39D6C2F82D64E6165C9878B3FDF4F3403ADA84A57202B94F4B65B4EFB551477FAC6338DEA7281962698CC54110B8F15D4BEB4C091B845306024445EE008933A8FFBE63AE3580E098A18FE33681D926D46AA99F5DCD9E9C6AF4CB2737036BE094EF63C0310A42DE5CCBCFC75AE57EDF5DEF3304BFD6854405781FA983BA2B582B631E4773A62CF8E3B222F9FB0C484653E7DC89851C989F62596377E35BA2A05F544D6C2AA1FFB71365BE259FA6AFDBB797D70C2E40474C2697A510E9C277133B26C2ABC03786589859134F5719314F392093125F15EC2334A2833BA6F4E634DE374AE5EE93E7C6FF37D978117122A19F5522E63D637E6109BBB80C95AA807B205B78821DE56BFD0BA9949BBF0A58E2D3803B89AC37DF91955536C5381D81377AE430C261992EF2501AB8FD653D715C93F63A98C7A00667AD74DE5548B685BAA6D301D4C6BD9E40F7B50434D8E88AFA19F73986CF55E5F318BC5264F909F8DCE692637FC09F62E9CFF2AE21FBF37698736557ACADB9E782B6E60A214216FEA674815507A12933B0A9DF9165180579072283F7351FD9696B1C7EF7713845B3EA3F618A0E52ED23273484EF1307E7082818903C5AE7A5EF2F11E5D1E813B8B2796D2E134C43EA733DEA8EC94CA03E64B0C06D7A52C38FD63658F549E49872BADB78020B9DD64055EF006D5D92FC0642EBBB025C44F436B9586C9453FDD9DF65B94ED020A5F647717881470C0C27C266AB56C3115E4336633E492893DC34359732740E954B74606232D2F6E988CE1FE565527395CDBF66F1CA04F42B34DDA2937857589E3DB5FAAE2B0CC97A68408B2D73089AD0098CBC66F03BEB12FF72A00AD72C5150BEB7760D700D634A0823988D20BBE9237B9E1E60737CFC7A97CA65AE467026E3664D2D2242E73C3D43AF26D33828358670BFB69A3480CC4483114FF22D93B452578CDEC1B93C732910438B66E30CEB14EF03CD044EB6D51E5AE1242EC49F176A4D888DCDBC6036163160D404B5B17F194BEC4A1A8FFE396B6A1E3500D2C1B17CC8CCA3F105A397D62B4462D3C09638B01B6A60AE76D93A4D7A204F8CD381C7ABB9C06F9B4F835D89A69A5F0424052C19D5AB4FED48B4CE549976F68BE60C54BBD5CD80E8A0DBF80A75A961332ADC8377CF2A286068B8E4C7F9BF85B2FFBC9FF2B9307BFE33070764C49EE7B2DA597BAA459C4C0C1D5BDA7DA4EDF5DF2ADE76F44A2C64576CAC913BBA0059027E98666DC03610189BD709BFE88F0AC93224DEF65D86FEB422563A83BA823F9F312CD13A7707275E3701369CB009EDBF95E966DB3DB9645F493852DD1F71B025102D2B5CBE6DC315DB57D4E47C9FFC1B65E0CFDA0FAFE7937459DEDBB5983FF57ECF7E1D38E9B67A0CEB91FD7CE01DAB9FA9CFF2A4DCB19C8F74A4DE51DF1D466A44FABFADED4CDA52FBA424B312A873D29DC420F8FF3C94DA1C896E0D54F8C882BAB83573716DEADC439904093EFB720A1120A7CD9E18DEE7B6674466737C36948A4EA961AD122E3C461FE6D5A3843262A3845CBC97E37EF41BA9274D0EE4E77CAC71DE5AA39E860959E353AC28D1A545BCDF977BB4BB7BCDED646BEED12A6E03ECDBD2FC3C1D845D5C9299882D15A295AD1D39888EC943216CC0175AFCC605938A2F72EA01F1B7BA77A954FE1CDE49A7B7E224D1807E81BD09634346DE0ABA64C0F5B3D2E6A9C47C497D28CD231A70347DC9B9713E1FE77CF42DE2AFECDFE081395AE1E2198E2C8D5FC05606D648F18D3B5E0D96BA194C1D9E4985506F6A96C48F1CA647D478EEDAE301E86DA2D916A41832D28A6315A2B95381632A3CFCE232621C8477680D4DC096A57163E4B570DC6AA475577A60166AB550437AEBD5810B523E4053AAFCA5D5F702F26C6FEFB18637B23606568C43AD1047AAA51E84178814319C6FE2CDA8128B7156F84ABF9D11D201390283801BBB87FC2AB6B050539D1DF5511893F809CA261303C54A7C8BF4D433E330ADFD495E3D36D61D469BACAE8F1F8814777B3D20B4F98EE5727C1826CFBFBA2E5BC624C4ADBC32519B731A666EC67D082570B1739066312284C1F560A9CE45EE0E576F5269EC5C325667D13C3A62EFBF24236A0598F973CA99C53DA3E5D4130FF8F4791E5A900B0B2FC93364B234F85926BDA82286AA1B04A2EE280357CB6D2A464E8DFE9AD6780BB2A6937F008DCDB8B64A904E9CAF6B75A4A3341D068381D6C8646992A7AFFC4C2749940FC7A51D4C7195F291F8A1E3C4E0C7AC189669269036A2996B9A7A1D696C35CEB82DEF7B4C19151E1DD8AC8706E38FFB945907D2D825B06F65EB460A5F51CC9B17310FB878D73A436788DDB87978BADE32BDDA761EDB2CABBF9D44B9E7112BD8D158B502AA34F7326244E2FF83C778B5AB05C2A8CAFA7E218EA97045C658152A21D8015B4A62B27ECB39B72CCAD51F52D3F323EF61F35304BF52FF7940642C38A0643181A6DC6042F8E4D87BBF40D04770899AE2165B39C2ABE3D00E41311FB1B3DD865567F9C60F5FD03AFEEFAA9EC299B50C1F378EBBA3700DF56C4EE64548C29A6ED299B8392DA122204FCB5CB990E898379DC6CFE26B6C37FA4F25066BFF6E296D1EDBDF8578A5E939CFB07EF8D5040DD3F46AA3152D5CD76285F9F864664E465FA66E338CCA55557467D6E7B443478CA00900A6E14FB8C7FE7F27984153A3A1CF070E91C8E520D1F6DC0D627AC966D6AE8B3B10B61BA99F642C0945174E3D62A3448A0F90C3B1F7104409FEFC05286B4AEC3BC389698D500E199F70F8374AFA60D2B4F83A22813F8121FD99E37BF310733F61635E4690B0C6D0498563287FFA83F2D677906A4CB0630CE3A768FA827125B8E37A5F5C855192762B8ABDB0DE0C94538E441620CA1B3F24425B37F7C13A9A55EF08117B8E5D2624A670473741449647E2997BB4F7A1E08A2D58ADA29E80F453C271BE545F2939E2F95342131C2C9C3E4FCD52C24F25D3D3C6B040BDF0B8BB0FF47B0E4A6EA11A3F3B10B68E4F2225D5A5E4946E6033926EA55A21531F7C344B06E42B49908C8F3D43439E949FA1", + "message": "36DC7A310D995379B796EB8F9CA346EDF60DEC7F6C00AA311B3E09EF96A6795C4B077C1D371DD8D4A538AEB78B81927D08008E817A6FC6B3F9B14FE56EF9B2664E76112F214EEE848E67EF33B4A4E26A2378E9480CC7D25C369E6C25A2673B946B635B6EECB5F5F1499B484DCCFD5165D6F14CAA8E1EC9A9E4FDE417403720D7B4BB30060AB95C6F227767D671B75A1BB5AC5CC33EF0509C69652748251869B072B9042618071233B48A9BDEBA330F0C450A2FAAE79291B9E2480D1CED11FABE56210A80C39F25E5574356CFAA32E57782145920D6C0D27C3AC7C63DED6A770A5A45119FAA92209F2A066AB90FCB81A886FB87641C550368C1B412E43F4FECC2FD659B2BDA6B7309797575DA2893314DAB058DD92C7470F570EC0B1D9C9A149FE0934D40182CAD14D5B3D98C4B7454CDD2AE7E54EFCD554AA5B458888048BD5201C04E7D6004FC2A597DA781BF15AAC9748B6659EC16602F10AD44145607917C3599A1F53DC95839086A6A4FFD66F8EAC8AF8F11C4F2EBA3B58C46B93D0494C4CDA4E8B8FF7278049D2B4BD7BA16BC57678219EBCB5E211D51A168B5CDF66453412565B9BD606CE29A5A70E60F3D451D4214B0A258D6E9325EA5196C55125F0E115B14FF34FF6B172471C2B4917FC36B0DBDC82D0475AF56249AB9297790535C0F0265D2A853DB0B41B418072D0ECC17CF91FCA86F6E10762EBC520F0AADCC3C79EFC25E9692FC0A66389B15ECDD1377A9C3D744CCCC4BD160FC65A45D4144DDCA04E5408576DBA6D5C875BB4071729361B0514E8B96405E2F48D47138D2D2DCF4DC865F717428FA1262DB0D2B7B1A356E9E76301D38BA506456B4AD70ED09B0D5A1375AA6E132D7E06F8745E7A5B5E4F6455F4282A87D2B372C40A34C09699AA8C2B2E060107BCDE0F9D99B64F17DA5FA01B6DA87B1738882976B21AE12D1BA0AEB37644AAFE5AC20E7F3F631FFC2A24EEFB61DC37485DF27FD9045BD9BB5D3F00B9B2694CB94B01E7A4F0D909B8612DD28BD64E6C1C5A612CB30DF6004276FF58491B8129FCB0B539CDF891A97AB58DDF04AE40BAA5781C3AEC65FD7E84DFD0369A53CF36303270DC80E3E428854D82B08C7AD022BD99AC0851B16C7D8D462DA21126F70D661A59E4D0FE4441806DEC48E37AC4A271F15D916135408A2751CAD53564967196763B512D52240B2B0D3D924B83CF482B5316B7988D73A16B773705097F5ECE0027CCB2C2EFF598B8F61ED4D6BC015E56D4549432A6A95328FE3122EAED0149E2144E4CD2262C7FE7495E41E0AC9FAC9A11E21AC940D25E74AED8EF6FECD21747FF8166589B7038EF1DD504F51E01F1ED911FCCF44949638AA6E8526F0B9DBC5E536FE2AE7D4DA9DEE66402A45CF55D0137FAFDA9207AA7E22FE396455F2F43108961FA6B0339D89EB8ED7EF13B936E3D2DA18E5EAE45B05DCAF5D845DC62CC55553E37CB328AA2C649ABEED0D862E8083962B81B84A85EC12D3CE5B600123AA7CE4764139BA7AFE5CD02F70D06DD9AB0BBE868070A9AACB951D362E2606FD940A8F5BE632393E0A179C2A62151A094901F5625D952D39D7CAA87B77C4919A8633458AD9B6DAA16D1B1CAEAA8075741094FBC0C08D30D9956812C1D3A75926C546ABD78A2B9D44C1B6EF8D6EC2A2EA8B7C23D0EA57E1320ACFB576FB9C575DA98B714D6B01F03364E618A2C03BA84BDF0E5D2A0403B1379416D87B5E022BD958B0C9170E82F8E9A727D39C8F7549E34A14792776AF0D72A27FCF63EA985B3882A717091EF35F5835D4DA127554B6637AC313BA3BAE8170B9E70A6DDA2DBE813A49F045D8C3A65ECFB4D5F71FC75AADEDAA91A81A958273ECF0CDC4512F0D0ACCF9D9D001A30D0B6B2D50BD216D6086AC5C9DE7388A7B1319F2E9E6CE128B1F72F765804E060A8A92C93295A99C66D6D79BD7DD4F7F02317927D60B2E9FD59EC3F95A874337228339EC673BBBF53BF0FE1886A4B14F19CD7FA9B771894377F904EE8BE48D64EE5D40882C684C81DA3198604FA599DA8D4EDEE8EC3294620B6555B3BC9627D4514DBD1F7E3E9DF7B56BDB4CD395A8CCADC184B2B8DEB2AC7CBEC6C96001EDB67E6CF6F872469B110097C69EDE1121D22FB5B5AA4CA540474630651A4F9E8F7B0ABA5DF568D882626BD158F925F8DCE1D81668EF7CF770DC615ED0F5A807E25991EC97BBF2F9E997A532A1BD82A2A616250D2232F72067A17550EE516F28940D8EDA9CCC0E02EEFA496010E499E62C50B03F1D3C1571342DB8A5BDE1F432F7B6163BA3AEF35656434937A42C4E1F473331E38467DEAA483189902364463832ED8C5E04E0195D3435A6FCE75EA3BDBDDB0A0319262083141B1BBC0C278CFD40319647E90BFB51374B0AA5EBF3C564EE95B7AF618669C935756AFF3150A93EDA92F0ADC29253758A6C8A83EF55F97F1A4C0DB566668F30DE59D93D8185BDC1CFFAFAE472E0B0FC4B1E16F0B748220EB2EB85EF127838D576638E738E9F93A05D41CC1264AC6BA03B202D9E3B06946CCC68DC15261A029B0C5E91DD81EC1D79BC51F74BB5EF778F00AC091513443308410F60AC1850F2548C8101DB3B6B4D453541E36F0ED57C2C14F465196F8F1D0D3ACD49CE3252BAA0C10521311B8B8366C579A430526ED58BDE92FED3F0B359ADB31D67BFD212BEDA7236DEE4615ABF13C856CCC93DD02AA28D1CE1F12C2DD69FEA828BDB9F4CBC9242E1017D1063A7BF842B00C75243303EF9060C8EA501BC73B3EE470919443EC91D1F0D6D0F23A899AB86F2E8A0898D318BA520DD15D9B24F4F10A1B9FC52457714A151E075BBE419E4216857500B8354A8445B5FBB526A6E008229F33D8DBA14DD42F424DE3675E704DB308048B2D17904DE46B76622BA08C62F17EBA3E9F414A1B10921858832EEFBC282755B319E176ECCDC32A25CC5E76479AC112570AA86518BB1E6CA3F46E010E8132C0A1E8273403C5C4D7046A05398D461CB6843D70EEF8C94DEA5DF53CA1A4C7842AF5DBBC6451554FC7F9913E56957C51E0A602D882BC389C5E5C7899539DBE6832B0AAB5EF26B2C96CB03D1795179A62F748CA501CFA34D5ABBAE3271AC1F005112645F10863AABB062FD2C781E4573173935B5392CF9E88A1A31989E1B8E94F77CEFBEC591DF6529C6D2FAB72E678C534C4EFF40177C41D02AF0EFEB6371835CB55AE0AA99C0653876CCB56ECA127A0A1DFC0F9EEB49525C9A5786F618DBF57C41C5CAA971A9505BECEA8969D9DB28B0E707C659EDC42280035254E91C522300368F49F2C36211E455FD620DC956AFEE41A2493BDB2B0B8AB78E0B838DA6584FF753BF88CA6A523042A285F84ED90E0FD5E28F75A21B53F618145C16925486DBF6B1E7D76585D0D117EC562E22239E14A49ED714814F01DE2B250E9B3B6A1C99D1A71CEDEEB3ADADF611C4A4F97E1B26AF9780AFED5783129FD58B1232C7E2DB9050AD3D494EAC254DC46B0461A1B4B63840621D45ADE97EE5663C9BD8FB7261152545AE35536611B5C65DD6D66878DB71640EA429F801D6FFE291B06062EBAB9B416DDA7D261A46E58B154684E86176169CFDC4A60EA38300C3D44F9A4C9DCA0CE1BF37DF8F786F28B5B3CC7B0199D3322CFDFD2CF88C5B794C69F59543FB985890471DBC93A313992ABD33691CCF69B96A9396E5F55B54FF7BCA82A31199E5E81CE94B6B523EC5C3E2F2884D8BD744CF0C072E29E4B542DBB370FA5966F68CB20ABF40619E76C099BC7A9A373707707624E8999D4CF0A75D4AEAE113D7823D7D2ABF54FB4E68B8A6A57A198B128DC69584D2DBA473B6725FBB8EC9561D6614D606ADC4FD9CF449008C0D54BE4F62EC1441FF79EB59442AEFBDF1F0976844B4FA3969EEFEA10794FDBE35E89EA52F50AB26319BD1604D3FF5AC660431F1073575ABFAEEA00E1246DCD1D9399939D655C222E19E9DBA5FF42709FC11E7E365D7F7CE2274FBF1738DC5CF5631547549F2BD4DE896C8FE039720F5E0149BD81533022DAEE22B93A3AAB9AA9DA15180EA071D98E9FD176804A5B04D089E9C2D386271A8B13E7D668AA74BFFFFCDA3B4E528937C41D43A87DBB46C2B49B63BEEAAB978415536A87D845F6C2484F21D71D0F904438C46E7B0A3C6DE5ABC01C6F7CBCFF21D3E74AEE96C20C32884DE4EBA0F282C0FAD06BD9CD6B7B5031F149E4788F102D2AC2C99FD09B14A4AE3BD6859CAFE6F5A494EE8CEA29F49D871B79BB66AA6E6EC3718B97E83765E96D5603B209027BBBBCB09EE6FDE3AEB65AB1D73684820AB1FDEF88086B93B6338BEC7088E04F5F6E520E3D715C6C5E5B79E73B9E7AE1C5EDEEE4015860CDB9FA21FB434C3F28AD865042284A7FE9A5FF47E8C6158DD83EDF28BFB18DD5AFA07A48BD5AF25B9644400CC976A9B0FE9D9071E708113802A78CFDAED28378AA4FD6FBD9390D8A17D6500A0E1835652C7E0B332A382576AC4381CAD51A31E64E5E24FEDBC62EF9D0CABA0C8EBD8B94625207D0C8C1C6DF4EA2B20832EE44D1E2DEB799BC97B7245EC404F10764296E5BC4A919EC24B4F5F7D18692FA8DCDD5BBC170A81BE7590B7BF4058DC7BEA0C545BC85F0B3F0936386C37115A333285451CCAFB8397F1AE1B56D0A8F884BC968E729D622D21FA26B89BA2726C91E6886838DC9912797FF2BDF6800665C1D1DADFA4A240BB9BBE21B6DD750389AFA49C5C366ACA5E9C3B31B358FDEC42B0032D9E2C22112E43BED2023B364DAB334BBBE2C3B669EF700702B5D1837A6EC15CEC2B2036D56B8760129F593A669FF00237D26BAD9F9C2F4ED4018D998E555D2C3CA1D53EAD6A1E27906353983D4408904E5FD9D79AFEFEC26ACEA1F39218C36637977F6E2F3F6211AA06AB9D5F991C76F420B152BC95C4BC10047E107CC82E3B00B2325ABBFDB0FFB2966D5FBA0EC7E8DE1DBCC053C4186AF23A6BDF3F14A7186665AC2682FB94B0E10516D500B7F67BE4BD2523E194A1ADD8B5564FAD9105C86B6D16B08AABA604419D55F571F11F4989197144DD12867D1636D12800D54D36FA88C620008095560103366711B8E3AADD5624FBC7FF51318D17311F02A807770466AD559CFDA0AE1439442E4413944855D4D0074D529CA8DD621DA02FA98F46327A7BA600387EAE5E724D64A82E94ABB760C891EE39F27F0CAE8D1AACFE20629DEC5DD9BF4CA91E65BF413FD2A9566B7DCA9E500C2C328F533AF2A957E46D9FB11F0DFE99127656B1D4BE20C946BAFF58E5FE1A9ED282ABEBF6EB35A35AF324DF0A858CA8AF507CE43D228ED81D863F7096044A084DAA37ACB6AEE98E5A94D363963D4F852B955C2F076848092E6199E07990372E56BA1D590BB83D0C7F834C852CBC39B666B801CD32A0C36B034264F3BA6911A719001FD0F4B63D2D628FD0CAD34B4C9355534A8A38512E758B110F48E5A09B504D20D178508E09B1423A1E61164E7D138B4A9455B95EC8EA786F5FFE67806781F1E619505FD7DDE9A904E9003CA7E5EA1077C94C228D36667031502D78B3B52C3B5A09FC398D8B5497B6E3F0C5381BC99DD7B11DADA2DCFAE352DDEA2C749F8CF5AF39587083C2C19576EFFE871AB94D1C7CA2183FABDB74B27A80FC4F20CB86B46B0B7F86384540EFF1C888168F74634F2C0BF7FB54F7002EBF90B6C4B2B25DFF068DFC7D087A27749D6C36AB0A33423044AE027DCA8C42678987005FB9DE5C2774924AD2A5A8FD2E89C288975F89B5C0EF70A20EDAD1925060A12606A9B03626039635BFF332A0E6BDDC4F5DDDA209AF8DAA0FEF045FBEA9523D04458FBB0BD81F65396938436AFF5FA66E997AE58D64E7B5C1B589558B3DFF6D035E31008D2C76CA426B07F1644F609945909DBD16559B36461CE882A361D0415A9D93CB98A5370C56913A299B2DD1AA372CB75C7E590A9629CAA6C439CC5C7D94A21F36F998C6FDEC1C1721ECC500ECE1214EFFDE65E479D38C635EA223286DB326EF9B19B3CB862C96C162D3DE238C2948E7613A0FA4843E39EAC51EF293AD7EEAFF0F522934C982890F83E922B2BD52815136D0A758B33641C54E7D4E0F3B19AA85859B750E7A7FB80892C3DAC5048767132E2DAC5804709B8560A4B3828B1CD25DAF263A2466AF7FE328ABC84EBBA26902FFD92B0D765AACC0C0DCBEF962E1B35B1195676E8A67ED593B23B2B0305B611F9E16633E77E3F31794C58C5309BA07DB5CF9AA1CC108186318A3F16A7141854C2FC8B469BC0F54BCB22976A3CA05FC2C8E23F1B6A891E7527F204ECCA0A5400B68565906E795FE4DAF52ADA95A9883676F9110B14CEEA389CE9BFFBB5D040E60D3D03C4E6D6CBE9ED53EA44B1AB6ED7EDBACD0AE0613DBA5A5C673A534D48B539DC85F48175F13404016C5289348504141338FE958AC28331853AE80ADFEB49A6637936BF82FB26B95295B2E46F4F9534720A4E86FF18B31335877C9CBA96A9B450C1C8C9C9862E51CFEDBE3DE5C8B901D792A179AF9A782C330035A14CE6A710D398BD28416CD72373FE216744F6237B38B97351A77D5D0DEA1A26A0A9A24FE15503240933E1CB5AF458E6FCA8624669A0DF439CD7FC13F7A1F10A0CC7DB8C6AFAD9C99B5FC45A7C565B5DCB74FF0EF426FE7C260D3ACB1E9E83DD8E6E11A642145BFBB7566D582D0540D7931AA28B7F8F682E6E2D90B6E6812FF8B7F15FCD3DEE686DF06E8E6C456C99C6B4215C4E874BCEEE3B4F94BA825C6A45C2A2B4C6DC04F8FF5939C74E7DA37E02D8230340C6E2AB7CB82BD226DDC1A7C7BD0C0FB36F71F9C772233132B8871A0D76728C2A141741C2662438C5CC7B129A6C8FC587A0E475545D176818B51190F0F19E91E05C04477283A0A7D4D646EEDA3BE64459780BAC1862D83E6B99C5731DF91F0CAB454E70A0D94D934D0CD83C8B8301DE282F9A1FFE49E73EDCB520C016FDB4AD02C261DC1A1E73E38809E60F91A4E38C69EC70D2A621DF0D21588F24CCD59D331C69E16F0F6BCAA8F24031DD5718875BD9EDA5B420C116E4316137D4B77623C9D73D182900BD7A0F90A193CD16107E692D469AF09F74702492E22C796B6B4A960D47FDC571B4A264EE3528A0F5A9D66DDAA33FF20C3101D50299EDA3225834C9429976EC8E590C6D48A721A14972BE70955EC1A0348D2F84347C1E8E21EB0C1FE67223B42A6BCCAC43648F3BB5464121180F8E3E682B4B664D91584AF55FD1C7D2E6F79A93C680238D29CB7FF36D259CB703DE03B2EEF6DE0CB77AAA8F49C61EE482A8DAD30824E603411D5F09482DC84BE794BB6EB65A7BC1DA92C8BC8364AA88D4B8212561745BCF3CBA0D6AC8B8AF80373DE3F44EE39CA3CE4C5763F422CD4E8827B1E7BDFF79DB990A52530E4A1E21F6CCDF50A322A086AFDF24EB5FE4D99F1D1BB4D6DA965D168E9726FF7A4C82F327A748DDB1DA5A3D0E9C8E0B060872B009CC9F913D35D94FAA912B0D6FBF233DEA3AE3C2A4E35BBCACE21CA3E5F7A7B9A486AE9D7A7D2E0B79FDB11D87072F1B307402BDB22746B86A1A0E6B41433D5BAEB2048ECA53A1ECF895E9EB9BC5D6AB5D5DF72353566BB90578F12C6A16A163E95CD35DA27C79379756141DD05C315B466871E2B726B8821FB6FB439B49430CB3CA47CD211D03DF40AE4A0BE87B6000BC9C75AD23552E2129F47AB64BC9E5E1620C99405CEDF7BC059547D547E2868A6D470D813AA5095D0AA4BB18D91964988391EE6F05DD47CA1DA0423CA238C5E50D43CFB0527973506B9F1DA4A8055C47D1FA1E0DC783CE3CF75FFAADF574EC2849631E2551368291AFB5F2C40A4F1A184E37A19E511F482B7920F6D51B13065E6327F3C21DAA7F73986F2D1FBF375DFE2505C0FBD35F403D253BDFD0BA1B00CCC5A20B683D4F1E1F2374FD914C7D674901A0F01BDFDC007E8021013BB9A2F885F0699D16805F9F2511A0C7D3CDC06E36679983A2A0F12662C88BB7DC643FBFFB58CB51AAB3CED28553910D063ED8FA37FD756B79AE4151521450E552E4F2B62EB6F6BCC8086BBBD30331F3F2534AB3ADEEACCF2A6E66F205935A167FA1D5C747936050E276E8E4CCAFD9E0A056E4AC2AC08738BC3A598F07E933B0ED285BACE3D24AE6FF7574351758F983FD7EEB3944473EDB4EC9A9828A5FC656BBF04DC623C75F8B8038F3699BD5F255CCD3EEDE4FEFA12AFE8F64436DDB1FF2DF100B09BEC657DC5D2B18E5722D5AB30D075D9A52A576B6F9FC8C8BA3ACA6A92E6596F688FF5D2A7E3183B696AB277B0B17F004843E58760683F90BE0C61DD0D1BF9099A865CAFD1BD1D8AB1B7D4AF2F86D51C18D7868BEFF3F6C53EC68FC46EC9F23D1AE1FE85CD97D8CECFD57A562E7E574ED1D0A7005813EB980C2A46A98CEC602C0E022E87D4A6EDBFD7DE9FDA8C02EF85701BB1CEF6013F4869D32CBA56B0AD6EB007591D03C76A839F9D01985C546C39E49D59395B10346820324F3E298C5CD977FC2FF83BD422CA550DDF2A69607BB8125647B389246ADF0095F22692BF907EC86BF8D70D7E8F2C50E35DC6EF34FD1258E1FEBA0B254470D43C77CB0073AEB2D4CE5F6772D49A101052D8CE943E1C7760F2994071644D27D26BACA88EA07F29B2F2050BAC5E05F2226F1F584D17DB80E4056B7F9C60A5D9DA0CC577C6BC802FAB26E570BF017DCC7236A1173E273397E373640ED02B4F9863C40D2A2A7828C3875D8081AEBEF349143BAAECF9089EE736EFF0EF80078D2CA7942FB24A92071D229A1FDD0F6A87D362E5165D57F62D927757BC31964B5DA63B90EB3591552F2B9902E2269A163FF221863ADEADC9BC92CAC0087ABDA02004C0B9F34E5CA8599DC3C4261489F7527FD27AD2B6501E602FDE47DEEBF3F3EFC0166B1EED95116CF43C8AFC0EF89BDAA9ACFB6DAC613770DEA78960C99C9628C0D21FAF63A0FF7A3F2733EDC0FC07B83F107A811BB3C1DFC6CFBFEC105193272A4BF915B1DAEB232E16216E40FD3F9D9399B15CC4C073BAE8D08A4EC42D91609574EB009A9B52F06D3F428F6EA9B0511D8319A1B1299C154C94B103CB586370A58F18F04F5D21AD3B638660D6C04E99D356A7289E37EFAD643A5EBB488D54F4A0194FBC4283A8C4ABB8D9A1D70150AA50F991204C038AF54B5B74F722CD6515045D62276A9E936476F42B282C3B08D9328089AEA259510240B95BD5E81FB9D7E006DCE0DA832BD9A833799E05CAAFA6305D16DBA4461BE13D3CAA95773B98F09230F2DBE13936495C2DF5BE3A8F3EEB4FD211810F4B07D3E2BE1A11CC87079DF1B32D44B6FE7942DF2627AC19FD9F584E771D7ED98AA4C074A9DA5B7C156F83D90EBBDAE78D636D51EB0CB30C7C7CBC1A96273C0AE0ACAD8E15D1196BCB2EEBDA332896BABAEF76B4275F863732D646C24627AB014AB602A47594D6031795B17144E6E2C23F0341422886C1E2512222ECD530017DA02FC015EBD5BDFB319F3AE942D75A55C21BF347A44B300ACCED7A339007A2527EF4499E3BA5DE334BE58D59918DD0CB55B2F478837F71E9CEFCBBC90808E0BEF8CC7712A3B008B69476C61535FF0787B7833B70C69B1EF506EC4F445B72AA12FAC2589815874E9123BA13A17477D61E41163CB21ADB8151658C99F1422C71A8183B8D0B1D489EF436564C47ED8482A0DE9170CD1BC34D88CE76E1B47B84E770020125F718B4AFB1E4587668634FC7464114762A9D74A93E33A5C0CDFA824CACBEB097B5CAC3B554BC0D41C402812D8E43DB37C730A6219AB6F0BACD096BBF261C78E991DE0A2278DCA7D1BE0E5F2FED72CA38BAA86924A84275BFED3B91FC8DCC5024316EA0587C96E030544F631076DEF65F05F98C7641A958313686B8580CFC20221ED50DE4D2CF32461FAACD0174AC46A6949EF8ADEE6FFA3F537228AEDCFFDB2250D7BDBC848AFDFEA67AE53CE9ACA45F349557E81F70F9DB92926FD0CED8C104E6B7AD180C7B3BEB86171EE84A8DD2C243F6869E04C2DAFDF0C938C0768415C56330C9BB6EE756BB335BAAF96EEAA5CB52E554E39E2435B0731B0062376F4730108DD2F05824A798DA24C239724D19F12C6F2FBDB52652352021E0167F31E0F5941C4687DCD13A81A20A0AF05A55D2533280941865DB4D5715AEC293A64AA2E5151C8F44A14B72C0879499027E67E4E2B487612216F6122361E8D34E92C2163B0C88583E3887DA93A3AA0E77FFAE3FE8FD5455BC86AE6D6D5AC7CB7BDF156A960C98B0BE50E1370A43E7D183636DEB2C64B264FC5922D4BD46A8206F911E7A742E72E4EBDBA39B6151AEDF5A6CB4157B375D9A59899808F1838C61EB4388B923423D3879E8228AFE0CEE9561135849A89363F84B41BCB166EBCD0E65A2A74FE710F2B3B55CA9DE2FA9DC163BFFF4BE91F10493936FCA15F5F39422C75233DB22299456D1EA3BAC26F6671557B2A5FB0E9460997DCA797C67C49DF109CFD597BE34C8E0FA0353F28B815D0CEB31DA93E49EF29CEAF20FEB0A8F5924DCC62E830353463245899900304A8C8DB5830BC0E97AB83853D8EB05660D6A9303833D170E138FF6F1C30D9DD64574D5F875F974225DA81ADE3D97924A38F552276F46A5208403AEF82D1E92959675EA6B353E5C6091034A295D9C12C288241055A2334C30DF0A37D2590626A7D1787A4F591A6E494BF55ABC76842BBBD508FE54C5630D11C54386A487A756ECBFC0AE8957E7CA8678D5B9B044117365AEBE79AFF2E6678001D23624", + "signature": "58BC36248443BED9F1FA12DD93EF6FE7D89828D96315A0FBEF047B5D57BE38BF2BBAE0DF7E983151E879479E00046AB12BA8354A6F51F9C286B83560DF391BB7B1B2A495FF27E582D3D09412950CE565F2A800D18454C0C17181153091B57657ADD3EF44C97FDD8DE557FA590474BF804E569EB7FBC36357710A307F3D540F3457FF382730910BC41C20402449A0CBC5A93B5FF47DDA2D39E59DD58A862079FD60B24E8FD43BF8750AF3A463FF810E43CC4E84D9B54B716C8EDC3B00BFC0A8FA7210E30DC6FA7B8668078782643404736A7FCE53A870491E3CF91C38A9E761426FFE7ACA6D1DE13BA213273E899DDEBD4E0BAB8CA084525DBEAC382D0155421B800A1AA921BC4EA1990E19CE090696E081AF1D4145B5C6DAC1277FBC483500B80F1CFCF40F49F48D2D86531E98EB3D14D1F54E435E976F0C123B14A4D8111927C2B425A43316FB10F9DE9BAEC23D49F7CF37D2369ED11FC3801E84C981472DED8DA4D1AACE2F6F4050EB94A483F79F2551CE179B31D753072D02642873DFBE5C7E61C9FD32701C10847C6AC35F41A2DBD695DACE401814743B88C579BA7B188CC878150C71CB5C8AC5763A805801FDFE267D812F65FF31D958B857C41B06A738646E93AD2D9D0AD0E1678697C494FBB76CBD41FA63719A3331A96A4840F0DC65F890F7F81BE3D22CE8500CDA8E3AE5A6482DDFD749F363882353D2EE9BE0784BDA8BB2AE75A011869108FC9736E6E6B08D9F6F42DD42F4C06A561C5E8B585ECAFAC49BE7B17299BBFB4B74398D8A300C6447108FAEF5DB463454010217F01AE45F0282D4A3B9EAF23FE092EB750EC081D6EC0329A9A537A5C270C31B1499983A7C293EF72F0A4FD91CDBEA3F029DFB35FEA766C475A07BB4EB7297A9592A20E3FB15119F5A7A9E658D18C4EEB3E35963C122A1397456DCAC9DE8EC08DF9873C751A10E189B9C8DB3F63721910E930397C4CDE3D475AA7E5C56FA2B139690C20418DC40F9AC14BC29B419A45ADAD66AE2790EE4CF0233EFEF06E75CDCAD7A594BD9D64F0A030EAB8FD2C77B3AFC4E4737FB5682FEA678FFD75A794DA8E2A0348088A48D1321C9828E0CBE6F15A746DF22248B360F51B501A9BEDA1F7263D5BEE948C72C9ED854EEB7DB56E5885F6892BDBE019B8FFA9CA30DB9D1C82D3E13AFF7D75B0D0A713FCD4934B559A80F4F32062BC4883CBFE4B4F905B8B8E639A203D69AB8CF33B61A3092B38F03683EC64605DB4585C1E30021294BCC7C98D8DFD80940E82E65DDE8621A38638D6EFFA26E19CC215FDD0A305E6BD731ABA1CD14BD397ECD52BBE7CE7D84F88323A4C2D709D28333BF97DF22D24BF792EDE7B5F5DD1FCBEB169B625E36D2DFA95539188CE7B7BAD539C2BE1BA1971648478468AA3413DD6076A213EDDD1AB0FA85076B6D91DBFC858F1F935EF31DA87A24E3171B30AF8F03E8DF50A1781FAB6E3775E5D14B3025492B4E0309228AD41B68B278ADAD656EF83B0F8B1ED030835255A4A07C94A35D27B256AEC0381C35E640C1565A80D55D8905C7DD3BB69801DD362AFA95EE532714BAA8FF701E8F8F30A6165DFDF4FF260C6DE1135E66DAAA7EA771FDB07E07F818E4B2F7334850789F8FD0E385B23641F0D8A7C754A60B35A76389F5920A4DBC0E890A7207827F2B6368CA95241DB5C6664397D5A294FE3CADE660D80F69F0458171684A997B68E6CAD05417DC192638F9275DC093FBD4A72925DF8FBFC7B6777CD28F13658B4D3745DBBC82C88E42A16C31766A9ACBD13DE946054131FBCFF70677F2FE91078D9593F12423A3ACCCA5761830297971F6AD925455B9313683F01541B53543808D1E8C6ACBFB93D3B4C715880545B77AD0E7F1CFD6A3426815BCCE1F3E7EC720BA259046B06803110F12508B33D7C04C567BCB2069DAD995C590A2560C766185D7F2A186AD1B336A1A5BE702F6691F90978F1EB6F3403E00A2464F19AC7C76D2490CCAE4C0D117DB7543BDC73E6DCCC6AEE86D74984FBE575C10E6AAAC0028D61BBDD001BBA9186065A7BD1E7A8C13CDABB33F6F2FD03BE5E950793212CEAF82829142E7BC7E97CCC4F774892456870B23A1D6CBC5E1D2B797219AA1D4AEB332F2B38DC3B230E0EEDD600935523D9C05D7C750B485F32DF4BDD932676E6FA4A7AF63E12AA149AFA49ACE37B03DBEDFD502B97B36238DCB412E5D9C6AD0E8209119DD9BC5C22ACFB7FF53827CD2CBF259DA76D48CDC11C452FFE69D73354BA70D9CF566872011AB6D06D027C9B1DD93B97963F964B33F8F4FE51EE4E1F4436E5B3AA240320BF3CC6FE63B219553F6923A134D843C9B49F913525B4FDBB87F5F3235461E8DEBE849449BBDED39DE58BABF6BC66DCEA2115AED2582504E5FE394B9C2C346C5251E9F058C6447526CB3786A8A66E86747129EEBEA89F6F27AADACC5A97D6D9EDAF5533218C46BE6C8A108F8723F78576133FEEF95920D3B92CFA38B2547CC48B97087EC163FF9C244343F51683E8B1B7D29968A81423EB1346DDF5C4E638D796C8FFFFF6C482E47227327FB87885F52EA0840B06252E5DE252577838D869B074E6D0FEF4811866467B82121967283C2E47FF209D9E3860FC43681E0AFF54E6418443D5B3F769ADE3EF026F7E96762E1018326A0CBBAEF233996322E495DCC06693729D7C744ED8B7780161EE1277AD7C9C4B40481869AC463653E1E7F7F60AA5C352BF1F1A9CE483446F13DC6A26239A6D784B9F44DE97299ADB3CDCE3896081A7C93445C45D9ADDA1ED9FDC49E63202FA99D02B240C46DB1DABFD69AA70822333264064184BD583FC949B5134902767D003E6ED1D05581C1D6AA5AFD9A119B15F745E835CFC832011829AD48530C7C51AD17785B06748230985E77E2A2C4AC40313EF394052AF472A74044B8542261BE57136759FFCB1F42F349A464066BB4FF963D9517D4D82181B1851654B73203B16E302E7F7875067D2198E33F819270183ABC0AACAD3ADF227AA20314979F296AAE763E9934F15A6544FC5CAEBE33B6D51897ED5DD4094B377C51C931E9E62E5C05F340507C82C4E2788DC84E6B719F0C1A729AAECB019946C9DA7920DD20A7E7DF89EBA8BDC8E8EC1B03FE6ACC18E855C02408FE1EBEDB17066DBCFFDD0B1948FA53A45AB7A892C071EE692454D94453E2D5E8DC33E7B6C304154D3843C6FFACDCE3358F8D845546E2DE5C1E9641646702E6CB83AE5CBB07B35E9CD28DEE1C6CC88D8A614F262681FE0AC38B86AA792CFD0509A76928FE196ECA25D9A8A231A1DC659CB37C2D7EB3B7702443D879D6725FC633D503841F43B4EA7AE7155074B4DE876E2918339CC2BECA755F757183748F1E9FAB045C3F22DD5DC2EB5752A4EAF055F64F9BA6B3AA65EABEA3F585B72D712E40FD2B9BBF5F62ED5E9343D613A59A81B8D4172ED8837137DD07FB77C3D1B2095B9686F9ECB15E37C6C1B19267A5C0D299A1DDF368559F615733F451532554D0250D52E4C56242FDDCF6DF7F4C5E0F372B04AD24248687BF21243FFE82ADBF602204E9281C2BB4F47D5E3233A6CB0FAC7854BF4B298EAADD9242C085856126A1806D7B063C38D2D6F13CC617D22626BCDA228ACA22B798C0BBAD8D3BE108DBCF6ACAA304EC51C78BF2D06CFEFCF9B279B7677F78AE5055F77E0C8BDB8DEC635290D154F59E13DD6E45CB81BAA882A54B26D2447C8DCE935FD0A9E5EE20136C3FC643ADCD342EB901DD8A0C9A652DE28E552A73182616FD7AD0F662A465EC1D947A0442F5583811B7A921FE210DB41614A01B880C0F811BD74325967CB5361235E92C6941B4E5EFEBD38DB1F22A084C2AB64308BA1E47AA7223962DD65E7152C840AEF3B0607827B6E99F6037FFF6749A9B871ACD998F719A222F8ECFF7B060F586CA9CDD6D9ACF769DB558352F7ACA2A2CD8BCBD91915835D96F0B1770A88097C234D5D46AB064D9AC7B3A387280C9C8A16FC561A7585F6FAC747FA4091BDEB5AF963E9AC134B948FBFB32805C80FC5DA7798061D0B26CC8675E2FAD9AE52DB944FDCBCA68870B29E270D9D51A113B064FC6273CD3F86AB72CF31B20F0B72E1B964A2B2E42CB71129481AE61536DCD409B431E2859BCFA5734A47A05F149FF91181F081846D376730E4D492250DF165A2B542B39781977E96802A4AC38F450AB89EB87BC19E5F8C323F29F13394228C985DFE60A185728ED95DD62D764EDEB4F46C6D5F24EC9B105075ABECFD0A27A24D52DD0826B18F89BBFB55C27A42496F5408D283376C20807922609616B07425B4E180CC6E33BAE22186AC37E3775A6786BB6E930B928CD682632D687A2915094F520D76CD439DD125B3DE7295C5C3D1D1367C49954CD0B2B944F5CAC8CF765F39BA61B89B007CDB7D46ED1AF4ABB6E219C67534DF7AD50C422A0A34B2204633E4763A386E7235DA77CF46CD2388062028FF8832FFC74A4612886B0AE4554BFE6D82E604978101B413B5AB9478FF79B39F49ECC91FBB639DAC7A72B97B7693DC8647FB472AAB87CC9B28C0CC91AD51C557ADDB3B6D864903B98793C0E80AFE5F02A2FAD2CEDB1486BE609832DFD285D92E67D46FE19AE445F4FFD7C166EDDEA185666FCF0B4B9F75D169B440056DEF1E376B0F6166FBE07BFFB1925B69A2E85C25C7737F9FB48B87E7F66D2E1432E12BBC585E3D4E6C5ABD5E65326A67D1C944C67DCFBCBB0A017666187E71D2B1CAEDE13DB5A4576F2F0606E892B7C57296B95B009CB92137729786672E11E66CDAF1081E167B0AA0BE018711C8CF7D285359B6961CD04F79F95559801D1DFFD3AD1E712AACB0C121BAD5604C9A5B95782BFDE6F1A2DFC110579197D1C6E6686AF1CF312B95621C6B72B4A57CF8B1FC47B773EAC6392B6CE10F6ED1D9A0C2827A0B12D058FE72F99EEEE750CD4D41BD4A3D95B1B7880535F78E4942A7D83D3E2FB8C1892DAA7971E4A0092CEFC9786D69D689AD31D7AAEAD2CEFEA23E0CE14305BC745A472AE0782DD31F8F5484EB129696950B2CD00A8F401C19441FCD6A16BB2AC5A9AB36DE2B75EDFB5BFFEC0AFB37886F415D79DAFA24350BD01FE8B0824FBE6FDBF6B34DF81F0A75B5F5F87D94011014AE543B1B7F5C1F7BA542BC3F4B134E1D9EA6345339F4606D132998969FDE118BB0F305F2753D1D63EA33465199C5D04D2ED4889C19E180B68D2C5CAE8511F9C69A6539B1BC24EE28DA9C9C87D7C46887D01740262F7F2E76447C5CED2C8E23A43CF9B5A9EF603C14BF4FBF4578A1A316029B0C036D085EA7AC855516CFBC6F658923D54AD182AA66F6FC62812C49E0A209F5FCD343B1BEED407C74BD4499024DC312918B45FDDB307A8DCACE261D070F84CD26458B62D7F3E9BDCDF3946384AC7AA1C32A34A218EF6C9FF835FAE4508485D2A3F4E9C94425A5B3FF0422EC098A34CFF4583C722389ECCDED9ACC397D53985F362DBD0DD401CF830E206BC956439BAA66981F2EF63C30F9426A389CF72F144DB8FC4F7A245A7DE66F1594629FCBDD6CBF44CCAA2C4E3D45C0137F99CC69E08FF6BA2E835DEA3D9DAE61DB48E684BBAC10562B6587193DEB0E6980EAC9877A5F954E1AF915D02C8C394483DF6C8AC9840DEF57D7885E0A38E14E9D3B85EAFC94BBEC68BDF2CFE33C08CB3CB7A8530E8759D27EFE663724FAD3F23F6CB10655C0AED09BFFA78FB3C671770A2A9B928C4DA2B0852836730C1874F7A027C861A805DDCE2CA765D091ECDB3CDA874165B5B0B87A6D6B64A73A47DAC6B255AE65BBF445E1633440FFC2882D487CD30D5BE629A4DC58DF086A4C62116A64AD799E34BBC46CDE85EB71E7A7B279B6E50A13EFFB00EE7E86FB19541596D7CE82F028A26DD5C9D0D807F686492E0DD3FCEA572A1D1E544EF62C282A904803CC2C7B2CC0FF7804FA14060A1B7D8E06A61F5DC2FA43179286B4DA6EEB8065C3D6397E6CE850562DA4E614A44BF81C3442D00AC3AEBF682D5B1A9625BA462556CBDBE75CE951C3FA91F83105887C24AE3EB3ECCD05B4BF4D6C910A718C6BAAF44BE750CD008C2591638CCBA780807D02BC462B9A16967D2A5A927FD75AE048591B5CB40B3DF6F092469BB30B2939CE425A190847B904B631E08323B88E11958BC5C6FE6F97DEC18B7EB94D14089F9EFDECA3D20958780998A7DE03881BD99B7315465BE6CEDABA61F0D3935694D1FB6610E00BAD93E96ABFFBE51F653FAFD2353F3ECA0A65FE4CF7D5583A19D99CCA53C11A5E8E5450A2383C7222880062C1315D81C705F85ACCFED53B9E46DD9CC544F588BB7C7594E4EA2B7720984C23347BAEE26C015C065F732ADB6B71C772FF539D9AB8458917BFCD3D8B8F6F9A495A942DD429A91DB1BBBAA2CBFF201086B14B8104D6CD77655510EC4EB8C995B95B1939BD0602A893F631499C81B0DCF7D02293A839483BB697E7AB5B364B8A386D481648557206AF32F4C96DD05232B37536793BBCAD81B515E6E7D92B8C0173A5D8186DB189BAEE053B0DD4B4F678FDAEEFF14295C719EEAF1FE00000000000000000000000000000000000000000000000000040E161C20232A32" + }, + { + "tcId": 43, + "deferred": false, + "sk": "5B62D37A8591CFB588DA48B3B1AA1570C3491210EFCB877AE913F5C98D06C5853C78D526C61C387FC6E15BC8E612762899056F844B324E4829E5DCE6E2144804682D4F5D3CEBEFA61305B64386107BAC5022DE119038F94F656ABE41A61717532E374C1196780C888EF1F7455BF502420F61FE9EC389C1BB6B75397622374EE00AC0856130828C806CE14840D9322440B02923822D53126A0221108B988822A191D43231D82831E2C80CD4A8705B086D83B001A0A64183180681027040220D223269DB940802958C8AB6500C056E2222311C91491B9451833064D4280A112750232610CC088054222ECB344511B90063128119C04CCC942914C36114C1049B1290A414460893242316665B184262B211E330868A280CD9920504009162A4605A926C1B28100C002E1C4491C3A869C246860200050B1888588664520625A0102158409090022288A468484685C3844CD428919BA0300381300C372191B2001C086C13142ECB30710B3021840864E44465A4B061E2144184808118B70DA4161201398C0436810C2970DAA029D840600282411290898C106A19140A6394711C256D18C08DC488249A881123418DA33491CBC801D010680B865090104161B0511A15501C0104C01605D2B825E02226D1A0708B98248BA22040426A529220941080D34006D3C86458B4651C1440DB168DD1A66DA0B67108325109128A92C869833400CC842004064ED9340502132D1992800424309B260E2319105AC669481061994028C3A29163024C52462A5030221496846280250A300862B26523282922292410436C10B11001120D993884A34661830430D0100A00318589444C5C28802330884C22445148248A083223C02C442682E3C86C5A0088622224C2444C0A854554B26D18452214214898464A1886610B26205330310A9840443669C3208424380D94C62911C445528249DCA431DB4211C3824CDAB885D800655C462E238288221980D93468118441E42609601488204486623445CB02411A266DC392514C142D1AA8515CB60DCAA22819286522368D4A0630DC44491B036641C231E0064CC08430918460142670E0000CDC10624036852348819334308230458A38300095319B082D608268911868C2C2109C048D9C084120B16C82804C14C61120C071D1B850930245A48420D8142A4C302663B29103932521466023094A0A076C14012190180E901012C2B62458C809D0A004429885834010820629D0102462C624D844021C054CC43841D4082D0A498C2425600047621B90001AB78C63A228A1A229121126828820D224028344285448640A3104CC166411A52520B0205BB61052422509C62912474CCA226289261222812D4A28428888210CA9210A0965CB948518929002C56D59C04DE0C04C54360063426D62206420C8815C484511037209100C14122964008508A225C8068E80062A84C89198A411DB302613851023C6681BB54D49066041268501B970E3B005C424458C8425DBC469A2A45011914DD1064261080212C9010AB1240035658C164A10358621A38050284021196543000C03174800394108B448049571912481A4982D1CA669511090928845194642094226D4B42842800021028423294A51284DDAC690D0262401B26161C0250C8265199290A136680B0689C9B84D02948002227053386A0C08885B962899988419060490964DD8C86119370C21986D8848515CA6294C042A2208441AA93111C2905218220C454EDA1404C42488C8280C20433259C668803891DA8000249301C094089A008C53321220C468CB928D623881E30426011505C2145181488D008244A4468011C38499A090E0A425133510D14088E394000A271108C44822362D8C004D4A86512430242405818C4624C9348598882CE0B841091612204968A1C830A096108348106332068022610CC491803062082301D88045DBC82510C18C6486601909910BB3480A244A8A9870813031532881C494111A88605B828C0315022017901383641046890103668BA451223840C002458A8011A032101C35514A481091488021990CD8949148B29112282A224440C3127281920C12B889524024C3B0655C8209D104712143710A326112389213042C9B00820431000CB344DC1010E2B82859982C032602CAB00CCB843113C6200331280AC061D2848C1A4110911430D3388CDC005262C0858AC660B6B814546CB4270B543A708AC86BC1CE481601287A65C59BE8D90379B0CAA51F6D98723C5BA4787DFF8F095CE307869084EB4783EDE6ECCF369F923E9F435FBC1E5AD11B5E20159EB53B41A0596BE86945FA60133274AF288DEC348188C166BEF153321723169E4BBB7CC6CC2DBD6158374E10891EB82EC47383F1BF3A103B912FC2A929461137DC00FFBFB8D5A8884B1702D329CE3EB967FC0B1847DBBD06C3CEF44CF4EDFDD34E9671A3B51572A7510174D26968B869F044919AC6CF766250953DC9F4F3D0B28FB6D7D0F973BD3944B6ADA312044A09EC59E008EE8F92329776708916B1301D2CA52F9F571EE458AB13D13EDB882305351E3A1B41FF9BDB54D1BD5B768B7AE758EC8CAC4668582073FEA7BAE86D6ADDA4A4F582E7C4C298178DB1A5038D9D337B1AC18BE442865444D24B0D2443D6200A6C938963A812F1600D3689D8EAE1D668A7A0C2A3745CFF5484D0E1AD2B25A9A70CA3FB16D423DB83318BDA289478A5C44C5F81253AF25A7EDC4B35BD73CBDF3C621B0DF2ACB9B1D9C5A87CFF528D0C04F77A31818BB36492F3445E250712BCD2A0C2D3CC3B1BEF6AE9D1F4653EEC35E2C34F14CD872172FA46ECAA5824507EDBC63A5D5E8222308044C6A0647924F9D1B8AD7584EF56467A4531004AB4AE1D48203E032A1B83CB53C8BABC556AA6163E7DB321E71E55DE72EA992BF47E0F70C2180325559C33F6A0F9677BB801D99525CCCD1738C19DE9AA91A85146761FE773255D8B6BD41DB2515C23444463616F14459536703096F595E841B93AE455B9F37AD2E1A5710C83042689944C5C4A39F944E98C07D898C59F4BBB9DC8A4AC6F3789286D8B61382994EEE1C7581B3F2D12309FAC0A1F5B5F02D0C4978231D52D57D3D56D8F12075F4145270A3DCAA543A008F8A39D95FB555E1EE9D2C9F1FF557FB6C38BF4050B6F59C51C02203046ABFFD51745EDEE1B5BBFCF7A9BE1017839CC6A4638F4316DC6CD63009360ABB2B6B02818C542124B280E18A74BAEB9273B3F2DB8111CDA487DB87A18DFD16D380B037DDC8E60B5F1874D37F704E1A8743D51259D9A778DE571EB1962ED8A07B641B21C274BA9D1385B6406CC3D8ED00B697FEA1BD10967FE481EDD332EA30619655E0A454D58E59672293694DED52C791ED09E2BB3126EF1FF977931C0116B67C91E038FC70C382B28DFD692B1ED75A3B3753D5859A46AB0159C7F9FCB7E6CE9CB91C13A0A3D243D53956E444E7EA734724D45EDA455ECC7C3C74B2A2C4214C7D2B6B66B1BE97C7D6057EE64794EE0130001CFB597BC8B5C0C3E4D159E76F6409CD2C8D6ADA7F8BE816992B191B80FBE9835BD3EDD60CE62A79141DDEE46673B189A0F1CD0B103A66A6B42A3D9319B92761BC8A54F416AA8942E780BE5B70262426B11E3AE9EF12B3FB3BB884E3E230471C020DE7FCB92091396817AB83B9A7C40D53F580AED146CAD8C64BE7E0B5F84F0CB35A2731B710A10D784874B5CA4FAA3FFF38536890F3E48C5B6BA96BDFD22A8C02FBB2668D16AB52BF742D79ACAA94893C81C108622AF5B4B0D1DDAA009A2B1205B02D1B8F754134AC4A92E0669278A0FA2119C62F9F75763FD76CD4712D04B00042C00BD8E4DF2176918F97D83C03DAEA19FA30FDD16E1F9FE534B444C7C4A3E01C2779135D773AF35ECE0A3CA8CD3F3530760059580980DCA09DEEE0740F5D83D69DAF36A5A92D9F4096CBEECAED0816CE1326EC1804C54584E8C28355E5D00795838907B20CDCFCA4FE18C0D3D6E0DE96EC0A6C502057AF96C61A265DDD8D874E4D42289FD04F9DCDA6C270E7C53C3A2B23B20AB13AA8E3FB8B0DC77C0CD0F00B6C2FB8A36D935356E10D51A20E53739A5BDE93F96B49ADC09AEEC0B35EBFEC815880A56DF5B1D110839A9BF7946576E33C226964F6075987489DF3A7C0B574E21A219B670E074713ADCE8E401969B6D1A5D2EDE0F725C0FD829AA435EB3F4B9E689061C92008547F4AE3430B259F557E1A2DA041643FE2FDBC8E03286B50EF73D6DCEF0B9C6C75AB40F1D2F8D4CCB6725AF56A37044A3933923FC2F32378855CC0FBBC0327F25C16C59285BD19627CEDA13CE715E35A689B67DBF61C3B45C48FE507B02C4C2689ED5CA3D76418E3C2FC5269E3525A7C122A0FDD0E00CF4F960D45513C049223084BC5519B028F17F94A3B7CC1C407618935F248C3FBF0678F2A7A05E8A1911059264409A8801BBB80A3AAF8E0B6D86CFB3775F7F9AE87152371C6216947E89BA04EF44E8AC304B876028DAAFB54C3FF067029F15AE768235BAB8F854009110645AA801B2904F6939014BD76E5AA510BAB9D5AC17BBD536FC32CB2B4505A47D8679AE67DA0304E4982F03E22E77068A23B32192A24569D40356FAD23B1D79E40F17F5D2B0DF23EA437EB2371CE2C7278653A884FE38AE0CE9D9C60F97CC88E3CFE5AF1AC3A1D22079BF9FC2B42435231F110DB596581B44FA7E31265BEC9FF7C86EFAE208B898F36302B66E409184EEF82DF40FD60D6A4796C071C088BCD95E8F8AE857047BF83CA41EC4A845B48E5631F85192FB998067B0B7172E575D6671917363064C08CDFF23CA8499F240738D730DED8A79CF015FD9FF34D53A0B6BD0D1DD38B32AD0B3585FB99AEEB5C11547B8AD365269FE96CC855E3E7E5508930A639D82BD105867396D6074A6C2330A35967B1914FB52AB94F44E3DE354D8349DBC86E444B5165ED20376B11DFC9FA5F51F6069FD743804BD04222E22A79B54603AB0983530E1101227F8BFFA3A24E084D452E1DBA5B5FEFFB23B9842395658C38C7970405E17E0E8451AA188BC920887B35917159F83D7B187227B26B659D168EA4A2C8FA6330D372DEAFACD8854852F313618DC847C56832CB2A3C8029C5770F7D7D63CD3109EFD2725F24016232028CB1666DC9F407040806AE63115BFE51D2BD2D74286B205557C7F58F7EFD4755C53E2BF24F3D9F97E48ED86E2B7689B385BE82849DE6CA634963F2782436ECBD35F58EA3CEAF50A452EFB16F6072FA1E9A10B3E948E5F2959C4DDDD89921D4CB0214AF3149B7FE5E2DACBD9632720CD06B4B210350435F663C4562424927197703D7ABCF4F278C4335C623C55D8021B7A5766854DA7AC210F25A326F84E0BBDA83495D44BB923FD32AF32528A68F11C7557F4DE631DCFD8C233F473ABD54C6ACF3B3E935CD6942495FA61211CC158B7C2FEC84F923D6C4F902A8A19B46A931C68F420260A477A6C3A28B3B4133634EB5751E3A7CC46022B706BFBE01A3E062284C2D4A8758ACE690514B137FA480676B09EDDDD309D6F52F94B2D0287270CFEB1A6E663B762080ED4C4769BAE6C168CBA07AD79B1A1690C5FBE0D9A05656D4E52466C906271CB7C023A72A2F015BF869446FF35E9BC1A59E23D9928CBD1285512AECD6C904CA47F63A8747FE79AC8438D6C26F13FC4549453349441D959B66DB25037127C036AB356C8CF79F99F10BE8502734CD91CA6ED2F543F2C2D5412CB6D16DF798204510CF5A17E6E33397B38BCF4BC57546AF7824C0B4DC7D107392B97730CDC0F1528648FED45BCE3443A44BDF1B28B31FC8FD17A1B4A737CD28F927559FE2564A3018DBE808D3AB4A4440527825D2013D487293AA875E5E911510CB8B56B04099F96CA23C62E72C2156EA08B6C7CF5E45C869BD2468AFA718C7E3B73C6D02C7FEAB0AE69C233F0E46E57945C4D4EFF7796285E8988B51280323A8E89CE7BD8C068B0828CC0BEB77C0F44E28C5E75A21853AB9D8159B0E2255C5DD8F5746F924E237A4A8FA3745F5CA39814EE64E7EB1C94DC7B4A2889CFE7A01690A89285DAE12AA6CEF45805714F05BF0FFF97ED82E51842B099FAFF2F0C0F2C608FB3CB6E069D276714A21D1AEF73A870159CF5C56CEB3403D96F4AD1D413D03583985068349F73524D66760A17AAAD749931870581BA8C576FF6549661A43529A2145739AFCB3BADA0EA472AEA14986670A97FEF749F520054CDF4820C191E5D94599D95A9050CB45B6E8E5FCD28816D331F21FF06EBA6C0DDC495AB8F1BC645386AD1EC65EAC1FB4C4AA5FB8A301BCF5A04A7D61A8310804475CA128824C767426E55EED148C766181E2F2573149C2AA36496563A4497DD9244F9B17791AF92489B0BE38BB5A778E679B93BE4BEDE0C06B60A048955A0F598FB16256799ACA1CFA818863EB852A7329FD13BB9177B8653E3EB32D6C40601AC61F69FC91468737480C6C8D422755D2AC35E410D7504E07DE414A7FAD9A00CE495C84452ED9EEE7817066DF613156995D4132CBE14F1607FF63BDCE71849C7E3A20B5F728EEE14DF98C950706E97F6C2E340300431EF2A6E0FDD9B2EE45139C2DC66FC4FCF8231A86B9F498FEBCCC3E87F19DA17D09FBC476C8CDF0870775891CDF0C94411FC686FBB54C9EBB8AC22BC43AB8A72528DBED5AEDFE87CC534E3127CFB22784BDB2811B39D20C29A0FE79061A0CD54787EE228013EFA979413F8BE983F7D9EEF5508DDCFBAD3F4AF8526291A1840BBBE247969C8EA5218778571891783F16D84E517B7CC7F1A50999A23085AEA463EDFA3AC16AAE8ACF4670C69437821C57349A12F561A87218BA746065666A7B76EF92EA8ADA926BEDC8F25F809F4E747F92B7F16FAE68EA88BE10542DB5ADD7042E8B26115E2A587C5BE310684AF723C6BA4BAE47725FA641BF4C0218F5315E5B2EA0D89F0EF", + "message": "CA0104B9DF99E87474389167359968A307F63AA32F0C804A96B18FFBE00C748B1D6894CBE2B7BA06EF17B6947ECE31DDC9F614348F01995FCCE77099A0D88B2BCD1035667631991C2BCAA4C86B4D31074A2FD46C38429B52CF0BFD7CD3E5D194DF22E2B0D57C0C9D624C772B54686AC963447E716C6B4DAFC00AE383CFFC69A2F6F931D616954BC9A140D785F15C5DB28ECC793D88C78D11F8F8452046ADDD3AD26988B21BF895DC810739FA7C45A8062B2931AD363B0C7EAB4CCFAC71CDD0DA3B54CA9A6388DCBF79AF799446395DC7A5B7ED1788188E9D03EB3BF7B80F8CFB9B7F33DA0D4DBE1840B9C6C5D80F6AE64487BBFEC86C596E2ED8E721A11D783F7552A4B01FA24F60B5B683E287BD75EA0DDC15314E014D402F527C5DAD74CFC49B4D824EFA77C359B90AFF15AC89C1AA35959570E2148DF7A09E27E2FC096AB5CB306B4868AB80A24DF745DCF9EDDE57357866182A9AF50796EAF97A1A1051FFE6F9038BE1F6239CADBF0BD81B23E2991941F34D0851AFCEBC4D3F8B472D6259CF61FFDB87F79928C66E69D969B254D57541A87C692160E5D58A837A1FE90A1799758A70F958DBC1BE5D6E6836845940C75E745245FBCE59D1F83462B9578534D7A05DC3F21C34EA93ED78387B32DE09ED3CD2A51EE2B8F7387C8C2D426EAF3795E99B158D467D9A039234FDF207D65D2577D1688E1B1E72B5EB096FB6377DC8EB6B3F51900380BEA561C03D546EE242EB4264C0369AA2D53B2B190E0422FBC4CF896CD549C2A08A37070331F15A9ECFFA0E91B1FC4D5157418914308EB8C6A992B197F33DDD517DF4610E88F2E35E505BA7C7CACB8E76677CA9B39A4094EB4590F6154FAAFA76C1D95D4072B5CE01F42355C47AFE569FA80142EDB49E2ADB34D3C356F4D882A52021C5216B3678AA6A5D52C51CC8BF09E7EAEDD2501A9886FAC977EA5F385F46E8718D39073D8995D392074C2525A4ABBE228F531E6B16AD5BCD5EF5CC4C3C71AA77EAC1747E2B763D0B3D66C7F35458BE43369BAA0ABED23202B733B3C7A111F9CF407A7D62EFF5BE3A5DDC3E49AF130012BC6D5D3641EBF268236473EAB09BE87BAF7707546B7AB194D2ECF5B03A56662B1D6462898DA94747CEE9DDA08A9026538D799F163E1E771EF7EADF8833C0510104FE7AD7EE75F44F8D4572E299A87FB17429718C576B29983B50FF81F8D48D41CC764809429A7CFE05F68168B6B36FF66CD75DC0021D774D07BC716A74F9450EAD2995089FEB89D1EA73A9CEB83155ADBA737B3DE33B6B617EE7F5CB6C6672AFC439990B612A6AE71540FC6D7FF535FC88DED0E6A80A484735F63209D39F12E6E129C4ED2EDD8C8B5A24472B83A058B0F1C86B7F4C53D88927C7E9EDB5C40C5D6C7F0ED8A626C5F35E1D3981936F0F1FE4E8CEE0FC7F66F0016B14F3D1EAA993A5DB9B92C03D99C0A867FEB343D9F43BBBBBD85F58B2380811CF153FE66E5B5DD07D5A87ABCADBBD472692358777BF17AAFB622D487A100062465D9BFBE0E63B9D862A02F09E371EE820D969B29B4E6F6A1120CDA9F9E3FB804B26E2E9C3DE219044D1D6E62A28CBC90C262B76914B8929465FD901777F6F5C112D196A002A0F4C4FFAFD2578B5CAEA21452968400DAD6490E313D32A708A42F64E9CF412EC0E358F6B833EB0190C5933037202C266ABAD212B570E609FB7D338AD3F850EFDEE9347EBCFEBBBCE90E7F27372E244C3F035D4ABF1008055215E573F0C4001FFCDA5E6B6C5B29B7F59132CD86481FD0E1245EE4084DCA3D44A0C9E6B6B14E1BCBF56F470F15609DE76588795D5CB62BFC9C253EEFCC155C116D70CCF9112D8E0A801A3C640C7D16634EA02DA9DB9AC57DC2F7D43F48ABE631D3438C2BD3EC97832244E81223EEE47054878BB2472F64E9ACA0D5A8B0B04F783C5052E0ED6AFADA5274C94084621E989084EF9814128226346996CEB6FA07FB957C7432878505442FAFC4D945A953336F9C92B8ABE4E4A092DA65E2BF1A7A274E1EE9D7958E35334D9B7CF8B314F0AA5C45E93111460A8F5409C0BCB842DF9C9887FE4643BF8958CDB40EB66438BA53972E359EB712BF4C553D871ED702F74C41D1217D7887C891E49043C0826FCCEB2897BFAF9F217DC9F566DE1C416DE9118491162113E2EB56CDD4C024DCA4A33359D88CB0247BDD6802455063DE9666A4C52075359316B3B557D42B7C99700F55CABCB2B802AE4209C6B937C798433AF94159A4EC0A7DE00C809F6E6675A4213A1CE8A7099FB7FE6A0C7FB383233444B64AA120BABA1C4E61C6426001184E897A3C6B0BDCF9759A72146EF848EFA65EF09076A4FF2E6DA518C5A08F2A2A12D904C893297234E53CFFA04F285F350412456C9A13E153421D65DD30B236653AC13CCE3D5CF1EBCB8AB46808414BD3725987D6E464EB4F97321595153DBF9994F7E19AFBD19E9BE929D18563789567B28B1AF05BDB5D2C5C289FCBE8EB159D0017E09DA8FE5E9D49D3A231814778370DFE703ADABFB175859A895A6ED86F9B6B52CCDBBF936622C5E5A01D50E2B6D5730EA4588680EFCCF390211F211472F9E10314482CFB45A24706BBCA8CB515B6A9AA6EE1D2509E8F9AE9D6F545BD3971A02CC26699608FE1F076A925008AB6CA8576CC5A962326A369BDA8ACED3618F02BBC55337FAB2D66050514F904083D4386B43B6EAD553DF5603201C6D684F7156FBD2D3DDE3D7EB0D569AFD42886E57B747F21D44B88AD58FA2370FE6BF2DFA4D94D8FF983A1C2B89876E75AAE3828D1306DB9A639D052EFA6A0EFA0F61737CCC45E0C516815E92E256BA49E7853F9E9D4670593BF9402E59EE80F6CDFF8244D156FAEA8220D483601794A3CB5E1D7B60DCF991A545D2C72F62E5EA05BEAA77FA86A80400A07B97D8159F0EC170913ED885B578767CCA7A5BFB8BFDB7AC99002555145D9DF5011654700D6FBF2EC2BA609C969EBECFCC0EE346FA01B6CF07E6855F3C832BF1DB6E247448438BAEC055FD41CDBE921E5F62D93F4E7964258A9CB3991E8084BFFC2E5B29BD1E32A64E32BF5E27416CBA7FA3DFC143281F3797E1927AE9D9E07FB424833A7911C23F231D676EB0FB061C179C72FF0038E48068D43A805D56C3B6A16F5A2E5E8457F1A3E0F927A8880CD261F0D0AD8F82EF0E52E1BED003661F1D4510F7BCCE680CE84A0181F046366126A53EE67C7309C6982C28966B6CA1F324D03F5E09AEB111486C44B6551B1C36E84C2A72F78AEF5CA31AA66EDFB0792C00579C0C7C1FAE501735706CCFADE03E9A0847E498A24AC1DCBC7DB8FFC946B8D914633559B63E3031C214414BCC1921D2A53726695340648CF6C2BB4FDF132C77BC39E9CEB2E4D22EB138D807D7B79F78CD9713F5BE7512FD32E73E886DE16A9B1B19026B91EE6AB92DE4DE663D9774344B283149AF4890BFA57ABD1C9DFF128F9F169E4CECEBA0FEE1C33D4E34B877EF04DC887F7109B2BA65EF5732ED4B7C6B33131EB5867811D4A8A3536102F5AEFCACAA681A6A45A3BDCB24C4FDBF49A134244044E2B424996CF6F3C514C77EDF2AEC177B8F80A1AB77F6D3D920E508C76EB71ADFE2209A132839E9BB16BD9991A545AA0587B7594E0422647DC84CD355B20983AD582324D4F19E33E9CFA5CEDC739B26F43BBAD1F165720306F48CB15B23B961E5990C2DCC39E5BF58A9BFC10829590A7AA8F60E13EE1DBA85EF5EB9B1F6DDA891ADF7357E16CEEA4ACDC00E20F8F364AE3EA838CB4A0FDCCF8B439A242F8D18B8E0B9FB8E074922E0C25922CBEC46C98A82E93F0E95884BA9853CC738AFADA3F08BFB66C17DE7977EB7CE5495B8620B537B49D1D37EA4B3477B79759EC7D9AF17EFDB2EF89945D453BCBDB349CFC623FBDB8F125EC492CCBAF30006523B543B6A17245CDC5EE7E28EA895654A5EA74781CCB0F30343C73B4BB88CE07BD37DE9220712F11748EFACCE925626FFDD8447D37BD9CF2476437C093BA4CC0AB674E4CF9543CEA67BC25B9BD56946C0D077F0849796EFB74C7F66D5B86CD9A38B8138D816F677CE08DE6A6A911BA4DD1834751548578CEE4CFAC50C11D685E52DECB77A475FF5468C38DB23853BB2118C78AC3D52079042FB7F370B3D0406E402EFA6432D3055C572C81DD999876E8306021118BA87D5D430E4AB9C24670EAA1274ABF4BFB8149D9067C427DCC026A61C5B724CAE1858ADE366FB42CEE52C36F0F99AC02E8BDF784EBF311334B83B2B277982519DFFA3AC35D97F9F30635CC17BF8E017EC4E209EAD104B52C58E8762052CA62BA7A82FD011860E4F298D889A11F6A2BB1B4157CDA42AF9CCD0B5324329A92CB9FD6EB81DB3FC58431BC5C9A6DC1B07F7D2B00B32E5A39960C5E2CD69CA2914F23365B518ED746B27733D713E8ABEAF9D1FFC6D3D9B601FB386A6911F24CC818C0353658CB826F43FEEA792055720065601F1364BB6184699F16E3EE2B359CF0642C85E9115B18E55482356E2F91121C5884578F3D2C45462E47A3D477B3D63448A8C1679E68F9B7AE509100B7B2B142FB6BA20179E599259414520B02B745E592FD10D0D40D780A95C164D651E96A7052B69BBDA979216989A57506638F891336E2EA123303F997194B7AAB4F22CB192AB59A8BDA7CC88D0F43E4DD949146006CA3F91CF28535ED42662A61F630AD6E7319A7B98FF5C7200FECA768F14BFD43BD60DBEC814E22C26F1A8191ACC869A6BCE61991E4F36148908A5B1557A507C407D73A6FE75A548CBB8CACF13E57BA6B01FF0DF900051AE7C0C346D5DADE5F1C1BBFF967236BA5BAEF19A70FEB320BD76035F3A6B11383F13E6DCB8D1533A6529C98334A3F2A9105A5CF1C940659459C405C197130EBA44F0A2881B4614B7A0BBDAD5930DE5C3389A7349265629E29C0123CC89F3F540FE5C9019662A4383A38248F22201967D908EB48D530D17D50A08B35FCAB73AE8ADFDD72A8A7551EC28C7573E2B33EA4F61EE84C3DCA33DD5861B8FB7176C4AFBC174250D51F86B1452903191E39EF099C0CBCC15B3FB5DD30A2822F68AA37D59583BDC1CCDAB1B2E0337BF397647FEA9111A5B94C6A3369E90F3B86C266F4C11C9A7D9E24802B31B5F93B8EA9AEDC6C2944965D6B54601311D251E81C77AC1BB2159263D0A92F377F111DBC8D554C3AF747FE7E82A6E6BF0E4E3743B7AA42C3B5B8D3E5D9C3B427B3290452136E61592609826F4B61D4960B7C3784D0E2508363212AEEAE624489B739D0573CE23B35D30826182DB5F4D09772582E4D6B61938041344EA434614C21B01530327C08539A84F03275D0C4A77FDF230FBE6639CC7A12C34545C5CAD34AABF8E25D64AFCA8206948737DBA643867A146F17ABF81A926294E2368A5A2F0C381E2C244B21843E3ABBA680CC3F1F0509DFAFF4C70B68C82D3D7EF8EE053DBD154376FAAB5D561A19362314B037CFE18DD03BB817444FBF08D771A13B9D745DC066C89C10ACD53597B74916BA719F9EEEBA865252FE13EDDF97978092FDD1524CDD865FD6AE9C14329EB62B322F46905804AF1CFFC13B46B6AF4ABCB107D44DD27B460101F7A38DC786239E34CA9D1A444898673BB3DD92EE88478A3C539A563CEAF5CF499AE8E07BDAC0CD5419DEFE2977105B5E0138D84A8F9BFAD82F58884377B803C8B68164A3E678648C18127A832FA994EBEDCDE4FECE85DAFF8CD6F44F4CE57694522DC30BFC492BF62796D05A9B87BF13A7D538EE5C55E6898D50ED127E8C12F87D160AEEBD3CB126BC4144A51F685079E962DB6FDDE3BA6D0C8038BD6FD8377C4BEFC2EBF1A876833516D206C2E309C61E4CEAB5F86ED83FF20C8723BFE63D8E480798292E6EC6D418D3CEB623AC6983A3F8A3AD568F73E408F15AB88C8F56F3CCF5B32C76BDCEB1FA41357C42E1215CC503A316EA0A83FB341ED6ED20B1154E5001A754F92E97570F9DA7EA8AB7F2EFEE7B79A1DDA705645ABC5B1E04CE4F922BB03435D11FC83EB580CDFF7EDEB78F2CEBBB6053410E84477864C16D4CD7CD9D16B932372FDB99DBCCE2DC3B5CDCCF7DB86AEC9BDCB8E4F27B65ACA9A3FB985CF95C5BAE253797C8474D0C25F0FFBD151E6558E524C6E96267677EB7A3E128C918CD3B09F1DDE311401152C62B4C59EA1D408ACCC4A12A34664D7C0858D7E99A0327724AE9CA55A9322D865EFB4FBFD37FC79F8D7B2BF08B1824D44777153ED6604E05DB1FC9B1ACCE05F8C53C32594A84F32D97AE49E819029204AB7713AF2AF2C281448A34C69D5F3DC76345031D2CC05B6B26303198E182901FE65710EA95793DC8495F1995F0196DC9473B7AB922786BBC61A91868BB0BE05E2034EFFB288502DDFE2595887CCD144E98ECA4D1E0C044C642396F98473BFDEEE796530467F6B5EC0D5B79674EBDF5D1416F94A8EAC7F4833947F1DE610029779CD436729E55AE3D959F99D5438E0E4407D0A870A38AB31E08F16A06345B7BA730CCF55CF1FDA1E9D04833ADE5FD74A34E2629DCB75A3482312860404F7E75D94D7FD2C8215C6A21BD5FCAE81CF4467931A984AA24B927039526B95C2F5F39AB2040A23C76B64CD2D04E95DE6DD9B8EA849F9F7919A619EFAC498E7E3F4A70432E28B1C5DEDB08D122AE503E98D34D13A4E8A69FA267C3E20671077F977F71308D3EA1AAED5DC33B3F41E0ED981050B3B915EDA07AFD71CFD3AF13A2063813039BE85EF98706399299118D2427A7912A131DB7BA731D18DC2838A116E05C4CBC660895294A73D170C060CD83C9AA0884C5F3FE52F4891C2101997D688709F356A556CE202C571E1170BC339F3E2A75A5A13810E3A2F2133438C1705895523D03F00BBE4F4FA9BCE6D7A14517BD54E281F202BAB40DF35253961DC9E94DF5C2C5C3F0E420AC67A85BEC2ED70545B94202AACE5E58180104E42C5AA6F7F59915BEA69AC10F678D40506AD2B502D77EBE4D05CF8253B4795094F04BBDFCC8033EA131BE83F3F647D22D1212C16895F52FEA576EFB344A476D2A8EC74739BA62632C4B5B08076905BC0103CC9B2193EF6C4785685F2B3F79FC39B5ED09B258E5E9BD346557F24CB542B69A3ABE367123179879A02F941F9781935D44BCABCC563BB1F31C44BB77D5E7A4FC7EC2C11D597E7288C6088497DCC97910CFD8245A4F255CFBCB8FFF95905E8224B770E910A253356916EAF1B3277D831BEA5BD6681C6C7D57D363608EE78973B7BBBC156FE5536C963030B6BC8D306F3C1EE72F14163DE0DCD0CE741EF975A9DDA77EE386B991F3096FEC95FD394E26578269F491572B36AF42CEF1D86CDC82D63DF00AA397E1960378763F5CED239BD2A6D0EB7C5BD7CDA2228B684FA57B7FAF497310D510CD386DE6406924CD592ABB1E9753EC8BCC594ED52B70C04F7C53E19B0CB607DEBA79FABD6748A52692CDA34BB7CBF95D1ABBFF8AEF8F8AC7E5D52EF58FC79B0C7662DA90A0F737CBD42E64B648B624AB497162A7B27E41850A9BB4AF0489550773EBF1EC6742CE8D53A20921149563AA74337ED4CF1EE8685F41D36F748B6DED5F894BBC50A8DEC84621B6AAE690D6EE0B392A7266A480CF985295361B14AF0A5CEFC1EB737ED3AEA5E5894FDE80CAE477FE742395CACD1174CF2B345774BDDF71853BA1854EDC8F5CB03D33C5F58EC386ECBAC8E4209F8881473A4FFE306ED3194F455D4441D132B7685425435E58AF1F2964B657C71EB6E28FE3568183F7A0E570821EA49DECFBA3128002E77208749DCBD3F5E15453AB6DE9EB313D7445377B3BA74BD2F67AE31F560ABB628CA0DDB120CAC6CB62EC9CCC65051F70FC41BDCDF29F885FC9A558929F58CDE1200072F96C3D8F22032A0AB3F705884F0D827823FBDB62FFAA39EEBFECD9F57DA083D1ED541CF36465A999558F2299A865456C94D67E74F1EDC7166F91F4CBAC8F89E680BDED946A174E9260DD50C6B0A980A4B886850797149FCAF8871AB3080A76B645E333290A0DF319DE058981B8CFAD7A54FCD62345DFD9C3E6F7A26D212C97FA6F09866E23D5A19EB9CAE760E876B2AAF43BDF9004D5CFDC41570EABACACD4B57662087B6A91B6249CDAF905BC2B1AF5934F1A05D20E6C6784F0FFDA0A3E79A2C0939BF36C55EA0E31B1AE614D44CD413118EA165FA549026574D1549FF7D63B4C464A896C5C0E8D5569AB2B10D1DC56458FD1E069B5F91B1D084F7AE34F67ECDCBF33299B12C102F953CC48B0661AB4EFB493F7E4B2EA8F6FE59C3D5EF7D121B26B912B86BC0AE987B6A3543558F0B935AE62B4711A586DDAC9E5960C48B99CB80191B11F4053527905123D20C549457BA87608948933442CB06BEA0E73FE99E3C4198E9E7C51BBB7074DA46E752E46B3E419FAE2AD60D180303D710C0A59C6B980B24F0BFD39959368B5F56AB3845A2167F4683AA82A9613257BC801F5146CFCA857F2DF4FBEA85C54930D4373F70C083F661077567F1173819EBAA585EA3675F97951CF8C9997887BBEA9B99E17A1E0215DFC2B9A66760A277F68E747141AFE5CAB6B25D73D562B91BADDCC7938F2EA75F1C990E88311549F38FCE2C52933498B22E2810227D1EAFED4BEABCB153324622E107A6D96214F3C6D5DB91855005056A8D1BC5D5518867C373709D24DC1FCE21537C58999E26CDF4FE61ABE5E1225DE80F98D02253999F39A145FF3008F12880C173A7ADEE15025E3E186FF0C2090872A0A51505A09094FA2946AFA1840B0D6D526DEEEA95FD8E259E70B2E794C97F50E7833B165E7BEEAF5D3CAB7C3AA1CEF00003B94159F0F6DCBC74808E3FF237D5C3E94353FC0E700CAF48DA8BD94B991EFFF2DACC9E423A2AD63824CF879EF838C784C7D4C0CEE3DACF5884941BCC14E043082D382AFF598BBE0321DFE9406434DDF558EE2BDC272C2B04CBF8CEF92EF8180D0FEBD3D62E1F73F3B1E7FB0EDF9B50538D49C52CEE53F3000E581FCD7E6FEA1CEEC9DCB4876B3F1D1B1A301A2D395DEAC54D68181406D7ECA05A416D3D8E0EE10228483D8515A0F662D933C53F945B50C65C5B8D51EC45360661C92761A1F74EE06FAF8889244620DABA05593DDD4D6A82A30F34DCEF50B1B1D261CC357AB0673370A38DFEDEF3D591377CA29DF609682EFFA212092ABF84FCAD677DFAD758575CA35046467C6925B6185F9B734D5E194F5CA48DD10D0B84B7E9096703A9EEF0D3EFEFFC0F58C4D38D741F15AE766D06156B26E9C82B464C9F609F0A4FF699D52E0E11E054738476456CB81859ABE457F3595E9D7F1CFEE5D0437094CF093F468C79C093CD615F7409A505C610169010F46E148F3D264FEEA1DF42B3E78D1C4B33C92EE9BBD9C508E89BC4CE0BA0C412F75821EB54730FBB627C6C93694810CD741167D5288768165A68034CE2B16B0E73ABFBF75A905C9A9E577024EF2070EBE8A68076AE37BDF3507C7CB10EAE13D3A05BB3DA33F873F488150CE67AB892D61A11FAF5850B6A26862FF0CE85E4B0AB3EEBDC81F68BFDE39B0582185E4322404A0195BF5951BF7CDDAA6530DB0EFA0A2E6B2A9CF8DCD8B0D15447448847D1EB5FCCDC80EEDF166988D55DCF3BCE37E24A0A5F302F820C2782849E70BA47523A7AA1FF12F144148E9B5A1E05035A346FC4028BDA824B8D5FDECEC4036EB2C3A7DA612A703EFBE4D5E5E17CBCE1EBF546880C227EEE2D9CA4113D0ED61AFA70171700F0F9A1BC7CE7807A081EF09E9CEDA5DFFDDECADAA7CB5ACB2DBBE26550ED006C5B7DD89A2585EBED5995F8F76F3EF8F13B6AE77084727DC894C74268D4D91000155FDC94DEE049E54F4E4D2494EF926F23B73E60EE16CC3711B67B6F6B3A3BA6BA8CE602AE1BA87ACAD58650AA8F7F0F36AEA21080CA8DFC618AAF865B14BBD69FF7B413FFC81DC6C8BF2A7B122EC2C13DD7832610DB9E6EA0E5CACBE1703AF551997E6C51BCE7BAD4B3EB1F392EE12C5691F795090C6F1D6405D0E682F279B3DE64A9F45B1853346D8D337FF8037370CB4DBE5B241959FB8DD985A4F154470833E422AD9EAD7A14EC1CAF6308FCF7E9AAC13ACAFAAD98011148A2D52D40511CF13C7CF0ED1E320617B908BD1A6A442FAFB2E543703844B0D40FCBD1B392CDF5DAC9CE4C2CA69C8F04AA033F5D6D11DC1A5667FB352BE6BF88A9978AAD37B01BF8652A2C475E8516AE1A6E56F8CD596B9A780864ADC65A04F615ABB2BD4BA97301FB0CB7D9AB5423BB14C29030DCD5345C54D556ABB116051C04D79C81402B70AA9F32CD01B6C06FCFB416C4CB7709CEB12DF3E8BC541333C90E6D991B24D7D1D98D0839AA86614F3D91ABBEE5DF138A9DF2C0591204FEB3D9DD546305FD017B72FCA4DF01A7C1728606EDBA07EC101D7172971C9F4ACE7D6D09E06BF9E8552A4CB3ABF6FD84FD350F60A3E1826BBCBA484D4B5B284E2E1EF2A164FEDCD0D22AE77026C4A6596ABCCEBF6ACE68C11ED108BD3C", + "signature": "3F1A9B8C87C0A08481C482D90D252CBC687B25E613C6BDC311BED7FC59BCABBE5353E8094DF52017277C5EEF17A07D65A7DE47EC40E127A745EBCABE4E77AC5781ECE95BBEEDCAA01914F00B98F04A6147222843A4F9A4F4CA0DBB5C26B530DE04D304FEF6AA5F3EB1789858760CBCCD9AFECBC45E02EC93827149960F8EC0867CE9D2F2E46F6DD8AF4F959DDF9DF7177BFCD67C43CEBC559037CC88772567E6279CF261CDB891631CA68FC3B88F7A5EE03C964810E29943607F890FCD81F4AC0554EC8FD304741DAC4A0F156B66DDCDCC7D12BD563B2D54411891CA94CD44F6EB127A7BB3C0FC51A06597639C97FA4787D4C819817A8100D9463FE92ABC339426B7C57670962575B37934E890F6924F95CAF81E62D42821B1B4E669320B4DFDFD8D213C1CA405F9540D3AF7776A3265A717468685F0F3A08A22E60517C6DAADED6AD1365D90E7D91DFC8F0415810C7F98406CF0C24A583B13531B52F3F492969B198B4AFDDA5340F059D21E8F5A830E1DE4DA51E17BEBFE8BA1E3B9F6C5222BFE154516C1C1143B96A49E04DD99F56F047E781FE925171D83B3755DAD89C361CE5D4A11A7E9C37C245BC6B3315723EB2DD15DF385A108C719EBE636ECB6529D6B9D4817EB011FD6127270831A097ECDA206519842148B029A1505849118CA06FD01FCFE100B1644C44379AE47442DABC2BAE7F342ED79B26379D50C0E61A809EEF8B7EEED4B403407B44FDB7E683EE3F85881BB715266F87A96E6E3DC1FBAC1715D1581CC3691729979E97D577D8691A9AB21769AB550C258A15F4A432EDC1E18669999051A7594950EE013D95E269973762E66808BE560D9765A104D4351F118653BE7F425D0FA9D3581724604028FA8A4D35C6AE687DCC0B55C915D75E5C590366713AB78A2AEA5C1515F36651F85B2997D6027C8AD330D914F3DBDA26A1ECBD1A34125342A32B5F432ED6E8EAD0E1BC5796108F5784CAE34A3207973A13044699B496753D7CD4420A8F45D71017C2439B773771229633E08E076F1AE5092ABBE3461DE11AAFAF154587342D3CBF56939B19DEDBF0A612FD3880A5B6D2EC518BE04D81B9F183250D9EB3949EF4B7A7EEDC4021B1A4DE20AF1B5A1633A26F3D1789C1DB42F379E4E16F1C87922B095B5751F8FCD4E9415438AC7F546B1BC000927A06A4BDDD18AD62B2E829C5C2E464F178D1FD9CFFE82083FE84CD61F5AF373D10B0DD30B151BECDD8FAAB9E185EAAAD459EC55E905B56417F5AFA8024B6D5B971D3F070F5CD513E85712B171D7DAAD6A47351279D4D204E33D6479BF0747F7F895117DC9EEB22552CE829DB8AB67A44E035748BF41C5663A17A1AC141DEEA02C990858508C62BB05D8ABB8825713C954C509B67D7A56259172F25E3EDFF8EB356A818233DE470F543152FC9AB0C0F2530FAF9B1B0CE6BAFCE2FAA46DDC76FC90F6B658DAC93263CDDA34294269AFD2826B2BB6F71E1608A6232D3CDD09BD5201FC7589AF0059ECF3F0EE167289A6C7EF1F414532BC981AF7D44B1F8787C4446D9619505B11E6F60C0C861C66291952A054DFCCBCFBB0DD75C9A74B0CCB3C0AEDA3A6D1C1C1DE0E494FF26133CE52A64B397A7DCD547F88F4F327750039B2EC77AD56E4D1A793A539C0EECF501B8E8186CC5AE6DC5CCF0A14964D2CF1BB83A974780972B2AF75545B9266DB1B3E2F052E15758086BEDFC5CD42DFB3E1F2DF6DE49D9CDFCC990174F52C66993AB07E66B2658C9B430E92838E38ACDD02CB9302756EEC3CFD74D92B0D89C90281A93ED479B7A37AF9D37A47F8E04B5B261669083F97062DE23B6C52EDFEF09CCF65B8F32920E5586BDEC1634009D42EF43640C26CE938B2BB5A5E459B74ADCBACC76A2BF7712509553DBC30F9D73EFA20F95B225808F22101CF4A068D6E1C1C64EC656EE535C57785296755F757722E897A53264E63A0311A13C6E47120C3850992EC703E98AB8029B6E29EA7246882D9083989C093382551663C570012FD42DD97EB86FC434D359B85716D0084844D185A1FE8AF8C90F17510F0E1264EEF6709A2C0E9A840F49C6E7E2984241DE2A50DB152AA9D43CAC0E7C6707B55BA44D18F36E2F5F89BA46A5C1E195E0860CF5B3CFB1C4C71A0A53AA1A1A83DE888D8EB9CF7354B361EBC37DAD4F9D0F96CDD62D108DA793BBC84761C5F29F24910D736C8C9A70DD467DFCB46A53F880414CD2634C2E8AC379F2C29F52167894B6E9BB41636F93653FE4371555E061B711442BFF93D04E0AC20D7B4E92A23D1BC77387A7679C688436D34CF37132FE336FE29B57F8D792BCC76C9B4F2CF048A2C8F9B3AD2EBAD9DFEF954A55978078AD5DD59189C25411717BA0C59AD2C89C7D58C6758019B3A134EC32B8DD5A7C90DEF509DF31AC9DA19BF136DC49CC8518CBC0B193D2A8D7681A1A8A6E1B4FD96896CEB085374A81C082C3EA606C4113C85E78C7C72945EB436497E5DEF79340B64DF13AC56123980C2B4985AB0F3DC4F1AEC2CBCD47B4693AB4DBDBB270F5FA2B7BC4A69D77B96164DBD43055A930FE97296034718569D3DD151CE0440B94FE8A2656195AB1082BA64881CCB1B196BFFD86584BECC610F9751DD29B0985BAB0DDC4D0583C2A12BAADE088C6A021A437989BAC7B72709340B4BB12E6FB9BACEC05EBEADE26AEA86ABFC225121672F2687B08E8C6CD87C744C62F65AEAD52EF3063F8492CC7DB1FEF69CFA96532001430BF131064FE5B2EF71BD65FB69F2E1187B34EF659AC499FA178B969E49F494A9FE3D0B3DF5BBBEA9E852D4A9587815E199474DCD774F5A1A4922E9F403EF9A56D79BF8D20BFBD3D3296757A29EE30F3A8DAB3CD909E8A50A775EE2BF33D136DF4234E7D44A2F5A4B8EEC945C6BAE494D35D24BA70122CD9071F3F7B3B217BB4B0C1035301D4BDFA7FCABED5E223CFA7C5420376B53EB97FE945BAC67CE84DA6E9E3A6BF44DCF46B5FB35957A30E922793FC47FB59AEE2808BA559D422208180F437108128C741F181E3ED84742A122F30B420CE3063016D0B8B8EE07293DF269E5B4A427EBC108EC22FDC33BCD7F02230A49B6433BC4E981BA5C72027398085E36BF72C868D3FCCE0CB15C8AEDB801254ADDA850EE2AC97392E36084A8456626131441587F72CBFD1974C3780875EA246CE93FDBA8757591A30F00900B9B9E07A77469D03897DBB6F52F8D6ED02F77469A825BC1F1C276D75DAE5307C3A72F09825C761CF44A9F78A2085B7F339549F0905DD0413211BD3A82961C5AD4FE88B9CD776640E38434392DF1510FF9F416541502FF9C81D0B92E5F6A6265A982DDA7A457D943F05238F3EAF3EAF88A6C300F1E6F800BAD8FB08CA1EB1C5655A5ED869F3BB7DDCCE5EC591A2D19A043342D554EEDE81242A9A3F0FA55887EB621684235398C15C5AAA9962361E94C223BDAD1D69C87A684390771364A87FBB854371AD33E80AD569753A389D7496A1A7682F1265C77DF9AC5B629FB576A4C0FB7954EAC01F5A94E213D1ECA6389D8F4FF9C4B768812E675A38870729756A14A7A17EFBA62981F03BBFD55248E515BA5913B770576652CE2836471C0A831DB7ACB9CF451CAA0CBE56F6FE0C84EBC5A551FA3C68C9C444D19552697E65B7A5D9535E7A6E5B1D322CEEA4F7DBFEA175EA716E750FE8BBA057FAF26D03F83011E92672E4BF4F1336FB883CD21A2AC3AAE4D81731DB30D794B04A25CA4EF2E389C54C237B1B142987383AB6F6FD7C527E8D3886ADA4F3DA08A20F33E252BF946424F058BDD055338E9DE72068D5BE75A06A0371102C429E980233157BB1B0B5DD1DB65248A9AADB3DDEC4EC4563E6353CEB01B8991D7E9A6B8C80519CBD8B06380F61A920395E4D2AF2910184870619F5CCF4E8D4E05F81068D88834CA0C64D5B91147A876A569BA0E23D430DE76B1A0CFC70B22CF4110423328196D2083B03D5791D7D967A82FA7DCFDED446518CA4D29BFE3A9B0CDCAFBBD4C74A5AF9445721EA1798C0219E9041A2543F31D8CCE862454F0BD361FFE6BD0B95D51C777C430D78E226E124C7A0908895C78A55ED6B0E841DCB6B42C8093958699DFA5F0B82F0C94697BDF822B7A94E1607FE85A801DC9626117E3D2FA3D9D828706AD8FAF1FA130B65400A5256EF7A174953D2855BE3FF62633E0C3C533A322729D5327AA103EF255AA3FE75A173224085BF3984A9C0E1DE30D08B04FA841BB0CB0C2C3C63BB3B8BF8310673200F2881AC80A621AC51DBE999B8561164A3883F022DE646A95DF2EB6ADC8A773805A009FD8BC5F72A758A109E4C3A4841BA80F27789C29E23FDE6ECBF23DBBC3C12556BA32737A2D625045550536EDBBE859D02279DF1A8DDAB731E1B2AEBF3F84588B21D109D9351BAF83E1AC61F990C564E34768025FD6124B0D8007E5D4C0D00521684EDEB739DA51D3A793C6DB364CAD8AE59C8D479E66843204675C8A6A76193D5BD690E349A27E6E55FCE7D20BA1460DAF762A0033CC54D42F1F387DEFB6D5108A3153FB43E425471092E882A06D34A226EB259667D6C85AA63421048C17B2E4E0488F5E4038EAE9C5D4198ED477470E4E4C4D4734AA77DD93F7172009E4583857501511C9E40C6D22ACA8A16A968F3C037ABE0E31437A82150EFBBFD7251EABAD03D93B2DE6159CB2B432802054AD2615F96552AA978C8F8F5CCD0626DAE79BE0BEEC69BD34C6988F6056F4FFC5DC3989F14EA6A486BFB4ADD7DCB960D25F71EF515B024CC9898EAF414EF07744A98F0DC3C3CFC91C4BC381238DFD67A29BFC43593D3A38C245E5E2077034BA8A646202AE547115BB40A4B4CBFB7D47AA6CD628243768F2E2A4A3B47B96ACE2E8C3E23A646C129C9F8885215EF0F7D13AE8E64D613E84366653A5DF27A55D606F95B1A44C56F40BDCAA60405E1C02D42D72F391E7BED3C7455CB3A26519DB1AE24D99BE9DEC4AB2119A6F05405C026AE30FE263AE13623F9A81F746DF4A0563DB49C14BD19BFABF1FBBBCCD6B05B565D9BA16B86C1F61B24CFAAEF2EAEB52D92CBF130FF5E49D834244FB34D478BB20899FAAFDB97C8901B11E906263A3F353AA2F87D66BA6DD41337D2C1D05819BEE7D215CC2B3ECA5E0A3A3A71F7FC9845FA2751F25FD292C37EF96B0017101E3C250AF43DC4307C449069E9257BA1BDA5B823E2343A7B1AD61EEB1BE94EAC4E410D7782AE9E8A75BB54849C5764C45935C6E4B2948BC6F72C620574096D57C14508719C21B02F6F75291A669740283303DF20ADE6A5B3038E82DCB3EA9508BAA297D8E39C56E1E1F98A20D57AC893DE4C1B59DCB35F1B15D2B923CB2ECDD2D793DFD3254B4CA3F8878E04CD301A1AE8177103E2012D17314D9BA9DCE0A05FAB6A7E23740E713DDA18574C8BF8AF2D116A16BD17367D5FE9C0C6375260481AD70E31FFEC9F8B9F63E5BB0FE6A4CDEC6782A5C62779B0B1ED0956865D963F89541D0508EB31EE26ED55557687934D2DC9A1093A5ABD5D2357672578D1E914E9329BE8CC1C6ABB8F82F1A63044C3119AAB980C1659FC7CCD04041EB8749AF7222E4626A22DF729D0B878A9FC434F7AB431041EBF49963F7F283BB5CB3FD433BD75428AD445B281524CA08E5ABD1AF6DB75208F70B06036399AB66BA84A014377685275BA2672A5016CAFBEA373C6176987232967F81E97156E1057F45ECDD86FE18BC95C10B3EBC7665F879B100ACDC4989427835F9E1A778F3A1E39B4FF2BE81E9B30B4F605C4144FBD8312A879436C532A72E6308BB794A2D69B4A6ADE42EF39C484A494A624909AE942BBC0C36B0FA7EE3838459B3C829F8A636FDD8750793ECFA500D04F10E9075957EB063776CEB14048861912D60DF85E43FA2FEDA98BE9FAD55E1B5A177D82933AD17C5B5913816C90FEB8509C91BFE8199AC75D66AE907430CCAE09CB2BDFFDAF40FF4341EDD45F7EBB55DB6A8691632D06D1DF6AF6974110322BDE9ACBF7E07DA4FC7D6C6D300B4CDA1AF21CF5EF780053BC38C17D418411AB6574D4F3F5E9426014EDD74DBCE26C76A53A09C6666B399DF95307F82B98264E45A6C158C7DE95567E74D67E8AD591E296B67EA01AF48C01FF3A7141F817C9B12C2A73BAD5B36694DFBD15F7D98DB91848A373946D9A1CE2955BECC1AB0801FF4B2F00256E3F62AB684B7D5F251260454C97FF6979E8ECA36F2956876009F7FD24A4FFE9276544C40044CFFD26C7579734AEB496F4E10DB0C5664300684D5D8B84E7466A4F857560F0AA1ED6916EAAC996412B4CE27DF2D877CD899DB377276E500E89533A9B70934365850CCE9145811379B924846C45627521E34AB03366EE128EFAEC353C695A1D4F13255D1393722CC03252B814890F7281C5A4BEC52A39AE4AA2F07565BC810DB4C32606F6864618E549E496F8712D45BC2B289200776958040B6B47F8A93F341DCB375994474059F46767F34021E3F424768DDEE1D2C3F949ED5EF3D42568597E8F309171F2046B7CAF00D1F2C88B2B7BAC1EBF61B36484C71AAB9D6D94C4DE4F900000000000000000000000000000000000000000000080F10161E283135" + }, + { + "tcId": 44, + "deferred": false, + "sk": "B6A445DC4F4638D109DAAB0B266BE84079A7536E8CC0598C04202D52A38D74A2663D2C880ADA729C99379BA01136A54B662CA0448D19740139F17FCD3D713992C3545BEA8BF149CC7EF5555BA739C80A9323261BD623B40C7844CC3B513FCE137AC51138544AF6C55F90EF757EA51472036D12F01E5D7EC3109C3E04C91E4F78209808DB8285C104884884019802924A9690DA0046C3A064600631212700E22264CB008191C42552422E100671A20884A080458288511CC66411B4315BA05121232024968192069010124859202583C6881132651B991041A668091871132322CA4449DB38021338622222869AA41113A73182100C9344808C107002A429CC1251191220591800828268093711480230A4221009271010B741190941C8924000822D88842941846490322CC8B840CC000C5B28908CA85124228CC416908A228ED0C445082760C9948C53C44C40480E8198515C8864C9B6200C172692063000004ADC8271C4304A0CC9250A098043040923002899A291831266C884640205000B94859218905AB0081C81491B156A0BB8401300119334011B26050A445092100D0245091000924A168980182E14244504446A143366620849A01400A3348583904D514480C39864483446122180A2484C1488095BA400841484D2248C649425D188690BB4519C181224992823316E194320110706839809CA30850C960150464DC3962CA3A471CB462C9C448E59C230D9C40C18972008C41018C7300238921217911CC3445C025220390861482164A26911C18853C24121130544482110306DA3A4904A462D20352CCB264A03985021B3055942681117262120716288705B024888940D99A061E44091888051E0B824CC086C2140514C10449C04002236820240104A082CDAB28D8324408C007120C589E4002DD8C08C9A24045382298A328060445122204C814871830628C416099AC289CB408E4C9801E0468A2011451834240B0790CC1406412882D146311B398ED3108C12A221DBA6201908861CC5400B090053367119A27101964D1C857012A605C83232A33861403490D8C2108B122958248154224693022E484060D24672223552C8120910264913802998926519458EC81864118688423022A14232C1880420454089288644064680C28DA3C0800B078012428DDA200E1B2080A4B691D4486A5BB4004BB85161B44102B32C0440724A209023822C4C46695344219844049C367019C1111B904814C605884289DC820D50946122B591D91009CA164ED3406C0C936D4C181001C4014B8824002112CA042809146A1C920C6244842034255920458BC671E4043150948458A48811C38D9C806504C9012016521B9821D93051884081232201D3488812014CDC9221C2183120006012995104B00993824123158120960C80C02D5B062108382219C72002B10099C424C21402D4000660306E0CC32DD2383113C9840314024C06490C219040262911382182A048C222724C28898334220C2846E30802DB4442221229C326111BA808208644E41620D8400013C80D83044D20283260080401074611018683442EC31804581206132342C998901134815A44901B26415A480A8430480CC89014B7858B002CDCC061122611C1422C44363199360420A9804A04605AA285E2B431E3086251166191824D41C02990046218B270404608221381C3B03064A441412292A3B0680CB80C00256AD34686919240D88029C41681001380D1288C1182811048690100301AB5901B0406D148425BC26523B08110152543006E8C268924A28CA342701140800C0126004406D026465C882DD148914A420E9100500B02318CA8008B38521C21520934121A498640B2210C9991222308E4B0314880699A8630DB40051C41259A32049314815400529094510A396811A68083160D830001603664CCA6242182850CA7600306661AB84993208560444E51948442122AE312100C0472E2184002B921C916464C868990B42420C20D03858519A068CC34044B308943B20913236524178548B060D42662DA0642604604110070D2121013C750D148716100099A049294102C23146D9BC86C848260D0B045C430222289695BC24C1880091B322D91A408440682A410641A256582C070A380298A48285A406C62140180486E083780249284A10042808888922082C9808840160551406423B16D24896DBCAB7827992C8BB6CB1790EFE735E25FA69A53857EF72C747691D235BDAA8FFB682A2A5835AAC37E5190412ADD9E5B91DC9513D2DBB8768978D32D3743156EDD38082F2C93C1C82994969F6719035478DAC4C0CD00380FFF08A9321B2E3A14B6A4CAA808A562B0D02AD7BB4DB593B318E55DE21EA3EA6828E15F150C0780097D0C576F3295C2E27B63139127E4302D7460D6443E1D5AE1B9B5B3B806F956C78606809347647DCB91331BC57D9C81B48C480138EC80A7EB9D623850C96843D604FDAFB611EB92201771CC4AF621C4CAE9A8D0CED827C6936BCB0CEE6E82C2A097CEECFFA25C62E713C9D9AFB571E42F1145E1D618B0A1395DFFF5F07291627EA5110185EE11B1DA3EB2DA29EC38596B47A70F34430C373E3A947E8848DAF8C269049C551FB61B25C704E5B98E44B39D34448E50DA0522F290328EFAC7BF9AD912579AFE639221AAA177673AC83563770A1DA92977DF8C7AD850437F0E77DA98747DD9968E965D5C1EDB47645907F0AB59C4374C0791C60A8BF3C447017E45A9BD4F2705A9598312B5AE0DEEB5C4F9011665BA56B733A2743EFCE0C9199D575EEEF740AE78C1254CC6D486509A26711742B5022DD0FEE1F440DBFD5C71C11FABA95006FB234E648395CB8B7F047D4112E08CC773043B848811E916520056F19198904B38831ABC6DE68D5E67AE340C08C1BD05E25E6325F5D0A38523DD12731F9FB134AA252376E24EF10CD7348BF0C2859257BAB1D09AD45023CD569C8ECA23C0E8C8F9159DA852A9B09407457F3AF0714C849D649275CF166344E6CD4367812C1ADB0E11F3DFE6A28FBADCA7AFB683E47A8FEFCC018FCB4D51061C8854E07EABBEAE2E0CBEF1F8D6302230982DAF37310E9D21F84C2D660C9D3C5D09DA8777634BDDCA0A1E720B8DC8132DAE59C3CF64D7EE262B49888EDBF98602E55F5B5A3D2CAD14438EBD8752D6C93579790860D47D5EF94567359A77E56B866DD04B77A86CD4A2EE6A21A476ED56B8A750B47907D65DE6F0FAFBCCA5397F125D519669E55BC5D03445594217141ECB649B0600FC257B8327F4389ADB0D6EB9080A444713CDE66D2509D9D8AEBDB3D6743580AB42568CF6D65D4F26F494D9F12AA89E5AE3146FF08A4EDB569E77CF7E7D238AD9F5FFA5082CD024676B010B245306582999936E9CED1DC493D8DF09F553A7F4E71540F10F75339E63EF17CCD3F9E857E17FBED81485C5F21672194DB806A66E4CEE58CB4BA9CE150506A8D139B044BFC1B985235AD526445F067BB4B458DD652475CE873B16BA403F4D2357825BF8F98D45DAC29376670C925616FF8FACBE01323607017A48E6D3CD18C78505BD0FECD7934D7448B5DABFD7C48D70A21B89CABA42ACF2FCF1C3EDB44A9E9C3CBBFF2A0B11330CC5E03BF8244F04F97A1014677BEDE221EB0E5BC64A8ED93224D517D8F525340DD0E2DB0227A56A3BD803E078285BFCB40B53F2980E3004ED1284D60A604D0FD420B83638020987E42433B52A31F052E5530029FDB0F52858D41D2DD6DFB85613D7BFC3413015CF544494A4EC1F21F5DE05EBFA829FC6811544F4B38E04BE93378F981006EEB92DFD62C58F2B8E89A8FEBD5F26C58B4D638D404382CB0084AFE425F056C6CC44CECB80E2247C51C20CA4AB9451060626C594CBB3CA5B1C3506E8D52906C0B5C064D35459B1D17CDE9B0A3A55DE2DCCEA8B71D13BEB28FAE7122F8F92355E247698FD95F5B954945D4DD7A80970C443A9577BABBB8886D7E08DF0EE7CA01935F46396061B3CA9126BFAE452235B04358E9574263FF5F0E052CC87095942C556C8C03A04FF808167780CCA0F0D9DBB9656BA066ADDE5BF6BB87DDDB4BB86E7CE778BDDC9CF467D621C529947DC47740AA21E275186F4DF83EEC4126590EE026C4874D67C60CE074E0F6CC3817965BE4BAABA2D4EB77D42DF37B792DB71882F5B10980F433B9DB158DA15E5EB9587AB568256342D82C1B8BBD4366730CE414AA25F7E97E4A0D27089C3A53EB451E51484C257F65D82A7F64D72267468E45EACA3BB5180694F842723E17901D4846BD5138F2F88DAAE1C79D84AC7C24E3CB72476AADA1AD0792DC4B031FFD4A35FD3F23960CE912693C67E0A3DB404979ECEF172CF8FE7D13D03D29CE3D57CC8D1C51690791682F68AF6ADDCE013D085107BF2674580D44E88D47B052576B6769607B7C285E85F5C4A18A3EC2CDC93C7C74289F769FE703D0D66231AF23631EB88411AB57E21FA1CBE2766B1DB69A6618DF0D9E85CB0D4D0AB001B47349FE49A23AEFCF72783B6FD9AF26F5863587CFDB320376F094D5DCBD6CC32631C9C564AA6A585C7F1CF2B4FB30F8ACB2A4C433B896D1FE2236584DE464BC17D680C1D4EEF6B561BE5516911299D7C7346228A41106A3DC9E5B4E75C8F04EEBA3D36227494B22B06D578DC99F8ED068220B4C4C791F6FCC4C8D9C2B94A7B3FD9930735A00675549E648CBD338157FF5163002E99CF94171849FDE5FF7530F552AF54A95E6CA4061A6556B30FB1385621253CE70FED7BDD09872165EA8740BC1E303E34F69ADFBA16CEA146C7ECFFD12906DE24947CBA94D068DA7F51B5E854CCC6DE513405A28D9CD3E409D33B70731040A7079CC3AFC2E502B3AB1C4EF1B2D514EF445EC99A530BB049D4F8AD7F58D55FA3909F76608CC23FF704586AEE0AE9050EE5F2634767997FB39D44688E949B9C82C3B605DB878D7E51941F8D9AEB66097FA206462F5CE7F17093389800B239B86D0ABD79B66DA99FD0C65E3A3183A143FE9B45FB85AFB57F2A101C9713CE6C4DDAAD90BE6731679DE7C72AB1EAD6CA954D350B9361FD143159B45C803420AE88363C327EF31BDA33D2B869857403615F20117AE708DB5235583E06B82B9A5E7B81AEBDEF1E696FA96D76C3F6388C4D1EB88EF3F9F7A95D5B9F446AC7C27D1915717FCADA4F22458FBCAF7D4377F2E743AEFA5246E840A96F017E139125851055A1B98A91D9217207DCBEC227D23666E76BCA0266566EFD0E2D735498A2102E4D52C6FD758568CEA164E0A28B67E2E2907BA6F63CC049DE87E61771B2095C6BD2D58D4A36055FAAFB51B63C3F9BC06F3B27F5514A9663950A6804A5D34C8E1BB6C924C8BFF44BC217423C5FAEC7CD56B61B746A0AEA7C37EF6C6351969AEF292178B75DC8922DDB935717C897098CC41E150E7633C91F6091969F19525FE257268AA74015EE2AC93163799B03785E14E69A87FD0776A438C01DD829348D6FB825DE7D2B01815C115ED418E5C132074904ECF4FF06775ABA0A498B1627CF49D8ABB68D3CA440517FF4B08B0C4B4845022A2462A0C1C5B706B061F406507094311D311ED0A5184AABF03B0B0BF06C3FF55D778F280E9F3376504DCEBE4B9FA4C4A55D93D7924EF9CB5849364CAF92DC3C5E198A3D1DE5B139C13AA39E9545959D6D738C1D88288A908A1E7DC3ADB26DCBF02D9F98BFD8FD61A6A96FC4534A2D212B208C48DF6BC95BB415932AF801B5519E8647AEADE54B68539484302C9B5A416848C2F10952D1A66078997E56AEF14FA8078FC8E35E1BF3BFEE35C3D91C31B0940E8218DD83BE1E633E649712241C61DE8FDB1B84C0BA60836F95444EC81A48E591BAE36FE7CC449C9B88F6298F9E9588FAE54C40F661A6914F001A75D4BC6280E05643F0A114C2DD71EE8FBF3D7D4FCE18CB8F61A6FF8B08FA1D20378922EDDBD2175A2F2920F434919F0F9F1AD7C6ED5E0FB13EDC924410708F7973270A03604A0043AADAB8F0368871040B418E74158CC4E7358BEBCDAE696EA38ED155E3599D06F86552D9556C39F6A435770AE62878C4FCAC7E8E558BB85EDA22D0DBA818AA3A6BEB5958D05520AEB2ACFB1BD403047DF27BA63B34A42ACD3CCAB700EFF0B6906D18672340F0B6E2842E8750366885E148AE0E5546D013427ADA215A4809C11590ED8A7547131880460A3179BED70FBED4A1C304452C1AAA8B0F6C5575C2F60B6E0AE93E0D7ED699A3B039A61BD63AAED95E4822D8D55452056A266D391E444819970CFB4BB767C6613CD0C65B259DF532D58B2E086BA9A36BE37537ED0562515B6AB8AF615ADDDFCBBA355363DCCA60F5EA2B07E59174053D6F29892CEBC4A44AAA4971D19171D2029854FDD977BD357D54E8DEB4DE463F251DC566DA73AED7170C402D3F4DF466CA5BCD8BD47AD1A499B176E39F4EE2FAB9C7225A3B98700787B73CBF36C42E934D0EF96B3859F980020679FFD83F106D609278C3DD780E2E5DBC262D9DD8250D7F4A24DD27F3937382B8E7B2C3269B6CA09B522D0DBE4CE098418E95C17FF32EF99F016AD4EC8EDFB7028CA9F85ACE4976A6D11E90E2990C762E7E4845CC7C447ACA8907C94E81CD6E7664755D378030DBA0208CF039005F433083E1E904F541B036E03F7C2686630D0E5F8785FBB33E03566E8CFD19056A4E6D1D277584EB20C8727D2C79D910F12610C003F90899CB6B5231D2B3A5EEDC0355DFA7FADBA5C949E9B9274E9DC69579C10DAD85552CABF32E90870D9D0CF579348F46874BBA064E918BF4A279F55984CEA32649111EE86059406CE0B0D50E4F52C7CCF110A5E34E01C414075CF5B31AAC9F504E9499BE75CB3EC35C2C19F7794769BBF34039F4AEC85C48E772075B887B63A5C81595EB4D17F2F25912C120623439E93482032C20F7CEFB0CDE27B2799EB945DC28EEA9B94A0C4C5592", + "message": "D46F4482D570F26C7E9F0F74A354174CA145033097CED3896350DFCE8200CB9448F522B118698DAD51F6C672E1B12A412DB6B7B95CDBDAF6205DEB631E44634412F026CD95440258FE5F0C72C5F3E64FB3FD13E545DD856EC2B7F51AC28C0D5D698C66C700DD3E409BFD96E14A9DAE1677ADEF2CA2CCD178B826AAD3859E569541561073095EFCA329B5B216563D956D8B7BB918224FB479FF7025FD8168F54D14ED1FDF0B399130C6117B5645D0E8DD242C3C7AEC6A8361361CAD9A8FC3B5A40BF7E73F1BBA9AC7F5A583A5B0EB95AD0AB4C1360D0145FC2C3A9AA50186D649B72B41DB7EF392E663497B3166AF9BD0C1AE21650D6CD04DD36532AEA0FD1071D6E9554CBB575B2C1ACEA3DD4E18615FE83AA211F8AD330C78FD32D920ACB40627CA4AC80F840A64C019124079484B053F525A5403383C21B164D0C6BC1B462C0E1C269A1EA0B2438FA64934CEE47149C4EFF566D9C2234E656969C1C89A0B0A4DE124EB920FF534B934172686A18A1A269960C725940D3307B8A913D56B78A6CDCFD559FF97E225B61AFAE7F62B060E7D3E2D4040D8D9233A24827434AB4EB31B0D528CB0085953D9A1A0FFB748588A2DDEBF241F93B41F5C856159EBBBC6571AB12F4EB534ED3C624CD3F5F836A99C7E6E2FFA0369654A5C07C19D44BC9FAD96983660E4D6F95DD9C38D84DE11271D23A6158B685CF050121425AF91C6FFEFD0B2061F54CC4393F99857F3B9775F81B6526444AB705F9CB88A2D276AF2F530B646FC3D93DE7087EBC1FBC7F9A8DB3F3C8FA186F7B636CCEF99FDC4532E54F560519C94B79B1158D85BFBE23D4F36B64F8056BEE7558252DBB3D9A43748E2E6A338162F5E2BC0934E89DC79091180C93D340D3615F82E7780FABF782E5FE2B5D504F3BD1874EB5DB76CB616CC034D9B2B080319FEB8EB97F62FA4498878FF049FA97C56ACACD2414E0BEF018F25A6254448F02E64815E525AA06AEAB53969A66D453B732891E31C36679B5C0A4637611A5983F21F6D4ADA1DA5E890C909A9E968F947C686C17EC73A0F9BAE5C7BF7433133F35F22D2A0B40CC135A7591E2CD216F7D8018969940EB9A5C4BF21579C524C41AFF5DBC0E141FBD02F1BCF376DFFCFBD06F9CD4384E128CF1F03139C853CDD04DEC61EFB8F1DF1A6450E4ABDDDD8A9D85BA79479562A08CDF06BDDD2E740DE7AD9AD1016D72A649A73246E8DAE183AFCD6FBDC64B6B6B2EFDDF525F3B764CAB39BF8D617D47FD3380B4A30081AE6C3165E9437B2F37A73AFC5E596AA626FE5A32D8873712F99910DADD0DE296577D4749F88639D07F83B0F6A05B1668D8008EA749580EE5A629FC2313FAA2F8ADDB5764B242B6B595A39AD76CED4CE5BC34C580069071BED1F98CAF4BDF740A5B1DE3FD30C29DAD808537CB16D0EF22D937F297F50E1681C898375FE0374ADD6EA1B84C10261DBECCCA8E1D224A4709497CE696BCD2BC1369F4135E815A781EA26A055DEA28AFCFDEAF6AB1117085EBF6B8AA6845FD4763FF9274BFE5FC6E377B9F9DA8263DC1F3D53C83F446ABA5EEA4095AFF91F3BE30022B9BBC2C74FC52A3B15CC76F29E541A84C5BF42D499F9B5EA134E24F01E8D866FCD20B7F7A302120B13DE636F48FE8EB99F17ACC153CE4371B266CA61D13E19793CBEF12C0EBA9C728096A3DC6A6750DDB0F52E3807C22EBE4DC6B2407593A1B7BBCED799DC3EAFCE50B483818D903765A63FF572F5D4481357CD6ABD89EC260417306DA1CCF71DA568240D4FD6858BB7833B2C9C98B9E7286FA491F9E318F25D0459071848BBA0D3DB8D2BDDFCB7B8E9C64ED67B4A2B5E1E49B55C6DCBF93394010A078E6F52065AB777C7F6D831DDCC115CF316ACF3680BE8766B4E15574AA383030EDA83CA45B965836FB2374695B50472C4159CB7980FE48B58B40C6CDD2629FE3C6DE6E13ED6728FCE45024C96402B78BAF37E74A1C071F4BCC2A1B84933C872FFCD87C02DBE65438A3E770903A04DF96C569FA69828CCC32D13A0A419FCCE454F06EDE43A97CE5A9A169C6E849F075C66BAB418791778ECB2C158FC19FF5927ADFCA90BFDB3B4216E19BE11157E858610BAA373237B42F811EA97EEB93D735828B2ED092518160A2ED894BB108AD74AB0113A8D5882D99A06CE2313BEE3F902D5CE9CECC835974A47FCF6FD1648C635FE56D1B2404927C49EB53FBD625E0624D5AA04D6C0D5A082C37BD67F477850458B8672C408CEADD9A55CC268B75BC51D7B3D75668D52BB701BD980ED22CC20611EF618277B82624A1192287B46BB5C4468F94C68D96F3CA3ADED476A18BE6CCED70924139F2E16C8A54FD6C9F6695E624499AC8E9AF86A430AB856924A0899E75C1FE4A51DA0DE1588E66044B2465C04809272B2A5C8EDBCAE42B47E439FAE06938810526DDFF4B64C515787B41885BE369A31F90E2D6F6C71528412572A67DF6E155C3705929EB28B80DF15345E0E32540BA9AB7E1D1CF0C015E50C9180372C678CE6C34BDACADF45B0172A1D3082565E16938F57CE6B55D9A711CF72E362A2ABFD45B7B56D48E89A0079E973F597D2E457EFF423E229AD439C3193C264E0BF9A8A1FB50266AE4E0BB671817CAEF10A3BD43452A2FD2DCBB2481D63BB539E0C81F6986400D3A619AA92F250ADDCF661FFEDE7617162B532EE2088A87F58E1FD071F5D720FF1F72335A5B4582F1BEB3BF19DBC9D51A62CDF68A855F7F6DBBE5FEB226C9918E7FFBC8A38079E411EDB44177F843EB8CC1F73B9765A0EAD825B3C43F6760B5F03BB75DC7469701AE555C2B7037952180255612DCC9CD35DDB31F3A9218397E1924791D29C410D2E4C3F5549B7EADF75045EC78D579EA7948D121E8297BC5A3A9F7AA2E2EF5776CAE3B9CB73316170F9B48B657BBE365B352A8129130BF1E718B386AA27E493016ADA86C4B3D3D116B7252A747FD50DC14AA28676F1C25150A86C9F4547189523280A3A897F80FDBBA073EC645C9953B7F8CEC3BD08BC0CA5640545B08F728AA38A860ED38C068F0D", + "signature": "216B7639BAE886F93D92D1BCB33B6014E962751B281796AA6DB6724C8B546AB7D62CDA401D6B651C4BFDC699EC03DF4018489EA99B8BE6A2D2CE3E442AAB604A02FFA0641523F3EABC9BC8EDBF7C19CF9DDDAB6A81E4DD5EC6754DE75CD071CAF48AF49CAB50FEDD7218564A02EFB0224957FBA6115544ED19FEFC7AEDBAB4832C60B454564957C0CAFBEAB5F71F4AFCB68458A503E800D6807155E5D61D78EA973FBC45CDEE09F5503D428F547D0CEB07E42118D0537712CB2554F25F0EEBE0C5AF76F9A5E88B9966D1504B92EECFB267121F1A988EC42E675CD605D6E58CAF7E9588E7306F64C6F81BBCB0D7CEE234AD2595932E723123EA215AC877FBECAC9D096BF307F487B0C7648A678CD608FEA23162D9F6FF44DB6D953CA947EB16CB90AC9D156A8A9A60EB7781837A71FCA2F9D9835DB909368A5252C050051BD72BC5056797E866F041EE2221836D4BF341683977FC992270D3ABB95AB3665EF002467A136CE28077C9868680E4005EDD8FE15BB499DC2E95846A9266BA44ACCE9E425E6176149F17EAE5D6176651D2ABD7C1B6538A8F26AEEE04840EDD165C8114CA55D500E1B260B2F469D3AB5FB90F9E198ED5A5A7845BEC24C3DBC48B06D6D211941BF86018EE634B3CC7D060A1FC3A38662E704338A197383526D4E55F5C09B78FB7DDB9A38424130D0D9BB3487348FD9ED8D0181BA9DE43EA5B5701C5F9DE3FC88EDF84846C7733651D5653F75B7E6A5C87C4F236F64147C3361E790ECEB6E20CD2482DBE6F2CCE55437828F4F8E1AAD0307947FC33850E27FE568761AEDE63026C167830A20F247CABFD0A2AD01E5799E0D68FA5BC25F0D2F9B42A2B8411B995636D472498990C549E538101D0CD0E29A29FDD5913FAC1B40F8D9B7655B250900DAEADEB417FF471D5B52DAD310FACA606ED22E4C98868BCA788DFA0AA030EE3637B39B3AECEFFABA6B14C733E997C2130503349E6F4A5CC89431B063819DED0C718BB8F78FBF763A64B28D315B6B0B90D48F94B306F0B42A41242CF27315FC69A83DE094D2CB11FD307E1268F976FAEE2053AA41CC2CB6A8B878407076E237FCD378699F5E65856356FC9363F4202EBE78483C4B2C730DA86473CBE588356F353B7AE64AF874B824B8060EF6E4CB302AF8FB027A25606B68CC4B3803EC2FAE996E8FAF2A6D52FA226E684D1EF4E950FEC819515CE9EFFCAAF7B277C5247ACFB57DAA0812B2477B4A18683B98D2BD11143504BC181397ABCAC048989ABF0386A17B79BF73A12BCD2DF5CE96BCF5FB6904D7BFD5283DCFCBD922EC508FD8C591EDC5B34A123857EAE97FE3665B8109E4F29F5625F475199B57F425947F37069CF30017935FC68272A1B18DD7502DE0798CDDA5A0B21E0C24CC9D8CC15F1F774057E77A007BE721343DED110C56E5E80596273BC9507B392051CF19ACB15A3606C452DEB350056CEEFC12A4467813A37386B99C966FB508D0C2FD757E9C10DF490CF600DB6FB3CCEE68376BD7092C03A3F3F60DB1EDBA925FB5FF7802D9C4618E53DE0DE1D8397330D1167D63AF0545534DC5644C16E6531ECE69579013D51C7B98497100308C1750629C8DF81B45FBFAD69F37102D36308AC63AB2D78D2F711DDB691D59BF4C3483652C260CD1A7EDF1E01FFD4E5D8364C69CE247B9F0924E6BD35D358B63B18DBACC7CA1E8C786D1437A730CA2D24FCC92D59E90F4552D490D19A06E11B1AEDE338A3A8D3207688FB27D581FDFE28C42B66240B6C8F5A24D50403FA2FD34DAA370F0504A87F28A4DF44AA86AFBB6D67C9614CE5CDF5C599CDC2C6294B25B641DB59DD7D73DC21923EB8AD68EDB4D0B16B7C16F3161F7C8C0EC493FA9951251D1C5394678B656B332A9FAB7477F32BEE65407B3D2EF6EAF70C1B430B45E104142FA2EF72209FE29558485DD26BE8E1B526B7098F252F58046B6EEB17D7F0734201AD865E7A6B838980707AAC9A05DC8C34E5B36AB03CCB74570670967C3AECAA9800106ACFB0B8EB38AEF82114C2036677118317E339D19CA34BBB68B30E46DF3136481AF7EBBF8C45951C8733C0CAC97E518AEA69A41C641C14EB71D6DE67A5F7C5C77F75C98906A3E5F2A6E875E2B6D7C8BD2A54554E19616FE3E8C39FC7360749B5133650508E8254601A7B33B82C1BA537623D6DAC9C4C3006968EAF3EDB233453EC8DF00D02D022B6A552FBCE8F3694EFE49A7C6088F3080421D45DE8C2F06C312150FC0CC0DA4DD35D25E7F446932406269D45A8358CD1E2736FE2E1C366F24D5A6DC11016FE6BC73447B1562B1C021AA9BAEED212B0AC8AFC337E1CEFF1609EE3F0A7AAC747E185E3D860D1D828B6EEFB93B31C7D2386155612A9815DDD2411541D91B0F99DE4D762F69C91C527F6B5A1BBBF6C8D65E7437F0FE9CCC669EF9D1F36E6E0CC47B682449258673A02B12248FB784AA2B7F15FECC3753119AAB9F77B3C5C677EE4BD54BE29CA5722E37D744E145F9E08A8F8015BE8A56057ABADB987538C0A1E02A9DE66B7666A0F4061A4DECDC2179E3613DCFEF4AE67C66E8F6114AC74CD9464EF29BEB0830CD2E64E9E5D8B547C0DCD1D625FDBC87E8FEC987C5F5F5E3D0AF5BEB341D62789F77851BF2D7FACDF815E101F335944D6EBD0F06BBEEE92B5DA5F8F98B1F41A2463C6569834ECFDEEA395D6D26B6EEE7EA08D261970D2493B86DBEA68663C042FF7791725A58F6B062697AC0724F09660E2E630C39FB7E0568785158CE9A7EF643CB93026131A9EF900E16DBE4E5E286AF8CF89C69F75C6CB32F3BA9D3B779DEDA8BB75193DED6651F452EA9124947EE70D43BDE04965F5A64DACA8CAF2B5885FB75D1847DC07B4C631E57843EEF344FC4B7A3AF886209D77CE5841BBD664E898F939704B7AF6AAE6D55BF3243E7E85991BA8F0C40E843E50CBF16A34A4E67B0C115542D93849F3C511D977B6B916D59F2DC7FEF38542B6B24EF7D6AEA82263C02AE73BFF5DF8110BF1DED037CE296AC8AD076642EC79F76AC62A1B3637BB4F3078BF453ACB2BBD3A9F30A77D01574933E79EF3C64A316935E8B69BAF22FBCCBCB10A2AEE120FC9F15FF537E3C73F2B3E561F5F470311BA00528AC575DB40E162DC23B9BEB3BD1C916D7E83860557DA21EA6C0E55AFD0903FC9AE08011716D67EE6B879EB7395B6F791B6E946DB867F6E9B1F11EE9BFE04D6AB7F294D8CDC6055AF46AC33BDA8808785DA377DC45BF488A7257C1E7AA193438A67E3C667342FF120FA076DB4057E8AFB443C07C72610BAFF2359CA8269C1795C622B7FABACE8599D039593832B46473E8A823F79B973C67183C8ED8F9173604CBCE4F6964265B93954FE916940E540949950B72DB4EEE74C5EB386109C99537D1B0E6DA10F12977320CABCB53C47F62E89F2C275C8D310E078FF098E4D6550CB80BAF8DF93DD77E5B3D32D94E13889C2146EAC717C7FD4231406391ECBC51E9161626186D475AF3EEC30A3FF8D6458D01980BA72AF05F03DA6DFF245DF4D23D976DA87D1B92663B82EBE0DF8A104ED77BD121357160AFF118D76D5A232E92AA1FCBB93038DF7FF9319481E03B768B68804B1BFDFD0DE0E1C58CD7FAA6FAE5D0FDB51E594BE5863303216E65D27B1EBEF55B77E08B4B485576A1A8FFEE4FCF29F71783721B9A4D8BB50D26BE513CBC62C787C7DCCBF0E2601AFB6373C69FB4CF3E50F4542844A266CF19207389C833AC3A03728A4E70C5AC3B4B099482B1999550BB8A1D25DBB941B51B872422FA57DAC6035732CA3B2F30F947D7B8FC5EB53808795695A295D7BA74B558BD0175A8AD7F46CFD6BAE928DB33A9E3B7D0AD554CD8FA09088325E5620A06C824A809461C378823293E0E7CA10A0A1B345EE60780FC1559CA354126F30FDAA421DE4A3A21DE4F96D8CCAEE2E1F2F99F462470F8215A6BCEB923409CBE4CD24D37252A6950C4B12DB6F2942F547F8C646E0B5F4C1E614C5B6F8EA0E23B249ED920DB9DE3E001CCF5F99FB3B88EDF9391833B510DEFA73F26F9155909773188557E57BA3C5268B45933DF9ECC4381377F2883FA121BA0D11CA20F989E16B43BAE6FA5B0D9C74F8563CFAEA595DF4C887E7970CD883A95D9017C08838D81559A95490FAE1C3CCCA7381EFDACDDF486D158704BB8EE0D9A388487566712736FA9EC72ECCCC5F88348D39D07D38ADD76788B96716C5008717C0071C413C3618727C48D0956DDD43876B50BD63FEEBD2692A01A1494AB26EC9B76E428242973AC66E6221D7404223F8AA8DBF1075E703C7C002B67FD49BDC253D604FB7BD38E27A56B9D27E96301EFA75AA02309336AA79D83FEDA510055C21D3A167458E883D260E11ECB2FAF4468D7D648EEBBF4C48397EC3058C163B76C49729BBEF4AA88B37D9989CEEBF3FFF400A1B05860D921440B5AF5B58554E6367743CF61246302D2F0A1EE3BC26038FB52304EE8E9BE69A3E50E7076E17E2462B44F76D3EBAB9761013371436F2564B23BDACC1134499DA39C276ED99603288D6A0FB997882C3257FDFCB71304B942D77987919845437F7BF114D6FBE9992A5B38E4ECC366888A9AAEED48504AF753CB88EE458C7FCC54045D9B9165D2E052DDAEB3AE8F8633174A22231C0013135D824EFD8D4DCA97A86A46D4A64C9E046B6DBAF99C3047C06AA8C53F19283BF3D649819E8E86E749D2C74C740C0BA0251D3C77C6EC2FEB3153D09900C7198569E66D96F40B566FDCE24B09964671E1B150E2C4C587DC97D3DF2F03AF69D9F13B3A387D1FBCD8A4848D9136BAA520E4CD55D36BF78CBAB778FC8DA179B7E8FFEAC21E3A3BD2ED16F332C2A39841A825EC138BBACAA19AD846A01F15B07431DC989F3B870FD27FAE7DF63EC34319E95304CC86EE8C978DEA85A8ABD84F839F2563C7FA7D1C7198DDE5B40FFBAEE7627AF62D7F57E2DA0C08CD02A5DE110C7FC04DF6B493D4656FD03B80E86214AE5DC00D9BA1F34EC1CF95FDC16732422515CBAEA1051879B87C397B10B08BDCA1CBDA9B10A53DAD9B8A13AD05478A73E88A107C0AC73F6C4CC08E7038AD4E2C7F918CC0BCED92AD77D0CE9C7543B6BB8539D0E3B99A7C6BEBFB4F90094BE399DA1ACE5668F5752859388D796B0FDC2161EC01E64EC17FD22C52E6FA14E5D057C78CDC060A06D0B9DE3A4E46E7EFFBA743AB83C14C3CA19554B1AA7232B6724048EEB80A256C7DF100ACE744CAD137FFC541D75FBC0EC762DC9BF26CE87A52FFBC2DE6C079A50F4BCC209EF47A53D6CE5FF88E90DBA6BDDC707EB93501701CBE6263CB7CF6A6A2B69E25B23658CBC94889AEE51D6A16EADA5C84181CC35257ECC21D60D8CBAE2B46E3C69C48325E4785BEF9A119BAF392CB0469B23C75BDE002898B6896ACBCDA44744081479F99CEF23B70AAB1378AB9F98F76564D81565B380D8A994AF696ED2B317379227C28F880CF58ADD23F0D49F829C5D23865AB87A237FFF17DBD23E34E13848F5F0B4AC551D4865A50183751419B67F30E3292F96DB6821D1B788B21880B5D6F0F88C1A9098C5F07F06474B9AADD76733D329355EC6E4A4658C81D4095B8E1094BE2B1EA4D1DADD7B4877F144EA45D102AA0AE7B9962F7BC5B11CB3ED7E9DBF83BE020EBD4D733C448426E7549A5225357C0319F8A690E2FB2FFE33B73F26DCDD461BDA2EAF1CBDFCDE7CC90A5F94769DE9ECAB066CDD158E55F10C1CE3A9B3793417F85AF871AD9BFBC8B02E3A94200F2510C0E61F5DCE3638E6B87F2B299FF627F121CF8DBCC94479A2CCEA282597CD59BDE0294857C98BD6D9066741AA6E4E8BDF83E00911B1BFC947778826022F6AD5377ADF7495F483FB01D7B83C7319E08BC13E6F161A534F5337395477FB7F03B5051C90FDD486B4B6FBE0C963E9650047E32F666FC3C4F9C9B391FDB4FCCF24EC379639D65F676BD686C0030A5946F0193C11759275F23F4AA242F6BEB1BB7C6FF4176F589AAB96C1D8C2A8F73F1D87213CC2AE134DBE1A5EEDBB6155DAE672A01BB621CAD4E32507D00DBA534173F6207441E65118459303DC8510E996A854015C50CA5508B3D3E9596F242FFCDF2440AA7DA52BCDB0CBD6B9578E0CC2FDF1B880C0187E280C4E2FDE44F2365A9E858D6C5197B56588B89131387ABA1B4845E1E515B4CF3C92478B50933F3CFA42553011DB91B47B16B2151DDD6014787F7AB7DBC053AF93468DDE606965BEE41FE7ECE2EACDABBACC069E426320AA26353F6CAF896D024AD9C5C94FBADB6BC93C5579CD1D9F4CB3F195C919D985E61B56B58953BC69DD6DD3D27B7A943D6BFBD86F41334D82E9262F86FA58006DB66433F02284796DD668D27E0E6B4C97D8A6442502603CC859210CBDECA85DA3CAE4D7CF080F9AD820C6CB8B54222A71A13864754518DE2CDD0E168DA6E601AA863FE4C05B08B4FD4DEBA3508552AC014FC3D2C35D264B58871B92A5551A033E40A9ABBAF2066580EF080D2B49899411393F556583869BF11D2E7BC2FC0C263B4C7FB9D10104353B5E6D9BA4CE0613535DF50000000000000000000000000000000000000000000000070B111A1F262F34" + }, + { + "tcId": 45, + "deferred": false, + "sk": "2C242C2E0E18E6E587ABBF3FEF52D5156E92A73F58F15E88501D7F6DD793D6513627423FCBD68B62D99650E4D4859A8562B9C868E08F2836C1DE1493CBD8E24937874DDBAB2564E8B6D5EB098B1A53F1117594BCD26FCC8A464843135BCB424E6AADEFE7FCC8DD6B27A966D7408C51872CE114D58FD4DC0F31EF954B71C322B8D2106E604801D8320A54B004D480500B179144B864590245C236660C064C924042E0904514282CC34482D82245D18290E01640DB428D1B1781233360D3026C12462501230A83084E9A088D0C299019388019366081360A14266E540648934206D1A28CCC300E04352018212224334888282C4832481A1272DA86519C4289118049C2C0411B484E43082D03934081400C01333153302100116E4C402C49268ADCB28022955140240614090188A66801A60860C46DC3A20D9B129299108A8AA668D8986CD9042C1C276C0A16259C4226108569D3866422A729A0240C9AA04804428189C00802C74014C75120B24122A56509058241B451141749882411E4A22118A40CDA306591C28419442D93B481934064000729CB86898AB06920148C0841520B3412088190D2380604B380D0186561904C802045E0400801A07008250102C90D82C4081221620436088B3845CC20664190402429821A458CE430051123251B250220A16D1CA53003244C4C84410033684C984CA120520986481133249BC271513682A4808084346E60004D2194650146501044611815029102405236904A3649DA168209364E5B8889CA120800308040221104A629DA30650C2329499829A0444DC0128E0A106A019028613850820611D9020D13C190184149404430CC226989A24C99343122082004B6098320296098891C30620909880BC7650B847021A0705A928198B05012261120290D2146281930460CA80844B049C0202684C04480A611C248924C140D9C260444244D50A408C8265281B42118A22449204598B8009A9848233400A24288A2360240368044B26981A24D58101043902543B4919CB60D1C414A94902D4428228B368E64048AD4188A9818281BC830A4402A1B0308CA8611CAC405C2C69121204D208460C3180E22264653961119982000988011A51160286A23037109A584C39849E0188DC80651E3127112A88102158CD3868D50020DC8422842C809D2246EC83888DA82812101609AA28DA242651C1205C2042E08830884A26D420608D38888C8146C90C4440B076CE1824C08394618C63181046409418D0C002A231041A23482003408E32051D2C26904B249D1364943C6840AC2245802319934495C106208310C232384C1B26922B781414641E1860CC4180E2349260A094A10031103926CA2A00018130120968DE3366518176519284C50126203296841B0211B04920497116388099334448320880B444E9B000CC2A6518304650428205146898812444BA68C54882409088454400C8BC20D1395915C260918328552204D91B0442029299C920022208662C6810C95291A466C9AC871A1B02D2049098A123118A20C9B322E5388518B387211820109022010390019337249C04113305061046410094420C568C1C48CA3C2489A342D9AA460CC326E4C30450AC90193462ADC025151268444000993A08100C784D80262510206A4046EE4A6481C29609808319328215A289283222524378449B66D64C4450C179101B54191226582824804A024018329D2004593A64064202513B42510200D4C8410DB901099466ADCB845CB46114B208210802DDCA28821A88921920500000AE4A84810B66D18A269E484814434728A244E82322204C270010324E234504C428111220600460101218A20274D1A39259442098C1405CC8660A2B84802300D093490D3080A0080688A2029123008D49891CA48828A82411C002120460CC0B8214232818C482A9308800C928C89082920266419116210454E61104CA0348AE02404A38410D9007080104CD2464921B304C4B02C9BA80583304D8094711221506420925B244944C49023207243202593C60521234243B04901232E5CC60CD3460252C669A0A04D193809101130C9466D5B324A09230A4B168522056612B97004C96C08178D13916CC232001C469082143183220418A76D40C4415C1001C8180EA0A684E2A2411128918B02450CA6098AC48C5A0890A1A801C1428E04B041803452D9A22152B86CFEEC2BACC5DD2E71A2B1C8A14D54A95430380F6D2F08A08E638EA94C74186CCEC154CE3B78A6B0E275C08A5979473509BB06EE8FA6A81AC2995E8373933A5BE90E0BCCB82D192BD1847A7319F3D61D040C12327370BF046773DFBDA9943C3B35CBEA6AA0FAFF2CCCA040BF38616ADF6EBD43D5DBAE2929DA15E0E26EEE338FDBF503D5F6681692C199A67F29A5938CF32E69EE7516B0C57F73C8C4C686B2AAF8350FD84FBA13AB611DBAD7728353276B0DFC78022BEAA249E4EB008447EE55C47492F6ADB6FA22CA3F924CDD0D2AFD8E4C5427DAA832192A3E36EF85808836AB4FEA9E5544461625A956CBC30B086D0FEBF21609361E0E690563DD39BEA5FF7138726AF93D868FAC9FED7866EF2AF190F7D3173ED949A76152993DBC8FBF3DE466A0C56E0AE069B8666F02EB5D7146718769DD2481E3BEF3E5F54B9F900AE8533090C904CB08633CBDB01054D6267954A315BF0BF748824BD7865DDF8C70A6BC0B47D4667C059F75C758AE56DC9939AFC7D71C2F7D12C4AD0BAF3CCDE9BDF0ACF2739FB0311BBD22B3D62381C64C9337EC0A735B7A02EE3E92939F63ED1A290F3D4A495682A3804C3587855610D2DBA663FB73E220952B6C1C4024E4A9163C853C4686C508B600C6022A4CD7793DF69F3F323807E4623302FF751ED61877221FC25D763A18574F1E0D11ECD755E6883318187D621932E0B30627E023CB5EB88C50D8642D1EAEC03F8FA7FC0179F602AB147522F818B993EF6938C02834E8D328B88D304CE8BDD502045888D337FE490CDF2AAC5237CFAFC3308DDE202F593FE3816B95561BD774F25A7EB0E302D08443D100C28B9EDA8995E5FD9C739D348C01FBE2A4DAD5038C052549010A8C8BC4CE40D76DB2CEA946775C5E46938AB65199ED491FF7F57956AC842C4EEA2A19F50E13FCC7F7A5B71247FB7C6B58F1B244EA25472321ED86A5498F914B243C135C8438E26859063201205901F45ECACDC37105ECA9606164D44A6EB2C9E26FD0017E7B6669C08BEFE43EA0F0A737D2A2F375B21E076BE884689477DE6507211BF8C34BD92D54738E7A41F33332B33E6655B66E4EBF48E415F6D6724272A232F85F59AA9B58F3B2E6F43DA613AF54872105FD116F4E24AB77DAA2D91994B45F89B7B79454A0FA77F1B369BFBBAA873D7DDE82562854CC987B45B3AA38B746F05E30301DE0B9E799B4976446D8D08469F00E9D64EE9D7A38854D9C9A6E6A747E77A9D2C526E6FF2678920B8F35C80BF488A87CE9053DDBF829E409A5375A4DFE0AFCB9D3D4CD8555E66E8FDE5438C234A579C631C7190D875EC6FAB628374018A31DB01795761401B45DE5744F86AD954474DD783B37E4942F5D90364DFE365A38F0566322743313F3E75299635E70B7C02EF7A1D36CAAAB4556C26AABC654E9BC194DE867C3DD89F8EFD710ED04AD115F5EF4E11BE33B67EC709DFE2D4ED3BB257624C463DBB5B24F0653ABF18736C6275E716A474F2E48271A5623F80F89EDFED811E5D0F807B3112B53D3E8D8BA71B7AE531A005B1A1BE3CBB87931E7DF937B2A78AEDC30E9543156074434F390BCD8DC83C43F7858750AC113F360DC1B73C7BC3D61BFEB2BA1D417E2A4774A166F3AE220417EA7DF29CC53ED50A1477EB003D3C00F95EEFBAD9D0EEA92AAC088AF47A94D847F79C5E43D999AA75728C9D80A0BEA59AC3407F1E41A0D46ADF15E51AB89A43056B1F578B31FD389C29936246266B7CA17706BBD0DC7678B26C199ED792E0D8488C5E79625018CD65564A77E6A9CD9838F066E431C312E17769875CAD6B77829E39D42A7A0AC220BFE22987D8FB3FABD9955F94965DCE2F5E534D87A1C2CE9962A6B346953651240A005E6D7A3919DDC1F34BF3AEDFF39FA895C842D33BC9B3C86636516F6ACD063FF512121E4F175F4E3F7C5E3449E6CACE385E05814F0B80831757A93C2C680F5682D0441892CB440BD50443F2EB3DDC6C76AFE8919D0DA754FA617F4BB3F07375AFD8BCC6D06E7249D6EABAE6F46226CF9FA61AAEDA3C85E16835E65556131B103B7CFD32FC1BDA2685951418FEE53FE2D0E13452E912F5E53812642DEEE6043C1390D8290D01EFBCD6E49C860BA552F993902277EA1A1C276005504FE5FAA377D4BAE7A41EEBF2EE689A7176E64D3627C8E01BECBE180629F63625D070697F6140F175CB4D61CFD527D3205BDDC38C2E5E3CA1C64C8F3023B172EBDC9C43B228E521584EC2319567DF0736A2262F1E4987981494AB775856D9E382B6A011B61F1FA4C14F4A063D725D5EB1059C3B10DD8108A689268B5A29780BB72499D758D70ED2548879F3223D410F098127179B3F8AFDEBB8C92E7E2E9F5BC3CA594752DAA602179E25524550D55CE8EC4B819B54CED54AAFB27231FF1FBE701CADF649B4CAAB181F786DCCB6B6F9448CCB080F47B58FB209B135B96B34A95A0F29AD629315205EAA1510BDCE86F3588E981FAEBC2476040B2A255917347FEF6BD984163360DC13BFA71642715CB6D75E3B06EF05823F827591236ADF211FD12EA3E9EDF7C33B95266BB4909EDA767B4312DDF1085E3E687E2A5210CAD2F1BFCBBF9D1098D4843B16597D914F2D17807D4743ED9530FBFE3010D834A552146A928B5142C427131EE73E8C1AEF179E70A05B1214BEFC391287E1D2F63F8FF12A5440129FD97B11FB4263CB92E54DACBB6B692CFC93ABA5D281DA468B81A607EED89B02312607648D35767DD52A031FDDC3787660DC772A3B1CD888AE7775E10A483AB1815C6CC07F7C4D959594B2B81010153D242AC9E9E77A4CD4A14A6F2E2A193EF320AD28F718745E3B68B32B97492D1D690C7494430F24EBF7DB4F1F18F94546DAAEB9CF43A2695D420582EA5413A57E2E03C6A276CF2A6E65CAE1D338E3945BCE4477BB8A702F584EB5DFC68EEAA082950878AD334F63FB91107D7763651622179C732B067E1C31B8A48559CB70FF7C31A7BA0A75671882D8831A925289E394C8CBF0AB0D001ACDA20D010CF4FDE387995D4151EB77309B7A6B6A1BDAB20113803046A48AE6D94F0C5CCEEE406315B4CA43D5418777E3C76DDA4F2E7C7A987977107E26F15238220BEB5EC511E749A6296C81DB3442C6E404E085232FF5B412357081251321337770C376F6919FE30C25EEEC062CA4EBE571D81B2A8E5E531971B7EA917C739B81658BD70F00A7A0F19C2CFBA5F2880CF9A311E4E67B3C54C0652D0834C3CA7924DCD9B82AB4A4B3B2FCF87409E547FAF41F40B95D7310CA5ED638E1CBCEDEE449934B222F189D19A653D9FFF4C567EFB366D614AEB8B4B885E401285154BCFD9D3207F166962C25475184B432837E698C4E4F6E7683485291B1E24A0D8A7F3316425BEA502F4DC9D9B4ED205699C92BAD86AB07D6F94A07D9DFF43F6AB0048942DAD6007DCC146DFF6B54DF61A21C77DC01E1F5C06E8B0C72C72DE39ED01F215F7C2A4D8DC15EDF2C26A7D5EF41876DCA11690032A756CB240AEBF823052E450415A957970947536D08A4481FE2D59507CC1A875F3DB2A1503CAB2E10D47AE301B86EE4872DBB814CBF04A536771EE820590434D066CBA98F05E04F067C12C5E04215CD68260383BDCC210C6CF84518BD630C2690193D69BEA8EE69ED4B1743B5F9E9AF874B37B6890E6A0A7DD660F4701E726D323A77A324F80CBF3800AC10A4CEC4AE1C67C65F5AA31E141DC3B4BEA82333F8A75417BDBB8590BAFC66384574DE632740E5DD2B393A4DAD98AA275D14751B7E0CDD81A651403F6B8BE9ADB0B5E6B1E02EAF0A6C0D9AD0CB7D2A3044872B124CC826834427951C48AF0C81488C046F7668528C7F53A322A9285C93F9B2E15D1A988B213827BC607FA79F6136D4A17BA580D4F16ACECFFF037B8C692B32818F5943479121189D2C8BF01674172B7A709E798FB5D903BBF93827887328865FBB40F247EC85D953714315EE33DA40BD74C0BD805E0C3A180FB5D039493730698178BEA7E4E7B1DDF9017835D8F00D5AB81B9F4C81199C5672E54F0FB9A81004F4E7C3FDD51F5852F72ED8F7003718178657A1688200375E419B47021221F6C0DFE0670DB8D6A9094C9D74A1C335E394809ADB6C101CB7A6FF49B894BCAC5AF8F5B866AB8BD50213A2D43F4FB1606AB30642546D071F38AE5DBFC348A8C8B9B606D493FB6A4B0E3833A52CE308C5E0E659292DD69BAFCC5FC8BD480A53306E9CB8CE71FFA1EB96791A18DBC6FB1DE53A3CD50E70225D1E5A386226F3A83D0630DEB8BC954DFA6569FDA606C51150D741B017BEC309E7B6BAB57367DE8CE7526F19C2FE78BBD4091E7419BBF7CFD94606B6C89FC9ACFA3D8D9E1A404CD93CE933A45A920AED24562CBEDB34D3C117361E7ECFF847D61BD8B46E351569B2561BA7EF25E4C9B2BF562A0A97B1105B8664F6F5408D4109632F23862267867E41CE805A1CAB1226CBE7535D1C7A155D03F3885BB1077E8013EB8B685291CF3355FDBD2F1DB43FD6D8E33320BEC59C6C7AB34FFAACDB152CC01899713AA5B6EC98743F8BEBE45A095B0C67F1FCA064C6727A509C79F2FD46F91972D17B52A192186F7F1E6E58654EE8585D2DAEA8CAE2E8900C598A8AB10B56D66A34020D291F21A8A41AFAC85BB5FB10F10B991F772CBA37F7786DE37172ACFA8EBE6C57DCE0A8DF0C44FA5968E2295B5154922C142CA5E2B7B45CD102D33C260D6CCF0DFEF41C26070", + "message": "78A2B7A4C8441C36E0A9831F65D41773FE6B81B3FA6259A320AB03D460D7E38F4AAB2B93C6142FB0F9584E4D47074670B07F3CC4513675A4367EB8F7F4168F2EF7CA26AC45C8F23B2FD3E970068F21D9A3F7EAF005DB5A7157715CB94F5E83E3C955DD68E0EA689B6F419FACA7CD159237085678FA5883D5330796AD64627CCE7F913D1C2259E1F970E44988B08E78ED1EC01CCC2D0274067100C1C1E3D880B9CA4F3A1FBB345354D4837A6E5FF4D5F5C87985E51C471EB9B0F85075ADB57DEB53A87D85834167A4A538134CBC24FEC2756F7760C3D46248D5BD6022D8F88CE7D037935DB74A6440DA49B97E8FF376101B296E3A9D4D22E70634CFE88142EE5FB6A33F323519EBE3A915AEE5BB687DA4A5E264C657438B0F6AC977A22D0E56882F74E70D981CF37FF0C57D285D8CB07ED7FDF6D7CB1DD39EB0D84F2999DBA9273E0B716CE754A29CBA2FE32BE13BE8B9F2117DD7359494A0E0CE623AB9ADAFD3F15F644545A39055D42C6C5FBDB46D121308D649AF9B86A350B70F77A977C8268FA1E04F4EFBC2C95A2D72BC37E558F0460BB281D33F75D2AEB240086CEB8246E8A44416A5B31EC58AAA88246D355591BF7C622CBEB1CAD3B785026CC04C73E352DFF28D77186CA93870339E132D57B11F0154E0CED426DB31BB2E125C5635BD489B52C5E77593145D3100E48CFC8FE6975FC3F60ABC7FA4A4D9030A2CCADA3854BF9AA213EF11E2F85E9D4E79CBB434C65ADC378F8A7DE33E66B4F8588B73FA7F79AF4130554173975280879FBE0A59D25B969FC45AB20401CBF85463A83578E63D0C8324878F5CFAA191428E7EAE37BB17A18D0459378CFDD4C8C0B23B1429950F054DF5C67174E99AF9FCE6B0D8C98BAA9078D2CA87EB8A014995FB79F7F49D78F2674839E14C8F74588B45C28E4769C439A930B2A187764D87D71200E841263EBF74F7428EC554C12A7352FD3912D95C96E4BB1D325DECEAA9D6FE360DBAE7AB897ED467A300A8F4C6630F8E721F24860D1FBBCFEDAFBD94DC9B4237B91B243A01C41D5E98E67B52B4A8CDF0F1C985EC0EB85131F5E970A6DD6D4E1F525D9D94530157F70B333F5E50B1B95D569A012ABA959456AF773B59BC2891D745CC036D06238AF3F34081A20F00A831422CCF6E4593EB56CAA3B7DDF44B388CD54E5EF9E3FB8A260847BEA5EB5FF9665530A4F4B56726A4C5E669904A933AB1E56C020967FE61E72185D56B38B03D343302712FFC1DF9D857C6F744E3ABABDEB3F65628932D69C65FA112AE3F7D6ABD2B4C3CF572EDA73C959637D0C5C188343415E9A26E698170F8E31CA45A8E6E8E96BD066BDFDFF49C98C491149D61AA7C456D3DAE0C017A32B81CD5668A400127ABD4316F3DCEA171C3F6A3E99B398CCD4AA7E45BB51963C82C43398050B8923CAE2D4E2A2FF5232AC8F2C770C9A775F29C261E1C7DAF54F9FF606560F869638B666C90112B29F469C3620B0912622892A432EAB443F8A93E3E7953235EE78CD3FCDAD3F1391A2487DA621526EE92735284C347853D5F65395ECA2B50B0CFCBD988F99C86B5AC56ECB82813A93208096ACA04F22AC015CD9860889E9006DDAFEE0B472FF7FC3D5677EE089B0AF7C6C2FD5A322D60BED621B8F099C30C2344F453320B6FF405639CF764B101E1CDBD312495C2D4FB30E2FA7B3C345B9935BB28EFEA69C829EB57BF2E2E5E42B8515DED4C32F9C84C33DEBDFB345A4BC592CA56A769533FBA0A631D5D0E07DAEEDD2FD588FAEE648B6391422924D28D08B4CE36084C20E827E6E73A97852BDD7508E1CDC1630094C9D3A2C8517A25A244FBA388EC7DE2CFABF139888EB7372E2BE3BC4FC71788AC3CBBB3EA1CCBD9616E76F2CEB356C13257A8E5490F3C4F7DBEBF942BDB941937C956DFADAF3A78903B49C5DE34F5EDBF0E98E3E04E51021B686325955C14AA335427C4A116CFCB3B89349B1258B8E0E354F13F86C86E5E8EF8F57D7B7501C5D75B1D9615D942B04E1FAC4EACE0FA10E6DE9B9721EB0651EB3C9DE4C61EEAE7D7E17C0D699EBF7EEB122B8C1A599A2CDCBB9B665DD9A653698735D5572EC379ACC6A8470CD7CC8245F871C83E6FD92111F5128A9797AE802889E4362104775CDB69FCF37AAC22EE4532FD0B5ACFDC4DBD56D9CE8B9EE2A8B923F42FC512B54204CB971BBC9677EBC49D287A3F68A31DB8AA49D6477B287285B88AF298E68C6EAC3C73FDEC94F7062D204AB310686144168C155281627F78C883AFB49DA50C0F5139E2A0ACB9A9CEFCCA39C6F4F0F5356D2898A4F5DEA78FDD20B79662F4D066E73EA4069DCE6CAE300B3028F15C98801912A86E0CF34DF53F7F6E1868DAD92DF22A238C710F471596A49843D3E60E4C381F713C21C3910ACB1515E5E30252C94F040F00A9D1A08A4FCA329DFE190B5464521BBAA32932022BCC5E119A96DFC941965CDF3B739F53DA156553C6BCD72927B07CC3CC945FABE44B7348257A9FB41EF85AD5423304E016E74E03D5164D9F15838C3A4BFDC29C6B9F134054B53B29183A6A145CECACB3EAC7C18E31CB4BF78BC8FE60A3B8EF880CB6C1EFE7EFA8D77580CE200ED96713E32FF23B86CF532D8EFA2FFC8DB1A9E65A78EDC30090E3DC02475D84F8D9F2BBC48B114C9E4A01FA79C17FCACCAB1FD304C7F901942B9EF57C918588C9CCEF0DC5FCA7AC84ADAD547982EF9E855F6E88D02751E8E7B8B76C3796F94C9F7B7C6860042A3A33EFFA55AFE1B94C97D68B76DD240346355012F036DA9C7E025C3633CE867510D54CACD36D8638FAA8EE47D315FCA9D5AE4BEFD6150086DFC368DCE8DC623ADEAAA07287F9B291252628F1BDBA5FE6DE45129509651FB048D3A686FFAC5F2299AB0133FCDBEEE8445555F5C649598649678847FFFCE6E0DD9C4E75E2F6E77B1CEE3A1740A94E678C1191EF46FC4D9648887DE6277B11D4C242DC4A427AFAD5459BF213E0A20EC74EB0C210D0A922B9E690EFDCCC2C160E011AB94F709C174F22629969B6332738654A133E8A13EF7C914CE75ACA1C37DE05A84708DA741161EE4D23C025B405CDEBBAF9040A1CB7492294C381FD069C4622BE1EBB0113F25F4E1D5A415C121055CDE5616662599C2364481BCDD35F7E498E80D2350AD3B34C205C5EA73F1B923E6197E07C502BC6F4F4288EB46013BBACC49A5DEE5071ECAE62B192294E904BF3FD7BE08F0C43E3EC6E23A7F68115FEB285AD388A0F8FB94126EDC0331834179C1F10CA5EC54159FC256D7E0AB3129B22E5AA5D662C6A03C7D9A6D066400859EC2D5B091C37E35DE31365F5125793E7F653013C722045F7292C014123246D611A7FD59E9B09EF24221C7EAB249330C91BC9F4D3A223D9C2CBF7130C5C057961BE89894221AFB1EB27A4604BE310EE3C395E479D852CEBA4C2F74D4DF416C8836861BC13D0692863667AFF8EC89BB9194407222589E1C27B9D59AC49131765273228E79C2933445B83D07E48A789FD6E406064593EFBAC4FFEE64614C5AB34E5C2A717C50AFA79A96161203531C161E46D71F447FD28CE4AEEF197A3DCA6BCA306AF09086D6BDF35A861820C469A40958923BA824F3A95CCAF8531E930210BE46D66CF7156EA0728F3448292F47ECF20DAC7C5E78A2A0AD5215FF37594D37A2AF4778B15BB1B5C4E0A44AD5910B62CA3FAC5BCAA4CFF5BF97C8B8CB239126CA09E92492121C9E6977111E6E5248661AD122C87007318BD3D98ADDFA1B2CD60F12AD1E072643FCF82C630C2093CF4A75B2D3F809A0496727E04AD60F14CADC7331B23D9CBE28EEC92C68C97E597C2EBF99F2B", + "signature": "9DD91BA5CCF4431DF756B1D23F47C0CCF24F869A2935340E59CD015E04D6F524A0F40C05247F5C8E4E0EC6DC0237B948D25679FB1BEF9435F248A20B4C2449409FC6E7AB855DE8F42423C83192DFE5EAEAE504ED4A490BC1FA3A84E66EB522327AB8741605348BE8C74040FAAF4F4B63D17B2157C3B216F20774412B70ECB568968BCDA52B6D3823DA6126FCDAC3837395CB0A22A6F4C704828ACF0E0B48A29400973B9C3567A0B4C0453F875A3DC82ACDDA5106895EB2B7AC33CD2982B1407E0259EB05E0DF60EC4AFC471D9FF5A4FADBDFD82FDEC3A3832A8F2A0776D650620B1DC4BBA31CD1EA10A93AC38DA5E22D9A0BA83FDB8C8E0F1C5751A11866E5C3E7BE5FB2147D7F67FAE52278BB4FF1486CD3BBA2FCD0544C71C1A5717AAAF6D1BD279CD97530BB1BE3D692CEE23A0069138D1F7AEB88C6A7A136763C132CE5C6F036E703D91FD76F3BC200656B61912576CD729540616FC49754E3371624137E39346BCD74990099A20A32FC20E7C2A8E23A3C0B3FE200F0402B2F79B825B3636C4746A283DBA0072B8D77CFE67B9EBC45350FD96B6F8C94247F98B90645A06166029C4B8F44DC998C0FA8DC5A0915CBC0EC139DCF1C75FCC68FA18DC365A198F46FD5B6C6FB69C9CF6D57586A0586511A16E4E1F94474337D31F97AF17C49E2283BC610F65E3AAEA08FC8DBAAE8A7D5D9573C46EF3445E46207536F57B7D69D5D0B61FEC95C883288EBFDD33947145FBA259B9C2947F7B837113303CA88DB7E0B8945F0ED413658CB0B1A200991D28D69D138A096803D964F2BE8E4BA04705F5F7E8F805871B7CBA8953B24DAFB9C1E25C272430B7F514DFAFE7A5194186AD8FD464015E09BE097F257DAEEDBE5CAC479E517A011E7059CE0FF415B42524F7CFEB49A5EBC68B0A44E54AFD136CB6EE143A2C6E8001FFFCA92AA4EF2579DCC06BA93A921DC261003C6CFBBFE4A8FFE70442C5652137FFB849B383022702FBF3A6197E13996C323D385234089234634777A9CED6A9E97DE805E78FEE580BCE6EB074B1174952608E05EFA173EAE7E929DDDBDB68985040775946BD70223D404E427ECD91188AA0632BF107EFD0A7296C4E100DBDB8EAB415181A4C12B43BAF42EF14A6B6ED171CFF05F96F919C0A5AADF18CE68381571250E59630C0D0967CE8B90FC4E075F03CAFD851EC009630001034D81B1CF2CD864D6CE6B4741B056E1E3769C34E82296B4B856B8523E5372DECD8FF62E289EDEB8368280D74239FF203BD4EE9A1D05438BF325408E199D28980DC8D3847B412D0CA652E419DCE0C42ADB52E5F33691304C0CA16551A4224E9ABABCEC514E0D183230937ACAA3125688F7F47EF9FC7BAD92DAFEB157EF880DDCB4BD1E1F8AB5E88641B1C087EE49824C2EFE263F149D353DF8FDB8B784438E74A17180A66792E02D84F1E7BAD76DAE2C5EA63E76C31CDEF083524912C73430C21E2A8E04509621A612FDD5DAD1213424FDC2518D116E93795F726210AA627AFCCFA7CFE3E563C5B97E5B0C276001325A13211EDDBB19017A0E8F0DAB523B5ACDD88D4FBA45CEA00ABD38FCFB98910A3330438BE4944EDDF55C9F2A3AB31406A26392340BD9907F1CBFFF78B320B1F9DF7150B215401B65DD46EF1A5912EEDD90ADD53F43E44FA8AC1BF010BC5130DFE9229FC93F36E4121D0E2767A88591001408D60C8507AC3315C74B72AD9CA05CA4CE9B81DF98771693A6CA084F8FDA0BD556FBB15F76D179494892EEEA3F961EC47BFA0826CC936451E66224045C82ABF55875F02658C82AED63E486941D37144E1CF3386844E2CA24C469B4344775C0A59FD2CE6091F575A260260395C52B3CBB0E65F5C3C540A8F9F8438370B57435A1F2FB465C66797B0B03F874FDEA6700C0831A18A7B50AA7B18D424BFA9887B3AC955E97C80FE176DB27EFB6E8FF0BD4172EB49D984B12A210C30F5D4A6AA3B28460EF2A32F8AE7D057D76E7A111F8CB2116F266F3070EDA1BC98AA52BE181903C2882F4739DAA06C21B4031A732375FBF23BC51A4E9695118113723BB1BB1C351E8D72D9A847A434467B90ABA082556980B92A146BCD3E13D9BEE551C14863AEE87CB56F7002BFF857AC9BC5E2156CCCE21724DB781179564290392CB47CB3148844F3159246F39665B69CE6F52316D0AFDBECBF8BF2B2A5F9CE79821B2E7471E97748D190268E8BCBEFDADE82F3D5C8F75768269EC41A4648C5BC86B267E680156D41163BF787278F3BBD9BD2AD483CEEBB9624FE531F76906C12AD16D151FB4AD5F08BD277C2B55650A86C060D38EF3C54DBAE10B65345BDC4CAC61376A5D052ED0D930E6BD8E9F4C08F257AE7D2ED672E82DD8FEBE17CAE8F3829D353638B2B104D49B7A7E62DA46C642CC3646CCA36DAB8D9D65AF695BBFDBDEB65DC07FF7F6599D5CAA6BB1F6694A8FC62BB3479D1889B2663CE704F4099C99186D504C3651331CE06E627FAB29B1B254B159435AD6A8CB6A678F6CEFFFA7988512328D8D868CC439812FDC8C4BC7D086A1C6532A62AC517D0EDA6005C16EEC0C93BDD9223AF2CF5D3E272416DB60561DD0B106AD25B23E00232BE30B9EFB7C82F97DA6C564AF92E5E16227CBB94EBD50E06CC34A2D22C948EF264E5A1B4420A36AE83901C346792FF99829A40714454757FA1CB0D7681798102AA90BA5D37FE7C29C64B86005713711D5890279CB0844536C0F974A46802320C33431588E42CC0F35D5BAF2C828441538843B185C4D93F57BB90ED1261B980C6B33B121D5C8F1B87C2D05442C34AB56512F40B06D326F8F7EBC5FB29D06AD907E687856D558AB423C72CC3B85D683814824DFD9CF34B810861B4E33E41F15569159FD4C6622A6FC797CA97E8D0B0D2824B199A2EB5B6FF06976A92775FF8B66763C1A430DC452F0CA701357A00F3A7C1A29412F1C308EAC4896F55EAECEF88D89F6BCAF7A02714F68E8D412C591A2C5F11033F7FBD2F29A0DB8B4171AA8D4C7E4A708B9742B51F80DD6F9DBB7242EC438CABE48E39F1C12AD886B7750FEBC9C3C4CAE1F6D016C412EB6812815267590F94794C90FE793DB920A4C6C0ADA4E80D2B64B81F04084B65A8251076073A84C2B4B1209655847420223A0A87C7612CE67C1B9540C8ABE46A0EFA9312C0C1FE5AD3165B90E6973F0FF8DB7FEAFA2E01EFA3ACD58AABAA0DDFB30AE7AA819F5D5E9FF72402117FB8CD9BA3CCA0BD2B8F52AED5A435E1F705ACE8E18D60845B8F0B13C967C39AE8D1A6D1EF3BF875BC32B21839077DC0FDF2A4D02A0D1554C2128E55A370168D0698438B21D02DB8C3A5691712B439D4E51E5E31DB45148977A8B184AA5FB63F41C2EC48A7C9C64EDF88E6B480956D9B0A63FC1149D85966D045312A3BD3AF480FD4A3C3F09DCAAD041427B3355B4C1F072A6A12301A1F91880F16A3B3B425BF150E01C6F369C84655D6F167E94613C052D73ACDB2A04CBD4EDC141E9633568485603E5D0339743E030066AE49FE5AF1BC28CFD6F4053348FDF7356EDA04AD72F17376339FF0F7AF432EFE60F3B4325E7C692A79C5099C29405ACB84DC6C991F70E73E1F93B4DCF749B5776A8D5E4A34744192D48E6450B39FD74F162BDE7EAEE2DB13061547169B627F3209B4D06E2C0F71C8D05F64A6245C9097FB0931BB838DDE1F26A211C27710900DCED962114CD51646E5DE093C7B4A3D18FC99EDD501DE8EA5695DBB9581322F903BA408E74D859EF91CB1082EE68BBB997ABC44BAAD87C51A82FFBADB819743FD0D06341666624FD88EEE897168E2EE35CA6DC71FACD98E754B7AF4FEE2B77E4B49E718877C5EBA1706EED84049DBE7019FC42698BD5E0696732C61828FFF5D15DB72654595C2F2B90D12E79691B69F2EDA1C137D2E69E396AD1862F1625AFB9ABD111D495D8FF41CA4896D2A83AD8D00D49B15F1BF0D160AF3CDC637BA2E32015ACB2299A13FBF43D054B420CE97361CB38022C684B695C4164D0CEE286DD1E6E34C483BFB5F91049351762D9D2609580B64425C06084275AB7ED3C3CEB8863F713FCFC091F460DA2351D54CD4A59261BA01B3A0D5F97C04A4A598DD6BB45CDD6049F2BB52D68A9B219F6474751C655F404DB8F75DA6AAA2609BBAF77E7F67BF27D721517A7E128DC4180F0612EA7FFC343501E048BC030A85089BD2F2542FFDDEF0F4B98B7A45376D9B33EC082C17C8815042C5DDC3DCE0CD64CCBD3E8AAF9AA70475E845E8FB4C0EDCDAE5CF67C2384737D602EE1CDCA0238E5F2F0D676E3C9564F9C1D4D9CCAA85BA8B1621C8E3161714256D6200A61642C1E3034A2E072E6D32FD941B87BAF22DD2715FDD8B50D0D366E20F1E9ABF312F989930145FB158D4A1CF607B507C1D3C43C6FA130F36B2355F24DDA2856149357AD1FB9D608E6F25C57B61CFE450EE9393042952AD2BB04EB4C1E7EC92A19BAF7FFAD5FB4CFAC804A0E18AC98AD1462E384DDE80F22E457FD9DDD58615FF9FB4A731F85B1510FD18FD30FFC74F56CCB569002B85AF3B593B4B117E6927E8475AE2C9406C383F686B8E79F22CC4DABA9759DDC9B1CC6BD91C13E451D5D30FFD1AD0D1BBF5F888AFC54783CF930DFF4EBFDEC0B1D0DEC4F781966BBAE1B9D0358F23BD5A83F0DC43699F30ABE458C7FD2E1B3B5B04DB570C598EA1C9FCC0BE0E607418FD5F2B375DDE950CC9E416868F0D582268632EA4F6777AFD49EFEBF7DF61B1F6AF5B8915A3DA8A4BD5D7501426AF0C99795BDE3D65317175FDD10BA8BA957824D45EC0B2653FFAB6BF4207798833D6CF875A87A181CE8B7188F09A69A8987C836EA923188D59B02C0CD2483B03654120794459B92228A8E029D149D6854DA86AA59C7C906F06E314C193C5BB1E94FFB4101B2AC1AD22F520F6E2D1B877E2CEF0CEE8FEEBBCEAC4DC6E66E270250FD77ACDE3E05EFAF41029645891521C0A471F268173EE36F5A6DCDA14D1F5D30CA8C2F772AD1CA92A5AD9C6B111793F38D62FD5734DD9148308344C5EF4D2D7F524576D3DE03543054FE8AB8E317660BC23513D4100FC1F3479984E1F8BD8D18F2097640A1CA2DE7956BA400AA5F06BD13AED8D54703029E7B927AF48A1FEB1317ACBC7DA9F3B0421611252ED708515FED233615C98943B9B1D4337EA182CEAB73B704C162812677B9F96B41922479DA97BBD7C83E6A588B0EA87B53FD80024877037FA98C058E3CCE7027A425957F87B0CEB5129DC8DE0D14461646864B7E69C862B9C4EB1C2240F35FCC0FEBB3E24F98A182737515BCC65A95E53ED42CD15FAE2F3329D61BB0CEB24FAA956A33F358C8E29BC610D02F1F9F3B92C5A6B2B4F1E00B3494DD37814CE79956CF2706BD3B1F92D6E262CFCA492FE20C2DE75D1B8C20CCA8146237536BAC89DBEC536F00B780A906BCAB0F3669CF0CEDEDF8314E3ED4811B2C8336A7CC94FE79D97E4B65CB6240820C88B785CA79D630C06E9575C9A2EF67B49A150B481BBC873BEC1F07769808953695AC1B4A2F971233C9506827E439C37040FD31FC49E76EFF585E9157F83798FF4C7CA1D95258BAB04AF860805C554D44584A478D3274E0C564594EED9343E3349370D30164EF7B2E2D104B7978E8CE758CE8C086D8F108BD3F925040552CAB65853B05A51B3510743B70F4120150E062773071EBA75E5DFC774CE13261DDF18FAA0A7741FCDBC1618D1874C8F7876B200F8A8E5158B65F8E015970B0C3C3283778DCED0E2FA6255BC5E0BF24CDA13F6A47CDF2452783C46209623A7C425DF9845EAD1E854BB810183512043A66046996C19AD1D89C1E32C1C3D9C697E7405E6CBC0E5642816F8D9C72E9DFD7222A6FEE81C9971657B6F06F9A0C8E9550CEBBC44C2593C60B1EC54E5DD2D93501FB9EE42B8CFD29DE790CB8A15A6BCA3F61163D39F186E771769D2B7BA9ED1DC0FEB03DEE86834038116C5B00D117B2EFC56C283436EDBE48A61C2C7DABF5DB3CC638F14D28AEDFF375AE638A3E05FD871D56D86413477BFB8D902DB263ED841367D29C4A95B03D758CE9F2E4781915755990A4C4D5CE8AF77376F7F2CD050CBE42BAA3DB923CD90665FACE9034087F56115858441C9E060B05542053324A0722FF12E6DFAC3330C12F20679466CCE4C4A24D7AC09A04302B95509A42F5538EFFD1BF3DBF1E9537614ED865CA9390854F286C243F2E7AA7311B40E5B3DD2208156B37FCE086CF064C41593BAC8C6B00DCF6386BED761551315BEA7F4E1600FA1FDD2D0B20B26613A312E1C03D82D3FEAA24D3B948730698C1342B4FE97B7085B192573FAA393BF62437C57362706B17B22ADF289BB31B32079C9D9DC9AA1E8FF63B25C8EEF97F13A628FA5CD151596E67AF80A4B1A71443501F6B6C8B6825F8AC7B5A6520F056D589E849949E93F0C2E52AE89CB81F3EB7C31388A56D15B25EAF35F9570379EDF4E8923B4F1C6666BF646DE202359CFA3C8E10434A5A8DC3DEFF104298B3C0FB507EA1B3C9D8F300617487C3E93CB6CAD5FF4D535E92CCD1D8E3000000000000000000000000000000000000000000000000000000000004060E141B21262E" + }, + { + "tcId": 46, + "deferred": false, + "sk": "CBCA46632F51931999369241A839BB7E57DA0237BC70ACEDE33B32FD3A66B20FB4EC73B8DF3E9EEB22782E3359A9CB10EB8CF52422CE70C71824C705B7862DDD926DD53A787E5B80EACCFC8BFA1BDCAECBBCC0F697558C85BF745C0741CE0C818A1A2159B5E2D645CFD5FD8A7914D64095C4B2EC86549121848871229F27D91D58847013928851224411090690A28493166A994460490891E4065221B98942B44C03850564C071C92472834244E086650B377010102924382922458601B224149085D44622D43231C3284010182DA2288C1AA10990082A542286D4042680400103196A019780D2A86DCC062AA422680B492854327123C36440180C61B070DBC02DD2300A644009A2922548262658200C14912994464813046D0842008B989144400511474DD4180598C67142B42880C62163C020143265C40241C21624DB420D03068A8A382448484DD0A40DD3924489306D09A52012856C1A4450113125412820421692D34012583481092912028684C094040136451C200C84B48C00932512190294A07108A388838064CBA88484022A13418299C48D5386848A4692188890233820DC88519B16469398000B046D10A45012B14D81A20454468E9C240ACCA028DC420611295102A4608A968DA2264E0C2931C13272614280A2A28C9A285288B40150A28118024919970814A7110891680A8644E048921BC68DE3C04923C261DCC00822C08840A030134972802844D3920C1C304620012500C64DA33485134140A12406E1226022130648006022C309543491A20881498425804240C240640A456D04226112106983C22D53344C42902120048192B80020238D23022ED094901C33685B16500CC7440826720081481294200A9148C9C0050C13109130650924300B0889110461C3908481B06C22044AD1B63181021091362C54C60DE13691C106084146508182240B20020C416A53340A132822440026C92089C48660D4300962B0600A274100C664E4A084098788D11646E28010C0444924444ED32471C4A851D9300DCB884C81488A1B3025D8802464982411C42DCC022A5C38869284311A1610A2164A0483601C33510B336020180D4394441B07480A21104940321C28804A402A81C840C3106E12C8456288819C10654294715482082045892048461439864C068A0AC585E4148AE2B02424400288342052464C53064A84226C932850C2187061244182487011061180A668883649C22220D4982054420E1C070194C04814A72D9226268108810B03651A210ECAB44D0020026140122202308AA48D24B74C0986416388804C1871C8226624C249003971A0164401246002810DD4C4845C32701999919A90702297712348019318025AB429029785E4B4080A300954B80923434E232888909268DC92440CC525508680621069143989C4282E919248E298059C308564201208B520E43225524668488809C12868D928442193045140401903095AA84C8148288B224A04B369C4028452360043442A004800C40445CA304418181292320888C690C8284E20B101A310268A1490E2464DDB260609498E1930260BB58D5A3866A0C60D4998619BB06864300483226D194071D048520AC829D4903004246010258AD428860A320A10C3091C4661E3C0806428686480815A12024A4610C8360A9C2442909489140401190409142721D8020998128C5BC84DA29409A28271CA322DE226825B16080CA00912384E8C84891B3748C08848DB980D04A84808982C24A59094246C2113669B102611162A13C96890485220B96513394CD2A26CC9320D14952C0202651C3980A0B62C18988483242A623269C20202C8446A82062A0300255294880C18259A128618C6401A310684066D18430D88C06024416281C06000380622378D02096E83440621372E50C629E148819C882D03400C5C48301B0384221061921490D446858944110C2431144051CAB421198444CCB284538050A1006C23418C8896298C300C50A60C8820848CA2509CB43124356D0C21120A3749C2C06014B44844108A41146E1281045B32080181088400054230900B344E03A048C834450C3290CB88044BB6844800901C946D1192100C1600E2366AC04866504890C34892A31830118600528871CB26400C44684312665B380C19852010228C8B928D8B40308A900C03C90D1C036D1C2652922032030120928248EA7FD68A0C62DB31279B2CEADE3F558AE9E6AFD3849A6FDF95B9F0C219B6155FB29921A667B0130D8B21493847393DE153BD4ADEEA031270DB812F827F974A2CD6520E7BDB2ECD99916FDD5C439EEB41514044ED8F02361EDEEE74F03C183B6E3F3194FD522321188ABA2B3D8C7B6BB4B6F2473ABB3E5337BCA906E716A6DF660DD51B543F02D35CD9A78B9D58312F62AA96635B8B65844500413B3D52BAF6E671487E6D882ABB2473AA4F321CED5A1F57072AEA093A6D51EA0C701FA0B915B14D5EC6F16E4C559C85FA9DC465044097ECC21498E3D6F919D75F8C364BE6371753D2CAA90166BEB726118266D8D7C5C3AC81307E74C0F796E1B038F7660E770D1707F10EECC95694A2C17A6306F661855DAA243033E624D208268461860E39936BC6915A86CCEF098B4D687AE1C1B22BF476C2AB753C8F5F528C7F749749372AEABF9724FC7E3F554B483D10EB78F3099A7ADF6CC4CC03E4EF1B6D0219DECDF5AF99FFE4B2D4CD18BA98C2D62B93555A2989C753BAB1D4BF34A982A71E0B10328E165BFF69A18F494F5F40DD2AA52B23CE544F7FE4B5632A0FA4C879D221A84CED7E097DF3A17F4E4731F87EBAFA97428C0CF9B51200A0126ED983C6FCBBD52C64E109A809C1353C3ED3A214C07A29BD3047D0E69D00B8BDA5242BCEDE709961CE83D1112F19BFA1C6C68FBCBB1B3045FD681E3EE1AB7EA91BD5F501F2D9CA88F9E6E040516D1DD238ED79A84C3E4E8318427A41ECDEA73CA4E12E575403FE4BB9AC0CC9FD8A7A1877F09612B8C8746274117D7930A0DB55EB493907822208DD541CF3BDB71635BFA364B01F293A3439AA6DA458ABA62F063500D2222A6CFCA9E545BC61624E1097031219D61DBCBF8C8D32E345058DDAFCE284B23BE63B5F3AB979C35F4B5AAB9BE0CC37DCFECD168298B744C37D08CCC0DF515AFB01461ED24850BA5D84977D4352E0838EEB9ADA60BF0862971A83A0DE929C06F4A4513E3E01F93EDA9CA7408233ADEE110DD0E1270AD957A296F8842134178893D39C0AA07496EDDBEA015A1E8F42F4CCA571D1AAB376556156863FB00BF1F4B329964B98505B0FF71D39D35EAF9D23A8589188F872D555A55BC37E364C0BC41468130B2ABC8F43EC7F3C39BF0579692CB04DF4A29C4E71AC4921A79B7D722A005C226A4CEC49967AE22E2FED24CABA43D915522E59778BA66F5D2E3604AFBD076DCB7ADF9CE9CC26711EFB4EA190A6660F5F7BA77E2A165912E2AC8C6A4756B5A305EBB92F00294F771B75F1B005E7E042D4FE23EF90C564E385A6968B0A61CA8940E8C67ABFDB4B57F16FF6EAB60ABF48866479C6B891C5A7787AF18906B528F8CCA98EF2D1CBBB5516B95033CCB060B8C66FB1B0049AB88CA15776971FAD4903639A1B354923E13E1322DC220ECC967C581334F8FC2FD10B7B8EA6517427637FD2A967DE71C49F24ED2FF2A72A43CA839D8893472CFD453AD66864AA73C002875C4A09F631321485D3E8C3403406E2462030EDBCE21E7BADBEC4774CDFB7914DA8099E846D69C6A7D58451864F5205D1854EE420B2915B84A933DD381D9152E4FD6C0795CBB90F506A4234AC4128A4AE863D68B06DA74EE36BA3AF8A35B30AD5AC6CD7DC29C467A088CC733AA88055F2246B3370947687E2F6A825555C5E8C6B6577EC2C3A9777882BDEA26F8F8E1871E1664F702DA4B580DACF7DDCD6E29763F5737B000BA424528D197937EAB91CD31504D626A3C33ACA17757DC65C7311AFFC35731272B18AA49CD9452C7497958089FFD021A8D234F80CC693B286C12AF252C9B32C8884CAA75569DAB60F2E3A0CC8CC9ED8615FC67866B54E2762B69F3F81DB13B510208974897A62EF4192BDDC9A7B8AA27DA597C5BD59131195D2FF648F4D13DA5E25B2FE99F1604FAD38759DBFDEF52D8B5E93706C0BEBD16048A496C8A95609A4D370F131B3094C928F650311FFF864AC94F6A2AA18C7E203DEA188B9DBD20FA08EBDC4A2A59095CF7E64BD16F1BDCB44CEDF7409DFA209B1698E70F0EBE387DC40B45C47B621961A34BE1F53A7CD634A538740799A3CC17B69579B34168D1D7C601CCA733B4774F3BA611D38DC44D3A7FF829577304B76B3A2A3BB5A3AB0FCA3CEAE0C4E50B985C7A18CD37D517C4C53F91C8BAB32B90A4F157B09CF14A0536E01BC382C55DC83DC27289EA546326D7F7D91DF5F9145C4590D1A83494D2C3B29AF79844F0658B453A8C3E44EDA25198B108703584DFECC3686C0BABD1078E26FEA2292591054A5D9B555D4B056CA7536CB81F8F7D7B5A2B6028540E9CD21B2458F1B2A5572C373E31922408B26AB3D5184038A7CFD9B506AD4D3CDB5B6AC8DCBCF56332C042441C79B9CFB71D057303BFD6DC98AFA0B312B04EFB0ECC4479CC1A35D53C13ACE0D77C600D43BB79319ABEF7531FEEC9E42270DB58F8692A51E023614D8ABE7744E5B822DC883FFB7C11E2CF2B9CEF5A1E0EDD47688B653A0B2DCA55A7F46BC2355B0EF5981C1672D09A7A74B93E1A92C8D8797322E67492C2025D6EF89A2DAD153F261BD967D5D63A1285F134077FA25E1714108444F76F1212C11B4EE73E448256F93470A44D1E0F7D9941BA5689D3121A47546C6B40014397927720937C6FCB50D283BE16EF175BBA7E1759A1801CFAE26E2D00D0CCB9C155FA15D9D269A880A5B1A769FF4C74005407BD7CA73DD3DCD09F0E940B7D84A1876ECB65F0D712993B5F2EBB9BE0699F6C2F79DDFCCA8ABAC2C88B0A02BE72065AD98C017ACDB90FF3F90BBBCC7C8C34146272CFB36C2D04D073049AAB6BE66266046E975FCC31C6050BAB10243F774B75B12986F97BEB30E659B2EFCBD53001654BFFB603B6B9CFE03ECC41F1B46571688D33DF1932AD1B82DF9535D12FF964618A2F76C6FE4153D53264982466D1EA1101B3A4225387330289EF0ECE4F11A8F2CE5643DBA7089BC1482A754A000B53BA46DE6F55C13B4B4C858C0D494ED768DF9A366A2021157908D696FD95750AEF985D7A7A2C56766BFC1AF0DD3591A63068FA1C6E1BA9F13B0C08FCC71C6EE02C0A2AFAE2A9C7C35F0DCEDC5E9823F28D5C1BE4E1B656469C2551704DB934E9FE139C2E9897553424AD74D68AB31CDAD48ADAC6F0C89EAE8BFFC8C4CEFA2F0D09E2C96A134FC158CDCF62B1CDDBB072F62BA0930755C9759047553672FE03D21270CD5BFCFA6F30E9BB67CF9FA9D02F8A30C5B977BE4E52D71AAFE6D3D1223F73EC5481DA72491F7C906FF6642D9731B396C4F26BE506B23084421A527DCA74AFC6BE1F15084078DC1DF2D813AE5595F40A94C15A7FBBBF4EC05F0608B28F283E29F8E730268981DAF3AE4CFC111F57CAB46588F4E58EF2C1536B0629021D6A599648F8A5382EDE2A4452E9EF6F5A7A221D35E9C2BFA134D11D5C5DE65F5F0500A1DA11B0DC055D0C2C2789F14F8002A487478D1F989578AC6961E262A08B31D913042410A39C4F9F71D1E70C2B1951732346E79A0CBACB0D63FC4D78D45A0D17A2BFEA3B81A7F14E3C680B4B9B967447B95E0F4E06DEC7226BA245597D2A39FCE4D1CFAC9B204DF917CA3CB8F827AB9718EFA69DDE17458EF3B0C0FE1CC611955FBC64A436B77C33C28A690CDEA44E0EE82B346E2461C6A1A1DBA39A12FEC61A892CB27027C57C1F72CEF1F190ECCC686DDFC043CFB2FB0EA8CB280928139731D88DD257A7C5554EAB6279EA0D0B819595DFF68E1612B71304D007633EE49100823E90EB41211848ADC7A0821A4B3A9113383E8217F16C11B331867AEEA9CF4CBF8310F0EA0A477F5EE1B2CED3EEDC4D0B300BA19BB95E4455EBF195F5E12374D5B6FED2A0E5D6F98C2B187B03E6B4CBAC7C4B446BA02D057D20CB3FD80CE79CE0D74856834228FB07273F4FD4446B8350A8D7C8AA11C64B89329886FB1327253FA162E4757D9CE08968A5C31612328D24D881F8A9E81711C7778B26EBA4E93AB00F3AB996F3BFA79269BAF026F33F5D616A4B306A100BE5899609BEAFCDF981C9EFBDAB444AE7A5982BD925E6B82603B8F9388D7AF9474B8AD18348121AB3E5DF4E7A9151D91F7D724CB2D6AD60A2FEC17D29DF3DD2628D6022711E7D4EB486F90419E66EA2C1479BCD02D2543807ADB8D75226E8B7386CB4C4057590B466B4FF7A244759C5724910A7CD569DEA50E8520387BBFAC32DCED5575B6155BC66C82F6132A780AD670A8C91A6813C89DB6D900F17285DE4DDF110579FB1E28B323CFF7164961B014C82EC825B25AF70EDD5D0BF74331B8FAC3A69913D7030DC1A142FE2FDA1D4CC5C83A747024DE772BBFAEB89CDC880851020A9D4C5D03267CBF996691A7FC1399BF265E985BEDBC9BB5B79487B97E9BB2DA935579BC5AB555EF633F2FF85E51392FAEA07A664F329CD923D4460423BB6C74BD63A4AB0DB1E3BB7C0EFBDABDB95AF5727CD5DFF90878AF51EAA0648845AF99A2286479E7125F867B31B3166AF309102A05F60158A968484FE5F1C0275E67DA8A84AF33A1ECAC4D49DE5D925748FF1E7A5BB442DFA88E5A3797A10E4CB044EDECAD83324986DE44A5A3896FA6EC6C71C646C2B4431AF55A3C2F325C6A62460C7C9BE6235A503A2301333F0261D97AC6692BA5B9B8BA375149685F85A443FF8BCC240409B6A959C1045CAD6EDF0EE593F8C3FF535B46125E00EA4C4A96446BB3E261429BC6B656B401598BB83E365C438EF16C8CB2C25017", + "message": "B5CD00AE06396DEB95C9BE213BEA279AF0D10F1423B5A71854413E99F7216D9EAE76C8AB884545496559B14AC9A69801EE3FD2EEECCC557D7988F34B82D244461388C7D4EB16DAC3C0FCE0783321A1488DC16C3C688126754BB4C26308054545D2E46C6BEE26C25A7C3B701341A0323BEBFC50C718162B7FF3B6FAAE7156FE300F2219655D8D44DE89845393011A2B466233B907355467EC49C9F832044BDFCFCF722D6DE7946FA503861C80037549ECE8FFF95026CDA33C9000FACC334765A60456084A0614455C83E0D5D991F7ED43952B7A69F1E326D7BD33822CF1F286D85FAE78F0B8DE186368EB334CA56070122DEBBEB920C5547C46C1291E78AE48B72C7A39020A1A2E54E59A2E46606C99E652FADB39AAB25399B0830AE733FDFD973294B93F47C30D0824686C735E05FF51A95C1C76467A4BE6BA80C5182353BD510E8D4B60BD43436F7021B3F5980D1A769B2E3BF04E0C257EF577828B327E2AD85E0581787B9B7FE44D6B826BF8405D3D0BF8974D2B1C569006C7FC3D2891DAF38DAC36F64A256E337B660CA59D2B45F1B4AA1C0C72B78495FBCC9EE9CFFA4B5A101F973E3211E728040904B0B2515DA4B1CB3774EBEA1324EB6907324E733C7F17BEF6FAD0F6BCEC1F08F785DC6FFE02FFED5C0B7A631907196835EFFD0730FC8FE020B0545C920DD7B2D705F22D8D205804397F6FCC60386F4A576204949EF60DEAB269905707396CCCD8DA9B895270CB39839BFD3EE64149B0085B96FEDAAF8C738E449E585ADBA037BD560EAAE978A6ED61DF432B6A9C2E50C2EA33A8702A23E6848401F85E2C18C7C767DB15920C9B3B030728FD9511F8903DFC8572A3679F986CA1B684B3AAF489DCD93C622C6C4D475DD60F10C390873B09B5A352B6F5A104C90782E053F8121317EB8D1D4C0145E04E3B68446B69A0EF81097CC6BD0B756AF78963724D9C83C61B7B79647F0844867B605E2B60988D2D7AD07CD6BE2D8F904F0D269187C141AC67C9DCF9961BBFFDDF3BF34D9CC5781D1BEA348F49EA8FF7750F7F3E0624C16FAEFAF1D8B6A818AF5FC5C04E2504A0CF4C2DB54930EFA759A292A2AECA1EC3A08918513D95C44BD133657FF043318A17BE4A5DCAC54B87FF38869D017A4B14DEB60480AF1C5F19A9F87B94B8EFE0DF3F931CFADFFD7AA50AC86D9CAF6D434CC81E6ED123711E34B8295A446B554F6DD5350B44C614324D8727F1CE501743043DE6EA085DB5154AD8E30E114A02CDFC96BEB4F2718033B227CB8638BCF617C73BA4473851E62C8A287CC4F9C659190E60AEC468DE7EA8841E3CEF893F3DC79DDDD56B63102EAA5B2793711A0451EE1655C6768393F59CA6085866FB41541D9997C94BB56F6ED5D731585E7B25B1DC853830DE5DD75F66298BDBD2E505DCB3850F96CCE0D7274633234EE2FA1E2782DA3D6CD8F5DA2C3063A923DCB6A2F82614527CA2A88C1AF21025B88A08C3104C679175DE2CF00602B13E58FAC9376BECAE56A60A6A8F144F1C98C8FBDCDE6FBCA4ED13228FA77CBA5CE631BCDB368AD9219568777FB4397BB40485A9AB63E9E3FB343154108D8117CE25BEA30BC854A241745FC6C26AF0D64124AF10BE4BE01B8A3D842FD9CC4D805B2BE26F8B7BA0631443F48C7F74207F640B215E0DDC42B1954A1EAB2C68E63601DE3AE3EA54E16282BDED00FC7665A9E8B098BF034F5E950ECDC46CDD22210244F102E41E0930FDCB24AD6C72507E5AB6FCCD4D6B2A2703C358EC1B51AC87302A5F507BD01CA6B5FE04EA2A5322EDFAE8161965524C61956CD201C4BF2F01B54F008F5F4B6770D0622099CDBF94D6C41DAB4A5362D630B9BF9CE240ED08D698D1AABF29E60BA533697C3C830521314F13EECD95C7D2600E2A756AF19AD94D9EA39FEEF0E3EAB3EB401225C2E55B2F2A8D7D1A3AA77A38BF9BA31399F6E6458F3F21DE354BBECC2E29740FFF91FBB23E0F61D7E0698CBF82D439AFB018DC5F5011B7BE98993E8B655D83C666FC0CF84A532C7655365746FDB97874D62329B1EFDB0B0C8A46056A85B60E38AF8979FA4910D2D9CACC3B5C1E42049D04C44273953350E0F756081D2DF6429193768802577C381897BFE540BC036293643360C848A1AE388CD17781296A99AF0CF75F81D568D0648C8A15436BDCB16FD83287C6A54F88F2F75E6B28E1C5A3AC03501D6D723AC5EBF90517D194A596F7F95947CC169CFF2A65D2BC9B54CA6AA45BA9E901D4AAC81FFE9E62A479EEC5B3F9BFF24C69FF56EC52F1183B5AC48A5BAA90BF595990B6EBA5B1CB6D88511C7D0D165FDF2615351B0343918B966ED1CA0CEBF6956BD2CA599E18619E1A5930E47CAEA92B8E9647A0262A2B24E955040750E6C7B935982CB742EE756DB65B462F677AE09A7521B0D3A42C2E97890C47148618FA6089975F5D491F4D3F69EBCD54C2B53130698A1F4A47505194F675D68F2DDF5983B008E498AB4A25956CF724F5C1250D5F9C75F3DF9BAA696E300AA86FB4B9378EE18E79D015CDA55D6ABBF5B0BE819F9EE58B49656D3B112AD8FA6651A8905061A8E37760C3F2EBE6DA611BADD44268975B5000051BDF7158EE3DC200B47FBF8568C9F22719FBEFE5906444DE9300689BFA1AD167", + "signature": "B2E661C2BE985A4DAA72B12734EE09DE1C78621F91D7E247553F39BFBEF28BEEE7F11654775416E4694086B0A640960D1DF784E8F62E16FB831097DD07A1121B00251D35E4275ED3312C22B41CCE76851A48D9BB0C46A64243110A4CB759675CA7D1B724CFD94255F11EEAD5AD01C88F70E2CC02001D6F44357BFDC159C4CE44E042FB429CC7D32968C5CA8BEED69C6C3769BF2A83AF75A7831B76232BE271B33A43A8B69A91D23E762280E2880559392B4752D29BA296BCE607AEBC0771AA0A92A30B72282611A693E828D068B04C34EC01634488AA8D1862239015BC437A23807FC2BB1B27CB9EC45DB5BAF866858F1D69A3005D4D5F210E0C25092D658CA9224B49FB147CF891C5127FAB6674FECD864A1C26E4881803BA3F8E6394BA98D70330F5D1221DA1D1E966EDB682FE3BC4F7CECBF7326AF5EB7C582B085B4B7F603212C3C8C6E59524A09227DFA93A44D532650F617470D9D250689538ABC832F38503392A96B0E7BFA01323A85696F3E80AC0A860C685AB4E248CB646A107562008358B53842123593E5FCF233951D43D33B110FFE33EFDA0D4A0CCA3F112F94C85F967F0C6A0F7E20B6836664B70522F962C395971692B29F659F0418FF753BD862966D10E44B406F4CA1DB909FE01B6F9F1B60715360D4617E7C0FC4B37692707ECB68B50D38DEB8F40B8C304080D81B84F60D49B7E4EC50B02E36E063FE28BE9A23E6BF17693B8B5C909B5B136BCBC6A3832D53E83A29ED9F933A8BDC8E318BDCEFBC10113888C1CBF39464AE16E2B30FD7F94AE1A0FE8B965CA8DB4667BD41B52E497D60C31277AB70C19350B2C410AB302754BBF7C126C1C9C8C298927AB39E9B4A024C0F47691880E11C0F8F7D5710D480FBADE860D72F43D1C676118E3F83A76FD6CBC7093B7BC18F851CD93D81B0564D4BE4BD39135BA2ADDC6A6DA8AB8F7B15284794E935A339E234E8452F766DDAAA0532DDE46FE6E4C727856CC29D7E78FFEE115147769543175546B8A838A0F831CBE16BE864C733C63F37E6FBC1CE2A36123BED296103FFDCF8F3BC36A7775A9C17F69193DEE0ED7C1423FAF6AE7CD99EF943BA174A6262916B78F9516B0464E8BFBCF512B80340C489B9857798EEB539062F40E39AC8EA3649E787C0A87FC548F0CCB801AF8C2B2156FE3FF69BBD30574D8C11D887A98231B7C6F24C662A48329DBD3DD410A019715DBB61F72D14883FE891731975DBDE9BAD0C2A85FFD773297E399B55D78C3A2C25C27E4FD0BDBBABAD85EA6BD6A3EC8931E0130EE4D068ECAD5BDAB22865A537B3ED2312D1462EA6E36E14D5E49F742F2A232E5216FBBBB1802B5ED89E361CDC0D2FBEA4555A895FDDA03597F2B8966D147FA586BB53316DAC62568CC823447B24052680CF67D8BC8D6399F928781A682A8BDDDCFF8785163A3615809D1D10E14ADF471CB1D93052434CF9D98F9D0D849283079FE431B8114EE9292E52F49C9868A013F0403A20BE45A2E157803CAB01F9C93701402595BBC90132E9FFF845165C799443F8B38E360F660AABB901485569D2B0081D00978B8A1B059BE9E4E98EBC19B027592E453FCA390F7C9DA085255D6A7436C8F1A857C547545FF0130A9F1E6A1B2DCD1EB03F7CDEBF39CAC153817CB450E501A62A1B93C450FD18CA956659D17A31310D517A81DC62640D8102DF1F79794CB7C096B5E37C2AE352E0BAF1A17DC8794D597A258BEFC66F26131298FAAB9EBD6AE3FBFB6DAE24AD74496BD1F077ED87BD1728D1809E96F70AB8254A9B8E3D30432700BC61FB747141609D4B9057BED02338233EE71B26364DFB9492A08933A2D3392C6453D34F33940C54B956BED2C11D9D1C68DD135AFF9165F3F2C801E0FD1480EF0BF99B95C68773CD2D765C1ECF04E1CCF68E659FAC8CDC03B44B5376EC888A485F7F71EF2E24195D75016CA6A9229C2D0FEAAFCAEFE07C46D3DA5942A15AD5EDFA8FCAD9A46ECFEF23A31F342071DA70A138BF5AA5003B70FEE1C00514EE0A3A2D5988F5EC5C279D7BEF153844DEDED0222DB3EF8A4579AF641444ADEFA07AC6CF37F58513771B8C7E406585296A7A2B6649B2FC1619BADF31951AA902EE48D5A9AE8DFD14A160538FF861FF64BC8E577C6E77F79672BC0273549D14AE1895479F8941AB0BF3093C5C439591F8A4FA453A9784A1F76FB792732405F05A8660740D329F2F68CCB6167D12958CC58AD567746667048C696FFBA426D40027820C4C740E66666E50DFD07C0ED76DD4C2080FF1C29794D6F17570A1B9D3D9AEB90AD34626B94A08202289A6409145D820C962183C58CB0345B287BE9EA15C5C443CE113270ACD15A075399DEE56E95E4DB23EB19E87C3E29BEF00D00A5442E67A7EBC5E12A096090C6AB5576DB5BECC84B8000D382540F98C41EDFEEB99D3DAA561FFA0C7FD6CC16FBEB6C514B45A70B2358EF4A53268612BF022FCFA354A80697225BC2AB988322DF31640FDBD05EE154F7C79A89463B2BF0C218749A454CA38DC8B5D1105183B7108E64EF8DB8FDDFA6BEF048C14CE5620A456DA5CB576F0BFFE4FFEB8333A9211707F5617628C2459A2104F8D5FB7B9581EDDDA27AD3BDCAAA7D037A3F996EB765237CF1C42B090F3B0453DABF26F9C92DBA120BFB577350705736EE295BE77CF70A7D3CC6AD388A526CAAFBDEAF67614224B6363E14B3DFCF2B6F4A0E8E2A8947D64437FF0E90DB68DA40D87AE431C02E9BBC647814C60F3CE5BE422C2BF3AA8529B8D706A5F6C3512979BA6E54401F405E6A8097CD0156A8B9D4C434014C2BCCD0DEC4559A87ECA3CC06200D77C02718330CA621F4F1B58ED3493B9126482BC941CD34A5BDC4BC3268C780479453CDD932C421229246D9BEDAD0B734F8B4D06A3780155FE9A88DB8C540FBB8677DF962FD0E0E4C39197479A68E42D9AAF4D1A1F56071F994B1C0FB4B9E6D150220DA7FDA2205E4729FC5517DBE0BFD9256EC717F0CCCE43C2862957E8630C10061D36AD371629912E9C1FA2A01B45AE331508D42630B39E5DAB3F141DEA254F1C6EE0A934B4CEBC4FEDB5B1BF6EDAD35810B836AC2A76EA9233D12E39553D77D1AFA964F8B104C48BE49A65CAC8EB3C352EE1ACD5EE14127340D6747886FE47DCABC13CCCB3410BAC0F96C718CE69DAD106C3D6F3565781EFF03812306F65C82613DC032F10ACABCA0E560D5A673F427FB231362D46BD40BD0B811903C259C2622E893DC4B91F21787BF0FDB976C4A6286D799EFE8269F9E8DA6870C9CF1A3A29897AA5C9D2C75D7C9FB29E467DAFE12A414398C6CE08917BB2A322057FF7BACE20782256624C1B7DDCBEC3AC680429497E06C022578A7D8CFEE14D20122C955005C0C4D3851C3D9D009334EC9B036AD7E1B08CED43DF8D148D5F6C72BB87F52A458910B0829B2848D082E3AAED3251818F7991136BF2E9433E025DB193C2581D1BD438F180CAFFE618CA88E677D0798DDEE55C4CC1776DBAEEB564770567432D34BCBAF6BFABC62E75C714BC76EFB785A37F91446E338546B5A1CFD83BE448405705D7F86B2E56F10FD54E6B3A047EC215DEC3F787EAA157D317C309B37BBA666810167EDC9079A4303D7402B8ABDB03383EC7A37964AF35C3C18D7713F22CA9D278A3F49FFE6C7D158DD97FB23AF1F23916E88539DBF6176F76A4DBFE11CBE3F914880AD2EE49FCA530E483859BF41DA5E42F01B0503A39D9C7A8F0A86B3A8184D87AD5F5CDCAD88BDBFF3C66907E7A448CE0C98260507CE656DA3316186A19B902DF6D1EBC77693BBFAA8121F2D679394772A7A1D127BCC51B140867EE4DABFF35E303BCDE2493D5CD02D302833AC464E34EBF202542AD81F38855BFC1C369F25C1AE2B3DAB609461BF7870D68D2E96D78176C2875F0C277D2493F5653CBA632CF655125D01CF48E2773C67EA58AADB857EF6CB50614AC3D1925C016E9112F36A28E142DCB5F2C1CFECEE0B974D254C764EF65C496D9489F65C976ADEAB8A21C2FB447FD7568C7E7D76617C67C812DDE31108200E5FD20182A393F2E2D6970195F7EE3C57DCF6392755991951F5471E402F88AC6200023E4B9E4EB49AE838F2289039664EC744C544994EF66DB2B86B970D20317C8A853AE532FEB55C5B3C09239435E1024565FB50B0C91A9896B2369F9CABC190C3131BBDA5C8673BA8C748A5FC49EA8E671C424F39E0162A9E479C3C611B5F5940C297050122978FCFF573100FA891CFD64D9825319EE01086D12A81F1D10FE77C8422DEE9E518F37A74FD8D1AA0070C99647B758D7EB8648618EEBB22A2049BC18A6FD41D3D9F712448AC3322B4F9BA2330E61AAD6FB3048AED745198ACA0598A97DC5B7A8BCE9803E0A62E19A2F54BB2C3EF80472AA5E27EE039B7B4E722358A242BBE7874EABFC76FB3ACF9D7F00C7AE2BC5B841DE02A8388DC800855340CD4B0A861B4E7C04FC5F50DA66FD845BCE7CC8269D81D7FB5D4968566A7EB7C984F71B9B5CB3B1D5AB3D6669472E92CDFA16B2C6B5E67BEA9FC54ED393121BC887BF0B099BA46082DF688126891D06808D2F2905B4F1607182745975A5752D890C4023BAD18A5FF8B4A4FA529B4EBC1244D715F186440EB3EFD5B6930C58DEDCD071384A1519B73F2EEADCFAEC130FA6DD6A6F0233BD1FE25AE7CB268405457EE6507DED9202544E0B5ACCCC830180D4DDBFC65DB3E32C16FEF0C1CB73949C2FB02ADB9A22C5727F911D308B3389A520441D5B5A7CFCCBF1656E6CF5B4B1D10B638E3D84440BFC32E45A74C0D428FB9517D765166973D25EB5BE2A5385AA6335975A4C8F3E94421E7DE1DDDA6E9BE97857C70F8C339485B5A85245180A317302A2E58404A1DA5D5583A806E8A7C8CF766F29A816C25BFE9EB6DBC2567C0D1D4D971FD95B7CECE133B6CF6B98CCC6C18DDB84B4B23FEE7BBA2FA00EF32110AE0B525F39DA0B0A7DD8C7DBF2A7F8B3CC90420B5EBCDC46A2367D236BB993ECE7FB1059453D08DF84ED0E1CB17C357BCD681765F8A6126C36ED49ADA5C82273143906B8FF421EC0B4DF20E9012B896DC3EF63FEF1DD1ADC09C93FA301C906FCB38F28A36EB13B4CD4FF9A6AC5D2E146595236047005814048A31226CB80E2ED09DAD75F95D5981AAC594B8C2EEE9D02D9C7383CB7EF4108EFE0FA7BED68F3E4B0972F2FC78373D7FBDFA91BA0A1982D47A7E6FFCD7DFE17CB23EFDF20B10460676EACDA5D46EB5EE83BD48B77C4F4559C460FB78CC3D7EF8D3016DA618D1866B69A99882812BCD6F2E72C679D894C97465EEB5EDE357FC34597F2490EE3CA813237AE80C55C86AFDB734627D188819E56C884286B51C5609C027D9E410B5B7ABDF45E539FC23B71F9068DD1E51C6A1DC922CB90716862B2F60532F34ED97627B43EA6D6D6A770DDA98E53C9358767B364386B549DB2B91219F17632BB02DD407969CA28CD8412B7FC8455A9C028A63930786FE41FAA360D240005F915EDA9E68B559113AD23F66541EE22632ED38187D4BBF77C15CC9F873105A749711382E202B5B66E9DABD165F3B296CD2A712C82BCDF9C3F0B9DA1C9BC0A34D6E9EC01397008492BEF118B3771BBD5756B42817BE46166C4CD13C8BD6D9B75D73A147AAD5F4863D664CF84A84BFE465855D7F373FCCF6EA3CFCC0E28BD76E5A5EFD85EEADFB15E7AF47ECE44DA1367C90C30092271964FF524909B97D2592742832933A0B04DC59CF62387AE581A2D7E13756C1D93855B8839F7965A46D830A083036FF30E42FC5F32F9E0021F79DA5C62E16BB2BF0AAE7769270704676A9257F62B0956EA742D8A3D176188029358F90BD91373ECFEE5B46AA23373CE75627B0C45C9A4F15D07425B5C1C1E1A3882499F030775A3CC6B5E2C91F48DA0BCC98CBD74691D7513E3817798AC0AFDF0C6B349829DCA9B9742ED77B4EC779366979829555FEF4BCF7270328773C850BC9348542113EF19012168BEA1BA4C1F607FC941A1B9BAB11F89D5033FE873D302CE0AAA51BAF328F74448E70907C302690385BC3C5E32AB5DFCDD887294377CEC6E1BA90EBF9204C28DE77CA85C7E870C3C74B91DCBC88CB30D07847912100B081578CAAEDD44CF9F79736E91EF4F0D8C3555D347ECB2AD272607AFAC189D3F8AD3C7594A66F2614133658D9FEA2DF536F6A11AE1B2DA795EC55FEA5435761F7A2E8F76563AA346F00CEEEB41B0E5D43A99BBBA029988D792FCF7B9E085C1052D319B5ECFEA85E84D354B832D84E370880D0552AB9DD31822D29E6476873E22E98EBE74A14B72437F5EF7E36987E905722B781B451053DD5A5D3CCDCF5ED40BFF1AB4D43921DD019C1F41B0A9E75CF740B6646380DA9A1372C4771E29C4772F67F0EDBA8FFA3D907ABDCC881F5D76E68EB8124A45478E9B66B061CE302D1605B708224A7DDFD25709F4F28E803F0E9FB3E90739CB3BC84CC84621A19F4050C4E93CBE089A2ADC1CAD12894C1E1000B6C9495ADB0B1BDC6DEE4F21B20689FF0F70317181A475F61626E717EC7DC48555E63A23C494C5D5E5FE0F60000000000000000000000000000060C101D2330353D" + }, + { + "tcId": 47, + "deferred": false, + "sk": "8411ECF640CB9A3AA61EA95BB60D5A31B099D67046A1A1953EDA3CC207F8009EB1C0CA1A40A71137B98854F470CB52EF825FC9D08CCAB2A406388DD22421DBA0A99CCACA95CE95F9E32BEA8AB715A39A8271B7789699217B8452188F4AA078C4F481339C532A2C2DE5535CC7665237D357BF547A7A051B0E1F47270231F00029A1B204049189CCB20923322024468D5C086052461120334D4A06461BA9518C148922933190A460D9B4852107929220310B31061A284AC2122894A2300A048D1A9609E444319000269886681244841397006312056118219424602142868AB86489C2218C302EE3C2611A366DC1405093304221A24409B1901C20821A8624A12800913430C816860B49614A44090AB84DD2B25100948CCB040442040911407108812909886C442082C22401CC2209E194484C263040082660422A03C08D12B90D91220220172820474981806020B27000018518C90C0A95051B224053A040233830123246C0908D990201C4426900954594A070E218112409251AC5908C2602830225D0487124B90D9C024689B08461146C62404D1B45440C886DA2080A9826895AA46980004E8A308E19032DD8C88511394549948101B225D330690B440C52862D12979048206A0C041163C808D8A60189B0691A858118882511158E0337108B200D82B229E184718304300B298A00A4610A1522091748D13006DA262560342E133461A2182A12B885502810989408C3941118A10D0A102A91162849906924348AD9C441A004010CA521E10610110968DAB28D08A801C4A24421C37122B570D394710BA700A1962194886D0A1802A2240C10900910A57020A86D6130918A04290B474020C6288490204B4648518420CAC404D186440A257010460282A6101A0166534804E1A04CC2423208C54148C07080160093B220083382584440D490648234868C04309244628120620A154198122803340520084AE4122D189349149565A4C8015B184299800502A330600486DC026C8A488184085103298188928DA2480D624065213371C0088699822CA332920402821244649A4260100131A34040C3B8291B130142801022C2200CB131142885E390858C24664834451CA231CB1408232506D0982DCA166A1A982950C26D128065C2306824174414496400B36CC9022A0C1704531225E32808C114021B18049C340D44488904302D4A242E1036325B34104B401044A8881080290AB16C1C9871C44606CCC81042268062248058B08024476189A43020C67093042C94986523496689C481A1446EA3866C5B46325236509BC28C23248622B39120228D13040E98B28519B02D1440681A230E03C92D521829003170D410441CB760C132490385305412058336021394911815204A106A6218259A883143064C839028D9B06C42482E4C286CE4C88018148D4B06514B8280DBC67001A8280A394908B86DC106451C0866C892091024521408621A27901200691249658B4852C1140E24488ED4446CE096715A347241800964884D53A4708A36890CB964244391082305098325A0000652965010054DC93671C1B0444338824C42914C16901A314101014212232A09882C9826300189440293312484281B8525A3468448141081A065043169811872910402A4364C5B348821354982209083C02123942943282043A8092437881B454D48880840122521004A93367012840D14A0055A188A43168601828C11352C04312A00046409054D1816300A0849A2B67124128410B545DA228DDA380E44B44C61002452A46CD406122484604B148480428EE14400DCB288C200915C141011334151980158084ED1887058B02904810544C84449B6881005310C132DD2145114008959282D63404204042A84160D9C1245481091A4482D9A1032E1883101302E14120409B25109B084E486600B4429D4A88003932CD822001CA721DC8680921849D80242021844204601CB2090C43428C314500B18090B9061424426CB288DCCB845839431C010304124319C304ED4C82CE3440E24427201230D23C80524216C8CA48D528669C2060808140A0098201B13684218655C381004C31121B5715B242EA216698B1040530490030441A4164DCB483049286860200DC84412030324CA060D242202DC3082132511119411DA36905224468C286421C3505324859A462A13C72C403272DC9260508240D20624E833A3104705DC227A3AD315484B9EC824A82F500712D61D5693BEB0E024505429B4D136758D53F67E6A5C66C247B3D03D763B77C17CA1632E2B0FEA3CBAD528695E70753FB16A0727C6031DA837CE9D9F7AE12A7F091E8E246CFAE2955424255667155384E6BE2A03689BFCA5E1C58C7F16187AFADB4CE28E2F9432F2419173A4CCB0154D7F3443A15DA2687E608C02D6392EE3942159C2996700070C00A194D27BCB61945E04A94E95F60709E59DD49CE955044CADEDA9EE37FC28ED3F3EF89FB5F03B77C6EFE685706B85A1ED1E810195507A55023A2D1CF2A0A9E78801DE90E1C7B80133B0A7AA8E17C022B574B3D9503EC2E152A4C04564C9CD4F84B8B8342359EDC28A7578F5AA73F5A480DAF80F9831E3A1C102BFE8DCCDC4621AE89409FCF986B53DF21425C9CE4C9744B65F706AD99B975E9907F2C8B5228E072241CC1C25111F5455FDCDE4D72A28402C2DBE6D730F588387E7265DF3E8B3B6C78E0AC3A5A2839F1E2E021843BD0BFF9C71C47A0BB0DE3AEB0E99845821B10949EA2C72447C64BFAA143220156FB54C9A62F6EAD3D534CA9568457277AB8EBA9E8EE5F3F42849C8E661AF178461663FFBE17F78D41C830F3342EF799F97C6B0E848A96C4606F4B404C382F5CE9B36E3CE90361C4E8A7665736E0C5ABD625BC4E1D1F3FAF90A366E3D3D9606C8FDBFDEE49DF2CED8FA268E6CA4CE20E3F4C962CF85E37BCA06F6385072280E5F5533711B2E676946813083FEC5D6E2CDCE4F4DA6F58A6BAA13FB159C6D8F33B6FA8ECDC0E792F72F64766027DE385C3060F38466BD93C8ED981CD3F7EF7B81FB78D76E6BBFDD565DCE1B018372102D0BB8537C1E60B1BBB564D6D98E45108D45139C71A96AC788CA14F08837E200DC1F593A19337E518C18E40C4382ABCB486677804D44B31DAE664959D908C4611ECD2F657D46B72F009AFE3501AD50BC49AB94EA2CB36A07FBFE8E87D5337841BA123FD8AA72CC9A4AFF0235F4EC2B08796DB4878A9F3939834C324E4E0D37A9C5C59153811F21AB57B260E9E57441298EE7032C819DCC475236ADC4EBFC1C5B26778B7156C3D37667C8EBEA75477F3FAC495FFFE7651627C6C87EC7CDCB60A3692EF2AC72A8820225DA85A5161B4C7274DB3698F5F1A92E197F99689B8FF5970DAD8776550038EF55825E4E0C00CC148DAEFDE552BE9BE94C351069153A3148B30C1FD9E9FB6E962A9A8824A1FFF238395B61C422CF56013BEF428638F961BCA565E5F4BBED2831769EABDC0BB3F5729BA331CAF666DBCB7AA15463A4D0CBCB26132F598789C96314F5B51F34B9A0F48DE75DDA95E2D294589EF30D43E7C44CFA63865123DD3ED045038A8ED261007374D096A46758138B7E112A58482BC3F7B14A83B7CE7B5C219B8A16ABA3514E779DAD6BF06A3B530E6C2A2E5C81D1C6152A63AE3D1159F4BEEAF8D57F6670CB15091CA10200D7A76364D1A48582DF316B7C65FD0816096FE238360B291772F8EDDC6380465261108B53F3C7EEE33C5950C76A87ECC41E86432AC231966DAB8A0C1FF9FE593F98FE34625901CFDF163E113730232E98F00FBBFC068028CAA132F071A828BCFE78F52713DF0F7EF903D5EE10F272CA06EF94BB1AACEEE6A9B89D459B48A5D580B085E844AE3DD20B866796492B526FAC2028DECC362A7FF42CDF73A827E2EBC3712A15DDAE09EB26E57CE61211A7E108B8C588EDAAAA165C2AD916EE80162024A29B6546AC6CA73FA09EC898E93FC399ABFF13DE4E4DD22227105E207DB1C50855079FD96383B3BD50C32C3D1E37B8BDE972683453C3F9632749A84A93CB34CC130070E51FC0D00CF504D9FEB9A8F068D4A1D7AC648C8AE47DC54824A69506189861E6838A0B08E13A13FDEC95F9148F2610084E4BD56BAA4E30B39862F86CA9600B9A3A945A7499F391879390419782D2934D45636013AF6B23A7E072B393E6F4E62140146AB55C9766B872050E085C152C79DFFE2240CAAE43FECE88B4C44791ABAC91635CD3BF47981B65215F36AFC2ED63F6A9F56AF736C2A0651A6C9208C3720C8D5F48A0B42C7ADC7F6161DEE6EB2AF5270612932F7ED33E2EDDDC61C4F3B291D42FD90D2F28B64D26863B07E5A2C445167C7EA3CA8E9D07FF0D44795903416110051D4DD9C481124A99ED2DBEA7F59C714AF50A15F6FE518277A3C9B17D71B4265BFD2ABE06FEE2E27109BE2E53D1D5C9D287B383FE32500148C5158CBC6932F6684B07FA33E122D1406A1E313C0F5A9901E82CE5224E31CCD04D31058B4BF53D2E15322C0C8EC177C6D15A250FBD3474EB9D255F548253505C979E65E671A6B7D1A60876254314F1329BFAA0E5E8BC8882F6BAA9D5442C38E0A5C15C2A61F92D2063385827CF052553A352922F9CB6C035D1CC5E15E2625FAAA6FFA2E4954F31CA10B18A3ACE08C122F826CB33F9D6995C12CEA96766CAFAE5F32A381958EDED4904C12EF43D66BFC7B08CE8FD61D42FA3F6F91ED1453AFFF2819559A385B932C484530D33BCB406BB87BAC9EB3F338D77B506CE59C6CD59CEA376ADE92B9D2587D8987FAEA9F0C707900BD649C5B81E0D46C17D467928A2CB9C53AAF0C55CF27FA09673BC6A6A031402126A163C4EDA10AFA09477F8ABECC81A49334B14CCFDE2FE4759EE15FF7D7D0D60111269ACA4ED68FAB56DE7B6F10CFE2C7A0E6DC968C8F90444D535AA34C1DCEA03C84F1DDC7C392868EB07289C4DE14CD53D5C7A1B768B312F6E238E2FA6B93BBF14FF286DA3DCF9CF95583917AADC02DDAE785299907BBCB06D559A04FE1DBCC75FEDAB0E42231F6225C9C5761E4F7603F87DDCA8AF1CA9424D36324659E2D249D7A83FC187B41434CB7FDB08F7AAD100DD2D29E66CF8188EFD1B3ACDE47B281BE8974C255FDA49CBD06E55596CF3E387430FC67F8FCC4B82101CFC11184B3E16E62F18A4355AC5C6F84BEFF3AFC12075B3BA48ADDA38CD6FBC04346EEA24AC60F2B527AE8F3B61EC32EDF64D273322326C2BDFD441BA40ED87852A0E8FD197A7E7E05117AAA639692C35CA5AC4DF9B590DABB9806122B31047AA33B30BA68CB405E539CF9927B6F942465DADB9F4F70218FA95565E2290FFCE4D77D122C1148E0AFACF3C1CF89AAF85DB4F06C48566166AAD370EFA52A95FDB52BF5E55FCF577D43B0C2C5DFCEBEE16BD4A0A426E84AB1FB018B6D701EF4981DE257E2D1096E206435DB0E52DDEC81CA2F8E16DEF12D411329A1B0CC3C3E5474F452D20C2EBE9B219DA00CA07B8FE5A14E56E8DA3EFEB1539EA9F2ED9C7474DB12B93C744322746AE42D777F22E1435D5B9C867F29C2BE6316A0941BAA39BCCAB41C9A7B5FB4C918F6BFA1FA76FF242A2514AB5E4A7B8D65CF15BD4336D151BB374D7906DBD3A187D02C4BDC33BF26448085F7D66ACED1BD6E8E67F4B3DA551CC68A4C493AE35AF18F7DB09133EC0692AB08D6DF34F1FBE23491467B5457BD831BE4F76830774BCA5131CD539F47FBC5E6F041B01EFB6A7E586A02742D50AFE17986A3AD7B20524F9C1D2825BEECC5A2AA757A299C46F852D46834EC67AA048832BB46D76C7D752150854B8689A5D0A501D419E5269E34C13464F37FEF2613BA45EAEF5083F7F699213121456E5AAD50722E8965B78843280DBD07CE3267912BA2FC59AED7540CB9C6B464B1F983892C34C1E2149ED712F8A56B2C6AEF7996D45A4AA3A6EA833D5DC471BF3E9A47E83572EBDAFA3D3DA7D930A05501F0C9B6EEE0FBC9CDF86190C52851AC7961C36688F8BC11A39251ED1E2F1528F98FA360CAFF6C1F2DEEBD712DC1EE31A4B5BC819AE169338E4DE7BAA00224CE4F460E25D2586BE63AF29705D98705840930E64EA0A9D7FFFFABA09869D78A0E3866A137A412AF4FD5A5E671B735FF456C79E24BEE529DC0706C065E0C6D8BE32535DBA578F36630E6C3EBC3C69B6FAB135A530B4281D40CEFF4FAFA364CA274CCFFE3F8D16DCC2AA7835C7F7E7A376E16ADFB940A2725B64EC782FC5F0C36E5F990807DB90E6D1C6869D6406A07CFC0B84A2A3C1A4E1585D854BDC2B506EC8427940299A9B19B2FE3116FD4A0BDEDE83EF42741262E7A9CF4393C2DD8A7E60297CB76157C861ADE284D44E73447186AC00B064B5E02568716565648CA88623E16EBB81C00D4377FDDE04259AD5CDB9C8FF75C4C8AC2D4F96485FBD353130548637235D100A646FADD5341927CCD114CD6095E97C622F02AADF7FB634879DD0614EF0ED2BECDB5A15F2B05100D97BFB128407FD8D54A6FB35DAF2B206DCB2634C2B14B33A96F7DEBC9925052B075340F48A096BCEB99E4A0DD1F9A35E8CC14EC724AC3ED3EB512E1CCFBDE1D755B1B3A3F63A66573946052022A89838A61DDC0D4E2A34F3C2067BC51AC14DB95DA6EB7C31505C7872620DB5C1B623A92C91B895A65EAE4938D3F823DF37FEF1964A71DFA1F6EE034F7C07772835CBB43465AFB6EF5BCAC326FADF26F762DEBE12432EDC8E53390EA89334E9BE32E535C5077D6E77684A1F51B1BE2F28BA4DFC42FDD63E88296262CF0C66220DB4A88169CA24B4F8F1135A50F9696C0ACBF3C2D3B345010E43230DD4F3044B2C39B91A242505EE5B2F690972FEA4526A3F473839763021A620830384645B9BBA9947BA6BAB37A1727DD94BA14AA9EF039023BBB46DE81337011DCC78B8BA6F9BF3F92EDBDF55B0F9C7B0942E397EEE1EC85719C4", + "message": "506462786389055DE2E4AA2A7C80388315711A7B5DCC73F2039DB99380D48D9A3DD8CC8B929B0AB224DAE74EA90808C302197EE9D847261DEFF4136D3B2A37CA32533384443B9D935AF2C384EA63E7160BF4BEB89EC0EE705D10C72F2F65A4E75ED2B1901F14B8C1D21DA9C6B8842DB62443D3DF12969CE4E45298FCFD6FB103B87B0817190C5ADED4D04E3BA4D2C3F60CC49FE0695D6366EACB9C79F28C9121584D997B7A3A7AC3243C3C75FC86AF81CC8B888E90095051F7825294CF7E1A11464BC153548F8195522FEAB9AF5AE93C5F6CF80D9ED76C19A0ED0BFBCFCDF30FF6EBD0E5C20EEEC4992765FD23F13F027E2261C38D11FD1631846142541ABCB82C0EABEE5D675EC130861F9BEE9D9E02305F168C85201DA1DA2E4D21CF1E4BB8C2539BC1F3706194AEE7E3ABB2D7447EA531619FD27F0CC7D09E5FBFFB0DA81432D173321C433391FEE90B92E8EE3F39ED492E78327D8A3586B7052602607EBA79CC9AF21132C7D3A9931D5DB4937FD5C5611F79C722E0CDC48564E416DD251C46C02567C4059A0DC2F59A124A4EBAEB9B1B04277CC47A9F345FF8AC3F8AC844A668AC6F7E1BF1C9889C3E42C1142CBC31A46EDE21CC84F230A483B5CE23A901375B27770BEC8F0AFA25F301B7AB43B714C6D0E98B009FCDDFB75C0E26EBEF7C9DF5ED04CB4183028DFADFC09963AA8CB3A9A1BDA047F62460F2B88FEE1C05D9E68D646137F660B68470308225FFC097474B2B2BC5D50A025724FB2CF70873BE7D04C05AFBF1D7DED56693AA4A4E495B1FAF9762DB83DDA6E75F530ED5351D171B7BD06E5ADF46DEAD06AEA37CF262AA33D062141F8E394E731B3942D084E583090F9CADF87C2B81C4B7F114D150C221A12393BAB92727B828C9EB86600B969E1B80F33E1304CEC68A1B3B474762175EA19A4D67220004FD4EB0B2C643B69C00FF3876E9AF63BBEF8AB6BBBE247668DA8F2E3CFD0B95D6926AA3A2CFF4587C45DA60BDB03DA78DDD9758FCF9926FA1F080A61FC0FC7660BDE9B4913C40534887B04E2DC666E981AEEE38746C52BF46FCE0E2233CE02C9307262499BE567C150CC54FB9D96B81D3A3E200EC8F7E87E28272E7B956600DD7692799473A8C63AEDBC8F3F43542B9E399398349B896BBA16E5F26210558DDFFB984FC924E1B0D272CB8834B1FF641A894EC113460C65C66BAE86248B48F675F1313EA76EB4DD0AB6EE41014FD7589D1A7DAB16CB8F113A3FBE7E01EC67B0B3CCD81C0A8C7E9824658C926736A574E9A0729C3BFCC34E0D4BCB1606E93287494577A6C4B1090FA6B997DA098C6CF555B5574473B1063B739CCD139C2541CC3F962EC42BFB3A40F4E64D322836EADA5F574B48B5722D7809A3A20EF1FDF5F3EBC000E466BC4CA10E0CC6A1390FDF159BCF0182293D9C408A8570789C485DBB977642074C869960E9648641C2A80D8A1C4E474FB98D7A3DD75D7AF01D2605945E89493699EB53E30EBB0F936B63ADF5859D9EA1DCAC44D0BCDBF2A069982BE907F1B560AD8327BAE013FBFE6E2709C9FDD498491F1D8603F9F6C9B1A643F6FAB97DCA752D9BDA1DD6BDBF52B03ED7768D98E46092D556C266E30C77A10E68AF76AC3D359D8752E2453B2E75DFECE6F66E6AB00EF37DA6E6A367FC808E1F4905339F4FA73545D13DA7E7DE49CC0A2A63639A96EA039C4EB643627B7EC4FACA1374EA800A505A80F554B3AB3233FA492ED6C17B5832BDEFB3A99FF1C64B35F1531A023415290124EEE2C9A7E34FE8563528B6A4B64DE425A8FFA91B753973CF0C96FB2A8A3F71D58B77C93C5866DF5CB5152B3A0A32884E349C63870E9CACA82F121EC2ACAD7B6052B0D74E9C28B20C76A7A821D192E11B59A7C8059FC49662C655551A7356046D46FCCCEB4DE1F5FC91F35B950F630D743C8218A10AB25D2FAC25308225540FC24CA794EF171DAD7258C2B7FCF43297F6E77A6E83184114DBDBE408EB644ECF49E04FD79769E4FE9B0530F21F8E3913A51094D0E49DF012144EFEC415B8B2A34AE2462607E7B89BB86F0C733A5553CAAFF9B19E0799A1901657BF4FF5AD6DA7886B477358E90D56BEAC6A963E0669C38EF47173503B0E9255AF1F153E673813053A899418E2BF217D01D9162C073F256CEDB73DC062D201FF6056180A8A6887B286AD6D3BD6B1462231D6223D0DF2BBB7299FA6FEFAA9A297C56ACA28E163533406141EB2E65F0C94A6286A0579C76A3A8EF96DDDAC9DC6A550538AD345FC4AABEBAC04682D4AB0977D439CB14F02FB504E10252C1F3ED01A7C4BFDA6E689D842D9B9086517A84AA4257D1C8CB842E15DFA615D2E3F2464E4012C0067EEE60489C044F43050E5B1AB3E54507422E1368CB3EC8CFB03A887DDF9695AD95378F875F14F7DEECFA54A775C60C6B7025E5D6C0563E0E76C05C93E33C3E5AB6D1E1C051B52D2805D3BE0A4D3E8F0DCE6BBA1DF04C7F76F7E13D8C3CFCB2AB04A1E605D4DAD72A43D5223FCC36EFB34D999095E742FB9DD7B69A28E070FD28138B403DF1DCA75E00A160ECE9562C92091DFD3A24C53645DED8E17B39D8CCA4C20C96F9C9F9D14AD3B45A1E87DA75B831D400AC14BF34A9840936C3277A135BC0E8C65E0F5E670AC912FA586FBB4E149B09F64D338C8C886BA65730039B5DCD0DCAD9D6EF11C228213438A1489F4FDC39395E8447212599BEB570D186883E02B442F8BF97884EF98D3D6E59254B3DDB77DEB8429D110F0689715F3E0A4F65908E5EEC867AC7BBF27CFB965727AF0A1EF37B21EC18CD60A1C87287527BCBF5249596083069315699CAD10FFEB2D87810C4DA090074FB26978E56B7D06186C48BFA4830A0BFCEF8FC7B95E73F64EFF78043E8D93F57EF6DC636C8FF612ED22FB21174EDAA59BCF89D1A60F0E1C15C5F8EB8E6A39139D500E8F28A5DB86C125C6C76A99BC47DAF66E679121557D85F5093806B748B3EA65CAC386B59C0A372AF2FB7C84111F0E0FA2C71E137958239534C4A012B1B421435B7BB8CA577DCD8C8B0A798902BAC9B95AB87B6A0735D1839DEE336996C2357C748F4EDAD858C81E2115595ADBC173782E36D4E720A5D29A5681231F9BEE91D455554A8632F7F02FAFAC0FD9D03804B10DDF4828A69AC1CF0581D2C88877BA30EF2982E0827147766F8B71E264E82C3949BB87562F810DE835CCF78A7E5FAB219E64B1FC615E7C952577B9B482F78C0D0C512833994895A125F43EFF066CEE293004E9E0E5288A61EF209EC52233EC64BC0DE76C78EB2678559724FBC05BB5B43CDBE86F6C481AF3BDA11EBFC0FB384AE00F4ABC212B0518644638F01C38030DD05FB06A7EDC6406CA18878DF38ACE8E974123D3699613ED46673BD04ED51C352F124A8F89DF8C13D2B44245084B7FA02677D5287D22102AEF4A4A0AE046BB1C6D9FC9733AE5066C69A10589B0F33780622C1709F179D4E8857564804BF5C4D83E03484FDBD1CC4D71C6A2421AA59043DA85F0B51EF91FA5DF9555072278331BF3102F5147021662D135F3011FA48DDA7C97087F01B7F86D549F41E244AD7374C7C1F698801CEAD305026D17666435217799A4A5FD0ADDF9B8BF6E31E51B654E4D697554D5F574213CF579EFB1B11CB2C136FDB9EBC0DE4D16DC9DF43E17D88EE22EC88326F65875439066CB47E4C656A3AC59BD9A576D05ECAC5B3E7AB7B1A3C0C1C48807C06F1AE4881158D6BAE9620B08BBFFCB9940B6A6D04396014CFD54E93D863156D16F6F9C1556DB1E13E630326C8B681CAAD146F32B6977200B204B632F6CBCFB2BCE9670D89A9CE043E2004773913188608455FA715D1577E03826A2471EF0143DB3C39E03D890F0CBC85040D1675821D282822F80EAAEFF5CAA49699B68B89422D1BEDBC3041AE2A3D6D5205C72123991B21AFFB312F5EC8F96922EBB44D7A0F8ACC2E390F9E3FD82353276D73E85FEC904AE6319B140E5C54FD5B6F19D17E65DAC5EE270DB3E402534B0F408BB3C554D93BBD32B255D478F33BEDF4A192233294B320393D38284D7D9987708C019742F2FC023C041219FBFE2B603501629BDABB9C4223F5B751DB78C144CC50D3A35370EE563D6DDECFD6D715F08E14A00FC265D8433055083048396F1BD4E9F010EFB974D6102401B2FECD972C26008A4B94952EBC61C35DC846FF7B3E20DD9C6E033BF1185F35A5F02139068E1D4F30C4778FF87057F34CE1D2D40BB61423EC055BB57B56C502DB8D0685B0ADA42F9C52B590610CE2F8237F92B71B3AC2AB75D2E6ABBDBAA1E554D99CDB687B72DE98ED0FCD618AF5D2B0196F1D3C19DB77686F01228C3D1DAB1F171A56DF9311939CCED0F7B22A1B77F473E8DB65C0FD6E307B6F7A0F0FAD69E5C1F87D01EA4699F4D5DE39880CF2D8E910313AA6026C17941C41252C06687A085903A502048726AE8EDDD2D8918B71A19B807889B6C2E866FB818810F427D2A7B6CB137D94746A88BBF068EAD31216A5511A54D81031D36C8139776E0FE29EF7C8A5EAA730C3BBF05988BB892F699F72F098F2931F9B4DA17243404F64C311767A98547284063D44AE74735DD246B0C189DB322058198F1D176EAE6E076965CDE68DD0DF2B284D23B94BADAFB8650F21B148B9C990F7044A777F9BD229F7905B242CC2E267610A42A5C3185C64079DB340D86598C589F9A96F3741356BF3E6D2A811B6551850F917E07E5289A07382B8B506C510C9396DDA81DB336179EAC1F84DB9D0E7BF52B906E82FD132647A84A299BA202DEB338B79F976A8D257E246B2B1B60425161C72D534B04355B2665129AD8A44C09D73AF51DEE7043228EDB62B858399B5A4312DDD7ABDA09A846A60FDA8D0C00E0ECC364A6CA95643FAED93D44BC8BF1264FAFA6D98528CD3BD1BFA352BFE1FBCC202F44496FDAF9F9EC53007915EB67F9F8BFBC88D82100210CD471C48F5092AF4253302475F9E60C287F0A8549DA00538432A342814E1F6043BA4355D72268F6E84A43264EEC3CAC024DD6E79143EB502A58E6F8478AE985797F00A295E84A0F669BD9252A3AAC6B2AFACD7AD398DF546", + "signature": "C1023740D113A2AA12CAC8BC94DFF2FDD05E5A70F45818FE3113DA3D727C8F99F9268FB99F75F98D3F9487A4084175064A4C06548D37E8FB76ECAE0B8613BB804C9C04ABC54570FDDFA0C938A339F5134C5C37D7FAA2037118ABB9D1FBC522A334AFE43E529EF3DA76AEE24B27EDCF98430CBEDB46EFF55E9F53FA479F60C95ED0FCDC31666CF15AF8EB6D4B870BF0FBED290860ABF033C9743CC8544B02C8F85BEEA3817909B39D3D68049E6383EFF3677D2B94830073AAA44EF9B056FC1C316A2B9B94D347EC2A551F65F540068D6F787786BFE45EE254663D6B99DC1A8E32620451A839C9C7B6D637B993F2906287EC8A0F270EB23E99263510BBD7364561D56FA3E73D87F0C5632983B63C9915CA85A6C38970CD6EE1041E7307A797094EDEC1F84D947EE2E4542B3865237C60AC5125F7515C805730F07D2562D76EEB5DEED5E3AA000E38D00A64E754163A42CD2508E496E02F7FB7C1078AEB7D673680EF47EC7D8F1130E4D61F631D6B6D43244345322F3766F1E246DA51438C265F66BFAD6C20A4FA0A462395BF7408B14A0791C21BA5C307FD38414B2B8DE07D4B134342A9C12CF170D3DDBA18BE378D52963514ADE5F9EBE135D86F0AEEEDCCED7729E2AA25456CA85ACBD18BCB8B79E97DB56AD29D94BC295F1F89EB9D8E71FA14B1BCAA46B8035C4AA25D14DE7C35BB5A02CABEA4EDF9F090873906906F68A13396CD2124410EECADCF085D5925BF6308DDAC2242CE240893CA7054C4B4C19332F4ACA897BE8F998D83E82944DAB9D65125085176CF5CDBF60EEF8954428EA0ACCC6A7FBBBAA9DB34AE72B93BF5D3A709CE3CA346644D5FAFAF3FDBF9D9D7C504E86371E0DEC5B3E2EE120E064CBF4FCD455E99207549D27E233D06FCAE3699BD34D5D7F195509601154044EB3EAA0527DAB3F9BEDBB316023AD53FEB71249F0BCD3A08F0CDB9878403C1812D36883DC444089999FAF16A40B75679E2F053E6EA2B835DB463C1202050FAE236134BCC8703397E1CC344CA7901295D3AF28B39853758D086561AB9A6A9904BAEB37C2AF4D973B702850BF0FCB08CDC48D582238A0FA0AAADF832AE76420439BF29A9B32FDE6D67D3D6B25EEB521218B013AD3408AF36C466F67FC5722D4EB2E57D0E58D045D46592BB1FE907D56E0B378FF59DF68B2819D21BFC686364DFE074764DB8613DF0BD35A919048A2CFAFDED34CD3331124E8C5F8811D730803845C7CE568E66F9E50A1EE2DF92450321BA09AD2C4D75D1D92CACA21A2737672559B1B1894130472F40C177F1CEB1C348EE8AAD47B5D1ABFE148877C39A0A46B8F9E4D3FBEF95B774AB5D768FE130711A9DD9EA2B8F4DB4E7F938352772ECB46E9A00A9479C409A4F9E4526DC307BAF5C3A0493EC9E1816D11CE212E0054501D2CD9865F6E942856D32B971E83C81D94DA4F584B230491D2013E84C898386F55C8F224BB09FFE58CBD0D9E9D7E21BDC2AC4335E2FF94EC95CE2D509CFA5EE33BA848D75D046D8F576237417701A7B11B3E67BB9740B7BA3D7A37784E6CE081D3F41E8AF21CB46D46B083796A08721B7E80F0A157E86BE0F08D3125A12F4733F8C27236AA898E6E950BE190A931D07A08597633F5187767D3CFC095D1886769E1CBDF6C20FFE471E9396476660DCD21877D799A124A2F0251128F08F9D45AD45F0DF38FC9A42CBF4EC4BE10ED87FD86B63DFFC5246239517690696EE839A501EE221C16A153C0800E7D6B4385F6ACFBCDA62981CD22F06A12497B97D13C6EC1F39879B2432BFE6FC7CB3CFA78DEC8B3B800916CE777BE327641DEA9E7F156EF6E943161F78466C0300A29B1B5EE8CB68F532176DF4FCCF606738A95B3224573D5DC26F90DA69146BC8FA37D1917E3CF3336FE8D444B606979D9650B2649B1F016F6B9543E31C6E9F48594F538CBECE25C4EB8F78955BDC88EB9540BF7AA4AAF1E51DA958EA818A8DC9008FFAD91529B4D8AD5576EE1CB21216136A0C85BA87C01B8A0E8B9B31F7826537A0F920F335CE24053500CCC4EFDFE3742B9403ED950D61BB27FABD1E397BCD6CDF885DA0E3559B21197BE6FC71B25DAE1C4B51DB765C154E4F313A6EA4BD79144CDDEAA94AAA9AD40D0167C5779F022116E56154F74F42D67540D8D0988A5869FB30ED2EAEBC4B0D80E1A547551BFA5D77A695094162557B76D52472A1601884331C9A0EBE0405FA61E5F5B38278EE11A315B20633F534115C02114B24D07A343003E2730BC17BE1F4432B617D0BC160BC2249E7B87A4A4C0B8DA3C6F082C8D515DA2E90FEB30852FB35D2A19A0A39C4C44561703C97C0B660A05FDC553DBFB21271011BBA5D4ABD2C8B757BF022C6225D401A56A33C901961DC765626B1607443368D2BC37886EA65B35A9378923B9F6D2962B1DA2A4DB3250928E2DE09DDB7C2B6D27EFA33A21FBD7C3C38B6B193A1AEFCEEF9AF68FAB8F87D20E1FA1DE0AF8E40BD00AB5C88573F2FB1FAE76028EF40793EFB36D92091A353F6B044603711514C4E5288BDA0DFE9BB6E10BE6FF42705FAC7C05DF1E49C7C93B464C4F3571821378B3AB9BF020999B2421F6BDD98DCAE5F976EF507B9E0A02E1F7C7BCCEE1849403F2FA5851D8000AB7933AD568313771A436CDF40909360A33D83D42ED1D2D5DD1D1BF4AF704646DF4178D83B3031D9DEF090CC6271DF522FC4013E049D031DD504856D217E9E79F5359421EC1D3F77138F3E2CA07FC83FCF72066AD407C27A80D48A484285ADCB8114BB6D98CE6863428D3D378E5C1132E0139CF6DD841230AC0D5F0240C589FA66D6EF1380C9C2F5D9482C0E387DFDCF966EC364FC614CE707EDF8E16C783E22F8FF29A31791861F70B3DD487B4C72D5658D436FA5B3426CE337214E705489798753666B47CF8591B608A28871239BECF722BD726C0029DD7B8C72BB2F7D60CA8D2A8091749686B62BD642F55AEC9777AFA52BE3ABEE6FE5ED2258D6FA3A9A1B55B7A263287A8A52EFDAA0A817F410FE325B16A1BE3B70CCBC50EEC72A70C27CFEA321005FD982EC093D87286FE7A46822D640893334BFA932BB62AD41B4BC88D87EF1890C24907BCA4136C5BCCE546B5470038E5D70D177E7F33B0571FAEB48165F94AFF353CFD315C303CDE5098093BA39052FB1ADF904F1C117503C58A7A991F9FA1422190E0A4952374D624C7D9ADCEB0F124111000047CB5662EB71B6325528C72C1D82F0459A2BED71982CCF84DE2434A4A7DEF2C1210308DC1FAE705360DE9BBE42E9F9204044C99EFE50361BB84DB15657E3B85C7E7E4D298A34933FFB5754CE06B2CA1F6F7599790962B0E77641567AD3DFF95DAD0315DC6CBB3D29EBC8F3B68089140BA87063B21E45C3B1AD5DC6972A7A65C711301C05AB5E48F31F031EE939740EAB8CB8DE627445EC5219116D3A43FDDDD91A967A400F149399B9A82FC54C0D629A349C84085A3D30EFE9AC4381B7C8B24501BCE8F827F27CD507BE20018DFDC9343DC5282F61D74E4B4CBFEDFBE33A3CC67A210BE8E012C8277FB202608E96C355BFFD3B4FBBCECB65B7D4A61C1B9463A7F6F732B5F73A51B01596CC650EBAEC8DD40C7C3ECA3F95AC010DD275D6CB419BE78CC107B6D0DC2C060F57A8D7E4BCD53289CC57F5FE0B0831F93024148D60CB87201335F4DDEC3EAA0D749C04D08C345C0ED169DD4AF598169990CC2C8CA3986660712D615C084331030FEAA5078C0C28D3432E9B1DC5B4F48F508417D588A5CAB2DEF9DB601E0FB6975FA0E9D681C84AED7B5364E192F4847D1090924E6463E527B1185DEBFC376E0EF221D55D0DD556C6468E56D09609484391981DFAA3558CA8B35806E4CBF48489EBE0D23A9A035C52BCB4839DA20BCC6939463E4B03FBB7382E435B97C7A53A48183AAE0A8095D9E04D750535292E6F5293B5E75E6065510537DA2E919E2172D232586865070551EC02ACE7DB95E75D3B321CBC233D5D48B5EEED7E93D9FCFAA378DA92B704F9FF3C992DE34713BAFCC3C38D672194D314A3CCE47DF297C739CF7DB273EFA474D436CFE109BE692E1EA8786F703D81ED2928CA69F38F45D819B08FB8BF9213DDCB2AA24B9E50CE9421ADFF3FDA75A95E3948803FEA3AF80E59C7AECC594B2E11F35A37B9B9C684B5977E5A4A0F9DB7C89772DC17B2D2902DC6B409937934CAF22C27FC38EA4E35F2AA64D6193AB2B340B63201C82F91C20E4BB631D684321C0EED29925FFE916CCE3F403C6364F827497350274F12B405D8BDD2E9FA56F088117B1F682D98AF2A8BFAE4F4B3B1A0626632F55E747A40B1CDD8DF9665834BAA353413DF698C5AFA6AD56EB8AFA9EA22E6B042F6016F803201E974E8E1A19FB5DC9B6210C192196C97B2B4FC0FB24441A6CFF898691E948D0082DD19F72BE037BD4F48D553280708F41A7DF37C6C6130C9C02D540DB3F6CF1AF3E1878E57F267D08F4E761B5DDD7D0276726FA942328A4393A2AA9FC25F6F4B531CD5C32E92D1436DF8E1491283318445D4F0BC81830B3A1B016E02A885751C65044610D24771A9E5F72BB3B62AF913B923DD1FF09DDC7E5077F6B91B19B9E7D552372E81C05B34799814E839C4C62FD8F7A010073DFE851F273E1AD4516B4D8F8389951E47B10BE213B553C76F6BAD8F19EC88A8D6D098F7CACA69DE23B9BA40AE8862981F3DE150207A55FC474ED195A596D96C64FB3A6CE439A89F350FA24B93EC74D4AB8793AA28C3C7701B0E6A301B00C4B384B49CE713F439F853CF204CE46A330695D640F1243165AE0721E2499483E879636CD5C6126EFAF822A21A4BD77FC6B067345715D879F29B41D53B3CCE27C21B68B2A46D14D99B34AF1A6317439E52C8BC1F3A6A83B108381BB2EB80991A1EA80687D61ABAEC2895BFD9DCFBD45E3B34FCBD031446AEBDEA38179533EA7E3D15C579D3B485EDD7778105717DCB70A727A572A978DEA742C0BD05836497AD40A39BD5AA945C942512654884015B32B920EFCCE1EB74BE65B50FFB9FEE543C953A8D586B718746C4214F0544E66D60E6E78F8C3EF6FA35344E5147CF861AD2A928C451D00B35FB6FAC2CB3910F214FAEEFE59CFC099B8E020CEC68ED87957512BAB2CECFA9AE8D5244A6637CE8B2ECC60417D674C10665DE5DC64392E3E0E525CE8CE3877E9C0C9A34B2768AD41206C3E172671E9D89556013CC22BC06B74BE25C6856E89EED22D7D9BF8E3F6AD3B43D9BF966EC521BC6424A9F45E5D459B5D6370CE73312EB766BC89B2C283FB59FAD9F857FDD67F599D71E78827834AFE8CF5A002659CE0B4CC03609321C8398B651C6D1EEA2224A0E54B819C9C867116D5C7E00C588C38AFECBBF35CBF5894130F9FEA689D6389CE65D77B16DB62AE9B8E2E68AC9299AA3AF4DD65FB70F2DC3F01B1EDE3D75D61FF92F8FC3E0FCB6C2F3D06A401AA67C445CB80F045B9A7B79DE15BB997A5ADE3BCFFD8F70738E61415A252E91FEAD291303EDA176D9B9004A6107F8C0C4CC29AD478099BBDE92A5C95B35559065AFFE7B5A2D65E7A85E95FD79302B229EA40A516CA45D320DF15E7F835B0A1F05813A5706B6B73E50121758259DAA790DC21EBFC25C45934717792B46215088AC8CF99857FDB20D985C3DC1BF052F4183D895A55237C34B2F0893F091BBED221B68902A469CD505E6F3EC768823135666DBFAC1CCAD86C149D68BF8D86CF9EFD6007EBEEF7973F6DE09C298637C7FA4ADF1A2159B07425B1636DC4CCA613278CAAAC7B6071C8ADC69DE93DDEC276443C8B284B7A0BB8B38B648171A9066CB6A7F868B6204AEEFB10C26D3774DC290C39CF87E7E9B9FC164E4D52CF5E3F48381C0E9E606FD0B2EBEFF0888F94B3EDCF2414F9D922AC26C75894E61721C18B6C381CCFDB847419CDAB84F3FD033ADA263777F36E07C38EAB79C28ECD65C3623E25479E3E3CCC109F7AB3F1FC3FB2D3529D722AF9A14B3A1D553F009364EFC462B3629E077E918674DABB948CB879430010E829AB6072C25CE6FA44439173026D0487D6F89337C40CFA28D4131D4D107CD8A44D677CD5256CE7A18DB338DD8FDF2159B5F1AD1E980E76DC0FADF27A970449A5059F4BDD6BF1D16A22F11062974AD2F8B267AAC4A3F2F1607CBCD91D0B55895825016E6D721B51DAA94E49BA45C1EDA32610ACAA0E5DDCB146C72FE55964F7CF76ED809749741D6DD1894C083BFD787FAC25149C0D9F095A9383B0256A4680A81B4BC4E86997EA0051C8805456D572ECFAA60E868A58F05B6BE4DD28BA59E64143CBD7FDF75C33D545F2845DA1496DF3BDB3D76268648245C00D8B6272F1C4A986649DD66574BEC036588508519F4ED9FA08874AC1561F7A54BBE7E29DCABC1499FE71467CF0F278E792CA6942F145011BDCDB73C63541B0C9CB7B005EF6243349471EE711C2D086C3984FE00887A408015787522D0037FB7AA0774F946526DF6FC0D1925325B5E67AFDCFB113D42A1ADB854717283C9FB020306262F3C718B98BAC1CCEB0F535FA5B5C4D4FC03151D46556E7293ACD2161B336FA2AA0000000000000000000000050F151B28303A40" + }, + { + "tcId": 48, + "deferred": false, + "sk": "823FFC401BBCE83F04D9EC178826A5BB4894DBCEE86C43B44F2D9F93DEDF2A58F1FF2BD5F907D42D6C18DCFE32F644C301C36F572570E985327F49254E9F4138562EAB80024CD250525C4C7FAAB88132E1BF3141E5CE354AA95574F75C48FEB3B742B08859BB4462738E5EA9ADE997A97129059FB937F7C5CD57884AE12AD95DA11289A00206CB068663C804501851D834812226451B4912C126048C281192464850900C18B54024B08823C02552904101B8280139664840882410015C9620D98001D40252E44811089601E33410C2A60108120212108A9012919038655B2431422065229468E4306A9A988C543450C8284160C28109251191064DA3440DA0B0499C182550A891A1A24D1133681B16280343504A2248CB28106498098212322423604300299B0869D8B80414890C0417721B18920A05859B14884B0071C3126184048000190C8B244D001349C13688DC046D2139068432305832905C828D94466EC93446C9282D48A00C4248119B806CA1244D100861C9B640C4127124337201260C02A241C2029113962C1CC16C60284E0C382C23190D01A22520836552B291E022800B3442DA2066043152E12846442024C1404558204A0B974119132A0BC3294C38000B21525B140A2319221A428E40124444362248A27084A048934891E1088E41020842C45063146020C12104A1455C228909108221012E42C0250B0569E1C68193B84089B605C0B6081016810199101B28204B386D04874C14C14912419000A58419900CD410110499250992005484010447015B3248244771A046214914640B024D084140D10022A0404604C4002037441825059908641C310DA2C02D23436221A76419B3455B261103C64CD1824818C420618051A024485022064AC09108338E1A92454C986C88407011403120410541089019B38C5A3284C92045132452998468C3422211B6914CA2450BA95064380862168A54040E4984100CB78923444104364A04A9110207211A202922034D888830604049C3486150984518801092960C18B22D24828562188453443088C62DD2B041C1202204312A02270D0821095390440A475088988121A04051426109C18983122CE3C49108496808172D81A6282235040220294C928818940911A9881A210AA3A44D0110890B4544523480D04085C8189011B2905A84058A92895CC051D9C42C94304EE126719242860B312DD3100821804120196EA4460D4B12101C002C92308A219961D1440AE3A00C9B206DD3B688DB4045634621D3C04084986102942D60420E242609CC424608C04C61900511308160386C438070A34209A3366D01850CD3144102C205D1C080A4202CD8A65142484D9C106E42C4091C304684C42D621260C33044C8A6640B043094448823B6711893655B30095A028E84A02D82204481066A1805301C082A20B1685C22298B46221C9204DBA285132622DB460510415180B60D249171E3202C04140A13382C9A8410A2140699B2318B207002B35002B080E20632901025513631641089982885DA4430113048E0024CD3008623916952C24D981824222185A33690D4948D9A028DD91888E0882482086DE2486502972C1C962519428519130A03A82493088613458808306C0B030EC1B828E0104AD1C680613826081588620805234588093781622028D2B610C3204283086D1116702481250C324124258411266124028A09158E4B34108A949092C40D24997084B48092B600C100641B292890003289426CE3A0299332701C910544028414097293900D1A424522434A04978512C22021156164226A00B9212439508B1492D9C625232449039201818690D208460016681A364209B3905C06268880701B166E1420281A03601B45618282908810091C258512820C83144ECA146022A080A41226884652C04849D13226C9186C9A2481124021C31881981048A1022188164D54962553222118C548E49610239509D03050221681A134284AA824D81022C114494A2681E2184E1A444401A64D2048848980410B820063A66D4B46251A96299932464C464003110852244519292A1010068808411B114824228404B30C53A08884967002342120A929183049603446D4846049829010954510B22853C01002020E00A00491286E1319258C822C19330E0C874D130610C0164A91160593C609E44072CB18709A02620A170994A291666064069F3922967BF867A52B7F48CCA1475730371BAE7D3CA391B017ACE1FE2B9E67D4F8EA687910569EF4CE84372DDC13FDB1DA2EB9E2634F9AA71E87CFFC9E28F1BFC862E08671CB976A54EA31AAE67F4EF5E7391CCF4F6614920057B8617E6B7743F7795E3D8FF767D908614D9FB5FA029AD4B9289CFB78D4A8084DB261F67F281523C1E191004FB18D7605A5E1B61B2ECB0543C153173C981B86EE4B47602D5478FA02DEF589E0B4CBE9A95ED74E25253A882E50C64C8BDD131487E02AA035B47E2B11CF723971CC44DDFEB02C6A112E2A5BC929E53D6A4C8A197C14C2995550E9CDDDEC38E9E09A5C4F8AA97DEEAF1BE0A5DF604230916128ED49ACBD9F59A4E0F4144391A8D718D3F7C0CEA8AB31B04CB0E6E5415AA6E0F2111601EE1C98E6A6B670B265EBF325208036407D3E768B7D68C0D9FA7DB1830A95BC2E41D60273CD0E0E9C8DB63BC1A3ADC3F126475596DDC43FC64C9FFD82B92E2D7BE1E095DFC89B18BD5DB3E601A1F1033888730CDABCBF13C2C7309E4B14E687236B11CAD4853D367B146DAA251CDF595858F4190C01A95292A94F43FF7BB3FB0D7E6747029BED764134CCBCA8C517DD44A0DBF59D135C9E7562A64FAED25AB711AA7578DB087BF8DD5EC7DBB7FBE54B6F7EE9E0C4D0625DDB0379D1949FCDF2F93B49D7949E81A1DA000461FC3F5DB8152E63F37D3DDD885DA6CDABFDEE4DC620159DA78CAD3C9E407BAA84226824C142A893D7A44B73172BE3D0DE12CAB4C247DEB9575EB2040A180E7C8155933396AB69E5C1F6995A3C85D1FE0FFC3F09522ECEC1CE40B033424CD27E22C8DDCC9BEB01796524CF433D9DAA4895D0EF1FDE770446EC32C2DD87D3B42CE75F4146F7528EB68ED027B9D789405C41E4B35B3557967480909696E00B6BF1AD7903D97A58422EE4A4DD9F2EE8AE163C930530CE93DCD6DBF475A245932F0C7EDA1DE3D7BDD6CBE66F93C0BC79250606AD329554F94CEFBC7C1DA08C4B1FBBCE1C4C68F36787F730262CFFBCA4CE3794178F08402890FE3948E0C9CD5DFED68C83D40AEB2C05BDAB5EEDD980F9783F6E29DB2058D3ED5E6D1952FAB5BB9DB63BDCD1BC2F02B81A7AC09FEAC6716FE18120D48DBFADE9A919AAAC8757488B2CB53CE83AC2F9A3DA3549649200F2402F574B1A636A40AAC099E8F25E22CA2949380F53D2A8AA9DBAA36088C6CCFE95B453F3CB39D147E25836B789A33031A850E16CD99C11CB8856D0ED82CA8078417D73C1C716672030257EC839D379E9095FCB0E83406DA139C9F93C0546B476899303B333609DFD11AB6788C650EE06BCA3948651C315F12EB518D843E8A718C04C53C968B2A951085E0E5A28037427C72C851467C8E737E72AC2156E4FDDF491097062126BAF36CDF7ED41C8BA4081937567618BFA869C2A21B0046269731BEE0BB1686B2966E3658651E259151A6A98B1958C5F37DD8C5CADE9504D1211A77773A78DA9E9A60070250443773B7943E0FF672C77219D5F76ADE6625802C9A7221B10A5DBF9F3BF5019983280ED3AF23BE20721564CCD7868DE7DB9A83A80AAAEDF357B215DCF9095F79F0DA5D4C3BB98740E6BE09070829C33767A52CDB97E3EEEDFE6E43199EB09881C2F3A18B43EDB5BC835AC7C3DCAA7D3E638C07E0CBF68DE1E6D14A2C3DEC77F26D890127EF9C42FBBEFD04E9C74D4B9C80A4E4B3FCDC8C8D9AB2CD4875DEA9D5AEA72BDE1E5C558B4753E480ED410FDBF2946104DCEF40525BB445EBA4FA77C4C65B0507FD0C9542919B3B367EF4F4ADC5A1DEFBD3092188758B4437B7F7B27D8D2285C24E4DACAF513391A8CB6733DAD32EE0E00710E278072DB19A2330ECA56D923DAB749A671214E812B324161DBAFBB2ADCC33C96ED14CF04A300255DF22ADFC618C405B718988E5DFA30255B75F8F0357A57761642811E3180C18D7D167E5DDA6D05B1FE2392240B62ABF2705DE27360061F10F6F98A0ED9CA604A3F1494AE66E4A8D637472EC8674BCD95B4915511BA70F5DE8A26EA034388AAC5BD8990A99FC3BCCB61612F99708A307C0BB966D198F603A777109A6416565C9AF7D06F620F48B44A9B2F32E034D2E5EF6B6CC9012BEC98CD1F89ECE7B3E5B3A1D61DEC92FBFAAAB32D668892BB315498DD208016E7AB0EB95B6FFD2059DB926E89053D78293E1F17E07D8404FDC24B4E2B4C3B3BFFAED8539FF095CF7B7BC97A4FB06B245E0D2C0823BC869F935CBF844AC346F0E3D5976D815FB6A484D7F5E72A1C1A6E8FB0F0BC209196B0F016E672D17771E04EA919EFFEBD317604A0FB5D4327D74DF07CC1AD6165733ECBB32623D0FB6A3B1EABAEE89100FE1B7F2185CE041E030A4271DF421D5FFDDC55F846F670498B59B4397BDCBEF252EFEA81BB4B3E4EFF3756E8B2A46CE51A84AE69B774374B1995DD2D9E5E656B0573D16676397BBD9955EFE959539080E11268B071F33E125BF2F6F90FD8BD166567ED9AEEAAE0D47F5CB9BB2262EA1C07943B4413E39470B97A2B5E8C92C083AFFD1BE622C1A00B436CACCD75C81ECE9262A737E3BE3558058A330C7C570F85CCDFDAAD6962503B91D16AFC1DBCA076F8023127FF0BDCBE1C343588B60653C6BD695E954EC4ECE6D034B4DF63A92F2D7FC212FA36C88E8137B3892DBA87C2396A9FCF539098F73B043C09AE38D0730356A0E90516DDF0300FEDE1FDD0B4C84E61616F9BDA41F50388BE8D5BAC92DC42759023679B05D02A536777947E3D1F24A91D935E2AE76B9AB5A865F83E2340DDF3AB0B9A56A5B08FD648B7900A48D2D65954F51D43CA39925A75E16F32DC1ADBD22301B0EC93DA01F06ECAA8EDA6F770D4DED24D512BB1764CC515D69D87966F0BDA86769149D38DDA1BDB3EDB7EED89C603235CA16890189F560A0542455E8E4A09BCB02DE7D5FB06DF64DDCDE70F0381C98466BA48A69436DA9BF3DD713EF802B214872A397CBE53D5C573890F9E9D2212FBEB99231D1DFB98241A9B10F10704C91E313115BCA7F3663F7203482CF6696E04567DB6AEA8E8D7B29492A0EBDBD4A97A7E6F0965A84B37D55E9F88777A968BEBFCD4A3C5C94A732F5C74BA11C7B4A57648909610C89D27A3A273A0D5DA2B3331E7036161807F1162B602EA5D7B83984C0EF08868571046673112D4CFA652EB927109DAF76A728DAE6437A6DE15027514983FC1C1CB08DECD7B31C609B0F7AFAF8D183F2588D4F60A1C7E80BED6D0FB64F05AD8C7AF5B6B5E861666761D53A6109310C11AAC7CCFCAD51CC54222B88FB7644C2625397D5745E4B282F8500AD496CDAC91078124E5416C3CE66FA8C82385A3DFD549ADFCA317A3DAB331D203EAFCC3DFCB7536FE8981FDD6C00912DFDB2B0D708C162440C5CACD1EE593F4FA891DCBDDD18EA0BCB1987152B3FE0CFDDF75DD31751E8F74AE01231BF3164D4917A9EA2372D5AD19523F657FC24C4A6D0C2BBCE794D2CC270B6585A4F7E2153E6E41CA9BE747D0348E68D7269084BFE188E4324E4FFC55AFC7D8DBDC2A47B6923556C9BE84CF29B1C6A3AF1B82B723D79F65810C767C140430DFAC14968F2581259CBE74475BF427A5012F93DAD6846B976846EC308903C489DD1733BE7193431EC09F70CAF0C14D539584F58E23A0B93CAE93128D1B52A68059D4D3FA6C4F7568C991B3FEBAB081498EC59EF340F91C2640596C7C8A69230354346C1BDD89DD99CFAB4EEDC3C2B0FB8A70C5391BE2D533D26F6A3BEAD450C05C93A43D07162068DCAD467FF6EDCCE1E1C594B01717E8345EAC25887EDB71A221BAD69E5F3E9B62A7C0303DC62CFA8CCD93659FF50F2A446A797026C0DFDD5D1D50B0D0297AF09402B570196DED70CFB7088E2ECC5D474D7D382E4C073130F12D4C23A7071D93BD7E66E2D6DC1FA98307C44D013F6C1335D321620591377FB5622AD625AE9AF030BCF3F6F32608AB45E2C15E78ED195488E5995D933FD54ADC6C73A02F105CC03D19EED13F3733389CD42F07F7D900FFEC6179CFED21C5AC4CE31691578805D2E6BEDD06953D0EA004CF9B630CA71FED339FBC6D465E69397919B3FC508A3CAE49A9B3276D1B0A75C78D8686DB7184BFE2878C0944256F98AB6C25DCC67C90F1DA7720ABE159C8743C15B3BD3469708879FE4C915A63AAEF01E5407DE35B1772513CD33D2678A9A34F430ADD7B41623DA000578A24E5737DA976DBA5C69569296FAD87A5E6E8DF5C7C2C1EDBB7085C046106C50FF4B4A3500A00E7E730D8E9B0627E10ADDCE06C296A6F5BEF4E99C411BB8218F6304311FAC1218ABB847D8FBDF5CDB74CBDDEE983FAD3A9447BB80C60C58AB0CA05FFA8875275C6E973EF9F80917F11B4C76EAFD58AAA34650A438B18246A4D87ACDFA57DCAB2209F65AACAB4730D6DF6CFF2E87FBA14B720B16ABE927590EB015D288DDED8DFF500FFA2E0ED288CA86CC76DD7FC7F84F5F926CBBF026C7E6D5D85D3DDD25EA103B7FA98946E4CD8D450D457E85ACA4311F8B52F27B4EB8AB2F993CE5C81583021CD385C2589073F997A21BAE447D3B4D3BEA154F188F7FA7A19C7B4E9315BA358F5FFF6D9FE9023C8EEEF0A240F10E698102A19FE48900C304E049C5A5C3C476D224815AE298520CD4CD889B44E5DE0C052F76AFC2F7A9F068D5A81E38CA8FD5D4D9ADB47D9D385E5B5C4BA54B8DFB42DE493D5080B326AAD8D41104D7EE98F51A147A9DD8130ECFD817A7A", + "message": "701B8AE25CD8187095349A4D41A067D4FD48732E62547E491D38845B3507A7A6AD8F8AFC53D139E47FC5AF2723B1BB057FC797519AC93CFB18DEB496BD9735455CBDFFFCA5E69C95990EF89F509728D1CE41F36A4C0364AC8C30E3EF67D3F3776400BF4C838A477231E455FF76C92CFCCE1B69B00F99451B0A8287ED59CD79EF0D6E697C93F7ED38F20204921E6E2F141D3DBDE1C201E5CE7C524370C339753676746DA5DE4A398CFC2CB1F568C16D4DF34A27CF04F0637B1447C6CC83E965A3F86C538CBC235E440CC2D1257CF916421EC75928DD6DA3CA002AC93C8F464ECD522EEF7E048C154D73053DA7BB63A5DD845512D2B6B7D1E7EB5818D170D14A4A698C8922D69A98319A10E0AF558E2318FC390ED990B75ADB50C6199DBEAF5D53B49235DE7CA116932EA38A109322AD05F5D681CE25FFDC9F6A05C4ED2EC6D4242173D2039318EF7D0733D86D57C4E114B3476392D47FC68796C9F66B1F1EC70610E1D57436614D5969564DEB8673686170E40BF5CDE506F7E70964E07258D4551F5EE0BF2651F8BF3D3177DA76AE90FAAA69C4F373E664F0A1FCC62F208A8BE130C499166D13CB34D77FDB32D5A7F3AD38856BFD3A0419B8744DD2F186D03E18634D826A5BC87F1566FEF88D9ED93E74ED4C005EA3EE2EB22FF5DEED283132D00C7A0B131BE1FA38E30EEC68B748AD533BFB23B9A14A936F609D4C560163235367B0D64C2C796F1106A1A9365E8F507B4BE0514C849A81E2C7388C8AF300D98D444BF808C4F9338C47A853222D5AA8ED283F57DBF0689E5FB89A456005B6B95AC3D791077C79BAA2BB42B423F93A7D0D999241AC5B9D64D65274817F9BEFCEFBCB4D5CAA67427F69ECB279553EF0D33A19E14FD4B284A72081F949FBE2A7543497F314CD7496EEE866F33102BEE5CF9C706426EF2365EFDF1AD141552BE65D1DB4373B0E8D449F3FD1733AA164C1F2C24F74E240C5096CD201A11113D6BF5CA19595C4B0A81E1153A4EBF88F38F1812BE517158787F2B378E8E32C9F97432BC9027292E5EDD7DA64FC6A32788154B62E40A85701895E13287BB18883820DBDD7647AE4EE1FC1D43C199EE69B1A2E2A7067AFAC541A8F44E660B2A7C114F402E2054DA7ACC41DDDEDFD7291CD4573DA22739C7785EFC2240B27A90BFCAFD1AFAB6C2B0EF5509D0DDF349C173E9A6C906BAF5692C39F6E0D1442F84AD2FC118A14B12C3AD5DF8A79056017F4FDD76603717B080E3AE560D7A601EE7FCAA36DF7289AEEA59EDD0B73BE91782377150F03C2C2ED40F33A250356CA17E153480A7E848F090DDA29C65FBBFB495FE9B7A2BEE342C7D422F28631A8C9CF643DC76F07F162DA1AD3F24589971032796BCDCD262F55A8C34FFCE05FA9DC001FB35D6FEE75B42DB6DDD2138C0517D003512F0EA8E982C2ADB5E5BC1F19B8ECE67E4AA1681383A97976B6A8F2025EA80B1BFA1796C27F6A54C583711E2EA46D85C515EAAD22ECFD68C5D02853D688302704EAC4863DB1FC69F8C35411EC6F4A9F0A7E7B3385ACF6DF805447BFE863181A945E8E7944770340496F5A19CB7DBD0D9010B7EEA3C585926408FD40F245D852DD208EA97CDAB0C16C1EF80B3E5BE77D953A04C1B6F53A23080B54F439705E417B9874B3FB524794D26DE3DDE88E9DB9FC36B1508754EB51D389FCC46F822F50FCE199DC14E4B4468B8B15A2460EAD05D0C47668C05A2315748897AF99D320E70F2AEB96936D7D739F72ABAA6960DA6A3996988F6A3F7AE7772D49915753B936367E022179E69B6853E1A83B429B42BE19EE03520A5666124B657D2FD6D15447AEEE45AB1FF4593DE9A2E6D152C64DF45C1F62AB9B67257B2A2115D224850A3AB2FA028F8F9FDE7C9A9FBA2FD291346037A1B4E00B0642B07ED54BFD70F3DCA3D1B8628627859611006DB2DD17A351751F85C60028DCF21481291526B1DEEA4C7CD2D3230653E6FEA1DDBDFE1BC3DA93FBFCDC5A405975A5DC68DA0D8338EFBD6CCDA1F2374D72FBE007599E81CF7D5C37985EA09C561A1EC40A70784FC606FB7C3FCD981F112C599C78B15B7739AF4DE129D489336BFD3966C10363A60E749162D1D8311C5E850B22910B999080DFC86D1787C35768CD5470E9F7A51D4EEBA71241DB57021D6569ED2BF201C06E235D6621B292B686D23E29DA4E81C873371593CB07B3DE46E91FAA3D4A2AA6F62FBF6BBF1954647E731AF4B99EEB3C0FA6385699F8EF2D8E1D7F75161129A1C7F8C7C68B906EAB8DAE8BBB3541FBC65F36BB67ECF19EBEF54BFC2EC4E1130A2E4F36B5644A73CB0E244738B6E5788A4B4457291B57F1FDAD2C11FE5C7DCFD4E742A0AECC460BB660D7BFDDEE4CEA074958AB94B6FA4CCEFE02FC7001D3A2CD013684A1ECC2E2F6D90D246726EFFFA99C12D1FE4AD10A6BE38D70AE3DE5C4843FE6CCEEF587191B56F666C1662F5C6FB03955C557E1B4CE247A2806DE39EC40CF8B97835EB0E3F2D829E0FEA02FE60C934FE72A25930FD6692B9ED979F14536F406F04C3CF0BE98647A5967B81DFAC353A2F8236FE147BFD7D3731C49476C3191981C9AF239AE8C72570C6C53E7AADD48E721E623D6CF11A1E386EA7C30F070E7AC4F63FB42AB74881BFA3FF3E8A35EBEF04D39B853DDE0FB17DD9DAE37A76C96FF55F64669CD9521DA3900B7CB297E813521239D87703CA395CDC8D8CC4EC21CB10A1C672493E013EAC0298F8076C8E0B56AFDF9C31EA01CBC1BDA4AE17FE103C9812E940A34EB321BE7BB288CF8BE7017AA58AD528C9DE09E269B10C6FBFBA5E8B6883FE7E08A0D184F8561FE3F43582CA045DC25CABA52C0157495410382A048BA67D051EA115D867D780CDE5EF512BCDD14489C43604F86D929F83D118B905C63BFF451FF3540E9E220851A402BEA0DB1A7CD94DE0407AEB9CF862BFA3FA703924D0A4803C463AAA827A04B0F09556054F27DB98E22A96D07F81662E0E910836B9423968C3F002E605BB688720FA7CF3167140BC21398B5E4968804F3C3065FAF125BB6D887C869FE3FCC27D88E048FFD0925E748C096C74BFB1E54A8FF6E2C838F16769FA4D8564E5CCC58DAE3B102EA300361EF89EEC689FB5BB0DE16C5CA98A60B8990EEC0006A147036871FC2A6ACFC6A6EC907D28E18A76560A5436BBF9353789C8A5DFE559FCD68C117066EEE5B00F349D6591E104295E78F445FCDD3D6883DF50D1DA6A04541C7E8171523FF36A9C072164147D14985BA30FD449667B580D73B06A5971B720A8B1D2A6896FDC5E4D4DAC78353ADC3449AA53919AAD15EF250AE12E9E40B8487F66AEF0B15E42BF34AA816F559062EEA24EBB01BA369747B29404DC1F1108DEAD021898298E72F4BC1DD821E4C88329D6F03F971F554A87FEC87F34430ECD1CCC6627D8CA49EEE1D5DA6704CE960021C847DAEC2DD544D4EAD2E2086058CF131296B7F4FA4B71A1DC6D6C642A256AE0C0EF9D1211EFA3845B12243BFBCB4F423E913A2976C1015569ECCBC159AFE70F1EDDC3AFAAFDA45CC02EB60BA0DB9EA83EC604113479BE848F381FC63C63B3111DC5179A637E0832A26EA32555908D79B308351CB104C43668371DB32056BB63540B9C3E5551A063D2B525F8A016BBACEB402CE7D7072CB9F37CEC13E1EAF7D867534C013D78B9DFE01C13DDCEC7A3444AFF9E182F12B6901CD9A70F21908FE692E4C0536B069C89685BFA9D973983AA8C1DA461D18ABD27A6A717D9F2122BEAA9BB1742622F51FF616FA2EC3A6D4724A3A9215D7B29A1BA372282CCF60DE90B3834FADE6E3743AD6B2F9B7344F45A29740DD7DB2D642F94998579A5DCCD2EFCD2F7D08486BB327B844EB19ACE3B4FB0D85F8A24FACBF318C98199A0B2C7FC2CCA59AE84A522890E22C2A7207CE91623362C7DD8E9F946817C75B71FB9654E2B7F2E83E46E75ED5638741E414D7F8E70914315F0E37B5B4E3E1CFA8288B1724113E4A00B59B7764C2D61443537849E77083FD13BA652001F39DD9BD4B20AB77CB945C5EBE686A0627ECC52F38A852BC9E1AC8D303E3B96D9D086920A19E5088054DECA635E802385600F673D3BD0A5CBE7A5B9BA8B1C4B73B9246C1A1C1071E5F98ED42041037FAB67184C89BF4FFE3CA0AE2A9BCB020F390F0B76DE2B8AADBC99268D3A1D467A024184CC9A455A8F2FF287A4C9DD1B0C86C8E176BB15B12023B291D44E7FF0C44577F7A6D788D82A75C68C9F5BBE504E7D64FD2AD18BE209E85C45627FC045BC81E3531A2B886173F3C3029D1FA98C792501A4942C72A7A892232F390CCBFD7863AC38D837755011F919AD8934742D0795523E6D48A958BACB9A9F7B9A5A9D914C37114CB111CB536EED3D753D6333219EC993AA5D39BF74E8E9FA02D8BEFF369EDAEC67A5CBD128FC9BA6F82E31A4C59D783A99912C7C389EC708824AC7FF05D56BA6D228C0A9D96324C6D9725E3BE17C44CAC7C4D49235BD15384F95345DC36519466A13110A58300F7E3362295DD7069DC6A88B542F2BC5C9F33328D9D8D1683902C025427F32FD562BE3F0680FA05851296E15C5FC67E96BAC924407AE6BE37E9B61D9A6383FFBDC6E77CC0887726C474AD735BC50039AEC665D827B0F6BCDF7EC87EA6BF793386F2A65C997545FB93F0D53737C53D00685DDC13960AF2632380F105840A1699ABE53999C568978ADAFBE21913193DD0844D89BD582418BF8B6BC430FF1FF7750AE8507495C14DF21A3437AFCA7DCEE7B1F1247C802081FC5ACE5B125AB2BF11ABAC97E201EEC2A8C90ADED920728EE77E1FE2BF31A222A1CA5263586A16FCF80E582258654D0793B1551EA3C24C4EBD27C52956ABCE6ACD05FC2F088273FEE8ADA0256F30B5ADA8768D8E9B70279DF95AE5CC68FFA99934C7520E12F57D213FF18ECA6046A9A3F32E280044023220140E2485A3B3EF7778006B18D4A9DCD177D190CD903CAC1EE0897F58762299A0E026B8EEC6F4F3D0BE1F070C648A2D73869F22DDA21246CCFDEB7A9784AE967F0DD0A2011C637099AF33E0D608AA0A5B2103060CA1A6718328D451368EA3049FF60FB66FE54E778DABC48413966EA14E22083A884E8C8EC33F885093F01B5E34477745A9F82C645C8C5498306AB00B78684252ECD74C163BB8AF9B49AA03E244F4EFC4A2E7099074F512D465C84773DBD1FA96D26053230C192DB289A1596E60B96178DD8CDD72FF14B340FB5830696B393CA319649BA56DCD517F5A08A528350E2D9531B3AC187414FA6E06C0F05D9987BB2FC98F7C8D4F922B8AA45287FA83B900ECB6C9F02669063296F1EA389858F6D2E10228E136FAE35F21DA151EA7AAEC593E5948536B68BE58ABC57771AEB406A0C3F931E7DCF85A350A3558E5C1B1F70E6299EC9FF8B9CC13E905D9902FED957ABFD7D09FB84FF22BF8410D387BA85D8555A75F432EC5789498EA36CF235276176ED48D1E374DB5C2DD1A64714D64FD20D4FDE2A605034E4DF607EC6E11D0465DB25B9D79C83182384D64477C126E9B8558489F69AF29730B4D5650B9860326249777DFE9EA5669736692D0780E9BA346C1727138F5DDD4914487CF32A4E9CB1DDD5617B6B45CF8C981944684BBB7921C88F5A25120047BAF2D9346E220EA08AD168B30A1B82B3B63C4913C708C02258B6AEF1CAC96E2A90EF7D0E1EFC0BC5BBE05D286E143FC0CA4A23833CA12727F0F83079F7BA80D809D6C739EC4D0DD9CF75C4FE30B12A892096BC4B9167F16819694B2CD5DB4B80DE8DE988AD50677695C4FB3E0940913C250645333B6F55E36F649A43C3A39ECAA3DE3EC1FD4F9F65D9F7AAF75B60DCA3BD1EC06495FF5F1D4FD6D83CC6316E40BC469EE5F44E5AE56ADB229A7CA5CA37A1508531E44B0142B4330048350A40FC82279D25A87E043240B4BFA7321340502F0D37073DF068596C4753F8709BAA2A7264ADBCF5F934E857B3225CA47D8A182B80D3DF24C3612FE4931EED565BE563115414CC2B6BD102DC6BCA9F104CEC8B24BA5465FEBB7E9730C928D6FC1144224232A990F8BED27FE6D28AA35A91F90D6A0AFE9A7E37A5BAE51D8AFDEBB7D5670F2521095A56862354D2AD946663B4BBC7049ED1884347734BF3E78ED227428476F1070F4DB011F8DC86EDC5BAE1BEDC9C5D253E4C5C6816347EC96C5F62AA3298588625304118EC32DB2DE0597BF2056046E17C69EAECFD26475066AC54D40A673741BCE72F138DD98F1939598E5D94D565C1337D1179DA057D4453DEE27B5C04777EA710D77B317A6E8DD3B4F26A6A9B3F4917A0E881E5EE528462508DEC6762DE2BC3F8F8C42E8D721BFEF7583C99DFA4D1CB49DE2A303B67AFD505F8A3865D853BF19C4A0F7CFA92F5CB18CD5D8E378A5B041449EC9ECFB80E0865CEC1734D34BC44E664243AA8F605366CE9F849700593C76BE0CB19CA1255B074A8630FC962B50106CD93DB41C6E4DF53B6B1257872B0D8CE9AD5F245C3027A3F75F19DC568ED1E0F60CC20DE625241D300DCDC8C953676363868B680B471C2EE623DA408C7E030833DBAAEE8E701374156A6B785E0EC7D1A0A55A599605BCA0FB517EF99939889C862CD790240709BEE0226DC7E8177F641C747A151A89340A6CCFF6982EF39683325390DE72E4451BBA74E3CB102870F1E9ACED30BDBBEF160A49746A23C432C3ED7EEF580969110AA438D00AA03F54E039195D61B7840222AC994784EEEA538B7E830A6508AA0B460DA4B4C0DD9CB052CE6254774FB147F7E4F80214AF1FAE59F8ADA6509123438E90AC13FF7CE71AAEAEF7A39C434C3824D49B894C389CF320A430A7F84A5F4972FF98C388D61C936E453BB1A340528A9FA5F0B0DA9543275435E91B0F5560E95F9AE4EFCDECDE1584761F8F60F0280ABF40FC5834BFE456EF66AF66ECA1098DD49BA2CC4B12CA9CFE256FBEEC328D049BD6BD19E2358502672F029888DC3AF3350BC2EDF5C4E07D59DF8DB9C14B86F1FE384227953E98978997902C8F237C8BDF300A72248B3DDEFD52577BCC0F99F75B92BC056719243F7EE67932A2DECFB15B59C95B43E183BA3DAA41B97E177D03CA320A5FD5D7E5A88C4D54A8467B883E0CD5924912642A65F191DD4DC2B08DD28EC0AD2B1CDB86EEA3DBBF6D47754B1BF7036A0BE90CC3775D263A5BC688844BBB9B1D9296804176E17C55D6DB888C2BEDA3D546FC496EAC5243AB5D51686AF9B29BF6D4A138BECD49665458B816BB09848CC4318136E6B170BECA544E8ADC35D40DED979111B8B1D4577DE2FADE6A1D97F9E82E9D3F069F3287E559E99224C6494F36233453036DBA617088D619395518B4E6725125850B3121EA957E721244DF53FB343483D27E6C3A53224B38C11C1D64CBFCD7041A44836AA606D170A80E84BBC0973556B9E4B1BD776C6A0876D727BB0526809700A0EB318BED67843CE4A6BE2BC10FE9D8228A4C94D7A506760E580E8A0E544ECCB07DD0810D79443046951C72E017CEE5B2C959754D477D706C3E043298CAD200189F4390F59BA27B0099DC551673B5138AA654E054676BF30DC61CAFF444CA22EB32E5952A598C07AAAEDDB83B8B3789EEF97663ECBD33FE356DE981A24C29DD5217E14DFCA30C0109419D8765A061F747BFFC1E221D3ACC7FE239375A9548483543599C837F48EA189880278AB2E06EA44417EB945F20ACB464CC458E249A8969273A460F063C5FAA907E42C9EE304B27C85BF41FB170708969A2BFDEF37B97DB4A16BBFE07370039369D04D0A9155623AA390ABB75D47FE2394E4606759648954FECDF4554F660D3176AF33153A9D7B0A935753B11E6C7295B0FF5680A18A42ACE577981C500581F741CA23DFDDBF22EB6511E19C016EDC96DA545AD16D5EFB9A8F10C45D78E01C74E3552FFAF35CFA1BC0C3DF9D14C1BDA9D510FC7C7A755C71B5273CD7CAF3AF44AF066DCF18B1B7D6C0D546C9C0B0B1BBE88F512824CB8B512438ACBB23CAE1178DA05DD67DA6392649213805D680AA61D26092BC1B2CE50CECEB7541D7F10808DB2D4A6B12841C8B4B6C5519C8683C998A74AC3BC3CC44D81B606A9A3174929E4AF06E032A24E67E9C66885004F07D4775A6C66A8F42F94920749FF902A8F1C3BC5A1A35BFA24040EF3B7ECD05654CAB696D3323485EF855361DB57A65C5AA0B238DC551ABD6B4A8DA0EB987A82F56E5EF05CEBCB4155181BBC61C645B2A4FA8B316FC6C5B3BA12829E74899D0A42B42821094B57E6D221FFA108D5D0EDE9012A88A2BC361D90673BB3D19D6355B9239131B42FB3CE832DEEA6E4551BF6C6533CD8DE572ED3E5DC51BC1ADA13C0C7E4F723CB964125DA08E0D08F1CFAE124568DE55E2B39B1475DC8F6558ED763FD7EC2DE373F4C54399A0317087630AED2A64BF13D113E8AC32E6318EB7BC0DE20E846C0CACD876F47CBF79DB6FCDFAB75B371156CF74B443E8DACBEAF94203037BA14E821A66244BBB7E989567D176FED12AD0BACF79834D067662C11422631554D1ACD6BCCBE23BF1D0C042C1CACA4B9BD01D6C5757E52877FB5DFC92161C8BB15A60222D12CEEE973812B4920B38547304E720AE246FB503C9F97BBA79640485624DFA2F4D508300BB80C70CF8E271770876062AA1EE0F548F6F7D95CFAA17FF1FAD847CBF6CF90B01D29C33B43473379F4B5491532432F6CAB98C365B84D357B48B416C2A00B25D07594ED4E4CA0E1BA5C92AA2F1DC7A6109AE8D71B9F06440A770FDC2501900B9EE466DDD853CA5482B4636BFD58AD8B24D91852ABAA0A37536D4118A122951DC78F02DDA8EC8029ED938125D759B24C90B0FEBA1F589AA1C10FC9597CB7E703D93AC4AFA43D3C239337AA454BCC471CC6BECF89266F588C3EA71AE50F146097D9CCF21E75790A5F3A252977E4D848DCF5D96DDD4FC1D0CB583A28AF9D7648BDAF8F1E94A83CF5349B1F4AF63AB1C66757B75C58D10F27F8619A5A6BADA67E841B6429AB40A09451313EED76B93166B3A5D5561CFB6421D83A5E343C8D277389950328A1646C3DAED357BCF2E8615695D7E8922030148844058D177D4E68A8EE31D5D810C73D9B38F6863083A8266652DB82A43615A45E6D14EFDF00A4333404DB65194EB432187C1EA7C48F819C34E48EBCB0836C84534A238C42E0B9BADFBB15B220DD0BF40F8C0511BA69EF82FA57D099BA84EE4AB6FC422442C3BE1E8DD910B4117BF4047D49419FCD2380966F665001FE4793F06F272E14E1893D502BD3343AFF5EE94A58CEE04E745E72E51124AE8013EAF2C2141012FAC54CD25E97B6FD3F0891BA1DE663EBF009A7008222F461B4E7D50628133DCCBA7CD0AE44BFE9F675E094D972D896551A1205FFE0CA8FCB739192488D2BDDD4E10493B43C7EFEF60888CB11ED68F34630623206E81ED04D300C2C43B6F27E41F18241651FC6B84C19EE1EB018BFD7A0D4483B0B6DCF57236AB27BF4CA17E52739E4D1C508C78F6B6E9FD53F423AFFAB01F75A9B1AB725C247492DAE3227ECEE2D60EB186BD8972FE455C393919E6D9760AD1BB706138824FC3C9EA0F673C1323366DEAFD260591DAE60AEA2DC22FFE5EA2421F35920550C0FBD78C4F6469092F89FB6908457BC81A175D75B1F97E2750194E68705B9D1E9F762068EE2FA9286BCCD3ABE98007AD1AB27AD2A094C6E164C5BBF88CD4C5F325E4E91FE2867A94E9FE1A78DAE2ED1C11CB4D365EC2F3888612FF58B493268645BE9ED69C196857F8C995A42D5CF4542E609BB35B0BB1B4BB85295ADE635E8FA237C5DF471B8CAD7E98420077BF1DBF6DCDCC1322C8BE1B8DD5E228B6E6E04ADA1D533B0C6221FA83BE7C19273F9AADADE041CEAE389D0572D2317906005BFAA17940026CCBAFAF8C7A4BBFCE30EDBF4EF82902E181B41A1FC006AC01BE64CF6E4A4A14FED995D6F323405242BCC5797E43276ADFBA44EB8E3EEC029292D2DCDC8E6C93AA6C02766308CD367D3", + "signature": "367CAC590EE6829B0FE910294F23515114CBA0A04D39CBBAE3BF908DC1A13ABBCD5CE2A9DDD0FDD2A011068C48EEF6BE5B4524ADCBB6F51E9A5B0F57068385D42704B0B48B3CB8D1AB011B8F13AE83726E0EDEA0A5880590AB8FBD689E6495AD68379993C44AB4308D0FB19D3F0E6D98E61BD2EAE1B49EF4229AB10D18CAC1750A60F1CFA9430649A7DE0BE1330A180106BFCC165CF60ED91711E5033E7B8FF29812CAE5A8900CD31A4B254CDF41ED4C5B4506F6FEEE43B389218191246A661CBB86F6C8F790D3D87343A37108E1D79C2DBD9A1533542A5766D56C9D013D74E2D7CB1EE7AABF50221ED657D8C2AABDB26DC3F7662CFBDF5F6484BB9B04060280AB53F0D22093967A19E754EC5180024F3AA2A615A45A0A43AF44D6204BB8BF512CF9F5DFBB8C9E6CA594FA9875E9801B1A3BE7983DC4865F649E3AF8AC28B0780C65314006024569774E8C7909A92539F9A647BE2CA6874B4438E0FDAA7691105C3D6CBE3F355FA37676C65C3508047A521454FC3A5F13F028465FDC9074BDD506365AECE7120980AA4622A7353C366202046CC2EFDC87459641CD56FC9AA723174DF368EF63517CA839813E16072951F53F4A2AC0B54F0E7A5A21683B81ED562358DA14794A798C1C14AA2B51B2F87637446F235316F0B047E757F84D8EA86B35A9F24115387DEC18FA8FDD6F0DF4A918EFFAD381EC87727578185A214B334C77FC5545923463D2601A302BDB21067FBBA672B7E33F3974FE1C2206A0EC233DCC44412A9440D7A09EC3A8ACFC99EC24F9BF021BF3298831AF56F272FC1C7A06DA01B1B38E8C421865EB8092CEDBE376E836B9D8181D853BCD48E97740E8AC046FFD2013691587461DA91FEAD7C840D923B0ED227F5389536FF871859F459FE2FBF24C84A8D290189BDAB6EA31BC1BBD98D64958106FAEED0E8B9BA1C10B66AEB7836063030E641A8E00422E2827D8DF1BD982773E0F13D17BAC5CE3DB813F712C95CEEB0E7CFCA45FD27289EBF6C7269EF58A5E4135A6F651B2139AAE3E1068E19C4EF3191DF10F37872DA952E95B2A831333742864D6FCEA8C0E37BD1CDC2EC902D210E7693D30E36595892CA5724853510B6C01E91763F376F20D650BD1C3A647FD2C29FB3ED1B8A8D15624E60837F55F65E0D0D8B0CEBA1A903293BDDA52B354196A1B138677235E41CC894DB5B1FB474463B168E25E7F55EA5AC0572428768DB4CE75255C47422B2D92C99F8AC8F296F1F823E59591DDEC09DD4440BFB9007B8BC04EBA7A7A959BAA624E2165D6C5C3873DF0589A377C6157A4EC57773F98763745627A51FB36CB82279EB9514E452F381AA65B3EE860D0EA2DFBFC838C98821907C1A99C0C18AC49BCBB6FF01127C46C439BEFE217AB080337B66F6FFBF934FB5A6D16118DDA48CC987A13D52416F7FB4D10C7F22D8F97A9E380C8A3902C2014F3C6B2F36702EBCAD5182E33641FE6D65A2BDC1729FD8230D5814545EE15D6D02907D2615E9DE534EB49D638FE0CCF5497D351C421C7F25FE57A507749640328EDDE3DFD807DACDB335971FC46AA37177C78D179DF12F187B531CD5B02A08A12A0C5B7CDAFEB636A1EFB6CDAFF16F4D128A0C1EC96FB97083C622C94F3F65105F865B1FDC81F69A56427B900EC13EDFA938C0E8FB31DFA821F04CFBADD892B1EEA6F596A6D02947F50B3B66A3F0323B9A1FF95C33F68EC2B833D2CE958552A8205B5BF0E554FDC441EAB46DB0E8FC319C7FFDE01BB3F118413C8FF941C37CFB39A60606780EDB9F5818CA4A26E1240EE6AD117745F173DA5B2936F1B25FF1AB49E10913E9144F6A1C0C547A93408C5C5E1155F02D5C90DC5E750F06BA51746536E351814F1639AE3C845BA88EC3FA60111C7F8285284AD1CBA5997BED7FDD71205032180050C4010FE353CE4695AC49DB104CCAF5309949E2D6B4485C10E92656FA130C7D0A2C424F98683A8A2F4ACCD31EDDE5B11DFE71057983A79DEF73DF46427A00952A69C0403C73707F151EF1C1B3C39121181FBDFEE8EEEFFC74BDCA8DE6078ED56A7968E2B13426CC387776CCE40411220FF01E2ADE27EA9F9445A635EB8C0D073232FEF7F580143EDACE3954AEDF5FD01756102F639FA9643173146FAFD50CA4FE2338584632D433640FCF619D141541B0C15D39C89CE07A47F24F59B3DA68A42E7FF5394A02B77A35DA7A61C2B7C430678FC9956211038CC2EFFC9D7C8E04EB0CD6277210F49940B39395022A226553DB46292774276CE5CC184B29CB598CD85672BDDABE25B8F20486C775DA97B9C3B97B4EB9B729854120555C25F130FE3807BC886A43BF605FDA29898BB7160DE95B927AA7EC5D5A5249E82D4D50ADBE591FBE49C927EDD94E557FB64F73643464E7AF168201C57A16C6A6FF6ABF1FF392F8561A66AFE569E51F820591C0A7A43D841CD13AEE08FC15A8BD8C0EA63C69EC331881697EBEF2C1646660E34B775BF497C9432394393A7E3200E63E477169D9C3FD737BB79C1155ECBCAA73B0C54A5C0A2B8ED6DB93504C5ACD7FBB15181696C9B6EF1A93C002FEFA46007D8DB5DF3A7F659AC032BC3780D8A7C7FF485761E632573E96D052183B287174E96B230025543288C37DEE87D6EB3C44FF58544C598EDD123CABA17B0C17C1D129BD90D72382FA5644FC94CEE6BAA9C152A04F6A1B5F6D167E8B27E2665D861D5E439F2425B562DB155DAF1573B3F69649BFFCCC73DC72F3E3A40900D56A810BB99DBC75A6594840006909E78299F4C56E451147C3FF9F069A65399B296C2B906E5B493FE4DDE19B4831F43BC2F0221A833EE99938E60BB2A71CE0E4E47140D73D5BBA00952E01883D9CD3FDDC0430B9C413455F732FB0AC226BB59DC0A65C73C915023C035C6C62CD6D1F3D5C27F473A0AB4C2D946D726A0B8742E8FCAB04D2CC23DDE5B0BD952D5223501DA188822F481B8F8CC377903EE38A740AE1125F4789777D94176042C70317528ADF14DCE224FF871105257DF7F1385D1508C04F46ECD2C2E1F3E49783181ABB0E2E503FD5DECF38461C9D6E093CC55850DC0239B7F550D7C054097CBB554CB53C3F43FE1E7EDBED3B55491AB564EE3AD7A9CF330BC4D42F2837E56F15E9676A838489F0908E1DC59DCE7AD7E72F57017BF6F610F486FAD183C714F99226889020534972BF58D414E6DB20F22FD60EF8359438FFE56C20F28D966B41717D3B63250DD0B5A961E73E06793AAD1836F8341C5504C15990B1DA9F37DDF87EA2046AB57D894998725CBE7CDBCC1B5F4EF0B48B05E545AB5125CD4A9C883BFB58BD3136F03E3CFE3F225284E17798A1F4B38A91747DC5A2D64AE13E2C72CBC24D25F809AE19100FF0C9B9E9063BBDB08DD776F7CF2900C56201F56269F3BD8C3EF15BAB0821E1330DA0C441CF3A5D0EFDDD4B2B48C0F567C00346B97F8EF9D377A7A590FFE77A6BB2D6FB6AFEFDB7C8260CC1EC3A3EACEFF8AD086CDEA49C39C961DCAC0BC22FE446FD1F7099425D559CBFBFD68EEF03525B01DECB52D5ECB1DE9FF4427C8C607428CD43E33F5DE8DF9D995D033DF6A41F69BF623F36451E53E422BE18F5F9667F5AC1FAE21B4106CDFF91333749AD32978EF6FE73D7AF88D4DE4D9E2BFEACE96D8DB08DA9ADF8BB51A16D326378B3394AE7307587F98FAD697BA01C1B78387DABB5D6E8A1F2CAB663A3ED1B8A833E4F76D11E0AA38CCF4476847741AC8ADEC7A5C4DD802604F690CEF94B014A1CC2FBE8F2F71247F426AA5CFE3745706E744DF24BB7BDB8BBE8BC8EEA92E46F8BFD515D52B3CFFAF81F127C5CB65B1AE5D4925161610CF562B660CCECABB35EB7F8BE085761EFB4A8F29EBECEF2726938606D2562B4ED69044AC08769EC112DCD7D7D54331549C41D7A9A9D9F5B004E4490ED183DF65D917DD1AA8A2B50E86F59576A304606FD527079F60A3D0EC2E36A12D354B6187D1A5301FB1977EA5E5011F3CC02B84BD6A5F21D411B4BB276129A81AE6471EFF6432427A191134542EF23CBFA2E32D2007C2637A189D7AF0A7D3990BAE139BCD2E225A671740F83856825ABC24F6CE908C4AC1FC3A61AAD816281985AB215AFFD2AB0060B66885168260028090FCFF612A034C68E0B2BC83F33585C3FE403A094DA453ECB21CBEFC03B69AFA16942691759701F101BE11478DD5A4DA021781642D9646040D6539A8A8B15868852E8E233178BF9DF56D048D17A88CC5C5FF875B2AEF274D18164B16CBACF4D2C12C2DE37EDF89A76E4273C7F888820B5C56699AFA1D2322D399010926DD5363B6755F75EF1AA5C0DB58D92FFDC0D666E2F466490B7FBDD01D2282B014F08581682A8070F48E69670446E0E8A22D388F2C36FE6B4A0958BC20EBD7D6471D89CC45C01CBCF09F3EB54ECFE1C1211F5A5C27D7C12FE983CB1CB02ECA7E7400F700B78346B9A4B669FE0D7B6DD805BA558DB32952C90EFA3E1DAFD68D8A00F5406A9B127B8BABDBE01FD099549A8F006DD30D20E7773027A3A402D8972FF70A02E33F6285D55990F0D378A56F5CB27F22904A37241C23B2284DFF79EC41895ED8D37EAA794D45C1AD60F6730F423F874AC4F2DCD82539E0EEBA01FA3B1EA2042E31999291E470606C96C23CFF97270972D0CA855DCF5BAA7CAE8205932D42012B0DE47201218528A76C21E5C0685FF03306656A6E5BB15494AA2BE9F01CB9FD740B8B0FF27C852665087EEE29806EF19265EE458275AF2BBEB9848D2E1825E617AE07D14A8B3C1C270F0FB607EA823EED616B90065F2BD545A0F6782E4491994A57D785D40CC92742AE7CCCCF12459461415449C8E59F44A8799CBADB6EB8AC5E0DE34DE602FD536BECA0C2A5DCACB9AA8A46843921A382DFFAF4381776C2EC6A588437D908F0639FA2F23C997FEF001262C996B7E28E074B7A1D2B217FC28E9C72333C89577CE807333F1255095E624530DF50FFF3E3FCF5CC25505E294A022E439611827C869E5D13540348EC4BAEEDF3DCCDD78D771AFB3978D82DA1799A930EEF91CFB315521CD70B194E413FDD1635DBCD193916C3C659F61DAC973A879F189D696D3F175FBBBF0FFAE496A5668A6E20458C9920794B0DDE8D06627AD4E224E112AEFD59BD32AE37BA750624D5AB84611D8031A3C3A377B10E2BCBA5E12AA23D3DFFE6BAF03FFC5BE4EE39E6612F917DA9215CE479AD49F59A34353EF65E82DBE07FC3E9C8D92EE011A5879DC5C9AB26EAC415D520DD2B72DA37E948C56AA177CDDD4B7DA86D1F6E739FEBD5EF78EBDCABEDF4E159D15DC81F2C9EB46079E1DF3010B133CE46CAD6350FB83833D4C33AE8FE4653B4A441800AFE90D4F0CF74C4716FDAC1FA292DA454791CA823136EE844CDC153FF4AB5B2FBBD2924B822A2EA96254CA33C2837041B70B20A3B15830EF876008BE6A8E412CFA7207B35EA6185A7A1AC2B81B4A6EF72A1C2B105836D49B7F96CC9E219D3511FBECCB704DB704961E669EB3FA517A7686DD118AEF575BD351AEC67477283344ED69C0F5308F8B1F82E3DC7A5029542E2F991242B179E92201AB8AE951C0198410A5A5C7C4CAD7CA714D9D706D2F7E0F9E4E2F04CFCDB4A3316F7984AF20F4D2A5BFD44D1B1D043954DA9D6DAD6A53E6B9F3574FD8D98B3DD7C207ACC73118C6C76EDFDE760E87AC11AC8B45F5B654C256FE61CC7F19DBF91E17CAC7261A9D3FED328E2DEAEB1EC2E8AC6865D339922892C680C84C66FAE7CA866468A67BD7AC99E532BDB02A687F3E7DC1DF7B6321598C0CDB20C994F2C1D84B601D8C497264396040670710A7FACB3F245E32044F988F6534766081480EB66208A03BC1B39DAA90200A98A0CB3965FD17031252F9D8E1BA3E5A555195BBFF408C899B138E5EF0F5F83B80AF8B9EE51C7264B2EA53A429CDD28C67020FA23E5D84165409B5EB01D091918648BD630DFF02CB082DF2FFF46E7674EC85F8630D38F5814879EA3B4634B2B60E73AD8540904A4D1AA123F2B21C3607EBD8BC49C4CFB36059E0AB14A528152552611A3B542A31A11FC238BD954A38D671DEB393D8953F0232A5FC11FC99E169B0B47928FE5342C3759CF052DA0C40CC39CBDA11D9C7FC05ACE2AB35454B2BB3F44C647499CC55174085BAC97FC4051E18E48D93F35FCD6DE8CA0FB468B7A5429C3A5845EFD379686F59B5FEBD931CD9AE932336AACC05E2840A8C599A560C25570C1F4B0D4638FF832628A7D9BD88FAB4E94A185C05FD8919C91B9D44FA4B52DCF678DD0182B9F2D3628E751DDB91F3B60C29D5A0B29E745EA2A99C84471E1B0957F1B2C591032BECD263038ACF0AE3BFEF0F28CCA64453CA4A02CB58752AE9C1E3AB98363FCBDA22A23C4B070AE3B92B9145B3C5BBF3B08BE93C42632A54ED8D728F84C5522B313C007B74605BC965A5B2B2C556A12B4D8CBAD54F370E86052C63CF26BB83EB430AD5482C8EC7DAAF302063A455878DAF56D8C93A4C6D34F82ADB4CBFD4A8BB8E3E6E7FC1F2627416ED0021E43516C81B4B6CCF5F822455860779D032033719DC80000000000000000000000000000000000000000070D131A202B3137" + }, + { + "tcId": 49, + "deferred": false, + "sk": "435FA0487592C90055BDC2DA68F33959F690A4F2724A4363262E2DF99A6073EF6EA41B044DA7B536B18FB802026B7A0DBFE4A80D41CAC87FD98B09A9AE370EF97FA99BD302424B43DA240CF31FD918246429B393D5EA9E01963E7B03547A6E19282B86CBB267B1038DFBBC3AD915C4997F7547CA709F68F4E8534A0E54FDBCC650B690D12005CC14444CC088E2120E43C0511BC391D844721BC6900A0744D930215C082E83066590462164245003A720422209044308129740424888C226615CB831800432983464C844051A3268D148501B326020970008C10101810D0BA41054300299204D0045662245494832104A844D09B9500438701BB889C80248844202191701C0B805422048DAA245A202060A4021DC006A110085A238092496494000411C968181808024B7696086480288701C9811900209A012814AA084CB122481300008314C49124940A62098286D99326E0906299C3804E082294AB09140A84508019011237019171023A45018B491C01601CCC609012601A1884991A06CE4268561120E1CA840CC120D0CA920491048A0A261E3047089460519B6248B446C5C306D5B8608C388444A428123144243C669DC44080CA660DC826D99C885A31092E0446D1BA605C9C870D9A085633269921866DC34508B305158C4211A496049384DA438294192045AA24CC31090DC366180C420D930041C0511C3B085098080D9C25121014C63186E4A16262129510A9185C1886D5B48921AA94121C14998162C98844841B444CB1062CC18324400460315440B252E80348092960422B74458004A12010E4106628B486481389012952109377002B008000651883672C1382ECC24201912700234461C2182092421241150A4B28553165101B2710A8770CC983149224E8C1630993046DCA6704A240944324D521224D2907111436923164A24394C18203223970491B0014AA87140A01011394002302812A365199065114521D882640B30061BA220D3082449402599366D22C06101B34199225223B460D8226818100944282218468AC11406DC46864AC005540260A1C02080304E21417050342001342A0A382590186018154522284418C94898A43092323012004C0192619A102CC816004C906524064A44028954144E21B55084B451E2366C12018D42826C233260DC240EA1A8081A896812359224854818352C9B1492532430203192123390A48228D3B281581849D3A6895C086A90A28C610806D0486CA3242A00076911B831030932211026828288022286D2A87193142C64047200B7088C80114398840C058E803265243631049889DA4881E0825000A765C94401A01648909885588628C8142E1A8380102185A3964903B8480A996C4C92319AA269CC864CD088095400260A80510824250083894B02481B108E12304D908449644490CB289012158A1AA724CC384A59360A42422858128E13804CE1124A51B691D0A46CC4328C1B8861080849239584CB9260200661401840E438204A2070C838888C3852214761A308604B04465194914C82010AB4442385612225024186809C2271D2B689D012691CA2458C420A8BB0885A040E9A926509A22881A220DB42695C42224A325050382D9C362A12262C241446212212CA922D9A166224108AD20825CA9844DC0825919045DB402D09A86504201188A629E014310836491489401B4520492449E2203122B46DD3184D600242981400449610C0880481A65188B0804CA4110A2650133802D0960D1B17264A48410807309396218A086610B29101B32459962094968411818118A090A29210D4806158903103018C893850A4B44140C004C0184200210E13012D0249649C14084A2646CA046C0C316DA1882904C02C4B9621082208A404325B264E9CB20D1AA549198484CC10626106291A1481039964C3124481186640326A220402999611A3902C1B097011206C5A342DE1128A88A4801A49401342849B82911A4391082525A3346DD0B2051A852C4800720800840C376510930050A22D5C04711B426D91804C82C241142632C8C86D8B824800B69090C088509060E3420DC41066640640A18401C202210CB32DA0A824919051A1906189202A12806590182149244683B645E19208C212095B96050942682122905AA020CB98091B302D09C410CB368CE3420623226122B070D4A290440841541208D3326694860C0CCA61EB683B44A65D855C8A8CD65BB1DD44C7E676ED115E302FAE539B8D26405CDB80C936C02CA3ADCB2D45237F170BF28E29C52598FD7B1C389A1A03C415B2B5CB096E345354FB26AC5DE65678CFA22BC9EADE8B1AB9863CA97848EC9D5E343F1C6936186D3C9DE36342175D26A5611E46F424D3319F65787FA40EC6E0C29162F572DAD37CCA44005DA35F5C85920C0463C266C502D2BBD9A697C0E69336290C5818A692CA61F1D60487043756B9F8FB16B807E918C4DA8B0F3360FAC63809682839FA7B52296BCD67F98B5FC0691184670D463143AD983A1ADB5F1AFC845A6FFF947DE0A98CBA74D06387F0BA27FB7F45BF49E89BA49EE6BE6D8F712F976C0C0971B766AD7AACC39C0ECCC4D2F2046E3390076989789C4E8C9FEE60567BB71DEE7CAB410CC1A9AB8D0751E5204D2AE85E38786FE3F436E8818FF7DA12949B52E9D4A3ACFE5E738163BFDDA76965FBD9FE49FE834A0B8C27AD5A00522D0B515E019E4CE8808A828597F25F2973DCAEA91F99F4EAAA101C41B9D9E303C22349FB39E7DFFB916443FBF9F9F231D6A615ABB5DAC5C63636B36D0E493A66930CD8C18B8E30B51E2F35B19B7D0C6118C9CA787F65148A3953DBA871A2B2105052DAF29C09DED9D838448E7459948501A6612013C599F51EA8BFAFDAEE41C94AECA8643623F46CC19A33A20191A9EB4FF98F484A86F7FB60864D5B4DB538A0FE14D6D12FDA1629B2D6BE674A242FF199F3567623C7BB649E229281C2BC355CD19C577A38614267471EAF4A46DE3FED534E150EA30D14E4CCB2C10B5F8CA2B8086B5B6748CC76065CEE5E96B4BB75649247164DCB67750B9597CF7F0C4A883B8D255375B048FB156F4B1E587B7387BA3B5452204F76CDA6DDBA7668284EEEEDFF0A504E19B737D733CAD1503DB662ACF2BBC9B64542EB1EE2D3A589A2DB224188FAF5BB8369245839449AE58C84D907E0F34FA83FABB302ED92BEDF217903C5769581AE4D783D545A8F3DC924119BD7998CE47919824AB5590A74C5AFD2D0A484232408710EED75ACD8E2671CAD9FC7A65788D6E988A621AB764E2B8B7C35D77ADAA684DDAB63B72316861F593609768AC761782E40B4C81D84169E04EF527B631269EC3F787143623311C7181B383FA6ECE49E11722A6C5A5900193E2427B56E961449874240E4E23523BA8B321BE7A0D984E1E84BC51D3844593CC56E61A6EB08F9107A097CDB8CE39FAB34DDD12DCC3475171FE0145152F44B4AE66E4D0226ED9BE6DA532C04DEE1162AE6692F8F94DBFF4A8141CA11936F1D2FD56CD9244036C73CE0B6EE0203CD328A5E1A04E0F6DEBB5FA6D648598EF1F0EFB0D05A16EFF32D527BBABD964425135105E67D0418BB17C3C5E4C53597C5CC9B6CC27B0139B61EF053DE290F511D7C39393A6B8C5D8FA46119C93E79AD18657B199A35A01CC48AD090CD6A68F84CD512A44514F997353A43F1807221B29BFEA62B5FEECC1F9388CB72FEBD181C49BA1DD96FCF24A6116A62563F8088148D5CF697CDF140EB000FBBE2B54FFCC36CD5B90E92AB4BC8B5D6D4C47C74C5329E70D87D8361A3484DCECB0C018C1A9EB6DB8094B8C7E0F8E5B1682948F76BBCFAA1D80C5CDAA1650428E2E1409DECFA7A1AD4AD428469B6A750C74297C46C7F216827197F775CD8D12280193E0471BC7449D8EB97A4B6EE40C5D73DE0C14293DA0B4C40C9543C284F251C2D4ACD332289D10442B72C3FBC564C092F3D0FC86F71E4E4228D7E746EF2153CF2A2FDCFE50E8699A7F5374B872EE9494D5A00BC50D7D9B356F9DBCB7DF82475AC89A88C6515ECF1F2989745EE765D4B347CF8A2BB358579B7C09C797A339CD744E8A69646B122F7C5386634B5F69C2CFE791DDE0EA8540DBD30187C9AA5737B728011160DA202D96D56E21BD38DD33EEA68CF5BF69FC64985FDAD57F329CDEDACE0C8103AACEAFE3AA1CC3F0A79934F6E57B8B5EA73F2DCBD0B4FBA7A7FE06C6707DC5549E0567FA09D1FF4829D127A5B427F2ED0C071A3FB317088B689DE3585240E74CF8920AFAC2E82F16541863DBBFB7FFCDCEF75F43C186DD87C91D917F4B9A25E8AD13FD4D771A427BC43A27054CCA599AFD0F5864B3C92EF3D0F29A5B43079C09BC6BD9A7F8C6757BBC2C99A944AF3A0C34D56C91637B6CD7331FFCDEE817DB1F91F30B5685361DC8C58007FC2A95DE3BE0EE011859652F72A0892DE1FF0B21E81F6155613D0A6A58A5F91272EC3FA864EE9BBCF875405D9CC9F103D0BE1F4CFEE618EB7C9F872FC1DB88DE967CE96B9C6ED273D1916D25A07702CD27D61162FEE2646F7B147EED996F817B0CF5EF4939FE7D13D653D3A8FF35427B50C0FA54E1788CBBFF7EFE8CFD7B7FC17963CFBC817FA2D75E9FE199AD0A92CA95A0AE769D40E71B7D61D4EC90A69FE28003844A0117538FC5CBE6F1B4C65B41D9161477C23D9F601B7B40A8AD23D79699A8A28271C000F160998FFFCEA6B0242ED8449C692AE85B64D3FB0C0DD3F0EEC1FDE20143504043D63EB4DB27DB8C3FB1A9605D1C13EDAB1025784FAA92BE63714F8A013AF297BC0C56AA291A0236E444B197704A03577AE59246F46EE4AC61A0FD9781F13DBFA5BA07E956DC9F7018EF0814B9C5F6F5EE95654D6D222BF1CD75843FC1482A8445C73AA2A82345904FEDEFF0EAABDF4F1936765A2FEE895F8A933A88C485FB39F1D36C9C6C3194B46E9DDF80B5F0C3F63A10C4E2C064D6D81FB4C9243A2C8449272C1B2066BC8E8662DC7130F940EA2B5BE2E7A5E31E1C7919F09FE277B7C0425C4477AC534E083789AD5FD06976D13DD229E93DF2EA8FCD22B501EA1D6A31BDCC34C225C858E6C307368F09071963A431F5DAA9C9CA5C5195AD9545DF69989E23871DB3D6BC793E5CCFEF6D9FF60912CD554416052E3D72865BD9AED12F48FFC38F6E9F0349566692D0E1711005C5925D3F679D6B118EFFA63CFE7C0892BC58A98FC64E1D0853F515CEB10693BC9D25960038A3F0F12D108D0094F0D4AB855847DB4F8B9D334D76589CE2A0F9C17A297FF5429F239DF27899C38C6BB426E459572A4620802BB55210E74D0B23334AB8686F2F0A078BA7668235E60E487F494165BE8BAA98565D7312357E7123443D9E161E663EA4E1F6F46BF36FE77D06A220D6CC7741C96C20925A99D7919588A21AE79F6F279E23D54CFC3BBB14A189974AA6E74853A494E780492F466AB4B49678F66A4C619C3E9BE8B904E9E6B3A0BAA7539C975E23FABE9BC401A4EC308239C73E9419C686A12741D5E75D940F6C59425C20137FC8F7A36E12241CCB1C3C97CC2C6D593C3FA81BF431C976C3369BEC74785BAEC41F8A671B983775416978AB2A779B907D76BEC0B25202ACCFAC15C9EC0CE171C330A1D2079892A4F5AE3F203A941F643C3C50CFF426BEF5833996312D8E34F4C606A9183A9B959136B7CB151E4EEB84361DA76A518285790BA43ECDED59377AB75B2E221D23C8CE880528A24C0E237A7A64FCC4D90BC0508C092D25F3F429A49F8FBE908497122BD8D2DE287FFA11273B61534448061426D37F960CD06A94E374AB6D7F3C69125F2FAA9B76F8A82E32AD4905BA7925415F0BB497F546191F4C6F5283E73D826733F1B6EA5B73A9C3874887E46D7F5BAA12BBAE84474CA1EABD2A5E83DBA51145D723B670187A2D54467ECB82C83F08636586D962147AF49C5AF9971B2F0F391F79FB96E2714C3D559D196511627487DAC91F0C011C8E3D73A6274DE801BE34762FFE9D030AD0282CE0DB79F1FF2543BD92E9EBC0317189C7883450EAF7DC8CAA45554D5E1359BAB98EF23E75A832B1477AFC4BE66C5160FF49E6F50B88EEF8DFC5F4C97BCCEB5BE1A1E9D0866DC8477C6C6F937D7D458CD7356A8770B4513767B2B4D9A8D29D763EF80698CE2605D0716DB6793FC46F46DD361AAB79DDC2EF6E41A1EA9D0A912BBCDA555DF3DE04C09F6AE1154306BCF9BD366FA43A1FC73CBDF41C0D46978C4BE84E999A94F9B36FDF1ECD0F6DD24A974E7719C3D63D6637BC317589EAC60BDEDE1208E05EC87FE382D0EA7179B713EF9C5DE38631081181C8D2E86A6957E5D75B2DB09CA1C1A6A6F6797F059760866B7585F0E2C6754237980B0973486C63DCD260E5846A23A7C9C45053078E0A1CCB4535F3CEADB65CACF20E74755179AA370F4214D81E9425261CBD181D25F192454B1E3BD890518C56D43CF46B2E57662E1BF523D864A6A705EC23F3B57578283807349261BC38FBB0D856BDEEBB18B545C96530722039F129D79F9784B99A960D32598C54FDD6D3F62248EB61DE26BFD73C584FAB4ED339AD7ED4062596E7908C2111E367352338AA3FDCA8248A6958CD153C395546C258DAD42C0FFAE0E5145F14F9883706EA9DA06AEBF193F02B03F27E261DA3A46E13DBE6F20A319230BE1A6E480C159B85261C74A0A4956799D03C70396F9B0F7605A54E4F2A928C7F68A2D4EBC5F930BC381EC7E347706F27C44CDA560A75623324B6C0415B4E78CEB6467BC987845917F63849F2DC6467154E65C8F14BD7D5FDD23547EA2E10DE39EC26C13AA36AC27728826CFB29723EEF5F3CB62809BF3FCBB0DBE718704CAD9AACE7EEAF4E56FF90DBB3E0F383B3F71166C25923580BF42364DD5050DDEF64B48337E0AECE1384DAFD79A00D7903E7B16885AE76134750B9E9E4654C819979E94296EAAA6EA011BC6D6", + "message": "14A8B812B4C9129CED02A09C8AB19443D34DBCEE85AA12528B61F84A2AA9D9DA49011C8E2C3C3856FCF761EA9C9882FB18666F3EC2C8543037E54FEC1F0F944FED3D350CACADA9428B7FB7D9DA4937DA4D1859BEF8C6177F0EC93BD67FC3D5B3D13C34D472D01372246704DA4763FA73BBCEB0F4C3658B2111A7DDC01FCEAA9059FE3DD5BDF2A9FE0D1C2384E82926EB895AA529532FB20E12F1C61BCE208E48ECED036E4F84CD60F8042475749E13D8C3ABE0AE17967D5C6D8C598A53A10231929822FB01EA976A08BCC0D18B1F9B6C7C1ABDD15121E00EE80459E6EFD61CB8D5AF950F0A8FF2807C32CFF7A56661C67348617059D7E128A72C8AF36B149DD8B46537EDE60EB5DE8A16A93349883B73F7C4FB8CAFD01E0C9D7B1EBF6D7C9725651980E0DA598A6ED5114178E47EA4C6ECF870033A03F134461146717C8AEFCB8E8DB1ED4E286C68C7358FA105641EE3ED9B4A5D4826B31706CF0946C152A365B246DC036191613655B829ED1AF8044F5707C320EFA1126B90137EB05FC220F122AA990AB476EBB0BB3AFF5B92442A857F6808E144C60F4B5190794C411C705513BC32447D83B760E907E6FEED63FC0A60C0CCD01734AD55EE178E6BD6D4B8A238ECBE8E4F8A464C381F16F11BFE62DFFC5021FABEA941D24B81CFC3D0F07F00F902FC5042F95A81BB8B795907F8D6BEDB5E5C56D4B2A4353D0188A90C01D7B2781EEAF2BC3D3D58A6F6AD63DF7FD4D32ADBC5A7A2F81EE3F5B98E8052017868EE59D8DCCC0199A006FE4FF39699EECC82DBAA846AC60B51FAB6F456DE4357F5EA43FDCE4B57AED55F2F6EAE49199AE90F6CC4AAF662ACEC2724337AD7F9CF74AC990D3083FE384685A1E616B233752E31CC4FAEB8048EF77480CC849D3376464621E2BF48CBB55E1A7CAE855A216DF4A8D1AE4E4016958F5855FC395C53C23327403720271EFFDF1A90C44E93E74D71BA29D860679E877E410ADE48ABD0EFDECA426DA792271D813116ECC894D799369EA8094C328D7694E8CA47459F31F5065858252C1EEB1AC4750AEDDD327048894F7D79A1D64737EF6E8B93ADEB938C1EF31E38DD60E8B4174AE093697DE4207C7733D82B4FE92590358515D30264A408746AC252ECC0BC28A9C98BFCD76C75845E9611909B0089B571259D1D115EE0D5DC6BD6F3697E1289C4742CD99F97B5D3A22631E33A81734A5D2BD1FF4A819CD6A22A938D3F18AA90794C120F4BE7E14324E89EAD34820070F8160B140E8CD5D68378C081DADABB41D365663AF26C606940E08B20581F4E63AC6E68FB5A7EF5DF86047BAC502223AF08F6CD82E6ACDE60116593046B5CDBFE2411A3FE89C438A1E84CE6D1CD72CFD3E5F67C331E72754F6CF2BF921FDE2C6DD5481F20F509A6852AEBF55BFB4B52D1F8B3E397C9B147433198073049638DDEA7E21C2043C786C88E45E566B6A7E8742209F5ADBCD34FF26962E87CD235CA1052AC02E4BF75DAEE60A06B19A4B0A61A15D9651473DF8AAAC6DB951EB6E669FA5F89175DC1FD4D881D688C477D16CEFE809E623B2F2A996909C3E10CFEF756ECE8E93072AF27B87715953E0C48946DA8E893160CD351E48FFCC6847975621E5C75D5DBEBBFB79297AB368D13BA95308E3D576F1C54CCC1C4D5EF2A41BE63AEA2A9F9A27822ABFF58B06AD99515B97F260843DD2304C855184EFE96BF10420184CBA2CD3ABC38D11B7A74E4A9E40FC26CAF3A84BFE8794477335EB1F4C67ACC9513BDA5D8252E608D03C69D493F8876FFF25D39DCD71442707AF2681CC6D5E117BD24315B0FB5C9E8175CD42AEABF699B7B77C9A8918AB94518B48DEE1777EAD8F18709A824F277BC06CB67915A5A2508E18094B0ADD29FC7CD554D8671CFB47EED2F850FC84B1C0F27767B3052869B653BFFBECBF6D8077697D1F440019E3381FCB917F5C06008A04C8A88B4493698C1964E25A551B03805244570D0EB6999AF2BC467EA4732B460A40F7C2EDD2CBB07A2DFA99B4E5F4663A45F2774C1ACB0C8B965E1053E3AA140E973049714DD644CB9317D9B3252150CC9A525E8729ED4A9A7900B417875391F7BDCEE646B1009CA479A1295555759C5A7597A775A1D1CD8D870A71DA7ACE7CCC7D2F38B18BD66441D80068F76AC194FADB3ED5F4201F26F670621D254264A4D2A88426FA6077895B9BD794C8C84DEF942FC43F2FA115509429A939052200196CC921454A65C4BF1A6E871970A3409FB9773F356BC17E03EDDE8CBF2F91E7D2B548380967F756D36520009DA5032F20D8C8CAFCF4B561A4C2894CA13929DF2AFC2C1C9FC41968746433FACD66309D2A7FB5D90EBCE40ED1E80C12D07BCB075FED76DE423D9EE6B1C787E1039749A0E559B86C4079CCA1CA7E4A3EAACB300C453782071725F6E2DC0652DB5EBE7D1C16B6EE0078004ED1F49DF439107AED04A2E69F70A35057C36A307C8F5BC13FCEA76AA997DFD2E2E4B835677EE961234895BE9C9E7D1486C04ECDE36AF4F7075C0CED9A33C372C33F751C953A2096815D9B6186632D3CAC31AE6D0A931258014D6F88157ABEBEBA1C11B9CB2956253D4950F5B2F64476E4125848F27D9ED4F93035FB5F5DEFE2435E67DADA015F048A90EAA9780B983748CED6056D021D21F6FBCB1A2DE0C627F2D9015B3D9D35CA17C54B0FAF85D0C45A53DC2575E2CB54B9A5681FDB66C9D5A09A3F48DFF29B24E45BE82856C6C76F0B9680F7B666B22221E14DD8B22A15FFFDA1D666F4EC6ADB5B929C2804ED36077E1A39F166C777770124253ADDE6B77083ED159CCE35894597E7BF3DEDB346571C2BBF69AAA9ED133E94AC7E31F2C30AD079EB4B4452232D83E49B43DAB60BBD92673D90F187FA6F3859EEE1630D3A232B99F3F960E8BE49CCA0F1A519156D2D861F8B6C15FEA4C4635C23F2ABEFDE8589A45947D391CD1DC3439F965C6DBB5C5C9AD14192B3D784D1C78B3DF6719D5C474E02D471B9B857611E2FED83869BFE8A2A74493C25D39C78DB019BE93E3BE331131CE85C4586C0D40D676640405FE363646C2264DE6F64365F19F87A8C54C884703DD369FF52F65CD9179B8A09EB92C38C284E06B0537EE686D7BF3BD399FBA8E1703BE3236F8BA262E2C84D55EB1E1E55DC14780DBA04BC1106D98B05593F9164F1651809E8AFA0A04BB0B51F9FFD5062B495133B509A569845CBC3003BFE23A7D7ED433B70C2EAFF5FD898009CF1ECD9E9B6F37CD7794234A098CCC39EF078E3C152017CC73A19B811FAB4A2CEF721029F6200A4D1E4F9E95A0A758A7AFCFA047B6707CE048C3BEA6BC561D152AC4F161347C098F4F44AD92006090324757D73DC074F1E1D445A500AF5A92CBE19EF631D99FFF870C60BCA8515125EEC36D004F22FFB420F5CB01330315F00CECFEE3254E54A047A7FA3C7495E6ACD579A9159F667FCAC4C4448579E7A68148D5518EFE269E97D90D67CEEDC378657A45E9DA855EC55E7BFD0AC3E52DADAF76E800ECFA61F2BF532E7365C4FBC8CE882AB327961C6A48C24CF0F0E6F2C54D732BC9B592008F2E6C80F7EFA788AA6BEEF0B6AB7B21DA3F9D92ED8A8F5F3F4B1D1BED6F66B6BF3ED52E49715C07DBAFD67F4F253DE368619A306C513E645CB5F154F7823781EB3E15F38EE482757009E42CEEEC1530A0159D25F052F4D4326412CBE6CD11C0DCC56B6556DDF806868B83602671C96F81D8210842144757A36CD187EA0900F36A0A9DB85B9609C11DE03A38A9984003EBFDD4E7C07CCA7A7DC7FB5F9F16E6C0C32CF86774B46C56BFE2840D8EC51E9FCB719DD1CAC4206372126DC8EDC9A4A2EDC8FDC8370C7589CE9FABE0DF3C8CEA90E82944B8D489C0F52F73EA3E3BF56BC3644A1BB0AF88F4B556A554851593E5FCAB03E235670638E4AD77BF012AE074F331F67222899694CB5EABBF0D6E6E6CEF75151FAFE89DB9D66DA4464353526116B3C2F382825B11CAB3CBD221DDA588F4BA13548CF627B52478F47D9B61479730CD9CB3F6622702C9A115D69EC232CBEB3FA88AEB832EB266B855A98424B2E08A699453A891C89C45FED7BBA98D6E7A2179A24D41D201C4214444BFFE6D01A15CBE640C3C54458E8DEA5DED484FF7AA78541686C60F9FEE76D1A7ED1F5686A2EC1F0AA037E6CE38FF695DE0C17895C9326415840FEDC1675E9CF30B8C45F8EACA1E65DD18290E8ED826738876FE8B69DC3432174151C051FD23CA4675A75E73F1D3DE4CE172FD657B57D5D03FBF8B29E268B3EBB8E9BEA96A4750168E8AE5AEF6B34701276DD18F1FEB01FFFA2A984D3A59D05A56552639D506BAB3021D507D56D0FBD80DC582B3C20940DF2393AF24FA5233DF073C7FF28B54C7A921949960CB2593AA4F93A06D38D896D547B28E9CAFDB479B7D1BA2EA7B4A6BAD33BA8B59DF8792B22F5FFF41EDB1FAA926FA3CF602FA63ACED78E85DD7C3094ED48D1F3381BCD084A9909613873513657879AD8599403A52ED0D16AF0B3B43C672867700167323D37FD6373C4D51B90327F4981A897CD54C8E35A6A5904F5AE0CDE36440393A59119437016E8CC88894B2A6FF661C10AAD7C7B03B7085B70A8145C305D5E66CAA265AB42B34539CFCC9A62B5D9BD09FA4D3B94BACE361B4C6BF6B550B89922EC01041CF05C0E4632274949D244B7776D6504C9803A67CECF65F750F9876109167CA77D412A7EFF06CBCF129D057143BCF03CB1C1AFAF937E55477F5B15020149D64F53887467AA16C6692FDDE61406D552660B88AADF65C03FE1B8D485C57FEBACF8B11C569622FBC56CA1056FD3600E1BF51084FDAE32876BAA1E97637F73677E8FA1462222DA72FB0936ED66C16A5E892C44093CFE7B4E3EE33F21091E04FC4A07C6CA21E93A500E5D7378EC716A9ACB27A5687BCD7F4559C32F6C82E8C06E82135ED16C35762E94BFD6BC33D5116E4FB209C98C871FA8E9230FA807CF1FD509A75DFDDFBA5CD4F131FF8B666878697B372B92CDDA15D0113E8BB91A7750843B3D14AC4E8C956B44C7A3A26720E774EC1A1F68435B122E539C8A7515A1AC94D456BC4DDD54839AAF6EEDDFF8797C9BA3A15AC70C34DAF78AF1F0C21734DA32A79C1BD3CC8B2636E12B9D2E42AD10446EA1A9FFD45430E03A78D8F38B64B64C9D308D18CDDB4D5DA13F1B4D15157063E58C36DD71677334B4D9BF09D8C765FC68B233B31105D0957F1B675798E5B9E982B1BAF1611EFED0E39E1E9E70BC790886A422DEFEF325A07D97FC603866C2C3682FC651CFFCA09B8122B636A65E2D6B8B9FBE6BB9220959038AEE11AA7003A9C4C4EC9E27F4A8350FEBF1084C292B6BA9A6E03C00979854CDFE566831B077823B025FD1B9C7127BDBBEF34186C74759E32FC222023EAC24A6A6653A7073F4033D77CF83831E8B6BC8F26AACBC3EFB2328C6EC35C3A509FA85E2E04532DB6E466BBF8071FA6020CF5585C70C29320786EBA815EECA6FB2BDF9C9F3A3DDD0F1800E93DEC3C5E6DB4EA5A695865303C48986CE26346B6CEA4A734668D5BED675EB0C2A1FFDBB9E5511EC715BB4BA3604629FA28A53CC0DBA1E819A521AF8B7BFF16B4FBC6766543C0111E232157B7BE4D561618D6ED7D13AC8817641E7AF77042E96C7209F1B65C42D115234F6C63B84D381F1820CD656C88BDEC7CD2A814D6346E90841005F66D6E36E63C5906D19904EA0D33502BDED36E7D77FF5E2592290D6F29200668A25A6B6F44FEA1D3EA00BD4BA165D122455E8F97EDB36061DCB335870F44068EE4A64FDE5695896D6A5B30D7613BD8C8B11DB330AEEB0EF239C105CE6C0B2E1BD81E867A2D823FF88E3E82FCA69923E281A2933D5FDFAC6B217D60958D18ACED57D670851D5A6A445A120F5B563070995793E618F885F149A3A3D498C69A0B9D99D92C16327B7568BA8CC35128500FF515273099B645C683EDA30092C225D01E6337AC652586C0872C9C5EBF09DFECA43697BD97B86FD5463F529CF303A105194BCC3014F4458CD3BEE8088B8B05D58A960334C73E1CEA934CA0ABB2597F703428EAC5DF6983A76A5EFBB4A20221E6EA04F67273D52D0311AB99979CB0EBCE738B0BAD72F0DA80097609F4422D962DE43D5B9E27F2FB3FD55DB5B9E98C1E74533DE23930052446A31E656E150261C6658324BB243E0C55C43BB397367D9E6EE51FF7A3F4FBB008F87FDC3448C07B88F4EC3788FB04944AE1D734E00E1CC58052AD2F908B55B39C0B1FBFB889EE2CF91CC1B3FCFEF11C14B083F8A898BB28B838662274B9974AA8E83579181944CEDA7FCD9C36D5FEE67522E828D6FD9CD28537D9FD57C8ACC7B8F888FAE4673FFDD859F6446B41609135BEEB20804F4331E31AE057171D27D1C338DD976634A460436977192E7FED668FF01B7F996F00958FEF2F89C78367507225C458A7EF81513D849081E4D22013A4A8DA7E6E9AF687918486E785E2E5D4EA5CEC4F92910E6A6F89198FF7911A16D7B46BAC5752AD5F7457E9B65AF0DB57148812FFE9F7C70F5531D11CF96ADF7A3AE1D86039FA5CFD5BD5465AA1649C40A513FAD60B54F7AF15A5A6B34F0935BAB28A1AF631816A0F5F1E53E1A7DDB5FCE521252E25910555D70AE1A309BB1BAFB7ED3856618161CB41206810AACFB9F748B06F6BB8ECA8EAE07B77934CAB2FC72FFDB061D5FEAC548CDD1BCE7CE5D04E9D2E4F38834AAD674F0D540DD6EEA85CEEE4F67B1D572597E9F2B66554F7F835894E81F4081EAB2578CEB8FA95964742436FC6741A5A9D1F2257572E7026360708EAA41D31ECCCB55811D5BB7648EF4021268C8AFF001F2D6BB3E1D4D304374E892E4384D66869CFFAC575398808D2042B2A33A874BF364B6E7A859BBCC67ACD4B5DC3494C1A6B55CE004A354C8EA8F14E9D9A4ED282AC4D78909F42BD38D044FBC1C730F921A1C678062A200CAEDB0EBD42D48C0B758F138EBD6BEEE1E45BF92157E3279C6534232AA6C361953A0AE37E81261832F29CDEE864962D44CC6C3C68C05B16915A8FE35B067EA754777725EAB0BB4E20C3BA7D6E75812C498F29A94D18D90D60F49339CF46DCEC6F0A546A90E0BD6E75B95441CEBC0B25945F2A38F3EEB1A9E20805A81E3008750588397A9A168C73C81C97FEC1BC16659DB16AD7BCE275A884EF801D53868B0DB816FDE421A9D7FE37E61B699736986325592EA93DC18B036D5B237115C35AE3862E355A1F3CBECC5BA89947E6E304A86196E0AD6A113BED701D21E07532A6D02D014C9BDEF9F9060799BB79AFFB218F3B98A4BC9488E5D2CA13531842C6651621484207723F41055274364FE30601C33663A6DA49C8187008BFDB1FFF4B7B3DE89F7FB0BF57F2E273EE84ACF8EE91A5335364BD034DB6A1F8025E6522B4F3D6212F3E75AB34179B21AA28FF6911736724FDD4F3229C6C26142BE5D6F2148C9BEDEEBE6C56B6A20746875A6F74CACCDED95179AF50E1C5E09B942B4E3C5E227C1A9DCA36F04CB89EAC24D5E87D07BB407922341590A739B825AFB80F544F2B1B70D877300B46000E660A568999EB8F54A3809D6879935492CDD67DF15A1FA902AE6ED30D5C5EC1178AAEA8E539068EA2A0132EFE51DA8A43E5D48ECD5D8BBD0FEF8F90288E3068D17EEF4204D639665BA3DB7C172E99913E97613DC4304006CCB37F1E9F62327E1C2B5D97E31822A52298BE0D6457708E0E2EF25A0C4C932F16D25A277C5BFE1AB13FD488BDA7BF30F26E89585F56D827DAFC799D7DE3BEF0B41A3EA3491514ABF11E633D7F4B8A88CB6F3ECA3D48495475A33C9107EF39157D53D447308BA03139C7A1A9AB4ECB178D818DB6F83B4489626E2EE9464D7392C80F8B4B6317095926370681D1ABC3A48D82DE7A810124099E375F39E5C6683F4972556FF258996BFB0FB81C44E3C0C1A814AFAE8CBC041D7E7EA4FD830568DE534B65926D6CB83D306A36861FA2874234E33F4EA5BB8AAE05C3DBAB96CAD63295D7BECC26F5A4E862546A166A09E059293AC85937FEB612178B8812541A929B81A090FFFBB17DFC3C774C5BCEA1398DD530C5286658D326D7BA7DA3F2E15FAEB038B8A397B68AEF622EB10B248DCC942E7BF4B4C942D33A4427B685A0DF2BEE8271E89A366708C9E48F6A3992174E8D401D821DCFE12099D3EF0BA0806E7ECD674422731B0DB2B198C495E9DBA6294FC736F41EAD9232A5E404A8E918A18D7A7846E0BB6716C4343C2FB00286049D7BD823410EE8F71347008A89DF42EFE049C61CEE782102730944DD15C0DA322F6DE4EAD8F9EA549767BF02BEDB1F091252F08B34B6728165B11D2C62805ED24ABE65A8E95441D1D5FBD361FA87B39135A75D749325F09416CD3E1ACBC04F6AC8B989716C55B06FC784B0254A884EA4CCE8ECB2EA278CD32FD1FD99C3085585201EE9492B7F7A2259479B1FF820661466022321457088B202B5F1E67709B763A3A945B19CB5A6EF0A322272D98F8921B775A37B6CF92F66CF86FFD26F84547BBA75AE82411E890A7D8F1B74D657380287606ACC8572D8522B87CF26C0247F25A7F8CA12911081224128ED444C5AED9EADBFF6EEA9FB7485884093C340CB326BD467CFC4F6E6C17D4F13C7F9F76192BF4A10F2F28F538C76BDC1F8528ED1360922E5A6DF1A38AF9FB28542357231478192219477D554507A47E9FCA585730292493A2B3EE225E0DF87C747E0CED460BA677EC691637F444D248805FA183666FA65110AD3ECAEFF59B2F8F619A275034CE415DCEC6E68A3530D17EDE27E93D87EE1EA55D22045CF436A34F907D35264116A848DF0B448E4BBE32A18BBF16A8DAC00CA6B07876ED0720591345223877E26D2DF4C0C3FD8484DF1DC40F1B7D4D49E871D8F527837F1B790CDC9FD95D698231CD090C60915C98F1CE43F7825613FCF8EC929BBAB9BF663A555210868653131556553F7A36368B0D83AED6F9A970CB2D63163C607ED896FC7342A71C6A1C90A53DA0F32141600F28F31A9340ABE97D0C6E8AA3270850B6598670DA455F8E2816EF82D3267D39A8163D34B135221D7D5D98069A8233802810C7605AF9764C6DB44FB55E29470503090CE6A720617DC9D17A5091CD3267DC4DBC1A2B7032B50CE46522A2FBFEE7BE29C3DCFA1FCDD43AE2E09DAE7330D2E6F2B15D10F53EC6D607066504AC50AA7F18D3C290296A8D9ACD1F5A3708BC035979CF03966E0081FC53F654AD68A15A3D17A65A768A4CA5F647BB21872B1ACC5BA3DDB5F69DC215735A5CDCCF50D555FE968551D507A7272FB591587383DC5930C5A572BE9FE0C2797B622DA16C6B87A03EA563845B8201168C45E7603B80E5780E493AE87584A40A09AD6718CDA3759CF1940479545789F08DE83333FACC26D28AEB54E2088934332EB7DBD5829F0ECF89D22C62636063532B4361B9C7C2B1D582E9A7DC72FF7F2DF667D9B7BAA543FFA20AF6BCA1A9CC22B7D7D177B73AAB087F868AC68EA0CA808EDE0C2F931B3B0CCB28E472CB316C0DB0367D4D7FFE0C02977CD2E5B20F28867DB1EE0DA77C5935155175B33D3275426C3CC5B73748426CEBB3ABFC50405E30EC21A53073C83A85EDB485B26AE7B633692326003004A822F261D5E20246F99B03D0AAE36", + "signature": "82A8419E4D978417C3C821D056A9393685833E38237A688EBAE52F9D22F6204C7AA8F8BD5898702532B6A56388041730123C978F23EC29A03340C162C9486044FE5263C5BBCB894F856153000923BD19369563F96DBB4E44D2EE7FF2ACFACD81CE7057D8F82DA68C4C06718732002C3441CB07FD7F01F72E28BC170DC10054F8C8F75F0BC4757E2F97B0C8721B8B8462A0452D3E8A9D55EB9342B9D747019A05EA83C6548905F72B2C9D62ECF92103DF350C926D46C4994F35E54D436B51E1B165B5FFA4AB85D5276270CB94973BB49A5589F2CC9919546E51DC629D81573D9A0FFA2D52D31A1CC81A7FDB76FA7A84FD312804BA266A5882E82E71DBDB8C816ABD9A631F8619BB85E91BE69C88ADFF9DB36794D7F97617E7C118BEF10AD3178BAACC2104E11BBDF22642A79F05B56B5827D1790EBE998BBE2821CA1D0D69D5091FCB2677565BB6E50AC4F7F3D1B4DBE411692F289FC0E8DD072C3D93A2D617EFB8E3C914941792E39480391A8033DFCBECBA8710439D83A821D3224965CD0B95EF31A160334458F22C9FE4DAD9126399D2E02D6D539DB4865A780F0A5CC125537B00B581778BF1FC8125C09B319DB6DF5F9AB2DB766589DC7DDADD62CB3E67215B37C34B3D019D85E4E94E4557EB934519679947F09FC5A80AC5EDF04549B4089F14AE3768914D05E22F6FE2AD7D098C90F13E6763E8B230570A13B15F0779525EDCC704F43D8E15EED9E1FD7EE39BE339A3FBB7FE91EC51855BA72859BCE0F78983FD0CE5ED5AEB6FD5F1380507DC37F893FADEB653A5693E16397D1566AACCBD9853FEFDB2FCF300452330D3353344C51ECDFEC3D055B7B113A337A94B43F0CAD1C74FB3317EB9E08D5CF252584D7B3DFBC9577D7E440D5B70D6C2DAB679B9ACDA3545A9AE523EECB01F403F3AB123A3A6A79E89E5D4DAA2D1DE6652C09E4A62EFCD924CEBD48B854A2F17BDDCB2E332F035EAA85810CE6DAC97297129EB4827228F360D4A30F83FE0E5F05A69F115A4315E83A9355D3F02819FAED553EB1AC05C67E89B095D1B09689F1F30F6E5B1E3281C52919866F0E297A6E70A507AA3643C5A7B1217BCE36851BE4A45C2E690FEFFA210A93C8EACD644BBACA1B3668B61612CC299ECAF8413AC3DF9493FB99F1FCF7CD4F261907B6A7E823F5D7DF62856EA94351AC0B1BD24532E8A58B7E9F49BE2C0C8C6D102327CA90FB2A20AA533BBA2CD56AC0222F697914AB7DB037E53975821F4A4D12FA24D5C8E0981B02475ECEE9DEDFD7EBD71A3D8FBD9940717A70681D3A5766082D2012D534949D5EE31E9CDE629B12523C4CE1BBF0EAF468A871C06E4CE30C05D5D5CBC7B75604F0288ED84C49FA80897281F4C1BD56D3ADBEA4532F6DACCA40CAC34575BEA447DA7EB2D7BAA676971D5D6C1B6EAE7F4704E46F9EB0F90A38BA3D4E308A685E0EBC44DD79EAC9E93CD94EBF8E6557C877F5A06F11C9AE05882D653E9214C6BFE82BD52B2E74B6BDB1FC72150720DC9F92B8BBCD96B0FC6AE0C8C51CB35A167FB93E755C7BBF39914D5BF1AD32AF8E2A53C4AD96B73F6BF5987389C4A089FAFC2527779FA3DDFD9C23AF408EB7637B0FC9FE1937B153F63FF3502C70DCBFC15E1E2817F3AF7DA6552F46696EB0E71D992B391B3A550E0C2078FD17994F8F9913ABEC08E8AC2812D2DB1BC7C1A3E718F665158BE3D92199EA226E5C1E2CD56A8B0D7A780A50E2E519A81E13909016A920CC7D557CC10AE56274FD6137C292CF4527172093E8268E1E4ACE29F9635E34EB83799F9E3901D5DB653807BCB6AA5217923A7FFC77D941A878383CFE455E5D84823A5642155097F60768F494C6C4D8737423FC66575940AAA46E62DA5F0EC6F20F517CC5D7F3FF12F7E127E0EAF8CFCACA2A198FA9EE5A0329926B3AD63F2D8EAD33877D8346965E93FA5E985E5171498A4DC3E6FB5CD914595D8FDF971EE1F63B5ED27B4D74D302ED11D518004D4B68A3666658FB3636952387055D0187FFBD7C18B29AC28C8A06B284EB0E9543CEE183BB5E98E4BB4CBE2291964689C98F21FBC4505F309B1EAD2FD6431CE913EC4415C01E3FE2B75586041092E77E2F2D1BEEE3084BF9F5D9E7D035F4E789924396B52EE47C502FE881520895C0026297F7336A50CD0FB46E966D32E5098C665AEF52AB2EFC89FF5D7378B2E6972291A57D4A82629F3F14D98B707B60704B18B48F0093AA2477C297E5798D34E1EAA25E8F440D8B2E2A4C556B8DFFB7D08FC690E15291FA768C960A8C7B962C03632452AC7888F20170CABC04B091D5A173592EFFFCC7860A870691AC48D44AC35F29CB7D57971E5051349D699DD8B511DEA73816A592B7D4E1C66B8406608ACFFC09F872AE6C2B13B0C8DBAA51186CF9BC3EA3AAD2DE618E13F0079984B11CB092CD1C938D3774AD4708ABA354880F98F0B3AE28E6BB4C8E5964FA69ADB78A68B075C30E08DCC8E8849C0631B8C9236E986D2E6FC6C3982F5F1C4683D7C61B8B469B617EC0976876A69C22180C37D9DAABC654A91E991122EC08BE674E9A02CEF4D0EFAB94EF5590D5E797490810BBA7894DF86219E813108BEE6541AB9E43F68AD43477AAF5FC5670FA2FAE1B3A559AC418E674994CF8E57BDD99D2CB349E09C1C68E5568282DF501B34BEA35D00613FE208334573A9E88710BB32E68363EB76F6B9F29297DF743609622345E4395BB52B9E36EBFB5A5A5F7F8EBDDB081C36AF9C26C9078DC7833FA7ECD78A4DD3CDBAE9C56ACCC711E29CDD03B740ECBA5D0A53E3F0F9379B96B9561F80186C4F0C8EE7BE11FE864B6F2E21379698820C32C12B8D8D4AF2E5781830E84F03A9E84B66335A3A454C269976BE5CAECC27894BC71AAD3AD6A6F0774D4DFCE48D6882E2BA9259AC6460801256101A35CC1C56955D8589C91542B9CF947EC7504FAC304C57C8D862A292DB0351DBF5B5B100D037479A401AA81320680C4EBE9E3A954CBE168B24F930E9928E1DA3714BFCA4C2D55DD971EDA243A92122F3648B9E1DAFB6FA303E4C48D4085260984AA0334713C4CED4116BDB3BD10C004451071AEBC2635ED8D401AC9801C694041B8A25398C50D0C1A7A14EC42A403ED3572AEC00CEC00F51C170E3E3738F7DEA1D64CB61270E38172760A71B7A9B52ABC0571541FAC7B96A9C0B3F8682E8BDBAC16E049BD38396787004F4BF722B6ABED9C5B3B058D06D92311EA9D2C67496551F2BEB1D353B52AE714723B1693C7CA78B1D0E5F212D2DD95C34DA583C95ABE1BB4ED435C5CC4105390825F0548D2D960B31AAE5558071DA276F28AF4F96B1FDD20A51499858839C80BDB845F3F799855AEF0069D20F3C9D455F34FF718B953B6B3AD111CC5ED7AF7F0B37969A0E474B21B1908F54806ABB8F6CE24F147C7767D10D1C42EE17FEC645253BD993E85DD82C77483667748E9AD17E463925EF4756A90EEEA62E0B9984CDA389D9B784ADDEFAE9CDE3279BC9DA177D842B9C1964FADF4694D9E1519D40D49D194089D1561FF729B41C6A111B749A14B2F84718892EEE595CCC97CD64048379024D76F04D31AB78348887B53DF69AD1F376C69D7FD86D919C98CF8B6D974C425D6C0F9DCC70DF596C8025E1D60C1D0C240B02DCABF093A7CB2287A5596FA1C0170645D4646584B4A27D65452AB91F79A9AC938B0058C7BD069DF24F5982E923CE56B070C84109C11ABF5BBA299DDC0E9E78E0D34488A564D4313562530828D732D98EA08E73DF307184470E3A010B8A0662BDEDE5CBBD15AA4438552D809164BB6C3D2B2F0A8AE13C3D78305A7D3140925D0A5D7E5F14CC168673E682C5779C9A325D3AF591B88BE881C47A313395FA88B2680DA2625AFE996BCD98748C2E82EDC20A3EBED94CD3FCF8FDBBA910D6EFDF22B66B955FA84D5476686EBF6F8A29D90F679773FC237211A4958FADACAA5C24ECC9A95A3E6D077966577159A32D44DA9FCE2689326C56F748774551E9F121E43D336AA2A2766E0A1E8745B4348BD36169D11A7046A98A22C866B2FB05EFD40BF95543FFC25993F2B516937DFAF8C9211D6CD6E10EE1FC1C4A6CF29999E7A63222433A4C54B98F00941DBB2A8B0AC62FA5C32E9436F9B2A88E1E683E04E36ECACA272B9515DE52A1B5ACBBB0C5946DC21665DC7DC6CDF9FDF40C9A0273BAF5D5F052F955528441311D12A7B92F306BCB08687CBAA3C094BEC781D3A05A3AECB65F22F086382CCD76827F03F1FC251428776FB4BE1AA65FB12A07F288FC4522E3BDA80C0195A2AA683F18BABB2DEA6B8A030A4FBE833300D1F19CD52FA250C178E214484B528BF01CB674607F5D5C36A7F7FC8EB52A25645AB38610104DB09DA179748AD16E35CF972BA3014B683029DE092F966F730124EDDF09F91D145024C74DD7D48A28F5111B73D3566C1F1FEEEFE06AC83D805CA81346C85B07D80559747A94C7AC24DEB3E54CC75A73235453DE3DCE3EB31382E83E398EE877375CFAF27199B51BABB70DAA700B8D0137B46AD7AB1AD0DBCF1686481C770305B2FAB0AF378C9BD4FBF9C11FC744970B5E2716FDD7E79E2FC57749120AD92292750011360A51987CF58998911AC914EE82C56CF3ADD2B8DF00EECEE9FA4C5D1905CC1A97A7223CB86EC5F1ED278141A681D772CE3D5063754C549BEECDDCC422A9C5C7832155D0EAA42D455D7F7D916AAEDB7DE3575345C9B22F6584E169167D818A8BC670B9E2303332B91D52CEA5F26674B819927B6374429FC5AF1BF08E8D9848E92BE742A93118606601D8BD2E42E1783224962DFFB826770D960FC9E0E5F3D68B635AB2C277FE0145CC03523FD06F52597A3D4AAFBB191B9C2BB59CB4E89557D801E77D491BA4A1FF81FADAFB2AA137A1AD099F839F60F74986A4E69E73595F10B7CC6A2FF94DF6D6887FFC45E3F1A39B2B0AE850862022CA4A3495FC0944964E0C5B517130DF7C7ECFFC8327AE8C3AFB665C751471863D3E59D79D8BA048E5C07772705024396930188C65CA8C2A3B9888B9D651483F7C2E96EFFE962CD5C3C26B781C506977D761A3C0E3752F1E45889AF1A74BC14643D44E79120323D0C649AAD09FA903478C7F8A4DB3F96514F78B6D8D46195EE66443B11569170CDC7898B3514B7AD9E7165CA58110EB58801E5E10466DF42E347CC690F6C9B95196F143AF84E3A81BC412F7BFDFDF222F8EA0D6F742C37BD4DBB77EA9BB0A942B10442285BC11F631A19A25C34B01C11552544981A3A6D0BB4DE21FBAAA2FCEAB1D65B961FE7D546C7942FABABD25F3E605100AAB09A0B389F7AB58668D31FC54EEB0433DF42D64869FD5662233DD5D48F7A9495E30068F9C80D4A66FD9BF1C7CBECB9944C6B79DBBA18981F7D0ED9F2945BD2646464D7DA473B2B64A9CC1388A0A7B588328577B644EB7EFF0E62A413B56B422D9FE36AA6B2D0B7F609E11085C4EE889CEA76E41B4B0DCF8CC0E19C656A17EC184FBAA22AA3D6E5DE5EFF0C212FC82BE6BA92653BBD044726D4E87AB68A1CF0A80D0F8B8860EFEEA3A257605578EFFBC43E50A8E86C9663DCAFA6793BA37B116272F8DCC803B5E9A819827B84EE975CAF6367E421B9970175D9593402B7394EA56703B1BB241592830EF0D168A4FCB54C0F3D88A90D5A1C2F977789C2DA3ED638C08F5932E91AE20341FF9CB9F65E0C07656D9F79420EE20AFE7F5C9F49DF3C87B8D23E709D1FD3ABF9375E095ED34BD768F8C07EC0FFE9A9C93453197738E16B76D7E02163B489C6F6426AE9BB86AA9A653F527A1D93FF780411ED5E59C478FEBA710D2C475FE2B2649E1FD940BC1223CDDFB566D94C9D2B4D0C91D3DC2BCC6F73B4C586A5C0BE72DA7B1B5FC1164B3E3091C58BB89529B83C3578A82B11542FD27B33D2ABD1E3D4A45EF0340D912BF8EC24C2D315F6C9F58F68AD0DA46920F896241EFD7F98DA1D10ED22BCBEB6A273CD7B29BF273F8B6895C05A622687B2BE13B3CEBDF6175CE25607CB83E46924C5CB00BFDD6F73F2C5DE790A87DC10FD1C77CCD9C9630C57A1973AF48EE1D283964891859D64D3FFFF8EE500DC4744D8871F7C2A735AC4366DDE9F03690AB740566F611C78D3E238365A017020C3959AFD4E152588F5825F5D8DB0A840FF6C7BB1F7BB87BB7BD1BFACCC806975190166EACB26FD8C388D940591A68C489D32BBE4E607541D05A6381157D53AA2120216C971B94E2FCF834E8D37EFE65EC5F086F30C316C889DB23FFF9B152718897AE049E4A191A043ABE2BBAFA94CE73F1CE17DC47EADAF8C8882D40000E2AA0C703C04D5332F54A0BABB7641A1F4C3376345B5800D737EFF9D99BEB908EE59069F504B6B8625A2343F070E6DAF42BA24FB48B9795332CD5A9EB317FB7DFE4B2663A17F6270BF75F888BCEFB51844E711A1ADBB9A935543ED5BCF134C1F52E8CE1404F789D0BBAB14CD229F8267CD5F631B9BA284F6D633576B6BFEDF1394A5673CBEFF90F172B3256799FBC0239567DB1BDEBFE05ADB6C71E5B7E9DB4B9E0E1015E7CA4CBF706073341750000000000000000000000000000000000000000000000060D151D21292F34" + }, + { + "tcId": 50, + "deferred": false, + "sk": "7377D2CE98A125D2293896EA97285838DF426EF6D3E06D3EDBBA7C6BF034FE0C3DA0A5CCB79ED5176DC24ABCE7EE76E7C1CD259CC05A4A784C8E7DE70FE1F4C1CDB96CBC97A40CAE2D0F29CBC084E65111808FC3BF9FAF728738346768C481B8DD506B9845F3A22B533A384D394FA268F6B8C863112AEB94D469DA66C7AEC36703035149C02D0B124CC89825A2A644D4A089010549DBA0885B82898B042094064D209988DA0432D2A80D8CA08922955013A79064222401202D9C144422B16892820D0B821180B66C62284EA2B40C08A35122C760DC20510CB77104446194006523B68058820449064199920D18170C02106E12146D40024D5BC40113056AA310284AC0302180292226455A384E8C040A08980812436ED838491318295A90651B094909B7248CB04909B28C18C34D044989420645A2922191A42019409198246C1B877103B40102048201B14801212D14130C1A204D0B176CCB046A03485112316E0B4572E2325013192C8AA640D98064022001C9320209100E134849429030A114120392445CC84CE24212C00844E0B62918A00514200241080E04456858B0101C1930113320111280028689D84684121168A3A0211009718BA42C0BA1450C279214972D01354E0B230C88C0418320492047660A908889064EC2B8449B206911B20413C32C40322E53162011096611072CE2420CE0106D1947720285254B264E58A4815848861B068E12126453865013338D8298500892285120111019708024214234080C1306CBB46CD808000CB3659042124C82612219296102411A94410980490A2580431450DAA684403249C18008A1067101C38514102EE1B60C99244459006863201104134A0B4104242352929845941872892249D038494C8490200164DCC864D43440A428060BC009E482104C82411BA088192649C4B64822208911986CC9C240A03442D340710492708200651A032C0CC4118CB42CC032051938280AA30D63A04D24C03012864DA4088559380659B868013852C8C4044C900C4A026582283101A7091402449AB8691C85701C414113148E0B4084A012120BC88559C82C22876912A10122950D64B06150120A23344DA1A64151C28408C20DC3825120A96420B325E0829118C94423924C03256EA28444A0000C0A4712A226621B43311C17464BA6458A340E228830C3368518106E09038E01322C01866010C4100AC4204C2282C8C07120B848D1200200426C081200E4A8040C444063A4718A304CC8B421E406521C92509B4889842082CC406108155020B171C2184A4A246C218421A3B004D2B608A1880D63B02C02B4455AC881143606C8C410DA86615B3466203131D9240D20B530021206E0264151040EDA048E4B2822A444319B008ADA822023086D1090888AB411CAC44C980282A016002128928C44325C262159182D101571CB406840C22DCB10669B30024AC00023B84C138724A4B030241764E1120604961161068084000104840D204461C8A610A00469A20285CC14880886481002620895240840401B421120A328D30401E4381051901091948459C8299B40895498681C3712C4A0905A180D04312003B5800BA6699B28244486509B3242930680E04251E2320A99420DD4A248CC929004B9310C366C09185200238600B14C24B7014A887108A1511B850023A328C846529C40848A8045D4C6715344290AC8650B22304C28268B462922008D8844691B230110C0480B492064148024223104466E21448A09430A22056601896989228C24866D23337062288E5082708CC031130341C1022D23007188247141102E09A684133266024661C9B491C0B08403B90CD0821012312249B00C11356A83A6444BB64562A84199444C63A645DAB42DC38601609680441206DAB840233170C338925B1271C8A660A04402A026068A305283A0458A14825B268C43445222272510332E8CC6414BB025521025A0142940486522982811194E14267102336420A80043124C6128241B3952E2C8459C086C90B6050B3452C1C06024210921A06053C68013360202802C80486808A54160488E1B2784518420834244C8C88C443690CB04860A42269CA62D9132101AA9515A320800A5845A8831A2B8641434605A146414152C00C90C02B510D3A229021728E40826E482014B280690B6851B428D10C225D38409C8B029E110882024200C280512454DA807B179BE146E96EC60914E74B78099DC2BB667ED709C1DC39DAE07760FAE0FBB086016F3BE0FD574560A68A9DCAC7A44629362330AE6293A88276F4B82BEAA2A42482D9C708EC75E60DC52DE3B70EF0F8EBAA0F591197273AF0DEAD7CA2BE5F6B7F67C99AAE59A016938F035DAF644ED94B5E9B64E153EB0DC49EFEC8F61BDFCE44B28532FAE0FAA09F430F4DCBDF34CAB952FD7E7C61C8FF1C36D9CB8330B556BAC79C4286331D7BC0023B643325C4E23B6E544D62F8D1E3B8B5F1241BE69A9AAC2F124DEBBDA3127093F4EA42E9DF7C7BA388E44197FB95FA17DCD6E6562D22C933C32A73F0D3FB9081DE04E513C9047F4DBB0F1A085CCBDF80BC0B6BCB652C302400F2D4C0C67B3698C23FC888D4BF06CCACFC202830D84ECD416189D0107B2F27B173D7541335004AAE5DFFC0DC60854298B1FD961D96BB8672A679E0D360150BA1E510B7151A440AD4BCE9A997B5D330DF5EEB6449264BDD4AEE6A86B8B00E0173838F2A645C9D8C4673908F6DBFD634034D840B378B185B21C92BBDCCCA0804ED6286FBC375473C46AEC46415B468CAEB97797FD03C374E422461F0807AA53D4C6CAE6FB5AF4C5EA616D295C5DC7D6886E5816FE47313A90BE1A7B8D528B96B351F1F0379F7F4301D7C669C0D27813EFA58827C26F04A09B4D9FF4B6007FF8BCCD3CB91E7CED0CBC1D0CDAC5F9205E6C9F3A1CD17FDF88CBD0C2554D162BD6BAC9AF0390A80745C6221B1CCAC44C6FD5F68DE32A9613AC4D4F77640A04141CA967061228F4E2D7C514C9FFA349004C0251E631C10B45BE25F148D37B05E14C3DF976B20EA5C26925818058584DF8428A8ADBA8377F74658834B3A72B938DC6C9FF8F923B22E99990730CA9723F531A5BAE5D619725CDEBA78FEF75ACB0C9D3BCD9C5BAAD600282F4145BF3E3BEB2A1BA7AE035659CB10F70D11D7F0A5DF5671466CF6554766C024AF1B9914F87BD74719DEB89014A9FD6247D089063D1578471B5BEDA5907825CD0A024716C21B186F3147F3C1309968782D8AF9CF40024BFC067111A68E27FF2E93D640657F422FC45537D9EFD2383B770E3702E2DCE1BE4530D17E4FC4C3755D47963B6E0184D277ADAB8037117DED146924DB13A05ACA3D7694CEDF95A0603F7B833ABAF05EEFBFC2585FD1E332070F63B486D93FA9D5457A09D9D27F84E80D49DB6548326D5F82A56B259271AD9EA4E90875D38718B2EC45E97F556FBB48FFDEAE2FA95A2A8FE1979DD2F48047685A3362C5F08B4C119305364293A498B4871CB7F5DB4E6B62E909960FC7495AA997EE6B885D5DD0BDAFC89BE1B4FFFE06789F6AA25497BF225B9AEB737F3C21BE2C7FDAF84F495E8EDABECCCDE3B0D60AB7E5958AAF5D0C5C062ED8775DBFC07E7A54EF47C8CEB59004FA347F1799481607497CB029C0A3981E564D4290C61BDE180CFC82F5ED40F6C89AB93635AAD175D488C1BF1C9A787DD3586EE49C028D65BFF792842D76F20E643E4E14312B1A52958DCCA1D9F7E0AEECAAA07B8BE1612AB2D5076A7F079F3872D8CDB5B128835436D14323732FA806B82014022F68E04862315FE6F16EE9254789DB98420BBA3F0DCC51159CFB7EA79E248CA2D21879E262DDBDE7F9C10757164A7096F5343AFA7ED777B8E2F0D13DD0A03ECA6F064EBB01E2FF84DA3542E1DCF62E7F911CE8CF632DEC6E376690C5D05CDDB42F7B0ABB6101D164D2A7CE931A12BCAF8E6BFB3D80E6E4CFD5ACAB85D4807054C406B7A93FA29F3589D5693CA4294834542884BB92BC1C88BC27AEEDD69E3D836130DD467F5CDD6CB82C2529B1E82837864188F6BEA25ECD031A55CF035A9F8523C30D30F93D2AB7BBC53E3E632B8F432BCA0D45F85FCD007CDAD638749DD09F7EC85C8C6B6FC7A4A3D87347515C73F64900C9B788B9E27C73469823C9FB6DAA6760D95626E74F18EDE6CF3E5888AFBE5D4CE686DF584AE67B5C300E8352288BFD55E5B8337A4CCB872BB999E86AAC9EFBC559437B10DC290D9A745692795D178B9134592232A696C5F0FDD653CD10EDABDEDDB746082AE54A800B43235DFD791BF7AA582155794D67204F87D9CCC52E51DF8ABFD24A4769C423C70B256C2E150844659F68E974B277840E98A6879333966F79B7A41ACEB1110E7E8B9DEB3D09C18285BE31A833AF62923E81B2499AC91F6273916B8E067892FC407074D2A99F287E78212194CB3862AC1F48D4B520B592D3BAB72D0101FE8FAF11564C88DDE8856FDA56AEBEFEA67B7F0BC4836190A8E6433F3698C0837F049F04AFFA2313FCCA95D22744C2C6FE08FD296E884E4D8BF1C05C0A7792F077900647B7D496CE3E2FC2690F2EB4402E853DE1BC21BBED13BC4930F1F3672702D9E676EFCFC6DBE120C398D6B335CB7F0C2483E1334FF4D526D59E5DB66E2B6BD865CAFD3A7EAE254536B07B67F7D883B92E0A0F59FB17F1B116626479117418F09F2C158EFE88F082A89957F1A4A625474C970B0C7BDB0AE0552BECE8485640C4BBDBE3E57D23F8D2419D8D5FE63CEFA90B239F611A13D2768212AD616025F3989FECB6834F3644ED914D75F08B3DFBFE497731FAEC81F84136A312BD91EC337E82524FC5E00EDDC07F59823320FF38DB34224BCC5502FD7BD572ADCB0EF53E4C16A35F37AB8B90E908016A649588AD1917FD5FB489C105CD2E59470EED23C90C7D9370F6406BF7EBDE494A658CFA1B93515C9894085DEAD882195E381BDE00DE045D1E1D4378D0DD80076C647C12DFE6441768CA16424331A8E8694C8442280BBD5CB6C1B6D504AE2DA853D089F56100E2ACC709A43FADF2FF110DDE85D2AD3F9F74854931CFD1A45CC769A444CEE253817D66AC7D8D2E0088A63D86608DBE29D1147AE85BB7F8EC87564D70FB2BFE0EB6D130EAECE850E9E030E1714D9E9A5BBA7EEC0FDF5BC660813B7893342B3959D137253F43EFDC6214D20B3C3C905A4813522091FD9D35D41193ED8E8478AAB5CC2650C19E4278EE10FC1F0EF3872C4CEC40DB39DB6384193E67E7E105A781BFAFCDFA8E88E1C85C5B893B8A442B4BEC0ED103F2F01C756B92A8ED8BC184632F9344C16EA3062457171CEC635DF6B1994CD1737C23CB37C32529B8A810DB30AF3376378F3F230BF58FDC564654ACF8AEB082E3C4DF005516D1522A7683F7A7092874861D46C44F605DA94DE8B004141B30152AFADFBE54744B0C1DEAF8F13221C050A9F4C967C1E5BA7BF78F579133C47767DDA12CFA827E76FE8E4CF31483E883ADD009639ED4EED93F4956D93449659C83EC23A7BD30AF8A55C8E6921A3B16959B3F1386A517A8C9416C838362E9AE08827F45BB10C1D222694AEF09B15D79140F8C0AEBCFD88394FB764371B67EF88E64C4140F34012179A394DCACD9E1CACE336BF723BE8FEA3D5E52E455E4F49F3900BED703ACBA38F27BFA3319445C4EC2EDDBF9DE7F9A1168CDC603C2C642764DDD0ACCD7809E98E4D36C838C2A57CDAA9444CAE82CE4DE5CED4377CEEE1922D10C96392262B4A57875A95FC4418A5953BE192580854EE92AF29E0949D4FDDD15AC811279E8E8EFC95183679117FE9C43A26AD455960A07FBA34FAB01386EA50072A0C5C026D1FBDA924525F3DFABAC3BCB69A7D2F800CA81872707D4EE0AF663768506C54A9A036D4D9C3FC3C20F8CC2203CA5F8DE285F70F4919A8044D39FCA06F484084F4F29471C2DFD3DF9E6D1E1AB2DE12287DCEA64E91EAA7C9C4CAA063710F4637983E66269D4C55CF24A1CCD1F02A08FD00EF4154DDDD104040CD15F588C93D030AFB06B35D7B06C3150E00FE3421DD24BCC0BEAEDB8185BB36D4E2F7A4493B98FE5613AB335475DE06B3E75766E9C662973A3BA91C0071606E4FD56EF9CF9E174BE2A42D8158207DCB81EEBDE31DACCC1EBC3BEFCEDF6316F929740C1F54C9C95E1E890D0A12CA2EDD0F265B5C3381DC8B1C2E719A4382862481E9D990F70ACAB53DC63BD502D9C99473CA00C452A604C137921E7BC050A776F03EDEDF95634FAD43D1DF4A239F047595EF220882097B282BBDEBD72AE26AB6DB46930E9ED585943A7CFD3597B134EBD74EA45BED2E3E06601DF441D7C2C9032E182B15E6B82276D4A450146B533BDCC662C9EB3D78EF75CE870272C0271C949DDE533FFA6CB4B9C70224FD877054B500D2D6192126F4659D11DFF75F624CF2304C92CFDCC1FBF02D57BEF75C69AD9502E387AB0F3C8A225D8486BDDF480C5B10F9442BD52A0DA149E1AD34185767A663A721218C7D06AF3E6AE29F5DA9BDB16E70856C3341DC58B8AB7CC133CFCACE0798123CE6C4735477CCD8E10499A0BC2D992E084A5E438605FE967DA5A24D0F66F769F78E2B321282717FFFECE8347B3AA78FCDD633E53B6709C2025C89A6DA9538AA643B833718A85477817AD8AF7B5986034CDAE1A4816C7449C11A628577AF65AD999EB00D08AC57053ADF533B2563001D08B001A65D46970E00DF0F83B692FB8683FBD62211B706E53C4AA30DB159D14235D0AC88FE1FC4FC994277A3838CDD84A0A08061F85CC1575831E7B56B87FFEB5E404E64B72C36966323F98E8A19202FA7F3C187E925DA291FE4C3E34A06C0C5CEB76BB7F8CCC0436A0001DB12B261BD47675C2490C914401694FDC04118372678AD2AE171F40B51C6CB4D40C849320F58B877CB72B222F2E4562AFC4C2FF91267F81BCF6D31DB8BF838F6EC3A3C45", + "message": "4F4C7E0134BE5200C4512299D134770A64A76B73A82463FD8C86594939DCFD9DC55B895B32A2E96B8AFDB8CA83AB857679C372CD88754CD8A7B0A31D2ADDFD7D1BA64556AAF1CDD674F3E8F5FC0BAD2FA38326365918430AB2344CFF785D5F73F2B5D631DB29FAA0F9CCE5CB7FFE0CF4AF1C7A8950EF32F1D72080A492C7A25ABF67F409FF5D4B1E0D77268C0A1B2A32D9DEC61BB71EDAE6BFD58F274707182058F0E6AA31E6D3763732A82BD6F2C76647C7ACAAE7FB4AA51125F0D2D48351B6A3FC7FD18172FA8689AE1602C4EC0CAFA863AA98BDBB1CD8C2681C2B6C5C254E346C18E2A270CAF2606A6504D30C0E2E505C2FF9D18523BBDF21424C645AF0EFB2EA0FD21B5D0CD85C7C1EE176FCF904B481855C4CD739443F3340AE48276E7F4BDC00CD11C2B0D6B97BD00AC962EE1FCF8A73D3DA3CCBB3B72095CB33C5542D86E843641CC98E27545F99188AF064D5FE74739C54F5678F411D96A0EA043652935BFB2E37EC934327C7C841CB0CD04EC17FD06A18E88882177B51B00DB6EF1DA164245A3F2554CEDE8C84DD777F0B92CDA456D922D8B7B8B63B548CBB72CFACA540C0D69F9EF21759F243CFA03EBD6B080D23DD62945E623BC4F8323DAEC1215B251C35EA13A0F081B86E803BF37DAE6D913B7D942BD1C276ABEA3F8F74D0C8727EC21EED2AFD438BB7", + "signature": "EC857FE47C6764CF4EBC33AFB24BCB47BD927916A484087D8C0770EB6B0E09427AFC3C3D41F83FAC1FDD609BFEB217C6DA6F54792F0B7C7BD05251CB34001A4B77F1DA65BEBF1C8CC8778C0DD44E8EE655279A96860E333F8EAFA468F3B2C3CDABB00E4444EB8F6E11F4284B17979010335493869C1DAD4D88293C629900A5AF6EFCEE9D0A685D712139FB5CEEDFDF5212C4DD6436376DA5890165B11F47B45251FF9F83F5218B966C0A6CB2C3FBC25D50950D9552DF6AFDDDFB6FFF40CAAFDA74A3A6E697142CFB3F3327293B45528B3D46CE998A24DF46D9BAC9450E64D73FDA9A14307E7CEDCFF2874E65E8CCDCFE66E93A6D07BE6E27494EA75170C4028173C638D7CF1125D3F2FC66025A3B0FB83F80EFD11B483B7CFAF05B86AFA62C2E85C4DEF6049A11C4B76E9CB0E9A959669B8376359D21C26DE603C0CCA5F99BE34872B9279E50A1504C20FA0DEE99BF757F68C0759E1287618F86F157DDF2F8D532D19F77C42914FB6C3E88EED0E52A939BDF22D548937C19185516B9358B4EB34E03D150B0B4AFB629E754BC5E4067284AE7133D0D5EFB3BE5DA06F567A2A4B1E91E8D1E7AF50B463E1ED8967131D6D1C33FEB94011E8ED1074D4EB2E4D30952FB76145541E5CB643750223F6952C196D51393B3184AB35F7E7B4929647721139F7D115A9F02745B46C22BC5C5ED151C7F764064C453179B221935EC48128026525EAF5287311AB4FB87824B772C093CC21DE77E660186B8D5A4493DCF0B4EA7A751187C9AC73953F22785371312FC4D12421A17EAE731FEFAE466BD923E08BF2196A820E94E1D0334B2B86994CACACE28256CFE1B1CC5E56102D16CDF512D5135668803AC9BC931B20162D17B1861C8D5A7584056E462815E9726AE29CE5BE9547FE2A698E366865949169F30430B8CA0D73037223B6D2D97F6552ED21A2FC0A9804A5B12F07AF98D44FBE3CF12927AD586AB80953B25D308E3863D5AC23A54AEA7A0EA0786198F6DDB4CACBC2EEF4987913FA6CFCC6AB0354EE7A226CA9F46FE5C8EFEF7B9D1B3718D27FA1227A47F213794116ACBF4F120175A189DFB83D786C2F89A7CACF23825DE573274F7A964B3A070D66D049C7245D7739611FDBDFFAC21373A1B52D9DD3068A814EC08599EECD46ED0C775AEF19513622DEE75DF2792D7F123A45025378912A35B303708D0B3426C65C69B24358ADDA1708989E2D1217EC7F7BE32C37449BE2D1B843C77555EADC7B29878B71D95C420A9A744CA247E3382DDA1996A4E749F7315942E47EB1383339A1C20A7943543531A9EF0309EA7114AB0B3DC4ED9EDA988D6E978092EB9938815A355087C63149ABF9FE4D1F1B2A37FE3404F7587246F42758BBC7F8B111136092C28400D45D28E50F685240019A30574ABDC1906CDEA07B29155A71700731904CB3B49A3DE0626003E6D903C22FE058F47D8CABF213BECE4C4371A0DBF0EE89C6C018EBD8C6D0C74B548931514AA46B6AFCEDFDC5BEC48A5333476CF48704DD3F8E031F62937214FCE74DB483740CEB6898426635C38C740939EEF69B4E009F8C3D208769AC3017C827BC2073911C3B1AF2BBCDF14334BC9265A38A494B033FB887E7FF7D1C3931C483CD8AB4E5B1374D03C325D7E266F6E9D9ACD06E341AE9E4C4F18E9CF15FFE0DAC5FBBF65F6ECACB4798BEA3AE6C4123B7BDFF4A9B34DBDAC333E3ECF74F892BB91BAADF533161764824970683AD1D513C98063779BBE2F1C80B90B29F9A333CF5FB391354F1838AD2650F3B8C3519A0CDF69E359D73379FC11022EB256FD1DB270EEBED9A0FC2E25F59DA828F8B0D0A756ADCF7F1BD3ACE22811062219CB9DD16FF101BC879B7B057D8C3A53E028469CE476B136B0CC929EFCAE217CC49C941F22953084C50C31F75B9F7E309CCA6AC26A33A66EE8F4FF4B3363D8748C89115D38CB895C653D07BB99677DC919BD6DB824A31FD90BB56BA5C62546E45360AB276729F070456CDF89B5F48B50AA534C8EE341CAE2CBE2A79689464C2CF7D65318C6AB8ACAB5FDA822F132F2B5637963174A628156E1D166654A11C77B3A428B41CC7C618E03C97EA13E8489E3BDEF8AF3EC98B74EB68474191E15019EC80649A04DE49136384EF7C0831E9B3F4582402D5F07F0D75C12B57220C7E762243996065366F5F6663A8621DDE3819A0BD52AB1E64A07FB0006B9FB458761C3255E88BF794141647E7A42A422328C87F6BCCA09B8CA3D435B5815491ECC58B874A264E61EA49BAF9D0F8C75CDF72A68B1DE29BFBC0EC715E2C4B9EAD89B30315D8C5D554ABF4D862CE78EC051D635D6771388B00E50AB1C1FD412FC592ECB7A7C0F36EDB8E9C3EBA02B3FB4784199D7C3984DC56B5B19847CFBF6A889BBD98F3105CE8A4039DAEAB3CE4784DE71E3AE19C2355C09982653A5A85C554F7B86A3839B7928B2E3433BE19C4C4C2B2A23D0BB99FF2297AFF64CA4983CA89F450D5E173F930733F63E83914D771022353D8DB88A28401F785ACB7D6BC3FD5293F600299E22871422C5DC47DEFD4D818AA741E64E8DAB7354CC927FA2A93397218823340CC695998B073DF31808C41A0DA96540B64C10C929FE54C62C99319F628CBF8004977BD13DBDDF029D2902C2DA2C0A0658D85D336CBED91B1A5813C63A5149BA4771E2EBEDFEAE4FBBEE78FADE02E8F1E03BCDDC1C07C6F9C402CEAC52A98FC6CB51D3EFF91F909DADCBC8E469E2E5585DA9914A93CF36838D737CEC90718BFD30CA4E0AD7EF7BB2C6C0A6E26D0C54E2A3C038177057B079B241CC886EA58E145496C932EEF5461D2D68FAA6FEF92BB8A0EB10544E81DE7C3C1FE3BDC25FD0F60DF0B21D55F005AC9F2D0C4E9D39FBF213359AC59FE2C6489149661688918CE6521BA46491296EABA965F6109D3E521B74556CE80ACE4F8A34B57D0FD6913BA3F1C68D56E41735F8D0EDF9E2C293659A73455829F1ACDA870E9F36051DC977C828946B3B89C640340051447B2F67CD5DC2A5AD3B298E655D49019B8A8AD0CE4BB3A3BA7DC10E8A619B12A394027E27060C9CB9C890206114A3F688C154703D468461A9D4A3FCDA140101035923B27498BAF3EE7F0D38A870E85839899052C48809C54D266830EDE8B5BA0F85C7BA5CC857DDC41D6013D51CB64B7F7F1258C9B70C9A2109DEE3416880253E05B4AB7191A4E4411154E84F623138D755CBD55F9CE28CB6560A4B9D8B2D391CB52FF989A147F48BB17587E1C382ACE220619E5DDE43EA51F711CDAAED45F9CC10EC1713DB50FB7DE410CD39F97A6779AFFC4A0B2C889A15C606382F431BDDA0186889DDD99FFC7EF6A871DE751BD0D3825F1290C0853C488675B4F29DB3EE7B6D14BBE454D8BCB005815725CE413F03DE990AD6F2AFAB259E70074CE4B7F9800FF680715F3FD20A605366B32CC7632C2E703F0084A1D821B7F760A324B3AD5E65D9098DACB039C75F9DB9F9A85820CDC9A779D3722E3C35480D8A7286E2D36FEE7E8A14D32F3C192C39E67ECD7693B3280266CA07A06A3BF118DC9EAE1A23F4034CD976B32D334365058AB3C8DF0BF69879C8FDF90FE33F61205ABB6A89369DF4C96476D77B6C79C370F853E4FA49C186C221411F7C504D5CECD66114649119C26FF8000433F4F7392CDC073D51B3D15210ED8BEB5A2EB60645F8A4FA228B971F347D94B9ACD102605968AB2F7ED6635B0A90A7AE75F3E526F86F6A062C77BE9B0391BFA87C219D258E5C3FD64D3CB360F96DEB05311DCAB0B5A0BD9AB1BD36E4F9C4AA62BDAADA7404B08FF4328FF5AA0D9651B676B23855845DF4712980E04262C6D7B6CA5B4F4941EC0F8DC4835355559FEC78D06E41EC597B47B74C1E5AD7C61A987B5A88D1ED4362B3C132967EC09182E4BE876BD86F1D5C3B1632A8F56E13125C0387454E66C6BA34412E509F1736FA4FC9694AC550979AB064389577038662628922316BD7F042B6A69B516F46A56C28C2139A3506AB7B4283BC8A383748C9BC24504993C2B2B42A83C362CFC1798B342A9510BF37654FFC41A2DD3B14AE1F23F349CF7F920A07923AAF8E106A83929A85200E2CCF4BF4D78418A37DE65A5B4F9D270DD3213910E765F8C8FC567B2BA1062153F9DFA639779418EB343924567B0E42D85015BF2F3379027973C080107285650AF8CAEF9B892E607DD3321914EEE134B3DF7282ED9EC79FCAB130A15357A2B858FA77108D9B086263A08B482DCC375F0C4CFC5084D3F1181FD4F64C04B3B8088E9E4D18FB75B376890798DE7BB1E85132A7D92E2E0EACDC92EA04B847FD07B9DB141F0CD1C823C39EB20C0C8F53724DD314305A2849044EFC32F0F0535DB38219C98FD8BBE0A8CD897FE00DC500D9F44288468B03C8E0301E2555E863128FF3F9649F03275EF56204EDAD48B20E05558EA52A2813E998E9BCDBA3426E53D2A3B3C047F42FEE803C5561392887C3FA2449444D6CDFE4A89A9396F7F6BE56747961C021CDED77CDA3230D30CFF132A8A6FF524FF7E1E6335D6C97D5769FD62B1BE97675770286712A4B72D8FD3B3674EB8E71491D70508F9B9A1624C8A4F9EDE2EE27CD3205E6890FF8314D840CD3C270DAB6A4CCF896A7C3195E766F96E67381AF09D303A22C62CB1D6C66DD51028508971E2916DBA5DADF4DDF6AED606B16A34DFFFD8BD79072281351AE4C55A9136683A9B78A240254CF3AE877A9061CD17B33487944BEB504D03DC2F0FA8CDD563E45E4FBBE5DA3AD9B9D5E27A8962915B40997FD64F1A10EAB864DE75F67E948B116384DCC14CC27D8964AE7E8D70BB9B8928883E435E34B923BE01F35140CF7EC5D1CBCD0B8FADF0399453F4C048B9D4009A82B8864359B9A5BB53B98934656DD05CC8B677B87740A84D3DE64C49D802E81F5AE95321DC249A466D87CC6F64C2DCB666B4437A75C42D68E1DB5CCCEB1CCE9C68A6E1F47F920CC7299DE922A18D95CC894823B38A900CFC2AE9F23AFAE8675F89D590B0E9BB69C8BE83B9F9EBEF273D0A7EA30690F66CAA88DAF29CDA9BFD3C88A11B02763602F978500BC2DFA0898D83898C09D4FDBFF5928D2DFE9CF6E058BCC1DD30508E58ED1ED170090E523C9413734AD74CE5CAC2732E012FFA6ABF04C6B689CF70F10C04938CAEF9946973F36B3AC4EAF643FA5922BBBCF32C6B648488207D7E7E236351BA4085EDCCC8C6F3BAF37C2B532A5DFE4AF3F65F65E321AB14E3F7F75B6F2930F47BC93FA683842F45B7AE9B432E9D160F67B45413DC31C319ADCB4E075954C7E5C353AB7DB1E422F123C97B83EE25F8A8A66A8F1880819365A8E53BD398D8C73A5EDC546B84780E0BB633C082AE93B0B03ED6C8CC900FDBCF386062516103F618CD8EDDE18F8885ADC860405234121CAF7AA1F9C31AE56B8BE807D8A51C67DA0370FF637D085CE08BE04834FDD95525164A1741117A6F15795D70585BC8355636448504A5DF0576D94FD542F8103D418E99413873D52D11EBD6E46B23CAACBA7898FDA32B33D0CF8B7A4A25611834F309B1AF06DE37B3993CC77EA755466AC4535C5970DAC912D0F8DF0DB18FFC17F8B9882F1DD7E01583B85662C8003E0F694AD2FC72732490A090D25F5933AE71185ACA1260F4719880BB46F1E22F56661BB341AD226814C73FAAAEA6E054D01A5E0A66B525DA998C8CEB1D90125B54D5599BF4714F5D6CAB9D7D205D90D1D0A1CEF7D241CC987F6F9767E73DBE3D734393DA178C72B1F24DC9C2F1E5ADCF10EB893AF6ABF157477A88DA0853E01B7F7D34DD77F429E76814C4974B8D8C2BA4CD8977FDD1156C5CAD5C75FA438876AC8C4BDD8E44843BED62F649E7C993096D26A77B067B4505B9FF6336E30D2B36D1B0C7FA8202F1FB584E47F8C02D5663AAE87575287C5896E3E6EFD143F7E0DEFEE4389EC579EBC9C8D75BDE56B2F7AC703AC85E97EBC6C08B55A29BA3A06C8165FB2D03889E300E39364BC4CD856D67291524C81E884B5153A45D7B53C66751E863594D40CC00A9B23B9B22E40AEAC1D9F12F4D4EC0A73A1456506AEFC318F8AEBBAFA5F8467209F03AFAEF0571863F7735C858776CA4016370AC39794B42509668791F614ABED4F3B31FD92E52E5790E0EBB47344D62E4254935EC21FD3443B62C6CF46FA9E82CDC3A2B58958FEB91AF1E26537BF98734112E2F8C70A4CDB3AF63F60F746339915AAA60CA846C4E2DA28B43018BA24D9A34D348335A4261CBA82A7C390F86B51FA5478E1053A5D7EDC07F2322AC52E0BCAF24FC665928979A9E51079F71A61144A8F13B7F979303271397998B349F1AD62B53EC90D0DED31B429A9448ACE6672AC28A74FF45CD596CE60D64AC247467AEB4E54C6C9A46719DD4D98D37642BF87AF933EE2D0492115392AA79373948D7D4E3BBF67C46E52B1CAB534FCD662F40C0B1F8EE5465FA0C40D6D49DC0DE315BD972B3EB87CF6BB182D507C8F97FA061BA7AE4FC2E5484C5D769AB5BFED418B95AFC1D2D5EC1B243D40586974A1CBE403092438565E8E90AFC4F0F30C474C507BC9CCFE000000000000000000000000000000070B0E161E28343C" + } + ] + }, + { + "tgId": 6, + "testType": "AFT", + "parameterSet": "ML-DSA-87", + "deterministic": false, + "tests": [ + { + "tcId": 51, + "deferred": false, + "sk": "F17916D95C512FEC0CEFA6A15C9FB3BF84FF8D7FA35522EB1C915C4D254E8935248E3C08582B745EB2FD13152B5DAEEAB0728042B00885BB92F844A86B4262035C9F448A2B78EF5DB347E0250415E1015FBB3431912407C85A2F362A85A9AE427723BF62697B77991B3E93A381133F950D40E7C1ACBC17E4F1D10CD1274C8D3C8402020AC5101CC34DD0947024C08994084DC2302063C024E18040D0266810970183C2915A902D44946D10095011A70DE404899B808D40B8454B860DC8B605C0C071020906A2002D0B2486A090112016821B2442CBB670433605DA16259A346CCBB408C4169024296C42900424064684126DC2260088400251C8409C162482182621060C12C2715098914A40284848215A18491BB7015AC648A1902C14182DD22062DCB64900096D40A84D24C8244C060880404ED318881209918B1231C91604641072DA849192C66522104818C90014446224C16040C6104A48289B4466911052D32652D8A60C0AA844D8260C648645442000D24885DC4632C822455B008D20A54501C191A2128420470E98A825D9A04DA4062D5BB00821B0804C102CC49871992424A436714BB649E1920009924C8912491A392AE0226961B25040268EC9A2080A902413350621246260B001E3C6295B2889209070C4A43108421110C071989820C4A8291A1532C4866C18146A024646DCC24C81026D49164810946C0A85909C348454242549A82104A62C610001614692E0A644E20090C8060690B82D0B858520230D83940454265041922909162054C62D81C88C094444E206301392490B1748932886D8A450D1329108B805A40262011582E3184283C644430281538804049831191846DB02891023810390718326891A0105CAB0014C840910118413B12061B8411B028C09986183186108C16D448609CB888D93B441589081043108D1C40419B44C1C8820CA30721CB58513273284B444044220611852509644033886E3483102826898069023280410180D1028454C846C09367182266418C6219018220A3708C49428E2302C92B42463467052960C8BA405D302850932924912211843280132450BA5501416659180650A446613B64C0138711149282243020B340401169180140E129301001180DC2851118785C1342802A211023844521464C2A0011B428CC2B271CB1600CC102104125284242AD34812084408818844012350C0A2098194500289610131881BA261909484912409031822A3466010164D48848911002ECCC0408CC051E44262DA241113194693344C424224C448900035801B98510B41600C25469AA88912864CE3160914272451264D1B0210001728D4A84548884801C70D93C8405B024951024A014210E1089003854811A8688B90085A020C5A18501187519C3892D0448210332188442D24280D22A330498825A1B2015C40201C0372CC968C51A688E3920813B0085C384403478E93124A882048E042208190094B066DD29010018249192891DA202A2085400A168A1C8360CA484AA2C850E4023188868853008960088AA2020A0A34450304421B400989A0694218494AA88C999030CA38910931728B442952A28D08146EA184501C314619B701CC06291109204B406640C449001324D0A284CA1629D0C084C88844E120291A97059042900440719C324E642622933666D30649A326514CA68984368493466D14078D182942523472441090123781D4106404A5088424091C088D02996C1B30500989811930485B144DD920200C012A00904DA102641C0301C2268C140845E312480920094140619044214906914BC08422955123380E5C2870C2402C9418629A304AE2864C5C108DC212219CC44DD996880C29451B456A1A006091300C120069A2A0048100655C388A18058948322481C64D609031832212E1C26C89009014B440D3B84589247009266CD9328A83440E21446199A42044162E1AC20809986C8C188C0C30628B46458010212033325A384C9806451A3309823444022009590041081308DC186812478643B82162028D5C100D609665A2224C83180941084163C28013816522039204A94D1CB04480C62400014422118021956409998CD3144AD1982D19314C0A924013984814892023B30D14986D1298059B14065B26910A380908982C19A0454426000A0521DBA0695142920B4300D1420D81302813C2200327601083910A537EA14F11545E254FCF2803952A580A4B6C9B29103D97436C003E2ECEAE2028017FF1D518B0B5D5E6242664ED337CCA4526ED5DB5EAD8BB3116941CD0C8F0A7ED5A1A5A00B98C336A9BC8EB6B3A308316F117EAA80D4B7756DD4A91DAA58E80D7B577558397AF905B67C59F14E12C158D292CA6B641ED0C75E39A914FFA1A9F24CA28F200C748DE709D15D722E7ED2C918DEF08CFAF9B7E24DEF2D51A4D420E7E8906FACD9A5A98B0D1D5345C8B9AC0BBF4B15EF0B46A8E3B6BAE0C6E9F092EB3EF1D49620B65E7DEDBEF687EBD0EA095972A56A0EAFB2D75F4321B80ACBCA32B1B11AA576FE4E0CCCC205212654296F0608FF38369AF19807568DBE171DB79EB8C1CB76A8EB95B288C9DCC620BEFCE96060F45A6A2DAC22F55E47DC7BAB4A793D9658FE27C662CA637008130F100D965B478177AC6DC35931A5ECC5F933122402C170EB8E0A41CB63FE5602F7B18E1DBB6DB30A76155C6CF030F738DC0916DB180F83F02909311CB6B3B9E553FACA05223B33C69602D0F05A08BEB84809651999A5526E776F3DE39304A5FEF00950A9A810D12E01D15D886DB2675F654CA17FAAEEBD1F561F9D1A95E0BADF7C3315AFABA8D4BEC1F0542A8F10AC666FD8D0C5AF1D6867A9D826BFB6B030B58ECEF6778D2C52BF62CB34B81FF936DA33EDAB31DB39AB76366D094362F046D5078B4223504A12BA0C7B8E883727718509BD47A696EE9880CAFF663612B9586303D6DE0D21F9A21962278EBCE60A6D46844095C5F892DACA48D782822453834B4E42CD3A1FE3987356EAB11EFB8EECD8E9CC8F39A0FF1FFB8069A441F851EB438E9C0B57E8818A322651E60F4B67890E5ED7A0FBF7536C3FD50D0B0658D7CCF275E8A9E9FBB99BE2E5F5E167BE290B7E96732F89E40D785AF25C1BA61A7786D3EF2D0C114D1048E7646DFA3032BFB7A51A63605DCE3E1D8989500D6E58E960519931DAC9F14DDA428F5A2C9C74D916D907707B53EB52C44AD71D727826EB2CA68070A6F0E47FA16E52E9629B7AA8241DAABB19497A5824E58D72675C3A67E10A119B274B84D9BEE2871728ED2F94F8559B97F979AE882EA549928D6B1A9A4E4A229F6EB3FB1A434A0FAEDAD62B70330CFCB24CB3498802A679F8F54BF83EF34472296919831CAAD59EBE83082EAB67D4ABD90229A5E93A0B580977F0813CCB15ECD74FF715FE8DB5B05CEF37D3493BEDA270584944C02098634514DAACE7047E47432F92ADCA491A3E0961A5D9F0144852E46326335E215243DAAE837927FBFDCE691F49859266E9008168C6A5E2F609C80C68E0820E72719E9B5873FA199E197F9C494AA8A3A65269E95B761B67BEC6113C144A56989C5750D450542CCF81B2462092F70715D4914EB2CAA3174BC9EEB20AAB6C640F8B5D9C6A0DCC6F0AEC97B3AF647EBF80034A43BF319BF40ADF79AFEAB5890D2023BAE02C9FD02C5BB65879C1B5EA406029AE77845CB994DB8C35211CA1DC881F7F20A4706505F29D9CD1989AD42B07EF52D9654E28E3DCB830008A1BE3199387E066B28B315CA1902F4BB0EE63FDC4C93E1AB886FD7425261C37AC58762D03DB60706887E72CF745A446DF6C6662F53DD612471A434AC56C4BEDB3C9F3647E6032B3CC0990A3A2E87052B36D4A162424E2D399E1BC237928D0BD77158079CCB208B7195079655BDB76CBAFF447C34C5829FAC199BB027A08006508D56C81D187090E71024DB7FBF3A7D64D8FA4874A8F470377B15380096822FFE465571B50C540558BA50E90EB81452F41275C2515BAE0592D53F6A6A34D2A34D8EAC6E7A03FBDB52494F4B981B56C09626084850C7CF962F9310722515A62AC085A6189ADDEA381291135731B2EE83A4F1EBFA09AF80A91268A87623CB557C9F66DEB454FB2F4FC2648F44415A7BEF29962D5F7C16E78579F526DD20E9209B6CA6DFD130F92EF724645B5B84D8724F3CF6F3A3B2A9CF61247A54BA928F53EACBA7E6D6B812C4CE21A18BA8D11450E70489BA572E5EB9A7722D9DC6AAE4F957936009E26EB3E74D9F9933F3DB4DA0A1F5449399B5E1010311F87D92C187AD2EFABB0A2C86B7D7F9A072ABC0C6606DBCD920177A225720A70576B8E82D7D53C1DFA48EA73181AF0AF086B6AAF80AB24981F275D66D4FBDE2C51AE8E8D45833729F45030130BC85B2BD9A14C813A37F1FA147F815488D7A17C0C039EAF866CEA75F5B2EBE05EF3109472BA5F7CFCE4C358B6080400C5CC085151492D13A5B0096A0631FAA30CB48F2DA873B857DFDB386D9339818073492559A0EC2DAF3738E1588B098751FF0FA1C871B22237E5CD15B0E1728EA267166C38A7197B6CC7DAD39116BE61DF4333CD7C2A413DB3063D7F0228C61FADAC3F8C331F44509B4D608531F995D15FAB119D847E6D8549575B7D850B2600E4D13646CF96B6B9DA6C62F2A80AE0258A8CD6EF4C55EEA7E78D20A464A194CECBB01E73F3276D66E12AD377451BBB94E5C948832595F6B6E382AD142D9F1B8689795E9EBC32A5A101E696CA34ABA005B4CEDA27D1200FE48FD82C17217E508A8484F0388345C9DEDE2A13928FAC32921842F6E6AA5CFBF57FAA28F43E05E9A452312502911EF9C33C811EBE7CAD730623DB7048EC218C7EA9DFC6E1965A9857E9294C4E47F4D9623CB74B65F7BB58622838DC44E16D915D9596555CA3D261C9C2AFCCBAF5AC03DE091F0DBEAE1B4A7E3DEC4390989676577A053684F57868D91FE6A5B7D3D7C7950789E89D83883BC3DAE55CA3078B08D991831BA91502A5A3354B88E159B0AFFD25B0DBB72BCD6F40465DDFC00FF8B6339C067095D6C7CB06F3BE759C52740395DD108296F2BBC2E7A5DDDE3D1C35D18BFBE3968EC59ABF85C1BD2928AB2AA678A7891746E88F439F8B4384031C3EDB73197E52A4E773D2D8B7BADDC5DD0A7E44C808D73B8181D191C3C89FE15EA90D7567E8916A337830305041B1E94B3B406DA4C36BEF05D9100AB992A4D562533730E0D8C052B3A62D3F69A83A0C9B2124F12AE7DACC978C4A0ADCC2EBA2D80F494AA16EC1E8E71C79B02F3261B6F9868B8D57E9D16F42B7CC66406549A276D371437DE88B7F39E74087CBBC5611680312DE8F0C36814E174F91EB600CC96E3CF51BB20258877A2AAEB827F7F5ADA80786B5084C802E606DEF388A39CE4F0D5BC19394CE841E2D2AA7425230580FA6675C51741D175879B4D03C390F652A503A7516A1F075E3082D52C60B8642A8240EE944D5FB427376B40B0B282E19AB908CCF20CA926116490AFED57EAD0DC0C8E296C79A48D088E837AF067DC029EC631F9933EE4D20746E64E5F216755A138974D308293736DC18604276CC418BA69F872B58E7F6E3A8B846EBAAEB383E7F890F54E77F5D7F5D4A58DB783ECA049F186171282BAC2607D51B298B14938EFB1928FC8D07806E8C3E73B4646BCF16890CC1380E7B633502B3EADA4477502E2467CFDB9ACBD1C72BC6AEB4F41E1C23C636839E357135F76BC39C4F9AC1CE8F1BEEFEBFF8759E8F71965D4854BEAAD0AFEDCA9D4D6BD1E63D348A42CEEFFC170D0EE9F136F5BE9901466926122F948BDDE2A9107D2A98BA2DEA6D6F2DA17724702EC518C03753D51EA831E95CB8708D5DEC822DB737E44143C86F47177D85CD098C21B9BC800DFA9DC26FDC261E921DE002D81C159F8EB1FEE67679D621ECE6B36D01C775A1645D52292B4B2B8227318772A8091E9EC017013B195EBF4EF201F4E881C493633C07F27C9790DD8AECC9449CF63BCB11946169ACFF39542266B0C6685BBB080B59F117EEB2A73382B3D187C0680C5AE709070DF03A008A7AD13226F3C3715392052F2441B4A178D7CF70518339CFFBB54A6D9B9CDE3B0B57DBC79F4E47AD6274CE2180C92AC6410E50D05F6665A57D4D4476C2C0E6EE0757A3AFEA2B1BF86A551EF98AA1DFCBA96315959452B2B3A2FCBBB955CB3FA1EEBBB83BD178767C02EFBBEFF6C7EEF94B55DF8831DDFB7B202CE7DE055EAF9928ADAF6ED0E3159CA56C483FA3BA3D2478CA394824CEE6ABD59670953EE80D383AAA608E15851135C1CDEEEB5F6A8897C3C9E066AB4734FDDFABC3BC3BA1206BA5434DCDEDB9D8B3A81A2E638146D83F14F06E56099C0C8A0FCCDB9ECF0F3D88DE3792F2D0B651B619C571B69F4BF8E7CD1910F266A4DADF8C2ABB4AC05BD1FBA058C0394C016DEE60C66401A17D13459547933389A356569ADA532C9F487698855A4D7BCCD0EF69531094DA4086F52BF98CDC9A4B0BC888DC3891A76096C7C483490E952326AE402D8DFD2F3DCCF1AA5D7BD698E2AA88D294813A88FD31866BCA11B3B91C009EEB667601CEEAFAFE97C56FA33F9381F3E4329901AC3B7EA7032C019E5C8A8EFD7044C973644AF2BE420A033C6C2C7CE0CEA3934DC18B42ADFD7A846F42DD406866A390929026ADE5C791B5F61F942B155077D82F2AFCCFFF85B0406647A9627E3695D4BEA3D58A63E1718D184E46B5F4BC8410334A4095D0FAF306FB9DC109425C31652D06FF051A162EE2B7B1C54D6C7DED6E395AAD1A86D03B1B6C800767EC14412EECE134620A61D369AF49E21B0D14BC4230649CDD3E9FD847AE50BE962EFC8CB0F339F9E6D3247533BDED8711D461D4AF2AE3FDD1D7D2A289C78CB19F3CDC2142BF52B23E6A27B39D699543C3D639B9C72CA80B37EA2775B5E2681F0DD01DFF0C05513369062FE", + "message": "9EFF341506D18BCB27A7FC4EAABF5A7C4A593777196F664BCE316C955B835AD4C9F5DE9A2BF89615DACB9C1E618C78E71144CD4B7046F47D9A600E9CE66596C4C55EDA23A66CC118A4A7BD0DED00ABDDCE53FBF2482033A4188506EC113BBD98D9891F0D69463A0D36156BA3EA0D02A14C1FD7A3FE704EE56B446AE179F72E104AA81AF0A2F8FCA6F6F96296059EE8826680E43F4B0740F47AC10566ED310799AC7141D38F6921315F23AB3E64C8A770AA57128090DB828C7BAA59C3295CCAA238C75FAC0F93DA7900741BCD94BB9FD3852EC2B7D33F600B1D51666AE222A57AF140FA049C2C9F6D0FE6C0F1E7A0DDE1143BE5CED7BBE232CBFBD8AE00EA5FC165026D729DB30F6AFD9973B6722C07F600665441E30B7C5FB297B8AB969C06839D331DEE96DE48687DC9DA531A95CA83A76F4B076DFCF483F00450E51C8D34D8ED8E4B3DAFAE664B6DC13ED88E6D63027DD438CB74F412E870CC9DFD29B52ABCA169C17E974758E03AC0FB7FE564508E017A9B4749D641AF0DE384088FA00C6940233DDEFB657C181C82A1B6A31FCCF4D52C9D351E6BDFDF48BCE414607462DB769F9EB15925BA9FAFBAB229B5896BF1F8E47DF17C8208DFD59604B6052CD2CEAB56400F11C4D9521E1AB8274AB5764C73E94132420E32B6AEB0763378D9BA68E1FCDE2BD6DEDA3917C000AF39B78F4CCA7C8FBF94B4CB8A8116EEECFEF0131EC9F2DEDA0140C902A8D6E60E98B3CD9D9C75248BF8845AC0D7E06BA0E18310FECE986207542CC1EE088843EF74A26AECB6D06F0FEFE1B72CF93306C32ED28AECC55BB103A0846D0C84136DB0B054F3DEA39A726C6FD6597F9B038CC23846017638F44368810D86293DDFE54861532F85F53F093048C3E009C4321127ADAAEC6A5CCE03E0D9E91DACCABB2F50E01EB2AC2B396D24B05D453BD51D529FBA51E46D30C56613005ABF6263B98D8DFEB52616D1CB7892181C2FC2E2043B994C816658482E0606348378A3CC8540E020273F10B69E2021A92D9C36CC9B9779FE8CE7A499AEB53EC6DDB4F2EC22BFB452FC5E797D3A2533260006FE6DCCE4E97665C68C3993DC7EA0BD4BDCD24721B02B0902B1840DDEC5182038762D55FC11B9873A0DD2EBBD55ADE3865CFF3D545F76335369DD9E70B0739977F6E98A6127194A1926A697E47F73E04FF5BD525E8F1722008F7C155CD3ADE0A5B66A3136FDD844AE5ECD6C8277C3D07F39721E911950E12820883A6BC8A9E793280FA74FF21AC2134E6BAE713F4389C9E7DD05BB4109B55EB92351C0EB921A0C3FACC5008CB85C3F2D5F9ACEAE9B4B714825FDE2B6263FEE1033074F59F073E9395C0D8BB5D1EFE5BFBBE180F7C591C172AAB05E7C53694C377AD27B9D1CFA0FE09293405DBE1CF8847A351F727768E2AFA56B54FF537CCD9D6A49D1CA745FF5DB54F860A74166DEFFB0B2F92106B7814C9CEFFD11D563D8F33A81C49D1BA83773572629F8B47F9FA27D2A632C70081E2EE7ED73ABD24C027EF11526E1095C2913DF692925E56839109BD05ED8E2C9086163CDF945BC16DC804C0F61EE8F3B72DB0245F6786981FCE0322FC2AFCD4E8E5203B51C7C372C58D5E292A7E2496C3F5D7F2B26701C0C167F49307114EBBE13F4F1AA5ACF98F20729B5128480014611A444AE6DE0437FFD5D84B56E3E550DE86613A9285A10840BED0B69F019699B34B86FC622D325269D1A046B53A4DF1293A52CEE1C35FE816B67819207E09A02C9D8594D51E8B314552FDE26DB7CEB8D80124A8A1C33748E05C1AFD6E87B567C41E0E73F325F25DD2F482190C404421A3D6A0E5D5CDBE2B0188BAC77C6E35D77C0A32B1D9629F88E70A765FEE38C1AB23975B945F2161F6CFE7E682AED96849547051DDEB77B90F6AF00747C47E02E80B69A0D4B78A47DDD81E299271FA78FE423ADDF120DD04D46C132E970F4A04E97A588D27C7BA84326182AAE04C251289971691D9678D409881688F3BCCB950830E65B784841004E404458E6165963CFB4EEB505FDD135F31ED0147CC9E9877FFF4107689106174E7666EECB6CF2DA9C9351DC434A9449384EED7F5F9077B42F0FC5D9F0F5F7219132FF9A470983E19D30A4F37D189744D832FD5FB397494E11ADF74F4E900A4187CFF5DA8F6D7B35AEA016A8DE8862265F1369FB367EF1860C8E07C33F3282B4D9837CDF3EF658422D34DEA41E56DD18703681D044E3C403AF33D1E7AFA96A8C4435FEBBA0D25DE0E4AEDFFB82A0BADE76B66CA9BEC7E9D73F1CB29CD73CF00C2F6044D83453CEDDE03F972EBB032062D0A8239FB699EC890D320F6FAF3D207BDC9AFEA2028B8699562343AA50F70A4E8C62DAF8B8CCA72D024763BAEC250023EAE825C651ACC4AAA0DB6C5EC7EFD071EDFB95AF610B6401614F4FC6362775C3810A9A2169F84A21123B031CCE087D520E99E262E8812E84098EBE9BCED6E6A4F73B674541DE0BCF5E7E318F906D901FEB1D9D1CCB6CFFE850DBFF75C8A89F43CB94895F28696FABB6ADCEE7697E60090387436E19B138819B90AEB18AC27D2C659B0DF17794A72F8BB7CE03EE9A78FE8C8A3745D505DED88500F4CF98FB6285B0BD82E27DED933BCC1873F88ABD828F6047ACEC472DEAE87D8ADE0AD07348FFAF59C17029D84538777F73BFED5C63630BC443E0FA12DE722DABBBC2250ABA3FD86154EE208D53A327A7FF26A01793394D04158BB320600447E2FD7D7C6DE076A513D68195B067204FF6005B1625542B28372F06806053AEE2EA9F88AEA29A2702154BF443BC707D0A96EB06CE43EFE66AAC1F1695E28CF107193D062E71B63AFDCF9E050BBED7484EC5E80C515AC820F0CDF965DD97F7A11B57B21A04BF42F2A33D619764DFB36311FDAD8C83A748BA3442C570645A785E6703E5BF22E846FC516CB49915FD63B63E5DBF56F55EA40116D5034BBB945F58D67695C796F1C1D053A3EB28A95E8F388E8004C3B24FD5FCCA7BB1E3B99A9F3C945EF8A535F137432071A5CA5B6F7DC7B8BCE55AD0F3B6CF1BCBB9CD35E241F86E4697272648F473DBD5B7681EF0C78449E6C5FA930D832C851EED2A651219D7D9C3BB23F3C6AD7EB77868541F3CEE09F51EE04EBA1BBC29698AEDD3C7ACEC4429D7A40CFABDA2293480164F37ECB673F2B5D7515743AF7ED0B6E096F0E2FECEC89F40D6AFE0BFCD70379169998CDF4A20DEB6C67AB4E36AAD53EDB98A1361C5E9B0DC1636D751A87B52053BAD5CD2BD6F6BA951A7E87EA4B677AE00893A1F76723FC56C494FB5CA2F5DAEF8589AE25B5476F4AA89D404AF1C2665ECA181062A4B5ED590B8263364153325AC979ACA1B6450828F656AD447CF7E937DB3CBFE550A469322B546ABD60559145E1BD42DAFA318B7A0D71170DE818BD664FD38BD29924180C44A6D341BF059A0D64855D2A5E291B671F490978B0ADD90EA619B30A62F5DB4EE7A10405989AC306E9C7BBC117538002EDFED874730FBD48AC6BEC720C83D51056748DEE2BF955E7BD7C786DF6857A929BCF8E381621B3758F2FFEEE8280836235B24681E62BD27C26FE9636753C78AB5A7EF29FE60AC29CF67409FE657CE653A2FDAA7F20C5019E6F7432E8CEB9E9992E646B78D4365FD0217746F7BA31E069D754E05ED5A71FC5E7D6D645EAF4144D6BC43055E6CDB8934C7026408AE96535BA2DECD2F7456D6ECA42368CD9AC5057B7D1E12F77AA87C437E7A43315DA081E53AFE23B5BCC2F4CE3A8006E81E08AF0A33C1A9307C8D5AC59389F26924116CAB0B87D549D0383C274E8E85D46E0FCD70E36842CA4C8D6D0F48F3EDF9E9435DBF5575F8EB789372758BF5BDE99DA2B98183DBAC82D1C12003724DDC42AEC81C0C7822772791504C90EA138B6C91DF5D25369CC2064FD5E2CC9D893BC4235D8817624EC9FAC8EF1D45E1FB58B38EBD8DAE12FFA037E07F5B411D4017AF952D8C42C61A2A1E8E7025D6D3A285AA17FF0DB439D0F2AFA04F318D6D576AEDC6F1E767A66FB39B72C67F05AF4087120DC898882DDEA17C9532B27AB59DE40D75D4175BB49273AF873A92DA4D87E253CAE72A5264E0C1DE4C9CF91A1F3AD605A0CC8D919351F9371AFC68EFBCED198E4CD1B58CA285DA0265ABACAECA8EACF02A4FC767162E247F73CDD73EE3278AF94AC4A8CB2B01556834A3C0B8D06D05F23B4C1747E76453F49DE08DF8EE0EA625647D1BD080E73C4197AECB6A23C25F00C6C54C8A4CEF76659528B36742EC17FF0EE37B306DCCB887D663365DC9E81D5147CFE5050DB409DFAD889C386F12A5CD0C95534113A6D0ABCB5A3F56CE23EE32612279E8BA239461258ED63E7883E115BA0581B81A7F73C1B79F29A1162E6E84C715BC50285FD38D4D6DC08768884BF4FB55853DA7B5471E73A1478DB1E1CFE6153EC6C378DD6A3F42296E619DE763FF2DDB83E51584C28DD8342E929E15B7BBCF5D6ECB8779CF7F3A9AC16A431F52A234E6A3699D9E44840A4D3D485DA5D90394B181EF8998E6D14421835909CDDB167C8C3878194B6D514DF8636D4A14A1BEF3CA381E36CF2E6D5FBCB40AF0917D6DBB875CFF64CDCECCCFB8BFB805458DF82C74EB863A969ED98B9C46E7173C090DB068B2D80CCE32DE5172B5D4A8B909A5A4CC47FA9F2ED66E6069CD96AB1F3E848C68720FEA32C5736E8AB51005FE425833F20756C1967623779D0AD242A1690683BAD2EB123D97AB23089015514D0C6A3B0F371525C23E5F53844C81DDE87CFE9F065E11687D686B072C1900F5C9A7C31FE8BABE9F090CE2CB3B687BA89ED83C0885DFF9112B52F6CED71E32A40A9ABCFFF420B62485847FFF703CBB743642255FBD0A9086A7B83F9EDF4324880C5208F7DCB1EAC338F9131665A0CA6BF0D612FBA63FF7139199B1DEE4EE1E989BE4A03AA8AC4A483ECB9EB41D221F5997248CFEDCBF6CAD8DB0A327FA288FD6AE313984FA618F7DD4EEBB13ED85C435C0AB0773C5CDCAD4699B9C382A1F37F9DF8C3AE157DF059F9751CCA693D5492AE9CD4631226E62E8139064FF0027CFA1954EE936AFAD0206DD2AE228B6DD65CD9A9D5FF9C0CC48C8C2E98F5AE6E2C9797A8384F8A3E3C748C706FE6A3625D2A2EB4AE2CAA049241A478C1A77F5C90DDC94184D898050187D670043E4E78F54DC608424F3BF5E92C70C0549BB612F480AEBE5FA8B013327103EA1283311301F91477BA63ED4F9C28FA34EBCA761561F9033541506219C5707C2F8ED81ED3615C8ACAB1280BF7C5E00EC1B27583AE9092B23166926F9CC3C5AFB66BA32F9AFABCBA7F7916A8242A79D7B0ED35DF6526D7D2BE6309901BDC03D1595C26719D90FC0791EABA767351253B06AE4B90A52EFBDCDD40C096F24E9529FF89F959557075FC8DDAFE6103A5138F09FBDEB0F5F36B52A57BE2139D89D2904BCE2B86D03F26D56F41840071A158BF546E10C4DED0E81B00D9888C55D53E11DB70026C6467ED2AB0BD91EE0E7C3C3E0837F8CB9BAE004E2A8FFECD59E792F13F927CADDF50F74D29BC62EF2F02AB0F96E273E8D66DB4482DD1BD5BB516E723ACB0F0B97BC3207C10CF394FF62E2FD7DBB3D4311B3FA2205BF870FFDD181C630C691D4EEA86B37B238F18789E00409ED18A63C189E38CB9FFEB303F4E43FB3947C74036CCF1624F856E24A7E9A21B8C27CF43D851543A5CAFDA305CC638D948270", + "rnd": "16B82B9B0A905BB3D87B4A1E40AEAD3CDE63B22CB716BD467A7BE84AF19B7CFE", + "signature": "E55D625692737213DD3D7F5142F3AA3387122F20C950930A7E7CCC0C6D21B95D6247D5FB3ACCBCB8A15ADF9758BA7E409A76D01CBF0F14C3233B21B05D113B1F70CB21785168E23A294A0DD03250DCBBD1CF80197AC7FC372D5A5ADF3E7E892DC60E759ABBDF698228B6D0F3F4CB4FD5DC5DFE8D01B4939F89531874292036BF34CA712B0114FB66942881F1F17E80B64E0E9E9E60D76AFB59C7969FB49C987206C16CAA8EC748E6C3AD8B4EF7819274C05A2B548D4715ACED4569D07C288018A39FB714C651F9027098D9C109C0D7CE8B817B30994C851CFAAEBF0595BB6E01E4FCE711169028C3C4369F11CDEBEB7115081D432B12A64EB6F935E4370DF749DF734DE35733967B72452F9270BB6FCD908267BB319D9E3875CD5B55106BFC0015C8CBFCE11841E86E92EC1A26886CF62A5C0594D7B8D07852688DC5BDD629F821DFB3284374C70E99D30CDEE90644CD77133482BA36207102B16EBACF9F1536C8F14E3630342D236C77ECCABA7C174F3F224A34A15CB38FD848D58A2C8B1BFB87DABCB6D959D69BF06E8DB152E18A3631A783CEDF36EBBEEAC3C6A6522D890BF95B1D14A9BF3731E01CF52995F0C008E897EE532785817D47E5ACC51B48A5361E8AD7F5C99374CE06EAC32645FFED39C10B7A593C0FEE89EFA4ECD0723495C9C47847B6B7CEA4D9A1B637C1F1FB4E4C38B04AE51363DC44C47E869CAD6929FDA1FEAD3B59242F70AE5F2C00FE0109A31087F0ADFA9B838F48968B9A35E74DAAECA4CD267C3EAC93269D6B8334C471E1C8938809AF00B57FD95A8E36C12E7EF10CC52AB3E448DFFBFF99C966D228467C433996699542ACE0C20C6599C8B0AE76E8183EA91D44811465F7DFD1D17B7C28E0779D799CE41AF1D0FF8EEA5884B347BCA14748B7C3D5D1F3DDA63B154CB3B5FD529D7EF0C7402C34BCCF1C6730C04DA1C75EADAFCDFA21E4B5338B372DCF4D074861B0B68B2705A08C71958402B21E59BCB6E22C3C204CDE1E3524C15B3CB42A8CA72DE3DC45266E29525D248AC21673DB80F291EC053E2E9E39125E118024F5FC864CD9F97059C8C8575D0F68753C7A3D1BF7D0DFE2F9BD44FD2175867725AFD328552A607D799C722F6EAB2F26440CFF52BDA1A907BD9D2A642E0BA1B878D3C4849AE1DBB44A4C457A8ED5A36B098D728E6D1734FFD6ED24197DC62D5B8268AE2533BBCB7DFD001583EABBE7403D80D59E6CE03C7E3E12C7367E4184E8B416CA4AB7EB16ECAB5A69247F5E81867D30614E0F7539EEF2F4DC5E2340E83CC010AD5EE6068E5F55C569655FA36E738682325F36A76B2C26CD64C8571F067AAB8BA7DB53481A068D36F17774E6F518628E8ABFB77F7244ACC89A0E604BABB29E95DF95289878BBA95D8EEEB484F5817EA1533EBB43F6D4B760FDF4F868B61D9AF7DA77FABB7444DE7C322D5C24D84DBFE05C70123C43CC5F00D51FEA5DC93A5C32EDE0F159A0B771DC65D2882020D859532D302DFCA9EA45B0F31E669FF6F15E9B671DBF5E19B32AE8CEE590FE825C197B843E45FF5DC22E496AB12D502D21F72AA239478DB517643E96139053EA574CDB3D43C3E7D65C5489DF6EF9E4C664F0881CD0F69D9ED7CD2CFBCC540E96D74E05D2B38885D860A4F2E4D7FFAF122EBAC45A3A3EC5D7F3604F27EFE035AC4A8B147DC4EF619A692E4980040C18B942C68C8A9943A65ACD7220ADFD9CC4AADF6C6C03EF483EFB4ABCAA44EEC4258FF98AC2247315FA0ECB00EE9B393F601F0095CAFEC22C355FD9D129B54DC166518F173BF4F14942360C5B58F29B5901FB157F21901F56698BE2A544CB84984B75A8CB830DE81C917FE4578116342FCE01AA625444B7D6C7F1689A003B7116F9966A906C2C4E58BCDDE93B60B7A097EED634DD494AD985D1B79514EC6A40E83180F1D85F75F6923A4FCD0A6EBFA12748792704762CAB2506EB43DD1B4B24FC93511C45F6AE77CFC9E620E4A52B3D7DF0EB517CCAFE58BAC4079575620C5068881A8A0D1B5C531A9CA84EFE639BDB05700175A13A08FA51D5F681DE69E540B3F87C4697A64EA851479CB925CD4EEDFCEE036ACD9365B368096FE8006A3FBFE86F09E9F26F442EB1817604DD6EF49361E578D4DABF05A1F49DFD57069C134597F248E61AB5AD091104BBA0A8A3A333CD422C66C29480159D567402EEA7E490DDFB0B3BF07A0244E811C43AFE732A4C923C23378B4F288E1C4E7D0D6BFD20B593B3753028C77E67C4DEDA27A9E3F2F525985F6BBE1180234930C88A63F9C414772AE22142281CEB9F7B70A82BFB2536A6ACFE8EFFB68609157ED9268FDBF22DC2FAAEDA50F62453DBBF929D7E48CC75ACD0D345092F0160BBAECBE6B330DAD9B612CDF511CF2B2AC6619A0559085864ECDB77CF64E24B6EF407685EE931B13867F9292E7AD203A6293F2258666A07D8FDC503EE66D466706DA4C4A1EECD4DFA3C3436C2C51E86B87B7CBC6716F36EF2B7EA961B0DA2C842BF30092A6D9D35B392BA3EE2E9E2AA9070CE0F07FA7C3BF7667F5CFED9721C4EFE7E868E7F628D41467B4317B944ED391B3EF92DC75C9DAC0500C6854EB8BC29DF6D6ACCEBD64486AAC95549A13F595EAFD5C9961984C04D1BE52C428D2CC8830026BF469F2097EC2CA92CF0A711EDE2A257834092F358B74ED63A9DF0DDD45F8258D3720569FF1EBC749087B57AEEF8CE3F59E1C04624F89D93514A44FBEA58A6AC9A7CA311A347442411F5561A3BCFECD92B6CBAA6A267B9E0CB3F8DA8C48A45ABE2101910C9DB0164C00B6F3BA1E9EB749A6393E5743FD37BEA8CD67D66DD906C696705AD70F1FA52BBD53D0E7E87E098AFA6E60E259170CA36E4F8F7951C48F6629A4DE4E73A92C62EAB8A757C45DA54B16D2ECC1346678FFFDA18E14CE46AB6AC65320C63D543B58BB152EE0CBB623430DBF708C6E85B07666D4B39C6942B229E3E45623D05032B1671BB851B6E84D3484D6326609745B8EA439600FE0B85BD2240A4A72FC1EBFDB522D51FB3EA7C6D20FB98A5F28470F7B92A12630C2D976CC276AC32E2B13AB3AB9EBB61B46A5F2D4DCE0DFB9780894A81FBB2723766B908BFCD9F63B2BA54F19EEC116726C798DDA3C5508617D5CF519722652B71F7348455C9D1FE75420A5A3159E88A0DE5771CF5FD270505F728DA54ABBDDC50B8DB2EB42841300440D5F012D7163D8F41E7707682B9C4B21F5710B6C4840DB1B821B27709F6D59CE4A2FA831356943F376D0D7C7EA0E5C8D9420F35B1DCB949D5EDA8900914AE63B5EA620D9E6D93BD3AEA24B5ACC9D17BBCC6C4BA68B165FEAB30D492D9C19484E1204E287C3A3E8B4479C7B5A595C2C9A83F9267069A12D3AE78870E315426DF97EB6CF3C95339ED505AF96A03278EC6795BD4D35797FDF5CB14DBBE39B9648A75AAE34A1959697DF87D8CB82F3257BF849E454EC4A065A40B7336C5D107F81C9107B80B4BE54FE6A1DF2903E768A4328E218F1551576516F055718C28D882DC8AC1E75CF2D5B818169F638921F1A6ED21DAC80A10211898D0F29EDE5AA151C9183B687975E7F4F9BF5FBE6135A902562D99D895FA788A67241DDF1314D0B4B62111B7A4068D1DF6D5502A0A423C7CF11F151C8169DACCAC8FB9084EF84E3E77264A1F7289CA917799BF28D23165303784668A1CC6597D489B4DDC874FD204A08B8B373B1ADBCF633907F337CF0E2FEBE62AA14CE0753FABF7DE4883798930A71BE8738E9D1DF65C914F447C04A707C8CC4A5C81AD487CE5195AC4298014FAC2261C5028B9F67F8D519ADABB8E90BA3BD94D61BEFD33C0CA7B09FF36847011B4BE81FE71EE81D761BB83A6A0DC2004024C1B4DED8AC13870C369C950C21764AD9D446344E5327B90E3EF4528A62392CBA1FCA8B439F1B1001F06D4915DDBAC7D87D4EECD4A063EB48465AA4705417C95473A4980C5AC32416A3A2BB9D92180C7C1D0C9954BC3EA0D3F0EE45AD8BD11D0766D3CA764D8CA4C8F582CDD951FBB768D10FDAD45CE716E2792C4A6174695DBD8EA9A5F0EE00AA2F579C374A770993B23D73EA496B55477718D782ECC0A4EF8A996EEB44B5BDC526DE16136E132D6A27B2ECC7892A18159B8C704113DF0F9F93E473CEAD5302DAEC047C861CC9C2EC04016117313F319AE724472C559512E9FE307B0CA6BB01520B42500EDFDACD6348BCAE8C63BFD0222E6912B4B61DF635C2B5F82072359825E0E21F79C371C7E6FD4FA91408B9868BD602F0AC8C899A1C610F12753D3FB2302E78E95B1F021CB90EE8DE02757DE40A3E78F61C18FC50C0FBA05A0588E868AF572E134B4F68E6EA421754373E73272809BE71D788F0D06479E4DB4AC3E0DB81123FFADB923E0A437A63DC215F464031F0A68ED3737E83E5B4978FCFC1206E8C7CD3AAFD454A7047BFC66A6A81C380C2608E6EE47258059A5398120EE5F499A0137E99618D0052DE373D5083B1846FE9E675B9EF853052F96189C090DA605B39E2F0B5AF393FF29F34F62D59ACE7464D0BCB308F1D322A5BE640AEBA5F51B7E0A443B1DA9489A2FED050F44B36DAD392CBA8E2BDE1738D169EAAE4E97CD61BA7539F281BBA90F6F82D4CBE4938211729AE987ECCC6DA17D476020B6EEC6AAC03C9508A08BFA04F66F6548CAA7A3A8BB3B8091B66D2F9D97BB52E6C424999763ADD2FDB3946DC1FBFA894578803CAA3FC07E8D3700A770D6572AD317B19EDF969840B81CCCC6CDCDB0F32353B64578A6A0886106048E1BCD1229500FD28C8951D1740BE3A7758A6095EF6A98C735A5C0FB4C88A1DACE793D4E4F917588E05F17F5EFF849FEB1DB0DE8B2F7D490BDB06B3A1BB5C6FB93EFF3DD60EA6711FE6ACC2C642A852E2439346BBCF889B349829CC004296D25CB19E153C6107D6207D2838B89047006604FB6102BA092F41A7AD64FDC6C6C27E5EC681B957C1C952CB70A8DC75792004DC05FD4F4883F8D431205E2140EDD2CECD52F1AE697DCFE9680673BD46373FAC84F4C4F2D6876448EC2199944EAF2332383C8B17C27439B67F9DEE1AE03A5A52B96B2EC4A43A76DF4DB325B54D663EA65C2A84B80CC652DCE6F612F58D1E5648A428DBAFA355C9ED5802D5CC347FB0D43207AA437B22F0B43B994D3D9C2D7025D6A1299E7326CF00C73513384A90C66C919889AF1B6F841B1DC60A480730B21F9B8017E660DB42B538D7D0BE1A30C27F62F2734537554F75E051C5A940814DEAA98D9A5A0BE80C1EB3CCF7888A4A203F8791F8484A70E951A85EF4CBEA299AB10DD853F106A9CD5DD7AFBF5D9D9AADF0378AF1DEC18EB00B664B575A500DC3645BD0C66CEA9BBD1F7E46ADA0E810F6A71605C41D2124514EF6FEC22734CA794DD1A422258140C4E6D777FF5C96981A3B86D1C3947A5C4611C912F67C35E871A85817D76F2E0B9D04333F1C1BA486F48D5AEB6DCAACAEB0B6BFEF4F16E5DE49053CF9E1380CEE5DDA401BC1650D078963F2B7A718E86FD1421DF4DD7DD4259B3ED81E3AF7157E704D226A883FC03908C88C4BF745459D8669FE27ACE5B9CC437FADB409ADD739C065A2143FBFA1B41319FF4240905FE5617529CC7E2CAC91FBEE2EB92EED476449AFAFB076298ECA0CFBFFA5E1B8BCD33FB1A97FE506522089EC38788CADD115EA7CFF3070A340E301BC5CEF7A6A431B540B881ACAA07E07D5E6A25858D1D82458276B265693E88FE21FE6A6B97D6707000831839A6913FB1B7ED11D3F97431EC21A2EE6904C0EA4A171AF8DAF152B278694FDFE6B9F3E7488B095F4A7A058EA8F6693D917A6F6CAD0316EAE004FE5471506D31E43776D61BA9EE567A3934240058E32FD497576FD80E8BD3887FE87472F7BA2625E4D586CDA81E8D49CF04925B50D0733CC917C30E6702C5DE48880D2C0D6804D551DF4F23897A2941B27ACA86A5CCC4F5D3E1EFB8CD84B56DB6511B812697AC00FC768D99D9358E4D3EC0C10E8D9BE579F3C7A0A4A6A2E98BCD367976F16AEECF918D91B1AFF2F543F6B23A399FBFDE160352186293B509C4EE279C566F0C1C1242F034BD44524C327E64DF7816D99ED78A11336542EC3607EE3F19979B929D3AE49883DB0C8539FA8D73F5BFE07540509BF2E6B6A533D0C4D6ABFF16DE309C6890E05ED3D5A9B0D96B0A43459A3DE8B666E457058E5B72FE50448CE46843510D9AD336A9C7F6CF6D2C9546986D9E7890871964D5DE1D9B374E52F514AAEE3183557C380FB3F6F21C6071681F06BD99FD4212543EBA4B60FBFB514D02CEE59E59B2E69867BBABC808E4080DF53B477839245680F06A1D33055FF2A238ADDF5CC5EA9CC70A1B5B43E9593D680023325D25FDA7CADAA1FD224E3496E70DFF893BA6560D1113A69D3BBC12979A2BAAE9E2CFD2D3EF95FC40809448805A3F4AD2B57D61A2267BDC32CB842E9B296345740D8554B216779B47516333E91A529DEB26067F97A0A1AA070F1E23ABCCD50F3E88AAC3ED06253A4A62859FA7D3F51C9ACC52879FB8C7DDF1506670ACC62C2E8CC9D9F600000000000000000000000000000000000000000000000000060D131D20272C32" + }, + { + "tcId": 52, + "deferred": false, + "sk": "D4732215DC31C10B5D2DDD6848918DD0B49252D9D36E7A1C7EC6CE516CC4FE334124098F2D07C14E787B6EE72EA14B5866D5AAE4BAE1D494BEE9B45810081456061C09E00CEF115FAAFB75AC4A2919FF822120A66CD8D4AA77D10FFF8272054EB0FE08B08C894F9E6FAAABFE15E27E565F9B46ABA37DE9E7E898C303C42FB2AB48141111C16810410A1C886C22A71023B671C8C84DE390111CA58082C68902342404102213B228D2904940386A6202518C184AC1222591082561182CCA3840649030118210121160E3A820D8C43018B170C1A64551C48CE2C6699C188211B72DC4A28C2229044230050C24261A334A9928500A498D41C8510B4408128981DB2602CC486843B2101448250225519B94840B418C10A82009B88DC12871A198640080444BA62C5488108938454B2270CA261044004C02B888122080030272DB140A1BC38894960043909121A42502306823184EA44661040280224786D3B2280C3848D104128B06041926654486255138841143006116305C224842244A03922553B270613232A3C42183260C1182602246011C16051B45300AB06808812008372E04466624266C80062482C42861C260C0160624010A00014689949023990863482E14362053B429E240101B838C0A346804B24C83A00052806410194600A6090A8501218188C2165003C6911039489CA8918B406E20068A091806D3362A4A2010E0A60508C14C43C009149100C03411D8420E419884D9C85104117150324861448A8C0450C2442E99C8209A144ACC3852E2948111016842266D942205A49681DB304224480D89A830C10061CCB809DC8620091764149021081872022940A1A485E344209B101013C7511B4242A2423191C46561A21149864813208AA214849B164E23197118318408B0285024059B1628940266A434512331212138298A12510C8540239571E4C68060208224B01094A431603689130150D2922543306E9442661044711A216018414EE3B6294A3020D4B84113069204494DD0C40D022272C8428914A00098262990A04D6484448A08809B8405103721D2C86118042948443004278E5306114C06281BA729DC148D61941064465063386E2447064BC66418904CE42852A4064C22440E93482AA13831641288E0168208997113C00D03B62D4C3800642000D2040098C48D9CA46958208C913060A22466A1B46418048154243010B8700B9821129310144401E4424D40B86519A1640CC62023188E12B36C0BA040414462DB008DCA38614A266C1B37440BC78518B00118912C22192A0C094C8034481B2180D3C02861048011814510938C90000159446CC4106912864158900DD8A86D1AB9511407200CB31083A24D534260E01085D14871220568C83626002882CA100501138E4B1209E4C06D482652218281DA38425084442027688C862923A36DCC967123040D921472C8984C934091D90272D424864C96818CC20812490E21475020050C8B9401D22440CA3600D4463088300DA3341083A411CA02901B122624C04100A3405904512119605346651CC58053207008244C813024A18401143550E0C8600248715448520B9224124469DB407164004E12A34C62B085A29890D990250A0909132491C3084ED93021DBC681D848245A2601A3A46011332A8908515418311BB32CA1B205D9262A1AC030DC884151864020112E20094001A9450883648996209A846504408618B99044282EC02810C098719032845A444019C14D11142409482ED0362D831062103991113072D83846C3240A9816858AA805028028104230D820655AA291D0A85118342621B820583868A24664109051441469E126469C304CCC9081040591E4226D58088DA1324004925100C129D1A868CBC681E1848D00C3100B230E22A2650CA9659C00240A2820181181D4B640A198851317455126899440460B2969E1C64CC2000E64023120448A203571E10866DA1429980880910492E0C2440894709CA62042384E43A4041B456248C60020130AD8387044046EC4386C89C00D19006149C4481A918D0BA42194C0919B30401344881381511AC72814284C82888918250C001405C146885C446642284008B76100270DA22246018270D1144E6394615A8005E1B644233708D49290C8465008448C942291131891C8024D53128E0C137159800891140920140018B6308302282046701B0400B199892B43B9C22F12E85984706FEFF279553BA31592B15FAFEEDD2AAD38B64279A9A7859130EF52DE8033F622C477B9DCCD0CF2BE9AB11B9FC9C2EB068B7067025F0920E2975320AA4FEDD28A61CC4D31D6729065A2FEEF67143D7FA32A0267882E176804A4AB50D45F77891682A9B071A3B6EA7F91844F6865C2CD8525A7F305AA1B1F237A2861F03EB4255D2CF2F1AD338C5F12C25F5C8240F140440103AD3B212A0480E6AA45D8FC7917E85BD91EE0A323F5CFDD292A066844567E7FFBE1DEBA04454424070FBF0EAF35D55D2095119114AC1CA7CCF6FCD0981E6C3203D16400D5F5FACBFB0C7FED2A897142BCB02BF767481A085F82A12858BAD2F318E27405BF8DC0BD4F941A16C009976E82B35A7C63D99793111EE36374C2A22CDB25956892EAE68A9C20A185CF6FFF2B374D7D62F5FAB5DC408C5411FD3E957DF529F3142D6EC5E37A987099A41F00BF00A2062B6B0DBBB8D9CC32291ED9AB477881ACCA9370119DFBD46B937802BAB1D366EEBEF995CE60A876F2F26D0468460913F6C62715E396E3FC1FBE99C36A8FF994F94DDEEAD4DB70C7FAF0ACA039BDFC2910DBB2EA8B344529C3021773D88E519D12EC21FB016447860D421B6E60247C72AB9F2AAC6C856C6F7490850F1F6DF6013CCD70043B317B12C74EDF3C2FEBEBC65EBF284E468EE276072B23A9736CB991EC14CA4A32F082988354E66BEA2CB683DB43AE72664F0AD2FBE189D8B4A75DB4EF6815E8BFA37615114FB48AEF3AD588C7912CA74844A6D930A43625CF9815014F15A1518A5876A51BAFE5B58D258318D32332CFCA4B47E01F5275414FFACDD83E8F20562D7EF60AA9021DED08EBB8E900138529BD2CD06B4DDE6EE598B20E0FC056012A51BFA0460A35148331AF80118358BABDB0BF6A62839A08233E1758990CF95F23858ED16EBE11E92A471DB396E0E5FBD15BBF6C01B7039FEB9B9DF71E6348FB7129CBE4C908EC2FF239DFE55A21211FE892A06542B128C99B030FD2E2B5B7A6A48F15716C67132C05016D2C5500679CF3F30D9F0B477CB5083CCF40C89D7F996E87F2FEB4D38B33985B7FFC2CA627CE772369A85C8A46E82F64D5E1F8EFE782DE14B058180F2760EA87B595B994E66A319226ABCE8CE1938830E4C2F40238D3D5D111F8013655E06CACB8BDFDCEA72B3B53FB9A0D7889E670B4C4A60A9413DFC4B8CD518FE0568C3F0D92BAE99F8D3D1687880FBD930313D14012DF2AE9C765B3E045573A1A94C16A95CED4B1419810E41431FC3EE84E1A689873AED145F31ACEE02D1EC90022C327EF101978BD0BFF114316F32F11CA3CB534FD37B634A96E6527446B4594825AB2C9ACB831DE697A33476764A00B2052C77A71D3399077D6EC5A5150C37D9565BB7284FEE8E23703C2BCDF3CC01DD475AE8A6142470292ED8009143D94FA293CD22058C2D6379115DC964C7961224F2A246B13CED08904AE423992CA500234DFE3CCEFDF2FEB8B14AEAD89BE7CDF2FA2A752C3480E71CF525FB912D639251DAFEE65AADCF496D920A9CCAFDBE8FBC234D6727540BA58435C5B9659F293371B3081896BC09D201412946E4F59FBED616CA7E8879918DC844EC63937F75EA0B2E0C301BBEA51CA06FDB35DF398B8AB0876AA8EF3E7CF0EB9B4ACE42CC9A6154ED9873173BE2442810E54E14111AA919C56608253493E0E37E0019FC8F336575551C29F6E9045B94CC7B17494783C9DD849EEB87B946CDA439633D32A81097BAD2D503EDA2DB4D28D985CA16227B9FDF28A6CAE26CD153D5C20B7B4C93CB411526A67E5D219AD777C605EF94FDE297042B67CCDE1C6F8FA09B28E55B573BA9638AC5FDE92955540F93E19B4B5C0D5BDC8158E2F97AB306FE327D2D00A86CE3A729DC4039F8613C2CC17C9FDA98036FBD00DEAA47239DEE5175BB973ACEE31D39523A2778C13A379EA2D84C4C5C0A644DB76306D49C1FAFF303009A17F58E64107B14F81EA88F8B9009F0ADF6F6C9597B7D08A49ED7BAA150929EC183F072D17BF02E1D9DC54EF9EFC50B2AE169181F040DD58A333BD1AC649C64A1BCA43F799C2453F2DAD72B8C9421D0497283ECBF8096FE558F2AC0C35DE49A742DD553892E757AAE91553B4F42AA130C8397DC826D1DFF96BFCA500BEB9864B642470450E2D19C6387F8F40E482F2E72BFD8D28BE379D4D1B4B32C76E28484425C910AFCB1F851734BF59E9E1558B70E4DE7DE7465EE0BC24672002703FC953059E063BD82A64D6C328913FEFDD2462AF24B4A0ABF0C38C38C32428F36BFAB0A8E6EB902D9A13B019EA999ACAE7D425BD8B9D995F7612DA47A30CD0A9D05A7693FE673789E63C07A9336B55AA024D2DD8D6D424ECDE8AA5144D296C94DF9FDCBE8CB39A1CBE0AB83375E531CE5BE7577C552789244CDD12EDEA1B668C7F6A1D86E62922053DD2740699BC612454E40BEAC997FCBB3EFF27FEFDF09EB6374411A5EE2A4B476E7352269D57AA14E9D9E824B0A9AC54051688947C4C6C8FC89C08F596626DF0E2988FA9FC4D6EB98B6A4631327A17726B3A6FBEC9EFA4C31B897F8677B26EF200BD5BECEF497F93FA5F2F50F93805BAC6A7B13DF5599986B7343A547780BEFEB6F478F198A2E7AFB6EAC84C0420140D147AEEA92D706BACF44470C42FA79634EEBE6595FEE0E349FCC5D3F66E0176E6020E23219BF52D6E78B5BA320884A64F00B1186560C0B6B2B4262554E19016F5B75B4A9188885C9D18A20D065AFB1F9BAE4F85021199BE862FFD07D4B2BE291C22EE580DC99225D631058C17A26C65D9D1FF043C33C352208DE67B5199D27553D576D4356CC64C78C2C7746D4447A75E943ADF3FA920F790221CDA9902EA22A9D88B0BA1EBA471C0B6E5FD8128A2FBD9C6BF892AEB6C6AF58929AC28AF03BCF0ADB80970EDDB67E229578B5ADBDE06EDDD2D5EBB7B36DD19870FBDBA34E46AF80C2968D8A0AA601D8163DFBD3C120E0E756FABB187AF351ED09BF5236972A7EA17A7060989DBE3E917EA2B33AEF0C7FE61A5C1A3E59AD2362DB7D62962C7878CE0D4FBA09CB8077E1C904A33C2E5CF2AE7DC623C826CEA732F87D7558CFDE29B3F6D0BB777936D1CFD590C1D3ACA5354F1D531891767AFEA3D5CCD906F67F52A8F95D8FE009C64594956A97C000CB1A5101FBF46B8099E92BDCA7844D3C59C92226F1BF3ACFAFE67BBED8F478E4EAAC5D665FED72C89ED486AC21D918AA83F9FA4B094904922059BB9C3309260DF3A9F68B999DBAC242D81489E4BB0AAF75500C73F4502B26A2B7EF1E135217F116F0AA53C241F1CE5A99E0D43A707155DF73943E407481FADC82C0389C8E7051AC5AFDE160828BAD22062AC33D03BFDFE511E670B1BE7F447A9E3153D2BD8D3D301F88F59E55355D833D4C37FBDBDD04ECC3C1663C7B4AF4B00847311486B6AA6E8118FFC2CB3291781064E69DF5A00CBC423453992E7C2BD447E7B3B1E3129984907989A36B504685FBFF594FBCF7BCD699A404B03BD10FA844CE0EB5BE620FEB7C1189F830A32E8A6C91918804D63CF7788C81A7D366484790EEB9BCE8F96A2890F6504E75AED56928D49B10F2897BD7C3454D15AE4D436F9D3E64E8313E440A16DA6D9E603C1196FD023911D01EB5702D7884E664695ED4A3AC77359B22C254ABC76CB7B9128A7D49709829A0982C1048E1D7265D85F718BD58FB830D4A2F5B07E9FBDC9C4CE1B83E685E77782F82B8FE1AAE447C56BEE5408D6FAED115676F56EF5BED2FDD4406791028125377FA2B5322C25731F57DA2B39E1C72B6FFD1732A07CE5AC34077EEBFBF57E336608EF4B57AC0F1C56D954A6758DDC07C811158315D6F1EFF5326BF2FF0F568BB089855D280DC81ACF8D8F5A767A9C9695E5E24E5D768A98D741724CC934A65546E25E586FD0ADE826891D37EC263F5FC3CADB1E9D2CB9071C6E3A3867978564EED6AD973A2E451B0988F915A1275E51896EE3E61EFE0ABC10D31A0CE101CFD0DE4094588EB7112FF64F0FE9697E4F817D188C9463B84D342C08E1D5FD9E0253B374B5C47C5138E62EF7C1EAEBC86661BD08435CD0C4ED4214CEA05D06F99A78CF29FC88451B01DCCD839698197E9227D8E950FF8EEDFEB0A44B767DD7076824FE9A29A192A4124C2BC9BE2C72DDABBC8D5239763A237F9A0E887ABB32741199A7643F1A53F6805E56BA71490A262ADB118DD965792508C793D28C69E60EDD79BE3D98B8B92B4D0FA6AC45DD496DBF3AF08B96C4183D58B0D5A8455EBC4366FA1F731EE10F73D432D5700F5ADBBD1FDD5D324EA559E9E2E87783E2A48162DFF8941221FB7A0193795C42783A743F7D8B12F60A407F5E72986DD39DD23313243DF89B00786BAECB6A94A607E28AC0386EB70C97947873F5AA91C6B5FC49C754E476203613211DA0D56F13452FF35E990ECB70C9CA532E160517BF1222377805850DE105903C5AF0DB6E5C2F7A55E665283887D46B5C4B1B3A079BFA63341AD1D921A82727699FEF69CAC37113C579D3813484FB66160C72476E08E9B985EEFCDCD635A2EB683EB39219D2E8FFCB070A2434D2E4615622057FE47C7EA090EEA6D80A99B252B1AB5B39D254D5FED455D39133C9C2185022F792AFAD256B9A2BA4274E01618326348C55228A28262C67A0B7D4D63CAB1A4D290CB33F20997882266C32809C1A3B4E1C1AD6FE2E0B1EB6B29E8663CC6F53745FB36D02D3D1", + "message": "0F2DDCCADE26134BC425DE33091C33A9D2C4317DC67E56A56CC097C759FA6C37C610768C08C7C8AEAFE00CD762DA9B50FB0FE29850DEBC86BAE591A7D5C22BD1FC410EA46D2EB9B45C825C8304108AFE676C8A85CB6979D5B5E4BBC17C25300B6410E7EDD903BD8595AE01CAB3726A76A60ECC06CD8FE2E42FE8A82AB44F625E4C0FF56F86310C34725815AE4DA9BD5E0E6F10DF847D1A5A806E1FE5382FDDAA5C4E7371D079E5B7ED5083E8EA62524ECEE15A91FABFADC080C6E86CE9F985F640FF109FF78B3F69010A9E313D9B2068DB08DFBE261EAA6CEE6BFC10E2E7C28B82C1840ACA2D57AD9F80AFA42B9B2B7DD6CB54AC8508B7C50ADACD4F39DFEAB1AFC9CC6919F7332FB564C6DDE3B447BCBB36EFCD9872554F2A9D02FE5D0C12665E93597358E7B4C698EC1EDA57E1620CD92A5C4C454944083D2550CDBECC1BD33F1DBF46C120E717833416DC7A92747A6BC0CA78E051831ED91A943FFE37FBAFC9996CCB5CCECDA3A33C9EC8671E23D1644E05B97CE56DABE91C148FC48A5321FD7EFA9E63D8C97079465E4DFD6C3AEEA958CA5258F82EC437D0A4263E47EA01899C35A20CCD292EA15DB1AAA9A47B8D4252D6AF8CDDBD3321076B8D076BCE2BF007F279FA7D4180085730162B4FCBA35DAB910C72DB097B1630204D4D3285D174DDF97448D938D45F498B9659D3634154B9BF8C3D4209EA7C3B533252A0C993ED8AEA8F901F5D1C38CE4F7CC685B7696272ED17C5725B5F6C8994A6F670A3AFC5511C103DC6B342D184FF98A1767411E149A3F54F8FE4099A275543612FA13767F1F23A9698B206683DA6AA7CF686C2CDF6D597A80BA0B78BB3A9EFCD1B7F782E7B8F28384107B7E14C01F04670BC4417225FE1A7D0B3F7192A7B9E4F9453692EED1A383B9DE52DD77D685C03BAE20751F9832085AD6549B4CAC61E6EDF344AA904AA28770D3D9B43E58F0D1968C2E049EA7D84DEFD6ED816914679382912668A82C5C59A2BF1CE7D621EF4867CDBFA43FF478046BECC6ECA455469DCBBFD62D91589F56306DF916BC342AA6C381E6BFB2234368BEB7C147728CB79BC5D92C00C8A2CA4E7D61D7835D36CC2D2439796BF11C66E7C0AEC05BA71CB807E1464D78615EE03CEDD7CC291B04077F1378543A94A8E213418D6FB8EFB826398AF29754B5DFA588641E04D32FB8752057A013DD56430A78AB034806E7544AF2BAEBE190345F2F2745BA7D9F118D169994470D3AAAD1256C82CBB3D4F6FB32E1BD26604652097764DACEAE8BBF8D445EE84EF21A4608191B323399ABC409E5F4362D2C65DBFED896615332B3EC67902C6777DEECEF691ED98C3C352AAFD8B80D729AE35FB9ABC6B72BE18354D19547675E39747C07688F198CD60192B5F477F4A8145933CEFE65EBE3E6457E829BBF9DDEFB2F27DD6021DBDEB24E1F97BAAD616005F0912326627D6141DC39346DCBDAF5A94D6365E80A98A57C6A317BC73DC02F79DC4E76A5372C5E850FD808D74838E3C9D6D57ACCDB3C5467466A42B1026129D5008C96AF94CC7EC83041145F0FFBE6ACF27E2867A52FF662FE0B71B5E49EC6143708C33ED5D637FF3D1FFCD1AF4262C820375FC87550EDC3BB7C75DCCBABD82D12C3A172B406E44236ADB882E3B1EF73E84D61CCBBE8E7E87B8735CA187EACF592D0938EC65B0582040BA16D49594AF1369E5B68A17B0DB65267CDC998E84DE80AF1EC3EB3160233B60347B99F3A504940DEA26656A7E78F1F46A4C88EBB954BC5309799929BCFD8F4B210990A1CFCF7304C752E240318A29B8ECA82FF06E5C69C41C69C318085C5FCD6797F4A830DD9C993CF6472219D9BCCD92A2851BCAF6E215B1C07F6C69B0FB0F74FB1AEE57BB5A72C3FAE651711A849CD52DC9046CD3C981864C638B4F60942348B93D9D7592FA5BA7F1EF94776961144BCECCFDD344C9B2998F8152160263B38E5EBAD32FCF6AA22B9D4935866210079E7A8DB3142281038D6D6DE03426F8F02776F78871008FD882E1205547561F076FB6780FF38A2985E72CD4BEA8EC834BF2908CA56A80BD1789803E3EA7682F612B16CDB871EB81B31C61082F181859C01FC8BE76B74B1E3C6EEAFA743E46E7EF5BECD702ADA313B10744F188BC2C0184F57C848F588A4D03187A5B859D88F70DEAC55B199C4F3CA3571701054E37B6CA6F98FD3653D1B5B6057451E9476AC9084940BF73F7711CF2B2D8600D4153776A64A2EF6691414DAA38538BB941EF7CB7254358C5A11B6D5FFE8E77A17BED0A902D93D9C322EE4BA205618E65D01A802A79DCFB4BE4A4FD3D661254DDE3530BC7B85BD4C219F694208E3C6A9E58D371526B5BF587B5C2EC0155F3B9B60EDADE7000E739426DEC856F63B00ED0A652301FC963B7C2C40BAEF19D41AE9F65F7D19D0D11F189F33BB5221EB99263B48A4303931EAEDF77EC82F1702C7D230FA429F614C25BEA56C43E78422FAF46FD1F1E1B64BD438EEDE55F68FB484D31B3F852CD008F83D2A6A8C1D7AD9CC5D7557D3ABE5E311B6171298597940192189BEB14080604C437DD7C4D801EB5B8737DF36A8E60E81DC80158D1C5C6604EF329E08C651043CBBF0B9AA77BFA1DB943EF4CF8E3F4BBF82750254BD1C3D0D284F7479DD8F8A7C075D75E4959106DED4C29959599E5463AC7B8850CD0B8A21E55F4B7E9E769E3D985E5DD292F82B1AC5DF50473E226C63CE12E07BBD22CA553008ECC0ABCCBE2519D78BC5F212769CF735739760CA3AC22FE74B5CABA80514145FF5199522403976B10168E48C5B096F9C23B236DEB5352271E2FC0634E61B3060425D2BE6291AF7AA7615FF5D3412E3518191C3358466BD20FFCE3D47E3ECD700C6289F3E6AE12DF6F7BB35625612302033FA11CD1BF698E19B86C75711EF65BB88557F7443174B935EEF3C2D4848B7C7155F2759986F5635ACD255A6848CD633E88DBB0DE9557F6B43BA2C723C45C3F13D4BE3E8134E39336358C9B2828F5D8B5178631C39E51309374A97D1A2B98E6694E825D21837AC4BA9E4F2FC5EB6B5EB9BDF3BCAAC68D9632E0C2FCF99E32856451879486AE96A9D331F7513483105671A31B4CB1FD38F1E2090BB72C4DF5B1F083B2D641DC01D409A4B9E3B8709F3E98EE49EE5023091728C97087839F4E8C14AFC2D4C1A844BB926B70BA1460BB53918F577ADA0A61B357747E86979340795FCE4473C431CDEF6924F8B1D6618BA750081BC419AD5B582386058F98ADDF8B1D471C9F070B5CAD5371283562853A5D031734771E5EC07B6E4C7F20DE2060915A5B3711BE8FBE85803A22DA29C9A4A2A7E4AFF93F3AE65458DA2EC690DDE7754B52FE0727E241B31074B105B319569C120FFEC596ACE359635EF30042CFF9323FD6F38066B7B2A6A946A623934AB34BDA71958A0F264B3FD264BED988EBF9B69744506664310EA79A0DECE2ECB6BE22387BEB3B8690778F3C58B1745E4CB3962892DA516CEBC7C5AD1B1B86B6889784D91D263C8121497195BC522BF7BBC3B594A26B843A97405EB76C5DCF020D4C8F84A83022014839931615E8AC497E320BEA1D9303171B2D093F2784BAB55F867E699CAA29C6ADD228A5829F68A07F853B27132E898BB62B2ED2F6CFD470DF16B67D892CCFBA5A1E19A71FB9434AFF000FFBF499CB150407966B6584E5C77A475FC5EA68A18F8130C0DE448D934D969456DC964EB73EDCA1E52ABC51EB1AFD5D35B206D9DF56DCA649ACD8A7B6E93253BC509FE224AFFA659FCABE7E35CBDC9886FB77C6A053E5F5BFBBFDB2A47B6BA4A8F21CC7B38459AC79A62DC44C9B61475E7C23228DDB45D91852667E5B730CCD8E0B1997133A15AA1D04A1E52CFD4825395925B049FAAFC2892F02C92E76B11A8B5AC295C19BA1832D6C1C3C9DCE081A1C95F40D8D982751A0DB33B4BE42163A413EB4351864BB2E67B348704B4F9EBCE3C00B45B1F359408FDAFA7DCA083776DD688C3C8BECDB27DAA601E7D8B72B9A58FDBCF5B8F4A2CE7B4022F48C95D4689A212877EAF7B9A0B6C33954C2D480B2CE87129E70D19705DF7733458D92EB13FAC3BB5869FA216B9C2DC74FF98246AE85AF8678A8CF2B557992710C6256CE7E1333D60882056155FFBB6E9C2711975183959B5B10FF46D0CB3E5ECB4F21260AC9EE6091D3C944210B9777EFA0F694D85DC12D8860976C74C4AAD1C7276CEC77AA0E92BBE9F513B11EFCF37D730B7B9D0585383C98D1185CAA4A87E77A631DFE15EBFA1B93995E95FEC65979F416BF4B914C2A456B0263A5292655478B12777875E79433570CE930CBA33EFC764283FF9212F9F2DC93E5A91E52277DCA29393DC2D0BC7716515E8A3F07D850AC82F751A41F71C44F3A49315EAA84B5972938A3F3EA7E6E94271E03D7492C25C44454A308BFA602CD2D28413F509E355535D36C2D9D94012500104B223EF1787B8882FDE0DAEB6B95654188EBA46EA5734142C9C1A8AE4741357DF32A3C670EB614E5AEF6117698FE9514DBE4D636A3F43B878A4DA78C6136780F5672EA00AA41265F224863E0FACB8F714E09E5C0508BEFDE2AE6A93415362D11D60C412770E31EC1A527C193D2666D3381BDC38E474F1B989A5AE3C802CB86E3DB354668FE112E11982D106C2389390EAEAB009B1A09471D7540399EF5B6EEB593E51D0C741CDF8258DD978E6D91D9D3F8D97FF1811AC8F841BB85DE9386EF30BC7DFEFC5D32E72E9D81B5E30288D9FA1FCD25E4E7AB3391E27B3E5C4A7C030EC09A17468BF8A01DBD669CB5ACAB748018CF5B9794AFCAD4C489F5FE50A5953A36618E7609F1CA7A64B994B27FF81BD7798E02DFB73A6F4F102138557205D751191CADC782ED0E1AAF12D104FEDAF5FCDF680328F6AE56E3291163170B798D36BE938D74F5FA3F7DB6F88D0E1E9960733844CF003B96E4A691A2C2C26AC5133D20EF9D5E4E2E41AE683FBEDB54E786EBD3CEDC1EB6AE255CF2DCA236A8A7BC75D4E2F6A4843342156385AE61F3D68234D86B69273AE71F169422929143A43316A0B2B2D61B5F573DF51706D5C5BA7F846DE6DADCBD5C2786B81103DB70372C695B731B725BEF1AB3482783616DD72897FE03C8700D8E89BC240DC636129F64797873ADED527D873657E76B47184B937E48157AD5B0A5DD08616DF0E225719AB36F9CAD005671AD79D87916EA97EA2914EFECA8AC52D4152674045FFFF760B06DD202324260826BF0C2CDA9C6CB520CC06DE742D6DE6DB6A1DF0E83C1626F478240E23CA3AB97FC32C2871A0975F534F8C5C16F3EE2F04F0FA6DDD95DB52D77DDD61FBC004AD281DC2625C62E7D5C7EB96B39EFDA4C1EA1FDE287762D73225788B59865F4AE9F31B59BBC5C84ED31971C0A4D800DB62D753C136BA07C871D9983A9B45F14798907EB46A507C25BB4688204FD4A0DA6013D15ACDF7DB68B785BA27EB73856B49B1A555A260EF342221B90212BF4E2C0173BE20A14B093DE611154994AE476458AAEF9E00A24E1E348295D725C189DCDF4ED622E7EE06294FA607F07F23C6C7F8EED39C9C1D7AD7A6A60EB76458E3FE11947D6B6630532C377BBB8B89E4B4433A0A3009BF9B614CAA3C634B1A3DA4FB3181E5336700D238E89337FD6A251409E118F50954158FF6C7D46C38693BCF6F7915A09DFE956C2F13841F3F8239211674DC76D9AD1E10D21FD3C8C33FE5BD07D2BA368B3B88D667F2922774F79FCA90A79C2E26439229AFA0EC16C4FD5EC13AF906DF5CC9C8A292F2CA6BD6CDB1CE36A8C621F120B61EB2170053EE2BD9225E68E526B5D67356C98D5EEC524440BFF4DA42AE1FAD3A202FCCB5C020923FE1EF1CB0177DB6A88946E5DF3B50E5DB67E720F62E1DC83F0E7052DD6E5FCA3C98B8AFC23DBC27E0EAF850665EBBBA830D2B159A6D3AF891B14A6C3F5E9190D9BD348AE5D3E3068D719E2116AF79896ABFB17EFF39777123AE73A54439A97F1C1F0FDFD8267A347C2A5F11DE6E9705568E95E8CDBDAFE99D1CB150185F30DC836C8FBDB4D01800A88F2CAF23148DE4FE8C0475063CDBABCCB4BFE03712C398C972265C4395916B03AC15A9597C9E4CFCE862DBF80A4EB9C8D353463B1BACCE38761BB1618ACD6167FC8F54E6A47F100AEB0BD3D0FC1EE53387D710F6F95782F10C4DD88C993808BC33C806EF72319FE44A4F92AE9DCA765EA85A998389A530037EC72834636A4A7DBA71AB726D8D8E116A9AAC395AF1C834823BF6E3A5B33DDF4A747D00530A8EF678FDA0560F088A9F4E3F46B7847A77EBD78B4EE250C36B5AD7AA7AE82CCC50A15220A3D2ED9FCFC11E57A7111E0589C56CA9DCA3BBD1172CC09DF5CED998F6F55054CD0E3FD495A43EFAB367E02BF8CD79548113B1A1061F3EE3A78343FECBD1CF974D06D2F319EDCD9E54B1E04610681139CD957AB68C9D6B900159C2533283BCA3BE00940A0736FA0BDA4E4E71AF304D69E6868278757D97D110DA2A13E997DC93239F765DD1F7B0401DE024247E7C6A2B6DBBFB1F26E043345E6601B77707EBFE72BCEE196BAB15D195A958B8A1F6471291911BD5965F4011A8E208E7D955E976A8D62AC59EFBCC8981816E76F1EC16675DEB1D507E94C49D728D053834A76304105AA4B85DA50DAEF19A7A6AECC29EBE1A3D9F4C69F9C14D8E886A9C9ACE140BFC5B39909A2094ED27774A4FE25315ED19AFF648A35F6F59FB4EE8F28225164BDA5CCE02AFB85E0086329BC943CC9C677AECC1B109FE58BA6DE958F8311B2FC3409E0C7ECA90D9EB6100470C09CD3354371A1DA1F856D9E6DB989379A3BF00CD4EA5968710C381889EBA17E3D53442F1630CB731E86E78D7151D425C1968A578E41C305CCEA650FE5BF610613DFEF41DE4BCE24937F4D97F02652D61C1DD8EBF2B45D2D94227BE5545FF26C1ED7B4C428F0429A817D0CEB6E582747D0BA6ED72B7FDEC7A3173220E550A2A06ABCF0186E22908AF5046AD17C0145C6426036F7FF5D280EEF22E7B97A379EEC4E88ECB31F6AA806B16D35538ECEE98AD1AD57833DF129576F0F82162842F82A57F99F668C16739AE373E828B5971E723810FB7362F5E6EEEF78C993058B799996EBEBAC40229ACC20B97923DF18D039A288A2A2DB8E1643A6E08826E294545C97C84086D0C1FADAB2D60178398CCF779FAB2759E81061D771BC6D3BFD4DA22132B2AFAF9070E4CAE18AB33C6588FF141C857485B5860F4777D1F7B58BDC656613670039A0ECFD1430DDE0F758D9A86971F91862B3B68933EB509C8D8515A7C2820B160DF1710D35E7283B3EBAFB97135E7CCB329FE7712975F2AAAD21E53C6C1C9AF3EFED06E53C2CB74A25E0FE2596FEBD72C281C35D75FB0314D7AE39ED324D1B3DE09295D1D13E4DF6FD5D6D2D89C959E70E178A87597B8585BED8248922B5A7920D88EFF0E5CC8A4C091DD8FB80C2ECFB385CA2D9E029C5D0827B9D5B8B5613D559EEEF76C59144B0F16BB01E4B07005C34AFE0368A0081FCFEB582297C7BB8BA3B2303811E21AB19932CDA6225C38504A51AD744114FF95C6F0D9771ABD7DDCBCDD6E2D00CA5760BF4F286845DF00A96272D015A4786911EF40F27942C9F0B19B13752305AAC31A6741ECAA26DEE6B96A1C411B6F18F0320063D7D3D4CEA2ABE95F473C987AB5B38E3F3E94BA7985B724D737E575EA00E2401DADBB6E515995D6A723BC960B90A201C7057FFB305FBE2F36253E5489430D0BDD48291CC77A83BF29D50A27B4ED5A059C7EC8F70CBF8836CA82D8E508CFBBA14B618365963E808FFC8CBAC88678A20F0A472434F4586D50ADCF4B47FA803BE4AD90A056FC644CB0B3BD4F7A10360615CAD36534B45931EBC87FC9E2EF343D4BF6CAFE9C8E7CD27F7BD89E364425D067B23A8C27CC22BFAC2D2ED3DED3C89941E393AFE09DB84046FB216763F56F1A9C5E9DBB788620DFA6BB9C44DEC3DDA0E33C83956EC23F056DB30258ABD96B38720DA7BC74BBC5D588F2721F9326035953DD30CF2DD128341B12674E5BA9D218DB3F6AE22D317E240BB17687064A17D5016DF27DE24667ECEFC4EDE2DFD1970F897869BAFB14C7564B231595CE0808F905372FF2B95B9134EA65F6E487C9471157449F0F431D0C2150BBD9738B5242E6A965AC16E2EE441887ACD7F736280214A690F800FEA26EB15E02D0FD7418E1C26D3D0C89DDEDA25F458DB1B1DE6A3431A94D9C6D24A013B5FF8A04953D99A6396EA6617A59BB52330E1CB102586E4B52A81E871A524068CEA766353010A06C06901A1019BCEC503057FEBD8D6ECB1C34CA2545A99036437EB01E56B9FBBA21BBAA2FDD74930577EDC82740A5CF28ED0E1020EA426C16266D8EA31F34CA286798948CB64BC92C55B467B1BFB693C221DF4320D25352B648507B9690F8C9EFAF87DDE467E0F8202EE2743D08B46692042F9BE91479A0358D0C7DBE7BF81ED9F17066264897E1CDB8679A7288DFB2B60EE79EBFC2BB5005AE268C59AEB097C9650D1CCB6A758992DF6EA4647F4E6C09561C6F13C183E71E3BC09BD23AC12C6CCC19C0F4E918D27E0B5033B9D98BD639F8B72ADB1D63E32601F5E43CE384F313187DF0558864C080F78C77A4A9E904100D8F572DE444DACC6F4959A9A9CA0A7304EDA2DDABD3B95FE50F2FF820427F6BAF8E06FDF7F800CB5BAC3941B4B5901784A7F71944B3AE147D5F25E5002668988B1E6F39E18F1AFC06F79159E836BF1AF4301E98EAFA7A0EC7F88D12F407B2ECF6217863C08447A330E213CEC2660CFA7229ECC3036ECA03823FCE39225BDE2AB653CFF5212134E0F321F7A50E0C4E8621AF7ED2227930B616A99505654AC5389721CB00FC2EA9E0FC1F3C4414D0AD17352373F784754C8154BC13CB0230F02F661C85AB2373A995A6F3476EFA95622A649736656A3B451CDCFE74A5C440D4438E36D9870B11BE7B88EE22C982197FD951D81BE6747E563F9380CCE1EF3273D9CCD9887A6EC402808DAAD3C06AD89D99D063D8381AA11D06A1384B0D924C266CAE9DA21FA3404D3A10369781850777DE8E6F2E05AF22677EE92BCABBFE12B7153C58D7E2A72BF8FE79876A821006226BE43920596152C58680593BAC4EC6B17AB8A787A7736C07AEB88F6874A8E7C824C80972AF9D7FCCB4004B5EBECAA18DD1FC1379D83AFA7566E8BDC92E06D5C1DF08065DDCA8BD8E328FB2A1E8C2E06C81BD7F4A7AB6C03B25D61B5D1BA24C76B23411AF27334B41468E30A866105B7245D97B7A8D9805E0A73D8117F9F41C632828C2343526360D27FCE270A77768A6EE05513815749F847856C56D30634E390ED81FDEC74977970190FF1D2C7E477C9AB18B382D1B4B4807998DBCCD379E271A1EFEEEE40358693D8E4360CC972DF6039294DE9A5847FDC703E21FB2B5255501BBB44A644B1F3F8015907519125BE9B93071E29CAFE2DE595339F332E88ECE036C731870D7267585317E7D26A15101071508318328B174D435119AC094610E82B7166A1352FEB161F51B4E14B7037AFE0A97A3F7118519C6967B7F88887A908F93343A1C4F0B9EB8FF431842880B5FB4AA234B34E091C6F132B92EF1B7B0B50D5DD62016C8251155CC8488D8865C8FB57D37494D87FE55B34AF24150516B4D881B9EAF07C0DCEBF360C323465501F38419805D0538C0AC0CDDF0E3A4187218EFDAEDDA79D09935DA4C821E23FB33B42EA659D27A4B2865F6188FA106A728757EF72E7A093099DDFC0AA82DAEC6C48C8EF78ADC8DE1100E44E71B13BE8530826A20D4F877B2ABB972E7C39A596D5D012C3E36472992A643EF962CB4FA1CC5BF95019AFBD7E0BAB53EB46F24350FA471AC05208444D583F51CACD93267EA7DE21C089A0DDEF9165CB27B1CBD97B2F0C8D8949F780ED1C82F1F69E4EE4D7D205B7206E735D88D064B7D3F660CF4A36F019B26AF9835FFF9034E628AE534939C18781150F6C49BFF883CD567F7E50691AA5F1981D995A86CD30DBBD1C8053310E5374B03964DCE2B2CF0453092C2F6BF102A90284578C3638BA79EC4EFB8EFCD6D782AFEA416BC3A876F0A9CF9240471C2AB9AA7D2A0990025EF2A5288458A279D3E64A734B95AAAD262D8EE88E942A5FA170A79E08D0BD22F5FA7FEC19EAD504D83864BC9FE98CD157B34DE72B85FCDEDEBE125A5D7AB137A3EA5CD86701607415B96E8B73081DB4CB0518B908600C51D2E7EE795FEBBE46C3D7C4BD9D58D7706C554838D7CFC6CC3871451CC0740F68A8F9303E72CDC95DF1455A39D455261021D92E17C8B44B032660472848B08B1D109913C368F8499A6C10EC23D2EC2C7F9A8DCC4C921F01BBBD9837BB68366DDE692D2500D5C09EEE25C037C970099C5E1BAF5FB68EF44B369AE88406E76E5BA3D95D2C6F4A472EFA435B41DD569BA4429F1E2AC3DA473B959C704803BBE249669E8D65154C3C7D45723AFDCA8AE7A7E2EC40E830D5F9313F7279ABC78DA1344125CCC5FD7E9183884F00BD0C86AE0E4738D5A4EF236F33638BE3A6CFC4CC4530468478992FDFB891300CA0095DBD2218486F94D3D17BC59E65F4DD3622B394F0091ACAA8C657B7CCA9766BE80E99586919C98259BD4F4B112C3FF1E6AC61089BF5AEA2B5263CE1CBC951221C8CF2DD56DB89982A4F899FABD0F0E5A822801ECB92F7DBECF033F2B2F4D1E35CFA1B0112E71367CA2D9A93D09A92E919EED59DADAE1C388E04C56A4253C5C5E25A3A3DB90AD37EBF2DCDE8CA86DFB15A764677B9B43D9637D50BE565D39597156519AF4CEC5F5F668F51", + "rnd": "C8A2E170B30E35475992075A595EF5037D31198D80BD6EDBB933B6E72B1817AB", + "signature": "88E11FDDF391804879D8B14A3AF402CEA0952C6583403C48D0F6F630B7D7B2EBF74533842404B96625F092D0854B75A1525651C774D9B246E68A8199A2D391F8335E3127028AAD1DAFCC4D95BF800F9E5217AA109976CD18743B8514D6C1F5EDA5FC5EEF357D4613C4AE1DD2821797FC09F3D5CD966D4B3E023F3C4F04EAB4B6EA9358DE7442FDEE4F520EFEEEA57AEFCD7730D59ECF15773C43F6FD804C1A8447D8A7FCDE7A9CB83631A8B673244BF23FE639BF576632FEA0FBB97A01428496CEA7D81E73F551EF541BEB500CD8BD9CE7FEB7177F3D10D63C23CAC8BC9CA09F839AFD4A35EB04138A35FF58790BE8F56B222FC15DA91C0FC95496CA3EB7254FC71B238453525619BE30D59EC1B04AD0E95C27721E3A41A841118E50DF5F67EE44ABE797E04536F2573E21B43E3FB3E9566BB3F3019B82BC4EFB53752DDC600FA9F22166206EFD210DA98D6E639BBA202DD0FB33F16C35D9F1EF6C30A86B02FE2DA3E7153376D7DDE9264BEEBBB59F567DF101CCCB13596A360C4D7F2E9D02550ACE2A83A63BF5D91985BA17D1925E41364F5AC3DBDB15332E645271BC03A4143194F6BAE651C379DCD880A7565746C1CDC1370AF89C0DD2B50440C1700C751DDB9898E0A204FD4F7AC75E1C0DF62AD1211C2F2A39633C7DE668907213B197B900C28459B212C6310CB6ABAE589ACF9293B7D57B5EDF6C34E6BF1C19FB79224C674FD61706CAA1BEB39960A89C7FA7F548FD215553A876430F77CD0AEC25556C37FC463A2B2C6C12D9360FA1553F1BD148E2D05D21F331B3A20A646EBEA66C54A46FD008D94ACBA610B02A26363A1057BE3231A76434C1EFD875749957B30D2CCD6B3FB4BFF5615AAC3FC7EBC3FDB09C4D343D7989DAB3A805AC01450C89265C21C9C48DA744F12F7509DD205519AE9B5EF6F925E484B22AC17D3ECE38ADFB982730520A8F609DF65200CA2F1C2CB7C0FACCD994887EE0B0186A27627B3AE90EAAD3A5198334EEAB4A1327A6958B3662332E278AD34A44DE33C26CBD5053D845B003249C6E989873691E17CB98F8A5EC1D94DD23C3CEDD55D7D7DD8363F5C99477D5F6BD2FC5CA0EDB05327234E0A52D392C54A3690FAD3BCC4CAB9ABFD722947B93B6F9FA3D31821C44045195D4BA7FB4326E46BC83012AEEDE3AC824DF09E829B7629DECD95420E71A52713E2B50DD88059B73999E81691852AE4DB268A9F4475642C7C4F5564D569678B4E44C345C17C0F0789B7C6A2F2F5FE8DFB7DF1D3173FC1260F7EE5125E6164960AD73A65806E8BADD3ECD4736EB5B0288FE42972D020DD8358A32955BF439E1CD8F3C7D7EF0ED84D1DEA4AA877A35324201F443039A2EBD6E3CDD9CCC3E048C23B5760988EC8BDE884A9EE9D9A4C3B5A4166D1E1348FD93BD653EDA2943F2DE97FFE902537A00B494959E4849F93217A6F25416ECD9EF83A9AE1523D894EC7A350C689578FA655D8A0CCCD2E08DCAF1D555D57952DE9263D0B38DFCDEEEB886CFA5B665FD4244A3463FC8F8E04D505810F4D460AC1AD8BDA57A3C96A9B1549BB04E02A3852DDAFD2B900109246397A2DB91E3A3696F03CEA3F9F77E423470FE11662572B50B6490A3D215E7D90C73D1B1F4545F8A92D04295660F8B838692A5D2E74222C7E236717B55DBA0CF1F633D12D5637E4F5467305EBFA0C59D3D932C0EA1FBAC0050796BDA12F99E4C779AA0562326D65EBBD77C1485747B98214C2E02C343E106EBE2CF585E5BB473959CA87350C12136BC4FA5E01AC2D36A21720EBFBC04250AD56CBC7EB8977FD1DBE93F2061326F62B602C703F69BD89D33C670FF04CBDFD5F0C7060A3AF97BD4252863E2D638CC5D26080A9E72CB87602FA1B61EDFBA4721464A1E9ABACB0D7F1A65A272B3762BA9C270CE58ED32D573A7EB6C88D8252EF5147D173A42B00D982BBD832C66EBEA952F99931A048D6135693B518B9674912B74CC8C16D0E46874E4C09A6171AB38AC76FF2A6512F12F620F7C834337DD3976E82870331ABB2F9C94D9C3B946915B6185A0CAD49AAE611B3EB2B7A074AEFB241FB143E3FF21643C1041147948F27C9ED404B6B61ECF763A740A10F0A61DD309C9396022A62687B0A0FA9C4DBC4D6326C464A2034B8BC66C1C12295A377282FED0CC050278CD72A4DED6EA7573EDB08ADD82453AF896D4E1729A4D0AE156F068C4A2DBB5D1AE079A28C2804491409C6D7D84AC2FE043A4DA0E8A2D71EA26CA4A83EB0D1047A0ADD74703F57734F3AE7762AA8F0250C1198DFE59306F5B1F35C4774FDFB186868282D012BCFEAD3F634786523FCD979DF9FBC4A966C7346D45BA8A2CA8AF069444C81C986BCD2D1FB489C23B8A60177D042556F482EE37A290C9839F9BC7EE82DA773DA85CE2D647D4FB14DA06A7B01C1DA128F4ECA69666145CEDEBE97B81C9C7979A863B9F60E82D4294914AA65BD56D0E134497C57BAA980BF6B149455557E9F0C90E621DB4FBDA4ECBD012B95B733C4E8DC9861F9D19CFC633FB2DAEDF1F697360F6AB47586201503E0CB2D2FEE4CEFAE0F6FD999DCA819358AFB5D83016BC918C5CE1EB2DDCA9589C3710ED05F1D849189917B92667EDDF06E984C7D4BBBA47E1EB25DC3B740A08C58559143563429BCDD16271F06680A98C3BA688627F890CA6E4C5D156D5D667AF1EAD5033C7D14468A1CEF5665521955938A5C112A050D3E6505BB4F5CCFF3EEEC02733091D4D5316A804674FBF29E26D9FC11F2D24565BB35E835F5788D81015A65D41495BE82FDFB5B0B1E032DFBC8C3CC5919EEFD11B48E6B06874F45ED1114D9A1C4C0F60D4B4944FC0B2A42018A97F76DCD200598DA6747870604906FCE07CDF973B5F1435023C7894EA8FEA0D4D9E126D4CE0157F9F8595E48AFD76685422F9CC94C1520E48D66BD04478CF48448334B34A55043A8684D36BEAC089CED40793819C25CA057EA762BFAE79F0F90A6798F61E025A0ED8704AFAFECD2DBC6D6E01166DCFC3194948A02B74C735D11F69E1AAB1DCD875D100CDA177429009B5570F5F4BB9E6FF4E494F4EA7E127691F8FE31619C771CE587C5E8BDF1D1727C21C0493125AC3C7E1935D0A49EFC0ADE9621FDBB4C4099DB1227BDA48B7E9D9FBF8D1391F74F2DEC3E040436A2134098FCAB229CA43835039CF79A44A2BEDC4342DD21829383753B319A9796934103DE48752483C1F551F1288F489B96EFE084030AC1706419856CE3D893313F8CF2A816984999CD09EF64AA86544E7267D0D3473EB31D95DD7B25971A4F4B7A91B355269B29E88896E967E6908C44EE25A74A63D64C5D3C49324E00B099C652E11B0D5BDB91662B6D10A974014E2BF306BB0597ABA30B69013590377739C4370D1D70A0DB022CA4E39309A91F559BC9EEF3326DED7E16E4A4886C173F70D17B01E2EF7363791A0FFA9152EA8BA4DFBA6A7AA5F5004E2C8EC07BD6D64ED86E47DEAB073E231DADBA8E5C7AAFD5F46510158FEFC7925E6084759F15178C5F59A7EE4499FD739ADD42D6ADB20FAFDE883DCAE598CDDD4BE56C2A737CA14E4609AE9F3FC7DDF29BA57B901921E08FA088DA6D55DF25A5C955049B8FB58720477CCDA8CC36754FE725829B6BC2D4D5AD17706B1CDE845301970084F1ACE4110C35F1F3909819569E8B4D09819F14223170901F356421EBEF6A6D87F605592A2D1FE74990729E8CC178CC0FB95DB0614C32DA2C6CA95248C5E49CCFB9324288C4DB7DE4F360453D709810DB5ACCD5971ABBDD59D8542EBE07D79FEDBAB31B17FA7F174CFA92201B713D85A1A84D74EE2F75AC46AA17ED102A3071CB6A4BE05D89F7CC52A1CB4B6B70077AB7F63F022F92270AFC92EEFF099982953BAD9E2A6D7AAA28451E6C4B504C676DB09619A098CC81B5C22810C22316FAC3CF63F956D9CE3878CD0D5F07DE678313A565ADB2BDAB4FF35023F0491D4826E232DDA2900BF52ACC1C064CEF88D471C18F8C53B46A6536D82CA9C198087AFDBA057D7F21268211426F1BF94B14DEE4D910B11207099713549736653454B078C341AAE03775D3A138EBC63C0D94F81BB8A0B5A0E6BEFD5C9E01E258E4DD5336151D1D299931FE2E5386378BCD8537928E261F606FC25399809D57D0F0F2C9AD6B05A6C231F4ECB390E72D2B0AA4C366F83AEB4E9BC95A51AA52D03861E02B8D8FBAC8979A58155AE5B887AE064DFD1EF03B832B6AE866F3CD14209CC13A686C9E6E01576633892EED2728490BD753CA831EF03D4BAB0495BBB7435B200E3A5BAAB6286633F5288EA9DE38CE1A68828D84881FB173729172A91C606B3BC1EBFBCCC66E96D569CDD840EC53982DC561855052A1A806EEC0B436C1DF42D5A7AF9209E377BC7A6ACDCBFE0ACBAFC8655154099EFA4BC8D25C6A7065C8BB008C0D2D5184C645F3A354D689C0395E032489BEFC6771E952F90032B511E0B87494279D5E5BA583D6B281192162E550911D61B7007C34AF3958CD7EA50F5B47D727106BDE27C8766020573C1DB97446AE2F346DAB2CECE3532EA7C9211B61807C6E9FB84995446F3D8E5C2B8396E920EC304F43A028F59D0F9C4962A2262406C3C2E280B1A458B1E9AC0F01C1A038145001585B21FD0442BB45615577B12E25A671A6FE94DF66D682F4CE2F53599D7C5C9E4C894CFBB7FBEB8134EE10EE90ED5A4301A80D6A5662D1CE604FCEBA8424A7ED6D17EBBDE716C31BE11BE36FC755E55F8FA02921B5BCEA1148816F67376FA7487D74D9AA45881A5D9706B41A64E9FC3C743217B4C56E44B156A9DCEB2A927244BCEC968AFC9AD28F13761BA50F73590C98E3007756C6AD030B0EB63304FF9326AF130202D044134B1910D1EF2024A67F811D73C772A3F3955A694A264F68ED3E54C9AA928D25F11905C61B5907D4491789E1B43C37ABB9E47B734B63502100CE8102E0024355840BCD536CC3729F5A062D09DB4AF21A159DACE8BE6417454C13E8C090BD60AF16419EEBBB4C23A8238F674766057CA1434254A7790E0145437C3AB49D027E77FCF4145232AD469B0531384CB7E10C244E0F9969BEB8532C14BA38B2A564BE9B22B64B975DE8DF44B423523C78F3009B3BBC4344BB97888C54F711B12EFD172CF9244657F9FDDDC7421F748376961662241BC69C610DA8E80F65C2ACA7483EA71CF5302A639F5C11D1644C4DA25A46F93539F2F92E47C113B2C51E2C6B6B221E8B79D991EFB88547E0017EF6EB645E8613F44BCDD962E909B4D71BC7040E93A9441D0F8EA65B014F0B10D64746ADA7101B4C7D6426A7879FB2C6D392D48B68277CA18608AB57A76C12536A5F0D08EA699C137BC58ED51183BF49BB60DDDB6B32C845AFF4FD8657E2D318C4CAD65259023A488AFCB1423D3B620E253DF1E05E65E4D61FA13FF6C54B80A1FE3D5DC3FFCA2E85490762B064883A91E1603308A0C2AC14651DAB71BD2164878B5E19B89BCA4763DFF9B02C7A0560F935FA921BB475CE4922AC938A21E96E04494E584AB465BABC536582FFB0650D6C4AED7F128494FEA3E598ED651A52EBCF3AB11CB1F5C2821F935CCE98AD4BF502FEC70E8BA7C3CBC658B5BBCFF3A08C4A1BCA6D23EF5E18ECDA5301A6C05FE112B44B51CACADD352AC478BE1D6A5B95C44E74B814035EDB328DD5432AF8A346F6C9EA047FF099977A0E3E6F38F66FEEE3A708FC81FE346F8CFF6896B10AB8B1001A6C1FCBF87A74A5D08A7BF6E38B7B1B6A290BB425749216D3C75BB2491B009F2CAEA10657E0BFB4AA55F41F97F0173769A56FBB1DA124F9DF3BD4A4D5AF37F03626A9EA70D95AEDB42F77C6D8767115EC5EEF663C590992F20FAE559BA85EBC01518E893B56891ABB5E3A3CA69EDD0000A504CE6D4C3B0072E122541BBF8EA1F92B541918EFDAA0BCD769E8A502FDA186DFD1101D08A0402A0ABA32E654A35C7CB836B9E1FBAD1A05119D994E2FDD42C521750E73FF32F8424F0BC062F02AF18999DF596B525EB734EE3F2DBA259D6CCDC45FAB25C2962C9D7C3BB624948A81E67E06AAD58F03D8810CBD994A32E6A09631753F968AD52AEBBFD4C63860E182A6E4C40695576739F73053E07A45F4F630DC8AAFE9DE67D0F110D49377F99A95FB4550A8209DD7DCF97BCFB20F8048C2D40C697B55E110CF58183DA9F8C5E1B75950C90426306594FB458B9EF2E12EC3FE2BAC4024CE9A2CB30E0CD8389962996790F17B81E21B3B460E1D15CAAC7E514FD62AE6266E7BF80606AA5239108556393B2F816CDA74234AD68273B013A5D5F699CC7BFC2AE6062471959F3FF361B26B6961C7FE142B865C4CAA9E2C145227682B0A014FE3392DC984C2033E9F6A6AD0BD40E2D2F8A09435D7CA8FCE6E3B6A27DB11738D4A4D62409D806ABFC95BA74BA2B5237091B89CC390457E82B4763AFC63856B3059C37C8DFABD7FC2536FDA49D547A5353849D949CFC99FF85053B5E72E5FF14181D2432373F45686F8294070F42669DD3B62B304295EF515C5E7290AFB9CE186874E61F33606B85888BA0A5AAD4E0000000000000000000000000000000000000000000061218191E262A36" + }, + { + "tcId": 53, + "deferred": false, + "sk": "9CFAA43CE568A87D072CB544AF4992BB2DCAA86AF0BC22A2990492C8D8FF77353E33E8C93DAC2CC3481C58912D1385E4EAB196176CE275E38DE46564AF01FB84CFC86AFFA7F40A623395C6CEE1C49D0B544314733D1B51E7D6433914B2D768CC79369C733040E177C2AE17032F848C9A6D86DF02EF9C85FCA6421F683E111AC5519245D91661D2A22CD006700B319019B985C0A48C12106A8CA2898A269023B4919B4225041350DB82050805050CB66510B9918B2868A2A4819CB25180408683C84422B86C62289061320CC1446E9B1070E14401A24000C3183019B628143370E3146118C98909308619206404C7051998494A0042190505599028E0486A0B908D98B224DC288C4A12720A001010030294B8845934210B924023294144C0648A2006814690C8B46451244A122866531288E2407242A030DB4001541661920405E2042D9844908B8801220406D1241151A80C4AB00051B62C81848501965163A02889442A01A38004412D0A99089024651B248ECA429008476D63B83198C4001B0224D2422D52B20523C7018A1431540264D434240A174D1C124549C624DBA28C01B58403A82894B20DC9C0041C0980483482D8120A04B780C44289C9866462963123A14914222ED12672043732094585DCA46DC9C40CC12425D386708020295348101B1082DC1670C020859CA0456286610B957001192E5B3884D32245843001811682032449219769193202232332A0B291524424114921A4B66940064A90B66848308452A46520B96D13B209208264C8980062848D9C104AD404220B2920933645C0C831C93009D2A829D3065189248484C889E23232D448300BC70C0B4410A3904992A6018B326AC3A445C9B805E3C670C21492C826061B076CDB928CC2A0451239111B292D02B58C01C38183A8049AA865C988091AB54001C0808B106111212D1AA6851A854881002EC24009E01884E4324D1A37698AA04458C28003B48911280EC3028294080411285112480C0C242E21098E0B832D19106D11038103C02113004001166883088C40220E0A00400316709C188E49286588000CD3A24190A64560B20D43C669410610542824DB484C1C330540848C53226AC9062A0B954000884958A8901B4109E4800D59A0041C2188223744CCC60902172583B03048B2914BB0911AC2855C42119A426523306A10406C04056EA1182E82300453A2609C848409304598A0250803861A880DE448821B222DC3A2281334000C07481A268851A05011988111218A5912881311024A32011B3209C8120D1006701A92690B3486C9146220B06C82420403308A1027484B46018928452489488A8860841820D0B4292340524A086C23124D1A460584B27014B44D83288299C28419804403877004A45019343022A889D1206424242019946984464823080DA00469610044899048500432C3848C441869E1A44DD82440E2A2705292851343605BB68CE4946463328E9BA20510A88001338C14426509062002C02553104A81264A912031202700404648D0224C22424200B93192B229CBA69082C250E018419902650002225802305C4030A0B04C91809081B66951A688C1B46C4420420C098664C00CA1825114254D10B6481340099B986100174A9B0690983228990292C928508CC00DE2A2911A3168E0B271E4C88402C448C9887148B08500068C01470903112D4A184A109008C8C82044268902402122954118A90044908924349200B3301A390AD43649218405E1386D8C482112968D102512C4446AD4128591040EC49025C892910A0252D9C24118478160B664220886C4127012146A8146500A132610320541206918322961C43153900013B58D84364DA4A071D39648D1886C11324A1A178C8B264220800C8BC871529491D1380C538671A4C22850A60D11062E20246580C02C0B277024B8258C128C22C44C89126458406608436A4CB489D80400DA225189042600C068CC26408B342EA0C48198A050A4185243801014B34D8308210C409109A37098B40880142CE2306E0A0381120020E4B889843491A34408E0002292140290082123A584A2864C1C22328A444610805014265210B9440A4860CC2892D00271C9A82CA43049191284E41468C290910117096428819134054B280D42C06D03244DE3028D0C2221988664C1888D1903311B9520D9C26CE0B064484844CC12100800817B2F78C1B6BA544AA20296E17AF66295BB4E9C2F97EFD899DEEBE0673C5178418C2483F75F60CCAB0C83134B9B4A94845909AF24825E8B2B7FD7C302802E41BB9483952C269509821B2767F78EC81221A8DA39CA557746194BF9B56FDD4116E8DEEB5FCF17CDAD92F22E976681D0E37F5E9CD6FC873B02CE92FE785892F22BEA2534CE88F2D737A22C5E5F73D378CE58AD2A62E63D47A939FF23A386FB778E4631E0918BCB42ECAA8C1ECDAEAA6F608425C7F5CACCAF1288A1B1CE503066DC671404559AA2052EC519C8989D41575F36C301C03462B63C81B4F287E16CBB2EB12B1431AA66843CB3DD859CEE21BCE990CD359BD42E1CBDF357E84E7584EFA3F8F118AA61EB8A66F16F3712CEE9CF8F4DFD2800F8CDC8F3B7729521EA42156DFBB84F9A8D0A1D347FD56837AEA38FC9563CC7A8D0541C1BCE5E3F81855634C5B45014653DBD30BFCA27BE063B56137338DFD80FB96A8626105D3942D335C6CDBD1936A14EEFD04B5BBC99126AC18F11E0FE6BDE5F51C0C8D42FDFD73F4C39D82E2382CE601C3E357E1A1788DD64B2115AA7AE1C1E873A283551E3D801D16F2947493E970F60C8A2388BDDADDAB0D35EF4A546844653504C0C44310268A856EB7FFC7A914BE7682E2DFC284B02D3389BE94051710072721A3613325EE27804B28792CDD00D837EE96E7195EC21C28C1A9C247DB9E1EF8427E724700940675E55F0AD0469D8F869D05BB426EDCD8414953AAD17BBC422EC5B40F5B99F45C27138439A45578EE8906AE4A9F9A6B1689E637CAB44FA7F901C056DBAB48DF8DB3CF7B4D35B85064DCA231AF02186488762502EEA6235BF6E05D7EA9DB422BA528DFABF1675F12E623BD830678E4F766AE7E4983DE20869542DC1072DCA6602D11AEB33BC50DAB0A9E649DC15E96FB6D54DE9174B4EF6D887F3D818643ABD9E4DDD49084F1331A55FB55F62F76D08E8CD07A6426B6A58E749DDD3B625F1814B16F397142C564A8618309D699E96EFA073CD149DE96CD85B93C163FEA1130106BC2E21F3BC0EB1DB7D1531C59DD2DDB10EF74631B8802D96597761D2221417A1723AF765AEF0E771CDDB0A270AC231B94DB3F7244CC3D73769D0F67674EE83F425D8B19D3B67F40AE79A66F6A41A61E4691B13F07A1CB7FC8ED1C2A61981BA4B61F4A3A3767E356A8285C5CD4411AB6B357822B6CCE371737400E4EEDA392739AF01CC06D8C4F4A93733E1C46471DEAE58414FC9113EFBAA24831AA696316F7B026205FA243B5AB9551A406EFC492492286774EDEE8B44ADBC103B5F9D839E5951B30ADA098325190F2C29EA51E742CF63132C75FAA5174A91F32BC0F8DA4B134953B8F7BE24DF61F4E6BB063273AB0743CD9A588D0C52042B54B98B6418DE97FDED42CBB8B8DC119E5A25589C74AB3C04AD8F8C3718532B6C58A6FA3ED5FF8816134768FB0E759073CA7CFB9A1111E7DAEAB996444E90AE56F37410ABB89DE79BC7E37645D0E95CACF95DA965291EF0D591851E21C169EF7011D3A6B22FEB6B59FE642303FE007F670053B735EC0CB5EC24A086CBF97A61243783C76067230E6F2675B4A774654701462086AF7F1DE30C9A5CA3CAAD054FDA848C73609305EDE249E157924BD7BE51827AA4BF690B48291D32400CCFEFB958CB772720F14667971E0C4EBF0D2A30F0DDE81CCB464150061F0BD63F86F73D5AF82E4EDC2D157D65468FCD911267DDB2E5CE1A81E53EF15207EF35DBAA121E357EF896B16E57567449F5943EC09E582A8389B2A43654AE42A705B71F2C991111C654C209A1AA82230D41331D12068FD3CB4F8BA7B79648F0B912253F0016F218366373BD75697714599062BFE9E3A74CC41963DCB4D6714750884A808B7002D8741702BDF6E11D0B2CB5E50707F975BA16521E27A2CD61B212ADC3C2BD18585E892FFE502B2FD544839194FED40EBD6B4157018BFA88BAFC974CEE7BC2F48ADBC2DD83623E79E20A8140C1521117500839788416803E8624818DEE8C44DB061844FD59FE17718030B128FC96A4F1736B0A0A1DD35C4DB35C32311A159869136F3DFED441DB5E85BC65DE9364429E9C875DC9B45295072DF8E3A27F4C15BDF6A1AE6F3C8BAD757B07AE9931F28BCB881F24C0C905DDF30576FFCDA8C9E69D55C799955486B71DCDEFC0717BEB8A259AD2CA0EC56096AC600B85EDF86A8733741556244D63C4B162A7CEC011DDF0FBB729CD9100FF5E2B36C1FF8E0CBBA1A266B806B601E69A3FE9EE2DEA984A0912D17DFA148CFD3C6ECED913F1A87CF0F31464A8F87705DD52ABC1062876DA03DE4665FF1FDF672A336860C12E26FB1F3048C02337AD24BFBD29E2B9D806F94E986232D1EE445BF8E5BC74AD02D5410B9630EA4B4A4A394B9753330D7461A71AD6241F301BD01D2301DD9CAB3CAF9223FF5E76559D5E2D541371B3EC883D513DEF4007934F8EAD5BC8AACDB637125AD95351191419CCC6FF3E4B563D6EFA0DC05CF9751DBD8F378AFA2309CE3C997F8DCC6EF5474F480B20538D50E748C1A93246BE6AAE76B2F1B7ECD70F76A28518DBD47D8D7AFB153F90810BCC144E046EA122CA08731340007B15DAE2B92081AA296C21E2E25C0C25732E69CFC0853D595E21E1A99BC474EB505F7D7F2946F26D1B1A7A0F52A24EB66E8BCB6CC52C8D9E81FB6E41A45592F6BAAF1395A043C9C8DEFFC8F71568A0C4295752FD2B71015E0E6EB398BDA095D12BFFCCC9BC497BF655412358BC72BEEEBFDEE8CB674C7A9F261F6F0A733032A6BBD2336A84CA177F478E2597AA9255673D69484CFDC0F1C0998D97EE70244609C3F79E323D071C059F8786E7E8F5A3596287F7E2C8D60083AC7326FCB75B3B56E624CF4FAC34C01E21C34ECFE88405D68C4B230864EF4CDE22B9FCBCE5161A6CAE38A4D099D4A93F169928C319CE21FC48EA9441643471F2C449FDC13090BC25B8762B132D750A7F5A6B2B7605714D9BE7C70AF6BBCB0A1D5BA3653DE98D0F1E03A884080560EADAF1E01F4A6EDDF4CD3D98C8FF0785DA54A418BE93703FF14712BCE9E5916A2FF52D06D9C539B51FCEAA7CC260457EB3D8A733C67A2DACB2EEF8D46CCA4FC13044D14578663369F1F7CCF8F23C71252D66E926D26E128E857D710EEFACC1DA18C1FC859A61DA318711E52FED92598944541CFEE56B48D41CB94ECBF0B016C278823B500EC1FFE57068E7EC25E81A6417EBC4FB0EF446359315AECEE524CDA148F12A5BE2A80A269AA17A54246AE7122242607C6BA9E7779E4CF986A2C8874AB5C2A3330E921BB1B19B76BAF2C0D4B157F84E92D9EC674E83D2CEAB88403375AA5E78BB45C140346982C0FDB88DFED89AA3DD2128E0602F4A1F10F21A43A17FD7E8C1FD4567E8A3D82529385BCE54F70A6C74011CD4B76F52DFCDBBFE928EA328B4B7E1F0EC6E4F08FDF6F642AD1A5723D99CE8A8398D445D6508F7088F7AB2D268998E72D18234AF6AE40C0AB80688623C917F4B1450DCA2D24C88E012BCBA8AA2EE1E4FCB1AFEFC2D77F98FC92EB4379BE2327E264FC3110F297DC9E6C0345ED0B492C870A93D1169B7968F0C2482211F82F079EDFCE64BD201A22E43E6D6044E3CDFFAAA0EBD26AFBD8194AEBA9AF709C47A2567B55E6C82FE5DD1E37405305604E89C33F48827E0884D2AEDC6747D99359ABD51F12CC6D2C21E7686E0327E9971EF810FAE9BFFB6B03E77557202355A6EFFE4273ED49F2D8DBAF1EE9C7EE3B77CD4F322562AE3A4740BDCCB8373D35BF3B8E447B74EAB1EAF0CDC82EAEE7565B4C8728ACD87CF280FAA8DF09C7E90B60A92825C060D9106F86ED34BB70F610DD9BF3802B5BC777875BC36B7F7676B60052761DEBB587F1E2CF9D556055B7D6B524B58DB8E3738E3F76D8D6615C4435C8A1AF698815C5FB515BDF9AF96FB1B14C0DB6775EF4363EC6F2351543A1156B85D843D526F75F6431FE2FAA52FF7942C877C99B26B33942C0A8A3B5FB3B019EE52D58ACC7F25505ADE989A663599668B8A6FBCC440393FA9DEA85F2588F602778ADEEA0809415C14D15182BD2663400D68B6F2146CAA795FDC265FBFF2E62A0F46B6EEC798366AA6C16F1F145B7A633B5AAED5F619003545871385533F68826BB1770E004FB5640FFD3D06ADF51A334CA0D59EA8364219FC27DFC04422CCB92B38A59EC0AF366E2DB116AC68D6C783391000F8BDDE5ECF594C49EDC5BE7BC014AEF074644FDAD28D74E29FAFB009B8E64416B0B1C0A0A3887129B77DD7BC07203931E384CDFF2C0E46328D1B001C36227047147D8A7F7F545DEC73E82EF9416F21C17AD782F528E7DD6BA76169022914A4462915EBA170CC77347C1AA0B818D23E806BBE51617CD63373031B5997C00F249D6A87870FE7F893A1AA9B879D4D8DCBA0E5DB2D89AC96961759E0238C051B7D7CD35C0990F702B799995BDDE3433976CE8F71D127FD0A03AC4F568C23513A8E60679C738BC6C746C349FBBCAA9CDFCE05ACBA07F9216B04C38CA47FE8AE6E4DD859AAC69685A8D1DE94CAB64377ED91872003ECD2DFE75598D5ED38036610C859D87697F003FE2DB798FDFC7164391263024BEFDD6A5CEE7A0AE0EB7C3C3F3FAA469FFA981A74523355AEA17319AF307A3BFF42E2B049CF284B1756ECC18CF950F6A279418B60C14D6E816D4EB574FF8DBA527D19ED0C87F509A0C021F6EF8DCE2E6B9ED896CCA1036AFE189181", + "message": "D1C758470730A9530BAA46E7234AE84DBFD46DD31974399C9B1CDE3A0340DC723A26A7BA2A66672FD116C8B02B36D974B29B5A658D1BCE798282AE6E5F7B6AD45B711DFDBE9BE8193AFBEEE7EDBB1F4A8B3DB66D1437E3572366551380A22AC0FEB66C4A8064B168096E9C7173F1DFD8962E10893C688AC7BC9E627004F187D76C62D9CD94B5789CC7F2D69FFEA0F685D65A0507", + "rnd": "445315AE90AF35312B52025DD2DDA792C1FEFC54768E9ABD95789719891BE1A7", + "signature": "B23469A18C93B7F5522C0E570114BF05FB9F715E3B7589D2CFE22EE22DEAB53C0600246D1D714C2933913431B628600E0BA647CFFC8F77F2E210FEBD9C3B363C2AFC13B2DD175166D01321CAFF35314EAF7B330E1066DA97D8053ADC3F480C3975E9EF0EA9938E58AADF9E08CEF9CAF23AF99D0F5E13F5C8AFC2D09A6224395A2B09882A2887CF73947C391186A4ABBB42322DE8BF981D4C7080302991A80BA0C3A027AC351FA60D05054753B1788540600B4DDAAA15431E1B67400252D92FA222F44FDF9A2482E73713B6DE71828C2406731E4B0D1376488741AFD61644F0868E740DB98B76556419CFE047CE04830E45913090D185E9D6ED5929828ECD4E2B5E476F859D05874393823C6E84CC9BBE95E61B7BE71B6584DEA865B2920FCC3CF9876366A4EF2ACE1173A06C040CB79D356776B392A6AD8390460897338A1FF236B4DF0D013CE97DED428A90F5AC5E84BC42E72CD9CC7829B32894C16BC4120ABAF2576952CEE833A8C8D00AF3977880A08A717B4C761E3F1534376D802823C161CEDE94D07B8889FA5CC39424A4752DDF8EED2378AFD2CD54DF531179CF2E94F9E88042E4C4C136750B70BD72088EA46B556215A9C0207AEC083A2B6C92C919B2BF1B7328CCE3AB628F6BC612917A66E4F6B146ED91B56B54EABE8EA4C95713F5AD564DD893A4D2DD57835CB113EEEE1B0D7D0A8F9A5A1606D143871DAAA0BD5D2EF8D3D2741CBC7A7419407A1D79EE695B47D00DC95165AFD447F69F2B3F82982B7AE8A5809DC97880DC776DA44037005635079C2E9F9422BCA1EA2BB37FD8C5B6F43AA42A1BAF22983933DFBB750EDB1D0B3A438DF1A7E2794309370B33F6F8313D2324750BBC6A2EDB48F3F849CA8A6603B2DC47DD7F70B787A12AC61531AF09903252FD339665CEF2F5DACB3F8AA1B7C97B47EC5FA1DA16998559056315A2F86CD0CAD4854EE972AC755BAC824685379C61EB2900F08ABDC83DA51082B5567698E9B6CFDF394B2782EE9A9EF37B90F05B5B7F914C45B4966BEA1C20A138AE185C8729AA6489A3CAEE50CB5CE1A57D6D3BD7DD3D4D3F1609106A80E81AACDC11D6AAB0EDDBBC3CD69460477E443B33FE6F9A432A080DEA648D1531B9C7A6F18E1708AB463DB2F15D1D6E88E9BC05B9E06595A66E96D70836D903BAF3E2ECB477BE5E209EE9527C0198AC0623EC8469321A62DF735D495E01377C4615087AD6D1D032BDCBCA10165B80D64610B1A2FA48967ACE769D8A95C22131CAB9211192A6745C947BBE12E5A612568AAF749F43105D4057ED411153CE1EEAEC8ADB94CA2997E4CCFCE645EE1DD5EC1107A43E90C277E781B24CD5BFD27365D50036E96CFBA58FEBCFB6A55D7CBAF749255A5E6FB69C17C706265D7B4C81D1FEB22721B22D165A4E1F8DDA0FC6B9251404F71C5D827DA36D8E82C35DD8BB5E886C59642EF99BAEA1DF3DA04EFDD669D5FAF274A98033EA891C0FCF1885860DDE13502FB5B7B9C789A191403183B71D7DC1BD2CEA43ECF3323577D1853A7E6FA8B7965CF5E0A14BDD7E9DA85685E392E32CAAF8B935E219E81631F7A50B121894BAD39B173C893AB13D11089CD555149979D98980B18BB81115C9BE35FD83F3353673FA1DDB5ABC0C8821BBC7793C391DF12D10ECDCCA3F1B57A91A21B7DB46862030A35DFAF3799C7CDE1F3C1A5060D567DC8BF00F92661183AFE750F2FAF76E7C5341F01446DCD45D7EAE9762400BC875BDAA1BF92F6FD47D85A629BADDBFD6455B8A53BA8F0218D7E7BE96CBB3A0756FE5DDE75A3E0F763D44790B5F6B0273B55C4953AA108CCD9DA438C253ADD439245119C83E066F89DB8A4DE618B373514D905F4568DACEC9564105C28FC6E37823C3AB7A391D1530F3DCD971DDA4DEE72B2FA971C025BD25937DFEE61E45ABA3DBE8B775297CB9E88ABF1549B622813FD5B5620B9248FD1E2CC8B562AD308E2A359F8AF73AE153D7DEE8A63357E48C8E6BE80B1BD0DF5407387F8A1BB00F19F3DEDEB5E30990FA84325B8EBC6039B021C1033EE47D1C3C806406B0635231517559CED0DF7E26CB651B67D79BEDF66365E9C2E2298FB3DDDFFE589E5DD1982628BC1BF4DA4BA3FB325E8BDB7B8191FFA1DF9815B71CB483773CC20E4E09BE8DF2915C24C2ABCD7E6EBF225B8185F242A62ED78BD29BCCD243A48C0BE697185CEF2FD6BF77BC6169AA7D98DCFD187C0C0551E954481128BFABA82269B5C3628FFB8656F367F3A6595532EDF2349A9D335003A44343F0579BAC8D65CD2C3261309855D9671009B6E644FE3D4C2DFE5F4FB928682E27FC94FC7BF65BFD71B1559B848FFE25AD07FEB7CE282F88547FEA518EABCACFD0CF0EF6BD56EACA079F285AF04D59E31A0D2E03A3F26E8F9690B29CA857093EEA5385AE8462A100D57AC2137F7C3E6A656D6BBDEDA706964C8BE08434BAED38729E605AE209F2C2A71FF1EA894484439D218F2F1A1CB4A89ABEF4EBE122DEB17026E488C2F894F42147263E4C2894E04715C04288BBDFCAEBC395F93159602EF72A1B89D9FA26D1745B10A87D038BBED00964C6719989BE6411F68670B35E4BFAEEE9545577F755E2311041C40F30DA03D4ED31C3C68AC5F6C03699D50051623FB6A186B7FBF38DA82DDF7595DE79509F36EB6566A54AF76213A1539BB58227314882C219A5C7912C8446F58B12E34FA3EE343C2056DECBCA69F93828D40E20806413FB3AC335D1855EFA8C860C8788F9A1FFB8BEF7A6F5203EBE5E8B92204C0CBF2B6DA82523D22A30D96BF9A4554B031A8866F1C41487295C61E43FC4AEFF7AAC801AE6C66B3A619F586AA28425A01312F2B727F97B87856B75296037D1AF3A87FE88705D836BE4FF958C16728175E940041A0C21BAAF6D62C6C87EF64DEAB002213A3C73535CFBED83318FAC82A4EDC91FC65B0D1B769AC1A4384D1E0D7EED6E576E9C919BA9529F6D3FA37C1A8C4B73D2A153A209740B78310581E408D5AA38CEDD36926E375743D006504331B4D2CE32079414399D380D4237FF1927C2A3CEC0F1CA4EF99F0E6D13B0E8B26F9B079AFEEEAB584153B33B10E5D6F9F4FFF95B7069AACAEE850BDE099A6ADD09959BDFECE2CA640E025CC44A7E9806949994FC618CFFD21CDB30570028E1FD606433D2DDD0EA7606F8839969438CC36B3536939A999026A4DDC1DC3D59BC0E784EB322984A475675112F493B5A8937AC8F6A728DED17BCC8FCA6C010A087BC159C711D1BDCA47769E929BDCD86613635DEE4FBCD4838293BFD9084BC7D2161D8BA89A1D2443BE00FEA224DA2A67124C632C7B561D1B1DBBDD7458ECB089CBA112C9698300AE664B29C1A3A99D2DFB8140CCEB489D928D2178A92829A8C5CF43AB4B9EDF5683AAB64E46B988E5FF5F4743367F84B459103E0B4B8E66411224C06D07A04805719873F9FBBF315B77ED876B4621C8C310D5C75A4E4A9ED3BA6918B81879D7E37C538066525A80C92B5A46E7FDE5ED2643315C6A3FC49A87EDF3B9C6D59F9E2455EF1FC09B5E34A860A6A07DC7E1C49CA2FD6968A422258F77E56336E5F4B4F2C00333571F2981BCA4CC6850874636CC05EF72B68DB6B0D51B757B620D215E4BB2DE99DDEE26660103789A0A5EDFB63B02E207A22BAFA50428C32A4AF52166AF0EBC8ABE13AB17339F84E09174EA0DDAED903595287981C1CEA280D9C0AF6679D0A4BA935896FBAFE85ABE5E398C7B8F1B73F63B7E2C9029D265FB53E13FD53CD587D96CDF400D5DA3A27ADB6AAF50248AFCC810B31AB00FDD3E697372ADB83FFD575086425E9A1090852425537F07E141648213A457A1641879C666BCD42466E8E2DBE7CA7DF3AA7CC1F738E44ACEC1CC4A2E7D15EB2CE013FB04150C54E029FDCEC0DB3065157075C3624383D07ED3084498A8A03E5FAB3962F75F28549D394C8082783BBAFA2505AA750CB036522496436AB11671D014CCA32A8327EE421A69A1E6A7C640329B12EE060AF0D3119B2F80441DFCFE9B127AEF36EE39E4563BEBE683EE1173133B1F7F2195F4A47687D67424E72D5D6B06B62827F41E1833409FBABC18E4C3C6A64ADB7E34B20F16381419B5B1F638D65954062B693F5A28E9A1CC6E25F0885AB55BFA7E8E94D6FF880CEA8437AEFBB8E9197D046616D03B2F736A18F2636D8CE224F6BC7E7D4366CA443BAFD890E583066BA5B614980FF5CA476C382F0319DC11B5EE10666C3341101A139BB43273E17F0961FA4FE870237BD4535CD41CE33532DD7B422B389769FB471B008C170E459DBAE2876EE8F23475A82D987D369687126490D17A9A2AAE604F807A4F9CAFD1C96A2ABBD913F11FC4BB9A80E78E789B0F6A5E10E69A824FBC9FA3E30D2B41CC86D0EB60B3E3DC2F1CA93625B0361F14FF8036D7EEE4CF98D1EC35C66B73E685198C52AF6FD59E9A53EC7D8C88DB4F86951F688FD25E837AAD3DA6D1019B7552406E46A8B2563E5779F61AA3F366AD3727883096962838F10DB16C8687FD451B776275EFF7FCF6B3F567013041C569D1E60C1B5C8EC1C879E3F2E5CD3AB78A371EB1D3562692D31C3DB9669D66155CB12BD053213181BE515A84D489D96A1EC85543562FF83A50A78786B5B552643FCA918F6A41EC34800DA6E14547FAC68F20948450E4AE1899A20BCF161CDD9B5F6E62A87942C9997CDE3A5DD354B82CB8B3539F2576E2EE0C1B93D8146318327315FA27C342F9221BA8944CFCEDEAAF238A21C12AB4EFD5512E4AD5CAB2BE66A520B1BEB0E357AFBAFEDB2BC8C56E1CD1B139CC2937F24FB81315A0796BE92EC8C154957AB4EC1E290174F12AF1D04E87AB07FF03A4E65D1AF769064734CDAA14A82B1C992D4AF8098465F9ADB1004044B4239B84AEA88115D14EE54A1E05C284B6D94F71D300E98572A07A335E5A986909178B31B572E9A4705383087EBD75F3945E57802F8FCA532B5BB4358A51B5D726AB1B959B35206DD40051E866730C009C89D442F15DE88888942BF4B9338F47443DB9646CC5C8043F757EC219B2BB5E7065710499BF62AB47A93B415A9340B4048000FD3943E692CD0EDFDC129D83578E1CCDB3025AC43B7FBB06953433347EDE591C987627D27692A21285B0907E972E4348FF7FE2DD33A685EB9CE5606333C243EEC252F468AEB1783D1884615B4FE7F965CC3C770D4D7715D6CC16914BC3DF693CBE2D79FF914F96BDA88217765B1701CC2D99FEDFA60D8F00CC7B6A7BDADC5C30AAC45DFC4078BCF5A33C1C7C22F247540880D328F457D4C41CD24462C502DD854707720229FC2A0158CD0AFCA67F701853431CED575310FD0CE9E422878656766DF0C07A7A38D7D1E3AC985039DFF8B365B3B909A48D030661DD1F3FF9CED6A256F603BC7587325C4E527E1E2116F47D2F6D606FA6877101A42C9D70FD8D1B5542E019205FB0052A0CEF042CCC20B88A7779DA8780BF68613B23D19DBB9F27A0DC2BAC46EEA362FA97D7E90595A8A17D7209834E4E5A66336E9F649A36B644331AA377EDF4D29861149CF4B569CD4FD727836B924575591E323FFF2AC5ACD1166FEAA0BC7734DBED34201421B76F31B34AAEC60AE123037625BDDA4A3334C7022657887ACA7212E2BA0C5F1AA1AA35C6467127C255941419F1B8E08016CC1398A98B003C40C7EB68F9C6328C4CB9AD2D4B6DBD0D699F1E278ED5D61BE9F84A7479A8C80AEADFC67541F8CA679C61E13CB57F8B9AF4C284007CF2EAF0C626CF3F53BD2E28FDBC0166E2C6E2DAEAB98988D2CE41359DEF85D3407D1D3B874F5074B21B550CD56888E886BCE48BF1D81F01A605F250B43E79BC3DACDD75477C8C0C4CB8E5A555C90860634504F7AE33B8DDE118AF2F0AB22E9F89350F374960DB99714D95B11146852DF53A508C8D318113B8B0548172A7FCA1F69F001566567201591204CE1D435CBEEBD92F9985BCDABF1A34E3DA49944D8A935B6D2F6911799DAE3D8C06018F238ADF96856740329A8FA33A76AF3480A73E7793693B6B356495FC7FC5A647BCADFD0EA7C7BBBB0C532707D962B4779729C2F7636BF14CE858EF0783BE5B53C5313CCD2CFD6B670993BCFA580212A030308997569EDA43CA50EF678633E918330AD279ADA75A06E0187234ED049878C4CA06B24797BEEB5E460E7A4C37F15F69AB3365A1D4F378C4524C020C63086422C7579918471B58F5085771C850B03FAC49449CB774D66FEECDAF5F20A15D4579C4A7107DE3383FD7FDD7E3132071263B1CEAD3781F3D46EECA48F4702BBF85ABDD62F374CADCB7FE0BECF8B3A7E7E167EDC0881352883F4F99C769E605C28C64C4ACF0A35BE8C45B6DCC15B657BDA6817EC1554B853D751BE8693D8C388A031C691D0C7AB63FC4100198B60932C49EBC60574E3792C14A1E1406E8CD187858FE49EA79E88E9A5839FEC759B1637BB78ADC2FE1757CBD7A0A6437DA02DCF2684ACC9D93A79C6D4DAFE070E4C5D71B5090B131D436D84A3E2F1053D5F6680C1E5F8FF0311125071C4CD217391CAD60927657F92CCDE0000000000000000000000000000000000000000050B111B242B3037" + }, + { + "tcId": 54, + "deferred": false, + "sk": "209CF1503755890910D7957E3EE07CA9D8FB60C485199EB6E94958413F8DCB76DA669CDDDA0A5ECEA69908064F4A7DF347BD6C9565A3A2E4B7F499B4DD21FE5532CF2E7B20788408C7926F9819CAA78835DEF06207DAC7ECCF49592EC2A63E3B80A5D3AD6F128037ACDABB63EDDDCB123AFFB6B68A4C9CE9E8A5185943E0910949162A54082A08C210811286E3A690E0B06C631202A308129BB465A4286C19A704419669C384859C96880217244C301023257124470953460ED3B02422C8509494094C226A1BC78924A47018A081130480A24220C8482984183194949094A208D438295B424023304801C8280C8310181871A1000218092458C08161144AC8445281B861C0981042C08081444292A66141A0511BB98C4A122D12B40D14A64021A044D4066A50940159265040C41002C92463088681088943C4491C270E53882DC2B22C0306244448120190455A02005CA091CB868DCC92816200010920211BA40C0345409AA028E10466A48490C9086541328A002952E1262589C86182B24484863123298D50004EDBC83013B2440C8249D8462A93B820C03208DBC80042388023C97009B38010066E12381112A66802B765D828021B32711B9964E2C0205A3049E4468E00150A242846A1C820184402C8C42010440509472020C689A10851E3C2400006499936706348510905628B328681926802A05061B805A3A02C4484692419061C310E2120051B0730A0826C12A68C811292CB064011156803484E44865184B26CE1464A02C42CA2140D10256C1987644A0206044602D246525230319BB660D90401929271CBA02D4084401A160104242C030085C98204504240A1340E42148EE33692E40809004029C4288583B66592044D5B38490A1469428468211341C1B010C2B80CE1329110276459B60908334D22A06CC82650CC3421D3924D52442D63300A5C225048B805C3480E23244914114688069221454C114172412211D3808D5CC22D128909E39269A2A4611B170A10B9041A850922334E08804DC29481D1C2700B314E1C112194324A5B304E59202D21282DA29489214048E30206548240410472C904644484314B9030610261531821418880A33605D1021111C84982C46191269152B4658A9290C02004D138620125491A010962166483348D03992D80242CA1264CC11400C2326E10383104094063804508A460492081808861D1C069CA1832941644130208802229E21605A2349219038E98226854A88113030520480EA43824433860A2185103066E08162E103952E4C62803444143462584102C19124501202922204A23B03118270A993486C3304DD3206AE434015BA691041552438608001469190084C3A66111388C1083081A336852B47163266CD23804A4B245514611E412519406010A31498AA06C42164E1031921A924D4BC66D9846869414419B2010143212A382411C27628C12909294210A074520167091887002B569939841DCA841CC16240B254163C880500231C10222241850D1988583C22021B42CE3C22418490C5C440C610892994426441802A3042421C30D6416015CA00D931409D01086622492C24806583846C8960D01A828DB085082488109A22842108C5A004C51C84821A02CA4182EC130654B448ED4320E12A54C4B267021351048324604224C22B665984864D48485A00221C382244AB28412490C5812315B3462240581C10060512208800692D8384809853023B1219A3062C330204A4000D2C68149440241962908168910B564D1246252488DE3B810C2248A22172622C48CE1347054C26084866D58189153B844441010D2C264DB44849204929428258944011B800920343060243143028999242021A3502011410A820D91100DD9B47018112050A40598085292440A6148511C482143B4018A004493124D022541D02828A38450A0B845629890A49000183985194429202344580829C9A440424610CB3405801664090832CA904D9BA2054330110816280C836140A828892430C19200D096601CC031D8B48422B949A3044D121902CC462EC212926184219B0206099400C94062110860D8280842A67112835061A2856388040A192CA3B261223342510269E11046C9B421098428D0040E04032C0C93004134865C140488048203C5918BA04948108D0A959109C80599202212009251A2708AC288C9864123122C48A2710151E50058870C1C30610170B9FD587BC4B3F85B703776E6F8ADD94EFBF90CBD56A19B70FAB9C75BD7C2950C0A19A76384441868738DAF758CEE368883F85ED55CC375A8B93900C3BBAAFC5B25FB409EAD61837A468FADDEED4DF9353ADE759ADF4A0F281DF12559D48BC02694DC5E64C8279503E0F1F22491B7F961801328EAFB849356F0E6F65CD5D17ED98807A8534C468C3D31265ACE7CA849B586B3193402FF6A6A32863301FCCCD2FF742370579066CA41267F2C2FD089A5060A7B020BB27640B31020078B290CDE6FD19F60BCCADD137FA78FA22D776C48ECAEF97DD45770AE889048229275D2F4413601A8F368B4EEC27C69567B7047018A9C9A656AD46DACCFA7351749D0969C3974C01DA631F2EEB2F16F313DC51CB7E7D13AEF62964BC6835FB30206E76C3F1314C6793D55916A56704D472FF027E6C950DC75B29290C922721977A1136B1D8695AACA31AE3031840B603BEBD5CFDAB31A21D2E52115CDE13838F56ADC86C3FD9CA7A3F371C55BFC84656444827C94F1E97998BA50E7C548368B131DBCF03EB86A9721F109FC97DF815A66006A4802B7AF8725ABB9A00EDCB85DF2101B278504D18CFAE6DF34B8A6CE5807FA94A3036E69ADA21525C69A9635594C68977CCAC05DDC80878101CBB64562103147B13B14D8358520433692D9658DF7FA44B40C159F8029AD9FB6D660BB46765C9DC705087E6F571D199D7B884D04104F93FD7EEF066E339546E005C6395156692E364B9688FB38CCDEA4B21686C98AF009A6CB8AB0B3D90C8C11DA06C4A54B957D4BF11A0B920426E7C5AE45941445E7C123329BB68D3AC9BF243B495A5E7CD28FE5D96E8CF5E5065FF414B2922A17F67DDAD671036B6C00AE92142DB0C9EE9400EF838CF119A751D22C11D408A858E94338871C2FA52278FAB1CD9D565926C431E66953704C8CC1373B2E89858B93F219A6801756F91390D8613B32C4727A54502F15A64DC5EAB77D6478B376B91D2B1DA996BC052C2DA9AEB9D1C5631CB6DDDF835D1F69C6164B54AB7B2689B74343AAA75957F87BD383D58DC54E8BDD7DFB1AF9C6BB4FA87DBE36585C693630E151E989E3A8157601597D9B83DF18E1095993B00B4E6FE4F70209F4778BD0FA5AFF80E906EA410502CECD1A017DEB921155C8B7835CB5E9B09378ABDFB054B22ACEB2F83C3664E8966DA5FD9A202BA7FFC0AC4895F1F7D3C96D4BB5142381F61F5CF00C792F710C6F3FE175DDE276999A70B6680B92F27A9661519E0F4241279E3315784B40BAEF111ED48D3DC850CF176BA5D220EB269E9171C9F712F70C19D5107732E44372470517463FEDB22D5CDD3A7809037878FF294A9CF04B9A58D0433FD299765009650D4FC1663A79CF2F24091A6261C110CF84BED9E62AE2475F2B40CE90AD670E309D4DCF75596D7651572EFB1434107864CCCEA64E9E1A9CB29E91B28CE86D85266F51B264CB15FF96A150D4A3CCFD31396A83A20AE19F011943EA2CAB4AA620272713EBB003D6975B5BAF761F3640A552B73F240508A940925DF60A7C6C42A580546E4522310E3755A03D59F4B376563A3C67D46AA9027F71F81DEA4074610AFE620461B348F4FE5CC193320F935AEE4954C05CB1CDE81D1D7936F08D8D796BFBF4E749A1B9FEC4BD528C2D0801EB02004D55CE6C03118D5BE81996A074A3E34D9F6EA73A09D37A2FCA4E7A6CA108AFE608C51D5D4B389768C0A3B873C445C5CE41F679FBC03D53F339E37F292A25B3B3DE21B241BBF8DFD8DA5BFC02D95DED7D17647D4A185AB6611DD3B5633E3550C5D36F3C6735B4DA9E387E27538DFFE1F9E0E59338AD012F2B3FF600EAF9823DE61986787641F1E3DB10A95CD32E88F7572E5ACC4F9192A2B479F5A7A51324BE33327D728E00DAB05D8B71B91ABADC2B7C2A8D970B680761CA1434532A6E9B88F055AC48FBA402766E642ECE0BC7D3F26A246FC05037E7B6F9309FB7EA888FE98CFC80096DF715DA794B0699D4CA0BBCC281CCF5940300FA9DF493EF84915F8A69081D5F713FBCFE566C93314C875583AAE4F20CE3D96D3497DA9DDF2FADBC36D428B84FB7DB4E283DCF3402D2364442BD98EE0300FFE12BE140B105F167F8DE5D5FA172707E5B06BA9D037904B8E16A343C0025584A3578FCBEB3CB81DF4A3FF307D161121A14628B9B3448FB41B7A6C6BA0525C6454B6319C4D8ED75A072249BB15D4CB4C53B2FA1699CA553133651FCF7B9CF4B5AFB5287F1D12EAC913A770FCAA9818756FB5BB6B6DE0969A0649E28B58FB0264659EDB203E54F9FB59BC1339075ACD254726B272DCBC5266F62435B4363254079BB656624009CE7BEBF9C0FC75444F1260E5D253244F0E8D41F0FEF7675ECB5848312B5B21BD3BF90C913A5A4CAAB1AD8047AF7A4AFAC85715A28693908296780E8692E30B14127727FF96E6A7E47024DA021C3113B21A74638E992A31E4C2C2AEC14B4C844279DE7FE7D71B4239ACC1737A64E2344976DE6BAF28E871F8920FD8B709A0968950F2628EE4D1A2BDFE643838147BCBF7DD4F956099964EB4019BD02B1CD1C910839FC2E31BCFDEA6FE30CF0BB6212EAAF68A6AE6A824D9FB34281327FCF710F7391AE2B2DD226C3FD5B272FD32AFC79B06C56B105AE000D720C14AF953CC61CEB99F3596FC67D066E24F8370BC39C72324848DCA63D6DB88B647972D500CE65626905AF5E7DEFACF8D320BCED02F3A70B04004D3E6633C10B274274DCD08EECC7CA63BCFB6331FB3F276F29D5290140F1F292BC2713C8F928289192AD040B3D38D11F09A70FA0632D40A1251A4759EB4D63DAB9B47F4C6A60B8B75CE5E3B80378D9490A2C53401A9945ADCEB43C59B6B665CB13D66F9C2997E628B0EF6A4DEEEB9BAE945E901C7F5C0E63ABB78E0039B122CBF2A9C1D0480CEEEA1135CA6779558C3BFB3335FC967693B378B90B5C540445073656B81A956DD293225F4EF61F4F90EBF9251FA1B465B31F560EC9372AE878DBA10434A55462654226C66730BC525DEDF0C1BBC3CAA44F03325F893C145EA6E433E7944BC4A7F287315FBCBF4AB60231832BFB7F1F4B2D2BB4EDEB6ABDD9660A31B1C73692734B3B0CA047E8ADCFC2982012AD18501C0E74F4EF0573BEE43F2C381C8A724602B405EF1C785EDB21671B46A6BA5432854001DCF0CD6FE2C5810E66C0A592341B56608BF21A5FBD25CD42A872E4CDE0FF1C04A26EAD330E696215C1EDD63E4185376E40C94F9ADE402C1E570D3DE551D1A61E90B6BD917C7131EB111E195E02392EFC8998E41F83F7B31424615BC5BD9D339D4E7BB1D5661CB2E368915FA405785683BB5FD2F310A2A2F786DF64CC1EC6632DD4E52DF98A294BBF575777AF11A253F7974D6F1001381C662D6FBA283CCBC4EB291CF5B5A79F284C0CE6EA9947207F5D4655C8A26162AF19679185FB2204778BD5D22EB1F1E4DC3409DB4A42539E76AC0E65D1EBC3D46365B96CC3C14ECE10B8E3E4CC63FE871DA586680879189EFE5D8D915AC3E6C5C7E2C5757851C3F1B393B0F374ED88528C1BB59C3E95309870DC002A0A10CF5F92FC5F333BF5943AE89701523E3A1220D4CF32F46E0FB2DFD0E93186BFECB7A056541E98F9B6F41CAFD8B37270447BA29FCC7900A80664044D60A7CDCCA95B49C64A81F82C855F1902CA8AD535C49D6C2A86EFA02FCD213770EF00E9F74AA8C8FB40BC83C536D199AF9FBC0E133D0459E8AEC4AD49998E9A985AA63581DEE44E53296AEAC9644A7AB7AEA0158ADACEBF55F9DEBAC3F33EF7BB6CC509B7AC3D6831D8F03DA6D2F103B882FE2E09FCE7FE1C2896AACBF008A6C5E47D8ACCBD12AD47E85543D4DE56280201E4F6243F1542D4308032A8FC662D7ECCD99E2D54FDD436AC317D69E80D1583B153FD8779B2DA53C4648FE434DDDE7BCBA5D77730D6ED126C96CF90E9C12DE3E54B148A9154ABBD083623E37363A0B9DC9B9D4C3A339B8B8791D4AEBB58432F2EF97DE72E3298D68F08D61CD2260FA4CEC8791CFA78734BCDDD485E5C35EEA534269F896FBC3A21A9F68E23F5CB5BC8A24516E2B8E5CAFC55A53A69AFE6500E37E7B8667462A72A8D2C33A652446E8FAF29492BA7AD879BDCC454AF4672D3A184DD20FBC7AC11954DE7DB917C70498E300DCB4DCE12407DA39A903EE84035019371C7AB01036F15676383F3D84421FB4EE2F43170C4A577FA7DF722D8B0F749DF41DFB093496496DDF5FEBF17DDAC067A1D8CCD880C591FB4B3168C8EEAE75444B5467DFF6532B8906BC92DA98BA0B7B9178CF15D881B4C837764245AB2DC3960878D8F89CEFB9ED76322138D51CD1AF6D65C65A415322713D13F03930763E54D3D59E54ED7E5C81A80D1D7BA3583460548EA385C3854882DBD3572B67E4CF836186C516BBF7A6D5BB21F2C14FD6E7E93890D9874E47CA2755B88B8F79469654890ABB4578EBBA3481746B5ABD9A7899E78E3DA3E6639D370F77A4D5B76D18E1A5E4A92A8CCA023C96E82EBBFD958F4D38E2C1FD9D6B57ED41808D7222711CDF3549082AA865278971B8B132F030EB07E9F60F386E133BD7B65DC0008893EDD072E2FD4FE5A426AB8F5DDB9F6B61D30BB07E5977CAEE7FF81C590C65557B26237BC7A1AAF24F3C91891FDB378C96136D0BC5BF4BE4EA780432C0619C4740146E8A100DB1855254DDDF1D53E847A8CE30B4A6735FC540E19010A5F41987B", + "message": "D195727ECB5183C651AF26E85116ADC65D8EE8BFB9D69CEB16EE2907C651A92661ADF6BB626FF86075EC72D375374D69168E0E41894A0CC750D4EDC4B2F8B2C3829B209F80C3556BCF720AC69EEDC004B2DB0079152BC2824C767FB7DAC8D37FB310C0363B00441608246D4CCD583DCF8BC88C857865D443D15C9FC4DA5D8F3DBFD71FDCBC4CCC3F6078DFE96F94DEEB3B59146A059257D2EC7D82083FA58FE70EDCE1AB447828A0339218D038C1C15464DF6A69449D1AA0836455E5EC00D1794917AB31E843CAA5C259081F33DB3741636F09111FD8FFB90DC9EF0F1EEBFA3CB14CAB6F0325C36EF089424457276A737373D1E73C83C5F587AE56ABB1BB2E049D5F479E4EAAB534564595E4CD86676475A1CA4CF0989CF9EAFA19B85919B3856E0FCABE8CE0143DC0C17FD87DB0EFA166AFC565419C14681ED37E62E875F5D61E1295BD28CE133B060BE90401BACD695D012D4FEFD19803CCF38D9F1B1A49A9C581934A194CA394FEB536D99FE15CAC739A7D311EBB57B15CAE09CB6212F03CE589E65D664003DA334C0A4783F5B1D6BEEFB20C572E32ABDEFA8B1C26D6E009FCBACF51B71A9B26A7D460516735ACE8CB2FA2431CEDF7B4DA9D770267AAAE939D717D2FDD7C066033CEFA4EE30C4956FDF2C7D46A7D7B7AE9ADCEBD7BCFF5A122435DB08CA9DB92040CC19767E061A85BF3D15C4CD1D7FB2209D8B90F0A6DF466622E45B5A549CF4F14A641799E83C266DDC8E9C35B0451891356D6782AA6AA4E3A35EBA2C88624DC95B75022600E78DF51E3B6B5BB2E9B4DD10D3BC926640664C8A28717621349947EA4F2F65122964E1FFCDD300B73F0C24C4EB6111AA28187AEA245F65D98DC2F13C229ACF0E89B871E556CA7ECB4070E99E4AF3F425D56A850E3DFEDAAB5A48BA4C9E5128289A6FC8DF96E714BD26A8D90F0AC012480F9F9D4AC3597E429818DC6B77A564197FF45E6D3C03B562B54867AC3172C436B431E2027AA81CE8DCF4D35C59C9F58E551A71CEF6C679F19207E2D0424B476B6536357D23C923E1C35523B605576AA828A9F788EE296CE9AF15DBAE89D03DF0BAD8B3C4621E385C935FF863B029177DA67CB0704BF24418FAA78B5C15C741BBB8E3DF1CD51124D92A437B224267813A71F165CB9BF6E489F588D596F752900E724ADB4153996F0C485C77308C39A1D03E82BEB5C5B406842522B6341D6D359173F76BF437CFCD20A73B8FA28B19BCABBCF2F42CE40405EE4F130110CA0637D7FEF24A38E55EC322BFA2B9DB9245A73643703A55453493BE3041530AF27CD3610721F8224FF02BF758395187C2362F921DF39D9D674F09F7248A3901461B6C112A8C01C1D7B539D11D91A44F2BB848694299265E8DFDED18F3DFE779D13988FC888D301A9F723B44522B9B4457FDC70C040A3ADF07E49E6A96A13413098BFCA8E5FC3CF2B44C738D783E432C5883CA27E2E105DDD27EE8B57FF45712FFA372A547E3C81225B9ED09E81D5DF0AA1E5EFDC433B67C31449CBE1E52ACA1565BAAD62EFD4AA7718E6BA95D37127F3D07182C95BD6EAA899192829B499081534A310A8C8AF7B23AE4AB32DE301DC3D727F7BED3FFEB9756376126BF759C1CB139E97B0AF99734B5FC1C7144C4D1EAC84208376651BB3CB53BF423CFBDAE5755FFF7A02AD615DF6F5E009F3C90D34A5B20D45DCCF20CB8EA044110C8F692C68B5902181F3D0B9CAFD529630AA540F65CCD2A527439A0680816ED3672B5B488C11B447D972017857358977D6A14CFC73AB3D68D8F53D1CFD6A94826B28EE537528387CA7C8BBA234AB9B656098701503D9FB567FD071C58D5B1094153523F29AEA0F47B650D66F02BC3849BBCB780DFEA9B78F1B893D8470EFCC7D38BD5F6CF55630D9A56FBEBB6917DFBD55E1B55AD9485274A21849CAC3B5B6750B3F87E17A8D2B70255155511D5AA8655301392765D8BDBF9FDAFA20C7562BFAC1DC15117C33BE8F081A339607F24E9C391120EEAF785121500314391C338B59E85D436CF7E17674EFE99FB6FA0EC3B413175452AF135704480CF2F3A7AE79A7D02EA5CBA662B48D64D001077D9A2E43F7BCE796DB5C878D28EACEAB6EDB44F1F11C502951BA71FBAD2FAF36A17FEF17B860CEEC9F6AC42157F685175D61BC1306A3876CB1E7A4C5A886009F7EDE84AD022C0D2BEE4B9479890210F5801A81AECF2D15262DF143C58CBD3733E34D2468EC0632DF0F8C401BC9B55EF5AC3082E0BAE4EDA24770B4340C1DB72F665D2EE7F8BD2503FA3C92BCCF5C96E1254FE243EC9E9112341D2512092C1BA2491078609783458F736F7E4BF622BF6C82BD6027BF003FDFBEC56B3E4C9972788889DE8FC9199F8677A2442C7D4FD89F5B72AB7CA5A42B28A04179370ABD31B89BFB9BCEC11BDF2E3906CBEB28E02037FD75FB7E510D742358A0ABA847D98D438D6D0C9D87D51557F1FD8A1AC783C84BEAC1109801BF25A89923A4D772D02BC420936FF12C0AF90D0EFD3D76B60E47FC781D79739DAED7FC5E38A881E323542F7440280F7F41686335AE46D9BC83E142A487FBC6FF9F0449A2EF33946E2EBC54D6F9FA9751EB8373E37913A2F87AEB91CD17AF9F782A286ED779FA03B54CDC48503E53A715AF59542773F0280EDCC39DF2E8E14B770D9329A11046AA40AAE7D4A1217EBB18DE7AAF6226AD0B54CA7F1E243BAD9C207E6ACFFA6C868F5EBC7BD47F44F38DFAE8D9A08401CAE1DC8D9528A0A467BB7E661895AF78A4F17EFEB12C088999E9F31FC38CF62C03391419489E5D058E0FE8835E182EE6ADBD74CFCC873BDEFB242CF32D2EB44F3FDC7F477C5C3618C14B86EC0A03AEC5DD204E77DC3609828090767EB71F5014FBF3870CDD0B07FB355006D60ABC6F72A3E3127E43B043C6E95D5383586C69C72190A87A7552A8EF9E91271FFDF2DFD413CFEB20E672A5A46DFD5E86FBA58D5D7003C8E99082418E04F9F0E954B1C448E34E29E5C9D9CAEA7A39FDB7E0ACE98F7A7CD1C13AC3223CB5B4FAB15D1FDE6AB43F33E43508D941C403ACB3BFF643FEAB4E08321C798717335EEEA31A8FEE27ECBCAE24AB94DD83AFED3AC2DA569BA35715414B46CA276264DE79138C882EFEC587095B9A9B13EC994FFD43DBEBF6AD717A2B498EB3AEF51848C0BE8177D3AC3116AED0030C1D835ECFFEF4C040AB249DFB8A5F355F1573570C68B71F72BC9844BD84861093A9FBD961A9A32706028000DF313E0F176AB59DBE64AC08F7E5087326FBC2C0AB04CE3A9976A015B232BCB970AF057A30BE3F8044321462E3955002BE5659C2BCF1AFE4AB6FCE57EBFACFD2C6909D47E8C7C980BD7FB25AE97AAA67CD8C0F8104824A0EF6ED42FA3EFD00F78CFDDC8EFC1D8FCED85E440600A5D2EE690D54EBF15CCFA21E9A657796A2DE0285B200BB681375227801DED42569A95B65D89C1DFF85AA8CB945A1714007D0B632696FA90137C6062A53719CE888E7C00CA57F6658116BF55C01F32F1A9F75EA9DC75D0D29B600E43EF42E6B7B078EAC74BB11B5F16D7D9077995F011B05FB58BEEDA377355C7C1E5A70D4D5A1E38FBC030F3415F833D7413E9269A6D45B5412CACF4E0BC391BBA8D10AE9C8AEBB22E040345D7018C5280CF86708F1044D2843398391C4C3CFF160804CDB2140CFA846836EF4FD9F8E955C9311DBB4F23BF5AC2B29985702A64E3431FCFEAE22BC1ED31CFA2CFAF9546DD1DA936A1204225D7EFAFDDD5EA2C441B068EE510C5F6FF0FE23DFD74FBAF0A909873B1B4357B72282085E1D12BB41B3F34AE7EAA35DF50CF5D7C2C927A566DD180F98A056B78B975391AE016C65C8C1EC077DB59709B8A22891D3CFEF0AB3300ACA83DA7C2EBA70007EF45BFF1D9DC8A7B1D4DAD670A79CE915CF10288B1647ECAD1F092D6F72C0E253263FA5A2B7F7A1FC5B0652A0DE29D4B149EFEF9CC426BE99FDB6143EC403B7267BB49A7B4D3304BEACEDB2D5E0EA633448F2722AE75D08C1BAF2D5BBB64DE90DDB338A425D1CA3BC19D7F9CDE8798BD372CB8CAE10935905F7F898F0EF1E95A5BA9A4E6CBDD6FFD5A083BD416300B953E3C5D94CF3A4A829A048185CF2443FD7185CCDA1CC6F984C178052B9BCFA4E10558A352FF5AE02883C1BDC56221655F33D7A3BB1100FDE18F5CFFAF52CE4447C9E3A7347387C52530EDDB0AB888D1B11767F9E0176EC4AC8D16DAC47011065EDC664E33E27CB73DB7BB19E5AD7B086A117FB0692D20AE082799A12AB58CD05AC38885B0E2F330D7C12700B576FC363E419051507BC9E75217213713447854C87090D1E3A94A0A62C03C330482B5395EACF5A31A4540FBA57C3EFAED560103F42B937AB05AE323E4BA96A1676F5391021E9D14587C805BEB513CD6DD3EB5097193926813C757FBC15E1FAA913C4CD2430C39926F72A79683A7321846A472045537DDA431A6AD4BB0FC96F01313F32D69738B5F430A314F47D40EB10318E8584E22BE9459A645DE6B7CAC90B1EF7A926845212F0CC03713DC374A877508B86D9D58EF8DA66B728AA2982F7A2E0D76826B73C9CB7685A12DB0650FCC20F8668AF6CAAE3871D6062210A7A4BDFDE788DBF37B7FDB83BF384B815153BC8D832257461D61A6E97A0DDB5F4D8ABEC1327F14219D5F534FBC98687197A27FB1657F9B5675F07D0BAA6952CEBF882C17A9D333C115120D2E78CD368A6D4142DCCC9AE779925894663029439A8DDC1CF322C5C2DA7F3C4C4CE93DAF0A56BD24EDF3D09ADC8B5EED6CADB2FD615EE65C27D79D47923F46AD676762C88FC542193D8AA280D9F3E4807A6802212CA3B3AFA1BD745C7FFABF8084BA9EB10BC9457ECEDFA1150E9809AC240D3241CFCB67F6287E81C53410F8EEAFA118D390189DACB9C1EC8499DC1E3372B86D68D95F31AD9E3EC9A965FF30BB644AF11CDB8C5491760BA0F168F624F217F7C474DC5D29A0BDF46FF4AA03B85AC3557ACECE263B472D39C5F2FFFF91FE2373AD2E5A0410EF09CF4306C381DB3C0EA0E10AE45875C5262E78ED4C336000FB3376853FB70BB4506F1743FB5165A62702266FF09D21AA08ECD555B8614E21033E683937F23E2510E19815F27EA20B74315E8A54734F636CAE877DEC1C95F87519B29D5CE9D7759C8AE33FF09E48805AB1625E69C34AC5DBB5130F77CAAFF42198A44B0F0CCCE68FB85DAF391B188FBDFF388C00B7812954B1AA19C0572DEA2A1C5B192E068F934D7305EAFC9F7775DED36695A4DA007CA1D2418E900A5985934A3EB080E7632494ED66112422FB96303A2419ECC12468CCEC00812B1470A3843A0DE835B7AFF2ED5366D932DD58A2536C9300BDDDCFA122746830EA5077FBB698EE8CC54F02D33AE1E7BC7256DD351CEAD19310274C62C6D337488AEAE4D50FD9200012758D250FA337FA30868469BCF32BCF2587D4E698F0F25274128672EC2842F6B08A3848B9F72AE50DE563B925AB5B016DC0FD52DFE09A4ACE472C2A9845EFA44FBA151804899022DAA4C7334BB099904D1EB8CBCC92A0C5A23CD24A1A0599D518AF79CF4B9820168CC9E580B63C7790913620321AF853C98950B034A01CECC0357D6FC3513AC67D50C3B4205C2A165261726706C5DF428862CB0A020580EA40FA31BADC8EE913083CF6016D70C6848362B5B58A6DD701E049FEAC64330363623134E6E0BD7918270CD4EDD7BF9C771F3F3D1578E31B85D122685597002FDD2ACDB0F9F7D5B3B0783EA8A5F3B824489F85AC84002E21232B3CCCA46DF146CFB2C895FBF83C0CCBB34D43AA1646B2ADC6C656DDCFD2A5B0C9B92604A1770DCBD8BEFCA655EB0EE6637C66B5EEEADC51316E1B6BCD1F8EAF7EFBE70712704829F33294F2A7F41BD23213FD5E8214BCA0B04874E990F10E6DA194AA71CD410A60CAE8CA9B9B9CA9B657BC6CDB8D3044196DB4482CD10302CDDE208F41AA639E9EFF8A8EC63E1A55086555FCA3BEDC9E30D644D56BEFF9EB59BEF8B5F0950F0C44501BA81B612A6E43102816CC6CB1B684111450B6B7FEBA9795EFE09C6D75308C2259557560AF55370B8D5A9A9181399F952365C59B3E9DB59118CAB65169D07AC2B85D96515BB786E9EBE545A44BB060A632063DE003347FFFA6C118363F22E0D30EE641E1DFD19B6145C8DFAE8D6C5230F0F5745AB379B8FA3F7622E718CCB2CB83D310ADE1519BB660E159BC3EBF65D9B830F2F1EE74B61F9423437B87FC52AF851E5DF3361A61F3E762DF69995D2D82E1AAE36B6C47D9E1D656B843558319305AE3196C324774AB9C6F39C8568C665C7698FE913CAD829E8A804ABAB60E53212B25F5FFA9A42BE03C2018FEE6646211017E41A8B4345640E2B3106E37B0CBA56E202CC89D77CAC841B2C592FE75519AFE726B71B3B15157FE9377747C7D9301B3076437FF60837CEFF56A058C54D45A278CDBCAC27EBCC2582C2920E4BACDBBB851E7D2CF8927DA3D2DF06083A97417B45C2F3A395B639AEA33B1173AB0AAE065FDBF007C98B656C715162619A706194353E18F9B33B97762546B85DFEEEF43540A0799C2B77B95EBCA6DE2C2C5EF55C991061A03FEEA7D9771B7E82EA2213507D8FC08FCDFAA497DF58E85A140E92A4C9A27F113E72C500304697CF0F98B7A401F33BBF03BEFE19219F1305EED7200EEB8E1BA1C61443B94EC34DCB14C537F25ED632351D7D32E4444625822B13C37E12AB95468B157B3328593D35A3425F47213F19B25532BA81D4A6B741486C128BF8F10E740D593277888867D8FF078BFB886EEF3E9FBC6F201FA29FBD8C04BB90313C3C2F3EE7B5117DB86EC553DA247464444504FD44C735204C5CC36AB02FF74DBBB3237BF03FCD72EC8267F1906D7C66096DBCFB094BE55FB71F7DB528FD001F6055C0568A7DD200410D492927ED40C911EB68B04F57A27B09ADF8C2400F7F36AB8EDFD0378D52711E0C53ABC7EE0DB0E1BDC5A834ABAE3F25F7E4DCEFF00D94B81118349D2287D7939C5CFE96C873EE8AE7B24DA43847C3C27CF2BF64E60D7A0AEA743BDD9898940B69E07C6F70BC18B749C3FD6A187E2D4DF5CC36B693407418CB6E52E12A374EE51D65236594B88EB3A952A55A2646793D556615E67DB2718C461028FF6FC109EE1E23B091BC83B30AB2B36905CCBB29F46EC2A334266C08CEF7DFE848C34166125772164F3AE8FFF89B3C528681696B2F59EB41D5D461603473EB7ABB7B4E460439EA6E37EA82E0AF98779687A07CBA719A64970A45A0FDC6A900D21A98977031C3F2023BDA0594F0F68676D2270A3545051252EB800AF73C26493D7E73D6360E4ABD92D5C1BF83ED5017143DDD240FE77F45F0CEA6BAEF56C8C3FB5EF2E4080AC453F637F2B58AF6E1F9A66F61BF0021A730637BE0FB6240F4858A4CB665E6F78775FDDD45B717E3C0D1CA09FBE4DB5210B1C3D8DB8F80C1313CEE0A984BC7AB02A1533C1210D26B093F0A60BC947DE38F23977D10E898DAB20FED18222023CB32869D78C76B76A82ED3C1746932D01F55112BBC16FA319F1A1AA888B8013FCAB474938DB3D2F4BADFAE774188B2F55A98A61A62EBD73FC513504ABB265556A61549275F8D69C66F73169355BF45F065D6CEDE0FA85514DBD320F6794267D1720437877917CC2976B6C3B700B313E60ACA8D23F8C85ADE9DC33F2BB6E07C322A174668A64FBAF2FAC6A66A87F2D71AFFD7D6F57592E9B96CDED7330AC6EF1D204AA9D7CD12BDE1BF02B5E182C7BC74F649F1A5FD9C7DD4EF147B63317AF4AFA729324467CE64F17DD492F266D8CEE84208AEFE759746528E11A631033AB652F51BB950AFFE7DA448673D44EF0BE595467E9EE7CCE9CB6079E142E573AC58BA1982FE4C6D1466E0F07AE841F8C034D1F619DE5CF4CFD4F368266416DF6E1F31A8350424DDDCAE24DA93B7A1DD3387DEF8225392DD01EF1EA6DC281B384174A81CC6747F9E2CF449ACBB5DE4EE7BCF90429D5754163CF81DB4A350D1255AE03878A51CADC3C97B4F7669CFD51FA4C1F7AD4D761979EC4D397438491A7C6AB37B917D89AF727DDEB8B6D14063756C55FDBDCD3CD9D571B501558F2AA1823220B7CD454274A27EC4EA274B8A2FEEA2C99FD9CB4D9D2280C0D3F12B2E3767050441002F063F0B2FC90A6A5F599545A72D83C792A7867421E7D4844EA46B892F4981E1D0D61B2690318151C2BE095444219597B867B086E612D74B2DCF3DB01ACC2969AEDA673DC43B2E432D6D87F83201538B54865659B22FBC3813E062BE75AEBE49B73C5697ADEA1D0EC063B6A24AEB2B8F8DB25FD916E1A504711527E24AEEA6E30FD2E45E90E13EB35F6D3A58342D4D3BC2ADAC1C92CE1B9B9AE678EC9E7D7CFABBEBD09726EE3C3ACFF1A7327C40EBEA01C65FC6E962CFDF690A4DCD1B0DA5079FB79820184E012273957E61AD85A6E7B494FA43841BB2530BE8E62810B0D04D5355B823279F7FFB09E4E29BB5DAC850335D7DEC5BF85D58DABFC0974A0B065631343C75D6D9453180553CE1748D13CC803134170701818FCB8EFD6DD1005146C65628C9A74881677584EEDC8828E6D82D91979B52CDAD59FDE3BE5841BBB66E32C50A5A65415E17CD86E4B45B7F7389E63E28876E830CD0B18E0A055F4EED5A39495CFCB1CD165619061F5E9D5FE708E91DA62E15EFB88EC2BC287C97781DECE4821343885CA78D6D3E772712CE8DDA0AA27D7D3BD2DD4D8DE459595B8494912D322C2B39F2AA669BE201F23C45731B1583002C094B1F11AD4D3532C342706F31B46D86E9A25D0BCE86C95AE48A9AC3171C9BCBF3C6459BB816CE97FD79ED643DE57DD7088B37B14EF4F24EE7D7287BE433ABB0A7AD55AE8B76112154ACFFC0D5B0320C067FF6C3CC42784874D011CA372243FC39C2156FF28456FF4F04F3C73C671EF8A25F9D2830E572BC1C4733E175612547733C27F4A8D46CA4A726A93FFF9590A8B2862B5C6AB73861B6BE445E28FE26F843F35CCC0FD17ECEBC08DF6947297A61A65BE09B59693BCF0837C527A328AC8790F06879F63603932185C5A58641997BE5E786D585B6E9AC6D53021364A05382AD66ABE0A460492C3166514315A8230B4A2AC8F7AA5AED3BD10DDA406235F973C8DB4DAA4DE3A6AEDE312F73F1BAB9479365485E141C5DFB10F8C44B0E285D61DA43FDCFEFB6719388DD130755FE339558E968C096D4B7C6AA3D60BE772E8BF238857225501230FB26DF32CBE3073871B63B799A1A96E64C684EE120B29773BAA9F70F8D6FEAD1D28382577D2020158B5D1356EBE934E94812E21021E4B37E7E5D52ECF89395840D2663CE04DFF92E796FC6D33115D00D95EFA323F4F7F835528736764F99845131446CBCF7CAD9EC36D607191A0505B4D4A2857DE5C6C979E25A99DDCB2F058089E0D936CAA5B01B6C89EABD71DB8FEB6402A6551A0E320A7B3661A7E54675209478F4AAF16AB77AF79F8C18D144AF44017E23414F9AF97E8ACAA0821FA7BBF9A1BC02211F91698744F6EF148DBCD51BB8804EA03F17DC969A133B5AF1FB70E7B419D4A76068C4501E62582C319392C625927D8F8E6F1276636289E3E288EA9C2220A81F82FBAE3610DD0F518D40F923F71DE2DC9892085C3857A30E9FD52E2EB4E66C2AB789E4086E152296CB4ACE077128B810B69E838F4B60A967041D4C3374DB9C5C476A4CB02E997A1C2253BCE1BEA72CEB08A2095043B495043912A1E93245EA882C8CAE9D14C0B3BFEFC643E064E279A6067E785F63C9E9F6076170E15869E3653421C4384D326980016C192CAA9C65AAF4FA5315AA1EA9F1C5FCD07E41B52C09F2EE7DCA8D6EA05A93237D0DBAAEF2D7DFB2978472D654B1EB51A6EE8DFDA37F79D4DA9D74445C8B7EC6EBFFD095436BEA5D7CE435A5DDCD8BF20FEAF91F207F224EA2FD19DD355B97CC2A4FA3DFA4FA3CA00DAD7DC5CD1BD1F47AA9A0F458A9168FDE748F7F0BF70AF9AA02C1AEC1059CAFDE51C8360E00C2327C25D43F5442CEECFE64E440AA1AF2D6E48BC6904D4E194FE9F436269514F3C3B43A9AFDCEEF8571920FFCDA5485A414785E4B02C4776C1723", + "rnd": "799722D7840000F900795BDF0D9B116977B5329B368A215E400EC7BC9862E95F", + "signature": "A62C54CC17CC4F8408F4364579A2F8A1F7995D58995AA61D3BA4FBC83356B6F675B4111B9ED9B6C4595ABC0F5BD47FF12B75702A9F0998C2AF1C5AEFD6921DF3FC72AC5AE2418EBBA4CF44C633BABE8EE9F0A6149E811969EE24561EE39D449E83903197BA00648E466D4B1F4447184CCE585044FF0C9137C61951DEC58A4D594BC6F3B4FD1F0E103A19E705D5FD74887B5F9F18146E849523B714A59765517400A2B792AA3979F71CCF78DD566BF4CACCC3E24F2F07BD346889FD622DC0068EA0DEF1DC1286FEAF5A0B3D09ADE4D621128B9F1C68784835834BBE2A65B78E0C8B76FB94E29C0A3E15C7115C8E6F3FC59504BB52ABBE3E9DE3843EB730384F11163288B414735D625A365E73F1E83E871C00BC9892023DD8EA4BA7798B5252DFE5DB6FA8592BA6C1E60C0993002C153796F69C814AD3B8F8B8E4BC248405FED4527C6DAB32BA0ADF6CA9F8D13EE07B91CF7A7B506ACC46E431395D03AD2E41D8630D5F59077C27876AF52B72BAF199D9CE5574F1D02C4883B18119FF923BFED8B586F119FE847B2877EC56F9C8C8808892C43ED72A8BD271372EF7BE4F818D7C71F26FA7DA8439D5B446EC4D33D4D6ED5C4CB31E6C6CA633129563E04F89AF20852B1BFBEEF7E59E2AF36B93DF19B047381B39CFA9C091F3773EFFA56D744B2DCCA2F0D961977F38683419E28C931231BD4FF0572507CCECF6886934D0762D4378775000F223807B59AF01B8B3F7643A4D013DDC9B7C560BFB255F86F6803FB3F63CCE9C9CC12CAB063DCB9EBBCAEC954CA38C4CCE9DFC61BEBE686A1B1821999B254E4CB97E78F690780F597E7B6C5CD3F748CA5FE50C651522D996F7D39F4052318EB8D6AD32882AFDFAB2701150C9AF1AD7955FD195EF98DC467832F03334A0E3CAD1246FF9D3E69D4C3C17A0D6FB773251473756901FE037EE937268BABEBCD59512AE474948045BECCC0165A2BF3FF49BA36089018C64278927EF512A39F323F066C17A352B18FD072FB01C35489C97AC4354AE927EB2921DCC4A086662F066B0E603D44CA6C0EDF977E47DDC1DE342EAE17895B86406A3EC43EC0402740B26B3D949B473ED6E257B845B7B0BF92BDDB1A580F5DBF6BF27132C5D2EB4C232724869B50F6928BFED7520F9492D0EBBC4908D799EC3D5B3DE954538FEDF05FC9729BA30F129D5A8C379C2C90040E7E5BABDDBAC4AACD9ED1B77C46A4AB53DBA2320A39F9892A491838CA0D674CF26AE3275638E593AA1543FC2E67A811E1F2E105053B7D78C919DBF1BAB6980AD045AF54EFBFC62D7DFB55983A736EF368A7ABC0D2ED2A4056FE2F7622D82AEC0A83616EF034083984FE137582540012BBD137117F3A19EB33BD0D9DB05F00B5ED27BE8EFD8092599AD6CEB59B4DD016318DB383FD6BDC1F018F9061AFE4DB76B94BAE7DAFB1231050B551EA67CBB596293BC3C3E06C1D6B8DF433D0A740B73D0133BD631AE835D48BB646E0720DC1CEB0CF5BE0899D64640A1C3B06936F7743C4F35068F04C6387547FEF9B24A4921EF5FC797975F2B75CB605A0C3C5DB341A5A9B6CB43446FB36C8C5D41DB1179AA3A8EAF9BB865C4CCEB65087A704CD3A105A6B7EA7DC28565587AB63F3D0E0D0F92AC43DB920AABFB45340224D962FF2AF0AA110DE5537DD4B0B94304B8DE6CB943C63C5E7D46BE493B01F453C694550A67D0E695C45609236291ED9C8A7A4A3A9EDEE727C310204D3BD2785FB27C3D300EBB57A9596ECFAB2AF51E63A25CF983D6021FC382F1F953A38D9E431DAB5FC245059F684B477260EA2AA4412BC4D821D367F4E07FA74B59D3BE29DE61D4F9DC6524E659E025F92556A2467AE2186A7D74C947584214296A284F6F8EF3F8C49D0BE2F9545720ABC60F8991D1A9726C797445BB737AB66B6A54F1CA025B6AC23851169D8F94B236477C1465147723532B92CE5A84823C620126F64E13973583CDB2726A661E4DA98593A57D440501A9188B16405FB918A35A0D9C8537C7A6A349B3F8E0557718F0CC90E17C829314960C62986ADCF8B04F644D4255CE73033E42733C43055B018B4D1051D482C5E1EA515946DB15235759174092EF06BF2AF602C94DD2963DF49662C1E426B743E597C3771A6243A909D6AED01CC40CD3BFAA7331F12DE39CF53FF30742F018BBC85A1888BC7BDB9862FDFBA85395689922570D002B0D25928EE54B82C40E4DDBCCFFA3A1D1ED49BF8010BC8751DA47AA62A846993A8EBF52D654331C1619E2AEAC1A7F8FAC3627814C621081EB6CCBC4971B21AB557F7985043DCE23553E4C9B30462745E602FFCD57A3048E3E4DB42ACE5EFC95170EB652DDF2ED453027EEBBFEE6B38B2D29D661152FEACDEFEFFC02A005569D48F93C013E513ECFF362A7F752488B397AD2F068BDCC18833E6797073ED325D9154C8283461C737C2A41C1B925C7A6B20F91C029FA59BE436812E3018F139FD743C3833B316B34A86DE2BC078919372ECBE7BCAE5BC609A6BC8B019CFDA94CC258B57FC229CD80CFF8C57B73B49D33A0A2FE3730EB8DCD06206D49DDADF190671DB8775C1AA514DE4DABA86B204E30708259FD2B320AC975DD92409012B01BA93BCF52794BD4F31CA2AE824284C525A0ECCFD9DD20ACF944C8ECF285B1261A80C313FB189AF05F59E724382869975818FFDCC04C7CB91E25B5CEF520EC2039887B8C98E1AB707188219A334AE1EAF7B51F39657186925E13B33BA75A5BC18FB3580FDFEAECE7D9325ED52CC29B7C7A2736B755E48DF69DC1FD86C980C33C11267B0FB5F6805C5AD537B14303C67229F20B39BC3EADB74DECC4047A4C7B4DB918D47298C621BED28D5665500A74F5C11ECFAF1AE81EB3CD94EF7A4EF26F48D92DB0BAEDEDED05B3C8182C036402D203C2D490A3DEF43C295D768058288F5510E760C4A4990161E4582B551FCF877F49C49BA7619C3A8D5F26C392B6E6F3FC4E3F0172A1E202972F46B4F98498F18836E3DAC21E47B4DBD2235F9CFA2D2451E3A9E520759A53DDF872D2E3D551FC406982AEAB8AD10A2FB3F66D2B0CCD026030B47DCD6FE9D5E93E79AEE7ADE86F48272011270D27F6C0FB97587A2CE6199F8C3191725214DCD8915AA66038FD3750D6E2BA1AE78B083B531003F74F315EB103D427F2F13E90C3106EB6065A1B8D48AFE4591A3234840493C4C89AD3049A3C6FF38D955CCEBEC075E4EFA9ED5135ADE944B79DEB8E3C82E7DEAEC9CC3850505290BE17CD1CACF41F4369225A761992F67BE333D8A248E344C37915D7DCA1C90D04F10A273BEDDE900BBFBE2A04E523519A97482BF61FFCBFF4D1D1B9D6CE87CAA1990174A144CE142E1D2C09E094F7C825A26B07D5B8CC0D97F5C102907093FAB1FFCC862019B50507907D3260CE849229117E8230BC583906530CCE255DE58F41FA15E68C447D868A1DFEB5411DE87983899A44DFA64EFE546C52AAA4C555CF2F0694BD9117BBB295B551F3225BE367A60BE271301EEFCCA78F66ED8C8EFFBC33FF3FA7121F7490B11AEAEF55D2AC5059B97477CB636B58F0A776A744C32188F405F7FF3E4A2FCD96FE7E76EBF0DEBC6D18BA9C1BAFE210AEDD680EBC3662E74DE900BA8F0DB6516417A7BF041699A04AF099EB365CADFA63B71DDE0F1C36FE4AE4BA6415E31B08BC834FD3681AC039AA135D366836662321AE4EB8157F2AC4762FDE0972DDD8A57F421588613494E47896692F6CBA5F978900AE8873C34FB6EEC4A6E96FA7DADE18333E57223ED224F4BA6D371E101BC759ECD9346483B1C596B57CBB8B13A712B056478F3621525D37B5CD65D884F2DC322D1318CDBF03EA4E6F360691A4719874075FD1340B0CC7EFF1A611C15493A48D83259ECC5AD8BF1F730C269FDD0890A51DDCF07A0460B73B0F2CE75288F0FB968F3E437515B0238282EA3B0AA3C557DE9487FE38898073A2127F97BD5E280696FD382DC7C3E73D2E6BFCF42043A6D19F3950714EE7DB441114A67F2723EDC9464690E738233168E7A6554EF99BEDA5E842D32356EB9070B0ED4E0C6228A5A5320C379C00F77317612481E38792BF7532A8A93E24B3812799005E62B79102167839E18742B0E0DAE18A47A58BAE35637D40A6983788CEE2F7435B6C0AB8366B14D151C3EA6E942D7E549178ACAFED7F15CA5018F95AD895C2781B32ECCCA0A7995378A8BAC2F69EC472860577D563196CFD602B1FE2825A79421B572E484657E42835AC09A5A6CA07220C843F996089665231DE1ABDEA1A69EF045EAF04675026F6CE3BF096EB2E39DEB876F9D06F91C3D7DE92C60A4D5DF2E227CA54B89900EBDC4CE467C6F92E22F7A6EF254D71B6164363EB9A809B786ACA6AA79D0399D5F150DC9AB913FD17501C90F1CEA2602DD827249AFAE9BC198D4C13253106319FB3F88A64C136A7C5409FE096CC7EC86E3095A79D27F8D72537256F6867BBD64EC2840B09EBA21895FE9F45590B5ECF44F9D5A93F785B88BF93CA3DA01EEBF1561CC6D2B9C2EC82C85DCC2C07E411C112D28A116D1AAB68EA2C7BAE03CD434F0C500C3FCB95608DF1B95BDCDAF233B49C60359651EF15C3BEED71568D86F49769E930FCED8E547998959188B70436DA47620297DC1447318C5F9BCE57FF6E42FD7D43DA8D8B0ED7C5B078B98B9F96B83EF4CA5B335590F12CCF991A9EE01287D2025DF85EF3A7FF0BDAD77D34D20058F62472FFB7BE1F10F2ED21A5C5A7B716BCD0C7ED701CAA34819A2D14CA8E511922B08ECB2D94873299DB67D5AD931150928F391ED5E2E0DC75922A83B38670F399782FF747651E8F8B0B651184B8A589F816C7711220AA73625A314A218392B9B6B0005F7F365D1285E43680417E443A4093138CF20BDB93E8D97E2C53366AB7AAAFB4B8CC1E8D24E7DF82A8FDCFC9F6C2A8EBA8B602443C18289371B8EFDE5D74D8EE44409ADA7D41D5AA879056A4CC2D7FF2384218834CAAC737AF681DEC973E0F701D05C8587155487B96309F36C95C6EFAA6FAB32488FD224B0D5EF2D8F0EAB1EA01923CEFFD32BDDA0D9FAE6BC221439A1C58814D2535679F613BBFBE66533A491E1361B40811D51E32CA739F06A43CE4E46C977EDB08C4EE121EE05B828DE8B086B68EE0B4E56C1AD4E4F211D101E9D41E24CB2B2633E797DA2F17E0CD3FBC3D545C468747EDA65F2625AB1A6C1530C628E13466D28A4DA26192BBB199C320DA9AED6A78AC380455B47537C63F2A555C2571CA2BC9A4C9FA78D9F04341F9C90E7FC95D41B9C59AA9515793B9335D0F442B2EF348CDF197CB6ECCD50F942D1394694DCF1FCDCC12A031D02823CC8A2F6A20A6DF7E71F28BA193C6D06405CE7DDC2400B74AA50899B3685AE9661DFF5A894253F3A873BCCF2CEF4A5C018FD4465BF56249CB7FF3A591DA2B409A95297E8FA04730AAF2458508DBD28ECC7E23D8831001E86224F895CBDDF137E92720C511FE8FDA800CE73A6653A9C1060DDAE88C03EE0D49EC876FEDF79F364FB41BCB17A6654D74DACD809205D9EC3CBC787FD8BD4DDB487BFB20558CDF3AD1ACEF8C12770EE24E4EFC41908149F8E0D92FC183CC3321F0FE60D63F23ECCF9353032704DC7714B59448CA8BB2DF7AAA46236C84D4AF7D1D61AEC7F7B321C22F52E2DB28C00A5D2168533C767DEAEF2B12710A7B7B92A51E3363255918F4DAB1402170235BA6C359FADD2A7F255032D4D90DBD2BFDE02C965EF7FB9EF4AC633B4E8E40430946257E4EDE1C9970B195E993BCF4F00215E9B7983BE138B4E3F8921C15B2FEEFD6F065622AE2BC1A970B2D854C383C9B46BBC45A702CFB564FFDC37F29ADE7F412B678FA41A08D4AA2874BC12B9EFB6B20122D113795279DFC42BD486FB9925307707F860C5D5AE65056918B4F7B39A5E967B493E1B1187A989B486305A051EA2C7BCC3DFEA9CEB8178FA5DB800D18729D448957706530F93F6C1E9207450F6911167B9D09DA305050C3D6CA3FB3EC01A9F16CC023AB7E95B7480C77BD62A023956C7FAD148264EA2C6127E30762FD6488577D9F8F36AA06AF20B635A3949DD889638F00BFDAC7FA7078F181F5CAFE7E1F0342CE048308D482C400599C1C53B90915A52E9B6F03FD013957A213A1F46C0A8F3DA9F66B87E9C4A5B3C5293D429B0FC43F968B04462AE9F1435AD8C080BF63388BE2807526961E068DF2A9401F50B3B74EC16B14EFB5D95D9085933C955B23BE69A0A0F896A7033F5B1613C00795CBB5A562AF979525D6125D285987F13A95108C2A020A51D9DABA45845FF33CB89B7825D022ACBA8BFFCB08B53C8592ABCBBC7F2578DF937D4B471A7AB2CABEF75D44DD8A1CC385D9F5AB5524E4504ACCBF0BB0C8F1FC75117B70B32BA1063246D7F9DE8AF0A8CF6839B2D05D0C1A266D1CF42F02225F583E31068E1CACA429556641069B1F2D0308195BBF1A3F5D3D9325728507595CD9124E6194989BF2011E3858A8CCDB0C135A65778FA8EF1E28515C5F777C82216B91969FE50A23395F044447777C80A8AAD0DAFCFF0A3960808AC2C8DC000000000000000000000000000000070E161E2428343C" + }, + { + "tcId": 55, + "deferred": false, + "sk": "F0AC36225FD5E8DCB96B82E35A78F9FC254FDE9BF232BEFB5ABB1BCA3BD4B120215C71DCB2E57875CF07504D34DDD3E18223CE52B42568906B23F4AE49A658FD3A0BA784C5A724A7E65489A4F95F1B2CE9FB03BB8DC2655A48F2D6469FFC28EF9B6E8372B23990C2D9F4A8BC44820680A6A8671D933A733EBFC97B9068194C450880481CB32C1A9468002424D3187109C0210C1604120742E08009199764524441A2444284C65002C92554086D882220C1440AD8347212A261C9A66D1BB40DD99640E0904C8C42224AB289624609DA424449464959804909090EE0928CA2C46802C780102391C8187111A0691C926512170119484A84B4815B2690149948511860A0C24DD8A25111A650A1360521138C0A826199B451822022C2C88CC9422D5AA23090428AC10208DBA220D2965104984001016480306DCA28921BC3308CA06D82240119046D8C0250D1A6501A156AC84222D4C4640C1905CB2625889621C4B22104A789DB92640C12401142851195058AC261098104C9144E900469C4C00119998818368621117119126C12358C0C304A89400400230CD9103042C22019370D0B356D08C16018B121D84270D4086189840962264C01A008DBC284113222198771E418728B22229C000C2427882295105CA02410266511A51020B32D00C56D83106D0038228C38329C848413A811039029D418244C404E9A38496014601A171101368D0A074952381193821024267020A18024058A628849142182C8360D9C340660804C61028D0C0266D9C84560A20581228253306E92962DE1B88024330E904020838491A2C8104918650B39040AC32CE2800112B36C20802021028200044D14882902A771438269A2B444E30092C4144D11890913866C9AB884913672D8160409107021324C0C078E53A03108362011C16D43A000C9C085C1B44CD2146C14084D0305245B24221C026900C709A0104410450249448C9846445BB20012C2611C858053048111305224C981010831CA1632D84204884826C8442CCB26010AB54DCC26929C0206C4384D641424CA0651200845238909098688C8B80D50066C04B94C59208E5C3661DA8068C1C68C0BB74060B66C13302903874189B68822076990406583A2244A2031209824DCC00DDBA6115B18645034082422004CC008D022640B11725AA08992A06011A13183386408B824C1846950B804631405C98485101506E20246D920314C280024086E823069511861224909CA44249B480A09056DCC304012163080123010168E03276488202681400158188DD440209C120C402452C8064521147213210D104704E2100C18C9110134105306450B92458346040235429AB8881B446558C068024545011980CA864C4BC684044521001060141668923288E1B425121344D9C27010B08C422448D8882DD2C811C3C04424B729604460A3065283880D18A965CC282A19454A034949CA946D04392564444C124501084930A0A288CA18092305068948118A86840C07105C302580A444D11205D40812E33822111226C3120A80A46C89209112186902839061420E04970023232699048EE0186009C52119174C129648E0168DD012628A220D03058E1CA0210B33066008119A168908252489C811101268E010264BA665030548642688439480E34846E1066448380A2299601BC2085A86511A167200034CC1B0681BA464583050E0C48592286194C620111849D4226111843064464E21B59049163123A00000388C24B90C1C080D89B4011B908DC4A6042004445AC44C48C0080AB721E0A470640891538601C432659A006CD8A209038811910284D2B42D029644C0968581846CA23870C90864140044903852CC320C148040CA86459A202202B61051804C938668121381408484DB4846634206D22469C9B270602049CA345252326A8A4221A1842D21A320CA3441C2C8684146661A45301B448009B921C4148A089708D1846988A00919086021C38D1B36251CB0201C346C8490515B946C24220DCC982513B58D538240C2A80482120A43B42DCA4030424042593066A124000A83891CA66841980564903000C451103786DA06802190050C884DA33268D0A229040664C4328524B52023884901486461C25010A20D0A866909316801220698462842C48D19873061260643B20113120513452D13412822B21094A090D8126891289043C810A1C865AED83E6F4913C6A6DF09344301517E78C34ADD6055D92EF588CFE8E1F50EE39BED84EBA124BA65B99EAC176AC3F449AE8A7E72AF7EEFDFE7E0E89A695EA217129ECF5C6EF3237E9F045024D30FF326847C81E21F761404BB6AF27E87213EFBC932BFC967626B7FEBE322502C486662C14BAEFE175C4570269F70E171A7255B8C57CFD539031EE483623370852CF1CFE72076B9827814D424B94240ED3D0A852C0C5FD3E06880A23E79EED4820FEE4992941459C8A9C0B2291528242FA4D15F2C5483096C06C2859EB48CAB7ED5E1CA1DDBEE881C1E5381B9F6C88F3882B1BEFF06E0DBC8600423C26CD071460D1B4210D4D611E53376FB1EEA145AC846833CDF6EDBFCA2F489C70531569DBB971F5787D8AEE1386256890302FBE54D49884BE03057CF7F2FF362A6AF3BA84A126DC304D9627D2A4320BDB4ECAE38F74396B6F9B682812EA0D2D22FACB01FC18AD3F4C273F4312E1DF6E1715220947B76363073CC0ED1289760905802C81A08E0C21CD1A6E87BA18F614762FC3402941457CCC36DD97AE3A9923B2BCD1CDE0A624F358F0F30ACA7B5DEB2460D0456DBBF1489030D53FE13D7439F5E418D7BB79943001CD82598A11C9513170FA34345D777E7329A85D3C81D089474E19F79896F0DF4D8191F5DCC0C1CD0DC0BD9720D498031BDDC8C2D104D8BC5785B0B7457E4D4D1C590B86C01727ADA0AC3DA690EFA708D884E1363ACAC7C569C76207B95D3C53B4EDFDF454B14D5F46AF612CCEFA32CA44B6FFB7FF3A21198C4F66C809E65A6458711282A11F1DFC76DC664C94AD56BCA1F19450823A1883DC41880D61AAB80E881152B554FFA0292C5D4621A1E15FBC910928676C5A97841755F513EF86CC18ADC4E87C0A6ADD65044C4F5A421B9F32BDECB4E3889A671DD279C245EC03078922ECF083D8AB61DA95F4ABAED8F2238837A309A40158777D436DD1C9D0760156860E7C433763BFB3F550E8EB4BCBD7C8101ACCA2FC25815ED1C110503F7CB2128C23C1F60DADCBCE44094E4BBC05ED4C3910B25F409EE3BD6597160011721F233040ADD61357AB730C9577A89F636200651DA9C6A4423B1EBA50103082BD1915D1064C74154D4B95A3EB7390D607C7B2239D821BE2260B55D16BD30228F109B18D74C2BB17241E3C91979E34F9796354F4C1057F9B09F318ED50715DDC0B5663148BB61FA980681099D2CA0EF203E2AA2634D8213CE8A1299381701E8396B5C689B992047651478CBA0B8CD130B3BDBE1D2A42BA0D84F0F7F210A6B5C6FAE141D13AB7AB73B22652F98F901F1D930802E40A4D7C818C5150EA0DC5CCB558AB0EBDA316EA2369FC6949609F64792478ABFB231B782FB91DB5EE80DDC77ABCEEC9C3CF0341064D4E3C85E0F30B5CEEAB2C1B09785A38CF168513C4A2C3CB16A3E0DA3DCC4AF6696D6E8F99058B2D9D33C334E947B6E24E589B7A62778A1499CC53B174580FC397AE4F7D3B245D0BC63D867C3140037BBA5C32A40A93C90B03E4B916044B78B976E77160EC7D2573AA6371415193AA8683983EE061B9FDC9476232CDA3AB690D07AB2BF9E3C7035726A3FDFDE53B88B3DFDB5B26DDBE3D85266248D409A143F82B714B842A5D5D987FC2FAA3A2F65E0E6B98393EA0955A754916BE9426771B8D663D506C9EEB6993840664B52E421A3A8A1522F0C463864265272C6D2CC85D71C0C497AD305A2CD7B64F08F5192803F48289BE9812265478A562BA235CA0CA29BC38CCC94C5FB5ECBABE42F191CAFFEEAFD814F7F13EBE1DD2F2BFD6419E82DE56EAB32B61C93C5D59D50E5D32938DF28894EF70FE97EC29C94B8909B4842D5174BF07105B7888BBD8DF85A647BB66517AB0F932DB3FA8C122417B7D9FA46C4A360E6CF7C39F2D170D816200BEFBCDB7E60A6D1098EBA2DB0FB0C2253916E23E32BA87CC61B71088368DBC4BD8F175F03F3B298CC5BAAE99BB2F7093F956A72AF375EF3F8D9E32A881AB6420F41C7EB3AF3975A393AED2F497D20BF810914FEFAA8CD92A03C30434707EB28F5B75D187C3CCD3135320063A630AD09BD374884AE5FD73BF25CBECF3D493952A4053FA7720B6996956E6AC51C6E1A1DEB2239CCD1CB067555F337CDEB000EB091C1E4CE0F3177B1DC3E593C08047B4EC51451FA4DAA629E81104CA6FE854DB5788B2EDEE88016C2694D5A7671827E75AE71610A8E6C827A83A207D8A8D791B86C1162647020C7880DEDD43A0DF26B1E8BD5C25F08BDC8013F2DD108EC63759BC63E83156E73C95B0078F8E118CD2403AFD40E7C7EC6A3192A008354D6F48B58B537575BE0630B6CD485162CEEB93AB1C649F947BBDE90AFAC754A8BE4780B5C4BEA6D27E7A37BFB376366978FC4FF9EBD56DC201267A483A01A3753621FA5261E159C578712D0C6056EC275A8EB6B5A27CE645E5D47C129232B8745713024889C893CE76B3C4616E3F723432CD82901F4E67520A6B7E21D42B919556282294F7AC6A2620E4AD365C3C6B2ECDEE97317C765C1FF02C023044B7AC0927E5906DA029F79E24979C41CF12E299C185B243D4DDDB4E3BF8A58F4E22106CFA4537E9CE307AF1021031C614D4D46464BDDDB13BB2959D31DF9965D6BD545C8A0EF85A0A3D6A89CAAF22255894867999A29AFBB3980F5CE40E08FA6CFF6DDE4E0363B8F789A4C0E02DC737418B276715D77A20B3ECA145CFCACF1AF370293E4BDA116A9A1EACFF6F3746E0A5274F1B7DFBC9AC8F22C285F5D748E3A9A79EAF419EE06DD4A76A8B9D4268321CC0669FCA025E8EBA3031173E5BB1C66F476491F902B23C34B19CE4BDB40A055A82D50B5298EA758D9ECDEDB0B30DB99B79F8F84CC387553C8CBFACADEAAF386EC67E73532B4EC743375E462947CF69FDD04E146A8E8734F1CFA270C3256BD6FFE1921A6567F77D536521BAAA5425A78FEBD1FBB55081DEF63EAE9291D1506FA7687152DF66AD0B043333F1AE39D48B6CAFF310EE78674C7A6AA97C1432D76F411689B8066D9E6FF2C941829CB4323D8CE1AA2CFEBCD85CCFCB4D78953C6F5ED2D682FF9E2518F7FA6FE65378C0DFA8215DE2F7FFD0647DBA4EC4F931AC470CBD7000130D447C990D1B3DAD3648ACB4E31B6CD1CD8753C41D32BC0EB2861504AD798445A05D00C8F08EFEDC6DA47490C1E25F27693119DF7CC8AECCB9BC74AC44259AC1970AF44083EAC46AC3D058CD6FB562CE552E490D91509DE6DBE7B75A62AD8DD23D1375F3D819633AD477767FE8406AB4F06B0F2F5BA2E62522D594C7A68E2EE6C80F66095DB3FC3724C1E3EDF776C56AE2E1DB6A505B933F547EAC58B7E7CE5E5B98625A1BAF607C8F8CC740DEABA7C1CBAA5157DB304F2D28791C85D44E380B5B9E8E9F149F52DD3D665D999B6A4071EFC5AA032D1BDB86CB4EE1C0150A375A830AD57E7CA76DCB8F88059DFA0F1C202F5EF8401F0C10AC25CF2CE4BF66F3A3622971A54BF23FB26B5899F5509FBD3005DA82CCE78720E2A37F588642277FD61EBC594EB4E830E82A866BCBF8AF64E16727B11D6067C265085A5B557CCFDFB25D251A0C5DAFE1C6F6587FFC7093C7C72442E87A200AFD7421CAB51667B9FDC304F2746DAF72EB987DBA3E4B3E3E0534CCA125A3411D7F211E7FB4D9DEC0806294477D310AF637F440F44EA0605FD352FCC1C918E71BA7231E42E15FAE6FB4CE70760ED37C4D7A50B004B85E5941A8079F1484779837A417E8659837CF9FEA2A52D31BBB145E873BA40DB558D3C3BDAAE7FE5980D66EF1169AC04538C0988B2AB1BA4D29F62EF6B794A1CE959ADE2B506DB3D1834D02EFC1C9585F3C12B0ADCBF0910D412C86BF165FC3E165DC6C850A3E88C2811CE951E40EAF14D1A8FE7BACCDCD187FDD36AA38005767A5EBD7EBCCFAB03F7AA3D4AF269BBBA40821BF43A6F55E008BE7A5E9B3514B40B85C05DBCCD27016C6F4266241A2755A226CB6B93AB7CAF55AE26F495AD9D9B41DF10C8671C8D043738A8A921A9E863AA0AEE6A4B2CB8C211F879FE46ADB50C9EFEF606115D8CDEDB38F2A01111498166432EDF424E0C548CF8A60F23C30AB6A32D32EC6BE995B7147DBC5C576C76CF10D21BDE645B195EC8559CB8AE23C6E3E3106B5629DAF03FE7AB12FACF7C1494CFE7B235F56A04CA11FE5E1FD6C0CC270FDE3F72F385D9527316E626768B0A9B0FB0449D38BF8B8D928D8F9EC58C03CABD289F6471F7D9F71DC1530FB99CE9B5C28EBD91A90D2FEC091FA6972608755E329AFA477B06F9F1DEA9A10D9CD6D45C15411FAB89A743C7CC748EE0B614420CE7314F1FE6C279EDF31CB3190D008F7226551E6EB6E860D97F1E0C0F10DDC6C70F675ED77A5CA6A5C26C4884E2741D879F543C7B6BBA26BC442644DEA3EA2AD560E2A617BB1C1CB436325BFEF34ECBE5C8F47DA46741CCD2125A09B14A88BEDD8DE01496D501CA93C47E457D6F9889A2B5855AFACDFF0BA60E9C10782FFBBFF40981A2BE94488C45DE42CADEF3958C9D2F54925BE9A4BB85F63E79C6698E3EADA10D586B583D71DBDF77C04CD3DE40DD8B67DD5BC4E848BC51894E147AE5469865B67060E41F6D7D5F08761201B46DAE1011792FE8E102F2475A5F9152A083E175272C4CD1AAF4995A7798367E713ABEFFBC73F5E56A017D30099E3693FDA0AF0BF06C948E196C13A726C82FB2A1BBA80DB55FF98F0D8443238B121D93F3DDBC874F3E284B594DCF7509CB", + "message": "D04A01378911638A1EDD841A66822B74D9032876D38D86CD4AC6ACD602702DEC5C3177A5A3E6A5C9B399050BE6A85E6F97A9E16FF601FB48F0A41D2FDB172323E96BC3C5F2C21DBA721F78CFD6777167F687ED269316581FF66968C0A018E82C68DB83581054F684CF74854F21F2B25965BE48C3438BFE6CC4D319E947ED2FF86E9AC188D1D6253E4B31B292821CF21053B0ADCF1057C72963542E359242B68106076C1403050A128D581B0BB562C0F309AC2BFD6E35FFDAAEC58DDBE9B397663C67F4430FFCBD7EAE1C05103176EFF13018E92AA8F2E9FB4A7B10C183B82F93694C81A454F10BF3D6D3F057314A56BF861194184700B2BD0C48341BEF94519F73365B87357502C431312A5BB0F5447F97FF55D558A2CAC5D4B61A56B53C24012EA14C75C9EDBFDBE6ECBB12C58774269FEA5813968040C0AC2575F551E9B1EC43F0E2251BE369EF13EB55986376EA4AAC6B40662967F211C6685933DDD2C73C841F89B0D12091DF51817A88910629055853C71925350CCCA0B446ADC3BA718E74E79F8D7C439D7484669C353393C50C161CEE4F603C2424AC05F36F941646EEB7AE1B57133F2147A328554A5AB8D19423DAC309A8293C903FB2CC9E8A409CDAB0F7EE0527E8E7D92697789DCC63D779A37EAF31F0F6E5A5B4423FFA1948DE1BC622AD31317512D20CB3008ECEF0D37EADE6E6695C63FC5D281F7A39BBF38D2625478E9FE2845F89E70C94EC540EC52E7CFBEEA76E046354C28FB691FFFADFA1A0549C941F4F7A9C8E546DBFB8BFEDDFB179339A952E7AC2DBAEEF5C21EDDE55CC4CAC41ED76A8B09684D6E8C63F03B2ECD77FDD4FABEE4C95890BC8FF1020643C34FFBB71D9B630568346837B0F4CE676EF6D41521A8ACB081D1BA4A7FF33DC0752F8132679A15A19D1F8D977F66AB02EB2C733ED28B6354725351233D0024F5CBD7AE6C07A993E225B69094FD2F13D304F74AA4E909A8238B98DBFB7C3B583DA48AB68349A00A25C15C388AAEEEED5E5EDD6E953DD970825AE81C11DF653E5E314F83EA7D62B0738C787E598C030B97AAAB60BA99997D286533F5FA2386AE4FB5B48DBA868809BF98082EBB01D5B640D23F987DA4F412CEFA0A627722487BBB23803F4253EDD7432905AEBC587732D7BB1832AF41D1CFE506D1985DCB32C546B4872234AD716914DEEA5F64D919A082683DA9F78F303255B4DCB3BCF2B62D787A87D5F8F99B05650FB1DF842784B1CA9E9B03F8AB4FCE8A702BDFB2D668C6BE6E76F99AE43F2D6C2655374DCAB271948F8A25C9649BFF6412BA3827073BBA370FAA4699194154B4647884AAB3D134A842D6EE90AFD658B51002DC38F381E4BAFFEB2F0F6AB46B7E2AD59FCD410F76FEE32BA8EBF6BA222EA9B15D74BF7F9A0445D5BA2AD027D3FBB2D54AD1F502666D879BA88D862A90AA15FF274EA01E4375A794CFA77CFE9A9BA93F068764381DD0F00D9302E53199158D27296AC38D2AC96CBF0A12D3566B1AAE9DCF2F301DD13F59FACBDAE7A024A1A7A30DE8193939785E46A5456777CBBBD87AB319E330B88B0F4293FCF589000204718A9F12439551A7A25FF8A8E071FDE7B153E7A229133232102BBE9AD11ABE3F4E25E975B37D3C6265430672FAAB3AF12EDE00474F402A5AF0429F7007C6FAA8D2E3541B632CC5C1AB36F2536E3284AFABB651DBC38122A2414C92794ED799679674A57F5AD6A780A9D3C871E26B9792BBDE57912E911D7862BEE21AAD6F9573A8E4CF05C5408DF357706CD0F9955133674FD8E44B325C657A6ACFD8DA0F0106B4C207439F0ED294B2A2D37AF697D32287CC19AE765A35B0286E14A7D530962AFB5378DCC7E8FF80FE5F3E80E284C39F1295196029FC6A2DAECF2C8E9FD0E3F123C5FFBA26F5C7A12C43AAE077E47F54FCA478C931C9F0EB1DAFD28F8A2BD4993FB67561D9B0439B6E4B3A2AE787CD715EB6BA647A23A79937C97A7A8135FC667E82784565DE0BA718F2FCD96328B4981A53C58682432BA7FBDB4FD5575C8E6B249D53AC1FE7D5243D3CB7A5DB937487AED1C70F9110F3C23E882D3B0248D3D098D86CD7B06369E15356A786156A302916422E3B3D17338175041F79C9287AE4B2DD001BBC8AD9DD0D0416C4A278C64E01F6637D2D96AD98E429628A4066E56A2B49FEEBA8421F79CF5BC1EAA027BAD78E5FE0BE92963EB1B8A85DDBF49928CEEEB6EC6D5054ADF2A4F6136C58664141F567237935D42117B74F304634B46FE2B82A40E169B03EA1C91682C3ADE600E8FE9280648BE0F93FA8561D8F06771927B9C142694F3FE485CBAF5A2F03C96DC4DE36BD4DEC29B3FA8390214E460A512345868D1BBAEF1FBBE07C9E3FEB7CCFC9A45399579A5EBE46DCFD486EFBC4F269DF459BC3930228778E579CAA7080F7CBFF1D1338742078D15A101DE366AE138D170EC0E348BED6B79C0D8803301866FAD0BF1D0F4219689028D48269C9C485066ADCB2D78BD88B0C1C6541ECC091B5DC89D7A7EBB47E59D9E65CCBC3CAF31CEDEA58A4F5F4E0D2889AC18DABE35EFCE4A85D6CD6B27F5F1FC2B7C86E6125DDAA01353BBD866E39E6BE5A6B139E1C81AEBB2CE9A89D2E1326162B542ED790E305D51BC864FDA81181F60A04C595754B16D6900F442BB2B5C99A296597E02FF0B32FF088D933584EBA71055B52F7AD4F7BC3344EC85403066DE4FBBD3C628297415CFC72E4E10E5B256853572210AAC55765D81A87614DAF92E579D78E7DA71DC8376BFDBD04A553EDBBB01603A5EBD7BC7A3AE3704ACEAD5AA9778A44EC16D58E56FD0DE8674F92495865461EA8591A6FBEC395532564B5354454FC96EEAC5301CEBE5CB05B86801F9E18E50003E1BF961E78E13F18A43CA3AD596EE75F20523D7559F057FF28E89002BDF76218629EB34C4BC740D9C86BCF164BD9342682CD957AFD62A2A4FBE1D5C9CB07846352FF869D956A1CC5DD2AD80CA543E0FEA25B0A326AC507E93C48A6688D1E049068645A2CD7E6818D0FF03FF55BDEED925A52D7CF97ECC7BD1C6E8416F71CB61D1033DB82E63B518A1AA22F22722457B05F9D85432B14D443F740683970AC2F2F22A219A39F4D3FEF9602D46C30BEFD8497F4B3164BD8CF39D77AD0261AF78CFF1E5FE16FA8EFA512B3C11BEA5EABBEC7667320FD9B3D7F0411B293346FF3B0B1FD3317EF8653F7B8E25E53CAECD0EC7ABF3019CBB97A32364F67C3A0A89761179BF8CB3B266E07804EDA77DD63CE7BD5533BDBD11B4CBAB87E4E5D8DE446936A2BC78958A64FA68B0135186432A074ACF5A7E74C019CEF1551718ADCF908B5574EBA7DE86B617D4A77DD6DFA521C29F91B569699ADD22499AFF4CA238A2E687F2F6A706C998FF38C41951E26369F0A1B95050B6177E4C1BF1707686EFDBEDF960394896C37CF0E16B80E8E7F914BA11853B7E269C47C03B8C6A83BA796BB9AC004BF61D7A75DD3877ECFDD8BAD986752AF0F1A987EE445657C30BA0B567CD6959A2C08089E50176E40614E19E17FF980B382147D4124EC1CB7F027BECC23E8CCD9BF0B97292AE4C37C6BBD6AF10D65A3FF863F4F39B05495B33123731383DA0DCC4F174713E916E2D15E2D95CAAF4DDB734B429631B50BE1062F70301DB621AA01880A3ED8E8EF421C60F445A15AB533613139452DDB85D67DE030032B2353C593DEF07FD2AF0CBC807071B79B89D14632AB63618BC57901F7ECEDE5A57FB28E288FCF82A0E7EED492B50AA6DD8DB36BC5D582EDB17C5553519167B173AF619B174F455EE5A72BB58924EDD128CA936FAE6185170AD9DD6DDEA529CCAD67F97096236170ED61CD5AFC9DC79EEA34087B6E05297D2007BE88C032B0B2F2185340B3C80521460174C7DEA51EC9629DA09F582BD500B8BD48AB44B7726239AC000B572A3C9AC360A74315E22A68A303404294EA5F0223BA7AE052D891FD448ABA091DB1CCA2D04579B72DF8BB339DAB73E6A4C6ECE3A51DCD23DD1CD03D27D53BC115C81416E9E50981CE041FE0EE47FD3315B9C2805BDFC131D8A697E9C747CB4DE9997B9ADE8990674738B3764F95DA64F6A784E313256A9152F2A08A5C40CA817A6F86B8BCF3DA9AACE5A5B66124247930E42A91C945BD6052388EB9244D5CECFF249A741F0B4921395E28D085BCC9E1BBC4C7A93DC9A604E395C4061513E8D5B62B733B05D04E089D585B7F4AA0F6163EA3CD0D130318625F90545D03E68994CD73717BD2F88578D1EABC462BF5A547F2D7EC9EA8B64927A746239B591FE349AE8774FFE8E8EE1B3265C36C3ACFB8833BBD7CF720281C42635A64C103B7EE9556F705E488D0F56FCF1CB6C4F8BC821C07375347B53A30B46BFDC0DE58BD27F92ACC28CCDBBFCA8EF5223160DC88303438CD7E3BB119517FB3E194435FEA91F07D934D38E0CAE97573045116B9F496003120C8EAAD958C77F51987B5353D834638EB557298715501B82BD13D8156894BA6D970E330CADBD315D5AA45DC91A14441E26D33303CE9B21409B58978A24DAF5F5456D671D538A61E95BF7223691B7DA549EFDEF5E8AFFDBFF2B87970FA78C547DDBEE80F469E21C1631BE03A99A4CC832673E177957D0E4C662D1FF6FA093A75EA1BC8359E94293B577472E6EC53ED02BF738A24EEBF53A5E476A37FC97935D602CC9E76B77BF6A0A8D026F912F2C309ACE9703FEF3D4288828FB18544C20B8E6D95E9AF6D89FC2FA369623137E625960BF841D507A37BFC7BFC00A3AB9A1A0B016EEF4898CF01EEBE77D36B29BE7483235D2F6EDD0CED4CDE727E6F68AAA786C48BEFBC7958F32B671EE1E4F05A6EEA6B694E4310EE96F12B58918BEA68FD906CC3B598A8DFFC7190405D63FE18A5700E68D8664B045A8A24889C75CA836BB472E00D95CA6D4333DF99477B68BB89B7DE6C1F561D70706A697005EC13DC0AE7BBB61F87C073DC1DBEE5E6CB7EB3FA2A74A041D57B276A9267DE19A68B0219C654C62F62D5FE6820318A7D8802E838731680EE2D925FADDB18F57", + "rnd": "CC123C9A7278524F6841CBF47A2E0CA2A13CC57784195E98C3C0A6704209A5CA", + "signature": "AB5B331F079CBFCCCB3F95543C2181CB4472A1C24FC8125B66996721D1D6D801B9FFDF2F22E383CD3DCDFA174312D393BEA20C4B825B26A72F3783219D45893324147CA7E7025A6CF6C626C0616553487FA4098047CA72769DB702F9DD68F1854CFCAA85AF2FD79A288A5F9B7C72CE3DAEAF5E72A0FC271BEBC2D7FC1069A24187802469EB14012E1703F6CDEEBC3F5BD4623FEA9A50994E31B76BDEEE26621776939D5EBFFCB8911FD50969FF52128D28A674D26E1324106F45B10993390A6DA58EA3BE384064D2951658FA3769968BF7689908306A527FE4AC1BD8389C143DD85F785F4432E9449BBFAE3D14B4C4504F757E632CF0326915D7B99581CF632188A79E526526FBC8A9257D5158779DE9FBD0F987E438056DDC6CF1EF859BE7A1FCF86206F2E9A60B0955A5B4203A33DDB7F5E5A79246B6D99E26A48E9E93DC702A169D8D759955DB97A385595F8407AB5FD5E76EC04FFF7504DDFD90E04BCB909B7D246A5D895FD3A63C0B80AB73411E2A64451E488108CB7A69C98BAC1E3BE1FA49E2E6D42A964C3B47115159982AE0FA427BD5C137936D3728445572B869416868D3AA1420464718009F6C41952739F74090B855A09D1D0BB7BE05772EA414BBD2BAAEEA25AEB27C4F8D3B14DC1D8387423ECD5EE0B111D35A074951DCEB09B41080619C865AFFB7705C8C57F67E23204525A2B93661CEC90411168B891DEBA115453404DCC73E43E69658473A686EB221DD05C1E75B905FBE9D4E96A5F1E62BC7B8A6B10FF82096644241346C9B02585214427C35645349FDEC0C42B7FE9981A072A09530631020C42A5729876E269FC3FAF24F7D46E868049837E6328194A72C38A5736D3BCB122EAD32825F6C61313B5586204B0E91C27A6E7C323EBE3C7A20C0756442AD7F73A8FC81563DB633A662A2AF880CC324CFB6582B7DE62F3977A948B155D6038C822F5F929C0F96C660F0B63AC378FA2450A7BE74C9B23D054B7F22F95EE27C7175FCBD747AE1C0775B396D2EF5E509BFFF28E1CBC766F91B896ADC4C08A49A8921C8B4C35753A5F26DB6401968ADB83447E1C6DB12DBEB11D2E2133D7F88F7C1FA30DEAD09CEDA4CF7F631CE52C475C7A1E2FF4C2CAA2F3FB960529C35917D5571224CBDD150F5472F91EE589BAA89DFC49C83B59584826A877EB2389B3C642DACA5C1EB06935B811B2C321C172A95EC083F0CB1ABD05A478B09630F5F2994D7B8DC64455EDD4BBB376CD67E2E859F25C3C0753DC70E27C1AB76F85339F33A5B323823BD939E8963A04A738C1C8FF41339E6E8CCD45FCBCBB35E0B3AB91A59C39ECD858462F06989BA791CBB0DC415FF36717B9226F2F572327F85A2C6084C9A339FAB94A3449DAE1BAED4CA0E92F47009B756CEE81B1D98E40AE5F90F145206294EA4F9F1926D3FA7DF39EB27C4590B843C8042442C8297BAB972DC1C45F55E9B68A9CF271826FD39963112F56314FF949EB909553D9EC9CDE10FA1232EC66E3F20E038D42F581D259DDC9DBDB04C6338B58D0D2A8AA8EC9A989570E2DCCCD7AD21522F6E31AD28A1005B9A3B72D16C1BF729A769215DC2379FB7C17C9C20B0EEB99A50CA37399D3AF036099E51DBF721BC8D25A98D0369EF11839EE3E736C12969704107F64EA3583DDA37020C65A40F7F7A91C5C1F0DD5EF2343B09BC4072D5F7E43D52AFB13DC93D8A5F24E7E9EE803397F2D77C7905EDCB2291C7EC25F61A7CADE5E3A0D0B4DABA97BF54AAA38A322EA7E6BDBE23C6CC2FBE3F19E5606609BF3795156E0FFBD089261266BB61EE83C84C89C45F45C6C95A6D0D34E843882BD8B0FB828415A988B949ABEA029B1C96BB37CE773B810C4718F8432CF322D6F5F1E12D4F45107F5E8D01AAF224A8EBF9B6ED6A85854823FB9DB34C40CE0860ABB74BF417A86A47A4CC7C5B28267F04040FB8D0610BAA0ADE6D73DEAD3056EF3EC3FB68050E3D4926F4464E7C4C85EEB46685401AA505F9FA82353732A68B7B94735F4AA9BF1FE909C33A587DD926F913C99EAFA9F0DBC3A336CFDB8D68F76CB1309A71EE69C723CE65D8B301904A2EC0D4AC789C60E5C3A3836E751CCA720AF09847957EDB983A37C6721D291D46BC371CE566B427D2AB5E9847FC48DCEB3EE764CD2E28F1B39122B1048205A78147ACF6303D24021501B4C81D6897A22F5EBC4CA1FECD9D714B0288CB40B8C6AD3593B536A9DD52365D15C11DB3CDB91A9AE00B51E3B6D56F5A1D9B25267806D5A6712358F4F49709FFB4FA40533729715D6907DE3E4BCEC953BF673DB6947A9E8E3DF5AEAA537D93531F53EDFF79756C3B2E2E8739C7F980F525297E60775F8D360B10C2A4BF64D2E3C8345D56367DEB6555B44F6A786CB76C4781EEFF4FA4F97F9BCCFD6FB0EC4CF1F46D2485B69F4183390D9FEFD93549753E98960E15EB5573CAE660800AC76B3B96880BB45BD75038884D57133C722258A5690318E11404D28E29CCBC07ADC05C5BB2BD953672CD84F51C6848D50787525173B0F69A2D2577215E685639C220671AF98C41535B4E5522DD2672134E0699DBF75851B131D16F43B17C49181088DD6734D3CA60A2B39F0A2C40A8A85340341EAB267F06CDC5427482FEBAB0AFA7CAF6D9CD57455314DF952EA26F750C89DC0DC18C44DFD5117E8220BF9B2A34405135893FC61958CCDD0B75DB6477C7C1911867B0604DC1682A362F660E7B8DE635B48B33CAEAE41BCC0A23E32C2EDD76619378AE09E1DF2B421032283842E4202E4EE5670502B5E9CB4FC4C6DB5C4A735E10C8CDEE47E0C185173FB8797F06C54669EBB8D3DAA69BFD85EA935D1D01E7BAA1EA3F2096DB81E154D0160ADF4F40510F99B2D72E683C0AD51B58447E27D3618AE71802E25FA0F3DC85948210E3D2B1379557D872E8CB08D501D1C62ADA7E66A2A7D30E27EA641E9DFFE76D8908D05A23F82F3EDE12B7336526A14BE119434982DFF34F0D0344CEDAC15C165F9FF41B042071A7D2079BEB538C35C6DBD0DC26633263B719074EA231038F0EA0E3A6C177081613A175ECCF0CEDF95E19489FFE773C981BDAE58E1BD49994AE4BB02EB6873D599310F4556E4E5C9AA255253E0F39C83DC4461DA6239833AB98F62290A7AC3E5144D8379D0FF59BBAD9D2D1168B6697BA23B2353D3BE3636CA910EC9A29BAB68F04508CD14BA60F8FD51A25CA2178C01CE1A73D320C227F98B1B0026E1EA65AD0827687354CB85A652A3661175E7C0D784DDBC62B48CE96754BC8F718D7F2FE8233888502BC56AB1ABB44195321D970E274A5791CA37BE34258B2F5BEAF8A484BFF8D6A7D11D1BE946DDB51E41D9A5E51D537EC855C1CDA789DC172F9D92F4E11E850D0E10A72ACE3B9AB1402EF3AA180EE1D0E39F7D6E873639DFF2E3FFD86DC45A9F55B62631CCB2FB0C3C6E12D061049E2A5712101993F4FA6B3FFBD7360A6572DBFD745337DA9732D61A2A5D94E6D77B265D3CFB4BE594AB0E95820DF5605F5C1288F60F0B94F14EC32640A60451C6243DA90E15A202801653FEBB8A93E5484B4E2A42C3F5AE97D0AF9D59A6AFE875976707CC3C1BCA9001D0FDA847505EEF552B22189C525F1DF86D253956C3CCD3CB327894B03AEE4F680F703A66D2098F9033E19BE814A0E1D6EC6A329C47FEFC1122D8E2A150AE8D4586BCB303163B1F0419114CA8C9EE841FC75C7A7251D69102EEBB7180FE08FC96020181056DB5AD304F8477745CD2FBD69BDFF35D7BD255055E9BE32FE19EC26FEEB7859CBA8105094ABA9E950B455EF18708117DF94B1BA3DB8A8597DD93C40639E1A77A78656C02D24815682D85D0A794CFF5ABA6B354FCF31B207B6D99FCDB8E0D95D5C10E446CCD6701D349C917F9A9ABD0F27BED861EF090A95978353CEFBC91973C1A7CEF2644352416FEF6D9DC0985AAD28D6A0E61822E2C998175409EE23EEC0176016ECA3A14C96B73D0CD660744975305A8A63D6E24455A82B007BC74A4515DB91A3CDACAD4680858B6F8220139893E334BF6E09B24A1984A61FCE5B1ED482274F3763C7E76E30844BB6E75AFDEBEFEC2D9E88348AFBA365C17B2477E21898977152E458EAE491147A231EB71FFE0AE930398E94D05243CBC953F45F21ED5DFC4E65A2A2D0DA7BCAF57185197E45E269A1550B5643BF4C9649DD9169A4C3CDC70272C1A1A062C51BD14E6ABA0A7CAC34EB03DDC7306AE783B5EF5FF34E149A389D7FABBD24436ABF6729054DEFC18ABF39897247FCF6F8D7974D8F5B13DB9416D1C68EC5BE73C7F01C47BBC8AA9CFB8A0BBB512F3E1838FC7F5DE5BDB515026A2EB6AAEF5EEAAAE2421BAED716C99891B9EAD216B72F3E21DFD3904540CFD5FA00EDDD1404AA6CFF7AE6CB0EEE60561CDAA1737979FDF7D782FA086B8F981F469395945DBF5557ACAEF48457B11ADD20656DAD7421890550DD38288BEE1C93D4F93A47D230C7EACF4F0C231E441F05BA2AC564934ACD885EA0974E28E3E8100D71221AB385DC43ECC19B5548F38CB133342FF70B08D3BEAA45FEA0CCA92D501245A7AA905770382EAF6AC86EF572CDF536E85EF0EA594B3A4F4E4C6DAA9CD2818BC0FD4A2674232095A81038F52B28610CD88B9E995A9EF0BD32D11A0957DD24D30909FCE013D5B309904F0EA6118090557E4A132DE23E9E9FDBD90A8B4EE45A81B00FB05AB1CB3078508258CA5B1AAC1C447F18771138F877361802BD000F30F170C53E948C90D9F1502039E0057CACFF3B76C818E76CAA893C02F5032B5B5EFD9D8C1E835EF254D5F5DE2C64D60CF36B8145CB44D56F8E07D3647B9682CB573ACB1AA0887FF6E20B96DE750810D17B15264035E27A92E3E35CF9CF550FB940429B48262205ACCB3B1BF3A07E4488ABC44ED04635939FF3BF2A3FCC3B47FEFEABED2AE35DEB1F27CBDCD3A9214DF5999B4759228C093A342D37A19EA329F1F894218CC2F214D5016748212B49BF51E790EFC9DD899BAED4F74F612E0A9C1BA2634F9218C9CDDDFF1A5D13A633EB4B59C393CB1696BB2C8F57154C3093B35A759AA39DFC336DC0BC96169FF2EBDD3684F9A33D53C977D4BC1D5677D83BA13EAB7139E07C437D1592DFF0995696AD185B6B0F22A9B07723832ACC329421E6DB36230A0E42C716A5824EF818D8E06CF6F11DB050640224EF615B3B784245251BE99B063A232C787AEC272D3229F6475BAFABF19DD32F2A149E44C98A95B383D3BC8955F37555F26E9C8C1DF5B7D6236250BA93C342DD9FA69F2374CE06EA884C91077E829FCB0EF9DD546FB35F6DD74D14F077174AF244CEF210D7AA9B3DDD632D547EAD0831EC9460A6E7A9221B4F9AA1B0986A0CC54A6A6E97B285745A50B6288B793E05E5A373BBE37A1EA86A041333D8F0F70D256D645782CB2DFE72E4C3B21F912279F56595FD8E221487264B96BEF634DFE05B5730D7A48867F396C5CF230907A5827B5BDB7BC67174B3D77E8BD7FB91B220528D6675C1800ED7095E46C7A0A62E12AF7CD72A6680780D3EB0BD2E46D166ABA7C4A704A997BD7A3EC521C94852AD53223BC0569A1E95AB9242F89E66B82D66BCAEE512AECF483D4040A08B516F9CF3824C1411B690D3A1D4C9BF5F67C68DD8BB350E2A6A2345C3EA550049692959AF6AEFD7770773E597F658BFEAB71CC05454D74F20047B0CA6616B2E654EDA1315527295F7DF24DC7CF090E5894D12422232AB5F85B7A8B94CCD1FD30B4AA8C312AB62E1B159057842DB5E2BB4703376D99816027714A039FE51B03EAB7EE65D3F823BC9FE6A007EA9A12C2B5686F1FB780829E1770EB5B8D2B4DC2D183A016C901DDF020EF401F2B639C30D13784ECC896E6425CFE2A386FFF52CFF7605BFD9F3BD2C6CD69F491A8C709F62C3D58B6CD783A1DBADD0AC8CB4455FC9853ED05D83C19CF3E44668F687A95BFFE2E22F83C4F1EF2764E32F226DA4E510ADC65CA85446422454AAAC851F6B5A33A77D9F3985D5BA33B514E8D9EB50CF3926736E23148A0DE4C2B136BEFD72DA5BDB5ED0E7AF38F77B19A241288206851E4454D0C6792D238EF4C32508D9BFFB0EA76BCA169EF264E1E1DDC1A08B4CC7FE652656E672EA21B5853999C5029BA0EFF364C1F62DE9A049E2B66FA078C7247A4D293BFA8E8562B6613FA90089ED9B83C6EC417CE5002E2D8D642AE3DB19686C25FB4BB1A9A5684CB911984241BB1BF31895EEE6CB1495A3FFFEFE790E9F3A535A61C90C791D81AD94FC34D495BC35E00C43406D45AACFFE5ACF8F18370F3F89D3514B33E76732378A91333CCA609A112F0C75AC2D6DE22B2CDFBE6BDE1E8610F4F01E4CA562B54318EAD6874320AA17E831F487DA76B9528E2FBF8D4EEE8B4F9504222DC040979F13C0D116BA6589D81E7E72B94763B5466F4D3AB306DF48BBFCA96D66827272188D7DEC0B01C88D9081888677E587DCDED6BB69AEBF1187291C2E36606A949EEEF2153B5FADE1F00223267CD12F4E7C7F8D9DA1AFB1C31020285D6B6C737F903B679FCACD0F27526C7071909394C6292B2D303A65788A93000000000000000000000000090F141E272C363F" + }, + { + "tcId": 56, + "deferred": false, + "sk": "0F1DFC8E70C9C500D56388DE7D02FDFFE2D196A5E59759008F172317A2F06B4A6412C77FCF9958BE0B9C821A85CE99A0B37A11D634A82FAE1129BB32E266CB2F7E08A6849249AED1471927586F9F773957FDA32AACA8AD3696806DF59413B260ED59A4C29DF28F9C6A6C605050254BC7FB42789DD6B1DFBCA47E22A07A7FE585E3088D04010C48A65008A240502885C2024D1338015224114C248081C28599143121997193444124438A1C221124014D1026714C344E13264554283210932C813625A20891CB148899B491A2846DE00225C4200908A33102300C0040689B3001A1422D52409142908983464202396A4094444C420A51A42C82A844D388080AB8501AB729593420C2A22D00014A90C83049000C09102903B191D086890C018C59B84863B4289B8005809609148148CC00080B426442488118A30503426AE49649C8C420194805E4100098B241C1B450D1920000C308423452A4064E5C88859BA071CC984903842180280E594682A4369188B60803172D112772C8942CA310468C361143027184A420090864429221DBA484244502483681833670E44051D304681A272A40820044428DC2B67040C250C9288E0932001242700C346084801024260DDAC091842809A388682018520332851B1481032250A11031E3188124410D59964904A7900BA16884128563C2045C264202077212220ED43020CAC86109241263C429C8A600882804DC4012111506003600E10464812060C316299B888D01B340A1C2090B898850406264060409081112868050166E8A140509416A4134411C4461C49625C008664286411A10009B96450311519916428C3272E4400CD0B62D443405098124D3C63192808CD9922898342E4C20121A1404004564A1140A61100C1492219A8284021051E19470D02421D2B485E4308551A4400830048128859A806984968DA4B20D10468519898C204012D3048CE01881CC8220C03644180368DB96900BC385541486A4C450D9884D9184102403691C00699AC80D9A841151A2504C4284E0429202C868A0466910176613380ACA020C4C1861C9B8619424710BC71003284042428940282C02160CE0122AD83271590231CCA2512196455A922023A68C4B20690944300CA22464325143C64021146EC98890D4020218033119A88461164CD80685D9A40C20338D24C621983865E3888C4B022CC0C204A1308C8B087001A244C23806D2421263060004357162222D113061A30068C03852A102508802711BC20C5CC090D0C46120C411DA022A51204E4B9045DA884CE0202484A2850C456290442988364560088E8A046C4198445C240549260803A94184A80D52C04C02A64C91189012A81042126283100D10C34903280D0A8130A2A0715AA00CCC266E92A02D14B0712118109AA86160A885149309E1922D13160A21392D8B282911268C23946060347103002D619489E010494BA08D891664DAB22DD9A00D8A4408409871C416651C0062A2080652C86CD1048A13C44DDA04905344099B18446182514B3241D0942D10C75009484D81A42DC348441C37620BB30C4804321233669A00824C28861C878D41388A1016849CC84944B060100720E2C825C186859242009A025243C22DC32820039130D2180E4C9800C1C6600A380ADA3080C148260893404CC425A2C8490396854B264D982281433832C2C030A1B42903135100A22851145183A470989665A2946062402E18190113092450B22819A5455820800B834091C26D218810DA068A24438C8A384A5932200C456902876159240013254A43062481084D149744E0122E144209A492100A268C1819090B0412002460D41269E3166022A490E2902C52106A883445128124DB328A0BC14802108C51B421821631E1B49144A860C0A02094A2248C3630D1062C9C12680AA24C1CC18D88124C0B4572888411C0924423408D141322042768CC046D0B972483B4411A494A912248228689C3B28904B269033600E2160D43C6450B468E8CA2884B484A4218220AA34880B665E19644C3A048A4085163446C82404921216D4CC4600CA1216136915008621945480BB58D0116219CB669C02628D9226C8B92404B140500942423239181C2444424921297054CC44400034904C691C802720218700C1252540049D9244A002805CAB080DA3065A442120C2149E3086E1199415C2812DB1465E48850150489421E0424E5D4198C0BC610E7A2C0AF89A802920E94BAD257C4A20FC3F441B15F18C12989823936F7500D9F396E7EFC1DFDE4D091C94D8274472A705C5307493D60973A7E6D1AE2DFD41172C9A1B677E4BA7D6A96CF0EF65C24EFC2F88C7AA2FBDF60C7ACF9F5D75B5313ECD9903ED84EA5553640D5DAAC7ACE3DB5D9D456D57CF61FBAC3B16E80CEECD0E7B81889A0EB73598987D3FF8CADC21477BFB83686D08642F97988AE8A115C76DB5AEA428F15836723CA2EF3A3C4CDFB40A90DF0B8CE63DEE8906916ABCAA454AE346507B7DA5138378F3CC640F7B9B6F4DDDA27561A010517037F3C4C41950F7B5C2C54F0DF192651EF0EA87AAE7406C84FA46B7438E9A75F85AE1FA95DA2171BC53A5659BD0AD135E71B7CFEB13583810C8D87F5F5D7F5DC08906BE60406369BA69745DBFE2A41349FC7BCE1822C18110B169B780AE66CDE18368316E8279F2DE020003EF92CC0C9137BA8D794C50D40876F891BDF2E588031E3AC95AABB36E1EB0CF39DE0C4E8EB7BD4486B5075C3F6D62273D3372FB22FD33B7DD8B4619AAD1638903D9115EED288ABF30B2115E65B28CA97A6106BC276C15B7394412F03251591FC74934BB646EAAF8084B53FB280199E1F944BFF4A86D7CC74D45F9D836F8245B98E2660B9C6257E15A6532797FF4B5D85C8A596C2AF154C23F938EEA0B93A4E35F54894C38C907758AA9B79E7FDC3AFBF0101A0E3707D2CE72C771A7919BDF72C2F58EB891EA62D9F6A5392DF9515205141CC7C4E0DB0B5514ACC11395613B66AEE1DA4386411E2D85EEB40063A00923691D246CA68014652CF4D0A2651494F059AEBC1C322E6EB0DA8EDFB1BC2618BA28FA3A10428199E297EC248902C2D5C671E285C4649E2D4B4E55931B62A25164DB73DBBE3A8A6F068FF054B749FC28B77BDD5DF7B033BB4B6B03B2C6770A509CE597328C17C845B6896D3FACBA71AA56CEB3503D01FB0E24038C0E635DA3E58D492EFED02263C3C537C19183E2EE3FD82CDCDD08CFB64BE10D8F4D2FF5899B8F9D5BA2505ECEBC43E705DAA8F7237B694C630D3BD0934C322002D524567770047E718F76AFE6401FE9D5AEE53535A07A7AB835177240F28624BDEA001AE4D1DC70999EC0C5D98773BDD2496AC287F819B8B2403D95D61FB9832E7BF669C6570301944F931146441A26732C2C214AB9E1C25EC6D31DA964D424DBC181DCA8AEFF5C9F475822D1F9EF07E6FBF7776F9A4F96E25A9213F43E9D03D6CEE14AA4EDE5B349EE478DBAD04D0558B0F77163E65CFE9D26969E2F90AA3B655674F8666014EC3149F8A848463A2D3553FD45724F1430D06A47A95F4C9941A436843995FBB4E86D3F7BCBE06A2B4D8B185FB98C1134B12E3738FB4A70B74C54C367C957EDF6262EB34D78465CA3E628F2AB95A37194003F9299735665EC7A5A638735BF11EB6ECD7B5769B599EA686D97092A9ECF34133656DDC4C1AF1DC0CA76BFDEDADCD447D1A1A2669DA555864B8D731535D5BB25B73542042F00D22E5CAE35C2C6903E501A48CEA7A75C9E876A2E8B6F1EBEA481BFA71CD7EC5A52DA70C3EC10032BB7CDDB16CB90E0FC09AA81A7D2DA695D96EEE71D5A686E5473D3BD96EC2764EAB767D072E8BA310BB9070BF72AB485FE905BACED609BC27AC6E847DF9271ADE7566130515734DAD6BBA77C8C38F588EA65DB5E869FD555F571034D8808D8705AF725A98F92A257117425663D976418989DC4CA503B3972A358ED6A90B49065445800F4A699EBF1E9C48A97501955FC7FCF0532B5A00B46EAA38AFF55E66BE0EE57511A62A2B2A1F8F367AB4B4F253F8637E1BDDFCF3EEB2668DBFE823643FEF6891013FAB5E8F486D3D3E510A97A8FC036B3A5C7BAB61AD50252C9C4617FE5AE6C9C735C6C20FF4185CFF4049A33CC6C254D4201CDE1417F22B31937A67A8ED41C968D548603A4373D344206524A6C172EAD2A496437D3681B6EB435BEB40C2F6DB5EC5331690D936B4E16BBABB593DFE5D823E8EB94A0379349A628C0B7F796AA85ABD28019D3FF8DFC2617FBC497DFCD3048A1DF6691636557D5F99C8DA83D954BDE8B7CF28AEEDCE8CDAEBD4E1F94F89E30EB53FC6F2C0CF30F84251C5B24CD2CE48DD590CA9EBA785F2D369B8FB92E054EB6A7EBFC7CB149EB0B6D93651A6F34544ACCD69BB40714AE401E0065A063A9786BE20E8BFDB349A9A07C211968EC237FEDC18EE6FB729A5817AC72E93B9ED4D5178399C9E7D7D5213F9C841F34B2C225AB0FF57EBF19B38144936D5AEF811921976AAFF85269B4F197797A6CC21DFCBE85BBF9068484E35257611CBFC9F6DFB808CE3F767DA0C5C0071AD3CD6E4538C0D05357B207D16B6A4C3CD433CE251BD5561268CFFC85223BA60D64B87941E0ECBE9021C07282F0E24B90CF4B26889C61C28773CEFD07AF92FDAD15483074AF6FC6E55651E473CE08FB7421F0A22397EDB4934F43862F4C2E9E5FBDD87606C0068DB2D7C56CC87613644400369A2B559209511EFE060928F8F0F9FA80AE7B9FEE5C5D96E6A4314C3CB274C140D56DF061EFEE25705A1792DD25F543470A4615EAC86ADC4D7493ECC75CBCBDA2AC4CF170DFBF709E15A4D79979531E88FA6C71052270A8D38A4EC3F9F6E0F91573FFE2094F0BB9A9E93935E14A4EE470FBD835E2C54673455FD4DD8E260CCCF45DC3E26881265C36FF3F1754C2126B857E5EF003B59100EBB4A6E2BF229E1AEC8260A5387415391006ABDFA76BC0A20756F77DF5542F4160CD0A7EB710E5121DAE6CB1F7882D7CAB20C166F6604507C3509F620B95F0C6CE7C20FC48C0B1F984B9873DC48CCA10784E3BD50EC90F5173C086505B0AA7633B721F27131F7D43981B31123E0E53582B1A56FFB01D29FF0A1841220922F2CEE0E61751ACFA55FD974B3E1B04C01D2B1D80AE56CA70019A5E4DC42780DA6973A949F197BA26066B94C6A07B6BCB07F0D358BDBB1E692B2BCAE51B48D5AADFBA793CBEE325C9FD5D498937BB25AFC2BCA00E69D06D0962654D136EC7DDB527575EB49CEF9A6D701492E9F6FD1E6A3977DDA7EAA13A844582832370A93CA00DC55FE4D19733756366B7BD021288FAC67AB985E9BAAF2BACFF23E99CB48FC2039C71941AACED3AD5567172557D2A1C324DF135E85B53A4398D165ABF22D45CE9292D6D3A6EBDA0BC4C886DFA80E8176A825033317A86517403F667881A79F2070443622D4F30F8BAB16DF733535DC1A825CCE694E1B59E839D4226DDA99F3DB362FC894868BD17BD35BA08BA240DA29D6DA8CEF984ADFBC321D51740487EA5AA13A1CD6E838473EBED93BFF889834424EC66FA3B978184BAC861B0C747683558ABD4D496177D6B7DFA3A1AC7D3B9F0554190F2AA650EF14A7737EFA46BE8F894D4ABEC0D260AB9BDCE4F256ED0F6F32E5FC0468EC982FCCE20C730FC39244975C6B84AA01E2A80822E48E3B21BE571689F3082F66A00AC75659DA0C376111FF4BFCA1977E6FC3B975FA75EA57D688F9273643EAFCC6DDB522533EDCD6CC9AD87BEE439013DCA8E7D8F31C879A02B610B403B6E2CC7595EA1828ABA4515C2A49CCD6A49E44E00256323BD623BAE01224E4760B63F1A36C3F901CB6244CB1F92F37B8B037689EB59F1792F93818C8F73BB545864760A06B0A6E8031D9A5818A58281D518142ADF7B96CF566832F5863B3C425BB48D8E32CDB86A6DACC3439FDD14B09A4A70883C3215B81CA810FD5839194363B80670B263EFECB8B4EC05D4541B02EBDB6E3F68CA7CE2761EBBC5C0FC8E7A8C19332B3473153D52439B7367FB121178AD1BE8E69C416F782E2D30C7E091E6999EE843D8672A0166C4423898DEF93CC8693F22EA645BB8DE5C9A2B0367E2EFEA6D1C3279FC44C64E34F784239566D75B38ED1F1044F4891010F66EE6F9F71C6EB2FA12691DF5672BD2D56A3F26351A93CA6FA179B00FA45AC24ABFDDBD47E2D8E30392457318CE9D0199091C1CAB1EA0E86A9AFA0B3F8E164109ED8DC3FCE62348767C6748F0A0054959EA99BD07F802AA15DFAB905A5657503663862C08167D8EB16DB0DB8FF6222268EF1BD6B36829BB23063A50BEBA7F1AE7D9ECFD3F16DBB03C52EF038B971D80FA6D00A53ED2CAB0209A980F3408FFC94AB11EC7FF89D08BBC2F213262CC416E999F64757BC3BD32CAC72FD0BDB6FB14F01F4674CD800394163C058E5283B1E7266772534A58E1AF5555A1583E89A0528DCFB6731809C4F8AE8F882F0BF5DAEAE416535902A5C51D6EEB7F4850211E3D2DD8A273222CC81AB4E92D9BDD07F85AE0476D936570981128962A33B7E77203B27830CB0D9C27AB41A2A6D4901A935FC41C4D57E213F207F00556B20771564F1151F7B3D0680CB80575C90D49F4E67FBBD24B5042A08DE7EC037533E95191845111B79187CF7F532ABE616CBD6A0B3C162E00778F56B5842E501F56DD9F22F8DEB07C2F6A53002F5AB883E615C4236E05B3AEA9B41BB4CB620AEBECA39D1A5DD7CAA64E8B4D321CDB918328F97CB8741B2322E06A3BAFE23B4110516880CB54ACE7104AF2C2BB9269987AE7D3AF337AA58105711DB2B44074BB33E67DE79C2871C3300588D5F3FF5DBD337E08FC30DE72E33D2FE6026C8F62F7DC40DD6B82FBA1FAA3FC0CA80C299F3A61CDD866A6D1B59AB40E4A44E42938546AD5BF47DD1DBAE68ADC1CEF24B7C1FC4BCFCF13C54EF", + "message": "73D988FA53D40EBA2286EFEEF43BCF96E20FD6923B7B5EF968C6F670682C90DFCA92E24B0E9420FBE91A9460075AF3952623C77D77E4795525978E73CFF8D4B7E6F648E8D1F5B9A98C4E76B5D18490F73AC5693DE377D5137AB341C73EAD4960CF66E497522E5B8F60ABF44DF7F409665FCD211959A41DCB8E9B162C841A55819B6EAADAEAEFC55CDFC2E1004264AE91E0C6E2932EE5CF7940CE87178A3B5142AB36B1A685E92C416150FF291E5D9915B2A068D65C00B74D152FC4163126ACDEEBFF5EDB796131489C3E94E633E4A905E5B83E361A3D420A122B07B731C980F537320EC8627FCEF0D782149E0ACA781DE7F6E0B11CE311F9C7C15B485208CAB1DD9FB0AB0291FBC56A5B1A2B370ACB6D735ABFFC7A5E95E7DE10595E44384BF1AD4BA9D637EC77A7F25A10B2CBEF09211FA0809EFA78FC8776E8977938EE207A0DE51A412BEB0DF4F8BA7577E50BCF768A914C64B359D7C88CD4C145E06F6168D1F5BD9B6594B26C0433F7D141895B372D78E99956F16FCA8080D5DD571227EF8BB6004143FDEE732AA2562324584961B11958075FEC1FD13601985307DC0E5B561B298AEA0D518680488675C3A6CC19D3DCBA666E7E0BB541EB4E94836EBCB01719C9F0721D3E6C7FC6866AA260BD85951CC1C48D2675200B9BA72979D04C06B328D5802B613695A0478CE39E1651E814C764D0746FD9ED9AF551A8B3DFB30BA92581F449D14DFAEC363466140F155D445A082CDCF62B341C1E52785B23CCD4ADA0F2B47495431CF440C6A0A4F50CEC6EADCB7FB360AC9CD9F5898CEE413BB3D7D85B20FC830B0FDABC8D8892052AA6AB40BA96D6A4AD09C1EF387FA51DD981C959A6CF9CB72D2844A12361696E8C12752FAAC7C3040C7DA8F8D82AAC50B1FD1DF6F71E18A0D655087D9BE32156019919E4D0571BF778C078BE70720D36A6E08445B86B08A5F74586C5BE3CC5843C196BE56052303643D562FFC40FE65C1BC7B960675D6F6C7F7937008D5FCCDAC03CCD56CF28FE6041ECA327D8871F2E4614248B1785C10A6F3A0E5FB27123E6FD3A87E33D2C714053D0E62967DFA78DD9E972B145CA1547200B834169523027160B067F15F818B8C56A562CCDE215F37B77B1E39939F104B99DDC56E537ABAAFDB40B7DD223058ACD0CEB37CECFE4FC61697814FC2DDC2288D9A21B82E5C5B0A225FBB2DE775CF48BAD11755C7ADE5CB85E3BAAE74DCFF866EAF52F179137DE8247B2AD2B9D5B9D136061CB26420D7E09BAACBAC447F854D2264F39157054ED7937B869F8E7166419FFF1E0A1A11FB5240AA06C7EB0163AB1AA944101749D0540026D45F83188A9262A6BDA81A9FE666851AEB27695EFE67DB19B81913C8F84D97389A0088707D3BC16016D9793EB4C2B257E90F97779CAA275CDFF0444C02798026D6DF62A8CE7E1A729F060925B4AB0A0C55164278747E180CA946FE87AE50661FFF3DD9CECF176E3B880BE5A4A6D093CE87F2AC68998F54B0AE21C02CB9A28E74AAAFF6587991FF018EEBF7D92EB62E7973A83A2CD510CFF5865360CE28ED278FD5146AD54A1776B22F81896974EB140EEFE919D12253891585307FF0541E9308457CB432B51E629D895C806E264525F653B4DCBBF56CFC99572FE3ACA5001EAFEFBFAEAAE167B3CCA51F3E2EFCD03568DD14F062CE72C7F417A5AA78DB07ACC77B8D4E6BBE031B4427AB3EBD51144EF1A8CEA451C79A3D2E1B6CAE0CABEB67D3DC9F333BD1DE278176B80CFBA0E350C5B2566442EB8956BEC91049E584920C24A6DFA0A1D9F1480D019FEB1E58F63E6542329EB8000EA37D411D3D19EB391151D655E1DF4892F8410E74519F0697DBF62A252EA5E3E28A88BEE944D2424671632EE1B624EC688A60E8829A9A97526695FF7F605C9C30339C8ADE37D303D0D3A90EF8E16D3DDB758A81BAE6278F0566F6BC58B325FF705C104EE40051E31C2BCEAA19A00E4912EEA2955FDCE84072808B302AEF2FAF8DC2AEF73A801C7E1ADA6EA336AA0F909711AB8852A3B22F434ACF008E7CCD7ACEF5542930956ACE670549020C3B9B419109ACE869FE94D1EBEF9CA54E838353EC6AEEC1EB90AA440A0586F775AE0EEFF00D8401D0A9D5BDC73FC9EAD974D3EDFCCEA00B2B8B5F251B7D923FBC5C01B5CA761A227170229C660A5D3AB5B5B1AC4533438753D9560A3FF581F3364BC8146A8F909B112921405603D471958F1A9D60D88B74707C355B112B4B92C078904A8BE2B9D0432274C0A7C403992467357B88426BD6964407246FE3CD95F9C914599D08E8CAFAA2DFDCAF11B88790A53EDEC1355BD4C22D5364BDB48322FF23E2505B943E6345F6B0E4172DF3E9A8C4D8E306CCB9DC296FFDDB7C2EB1AB96F6FAA2FB514C698845AB7B018534BFF8CF837F601A19F9C6DDB1A80DC6A8E161B2695BEDFCB92C34390D20C680A9EB080B922500236DF042E89FA48D80A2956661FBBB603CBB9AE483A2DE1A6CD266824F28B06C1F436D7DC998A9879DBFE707278D98E73C2A30BBFE344390EBC9DB8227423D67A9BCF40AE2E78A6D778928D733B9E448649DC48C906A29034E406554061110C6871AC10BD60D7500A6C116174781D1512DD1A34818C4827AC8CA0857F8313E8DA07059151B022A17D5DD4112D4E1CD46A85D8534AEC136D02FDC1DF0255ADDF7E3EB0914D889BEB31652094FA4B246E6BA3DB2D6291278A985319EC9C53079EF2CE5C52BD887845B23BE47277ACC11CE95D3209F4A0AEDA916D19C5CD4D2615D79840BB670ECC9DACCFCD106CB9F8B218E739C268DE37338AC4608A252414804B502B705ED90423209BE82BD4389FF2F73FEAE2CE726603089F956B31ED3895FAA1480BABF0F103C90835CFE23FD21F3092775EB90E22945CD66150DDCD2B556ACB6AA657D0846F9EA4F0F007C2DA69EF72395D43A3606548A0DB30608FA8BAF83C92BDA9C19169F0BA0219736A353807C1E085872392FD881468E93A7529A0BE645B3CFBE12ACFF8C081D5A0E879B18A15A58930661E53798D9ED4908A2A7190A202ED1BBF4EAC4A10ECA6770B8A27E8F97365E6BA42C05176FC498D75DFE467F8E12B0F62AAFD7B8C43732770CA75D72C4A706E916A71CD114FC6BDC9388E831316418061533369E1F7512B10D2A13CB912C60463F77D3A628D639514DF72DD6F83FA11072EEAF34ED3650FA5D45A75E5DA9C3B16FE070E2848AF4B47823D4706F6006B488717564EDC036A05A58211D9AA17512778D46FEF42981E8438CF523D6BB427E63320FD2CC4B3EA6EF650C067348416D47BB3BA1EE69F6884441A01C771605666EA465DC1EBCDDB33F3558EAB1D639F3A97C39EC21B122C90E1E9F99FE6DDC484FCDECAD4BEAE971976D530122F496D3EBAE8A535E45244B51A1B6F83E651092368BEF58BA15A223CF982155FC747AC506DE0F1EF012C42F1696C2EE1EA909C8B35F859DC9ADB1EACD8A7622744AE2149FC5A1482DD3E1CC29A9066C006FBE35BA9590EE990A9AB8163CF2E1EEFDC81D02D35DCCEEC46E544E1EA85465C817B07C55203C57F4E7ED92800C8C383FDAC1FD6C2428202A9ADAD1F8D370E82D3822B92B11B9CFC57936FB7DF779AF305D219F80719DEAD0EB9E0EE001D12BE36B8A09BBCC85516A527EFA1F091BB8A9CAD3CA0F6443A731DE85B07324224473560489B0236A141720F3D428DFC966AC013302464471E7F53A2D25E0AC826E3697D9E86FB7C9DCDD2A1E815C48D16F04666CF58258DC4D3E644179F0373E35A2501CFA3ECDCD0906B56B1291B05C36B41D6D1EE234BE539218B63CB0D082384CB031B87F958C61854F2A40BC6E65F491025A827F7AF5E4089C9FCB2F524830F61780F7A4FD390E9FDC99D818C6E021D3E58F0901885FCDB7E6A5A8942C3E2F2743079C9039DA200B5C0ACF48ADCABE3523E76D717F740DB411318F1D445AAAABE275E3752555BB42F078758613EEE965C2ECFEC6EA01AD267CC1E5F52D2083D190E3379730712212BE47831C9A7A860726AC4DC82C4B8F1A1D13F65778799A8385100099F6101200B52B02692BBA3A63295E6EC7A418E1917D2DA74281E74DC0B0BEC6D4EDAF559573E1E11DDD0C47C456783EB63A5B325BE4FE495BA585F29638EF65637E90EB68049912E664C69FB6795CC8848D76B026123565D9076A2E86C855E46CB2B1112F0CCC2CEA8154915AC740B5D41CCAFC1D5C28249FBFE8243183943B061157073F30D54F79840C5E46C525C13BABB22B035C05C3C9E051F44C45B0F6DF9B6670987C618637CE48132FF204E1B43469F27A73D66C91FF8390C71D1DC1A73C404BA6D9F5959E2", + "rnd": "706E732161AE0909F0DC9EA67C78B2102557DE18010DF12C9FB5BA9BED9819E7", + "signature": "236B770A82EDE02449A455C5FEF6EEA16D9E3CF5A78240945462CE0A0404FC1A23D9E499F7D654A5D34B9ADE3CA0902EA0EE7297E795E956218491280915329C2CF8AA9F69872213ACFC0DBE674A490F9E2D999E875FCEAF88D80EF1571ED90CC3BA7824F71DF567447AB15821C0A8EF6AE03673FFD11E2B35010364DEF5D084895B76BE2FFC8171074FBDEDA6B0B2D95EB56EF7915CA85AEDB0ED4DCFF10185A7CB099FDED19A2F4EF7C8929776C7549AA765E22A3E30D3C185A4E48B5B7F12BA2221DB96517CD0EB7216EAEF8AF51EB193C077ACE562CD6F7B0F2E212D309C7F37296E96D9BC8AFF71C4959A875BD291B55BDE785EC3C8FD35A07B42249FAF729C2279B506B3473F4F50B10D538507C0C7DCF5B543EC871AC68955B4947570D570B4B39DE614708DC014478D7DAC07545E9794EFA3817B7A68A94B9246F0049786FB8C340B600987112A36430E7D1553939170C413CA6CCE66626108ABECCC81490EF9C7CAAA40FE6A60C2EA3871E8B436ECE929585FCB5ECAF5E4A872B52D802FD821276EE0F14839AAFC30EAAE416DCD6F819ECF95D640D903D0A9B05CC5FA51CC3A5773DF9789F4633D8E61E2FF83ADEEC644D230D1D34F11A92FCDCD9885BF6A1FB2360A6B4445342B9665FD3FE51759E14FE029F485DE6CC069986E9871B167651FDF0D0DAA23493797E61A4BAD6F039512D87E21F03659776EEEC28C79FB8E2366270A205883BEE683546CCE32172591DB6E34EA5BE155BDE40C3D13FC054F622CFF4B46AA9D84F5E7B9C4C2FFF27DA2E36ECE7427191A40C35A9D69E2D57A1ABD730AA61D12AF2D862A7AB632FE552AF70F905597BF689AE821F3A271B2F1FE5335A5A05B8F16FE131AD401934B107DD13A108E397AC07AE3C369E131B9DA8AAF18288C0BAB74B721EB84F71007DFC4C14ECAD88CB29D849726BD7F7117AD142F1AE9C6AE5B63BB316BBE5F6655CB7E05CDD86B1DBD4253C1A6422D7256CF32CD0CBC9F30500E964F07DB7EA2CC5AC7D8807D313F6EFCD6DA44D3E41B3F8112E5B1E0EEC5ED3A995C77CD43877BAD85EEC96CCC9F8DF50F5BF94BE00AF0CCADE2270D4FD7A844979FBC3C9BF9B3890E051F1C13BBC02E94C44B4601DEC5733DE32DB9947CDFB4F04B9CA3867A8C4C96AB5B1C6AC84BCB268216EEE46599FE6700608724EB7AFA7A95B8D487FA253D5958CDC44ADCF1D813377491753BFBA628DB2C3B04C2C45659863A3C7B5C11E86B5BC77BFD3C79D4D4F184B3B1CD3CF5958D19BE3C2BC2846C8807E07B05315B39BAB840C8F49A19C97F73460AE1D2415C05EEDFB32986B5567B39E66905C5D9558FC739C6DD2FCCFD5132C3EF2C2A765E43E720B6D54294712DDE87746964908924AAE29B58CD6B8E15166AFC4B40463F44A64D662DF03AE020157ACD344B6F45EB95A7C82F662AB711A03698B6B102A756DDEB2F81C43AD5D3C4B897C1EA15690DD28891B0BEECE56796675D0A1BE5F1530C0F7445C690CB693FF30F815BB6CEBAC8855A4B597B8AC9E3794AE090A776E38DF28D342F04D96C7849E6ED488781928DF0E1729827ACBD4C89DEC4F7752F68B0DF925956D6DA8F50AE9025BCFF574BF60916F3B552089B520F35199AE5122E4D57B03D5637217E42371DDD017EF3E376CE4B9B80E37C7790C28F2385778E79BE816025671AAC39BAC1A6ED7F28901DCD639A2213DE75540A2BF48FA5B3067C64ACB21EDE5D2B35129061ECCEB899E7ED58A7BAD11229E3A507B9E2A17FB0F13D7EA938A05BCFB1046CD7167C9D1CD022251CCE25658DB7A6CC1F20A3A0B5F40415649DC98E80BBC898D1172F1B5D1EB38C3F1D9AAD089863650284A5B886F225B479A27D0FE1E2C1461A3EDF10B1A9CFA4C390B698C44852AF82338589AB0ABCF9376C8C280397B33AD3ACAE81CF2CE76D5D7FE07ED3BEA6820676968F95EB7D26FFB9A2B2C254E0AB3A106538B4BBDD4BA5CE8DE7AE355424395961507A684A6960D4381497336E15C886EAB8BC79D7CC405276B92BEBE88B01D8EF4B5A1973BA1FE74812D0611451EF0232DEB5AC30EED0E81E2667DB4CBE29787A73BAED8181E6D09BABAE9E4B6992BEFA8CCF5FB75867ACE8BD91788350EB0122093049A677A8B74317CC9F9B9DAD51310732AA33E610E2F39F359A389DAD02CDECFD4303299BA6DD8C8003AC6026F26A3B7CC1E29FAFACBCAD60A0752C15930906532A74F9342BA655580186656E5774174E47DBB205061C66CF69A9E08A6C76517A95FB52179ACD225D132A48CBA945452BDBAFD90E3FC6D28A3C04F05D64D5B4BC5ECDD56F8F556C12EE7562F043BDDE9235EBB8BD53EDF8FF20E568C3D8ECACB7613BF3990776AC925B93B92231DABE18E59B92177912EE3EB533883F28484554D8ADD89A34C785A8C3F23E284EB0CCF327FE620D88DC552CEC4AA6EBC98ACDA945A64988AC1E12EA8FA1F6CC6906D6523EF8077D23AD02C4162A2859C4727A97FFB63DBF6C8D7BB83C39516CD2A17E83F27AF6674C254CF1DEDC7051A2B7472AAD54080E247569712B519DCABE55E82325291CDD9A4648633A66381E70AB0F7B65557307506CD404FBCE9F8C137DFE328F178DB36267CD357A69EDE4D711A9A0199E17C87A200BCAD16D745EBE617FC11F64CCA396ACACE56AEA83051FD298856428BA47854306C804911D2779E8C6FACD6680808698C2E57759D92A296610F5F46A05BBDD44FA5D21136EF31063A9CF9BE7EA0BA61881E8ED6C72EB69E70C7741696C67273B0B2036C5C25BA5DFE3641786F5CE0E35D77195718CB31C8AF1D79907DC35690E9BD7909B8C8873FE2B4FAD75E9BFC91C4C9F3764B9927341010C07E7AB2B0695B998D0E696D936F494E3618BAD52B5994E44C051E0268AB16C17DE391951DFFAB6FA17BB8603B65B30B21A6D8337347D0E5DB460A594716A2D354CC36A38EB8936C80074FCAAF0E1370DB499EEBD31072F1344E259D6CA2C4F25759526909FCEC8F3BBC5685C06CDF08F3678784FCE3C5026219AF2EB4BBCD6264620B556F70A839992900CD89611381025724B0A1D4D9DE9F2032959F3554504CD1BB116EC73E93924B3774CA7467CCBBD415287A13CB82F286C4E3B60F15FB6C6BD5A11B036504083A3BCFD7ADC916994EE921B0A15931EA1DD216529D4A9149BEF3BFB3E5F531BAB3C7C6653D0F9D431D0EC9835C6736A8596ED756530923C362D246D83D03DA6BAB711601CA15FB4447BD357B6F2095D7607C17FB57EC31F9D9113F0FFD59E79C5BB59F0FDE20647F5AB4B59A0E7C9BDB51262B68C9E5B39D893685BF868A942BBAE2869812D1BC61AB2A93210F0F37ADEB6E8F721AB20FDDF8F74CD94574F146204782F2AB3069681D93428C437092780549E9A7DFE4710EBBF3E62FAC75D15617B5E66CE92A8CEADE4A90D29CF7A750AE8EA9060CDE98DF39A7E933F5E1FB636C7F56F5F5ED7B4282E62A5ED04720E76405CE7185F200EAA6FFD83E58C8347A307277F4E77BE7C407A82BC5D769B744F0088D1ACFB3916E86F01191101EDAB8E5F155CCD9EDE85737F15A3EDEC7960D9E5B5A1BA530B078CF005001CF6B1D441254248BA747F88775D274CF05053526C65341C6203E2B475A6A5C6FFAFD07542EEC8A38FF3C8521F9F59345CDC2DB4455AA21382F14E2D244C5D43E6C2069C088F31C337D0D24361C0229463E0A42667B19DF96745AE52EFFF3B64F7F63B1CDBECA36582E1A24EE5C940CAEA1EFEE35F0E9022821B9F782A237308B32B44D2184E5670A7AFCDF0EA4CA0FD4717DAFAEE48848F12447C0EF9034E5D0D877A70D9CA133CBA00EAF76A7F786B343F9CCF131085EDBF30F4E13F208E60F78E1DE15D4585F88550E407D9904875882F3E10485AE12DB0926F59C5D54D44C17EBF4B7CA711B6D3F0B7744D75B083BF9A0E4ACF36CF65C5B4EE82393013A3DFFD8F58E8B20FFF4E3A2A598F24E28C4203ABA8980BCDFA0F45D819B11129C192A1B2063BF3111332925144BD1FA37168B3ACFC86F11726BDAF4BEA757162FB077567B71FB7B9D67FE655A5149656271413DFB0C51548A00388556090606DF5EDBE06AE344149128701688F42D1201B33AA4CC1B209D7838DDF0D94E747A0FDCD0086742CC4412F8AD43AC2DC73DE841FEC9753733E1209FA60BE760F8646CE29743C3A400BF3310774A94E271249BA5DA22DF7E7AACB9768CF6BCF8D0471FE4980E460E968597976D0B3F990098014758F67E2F2410ED15EBD596115DF1124C5C782880E82F57077D0DE64A214D10BF9883B6CE4F43550E395832612B639F13168105010B52BB64871157CE78205B8952013B94C339711F70F9276110BC3391CFE0C112EBF1FB020CB8F366E0C017AE557F72F2166D823F5CB6D7C4DA26E9798385240C8D9A801313C7757B924511CD4140F0483BA6C0F71A04C4486C2135DF377B7562868EE0EBAF13AD34CEE1B9D836DC7708B82FF6E5BA520C558649EB2121ACABB393868FC585857F69E5356F28EA5743928B5B22F06F497164A9DD0EC2275FC16EAA261B4D23D5EA18B2512D0288BB1FF3D09B73435BCC9CF63A6414D00C1B3987F3C4A272D49F1971897E13EA3FA0ADA3A1665C357A24AF3D818B2E25450CE5D0685153EC6FF3764448F66167D60D1E09F83ED9A9F2EDBB986DD79BEF8EB636D8DD6D618B76E1CD9F56CA7FB15BFC8706B18C0FD48C96358E2C8A7AF0631C7530891D45483A1C78BC5868F949C24DBCF08E500A85E96976EFCC72E1C80C8EF09D2B1B953C14A0798B7D58FCD0F0CAAB1F5665E2C3A2A2561D2E64E6BB9109FEB037F9B48BEE0B015D7366F3B5262511D46FCC2AD1986D8356EB41AD954796BD1D65F39E1A789058800138B32106A5C503B463664CFCB7A62A26B7ACD8C798DF3E0B7CB31EABDD6FD48CBA6F2E4250AAA1B0FA3DB77E9CC93B150E93457B29B6F7087912CD77AEF45ACCB1FBF22010DBFE40AAC1D64999DBE6563A5CC1CE47E133BA2F147EA637DF7CAD0BA9FD7AE7B71BB61D9CA42BB6A933B355C94D1DBE4BF4D335F501FB8CBE8CF9B0D38B8A1A8A656C024C58D7EE7D5BE50EF4E40E8DB9E34740B4697E35387BAF78733DEB8F53E15B9F1E0E7D078C76615B344DF6772B8CA61EDF2946667D1F32141C194743EA1A32390610980E9A4B1A47B026F9BF64A42098B4EAF9EE5EABFC6A44D555CC261E4F9C46EEEC3166BB15EA5FC0673F9B588C09EA98494440807FFEC724A90B9CD37B0740B5C48625CC12BC0D0E90474F8748EF7CF71E00BBCE6FAB65564F0555855946434DDC70AA85441DBD669D5EFFD790DA8322E57F0AC63755422C050BD9BC87AF2413DE495CD656A2E7E7F16377DEFF67FD05C610806D19E4BDB8A7E077A85A8AA480867315B380CFA2F5384B81C44517F748599CD85789C370526C1BEAD42A721608DB620DDD5B101DB988C900CA7FD93AB973BEFD69D79D90797484A95851AB2381629D924C12ECA441F7E973AD819956F2C403E6C67FDD23605CF8F59C7BA36695F04FA474DCD2A1CEF2008306665DA1E41810047120347855EA0525420CBD387DFE44C62C56F139E22C52A95888746443B3B7F1D0A2D58E087563A1BFCC84CF7742610E9CE8C01DE1C41BBD0645E39C7DD7DEC04082A22176A205FF5C37C1DDA038F8C29367E19061295CFD0E59E4484F3786CC793FA3EDB92E4D873434A9523DB3B225919C2E7C8B9D135F39E0330B9E9728C58C993A23AF111A79FDDDAE33295FB1CF75BD618D87CE76DCF28A86106B663111E54A3DC4D60A3FCCFCA85617907F1536D82F678DCF8E604E55D95381C4330DC1FBEF01CB40486B34DF88B5592C7A8C7BA31998D354E4174A5E6E35ECFEBB7C40DD4C85B8671EBAFCB4085F69C1DDC9A620976B71B8CFF203C9B29A72D25E965A46DA99017CE894281264E206F42132B52DBD7C63DF063E6E2AA7BF9C286762A60DD8D839B9BA332D536762E246B50A195102999DED71A7D9A20C31A592CC92F5CF8C705EECA1F9FF488FC442688B427C10427905C24542C491A7EF16ECF3AEF18D9C813F4A13E7413157822E3087FC8CAB2CABF84AE5F8F34C7B69CE5BC9824B88E595AA2E6D3EC7965A5BDC18F12F48D9BEBFFEACDF8296AF282505859A788942C456429A7EF15E63801C13EFC16A67C0CB7CC39A06AD53AF77A1D6A84C2B86D7F30B01D3BE34C8AF522F7D2355C19987C93786F92F32641F524A0275BF6B1C556D2F83DF47D2E307D1D22E73BB3C2D91CD5E8B67618DB023B78B38887DE67238E49C3C76FBC1F8B65999BDD299B33ADEADE0A6E1BD9965E97730F4C83B29CD289BB0160BD57343792F513E026A1FD527E530E9BFC84A184C340D10121F953C3E2A0AF2E95E6F335641C16C2402D1C0A799F54E061072C11B4540FBD0F77002A52C62971BAE38A9A3AA85867181D2438497388DDE1FB061A358B7480D90311565779B0FA8AA5CF747C7FC3F00B2428536E76B60B17464EA0A1CFD3D80000000000000000000000000000000000000000000000000000000A0E11181B202730" + }, + { + "tcId": 57, + "deferred": false, + "sk": "1718BD673CCA459C0C1E3E4B3DEAF8F07873B62AC10EF3863B76D57A52BE23E6AD8E5CA42E914633F9974ABDFFBD666778235CF1C9CB28170BE6B9E4FC27EB647B2B7AF5FC370DB2E54F69C984022D0D5D6070F3B52C137A492EEA0F0414A4DD24F0187B8937EB064CE899492DB2D1D24C14C8F821624EA7F25F1EC2B01EC06A0C9580041280D0320949428562B66099282408B72818252D1B250C62068AC92201DAB628D2B40C82B001C9160109C62561122E10266CD9B62184321124012D1BC08C01496C9BA0840AB93113396814C90542A288413841C926490010841199208188689010445A124091B0881446891A10451C136613163262006A4B1812C9A06C83060521A1410340658AB8292481498C4626D3C82819066800196809B901A0382189A404E4C66950C00C200426C44681041992A43228803609201420038470D94026C1388502A3051C250A213321D83044204411118290C034095C36200C282C2449208990004CB46549B288DA982D919248081545A2285121A98500896510222992386812922822A9090B838D5B1852E0946411976C40808541184103088119A5800224900AB800C1324914C885112451D2B2201B32615A248A2247290BB82813312560B82112C589D3B4101B374CD1C20C5B384E92408121978902C7241A138280064AD4806C6006300BB24103122042160563466458B024C2244A9448120249080408220300268A14290B33000A25120A310210C20C880046C942860BC62D93100C14286CD84072C43280A316529CC66DA1225200B78992160C902680839244811649222701C4124CC0062E41846DA1386E44264A1249440183284040651BA02C14416CA1207113242D400406111671D2964D13069052422019B390DA26120C267252366DA1A05112A2001A2869091891DAB411D3B68411B2415112515AC06CC216821009468B026849B2659AC04552406A23B82D4AC009C8428E420882E22468C8084A103150A2340D0CC95189C4611293289B022823A4051A4988543630E4348E591631DA308E1A016400C46860B8601AB151D4B64D0A298A61B62CC9422893420061B280D182510BC2409A326A1B354E1246115C9070E3B24D8A2231C9B028841812028144D9A6640B4180112820D2007288B24C09974448B6005B18309A040509002EA2B68CC91406483064893812E1164E80080E21176DA4B06C142651D0B06D21428883085112C7449A924488C64118176410B48CD3208DDC10119C186444088A03C38DCA0866D0283214C20102429004198602920C424865E026921C154DA014016488100C03928BB80CA3000AD3326EA0246DD3262504C3480B3688D934015C868114076CC2243213C951622820C3A60008410A21C84D0AB21018292802471214108221468803230060C82D94425100901009C2641C430D5C963141929042186823C5291810520CA62051A4295B042209C18940321062324113078C9B92890A331153183108054DA3968808362DCB1061C3226C113902D0888D41040503C888A3A850C1964823830913288C0A838D1A4806D3C62544C64C40302209060809234418008A5B302E084052D8281140402112382EC014901C043009474158122A1B44260A20900C057193902D4928410C84689C007208C98462902D4906668A284C020190024706D1906461904CCA0864DB12681B8248DA3048A1027254065044B870A0488890B2250C492620892D5A806D12186AC8202EC9320AE14210629440E4144059A20CCAC8919A88715C26129A18690CA7480A398250C20950C46523A3400283041141441023259A286109270A98940D53C431123280E01446D424291B204912A42D61806D09B75004212C20C320222206C89644A03609533892004391543221A01244A240884A000AA33212230711DBA22543284C21904409C34880308E92364284C44D0A2629C9308D5A28696004090281508BB008D12084E01805519430D08060E4B21181B231CB922C9C484544C44CC11688903244413688D40801C0020084481112A28064C445A3386A21B590A2826964A6902297048198118BA62543322E11A74090822904B84CCAC4906386649246659880290C464D4C422E1C018211400D8C00810C89842201228A326CA48865C8467163A225182470C126614214655C8071D8464110A56180C624E1346523A14884266A0288482E67F57FCDA8BE49745E2940134FBEFC906E4FACF23F089C467CB95505F5D0EA92D3B81D507F513870E2CB01ECC2CC49D0E174DA78033445D4BBC403CE3D8E994ABACECAA4EAF3827C089F6FE8874D32B9D0F123973CA0B090E1CD16CB8EB6B5E95D1FCC4AC0A6D2386E37B2BB8AF07558AB52908280FB8440C8F36F85476252E8BFA1FD23E00B399FE13EC2EEC784A23801B41263A94D945C5B336244FFBF37424E60480B34BF732BBD37881A6DA29349904E9D89D66C1661E69A8421AF8395EBEB9C924AABF6E09425954A86AFDA3A0DAA2FAE51C25E288CD90669F952932D720031D41EED8AD35238843317A543AF0BE6CDC613CF64A04E062B1D25B17B68546D359B303CF0698B32B4A8CC5876825AB6F38A0C05CC7D0A12379C0836857F0E3400F4D3DAAC8A0706BBDFC1B6282D0536CF453C225586C6A3F673754941DAD661D1B395394BF98FD195D77AF9E64EBC40B2BA1A793A27E1A83E834E6B64166834EA7126D20EA1EC7ABC63645B3B57690E9205B31453B5E8BFA56036DB365DE2DE666003CE318B011B4DAC8A5D0ED264826D793817B368597B0829AD03379D462DC9D930946579D79533FE6354CD3E0D6D88595A2B525447EAC920B6614CBD9FF23E8593A81528CACF2F4FA730D985A2A26803483255F0671B506ECF086D8407BE3397E4E18D7D360B5A16A532F75215F3B45215CC1096FF8F6963B73CF9BEAF8A2A245AA5D7433C07BD04033D0A60912C52D79BCF651C3E3D5E898F73BA91825B3622C81F9D6593D1B34769B34A4D07AB2E26C455434DD70529BB5DA7A19E7C7872D5C558B1A755D59330D53344732AB03B330A71114AA22BB1CF9B1BABB10BABB8E317A9ED4D7F205E19010037B3A2D19B7E2E7BBBEA3D683AB0E5B66461C23C8F1A21066DA231A5BDF8842F867654FD6EEE50489670B7EE538E6C8596C0BDED51B2324AC33890B421FF31C5C6C1DA8F19E42188FEE8BDE4F8B68E7884EA646761DA3D653FE36068D08DD34A2FC0D6BBE39FE62A2689446CD7FE3F814C504F937CAA3F9C02D1DDC183D79751036BAEA4572C310B4F86F2766D71D050156623F78B40E47A48C995095D52CBE17F3F3AA23990F5A3787329C4E6BDEF606008EE95E4D4672D3C06425F959A02F97D8D42B3A0829E6044E1881F43357EB1298F69CAC5F574AB387E702EAFF35887ADFD2D6D70DE86F636DED31808571E456458B535DC7C89A1FBA607233D42AF01F6AC31AC3191BCE2426456CA9476C832DBF1B82F3CD7A367B8E4AA90CA1886D49865D76C6B09EFC788753D9E7DAC35AED2A459F9F71FD07DA1F9D17BE8278D51F185C82B702A2AFFDE2CEEC0BF97A3926833470D9E230F24C200FFB5D467F28A002B401DB07084DA658DBF19C60C53B61AA24330FA17CF60358E151555DDA6B5F053389724DBA5EE5041C6FEB7EB4F1D9A0A7E55A488A95BA809F0292EB3C96B06B8795DB645CAD085FFE9D8AF6CD17636C1AA897A657EB4F3D3F81024F83FFD7480BDEEA4E85C4ADD22357A4322EC55289FE4CDDCBC4373926231DEA7F0919E6A52F04666C0A1C2F5FBB457826A12AFBB6EEE07F5CF920062D54CED0179E7ABB79BBD53C2CDC69BBAAB8434A58216E22169C41446401759A602865CFD7DB34230D981EC4174736AE13DD36709B1F0D6FA84D523735AD4005647D8A190D8C5BFA8ECCF3705CD07399ECB638F2B868ADBE5BC31DF3565962C62CE3D48F45AAE701C8BAC0C4BFCF757CF9DAE1A6DA8A977A3815D7155DF0074FFEB54DF36C736A1CAD9CFB3EF56188943C3C709AA2B5693294708A988EC4F0D3EC87F53B433079EA5E81C4AD6DE29B73A8C88768EFC9309E08C0CC2ED37433A5C9DE2DE6F1AE6D24F220FAFEB6D9961FB269CABD025314AC0A94383FE093556C13821078345A8851A96A93779872575CC1290720C39CBB3C7571A940978A9ECC9586F6A465FECAD6813834F615826590E85201773D0E62FBC06CB94EF9ED89889A9F78122109508704054F31483CDAB9DD70E03AB3515E0A4EE529E0AD8ABD2051FD454C3ED1824CAD852ABA3EEC0189C5C8FEB2588932081E91533EB2E5ECE63481BF9BA06304F4938476D99DEF5E3011674E4E6C71F8DA376C528210E6A27359AFC1513FB6CD27AFC89731A0CC71C2E59F5C11BE669F6CE13D6D7EA6783FE8518B39C1CBB77E2EEC810A1742B4C64FEC4D285AFC6C2078AACDED5BC911F365270F10C9AAE5BD6A4A2F430C92D2B55E02BEBDF02C99BF92187353297212209A24430CB74D6FAA5BB9CBA74E88033E68A6E3B47D35925DA8A7B2F46B16FAB19F96A660CF59471952932FEDD3F3E4F39BE194F0D50B435F29CD102F6292EA6C13B118D59596859CE06D476B37F192B07F42A6DE274F197FAD16251810AAEB2C98B8E2ABB3D33957392E436341BF20037DAA2073412FF748EBF54EDA9580C3816A5F732D0CF9F61F58D0F93DAAB636B67D2AE3D70D57773C66B488B717CC5A9C901AB34ED8F5E6ECA7928C2F49E296CAFC9AF0D7A8AAC7DADA151F76EC8888F82515039D455C021DE319F548298EA7836F568A434DFA0BEF58979517F296F2A3CAFC5A1E60E3BFBD708A9D7667EC9173C4118410A75969518AC6F16B228CE2D36DF47F8E17A9501FA7E62F3A8531D9B1B5F5C43A978D2958682E23FE7BF9D4629748768320882A5DEBAA13424A1A793E63114B625C01775AF43B4225E9231A14360C55DF6B70A867A43F80995AE586F7739B8E0D6DC4B59595A8B58641E040F30131832858047A898F62558F2197B9769739A695927DEFECA3C5CDDC3D561C25BB3DBDCD6D6D4EBB7D5AC42B15D5201E7762BEE43D3618569D48B88DA5E58382197F5B76FAA1D3B5F1A2B4779F869AD59BED735608C13DC447238D5D5B985369053130DBBB345E4B488CE9629FFE839B94B50FA6CF7646961E8FA660331645D878B2297ED01BE3EC0A5AC56F488773444867C4DA671BEAEFEF971B0A6F406CC2CF9E04B47F9AEBEE7D4C2C4EDECF95B09A4243A62EB9D6FB544B168B93C5DE3684EAE2E3E4051ED740738DC5D57093B9E89946F9640386AA0B27B8E3E434CB0176BFD10B834FE140F53C940B551CE7335404CEBA225FD2C5AF4B698CE98D8264D514F6447E9F23B8244361B47C415F02085A787BEBBD04C3DA201C1095755C7512DD75E29F540EB008E77AEB544FF4DBA1875F7DE7CA16C4BEAE118373B74E7710C1F7BA90D35391CEBED33D4F5665CD455453369B8579DA2724BFE165E1EC24E223D9CBAD40E704E4F1EB29824027BE98F0829F712C3DF8EF8D83E0D55E624F27582BA13638B14630F362B1FE9D8EBE660686D011354A261DCF9F22B67CE1F84B7FA5F51D9FD8C272B091E40C6BDE3DE2DFA49D93C05FE21158E0EA210F96B16BA4B9FA272C39839CF1E9130DFFDE0249EE7FC6451ACCA87C853D1178BD05C585AA28BB90C0CE7340467632B746C3C72EE468B3E8C6EACA6D3DF8279C3F24BFAC72A2DCD1D6612C2682A51741DE2CB3C18308453E6047EF119F53E16410801C1AAE04274FDD8F6DD7A9B6B90FA292B6EF23A129764BDD65F69689ACEEEC6B646A3B9D1E1A78EDAD27D6331C7E1AD23FA0E7C136112E395846C9E19252C9FC9BD8061B6A5416D68EDBA8F449BF9612B70AB2D8848A9F7F7C0D2C4AC39DA904D7813D5D964A90A567E4D082C9E698440C68D2EFBAAAAF62FE66864A98015A54FC55BF202D2E29CFCA0EC0235B4E0B5E1060FE84D96E2B72E26A41D4463E1FE0DB3429D8269DCBA269FB2C27F2EFE8D2DD81997275418FA4B54EB8CF8BA6095AF2F6627623A75963B257CE65A5A4F00755B3F2EB13BCFC6645D5205E77FD86218FC812EAD4C069DF85E6F644A6048381795DB64C366E550D92F4D678EA15E2CB5EF550267BD44A98B03B5330F5AFA16C59D246DA9A84B525F1DC77EC15F6A1BEFF74685F685CF9F4A1B97027CACF4A7939ACC584D0FED204E49E9228005EDAE479B3D2DB6E95746C7DC0D1E43FAC0380FBBA5FA306CA852084C726DF271233E6A3546201D1898C7BD2A43DF0A89EF7045305C9FA28FFE6AE7CC34B479E9AAE2935B6AEBA436B4DCBD85B9587F9958E086CBBB5E221CAC4E5156A748DBEB37D6F54671BB187EFD8B4D76C6EFCAFA2BE550068BDC379AA0F8E8A9EB50107D7D603055A8DA4034A03DB3E448EBF2E89E696B64617D905478BE16BC9D1644E861BEE76D1293B5987F2B9AFFC8546EAEB71F14A7A4952966701C787EFDA6F249C3AD6C8E2D02705A7F4B622BEAD70488E08048F1D18283074CB5F88030879880B7A6896EF30B48EC3FA5218171433F9B2408216C62D052DA8196E0931CFDCE3018C312F37788DB4D9A5CE16B7B6D0F9FB595F5F3534412C70A7A0568BDA1204EA0CDD4901289DB5A13C25DD87469E0771C7D779CC219A95EB79C9E6184E105C76EB3797D78F807E01A32367632B6416BDE50216EF583D6AE95312467737586D19EAADEFCA10355EF539EF11C326DC08F22E76DB7BCAC5451B4AB6522DBA7F906E6A91538FA959A76C8B611961FB5CDFE417CD64D31164F8FE682A94FFEB4CE32E4942453BB22DE100EE0C9DBEEF671313E21A74341835F8233E3DE644D7326DA7A5A0670040C75313C9DB4089D2EE1815FADDC976C68BF95AAF6021B60527409508FF1EB193201A30C357D660341807B23B7652B6D5F1579699089D93A2D", + "message": "38161360466B3700B9AB64F10CAA42CB552582B219C76E76EA8645BAC798469F647EB5F8F93368D44142FFEB56546187EEB014452639E6ED0F0C93AE3F7943B997BB466D32307C696BA8EB00B47D837D3585340B52DE5AABEBE729759CD37C2D42B469DAD2960D22BB662380E4D2D439823082BCA6866D019519043F5338D08F28D0D289B606AEB741DB91C0DFEFC4F0267DAE6C63A5FD153D1FE1804E4EFD4D260370A8C2FBB6319DE561A49CAB207799528E5085F692987895846C374B9DA37F2D6CFF665E42B4CE3363F53E76ABC28B18CCECF27D7A9303D60605B0846401DBA01B476EAC8F663E80CE008A956F7F9A34F09C4D78439A75DAACF6C481359C33ED8AAEF545F77CB519643618EF6DAFCDCB86E52098EF654E108D66294580A3B6E6EFF7443D4A201A11353CDE91AB0240D53C4524EC8323E5CFEB3F66128EEA5643C7C3F2AE850A10AAD2A3BCD4353950F478B730D7E67EAAE2A6C9475ACBEDB5F11113CBFBF6B98D6C1C0A6B2D058B99339A31FF43DC685693BFE86712762CB53DD1C260CE6DEA2578FA0C3F3D1269CA0EDBBE87802A86B372E238E51C3188785B477D96D09975F121B12ACA8FDA39CCA405999AEF88FCBA6892FA435E0CD7A2C59C1976DE0ED0A775AD107DE5EE466D2597F1F4D44D1475BE5BA5A041EB9E322E0FB9D6475E6396F96EE703FDBB150D333C2EFD3E06B27E7260D541A4C9165DB10D38FAFC7AA9549430FA86CB87D5939C496A5748503F670AB550F0B3F8C6F3F4B38BD34FB2579E94774D7E6DBC33C35188396BBD0A103CE187AD53183ECBE2AE6843FF4A271CD6B52762588C21EEB708692F7FDA755C37B2D5FA6B890DC6F7CFDA9F5C743C2C800814E01942C212DCF33660DE359BBC4DC4B73C77A825EA9641A51B9EFDE1EE6947641A96C220EFEE4CA39073A3079CEB789C3E62A674E523ABA33A31B15F7F84AA04E6D28735EA021AE2EB8D48953A7BD7CCFD7C65986D2E36A2CCAD2309D03830D909DE8374B87619A3FB13A21CC577515D3B8197B05DB4E26A463FAB04A616F58EA90D0D8BD9124E942CC24D4F987DE177B2C91FC6C6DAE617695D86070B466649633B99A7EE03275A485D8A44CB4CC7CD46B64B0D5F59C943B5FB8F006D96F2B706189C5F4A282DFDD67E1F8F1D9B12F95DF39EFDFE6D61FF9BE4D01C00FDD967EDA8DFDE4524C1E5B3497AC0596427851890FD46FEDF5FE6F6E1840B0DE147513F78F445212B895B3A9CDD5D5458E11FEFDDFE484E18E0E2ED0109CE80FB8291A7CF193A84176317D84C5EDFC14CE700B004078F73EE2058B3795C844261A8987C9EAA3C589124F66D71376F70945B49854C302893FE2F510B72CCA90ED0880FBCCE731D966D4CE02D9A8EA3402CCA7F236A55CB716567EFBB40A9A5715291FC14779C3A137EB4DA17A18DFBEEEB92B5173EFCA0CD9D865909879B4A476481BB967C8ED2E2E2BD1F0A2268F8BE7177578BF109F30D2779A34A7E1CD19DBFFC80994B6C65431DA6213109C74640D1D82658390A44E41B0702E2D2F08903EF29D268A9C99698CF909635EE0F142A5B753B0820C0C692652963E10434D4B4DC0F411EF2A1B60CE04718009CAA0D7EE80717A6A466133047C50A5FD676DFE89133DFFC8DFD31721CE06E33F10E5770893958E41D65E7BC0BCF1C2314D2EC4E7B0A0FF41A97B741EB340C8C221FFF64E91E32C2C55AF2A027FA93453F1CA6286C9053F173408FBBFB1D3E0F060EB69F145B40BAFB59DFCEFC8235A952B35F2A43129AD9BE14BF2AD92D1BA529EE235DA4E6F89E47EA3A076A1106336A68E917C368FE296B5B850DFA88A536604AE002B5A0123CCB2292423B06344321BAB27E637CEF09F0D8FDB722C3C1DA2C760D9F5427ED1DE74D93B271EF016912A7D1BB62D2AC6DE93429A2BDFA895ED504323D6F47EAF375145010E9D83E1A7BBAB1AB2296DE5FB47DE63F1A6231385D7D8BB00A7D23C353F351403161EBCF744405EF32E7DC60B43CBA930A3EE6C7558172D5A8B35F80A9E392FEF6939B6F11F07E012A87B9CF53346369FECDA7E6F248D3CCD1FCC0F2463076ECB62F9417A6B861B124D810294E43D269A6A6B020D0492E8BAB412872A2A2DA3AB00813259D090FAEEE772F20D47E0EF96F6395206A27F4C9543121B6674F2953F9E4A85C3C41CC3BC61B47C41382BDCCF790C2CBF6D31E58644F666944D6CA353C43A3914B0589312F8BF4887F5819BB9B658D328565979C75F362C673FBC6BBA4C71D2D3D583284C247318D70934CC615D9650A926EFD5970E0E97D8A4C796018651CCC1F2F9400701FA082BE077D5E71EC12EC5CDE20C0943C5CD258A2A462CAF094EDF2BEB328C6C1E9B32E9196CDB342202FAE4450AC520E8AD2575BC159D2CF1454D431A1921BC130AC8B73CE1F0EB42D1AFC7731DF44691E9350CFE9F66E7426FDB0A581E15D1DA6E023951671A2DBA1415230CDF9CCC5F95512FEAFC2A15442A1E471FAB0F57F4BCA71FEA43EBF3191FF918B4AB0150B6EAB557761A8E717DFC7D4D5A234DA32CC9DE0E3053B704FCD74A696DA811B167687A5D5E3C21C2BAE7639148E8CA538966B0C66C78C93138038397ED4958E18DC6261486C709ED903A870984EF08706F27B2C689AF879D8D01146829C20D41E0F8805159398B3C2D4A65E41646325C6BAD59FA8B49DA1E278F4E02033738062E9D5FB74B741DC9123E0053BDAF1CCB03279F51C83BEF30AFDBC576F2AD7A2DAE239323114573FAFF22266A7A89E9ECF640BF8D54D629B1C0710CCF6F1CEB48A88ADDA79C031BC2A4E437F1FDAFA1BC9B3483EDE622A88BCB2F363D0828EF3714141A2C3685218A2EA5A00D51F4E0F6AE04F85E440F6CB2A7142CBD9D4A6854F199E6DEA64FB18382D7FD52E55F9FF7ECC377608DD0C10AF2B07BE808B4522BF8956CF1ECCDCA1575762F050A5F73230C3571EF6650FA6E8BD39C60653709B1ED07A258829C2D5EB2DDC1783F4CEE9F10E11F12764F239AEDEF8E1A2C7CF336FE6E51F8EE84041B47F82E89FBD84E09FDC8ED686DF8203EF090EC86B77546E167CD508D56DC580E498D0AA67E142BDA76358F736E6AF44EFBA8D536924DA8529EACAE27B2C44F8D3C4BC362472BE7C5C77ED45FC7E59E05E50341A669844A0CFF51C265D9F3595A955758FC60E9524D5F3ECADC5A97A45112782B0C1EE4E48548245BA96936F4925B3EF77C46B08E001F608B4E1982314AFB3BACDE95A4899CC39FACEEF971ADDA7CE46E9BE29F8CCF56B0A09871B824E513451B07117186B9CADA1BC37FE4C0CFF90CF64E7754800632CE501C5E5476EF632CC3BA41A6D77322D5E062A5CF8DB6CD0EECE8978801E6FF5CBDF8E4A99FAB4CB192FD9B9DDEE5E58DC6893B8F62F0B744C5EE0FB3A0F61A5F48109CCCF0F96F1BF208B044FB82FCFCAC388E2C46476D4AC5E5A2FEC74ECA53428720CBD291C654B571D6D03B7D2A68ECC6F26B596CE678EC7F6EC74E149DC8D8FBC225FBD9C3AEA3E7892CC059BA24ACF1036517A34F04AD1CA5A6406A3C4EAE9729E5A1D759F03C1A1EA86183858215AF218A534C6002E163FD45C9FFB8B28FFAB045EBCFC3CE7B66B177A62068AA627F95F91CBC395EED05B565A5D566ED81C4D8CA2DE801AB983E469CAB4D0896C9A32B30ED4A7758C4EE3DED7B6C0CB2035CC4BEC7324D8DA083338414FE4D1AE", + "rnd": "638940DA83C6DF9A3B72710AB62DDE43528F28387DE06ADA4233E87BFF87D468", + "signature": "E540D8332B5B3AA03EAD9E51A396BB25D3353B6C8A9E6C997D4C18FCFC0964093766F9A3047A727C8FBA23D14B12C1B84C0CB90D90BD73922470B082379B647AD8235B317ECACC132E7EF9142CD6B188C9B03E274F79F51726EDC4903FA16C74F9D9DD98FEE960F05D2F629C25D09ABC6C9A58FEA0D70A87D360CF4F3B45FBA35BBAC4359FD42879BCAF6EC103E6E8FB3E919B26FD05BB4FFB4B256432037B34D6D12AEC141E4C6F701679FC19337EBC7D3ADECF93B4038C58D6626BC10C9F6EA893561D8EF7EBD490294229EC5BCC84321AFE4E30EA88AA04CA9E3913913B13A6FE9D03D502D2111B892974691218C5AFD376F0D54C2950AFF93D62452546B93C569F9F47893CBDB4CEF77E99BFADB6FF671FF1D2A6AD6DF43D48E64305FFCCB371D4B0506E73E205A2CEB0B8F59CC26FDA82007DB02314B5F9D6DDC1696BF124E8150125FD925A174BD08980A08DF39305510A85408005BA99BA46D7BB3966FF8C9DA0A256F66B7BB249F5004B63D8FAF09F7E7F66BEBB4AF5CEB4261E25D696A1277432380FBCE32D47645E0401518E8A8FD38056D8E37F67BD51F3C9C262AF184913A368BDE2ADBD2815F71E43CBE950FA07FCB772FF0DACAB97D8D0DDAE8C060FB3CFAA175587431492A7D6A55A859BC2D9750C6EFCC3148A736D61BAF0598EF50DB101B0E4A1D2A67B6DA6A9D368265FA60C66D3E07DF155F7EB73ED8642C8047CB6CCABC79C550BE0E0DC30116B2840609BE9B74BEB77B7AFC208FCD895F4131656F7CFFB77446CF2BFFA8D221E1A802E0F5C01972DE9C4415CF8FEDBC1DD95EB72EDC3EA3E259B7EA9C5A6F4470D955039AE00673C37B98D8722D6CA1578554197DCE1510B54547CD610A9D4CA7F6DECED78303B631A2B2885BA9453BB5A7ADC2F32DFEAF847424FC57E43B1040D2F5519265926A60673CFBD429B69CBD5C3B73C69BB70ADA2423CFAFABAD543D3DB2D0B3EEE9584230D3A10A5A0B3B63176005084B34FA3AB03B6163EADC56316C28C13944932A53F181120734FA2B0B1260F57D2B7A8795F684A2E1DC415430BD678883E73F20AA5E9EC2DCBA06B0FE99D952D565E223E33C2E274980F215E5A76F04FBF38DD463898AA1C440E2ABDAD6960ACB536CEB74BD8D1FEB34368D174D76EC54D1CDECBD4BF7C667D9A5F6C88783035095C78423FFB4A0F97A921B8DECAD99F29566C524F6F9C0AD87E490A744D8BD56E472A3071B5E2ED3CAF9F94202EBCAC9272E712B830D2F851499F3626B7715FD8ACA7A807DE58F87C4FAB37FE6CFC33775C8E09F1908D7345D8FDC072B838696896FBDC24338CD15D0AEF9BA97F434F983E8CFB0C4B581134596A1EACF88D632B03056691EFA1A3C7EF7E8E15B33EC6AD17C565C6ADE470C014E58A5B8DF56B0ADAD6A68CFA1AF078397B7521D69F1D195C59C0BAB0EEBCE447FD1950227B71375CDDA60E797BB62E2A082FC636B6D43F0705FC6E97C3D8942EC0128A147CB2C0385EA95DAB645C06EFFF098D2698C46134F4ED2A89E7C1D18810FB2F75724CACF8E6284ABA67885D3B628E4C84110F755A19D7A2A5804941D28A0D0FA0970BF871A32650FA74E6230A9559AF6EBA554E8F5AD416994C55A42ACFAAA669ED0D7D1BECF4FC53FACF92EE00E85AD74CEA4167410239AA7D583358EE3D636F7DC22DAF59BF277449CE2709D0ADBF25C3F90D30504A6CFF974D7F236958AAC212C114CA0D06DDDE5414B8203D0490FF5F498B136E5D43C053F75BC55FC5FBA9888F7BDFF003C279C9FF8A0E720E48566F6DF0C04B853296E9D6BA962FE259FD01DD41BA9998333B1FC8D62575F2AD59397CD4D48E5D0459493F477DA97B5388CC4DC4D473C247F560A68DBF054AC28060E9D93E454359D4B4DD6EFACDD39E97474B87AD3B28B6F44702A8626F11B9C750147BDBAB56AD6B6661945C18EB443A5341FA5555C583AEE2F2127B93D1881C862D62A4FAD82057B051A023119454E24AC2CE518B5797A3891B565DA66DD568BA925681DA3D55F6EDEE63571AA4A1D236571341E5DE8B521C27ABD57EF7F23FEFD2A923F5E59A3989001F2A00D9EBFE804DB09856F7D7F30EE85F8CA0E7BF322496326D228F22154F63801AB74B3DAF0A06A727AA122076121FCC93B5B25334CDF2B91DA0C445F1E2F63989CC60E4449EEA0848B1855F9F06FE3676FD9252C6E0EBF1C961AB985A5A64592C01E5F001CD947C93D30E31CB8C7850FAC478D1A6EED4307A6CC72D67B8342231CCAF9B52AAF3A1C4738672E3D04B59437DD6E9DB7B38C666E845D2D191707A0F97B2CE26D2A51C3886A0F75D8C403F64F39DB680A2DEAD1A65E81E4838F76AFA586182B2C0336D821698913AC2B1052CBDAE05CAB2C0638FDA6D901A670AAB12832E82BCBCB8B151899ABDC6E30F96CC5D8F0C894E80FE1F9C26ED9F9A7F686D896E39F578466771DFA8B1D81035E3AD99B5FA7F0539C48A1975CF2FD9078F25C2328AFBFA6F4FC46682E455A8EDE9F831C29AC80D47FAF0E75D75526F5955E822CCF2BBD20CA6FC8E371A887E45B733A72C4BFA0FB0A2A5F17696BC2050CCE3ABC51ECAA2794107A6196196ACDCB19079CCF97D0D85A4126D2998D5BC9DA971548C8CDD460E100F311332B5AEDAB0512F9BA3131A66B797AE63AB4FC061321D5F4BFF9D24FDD4D575806497C4A0F3DD98553AC2C1A7437AC17A9511B99A3285AFE3F11E78E3162C4549191FE6605945285271A4E6AA75DF65E1D414D2493095B5CEE985A7FD20EAB8D2763730059074DCC90EEF484CF85C45AA6CE6D9992DF1618C44E1E0C08C5B776E4EE028CE1A566E985FD70E6E4E4866C374B9A643041E2E3FB27064780872512B5C381404D5EBA6859D77B1D4A3C98A972ED75E9A0CA335063FB6F7FDEA6242527AF8A2418833449D4E07CFE519D654BD0D78C0AC97EE971B288FD8D91F68E92856AD26DAC988BCAC36DA16112E336C0EA07197CAA5964D5B08F58121687BE9B97AD46ACC3D72C8DF243F4A5659FC7B0D4762570683511B3139889CF19DD10632682001B6831D9C72F967D896F01083F4918E7249A424660BB4A0AE6C28C7B4D70106F0234E9A47588F13799A255713211B759AAAF944C5F138224BD746DE159BE480D5F6CDDF5E1C3B1BD26F68DCAD5FA0FA85D0FEEC69ABC0965BC233DE1C625F238FEB72B8938EC28E3C143D3174BC5AD8A34B36AEE5F092BFC00E711ACACCBD4456DB9981F8443A1F8620C43C82EC74484117664872BF5B14D7C81BDEF08E5105B4A966A7FC0998B1CF0B29DA31102982CEE44C6A761260250D63AA70C7D9603CFA7F533BB1719CD3CA3B44D740DE2355110E14BEB9BD456614C8141873ED80FDAAC5B544399D17F3B39C286250E3A05DB3F011A1A140D7128444285FF79FA1E24329DDEC18480D98383AA3C7FB552024DBEA14DA8D648F966905E8C0A7B846A2B74D1263451E7DF5079E6964651F4AD708D420B5C6598D4E913AD3125F1F3D24B5D3C3735C418CB5792910D2E5CDF5B28A885F4797922F57861879597D7E6461558FB3974E2BAB195B11B85FE164005222FFC1F1FAB89A1289ED8C2C9C7207E5B648B78264D93A0336A3DE4E24052541810D965ECBDCC86E99BE01208091FF93A3CB7AF6E93E11E1C73F4484FB05BD74959D96D98D7CB26E565FDE4887EF7892BE0F725AEE253ECCE0DEF7457A811653B1A61690D3CED8DACD871E72599864CDBA0DAC0A91F1DCB4A538CE0E8C61D689B58377B34129156E6FF5060A4196E30E4456501F609903D841F3EAA91E5F3716231AE5267080FB99AE40543D2FAB6509932788A213ACF814635E33D6F5C0D0B44B028CAF5F80F66E18BA4C81A8635C99F753414C2B5DF4D559B554233EFE2E5B26CA8F90005E2F8739159564B68B80FC6EBC71AC3263FB4E6A224FD607E212F54ABFCD9F69C0AD451C4B48A2205358F67AD8CA2CF412EF2E7B01B6F9ED3A8B39089316C8A4AC34786C127E27437A82AADDFBC1D52A0E4B240F9FC60E71F3FECA518BB1EFB79D82BAECE98B693E42635FEA32FF03E6DB2866A3937884A82D0AAA4B577066A603D81FA52ED761B4015B52DB1C2A54A3D4DCCA46FBFC386333F98614EDF79103A6C617416C46D13C2D4CE8BCF656D014EF62AE973EA1B2FA738889FCAD13B09D33D40B0C20F3433ECA31E171C41CED4E1514670FFBE245EE1B427FCCB64FF8F0A284D46E963EE5C1411AA35DAC796FB9BCFBE5719E4E19C5599379E8396EDD209A84C75E350F0CFED3476E8732EE5DAC6BFF9FB985A4F991AB4EBA5475E2A29661F3A179C0D5233B4768F4FC51E9CD93C50A85CF137515458CA33D6FDD2A57A486A2D466772AB30510D91648700B36E97494FEC74E8A3B321C08009BA2C0618147A86D1BB323FF9BB62367637D0D461504F66A99113A30FEC880F60BC322827C98E229DA0E6761D4EA0BA569308F985378C3375866A795008B82069038C673680BAD8BE5A032085823A610DCEDEDBCD968790326907E618922851A43EDA9E5E73589BD5F17CACCB5B457E2E34965768BA04C3D202E54446A3A2867CA01274F4518A5D3E8179A5F06CC3E8F811E6FEC5F353F4CE88C8D5B3F9B78FF92E197ABB7B32AF9932DAF62CEE6CCA2807B1292D47C345C0375603803C94547C93CEAF3541B9F42279E6AD1D5069C5B440487E50E6E42FC85418E99ADDD4C4C7298C05CBD843B15948D8352FCDE85ED55E7007F1435BABAD8E68267EEA99B4E88F8DE12EC2F823235853DF988A0D87329819E51E0CF8FA982CF7F6983B7A3218972FD17F945936887A4A079C670A9D55E24363AC41B042D073DAD452A40E341F6C93C4F4310A5EFAF1604045AE59CAD42FB00CC7D38D83E89F1A29EC7186648F037B71F9AC59F616E2A5D636AC4B77D0C1932E595BE877C418554D6760D10EA1DD92DA611E8CC3DBA267CF550C7774A75C80D0439DEE4F885FCEC8F4CB9A8425EB336DC414A07E5ECC2B949AFF62D8EA3A9C36CF95FCBA8EB1AD8222170FD50142E5EA6F97BFACAC40230DB389062FB5466FED4DE375D213AF8E998F7A89977CB8860BDA7E7DEEED380FDC6764999C49611F024397C85E98C572DC06FC43E1A5EEDAACDF22D418C6A91B12BDCD363DD70631BEE69877392A564AFC94D40A4562FFBD5B2FFEF205B45B26E1E64D58C5D6C059E21245DF82A4F52793319779AA4B9149C24EC48F89A88CA79C1732724F22E84B6335673A0E1D9D9F0E1F6F65C968BD3FD23CC7284CE4518FFCF1B901A1ABC8A4FE879E88FA6AE545044EDDA55CCD1CB7770DA620F569506EEE789571C378B1A0093A2D5B1D30DA08DDDD8330D4B640DB1B3E32384CB4BAD2FDFA4464F795ADDDE61C73446022EBF046E1CE9B2CDE6E194B1BB9D57D6F6FF410D602BF4D7EB20497086CF7A2C143B75D9DD63F5B6507181A20367002042015FF32AAC962C825AF72B9E54A84133B05C966191FDCF56E2E09280D9F7FDD0CCDAF5FC2F938DAED2B02EECA5901081B80D9F28312DC6DCE95664F80C7FB3CD6CEEA4807461219C4BDF64729522D5CE338FF91AEAE38B34FB5C0F3E396B5BE94CE82E9A8C2F222B4B2223C8BAF24F63E2D9F41C3F582C35D7198236AF5290D413AFD29EC8830064D3E346696B315284260C19C16D6B06163A6EC930A28CD764AC7BE2BD6BBC808EBD180DDCFF72206150F71B0EE876EE34266EAF4BDF9B7AA05B9ABCCBF2CCF264159CF81379AAE9FD951C0192DA9D636FA789AFE4CDB4A25ACCBF69DA889FC8FD73DC3E7D0A2B9BFDA1FA84EBA8CDB3959FF42A45C2FDCCF236A403D35CE50C781DFC37F0E42929F3567EDFA0C2E5113686EE3E18E2427376D5268C4D701FBBA5F365556027334843AED745A0DC09E74320E786AE5A8E51FC55305856D634DE15BDA96645F29DC72CE40C5F8AF85699E3B04EE0A10C8AF1B048D2D2CA8A9CD9E9ACEA7FDDEE6DBED51EEDDBC3B1AECBF4CEE3F3C6BFBBAA84CF470205EAC475D0D74379D8E2446F0DBEC7B63BB98F0A39C6CBD055D43441D310413D256EBE5C7AA4AB080F2421485FDA3CBA5172742EA0ACBDD45645E42B553C8A50C65274522FBC75AC20E2A523FBE57CB8B3F6E2763638CBEDF84243E88E34BB76E95A652F81B0F1C0E5A97D78654802C7E1183BA7E78DC9FC0C8ACF1C9A6A3B74F176E57F016AFAD9791122D3D1D2B012A6B92B02B0ED0EFE6868CE8154B462E8936C7EBEEFDC64D4C00A71ED95D2CEEF6B204F116F0FBD20E5A3EC7D45C9615230686729EDE9B8B23B5B5AFEA296096CAF3C8ECE2E985251ABA2BD5B794FD5F25F1D0B58FCC552DD295C796E5E75FA147A6285461864142270C027B1C38F690D5605F6F3A9E0F17C19AB95405F2720258BC032324B7A4CD6F96C836AC87BE8C9AFF5D244009F5301A814B8FE746DCDDC7796BD29F2F64B2F3D00356DA9D11B737E959EA7B2BBCE657399C2E80B7BAAB1B8C3EA07455A910E45466073748DA0DEE8263F506368102C59BEDAFB000000000000000000000000000000000000000000000000050E131A1E282D33" + }, + { + "tcId": 58, + "deferred": false, + "sk": "8D144A2DD8630D50072DA2AB863B9C2BF4EF934D975A52E011ADB8E9C912E37878748DE31FD4C5AAD033C3A6CE0F06848796FA1CD82315828E0F2573FCF2613EDD63226C8A38496EA8EFDB8D5D54DD152A6A44AF742B13D33B4687215559891AB5199521FB1BD5E2D7B1D8757EFFCD6DFC241A8C5A5EF0BF759B371E206672EACAC209E026685CB60C49980942886914204D91A84804B44544969020B29019A741104466DC3824C2000EC2440C22016A19A42D8CC2200B26910CB1899A40261B106CDB084DDCA64DA136068B26044124818392400C328AA1825163B08C0188681204241C20704912915C1284821841E01044D1A06892488611280198002DCB242ED8086A0A228680366019022E131770D9460C42C4000237261896044B48245496610A21248A1206C8C828133069944204209280D9A84501A5701A48321419710C0211208850220541503432C3C0400B4584C2046D6104669B002503226208008A53C88549088A923485008900523825E0020289B620CB3661200226A010105B066124A164838609D8802D22206983180118188983924809348ECA243180108A403891122669D2B62CA1B49083C45118333104C5641B260813860D2329519B442499C06D081612A4942C8A0250112490D90869A310500AB630A09820110784810651DB84608B347101A80090426E4346204CC28CDC8064A424049902505916488322890B002902278C11210964102988A42CA320309B3049149551D90431D4908D43440C09B82464B65040364880B82C590661C946060014685828268C924503875011A669E4366C08A904C946281A995004296582166E5244714BB0699A002C4286911B312E22800054080D020992A0328C5A4849C8462A0B390120362C19442010191262984402B36CD41041588288D092601A304002C04C948881DA842D208391CB30111A13108A242E0806801111724BA66CC3102DA2A46111868D112604A1B460C9A0451A38490C858419B88803204AD23612D4B00402050422A4280BB8215B9610588428CA8841C20890E20232E3B045C34026A436624C484E58A089019449C2306804030C58903040288548244614994D1015698B9408098624D0828D9C846DE2262824194990220453942D040906223946984032A0044140486650C4501907815A242610428E133520A1825058C8448B446C093022811885DB484040346202202209190814216D628680A10845209801621040DBC64561C66DC3160A63086051080213C760DB326808260520470993180911B7480230295900889C844C01445299920C19016AD9B870DC2289912270C1428A948020D9C02122B82C24376C133608188664E4C00CCB0288D0B8040918318C249252162C12038403218D14444AE2304104B5119B9821224112612468422429CCA2290A260822148523386A8B14240084855A2884098691881641884689893889230871102260D1888462146DC0484AC3406D8CA05004B08850220A5B928C0205914A44820C9165C8A828114051E01040A30691DA4670D0020242B0646044308242124CC82194340502214E4448892349320245610B35500CB86D8896682414105848449898908B8649C8464003B1452491458414294A12441A940549A469C3C6009A420554402A01406211998DD8A090D33850E3C405498880118411D0140CC2002924A964DB04501C92108B94090231205A4829918408432430CA4621A23486001324D3060E1034200A936D1B17418A00459BB06460962424388A00826481B84902350C51488E9A1604D2B445D0A8455086684334911A45268438825CB6641B482A8CC071D1A06CC4202A09116892B80D004448D1A8655B068819104150C24D48A42911064888A20D18032D044944D0C40C4A920C1A086A49004959484518B808A0A061110606084840014904034128DC040D22A32C8034904412610A08849B0072118289A3C66D9B128A030221C9A4711397505486400A244610132E54C80C811605C8A489C4969158B028C4B48DE292808CC62D21994150882CA2A4010A988C82806888265263227054A4445A006E191552DC948114874040268E034470C0904DD43605DB3842224090DAB6041080841BB3801C818524436E22110594482959C868120765D3026D53A408500082E2826D10138D13B10509B26C14883082A005229848E02020A21810A4522471625C747F79B1C4A0628B79CD627827FD552BFEA7156957BE600D8ADCD692BDE40F4295669DFD87C1715BC459AE0A7228906167DFB96D858C0CCCDB1F5438D9E91BC82324B50C604008ED4CE3641AD2FA5D27E01075A37E39993C097937D893B2996D206500BF98918CAD253CC78108DBF40F4701E199F5F8FD7597F397642977680707EE2BB018DEF79EB480F97567B73FEF116643A5061B349FF75720878C7279C6F22DB3223F52E7C72EF7C888E8A375B4943326A4B25F195641527B64C2B08A89070F87E2AF49B2377825AA8EFE043E75ABF82BF9E0B2E5F5CACC860D9B4D7592D22058E65358CC82A065C0A045B95B167B68FEFF0B330CA00BBFDE6AACE6F31222F7339B675C77ECF6334E679F5768A70078F02C0A0C848DD72F3292151C696A1AF7A774AD7145125831F3267E6CD5FBF284E14A076B52D06CF94063C7A298AC17709169354F62EA1BD025AF60699CCD6E1E8613F305ED6AE463D4875ECB69F946AF9505A49C4C7B2646E4A18974D6A0283CC225116DB90DD2BF7CB826EE1C157218302B3C83C91C341139AC76CFC069398C2003917EE241CED1D716A60FCE15AAAB9B14D3FD843EEDFFE1523A4E6069E2D18A1CA942473C12D55821177ABC71B65575E4066754D063D815F407B415E83A7F73CA4919F31960C75520788D88B3949473DFDC907AE5071217B2738C5733B68FD72D8F6AFE7BABBB61842F7814FD89073F636608248AF55D941445F3AF69C7C581136906C3E0989E2D50F2B46B6B6B2F690FB57F1534A38D577ADE7D486BEEA5C5020522D35199F50459E1DF6DEDAADA7922B795BA7A057E8A0A2F38CCF5499F72F5D7618E8459053BB0701815C0F0518CB36F26FE42CE5D62EB3D08A4BD1BD47A09ADA0DDFF2DB88547EC648B9E25575A95DC221435389041F8BE375260C60FA6E8347A925113D96F13EBFA45EB92AC2F5550F2D94520B836328535E44D6EEF298AC11E8B165A96B90A4C36099B5BE52537161AC5238C65DBB1B05D2DDAA5EE46BAD18C0CC9B6AE090956D484B83E0B61EE68490F0B125AA20D12576277EC5BA6ADA3FBA73461F2DBF288C61090E520EF01DEBEF1EB012AB5EDFA996831490700A3871EF2B91A7EAE8BEDBE3502340F9876AB43EFB6E746A9F7F5B136DD68E2EBA65BD909C16214A595A50C4CE1933C58DA66A5BF240C2544A352AE7E23F322390D9EEF129CEFFCF7A924712331C84933F24DF19877D73DB29E141BF9DBA79E3DF597245FD64B271247BF28F94A5E6CFCEDC0F2270D23E96B30A8D751BD647FCE50E49606D732AD46494858EC9CD99B91DA59E61F1AFBFEB7736A5ACE95649DAFDFDED4AEEF49144BEBD173712294F3EE06EA0359F76D24AF451CFDBF4B82E89C38FEF9883F2CE470944B9BA5ACFDCE187032BFFD094989B9F4C165BD8492B647C31A1209727596AEA59740C0182C50FFAB12EF3B8D1706C5A9ED7E050C510C240CFC25EE47CC72BF6EFD888D47E75ACBC453E0FC3FEA0DA6B2A5BE352CCB620848021F4AB26A8565CF0BF37FDDAFB5FBD6A47B3E311767CF269E7F27B2AF2305B4A2A40B725A5B5FF4ED5E2B3318EEB8F0D0937698F41AF39A49A9B5F0F62461D31475F41566ED82FC674568C03B88D9502BB67C86386333BF03CA31F90DAE2E15F8E775498C75020E9F91AFB983E700C60D64F6A5EE43F61DAF91F7C928DEA7C730B55A41590A183E4BF535698E2DA0C40B7357C37D5EA8BF4E3D8221ACE0E12A3E859F2D548CC07711AA798B036BFF5947144F8F3CE3B4B78CD0B1F6B9E6C2E398B0A5B97B7E7C3224999021778971D6ADA7721FAA4F6DB2A6A4C37AA49E2448F78DE890459CC22469C398F582F0655FAD41C79F2330618F1D6F4ACCD14DC1396835CAAC3822A3A1F2EB5D5F4C08E6BCA1FE29BC31928C4E9E14F6FC8E7B522B934FACF7421165F0C2817507E4196AFD52778967538FC4F7FAF702C86F374144BE9D8803B494222B6C2EB1B0005C8A2462CD4938230C67C414B8D2EAF93DE03CC87A4F507021AC4175ABF3285921563FB3DCED4DCBD8B92188647F5ED9797E0BEC61923A2E0B567C84E0BE536BB78166342ACC0E325BE16AD7CD0909B8D2A2A2097B23F6D3F1872623F6BB062F772B8A87A55A82E51ED3D641A1662D2EFEF8D2ED9A0090A287746C33A304E7131655BCF98FA44C1C9726809A7DAF2601B6EC9BDA88CFA0838A7D2C9F27C7A36CDA11F15C52D8ABC6D7334092C6B2FFACEB37163F60BD31705ADF5A6138E4C7525836841BBD5F6CCA3A8FD0851404A29B6B91BF0EC89A4A99CE9E7566185456E4051F38F0FFE9FA6EC51A4C98C4958F670494189A4011890CBC54A4E37BE4E6B1DDA3DABBD593FB40CA89D72E75C16FF5DAF8070973830BD47E480B02B09DE28748D646B80671BABFCB2987C7D8529A07C951E055A7978278BCBB3B6EEA646AB5881A636FC5C16558D6B1449491E7830795B89B05B852F835C9C3DF32F8B8AC320FF5D63401452C695E5DAC217AA709EE92D517976D438412B4ED9C7411A4873D6617466B3BE5EECE45E5B25006EA7542C88C3C3D2A8BF8E55C1E51F479B30AC6FB80C7609A03D91AE1A69278EFCB361A7A8D8A5C2A22106920AC9BF66378BEA6B12563A8AF3BD392A059324E634B9544ED5B59A053C897A9EB3DA18DA0A941B71912284011C570C2AF1753758071F71CC303C586E6842F4B555123276CF8AAFC3C42097C50911EC9C87E6C460D549AED1AB45A9C27E42D11D83D0EC51619A6C1453895391EA297E6B3E0029C4B4EF9DBA056CDBD8B179DBF9E354EC546084C3401AF1AD49AE86D799D9D73D60343D6D52A10ACA3AFDFFC83D296F82261E5401ACB7D780CA05490A6D3EC2BFA076CA2919E53A7A3C43EF728FD6520FE3196912E15D9FF3804D7A4857AC4A25667584C7B237568EF96DF93B17B9C27FBDFA4AC72EF17C57BDA2008F3C1AE65C2F742773293D71D0F598F7F3F0897466C9666E11D71FD1B49F08FA176DBCE2EE6993F7F986EFDA64C3A1C34AD5360A5BF8F779412675FC0D3E2A5C5A358A803BA9F976C9D2BB3710F8B9A6D9CFCA7F36E972E74DCC31EC6527C5F03145F31FF66A666E76C2FE412A75BAEE7BBE114F2D9831E6C5FBCCEA3167C5E37D0ABD9205E9C31A9C10861BA04F7855C96634E4D01FF9C4CD53C1075610E213FB5DBC87E109931F0E3D3EF45D73B7E889802164789564428A420CB201E7ACD84C49FFBC2F68E22AD3691D969694C4918011EFFD0C06C54DCB3ABBF7BE3BEE5F47F2BE63832DF9C4A3A5A78F76D642C02E9E4009AC5C33CCF6D680B9827E1FD9BF8385435509DDA48477F1A77B82B08A9E212A40BF7787991936A54D19BCDD25FBA051393830BD161ACABE8CC7BAF1AD1AF75A2B73291CA4D5C2BF85BE372053B644DC1CC7BB3806B1E7F9E05A234992820FE4FC525B176ED979634DB3F13497C00BC4DB8BB07981F3043FCEA6144A72A55068BBAD9A7898D663FDD51C4E5EC37856D290970B717C252C0F05AE3B9089C7041101ECA99B9565064EEFBB27F10B1E8FBA6BFEB8C8A96BCB3D728BC9004209D334D71D1B2DA8A274FD67375F92D90E7802539491681D93DF0896FEE2F2C47089DF27408FBED77D1251EA5EF7133786C9D75EC2AE0C73E40BF12CCE9A321C18559F236B14FFD024EB58FB88F1590658A29DCABD4D9D93ED27CA28D852EDC513BF401E6179AF10515223ED756E8B3166261AB002B34F13C7FDCE1F94E1372FEE67BC6D16D5A5CC3CB1C4DBC129BFC8439E43B456BEC1FD2D4872A2E93A984647F686EFADFFA39D6A9C6A023713D48AD586F2D6C636A15F05C6A52B47E74CD812DAAD7FC50075BC295F02CA578DAB9848DE3FABF117F532F214E089E42ABDA6EAF4D3A6D27A8CF747DF8BF25D20B7653AE4F6481EEC205E751DE58C3647E47CBB69C8BC16050783AD9DEB1C61A330E5A73681E79D1D2BC247710222EDCC9E0A06F0FD313244F762B24694FB8F01F0E8C3B7BF4470AC9D48FD43FBD15385BC552EE03628026637BAFA37DDFDA92B1BD1F0F804D1B9DA0FD83C7A8FA5F505D7D558D330A9398842AB613A4B1D60198073E17AB8FBBA34E897D7924199DC67B4056657D743A0CC02E53220A0071E2924379C7F3B9CFEA806C6C5E49033DFDFA865D9BCAAEA9FEAD79125E6CCCAF0A8CE6FD2F2BC34545036C33EEC1FD49DDAC243486CB0A84264E755AD432A98D061268E12B5B1E3B460E331A431EAC3762D72D8EEAB05181F5D482324CEA0449CFB484EB15E60AEF939AB954942A4C16F0C82EC1C87AABFDF30031C044D1F4EC26D664EC7EA2CA0DD56436B4EC8497B27DD49ACA689BA3E36A9389D1B0AA7A7BEBCB58D65A336DE83B3C41CC6BE6FDD470BCE35E70384DE651F25967688BD9662424BE19B3CDC15CC1B5C2EC64BB9E7676D8C1214C6A85F9160CCBE1CB444AAF48632A754BECB450D3139EE39227CC22E53166BF32D5CBF4E31E12F9AF24426227B3FC39292F14CFCAB5A6A3EA4212CAA01C63F0028424684D6C6B38A1F05B2B5D1DF14831C29B5B263BA730A2E38F54E712EA8C7452DED75FA0D492888CFFAC3DA70D755C9B04E9C9769BFFB2B690F43825FF3D65B4D0006138BFCB6719893EDD8D624006B0303D88A6911CE616ED261181E2842726F6E05063D4FDC5B620FB9089A4D90566A8AD3CD474A83B8FF37047265C8E1CFC", + "message": "F1EBE589AC8F5DB9F143E620F88F6FFE216DC2464F4E5D5E3A19FF97646DC912C57C4E521625AA57709430D646611BFE547BDBF7B683D53F3DFBAE56E7CE4E221A2C82138EC47AFD6579CA248D9B5AE870E765B28FE33F488FDD1690220FD03AB9BE71A0498BE6BA2E6BDBF5CB651D548CD066B80907E18CCDCC9E747EA868406E9689AAEFE7B8D69F6FBA706F0C142E5195398A503FD04369618702618529E9DC4B02E0936EE9C55BB6F7DA4B4AED55CF00FAA891448B71761D19D9AC138C974905BB5D62E32E4C3ECACFDCB04760833A3416EE1C73EE97A864C4C1BA28902A92A821ABCD2789E5EE171B80DC34D53BDED4013D3E1F3F6BB18984ECC91D63594BAC1086823E583B71540D5CDEA0212D508DDE1E82DBD7A22FA4EA2663FB3AFC73F920FE6126C8BCF2831915C26F0F9CAFE8E70319D7536CAB72AD4BFB4ABF8A6AD0CCED3CD1153891F8F5D5488214DCF0E6702286A5CC40E75DCF775E5AB4E8596198D64B0082200A6DA8E6173BC97AE90BA6B03318EC03A717EEBEF120A53ADE0C1111FDFEE89696A43B72A87357D51BC197049493F56A7395D5349718C445E0515A6F11E53B80103B4428825F997C4C85D6B666868C397C22F7397FF8D2DACDBDD242F0A45BF277FE8A20CD718D6ACE542C69F29203B2934A136CD7B37E9A5C119A0FCA68D078EFC9486A381F848F8FCEECFE932EEC67CD9CAAC01D4ABCC068C34051011C39BB52BF97DEF9D14F3E0B30B79373E75D9C639B2C0423223886A8413C875E8FC0466260E5F0CB4F02FAA0CEE356D16402A44A9FE1C1639C1B37B0622EFCCCF00CEE8689F8758BA83C455D8FA03F5AE9E9D73E08786A7E47D05BD671990794608A410D3D3FBB3B40ACC209600933F7F1A8496AC25C5631192BC64434B6386B45A566C39731023253999B5EA984AA0D148F8CA9044C3AC64DD93E40720FD5DB0B6C8E0A1648877E524EB6FC23A30A586B38530A9144D7D3B07C0B1EAF55810A96BE02B3DD164568991EEDDC20EA4359F8EE95F3196C9A0D206B215BB0209C402AD7E767FD0247012B6D762B51F83ED1D8BB3F4C96ABE27E25FFB6241770D5104A3FD45FBB1B15373A2B9EFBEABF0DD68F38CC8531E680FF37A383123A812DCA6961EB5FCFCE0AA441703216AB1921A812F0A5453A3E71359FA32DC5C056A86D424A150C6820C7357D07C3A21C20A365694369E3EE70147E6D5380970388AB05134F374E7E8AEC7BD494B54FBCDF891F3B314E6C5BBCBC7A989396549B9CC933568082A63FDE96B7B0C49FABEAAC1104A81B33CDBB018596F5772D14419C407440A0FBCEE3323B6EFE096EE052B2F1C5A8D8F0DB100AD3524E66D87B4C94C11EA5F25EDB72BADD99F743D78F54D4FCCEF279A903BAE5669E7C6E88C1CB33B1D599C2B54E80E33F51DCABC176A850C0D727A4AEFE6A5AE05A41DFBFB20BB945B9B980DF14AB2372A178145D9B40A77D3C21947A11EC6B5579D76172F385B8653A47011E268CE26CA2B59A6AC0D3B8BBB3D2446B71F38DBAD8A66BF7", + "rnd": "79B16C7039AA7B852BA484BFE318033C952945E279E72701FEBD176D2EA4BD58", + "signature": "710AE5EFC5E9C10E83B560B5F5CA0965C9A1824EDB19895E210F0DF7FA095E0074EBD42E07ADB3B4398FEFCC92897CA17E059ED35539CC1E4B8C2314CA0550E5C2284E4B0915FC852EF490FE1AB6416D5E8B587960994E1BCE8C10CA7E7CEE3CD10D7EC891F96F901437E896034F13357540F58B12A8F31FBA1B71FFEF900BDE1994C06A01B4BFCE0AA0B275F4D5F9411AA13D49FF692AA52BE503C127D46D7076E5919F553321871DDAE309CC67DAA04B557385E5F2EACF8B9063547C53D8D9EA43EE3F9BC22C8C6DD55610F5BAF34D566F860407DE3DCF1751C4998E2C06E96BE7B8D461D0F003CE8E7A8774232ED8240B129E0FAFA27E859A5E7C8A7180A27D61AE58AAB7E716F7A2E92DC07A8A5E468BECC1543AA13A6D68CFC6B92E2A374AE6AA5D0193E1518D548654DAD993F34B3A44B8FEA2057BB566A086714311BDCA61EDFE3989A112F469CE7B8C1AC8EE5969F85D9FF05CF11FC48C97EF7DE78B3A3E72275123F9E1AA30C272BC4BD9FBF531B7F7F671E67AD24299AB679B565A344D38F4A78F62B166EA53588CC8396FB80C1F2D85D885307DAB91D51EB5CBE2671FBB0D3B48E1521A24907C13CE606EFAFCFDCA6D3BDF08F65D98A75D0BC874031F5FB767D03766BA680970639335D3355256C46D3A421D06B8A111A1F1851BEA0E49A6E4970FEC0EBDD420E82C864AFF3ABCC4FD011188EC170F006DAE9C3859E191F6B839875BD32B0E5F4C7F9C7263B56E4C33D61710FA61DCE629226B0B9A66CEA92E046F13415CE53C62733E33D4EA4AA9BA487D98F3CE16488A9577C0A3722A501B3FFCF657B524B4978A58180045C0AACCED96D2A87A931D83FDD411C1C4C091A10B609BE12C136EC7DD23EE0236D344FE51F3C118B56421A640B10DDC544E977A80D40C24044F13C8F1F4A28B0D7E3C0A9C69683CAFF27E5D80019EBF49BCDDA4321B40891FF3E5E82189908A248E07CF9D2486D23D06B66F642A5A4197F5F6A7E697C0B94E7C9F03CB8AA027B68B5D78B39C4F24193DF93CEC3909799932103105257178F492694A36533778EF74F685365A3C87F7D26E4D07A960E837E23DCB53F9FC9307C72D86A6910C117EC52A81E222D889F83B41C70A811AC7022A5D45245137AF8016CCD74562785E22A0C6E024DCB386CAFE9C57F21CE7653D1698310D856B2835EB80F72304885A13C1A08DECF70A7FF676703DB0DCBBB65452F01FA7D0DECF9F3814345D6C696D8B2F3EE2A607B943FCE6417F8A85833D48897A1E0A48FC862C30EB704EE969344F468121FE68535EA11A4A3501C9101DA1DBB0A04E6DF60D1595A76D4872AA3387EA910BE3296F28385E9666625E79B04B03E02C737A14D4D890A0333CC4CA6365577150D32C8E48B57950928552ECC61E857015CED476FE7126464EBFABE580FF7B481AAAFC0DB0440F64759B0201D0D58A9DE5BF97FF01533DFFE5808B3808EE4AA3E852FE34F3CFD025AFADCC3F6673E0962ADFF96E2B661AC311E3363127A69EB4DD86F3FED96F01EE82D763C2AC5040D881A710CE3402DEDD97E450C66DA7D684946B9D83C909525F347123CE76796AC6D02507B26C8B0F87E81BE257436EE43D5B1570796072EDDDCA3EA5D3E1BB2AB923E1E641B474F29F7C6230058942A91BCAB261CEF1F73368AE7237494EBC6CFC6BCD43D2F0F87499BAAB45533665BB22AE2FE48B98E4D32407C5905483F0D3FB8C075B6D1FCCAF2C222D7A7F01D7AA0097D7CA24A10E4BE41E63F64503CB225193C2E8FE3CEAB16E8980EABD2202DDC190F45743075AF1817B9CECC9BA576692DF4BEFC748C4A00401D4EF0537ED7B29924F4F5466825C260C716CA7547976729F534C9EA8BF91ED957C54829CA6AEB8358EDA49A7B9D6F4C283DF5203350E857099F3E8F0C58D1D88A4DDB274F60B98D3F97FD064041FEFF037D06B450F346947B32A73C07ECBDDD0F155AD53B2E467B6A796470E998B8E2D599EA74991096610B604EC33DCFAE5B7B09871AF4C8B12476830B1607475C686A2E7086F09BD9D3D5A347993CCF2C4CCC4F5452A72B46CFA1AEE7F5199FF28E9533BA06EB599AF219371EA6FA7C6450CFCFA8DB1FC84660E9A04E29BA4C0A3B70EAF38662E1554D2788D4533C9CDE1268F8BCCA9464CC216D24A477A26443345E037A24E452BB078E5B11C566ACDD7A8D53CCE9A86AE68656C96A2887548A8A1CB4A6EAE2949EAC0D18ED253B57DA4337EE5829383E31274A13E608271C20530DF60193EAADAE38C10E274B0E2E62F13BDA3AE60B482775B423B8F2B10ED86B8AF4FB56023AB70EF07A910FD79EF73D829CD096C5BD599C2F9DEC66FD018ADDFC2AF46189EBD00C3DAA0379D6C69A8F407FDD4AA633A43424DD9B564524CA14C5BDD96B97F5D66B6EB9146E0A4DD9A6B258525FDD4BF8D07949E92929ADC0E77FC9619A9F32A0A888E23269AE028855E54758FD187E29C6B09EE1124176849E6D55C22CC7D3254A3C15DE5D26887EA5A2B6A1B951C6C062D9B7DEE29F2CA45B54E19A9BEDF9099536208D1FA96B83AFC20AAA1A78E72F4BC3EDBD88A25E021E3626C462E411B547151DDAB86194FC82AA21F20E313804D592E90A7BA77D51245582C6BF608332E4723410E5A5899235050077EF590AC4D73EA0650DAD87339EC7F4B5C0D82E0B560B41437E2E52CA013D5F15F6B9B55C5B5EFA3A8D58275E2E705E555CCAF47E8631450171CFE1C4E7584D6717AF9C3B1A47C68CEE15476332104BDB15A32C6EA7C7048356582623A6EB2AF60B33806954E9CE31FB2CE27F27E15AB1484B7775C2EC8BB8563D004528B60629C8C326F798F2E35020CF0DD867B2778D7B59FA12252E19C8EFA6480ADE2635CEFC8DA37367B8B3F40920C47CA1AA283A61EEE06F66AB42EB9B4B6F7A9D4F01F2F46D6D759630729C98B01A20470D515AB99FFCFCE1CAF1C29862AB51C7900156AAF3998FDC735B5441ECB0F03B4DF0BF91FBA60F6D43F0CF424AC16F167888FF559CC3A4854A76FD93C729DD29BEEBBC992AED8D89B3892F15FB0089D8F50B3458A98CC2D2AF7FE6FCBF60548ADF5B7E100B6698A6222A9D857A5AEA9FBB8A691B165E3C8FBCF60912BC4EF6E73287751ADC907770BDF68B864BDC2D358AE8FC5679BDA17C57983CCDF77D17D9DB0933FE919B439DE354B8A36F826DE8DC453025002987BE4DC240318B6FC58A096A04DFC4900D01F4BA6A8A057D71B7082BF6A05F5904DE5D40F42E5A58EEC0A8EB0B08AE0D6D66F2C5EF94546C675905A6474C2F0828BF078B552595DED13EEA7545E1B48C07976EFA314B1D27EAA5C42BDD8D5B53C73984ED4786D2AD4E7ABE92EFFA0AB8B12A024FADBD09CD98330511522D819F8C469CB21F0CFBE2FFD1BC43A328B2FFEA52541FFD441B42A7550F179EE2F80997F2982F7BD4316CA15B29CCFB18B82FD46C9E9B3DBC7228E97DDC5C05AFE8D1EBD1C4F1D6D376A83335761BFE2ED91C297497F4A4C46E3C462219B89BE7E62BDDD0DA81367027DFB81CB3A19C5A7EC603B4B0CBA7DE96CFABB553A2BCBC763278014452114BA92850B2D254A72D06EFF56BCEAD95F73EFF3AC478DDD737F919C896AEC8D28DABB043EF10185534FEDA48BE6B2563BDB64C40EC4C964CF28E3685FD43F275CEFA3528A2D6013DDF487858D73FF137A1F7E2EFF845D13CB5C18BF3096778E160D0E547C22DA37529C5D295B05E11EF7B679FA0CE268C6B5BA28444732D0FF8CBF0D557CD0170D3B9F973A319BA3521603F940B33D4746BDE2B66A20E7A798430F136C6E330F8621E4BD4844951D0D6B78592F838D37B8879477018C5787A1224032E12252B243A2BF78F1C129E03AE8E34B4A27B1F76A299FDECDA1CD547A42654EB6C3F7C550B46E1736CF0F1133B5F534AE847B5B4CB066EC760BD51D46A235CEC1FE69D8452C396DCEF30EE40976F43288A8D0544B5423E8E674F3E7712C0B5E85BABFC4E6A946F356E9933C7E0B422A47D790E076E910E88C286B161A33D79AE5680CE754836F7097A895C6D0EB67B116A79DDE2E15AEF9EBE6A2D717B3D82060C4B6CF8C8BC4DDA37AAD2DA23463A45787AD9C50585571BA73E3B3395EDFB041B5B7CD8A3AADB318D6E16DFA971EC2B97D816C3FC0634A3E08E58B81B2DA020ACDC9E560966F1144BBD2E7F981343822ACAFA69D4CFC7D50BD9E7D97260E00989FDE885EF10CE73B6DAC004E9FDFEE4024CAA2D58962E25141287C8967139E1F5636EEB141D26F9E70AC55C4B628C1D2D876949D3871FF995C48B1F02FFEA7294DCE29854BB03FD260F3E32700D9929DE7D39FF0C7170726108E31874724AA11EDC707C24C1D5F8104D31362021400C91D227178EED1660079DE10B21E8BD2C13982AD09312C8C89710F76CA4765F329CFC227B64DA61C950967D4AED060E4F53613BE363CDF3B2D60AD446DBD0E9F5763FA76990530E57601A4A2C5197977196F8774E06CA7598B48F05F37CBA59E2FA3D6B6B5AF6FA36232CEBB179A3D3BBE262C69C43C85856063F37A986F12C86834B4DF4C9E4F7FB3E8D787B98D7EC11018FBDE3ADF667BC2CE6C56A1EE5B0BBD1128DEDA1E733D467280E6380ECAD8BDFD66B004D0A080230D2CC9E7937CA7189BBC91E8A7C1BBC843AA2E523A9229C62135FD3F5B179710B97E167068E9FDD6CC3DCC66D5681801CA3A4AED14E166FCE2B6C594EABF4C95D5B1B15DAF33E1CAB2E231A2BF69C2C512AED6682925E75D488DFC2C1DB11034B085210F95F4DBC9D80FF97B968A17482A57836A1DA3683830C134750FEF774AED81588594FC9F882EE528A02CB4C338119F2E4083B48DD578EB2F9A94E8FB56B71E361BB3E08659F5455149D9444B0F37E65460DB7D8A23E05141BF1882F870DBAD3A9244D089088940318163FD04D32BE892983EBB97ECC8C71EA2B8D58C705D7D7B37130D98848D279F0DE1B3B40F0A09A9C23E8CDB61EA306C6E0FEB11D05BB5A21B53103C531B16D106C1CCD154CF4D525A2A8D4B22E24A515BADB06B075BD293C322BEBDA1B16E88A1586085972035C1A70FE7DB3A606F483E08E2C783A089F105B55F1454B7402298C051FFB138A369A69B66A2C531303F686A3E3688578EFB4B67D4BD956202FB5CFC5ED5C8A9598B58E6C2DD255674EF9CB95F5CC2FCF8AC7AC82620084C399B22E9B208EF4A7A930EA419899E5B6F01B286A3F401598D6A3E0491CBEF9CF76F288C52D5316BDE8B81B25AD01BC3B8F8D7630ED38F0E99BC12BE21BEB227CF34532A4F6101EE946778A82D16F1AEA580F323E9E6901E26C631F1A1BDA9F2D23B80A8612E081598A3A4665DA6EE7440E59A7B18F183240F7BA20762C1E381C0E13BB14151F6C9BCA5606F120C30F883AE5D054C6B11BFB096E319E43974C67B0C335DE06351B72A1C23381101D5C409B223300E1E9743064472124B560EFA5DB460F2CEFF0FCA7888B34E0397A9286205A102DF324E844946FBCE1FF6E1F8FF0C06B91D2544275A985690102EE9963A87174FAF672B71839C93BD323A224005FEE75BC8184C8C873FCF438017BB30C0E5CFE875DF92D3B502B896E8671ADFD8864685DC7EEDE73D0ADB04F05A0E5291E7098E2FE69C3143B9DFBB316F59989B7670624AB87C916B3422AFF08B1B921A1084285C201FB09FC16B8209506EB72ACEF64832840D9D52792353D02F10D14FF4FCCACE35783560FC318C1C7897FA031AF1362064C3A6E1F9759923D148E9300FCCAD73F7652A7B8A61DF62EDF20E6067246AE679822592A673D3DBC14BB5176BFAD02FE61859A36EA4C9E78985A2513ECCEB0FA19D34354AF9FC1F7239F68FBE87381EBED55B9F413C0C2E330E3DFA52B1AD1BBF6054CC81B6ED46171C8470EC64B9A826DAB0C038EEB91B0ED5EB666EE2AAD904549BF677987707A2AD7E83B873E60D8B1CBACD54235A240840F2E2109C20A10AE9901BE5642ADCF5EC18BF47B5A7753E8CA5CEA7348CF666CD03F75DFCA3A7C28640693109C48C0AB75635830614C8FB714D926AA560C8AF47AB1FC2149E761BB8A4852A11728AA4B2EDA24D7D1F842CA51F84503CF919C2177D3B5CBBF2DB3EA61B7365FC80BE7FD4FBA8CB4D3B78AB6C5E94F443FD30B834FF67574BE205761368E23B0BEB460F0AE98F902A2923368A1A17F5CC1E1375D5B6902B8B369FF19A9E73833D2F7AB1A9BDC14E997932BDC4DD7F445586CA6A0D03BAEB73FA97F43228B33AABA5ADA5E339F6520BA1793A6AD17403F848C4E5B69C1FE1BDF0FDBCFE2095D28819C3F151CA42D34CAA187D10D803C06814F8F202878E836F4778F200CFDE3F760EC93674957CF8A9219E9A904A5F6B4A68F9A58B162E7BDB940B317DCBCF3291552B5F779D9B917D93F90708CFB00E95F39A9B1ACB7D7613D5A3F835A93D3B660D8CBB937DB642033406324961677A9BC7EB03070A3F4375848889BA151B242941585E96EF0A96C2132B596D77A4A6BB1A336071A5CCDCDEEFF6FD0B2D326882B8C00308143A5C6F828FACC6000000000000000009131C1F27323943" + }, + { + "tcId": 59, + "deferred": false, + "sk": "9ED577180D038CFBB5D937D2F2EB60674F6A6E3F49A8C14141E0C0CED545F1C857B5C70C1B3D7489F693425172A1EB3A8427101EDDEE89C783AF745EAEB672A58D7441DDB7667DA21A41735A15845004DB755CE182588D21085E293DD933993CA383F96F215AF341F99201CEEFA881765CAB31A0B40704B2EF039BD6255B3BCBDCB24143004163100A53964D230961C496048CA65112026AC1A6419310900C214209802C820211D4160992C450E03290E386114A202A24877121314A51900843866DDCC82424B0209900905B20211C014101C30C103941D248820991854BB28D82828810052180B2881895451A3109A0846002142D19C78DE3388A04422A618630E1040E09A42D24021203B704A2388E40324581242459C071CC486CD410504CC601A1B00492822104B1211B430500856903B0715CA66804A38863B069084541D84466E2C629D9029101944508190A418489DB3846190265982224E30048C02485CB9224D29441E0B44183A40851A420C3344C53288CC48091639221E4982C93C208E49261C8088411395293340640902109328D93906C4A30011038040A33905296890A45251C8291E4182423054549A86862180113345000B10054047091060192B6904B2801421449224552D0C808D3C280424809628231D3B80144222A5B94449BC811D33091133402DCC28918B441CAA408D406811AB0501B98441A01919A480CE4382019008860A06859A68991062994024A19B725503609C9B86CC1C0000B078E1B4642DC30295996695B087109202943963183948093468911C911508451C2160942C84404870CC3228EA020902144889836721C44446190490A298A0C04089C348D80168280929082B00DDC10651B970999368D08B7081B228E1A218022040C8B82911B43851A248A5B12861905250C075024426289262D42362902950449926DE4C22C410804D19689D9B4651218800AB925C248248B022514293100B20D11A5100A8750DA4462238831C2300C220021CB402A8CB0410228829A848D20A349A0963060142DE234880C33819092448908040CB500D3A000500648C8322423A790D044814488410804241CA72954B8115810406132252000205810650A168241B0889A028699886C4AB4905888849C8651CA4032A432924C260549B6894338810B874042924843A4215998602022081A27108B020A934041CCB62D0C072619154A832869CC8061E4286C11B9904B202214C681C322094C1661D0002419416142342ADBA28CD83861C0244018268899B28021C66199C44DE0988C10A68418432E43924958124A011180002509A3384E5B34464336484B184CA4320804404003836C54168E83060E1439425222911A91411106504112869A442D9282911210401C1500D338614186310A255200C3918AA844D2B020A1420C04800C5C346D90486009A0040C2929612000513472CB402418852111288DC242461002904B80295906610C284E61388E11262A2003050CC78DD1203203B429190891DAB20014A49051C025C8142D9B844084960C62904C48164EA0365014434DD49230D4A8441C21114CC47058A04124B66918062623126A99244102852D61244401326591A024014690203461849830E3422D5BA44011B54D58188C20B669C3980582842003046A191902201542E11449CB3608D0046903C92988A6111418305C80645B02866124004A026E10B54D4832051B26240C93011414640B488101C369219310DC88002246510B86619A288C22902413000D24347201306E4C82041A41115A828083003258B608A3B22510934C19490188160D02078A12A3501B8765E1C00002C290D3B2095C0041084908C206248C12840A038454446550B4416136068AB08C08108A13A2091439720B43711AB630981872DB3850610869DA2480013885A4284449C44C630888120870DA103062A46C18856588040A994481E1B6315C9671DC32124A10711A41729296451C385113810DCA3052100409100612D8C6042182401CA05098122611129001856804254E19812C63400821800001192262B86D00158524268D53804913476D02000813A18CA3B60D119164822625D1146400188D0C188E89002662224601364950C26489462402B2412037259CC420544212A0280993904D1B37441B16310B482A4C360CA1448909913084380420976CE4466084B86D026FF2D8833263BA2BC2C042E32D7B42A4CD80DB7DCAE277EB729BD769DB28FAC30614F6154C726CAC689FDFAC54AB29B5A80E36D7D9F5C78FD5BC62318F0EC3D7276F1A6FEECE174A39AF8F02351CE28EA3B491A9CCB6D12CA74F5B804E938509F7899D6FE154F9AE31705AE6190ACDC6D75E1B26A5934C90AFEA03279A0521F7242A08C182139DEAEE9297AC0B0FCAD1EDBFDB058A9D87FAEE004E4A05B8B4845F9537DA55244173820F5D9930716A3EE9A3D424A37DAE38E6B57FA7B2A2E84A0BBF112C0C79FC74785E46F6E94C0976BE3F2E80F00CA1984943E6E5DB90C87F0D5CE2791268FD23D26EA0C7D5EB046C2829B4DB162B8C0499DAD53E4F5714F5AD1F119EDD7B7F1B9DFEE77ED10768F35477CF9668EE0277224C7B99A93FF7A9C86C99D28E6EB7EFFCAA6C4311F80EB782DD34CC3A430C7388D32536AC05DD512FBC4C9042A1EF4A3EC99168DA6783E4859404A5CF350E18C76C5F44C8CDF6BAD1ACEA182486CA2480E833AD200BE8C38DDA71D9B9F4C6ECB78E0FE37551B34FBBE9B5FAC4D11DBB64D67AC0B597BF1194AA558182D6084F174BEA6A9DB366C60A3491D7227B50EE1FD93DF7DB3D3187B0E3903A76676E69FA90AB797F305AD7D169C5B7831319070688BD2C5AFDB0DF725704F69EE41F9423AB25FCB6252C3EB280E5B46AEF5B3F1EB11A532594BE3408C063B4E6BDA200E30F2012F5F2B5F7AD09A2C840ED8B64DEC8EC4C627401DDE05FEAF2EAAA181093A16B4355A8B7A9D75AEFFBFF36CF1F3DB263731F079DE31E0ED09A5B2E74E6FA925FB41E803071B46749101E395797BE9620910E17B3081A2031DD94C1162C7CED02A99E9C1E8FF157C5E2BFC6CC14E26B8AB9C35789BCE965D5EFE319EF4AFB16712A8B8407A64281BB0B4053BDD0B08ED20A7D347DC72C615E1004B3B3776EF9AA48481B64DEF0046598DFD413C156BC474AA2EF7969A3068D348DF5B74C22470C9323DAEDB55F76663B43422BB4E57716513286C58D4C243B7553F1C8FE892A6F11491B98BF6F5FA8FC93E4C915F3DE618ADE54DE1D8A1A7FF264537CF54ACC5CAEB0ABB56933BBDE2E25F556067E778417ADC6C33B902C473CE32AD2E5BCE0E3D978141F5E7C011E0CE3EE5C51AA77C56E22C6232BB8C9A9F80968301B69A098FC0DC0C3064288B93717820456FF85864D568D3BAD940012D0F5C6C4132B6828B30F21E9E1389DEC2952F830356014C98B883788A6BA6A22D5E82878012FBDE9D717A1B860C786A189D77BEE8F443CAF8F6C851CB17726A4F490B97F938338F9F48D826810556CEA4EF31DD58FA2EB97F2403D17D72C50B29EC13B1849EB3AF77D181B13896607F7F8651EE625E670BCEC55E05C7C02B7FF38B261C49DADB033E4E7E54F8845A81703441200D6D5969B03BEB61960338892B3338F5EC837959B6CE687E168F0FA2018458573A89A27BB5BDCAE5D70A4913BE8A652EF9896717E0B184E98E517FDEFA1B8B0BDD5989549661FFFB2CCF7BFEFAB3422BC19AB7C5127149941F9C1AB04170AD9E5A197671F136B2F2C4BF4F0B21D9B16D35DEC11CFE0167745787F0C92C252307B342BB12DAF5564516AD3EF3181B521BEB76C3356A13B6DC00B0B9536463E72F5B72676A2BB85BB49E9745CC87851C8C778C90CA1FE86D44D8136C3BB25034B181E7FB551AABE35B3ABA5F96BEFFC090123295B7E846E63D121DB9DB2CABCEC9606CFFE428C7BB3ED76BBD1394D3C632CD7CB2B7A533E506A6CFA69F141186756D3E23CAB8DE30CB62D08346BE31A9B778E4441FEA8D2CBB994C514EDD843648E902F7A6E2BD9FC715D19A6D5526C7B720C2E7752A9FF1693DB76B7FE4F03FA1E18B5F22FBC3997E9D724241B8F0C33F81648C03056D99F3D94590C4340D65BBBAD06F8AA090A8ED237281E4392B853BCBEFA6C1EBE1EB0BF878AFF12D383E9251273F75EE7831186B3A74A93E295503673F26D3B91504CA555020E950DE527EF8CCC1A5D0B7EEBF295ACBF008BE0E46B6A81A3FFC48D3B74B5F34FAF059AAA65D4B3324B9B6E0389DA387AC670357C53970253B76171B59E6D3980CFC62C0267C3E572F4371385AF0719B3752885A1066CBF5C1600AB3DBEA291E0BE9CBB06FD39B5BEFCF9FF9D953A745FE56D5C241C7670B6D89913A732899F0C36242B877907C7C736749A6BC462D875E895796EFE33913B2AD7BAFB93A07D06BEC8AA613A2A4A5937CDDC2BCD504597B79492F00366A29E0BE581C1ED71D2614F4C92490D9A9D4BF43E32DBC5E3A32EB81C6F40143D14948A57DDAE7C777F9CFC3F7F4B397FF2E240147DDE7AC72F9661300BC83E887C3D96FB74785C2D549A1016C638B12248AD5B4CBFA4593F3F8DC65ECE7554C7361201C8214F82DD9CE4279A285091B8CA5072904E56BCA0B9357819438C3C7CF4C37A501AB16344C623DCB4E71A8BF598F31A871A58251DCE6F3BAF5F341AB0BAA5E21CCBB09F52130BFC1B3099ECD91DA824EFCD3CFCDE90414A09A15AAEABD99BD991D888A43DEE1AE8D8CAEA29D916904DBDD6632B8C3550B0B2BAA5AD06371D6093AA18725C345F88A3FB4B7BA1DADCE711C292EFEE8FAF0A86672F3BBC2107C70AFF0C535BE5107F194988A98CAFF84CE790EEB7FCB806EE378A299AFE9CBCA8EB36DE898E114371BC7BA257270ECC127C761E937B8147C328433874A9FCDD8EFD08D111B80FDEB62C977EA4F8800FC77DE54809ADAB4BEC652E743CC868165487E998696FC55A5326379169B868FABAE53C3550EB8E21AF1EADD927B62BEA41AC4F16EE651F2019E25A12FEE6A2C9A61F17BF567B72FD32D3DC5197B4847B8B7A0F77C166150F69C847A8A98DFD192F14559467B57A5C91FE84BD9CA2B55617915B3C5BACF423D4F79CFBFB00ACB37B5BF99C2A6AD319B86F004BFB569CB681347B6A9FA9D1D1EA2DDA71B3EEA66DE8E6605038997B0D63C20A5190ECC8521224BAFD6BD40BC827FE9438C06D3CEF5146262D7456E235F3D643D4B0A29C873D0FD69F98663849BCE83D464483F178116B91777ED37F34B94F20C175A84B6041446A711EAF6381367BAD9E78B03272BB2F6E882F71FAAF51CCEE79A2E8A19704EB5C7703CCDFF88076ACA75BA01FA886D7EA2DD63ED2BC0C1AE633374A37A353EC3645D03B5E650FD0BBF72F714FACC8185F8A1075355219791EAA297EA8E0234C3332544CD64540928C87F4498CC26BE188A2982D639128F3290C11D495EDDE51F26F942563E0F5B7180375519ED7F8CB6D2588812F03E1579CFF46808F6F66D6F4A6B6B6DA6BB7986CA65BA6409FCB059C88F0065D37AF40E0F035E9A1CA46D1FC682718A2EB8AFC1EFC70A72E8057DBC97DD340F43C7EDA96A0713D39A995064DC145216DF14A5AA10F18D42B4CFD43E2ED30054E26AEB1648A71B6F50DB7EBAE7514C5765D69EEA59760CB9A9FC1F724516349676DAF1E5DA679290D3827ACC54CD99577C230CEE8276DDFDACD485070E766098A76FAD35CBEDC6FC8CA084506DBC01F4C80F1C92CDB349422D7ECEE14CEDEE941F055C53C0303D140A8D710244A285CE38333F31CF2F93D3D67BB7B42F99546E91BB66C89DA01E30C214369822D0840FC598EC613724061D28D074E29E82452D04DB474550081D9E9BF581949E87DB10500F1BFC0F118EC0E2BD8898E15740BE4CAF0C1DE99DBE2254975BA7884F314A2EABBD36169322CDDE8CB6419D166AE8EB5EA45ABA08EC2E608FBD4E7BA4B4DF6438C5D90286E8B95089172B975A5BF5CF00BAFA076F85DB79ACBBDBD7A74A3CE3F62F10E658B177AC8A7AE9FC8ECCDDFB05932C84B8A9B4A35ED560D313CC738CC0F21D2ABE89FBE711ACC8ABAFCEB1019630BA0E357D6686A86959A09DBD6850E1C8DBA5E31E8EE826F2433F15A7389A01F1D655A6E30266045396BAD1C43DC0A816F9C2A940541AB7FC0F012BBE4E2094FBCB08BDF31AB5DE962CCD92D876A4A28041067EDE706763235188DF58E18C74EFE3C0DBCBF190EA6186F48E393D2961CE6B848C01BB17191E04734F57D41E4E95E47DBD268E419199EECAFD57B3B97F7AEC98EE3A07B27BE242A9D1C1C59382FC1847E071190AEA2C8CE760D56CBDF3A7D09744B9F6969EC5D2092C14E733CF028D1E09046DD5607DDA5EDABD55D04233E17F50D78595BF16ACDFF44015FBC8BEBAC543556EA13C1954F793FB2440EC674FD582D93E1A68F2F129772CE80DD4248068F853D78A70B66EA043537C72F1405168023DBBA7D50E446EBBC4482F6491A793E4286E12868603E38B0A8FD563007F9BE3FF3B09DCB327AA3E88CEE3D85E25DE06D416F8A1F8BC7D009BE1933981ADC93B7759D15940B3CA8B936F27F2076319B1655178D833FE47D86118A0E6E142300111A4ED69A531FF5FD470233E48D4BC90B8F475C69BFFC62F48F8A4BAFF33770E54D8F51AA5CF8ADA4D485CDC29DBB4027B1D35C42DECF1D0A874A9E074812CE4AC3D3EDC0494285716F62F7C3414B1113057A9373D55DB5C1939BA63B4A48561834B25FA1A2D2F02E3E32CFFDA2D78EA0A15D1F7B8A928C536A9115B7E70A9EB47C46CBBFE67D387647074ECED0AAF66EDBDA8FADA3B4C927B9AE214FE615806892C7125EC1D00F4EB624EE5E8ED825FEEBEDA13D98C977476A0453B40DED69A89046E9AF4E4B909F805A5692D6F4E9425338A50138A76963", + "message": "AD01E3ABF8862531FA9AB236A880738404C34D41D087CFBD6D8C6A873A19CA4CD3F7F56C44F7216E9AF3BAD41DE70C5B8AEA89873751F2A36E28A31AF5C024B56ECF1DB4DCFD6E8D4A8593C22A3EE610A75F475FCF391CF0ACD26AB3856CF42DB5E51203F8B3BAD24958C154429E75D9DB2887E9EDDA9A81D2156897CFB8E60BD9D561A017C2392E48353969BAEF0614693A6B6C78CE0217852AC631E2030782C27B4348B3DF13479400B8F0F120AB98474A9BD73BA9871D1D157F2B0ACE2F01262A8966884D5F0411A61500EB202C0555D00011052DAD4CE2CB9613E325EEAA00A3111E250169485BA005E9F56AE8B4286351F87830A53749AF68F195BBA417900A6AD4D45569A7C97941AA65F7FC4ABC2CCE883C7EB46B78E6748EA832C19D4A6BE0F1B4A5E0F7EC8E772D9B1D1EBD3E11235758EF8270FC1F79B54D553541A7DDC783B43A5BE0832778BFEFB18BF19BC1E4DE73697A11EF952C1085641E644D66DE270EB97E22EF97C0D30171052830FF196BB982A78604D63D335D4A7844FA7931F4D9BBF0B42C9D601BEF7FE82CC8895BFEA819DD7E5BB8E3FF6EABC04FB3B053E99ECDB28BFDC2859701033EE7D5ACDE1D9A2BF44E63CFC28B46EE77B235621E2E67BED8A7A7F52A9D67404E1D432AEEE55DF5B1D2DEBAA777745981275FECD84F208211C4913C134CFDD2080A4737E5C816D69F0DB23FB079826AE3BB422770704B955428F205BBFC0364118F3429E15814C34FCF5D24E575AB03C94D3917B00F613C34288FFA8B66A5FC3197B45C7D4BB81DD2F237D1AD80BEE4227D6B61F935FBC6EBB1759975E7B686A10AA4A359CE8134AF334CABD54CEEAAC205E141EC4707D53A0D2AFE8067501E9E0C1E9B2A80E904BE58A8000B35D415B0F601C6065493C0A6CE2442D2408C583357E1A9629EA0C3CBE7958007ADA45F50FC3F0DBF847580B6803ACA44B5EB54D8AFAEAF952411EF03C04A7BD44A40E19869F8BE946507E10676CE738EA38416636ACA478E3CC849BBD372C7657CF785F4C96DC8CB4FBFA3F73CEB5D6ECCC37587B0F8CBCF35AA0631C40D5408FF1EF2D43C4051190BC65B36997D3843FA0DC8287BC6846ECBC2351B86D492ABF53D75752F577B95EBF14E346797916BC58D0656B849457494212BB8D63D0A59FBC2CD2BE8FED000648171C13B1890F77A0C58912D8D6DC2685E74FF57E0175DB2894DF78E0C771E1E33E4260CAED208208398ED9ABCE349BA5B37601CEE3449A87E6F0E21B17A13F9F34D10D7281EA0BE90ED8C29BFDB22976FA8081F71116C44BB4E2A4E91990E0FC1AC75DE7AB8626456D22D5A7904F6A9BE9FBABF8AD5A6682C8B8F8B82F790BE47052EB584E037296793F4177998D04BDAAD4522575615EF62F9BFB2E2CAF74BE9A7F34950D05604C111159FC50862EC3E72557A427A653B4E7E86DBE4F93B7D33BA20DC850EBE2F28889CBC91636EE9D5A4AB1E472A060A8478580E007F8C5ECEA60333F23790E9909DA54885E9B3A68D875A71570A2436EE131415F84ECDCED121A6440AFB712F1603286C61F41E988E505DCE4E5E8075EB0E2F6367A7ECB909073DA38241F7EA55A9CFD77F0F451D777CBDE408D7D50EC5288502E6C7D9E6DAA77BA61195154B3565A5236C459E7110152A408DC76185AD4E39978C2C4FFBCD3C1D1D805533A1BD4AAC695C835DFEC0122E35C2A622F8C5FCFC4537D295E1CE01A7CA445E833E4BECE6AFC02681A9947069210E1EFC7406627B04947F8EA4F96D8FDE2DF16F2A343C54BE1A285B410190C4C5768E4E5EDFD5BBB488B87BA0AB01D81B67833A5936E0B05C7CDC49C21704BD0F1F39A5D289F761684BA50AE599D09B64EB7245BEA0E4FF1C61D755413D065A939D14704666C38EAD41DA3D36FD1234D11D87C971985A2490800C9617A4A34388DB07F7CEA2B8EBB4E3DE19C5748028F7EFF9E4808F369B94E213FF5178728B5BA0B2B6250924CB020758A734EF07A37F5D0E892FFEE33A922D01F26DBBF30D8B1208CC17FF86067929E363CAC8C995D580BA4486FD9E646CC9B5AC0F9DF4E66A236FFD85DC243AA29487CD624F0448DA108F61A15D31FB108EA93C39299B00F646B3CF10A3A665E25CA2B7F8AEF21606EFD5AA9DEB2C1EF280A12C420796454B7F7C55650A38AFBB2D4DCE7C237BB2BAEB43D06EE780739B19D9485362922F2A1EDA7460AD0149C044921D5EC837CCC9F48FD436C16426F4DD036753F8F34E4BAB97B3F044A64AC07A92D20D74509F802D4147B0DDDBC1D2CBB907F7C2C35317A092AF67B7FA0A3B40B2128336F2ADE4FA29174B0BEEDD5BFE6BEA4FE28A728C1609FF213599AA458D529EBB36C03DB508EA8235506920A0B3E501623F978EDF6D494473A7B5CF7D5F67B52B8E904000CD2AE67069E0D65A7CA7D6041709AD427D2C4B77C00BDFEF5BEB1526C39D478AE9186CEDD90B0CB9C0047E87A42A69748E78C8D51B2A183917C07C759A975FFB2F7B2F807E3CBA460267A1D945F7AFD861AFBE229877061998EA2994520E2062DEC37F5402CA244D9B614C2143B1244055CE84BAF93DBFAECF324AA38956A74F88E58B693805A7E66AB7605825D64BE38EB2EBFA5EA947692DB759AAB08F05FBBA72F78F95B3F340C8E36341A6ED6529DCFB338E5262C27F75201D2B4670C9CEF907468BFF28DFC1413D5C2029BC894BE29F1A795EFE0300FDF7B87474347E25048DFD303847C9F675918C5562BF772D949260C495CD5BF6377ED3C91F5452CD93BEE0A0E91EDD4264AF47B9F43B7FD0C0D7C9C70212E4E42DE74F168A2DA6BC4B8190E19037045E5A62D679B189DE87955DF7C5119E4F24A070D7EE7D37A43B28F943D3C2142EB79CDA655136845504D6CC4D2F69CEB58E5453F6BEEEA139BFB30DFE078EB553E38D6093C72CA477972FC58FB6F758482700D18815F7BB1730A292F5AE1C85CA66824588B2F5B65FDD69EE7906D1DB52A9BB1A8C581BD6281512897E8C81E085A9CC6192490204418D2AA3EC20D02ABA201E778FA12E97C7158F8AB637438A81550E4A308BFC70204ABCBBEFE3EBB8A0C9C1C216033694F3FCED8EBA234FFD481A87D7D870F47BE2347AC5362193B4A34AAD06358CA4082DE7BB2407DEA59B10F2DD83978E024DCFF64EBA0B637CAE21F46D60BE5FF0259E1E66DBBEC37131EF8629B2D0B5A810AA6C6525B1422794C279E8780F952239A4AD39409FADBA351B00FC33F73E280A6C7DF5E09994D3D85F068878F98D31ECB921F1F9C0158DA04CFFBA851A879A4BF2E2064181DB5B95A6FA562D4D0734D58517BA928A1AEC72BE77BCF42A79D2B533D67F2D63B70374B37B14AD884C1709F3E4FFEC3DCE21720F69F885500F11BAA7DE79651028BA8404F760AB8DFCDCB6FC0C033C347994AD3B90561E3B086B1427A1A964021316F7203466D17C5C036687348DBC23385C51437C782620DBB86BC9DC08906364EA89C8277491CBD82AB3B777FAF47335F12F320CC9ED9DDF1F95C531AAA610BADD822800F114688E5E0C6A160540717E9D7383184B40E6138AB93CDD2029E595CABDB76B7210A874487D4DAF0127995C72E55B8F3BDA7894ED9B119A89B00CABBC6B3D9F9CE464F803BFF2C3D5D4AE9B54C68D2CD4A100085C5350D608AC333A412283AFC3ED2200122F313CE2D4E83E721946BDEB4DCD3F1B018CBEE5762835FBD598BD1220B59A83797AA2E01C09E811354D30E12F10D9DF95D07887A5798DD21259EBBDF973BF4A28EDFB27ADD4EC7913645E04FA4754C055B785E0FFC37074A150B50882FC7594522A2984D02F971BB1784A16EE2F22C8616EB96F0712755171CC5644F09DF15E7A4C331C0FB62E0F278DF27514E241F894A6A6745BF0E18547383BFF3EBEA8A4ED5FF82F27B66E07E21560E897BC8AADCC94029942DFBE727C5BD27EBE112487768A329E8F0D8D973FE85419625DE11AB7F91063451E2F20FE873CB54EAEF0362EC24678D641A6DDF848B871FFBCFAB910212CAE485349BC0308E036EA85DFF75954D55D16F13BE3A859B68FDB3229DEBD273A2EA54A8A041F5C6A12244F36AFD793A4299AB8E04B4FD1F9D35769186E1A05852034B78AFE7D7015F73D8BB5A12C0EF9F4A144E343476FE5304808743553A79DDAF162BDD087456D7EFB28BA350241DBCC9E6C16B8DF7682F2881143EAEE111FF8C0B7E307DA9860B7FCC2BACA626E428CF26246739F5D91D4699868E8FD6940B6F21DA344CECD2FE5E0B615704BEC8AF1FA40532FC7111564FCB1D5097D416D113306B6EC5F3CCD46920D84B4C28D863EA2E6296A7B73BCA80903819B13C1F2646AD7FED22A2CD723ABCEA384BA1E677D4CE8CB6FA5D8E931D8E119375F781435913ED3290AD3276D55CF4364A59589233AE01328F683A33E0109A552992DF2EE3348194342A25E6011C1F34917EB3B7E33B3645266477EAA8215CC6933382E49185A4FE113BDD69F337A70742E2654CE72D88BC8760A4883292D01184291DA8135226F6BB9AD57BE7BDB5DAFCAA7D8842E0EFA0DBA646B87C5098F6A7C517A90293A1C06AA82DD6DE6452CE2920E8CB9977D6ABD2204BC512919ED971B3D04A7BDEFBD57616F0298CB1D1176B694A0B3A0AAA881F9387FE6927D76AC1AA98AF8BCE27733C12D6340FF63F5A2EA4ECF9FC50840A636C08935227E84C4B001FBC1BFFCC4853466BCE150DE41826DA265174227AD166A49F58167AC997D0EB41E41E66344506511C6731EABEF2B41F1E1BBFC9379CE42E125034D2A96FBD9DB8C400983744F5E62AABBF5EFF7904D42ABFEA773589BF428C45AB2A2B310CCBC62163B3C6EEDF0882F552F6DF7073CD8A5003B63B83CF1C87C777164D78DB8D928ECF63468F343E66260AF4A6371A036BF8A2F6BEAF5A9594BA42FB2D452E8DEA092DF973DFB63D56C255961953C6CAC2A45B6C06C586C0784342FCBC8B00CBBC24587CF1ECA7B754B9BC356FD2D8D7A6FF862E00DAA232762FD61B971AE712F7C568F22B7DCA58C25C46B8F7FCE05E5EDA17A3AE0881151683FABC356A139B72B422502137A1CEA3342681EFC8C660EC1B85BAB669D72A159A39DD4C6D9CE8EE2681BE5DCC79E484CE0D8522A6BF40613729D25301C1F472801CAB1C368CA0C959289F19279805EDE8BC885E59BA32354613C90E564216C5AAD5F5D257CD41466BDEECD8E49675003828951897AF5875FEF2D987D30C98360183BF9C983E067DD5100DB23021382F9BAC1AFE7818595A728E006E3B166669911D0A1CC610AC43170D30F0F9DB03FF51149E496639430B9075AD34711D8B0600F78D3420894439E58127BB23F9D02FC2818BC62C77611E412AA60A4A91C43EC854EADA0AC680DCEABAB0C7578436468FF7D6455C536AFBD1880AA1662EF4A6587F3F6A30502798C6D819876332A64BDC0C393F381CAE07CF2B2A226F57B504422409FDC01252B9370E620A5B2A16FBBA69F91B2336CA527D0F8C83095E9738D274B18A2E50A5D5275C75F26F2B174BAE338106808778F3AE385E75E78A15ACF0D1256275C53F3B6089A2AC2A688ADB85741D1F0B980A07E7374F6D9C165EDA08A06AF9F69CBFBB529C9E8A9F502AED95FA8C46541E4D5BCB1C0F358081C80F04320C555610C611BA613D58F3C523E66CCFEF5415631C14F5B10ABCAE7A2C9FE5925FB34697BD754EA1A97033431CD5D8ADAFBD11BD9153F542ED139614B353E160AC009AFC841C7D0111B6B70157E2D4A0C161DE1DF08192FAAFCAA43A86606860818B25E176AA1F7DCB124F344E951D915E1C752BC462FBC1F21196938A481350EB05A6757422BD368D9270FC53950C466E3E8299B143762800AA1433D09D004C1E92C95AEB7BCFD0B6267F3A9AFC6C064577309A8421F3B46091E133F3636CFCCD1BF8CF9B51BD9EC906CBB507D6B9E1DE07A74D99DD58076264BCA91A98D771DB771154EE4A1DECB4CA77DC2966291D3B0BCCDAE54873EE60D719A94E725940E2F51B30F3F4FDAAE28C860DBBB8DE7C1DFB1B73D9BA76F6A80549DBF4F0793AC8339507D24708467FA6956C3F2BE3AAB30EA9B7AD2174780CED77FC3B6D5177F8B529AF63917AC7A2B8954E3273D420017549466861FFE1D308995D0EBAFF1", + "rnd": "DAC193E362091E309A9D4E75F9C0F35E21582233045F797FF103AF70BCEA7DFA", + "signature": "3ACF457FE704AD0AB2D5A82A9EBB7D04CA8F75FCCD035D72EA3B7869EDE7909C2FE1761B025D4255C4AE0FCFEA24C049761293FA15F93FE6529349C06C6477D21B05FDB8284DDCA41CCD73D9BA9683965CB4D3888A7E4757EDF1E7C8F5583E4E19783AF6F168C5FD4418EEDF9A7739946BBC0EA95A3CEDBA7C8BF88AB720346FEDEA1938D5985DC4533432B03188AF57C00B276987E7783FFA05D9091D6C4EBE06DE51C538EE1D0935C6BB58FB06B4C9D26A39A9E4520E11D93FE4E522AF70CDBFF228994017599C92770EF758F8BA78F0238CACA1D5A10C77B57784642B6DB6889721AB6A2A9B65EF29E5618763D12D8C28E8918345CE6F07B8E71C174477A6E896046DFE5729110548A9550510E4AD8CB314A88753CD1509CE817ECBC7384198D1B9E141BA815E1DDD016413D90A7936F024164BAC19ABB967F2D195EF943F9D85042781F0615CA169552BAFF6AC83AEE7119D6298172214866FA2491E4FED12154B8EA166BCBD1D3DC84FD8E0473A5608475105F46A84568B361724295FB7291445C3BF3943A27EC5C66E35CA64874831A9427DFCBEB2E76D91C4C7DA1920116C33A41D249B668F30F3C4C683D86E5047B8B19A7EC2DD73D2670A8BCAB3F95FE665BFE5D9FD490E26DCBC753E6A50855060189C066E4695EDFCA623EB2409D51616518A5C711106EFF8B1CE1D924937F940087CE03063FE37417B74A510D0EF889E749778ABC9544014EC5C9EA6E30A9326BDD5ABD99996797693EC3707AFEF0B1060935C31C8995F1EE9FAEA306579F91D060888C57BA7D56B375224314343706B42B4CD0C8D21E8EEAC19F479ED566779AE9C93F5024430A899ADD35374068E5D792C710B6F35B07E9BF7A2B681FC82A5A06BBAD07B2D3B19F591C79E808D99DE67399CCE1146792A762FB2FD9479179DDE4755A7900E195499D2BEB6A8333AF96287793B47A49BADF98B7A5C3002A51039A6F08A8B946ED3E22026FC3C33F0762059F9B4445E67D8E8CE999CAB79404EAA53618230E2CC0563045E961D3ACA75368A0B84E4D281A14DBF2C51C20428D224FE0FB655A9B0C4CE8CFDEACD0E17331B5D872B96D893798247FF6D63A7E4768A1E8FB3FF485776A75FAE12D290B192F1480A4947C6341117068C23AE9EAE798D0A90EE82A2EE83DB8806EC26DDC0B062EE15B2765B68298AFC40E749475F1179DA174396D6338BD908250F854D36552472C4D7CBF4C20E0E2F47CBD421A97ADDF04B3B9BAC818DC9E9F1C8C9F034F5C0A411EB4C26A6660339582D78562C442598FD5B20A8487873A8E7B0265E74238030559A847A47AD7195362D82DD411496ACF0FDB82F289C4B7963F0C69E1D153151EFDA802CE9B247FB4A5F67C966F90D666FFE6E135CEAA70B772E45E68B4D9ABD8FE7F776EADAFEFE2E712E16BD38C67985F6139D95AB3E29FB6BECDDF072E391154FE733D7A7E48AAC0357DEEA547B001D121332C314A418A579AD8FA4345E8192A22751BC86FF0E6A822CE9772993967389FF85643318E40A3A4F8D66889F917E3615F29E9A40468C54D0EAA92389C59745DDD5B71E2184FCA9886D14A82D3D41C662E4B78F652EA08C14DBD6B4332B7E3445C4AE2251B0C40F6D445FF9613FCFB82F8D04261B9DE204FA93F955F94CEA006ED205C172D250BC6DD96821929A54D52C8196D59314181CBADB6F4C2C254CAA7B2C82D98EF8088D88462A2D697DB0DC75C099DA49D0CA63672EF3149DF556B81E4CD6B5EB3950CD8FFF37E94DCA7CEABB31B2795BB396AB8614989E2B787E82B219D55877D5F0583C43B86F2DB64635CEF15AC7BA53052A50AE39239D69EB3B02604E286FE3BF1CE271CECE732B428E54042000AA236ABF8F1D8834A51C5AFFEC3D6C7C273087B667FC69FCF05E5261C77BC7C15B6AEA59411E493C224D825EB89A675DD7F04803EAC12AF3F9C8A1E6C31421BAD74A288A742563E7FA8D88D51945CF13E769962CE7E7CC5BAE81587EFB5D8434FE6495A22133DE0543BCF23BBE48B3596FA88FACC83C7E53C3BF075C350083794649E9650DF5743BF521A120739560399C372B5DB8AF0FA188FA7A7DDE7267B647ACB3A2D4628FF0CF7E563BAB95F200945A58B97CAAB5309989E37366E1F1DEC6BB7BB717D70A7B55539923EC1090941A935C9FFD7FCAA86324DE1849372381BAAC34B01F5E61C38E660432F12FB959225501373D0BF512E88F202BEF42F92107EE6AFBE13EC37110864418C33EBA71A97394BB174953EB22D22C11AC7E3865C185A78A2F17C6134A7833EE5879A17DEE8D46D7573F0710769F7332238C7FC91A1C7AB2FCA97A79762E8B3E56113C0E1200142EB5AA59BB617A27C7626A3FDB3CAC899006E8B78AB6F43F89A8C100260895241BEBD67EF3DE03C3A52E56A58BF65BAB3626EB3BC449340C5FE83B071462E8F579A077FE9A332A9007D20BA429BF6FA8AF03A254C5991B9E6014FAA07C8F5E163296C8CDB48533EE609A771911C0D50171E366A1B9C237FCBB255AC68D7974460CDF50A5ADE6FF9C98313F93CFE3823343FF086979C7FA3804117B7882610EA1532B7BBACFE2C7924D2691157040232226624C2E10E5EE7D9C292C76F6B9207A293C1B17059B0F0CF067ACA10C141E53E5D49C2A3F5ED08548B67B93D073E775CE49D81393FD9140A88BC28E2DD36A9E1BE70F731A8C205F4E5377520C6F6D441380DAA3FDF63D7C3E002DAB0F7A078938C0DD65C7B9F6FB0E43B2D864C669133435E578825DBCEE29A407B826D925CBAAD633CE4ED040D612DA96DF3719DB9BECCBF53B67A6680BA0DB982DEF3DC956DFB7B922483E6C9B308850D24E5716AA891BA8B749265F52C6222DB1968ED9412F593CFEE021B118181340750AF176E080E7F7B3E0CBE0C63F2F2D0942EE8B45531206ECC088D9205CE5D26381F37DC3A96561CD3134BC9B10101D73D2C6D9DCD097C310A52C873BFB46D641663486B062EE5684FB86FE7F61DDD1F7864D4C27D4897671B2FAB2773A41E0E894D47357A3C0C9B7300914C3D32904753CA87DDCE8D663A3B4C8EB0C2563EB9C3F205AC09ECCF85F419731905E0DE587BA0C04D8D9E618AA0A7DFABDC9BB5640E99CE82561A094E4CB6BA66FC4FD9950736BB20F669261304A033B09FD03C0A452D434912AE33CCA5A66EB2BAA3F9CA781F26150D885191BE16FD4A93108343291AD65858A830394A75FD9755BE223A4A6CE69ACAB3C711E96866CBD1812514D4FFAD3436F098DFE7D57F8583C84768A402801E25326C64268556D0ED482CE3409910FDE35FEF751274BB4F719AC8767572C11723A8EBF7D6D7D246453577513CE8F1038505F715F42EBF846E825403D6E20EA5D12454ED1E2747A0F1AF4D99633A91BCF780E49B287CCD3D92E4A0141C0265185D75106406F7CC309EC08CA67C787298839DF87DC84DAC33837C535C70BC59A243ECDF8336FEE32F5118522FA93907BE3C34DCB5B257A54DD76B563F8A62A48D6AA8CA5C83FD4D1CC8161762B0915CE6812541BD9857F16A8F4B13C27EB4CA444437FF9C37284708EE38F15FDBC5247A8884FAAC95D9D5E82C8729C3463D22E794D232010DD26A1EA42604E26D1441146DF451903364ED1319C20B46B4D6849FB40F60DEC81DF061282B8B7E8022BCAC0AA53E51868B5558EC14F0B432A60603A29AEEC168BA38751B8E1FBF586F2A68FD667FEECB6F2FA11D94C49E7BE858A086430E0534955CE3C6C4B0F1FA75F42ED8E094DCB55B5AE4B334E1A94ECA4383538FA4D13A687F1AF3FF0E749416BBC504C05E80853A71FEBB9674FCDB22ABD028D3BA8654B2B5D71BF96D68B9358E14865B43E13F845C53F2F2AF82AE6C4A83C779B60A8EAC75F1DDF7F72F7356F8613FFDBBF8C11151B29474E91078119148EA7D2826E918EE878B10B9A7719955E27694699F2170DE595125A4EED51BC2E78EB1601491BB8584629C88B237AD8148374CFE9EC7C438D65D8BABA450C688B98E83A8830830A6768221D24027F6C932E0C006DA50574FD1BEA29A6F09BFEB5ED25B30AD2363D1C68919DA2D0EAB60C1FB15EDF568F8DB694325BFC5E16C7A4AD74ADC17F5CF4803950F56D5B2EA3605B6002693D2DEE54FC34EE67359E5408FAA05F48E62DEFE4E37E745884C5AD1054C68682A8F47E8BE71C9C4D8571023A9E0908EE02DF074258AA3246B37BEFA957B75DF2A1A45707A0E549FBD3061C6C250290691E7E3898163056D648A954EC8D3FC72522E4AAD76AE2C71B06594BCB377FDA1C16868D6AC3ECA7FEAD8056A5E762909F638D8AFBEED065B411D71B37B23B7AD7D2A1110F2F62785E32823E2C9A63AC14C00D6DB06F7CB985D77AB38A1701EE5D1688CCB53BE12C2F485E33DC7BFDFBB035CD5485E6189F7F4D996F4306DCFEBA0ACEB72DBBAEC07D15F5451C7C25DA027D405F50C1D051ABFD87D3EF9FF3E2BDEB037964A10E22FFE23864557873A8BFBE474AC2F12C032729C5A217435E41D13452470397D3AB01AE279C63253F1F654ACA822D705675924C0D6F273699A190B6E37B7EFC6FAA56A87FEE682EAD8DC4D230CA74A0CD611A3983A9A75B8B64BBAD109A69232980F235E0B7793B770949948C747531D92D2D2C9A5AF8509B44A1B6D1200086C952232674645E5FB7E170DE7B3862C28506B7392B9AB968FFBA569CEAA800156F07F4E6FD14CF2F486CFB289F4079A7F5EB20D8994076F2505879597579675CCD72A67ED19B5FD0AC47D495481732661D2F1B860BBD630C3EF573999287F7DA0993F1B68AEE9CFB124AB043641BDE18A6BAD7A17FA6B32C847ED87E6BD3F80F7B715E9AC2F9523F2019CDBC37CA2F11460886B871CABC6B156840F475366A8CA20ADFD7027029002F6848186AB388B9F374C979141C99D98CA3B28EDF9E6CA4DD5481676CEA525095ED2DF4FBF03D5DD26CAE384A65CBEF049D1848E4B32F8C472C8550334EC0DBA1641EE86325EFEBF7733E5DF9DF93538FF69798D825FEE376412354811C558036654DBD7FAF88F65501B8461680F588781C9AE098B32D1428D446ACD54847935BDEA49B9B8714F5ADFF34A63DBC3EED95CDA2DADE8E1DB4FAD64BA63233E7C2A23FA76A9E603697C3F789A9945F786D300742258FBDD4B48FF24041B82DBFA7F80275FF509B8DC571DD322A51F1E5F8C87A444B2CD0923F44199082429624535CF1EEC044C40E05EBF21B24750F8A8681502FD0C45F4CB7D1E74E26501AD42F4216B7802B24598BD946A1E93BB0EA2EF41A9B3879D6FD15FB450C25BCAFAD93F777E33006AA5375ADE104CA41A93599CCBC07D77B4849BFBDD79B8C02F8AD672F26CEA9BB5EF0B839DE5279C7BB6F1B52FD76C66F03067F078A0CDFAA3D7D3C73BD2EAE745476973E4BEDACAF9131989897FA9EEF30353D8C675E5C394FAFE9528B85F88D69FEB078B2E51D46952E7ABF1044321C0CFBADF522C81D8F182CFE6F9A236DF6399C9E8A78C956341B533062F315E511FCED297FC3E307813D6466340FE1C1DD3E5019B3B3BE98642D2C616B2B6C39CC1D7E0226E810432F2C3E36A4CA521E505DD27093C25E6412E84B90142E9411A9A6869C3F4841202E08B10872489B389613B80D24E6E793492A66EAC7ACAF36D982412F45E8F646D596DBEDC5E3A2A4806CE94F253717317B07B56B3ABEB2EA88F7191733298F17EAD44DDEA72B3512DEB79ABEE10738F3F7599D119925BF992637FFFDCAE9E852920DB9F9EFDD8287D19674329A967D1482F6EFD9D1D280635648F6A6E0DBF15D63B29E369BEE976496BEDB3BEF1330EDE318D7254127850C1F6D78C26E017CD212699DDA4CC3E081D7F60E68F76827262D2B7DC033B03123B4DF9835F8A7700CD171BCA68861C76A1E12A88668507EEBBB995CC59EE569A3B316E1ABBE8B628D7067D290515E50CA5DFF0B3E9F27CE6EEC097DA7E8CD4B52AC50D96250F92F946187A326238F17FEF842262045F8CF3FB6A51CD7C259892ADDC865A9D33D3096E1DDFB3DDE1DA1114D0335915C67008DCBC75DEEC2AB7593F44D26F840F94FA221402E3566F11A89081E7D87F4FE56D58C65FFCCE1BB149F3D0EC653ED45FD8A7B604DD94289D440FFC61581021C4BD9E6307B1FA2D1E2A9DFFDCE0907090705F3507DD9B8E2D4DEA44727630C51186E5564190A24F9E582AB3B72608CA57D66C61BA0FA0A188651249BCDB7A98FF15F6DABE4196C9CA725FA99D33AE7837DA4D258F76E87459423DCFACA5ECE7A5DDE57CC4B5DA9C2598351D5139FC9FCA0BA3DEA071A3EA5FF82A901F4E83AF628EED0EC51DB28C5C274272F4AC0EFE6A3C5C8C5E96D9399E6C414AAE650B46C00FAF61EF8B56DE33593738D8E23610E4325BE41D2D37E4F034C8FFA442E0A49AEB2FE81673A3A1B80D98ACDAA804CD3C3E9CC12B41BD8D92C69797B7CF0FD141556626D894E5663D5FA08157071A0A65C6C797E89A7E9383A607CB6B9BDE4E638B0B5BAC32E4993F10000000000000000000000000000000000000000000000000000070D12181F282D31" + }, + { + "tcId": 60, + "deferred": false, + "sk": "0CDB4AACB50813772D9F13961B5F51018335EBEE1BB801A0E8A0832E901077C302B0765110E4D4E6AC3653CECACDC2EEA6403F2918B2E7683B4508702A1CAB340F1AAC24A537DC044B7A7651DC8D222839F41F88D8A82667D8AE36815108BAEE95E01EAFF181BE89E15ADA2CCC1393FDFC696E0B2682706D5F4A1CB69E68D87124320E993872CA24709AA22D4BA291E3340D18164214896CDC38910344880CB28523C62D59080504456A19178C44362AD4C289E23849220866C8286C149380134051209425E1844463908C58866424B311E4042012340D12474DD2A62490340E44189194042E14080501C2448B26225A04484C8070D88401CB0249C810050C42521A2889CC081111C89119060812192000480E80489204C421C9248A6104651BC28121172EE1B211913609C9283183348E4200269984691C90714CC46564B2254AC48D1B072904826923C92C1B35244C1465C0888DDBC441D94825C1865012B84042C8200434041B4565C41006E1324811936DA2267000040E9B400690146800B5098B362E1B932D63981120185214212C5B04511C9729032090E3A84DD3885098226264902D204551D1C62C84268D0C258D80123002408E21334ED948084996011CC1891110085AA44D60042C9192611B032AE1166103A10C12A28C82C00942B8485CC244124421E3204CE32261C000715AB011A4B2891B85908C164061222CCC88815CB8480C256804A48C21026C91204560864101318C22124148A265A00092031582C106708B986862404C1BC40989862520C300010264C1420240142008038822478E9C8020D402814B1860994601C82224240571CAB85090A8088030911CA81142B80960A804CA264519866C1A816C90262EA208014C062ED3262699348C149481CB2462C0A8240CB62D42B88D18B829D488108116218C222A18B30C84C82D88C424C38268A4B48082A63114991012930104410044368C8A144981B2100B3000A3068959488893246122C82D5800699280241B006992A671500885004348049464DC80856320844CB20124312691A44061A425C1C261223012A3800C59301201C02C59340243048522C681D0140C501642431890C93402C1C66D8A160E11824103A264D9988914B16891984014A44C1028125C04814B424D12372E5CB07083208A9B226423C5600B362E833425098949584465030505223321C9B41081924D83026ADB364153C0618C3089D8B489048665214124A1B0699088810C4785E22030831080112308E1340D4B3201919848D184655190091A02029808115AC805D1862C0130484B10102130299C882180125243342419944CA03488083342C230690CA811230986A4C02814043102B20DC0184A844805E4464A41304A61C404928441D23269CC98004C964008396D5AB28941224E22124DCA4281042201134810D3204C9AC6259322064C26901A4604D4A2041A34681236801933009BC401D4922510213119108AE114261B316CCAB6715A200DA246284AA250C344311A45500943080CC62D21034908216803C751E49601D1267091084814064494B825CAC64D04B140D04060C3024900272504C880E00445033402403084E100709C222A03008DC8266C18846524C410142130CA4645513264D844068BB62D984889CC046513326C981204E3264908C561C8B44864A80C882089183785CB804D58B648D2168C94C8610B1560E2C0901017928AA40854B6084C4026C2162AA4246D51A40450A6101A3901D4806002B08104B500C006429C3625D840059A000810A328C0022101372D1A342E00272A41807020C02511B241DBC69199342EE3262C140666D3B00951C08409A02CD20020C9000ECAA20D0C88908CC2608C140C1A27881AA81063A085994690E3426DC8366940080D22A66194322513A94C9986008C265288B065CA48604A208208B1510B414651364981428293A049800044C4C8515AC611401045A08225A4242E8BB24012108E1A241291320501C865D0B6318C92211A4286A3348614166C12C10D049269214241C0A488DB380C91C42D8B246852444A0A4745C9201110324620940D5A20629A224AD0246409C8481C416063202460040C01C54082044CA30650A4C2804B184DC1446E1AB265D3148924394203A05021040D08058E1A1220490625A1186D0A211099A82562120E11B900CC240420A269E4860C5E324BB1C1AFD2EF43693324DCC483AB792B3D96E6B304D0222791D25CE8932BE83F480CBAA06CFB19C34D0B35927068ACCE2C8BEF8C8A923BC909137C869D424A09D29316F523A471FAEA4430CFB62B23F5A2A2831891BACBE4F2AF9A7F54311B174516FB251D43AB3DD76CC90E5D1F8519C0DB6C257E528E2F2012250F167338AA71F5CB2EDD3C06C9C44F6D5703742C802F3EBEA338F7788ABB53F78D80E36FDB09D03562CE51DF3C9B57D7A51DA38413F40311586600B33549DBBA8C8DFD5324CC5FFE16F97E5454D220F6B2D9FCA26D3D389268F28786A404594224E96B1571318EE7F27D3D9DEEEACAC882C38CFA1D90341A63ACED680E766CD4870F5CE929F551FF98B52E8162DE2A5529048812D1E590D0CC519018FF6B45ED47D4BE3515166B16A428CA56388EDD01B6F56A1FF2FC8E6729BD85E01085E33A12E27DF69E9E0D7218FCD71F105978F4F23E7A143A0FED7FDB510309C951FA85E666DAF2E336B94C47C5DBF08DE47CF2CF7EF30C9E3D667BF7E434FD1557855F5381FFB3296A409BC43092E9EC00D31A11092F63888B169B140FD845A728D6B659D39A30D8D37DAA815D697074DCFCAF69DE9085965D22ABBD711DAC1FD3CAD066DFCE629D79903C9AD6C1C173C0A909C6048601142F316C2A3580F65A8D96F546CC3E2AD915001BF6C66F12D415F303860D704A8FEDBB4B1127465D8427CB2D5C2845762EF33063900168DAAFDD1F8F06248A4D3848B5065FBE346905B5C96965D8535A22F22BA1FB2CBD4EE244B16A662B8352185A5F070DDE1EB0A9D72853643F7FDEBCE113B7120510F4C0303F0ACF9DC7C6D4E99841879701ADF806F38A798B50ADBF2B0AD42E8112A21B1FE90B4E93A1CEB6D953BBB19ED150EFF5235ED488F6DB7AD6A6C690FFA153B5670905B3FC09975D2A1EEEDAF44FBDF46B7E267BE0AAE8B94FB7843C5E31B4B3BA3CD6563BE68AA7BBA64E0C892CF7A791E4D5F6D2C434E082AC0B95922C303A13495E8047A8400B171C8CC7D7D61FB858799B09E315473005813554B94F8A0C4989EE8412A9225CC9140C1E4B706FC070D37E62D38B3055DCF1F2B26D84E373498C1A9C900DB1D556BC585C440D8AFAF057967DCD4A2BE1420F9A2331AF1C64FB25B79059792B3E8A69B0F1B33CB9EC3A9EF30CA1A4B75819FBF05071753957185274BA1535665C26B1E3C93BD27BAF47F705AF0DE5799A223DBE1B3D1F0444F1CE5D8F67F71FBC97FBCEB8AE8143634999E3C8B7C3D8D2D613D96CF8AA3ADB3DBDBFBB982F5863DE70B654B21C64C6E992EF1B1F0CA3821AE6904582B763FBB08422281C54DAD924BC8B2BFE14C87EA97A93E86D2E841C81FAEE5D6EFA35C049B58E74A06DFADB300D78DDE9FA06A26D1EC64FE20D5FB47BD7E56B999D21DC0BB85DEC6C1814A27640B8FE49EFB84C3D8A94185D82CE3DA91471870A62CF411686AEA06C4FC789FF5F0C2A37929D29952393C8C997BA86830B9BC26AAE9410D28E81F9DA87A3FDAD8B9459741D7D134BBDD297A22A4D9DFD157280586EFA73E2E77EE5A957BECFE8F01ACEF9E0E41EAC197EDB02071096307B8DA63C89BF8F56A14E094FA955FBD4B60EF4C704AF5B4C970B1C0C580ECD1B0764025655C20757E6B863F631151D64007A481672700357F49F57D551E3C72C2101BFF3F788FE00DFE3C8BC6A8CEE46A1B8EEA226E8327E4C872174D78ADE31CBEC003CB0A916B7514974A2FF5FF5E75066F33D74728B076F2DB0AD0C44085724525EDB1A0D9205D4873C9D0292110B9493ED361A33134B8EF16F54FF788ACE7CDE2DD26867330B87F47B5558855052C002E2EAB725D7508533B12239AA4DD3BFA64B09F7127AC953C28627CF2F4723898C02F9AD19FF790519064888CB84AABDAC48FDE34231546D42A337F38D3B11CB7EE1A42590584BBD75266F2E884E5C2553DD7A5684F1E94AECFA4716DD2E84ABC468C73B5C90D8FCBDA658F8D3E4676F126E4B7FA292D0391A6A53FFD3815D0A1CF5D6D58FC65F2E42EFAFE2EC38DABFF171643452B6AE1E5D79E4998CECB57C4C81C15548970C9F33536E846083E5BF6B9DDC803A57988978315D2B7FC74A2D87D5A635FAB415922EAC1EFD08A302812EB0CF3571DF982AE6546D35BE5844E110AE3C83530FAB2E80608082E9AA6F2E32B05DA5D7A99B7FFD6D87FC0183EF22347745840392218516B58A074EC5B8A3B28454D560011BF57E2D19175916FE6ABCC3A9196522C6C6D36DD39772F1246CB545432CA046C460A1070A65E8EFADB3B06ABD379D5BBDC0D359D20CFFB39A07D0905CE7B9C0E20D8E19EB0C630E16AA717FB66166223927DBB0E76E3F399AB813558F83DA52616D430D41DDC8A7ED70DD5B54F9BA13B5B29DB051558271BB8CBA9D01EAD2567672864A7400481799F0B06E832D0BC7D78640C78DECC70D5412F83037468D4ACC8C7809F54C5FA6FF73CE146A522A91A1A89DD44A6EE280CB85C43AAB4DDD09E25295E030D5FC66C2B48ECED1C32CC554DC69E97DFD3EF378FC099DE452AD76F67200018D180C2DFAB8550378F43DF30F605D25332DD5DEB554C934D7F1DD2FAF1E3EBE5545D38259D9FD441E6F9524327CE6F868498B1E13D98025162574E2F7DA8D8003C3779BA0134FBCA08A7E10282F0DBF480AD30AD669C5768F2EDDE0DDC17FE97FB7FD724A74C2FC0D19AB5EBBF762F708EEC805FE13F95E5CC8B9F87F18D9219FDA0895BBBCBD17397C130BAADC4752C575EDDC37DBBCBFAF9A894B90F02E2E1B7645F64350857BC9B11776B40B4F6BE8AE4779D2D68C69CE207A4FABEDD687E87502EE15E301409439439BD23306B76CD98F22F05DADC5422B84A1FD0CD6ECFCD9F53DB6DFB7FFA8ED87887C6060557FC7A664A6CA09B7D85790BB34482728ADEC89B1D3088A1D315FB30639F6BCC2B3E0AB571AD624BBB6D05DECDD8A1E3CDC29EEAA5F7A2FCF9A9A122FBAC8F5C9FE3F8A80E5F45F972CE575915DEACD097606479668142EAF15F7507DB1F0FEF8C1A7A8862B7842D2B018798675C0C192DFD599A27E8CBC01483AAE21E73828FBE25A5D841E402E46E310244C6088185BB9ABAA76020C18BDD33CDE7976A33635290694E60983BCA35D2742F6C3DAE63AD5C2A81B87151D9F9C0888A0225D909518B2B4A23F3D4EBA16097A18DAB083AD4203F0BCDFE9F7FD9A6DE4DBBE3BB52CB23F2E12AFB9E68C5098F14FEE38C81D768630FE51DBC843E9AEA80CDC199F7655FE5172BBF8E0E1F3D5337DDA45F0E8A5BF4F09A934323689D8897BC4403A0869070B25324C600F03947529B259D9F3BCFB951F5A397456A19CA32FBF6AA949D87021D5724BD7A49CAD6E3FF455211DD4E93852338D2BD2CA92AD4B29137215547FB57ABE65B7ED1A5D4D76CA893B48D18522EC84459F9524654EF2649144A662DB0AFA7925C134EAF87DDBC3F2E614F77B7EF25FE55639AE9563EA7A438B6DCC61AAAAF9E2852735DC7FA8322CAFB0B8B626384CADB5A91E83F291C63F07295E8B8302A9E6827CEE130A0A6C1E0FB695FCC411B38512F035FFE522F8DCD2E2E092CB0C6CC2B0BF8A975DD14DABD03D332EB6805CA392AF97A6D43C684BBAF73607D5A34A036835406D72D528D0F42D96F04231425DF1F8F58E1BF79D2C25ACCFCF63FB6974B867CCD0E2ACA54929D44EFC8CE8EAA2592A49533CED723FD5BFD73BECFB5048864F8526A3529994A979209DA05C0EDDFD3D69941B4C109465D167F780BC10A7BC93FCE8CD8A6EE414ECE2020EB0F1150630FB9FEE8E45FC8B68050981AB885EEDC5027F0C546398A456B38E72968279DCB81BCF205D5539C503A2CC246D36F4A7464C67973A38D48AD935C3FD0D6946AF7D7EBA58217E03058CB88685861C04E3A0DF5017006397F3D3823CAB0BF29A7937311BA55F17A50BB64FE35C7BA700EB23F9838394D719CA2A9C46989D667BDB0BAED2D010A21FFF8D072EAFCCE4905D9B7CDF70838DC18AF4B1812EC0BF1453D731E482E0CB86A38196A20961D0B96E12F4F27C7BB2F1AAB70CE0361C62DA4121D9791E9C2853C635A649217E06BA5D7B89272E13CAF9C5EF26F15A1C98280A36380C6D7C1EF9C8E7FE571BBF14B2BC08085C629E6A1A59C5911B02403593B8665AEF34F611CA87834B8EFE0A853ABF1186293C9244EAC56001E457B684CAC67CF172BF8F9B25D87927DF2206DFB7F032850E1B1AAF1D18A62F763FC369808993637FFE29A7D7605ECF9083948A4561D2051C11402DA25C26F6C60B156E8E533300E7C14EA530761032A6B36C7C3D79FA82C3035F300EB9B663A35D3D01218DE9BB45DA8D69511E3587B38602E81DF397D3AE33CBF5526928F7AE78C6E635507D295DA7CA15AAE276AB20B56CA3A491B8B3154EC810B84B97BAA9B8F86884B37362369C4AADF707905D9B730CC8A6D4BCDBABD995FAE9189AB0148B815411999CDCBF4D0BA60407DBC979E2E97132BA2167A631F8A98C8876B18419AF0920D49CABB1BE0E74D24D0297DED9650B81AB70A91953B9995F1E48619B806289C4DC1CD9D44E86479EFE86FE0B8D7EFCDF9FE2625CFC84FF7CED422D8024BCB302F14EDEAF25D1841AC76AACE19EDBA4F0C516C297FBAA398089890AA3AE42A8361BC16EB84A795491CE937622B0105D1E6672B17382FC60F8404E399610F9122D9EDF6AD06ECE7CCAFBCF502A", + "message": "5B33CFAD9E1F3FDFD71F676AE23A6B1667E9BA1E8F88E3698F3870054DFF752507852801D8940D2712FE057B474EE2FB7053780DC7D3158435A742AB4751DDDD9BAEB9C435DB69E0F681F1A50C1811D1E3B7562BDC11D4C1495EDD417503A803A31294581FC5B2C77E551E9B945FE212E9B7AFEF5581EF3007D88AE8A2E736141D8605EF2BFA8892A6ACADCB41DB9AD4467F29AB18C58AA801BF53A85859732C215F772E3328921363C7B5DF2AF0EF5A81E2411513577494B43817BD0DEC5A5C8CD7BB30351BB687953D028C5A3EE1187D6094B2B5FF03DC90AD4AEAB0285066540F1E0B096DBB1695F71517340441FF23C8E65E52AF6BAAE3C59EF1314C7EAB5436919C3E05E163BFE76221AAE7A22F9E7C372FD3A59DE6AB5C11EAD17AFDF718C0FED633E07B5BF8B903EF951707F4B0706B2F44976B530DC57CB960D91DC2D6F738B2DC529F09AB7CC63EF9AAAB271671C4EF3CD3EF5072DB28D2EA26D7BFF8FC99403F1E66755FA80334E7DD2E359766E0379815BF703777D042C7FEB2AEB0AE1C28DF438EF6A95D05FB4427C8421DEFD19CD5876D15247983CD140FD264A4475BB0204C256902B5BF062BE3EABB44E4519A6356F60B5E3C7405AD91AC686430DF2EE20D276E8935F3CB93CC52987E305EC177379484763DBD47BAAE9FF68152D27D7C69ECA3A6C9D1F8DA6C491C842EB44C872DBB37AD5C97CEB0CD375B2DCD37DCE8D6C7337CE5EE336E42E00D0C6E15F20ACCC3B82FBB54449C688994FC403ABB79558A9A21BE184BE6EAF201A033373A62339B6789B1327270E8F19531D51E6043814143A87726A5344D6A612DC42D8DFEBA6A1AA07E3DBB99321147634C98504C1FC6CEC135F4CC4E3CE5C66CCBA5823055E1C9256A800A5003799D4474E11A13D62DD2475DE3DF838F8421888DBE13D056BB4566AB277AF20E2CA415785CD35D6D532BDE75D9EC9A48754CE472187CA88F16A0473F8767020C47204A7D28F8DC6994A00967A2E6F70384EE1329863A2F76223E71383CF10E5D92815BD0F01F3788766BAD47F2CBCD87D9843196C4958DA3F13A9D608152D541E7FB326F6ED088B684D7BE14DD20B0C09EF28A1233F559C5F0CAA178D5BC5F347F8A67A38B6B7A6496648B1D5A7E6D93B2731CE18654CC4F9EBEDBE8351F1A10F518924BB36334BAD31166FF45F883CCB2D697F0CD554D11D61B06C0264E75FD63D115DD4A206A4964E936D466A36BA57E0236AB1C7EE20BF6DC6C1EAD98A40AE5CDA2B09D01CEE982B36FAF6143EE433AB358CB585BCA0681B3DF180AECFDD399971755E6A558D7CD8F06E78463BED5F5760AAA6C3EA1FD228855F5D89C78889AF3121F19E4B9445EC409FA58ED8ED6A9B8B5837598C7ACB7303AA0E9B69CD7895FD4133A678DABF9804333EA592E5C283FAC757402E86F074D87A78FB3C4A1F7F453874AB716552D29855D08CEF93FD8C954AE5794CCDCE61FCA50BDBBD47FDD4B01E49806267CEE040940DFCE8ED29E44626433A2EDF9D8EC8D713404593669642C96A097843A2E8751458DA4C87390FF5516F23EE30AE2A17B1C4155043F4996E4A7421ED1F35B54A217ADCF9A5409CEC63844A2CD4E0C6FB5718BDF8FD09EFE1428F8D142563799B9BF8DF079971307FCD126A23E5DBFDD798575098D14142F072667AE5B05A0ECDB83008C2C86F52B7A19F4A400A6257BD654D7E243131DB94CB9766EC38E20F075274964D995325168B91CAACE60E97E952A3C7CF6151324E7DA225FD75DE497C3C204EA24BBA613D1CDF8573704946E194ECCA725E4B37A116E1F80A8031F601154AF62CF03CC62D26260A98F2593075ACB63F6BEF5EB7324D4EEF11D78753177877DCA0CEE397C458A9D1157D84E00603DF81E3596E88E1FBC51088012ED7073B781DD25F34553E9988DA7840A2F76DC6E040AE8E8E9F965A3BE51422315D332221B864E2A6E6448E1071E904E31DD0D932B95E51F928F3ED00894588D35F0B71EF5B5E83D090804EA297B7728CA6E3716DF7713CCF127D703C45833724E725C7F465ABC68F3ED0A3F62D7466A9202283C06A7FF916FFD78B21EDB2A144766C170E50A2AF2AA3EBDDF0983CA6AD9F6DFEE6D7BD910E24289714D66A7B1CC14C22D41206072F195B7E0B7E2D3F96FC518C58DF7280A930390457D1C88611E75C1DD7C3930F2BC6DE595856D137387078DD6C8C6268EF13F6771121CDFD72B3D4DCB555B01FC9CE18BB4851949FA74A3615DF3B49E6C4017387E36CCD448216BAFCF688816E965808A673267A529BD9D3EE6640143DB0CB5536B44667D2749BE1B2B430798B38AC65E368FAB2194837DE4B4F31D063C97F3D6003BA0AFC3B71A1253FB29A7A15131046A3DDBCEE2B68F0CF42A34415C121655EAA9EAE58E309C115E8ED7248F710EE835791852EDDE7FEA212FE060C879A02B1FB919B03A677E8390C8AC62A1B13BD58AFDBAFC3D360E0359244C0DB32CD90AF078D5CB4699E5F0765689FBE1D90F6D3C948CA28391A4F4855F491F57F4D919C38E3CB01E7869169F3E8EE22B9363A344A4018D469D992C29F444B0B0842F0438B48F457D53113E21D23F1CBECDE8C910F9A486F911CD53D4B90430B68BE9DE5B4CB0145D749DE92AFB9F14F06DE52D24FA3B99638A51E8C8ECBA1A3C3C39C0E7308AA3FB0DC44C9308114BFA963F8ED3416DF04CD00FE5F0AB2121C031F13C4699AA30FBB96F92EB886A73704294EA0D7B4B2E79805A9161855D6AA0AFD4FE7B818D8F804D091F6FE670A762706B4D16C1D0952F6DBDD4292B7E05D8DF795C2FCDE4DB90ABACDE117B9B375484BCDF8B364A190B04CC5F5D1D3B2C2C1A9B0B1EC52C1F50F68461DBDC9AFCCD1BF16557AB2074EA97215BEC34D2140C87BBAB77685246EA148AABAA34B02D60B894303148B3E8C61374700C1634DBA22E958B0AFAB5614B23AE0B93E6875F072E71210F7542A212C5A62CCA9E6A98201E913193B85CD2DAA4A574EBC6AE6C3F3E0E76AE54F93460294366CD8F05F19799D24153C79D16A5207509A9A2CC562C73BBD08F0231F260E5F831CE01F24FAE4F17B71CDAE0FB0F9D78DF475A19585B1268BFDEB440AF50EF1C33C2ADB41EFFBD63C2FB276894329A84CFB182E17C18BBDF8320F20D111212DF856F1396936D2A6229D631143A9588B1ECC552C130748B465941214862E63AF40F62FE1CE4874A2173B256085E1520A46854F44C062242838BF81DDE8F9D157FDF90295B3AF006E01259E472F7173E771FB0E67766198539BD380DEB675D7A57254E1F9D8C3F554ECB5B668C5B00BB99E3853B09F43ACEFE2EB69B903FD13B78E54073B3B121FC5ABADAB13518B3EF59C84DBCA3D560979802D0BE899A10297D907E3F4B5984E69F2811698CD3D0CFEC4036A0694ECCF7258BCC3898C1256C24668505E8A0308F68B60B6FCD8523653A6980AF073490029667E07CE8EC9DAB97DEEFAF380B386DEF3DD5F951625E0507B425356CBC4B1416BD11210D1FCC3DAF5CD12C8B2B195F9EEC6B5248A6C0A788ED9BB42A4D07690B7ADA526AD7595B8F1DA01109E7F3A3694F827425568EF1107BF8677A5C5B506DDB137FCE83AF216091A9D798D02380551610869D75441FF9A9D51AF8BAEC38F538E12D6748BA7AD620E96A76889AE596F121679451894F087BC789FE85424AFB1F6033B6B971767EA5D726C54D9AC132D3A03A04E858566B97E6D9BE3820AD47AEB7104ACDB9362C254FECA7F4E7EF5586C11E3389F8B330AB006FEF9D9BCD927E1BAC3CEF48F4F2D3C4FD9B88016C07D5775A06B22C635BF30093C2AB09F022EB74A861EEC5CCE1C8D160EC53A7303EC31BF98EBEB907277C9B01BC29BDC333B05142B83F3023CF0518BFBA53DFF6F5BDBD7F6F3DA1732E2DE8911294D2F9888BB3CC4A9CEDFB438A372F31E7350F0EAD958E23454FE77D9BDFA63B73AE06344AA7EF63EEA48A4BE0C5BE251E0F0ED42305C09B07432F7B17BAEE2739DC08495C4D40F50933136E30956775CAFF378906E0177BF763828A9DF9960112BBE1483A8924569814B43B80B7FE89CECD75ADBC00E31A2442D281A3D90ABE6E94252F1F354240ADF38AEAFA3CBEC9E52664A8B8059538EB007D7DC9D24A23FFAF773F81E3B032762DB25238CE1BA2BF9B53EEFD0A6DE5D3A713D068B96D6046C3B816DE7E65391461B226EA69DFFED0E536373290E6B7C655BDE71DC59329539DBB18CCEC87F6D2867EE3C1343B918E3095FBE2C1FD01DB8503657438BF9344745A26FA6E2F66E118F83091C23CC9BB311FDC58D89DAEC4B687FB53690ECBB610A6FEFDF6C3AD0DEDD4806FC1B8628056CE830375A3EB72581CBE1C3C54B59968F24A25BD208AB42252FBC31006E074A338A71EA833A85ACBBB1D8077D05FE9989076A22C06B9FDED2B371EFDB72E769D36EC9C3D4D29DE94762B761D77DF5970F97B3E7C7EAA90D4E46CD1123DD1F7313BF8572AD0E213CEF320D7968DE259FC4A5BCEAE5FB1958D176D2060F8D2B54EC204FFD1DCA4CBC8299E2E1338A74104CDC9E4F21FB9363AC934CE9CAA3C6C2134103ECFE626C62F4EEE6896EC5FC2E509CB9D65F3EA5E00D4E6F8A2D319B692341A73FA8D4BD06A2ED8DD7EBA0A21C1D7A1B661CFA13CA80BCB1BB691F5072B6C23A00D219987BF2C6C062F9269CCEF9D8998DA4523B5D4289494140BFCD735076FE887F9BE4B6F7CFB858476643C9FE026B3692A0F9A54AA9ACC6D0903BBB1F17C93CF09AC1651F2C3EAE0785F6EF4019E18C7AEC9B29B3EF1330F0F3E3366DBFDE4E5593E3EF8ED6232DDABD946DDAADBAB3C6A97AFD661ED0E48A404B325A095BABF3D18D0ADDB825E5EA014894D39D714C363D3FB96BC22FD2AEC197A4CC0D2F1342680B5BE9F0F10662D6CF85F17FA611F5074F892C9E13FF3D770BCECE88CCA9973A0479BF764375C65C577FC15D49AA80563D88B6B65D46E1BAC22D76B762BA4680E34B1A36782290064F79E4F5BA0F9472862143032A7A852EA03798D38C05D63C657B5CEE1D1687709BE130D27581F26B00F2CD38F6BBFC4039374CFFA32BE7704C5A87AC7AA565536A39CF26CABE65FD374C0F63861296ED27C7838269E1BA5B07FB90DB8F29B71056535B8DA91417CCC9B6E16D86EF7BDD2606D621B5CBA6B5B7684AD27B2FB418A9965301FFBCF3FDF9494E109771C352DE1BFB334250A6A9555B4A9D12010607D788DF4A4259F9214A18826C750C00F1F55CE381378B9178E0955BE8EE3E067BA5B31CA873C8BFB19D32CED3D9873EB14428DB288CBBCAF4214312F20B865418FC5BE3A3BD452AD085603D028FC2CBF387677F424702D79966D9FD9E993511DA354EA6958AC618B37B222B544531DE2EE1AC272D509957A2F17E79D608A5F2A0B482345DF1ADAFAE84DFDBAEA5D907D0B006348BE5D65C79AC98432A649D8356C0C12D5D128E2526380CF3AD03043B44A8DE739BFCC371E1DF56DC16C3D7BB788CEEA2E11DA0BF2392315F67B82BC078BF07022016103573B24AFDD1A1C7578764BBD8C37CFA4BAB0E99AC3247343CDD287DEE2B6F203455B22FDB695BBDBD4E63969BF4F8F8F6AD2261405A65F7A38DA4599F5F15CB1E00A0C1CC63977E1C4EE41229EAB1D126B7DCF3E68D20D5177E8372E7680C91608D715DC61FB0C3A108FE613F8D6636F09BB19BF076489F5E76E17D3738870AB0139F8011B27CD853CD7A2F1C7F5C08EBCAAB6E72BCA4F01D830042F804911B380AE08B8651F1AC0A2458A57666126EB9D981C843CF15A09F25E2036E770CBC62E0953EEE15D27D82FF3D886D4415FF866EB9F4B1040BDD49DE9168CF849B37BCC5F99C65A8DD63DE42CC5F9C5F7F308EA18809AEB9725C7CFAE7BB79B0B05F4ED9E7DC84A4A11E6858BE336078C8218A1B197FD3EA11A4927E3106C745CC9C763CC86480F95BA8216BE3B06E14DABE01AEF1464D268C173E78D5D04CD27A5C191C483B36D9C07B6166A66FF1501D784E8DE93191E5B8BE680F3E5174BD0ED7CBE5007B8D293BFAE0933C05E4F4167CCA5A8D5BBA46312997D55462C4B10E9D6C8B6417CCD7D2DBD9A387D31F4083CC620302834A6B633FFCDD435FF5059E78664B4678C0887FDCEDC7B71D863E06DB355978532974D8A2F434904CA4B0A390B10E11162BB925EA563C08131E67649D29F810A8965F7677516221F662D608E5EAD584EADB20D346021EA2AFFC3A15262B0322BD969E6645F8FC36FF0F27F908DBF44D339D8FA04CA5A7370C956F739851311E6BEED4DA3809126A8B6D88FD392B481F6FC27657497F019260C67F586377A477FC611440EB541FA9F4C91F4E38180D8BEDC2EB4CD92D7F803FC03E57B30733AABBC10536A725D24B0F4F84C8FF3152AF1E225F971260390197CB76CDAF2EE979821E8F9AB71BAE4D69FDAD022F174BA68DDD769C70C5B94B5BCC5255734C48BC41A3D04AE7E07C94CED06CCBAB84CDEA10EA09F7DB2B2D6269777B33B07D1DC6C95886ED016C9097C551C79E2812B2D6F002C291131204D890D1B7887841F6867E84EE6E5BCDFCE38B1D09E003BE34110FF375A7038C5BB7B6E2BB0E501BB4DF41CB5C6C33B2CA75B9C62D6EC9CBCB4BD007A42D213851CAF112211633B6B9A88BD3BBCF0A1428A41096EF65574CD9E808FEB509C430B2FD9A56805C66DB1CA92B74BBA3B3C43A9511686DD435FC21717E97F1505FE51D37776F9344A93A1C8E7B255188CE48700A4F14EED1783A6D2DAB3986736987CE8CFD79EC23DE89A9F049D60E9329DCAB050B6AE82E621AB1639361CE532A566489B87B55794D8B65273350FC29ADF09F798CB0D9CE01770852E339AF33A0ED41460FAC83B94637B5E528E9A56A6DA4AD32A57F307B9C64263C349BB103609E10D8BB69CE4B2334E8CD3C762237B33CEEA43D1FC1C1C60CAFCDF7B6FE2F04F25B5B2168974C48EA527730F6884C321DF322BAB5F5BBE9423152B6072585AC29C3B4B26455B65FA95A32DBBB03F76F55D51D3CAA58D8B70DBF871EF6F5A31D2E2244FDE792073B2FCD139EACC998C94049ABAA42A3DE6EC1AC546B90E61CBCE8EF9553DD47B9018F5FE078C79A53622B17F503A29C0CC376124590A3969B1035DB29002BB3E1455D5E364F774481174CF8022BF6528811EFC107BE9D065FC5AF57CD48A1905A2D43EB663AADEC848DC0D2A6F35C3A680323DA9085D12520C388E42BFBD251E9E3EB5E665E55BBEC7046E8D3BDD9E8A9DB539FAA9B74457BAA49CBE69A6CDB76A49070DC0605BB92CE6614CB5CCF6A8F7F7E98D748F68A64C7546C19F87A529512459328596828642AE89115E91CD00663B460ECF1FDBC47B8CA442E69E68B5F8BFDD82CD5DE33D06B9AD5053E333F0B72D60073D9DE82FA7278F69D4883FF0FEDDF59182852EC64383ACB84E83EB0BF678CB268F6793ED505F07FB2327C1B371FBD33EEE29698253EF6ED08B398FAF23B390953BB1ECD21BE4BAEB0782B6B25338F2DE320EBE860D06D77B39AFD10B4B0F7EDAD915EB64DA054DADAF77892B6AA87F5D44DABFA18D69AA2615C6D869916A6291AD215AD39537B8F1AF4CEFB82DEC4111186375ADA12BFC33E8809B92F7FCF99F2FB717ACB997C1BA8860CC8A9D93A7B059CF668B099149C4CE146B56F141517CD68D4BD59C9AE07EEF7E3FEAEFCA4853D78CD44879D02C7B8CB4479A16B039C84BBC54E5E67F3D2D18DF5B360DD57815AF81062A099D382B723254D9C8F85D4BB54CC068DFF7D5DEB7DDE6B1FB9FADE18E0F9374FBEE140B2434DCBB5DF40BFE9057D5BAB7062442F502191EA95D5F4FEEB1CED3F6EEA28A07776F0439CAE0D0FB8F0E5AEE9C925CE28A629D781C83943816863EC5068D9FB2C357496307CC58A0913A2CF1976575EF94DA848E544D5EC1D30C0522816236BB00F2541182F0BC0EF0F2C67B4567441BA9BF273D49A0A41768CC54C4DA489258B67159DC811EAFBC17CD2EF965C78E27D0E06B14BAED2D5ACFD53031ACD4DC1FEB2B42D38F15FC15D3E22A77FB74ED98FE0199B6687E84F944E8F27D33829E4245296D52608C286997D4923EE67243C25364B44B162149597EA35FB77F93E9662010E93E3640FCB24CB0D8B2D7029CA4A072111DE8BF532E68A3935C3E751A6F866A418216E33464819C0A6A50B1FC12009E2D990270D0629300216AA57E4F571A2863D4149C42CD0C138DB921E62F890E38DB8DCC3497EA3F551E59B040780F562C507F3B0B4BDB2CF9CE995A10B8B25AD2AB1E8DA5836BA79FE05F776EC6DAADE8C9D999895CBA576933509F3E891FB596C8771A26F82006EA0997C5A2445F496DD8E4306D49224AC64486C58955B137A602BCCD104886CCF947E2ACA7809CEFF8D9F5EFC0C6B753968863ADC4194DCCB53F463E34582363C8A5F6259CB8D229F24BDFD7216676ED40F12633AB4F71EF6D7F647AAA8E3AD8B0175637B3F844BCBB0EFD3609BA4B1AB9F1CC6F30D37A1FDCA91DE1748E38EF82E9916D802FDE0D605607256F4E998A61D908E27DBCC14285D7669105A412C2346C84A345ACF3C1D34A2BF216FFF6423A238687516C5B068CD71A74F1B1578B481D256590D4AEE7605A4ED9C34E199F4B57435D305BE059D11577F394531C2224EF402F9F429A7E80B7E231C52D1C04CAAFC70DD47C7B894CC4A72B522F9F438C1406E052E44F136517D9ABE52C1D7940CA223397A8362ACF9313EE55FF955A63C75EE3A75DCEEDE25FB50AA64A1C60B2FD2AE889020BEAF7AE3D21D232721A2280F6018DD0776BB3AC35A2932DD90CB5E520C71AB8DA59C9EBB31EC8829A180148387F57D146D3C544A0645CD5D6ABCC05A36C4A74635A004DD3D3A43CAF5411917769D9A51158526B3C7D13DBA79DBF575B77D6ABAA79B21125692A983E01C2B33F03729502287D7917F5ED156C26B6FE6BE23E72075095EAFFDCCE8FD26A602A937F015D9B2A3A99EADEFC3F63B2EDF3F8FC029F2B563341610DC03DC16757133551C85A1AAEFA6D8269C83B91F6F7C0198FF62A7D967B5BD91B0C9698BD03B2198D365B720783EF278036A7B10D5C6DA359FAC41A71A16BAD3A619D9D22EEB8117A48EE649B1A1454119B1F0229963BB9AAB88676142D627C9AF78C1CD700C2A038D1484915185CE071D847D31E06A5C77D759EE58EF1E2C292047CF8FA852D586F3E08CF5DB92E489D1567F6EFF48017F087A1045832DE41A0A6024461F9F5D8CE37C89E1E954E1F7AF7176C3282689448DDF2F05EFB8F37DD2664ACD9A83FB48199785889C8F5E2770000E869BB670553DCECA0AE7772478F51671377C6207ADF80289988BB71347EA067D1431F88443ADC72FA231F35A9330014FAFD7482DED24408F200A1E2C5D610C0E321A648A44C6587FAA4F2BFE772283B6A8147443F8488778CC3D5A9C2D717ECE307A8D26F6B964242B3066749D1CBC7AA64B9DDC3F3C78BF316B43A8EA73B010B3C90B33AD29F235F0B37060F7C8D40FE6351FDD8232973BAE2A50F8FF54D7ABA16E3D712CA2BFB619101EC67816E98254330DC21F517EF13A27D65CE01B560F79E887E14B3842F4072F3F0123D1637487311445645194294F88A96F96B6E548114297DB9B60B368787213A38ACE79E3976D13C563774211C413520EA0BB661AD2B9CFADB50AE1AAF677BCB663584CA1875A2AFCD1B801E0E05CD68D1BB9E03528770BC760013DB269E57D6568326EAA906DB890F08E91DE713FAEF2BD4B8063ED24E8D202ED0F4FEB1B8B639683209F5F93C89C1DDD5A01591EA47F5118CDE54903E888C1BE3E6909D66E5A9FEAED25BEF01B8B30D977D5BDBA904156092649761B5E73A8DF9F6B1F097595A307BBE95FFA78776243F0A787916861295D627F6C11624BD44D2027778DCF3170FF77161BB99EB878925AD86722C0D90706E8DE3AF6951A2DC7A2FEB2F109CD2C67CA586A6F68122BAD66012B9013774BE328714AEB994B57E18583DBCA55EE9386788A9A1CBC2F8823C9C431ECFBB35B7EC918EF9D4394E26465269EF045F561A7EE27436EE614FC081E8E708BBFBD08147411CFC78681BDBBF98021B82796B23A4FE1AA03D7CF8088E0762EF140DBF496DEC686F82FB199982B1B3E76ADEC7E3D7FB167A453D6EB0B09EF891019D8C72806CF94A5C431FBA795FDDAB2CA8A78799638DA1803FB66636C5B2A2B692F8605CE09011656046659D96BAFBA4A5756340AF24FAFEE952107E5FAAA3A8BC51335A8250A20CE837BD5D8B8AD35034C6E1695B5E08C553E2AD829CFA9C1DA4F1276A0A2F6A86DFBE9FB8E94DE196D5AC78FCC84899E4BB3D8AEDD781CA88EFA6AB6C21A8FDADC2AAB2F543C402DDD0840467828CC4505D481307DD2D3191B3E27CEC2BB11AD914FB888D98F72DCE44671A08127E6B6C93D61E3B8211A84B374AEC70934745EA8C16E6EDF857277C849518867868DCA0530F34719CA7F0FAE881E4C074B1645DEE9370EE1FBE7BC747BAE3720B91CC1C0A6022F7A4347DFD0505AB741F6F36680824184585E7017507D8A51AA5F5FF94F5042FAB1A6C8106D8F6D5203383A0EDD488680B26C2203A0B3C63263A56F3DB25DFF7BF5C0BF070303E07A5210DB16AFFDF7098D12573EDC38BB60BDCB144DF9BF62DE4ED9FCC4521393199AFE4C5C24740D87F368FD253C3E55F295012AA61D8B689E6CFF8ABD75FA628A37837D222B4071D87131C9625DDFCDD99772BEC49DDA9D182077AC965C7EB9CCDB4B050A17ED6543D5C870BA9389060995E72C3FB73DC53C8D951F909447A0E1EC6CFB63E963C0B3A2760263172AAD300830EDFD60A629C6BEEE6DD8A107C9D83B97D530C91E4A73D48CD5D104742AFB7DB0985E1FDC79C19DB47223E79540785", + "rnd": "99E19A50C56D2755BE9CA2EE96C22C236DF46E7D98DEBFA98B6A057997A1CB90", + "signature": "4FF204815C56D5C51452860204405E49D9F43E1C34A98C1B014E87DBFA10FB99054F398FD9FA520AA1467BF785E3565EEB4E2F6C88B4827BED418B4FDE96A4FB370C394D870C776A6B75ADBFBAB97A39BB0E004356B8D0A127D2B422E736D5453E53F658841D91A6165B34F6B00D59ABCB29E7F611E640C188ED3FA735827AA8A48319F37A543EE4DD2002AC491926DD5FA3F732669771611E0888F01FB4923153ABEC9FB54A83B2FB08A286CD964F692ED4D44C74DF5F86770534CAE9277FA27B401FBB40248D5E548C7698C7C38247C22385E34740AA8D883F57C9A1EE00581DB297256824D19B47608214A1B9935A14163B1FA1DC70241FF46EBFCEA830DA689400424FB3CB63B060A8C544023D83A8E01B6936052996061116E254E129BDFD6CFD23313579CF537BD75F72BA992971CC41EF879048F793DEADC2124B1E40FA758F9B331785DA765EE11F5CF204B2C0E5213D853A3D764351B296B4D2B71AF6B12325E30827AA3889F529BE132AB69F0FC3EBEC83F1A481237E666F3A7F9F51919E0DB53F84722D73F7874F93634D5705A0B445023F5FD166D66704F1C1E5E42615DEE8454A28B82F97BF871F5AB22D766CD3996CF65DA8D63CF060A97861BC67859DAAAA4D527ED1BB534BBE2297D413B61BF3C6C599C26E9488D470272A2FE186A886E42C7F8EDC555B4D6E3F394FE52AC51ABD99935786566A7674EDA529A830ED4F48364F2A934BF8EC63F81EFF65A069080B1056A7DBED12F824525A83D3994D5F6176A97BEE8BBF958C657909B93FBCB8B7904A3B6583DAD8BEDD1EF1D6B4389461506AAA43CDBECDE503CACD3C7AADAFA616598BB6DCE1E96666715CB6C03DC5645A9211AB2FFE0A684795A92EBBA2EEC565F64522602227637FD544EC38EBDDEAE706F420BC51E2DC9A543FC3B8653113269938E911C9251AD2E8279F8B03B991CA3891639B652460BE2DBE2D966852F97B8D7D52E5CEB5FBDAEC1F6966BA3708EC24096B13CF80BEDFED360A939689FB8C75C8C12ACB27220B68660AFAB12C9F92FA3AD57FB0D12B256E946C31328266C3F54C558A30BEDDA86F4B5DFF5E52D02F03D7CF660B1B4EC2699288A0D354805B9AE1E3EB206882DBD1E594C82FF773E921D4BE58834F72A79EB7778F889B0B2529797792E8E905FDA6081C2F6FFBD753766C753650FF6A7C056B8DCC54B5FA7C110D8DB47C1FD98F7F7FC5E221F1AFC5F6404FE696D72FE4DC31A9F75D1ED957A1306AAB348B2AD83766B45AFA30D1C970BBCE8103EF29E1BAAA17BAB49E6AFBFB6DC4F201AEC5FE98BE5A9684DEEF7BD8F647474367E37A2E35A37ECC0E0904178E422034EC1E884BCEFBBFD9ABD27E07F6E49F7C657BFFEAAF2E1E46A3BA46E93ADD7E537DF724D77EAA018B6FF28DCFDF002708F7CD8E8E8F81CA499D5F4542991F48C330BA8823B5336DBD0568653CEA52D3B0AAB8EF2CF3A77CFB561C250A7C2956931D09686FD21FC68BC8DCADE1731CF9C6F93CDA2571C8951A32CB24F1DC2C1A1FECE255263392FABDBD4D5E4C5E3C7F842D0630E9EFBB57532D2A623B36ECBF616B5C7FDED9F45E2FA37FDAC7257FFEDE0DC5B6DDE6A5B49E8C151832F707AE948E45416E7A9082B257CD02152314FFE399BC48755EC6A311DE39A5C8FCA15BF547DA0018E5B98FBB02B0550D7DA298EC788E71E34ECDD769D3CAA36571697B3F9EABEC88E8EF76F492006540128C1FFB4F140796559E17EF660F34386355F46964A9FCF8D37992B9803BE4822EA8B8358302B6B4038D8DB1A71688C8AEF77FBB1013CC677777BB2452EDD89225B2F713683B3C27D35F4EA5DF3061C2750FB011E789AD055BC3035CD1EF947375321770C53C8D4CA48F0B51E68C251CB49537FD231ACEC8A2C2BDBCD349FA651D8AECD202719ACFF8B7EA26DC31DBAC5EA338CDD2160D15C534EC6426E63B0DD3141B133F73B67CDAC053D54A35CB8DF2B9619273110558E0B29C6DC2D9BDB0337B11C4297D171990C32CAE1538C69B858E61F4F4306DD4749BBEC8FCEDA713E54B3F742BC6B691981770EC5329FF93B140033C252551B37AE873A2179782695D4F8D18835718636DA25A3F40794676F977AFDFF7364747C1FB1F7A8A2CB08AA11034FFE89F2D4B67439AABA9BCD6F9743982F4CB318BC7C906322B0E3AC02528A80C9D2E6E3C2A3EC4DEAD7042A2943461833D6E6C460223B2879DC8E1FA97CC1826C620A01BE5F991B0DB50C5C7A976F69A1FB19E16E03ADA7F0448C1CA4573D94E13498A1FB51A1A0F97D277D80774BE06CF1D6D96CE619FA7E7C79401E331293706CAC3B185C352EDD07C91572A31716320E1B25308B371AAF43B7D232894281E4671F9ECF731F228337BB7CFFEA68C0A5B190D0BFDB47BA7836CDA5923FE3F6EB64273EFDA6CBC1B549FBFCD9B5A9B4B9EAA9F86B359905D014021BF69B3862F57EE44136015F6C32E1CCF0C08BC1322D4FC1185AFC3CA38C3F7ADA19E8885C108EDA8111A6A4179670C18E718523AC4A04C9316F803773A68BB5D4C6E82468037EBCA5E6602383E8DD2C4E830C1834101E4F87A9A931199D7E74F7139FDADCA6817374A9338A1AF2F3458DF29D26B1A0C63FE9AF6970B993D9A6005BC57AFAA6002878367E4AA538ED7468C52EA6CE196A00FADF1F6ED083E5B98E70742D28D92D60ACDBE5B164F8C03E0E96F8950D230C0FC3F6CC9FF447B74561F66A55C2B962D4555962E51A30F998657DF2986F47F1B3DC5C87D8EE5DAAAF760A06DA656251BD6B21AEE25FFD6C61190C1EEF85781C8C13839E75E206962BB4E3A3A34438EB1DCF1B8EA649CC3435A41050842D61D3370FEDA4E950D28DD062181780B5BCCE085EA7A976CD38B52464B2D65ED01220ECB4CAA1D7FA2F48123D45014B522872FDC8C642BFCCB801C6C87D26C4D62C031CF927FB2F1EB8B23499E3ADF4C781F5472D914F8641EC60FDD3558A81FA988C38D6E26B97E1311D1AA3FE9DA26FFA9B0CB821089628B7D8374118C59C96385DE497520324DED714BE995B6A08C0B5333AEB7ED41A931319E7F25B23E41100521EA8A8B661426D676469F1E67D9F61881E74212C2CF74BF332358D396EBD53B312C13D22AA8FF3C709BBCC85515B3DAE37546EF2E437EB807B8CC0F5C985F19A3ADA2C84DFE44EDD45760A409309A22EB2DEBA59452B379F952E85086D0FEECFFFAEC7CEED3F32FFCB8B5C363296ACAA0E891DEB5D463B068B40F40A5E8DDCE2AB383F93643A9E5B69009203F76F3224E40399504E47D13C5137579C25E10B997D2D3F32D7B882AF31D63A985EB05725C7DFAC3CC58EEE7CA7D25DD6223080B1F8413C7AE3C65FA1A3FA61BA2B83451E7D782CFA6378CDF3BB5668610DCAD3E8A251EE2CEF84983F436D354AB7F3C203F4856CFC8EB64BD06077523BC70837FE92C1EFC6060712B9B5C545BB45C66A8CD79857E1C265B99FD83FEEC38F3C919F1F83B7E9682BAC6215A53A9E074885D737EBDB4D9A851205D211F92579312026AB3A7C4CB57E2B3AAC6FD6331976C557FC24451B199FD1DFBC3EAA4F49EA1F79A9AC08B1B05323326D40230360E454B5EC83E484E3D1C0A815D97024F7164EEE646361F4DB3AA830B2BAEB07CB4F3768F56626E64236FB8B03559525D2A2E9C80BA074821E0EDEBFE288032983F765A589CE902C2CB4003996BBCFFE8D372EEC34F705FDEB80A9D7AD7287FAB144117C19007E6FBE30CEE999ED98A262E7790D0B2CB10AAF174B791A010CA89CB9E2D682BBF3FA23BAA83401B86E71F91B3A389A4F250C524DADEDEE6CF2938D928FCFEC5BC843BF1F46DC49E73F2AA5C232742F0FC96220FB17D71EACA22080A9EAE6BDE929236FFDBB4B6A86D0C68BB04ECACFD4EBBAFB1BF11B78A9C7DAD0B6F7058D24035492195205837DEF4915C8D745DF92A7FD9B669C079A2BE092D702BE9367A57B22C0D085DB794CEB5050217B53F901B95384D95614EBD58EC6137BFBDD9DA4E4DF735F02A344E95F316347A982D791E95302F92500479152375F886BDBFC33299C45B629766DE1C9AD3B51B7F3ABF0BCF44A89CBF30446F75EEDB548C65EFAB80D506BFD1A740FAA5AC16203C2FBFF66034C5D2FA7577A543F8A1AFC6370AFDC03B73088CCEC659CB96481531F60E7BA5DB671AED97CCFF08D4280ED70E5CE1C54FCBFAF120C44BA63F4A76BBA631F35DE27B9D13AA4275E0D17D40B41C37647BCF7BB1439B86126A63545DE4CEEE5FAB270D64F5A18ED479D2C7B6190F45EE9E284FDDB7359AE17DFB28BB0AB54936B366BCF0475DCAF73E82247429B30EDA353E30B887132D0D50AA7388FC49D599837303F6376AD03D090BDAD02B36A9563EB0FCF8A1EA5693D0C8A335E17B79FDFBF77C8866874753CB1D248FEC3915394C6BB10B3BC26C6B03D54056908D504AE7320A4F5BEE4DDF1FEFCB1FDFFED710A644DA848FB124DF10AAC1D5818F35EFD2587B04CF588C1F228EB18A81FD1DF31E79382B9A9F74540C76438743555B9A74DEDC0EFE4584D3A69B1F7CB5471CF866CE6CD3D262A8D8E4913B3B7CB53DF8CA7B023FB199CCAC264C0D314A2203FBB08F5DF0850811D342E6D5067871AD16D70509D82B58282AB68FC4B6317A930842C5630CDC9E6A49BD8D3F6B38C1F3F1906CD71C1E1027B0AFA520EDAAB597CD5B38F0F23345957F27E440CA9E6C78E1D5A9FE600064FC04653E13884CCD9B927764973845DF9130587F06B5A879E243EFB56E91D8FA19B9DB14EC81020FB86F7D007351013EE0320202C19E7C2AEDE274D60B146328D9005A1F4D9BA1E86697208E26BC274FBAA0E441F65C22A44AC386880F7672B89B3ECF4784E462253FD4756245DF47D887BC82059608DBF0AB7AA3A0E4131D732553A4AEB07DBD7E49990AA2346E445643DD65F0FBDDDE9F7096CA57959288D425DCEFC093C44FD2A70EA12D3A1F3361AE88BE7855EA010E775982568EB4565F25116D26627E76F78CBE9DEDC068D123C785C5C500CAAF212667F1C9A269B4B798C2AF1344DC00CDE7D2FF8372DA48F0C943634C631B494D9320017ACBB8D2DC3F3227BCF2B17C8C6DC241F73D797000552366D8663B1BC702871C3EFEE8C058C5463C4FC55A01073D19AD809CD1C70FF18C1D8995786F6BC1E676E532C5D1A9C201FA00E3210BBDFE33BB8060DB4D4F9FFA2DCBAA111FE12111FD57B60E58E9AE00D6B858E16E1DFD2B5EAD33C989CF5FF29073A75957A123B3D51A9A0BC9C34EE83CD91FACFB2E3B28365F824CB4878C2326FE3C6B8C2F6B92A2EE3C3E313C5F8053E3B80D68FA476BEFF203A196B79ACCD76EDB0D54B2B6CC244D6FEBC033999EF1C7547717B07E53B4EAABAD911A7FC1271089BAF11F8A0FAD5C9191383D2BA83126DF21CB54CAD8D4757BD45974B7CB63864138E67AC0690C9DB790E728D5DBE6FC1B7B8D271CAB038A0AF1FE2B8D2B009C3E50EF9068E71F8C53E1FE648FC9AF86628037C909F21F0F9E38484D0DAB7DDE575DF0B1C63E7A8E182381F1438823C5AC9B3FE2E166F18C2A4F0D4F309CF9AAB0330AB9E453F29A3DFBE5FDDAABBB1A981E1793F7B7330A5C0A80DC913E1866F2AC7CA33219D89E3314FC5B54B06D9210A58F959DA6B0CFC591B22D4DBF9DE82665375FDEAD8EDC7BE99FFE00132CF4BB3399B39FD987D23731C7830B5A6D38A141110C7A67D98CDB4B21B22CA936251EADBF16E9820F5646D85877266DE56DA00E732A2AC682EC55805FEAFAE9FA18580DD147DC7B4475DE3AB37F10350DA49929515A2104627C8EA40DC11F58D64EDDCF9AD9E566A3F75B4E206AB1BCA16B9216C484AEDAAD5EF0D6C05CAA29FEA88F14C7EC842ED53FB6BE79A0D07B78B5DD72C42C5B06322B2CAA430A8D6DAAF008E1756966A706C9331D92F8DA4846CED35E7CBC9095C7D4E7781C856A4EA6DCA8F15A7F387C582DDAB0F908BDC04646913FBA2FC80CFB652DF0E398717A0E9211ED22DB5470D857CB9E5FAAD99126BDC4887238AB80AAA3EC0F0117B0A147F541EF4A330F4079CB1165336E0C7887482EA09E6CC5748AC7EE16F83CEC086438A054846BCC8E5D93EBF31A9AD3FF12575901FBA88ACDB257955275A6F2ED26A0F4DB7C98CA63B8FD6121A4D6322DA3D07B2A884F0FEBDE956DFCB028A0ABCCBE4DCD16E97EDB27D297B40935E42B1023CDE63F6DC6D86900036582E61C3D3ED94FD205AB8B9BFF81C6DAE8D603CC9AEC3F8540E7222F0FB9BF02FBBB58BA6E7CEFBB105CDD5002E6523D27963642A99F7D2B520A0BA00A91F10B980BBC0F15819E8196BD4E72C7FFE206FDCE8E0D14EC0A6227E6EA725E9FE330D2DFEEEA928B50EDD959A70FA3983D58532CBB996CE0D5A2F9B6D8F10DAB2C39A9444CDBBD1DCC9FB14FD7C6D309224E6B34B439C07B340AA77B5EDA8C0549577A88B5D8F5FA0A102C4C54575E6A81C3DB2D2E5B60375B6B818D8FCDDD070E333539457088B3FD142448717ECFE5E8FAFF2746617C9FA0A3D7171A1D3739408DA5C7F20000000000091418202A343C46" + } + ] + } + ] +} \ No newline at end of file diff --git a/test/jdk/sun/security/provider/acvp/data/ML-DSA-sigVer-FIPS204/internalProjection.json b/test/jdk/sun/security/provider/acvp/data/ML-DSA-sigVer-FIPS204/internalProjection.json new file mode 100644 index 00000000000..f8af6142f52 --- /dev/null +++ b/test/jdk/sun/security/provider/acvp/data/ML-DSA-sigVer-FIPS204/internalProjection.json @@ -0,0 +1,396 @@ +{ + "vsId": 42, + "algorithm": "ML-DSA", + "mode": "sigVer", + "revision": "FIPS204", + "isSample": false, + "testGroups": [ + { + "tgId": 1, + "testType": "AFT", + "parameterSet": "ML-DSA-44", + "pk": "09B4887D97BCF6379CC59B6162C1E8BF0560BF44D61809170E6E28F70669A3E9496438E8915735ADAEB445CFDB7D89B38C048F4C3E00581514C5FD198B2D1739E883B878D56BB41264BE41D3D51565E2E9CAE33184A899F62DD57D07400E98E58687A9B22FA317EED134CA7214BFF021DD2162B183091D15F263B7298214423C6BB696D75C20D9EACD0A03E4262C4B08BE39FA2154BD6E5025FF791E885F2226E3CF48F7B5EB04FBE9ECF75B19E1D15C305E92260AB0D6AE7DBA7BBE73B6BC181CF933840CC10A00050228FA46A2636DD9A90947E9F13A93EF4C62BE374D76D1FDBBC5D8B55E729FA58665AA07B90C8CDDD61C566B0D7ED65770492EA0713E1ED46AC7AD1503C56D9052D2C94D49E4416AC92B70396F76F6FB481045681725A68CB356377FB231AB8F3EB9A4982FFF1836473BCBDAB6872D229467EFB9366261FEB148BA9B7DB9C4FE0BB88612ABB8FD61096F1819604D55DF6020464D3F092CFCA59812082218566899A56A3C633CC81F88ADB2E1414EF3850D10BF5A77ACE724D6C1F388928744B3E542AE491CD56A64213F1D3CC90B29105F43D237C83D5FB829325C83E654577776392F8536AA9DAE872407ABAAA9ACC22A6812CEA74C0BA67EAF4A410152975E9A83EE4469295317BED10551BA32E65AFC8C8E68DD55420C502D937DADD2EFA2CBFD1F739FC0AB2B2654FAE08C0C7F8EDD43CF9FF0B01D984D491852A372E9FEFDCC1BC16CDB5239AE1001155F89563051CE47996C5AEEB2190EA18F7F734042DE68E988367D89355D9D8377BAF9647978EB2E492AD021C569AE8BA69B15F1FCF7039A7E64AF10ABF3EA45B7222F9659E33373372E1DB186D2C2A0D75451C478AEF33E5949F240040C2AFC44B1D3A02A6D2F87902A280E27A20D4E57F889662700DB8A9D249957A7DB437CD480DDC05884FB23F868268EACE34EED274A927D9D84F1EA57EAB1A813B5E6AABE9ED2610BC6F72E320CDEC4F99523F93FA448DC1FBBDD259B102F5DC9955AFA0C41604D83DD1C2D2295EF4461456BAE86905C4C30D8A9FA48C90F37A19C41A2D5988F13D51344EC30A4A46219FE841137D5AA1F51E6C444168AF39890B6FA400D67F4806F5BBD444703074A7A1139C71746D7C4CEB3C911F5257E3E53EBFA5AA8F227809D44EE7DE13C027924DD60153B30AA76DD96A7C5ACC59B627919507BF14257AE7A26243C1683B28D1B14B501AD059B4D522A57991E5539CEF18CEB5C26D660B8822454C9C42A95E6F72B84F78AB99F51EC49789F9DB4C128B0318FFFC82D95CAD277F11E14F1EF871414881122A9B11BDFAE4A7ABC8E75755AB13741DFACD664293D1A326BF5ED5ABBB153EBE6996DD622F0A8CB473969A50366BD0B01C5C73A892B8E26CE08F75FF801B6DEF041E1713BE6DF0EFB51587BE5FBEA727E00D717647DD539079DE18AE7BED12B91AF8DBB1B8B32D2860BAF40AF8A0BBFE02887EB5DBE7AB1AFC41DA79B016AA16EDA281321CAA5DA644FD8658A7B702181001431560DD63CB21E5FF75C3F7250456BE08C0D5E34C3BDE2F606A2BF3417768D24B23739EA86CBEFDDA34388BC1F918F951E15E43B1385A7BCC559F9492C7213A14227E093E929F32D1EFBE7F1EE57C49C9055623EA42EC6C79D7FCE71FA747607566DDA69F69DAF68115919C6322EBB42C8C089338C9E0C53565BCBE72FBE4726687B0787071806C5A6C149C82B668AA64A7BA0CCC1CC49A1EEE9453D04336E5DC811E03892F7F46688ECEFD04F1876F7111712B595ED62DA00678F9E3786B5C1A5095BE8710DCFA4165256509E00143A6F1172FABE8BF21E5FCE7C79C1A44B4B1525A076FFB8DD9066", + "sk": "09B4887D97BCF6379CC59B6162C1E8BF0560BF44D61809170E6E28F70669A3E9E7A5A2506B0783E5309F18DCFB0AC4DBAE97E16C09A7C15216B9F43CF1FA0DDA852F5E3BC76028C3E884CF87DBABE8D530527C68C404ED51534564C40E5CB3AA8F3018B70D93D1743F9DC5925C41D00498724F0752FCF8E76BBABF3A84238AA7213806609624C9B46103C76C534841D430614304049A444D923002E1066661346CD90485012048889440D140128A167160B68C14928C521071E192319008900435485BC2010318202000285B120AE2245264388D03954008A184D13671D8182910838402482D54385144206CCC088D9484840AC84D2495518B1891CB9665614432DAA0800AB110C2424E89364210306A9BB80589C83019028E4AB480E38650824025631241C3100E9002824326861A910DC19068D8287208326DC836100C8685C1B6845B8871822808A2324E20C29004938C84086D133500DC408913110D61903013140020935154109008B40014944914872C22408644064158066051368C91001263B0611300440402519394842421700B3189CA862508B131004720CBC22119108AE296480925910CA3618A2809D84066CC384EA3266A24349051068E59022103168A4C128058C26889C63021B364118249CB0421A4107083A281C8A449C98028E09488C0A4045B8225628221C10684D3A47194A21052226822174A0BB44D534410E248719320125196881A9308E1184463A2890039226182315A86405944690CB089D0308514A34CC3304294162AA31051944248040385D3900CA382111983815C204501A02801265144B20098142C00112D03410D090792A22070D0967001300620180C8B002210270523C92162480620A608643600C0346E6142845C062C01C44048A06809C4640C43889C0202013082C01002DA326C08C560E2C2050C938DE4080CC30028A340301494291119800409504B368A50484220A668E3A050C886001202024A442CC9C408C1A64524102C0B43911C234E548489C94080121606441625A1205088140D90229294384C80304C10C47013302A8AA84959162ADA322EC4C465D02811D3104C13A850D9000800038C23064623B828D18865DB206C8892899A80054C128A22986D99B00003B600E3B22582440081442061166661965111B4201C08680B1928D3286E082100E42288E2825048328948028A544001244829D9906104C468249561191705E3025108C024A08005D0282013384504290CD96AC25707AFA29A10322AB2F4106E2BE2F6A906A02184B4355C2F26D0F8C0FA7DA77565461BCC8C40BCE7A4C9BC109CB1EF458B6ED858D9E3FCB29D75D3952AEA72E1ED308AFCBA0D4FFA7CD0CD91257542B632670D8AEA9D87550F02B51D54870B0A6DBA2B625898A386762E1CD774DDE6D3173CE1EC46CE6CFE2E485507416872A24E1374DD2705833631DD6ADD3AF142E9CBF4313108250BF16C9A6EB8C680B623F550EADCD872E06DEBD5673374D680984B4562CA8F784594A6DE72A048E5E56DC74C77F2A59543646933EC5DDB7C09D27A6BA87DA77F164F8439CC2B31C069A1B1ADA3EA264869B6C1180BD57C947D804790003C197838222BD73B41CA8AA324F345C08E408DB6FB3587DB4FBF73591A181D97AFE1917A5BBE48AEE07AE176A9E1596A36771F204B88D227435C586698356C469F3A9BFEBABC1C276742B5F5A3BEFFC0F6CFC9DEB8F3D82A3BA5C865DF146149DC9F7CD8CDCED076D5D6A308FE78E505E7203C836C249A1090D8A01BE81A000C707393F8851637DE57C5B4569680D31859A5CD36E1585D0D0FC50FF220B6FDBCD68863B280E01144A0F8582357C652A1892F8D2F68CB684917DFF64A9499C680CFDD261D7CF375EB6B7B7DA353019DE45342F39B3101079432784C074F1C2A181CDE6CA25CFB203986F94D20442ED4723DD6A54E5327AD3714E262EF999BE25E3ABA175C03A283D17CDB852DB4FD683D312FAAD9872844D503132A21ADCED8CC09089F9C952928BA086B597B78C2EC5B8B78390BB91EF456A5616EEE9D846157B0B2F24DA629B04B18B1F54E36348C89DF6E06D108EE6E6F8DF7C1F918A9636DA9433948429BF62AF9F702DA9A3FF5CB76D633BDDAD61EA7ECF76F4B8282DA60735E4A0F1D4DFC59223925BD212F065242FCC990A8A9C72D74EC498207590E11DE6E9157DCDA9A4DE9007D1F20A314A8E5BA0C0DD8CF839D3944907144C132E10054B8077854DD8D18BE88E4C109586C0CDCE798DA594643D749FCE0B3556C28774CA4E4BA765D0888D4DB090F2A5691343A3147CA49BE3393A0FADB7E846EEC459107BED1106CC891F35020F82ECB52A7EAD9FAFAB62DC257192D6F45B97A67B076B546145902577BF59376A0188D5EB322543D2CEDE9147A189B1B40233EC1DA8AB2EAB9C4EF623D0FD33EE0768C4184519F216C3A8AF0FE83A9E2552973BADCA07976138E2EEA5C707E48D9220C3DEE8CFB2DFEB37D43BD4CFB1D8F1D2CD29710B3A0012379BC89CB1FEA8B57351FF1C03BD0B0D3D91595E4F75810F5B713923F7C44D2DD8D3DEB254E1C9770F0FF980ECA073CD1B4B1AFF9C3A77EF4A75B77EFB29C2B0150BC98E829BCE3EE8F914F9953101E08BE5E90F2F3C88E39D752469FA7EE6AA6C0A017249ED3DE5061CF50DB924201A789DC6D9CF1B3807BCCB5472C1E701DA329181ADAD34CACF79BD80A21DD076572CD6605EE71402F541D09DA885F1D6C4CBEFA068B1DB5AFE8667D8C836C15015429BDFC2935EA45C92162B3ED9F283255E68B9EA863F27FE1BD5D1BBF93354734BEA18CF2F09FC331D492C2AF749E085C2D472B6128E0FB4D33C6A7E03FDD8DD7C41D8CDD4CAE3492F69F2FD3813D561375A5B9CE632BEE8824C5472F4F76DB4DFE5C1FB852188DAA42B73FE972FA7B5BDF3575F4551F5A7AFDE1258342686EE67D0378615BB971C6E1201FAC15447A1AC82BBC2C2C1247BF2DDB704B2DF84308DA03513A7291C4EB505D039DEFF232A1A984D09837142BC7949C54000B87D17A22BF06D43ADF14DAFFA7AB5150F60F42C4ACF5C7A5DB7B3FEC0C1F544681F27274D6F6F9EE1AE7F60A82F76B93D5BDC31E9AAE4C70282D71CA6711A0804E862923D7C5872DEDC16BE172B3570DB3DCDD79E37040EB12E510136B01CFE7F7C030C1E34D06143621E05EC46A3CB250E5D8C18244491E9982F2CE5716F4A6BEDF61EC85E2B1D777B4985C9E33AE94C05992E9F4723D96ABD7BFF52B1A297561C6A4DDFD86B483C19C52C95514D6446447A920DFBFF52312122E972A5F6869EF39612E2C4EFBC266D4838DFA9CEE0D70DD6B908BEAC448F88FE0F455802C1C1A07856FFC7C04F98A3EE5714A30E2DB52FE2D7F75C395F355479440D5FB10EE90FA1DB1120E80CA4E357C7D66DC86590F319AD3A0DE8A20C6611498E8A6C7CB854DD9C7C19CC1378FCB3F626C7667C8F92154832E28C5AF942549D6A81041F0E01094BD986D14A67B14D0B598B79EF4045CF58C88E9E587C344DBAC001F9E6FBC8D56F3B807594CE6216238DF8091E862FD800B5B44C347B69D0BC8C0D34403D3F5DFAED880877E809671541AD300A0FBE80F3FD7E044", + "tests": [ + { + "tcId": 1, + "testPassed": true, + "deferred": false, + "message": "3AFD7FF8CAD3ACBDF97731261C7A1C969D5016F17D3E7F83D2441AF9014B63477B14A6413150FAD7C84439BC88662C5E931F06B9514190E13FB049C4AB74013233B98D48D9AFB6A30A67330E1FBE331B09C56D037E9701085D80F1E7F4043EFB53587ABB823624012384515249EE6130973DC9EA6F558BAE75107EFDB1D9285B", + "signature": "4A2B16CDB552F9297F8E391AD8F5ADC8CC5D2C56C46B800F9B3EE4BBD2F2E8A89D599D7B5CC2D88C80F271859BBC83043EC4E54812F5936B446C9513C855289C94B11551A0C7653E7BA74FFB6F72D4652C91D38DD1F90DFE4439BC21CA53E0CC7A7AA5B875A5B9BA42366EB8ECBA2436DAF08A91978DD093F20F1EFB6B0BCB90DA99CCA05E8F6F82B86D3C6EE24BA5D50AEA10B2307F57F89ED78DB4A74FBBF6EB332AFB08D074ACF0DE5CD7FEC12F76F3AB619C815B9EDD287EAD67F04F14797F8DCF2CDE9A8753B5AD0AFA12874197D1744092872521E868AF9E64452373FEB6FE25D5273D63C0EBD6D3B1028C1CD06AF32CECA2621310837C72788C8ADAB5A0F03817128EB7B766FA812C696CF886F00A1044CDD06BB28CB2E5780C8D8CC7E60AB699DD78668BE4FF9F4690C6FC98AAC9C02B66B9B9826A3061FD3222DA8482667960A31652EE88EB32B0469AB71CAA2519F23D1A2442D5B1316262131DCEC5F287E32FD343FEB4429E54258D690D9D20A10ABD75A536DFF8CF1D6DDF19291E2749A7D16EB90AB5093BAD38E116A86B730E65574C068C38BA9457C9D6D913EAFF57FE23BF3DD24D8CA511EFA376A5DF08467025FF51BEAD3EDE0A84EDC5321620998061E8A1A73D67B7021B810C7867FF39187B59D403BF7C7506300C7345B1FE07C11278B0ABA61DBB4F2B8C43E74FEFA55ED52C10A8C490882BBFE3E3B3CE579E8116A9B6686C1A100AA1F6591F191F772B5A5A50DD6CC155CB5A1BE5BA122E91F044420156CD63080F0A45D662E76DD57BD0F689D0B299042BFF485E8A382D865C26CD46B4A54728BD48458362D79AC3EB756FC6C518C9E2F0E7D5A303AF1159EE6DBE7DD56BA0712857A68836C3C78C6C9F7488572813C0F6A814709D2BC142FEF02527CAE7712358371C5426522CCC64300C2CD9FBE20C6562E34835205FCDD5A8982C920BB477FB881702827B4911871394C06B5FECD0C740AF7B27637BAC1A0CBCA537E4433EA847454C693897A32E4D1844195426A0C6AED67472BD2C4EEE179F3F6084A36A7689F4CB1F8E5DB2DDE54ACC0666BA98415431A4B202F402FB1F1BCCDC23BFF13148C7B8F61FBF6243B296A78EB698189DA95BDA85DBC11D15FFDC6BF46C53F6E472A871401E9A9AB7F9FB467EB4ECB1F0DA7E63EE8619CBC486EBB0F2120A7811BFB0557D13930574297C9464FC595B27569ADF5F4A8DF669C9EEA0A250F4D22C2E8C641BA3902BA80800489965F11AF1E1A85717C624E742F161550819D1F0372C5CAE8BC62B549EFE874461080D06346E1FA6F01514FBECCB06E34EE271A0F0031790BDABE0F02BBA4AEA4B7397FE3333EB8121820757281F96A5831F9E490366549D16763FF19FF773580ED5E3E1E2AA3E38F88474DE6D9BA6994F8E629160488CB4CD5B878CDA37AAEC9B56369A7E73F73B428639A05C1378448ADB7F074DC8154D92E13C6356B5F466D66477159B2A943799AD619A029F3010D037672DBB6820E51323ADA98881C6DE859DF875ABAF11DA5DDCA5A777622BDAE8FACE2E0CED3B6A77B88A8729FB7C50933DA6C52E3F4D948F9DC153B5B1299CD8621DDFBA48AF44E4B6F6106EE7779501DD5FB3C578EA4D32C5C2F036A7352703ADD135AB84460162417E50BF91E60797D59B9E18D324DA971F4FF428AEAF23AC0BA4E2E2FC7ABAA6C8984FE9E2D85B8ADA4086B3C13ABD43CFD1C711D8326B18ADC34CC14CF8957EC3959498FC2A7BE06BD1840DE170366566E50741957763C2DD27ACF8C3F1026FAEE1D2562FA1052E69AFDD42F446F0598866D5D306BF1B775042B035927372827F4386316534FA1B7EE633BA958CED8F0D241D4688E3C7918E2A75626377C342A590692BBFB827BF90514182D4090DF8D7323519A1AB6CD0227367410DD14D3786A26DDF91724FC82D06A25D5F56683953E8E0F20E3C1771DAF42E52024C116ED8A4C0A611680F5FE00ED9B148D15F12AA95B9BD5A9FD8101642B36911F310B0DE18171D6237D9BE1725DC299A1A3AAAE98540CEED26953D10CE8547F1C3E46A862BED428D1E10601BF328C727FD95343E2DB4D9ACD5D1CB4715F6004096EDA093D1B0A33B1E56F16D73ADB8732CB4A31160A4491FAA0C86E680E3D7C02CCEA8FE92F1E001016D220221DD10ED626017966C3450AD121365918C93091F14712BA477CF2E263296C778A2BAEEF5849455FA35CB617251E02A22DAF5C33E5AAA9F00E8ACDC50ECF47C521503C52F27D6B57C8F2B3D8F1222413E7FA4EC59296338098C9AB5A1D8A57884BD860041406D9655D17382949A03D50F1108D05BDB31CA08E66F2D8DE480C6793518D49A60D4762A9EDDC0249B422E84020ED539A14E2478F68BAB1F2B00E22A5CBB62979AC744E08B57D5B578C401A8D26D9ADD1505236082863672D911CF3A0966D303F8917093BF97AF90A7E1F9D59B09206B9CAC35110FA38D5890ED2116835CE37384F5630F1C428E213605872ECF911B014B91C2C600E8A40729D07BF918790742C9279F3114F68CDF6594CDA3CA6694223A82F66C2B4BDF3E51C6FFDC55E0FF51EFD6C934362BE7D6FABC11B8B0DADDD52108FA5FB5CA758A64377D386D45CE70605B460E8157037B5B1B2E0AEDD12A633115D6C43BC6C7C836FFF33E7D033F2E5800527164C0C4781C37DF50B66BBA5C819473A1C5302083A16F01437279D2F2DF14C878269A2F3FA40C1C761ED61501AC9EF141029038C819954089B738098708174393FEAEA7B02AE5CEF67B3C8CE6A970675CA1B8C856DCF5972508C7C6B25EE4D12D8212B98940B488EC402AC7AE3C70DF938D1288CDA7A319E085BC73A469B2D2A3303B11A683100AF6DB86937BA1182903616E3F0347BD68591B47BA65156B93F260DE59B3AEB289E2A73A3BFF38C2F3ADEDA29C7E90283AC7B86D036B47D5BA1A03EC783D250BACAE5847E41F829CB33DE08DF8F7D69C9AA4EDE8D7AB968407EED31A056BA0EF8816E127AA90065A679E1CA9550DEEF25AC5B7A34F70DCF2B116CF351F3BADA99F836C730DCC1AE03F496CF3F0387A0C2C702E2C13BDD9CF45A1CD53AB58731188B18EA8BE48D510C5812E90BCECBC6E198E708B1C08C8F864B124BB4CC0BDBBDF2C2F4E388FC19660D69CC2C0EBF91008C8243DB42DDAF57C024251C4231DF53790CE575613EE8E1C7A33C1561F3504DEAAED1E8408500623ECA5AE5A2845411749930D8E42078C032349957FC39A1DA0EAF9E87C31FFBF6AC0C1811EB28A41B1D86BD7D49AD1C468A49594956525A20A31700F122F4C4BB2252A2F3D5C5D6873838C909597BBCAD8E1333D5D617C87C8EE0F1B22383B424B4C5C627298A3BECC1B32475C9DB6B9BDC6D6DCF50000000000000000000000000000000000000000000000000000000011192834", + "reason": "no modification" + }, + { + "tcId": 2, + "testPassed": false, + "deferred": false, + "message": "8BF66DD868FBB9FB6B22B0BFDFDA837C40928C26CCD6100F0F53B4B12FEC0F313EA8536BC70417D0C16C4DBA53FAE01AB59836F6841C47DE6134DD80CB7B68B9DC03BAC0F538147788114314B57244EDD3802D97A6EB35F86848A4DC7BA0E20581032D97E7B49AE230DCE1BA15B02606115821AE80E9BC099BA1748F1B45536A", + "signature": "3B11E655917F17AF59EF6E3D4D8F1F0EEB2390C83FF37D7C55762B8C5605622A8838BFA7D7D8DC31D0317A7B5D421E3561AC357017AB598EA70AD59941D245BD787A05D03775287F74D376B928A17EA9548D1437F57D884B533B978D7CE167779C70A31D6A7DBC538BABED0AF6424F3E2600F3A0E197ED01E5F8E21F1C808CB6B7D8CCA838F2F1C9B7D2A0953ECDE316E9F05AF601AF3C2847C1B50E1FBC0FB300EF3E3B683AAA9E08B314BD6DC2A35A8FF6046E31D0C432603CD05EB12B817EB0CDED0192C6D9EED2D38B759F6186D75B6E14FD034FF6D806D79D8BB02183653C5E147098D78A991950BA72628C1E7E8852C860E945D75019CEB7D3AEC42AA49DFF0184EC0FA79513D1961467E08D258D97BA9C50BF46BB40773B0DEDCB2CD73E2A14AD2DEEA373BB57C2CB49A83285537197F0D6BD5EEAEF09E6B542AF74131D5BCC47EFC006703204AB8B98EA17471C67FA1A7531D3E73E59292E94DB910602BA1B87CE8B1CC8C685AF989C3DCF9AA48FBBE201074A38D96EAD10130EBA27433F80440553A1FE77B96888E85F581DFC8C519227FBF25DE6EF01C0457E25C1AB975D9E90A86808CFD04A38AE2AA5957A07F7363F865687724E4B04EB8BCB99C8A2DDAB80B60E8D6FEEB1CC280DDD3FD2C666E929ACE254B5169084A91A8434E763E99D9DBD2E1399AEFDCE40AF79028895753C6E7B5A612B47E9E4D4AEFA8064449932738B49FFF8C4283244B4387A6EC4E2E87AB51824446B536116587521D4C1D6488BF8E54CE21F8A976619CD30700CA2A2BA9E0C0FC4AA079978EE78739F7A441AFDD1B114E12EC5FC06BD169762B2BD2795E52B16CC263548EFC10274CF8B544C698B17E8886952B3D9BF20BD55DDBCF5E555A306DA426FCD7D1B8861A53BEF89DFB5C904FD0499F7BB3F334D5D85A972236B2F3B2A9C70D10C4AB973F8298A52B85B636545EEC91E208CE9B7E6100307FDE532946284DFFF5CF78E0E8229E38A49A3604817DE56947907C6CF4EFE5077A968E8029DAB0204EA034383BD57FCBD1EE973CFAA7A27781C5805C474BC14487339BCA8B21ABEB0E8BE05E8288F2ED0BD1804903628D1E3045841BB75804FEF40277B80364F4F67E3A6B5E6D5FB0939AA678D700C64C9C23068B3C3B35F337B3A0C10F8143E8A24E31B655A199C06733E546A5403C2A53A07F12514F955F2575419A16FAF5892983658498CBEDD8291C7E253DDBB9CF82E834F09A19B80E17425379F9561235B86F7AD0372BD1CACA92BA68EC3A381E62DF2CF8E638664C1736EB083A5F81AE5676421AD8172292B1EF34C0E5CA25449214C6B95886977A78023327193FF8980CA876AE9D6A0B1294E8F3779862E920860D35516E7B7443CB3A0C7D0EC7091303DD51C140ABA26F0E67B8F57536E5139A650207272DA3D99D880CE09233E9FB9804FC59B8D520E91333E49DD26AB03499B00EAEF1FABBFDC6593BE77ECCF03F68DFA3F704A9F54660C8807D5E5210D58F6B8DE248F8C607B6CAA8BBC34698A683ACE430C89760C541C4B38C1B922FB0CEB93706DCBC1E6C215DE9A8360A8AC17FC322A4628FDD9916BA865CB1F6798346624519B135F3B65D90CCF808AFE14FE49F659F14A85CAF939B29B6E9DF1AB3A55783C048B07E4C46ED555EAB538B492DA75B2E261B80A6227ACC006CEDAF1935970278F691C577942AE070F2C7EBF658327C75D5D7C427C2DA62E3192DB633A931059FAA500F6E3E4CE25E19E89E1FD2FDE0A1D663ED7E2927AD0EC833AABBBEACA0D1C39D492722C99F7104F14C07323BDB302B8B86C8EEBF7E3BB758A84B665961F14A65BC7FB8035253801F5E597D8955C48F6CBAE138636A82093ABA37008570ABF8B91C1E93A180CE041CAC1C45EC7C6504DD36BFF753A4A03973626B920132D21F6620FD4B00441E3DE4BD82691B073D97A725D0F8626E45B9A2B3CF30331E833051BC7AF3A4FE1144B347AD830A804E3126DF1CBF95F60400AE3B9EE8752DC1554B54F5A24DC95EBAD0332C2A5CEBF4CDC174BC6DD58F4C26C7E05B32621F28C9587A89DDE0168780F91B1425F486DCB4992E3D42E47E1532E01F9A1961CDCC3BC3A703D77B015642DF0BB7B82316C8B87C48DBF3F32259083575C97AE6DC391CF7280E2389D32327EB8FCFD17BB0BD7ABFAB3E55D40BB9CEAF378EFF25BFDAD7491B29A00EA1DF5A0B193B90666BD1CDCC2A4CFE10C6E488BEEA662E81635B0CDDCB3F93E4C78DAF10B032578C556A0B715D276E297891C0D25AFE11B1F4A216E2490FF309D3728D88D079B126C61654427927904F2707B1BF2AA1AD82C86B2581ECADB5087DF09D773A0EA490E6CB81375061EDE897DE8C7A80D907854714168F84E4523FFB9B91684D3EF6BE0E03338D6FC23C83C0974CB1E28B5B6CDF74953F0888265E98C7EA760AF434E3C1FA6C8D690E26A5FDC9717EC4D0E18B206A675D4741F2D4C4957105558D0421833008EC2A2F96E7B18ECEA1B1800B3E4C07BDDAA71FD923AA713BE1F09A016890935C707A78CC5AE8E828F658A6797D6CF75414E9BB154BA3D13F1B2782F182D2EBBF93ECFAE43CF89F5667A1EBA62E816863F62912A64E4A329B338B7C8DF34801C9B5E60A097954F116A1DF74A1355D9CCECC700F4D0B7A8E432594AD104C6DB2D8C27EA98239C9A4A231F84BEFF79A8A797BF0684450C7E5F31A77119E613F6A1F6D1636E305B24A263294FD24FEDD9F063E279DD1FC1BA5A0150EE3AF0227BA5F46FC4F58289B1029A4A93C2C6EC1A5B9984EBA0C33411698AA154437CD0BC927119AA64D9C148048D77ADEF38895B2738C4B0DF42B9CF9CCD08A36731C89E64D9329FD5B8362539A1797B76D5C73C051C8159ADF9FBF5E3740ABC6B57292FC69B20451D58F5A9823D89CD79803B9FE5A2A67DE620C10782A4EAD26457FAD1620120D7659A78B92009EE0303EDB7A0D0DA75E0F7B791BDFEF285997C9445361FC8EB84470DBA40116A99788386BD185FBBB02C7D8964A52D1BF9A27FC8942732FA54209DB998FADFB0D591E141897482844201ACF0ABB077BF58A6ED1D2A1438657E486B5963757A95877597AA73072AE88A5B681D4A1879A0CBC361681A9ADAFBEE0796A71825FFA889EB7C258F7D6CE02F3C2647356013CC115C9EEAE8E574209409D271AD544B329A8F064F17BF3DE31EB439307E4A4584693B2D319263810C4C23BED480170081FA870FCC67DD50A336B9B120686BAAC8713073C3707231FB7E02EDB04AD8BCE6C024D5FF799D78E844C64F0E34EE88961062850ECFC10BC9495A7B8386949EB9D1DDDEEEF6091D263C494A4D5765686B929397A2CED0D3EAF2F72B2D2E3D52618A8E9B9FB5B7D5D8E1E3E5F2F33C3D4647669FA2BEBFC0C9CED1D2E0EFF8FB0000000000000000000D223546", + "reason": "too many hints" + }, + { + "tcId": 3, + "testPassed": false, + "deferred": false, + "message": "E071BD6366C43CACDA4087185EE99855D3B0F6C5A83FB9C2167EA0CE365D6ADA30844F05F178517BA72519C3439C6ACF57BF6CC76D9F8D3077AEDCB740E4D1F403CBB5C8B8EF153F77646435703171F335E0B308516DA5E54D08F506B8C8E00C5B89F5B48FA0AF0AC8BE351384DA396DB4948020F12D7DF87F446968F9DDFEAC", + "signature": "B4DFAB287B55D27F80117C3B131026D75F552F75C6E79800A1F3EDBB0FE6F14DC1FCEA47BA927B065D3577DB997F74778BE8327A0D29C50FAD1B1E4804A6E55EC18A211E1A8034330D5A32CF7E84E91031FC85CD7FBFFED70AF934C70B852818CA282CFB4B2CA985C8003922FF4706DD3899EE39ECB3213FF2BDB44E0534E2DCD4C2EF67DBE3983FB73621B2FCD04D36896EBEED28F9579C073D2E3B730BE4F12F5A0A791C3A8301133ED772B0368F7ED525EE98E06D0796BEB4AB2194746806654F9D0DD4A6C4232DB8F4773416F4EBFAE9E87F86698CF64CAF39CB86DF0B8C9D64ACE8E433950B9A44C6B97DEAF1A29F9C3DB8C0B3D954E02486DBFBCF7F9627AF3E32D225C8D5687B5BB74278887CFE4B086F89B4A8F19F4D6AAB0750354FC1B0F8A82AEF587093D51480416FB8B69DEB39812CB94C0B96901691D4F21DBF87AE08655DBA6D6E13A60C3784DCD3F2DCEA882F92957BB8BD8F59BD18841B68567051FB84995B9FF45DA1293ABCDE2E06EABDF676088928327CA67C655607BE1FEC8B37A542BEDCFDC35E9AD3AD647937CD1D616A284E4FCD8D8BE8B08CCE62FDF34060E519CDA7AA6CD7365C83C6ECB46867552FD9DA6B5B6E3D158505AA2100AC963B000F66AD8147AACEDD8DB653BB974A426A222C80056EE90C0445A3D7D3054BC2190096316922DC182FD35CB30EDBB8496A2CB291CA66C0638B383681C8ECE75A404A16654C5845F7C4A95C22E91534329DDF49070FDAB46A5E9C4562308EF10338204291F4725DEC429628C138FE576A418B90394FCAE7A0E1A98A713813C71F3447963E5568CA592F39A2B2B15F106076893D8D15888DC9C0CF428571493A29C9F2C5C05C24FA8341FB50002FC641BB4A0CCD2F89E8E17AA8EDD6F57EFC96908D9F5B1C5ECBDDC6E87840E6530A8EB372FC22898359D6422B82B030990683EDD7FDE884E8EFFEF9D7FBE224E22FCF03614342BD08A92395F0305D5308708890E744DC2C42AAC0C22045C6BFD8E69AAE13142CC566B71EECA31C5A74A33DC5C4ACC15A9659F346EC9336CAB7AE2BD9ED3D6117FBCBF2787D4F3717E14E47A6A6FF907EA08E065CF07956AC73FA2655C153E4B3AA8A7BDF0A22A739A047FE8766BFA6B1750AB8EDFFA78861267ACB14716D2246BB697909CD5CD4C0AB05912F9165D174BF8C881B827E795D4EB42E2717E776851D1E98E69B93849B387193CA1A28DE3BC7FB8093E2A76945EB5489FC15EB13620568D0CC1006914FB3A495118156031FFB96550C806D1A200B1DD528019E97F5F805874D4803A981A73B8B4C11B6A9A6CDB899C62B7692E2D046E47400680300B395C420B2BD92C50243A2B7A86F2FEB753F84CCC99572B5028EC98CCF208D6CBBD15470BF16D31BCC20F5EAD65B93B7B82846F58CDF9F6B8054120D54D86DAB97914E17EB4D54CB1F0DD6DF7A1E9272EB24D96C28503FDBAAC0509ECE7443637075E294FABD9AD0209079BF5005CBEEA1E9800A496265F1C7B57ADC0CE0235F04F3A39BA5DDC211F3D018017C8E09F178A8431DEE9BE29EA85748A0657AE0934AF5BF0C859C4B2A87799961D8AC4A930B1E005D9138C18CFA74439D8784BC1DD24D2F6B229D6098BEC97A9114EA0628BA2D7ED2507CD1A0B96EDA088D0FD45E9E0718640461D6AE038068B9203A9339D4B23A670840A4A8E6D09A29C8FB4AC4FD8DF92A4063285875AF6A291EA6C509CC623E0F8FA1A8F9E45A54932625040FE61F0BA7FC726C940F0B64F3BB61F0EFA508F8C21DB5470E2ED612858525E413F4C42F64381C88910AC6ABAB7A47149F8DCE26CF7333A50F09CBC91F7AC3FFD8B4220B9F365B8AED8F82F14F45CB2E55B8B46FC60BB030FB230F69E2D6FA107B0DC2EE435922553AE2D35122E53214F085467FDF5588586874E62FD115162D46F18270BE41FDC721D3AD44E0EA0B0A4C082E39A868C28E0E057A353A846D5D5B32064DBE735C935157FF961FD86D6FB774A350B7BA3371FD9D0530CF1ECE4C9C09FC92DE2925A6C9E8B285F6ED9664F829B62E24B5CA9A078009D70CF7A30AA0D732239D3A9599782B3EF2BEB88ADEE90E59027C1DB649BA94CC5155D4B885905AB56AF333574A68C17A52AFACA56EE8665593F28D5F671F0049E9E376EEEDE6532837C03A52B3AA9188C3C991B894C2AAA43AD953E62CCFC1E4F8260F29956AC68A0B68D0E0B4B7D5BC10111BDE08C0027AAFF48FF21C591E095A01A4151D157DBF8DC34FB421ED7EBD181140930BC2D0A370C22A85322617F738ED12B0EF27AC7A6DCA73AA39DB422F97CB4B6ED1DB7B0619F9B3669DF905BA703E34A63AFF0D2233D93C4117593543218F1E2ECA0CB190BFF1AA792C245D1379D57A586EA7DF61314A201092037858D0F9BA392B185696C5555587982A74782DBC56F6E522498A33D007BB7A9D54BE23FC18E88FF57FA621800DAB6CE91EFDD8ECAD1F8641770A64E782308F9AB2F1EA59DB2E95DA6C77E6BA906C87C6334877210F54BD37FE7E2800DDFABEC7135DA997D403E5BA3C4B4EB2760466F2ECE0A2148C10CBECD02430395ED9F33F308D68B08A6DB7E6FB3DD50786C2E41FC333C694A39C74D8A2BA054EACE765D36C9A876BFA9CE150D92C60B8C9ABE3BE5496FEEC40C3BC5E8D7DFB2EDAA7F534742B85819CB90F3D3A02BF34BA793181D595FB77C50F583D8B3CD4A1E1A5A2E6AC23E127CF150FBB7BD6BCCFCECB5555B3B81CD35B325C1A155189F7C079E8649A8CD52421C66E9340ACD05D431DF7E31BDA1B2304907C54E41B968A355A6966EE2B8A666A1B823C6B58AF431B3A49038D0FABB4E6E6D749EEF97AF3D6EF398BBD04F72FFA053A49908E0EA03AC44461F87B5A915F869800C461A32785FB421A1A435DEF95F840B8755FA2C7146E1E02FA8B50A9A3A7571741D82596C9490B09C8378AC2719F66173B35E03F3CC634DA6FF37F73DB2C1190533987405B1B7EE6C2911D83EA6BF4BAD55D85FF2796EE044BF72279A6D23E84AF03C5E737815E31AB5BDCCE095BC4720D5DAE26605B0AEB993F235674139498FBB153FE0EBE49A4D76AEC2DD4252E9C63D891CE3F304CC88A6D22DDEFD880E0B2164438A0282B24777632368C2E4F37B8F4D5388971DE5A3BCF4ECFAD6950AEAF6C0C9A430C55C9A72DB4E40EF3D2B7F70ACFFCC20D7B88B347CAF4E15B8625231777459D90CD339EEC0CA4CB37B26E45A036BA317F279865E1267D698B94260738A6B15D27DC4A1B60C8C679320E5696DF6B78BFCC045941C94D1CCDA5CBD10D30A9C5ABEE227994050E0F17292C3441434651535A5E5F676C7D8C9397BBBEC3D6040E1E29313651899192C7D0DEEA05177072888C93ABC3C8CED0D1E2ECF83258637A7D878F92979DADB5BBC1C3CEF1FC0000000000000019273748", + "reason": "too many hints" + }, + { + "tcId": 4, + "testPassed": false, + "deferred": false, + "message": "13ADEC8EB7907557621CD4AD36126CF3B8EF81650805B8806BB75AF36F98321CE21AB29B849F74FF43087BB49DAD9CB1AAC46F57300D3DC648712E2C90B960DDD0715AD2C417B72847B17346CC00F299E4EBACCF76038E3DEC76B23CC7BCB1B74E47B58F46809C5794E55BBF4B2A3CFBAEF6E84270AF258501A152616E4C0EA3", + "signature": "7CFBB2E16D1D00B96DDBF76479F0EA008E851390958F220CBD13CC2AF84982584B99BDC9AF25C596FDB34266C6E95662DB7817580F51156BF9BD0F1E30C37DDE8056EB17D3A706BE0F21C9C7DBFFAD740C16C83019E8588A3339548CCB7E477942902AC5B3C1A05E5DCDF575A62041915CE57270CBA4BE6CAB1DF2BC021EB206317F8FCD290462B4E6B4E0118D398A5A4CA8B91137DB39497DC6B4D9FD20F9BA9A3FE59DCCB7BB23FE60C23DC48C571E86FA020DE7EF32DD0CAFE45925E138E3C9C6090A3944F4328D22081D6078B9163FE52DE4C75B6D6210DB4C0D8C1B46357604E743DA5C4F6F32C131B936D70933DBE748A5ED74362A0985C84B48E4C983E33EC8E2A3C4A47FECAAE3BC24077057909F3B8FC9F49B0346B82BE85C941E97094F7711E1B4A4C355FBE91791EA809EDBA77BF7C90C13DF3B9ABF4FB88A34D58B8A09B26D39E2865DF480BB592B34EC8EA2EF8E91C65D0DE9B53BD058AFAAC7CE90CD64F5218FBF6D961D7169C809C5171720C56BF8737AFB22B46A552B30A4639B48782CC5C4B4BC28DFB9768D65903B7BD18D7D1A648F69F1EEB7F6042FB148CBF373BB539FF1A94F4C99E2A2F060A900EA4474954244749B8373D4C78616629D3AE9F45CDE61DACB8A45C153088FAAB53EAA1A4CE489AFF229E1A8E9EE1F0BC74BB0A4A9B0452C2E153346EA3A4CBCCAA70AC06270CBC6CDA804A8706112CC8D42A7EB70CDF0CCF4379937ED9570ED58F38329808445C64640A16142590A0DD982EEA71DCB122D1FCF9458F58DEA539CD74E83A10B935698E6F9887457963B407D434B52126DE56E12E56643DDBD0DECD749F6C42DB19B6AB00F750257DA25B5310AD0DCAFB8E38493898EBF7C0493BE5244163001EA2BFC10CA8331B423094FB78A71F8639933830D8F8A6BA295FF20DF9890730B18EF206927B0AEA93AB4210CE7B061E64F8584A3719B84F9DAB14F95AB6FCC7B7982C1682B6E50300CB64AD2DA9362AB2B31BF273E05579A9493CDF007D5C3F62A23FED9CDF57C154E3C7D1D2CAE79B39A021CA488FBC06B3817AD6D2637830B8DB69E38D002AFBED69D00371FA06D8415D6EA91FF79500C2B04D4DDADCF91C0947FCE32F9ED2447F0ED03BB0F489C35F90E7B17EF1A95A5F5C99CD4CB04F7A949639F11431A49679470F49FDE30AEEA26A0F3AB009BF3B89FF223A2092D40ACC32C47E9A2474C5A93D3C0A8AC2CE633476807271C13EF5C3E022636F87E1B6854E1ED156B0C193BA901BB74C6E60E74214558E576B67E4D53B6DFD6C6E351A3F940FBCA28991706CFB6CE20F80F62B4A337E2497EA70826A6264F128506AAA2C7F408E3A903D3F1D7FB2F8F72590F9631F55A3E55D7DBAA9CE4B6FB4CB5FC828DB7FD9CD525198664894D1A37AEDEF1A539E93E5729F95F76885EC45CF05D83774ED5EC524DCD421C6589EBB12712D14966EDD08BF997BB8612D050A12EB510ACA08E07129B61E30605FA77BE1C3D8A15A27E7D2DC1B3F81D3206CD6361222C501982D73D947EAA4A93FA2941A4DBF05F03CECC25D1F6CF7A563608588B8E03635FA5A254D3994BF062DE3862DF9F8E2B97C01FDC3DB009B299108CF262F6DCD00463F1FBED33B96A1593590BF81A30CD2F8D41ECAD7038301D4673915CDD4F937EDD166FDFC7790BA20693998D6A4B186FF5860B902D53A70414FF20AC7F89C883938C4A5D4AB1979BBEDF09DE309235C8A94A6755C7FAECE66B81BF36E7EA59F9D8B08A987AB6102D4B2FA04CFA3FA9A6008373F9B1A800461094F0896CE1B94AEE7096EC7A608431F4065293546447C8E1A848E31C632A54F014B42F81346222F0FA1DAD0EAF017CD47344EAD21DF73C2C00EE7052F35C4702690D0B5D8069DEB44BC3BED23BF6DFA460A758BDD29A4C415635FD4BEE274A69A277DD2057F2344723CCF932776022A82279C710605674DE3B783B6246902B19CB3A7E293FEB723149B0FAE1756CBB8D472A9D2B713CC44E38048286C0CEE06D2802A7290118C8B40E8859AB23FAFFAF6283097E2532FF48786CCB9FBE1379FEFFF6F4CCC96A21EC8E1AB218B6FDE46F287F3B123E661C71681AAABA15F76C0747DC050AF3A8E72607C7A2CB6FA8A42721C8D1506697F8F2E33DACD6D779A6E9167343B19760B86BB7547B09C2623412D344086C2C88DC9C59E383BCC6B38F78068E90E69804799B885DA08234A6DA74F599BE425738B18E4C45E5196AFF673B3DBD6DE81A4D2685AA8B474E128BE141BEA3D17D972AAD1C159E7828BE499678C7316E1C0108D14F9305297CEA54982EAFEC308BD2994C2C3765BE6B3CF4EF7CF7985F0EB909748FCA242BDD65DA8B279786E9A52BD9846E884B881640F1DA9569BE33A7431BA43FAEF27C835028ACB63E68AC02AD54FB3AB9AFF1C8194782641E2EEFB8574D6086FC5021245A9D2B5570A4850651605829D491E8E5A63135C91DF65D1C24F3B12B35A1726320E96A4A43C6EEB097B9E4F5EC83F3AA88BD15EDDFCC847ED1AD15332A86828C7FB85F87C1DD2BA15E1ACEE80A0FE5EDB4F0DD18CA4DC95703A24B91A98F2FA2A327E7AE3856C5D8843F08F3AFA75FDC443AD5D35C385AF150606C10FF4F6ADB5C7E25DA5BF317EC8DDCC8F7C8792E80AB6E0683EAB2C3CD5F48F23EDC5AD4196427F462DFEE7F742A71B594A75AA70F63A71B4308E0F8FFC0A0934812F959E5C12BF3F38EEC30ED74936C3E23E31CA3DEF3658776FADE8DDAE0DF6E3B9AC3372002C4E4C3E73B0CDCC756913B22970E4B9D2BC88E1C1BDDE37A840B54DAFC0B1BBA8C467E968BF78FD59A7A0C61B03415569AD9D0EB8BC44E3913CA8F980F045E7D52332E778F39363B3B27959F33E6574FAF8BEF0836E49E912F9245927599BA10BB39E4758EC846E146BFA643BD53BEF3124F0BD2EDCCB302FC18CB7BE16E8CBFD279520A3D58A34EFF4FABAB36344CF25DFD7CD5ED029CE63F895FEB4EDDD9D6F26D945F1E985F532638464305195CABB0D3D0B2074642AAC29A4EB966416769E76A9F080F3DBAAAB387F5E49C3A0FB95019A548C51D8F09D2A05E266622015FBE1D6D00B3C88F2F32DD790CAC516B2C2E6A2948782AEC0396A2FB6CFD9CBB66917E703C97E8EBC50E47BEC61FCEB300043E957D236B0AFB15A937502BB9DD8EBB2BEBAC3AE44CA43EAF48A3E9A3FF65107F83B4D77F7E39EB49116DEB83E2F01D22CC1F76AC1E69E1AD6C5D71B453FCE314886C31EB06503D5AB5DEDFD9DBB33D39BC3230167B94F4719F043458B44B19800CF6BBC16802929326432739EDC2184B56608E969DD0171F323D3F6C6F797C97FB02070A0D2A4F6F869698A7A8AAB5BDCF0622373A446C778BC7EDFA000000000000000000000000000000000000000000000000000000000000000000000813232E", + "reason": "modify signature" + }, + { + "tcId": 5, + "testPassed": true, + "deferred": false, + "message": "0B36AE74905A488C25C9BF47B4144E12E75A8F54555E1943E3CF738BBF0B9C4ACC270A71804B0D8FEEEB0451AB504027C853125BEC7E7216A82EC09EEA3778291A6B97F53B1766FAB67CD3C875C171A36D5DC23835B7B5641C4689E646C40CC2B379131DF4AE848B8C4713A1E38F5C31140662F6F92BA22E888CA3C0A2F242C9", + "signature": "279860C94C551A0A0788099AB39F1F25BEE8CC4622D20DA037005B8D6B5B7371B11BADFC236C9B0028868DFE74A9AE59642CDFB8D38BA5A79CD52278E554C25B07A07C77C1420F8F0CC08A035C99BC4F0C303F20CA1BFC0E46E9FC6F37FF1BA5E5653656B7FB488C3B600E0BEF9F4A553A3D2FE5F0D2B76EBC90C5A2A99B789B55316ABBBCEED0EC70325CE2E89890FB2A19E30E79C4E8E619101FC2428D9579737DCB3FD76947FA7BF257FAF2FCC360051F55912F051DB24C51619439369F13F34D669DCD5638D3565101A7A4D379105EA6D83163D046DE3A6F9D9036CCC347DDF8B363E873D959C33D1B56775914ABD50EB6FD2D096E669F11C288781681D693A3A52188E80D0D33784D2F5FA1954D72C35D8929A2223577F8119CF241317D0E95C615641F40EEA3368BDA7619EEE82BC4B78717CE9E9D7036E0DD7DFFFD56CCC29D4F0EF46DFD4D07E4838BB513B2EEFA72BBFA0E9FEEBD1D2B96D9B8DBCAB4241FF7AB080ADBE1099AD3CEDC4597B23171E3ACA2027CD1B6E519EF29FDC21CD54EEAC264F4B2CDFBBB8104FE81C3C65691B0C309C31B877BF0B0DB37C6F44B9A11DDAFFCC40CEB1E78D2F86C2A0F902699EC1680E46F94DECDE4EC119F7742D3D47A383391B8DFD614E375B8C32271CDC49F054D2C26DEE4BC60C3A474888642DCD4BA1AE30CC8CAAE80AA9FCCA55528AA33FD4F732677E7D1B9E320247B299D6AD384D23D4E478AC2450F676B9BA27E5D4CB01F0EA50A62A2136DC4C2E1219C0E749444B2943890F36AF1EC2C273C42F22E0AEAEBD31FA8E6C9D1B8305A0AA8C2BA6601CCF28F46904231E648AFF4D4A72849A8E1EEDCC774FFB1479897C1804BB035671E8F90D462E3D2665B2A75DBAAD3BDB00C13E642A23E84ED48CE3E9B1632ABD0B7D579E7D18F508F33DABD97083EABD3CDCD1C70523A969B9C25E4011742EFBA6B3A09CC6CE627CF95BD51856DDC8C295DBBE180C86E0097FCE5741B3F0F6662B486D1B17987C3C47ECB101DC165372CA696FC477860F3DB7A68E3102B5A91BAC2A256467873C233ED212C7537470BFE88B41C3C239B5E38230E20CE2C41EF2C355884CF7F46CCF0CD688DEBEE8554D118F9088B4F807F19FE17732AD3C145E634CFCDCFF32A54F1C1D7A7879E6C022281130FD5A8188C560658F1AB6AD3EB3FB622D52A1939FE8668F2116A05F6EF6E1AAD846A4279FC3C699373A2FE17A3E9823FAA11F088846B36F5DB4BB9930101D5025350462D2F4866BB3010D9474B5630BDB57E71AE4277247DFF67F37E3CD9BD1307035249EB1EC316D25F913AC4B0BBB21D60CE2F4ED5F08D48D0C707795C177E7044E55D438AC12C2DB918C7087388650AB4AB19095C0A480232B1BA0C794991E89A650E070A5B562D9965C467D6CE834167EB6189A41B58E91685A034C70CD7723840A5561F0F751AA8F382A3772B07864547C1862E2433811633C97F58F85B9B14D3875ADCE2494D8BFA2E0773BF4637EDBD96AF9BAE43497CE2D63D59640C7723761C8AFB534189509A44794BB98A6D8E4AA3C5C3C136AA1C31CF20EFF2F5968FE4E71415DF760A52EC88BA438EF6110CD7F3B7FBE53B13999DD3EC4FCB5CFB4F9744578CEB60F800FFF2BABF330DC20DA5C128282C924244D9E5A18C3AC59DCD0D953156E2020751B708C0B025768963EDCF0DBAD16DD68A792A5E30981F17A4C355AE3E8036F9E289EEE35D9EF136AE402B4AFC7DD04190A8F0C8F66A66B701F995F7869855F59B47634B4A1F9E715E5059371B74D65D9501CA814F255D6C4D861B5C5A903B7ED44BF55CC18DB3CEA98D7CE951CD241A661E823F0A0EA92FA33A23294338E6F96D273DAF63BE9D5D5BE92FFEAA6078A9E8C5CADCC8AE79A1D5FC384519DF06A5832CE1DED5C7A6E937E86B854ECB1043169041A4BAD0FFEB13B0017B5BE16091AAC3F5DEB017B01EA00CA323AB44CCB193063406C970257DE61FAF1EE51105A22A4703562DFF1230AE241D67803FC6D997A1B016A73CE4346DF97F8ACE220CCFC3585B8307CD4B3AF74F6E0CF49A33CD5F5E53D04A197B4AA55ECCF645447B6033FE38DFE155AA979B2D4586D5249450E01532334C8F342BF81AF35980639C7E0AD431F3D3277F21F33A0622568E08D75A97CF2560826EF3DDB8A1E421217EE28B82D3BBB6FC499AE696567EF24681D482B051CA65DF9EB7F59965F03A68976F8A2542A58837CD3DA9EF5F4F06F94313B63B6B25EA67B1ACB4A0015F026D6A683BF533C3F730CD4D8A0CEF6D63100B4D9A1ADA15305A441A71B829AB2D33D3D209B598E05F19916569FFD262EE5D4160B8DF16E3FE63AA48029FD4F080D07602DEDC1B383F286202C287844D4063584087F29E36D5C19E54CF37DD504DB01452340D937D438C0E63EC35F948A4681D74D54CD6AF91262B075F55999137B5B94A2FE4E2668FBE44F68A892A91F8B5AEDB265BC0464F62C768BF346BC91AD9F9733E3DB9B846E2DBB0FEB3D00D817DB052C69474D77AAF7DCABF21E137F4C4607CFACFBCC7AF1F27BAF377B261358C7CD69394C33C89ED66F2579F29815B1FD957553FBF4F9FA4A5C85C223BDE78BA0722375BB8E7B02FFAD17DD7410F384A88DC0A77CA6345AE26A87FBB4753FCFB7EEA6ACE2061694746C8BE7E645D8848C5742ADD8815DD48AF19021591C7D7DDBF2DED046E7DF36F092127AC47432555F2BE60060433B561E7CEE0DDD1C5650B92898C8D6E01531CD373271A24A489D95FF24F4B4BB06AA39F56375F4B5B5BEEA5F4E5DD3B918136FA98AA2580A691334F8082DBEBF34943B27024C69C897D31897C2690C3D72C22133AB467E0626A4618FAF403A63DF25E2DA82D1191787D6487D87A6985F619CD6F1B7937F06E448501498DF0A1005D408D1CBD943ECC4EE03D038C5ED1FE462540DC937F0E4301502228D3B3755E3D31EDAB96D03AD1AB3E0A631AE80F86C3AE9321F35AF90F8D4D9B2B431BD529E2D29A29FE066269FB90248265088FBBBDE99B24A0F38282847D8FF4022AE6B611743A5B5472A4BF054B95F2CB09EA5E088E8AB172B7C3B53BB32986FEC298F41E2FA9D53D6F85254ED489A3F1FF01C07D33DEB98CA4EE704F27FD68F47B2E995E6706FC8D02454D7F2A73E50CD2AB15F973C9297B3B4989393588BB6C6CAEFF67BF2E241A158EA96C1A2FAF13FFBA4358A38928C2FFD0A7E32137E83256941DE749DFED36C63F2D07C557C7AFDBA351329899CE6D96DFD3442725BB1F24EC43EA41B4DE9E4E39D17A6F26384168DB92BF9516D7DD8101B970B83F2A2F323B418385C3D20410122D414A586970737BB0B1BAC6DA0B183244494F7375799AB0BDC5D1E2ECF3F4010C0E0F3537434E5366C6CCD7F1F20000000000000000000000000000000000000000000009192B3A", + "reason": "no modification" + }, + { + "tcId": 6, + "testPassed": false, + "deferred": false, + "message": "224031EEF8F5E31DB25B2D2FE2312A8F169D8F17DA7D6A0AFC7DBFC2164344FEA82BFC8D20967D96DD80B5BEA1093EF3D32DCEA654DD781ECD5185758CC19E6819CF382124FEBDE443E3F4529C375B82F34C83B4AC5DCDE04C208CDD7BC17AD2D352F6FD8B323F57E27A0422BEC53F5A2E0036079372BA0FCDC45364569F5E48", + "signature": "2CA336FCC11BB4D9A3F6DDA5A8B1A03F39E2C6FC5AD45F294DCEFD35EC61464A7AFA41BD258F5740D924E7C7961C8CFF7BA028D05B5375E1483B51FA6B5DF83B30BA4FCDF6618B6A261589E019185BB4D080A40927BFA3A6068BFE7CB849651DFB1FD9A5087213C6170A0F052CC374DE843E784BA3020552E6F317A229906C7765D4B0F9EDA40281758A365EC1CAC3C4A988DA93857A1F40297A1BB268E5313577463F26355A241D2035AFC85867BD3D2FEAF144697090E873182590A0CF1A70010D1BB5CFD3A9EBE9630237F4AB17D95376E344F310E2469320B2C6E11E9CFFF1864669DBA775FA6B8F6B894B74307A5DA310013CC5491919D03FCEDC59E92427A61196744BD5432410DD4F542ACA46515406EFA08052C3E64CA35C1F0091109968E44C2353FAD3727CD15B058BA2A88B862988915FEBD10DB8FD515D5E4DFF0B4C212B74839C50C488B0D8D52F47223EEFC87793D1FE803FF7EC1B6B984E00DCF750025D6B58403B8D274CEB877DB39E00F575611738C9B4F3468C23696E832CDDB0F136A59CA7E29724473EFEDE9C2B645ED5F109CD5A187AC21182A05E6B5A121EB86B1F26CFEDDCD96628EC769D6A839AD31C1EF817F6CB3DD9E2332E13DA61BC1AEE42BBE645C3268B1A7AF79175026F78FA757E058B2385D598AAA9F727B5F2BDF93F71D1E2007A53686B464BE838F904F067ED06782C7A09761D1A0D679563629EE353AE183F6BA7091B3BEA4230B32CB6C404A4AD735DE64E042735C5D60C800AF870D7E3BDA384F2D033047FBE85755C935982A5D84684AD7A068E2BDF66ACCD48F35C1F17DE3D0DF4B974AD3615FC9095A21300EE8AF23B91581FA4B596E9E3CCDD82BAA694A273EBAE7664052BC31983730E8B12E07A8024749186259A3A5B97FBA2746DBEC6D44120150795E99760E667E506C93A5372E55DDC84FB9563E644C8BC8B413BE27CE6E479EBCCE0B02BE7DBA69E91942DD00D290C9FDC76A96776C371D1627B985BE7A5D9ED1FE18508807AABA20EDBE9768763716541CE6CB3C1A7C9ED699C0D52692718D2914AB91C99056F31F0FD16C28D6892CD59B4C183DAF46D0A9763E2451C6698B93E55DBC617F25DD528E783BEB671F96E947B487AD9A0517C19C4F47A41877B955AE97BE095B9D650F1413A31C10ADD0AE047464E1CD5EADA4A3B93435210EB35AEAF8D395AA29B126EE2E9B9EC9FF3232A96879BAEA38395B7AB3AB866BF0EAD9A4241DB5DCA8BD0377CC9D6D772321F5EC6B47A9CB94C4D9F2008663165F400AC1A16E1BE2BAD0A1C3B85A2FF909183359528F6B4F43745625CF3B6EE4C71952224D057B653295980C6FB452BE01078AEA2FC5A780F10D87F7E1A12454DBEC9537075289FB178CC3FA5723E0FF0A7BF2EDD9A009FFDD5DA9BE606000B427EA2E7616A2057D8E395285ACD47FB7B54014D50A6FFAF463498117A19FB5E2152BD75E8F36EBD27BEE3912136D39A57414474F3D670A07761ACAFC0E2735080D9BC781CB7F3CF7F28CF21332558ADAB9384F22EACABC8D4DD7801256BB6835F12715FA43BB72F2C8F9653ABFA35A72B2EA6009EF90C067142C82467FB596EDB8D4301DE6D60D90CD474464466DEDC3FFD086312DBA730A589FC7A8F62369AD00BCBF89C1417DD9323A5ADFC0DBDC4B18DF614898BBACB73A2DA5F1E71F25CDEDE5CBC4AD32739911E8CBAF9496402A17DB96C18E3AFBD69166BAA8863C76353D053204897EFD95E3599468BAD7A7E2A91679316472004768B962C026D7F139BEEBF00576478AA1C8524A87AE96AF26592947272AE88692D1D8F5314252BD408B4779C2FE49AE3991F59969FE9B55F02EA45970F048D520D51685D84614890003E827976089D3124E88AF312D22135141D29755F0BC040B9F3B2B0476BFCA69BEE23F974FCCDBCEAFE85DB346139F5F8E004CCC0FBE19EB0FEC0E9427C528A2FE1E2B7E03E8D7D8C7021D5E44BF45D0AD3FE388FAC30606E6E1EC6149BB3128A8FC13595D635CF8BB1B52C6656019AF80C49AFB6535F99B8B139AC76EAFAF918F3B6ECC96EEE29EE1B0893EF8A51CACBC7F24DA9685E50E5FB938006B28C70079C047C61011AC289763EF2E5DACFAA3DA80710AF393D01986978E894E2373F4E9CBCDE51C0FA00C471A4A5C44F41D25912C6B43A0BE14A8F608189E3209D69689488BF0CB4E4B5C289E589C662A16451A0F0A849FDF9626073C3DBDDC893BC41B2A845891DA6C1F5C8F37B5E8AF3F2E7F42C22C2E28ED25E1CCD47C4C2A337FE704784CC8886966D2142F2FE8F3AB8DE8ACC228C072FDCC0626C52196E94BC926AFF04CC14B70FE5DD12A7DB2F6120E3AE6143CAB3B0E8631CE0EE90D5BF507312D0009257553AEA15AFDAF81779F0E84C48426103BA189184C4A71B227DF89CEAAC7E4DC6F103441567B7EEB92A7AB2576EC0FCC0275B8A9D3588B909CE3C1675094C0551C7CE0F82286D226133FE8B751204E31BDD579005F7605B7C6664638F4FBFD3C1F8370C07EF3E70764D12B13FEEFB6459B279DF1ED2A40E9B58F84589773F0B64E10815E7905E476315152A228E1E024FE1471C8451473DDEE11F04C01DF26B8DFBF529F32E022CE4948995FDF79A95FD462C83F38AD7568639EE078B3DF84ECC0EF17F8052FF048B5F884F021468A319A2CB65DA3843B9C28490317C8BACD42193DDBD5AFDEB9A6870E955FE869ED76A4BA41AFC65901C0EF6BBFC46A26A619E04F8F549B9565BB1C9545075522191D5993A51AFCB448AB9E888FC400A060803171953897046D28470BB0E73C2B308556789522E3514E84347EABB6744E7052123343AFA90C0C529534A389E561B87774F1408E8C28F669247C93813CF680CF8751749DCDDE11134B92C76D6BCD758FE9EACCBF165CF0D41269495487BD3C5D7E85890F00718156B4907DCCBCA498B528E88DA1DF08B1D7D3BFC4ADC9F30DA8182E9971E7259F9958CB3F8B905E27513332A6FEE7BA3CB659A68EE15FFF061BC567F09D9E53BDF2E61D3133BF92012A3A54A5EDF5093E6871FBB824408AE33623E99E4033EDF3CAAFF1DA1498A235C1DB7E02B18151C045427B701586A396A69A9335BE8A14C9C010E11969AA2BA26A64739F7015B288029466E7479F87C938C40B46E456D6242C107488E2B272846513428899619DAED1F5F084879763D330FD8E7A2780DC57ABF27EB91CCC2F9D704545DAE719AF611D06E45F5CE1D6D3EFB695B5F6F8E7CCDD394EDCEC22051AADD5C069ADBB42DCA5206D50A95C77AE2DAF141EC8B66ACD8161336B6A119262A2F545D6269ABBEBFC2C3CDE6F612182A2C2E404E5258646D74757B8D92A2C0C6CCCDCED4E4E7EDFD071B20222F343D548092C6F505305E666872767C7E808289ABBCC7DFE3E4E9000000000000102B374A", + "reason": "z too large" + }, + { + "tcId": 7, + "testPassed": false, + "deferred": false, + "message": "8408024F21F9BDA5DEC8F651A4FDFB30C7C427B3C41ABADC17AED23818BE04ED6AEE3B9B0DEF2C5B7CF59AB4678D1AEE0DF7DD537F7570C0A4103F4E553A9B797D5DDFBFEC0928A518A62834DB5EED56FC2872B338824B4AAD28A535944502A529761354E4161780AB15D6CABF1DE84945D49357DFC5EF91B2C4D50389D3BAEF", + "signature": "3A7DD5B02C1CF92484C244796653FFAC9F084F2F04AEC56E362B9867418FF3435B321697D50940794FDE228B4FEF5492ECCDF59954157E3B2288EA9E880F16D9B1EA67D50D25976E5F32D14C2CCAE68E388FE6AAF6B349A379BDCF90FC3E6A2DFADCD4D5707D0EA4E9B4956E051407F52112C4FA0BA8F11E787503268228CD2E289E18F704237614B2D44C13087FE46E02E5EB89108565074FB6BF1423F69ECA48D051ECA83D14841B8AEC3C05F722E38A6206B79E39FFDA6033E36E6A794ABC84508D449B64B847FEB5D20CF56FF1E2468412BEA8106D66E417EE48D1DBD3CFB167BAE14E593048CD1B73A5B0399C1A7392C9A82B4D4BB62B4915FC75DEC75F39C029F31D379ADBB872312DCCDCB91D17E2520CE4BA8F41F8CD3D33D6EBFE9F9E7396C632CBC27D7AD3552C58C27A13FBDB1E9C2C5BFA85A66C4CC206B719C4D2824BFB6CA59358F2E90B40BE4B90C981527A08ADF997B5B0407F7ACA27B2AE7FCCB0CC56E43051F6ADB6B27D1656D93F4003C30732B3B16E227C8D3E04526715CF23C4AE36AE3CE011CC3FC4040FD35137AB8C4B007AFC26311B32A540975BD79BBEF2303EFE157309B7B60DA66E63DD3A202FE46BBA0AD37F49F2452523972DC59D5CB37F976463973518D05EA823FE910D0F9A32EBCD5FE15B794573899151E585F305320BFFFE537F3CB4EA229F9A7425FEA85753BEE0E3938734921E55395B1C534E85B0568B817E53A69A3D835C8333F771D9F0DB43C40D33A6C4F663B8A7F86D64AD9CBF185D4AE386C2ECFE8985FA30995E8ECF2F21E3D22640E2902588C879DD85E66E03F0B7B36E3889A715BF6310FB6D32655BE7BE67F2739CAF620BE33EBD135E139FB6BC494E23C744F1943CB225D3930BD6A6F05F4757D88D7A06FDCBE327EFED6061A66B66C41B10EB07A4D9B0C20EC48B6B106BC32D9D892421A169D0D90C27C12E8534DCAE38555D1B2164261C1770B5091CC6A2EA35C48EE5558B26A741D166C43FC9EAF1D7F40CF1A6B7880037C3AE0118F374BFFC09B2842B91CD8EE1BC526F2ABD4B1470DE4D4D2B8A993D0093EA75CCA353669C488E043B926CA7C8C800F2963112D931B047C9755CE0C6C4B49DB1788B52992BAF1FBC35A10184DD41D1A134FB4C47B37275F0ADC9AAA0B66828A3C903D333B0D8F423A71A2C4BC7281B1E79AF89CCA0DD3D739BDEE1DB0452D2B37C45D5271F414AFC2352D2AC5588A3DB02DB60417455CE08FBBC440FEC58A058CF27E30C237F84C202B3ECAF3471A65D9496189CDB48629F285577B69DD4C1FB39D697EE33F974891DA644DB9432F91A3A57131B803320E3FB26AA87F41780FF96314BF60D657902A5CCE713673345A93CE9D2429B2336FE9B066E080859DCF9E6A8F53CF460A14F51E7BB3D79C04F9881A1F3810859F23BC510D41AA2CC1D587687D75750C9E028E1D2EDB28F3732F81F35D7F2437A92D78F132650DB653EC5ADCBCBB7FA18549024E6AF37D8B663374CC73FC2B0A648F50F9FBF7D31A4174635B55F771C1CAB0F5EB9A0EB2BE7037D56C1A2E2111DAED6C811957C7192784BFD6E73F469F13122274A96AADCB983BFB225CDD61DDDA7DFFBD35F6BFD2FEA9F13F6CE6E1E41EDA5EDA64E816C7A11FC272B3426E8FE331D2D72532292D61350BBCA519D6168497D8DC9FD38783654F569976BB31C4CAB08E7FC0E143929F1860343FBDB79952007F71408224E40031C871AF60F040262C54917E3A5FF6FB907F54A8A243B8B1616D4355488E979789A9797CF887490542E013762DC10D02636792CDE553906A9567A3C4DA2F82317662316407B3106C9B03B581E628F1C6576DAB45316275C1476070417565BE835E076148D2CF15C0A1709E678E1B45F89574C4FEB1115CCEC6478BEC83388D244951813ED4D23B0017E02870412C081A79E4AC515EB3E99C65F4905FA6A061383991B0656535C461E18CC5D0F23BEE21D3C89859163451D60B7CDA9D674BFC1862266C09BC28A25B5CA2191380565DD870E06CE930EBCC844DDF54E05B3F17CD34E031452741C05F90985A45A369DB87C237F6523DE2BEA9075655C1B083007065A083B1D010F6A69A9E4E1BCB0E79ADDD9E0A47420DB96CF84DD34C3444DDEFFC2D3E5E2400BCA8242A46E1855FDDA2E5AF3C730A07887347EE14E230DDB58E1D57C69508A555BC2F2CFA218725DA0F913118D2023923C834F2ABE3BA63148D252E61F8232B7D79AC01050B9D8A24388ED265C10A9F23480E55D532B874CA9FBA496C8067875BB90B9A29F7DEBBDFA27AA5F3DF4EE175783B542ED4D880141AE992EAF080BEF83E378A9905D307047D1FAE932D284E2D54A91C0871A1BC7594176285B98776DF3D0E0592494B8682D1F8A15AA461AACC46CC4465DEB060FF8096680109377BDDD4C43B1AC107AADA2D177B480706D9E7587E0FCC75D37F338021B2F3B1B5857C46065FC3F6563E4E04E0740A8EF45FB332766D8395FA7B51EE29E350FA63326C157A50E81031BD0A8F3E48181C34C2DDA2A907688601603B88855EB5E0A366809CE919725D9034DD33FCA05A6265CE839261EA286E39045D77A9B46898032E486058841CDF72BC44420E28B8AA3A44A03D969F8C1444263C407E747BBED65DFC985A3800BD3919273CAFC0E88654B5625F8DC5B6479F8D10F39351D570752D9541352FBAD34CCE44AA8EC3D2FC67C9F052DD1555B11E2E51D95571A468F29BB2A31D2EF9314E131ED76ACB1CBCBF60165A26F14E5FF25036F0BA03A29F8A382B33C042A4B5281245B75EF2ABFDCF899481ECDED394BDD8E9A41DD554B1F847B429D2A9254EA15611174453188F2475AEB692F40EAC3E4B3515A8598815372BEF0683421E174242AEFA4C1FD10CD042A1C6F920840D8144A9CBACA3BB15E27B20208BF6E8CA153DE23687FD02E570165207CFDFC10E37D73F2BE2DDCF5B7286EB79DBED8474CD2B69BA04122FB73469E66613E36B6C7953526D97B92246414023A93BDA49979F75613B89C47B0BB4A2C3AD65688857159295DF92C32CCA2489BC0251CC3DF0D42BA777137A5E4BEF845C82B65A9FB8ACE89AC1005A00581010B2BD446A965BDF81EC216BAA6C5A6AD4CBEA18E2505D750CF67B97EC9B97A7008BB770F90BEF9EC3FDBE2D0BD0CC43E046D56C2884EAFB92137521AA1C3655AF5628ACCCFA150AB517538F8F293941783354002F243F8E7F1BDB19B8DD81FC7EB5271C3453F8FD9F93355CBA53897FD6282CBC8072188A18AA6A77E24FFA3998BE511AC7728FF05191EF87DE78BDE35A9661C4B51537C8689909398A2A4C1CEE9041446505C6885899499E1F801101626334150525B7D8EA2AFE0E5E700040D181C21252B353638454B5152565E6366696A9CD1D4D5FE00000000000000000000000F1B2B45", + "reason": "modify signature" + }, + { + "tcId": 8, + "testPassed": false, + "deferred": false, + "message": "422DD79F96671E4DB6A498AFCD51F8D13017391E0BCC3DA960142CECC7649C3A729112FE4D9D5E14EE1D2660C04770F302F0CCB702A61D542B253DF57C0D6ADC0558F63D45FAC2FCCF3CC4282068CE9D0AA9F93240A29368CF57F80F9A2E51B24647C98FE47A9DFB220D5A950FEDAC2335D723CDC0B123CEE7DBB8E2F5E40A29", + "signature": "8A93A49DE7D00822747BEF9A59FF02E2940753A7AF6F6DBC20EC14F685882ED25061533DAA209776F6174341A9C5B83BABDA55E6FA094DDA606DBC7915E5E5A6316D509117867381F4F69B2258ECC8C5564956ABA4BE7C80C0919C2F0319613790BFC54AA2E288AB38075AB5237B5A022BC8D7F1188F605DCDACDE318D4E2D1D1A24A326F6E41941E9105DC934E6CB1BC81A6ED0DAEADF8DB7E21D61148D5E46ED7E7449AA04B07936E7B90DFD4B875D3265B9EB5A370F9CFFFE2CCC0C74E691F5A1F673320E994CC3C2FFC8A1A384FE4C92D43D67B3174A2357E8E5D688456B366620DCF02BE7897012DDA1F9683658AC61AB34B6CB5B23891D4421ADED563734280A7FB42BF1E56962889DA2E7BD2F089E7D95BC365FD5A18EBD802D7722AFC6932C4B01C881E30766539B20A14801EE4503370B8485F7ED0EB02E2621D2E8D998C4B56ED5A9DF0F1C7AC29ED509E1A1208C4A173CD0ABFEEA1BD542468EA13C01B7A95C44B269D40F3BD0E6F8C1175FF28A8D43F2BC27E4A68C3D6F980C6455E1C3F4835874EFEB2E6EAFB0A9AFA0E35576B212E98ED67E04CF4057531BA4F78A96D507B84535FCC893095D28C87EE070F6C3724BA9CD4F79E464245A09EF73F0DB69ED23B73C690596E157C394C75C120D26B94AABD91A9A697B4159D826878E6BC8ED651EFCBE4914B55E9F65859C123CF2BD0754509C062FA9B9BA0588B71A9FF3876919C07D2CE5F5403E40B28FA51BB309F45373D0716DEF200F875CF1609DC74AC3F6C13E5C7C2C9A47FEED5AFA50E8FB21504BA7F35758B05FC351F5604298509FF1D44613741434A29D37DE8ED7303E0BFEBC014B35E610EB73514AE54CE930E13EA566721469D6878372791BCD22AAF376EFB73FBF0AD2D9213277678EF18B0FF2C2F280A140EBFD0909628BCC6E1077210022404E216224124F2A672B9A079F42D933B79586681FFEF7E28A1EB565F3A5DDB0282DC818023D1D30306DD3F90229BAEF456FBD5DB6D49A07F698F5E4B8F5554E08D14D9D670059E120369BF25F1E4E18DA778C94D3F8D9B47D4D29A42A08FEB7EBC0A5DE6BD445CD8A6E5B537FAEA2E6AF93177AA1AA7393CCD876259838401CCC10C9F05ECB6CB301CF7C59D103E5690A5BA9EB970393EEB272E6FEA4E502F55E9227D22F8BA16CBC51FFAB327A8DC0B634A44F131F57CE89CC4EE3F6C440FDB50A7D54B1C4BD6CD11D4A8D4F820BBE15997175346EABA1C895114FAABB489FA7541E0B9B117678CA9C745F52AE7DACE76098B5AEADCC69780F607E05DA018D0F9CF6D02996FE07DC2443C2DE8DC280557669B8E7456EF852F90BFDA9D1767F3132976E9A30758DB8C127C6BC173181E0CDC1558DEE0B897C8445BC12840A45ECA768ED06D82685F2EF907A90B60086480758A8F6D5D5FB1B5BEFAC7A33660B85E4A8A2502FBACBD918EA748B4870B171AAA498A62170ECB731CC7A6C14CE9D179766E433F416BFDC3BAF1E8635DAB2FE48CACA98597A766128FB1BEEE7BCD73D0E6DB5F24AB1BBF28EE8D9A8D00C70DA37D46390F1EE0ABFB5282A8B978C3D8350CCAEA2BD0D75E0C8CB10FDD5C4B89D418590DE958D5F7DD51CCCC9BB553C9FE5AF568914B3910A6F8BF74957C546DDFED572A6C2B8825492DC03CD516C6AFA1BAC6877A090618727B794204187E46E5530082F259C170027F521170A70CBB7C59CD2F62E1C86BFF439A368759857FE547E742B0814D7ED8BABACDFDB2CAC044140B2120255DF4B7C930A1B3E434ECD710C01E67F6A38F399052BBF59073D46F3AF2DA1462938606F364DBB00F5E7633694FDA8CFF2CDFA9F5C5D5E1BE9E67A6A8135B4132626FD851146C3702D17C0CD3EC0B1E824CB98EFC557EBB9E9EC17D85A99A797AA24B587536DB3C0CAD1444D0EA777680A3DA2D45B7BD613F71FDEF665EB334194A7BDC1290437FAEC0ED1F2127FEEF1D0B98E67038DE9131810AB1FC07F9B785E6F5BB5D54C0A75FBDACAE7C4C1C0DDDE98F514FD08D474C7A7ADE09A54C645E42044AF69D47B28C94C95CC21BD6EF867F5D4225EFDB732D17A222DC2A74F0A87641C34CD583786E8E11046967574A02D620027425F4D5AE34087E88DEF7AAA658C43C6E6AB9B008602932C7EE5A03AEA56E54CD72B80898BB56769419DAB7BA811667965126B6ABF260A75809BB036A94121E767314314B3185B3E6859EFDD9FA7622E24A39BC64C55DA5BE1A9C31A04CCBAAA24455589C15365FE8BA01E3B12DE45E3FC2B248E7552DF2D5A603F9AB97CBB4DB762C3198C9F2A5E200749B35891696AC5D14DA85B323FFCB9323664C10D1DDA7DBEDABA11F8753CF4E310257F5041CEA0BF03B4A6777FF4C929EF0AD1A08BEF3B12E91C542653060A5A420B4EC72D2A13AA8D67287688DEE3CFB8B2C1EEFFF045408FAF927D0865EDEAFFC57102140E94B5F808DB19F566CFC21629667EBB3712E49BEEC070FA4E361A28FF888DC58B4E6A26A8FE2E6FF8014FC9E35060853CBB5162D06F301B41E5D1D753C0BE60531A94CCC06919B9C0E96B40FCA2094605C98BA5F4B8527FC7801B93E0DC512F06A05311A101CB954D0B3D7E142B2ED010AF4E8FC247453BA33B72CB06B03E925F42A283FD71A0D7FE89D8FA465853403C40721E804C79025E533EA15DD2F67155E1963A66878669CB3751F0054AC722B9C0B18C1C9759C3AC0337392E53762D37A2F9C4CFB5049485B1D2EE725043FC0AAFF2D7D81E89B33C3E8DF1D0AED1BBC7D767ECB876D2FA46F310E5F31881590DC2C8F68D2042C565C3A89A7B41F4E19912C9A51E0608125E6ADCD5B18D2AFD01A68D7E1F6237B2F25502777F2E882F4D995C1D2F5A3DC96D12F6953343E70A46A0F59F835BF4EAFB1C37629B94A05FF4D5F6EC85E22E962DF3FF2D21D827439DD7FBF833EAD23940E6F6CFB2A9AB2090BD323A59006229907A72A6BEBB79835FBD95DB1FFF0138AEC4984E78BDC817D7E6FEEC791B56D9B51A2D54C1E45162191FF311A4FDD11C2C5F8843E9BE4019CE6FA84EB7A29D98E1C56C14B9C30E84FE2C35E93B93635B265541835DD1BF20A3D94D32F24E618391FCE02B98DA28DC4081AAF408A6C7AD41C249F2FD783A9829EA0808EBF0D4338849079A88236EB18F02501355006BF1DAC2F1DD1AA9AB9531880DFA90811EEE2E96792590F47F1842C6ABCD16A8F5B8429E2AE9A6E56D9D50C72AFA9D0329B77C8230E0ABD756CFB2CEAB0A21E59DD9250786ABEA3ACFDD43E18BCBE671A99F23E85FCBE2144A7559F88C81723BE12FA5CF2F8DF13300070E1B28444F566B6E96A2A6AAACBEC5CACFEC0722507F8494A4A7ACBFC0C7CA24252A4061838B9CAFB6C4D2F0F1FD11161C283334363D4465A5B7BCCECFD2DCF5FF0000000000000000000000000014213043", + "reason": "modify signature" + }, + { + "tcId": 9, + "testPassed": false, + "deferred": false, + "message": "1FF8DED450645CED8FF0207337ED352C2B2299E9E261C2FC8BA836507339C0742F9BC51A691CE3A015BAEA502605B3815717D83F4D768AE51348F0330472A779414778EA6F8C440461E6606C47D6457CDB3AC21BB301BCA78534A6AE204486752731266C818FBB19338B41091D1019BAF611788AE7CFAB68B3F97A2AA57790A3", + "signature": "17C9BE2E3E190941FB3A1A6F839FF514717F14B707CE8686DF3CDC4C111BF135093E7F3BDC3D517076DC8DA23F9B0C80D4ECC32702347A7FA169792197C4B11E698890B375E64F223F432D74E913578902520562EC8BA5C5ECDE089C459FEC420CA0C97A8FC360F98903B333B0F654A5DA3EA25FBD42ED7CE1365D01428DCA0F36A3C9E4C2F5618E4B28501873BDC7C85BFE8C604881CF342E3782B023A1F448DD4EE9154D8A04CFEE6E50E415B2E2D7F08E4D9C6235AC1FE8EE3BB1FD82C88F36B3C7AF4C1CCF0DF31AE690B72A1E58E230A34975BEB0F54C8CA80548AF0C2555CDE3714004544D802052091CAA74E6784982CFA05BB55A86D828D74A5EFD15F15D7139F8E604A6372BAC7E26D03EF9EF606A7450138A63DEE4552A601C36705A0BE3C6B44D6451B1482A87BCDCF52D4F5B75F6597AE5696384DDCACFC862D63A5E29530D60E5E47BAEDBB9DC1DA4EEFA08E85555221C52049EEAB6E6C83BB5B34FB70627CBCE826C9429AFDFC621861D3C44A8D64DA2923DF55D63465B5D93D68BD195B2980B41CB4B0F3E2B2A726841BA149AC9A481018B137E92D61DF393D3A423AB3DC39FDA160069F255B9CD92114CAFE892425E0007382004DC0ED746DB396CBE25D591D8766223A40D1292838CF3F89466C914B3292BFE1FA4CC5E6CEBD992387016C9325E319BECA538A8C42F1D4A4FF11A96B655C7960649ADCA5F42E57031586B6967C4F50B2E3E60207DBF03E5C07C4B4F9CA13F7ED4DC46ED2B4249389D4569D415EDCC84528DD38D1E7EA8CF74F7CC1F0E23D3981C0FB463E27DCF8A80313F39F3A52A11240032C299E767630842976D9DE2E9B3442A244BD9DBE453F42BDB934C47EF9E5D800AAB5B4113A9ED1AE4FF59811652D1C0AF21E389170A4DC36E98A6EB811CCD56243DAFF012FB4332610E686C8E3FAE5F5824EC57E3DD96DD254A16A1D42A3318A2893E3865ED9922CEFCA582F82013909031C0E6B6E4788A284BC49044F48B3E0C10A6AFA0FD6A672B9322ACABA141D970DC975860A564BC8947D4F27F9A69FBCFF4304A05E2E8E696A83ED863F845EB9A401D2BF060A5D5063CB0596489B2B1B2BC3BB9859B9C47A6885466F98DD66A07BB52605D3941D271DC7C30668DF692631C5325A2D6BAF8164F779D39C9B8593B290AF5E4D6E7F431886A3210E892629CA5377E7144F4CCEE2CCBB315545311C8D04C8B6BABC5BBF8DF87700523E3A306607FDFCF151768FB2234686D2F3D8AA8E377CC3CC0A0EFE07A18AD203A221C16E3DE5AB9CACB2FF58F53241BEA58548518220A6A3BE12FD2C834793D39D1764151E3BDE9D1306647657D5AE1D0F50C9B034A46C39734C1BF676E1D855D1ADEDF9D8F109DD2D9F84659F5A267A1BAE72DDF211C16B1605170FE3B626F82DB76183DBCDCFDC7889B184E8211C4F7B8826DB146C12D937D73FCF616259C4C055C4309AF2BC4EDF11A7AFB4BDB5404DC3AE4B9E34426B21975364E2AD7EAAD30A86B6071AA25FF289A7D50189981B2049E1251A2DD602B1344B2F010DC4C826EDE01A54F980B8466001E6ABB527C5AD637AB7148607DDB800F174366D0C2CA64F8B00E35C87126F90EA0DA21755FD36CA879308538FF91494D2CE46C11BE7264768011DCAB2552993DF1A3FA6421444950F608E149DA05A591598ACAABD529B22F9BD9283FC036612B68415E72827717BE0BAC25601FA00511E919054B5E08A583ABF3D33E4BA3AA1BB6223447A7DA620BD1A2E47EBD1A9A2150B1C4DB831DD02987F1DB2051D9B46DB34D4DF96B082C602DA91E3FBED168F41577C26C48B32C929940879DF80408D296B2879BB93727F492714A370241AA86357C23D1728DA0C88B699235792041A79DFA6C11F09DA09B00BFD14310E56E60D3B0601191AE06D21C0357D8DB2163CF3EFDD87B45F54D007F89816C41CFA9B0A5DC616053CDB698545F7E99C15C8A3D4A7133FAA613AFBCBF50D69423538FAF9C65C19D502CB58B6A7E4E29071C9719A923042EEF6537CDC08C34BD02159A807335E20AD0A599BB605DFA95DE966962D23FDA3FC3BEEA023D0ECB0EC1A954F4F3303A4A8FB89B4A8421B5468EAE82284F0C5D8C85DBF26233B13038222BCCD6199E5DE244BD2360CEA95848319F4EFE70FC8E98FB8C49A1A151D114A528C6D0FBAABE2DC0E596F11C20CE836F2605EDC98F49C72E9F1BE0400B1152D2F85F171EE261845E312AD4B1D1DE166FE81E07AE2B97C0BF0D508C430E4372B0D2AAB07E2EA967C7BFEC8919AACCD30F271B810F6CED2977A407E565FFF83CA6DD414618C217811ABEA2141E47C482C85AC2293C2C392BAA9AC3443275B4F0616AAD4C457ECBA79DBAB96ADC06693698744E39B3A1F6D5801C9C9CF6870E3C5C5AA7E69837E7E8E58AD72F3C6363A18B7E93EE82DA43D383978BAB866AB156BF46408B3AA9095E637AF1872636FE0AE5C425AA37E8DF12E31C38E5A1D7F7EB0EEE5C929CC9290DD1C13F4DFD1A674A49B81FAADAB243CA1197BE9500F2B33CD57352915330577DB372B8B3D9F37DB178FFAAE4A7E39C696232A57D2EA249A2928CEAAFDD7E9F44BF25F3D1477DF29FDD2BC08BC15F2AC452F308858F5F6F9D83E6C0678E272BDF9D2281887BA1FA8D6D7858E0CB8A61FA6273CA6C7B02CA95E862ADAA91CD292764D738224E1E5AFA6A5E677E528F25F0C5DBCD873143C2FC8EFD5E561060EA7181601851ECBBF594BBD902976D3FF31E6D693A5BC2A97BF2E9D244077E8F2D2F73E1C9F031ECB735C3DF50DB16FA46CF424EA1C300143ED17B96F0BCF66026692EFA599E7C8B746C6D8C0EAF77022CFFEBF4CBA7BA5EE2C42A646D483B5C7F002ADFD08BF29FFED5AE3C168E1B950FBC04D9EF3F517395DDED4B1D54DB9E56F81ED1B162C56BB5AEE6049E7F3344223944AFE06C4A2A4F8607B7D751B54FCA004DD5F545CCF3A4C4C257812E9AD0860D4FB5D86D5DA1C3BF1AF84F731DEB8E3210F83267F5D243FBD6D287006788A46A02C1D3F51BA0DA9434BD6E0E6BE5D405B572D50092AAA542943C9589F4FE4B607F7705236CD8C5918AEA04604D18521243612E134DBFE9D2D5EB164557783B12513648F9D294036B06AA00056DEFE08DBE041FFA8E949E9B555367FA667995B43180E6AA797DAE894C84D7EE33CCFC93EC759D974D41301FE6DA75CEEE62E924F9AC939CB7975E9A8EDE2302203D9975B8B5A68D2638BC562A7C0E0888E9DFBF7332380971B69A224264E2C84561DF8755968477AEEB26B94EAF58A11F3CA84C2D7EA4427393DC090A0E151E2A30375459787F81888F939496B8BAC5CFF4040E313D495C6D6E7B7C848A9AA3CCD5DAEFF3FA02092B3F4B4C739DE0E2E6EE0E1A2A353961646A71858AB5BAC4ED00000000000000000000172B3747", + "reason": "too many hints" + }, + { + "tcId": 10, + "testPassed": false, + "deferred": false, + "message": "3A3ACE744153D62F1499D0AC7919A1ED6C1511FC4D70473A86E328CCB558C682BC3FE7F175E48C6D9CD177157BC2BF58DEC173A14B3F14222C4459CDC073008CAF4C6F38727FAFDFB75C3C6192737EE0B0E93FB6E476CF2C785A7124C443C9D8330A89FAA26F421E7758171B6B8C7D9E681D108A4C3496394711A8B49D2637CE", + "signature": "967170535FD559F7D1BD00172510EC12D57ADAFDC86AB4C8117840F02FE63538B963D3B4504C5BAF8FE27383FDA4218A5B9687A4326564BF8784297890B028D21CE19B29A2DC1EB9B2BE990D6A633FCF97D9AE42CF33AFC7A045C9469DEE6AAF49B4DC0092E95EA0F60D259493537767CD0A2A495C9BC2EDD71CDFA7EB021D0F0673F602B9D4915A8FF44CA197EF4F0AAE7F81D698077C45993E4188477AD4FA32DCFFB1AB759CB72B6B2E2E82CE7D9C96B04CD4C28AF152DC89006C2652B14E4D882CEF6037E394BFE523D9F4F8BC9C565A123645B96E9C83B9037F6B64956B84B257345F33C711274EE28D46D55903F56752F9CA2B5C983BB9AB1786199314D2417A7CD7A61527C8596E4033C6AD7C2DD60A1DE3E126BA9FD197D3A0436EE5DE4A256FC57A21E537C48911BE0580912BAA0CD0AA31248EF67531CAEA67E892D31AE5FDBCCC536E47E193B8AA12C1F36786F2C88BE923930B4FA4A8619B5D22E4F0B2469F094FE619DD4F6F2629D48C05B2C58E78BDAD42F2DD6B0863E1FDFC0C3B7F907942BD134E19A329BE8F9E864AE99C36099ED95F479456A99A6148448407E006F163AE5DCF18CB0505B7B9E981A7254CBB9AF09913ADF7CA293C1E468DC7A2F309266AA491C48686A6516E2450E7CAD0E126ED14D0E3AE919BB5DB809421020F208E4637B7714B6BF0E6E153BFDED992C371AF5445FD1D78512C75B14DAD92415048DB65D44143C67E1B8749AAED09755E9FA99CCF1DF388BF252894FEFE83ACC4475F1EE440D255E51B3B66B0E25ED9F6A6287913315055992CCCC4B24F53496D592DF92A463F094F36242B4344C4F2D30A1437F638B8E6989FBA82A6246D740948EC92F97C7E8155A7C14EDD7E7E06BA746054776973CB0C12E416B0CE6397C8CC6060185B04397F4E101CD0A9A9D9801AF6383969E796DA348132AF707F01474B545FFACDF1F72D0BCE5BEBBB9A54DAAA8DE145A8A7B3B2E77E87572A994BE0489FF696F1E7175CB48A8B4B0BBE600B7A3C2F28C88DFD9114DE4316B918C61B72E2D1C2BACF74E20C696D17F007CD0166E691B8BDA303525467F8BD6AA007C7E65112B3B82AF99B1D2183E69FF78E41BFAB098EBDA5760B0D95B1A73260149AF6B559AA6452DECA184CBEC6753835DB478D3E24C179261053ACC333C0401C3941E2957FB700889BA2541E88A19029C89DBB3B2083B85D90D7652F36357AC00A256B14D7FA8F825B5E1463F110B88710F3C77A5AF468A9DF5170EAA2E449FCD5F122E4C6C4DD04A4853531B0E4B4626F2DA3E49D358BE15A7AFBF677CD84D4EFE99304586C959BD23FB345B2B10A968A70240683B55DDF75D1B76DF5BCB2265E4D2B48CD283BB9850740BBACDA014CD71355A737543340EAE3CCE32B6A85FC712C7CBBD6E09C40E070C6DECA43351B114B5288D81F09FE2EF3E120B02CB0C3DAA000945DB75B69F4CD481D7DCC8FDB4A23FBEFA88B31E9ADD72BEF59C182D6F9674822D40DCC0898B2202A7A41D9E1AACEC4D7C5E87791C14AFD9CD9B5D2764414E5ABF306AB09082322397AC75FFB1AA473AE7A35750481E95DE64FEB54D12CD2FAD1E15574FA5F159AE9E450FF8215B7632ED333E768ABD20983E73CB0D4D9F1D533098C86E21F73BF739C928874752F44DF1F60A09D157F49A0839ECD5AA00A6A62948E52D8FDC0AE1FDCE14D6732A2CABD22192F1CE599C7144807BE8DB4307D2A09B37E5A7160CF624CD571A73AFF849B1B13328E8128418C957888B57430EA12AB4392AFAD89BFC86299CC4B5589FEB47303099A540F63D6AFAAC6AED978C4A36FB4EA8E425F7CE11F11D178E4FC83F7ADACC1F9C69763E3F88A6F558364C37FC12BB0F25E1A22BA3FEAB13A3D418CA93C7FF8EEA6028EF3B5E8C3A76505C3355151F3480CF292ABCE382DE98102C4165EDBE9056B60DB75F046FE17C47FC742593A79F21C35FD928CE5CEF29951A2096D3A2B79C453B9C17AC1794F2FCE53CEDE0EB1EE299949032ED031451FCE1C00DAEA8B4B1439B2353287D5A6E0ADD3F44BD527DBC12D99107AF45BF8002BAC28626EA1B8582F89A280B7DFAD9D6067FF059407E05CEA63AF80BD9DBAF201369BF6304324EF9EA644DF561664DB7113984A27C1FD1D3E4ADC3526F47A0A43EAC82B33B81FBF72E2FB386D3B8C19525EE2C39C74908109971CFF2019144A5FA7AB96F6EBAA5B1E49A6266F426468E318EC81D4D25109E337E2D04415C73B181021CE0ED3DEC2CE028B4413E36649313AF07487B62D9FA493EAE16A2265763F3A9FF493A126EE62BB448EB677AAEFC614B2E78A48D7F1E11A13D555CA2A22C5DFA35FA7D8DC8DAC0BC9FB0DFF12E33597A5706B8614F849867A4B97F3ABD6E8A6692A3866C7C961F052F16D8058FAA746B6FBA495C26A9707C5BBD8ED04ECFE3F81DF2A07657E3DF4D7F34C1D93C8E37414E744CA927FBB6E8D00A50FB291F8E546256A6AA27E76ABFF9FE60EABC0A4F89D86B91C04220D1EEBDB80FEA506190A405E6DDD2DC1E99BA8CD1F1EAE073FF1C331A59B4AF83600473E66C3421749049ECBBBDBF1854618671C09B6810ED42DD43366DA42DFF7D37AC05D402B731CA97C800C125583EAEA5A191DDAA2D9F0F2FDF35252AB5D5DA15B102BBC5750FA6053885F99A5BD6A9B09C23B2AE95CCA5701511C4DF77ABC6F19AD2115F63A81E6CC5C82D86299CA76CCFE694DFE1954DBE43304E1AF252A15FCA8F6723C34C137EF5CFEDE5057457662E21809D17FD7FD398C5715FCC0F96097A816F7A9F429451D89CBBBA0815E56435C576BF22A027E450210AE155E84D32615E6486E67997FD81557C327027E30319828D25637B606957B10B61BD764B361F57EFED8FD42121542E1DE940A4F9FDF5B89E2DA7FD14D3CB9999F2322AB73689CA51DC6D1585169633BEF128FAEC72F3D3EAB21BEB8D5F07D5D883C32BDE6F6EA579ACD3FEB9E15EBEA9A42D5EA26762A376589C576F916B710C679194ABBEB6A1B32DD6502A2DCE0F3AE83CD677ED5E927C89B63CC26F0F0FB0A6C3561775D46BEF7A7195AC07CB2EBA43EA75FCB5393DBEB781E187AE8509FAD509207C87BCF2ED1F9467067E6DD3CB487B520F573E3CA8431528878B18E7CFE5ACF914EC0DB0B99609F7C9B306AF59156E58588028651BC73BA562D0343A3CC10318AA08C9C79A25799BE7823BBC8335EC0234EB42E52F7E420D6927FD8D19A676EEC7F0D535E9020A58BDAD870D9F8CAD9709CD0D24B8479AD2E940929BEBF540A6B447E46AE630F30C1C09857A9B2766D9F2664022E323A3B417DAAC1C4D1E020232F464B4C4D5053686976909AABE5F60A0B141E2427313D5269797A7BA5A7ABB1C7D7F0192025373D465376777891B8D6D7F3F80000000000000000000000000000000C1D3141", + "reason": "z too large" + }, + { + "tcId": 11, + "testPassed": true, + "deferred": false, + "message": "3DE9C8CDA014784F23C8CB6D41294D39D27C9A5DF8F8D939B6F2D821824E584BC0BA516037E100C68C02480DAD436E12DD095DFFE293DF8E4AFFAFA0DA05516BD579B1B03B2A43307C7DF0D88624386593B226D4BA2EC5716A8C8B7A117C437DDACE31E6A902C403DD172DA7054A1BD679C01C1D822C3A075F5AB2002D2147A9", + "signature": "4A3C0683EE52A2E3703716E44D321208374CB0ECA74F9E6A624A1947B6788AD7F6AE68F320A580D35697E48B276779D4F5D2C8AF78177F12C9CD117875E0CB039293F140C24D80C895ECD7AE9C7C8AB72395A2736D7DAD6FE3EA57F21F9681806D821C91EB790BBD7F4AECA96100CA225A45CABE9372F48732B1A0745BBADAEA0594CD87875C05B703FDACEB441736811E2B6AAED172B6EDB8FDD087EF22D30CEEAA7F9E9A0DACD13D60749C0A04C376B804872A6C5056C37B9B64B4060CDBAC15B1C00CF9AC77DB99C506FDAE0AE16C198DE0BEFC4CABD6B38BC7E268112844B8ED5525A5624A36701A2F6AC6ACD2E4E40F01697E518B5F3107563865AE8537D04FAA57E1B71ECB1E2C2E36AEB3D8AA4674A04306E5179FB7A45CC6D57692BD787137DA3E6C5395D3F6A2EAAD0AF8F586912CC6E6DCD5DF34A6E4B0A574A350D760C646FB77C76377B6F88FACCD1B7187CC10E363FABDAB9D494E749E0EABE63D45901A54E06FCEA5A46487123C3C1107BBFFA87B7D7D92BC6793A7FA3CD18CA2E27DEE2213983D08863126FD79FADE804B48830AF687B02B4931357AC4247617AC13064804D3F780EE18A452613E9C1B188C0655FBA86F6ABD38E5F7D17267C747976C36EB37267759A9EDBD6624992F704684484FC562C8918788732DAEF29EC1386E73A2E2FD02BF7811E1D7A20822C8985AAF86B8E253AA7F0806BD6FA376557910497205393841BAFA34598B7E29EA9E67351CDA2966D0873BA914255649CDC89B2B64A751EB627F0C2D0963D391036C7297518A44C6783750C3CD6DF832AACA28FD5643F94A38571BCE04C3E29E2973CD6C6600C8102C1EA725DED21C50C90DCAEFF9D73756FF6BE91E8E766598EEBFC394F83C6D36FAD25B2DFC31D720E7E42763F10AD75D8C93775609CD7B0285F0247B52B797D11489CB4EC333C27E195ED8F7071E6C3E5E9220CAB46983B4013705F5934C0F1D61E70EFF9CD5FD293668BD3D0546A884D7AAED9EF7D2CA8E84A6BBDAF7FD8181FCC9D65FD74A4AA26DFBC42EC10484D7DC073E123F95CA705BF6CC3A803C186985721406994714949BD47161AC12AF72C0A358702CBA5A6AFF793D0DFDC7009861414CC3689E907D65BFE48751AE296D798912D49F4F849E43141E1BB050F9D17E5A0C4B7530E83463469F1D9443533AE36C57C6D80B915A3B3C8D9A3E43F5E6AD0187E8F828FFF7240EE9D4304255DA0528D0EF59FF1993731735245467B1BC5E6DFDE8895714F34562229E79AF8AB5E6269BD1C9DAC265D34C6CFECB2A4D02ACD092822E1EC0335EC1BA0ED22DD5D832B6349BCAE8194BC550537B814492DFB96EE870B26B3B535F2C79E24705E662C11CAF10E0E081573BD8B12A393F9AEE5A9426C22F2F14C7EEDFADD47ACFC4AA01E0282C7AC03B667302A98CBD84902DC6BF66FBEDA65B84115D652EB8C479808B3542567F2ECCDCE06692FF06C653714E65E202AE7363C4C32A71A636EDA410AA0B8F4614E3927BF5821AD2E30B5ACF30201F35028994A8568D68E8CA28C1E2C3D482C6609AC36AD5583485034931DAAC6183776935E42C4F02ADF19730260AE56BB8C2839B1DCAE85E6F81747AF80A55A8D20132D77BACCFA3963896E9C431714D3BFB78DC74CDBC743151615C325AC3BF0DCBDBDB8CBEDE8E71A002C20B89A0E7D732AD8934262C5F29D4B600F4BC690136CBEC1E93FC8F07F6C5CB789D06D89523DD1BD6D98A3015C4950B9AAA45427A3A923B15D2DF53F030DD8E07F9E2461C5676A09D6A7928B2334C2B621B28B82A45BE731FC8ECBB030C3F85B03B7877EEFCB1B7E5736698E8723B55385337C6DF877FC8842343100030E9876CB98FB12E1749D1D6A77DDC94BCFB67B0C61C589C805A79F2B69AF01B2456B5491D776ADBD9C60466F7D099DDC395E6E297677DB98C9DE5D2BC6C5D7772A2AE30916C21825EA848AECA3447766327552527687C702A8344D008C39CA26A9933320A93764F4D0EECA250208321A4E465251135D7FEE9C69FBBD6B8162A4321D3133A6F23FD8A459B05E9C9003B4AE86B538EF5E1B769E14ED84AB3C963B3F8C64A9FF5979277ACF32EC2A65E65327001836AD53D66D420E2F39B42CF1CFC0BBB95EEAAC57D64262FFEBF7D57D7EB86430C3EB5E25EB183DA1196D8BA5E16B106D874EBBEF5E90256CFEE4DADC26A65EF8FF340CAA19B99CC298456C558E54F8B3155E3BF457FE61B1871C8605347BA2B399030ED93A26AAB17711795873DE7C62C1ECECD61AA2F54DFFF5FF6CE074937F51AED1811CADD4BFCD9D9C9B9937E4D43F1054932BB81427FEE0AC894E0F9CA81F299A9DAFADE2F3735C756E89A4D3136AA5533F83AD4465FE212EC6A6C04C1A4006521145B762B2744D01331F92408A5620EDF3F33F004790F2AE2CBE6780D1F295BFCC0749BEA94900782F33F9807F7058439D17D09FCA9F78A50FA8231D6B90B6D3E2911643F08B68A7FEFA9CFA0F200EE15F36C5A38163DD7DBADBC496673E0DA0470E644341DC03969E9B88EA9BCE9D041F34CBD852798B388773FE2EA344B017B82EDB603B6364EAB0CCABF1A496C195F7073105EEE7E444A31E5B57DA2BA0C8627B15328D713ECFE8596FCD269B9549EE31D89890D05049152EE7B5466296963E52BC368A2B874B2991123B14302234B6493C3E927B2B96C2A39A78A7D0331D19CE9291037F91877E76739ADE0D0D4FC8F20A5749907D4012DC7F54C904180B5C98C1B3ECB0363E22582E9604BB6F1D837D797E65BB0C798A810A41D4DC26923B56B79B8B26746D691865210C15F4B222D8F158A65B3FBAED2E81F3EFBA36CEE2BD7082ED8FD0CAC3948CC52CC9567D33DB07BA6A715CD4E66AA376C477F105A471E6F9A2620013C5FDAB9F064232942108D42C0117F40505AA77CBD6597AA47EDC1025CF532C07C432311B40A32927A3FD2794B8D708DF6E93844040F0A26D8B12A32020D3C49EF16F68CFBD5009D82DE4147D6341CDD3868B478C93276752FD3A175E23E4DF15329C671E0462E502B894C53778BE77BD94EFF9C1F3FA2B40A94A1E219056C2CA86A217C35223BF0265C5425953761943D9A68292D69372248A219E410D1FEA3621612907E102438C6D7B92D0868C03B8E5FE9D6AED83C4B8221DA6078451343ACC86EC5B3776F986031A0963BA78DC2045D04F599780DFB1E8277C96AB84EE3A27D145F8EE7A86C04BDC4A6AFA0A8CA9F58C55C60E32101B517EE1B154F60290F635FD13E4FAC422EA874AC104202899E020832C15FCD829ABA48CB43AE8D151B2E3654ADB1B6DDDEF1FC27393B647274A6A8DC10181C24404C56606E8A8D8FA7ADB3E1F104080F1618263342646C85BEC5C6E3E700000000000000000000000000000000000000000000000000000C152636", + "reason": "no modification" + }, + { + "tcId": 12, + "testPassed": false, + "deferred": false, + "message": "ABA83F23917F4EE684C8C3457433E1CB08D1A3CE58EA49A597F82C9D549DFD2C8E460943FA31D252C1CC4AD1AD2FC99E9339B7F22EC228B4EC395563D20FB2CF9A70753ED17404C0C3D191819F35DFEC5CFEAC076C979D0384DBB8FFF19624524DE9078C1C269C4040248ACCC6AD90A43947FAF66200B9A2FD91646EB445E54F", + "signature": "42B0AE8FECAC6B9747D4DFB2CDFD598926A887BB9B23D20F6F74646DB40A6D5998A29A3F4D83DE79F2D74F369EE126DE430A4A1E4B2E5976A979FBF22BD93085058D27F769411DE3F4D80E252DA1EF8B4BA705A970CA0D87E44F7F1B4FEEBA2570E1EC6E133E639958D8BD3D41073509503B4BAE906E4D663F00F97577AF3AC5260215BD297404C107DC603B70B4F611E9FAEA80051E211C34FB4284F439A67BD9266E76A9DA05A7A3E412483EE8A41F1E6587D1F5442539C133D18036A5C194AC776EA6522CBA1A49F40BDA2D3606E90EC36E2A806CD988ED18E2D4A6648F31C862071F9F5E07BAC0044579FE5CF8C9BA94D0EFBC50ADB427D51AAC95BE74A91E30902A6E54A33F8BF9E476EC191203C7E4B2E759E734C92112CD6C1FDA595E5774536BBCA83CF12A001C4BD4BA29B7AEDEDAA1C30426BE7C2DF8FA2DD3F8E28B6854EF142C38CEDE769F0572562B93062F19079DE5F82A4DCB62091CB2A9A6ABD833E7860121EB09EDC8D8104A67CEB3B74CDD1ADBD4CC7F7704946F3C1F561D0817349126A387FB41AC0D08AFD35A4BA40E86E49A0E30DEFB78E24C49DE88C6991AAF09B72AAA1EC1C5BF0F67B2988D96EB8862E6E88E3113F87642769300DD5AEA8D72983736D9B6B670B6C4EAA8935087E0DA7FA6D918C2B7DBC752B6182A6E507340161B1F0AD55167E01BEE73F4AAFBC51E82D7CB2F780F943FA78644DCEFC46137F76D761E83DB23C0D7070EE7FD705BBAC5DFE39849F28B4AAC5B17072238026951AA06E0CD956392DBDE08901EB9DCF5A42F97F843F1168BDAC6B20E71E8F61331E2303EAB3B779EADCCBC7508A2F2599DFEA3B1BA06274BE0313BF5BFE16783F94F3DF7CB9E27E72FA51A80F056AD216C76886BFFF80C84A22F963EE95788BE8202671FE573F2ED3644D60C23C9FDA2FB84717A5AEF30C96FDDC542CD60D6B7AA01ECF2019DFB46A1106583B71E862F17EE7585895FBBD001E2B178851379596A7EDE42A10A15DD2F7316E88868A11501258AA36D96713BB2E52C87BD166355AF173930E6FA3A1F4C08514764A4BB7929B46542974865EF0770A349464FFD3AE35B752F8AD97323CA7A669BA1BC73425C2D94CA7358E67978E24199D271B230903C457A1F77B2D64F1C00118EB54185898AC1DBF8CB2FF930C1A05B3AB12B317AD7163267681DC171A951B48AA28B6B00039AFFF242A1250288F763B23FFA80FBD40FC5794E9A24E70EC0B22BA40C0D1860B82FE5271A6F2744A9A7872E29550EF0C05E90C30ACD553D0126E49DBF22C9E2B782CCECE0585B5956D286DB789ED1132AD24F08028D7B4B42866C055D7D5C0252048793CFD01DD46E814EBDB3534FAF505E7A846650376CE28097927C7AF6D496542E4E5CADD6BE0F211E9B0E1E38081B80CDD844D9C1D4B14D3ECA12961C7F1BF04B6947B12D8C79F552A3D4B78241C35F8405B3FBEE75E3A47A69101607D0E03B8939C477D80DFB8A3A75560221E2067E6ED24B3ECBB7BCBB77D639D395EAA7AC976DBD5DEDE4F0C2E1F68EAE3E59A933B3270F398192F0060E2A28E3F80BA5008D0E552F66213365127C9E296DDC5A9FCE9F7D5FCFF72EA3C9975846B9FC0DF2EF560D22EE11E069F80B5634998CD18B88638D66C00B456FC4BDC56C27FFB9097CA96DD2DCE53FEF52CA59E216E1BEC43233951A830C9CC3F98008F32668F67CBE022CFA4DE4148EDA39617ABF6E4072187234BB52824F79853A0677E221619EB3A413E639FE7165C0D5371A360B6529C877F02F542FFC31962CCB2EE6FF57D376A066A1A8BAECA89250EA67D87BD41A1CBAAA6FC328C9340A326973F6E2EEC86E48F27A86485AAA9752FE9478CC765E43907EC740012C161BDE0A145B74CC1F091599EB03A97076E8134595D7645C06F13D2DDD311F605C87067C87238DE08583335151163B4C9A286B950023A68E7DC01EABD82D22B019D74DEFED6331297D243A42748C3AB7762ADB63BE289A76871793934D76E15BA24A91FBADF3337FC5679D6979F757BF87C6CCEA4DA1C11EC2B93E87A68C42A9E39173EA3B45459E72696EC8BC68693E8C6B1776214D07DD3F13826226D3F3D3B4719E4CBA100915A3EF100C7910B21F6E39B8A86DEE7DCCE80B0C21F7E690F65B21BDA14882CA27AD34A4FF516AB126AC3A25681B20B4250611F7F748A15F2597EDD9DD3C78B588C74A493AF73312BE434BB3D911ED2CF45C4C9D707E705BC6124381109F517E0876505B8CC90C27FC63C1407F02C28FAAFAB44ED64F13ACC751FFA0F6521F7ADA08C0CB7CCFBC295A7C5BA498BB250732383B5FACD5A5DA43A2EA99E8C4E1EBEC7A98E085323998F9400157F20D1BC2B9BCEBAF3BBEBA85A33D678C3D9B8AB90129252338C787A9A4B039223ABCE72E270EE4F23AA971A638B4E27359CF9D62AB4E4A92A8798B8F70F3A4B013C195EFF876217376E0B8AE1FC8303B892AC2620409AAB45917F2996797A87DA6CDF27AF1F4BFFA03A739DB169D490A163D5699A517CF33A6E151E1B21405B42AF3300C901A9A247081904A330EB605085C2099BF7D7D5D319A1537E6630E0DB811E406F6E6D37F7829E997D659C016ACB4F9F655A0AD18EF09293D8436D9C79FCA1B0ED9D3A9E2B8E7E3BA7AA0A89DEE26BF10E01B6E19EEBA1F83DC559D2F817723A227AF950DA4448B5406FC9C98DFFE09B62825FBCBAF2004FFDB6F94F297465170AA39938891A7806FE54FA06A622E70C878EF6F5F7323E786241115C062DB82690446D9CCEDB9F7D596DA5CA2EF7EFC62AB1B500EB396F6C7DFFA3458397EAFFF1CAC18E987CC9D22A82C385829EBAC28426E5B3AA301E58CA8F73CAB8D893351A0D52ADEE8E9FC65C6685B3F6CB567D6E0B9F3B509D544C22013A5C8ABD1BF7FA8B12546AC1349354A09DF81E39E097DDEDE876BDCEFBB1DB2085445C159C44D433A9B05CAB7BF13E8AEAD2F3C8EC24DB9083B7C5A2AD869635BD0956D541663281F0DA3C88BF9EF2AAB1FC93F71165A1408ACAEEA60878A15A5B50D7D9EC284B7B84D746C342F8AF4163F2F97EE736FB968C4FEE84A2799B1099AB2459AA6BE6A123C03100D31270ECEC936AC34C54612D02FEEACD4E02AAD3262AFD143D9DBF8CACC6B863467DBAA40CD38161E0AB1A3726390643E35272B9239290F4AE945B8AD975BD892CC8321BDC6949BA3E60DB447B613F035E1507ECD6039D158D0DC08D0036C20F7C91CCA509EB91A43B5BE76094577A2E6A7842166DBB5B4815A8721F7CC639FFD055931E356F6C33688D2F8041F6E6B2462389A344855767F8592A5A7C4C5D805111F263D3E40424B5B6B95A0B6C5DCE3EF080B0E17334149616A7378797E898A919DA7BCCBCCE7EE2A3941707E8BEE00000000000000000000000000000000000000000C1E353C", + "reason": "modify message" + }, + { + "tcId": 13, + "testPassed": false, + "deferred": false, + "message": "50F8492B1735E32E32D275E0BC94ABCEAF820FB6E3B9CF3DE97620C6E086BE112286FFDC8363C82497CA3BF753B41B3B98273B561A1E724FD4CC8FDF597BF86DCAC995D8CF43F6EAD92AD45509A40A78567A42D9F388DAB75ECF207A4DA24E6C20449C5E2D72B5DA002FDFF5D5D11EF546DC81A8E718B26627C24A851EF71AB9", + "signature": "0E74E2B162C50F7CEB442CD3453B911FE47065F056F3DCD291FEF074BF00E094B2FF7CB329C7B8DD8F6196168E3DC8FBF83156B93ED0E4F42ACB7665425F0DAEE7F8FB3D4A6B29FCBF9DB3507B3255CE86CD52C6F7CE75E9F2054A8B31805441F344521E33F0285B58AABFE6F539A8C0CADAC5D091AE88A88642F90F5052BB9966960F7FF8A2AE4BC0959374BEC9C5CDB98E61D3699B545A7A5B2331C3EBC5A67A9CAEEDE9CE63FD11CD0E1D1CF2E33C33591ECC8433C1E4430AADF33ADF073BF1DEFE203E968DF98604E925450EFBB9F899FE1CC015D19B37B9344CEE5FD1BE7C495C472C4FA10C865C34EDD0E9B7D427EF9D1EC2F39617C984E26C74CC278176B4B44C5EFD2D7DA000C726A5FA9FF0EB2F93D8116CECB5297F45D4DB7B66E7AAB2B054FA3FA6D09A8DA9593EAE11E11AA5C191BE5A506EAB475DC0FBB4F1B756AA3D97ADEC0499454111A5017B3885C199A834FACD8671E03175E45C86EE8D4280D204A44F9F9A62AE65CD275DFEF5B0F2D786DE9A95560DE1E7B145DCA4BF1878114989D9B72B346808D01C844FA5951C75F3FFB325790205114BD5CF4818A041FB94FED2BA6A7A8F11ED90E63198E4B2AA55CC3523B23EB926C84C67CC0CBEC1B59F248586E0F4E26FEC64FDEDDAF8A2F6F35BCF8502CF99F0E05E080DD42AD2CC3A9788F261F2F88DF7AAE5A1CA027F3D4E8B3C16B8777C6D2D4E022045E3781DD8FCFAE3B420DF914B19F67D958C59354146A4ED1CCB6873F971C7E19DDA261FB66B97633F05F1BF493D7A34E011AC2A89A25C9008F0987D96F4C4ECA564B95E850E24427CBB286A0308C70CFEA8F2A13EEE1C64E36A112B009B8608741A6A72A28A8775990670CFF0F1368F22ADD78A8E4547F0F9630DF86D4B89CF42D37BA06FD50536C27580C67912D6D52986C3ADFBBB1959631B44F03A9D37F00A0D1DADCBF7AA83BC2D272C67F1FE260D7EF2939F972FBF0D3E6E288FFFA421DF05642C0E5567DA8E08557A4E592A24F5A2A9E5DB5B556E9BC37D9FCF5FAF21D306498E9B3A8275337E42863D5DE3256224800230162817AB4991B7DB1F0A6210773352359EE61FD98CC39984BEA1055CF6C5846C50D5FC8E575C088A09685E0E210F9D92DDD479839A65F4A7274454743A7571607F72523BBC677F65D975BB18342351AE18302ACD54D51E6E1F1BDB5EBFE5A53F3B7B92874512E2BD1E2C300BA0078521447579123B30F748047B190C97E13A4DEEF48C8F655E9FAEA4D6D0A9F9592CB3FC94DCFEF700B526A3E06C5F7A405EE3E24AB08E844EF7643678BE379A02AED5AE872A87F78F6C56AE4D7B81C171F36214F78286687C51CB5DE95A91307DEF21E11BF95B326602C54F0595C816EF388A887FCF234E806D04FD11A687BA9A821EB169F480ADFBB5206B766C69093316422431697556A632DAAD5FDC2D5358C5889E19F46E022973BDA3FDEFE217CC91299DA3010B8F8318C9EAE7DF3F16F68AF73549985EF95DE90EDCD6D23CE02F197CF2738FBB7AD8E146AACC4297B8845F6B2C91DD8290031C5D51B6DA785C41A6BB4C15F4263014E095611E563931720FC6843D72FA72E9F948A926FEBE2BBCB0E6AAF83C9C358A9D129DB81BB93530DD07960C710641D87E50E624DC5F1627773A91E4353EBB0D52572AC49B6856CD9F929191B3A826705D81C95CEF71334B259AE2C59897D5C113F3FE65D758F81F7C458714B771285DB2A24F6278280DA17A4B31FA41A0A226CBE84CDDA15B02F4061CEACC167DA3B35514FB5F56B8F298AB11BFFD8295B632374F662197F73467FD29A7D43AF4B101654FBAED108C009A1FAAC9181EF63E20E431EAD51C36C399FF6C2DC50524229CCF97AE5C620165CEB51E9C584000BD36FFF1F7BF7F5F612B9F0568651D8F82B5A3A6CA1F3B0C25781DEF1D5BA96362DC367E6FC1EE38F4BA5C79F2D3158D71671BEB04F84C11329F222E4936F805A65C6DA45D8B16544D82ADAEB89B67F83F422B135BC57EDD52F3B6F3D6BFAF1905CD6B8170869CE6F5AACF73AD978797D9A0B2311B032B68A32445B28745587E2B729A1745A6FA46C56380BF8821D988D233D0B360DCA043CFFD53531C42736100D58BDD022A475D01ED77F85CB79D17D81B704C6658E4FFA5FD66938AFB6B4AE99D61347F5680DBFDDA1A3D273AEC674A39534FEEBED087E458E07067B3598B5F6EB9C40AE020357327FDE2542EC2D48D243A2E52DEB9D17A5DA2E98EFD5463759B3B4A7F50254D7443DA637B7FFBD8ECF0CB849D0A741E6A4A07159C99C53003163C43DEBD3394B138DE3BE7120530424073D2464E80119C3D1C2AC670010CB83F41BE5DBCFDEDC806A3AD9336F1B0D81C012ACB910215B351D9A8B6CC84D0F2C8AF78A4D207D36B908CE67A5EC979ADD6AD2413B5F1C17142A3561C1D422303E1A9CC91AE2F759FE5910C8C39374094CD7247CEAE835AEE30CE1E54D30A2083F29A2B42D91BCD2F2E8D2686B8FF5661B3F0E49883E8477A8BADDF769CEEF24E245DC6786480EEAF588C9FFFF09EB02180F9BD4FB297A2868CE388CF34B6AEAD480BFD65EB2D168B9363CF8F02198892B87DE3399BF8257170CC5BA9610E7D1C0ADC9BBF5125C2D95A6CD2EE39515C7DE203C20C022239D752F75A4B0C84D9ABBC70AFD02CCB8EF03370575A391B6B726017DB61C51D68DAFBA9547D81317106783B12AE6CAAF840BC53E6F7C640E36A85734CDFE104B9CDF0FA9EE9FB5BF1F3E616FB93DBD1A55413BC8896ADFA633B311ECEBC6715B9B8FBEE8D0BE9435D5ADE4334801DB0643497F74B2875A1862D3B1DECD42D1D154E79652A8C549C7EFBA49AFE36489CEDE1595FACC55AED93489D58C2FCC0C661C0F4FC88C6523E62F17630A14E874B028997E0FFA15BEB33CAFE8D4137EC88C28FE0B77773C5EF4DD2D1E82A4D4261AEC5E96DA98E92A891FBAD7891C86A937B900C631EF9A1683AB69C69CE3B9DD114602EBA81239B06DF988A2FF80E95BF21838EB19FF79A309D839BB1F9DEE08E24FEFFDF4B43E1EF277A45112D67103B7E8AF4EC88C131C5384859E593CC03F483A35F528B021B38FCF46EDBB14D9896E89095D41BAF69D97A6A31EFE6FCF0E0B98E8507F92A552953CB733377E7EA66F4AAD259931E5E311127F8147C8D3044F536A2863BCB7E597BDC9145DC9C32311E18B25FD61175884F33858FF75FC33371B747367BF92EA3364DD9F26BA8D9F07585BD2AC091A07CB1F0E17CBA5D5A64944504D9E30F2AAA0F3D9D33F07FAE122C398949BCF7FEBE4419F0B8F41B7BBC2A181E222A2E2F3A4346595F74ACAFC0D2DB0F264047484F7C8587989BB4C4C815262B2C2F3A3C47576B6E819293D8E6EF030710162122263D6F768996A6B1E30000000000000000000000000000000000111F303F", + "reason": "z too large" + }, + { + "tcId": 14, + "testPassed": false, + "deferred": false, + "message": "8E9B39AF90A95C984BF578E798B18C595CBF19A8DB8C48B198A053FBBDD3AB7A8CCE81F27F86768A97BF43BD098F0C868F98EB012B3ACC0F8EB8350734F3578FB38177A4381CF247C145E3A89CD669CEA887EF15635EFB0373B90E71CD37CF7A67DF93725DB40E7EAD4E60273D3FC89D29033E036EBF6E47F4D458469B9F9620", + "signature": "4CEBE38D2AD86612E5E7D8028F307753E59CB2703F743CC2A73A9A413051E28AED6E7C59653E0B6CC88B88D4EDE3978663280BFE4CFDC154DD0EFEBA84B8E7849D182852DC5EADC862291387DE3651B4ECBCE7AB39544CEEA95697651E79C8837CEBC1A4EDB81BE99196771A464D5C38656EFB0236078EAF1F7CB0426DDE117115F6889A8EB97BFCEE6C2786873424AD45DEBB7FE010066D6A498D1EF566541FC0805AACFEFCB0A12A22A46D2BA151D0D7169A9746A343A30D924C3306BCE616F0C287DD27FDDC68C39C53D1AB9AF812EB4AEEDB38D756D44295B38629FFA164DFB34708D9DDBEDE30721DF5F53E3388C77B95FA1446811D098C51B52247CA6CC2669198C36C45E1254A2FA923D3908570709E052E179AC01EAF73248E2D97ABE1C7E06AAC64A63EB092059CB7B375CFDDB094C312A09400A6AF90469804E4261D7E2C7B8C4921A3BD1E2F5172FA6DE10EA6742A7ACB9DADD33BADBC70A3D2543F208252741AE4674227AADCEBBF0F2115AB647C7BA18C4A2F4264AE94056EE63B8503DF9794B85B984B27E19BD2BC46623DB2BB480A76CB10EFFC2914D0B7D8A72F3CCD94AAF235872FB225DA2593998A2A0E1BDDD63C7545615D190B699B2251D42C1828DD9548398C8B457DCB5CBA4B3633F12C99E731E65FAB21083A437A61E184A05A26D6531BFF455DDF8AFD59F4B98DE10ADE3A07CDDE526DAADB475AFDA2A13308CA9DF38306A3E260A722D4EDDCB0C839C48BE17CF265444D941CD4284E1E0D4FE2DAE9BECE5483B111328DAD3C692F6C60ABF4FA6F6710775336B9B22CDFF5BA8C24D39CC1687B400696198DEC9FD11D62AA3AD1DF428C826337696E6EE2CE3017CC434CE945CE69F4910D7F56B9F480B050180EB2F34E9A57FEDCA57BE370A8FD802383062F2B021DBC96F403CF305352A290FA777733084D64A7E158B165300817398B4ADBF582A718681CACC94A117D0210EF81C922C2AB690705C8524DB63F3466CDF672A999E4C29FEADA24F0C95E08EB374F5256A576F40C8CB65AADF36D15576F4275E685E2C8ADEACA26979785516A2BEB7CD3DD2BD7AA662C008418AB760F1015689D3B2AEFA8BC7F433EBCAFC0149E4AB054C5509643AA03C8DDC3A4B8940083CEF3474DF5ABFDB59E6B9F50A467F6BACC556E57ABA8B7192AE57E1DE163B69DE8D4513F7DA25FB4B4B3AC49FAF9EF529F569E024320FE545C13109A9DA93B812D158722D9F1ABE71A65681F9C840ACA1FA017CEF3B175C1A53B9E5C015DDEFE07C314DC31D4CF04594CCB1081F177419DA161623DA9E56BFE349E1B3A7DFFB65B6070DF582A11BA3A02BB761F0FA5F6B2DC17382FB71429793B063316E96E666659FD663F8E740A89DCA7283C4A5F69532F60D201E59771E08910DDE679963E0C10B5413D1B5AE21A0251547316A908651CE207A371F26DF9EF47C5189A71631354952A5020C7EFBB8BB19C71EAFB8671855B48FDE3EC4700CE9A78C5772B6668DE037A17A6A7669A1EF28AC9CB1C96B13116C9956887DA3EB6E708677C423CA8B0806FD7D77D38B2EDCAE4726DE88C5C997D1C3D8B1043AD2301B703844DF2AC732DD1140A3092D80D639BC76E94184D6F18E58ECA747968B5559E359C3518392104E54D9C53A8FAF83B1C8E9367D4A964B0298AFE4F13F27CF4F10EE877F36C9595A9DD9DAC2DF2776E1A5851DC377FB59710F1F6C3AC0CFB73B6E11D3425CBDB5796DD78AA538AF0CDBEED57363A414748F9D897488F5F8DDB06E726F1893200BFEC9CDAB19C32B7CDD4428191CC2C25E90584B272C48242E80B644E30B1E44F15DAE32E5B5885A14F711382592B4F4793078082006097FF28EC1005EAE0FFB3E14D490B8221DD4DC2B57DDC1A2204C6F457C3598929C4546015EEC272E37FB6FEA4E9EFE6CA920C220E40947667EAE9480D3FBD3042D507D08C69EC5F9B58C6AB9FF048E8FEABE2A28ABF55A20274927CE4CD793EB4377A085BBC4ADF4FEB88A5AF8D584D2A7F4FFDD642515839FB4FFF34CDE645E27EA8E8D84D50132576DEC28496C72F636DD75B4828F0BF4C625D923DBF165ED7046741C596069175D0D10DC6016D770D841EFD78B6F3BE195AFD2E0EF07AD597E528A0020746FD21287919BC01BFCAF333BEC32FD398C9C8730B4397C0E3533D0B1DDCDD88F29C0C937CC2CAD72CF65A3D64F43974FC11CA11FE8242E1EA70BFC64A43F3CA095374A55344291997B372C87440F822D07300B9DA15B0470156771CD89C5DD01E3C0F86984D9B0EABEC9991D178D3C260DC2EC8BB8549C54D55E1A05F7F172FD319040F4455D6C134437432AD75740A1E1369ED4C6E5D244C8650AD36FEDA00087653AAEED5C92D1FE12A53B1D621F99AF69581F349F3F41A50D0B18B8361DB4C7FB64AC006F2318E8C75682874E8EE47FAA1E59FEDF5F0D3E97A220FD50707A025F2C764FF02BCFBE728057F6545C444CEEA6DC458B8EBB10E64F539F3D07712A33407B9AC48F93CB484609D313AD3E6DDB24364CC3EFB579DAD11E4F42E3961D1A414D4259A55D1447F89A8CBC18BC5E2757E177605D2595E36491B3710056DAA9E3B7A2AF511B3843A04B0D5A8DDA943A75EBE00F611422F1749495BB3F18731F14B43A2D2246C6FE9005B6D4EEFC6DBFF53A8B5405F732822B7BC772F80635F5AB2FD46E4E97AB149FDC12465C21D2F0469153E3A3AA79333130D29BE4C41C998A06AAC624B77DBAFE4B8E64CB9700843A5717CC9B59A331B676B4078C52620FA1D4701B0F07418E69835035D8E2DAFCBE70F4E2874FAACB9E1EBD3314706FDC90B389696C703546EA8543212984825222C9502EB4106F1C7609363D1B74AEBC7DC0054C93A5BAD6433F7EB1717FF50AD7ACDA8419303247DB48337F201A362F826EA0BCD70EEAE6AAE6D4526BCD39CB5465DE1B08A4E8E659B8817952D41C40FCD10576FC1FFF52ED566DCA0AAB931D421238867E5F7A0443ADF92C6E5992E2368BCC5F5160B35B75E5A6CAD96F201980D0727E2C0F9B6E2FC4B64B1A02A31EB186A0EF3E6C43A4185ACB596BCFCC5FFB7039E3BBBBF4141A26A45FF9DFD045DBFD8F8F6F59FE4674FD7C92474827A8BCDE6E4B9E860273B6609BFB275135EE189B1E5F80205ED147DB85FCBA0D998C185B40B037D544A51DB592D3F4A573B05CE9164216DADA873E8E3BE33FD0F5591E21787BC8A1B3665104EE1445477DC6CACDA1C8BF08E02B6B5D81FC7A67B5F54A7F883E92A99E0D07C4DBA0BC6AE79C23C25A50023A47E83329315BA049CB3985A051893BB530B1530343A424F515D81909FADCDD9E1010B2A5965717987889AA0A7ADB3F314182A3B43454B588CB2DBECF8FA0225588B96A5C800000000000000000000000000000000000000000000000000000000101F2D34", + "reason": "modify message" + }, + { + "tcId": 15, + "testPassed": false, + "deferred": false, + "message": "D3C632A9AD8BADB41A22CCCD57B1D429B2DA6A47880B95AA529B9BBF9B18E43F59412C8441F0FB7956D407A6ECD3BEB65A7EB816F502A4FF4A7399A805048822C9B8A115672FA86BF0604A2C0ADF1EEC44A0C3243AADF8FA5793B3E95BEBD9A00112860AC003571EA2F3C4EEFDFB93FE5DF594DEA5893450C26118BE4D4A5EB5", + "signature": "7AAAA0A80AC81B1D4EBDA407C8B7C2DDB20ECA18DEE95B35DC21985816C8AE08070C4911D8106C50CEE8C21C72AEBF51456E882072435CF5D557ED219A82DF76CDCB3638E2353291A1BA8BA35B9BC2EDF03DA73D7C0A0E65A2D6EAB1AB2AEF4ABE3329D9EE81477E0254A04C2C193DCDF57D535ACCB3FA9E37037B81475935650CB816ACC7E944B45D007DDEF7D86B5F1E50E32CCCD02EE2EC5595E142BF06D4ED48C14197770A7C4E93198F9F75452DFA915E30D4FC7A504DC38C29ED11E90F5A7E16D9C9E00069743FF052D1C368F1E6D1E793E412191B3CC53BBA0E0F1881B3A48F5245A5AA9FD0D5EFBCE6573E3945EA5638AA294F9418E7462059B95285DE864768D4DC12CB46BEDAC3234176AA689281CD559175B0F0B58D3FFF54F2B8B5B2CF598793D9ED74FEF1922C2D9ADC2E3278D4224206FCE9B776F8DC70B3068A11053246763A2F7B0D841B649DCE656D3A9BD3454DF86E238247CEBE45F5D4CC5DBA7FC0281730F46CA1CAEC0CC12CA4E24D230CAF5FA75590E5EC2CEE5AACC653BA6C262842ACBFF89FD435C37F4D2BE5829C1EEE1D2EF0FD6A3AE250D44E2791E20A640219FB4D10ECCB22BB78DD4AAE7CCF4153815F35FA08375A9FDFCA3B15FC14D129F60D5528F5F369AC01998E66446159AE628488E876DDA39DDFB02FD915960CE91F212E5915DBB684FBBE7C78BFF70E2ED2EC0873EF55F8DE4769D092C672E397854E41C7568BDBD8C2B829EF68E6C76A6A98A788EEF06DCE863710D51EA91E3575BD349A44F273E50C6834F85A90B3972F24519BABA64E2177D8FA0BA9C1918B99979D0E6654E6098AC7CD00AF97668831464F466FB628527500DD65C35DABD933900D866F27A53484400EE3068394681028CAC7E82652C5AF959A58494E710F3F7BDCA057BDE3B8322315213A1E19739C361881DE0042FBDDDE573D7D2CD312F66B71D1C8CB41A7922ED058E62C78E2DFEB6E414593DDAC5E66D1A88AB95836FC6B183B5C189E14C1EC833C5EB8D4D6DA8676202436345FEA6F3DE400C02DD8CE746E2F30278A599C1F3A2A9D97C3BBC9529DAEFB2A70237E39738CF093A4E10BBFDCA2EB3967541CB0D7AE7D0B16479A337A4EFB13D38D7B5EED9D477B4FC5C9463CF6299CED1381F422E81DA93E0A3086CFF4055785817F0A7AE99FF2BFF5D67E73082CA9CA2C1EBF13765A61311D9467506830816D99DFEC08D3075FF28BAC221A098AA9781C862245347A44595DE3869A58BC583319F4F61945DDA28C5C25ADCC1864492EDA40526ECC07E326B63838F1936E7E6F0B16F69583840E46A78090595D4D6BC6CD1A7711BCCD2507652B1620B48E0EABF157F08C49E315CAACD52D3622E638A2DE884CEEBFB954C95EF5C3E8F30B33BD0EC3B1F64FF6250765DD87EA6F4AC3DF3114F5214A37EBA198F4B66E2551E4DE55F68236677B234BB72EEFFDB3D404711CA81D28CF5CEF24B662E5737779AE0A76946454E960D566E575C3A6D3643AF381EFC8FBEDFCAA505EEE3CE26FCC023AC5358E925DED12739EDC663AC8ACECDCA68BE55E3E08A20EAC19156E3E4F0A7CC84F7FBCC1B359F6CBF6451CCA223747E9368D69FCFA355211762F4BF6EEC7C28566F7DF508BC0C612EA08868274D847FC6464A6455212E31AF3AC28DE1DE1866B60FD0157A0C005267014BD23A703FF17D7E8B0979BEAF8A145158213F530129BD11DFBA455293434F8E2A55FB6C13E14726953F3FE68C5A21242FEA35AB99334F7F93EF3756D31E0AD6D396CEE242628DA0E47ADEAE5891F2D04F184BA746D8E3D33AE4DEFCD6926B43CB46241BD0D74B7678EAC2D924B0C98DFF71B00D1185B3F793CBFC5AE38B499BC0B7FE4024577F8DB43DA183EC35BA7D877B60F24B42BCCB6B71C6D0C8735707751B507EDABD083C05A92AFF3E8A82652C01433FD76DEB991B2FCF0974F2EF05B2F823302FDEBC91CDCAB116354531FC50E6B9CCC71790D9D9C7D7EC98EC38E8BD030D3E8D60C1D1FEBC50D8EAE4432E6D302BDFEBEBC0CAAF831563A2EA338A17E16064F3370FDD18C31C636E60A23CF9CB609581F7F64524637FD3571D3CB3B99DFDB230750A1606CFA5CED44BCC6FB149B836D8D703093EBD6397A1256C3176A3D738C703629169077386322CFC3EF6F3453F9BBE1A654A53A7A5DD17456DFA1308D91F5093E245E0FC287E206E406F239A68ABA77E3BC6D3EB77F8BFADFBD285C8F171646A74B2224B1CC9D8D3B4521A195376F033954325F5050FF15B123BFC21EB5197242E6EAF6730DF2135D9753B210D8ADC109943F57E4D77089D90A1032DC2F535746D263DB4B9E2E23274A486C4FFDA9F43F981CE616703DF1813A54272C665F9652245051FD61E2DF34A38910FF4F71704286B05B44D8B4D7346D92CF5CF17C5A0C80562390180CD9C42BEEC2111ACFDBB708BF750316D49A8610F1644A31DAD2A1FBCE2A3980490E6CA887981F06B8FB2E44083AC50F8EAF429F6E8261AE49EF2D1EEC077738E50487F356C304044B49AC3BFC980C76963B95FE4D48F2109871B6AC32F40D538EDC54774AD2B333018CB7412053C69F86F53C2344A90988711EA630A4BCFC93E212A5C183C87DE65EEDCB00F0A0BCAF14C00DE91897FAB1F12E57F3C1993DB6CEF169B75F014A2CB28D07DDD23505ACB5303099430C4B62614D96EBB4F2DF2F77B51043875C1F5AB2ED40E5E3B5487E9943F6BEA13441605385FE9D09AA0B7DC32946D13A8862990723DFEFFBA9E86D80FFFBD0857A9ABA7F2B18F52DF347E8E390CD1C331FE9DEFD1DB0257EE989ABAE16873342CB7B195CDA930E37D9B5BC4AD9E079042079D4A3119DD025E73AAF8009B6F67E268FBCC281AC2B9501606E71EB179F366605A6D5E1CF7F1BC8C152EDAFF9B841DCFCF32D70354EDF9CCD1F5CBA98D6DB2F8C610DB50151EB6E38F12F0CB36833D42902EBBFF90D443054C3EEC43C04DD6C719DF119E3B9696AFF936F9AFD73FAF735BBC2D79A60B2788BA86F857B2CE38E15754F419DE346605800651E159038A87AD3A6808A6B66DE07FFD106F4E7E41F2D026E6558EDCD811F4018112A82745FFA55BD0172DC402ED2D0196ECC9733D2FE372E3602E3D0DD5FE629406BB67522D37DC0077BB7234899864A227AF6C9CF3E3A35899F17D57CFA87A2A63E8DE0259818A93F16EBA5BBA4B96618E10685ADF1C0BE38563A0850440A76495501A71FAEE49B4AED01CC0EECB303005B2ACB97D31C7859D25924D4AF86008FC4387D5529E03EE713289FF5C7D7AEF659A8AD75C39BFB40676103104C5E667B7EB2CBDAE0F1051A2529355056587ABDC3C8CBE3EEFB000210243F80B2BCC2C6DFE4E5FB0307262A606B6C999FA5A6AAAFB1C1C5D70000000000000000000000000000000000000000000C1C2A3B", + "reason": "modify message" + } + ] + }, + { + "tgId": 2, + "testType": "AFT", + "parameterSet": "ML-DSA-65", + "pk": "6C9E7A1EE36625760E5D2F33DF2929DA56203234069160E5F2BF039C11062273073C237566CE055D871F38ACD1A9859A824467F19BE68E4F00645D225C42C85A557D2C5ECB442B0F028A6528898EE2B673D863F32EB9EC8164127541F32519BB88E034A03F46F7D193CD3DFBADF63557926C5C8F5B766A7FC5EC8B3F948BF7A821B54C9441AB0BD833FD6354CEC706FAA500ABB5289B90B1BF917677A29D115F0094BDB48DC72E261DBA120BA6FF5E52A01B178981DD8296444656D9442DF9CBB6BFDAE56A230F6F29F94CDCC265576AA8752ACED07E99895CAEF0168BF83D23FDADFBB928CBCDABA25FE2CD26ADDFB0DACD74940F351426942F176FFBC5F3456DB7C912AA16B86D0745F87C9F45370A8456A1ADB51DB4052B5C9EAF60AD7B80A42EA4BF92C841273AD761DEDB0D34BF579600B149FCCD42AB1549BA0ABEDA57EF71D1FCA5702AAD083299BB98300189C25F3B270A87658D0B2EA56524147F739EB6C676D7BE73DD3B95B10C55AB46FD01549C5168BF7DA13A499785F35A1E3B56F4C567F54EA9AA2817A336383643FA2EA31FB1B73E10248DFCA05C04131266498E1C9491135A50E63D02FADF4165FC9E15E3E1B32FAB8337684C49193E1BC4EDEAE373A267A714AC1F909CC657CD8066646327E0EEA041AC9F2AEFFC80691BF60D3C94C642557E4299D395922216C65E75B7E1A5028960384BF816C9F7054829E7985B5841A733F33FCE2455EFC89BAE84B47990E8D0AFC6193E4AF9BC680AE24FE591E88BA6A2AE12DA3858D21F492D24ABC4FE4FD52D5ABF24BD254687B918792F0A003A5222DF45038685C725CE7579E02CB168BBC666ABF669856E10537C9291692C0CB0CFA906270AC2C7B7DC31D4F9283CB2DB8A462AEC0B9807BBF4AB4576FEC6226B4179322B67AEA53BDDF9C9BE5E0DBC43F78743068AB5BE49F0E62F8E2EB1B6C6736C05C9413D065CE0CCB790548041D7E832881A839B5729AF94AB79FD8A16DFFF78CAAA141D97CC0650F86262F26159BE8B361A4A041E9A0B6511BBE3355A4BF57AC09848847EE0243C3BA774776F7E9A227275D74E6E3101D382818763ED1E1353AB9EECCD920CD28922D559A4048F40F062164CB661C4F4AFA81A3D55933C4791EDDAA3939E5AC342B0AD1F438A532C6CE786681A870D94EC88A334CCEFC6ACE7D988A1A82BC0ACCE785F123BE23A7C92AF108E5ED4F0869E22DAE273556D1DE386623A6C3F115BBD119271D3FBA796F618B53959FB98012E7D5B9AC688940B87E2C9C065524A00D3A4F4DBF52F4B1A63EF5C46193BADF7AD7F988D4464345B2C3E549684F2F905F6F89DD641473EC05108A52D8DBB91768C541DE520B17666970AAEB506E75D8EE9F4B4455B71E0088AB25655213B75859D25F559D3C324D283D397ABE6F0AAA386815768D03357D775964902413153E3560CCEF1FD44B65FF1B287A92A9693F034B7EE668934702D7501CAF6DA4EE98AF4E8E64B0340E0BB8BDC533B0EFEE1915A4B68B93C5E95321EEDC234AEFE71AE2E5DACEC2F52F83723A2392A7F8E13BC0301CD104D852E62A7F828AD329B3D9596C58E13FCC0ED96C1C48D82A2C0F4D9D24DD8421FDCCEFD497A9B05FFC50904770401373FEE7DC73773418AEB4A1F599A4BB38EDE8D10A3CC83A1C72DE921969E3CE3E8EF2F7DA89D344C80D61CF9C5A423B1A4F3567D96DB2DA3DB9B5B5FA68156BE7452C8A0181BB9F0DC75CD9750883D0DDAE53FC156D67A74200869046B41DF4BC4396993C08AA4897A0BDDEFB55F69CC1C4D7B5FB150408427B416F73183F2B3CC16E3B7DA63CEE1143ADA1A056626A077B6D21C3DD974ED907C5A094019225737EFB93319AD3B40A4F434AE49D28391C17A999C744A68C55A91B862729583D3DA46EE70C5CC461694167D32D21DE75327732C63BBFBD7B30DBF2057A0D681519F6E4AF608D4BCD0B4750726770E156AEDE85417BD759D5FFE401CB2996F34434DB428D9A417037201FCD260FAA98084502EED5C27A8916E44F5929819D21A69CE16BCDC3CC8141E285EF897B1402C15C952590119051E369A1B7BE443FEAE6E32BC8F3D647FC5315A5200CD5238DC6677466EA86EF8D18E5A79F262483E896B8277C741F516FC040C1090F2495BF1650B02AF30456733A071AF47D7A15BD8E32A49806455D3BEA74AEF5D00906AD2F0C045354EFDE7C9A276E73D9EDD11D1CA5C297B9A6851E7F67E21EB061BB55D9E673C4A75FEB84D52629EECC53C24BEA95153051AC206C87DF55410CA1FE6CFC3F403A6D9D43EA84C60C945E642B2836338B5AF9F69E52708B2E225933DB320BB3F790D397F22D7B6F8A433CDACE9810AA0E27C699555530C562DBF7517A4162628BF10D1B6DBACEF5C9ED51E55D9A89D60E0FC378C47A21D5E0F2DC3BCEF5E05C6E0261530FB027E5032558CA2B47005BDDE99909930391EAD7F3F0A96B3DEDA54A11145F530E51DEF892E5AB0204D614E6E38AFE79CA92C28158D570120353B7A4DE0889846D835294939557ED0AEDA270D4D73ED84D3D49F9F032D43457BF59BB7D66359DC53F9B46963B21784B06CBCF04BEC1E33A33371532716C9EDB3FBEDB81999B4372D0945C10AE826C60FFE93170B6D294B3891B0D2A7B35B28A8971845DC2FECE237B80F20B379CC4D136DAB3FBB3792C63EC61F5C755BC9DB35086FBF46D2B7970DCA2A8523FDB4C7A0B8E42F8AF9ACAD2A0EFC113602A4EA62E4EBB7D269C3A40BA2C44EDD2956", + "sk": "6C9E7A1EE36625760E5D2F33DF2929DA56203234069160E5F2BF039C110622737E0752B0C7693004EB0BE13F45B0E746806722C07576AA784DD5768B8E9717ACF948317C1766ACBFB4E7BD185519904E6C692864FF50284E8E8A9375EC4EA34F5F12148700ECC62348233220AD775B1FD83A9D3033C5726D5D2B7D62AF0F321073265767333773710146658307501027637053370657250225555720040341823880257151604303437436364873068203400580355270640528800356423156175845702205553010102421157700782401137236740715853511546827780058171285586565471778437044287102661645257880336080652346080345067355710525170351103044582875788416670381280332611148212542274864328145641171634161472073852747637700366176681206471154344726473362010558700767083172687387540864551263076218207175324250705811241381122505668870883105533887700160238574586677413700824715657338861660882118224618741375072746665774007680684008408864784248583305731165636605282311527846513814557422254225763505335185805045772607486115373775501301805588136883017444342358512002083355886761447611843130517161431236500430633468042808454504363744347278406783741362560056114518381568433131845104766515171258063754487005546787785164813636668836714814331250407272582855656455511302530021167653585048803872700335710803434230171774356436378811535174553563760650830866312030043372500135850715242334552801436552652110143858484825063518428451016281466626867327412840616146432745720226734334344336864822713770160361506648005108030701043675607201545188516112422024543610332866143554022500172345126884075052637375885843455637816811081652004223238015767462112427318073848157877473355128053258038403285128525243021068260454320361252184050053654686616407543807371115562533303056062263720288443812612332480436644178134504083651088857081564755707730220287025300326401157363132137353852252445460322112121458848603250488457321572732862717725572184234644216036037273104120246263515180767257548713266788448387550377150332045814585223076167211046522802041228835008465653353475403760827857254217371277417513518217322601416217082333145811872187548446230625704712408403728866868256173636515663287433218023005128757488114046826253156374566356518567854271258515782580235784787078510132518218835241154170380682321437624740206653476855162418705517324874146320502540028563553337227338137006846351826061025422151576867143646335103655216308746420764437120657888051475701461726087878200883725652314647322670452815523887856664444466486206152851777584535231176278615046820787684744516215818777031852713826230320241600661118701454424002376662882163632310542162672683874733463167347138530146864174004655605137026283771585270368460221040288147108303664158073248587845541156271113728404628268142526020534444710553471748763668442470088242387126541621045830510034783657806137713048564534131885226765508146165284157135227545278676445535730788018243348644536176786163115841288118664034311357777385628338216462375410335504164603274025383302566113744712177274654435563367786763665380177257043122543435171305472235768533118803341085768577357055022185512180623748870526213438432586831083855300868387436611124101644003645154833742857702507323136330340D29203183C9F15AD8D5170812805AC0B6CA848D0A1FC80316375E73FBDA6CA80FC412483A1CD90E211A82093984B22E46615EBC2D64A311E2718C89A14FDF35E5F0C7871D83BB3FB731A0B2614D7B9FCCE48D2B6B155BBC7F246C20BE814D4C9E9093AC20DCD3A4F89BCBF25E86F1B8314125F7CD14F1E395525ABABCA5EBB33D28C13D97199CD4927CB0CA5FB59587856C9FB22035BEFA45F44CA9F0E5EDE014B88825A304BA5E47FB95791FCFCD3DF9ACCF4F4E74C7BEE8235952186ACAD1CCFE60C7EE2B911FC47A95B5C4C1FFA3B6F582E905A33E93BF8733CB6155E1859E7B78B8CCCFB61DF62A13A2C744CDC9A61FE6023299508EAD29447311032097043443F482C8512ADCE0718F192BAD182D13081E690F1452E81AC9240843419133F2E59F0110DBB0060F6F3719D5C1DB49BE3999A45F187F53F7A5BA7539CF2F01409EE71148F77BEBDABE257CBEC316CD853281625B4DB4F8E8300769AA431B2D611C4E52F1D9BF8D8C5F85E905983AF2E7E2A3612FA97E84121BCAC53D6EE09417D7C7AB07FE6AD777A3727B5923AC21282BB8A46281BFDC17F6701D5AE292562CFACD0C60E3309B27875BC69BB4E9CFA1A68FE484AAED9AAA3FE7656B0C2B8E0D2FEC5C8D37B90C3CFC951043A2FA3DEBAE6FD3A3E1CBE0AD2C70929069E4A7B79A750411F7096C05BD858B51F20C7AAE0F5B1A0F457469CAFB507C09BEA92AE3AB67F6C339553F2FE5E865883B5DE45BC2F2F7B22FE875BF662F9E644B97E9E3BE68CA44380FC50E2C66BA429B1B5F417DBF5C67DD0CD9CDACE53D9BD86CE66C7881768F833E00671EE5D7251DDFD27CC912BE279A43B8C700D6EDD288A66B87858DFD779029F696928C1F6EEE18E794059E9C1E39D72EBBEC5F131FD3CEBD99E9EBB818D8BF300081847B2D154286520E681C7BCC0AA3013DFBD4A440A1A0A9E00B4711E5056B58F0176705B888AFA318144F8742BCD9026B8AAF6B9327478E4B7E217BBF1DFC88205A4C91C64DCD4D9AD0BD29B44300B405356784F50FE51B525AE16AC295D94563EEB5A0C3035A5CC7707B418AB1302BEBDECAC06001DB4DC9324D7BF9652BC1EBAC4413F0B83BECFBD921A037918A246910AECF75AC099CF7DA75B8102D4223922D8351C310109949959B8D8560BF05C0E5FA24D401259862F0F328E3451789B09D09566B62DF9EAA561C17C83280019D2D15A287A49C75C712EB70B520DE68229A2B653FC6A2067D2A0AD42CC37F8AA4EFCC96C4F252F8457E3187EDDF63F2E67EADEA0DC5F1E419CCDFC36B864FD0F91420D4CFD5E11F3801502770117B81AFF4A8C99E3D05203A7892EA39EBA0B0FF0B42215539438E72A1AB2FC32889E92C5600EB03C388E5359797FF906F387B79D00AC97CFC02DE5AFD1BB8AFFACC34CED19B200F20A4BC28F074A2B074E2AB6601CB0F1F1FF2C0046C4A887542F3B8A93FADA8A7C647E4B2ABD7EADE8DD9138A9EA86BBAA8D8AF39C6D822585C9A3359D87D73A77A938229B31F1495D4778F51D5CDAF02D42D039662E84BB3826D881802467F56ED258B3046288DE376CD9F9DDD5184D5441AA6B12FE72F55800F18C7E170159142F3A56E865832846713F430E1A0ECE056BBB99A8FFBFAC60C3A2D89E1BDCD2E6DC4FB570679368428CB554D62138C7CF1B13140E5554E2D33E3E4D5A983E7AC68D3CEA0AE7C5B8F81C62AC6F5ECD2ED572EF101B9E3EABE653075D58D31195DD5FBBDCDE459DF6439A1895E57B968F970A20B78E50699A3FF8BA5DFD52FC91F2DBB9539FC0E1B164FAEF6520A7B4740E6BE81E167D5461CC42AAB74C375B6B7288349C8D0D9B596F4526CC37647C1B92835503BEB5E982825B4E9AC787EABF5745877691E22A560B65635715AA5F334631A1A76C51C674B0ABD1075DFC925AE284AFC4686060F68120016EFED366AE69313EC67B23328BBE383ED68DD73D8EC267867D4ABCD8D33B91679820DCC602EF8CB6C44917330B08950C2B83689029DB502CC9C0F9FD63E290128F4DBD5070A1120DD95C0C7DC1D03FF9B91AC9FCD1766566A424048D583672A2CDEF1F373CF8BE3F6BDC4C980075D695440FBB8FA518DC5B53BAA7736FC922FFD67E7F41F9BE95EF41B5931AF7FCE19D3359DE29DB8A00D7B7FAA44D60E81C16F7BF2D5258AC9791777F8054C4D1601BB8EA5DD8C24004C723DA0CCE94F7077FA8BC304E9911D98A4D6E09CEFD61598A2CD1D77FABDA70C9E42E48F9897436FADD1A2F578357A0A8C4BDE8BB1DA9A2BA6AADE3D103F9DEEE26B5F7343940E478650EF3E40E3EDFBE6070865D27DFEFF04DD80F0FC891B3A2D9B536C02589D0806FA43E635EF6A8A1F943343C8C993857931809ACF4A25D9D93EA36DA80B3E49B01AAD63AA646060E5A6CC11765CF34DF3D2FCCC2A32ED6FC2BC792C055D85F477F374D63A9C1D0B0B7B2C0A92241AF8DF99A7BFA037045C5BE91B13930EAE43B44572A5CAC5A76FB723B57BE9824F78C59244C38565B74E223576E7FBB45BAF9747EA97ED59AC3EE567B66EFDDC73DE2FC27087CECE955EAF33DF2B71A1D64C7ED6501E2E17A34D17541677B96F0236E7C4CD58C2DD73226B215EAD1B76E38B281C8B173316F5C5DBDB91CC87F9774BC76B66A2CD94950E6AEC59FC3559F79238CC7F57083B943604BA9CAFBEAF413E4E38125031AE173F9218AA4CDA7544776EFB6C1E416A0B10061A9DC4C855252E0751C5B58AD141AF38B96F887372FB3B7FB0DDA5F2350802E89C1FE7AE20566CA1FC147DD2AE19958814A105757A07994B29B236BCE28CDFF71C1EF5F6177727CCB2B1D1D9463172D82CB513684D72D74DCCDD9CC459FF5DD5947DA7222647BA1B7554FE500238A5B6B07B9FD9BF3680E33DB9DF7E2F166CCC0AED8C6A233222C6B5034B51AF8D25DA348372DDF66A6E5FDD2DBDEF69041E0360A69AFC6ADFFAAB2956F28D3EB6AC07E1A974F889AAA79879345907661123A66970ECB56223233A18B06CD1480F1988C172793CF89E97E8625BB57463741628A8A1137D9B25F9254896172C6B687296E185435BD7CF6EDA2AAC36C3066C3C867D5F206FEC34683CAC889693496A851A74B219D389C6E716AB5F210D50F553ED0EE5B9BD8FA306E274439620FC769F25FF1F11D27A8DE79FB651763334DE8FDDE804F5F1C29F5171D43C0CCEB5D5AE2A458AFC3A3B0A51138D26A42A923A0E551AE38B16241686CBEAFC673E900607B1A54DA124B2EA588BF28EA334D7298869AD1D1E96D0C92EDF817985331E6FB4E09144ED04FCA941B2660494372A8AFC0AD18D8225F0ED03F1DE7F8F918C27380E078C12C2693A72DB09890485ACB99F2B541B3D3346F9221B67359C30272B527279C20C35B58BA2F3F0E07CD50DB8D8570A0A13181F0791531A48135C395F88AEF1F39A3DFBAD4964226BA27305DC0DE338FCBAE1BEB645B5A47BDD6CAEA68A7B21F110EA35320BF756027876A83B11FF2A443EB31393FDFEE5AC6489762CFBB68D33DB4F55D24B9889D018E11E3E7", + "tests": [ + { + "tcId": 16, + "testPassed": false, + "deferred": false, + "message": "02F2F930680B35021015B0DA413D328042F9844348FAAC3DFD586757C3574E4BADADE11EA4099FAF12617D5EAA9F4CF4D4E78628A0D38FE3119D3A08BB47648E735B798D320668C9222516D7DDBEDB3761229F27E5C1A6273B13250CD2C2D429395B1C86D6AD16730F6CEA46FBCAF737AA0CCB8F719DE98FE1503B487978350C", + "signature": "CD9BD3FCFE65F76BD1A9C0F4860737D7E1E5DA8E7ADDE2D528B2F85283B36B9E1A0694D5631A2B32BF0F133FE522E5F40E398B696B506769864672328C942D7FF10DDE0E5644FECCDA421E89DA2C3E65F4052AAF4F2A372B0A777CB76EDF55E8D4C607EA72E79E6F81154B35FAA6992D2F3A8B0C2AF0E3672464A87D3A343D64D99366AEEAFF81FC9F647EAD1C7035F8DE518D003AA0912D15C63C0DD3B73AB37ACED424610D6CF5BE6475B4AE5C5BD9A7485647844C44E1C9E01BC5C469005F31A59D0119D872B7AD4D09BDCFCC8BE28D446BF7FD32041633A8A61F55D86BB73912BECD657BF88BB8B8F7D06443C51BE667D3C0816A068D1DE5DCDBAF3817B8CA4E1997BBB5186A467A0EAF1BC5B0C9F7D18BF63F5B82C69FF5DD403601C48B4FFC3CCB9C4711073DBF8130F3108F793569E717509CAFFDD2AE659E4292B80283A9BD6C1067A66A35C5B7508DE3C665CDE71044EDE2489EAA6E6C42B10F42DC321511BB991627EB7227BC4E16A4CF12243359C7ED6EA4E396046C50F5E91262F0E14A53B5E7F6EEEC8344A9BDDF90F9C4FC5C1452685E908776A454BF66A2622CD436F7DD21EAE842448181B8320F87B169F6A4C803971FD6A40AF7B72B97F8102FF44B5AFD170F9A91C089D44AA803DD088B4FBC339372497E44FC9D784753164C5ECA5601F2E13043B7E89A7D86489AEE236289DE7EC9EE4C37A85E41D627787032EA98AAE2366A15FFA9226B28C116A82E58466B78D753937E38D25B5D5A63093EECB73A1E6BAF7AC1C7A11CF3412218C6021A1DFB979500E7F361D7DCD998F964F2AA01261C38795C20AFDBDB911527DCA0397837FA630EFF6B6909AE84F740DF12E8F2BA2E661C3F341EE15E1F2D82856EEFC1413D9CD9F4229BD382AE541C2EAC7332FB9A9D10F6CE35AB6D5EEA16D9C192643EB0C95B45F4712D70CF2F562A934199283D270B38DBDF5F288D64D3FC5D21841600843644D9F1DACE168118F2AB90892086C4C3EA7AEA0E0AA10B79A40472E020F41DD7C071A99741A6FC01FF56EAE9EFB62E43921C5C042696ED35403FB42F8734268442CA28A7033E4E495D89F0C79770C3457391A98A580D504C4B17E138ACC4F1602B47C63940291BDBA5C77B8FD0059797220238E9C9A9EE266F5A37281CB1255BB81F309A45D0119B5D2FD04385C91AAAA574F65D71AF509B7C0199F26EECC755C36C58FFA9A355220C4969FDA2C6F576D90507719BBB88BE2BCE537AEB9A1B0F84F7E149F6AA39E0D1F59AAEB9D41EB380046ACCAEC5649EDCF7EEA83367E572F88915C1DD31A0419990F33C33064AC625609423CB87BA10A61D104E35848324F1833BF6BFA95E803C1DB3AC312C4EC6A55BB6622B584D55349F23BFA68B96381C557F15F403285E44C4D80F629AC75B559D8D1208703848DDF77E45E0A91C4E3A7E9A6FE379B970C7D053C56DC55081B6D774B1B2D2F7B94289E55E7503CE5D853A481AFB21F49F758EF29E927E3F848FC1EB7EFACF1539D8DFD1ABD91455334A6FEB69B37851406987948763B620778F3F9C34CCD0E1E034C50DC0ECB30407C76A5EEC86591DA373926E7D7F89BEFBC6260DC26FA148485B48C4C4C119C5C0BDDD3811C31470846193CAF12F265EE484694D3CBD7C3F85498D24C09BCB4CD721B20807D22B8D8CA277E3B519970E21E6601051E8E07E59A8CA6D3BF3CB8C9D2D2F9873527AC5E842BE878508EED43CAB8C44B94A07358301337CF0EF1AD221F77543AEAE28DFA76B67577C945CB0EC09E92C9C283355797590A45A707EEC991B70D6B26B476B5611C4CE4497343174BF3F1424C78FEB79E42ECEB1C8ADEF26C08ED8325C34801B4B0B458B0D3B2FCDC226A6E0B164854871ACFA5D73ED78419F60DFBD27B5CA61C5D9FD51636DC61C3727CBAC0C4A82B69CF8859D427F23186AE35A7C41C23007D382E2E00C6EAD5109D1029B3CE2FD0B55CAE9C054BE7E8280A022B39E26AF444044CBE847EEA25ECABC2BF09A36EB90A60938E77153D95FDAADD7938E5650B133A936910A09677F64B073C7652108B73993BEE1CF79B88D694E46FE461EC80561EDEF770901BBE3A58B167A7078E32795B842984A3E1A06D9E1A8CBA190D424B5AEB7A29B69DE0BDD7E4053181DE85402F58595063F9ACF66BCAD182B96EFAA9F2F9A19765B3D7105DB3C6F9CF8DC3EF2D05E886079E9970358BE2978DF6FDB47EB70D1CDED8C155EF8F1003DDA3D38250CBBA07B43077B0E25E610FD64C2FB7266F471D1B245A528577E1BBEDCB6C4E23A16E9F629AB52983F48F75801908FA9CC68C1B4333D4EC84B836AA70E8395F25EF6908DE54653070A721C4B88D1E10510E44394C92A828EA30EC54D833B06C91E721F5D29F5E8E510B478A35A6F0C36B559C3C379A82DF46AF0E851414095395F6CAE2F7600BA07DF7FEC98460598C6938C79B20AE902D757A739792E40C7BA73D71DBD1158FE8768080D69892D574D28F912A6DF07EDF59A3174E10D043CF046B77AF5BAD8DF15CC79F6152774CC2C9DBBB4B8DED02D00FE683282515B79D3325CCD342DDFEB8532EE5663F7A04BEAF9D9EA0F7BFF045A43E15484521934677868F0707916E6384E9029E8AC655C60F473C682A84ECC01F3635A11854985A218F819294D39D9C320AC373B4E77C5FB415FE9329EC62F7F5478520A225831CB2B93D474A4F1DC72C80F9FF70B0F6A7B94E0ED2EC5F7B757D812FE61E1DA3DEA83867106281F54CCD9F5F8E1A6BEA410FA2E90C67DE915A17EE76E9C357D0B4CB2575F529EA7561C35AE39316197068A42954C9C0B95C3835E6FE4C60602CACF403AF965D1B12FA3258648E4307366625651099702888AE8A5A9087531D01B88C9AFC31B0F818299C3B56A62514DFE077EC466AE06547FD5A04CF26FCE02ADAA4FEE49F2083BF76587DB80C6D3476A34AF25164A8A67CEB6843BE935DBDE7A6BF4C4489A8E249837CF596CC83A575432A428E74FB706BFA6558D394D667A6F24708B80B3D33E918B148A916BB7AA98FC98ED8654E5D2B124D39ACEEFF3542D0C918BE561CA538E3071B0D8440171DB8ABE17928D968710FB71F529E0A80A57EE28B26433F9A5A9C85B1E693F30AA246965225D9527A3017010899621EE3F2A4CA0AE8D86994B8EAA3C19AD4279FFA1D8A9CADDB933247D6BDA79F392B301B80D4C0CE9756E5EF4270A77B036EC9823A8D8BFBA3A0D035F0E8EB256C5D715B819AB3B2D65A46AEF8E60E3ACAD85C5DB355B4E71308F524B419D4FCBE97C0D88873005F5D9BD06AF38E5F759D035B2E9526B9F6B8207F884DB1731B0A6BB0472546D819F959710F22E347D97C26FAA6A6962E0D931DFC92E897822B38820562F4CA63ADB20C6D143A07831D0EF3AB6A28BE35BDD10958B9AABE1D4D226FA4451312C2E2A94BCBE990BBE7EB9BAE9A27A037B2B9AC11787D3099DFC5283066CB9089FE5F86D8957F79F156A45481BDA3735B9CE2E37BAD42CE4D5AEA8A6D3DA879225A5401A8800AA6A5AA192C1328617F4E83666181FE79E3F65F6688A4C38BE1C42B4F2720C82EDA1A380A3E793403E30A44F1C154E57856B5A067E54D226594B11A191F1644E499BF29CEA93C0B6215808D35C5016327FADD945D896942183B8CD7FD34272A3CF5E82E0A5777F4397F0B8F2D75C95C0B337165E18904EFB0AD19EE5A98E9E347ED13213350BD848C40D2DA8055CF20344A2BE18EB0A9C6F275DFB989190282A25CD043DAC59A115695C4B5AA9D02AA15DB9A1F4906E34000EAA57BC408FAAF13BEF5099B12B2410244EEE412542A3426DCDC5742B3CBBDFABE2BBA473CC1D0FB05F8523B06E08810F061ED148ABF40B8EAD4BAF88F909FBDFB9EC4EE7550233F3F05A4C450C6B38C442B99FBF7AC6BCE1761116A3B0F8319EBAA9A909E0948ACC5BBB4680CB651FC3808ACC7EFAD908EC78214D243EEC46EDCBB116151FD08BEB75F1F4AAF17F5E62A5194E31491D4001595A7BA1D9786BBC8A78FC109DDC99290554759CAA0CEA1691C0E2F1ED078DEC0C04A78826A459C1ED8B4A569503A142A4D6FBB8E26A06B5A014D691CD79EEB46C2E980B674C5F21072A560EA1068A079FF80FD9B1B8F44C50DC22552946D0E7F02EEB28D7B223850A6CEF8A01DFB3FA8C6BA9F9A3090F0383072F01E2630F678D660C0DD6B9C280B53CF4C99BEF4E72AC617A852F8F5ACE0780E8A537082EB8CAB63886589006E6C5F3B14C1C461CEF8100969AF274584C1F24FEAE0F43D0150BB87AA8D969F584BA77098A43C7546E53D2CFC93C3FAE48AAF554448638EB6D2D13793302143DC8DFCABEEB1F654F5E9EBA944A24546498865034204DD429ED6B6C8A65FCBF746DC443BF8F147078CBBBFE59AB1141966861A0BE4E95D7BA986E3B1CDC54B06FD0919F7D14384ECF6FDFECD00A5005BCBA03C3BD70461263299381B2EC69EED30F855BD86B3C7C148F854D76114F2FC495B5D744EFA5213C9C4D1BD828B8402CC5417C247DB4362A67F469C3A3EABBA6633D4F34B4104FAB229BC3721A6DF64CE6AF6DE84A83D859BD053C627B28492535ED37E7D84ECE655F0EBDE090ECCA26A6132A3F747F071F294244515A69BA021F214ABE32346684898AC7D2ECF42B2F575A7C818B8FCCD7F4F6FF0000000000000000000000020710151F2D", + "reason": "too many hints" + }, + { + "tcId": 17, + "testPassed": false, + "deferred": false, + "message": "D5CEF84F7A7234B844DD16FE5F1E9DD744955D23E9EF8818FAA19ACE0A9AB6392850C48CDABE3FB1625A57E38610E80604BA1C01112C43995BD30EBA2496139CC19D0F4724A19261976E502C88E3EB085BBE651D3677D63798E92E6C20D620B387E0C7711943C46AD75378E864DB82893F2E9044499B7C890E288AE90B69B40E", + "signature": "41A46D25AC11DFC0C8DA30D7CD9AE37A9E2EC564AF48C02C8F97C10704DCFA791F7A53EEFD626B6586C75C7B501EF5486928EAB66BB733E07E176DE56F8E64D10EC68A8311057B6F858C22CCE4A5661298D7EA48528D5207F2659010A94122519300627CE5D0F7DDF0A9101539A0D21A15117BAA14621D5C9607B0DFFC4FF87C981A1BAACB2D2696F6A7A93541D71F20D8FC9C4D4BF3085A050B473A45B8CC101754435384713A7FF622C2CF233171912DE74870A073DDFB31B21FF3DA4D10F8CC02FF8E363D44101D2634D510E7452C32755F739AE6B427A81081350B476A4AA19193A9A048D503CF9918C3B712BCF2637322550B854E82061FFA931CC0D6947B96C803764CCF15E968335F0ECD5C8A25C4412103019670A2604883B207E25A772C2D106BBAB2E3394EDF27B02007AC6371250C94429BB2295D93DB0F13112A5FA87D77EB8D26862202C14A2D87B7FE9E4CE680B7A20396E391C9DA0424BCD5EA3488F0260AE859DE7C97E7E6C34DD32E1DD56A7A8DEEFF0257783E98C9B15A7AE673AAE7A13A13135466D0E7CB64EE95C4799F8549E63762E35BEC0608D7384FA8D1E5EF0037185160444107B07D87A7F2136F1C0B10D322ED299A6847920364F835B35515FFEBFEF21AB72B958806613E3BDFC98A82E2B276ACE271EFA41905614D9CEAB00DABEB1922E0FB475FD5BD2C42342845C36A73BF42AE17DDD867362829D8F89F4B4887558E7BB123B00225F42E1E8E37A7773D00000CF967D69B75C8668FAD82C6F6325914DAF958349C7D5E05DAAABF604A24CE93C672ABFD6520F9F7C687AE01DD3D91F08A4DF299A9DE3E01E2B6B80FBFE8870A3F492835982C0B4019FF39554225EB415F5D469E2A9CC6B89516B76C14992560C0130FBA02EB9123EEFABDCD802D875B5ED5BCD7A56F3457246D6B68CCB9228CB04CBF5DAD2B7A05B77A3F62DCFCD4CDBF75944AFEDEBDA48A0AA051BE98148DE2F81FF91967FBA311F8EB5456E5745C64F6000214D672E8DC43EFCB2BE8D6143F9AA7B301A343E1ED93D324D3A71A7A33DD56D97B1C0DD3CE928A2852BBDCA57FCBFCEA7119477CB0DA51FE44E50C7E21923947037E1AFD20FF81B0533B0289E188A323BE9A61AC5F29027CA360D6E8BFC1B37EBB3307C69680BBF37741A94340EF4353577259709C45F25768CA9EF0EF09588012F284EEEAE4D435E37AAC4963635F9423A97BD11C43A9FBCF174C43FE875D49C15798D35C6C2A1E38FF0AA86B2E7448D66CD2078C646C1745F59D2BC9100D7A61822A5CCBAC672DC7FAC6711432C4864937D90EC296AE75D2F07B7B1136892520EF033B394EA7B490F7C92A3CDDDCDF83DE9C0148DAA0624D125D25C2E70719D937085B4182C0D6D59D602B5B2F501F34A545F11269F35B870D43DDCAFCF544A6BA598430BF99CD2201558C49DB59DF1F7DF9D74EA2DCD814F214A2CF28148AFB13488882C090E413D118F9613E3C5174FA8A0C7DE7D37D8EBBA0376B57F8DD651653466FD7D5FFE5BC036747934C82C8639E4EF539D0F6C6E14A12C2C70610EF0CCB52A3E7A8C2D9B1957E5163A40F633808D835BE042262FCA9925315F73A4A3E2A38C8ECA7B84A044DEF8E5F5302070E634E56F6C214ED754FA9F8725D1729511A40AC5A7DA7356F2FFDB577CB69476F4B064C47E121ECB1A50AE0E7B2354D3751961D705751AFC789D5256BAD729C7B418CE6936519D75B56A3431732AC1D48010E29A91CBC30FC6EC973A48079E847FA32CD1CDC21E39F2E4EE3B0AA90EEB4C551A9A960DB6A3F5A8967FAD231BBDB5F6F99F49CE02E9BB62E86947F53E96E3772ABBA6D425E315E8C2D6E673CED8C9C73008D9111B53D96EA61ED19C4B60C55A15D265FCA46C76DDE199F2FC6EE573527D04C1047348AB09FF1C4A722ED626711AE293FDA3509EFA76FF1FCDBFE0C661F1B51F457A53A4A228C93A3E6ADA6487C67D3B74FBCE72F812CC4C66816D137A9AF266A81A8A20BB71A55980B79F7564E9D421D2822024B1E8020271A2C1D8A41AF0E086E5CFB3FE7A70A44E6E9D3DB48A818DE6EE2ADECAE6DF102F546337CD6BA9AB34CB7206C2F66966CDFE50016533D4A2299B8DBF60A2034ACCDA59B10E2E0D95E60766634BE61E7B8DD7B432C9E842F609EEC1C42DEF8B33756A10C17CE782BE03787C100FE2E5C668EC947FE21D7AEED873FFF010A6E939297EFE68752167DC81F84C0FD6BC8F8EBFC6E2009C521AC503B9BBA57A9A8AC1D770E3E310266C73847E2A843F0D3C3099B8531DE2FB3BAA9516C97DEEE06D26BD11B691933E40ECB46361A8D31B2CF6A1DB942DC0B00B193D5F20ED40D603CF48E24E56C9786D5704F8ED6DB94B26996456214E3746BFF6CE971D813115AF28EAADE0FB3F2EF6180B4D802FD022F787192AA75B7E7E2D11B6405060E29E93CC251983DF2A7A69772771A2CA7E1AC9528681EA8820151F4ECAB5144C0CE88413789335776147656FB6B085320F6FDB9A972F0DB63CE10AE722761CD538B5B7D6457119FEEFDE7068A529625A1478A43F85BA01C9FE1933155880CA6A4B24EA043C36879AF2EC97F2E30493669AC8DB8375E8A782F2EE16317D742CD2D1EEEA354A20A2B08431AFA6C67A14C07A334B3D7AEB0ADC26EB2069E2159166D59FA14FBEA6EA2F0F2678030DC933091264B5F9644005D118FB26D09C2EAF6D9166C15E3AA1243090F10996FD1E7E8672C650BC0BD095598FAA5DB90F72CE7147FA31E1C67248EDF9B75E84D62CC637547CC8347606E5E4A353FB5D4928D1134B06D06447C106F8FF55E3F55B2128E950B7DC75ABF7A941B29B9CD6F9D67A68A53252315D4CA7D247E0A107849C1A01098F62F9CF601850496BBA2413FA23E8807EE0667FBC60E2BC76E52BDBACFC5485AF03BD1BDAE72490EDF58D4A97610781B338F3739753B61A42007D0DE7CBD42ADAD09911D892FE02787A0463D55B0108770D0D14FEB60DED8CD32ABC1B07C5FCD796D85B792E5F3FCD9634E325C30BCFE761B435AD214422157653A59BCF7729BC2F036AB7C5F7666BCD25E70BCD07313F93BAC1E62215EDE7DC6C2F3D4B1A7AB9C84DA53F4165F8110AEF95F5701D02E6F9A912C4850BEA44D37AA9640809F2E0B42B8DEADE4E9438A6F1B615E9D2DBDBFDC71D9E47882F9D91B5FC6AD5B2843F63236AA99C894C156E876ED6EE88CE1401E938533A0DAEC0996DF97A6079C31A7DE8B8AAABF05A98A681785FB6F5D03F5EBA0D43019D613B3387F9DF0BDF47B9F2D64699C7113851E53DC4E28F7379A85C07A62445D8BEA23C3F8CA145DCA267E5E95E9CF3DB3DAB806BFB39BED68DD5576EC5834DF9131B3B112B80D256274553B82F60269318E721175E832490BF145798DFC4B767FF494931C3A2BB2E62AF33C4C305A3706E2B0EAA0A26326EAEBABBC04E89361A696750271978F99BAC4CD2BBB8D04EDF9F0AE73B0B0B45213A959941A8E774F74073B9E483A94A4737E849D2027E2A656C2AAD8190C73721A545A1C4A30C46674DA3023976E49236E0D332EF4EFE5FFD0872E2F9F170D70601EFD9B8DE625CC9325129E1F13EB4AC5C64F051463C994F54252470BEDE3769FBAE61F0B05C01C306F5A003CF37C34AE18FEFC74E23CAAE39A966289BEEBB4DD5ACA07AA4017219E660621139B11BF6FC52C294452A9DF4578A0F07DB7BDAD6AC0CFD9349D12D2494CAB88045BB7C75244EFA7CE6F13BFBC6A27A202BDBC69BEEC46D8F3A7C670DDBC6D7C6C72256EAA21F64D6FDB52AC54BAD164A0D1DDBCD361C8F1C5A747EFEA7E56FEE083F50891765CCAE43470A7157C0551390AA73DAA380ECF6B11A850E4A17463CEDF89A41743636C28D58B571CB69D8A7E99E59941AAFDE9210E7AF4559D24310C96140E43C29F3DD385F55D9D7A7A678F9FA7545A13CB62118E3FE2D8B1383574CFA80A1192F46FB2B92C3B8597015094928E91217B8B3927C48F71B189CFF533767758DC89EC5DAB6A5D031E96D0A23CB2CF76FE6A0747AAA990EC6B82CC21D8BBE0D8D805270E3898E4990DBF497B7292E8549D87F224949F2CDB690A88E3348D03D9736A9F6ADA868580ABD5F96CD0DE30F6490BFF18D8F9728E84BB595E7AD81EA5CFC1389734E1B9C5B4AA3DA8C5B6EB7FA272C36114DD442A4E951EC170A6BD66609F73331DE4938E82C92E5090C4CB50DFDF3B31E9FD2C058CFF7480F0FC081745B07AD6B5C6BC724ED85315936B9A49988623E15E9E7BD5D17C2FED4FD819EBD9E69F3B5BB7941F5C429E4820A45EC76E04409154667BBDAA6131B9E12B957610065A769B1314A9EB9B9C3300271355D1542E2B7F23E8FFC8EE0CFEF10EACEC97D3476A3FDD999188D145F4B7BDA19081D099F2FB1013D65247BEE63943E9B783F701F6F8089371D0642C55F4BC86702CE6B1D78AE140012978943D42E0E86FC0CFCB09028AE47CF80F429BDB65E5F9350FE991D50E803B70B1965BBBE7A6359272EDA393BB49E4F35594DA2F6E8B208ED81C743C028B7ADDEB0A2CDE6A38E8A740F19FD67EC37AB2E5BBC060ABDA35A280777116661137F76231991E28328A390219375F88F915262C305C666A88A7AFBCC4EA1541C4EAEC54595BC0EFFE1C869597B7BED9232783951720436570C7F8000000000000000000000000000D12181F232A", + "reason": "modify message" + }, + { + "tcId": 18, + "testPassed": false, + "deferred": false, + "message": "322A8DD07A5C30E8696FD2A11CBE14DB92745C958ED07B3533E8FF575BC056A26E83D681FD6FDD8933B1692B6274851D0B41FFA4BE760E08AC8B4058E5639AD29B3516A2DB1F1C92191A0C9DD927C17340E5BBF593F2D78426B2A11A02F6A33F4E425324E8C502C636939795FB35BB4DA6424E89A3E815EE59FE68DEE65325B0", + "signature": "5ABAE281A15ABE7A3C0BE553F406B6F0C5760900976221B0831DEC6F144ACB426B3A6252D517C1C592A5A9FDF576C38B7B8960E781201346EA99AD5E52937E3CFBEBBB40F0E29C17396A808ED58F8033C7B4BAEE68A3C7811F43DE3C18E02A38EA071E043F811A95802B06A37BCCED5053813D477AD60DF5A3A5E23D442153E8F8DFC245741680440CFFBD364A0225978DED965EACEA576B0C482568093ED4781F48CE4893BE763A36D7BF726C3DC81306E74A1E6261C045F06E990169442A81B797E2F0C40E917504425E4E6D971596FD1C760458461560F02B2149EA1A8B9C2840C58579EC0A973B46C93C71FBB3BA7EA31B9703E6E908FA0FC01E9FA00F847A1023B006767BF9783E91F5F37125D36E2C8444AC340F7B2174FD03C66F188272EA4E74E6DB0CFA18D5B2A63DE17C7F53F8418BEF351F36577099E165DE01F8C302B3DBB987779CDC6586B8DAE20A2450624EE005052ED95E4C12A2CAF1FE20A43F7276BAD038222C35F930D7EB1BF3172E53070D424AF84EB4EC1678DCFF2B431C5FC7D16C4711CF19E6140455E526105F174A16D3733FF91FC81A5E92C6A916F4D8F9E2F334DAE8804E682B5317660EEED9E8F9C8C4E0B0C07E0BC4AB193C1A47501A5982592F57289FE5C919BC66A861429354AAFD66BADD3F3876727BBA4898BEEEB6AD7E5852493DA29688D4F480398E75EFDE419D9EDE15FFCEA1BC5C8183E017B9F973E6D77CF73B6EED2BDDE82137902DEB9A258BE6D217B9DE7A08EF0018E116F98440F69D628BD127AEE447A17AB8FFEA119A3E69A11DE67B15AA6F9AB63500EB3764ACAFB465068977215D8E310505B5622C3471EEFEE54CFED8BD730DF2C7AE1C8CAD99D5453D58F5BE0FDDA386BD4690622D8006B1E95ABF5BF862229E34F8C9FFC8C0662857178EDDCF88E8E1BFC265734B28FF951EB8F303637525E7EF1348F40A7B14709CCEC2CADA311863FDD0DCBDDF8A4FDD7D78AF63D5EC7321F15FE15F1AFA64A8A622D00A7DAA4698DD0FF584C1CE16483AB9862CA12479BBD3814C8E546159EE19D490BE8A8396B3D4F0C6133ECF602BCAFE6701AB3B645A6C3D8BBD3DC3DB1D96A0511B3456290BCC1C232A44C7384913079CD0E0CD99CD7A1C91D2961270AF6CFC60E50B78F47C0B7B0926575A0440D14B84AED885963CFF172C8EE791A84DEF0E9AD82E80C5CDAA04F74638BA355837C28275E456833AD1094E454E9339C421CFA4DB9C3454ED084C8B15F94BBBE62953CE2B3831771D9B8BC8081CF76C285F9A1CFFA9C02E7678CA0989E4A267FB1E0A9CC41C83A57D896F09CDFEE5839DEFCD4F99E71553EB0CABA990A1B41B3985423D1CF5FB65C9C8A651FB38A00A46601F9A7A7C06873A4D65FC7C451A7AAD7AC09C9EA3CB1C98CA8E180F7409EE43A9058879E21E860908CC433DACA33AEE10A81E16EB56DD4ECDAE47252DCC85335054973D69E4E5BE549AD7FD1BD5CAA5B259E0AEE35ADF5E9AA6EC6D67A8F1E615F17D0936926A44D7AA6475A34426EADA003CA8DD2D541727C1B2052E261977A22A16139B2E1D04EA110392BE90F35453C215B11BC54E9A06BC7F31375C45D584200EBBEA77A025D9DDA57B1D815C47F5B296F1E66D8321E1B448620F387D19D97A36530FD0CDF6E1C689BA53453DB02B6B0BE903E3D273628D577288A376DE0D2BCF349905289BA6EB247FB54AADDF51D8C219977985715B33C10FD9D8381140083E2485DFFBC4C55D70C9EEC73F46A29F61F76C019701293D684DDACFAF5A3957620E549CBAC75F349F8C3263486411F293BC198A1EF6B7C31A947FB51F35AAF5637ABBA1984F1468A2C5E7E80ED3664DB8AC70647120D249A9F22223DAADEFAB3D4321A3DB39EDD8EF4D72FC9E707C92C10032BA6FDD56FBEA999C4347284659702C34EE4C23A284646A38F3D02E08142A4977DB49DFD321BA864A810B4B5545640F3E441C627860DB79C69D46E13AF6292D505C35BEFBABABAAC33EBEA381B777CE44E54AA9C9619BB6AC07D91C1B1EC448DF9AC348E7447415EAF09D34D8D3D7879B44B20BB243C6251607ECC3E654A317CCC72EDB65BB0E90128AA47618DACE668BCA5BFC8D68A4A020AE6EB60F886EE1DAF5D460BE08EF65C83CD46C1745F7D313B9989D9910F866FCD0564E04E6223C0BDA00EF40AE9B971BF49E7AB0E5D055AE96C50F96D9CBD7C696946D308636B0B6F7F72F0526FFF23D0AD61911ACAD1CA72DEBE007663D691548BCB3DAA1725578FB2551C0730056BEA3E63E30E4B2A667C58EE7A5951263CBB74A9EA776366166FDC60B3AC3A14E4FA1808492A899FDF85C2C495754C55697EF4402C76E8F09A201126F97313FD2628A4109B34E29D1C3E4E135307C8C895FF8E3542C6888E728DE15AB81E73594F5368350E02AC4B1433AF200E38B0EAFE09317D06ED9DA3E61A82ACF924249C760E159358438EF1B32E58F0EA4E7B3EEC423AFDB6F4A25AEAD2A6EBE96B140483FB2C1833F826E46F62AC5428D6C3926216DA16967419C60EEAA7D7D3D9DFAA94A411843B3AC026EDD80A73B52A5F29CC0C2526AE660128015BBCFAF0A0DC18F5239B2A397036D8BABB4E366449842C0820889182C742A1AA3CBEAF728E9E22E8473DD8A7C0B70800F954A00E73DF3992007AB34BCF20B795B4DF3392D4A62FC52EB24D4598574B85E6CC188CFEAF1FBDA45B1EF57B99C89347006E4C3C3E0809EE541B0AC27773875ED6C1EA615CE5190133EC07036A014E41B4C99EA0E3742355A02FF0579DDD6E7AE9B7F0A735F770B7CD157E9C5893592FF384DC78FF864C2EC5D966305E82FA41AF3818A122AF70C54B16282958D262988F81D7571A845A541976E730C37D79F931B73843D41E927A677730BEE342F774C8189FE5547CDEC9F8C4E5D8984EBA8DE3DBE9DF73AE965EC39F6FCFA0868E30F5DCAE6AAFA62048802E7A99389EF1CE6EAD5A9C8008C575B8D41844DF779CCCB519EE6C45E9A2869F09AB938F4EF564B40E7CC9B6944643C3ACDB4C3C838BCEC1E652069012BB7A8428FC8A1B205D7D13F36F9BF6814AD4C8D3EF646B4E5634C794FE0B1ABF6B13DC41CC5EE45F84234C77A403D306664F9D7B116AAB371A769A4ACD163EA5FC8136B26024FE501088D7698F3F5780F5CD350B35419752FB98C5DC5DF3C360D67988DF71CF06261FBEF28EB46D91F24B41F8B82F5617C1EDD527A67D4F9C1A4B46CF753359A0D12933342C1E274322C13D0185125A24D4C20C5950E5703074CD6010F9B3179D56CF5B9B351D8FD7DABE09A729F8DC90D889C2FEC75539672C765AF0BA41C9488BE77B51C0BDE49A7B43EE9D93272647D129356C134B43D5C38D7294FE164A366625E239E2EF737FBE5C4A3B16C09D38D4CE6C16C783A79D2EE0918F4005B4B703C8D08422B8AFB93D4594103BDB1FA7B65B889C93B0436D7E830E1DA018BFEF2D52E3FB48DD19BC58F59899DBA4B81CE01B40DC4B42FFA05CCFE2C0FBF53C60961B8AFF7D3B2053032630C54AA105B2F3EA1021405ECC07608E87329602EA6B4FB0041F891405C8D9F5654FD17826074A385AA29BAD71E6727045ECF8365DAB7DC5B8DBD673C1231E9CF5B4C2BD9F870819391909C5FD479CD973AC7DB6C16ED38A2CB9B06481081C6486199A2AE7DD612240F4E14CC09C7614D5E2EF4465A83462D8C6C26816BB755690DCE898A0EC84AF3FC773C1A1F9401764D2E4FB346E38709ACE4DF955A64ADC134A7200213CDCB4FCF4A4189B1F55E917350E90EB5A5D7BF1EA9CFAD58C92B765E95D00DAF217C68122BB85546E1BBD6BFE8A47D0038C1D71C425BC9F6B978BD2C6E2BC5A99D89ACFA359BE65AC72FB1769B106FE0608659B672FBF22FFEBFFB924DDCF744E964490689A0CDF9A9E0EF4385CB591FDD8D64B587EFFB90DFF3A1CF2C051EE94C36904CF32A6BE6D51D33E445B48766677E24386EE1F779CB7FF582FB54ADDF9B908C83B0A3B7CD7F393CA49440A062AD6E79B4B78D30EF43E157D9692A673650A993C4320FB20468A23ABD333621F4104ED0F4FF07A30ABADA4DB3FDDAE7C27B39635734EB60C0B06EB64D4F2965B3577D0F86B3B3331FD9D2BC74F2ADFE392C9E7A191A4009755D988D8B4795058A3A87F9B4D0B8B2FA649F41F68D7A3A3F9736B6AC164E5A937AFC7F66F28E6908337EBAF78D318D46989D0123CC45BD274321A1005F115CD47EB1839C032FCAC6237F013A8FD5214A87611253B05B2852BDA85E8B1643E76BA5EF2C450FAB484C0525B4B31377170A7DBE4C860CD611645CCD4510BF2745705D9B1A016C847874A2F8CD7A169E2BC0F7281556F0F326CB0B084DDB230726355AA6C2464EBD1EA6558E09942C393D98FF4D1D9FAE9199D32941E0CFA9B9BE406DCF09628782844AA841AF274E8600A1463A5B9250D80EFBFE835DF6C7E5E3DF2906556F1E0B8541EBC93BF6CFFC8CCCA6DAC6E6B2935CCE34205E9AFBD58CC1D9673A1AD76AC69B5C9970FF5F4E7F5191250B7C483E94DB54AA5BF6F5D5816EDFAD192F5EC2ED893BA7DDC881502BE0E9608A5FB3F30CF15D2BA23E3CA5740CD426762468FDB387D4E54D6F83ACB0B7ECED0035243A8C8D9A9FA1C1056E767908116E950E23525D7DB2B5EDF10000000000000000000000000000000000000000080A12161A23", + "reason": "modify signature" + }, + { + "tcId": 19, + "testPassed": false, + "deferred": false, + "message": "C23CE9096B49B3B16C601264D8100ABFDE745D21E8D54B1D4934BEE8FEBE6D84561E9AEF470012E12514CAD48B15B709B0BE1834C274715D2B30097E2BD8C537359E7A9019BA7EF6A91F955933774E52B2E9C1C4F6A322D0AFB4AAC5F6BB01BA6DFE4CDA6869F371830ED8E4442012D5F6FF3A2C9233368278E2FA0C2C010481", + "signature": "D26C789AC9F192902AF965AC03815AC01FC94634D9D8A59FE7AB584F024F37EB23D128FDBFF8B88CF78A0B3A9B3B65A3615326A5C57E9CB6E0E785B9BFE71FD99CB92F4B13F3301CF5FA92E16F2352F7099A3409C87FA240A9B4641E1D4BFEF00F0A6BF71600E86EE2052A25F4425C641D53B41D2D9527C06DACC2E404535919CC9879022A4436013AC82C9B6A6F4C949D41A5114749764A65FA490A620012E4E5F750F50E2D381BD0921FEF3E900DBB64EE32D20A8521287E9C5B38C4875930C3A6E4CD9237CD7C3AE80999A73566EA5FAF1028824FD8F5583E149F8EC08164F1EDEC8559BA29871308A41D5A1270C8C7DD5425C2F8CEF4FF101FFB2E77C96BB4EC02AC94D7CACBD3D70F6B540A23F5577FB0C3D40ADE3DC929397EFA7FC4BC522220C4795A6E28E0C876A18F3C2607F6F9C7442CD8CFE98986954BC839AD483907974984135948A68BA57CD127367DEF3D038DC6811A528F516F5C7BD8F3FE6C42EE77812A5E97D131FCBCC8FBD153182D24FEDB3B2CD1DFE5ACE59C67F81A45C7C58102E942A8F8DA73D5B9B9912D70F9D81C423E50F6289740EDBB66871ED8B9F4A7E2CE2B61175EDDA2F8F92A9A123CC94ABCC5629A44CC0FB10FC0B6231B5AA9607E0D931E0E01CD00B82BF3EDA457704C0B851639A3BFE49CCD75F85F93C41EB600C633EF980FA0974B192A9FA2524D9212CD54721EA40FD8043ACB61121FFA9BF191D5F5A74202C53EFC3BF151592BC7E34A0003574B2522A0B3AC1359522BB916CF7F96F7D3A32B5C5DBA09FDC73AE0B463C9832A8CC998CBD72F343444D6BA396FD5195C70774725009D54585EFA6C20FFE4181E5A1E66545AE0F59EEDBAC996784134CE78E47C388B247E295374FB538B67E7B05A64B918224F8EA06AC609D45EDB4382C5181CD167D772507292F043C546CC86DBDBFD8C4C1C0D158021CF93A4DCAFB98470C521D2B97D0DB7BF0CE1A43EDFD2EB6A8BB74765CA6B92610A99110466D818F598D56D86227BA96541F67E56C40118E9105C44883D884976F8123102994E3AD063A58D2B2C9B43806834CC98C63D43E90475E4DD62BA8BC782CC99FFB80E92D45F74468F5F799500435E355BF69CC12B0135D2C3D24EC61050949F10213B9A5C2DC972B4FED6F094A5671005743850F544747D3BFB8B3C5A5FF3BB293040E895C0E9C69E25FFC3B5B518FE2056CDFB27E8FE9007C527FD81074F5AE1D1D84070919F0DED0D45B14F79976894C0359F80035557E7A87820F2A327DC6436A1FB9CE9FCE4AC85147EDB0BF0A214EC9D1D4D3050C94A521C22ED55FC162EC8D40AAA5B5AC631D00332D4E1A3D39206ADF98B57CE9AC41236638E24E1F150709E776A91D12F5D93A542D30C5A145384FA03154AB4BFE5824E0A9B5C97F21EC74ACEB36DB12B3ABCD55BBA3642EF0878A3D96FAF554C6F339867C51A2D2C43231FA4A05C2BECFBCFB08EE96FFDBA262B1E51E2FDCC4099EA853F95A29E0A9DC260B9C239044B691E02738D442C3F1D59367AB1DFBFBAB80106B011CD7150BDF2A7B0F9A45AF105DCDAD153550D37F54B1EB4C520607470565CDA8DD1A7D12EA83B3E3E068288494A16FA864EE6C50F617EE28540201720AED47D6B727FC5CA3D2D11DC3318AB1C0B48368D94215D6A1586269FF91C298BCC9C866360C122C5157A3F7E219B0D04CAD4BEA9A8B517B3B50E8CB6296775267FD1489C6BCFC0B61D2329ED2937A562C8742590E9B98C3F4E80216874B3DEA5AFCA3CDFD91980016491A0208F42389F1915388000DCEF86AE8E9B4EE3062560414FE8496AF7CD6508393A35E79DFECE58CF388D7DC49E5DCB7ADF0364DF00495B26AA5B1E130E59835F8688EEBF7CC4BE433EC21AE5D4FAB50A93DC85DBC688D873E2F33D4D3358BB7B43EAB74BB88D983C9551BEB76AE33C22BCBD92A9CFD1EE4B0A05B90654624056DADE0EC560F50799643BCE690F821070A5E22CC62C8E30BA3D21658A335B143C4B96C85FB21B9B4399390819B56848E3A0A789DB58DEFE912686A37298C8FCBCC2A63E1A6D41E971106A4084ADE356D49D2040D196021971E1C945B175B118B9B9C619AA19C42C622CC603D0C555499D7AF6E121A34B24E9F2118B632A638807D961E324D1726B7A6AFFD20EB0F6C8165ECE661E2A688B5F4B7F95D919CFA2586DF48A00FF537D7621DF3C618EDEBAF87C250E4175DEFC07E53C04444DFD71EBA20E4C819B919D294C97DFA4ED966D33D28BC0E230BED3E5B71AF6CDCCB699F5F28D2C9BE23AB854CD45C6639C79F89A943EA4E7ECC6CE9170BD62AF65F3A03E29FE42BFE466A5448D728FCBE40E1EE88DD467A53AB8DCDE9652355452AB2D511331169D574F39AF8A022A79B9B3EBBDF0FFDCFBE400388BED569DE2B48BDF7126CA5030F1A6BD20EB90B4451C67726D8E3D85D05BEE892877D1A5494EC5414D33A6E3A8AF7DA146758347AA33C06C7095F137CACFB3C7D479180C43941FE2F2AA6E7791FBB66A25C4E4AB06B2C1A4DF85A8864298D6D2C5004FD8554034A7E8499FAF763B49AB68D6D2EA1618C9EEF39DFB950295E96423F104D5F48D71C1602F60747A042319FD9D9A6BCBE75DFE6EECFB4078522447798D41A9285D0B30C36B9AAA06419FEFCE7AB3EDB392C12DDF08BC5813EBD3A6D55042495CE8010A06964C1724EE869AB0526A99A0DC129A7F90B5BED46AB5F480912AFCB43B95F6E5968E075FFAA61E696A986FEB26F47F472090E966E74ACBB041A207D6161077F2C8D1DCAF2DD374BDC1A36CE0BC5BA150402242311DEF372213E800B8FE450ACB68B76E0627205982D41CABFC76F020434684C6AF085F7F1CA286689025CBB3089700FA73DC287B3D434ED0E3BD50C6E2FCB596ABBBD8A5E6E801EEC96F20AC2E1C2A9E853DE118E5D6A7C4539692535D58E011F8F347E7A97389775C1A9F8FCFA661B6D9A085227FABD918261EA46FB0D6201D1A73DB702ECE279FF88236D3538D19EB7181492A737D8A2DFE00595AA603A95F6DC040447EEED1167A3E427D1EA56AF160EEDC95DE2BC1B2F7465F2FE718CF31BAE5FD4A731AC9A71306A522815EB3F19D6D6DDF7F0AECE01C74B7F34A083A3552E60FE9ADD5C5A307AFBFF4D6416DF6639DF9F3A1998EA0AFA73C2202D8B9E3975E0944AFB73DAEFD9E145F79A2E9107115A19F9743EBC34D17F6FA21AC1F65FACC3BF5061289DFDA8C23ECEE83B90789C835C7E58882886CACF96A6902E6F20E5467FFA0FE3BE62A3428A04E03FE69BCC36E66400A423C789DA05710143E22BD72BF48AE4DE9F245F86E9DAE3665B0DBAB60B8D270C9CD43E757A178F8D949CBCA6E5D69B94BD08A4357EC5D48039FD07B973883FCF9FB8402B6280D9DC14BB0515DD167AFCBA4E66A72394A18557E1B0C74E2840B32BF5C21569FB16F0DFB33CCA31511C86008C11FD546CE895E0B9C10E92E9B9BF3611F8EDE669512E89BB1135D1CD2BE5D314A70E53CE1EE85636D2474276ACB2464AC94D26A8DD78E0C613E8EAFBF649E474E2730471B18E04748C451F735C04B2F00EA063103097A36B054ADAD1E5BFFBCD97CAF46B959959EB1B1F581143EBAAC81EFBB7D182162BEE1EF939F8F5385E9352FC2FC4B4E74751EC03071AA8DF882134AEDD888F86FBA8A7E048873C945CB01C714584A1FA76F477FADE061D37E02B1B1679B0980D6FE828C51C367448841F3EA7722891DCF9B6441848AD3B02782A82ED2C44390671D55DDCB38FE2BB48622E2BCB31BD932F89C20FEA7B054DD885E7995B006D76CFC9E88B4D442E231AF1159F3B7754132B07C7F9698EC48AB54C12042DD111301A5E67BD430F5FB5124188AF9A9182809FB670DB9A4A3FA5A3B36A30C5C8A5F12A879DE1AED9C560FFA9A84B5F1EE7D4AD1BF1CF72A70E67CF94C2615B34198C2992683637914805CA45B71981626784FF67F2208EE07A5A3AB76F3466CBD7C6A8CA2B29278C9065383B340B8F8700EA8C3F5D0E460A1C1B5F8C0D910E38FD3028DD6C39A86616EA08A0A6B747DC6470FA38B51135BAE7FCB061B20B376F031224A8E6B49A84D64F166E10BA0ABC398BB3F2E75352C1C2427DC143211A3CDF8BF7DA4052BE707F3193448835EC86A14B9E92D5FF836A2D54FFB592DF00402C288FC23E5210528707AABD320454091A748E2D8EFB0C5AD84AD0BAD74839899B619773BB68386A46182CBE0B9B48659BA3D4A5AB17B89AABFAA5DE7B83250CF322EFF7F6EDDD62C59BC315C8886D0695BE0993A0E20FA231370C0EAA9FDCB23D6608D246F148F2C004A46755AC799FEA3322C8B0B6226208A14BBEB62C54B2A82FBCF060940F9E33232F2886F5C5216721B47838BAB4CCDF46C74FCB564D39B626453E5F89518DDDE578D7C1013717ACE1A3D3014131C0414045B9178EBE3F525C2D22E197B14D6FCD88F11107B9B161FB11972D990B638BF56C1D517DBA8A2DDFA257F37C4E6B8DA9C9359541BDD9F1953D6595B082066BF71739B6AAF762E0A8EF266DA22BCC59EA80F6239EBFB3AB53D1E6771DBE3BED9743E15C4B4F9C3AE7231AE1D37B23F41696883BC57726EA5D319B48CFFE18CA3ACB9DD1D4677B4B93B7E878DABB5C50001295A6E7881ACDB476377B0C4C5F41D2B2C327990B4FD0000000000000000000000000000050A111A2129", + "reason": "z too large" + }, + { + "tcId": 20, + "testPassed": true, + "deferred": false, + "message": "C4F59FA2DE30C8420A7E7F096BAF6AD69B1C15A5C6E61C9D82AFCFDB6EB8F275BF5787186AAE781F487F9F88758C9C61F35D5083EE70424B0D0A51575010C2A907F49608115D33EBA0031509322AA7D3061FEC3162F96A565F98769E9A19235D89D1B21D60A381DF8EB37D58C6A2E483A8EB70736E4B7BB911F7AB923DC29F1E", + "signature": "E895DB64C57BC3C2A97F0EC933410E98F6216103E3423CAF06A671964C514A694EB6F65CBD1137CCCF8881FA403C5FA0E0B2F36B9F4009C378210D29E54A7A5A9B793197CD6D2F38D7E1F3ACA69D48881389381C89FA676DE426D634F9A157055F17283ECE8248CAF14DCF11E2D56355B047DF632A18482E79CB2D5A743966BAA8A76121BB69C2E68155ACCB0A31DA6EDC73CB09A9E660FEB20F66C7BD967ADE32149C5552EAEB2EA175B56233F3B370EDD8679269CE0D2B43F6B2F65FE957E7AB37B982043754EAC8A30B36C10004EF13C692E219AA7AF0A4C5286910C7100DA41E17BBEF2DA2AB03ADF3074BA1DA15BCC84805B89B9DA88E9B400AFB7E3BC8338D354DA953AC0BAD822756CA92E5DD9507F42BFEFCCB32B4B91A2BE5EF34C2CF1177EAAFB250AC9ADEC4BE71807589F1003227F9B76B74E07BA67AC60819B2AF766A47FFFC7B76D3A7C077F5EC69AEEA3E963859B82C2ADE58BEC2152EC8205110975D37C6505E0DC776FDE071097E93013D1004F4E1A2FD79B877ED5025F527F3BFF137F041BB9BD001E949F08B4CF88DFD32FC7CDBCECCFDB0FA2DE7823E110BCFF58A412CEA2795753E9C89678C3AE24268F7489F72974B6955EDD04E190D99BB0D7A252FAD5BBA606C1A1F3ACA733BFAE3309EA0A6EB7D07E36D8CA336D2644FCE1A41895D014D1A60CB106F3F8075F9378461738D63D115D00B024C677801050A1B0B50DE057F85DB6AEB2C9D6BB7402A66E3AB4DB05C58BBDA12F695958B8AC7B4E45EC6C952F679C1EEBDF860E348982779AA6988EFC2AD1DC1EAE22A27A5B2C61C97B3B2493CB6C13C5F6E20A67B88D3C3ACCFAF0A425742DF240634D1EE593828FE6297446C076F979055988AB834B2BD82E14DC086400E1C956CC0C30CE7BFD962223D23FE9494964A811B93E8D7B8F34C89AAD45DD4113F2AE7BD94B53FC86E8B2AE82E51EC6F3EA4C30D60B86072748612D1607056B5FF6A4500EEE78A5A639C7B74169777626864DD9EAEF0E3AD8493D831F71DEA95BBFCF81423A266DE56F3A8FE8E6C3C0D612FB62BD642188CA71CB89834F30BCC28BD178845F1F6F46C03D306F7ED4E68759427AEC2701198C3C05D385DFAFD528CCE8425BC551469A0ED681BEE4D12A843E333B5A8E0517FC61906F9C4E7809BAED4D3D16EB22F1FA9AB402D988ED59F9FED0455E9260FD627A24A17FE7CB63E530B48F5FB6687A2E8C49DA79FBD69A3400056665DD11D19A2BC4DB1D374AB6A6E42472A27AC6B98F676E8EDAADD514F6D44DEECDAB5A6DFA0F84F139A803A2524BF335DC52EA58FA50D98FB5CD55D5D50A663CF647EEE56FE8E664B3BCAF9E333978A7946973FD113E4FD3924E6C09E60386444214DFA7A4D671FC23890637EB859134D79E265C59CA3ECCDDFA018223C9BAE1CCA103962078BC5F0DD02246FA28324F7CB2FCFAD07C25B4BC2D888069B0CF5F23C761C0E47109881CD31456A64B940B4BB9B4C2C3B8E6BA834AAAE69FDFC47D44B3C96887ABED36015E7B64E8542928F277CBD2D3C512C24DEEFE590E81C684E063E7AADCF117B48943DB771FC2207F57A745357555D419C9CDCA35CC1A7100A6913A3B6AACF796FE3F94DD2F818982716CE0316542A1B957E12DA43E231542CC14FCC66D728A68326B2BC311248330F3E98F81EA38CA924A8E4DA97CF673842C759F935BE88163CE97FE4D9457176F5B8908AF948F74D5D1DDBC521825D931C63CA8A8E12242626305AB6A2E0624564EE041983C18C2952EC3D9D159BDE3985CF77897EE2DC888112721D4854E914A5397E08B54F4A54323FF820821BE026EA091ECA6B7D80D91E3DCA2EF7848B86FCA6BB40CE48271E1008368E3EBB5E395E1CCD0D178F1A6257D26B6BA4B7CE532CAA1E76CE28FA4CF9E029E2482B94D3ACF97A326D235D1BDC89F70002198451D9F1F12CCD5BCAECDDE9E14AC80742EB31E6464C83210A39F35098BE0378D074CE1CCD1EBC1C7770F778D605F2BE59DB7EA07D80CCDF55F16E985B142FB7BDA07AA7DCA5B201E1950CF9A728F21E9A9D8AC4D1327E3BC0FF339A250522F631DF2E75955154893E4A1AAF9866FEE1637EE1AA5106D244E99E6F31FC5601BB7B79BAD82860B1D6059D9B132E026418020DB06EB8391FA15B7A0F29E36D966ABD3D2A2FF3F2AAC34C8B45C7D2355EDBB80B224BC106EBC6750E55070F85A7CB6003394E5161AE26F5ABF83F0DCCCF69B86139AF8694FE1DC00781EAE09CDB421814878043DC9B0530E5545A165E39A9B7DE88B4AD2AEB90D3C329412ED2FE1D97B732C8439DF4F83D228835B538DC278FF0A2DC42F41B00CE3ACA06B05C4839B896931515D78EA3673A378279F4E89CE08E3453FF2FB453BE031C6318628A731D029FC7BEA2BA5EAC4916278B938A6A6ACEF5BFE2158F2AF43D8E56A0649DF28A250D2F2536ABDE1E008EB631F4BD0EB55573A40539A6004181A9D2BF7A1E53504F11E014840733844131AC668946E5B827289AB6B21366C5D0E2649219B92C4760DFB705F7F61A96564C9E840D14B0BB0DA82DA50F8B8E752BBFEA3B0A337BE124F72D8F8249195BC19C3E0B62EAE496D38CF7500B4F10665FC2D28B9EA935F7E316472F4FF401267541BDB62301554B2009928C6445BBD0EF21D09972F35081ABA9091A6C23FED29F5CF9E0779F7EFBAD88E62A454442B30079BE0AC9C64826B98C1E1001CB0FB0F0A95F7965FE9312BFDAEC33F95065C8E59D3950F80ADC7FB334F202D3E5F8DA481C9B54A75983930FD1E5ACD16284F07193FBCB50D0DC00EFF8203144C11EC61420FC32D7982CE896406BE769A75DD8D3CAC753ABE5A278655BF54BE33A1B8374EBEEFF212C39CE514668F1C456EAA2532828C84293F1A5BC9EB5DEDF558A9B4C1239F77272C67E1AB28E1EFEC5893E09C10662B53C8B8255B1C8DC8F8E5120A25C75EEFE79C43F7A8B37DF9D1E4F32486933DA1CB0664C5DB39E21BC227B0CDFE7A5507F07F218A7A47DEBCD9DAD7247B4D045A13AD4F75EAD2D45C339D0DF04577F2E0FDC780392553033C738852B1BE4E63EA3897D6C9C4B11AD6B58D3E2D342D32840F649DD83E759866B7381A84C8ADDDF413FAE18E6431B1EEA73A56CD889B76BC9786BEDEDCA2541E4C9B24E28F58AD374C1D93DF2D3F2C37EC594A0498C574579A7332F72C0F9750877FAD5B90B968D88F11682C4071E4EA38B816AEAD6BE54D2F371324F2475B862C75424ECF9858AA4E200CFBA412D7E3E6C308D8DE11DD185331AF9D41AFE8879965D6746EF21FD98D3ED3806FB5C4619C98E347D76B8B89849395561EE286DFDFC6A04E1D47E9F5B5B49257784C39364DFA88AD630DFA59CCA3237F4A2B141A813D22C6FFE73C2D99ADC824D93E06A54B6DE62C3125D94B49E950DEC361F961F56D3671C9925377F6E670665322B8489E833D3830ECCDD0F53F4A4F9D68F1445F3AED5C9D766409B59BAE7A72912E98B3BB57342D29B6ACFD14336B7B8B6B7549AF8CC8845E10C2811287281985D5D47685FC589F2678ED893F57B85ACED75632E50DE5E074E6CEDCF1AD499BCE67A7F498564DEEC677C708388DE8FD7B099CFC116096C45FE28890B5EAF06169939FDA35E1215F238E8CDEDFE670065F5DE3272A232FD53C250F5D779B31694FBA91B554803676E4DEA288463FE1063009E9CB76C317DB400ACF4D2D2B6D16EDEBA4108913F60AEB252CDE413690CEEFDCFA638963DBD04F4CF21AD74DDE65F0F1E7CE70AF101A6DE9A59DB21D38027DBBF76167827950B69418266AFA444C728DE3624A1C81E5B1641DBE879CD822FB2303CC3A9FCEEFE3DDF7DBD0B7057248A28D6062D76EB13B92C9C9D003B69E1842A54C09CF6B484520815E2BB237288C64FC696FD3BC45DB30CB86465DF1188BF47956E5B916A8009715CC9A9A6DCE44C54F928816B41D018C5FE652FFE4E33F352D383A9C1365F02ABFD647BD6B42AD163730F8BFDA1E2BE5F614D79597825BA09F457D3CBE7561E7E89EAF059E977D1EE88848B781F21F723890FF1F9873928412C8F11EEDD2C0C39C9512790986A19E17B2B70A4D7CF49D9D18CAA0C2023134CACD169200D8817FA321F04ACC910613DFF250EB325DBEF29EB5611B2AD2A23EDD538049B3F43EFEB4D60983792B4BF05567944AADB7AC4D3A5D80A1B9D8448B4C0C115C3B5AD3885353F47D5FCB9B7D6446F1A7210BBC667FC411415F23CD40A2A3D64061D71C67191571A97D01088A24B6711567FC89106732D8892FF985B8E6CF70163829CC085BE4E408315361BB1B2003D6413220B134506D3C304C0BBBA9C9C45D3651E0571B6B115177213D8595E143DB90BD72F7EB974D8D0A0317409D64D5837EAEC9B8D44DD7ECFF6CDA9F729382A43B379CBDD43FFB18AEA35C1A996CEF1488D3B7A81EE7CFC0B9623418AB3919A6EDDB99F222F0DDDB2F32A20C8F84FBF4C49B4CB3EB50D9C4CD25A6F7175467066D25E6437B67F2DBC70C2E6EB0BDE2386D03014A789FB6DC08EE33C0C67951DA9D74B9C94845D2A99037E095FEF7919920FE526EB5DD0BA1F97DFBD2DDC31609C1B7B45EC3ADB586FE3030A0C7A9DD034A3C2E6F9849093CEE10A181953547F8BE328720A4A5A8290B5EE00000000000000000000000000000000000000000000060B10181A21", + "reason": "no modification" + }, + { + "tcId": 21, + "testPassed": true, + "deferred": false, + "message": "C1E665BF7B8BD0198F069CA17EFC55B7EBBF9CC9D41140BDD0B83AA08062FFC717D3F6C22DF38EEFAA6EEC91760CAE0B3DFEAB78B03A7AB7A993B2097B7B887B9812AE2D0892B696374C034FC9E95083C2B61B09DE97D9C500FE55E489C53CAEBDB57BC69071C15808890F8A007BB5FE773CCFB729463113D93E9EC9EABE2047", + "signature": "051F8A9A5DC6D35B1485288359F818DEB027E1231DA8C048E79E9FE228AA0E9F1C0B7F4C573B5DB8CCAEBBAE8EE38D8FAEFD3B8E7730BDC0E9DE365B20E5A0F9635A0B39C7C0D6163B7876ECC6ABCD8A5F608E7253537C1C94C209C8448E02806B2B5EAFAE2483170B4E4450380C2A87A51F82B179EE0F46509404A3A9BD74D04BD75635B797B500F656ACAE5DD76B04741792112579E24081A6C88BF4981346E2B3D38291026D3AE47BDA50AB0B23B0881148489CBD057CDE9A4F6FF108B7ECCEA44D599CE3ADED82AE0E8F74DB7D604161C8664B7389497EC9F35C46FEC064BB867E867E9309C10FBC07BD5E7B8A74BBEBC1BD0E4A9B36EFE297E9F2D23DE32ED704EAA377F5C3BC4BABCCAD5B4B6B9A137F23C46C0423ABA3F1AFF00C6071CBA51B7D0A8E677F5138DB7C013CAEE1F68501430F0F448AB283692A18D15D8A46BA620EA906A3032570A659F594236F0512389E1DE63B8E40AC22DB79DE60CCB9BCF0B20EBEF676A91AABCD01D3AF882931AFF8C86A8C946E09B8B5CFDE62D53A03DF07163B081B293EA0287AEB97D1762F34361DDE654D400DFAE5B351D90742A0A269865D49C9221DD89E42FFA63EDDF449B10458CFE2EA7E1A16BD22FE73F208B4472DA8094F28CB9DCAED6E843C57E9E3258BEADA48D7761FDE0104AC6F0CE09F95E1F4AFF00515AC2E3703D2FC6D757B12DFDC044E854E50FF2D897900B0B59BED90BA4201694E29E6A830D8039CD835C706EF59E7A6B0ACA7B7D0B40D264661711E0372BAB7410A74460D07FA988A8617D31074950838411037307B052FD536822608F9D15BAA780AFAE1A8D87BF844D3A4FB31A176BBCBEA46A72BA990FCF821AC3A73ACA01E09A20AB93FC737ED4C4DC482BF9BA21D7178D24DD5D6A29633386933A3E8F28982731F07606AF28BD2D81004B044B4EAAE67E29840BC78EA66FF840031D8B2894B603733E1A0398FB0E4952B2ABC567668443581C860F87A76774E6742807C39FE99269E3199DAD02B246D7AC24E5BD9DD91F7D16A76E72318882FA21672A7D5B1A4F212954BE2B19897243F60C18D1DED2AFDF69DAB8C9B10342471C633B33C52E95A85D3142F2E46C681AF373C5E92BC948FBD31207F015DD32DE2591DF4639E4E563344D440653592EF2685E1320AB9E51837F6C06D07E5462599FC6F8BB120826E738E2223CD4B8C7CE446ECE681DC6D6BEF1D6385B0AE7E404F502B87989D969B81CF42085A7B58A41EF73EDC73056DA72EF65A7AC8E284E7F51E723102CFEF903688F870CEF1C7E5264330E3033691680050E926E93A1C0C4161A7DCA14A0FF338D431D68FAC204DA28CCD1CE7BA3B7F3C45B4FC74D9E754A1A2F7F23F0FBE8D2FF01CE4683D8842E8A1528589E7D9260368A654CB514A85DA9C2EAB74C66FA17FDFB256D585D28C1DBA35E18779D7B6DB876CC0A98CFF752A0E8DFDD532ECB04C4101AF32E689D13874B9F20AF652069C1458D7FB382E317AF49083B5870078B39221464F376EC0BC2DC1C3FAF10EA4EA87A2F9D547B535F60406E8E68AD190CD4F00EFDCD9D54D4810F31B9F68F0D95E32CDF2747B9C20FCD1694FE034EF6B5460F163AC78BA235A441DB2B3AE84BC28CEEED7B3FC2A4D63330D14186658788DFD7652E477B1310317C86921394219D75FB6FC319575745589F9E2096801E57E6AED2369FE115C2D937EBEA3602194B7432B01F55E6C9572CD0FF8BE8A4796815914D5F64D93E0E709C3CF88741C851C8BFC4CCE6F0AE60A6D2F4DC6FD8AFC82E065956971FB8B4160AD68EF7BFCB3A9694CC7EDEF64FF08011B183BEB7A2D3D9024753B59900D27F52DF6D4B2576BABA673A0E33CC57B501E1C74F63A988E1A157078FA8B3F2A143CC9D41A35412B4E0CE6B1D9CFAE7470BF4C778D026A9AF86DF7F974E2414FD7C5F0FF6D62293C6E2A62D4C5268CD0B604047C9658F97D9A7B86E1C953FFF95CB478028FDCAE6E8F208AA208A282446B2CE8B4C7E893E269FA8E02C082F82966A4AE3FD86BE89A8CC8BB3D6B105A91DCF76FEF700E5AA4A15BA0F753129D3369915D7E896527CF6E71C363EF65B2218A5FCB8D8FD96D6A63A8BC547EFC942DCE1276E268841BA00E35769B4AC706BD65B275BABDD530771D854EC38AC0529729786A86C7C4161B3E7074023516C84B4B4776AC47C2ED1587861126A7A707978F2B2B2972C20F237FC223B56A67538F9241D926DB7C992A3FDFDF999884EF83EAC7DA0F6523F53CD40E473AD370C77B30DB2FE408783D24CF4C3512E3C6B677C41A67849FA1792313581EBBDB7BE0BB3EE85330FED8B5A1915F6343F3B7C928CD363463385436038B64BAB5D055BC39D18F9A1A8196AF8DDA5A1F428434958F5C89F07D7A53CFF2118E80060C5ACA71975C4C92A589EBF5746AC92C50FC1F915C146C2DEE7531B24970790A4AA7DAC425940AFC4C88ABEB998D549681C95ACBE9F7E274521D44E9EB759C2946504161AE7FFEDAD3E62D045AD77FE8C2B8ED529843DD341E2E50559A29AE26D431C9634C4C19A84FA0257F71CDF27C33F14D57347BE8B19D254E3C353CDCA10489F06214161AEB2A9D3049B3CE4689503621C46D192C1421B4B033775D9218DD2E216600E64D977CAB0E1675666A7CA773E4E139DD4EBE94CE35A28284755C52BE490514B25FFCA4174F54E8A5F715F924949C1467A282D7F2DB468DF363F9A55E5D7858D8F95D8083D6A594DC1B07A8C4FD4AAAEA0785EA3D9B50798F0A96AA386F17C2BFB94FA8EA3B5EF71012AF9285CADB1FE330A267555A942682F9333AF2E81515969B76FDC020F9CD29E848B94F26F4B53CA5144CBCDA1AB6CD2FACBAB0A2FC0F5B88DA0AC0EC08B9EDA7CAEF502FDA52006815743520F841CFEC3B4D9AA732DE408D6FB14739E8FE77CDDB68A5F6AA215B588F1491988B4460F6949AD647DE9105CA50CFB413A971BC8E6179F0724FC28D1A7D30C41180735F4FF6167810D9E88A5F7FDF791BFB474BB5478544EA74C9F07598D038CBBA17B83228A18B2AB09A8BBD2D2205EECDF01044D5A1B2BD50D2C8E3D5511450A4E594C1CE7067A6E14128BBB36E95C143EE6A51CA0EEBDBE47E9C5A87E81BB904013DC892D03F483B1DC82986DCE7A6E10192E6743283202D78D11B2169602A75C2A688DBAD50C9FDF1A1A15A470D882ED4B5207E659A94776ABC3D3583E1D2E85291D3726E75B7AEF9344180D325583A05266C196ED367E906121C33E701D428B46865BF32AEA4A90262866A024209A7663EDA4C340B5AF3E899F009EEB5E8D5003635EED501CC02D5D11F504C823C17E961D0BF611519961BF422647D97119F5745478888BCCE367639772953C5731434B28913F3F709AF455053F6B09519AEB6B755CB02CE74DD814714A2E0B477C05202092525EC03C5B365A75086E3281D4BB5C3AD9D742806E58B5CE4E1E95269AB18B68B2928BFCF7EA683967C0B88ADA99FF35E1D5A661CDFAD76774B42F858AA54626B88050D992FFDE16FAD3A8CA496CC6BE339977BE24D33E8BAB86B421F4BAA9C12A93117E43415929F0C4DBC9737EA5586780886A8EF4E4295DDBC967A2B5523FAEE0C060468F9704509C4CB14028E8A1672609A8CED43F1B06981FBFDFD52296D7BD3B4AE68E7D54BB2405799278AE29B66E258D3B9D276FD34E192BDE869092F6A7F761C6DDB0DE9454823256C7B17ABB91003B1A3B66CBCD4F9ED068409161635F6DF9459AC382044EC14FE8B2A586FE02C74232BBBF27800ECF627AD1C6ECC93C13EDA2DC20C8D6714C519D6A571E708787BF342DBCDE10EB1BCA5A7FCD971CA52BB68FB33ECB7F90AAF739F0C5B61BFED72CDB46A712DB6928F84892D3EC2F6C7023A6B664CE9CFDC33D2F09D38B5E4D182C73FF1D7B474C8AD6E883ABC78FEC75C8A390CEA561A86B92E2A4A1950997594C29A35E4A71B0E484FCDA63E5EC9666E0A463325DBCF7258D36B85099AB7C81E70FA66F1A471D4C1593AE68404F31AD2667017C9B5B3843FBC48D831F6A9B5FAF7C73A8478A7DADF28FBD9DDF979418870AE61E94C6BD47FF2C39073AAE16FF18B161B9B21413E66E489EF9F8784E5DCBBE29127B0C51A5C1E2A04E9C8794964D1823ACEB9ED0DD555964687848629EE06B0712483CA30D6D4A91E047EA33D30A062D8249278CDCBBA2A1B3C133D3E671FACB034AD0F9AA40628C0E2288B56F7A76DCDFEA762A8DB323B44925285557C3501999CBE145D15EA82169007A97EABABBE69479E03D40F2FE9217F14664726DCEA227107412B3CC742E4ED168E051D9AD4468131AB035708ABAD78659CCF5988F70680C124468CB80BD9924B0E41CB25AA69E7877CF5EA348403AD0899A5FCF35D4F22F3A73F0207E96785F4EB9AB93B6F10EE0B247D31F3D62A85B99C88CD3B19BB68E69C51AD5B0A8E9E34ED611E24FE2644F1697A8A11B64B578FEE1C5CB31A605CD987D765FB68D833E4BE9358D869F4DE0362E6889FBE8E95B861E078CE6CF0FF35768AD49803A71E8DC60296032E50A9D0A4E64A3D4661E7C55DAFC6FDD1B18EB1003D290BE486C520A2F8F0EFC1CD2CEFBF7E2459CC7BA88695D1122A7494A3A41C329EED2A8CD2282A607F93A2B7DADF0F32414C6BA9BEC0CB00000000000000000000000000000000000000000003090D101922", + "reason": "no modification" + }, + { + "tcId": 22, + "testPassed": false, + "deferred": false, + "message": "9130D413AD0F370925A8F3A78063197F17C7A777CD304F31EF5925E55AE5208702FD41CCFB65D2D22B2D6986B1288E0E45C7053B9B3C08D2FDD07880E162378F2EA4CF0F715E461D0342B3D5024C0168D9074891744E2BD20CB32B4282D515DE036CD2B29068158D597A8AC70E14852812FB56F6413AFC0157607787EC9F978C", + "signature": "BE9D4FCD5E8BCAF5B1CE72E924F236017258F62B9AB8855FC614A1BF12D0961D783877B47AEDD9857F9FF79FB236BA15F170AE2603A2BF76F3CCB132DB762B95854BBD4126625A2A87AC57CB0B18A5D4321F7606829793BA8D959326E717C6E6F7F454791514C41598BD4A3D275A0D4B4424AACC97F9B2765483ED2D77A13CFCA170E9292812F127171A5EEE16CFBE43A2513B08E491A4F119C33411662BE66FBCD2C099916D5D7C346271764548C669B7499C5972D861BE96076A2C5FB9B4312FA2DFB58D0CBB02D8C29C131DED78CF9CDE95D0088ED8817EC6420F6FAB906D33F29423BCF4E156ABC4F65417353F24938E6EF40D7CDE482D258A55D22AEDDDE239B256AFB9F1F1537C9F220D6A4F9DB6748318B020FD426E3A84269A8CC3B98C0A4D68A19385B74DBF6208DDC237E17D6F374E7B8428A5E8E65A1A54C34DEDF025C433AED396C799520E2631773824F35F676B85CDEC1E03DF3E18AD52E503DD753A26731E3B68BC3CD0B431E2A1088D07CAD3108E873ED2ED6542436FFD9F8971BC059CCDC312EF3E37D6DF2B416A2EF8845FFB70664C1CEFE398BEB505AC690FBF6643EA3C11D3C6777FCA35CAB40A7EEC3E74263743F6627958CCC3FBC4CE47231119024EDEA799C52909C46A6E90698CF8659177DC72D996C77F6C610FBECBEB011F01591FD5729C0BCEBFC64CD098E19E013229285B4EF0AD28D7CD2E8E9639A6C62D654CE40A181C6982DD9C7049059621928FE7FF164CE38943853FE909E5736C9ABFE1B739217C69390FEF037B8E018CBF47872FE33C0389FC365F47CF72C26FD46A1A9490F5B72084CCD58B1F81F80923A6967D0EB9B3EE6150875DEA1750929BFFF42F1DEFE7D3E208C37EFE7EFB44CD500B3BE75E3D0E85758E035FECB2B04EDF951B3B42C66F61553FB6FED7C7AC657ABB82A752E16D0C162AB25B973F34989E3FBF97AE549C547DBC35A7E3B37A8645ECAC5D0EDD78429B86AEBE242135FA7F64698443E4609B6529C94E4297D70E9F6083F5A35169A4F52A6A502ECBF1A3FAD02041CA3F89F62842E8992F5D3EA932E6B3A96A09BD50CD45E8F37A1062514FE68DF32DCB1F73E29CC7D34FE2925EAD3C64B3ECC2813DDD2F11AEC2C69030984CAFEA9191F230DFFFF45928F6A4F789E508D26682CD6AC443D680E8E9795BCE04DFED504CB325A603FB8C349FA0ACA42C5E44B6969ABAE230F97D8799AAB41F58082FCB946DE9791D2EB7220D4DB4F608C110355F91DF9B0625100DE20484324F1D1EA67D5019F47766409144C877DF69DC3AE64343B80E5DFF07A1CACAEC20D8A27B7893ED1A703C035032B2FE04D8371A7417DC88CBD0B586CAD79A2B5931915AD32DDE4974856A79B086E44D30E6A9F857E95B03545A61EC0CF829CE09389432B50B01845CA5216B6BB1B76AC541136C73D2F0D2DA139ABF5E2FE80A9920BFA554830BBA02F6F178F74A2AE76369F0C0F1B27AEC1252F9FDBEA8A21E1B7D5C926E75589E3696CA9AA54BF647937D5CCCA98A385CFB145634F0419EAE62E8A325F74108A8295D02C23684761DF58A77B6CB23B86FD562C6D41FB88BF16C5DD11666FADE6B9827C8D37C56EB63A6A32C548BCCB675CD2850518AEFC8DA57B2B27F6DB88B00DDE2417D8802700E9FB0AE53A21230377C28B722DD3458051675152BDDAD610D2E70735869D085F3A76088E9290B78D5DCD9137D49C21EB21E36E3DEEE68D59953ED2EDA2C2861CCE3A99AFFE8AD4C130B777E2B62CB6079F9BA61866048B0E5C8F69E1BEB9DE2532AAA18962803E08B95B079CF3A08AD1AF5C0C0DEE3D3D4CB9CB0464979B5AEDD2C359853A7216F89F899456C910F97801B4EA2FE08197E77FFA5F73939EF6EA6503896DDE19CC808BE5FA91DFB8441DC5D7655E0794E62D82FFCC2586E791F6DF3DB0360319B56B400E6876A7AE010670A04D503DDB102DCD4F2DE59B1C629CBF3B0B9736DDA9DAA8E3B94FC156AF7C7BCB293B3C03C401BD34A751687DE8EFB6614CCF3E36219BE342D9438F55BCA880C2A0288ECA0A183E7A2C6690E3B87CE6D7DCD706E8F8C7EC5F0AE42689125D948885F47DBBD5B574F44982FBE108E8A66DE9FC709437BDB58934F2D3A99CD793598944AA6D7A481FD5DD52D56371F58D83417264C7ABA14A1E2F96B95274DBFEF317052F66B2AFFC603E9ECD4FB87954523BBD13B25BE736F759FE31D288CCA9265115A0A16A78D15E8D76AEF8E668255CF270AFA2B230CB9D9920528C8DE0885A24818C66A587C7F8E24AED2B9BEDC6C03F325998E7BB31AFCDB0AC4C0C31711B22F4692DF4B692372F3CC189B3650C1A274C9CB9F87AC3D69238DBF1A9BF34B3C800A791BF66F229E9D0942E46F390D2C871DBE11A6015BA9D59A34D8A38D7025343CFCBF7979EC8B9237443C4BED2BE54A58082931A45E0A98F9910BA4F2EB09260B0D96D446D6024EE2BB25F63C428F16882E903C427361EC90AB0FEB6FDA2C9133158DDEC6D8E9059AAA10AA12F8F32EC58CD78348ACE6512EB26163D803CCB9C1602875A692D766C859B5AA3A9E7D8966AFC1ED898ECCE5854532353B8C6ABC4F70153A6DFFF80EBCCF4452284F8C059B15576359E11B6C0A3EDFAE3B925222F1150F4B2703971BA35DD2D8D6C564B4F5E60FBF3BD5CAA6A7087C72AA1B566E339B18F794511AB00B1226645B517A6B84CD3C04E0ABC4EDDFC29B3426E62CF83916CDD0C2B30A1D569E4B6A39E8AD3B7BAB25EDF5BADB7B9DEFCA4210794BAFB6FB0E7F612D3674ED68690BC5D0152B15E8340FD8B612AA91930524EF917C6F9332C24B698EAA20EF9513B8A23001F8113A9E915F6B9A6359ABFAD88687D029C911EF53E61ACFD59CDEFCC695AA8724C634DEDF3B37E5038E6D95179C7E91BE5084EE7E6D130DE5401ED9113F552F227AC9F707D0C525A7C94709E4C1DF40EDE3DEDA83F8F2ADF77161837282CF2BC478178BF18A6EBBDA930C1C77730E7C3F9B9B80156BB45F912CCE523F6D52B4B3F2415F012A59D8E8A477190F084ADC66450F2C67AD4EFC74E91DC2EE2E582A41BBF0490D2F401267CA2FEA44AB79CC5A11DF418B357B9381FC76161D6D9ED5166A4587C212046C06DD324115C2ACBC100AC70C976A67AFFB8FA1A186F13375B11226496AD9440EBAE45CBB02AC351129DE637D35620B392C7266263F6D8F47A4E65CAF71DCE0BA4D4C3EDC467162397595196D8FCE5884975B7E09A3B00BF2EC46A054E326AC6776BBBD964E368B61458B085FB9AF75EDC27F2D81194B8716A614023DD356AD548854D3B695EB8BCAECCA4B0AF983FECCA875DDC7BAF0E1C90BF307FE57772FB5D392439838EF9F0C798CBEF92034B019232480DCAF988AF4EE3C482D3FA877F22E28706FDBD2A8E7705801EC67CA3B8C5054E7447E0D3A63F9D9307AB3F1992A1E00BD765E861F3580007792BEB4577CD31EB814B97396CE723D8C633684D08AA53AFE5BB543B3369CB8B2A24A108BDED07033915717292B2B303DB9CB9BCF67B5E8115832BF4F669E9AB629FF2A793F0AE0B8B4C43BC74488D1725855193319132AB1CB3876F46A2B48E7126E8F4BBB09022B02152EF906488611EDC82BA87D687435FEADAEC148F0A2DFD784D3309E9B7E8AF7C78C8A52B7419F94CD6FF1917D7518B0802038A9414EA235E914BA03A001CF595A63A5868E23EF0F243C62828C625593C2C5907B11C8348583F0BE946CC7CF53990EA39A18AFBFFCD205F11FE2FA257240CBBE77CE553008EDCB7C15512811642CF46A725DB8802AB3964AB8C08FE4E06658D25EC46E5B38DFDCB9EEC0BBB3DEE2CEC204BBFCF32382C1F4F5A83901FDC8C33CE0E0E94AF6B28C252A57F3160A3F28AFA7D5B0E81E2ED3165C89B98F57B01EBBB79943D568177DB9D5277B3F4A0614BCFD8B464FCBBB228012B9417D0ABBAA6E49FF25B1BADB1350675760F21C17D1842F04B36940D87BE06069C0062EEC8F85A6989FD151431E1D977570E1186ED00198E7C76B26D6E0871BD695C78AE2CF71D322346D51F140719EBE9210C28C76D507530D73B2343EBEB4BEA944EF3BFD48261E739853C16C009FCB89C9507B46C6493B8C1E1408BBDF5C5E582FDDD36EF90463D4B098BA267DDCFC8B734B367A517CA10B57638A91188449668EF135E23BB376BB53662EC04436024A7B83988FC0D3E84F183EA7341F9F29A9533AFEC13D477A82D3CD3E1880E35ADE1ED374A60522F46E99C6851FE93A8A6507792C0B6A7866CD2913863B10A916D7DA42C6076AEA3F8EE7D9E9500BF15D5F49B62C60E26F9F10B79D409D9F0F1AA88973598CA186877B8BE701CA8F1D65A3275C1C6A14D6047569E45DB8837313D65F775B2B85AE34E300AC93820EDAE934043CB6F195B95FEB67EC987AF7C4CF9499017C199457C4B2D6A95283A550D688062477368362E8C1C58413BB957452AB3B87A68B6DBE54BA588903BAA15D75F1CCBA2829664FF61AD8CC3A9C532D9E70F076D417838B817F76979345A8B5988D2B1990A5CCFE31B12C5052AC8C1D7A610458F594D371ADBEFBD485C9305AFFBE9558F08B132F880B5FF151E798106B001725697BCB1123505160728C949A9CB3D0FE34384287A1ABB5E0E924294758DE49879DCAF2FA5B688593959699BFC1C200000000000006131C212731", + "reason": "modify message" + }, + { + "tcId": 23, + "testPassed": false, + "deferred": false, + "message": "BA59DB4AC8D2DCAA1390F6E0501A5C81A68B91B66D1BEF88F09E9111F11733D94C0906A998B88E49AC90E8B3790DCBEC51E3C1CEC5C16AC1037303561B893BFC4470ED1B07AE65685A5777D8DCF3FCF4F5AC9A2D14774939250E58FD21E8A02468C5A67601C099EC11D5460FFB8FD05B71243FBCADA4C1EAE6EEDCA09A763EA0", + "signature": "93A3538393083407CCB6AC0AF86469AA48915CF869B80EAEE9BAB41D5A07DB4A8855FA49E9670AB7A60078E4D4E72018AF92CFCE91F385DC4500AAB15638C9F701200D8E463338FE27AE7CA53FDC65D79123D72696BA0ABF3FB7358E4BCCFA765DCD62D54A7874441D3E0B1B845AC8628B3DEBAE88C6F4D6123E32086BC4AD7DF032C78FD9C68107A73D2000D2614C9A432FCD1885E14BAA467E993DCBCCE5DBD1F478530A0F249FB8BDE339E16DE6BDE7316BE37F6B7534A3FF6EC51E8283191F4A1CE9894604EFBE6CD3C6BDCE7887669D7848DB88764ABB99706E6F2EB01D1326DF02B6772D0A820E1F078F203993FD59B0377EA79B5196EB6C7861090AB44352C86A381B6C36C8F3897613A299ECC87469AEE0FBE450B6C42959ED8A696644B5DE0952EDFC71460EDB241843DC32ABEF308BA3A4D2DA892BED1BBBB00B01C18DCBEC6190EE88C25E4E08E52B400C619F24E341698EDB9D66A77B1211203A79B3B3700B672A469E77417E8A739E0C99E68EB99B2AF05BEC0B8022A051CFC5A3E67BB205CDFCD902E7D2D27F14E625F34EC8254C514C64CFF9EFAA5E009DEB6A4A8AFBA5820CFE4989B54582A6F83B8CEDD782BE8C57E5EEFCB529846F9F6D97ED8873AA0FFDFAC61F22643FAD4F2AB0D9922CB90704B3E473813B6FEBFDF4B915B3E56E1DEF11A64BB2CCCFEFB81DE49E0F93C36FDB576BD24CA7E2349AB3BECAFB0A121952CFAD177EC46C1922EC5E37B7E03885A6086E12B0FC47B174857DEF3D6EE4D7C7CACEAF1694F0AC63CCD1F6D2467AC090D88E43137F6A303A94F3EF941D16CE01DE3C95C9AF1529FD34DF659DB2EE995406910B4FAFC9357223BFDFC4E95B02696C0EBB056FA9994304FBA56BF54ED312F998FCB4B79B5651B25BA993AF01751336AE38A163390F172AD25CC2C448B4582A5365E3023903BA78F97DB6C9F43C006085DE760EDA485BD78564A4C2006C59A8C298532A53E848547A636C602F4F1AD80E21B11040822ED28B007E268516367A9DDB3A0603FBC2184C8E295BC5F59C49ACD72D0A98F909F0523470B6C1E441ED8A9DE09E82B1EFE67095EC81D4A818E4E51EE16737B0D5C6B26A2EC75EB21BDA66C8869E09C3C1516837707B3C2C0220075E6ACB9D172B6D406BDCCBAE3D649DB31C8F30B4D992EA15CF8FBAAE8491CBFE16B94E79FFBBE9C01B075F26581671C9C998058853FA7363C2DEA9B230905C5925A26F3AA67ABCBA1D347CD601C77F03701A35C651967775693B1053C9E15A79BF7E04663F9EE1C935DAB43B46EEA5A33FCB501B4F57765028CFA88FE7B11A104CA98508157403BA8771BDA0E6D89E6C6870471DDAC89A7C0FCBA4E4362A4DCA911DFBBBAA8925798AAEA69B9054A482A0CB0364CE402BBD57A41B248562AC4573C219813341EE3A693ADC4BF5B087713D3DB8C9A0EF8039C7525B2CBE7E602E52FD9004139A36AD1DB24F611E2CB846DCB170566C7F2B3C05BB2C42232B17C9152B087B30BC840D0F9DD55A4B255D1BE4E8D97821D71E5E4A88D2D03C18CEE56A7A89BB3B5F96C17F683E6DDF7C094407712C7D68647DCBCF5FF000D4E4BEF3F13B991DE29E2CA06578E8DAD5E1FA2631BBE7E6CC0704F08E1B48499F647E3573AC54BC93D338B4C282FE13EA7802A582086DBC3790F44429956FDCF342B77C3D7B3E94383F9794FE9DACB4D19AD92C20BE1E4CF23BED7EF067F32370EDE32890019FADC19BB4EDB4D5022004EC16441BDFFE4DB752005E26EF733290BD14ABF168F7709E80F9A3C04151A6A1B19AFECEEEE49DD6C02FB5625A3645548D837C1FE95BB6CD954F57A26846E675A20F0CCA237B373299AF9BC4E387BC7363D7B54839E0F0D57B3D2C3432F4935BF6058BCDA8F045D225284136DE050E80A3E7A75E168DBE5204C3C8B428226F9A901836423717C785BE122F6D4C2AFAC95DE4E3837B25205F75E4B26F87A86E4BDA187BFA19C42299A2A527D9C600EADDFF8101772F05C2DD2BDCCC4CAFD08CC3141963911B6ED617C2D59C9A4CF93884AEEB49C7FE30119516AEA554D592E981B4163E54AF4A7FF32930BE9064F6134DF3B6869123259AB4FA0DE835B1B513C063FE4A2861A9EFB8662404A6C7770B4F2EDB717FF6AC75D67366CEFECD4C3B7356B6B863B0DD2B340D8605230CFC5671EFD4CD3A1DA7A78DFE0F1EC72DCB0846772AE2C7C9BC31C4BB0175EBF5AC5FC2E0CB7EB850BE3541451296AA0BB8EF5B4216CA23180BA2EC15683CC32EAD709CEB3EB1ECC9ADAA936335C4A5FD5BCB62589133C8282E11E774207924E7BFE4A3E668C49B428AA8B5BE652A525994BBBA2591EB05B1987F4F4567B1D56E3B26A03BC3774037C117D01636ED8E49BDEAE1B2882987F08707BCB99BE22A8C4A836119EA0182BABF3D139F60F12B54921A542532508659E71911F4E076DD04FED381E1BA91020E06E220F1E874D49DF7C91DEDA8743DBF1014D11C97AC61BB0A91CEE6959BA1E3EC5985D9C11413044E8F37450327616531F5B5DCC99C3419E0053F51D654BF8144FC2D8C7A31BEE6B92075CCB831CF84B5E883BFB6602673C3FFB2DE342F69FE1AF9965078F3899FCBB57F42FC116849387A7FA24F0929F6C86082624A95AF60C801D766F9957EEE61FC16644D616D4B43AEE84CCA01F9AB32451496EDAF7E7E372442B3981195B846B1D5AA33B799C07759DD285AD425199B4FB6D934EE45BB80D070FC2517E07A29F744E2CA378AECEE110F18F186DE866D76E5C75C016EF6D50A4F97F7A3321ACFB1F9227C50172015C867EB53004F03A7F1384F221EE24624053A485F06D6CC7061313586B1E85DD2CCA13F8F82D71BD949D944C39F9AF03A2C4263D653EB7B1D97ED48A33FCFE5A8162A2049EB921BEEECB505A87688DAC4519B32A2C907103674AF3EF91E3A137E82727D5FD444F85E767B5D98C08D2AA6FCD4E149AC664D53DBD77EF0C774A2CFAB8313C31A31A02D3BC8B4607D5D433EB0CCBB8B6B3486FF7A644235E032F9D7972BD9F2A8EE77A425FDB67E30A6908C1257D87C12B8EBEC3134493DD03BADE1B83CC2C4F82ADB39C002EFA45A67FB6A63D7E132DC278CC4CB51DCC425AA4C7E50CA20F9E89D06B7DF83FB7B0A26E9057E5409522EC0A8BC45E1BEE97E4E2CD27DC26A64B33FADD3BB7B65A24D7FBB3D8DBA0B519E7891F596C6289D34EE3ED72B46108DE4F1B0AE537E7B2178467550207DEE1EF4C7C0434F62B8B215F697EEC9940420FC1F50CFBE18168F36D846D50782670E486C16F4FB8F026BABB37FC1AAAAB6592794233B8AD74A786B6A3639367B480765ED1BA14D219CFD9FE31D66AA27809FFC7976C36CBE88F6AB537C5C347989192DDDBDCE848B465E5C9C3BDDE6A2EFC140C841B50E93421F727085CEBE43F2C13E0DBCCB03262C5F6A6D5F32504CF26582FC936FC610F885D7DFA3EDB7CEAA495142AC58BA127AF96CEADD0184AE269A97D3366612791557084E58304908D0E939198AE87CDC1B45E5796EAB37C537A68B6CCBCC09BD6C0E652FD20633E99B198128C0A8BAE79A4C6D6C96BC3D5ECDE776B3A83E88862E70F975557BD383647E6F531B4789C8D47D0E0E41FF5FE4E40285E0A3FCA6D8501F51D834869ABFBB55956A52E3FD9486B7DB6DBF11D6A1916F09AEA9C8DB59C7E7D6D7FA23E0C250501E6623F0A19529F7207B86285F8FB6861A5E3E2916B9B93962D3D7543B198458B0967D2E50653F99765E885B6FAAC4C0B2AC1371C82460C7CC21E9B855C3FC6729E5FCE14BA7CA093F905510F53D648EF056AFE51AE7D7F9EB3A8DEE1ECEE9846D0E94C1D385CD079D252F8A9547A50B0BCD73C44E9854F24FB9CCE13FC2FE4FE73186C4D8AF0F4C9328EF9F2F517AA31FB0B536E4B61F085FB1411B448176453CFD8F9345E541D69BB248003E01A716FB2C03439CBB4B41DD4064955F2289107DEDDB4AB065702E46928F883CAAC5430A7333F3D20D7CEA9ADFDE9E1505226C7923C45DB48CC7789A3D7DF6D67B85744FBA31A0F215AC354E8B7F9B0D6A7668ED60608537993D42FF354DF4663BA27EEFA28CAD71E8A7667B239192ECABBB79C78B376A46B8A30BA64407DFB58B22B44A5A085E64A07F6C740715D4B4A1DECB57CC4154744AFCAF0D7747AEBAD46DB51F1E85ABF82839E677B2198F99806F2F0192D2A06906310950F6FEEEB8BE92C6883EC716B66C02A894083D0B38CB88A511E35D45E694F7F136591B7E43AA1F091C1F4897C1552D0F6160FEDEA5D913291FD0292F9EF933BA3179AF2E0F50DAF3BBE6FF225DFB4DC256118F4F2AFFEBD346BB6A29A3FCE50752116BB9AD75E9F35AB55E37B3292786324C7BD34408F2BFFAF6E6E985CA044C03B449DCDBF25781BCBC65838631F9A40828FCE87FF64DF81CF26A1DBA89C453A86E507DC27E32FEF9BDD78CEF8ECD6C2D8AFEDFEF10726EEB8D245B338E07D8F148B1B854E07732BA48FC2BB9591788B2A375C20FFC6BA983629620F0779C66483F98523C2CE549A8AC54ACB48C4B4A775143212CDBAA198E9630E0D685981A01B97B63C0BAA0700964B8362F3B59E525661C73024B0299080B454E4F65698C223852C3E9002A2E3E409DA1F8101F3A69838EA727577C8696040B6EA8C7D400000000000000000000000000000000080D151C2127", + "reason": "modify signature" + }, + { + "tcId": 24, + "testPassed": false, + "deferred": false, + "message": "4E86E38D9C01D9DBC6A4E14D6C57076F6804F8102150D6D744D7644E57D8F1FB21FF10280C07C16832BE270CAB2E85FCD01A72B4D949DA5FAFEF955D690B99EDB18D7CF254D889DAB8D259FCAF85C7D935CE5AF1C5A2889DF1650096E2793A8CBAD6917208BACB2B0C385661E6CCC4AF8577D7A39754C443FF84AC1F0395120F", + "signature": "44089B2C3AAD4A6744970DC84374B7A97CCD127A4F7AC00CC3E513FFF8377F457B64F273972E7151506D15B37603922B00D8CE35C5675BA43C70C2856452928BEC1C7CC835188719389F6F3E35C135DE3C4D4786504B45309598409CD5A0107169EDE5FEC7A0439CD3A8AB1F196250483640C4B7963620A67D421A4C9BC8F1F67C5FB36B6B405CDAD5E78320E71951908D0CE9D80055DA4F499C67C531639BDA1535B9D44A450C63430D43139D54A941183CDD49CD608F25E37D018C4A2477B2E977779A1DAB8075A536278855E50BA4A18FDA14D1B8CBFE3D414DBBE42ED79F0EFC393D3ED5964FE6FBF2CEC87BD693A7F986A6983EAE7CC8441E461684BED2D19CAEC6CF65A9BAAADF13934CF02CDEF9FE1CB8EDBF7461692C65BF71421D85813752CAD9281881FEC42D031EB791F2521C234CE082189D1EDF718A9DB28290BF29FBDB6B08B533588E85D9877669FD6364276C0C0AC9373645C6734F77A59BA441D7738AEFF290EAF281D0CC7D6EF5132E0332BA475C7072FA750AB4600AA2F45B00B561AEF2FD145267F6CC53CE3EF1D12991AC16248BFCAE693CAFE1A5E1970806FEC9FC229A652D7150457B058126A39B3CB685FB24A270F52A5BD9BAD7210CF642AEB0276CECE63A099EE768EFAAA29CD8336EFD6B1A18B45BFA07769D6289AC0C0F1BD987C9636B10A72EA145CDBFA13A428EEB7EE04C77EB133C2B3B7DC5F9948D89A8071EDD7177488C0D75D4831D5850C3839D5EE17A7A7DBDD7A4EBD75231EBE52403A65BFAE535D2CE4A2BE9D06C7AE78CE11A2A294FB4664CC9AB62E307167A30CF49AF09817A85C5C302A28604F95BE33EC078A00BF2ED02D1152DD86F90D3AF8B8D795FE70C9D457750392FFBF15E5F5A57D704BE8F1FB7964CE11A4DBC9F9CEDAE2EB3325F6890A684A58D353779A79AF819AB993DBC1A4457D7A9A1CABCC9DE83B12502523CB065AB48D1FF71EA4F7746696A113B3BBFD06BD66B995FE7956BB7E5376C5A8363418498BB4E3D793BDF66F7D2F7D39AB842CFED646D4D93954DA6276490D27B55B57740A65DC88B766C5325DDC81B5C154811978F73F4CD97FB161D1258A4B928A3F62AF8BB47F65A43038C95168331C50987FE6FB4D11E28D93CD36AB5D5096139880B0AB265E65EB5ECBBF5F6D107D18334876EA6785A36FD0D58C2F67B2B2F06409B8E6A5A5BC31C97F071DD0590395069886B7C12B6E7C1E83E34CD7711B2A92D2BA19CE529496E020C50CC76CCA4BB86969D3F9A7DD6724C09DB6186756566F662FB289FEF2C49C731F2FCEE636FC9947D0CDD5B1762BD7DFCBC0E9FA34845B33978514FA11CC64E8E51330D9370636BAB77A0A523A4773717A2D01AD532EFD20C68A98D6BB4627160A7CAF7E5BDEEEF09B77B94CB8ED8BB44BF70EE9210D0C2672192F9582E5D78CDE2FA306F7A05FFD6BC5B8038241105D8F11D033493E6975437DC8790752EC863ADD3150CE0B5560C07E59F4302BACAAED464799962E62F5AE579FD4E2EFBFBC51A8CC547D0F26C392AF44B229E6072C27D789D65C31298DAD6F7619B1A86D5E8A1CAC881B1FC122DA6A520157761D6FD6605C49AC53A09532DCB1C3A02CE1C83DEAEBCBE63DAD9FD84B827F8197911CCE9382D2467BE64E1F36C5A4D5CB93CEF7E43A699255D2F021F9E04944D1FE5CAF43F2ED3F85DD9C03FE48BF483BBF706BC88476299C13565105E019E3785A7BD8C16EB509BEAD5F7F1BE61A3B9D3930DFEF308C881FEA75C4660AEA4B5BF8F518E513A421066276FDD528F1DB56D626562DB5749BACA10413077C2F84F29B1F4D23834FA2E27C3D23395432622AF4DA6B7FCF3A7F582F56B5EE28C15A88487C322B4269A9EBFC75D765DC2829BFCFA598830D55ED591BDE032E66F6579636C1ADC8A28B1FD536B29465AB6384FD04C721988B6EC52D66A28BF694C9F74C5928C2BC7E1C5CBFC74AC3EAB4665DC39A3A2A1AD4FF98045A411811C30D1F372A2C50E288C6546E07C5CA8ABC1513F6232D6F6F2F09E58291F8B8964897D2ECC0B9ABAC89817CE3C18B074D3EFDD14B27FF1D676A6C9FD15D0F03857491DDE74DF20DEE2C6E70C3E7C7B2759158A845D9BD739A797E2AE1A7C57436F77417CBE94C44863629CE521F6A103378E467AF443E0D4FD3C1A3C2A5158F1804AE7F5B31F509AB380E5ED15D646983C92B2FF6001A511942250848AC91EB5C6D988FD1E35C99C4A1EAF69FCE80FBE44B7AE6BA7C4FAA5CE7ED20198D380AD67706268918E94B9CC4CCD12448BAB33C78FDB7A6A43D0B58167FD59DBD2A0F2E0395FA36E1BCD2A2ED329C39EFAF9A2016240BC80E4E2F6A98EC9C7DD07189598EC9A1153798A4F615DE69E57A188464AD363FDCBB1A9C1675FD890F80E53DE8D4A7AB9B486269BA4ED6CA70919FA00A397538DF10D797231ABA2D19FDD5E6F9C642A8A40AB376FFCA700BB86F5114BF8A41C315EC230182FDA1FDA64354E5CFA541A40316570749B6D403EF168FB50E3761A697D50937D777DCFDEC1394BE17A848F9C2D87114134CC299C5414F862DE3649351CC848E09D2C1F49C65CB6E357C2787E36EDE57538428AE13A8F0E6012D885E355A7E310B49688D77CCDDCC5F281C4D702E4F6921E4C8C682223A349AF763A0ADA84CF82B8AA03547D4E4A3F6816EEB6A9D0EA3765DAD7440E21D1E2281F4539AFAEFF46B4A90DC473A903ADC1F791599353294E9C71612540395A53A851FED2E27075BBB7CF9D03EA69F775E6B1D9FEC2FA85D9677D56E8B054B4CBE7C3B4DEF91CC74AF8A1B7D543CD6E94DCEE83732B75177908B7483252374765F8AB2C83DA20DF6C231A2C6625FF210CF2DBAB3DF5E51144F7282A0B3DB1F1601639A30505933C1655685B1EFE3AF7536A2AD76DDFF650BF8F3E02C39E6230E920C8F4E30EFE3C3C5A7515E216AB9A681569910D7D3E047B6890155C88E2F0DE2BDE6F21AA2ED11CD481A865CDA6100144276E648A25215CF491019F2B8F2207801003C2A7D139CE24D1081D1E8636531D2BAD6D98FAF8760610446C379A7F636B188FAE1B92F06A70D4E293484536F10B6609774B0F3F768D00CDD464A5DEC739AD28259C28B3E7DE34D55E31BC734A8F02E40AC404AAD277A3EDB6AE75A43918E10F3139CB03A40A32B52C4BCC5B9891064616C88ABE5EFBD07A87485E81B91AEC8D5406399E819C6D9EFFD9FBA81F6C7209E3EFC7FDC2F5758450EA076B95CC777C3C56B8A7D5303D77A41600376FE003DDB8FF01336AA912B998AA7C1204D861C0ADBD693D891A4F72DC40AFEA71B8384FBB5FACC134AA0DEF3D773C88B42A2729DB00F20EA4D5C3FFB8376DEE9FAF62FE11879E52A2DD1C547224DE8D1D8E0E06BEFF57EA00EE79E7DE50EA2DAF961E9567E41400345DC0CB201ABE605D0DE8B8969174EB469C4D9664AF7705DEAD5C0F22237AF3486634AC83799AC27C8ECCED21B034FE4FE468B0F658A1174856867C8E2D6869A40596F9DF4F5F10E9398FC8EA8FC96589CDC07B8D8906AFF0FEA6EDB959FE7D35F6EB11D5681F6A44538429D69B01C92C1ECDE3287C83C26CEAAE6B8C3C1AF639F8CB89744142B250B790436FA5DFE2A3C5490E51043A8DA334331B9B55726F3468A5AB12170AF783298C7422231DF52CE78BDCDFCE0CE277237677E0F0878BD60AC3C6FB6800533C77265C3F1D061F0CA73C43490E3D12788B859535E489ACEF874C2DC72BF32F14FF0813CFFB22B12C67268A2A949D62C56D05974714416FFE18B654FA2FD033C556270EC7D1F8F7FAA744733D3DACABEA4B7DFFDBECE868EECBD2E97AF552B9FA792BC6165836596AE3A21445056C8B7D5938FFCE31E2B0DD91FD6DD63799FDDDB3C58BC4AE8AF01C0756F050709A3D33C08AC4FEF17B02E29FBA4DA1B777240AB69EF5F79F8E88AC4771D658DD3F8D19FE4C77151C7F4CAC47896812A3C27A0B435F51B4D82C038CF7B9A6BEB2DA3436D5CDBDD3FD5E6C28A1A5C1DF75266BB1C8030FCD233567A3C94EE4844B031E0BE1FA7E61308AF9E251FFB9CD54042C5E189D44421AF87204E740AFC8C7E7BBADC5D966E5CDC96A2B16D4E89ABBCA7BAF8AA0375C15085926188AB47571054577483A10399F9F1819147DCA4680935287CF5FB8A012461F28B93017E71AD35F5716328153A2272CF0162436CE47B96D37901F0CFD835F33AB57E1065D8D23AF79EC096469D0C7D9D7377B57F35D5B05AB518B74DC27754E79213FDA8097F455A1D10A96C4BD0785C8626B77FE3F5817773B0F0C7D68FE7DEF3899CBEA8D1C017591EB8F7BF29A498203124B8BEDA298DC22D9DAC2092EE64077383F3E603D1651F826F6B4E5E38EF01DEFEC91C62EA2752A755B61FF46B0F21A3FFA79AAE80A72A77CB1805A355AFC7541184C4DEDF9B2B27A28CABFD51BA0175B34A9AFDE50D92B032D74A28B810782DEEEBEBAA9F61BABF76703EE34590B9F816659D05D30B5FD204B0609FB82C7D9C8C0B71218E7F62EB4202AAD7945DF4FDD156C9F3E92142125F9054644BEC0DFF1570A632098C9A1281E8C929EC72824B7EA0F0EF034AEF048BA47484119A54D069139A812353C434859B5D25B6C9BBA014675BEBFD1D2DF172226294E85888FD9DDFD115D7B7E81B8BC0D16586B6CBBC900000000000000000000080C141F262C", + "reason": "too many hints" + }, + { + "tcId": 25, + "testPassed": true, + "deferred": false, + "message": "62C2A85A6AE40091AE35068EB3E5B54803F495D49BC177F7A29282DF0C900E86F66155B4026064E7D6CF7A171F8BBB33449232EB5D7DB2B776ABBACECCD660294C25196E19FADA35E0F3524D78EDA25D614FB56DBA5BAC10D06EAEDD9644DA291DF305C1E91C82FA00EC470A8E822525895113A6FF7D1D52E7038B9CF4DB2227", + "signature": "9B829A093EC253FF3D955EBA3C0FDA29CD14089C6D699F26FC62BCD40F43D1582F2B693138AACA59A162CEFBDA6328F1BD67690C63B903F5062DCDFFA840DC2DFD4051F82A557FFDAAE8F4A4FB340D6F4AF03A19AB928F42DFD29FF8D028333A0C336D253C826175C5A194C0441DAC1C5A4C4A3E0B8394E43678DC915BC98628BF565C9E751BF9801DD6AD4A3621B50C8DD1520F0CFE475F5BF843DC2568B263978587322FD1D2709ECD869A77F054C0A45D466D297ED9B63F10020826836F531A06DFBE20BFBA0B3F204033783C5505BD82DE732204917E3DA12316559D07366600CD18EE2A329AB3B20BB0C9C607D0660044D2A9ACC5D25806F89DFD5813C9E54E0CDFC190A206300FBC8E2561BF3F23D04052902E49CD5DA530A4D2BC2E5F47EE93D0588AA66EC8CAFDD4B353D73B6C1765211405C080A614129CF9346A1593503AD75EB9C3CCC99DBCE1D937AEB7929A1B5351BE262FB2B41FCA6DD965CE596DBE39D07D20281A2ED74C35FAA474EC425A897978FAD88D470502008D9A0E08DFA2F6C33A0B4CF2456951109BF4F877D74D7681CF287F6DCFAE24D1FCB0FC69D7C4D33E20536C64ACE18F04A2AA8E767C24068F4BA45C4C49DC3B43AF803610F300D01C5CD9ED92F33BAC270ECE09EBA2CA0FBA180CD135E420471A7C6CA249D877DE616F054711B3DA2DFA5D2D3FE774F802F4880E4400FBE4D12B8D678DB076020D356769060253E5D68F665FBCE0EC702F42B94E2B0C8359CF4D6EBCDEDA9FAC8F2FE95B9FDBB9346C06300F60FFD4FAEBA01929CEDF0F15021689B6EFF9298BFB8E514D925541CE2130EE1F25ED6EA895F432987AE4A2CAE01B5F4691DEBF12129EB19C2890A9D268774881F151A06FE42656CCAFEAFFF01E3EBF52C6716CB28BCB6719F7552731C275DA226914D733AEC1BD599AED7BC0646B8E3D9E0F3B771295D43391F00293401E6331E37E779EA8914E7F03B4CA3D1AFAD797617D9D0BBC6020E1B40B431B930D19E0888518D6ED2E6D32BD872B9A416E0B47133867FEC96A88C6B67449E8881B8A455D1816BE7DCB22287D63DBBD87E571F6887AD3D6DDC08C0B710395A12570AE985AB08393BF99DF1A1EDEA499BCBBC2F2EC05FA3EE982E34814F56373891282882A05711EE9A906CFE5952A6AF64379854A4DEBEC24C22F69065D6FC392B4A687D66528615AE301C82D6C694D358B71451A536039368D05C3C240062E455A119EF5A1737D732C1079C7CBA9A05D9D8119CD94497CBE2A275C69D6623628ADBCDEDEAAA143073C6EC43C40229606E6AEB982CE1827F875FF0A6921E0D6D08F605EBCF85EAF0C4AFBD067A14BF9FA6C7A657213C04FCB93630D892E8B340217EB07EFE9CD320DA3DE466169001566373F589A4C48BE25EAB1E6A612187F110661BCED6C2FE2583F424641A420A0DE61B39026172DDC93EF444EADF8ED5CB674F0586307F2886CAEECBBF78A4AFB96ADE18F0504734A082C168921005300431BAAA9FFBCFC96D272E8FD9A10B7F963BA868A273CADA8082353C0E1D7C8BD323779D9BB23CE678B3A5AAD2B6836F65C0F79E32D08006C72EB2431FF9797E7630F27B89635F08FC92203012EAF6B009A32437ED076D66E4CC6074B1CCD0D2176FBE508E43EDDA9185A91E2AFBD235EA8944B711B8C7D0A4132351FCAB1ABC338C3419C9993FD56FC3C89A08B0D8F28914FBB4840A7D02F209D1EFD208A8E47902E11C1FA92CBA1851FF0935D3EFA705FF4BA44A6D4A675BD979947CE8FAEC565B3BAA9D441AF91F429D42C3E3F683E0202C61318344C7865957131A1F9EB822999F137C0A930744CDC698B3D41226A32268C968F576AFB37D8BB4E533B077124626535AC470D649A817F42243CB7CC73F0837A6527C2890ABE5BB762174ECCEF9B2F9A3FC77866ED031947CE54EFB0DB647BC9AB219B974E0C42A53FF6C65C1A67924C1B0415C9B9CDE4887023FDA6DF9A2F3BBD7BE5FC23EDCB6CBF5CE5C0D6B75C2048F05C5AAD82C87F5D0E9A146C3CDF01A973E85ABB5DBF4B3834BCF7EC7FCA3636EA417B92E7838DE1A8527292FEC5183F21EED1485B4AEE3541C00E36E6D3AB5563F3DA1DB962B94FE6121D36273D2813E785E491BDCFC825B0E98539B7364BB73885EDDE73CBC41B7F680BB00D9EB3047956996B97A6994FDE741AF9D0B302E99D3573117B4B537B1A3C384589FBC24156141473FCDE30DBDD305A6E8FAFCECB98800348A5DC2940A8D5CF2005CEF09F49B5FD5B415BD63222BF23DBA151A0E1925FA6DF135075E02D5A7E734AF9B92E947191E7221F1122387DD17EC8A4D3582949B58C4EE75A0A83115D936F59653592A5F86FC2B7C277DE26526AB23AE4674417C9C9388B0338F81FEAA741C446CBCCAB5755F07A195325E708256AF861913F50AC03FF02DF181E414E185DD7CBA0714FBDA807D67C938CA36AD52BE1DA9CD4FEE14BF1961CC1C20D3268C5563BD5BCC10DCC0FA42F01B8E278D3B2F549D6A1B497C8DA54995D395CA6E761D3B776C1D012B1F9B39DD73CD831F6193847930AA15A4C3B139464E3F89AF3B1C583E4E986B80C4BF117DEDC1C09390560365754F402C35B06DE3DC45ADA558ABC7EB3A63580FD8C9F29D335A8D9797D1420D4E3EC0267078F68361B65DE8F6D153F38FFE6304F0B886E94AC959E71EF2AA546DEE0E00E39A3E8DB5869C4434E862E60AF5883DC6E905469ABE8A9DCFF2BC85D14F9CD6470F8B092DD622FDEE25678887B97B021013BDFC8CA38702A7F49BFE92A3BFFB8DAC66D888A070613BD09A6B2D6C2CBC9E61DF92BB128E8C87E241E83BDDBB294AA56A5B6E70742F6EFC321CBF8717DBB5EC7529E34B21C8A73CE9EE0B7D6A62C96137A19D4836D53BC4EB8C1551404CA5804C1CE2350EC41C117DEE4152B65F9BD050E5BDD4A8EC392624EB27927D21C6F3CCA0170EA9C74534C28EF5BB45FAA789A46C703A723A82EF4297F907A20FB4B91694D5598BFDF986E517D251A401D035C5995EF8CCE18BBCAA3C4320F0F90938F7D5D9B04E187BC72B7DF045AA554544368DD90F726115A48E3BE841086889FA99ED5ABCA67683D090A8F3002C164C7C431539C1C8FFA7B871F40B0F42237810E3F603C63DD59737AA7275862DFE9046D22D59754D3668826A410EDDAEDF804E16B8E6D01D7705F611123C3F6A3822479430AB3A10F79FE2295558B60DF5A7CB1F02ACF8EE05F74A38E025C1A6FE1C02EE50C2B5ACE98528523F5C16C620D78DBDD54B0D66BB1C2E832876C304D794DC28D1501840A94FE7ECB2A62C9B68EFCD6D60E9F12E79E6793424B66F1CDF7C16B0F39D03DC0A178F850B1BDDACB3629B456F6647D0B9AD45E0A635420C1E1081D0E99D8B5E912F295DFDD262100D5E95B030CDA6BE784F6D38ABC0AB5032B0D42C85ACF782D382BD0711A7B43CB7682E908D3E36132145A1FAEB6670B26A30917682E4BBBAAC884A7306192257E9ED98A771F707A1E14AEC44DB71359E49FE15529376DF4BE36A0D00241DFD320E93C8BD8BB651132C4917229A7E5284F83408E2FAC8588E3662F4AF09D4E3A8F97CC55B507A2374754B15B086175FB593B007ECD560F7AB9E7D6611D816FE58CBFD083D144E5D0BB7C4D76A510F56C7B3170ED5A4AF94D3042073F3720A8BD2DBE40A90AEC4765371C7F27036C75B3A05E08D3A0EA4EEE0C583196952636745A9556776489A46B7FE6884EC255032CA37CA59E33399206BDA71ECCDF7E901F57F7F11732FC86CD6F6BB761F612DCE82455C80382834A2F660D38CFEC1F63DE2AF8B1779394E23747980B3D4AE572409E03AEAB7A80FD951CFD64BFC061E4FABCB4BED38F1AB19C819A797E8C378010A56C3E7CE889DB8DCC832A637B4D1E04C2EEE52E2BBE8A64FE47EC9F3ACBB73D8AAF2DF8F14D67F92D2C80373D2180788FBEC28190CC824D90DD5DE2F4A95E0CD172C1D1D33D2E24B48A0611C908812BD1411DF363F40F317731DF586F7A156418F5EAD8C06E116F28B4D0A1D1E047FA249ED4CC653AFA03DF4631C80D529F886D1393C0E763C325FC3B1DB7DE834DC7A3775C5E0A8393256D9DF355D7B173BA5C0FA8C0807F8615E3EE5A5330F7CF408848188A46AA98BD6BBF5B6925667983D4354461B43E0E5A09FACEE9E285F2872F972F7121957C5A818BF45B7B4D8A83DBA07DB5D16F96B51A46B771213FE8810D53B1EE68EA8A2EF1870DAA7E9CB8570FA04DF817AD58EC6556929AE490B09463B663D899C0F01C5A30E31991812F60A686877C254084FA73C4E28D8267E43FC873BAC32A2EEF54CA235D2089C7BD98D90099EE3512B629BC63A69EAB96D2F60EA01D293DFFC6FC355A726B0EB91D66358834B1DFCDCF5738F929226A63BC8F861740D844E47E2D3B731D03A902F7627C0F287F1863CA4E29773E966C9BDE3D6EB2C83F1FEA43227BD9B556B9773378F3D5CBF571EB6877A334C438C8071B9CA6B8F2AD85E66CCA1312826FC0428FA80AF251D13E3BE157DE900203A2B2F09CD22ED5CB33A71A10154828784BC0D9093B731096BCB14FDD8A59C06BA7BBB6F46285EB75BE0F7E5143E16FDB3B0309303392E62E536299C825293E5764040833BCD0DBE3FF00122F56C1C2364B798293B9CBE3000000000000000000000000000000000000050A0F171D25", + "reason": "no modification" + }, + { + "tcId": 26, + "testPassed": false, + "deferred": false, + "message": "A03A6A2260AC6640CF95C0735AB67D18EA114C8552D2F7280E61EE1073152FE4A0E28094D29BD1EC79B28398D10A9AEFC2C55125C994D821CF3DBD3199DFF2522E927EF4A540DD3B36161A2BF3C665CC9387F066675E761ED626D4B0D6080293DE775F36D72D76B22BB98340B3AF47A3EE94399C73D0C98EC955221BF209F4BA", + "signature": "AB5E7394A0BDCA1DAE69C30E1CF49FB4FC57DCBEF58858F81BFD72B52BD9617F71AC525BF2E6327F551EC3208DF67D0FAF5633C42E45F01BFC23BEB54980EA8FA1C8ECC4F3C71239FFF932D4AAA763199CFD07B7CD8760BEFCF09DC593272979A2BA0760B85D36CA151EF200BE3C87EAB2AB3B00DE6310F6AE8BB6E6BAB0639AA65E06CC88ACB84E48E5823BC41E581DD199B2FFCD04ECFFCADF37FB5AAA68C4FB4C4512DC1CCC1AEFAEB1A36C156567F5291E49012E4D09BF17852EF5A0DFC3F9F7C7269E8C034CC0CBC28A8E4DA941F01E0A40A7ECCF0FB4D727875923BAA510F5BA2BBEE1AAD6432478B488CBA8C7A779E5F10331542FFADF4AAC397015E8F8B24050EBB415DDF9E5A3E03D0895567AA7F359D8E18CC68EA24EB43B98FAE321B5CCCE983A1E4D1B86F99EDE4485FD745F10E11A647EA1BE115103B4648C91437B5E55121220FC9345B2C9F6319C472158E021E90E329C838B400F7ACED72CE3909BE9C56788EAC3CBFBCAA6851A6A8BA477636F830BADC2F68068FB62C58ED1A935D7428A92B0F04570C56A019CDD31ED67067EC64CDE1E1C5ED6B997AD51702806DB0F0D15E335D8411204FC44912871529E20056824B07BD2EDB6A21469FEA577D95C777A14102ECCFEEB895101C094700CE2EDE19B2DBC0B9243A01BBB1DE7C00453FB2363A17A383A327A6AE2A0104FB86DF2EA59C403BE4A88F6D6A6DEEA284A54DC3AEFCF49B448BAE1AF32360E01F6BA07B2180C933F0F9006F77F2842AF5C1BF2D18A405762DB1062F07A7090E3F2B664A1B4E8D2DA0864F7F187877B4CBB4E68338B67CCE16D3772EE9A13AF2C4FFC3BC30BB11C7B4269071AE96E7A83D11A87438D3D2668DE92E71BDC875DB484BAC68BFF9831D9A3C60660C3931B4107B4B7C99AE846B9E07C54D57C6F75D9292A8C9CCA3D58852EF86675F92E76896496031B2426EB244FBEEB55B05E913AB9B7375981033696780E475D0EA327A89B2CFFA64F5E85CC492C2163396DE4DF698659BF92BBE304667C95F95621AA46B4DBA9D60DB9133B0D461C73223A417DAEF23293E106F8703BFCE01DC9924437B043E937C067989804FF2D2E3386EA4D5C3FF244261203246F3E72B7F23CCE42D66B3BE2A0F950E8EFAC78954A0EA7A47D87E51F52B5E7A8DD0F342DF5EA40B3B574B973DAC7B3BDD4F4D5DD688798275AFC5FC92E1AFFFB789A68D42EF1632EBDAB5A88FBAAE6ECA47966871283B904C4E28DB8B4D51690D0FF4AA5E5F3A99F07C1CC9AA7D634036F396BDBAAA11C7390EEC95545C831CC7084C84E5397FBE980E7B7398ECCED80661F3B9D103E607058D7DBDD1AFA1E23473347BB8983D6AA634FE946930EF6483D89D51F64ACF4DFDFB74B41AEE1A38479916990E8895439B95C257EA7F0B53B5385BC113CC169FB805D61F0222DA04C9EDBAA46D7D0C80EEE91C58019C63984FAA0DF17B946449B8A146F0709AD25CF4D8E1EEABB5F614050DAEA191D7CF57B5743336F90BC9B09F39CDD7C1E5A5F2B897D6329C5680025305C50402992940796A5E5A5B32017B14D80053489755AC2F992055D7BE886E68C6EEAF07D54E326BB6267BE0F7B5E797BDBAE654800595D2D6602AEF13346A834E33A0F594C51100DA306CDBF0C8DF9D0FB0A304D8B4E3545908712B84CC7A1326EB51415583C5091242B7E8B3F71185523C637B8530B704EE79F1230D6B0FD5FF4328F74444A17ADD464510C09DCBDCFAA3A4AAC9B24E8B5F14D4E57D64B877AFF1506276BB835BD66DA230C40582E6DC4C99C32A1BA63D263999253E456D1B88028A2DC08E92F82BD5DD639525524761ABD0C9923C825599D3BF012156AE6C6377039201DA90EE5B6A74056D32B683CD97D4346D60E66673B794A724F66302507544DE37A76DFD88561A9FE5A9AE61A80EEF73B641FFFF4D76ABA97166CAB36A4FAF705F4A9C4C27CBA3DF9B63CB1B4BED874D281E78FAED9031B53600805274443286F702C7DD39F2E11F86D4F58AF9E5E9A04C4DB19CD97F05FE5DFCAEBEB863759CDC4BF74A85C1A1B552943BC1F59B63A2BBA9D707CFF9790FD47A2D2F484FC438C51D1832B96D90765929E3C40E83CC64F7979F13C530A49891E2F64944C33A3EFC95DC99808968B3CE2AAFC11C007AB4196F04EF65430DDF2D0CD38C81E447EA3E16F35D1BA279D8DDD191F21F2AD3A3CAA9A11E44158FE703183E46B48BF22A70B1ABC607C5C8E22F4EB45167EB87BB56E2F4E091C3F5DD98A7F190009218961F82F830025E217B47CF75E5C71AA0FA8F33A7F9B49C7FE4CFD4D318A9EF7C02ED51F6DF5568F4DE182DA87344FBFD66450C9628501CDB19A86D8E311F625F70D7022CFA950A53FF47B6DA118D32908CD1B9DD6010534B6D9BE0D9382C6221F706053FE232C42A97A32984ACBE1F78571454766BB596B13E71D763D5FD44B80418AC43EBFC160E5C31554AA2C710984531259751ABADA4D7F3810D03BAAF95596DAE4D1A930B5BBE89688EE4B80638D82BDF536E52F3437FE94185264850ABC4C908C58E35D8959C9D0B5BC531BA8637668E4BAAA3ED432A12098D9C076CD1D4359E2508FED7C90F6B5931598ADF772301BA27AD7F4DA681328E39785B0CCDAAC3B23B94E0EDC6FBEAC9D9CF31A573D972C1B7813547C388F17E9003D11B66A873CB19631F59E6E4C24E89DCFDB477015FD5ABB50AAFEBE00B93C835BF89FDBEFB32F673B7FBBBD2969FDFE4EAEAB872B470BDCFABAB1638B8281CCFBA0464FBB431EFE358B3611E6EA2224DCCE734EF9644E0CADFDE0AEAE01EC30F320E5BC6BCA88B2D2EFD7CB32173E2E9EE1CD288479B24820B0327414C4BAC9107C5D86E3CB1C313658E4EFF0C3A5851A7FE9A03B9DF2096C77C768C29221647C02F2760BCF9E361E1350B0E2FB7AD94A1DDE61F93249F7C7CB12C0EEDD7510E34C4C991364685E2A76FC8E4E94EBB25C4DFC07DF48936B52BAF32CBA17D3CBEC7270A3857376DBC14F6EED0A8ABB8E9B1DD2C3890B1B954C2CA7845269CC5E9A3C42B7FF2104D5CC87E89C35881A7556596848A57E5A76E15ECA79FE31090B97DCE0BB6DA4470168B5EFC8E6F906B4D67DF3523EF0775E5B3CE947D7ECC79B7BD43FFB68EED3FF15693FAFC17A3E48E232508CC12314D72EA3310EEFB4C3A21D908BF0817BD09D7436B05EF2960FD64C81A779368150B4DB9B60D0D02EBD4BB01B7AA065F55006D2B67754A3F5E5A67712E7445817AB96D50701B42CE370EEF826899D6B8BEF0ED0F26553EC03CB8C6B9657FAA30B2AC670B03C3BA9ABE791118E93CE084A669A899152A267C373978FAE2E95BC96034A4CC6F47E8D2C6E3F5E8A09800B581F5DBBC57DF6C1ECE709D159FB1B8C6D588E8CB7F09DD03989BFDC6CC04942AB0AA3AC2D22BDA3933EA04A311D39C7E752788BB073E4C4E82F38BFA7DFD809CD62200AB04BC235530EB26D9335F23A39496B34CBA96D54D485CDA83FA98CF1D2532A29E97CE8ECD123B4C601D1C313F0E62931FA15A003DBB8197209993991E869D0C19D278EFFF92BEF16E1E29876DD54450851D43ABCD8BD5CB96CCFECCF361016E4DD9D00C893C982E95733549758C106A4A71C41213AE35C7E06DBD7B8326B1C1927D2D310219CF847D527F2EDB0326CE9C62B1230226F12215710CF311563B2F5357A935A5CFFB9FDD4BB046C60677EFB7D8C71C5E8B00E8808556AB9D7CAB0E56CF37D5D0D257CA124BA9DDF50DBAB9CC2245C4CF50D29A644670D2C80BC0F1BEB2660BF579179879BC3CDC3491C215A230ED7F20440C7D1FC701EC26FCF57034AE1011AE2637BB94470C2C47A675493A26D9DCA74342C006E26C83C4A3BB3DA4D5CB4D5CCBB4C1464C906C053752F3E297F71E5E90D7032B1BC83A274C1A2E261EDCEAD6EE493F920139275D9B03D9B189341D0846A415720C1D5A033B0FEC98BEE8B21397EFEC13FB39D49717530B179E9CC6A5CF0721C3F3DE79D8B5F30B124A391B1A985B1E5E5A62C57887E63D7209139A566F5D7817FA4251D579AB5F525EA21D54230C3EDBD914A6E4B4B6EF870B016D966746BB3475FD98A5185570FFBAFFE7BFA696B86540D03DE2DEC443BFE6F287B75B04502D260535D99E826E735C097AF30654E38B64399F2066E62C9D24DAD37361D3F7C9CEC99CE170418102AEFEE3B091423D497A71E899F147DED7B676C374EA71EE2565BAFDBA9EE69584ABCDF6728A44B999B924ABD3B25CEB8232724E1A744F57C1DABCEFCB6C7B9B6BEFF38E3ACE5E4529BB527AE7DE7B0F00C4C0F94FA58359A588CC23E78125D2A51AE14436E32893DAFE64BE3F5B45EC34C1368ACD588AAE845A1C76C486CA333ADF09459783BCFA29A96EEE2897DCE01607F807D076EA7CD50C37BA90ED8CA558663E2A701F3D31C6A118083D4D8931381647E03358B7BE9789EA904DAC783BA876B92FC55B1A846AF74E4793B9CB6DD6825E06E0558093394F39927B7F1C1458A7808EF2328FA60D0161D2A64946BD57825FC4F451B5CEB71D13FB85328BE1526D1AB8A8C137C585AF7541F32F3A03ED92134537B8B008A73B6E4DEC8C17879EC6240537F87BFC3E6E701345D9CA3D4182C31749DADB2DF0D122B505F6072939FA7070B6ED8E543536D71899FA5B3B90000000000000000000000060C141E232D", + "reason": "too many hints" + }, + { + "tcId": 27, + "testPassed": false, + "deferred": false, + "message": "EAAB79BE1079071DC26001DB743D1F5C085DAB69967A4E693D8EDA97594FB4C7855F9C89CBA95D0BB6BC2B36E030336D4F025F9747487E863445686D84BDDAED97E10CA8AA6E5E67F4F3B2150083AEA5FC5E55333C4BA9910747F72A1151FE68D22BBA8FD630CBA4359BE2F0DA86CD2C6F79BF8326AC195171E2D876139303D6", + "signature": "772E55BD1F938E1DC74DB2D4A126E060650FF9ABEE2C8EB5F02E0E190DA1609AB6AA3476F9550774D5F8667083AFC49A9C1E05F2D7487C23D25C67C55D3BDEE6C78AA56D9E0087FAAC929581B87D08BF0C89C77AADCC99AC150947459D93101B2593B8B9C92F33699DAD8B0EAD27C248149E7A439EA425FB8DB40CB7036C3EE3970D1903F0B88C4EA0954AB78D4D60A04AB6036A7B56FC5400E5FA00E8842CBDA39566A43533EF7FA217ECD12A912FC8FD55B3088E504A3B777DFF32963628AA345C16ABC566C280F788FCBCAFA568224508F4006D92E1423E0C7CAF31B9AF979462DE827DFF858FF8E0D850A69727E7C68CF0644B56E1E5DB072476F9400147CE4AE8D87B8A2ADCB2A7C0520AEE4B89559F8474FF5D02BFCA275F1915761F4223A7D88A9FF05D0F32EBB1B0D1A7C60A7D9BF7A39F4AC73D3E941E29BC0BCE4C7C04805DCA40E568823A0239509075AD0E1F11F7A6D9337DC3345FBE8B4739D0A421202035BAB8DE52915E173A74EB1DCE176BEDC5792F9C9D65970A811B3BBDC10C2069D71D1F00BAF6C0A3906CF46C99B42D66DBAAB45F8DDBD582E31B0FB09919BE9B10E4CC90DA9BD32C1B87D03AF2478B82966BBB5F2CF5D0BCA4EE3C91A2375340AEC44B6E8DF29E7BF87723478A086601D477FA274C1483E348FAB9649C842ECBC062AFF4DAD85E07820B097D7B90AA1726B516778F5E3AA9A23624B0F217A9E92C4578172F97852207A1C89D57D7473E8CDC5C7A922BD305236F92FF20A7575319FE2FCB4E953951A5AFC25CFC6D5A54071BE9358F4F4B80B4D91145E33E88C9E2F6C421D298AA49779A4FD5A7A565269FCA1D068B708EA4F1D9BD55AC06844FAD15472DF6BE71910AAC27AAFB78C6227C84755AC1B99011B3BC85E12E92D2C5BD83311DC28F1B3554C669A5688F8FBCB996800365F009E676AF23BE2D2AB3E5A5CB5999310A151207EAE2AD15709D88F4DF84969FD2308A26B5DD15D3ADEF04567BABEAC298DD2ACAA5B58B44D592B87B6D32E55700EA77CFC5CBCAC319DF13D7DF6AAD2207D34231F1D3FCE1CDB3889CC8585BC13884ADE337E81B4E7F85DF36F48B5BCF405F62906944C77746B5F03D94524BAF5217CD4A0E553CA10CA15B90CB9366829F9079D2B4F35E0C47520EFEC8A04B72AFD350CD218C0D60AFAB37A9D52A020B84E2801F298F6BBB2261C14298E8BC22A4BAB82A725B9A5A34759BD7567BEEDAF966A241A9B6407DE844F72FA337C6F2792AB5F054FCC832D3826B89C1E93F32BC6D7B70D505F646B94780B2414B7EB4590754F13492AC09CD805AD88D8D5BD41C6E53BBF42F01F7DC2849280E840E20DEB7C8EB8D8DCB738784DFA6D80EFCCF7A6CDF03251723F3713F65EA378106FDFC7871931DAFBABD6916F6C43D24692D684C4B564844EDAED0F268E93ECE36CB9B6F4DF8B33D5044471EA9F3BE8298DC87FEBAAA9612829A2E188CFCEC1090BD1E84C39B71C72F7F650A4BFB4DF9A1F6B830233AFBD7D244993A57876559533A695F162C577455326497AE0319C96A34E7FAB0F6BB1CA56484B4E6CE3394D2F0D7C646C8C82A1B406C4E532486E6F10E35956FFF230AA48CD993E7EE01E1C1A4F84ECBCD6AD1F24F1A77B47981B7CDC8BF5450FF61A12B33A4FAC8BD98609805CB290B955812646357BD3803643400C252D2C9746E05DC6EA178D0AE1042C70C75BA26C28B84A2AE0B3321A45ADB6CA5B6750A7B5B58A57E8AAB749DD89EC0EB40375059158357ABC89E023E47569B37DF9A5AA8BF46FE06725995BDBC58E9E910C3F41409AF9C84A1C3DAAF0A02DC2DE0F844615EDCA580BE56C5A064D586C5070095104C32120AFD6943EDE8CC7D6FC7769C340EC5F32FD471242C964924AF0180E978F76295412D68C4D9DC1A3623B96658D5A04CB55C5855326137D9FAED00B661B5361F7B3DE3B5B17B8DBDF3A7BCF41DB9E880FC2DEB7F108A66DA4AD99C1376C0A7469B184B979FECE3C4B0E84252D19333661E1BC86F853ED4744D0FB6370AEB83A668188D089CC1E56F9ABF6C8962BBBCC7E3DFEA216075230E34A09E9E9B9DBADE6CA87818D37F44372E8EBC717F09BCE684CF44002B4FDF9AB9FACC5A6B510241B1FC89789155771E0199179532985F2AB2E5A25BB83471174B8B018FA438FFCB7B342BFE8269BC87BCFEB8B5C93A34384783ECB8B3E65DFDF5F221B506662C162ECED16879E5E71A88DCF34EB7265174397A95292390CF0AFCB090F6A44993F74700708A8291784FCF280E24DAB5CD8558A0B030F76AE6723C6B97A8EAFCDF1C94AF0A97B0059E8CC4CADB725D7CA274C3660C29CD37DE55098359B1615CB73DB1A9FE1ACA4D3C38CBA8D9FCF2568B073EEE016CD6A96768DE41D8F2CED20F414019E40EFB7DB7890C0AE3F0CABC9F083973F560A2593B0C671A67A52EBB3BA1D4A1B38CFD77E9A83FE89CDA9DD417784950B75CC48CDA6575BF9D2B795F9298E50CDCC7CF6D0A1C7E8C58D2A19BA30E99004D4B78FF807A9223B971F4104664D9E035A0C7EB0F05EC3E39FA91204B71362BFF16EED4794A09FA87614613153AE2B190DAD3B732BCB4DD0634184E96F1915EE499913B839F7D802663A02B65122C7EFC566FF8F1477D5FA09DD595547011D7441169B194A16AA4C7BFC7258AA39EFF878E88BFA47102275298C6023B3613DFAD69B384B01803768905C162A6F1B632540BCD3751349F357037E97C8F8DA5B9E2734DDAD13D1C1C438C1C5B53DF5C348B8F13EA5E13385E93AE453C22A105EE64F95D7302F870B1C31DEE5620BCC29839016C5E993293EDA36F85A4834678A4877A45BC857E864979062D860F3146154DC592EDA611A9705021A6AD5A219C222D09182F412D8AE27A4A14FD5DF4F22F887254F8540E14E7772B634A9B1DADA498C5CC86BEECF360077FCEF43B624B26062931EB42CDFDE282C0A77117A51E3390FC0B710C2C98DC6C525E690998EDF2AF5756E019592DF54BC610441CBB4B941C0F1922385DD29DB0D5B3E58FD0527759006CEF36ECA0A40325E2B8EEDEA7CDAE059A53F95420DD719BEE493011170188C5B10D882641AABA98F9D475D4E90876DEA7CB1A9CF36A0BD37294CDD2142607A7C940B9EB5C61E7D1132BB55DD7FA3EE35ECDDD26ECEE9D2B0E8D474AC4788A3AC4B888663039F2854B63273C3EE4B0D0BA402DD91AB5A88684EC93352A4C52C61A30335449E03DAFDBCBC25F1368EA0462023417CB26B5809B6D797087D92FE25047871FE11771CEEA1DF59665DF7FCD33329C6317323D84F05EF72684073C37CDA092B60B9F51EC74690497DBB9BC6FCB9138ADDB3C3E2776001210C45962CE8DE95110C5E194A4D5BDE6EB1E37C678C0561D331D84241D2E697D0A860B589F586E9E8D8DDD4873E11E147947DC430AF3382356DDD83E02D2EFEEBFCD191483232ABE60821FCA0BFFF456F2DFC5A147B98F9FB6D0211ED978FEBDD603E06D4E45CC150962EB8C740FDB3706EE4BB5A5B26EA854BC059CACCC0EA418BC8BF32A6989477610889A4DCA186417549DCB83991CB1C15709B9CC9B6FA6444FAA694DFE607256A9577ADD098EBF167B1F23C70124E4C2E99082C876994BEB57084DC6A31C3AD23D220DCE10A4BC18385301430CB1EA2BB0C73F775E4EC21C849F98402A3CA065E57E2BBFE93D8D0B019D889AAC393A2431F6BF29AB55FADD47323E534CA3E22AFC2CDE990269C8F5169AF0FDA26634A0C164588F2F34B11991AD52FA94449D15787DC8D841D474706DDCFD740F9A45BB14E877D30A310C364D21F65BE4CB2DBA391410EFF55583A05CB6B015F51FAB6CCE2705C4AA342994475AE3E47C72F113A96175191271ADB4927F8CD2862424D17FA66A089EAD6933CD50DAB62FBA2B24B3F08F9CEB08342DF8479330DF1CCC65DCE00A50F1FA53CF86AB22A8D598F66C460CA1AA1A67C47119358EA36065E08A96B7B399053D09801FBA56350BBAC23E606CB1F03A5BACE7D3FFBF3597402A6F4B39D75BD881393C7B486F01CEECE4060D5DBDBEA8987D508CF9172341237040359E4F4314313E1F158C105F2DE9B1E8070DDEAC3A89474EB227188828BDFB323C3A1162C2FE2FE2E5EDDADD653E9218FE8F16DF41630C327B7A5AFFD0F31552144A9A348256A10110951F489EACFAAD087D12699A26621FB883AB7807184F2C8EF84DDD6C262CE2DB192B2751E54D070AC79933E65958DAC87AD3592BC3EC1B3B8C72649E19A026FF7B2BB7EB2D7847E0EF58AA38FD2A9EF2A24C8F01F74010DD5B15DC47243309F32E47268F94D8213931B16E639B71D125E069C295216622AD548A47B6527199109B243355D1E0506E8C76627F92CC170D70EAC2F13061D7A7325F2C03A83815235B89E2B896D1ABBEBB715FA68FC3B5E4DF3354BD7AE37377E57C07FDF091E2053D65E7160D70DAE06CAAE7172C8C2E0F5A0383377A0B4FD83BDF4447FDFD418F79800D8E554B7E564F04D0CC0BA443055AE7B34D3212BF56CDE38496E1647E61AF07B40082AA9DB16DC041E2DF4E94E762C20D8BE0320611793663DBEC3350EEDAF9B2E7AFA46DB0D4DFB6556ECEC2CF0814D3E00C4B578A90A1E1EF4A539CE85C9294A2C1C3DBEC232A4446A1BDF8043A6CD1D3D7DD0000000000000000000000000000000000040C10181F26", + "reason": "modify signature" + }, + { + "tcId": 28, + "testPassed": false, + "deferred": false, + "message": "07F9CCC3426B0CE4C1D28DA2314BFF42BCE5EB0326161797C40BE656BDAD88D5996E1B6EDBC82ACF96AFC7C86E6AA90278754B038A8B072367A78C6C3BA394899AFC0CDA4D78B707E9758F2D397F3F507822F9523623D1A64968E693D0134525DD0147ADBB222471C781265B31508C4E3B5C8080C8728AE2A9C7FC72E97F8910", + "signature": "6F33B6CD8314F3735E912010847923B7618DB9EAEB0161F4070AB7D76DBD7084E7FF1BB01333E80BEF830D3F06262EB9A70A73AF73552DD901138A4CC4C30153C95F62CB4A33B14196DBBCC551B5B3D0A7C052D9251D5C260CBF683049766899455111E51F1EBA80D0F4B46A4A2E95A47C2326E837CA160084B80781A325FC0C7511BA80487A31D07E697E4328ED4630C4E4D9B3547DBEB8B9037D4DD0AFABB8135C1983CC92C356FB02F93DB17D42A042D5A82047B67B26DB54BDDC9E6A42C2F4B4CF6A79AD6F294E0763111FEBACED66745D3D8E3EBBFAF934F6CB4A1141A2380CFFD99E9EFD97D8548424FFCCE6A6C3C73A931DE473630FE364D0CAE7C40570486046A715296ED95543F65F7086D1EE3753381CFB1EDBD6EF38A3BD3B982A64235CA1FB8B714A4E75D848EAAA3489DAA6DAFB896936C38FC4734ABAB020FE98BF189A15ADC08E1806F5B36F768D76D9101BB326F76A385F40CDAD629AABE51BA3D44C1BF526B0B149481ABC5E36310BD45BC2C6CC150F1ADCAC721B9A88421B76E592D961AD1A2E101A675266D5CACC1B5BB7746F02A3E2EE93F34750594C288ED3C09C6345C1C25B90FFBDEF95B2DCBBC2239BE3E522589E2712030675D98C76BDC0B86335F06037E90C7BF706B65888C135E48D17F5C0653DBD7BA8C25F8BAFE761F08637ADE2E6B52D4084A7BA6ECBD3A243BF5B92C7113B10EE46B631BC92088A93FC1875A24D1DBCEF1320F037617005EBA9421E104E4D4036CA085DC50654CE458ABE7C0FF8B830FBF77501502A49D65385D447E00829EE9C28FD94ABA580DBCCE095C6A3402AFFDF22E4AD23519626014A47B66AEC54AF3A41BECA3C276D06BA999BA7E5BA31748AB274BAA1F137C9C2EB61DE3BF4490D9EBA754CFA68400B168288470C46F2653CD9F12B8538AD3B1AF5B912E90BACC76D55D089B9A844BAD581B50ED11AAE6FE522ACAF9DBF1D6B379A7A1489401F01E0D2DAA4233136CDDB30D8E9789A528372D21D2385DB873E355998BC78AAB08D8BD0100C4A0B76FB90E1F55F44B6811CFE6B35FA3329FA130F775257C97806D79D395560F3999E42F3850D8E5116A01C802285ED4BBD091A5699A2C63A27B372133F5F75980CD5FBEE1DB513B2CF9A4DDF6ED2B1F7F198C87B61DA236B77A2DF6E9385D1F3D2175140D1E0C126CFD932B987A9BBCA2F4D151C93F8F355333B3B4D830281A7C10572C4D64C9D2B1FD587036FEE580E5319B58CB9D918925AB3256F19C6D41CC2D1790687F42B22A910F2F7E914AB826C489F41C85683ABE8DA220E7535F636DEB2D578E81689F4BDF9726CA78D3F9EC367E67848ED3D3AA82C09F2A9E01B78B4CEC6A02E591A41C3519E2489B9CB854D71305C2F9FA4C3602415CF0DFC1193485CF8A2F6501A7EF50BFF5EA3213C45606257E26EAFB7E424A7A8E22E99F58511C568571E56C3CB30253906B3A0FBB6E23D1A23B28540A13F5C0A55D97C8DEBC275D7EA127C4946A3ACF41C14BBC48E9D93A616671206D4FF6ACE1087855095FD5799078D9EB31E77E2AC9FDED6B2DB8B691476A80414228E45274508BD0B8C4B020C73C832CC08E2F641B23D805EFCF894ED099FB67A31CB4DB809BBAF71B1E1085667353D4A45D422ACF3F7CD126603CC657FF6B381A1F5768981641A4450335748476EA00C0E37EC411F9229B2424DBFFE24A5DAD587FB496B85EAE53282265BEAC8E031EA966857FE00C46917DAFC4F5E9B440A371C33ED31B940C74939BC92AB425873C64B4C7AC597D27A1F891D1288F839FCAD64CA9FB5A41795C7B9B495CBE1A9398AE9D18A25685ECE4BB7CD63EC00B8929480CE0FD2ABEC9DABD5EA6AB30961F0C4808D5A4EF33B8AD395B8DC4CB057341D5CA89CA90F75CFF7771714130A661F6150877C79D521D145A8934724C387EDA2E91FF4F420016794DC6A477D28DFEA5EDE130A5DF51F96DEF285564BCEE0B577CA3516B0357D6605760439C7737497D9FBCF5916EE558E2AD88C7420D4BDD6AF34B677ECF51440036217227E3C80F015C20FD0869030F4E5B8B117FC520D4E508BDC007F67039B28583336DABA25ADA73D053115910C6B28A77B6DC72D3C627868BC5E05114BA0D67EB622D232E80CF485DC236E9BD3B88218F09F852EFEC1391E42B3F21A42992D3007390D78FE161F784700C31E99C747BAFC93C95120B5B542B41DB2080DC608C22E975EF2CCB0681E2C170B297A6F45354E7E2992C67AB8F2A3B7537F902BB35048C199A147E8C6D697FA08EC3A8B3EFDB6573C82059281D5BE8108BA99E09AD6139CF0A5241CC364C7E2316C983BA751EBC26183A8E9C6E74CAD33689D3CDE4B74EAC6B566FAAB81F6C888DF9C30098C5A7538D80EB3CEB86EE6B8C75C62FCEFC4CF913A63888C1A33FA5B862B59541FAC78E0423DE95C2277A17D5A7F1C60B52A21FD6D42E1DAB770446DFDFEF9C5AC796921276FE1189BD38C40B713BA0813765DF17110E6EC0A9532D8625132090D15BAC647E16F99E9A096F8EE307793AF2422D1DB178F618B60D5F71C82B7D667AA4E45BB2775F72C72D95360FA269F374F140D116A110598CCDD0CDFD5ABD067E7CD1C8C335650F96F235115586E16805B442AE0C592CFE4ECA870E8AC0122F4D433AA3DD66CD7348D925B209670931CC4D9ABF11DAD7BF711072CC5FE786B24673A056645B4478A6C7BAC1B87AAC4A83EBC78252362E7D703760CBC6836011B01723519344337A0548F058D72601BCF8256AB246823EC2157251180B28C4A86FB401EE3F68B9F63B4808EA5902D1C4FD86A0B06A718DE7E4501F989D32E58EBA01CFB40FE0F9B5A2D47CD6FBF802E83230DCD51AD89707BC0EF7EBAA171D0BD7C328AECFAC246B5D5796BF0E54B33F42BB1C76D585CA3A1EBE7DF9075AB0BF4701A3147AC73630ABD35FF113F3A3505CCFA799C02DE5DB1EFB35D985E70FAB2C1755CBAEC01E95B34E52439DFD7EBA30BC80D6222ACFFCC962A7010290BE5D7BD84C84BFBD9A166D7209AD9B187125E7439BDBB1D2BE4669B35E26A165A15F6D6D86B6FE75C7FFDD854F19E6C06978499E4D3C807849C5A55744BAB74F0B69DA7DFC7824124D2DD73C34F670943771A9022557C1CD7D96122C67DCF8C05AABD76FE45A89E1D4A820ACBE587233551AA615B0573DEBBC1B8FD09662DF7B3F26D1FA77367A6991F186F1AFC079BCFA8E36708CB26DC9BD487A82A1E4404DC71DA72D63FE8170E9CDFE02AD400B2B54DB2C9D8687F51857AF1C04FEB4119947212A3571F54423AC0265F5D06ACF77AC5550D53A1589F5D8F17CE5EAB25C6DD3048E3BF24E04F8E55F35663FF00EFA65DA4C9D8788AD7AD29DFD776A72E5C9202C08CCE2A922B9BCE81B7B7E047C199DC4D3CC66C993C405B6CCE80B206E2B419A89BC36518FDD0D3F902EB6E6E2E948C182A0E2BA1A6F466C95D48F87772B79BE348E12CB38FE5C4184B5D23CDF87EF6FDA9FC674B890629861245AD9F401C42A2BD69A4CC8D133A952A960DE206AC95E44306A9817AA5C63D69ECF47ADBC6DEBA3BC504FC5029B2EA0FD71E6BF3997BDB9A45A2477683EE5B8BDDEF8BBE61CF90E9FA426DF70603C381A64495776214FC7F89E42627C7065F7CA096F91AA357FA3565706D5D108EA1D4323D0A10DB99CF48E374B54D8726DA7C25F09ED9322B63410D3F017B4F6DE87BD442B339F50813942039876AE0FBA196846B66FE453405C449AF7EC09AE1B31B5695B00D7BA81524AA1EFA1140283E3A8140575C33B0C6C679E8F6AC6C8BB09E066AC3A39D732EC29209C96388A6E05380EEC6F9B957D6613A979EECBD8D41CE7A075D66A44A212C9335771F9902682887ACBBA4020752B250ABBB886C7B0BC50B8C659E4BF89CEEBEECA053E52288BCD4E5536ACB969CBB61ABCDC00E4F575D5B1084C6EA4321BDE61AA728F03AD072A678FDF203386ED0828F1883A96DFF45B15F81A50408A5E54393DC1757DF3FD304E9AA212287BBCEF5C92587989AB4A699D2AD3EED036D4D5FA575D183DB87E094B8F066F125FB97A27783C96AA9B8628E491363BE4369607CFDD81F4F6137EE707325C4420F3DB2B5ED0883DBF9FBF86871F6EECEE49FA91B0972A9694D0DD6BE797F6CE18E2F6A135F82EA01ED3F269C46C659B0A30E9A7919309AB224C2E8D96AE5B1135EF962BD9A22BB68F9B8479719EE5B22961673F5EA324FA6FAA011836ED1AD1C0BBD9378C82C8A20EAB448169557ED4044833B2B284F62E34BD3A6DFE3730A6D4C73ADCCE24B0599E730019D71EFC032F849F0044C19FAB0B37C4152CB518C532F78DF6CB6DF2EAEA603226210FC42B19EE66B8AB2EE61DB703403DE2696E0A90CD0B3EAE8D610EF52C761A91CE16AF4A6507E04820CBC7A83C679F674979232BA01A581001DC0211D37599E83D2081A2FB0926A0FB033351EBAA3C80DC1747630B918F004A5C8D4E68CD0AFFEB74695EF100A19637717353C586595FED8C348143EDCB834B54EDB40B0E87BDAD3497AB4011FD48D6CBD6E0A04D9B79F981ADE3340E1A3A45EDDEDC0ECE121767F52D1A28C06973C8D9800774C23FB32F9884E38262C376688BABFCFFF61790F164E75F0344E768592FA476B7FA7D5EBFC1C222F337B85B9FF000000000000000000000000000000000000090B10161D25", + "reason": "z too large" + }, + { + "tcId": 29, + "testPassed": false, + "deferred": false, + "message": "0579CDC4FE55C4160377BCB12B67BEAB78BAB125F9BA892479066031413A63BF60E31ABF90D9DD845FCF8F6F9CE1964B67DD8A92877A7320385D9DDBD923E592E75993C1B32588034D399F6CDBC28217E2395526CD4A18F4A5CEE419DC2ABDFE3C6A321EF87985BC0457DCA06E18EE1D767A06962221FD19778C3A39E28D5B28", + "signature": "9F04F0F9ADAF2FB20F6A51946618176F160FA06F75BB13ECE89F42A298B404AEC07578CE883084D4C63F30B62232F725BC16168223D1C7B4375657EEE2208A9F484188D9F54738B47B7966DE3B8B16BB3DF1786CCCD81E921BBC520DE5B3E7347F47E4EE104B958CC4D2FEFEFC9A1918CC764BD3FCDCDF9218C53921203ED71631E0017B93D7AF56BF3E1073B0976F4B4BDEF744464E43FAF0AE22CBEAD9A78434C58D03F6CACEB3F234E4B3129DA9B2CC582EFD51D3AD76654670AB94BFEBE62C5DFADC56089AA1177F0B8FC03818363256065FD6A7F5FD9A1E4320EC73422A3DF374F6FF2C747C8F77EEECA899313D5990EAE749B2EA5E00B746EF61C3122322D4D207B21A020D40B1B46E0434399B04F366997EB6A38BEFFDA6B523E14A367ECBA8BF4245348CE4F0612FAECC89210C45C359BE25FAE383F62F5DBF15D178609D5D615E5BA86D11D2EA06906A61F4F2B2F7645B9DBEB37FAFC92D70789A85ACFD6DFBF5BBE2668AAE07365FB5D14CE9613027FE9BD88BBE22B9C8645DE8B2F4A395A27F348CEC07E0D5EC76FF82EC79A2906F04475E6CC29F46140ADF86FA189AE38263CE15E221F38A1CE51C339D06F9A2D4A43D75618173B86F41263E27D9C7B07F130CF03E7059EE3A98037F4390A1AC61C59F718FBA1F17EEE2BE456FA63CB25B8811B51671CCCF8E538918A8FF10E69922F6B9740258AD2A08E26644646D534E3D0A622B74A07BE7C0C8EEB5B1350F4780F3B66FA803521AA3EC8C9027696DE80C07D19EEF26941836DB535E00F91252446222CF745C33DE8B42FEFF80880006AAD2B0DB5ABA4A436ABC36D7431ACC87CE57B698C1A238C7CD75BB6D5E3D7B3F8DC3A4B0B444D6598E2B21E664FF595F49B7267E3BFEBDA2FEEDE3FD313B5479A4F8059F0BA56FECE23EA9E6018E87FDEFCCC34F2C9F0AF400C578B9AC335953DF6CBAD3220D86B49D4E6D933DC6B37DAD9C671AB87F30D829E5DC6FDFCC1EBA016F37F7014A911100B0BE3DA87BC53F453D323D567DB3A36F1DF24EEADFC5E603FE4D425347408DB8AD7D40E530B027B13136E30B5B9693F084C2A160F50D6A2224C2257864D5DB52E36D9052DB125A282E90A3314554108415087A852D22605BDEC1996424288B9D75413B5F30F1E0489B8AC76D13731CEE2F3A6CB0A002FC25BA859558BC17ADCC4ED8627415589410AE3A52B6F06C7A7E103BBB350F8DD4D6F2BB92FBDA54AC9FF6D34DE291C966A705EE615F3F868F9214B77ED9A54ADB9C97FE1F95313CFD64AFA6BA4594E22063EF070FF3B913E9F05351958B963423DC3DD85FBA36C452A681D3D65D6CAAF1C6043F8A21C683ACA6038E7BC2C1663FA6199A57C881B335F92B3225F60534631C30025F9662046E6CD1334DF335D0FC45507AEF68E4D0F02F07F88C0D40104BB8B64F7D8BAE8156A6027266BC0C820A0AA5E44896385112A0489291C5D55F24065D5EE636D5FFFE2AB7778E4A5FE5555E535F30AEC4AF0436743379F0D5713DE40C44079810F6F05AF48D149E2FC28A580AD45E658248DC3A0358804149A6FCB3F006700D4B27A8D457B32B16E17F3CDCC132782C38A70334BC4B7F8F178CEAF0F1145E3B52C3861795C400678303CAD2A2CE35EA95F6604342EBE4CA46471A5725146486E477C8ABE47DA05FB0EFB8A06B4477CFD4A8E1ACDD95937C8AEEB5B7629B5978A55B08844B122A75861D71311CBD1857D29AA5ECB8AA0739A4576FEDA91724D068674D8F02A9FFF27835E1B0B0AAF395732270A95F66156519C68E53B623CA04C2ACDDACAB3422672CBD55F494D219CCB3AFC52A042020B1BAA0CC92145AE2D663327236864EE590E31ED424014E0C152C99F04C8029A5ADF03E6F05F19754AC5B9B5D9AC272A0F01509580E149710A5A5B031E0A79C52D29A86E153A108686D68A9B6B30D64C6F450B18703252B773FE1A5EBC24971C88D40C07F0BA78230507B1B287399D58C62F60EB76CEDAED0B72348BEAC679466576AB82B44BA81C0228DFDBB557184EBC91EF34543969A5296607016773D233F345CEA830EFB0E0DF5AC94C573E48C3843020CB9C0375225D68030A878B9861575114A8839E888246EF6E2A023C6A062349565F13093135CAA4A06FC834023ABB9799C5FF14467EC99CA844957DF3DD1C18AB93B5DCF2E36BAD64D70F9F42889B5A709E6BCCC28A3F08BD8169A3B2B5C637EEB3123F7EB3BE9FB82E950E14027D2CE76C3A2A4E0169CD66F8C2B3E942A8418417F439E3F09E6206735678DCE772FB2F45F6B9907636D17D1B1E6AB52D726F04CAFF9451E70A6807B6B563AB2625EBC1067C7527A5F1AA1F6F63033B216C5589FF612488C44EF1813FC767AFDC421E96F16F29E7BB60A3F6B76C907A2AE4DF42E8A6E3091A50BB4FBEE01E80F0505DD30BE0668FF508D12463C609A5DE7917ABC84F36011695DBBDCF88547E7F229D7708B91CF24F6B3F435EE75D1C9CA6C32A71DB3F2574A1898C81B099A911FD5AB42D8FAC3A5E1011C0636A29D9804C8A1DC97E430798B6A060CBC0E29327A4ED8FB56DD1E2622A2AEE4626F250FE9CA071BFE0BCEBF3C07D19DBC1A3AAFA5CA9DF96BBABD0F54973457DB8AE1833580F47B2BA7293E89CD2DD1E6A3CA9157C8E1D37A888FA1A697D0A7CD081578B9FA424832D6AC08C36F37F163F84A4831CE0C74EA8D419BE6616888E871B39762C395781C4D3D96C73DB5864AC52589F3014EA6CE21A252D394AF8E9FDC1C7EC1F827B0ECD0A85F1E2B44C70AC2AE9492351AD429E8845CD0B6E8B5B1053B6AA7A26B2F9C4BCC0F2A7E56AE91A23B9E3A87CB125F1A4BDFE41A61FA1D650C7708426DBB9726608E25E47DD7F7D54F5F2795504B13114EAF4DC314DCF0A90E862620D9CF055CD0ED0435E583C7207D365390E13603278F4B3D481EB49C2B85ADDEEC89C742131744C970C53B25C5A7180B5FE23EF5D537FB9E329867365A3EFEA00E3B4FDF3C6A711034E01FDC4BC2B51A49B5479A0C214916CE3B37CF09ABBE137BB0B5BC2D5FCA19A2274177CFDD293AC37B0BE57C84994B86F2E4D1D97522D90C12C1D4F8562273FF024516F26F041C0410090655DD50C4BB3A8AE54073636A48FE3E25AFC2FFFC39F558F7F17BF4A8D10B01B57007A1C69948CFF1EB43D7A46963E650563737990E3984E8742DFF692830BEE970A644A13EECA65217ACF8D662331FD2037D6676F4D4FD0480FF3F5159BBA35E23E490DB27CB4B43CA8760AEA2DF0A9E0EEE7F0ED695D2A844F1408CF8DE47CD0F0343515A7167439E58AD8190D7B1F21EA9F9AFA90C5724AC6E9B9A1A2A0A6D848322316FDA2F0748299D3343BC2323E06F4F556E6A537E8C04034B456A553A29F1F91B23DBC364BDB7CAE2B38B822B25A1C40585F20D44F182C34AB57F93407FC02FDF72A7A6BECED973C84BFAD5058F4B58A58ED2B85CDDFB21B1340ECB6767DFCEF879A7ACCF8C11E5D8D9E84E5962668EF6CEC28648FE00845AAFE8742C3443F5DE31087F1C48FDB1ECFAAC5EFBEA318ABE5F8F71C3E9C212982640F7139901DCD23B94112BECD31D2D218FB1FF454FC72506785BD74D97026743EF28DF62554B6F9C1F9F1D4BE5B904F0B756EEE696CCFC4AA1D99EB7EEFE457AF23ADCB8EA8E77591FB0E366895536E016E7C5F8F3B79CDB28E91F16B207C9FD2994BA8A123F737395B8926210F1205FE14D28FF9143670C4DA3CAB12C51D289A50D8197883F4B64E8D046ADBB74A2F395472FB4401D85AB76C4EE3E1430F4A4C29F884C71A0D8C534D707D77F80B9EAA77CB9FD1E9B8166D9B71980EF749BBEE6FD9BEBC9F8C7864E734D87FC946E2DD076B3C4767F1EC50C767E31CF2D97DAED75068D5D8F6A0D49BB5C0FBBAC550532063A0D8D487D8C757236AC37F1FAC5FFB5B18BC258D22C9C8D94F774D4B000421B5CC2294680AF883EF82C79048810CC32FEFD1989FE254B7E0A445E0C055CAD61A0C50FEC40D44B642D668DB884BE44A1AE6DCC91ABF5809826C48F46AD5D26694127AA3D513AC35C4B43B94EBC9F3384881F48662C77ECBFBC7DFA45E2C4F22DCB909F08CF1A828A2DEA3FA7615CA12B77B48DA7AB10AFA247B993500943E5CB79C9CB5D0D98754B69C5F2A0987ADD573007B62BE5781C9F371ADDC1440D0EC9F9D95F0473AF1A39A48836E87B63A40C7B62768F23DBC2D51E1F54DDA555115DF099F2E72F4A32D09EE45ADBA7919EB2DECCC2A5E381D3F10EFC7338BADC11BA2EA7921A82C926333907C5637FC0BF3CEE18070D03DE66FCEFD96218F78367F8668813A56CACBC97B6E9D5349BDAC6FE7D326125737066862492C1827C7EE809DD5FE26284CFA6840B29C01A31E2AD9EFFEEB9CB8C4D1752DC17DCA784CCB9873DA370C83EE854C7AA6722A7D35C7BB9D30F3F506F39796264E73A27985F23E5DEA5568643D573A8EB57A428ED67B2B1ED20558868E5C3C92E80B57CCF9A71551C215856C6287181B050766E0BC9BB6D5C6EB767F872CC72D021D63D3C48CDBA7CEC6F57592745BFA99C1E3B8ECB4E2BEE493884CB488C2E298E63964A4DC91BE46A8B4FD804A6EC31AD797F271A3C88A90B0E5C8E45647497A6B9BCF8252B639192DEEDF7FD11168198A6A9F1131D39567F8ACBD2EA0000000000000000000000000000040810192029", + "reason": "modify message" + }, + { + "tcId": 30, + "testPassed": false, + "deferred": false, + "message": "3C77C67FC34BD5146AF5DDEA08ECB7E59DBD4F0C676228768695DF4A7C20854B49E6959815214CDF93D58ACFCACEB6B71308BFDABC6FFAD20FDCA00F2B69EAF5C4A8B8BFA3CAED5D980C7B6135385327A50BB466154AF302A53962037EE4EC0F37BF071EF55BC2C76ED524B0719F0C72E01EF4177821B4CCC6AE1A66915C32BC", + "signature": "2D26E2B81D841244C2B8FEF240C6B4EB2E4B78E3363EF6D931C2D1379924E0C0DFA5799D6A5AE4A6C5AEE785598F5EDD014F3FC086CF5C00609DD68A54E2EF651941EF663A788F776B32B2B32C3E9DD53C6F2B2CEE72D770B3A420C6AC5D1F5D1850ED4276552D4E3A41B203A209E79535CA43A5F576AB37C9FE1304A3C3E275D0278E05BC90425DE33C9A54DCD4BDE1AAF659F673EE154BC92AA76456BCA5665837EFF2E4B7F9DF03B638C49C013F64C13F13CB52EF34613F315A8763522004D77C5728181B1B133B070B43CD021271E697AB55E1063CABC89AF7978A822BAB223AB8D0675B26D437E645C8E8F909AB88D1797DBDA878F3C5DD6C237F718903813E1464DBF47CC134348B042423138EFB81411729BC94068EEC8DF1BDB5950DAA03E6D17D97DEA579109EFA0800CF2AB52E9091B0D39B3DC576C66F29D0028A503DA6144B63DF6229995AFDC2F3E1C038463E29B3303CB89D97795725FA85AA35EDCBB4428DCAF3F4DA6116049D68060EE16CFCDBC8C66AEA37261F7E85F711D882B1EA014AE7C4DAC02FDAAE43A7CD3B27737A3E642CE3059340995D61C05451468737D3F88DAA5D9EB9EB12364A77F9381A55081BD2370CEEDE386D23BD9812DB1A09AA3B9268CAEB061B2530299841234C35AA557EB6CC4F9671ABF4067CF14939698816F3F8BA59A14ABCA1CA7521F6595FC5E90E37DFE52E23AF66F17AF8B2534366FB022C861663965FFD1737BA6B47841AC269F2DBF1FD1CF91C9DE5DE46E90EDBBF259548FF9B89EF1BD29AA6519C2EA2E7778A9FB76E8E36C9C9EF96ED92F93F1CA1A26C636CDF8C162389DDBCA74DECBDB1B9D543C63B9C231FEE27340389D183B3B2D51E614CB0024ED0B52DB62759F332AF45E4033748AE6530BCDF3F3DD4A83AC5D56FE1F4AF3DD6421C1DEA849712E1DB78D816C6889FB320B7A18C6B8B0ED4EFD25A3D500F6505F3A03867FA6B8AC6ACC026411743CB0943E1F5C409B03A532CBF21BA7F98B79850D496AAA4260AA733761C7A144D6AB40F110146F7F9B47FFFDAD1D591014307442CC1403D94A99D5985FF51A42F1E513FEF30652EF70E40D12F131C259B2023514F4E0EAB848FE89FAAFB2BA14DE6973016743D645CCAFAFE07ECF74A39A3175DB07009E645758C7FF9AAE413E9D97FC107C46DCABC6948E6A7BFF4F591D9BE8C3F467A6D1FAF005CBDC511491F8D71FE6938C383B353B058DA79CAE4E9A8675FCA2C976BAF4DA3A0D474D5C1E588F9AE73BF0721FF5DDBA42B33F2B5EEB2E300AD0F75A5C08BE9F91F8F4497D3C95B509AF42DBD04BD0559D45644D5976FC06C492C67545AF347D86FA8D076888ABE220818E0744AF6BCA8A01D36AD99B984EB30A79C453A2D38070706751E820D05FD25E293574352E9374DFCC8905AF57E7BD7D80F4132CA730FAA66C3F85FEF050EDA1EF647CDCCFC17C2BD5618FAB36A15E328266033AF9E6C53E8DE860060D0712C239E20585A50673D67A588DEE874185230221E2E66B86ABE7DF161F9CC65E5CF3F6A8E817E9A9677CDFCC147A71ACD6B1D955A2220BC7290EFCDECA5DF07102172CAED11E7AE7C8D96D40804601D3BA83B7678BE58617BC90D24C5F4549B22E39C42F9FCB2D75AE069F3B609A53B70F33FBDE04552344D44C876B1A4AE5C21C72487A01710C579DEE84A77E9A431446CFF0A41CB9FE30601D19DA60B4718E5CC4D006E4F9081F277615A5E5CAC3E057C25761ABC7F35FACBA35B237A29AC99C4EA911CD8BBD1D292C1510E8D7742A5D7D41C14195C8E7DE4F4D22F1F265EEBA6F0253770954CDBBF3A558A34F5E6304CC6088EE19293AE1B32BABF93B3542A0D7DE13439B23A30A634F55E9AC557F00C7494F16FAB7E177CF828261CF6EA2B7CF9CE7E870A915D3443800D81507E9CBBF06F9B2444B347FE82AA2E7C9934382746CE71F625B582678FC55278CC7F3FF185358EF49068E5D9FFEBCF3EFA6184D290C187FFC290D04274CFE95DB27BE80BFA7D7D4A813525D275F9DCCAF5F42DA4257DF5B10EB1B605401F1C2A59614B1EFC7B6E5BB5BFFE687F970905F1BEB8302A1122C71F609B413F7E88E6CC08445ABDED5EE6D40C7DA0F3AD53046D209CBB08C95AC4B39DA6E72F697603182060EF4635D34CE5DB99E5DB5A9A1D1A2DDBF1082A13E5C0B07A43A950584A1BE99FDC16078BE1D873A6F8B1DFCF9E4D667CA42A31749445D62C4D480200F1905FC97CED9984565BB0A1E46853C62E9739E83EC0DCFA21120203F1D43C5F732F3A7768387D254C2E4193E00BDBFEBA0E630797E59741F1540286A30949AC9B231A151793393D975BC74390A288E07E143D8C70B071323C0294EE54C1AAB8E193FCFF85B4D6863ACB6C4CA3FF4E23EF4DE7D15788EF8E2E4F285E23D827BC2EC88DCCF9E054924A83B369DD59C21759CF494511A63DAF8FF725ADE637C68DF6B1DF7139D56C8634EF66A25846F1EE8214951ED1B11E28AC9BBC3FDB3B3D8E9DC098826298554ABF8437D8382F7DBE3886ADABA8CD7651FFABC710CD3775D12E880066161775AAE2F247F2EB58FEA434DB535555FD06163B1B1E5AD6823A3EC2B673725F7859C6010645FA6CDD8C667621BC31767E20340928655CD613F12AB6ECA70A7B2183A1082853ACA2E618DE29D1B2D8050C7F6814AD4D73D9DBD9A19A26E800C34CE0F17881F1ABEF381AAE4ABADA2F05F394D125259A919CF78E8E65480CC6C61B779EE5719EE6DCDC7C625FEBF5DD68C34EF77620E196F8BF9E3FC454188FBBA2BA62851D82F4F9B0B07BB776653DC7F929529CD258CEF275956F92139B9328F5857545BA5B2FF560E945792697CBAC7724B0209CAD1C62FFA479B196AEF1EAA9DC66E4260101959869254021493B8AD22F5E16F0711658A0E808D54A943057DB7E8E7FEC1A03D316548D586E78986AA3FD21BC96F1577F89C77FF72B75B4A937A54359D5134BAC694EB15610292FFBAF62AB08B10A981A8BDDDD9A54D21953537C61BC575E6D5EF0750DF3065430729B6B2FDDC324B81D1A70FCDBA156A538FBACC078E831010155A2B3945B83D320E3B754D50CAADCAFF6D7931F916148C262DE2E0C62DE8211BDBA6FB7F5D68F012942B21DD6B77058CC19737992A3004D7EEFFCB2E3B8F34C2CC9626FA8B8FDE53390877B73A76BDAD294E93966BB03BCDBB5A8314FB7EACB2A17DC0C2897BDB841D8C2BF64E2AFE74FCA2EFCF6A11CB818935A7B2C329C9E70D89FA51887DAA8D1AD1DC2D52D4120D9EF2D43BFCDD6142D5083A352FD0B33369E4B8CB627FF593169244E7D44A769566A10FA31343DE188346D11EBCEF039CBBBC8CD57F9143D7AEC2C4BD4C32814BAB972C99EA7CF31E94EA9B634C45BD666B56BC1B7D9C04D7255A1B8D8180B559ABCED0B986A420BA0D7D9376F672875D01ADDBEF79656B3E676081B8A9AA329FA82715B4EE63294BA256858E91AC9559E5C633A7D404F5F8D80BA201A2D6E976AF3C3DD6C97455B0FB701870279D429271929DECEDB870514BC703F7988AFD6653AFBA5C1915EF7276DEBF51F564C12284D4981B216E00D20DD651A58C9F83BE32DDCFCD8F7BD4419EDC7A14558FAFCB12A2DBC077A15F525DDB339ED8FAE9C3EA17FA1B49096105328784DE1F3B6AAB3D411CB7EA74FAC1CF27D9AD594CBF5931AB825864ED976A43927A1DC18203656ED162B032E03EB9C1866255DABC10F141E49F0E388E1D4859A89FE15EE09CEF6EE2D27DB1CEB5873991C6F069DFC101E218652B756EB6DC724A8073F0F9A2E287A76D96508229D85699ADCB8A1EA78C98549C5FA53B3BD34873DD0AC236D1E3857D0E6170502FAC157F0A73014FC611DC05286EA49BB255BBFC6AC480722BA7B1C28396622DDF9E45217A4AC64D365685BFD22D3EEE8958D3230C7DDE7653F96665F62276B21D919923A48B51591BC57FFCEF5A051E0DB7C02AEE586DEB174A0E924FABEB3CFF1075FECCE6E6F231337E00F6E890203BA7B52224D0EC696E578EA13869713F68BC654CA98DC489D33784F081664B4EAD87B28B32D75F865F32685AAAFF37BA2A719CAEAC5B971D0B96C89B53A80AACD005849E0C5DF63EA42FBE93D09F2A13B15F46E189874FF57C33D6A2EDB2A6686A3479A97441BCB7FA61101A05E106EC16CCF10B85140EAECD8E1C4201782FCD23EDA7835EB6D5AE2F64C723A87430B24C295B0F281087EE93859A6131F36A59C936E0B23F0ED061A7412A3407408D49C2976BC6F50E44BA32D21F819AF80268DA3E25B7B517FF9986393FD9B880C1CA9D372A35BD50F98C6EB10AB1958DFC1BE1A5AE0D606C5355EE92C5B0D9259C1CFDFC2786A81F1A7B77E185A9BA960019E16014DC64B5032F91958FEE7F87A8CF659789558C82E776480A6F4CA133844E0A54F7F2C315FC6927ABE684E0543163115D6B6D3F247BFB22F0CD6CD4977C9B88CB588011031B265BA469CFC2BD1DC17272BC8547926C255335DA0FCA8F66F31E0777CF4317C26FF84D58A3CEFE5475E753D12F793F1F929DF9ECB066348719EAAC14D71DD11DF23C3747272929601C89021ADECB02C5525CE5B73CD1FA69E9B36375D68C4012F4552BB555E84D2FE026C7686878C91A8B4B5CCE2F30B0F455F9195A7C025697498CE0000000000000000000000000000050A0F1C2429", + "reason": "z too large" + } + ] + }, + { + "tgId": 3, + "testType": "AFT", + "parameterSet": "ML-DSA-87", + "pk": "59B2371FE7BACC207FE1FEE88A8B3805A7052865691789BB90542FA47F7EF2B75FCA13DBA5888BEC320514DCB05FD26EB5541F6E572ECEA6C4F1D38AA70259094AA945F19FED0D980E65DBF65DB80F564FE29D836C5479288B55CF07F4E00159B6955DABDECC8C4D66AE688728BA6D5C0442F3C1232C782C465B9B7C5014B1464065CCD8A56D6B1C16510869E014E6933998EF725520B400913D93B0EC75E2FB725DC1AEC0C0CC7343B9E544BAA4D679860E347B2E947D8D2436F09298A7BB8336B9DE9CFD5CDBCD91C7249268CA03EFAC273AF52968D501406CD9C96159D7C15AA2900330C1189CFC2CD8B912C480E458297EF14DB694A3F1E72C1DFA3A3D2A8A69E011602B93020BACD1C2F3AD06C95A7F36EBF5261F6EC106816BB3303CC00BF4E8688D2E8548F10490D9EB23C56793B34B8406CBE443D8356BCD0F4F61D0D017D54831B9BA329F8948F25C3122F9DEDE8CECBA51569EDFFF895FA020862C5DF79F864078486B5FB228FD789C35FDE1C54BFFBF4A025A7FE7D8C3490A5D4E62D04F79F4183CA68379F4648BD5B2416DBE5B845C9F4B7A7E2339C0506D58539EAEA9451C9B2FE2A18C849DCA7EED9DACC058D005FB7375C4EF45B001543FC68E47DDB6D14FF937D1AA0D4D7489DFFA6210679CCCECF9B8551DCF682D2AF1E5BD869F3E8D400D5C861AE51FE7EBBB5457F2EAAFD093A9598EC721C69327C51930F4B9FFB2AA7F1A28436B6D808D75392BC43C1B5B859C66C54FA515C7A615A69E60921434AA9CF9F9E03C3CA35B5EBC6A409E822FE76E0924C6C062F1724C382FF3C8ACB5C1666C2EC26B7628E3D7C13DA8D758890E6CC017B7892582E95EDD04BA9345DF70FAD56EA68BF8875B932C28B32807C86371E17DCC04725CB597B524467963E1D4A61B5FBF9EC504D5DDB61793DD4E34AE082A5990EFCE801E938CCAE738E02E90599D971C2D7C64E5B6F8639F758ED621C1F21073C03EDB782C7A0F5D7C66F5CE161DED55B3E92DC27183AB083DBC1F3930AE56EDB8C53E9A7E020FFF0C4042F518B26F390C96C8183B79B53C7C7BC515187B3DE8CAB08769C5DD6FF5492112E8B0F28D09F4067ADB04194F60250E75ADE331A5C25593BCD92A6D1350439585860BB6FEEDBD2F839F317A01358876C88E898AC0C85378F572F23CDE931D47DE71D3353DAB1F810A61B18D24CD83DDAB8D53BA9C7B8274B0FE82AFF30C57072F643787CA1DF03B99EB57DBDA8C8EE8EB201F2847CBC9D34FD80CE6BC5E1E328EB6EFC83C4BD9D52F324E30EE4B5E86351E5C8C4C5456836D5A452203B3C372C787AE3332C8A5E9DC2197D9C341B9756BB1E63C75BBD5CF3E5CD4BF47BD1FEBC3E3710912D63032F6B97DC19C4DE196ACD9157715E2C14E054A9317BF96A684BB96CEFB7D8FDCA8AA477A2AF6F726D2CAC1A603CF1360EC11CA897E5BC735AB69B8647F30CED4947BA9F635D9CB2D82A662FF17A0E12D4D06D641EE76EB8B45C71EDE38C905C52BE76C6109F2612FEE6C3194465C19BA5D3EBCF1F0B5E534E0F0F1D31CB1E7A36C4303F283DBA8591CC609311A809E444E33A893880CDBAE29119146A368E4D2EDD91FE471647FFE821AA6D31C9FA49695EB9941B08F7BE3F06CDDF2739B8CAD2AB0DA4F5A3C0A26DF6A17B137CAAB3B919AB636D6C89BEDA3058898628721F2770315FEEE881595E24CF48B441660D0B2E9D5B90928C381F2B0FA26342E4C9B88C0887A4687124C012D969E1AFD8532754BA12125E9433DCF6D7BC1A36A83E6A10BA1CB7652A81350899C2DFC6E4FED38D009E6D0F1D44CCCB95E551B3AD54B3AC81E8BA4665EA428B3C861E8677890CF5F625C19A7C5943A9401CB78E7026BAE92B60A8B6807C17745415CD8E030C64C56E822139A35DA423F264336E0AFDF167430DD36E0064B2F6E8D8BB6BE99C5A9FB551CC63E508DB636667DDA53F611F02FCD1F99410F1A7A82882F9623ADDC50EB01E1F39978BF68506C71DBBEE42E4A80069B0E4C7FC4CC1471F4F1028DB25C4687B60DF4255DEC9148197A74796EC760A66AFC7884038651920973A69C203516222632EC5875EA6D838096E7FE9B5B4FB69C5E9407E70D27FA34B0CDBD6E119D87CE38581DF1D3E0DF3AE029042A3B20E923EBCE19A4958755EE2F98FD234C4413E2DBC93559A428DC37F2D1235BD4419B099E0F0DE542C46935991BE0692A6D80B8FD9886E0FA1769B49E8AE6307CB0BC1B49732D26E25CA1CD9D407E0D8864040941611F9333B6367E8300FD646AC5A71AD913EEFD808D5CAFBF1521A3062EC184E52165501E005556DE4DEE46F9E53D7DEF9909F3D5D98CA80D87707F7BC0FF8D879D65D4D783D196F2460693811CDF33358E082D81F4DB8F6C20486183A36D4FBCC8A1C6DA21AA4DD136E19FEF2EA993972BB9989AC1C38A79F31852178004123C46277D38A88FC1589F257332284CD8A873C25A1A6D40265B285DF09370E88F72FF70E434E8F66084CCFEBDBBC4B99EDFBC750CC5DEA63617F647F5F021D57D64D5EFF048634DB2209D7C8B82FB63B8823E4CA057168BAE88D9715291240B3758D7684501F861867B7A241C063B05D5E8CA6B4C79CB2435D7F994CB76915B4A548708B11B29449685941D43E60A8976F9A96072F91041F4C3DF7C73969012AE1B30E4B9C4E133558DABC46C103C0CB1DFB99B585374A54F9BA56B7248B8C3F66F1D55760D6ABB430375774DFBA2059C5DDDB659FD2E1DA9C3F0B80868C92BCAC10403DCD140D6A3D3F35F8EF1A2DD98DE1A4334238599EDAD920DC0AA698E9FE6106A0780C9C245F2C65A0C3E5CD5366110B1760FCD414D450DB9D76A22A9EAEA0C9FB72ED543CE9FA3314BAB17687E9DE5ADAD7561F1A5BEC16339269A87E09ACB29E4C439605E9572AA9B7D0E8371A30E41A0A7BDC02DA3A6121BF261EAA016A2074E4432CF63AF96BE81CEB6E0C2676A8545C66D2F30C98B5424F0FEF04B3C6C7064E2D2E11CBE60F85723FFC0B770D6866FFA589E3F9B2ABF75104019AA69CB58895B474A0ADE2B60A4AB077C3A6DF615334EBBE732E95220213994D3BDC443C8EF94AD515F45418355183314485857AC12BA1D62CF4FD4F4DE2A7FFF1ECF0D290C4CDFFA88D8F48C5B837D3A94CD17B3D169966EB038FE5A6E85DFC60A00233F10731973DC475D53BC7B9E60320BA7905D88519FA325DF5AB02B40F2ABBDB37D2261CB8148277B87AE3297976C80C35134E5F786904564C1469947F620FE09FDF3862C4057A3BCEF70750CB727F031283A1826F1381B3348E3EA4688609ECB193AFAAEE1CD97E4DDAA02C0C30E49F137D08285941528101759A7422AA499C900A379DD73B307284CCDDAF1FA1B0C4B280E3F9F1DB6D38ECF8A841F9D4E40ECA86247D6CD9B31EACD6A46F0E333B9E83D690D7E13467619B46AF9AFCFDC4AA9A049B180260D70D9EEDB8A533051AB83517AADC2CD900B3EA51260F464AFC5D2DC411029779B21CE2CBD160218DF41F661DA1AD95AD40B8C353C7F10FC23F830D117BCAEF8CECEBCBFA49D79D8D9391E8D08281F000A55E92DB331BDECD73183E058FF3FE5839AF50D8C55F22F6AFF5A33DA774BA1B3E643F5877CF549C4F908EA64A37DF3BFA4CD5F70F8CD154476D34BC853C9E8F7979E5F4EBB888AF761", + "sk": "59B2371FE7BACC207FE1FEE88A8B3805A7052865691789BB90542FA47F7EF2B76EA27B03A86FCF8E129070FCD8B5A4674A7AE44692497E3E3732874E08F66EA283C547766DCD7B618D05F5E56D4C53C22E1604405BFAE54D3F0CAAE9F74AF58943160BFD8D16D0F8E20CC0C1A4455E0DF5CCDE4892A154C569E9C9CC44810FB5C3324848282DA4C2251B444160342A100040220649120986E204510AC929C904005BB285DC880891184D1A09048B30121C480D193388DA40290AB44D02C0644B488A020946824605E042080BC2305112691922429CA2255038868820464A026E994640512685E496305B082013288DE2C65114C36D24A8119436241A97291110619CC021D42222D908081431060A2006A3C4850201650B976CC4885000C32D60040902C490DA868980A460E0801101908D1017669842728BB24402A60900434A59046C4A003040A625924284182141D428815A06518312851C18098CA809013772992029C296494A480A80A22100A64588384D0813211CC95180A48154C00C1A448AE30820119925A40010E2C64151282014904C24034A88462590804518806902958989184420165144A43011C6805A0010D1928998B63109048A113165E4142E2423058B404E43C22400234E19332C041024CC184903446062802DA130101C49841A8084D83006A1062681224244B4301A265011496C2207284C042A10329108C86C239181510486DCA20812890C029785CBB49093468E213530A2128CCA20308B3221801468D20205D11280A2346E84920CD4448510912D041551D3004190A66464B08C0C15801207200AC304D0366E5A8681231682DAA02C4A0851C2362A64280A8C468EC1002900820C41266182180DE1424124952D102831D1A42911C06949104021336ACA444521370A11C39164120DCCB4649CA02C5AC0881028825A148219C868A1408D94904DC31408634051DAC82562026413318152126941B0084304208A12000CB6649A160C10B90100B78D1334826346429422258A40295A44450B368923404584240C11A6691AC229A21802C044414C9285000805233862CB3291E4446423194ED8A68C0C47210284415B406E0337715A865141A04D5346120C1425C1406410334810314C990051C13850184271A3A8319C86315B2040DCC46058062894847021962948B64580C4284B08862237529B488CD132092301241BC7091BA8008B424C144450A002420228060CB501241100C0B86DA4C2050C4392190966CB204D2322115B188C60A068D4C431990006804890D2B62D5C902003216ADB162DD8380640404A11A9680BB1015B0651910225983204D89625122925CAB6804C480601826C94A82D18A4001983101935610C158501832C4BB8618334618240459B46620CA84540B06510346C98346D13A24553468053B825122424E1C4481AB16883A04CCC14291A997111920811250501272A04986C91802120286A093648E084108AC6915384440BA87003434C11992D02C36D54B84023490400C748D1261161925111B7614AC20001434C8B1408E3200E4A10291C05719B202E43182ADCA28C24886099180E0C444D81324022386E22112CE1320D54A0205898441B3260CA2480589665938830E3B20D4A462D108068CC886D2120880C198E8428251BA32DE100221A176D9C824CD9088109C56D444862DB400898A0448A4272D4344E22332AE036611A810C91200454904C44026D48302252A60C84404242086122162A1A471251C0308C806918813111372410080EE30281032666101470D29228580209239210113289C0C85194242211260D63A28922376951140061A42048A22D0A28265AA801A4286620288A8AC8900C2024C1820C8C2441DB060D1B03805A326688244C91020A932648D90689D2402680A28424068CC1024823160A4226099B04669C228D0B446553246464009113198948122C11091200B7889816099C966194300DD216201A3062482249D9022C0CA241493425E4042D234346CC96510B3644E1B82D0117105A4800C3120C0130869C922D2294099210451B329153C2111CB33120474D849809C9881142A070619410CB14408C023261B668211182CC246CC03810C23862D12425493245A0B04C53C84C11111208352E51309124A30113C5411C930C8A386C4398640A460C52949112148A24804D5B300D1B260DA4840D303AD0DF21AE5B65EBEEC1655F182345D45DC837F4F00FBE89745E7CC7FAD39370D1FE8EAB00B966ED3F8285B1004DE2690C5C29F7DC8F354989E4E1B905280759F03460DDD395C2797399B1A752E7703C4FCFDB00AD935D6E6F903811C9E9CF1F6FAC75A947893D5F694C3E1D956B4DE18C77F53C98BBAAA9AEA36949CF09BCC484BE2BD1704856A056C87EF210627CF0FDDD95C4C59F57E59031905A90ADE4DA244B9853065CFFE3C79406471A413A78E2E9AE0D9367CFF5D0F9B2B724F41772A8D2F9AD3AE834CD069CFD208F0799AEEF7DA2A6E7CBDC3AD47BBFCC82C508CEF7F32AA856E545529EF977E6C52D2699176CAA2B3A5A4295F5456E4E279F19E87659F753F2EEA37D57222B2C082EBE1A822C387EED1A73FD0CEE31DAC551F83BB5A18EFAF5BFA97A9883644A8E811A2D7EDDE63FC16DE02F6231AE67D2369C341305E5281D36B48547BA92BFB6D2FB9287E311DF58F313BAA86F9E7CBCCC208EDCE5D5ACDB3BBC4AF7607AAF697F095D97F9655656A3A760758875DD013FD241FAAE8349AB8A3CC588228CB0C1965E3685A5F81242095FD8B5DF3EA16F86CD1760EC1A93A5E38D033D5C5D06B9F99F8436E74138ED4E265B88DEAD42B10BD120EBDF87FA1A01B027A84610F9BDC644760E9344BEFCF76827D58890685718CD407613C0AE540BA02D9E03688432200C920009B939311CBD16325EC0ABFC60FF567D59B20E2FFDB84259D7C53DCE77475E809E6CF70CE681F2485CC67C9F373D66279957616B2461BFB9BCA78055254C923E6D555C0A47D4A0AD35FC4159566CFDFBB067884E0A505E7E425D084339603E68925B7A1956E9B3A9988264EEA0CCA20B8E9F404F82DD65AACEBD6202572A9B3CB2BB0AD1282207AD5DF4ED63364974929D75BECF19DAE767041BBF1325889E45700306CD8A1F694AFCB77DE75D17562280AE06DAB6560DD17E9EC74C0AB48DC8368599305E856762C822EC0BC79844B182036BD65CB1BD5F612FDBA42D45C7A721ADBAE463A6B27413773CDB7DF6EE5EA901D5CF061DF0428320003813757C5E6C44F433136ABBBEA4555A4600CEFE45D4B2300C290F150288DB8A9AF87EDCDA4F6D9364306B64EA44467FCF9F5D574A73944BCEB06E318B0C79BAD4F1A7D060F7B5482158D49A73C9C0E20FCB2C6EAC18FE22C67976345F0EA1DE7DCE9573D51FF894B703B409C45B22B225CF9371BCD6B0B386B5B9D756C7731E178EB32F068C35571442A3046302A8685961AFE47B957BCF901A3686DAA130297CF9AAAEDF2265FBDF0D183BD419AFD428420BD1C8E8D21FD1323D48642B2666E2A4266417F5BC4D2730393D69911D748B2D8DE772C21586C4C0E942FB3BAAD097E9BC4FD38C95EBEC8D8907D47CD5E7F47AD5E0B5FE427FEF6E251367A790D3C3E09E2BB332F334EAF0940A59A9C6F52A92FC9C25F48B3D189F23E2C5174B1ECC90AA9F25930791E83461C349197F72EB2241F29C22EDB4995DDE6B849F8B294672D26B39ECED7FFA4A4F4F08FE789B2A89DAB808BA87F79B86DC9C937613A1A5C8AC911342E1AED13ADD930A469A01B6BC078E2A783A63D9D8CA38BBAB3BE6835C4ECD25D031B0AE71B4CA1AB6001F14AE7BE6D9A2CC935C19D513B33A51252ACF62DEA70325781F6C1D0E99ADC0EE0866D77249F671D6A98CA80DD0ECECDBF76FD01B42D32C21766BFCC6393FF88B1165AF83116DF5B0562D6461589BF9941B01526736CA75BB11181A3461C1AF3AD742F3F64B1BE655DD0C556CAC0CB459F2F17FCF1BC76B046195106B170AF0D6CB1ECD508570AF5BC8CA6D8411051FD13D01F53632D8393D21D1C7B06B4C2C9B862EB050890D9052E3F59294CCCFFDE5FAAAB8C53A2B4BB35187C402F7D60F78417ACB8CC89DCC15CEA2514A68B0AB57DFD9D51AEE33562E7BE76D155E55B2F263BEF66935B74BE28AB1BFE5D4CDB269BD45552B8C8B8DFDDEFBB00471B5FEDB6655EEF628F36FA32B9A95369844002919316A047295660A05A2B58305A474C86A2F0D7A5533EB139DB818B08961E59864FC4DD68FEEC1D88B8AA31DCC31B52B7E33A135CA30C18A2DB8760C628FC99900D1BE36CF21F7F7CC4ED3A5D73585CE97D9028ECAAE52F63896749A228ABCAFA6624665222F1BBA1538A839DB33717B3543ADF8108DCA296D66CEA06630DB0B77358B8A809228F8D9DD214E6FA65E38F9A330FA8023BD509DACE1FB99DA49CDF07A462A72D3B5C89E632B0F2D88FF81C71CEE084C21291642114CB05B6D90E07F8D6606D496ED74899D812517F51C506612DB09CC01E5B21360EC1A6212B65D75C071F7634D8E641C7AEC914E52979A293EDC56C5C10818AFF8748D0625C642240344E0DA90752BFDD1E1EBC9C41E6523215FFA1DB8EF2C60EF0305912B3C70C9294F02F0D8506B9D47BE1BE95CD965B842091EAFC159D04AF9BD06B8A63E87EC5F8F9689C2DB8B019D3BAB17EBFC35BD9E2A8E84353CF1506F52F20F9C340A793BE25FFE16D8762209F4AE1C86419D6EBD601633C0EEEA61822CA59A62E2C2B44751916B65C43625EB03BCF41FF887EFA5F77349CD289039D62CCF36D073D4AF58A109273E8421ADFCADA71D84CE653510795C83313CC82D04AAED74A54428EE53B777BFD44ADE392541398E40C94A5DAFBE65C78B7062ECCFCB7733CF99C567A154D819E57462BB30F8812D4486E8D70BBD5C06ABB4CFD721CE54107342B008CFFB8FCC0757B4066C8EC9E7E041B7C5D2375874EADD116F960A00A4EC283E67024206F4C325BF7551DD10CA437961BC573A63A4A922AACEFFCF3944FAA867163ADDB6AFF5DB82D0B262764C25CD84B47BB0D2336F1711DE1D0F695099578C8D46182F1880F495BB5447CA9F6A50134D96E5BEE01BCEFB0E66B5F2CF18257D0B30B315BDC6197DC9A53CEAAF26C02307DEDA02402D03C46F65A97CC753B86F8808E339DCAA939A111FE105E2B09625C222068B6ED675B1F8F719F571A787AF823D8B95ECF7B17C1BBAD30B626D80CAFF9A2B75A0F97F923E5042DD2D88F6EEA818DC350661743834288FC5C4D7A1DB51DDA87053429810E04DA1DF5126EFE6125B18F670DC6C0BF411834E4C284CD12F5AFC38100E60A26B7B5DE7D5AC974646BB1CBA6D17CC559E048E74C5BEFD4978EF7CA43294E270D2BA75213AA91D212B2EBA891AF78804B384A277BE6EF7F2F000E1414439652A14C89782419B1D4A30FDCB4D80A66AD16AAFEF3260E3F107A83A4C0AA9E5A43B90951A21043F19F8E2ADFC12C967A59DAC36F82C0ADEB0A438DF75A223BA905C1360FACCBA9149E1A9D0362D0098FC30C193CABFCEDB7FCDB0FCA67378349B32D8E6035D4FA532E7EC066200F4A8D071CD9EC30B25EE049DF928338161DD0BCCB52C45C6F6357267F392FC0BC8845E93B038C0DEBC9588CCA22B4D484C29595484A58B858D55B84502369F08B5BAE4D9B2F6B03BA2E58444EFD18E17F33BD56AD64ADD21F7D9238D3A6205C5BEC19AC57A263FCEA53CC6E750DD0FC24281BF392ECD9CD650947BE9CB3756D3DCCEC813E26E457A4A5533EE11D68B2137FB83132C88DC99E323754984F3516C2252EDAF2BE7F259D976B36094C1878F24F3706394A1A9658D7A7EB44D60C716D9FB7F4AEB4E0220446B673A9A4A6F4A11D43CF551A16B63564961EBD07E65F78B397B471B0E75233C8AB278D7B3FA7BBB5706595F3FE360E6EB385448FD92790CC06BAE5067FDE83C233BAAF97262EEDA4383EAD8079A3A6C05C162E18E98E7FABE182C2C1B3463A6677D056CD1A8C1563B4FA547447C8356B0FD00B776FEBC76EA81FE22EEB51C648A6E36B6D1C0560D9B2CA53739B18B93480CEF3D38B4999F83306F8A672026E2D18BDC6F84D18FCD9F4E0736562D763840D5DC76EF5E30B6291EB3FB89218A5E72A87472611BCB5F44EA4FDC76157E12763503E02CC0527DAB70FE1D183DE58B84197F4901B4930687506BA2900C51FD3F89810D3C0AA26D4518FF5DB44EC4D230572801696A4AEC116B81FC6F2ED93DAC6313D549E9AD7641E5B13A4B328866B51D51E9B54424670E494F585D77B78178262D5CD6F21332D908678211D6A81184EA689F2EC2F7981B650FDE5F2D8B1ABBFBF34E3D0B850DB2131D363883F7D02DEEA6A6FE32EE80A9F0D913F14607016467FADF9CD579CA154A455E0DF4E1923865CE7B139DF9D44EB3465BBA9AB678AC942FA7BB5D02FD53A52D5C44688F758CC1BF46AE3A43BCA881D60A1A1ED3BD02C4D1DE124EE1E24DD3E20BABBC9FF7DB0FDD6FA30C639E09F0779F7B4DDEE3D4AA70D1B30593782BFA5298A08D0EEEC899574AB2240C12A1F1A98343D6A705D10CDF376B6BBA4AB117B680D368B970183020C7B5A99097A16E9682DB66B3CF066C4145EAF6680AD9E0C138D14B8C6867872ADCD2EB4A7DB5F2ABF78F6DD8E54A9048564BE24C66F05644563D149548DE47B4E26A89A754D69FF2ADB7561B9FB8EC5A2286CC44C66779A33A9422E30DAB2BF5AEE80A5C1F6B940BFAEB072C3E252E16DA09199FAEEA472C29CBA4237899FF726275E59875C2C35DE4537A4D39EC1478E711D982DD76B7A5CF958EA98167CBCE8EAE1BED579977FC776873DFB0EF2ADDD1E496CA4F1D28B9453F19FA23BF30720DA7B14CCCB98BE19C35E415E44DAEEEDEE0C356B233FFEC7190E5B5A9ADEBE7DF1D29", + "tests": [ + { + "tcId": 31, + "testPassed": true, + "deferred": false, + "message": "4AC4675C96D9117D1EDEB80D7CD284A3E1E1FE038E301205B4C408EB965235AD1C85F8BE3F77CA486FD207F7C75F4121CD3CA2B23D6BCE4382A6D36121815025D5806CBEF452E083933C6E5C7394AC88262A6DE7770B2D8843EC101FFB5E84DE2F7A8B74E7674B3B2319BD6BF4112F92C5CFC0A55F7FA061F45325408D039D51", + "signature": "4B3F52F081B3D914BC7C6C073B182B268ADF5189E298A869BFB991B199993C1042DEF5B59270B6CD3FF8F907A1CB0D3B6FEDCA143838F8F81E0C370FFEEE6B25CD07035641A051944EAB516CFBB801536B4F262B16198E7DDB1D61C35A64D90D3948CEAAC8EE580DCEF540ED99D912BBA2BC4F5145BB949C73CCBD582613B10EAAE863ACA34683EB922B3DADFC74F76F47E4978602592402D9154394EB09FBC2EBCCC594732F2D8BC38350E5535A4412A77ADD7916604576FD6A3631E515BAF26A6F9CA4061EBBDD3BEC7179AD58552A5B508F31348A56AD1ADA7A05352C72C004B94C47E7049A10B3A59BF238A8DFC6C7019A17F05D5BFCB9D93D9D1CCBCB47F8C438098FDBDFE23F9F78BC28069908C6B9898B434CBF37787E1AF6A6B827E830E9F7629CD8F51070C4C8A8DEB260D07C3E41D8490484877491B39AA6D9E10D91748B64E33160629D8AE43EFD5F85781E69F76B6895C141EBCDDFEEB485A00BDBA4F7C991F53F2F84933926AF39E6964ABF2DFEBBC19A7E31C50797B8DA2931E10F3DAC493F198DFD785D21ADB2C062B097E889A20737F186008F2928F6B84D6E09E975A8F2AAADC785234234FDA03703A7C21F812D650BD2510B30F0550081047A155C848586A96F100D774F3E39E029B0777CD33E68318A11C1980293FAD3E787D20DFE7EEE7053C05EEB6A159BAAD4020B9EC3F537DA4DADAFB3B1BB1DBEB2D5B8F9D05A019798EAE0ED099DB066D73EE8E9A56DE368E878A7FF39140D8021D50085E6252941AB315309CB53AAA49E86347FBAD54A1F873E0CB4B86A8D5B1B2A95D485F37A9FB6105DF8440FDB8578F2624C079329569A75F36F2C55D8D030FBFEAA8889AD746C323B1AC4EC8C403E775A6FBE596E7E6A5A2863576625149940976F7CC93617B43FB13489074ECAC5BEB1A4DFE58B9AD2E0C6A15B76A7C2D208725A3123CA4E6F2C5847EE5FA8384919EF89011D219B257B3E4DC4F2095160844CAEEAFCF857260F1C63D3B05A67D3D0F2B0EC9DCC2723F13755750BAE62FCC361CFB584F774C09ADF9A0431B23E488C359C0AEF5B1C9787BD8F52B083BC9DBCC9B3039F777C7E8EABC80078050CE6D49C3BB70168FA2177298FB0A8F72C1CD28D662A07DAE6C7ACB7FB8E7FDD01DFB27C62EE683F4E5F88C7C1DDDD5EECC1C3AF853F1FF6B1D9DE672F1BF6473AF0021D8A3D4DD04A2FCA2325C721CF1C821676D0A0D574186625DE831C8411F64179F9167F78BCB22FB41C2CDB63C4DB5E138766D3803589598F114F41BA42CDB1341020449BA99656113990B4E022D8DA20D744491C6EEAB67B918E80FFF343CC5B4C8E58C3484B0125A60C36AEF763894D35148B578F417C3A98A143EDFE9F8C95BCC346C6F5EAF97AAD11DAE01C477C227A88D10ECFDCF450B37F881968027849D9B43E2BFF90C6A34AE41B8BBD743083D3C58786B036671CD6EED94DAE51F7613247EF8607ACF74A3CCE932F1C3869BDB35CA17FC6BA9F9C956FF1D4D88094325CABCE41233FB1D808EF41010396DEB0ECF50734D818DDAB70015A0ABDD1926DFA491F711AA85DA2A8EC60E3255CCF975C23CC4E8DAFDDED9FEC60A6467C45B03CA476499AA331B0E3999576CEC3191A9A62BC1BEAC1EAF20E18CFC3216127DE4AAE2E75201F9E427E39BF921150EAB949559C022D876FA242C2A845BCA7235F721B0056788A44ECC3EB98F0F502B89F8E7410EA5679AE7C0434F13AD816421D2FEE30CBCB2DAA6B851CD1B6E996DA7A757E4C4D8572C8B600DE85DDB65320D1CB71D9378349C0C401AD4F9E91272139228A8DA2F4FD2F48891A4DCB066D501D447483B611BB3C80550A90EA0B732D639D8B3926B6E7C35453ED3CC110BAF556CF46D8FC2177E76FB2663B8BDD171E94C0ACAF25B9153B22BCA749916756FB3ED3018E0944B6C3B9B6BFA15B9BE803AC79333CD2C3A27A26BC17CDA257798AE16B28B463B6DF3FA87C2D742D0F6885BEE0BEC6E20D01E5DADC86823E92D60FEC79B0D240248753E42048384C804289604821A57F4F9F50AE0C38527FE5A34938DDBCDCD9A1D020839BEBB62F9F41FBA08052ABB82FADA884CBE563791103AA585546EBFEB11272CC2E87A3B75B3C6BB1853AE7F9CF5585B2653CF5EEA244D204EB269C56A20985160659CB0725EE13CE35D55EB095A53414F232DF8108B18024EB0DBF345EB5CDAD0BCE7263509A341D54A7D534E553EAEFFE4E242EA23BCFE59A58A60425882CB7E3B0C9E4AFE8698E3DF56AFD6D611E9168747D8735CF9246D94F2126BE727FB42B2241A83B34F0B9EB47938D726502C54E4572766331628FA5CDA893C35376AB4538FF8717C2795B0F51F08E1137612B89B0C1E2CD1F099E88556923AE57A1DAD2AFB1230B5094A1B21BAD7DBBC333A97F179304718F3289B6DE31315B74C1A73AC7756FAA4D7EB568BBC6F7E788CD089B395564D2176B0056DFFE952C7748B048306720F602B67E8F6ADCC91F8E3AA4B8C4D7FAC233AAF93653AD2209E2FF92DA30C2D53FDEF6F4C90EAA0DE60D594ADA3915DB24279D867476EAD757B4C0264A1DB8A1F57A1B5D7173BB1A960CE02FDEFEF160D512667D655268FCC3A153A4314782A0EBFF84F65F14A0E3E12A13250C07D08C225B11A6831BC25C40467B768004DDE0E874A51144C18920BDF286090B59F51564EA4070FBBF61E3696435F28F63332B64496DF3EC8B65D54E1CF4789DDAB122DA6B264D312A711C129E3B07F4C6DA25A56173AF58B90A71B7ACFA3161A81F59D17914C99BBAC4F9A314977A89CEF7696943609BB4827964FB2976403BD4996F1E842BF5AAAE1ECCA11255B9E6001C20F72F1FD5E32CDA32D8A7AC5F62B09A0E615847CA746F489515CF8F183162859F53B97E9E5CA800EE624F729843A0009164A4A9FF76EB34E4704184848A139AD97D909F7A7ED114F087A4B2E1B4A3032391160B6F3A3649FF15AEA2B7107AF8A3B5FCAD61D43D602E6286A900870CC8CE24E39E78F0397A0D7E27E8E2D4776A44CBA218EBCD88B3C28C182A7C9F4DBB2DBB5E981563D66CEEB77E7F9034BD429D27637CF797DE82E01FEBBCE2171EFD016E402A42D78EA1ACE2CB370E75C90ADFA1A793B2169CC26522DB2F546AC1DE34C9087120C42A9F10C00D493C25730166F9D219FBDAD222C8B28115543313210848FB2F04BFDCE15D320C3634A8E4D63755515900C75BFD090AD78DD588659FBF97C96E0D0ACC8E815E608F9E861D79AF3051B942B52570B6292BF48C2BFAA9077DC76FE902683217B8BF809ED7A0050ADDBB65FDDFBD24019C9181B5AC81566113D6694EA6291D7F4A7F56A41EB91F76368DF82B164B4859259D7189240F1D8803F8107296D378BAB4D24FE6D10EF788367BCE16C5AB77FBC168B857F7BA5CDCBE5067C864F879809FE5217DEF0294BFAFDF809ABCE9532DD9DAB3448F4DA68ECA51609476278EB8C4F69EA29673F69418041D26857EBC24A487BB4B0BA63AF848545EE9BE89F139D502099B9D35DB3807B925CBA576E27170EAEC48CC2CC15B043677825D0EE81EB2CEE3A8ED14A798B879530220E50CE8C003A305382A24D23C277B99D1F4C54F9A8D33FA3D1E337E18D7CBBA5E5A47F2D5E096CF4551B23B1B86436E81B4A09D1E3D38492EC8B2A00967016AB76B9A9B1864671421DA56F57D008D5CE1B892A7E9C1F69F6C722CF109DB500E53F6BC07837AD1CD4CF4A64DA763B4A9C4929B0DCDDF7C7E1186BE3FF0C321158437820C81E74FF316AE3254E972FC197A7F0E620242AC05A4E43E987C2A8355B0357745CA79E6AE48AB29ED4FA63D3A1F19B999DE251FDE0640DD87876D55762878AD1DB12D65BAFD14B6A9A7081BF23F9F06D90CE273C5A26E012CA94DD481D32E10938C165163E89BE8A93A63034D345B74E2A94EF643D06AF9E1F5C9F104930DA00E61E061EE8C3BB17C11E05D45C1682E4D593C9198238D2BA289779E7D0F227BCB0B09972B19770FF011BF6C60D9D193CFAB32747A0095E1A4AD32514C782EF3DE7A26EA771F5530D9DE9736D0F6AE1AFB78EC7CE4884A1BB436CFCE459CD99358260906AAC99716A536CC7687A0375FDA11007618E553534E54D5B214F7AA6FC7DBE37C2BD2B64850AE469A9858987F3FA4B1FD26D954BFEC365DBE06DDCD615E1FED58A88676402D1D6B581485498B5ADFFFC42D47D61DF99384E22C5157F0178A6FDAF8F4A9491DAF298B2C3EC88085022C0A7CF245ED0FB5A38CD16F30D37DA5C4959A55501DAD50F1B48BBBDD86AB8BB522A936DDF0003B81BE16231A04E7A589C56FFFB51B07927B4AFA1DB7D48BC6FBC3F3675637184B7ADB9BADF4DE7C085BCA1D428DC9FC8277CBD85884A5921B52BB05B710615508261BB4546BD6E1FC730D16B049EA12798CE2E6DF43F5B8F3EF9AC8FBAE31B011E10C4FC62FFD7F39D16EC32CA8210ED16E041DA43D9274229514054A0F82D462FE080C6FFD7BBDBFBF0BFFC6D5ECC432A3256C0BE0DDFD5D9080C676C7955D66E44D1CE51FCC2382F868D732E85851721B48A01D08C639626EE0509CB581EFF5628FA6CCD1089AC0E12DEBE0851782E64C5049CBD6501013965CC0CA25ACAB176EF7CAB92940985DDB49021DF6C60D6C4A489116311E86BA19EDF00D74797358207CDE50506D007FE03C8804C66451F02A0182D387B759894096F65232952D183DBAAABB6BC0E191DC2C3F75FC72BD61BAB2EF19B6532B231C4AFB1A9C2CB2F3D6C451E8440D6A923CF72A63E2ED8554773887910CA5C671AD4FD5923CB95EC73FFDFBDA4B6655F55DBFD1317D024422301ED66A6E4C672085CED1F4C7B05030A100C4788FEF4CD3E494A853BDE63E9D449AE3BB6BA1083238DA3F4090515D143C67DBE53D8D507A5229FFEB2072D0BD092FC9AE52DEAAACD1F0F14B5AC84752BFD0025E5F55B869350F4B2719C5C05AC1669BB0FD3C614ACE02A270613FD3309706DDCD5B1A6AD26F359ADA80B30E50A7E50BBD3AA45D0654DD7D058B0BBF4D0D92135142214EE70511F3676AE643B5F245063B9419CF6B49FD647F27D7C41C866E6CAD9D5E2E3E331BF6B9F72ACA329BB64259C3E79783A26674B7D38EBDE8318411F4764EBDC4C7E41ACFF85BBB30318D59C42C9203ABD6636BA3F772B6725121C052DE99910D55158C6F3EF8BB7FEDE2F81E58A7AEB25E2E46FD7232302FAFA8FC37FC8B55D594B76EC4A53EB11EB3FD634428AAA5D86F839D089ABE2FEFE2AE5262FEFC7348D836692EDB215D6F8F548B885290C2403C51C3E269D493FBD339B5DFB0A38EEDA7754DAFFA16E5BCA5A9BBDE04B014B7AEA8988F3749D52D2FC1C9F7C7B2C2D692E7896E4C34F57C558CFE8317A8374409D566879A08628F644FB45B818455BCA6042B4E6187C1DD177E9E5146319904B1505F3EE00CD7FEAF0E83C3024956F77659ACC56D8D917A37E8FF7EB88713CCA334EA04B8E258C9345DA9DE26A0A366519451E1012DE6AABF4697C9DE821D70021C3250A106CF4C23A1B1785F549D3C8CD71B05FEA753E0046A3AE0A9B1F40277CF453A2BA14CBA923CC6269706DFFFD517C1E5930079912E05A5571897A06865516C86699F707E00CB38CE193490AEE30BA47DDDF3A5B4FBCEBA73DC13D0A160EA642D30D63A02964EDFDB2F29DCD32CA9974F89C32D1FA9A83C94A2770FCFCF86E64646882BD550DDD65B4E2D287AF6C196F42DBD39B020D7CDFBB6E6E75FFAAB26099EC1D25E3234F70DD972286AEA0C3436595FE49FCA898BFA421604C82D3E94856D186905076D186C684174BF4290DF31769EDC97A1DF2DFED03CF45CE678C8A1429EB978D02A79D4F8CF0168DAAB482C6C612F04B1C93637FE77B302CEFA788C11356C52C54F37A9DCFDA55927A8EF0A0CEA7CC4ADCEE459EB64DF08ED0FC29FDC3C7B762B399332063340D473966219BFC87B4A3C91C80F0E4BA86AA1879C76625C8680A227AB22780659D4B5D30E0E9A0DCE094DAF537679273A9B277ED2A2E250EEA0938204C9E963D338522A3D1A4440E2A12397A5B97D35657307BEC94CC0C72C5C6B09DAF2BAF0020B7D8CA560BF6596929AC8D4E5460F7837B41B4AE6FF12339DB8EBD7028AACFE0B42E02CDE906783ABFF694E7CBE0897ED6ED438ACDB00A4709CFEF7150EBEB08C8FF6C1543815F4B8951C3CACE499586458A73C8572389AFC9703A7FEAF673445FB4B0CCAA511D4A2CF463F57E3A6D72DA04B256699A30212E7C5768EFC151B71744156575A2E9443319232D159C6CC006FDB57C58173AD8D2C866C8887437C223888E21EF67E1A332C1FDFCC15EF17476FE0FB57D4229894725E1474C1BA1216562817F16C53ECE01C7F9E3664EEDBBA94952987431AA2A57D330EB11B28E6BF770E349ECE350C83E90DA6FE0D0A4AB9715DB28BDD397FAFA1428302151E1F222B4469879EB5D0F018606A7594BFC82C394E91B9264495C9063D505262799B9FCBE6316BBCC8D8093053636A74D4FA000000000000000000000000000000000000000000020F161B1F292E36", + "reason": "no modification" + }, + { + "tcId": 32, + "testPassed": false, + "deferred": false, + "message": "5BD074132560F373C7BA6DF8B31012982EE35DAEF19705A0B46B3C34D474DCCC8B0888E5C2F045BA71D6B6A08C31CA63B9576BCF10B43BE4B536036A1B654A7E5AF9297E74CBF099B26D632D7BBAD7B8D657991EF336C6B486FCB0B28AF828D403315B63E9A0BA52755E06D669C2E066E98E6343394DB0B55C121F2E1D66F8B8", + "signature": "CB2F66EFAAFB006C0D60A81B32461B76A31C3A814513444B3312469427395E0B530C67D9CC5D2552AA544C4E2A6E132CA55E187642DD9FC08977FAA7012349E23E537418A90691957B03E8FD435D670F8AC671C0CBBE3ABF6EC28BCD3D66362EC8A13402BD18C7D782C96901EA26235A34EACB04D2949072430B0DE3256B3ED27630EFA915FD1302E1ACEA762B52330E7ACB34F306DF3DE26C98559E362E930E89919D1C2641BD37542C035A7EF25F6B8C29044667ED394F0E3F830876DDC296C880FEBEB30D87876911B1F4FA582D191FC7C274F52C5E53E0DF6F0A5C2C3B6D781E222B72C0A41C5A40F48986EA28A6296BDCFC48FE8FF0A557284A4CB4968059F44DA7FB77A7A5DB8684D6151EE35BF1BC7958C086A1E5C907C64469AF213C3E7866D404508F723787F6A1072914F66279376FBECDC853906E8E806B3D07F06E6355D5F97191E4C55C55AD78273F10650E7018A989542D68EE8073501D331C7B9D80049C94B3F8CF6F0D7E569C53EB76A4861B94DB95AAB1C09BAEE0B998012E72DF702176CE9578F1995B64A4B17FA95DE9EE4AF0C012EA0445D065B87E49DD2C36186630585A414BE4780007866FC3512A8CE80AD1529BE7837D2AD5E0274DFB9ECB0B92F9848FC41695DD25D05C31E3C4A44C75327032065A005A4F2349CA9319A03705FD802BC73D12987095693A60F920103A248340C75F38EDB9068668795C9166351F045CE8560007985F140218B865478DF7A53D57F0802D48C28DF1122FE9A7EBF0D449B361ECEFD2637ED5D7627B184C73C39510F15CCDC35132CD6D5EEF4FE10CA6FF0FCE8BB70FB974D6D6B21CBCB6A972A070AA8DE01D6CA0AE3D937D0FBEA3148DB2695D2B8A14B1533F7A303032A35C71772A272A8786805C3380C4F49C9B5D6136075676F806D4DC83D3164E1E7723DC4F2EF20467DEA7CC1FFF6AC64C9AD71865B63797AE1D6A27E6E2FE2863050271A7A42E77C5A1E3A4C15F2EB8954BC1C6C4A969B997098A8082327E9747FBA569C81201F54C0240EABB105048ED6CF54AC99687B1539466DB4B1DAB99F41738EAE4CC5FEA8E7BC89CC3F9C8A19274E038542182E9D7E0FE0B89514A3B451101039DD65C552A75970A8BE70BEC1B51BF290C2CAD36F94D1569ED58A0E0D9C9D0A722CA8CD5FD73600A219BD20AA4215E914B7D9484DA8482BBCD7961986C211567FA7CEC033C44BAD8E3B2CDA9BF5EF4067BD196D077E9B7200FA54EFD99ABADC8A75F0F49E6E5AF498E7EBD25168193B088DF78C90318970C78748A1AC611760F90C85D190984B29EBE1C50075C3A9BC8C78584EC751BD28AF8C1FC270658DD975F32FFA4AEF96940F7FE4E4664B39CAD9BC72D6F51ABC37A93AFBF5A0238700A0638DBD158153215F5A8F79782803BF9932C70F4F0D51CC71AD32E90B98FD8134939961874884A6C0D372B8F67DB7D9D65789171AB096DF44AF7CB6375D4810B404B5F19E181EEE008043C4E87383055EB6D822B570191FC80B616A52E64640769685266EEF6EB7DEFAC733237DFA83864908D4231CCA0CA7F4C82BDB263B640ED78B7932542B2C1B0D73230B17381B9972F7F999131BA94E44238A2DA2FF4878D306E4AF5E0541435DC6C3C621EB5167FC7EF7FB73E6FCAAEF3B9B595D74F390E5D578BDADC44194E86FB8F39FA546FFB7CC51DBED456E1060BBE5564F5175CEEE910727936AA7A843DE98F7FC36BB1242DA716247227305AFF1A234F267CF09469D5C4EFF8326F0950AB60E57BB8D2BD1EF9782DED7254E291FB4945BF4A5F74AD881028FEAEEAB4841C2E036BCA94B125708B26D50096B0B8A9F08645A25C0CEB634D301972B4B6111AFFE0F3EF5773513ED97468E1CC1ACFE2656E5A4AEBBECFA6D74DA692ADD3289D227E4DC420B4EA3E768CADBF0389F1AF967BE317FEE9874B4406FAD1F0AB9C37E54EB48502F14827B308B146E889EDDD26731571CBEE367403B1EEAB26F0BCE876502852FA3EF2D1C383C322641C51A3BCCB6C706D7CB43DBE3109C569C4F8AC26E75EE844EFA4AF8E2CED85E1875F0B93D17170029C408F65BDB96F5517DF6283A24B19074767A46C0EE54E993048B73D887939A6D956F7B47208BD1963AA580D7932D0845220F59F3F2D57A227EB57AD0D302964E6ADC7461DBED7868C79F0562E0207F542F8B04AD35FF3E3DFE590F8DB991BFC54D7A80CA74985628DC5AE3C75875A34556A9B5B058D433956B0E10607161F0C3ADF653BEB8E694C2E30326D1199B6E68DDF987F9CC4B4F4472C23A7FF546CBF2A22F69C2575566FB57F31719675294B9D5AA9477953D959FF3D538C3EF619E12DD6668156EE016F595F8F675D2A509D73829B24C3856ACE4690C27F804E454BB2F776309CB8B784C5FE3A2C58111D33502BBACE754EB9DDD9C65D29011FC9D601D749B9390F21E5E4BA87037429A3A3CE2E8BE753A40818F3B9B0904408E1157D55A7A3A72857D9D20883FDCAEA9ABFBABE604B8AB95C6A2F4BC90B2E355F9FF5BB02D9516B68D3932F13F759535F59602F2AFD8CE288395E6A5633C9BEF5EA6F88C705C0DF1AD505799085F04B5543D44931D89443789E6C94CD6A325A716BE0BA14A411F0EDD881953388951B8FE937B577A0ED31BB09882DC153AC2C5F9D070874A984CF02D2EC062B6550585B1797B0F62F0D1AFCBA76DE932D8DF2D549FEC75533BBFC60AD7B1DAA59351790107325C3D146A766DF7C8C6377E6F9BAC28736ECCE30663CA37D144ABEBF36E9A6BD7FCD9F4DC3DF055C78F8852316D72AA056922AF21C2DCD7FDAEE0CD8AD3415FA3FED92D8F5697DFAB9FAE2B32FA800E04C7CF6109B4A8C682F5B11B14BDFBD1B96C1C78C36A3F1BB4DB3DA0CE940C917D6A61C2B9FC96546BF6E0D697DDAE3FC38E683CF29ACCB431453129273A1923AA9C70EB0A0DACADD0307C6990FDA42DF9326503C4A6FE72D7F2D81A0797DB6B2399EBC289DC4E3DFB1BA181708528519B378D67CC075D47C3094303267B9AAAFB487E2E93CFCC9D20CD2B0DBD6E29A020337D4D3976E07289CE76185F5448FCFDDF7986CF3ABDA625D0A5A0E0CF6ED779F78F93BE57CF1483D975428DA71BEEAC5D9F02CE9517FA842E9546FB2AD94EEC611CD89686007FDA46A63A5FAC8DCAEC36B569469519FD5951477CC923C29E3B540CB1E19D90BD42EE24F998C0B793C7BA4F31B2DB4135D11E8396E5EC727F57C0C905D6EB4EDFE9BCDC3E671A0AD7ECCC136D3A11CF19B7B3CE54D33AB535E2F99DA800677475C20702963A2546EA43B3E6793EBD9EE59146736946954B5C7A19DB21A0B6880625A540B74E4ABA0C34C12E151B40A2B53F548CBFA101C2F05093BF75246DA04326EA88A282EACC75C5164CD7275AD784F2D6FF37FAC83A7C1C9627DA7F52B407DBBB1F6058C40A20A7377E30CF31C69391EF831FDBA2C09AF1FAA9A97020D0CFCB9B87768D2D0A022F7693B2C6D436FB56809435B576CE887B7233181451C0F76124B84D97DF996D331DC77DED47C63970D852095056BEE43810778C95B96849D4FAEAA090B851D9BD6290703FD7BBE957746B7339B52D4437B9421DD3776B2E6A712BC3301E68FD0C3A2DA9261CC2632C89C9D8564A25D38ABA51D571BE57C53685816536C5038159198DF90E2B4AF9E93CAE5BA948165A46279F1835AF6AD7407DA77AE06645A3711D262B3D37DD8A9D6F419F0A74841C54785AD2F76BDC98B0BDB2CF287BFDEAA9086C459192BCE4D34FD118FE4ED082AD98F67F96798945EE37A2B0CDD0F99A4C92E42851D3D12A496898869D531DBE39097CCFC0A4C232573C9F3646AB622C5968DCFBD149C7EFDF34924C709886A4304C266F4E940E0A7E046DC4E402E80DB82A874E7A5107F3FC9F5D7AD452BAE62A829A4D3B0EB35F81274949C57F9077488CEA9107CA2DFCBCDF020B8101591F4F1B67B3FA981D0821A47673C4F8C2D92A5E1BD2BF46868E1913FF637DF2A00B770D1BAAAAE0D52C3DB5039AF27FEE018BDC96143073157A08A0734477375B7C6BC7465110D4FEA768EBB37761E35E0D9ABF88689F615C147A7BBA2B29F135B13E879DB6921FD041F185AE7997644F46F185C4501963522DB385115E817ADB3FE9FF7B8FEC793B805CF73937F1913031F0C2EA2E5261C7DC13940158F57ACAF3391EBB5912F29F8654F09D10C76ADB04E7EC4AF18B5E5180DE73304E6074B5A7BC3BC6C97C1C7F2123272C0038CFB1EB355674A14C3C5DE5990592DE1D4A86B1BF683B1884D69E741EA9F394D3027004E5A7E2AC7E703FCAED452F78E215AC665142E5B3B5A4D7EEB4B5B08B50857E85385D2E19DCB5A29C16E32DFCB75EF4AA77AE5DB84E5A5F861AC1629C97E4403F4CA948AABCB0FBA0E9F3AF1BADEFBD04DE312018AE989072CB743F353502CE4DDC7665B193177DFB01FD93076641D037AC8316803B9681AFCA01002B0B6A8B3886F959BB71D9912BAF99152118B2A83F214B68ECFB6B836BF0F44C8BF2A8CE7CD81477BC752BF2EDF295FA51C46D1B528D69555FF46CFD0BCC0348BD1799146764CFB0C851BFFBDFE200A0C0B077AAF057C6E483667396F3B7689193F211081E069DDA669A4BEF6D63DAD5D7D23AB6A976AAD27DA67C2ACB9384F1BB9CE1B02E55B1CAC61D6BE4C279F87628CAE6C8FD584893A875E1B1ACF3255437404E30E96376CD091C18E3D4268422852C0A038F1ABC37FD032E27746BF00C4358FEE868A5ACA9D74520955C10CF36258F6162E595A70D3E5D68E4A2BEF6BEED7E04F85411373937500DDBCF88CA8B384199F5E693BD69C0EB9D74674C35EF3D821096B872D0E091B5B4F13115445D286271B20EE2CFD6D2FA21EB45CA8507A71FE7B9D8E481C27D73A927AF82287AB82221B9FFC7139590C55BBD37494B3446229F233FDF74B9396DD89E2AB36ACDFF9A29A1BDB9ABEC9F9912CAEE27EC98F1CA99ED53434F180FF77E8EA9F9FB915227A706FE9CF012D6246F8A44D94A4F54C702B14938FF7E6870D49EB7D7EDA2957E4D0BA4FD1AD6EB645DC0EA96120C4A3C11E469B3189F939F39D9EE8B0B84D10532D1BB0CE358AE06DE63F880A338E9563558B4CF8643058A4D98DC1D508E9BB5338C7A5872BF3BA6F832248E58C3C76CAE350F33D0392BD365CDCA382B044A1711E9A3E2BE45B3662FE0D0E3D5DC18EA4F3FA02DC40B61A7EB1B13E49AAF38426ED5ADDBF693E046DF73A4F0B2E351A67B335CA63B850BAEDB4ACB369104BEFB192A3B5E29A4D7ABD2E27EC436C11C8305E370BB49649B66B7BC20A9C8C8EFB0B6276B7D2E46BE86AFA936C98B10D7B34CE3C025B7B6AADAEFCE6D1084E9266882B40F035D147DF5B169DADFDA674607E91DA77EB639C0C3A6149E0E57E3478CD79DA24FDB42F3C0295E8745A2CFD84DF6E886428001331AB711954B5ADC1FB3F3EA9D00BD8301B2D030A372981EFB155DA2172993FC8C884A2A1B43EFA3884E142CD191EBE56519E0D79FD5417D8ADA61BF7D24C1C12DB5BFEDAE5DC1B14E869C7106E4812B7ECA27C845B4035FEC5487507EC61EC899C010D067A41BFBD9C3182E76C79B2492BF6AF4D78AD413D672236432E243DD87BA8BA26C369D5AACFFE7DA458865A8F596FD24E740063F57E1C5771A648E8BFFA222C33BF137D21B967D69316B3426E4E358A08294E7F13FD129C09A8E424E6B4A0A2E39930CFB5E201802DB7134D0E005808B3BA43ECB843744EACC004CE159456DBC3470142C103B65B0F7F7CED63E662EEF1F7493E65B950C0080ECBDAA56E209CDCA1838FEA248BF98945EC17E3190624F27C5252C05F9DDEC36EC7C013C99C996A68DE737A9E06EA1F263EA3D1EE8F4B959F44C2B74C67BD70A3027E6E5EEA6B4C8027552F29709CE9FE5C9F26964D0DBDFA765261C9A29CABC89F8CDF712679DBC1DD80A4F676EF5B77B219A3E5DD7C9E55EB014002CBA4A66EBFF0467BBA2A7AD6CF696AD8358C0B819FAF7E7A18E896E6777BA299A8C3B20F20D7AAB99C2F524408B6A4264B2062D7C7E6A0DB8DBDD9C0446A4188FBFDB6ED002B2807F0997A68A2BCFF67A49BFD008FD6AA129053CE16907D8AED2896315ABB3683C7D0D8C846658EEF4719E3D763255F3FFAB2602C91CEEE93B698F738FBE3EAE3FF48CB0D48910F503CEF3FC054C006EC9181F0A6942716EB982565B79C9BB03AA05005DEC009C234A69D1F441B63FC803B59E9FC4AC22D93EC01685397F7C4BB6FCAEF590F272DD1B85915065B4E2C6103296D1EA056D843DB35387F3AC32CF2DDEA7710936A692A78095CD01D0CD5C8F0C1FACA6B7495FD1976BCBC5A03AC39F326B4F2877BD47A8AF5A35B1C256196C9C1F7D39C24624CAE958F38ED815B5E1D2979B900A453131DAC0D6C2262D33026A6F9F047DCB0AE1C4A394EDD0C5D899B03DD4D5875768D010D1640418D96ADC7CCD4233741515662646678C8D0EBEF094669878889C1D5151718275E9FBABDC02F3F5B617094AEC716182D3D4E5B82A2D3D7E6EDF123415B98B1E9EA0005101D252E36434A", + "reason": "modify message" + }, + { + "tcId": 33, + "testPassed": false, + "deferred": false, + "message": "FA8898A19236FEB6DF01469674F014833F997380A917DC1C6E03E5A1EC1289658134E16DC7CBFD745A08AE0563D530DB01B097FA23C922DBF5606D90AB58BE8D06A96CA5CB1533D6939749CCF2D17CDB9391FAAAA0900FEDDAAC82FBA2910BA4D4A1D7E0B1C46CFB5A388A33B7FD87785B1022B7FC922FDE891E6A37108E0E1E", + "signature": "2B0316A1A52484BED62083ADA27B204106F7B0E5717621088E95E2CEFFC2C83D91BF58ABE06B2F1D6CCB15536A49CEB8C1E611BC67DC1AFE04859CF3A714EB8DD6A9DB990A52E0C85F45602A7532EF160477BDC949F303FEC13D400447F6B2EFA9145423153D256F9265F9A2148066C3FFC8E028CC28A10F80EC6CEE2A41C5A0A68617F8017A373CD45249BBAD796032071C12802705B69A9933CFDF03B41FA973497E50B65CEC5258009C6D175ED9D892725532568C2D3CA4629301D718DF3F06057D90EE59F7FB17532BF7CA8FC7F2A9B570C2538384F0D9466878889E53D2BDB9DAC3FCD7F944E7FE0F2C098166D3F7D0AB82A670EE15649784C1E91F049EBDF01A9CB236F62BE5A3EFF8C98CBB4C22ABB80EEFB7721BE350497F199BE9DDF7A9473D79E8B9990ABB9778E13DD1EE2BC77B0CD8DFAC9D43B29103CC111F4BF00198BF755C96FCCA91A97B8CC548800EC14D4FB55AA816FE5244B0C2AAB4618EDCB2DB78B2B94A7CBA1E0919282E467328BED6FD2603ADA2B8ECEC7295055D68599AFC01B00AA17F03D85ED47783FDE403368985C919DDF4D4A32F83DD1A1A18F72A364E2B9ECD949173D05117C1B77D79AFDCE6696A903C161329BBC75E353EAAFCAC98BF9323D5944E22E8B2610EB65E18CA86A75CC5AF5B4E499AE5DAEB82BDBBFEB219AA245FBA3593CA62817D3BB254086353E3C8CF1563B9A2F4F038ACCB11460EAAAB8785FFE3EE2EAE9CDEF5922E3EF7493307E1F7EAA3E9D535E7CFA480AC009E4F8C3FA64B985DB9148246E709531859E8994C4797753C5E3A572FDB73784170EF3CC7643281B2742D3D66726265B1D54717527DC542315F57D68394EB0EA1922C9EBFD58E2D61982B6645B79F446C5C1389DD4852EC268B58C2A8B12E644FC4F504E06D6FBF74969600D55598E9046F3FC227E91AA8F03ED29A8276DD55C60617B0AF63AB1FB7EB8EB3DA92C603C10E2C1E6C5412AB9CD480162322C74FFE3DDFE3D7F8D26277C88E47CA2952C8743D198DEAE2E25458CEF20AD16E1AB346626A9A5DD8371B9CF46F45DF1021289BAE310B71B3F8671490FC79EEEADDCF190700140569281F89BE21D0649417EF414DB22CA11B61CC54761A8814D722489883EC63ACEF8B2F780A36689FA8694807CE9685224557583EA556086B6D2944E20ED98C67E30DA8741FCC4EC6EBE67748F7F324A8460B7E65BB9958103688584DC9662FB348D17A7F5AEA853E2B5EB921283FA40626C67ABDC74457892B13A34EB8903EE47C49943CC9ECC002A65D8E91E9CA799E799B7ACEE576989D627042722465CCEAAFD6A10CC64DC91EBDB932F21C76932D5487EAF2AFB637DA0D66A7D5AD87A4AC4DFD430E7FF251E3AC9D5F87DAE67D23D93DB777E03658A267E838CD5E6377DB8FC6D2FBC0208470334B18D071CEA90C2CB75FABE46F4923F4B9BEDC32C6661BBB72B7A1501E54C17E44AEBCB6B5C89C3BC7A939986EFA1660277570781F2EEECA7C011102FF10FC3EF87312C89E879FBD380FB42DA15C989FCD7420E047840AC1F962E8A16125702598B36C4ACFBE43698E596575F4DF5A694F11CEABACE90B2E25D05740782EED193E660B2BE926F469E9D7BC73136704E133E69338528B52782FB820946FA3CAEC5C695053BAA341AF58F4F9C76A13FA7C7DDBAE9F9D1EA34AA374DCEEC010EC3C0A67F383EB2758F2974C54BB94B1A9A4F8D18C959B02EA03534CD473DA2CDB5D1A73EA507E6EA85A013942047DD8DB96AEC221130DA52E1BBE8BC62C5A726845E46BDF7D4FE685820D4712528BA4442512A7927503ED61BA21546C24D4DEB73F6FA2DF108988F73C62644FD0EF8DF5CD9CE9A94E019174429BC32A0AD3D0F9B46FC07AC4D674D758585B31E1697658E55AC6113C23674B7B5C28B3CAF3FE20CEB0B6EF8209A35E88C22683055D974C2508B42D1171053842E8911882B0CB1828449B691D48363C221EC4371F9E7045FC376208358368FE803C7B10EFB3CED14957BD6048585BE2D4D3158AE3249120F8F0F984C317E2F76185E71515A7958EC162A07D9EE3805A186CB3DBDA4FDC27E70A9360019B6A5E2E492A8ED2B3736F7F0601FDAA1FA00D91AEE2E6750240176044194AF9C2D2BBBA8DE2EC119324BB41B2DA37E91EC4A772079C9DFE91DE77A6BF7822454C63FEF6586B8ABED3B6B8EF74D01AFDFE12CABB27CA898EE3758F429EFB2E6037BB08CDC19F9870347B246CBDB960770CA1AC9F6326644CA4BD263B85D580B7E709C789A0E96377FF53E94866F59728116CC11DEEBA5B8BB3B23FABC13BDAF3439340D6E5410DAF61F091B7BF37F2ECFB381F1AA0C059BC5CF4119E6EA004136E5657CF4E6A0F35C27D5EFFBF3AA59AB62BC4D75F0EBE0EFA2485B4BD61D83C2BD4FD2D52B0253673FB971C3674B94331216B5C69DB6C256B4F5073D4CB337E76225B26F4E13E70606177244644F18F8C8C0D80A64801F4A52989094A5D5A658AAD70CA0CD71239AC55C75BF8522E0FC36C572439F6C62FC0C56861F966FC9CD55A75E55DB5B968DE2A1D5F4832C601D4AA438714D3A9D7549E854A1A8360B8A7E0E9FAA042883DFDBF8517DD90D7D68E1A18B5AC9569848C69DD5A9E9B117154440CCCE5D6674AF8A2DB3FFFC651F766CB54BB2FBC1D3738401CD826991AA1F5EB0C0803BA752B37548864BC2D90AB0B7C8928BB46B88181697AD0D24A0B0D58341C9C6D77D76094B07366429E8073BF676918E5B0188A28C5355355DF7D762B9069F4D65466704DF3BB1C130D4C9DCFC141C29267346387855DF49E1795BE70BCC3D3142AA11B99AEE4E1B71550281351FDB294D9C13B075941EEDD128448FCDD246656A03C7F8E54118417656D19910C75DF7F96012F0DF7EFB2094AE54165EF8350721ED25E54C2B85659D72646D07F3D50939CF68DA2C85C1C45F36BA35A70CC5F767C67FF8BA5EDE72A8E2664E06EA90FA5D964ED2B3DED93A7F005F930ECA1514D4231D057278BDD1868613FF69D0B3614F94E73F93EC4DA38255357C6A37A5B9BA515F3DF427466FDD40E3B203C66287A26605182E44BE3703AA5B09105CE43DB73D75FFB35ED95205FD03107F5DEAB124EE6F40A1EBDA6C8E78C814FB18FF5C7917F0ED173326F0A75B00A2F001A7607D661019F7910E928D8D2A5EB8BB099F5D3BC09BBDBFE3339FB59678A6AB56D8A5C7AEEA30F08CE081A2BA3B0EE91D3A7CE1133C7552EF3B31C828CCE11D5E85D136CB6CCC4015AAEDF2112DF3C8913EF467F658FBF2820703AD702752AE1908366ABC429720080B53C4D8C0974D0C4DEE2F82CA85D4C3CD4F81232756853F5D441C8D66FA0A07519689DCB52DE3558E1E974D59FF93DC9431EC58B22023B010B1719C4DA8D60E620E979B4D37CE3FD9232261A9ABBD1B9EB651C40AC920E30792D1CCD51C848363995D4D13567F38F4C194EF00394B387D87572650BAB9591433E4C17E98B95AD927A124827195DDF3BE73B8CB9B4A0953A3D318065A30DA3A053E9FE93C3CE0E9C16AF2C8D4C808166877022ACBCA915954948D4D2DECE5946558FA0826C5C95C27BCEC580983C1DD5F11757CA75580A333C5BC839FC39F2A562A17B1728303800949C5C942968927D6A74897E0806DF7EAB7446F02277238E93EED246C8DBC8FFBC177CCE02244253F5F20C4A344900AA3373AB86E0451F2D7BD8B79FDFCCC6E038158CB12FE00685B5ED63396E6BE28283607B0C71FB3C20F1CC1D1027CE4FA53091537D46A7DA3B942862B1E713C1B940B9FA35C3715949CBFE0684B9F15EA436B84A867CA6A0B09A1D8282F6F9781EF5E131814AE55BAFBF243D8357EDE772C78A453AC367870F794E8A707BE4D4C1B6B5CADBB4D3E5A83F969BB8B928545869D93C0BDD184DB99B7DA1B183D4CF97B3AED11C1457F2C491BC8ED64614891D3E9B7F76CD2241DCEEDB9DC2065A905CCE77F24304581F0DA12434A6FEEEA6EE4E7B35160DA2BABF535398E4501ADB0E70C422C910F3DA9F1B0EA247978BC6BC47DA0B3FC9F178977FF4BA4C178DB0FE55E3FBC2B9D30670030E5DAA5804710F685A3CAE659B0624336D078D839E034C7C02CF4083B0DE9D1079D04C834A01F0D4A6B1C0C3D1B99302ED33ECD71476497A4451E81271562DCF28AE7CC17719E50FD6AE47BBF2C6684CE651E739EC6AFE0836395179AFBB65E78E0213BB243F205020FB39E83B16E43CB6DE10BF09AD231024C2D4B7DDD17FDBBDD3C4CA0E2CA035D959B2B6BF8C9CFD9744EBE1D76B6C0F7167EEA0ED03B12A4622C76E36DC1FE53364CB6AD7F516649E03C566B455A544DD832B2ABF6C3C6215EBBBD82A393EFF42CB596DCA12996EE1FC150E6AD01951ACDCA4EBB12059A267D821CB969A78AC2AB7039C49411D462DFCB628C24BE48EADB7988E53ACDBD8CC1EE9D9A32213AD77EA9AC7FFDAB0DAC119A69436DF3C3E8B93B6A2C300A46A56E852E156A3132F4B8FF9DD85511F592B8BE20F0A989E6F74F6A9F7AC5F89692FB49C784686E7A644ECC984AA45E75E2F85542346D1CF6B6B48F699D8A945E6B601435A6936E40B68F6DB3D2E79C5EB16A86980BF7E63D49F4C16845F5A42503417372717E9C9897752D256DCCCC466003301A5A249A06804E261916794DABA8506E796C14612E5AEC53A76FBA6235FB32EDC41E1E46E70698A02456CF28FF289A980731F76376B9A8393A41043BDFB141AB7E3C32FFB0E1F19EC9E3480BE487C06F85BA790966293102EB56A28E0F33BAD28F66CB988DC56954282A0AF25B338AEC84729561CD7553B5686A98F3321635CA0EF6AAA82CB6EB711C272A041DD3ACC5A9FEF21EF1AB4F42D8C197F604D8FB8E1989AA8CE75300A9AD43FD97929FD3EF816B2123C0985E736A65502E090D4DCC6ED5ECF040CD6D0A131562B9CC185DBCC2731FE88B900509D45F11756AB7E3CBC12085C23E272F5534A1823D8C4958B4C376551526874DB9537056F254E04639776EC75F8E78DA29FF55EDED2885A855ABDD56F8D086891E04870F8E7DE47DA1104495221C25E13B5F5E8A4FE04A48EA5CCB752833B0517C25E9266F3E33FB6CCB2881D9299EBFDF82626C3686AB4D4C3F32E6C350EEB0217057555330E86A414D2814EAC14368580D122CFA2D90A211F2F84B0C0C72F30FAFE87CE30D55ED5C23D71FF8BE34E83DEDCA732B850505154375CC8E5EE7B55221956FCA214FF076520F8807C845793472CC5E1B6FD2150AD626D2214B7541B9FF9C26EA84905B201AE8BEE42224530C5F5ABF70649F14A0AB94BAADEE25A54523A84C1E94B75F0D7863391737EE79034CD9F2B7D8114C1A6A889932A9D0603FF80996E812D9C40296B8290B479D068A01FD76405A3A9E684FCE29E31036B3904F1C52149286FE9393B9B1A92074DA5FCEDE5478F027ECBE233053A8350F3CFD95675FFE6D13E332E079DF3CD7682A9384244A7BE1932ADCFE3EC87E212085E2C5DF0872868F71DFF4C9B6EA4DC82C501B62FE51A15392C5133EB156C702DA9B7C9EE78DCFABEF2F962437387470381B1B8AF784E362103E3BFD6EA7078C0E3815E207DD973E7B5FAA74598890EF9D992756BA855DD6586DF4E3830CC87E19D88C211740A10F1E52BD14A69466B88C208587846BDF4BFC2F93FA11910777B98E1AECB26F8369EA39089A2A462E042A701038D5AAEDCCD419AA42C1579625032462DEF31C713FD2F70019DAD7C11C3BF6D2250472FC9850D9F638430A225F084117B28CEA4DFED04DE202F140C5196CCB78CA80307D28BF0F8D052CD3744539ECF6B1439E670E90AB0C8A89DE7063C6CD0C9F51E3ACB5381307AE13F077B21F32602DC278268F375288127829B6A99CB57F9DBFEF94B4F0BF268C098DDD397F92A8D6DC346AFAD62D8C49C041B1171BDC8E979717F0062A1DB8CBB75BE61CB1884284AC713B8318D917451BB899491E7002AAC371D620FC194529531E930318B7326C5397208502E1B8E5548E2C09206333043DFCD1DA00B957012A6FCF67ECEA3E4161DB05B6F7F88BC157E6B68F09C4AE22C6287124581CE5751EBA46FC893A3A8CB274900D6B4FACD08045C07B9F4F480B8F9F7419938ADA318B1C85F89FE2A64D683A2509FA3FC90C25DBEFB3F4B344EC2D1AF1874FD8E67E0BE52D322B5BD8BA228E088A4590CD7DEE5A534CB622E4FE35775577E7E99F3DEA58AF2D6B0D80E9319F4F9CAE87744FBE2916B53BC113CF778FE9CF7361681369C92037F38E89821357ADD3690D5699CE580D920635A11EE57A772BC78CE4049FD793CEFA69EBF4CFA4A53C9EED3540F1767885DF1136F46277EF6204AB948536F354D7935C05DFAA14BDFD49E95A361D3F7F0C2A388B818BA66EABC8F3D7CF9346EE273E927609FB253579678444BD3DFA5B65BC394CFC8DCEF55430C358460989FB4B7323D415CBADCF5F7061C2E84A5C7EB0AA1CFF51C233B71999AC01D3C424C7F9FA3DF082189A2C0CAE4F837417788A7D0DEF80000000000000000000000000000000000000000050D14181F272F36", + "reason": "too many hints" + }, + { + "tcId": 34, + "testPassed": false, + "deferred": false, + "message": "3FD78CAF8DFEC532282C5DDE309BAF88CF1E58ABF79342580853DA3E886E218B8CB1FEA5596AFB306B18624D076699BAE4759CCB551C633D7CE619892F304B8B796545CA5594FD6BE9AEC85AD1BE3E22DC0A6FD3F99AF1D17C543957D5E5DE3373340C468876C45448956646EEDF92B63DEF6F0E64BEBF85ABCD401AE846014E", + "signature": "CE15B9C213018F31DB2B8D42292558C307CF883C9AEB567C33DC2AB94F9493E9E240BBFB6455308ACF55706DF347E55CE50BB5A80FFEBE8656F5EA7D816F6E996F4FF5CAE356E5D0716A959BABB4C100919CCE60E507CFF07A1A74F06D3D3C5232B11DD93FFADCA9C2DD5E88577B13403648443FA3F253283CC6C827269152E1D47E5CEB8B325CFDBA80E7AE03195AB88DE4AEE19E82D6B49F142D05D7667BECC32CFC2EDEADFE301EA4F545FE335CD6499FD97D1E9F7EA4BE9F93E14DDB2B41BB2BB2B30F7936D9D75E89F3C6665A1E12AF364848B24D0D06B2414879149EB3D1FF1209DE6A775986718859E4284FFDB444AE7742130C67761A0F110552B8881B76A2CF55D45474F6B97D9D2C936362510583AD9D9F1926CB26FD2389E83E6FF57F5A0C8E48AD44E96ACB402EFA2AA35ED468F88F7C49EB713EC6A2314B74A108C51401407BF5AF0EEF3DB6FAD8A4D6434B10961C7E7B38EBFC0E7F614A96499AE811A281907780FDB57CDD94E55CD642D47EB5D19126E508C625C8AEB4BE0ABB29BE84E0D26062C6CDFC93424DB3F4097675B14201ADAF869AA11AD2DD500C67A0F2B6C0563B671F54362B81F9592544CFB080C136943E2A15DE2A1F9FAC863606430B077E65F9039ABB52AB3761665059D22CD4A626EDDB9D8D63ADAED7132407064433052314A61EC08C3E83117CA167F717347376F85BA787877BEC7E7319EB06B85C3C6C85EA04E5CEFECCB877C87192E4FAEC471356E62234D16039E3836EF4999E9AE3B3E6D9DB5ED5915EA84624FCBCFDA4470DB4E0FE04BEB93E769EE2478FC47D61D8FCE62B7ECFDD20CE74ACBECC71A493BAC2D17A11BB47FAAA1AD17CB0674B93BC7FF771C7B952872EC789D70FFD9C3F0976C9E63308382883167372082A9559F2FC190AF2A8F6861F9C6ED86736186114786DD07711EED8699972456D040DF7787EA7883E8C7EEC9B0F6AA56741B20817FEF76DBDACEDE4CD0A7CB5F52A196A03B382B7593C1A7F84985E194371646A7AB40EA98F7AF1FA898E118616E168F5CEF1F09E3E72A8DB311DDB798459179769FDA5B9FF5E05A4E072703D517B176610C3C585BA956CC7568A94DDA4733F054DBA2D8DF3CF680B4616B92BDF1E47E274E4E4786B428A50D852E369A7D109DDA7061D44118D0E826B1406664D7BBEF49A26AAB00F66513D342199B6B66D5E1578FD7177E4AE2F7A45B711DCD800AA22B6D37FE2B376BA07E8B50BD7DD7D5558E46879DE6BB9BF453C329BEA037291A9CB05C32655F33BE34FB5A67C54FB1E131510D3EC42FD999FE54193480ABAC2F162A2DC3D7D2FBD5C8189953086E49B6091AAE7C90F242EAAFAE9A1A47FDD0F7306140E2A2458CEF4840C8D76AE4E0AB27BCEAB5195DE1D76EB2A89A12E67382A43E97AE4C194A6664AA9A0595E505A176E297D11B67A3631560F7585F5FA87F4A24B3E1E8CD72E1858857F988DFC310771D3B566891EFD357F79B075552E341CECBB22C95AC56C490DA3ECD9F6724BC12AB1CD367394B9EF1B6067CE85378E47F288F3DE8081B51157D9003F7163070FF1A8CEA914F0F8374B645D71EAA19B0A8C239A00F66F7167D25E5D2F3B0C250CF0AC0441375D0EF6645C4C0EB2974A712083D415284DA2668C9E3A0C9CCEFF736C1CE91ECFDD605CF3DDAD2631E3377762516A340D2879854A3E3DB98BE6C5CC57D404EF04DD86500D915983D7288AB095268C82B1BB032354685A003AB8D7784D77B061ACE0436D60FA17AB4B4C14898FED46B645CC1716B5C6F2294836273EC02F51F839B394E37ABE7BC14374F34CD3D3EEFC57CE78349D7F60110685D8327B605FB975BE0EC83A829743615D792CD1DEFDC4B3907B45C74E95B0C8472E282C0D1CB6D571D5EDC39D6B868423164ACC8E418DD01AA445C54DBA6DA0D90FDA6A1DFAA754DB3D4B544ED6E323EFB271B8B1CD313A118FF0BCF052772ABC2A792F629B94BA2CF4F7C6A882B954A1A52A4CFD204DF72D858E67CCBDD659EFC73CFB2A1D06808CC0602D264FB763C727B6C383696D10BE807FB665D4CD4D48D916515C590969BC6AC969062B37D6496463D7345C556CCBD2204211B012CE12C989B36E4995E30CE684500E8ECE510BE5E57BE0867F7184A6470F338001D490DA764140E93211F20990A4B7407F371CB04966FEAE7BF70F667383E90FF2135AD36718826CA1D86DE281CC6D9F3A848F2A30B8DFFD076683FC1B4667681EB95E9F310F49F36AD872EBEB6017A3451AC8F99F2334FD010F113D8D93B5F9F9DD7962E7E974DDC914CEA28ABC229B999311A26B856185F0A1E61872C11B21E79CE77755FA53E10B95C48FBD4922AB984F953618C468AE496A4525177B9F6D02DB2C997785ED70DDEE07F4768BC9DAF9CB3040F02799A37E768EA6E50A013ED4470EEBAC3530BA2CF02286C49A6604D82696141FC78FC26C841063A7BB22246AC262B17DBE0DBBE5BBA61B0FD441B3C476425DB857813B57DDBC4B704884C36EF43A96B5B265CA557F78F885088B201A86A18EA573BC66BCCC43C61410531CB769C8C52DAE25E49FF58F06F63BCAE458DF6F587B3BD730C81ED9BBD0C408B04115A246CD3A0458A782FC7B89356A665D24AB0BE5A5AC84E2514A438353654605ABFEE00C4C4DBEA70F9EC56C063AA8A632FE7F6A161D3D868CB7C2E8853FB79D36AE27232427E3EEEC61A124E3296067C522D7F653698FE6CEB7BA6CD37CB9420BC646610DA7C9718DF4773380B78877898B799165FC7981B7BCDC9EBC2F052C8949AF88E3A734909D76D63403BEFD144456D895151B9FD53E815C38AFAC6BFC9D497C31446ED063A2EF5A30EA3FA0DDF3519CB3CAC529B8845E6B3598088BFE64F3EC8BC7F5FE16D4565CD1A89C3F5BF38AF8A13BAFF9E96C12EE28660E5DBF519304EDE80C2657211ADF4181A96939887220ED4ECFD2EC68F04DA8FAA38CA8F01D69B387C31E28631EE7BC69C8949911E8088593968EAD3D704811352529D1A6F88A9859A347EEA7F3CE7A36235DA5D6F532F7C46CEF41C4A1EC738587C4065323A1D88646618896EC0A408B524762A0EBC2B1D3855E2631FC7BB9B5AEC0DB18E2D22FE96A36146693E32323292CD7C8377DE06ED17493B891C0B6475B14C7D3FAF7ADC40667D98230E7E53C9B5BB17BC07C14B8806347B81583FA6FE095BF9B2F735BD3D7CF8084050599E39D06D95DEF74D63F641F90C3BD73652137B9676DB23876708D4D2A8554A8BE9739CF0A41D881252E7C543A89C4249CBD8FE11754135D0B61D3AB8772D3D0AE720D31AFBC1FF259B5B59FF408DE206EB289E6C755707B34C043E58BDFDE1ADB74BE2F17205836A5EA327A6988E1E5BAB36268ADC09874DE034FB748A32B23FB1C8C2A77DBBE9E74B9EF421A91F2D547D8689FA0B846B861803AB7EC9A8E671E886BA211ADC67BEC738C020F6489E9ACB275D88A35507BB152113EBBB94CC43B1E2C2392009A3E80472883EC9332D30717C629C804C6586F36CFBC67C0E29B61010A2B7ED29AF29D3485B2832FAB942516810147EE31BF37B332FAC89629050826E053A0B73BADCA0F26EFC9EF0A874A1E788BDB78E8104BB56886B9D86CDBD7731B76AC7FCD719C76C281A3CBE011B1FCEC4831A173FDAB0BDC1B35F3A51E0C8F7BE8715FE4AEA8590E6F4BD96BAC089BC8AC2B2AFC20756056FFA184850C89E8558E1A552801FA7D8BBEE741BBDE30BA140BF66215AF54F282DECFB944C53F525CCED0ED07B747270790E7CB54E9B8099639513792B374D3D378013F558A608B1FC95A73F4DB92E692D5CB72DBD6AD7B4E28C2FB0949ECD3A2725AE7195655EFF289E292244B4C82A803349C9210ED23EB343AA7807F5EC73161F4370B3C1B486E6D80954021A23A492A4BB594871E24B8CC5C7C037AD8B76A5683D63C262B363DCDD6351163838CC5E0F4D6F287D773AACF92A3693A8431BFBDBD4EA5E6DBCBAAF34D66643F5D4593DF71A2AE95FB23F72858DE14941D46F3CAA016F67BE716C30A31706798F2699BEE4F782C7A9958F443C5F7D7D8649A62367F138BBFE49208CE94626C923FA6D2E5A8B6701C6F7DCCBE70E1605EC4668DE789FC6DAEC1B5EBD38292091AADF152DDD11BAD0430831D0194D1474A36148296C0898F85C945E2DBD55C92DA90711853A22CE20DD71B5CBD12057F3C00D9EED62DBDF3CCD47251401EEB7B2132E52864622831A43FA10DEB7D05F96E1DD1BBB25648EF8524A03D771AF597CC2D3A6E75728FC9E96357CEC06FD5B9EE31D728D8B6BCE4BEA7EC0EB5EC9206B746BB494681DFAB5E95C62CAED2EFCED1D73CCF3FB61F976A874C0A534CEC525D88A7EF9EB6DA892FD76C1F56E400374D58343DA6470D8E33BC8920C9C9364EBCCCC2F61D6E8ACB005567AF19DA5930514CA8ABC226DC94EC3258D580C76ABAAA2E21540B77FE5B37D26EFFD315C8C5455EB87FCEE70ABFE5B964A7456EBFF0A97398D55AC07F689FD7F1BE9533168643B901AF791D7053E706412164E0B33B21BB609DEFA3ADF48DBB6B864E260264E1B22ED8B3C261F8FFD3660C18FB57DAB4010485A48D6FDDEDDA6BD235807227463D2C1EEE1F6045063778C46EEB7C1CD0961E84F034FBA850A462BE09BA88072476D71CF86B4BFDA5B74793ABF074FCE7F8E9883469EDBA7BCDBD490982FC111F47A3EDA59726A772AEB7B60B155A024244FB2AFF2864D39DFA685887BCE3551BDEF870BE953CF1E13FDC4EC645071A468D4E9881D27845E0658F8D6755611D2D4DEB535D6852FBDB1C2CF888F3F43FCD5EC9F6AE566FB1D071F60413C5C3B041D405C813DAE726DF6D704937709FC517670394E1BBBB0BEB3FDE7E4B1C4E0090CB18BF0D5E04F56A6955E859DF37B858EB68CF41BCF9D662B2CC6554B2246E7C949A52B2DB14A07318169DB3D9149A98DCE0E9474C7A17DC137B928EA370B78224CD5E06AF1F83101A96BD8010EFE450E52A918F77A9E330B81BEA98AD44053E20E40D7411B008E45F8C1FC472694AC85D722397AD6103E71EA955DC3750007A6AD3253E23AD619FDFA24C32FE8E22F6344B513303D7144ACE4C6EA5AFF2A41B545F5A6028173384A00E6A6B8751F0929573EF5F604125A43CBF6D1CD4ADEC7C61844DD799DFF6311A5ADE2A71369A80F91C3091135D37F2CC830B67811D767292DCA85F59E0D0C0E712C730E5D87987A35D97EDEA6D8EF10AF7462F851FC2901444EF87BAABAB761A5AEB02039F87E5FE22CD23B981F6BE4E7F8C2CE8333566040F9B34D3C097BBC46A420449844DA66D4E9AEBC1A91867378E565DF288DE5FE2B8BEBD10BC41535DDC5286EEED3DC4F729EF65C04CF2F1F920AD4C41B624B5875881F574C74E92132DC2987351305A3985686BA43A29498391BF5542EC5E4004D50D873EA41A8D7EA6F7D9C1641932E7F65731F7E1973FF13D21FE2412644CA7C6DA082AA535CF36B0D7719FFC0FC7A401A245685CA950D2DE8BA689F7F0B270D379CD523556ED54EBC17C4FA661B898A842FDD0B2DF9D63AB8313A69F8E9E145328500C57031DFFC73A699AEA270383DCBB8CA39DF61C6C8207515F0EC8039A18818E60C8F7976CE0390FC4E02BCF8DC21D79DCE8CE9426AF9774315AACBFC38CAAB473DCA7ACCCE7F5BAA1054D2BDB002351C9AF7841CE683CEDE23B69B43DC83183CB263FF5183AEFA397057F66F4A6B665F9980218AFC96783B3AD24B5D277E65229B337A14ED48E5FA303173D10C5269D61AD43570C14DFE9FD6C824E81EB95CDA16F0B01CCE81311686C493F92BAD1FD5F210EC26660F983C5AD79418994C71D3EF5155924F2E3B88B137795310A1FCDB63D697FE085EB08130E69729CC62D846D0192BE9424FF15F4F0CF1AD29F967D7F85FE131D8B5A35D8281B02284EDC8D5207B822BA7B5341398CE0006AF2B466A9D1A7D9760E61910A95508F05EADE6C6F2BED17E68AB3F0F1A8E8675EB74A1E034681C80E757E7E69800C973B1C39525668EBC5C5910C071E2004EBB57F1C5E1FCE6D4B62B84F48A4FCD7E11C0B2ACB22EFA901C25B65C64EB1B95533C166AF4807C2994D374FF28AE4E032909C30A6FC5F445BD3CF785B625227E3672E5B9DF946DE67AFDF80FC6829BF207BD686E2418C2332740E2DDA4A98350694406222CF445028A352DD4934D1C1CCF638D3A01754E1337220271D9755DD40184CE4DC3483A4D568639BEF1751CA0AE5B7671CAD3F9FE5107EA6F15B794F0203C9D4B9AABEFF8151AD6B1FF3388B4D6D041B2C062061A96964972C3468A87C0229C69D5209F190DF30B61616295C08B7CD58FE5706D974E9B4DF522B600149CC873A3EF0E83312263E5ED4737A6ED2A827F797383BF86E2E4E13D0FB11AD8801E72D420DF2A5165A0839C7C4E7B3903C27AA7CC1C1E25F8F991562A2C62F424D536C9FD4D7DDF1F536384247727381A3B4C9D5EBF61B2227306F82C3DB6586A3A81A4F57646C9BE9FC617375801A1B3E728695AFB0D4ECF1FA0000000000000000000000040F1C2428303440", + "reason": "modify message" + }, + { + "tcId": 35, + "testPassed": false, + "deferred": false, + "message": "B6A320368AE214A12B14A0A9503171000081AA8631151D69404A1D77C6EEFC219A540B4F488D2EDE8C9873345244CE047DDE56B636C850C1F268C3B8C1A0399E49F2EE1E36EFDE5738E14F82D70FD10403DE18008D45138872423E26E466BFDB1A4B442349D1E395DEE4FC4A51C304308FA81E817B53E98D1538EF1A84BD3B34", + "signature": "C62E458802B7062014E7A44FE2D8A39A16DC699C777CE258846BCA2C9B310F8396814754295365ABF071321722F3BE06A000B88475F88DA9088F636DB974E4CA96F38F667C7F13674468A01AEC084454FC5A714A0CB39D7F29897A5D1B1C9E4741277D6A1C63F968EB23B206DD26779505FF7FC5B7B87F58D57392D077D62A3910D11A5E7B2E8034318E9D4004FA2DB0707987DC8250801F6E53C8E0B31D28AC60653D18FDFA33F846FB024F09C8AB23E15FDBF568573239297971F4E8587BA55A63C2FB1A115E62826B65AA28D3BE1D073F7D8B67FB14F8BC83BF849CB2C7B8AD00F28A8B841CA912FD4B66FB8F400E5C43D402EECCA3FDE103EBCAECF7C9294C90DCA2A0F4E50D79F143D1487C06C69E1451E9A47DFDFEEC9B8FE1D8C69074E9FDC9A17018A9BC0273472B9FC75B08B691071CDBE8937E4406C0342F8D214786AF0BDAD4D5B58E455137754774C699217AE9C565FA1032A6B7400E2B34086BE445E518176AA016F8C09FE716D14E99D7A710150E224C3F6DA2A6215C9B2EBFB9BD357D598D6ADBE0696D07CD2F5664F081284991CB15764E6407040C63683117B2ED6436237B76FB42E6FDB14A4623045DE7F06F52241DDCA7C6B3D6EF39B6C3A76ADBEF073AA0368E80162126403CDB2A995544B5CDBE42D256ACE987A714E00E9923F5C7D09DAD6F0F8A973268138CE1947E4CB248A046C51CEAB23228626F07D25D8EBF316D797EDA9800C25DB1DD0B0D0B57E9296A0C614D3CD1C585C97B88592CC6D545A202A70ED5D9A79E68F9FD6537E51ED5D398FA0714B4179CBD0000B6EFA21F22E40BFC9565EBCBF7889DAE85D47C4B33BC73B941E7CFDB48AA6E965FCE744C03705A9B143D625E8C7015DF83AFF0B46BE9C9F9A14C13DFA3BAB1F00F594351DCEE81D2B7B9D22867366EC613E621737DE605A7510380F83ECF7F923EC8FDF07B6CB208754DC248A26D837A34CFA80C8B40A888DC00BED9734E6BE19168E4CA7B63C0B6615E4D1CEEB952B8FAF481BC9E362BC888A0307FB23EAA4616FF00F4C3FDE918937489B920071A3215E50C90F97D1A05161E13C8AC4A08CC456AB0AAB06DF8A62465B085952EDFC787F798F4CB65A17198AAFE06E21C932ADAD45C87DDBAD4C76F0C75E28E5505BBF9FFDE930B327DF02AA154BAC08BECBCF0DAE652EB8477D96265D37D21851EFED964ECB9A72E22B914742A7F851BC5B1E6AEFF22B526DB0EC5F3A590E6CD4E177FB0927382E5928AFCCE04C794435F5B4FF7403FEF36CDF7DD0D031DF22D7DD302C48AF80C89BD06AE5B25FBB42842DC1E04B9B615A0B8BB15D532B433D9D639A76EF492CE89A91198D64A53B5236A5609BFC509AB937C41DBE42256E34C41D7B4A50950BE530F24A0131558A8D60F5F6DB33047F91683642FAAB6B0ED597EA7CAA29C2C04C536EF572E513B2B37489A2F71D7CBE73153DE907607420D880E8DA21BF6302487DCAA93B73B1DA8CDEE9833D50D5F8BEF6BEF33CC3BF47D4EA6310E79BCADD3AC02B76509B9D94B1DE0B3559867D26FCD294B09E5CF01192D6704CBBA94B48222ECE358F0AA0AC3F9FDCCBB5E258D2C94B8F8D3333F2A45FAAEB8D508FABA49E37A6C08431B869E6B19CE21511451AA6A6218A7BDA8B4204A615BC0D00C05B9872D086F3C28F35539250965639FEB8300F24FD29000B74904091E488159737A13611EF47E79A5023D6A59E83207C64212B16E63F5C6A62DEB6EB9B9CDA7422C531302D576BD19B8B551A4C72B5CB0179C96DF29AB63519D6C2D7DB08DDEBA95420744CEAB03AE8526ADB51E49CE35B86E3FA92AED98E84133B2962DC73C219CBF038BA12A3C3AA979C88EC7F3A218BB57ABD8DAAA9E2D487C7690ED55A89B56D834650CE24CB6BE05B1F651AEEE253C0D14AD9969C3CAF27299CEF38940C792A8C29464215FB9D7EBE90AA4275DC6D7CDB71EB2547F320F9A76D3371CCCB24174CF768D5A29A7199B25A9113067B430F9E21D3F1F1C699F8D836885CCC5C0B8409BD6E4E58FAA18C04B9E16E366DE282C45F31D61E9168D5D15D7AF3BCA6EF8AFE6CFB720ABB39098EA4956DE62C68167B0DB3BB61FC3EA185236DE3E93213ED4BECC992C7A2D03B60DBAA139693C79ACDB097E9489474660F140F100B9A6277F5168D207E15BF26279494B2CD03401939AE8303021652B44B4E5A6B6DFC1200E6F5D188A04EC407C9F46CF7395F16174314A65EC0FEF310ECB46F37CE9F5871DF22297A78B1321C371E0DE2A7A3AC7033C2CE18060E24D209FED3977198B3E025055493568463C0D0158C2F8E81084C16001091BDF93C144A7A96D463646438E0D18E9A873BE209B16A6DAB29569BF250D6F3193E6EEDD3DA2AE0A807A0EB1A124AE7F259EC6620ED362F91CF5AE7026628986B8881CAF7ED412D3A42E15F168AC443424E068DC5D5E9F43626BC00CEE747CDE4446BCDD130B015AD51F2999EF2A073C551EA1E0CC3791FBB7106487B9F9B5F735D136DF4DC563FDCE76831BD8B132921A303EB122DF714B9B3D9CCA5FE56FD2B516E24F4CF4869DBBAC1A39B6F727603784AD1D365459279320C5CFBCF86FB5D824D702FAF1F9C1F286FF3813FD1FBE345DE64BB86A22C981AEA10E6FD99120A8D6264AFA6FF5751D108CEC8B80583FA6138B0FD87308DEFDFC105AAD5A32A20BA3B677F49C2E838B279F7DD712C0C6D0B64F5B90456AB58BE58D39A9D4CE9DF6345729601F7E6848A85A808CF8D9FD61F7ADBC85E4E1311BA1507B002875BACBAD72220782465612FD66A0045713B0973EA82A0051768DEEED945EAA763660E831CA79CF6CA0BB396A1681730D0CE024F8DA6FFDC91787F7A4937A317DEB2AC641995A8306078D5F866DF5AC147BF8FB88B5BE36496C8AAEB2CDC2F31F77BFF6A5ABEB9FAFB8DFFB50688B49483C9F1834173CCBDC833E8D468E792D5DBB9D89BDFB8E4412B627891305D3DD6AC669835D215F890A9970A4E103E848258FFA2423C417EE2CF401AA53572F942CABC4185A712468B413E77A8F0709A134835298C96D2DAB39CE0AEEEA1C0B50D81D2F9E69ADFF902727942EBFB2C782D32D2F8DEA3EDA951F1F389C7DBD3F00D26FBC19D9432A6E1E2CE7F98AF8B121C72F12D30F98263CF53463E027830C94D735A5B90C665C634B57ED04DBDF1DEA737DB1B263A27A0FBF13A4FCD2350DF5216D0FAA704F72AF057056EF6CB1B773A77F749EE9F0CBB0C160A353B9F1312327E8EE4B62EED3B12273F28163069D62053E8FC3C75FE7BF55C66117AE91148470EAA9AD52E98250483B76C9AD4F116818123D49C67319DB33FDE4B3F7CEA47965FF2B0C12DF2BCC9A536A357DF98F55D06B213AC32C3B75852062A0FD06B59F5C76ADE0864AC1FE68942CDF42BBE083600EC89F9336415BE47A6C6657FF11EF8D39105FB7B30AE115BCBF652FED8F0CC153E92E2A94E8F2F4E123653B7E0DBA8D40EF586377D0F8035EB337D5253D4720713EA93E7BA1B15B67C488EFEA8C5364DD08424337709B2A8881A11BBF59D5FFC072A27E181898385139B4EC6173E88467E8969B37A6DAFF57E5FC19A82814DAA2DCEDDBC3CB45ECB397F31A3FEA34F2057AC1F1833E1457AF861AAB96B55EAD269D2BCC0C393D2B621386E653279DFE5DEE3C03578CAEF2263830DCF865FE513BFCE00C26E2E70C52E5A89ECB4D123E9F6EFDEBB554DD6BD5E976F6878A9AA726B022974207AB01F8462AEE960BBDB2A049C047043052C4D53E2F77901C0D6231B2DD57C13A0DFCD7A5A33DA7AED45147188A6A1EE330485B096BE54240BB0E2CFDDFA1A89D60609527C87CCC768DAF475F80B4CF778308E6CE9D4BC72DFB8213913807CE1F8891F84E7AA2EFD3B6B7B1F1F608625EC896A192FAEF1DC304505DD542CE64985CE1BE3A75DB797BDBD2B170823A3D0D49AF854C023CD37660B46292630CBBF8A7D60FB58018E627BBF900BEA588FF7A9D7E18DCE62576CD67320BBBAA31B104605DA9D8EBAEC31F37DA1AD5AA0AE36DF024425F42D72221EE8893E305379C593B0F914AC2E9B489552884AFD7A54BE57C02B9AC8622974200A5F236EF02B399B169B2A0FC7AD625784EAE3B59BDE0CCF8C3792746231EF45D95B111FA1BE3FA1FC5F6ADABEE9ADBD1C4F3098E3696268A317B2EB9152BC60B21480D59F9D182D8EC3D99FEA7A7164D3619A8C5EAA0860E2B1954B6A8A383B516D8D8FCC2783778CC1851459355FEE257350BCBB80A0BDE46FDEF9FB0333B430543F9BED2D9D687841EB37C45DFC1B95EA52E71E9CA55BBF9177E9A9006D6F2120C31FC4DC43AD1F7089AC54067CE468BED4E78FD09EBF5857EE9A0C99547E6F7A039F6BFB6EAF5331B0448BF330B5E44252CAF59A47EE33303D99E2B9D43D2FDF3B8A1E6FAE250C3A265C23FA1D20E69177940E55495CCD326B70383D646A461B197224A3BC7E22E86347D61427346CEBFFB734FC6D71FB20CCFE21079D631D30AB569A9DC5FB9465B7941AC1072E9CC9A51F7CA476219397A39340372988658C4A43B7865B10AA66627981D0AB0A6F73055AEBC2BBFBD9183930A37169A8EEA61158BD1748EA40AADA0025DEA687C4404609790CE1E0E57A9D3F2E3BE362B1C3F111FD9FA982589D86298D049D99A51F54F57F520AC9044D691394996BB455FFC7499514CD4C0DFF659460633370E4C6A8D945C017EEA65F944E77080206EDD2F0E13FBA76CF02D54BA3A8A35017F4E227978898E8897A6C1C5E3193579DC75EF5A729E2554F0556E4B19E67031412DDED19E8C6850811CEED24AE3D679EE9EA726A82CF18410838B5435E826E8AFFB61E7E524186D1522855FAF4123183822CC1295B0F3D722038672FB6A7F056FF9B06DED416A7B59D94940C41BD9921890E11D8FBBA21490C1C0F2391D871D19B1361409E3239FA7395EFAC52DD4D215B25858484A41B1919287689C2E93BFDC3CD3ED5DAA0D3D95F160C6EE888CA5395D10D8112D1DAA07E80E4FB0B95B6EDCA7576FF98D7B53B8C9CC09DB06753C0FA874D9B742E1D562AC911783B4EC89CBE7C660EF9F1E911C5C8D375B9E049219E6D330A8E31E0958D3E991F245B9920798CFBF43511777EC7816F09EE1E4DD04D08C4FAA9E59774A3F3AD9811C08736AE1D4D5B25CADA834C099AB1F8AA494ACB8BC04759224A27376DBE5A2E3BB6F6D5E95C3C86BC15058D95737925B2068A3578F70FCB62287693BCC05FF8594EF64386C81837AB40114D5C990C6B717FA2C6AA7C5A538CF7E0525ED93A335139EC7C5E7ECCBEE8F78D72C1873E994190502378C46CFFB435A39B2CA460713F25808ED17904BA5251DD5A0C8BF6DDDC8AD6FC6BA184DB52C16C451B91F717163F26D4FEF14AC1D1E837FB22626B12284568AFC82F99D52BE96B0FD3B11A76E6B135EE0CC72568789B61F1B96F43BF0B0F63B8971370E6D654D260005987C6667EAF75A6FA5E740892CFA84AF5C10C1EA2E56215AD3AF49E6F4F549644549E478397945C050C6A38832C4C750D64A103245A04ECC50BA1F3E6E306E19168F29C5967F0AFBFBFFDBD0B97429000BE3153F530AE0ED22AECE0EC84299AB8E5097D65CECE11C497765741350C43BD85916F140F5616C66CAF8D7AAC20BBF4F05ED44703149E68E9DD28497A8CC8DB4E3733F3D530AAEDBF57DCE7BE717F63900593E09A55FE30C92EDABB3B96F698340DEFA02AEFB772ABDF9DAF216D7B4A4875CB6B023500CF11BA8DC8CE9D7C3E8C069C5DD1724F0F9CE07BF1B28A3211DE569DD2F73C228CDB529D538DF444972D04501A8545713AAE4095279C21AB2D332C8A70BE4A9B5DE41B4FCFF970BF35DEE2D9C899393C1D0E573D248AEA42C6D9DF7C28DBBFF23FDAE86140BF24B4FC3598ABB00605295569D75CD92E4B3655355D497CBE7F7896B9867B60033CE910FBA168CEDD75C5B369B452C5FB8C020FAC800B924085F748E19A57B33E2967A110E32A624DB453BC83A8DF22B43E9399591717BD0F36DF5A9D5539D87F5427577C20A01548091F6C5261334C0DA1F1C2028422ED3A2AA67C774B662D332644C6FCB353DC2EF12755C0522038E611F4C698B3F9ACE1C4F989DCC336D5FA8901A5F2E76E4C5CC0EF3D9620F369D2EDE2AF69E041D341AADF7F3A5319D6CD3F37B1C37DEE089D9143EE0096C8EE99C4B74EEE21F07506277C4AF200DEB327DFB94E4C1472C235F4EEDE61EF21F55A6E7086983A628253946276F5880DD95B9BA8C2585E3DFD256C35D6EAF7CB2A6EFF89298FCFC7731E9E24FE37588188BEA692C3A65F5768A7F5B0B98386A24C80C9A276CCB0E24B1D4D684B1E2AA31B86E752D33833247B4658F9F31999D7D1C5473E4865C976028DA0D1B1DD55CA9CE0825AB264BB3F24FC1286A59849EA9BADBFE4EECF904751FDACB74637259E75C010946B2BCC1CD031F32787EAAB4C53C595CCA2E344D6E7079C0F61419575A62667D8CA1ABEEEFFA5D828488B4BDADAFB4BB1157A40000000000000000000000000000000000000000000000060E121A272D3134", + "reason": "z too large" + }, + { + "tcId": 36, + "testPassed": false, + "deferred": false, + "message": "200617160BC7473B67983F090EB24EFA04F3DF7722B6288437F32CBACE387ECA67E384F4EADCBFDF21341A81C0D24270C2D46819644466A5FA02F2CBA7686F811900DC502311CE6C0D43BB885B228629BED3233DB998CB4333A705B949CD23DDBD75A447FC0043E61222B22F87994D00BB3B98CA462CF7BE47D85066F7E08EBF", + "signature": "D1750DCCD7D25AF7D16C5FC680D2ADFC8AF7ACCD53611823406448EB4B748F85B08C71C70AA94A92AE83782F510A0365DC9A342C97A9F430F62E87D163AE1422427ACB89AC0DD0C1FDD25ACE097A2E7852494D5089E1BC6CB1E08A66A48CE391BB3FA9C691182D7CC18E378E50E129A87A33BE6416D04E411EFBC9F19B69BDA966C778644FA7C62FA63B94BD45AAC7033507BC1155224C124FE2DBABBC5FEC1C65AD761C92552A6B4A2193B6439B1EADD04011A7D630CD3B728112BE33D6A9013F8BA2D3BFDF78CB084D729C50E9A71E4BAE1A921B606069B557574E3D89266997DBC1F3FE0B713CD8CBB66C29CD434253C12F8CE897C9D85D88F89F953149B3A4978D38FC3AB6308F3292BA7BE6C3AFD9D60145F5CC7B62FCFC46C62439864D898819EBF95B7614415FF2769AC9920F12C47552B569F5850F45457762945C5F2E16D5D70129A0B0DA677D002A47F730ABE8B1ABB915523D872D6EDC6835972FC8DA395315D2742B708A0746FF5E54960C20C195A336C8383B2CC1F97E5D59BB57BF91ADDBFFAA5C31D10B438AD9B4EFA7658C4048A17226B621F787B9D7A06AD14FFDEA85CF33895574F4A13F28FD02E9DF58A2020A567DC529F552770DD3B0FDD4C643B01C1D0FFA48ACDBB2190B900C99D27E107EE84327ABDBCBD6CB5ABBB880BBB6F556890D10286BCE97A13310B33C69B7E44CF5FAB8850B4F526A8915D35469D5945AD8B5EA6A65EF961A49A7081CA5D3DA8E0A458EB15AC11FD9911BD2E25B380AD6FC01457A52807D70CCDF5F9E0F363B6EF057FA35AB2013CDAFE0FE3E4C9539181B5C95EBDDD92C3E915A5094C0C2005B22F3C5478445BDF3F2D628E593B3A2028F0CAAFB5786917304F76D719B951362A745A9D4401BD847B927C240E2C9353A64FD1AE944332F43CAEAD9BE09B8466CBA0E095B74398DB39761B8BC37B9FD0C8EBDB62B1265467C2C19BA83F59B9309867F2D432AD6D8A94E4DF8148AA33CFC48AAF4C56702F1B7656440AA20071719807954B587E906C34ECE51A3E564313BD28035E588704BECE95D42C5DB875681B1AEF67FAE25271D13AC585C5921F1D47C85A56807E09941EDF2B233A697EEE085FD5BB9828AB5EE945ED42D596D103A4B5C659603C531BCFCAADB32CF33581E4588CA1E2C7BE8F24488DD1E372EF7F06E6F23A068389E9983B0D83D20FAF56FEF369AC782806AE6CEA531B1ECD41C89642E84F9D617930197D712A306E6F0EAC1C32FB4E0D9E5CAA8385781548500698085D236A8DEFC51B78A8C6797DEFDB858C686633F3839BDC271E177637A57B49B053B837D5E4DA82668C3337D505DE11F13C078F63AF4A287D49C1AEBE157C96AB9762AC7690480E85FCB2E8DB3EA32B6DAD096BDEAAB9403813FF4AF4555203CDD7F245EC7800C5F9A77AFFECA3E40589C102574401CBEDC4853561FF04A22AC7DF323C770783A224EF33387E4BC6D1FB2F6012782DEB3A90847C61A7830ACA74C9F212582C15388EBCA86D9CAF3F239F77AEF4970C7AD802B17B39D4943DFF9EA67478FEC49079E0A0DE0F29166A09E7ABD74B1573787F24BA36B96094F171F722E08277288F7FD1667587DEB64AD2E00E787A465CBC3FA23938571177476ACFCF5A7B0A70D678C99417872B01865A84FEA308E344DB3386907D88E733F64F471D2419915EE8C64F4F1D37CB37D88A2DE92ED826C44A990EA3669A8FBB280810F4F2BFB13EFEC01D7B479983E7A7FB04EE34AA1008A454A2DA3F3C473A2DDD66C46541AE06E30620AE4618849D021B03C97D741A9993E855A75245A291D43D171A0509A6DA1ADCAE892AC3C6C4D7CD03D5A22BD0B110D345D1C6E968BA01DF34762D36D0CA07EF36DA48E6B72C93899DCD4B43FAA379722D09E88ECB4CDC2189F3646AC0F4229D35F623EC9AF96F56A82D6AFC3DE7DAB71D1D7AF15567328BD221A79114FDC7A3C2CACAC9206F67CFDC34CB47182D146BAF56566746A23D9A8894D5DF5CCA3DF74F013E095835A8F92733493F49FA1ABA71E47DBE87059A717BFA378BFB50064D7081290BAA056D8B8679CE0683A332820E60C01AD0C4AECD7EBE8ED71FE875BD688CE30FEF93747A86EA9ECFD8E850530612EAC2AE227C2041CCD4A9FC942168D2ACFE19A40CF1AF665C3E3C300DFE4BF925AC4C5110F5B0CD13EE2245461BBF56D87AC735910D52332280CD49D49B022756DAE54E94E264CAB28292496408F779F2395CCF6303853A31095F81BAE6832E97CD7C2310C3DA4363131BA7B54FC128C7B94CBC50464AE9A785342B5C59CF7550C1AFCB190AAFBCE292ACA3A0E77E21EB78742CEF7644900E85E904ECEF3F4C85A8D524DEAD6BD1653AA452517DDCEF08733CBE02508CEFC50A6B0E359C8A10641E43FE133CBF6E65449FAF39021FCD75CEF6FF4403B8262729A41850AC6526635A024796E63073CBCFE892CD04C1579B827FC859A21072EF323E3771F63829F44972F6A3B7B7DEC4841A5A0332C58B637F8B5709E8CEB9E4A5FF8E9CD884C729E4EDF931D67896A3DE87D8238FEAA85EEB049C9A7BDFA6124A58C43964CAB536E1C180FE35B9362C5B97378E9A9BF7732E7C084B2BC81588FED53E3D4B6912461676D52620E473F0B4248001A3F84197A14B21611F43006AF624D115E5900893F2B97CC0D3B40CCA1B68029D685861A9DF94F078BBE671FED17573329B5B357A4CB59B13FD8B90E50FEBCD7516835CDA8148482D59816E4F98A0473296A87B2047C4C1ECE93D17706B5F492FC7C7BBEA333742FB35EEC0B73A0ABCF518F95A7FFF8D8EB91D0132705040BC2251325ED66EF38AF83107AD7B3048F86E8880892D5E44F2DC47C8CAC005AA0E3DF7229B90981FAF35F11BA8EE78602B9A3E122F1B9E57CF54375BB317B3AF1623A131521AA77971C0303873831983F8E252995A03336AB33B8A7EDB4A81CCEC376B9293387FAD9FDEDC0B79C46D42A94121AB6A9FC25230D5433E012404AAB472FDD008D87E10C0DBA9774F3DE93F86BD66308557133AC6623FC77704024FF63C337B5636784B4E2457EAAFFE3DE4E125227FC7E64869C688960C659820B67DE905357B4C816940F28C3B8379B1148AF47DFD84979C3B39069F56174982912457ED1DF33401C12ABB79423DFB40435426F17A7B999214F1123D00BAF37342D7E861DFCC2B55522FC9DBBE2F55D7AD73B770D07068E270A2A4F41A334D6C7D85FA392E9D74357AA15F98D73D0B0FBD23213918395B63FA6DB4F6DB19B5C01F8A404EA9764FFAF97321D02FAC636E81C964C8B1869B8592BEDE32E988FEDA3F7044D95E37F1098251E4EA087829AE2BC3DFE57D7ADFB84CB8C115325334933E1C52273C3634312BD5FE72F173C7B600E44EB2B363F08DFF5259FD676B0EEA185EDA97C7E025CFB46C80CB46DB56184A6DA09DB238D13ADD9DE87C7FCB195039D2D761E6746E1953F09B9F5E5847ACC67F30CAC3F002C1D65747DC10289A46F7881485D7327360E432C9BB978FC38182B756F3958CA73D98FD16F9690B019AE8FC610D6C9D6942C2C44E41DB400541CF85482BD6A571677FC8028E7183785063A425A75091455D5EFE6FD9A4D70FA72F541D76E54AC7558B5D412605A6E5466E351BF976F29E4866CB21DABBFC7E1CF32C23567E230F67AD57B55DBDBA2B01F87ECCCAC4490F03CA5FD2CCD8F6A97DE46C66F10E97D5D438855C9E83DD87DC2BFED0CCE1ACB5EDAC96A1A30B00C7F870EE9701481CA4EDF224F3AF0A8118CE77DDE2AB046054C2A6B05AAE6309CD52A0218245A64F49EF55C14AA3B24E65A21F26AA5C7FFE248BF712F77B59F646881920AED9BD7D8D5F2411821ECE61ADBA189D1C9F6AC79C99D33CF9FFF4107BB2D5B4EE05E9118D95F8047295F58F10B4E309BBB8B1DC0AC771DF706C70DCD05E89049179BE6F71E5D6B61B2CC5AC484B4453BC1FA1BEDE2F2F3C57ADF7347703FDF4BD3B2A62BA57FE9EC3F1D147D4813CB6884037D7677DFEE8E3955517003D1A699CA99C1145AEFBB92019CB7B44938CCEF7D00956EFBF528AD0A6478194D62871B45D2B9CD7B4BC6EF5BFE5620299CC72F9909C051E983D7614032B4A77234863023BDBF6CA1B9A8399AAC020838A13CB839310B352AE9C9BF67A51C9FCC87048444E7BB82FDE63EBEE2A99674E3D49C8972F1EF68003F47351398A419EE619C4B7C4EA5195F97EDB480AF58C89E876E52D2043E80A99620E450CF1FA841AB658A2E772DF8A5FA8EFB9798938193948CBC51C721A1DC557EAD943B7465B34C93E7C15AA7FDB96F11B5B15A65BFE43238CC5683C5CE81D50E44CBFF47134CAC8FC10877E4045846CFFE4D9393B9E67829787FD91A2DC3B482FF4A75A207CD98C8027BDCFB7CA55914B26D78CC5802D918C22ABA5E95AE0D186E6A02EEAA69E55EB7C1EF6683D301C354D11452BAD3EF7A355CE394C3CBF986F4DF92BEFF187EF32659078B0FD2ECFC71E74822AEAD42E020D8831D4E676C80C82EEDACB6A0075E7D6203BA4D3EA67210B00045967D8BEFC515900C306224D85AB912C22D9912C3E06678E2ACB5F488D106EA0C959E89B4F673D89F961283DF3D74E22315797C8B7C89FD1FC8011F70636EB0FDF1734D7513F94D8CCBF808D5A0FF0A26205B3A71F6CBB82A761CDF235B1074ABBCEF0FE4C4D1330079C1C326073090EAC172696C584DE080EA8B4BE658B26370014497C38A8CD862492E0B62CE45EDC9AEA5DCFB5DDF98103C280877DDC81D54C26765CEF43FDA32892A7B9E113194C3B902E907B2C41A53FE9B8A9E60649B0E8CF746671F1525ED9E57398AD5B60B59EBE1FD5D8109D6BE635A186F3F7EDB9B233F191B0D38F99E4922ADEC45A7BE20A6DF9EE6DDBF847D7E1FBACA0D83BFB13A4941033FF51AC1892C23E94173F85398C06D0816418C29E1962CCF0A3004FACC78087418E0ACD2BAB0B4D25DEF5444130CC93CE62D62FA62ED95FCF73B588D83779ADBDA402C83BEC861F5896D92AE20F1DBDB7E4C7DA14BB1A81189F2C9A5C62AAC6DBEAE751964F9BEB24B97AA71B8A4A610BB10034DF3E6B8A98579F15C272E3E404CFD2F33DB7A89CC0F68ADC9029B80796E4C798F8605E59D7CEC8FBF4645A099C64A40B75EB3C824D5CD98567E06DB9E24B7EDE00E1C2734E28BE1C69B5A0315642D15D0E53741948ADD056E2C5A120A450D65B227550540F58B319B08D55109580C22552BF46BE3DE71B04BC7BD1CE7D57C3B052AF354FA0F90C63F5B388A0564858EFFE79EC73BE7CAA54683665D04CEA3A0A0BF75E191742BF0EBFDC0319744365DE8C1167622D41D919C629974755FCE629E1BA8779CFB4A7CAFB112D3AD4D38CCD686633F520FE6AA2CED9FAB024BF1F13C7728D54A49D6F772A87E0E47AD63CD2F3EBB58F4F9E8976E8A311C14A9605168F558246AE226023695FF5ACBABD0A13E54A1A53A03CF30EA3CF7E6B615B93479B63AD07192A7DB59F2B650477913BACC4085F87AE04BAC4569D5E707752F0E690ABFC026529D29EB4507BDDA65F5C0DEC1FF25839C4477EEC97795CC7F1BBFF9FFFA7F422FC4AD51BEE8ED434791167A6CA3BEF366003F0099CCBDE3723149EEBC956E1C7B490F238B54CCD2AC7C19BBD90822299B4F5FA6AD6F1ADAF71EE65FBD1B2D1E0567DA7DCC6636BC0DA1E92BE70AC75071455E91C239E52D9F9560309261F41EF1182FDAC9E47B0A404BC52343FE0EECFDD968C7294408493F7C9E2505EADF3E42A7B1E261C486943436F702857A33EFE05BB1737610C4EFF71D941730FF7A77DE1E5EF0257CAE318E9B78AF3EAA5B9EA2482FFF5B39C5E7E693BC9E66C597B7AC73586354237888D36F4C5C1A2A7E0C9E809ED4EE39C0A7AD396A2CCA0A6AF60E5C78529F893B3592D275F3000029ABDF68F9CF0A32C50DD06575FAB733978C0F0A0FF35903C578F6B59876013590F19EE18EC14D2AD693ADAA3C92EF4A1A9C61FBD22B8D67A98EA2617292D3B75BC17D9CE1512DCF5F47E6FE500E5F2F94E4D27CE083A8FBEF4F7BE479FB0B4BFE84880E6A60B203C81DC04F9AEE20A641A01B263080BDE6EC021407C7F1823162EE44EBD94673DE5DB5FA5C7BA4E69008C75E15B1F7BA62BEDC28DB3683DCEB5EBD719BAB6E6BE37190E0D7139F78611EC6D157E222097FCF4359920AA58F4CDC56D1417EE8D45916CE055C9C3459B6B522A566AFC55970BB6ABB2D9D2A2F93B3191312C4AC2D56EF96FF3DE000FF9C67ACD1FE539175A23F90FD3C7ABB5C25028A688FBE4DAAF7A8DB6CFD531ABA7C8FC3CB9836C4147933096FDB4065B7A88B42CB20872ED42F159A2F70F7FA1740CE45D2295DF32CBC8BAC47ED2ED56DFB5B60F1C578612E0A0EDA21C24585DFE325402DE9840B649F2F85D4C62E048AC84E56B555754E68F32D25F65E1263F54070A6B3B9D6D9EC094C4D507EA6ACB8BED02245CFE8383F9AA2B6C8FB92DEE03C676B739AAEF40E484C82FA0A272884BDBE000000000000000000000000000000000000000000000000000812161D20272C32", + "reason": "z too large" + }, + { + "tcId": 37, + "testPassed": false, + "deferred": false, + "message": "81E44E2A69141D37CC4865E66E763731779F2CE35F8F88BFE8DA1D19D85C159304ED11C1C156DE0305E866E8E25E996DCB0831625E790093A50F804817221F3230474508E3033AA8018A5C60232ECF6922343BF78E45DB49F6F5C4FBFEDF8E61488916B2C7BCA20700C0A739C2F6886A0B7F27A58367BC46F90DC5860A3A69A8", + "signature": "1FAE6DEB76E4E0313CB77E0F14C21A095AC11EA26C1E16FCB316ED13C1356746E89B6A14B9172A8047AEE85463B63670BD3D5A9876452BA25392C07AD179484C74F6461DF5C71149F9FAD28F43471D811066BDAA0E53EF8B728D14D8C557924C9AA7C1471E31812F0EE86F4846710B4F50AA693DEA909B1CBBF62BF64A549A7AEB38286488BE3A5F1D70D467E0A89F585B3706375FB39BBF878BF940BF4EBC8B14614BCE154D726DD9668A62A982157C444FC972885F36CCA9A7B825A3A4A627027B3249CF91DAC34C07DF076DF6B34C85A97CD5B50C3C26A3CCCD72D8E9B91BC328E3D487E6B50DE028AB628F1641284DAD8E6FDB183545A37A55F2B2754672F3ED82C999DB5BCA4AA96357406C8C04EC8327DD1FD1E5B0A6E8385339ED420437B541C48C058124BD688B70F9E0C433A8FAC5EE812D1D11E61FE6487B64BF0A998C143F7F351F2A2E954CE402B316BC678D4812ECA7DD749010B4FE4D5A6E5FB05558B5AB395794DB3716E7104A0A3D9DC58482BA461E8938F7E01C267D4A56CB16A4530DB11A2D63A87D9AB959BB54C601B1C9CF785ED1AFA5FC9DF821EBE779D8AFEFC5222D4BB23E096391D1A0A774D272245623546C8B9BB6FC5461740DEB8E8AB350A83E779C6C90B50E7A79AE8005FE23CED67AC0551CFE6B55594951FEE90A1D18601D637D086AEFA9890AFEA64659DF35C7361C3A42A5C270EA58D5E29280C62BF62DE181FA57E0F99702693FB678D6D0033C4CF216ECD2290CFDD9C902DB756A20D0E67B3FB4D38953D731292BFEF03457BF5A05F40AEC5D441F695D169F62074D8BD68C1F855EB52E0224576BC8BC1B76C6051DE5FEF9CA18D01D1F693AE2338DCFB6E860075FB4C75217438AF492D2D55419084B09B2DA80BAE5D41574957CD5BB7427441F2C13021AD851F794C5CB0D18838284DF6CC6BEB466F65EBE8127F77F2DE2A3F0EC4F09E288EABACF101149851F985A9EC9925DED8A3845292EEE1062EB355094E4C5982E097A1CFCEF4BFFB1D9BE16EE184B307E63CC7F2356DC807632DBE14FEDF602801AC77C21A34ED5359EF3D60D9CB370457EA89EEED425AA9A40237265644BF5FF3E114878145A118DEFB1C013C17DBE32DCB53F0B4DBC59EE4650F8C69A00A7FB532955448F601FB7885F817AD83A801F43BDAE0CEC3ACD4910E839673AB22BF91035C4C52CC2D25E43CBEC6DA80CDED7601E1E9C32D244F57A7388EFBB79EDCF66D87900259B91D42A8EF7DC5D5A0CCEC2027696E7B3C9D37A06817D0586FAD9E8B4AFBBA64A7ADC0B8969EE9A971A4E5E60DB0A7F32DEC3439515CECFAB30E4F799F2F0386C9E28A9FD50DAABB37DF38E034873BAF5D9839C4CC7ABE73D0D92D59995EC37F7CDBCE32CA3682A9782FBB446FC27DE2527DF7099EBA7DFBFDF750587C78FF89FFEEF91A2FD467020A35C05336B73611DECE1BBE59ABC5127477D3D6AC3DE6EB2066870E1E919663227848F360CB9132D7C0FACC01B4EEAAC0946FF96BFCBD7711C41397E952ED169DB0E63C73EC1FEBC62948EB32793EB1DB2D19597BDFFC222665074489876F221320CA07264AA8F7314569EFF7D249850B8B754F73C40617BB8B8B8E442D5B2CB53BA3D1511C63250F7630E2B09ACA8BC178485A38B0F1F2D5C7EBE66ABE352188B10A1E07DC2E7989C6CAD52239703E18A7A2A5F92E366CFE7991B0AF9C27F77E7F268C1D5A6777668480BC0F616EE35D3A81A1C72C75325693AA418D5E52D622BEB1384477954F662F6F913203FF3A02AB87CC8539FB9A11266C9E0F508593502DFAFAA65FA8BE0EA5171C06C792D4DFE99E4B105E0FA55CB9A1BE5EA9F201CAE326170CF4307C648CAA2AF0655793B995E2DA5E1C02097621E43BC309A4F4CCBC919EBA6E4AA6008174264A47AE24B23C38EA67807215640193AD9C688E818E3AF38DBB84286F3D1C950CCABDC27A020DECE6264A15B9321DEC8448F5E74A2C7F7AC71C95D94B63972BD06D5B5BF39BDA57EE9E3FCB7B81EAFD6365303DD7678CD4FC1014A387316FCABCCC24D1911E4796139C064D0C8072867C95E5A167DAD38537CFC7CA399131CB0741560DA001A524CD9B72C9B41B3C0CB416885F3CC6A963E437F3BB43530F44C28693C20997FDB1D57D76FF2DC42D22ECDBCD1940AD2F2EB3E0A2AD85FF062E35A56CEEF8E58045C46F7CDFDBA569FA7EEC4FB6F741E1C799B14409131A0CCC0D370C7469C16A9F45693FC7F26C9497BAFEE42333EE3E75F44D4FBF83C7EA9554BD97D1202A5A9A5183C453DE9A42ED1E68B68DC579498D25A5AA82A27837146C0B88BAED74235AE59DB5C4D1313B899BC7F553400A931340C8E6DAD468ACFD2652A6E07B80DD2D8276C39ED504FBCB8984A8225C546EDF9316B838A03F118391FB76F46D10F92BF1E90C59E30109DCD8D72D2A7827D5DA23551F9FAEE61FE57FB6BD6D614D9E14727E0B4F040064D21EC3FCF94F059E44129D47C4E32C9126421A32A0C67866C4BAF624F959B85BFD9CB83342CD8B765820B9E18F49AE4C7D471C80E0B91765A83F0A0120CA2FF212833E4E0A64C5C8AB6427D40781965EEC92A9B61A1668083B22BC2C422DC4B9BC96EDC75A95E180A78F8675C3EF4C23687B427B4F33AFDCA81921752DD4727DE2E53B0302390A4341E072B1046359EE421F2451C33BAE32264DCE824E6628CA6A2087C434784D39B67E0909BEA410E4A7736ED93F4F9ED6BA9B9379587FDC49825C021719D762CFCD35504FC685C0CEBDDF47E528F733B24ED1A3107C694CF1F7AED351B51710FC872B5A74FD7AF8C51D867DBC44FA854577BFD477A3B12EB6F30E01E6B1CE3B88774543BCE9CD9B38FE9F5196478E39ED88E122C60FE5767A2B0F124F698C5F8E916DA161FA48715325398E97A8B7CFD222225D6202296D89A1CFC3FE99E63819BA5A2C771C4DD53783908020B2B6D04D19E43EA178C880F2A740F4B210005132568E0CC25BA2B765318DF5C9D7721734BAF1CF8E16E0930F7CC658F1F3BF63FA9385BB7D42D72741F2DB26CC8648304C444E3A8BE6E4330D2099BB6AE3887C56EF0CA6D05DA6A96E8FB9AD33C4F31531EB36474258AB81663FDB29C97D1E5451E48C242C580B6A8E7C37CF998F10AD9D182823B8CDAB95FD2FE21C057363F0A96898F835624461140C1DC348BD762276F28A2DA880D8486796516E024774EA4A8213CC9705F799920F6A0D8167F7ED2F7C10B2D39CDAA9B5CC374E532E9E04CF5C26FC4F75B0D43FCCD3F5762E9A2CE203BBBC9E2042484B4BCCFC06587F4429A18BCC17AFAEAADD99F50B672EEF75ADA07B16B4E72E92E946A369343CD39303E06D1187D9E68C8E8FBCEAE47C0D4DF3DC9C804C8C789FDFAF233ED9CE2A8B4A3E4299AFB0CC82C28B3B6034B109F882CA2EB041FCCF4E40EF5FA1AB3341B12AB59A230519868BD2E547A1FC3C47ACAC9AE515B41F053071DB21309DFE6769073975B1B7731FA072D958D2850EFDEBE253915A90B6773E714C9E907C057D0AD225789A4A293D6CCB718BF9467E5840B585D0C4C63344D74B7D735358E77E1395A578F9C8FD615004894958118EA422FA9398620C0513A1815504ADD0DF7239D5ED48C532291E68BFA47F8CFDEBD73845A96532A0153823B69280C33FD24DC1D44A1C180B6CF0CE017BE10D48D5238D90C0C168E7E50F53BF8915F50E9FEC70397FAB98D4496CE127280ABA40AB1996CCC80B106AB5790CB1EBE626C5039F493CD10D5BB77405BE0A4691ACD3F2527C18B9FDEC56878F258B396A6C0E3F5429179E447B21555DCF9E6C6864E137C478F475681193AA52C99D511337357ECBC461E9EE6882B9318549CCB238D8B1D82BDDF365AF2C49DFC5E18E175788A1F8C679BDC43CC96162FD2EC70EE92C3E967B76CEFE507E0855E05D85CCA7EE0C181654373855C9541659A4B5C5E27F1B642E9DFEFED3BDCD7B917415BC6BCD7EAA774D0B9995905AC7E5F8E703D7EA4349B6BFE47139188F831C82A2A202ADA71584744F6F3772DE98889319EE9E8C83D1D2ACFBF05301366D5F447FF1E3F8AA80873662DEBC351226035089ED0BE4143A055D3FF006EEDA8AE3DBDE42A033BA067B2770BA9E4599353E928CA61A1A1180F715C6EABC3EA72C05DD16151B8D23DB12420EAEF8D11F2703C64E9F0215B278BD9683C29BC0E66470A298058762F822625BECD3266FF5444ED2C6D91D090DC0491A0D0AE2A5F2F36DD34532BCE4A5BF07EC540F6393FC18E61397DFC2826BE2DAEF6FC74F6EE8BBC46D57FC4CB1B1890441074D3AFCFBC72F1E88D7E27303AB82050492E061A0DE93219E0E552B3CD45ABEFADB711778275C9EB4CDCF92C84D78B59DC6A1C273E763271D4DB5E697CF06BDCA18BAC8A5F29C184F8530CCD4443AC12BAE4BFE68E70C03A9CC729A2A977A484B6D19B03BA8507C1A2C04B58F8456038918BD442C1AE7D18159CB78DE3A5BE89310BE8208ADCCF3CE6A29008DEB15081A1B784215DCA0423DB82661BA6189774F908E4BA4E851301C657FCE5355AB5DE06634A09811A16186B22B7FB65AED16CEEA0417F0C85E6C2C3B483412FD35BD70F859E95D8C9EBC51E5EF3538F127A07CDF85A472427ADDA5734CFAB812B794E3F9E3E2EAC3FED574781CF9D4E1E5EAB72978F6B44D9299A225D25C338755B473D0FBD0DD5FC1AC9B6D1CA09E8817C6F7EF2E61E8D70E347E331DF5813CAD79426794278B5B832AEBDD058C2C6DF73150A798484966E6FAA48341F5012E7C244F818F4CC0FD6C197431C804A508062E46BAA14CCDB86C47498AE84CB3D759EE50A306DBD947DF38C95244BD0BE7E6ACCB12EA5EB588DED383E01E2AC820CECE8695D96DDF76474025C155BAEA6C77E8B36FCA710821A2402FB796B9B5300C9CE6F80BFAC600BBC4F53F173EEDC1184F7F641D40C4A9DBEC9D7DFFCA92CCE1CB8C2812032DD2E5347F61F586DAD275B725807A624E6C75D2A4239FA2A4166794FFE63DC59994815732B26B659DCBAC5720BF721D483553F86343436B8EB29916D8C37484F179BBB0B34FF1C2C4D7144B7881865E1976D25BE8FFD692344E6FE2D506E84569CA18C43222675B80E88E35E25A9EA4F1576B51A224AD5AAE126208F71A572DBB78F9DA3E581DCD28DDDDC43083F20F24147AC9220BFC2CFAEBB4619DCB5062416D7DA5C9BD09E5D62E3F543D39F7D9F97FE6B1F4EE7ED5609283752B3B2ECE22C12E25D6EA2CBDBA4CE9A92FAA2020550C5CDAD05F7AF9186D9E6C6EA80DEE9B8F9A491A55FEB52FA858AE349398EA17C06CDF14CB45677A2159C99784E5B562D5F5BD25438EE1311A86CDEAC43DF25B9C277248DE1906CC9F1498873419D333A42EC1D57E2E46561B30A6FEC48E87DD2ABFB985C23407A6CE2593A28195867CC9243E06A71421535407E557A6138A6DFCDE0C12A8CA6E11A830419C666A8983CF111527099D652B16DB643C14B511B91B08ADFCE3FA143F754C4E225A1619D2DD11EA4C89AA3742292BB3A33558A31C214CFFC31C3FDEF0BD735B5F39692D574CD5FBC0809228BE223C73D126A92453DA092D7AB01BE44E2017D7B8C588FC7AF41A0BDC66AB335A0B437BA3BF7E1218C71C563AAF3AD81DF557D767CBD48451C1E6DCF30C7E8BBF73938AE9A0C0D27505CAC3AB8957506F4C886CF7119B0FC00738917A28F4FA8ABB91120E7DF7B0B8EBF07F2B5D5F2607B68AD4C3ACEBCD07BC2123158AD577CE5D02DC2F0A8EB0EEC1E0196CF4FFF02015F8CA74A8A100A8CB69C6D67B88E0F8E3F9D360DBB4927DC3E7B31876661018FF9BF6D0E181C3266297890C541D1AB9583EE1093507DF4970F60B6BCABCE7ACFE79FDC8E507CCD3616E70E6FA961EAFCA887C0BEA2DE39F205C2C5667A4F09C151BC695EF8E90FF3C2D22AEBFB2F78F7959E290700C1A782ADCA186C5C6D9719558633DFBB217A93395985C9C7235D6BEB4475E74FAB80F117B938FE06C19B763946FEB44461A08AB448D898C9C5828DA0F2C639020A9F105F0F636E76A7CD44BBDD4BBD2247B6356CFF228D81F151A8FFF5FF7F3F954059DAD4B0B4F5CEBAF811652AC5E1B9ED5191F9B7A90FF06619461900F0194108230B97AD061AFC44F4F61CD6C20157107B29424A1FFA746A214485B95AC87E9B070E63CF65D255943147837EA8F3EDEA4DED3F7D8A634451ADBAF1C86F7D46729D0CD87D3C1AB946D0FDA220BF97387C75457C96E1F3C0D0AC4EFC2514EC309BCF035B51C1146C4F87FF09D151202EB7E410BD8DF8D096575A180D8796E746197DD9FCDE9E49BDB2C98C66E88C2C2E3D61F0FA66A3703A8624D9A1A9D8CE2E701BAE19F8968E089CFB263DDB65A9A4BDEB7D643DA19BE1DDBF331FA36FA0F656734851C62E699E593A4872FE04203D74D01109553D8368F04CC4C6FF3B5E73D2DDE6080F23386770D33C5183BEDCE3003FA6737B7C84C9F0FF105A91A3A7F403344C60A52B5264CFD3E2FE0000000000000000000000000000000000000000000000000000000000050C12151C22272E", + "reason": "modify message" + }, + { + "tcId": 38, + "testPassed": false, + "deferred": false, + "message": "9ABA3D051A7E3E19E6DBCBDCCE6677678EA0F88816BA02140AE5FD27E0A56D38201E7622199340C0C8B8640E28BD6D318B6EF56F67BD7610DD57995A3E06D14AEAF3993C9802D5841060458DCBDF6BA3403B2DB2F0572CB95B0F25EF1750210D452FEE9460AD6DB821E5C79477D2200346B0AB5F14177AD988FAEA06BBF769D7", + "signature": "F8B96BA912811CEE92B0D15D063111FF3775C2A96BBA5A4F79A5EC6DB47F2FDE21B64B04EF9AF9571D2E189888C2170D8C35DB68EEFF492C68135C6FF69D0E4D3C44843A8E65D1311629600BE1D6B14682B54187D5D75D031D0A58E1D63D832505AED81313210B4827835CFF0CF4F31A6195CED3C9D741AC745BC0A70197F71056E15061935366A6CEF1506A3D9584374FA9BD71B0576C6A817CA9DB909203C21FFE1733B0F35C470F931C52010A3478E27DA1987EC9CDC814EAF80958906903D1D8A5317874DD60200E1DE802CF261FFC31B9FF76204644953914EB27EC07DC76932366B48E74A517C995AD3C366DF1722D6D9648943D5B3396E57B97F8E5ADB1ECE86A420228E3E5D3C347000C2FAB7B1B6FDA0DAC86E7631B1747D7533AD3C8B6CC9E2536784CC5AA30E42150E19149D133F6DBEB87A0D9DA69CBF3835FD61D380EA799A619CD69D6D70CBFDF300ADE3DA903589AD4E3CC7B5547BC42F0E33363833B504DFE925F3865202C8952E2DE0F13DC0C139A153D5B9135F1B21BD8DDE1211018B03CB09C8B02F883CA83A7D02496433C57E16E039E36851FBCDF78866ABA9786DBE8DD3FD9EF9B6C28962ED85C2B7CE21694008B41E3D5A8C4574E13F065F78D904DFAA5434BB8B4A9B05F2006B7DE193BC86049F82A7D849D071112974AC9B14CEBC65AB56917B3945C124CBE803A31ABDED9C9E30F3707F2E795974FD1F8881888135FE3E10EE929667D6FECBAFFBF0FE91CFC9A8848F1AC941D163F92639C2F056C6AB3E26775CA383B8985F23AD599FC746569593380308E6A9526A1174D97966218E63223307257773670798FF8840CDDD4552C6CF4324415DF1E73E064E6C85598AB08955004A796C7F74EA377C23C1C426ACC7356D81B4F129C1A8554E6E05508D0E7B3305232652DEE0A301F1C4733CB370E2F099DDE24966B87E559083ACF965319A5CCC6631EA195CF1188A2DA1B63BB6BAA9F35479E2B48601146CCC422403272F28F65854E480E51D606B3DD2EAE6F104D30351BE4F2690AABF139CF4F8ECEB6EF0D2EB08D9C1AA63742AA45006F2D7F486E752D985AAEA54F9E176C4844C9D0B3566E46DFA7C02FE085B0D04C67532401514DB0C0BE8CC0BBBF47F319F6B7688923A93FC0476DB7B6CDA5CA768E4B7E4C973DD95268A3D3AE322B5B34323FFE61C4598C71705C59B68F039265286187598DFE1E45E16A622F6E75AE5B84D6634A4EB6C69EDCEDE11D57B1E4EBEFE7FD1ABD578DF8CDFF0FF7E957CC35446101D6CF372FB230A9187CE31D355982DD1E174B4C6C27B08C2ABDF81F2A4EDF67D109C22B5AE15775279E549194A0D84515976B19D2BC852B46896457C0EF7C5BA08AA92A671AA461DB21C6857A5E42663B822488BFC7DEB452377CEF9F96429134E6EFAA01E45017E17A7C66A15C4814ACB051358E7794FE676C0B26EE96CBFF0CAE8E3BFD4DE21671658752916EAAAA433ADDAC6E8611E2494B1021C7B63392B15214BF1F50B758EEC774038FA6040B33B33AD6F0A98603CDA952CED33C812D45CD299AB38E25EEEBE42AD90DAD1CB64DF58321F6F26FE2AA739130BBA3550602D3349864D7039F2992C94EDBE8ED8501FB4EAA8919C421247BD280CFBE16A3CADC66EA1986DF5B753807020D6C77C9D8A3D42CD599DF41672460FFCA7AFD80FB2F1465CE208A69AF1B84C568271BE21DC607B6302A9D234A79B510C49E3015B3E2D5BA9E073C376AE251ED255C62AD2469839E1920192674EAA995519B0A915FCC38804CAEBB56F8398A46D89CE0C1CD9240EBBD154B4AC9A0F28E81371CB9CAC75A2CA89645519A59D190A677DC8D411F1592CBAB5C8C12B88DE3E494E8272E7104EF6B9D7684A727A73C6B2D099E588624693D23EF0DAB2CF27924B06D2CA6056D73192B89CFB3530760920669A966CBDEE3AAB9CFDEF82D662CEA11E57BFF4BFF5316B446E5643BE03209E1EC4DA6D7060D388FAF2513AA04F37AADE5FC87463A70AFF8B0B179222E5F1B94CC81E48D42A2AE3990243BD0D16526AB2FA273BF003B7E1C76AF28B2A697424280B5A39DBFE9A48479EBBE740C76F599E8F36CF0E5CAB87620F2262545D82AC40CC20F30DB847DF088E8261703AC60BC8AEA56023A337F5FED92EE8BE9FD7ED6738535E489C0BFBADEB275277D4FAAB2FE03862545E18DB5760B6E76F639DC9BA96EE649EF9C67CCD3510762EF405C4AF841DB6A87E794E440BA8E25FDCCA2A947B32E5FEB0C5CCE31E04B75A50A553CAFD5B9DC682852B44A7EBC1924AE7E8C16995AE94DF8AF1638967E531193CD97DE15CBF1FE60981F7C2766C372D19706E9FDB67CB8AA59D32D260B2E6F8084D71329FE0AFC9414E19FEA8ABFB03A6F5A80048418BA2A8540747F7330149FBC1E54526B205B9188BCF9E10AA79E563FA057AA2BDD955972CACA04E21426580270C7174487E5E27778E5E819516C3E1EA2724DA7F421FE1F0F830BAFE519913C9A0202F7FA9979A8A8B40E668884ADAE379AB14CE65B77BF8EDA5FD564387B968E92A5C823C4D3D644A53200D15B143DC7001805267C0C54842BF2D709F7416F6F9461E3BCCCEE27C2395528DE2457ACFA1BC59BF9EC4D4837EB57C58756E98741B562423C40BEF2A5D57A57C41146AD81973BD1820181A275425E77964A0FE88F0D93303B6C9AD08EADEABF6C1C90B785D0787FE06961A5F063EDE1DA0AB5D163AF45037CEC18E3763E18C61C57A5F72E0113FA68708DBD8A81B3DC2EFA834B0DB36B571F4FCA7CEAAF9D5B26FE56ACD77587529E73A2E54B97482A76843DA1648E47E0E4CCF09864EF30A4C1E1825CAAD8B5CD946A4924E53D26EF0719BDA223300F1CAEAEE8D8649E633C18522A678E28F18D964C81A7EA1C51AD3BD461E8D32FE431D6A163708FDB8423DFAB9F041386CDA39B1B6779B5DA551E79BDCD69029121BDE222D2821F1897BF9DAF9EFC5EBFA36DB0388593AC4BB3D5B2B2FBEA0F2913C7F024C36AC635F971D2815F841B8CE8EDB809240C2B5D69A28124AB3BCF4B3A202096AD2FF86E1C67F75E13796488B3E7D246A08D3941DF661B55973CFAB4870B05D5E98E7CDDEC0C62807BB04473669EEA93415ACBD16DA333F845B400A547609B455DC15D225AA3B2599300D59F63FD4A9EEB74478DFCC1E624DE46460101651FB8FFA621BDAF01C2EC0D41DB2A6FCCC6EFBA480EA1256BFC4C00EBC5CAFD144374CF4B45E189984F3E02C835DB71E8886E1F74A87BD565D4B15216B893D7D7154DD080BB35AE16D41200BC9AD818E3F79E44F5718C43C6AC07120EEB0A7B621A25A47785D5905B7272372C11FAB913360416BC8D71286EC68C2AABD611F9E4103AE32323D24434486F82AD739264D4E0A17A9AA2A1BD0365E4CBE9697008614FF730413E2404F3612DE9E7DE7D3EA96D02978FE9ED2B26938AF3AED998325D20CED38A14276BD86F42A8D14090D45B21B205A17AE869F93E6BAFBE1E604869F920F4833F9D46B8154C3BC3A0272A4F3E8DEE1009E6597D50CC02329EA5DAFB88A863084A6AD17222F3E77E964C07DB97A8283C057373319D150A7A2E84D81B03955A2FD40ECBA0EBAC48C300945D9BF862F3BCB98C124DA0F83CC54F4EA75A184DF8E035F62E96CFFBCAABCD5BEDB259131EC5AB9C65E66A3F3C0ABDAA158CB2EBE18644042E05D048F044E82A3DE759D54773F643EBCCF7251159BA8ADCC4822C1DCDE92EAAC056D13074BB00CFDFE60A22EB685C6C758B5B0562FAE7D047FE43A22267554996250C0E56CBC5D43831C40FF8A4BE41E990583348DDDC769C2B4D12C8CAD3491A1E59A2A612A56159C0AAE2B39F4FF432946ECB2A206754E220F193F0E4799A05F954EBB2CE6512B95C0BF3FC8ACCBE5031F367BB9C6860DEA165362C86103F1D8FCE8525E9F98DCC3C152DDFE24DC939869CFEFFC367012DFD064F8D1ECE56225D7C54BB11AB48C1A3A1E092BC92F683D75915A9E11ECE7775858EF2F844CF9822EBDB5DEF1FD805DFD2FCB9DC2C94F62A7FFD142229FA890E6D066BDC0B5E253346DCBDDC6DF4E4D81C218950A7DFF0116DD8BF2686873D67B2852BCEE7918FB6D64EF099AF1C5962A2DFDCA5B63535DFA82CB7023B201429A51A02047870D5C99EC90D8F3673A75B78F20B89B91E323A314C9E0D13BCFAD427A29FD6F72110800C772B0576AF15099C91AB4220678EA6737D9932666B10F39AE5861287562D8D60E7A3EAEFD8085EDD231F2A7D91D9A1218AA17FED7157B7945B582A75A4293F087FE3AF3C5AA8BC85A14AC00812CEE5AF591BAEFD22F22A3B3C3BC4FE04B92AE41B3738CADC1ED4FBD16A8E5A572B79F07AE4C468C34CC60ACE8FC6CF02925886B511C437FD01727B21E8FF06F2F844D9127E2BE7969B9EC0F09341CC2B5B4843C1FC7C1B23AEA33BF2831CE5A4D94C9291F04BE6C87B37916030AEE74D8F97BF2E8BACBA220C8EB2D2EFAC748E2315B52BBEA898DABAE0A6421FBD2CA75B041EFEE67BF2DDBC8EA31131AB105AF70F9F92C566F675E2AA982F19783085D3822DE6732212558FE658ADB36703ABAF9CFCB4A052FAAD081BAAD616C05CB20B65B540EA8F67E83429540EB71E5D6D8283072A09CB8A5DE291D0DD67F67DA1B11CB7F564ABF248BA6B6E427F62B0A9D406BFEC39BB4AE854076EFF9876A6EA052DB5CABE436D292C10ADBA4F445180D300EAD76471401E29532CE949732FD24779ACCA31DA03D41A1BBF926E1D8E9656CC02F0EA60116BAC17DAD90190C65580F70009C82D111EE70FB5B81EFC94B65648913EAAF79423BCEEE03F76C4C80600B409771A8F0EE87B309DCF15F432B2388B4D8A3525D3A31A8C7D61EE4ECBB3D3247E6A358C23CB5C1CFBD78C3CB64C9C560D355C8A5DBAA916D22909458BDC0EAE6A92443D3EFE3B69B443013F3B5C0F0BEB32CDD46E58A4D5F5D7B8891F0CF78005BBD04460BC5D6023A413E9B709E8840B322C2FD2EE01DA490B903469D60391FE21D2FF21222FED1DB2F324176A9DD403C1888F68DE34E5A420868F013E205E16082BE0FF504E8D0A7A79250D7F9A38CADCAC8A4CC887E6AA50412FC8F4C358920B29BB09551F21B858843CDB7C3AE1536B80E0082C0BE3C7C48DD08AF37AEE343B30A0D3D68AEB2DCEBD57E4EB7E71752C422D5CD0426C6538B1FA74FDDA2F7AA7FC57AF89016FD32FB63CFF54B5E2D4484027B8A66E0E8C3DCAB404EF02EC1DAED9EB8C234D49ACF3A92B43782C86AFB1F1A6D482F0B78D1F7DB4BB7DA4BA27939AD0A744137295E802320DD305FDFA2CD7B31011E9FDAC312EB6A7A4F1DF3EDF3FF3973AF627B6DC6F1E8A0EDAC416D1CFEB566F73560EFD06C0BEDCCC0A9C14BE273F1279A962CD06B04AB2F7B9C8C05F9D3A5607CA817F19890D4B9CBEFAE9CF3DB58D1AAF3D3A901DB7E6019A816EA1A3B10E4ED7EB0D89526C14685823218113DDC4FBF5BC73165A08664719B7DE597E45994E92B667A84DED5BA2BD0CE6AE57B985ABCC62A81D41ADD31A4A6B3AC1ECD2097918A2120B1118262FA112E53521F1BD55A5BCE15423B9E15FD1676B6C2B71C7ACEFA34E79E7674B1C6007859CE58700D1D5BA8CC3600C606A954873060038B21BEBBD6333D6632405D7FCC7682BD8444991C51EDF01097CB889E6958DEAA37392854F30A29147F317A25CCE4CD6CCC5FDAF4D6AD0FD9CBF98EF9B047A5EF4B7904B762577F974B4E04AC516ADF0695183D153D5E321A2EE192216087A3B0F3AADB81B64BC7B5A7520129798F799ACFC2FC1278B2CAD8E41083F06268C17813AE37A783B0CDC88A08329B161774DB27A1FD7826959FC11D494C6723F99E38264C29CD1D6AC5407C51244E10E20140439B2BBF4AE9D60889B1A484972B5243D0C17D72FC0716F0E3E38244A627BAC2F1E100D4F8DEFB60D55CD8CA28C3AB55243B080D1E528A61805E943D0278C126034D1641EABDD09B2DF1FDC76494B1CAA37C7AFE153D6D5077E616CBE4D7399C83DB15F1770771BA5ACF40802B266FDCE07240D2E149566A10C64CD42D0BDBF21F5023FCA7E976EB69E976BE4BB5F5DE97FC688E972D7DDAC853F70277E42DA44AA1D800445A05177052A581380F65997FADB548A350C398F7F076BE8E6135161268936CF6B90AF84850FD1C849AEDDEC104A5ED9C4723498B88E0375F390F14A1FEC03064669B3D08501DFB2A0C26C755241FADF278811E6B5A6ABFBB6D72447F55EB8F5F7C9F7759A1386D89FBA1DEDB048C56A5013F30506B226348DD46F45FD173D6814712DE2708D7345B9B6B3EB251D22EF2E0D2256068DCD3BA2F0327A20C9CB5DE5C86440BD19DC447204EFA578DBF769FA022DDAA02ED58E1C3D02EE35E6FD4E13FCB23018743B83F769BD08E75088CD2E01A8A8957C07A99CE305D50DE8FAE597843E102B3B4664ACDDEBFE153B529EABC2E130666D878D9299A0A5BAFF58768EE8F01D39768AA2C5F40F234F59848FE00B38C6EB2A608BA8B5BABBC0C7CEDBF70000000000000000000000000009101B20272E323E", + "reason": "z too large" + }, + { + "tcId": 39, + "testPassed": false, + "deferred": false, + "message": "8F96C963CADFD3585A29E3E7A46618FCEC87D18F54B7F283E0C761C224B4FC93C4FD705D7306644F3215D4527C58173B2CAB900567A37800F43C692F2F056E2F7C603FBCA145A77D8C3833CDB7E6C049F690C892E379F304B911A31A83F18865E38C393DA10ECBF53E747E5BA832119757EC20B76B52BCB59DE1CA6D3BE5F10B", + "signature": "F32303279F880224A7EFB85C7B5769442BDC949700D6D54B5E3A76ECD8EAB821FC8515D215934AB74B2F10EA8648E6727D91B11E0DCA12A1F3E3EA935F7755C48614EE56E6415614542783EB486418A05DAF900774596469B262CA8608A96B267F0C105327AEB9F83541F477FFF4BF1612BA658F3EB530FEDFA5DDF32A0A8E04CA0392FAF2B37823D9DE329C0154B08535A47F7574B9F2CDF672B6CDE23EC3EC972F9CB000B7197F4CBE8E263094A8A3E3CD3F116A9084CB7F03CA76DA15104ADAE34AC5B7CF93A535FC8F8B9DE68FD14DAB8504E9AE3307825F93C67BC29769D5F09FA1630046EB8F0FD873C533CAE2294276CB734F2139724F0D06DBCAF4C3B9E3B8DB72242A77255C0950FF383F0C513890751253B39D00BEC708DC0DDE724BDBE1CECCBD8C77688A98DC9D18F6453E7617FDFD32F454E0582AFB47816644A951702911BCECE4A5146D58C6931FBC762D42ABE0D50D4D3C1B703220C662EF96CEF8269290DBF9DB1A4EA83C23503764F098B1C4E13BB90857D6FADECB096D53772391A76293D2F3F39EF97652CBC721FF4020775927925025FF2C5E2B7837574C60E9D6DE8CD5CDA790304B757D194FC04819ED430C39A79756DB693D0B9A0CB4F9959C21A38928525865EB2F4F85781C8D55EAFD724A2B05D296B182E30064F5C13643472E77C5A9E57C7D3C35B6F9276065A8B7A29EFB26CCA534F03AA8F56485A0B17DA02629494D77B3657E64192C3D22FB906AB3A36E2223D8E3C77DE16994B782B5FC3CCA105ED53404EB672654E75EAFA0FB23EA9E04B21A1E4A9F1812D98B91BFBD9822CE0886EC7D963E25C1015C9C81CB825EAD31C19B00F0BA2951C2E1D3BC898AC34DF10695DE24CDF92ED45669B3418BB1DD9FCBD5602EBAFB5A06FE45A581B3CFF7B948FC9BA3E218F9A70A711202731E21B04A3C1D47D14D02B8FD2AD3032C55072AC1E63FF42DB2FE2A4B7E13C0349B8772F46E95B9AFC058C9A8FA813B752354ED98C68C1E1748C249513DC5C0C12F9C1BE762846B4D60B20C8A2CC7DE27C521BD459A783C37550B478005C6178E41F3E7157C73C415411F03D64F6C84C61C5C492DF74F53E0CB50092B457252ECBDF3650457A5BF08747CF2123B01648C061A997AFC6928B433535E7A0A9F4AF6CB97A8778BABBA06DEBE52ECC22F7C32743FB0FF168A1A42F6C8C9743D84526A5374F71F2B748BB308469B8FCF8C9DC85149FC8E18A5002ECFF106A3DE03D4E75CA5A2BCF0FF08ECAA488940F4B7AEAA23705C00B2325BB207DE4B6CA8CE6625542DED262B4C2370D8D4BAB4A171F702345A129F1F65A10ABAAC7676456C8DA4548B024F2E189720E0F4183AB26C2EBE42349C1A81547AF49C0EE942E429F665366316B493EF48AD4DC5C1C87B69CDDE11AAFEF6DCD7574E781704E0CCB9590C839F44DBB05CA4AC9B24BBB5778C672073082123AF023F06A8DC724FC72B6216D72BFD5A19CE87D33B8F10FE428BA86C9309841ECDE54DC94206ABB2C3341350183B249A99695A38131D961F5627E5871032AB2A823655BBBDF25137EED1CBFC48A964FDF696341469F11B8F05E411C8A83BEF26A9F98CC0DBEF0AE025EA7F420C19BE4D09ACF5CB13819AE74C10C6FE3F1AD08356CC75A89722B50CA5A754E87DC397FE4D8E38FD7D63FF6A764B8C984E0192322FE082ED3B6D5E5BE5C385D03D98321BE49FF1A47FFB981191ADFDDC10ED00BB73F8915B4BA03F7E87E17CE1E6F53BF90B0EDA5D2A4D6BF02E0C3B95609906CC976D83E49D364E9691A2AA552336BA33DA41ABCA4B9A111347145D3C6BF70EF1A1D2CAD1F84618D4958EE680F04FCC59E66364D83205FC72DFC54D94428336B4B1D8595162CBA370CEB8EA4911051F5DB258F110AD5F4286CB4E00B3816FE9DA7C9696CCF8BB6B51E99E20354906EBE996D460BF5BF484CF102221788A188E0443E74E31BFE648A6CEFC3562A2610891A19453D023F170E93178C570644064478EC7814CAD9F4DF2DBF5E6C74B80009A52EAB3E54475D9AEB34EF7F0462164F975390B69C3AFE2D9510331D585186321E06CBC57F5C80B9E989260CF77F67EEB36AF15E2E9E476C7115607F2D74D8BBDEC2A37F3AB6A646363572FA1E1FFC0CC06D27133BFC42C214862CF21F31B3A123260D42CA6BBDC9192C553E97D26874A721F6F9E14708DB2EE51B09E277A6AEA511373DB5F5E0FDA48E9BD153967992C79589A72C9320F78E85F59E06BC4750CC73FCD930C470AB38535E8E46AA85C24B7909ACA478853B6CBE134CE3EA6FC7F559F44F4C4795E2C6B823AB4E5E880BB58F160F621DD56F22E99FCF5822ABE04D8FBFEFE3E82A77B9D47785399B710ACAE177E399F23476899CE5D6DF96329BE6A366F3D155ECFD95D4400FA13E7AC025A8533168879B51AECAD85173BB7E4A2F69F73338767EF8F3E8C9F58F6E1628F8003D328C6F7D5EE0D1DF53BB86FBDE535238EC9EA1CA0BF8CE19DB3BA4AA43F45D7CA77E2AA8707D3573FD70E4AA43E7544CD55793DE76B35448A25656408964E6C64369428C87667D19E1071B038967BEA44FE3333C55D325BE45F052EBB8247FBDB8D64CBB2D4B13F7631359E9EC19FB38C36B5A74955A17B7C3198C8CB77764489AF91CBB16710F6913022A0A1FD3933B824E9A2EE2FA1B0B2E1B4DC03C0EE14C351D8E14228FB4CF72888A559021BD00B496529211AAD4C4C5BE0880A658FBF144C53233D6A0EFD563353E40B44236F3FD43BCAFDE78A634F3EBDFEFC604D4C136099A338FD31D4A0475E14FC8C672F1B9CB726DB60EFD36F2CB93120CB1D794AC1EB0043006FDAFC4701EFCB035C9B53F7DD286B5FEC8FC96DDB58C9F36D9EC1EA660F661B9FC6B5D8A86E66FB74FF7BA446FB9FFE60046D1C222FA6C00037B2C839FBBACA7E4A4CA6A721D2E8B5502AD23218285EF3F9727D863DFC1AAA49F19382C6554C51B423F7EA1CE48A8A90E4F98C035AFA8AB5170A992A8CE672F95166142A39F2DE4AD2FD3C88D9186C6F1CE6F53E4AFFF7E17653465736266BF7ACBCF6DE80929028912E61B0A606C0A75C76C9D3776ABAC8D85839086A146735E4980C030077D4909CBDA90FBEA68EAE87193E7817980DFC8640E74503EE46CD808833398D93191A08F5446CDED75EE1975AC0119779F6223E05FA70F4252108854FCAF18B9FCC56E5D305F1F074A3A20742921F6FBBE0EE1679E30D06FA13A0A21A351EAA943FD848FB2B8CFEFB0083B39628F0E74D438EA14AED6FBD7A251346010980D0168378D78B07299E97458942F03BA76131442771C0FE648D118F7E4CF18096CAAF9B86ED02C7DE8C498A9426A4F39E385A6C0A3FB4F2D97FDE40CFA0617075C8BEE816A977A60CB3FDEDC41CC162216BE52599D69AF917250F9A2839D305023A6D395131130027F1A93D3A2822132609FA01B298CF4B56428407E5372A9ED9B0BA2230705856C8D6F8E6C43EF52322FEE4DA95AA4340F274A58217E3FA5B071F8531F0F0CABE9A7C42CCE6FC3C3B5984237600904C12A72CC93E64E0EC65B236562BC66F93E290B6BE43CC6E828215252B8A10AEAF54D2DE1E40E0BA6503BEBE1AB9FDD30ACEB9AA2E0C7FFABEDB3CE00020CCEC59354C6D1D102DA9177105D7D4A0ABA4D812BB16CE42B264BCC8FDA518ED5B55951E5FEC855708B6FD09CF0D10971B900B23522CE089ECB231ECB04BC821007DC815A77CE6095729D5608F06136389660F34DCE02958E753AA42955ED9EBDC41F2DE8F480C07B95A17420FA1EC4AD952B4CB3D1ECE9EACB599C2BB46CE7EB138E42615197676C301EDA16B088819CF7324174E3E9520970E83A28C7E26337BC084FEFD1B9FDFF2E7EDF5A13A3DCC80AF8F506C6A66490CE57497829C58C3ABB5B89EABBF40D38DECBFAE8A03DF466A1380E5EECF3302E2989E4FE1B45DB7ACEEF2B333AEBA5DF806CE3E38F6804CB6BD32953991E78ACCE1545933DD41C7AC3543C91374E8C77C1EE0A2BB079A41654AB178033CF30271B6ACB7777A9F1585BF3226B81128EB67DDB35CC7531FB5215B04F171F10370BC968B65C6F77512EA8A8A82FD93E934535EC74663130272B1D63847205D4951E27BD8F4B9540B6648DF8F85E493860BA6AAF8B2A973FF3021D60AF5A0B9D4273C129E95793B273EFC3A52B4DD795CE21322DDE228BB6633904645ED74C08B94163E5A95D3E91C1EE5854650F8A8128CF803DEFC7872B0543055257AB908F6E5627D97652687923C600EA8F2CFFEFE640D773E84B33F28F6CB84F6ED92388450A3FF1FE46E43955E8A942A0ACC822963C56BF5CF956F99C41E7926AF9C8752C62C51C1E8F8B310A4399C3BF745052506FC869193EF7FFF5F74F0FEF88D70C579933B85D35C3972D85660D6806BD5B0DD764161E0F863D9FFEFCF87D34EC3F70C1B664D940EDB51D334340A9E4635EF480676A22B1B4C801D56E1B774D4652DA87CB0644E979D10778B1C041B1D90F2E6489E26555E8DF53E0DDD8E658967875EE41D25C7EA3307872F0EC6628C9C636C41A992910FD6C99628153D3DD6881871B7F82AE6F0A6E91CF871AF51BFC38A21CBA5AC463287CF7AFB765AA501D2C0F3FF8DED54F5D446AA3AE16ABFDC122A953AD0D6528F7E30C34B79EDA8DE0C4F912061124FDAE05D60001EDBEE9548C622B538BE2748EDA45DE098F2DFED34F46460DC9DBA30321B74E965C74920B9EC5AACB8661C63F45614CCF92089BD56D218E0987F696A949CB512B53264D0E8B5B283FCDEB78BA2B3D51F46A1DDD38F249619A82CE93EC57A76FC76407F8E5126C5B68B068DE7066E67781C2E36DE9214A260923F4CC22E07CCB78B7B3301BBBBF38CB844E745F9ABC72D149928F999915BE45D93B9966E4863D9D5E1BA79B6B4D93907D08C0E1B5DA2FD80986822E21FCFFB5D17201F1CAD026155FBEB9FBA5F8BB5FC08D5959DE9F42635FF8707A6073B55E349521275BBF7B72B4C1C7CFB6B121DF6CE2F871B98F72303955A79DC50872EE27FB6EF8658A70640749A761C545C4046B12B55D26C2888EFCFCDFF19E020EE96F30E37EAA0A098CDA610679F82F3924A17969794709A55A50ABB5FCEA546A59C49A874792294A26A004F843C4B472837C21AB165D958D86912823C1FB93940200E13E773047738559E64A96DF659439B6549FE542C6EA24A495B1E22F7C115145C5539745496826CA8052DCE4D0F28C55E7CED257EBDBAED9B457F262B7C99179499468CB3CE0273B524EB74679D2569C3BEE69B37E3DADB594BA93C78F69902291AB8A07246E9EEDC98CC0485213C707C4E7BD32864310B38C72BB1C7A9B1A444CC57B7A1EF39B3642FC60ACFE978D9363CE66C74C5066E132CCEB58C32FCF51CEC41FACACFA622354D70766448E5C447C640076119861DE0249512FBC4773412013B194828FF8A8EEA037C371704C4A7CEDD2E3894E05CC6E75410BF3C25B42E63B9D287885E682BE8E5FDF512F9BC667A56E04C094FEA642E7A6945E860775D4A9F88CDE98C6B3BE2D43A7FDC174C8DC35423CB7444F3561A561534B42F8F71DF4936320CC8C40FF791D8E7952D370C58B3926A7969D11EB7E79E8602C821CBB57B6F15DBE09E9D405F2F6CB9F3C5985AF3AEB6564228C042333B55A55EA6C025B80F0549BF32519D727DE5946EF2CD3E6DFFC074D15E0BE93A5F53F531CEC60130DBBF9E588427738AAF9070D7B87D1E51A16720AA4F2088756D2A01C9C5542EFD7756E20CD20B5D9F3A2F55404BA631AE2D47C157DDF29B635F596312A153B620DCF70A91C6AB93895398C3B91133B47E690403E889874C9E3D1ABA23F35A9D914C27D3FEB9053CC039A2F87D71DA703040189DBFCD4CC114C0A8A9227E8B674714EC030BA474115B5B3CDBB20B964A1C12B02D927E140A6C30F1B09C4B3680A1423071EBF8C65FE367A6AFD13255D6435CB69F3F0D339ADD6C20B7BEB7B7D9DD210A587DA87D588F565111F90799DC7CF17214F96E90471413DE85519B882DE15F693A2088BAEE85BB5873B0611ED7FA0C11E11B16CC05635B8B039E328D5400C8D3EFE76A3402267EDA22FF90B7D59E506E8403C2ECD217B310528B5FD30831492E6723AD06522E8B9AE979919DD0429652560F3E3C264E213351F0272FA697A1E0F27FACD720A60621F0A2D5A578227D38A421E0A088306262118D813048E2E763022EA832AFF510A0F93C581E7C80F94957CD6FF9059F72499A2A51796FC1170048C69D0AAE791612AA9F0ED76CE1792AAF06A88616A47313056A95E931F38219BE85DF42EB827FD88117EAAAE1322427600E7B44C58822B0AAC13A3604FA9E6E8D271731949950A5B0574EA668D90161B74124528BC09CD44057DFAD61B43B50B4CF81EB207933C2ED8F7E43E2848E1C5A21097D2AFB407BA94C3D11037A8397A5F203506382A0C8CADE0D2F484965ABDDDFE6398BD31B395EA2A4E8EF072F323C4258D8F9216AA0D4E148516E76A1BEC8D9F3F700000000000000000000000000000000000000060E171A21292E38", + "reason": "modify signature" + }, + { + "tcId": 40, + "testPassed": false, + "deferred": false, + "message": "0C63CCD167A88F14194286F529AC33F7296594D9FF530CF1C7894A89C73FF3569D2AA1691BF58221919AAC325A3A86BCB55F0EA6EB4808ADCCE8C6EACA20AFC574E02FB068E857370C80210701D9D98D7315AA76046736CCDA0952722D8EA1B3A2AD0B33C7FAD15FD6130E2215E2B71E5BF3786CD452738014F7AB3A482D4A1A", + "signature": "C95E934CA235DC9EEEB45817A6239B167709E59FE25C8684221315C4F8A76DA028286B07D6DD0733D1FA713A94964F325587E2BC491908B8ED3A40A014C82FD25D26B0377364F6DE69CCF14A5FD65AF5F56278B202B5DC3812C9801E96C40381FC45AEC5FA23D3B0C99E79FFD931604FCF9F51CD09484A671A1374558EECF31C83EB837D7183072FF7CDB1220F58E6B77522139F0F15049748A46B404CBB0DA079A347CBE281D717616DC8F9FAF5DF5373A3AF9FC22493586068C14F7BA5FF7B90E692A65688C8965BD6452B807BE5CB76EBF45ACC3DE9BB0E1B35B1FD8CF383933F1A9928825E62DCC3648D933921C926C1BE1B40BF7294BF9241226500ABEC0420EAB0BD021B0410D9A79181921680491AC9162819AE3B9821E4377754A37A0AC9A0F3ECC038BFBFFDFD7E3977D0087435CA1843B218E6C024759124BAFA889F59AB0D178EB2C3896CFF031C57DA3EBBBBD66CBFBD72BDD52D19D1AE307CB9E2B8BAF3BE556DF71B28BCA6F9B2EB69F8005ABB8D29117C43BF42459EA813C8CB4385EEC23984BAE661C59BFB7F9F06DE0A41F70430AA448BBBF293A9E66B55995B3A5114032A11FABEE6BFC0DB02ACB8E488A05D4EFD95ADA2A47561E91C3AFB64D24B69D0B1E320B1111FC4CD1D48F1DCEC0C8210E6E632BA1CD0448E3399BE8FF9FE05D280CD827F09CCA0A07FAC04B2C1C96DCB778A16735C5BE6D71843E9FBD0095C460C6033750A3A6A40788DF53C115624A75147D8FA8C1786F392DF1E52DAF68BEE09DD081A22440D801061260BBBBEE3FADAA4481D71E9D837137D6EA56AA4B8A30D5EB0163B7117C1404BD7E2B843FDF0FC3E633AC03295C405FD1BFE2FBBEA961B5CCE96300DE4D402B35DA3CDE854E55E9F0D89EA9E3E05D5E004FBA53705CFD74DEAACD1BEC24CD167A05B5D65A895944EF7729FBEA53B19959891A98EA2EC69E5FF4C22D3B2317955EB2B2976B096A621ACCC3FE812B8D59C195BBB7E573393529CA246D7DCC445270C60DB57EAAAE689FDCAA28ED889FA1F93AF6B454C8AC59C667EC338DAB35B7D2E6C5DCE92973E24E5B73DA0BBA9950AB8D2330574A10EAB9B41D52C607463F5DE9344F1035974E5B166EC36E8895D1530FE1A165DE7620F9957E795CBAB4A83775D4E267A6F660C73CF85CC675C0ADB8DC5957F960B3084DBDA7C2A6855D65F798E8F9679A4D7F96FBE07F09382FA424481FA2A4D808D501122B46F1B6B9D43E8C9369457EA2C6A77F51669D80230D02F2EB017B19352851B7A0726E4BE6CF69072AC54B7FB5D431940D06CA58B2EE61CFE8690A0686C62E1B29F4C22C28D3C386A16D63D8B9BD65353AA48188EDB9F9B19FC9B2302FA4D7864243E959C1BFF2DE4E256BB985D4DDE0C8EF9FBA0FE8A7AFBB2CD4976C3CD3B9F6FF162567B65EFEF5BA87F3AC5509976015BF404704BE1657A4B89D1DBC98072838369567C08DB761FA67A4A2FFA2C7816AD31C0BE09B0DB27D2AE9CB7DA26DF378516B17CC07E90D7B702BC7CE3568F3AB902697164B853BCD36E2A290C1B7261959BB5444B6D75C1749D939145C6411DE4FE5D1847E70E473FBDF632533153E701881C43B89D32FB3E112BDBEA5E36B12E15F941F4EDF669A5867D79B34B23F1F370501043B8ED95A1EA088A46A5D0F3177A2E81DC06026539769808058916F003E05088A062CABCD190D9CBEAA12F8D3A7BA0C6EDB6AFBCC3D1A269F71835CB1D3BC4649F998903BD1EDE9000BE5908DBA93BB4C80BE7DC9F97A28BF7EE423EF15F6769F9031AADEFC28C4715A27494CEE7EC990B59D941FA42423D8C51B6869139302834567316FAF4595546A19F317DC3A2BC8BCBBD4BAF3546CBD3DF2ABAB198DFEFE75C64574A35F3B1E1B9BF303FBEBF08423DB4638002604DB5BE70C47DF86C83096BCA682E1EF3C65A819517DEBFF8E9EA59C0DE1D8FDF2F809BDD4D8C8C3CE248A4F49FFCE91DA7BEB1361F40948CDD5F6FFA77F4CEB79B3877CA83F93B098DF64A3E864DB265DAEBC7FD1B8F7B8C83BE4A77947A43D5351F107E84F5A080D91D85B45466906C6DA51428EB08E0D9D61CB4A02A7E4B7C66FFBD1DDC3A3EFAE9B3363AA6DD3A09DA1601C9158B604852B24EAB2904224F24EDEE8359F165D536E17DEE779E3208B8960FD1426FE9DB8861C81201CF55F527B2465BBDC2E4EF30B3E4633DC01CE8E34E1B4CC9EC0C78AEF18DDEBFFB013145F7D80F8ADCAF2A4D1DA1B30DF901957D36DE50EA5B9B5560FF3343DB04C8844B5C2E546DC426BD945F8E08C4A04454C0C6257F1E1D796C29466E099956118AD53847F4A579D01976D5CFA389962ABEDB6AFBB91E31D380CD9B833586F5DBF598B70D76DD6E1E2AB8BB52CA97DE3705ED68A2A551C96977DA36FFBD27ABA84BF99AF9C539AAFA55680259B9CE72F8590FC786FE62A501D52B0FDA85AD3D245E9F29BDE1E278D1E2722088086CB51D97D960511814F9CAF0A5A57E2C616867138E587C17DF20E968BAEB83179003F9B3D9DA0D6AA15B61547DF2E9612792111A271F723E7DB4E8F2AE272D356EE9753797B85401E83E6C5A87DD147DE6BB95A55C00BFDE51E3CC6360C8E827456E423799D294EE3BB81A7B79D9938609AEC20B51D2CC17F08D6AA46B106771B845358985DCCCEC29F861387CE570296BFAACA9F2676B417D625322B50D9E8BE4C05193A9FED61237B44851F3419BA403DCC1662C0EB30EF3BADE28686E3E1CB3783CC3C8D78E96111562E08C132BD8D3F26C8E9665400EB44154E4D1C7CF16A52108E21137DDC1FB310B7A8AEFBB7BC7C09BD062C82C3F490D5B5991665D3BE017EFEAFA648833E958D43D16482DC95C867357103A0F141D230522A6BF24C19AF25876834AB24239BA5DE9BEA4CA4A22B09AF59C69DA9BF998DCBF49F8486D8FC4A16A411F9F273FA44998950C620B3DCE24C5E6D5CE4D3A070BCE23B20897BBC654C154E159B093CEFEAB13DD4D07ABD1F4009FF72FD850AF9098755214F668C2E1A93DE22D82DA6711D3E804E0F20A9A95775276FEE50B3F3A348154628D46E52DC934DBBDC514CF9BB6754E349482BA658C73E90AC72C84550C179172F87869237C4A902FF0FC0B8466BF2440F0EA1CFC4EFDBD925F725A90788A4A89739406EE38975CC50563C08513ACAA7E490AA33D67921A189BE3216FAC4376CD5C0CD255452D7B353C5DE44BF66BD420AED104C144DCD9B6F7D3C40B146EBA5BFA6E479892CE194BBEA3EF1A3C4DDC49CC2A564A5AE61969A951F5BBC5B1F580F04FC8E19896598A0B1BA2C81A9BBEE1F7AAA26FEBE6367BFCF8F86F6EB2A72F88EE772AF8ECAA0B2901C487878ADB9172E330434A72CB709258BA93CD819DC15D836E944C1ADB83E57547F6C0D3D1B026E7585A8B7CDEFE1E48DF5C83130B13FF078526B21F57D3EE3A2AE3BFF55BEE412EF27F9065177943617CBC0D7C164EB2D46CFFAC89A65B7DDFCC75AE57C63A5CE04741D51E5AEC1DCFA0F27B47C4219207A418C82CD513AE3252131B9C9F46E86A4FB45939328C5F10753136C5484D44B49CE0AC7373CCA7DF7AF2C0B7123AAAD87C0921B238C37668CF8BC77D7105EF2D994EDFBAF2DA2121C158B6DE42A49B5A0CE371C2B629E2B7B585665D5CFB24EDA544942C2862BE57E6823E7CA71C46C3C0AEC9711B19EC11F00DF8FFC8E1AECC8DBCA323B51929891DE34968B5F58F9DD2A9DB8F1D6528AF7BF68AC5C0EC44A11E58FECFFF780077C5F9AA436BE772CDC5547449B7F9189647B1E254A449ADD1683FE7B7D1482A3B50D664C7B3D170E47513B41EBB4C46A3780858E1EBAD19D1CA4232D53A426743DCA140FCBC8A24D547CAE2CD561ACA7924FEA71225E289361FBC2C540D69BCFDAA9FF51D43EDE5DC6494687046DA39F3D38FB3DBD776119F488E722A79A9B416DC4A99E0EC04787D2CEA75C134C7AB7C05A332CA04423B6F45028D2FCC4705A9C91E6351AA120F4C78C4F2F0E5BD221EE7C07ADF701059C16A55DED766A05A43DE4FDB40EF8BE2E69A45B4532DEC5F169BF404FE709FD5C9113032BF8818F2F51A5C3704CFE265B005C481CAB1732D94511C331C738A838B15E084021F5E10200E034C02FB2F883F2464474A40B918965279AF19225A2748872832CDBDA50F0729319883739069F78B872F71337BC35EBB581445A9591388BD71DC5121C1E985F634F4DA5FB8F1917A9FDA424F4904BC21BF6AB7E24BA6C00FC9A89B3A647AB5756456003D47101B4A336800EDF75F08CC0291689406E416BE8C6D4826960FB9D7098D1786D37E33D2D0F3778C5DC7F87CA6858E3B4D5D880081776B5B9F6A1B26D2C829AB9E862E33BCFB9F25F19FC3F683C2D3E6F89518C5A763EF5A64A3256CF889F7C8C86FE7BBD800C479D507076C628F54C61D8F749A6D63C363449ED55BB9D9684C9E00DF3C4DAC78D73B499F229B708E44F7E4692FE6AC01D8FBD18D486FA40383B3BF7B00687E3C0393A0D4894B60F8C9A395C7E6A873056C486FD05B983AF8127CB4A100F7D49108ACEF78C6A92390B984C7517C6016819D0A712E808C46A6779E3FE151E12C88864234EECA65AE2F3CF39B1671DAB8A19726A7F088EA15A51282BDCBA93C22EDBF67FB9FFDA481D929BB8A3B35659DB2C235F3959B60901288D111D65042FF4BB30E4D92A90B0E8997E9060C833D2D26E9076B5E1AFAD0EF1BB06AB415C7389A76324184DBAF2B9571379BA4168D316121CECA90BD032322D3C0B227830AF93F3E62A02F1F34B0162B957F26DE9ED9DF233D2C3F92C25018B5D38794F856C98F76DC40DCC6AA5DD78986892877B538EEC358DA64A2DCC3812BC4B66F28FE12DC453D8A3D04647408F5FB040FB54EC9C645A2BBD5F04DB4ABCB5BA5B0865F1FE4428752A6BFBB3B8C9F92B522B6324BE69F567F96BFCCAE23F50B60744C72BF69C319C241B87299601933495D055CD60664E410BD484B06779A0FED262AA5FEFE085EDB88F3D9719A2E8345BB8E43AADC517183AFA83BD75C644687351D15759659B244FCDF5FF2672CBBA883697FCE4351820659A22E6106301E27FF03F850246D55D535A9A1BEE416912D9D95CC662CD6E3B7600E3F60D72EE27211284BAC7527D49F8DFD2A1C294AB5244D27D6202A7DD740E60DD744CDD35276DA2631ABFB3F5BAEC841D94B2CB43ED93E2E0717B3EB22BB4FD47734E599FB1C5C4AE4EFF01BD51582B0B8EF1E8025749E1B0C91A59B09AA55FC4886703A05448ADB712164FC815A6662BCA0CA12425C38730B45C047852ABA90EDD23B30E25421CC59BEBF3F701B861DA76313DF425473BCD7C09D9F5F8E2D91CABDE0E84B4F26885FD99231573A5E6383F3CD9F38EBF906C8798E3B29A2E6C86A1970537B21B4F0ECE582D7906598A0BA7A04B0F3ECA48FB28EAE5BA083DF3C3FA714C753E1C72595D741E374F67E8DC85455B5253BEB0D7CCDF3A1F8E565F844676E4DBABFF5DE3EA1CCDA3A03149E13B505CD2D3285C7AB79355D25846DF70612CAA9D13E8A070594BB5B254DFD4D632F42295E0904719FD8FC26A2EA3C3194B155CF180E977BA9D3DAA9677C5B6A125DFBABCD52CAF89A406D33AEA504D4EAD84283055AFF09278D6B0EAE9B77A03402DFA1BF7917DAE721880FC1881DB132FDBAC8563DB1A4B184AE8805211DC8A8D89E61148E2F3100BD055573FABE9B7314DC7F8314A040AB05045AEA1EC0CAE452D6FE031F9135F2D505B1BFF78D65F43D9FF7EE01AFA332165C3695C11C8CD48C975A3FF2172A8BE049533F0A98E011471681F6F728BEE5721987D4D14806F525721C09A6210AABC56ED566961E167AB8C4C44714916EC6B9C3600E32A06667E35C12ABB832B9D94A6D05FCDB5F3AD31BDE2B47148C80D808BC108B2F3AB3BF5CC9F84B60473651431EF01ED69233303E26E60A1CDD6132085FFD53524C8DD88722EA5A0CA7974C6C1962ECBB487B58A5D1981F0CDA6D3244F13C4439B9B394DC7D50BF616771816BDD17E7E64BBB51EB36421F1095F1CC6DE363F26A3C0538D4FCA4199D5BBDFD9A489A71D88B768773920C281BD9FC9A848CBEF9D136114D215A6F996C61D601484EEF727E01405EE8D99285A14DEBC231EF9B2BB01108EBF48E3C12B0D723707FDE4C87A673D5118730CEF0D23DA56CF7D1FE6E4F7CA90D30550C073B2124C83D78835EDC93B86B202BA64C6300EC11F8D7A2307BBFEA50ECC3FC41560FE2DE6584D1C9BA7CA10DA7C70284052053616FEC2AAEF2D5AE024BD2956497BF35969572E9DF383773886C36D2F4BBF76E3A44CB36CD4F64064831F5F3C9A212A6A23DA7FB5E051890D78140D4113E21FAACF8444AF9C73AFE4DD54772CDC9A58C7836C9EDE9827D6C7A2B1D99FA6C33756003771D6CEB3FA05139A6A8977BE3A931AE65DBF9FC4EEC432F7FEE2337CDF20D212F68BBE1F33C50525C619CC2C5F0091B7B8C8FBEC4CCE18298031045565A65B808121D2E385075C2FE11606A959BC300000000000000000000000000000000000000000000040B141D1F262F35", + "reason": "modify signature" + }, + { + "tcId": 41, + "testPassed": false, + "deferred": false, + "message": "0B340E19B2043941E7B0F80507F1F586BDCC03D19A75DDD23809AFD11CCFFAD3C4673C825B14877FA1D0DD6624BAA8E480A98002508CC648B66A2D3A83DA12C5161CBFAFD575303DCE545E61BD943C664333AC2E9511EF841612F78C5256D3FF319BFA6120EB172CD815134010DD5AAEF67F9057D94360117DE09BEDA20953E2", + "signature": "49A65D1140D46675E154D99E7C158F424C921204BF93E32E84A7E3209F55D4829E39C0BA4AD6C100B4D6AED81C556962F12B50C3A1AA43E07AA7D19470E7D9F1592A69DAEC642E705924B523D4F21970FACB78BEDAFE43967FB8F475F02D3B8EAFDEA3B21FE862F1E9D8CCDADAC689A605158D0D06F3EE2DAECF6DA2DDC0140D31AE1A5F9917948EE2ABBCB54CEF3C4F6307CC7280D38CB4A51FCCD538DCF4ACE14369792FE880FAE536F35C48828B7779A1B9BDDA19293F043DE269B97F0CBB2647ADC0F04341DCC7426844B58D4F32C0ECBDBC068CAEA0A6E4B8960BB80D75C23A60ACD615119B3280947F4593831989E5426E2D268364B6D381F31CC4083743F29B56F4C402F636243A62B0CAD315B1CF14BC120D1DDAEA3CE7864ABD09366A1241CE925BB5CB1B0E4CC51C2D8617549D2A627A7C5062307FE01F0F16D7A33EE3134934FCADF99D13574D66D8E97FBC02ADD7B18112975790B16288EBF426638F80E3FA26DA81505C56AED3B6AF8DD58A171A88B35D63060CCF56D715252C1E550302E40DB003767569335B03DD483DED86CDBCC8F0B62F4FB7BBA0E39ED8A65714459757665E9357DDEE1C10C7189FAA55A95E11C99CB4B01831E325244EB1FB21F89EC2054A23AC89C16FB28D38787BCA63B4642E3A065436650A78A2AFD7C8DABC4C904BD255BA40CE53FCAC84F07E85213EDB8DE9E5EC9D92EC50495F64CFC871985EED039DC5F538CA4E013CE29551C3A32556B7B661A5CAECC65A4D9C565A5BF5738121A8950ADAD2826C2DECDD65D19142E8346BDA85207880AE284DAFBB485C4C7FE9D2E91B2A027C85542267779143A3C33C00B9866384F88AD93CBB7F134E12DD06A8A2555375C6D2681FC2FBF931E534A37A1BB8CEC823C041E54049776EAEB8BACFEB899BE4A2D9DC7727D3A63398CD230CF79C9BE9A77FBA48C1236A0AE076CA169B483B0057C21A3E7C593377E3760979A45E2FDFD653B4C0EF75EAF2979E3288A78E23C21C15B421B9504DE1800A035CF064ADB30E6213D829D293FD5F7B27A96BA398163B0172EC91BA569B01186F5488C98E5A3BE3973968409F31232F9967F3FC1B1B1F14C1A4EF9D238C840544FD466AC31EC5CD915774B1B6D31DC3D8015A842AA31B033306CA16432060209AFEAD43FF68A0E688E9928C72CA10FEE9BFC07C14C7A58F6C0959F994AD3D9573CB875765C9072741D47E67D48CFF03D1C159483774FEBFCF186616BF0F61E8E560E40889C261859BE21FF472809539AC713273EB1C3E3B39667B6383D55EA05A4159B9870214B175EBA1E393A43EE2A4354F507AC845B150B6FB0C1DE94DF02836854172D56FE92E7EB02385B2BBF938589FA1B280BE72B53DC26D65D6B7F8C5AB339F055C0A4EC6C57C6232448EA637219429D30EBDE7465A57CC2E798BE7CB0B83191D3984F3054EC7674ABA773224C2FD53C1D7A14F475B248FF23A9BC724844DDBBF8FD690C8CC2F660537B797039667E6449552E39B8FB5638AEB3E41CC8AD8C048F403605275C0C72588A593D11392C5258BCE745BE5EBE364CD84052AB3A609BDA0CC1F2B120BB6600A7E24BE93DC5317D3F1AFA0B3B2496D744ECD6711C5E2E1D1BF0F75656449BFDAE5ECF0BED74A0E76F001893C2D1FD118B302BBC33208BFE5891B47E333ADD1522D71368B82B68E0FAD57DD06A838FFE76666C3C055B9DFD1BD0A3549B22E3A42902567D3B59E0D1EAA3C290BB9911D54FE40950C74094C8C7E56F4443B83B0BE8F04169F4F18796E7D4CDD04484E780D7706CEE1F53303E604199F36C62E2A0CFC18379F428AC26FFEE3D0381C5C7D7E7E8D9F2B34BF648442BF2D33817E2239F9BF9ABF5FE4418E9D4B5AB2521344091C5418FBCF73BCB2F6F639F7F6110FD6B48A6DE268EBB6437C0B10C7159D22A2A5FC510F4C5CA3E8F23D01E4C65C17A88D5A1E7611EB7607717A22A7F82560E83C20A902543387506679178A129B36D1BCF3192C4B3B1A5B8A97508BBE95E90723778CB574CA8210B23E95BCA2CC380CAC5B0BA367F1B38997BA35BC89548CAA818E194364B465FFD28D10814181B9F71923E94F09A817FD0C157B5529749AA130A8BCCAA6B7551236F665A30E115041C916C291344C804FFE423C31F7DFB746295110275AA29E34EC03F5A2FADC580F011A0CF9E13E657963E552465728300422648986AABEAA1B90733247DB28E636E0594AFB09BFFE21130C974671765D3A197922F633405137FD490EBA9B953AF7174F3202AEB0CF91FB96200CAB719EAD3E3B93B0E6AED95FC38F6736D8376CB4FAAD3B275636C7239D8DB7E64DBC3811B297CBBA994E8EE64F60DCEA83DCA533102B412BA540F850957AB002B62388AFE9485D298D4BB64DAB4C445257611741A3B25A62F8433BAECB34B0BDB6E2246BC62F2156690BC67DAF50E13C8A797C911AEAD9F8DD61EBBA1159E9C7DEEF678673C06A0ACAA57472EB5BF0C6E26139F551054EE16B1CDB244F6FF09CB2093D273BEA1A7CD04CD520582D9627266EA91D2F5DE1E7FA423AD598904EEB603C38EF13D0B4069109C48A27A84B8D44C9B3F5FACA26C1055AAF326E1C560B76084D5379C7BE7457146CAA6F7223E82C32EBF803130E1B9928A5D65F7D4713327C1E62318B169277AF942758E4ACCCB3AF60A75ABA281089DE3D4210FE485C3F336ABA95E0BAE3204CD33FCF0F296AAA646814F1CA3F7AF690FF289E29A8564038B20707909BB50C48431C0A4EBA40E0A9842C9524D3956792A9B0902C8C5D97ACE13AAA07D86C9D415EAE821080AF50882E4F1DBC4AB93F82601AD4F9F07AC7F072542844C9F326C26654B17BD5162FC3111A62CCC9D5CC5058C357CE008B7583808526135B4A3FE9BB726306997D520AFD46E24C790D10E63758C28D7E610BA2CDA843C86A97B842AF876295BE7743E4603CDFAC7CD7152AF2E0564607086B62C488EB242EF10CCCFC34B7826BBCB6EC1BD907F6758682E39B8A9CED3413326602345D3271F3FDDAF77BC2BF378F7FA999343285167C61A5E71F9B6F01FD903B7E7DDB6DABB7394D0C889E89793AAAFF8FBA202477E7920301EFE2A1021994D9DE9EFDEF8D4EBC15B29926ABCDA5CDC4D84035A43EA7BA03B1556E319F2E5155FE1F625D65572E57DA6ED93DB04D85866F91EC083A109EF9BC11A8236B496E80A895A48E52B18E5D7DA80312FC77FC4C4EB03DF576B3BCD1C8B35676E964855D88D561E981D5B280A0FA090E0322FD47F027092D7D40CC414A24805AAAB2D3544DB6223E739C899C578843E3128F9B60F344FF95EA911D57111224BFB33621904468605C178E404F5E129523765198FB59C6C5F57B32FDF364CBA6C1C6E2135616C6F54FDA431BE95DDFB92C3720D91C5C99431BA9716F3018B533A7E41323210CD7118DF726B57A1EEA7025BA0395F7DC34C6294F9BBEEC48EA2D643F856B67A5A7BC4B26E8C0078ABAD5DD1774A15B89EBFE4C6C8A19CB9CF4A75678A2540FA907D0E1091650AA77B10891E33979B31D2F7B7D04ADF648FFEAE0CBA18BEFFE582AF1C2BEA0C02DA17A7EA2BA484DEB7552E73151869526A418516D511C3D3475C14E1EC9B4AC5A122C93A98AABCBBFF3B3128CC280871B4A7A5197093EAC1BA34A2B95C9D841D1E1D604491CC259DB8FF1F8791B24659DA53A1C3C95FB627C2B855E656C01FC6FAD6A5CC0B10A51BD635D4F2646A906697E7BBEA6E50EC7DDA0BC9853B2F537C24A7B0E3922760C082C437D6EFC19F9C8A749171CDF7F3C32BED621746A95850A3F7DAFBB903245FC58E3C9E40B434AB0097EE96150F6FC87029DB5CFD7768BED7EAFD8258B795B189DB9489C5F27E5CDAE529ABC08BC95C8A05779411ACBCC2563E5BEA4633E3921459AFE4CD167192B2F280FA5FDC761C1239BC22BC558C3699FC0A31AB388342F580C4972C2A96D9AB20AD24A3B27CD4407D4F4C37E2B3E4EAAE7A0C5C62A380C30AA6D2D103FD15FC79C9C37183F20E7A4C13C4A633DB8D54770CD205930D27AF97C242B13571636FE1231770CC5EF8934258844F373027A888BA7603237502BB0F00C7DFA412CE0996052CCC446348D4F6AD31DDF4E6E91B03C0329F7124AE619432D2D391A275189BD86DF5F6F64395FA08836F692DC7B5A5DED430CB3921E059C52248254772E1D7ED3E6D00DDC25D2DEA29BEE0F751EFB30CADA85146E4999EC5A4D9BF1A48BDDCF4FED7822A50A5C600A61A24A03A9E60EBD713A1506C055F23DDABD8726F3CCD0B91BB38FDA0B023BB7BE6AB85596B54CB3686D5B1BF3DDAA8F41FB6FEE0966FE2E17E75F483B2445B096100EA28CFDC822319CEE645B7D66797D7419476ED8F8179DC3041D2CDF941064DF71FA0E2BFEAB5BF4EFAF0C9DE264FF4733C494EE4709FC6E3E7DBD25A803DEF3141E3EE722AB3B191287338F07CC017053723A5469860BF631246225ACC9600E0E91EFDA6009DBCEB469F8DF95DBDD7395944DE61E0F4FBE360D4CB6AB8D19D1A479BA373E076F7E70706A1BF95AF39DD374E5FE9AC42BAC6B10784AB8220C0397C3E8BCDACB9D806E4323E841DC80F39FBF4328D46F964E5ECC2A33248EFF1758A388B22D620B52916CD6D9CEAE5EC7D23296339ECD7E3A173E3DEA02227B6CC0E036ABA79B0CADDDF3F08E5EB0A8496F85D26C2592D2A4891A5C1CB34395A7C72C244AC3A528A7E3E2BF478F9D74D45CCE1C1699F86553F17D9C3FC6A16F8D449DBCAD72B59B52FB9410BCEC725F4D964FE0B43F7C03EB677156E2A02381146A13B9E93807D860C10975E8E9D295F1D626647CD9550DE87862BC47CE239B9FC997732FE794DD99AF7C3068CFF65A1250F91F2CA3F90BB6C1A6B0A6CEDEA611948FF04F4E0B89E0FC4B40B424B8C50C402CD1441E9A5A387A7A577FF9F02EE2EBF97C4FC00ED606C413C71B873EDFFF415A5EC78D4E4CE9F73BE817545B3475B4E485A062CFD841EB7F4572F7F6F705C7CA0362C934449BA673741CDE8FD43786B08CE02347D612550D98139A73AF83A2D377C1067BFFFEDEB666FAEAA1B9C9C2CD8C6939CB73DE9AB305E125B259F0A80E7B99F2E5FEBF27F5DA65E5C036B50470BC78430C1CB7BBCF40DB773543040B1D8007669601B2F1CF098050871B15B8ECD45942C79D995A2A7318A0D00FC2B2B25C04C7D3357A413593A166FF7C8CED6E5AD92D0D8737F42FF18EC9FA4D6D39F1EA3BC8CC253285B4847ED982D2ABC5D3DCD51FEB9E13437058A74E5F72971988B7B354D0916D78F3EB0A378BA1917E089994D7BE851A1A17A7E0F25ABC1E17D539478DF18194FF7CEFA8B2B35772C6D8DF88A8152F9EABB3C9DA3101090F1AF76FE37F54D1954DF3EC25B1E014F2DF3BDBB063E34509520DC07DF8B11EF61FB00206B423F43E10AF77F0E401DB9D005D253E284AF929B0BA17B65C8162335A768406ABC9AB6C2A25CD257F310983B15A9B2861E6986DA7A46D4A09B43CECE1CB052A6206FF8B05CF5751E854C12D83AEE4CBACA03863DA4868275B8F08A5474DBEF4A5A5CCFA69E8A7F3732A82B5AE22027F62005C771D907A583C72D8949D7457CEFDAD560063534DF6D31DF32A6445492248BA10D6107F3A00225F4530ADE4969A0F567FF5711BEC3369A0271A338F66EEC97635363DF4CFCA6429CF9CF711260AA9901B12D6605D0342A86238CD891D50736430575AFD05E067D806CDEFBBF7D501D8D394299A9B3C3A66A6324BA6C9052F9B41A030AD4AD2957D77907FFC29BC5007CC15843887801FAAA3BD4F3C52FE093890EC0B45A90DDCC99E14896C039668B4CFBA959413049C1739A430502E7643011621BDD7C97116CA7EB093F4C5719C8878FEC0FD31D4B0683AE5C4FA5E33A7E0834E5ED6E68DB138F95F748C450FBFB7399B66B418A8AD203796FE0B0D7327F2628B5C71AE0F03394E6BA312A61587F8E62ED5CE71C202AC6910BEB31A23382D60654F659052E091B5AAA8BC5A33D0BC3312E914C57018EB54EA0B3CE4CE0D55CAE2668D37DBBCD38CD7B7CA1A61D4CDAB75F50A23AF9199BA6BC7EB7D2553DC0F9FA52E48B8C68C7A731375A5A9092CB470F5F28BC59AD309ECA693AEF5FD0E475E49D7FE1F33C5A324499259628F2D5B26D5ADA97BC2F983EAEDCC1255D11427B61B18416B3962DC03CB084F23DEC9F61115669BBF5D833662664328D365937B4D845AE7829BD553F47E1D327F967D90D642D297427FC8521977637BB27383ABBFB736235A11EF55E1FDE9ACD2E94FAF24F4789350CFA58C1110CBEEA2A29C4AA9269C532238BEF1D6EB65757C2133AB992D4ED116C94BC44D746301775506A3B220D2775A57789207D49668A5C32858EAF64EFBD33F1C258D29F906E7336D6C3237BFA2022E999275C5DAA606B006598CAD77EE67E3336F3E2737D2787F8F5298011553810C1527445157CCF80640477889989AC8EA045462798DC9D4194B616A8ED1D3FD0732455C89AACED4FD3E6589A3E9252B5475BAEF00000000000000000000000000000000000000040C151C242D3239", + "reason": "too many hints" + }, + { + "tcId": 42, + "testPassed": true, + "deferred": false, + "message": "EA707F27A8896AA860FDF5D5897B58538D1CB6096CDF2AD5F583C5D4FCC2C91839C1AD44920216F8D027AAEE2E563D779E86FAC4B2502497B41229BE823ACF0BEB232CC6F3F7DA88E0685A9176DFE71E42470FCCCDB43C6688A03B6D8AF6612AB821CD16757FBEAE52C779EFB6AC38EF7FB4B5E365882CB83AA246B2A52D5059", + "signature": "372BF9FD2061BD26939A23C3DB128746EA3346F0C0E75C4C358405C12CAC9636D241A5E555ADF1B8C448152326F9248EBE31E8C171B3CE7C0079610C6C715BF8DA26F4344C0F043EAE26E749E56BAA190E502BCBE70740A8CDED41CF2FAB99AF00A6D788FF05C30CB8B9ACC125FEAC8C7CDFC1DD7226C819BE3A237BEE81FDA6B1DEBB83207B53BBD1E3FE07D3919AA9B3505F3DA78B7AF7A61979B9C8290563B7ADFB676D06C7AAF545452D3D7C9262AD40456D0333B362A68207D0273F488AA60F87543B4E4F4B0BFA36AAB42D523AC1D6691B680C673832888480CFF337B1590A8544A3663515198481B17D0839944754E14D565A8C32CA1D2BD4863EAEE16AC0BF8D52EFAA731CDB0A3A25D2583424F0F57E08E2018247B610F843B1ACBC54B3AE0E880B994254B4DADD9652EF5E36D3F1CCAE76DB8FF110CB3AEF24EA7B00E32278A05267C3A3319EB58E92172DC5C7EE748739C5E19AE54F7A8D714CA642958B820CF8C71F20E03730641CBCAD74E1956A1C50562E27F21FB03F44A3F032519E2E20577D4611764159405D7BB138F34126A4E5C8B3AC1A8F19817061BFE1C50A8A6767053677F1B507D70B56BAECB8BBE2F54DAACC13AD373020C13B103D2079B140ACD18D3824C03205C6198AC1603CE63602EE853B08395BC749B0DA7ACCA6DE54D1D742442C81ADA46C3A21F8F8B4A1E3C212315E6D19D290D139E70C037D4E64D3630996606E443414A371A96B19433B1DB4B5EE677113DE2005ABB42CC8DF12C33DC7791FC7AEE807E7946B023FE451ED32FF21ECA246AF26B535A11B4C6F380EF56DBFFF984ED15818EEB08578D045F2FCF39C3CB456C73EFB76C66AA09E6F9458AF39BC5A9E1E9D6E8826AD3ED681DE22E9AEE77FAACE34385376EFFA306098EDDF4F122106EEBDF32AC04884554BE6945753E6B831FAF701B4AEA4F48A8D490BDCF33B0E1630C94F756A1C565D2554F5081EE3B4EA5C33EAE04F06BD44CA0D0671708E9392EEB6C4EB80AE8A17911B27CAC8980A87A3ADD2F5E2FEC71FF711D89A6F96EA423411E81B292668F60AF44F0CC83BCF835E78F2F6BC503F54C2C6CE827D97023B98F23A85D269238013F29E9AE8BE2FB54C9AA69BB6FCCD96916918B8E534D3CDFE506A2AE474B59589CCC730A0A857BEE1F4CFAD0433BA4D34E8888FE2785A7B6331C1CE3F66E0DCC2F801C112DEE85EB869567C387305922B252073023259E1C042D3A245D141DFB0F2A1A5CE0FB772B12A0AD875DE56A8A0151891D4D4D2E2DD4E025D8BA25E63E44AD8798D495CD099B57CF73623A2FBEDBCAF1ECEE43AA0882E553F5058C50AD9C4FFCC59D93F51DA653DDDA17B14EF03D86EE7234A3808B54A1BAB7FE12154816735D62BF3ED4CA9C180D6BC050EA3937EBA6F8AEB4A7811A7307FC7A0BDB24360AA517A2333FE86CFD05E5924923AD390E6F0DC4E757AC78A754BC6B3C15954674F4AD41D05007BB984C89C198C4E4109683BFD1A1E59FD8CA36040090764B81A747ED14CED83ABE341473BCBA6B5629044DB6CCD65CF6DE91C91AC20875565440194FDB3D21CA637E019636B44F69D578C1E1CB12312FB109242C228B02A70FF001095801CC2D308A5E802C34B102F174C6C0A44D14A76B9D82D8B97C01205BDB22AEA9B2F0DE6507C0FADD1321BA71157C203DFF28207B5CD7AE18923DAB57AE263BD26A97210DAC238427857AFF7639195EC13CB74D511B40A5C5855E1EC1223B6B44C5B630AD94050B573FDF919FEA24AEAE8095AA8136D15294D876D1ACA1F862B038F35265BE879A0F1FCCE07FB76884DDE073E73785B46DC0EC95B7859594119D272CBDCEC3FFF7A1AF8B5076C977B76C7FD640B834B92066257EEF27ECA1699A7BE3ADD1746624C27256BFF5F9177C01147585D1D5CBF576F381DD6DF2320F24293F32BAD164E474CE9C741EF87302331AA9B67D64E95527C4BCFB601699D68F1F712222BF00262BF4AE8C49E098A8EADD108288EC0995D068315CE39C6429CCCB00E1D94477B76D866AD7B7968B5AA98A590782354EA512344FE58290DB10717E5C6102BC7EDC1CF85D634439D5D82C1B5A2A9928FE389BDBE4FE9AA859DCCDE68392AD6B35F516AEA70220B0D6DD2A91239EBC0D15B5930937207E0CC5AFD925A4B8BF5A0A4DB25BF87294CCD7E148684F331508A752386A0811B606B91283D865B58B347084CC01C874C046861ED3FD8DF8C5B07E8A2F27176685A39A9BCD955645F1EA58B4811DFBA16C98BA52BC0EA443D592756B00CC4CA428511A7F8051E94C5C273CC6E8652F3E9132E0ABB003C31DC61A8802D2CA650EC0B5AF5BC3E983C2746F4747AEB1F6624F010C5104F7A577E58D5D527CA58BC838C60049C99270A66C846258D32A5A5E4245088E7C6F824671AC80571DEFB07A21B64A688100F0BCC7F28B985DD9B0A1F6780B561BAA8616909555E6BF656F1E02691EF83E475E90FCE338195A88FC1DF0864B5375496B5D8FCEED265163ED2EDA2CE6CAEF6583800F225084662591706E1F8AACE331689219268A591379219CEAEF219A02CA85AFED70C96CDC7B50905EB6C2BD0E1B09DB19CC8728EB108123228628212EC1A591148DEDCEB7F4938F0A99B727B79F230BFB96B82E03AD90B6EF858CB899AA2549E0FB1E8919AADE94580A530479C140641D6620676927DFCE0DC4374AF05B379AEDAF0BFAFB0A4EF6FE04E2CD93DC6F0F4B8B680804F296FF8703219988FFD69110830F3C66555A33026EB524E75F9D4AAAFD385BEAF64BB448B2CAF9546ED326E0690948EC06BC7FC9204315D68161EAC551F228373C86BE56208DAFF85C71053355C6FBC677C87E1BEEB1D0F03B8B77F86315F98CBB8FE07B17762D9FA93E484A6E991D616E95476FCF1EF1659DAE67FA92A30CE609127DFA818CB109B5C33615BFDC647B7CB8F74581BC90EA05071E7F4E542EC1940D0E8B0BA4772DC4AB89A3F0989BD4EECC4D026BACDB44AAC9524828EE59DA8F9AEA5323F54FA60633F676B4A6537BAEDAD0B8492695D7333AFFD413DB2134328568B5B7B892585ECE9E5618F7573F014EACD05289DE2404E2A2B7CAE0E79E7AC7AFFA74CAE66B956A7F6BD9FEC4D4E10F3ED7CDD8433A35D785CA2217C5D963A29E9389928FBC1BF380E37CF1242C47342B58AF18CF83F209CD1932378C02538A5C07D369120B3B493B28AC4202971A0D2C7ED6B65E3098107ED5B20BBFF10ADBB33710DC13064C1ED6A289559FF7CC3CE77FD7A7C8701D4F9606FBC7E554E0047883EC6CD106616BF8CB821E0D17792622310BD3FDA8C5C7088C395C6272D8BF06F8F33DB65333F097211A05E2DA3E07FD05331241DD2A1DB878124F57237F5DFFC021263197B10B9352B6BA8061C58BC1BEF2DF186C376E3059862CD9AE36DEEFE6F8DC72D43BD043DAFBD54FBBB93EE72D0E792BCA927E785C9330E79C39581F408A4DA9CB0B4FEEDEB5DD9D8DBF08A736C0418284C41E9195EC680D5A9B56843E87DD76A7519CF03C5A447E407386FA81A38FDCAB479F7F239202DA95D64EA059C05DBE730A5AC672FD3D7C854FE0DDED4340F4FF0E7536F640ABBF7FB1E12DDC7CEEA34FD46BC24918A52EA55FA6FB1B91456932BA95897C92CF3B805994EA5B4C7FA069135F19CBA85E3BB73F55336A9B6113B798BCD3758E1CBBE09E7207345B6DAC55E358C60B6C9768AE2E6DDC15CBBE058B6EC06F1E99D4797E66AB0935B340D392A4C4726D8265B9C5D58B0C7FC77B367495D81518492650D37EB852E8B4672453330E30727F200646E6BDD6D70CE290739A06081F433E27D87C09ADD00E217CAEC0CAA9493AA681C777307E70EEF7184FD658F4B77B88FFDFF539E9284047787AB974CAD538FED6AFB978A38959D02217774C1B3BBCF36C805C17AC104EB27AD4E40A3F46BA2B08ADC30B713F224C18D13F83CC60B59CFBCBFE0E7864BC7A7CAD976D3BDB8CF71DD5888169E85639304D759BBF6FE7C3C6CBEBEEDA02E819A4DCBA188407295AB2D885B34EE22572518BFC0E9749192A839CC08D4A160794AE52113AA94A09258DF03A7A4DCA3EDEF6CCDC720A780DDB561B319B574F2A22A15341746B4DD6281328B3667786AF8B729C135BA418DEC122D3E119F3950FD6ADB0B0C773B90ADBC4B9E8B27043BC5D287BA5B92727FF4759F4F64B620BB226646F08414A0513F72FAA4401E371465EC7E6F4A867A47183ACD434159BBE352FE1C2D8E30BB3D7E08E25D15F1C3D996C811B9AD35A8D5B4B6D0A9A606895E4044E9ADB7A6427DF47C48614C6431F72897E5052B878996C520E9D33AF693BC69F879B8BE87BAE0564701438A51CCFAA342663927F9B2D2271ADA3CF44D8C4016020368C25FD56CECC6EE192734753D66A97E13C2327AC71E5726560D4800B26C604F1A9629F451454C86B6F5AF4CC3419AAA120BCF19671D577927E1A88185D0457DBAEE168A9A45F9BDF0DEE2A35D5E66C2DDA27D6B4EA492BB88D4EEC6CB68B23FA2338530009D9C9CD1041BB0592E83EBA03D39C7FDCEAB5C1654470399E6B85E63616CA705FDA4EAAECA06AB3F87857F15D2EBA75A3A2EEC060177F74009F5943244913E1959820D0D92A0C2AF7844881BD408F4A0CAD81AD6EC9243C8CBA108C8F58A23D5971807233173F1B98AB5C3C73B72706131C9AE644F46FDA74839D497236F152D15B97B93BCC9ACF405C1A1CEDDB9C2F03CE111977426D3438F929219E859CFF3EAFB5D2BBE48E00DF7A4B627E181A8982A3D0E640677B6F3B419B5E2AEC12B8E306253236B5D3B0C7252C2D2F7637610F07094570431E129FC23B631DAA0B6A2A6CB3C75FF8D2ED1CB906EA9CBB20956306E4EA261E10DF1FB7B3FE1D63CA8EA742104DC678AB572D0792DE89CEBFAC8E541E91CF2F7E8CF7A767365FB99A57D2C259DECB1957EF6AFAEDAAD93AB7DBBDD7341C73AC40D25161A103888C8CA74CA0EB52E195848A006E872D0BE5F5A6B5E972444E925B5DA4A3F8F81AA168B836F17F38977ECC7AF48839978A1EAD106E0C3A8A715C86448E9CF4D23703273F4CF00FCA36DAF8834DCD97655B95E6ACF495D4CFC9A7F7D5499260794107B331BFBBD211021B9B7E4C9F947BB9D338C6385B9BF73F0FF6C97C7BD8EA33228EE939BB17E11B3C9D182F818055F753C5356C5BF371E21EAF1CF14B0CE8E3EBFEEB28010DA0B7EA9E0A4285E435FC06B70F4E6DE1DA12D871C3BC8D0C884A7A99DCF2A2C8561CD445B852ADE1A11217A9658D210050AEED89DC18D71D7906389D4056E7DF99DAA462D4C77E7F93874883F33BD13BBBB5E1AA8CB86A981B5491DFCFE2B474F63EB68D923F2D43FDC21E9A56A535347C021B65E54D7935B8EBC249903C7BDC69419E683F3E1BA7450DBEB2F175E2A5593A202543E0655B909D6614290DF1792FCD7B17CDBDFF0E9121D185A082EDBB630369AECBA8C6D4C642ED0AA644832A234DBD48B4C6D8037BF97AFB75626FF28EE1206DA462ED05FF43B23D98D1790106D88C3103232B82DFEDD8B62C8006E2717C921C1695E49B742281AF1CC870CDACA295F867BD72BDAC03CFF02D406A1DD6C3A3E59E8DCF93A5BD54ABB022F9952EF1906FA66ADD7124AC3CB35209BA7958C246AE6AAEF91C5C85F844AFA38335AB67C0735F634203AACA2272994B719B655629E54537A1E75B316E22FCAE758EC85D4D968CB3242510CCBAEAE4AAEC63303EA8E1DB841893CA1BEA38EF797C756A2A75D8C7A823C2DA46FB9996C3C2BA27E19BC5D23005D97BE4D2B899CBD0748811D6E920D535BA9BBA33C4D08868E70AAB6731982181C784EA4D4CFF1D20137645CAEACB27D295F14334D102A5508DD586CDFCE93CFE4D6B5B948D16AC6363B4DF5D7DA3E61D9E0966BD23D46B2263277363524437F18FDCC302540A58823990DF6A6214CBE9FD47F336534E89BC307FB0B030FF063748DEE749FC7907F78588DE4E099CE3D9DBC4ED4F254E7B4B297F5A11999450E485B462C83E9D6519FA1BA4FA39B25D195ADC14C1B862DB6A2222FEC7A4DD09A5472410758B85AA8AC57BDFC80BB4786B2A5C3091B7D24B6854EBACFAA87FA6895E81554AE08D5EF4B3144F872CA9644FD8E7A0C613CFEA146275A72CA3F68AA2F67FF49ECA257FD912F48C6637473EEBADAFBEECB7019B99FD5FA050811ACC255F02307835771417C782D43497C7D2B39B00220396E3C5B02696A16AE562E2E57D227E71502A3DE95D88BF98492035DAE2D468795DA1C32DE795717D43B1BB0DED8C450C34CEEC27AB138D303A083980F535D9F63EEF8D8200A52EE84802B5C6D4CB14D75CC8A719202363F97878B3E719FB607897C49752875A4C9CA7CAAD5511DB6523AFDF0CEF8BCFD96AB239044FB53EEBF3A70001C62E9B86E1A604709082330081EE7538C474D94B0C5FB2664787C85CCED00080E1349869EA6AACDF321546FE415268A8D9195B6C8DDEB337887A9BCE20C2C4178B2C2CAD9386F7C000000000000000000000000000000000000000000050C171B252B3336", + "reason": "no modification" + }, + { + "tcId": 43, + "testPassed": true, + "deferred": false, + "message": "EBDA4B4198C041F515BA16E227F1491F54109B04C5836855038149B60978EA146DF46299A38794D61DA89DCB74A46E3EFED16C832884194E74EEC82C965E9DB2858B87962F48F0C094C389DFD1DD44CBAEDF14A62A709FF48A92E193472899A6876EA8B9701C1D137896F3C779A4E056820F55300524202E44F8B24D5B685787", + "signature": "A2E6DFCDB93DAEF3A2B0A3A548EA48D51157F45034134ACCA15A29E5417475AFE72F571B34545F92DE26B06F141B1A18545CB06D547A1E3D19F9006D7C0E9640273AE424EE20CDC0AB8CCD680AD1CA98047108ED0FFADBD8B568753E4FA7C74CE79F7980297426BEF9ED2C88ED43B45B92E77D47480DEB54993BB03A956F617FBC9E40EE1F726A1E095BF25AA2B8BAD9578506A624E018287DE7A844D4ED1AFFD8B013131272948ADBFB1B40477CE56FA0C94E1DA951049268F26B7544FC1CB0F24F14C2D7A51EE5AA9BCB8A0237231F7ED5F7D2DF14184DFB66CE0336233A506193D6CDDACCD1E2D32A449459DB55DB87080603330CD1A865B719C0C389B19C18ECBB240EFD582A0AA372C47CD00DA92CD0549AA7F7C41FEA9A348D6B7BB78F46DD2998767ECC6CF9F7E2545CA2CB1A18503167A85EA96523C537EE2FCFBE870E40E00E25E7C092A2AD5D5936AAC869D167D9D76BF2AB47185A6F3F64D0557D78D553379ED2542EF2A3CE45E5D97EB7046219E9A9F4A0021EBF5B87A95056F3D14F8A67130B8BDDDB7F5F6C41E189E070A914BF69154F06E45109E2725C5516D1FDCD93A610D3328E2758D5BF0FE58B51E05075D7DFF949E9285924CB3773C8A16CC09F86A0F14925ECADC6FE687C5F864B93868E17D5D3CF218B8E49B991A8CD7879194C425DB3ABAF41B9FCD5E0DDFABD24369EEAA68E50932F6C1C81A72D12DB8EF868B4CAD837EAF5FA0B5915C9BC48FD089F365485A92A6153D1A48B4B28682921C432DFF4B09D63EF3C9A692DCB8FF2D48A5EF0FA63FBC24C9CA2E26AC2ABBA339D2DED6EECC6784C1ECF9F0D39BA10AC8688408AF5B85D4FBC09B73D9DEEA0101146ADBC08004DAF9BC68E66515BA9E103EC4B062A45E733485FAFD9262CC7737999C76305E1106553E495B26F0B22EA7F093B4A543AE8CEB0DB3607F4CC023E45EF9F957563DEDF945CD88FDDDDE42826ADF24D95C314BA718A1C81462C2A4D1BBC2E9418A11954D972D386899B65A2D7D8FBB170A91EE0EA02D18DF1541D95BB64CC54AE8DB48E7B66A633051C04767D708C98BE328EF865431B29348D7306D389287BE9F41BB23BBD3D7A7A3C5D4C3A5F171D574B0640EE6927C1E96F2E9CD0A1BD90430D42A330C93CE66DFDC65B067D8F173EFC0EED00EF24F108B143F589AD94D0A6FC98798C1B63510734A7853D2EDF70A1918D2780C23B12CF5B1EF279604304160364651965646E0E223562381B36CD81FAB31D436F53A9D65EFB3A7EA2092CE202C1ED7FB9EA64AAB6FE7FE107424014E5AB946A3EFBAFDA9619CB7A603F11E9AE507098AFF80331075B06AC4936A711BDAAE97057E31521D5479E046EAD7E8F024E3B9C49A8A253C81A283FBFFCB0C1D896D99E881314C04FA7E0C9DF25B6166F57D97065E9166B37EF612F702E6FF1C9E81F0189E22ADD54B9F2880B23F1D3F88E120B89BEC9C699BFF18DCF870362F9B4D0F66D7416198864484393156D16A7069C0D385910DB49DC9FE8015851DC43E8B03132444BEB19B60DB6052379E5F41109354C0350A2078D397389228726C33DC492DEAD0D55DB917C6E212ACEEAE78A8530DB6A53C7A566E91E1AB62D3AA16F2736CDCD965D38D945E8A15EB68CC2B50A9C5E88F5C40B8F67AF4C36F241F3DE9EC66911937739F8F5C56C28CEC16FB453818178A3698D639A7E9A215D2F7400F5FA0772485BD75A58CA574CAC9BEF89F8F3B554A92687EEA5C6AE9651D9CEC267E13F84FB98D43FC7D24895296D78FEC1B2012F732092511930FF78664E926A57F23D3CF17BF19EEE27D833B88B6E30BF5AE5498FA55EC0D14FB127D5E6EE80560F540FBE26FD81AA62B006A139A065C11B7B48B2AB038B522168748A57DDB6C0A6CA0D7B4B79527673E58617F22F3C1B32FEFC787B41DDE9399549B0608478487126611634E5166BE7AFAEAB42F348B2691A1978CE61C753A049767A02E7055DBBFE771ECD8613B3AA29622F2FBC06F9BDCD9C94D0FB8C75310E2D4100C5248FFCDA8A898AD331BB4ECA6939FF31094F418BB8BAEC58AEF7B6FA33ED8588A21B437F4AD5EA5F2D86C4DCF1C4A559BE9B0C384AD2AA778EE93CA70989BD2ED681666CA8B082B7B83272F8A10E2D245628C8E1B5FF3BF8C5FA9C6E09C238482679888827D0E3D0B9A8CC36027649B0798E14390AD84D3D766DCEBEEB670E3560C6378F90A411196365F4FA6D332244EEF1016085C9B51614D8BF3BB44A67C906E7241213318B714824C03D9E8927AB2ADFFF50494D3F398F37E6BFAB3F8E0B89643FD220DA424BF2D751D07B5F335944462B374F297726DBBBF8C3A2D7B26BBACF192C05FF89F0878E26ACF8275644CB85C7D81022D1E85FDE63E7055E1202B85E0118687994931DE1617BA91CE9054327D3DC9DA0135DB676E9A4388DBDC3727DFCE71FCA2CEE2B2331DD836086D86C3F36767BD2F210B7B8CB1458CE8252DE845F507D78C93F7ECA7FD8CADA3DDDFEA34D2FA9AD31F10F02430C884F65346840E4CA5CC54572D6533A4E2417CF859185CA5B905BF83135BCBD88C0D86CB7C3344674F8A9A09BFD460CA828BACBE12B661459123201A5CACEBB6EF6E449B049552AEB5EA305B870055201B4686CB255E12BB1CA67DB46AED1890716672A898F71B5109A5C253276C42A22ACAEAD6E4F0798067FE983494752574A612969F1C923AD5718362E2AA1C4E5255A777DC6CBD53F553B0953BB464EBC29AA36E3F72B5C6614FAB08CC65F540D662599D45269754C0D6BE109BD7E0DF04D5EFF30000D8D6AF25B5AAD51057C31C4C134C59C3356B34638692222273144CE9D768196749FCE54DC7A7A1E2E36192FD7E756994E37D0078850E81D2D9C40670B77A02C9F708DA28CF2CCF478309B4279A6C45B9FF854A5F5B553CB291FEF5D1970883A064200D2C99597829F15DB4D9506C82154EACC4FEB0800D268902B462FE9D3284D89D83A7009AF5BDEFBCB310608151430B779A6FA4CBF6DF1E13C4A9DEE96D6BBC0CF989C48888BA58316FFA0114020B5C326D723960FC20DCFB01DC50982FD824F9512AE73E3676ED8040481CB536F851274087BFCB77A0EC7DA2BE274288D2212471DC7949EEF77A8333AABAFB57581CB43774E07F192B825F14AD564658792A0E235F4DB5EA6E3A84403492E209484542C2C2881042F54CD56CC00F2C31810EEC70D8386D0C8B7E4756A77B11563A42BC3A5D2A495D0C8278810D55EE7CB38D80C34E4DC58F0A8B1EC6E2193E6184E5F0793AB882051EBBDB3303D86F4A0E22090C7A957BE5F7BDF4652FC8F38DAC71257B2570D5B1DFA95BFEEB7E377DD581A8975D72398B4D258B1B9E7DA60217FF77BAD7008FBCCDAF7479573F9ED6BA8D13F83C233166D8D7A400F00840887BE510EAF1CF2E30B244C9EB6E166C98156C27A5FF0DB563A204B830C8FFC64D6685C9E3BF8968F3A2D2B329AA6AAB0D49EDEC26C2B5D7462AB465381D5431C85268EFB89F4E04DC660EBF4A0962F9C9F4EBB7F2A1EC5B3262DE971219FB56CF42CD720811EAF66DC2C428F94E1DE4ECE5F2116533B25E65D732A4BBD5221D28EFA946DAF52437AD6657703A9B454422C7DADEBF063E5FC433536CBA84E07F7086FE031A0A2B4DACDC99E5D3486E77D41D949EBE69E14BDF21090646CD9FF8E9F0FBF5E737DD38C0EED3D73D22A7C23AC781341109997594B3D1D4153AA1A35FF7AAD5636BFA9BE09E3329FB61950CB6DA58600E05DC2782B2EF58466AC9A4BBF6264D0D616968C6BAFC496F859EE9512072180172E91E3B581FF5CE9B8AC0624F221D111BBAAD988A530C0CADE0C4CC399EFAE9ECD624F55D93F9D0F0FC915292419ED119E177095880FBCE058783D85380F1F6673B7ED6702446098693F3FEBB9C9D7906391608453158C695D073B259518AA7DC5125B51E58A5170D1A68CF6CFC1A705B344911A63875080B4FACD9835AE85294D03EFF6D3B02888BC1D094B9E7374CAABBD1D0C32F1786B8CC12D0E4C76BC99694A1862A73ADB58A20908A601ABC4015ACC17E5B0AC28F3D8896F8BF0AA344B814D63CF558E0CED39D1F7B16D411E014BCB594F37CF18BCF46EBDEEDF1AECBD13ED97AD65A0674275868F34148D6E03E7D802258987937DBAA69215216F1CDF8BA2BCDA245D42A5D9891CF0ABC804595B320A774F1DE69F8ED595007A59F1FB570D6D024ADC97B121C28542E3043C3F99EA5EA4BE47E3DC0B66E297477537041CF880B5FAF2828E3DA2D2F9414297C59F17ED60E2DBA0502E8FE6B8E5B13FE2E945B2E78277C568082F678E4F4FF2E323D1E0AF996364E2AF2FC95C53F83953028D38BB168A1FE68C02E4477CF567DF6C2A72AF3F56EFFC99C0F5223E4CF32CA3B97C700A40803E3C91DA686DDF45A47208FC904B2384730F050A9E3440CF9A010044F7E8B6B0FEDA288F810E27AAC5DAF358046D8AE85AFB6020C22986C4788E07EFB41B2C18C482C72027673E9695CAB29FA04ABC0D7C790D3F32565A859696B6C036ACB5A6D1E444CC7D9D23B3A8FBE6E2E851914711EF790E8CBB097ACAE791825EEBA70C3AF28E6E8EFCCA38CF6B6F466D568100ECA07BF3B4B8E18EB791A2431A7FC2A795B4CDE07A38E1662044E81E85667BE36058095C7F0573D930CACEFE4C97B3393F8400451AAC6B55C5399826D8C7746BDE6484D4377BDFAD25CC5CC17C774B4623BE25184DD627CE8E6547788BD7CA2FABC9B7D4A602C457FE9EFD82B79E9322F99962FC7DAD35BFAF85A03D67DC7E83FD3C627160DC96640683AAD733B3D1EB59646A2533B99EAEA4E5CFDB2C94A8724B03FC4B72BB5BC5D90B0D4A136E44D64F3985A7EF7C6D7C55B61486CE529475F21630DD824F8AD4D3FBF0CB2C48CCC0DC27516733FF5BDC1F459B00B88883006AEDE6602DC51A316959DEBEDC0F36BBE8D017207225C1C2BD94CFC1CC60933CEA2ADE45BB4425578F4D28E0AA36DA346E2BA4B34B65BD7E71B9FCC3B52F8C425AD44B5CCD006E26857FC5BAD79D8345C5FACEAA4DC3A7C613D085826F82F10961AB2BB7C087FDB490B5A082B2F5DA5D9E6210D6E8B37ADB10DF510990F3ACD81CF93965CAAB334F1B2A76D9B17D758F273860B074B2FFFB88D9B5E6991EDBFC5FFB54325BFFC0C66092E7729C9971101D7CBF74491CC4F54D535936CBC5455E3215215E836500F411382CB8658BBB60636BAC343A645741FCD6C5E23433EFEF4F14967C5B742BDA45B2FAE1946FD0042229A1E462E172102124540CB203D58DF1EB8ADEBC4DCB37F8450DBD0FEC87CB4A56696141C9513F7D6E61BB117B0E35E1DD314837965004C6C86388C2D3EA57EA4C0CE9C563C68F5B3CA20043742BB5060935C23FC7FD5368EABE5C1A1B715B99B96E1B434229D3ADE0129AAD85710596DF9AA2D86C7EC88B9552F876861DBAD135B4EB318FC6FFBC3AF0C98EC57468A0F4BC3A29CF1625B03E33360D152B0B5F5706C169B68C7470379BA15D9188F13DFCF789C18A9DA14EAB56DB261F978D9BD894C84C1BD203A777DF785C82B87FF975BAE11437F9A243627A1715CBFFEED727B405C545542A7BED9395ADE1A671807954EAC7C9BFB8785F18D5D5C31A01320E7D863743BFC7852E251631A03EB671912F6138C21E1D62D88E1941095A8DFDF3B052A0104E72C186BFEA9CAF32B2FCA121FCF6A3D85FCBB9D7978EF2E227F321C1BD932A4DB007CB2DFE3BFD9578BD7AA6844611E4F3ED7E5370205A07B6CBBFCA7AA204D76CC8DCB9A1CB6FE6C4AFC5E5A79E59C6934D473BF834F69B89073DEC0D9ABD347B12BA21E308D42D1576F03CE4BE6EF8F07EA08CF1846C27ECEE7F8415C0FA756A540E42738892C7E6D0F90520FEAC6160911BB18BDEA2A1D925CDFBA7C585DAA3A3D27B12E4880A9B8C87B0EB5EFD7C07507D8C3B274738C90EB4A745C1AB3749ED000075E99277B927B1CAF2E19E8D588AFD3CF9BC0302724E71F129E3E3BE9D114542B16C4DB65AC8529CF95CAF7A2EED53548D1769F809F1780E5102D80B7E52B99203F5CA6F2A2A7608171190EF391A4EF5384D15C101895B5402E8D4FEA052872FBAF6DC9FFDCD3FF9EA884ABA4D90E202206E861B9785AC572A0013765C24B5E3AB9C4E31A6B7F958A4D3DE78CA4D4C097AB9AD50E588BDEC45528EC7B248BAA3BD3DF31F8FEB29F823123421388A2A021F37426188CF830BDD10C75BFFFDA15623B33F89567EBD2EC66EC7DF533CE8F33C32EBD6D074606380F37F3E9D186E4A93EB098B6EC0455843E7784A9CCC67E0326920223993CEEF7E4AE399E21993CCD078084804EAB9881B6C40CE2B20BEC97DF60381E930CBCC038A4A9153B2AF6AC6F743FE6E2FDA9A0FBD4C00D93C972333C8A8D99041D8C93718CA0CB864B5E50059D73978FA3FF33115880D43D93B8512246D82CF104A4B525F6F8B95AAB9C8DF02649497A9AAF01EB4C7EB1E232738557175E6090C2F657E9DBAD6F90860BBDEE0F701236C8489A7C200000000000000000000000000000000000511181C242D333A", + "reason": "no modification" + }, + { + "tcId": 44, + "testPassed": false, + "deferred": false, + "message": "72CA115375E612297C7BF0460D38247B3661F5ABEB7CF4E3278BB49E2DF2A96600F19D95F67BE92F99DF204D06ADE7C8F4C04C527AB5F70F6007CE5F16AB099DC8F7F4F401183C83B47060E38B55EBF6EACA4A378F725EF4E59EAE32FE9DA0F9C2ACA2F1A4D2933EF8DCC5D8A9DDAE0E3ACDFDB6A5CC4A6BE998C79557345F79", + "signature": "1211BF1AE554B57C92AE74BD8FD1EDA9B22E8993D2675D2A2B68BE5E075B1815DC1B65582426A37B0C6B5F4BDF20129E0B1E04BD27E33888148ECB88A0EC7CB7CC58E3767BFE3538E24996761C624377D2150C41D59E18889DFE6B520CA7F7134B2198F4046F49C93D17670D314D856175E6984EDA6EAF1136FF2504F9B6B82A84C72DA8CA0DB3BC235C7E50E130369A85225BFC014F127A15438954A2837EE902119B26AB40BF6B7C44737B535C4E97EE475BEADB0F3F94510D05A6314DA421EE021A06DE18374B7AB1C3B4D024CF66AB103A010E40D12D3B8AB73980728AE88DF3172C5267095618070D732B52BFF4FB42FB68C9DBB9AF8B3A09E535D7F65ED1BA967247EFA9B8FB7CA86B30701E1F91553E01F95444A52F76540C85231E114A7661A7C479D8CFDFC0FC9522914701E446921FF84D1CE4C06DEB0A4478DC2ED341EC19BDDE823603DDE9510F71B5CBCD4DE3F6633E3FF4832AC830027D9D73F362A01412B14D7778AFF81ED02DF5E2DC21309C79D6397BA38F620E98D65A0DAFE1C8D54FFB0F6E01C6489679205F2F9191707C755C4681A23C2224CF3825AF56171A892066EDC36011B781DBF79F7847B8C2CDC657840501A5D0361E8FA9C273AFEBDB4313603A50F803ED419C65A741A921D25FB60653C8EB57703EF4CCDE3CF251DB65A6CE1EC4E2BB5302F2F173E717C180998D3116C89CEA8C60A85AD425AF90819056683A299F02D20514CC23A09EB5AD82514FE04CED2E51A11817C38CF666DF186B52DA61687E40AF5EEA73A07C37C3EE76E7C72F957A83788D4602664ECFE8911C353CF34223701AC2244C3B2D13E3B0729AE05BA52CF345D63A33E0D4C8829088E392AF3D6AA094F5AEB09B64487745F555A3F6FCB54EEF667A8E75D397E5825489B3EBDDCF86342372777662661061549AFF706042425E311E3584035E5760D3ED592BB84F236D8A1DFD94A49BCEDC2E23CFBF8DB8DAC7730FE9BF8A89F7A7A12BC4627E19CC8E55C7B68B8F92BF42B7686083850F632C3BE403F988CEC8EB04DDB206664C5123BCAC26ECEDAEB75D39217A10C2A366C052E54D18EDC9AAA5966B5D6D52B31E88F1BF4E986DA2B46F7B1157C06F7B924DF871BC8F9387FDB9073BED2E883B43CCB57A9D7C8DAADC44156D08BADE88FF9B3730829568954EBC46A75840E7BF40CF4FA994B0A7F03D3307001E3F98073424BC7F3D43FF708DC8F17492DCD0997630F912A16FC28F388B81A0262FAD6BDC1830348616A56203E8BF36CBF4C96B705A6C7D77DBF2E89B15DF185B3ABE8B58FA594C247E7A97CB9C616332B50E4B14644158F3755B4333B09564C26C15B5EDD3403F526CF6F078B49EA32AD3C3051A0EF7230D43DC09BD102F28C2853292C108B3D45AA2402D5A7CA29D9FBFE922C2F9513CD1E6B76CFBFA1D0FF147F35C9ECEDBC96FA0A33FB0EEF37245474153CAB8BB1313BB3A328ACC1D2D3DF243C439BF014855AEA9D175000485168C857E47C43CDF01D19F5480425CDBE8D2A0243DABBEB1D2DF43FBB93EEC2497EA63FEC6434CD256CA73D4D0F173939B82FD9869431E86AD231C3DFEB9856B4B416F018441162EC0D747A4B90DE0F4E009E002BE016570A5617CA1DBEB5705C56DDD028CC5D107227BE307AB3E58FF43CE039F5F20B9D84B60399570084C5EBEA82CB74C2033E6C0CC65E557569BF2DA761B0DEFF5CAFEE2366C68561BB679CB5A36CD8F41228E86E736831F825E5ECBFB11AD0795865169BB3CC17DFC3487763DE2C9F97AC9EAA39347AA0CF08377B046E83F7DDDC021AFEEB96BE53BF0B2DFE77288D7EECEAE08A36E29BEBCC8328551982ADDC2FFE40CD0F2EE075F2FFDBCBECFB188793BCCD837FE62CA5C70DCA57FD4B2D041F7D6785223BD0160935B5255003C850BC473171302C99CC251B2D790FE0A4A2A12F98B1DA0055353CB9AB3A88DC2C5BD1E10A3BA0674F3B533C9FF5523C6CE691684CE2687748DD5B04F7B8C0472DAD3CCD7B897FAEE9C6977913EEA790FBCF9D78B29BD0509A7B7422EF951CEE5A979F54AC17CE08D666D0B49D7286BF064C11F23EA72C25A2F4AC497F9D4A7C2F5973A1F9ACDEB383498903EC9BDBA617EDA67C2F1EE12A895F82729CF0B709AAF901DE1636572F39F9AD56E925687B5425EB9BD69E381F706E6F5FAA4B171D8233B56FDBB27B949486F46CD13C803467A654EDC7626B2D19874C1BDEE25C4EA73B007323F091B8C14710EE1736D88FE4EF330CA52FBC76F79FE9A102FF706261A999E874C685A3ED5B5E2EE995CE1330580381BBC62DDE13F917CFAD6811DCDEFC9B3064CCAB8CDB8FCD125187AB46B335BCAA7E69C9C2F5E95A94612362B3473F6263D5B4BF635867631D609BE0039D32DA303AFCAA32140F9D08DE2391F7F8D2566DF591C365D5FAF0EE3394DFEF4417DAB1F404005B64764EE9569D89C13C2901D0526CE45AB4EB6198354A97FF080B1AF57C06F4F062A6C295F8AF86F9CBB49922377354AF8C0598B2FDFC0E51AB9A429E9B973F5804704352717FFBC392D094BD5049C1360CA561490D5B57F2C14B40A6FB7597080A28501BB2AC61E38CAFB10BD97226F7CB9089A9D4F913345DA269CD4FED4D54C35F4908D97FB1FD79B84A81209090E12D642BFAAD5C6DFE24468E9D0D89A422F78308F0459FF1D7D444B63A37D91469EEA6C9F6118D9367C76FB60CF50A731F8EEF6A1C19C7DF13FF83C6C71026A8C3079C2BF5B430CAAE7D7BC42D2957A561E22895365AC8126B8350A2899CFECFCDF24357D3D4E19A127E934E6313F65B9C6E9E9FA34650F89EC90A042FE8B152D75B900E1CF4EBF10034879F279E3321D80DEB7161C5F37DBD5D435E2B844631F9DD6590ED6C33A5BBC30D71FF6A03897FC11DDD6AE2EA9FC6B51EE79918EB583F85EA0FD4A3F54E4458F0ABD971E9FC9056C9CCD91038A19A807CA267C6FE287B30F054FD8C05992B405BC6C509E7C7C1CD7E8AB2609AEF6A8904546CB727B7D857E495F892797FB5749EB043047E553647B408F55BC0E22DDD8A05C1FCBED4A4C1C70970A75EA91D7B38E30F47226C9DC20C9286935AD568D2024550E5865BA1A807EB1CBE7251D72803D35EC6FA561780FD088B19CD7B43D089E47EF8ECC1B4BA5A719EC6B99F20139718667DA4CC80BF793F1E7B4489B59F0D8EA66A5C8B70DD3C8CAFC9868DC9133F698E76D0543243E6DDAF6AA06230941E0AFA461CCE0DAFFAF61EACDF6A5BF16E83ECA3EE0E47C25E831AB9DE3FFE14C4D225C1EAB929CE705A22ACD28F59A21072F2A1FF2E13510C2EB55F379AABB00A0F900D1BF6756FFCB8803D860D3CDD3071E6063728942A08127A2C8535D751A42E319B012110F14EDB97FE1C28E9BBACE0523A4CEE18EC642E7DFCE61A3BFB6260FFC3BAC8115F5050617FE9B5E9842A4FA4D88B6B4EA76F71AD5DA7ADCFE47A68CDDF50A9EF291D1444DB124A36B2105179803F741B832A41ED087D11CC4DA31B5E884243CB9640E0F7843A70C681486C367F53A7A7904C6E5B813A69B26FF695B4861167564C7E4355AD14215AB2B083BF33B540D067F741DD2CC4DD423F4F22D00971534B20D7D14EB47F54F8CCCE544ADD50806EC36A70E7DE0D6E92015012B238D2CB2D7BFE2FEECEED2384751A23157F5BCA0CEA478DAA5D84BF6A4A0081C1965B575C6FDE2B0812660398A3365281768D7FC094EE6CA0B9E82F44329176AA7236F360548316E538AD9C17F938CF0548CD151A862282B92873D8F1506B1732735E65A7DAE16E20982D8B2ADA774D16062A389A832792E227F6444E83225B7A53CB808D37EBF4A7A520D93DA08EE86C51EC5CDE210EDA7BDC978E0186BBED9629FAEDAED542FBC1224E6D2E96770DBEDD19BE12192330EF7309216E7A1BB10E2DB5A903A83A4240D9C241AC877C08EBEBF5FD5BCF7B762302AFCB9F449BE0C21EB01D69CFD4F770DC67529DBCB7A7926AED09EFED76990D2F6FD4AB731F8817CF3B72E9D4399E498CB2E775579A23DFF83F3D452984CF536C1780A3BC3CA8F6687FF6671D54A099F3FDD7E136AFA71D84FF2D4026546765414A88F6EF70E218D77B83F3072251A439C954E7FFC9DF07D8DD75B05C4948816FFC18E05E80C178E5D4410240B5415DC524EB2657C6DB58F2DBA84FA5840C881DD071133EA193D92AA42F5A0F2ADE18F23817F5A2D89517105A61BF75CE208BA92D6DE21A4CAD67F7842A6523517F66F339777961C11084DAE3B20D88F62E4721CE8520D6429C8A2C0E55950E62342B7DD49DF933755B9AAD0AD055F8CE22A19DE1AF95207BF5880FCBF68ADBCDC6694DBA88920D57A768D5485CABF929EE2574B166CBBA5E8F7604EC6741DFE4388CC2BEBCC6150E87E1B9D9B2770F842E3EE68E15941EAF4DB429CA65B77B457251A7424CEE4E75B35DD03E35E8A4ACAA25968B26903B3F81EAF7EEFF5E96B1F911D4EF5F2CF3A18F95DFDE4B001448578448FCCEA9D7D7DA4D099DB0C3CBB54EE4AAECD771AFCADBE5F8D6435D9050E75A7246ED9E7624D3EC62603A0914E4DCB495DA579B0E9BD1B246C84CAE2B12849DCC58ADCC1EB2B7A8ABDFD31CF1505C398BFDC783CAE10366C78EB0E67E3AFDD9FF8FF57AE9F5904223B054B72ECF1B929AF0777D77234A5263446F3FC6324BB32FA2F8816AD713C47672E147DE009F8741E97023F16162DC5CD40C0D2305F495911325027A299FB7A2C4B5FC8A95315A7BDB3FC27DA121AE5CBFAF825470C466500F82C146E2537CADD7D518CED56FA41B52A8546FE4F3CC764A5115CD994704EEDDF98F75DE7D38E59A0ED9CAC4906FC134485DDA5253D4FC77F550D5E24CBFEF5C5FAEC45B7276FCF21D27F6939BC5FF768D70C1D07E41253AF08A91978F60D7E289D664CAE8093FD0EE10F0BD4881E0A6F00632BF18FB04496DA0B266996372DA181594B5FC39D4595F65EDBA2095A92BE0A8D30697D5EBB5E99CEF9BBF1B68277408D17F79EB6AAC978CD468D83AC4A4090046F603FB434E9B0A1970D65316E97664F2D3965B92AC6E970BDA957321848A77275BCBC2392A640E6697A06781D988E05C23DCCA29BCAC0BC260DBC52B1C1C0DBAF67A4C6C04B7063F00A095BE98836C3A48CB5C7F21C6A58F7EB3D6F71ED9A6DC8495B7C4A8E1FA0CAA350523B7B9AB67F6437EBFF921CB468B8B8935FCCC917FF2D692380F0630655B14FE547CC8EF7425F21C1438BEFF38E76207B752CAB4013F4167E5E5DD5061E9B31B785E7AB042EB71074432B5C078878BB9819757CA9FD287BCFB994C850A247C2F2DFBE787159A4565A54482361411321418AD24BE572436BACC704FE8D4CFB60B7355E1FDFDE349C73B9B4453EDFB6390A8EA3FA5ACE7C66D125938E16AE96DDDE4B01A05B556E766F3785AC36545D958D5EC52BA88676D4F8BB7F90EAE8FA401DEAF1387405364743CB00CCE3D1596C3B2AC687C6748B1925421C1161A7B757C8301FF9DDB64D25C892203DA38830AC9FB2C117A92B2837A9212693931ACD8D3169ED009AEF6B0509524A66B2115DE79EFE725C9E6BF718F00FF39E22473F5020FF73D82DD780C85008655B9D9A948955CF591C76B01B55F7D964931F6740F14692D15A94774758569D73F6CCF76F282C81FDF08170F50431B50781E19A915F108CB6934872F092FCD7F7F434B5B0229A215C0719478696C718057E0EC56091315C3395EFB4DD1C4B03A5ED74D0B739C174E938CC65A5E07507F439262747BA5A22E6E14161A681106A3096668224AE1305C97AD7F22173B6032326941AC075DFA9EEC0B7B0C1C3C82170FFFD43E173AE5178AC6C50BB7314A502CF4179F876DAB4AB0E20E7F6F60A730BD873ABE401C6245AFFA904EA2EB53F689826BD6B3C5B18EECCE51E8E02F284497DB7F2F7DDEB992B926EEE37DA59EB72C2C853B939EB6F9C37347032ED5464325228DFA9F8AFB92BB4CA4CAF01D501AA06CA09BC3E8FD830FF9776F6FD6675721DD8FFADB62C3497D486C3835BE0F715BF68353B56C4C05040F6954366EE383CE3020E946C277C6A843AEEF7085C2C5DD80BC16B2AB45E831BDA62CC38B25F987D48BCC3675D7CBEF0E8A3D8E95D131008172288034EC978D4C330C2769072E335DA97C8F46A1D91998442C144A8343776B108EA205DAA5AC7C7E5141FE11A1A045ADE76CA5241F733165AD2B80FD4B6A3FAA1E7FBEED3A5E0A93D6D2704251D5504F47CFC3CD7CF4F34BEF0B8E5D8221FD7D94C4D9BABC8BA952EF3FBD8B74CA4C167E123014594A46346B5AD01C48D695565ABE8FC554BBCA4CBC1D42226C06AC9E08F27578828A2FCFAC732A5D96DCC889517F182C45118456F914378476B3176C3BC0AF7CE0EBF92DF820B3A7094BCA1105A9963D8AE10292FA43DC11DC9E99DC6D61D9D02F7FC96FE65B2A33143445B65CF3E414F777EA8CEDB7B844161839BA4A9B9CC4049AFDDE0E1FD3B3C72C4F3273BA5F2F9729098F900000000000000000000000000000000000000000000000000000000000000050D0F171E23282C", + "reason": "modify signature" + }, + { + "tcId": 45, + "testPassed": false, + "deferred": false, + "message": "836BA1D986C11F4D70FA74ACBFEB03E265591CF909EDB3770DE8CF10B5BDABA9158DA368E49AFEFA0D0C2ED26FBDA40FB427E9EF98A7C826D3857485BC2C5A9FCDE36A63FBB70A4F49B5A1D21487FD816E8B3D105C788C7FF19E20EEEA48AFAEDE42596D3E129AF13846682526BAC5F4745ECE6CDB39E12750A87695A94295B1", + "signature": "7E17E986B981703C6B9C925DBC9BD0FED0043D532C3D10BC26F822F48EC27A489D983D33EB27D647B1E1BC79F35F61FC51E69B4B4E98AA108507DF2A521FDD32E01B6918298FE9B709B9AFC62D807CE4FD00F8FC7D57B9BDC8F26F18404B2E4C4D71BF87FE960E409DBB1E147DF3EEF02C22A277C49C34A086DD0A3A7DC578C2CBDB82D8ACB98749D5739836F8874F06A2C253D546B59562A72ED7B79B1421E9E4EAE922D004D80DD374B30AEA20677D1E38107161CC88BEFE64E68DDDC18BD9EEB7301671F3D6E3D69E7F53D5B8C59369059CDDE011FE083465B49D062416036BF9C93F3E73F5B96E4C035A79A53A935FEF300872CEA993A8505EDE7483224E3B07090BF480241000717E000F4F3A6A97ACE6506DB1D0939F0551EDDD6A6AF1283662B9AA677FFF5C37441959AF5ABB88F92D8FE2919FE36B6C0FAEA55C3DDE54BC201617E8FD1FE41D433650C59E96E247D4C865E7F2CE026328EC144C83BEFF286B1636F02072E3EC09225F5CAB89B555DB19A052F4B22BA855E644A4C0B77E211F901BA066DC7E78AFD572464C0155D2DE4833E98916FB2EA796E856DD6FA709AC3009DF271105600BAD669397F0695DF7D89BECE874BC70B27148A1A1BDF62BDFC5659F66F8F872EEB2083D43B6935EB8F9D9DB1F0ACC791051BE61DC1856F6BC397C25C33A324749D4918C4A91B9932CFD68895DA61944494FB1ACA3C5FD846CB6288E6307DFBD91C3AEF99C3EB230DB7039D48F3EC3BC0F4D200F8749D290F858104355C843A1C405DF0F7414871FC08EFD3A65E437C5F37F60E0B0F189D53CFE6F218CC749BBEB14DC81B293673B0690A058A2D03749922AEE5DFE647442CC39AD04B2045C04EF7C452A3636EAA7482AC2E4CA4B4922223243D4A83D4FEFE91E7A44E68F7266BE7FB3756692C3E9D73F025A20A375A140B936069E59F759BB3D16BD01309F9E6B2DEAFCA8FA61A72B982F104AE39EB426E01220ACA0650F87D7DEB2689F8F6DD169D58D353960D2657AA434D40ECE88480467424BC60CF737B712514738B2154F464FCFB3CB2FC6B1D6D347A1664D5A494D593C4A69DF1E98FCCC79DA39C06237016F0F25F8B273ABB98F9E3935B03EAF0A5A3F415B98ED2CE6C9309D21D4D147ED07FA05F98B0431E6C22F79A31267C625F6B4E57DACCF9E60891403D6F610E4E0F3E162D8A5167019F3332522E10C29963C2641CEF2965D516F3FF0ACF416FB029167FEAF09C214ADB16F1EB9750D8E929C0A908A3934A7A75028DD343CE270B91D1751B527E480C94F6CFDFE9BC9C9CE4B0FFCFA92FA2F1FE7921BE4E22AEDC6FE4EA8D28B5A627CA3D39E3ABC67CE5B1BF044FE922D52FA6BA8CA194AA0518578697C7723428B96F15C0D8D918E17A360B1A0EF817DFCED301A15FE536274BD36268ADC76572B49092C5BF4ADDB5453FCD57A31D9E23C358126A4E59170DF831A1D62C3C7FEE6A009E74895374A7BFA33DFE98AFACE0AFCD61EED6BEBBD9B5A2671D8EBE4BDA3A55AD2276FB55A52E27809CD8CB471A6B4FACA92EB03EA5AAAFA4B8BB1CDA709F1EFFBDBC63BBD545AC1658C751F180BEE1953AB66AEA4A129BAB458E2DAEA62FA3360E744330B2F0293B609E4E3AF482C8B116A7FDA359E9ADA3A6100BDE1F1458A6CF696DDA2923779F19C0BEF05A4C103A4F239FB5133DAFDB651CC78F3D0771B9B5393D1F245134141819737E506E774509F96ABE3DF1B5F6224981510ED4D2D3F8EECD9E2A9D0EC0E4B891FA6D8D1BBD6D0925B88AFCDA59B8FE9060633CF1AC381B73907A923BAD827EDFAB05B1109459596BA150C3E9BF15612A1C3F94B3ED874E0B0218D470A1C2E219AD9ED3E63476197AAFA8C9BF7B179E74961EC099A487ADCF5B56A10D7B974F6A8654E1DFE5A981193601AC718B99F721149273A82A7194575DF5D58C0E4542F6E313F24F6759436F96F366BBB3B4E7B901B33A4578A94E61E07F9F880B47897DB078D7202231B950CE64305916B57052C897689020898E34CC9DB8628E009B906FC2DDB56EC1D989F2C5862967132AEA827551F15ED16663C3079BCADCF570E05F3AF2500C6664063A798EF4414F6DA77640BA0ED7848B17CF614BA3D7AA909A93F050E393E37946D8B59BBA67D1E510D418246409B6A5BC6DC6BE13B6F355C57892CC917E68D99172648268F09FBA9F5319478E34C807327BEBE2EF63D366E50535603562057022FA4300566CCE7D0E7F9FC9F9E47CA89DEF061ED4C70DCF0578EF7A9CDB0345D78F091419E25BD38D3A51DD8692DA19F9AA1F3965FC0E4ECA0A9A7467CD27A61CBFE892D65F959049DEFBC9F1FE3D6195D067BFB6773E8934539DEA3BB0520A4B07FCA5BD61A2D63307F8F06158CA82EB71E9BF5C356DEB9AAAB2547848FC88A6DCA74543C50E4B29B09BBD20A0F45C95DE94DC7D3AA845422791CA69E2D75868111620EDA5A3F9DD57054BAE58A99FC9168AEA69D00513DC860CB55BC3FF0393BA3A686A7692CE2A76551C34E56AD3FD6B617618E9227D78B3468D9756290DE73201BBC91DD41F887F6174697943C080A3B5B068E3406DB5A03457F85200FDA20D32C36A11C26FA26B98C32B3354D9910DCA8D91C487D795DDE0A45929293285F614F7423C85FD5DE6F0D8EB5D8ADA9D93B51DA697FDDF8D7EF0652118775649E1CDD74C4D9457EF3CAF8B372F6DEF2BD5B3754ACC0F5CE3F4DF005B9F2A259414B72A1EFF73E15E7E161EF1C5BAB594CD09AF3BD8E6B07C16155A3B2DDB171285A5341893A5929308DCF07D21C46DF7F1AFE4E7F9F6328CD09055D616F7E1A020F7BE39E958EDE7A6B63E4053F22D77B72A2C9F7B977D52BB3CF1D43AFE3E477EE04D2A8927371589CFB65359D74E46474952C5780F23804FA89C7171F4F9E6239C66BEED14D08AE9623885EBEE6C3D6E55EC693A3D6426219E99347619DB8994DF07AB77142BCBDCD4F276D4EC9091D7C04EBA33FA51530559A8EE014DB9B6BA9593DC62B7D51B262B2AA6D4FEF6E09BA103B697530C1B8C559D5257EE50E32ABBDFCEC786E96DE903A609FC1813A9D1279D5D23F0A5A51362D79DC24DE3CA4C252E1224A35B4E63075CFB4D75ED902043C6718FEEC7EBA6A3F7E8AF52742DDB3CB2D069D76B8E2403085C67B54BF15FE23B813708E0B076070D00C0462461639C9CA03FE487BE8ED5EFAD12747E5500FFA5485345DA9157A64EBA87E78A9A8683D2C26B797E9D15081C2D5250382D79DF4E4D6F9011467E25E9BEED0BC3D5CE410450C6A44383076E720BBC8E54CA57591F67E0D3CD41F53F40048CD1350400F0C0F0B0C09B95825DDC2019A140FD55C3FE6C5E39E2E539DB1179EAEA035AE6994DCB59EB5EDAAA83007CE7532B41E408274900182D305ACE4E50F57B46E7A17376AFAFE7ABC6F3E86A4FE0A3F9D9CEC4B5C05D7C4D022AD3FEBA6F091D0781DA85AB2B7B81851C4D4623E8273BF05C317090F5F1C18ADABBF04DB385FA2702AE48D7B7563B41DDC549373FBDEE10B28F89857F941D538BEE2A53B5B83E3E5DE203BE4254707E5B8292669F204C1D3950C6D47A169C1866D234A9C4B9EF09428853790828AD99C24DB6978D7A0B9D6648685F8B49F5B244BC275E426973AE36C4F3F7F695A10B9C9A72CADC969607255E960AB1C4D4F88C01664A8D825EA6C3E7DE4D6E3E705F072ABE1888EEA6FE33054A82BFA9E8442CF3B10B0294FD66B5E794837D0CA7806CEAB4D388AFFBCDAC19C8FE6D11C3227820F65AEE73AF7239804AF08C28D08EB349E4F568B5A9F9791B7B14F7C5EAECD4F032E6630CF1BDDAE50E3429FB87DB02B65066148B440FEC27C4959F63A24A3D1B019A4266764EACF703EEAE3ED1C4D2B3896756B59132ACEA166487E0A92BCA671761CD1C6D1D0299E1B7092461F9ADD6C268A10A5208BF7A6250123B1BD1EFBFAE63356654E63703A9F6CE8C80B898FB490CAECD58058F9ECD5398F8150C3F07A0CE122F346D9C75C9B3E4DC2E7D7B57EA4BE32DD78ECB95D84C2CE3A7D724DA41205CD894D843F87AF5EA8722A06CFA4AA2426E7DF4C9C69E8CDC4D6C7FCA8AAF0644A3066BF07F3B7CD2355F8641519DACC4D77ED8AADA6FEA6560073FB9EDB9CB970F73A66EC4663834B0274F9A6580017D4A797231A3CFC2134EE206DABA45198B02DCE3E534339924B66690C54436651D68C9E217AAAEC59873D822313E03D7FBA864D3CCB469711444B764149AC3B2F844153D8C8E8523FA8273700E13DAC42D24C9314A13EF8CDC500B51D85B7274E876E6FDA8E0FC7DD30160602DAFF6FB0693543183DDB01ED4C3F47949C314F32B7E00AA65AD8D9692879D1F9C0636548F60944F4179D90D89E63141DD6673C0899F181DDA52B958C08B53C4C63C5C49532F500D15FDFC28A6A0CE8E85BF4FC6AFB8CE196E1A53777C34290BBE584245A39A8E2DEECE822E24BD926459B9710ECCE302FCBB9839155AE890E8660F1D1505FFD989C6D9C78339984F491BB04FDBE410B02DF01CB426B992AB719F6B07686525077687D3092A9876869E37C3B97938B5668F307FB2011D36336AD76C2210163C26EF8850247DA30710E9B8419B0CF7BAA88824A658FED3FEC87945D2AD5BA693B6962F9B4CBF096C417A038FF10232E96DAB2870EC7584A7965AB845EB4BAB27B943087826A1FAEC43B13BB9E97609A9E28A80B0FDA4E7C44A3A751095760F1C9C7B1A20305E2DA0C903C6FE12B4EB65835533D56534044352013A174886634C3B02FAECE1BCE571CCE84BCA0836FE4D787711DE5C186D451890046F4011C265E2C463FFB3CBF9235C7A717D680491C2AC4E4C0A070381919E833EBAD2504D22C9DEB00A0F1F07E3A274B6192D28DA577DF1D2C58924D3658E97C9D18C93A69E5A1E3113D61C63C89805505C7EAA01BAF89BCF170396EE54A4959CC8B5A9D294EA8EE2EFDB10EDC9CBD920C92C320CF985E626EC1B5D07EFC03DE66BA11D6DB5E0FA415D0934CA62492E2942E373489518A35A56F36E62AB4F3A7594F1E027A8F5EA56FF2B23D66823090C48804CDE2D8E666A711254DBBA150DD623DB32E86F8E794FCF2B1ABC6351D22CD6CAA26233A4A170A2E872E5921BDB67747802D70EA1794E02490FD875CF01FB161497B79AF6DC6B0FDCE836917F90E4699A094241B38EDBBEE271FD8C4F90E6C8F5FF79A2FF6ED2C134E4BBE161DCD0FFA3C4787640AE8147CA9DA4E7E6CCD1FD5BA8701719E77964F9A66065D4A2C3789CFDB3B2322723D91A51A176CE783C5DAC8DFA0B62069A037356125C5B865DA49BCFCC578AFF194FBBE0F2DFC07413E7DDCC85A35002E9936C9F0B259E51696A1A2EF654116777DD0E284CFF3AA2D04E1AEF6E2FE18FA119EBACAAA0459FC2DE11F6D6A1AD301C7D56D8C8CB1ACD07758B43AEF09036BAB1442C65528B1F52BAFE6D9B8E24114A82AAF432C628A83BFD25571FE0A5B6AE793D6034F1243B029A9E082E0D47D9ACB3B6566F2DB0D8869360847DDF00F238AFCC61D51DAB0915FE704C6368E9190D3BB4E244166151F94F2CE67D618E8E97379CBA6D33F4EA1B1C8277E0AFB06DE5B2D9212DBAB0FD94CCFAFC123E9B7B60827358959C50A9D6494C566A32F84B7670B3E9E0E3A0C8E148FC42A077CCBC0707495F2A4B9D5F6CE53615C64CCE446A6E01E2A5995366486CF2746CF03A53BA42EF6704C084C48F586303D3589379B601C14604CF5AADC330A1CCDE3A835A8CE22C1AF8D5B248169F7785CE4DB9D62EF49CDED793F8C88D927BA6A2195EC5356F2A417A442B708DFE4C32F40EDA5232195B60A1F43407F757CB11A08A2BE085A1923BB29FB4F13404503B7E84AC9A0B81A16E03343520E68F4DC685714C8AC84897736BC1400075DED531ED9E4353851A01AAE3941C572C2DA112113462EDC499B909C77E65B4A7914ACB88E8DEABE3B447C5CA68C0256B54438F1B893BDF0DDB2AD46851EE62873F8B97EAA8FE8EDBF1DE15C4CA8C4D57C1C2E45F3D045C56903CAC81BB083452D23AC838E84F26E62B5176785616EDEBD14DDD4ED349F6AC3F932FC827447148FD05A85B8D24039953414570F51A4D8B2FFB401B2EACD14EEC7C3C556F7D80D68CA89AE772D7ECE3B4CCF14CE8C2389E934CDC192F106FA31FEE17D69DE01571DBDB8507D002892D77FF8D9DE6B0111433E1B9878A37D97D14C46FD74887014D3BDBDB8378D03A6CD1C30120C95495F1E2A00BDDE36827B81B7A6DF0DA2244542F4230B19BAC1F36B8EE9AD92472FC1514F7379EE38E8BEBEE584CD2998BCF8CDA8F0EBC870FCBFCAC7DE7045163CE73932405D639384AAF4D28B4801E1F75924F8319E9AABE7F567E6583569888FB1C0C607DF08E8A0C8C3F30F38B5C177F2334C33F537142E57E89CAF4B1CCF908C0D7F3DB79864C4001BC45C3882BD7B263840517491B7E4159495B0B6E700536389AECBFE2D3F4450D0D2DCE5EE15515D66A6AC1B9018636D76788DA4ABB9BAD20E2B2E318992D900000000000000000000000000000000000000080E151E24263139", + "reason": "too many hints" + } + ] + } + ] +} \ No newline at end of file diff --git a/test/jdk/sun/security/provider/all/Deterministic.java b/test/jdk/sun/security/provider/all/Deterministic.java index 11a5d4d74b2..8fb0e943768 100644 --- a/test/jdk/sun/security/provider/all/Deterministic.java +++ b/test/jdk/sun/security/provider/all/Deterministic.java @@ -205,7 +205,8 @@ static KeyPair generateKeyPair(String alg, int offset) throws Exception { case "EC" -> 256; case "EdDSA", "Ed25519", "XDH", "X25519" -> 255; case "Ed448", "X448" -> 448; - case "ML-KEM", "ML-KEM-768", "ML-KEM-512", "ML-KEM-1024" -> -1; + case "ML-KEM", "ML-KEM-768", "ML-KEM-512", "ML-KEM-1024", + "ML-DSA", "ML-DSA-44", "ML-DSA-65", "ML-DSA-87" -> -1; default -> throw new UnsupportedOperationException(alg); }; g.initialize(size, new SeededSecureRandom(SEED + offset)); diff --git a/test/micro/org/openjdk/bench/java/security/MLDSA.java b/test/micro/org/openjdk/bench/java/security/MLDSA.java new file mode 100644 index 00000000000..2dc33e2b298 --- /dev/null +++ b/test/micro/org/openjdk/bench/java/security/MLDSA.java @@ -0,0 +1,833 @@ +/* + * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package org.openjdk.bench.java.security; + +import org.openjdk.jmh.annotations.*; +import org.openjdk.jmh.annotations.Benchmark; +import org.openjdk.jmh.annotations.BenchmarkMode; +import org.openjdk.jmh.annotations.Fork; +import org.openjdk.jmh.annotations.Level; +import org.openjdk.jmh.annotations.Measurement; +import org.openjdk.jmh.annotations.Mode; +import org.openjdk.jmh.annotations.OutputTimeUnit; +import org.openjdk.jmh.annotations.Param; +import org.openjdk.jmh.annotations.Scope; +import org.openjdk.jmh.annotations.Setup; +import org.openjdk.jmh.annotations.State; +import org.openjdk.jmh.annotations.Warmup; + +import java.lang.invoke.MethodHandle; +import java.lang.invoke.MethodHandles; +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; +import java.lang.InterruptedException; +import java.security.DigestException; +import java.security.NoSuchAlgorithmException; +import java.security.KeyPair; +import java.util.Arrays; +import java.util.HexFormat; +import java.util.concurrent.TimeUnit; + +@BenchmarkMode(Mode.AverageTime) +@OutputTimeUnit(TimeUnit.MICROSECONDS) +@State(Scope.Thread) +@Warmup(iterations = 5, time = 1) +@Measurement(iterations = 5, time = 1) +@Fork(value = 3, jvmArgsAppend = {"--add-opens", "java.base/sun.security.provider=ALL-UNNAMED"}) + +public class MLDSA { + @Param({"ML-DSA-44", "ML-DSA-65", "ML-DSA-87"} ) + private static String algorithm; + + @State(Scope.Thread) + public static class MyState { + + Object mldsa44; + Object mldsa65; + Object mldsa87; + + MethodHandle keygen, siggen, sigver; + + @Setup(Level.Trial) + public void setup() throws Throwable, Exception { + + MethodHandles.Lookup lookup = MethodHandles.lookup(); + Class<?> kClazz = Class.forName("sun.security.provider.ML_DSA"); + Constructor<?> constructor = kClazz.getDeclaredConstructor( + int.class); + constructor.setAccessible(true); + + Method m = kClazz.getDeclaredMethod("generateKeyPairInternal", + byte[].class); + m.setAccessible(true); + keygen = lookup.unreflect(m); + + m = kClazz.getDeclaredMethod("signInternal", + byte[].class, byte[].class, byte[].class); + m.setAccessible(true); + siggen = lookup.unreflect(m); + + m = kClazz.getDeclaredMethod("verifyInternal", + byte[].class, byte[].class, byte[].class); + m.setAccessible(true); + sigver = lookup.unreflect(m); + + mldsa44 = constructor.newInstance(2); + mldsa65 = constructor.newInstance(3); + mldsa87 = constructor.newInstance(5); + } + } + + @Benchmark + public void keygen(MyState myState) throws Throwable { + switch (algorithm) { + case "ML-DSA-44": + for (KeyGenTestCase testCase : KeyGenTestCases44) { + myState.keygen.invoke(myState.mldsa44, testCase.seed); + } + break; + case "ML-DSA-65": + for (KeyGenTestCase testCase : KeyGenTestCases65) { + myState.keygen.invoke(myState.mldsa65, testCase.seed); + } + break; + case "ML-DSA-87": + for (KeyGenTestCase testCase : KeyGenTestCases87) { + myState.keygen.invoke(myState.mldsa87, testCase.seed); + } + break; + } + } + + @Benchmark + public void siggen(MyState myState) throws Throwable { + byte[] rnd = new byte[32]; + switch (algorithm) { + case "ML-DSA-44": + for (SigGenTestCase testCase : SigGenTestCases44) { + myState.siggen.invoke(myState.mldsa44, testCase.msg, + rnd, testCase.sk); + } + break; + case "ML-DSA-65": + for (SigGenTestCase testCase : SigGenTestCases65) { + myState.siggen.invoke(myState.mldsa65, testCase.msg, + rnd, testCase.sk); + } + break; + case "ML-DSA-87": + for (SigGenTestCase testCase : SigGenTestCases87) { + myState.siggen.invoke(myState.mldsa87, testCase.msg, + rnd, testCase.sk); + } + } + } + + @Benchmark + public void sigver(MyState myState) throws Throwable { + switch (algorithm) { + case "ML-DSA-44": + for (SigVerTestCase testCase : SigVerTestCases44) { + myState.sigver.invoke(myState.mldsa44, testCase.pk, + testCase.msg, testCase.sig); + } + break; + case "ML-DSA-65": + for (SigVerTestCase testCase : SigVerTestCases65) { + myState.sigver.invoke(myState.mldsa65, testCase.pk, + testCase.msg, testCase.sig); + } + break; + case "ML-DSA-87": + for (SigVerTestCase testCase : SigVerTestCases87) { + myState.sigver.invoke(myState.mldsa87, testCase.pk, + testCase.msg, testCase.sig); + } + } + } + + static class TestUtils { + static void printHex(String s, byte[] h) { + System.out.println(HexFormat.of().formatHex(h)); + } + static byte[] hexDecode(String s) { + return HexFormat.of().parseHex(s); + } + } + + record KeyGenTestCase( + byte[] seed) { + } + record SigGenTestCase( + byte[] sk, + byte[] msg, + byte[] sig) { + } + record SigVerTestCase( + byte[] pk, + byte[] msg, + byte[] sig) { + } + + static KeyGenTestCase[] KeyGenTestCases44 = new KeyGenTestCase[] { + new KeyGenTestCase( + TestUtils.hexDecode(""" +93EF2E6EF1FB08999D142ABE0295482370D3F43BDB254A78E2B0D5168ECA065F""") + ), + new KeyGenTestCase( + TestUtils.hexDecode(""" +D6A5D2325B94CA1B993A0151E24AB95B396F415831DC14A08404820AE58A2AD1""") + ), + new KeyGenTestCase( + TestUtils.hexDecode(""" +8A5E79B82DC81553BBE821EE367F0ADFA54F59A3E8A71CA626F873F638636DD7""") + ), + new KeyGenTestCase( + TestUtils.hexDecode(""" +6137CAB1DBF57A5CFCD0079BA87FAF2C7141EBB92DABBD45FD8B478D24AB8946""") + ), + new KeyGenTestCase( + TestUtils.hexDecode(""" +B9E2F48349350D30A5342783C915A608C905E0DA4BEBE2067FB62C714207C62B""") + ), + new KeyGenTestCase( + TestUtils.hexDecode(""" +2241FB7005D1B26A1735FFEA5186D08950B4B12CD4FF51BD263C6B8A2A2A18D0""") + ), + new KeyGenTestCase( + TestUtils.hexDecode(""" +32BA0BCE82AC978E5932BD14B1AC1A9319BA20412538191E2C7B1E0BD1D01CBE""") + ), + new KeyGenTestCase( + TestUtils.hexDecode(""" +0BE86B084CD4B31D855EBDED6DE39326516D4BA6770B76B1D4398FB2C9C75196""") + ), + new KeyGenTestCase( + TestUtils.hexDecode(""" +68E203AD881ECE7B354F6A760C87CE3C2F7A62EF1E12C71DC2A965517F0E196D""") + ), + new KeyGenTestCase( + TestUtils.hexDecode(""" +F09E23ABE72DF75EE36DC1C952F56564FA4213A987A0656FF758F3991BF4E1B3""") + ) + }; + + static SigGenTestCase[] SigGenTestCases44 = new SigGenTestCase[] { + new SigGenTestCase( + TestUtils.hexDecode(""" +C1623CC91C677078CAC1FE857F7DC40809F390BA0D51BE7BFBAD9B55306FB2E1C5B3DE04C3E7FE3E3B24A41F45F5FDD3E73A72EAED3B3F57356483D7CC102953873F519C79E445456157FDE4EA5F64D613E5ECB8C6258484AFA36AC4D31AF313FC17A5835184087F04CBCB7AE63D41AB1685FA02D1A64F5D0F844F6FB5213DB1C0444190B48DDC04111AB824DC342C19164CCB242803018284C2416206650A280D2020900A83314CC62DE1824C128489E0844518A22D141628D19290D01805490010E284500CB409E11429D2220118A30D10B561249449C2201213B525CBA020DB148DC3280853B0498B34262045919A424910098C89200553A00C12430060C060E33869C4428CD984648C8009C3C844E1886520478060264601140EC1046ACC4045E444921921921AA15023074A022444903470C33250C9384D824249444042809060842811021660C242251C102EC034060BA74D81224C5C286C50A861009388534062A32671524268D42225D9106C08314C231385994608CCA265E222685C804904080013236994864C23A03014184DC0063114488C5AB0850922080A396DD29045242588890286CC18858886700B474CD02461DC86511B932CA38031033764092446811802503671E44624A41632C9868CC236700CC489038910601670428811414042A0A224D92831E344451A2548A30281C024701348224BA06003C38DE1184C59A64954A46810348D4B34815A00215C24018442685B088E920002DB42508A3071A39881811871E4A069A0180603203022C68C8212824A180561A4311402301494691840619A482919868051308414A30C01350D94362DCC220820368624280E623200531045A2388C1039498004465AA86C892682E2C601CA14652340704A246502882520B56508025124248EA42408018270D036804940211834681C862490241018239023406841384D1028718C4226D1B04099249214219140362C0B216689A268A23280014545A0320C89806492466DDA0802D0326E9BC808D2A249E0006D5A226A93B42020364E413669A1124C10A2901CC66D99B26C92442600004A1AC36C9C4221E2B66C58120409850420884D19A930D3347159128D024271C0140603A790D1806C00296D58B8011A29441A308124A58C82B070D2B60021270E48A809248709192585593462A4460C13160E8B844C4AC07154946D22235003244AD0808D83B644CB066289C250C8486811407242C409138268D0B66980B46D52097202586725A9DD16DFD951EFB6F6FE3231A2C471231B53057FD316DB0876691543D51B66FE1CD1ADF7A9A73C97CB74056DEB19AAAE8DAEC4EE2D512F19B5521DF260609A5F1DD23CA4EEBFECAEBC9CB0DD9D612D0AF491655C6B22A2AB52C6BDF09B8C05784D2BE8832EE184F7D7EEC0C15F06052258A5DD658C74DE50D9F351979A1B0E5D4C94832DEB34A09F08422C53BE60568F81F379B76F5C1F85A0E74434942DC524D85C26A8489C273643CDBE8662EE0D7EBE56C7E4AC93D84016D99C0C180D24B6B3A9234E60A01A83DD64446DE5DBF8AA770BDC66097BAD4261AC8878450653F21EC34CD3E6F1303C44A4D29C9E801D6E87DEF63D4D35F7516A992B788913829191A09E9526F8CBC361D6530EDA7EC9013AAC629177CCB744CAAA8ADAC376F0222B97997F273BF7098FC39A63B899CF35D2E9D397F0D2A49D320B03A9FFF21D98D307DFA94A328E04BEE9D58B77C53303779973495E3EDEE49BAB18E3634E23E363E1F46F087D8CFBBBA8A210661C6E790A6A6449E0CC2738DE05A034BFEDD377C0AB454D4F39FA6F4E91FDFCBE621D0AF8F84197B4762CAF6D5992643A16BE5626E52CC0ED24895F629B02D3CFC92E98BEFDB1DC80475FC9EA7A40EFBEF650355B03B76E7887BDBC2D4EF8FBCDD6D95E260FE6561F17C44E1E01F6712DD0E5F7EB89766AF3FC9370A7C168F64746FB8F744D146CA781C6C708A963EB90858930875223CA379428A71D8008C70264C87E420ECF17DC963D3D7E3C8F280A8716EB636FFB857E8AB92847CEAE7C77FD2970DA98D08E001AC9605BDD6A07885B330F04AF2DDDA3EE6E9314C012E3FB14358D67070014A728B6ED5006622052EB43B77EA3E5DDAA0BB1C1C6A973C8A455786A76A673B5F4BDD339258A7218F4A210F0BFA65B4A07EDBB199EE755B8F60CC001026107163EFCEFA41DF85065D46FBA9471513268517F06B5914F0C625F3C40DCFE428853BB58B10FC19C2685007AE56F42CD6730CB4A6283BA4AC4B40AD9D9B2FEA1C2916111C39BAF1430612E569227E2C6AEB11E0451AF81E308F3BD59CBE29D940E2CA1653F6D6C70CB1D3358392F2A97A34FB9BF05203FF507DA2041AFD85E4643A77CFA441963E282B7B2A5A2B8D293D036CB5143F3E01722E589840DFF12186B7D9799A3D74E99288FBCDB6D2CBAD2E5FD4B449AABE16A12924AEBD33AE5F61856EC66F44C0B09FAF4D0C20CD0C59D760368B335CDA9422C695653E06C0E839EA7FE946237B222F61F9F02B3AC916D030560B8ACD07A41E7D54C402FA7CF6983F09D3E46EE6A7F786FA39DC369E0EC4A30BF734C636DAE26D756AA781E40BD1530A0BDD4040AC17329DD6B90534491CB2AE4D179C2215CEB1F466E7D871D42FB21106834D72BBD656D836F09FDFF875B0029D9F3B50BE25BF05D6A2B0EE322E969247609E16D321CC928C3C7F9CAC3C9F53358D066EE23B52837FFDA6CE77D6235DA4FC06869BFFF3FBA209E8255EB6DE7DC40D0C89969DE0D33B5E54151378BD3021C2A8879BBACEF98AC7F542CEF27F8C639FDD3BF0A0194BCA92E46D6AB5C44C7CD960B1409A088304D807AE67442712E3F72171E06FBA8CE1CE2A6A15562F6BD6968D15339233C5BDD9A5A9796C1DF657F08BD90D1EB5126314B16324A63ED2E8486716B38DFDEC3B14BFE21B2D710BC4DF2ED5A45993DFA197E5B190BC11275E5D9B2BBDAD69E819E4FB4EC859B8C6D32D6F21A7CB35E62ABAC2892E0C6C76D6A416FE3E5CE80361204CDD30C584344C3E61BF91A239B626D8C57750CE0FC4BEAB5743F93083BA01FCF2A9B4CE04BB80AD8B3652C28F4A81D96ABF4716E8EB090817710AB2D052366391F1897C7512F221221B2EEAE39D36C24B919CEA2EA7EFC42CA4FD6FEF946BC241106F12FB82B12D947527723E32BF5029EF8E6C6EEC47C54FFA329D8832F43811EF85FF1B2133FB6240849D7435EA99DFA76EC12ACD6E7AD590889441FBAF7278F019849872D9F4A281764005CC34951CA11C2CD1CE31E51CD2C9EA8E4185274188718D56780DA3F7D234FF14422697B3B4B3936BB1607BB9F048A69A293C7C9DF377E380C9EF8B39990E6D7FFCD4FEAD58C1E5249EA58F9ACE95BEFC1A904B6BDC284577D8FB618278D1F132DE15E55A09FA1A558999298A02B3787C5E53B34EE7D017599CEAEFEF80AAE2953E1CEC97E880349C2AEDF507B3AC853EDD5C0D8081500DAA684A20CE3462E1338917748A2869C9708C5A282FB7D66CA0AADA519FC56874D158D8951BC66EDF57EAF987044C7349CAB7C91BEC1655F22006182084F1A65C356CA2AE8AEACE36D3C5EA966C23F047EA10F1681B679"""), + TestUtils.hexDecode(""" +430B1F46E87DDE9A3D055A7D4D6AB1277B2DA6EDA642896412126391AA2B29AFD81C246EC839929F5C06749491DC4D81D58CC989D8500B6879E8807B1C3AA0B199EB599AEB86B344B77E3DB1AA034C938D80CB4BDCC29B31B710F57C7E491D99B71E97DD6FDA01A0D8A54C7481C2786F64FFC53AD358CF31C9C875ED278CEA03F2BF732372B19252BB9FA4ABF465FA2CFD1C08684D10582B410A8E012DBD407C5140D97CEE768C6D68124B2C84113B58C9A2AA67093B44CC3B6199FF1EFA6506CC28BD30BEC4CEA88411A491DD948DDB09ADFB92C40CA50E709840BC1F107E0CA428C111EC4505C5346E74AE4AB5647C1EB80F9C07092F8D39A975C4890317F9C0EF474110AB941949029BF39ADFB8E65CCAC0360A3EFCEB69D2BD805E4FC8D0620F8E039BC046DFEF1ADB03F5995FF62AD41352D479084EF3E302578B83332506918CFAD6E3BA701C94B0138DF0CF6C2948049274CE61EE0A64E756306273A02D68F3C405883F2F668820356812B2DA3A32B9FF23608DFA559183151221F83DCA18253FCA099FE24728F302C8B7808D7AF978299F3EB853A8BECDA46B8657598BE9ECE8A02DD4B25C593DDCB436B82335EF9C6A7B8426B701C66C9EBBFB3C8405A73881DAB57D1664F3AEC6F5BA19155D89A0A80B5D01C46BC79E1D4338A50B203397CD4B16ACD597A7C77C49917E9FE4B0D761065CB89C758498868B14BE2B6FF758745AFDC535EAA605C3F97648034D2A320264150278A7F1CB114B977C9D6BC1F29295CCCA16B23B7709D5608E4095E41D08B22AEC6289ED402414787062B0DA2387B6DEE76B32E42C51788B65E815E089BCF92D778F49A9707D37FCFBDF8CEF953A48A4201FA0173529BA360BFA6A77200F57FD5245146C2CD7FE8882670EE6878386D06036F0E1BA4B728CFB75806F05BA6409C514731B0BA8DA11015A63A8B5B5AB8C69703185191D12C5611F1407E8FFE3E50FC39C3310EF4091BC09FECC11D3AC107C696EE89F74CD6147830B4B3A971A0027747B62C528F6D858D1F9E67F59496C6B4E9E03FF0A598B26625B06C79863B5F07E265A40175E1A6D6EF3F900F3C4A28AD3E49D4D0B7E4ECEBB79244264474CCBFADA43FCD33F4FEBEB0F7E5928479F869D6A0FE52EB0CAC1232D7F674A057DEC4C2248934A40F5E2C9CBFDD53F71FC3BE06E48E13398ED426D8D3CC82118B7E8E5BDCA248380F4E64C427D1BF2384F60F6A07F01EE62AA1746CB143F26412547E7EF0E8FD1F2DC606F3643DEAF330D81CD6309465F9ED7F34D9B175FE1641D90212D4FFFB91CC300E7DFA0C555F7B35D2AF6A343D1467436EEC7AB95F2C34010FC99D66391377770A7DB8CD4D5C6BBF931092322741929F790E037318D6ADB74B4768C11F0E4674D18185DFB3D051725F93800CD38F58688AAC747F885908804D6CADAEDECB43131D75B18FBA2D4BED8D9BCC2156FB23F8F6378C622153EA8301300D0FCDEF1E2BB4E6F807784EA0171E95C372EC19B05A6C7B8DECE7080A057D29CE5A445A83410EB83B174590647424736A3B6967BCDF8A416A51202CE3F00E4D97DCC2C48A78D12CDA98E94A9BD6CCBE09DAF8085304F6911ECED3547DE9512461E16721322E4E6233BC7CA360A9004DA5AE064514603EFF0DF4E2D8EB04E9574C59F3AC14726C10100C688203F4960197CE696730AD7E558D7B939E3E6E7EAC4E70A7F6AAA80C1F1546E282B5CC7AA193213769B137C7F450AE5410817166F29F2E4E7E962932DF282A9F08A1DEF3E19C251F95611DDA9CFF4E2FED873439B45F8451B9AE06C6B2C698778BC4C742708BDB54CB35B686F0E7FC856CDBF977AFB663DFE44F7FCCE0E0555BE81EB28984BAFBD6FED3F0182F78A1396AF7B7081280864E5E4BFD7C52DA28BB5DE5FFA211678D13D41BF825F4B21BE1CBD29719ABA341E7B0C3F101CEDFE2F709E4DA4B5A6D0C021152AB546837024F4DCC4C45C132A038315A0F1D69AE768F70606D070169AE0818685C4BDB7341BFE15AA0455F535766FBEBB50875246A6DAE86C7B9F6F3A9FE01AB9928A99C13E6628431D41C1506381A63FAAB57BFB3B180F5D7FF59A434233EBC5A659B71CAE6970CC838D5FB638676216E3B16E8BA6C01349A7482AAF32ABD17DF7FAB8C69789F0194022BC4E62B6A6AAA4CDEF13B1E3BF5E1F4FA69F82B1EE3FDCC16DDE1106E3D2C41F6E661E33984DE7AD6021EAAD3E64D8C9CD7B5CB538AF88DB82FA048E5705EFDAC0EF479827EDCA0255BA60771A5EBC716C690CD3AC840FB6FF462063503D68C199050BFBD64533D94E093A47658822A25D54CBBFC689DFCBEB1DDD5BC6190B8F02C6FF3D001AC63729D35C8C50FAD3DCA2E67C5CCC6A8799420B159C7C5CACAB958B423964C489DAB1982A4E2222D700BA5AB772C4A11A44FF64018AF477D054217EAE28FB8E37595941FEE7AF87FD44960A144DB0CE2A44B33DC79B1EE31CAF80DAD620666D0ACEA76841EEE6CE81C6FF1F6D1027502EF89F1595065CDEC19B30E4B5314EFD64031B3B9DDFC6C95A4943247ADF7E4C93350C241ECA71260A454707B84017C5EB7AFFEB5DBB863A1CBDE0062C662308A2E824CDF6397863EF78F62319E2873B506F8A9EE82135B803025D962E609E006961EA3F7B67347518E70D9273893D79530F67CB678D6A8D28A0342BAF904BFC0A69AD575CDA4AB73AF22B52AE5D58372E0C26795CA96A16B8461AC61E6F68433ABCEFCBC16B857A89C475D1A322D34266539A17D485B8FA356EC3E154D37BAFC4CE75829FBE8BC823FAFF15A49F847C286F999A1F2C12B03E8F8A4C34A97588D91971279FFCB100EDB943E636F78ABFBAF88BCA5C55C935F6147E51BF798267E1350D2F5E3F74B339F6EFE86208C5BDE149C5B71056BEE748D06614AFEAF6DDA2A6EFFBB56B0880AF9B201B3C12055D292E3BB556240DD031C29A67BF244F59112BFB6865EEEC1DFE1CDB1E27F0A9E3372638FE4407099D0E54E9A188079C8BB9470BE6F63C83612D80BD60C21B251B64236E5CAF09A11C12F1A5E94F199DBC7C9E394C0B0E07A583E707E5241B8FB33E39BB26C31929F39316F4FDE206493566E17B51CE635420493176D8FD353206EF87F0994F039DF8F008AF602F50D7F9C0051B56227F3A2ED20B29611219FC4376234EB900093A81389ED00991272B739389F1F978A92A3E41F0A28985D697C01240875AC46A82B2FE94004CBD7B1E7594AE38A9DA0E84FE7E122482BB391538EB8E85AF9DC022CB32CC08FDA7A95165725EC29A0F824F97F0251BE636B57E0791A7F50EE190D45749472B29A674239AF95B373A40A6E0E09C674071186B125EF5AF72CB434AC0AA990341F063EBFE30963451491474B603733959A23A6D5B8A378F15A5A5B9CE4BA44BAEF6AA531AF5097ADE73F64AED0A541784119665F548FAEB447DE108AB74A74893017F0A1AF84AEF0730B555767B0CF6AE502E7693374D2E01C54C64E411AA93C96DC5FA010267B387299D4376FBB190E1C51A560871B559FC800D82ABD119A5732B50270BEDBCC8A636E7499149AE0E47F736FDB71EBF1995D1E8BDCB0EE96E732E8C2509F98717C3D174C78A4A2BE43DD89195408CD300505A219305809A1BFE7294BC2EECE6D98C768A8A1E0F74B665EE3D652AE8E008EBBB11F0D2148E4E5C93D7FE0190D27B3EBB7D2194BFBB624AF3A894CEF7AED571954D006824950A981F4ADA72BEAA0D820C5DD9BD519D39BB7915681F266DA66D49BDAB9E55879B953A7332F877DC5F5CC7BB3C9E1C1F2E41EB55EFC02A450B5142514F1E06D43E48FBF5DC80DF241169D5936432BFE9BE99DCB17293CF968A17F3111C884635EF2BEDFC87DBB80BF25EE9BF57B55CFE635FD99554F5FF2B4482D1948BD282FA282C48C0302348982E30A772BF14195CAC7FE39F836E6238EB1E1FD074E63B9AD0A8D37111087E47FE5D04B62DEB496353457BC76C53A2FC9D5AC9AE6A47F632E6D45E08786DA128464FF2266BFF92B5CD89176A19226F2EB14CDEB331C497F1836FB6C0A117ED6BAF95E9DB8254487B0DFA7301397AA29D95FF2065D851BD302B747AB47BA0AF408B51E4BBBF042ED1B2B604EEF4C266FE243261515778BC9451A8DFB025FA3212E868C3A078C7CFF65077DE94E50ED90A259FAFAEB398A94FF15C838EFA7F49904BEAFCCECD8C9ED4E014EA00C7AEF1D437DA306E8B7DFCE536912C169BAF0A3B78A643D6E210E5550E3B2BAF7EDFE01E721E3D05BAC1378EC1DFDEB2E2AC0F0BC368E0A8CC64F375DFEA2FC20CBDC515440FC2ABBBCEA3584E103BD686C5403EFE376D44F5242D35C9F9D35E1A869FFCB6657823EA0D4331ADD5CCFA99BD6EB3494A48ABBA7B7ABC32ACB8FF00512E1B0AD493F579898847E328C06FE05FE282F8D4AF48A1AAD0495AF1AC7354275A6D45AD5A7B3F6787F893EA558BC5D4ADDE1F0D265ABF73C86550D25C00821C3138B385448E3E02901E2E6EBC6A0F211CB6F22F8F865F0DF3893B987DD086B6674F5464ACE18B9F0EAE948667B2FC04FECEA3E2B7EA6B869D5F66D02D4DB124A59621B96E0DEFBF99A91AFA0CFD6D5A5968E62EF42B4C8908C3719BA0254929A9A183D50C566CE4FC970E047474490FFB07F576765AC5286B2E0FDBF1EC56A8AE8E6F560C69614FDF5C89BA53B8B7189E6388F7CDF7B819F78F3E6EA54C40865262BD2C8CE87284FEC36E2E73BDB8AA9CB5283272A90A6BBBFC3F7FED5F124E8BFD770B6254CDC695FBA0D8627315370E2CCDB89BCC84C96E20805AAF087F9E9BD1A189F4C6D66A6DC3FEF773788B3B57EF876CFEAE1F2C876CD239BE3B8A94F21350EDAE6C269698CC66BAF90B3641593F96399C71B2ECBE50F61B5D6F37D47DF702A9B9E47BED2824DEB19ADE7D7D8830A8F610088CF4BD0AD22A5A4FBA767D01987688BE710235A74129666FF7917B506A18E6B5D6166E8B682BE6B1946A4D4420926FF8CDF2488EABE71EFA7F2536B9DBEFBA08BB9E94086F55B1B991E18E6023E6952D4A563F2420A1536A1EDDE119E5779223CB712AB5C0BA4F0C176830FE523DD8603F1B316E128579E65454C2BE62C922C1DFE09DFB47D4497CC552AA9987A8BFE19C44E207397204686C718A0936145FC102B8A7111F74A421226AE016EDE658DE5DF9D3C28A247A87F2BC6FECF66CE7A6699880E0871CDB6F066D2CB3F9F625DC5E80751DBBC85982982E2EFAE3AB8F4F1EDA0D13C3B65FD2178E8AE4A712B521B7539785BB058176AB4396E6EFF2FD9052D4C6AF17DC30F50630233C3F05C62E151EECE13CE124E58A25F0F3AB65033ACAC9EA6E41CB3FA435D367DFEB0B9C9B37414CF32DC85A3C43087A578165C86D100E47DBA1FE7061111AAA961E67ED057C715974D3144912A58B6DB22D51BEDF6A8646D810190D91B61F0776DA00C8B0BAA7A83F4433F357E758F5AE8F278119908497E717A7AD25B09EA7C76B306A9A3AFCD9AE6B4F64016D5E80BD3FBE2F5EE673A7459B03AD9356148EA83461B66716346DBE85678C37C932EBC53B033A3F46DC28219880CFA8BB5E15F8862D345923BBC179FD763A0F943FC56BAB69F26C0C15D668BAD923D7AE6B35C07621768F9D972E2D6F46551D45E3FBBB577D13F01E8C1AFDBDD2F052E931C0529380F290FA1DE8BF5A11F82612943BAA2C0D086EBEC84069B271AC8656883F686C67B1808E27C860ECD1B95FF6CC6E6A5846DA29992CBA450081B8C37DD4911470EFF281FE94F10636A29B790E41EA6A342A5BE79CAF575FE9B0147F2EFE02874BC8A0E136A395B42E77D9F18CA4F61501E6C1805CDCDC10D0292593481F7E0F93281D0456EB51F6ABB7C379C028890F445D9FAC0D96AF68CDF6CC879A406CF2F0991916B33A72A193CF170B45AA079DB1BFD4B4126FA9AD3ED13FC98CE4C6C3C30923C8C53BCE1812B21BB644ED3A0CC0596C60032FFB1462DF5182528553AE865BF87FB7C7F61D1FD8E40D830B8D8F54924EDF934D1EBB88DA90BC59EEF1F6BF9FC2D17D8E9E0E39FFAD22EB84EFF39BAA70447B124E492D760E55D6301DCDFBCF9173FE293AC4D6CAF2E1964B32973067EC76BBECC65113C1FAB85375D92CE1436E1D1B205A88202B304264620B282E62CAAF5CFE1169EDAD9459B15BF0060C5744A17460F9FB164974CC55B3FFA71AAC13437BE58325E5E27E151C71D195F886F5630925D441A54695DF23F64C6BC3B0CA83F0E88D01BA4DC748A29F42AC2997C2A21EC258E430032C09E73E73AC2B21B55E1DFB2DBA281426620A0545D2507D1E96A3778C780FE77F1DA3B615E1B0D14DE8729229472E6619AB3B67CCAF21CFBFFD1F237E780927F147425B2142BF62CAD6B467A10F7B3DB922F095A0012EC179C4F8D5437AA8024F13A2A485E8890940DB69FB719B94B7D2629D277B593B94ECC744AA4CFF3D33D2250236C74DA057496BEFDB961B89BD6F44D581AD7A28524A6AF2253FD27530B7FF16FB5804FCA7E44BA2A3AB85FEDEED837DC130F533E8215B3AC3F584A2EC0E9B6194F97741EC050576E16349AD852DE8AAE2BF83CB1894107299F101AD5A2C05EC590B2CC698663C44FC0DC7F893F42BC5A2DECFF2FAF46CC1C00FA7294A0184A85CDDA2B1F38A89B1B17EC08555D082411A4CAEDED562C9FBBC1F512118EEC3BC931CC91636461151BDA454C4F029E01231BF170EBE17C526F3D8F705DC46560642B1AF36E3B401325A6CF59B88BCD4B3242D676FF4066E4252ADCA37786CBDB340DD81C5DD0540992F0B142C5A18D3BD1070719AF996E3C3768C3B234D303E6E9850B35C7AE52496C76106D7CAE4CF8ED01767B6DB5603F339FBAA019B08FA35E3DE1129A6A4D578264CF1FC8A1DBF218DD72B4865214DAA795A00505D4AE2B85E90F589065D65FC60CDD828007D4D3A4C084C7EC159C5D86817860CA03545FF74F17AD8570B2ADA55ECA12BFAB5C10067A086A34A57AAD8694C953137BBE901F8D3DEC27DB5DAD2AC96D56C312E25FE48BDC889373ED252B4F88D32DED6702B58D35A1FB40ABE2F2ABDE21CAA5FD0F67E7407A8"""), + TestUtils.hexDecode(""" +8C94308B9CAEA02AAFC29AB18EC01929A029D49F06F3BB4EA3110B1A9A415C77DF646A68302FFB4D853F8B9AFDD4D46B30ADA30213D763551A2FB98F690296DA77F08B3A1C2363EABE33DB1A891C331932EA22902277F44D68A0001D339C1108C3815A68DD0F7396119FB1DC888E10E3A95182E5A185E9CFB0F76CE84ABC199F7D58C7DE375F74EBC6B3338E3F6C51070336A1D513B3BF6FF4250313A52282D32DC616EA4B2B83A1861024AF9ABA17FE0159544800AEE0534511D9359415A66A6D79C2B3173B6281BFC3C96F07F944CEA0841DDEC3BA1ED9B337ECCBA219C675A13A1466463C128FF79E5C8F1BCE22220E1EBD1A071AEAA32E5506B553176309E1EF15AE7C15BD361EF6676046996132716B5391E9C0350C248A70A3552540963858FDDD3456FDA6707B99C120AFD925A47E4DA492DE65DD041E58A881A8E4125C3CAB474ED7D172F05FFAD0655FB7729AAC1C951AB05892198D713657936808A2E9795488F3F6E3183D0AB6B69B3484AC7B9F3C2AD65AAB9901992FAE9DC1E585D9CF7C71B4C7CEBB47EA07D534F9C869B114E3B0BF29ACC2CA60B91055E98643E7F16D3B4FB0477E3AF62C9BC5535565BAE2B8B276B33DFC50C3A14A62891435DB43DA2861154C654A4429ED865A373C28FF41F0C0ED11A1AB963838FF975EC9754C5FCAE3BAACB9ECDD920E365964DC321147A39653FE4B2F2D1EFBAF8D82B2198376C814FBCAEE96411B9E2D958D64AA731BBC1D6174D6EC139FDC73C9F3AB2886A92E0E82C700DD5A83F5EF0912ABE4CD30E0E3E9C8639C4B329B639DE189D8AAED2250F3BA74C381D6A4D333EDBEC2D1511B20A8144B42F0B5F674F4004F39CE1091BD431ABA3719D994893F4CF798F3CDFAEA9ED0AD5A3BF7DF0BF7E9E716CF2D3C72B17870780C724A0A0A2EED8E5CB4E8D15597DA311A4923BC8F6FDB64B9CCEF2C95BC026994ABA7C743F2FE83D5E771ACC2B6F8AEFCF6E1C7360767B9BF995778F95390C303C88FB81447EE993DDA266F031B9E4907811E3868F883AE4175D95C0B4C61092FDAFD2A41514408811828B3FF30150239C28C1E3E65631B178FA56D019BA08822C038F718BAA7A12FEF65C08A84E2E9D6E292774859574686AB024E2DAA6DEF1BED248EEAA02E0D28C73ECF803A250123636E6B8C642A10C3B8B3DA55706E17ED5EA96B80AA9D99E450513E16ACFE6A587896BF17254B4F420EED062775BD74CBC09ED7F925D10D34FBFB9EEBBEF6DC29ED87BDF01DD57EE8909BC0889BDA2AE430D8CF80E211EEA8C41DFCCE7DCD197352F60CAB92363FE4681DAA0C8F62ADD5FB1874151E1EBD8BC025A8341C46D335DED5293F012E7E9C2A8CA2234E1E5970E6C51C6711ED16494472205878ACCEEFC98850E3AEB99F10B6A07CC3A31CA742F1F93B4104496EEE8DBF0480AB395310ED09D8C7A117AD8A9F5C4A3050807A600613723555189F22ECB98F01ED8E69D113A03923B9C0C8889F094B30BC16792565F3CCF427EE9F0BF24AD436DB5C40E6FB66BC416009DF2F4D422A9C719585D47B95BF274063B64540B672A373073FF87291A62C7B9838446321B71356E7BB5EB096E9EB13B51A50EE891A2412E2117A5275DB0265889D74D9AB9FEE8AD1B039A0EF471F1410AAC97323E30DA2F91FF22D33DC9C8379211A404E32EB01786EA0CBD618821F710F093DD276F52A10416648E52879ED2A7FF6821EC49768D687984397D532C20B7050ADCB4330037D1EA1108B3A98ADFBB5457B05C8027E1E9433BCD89ACA8A84B802634C0759BA1AC6C144097E0EEB0A8E1A3A64E3E66A09D443E49ED53FA8FA8A295AEECB459D4CC32109EB999A4BC3CDD4D744EE7D9A73F07D763B8F80F4BFC63002CA3EAB87319EB69DF4A25FF1A7CDB72A74CDCD2E49B5A9D780ADDF902B9FC31F90AE788AFC954074E010B495885153DA0CDD15B26C6436D077A040165B6454A24B2E2162F9FF31B9C4B9199934A7A1FC78C68704B9BB784B0FA15A84AEA9E70D51000D7F335E450A026AA935533DF695F471739D9924D452B3C3D84DC597442A92E9A5C950C72B80138BD6154214720D8F19EA7E99328770A48069506F22869FC67129656E26E8E85242FB6E93B466B5277E8FB8B235A221A86A1191801B6B2EF236DCF910CE2FA399F8CEF28F148E977B762C8A828D57ED48C95711A479090255308196CD168B3C6C49777FF0E4D2319B1C44954E9A20C07E23F79CF1096DAF01ECEF4D47BA517554FCC1C6D139CD2F9F5754B61963DED55FA7638FE20041D4E689E6256A305AE0BF096EE9ADB9A76EBA46F5183575E8CF70CC6F69E5AD1DE54159E5339D818EDD92A2B9345AD759DB829C6BAB42398922788DAE97AF3F12A4354014F147A27E267495208978D736C632A5F0270C561353B27BE23CEAB57AD68D02F9AA94F301D3FCEF3E6E234BACE92F5D8BB1F975400D0D6B22F1347DB350CDBC71DB4519BBA4FB5C243A91BD0DA06C1155514E45184581815C7229AB66C921F2BC95655CED4A32D128FBB6B8BAFF83708CB49F69502D90BCEB6BD55DBDE19732098D1D1C1A26C74FE56DB0470C5E76BC6F4927A34D6BD84E57233E37127146295E5F19AABB77F9A6F90D702A58CB0EC0648AA54753AFE9140A9A60EF9814E43A916F07043819F09BA02A7A84525C34D3492C67ACA7C5489B72084CA7D1D5CF2A061394FAC77DCA111DAEBB9CF6C1B270A027F8D2EE04E0BB68D6BFA136640D04366864213F9EB3406A747B81EAD497416880A0CFF50F95784C044E58BC0839E6D36FCA9A45374A4059C812EC2B47AF8FC3A99540A62EF1C4B6D75FED8AFE7DCAF37832A02B3BC0339CF41A6F42733A584DA80A8CB328A5E6E59848DC23A0C0332F529853B138ABD0D3F2A8D2FEBC1D71E249E1FFED726E4664FC3020566BB769D4F3CBC8A735FC7309AFF545C3F87560BBE3D5016FC99CCBA9F5410030A86858F320DA5058DB5A188E68164E2349EE036B6904E5229920A7580206D3B75E89A8EED7ABF650D69494A13E83F37F841A4FB2A7F1BA538D40F84F25DBC0EC78DEC1B5F29F1A27198291365257819922F1A42104C721ABC95B2D610B0DB4576401E70B1760184DBC285EDDDD0788DEB108E824A21B8E98F0CD8A60557D183D16162F32C3D7C7353C3DC402A8B96EE8C5408A4D525517F76EF11238DA98E8069402FAA2A9A64350C4AE80F033A52209E66FC36F1802552292F706BB6B703C8E1FD66DF7DE25B4167EBF2E6F8189D8AE114460A1B0C0398CEE7BCE10D022833BEEFCA70D5BD174446CEA2C23DA0426303D45535C5F7E81838F93979DA4BFE71729373C426366787E899CA1ADB1C8D1E5EBED05315F646A798795ADBDDDE5EAFC1A4D6F7884929ADFE4E8EC0000000000000000000000000000000000001225333E""") + ), + + new SigGenTestCase( + TestUtils.hexDecode(""" +D9C4374117AAD1691D8CF8789E3E9544C379C5021B04E4BAEDF25FB2BF7225CC5530437B7D76D449CF4749DDDD18BED539BE7661D0803A4D7F379DFA3FB293A0B1A5F48C7818986FB379E41A921DF4726396F2DF788606A8C8C5B4E973968545A66B1467245A5A9140C7ADD5083090B658C7654630272C9A25C1CDAB4DB6521DD49641491664C1A06192B68420970153A825DB263249429018088C13289121236A0C022912276604194109360D52948812C93004209092142E22B52C24900DA086248C940D01A62D1B948D84A8300B868541902C00316D8A306203C47003B4440BA6201382515CA42489884403204A00338403B72498142A5888681C12611B116A18C16D5C8248A316815C1630898464C4320403A731892289602424A1464A490868E2B64101146E8B884012270A4A242C020522C320411028124A868C04358902B6259A244A8C008D0820882202320A3442E2308E9094900CA730C44046911261191708D0126A81308DA2204CA2165221134498063264046E23B461A1162A1383710323421C042A1C840D840886921070C0160E03198AD4A2811A484C53200919079080C49009400198A885583682931882A4184C530805D8C648E12272C3C80944348ECBC650523610D3A481D2244121412C8C028D52B4210A244C44B8641109099C440AC2380E9036082016645C30314220725C48440B3306A2C24CC0B689CB26801CC388D3306E1C9261223108E282680A1852639224E3322A093260C8C2842085485B240603830511850903246E61880509A851011500120592DAC8419B826D4832660C2121C3166882084221359059389020C20801824951808D101406010431938201CAA8858C44504B4680A3265022470ED028500CA60520928113232A409449103865DA808DE1208E40B401C844261B808501294651922403490452124090B48914294E21858500A565DC2012193584C02668544608DA82451346055BA808894090A346708C4410DC349049A86D110742242288DA388094364181188C4C086C09150E0BC4290C070083422841342D122508C40865C8B004121631C43430A044900C4822D8086EC918815420214C8821A49088CA320E209361C8B8605C04529228900045501C0829CB0646C0180A03232542004C11276E0B448D02A7110489005CA021881071D9A201D0028CA3B08C01252064102652946401116E8A002E0C05465A186D1418405C464C1A0732CCB820D28420C224710000628A1088DDBE8BE20BD3D9163E7CD8E081F70C5EA00959FDAC57B0D8DC10873C27E22EE17981C4E689700036D682BDBA68454F9B7C394C50CAC4DE6A8CC734850F95764B228134B9AF1E0BCE16A593EB6CFBE451620DBBBE3666E3B248FEB4E5306609AEAFC331E92965C0479F86FA1AD47F1C4A793B2904949ADC0B4FE939DBBCF05066CD0E230A8E485C26F41533BD744AC8E442CD1358991B0C11A90CA17697CA7130FBF44DDF626B7F4D2FEB954FDC64B1D3EC0B72AE26B90B5100C649BCC89172FCCE6558F28EC5B764DB91EBE971C7E881D879956210BE220D6607BD9EAE2C72C4B413D8DCEB01F386C0EB8A1F8EBCB4053B6BCC383303DA64635B9CE7892662F8680905429617EAE18C58DE9380FB69F558FA1B706733A1B7B324B92FCDAB07438F020F0449A70B8F602B5A9702C771B2B3A4A906B2D27CBD824AC5A207A2FFFF1FF1FAC38EB85DC30F3F17C799A1B8E71D7A69D1D5046C73AFC04DA3D1F6487D1CD41C4075E7A6BAA11048273A416B86578047057C6027F89E695C66A6880AC8053D5FC6360353F336F282281C32484840B3D7779A2B59DF42467C42100D382530A74613E147EF863FAC5CEE1522871427739EDD9E089C1327E10F39ABA9F27E66E074200DDCBD31C7CAEE7D4967D8DAF612AA0B5123A1FFD4F8EB379CB8097C3A49E7F45ED5872AC1A579F41D1A8B9AB4F1D0946A9AD6C2FF429385DBFAAF002E96D85DCC93978115CF1BBD5F69A54B3AEC88FA74EBB175ED930A5E47EF09138C0986811946388D4452AF4A07A1E8983333340F9FAF033A87C56855C8975471DEA335CE0E0A57D36E43E1FF5DAF699A5258DD22FBEA92C7F7D7DA258D250717A6EDC2082DDA972A36CFA6552F4397F502BA040145207F874D4E5B07222581646132A5CF5D5DE59F347056F5A52BD89C75B7EB3D48E2326C02AFA1822716A4B4D109F0DA405380BCAE4C7C673ABEB898DD21936195D3F3ADB1B3F042016ABFAB2670A977D1729A605F201DB816606DB7D73B1906C9C4A49C1687460E2093B51ED68F7C548F84C01372CB97FA557B2D7514355E4D0F77D22C0F245B6DEE89982F7C2DF3EE89AECAD428C9C6CE962BCF6DC898EA7AF0A0065EB4477771E97DD30DECF8F41B1B0BCB5DD84C20F502D894710F97B8E93A6ED694AC69A43B6E20F7FA885997D23DB912F1C5336EE2050A96EF1F4CBE9BB50F977C9035FDA05E063928069394C18393E988F715E64F02CE6C3A70AFD2403E3606721EBCA72E9D4A63E3E11707604587301CFC4D461EE07D337A9A1C74870B67457C22D9E4EFB60A5F6D405A184F972BA07CA8D702160BB598104B35F0C0DBC4105E3714A32A789C3C19E3CE8D19AB71FF69514F2CD7C488D6F999625405E9702C38EB3C5B50F53766BF51BA14015FFA2EDAF83B13CAA06060A30C9D3D44BDA226905C357384D027E05B3C0837C246629A070AECBE608E743E330ED18BA3F8DEB7F09F61808C527C5695C4F3FB8DD5F376EF656EC4AADBB21234E85C39CBB37910ED7A9E12D04AF813D3D87A7FCA55CE6F86A53C6432F9C99DD23AC297B217DE1079EE21F467EF700965A326C82CDC548084EBC5F9D0C3B48F75771ACC1C3C45A70388A0C65764829274062989F7A209B71D4051F26897C8FEB6AC847763463A0858B0B2F9CEC93454C35ECD5CCB9AB987B1957849E1EB610D2636FA7BBD08193A69227A34FF2BBAE787DE0F9EC719A3DD04018D3F4DAA2047C569C6B5BA52785FB44F24DC548BEFF25B3E51C24880469BB9D0749121C039BD7FB831D098B8DDF213023476DABCBBC778393F02B4077B57D392AFFA2215587D934025D148F435C1B49998C937BA3D0E7463C526D08DA8C67A2C305934E82B648D4A8CC3EC162E56A42575E944CB711C3AB0474EBECD829CA8E678C10782A284485F3D96A1DB852FEB36BC1748EAD20A342436FE63124C161183DB1BF5CDDC1436999764010C2F57E55BAE6788A7D653ABD03989A6F515DB7A76A77CF3E282E83FEBAA8326B9ADFA176685FFA1C6F9ECFEEF97953685EF2DBE311BA25E2D76F3950E005E4117585709447FEF5F1ED198B98DBA256B4BD2A430D7CDE4052A36D87905A8124AD317ED4DF338CBD1CF26BD02680944226BFAB3DE9149CF19C2519F639F9068825C0BEC1A7572C70B948BBCC290B95B0BF5106A8B2CA8FBF9CE34599E633EBA37254C250438218AB1D2A3EAA0C148AF2CBA48DCEDB11FA3B5D873BD161D24C65CF7DA109D1B8CA296071FF706E5666D66ED10E5B1FD78D2F993F76DA41EE8A9299D33C2ADC8303EC322449EEDA11FF245D03048E5701C7763D545EBCF540CC2CB0E3A06265F380C622FECEE4E"""), + TestUtils.hexDecode(""" +8F69A33C4CB9627BF27401D4A1BC131D28AD0E2E5A317CE983BA2CC7465861A414FB72745E4DA31C0E04576DFE0D0EE834A1EE323D5A0901DD0189EFD6718049E2FFE1AFA548BE16E04B8963325AEB0CA90238C7A243A3F6AA17BC1D63836898688AC8E919B8EB6D689075E050B4189A1FEC723E0AE8D4AAE9FB6790B527A7552CDA174BF40BF91C4142B076ED8CF112A871450AD994737FD5BCF513D42DB01906636D42C6C10B64F74BD37D68A966DE0F3BBE6541AEB9991DDD0C0070F16715C01820546A014E66D786B8922E905DE2BC65053C42703227B7D8431427E3EBB0DD010DC58C2343147700D673D5707160F234E35BA24516CEDEAC77AE15C667AEFA8E029FF14F169FC0A781593E11D42E8659DA8E91E53EE0A1FF15A3C203BBF9591584A99FF8BACDC37541E126B8CDF3503AB2D1BFC0C37F38A298AB1DDA150288A8110C052469382A9A4F5565778339AB327DD80644A26B218ACE0830E56813CAA658A9F17826CD12B815612BE40906ABC89185EDDFA8E05102842CF27BF040FC7B396E7E2E023CB86AB7AE25F36DA6B6C0842126658E0315D6D8F4B5DF38CA663B55998ABFC72FE9B7EB7CE3BEB72AF73A0B2A45577C5215C42E465EECF4A4E69B6DDC1E65E0C1EBCA"""), + TestUtils.hexDecode(""" +3639297077C2F61950A09D4AE55408D1822CBA6133C788347C1881F8E02400B683B012EF2D9EEBDB65029BCC9EECAD9881BDD4FFBCE8FB50242D9081E2C8C791577C800986BD7A03A3817A06E4D6609E288B3849AEFA840EB7B69C589AACF26B6332DF4210F3AB0E8DF14F918848B907FE9B09CFB91F32871B0ACDE0ECAB8915A0621CEDB4A591B1A6EC4B4B9F83F432A9B576D9E5D40AA57D24D408135E72C77281515A3783C8F3397C9E7D26B4543A528BFC1FE91965142D52FFFD2A26470EB821435914D346EC8765539D39083D743320FEDDBE31E08EA0E4ECCF74B231934B5757D460E5B79D16758F4A56E59C166C7F9F1BF6C1DEAF5478E97C8F55000475D523456724390D94AE9F5C4B3F96E86F1932412D740D04D1851560476D50D7B97B080BBDBDB7A347197F2ECE6603B0296C8833B5DDB95BDE239245F1BF27A7584F5B9243D906E4880CDAE82E5A7F1A71A7DF8AF9FC41C0FB4B63CD356CF5F36F94D20592BA58D1FCA9D354B358AE5423D7D5FCCEB05B831024EDC7DB64D6C9E45454790F8B4239BEA02983C5827E4D08E8DF3F795D46CBDE5D4955A6AF2A6E0D101CDF43F43D7F5DCB829A5A79881EC903C1B8522CCA5D8D4722FE29B36BA0C571DADDBAAABFD48DAC4D2603D768A92D8ECFAD5264A9081A74A2F7FD635220EC8A95695F2264075DCC05F69084EB8336588CDBD58CA028E02A2756C8A3081E720F281172F43194D8ACAD2F61F2DD4F01C235694FC20921EDCAFB9AFAC8FFB1A234FF35E68AD90086CDEF922C47C84ABB31112C6AD6CFFE0DA11C1999483609EA98573217C28B512ABDBA6F7A7E69FB8944D0B0C4B9CE7AAB52BB558A5411671385FE36903D148D11DE00A9007929094C54ADE5E9BA60AEE35D5014C7293FAD0158D69FA08E2CCFFBE2AD99C66A2FD2382E6D1C355481248F53A5130EB4743DF24EC048196CE056A7EB032FBF6FD07D12C153D06BFAC06C1AB23147F8139DDE1C00F9A9C6347456C148245E3C94F2C012284190CC3EB04ED006AAC3DD2F08D6D0AD54EF507D7E80671F12A3E4DE2136B6ECF02EDD28E75B985F73841F600EEB64F8E5CC101756AD7794DC14D187237BC82CF6531583DE7B0F60275E63976296A0A02E67298C20FC64A1A8B1CCECAD1DFEAD996A47E9B6DA0079AEB435FA40A53A4C0D565AF713DCDC8D4F16CAB00263058A9CA1F276A39172FABE34FD75422E64F23B2715B395C73F2335B6E4EE7E5BA8E2DE18EFA39FF1B0CD8C0C6F5618C971213E94BF2B9B18E05BDFDFD9DFD88CE24B392BE1ECAB51B95C0BBD9513F881DA789C57B1EEC8C53EE9CD4FAD5E7526B1F1462AD88F180243774B91A9CB219D4CF9730E682E2C6C8EB160131D3AED3D3B3E64EF6A1AD7ADE7048A0CCCB67852971330A62223A89733E06615508029823D397EFE221B35896C18E9BB08140C464F8466190CFD8B0F09E6EF46BC14753974AFA2CE926EB6B02F4EB25CFAE70C77A865CCAE8FF2415C0D81A82F3807A4BF61F6EFA9BA4A16D14E3169C2ED86B50059880D07897A67C882E9B10450DE3978ECD78EE2A3C2B2BD51544FE65ABB7909FE439355530D44244052F2154279B6395E77FF1B288103357C5F83177794D517B0D8A368C9B008838AA4139F1BD10E3ECAD45748804F45122F3384A1A2D541BB8B9FE3C478EC0AFD81EF69FB2A42CC9059CBBEF42633139C342627A604AD07D09AB962E7C1CD2E1F1FBAA633E00AC1EECD29B5324DDA5F273154E7E9D0AD3F78C6AA08E92C77BBA7CF202B94377872146C60E9384830DA573CD7E3BE362267CB74BCDE63FA708E15F5933E27117037F6C35F91D03DA285222FD3F29C440DE820C89F6F37C250F82F0B20E69D728A680095B59AF058A06E46CA75B6BB1E2B0E14D2C9C4705A080B9B826E2F1F96CAC70A902894B416C68171B7388F4FD6BFC4BCF7A6745F3AC83B8A31F869C64F67C5600F35202D3F45E697F46DB1991AEA695443C79810796CF0C0150A83E24B2DA00DC72364CD34C2BF6A9F1EC4C39BE42F8A7E9DCC3BB6D0BB6198FC08C9743335262D996C489C460DA87FF75D4B75367C17A466AE08D24D736EA63A6B0087041426C03BC94BA143264086C94B4C8A3F6B7914CE40EB7FEB876CF16A2F12C66AE3EC3B57A93866F63E56666AC7B59D3C78536D77F73E9E9BEF9899EF390E8BDA6E2AD5CAC671153C348C804F65408309A08B2E78FE79F014ACD99766B383E5869F3A3562B4A312CEFB3D8F5B90FE769365E1640520C817B6A3A26734F406D104CB7AC9B6DCE371AE3D7D10E265EA370C0C78D0685F9BE4B3E9E097A334F53E47C016215719A5A25EAFCA799BD13F5B23C63CF372972F5588B8A125AAC58A0ADF961A6D0A2646F9520DF6699B67293ACE799C784CFF813CD508317ECF90726D638A13AFE574BAF3D2E9F39103DC199510AE4B28FED016993FB16CBA627C820F4B76227044F39AF0B8222E1D387C7005080E5CC216E22AFB8F591074938A3510AEF62D18D8CBC9978A8284DDEC00F7BD3C75F724540174416CFEF71D5BE602FEAAC4EDABCB72F7252471F4A3D01A5D1BD82F98A7BAF66CD6193E17499741810B68B1B066C827FF18763CC557946FE1B60C706606F7CE607047F18D93593A7859BD669642FA74EF569C31F811AFEA327962E02FED620011AC0B96C6CA3AD9120EF1C3DB3C9EC43E7C4E1A255C822EBDBD71080C103EAFF847973B30AD88C40CDEA8E19750BAD8E298D8B0569CF6D3F99DCA585B418355ED039B585F9F829DFD4460A748083ED38C6DD9A93C34447AF47B339C5621D908838469326D318C41ECF288B16C62040EC628DEA4C29DE18F6BD3793BE057B52BD0AE44EC5AB575383FCF35EA91E74ED011792C415934B16CE8D4E9C2416C1C79C1C8B09DC94E005DE0D9B8BFDD07552140D3EAC45EBBBE9E164BFA885940702281DC14142E236AB3307EED9A2F4A88AF5FB61D771ACC92B2306B08F5D8F740C3F10BFD5368A744BB6590AC29295085EC4DA93C508AE62AB59E2390C1EB5B2D5976C55DB166B9D1FCA8A91FCD234EA2B5895DC5228CA981C630195FB832938ED7BD73353EA9771ADD724BAB7AAB17CA622F4B9FFFD6878E7759DC98C0F5F57A5F59132AC552FF4575104CDAF00FC6B73F460AB4F3E06861EFDF5DB48345F35A00F5DFDEE36A49C2150547036544F0DBCA21FC5B41D36D4823B2917432366F97BC0B0AE524715293C6FFF6DC57FCC9A7806C7ACEA749193CA1FD24266CCF42402C565F488CDD0794CA7BE9A78E9DCF4A2BC2C83024C0C58876B2921A1A5203152E4F73757A9AA4E4E9EEF103273C44454D5069737892B4C8D1111E313637445D7C8292A1B4B7D8EC060B3B444D646B6D85888A969BA0DAE1F20000000000000000000000000000000000000000000D1B2A3B""") + ), + + new SigGenTestCase( + TestUtils.hexDecode(""" +B7682E0C424BE42ED48F21AB5AB57FD47BED455A6853B3C166D2AECE055EAAD23EA1D186FD4F24BF1F8D910CFABA719AAF8714606159023E27B81BFDE79B4C21F2E28722215C01B06BE6835163253464EFAA9CDD2150EC59085A32C2BD5D840DE568E12A825CAB4E5CC6CA768D632BD6780CB532522953FA3D774AEE03E2D76748206C49384D81406A9B82201334601346214CB0419C228089C88C5C16690A10022006715A308510102210B44C0A042A8802425B202064042D1BB2850B3292C93461634488D900111C092ED42884CC484D5440440A318AC0B08D1B024D04164DD9B44CE1B01124A72004A671E3106514A74581062C193786E04291600242CAC40C93124E981010A3226262982990806099C88418398019018A2140828C066D13B929C384659B82451405910B114058484A00210663942911358AC1420DC8A484D8344404908921C408123160809000494010CBC4911C041223384E14364D633806032720A006524924850A410693A804E4968CA284510492609482242214640AB20D89A44821294A8C246D511666048949D02685D38688A2100E0CB028DC3889C3C88913B540401012E3C48992081241A608E43425E31645603022E312691A824011412684286DD1A6811239825028692200249908401B124908056D0AC58111352A04A1909224095B34281A2408DC984DD300300222724C145182C8241AB040D1B849CBC26DDB9411D8020E0B2708A4266490A624C28085140726C342819842068A0092D91600CC224A21B20C53067100A37121C14C98B42021818C99004242086E8C964C03086D23017100004CD0B61049385191A6040941261B2891C396704C0646E03421A398010C3784C31248D1C44DA22029E0366E54846D230862608404C3A88CC34021C9A8605C94518B16309BA0499310891B87856394854A24918C228CE4388802434424346910A948C80288E0A68D613081E00269E0440A2187919A082809A165DBB24852080E2180711B16250A338802368004138CC018415A020591B8699B3250989611D406525B820D50B46DDC884809102EA0284D0300242031640C382042180D91925103C5291145109C98315CC80D60108C10220511B12CDC366492383183444DD1802521055153185141328499444C2390505494201B830DC3168A48A29064880019A18CD42208520644992245E2360AE404851C4648C2B8814C2822CB38218124084188884802409CA624C184699B360E58B64181046501E3E9D13414F71537E2AB58DE666A17ECB001FF8EAAB0141BEBDA328E8C7EC44F552DC00A1261A83DAB59F8CC4392EF5F14BD88386694EF93223BBA9EC78A67D5FC9A01AAFB16F4E1C80BA31229514DC1637CD43ECBDF85BDE63F6A2A17E6A1BEBEFA27EAFF596624B30DDF797120E52ED396371C1B143C27EA83BE66C9C2BAB70EB1FFA60CB818B9D159C0C7B02734A91200C2282403D316F6136B0BD3E6FFD328DAD5F257B316BB76D6B3317FC3D7808CA0A8C3A7BDE19A2988B994CC13C13D1E3C9790BA3239FF91081CA6F21AC9684D4189BCD387B0E70EFBCF09B8924C5D9385E1006CA7E153B7CE207B920671065FF7A9AFAEA91DC64484A857563C9E90D74237DC453A554D7ED88CAD9EA30F0A49E0B835560B4D7741FD1B96EB6EDC6BB7201DAF2499623683B672956FDD51E14EA62504421AEDAA2C3527BF7AE8DB52D35D673F5E45918C833FAC8482DB27001C766DA36B3E8B0B24616E749E38807F3E646761E4C998E04D53FC98B7D636871D5719EEAA6BE67D20565D7C120E210A67C12B03571B9BB450A710CF6986D961BAA5A9F92FB33E61D605CF0E4FF4C689D535DF5FEECC5D5BABBC22975256B9834143A5DCB903308B18D7503A2EA8CB8B8ECAFA6BE70BE6779B9FCBF3984830B72C513CB150C5529ABE6EEF29E24291756BE46DE9796714A940BCF0AD21721247EA5449946D987DF5E70326B15CBE2C439388E64480CE84EB9063A4213B58C7223FC06A5B618C3BFCA18A4E46205DD963CA8E2C86712D75A4582668E955D821AC4A7C136D7F31C7CA4E7B8AF187B2C6F4366CD11996BE298D71B9E6C3D6C9DC47826F58935CC8EC353C27B3827C3065165B3645032D3013036690D9232FBEA4FDF57D035D99FA9CDD8697BEBE97D2B9DA476BCFA7BF167A1FC66BB1C5F2348E86F3F61432600D231A593AF2FA3CEEDF7F4417CC0E75023054E21841DD19D53D3547D3481D76401E66FE238D68A5381F98E0F6C455B852CF09A1B17343336FE25DF426A0FD29CDC00F207402C7F96668881EECBE43A4C1DA9B86AC50FC6B3E2C74D244848FABF414BD7B3BAECDC750BF2E58033010B8944991D6CBE7E5468C168FEA69B167B566078673BB06A035BFDE64F66C50616E9B3419394E71F8AAAA636634F51F588D3E012A40E1C9A787044596C51A82D77EBAE4FEB448C919601A183E6A847E605CE142B5D56A0417F20356E7E1A35FE18E94188155E3867BBDC7CD04069D1DC4B3EB8C9AA64F7F955C7251667441E77D7C818A8F49496F1141E829C51074D3D38AF41FAF4C77A56D05296B034913A253536702A21B77DCD3137BA26C413461CDCD413296C9291F1CA056EC0DF02FB888654DC54192EA30631F8F9C8B4921A1DC2AFF4CA8C350DAB4234D9151078DB0EB340CC3754E48012E8C21C84B410FBAB3134DBEC37805E723E5C08F1AB371624AEC29A1885AAA7915497220DA11EADDFC7D9FCFD51D0765515C16273F978BE26CD6D7F8627587F82F3BF4EC25C4263DE24B3D4A0839F7AFF0C4D16A3DA89D1F23678FBC23F475B18B523F115CEC9D59928ACDC7772FB39B0F44A77E15C7D786317CFF38DFA9222FD53470AA15061EC8A9D6CFEFA5C32A60B29FD1265B10C78625B2634158C3131727688D7837AC25BCD90FA8EB272B7B3B232E8259FDE162813ABE082BB0BA76B62DECB230310DE5AD36BF3F1AF145660FBAC027D58D86B03E2E1B5ACCF81B6252B90E1B9E85FF41FCAF60E308E5FD114B63CC26262B4A5031E654B673B23464318FB55785C5B707D901E2BE7A3C7E2CC4BE5EAD3CCEA165A577680183A1E05A2FBAC4EABA9022F9A43A53CFC61E3236652842ACE2C8B4249523BF57D6404EA8B247B0058FF1AE98CDD79164B6445A80F31C427EE1BA04256F0833E752DEE5B5224317919242A7E8CFD0791637D3D3873768FACBA6DA65BD8B4177E6F634CBAD83A94F2CC6500A0A5829C9BDB3849FBCFD517A80CE0D8411948791D0E5927BD13EEC09C4FA2B2453D9CE1BA10769B067D8D92547E8BA2F6103D066792655BE8C05AF1628099D2617BF2BBC2324DC6E3E36C9F32597A13FC45C1E974B00FC53009716EAC9FF0FAC4C6B87DC59B4908631A6A21FD5E156D476E438872D93FE112AABAF99A6952959FD9FFD7C3C25E11AA011333FAED86DA99A6BCEF75E4F341BBDC0E181B5A2A22E9CA06BD4F9EDB955CC44F11C6D2E23378B94BAF0509DF55E8D05C4F8DE0B4FDA82AFE7450A0A3E5D8DE82368F1390D5696FF19D1C4F265EF051CAA0E68E336DAF98698FCE2472A6B580E1F30BFA7B385D8F4DBF063FA79E412756ED83668D5C3EFB0FF4A59FE6189D1B70EC45C7B"""), + TestUtils.hexDecode(""" +5DE75924D05BBEF6B34CEB195AE3349EB621187051B1EF95A779B99A3E0F729994BD19C7D1172418BBD3E015B20699DD09D8BFB0A343F477AE2A3BF5737AC994619D1FF3C13E7676D1BCB446289DBFE36E2D1508A3D437B4B0DA06478DF6D4701909B272E9070B1FE06385DBF8A552B471C8EB48EAE39D141009FBCC5D57D95697ACEB7B5231AB5976FFEC41E947BEACA7639F664C6C1D058505A49561811ECDA46E23B651F918112F38B407E82219B49E5C4E7C247DC4BA633C746B42DB912B07D56302FC5C08F5E0C3E311268041F970E670F3AD26A207701F1359EEF9D4134ADB882A1C899B0E4FFBA2C68535D97796636417EEDC0790FF808C976B57F0838A694700F8D75DD4FE5ECFB4B6A188FCB77FB1DF7C5F7C91DC81017A5E9A6D1EAF59680D3291F74743E1776A6DE31101FAEA31D876A0DDF3777A91EF1EA0B575C83C97C7A283E7E958287F5A52F30B6E70201A1410355B47210B911A7A4F6FC23BC95D7951822115FE410ED2E7FEFE08940B3F8E63F13F26B6E949C498E62A66FA675850FB9F7AAFAF7D054F5C12306ACF2900A5B66A29931A5919CB31D19304916AE41869CE3294B0F5F88D845A7FCFB57B952BEABCD1DF7FC11E2D342AA5A70A8AA9DBE1E6E66555EA618849A95439864DF6D7789D8E3B46C6FE4F33877F127D4136D993061DAB530EC979F818A57E1052B5B33D22E941643DE2FF9239741F6459A0EE28658C3C0033FA62DFF37928C59189A7A7E36B1E305F3E1F421EDF4D71A96C71406A0F9AFA5C96A9411AA1A35D241D7186E5C8D0CAE15938FF869897DC3B7D8196D64DE202108D6FB436FF89983EA6DBB5BC88EE2A02488E4D12AA87CC4BDF41A339E10300D32E0FD4F3D3136FA64BA90D64E2BC7C20BA77DA4DB5311F616288496F2FE3E7B3409879050FE57A23DB0344CAE82ED329B0D31DC9B7406CA715E3D84E364BA98F73F693B6E62DF4D741928D21D934453BD67FBBD9725BAAD34E5F3204BDBBB569251DFE2D69A9A96BAD90256213BB0747E7950AEBB4CEAC7224FD5F8F99A16866F5A1DCE07C2CD1E06B70A81FCECED0AEEECBA62521AA0A01FD7B5A3A8A14DB55AFF331E469F5138DBB2B96BFD0AAEE7F38EAA375F71759268546D590BA8C0C022F78CABC4E089992409D3D7BD19048D30B15C796170BCD7AAF7FED0387542BF8A6674F197EF994FF81BB80C59208A572495DE4E584B36A7E9149B5E2081A4DC162CF8376029231EFFB4B4981895FC36562F51DD5158DC82ADE52ABB0E98F4BCB3C0A24566D07686732FA734CDD48D03DF99F7253E589CB8725F17E6BF964E96F9827CA5A9DBD04D448025EE014EE1B5DBDA514D3FEE4F20664C11371DCB16991DA883BF9A68EE30D727137D7902F4839635B1C63F6C4F7D42070E880CA774680DAEF105D277EB8D9090A98F6B813774D42DEE922314480EBE562775F68ED180B67EFEB077D8B174C7D4DA877B0DD3698CF506EE382AE6FC6F68EE93ECA3627B28248D3EEAC469EB0C26BD1A10A7779CEA142958F9F9A533BDE974E1B3CD9B74FEEB2EE29ACD7DB65E00D7ED6E94E5E44A925188285166570727FC687AC7EBE4042BAEF68BC23F4B9C51BA5040BC6BBA41FFA9AFB1AFA09DE1BAA4DA091A08086128A9CA5F27D3F4420327C8FF4801BBF2057282D05D1CBDE60E1E6FB6715EC41AA9A852686DCFC47279FCCE5D86ABF02A6B5B57DE22B2097B12381EEC567E4ED1855F9B482C174D6D40A5825687C02E1D0AB634C020497A44E07E8FBB2D05280C53562DB4C90AE0901B88179D06F9F991E33BF17E7A9227A30454430CB768F56842995081520158FC34BF5257EC8EA9338B3714126D6A95A3D77FB61207154F6DD0041BB03D84D8F75E6EE910460F22CA765A2206D6C56C6E498E063B08B76B1DDF98571F492F9DBD3DEAE7D9C8EF21EDBABED962331F06371364DFCB3216E24638A20F77FCDD894FCC5525DD0C8FC329494841EAFD93CFDF0053FCC27F5A1263C7F4599C186B35FCA9C6F5F2FE169B00275F15447AAA3A823E27E322CA2316B25823F3A79FFA785E9CBC953815FE06F376B6F5860C6A87CB9BE98690C9C2A93EFF1BF1050A01C72CD521BEF265D66BC4B8ACE5736215DE59290DA957175D704BBEFB0E81C2CF906C3A579BEAC3A0C945409DEE4A1E683A0DADB3C4AA7E0174710C72A33F1BBC62A6E6F3EB9C138C0CEDA817688BCE8CCE523A2A4E2566775015F3BF66C09E716CA929BCC6DCBA7427EBD93B21CE276820734331B078558C63ADD096004B67E618D9E58FF3FEF00183EAA293A1DA2520BC03FADEB6A74B52292DBBC6EE4E5ECA8F8B0556FED36C2B41F9D8FBDA8EAA1F74BED46F05E7712E20E463502A420B6CE67D125BE999EF906300C627C57C468C8DD608F9AB354791E6FEF0EE63DF3C1821AE78111B27E57DA88FA44D89581D11C2C72F565A3D0B5E8E2D83DF178810075E5F8FD29E1953BD2C6326B693C5CF6ACE086673D69A67A181062A6ED511E0CF36381358C2DB2A394B05E0C1EE9C54B89C68E10857463F71A842BDB8429EB31D250542F88E6BD3BF10BDCA160C0FF44EBE7D0D982F15C4892091B4A69A3AE7051BECD1D2DB132599F1101E2BCF60136CE947F339A3DEF9F6D81E1BA3F5D4CF2ED989861F7CED86B1A6A167291CACA74C45BA7B5969C09EA20C4EB061D4CC4B68392AC866AC591764A16D0A42710645988FE070314D0859A1F022789442381EA0E3E83F5245272CB5FBB861C3729EC484D2F299F37D2F50688D1D8DD91F131D03207CD1459B289B19E3ED609D70D6BF8E0B97A75F4B4F1DB52DCA7AD03100A36C45D2AA221CD01C8A51D5328AE47E3307EDCEE9B27F62E5DA9EEE15B7A2FCFF1678551BB3DEAD4CE54A16C22119BCA343822DCD20271BB1518688CF69B566A123F65C4787C1C525BAFF00CE20C46C536E47DB1E4410E572BFECDD7904583BF61847868D7D1AEB1EA071EE15A9CB9E3EFF8D17A5BB7EE8BA83C95272E065979904AA99CF036BE085ED869D3CCB694C025FBDEE9BE140A0A21689F95D90D8A54DAEA98EE5DDFDFCEE2908E65C210F347D26F35B95B34642939067CCF04A098ED3E2CE3C0FE66305BB5391E223E43119D38A33672FBC980BEAB96558D3A940700B3CCA9D3AD2CEA08E23082DBF30FC08E94B6640CA04BBAE80091ECE96F128B37141131FED2A5549CAFD7BEB5B180509880C49FC6CB1C11E4CB7C7901C89ADFA0E5335C43A74053347D3028B23085647993B5844FB2716B7154D93E25DAD1CCD889EF3B16FAE34D04145237378D66BD09A254D395736990204A5627F5446787B467B619EE8F06CE664BF7B94392B5C77BCE828D6186348EA2DECA1CC84999FCCD95C9EC55E28C8C2FB559C9020C6EEB661F708E40351D7E530BFB7B1C3683BF15FAC5B17D1CE7EC5CC3C27E04889A9E59E6534C08AEF6934747083CCEE84FF2345D519CABC7D2BA6B783D36C864C65C47CA636B28B71D6797717950D652659AFA8BE3CAE4E269BD527C0425168D04C097DE8F34834A7D1728367F148524366F9E53C4CC255D3BD6FEE7B5A6CF459E1685FE740CC203EDBF58082820B967A40822D36BB4A489BF0CEB51387009D5205056387C292D584309076956E56926283657BF7CF096F54E0128A265050DF528AEED9247E19EFCC79EC301A9F38BE7AE5057456631840EE39E191B25F4F7070BB15CE2CC18777F7CBEF100FE7993681D4E965D0C19A68591BAAABE601BBAB89FC27B3C5BA83545AD645F0DB716C98D5C7A37E0AD97C986EDB88B025D25E3DCCCA816C707F0E2542E44F4D69F943E1DBD08E344F88661B68A822C3EFD648AA23AFFA2F533879540BE2F670F4D53091AF68867E7C71EDB6E9E494E9D30A1839653422AA8AE34A525EFAA62D3F5FF00D91F5DDF80FBDDE464A8502AD9AC85EB21025C0E4E2C2877D50962C5AB8283BFC823FB221CC285F3629056D1260AAF87B556E556B4C723D44279A106EE4075BB79773588333B42065811D671016AF177105106203EFC36FDAB2F5E5EC8DE043902583C1782BFD8BB772353EBC5CF03A0D869E5F3797713B58EB7480CF7B92AACFC9C41040BC9E1F5447F9852B2C5B5F33B5517F28A01D5435C47E063B41D3B0F7605B07AC33FF6F05C6FF44EBB70FD6E1AFC2A32C9A0B1AC17044401B93D6439CE53C3B033CFF06688E1933CAEEC48A04999A01956096339B5E44AB3A57FD1F0ACA23A03114708BB16803C2CDA679061B8E9808A2E11DB0957D4F73C8A06E6C50D6DA43E4D008ACA23CE2A3213BA0DAD20D5BA8B44DE5D50E188039C112B8A40B250E7E815B1367375C5698B61BD915A70096815479916F455B9EF837300908C5A8BEFA5157EB688EA02245AD3B309D10C769CA1B8E5CCA2F5FC66CC3920759A203C3F6B8E9ED10CAB20FA143B0BF0BC8529A4E89AB0C99AF77E43E68B61A9E4176066C4708FFAB05F3652817FC42039E2F22DE2058CFA8701AFFA894F3143FDA27AD85C45D3AEB30CA9759537CA4AF2079317CE5F4B5EEFBCAB981E42065AD5CB8A4CC9B628CCFAC18D2E637CB73399CE3D90A9060F88EF438E8511CE6F403A0CF14C6B641830983C1EDDE73BA27E41BD678E834167C718F5B1E2E6C109199F756905FAF9F0005CC1D110CE277DA02675461AE70EB6A412EC455B6575F16A4DEC0565DBC8F387D84F9D3AE67AB35E511657D82B5606A4DB45CEEE81C94FFAFCB88B8185CFB67E4D7171EEB391E9E1DAC625B56FED22D86E8A34924740F94A3D50CBD05B8E2476CBC7C54D2F742F0FD7162E7A138D4AC788E710AA45824513BEA162E2A1C1F709413942BAB5AABF7E347A148D53B8EBA0336D91539766AF0E827BF8EFF36389ECA38232FF2D7E341A3AA710F590C78EB69156462BAE9B8B73386F38EAC4FA26456FA555E26E7DF679983FEF23DAE87DBA66BCEA19A9F991F864A17C23F7CD592ACAEADE0E82F4737B70F0243F94F015B59330B71E25F1304DB3D8D7E2F96669BD7F8313EF9E10EB1EDB0F0BD94745D03C83768A618AD9ADDEDA7C1E6E134F8B7BC96B84652C982B1D9242F8D2CF0ACAD146EA3185E2332904E84088CA2D7D60D3E2DAE411171726B5FB6C95B3DE961E62474CEC73226E55AE7D9C7C534E278927F5D669EE6D111E325D54F338E2A6A06493D6F1B7A556A94CC9512235498409EEA477597EFAB239380491C9CCBA1F00A0D1C5D758162E9F4F5464A1A64A22C32721AE57E246722A6B2E07E544A5FEB06AF86C580DAB2B9DFB5AA0F0251E6840EAD66FCB6B89F80C2AD38383B329F9EF4589BF0E8A0C9996EC19E1DA539CFDEFB2BB0F3D9544392A06F765A74218B7DC34F38D230D1AFCF9130410A4B4FE038F7AC59B6B062EE2D2ACCD288606AD9AFDBE95D9572B78B54D26166C7817E6F72F7E6C55DD1576720E4AB99CC26722107F7C278BAC2D82FBD0A3B0E1793C2D8B498F90A9172D17244A4107D9274958FE078FA8A5A33087BF278383F439C0B41523E0E51A662A9F2822CBBB34EDA97F5398EAA12D52506C2EAAF6D4B75639EF0676F482A69DF0E8A9BDFBF6105E32B6FB3ADA2E29C62A0AA687820B4ED35C2418DB1A67A3A5B92DC61368585CF7F3B1B644A8137A52CA21DD982760CAB7FB111558ED0310E9FBA34E5480F4E707A2CEE74DC24AE5717C06DE2B509E4807824707505FFFC5DBFF798E8D85F758A94C2D3770674DFE03627457B2DF10628A31D44BD89D3435D93E4F9BC14D47E6D4B9BD3BB2287ADBCE1FA58495D9032A9A3ADCD56CCB116787E060EA431C1EA9E60A30B609AA9C66064017EA05BC16392992B7DFF62EF1046FC7E64F8F811CE50AAB40AC122CBD5119D3045ED0812F6E30EF6B6001285427B643E3C6FCB6390A9FE76B342A462994F2B9074B56A848538DE205C98BBBCC75DF6BF23CC1AF0B201E5A0618D4BC5035B9F71BCE9D3493A97FA47607D65865A5FF3FF17A7CE28C0E87A57FE951C8F804EADC21F161CCB5D1E66F1E4DBE92C69D4358E0CCC13A12DBE87C9B530579189EF2359A9DF5A8FDE00CB2B58EBD748B23F884626A66EA39847917995EADC1839BFEDCC24AB6BF22A5C247B6FABE8CF382DB48148915167BB47F505C184EC027C3AC741BB0F6676B0D0E7781E19FB8D4D630E71ED4843010198DB9B122CC301D432856B393632369FA1C99BA252F086E317229486C034F1960087ED4606288A7C89DB0EA0DE94700785322249E901897611913AA74F8BBF412639DDB639CBD1C41374A3EC66A87451D9E4127F7627DFDE4E1701D7FC9DE13DC7754952F659EBA7B1A861B8DFC78D1379274530B976C66F9CC4002563837C852D83B3F3BBFD892F14DBF64C976C924E3C656B69131EC17B7905507F78F073A7E509157215C988D490685F8AF23F64ED338915E72B518E4305C9CD44C219876456E87C0C59C5D7524C86CAA161C745364A12890064CA9061056F37ED1BD56B5B09B1423775BF0FCC898AB1BBC283B23DB6E91A3D749125992FF1BB598260DCFE428D2524050C1F545FFDA18A63B052C0C8CA4DF8C3BDE83EE5474395135FCA2B05157C25548B0804D1EDE"""), + TestUtils.hexDecode(""" +CDBC27DDFC61E219B3448514C2DDD3D8A8199E8F4B49C7E4E73178708F40D30FD66E7873D6BF716588C97559C6C4998B2E43A58575F4854C6637784055A0C147AB1CC54787C73A49FB8BED952D2679DCA79EABB65926DEBC4C7D25D441C56ADF09C409C9FF12D2C43468CA67E45AD07E58CEAAB0F35ABB7F3D236DB2849DC0EAC34448643D7183055623A7B9BC8A08033D3B5939958E90DDDF6C9A7602A44F8516C78386905270FB047C354303AFA6E2A387A8832DC8B436BB178F713C70ECC12E98FEC4D5B28A3E072116B9D2F0BB95BED447861C56E6160170DA93030C32E41288C1C06794F7E6341DC4D6031051E51A18B1D7A9FD1A84A5DB0A1F1FFC93E0976F7077A83FEDB7B085CD366B67820EA9FE232C77B54BB368FC6A530DA21605249B3CEAD87C3E8B4CCCDC776F0092069679FA63DD91C802A368C5158718BFC115BBF9D45B7A87D4B03040A1E4DE2CD0343A318A04092EBFC0CA2BA1B94552DB961D42B1E638234617DBD18B4EBDA761CD35D12C30683428C83754D8FCA43DBCFD3B3D486D234A21D3563C8396E8AADFA89D1D79F01E6A139504441BEF37209F8D5C5495146A8A1951EBF17F7317D3594A54FAA220E3A73DD7EA3D193801C0640D6BCE9FD57F16C2F749B3E96B2071F5A36ED9D038F97616EFE62C383E69C3D70AAFC5FE4890D827D26CECFC0AE1C8BC96841652628D318F424F50915EC65E9DC9DC43E19C08CB4011818C53301CE8A292165DD6249A8D796B257481089780C8895995F7672F1B2124AE77D38E825F72EA07E0B7515AD8DC615735268A417C25944B33513BACD93C3502688130862E2307BA77BB74986819A152A3DE627401B268587FE1FD45B373CDDAB5C4D6B593D07A8421394D97C564F7F373C2D90DB689500E67D9C7FD52B14F7F1B20F27CD97BDB06E04E13D702B92B640F6E20DB82F0455DDB9C2420E7A51E063A00962C29B4273030A01EB60690C48660F552D41D7EC955B70379EE13E390D421F032EDFBCFD3E958085EFAA573E60A55961C2E390B50F85992864EE654007CA0DC6B2CC7485A558F5909C58D701F91895DCE90FDAB1069B87BAF2DDD822DCB61ED44DDEBA48BD257827F0D1045FC7B482F462ED3ADC794C2974EACACBE3577353586955ABF65538C942CE46A3B5C9A3255BE71DD5C8A572A86095BF4A1FC36BBD3E65E7AA536FDE6A31069BFFB676158664B1BB87144D3E129156E8A22CD757BEB1495A5C9740B0F0B271C920EDBDABB208BD544AE20B1813198605042A38B40969B0D6D044D4804061561ECF8AF816B7EF6B4ECA3AC0EDFA4C8699C76080CE3EAA5E2CABACE5FAA150E5D233BB694BAFF02D6825FCE4412725DDE05DB5F521B9E17DE3C719FCCFF0CE174F369C2DC497062991B157FB2FF36772C084A226D577E9E451BCE364E0EA32FAF6B366CD5E02C74D8907ED3DC54925EE10B3E97CC96DCDA7067DA790409F2B422616C65CF3CB26A7C6C8E9240C9235BA9B7A67BD21ADC729B102FCDF7329ECDB2EFF495122E265D0F749EE7414312532EEACF600C62A15A18172FECFA2BFA62BCA47CE794835EBE25557A61B61F6977BB7ACD04BDE30C2425F68785B3E227106FAD9E5ACB26BAD47FE1AD461EB2445560904CD6DEC4DB091BDE4CC2ABD72CAE258BE07CA0A8634C72DDF75A06B4AA84DD16F9E9FA2D2DA81B5553C598E10E9FFA7E80AEA8131C16775C1DF3E45950AFD77E9045A419A7B52D3F3B1C1309EEFC00B53060FDA34B95FA6347305DC91F477F4D99BF4A1BC5418CBEDB316FC83B090B0015BB6D0EB1AF1EB32EC962D2AC089D92BA915A8F5693D04876D2ABCDBDF675B8A871B837FAB190CC47D93C2E00DBEC028A26860DC39678B188C27E8E776C7C8C72CA22FEE2861725C7340D4B5B6D8D0FF63A5C439A1CC12137DBD14AA540C10EF6993CDB9D5F6D1C6A8980F48818AF7FF6DC75A2AA1987E689EB10BA40F2255BA2BFD9A36C629F02A8CBD4A862D9D6B0E6D7C25327CB87F47799ABED84BD3B4BA60422B5491FE512B0A689E49FC2D037B8D7B9FD5895C13A40C14525A6A1AFB1DB0A6747A3FA1E7CE023F290757BE19309154477176011100160232AF0C5BC2CD425AC5AED3955CD7E1A700FEB09ADE5BF281EDA1DE0FD91B072F78AB77EDDF7C7E47343B5184FE540DBDF6BD617719550B8658C29A276A704E500C379D03F60A2A977676F04B0249AF27FF58F09275AB99C1201702EC1B5AB7CE4F08096C561CE2AF0A373B2C797DE10C017D1D65821312989519173A8F901E9832C210729A48A58DE10E7F4F09453A02E656B629366846C5AF57CE17C889C1CF30FAAAF091EC80A831991519580F80770037F1775B534612F5B7D1FE5D161BD3E38CF00726779792C17E51ABD013D7A9989EB9A136EC7059B8BBD5E3013D03110326299134B2CC96CADC3995FAE8EAF9466D7E502AD3755058612C083685F9355DAAC4B43AD138C6CFCD100E463D17ACF63C830A899C2187E85C2BAC006D9CAD1276C2154FE264EC6E607E178BACB3290DEB1FA077FB3843DDC0FD44707096CC54BBB17F1238A975A536BC00BE8BD625C930147EEF5F110D5B2B3B3E303D44B57289A00D1E047314BD3A206B55AB72AC676C4B26D004E23E590396B52AE35E3ABAFF7E5C965404714D1ABE9D69CB6F780EBBE4027B8AFBCE253EA7D7503887262673AC0132A0E4689DD45553AEB1660A72D3AF71D85E94EE92E478BE68253B48F2CB40F88C35828274F04676CD22996D6A7F92175C733C06E0B71F077F0B7E122314B771A28786DE8D2DABC94F720BDA3980F0C97BA6849919F469A3C6B0FC12263B5BA87B8BB5F01BEC53A68E5A1CDE4749223CE118CD17EA6F2743B9ECA60DB616BF30C4FC3B15F3F43352D72B8094C47064EC5E6869BB45EF803B51DB512DE5AE26A90C3EDD184751F9179B14D8363B7EA74A27463EB85846EDF89D38CED01BE910883239B51D20C60664A70156C89D7031DD2BB0E51E1A520DCBFE8F5099490F3C1477BE812D0EA2AF032F1E628067998A671AF4AA84B694EC2C6193359E8B43404597F4C3900979EDC4CD7435E95A66DDFC704CB918CDA3541FE63355C1CAFB19E9277C7B843AE4FBA7B7AD8873BD54E4324714D80D906E8BDEB17272B722681A2BF2467CAB68C5DA699CD1EE5F1DF3849F7AA1F2321F6D34DA719E2A93860EEFD441F25442B01081511401648C778F3E081ADAF247FF8BA3F2DD2E70294B094D8C4F73292F0A28936273710E6BFAD532ECF02EACFB6572C0EAE5B5A258E12A112E1A22AC086938857D189DE0912313E53757B80A3A8C2D3D4DFE4060E1D23263A3C63727C95BBC4CDD0ECED0B1D334349858A96AADBE00F1A3D3F6B849AC4C5D4D5DADDE100000000000000000000000000000000000000000000000F202B39""") + ), + + new SigGenTestCase( + TestUtils.hexDecode(""" +ABCEC4A46E695FC6EBE64A191389F0D0AE180F911D5B824F4ED9111728FF4F9493EF3A7512DACF766D576898D33C4C8F4001B777EE5EC2E2DC1A8E3E181B43418AF45100B92A3835D02B9892E609B2AA8C6AF7661CE0BC8362AE0DA172A79E84FF4CDAD8607E4924FF41DB6EC28DCCD09B8D1F5657BA17C848BABC71BB242A50C44069A0200101914D130822C114288436508B0422D83004E23848032532CA902509A0009A848440004CC3304D04C0601CC84889340950B68918C81103410D631870DB444AE4224D8B96491B0224C2802904365290222D424626E0060613B12DE1187203B18442228144027159186C22092C012751083160DC48061045089AC444601609240224DA006623945149C200182232CA462A0BA16D22B2215028700AC108D1828C00B24014083221B5810C4501240225E44291984622C90826532650DBA8495B226294B049603050242382DC0429D2260254262CC3A868001546089168CC067184B86C518285DA221110402494149044B8102220299AB40190824D523050229668101072913411CCC625D2880D1B1951C3888C222509DA20322003209106028C188000B02D92421111B92DA10890A228700B4464A1B01153966800B925423860884688630800C3C2910BA9511A1902C2B229532052D9906DD9C080192400249589E004914180600022440908012435624C48864BB46123C900588869C1001251248960B64844322513C5318B909118A8691A850449B800A3B02598A2052293455342701B3722590860911248939221D9024E2042601439410937318346851A836D192751C93686111749A0B4649BB285CCC049C0C4611A066203C304A032248CB861A34408CB4852484866244610A1068909280C01810C028531232102E4442C0A988C19C54192187223B168D844862295405824408C322222C27110170A910668D438529B025212086458185208078DD388240C1092C2C60D549640031989093530988425D104524C146E62A06C5AA004CC126AC3284490268A43468021454460B249A390681A4745D2965188220E6032249AA6280A034A9CB6888B180CC1021012B70D0340480CB3444C0010011549E2B23094064504378441B2401AA3884AA885112229D2402550B0048C2621180872912851481842499020C9126D1A1289A4404C4A82710301228920449C48624006920813819CA670D0C808D938721A118A1BB589111150C3C6695386851A0204D2426D19116419A38152C861403A93CB8575520D2A3A7317CAE1963E2705B7596C8E5DBF0DAEAF8755DF38A5DF16297CFC84097B480D9729E4CC62170739A1A8A2057EA7FEFB06275344ADB6934E1C2DA7E7F3E831FA35E6A4B8D8DEF435235CE957DF5FA1D842962711443BEADE91070833C84264B45E2380B094202E079A0A7C6058A54E6F552F202760230F6D95F5EA873709BE4D7603AC010CFBADAFE229CADA1F2BC717F877856D8B930D0E215C4BA2212D66E21A2D1F09B1F1A9BC8C298CFD65B318FE91847279F204201203E0922E82BD298D9BF18B8FBCF72070F7C7C51D5480E60674341CF263FD179862F37D5665FE35ED0B2A86B7115C90093F5785309CD56C48BBC50570A0C2D066BD0ECCD3C86E2A6C8B098AFD9C0E235CEB920D58F0B913BFB633BFE21BB1668D9C45638F5CE9650CAAA83DB2D9B4B24B1F518B19226ABDA06239698A90F30A50AF69AE1D20FA00E3D88FF6F2C2466E45A39A1C946FB695888383CB6A59A7C8395082134A82DEA3DA7FE6D9E6F76C7E86A50CA04990C70DD5F9AF062ED14CC661F453BF309DA08056E19F2F7B34A15235230C15EC6859D7DCF0ED892DDFF4E5096B36B406A10CB35AA81F72827C5982E3C5BFBB989E062CB4A7F0F76B008AB8CA5EC1CEBDABCAA1E97809B44C5F49281415337978184811ADB8131D2DFA2477D27532E92409493D46C597A6886250593FD58D305D0760CE8F772337D42B0F7DBFC483A941E8CDF32CE3E97309C3C404B6E4101678F123438853FC8A71C835D1AD0C7712460DBE83C1ABC6BB0834C0271A6627E7DCB93EFC25F78417BBC801488E5A051455343757F6BFAF923867C45ED5BF37304B11E012EE63A3B8D84DCE7A15D5AB940D87FE1181EABA3C97BCA702F5DE4DF74848A99D2B1F34FE2B03633D6AAC900A09C278556172DF5D9CDE361A8ACD779465CBAF50DE5C8F4CA0D15DF3F74347C6DDF7D9B3E3E5E197BFE0AA170949FB42B78364A72B1B106156EC09A6E4EC72F3F814781D3CE7B7AA2B02E49CAA25AC36DAADE0FD570A61589553A0CAE582BA2894C82C0380A713B0B74924E006A6B341F21AE2AAEC2016D2687F1AB696337F5A268B3B6F3730F507D6122DC92CAB36107E864BB3EDEEA6FC1C5309A9B51582CDFCC1A899929AD7CDBECBCBF9D38121D58C3B3E6D9BE001B117E4A7F762816174B761EFCF291A1CC5DA354029962EB8B0F6166A9C9EAF26921D1777E621C50C41614300605B1EE2A0CC41BC666CE90A15733C69A82451FD41F23EFAA73A2482C4E3D476CCBBFB59B25140FFA0C1CECEABD3B036F2611C83AA834E6CFE03963941BDAD4AEFB11D01EC43293BCD22ECB8784EF5CE2A6042F200F1B9D6C595EF920C3CACD1C1C3CB61B6B46454A3B28A472AE0203038A5602CB9B001620C98BC09BC2DB5621C8DB085D88561058AEA691AFD199C6D4BB1511137ED2800722A81670B44FAC51DFA6683675BF34C52F6EB7EBA35D22C907A207AE5CE6C3C40AB0A26B88DAE777E10B4FC33AB38C308CA2532032A7F306E9ECA723B58119C3BE662817A1EAB6069FA05C3B0ED31060D5794121A83FBB152C7FC05BB753C9D29BC329E745D7C7D493372C26C0336AAB37B884FB41741B344EE4D247D6B5D049E5E322CC97EC6647EC7551824C6AA9CD249F49FE1652ECFD01C3E7EB026FDCE7320D21EC9E4D460E50D6440C7364A15AE3C107CE8EE1E8A33EBC9D2B5585B8F69771F687EB6940C21F45750079D68D3DD6CE1CD7CA8D91A64D093A25A96628169B675CDA9F14FADA4AF3D11B6524465B89DD4EF93A9A159F8DF2A134FEA301110EB77E1ECA51166D26CB036BF92F1655167BD32D12BE04A91FF0B3C52C69DE376856FAB9B4E14524E5858717ECBD0865719BF1DDEDDF8CC141396F9F0B4ED38B0CAADA08B64451AD8BD38557660CFEF46EC0059B4AEA6A7534A3DB767C537E60210A1AF84EC939413FD7EBBF14FE96D6EE82A0C632EDC63715C0C6654AA4FE298F43ED5B47AF7350C32C8D7F696F9A96B81E9832F486A66D9B304A6531139561FE5A967061BDFFA4793EA986C3A2693C21DAD4428FE98F168EB928FCBEB8FE0A611049C1F430CCD80F9181D276AFEDAEA40261FE1B038F5677AD507EB48B9768964BAEC928197AC26ACB1A89CDDAF51C4336B6F49985C13926E76AA7D69F5F0844F23E7B2B977565587718903B39173F7F18AF84264370BD61020F2A76ED281687419E334443159BF6A21533F41E030654F6876AABB21025B6D2312304FF8BEFFB7AD2E225BF79F1B6F8C33AA90D9DC18B369846FA06548E72EFB2EC4FD6BD833F1872DF9659F62AF040345CB5B8399A4836F7F5A9F920F0484009C1F6871D2"""), + TestUtils.hexDecode(""" +22AA98C685E1552B525B4302C943037F668279C224B6270DCAF2B06C4F4AB1254C48DE253829FE6DFFA9CB6BB294F054711BAE3FBACFB900CFD1F0844E55D51EC6F697B998759B14C13392DDB6F7DEBA77FFC22468781CE402"""), + TestUtils.hexDecode(""" +0313B5DD1E344BF95EB5D825837F570922337633494F8F2EE3618AEB906DF766F5ADDCCB8EC1C5CC51AAE0B9FAD876FCFF5D6814357E8C63FE59FD72DB3CE4D1650660A0CF64339D8B7C6DDB7A7A3C8EC6C88F2F0F70B377D9D5E21F0D40E17573F07C94CDF844CB6794CE2CB8E4A11254FF0012D562DCF4D9FBBD18348D13E1B69395C69DCCBF618D7A38EA6A51B9F1F8CC70CD36D087682A558A1EA9BF9DE6ACE5B350B6EB977F435CC46FD43F155B29822D68D1CA9603BA43F1DB28BF4D3CE284523BB440D1E2C124CF92DC74F19B74CBC177DE9B08377B0E363401D23E97AE967E13AB77E9B7C7488E49B45E835136EC2874A24CC79059DE5B0A67C842F2E09B37B3039DC186427F760CE60790A9FB58AA388880EC720A783EFEB4E11ABD817A7EA884E5EFC279AD9E8AC2C58A41020C7468A749933348EBF78A0F0597B29B00A126050FA40F532B0F4411B733BAA5C80CA1B52828CB236268989EA2641431A359E6595F49B4FEABFA85ED4BA85443E2D7B82DC7523FF627D336DA1551897438100C20F0184A963D0B9AF7F7CC9FD64A2878D8FC5ADE2D0D928445EEBED286F2B280AF573EE62E70F698BA0C14381A5B4E001C53C49A77E9F181EC65B49E6CD8BBE30B5F309686F7DC80176F654771DF17FDF136D6C05498CC00C476E71608A39CB29A19A986297CB9C1E3FFB4BA08ED42AD12908287F018D49A0E1AE89A9BB3F932DF98CA91E691AB5F3BFADEA9A233350A9EDE63CFC45427CAD109468FCE4ABF7FDB83C6EC83865134380D3FFCA4D94C5604DD9DAFFAC204C14009FE06311B81310940C43FBFCF049F99F5DEEA649A333F6A3AE6232EC7CDE62C95338C23085D776B9B8F4454E03BD0FB28046618C33A7CCB409BE7BCBC0906B5A9424B41998A3A1E65E5EC667A14339E3BB44354047A2868D64B78FE5FAEDDDFFDE497368C3CC130D0821C1DEB2C43119195C6C4CFF1D5A778965FF97685DD93775837EA0852284C670DD418DC9FDC9C44DB7EDA60E58030D8FBDF86D48B98230E6AD19E97D21D7358510E20EE374B8486341302EFA590B96C1DC253226A12CAFDB3B4A31EE2270F764B74F17BF9C5681B6578777739FF767D4E094CE80AD9804261767097BDB163430332C428CB3CCD9AA881316B51556C718A95816797CD5C8A2A640B85DFDA520D1A0129F0E9DE772724EE8B74B4DF6793EBC0A801B6F77A2647CA2A5F564D336BC23ECF591327A8DC4214953D99EA3A9ED9943F07809B4C36A8BFF093721949A2AEF2CDD9687934849CA35BA1F38743AC663E48B39A2A32122B6951CF6F1BE17FA96628D8DEE8760CF7F2699045DF30484722601E7A45DEB277CBEB749F5CB4383C8643241158EF13D8723B9B00C98F8BC68C5F42DFC4A1B8D95F4652AEF67798A8B3C0C2AD40CB7A2B88A23650147E32CB605324A99370BDB640EDAC9CE57EC22689DD45D1922811584B01685615520DBB0FFBB028E43B77B54AF4A3EBC6B9F857E9100FD9C64028867999BB9C7FF05D37704D41C94CD63DFD1A7673F817931A4F2C42CE572B24FB5E779897FA4E6E2191524783C710A099D1A6BB9EAE47E849187432A2039BBE1D37D0E7C797907F99BDB8E7FB33C3B2FC9E06708312BEEEF2935D443F29B646FB5AD52C99EB71559571781A4C86250D262329FF3DAACA18A5E7B77C3CE593CF3A92B12B9AE86CA3AF05EBBBD75B6BEFC368982D96F2E5FBC128B6A8D65FDB0B0F7859689F0B6F0A3D1EFCBF1915DC61C7FEEBD077F71122E77775B4279F4F57ABA521BE4682DAA5B836B5B4D44CDB726DFF3AC9CDDA9F0D1CF4E79BC9E90DFF7562CF206E756C38E708BD30820A14C595288730F42C8ED99A7C1F2FA6CA9759CD31B8F28FD35B9E0980ACC3432F462CD9CB4C594AB63FD250DDD4877269056677EA7E3B0AACD4757AEBA398688423015D952D0CF67E5027BA4B6B376F6380B5823717D64513EFB35015FBD20FB2284E1E340C9B94F87CFBA24310325D7597AB34BACA6753215AB994390C2E5A82EEB06F338293E72C5D0FF786666FF2EE2D429461F1112551AD0928844D7698D3AB0C4054881A623525D728E514E12550AAB227389E5F0C2341A6AA34BAB5472BC9E465DC24E9910175B2B968F2E7883CD22CC07B3D203CFDCDD877CBB28368DBE668F561E3FA1C5D3391D4A408A71E0BF0C32C1FD6494DEF7678E58B829AB428509C33F2491725959485928B2E7FA96EC7AFF12BA3196087D3C83DC242E5EC95BF95C8581693FC0B744E758E1E85959AB63E9B4B0A4547BE5ABD7D29BF9DA2D192B4BCA491D1DC856EC80AD6C3C738FB775F95A217D76093852AEE0CC203DB1316C6253BB75CE2D92906B47A5B733E4A8B0C28B1283419249B5A05F6302CE110F85790EB46DED7109B0DAC58A4D25255B6950F3B2C3421140E4825B6AC968091EA7AE9790BC8D03F3F8F4C1BF1006E821E5DA2C65C542183F4230CEC934ACB81FEA94D959FB6A21C7AB20652C9B247EDEF72674FE915858795A9A00564F602136C364A6D9638CB1BBD8A705B90429D13A19DE93520229282D5122EE112A32A68E23577E358FB28EC45478D05F64513A9E814A5F1FC7CDE4D03EC51ED41D29ABBC0F60292E2F7D0AA4490C38B583329E2D5A1E61C73D6033CB73A7A4F75ABBB29A31E52CD1EEDC3DC4F0B9152FAE6B29DD1F9739456AC5B1890B3BB00415027C634F1E6374F310C95E680086862B8BDEA0833997746814FC602F97999A2309D4CC05362303F72BBE2EEAD04D566579A00A8265E238FC578FDB2A63C57250B5714F2C6485BC6247752853F75ABF066637645A5A6AC0E85459EC2E24D704ED7DA4BA0FD23748D1D853BCF84D4D00EB4B6DA6D036B8F29797882EF5400F2F7D6EFCDA0418CBC5752AE5431B59D2D518FD752467B7EE13F699CEE1581AA1A305B2ADACA12647FA8FF00B427F28AA33FC094A374521437E3B4A109113E1AD8AD23E2AEBD69EDECEDDFEF0B5AA0A484AE32BFB2B05F8F7F65077F5B35C99B61EC28060437D9CB982AFA28FFE8AD4C02BFBFB071CA8E9EEA15CCEED97D47BE2313E3C344793D40B45F709C8A2C639C09662A81F117839AB62135B6715FD57F7B0368C6EE1E3234655EAE94213D24D92989A46CBD5C7EF116243A085462C5454949D41D2D570AC810B54C727FA5E187D0D9F7FA7DB3682D99460F5077AED0A90D513C0D833E5F5A91A5A26CF47AD134C074D658AC0164ACBAAE8FAE161E00C7F8B043FFF46FC5C900C9ED14C44C98ADDEDCD5F3BB7038868F8460EE12472DE2A24BCD0A611D9E039D60000D131D242E3C436E808FCDD3E2F55667698D91929DA3A4F0F72D4B58636C6D9CC9D9EFF0141C233B3F4A53595F696B6F848AC2F7FE00000000000000000000000000000000000000000000000000000F1A2536""") + ), + + new SigGenTestCase( + TestUtils.hexDecode(""" +3820A7CA1DDF6D374E8053628E628D142C4305EC1F3F05C66908FD5A1720C7F02EDD55DC8D2252C7E3FB5C91BBA1C615E23C16AD39B4FF5BF62EC0E22F081573D22DFC983A88CDB217F422AE9FEA6F82BF0E72EA8E6193E9DEFA584C29A9873CD76741016481CCB01ADA6063BC8BE27A5887FABA7F701DAD4114DBF31357508E54982900B391C1A42822330C82485114330A14A3601BA310D2344D63368904368293100840B42991C2405C22290C492C52084208A788CC266682148180300E10C330928021E214499C904812A169A13009A4908518882420926919A44D2448612217821A358019B2891245619A342A2132665B362994220E942812CAB6300A9251C910295B160848486E9A90641A238D0CC52022B9318A3266A2B82902440463380A0C373022B22C0B3152D40410DB100011265150C245424622103792882691D8207221088C8C246623044E1845698AB8886192004A244C0CA46518206C8A342C12498A1034455B200D02184E98420D09A30DD94028CCC821200150E4B02981466821434880C46DD0480E14884152829052C08CA4B26DA2C401540850A3828CA0A248A33240044032231041A3C680D3042DC9884DD1302A93202A0C250A991408E3160548464C64A2319818122308865A926814B7219A2071C214640028509C806413996D99002C1008909B925018266AD4020453026001950500953113A385829820C43651C30004E010269824660B920109362E500889E0326C14378C181589DCB864993271A00260C1A425A3C8718B8829CC946558243080C204583465D1B01088A82422120219244A02388D1A295244446E10320514488C13814544427052129182308A1BA14C1AA3119A163200B53049322AA14061801885D822520BA091D02422222112D94409D944215C84811416641BC40940088A61C40DE0162120842CE19000E024654110721B364A511085E398719A448223016C12A12121C4240A346520A850A332815A2051A288500319421B2831D4346C24A06082140C0211889BB009C424001034525A482AD91252CA96090101611892604016040B91214BB66910024840C40D00828D081161A142310BA424522612C3328820300D18C705243505D4320E94C8841C406253364811A061214669589611132001D8A430400431DB18120294281CB0291C374564A88811824810236C01C2500A24094A842D9936688086284330719A280E04A24C091312D124718298100C297123324843368E17AE9DBEF07C60FC5C871DAC487C6EEA46F0FB8B88470DE3D6C3F2B75C615689DFAA98540F2A9D1A3F8448947B6AC7D535DE9F3019C60901BECBADC594124FB4C677CF4341088FF2085957DF9F3837121DF75F92D40EB77D6F4B0AF61B2577E432316D09DECD949F1A31EBB1E4B51E3D412B5CC66BC65D4B399EE83AE52F558994F5C0C9D15617E43E9AB83A34C16D097A3690677B35119EB33D80A88F1A8A77C2343A29EDBC9B3D77E52CCCDC1977E09BD3EC6C8E05085D23C063F785B518E49EC3BA8AA156F16C760DA4787259398A9D343E5B37602A5318DCEB6F27BDAB8C143FF882993E80FAEE6707B26263EAC39E22980BFD23C61ABADE42C22549D493B23BFB6449FE242EB61986E5AB99832B161EF32CFDFEF5221C2710F1D316D12B170F4C9EC71DDE912EC7572DC0B25BE911DD536CFE6C6EFE9B7ECAE861E5D3DD28E68FFC7BFAF7CB38810DD8DE12B23DFCE3A69337FC423BD82764263669295023F3BBE4E48DC7A3F17337C7BFAABA2F7B57459C3572881EA0BD39DA3C2CF160B6C032F81A6AB8FCD5B94A7F2014F0AE904B4346994CD4C54EE678E23AF95BEB21A3BA062E1A9DECC2A983475641A66550FB2892F732437302F19F1B80F034208F6E4250822868ECC32F43446028DBAF1A910B923ACD44CDBEF856098EC10171A53B89DEB2488F6D4CC4EBBD024668EC570C00E335CA9AC4C031A3BDE783B093DEADCB5D6DEC107CC35591AEC160549D7263D1D3B6CADEC6D6DD874CE9C73E61804173F07E4F20F5B7A5C3698799C30E9489D1805F3A5DD6C36C70D38A573CD425FB89A928061ACE86F065F04D2C14AF0B8C9D8CB4F7640DC5AFBA3EA426FDA628B72A4CC276BE9DF0844ADC526BE701BED18843F001A88570BAD4181BB66E37C35230E2DCE7DE953D1C4C8F7CB7C46E1C57FB7F32BE90F65ED059ABB9250B8D8046AB35CD9098A49F81B5957B830FA47184DC5D10B5176142C956098C7410F3EF6B0CC092CF5B0FBF73060FFC9FC612767B95D1FDF018216F8CBC1FDFCB5A97B21019C0694231C34783D519346BE304BF1217BC6BEB5B2126CA975725328ED5CD6542B8E41AEED52FC50D1F99C35C755E207BE22A7C5904A10204BF0B583F486CE7BFB5D6CEC33370CC02654A6837F4A88E6CBE64C1930DCA4905DAD35DDEE0F8D4BEBC17A04BCB086D3C44BCFB68394384AEDF39D27471C422371FDD80BC72FBAD6C392285EDDA04A0EF4CE9742C020DA2F528E183E634ABEAE41785EF3C69FC8527F7334B6C7278960364AADFA66D58D8F7AF4183ACF3323EBB3505BDB84FB4A76B2CE0B768CC8BBAAE17FC2B637DE77E107ED1C6314F94677A4462DC03B60DE122E5AB843893944E6902724A8C4CA0C00D88C3D08D6314B4B07DB39C4EA413BE9E0DA58270EF6A949AEE60804A78EDFB0D4FC989C02CD7E48D116DDA1E91E72FBCBC9E90172501871A7E444449EF65F639BFBA5D4F297FDBD2A6295B67499FD853B4E26A82B62975B07945CCF29BFED8BAD16E67D95B8A485B9756CABCC8C99A11A577C50FB6D39C49B53B309907213D9E60983EB820276B2416C8CF8CA98D9A9FDC6CF3F122A81901988DE195DDF69D9CC38B36BF74BE8D4DA4C1345A5FDBEECAC4DF62B2146AA5BBA74AF45D2B736BE08593466E85AAF96FAF3FE9E5E6FCEDF7E3C80D1D16BF761B73B5C5EEB5F01AEA31153A5618404AFDCF85C2FE38E370B844FF850E1EFBE759779211CA7C219E2425B2510C00A653D32A1238CF423067A309E5839200F6C5AF42BF7EAB25A685D9965037C61047155A7B33BCA049ABB15DD4E869B7C9E525B607861EFBF250C83F95ECF3593484FEF1D49FCA407088A3B1B9CB6EC4FBD9CF8F2C1A5C98E667A8027C38F51299B6442B6188963262B14BB71F6824189FE8E372C6BE319147B719FE723C6861DE89A95FB61BD23A61BA04A6751033C5372E840B29C6F04951D3FF7FC559A3387DE0D582FB059E43FC5C230B8352A563E05CAA7DDCE8E068E5910F490706E8E6F58C6AEC45C6BE781AEEE0FB9AD868036E5314C44D2BE4DF0D4E47278BA9FF6418317088AF48347602D58B8F4CE43324CC9A053FA1AFB622664E8DD5020E4A6333EC1418E57C26CC3C45EA61600DEEAC5A93854D39F60315E99357BA88F58BD6136E96DA043825C7C17BD246054DCB99438E24DBAEA048666F15158D71C1543C2A550B9D24C5A24A9B78BFDBCBD3495D25449DCD76E8BEC2A65513C8EA9E729D7E1AF990D323A6ECF88E206C94A685DD3A4A9BBA3DDF153B7D98912B130C2A1C1DAA0262ECD8E43B5B1AEC483BE373EDEE376A866D51A3A6662C0AB3A062CF645FEF874E97CCD2D6C5"""), + TestUtils.hexDecode(""" +0B0F604B53752973C4A72EF940C3FBA910AA9AF2916D673D69C4AE4DE92A237F271E84921C309B59B92E795BD26C5C015EC5176155DDAE8FA17D7BEFCEE3A23E0201669CC55A6F270CF0D03FFC09BBE4B47D318B6926808EBB49EC8B57A849896E76648D51117E8F518088D66B69D88E09D298186C10B5678EB8AE43E9C0A794C63CA9D597C4B74C959E9C1E8E0F46698CD64CFF3C0FC6174CFC51095E142DED9F16E5B2D3656555D2D42832280164E0C10C5817AE47ABACEE7C3BFD198A21BDD1C420F2EF0776E5EEFA46E8BCB49388FA6B937FD1FEB2BF09D5B9494A534F19BDE4E7BB8A5E4C558C2A166006B481A7C5865069A3DEA2B880AA503B5C020F045A4D9C3E5C590E4AD5375E74B732695A11164B5A57AA665922431498A9218CEB9ECD92700E92BD11E0A8140938C4FB9543FA5DE8EDADD1EDBDAAD11A6AEFF2EA409638B2C7AD546EFE390729982304F35D7F889C0CCC81D67F5A1D6201BC4BE8D1AD2D3CB85815CB9669B56F845148DA0DD2D6B5D7C4986DD3F10BDC78EAD8B4A88B7AE1FE11C634355F60A43A55C88B37954CDA71F4744C8E2B4D7F8D4A2BF60EF0C44CDC7F7059AC48A94B10279921709827A3E1E7A46DD857616E6B737CDFAB71CBD47639245E392DC116614CA3F099B8F2092AD667DAC43B8501DEA9876E5E0B98B41733DA63A2517A49C169A95E583F18F2E1DAEB4425E307509CC6B0B376827F0BAAFC2FB2ABD4E4151A8DBDCB8C22C78F5DFEF0DD1743B047E58537866795D67E35358020CF75F0D2B80287D62AECD6D34D18494D01B4412B1CFF279CA69C18A263E7B862F514A7A64BF192586ECD460D22DD2280373A66ED987635761C3CC34A5BF6A370F9F8B16F98808767A2D9A1517544D869E674980758B15BA7844027D3593432101FBC51FA4709F4D041BE9FF31DB9B7430F1D7F8E06C22C4BF3F8798D50C92641CDBF0B2C88E88666029FC985FD4E9FFDCD779C7F7600D02AE8D9E3CE6FF76F0B449C41BDB785BBAC9CF58ED7ED1525D7C7E885C0D46ADD0F7CC3B14394235B9176B69A222567E6533870EA540F4DED9A1D78F2CB89E6C1DEBE67249ED8F31C87499E24DAB0434FB9B40EA695499C76A1618A37B1AAA5309A914B6574209A61DE0633F086EE4F2455299C70B981532A23DC453939D223BA3A25122AD498795624C727E973C052E69AC40AD465DF55ADBB20FEEE76BF2906EFA7B0D9D5EAE860FE02500E2E0F4A21CABCF963D91262EAFEE814BDF9775874D656F8BDE11DA29327E3E7C7C95395D0DDF766CF34005CE86592F6787D1044E5CA1962C4DF2719308B2D6335FAC77DF46092CD3D5D228E381BD7E5FB4D2EC18B19E18E4748F662AB34C3F2C33877BF4A8D43A63F9B5DC75861AABB42D34EF37EF19CADBA110A3807D1699B247BEFE3D61AB84941ACB227C79CA05180FD3415D0E76EB31B4DD903D78553F2C22563F9B22BB876E81EDAECA4B8FB9415E2BD5AC32CC08775A20E8F90A1681C9957DFC330B6343E58F841906EE3562ADD6AA53FA1EC4AA2E894AFE769116E29AF49D0FBE2D8FEBA215E470ECEA81B258977A0FFCB17666953C29B2F70559DA00610398A08E0A17D69705707569D6484C4203C06B17439E9D4D9DB8456682A79659DAB332DDF45C67E527304013A422E46F2989BCF033DB143676A4EA720D0DD75584298CBAA765CBB0B09EF267D503F2782A427459FD2A83676DEA43C01D288429A82527A69B1EB19DD3BA1AB7428220BA74F79A81377F7ABBC027D96903AF6ADB4644E9F5CE676FC4D3ABD977D6438F4743476F77F3DA6E822AE61E0AD38549BD21E0FAC1C963F1D47F9E6BA6019591DE22BCEE5D5C9CBC4106A369C04BDF633F41EB1D6821B1F43194CC14B02B753584A659EA46C49B983F592C83BD959690845E872B471A38381CF3B2E8F4DC157D9A60FF56EC63B1C66D2227A069CEE7E48DB0E0D5991F96740D364DF89B08BA67098652958A14516534103ADD9E457E6AFC4DE1AF332EF3ECF6897B3DC8E5D6980FC5E5D829D4326F6023F48CFC9D0D787416EE61A0BA3CFF5E7C69BC83B18928AD277AABBDE271EABF8269701E526960460EEF521E83CF7A61A3CAABBEE1F1C99402EF55FD438753790CF56034AEA3292828AE858B2D3B9C8D77FF4545FAE7B4F2AE1EB17B8198F4846A8F4A105CE250F900969696E477B2C46AE786481BCDF85715BD270F9C29BECF4579F2DFFFF7750E375113E33ECABFC52E4DA5405849FE5D5F4A17C1F0984A1479D561943CD1120037EE821A2B57A12D7F1797E64E38A4B71E2FB10207ACECB96B3F3ADFF82EDCB633E388FCF11C8D105C1F6EDD41B553B4B559C3199745F3B0EB7326B867FD4CEDF4E9ABA1FD6A10E1494847FB5DC83C91F7A2DD351CD1AFDF95865701FDC658A41ACCA58E574B67929EEFEB371589374285148EB09157AA9A67F2FD54FCAFC1248F6D84951AB1A676637E9CB76C17C282DB53B1BEFAD8019F51B0400DC1CB012B97575ED81C129636C38998A2E6FC5AB7F0BF1FFDDB588BDE4590A7A0F879FFFC1183A3C6CFB341FB518D0786A6473FF9614877B1B722AF4B2E1E9B5E0DE7C3DB004EFA16F5CBF07870D7208A93A9FCE0EEB598CC54F04B1BAAA992C02BB2D27217AB20A3381EBEFA04CCB1F23E59E4B0DEC700E069DB7620E22235A4C5F54522D96ED4785ADBA7FF95F2A7DB212D3DD05E58C560E5ABD0EC238B7ED01E54ECACA7D32F7C2A3309A437E68C3AC7A9BC51025409A2A1ED05F8DB0EBB647FEFE6222D6F74DD8E4034580B675DEBA4BBFADEFFEECFF4771A0C1CB0ADCC6E9B050B85D230F6B288AC3FC24880CCBDF9C6A6976D46797B75B8532411FD89BE027CD8C81547B24B535825695A35BCDA4E2E0A3A6BCEDB73DD10DD847C4A0AAE059A07F56B0ADC0401026648BA469C534CDF6E2CAB8F581A7233D2F15BB35DC990EFBFE688F9B9AC5AA5C9B3E95DA7B0122947DA03AB9DB58090FF14B736B9CAC65F966206AE7C84B971D83944D8AB61589A28058E14193751B685058E632E32EF1E8C94BF005A3A2EC5EE2CE2FF6C05A67D87E56998E952E4557250E8AB5A979ECB28B0EE41DEE07F919E67670D9CC4077DB0D90ACCFE17CF6AE69DE0C9DBCD3D552A7FB37383574692A267B0A8BDCAF3532AB47887FCC94AEC3461A9257322095F1024C880273222295107864903F3DC8FB353FBE51C4D89F30FEAA5A570979A38B0B4AC9A4AB6B7169984C576BC4AD6DA1719CD0D5ABA03BCBF1336DE48CBBE167E4293DADDE3997061469F200A391646C8FE712EBE087B448F7A7DE437186D38A4CFBFC2919FC888487B15C60E93373D076DF6A60452E62E05256AA66BD1FB771CADB331661DB4BFA47581A4367069FA20E9C6229F79D6680125D0464F7CFDCA1F5C46688D5816CD90862FDABAE753E56BAA1369AC1AD3530630998CEB4545C4404C8B9A65D5A43443624D62DCEC989AA2CB8B85414E06AAE6BC4E219C5A3FDDF8FCC75381F6A0F73F54A7A2B5BA0F546235E71B233EC107900D8116CCD398FB14F32CEC310AC089D6BEC40255A6A877C30B05355544D115E8F85E428087A5F3670D596E31D25F676B3C6FF444AA0FFE5011AE62D6FFF86E615EBE80622BB646A318BC65950889616DEC254DB332649788C07E46CE590C2362EE66BB33BD43807A1336B94198BECE586CBBE3136B5CC809F24DB5BC3069E9C1FDFE53C6D1DE29DF48A9000A7E89D6862A773832DE2151423D9D11D722D923233137DB6F34F8DFA4EEC134BC9EF5A70424D895638D1B09D95D98CFA17308908D65AF00259DFB5ECFEAC55DD7FAAEEAFD4E94EFB36698D2315D795A93B8BA6A3CA93F6B79F2E599149BFBFC6F5C5742A83C886BDD4539BCC128F30B370FFABBE724AA3F3D571785AA6234FD2359FB3468A06A8E74918EE6E87CB29178900B49891F565A80BFF302BAFD0D5C2C123973BA7B9B425973CB3D7F2AFF3059D272A7CE611F5CDDB5AFF3E2B4024FDF0E01D7AD1C63FB47D9BA986C341030B3E5C6CD3CDC6A3DF9D6901E76D31C141C37619F5BB316209FAF8428AF19236DD426D70EC81E77309D5D9AC33CF3AACC0259A19F91E4579AE49EEBA41CF79B9499CD1211AF1E6DCDC70383A35E0ABF7B53A1203AADCD3AE638862D35EC4E441100E8CDEC7F0E6D22845F6CDCDA801111C4C7F261189C7D67B981101C40F21D33D05E336F1C7443560238C72B34E47758927E37F972247F4457EA60B2546F6B5B7A91B151E8B3800CC1748587E0D5421A43648BBC5D87C591B01C229C8104CA87C0B7F0770ECABD1E2A858147B62F607A86E1C71EF73C036B18C01CA5C1BA8242BC4BB7414FC90C0A8372F860F2EE51DCC1E457135776C377F940400AC5309112E6742617FC226EDDF51E95CAB40CAB58CAE1E662DD78C6E253B373BE970129193DAC7DAE372CBEA847248C2E69273B7CFEE70BEE59DECF64126D44BACAB5F2813CFEE1EF89AA3FD6D030319CDCE94FA86E4E64998266082F8BF74877038ED888C16907A8DF99BB53809E54520E4B5B6AD44849A33EC3FA44A7B179350DB07524823FE8384413F0A7E1936D8CAAAFE1052C462778B36AB8A9A14BCCC0319CF6EE2AFF01EF5077A10BC0FD0DF76D9B806481BAD1F49EA013942F38BFE52FB194EF8ACB283B1462BFFE4AC618D6FEE7E25130EC71D68C81A9532A16520075EBC1E9C3FCDF5FFCC150F3815E8647F34DAA814935D0E1AB68EC6A1B14FC7566415CC11E0C14A9693B8711DE2D3F78EBC468269BC851D2ACDFF5E8A6388B73E33F20C0C7621C6B644649AB088DC191418292A698EFA4871224232A7788EFA2D69F9F9FBE80FB8E6B0106405F6406D00A6D6185EB521372CEDF51C2E0876C7A86A90F1F5DCC0EB3187DF8BC62736663F713A1D403665BD5AEFD6BCD3413FC63CD68B3C5C7FDE3AC4164FC3737C2703AAC85E6ECEB29E34A6ED70D4178402814B5207ED2AE12E9DE009D0DE6A0BABCBC4ED41D5C28B1943C4B61D8B1DBF4395F5BACE1E47ECF0EB9E21F9E7F663EAC3788E935A1AF73B19714ED91BCCCDBEDAF1C74155CF235A58485BCDFEA58A929ED1E959DC99345C36109E42A14438466B1F9E728801BCADD16B2D8F762E4BB8B3F01E531339DE79634F43117DF5C585D7D2FB4A5D3E82BC25FD92BB1298AC79211B3866CA1019666AFCB10BBEE1AB63263F2823A86DD3EC57E8632C9F4975155A01F22859EBC400F5A3B8302ADAA5892A320487AD077B144392528F100F0A222DDCE5636AD5962AC6D62A2382167EA977743CAA6BA2F140655DFDEF168BD620C73A47A8831DFD66DC6F2A9F47E0724081681BE62FD15C74846980683B729AF1757203F457FF12925B6B7BC81775A9E5C53862B07D4B93CB2E9FA896AF58D258384115F1C63779E4189832C29C8B142DFF30C00DCAD2328A63C92CD1E42B2A8D2E18542BA3A81686452C83AFD5F6955A708CC1DAE500718C6DB89ADCBEBF119C4707B931E685BAC00AA60E3B5F9F42FDA6EA90F5C77295E84A3AB05D69212C5368E24F18F43B450181884D7AE8BBC61E1603FDEB13797F9620AD6C2B863C495821F7F726BD5801A3D5A36F4609B595B7653799B3794E4A60090D71F5DE1AA5F0CF562F7E722C55AFB676395ED988A491A34B462B2D18AF517569531308B8190F0148CFAD463802AC62C6CB289FC0C95C207AADF82AA7399E0476B774D9B876829ED91EA3E5C40B504370D266B7B3C72DDE2CCB7F3AB8E820ECB5715289451D352D83DB67EEA889EBF9E8B012C8265376C841BAF6EDA4067A400D4C6FB00539F3839A8D0B29906F9923B9244132282E38242257C339A0D0BA8F05F75D41ADA51E29E33BF65F78981F04F397BD5F9580376A8D1C552363D6BE90EC83C2AF748CBB7783D6B26098C641777A260F5F60A712C7A7D1CE681CA1FF969B8F25B90F9A2B03F71E06A848DF3C5C8571C5626D5A1F123DD14A9F90B3958A7EFB3FD522C7E83F897CBA80B95099F1705E1CB22C7E91DB644880F7DAB480B29FC0F8E1D0ADBAA123F1E1FE36835ABEC924531065354B77DC1082DD690B316A7BF104140F6316C46E81E777F56EECE625EA030C1FFBA3A4D40745E77129230A69D76C226A80A8CD31720B08D9207F22F8F3068C169B41E7136F94B73047377A8AC0987490E4DA2B7619A760E3B61369BF762FA9A3ADCB014CFD0644AB1FE6D8D3EFBFEC893E98289DA93AE19D8DE41AB33FD717200B6949AD21B3290C77D5B1FA44EEC7D0C6A9978D50B40DF77823FF2613BC80D0E11DC2B790B332D5267851B6315AC08D0A2D6FC0A8F93DCD20DA6054894F84C88CE254057CD2FE36693F868D812DD1D978897597840CB336223F8A8EEA9C15AC05D3E40333391680C4F4CD5C2F600CAA684BF09EFC8A9B71E6883E9353C22B379BB6ED8ED83A2468287121207D9ABF61D2DD5116D3B163F262BD3D57A23EF2E6154BF6EEC1DF88B961C4505F7CFD2E23E0E0D245A9418292A5AE6E60F3852D78D19E1EACBE9F42A522FA57554308A1D01E31DDCFB7C38534F7B48E0384AAB4B81A93681ECE4C55BEB089092E757A4633B2F30BA83E470B3ABDEDF9135DF22E2B29CCD0893C54C329DA1B16C2FE4221F1C7EBF6B3D6DE84EA1DA57392762FD9C64C0771966B0E1FA9A6E286C23128DF317F704237B97A339A623C985BFD6A0C60DE48EBDD73A0610A22B02D0978E626B50171FC8390B80F37E5E536CC184259D4ECFFA958DEE1A27CF3D2EFC9B218809909B19D573EF86087A1C9BE161C54DD1279E022F98030669FC93A7BF03FB101A3FB5321F654D2B40EF8298844806BB66EC32F7AB3BC7BED2AA7F22AF20759B12A0E3F82D3C3A141F393DE746D5A0D91F32D8249F0DB0FE37D27E49795C648EC6D96E352115FE4F10D1F56C39FF9140E3E87F13AF3C6480D6150E1B7B4AE614A577D6E81694C19E468761039E970335FDE9945F6119F6ADC184C9F2A434C681D593F34D258F2A8847E02DA5EA2605A007B25031DCCBA8A8C50C77411D197E742D4B3994471AE84E2B612B09B2BBAA38C5E71C22A8E3DD1F284A681DDD45E962F9D061846EDB9713D4F925A9DAC0E32D2A4496F68C68448EDFA87FDE3ECD47411AF5DA95D8C48D5CED988AFD72BCB7A81896EB1496F468D4664A58EC3874BC6FF6A85692790BB405592DFAF53CBAC93884A842EB2D3DE9619843919CD9D68AD89DC7A84BE54C406B8208428066011807D722C2B34D4A279EE43BDEB967360D9BAE50F654B2A06B576B803544DCDDAD670CF8D2D7723929842C6AFC4093BBFBB75D1F5E03682500AA0A34FC66CE4409D08C726552ED5ABB0C646E89B35A659C67F6F398D6BE39D9725BB0322D458DE2A62E46B62013F2BAE5E60C3D41975C6A4C6231F4B0EA2827329279459840911891B0111FB4B1FE99FBB482FED56C7BFBA15882CE5E2FA2C73E0B682EADEE6F68E4E1A9CD92FDC2CF30902453A16622AAB1273407B985FA4B7DB40D87812F2A10183464F8173D22D5603C44586B107B4B82E94DD80E87AD49E9C0FAB5C3330B74E89F742CA1A5940F0F329F56DFD40C6869D0BA8CA412AF9C5116ADBB3C22080F93142C7778D52C4D75F1EABE13FE50877C26D7DB429E991506ECF1DDF30A00F9E0B355306B889F41BBFD1B4D27B67952E4A0B53D1BF8B2E84497F00826D84A913F02649D5145383163F3C3F586EDAD06F518B64D9B300C4540A67593B9F3358FF2A22AC4BD7E7B9AEE507D184E039ECA3BBA0B5C584D3359D7121BCCE01691E11C120925A7D8B100751E8ADE99D3676C7355BA4BE451920BC7D2AD6E8EF0A9693F16FBB570122FE5F5FFBDFA490B3C84809ACD898FC0F807C77937C7CEB6F03308D3E9C657F80730EF3A1CEC6959850FAA6C158F23B23D28ED53BD77531F1012DC1753CE1AD6E0A629E14BCCE9D56B74E09AD6EEC9DC4A5C92049D48AE21222AF706B1C4DE65AA814AEF5B7E1EDF2D8A9C5B98853A17199DDC3233C5583B95756F5A9C175FF7D0891010F5D36A268ED5C9F58433A69185931E11BCBEEECAA240C2C5A4ADB4E770109F3F16CFAA37AF98E1228FFA7C584B13F850FED0187FB836E0A01B19CF700849EFF09BE1A57DE41CE1D52EA6F182E0DDDF741DBD2150113B10CC3D9E44917E0FD9717D6D361A88060E202039AAD8F31E4E6FBB4D7FD1BB5D6DC20C3D83F23D120EC98FF4912F3D9AB18D8EECBD7EFD1CF9B19081B38CD959660E8C63A539939D0CEDA897F5ECDFDEE16ECA492B216BEA35A167178F4A0FB76175D160FE2EF97BD6BA0E296922CE60D91FCBB3343ADF477F8A92AEB56A471B0711CAC45DA8EEBD21FE83FA68EB74C8502C81C65506C92C4A3F19ECDC2B7A5AB47704DDFB2E8D5AE620CA0D67197699677EDA3FC4FB821BFFB5F2DB03D4DDEC0BEB13EF84EC372A5C56C1E712C8D23D1A2DB1BA077645C85689CA2258E9B1B807DCC6394680B72938E1B61AC3E8A5B9E84BB4B58CE5C8C2246A604C05701C026185CFB872BA78CEE33EAFD0486A22C6D5CF9264EC134DD79548F3CF5FAA67D8B1FE74F6AF7B897AB0A0D8CABD5E1B2829CFE66D58CE00E68C6F23FC35397FBBF96D2E63825C96BC3CEB22FCF9CA46C93538F8DF566145D06207533627B665E39DD284F4275051229F3CCE9E9E62EDDFA55BB2AB1D1D8E8E6145B3E38F35F90B89C15FE799EC14F7E415FCE4EFA72615EAD26C10C1FFA4FDBA2EE04C4845489C21BE45C478D8B2116C84AAC21B48BD4181FC28C7C21AC9CF95D8B04C0D817C8ED8083D9CF8B81213AA2E3B8BBF4AD66A7AFDCDC4C420945F5B3E8C8AEC5C4F98005A0CE1B3283F5FC0FCF8567A150E12639CA85D298CE8E4F9E0C53817D3009284A5A0BD5D3A07234AF751AD059E301076946DECFED43DB1176A2BBA4B8A571299FDE4AA3574B6C189A721674E004F259B00B26EF5AA90794FD622040B80CA6C5E9FBD44B3DB21290353878F4D8D87496E374B05E6A5B25742A885569DBA2501367EF4C549BD5CE6169914A7F1D311D52CCFBE2091F0DB436506F210C137C2180B89626F52B4192C67ED06C1F9175E44B9468E6FC2208A98DE577962D9B4C31D5B0DCF4017DB1BBB2F80512C89B9AADE69DBD584452D25CAC97A4A7E6F48BCB909907B93F5B8108EDAD38CF7FB541328C5E8AB867DDCADD6A1B5083869E68EBC785C80ACD260C715624360F2F3D78FC1B2A464FE0525059A3D5E04BCCD72D23BC680CF7B25C5CD2AD6A0BB8366DB24B671D5BB3C12554D37C7A662AF9B9DB61DC6C7DE288DF1976DE08743426CDD30AFFDA05A8390A8F3A4A94D7CCD33BDB229E32850A77B2256CC595BE515F9E6854463966D4DB7A946276F594AD4BDF0B9C59D4D38E211A4465AEE023CE6C062FDF4123ACDED834F672C1A724BC17D44DE9632A588E7EAA77F3183E09D2ED55099BB1AC8198C96EC7B1635139980D5CA4B8B3102375A2E08BC3BC754D9FE659C3FA403218BC8C00FA87A0FA6F096E336865DDF02BB05049CDC9680E99C4F567ACD25AA7CC76C182A8DFC174BF6FAAF4D2553A4207922C1EA10CA8DA3E35DFBBFB5F6919FD4088A3A8E48358CEF25576A3A6447980F1C716EB58E755196A672C378F6615E54E9A16CEBA33CEA918768961C244A561164B61754F679856575DDCB32C70447BB738E84CA590CB523C6553F13EAC77461A58A7D4E1CC1E36E7BC5E85860B0E6B67C70D398AC0BABE1F42426D9E7F12B5E362BF3BDBAC42C572730C5F4EEA957FD3F17050625BA9D9938380249290AAF31BAC"""), + TestUtils.hexDecode(""" +7C6B47263ADC85F69B12955F66743C08E52EA89E18EEF82D6ADFCF8CC1B1A13D386305F13956EF20C02C65C64BA0AE526CE9EAFFDCD44DBA07600C4563EDE57CC7BE708C057BB3716AE33D09FAEEBA0E9B71A8E24D03DB2ED26C85754A25856F054410E286BD70A176095540559340F1CCABD50EC5E89B36F97783D35EEF716A910E6ED934332083F0B49B9B7995489BAD905E86D54576447BA6254C382732320D1ADEC8B75C85EFD00217DBE6F386C0C02CE4822AD52B72AAD0FD00F74BDFE62F2182FA1AEAD069074255883B08434E20886923086D3083864DD22EA3469D56A8A7F4384DCBB04B819274399346544F08A14E5E5E7DE0788854702775DCD8C6A32CCC85C1CFD78D5D27BC651FEE0E3EF0082DAD5ED0399F33C179AC987A2B933268A07BECB62CFBF4425609161E1AF5E706CED78857F3D1561A4615A058635C6D4F73E60ADC5E5567528A63B60D26AD8C8607BF09F4C8C96A6183AFA07C63CC19C25EF43AF3A21FF390185B5EE30904988DDD853F7F3DD4E09F145385FE52358CE2C69E3B14F7A2872AB7455EDC06A5C448298813D7E0A2605EA911A03D6670D08631BA4E11EC4CF9959C38071A959DF07610C3DE964D82FA9C5C37821E4A3FF7E0EA642370DCC4EDA58F2CF264A8A87E21260B4C0B84C5D5CB5633AB0AF0A40F9E4BB3D5A05DCC5FEE2D6C1BE45EF44099F740D35E5A515C6CA1D578E1A0C57BCCCADCEF80FA42089C055F13FFA1CFA8163B0C338244EAD2F473831640ECBFC4F7E244BA5A00FB366C87646A8453F44BE68BF5EB96DEC1B1428AE0C224F82A0CE6FCBD5225F1C0EDB502344066B191B81069ECF87088A81F8CC6710976C65C9C12CD4FDC0964B77A7D79A055A907AAD424F6D0B951086C3583963D823A2F2244741277B15171AEA99A691AC76EAD489F25FA84A1EE6DBFEB3E1827E828B8A04A87B8174F5AD43D0B59D39E88321D301B6506724042FC1229F60BC0D3CB2E923AD72D4F6F1B416D6E83106B042055C9F92C79C97FEDF1DDEE892C080521FA69AB735F91F369595F5DB09F03CC917F4AC29EC03E893D3EF6D536923B9DDA78C04489F020C4EA18A144E2BBE1B5686A1D8C8864AFCDC681632BCA685F5F391F07192F51FC9A18F0A05ACB47F818A12F3BF654A892D396D3BC54BCB09D877FD0D98ABC76BBB3F184BCC3BB294D7BF6F548720C6B8BDDE604476A876E7789D6584B2BB9EFF13FE32113250B6B15EED1C6BD48F54D2353E15766CF4AD88921E66BB2B17AFD3D8C0CC18A2DA69443F3F4CA9109BDACAB0CDC704B835F6992B96D088BB3C7D86F072675EA1C259A4A11DB96B9557F60461F33C06264E3EF6A405BE4640710A36835AD44CDA5BE55F0720313A5BD39CAD155F33261076C1211930D23D2202E8DA8130505E1B18032A743F293111DB0ABEE58CBE2D5FF413CEBCFAA1BC10EEF60477B2ABE50D598247D00917F0FD2C9122DD7EED52403364B14640EBD6525DBEF7AF9EF7051D85C7F80BFF2CDBCB61E0708AF53B2FBA4B6D5D3751D07115E693D68F4C6A0E41270EFCE43D9A888E83A6006703BED0622F5CADB57F6DE5F3E5DB74AF934CDC70B31ECA0751540F255EE3D29DA18069330CCAC2E49BD2E85BAD2B43CD6F39F6601FCCB84A5F47B94BFCBED53536FC7DB0666E0D50A9A567D78C2F6FCA01D94923A6373743C00BE3FA1A1A62C24CEDB2440AD7645475DD6D7D7D616D30EE0E35E5912ED4055A895848094895329F07AE1E201568061E27ECCCBD78D564C38F1681E7AEBE51C02F563DCF77FDC4F32819FEDA21F0812067FAF1FDBA95ADAC178B92A4762551C669057A483453B49209A20A52DCB6F5266E1A8012580B65707BE63DD5619413B56644BA6B5036C68E2E66245BFF8D6A84D55B37A497EB16D01724BF3790931AC164DEA3CE1952912A938924F5D4DFCD5FE398E0727A79C0EA11DA7CF1DD406AF37D91638ED36D8C03404359BA719889C8DAD452A98AF1538CF1316CE669AB2468BA3CBDFB76470525214D177DD0BFFDDCAB4C82E2B1D1764CE850209E37EA76E8CAA553BFC42CE5D2DD483A34502E73B0F04F497B8AF26A188FB68902A8B2F5DD8387D71350C77E7FA50F541E45EF0F68D623298A88DCE27547F83150C2E679A5F8A3D28EF96C229253BBD5B60F2BD7845E354B3D7329179C1DF91626E7549FFECEE116AB6A7EFB4C8B49424B68BE363AAA794BCC68E751B3A3F203E5A9495B440649F9E3DE6A8AE4817CFB738875FFA75CEEB6ECFEC6EB555B65493234EFC90C5203C6312B7EC954B444D706F4A572342059B765DF362FD07C3B48150476D5DC08D3409A79BEE44634D0AA92C6B70EE7DAFCB38252D91EEC63164EF7555786437A7F8A282E56BCC13511D71142FFFE35E6F3219555766A0A08207B2DA4C894CF35206485C2B0EE6B28662A64A37C5C1A9D4C0B366CC6D99E92ADA28792CC10E5AF605FBFC638C0A657054A0E8760118307EDCC7384C9DF458C3C64150925B22EC3E1A1720BFC967ECB4EC5BFBC314852CC17A2269479F1AACD60DFCB1E415EB40136B7A6A027C782FE7D7F7C6D19507D8C2D0F6C250106DC0A72E4448D0585225F9E735A8F126FDEB81192DA13BD806DE1482AD570BF016DAE36928EE49D735F91F059EDD2750D785BB14A44019916BB8BBA2B4F818637BA312D54AC37257FC9E2853C086E95EEC0066782713C98C82F582C0431C531FEAB552E1C1AF0B82D6034F04C85171FBE7BC0818E8BE09C5033DB552FDDBBDF5DA0A048F920B7FA61B7D5B38D1C85F3CDF837D90F64D31FC5EE79209C45A4670849C70C82BA98A7EE2030DDFA50E6952BC73C71A8CC49BDFCB0F10C1304B291221D56895D47C9FFC80FA25DCD12B40C96EE3177E9B6B78A2D9F59D2C2481143D3C70605830E3634931A3027A8FA3FF22EAFDEBBEE16AEDE4D8712EACFB58EADE2E5DB35CF01BE532C2631A1EABF4B5F373E230BC8765737D1F1DD529F10D2FBA8882E62C74937DDF93CF6B769F84872F779D974AC8ED13A55A076790C032D8367AAC64C944426D661A87BB24A5E4861D0EE60D07A600D4D15404EE920573F2F5A3AF5D31209548624B52D1001D2477097A25A0D480C1A1A04E7E1FAF0754E4DF5EDBC0E5BFBF152F23B54B90C55A8900F4091BC9C7CEAA1C7200C017D5F99DFD5FF5D7DC33168C4BB834AF29F3F651C9657D3E1653A7DB02D7E61BC48A13EC743F3107240F53FEF424B864577BC4E6D78E8634AF636333063B366F0AF833949B0770B3E545C563E3B3354D87993940A47128185D74EBE823EE752375264143555E6D7F8897A7C2CFDAE2013641586A91AAB6BAC1D2F3FE292A4C51595B6A7985999CC0E0ECFE0B181E2E3046477D8B9AA5A6D6000000000000000000000000000000000000000000000000000E1B2A37""") + ), + + new SigGenTestCase( + TestUtils.hexDecode(""" +0672A2BA2653D9EFAADFB90DFBAC95F77BE8540FFAA866671AF76F7CE585A21A5EE3BC98E969B2DF5F910F15A109DC09B91579F8761F4145771C80666362EAFE59CE336D877D8C724953C5738F65F3E1C551C1FFD9DC7E627DBE0BCA5174F200E8CDCBB1D8B0F84569DDB324562C66B5692C9069EFF52A7E4ACA9E293B26C1BAC3162A43808DDC4248A286401248649AB208E020462106815128900A984C94988C4CA82090926888B44D4924495A426E83B6050038500BA38D00B96902436E9BA484D1B88CD8A42D043208CB4089E12032613210D144491148258B08694BB00CDB280003C70C98883041A40CC20612982402DA06498C362C822209643089A34624129690818270A3108554206DC2B66001426A212222198204D1248660A065D0482214372662384C809808248040C1A44C1A4692133430C88808DAA650D812920230518B244CE302300A114CC4246A4CC44523B044D0B80C633800CB062EA4304E103051CA084D1BA349DB4828D1464D9BC484D0042CC9B60103A64443941080C66999100181142403050293264C9B028E53180D8A16411BC0290C47259C482553A405538401CC8868012882E1980C42440208A32008836D042292882800608408040289820812D0B609D992248C022C0C482A13920D1400244B380081188C0A9328220808E1460682386120196059441151A80D8C12321A07881144116338255C340050A064C0266DA232308CC684A224710CC72D5B323111246D944011C2B87108054C48184E49A6910B451014816CA0480A222588E2203050A80551366E234820242932D2C40C9008081A9750221345A1304D14A088CB06111104095B928891A001C48848E4264C0BA2499B022523160100924DA006908AA481A312481C9281121842040152892846D0840513374419B9911B010D19912C42386559466D802428E3068A24952411C38D0A1491498400C082655C448C23476889308253300224186E08414202248210846594288C1BC1210A246693A8011C041204308C9C486A0C47460AB50D8B288C58162100354E4C024E14B05112C80D80C40CD1484A1A36720B372419440962048D48424E91028103B405134082184520DB4288E338019B460299B860D8106D13240AD0B08818996503022A00372012079082B04559A485D0266290822D0B324E218291212006C90270803681544092D034640903011A90510CA2085120229BA009D8120452028820315184804C5492000403810A4809FB030EB7ADE0094AF6D6A78EF4A30D8A22BD35A79B413822D86A8ABF9BBC04D838EC1F2150FD86A245498E76DF32DE661DE605C76757DA5FFDA3082DA464400EFB1393D92A3A53270E0F144D255B5825B05BC72C287634A16EDAB6AB4422CE3AB84E45DB798151B1697FBB7CBBF0FA370D1F57D887E5026226CDCFABB2D502F7A82E983B03BA41D643DA93BFA387620265DFA80DF45E82C74C14963392199609CC59065A7D4C26646A87C04C31B34B2A70E029C24EF993B30EB53EDECBB4FBD6FAD614C581B3C04A15AC777006B0293183CA9DCD587960E736F780B1BE219928BEAB8EF5DE4B8A03449F33A65B2B08DB13F4B7DA0B756153A322282AD8F8D8F64EBCC6D322D519D6CF1A8F684CE469B9B9269759944CD1A863E236C856441F6C2198B73999AF6EF8140C9D23095847D3DB2518113BA8C96D6871C4BEA7067C0BF6947FE69B3FE12081BF58DE113C2B487759511CCE1FA48D814FAB7F0AB1B1323827A8DA71454578F1046CFD395E3683C332DAA81867B112E8865B6E2405D5AD2E57E8EDD695C3DEC48A52BB39E590ECC8F32B5F80382F1D444CBAC5FC7378C4D8EDB275CAE3DEB4C298EF20E6E4E25DFD2996769361ECB2C86AC0D28287685219F60213722CD172A2A2ADE055B515955E2D982FFBC13C2EB17CBC96371EB69C35BFBDA0DED49E6DD63021F38BA0C7E30A655401B6B8A9796A675FBD5044E64F6289C69248AFBFA217B68A5499E605E1487A07CCD60EC743F053731CAB8A2EA92C4BCEB56560FE3F55B21FDD604E6AED8F2511F0562B6F1AEB40B70C116BCD8DB842E26EA0B325246F4B6580559F26D6817D6BB4FBAFE4B144B26DFBC52D45C3DE758999834A642E871AF54DA2C86D7D4E3DC6BA54F5ACCC8B6D74EF7AE1BBD0C82D76A8E837F47BD53B8DA621FFD51A05F17FA88CC3D7143DD4B36F0674548FB886ED228BCC53B33998C3094258ADC3E05E24C5A8BEEBC588ECF45178D246D20757C287FF45149371931C75A7C59955F5BD1834B6738DA57D4FD28CBB11ADBCC6A11692021D5AEC5D36D6A992E7321C9FEBEB0A8544ABD8DB5CDBFB40889219F893FB4F543C22CA29ACA96B8E4C48E3FDDD763D5AF7C4A69AE763926F6F687130CCF2A2EE5EA746C3F1AC9772306A01E378845F568D3D885D4C267708B2C352C45905C7523A3C390B89F3E034D4EDAD9327785975D7286B755CCC9D9D4874B5A9DBDF90544421D7C6B2CD2876C4301FA891A2836E1C078EB7E4C31837DE4B8A38D270024F121DA31F48021CA533ED61FAB4B5C08CF3CE5DD5300722CBC6D1A11D068C604967D525394E88A0920EBC56AEF47FF4807DC5245345CC7CC13F5BD929EDDC183D10F83E5AF32DB1F7D87B2B27110B4A6D0B3AB5252079D4FA1E5FB3D667189ACC70193C1CFD4D7E3FA9BC93CBB834DD3C8854EEEF5FB471D73B3A35689C8E04A1367FD191DCEA35A661D0AF567DDDEECFA8AC62C34DDEF14BF848B35C9D97BE3978B055CF895477902B40CC35F3A7DEE7900F5717073486E8C995192619F7BAEE5EABCA9B314B4D0F3F602CDEDC8084CE573A6C7BB59E4E0048EE367D7FC40419199E0B104DEB93B9E36BB510B8E40A00AB9AECE27D5FEBCAC6134A303CA9B07F332DB85A8A03A56995876A74699A8170EB695F77395341355AA8AECFD30443824F7BA6A07034AC1638F4C6B602C48A0F11EFCF4CF765F886DDF128D16518F2E7EF3B4E6BF799D0FA82C152832FEFE7BDA434EBBD1C81128ADD704A749D46B8D5A4BECCEB7AD6E4959F8F4F191002A43FA609299667292332BED76228613EB5AA536F15BF7C2DBD73A002B133E7E780DE1F0A3F49FFA1E32DEC1DC496A0080CE85130FF9622882A61CB392D3233AB3AE81458517ED1A65AE45C6577308FC98B31D74B008056B666E70423816151EF5881812AADAF241B299222AB9F6F0C0178196846958E2C1B4536E2110029F1E2D7B8796B049EF697EBECD35E467704AE9248836634194BCB51E4F8474FA7699A1125CCE9FB62F16BF5CE11E422DDE6323CA490086F2F9D41B7659943D455C90BC978726707CBAF0224613828281276672CBA3FD13CF37609CCB8027FB026A8211DF8E13252AFB9DF7F13423BD9477A0518D581326181498DFE98D30248DA71F1DEC92E7453DAB2CAA2DEC15E1F73A249D9A8DB45D503780C94DF2985E339612AE8D9AF07E96E3B54F233636E180867619700CEB0DA7C2362496013D14F904C30594D6DCC3FC5424AAB9A4605B34808E22C697DE85453D4E9E55E0B7C04E5CBBD8F3530676B09ED3A0D5870042940C900514D9361CB3E3C5FDD687FA90F51C0A21A0E27CB420CA68356807DD24F"""), + TestUtils.hexDecode(""" +0C39B65F4C2094AC626652CD33CFE44EDB2667CF722443514CAB443DC398A8EA009277BE397E1C1E7ADCD1B24376AF0F19EA50E56C90D683F8EFDE693F0F8834199544E2DEFE392B0BD46048A83C412A14834C4BCDC180457456BC72AA28F2DB247AEE84A1C49266361DA7EDD54BD9B562889131EAADAE071AE5A671646F49B2C1359382F1A3B2A6B437F87CC99A2A1BC821E1F3DBB311B8FCDF28546A479E2F9970870066A2D6447B6CE4FB65ABE7423910B9039EE3234836F924C8E82E1299335E27B0DD642B812480D6FEFC47B121A710827DE1D18DC12064649224FBC4526AE14317CC8E53BC8E9BD42BA444AD9B8B48C3AC807D7A7675F43E3021BA1DF9AC7A42A9E23D696BBD03FB5C4702B55F95854C41F470CDAD8A255436F910C089F71C2E59A44221D78AB81D4E2B059CC92A3841E1431415DAD4E6EB0315F423DA512661E4CCE098D6678F560A4BA19475296A2A1DEB12AF5900FA3A3C188867E0C268EFBF7AC53455552DF4F36E16D50E23048C7DD4E64341E6DCAA0036EE045B82C42121B0B779B5E7FF032F549536ABFB702B1CE4EAA5E389A077F47B1B55595D4888A4C1D17F4E21706779C9CDE25DD1261C8B4761A40B69E2F22F069A264E79CDFD36F307D117FC737D88F50EC67CD07D8FA269CF265A7E7CAC93E97BC29EF95C88904AB2DB61C8865A6EBB23871576DBABC83920AA015D47E8CE699A9E57E139AB7D233C577B46C9C314D084A1674A152D87D2A3D8A5D9ABCDA22E212B8C9A2BF25D8AD22AA3627E6C12C684AD2BE917F094263982D396364F4DE0BAFAB2DB89997DAF8B7E3AA953C055776FDC29F8AE5C28D4071534A9A2E9090CD3F723D3E381A2ADA6D9463FC49B3C6D2B76803F5C21D8DDCE965D2C472389D2BEFF448F2D81EDEF1C851A863AF66B64417BCC2CBBC70C18875055D171BE32C06081362FFF7DE8F8A23B076839602E2368CEEB79E4EA53F42F440D167A902A23ED53E6691AD3332DF5B0160EBC3B5C9567CF619BE2201447EA500332ABDEA9B849C3A395F596F2C96ACD9AF8313E453277B9F4234874E791E9DCFF0C9D9DFA8FA9474C026DD34E5CF3AA10CAB1FD23EA5DA0D0A66E520096C6116944F2E5747A974BF55428A3D2475F6276490AADA25220F2F2111892DB9E9C75A5401BADBF69F31B77535044DC50B1E93849F19C0B6C5184F1B14F68960F9F469805F3843198AC68E51619F3D712A34279AEA27BE4357A99C44C456BD2D9319147285680922B98DBC4D6D2860515D1371D2141C7A1E76EEF8586AFC973713EB89C1F09A84AC064BB7644625224FF1F7316B9DD1091CEB151D1A040F7E60F202728F7862589E7F1FA32D39653383F90C67D96D9949967AF234592903CBB968E0D979B92B5C69D09EF4E767741F1F6E361DCFC8D751CB8C3BAAC4CC393D63F71AA1488491CA06CC20B0BF54C5C225B6F0825677C2C40A395E1B7322288A815E59AD2999D61FE09C95828CE18B2997AEDCED56CA8BCDA4343B1E948256AC5EBDA23A8E6D7102A4474CE23567084547F2ADD9DE77483398D81A9A9C7A573D7EDAF99536D31C3588BB649EFE1495CEDED788EBBFD5775842D91DAAA2F9BE08D63B06DB35E72CD0EE5DBF45DF9B0CA682BD944A733D6875A62F8C53A3FA9337F13429FACB288C73220C29285B2D87DF2CB1A54631AF3D0035C1F3B26A5EDD07760A63576A395827F3D5F9B03D9E47A9E1E6A271021942648B8424234080492BBC56C692C769B5DF32A75F7403C88469E54432A37A895E3CAD3AB110089ACF534A0D78C2083CFE149A2D0A5055EF9F4C943CBE1FD393292518CECFC57E4FFC4D07A563A30528A6A3540636A3BE770B7CF03F5004D7C6F8ADA08DEAAED0422AC0C0C8D7515C9F8BF44195D6DC30D9B3036DA007A910BD05DF06B032812CE8393AE2777D717A691D07E860C1EDA60F6DE31F0787097D0D483E3A51CA7997646503738CDBAEBCC21AE4B984B668FB4020C139D9F581EBACB7BE263A33955DD68C9ED9BD2DD6C0A7BD049972B624CB7E787DE7184023F33EC0A1539C4679D6B4677FB971D763BE17D989FDF8C0AC4E0B5A6CB40A49B5464610A110EBEE9A21BB0D6A2F043015EB2C8820DD966A13EFD18D32367834D41E8673E997B2803638A710580CA08DDB4D90E4E8EE584BCA2FB853A122274142130A1ABCDF7DA6C0056689195099CC3382AF6987BA47EE294353674E7295ACC1C070F1D8E4107AA7189F20CC818F1D86F6D646CEE911B304E2FECD5A14CF5F36331AA86E10C319C96E52996D4CC12810AD7C1DD1DBDFDC78DF029BFDE9E8F9B1FC7D9DA99FBB0304A8129EC58A82177EECB7330E715BB3C0B4482923C7B1EC0D1823FF643014C7D08A8F2D9F9090B0F83663AFC5E601E5FBE1DDBE678B9D93C5A23F564B8A4DD29C8D19106747959E72AFA4B16B879E3C6E7F79A212A144F9AAF665253F1360ACF7DF37642270656583E06FAC85389A3AD76E69BC2735B1C3E13B80CCBD298EE25C29F9F5C275AAD83BA0E7C47526253BB3125EBDF5CCD6E1C4F9D9CD4891167BB4E4D2AA644D5D362C6F790E2776BDBAF8D96DC3A543C72ED46E431FABD737B4BF0F4B32E12E0520E60401CCEBBB40180985948045C58B0017C3D8797E433A2E2C64B9679EC7409D59B3992053EEF2ACD7B152E5F564196876EA0A31CB6ED47F2455BBEE6827D96C6B99E46F3DF1FA21F593E842B26E83D843118F6833BC273E12C7224E00E840B0041544893C6C8A06523DEDE2ACE7365693BCC6A8D7DD81B01310CBB8084C5FD3868539F8B5179519CA6745B56C4A5EEE8F2A8A60CBC7453E1E0990D176446D97F34A2D0BD5C5712E2D82601D0B9FC9A3F2420C65E4532DB3810FBE3635B2AC3A84415535FE41208B907EB3E97AD63DDC4FD694127EF1E948801B5CF651119CE17BEAE3396C098A86548B67DDABADCEEDF60F57D2941815778AC14F78C78516F84C5F9749B433DB97A9283A94697419CF94248B6819D9310324977D47A133AE9F1FC141B56D6302817761BBD52B4A1EF808E0AC761426C99E0504ACB6B552F9550D55DE787C12A0409A9F9EE3674617D15E229AAA98BBF4FE49CDC81DA3AD110645132B332B6D2AA38B35320925135BDD225053D6594E78389909E596C63B85DCA8B3F6C3233A31A1F8F3E900E49DF83F649E592979C9CA4BE65E7D6D1F23A7744626972D52B07B7B89CD90238A5E871666F4CA6DAFCBF34FE15983AEA5BB7F9917736F7BA46F342F0C08F56D19AB9569FD23288EBCBEE7B5924B8C86EF77748F3AA9CF2FB884398F83772C9771958B6DD063162A3AAA42E6A3280FEDEEB7A628A07702950975CD135D6338FF959ADDA2296B3E85A024F63D4ED8A5859786E2BC76C2325F37B4D91EE8B64F30E781BF48ADA774C1641CFAD2D63A59E294B5D99C94108154E38B499E3CA2A29AF7CC77A8BB3A3B712376CD081715EA715305C18B51470D5F3A6A82E9189848311511E8B0ABACF856312AE3916FBBCF6664523684D3C7ACE08D2345A3907C9C07183CB3E68C5EC3899A95430E278A72701E2355A4AF606DD8F8750F7F3682FB84290B2BE23BED99CA06D5E54190A5558C927C369C00C512342EFFC41618CA6F8FE6E3A38D1714FC44BF5679C1A49CD8BC8B28499602E277DC8832F738225920709799DE6961E0B4EC12397E7891AA772627F66F494AF719C55D056DCBF10E8E3DDF1B6C1BB2F0B2FA61949D1CA7D4E1F60EF836B086FF8C03A5916A14EB2670AF56264D7390761E6EB6F638D6FACF56B72A48F271ADE4541C8EFC91D15F69E0AA6B97EC0E9C0C3EF169E4A4DB1C1AF04762B98ECBD0DC374224D98FDF7788435BC154E1FB06C970A914C34DE52678F61ECC1969A2C5B1FF4D82E2C80CB543B4B7C9DB541229CC50CC6C448DC029CA24ECE635233C401D3715671BC75785DCFD929377AF5B65EC43EF45A9B00CC766695A4A5DE9A2E6582F7936B9FE7DBBA6762C41453683146F4ACFD809847F866DDF559972FE0C093EE7C9FAB3CAB0BC2BF8DA19466A96BBF2DD4859E2D1CE122A3CF16AAAA9A4708F72BBEBE285E1B794B2B9C7A699B36F39F033277E8B7BEAC3BC70A572556EE5C070A309D9D0BC35F4B6E55ECC91CE9AD273B0098F64E1327C85CCAEBBE67E8A118669653495D2FA09C29C6FCDF870905B2C8BE0DF806C29D5E7AFACDAC5F89116A3474D2229C76E649F99EB9EC71A2C229764A477853D68C39B8F0BF4378993AE2B26E814A337CFC103760CE92FB564E3A3E4546996CC4D8B6BE069E99861DA9C731B543BFDC006FBDE3B33D2C8C4A3F5789466122616C98F52E5E4BA239E0C3758C5BDD3BAED8809F67A70504BA061409A9D87A499236230EF0F1985DA0D765E9B7F733A154E8300490F458847A89E7C6BBEB7A9ECA7B6CBFFC3124DEDC1093C02C808DA1CDCFF5237745C5FFF51F3F15CF746D3397916A45990070490CA74A55F34EA4BA9EB73A281F123035C005BF6C7B30852665860ED13A2B5808F81435A77A8504B58CBA45559BD3BAA663A571F108685E414FC4DBF8033075E30CD6FCD9B893DA32F7C8D5D971D5EB417F1201B00F65DEF4EEED3B55B7FC7E6194B72A861439B865558157E65D4C2F8A1A93F48192099B375D111370F830B34EAF3225A16006D4749494B9AB9D3B05015E34866A4A2D94B9588A8DE8AD4CF90F2CF422634E8DBFA0FE3FAF27C3F3C2EAF9C1BDF23FDF43D196732E1FA6D2B343BB7D9F5F26FFC31B26C64A8EFE2B2D86AA34BB618FB58CCB54486211A8E66648CEAE52F07A6C1EB5234DA7CCAA971AF984D6050D1A81F10E6D19CC44B5E668CE92F4251924B25DAF41D5E381C3FAE4208D18F710B5F93CF3C776A3D81C608B06CE6BC68FB8A8117CE7BA065675B88510F2E8A440EC363A5983DDC1352E446A482C593A490AD6093258E447EF52BFD189ACD11C87A8B75F08B5D166C1DA69602EAA5916474131E20F704DF84C3FEF2AE99F9B9E8F7315A143A07C7AEDE5797F503086DF7DA971244A61909C4AFB00842FBF4C3A59B991B58AD6C0B8667C449F0D97F34CC41FE935D9F55821299F780359E2F631858617437D4AFE67DE4A1AA382B93CC3FF596726F0D1C071FD0E00883E9E03811FC659495AF2A62B45DA079A66552F2928B6A25C6416F8DECF723623764441E5E581F9B2E36479A1B6CB3DE9B090E3343277CD7F84E80219793CAED4945DF782C4B72B498A62A1F5362745662F711A7E47CB816EC7069D10CA8314845AB0C9FC326C5BCA0E2AFFB4E6948522F8CD9C8DC008855E592AEF1F8239748916878ABC493E33CCFFDB86CC2ADB99B6251F493F0D2A0BE56D133B66395AA695F6298F7F4BAB41420CA9B8CCEDF2719590287928CF6BB3A506D6678B814076B7A774BE9B7029DF9F4719AAC1D012BBD49EBCA6AF124D0AB5C5FFA92B4A895CB76B88DEA9C7105136D78B76D92079A5B001B214DDF7E140861D86ACC260B72ABEF2CB3A75C2BC87B39A9D9052D4283B71C10AE275474E82A5FEA1654EC3ECD468DE4A015CEB67BAE3275C2C79863E2883D46FAE351F0908F42825DC7D9FAE0FC7171791FCAB10E16F3F027E5043AACBDB1F05FCD2B3EC7F6F46AD6DCCD6F9E6A6AC702451194788D14261219F794EA195F2B3778654BB373C68AB4333E224D161A1F89FE440BD8E968B518EEA28E81B89E04FF1A85B879E4B54650FA8DD1322D14B4A87"""), + TestUtils.hexDecode(""" +947B02936A53FABF0009C0ED2E82970B33714BD4F15DDF7BC3A895DCEB96F9304811F783F8CC627B5B80868E23EE36CB98E6A5F9AF020BC5DA891E898BFF4A5AE003268A74BA6088E920511F5EEA54A5338D03356EE19C79E7BEA43AF809BD763EDED9D639DB0CDC790BACEF8983CB91F1087682A4E707E94B7D00EA8EDF04B57D5117F84589FA045A7B4A75C62FF9A344035E8B771D66D82156E28EED855DE1861023D5C1CD356C225AE03EA0A11BB1231B784CE9BE0D54DD6C4EF3128C7E14928CC0DB36DA5F81CCEE1924064403E964D375B071FD36CE9595509DA0BFFFA4E4C2DE1DAE201A55EA124C86F9B963221631AF131D2C4DA034A7798817D2734AE44282DA3BF2803D4DF90B718329F31317E5D585E323DB512D2036B74812C11B219729214B485D05917C913E742402ACA2127782534EB2DF176C5C25C484ABEF24A969EA2EB524FCB54A7CAFF7E6F464D8E716689810A2A02EC899685A1E28C2FA215572D188D3F39184D09EB93AB30D507DEDA6D6049E5345F989E071D26D909170D7AB1BD6CC35AC198EC7C0B48FA5679D24912E9EAB38FE594F1FFF5F2D97ECC84D8C81B81B2AD476CA93E050E550887D017E55B2B5D15700542E90A4639F55A63EACB727CF1F6C76D1DC7B6C0FFCDCC1086B7D8EE1C6624DDEF545082B4A4BA6637F8B77214914693DEDEFA7E62F5342548C0264206C30B631486CF5522D3BFEC6936AA961719984B84C43C49F2399EFAC02020613E97E16640EDFBA2D74ADFF5357A064FA43BEF8CC7D03AE781859942111E4C14CFEC01C47DD9FFF9D3D97EF92B4AB04C571A0C58DCE3BF45CDC01A7E09F7C89C81BFC06B5A4A46C88FF95B7FAAF3576D53346D18A0C179E73C4DE8501FF6B49963E2683951FA7E55B49056CCB0BB6759494AFC8A14A1D5823074E0C17DC279540D29C2329635189397DB8EC9F8327958BB00DDBDA507E1B54C226E7C02A680FA84E935588A435AA1CC029EC15CBFFF5B3AEC29034332C917882709A95266ECFA14D4459D5F7C60AB739AB428CD967CAE7D1D925BA66365A522F4F9D559D3268913CE7F0F228ABC49D4CA872878D7902F7A202A58FFC7D54FD7AEF88E31FA605840E510C639D0D568D7BCB1A72268162576717A238CD3416E89B3A77163529A816D613928C2CA18D2B2C6728FD622432E54A9085185042034D4DC8EA8E9F100BA7629201636CB87B2E5DF1F95FDEB407DC330716AD0D6ECC93BE38E497E1B38B94DB5DB6A5C067C6D0E1345AFBD7D2AB9646B16C531A96D4B3EAC2E540D479118F448780E15A3C17FC34051B4137C8E52C84495CAB2CD93420FE657743180C93337E39306874F8D54DCE702D5729F82710ECA144F040DB9A0907A3CC4DE9A12DD3958047C157F826F9C054CAC044567CB71A727CC9FD94DD0A388DF0A167DB6F9F16FB00DFE96968C463CAD7617587E5698DE7AC658E954D94AD94A1A3E6A5FFDF9B7E49429C00212839005E29803DC4CC4FF778CC331DC060E69279263005685494F686838DA7930805AD839437056C62510081D276EF676739C0D689B2415D3EC4C0BF67BF52C9A2845E7361BEA53111D6DE6F5EF65A22A62396BDE531886D71B925D91AB1F916AAC97201CFC477B694E898AA52AFDB46787BB85F01917B06E34342D2977E78A5A82CDA3C93F34BF9A99F7AE9ACA24D4BFB2C57485934EDFB7123BAC3DB085DB5B0F2FECD29AA6BBA2EF2C2B04F66605678BEAF90F448B19ACD4918A337FC9ABC098FCC804AA1E37E22C9EF010A9FC40CA42CD270ABD9E56D31B12663A984513AFE3917F3982F32E42FA9D67BA2E5C149FC2E6562E7EBC24DE2E1C475D05028E69AEE688EEA60155346843F71F1F99B3D4BA69DF71ECC4AD75FAAE1921EB47EAC6C4B73F31220F1993665ABA88F5C504CD7F6D0789B1166E4CDE2CDFEB140356CA5FF1B5074661A90958E940B8A7F80CF298B8366D81C4EA232DB4A8A4153028F9BC9B9758BF1BF27B7A4887D48A09C453E3F81A8D7D92ED7DA35B3828463C4F2AC5BFBDADB70FED3E73BEE26CF0B973FC6C00922C2BFAFF53842BC71294122CDF7E057931E46790356856930EE6D653A70F68E107D86CC521232ACB62F86626DD626E1D5745EB26B91917D11E68A6BAB09B6BB0BAAC327A37504E3B10037871BC8D92466D2EF236552C1F3E80102F8FEB03BBCFC4C51039F17D5490FD61A6E5BCB4BEDA507013CEA1C810E933CC805E67C1AAC6DBD9D9B7204FB5560D691148F7369996B48D370F32739ABD5E1DAB98BDE86FDCCEEE4459E3396C8ED7137BF5326322AA7A41B2AB74CA5D76ED91DFB678C66874E7C6B4C6367A5BF256DDBA53BBA20AAC90C4855CF1C608774896A974DF5B1840A83B2FEDC619D707AE30B186F9FB75BEA7531035207AB889B92FEFA6D9802E6D44598F534390178F14E1F629629F6E120C1DC8F5C14C392C117A239E539A602E521360CCE81F3E70D94FE371A13B7A42CCDB29709428D3EDD96CAC31BA34B91BB2A92C9208B7C81AD8300905BADFB91DE8632C7E62C4D4E4C32616F712BC4A50858FDB651AB486B6D0D16A0BA10D128D539E3729F364E628A93DF73DB954C5D8A1CB6935E1D5D3AC2F905DF189736539298F7A20B3C705453CBB0E991ACE069DE62A2C89CB956E8E0110083C344D971C61101DBB2978E1831885EE7C27A6CDEE29402552D701663E5579F450C4788D46AD794217926CAB7EB351E93CC7D3771975A969A3A06E789EFB410FC829123BC00776E6940D8C15CC8773992C0FAB5CDC59EC4AC6A8889EE8087C26AD7702A8672F711859A179CDEDE22D1A77D8693395575ED4E023B903C6F14FF4A2191E49D4C21398E484B3189F50853B0B20B2BBAD0EBFB75528B4B6FD5C7B7B71CA9D4DF36E67ADDBD7305839E7FB2A25AC53AA1622F13B3B4C4E8CC8198269065717451CBE58B8DBB1F448C96D5940EB94460618036398172A2F22CCFE2B31DB2DB562EEA7415AEDB81D65EBADD8D2CF04C69D870C898D05353D8C5CCB2E37A6EA9EB3E5E9DF32175888E07F4472A80DBEC699210A1E6B8F4BC7968C3FCD9666AC9D1CC81C3428A26A3A94C96292F3A8341FB90350FC79DA7E0D947751C6E1E17770B980EC325E0E87D8A283F0BD853F221873853DB22213BFD7A7D621F64BFFD73115B48C4B06DC11F307538CC86B351CB23E199E15733A2B5E3E2360B42A203F632A8243B1557C64773D72EE1D3E3E25AE943AE3E9F984D116938D39005D4556B76A793AEAF0A6397691AF7386F509668B435DCF7B10A8B810FA55190D56DB430E0061026292D3E494C707C85E1ECFF151D1F243063646C7D8D909CA2B2BFD3DFEDFC08173649595D667C8598C5CBF10A37456575839BA2A3A7BBC0C2F6F9000000000000000000000000000000000000000E212E3D""") + ), + + new SigGenTestCase( + TestUtils.hexDecode(""" +A7DFE40E0A335C3B287EB94E97BB6875F589EFCF7FD841EC88F9D03248BF26C9EC8E7F8DC376270F7112B52DB67CEBFB8A5FCBEB0A2273FC3CB8FF1CA1DEB5C581335B8F6C53E0F8513C42D5AE82B193BCB8BBE9298446ED79D278DFEA201D0B2667E3806972F34278B83138432AAA10065DE34B24303A4E5BF1A5E3DB90825684A0205948885094459C3840C916061A284A8AA40CE0A828123369E2208254C66C91A06C64426AA1B44508418220379218170803406C5B384ED3224A48A2519A840DDC420294A82C14C105118070592009D00405C8B08DD2222920B8880A39511086805084910A098AC3A84C5824080912698A486401182C489804CC14051912250832855A202942382252B8880A814119032D1BA5214A448492366A91B84C1AA528513669DA240E14820C08A0244A444E83B48C22224212C985D014690422824B882913298918A1201293306400201806451C8051D2A870D1444D13268A1C376D84186024C6081A262D011621C3048E02A06C832446C2C20599826418B86459B0618B240422B58CE3080A0231229C244DD4C88448202202868063B68543A68D1A132E51862911B929918868D9C828D4320C0149498844105842269CC265D1165064A27049A029C12641D1403100262A51828DDC2401C14670D3C0484C962909A18CA4A485889410D00030C9808C8814501C234E91287218490248828D890005D4222D0BB26C21020018A00098248960A88D8B921062B251224282D8B02853A090A24268CC0651048940102229140988D1322A12C95023C68401068889B62819180E10468D03A7500028051286248B9880D3242C0B172111176D5C048991888C183388D2268DDC42450208300B302253148CCA888D89B665111482D1A029E428315B462952B221DB126A01B90C0A3361A3420D1A3528A232498898802011285C200EC3284EDB283120264550C04903298021004A1C347098360E11A04914390CD9046408100D09202904A52D524400D01488E4084823B4110B907103440C20425021085212994CD1A8290B4229DB1229D3360513256162340814B24450068002C20C22C98D4B968520962480402C51B26C0922424B8041984809E3346E24829024930C0A1348533440843004223826A2042C1C9484001860DA864D14331204118E030144E3240263C029E288291291019AB22183B29153222051380400A244D4066E19160E08183120388C14B88420152C19A02C22192E448468D3B048D310612181EF7DB8F0B9A7828845B0CEDCBA94F60B86C183E48327BF5CDF316E9A8F55571B452EF600C2A1AFC57A159F501016FCA48627C1FA9D7C3DDA58BB4D41EBBB6B7F9DCBA591719CC4B9ECAC146BF8788B48C911600FEAA5683EF2D12C45A3C14A0A5A62839944B427439881DBCE4481DA951B10D81FC7711D64CEB088DB4A70B5804ED577C30356BFDA58D5426DFDEACC6F7CAD7C30E718E7FFF4AE006BD98232417ACA13359A05F8B389FCBB29E9B670B28CD8AC24F3ED55F70D8BACDE3F144E79312D8298FE6AF01996E00C5E8D940A408D532CFBA872B461F538E0C7583A73D8C93E9889E251EBB4C7B1DCE6FE013DAB5AE565DC3EF4F4F5429930F1A6DED98A66932BE3B985E4DEF769609E5EEFE6EBFCB6FC56E9542FE4ED8A121ADFE9E19B8F9EBC4B9C1F4AEFB351C2D3840499D0D2227B157DB138EE62860F2963D6F3D6458F457057E4A03A72ECC52589B74E12F4EA37D8E0D9797EEDB246B88744602332EE0886AC9630D876BE34D9FFF286B5CB06498C60CE53A558CAC63DC5626DAEF14F702CA476E4C08A569DBEC1763DB6C5910B8D2352C6A648B2A6F27F9E248FA4C42FD48E7E9CBF37F318A8D4362C1B53741B41E4231680A6F91122520306325C2621EB87A1736FB79098006E83E17E7E22637688CEE4BA8A399EB1583CB8EC9DF3B8C284A230AB6622D73F590D19331783CC2C921EBAE23DC5605F4707CCC96A18924BC17952916A97408B4715FF3F9ACEF8FC4943BFF6C9F7F5E7DE18B93E679D49D04366A658AB913EA5209D22D72B62992383C7EAE704259B5932FC09F76A12FFAC12605D8715366167DBE45B272EE7EE27817128EC94E1C1299DA8F58E4206D477AAEB8BAA8634107E14059E75C90926189D3FC06C9D38799F3E00BCB87637EE24705551A797899C9EF7FA41F61342E9B2480508D9D3401EFBFD12776EAD4CEBB815F505E1347609AE7527C81AE892C841F0D21C7F97003D5F9F3843DBDB89A4E55E52BF915B92F0F2CF0345FBEDA99C322FE7BE34E0E08034078FADADFBF0661AE573EE9B664C9F05A8AD3F02B1866D24B8230D20FDFCD358BDD88AAA4C3E458CEBFCCAE2D65C64F6066C7495B571814F714545E6423D322848459DCCCC2120D8BA7CF672F37C5343085045FE3037070310E851508A0D5605249AF5D911560D308C81C7E2F2538A0A7EDD6DE341424ADD8249D628599953F857913F5767584A7420A669AF08AD060281D536C170F383C450CE8C61DCCD534AE64B91AFAEBA4742808733AA718A13BF0A55B1BD4AD618A932F84F8039754E1E316C560AFE646D98E928C28D39F5BF2F0D0E079C6BBCDBC5843A5FE72E99642B0E297F11AB5B9C629BB4601230F33837975AA2C81664825216D8821B79802C0C3812D1C0140AC676860C565E7775ADCD2D41865B23DC61BC5BFD3A80F56561DCE6F2A79D37E85629FA6EA952289FA3AAE5DA7D4E9238942684EA932F89AC0AEB15263AB2D5FA4D3D181851E38BB2B3B5702E6E8DA5CA981D2DF3A0A7371A75EC897A46205D9F05594DC169333158F929E3421220EFF6204BDFA75E41481A3E70BD4EC1D4502D902698C4FF7FA6D69CAC4A8F67EDB414FE5EFBEE8A6B695B218AF6FCCA45CF900550681B124CE36D2D9CBE8B2F179B4A4009281A559A6C5B30D4B6DEE9BDABEFFCA70446166CD353D8905641EF072F00571CEFBEEF7A296E7F49F5B112F6F0A6F1576468C75942609484DAA448F4508EAFBF2E9DFD2F83860831D6EAB17B8FA73E493E3D8B71530719209FD2D24637D6323FB03E3CAD1FD601F1FBC7B408D3AA6B90C053BAEAEDDDAFCBEDEB3CE0C6A70FB83AA450A9968CC458C18CC9571F74FFE1ECA182ACA2C4EA57A60BAA4D922AB6B006EEA433CF69448AE44A807846361F5E09D565D89410C3CACBC284DA15BA53860450E28843A662BD38E89C0AFF23ECB50B85C7069E44E211DF89CB12E6CC211036B0ED7EC5C098027A8C11EEF0898B785DE421C8212EC9CFEBDE72463F3856831FA209B8C21E63CADDBCFCE247F0D831373B7AAF82B676FE9C7E3CE70752AD0C45FBC3C11B157834103B74597644E095C386C6FDD7C9DB072EF20AC511DB9D4CDCEF85330E1372512336D5CC951A7424A8EF7FA4CFE956B6926DB9E1969747B814EC682659DC28A088A37B62D9E84485FB3B33B6F69BDAE3DA0C7D734713632B9926421B7941BB44D141AE72819281CC405F667772D68837B58156BEB2E2EDA6A51D9B9A5DD972E70F3F2B9DFE660884250CBF8E539EA6E637A693AA3B7E34467ABB697AAC4FB376048621F2DEBBD94E1DA4C9A1D2AD21DEB16A94BE1B0DBF0B5DA2C38B618CB3323D9F"""), + TestUtils.hexDecode(""" +214BC54C508E63F77B261DC59588A87CF95C233C22A339E7158C47931C1EFEF775EB3C91A32C56E888214F9F68D7CD2525B23F695871CF5EDC6979A677EC19CBC5859C63ADCE2E38C67CAEF20116508F33BE8035E9C47D124EEA5FD1651D64371451B6B96601E4A6E8292ED6841E483C3ADFC3DB242D1D7B3F036492741661F45232104A528B6FF79AA4630740BD16B37CD3E7C711B76A259C0845D6F87E4A4B306E939AD1C41022A7D5938E52B98485D95D11BE629263E6CDE20F63AE16CC2E32B6C1C442EF108D92495A759D3707AB6CF3ECC5AD7C02F133D689E252A26C014A31C65A65F079C622BE3B648496BC57C462051B17175FF81126B5BBB5324CCEAEDE0B5A8ECC0D710F04DC0C751318E8913F149E701AE0568B5426736288CAFECAB1779C7F4E96D9007635F76DEB4D379918447F30167F257B8BA825A50EE845FC4AF7C34AB200D5BF45B5F0405BE2347ACC814BCDC648C274C24F8024561FB66676534F1FC8041B63114679D9F4E8CB0BCD7BC4C54FBB4F9A178B4FCE64E705BF8FE42826EE01F691479A8815E2DA00111DE40B5CDE464A9F7A3D21BE9562FD9A5C5CB3F4F9E8F0D8D8A20B9A5AC9D7394AE4316181621B43D8220FDEDACE345234E3DFBA134BF54E458DBEF98923C1891CFB8DC9B5317E3B16C740EF373666969C95BD1C53F435D7ADE792FF9E310A191246154064D0E8F20032AF4823A335D88D5C2A943CD4CF313CF2999E237F6EC50F63936D0FF3F2C729FAF0232671C94785B67E0CF71A7CA5B32434579711EDF155D5BAEDEBBB8F0C6922AEB9798356714931AF1070C49BCA507E289F005BE9D8B46AA67CE2137935C7EFD192E4CC24DBC434B381E9A15CFC529D0064F057FC3AB592869E5F1AA5FCB299B2CCC0ED6750E318F6FC969E6A3A08059788102CCE79BC92804B1D08F3BA30492054DB6401EA251191BED1B8CD35DEA3A653D5D546D2EE8D31C2D88D6275D6C7B463D449DDAF586D5E57FFBC07ED5558D87F7DCA82E4ADF49EB9135A578468907BD8A6228EB723241D58BAF3C78C46451D2F11CA0552A05A85620001D376C6194AC6494E337388EA49821C233F32579FBAE6D11E9DB257C426D99516A16DA63A7BFA261F2B012CEE4EAF7C5C16C6331B79A26E79B1421371E574505F61D699C6DF33EA734ED14129608260B1233C387638F7ED3A34866D656D74F06C2B8D70AE60A0994F3D6C1267DCA2001EA781E5D6E17BECD284F967788227E060381ECC60A10832091319F225C972349BFEF08D4DD5298BF7EE11B693AAAC682F91DCDA113EFE0F35CFBAFF6C73DAE43B8C1124EB57713C122F0A5FB03D02C4128565FFAEADC0AC23DBE5BF123CBA024DC2F3956EBEEE95918B87D2EB22EB1A8ECC3B267528A62F2280E3DAEC02C89A01F5829B5891914DAC"""), + TestUtils.hexDecode(""" +7D337573A06A3698B8631704D2D6A1E529B45BBE47236936D0BC13A6DA8E09ADAC5E60E2D0D2D5100ACE99EA411D50C77CAE43BDCB50B330412EFD99959E562100822C5F2B932F7D43EB8015878C49D182EB968F3B12313F6EDF5056FD9518FE09EA1CEF89411D126346924C0B4EEC9D7447083482C12D6B98F0EF74913E66A018319143A5DFBCC3C21D1AE52FA19FCFF12E4730E4510B90EE9F9727C240A145CF34A01A5BA058CFCD26611D7F729F742610AC81B94E931A47039027F81377C84CF225763F68A446B63D64A3D375E1EDF67C1EB3E997A43BA77F108CA3D16BCCDB6CC451308146348C33C9485F4320E8A7ECF3758128B929D4E8CE07B3E84999515A0E5CD7D7D6C5B3EE0E712966D91666AE5C2FE8E30F22A83A1A7DA0FFAE83531C30B3A0B49029239409F36D384C888AA82F86B6D00C0D6D02FB75BC49831489161BE918EF91AF79D031DACC7CFCEC51467F5FE59095C1E8FFFDA2970D4D5EF2B72D519AB0F9919BF046A19BA279F64A084627315938EC50A5B1ADE46A4A2E3D382BE747D895E0AC6926EB6ADBA0E845FA49903B83BB56520B809B034DC7A4B7F292CC7167C51969C2C8E78CFA42BD342B78104512AA4003C48FD059AE0735F78F4837802E6711B35BE35DE93B86D9EC82C9303B732CBE1B16BFC3E718C65288810A5510410CA87DA489A71DEA594F993C7B45FC00CA68BEECCA107FF4723339E15C49F7839725AE5643BFCDB2B98C443DCB6CDD5169465740FB9959F2B17B4BF31D0704FA48ECAB5BD0F4CAB954AB132D4BB0014E558083F1ADCC81B9B5ACC2987F57A3CB069187325D5F5BF5128185608C464CF9534755EDAA7404E35F6182BC83D016C8892E63A7ECA6406EB369FFA55AC37963946038E3F74D9E18F3F40FD190DD510B07D2FDD244D74342A2DF22CBA0835B5A5183A4A9ADE24D82D7C988723031FE07BAB95F4BF96CA393BD58E74CFF56F916B8D3835F833EE658C788E9AC56E408A5A4E98F05C2379F75A82514AD1A42D9A90742C7F92D982B9C789A862259953D9D88F1BBFB1BDB345E966577226C87C6AD8DEA26F75F0C3715225B5297FA7C5D375C1BD8B5D6DEFBBBEA757E6A504E83B0F2FB3A80CBE2FE526CE76D799135497C498A721AF6EA8443934E0D76266ADB52ABE212AE58D7F52458901AB3CFB8A1EBE9AFAD9203EEDC9D1BA66ECCA41D8C268541A83CB49243FFC534C9EE8E0279139989FAA602B668669AEEE6E00EDE80F60CD41929A6BE3800E53677056C7D0ED1AC4D80AD357D96B7B2C2F1B35EA9B9CA397D23A2928245F7A9A0BB4AE0569F16C4445EA9CEA3094364A40E8CB5D06E1F624DF1929782CC33FC322201525CD181CFCD4A5D4201693D0EB249E9967095F73A35F4ADCAB9279C93E0F62E533E121F3396767D409CA80447A4208BB1D83BF7688A007B5402B5F0BCE4ED4EF51847B9F036C3BE81EEC6A6FBC6980D5505BBEDB99FEA87140EEB4B3AEC965108B48C6C808414512F04B5DB3D27FF450D54D6CF5CEF9F9B80D60C0C9A2F2E33129411013599A1ADC3B7CEB410CD007E413B463C1E08EFD1AD51B08B21A08163080450812D6B020A299BD8BF3C8B5E6AA69BD5ACA973C625D995EAC71A81B31E75B4BE92A773E9C10E7686EAA978791E0A68C0C5371D6FD12DE5A370B09F90CF140B7D1B63E381919EF326D0F58A21F04BC24B5623713C0F42E56F4727278C1AACBA51CA553CA46F7B4A3651584897B5EB99BDAAB90966D971AAB0768C96CBAA0D87EEE1DC0E8578B2A8416157BB7BE74F1D815EDFBC169D2D848AD00CED03966DA2E6BD5F98B230D26C3979EAFB099A07CD5495E623238EB46C62F62B748CD97491F0CA8C9A91FFCF617649951C6C61EFBA868E240A2B754C4C920B025BC51278E5239A7EE1F1223F4B8574AAA9E8EECA6B65356820F8290D336EF57A7E6F84280BB7179C6B919B2D89450DEE63BB4DB6AC77BEBC00D0D4407B8D6018C3D878DD74D27D3C01F555B7768859E499EF742251CE86E7ADDF7745C4C2931FC872DAE54060CB6B930F9483D0634613DF19F9AC589C39A666E00F8627B234B95BD77A88C93572FAA2CB38374414E56BFCB9FE30E55F85F476D08C6C6680468F6E23378795435E6B974BEAF4EC6FBFC49A3C0F23277C29EA4822D36A081EE3AF75438A99811AFBF54BF9DEF686F26FAB9A8618F6AD361486209CA84ECDFC3960F47C61BA603E09BC3AD5048AA4D52842C3B9A9C79B49AF43AA952A972B86C485CAFCF2DAA0D0D1050F66E4D8DE1F1732D9C88C0837A83EC78F033C762E950E25BACC1DD6B89C1D4C05728D6EB03E7435523CFDDA3AED8FBB4E131A494D11C951D88490625800E35E594924D84864DB441CF17C5A5E70E0A338D2F5774FA6DD8E3DA2478D6860D032C54A95990FDF5BEC5083552A386A45A81245EB75ADF99A1A6163DFA3729308F310C8C212322F96B08BBDA9ECB239CDE74E75D324F61CBAF7F1A40657B86E83E896706624E51B3730680C574872AF46BD84D5761105CEDCAF29ADB1DC24A1C8B74E6F762292BC03FA07CEBBAA430648BA27E9023ED7C7A2B61BBF1620514CEB508742328AEE012939543D69E0D705BC57903A4E8183286CAD8579734FE35811285CAAEC8BC0EC14F126B10022E0EEE54766B221B6682854EE9B16E53EACB6BCDC989E47190275BF19B3D894C8AF56A4D34D61CC6C078A04B70A69DB3019A5BB0D3E349DD21C101AE2B42EA29950FA164FBB86871597F2E64A84BDD281F1B3538F51F01C0E87ED962640F18DD3C429CEE89B017AD485F188A3A1803D053E7D8F22A47B6A04D558ED17BF0101EB7E1D7D0FB1A1B6082D12398F500B2F65363912B8D8D94FF8F73F1246FDD4C3E6F7C4E372842301583AE8CBD5EA185FFA685E21AF074E3C2883774534D8B449A5DCB07C46F36FFCE4F56222073806CE59EE5BFED172E5A252D214ED2642207DF742AE7A62F8D9A4EDBE70182DC277E09F6826C8DE5B103AB17A892DAC844EE7B2019881DA549200B76AAFE5B9E92711BBC36A3EEDE9B24E44AB42883E2BC7B9109B70EDA772642317B50A4D307592120485F6C1C7B29A0271D571C7DF5F0438C8B725FA98AE2147556D38A295C373B627B732333A0961A45A20EED30B4AF3A95890A12E932B1BF934754A0994154C814E114E9D671306FA257AA8D2FAC90C5920D2E20FB35C5AF0259F7F69607C29075B8DF9B7DE0C4059D62BAF1660E05EFAEED41091D3B6323E32538CAC3D88225B9C683B69C415003CBB0A770A0530F2738FB14ADFBF48459AF82D5D43C7ED0F1E2131535C6266757B9398A6CADDE9EA000621252D373C4352767A7B939EA0ABB1B20E17717E8098B5B8BCC3D3DF152A2D3855565F606682889DE2E7EB00000000000000000000000000000000000011232F3E""") + ), + + new SigGenTestCase( + TestUtils.hexDecode(""" +55FDD4E2E182AC68535720F7EE49C2C48266568EA967FEA7CD50AC62663043EA16FCBC7BECCCFD1E71594F6608124EA79CAADB039A303FD25C820B2186E801CBB5E715431F30363F908858E6927537FB74E7EF9D094790AFF50F5E88AF6139E20933274A7D4F3EEFEFBD08ECC4AB77DBCD0CCCCC17BCA0357DB699BC2424F1A99A08128B20486334062116120441525C3001E206460BA77082262A18314D63106E5AA669D12229083746129584DB30001132049CA45058046E144021982228510681C1C831A39244212162CB200CCC444A200529D23860D8288441024D44188D1B39460BB391088010091790C222491B378619384000126A5B828C24B600D1C4091C3750E39681A24031C1A28104344060C8691AB88D01150C24375260C44114274152462ED3B29124278198244920838198C250C1906D1B0788114885533890624871C01291024902D104729A26521B2012D124051B146C4C382D23465261442423C451C1388508480D14428E9B304D239330CA266A2385050192040A826819030824069061A469512845A2044841122819A9688B34664B8471A3808C844031D030460A31018B102D98A249440821018281009585D80430133288DBC04C6132820AC645CA240018384EC1048A0CC72911294940262941205202B430638090081685432689C324821A0850212149814031C8485212028404106522240810450D001830431081E4281048B850008545D188108286658C04252445044A204584863113460851260DD0260923A7911C4761103861DC226423C96492C03110B40C22B3012023648A0480A302601001509AA86050180C442270D1184DC49231DA464619438C84226293C685E2260420084E53240C5AB605CCC44110B951898628DB96216006011A4045C84448108601621461C2106904140050284AA2946123834801C64D981068118409C9C8446186445006100A26264182714138720C43091CA90851A40518418090B610CB429103B724E1800C63060022908953244D0A094962B80894208D54A46C09C09064B084002205A38689182905E12065138551214648191362989881C42428C330618C386CCC186A89A0891C246E5B489108262CD1242D6086645122855B1441DA105083006109088613868921B5480CA131A420319446408A060C480008D09029CB06255B1852C496109B442508260158B60C924229DB248504A840D4326C443080E44810C9A260DB060E91841009468C5B2249232425B4DEEA430C8E4E98CCD4D270BD4B96248155DF82B14BDADB0241D93D57742771D73368AC1C839621783F161524178734CABF900B0AFF404E4242826FF4FDA48FC5D09CF0C54110C688430DE63F1A16560D4A4F36363C00C8865616B178243B4282879D0E90576D18C4ABCFC821CCF87DD19DF99D8C341C3A7E6AD9B1D936D83EC1C2756616439D59688709FA7C6ABB3783963F1DA6A5BD3F3C391A3D50B65EAA6C1547B3C8CBD9F3D9BBF2D828E18756A35933D217682E527F68E0935BE2EA5CB8F74DBA51EB3A9BD4DE3294B962E74D76BE40ADA71B8B5D30DAFDC34490A91D1A7302097EB7C1A9B75FD018CCB0FA8FE4AA8C95261C837922A08FFCEB669D7A4C4D97F5C657080FEA40933DB7EEE691FA496D015799B72A2C6D48BFD8D43A5AC1D4035AC92860D3C58E52134179D459A9E7D34A069E99C702A7E3683AE83B6EC19C322C5D794DC1977C7F8C75C3B1477AA4553E7CCB49D17A6DC6418ABE9EBB80D1329E4471DE21D2944B4041A6DEC0B3A7C38EE411946B9FB552DEEEB4C1BA2F6279BD1DF088C3F5B24412AF02F8F28FA8BE2C5D8098C8BFE4008F53448C28420CFF19DD3B9CDE0AFFE43293EED189CFBF2CBF141EC1DF9AFB5C3678B36DFED40868C8C73D0BFA7BB6B6C6141A9226FBD5DF9D8CF485EAC66803932D2487BE19E5F48F8D34E175D0A24EEE880B4C6EAA0E093691E7A6BFC912F89AE07A4613D1A5136EDDF15A3DAB94626C36143FE16558867BD43E5EAE022011B0DFE75610CA7B6F220AEB7BA46BE1A6F1CDE340EE5C6D915AFB49223CC34D183142AB7E82A922D6669E15BA4A316B9282FB6FE5A1F310B294910B04174A955F40D82CD5517437642E91C41451051F2D063E492AF13EFB411454F90BFF85BBB8B0666233CB19C2DAD4A192AAE440344A9CA97F26D504886030BCACDFE72C87EA5785AF2BC55C54C641BFE7861ED3F5AF1F1B430B63C872FADB6C5FE4B446C4823B7AB7BCCFB20652358611DFA20466A176CEB3CE1D7336C34889A6EE4BEB96563801AE9DADAB2DA8AD03A256FF5BFCDD8BF0F65AB942678391862DF6B3EC81385DE7721B6B650C8A3B6C59CDA6B2A799383309D4176DBD7F9A91952298600349690A6FA57B02196BB2483E57907FB8C027849228B884BC33D0D0B3D49C6FFD11EE219D6379592AFF909862ABA39C0B0E4B2CE259C4C77F51E7C7833A6FAC2FF2AB30F34A54522EEB3EE52F0DD3FFC1FC3E0EB51311CA66D47C4160918BE13CE1946F27F56A0AE6B647A1AC04E1148608C4D35E60E95DD3FC887C812710920004B55027EDFD5D77396BCE2E43D696574DB561E4FF9F475609898E32650E9A18B7E22692ADEF2848E1A0B26F3990A5CE03305EB6D90228D4735F97D008AD96C019C79186B1994D8210052C432FC145D280C6F8AFA51B7D52E1F0151E266EB86CCF02144C4073FC01C32DC69234250953718CE1CAB03DD64E5AE07B3BE21BD208B5A76E2A990987AF5DF07DE6AA059DA7AD6FD1186B99223EAF0E8096EE716705D0033E8BD8172A732DB465284850B41A7C3303116AB487D03999615CF0B43AB8070364B7E0A50364947C92F48422C4EA043D33A31248D4ED643BA3314B9F42C380A1319E18BF300B3F247F334DCD78D1E917553318DCCEEC91D1CEC4A9AAA0685EAA32BE2F214F7CBEE8CD3CC60AF330187F7F688AA009D453E21FB0D1879D39C6444FBEFD02C6547BB6EF70E61F7D3F0A3337C157ABBC4CB598B8A750ECDD2DDBC1DF4CE5E1CF6F2A7657BCE25377F46CAFFB9FC0DAB2D42C590DBABD7147DBF56C619479598F62FB5DD0769AB4F915990BB524385AB946C3266C95870F199073A81B172F23F7DCA7B2A9A9B3B6EDCF5DF718340EB4C10CA61FF4FB969F736028372795EF6AF711FE9AE752231C3F9C6CC789B6DB5EF2086D91FE6A22027C83B5719DC6FC87FFB8F0113DB674F4E23B4EBC7F984136C79EF8881E0478B8EDD289237044D7FC11188C753AFE34664C680902A2066A2BF8BD48ECD2ADC23389288ACB70117EF8031D332CFEAD3ABA3B3A8C8115762AA9E8F8B46DFF5D97B6441489CD8A5F53E0FEC9A105FA7AABE36F1219469717C510F5090BAFE13506BF7E82BD30E5CAAD3D64537B047268CE62C325B89184D55B92A5788B2D09C1E7F9B7E1D5708A0C2D47FF9C79CDDB958F7AB25FADB4078B1E4C45093B8674E1E605DCAD367D2CB72D7009B9FCA95C55B91081F0A689D7CC3A7616BCEB070D49DC25AAB7F7F53C0CEE24E12F97327DD511B21DCFC004B123B2D8BE604D1F57A490D7B2A7A6E3CC3270D41DA5E2C02FC1920BCA7F1C2689D20C4F0310081E3B3D7BA8D67489E00A285561"""), + TestUtils.hexDecode(""" +E742D452F392CD3CE405908EB380CB0225A4725065AFCB0C91C5E4823471376E6424AB24D57FC4265B24DEF6CA73E28FE20468B6E26BCC9267AAD2B7B82960C3FB5A01960FAE078D5A54BB324232B6647C9DAB943533C865BABBD3DC0D1E7A1756212980D75F2C8E999DE9ABD1874E3A86DFD53340B6E424DAD9F53C3CA02B44FF8DB9906D3D4352D0EC4B1A57A33FAFF7107D38637AA410B196BD1BB1FD7AE4B7414E1037454A031839AEE4C796BA98F4A739B785E3854E9EF0D5B7415C8B7ED012B0123C335730C7021CE8C94200874EFE783D7C4BF768538A448E76120635217727C81D08976CE4B5027D4BD9D9E27E4BCA4791ADF6F8DACD1BD3A03BE5CA7F68C2A2247FD3184609EB7243D2366E5EE4C95CDD869DE41A4B47F021DE76CF27464F814837C648A7A7CE2F91104322BE3CB1160A0D10CFE90ADAEBC87BBF14387C8387F4F5AA10FBD469ED5587EEF537106CE0F3AF4CABCD4476F248C21D119523B680067B332A1CA4C657B9DE1360FD23ADE58C5538EFFC8902281FC7B5C12C22CC69E7EB18E5F6F8352B9E4935D06C96BAFD834934618D9E6B1F60292352D064A0EEAE80F7B721312FC1B6C58D68A96351431A8626CC117BE9DFA33A1625BAECF12CB1DE33BEDAD584A91546DC767D0E59764FDE3FC29052CCE23ED28CA5DA4507933C0A7702D9A1225A48B71FDE5D27B12FDFF16AC2802E3629E10D5FFC2FCC6135243A9E2F3E3867BAA0C0F0C77BAEEF9DCFBC723C7A2BCEDA39B53B415BC21A397F9A8C4DC580EC512DE4EE4E0870DF1C4FBABF4906E0CFB08863AF2A89949F8E0FF9385ACA3F588E05781C49DC563EE9E0C5D6FA512932B7F5568C1E0FF1C9492ECAA5465ABFE125B511723998C4071481BF1C53DECD59B440931AAC640D9F78B1B40EE46AC0A8FD18B4C8AADD734B0F03F02CAF6A7BFE3DAF100703BDFADA7DBB50ACE3D40A05AE6E87CEDC0B08C44796D7A63E8B5BC95D97E3EF706E1684E791D3B3A2BAE1E7A92FB70A33D896219E80751A41E16B506FF266C4BCB4346578BAA7732CA745BCB01988AADBCBBCC45C9FA3A5D38F3F8E04005AE777910032D992D5EF9DF2C0422548A980707050CAD9DE56BCE60EF74EAA4465EDE96B055999F81A2C9596A2B35C8AB3CBDDE9D26AED44527DEB9A2AF3BF6A853FA51DCCD913876A43DA3E0E2C5B42571101B7B930840B0AB64419E1043CF56AA3C2FEF5B39CB582971A5776F8FA9696CD9F67E9290E483E9BD1698E961E849A513608C3F20FF678EBE0C778C2A6DC1FD3AFFF89D646A1AB85F005AA14A0635E92191CD41A6A46CC283D2FCABACD2FA07B7E2FF97D17B36E0B222D39DC1EB61BAB8146F147579D02A87DA08AB4ACCEB32AE1C8CBBB0EE0D90A642BB76DEF4AC8C7E477888159824349EB075DF0BED236DA9B2826E67EFF220AC84AC99BE6EEB0DA904887E3A84E5208AF49BB31EAA1552EC79E5BA02458106B5A31D0AC8AF392A63947911400FE78F6C94B3F8E6B7C3B98F6548E7894EA22215C87E121441C53EED726AE26394C825517EF8A477A6DF33B5315C8DEE16ACCE76ECA60835390E65392B9FC5EB88EADBF336FE361D190ECBD0B35B22A6FE6A8D48466B5E70BB6C5FA515CD8672BFE70054038C5893E514E23B16C39198B37B06B21275C2994EDF7F9F921B320B39E29444E3D621F52C9FCE19049D403AFBF1C047C8B065543BF43A25817533A33DE6C866FE9D8A73B2CF7277CA0E8D78F4F104C5CE6FE2025992E26E49D4C49F0798278216453C00C78EA7BAC2BEE71E5273FA46044B4B5578EEBC2A9E42025A8A3526B11CEFFCFF47191109C56AE105CD70A04C3F4EC43E49346203347319D8986D15B3C4A49F02C02994D8798499DAF1E0ADB81A9AC79FE8EB55ABE2BD18EBE18A9E5F35D2F66B38CAD6F6EEBD29AEE054C05D6F0B5326CC5B86BB0FC7CDA720838593238A2FB24E0CC36DB193FB7FA66573B064497F771DB1D965953477FC28989AEA2CC004640524A6DE8270E8A5B12BFF87B3F63FBB7DA25337EE34E6E4EB45DE9A39BC9B95ED37A6A404ED2970F9C79A7C2953420732C496B855F19BBBC8ABCBABE1D26D5BA828EB060D7280046AB93979E0BF90B6F1C07CA70833BEC83DB41684F1842A23417B3BBA0A33D7AF7BAEEC14C9C96FDF30BD201C05AEC6D3D2F539D511FBB356DDF333409EC16411DC7255DF0791BD67892880A4DB082684BBCA8B7E55B421C17DF3B68720E907C1620B142C3382AE6E738F8943CD214A847A6439A682D62CF0AE8961B5F020E7126C5DD6258CA0E8F5711E5472A4C05ADFA9A6B8180B741F382090CD1C781F7CC7F23E041800F42B228C351AA21E4D916BA5D9C56CF8E9507065D729B7C3653A8BB062C0463BF0B97F13A1016BE4851F5A489081A2AB3D2AC2744008BA734ED38DA10F372D97EA0C278C709A23ABD4B07E91ACF6A6F2DB9AF7806820381845FFBDC4BD30A503A0F74F37748E3624BB2AA478210072FCA83AD1A43ACE9F2943AC1AB6CEDED67938AF921FF34F2DAD4F224EF7498BC450A67CA383A9DDA333073286A22B85570A11FE03F55119794BBE8B81EDF1966BCA5E363C15E8E8673C94E3396C9AEC28D110408DA5561296E2928C6C111A4826309F119E5456675AAF935A17E80C0BD82A9CAC2627D6FAEBEC9A928D33980A86ACDB35686306B57D466864A0320F21751FB0041BA0F4F1660774A519D3ADB304438C1709711B982EA84D1B193D026081A4663AE69C5E12C3E4A683FB356DCA618191B29290C5DB4AA6A069C3B8D61C8B7FDA779E1F34A5F62EB7DF5C563ECF1200D3FF499DD06C2BF44A2B4254318BC402EA3A047FDB3570EB40630CF1DF84D1E2BDF5449A1F65A9DEF76954B5814691C4C12BEB10A1C006189968F37A4B236D9EE0D39AC340852EC54AA64FE15E1A4433ED48153D23B2B648C8852F3E3AE485474AB2DFD58A7F0CE6691ED36818DEADC8973E6ED06AB841B0A915425D7B87E41E1E68B00BE2EB725C287FE575736F6E1AD2AAC61F02A3A00ABEB2C0FCDB35564E8446C776E980636D5D61740AB2F0736A021D82C1D66864E5DFA98C4648CFBD9C7AA865F6C97038656C9C8767898FB43B0919BC98C1D0F6FA4D90F711E5D009D4C8FD8A773B7C73CEA654A2CD52A276C6CB62265294869A052FA1634D3EDEBA1F69DA09F0568F9D2F6C511F6BD6169BA0DE25F09FFF63AED2FDD0F6D89BD01FC5B088D3EE5344FCCC0215B6436987D6167A0F2D5EA47A984DC86D45534BAF35129488F3BC2D05BFFB84A51A87A1774033244277D0F2B45EA43500F4034081711CAD67BAA9CB0A58E1D01013032EDD5EBC7095D4BCCBD28A5F32BEB685F7901BA7A839650023B0C908FF33B37D038162FB96EBA35C2919560267EE5A94035825938D168481D8E59813E20DD611E4E23D8D42C9DE1D2398CE3CCB3DE5CBC4BB16D555985F411EB5B56508C6F4E75621304DBA2F4F1A2D8B2BEC5793478E5AA0DAE6F52C43253FE7BC91D3FBA84F8525D002CC307CAFA20BF198BD8F28CB579960A1168A1D26340C8E26CEF1261F23E97B806E9F27BB51F16102527721BE0E8B930A1ACC38F0A63EA1F3FBCEA1031E441FEF4D3746EAA37B7D4F8AB354D5F079E56FF4446333C8B8B7B589CB36DF40EBC5A75D2237F3FB874E7E0FF1B96DE43BCF229DE1FED3FB6D01752B3271E1F98D4134114911BFAC8351E3186E90DA3DE2E7FBBD305C822FE6F06ED1D4774D7A66DCA0CBF740DC277C62FA641ECAFBCBE359A28FEC48D62E1D3B6215392C0F8DB601E35A6CBD978567E806168A9F5B4915A80DE405038C4A370D898ED6441F727985037A040163F14DA78378931D3B96BA486958AE8902C98BE75BD0AED53CFB609923C63615917EF0BC6D07CD183192DE3854133F701B9D4B499F958064ADAABF4080C4A019DF1E5B98C8CA265E031B8CEC355C8FFC3BE16DC3D01533ED17C9769365D023CE7F0384D40F7B6179612B5EC382982E244E2510B4831F2D53F26B142A33877961EF1F845370CE115CA5F0D2FD6926482BF3BA1AEF3212DDF36705A210D8076A4428C7F9CAC411DE590452C761028469947BEC31ADCBA229D8EA58755F2715AF6D51E581D2CAC4182557E6815BFBB84BDC54C9368764CC29AA9AB49EEC37364F85AEB3295E60CE6DB2639669F55CC49D7934BC8566AB5E207B33F29128868BCBC1DBDE1089317088EA3FE1D595376DAD3BDD156802F82B63CF4C5ADEF9A89D94493BA152F9F07A9E9CBF8D821F1D6CD602EC49B61AC4F7633EC810F3D01D4867B1F0F3021D70897593303CFA6B5A3BD0303AEC32105F854C3DBED373760DDEC9B9E8EC4AFDAD00FF2E5A05A0113522024B86F1AEE6F250AE3BF0AF1E6FB7DFA8E04E3F9D5C876731D9C33460FDC13CDCDD433B45A6BF17E98638C264DEDAC262BB03714E020F4576DCA85DFEEBD6D70E557DF9321A8AAC519C419CA20E33DA37C22047D4CF925AD67545D04300A42B22DAC098A912848302D830E06CE5BACCACEB6E9316F9B1DEEE271BC6AD9D74927CAE725CCAD0C596653731869E8071E23BF"""), + TestUtils.hexDecode(""" +39F0B36E2780F8D81EE231CF85B28930B0876F344B4EA32F8CEF086931EE1E6B9382AA19FB650AC81A2BFF86453BEFB33BF8F0FD8E0FDA5737D7C56E4D9427BD1E802930F500594396F98A2C574073FD570D30666F5C067EAA3C88610A52FB0F6826CD12BCE739EB685B3800B3B4E3833DD2886CBF4587CF0704B2E72B128E43183F5A5613E8A5342C123AA38FEDD3AAC513432A96AEAA598AB9DA0789B440A4F4AE37EC090144670E8E876D83A39E0569A1F38159B8128317216ABAE8C5988A396F2964B6BAC4521E1E35B4C1BE3A4AD1745F718A1C74B260F462567146394C5190A3B6F724BE2804C3E8BB3FE3587B09F22F3227A2E69B651F52A32F62693E212B502A5F7917D17BEBF20BB261D554C966418273C6BDFC51C8947BE2704116BFB1D1657D5D82E676DDE05A580F048F7E111A3D632205FA52911721CB22F937E6241E1248F1A6E10A71C34932DB75A4878BEDF3EA3E6EF5508E5CD691114192DD4C44E6620EABF1DEE4D09448680D84C6117773D240DDACE06A2D925920F61A0AF12B6E64DB0FEEB2274EA1238E22BE017579792F2EF95BB55F6A23D18CCE1D3AD209B6463370CFF1F8278E779A9A943B5779A99C971F8A3794CDB3B04773C9875D82D9B72C39368B1FD4FB0A661BCD31821ABDCF4CAFEE9FD959285FF15B9FF8211619638EF4EFA138E44E4EA9F1FADB550C13EAEE9828A34BA911D4027F38FC0B9D0A1E788A6B8648C63A9E4D6AF974F87170333BF82233C199598D7A7CA1F90816CFC72621DC36FE881F25BB86C67B9B59DBB02D78A1ED003193ABB5470A89C8F958FAD2D6491ED121AB9A02EF470099D42FA37174052E231D4D988707567F319D964B4F0551EAC4CAB4EE069EB8FAD6BBC4A9F1D98DD8BD73A5647F64D4535E8FAE71B53902C917A9D286E014474E4B126AB17C29DE31ABBD58CEB1C12669FC2EE50042CF30BA29F08E97FBEBB6059A458A90EA6613C7F76A5AAA9DDA66D266CE0514B0B0442694252AEA4ECEA14CF5C90A8BB60FDC56F865447BF29769F49E79751E8AEDA70CD78E29154D688558D1F831096C660FAEF3EB1850DA01F2E929A6432CFE9DBD342D1CC234551D6301B6B61819CC487EACDDEA62C2CB8766E2C7066698305CA924419C8E83CB1D68527E923700EF7C5A05DDB511DF15AF11F5BCBA557C815B95001E0F57E6A7B8798133ED1AAC2819B10A8E2E4BA69606BB148881A2C23D3EE0E981551E02EB1ECE320B6BC15AD1EB0EB2FF3FEAE63DB0AB4C2F315E54F047734833CD380DCA1ED68FF1838B09495083457B07D93B8607217913D678D409C1ADCA9C7F496FCDCE029F2F4D254CDFFBA036CEB59D15BB40B4215397DA55B5480EC2DCAA221D4CED195DC440BD0B84EE2BA5108F46B7E24148EFAA6C2AA728F6CFF1391B46C36DE741C7C546A0EC22776B9830C3165D2ADA141F97C05D03D93557BDB24012C336CDACCF8CA3630064460C12251ABC89AAD06478610B8A2BAE5380E65A2C449632EF9A79CD9AD8857BECA18552DB913C0C79CAAC8AB166A1ADD7DE272A796E72EA53E23582DD8A00F554849B9EB9D77390CA41B04F6A0C9BE3C3D0E94F9E3DC39BF1AAEE34E910204DE1A2B3A92557A67089B912B676F93884D4A6411B89740953E1F79ACE3407B2252DFDDBAB75276C10EDD534A9F398E51CE9E36469C1DF0526ECDB84B07308A0D5D5C520D028A8E30A193DF746F0402D160A4E9515CEBA20655979124B1D6F5EAD8892D9F1F92A0E1A1DB0B4BB90892F569194E088E98C0C5FB93A108F05507B29A595CDA161BF4D97680D6B0D4428D6A74B016509CED3B635B02183222B79598B6342A20DF2269E881C7B121889C0751462D76C5ADB628D26359D56F8876CF14A71D330D03361F63E90C85CBB275AA78C15293EDA0356E9DE2474ECE7C49419E15ECC5EB8233DC8377D88316AE846BD464D292B91FA8B3319A28EEF4D678F0DBC04687C7C59CD98B694BB15DB7E18F4599D4F2806D0D78E80984C4136EF605FBC268221E7608ACD24004CAD8F533DC1BDE1D3CBE0605A69E828AA13210A07001D60B8EE2DF19D5AB8D792F3899C39C9AA1B82F1FDF9222264F7C3EC8B756DEF951F20D1622B23CAE013DE6CC95B0F39721FD46A64B7134A602E0D9B6B19299A5521148AB61ACBB878686C2020663EDF3652CDB93CF4E24C8FD2AF8D0167573333A7DAFA1CDE08C253D523AF9F944680B97BD7BE2196870A754894334A029A870F8FB342E53BD3F080657A4C5A2DB603C9F0F3BB341AE936A2B9356A73DA67AB54AFAE131C8FB0CB73EA10832D2094D014C01107FDC06177FC3884E7F788384E8AC89C689B2A2BCE8D6852C8B5BE520671DBD8447E4D78049E1EE50663A609DA79725A3822DC899CC87224C115D129702C7573B45ED58188D422C510381BA3C77DB099B87C028C895DDC6F60C148CB1CBC60CF56C15455048AEC096CE78B0E70F8C8F1694CEB365DB8FDA1F01897247E632B30FEA0F888EB49D5487482B367ECB413856E8630841F811BB1AF14CD26DF29DFE7238AFF1D169804445A74BA5F9F96D9EED27BA70AA516C1BE7DC46C015704E1BFB42F0CC44456CAD7FFE48B62BB8BBFFE5C97027BDDBA1E83C027DEBE20A908486A351F077E627464F6BBEA0AFE9230FACED923DD9DF215AF123D8089B467FBDEF42C4174156687ECE49D87C0F9711592D2469BA2100A5286B086C2FBF47A60B864FC9628CD1977D7D8D72B411D2494BFDBB77543DF4B39664F7B22451B8C7244008A3D24DEEED0C9CA67DAD2D56F1987313B4AD33A72CB4973B6125257BE3295682A3D0418A2251D71510F858F65840149C8335BD999C55E51181914DAF055DA97746FA5A80A7019D9424EF0087F38EF1491A3861A19C87452E05BCDAA61CF148A84507B043AE4A42FBAE9359842B0CFE70FC17DA78A754E3D7A768469C170DE3AAD692101422C00C0F8315BEF3BBDF887E75E5DF7101317CA4F8C4D365B56A63A1D833B5D79BBA1812F3659C377BF9CB4A913CFA504E0CFDD1FEA0B87BABC132F81E9A2C7FE0C6E6D8467BE84EC5E21E0A46E4759A5267E6EEE4266A4EA8718F8D40A1594CADC835306F88E2100AC444379E9EFA4B3FA0E690550CAC00EE4633687DD1FFA748DA3882ACC6CBBB2EFDC0513A25B31361DDBECF5ACB3C488AAB788E63A48D556ADD74B607CDB8DE11C7448DED000E8665EB75BE788AAB14C3E958CC969FE353C0137924941951BEE553FA392DDD5D7FBFB8A2A8DB5FB0EE58D08FB5ADF617EAC526044962C599523981AC06B60E1A6A34ED97B80949DABB6C9D6D8F1F4FB11222632456068798995B5B9E4E9F1F4F8FF10161D2B5D636E9395A1B2D0EBFB1419202A2B383A424B578592A0B4C2CCCFE9EBEE000000000000000000000000000000000C1E2C40""") + ), + + new SigGenTestCase( + TestUtils.hexDecode(""" +382FE71D7DCA3DA9138076E84FD5601E999042CBEF87ED4A8B5200087B61564E433A8E49F18104C7A7158AB1D83044AAA46F6511B361326218771C3F99094F9624AD27D16068D01BC7BBCD0B5448338C2A81FB3F83B2799A81EE2610C5534CFAF09100FEB0913F2DE35DD5C21DE040A2E8B6FD99848AF401BE6EAC45DCDAB38AE1442E88B24C2233621A187061C4606390801B272A133450042331A4300994204D11464404242051C48DA14649DB4428C0084C84304DCB8244CCA84C13B39018150DE3C04122160400A6252384511A28221B136E2049715A04222112724B4889993210E3A42C02147004B06920110918352EC8B681614400E320324124321CB47083C60D0B970451B8101A3268E2A84951C06C20926824B448C9902922122101252C13B70099B02519A6410AA049149069089751C8006A1A233142168A620428D3C6900BA544A234251484605C48324B384E19296661286450A409DA162A9C10100306019088410A0006C9283020A44808C04920B78DE2886809A64C1A030ADA180DC1088962384D61842C91180D61A649033672C2A24DC2B02449260540006948226512C50C08C36D54224D244368418230D3402114285050366C4A446D989604CA90605A162ED2422241129048827013A2815C8025DC12264396499292281A042D8C800100262C93025192A288C2B29183080E12382262406D14436923112E521480A4187280304961863182224C92486C60B84808C30104280152084A1041520939664A328A99960C14430E1AB46C44C00801C60C128024A390104C0046048069E2C260D2360EC9C82963962D53C870203311021568E3222453466C410891E0883008266E5B386510A991A1B88454888152444118A81093004581122C10224E1BC909C04406A4A00414C401DC0286CBC645CBB889800885244945100871990804CB382512359244067011406550483240A009E0C20020244D82A20C81360514460E21C1494A442D9B343120C85004256502B59084B445542489C4A224122225643862D8B02584A005024828E1C625E03462E19221E03452DAC2219B38311C113293C80D612466C4024DC8026E240582630248D1140A51342960A82C2093891B496C519010E102654CB0251C096C4B18860B35421829658028696080296012250A417081222990A00950C041C0884448804D1A182820A82C22806D099501088670C9120803272DDB208C1BC92C62128ED98681CB067010C7498B386D9C8005F34E25F7A1DA3F630CCC7317F25ECDDF9ED98A9E07707DED49B04D35168D0ACD1EC48A4A92EE0A9B2AB5B84F7F3FD38F399E54FE65FE2EA64CDB121AEEB6EBA1C0D52580543B76E82C799F8ECDCEA58DEE9CF8E24C1B08C271B805BB729C7060608B6564F93CF8DFA6FDAB6F7B6F483E81C9F35E07C061F88585B86F7DD9E62CB027AA2DAE58ACB5C095B23661FABE88C717A46223395B94A972E3CCA2FD131EF052F7C8C75EA9B93784893E354BE0E4DB252C36AD03285A7FCB33A3D53269D20EEE2C3E6C0D74C91A2F1B35510AB2E7C4D12F0C564FE96090081A76B9163DFF22815EEC4B7AF398DCAF4AC6A39D31EB3C4674F7D007D6C04C95AC37C4E62182B0448CF3D10CC25823463A9808F97640E378BDB17EC0A2972F5F70812625EABBF6F1F93B566E36D2CB3FCFDDF94B3DEFC1AB168DAC4371398DE157EFA4B1998D2E19B4E9536038DECFB279770CF87FEB7C0904DDDFCBEC1721AC33D837AC7689676033D6D556DC70CDFCE1940CE25D69A961C6BCFB4E16CF42636B5DCE6C0F736DB467C39D0E4BBD0577F3535E7A47D3A80010A5A96CCDBA9C89CDF7894C43B19EEEE86D7B248E6FE89F84D73F76DDEBEDF18BF3AB9F5D0E69BDFB35AC1AEFD64E64488711C95D132029440D3573F1DE86EA10B9CB85241735112D992319FE5C28EFD072D2808BEBB97A75607F2BD0D62CA3223819F2FF26F047A5E1283C39317C1244CB95CA3C91C752DA2B1B36D185FF6B6FA6E779860DF82DF8450A2B131459E5C437B0FC44E49A9C613F8CCFFA188850E520E166F73BE0F978C8E770E88312F8DEB9FC4F93962AE579B2371484A6A7E09C68DAF0E00DE46749AB332791745294C3AD193FBC533E56A723D230BA35DCD4308728014FA998C4036066238B50D5A4381A1E46BB6CC2EB3C4AE4A43BA3712462D7A842598A1E5A7076320194C57BADC732197DF4A8A1E9455201AF865FCCAA674E2B427F7B3D35F9E66D1FB56CC690D61C7EAB983D3F31EE3066D0CAF61455B185902DB44CD2A85D6BA2D4B97DB516AE75CAFC855829E24160ABA921528CE718E10023D84EDAB83D42CA84E4E3B078218C44BFBA356F1815F927D61F2EF8C46C4B5521D0F8971D54E81BEE1FBE150F3B303D8668C9328B61D68ADF26AE20B4A38C4A0DD62A5B432ED1A3DB945003FFFD37870B5A514FED603B5EC54668FFD29D6DCB5A593DE0852CBBE4376B161BD7FCD8CCB8F60D453B68510E5705549E25149A1271A8093F6084759F47AA3B5D32ADAE32173B7B0DB4DEFF645D172BB02F5D2BB776906E1118167F3DCF7CB8C0AE2866344A59A9F6C3687CA3ECF74884E632CD63B6AA193DC56E087A67782B69699525C53A35DAB992F9BAB1CB098723BA2F1027E72BD20076AECCCA2BCEF8EE76ACD195380A34B934B44E642BAE00DA4C1ABF7174CF0C0A353F96F27CCC2B6281B7CBB29222E9F7067646F0D915AF86F90ECB3E9AF2B1D7FA2A233A5EC015C6268981942E0DB8E1F3667DBCE020907148E61B353D505A3077626E56B8FB108D90A5922E5259387CDCC49D03D1D47E3CEBE87A752C7562C219C25F502A8716722EF7CC7B4AF8C33DB33EFCF2B31A076DEB28A410B8162A9D3F1042E1AFCD5A9DA472393CEE28810C853DCD94F5590F2F5D9888ACDDF1FC78DC26221CFEB3EBA97D0AC4B2B2CABE0BA52E6D7BC29738837B7DFE5A2236AE31CF61A449186080519DE388F1211F6BC81663D2AC7A4BFAE83E9E64BE6EA7DAFCFA7C1DEEF73DC6F9F9714626B9F67F292DA66D19B6A5CB4DEF0E870AD09CADEE4DF12C873722521D191EDAB644CE9EF6AD93CBC951B8AE64F741B6497645E92A916605137CF73C5E30CCBAE5DBDECAF908C16543310C592529819C926885DD3C8DE66480FAF7DB079BAFB47BB99341EB9091AB9E9A0CA721A8144882154C3D4DF29427042F41810DF2BB8D59C5FCE38468AA8328A740068843F7E2C911990C9B2CC9C8E3597F03502ED2813587980918E69D4C482F040A8B7A09733BAB73E581E7DE74899A5EC59369EC1C112EEE0073E1320B189058ECF06DA8E1B74A7F4FAB3C77E2CB93066DA683BF9C6DBDF4E673F11F446DB7AADDCABCCB6AD68BFE43F5AB8EAA5F8C737AB144E33ADA994E5F38E1184A4CF2EF21734DB0CE019F114D02316703CC86BC12550C1CFB863C1249D9624591ABC9661DA47E2972231378F57D27F5C1A6B0ED2303DBCF69A8E98C6317929C6B092E1C0973AE4DEC65C3F3B59EBF6AFAA60C5121500EE6B4027480BBDFABBAD8FBA8ACF4A23AFDF667EF95B6B60DCA6A39C688BADB1DE6F3795DB7D4D31E882D001087E81A0B7846C7D0B383D6E85DD516E37409"""), + TestUtils.hexDecode(""" +7EBAAFA6D04129716131907EAD0832AD490D09E97D865B4AFC5D6B0FFF4EDE6A52E961ED88DB60A325AFF2675DFCD6A87984884AFB8680DFA7378130E44F205398ED7B83B1AC32D2580570FD6603827E8E4F5E20A27758CE6D1299BAADB8A895AD586BDF7B64F8D7A52BC15455EEF240F22FE98CE4CEAC03CDF7E8A983D7FD1A59C5EC594474AE77DC43EE4E7B25C556BC1D91ABD2015B99B1AF5329DCD41B93793D791A44AF5D83DABB8E40675EB32120C57D9E6B7757D3E03008A2F788336B8355AD2E47E61B39BBFC2229D53BC9BA514BB20F3F9EE9266BC0015FE81980FDE5637B3018046DD3D4BC3D549EC394E190F1BB788619CFFF86C532B4B9F0F6F951C0ED691C59AB0CC438290E9D6FEC9E75BA4FDF12D2BED2CD988AC411310BFECBDAC48A61099CE0D0CE4B44EC9C97108A44E5C5EEC1D3154B4E72B8397CDB0F7D15AA358076E25B7F3EA1E6E80A214051C440EC4189137610450144641B1E71B5334F0DDCE9D5CA30274E0237E45B4D92D7D458ED9142CC23871E56411382CE40D9CA4358B417261C2E7E845637FD2E9B4357E7EA5F4A8076A7C2F40FF1F8AFABA5393512F690EABEBFB73811B974E57C2D473AC22E747A0EDD39E99FD6E5D3668F3DCA1C795CE27D1A155ED9595EAF9061CAF5C55F3EE97056AF6ED90E05D41E90926F69044746230C990118E4D0BE4C12F7A4AA0464F8FFA7CF64C07FEF171B2E43A917AAC2880675F929583E9040BA6FEEC8262002613AA91A2B8D4DBC1D36F23FA9248A2D3ADB1DC5AD669EA219D35DB17C9C25095AD7673445E59DA6CB2260C8FA57639D6BEC8AEE307BD9C96EEF00C93318DF7DFEED970DC1F61AC5C94D4086300D91199C90C95C1A24F7F1E4292A60AB67F30BA990D58C71002D3548A412276DBEF3984FAB312723880ED479080EEE2B636ADC75AD4423A6E0C5CEB7EDE528F871FAF21855C3164469B9EEB47B6D37CFE4222DCD0B9867B00BEE12C27590DD77C24FE640DDD34E9138E70D15F52E94F3874447CA5CEB48573ACFECA3554E2B76CEE4E31060BF132CED8AB953F0A280F7916810A107AB5BA66047FFF0003B1CF13BFEB77526265B98E54E76B891A89F3AC0ECDF71406674865A0936BC57F87B64424BFC8FDC41E471D951077C32B5AF960457E97CA05F3C378D94B60A9735E9EDCAA96E413FA391AA687FD07D9D021B1014CDF241E5460DB08D3B336DEB4CF0AACEA57E4DC6C464F698CFC2AD10CA72C102A25787E0B89249F63406A39A2A792B2DE04710C41DB36B55D2FA789004E593DECE9865771D8B16B5436A792FBAC9934852B1F55D518F9A07CFA56BCF488D61AE355D63BDC27DDED6A56154B8BA3AFA3EC9C01D6593C83C315527F5FC61BB169723346AB4075D09701789268EC1F02EC4A1CD8A5F2584E29F126B1ACBEEF660CBEF16A8E9FF9C0B542042EA76684F9D70F2E3F3C18606ADCB1D695112B129B301008EDD5E6121A8948E1165D350FF09647DCCF4A1F8605ACC750A0AA8319A6685153A7672B31A3DE785EB22E1D223D6271282AC18AEC83C760190799F082D7FB0F238F627271BE62AE5A36A34D65B5DEEAA12D6B14B59BD0C619D8D9A44238AEF1FF83C30118039E834F7716CD59E138E2ABEC2921D9FA92F6808A760031B2157103FD2EAE988AD6CA4F350F488261409FE91B5667A9A2EF1E226B8BFEDDEDB84ECF993E9A71220E0253D2C4B918C5521C7953FDFA00D50A32879FC0A68D2AAD13EE181DD47DB9E3D715574CB3D566BDF30209297B01A666DD7DBC5464F913599086AA2FC6C8541592CEFFA067B287EEDBF4C9B9D6CB23CE1DEED628935CB2D6B5CEFF3BC442B2BCBBEFE4AECFC455A3A64FA117CFD9289FC27E6289750005877DBF64CD562E2E7D1C99830F5AE63C70685B3898D420862A8C4569F2CFDF564EEF4F94FC34CDFEDED8854855F3A4E52C612258DB5EE4D702BBA98B450D070264FF86A440129DA2C126978DAB3341C4079A66F9C23445C5938FA799E78F157656208BA7C7BC7F936AF49D11148856BA55910A6A736D32E0974E50BFA608975E37AC0601FDA7551204EA66F524DD03F44F5DA28EED5D126C32794F1CCE747DC1E9B1FE287CA607F81FE7C795C96569E66B2F3413DA810035D472B7F5AF74F9CC70306A8EC36F1383617D0FFD92F6DEFA7EFE91C840EDF24430B197802979752FD55A8CA85FD8D4FCE774F1CCC540F77C02E16F1494DF170CD8BA57A86BFB086349D53E8A62E1DBDE03369757EADB0E985A038B31DCBEF513D4FF9A3BA6E8338EDCECA7C3E9417F9E133BC399F2EC0C72E60E809F79D55FE1A917CBE28FEF19D6D08A43F74DF496EA9305072C90AE3BA0D21A1AC0BF040920D3F5B8703C12A32A6864382E9CEE8D00CF4F93830623E76197F7F52309824B08B8E0D5DAF5662A36981D50880FD3A8D73D24430A1CB201A9D0BDE656593B37B8EC47F235B5CA251249A04507DDB81F8E5E4E5E414B3750AB168BA51A8873E6ED153E302F61F7159B658E316D6D183575D87ECA30185CF72C67543CDB658AA07B1DB220032DF80D287E769E3253C80F43570AA538EEF49F45316E176F1F9411F3C085257C6B8C708DA7B924B792389A7EC34C7F778E6100333E8B9FAE75A4D1A32E306AEE36D29FC6823399FF37CDD0D11C8D03F14740342B736C4EFB5302C141A86C857309A70BD74DB6C7C29C839F8D86F2A136F67A0FB3A3749542A9DD8D4A062672C75B67D3BDC3FA6B56F3E79008AEF8D8E04CC7781B23D0DAED64CFD1A91DBBAA2C9C4E765FE2FDFE6E8533848E51FA027B86AB05A0530F15C1B7B6BBB268F09A7865E202B1645F8B4267CB1A49A2929410823AA9B834101E9EFFEAAF6E406639AF7D2710E60A84B6205339B0719E05BC6724FC2892A017AF86D80D361A7FEE8C284CB84F5F09B90CAADD49CFD396E6AC36052F5CCC8E7667CC762A9F173F837A231D57584A3BB19671B8B71907E415A1672475ADFA11998F94F28B00903AC551E651A3F9485DC0ABA3297E561E0B5A5786BAD9EC8169CBD706AFA60AE764BFE01EC514623BAC6C4100F707C5E8A02F4B0D6265502AE4170AC3EF95B49ED1A2BAEF56F63D5667C9FC0AF4C0A8648FB6AC5444EC8A1FAF4715027AC9F5987735D1AF7C55AF4C838FE9FC84FF71F929758DD52E2BD4A34237350642C0E641B6710A66C9C1EA1D9BDA80198FCC56D45D67C3511BAC0971AC9B6166633B1713A969B8DBC3CF60FCD6998137AD713EA3ADA84169D49FBB7F5CDE362ABEB0B71D022D9ACE7FF48C9EC1A7E0C72B564FD2C620272A482941443838D0506E2294B760AC9DED5404D3C4D2898315D3E3A82D2E944D537817B9901AFEC343B95F2844CDC4AAC3836E7713739F4201B95C42FB7C99AF8667628C1B60115BCB185754148B3C7226DF14B6DE1AB4C6043329B176C9DB9B1D73B3814FEB89E84A4C91C84993752B7AD30CC707A71339E8A277A5586BA85CD090F799A6B75523A62C6DF1549D787BD8722D1F26BC2C150D6A38951F3014B83DE665B21F5D9D97F2237333CC10A4114796D56D13D643364306E7445F475729602A11F8BEB002BDDF30E579E26F2BE4AE87DC666974E24FEF2462120B6CD8E79D65A2E80542A9240D4EE1F616326AA528E2A1282EF49F0312174B67D40FFCB1370BAC5D1444D75FBFFB6B0887F4573A8C4622082E1FE349B2C73CDC92592F684769FA7D7CE6FB5AEADF38023E51DA4EE3EDB10368442B218919341FAFB22EE80DA96A52434B184D499A4C49317C62F6D6DC9EC1413D01A1CC3DC8853444E52718798EA158A12B72AF023079E5E76F41AE685494E947618C4AB3036ECDC74F7A043230A0BE116F2B617818A2C94C54CFAC964C73BEF969591A3CB2B7DC9CFAC7B4F9B64AB70BD7FAEC138E42908BC90D6ADFFBC88EF473CA8CE7BC960C4B3EFFCAB92E8259CFAFA85EDB7832B3E630D6D2CF031B8CB570E38C101A56B426C654464228D152ABCC6DEB888DFFD7FFDA974E60CCC2AF7531F38A813E263D9B20DCCB50229E7D8F379F81A280CEB90B64BA3657F1E50381B468D0A6608A4B5E107C4736FB4CAA10FF3045C05453EE12A9FB0B79845E077803C69CDCBF7CCF7D6FE6067ED152F67023CAA6095D1748414580232007AB3426FB2889E1BCDDDBA539A2D79CA523A2CD1B1314C87502909DA849BA9B11F9104772BBA27410018348832B0BFDA4F09AF02B351927F2B6D29D9CA9F330266EC035908C9D4023CDF2343B177F57903D37AB89D0F9E23EB0C4100BC6421235CE5FF2729C2ADCAC24D1151757D8C6D6DE53DEBC38FE866142D1BB593974F4D3198C03DE4625F41BE3D488575B25007C2D5970BB152BC1C23E48A88036C070BD38604C5844E4205F1EF3D7FAC0B4B9FB51F229BA322D3355E458C27685130FCBDF591C0520626E5703A2E85871A62AF0CF2DA3468C401644656CCAB33B2402074C59A0EBB57928F548B5FA4871A8B2AF0BFD9A871A5C257044C17E4967B70D0DFB59F1345526FE59B4BD92A1C06B15E3A6226A4821FD614D8DF612A3D2DDB2DB67BAA3878C68C16645CC747BA9B366677541171A9264B89EE18D9D169D341629393C5526C28B24CD4CFCACEA9C42DB2B1CAFD7F906FC17CCE16612B1261E62E2A700CE74DE73174D3A1E06AA31AA05044EC324F026CD39F7B13399D9D86EEB53A6DE84914719EE31AFFEB630F3D8F08B4FFB10016209C13BA2158ECCB4B74BF04EFA73222554FF5EC49709F7F8DC1D40005E91245F3A5E2A00B9F64678B2D8A9E6BF1D011900D9D12F7F3BB023D1E5985BF78F8D6132AF5C0B9C330F361EDE00473DC9EE7469478FEC02670E8659B643B92C5546C32FE7B0AD816A5080B5E3867DC209EA15AEB4B14E42AD58F34CED65ECB3B519A54BC25117EF8D392A85C2895B5A4B73CF93077E360A828570FFA02ABA84D6534F3EE0C935D97D1D1CFABBC0D82E48937797FAB31704588605082A950CAA23D6569AB793FDC31BBA561E729E80979DAB84ACD4EE6B2CFE06D2EE8C4183D33B9F894C6865D9CD405C7665E0150B2B649159BE684839BD12CF0091614E1F821046238DC9F538F769FCE51E9B8DEC0E98442CABD3A4296F1D4331A16D33CA356B11E3DC13937F814D3D6281A746F054606DC52B737AA40422471139867624CC8E9C559BD25C7C6D7F902677A84BA63E8CB817820048C1C0ADB6288000EF2163B51ADD4D758D1C87FFD574354B41CA5AC72228A7E9E9E75BE9DB18FED47C32E3C561C972A67D50A560017BE794AB9BB6B50CFC43D2F6D57E8D73CAD6227C896BCD18E0D7087F57C365FB9EBF5864DFA4A13B6B5DD7FFFCB648C1E1FE40B6A10EC0C45C74504CF2105AD443DFAD1E306F720B9CC37B4A30198D3123FA9FB2A7A9DB3BDD98D441B03E0EE6A8180989E76CBC71B0E8607C3A9E5D20B6008B010702FC5D59847AFCE122F3FD4FB5D89D3A3331AEFB96B593F724C04885B574A43B5EAC70B543BD191BB818768C67A10AD6E2D62AA4C65FA373A19116AD86A4F9A97064E0C0BF80106DE6654B4A3945983B7DDF3AAF1E14A04F6D3035542B0F710352AFC20FEC78B61D8548B9669F10B3D6E531AD07A84C493264DD49759D95A6AFDBEA5AED1C7D7D2AE6D2FB6747151CB6A5C2F9C1AF5CEDBD9CDE8D5993ACF080A0008BABC759A9DF035C648609E610F226ED128E2656A057862246B65C70774B68F54D68073393B85110285FB463DFE394D9DA0AE85985FD6882EF5B11FAEF2BAC18F9D9D9B5CBF0F80AE7AC4418EA658D68B14BAC135452DF271DD3348BC338BC6C789ED95D5C5625762E4CAC6514866613E6D533AB9814B7C337260BF16716478401689F4079644DF4F734281C16164D19C4ABA20ACCCDC517EF42C19A5B1CAA4658C27B61902ABF88EFF0795D2C971608B0570E016CA0568CCA3F7B38FD3DF5608154A33C1F0D70C2AD0EBB134A8F475A8BBEC8408D3B9B0BFE8A6F10FD6C979B13C3EC73F191B788A79B4D07AC45172950689584C909247DC8A4CDD686186DEA16676851B8A7C311439149B1A963B0CC60E5395B56ADF27C25A51BB4A2FB19E14CE66B6D11781E89B3EC22CB854A12D46970D1A009AAD071C479D9C731770D666CDF0BCC381A3D328542F6371FC6F5FF7C4D3BB06186C048B2A3774EAAA3CCBA1342927B498F2195213326C9E393153BC8846AFE2120B8FF4A455B59AF6E65BC0CE9CA3502BE73D74B6CD12A760A9E0E0D26BD105FD993DD879539CD666CF2025DACD481A122627594CAD7C4FE30948412C1C6A160C358E16B6B67653418A22321DF5B1A9EA0DFC3C82DE3B8CB0F48EEFA7DD6188023D1B8B7632270E63AA38873A2C4472F9EF1E8DA56D5328C00548DDC4D9FD79115C5F6168AA98099BA1AAD606FB92F8D253C9A55773E5629E84350F3BC3B00D803E83CC2516C6C29476018ACFF2ACF61584A175E67EB8952885772E6C2D7F9C2B79C8B2F2A77C73C8B0230F080DE716B2A13DBA5FDC8648F17573A2898E72B8850997B6085F98523F00516DC7A90B9C2701BDDFE505A6C330D1118AFABC731A1DEAB813AA0E17708122C0069FB61A02FF6D5EFDA990A23E1D42C520CF1975FF06F123E1AC0B0A86FE666F8843C406F5F1E1A36FBB7A0B41CC641EB49416D6F0AB03CAA6AC0CE3A3DD1977B4D16EA33CF75A37A6092003D097D0ED8FAEE89F761B40F7E600FD502887AD90BE4BA311B9F4CD9D348DF230A2EACBA3FC356B506ED8C357E228970A948FC4983AC3ED9C3ACC22FBFF56783A73231F7E0B91DFED20E754ACE7DDDDDCEFCCF3ACC76554C269D634DC228B38C284AA35C00487D7873C8CFE8E8657726FA845863719FCE5A9E32406E2191B791F76DA035A4C862176040DA9AC0F37E66FB84DF89CAAAE9D8804824725FEDB95E5380DC66CC72BBCA1E131E6B785EA2B2B4A05BDAE01B22C3D47CA85092802A8EAC42E963A62307476FCF94ED7EBE5538A8C6F28A6C65914CF48299D3BA2B89B3008D29CD874B79A72AB840815827566E50627C2C332B1BC60060BF2FDA320FB040FD14D52CA59B24E325B5783BA1BDA3B27415C9DBDAA01562466322706CDCD0307C3305DB08D2663C57F6D3307E1C73832F8CA712402C7402EFEE0F1BD77CDA08F5F6582540D34F1B2809F84EB2F540558EF9ED46D5C636C45856AE57FD9E4650359635BE72028D1CD37CD876E0DC598E360CAA1DCD1F9F2BB4CA27CDE012980080E91B1C7376622907BA6674F1EB9E80148E6A959EC74950A2B934D42B84D739F1DA528F5C6E1C90A238E5167041D4E9AE5352B74C89DAE368778A90170461ECC0D6B6C6C53CE36745A72F79AAA1C82D494BD89D719800A89127BC3FD55247C1A29FB8387F1E3576E0C45F4D327C0B24A75FE25EC6147C890F25E50AB3C43B94F451E5B5D67F8D3BAAAEA1FE211FCE8622600400F73C1398459EA7FC59D02582C2806D01023D84BB50E99AE9ACC217B7223EDAD956FE155152E7F35B2AEE1535885EC048C6E0C50D395B0F1C9D767048E9D2DA7F15BDE192C923F1C74ACE06600628602D1B0189FCADE0873880EE8544AF3E29314E2B5DF87BEB5A50ED72FDC093800B12CB2F870304289A73A65D7E2384EF3A388EA9F0013B2B5C92149E2538542D95FF020A23E976A7DB3E2C9913D87D6EFF12BB51EE298F1D2CFF18FDBAEF56B70CBA35EB9273F1E58A6CD38F1E682A759FDF8D8BFF60E7CBEA948E25DF0114BEBD4AF13E4E0D4E7C9EAAC2C5F579A1AB14E7FECF9E13F20DF873F8D0E090905D32C8F8C0033F5D8E9F1B9FF17EE04FE3656EB66F5E4777B60B047DAB9BDD883EAC31A6455D1719CB475D1715CA0D12762F94AE78CF3C8EE90E55E71D0AA4EBA6216A0E81566F7813E7759BED30860BF22178407783B9A8AAC30CB4D53AF140E33A47ABD60F33EE700C323277E751E5B32B221E4B9815FDCD400DC544DF845619FD733F164937144FC3D89D8186F8B898418459811B3E66796DE51D1373B248A9B3B9609FEA374784A33989FE9F5BB26D2148F7282E09C35E13295D90BBC7795DD72CDD4955E9D148BC779AEE9C7992BB85D8EAFD102FD690F2C679CB7003FC4E182678320738361C361747F49AC6149CF4CDA4B80581844F5EE4818BF61750047C35A4B10697892A80F07E946F357574527FD2D0187873BCE78EC99062C70CB4ABB72A104A770CD7ADBD20894E7BCE2874E45302DC0BCB9645EF28136F36E7B179BD003D5DFA68A572BEEBD40EB9AC1F9228C74A788671BBF4781AA31C7F8699813F32EA8B60414C3ECB894DC7B01E50924482E5C068F0BCA79BAD9F469770FBFCB3942D1A3E54250E87B3693329479217514A8D7B734D256C5D28EF854FC3F234BC671F5225B1DCC20E590D8E5D09C07B22EF0A89A5B863C2E652CC0B1623579541C63CE9C2C4F66BC43323D7000BBF2923F5B8A76933FAF950D2172C1D90F522301D9A0C22F470EB8673CDA0A1B494FD7EE9AC1B4597B2DBC26FEE33A08CDF91E3C59BA4F93E02D010FE3F1C1FCD694F05B7A8FD32D8E7CBC2934A25C481D9C58FED7E0AF3AAB527D6DEF43D53756F0C95B2B58A426F7F61D09F4FBE55D9AF053B92818ED9FEF1CB41FB5CA23AC85B0241900F73971558116C5809F565F71333713EF5BE87B0AC95364C9FAA80DBB9EA84B5A5790D20343141093F86942817D195ED8DF4A2DFC7F7090CA3DB46A92AABEEAE2D7DD8B9110F23A89E4FA7B5A1DA27D643BB879888A2238E221E2F67D9DF58E73C46023FB7E999059D3B81FB753B2AD333207873831AE42FAD8092AA04C0E4103B1CE0DCBD6B06CC2F0AB37CD1D10EC4C83428CDEF84041D12BF9ABEA5C80050A853CC73FFF3076BEE68078737F6EF483F486215118C640790D0CFB4C6E5243691FB73B1294E0D3A494A4A538B94FDD2746193D9FEA24C1C04F5B20D2D40B638CB932C35D953A9D31260B76DA878FD52EDED058D1DEFD9CE214D14C3112FAB00B7F2DC88F7EBCF79EEB1C9C8607D6919B8D32CC8416E2B981C141198DD9884DC3927EB0192B6361AB556EB3977E5E242E5E26BA60BD42892F46F3F2DF684D0D9FB41BE42C04F0C248938AC79F110075B42181DAE62801DF76AAB50AEDABF4361C0EC597F31245B0390CE2629DB933E450E09DD39E6A1B644B0FF672B52ACE2AF52780D3F6505551F52045028C4DEE6D1C6A34BCD5E95E9DE1BCE849643BD07E0E6FAF8B27504F859D73BDFC07FD2034595AAD85A9DD9AA5B3A72346D6F3C4B21C4CFFAD8247C8CAF0DD9A708E11450502BF3C28EEEDCB0E1D32D3EF1A3F6237E34C0E4D0222F496839B7374EBB7D786973E85392AA8FF2A9901D076DD4C65635286276698DD4388F867D1ED18650FEDA9B03C80A3B5BD0AB3A62A45ABECFD55898BDAFBA58137D4BE29EEE8B3B3D1C4467B63DBA1EFEF2C81CDE7CFB101B1E65084A0E92955690C8CDE6F93E23FD79B76DB475CD24DD92A7504510F8DC3B22EBCD0288B4E479F8DD835297B196531D2DC759364306EB6780FEF31C9E34142B55988F81312B310093F77CB89C6E819A7CD3450D0790CB7B5E33A3E5E51DF05A3BFEF63320CFF072D450D71E7239AB24E4D83A8E8E501A5BDBB041219E15517B15EEE237836672A761D36D11EC973BAF65320B368906392E2689A9936752563172B3A5ADD90066E01EB394C77E40D57553B883F446C42EBB9CCB47FA56816B06AAEB62C21C8F57F926420AB7C1D5E97E73F024C259011CD585C23D30F99D22197B569D67BF5965887AECF553A9B48DCA0C418778AAD65D4843221B8217D2D61BA5A46C4F9FF5B00B78CFA8B6496007A1444503DFB8D7CDE7A63D5D7F54EE5823A33EB3A155C20F0011304068CE0385A09170606FF6895A6955C211AEF5D13BB93866C9CF00A911A4A50A59133113A9C7DC53409097808A6D0DC44A7776B41A7A43818C77CB51F3E20107F080F6682D90399853104B8F3AC4DE8521048B22BCA58B5F7B5EB3E3503F638C1FD24568F23EC8C59A3359A5C9CED0305B1B81677E20EA35F9E896E665D3CBBCB6155E1B0539A0B26BF95396DB8548124519B71BEC19A17DFD4AA2A2E134BEFDCA352B01E1255A12377D811FAED7809C9B881B24C185F1D1273F405F5BE82FED08F26E6C11D39A604E88A1EDFAC8AD3DA9FE8B1111C7E038A14CE58B9598AAE96B7BE84C153A9B26993CECB1CE931E0CBAD5F7F6C18B68E14E83A6BCFA33AD2B3A707118D56803A1E55CAC8AA93EBC47F9EFB"""), + TestUtils.hexDecode(""" +626A3DE2BEF13592E52829D91DD5CCE8E679AB2384C317DD721C3D90C9FAC0DA9E07F5F329FADB83A1C3C1A06A6351AF25496EC7FFC232D060982FE36AB460A905E7E5BA6FD1D12F17E4C4C8D34F531EF6AEFEDF5F29E4F6D24A8C9BCE0F803B47777C78840CCF9AA4BB798D7429EC8D9BC547F24A203D565A012BF17903D75F021E2FD41B8128320C274B95BE21F795F0D13F1096E59D92B85AB447ABF603DA95488C8CD4EA2DB181D9B66626168B765A6D7E922AA9F2F79631CE32A6DEFD4151C4F0EAFD26B50FE8007518280A647B8C4BBFC48B75AAE50C20E988BA863EBD36465487C72385C16DCDC5EF409911FDC9FD9F1F69236E18813D7688B64F8735805AD8FF8494DA36F42133FDE81539CFD1C430DE02ED8B88D5B0DC2F411E7192759971E4AA68E5546F14CA4E3F43ADB3070A8EAC4AD82383FCA3F8FFD6A80E1984653968EAC57BF55BC14765D91101302AEA86B3FC599C100549F80B75ACEBEA040AEB4FA0C2B4EB4803BA549E0D873D99DBFF0C8992CACD6A2300B46F5F4F61FBE05EC6B203F6386F57F49223550406F6F4CD9E31C889A9ACE17D9A846F7590F8EF0A3FBD6E4E4E3D940EF78A9B0B2975A5B442F141DB9569F993C6398AB98A4C5C5B3BFAE5D00C53AEDB5C6376A7C72387481D72AD84F96F7DC59DDEBC41D062455CE042B573F62C98C0B580AF3DCA8155841FD66736706FAD04D9A518E96C0A1C92BFCB82A78A696ADC70A518B25DDB30EC97E8DF355F87C322008ACA4151E57274C2E219EFC811A538B8BA26DD44DDE9C429C8566C30AD085C1569EB163DE705612951F8C022656A2462F92344329FC40D59EA66C07D44145F54A8CAC1939A01F359F54932A9E8B691E0FC3D01894198ABA75E851DAF35CA562DD5340DE311F091E2C65CC294558FC1326856924533A46F754F90F51569472C9FBCE63991D95B43ED76453707DAB30717A874D17535C94D880164FE89B014016F1BFCB971F651178351885034DE97FE94021EAE46FD5624E2C501C133D56D359904F9E0F8A1ED887D975CFB4461923FBA3AE566A27198BCF6938A4C80596396A2BE7755AEA803F4CB7075DF5A7D70788713DCE543AE2280989166EBAE4E7DBAF3DD6C92FC4792F0F11DFBB9B4A465FF9AB96701D5795131D71285A74FB93EF20C8DDDC705EA1992C1CDA769D2F43C5EDE7214823CD8F2C7219C482A6B07E88C6DC3186E04FDE3254DA0E9767FA69836FC509F5A9D9CBA41B12F948F163B2FE487CC83BAA5986CF84D07D171EF9F6944B5DC9FA7866FA72E7CACD7B4345164E4731971C8A75D96E9EB0C61B4F1F3F32CEFB9453615929408411F118A6DE1A9FCBE4FCC71AB730CAB4BC28B61DB6029A788437BCFE5AEAA41CD90418F49766E20D91E0E29714019CCF304371CA4C498EE48C5584FBBF146B888E2C3926FB5BB12CBD0D1736BE74EB533A7C34C06349A26C3ED86DE52A37E4B8EA2C1108BBF3E6773267C5B5C3E50EA16D56B24DDB32FC7F9BBEE75DF88181AE97FCFDAE2CDCD5CCC2E141A9379820CDE613E9FEC61212D23763825D94FA1102BD7F7EB1929A2538731A7E753A7F6E6BE57172C9B8349D8EDD698D1DC25C55D7F06775C4B9534BDDCDFF33DE2F1E9BABE78DC320A202ECF94037801F42ED1344091A132A24B875535322FCA82282D9AE2C0E1E926A2E9E1A4D2BEB6A58B85D65A7847A57E6336C367F8C0812C055B18E8A0AA987599531DB98B8ACC58F5DF9D8E7357888594A188ECF9A805FD767A1CC04847BE22833994784B545C4895B18D06F157F3B75BCD922A8894E2D8E3D174A3C3657B4D4A7B7318A4864D7EA59478E49B0C8319375DED55F93DDC5A51C6048D028195D4DF04206678644A2A6A488F605228E4120FA97E271758657FFE34F0AC5044F8718C3E184EEEDEB62D0C29670250D491E1FC3E59246EE06D3CA31C167BA3FB52A77E1624E34652EBB1FA92DEB762FEFA87AF0CA5872AC6E2B6429ABFFFFA10A5F346F032F753B7075B7CB32E9E899D371C7AD8FC070D25D6C919FA478FFEB91EFB62BC331D0A975157653D07E3202452A05303C9616CE9A647FD4C97E1E0DBD9D8470ACF5D5DB77780A5D515FC7BA795A071B67F7F63D8A4C6E05BA2A7B31AE16EA31D8252562F44DBB447935A3EE504DD135AD6DAC43BB01EB0C5CBA939AE446FC260BDC488E3991D1BFA5102E262C4E31A034B8BA12C1E0AC599474DD98CC014F387B719AC06327BC5F157AB80D424BBD10769BBBF97964DEA127FC52F418DEF5DADCC93724A725CA47300A31F5B1D2D93AADF5FCD59D5F30BECCCBDF34AE458C50A5B54FEB305EF1C3F42556C2E97DA0327629DB5AC8532D6E4AFB22DA1687F536C17D7153D8791805061FBB31ADC0AC2F15FFD764E46DE3AC541B07C55BD67C7A5A972E0370620FE67449C58769D269E160C772C1DE53C46E880D5DA7D58EC100C6810B1C6A051F73B42F8682F166069E6D0D06D2A5894E4B6F74C42B31DCE09281EAE9B1DB21B521D6F910CB8BEBE8F7C09B137C7C1B7B185CFDD91E2A0D9503C35C99EBEEF4B3011A1E5996393FC21E972AA0E6F576A426141699AAA0487C686C1E14E74CC697F4E21591A75F5DEFB98B5D649EE2AAA85391D25FD8E2A20ADBA6523C26713165ED207CA3EDC7F0CBFD5468F4346A209D7A8EB2F63DFB6255F54C062BBF2C90631B539BED1A557A16225FC3DFAF9B6EF2BE10C0CB279644AFA74A03E66FF4FD965184B9571D4A8EB2357A4EEDBAB71275E3D5DD8635C53D29516E98F74B51051752AB7D1954156A906144EA4E54A11826254529835A80B6A3599953E012D4953F4B610A85AB55860C305787D00BD61179F369579EE1277406A3F55DE431E3E7EA8DE07FD4484DB4FF458CFDA28A2307334A41DB55E31CEFB5EFCCD922E475D06979E690144F77780BE1DF0667F746FD0B2F72F87399AC11B9417568D3691AFE1671E08FB2FF508A68AF6A3E0CAC6A9ABA02A4E8AFEC4B7F41CA03EAFC31CEAE5C523703FE41C1CCB6D021678EA00B6AD24AC63ED1F6880C4585E4E85BD975EC84417E8C4D4C2A4B6C10E11853C9DAD6F07BDD25387B66AC3DEFE166D6F85576DBEC76943B87E7C91293D51CB2542B63828571408F893CB541C8A69AD3054FA9EC6759A173E82B55D78CE64920548856A664E21844E97CB264F42E11754FE5B17AB60FA85897D65881207164AF2307376728D738EADD4F486BE0E5CD0F1FF2B080C8D966C28579DF5592AF1E2FF39EE0E318596B26CA5F48F789CA0712A7573BB6ADF3706D53E644B70056FEA3C7EA90D0D1621314047545C738E93A0BBBCC8CED0DBDEE2EAEB0709142630353D434C50657D888A909AA4B4B5CBD9F000061D2C2E39464854575964747D859BA2A5BBC1C3E0ED18415379808394AAB4CEE3F500162C434F""") + ), + + new SigGenTestCase( + TestUtils.hexDecode(""" +2EEE200F329D7A51E31290AA8C6581EE83A0B6F215ECAB93D0F0E4D0350B4548999ADCD8E8E40E7BAD4ABDA6B7194C206595C2747C4CE24E6EB6BDF0101CEB17716EE0336E6730404E8B6F8F1022F66C791D166DFF04E6A18CBC05966306B34745F4E213CD668E079A0DB2762FEA5A1CA548A026120289781B847A96A070F43F10280A08252564A48818052C6042280A4989199005CA826940382891820149121204024EA4240512974CC092859A122048B82812B881C9360D4B001090B60C0A398600A5100099710BB5201A196ED10612D800251A418E1B3321DC404D20C3404492055B1248102500080468C1B611D4C2100C94046442204B361189885022A08561208A23B64C43286413027121488900300212A33109B32102A561C4A80154185203010A00108D2230801B1760CA406283484E00B949022622001765CB020213B90D9C368A83A2915220465C82898BA09182203118B30112B240DB026880200610112919948884222AD0808503324A583231511646A14445A0A64598B80CA49230C9828D138685644864813669080460E2422C60204900B50113496604C06C631285E1C8295348614BB828E0182A634881D28881C1984444867089369208434A19A920182088182940A132514432688BB87113226D132051A33031C118220A450C9840518234010903929A1226D28691E3828DD2B26810094E039728D8402598243208938492468543962192982563322102A291A494318C306CD4004009874521B284D1885124274C0C410D61402D8B146283A689618808D9808464862921994C0A990454207014B3608A168D09150C9C38305AA68C14118A4C120A9AB03109122018328AD240492294650B23121847060A321061980583B8300BA08D633426D14260D1886513C6685B082E09B9601CA48D519861481248501431E1B811C41082D344249B424D1B310D99105084468DD832851B14864B102C221211DC908183167008A770C2440253388112C68423184952828DDC408C8B4884A11060CA8000DB2089C2805199900C1B044D22874802378602C040591484C0B221220790C4804C48068EA22006109489CCB60CA04226CAA46552003050B608A146914A007221C711D9088483103143C009E3086961204E239200C390611A3529D808421A422DA4208120A351CB080208495161144164B044D0A6400C4081124025C9B631501870942850034868E0B22DE3B86062486C0C336D0899305AB845003991109040B90DB8DA1A76D8382906AC6480001D09B8B836B9724779F5333E5CB7EAFBC9BE79ECAEEF30716D5B8198957F201320D88030EF5C82C56EDAC3E6E7CDD8D272EB421CAE9BD5F07FD96EBD3F21C0171EFA28612807DBDE1BC11587A52AF2DD2A9AB7F24267DA67ECC77585BDB335DD29E7941DF37995A7680E71C4E688B840A19455E569B5A777BA3137384E0FB6F2CD937FF55A389758E95A4F145416EFB0EFB094BAADFEC3F91EA5B9AEBA8F461F4B2A451ECAE68B50EBB69D358C12227E8995FFE00D9A3C6AB4E00B58AD99C9240B4D2AE6722AA144E27B6F91732C06A86072B69001AF41F30CECE4869C334EA78126A47FE2587BC76B587E25E61B1EF8CE536C0AD109033B14DB41B9F2F3E18D4F812428E9E9AB88E6DD01E8C2474F6F5B1BB1FCC3BD905F1B16034D9EC562E65F06C14F5BF497930D02565EC9A458BEAEAA5CEE6C93207AFA1C934961D1A0F6D726A4395D4730575BFB09F41B21FC5A816FF6503A0ED308D693EF4FBEB88C09CEF42B1B1982218C3BEF1E81B63DD0D9B1BFFEC50A5782D00B9EAF42DE3561E47F2EF9B3882665328D17567282D1B1B91FBDDE4B64A5876BDC61777FBEADE3144444577D591CA0CB5A665251DF22E055E25AD7543A21566285FD3D3C85E7A4849DA65A28658FF631DE44ACAD7B066E2D88944BEDAC4B220006B19F5F15805DF64F320AE38D05F0DAB0E95E02D1707C23279F3CEE21FBC0D921B334E2A41E7D07EAD955FE5D530F3EEE696248568282A4CB03C3E017FD959560DB0B2F2149F2B01FA4ABE1FD17C0321F38E77460C29E93D88CE4301B58A493C1B29C1B81C0C6B720ECF408EC4AC8BB744A79418531BDA100236268C257049D84598BE897D804FA13076BF9E426D700101D10460E1A97FF32974E1B981893C0022C1BEA990AD92C2C52409C05330FBA5EFFE835A2D57025BC8F22796EB42E6C3CCA9240E3B5E098873F45D5F2B290C93DCC1485481D3689C835EC613A5EF5C6EEBB21AF65403023EFF15867EA26E400FA648AC02C7BF4FA9EEA4FDA649DA80AFEE18A660C6C8F09FC45CC6D0C1941829488249052FE94E9E782C49174B680D7362E41AEAB16B797A05FB55E66A2A0DF069106B3E28F1CB7E90B5C0AD18936208AFE951DE9BDBC1EC66259C9D80C9623C68E95102EB6C597C955B37C510BF421FF5B38590564960AE172DA8605E01396992FB918EE2C107D5A13AA1F8601B775BD5B9226AE66F28FC62FF06FC2ACEE4ACEFE64C3234E4FD53B76CF0232D5C9D7802A040D4E529616F0F43F118CB678FFEC23BD92CA08B18617B4454CDBFEEC86E9CDCD80A8E918B73C3C3311D258C6E2F7ED1890FF0D4F28E935B41FEBD17A41048A35B9AA2F15D1D32864DDE6D8A82E65C17615C71F04A2750F5D9C5D62C24694DFFDF1C900733365272ABEAD17DB695B5285DD16AB83751AE3F63742C5F87806950EAB68E35DF9DB0FB4ACC7409BB896AFEA9C49DCECFB9C933AF12DCB7723777D0059460A02309E9794B04E7CEAEC0AB433311BCF42AC636B71BF73AE439EFC3C4B793287E7F2C8FADD81B2C2A9A09FA1C956DE94423BFC76F791AC88E9BF0EE9493BE031603BAF103BAE535B9A366DCD45EFD324A5087FA6D214772FEE650488F83EF201E9EBB8F60B86B40B2415BDF5AEB0E20EEA5153534F93EC093431850241F7BCD4DB2B5ED441FD8013F14566F6B4ABF725B3F966E0C3BFEAFB5D0C2B6D819887985CFF7DCD647E0B5ADA53D895D14F0361A8E83A7945A99A833EB3AF65D6C9F2FF811F5245A629BC646F3E31DD9D7810BD4404A1301D11D30DBEC2DE0163953760A6C5C7F033BDE8763DEF5D396BB141788D239B720590A79D73BD46EC7C3280BF852A451FAB4392630E071ACBCF86236F7C07ABA6C90BCAE4C18338308A08C1760879A8C2E0D561981B39A4694DBAD9AAB1E4A752F87CBE6BCC9B1BFBB314EF3671E95C654B619394123376DBD4823F5498991DE817B82FDAD2C06AC74CD2F0FE13897527ED8056CCF315C9983031A10E226A2FCBAE1FA327EFCE9F7241218ABCFF7F3934D45B82DB6124897DDAC45DC241CBB42569F926A6740ECD74A9EC6DACEE48CE955F9B3B296E779625A6514AC5D586BC407300572B3693C1272609DCE114A1484F09BD7201C285C2E8CB5C394B88A1FC9A0B72F491A7CB445B3D7F6D9585FA0AA6FF2B71E32678C8B94625B69B1F008F248DA1FE9480C653974BAB0153B78AA642F191522535138C326864C4C9FC895C092C1D05659F01EC7AE7FD50C9E30C7C2E4785E2EE1A7042D6A1AD17A73996B8ADCACE9888DCFA120C8DC527860734EAD355C47136CCBF738B3594860B795ADC28"""), + TestUtils.hexDecode(""" +3F1B179FA452CFFC1F4776B275BC9DC61A4448989A5C74AA4F6A42748E49DF12AA62C5DA238BAB9F4309D563EAFD739B54E8957C0E91DB05F63B2A50F11205F5AB60B0E857F1AEAFC0562A76626AE579BA3387943E8B735A4B1CCBD23A6CF56D7F38CDCF772ECFDB7CD40781EC2622C10D65BCE780852D7930281726CC2B83C8D8179D842CF3DE761B071A6B04A383624398FEBE34CD841CBDF9C256A5EAE3973F0C256F89665A0B23F0B505A2EA73F37EBC11AFC2C3D4FD8626EB86FF0267D00DBC567796011E5548C08208CB0B43A880C1590CBBF0549683BC71A8BBA2CCA5F98011E592F3B5D7C8CCA0165A58BAF8CEA629CBA860511EA2E86B4CD9E721E8D7DC608504114EA98D016C0C0EF67EEF084B8FDD8BA4825A0615F7E09C42D935D9AF0DD847C2435D84B4702ABA573499C9088EB21CFB97E5B5A847476FD25EFE2C2763429048F797FDACD8238937024E5D66B3FB40055C3DF19E213E5941095CD8FA62BCA591007D03CFB879388983D6E7A189782F36F88EE409D490C5FA66B62510AD0D0EE9EFE6DFE23139944046C62EE639C0F82E6D850770A69577DF6034084DB97E4FB2BD206281A79CBBFFFF8A9E4B70252F6F03DE8FFDBFCB0A5267877FED3893CBE5119F0C6930FC0DFD82C63CB1E7DE66DF2141E184646151CA8A927DB49A3EC63B3B862AD60551B0E562F35E109594E4E43B192BFECF066B3C7612BAE0E170F0E1D7D246CCC3A2F94D3FB08BCF9DC7DC44735E258B1F9D0D8152EE79FF9EF095EEC3FCD872D9584361A44B9BDC88BE2AEF1158D1765EB4DEAF441F2407039E98DB8D148DC8B7EE9C44D5833FFE4C52A077F57D9E36CB220251C58F61759D18E4E449E72F29351F6CB08F9D996005A33EA695C21FE883E1C3BC3DC3E8239F2BE16FE445A18AF83639156521188EDF3F15ADB300A17F88C829EB72275F6F35D2D1A72B79A01A50F1A63741A8B1ACCC35E49D331DF670D30DE8855FF27C9F6D7BBD16CDE4C4C4DD48CAA971758D714E89DDEEC7CCEBF2E89F8CF03D7E631B9A18ACCF19FF35AA24AB6A1E10DF105FFE2603C30E16B7194AD615038FE96F4767DB8882D48C97514CEC057EE636C9FEA31BDAADC5CAF6239A805BB05081962A2A5054D9DDB47AD9D3C98D053A5199A687668425139998BCB466364F656B1AD9F13FCF7FDC50652841EE475D86AB89D0CFC01C6B5B876AF9D0312A43DCBBC71B2714B0C3226967A3D1E0AD7E9368EDDEA9120B2C8641EEA203F2E943F43708EE6CDBC6748A33E3DBEDA2AC492A6DEBB9751E7AE4AA33F6ED893AF7054454467E29D7EB7F2163FD24F7B5607C2E77DDFAF72E983AB532C6585AE8D78757DA904D1FDBC10768E3E70D582F17708B51D561C24EE0D5A26559EADF5463097155540F26EBCE03D89F49D7033AA00E1DA5ACBDF148DDABEAB739EDDF99A6B2BBEB48F83E3516380FC7AA9FFACA8DDB53388485061EF5B94E92443C24DDCA823E44A29116F346A22BB3DCE7022C3E2EF35ECAA91CE5F65D7C5EEC85D741ECEBAEACCB39F881391EE2A06BFD7B72173B171B7D11C8792F0A7D9A125011294296B157591A675649716F92234BF074F78EAEFDAE1AD79E4208C6338F42F2A9B105EC5C717301C638C63555AF0A81F63D0CDD04F9C22E2FF223CA5AE1A01C7FC61E9DA4412E80D493A7C0DD49CAC10C62A7D3ABC1B9C74EAA2D8AF248946EF8A37F1F7017E49D11B89EBEC111D85D7C1512EF4F99BFFEE68FB588DF3F39735169D1B5A647D71F52F76C6BC09F5703320DC92BBBE6D7CA592566483636957D235F5D18150B6A4641CED6276319244CD8EBBF74BC5DD3AF82E6C1118D19ED291ECF84E4EC2FEFF28286898E9659B01A37F4612460B34DA8444A4805FDEDCCCA5D6D8013335B4139101F28090517FACAEBBEFE59E44A969FE3B8402D690012AB908EA590249BD9354D456EF65331608478B2050F985C5903FDA5AF0D918E7F7E167C3A669B727DF0CE96B63D4D944493C5D2BCE97F2827CAF54103A18CA8CC0483BC8B98C42657349B8438C0274E4401463CB55E93023BA114FF8CF3A718740756DD8C92958BD07A304FECBACA3CCA8135AAB901AF23E1104E202395A08784873E03FCF2D07AAB003E6581741389C238942D7A2B9FB30B53CF5D0C408C0EDFB1C4FF448D745FAFB0D659B4BB76B16D5B61B0A38039488682907151802A815AF220F82680E523E838ADB47425369CC421DD36C2E60100A9EA7F29B05D985D644A7FEA573BD24B922396A481E33306AC41CEE9DD8ECCD9DD7833F8CC77477EDC2E97A72CE2DD930BBBC58FBFDE78DDE34CA1F8DC758CFCF2ABCD35CEDE0657B35583F9C016524D3AAA5E698BBF85AAAD01D7D3CFFAD4602858BD7E2F173D6A24504E448926DEBA1F70F3B0D5B454B02AFC4D0C482BA8019A0C209ED071BD2D5B341EE06FAFA7FB0D1FFE77FC6F6C49F78EEFEC44999E4330BDF33021EBD91DE8EF2042FE4C3F19E992A5E66FD9BF8E3D428AAA8FA51C7C761C2CAEC8908DB3066D50BBFDA98B82387E92611514605D6CBCC0AF9FE08B39AA1DEC89CE77987BF3BBFBCF362B4AFDF12A8A1ADEC69962A6FB26610C816F023D87E648A77DACC3997127AF770658921DCD300EE2C8C0916593067B3B31ED1B6B73D68EBE68CB22386DE39E57FFF6AD766193F99CDA751316A5B0729FE5307C107FAF6DB4CEF4B1C6CDE957DCD6361606A6606BAEFD9A1AE08A5DB21991F022C4BF758D16FD53D6CD41F637F5569D7357CA048F07F53C850CC56A07A4C2F3BD04DEAE79498EE10B366861EA82A7E04B9202750D4FF4017239BF1BF7088A3F2E2C79DED5A12F75CDD754840868754428BD7392E4F01F36E3B450A9BE5BB95FBA71C960C7D09DBF24E6662C86D8B5C3E37D76B16845B0F88C40AE7360545B3304DA5CBD2B58C29F6EDBD794E9AC779227B0FD198EBE3A172FF4B8896F0C9BFB7A4FD9FE6ADC73E097046FA25CDFEC45CA1E7FFC4FD582DDD8C79A9F3959A4DD7E3473D6F242B0A6AD4DEF109C12DEC994F2E313EA1930ED25CB401B82212E86150BB53BA88138AE3269157FC2A7A919E21CC068E0B9E934701B572AF0E20FC2CDB2B7452CC1E5545AC4CDD34EA0097CF531FD92E3FC38CC50E1FC8ED59272FF3D631FCC239E4AE0AFA46419863A166DAA2CBC63E24C26ED7EDAE476A194F8BFDD540D640DB3A8B294E0DF0AEAB7A735589E23CE524F534AC82D80CC51DFC08EAE4FD02E6F6E0BCDFA0FB23697EE1AFFA735566223A70EAD827DD31881A3C2471677F905B64E6AAE00467561FDD6C79B45016F1326D705A854877DD91D0B147071B00C5F8A600116487D39284F6334FF56F124951333F723D68465B765B32B396FC4C432D51E8C6A9782461EFADC2CB93EE38D4945833435E2E27E17CA98998F9B33057B1C73E2E43B6A184868DA05559B3050FF42C76D7440E1A5B803C8D4B0CBAFF9FF31C7E98FE2D011B3F87416889A81DF9F48643E943336430602C5B44C1D11BC7F62A0D67BCF9964815CA0AB83E7A87DB714F2C1872E5B9F0843B82846516E54A3F7FE311839F4910AEC6CF0D23F86BF2B0B05BB71B5B47E93B80F7060A350EE4D73EA09A6D489BDD064763CACEF5818B319CC973FBBC78E01A505A2F6C4F6812819E02A573AD8F7A345763943B623995B0634562479072D9E42437FCB2D02479DBAF2D088B31EE870F11047E965D04524D0CFF90B943B1BE969DE752249E8B48C609F14FC48692BFF40EA6095F1967DB766C8B4E18FA73DCFEF18F2DE1D295B51A63880E288ACED85B188B3D10A0B025BBD934BA43A5AC5E1829DA836EFDC88F4BC6BA0F4F23A4AB16DEF3B5488BF6C974EE1BBA51D17BD472C731DD35D5B74EDDD3C9177A3503D783968BCF8A1F2549F70069164C965304DE2434530B3841A2AE7DD47DC5FDD9DE046840B4D65A08A71A3D15778865CCA2418F154403183FD44B622982C64F771C87E18C09489493E378476B3B1C8D14C8009ABD3D1A51CF806189496A4D70FE857822049D3DCD4CFECC2F95D2A8A16D94DC6703B4C4EF3E8C7EB9D6859350131E1A03EC8A21E13F045F822C48EE3E3A481EECCA508F189954AC267E6CD19C80F8688410E2E97C71A6C792DD6E33EAB2FD16B82214588B923AF6C6069387F6A72CE06033913B50F0310112DC2143802AA2CA066388C96158AC154C33E9BD72C993B410FE5E9D7CF37A30EB85A127A7773ABFB416419A5B4DDECEC10E2EDB312C86C3F3C8BACADA66D057FDD40740176D137B1F1ADA098D978CDBB938F45D4B7814F2C5B894CAE249CA8E1FDF31E81997F7C55B7A43461F5C7C9893AD0494F4F0272FBC20D80F327EE55250F9560A301078BDCDE94D72A7D113ADC7C739D7AC2B8775D961F89245C5AEA8ECEB1732FA345FCD84A0C07C65F091B4B32DC4E117D24D782C404E8FDDFD6E9E65B3633985D6DB8CA841B9F9A3B3C617F1D69FB454045C5024AD09C5C1080F3EAA64202C08838B42E218F56422722536160F97ED3C08F285EF7BCD1119BDA59DB5EC6BC8E9DC1789B3CBCD469A4BCBE1CE237366A5B51B062D0A08201D4F0EAF6F8FBFFE53F35999763DA2470F2F9FE79BDA60285D052D65DABFBC43659DC76602DC662A3357BC3E4BD07BC32AE5B5E94D7DBDE4B5117BD5A9E3461021A569E200CD3CC518ED6559BF2539D8DAD74920DFEDE8DF8FD8333FA17F0798A17B5385A9569A640685D7365D3DBCE8411D44B17BF79B852B1348AB31335AE013B2877C1D8AF62F88C5186B7313F2C8736472FC5F2B4B38F761009F7623292EF14A4A4006305CC419A3ECC73082F63BB2CECE6A624C2A6DF29DBC6A4F0FD3658C58EE694FA58741DED54889994DC6A3DB4FAF5998B577EFA399E58D822B99623D76050736C17B5218671FDA3BCDF7E81B3E85D87200DB9150253ACB07AFA8FEAF74578125E1E26128116A7446C804DE54FD2D2B1A48E684F73AE91932A37372DB66A230AC4CD54869A0115895D2CC494E6D6E8B12845551B4F3DE0B3A4C114979F0471311434BB3784FAF7F9A9B88D536235543ECED732289B383E8005D98192FBBF41EA8026CA3A14B6895A6EF0548EBEE58C25530F56E0EFF157DF6ED0ED0D5565E9FD474B38EF5BA74D24B82219F317AD51F3E7D6F8E4BD8836B91525E162DB417C87E36B3C0FD874FB4BF4136926AA6D045033C94FD1EDCD69835A116357F341372148C4601CFD84BC36A8E5B2260B90CA797CD5A41362C44B4488399394AAA431A63A74B774E68025D7DCB1963911F2BDEEA60DFB24E87196FF38479D235C98E83F1FC419C87F708677F98C84F9C4848B255DEF2D92E3506A533D36E56DF81F6461AB5BBE9D171ADDD39FDE7552C5D4351DB59543C0FA939ADD6130E25D4326566FDF49CDFAA240BBA0B027257D2ECB83209329944E8F44AB785560DED2BA8EFBC55CA31E48F4C94749E4D205A50BEF3E3F039DEB3EECB213FE92C1C3E98A9F72B6CC316D6C0B87BE7F688000A2433E3A184A68722D44C7F6C90F2AD0B248AFC9E57448E3450888A875CB3006E27C232963740B985484E7FEB07775F4B4FD89AF6F627CC56CA1AF23E3BDF61443786D3F04DECD3CF71E2C6139B584F52B6B656CE0737F50BB270830B102B781E621B3356CA16019696A23EEB238ED74D160269A3EDD35F7ADD9E065F836A61A0CDF99272956555106A349166B2C299B8D0066581DC3608048DD8BC2F267BDB2808E1ADCD37A7538B9435E9E5D7ED4389BD2CCB6E926A927BC6DA19E8E0E946442A6943F65C56E5AB7507FC6EA1DEDEA7C1AD087CC005914CE80A241D42C88380A49BC4B6850536C5A99B6423B77A75FAF76CB17479EADFEF1FC90B832C8F36D92BA3E927C9D60473117267AFE4B115E39D50AC7991BF248DB38E8C99784848013B48D4CD6E034B93E643239E78936DAC6283DB748062220071473B0579FAC64510D033525D786778C53CEBC3BF95C4FE9406943E9D68E17EAB3245C57C00D0C206E3343D8201A2F6C278DD61D0CD42B71CB7064ACCDD38551DC554007F29E1929EBC81025CD1A5AA41510BC5CDFF340F42C4FF6DA37F8E97F5911F37ABF457DE3EAB6114DC858C0C14B9BA5B652DF63D0CFFF4D6F8103E0FD15D87D8EDCA53FBBC70E3B42C410F379BF77DD17F6FF57D7A0D01FFE0044F226F8D65DBCD1803928B29CB6AAB703A0EFFE4EB47329D9D373954F0F15CEF2577EB8F34665FFF2C774EB07F0CA72ED27AFE6EDF158C3AA193F3B5CAF99F52430A3662997DEB386DCF0A6781E42180ECF44E9043AFE95BDA84FD1F9EBDCE26EEC0A4A08D8423111B320EB87156BFAEB3827389108E12E7AAB3F6CC8EF67A7C877BCE3192E503608D6F1E5697941FC1418C16093A55A2ACF2378590F4B0702998A65C8127F13AC98BADEEB32B152F3054EB7D0F200322E40CE632CDAE8F0E6C22497BB6D464ACBE9B461C5D39AF9334F5342FF31C9273146D20F5D4BFC61F980B1862BE4A147474DE89A1A3278004F2CAE293CE2709748507C5DB48D98B484CE933DD3E925E1788F2470C91177ADA3869DF6FF81308DBE846F50C51AD66CBEB2AC91DF1C86EC22ADAA6C702F1CB7A141778BF957663060725A5AD6478E22FC959FE5C918EF1A11964E66B1910018DF4698543CD3015E9876AACE37988370135BFD7047FBFD3996B45EFAB6FFA70A4191F259B8A27EFA05E7E1C75285CF70910465589B41A9D29F51F7BBCE06457A3DFC540608157479B499B2F0CD9D8A8D6F2C01FC79E5079597FB6E2D1C3394B8D8AF65DD133F9D9300DF3DA3D740CD0E7E13EF62BE1D29A3DA6745A5A87558F23D89319BAB09A15F8FC01AA388E1FDDCA117A27426D142094A11E6B49E2C541A82C685D41D6E2520881534012774B4C01CE3D2FD8FDAB8C25E4F0AD1292974C4C141173CA219C07314314FDF94A05955E210DE13F0165C990227EEDDE23A52D7F4C8A181C996D0FAF6C313EB74BBEA4C2CEC0B7B01698C63C2E1D37313B637271DC49A7EED8542EE8BDF7C7D791F7BD59A029419616F9C8F478F060B855CDA73418D0AF090844FC0066DEA9DF8D4F3C9ED58CFED2A78B427B42B033C46485B767D75526DE8682D6AF0BE91169650BA4ACC4D54E0D357E993FAF358BEEE3F7F988381EDB31FBF174239A345130BAE1B0DEAF27BC5E1DFF86B29712CFFAB670D35D19DC5B25DA43D481336C0CCC2120427F30326FC74503548344B585C082A78F96F072510D50E1110EEF01617282CB681CD352A23607C3CF7AD9AC06FB52B38294DE8F87894D25C1D278678B048E3E3F4BA0D884154C5E16780BAE2322C389667A15EFB0B21718F56767EE942E4BCB190CDECA74C92DA8848F41AEA2328D29B10C95C6DFA74B0E162591B1BDC0ED6826ADD0B04C7495FC30E586FBC03D4E871915AF71866278F9CD1B4F1AC56E8E1B7B11DBF0C9A64F608E1C3958910829654057103BEC687A02AE9A568BE514187A3E27F3F9928EEE29519BDA0065179423A7242EDDD8CC337F0B7E7FB7CF90FC682C9E60253BD0997F34F9081FD785712E52262CD17C3508AE4D2FDA3BFE232269ABB185E635E659D405AB12E17A80AEE5BA7DDAF1FAA819A284A60B85B49F1A57DA72A0866B2B9C2D28178995E79D4458B58EDB187B0CDC5C37F111D20371FB8F410A7EBED95474859645FED6F451A396781EF7A02E6B52593189EADFB1226316FE8DF79B23CC67BD2EF973CD561DD612D0C3047698EA0D3895A28B4111938F0A0354E4DA7484697C85908A3BA3E80BCCCAFC73303C767BD3587C1F9D48FD4DB93517A561DAA10F53F330ED14CD65B4A54FC43E5F5CB421B8B6CF7B83D86CBD72A55791588D4B81094BDFE45E3F32A2C3FFE809F66FF310D66032AD6BAA5B33E79F1C476029A49D49CAAE427D8A81EB642B15EF0C544C9EECB7CAFD2A854BA79E4D7EE01A96CDE9EEF45E430EEFD8A16D5D22B751F981667F36DE2E139391980DAD22462BFF4896D277D89DCACBD5CAE5EE90BC2D5954C083AADF632D9051B782190ED4AABE8FFE195000A6BA05115EAA0BCE755B23B10C81DCF4BBED61E6D31E9292DC1A7FD6B453EBEFDE55D6AD8866CCD50473705A24F519548172D3D9F92E668D679D782B7F1041E5A558A625D65E679FC75B15499BFA304435FEE6F6498138848BAD0BFFF6942029BD0C5465395F5368692D6B21B2E22A638D6EBFAF3A0EF1F9BDEF8529C6D0BD328CC82BC66DCDB2F5AE20F53B8AF66400D6C2C0A3C6BCE1E8D2B222FC54F1896E58F61816E301365E12866C1BE7C4BBE0DBDA2B504F0628A4DF1EC7942BC58C0A4CED0046D73FEAF2231FB9FF61C0F7AA564EC1E10BD65B693CFF56DDF3596DDC85CDECDF7F123F9DCB27269A7F65A435ECCAFD89A211C829BC7F5916DDA61959AA296505F6D46543D863F2D3F007D8960634841CB317F5EAC3D3A3E4561801CDFB269257FBAA6A60E7A0A1980C9BFD6053BF2EEF7414704C7160A051355CF48A0C0F6FFD683C453513F8212364775B7424D9315A920DCD5B140A8440EF7E5908D4061F580022399509C0ED416F945705A19FDF8E65C8802B67701FA1D15F06013990C7BB8D0D0404679713222924DB33BC659FE58F82A99BB1AC551426A13C2CF316664AC8037B41755F110F6441C7BC9446430D7BF917AFDB8FBEF84E895388A68763E0E16F89FF630BDE9732852B70A4A3AD8A29D2A4670757AA4202DE5D53E653848FB26C6031D07CD010501F0785D1B1D69BED49DC3B07265D51A15A7C432C3EA63A0B0D228B4F8AD4060DBB8D54B94BAC7F2179829C8D9F9CE4F7BFCCB472EDCBED73B0D18E3108156FE659CAA40B45016E0EFF20F81C29EADC8B638364FACA6FC85F98A9BAA9BB7E5261AEC6786C18487B14B77ED2B62B762D6B8B39AF5A870EACD236CC53C016158DD1E71382475657C512EDEC0977320F1BEC79D0CF39403975210DCEC3ED5B58F"""), + TestUtils.hexDecode(""" +0E27A9CBDF2D81A93D2B091B79F926B66598283ECDACC0D1F1FC71EEDF8A8CFF01741193BC4A5AD7E14CAE78A658DE7655C93D50F88FFC5E4FC993B7D936F7B7E3A7A0BC50C84190D300032369A74367D1E2165307DA61D4255CB55B12448838C0783F61210E9E8003814366A50DCF6F7F504AE587598FCD32D00A026723A34F040E5ED07F849A6884C1E96D6F15590BEC3E3134C48FEEC6AA56A746C218C7B40D5CBF994FE3DC3EDBCF546DC46907B64B3A438785544F9E33C78772F568B206B43DAF1315B0A6CFDB4797C127AF6F47F605763EB9FB0547976FC486ADDA2597CC86CB461A3B1A2C02D600039C2F50AF91BF47DD8FBD791155FBDBF4709825C2B5D302F5648CA842D6B9021938B6569DB7ACADE0E7A13661BE3C50C15AB3A4E82193BA5A342AC17A24263EC52B02857BB78C3B7122362C22FF1787DD9C3686DA382CD8BC5C70B2F16C8917AE820371D813D8367176DC993F72AEDD28181E57C8E0CFEEE2C81BA538655D888875E7F6831B1B5178F3C2D3FBEA81C12AB19E507F2F4ECDCD91D1CBA519816B87F16CC48D8132DB8F042057E21C635CC5FE3BB7D695CAAAE0A2D35591614E9FE2D1C47FBBFCA82EC92E05182D392011A48BBFA4788298AFA2F5ED2A4B2E933776AB1FDEB35C6EA224A69DF604A2979E826D00134AE1C13A7F2A17A0B3AC498804F0EA2D545CE3E37092D672277C4CD051B652332CFB8D1DD8ED703080032E4A7776A19828903A857C574A954A93EFEB26B0CA40A6780F331EE5AA78EA847EF4A624AA0B37D90BC47964B114E8F570BCEA25308CFC4E13F478861851E08E70F8188E147C1F17A769C868FB37A10638CE2D95F8490D2B4145C302993459474AF385794E4097D1E6B3B8BCF29480B25CDC9E8127C07F701A03452FC6953A16E864D6DF32B2D746E173EA181F2939AEE6354A940454F946E9450751864BC74DAE264FABAFD2449D7E51598BBA2D1816B3E912767C1DB51601DA9515DEAB9D34AD7E5F4072AE029613CD5975786FA16A7443F628AFD31B5570DAC44EEC0D41E9F2740502A2B2B6742472CE59E900DF6EB15A3B8D37D05EE0EB56F1558A2318D40C6B7AFDA5CE952344C8D27ED5E22FB57A5B6629D2B901BAB796ACCCE5CDA605B5B9D276F082F495D65EC4E96A962B4D373DE2799F5F4AFD748B9C2495440FFABD7C76AC29F0EF930FAC787873D0DC93158325649821D6F5BCE89C0F46EC9EB43406EF0F2F63F5A9CB90E542D0A3BBB219D2D174377D60D845677126DD80B62464ED3DEAEE110018B29D0354662E1BDB4BF07BCEB8DCCB73F631385617C9A9944B9E6BE8FFEC492847554B1DE4EF5514E5E8E968F69C98133AEF51A75E0FEF2C60A1CB5F1F8CA4855C5F6CCB4ECBB696189948973EAB694004BD998D0FFF5E0B5270C71244D57011835CA161E18928D1F03F515E5A271E46093F2D43052B9266373D06D040C3C735665941B9BA15C9ED03D0941894D521B3518C970C0ADDE281A863F1B09076C9E7B377CAA8D5A3813D7E9316B3E8DAA28268D53DB57D2A1E4A64758B548CDEEB8DABBBDB81740386412B2D3CDAAD98B0E90F98CF39860A11C3016FDCB87D8F83155EBB4623E3F57D1CE98B25FE024DA73449441416EBAE515FA4CB1139C6975BF953605FB1B5CF9FF952E674CEC3FBE66AEAFB1E5D3EF0E3AF3FF9FBBE2E9DF971E8D6AA5A79C0C3A4D8F4D18313EBE0E00DC7D5C913A879C448AE8D31CFF3901F14FA7D1C1C1517BBAADCFD2F6144B2FFFD3440620594CC5DE9B96B3F509BF13F98098187353094EC60D93A57EED58CD91701451C86A7D96ACF611A57F212E27D2EBE0335FE030E391DEDFC2CDE76AEA4643BAF0F4545BDFA7206E14D4146FD203F9E0ECEDEFFAC0363E210C4777017927A4871AC70725A3FA8F593BB9AEA1B048E07BB6BDD718B27F2D375B6690BBA1FA85FE48E8D85CA3B35ACD83B568B286D19CE7C5E0356FD18C203C91485E2B921ED491E59EA5A85796EEAB8208A75A57E0CBA190BD93721022C0303463DEB4D149044FA1E220CE7B253AD5564191E1CF998535050EEB66823EFC455AC058325F1AEBB3EF0FECEEEA8A9DF5022411E04FFA1AD7FC67692E76AB3E9474D461C815A77E0B08CA7FA5940C18BAAE2A7C93C7501138A7E071EC321B4BCC684AEC1546195261F2D07676E8E4F36AC2355D44C8412DCA71BB769AA2B459F285819CC9F19E53DCE686E24600344A32BAE91AB109F01DBDEE0A86AFBEDB1689900659388F2D57FE151AC876620A4B270DE0F9AF057A06FC9A746377F94FBAB3BEB63A96ECC1D26B055102BA7781F7EBC57F48D1221DFF5AB33F9B954F89B1EE348E4809219572CD379B833D690249F70C22D28036A82EEF543926922365643A92FCD478171AEF25B31CBB010164326E680CD247B85B1417992ADFB613BABC7B0B19707D9331BA1328C9677E4DEDD041D2259BB4A296C338130A397E003C34AABF3142DC4DAE8F862A9A9D7A5B8D39647AD00EFFCEDFA93C8831551A4C5FE1A6A32397F8ADE69557EF57C88D3A7EB14F4E43789148A31BD2E8A39F89BDC2E02DEB4DC2B337CA72AB3E00462A1ECC7D212EB18B25E88EB05897A3F29839F840909552229718B725F9FA2F23A4BB802BD9835CB4E765F422A10336BCB804EF6E5042ED3CB9F52EDEC95B0728B117736A0722AC389BEC0A0E593CA4196B857A7B89F23B219E48AD233481BAFD9691A35D929BED17CB12CCABC4BB101B8B413ACA50F2CAF472BEF9D3FABDE8DBDCC9531F8FE67FDDA1CA3E9B790CE4B0A0643A58B48862EA3D6FAE5972CFDB0EB6BDCC9EC1245BE418B2CFCDF3CCA609A132542E68805BB2987A7962E54D95F370F7AA9C869EEDF525E6DD9465A0A1B2B93C033CEE24C849FB41F0313A98FE766546E430AA5AC928741D19D39FFA404D070D401B5C26FF44DC9C7F928D51AE42E1FAC8AEDF8EB71BC96F05C5886E47F8970F071358B534D073380AA2037C42F69982E89B3B76755F7E5E1DF981370467B7E0ADDD97C69B21E37CA263F2BEE9CB46EBEAFE7C02629D31DC040187DC375C72040F5A43B35FBF0676417DFFA21F7BEEA23D0545D9C6FA337976F0E62E25647F7A377A965EF2C5B7EBB6D074308F93BABA96A9AAE838C16EE7DB31A64A4E3F6C416EB9925A3AB70757BACD418983A9D0E23FB8AD69083A98137D640B440A68594C65788968D3D3092B319DA8560E6748190D8A07B76F70D0E3F44F4557BC2B604A37059F0A544F184198C4C22108315DA78F45AA217AA485691CDC82AE5B06EB6D787EFD0A366DB7F1B2C2F404F50757E88A9ACB7C3CCD4DDE3ECF1F310121D2E304771727E9AA0A3B8D2D6F9051537396B7475808D95A1C00B233336383B5D5E65788082839CAFB7BACAEBF900000000000000000000000014243044""") + ) + }; + + // Only three are expected to pass, so I repeat to get 10. + static SigVerTestCase[] SigVerTestCases44 = new SigVerTestCase[] { + new SigVerTestCase( + TestUtils.hexDecode(""" +09B4887D97BCF6379CC59B6162C1E8BF0560BF44D61809170E6E28F70669A3E9496438E8915735ADAEB445CFDB7D89B38C048F4C3E00581514C5FD198B2D1739E883B878D56BB41264BE41D3D51565E2E9CAE33184A899F62DD57D07400E98E58687A9B22FA317EED134CA7214BFF021DD2162B183091D15F263B7298214423C6BB696D75C20D9EACD0A03E4262C4B08BE39FA2154BD6E5025FF791E885F2226E3CF48F7B5EB04FBE9ECF75B19E1D15C305E92260AB0D6AE7DBA7BBE73B6BC181CF933840CC10A00050228FA46A2636DD9A90947E9F13A93EF4C62BE374D76D1FDBBC5D8B55E729FA58665AA07B90C8CDDD61C566B0D7ED65770492EA0713E1ED46AC7AD1503C56D9052D2C94D49E4416AC92B70396F76F6FB481045681725A68CB356377FB231AB8F3EB9A4982FFF1836473BCBDAB6872D229467EFB9366261FEB148BA9B7DB9C4FE0BB88612ABB8FD61096F1819604D55DF6020464D3F092CFCA59812082218566899A56A3C633CC81F88ADB2E1414EF3850D10BF5A77ACE724D6C1F388928744B3E542AE491CD56A64213F1D3CC90B29105F43D237C83D5FB829325C83E654577776392F8536AA9DAE872407ABAAA9ACC22A6812CEA74C0BA67EAF4A410152975E9A83EE4469295317BED10551BA32E65AFC8C8E68DD55420C502D937DADD2EFA2CBFD1F739FC0AB2B2654FAE08C0C7F8EDD43CF9FF0B01D984D491852A372E9FEFDCC1BC16CDB5239AE1001155F89563051CE47996C5AEEB2190EA18F7F734042DE68E988367D89355D9D8377BAF9647978EB2E492AD021C569AE8BA69B15F1FCF7039A7E64AF10ABF3EA45B7222F9659E33373372E1DB186D2C2A0D75451C478AEF33E5949F240040C2AFC44B1D3A02A6D2F87902A280E27A20D4E57F889662700DB8A9D249957A7DB437CD480DDC05884FB23F868268EACE34EED274A927D9D84F1EA57EAB1A813B5E6AABE9ED2610BC6F72E320CDEC4F99523F93FA448DC1FBBDD259B102F5DC9955AFA0C41604D83DD1C2D2295EF4461456BAE86905C4C30D8A9FA48C90F37A19C41A2D5988F13D51344EC30A4A46219FE841137D5AA1F51E6C444168AF39890B6FA400D67F4806F5BBD444703074A7A1139C71746D7C4CEB3C911F5257E3E53EBFA5AA8F227809D44EE7DE13C027924DD60153B30AA76DD96A7C5ACC59B627919507BF14257AE7A26243C1683B28D1B14B501AD059B4D522A57991E5539CEF18CEB5C26D660B8822454C9C42A95E6F72B84F78AB99F51EC49789F9DB4C128B0318FFFC82D95CAD277F11E14F1EF871414881122A9B11BDFAE4A7ABC8E75755AB13741DFACD664293D1A326BF5ED5ABBB153EBE6996DD622F0A8CB473969A50366BD0B01C5C73A892B8E26CE08F75FF801B6DEF041E1713BE6DF0EFB51587BE5FBEA727E00D717647DD539079DE18AE7BED12B91AF8DBB1B8B32D2860BAF40AF8A0BBFE02887EB5DBE7AB1AFC41DA79B016AA16EDA281321CAA5DA644FD8658A7B702181001431560DD63CB21E5FF75C3F7250456BE08C0D5E34C3BDE2F606A2BF3417768D24B23739EA86CBEFDDA34388BC1F918F951E15E43B1385A7BCC559F9492C7213A14227E093E929F32D1EFBE7F1EE57C49C9055623EA42EC6C79D7FCE71FA747607566DDA69F69DAF68115919C6322EBB42C8C089338C9E0C53565BCBE72FBE4726687B0787071806C5A6C149C82B668AA64A7BA0CCC1CC49A1EEE9453D04336E5DC811E03892F7F46688ECEFD04F1876F7111712B595ED62DA00678F9E3786B5C1A5095BE8710DCFA4165256509E00143A6F1172FABE8BF21E5FCE7C79C1A44B4B1525A076FFB8DD9066"""), + TestUtils.hexDecode(""" +3AFD7FF8CAD3ACBDF97731261C7A1C969D5016F17D3E7F83D2441AF9014B63477B14A6413150FAD7C84439BC88662C5E931F06B9514190E13FB049C4AB74013233B98D48D9AFB6A30A67330E1FBE331B09C56D037E9701085D80F1E7F4043EFB53587ABB823624012384515249EE6130973DC9EA6F558BAE75107EFDB1D9285B"""), + TestUtils.hexDecode(""" +4A2B16CDB552F9297F8E391AD8F5ADC8CC5D2C56C46B800F9B3EE4BBD2F2E8A89D599D7B5CC2D88C80F271859BBC83043EC4E54812F5936B446C9513C855289C94B11551A0C7653E7BA74FFB6F72D4652C91D38DD1F90DFE4439BC21CA53E0CC7A7AA5B875A5B9BA42366EB8ECBA2436DAF08A91978DD093F20F1EFB6B0BCB90DA99CCA05E8F6F82B86D3C6EE24BA5D50AEA10B2307F57F89ED78DB4A74FBBF6EB332AFB08D074ACF0DE5CD7FEC12F76F3AB619C815B9EDD287EAD67F04F14797F8DCF2CDE9A8753B5AD0AFA12874197D1744092872521E868AF9E64452373FEB6FE25D5273D63C0EBD6D3B1028C1CD06AF32CECA2621310837C72788C8ADAB5A0F03817128EB7B766FA812C696CF886F00A1044CDD06BB28CB2E5780C8D8CC7E60AB699DD78668BE4FF9F4690C6FC98AAC9C02B66B9B9826A3061FD3222DA8482667960A31652EE88EB32B0469AB71CAA2519F23D1A2442D5B1316262131DCEC5F287E32FD343FEB4429E54258D690D9D20A10ABD75A536DFF8CF1D6DDF19291E2749A7D16EB90AB5093BAD38E116A86B730E65574C068C38BA9457C9D6D913EAFF57FE23BF3DD24D8CA511EFA376A5DF08467025FF51BEAD3EDE0A84EDC5321620998061E8A1A73D67B7021B810C7867FF39187B59D403BF7C7506300C7345B1FE07C11278B0ABA61DBB4F2B8C43E74FEFA55ED52C10A8C490882BBFE3E3B3CE579E8116A9B6686C1A100AA1F6591F191F772B5A5A50DD6CC155CB5A1BE5BA122E91F044420156CD63080F0A45D662E76DD57BD0F689D0B299042BFF485E8A382D865C26CD46B4A54728BD48458362D79AC3EB756FC6C518C9E2F0E7D5A303AF1159EE6DBE7DD56BA0712857A68836C3C78C6C9F7488572813C0F6A814709D2BC142FEF02527CAE7712358371C5426522CCC64300C2CD9FBE20C6562E34835205FCDD5A8982C920BB477FB881702827B4911871394C06B5FECD0C740AF7B27637BAC1A0CBCA537E4433EA847454C693897A32E4D1844195426A0C6AED67472BD2C4EEE179F3F6084A36A7689F4CB1F8E5DB2DDE54ACC0666BA98415431A4B202F402FB1F1BCCDC23BFF13148C7B8F61FBF6243B296A78EB698189DA95BDA85DBC11D15FFDC6BF46C53F6E472A871401E9A9AB7F9FB467EB4ECB1F0DA7E63EE8619CBC486EBB0F2120A7811BFB0557D13930574297C9464FC595B27569ADF5F4A8DF669C9EEA0A250F4D22C2E8C641BA3902BA80800489965F11AF1E1A85717C624E742F161550819D1F0372C5CAE8BC62B549EFE874461080D06346E1FA6F01514FBECCB06E34EE271A0F0031790BDABE0F02BBA4AEA4B7397FE3333EB8121820757281F96A5831F9E490366549D16763FF19FF773580ED5E3E1E2AA3E38F88474DE6D9BA6994F8E629160488CB4CD5B878CDA37AAEC9B56369A7E73F73B428639A05C1378448ADB7F074DC8154D92E13C6356B5F466D66477159B2A943799AD619A029F3010D037672DBB6820E51323ADA98881C6DE859DF875ABAF11DA5DDCA5A777622BDAE8FACE2E0CED3B6A77B88A8729FB7C50933DA6C52E3F4D948F9DC153B5B1299CD8621DDFBA48AF44E4B6F6106EE7779501DD5FB3C578EA4D32C5C2F036A7352703ADD135AB84460162417E50BF91E60797D59B9E18D324DA971F4FF428AEAF23AC0BA4E2E2FC7ABAA6C8984FE9E2D85B8ADA4086B3C13ABD43CFD1C711D8326B18ADC34CC14CF8957EC3959498FC2A7BE06BD1840DE170366566E50741957763C2DD27ACF8C3F1026FAEE1D2562FA1052E69AFDD42F446F0598866D5D306BF1B775042B035927372827F4386316534FA1B7EE633BA958CED8F0D241D4688E3C7918E2A75626377C342A590692BBFB827BF90514182D4090DF8D7323519A1AB6CD0227367410DD14D3786A26DDF91724FC82D06A25D5F56683953E8E0F20E3C1771DAF42E52024C116ED8A4C0A611680F5FE00ED9B148D15F12AA95B9BD5A9FD8101642B36911F310B0DE18171D6237D9BE1725DC299A1A3AAAE98540CEED26953D10CE8547F1C3E46A862BED428D1E10601BF328C727FD95343E2DB4D9ACD5D1CB4715F6004096EDA093D1B0A33B1E56F16D73ADB8732CB4A31160A4491FAA0C86E680E3D7C02CCEA8FE92F1E001016D220221DD10ED626017966C3450AD121365918C93091F14712BA477CF2E263296C778A2BAEEF5849455FA35CB617251E02A22DAF5C33E5AAA9F00E8ACDC50ECF47C521503C52F27D6B57C8F2B3D8F1222413E7FA4EC59296338098C9AB5A1D8A57884BD860041406D9655D17382949A03D50F1108D05BDB31CA08E66F2D8DE480C6793518D49A60D4762A9EDDC0249B422E84020ED539A14E2478F68BAB1F2B00E22A5CBB62979AC744E08B57D5B578C401A8D26D9ADD1505236082863672D911CF3A0966D303F8917093BF97AF90A7E1F9D59B09206B9CAC35110FA38D5890ED2116835CE37384F5630F1C428E213605872ECF911B014B91C2C600E8A40729D07BF918790742C9279F3114F68CDF6594CDA3CA6694223A82F66C2B4BDF3E51C6FFDC55E0FF51EFD6C934362BE7D6FABC11B8B0DADDD52108FA5FB5CA758A64377D386D45CE70605B460E8157037B5B1B2E0AEDD12A633115D6C43BC6C7C836FFF33E7D033F2E5800527164C0C4781C37DF50B66BBA5C819473A1C5302083A16F01437279D2F2DF14C878269A2F3FA40C1C761ED61501AC9EF141029038C819954089B738098708174393FEAEA7B02AE5CEF67B3C8CE6A970675CA1B8C856DCF5972508C7C6B25EE4D12D8212B98940B488EC402AC7AE3C70DF938D1288CDA7A319E085BC73A469B2D2A3303B11A683100AF6DB86937BA1182903616E3F0347BD68591B47BA65156B93F260DE59B3AEB289E2A73A3BFF38C2F3ADEDA29C7E90283AC7B86D036B47D5BA1A03EC783D250BACAE5847E41F829CB33DE08DF8F7D69C9AA4EDE8D7AB968407EED31A056BA0EF8816E127AA90065A679E1CA9550DEEF25AC5B7A34F70DCF2B116CF351F3BADA99F836C730DCC1AE03F496CF3F0387A0C2C702E2C13BDD9CF45A1CD53AB58731188B18EA8BE48D510C5812E90BCECBC6E198E708B1C08C8F864B124BB4CC0BDBBDF2C2F4E388FC19660D69CC2C0EBF91008C8243DB42DDAF57C024251C4231DF53790CE575613EE8E1C7A33C1561F3504DEAAED1E8408500623ECA5AE5A2845411749930D8E42078C032349957FC39A1DA0EAF9E87C31FFBF6AC0C1811EB28A41B1D86BD7D49AD1C468A49594956525A20A31700F122F4C4BB2252A2F3D5C5D6873838C909597BBCAD8E1333D5D617C87C8EE0F1B22383B424B4C5C627298A3BECC1B32475C9DB6B9BDC6D6DCF50000000000000000000000000000000000000000000000000000000011192834""") + ), + new SigVerTestCase( + TestUtils.hexDecode(""" +09B4887D97BCF6379CC59B6162C1E8BF0560BF44D61809170E6E28F70669A3E9496438E8915735ADAEB445CFDB7D89B38C048F4C3E00581514C5FD198B2D1739E883B878D56BB41264BE41D3D51565E2E9CAE33184A899F62DD57D07400E98E58687A9B22FA317EED134CA7214BFF021DD2162B183091D15F263B7298214423C6BB696D75C20D9EACD0A03E4262C4B08BE39FA2154BD6E5025FF791E885F2226E3CF48F7B5EB04FBE9ECF75B19E1D15C305E92260AB0D6AE7DBA7BBE73B6BC181CF933840CC10A00050228FA46A2636DD9A90947E9F13A93EF4C62BE374D76D1FDBBC5D8B55E729FA58665AA07B90C8CDDD61C566B0D7ED65770492EA0713E1ED46AC7AD1503C56D9052D2C94D49E4416AC92B70396F76F6FB481045681725A68CB356377FB231AB8F3EB9A4982FFF1836473BCBDAB6872D229467EFB9366261FEB148BA9B7DB9C4FE0BB88612ABB8FD61096F1819604D55DF6020464D3F092CFCA59812082218566899A56A3C633CC81F88ADB2E1414EF3850D10BF5A77ACE724D6C1F388928744B3E542AE491CD56A64213F1D3CC90B29105F43D237C83D5FB829325C83E654577776392F8536AA9DAE872407ABAAA9ACC22A6812CEA74C0BA67EAF4A410152975E9A83EE4469295317BED10551BA32E65AFC8C8E68DD55420C502D937DADD2EFA2CBFD1F739FC0AB2B2654FAE08C0C7F8EDD43CF9FF0B01D984D491852A372E9FEFDCC1BC16CDB5239AE1001155F89563051CE47996C5AEEB2190EA18F7F734042DE68E988367D89355D9D8377BAF9647978EB2E492AD021C569AE8BA69B15F1FCF7039A7E64AF10ABF3EA45B7222F9659E33373372E1DB186D2C2A0D75451C478AEF33E5949F240040C2AFC44B1D3A02A6D2F87902A280E27A20D4E57F889662700DB8A9D249957A7DB437CD480DDC05884FB23F868268EACE34EED274A927D9D84F1EA57EAB1A813B5E6AABE9ED2610BC6F72E320CDEC4F99523F93FA448DC1FBBDD259B102F5DC9955AFA0C41604D83DD1C2D2295EF4461456BAE86905C4C30D8A9FA48C90F37A19C41A2D5988F13D51344EC30A4A46219FE841137D5AA1F51E6C444168AF39890B6FA400D67F4806F5BBD444703074A7A1139C71746D7C4CEB3C911F5257E3E53EBFA5AA8F227809D44EE7DE13C027924DD60153B30AA76DD96A7C5ACC59B627919507BF14257AE7A26243C1683B28D1B14B501AD059B4D522A57991E5539CEF18CEB5C26D660B8822454C9C42A95E6F72B84F78AB99F51EC49789F9DB4C128B0318FFFC82D95CAD277F11E14F1EF871414881122A9B11BDFAE4A7ABC8E75755AB13741DFACD664293D1A326BF5ED5ABBB153EBE6996DD622F0A8CB473969A50366BD0B01C5C73A892B8E26CE08F75FF801B6DEF041E1713BE6DF0EFB51587BE5FBEA727E00D717647DD539079DE18AE7BED12B91AF8DBB1B8B32D2860BAF40AF8A0BBFE02887EB5DBE7AB1AFC41DA79B016AA16EDA281321CAA5DA644FD8658A7B702181001431560DD63CB21E5FF75C3F7250456BE08C0D5E34C3BDE2F606A2BF3417768D24B23739EA86CBEFDDA34388BC1F918F951E15E43B1385A7BCC559F9492C7213A14227E093E929F32D1EFBE7F1EE57C49C9055623EA42EC6C79D7FCE71FA747607566DDA69F69DAF68115919C6322EBB42C8C089338C9E0C53565BCBE72FBE4726687B0787071806C5A6C149C82B668AA64A7BA0CCC1CC49A1EEE9453D04336E5DC811E03892F7F46688ECEFD04F1876F7111712B595ED62DA00678F9E3786B5C1A5095BE8710DCFA4165256509E00143A6F1172FABE8BF21E5FCE7C79C1A44B4B1525A076FFB8DD9066"""), + TestUtils.hexDecode(""" +0B36AE74905A488C25C9BF47B4144E12E75A8F54555E1943E3CF738BBF0B9C4ACC270A71804B0D8FEEEB0451AB504027C853125BEC7E7216A82EC09EEA3778291A6B97F53B1766FAB67CD3C875C171A36D5DC23835B7B5641C4689E646C40CC2B379131DF4AE848B8C4713A1E38F5C31140662F6F92BA22E888CA3C0A2F242C9"""), + TestUtils.hexDecode(""" +279860C94C551A0A0788099AB39F1F25BEE8CC4622D20DA037005B8D6B5B7371B11BADFC236C9B0028868DFE74A9AE59642CDFB8D38BA5A79CD52278E554C25B07A07C77C1420F8F0CC08A035C99BC4F0C303F20CA1BFC0E46E9FC6F37FF1BA5E5653656B7FB488C3B600E0BEF9F4A553A3D2FE5F0D2B76EBC90C5A2A99B789B55316ABBBCEED0EC70325CE2E89890FB2A19E30E79C4E8E619101FC2428D9579737DCB3FD76947FA7BF257FAF2FCC360051F55912F051DB24C51619439369F13F34D669DCD5638D3565101A7A4D379105EA6D83163D046DE3A6F9D9036CCC347DDF8B363E873D959C33D1B56775914ABD50EB6FD2D096E669F11C288781681D693A3A52188E80D0D33784D2F5FA1954D72C35D8929A2223577F8119CF241317D0E95C615641F40EEA3368BDA7619EEE82BC4B78717CE9E9D7036E0DD7DFFFD56CCC29D4F0EF46DFD4D07E4838BB513B2EEFA72BBFA0E9FEEBD1D2B96D9B8DBCAB4241FF7AB080ADBE1099AD3CEDC4597B23171E3ACA2027CD1B6E519EF29FDC21CD54EEAC264F4B2CDFBBB8104FE81C3C65691B0C309C31B877BF0B0DB37C6F44B9A11DDAFFCC40CEB1E78D2F86C2A0F902699EC1680E46F94DECDE4EC119F7742D3D47A383391B8DFD614E375B8C32271CDC49F054D2C26DEE4BC60C3A474888642DCD4BA1AE30CC8CAAE80AA9FCCA55528AA33FD4F732677E7D1B9E320247B299D6AD384D23D4E478AC2450F676B9BA27E5D4CB01F0EA50A62A2136DC4C2E1219C0E749444B2943890F36AF1EC2C273C42F22E0AEAEBD31FA8E6C9D1B8305A0AA8C2BA6601CCF28F46904231E648AFF4D4A72849A8E1EEDCC774FFB1479897C1804BB035671E8F90D462E3D2665B2A75DBAAD3BDB00C13E642A23E84ED48CE3E9B1632ABD0B7D579E7D18F508F33DABD97083EABD3CDCD1C70523A969B9C25E4011742EFBA6B3A09CC6CE627CF95BD51856DDC8C295DBBE180C86E0097FCE5741B3F0F6662B486D1B17987C3C47ECB101DC165372CA696FC477860F3DB7A68E3102B5A91BAC2A256467873C233ED212C7537470BFE88B41C3C239B5E38230E20CE2C41EF2C355884CF7F46CCF0CD688DEBEE8554D118F9088B4F807F19FE17732AD3C145E634CFCDCFF32A54F1C1D7A7879E6C022281130FD5A8188C560658F1AB6AD3EB3FB622D52A1939FE8668F2116A05F6EF6E1AAD846A4279FC3C699373A2FE17A3E9823FAA11F088846B36F5DB4BB9930101D5025350462D2F4866BB3010D9474B5630BDB57E71AE4277247DFF67F37E3CD9BD1307035249EB1EC316D25F913AC4B0BBB21D60CE2F4ED5F08D48D0C707795C177E7044E55D438AC12C2DB918C7087388650AB4AB19095C0A480232B1BA0C794991E89A650E070A5B562D9965C467D6CE834167EB6189A41B58E91685A034C70CD7723840A5561F0F751AA8F382A3772B07864547C1862E2433811633C97F58F85B9B14D3875ADCE2494D8BFA2E0773BF4637EDBD96AF9BAE43497CE2D63D59640C7723761C8AFB534189509A44794BB98A6D8E4AA3C5C3C136AA1C31CF20EFF2F5968FE4E71415DF760A52EC88BA438EF6110CD7F3B7FBE53B13999DD3EC4FCB5CFB4F9744578CEB60F800FFF2BABF330DC20DA5C128282C924244D9E5A18C3AC59DCD0D953156E2020751B708C0B025768963EDCF0DBAD16DD68A792A5E30981F17A4C355AE3E8036F9E289EEE35D9EF136AE402B4AFC7DD04190A8F0C8F66A66B701F995F7869855F59B47634B4A1F9E715E5059371B74D65D9501CA814F255D6C4D861B5C5A903B7ED44BF55CC18DB3CEA98D7CE951CD241A661E823F0A0EA92FA33A23294338E6F96D273DAF63BE9D5D5BE92FFEAA6078A9E8C5CADCC8AE79A1D5FC384519DF06A5832CE1DED5C7A6E937E86B854ECB1043169041A4BAD0FFEB13B0017B5BE16091AAC3F5DEB017B01EA00CA323AB44CCB193063406C970257DE61FAF1EE51105A22A4703562DFF1230AE241D67803FC6D997A1B016A73CE4346DF97F8ACE220CCFC3585B8307CD4B3AF74F6E0CF49A33CD5F5E53D04A197B4AA55ECCF645447B6033FE38DFE155AA979B2D4586D5249450E01532334C8F342BF81AF35980639C7E0AD431F3D3277F21F33A0622568E08D75A97CF2560826EF3DDB8A1E421217EE28B82D3BBB6FC499AE696567EF24681D482B051CA65DF9EB7F59965F03A68976F8A2542A58837CD3DA9EF5F4F06F94313B63B6B25EA67B1ACB4A0015F026D6A683BF533C3F730CD4D8A0CEF6D63100B4D9A1ADA15305A441A71B829AB2D33D3D209B598E05F19916569FFD262EE5D4160B8DF16E3FE63AA48029FD4F080D07602DEDC1B383F286202C287844D4063584087F29E36D5C19E54CF37DD504DB01452340D937D438C0E63EC35F948A4681D74D54CD6AF91262B075F55999137B5B94A2FE4E2668FBE44F68A892A91F8B5AEDB265BC0464F62C768BF346BC91AD9F9733E3DB9B846E2DBB0FEB3D00D817DB052C69474D77AAF7DCABF21E137F4C4607CFACFBCC7AF1F27BAF377B261358C7CD69394C33C89ED66F2579F29815B1FD957553FBF4F9FA4A5C85C223BDE78BA0722375BB8E7B02FFAD17DD7410F384A88DC0A77CA6345AE26A87FBB4753FCFB7EEA6ACE2061694746C8BE7E645D8848C5742ADD8815DD48AF19021591C7D7DDBF2DED046E7DF36F092127AC47432555F2BE60060433B561E7CEE0DDD1C5650B92898C8D6E01531CD373271A24A489D95FF24F4B4BB06AA39F56375F4B5B5BEEA5F4E5DD3B918136FA98AA2580A691334F8082DBEBF34943B27024C69C897D31897C2690C3D72C22133AB467E0626A4618FAF403A63DF25E2DA82D1191787D6487D87A6985F619CD6F1B7937F06E448501498DF0A1005D408D1CBD943ECC4EE03D038C5ED1FE462540DC937F0E4301502228D3B3755E3D31EDAB96D03AD1AB3E0A631AE80F86C3AE9321F35AF90F8D4D9B2B431BD529E2D29A29FE066269FB90248265088FBBBDE99B24A0F38282847D8FF4022AE6B611743A5B5472A4BF054B95F2CB09EA5E088E8AB172B7C3B53BB32986FEC298F41E2FA9D53D6F85254ED489A3F1FF01C07D33DEB98CA4EE704F27FD68F47B2E995E6706FC8D02454D7F2A73E50CD2AB15F973C9297B3B4989393588BB6C6CAEFF67BF2E241A158EA96C1A2FAF13FFBA4358A38928C2FFD0A7E32137E83256941DE749DFED36C63F2D07C557C7AFDBA351329899CE6D96DFD3442725BB1F24EC43EA41B4DE9E4E39D17A6F26384168DB92BF9516D7DD8101B970B83F2A2F323B418385C3D20410122D414A586970737BB0B1BAC6DA0B183244494F7375799AB0BDC5D1E2ECF3F4010C0E0F3537434E5366C6CCD7F1F20000000000000000000000000000000000000000000009192B3A""") + ), + new SigVerTestCase( + TestUtils.hexDecode(""" +09B4887D97BCF6379CC59B6162C1E8BF0560BF44D61809170E6E28F70669A3E9496438E8915735ADAEB445CFDB7D89B38C048F4C3E00581514C5FD198B2D1739E883B878D56BB41264BE41D3D51565E2E9CAE33184A899F62DD57D07400E98E58687A9B22FA317EED134CA7214BFF021DD2162B183091D15F263B7298214423C6BB696D75C20D9EACD0A03E4262C4B08BE39FA2154BD6E5025FF791E885F2226E3CF48F7B5EB04FBE9ECF75B19E1D15C305E92260AB0D6AE7DBA7BBE73B6BC181CF933840CC10A00050228FA46A2636DD9A90947E9F13A93EF4C62BE374D76D1FDBBC5D8B55E729FA58665AA07B90C8CDDD61C566B0D7ED65770492EA0713E1ED46AC7AD1503C56D9052D2C94D49E4416AC92B70396F76F6FB481045681725A68CB356377FB231AB8F3EB9A4982FFF1836473BCBDAB6872D229467EFB9366261FEB148BA9B7DB9C4FE0BB88612ABB8FD61096F1819604D55DF6020464D3F092CFCA59812082218566899A56A3C633CC81F88ADB2E1414EF3850D10BF5A77ACE724D6C1F388928744B3E542AE491CD56A64213F1D3CC90B29105F43D237C83D5FB829325C83E654577776392F8536AA9DAE872407ABAAA9ACC22A6812CEA74C0BA67EAF4A410152975E9A83EE4469295317BED10551BA32E65AFC8C8E68DD55420C502D937DADD2EFA2CBFD1F739FC0AB2B2654FAE08C0C7F8EDD43CF9FF0B01D984D491852A372E9FEFDCC1BC16CDB5239AE1001155F89563051CE47996C5AEEB2190EA18F7F734042DE68E988367D89355D9D8377BAF9647978EB2E492AD021C569AE8BA69B15F1FCF7039A7E64AF10ABF3EA45B7222F9659E33373372E1DB186D2C2A0D75451C478AEF33E5949F240040C2AFC44B1D3A02A6D2F87902A280E27A20D4E57F889662700DB8A9D249957A7DB437CD480DDC05884FB23F868268EACE34EED274A927D9D84F1EA57EAB1A813B5E6AABE9ED2610BC6F72E320CDEC4F99523F93FA448DC1FBBDD259B102F5DC9955AFA0C41604D83DD1C2D2295EF4461456BAE86905C4C30D8A9FA48C90F37A19C41A2D5988F13D51344EC30A4A46219FE841137D5AA1F51E6C444168AF39890B6FA400D67F4806F5BBD444703074A7A1139C71746D7C4CEB3C911F5257E3E53EBFA5AA8F227809D44EE7DE13C027924DD60153B30AA76DD96A7C5ACC59B627919507BF14257AE7A26243C1683B28D1B14B501AD059B4D522A57991E5539CEF18CEB5C26D660B8822454C9C42A95E6F72B84F78AB99F51EC49789F9DB4C128B0318FFFC82D95CAD277F11E14F1EF871414881122A9B11BDFAE4A7ABC8E75755AB13741DFACD664293D1A326BF5ED5ABBB153EBE6996DD622F0A8CB473969A50366BD0B01C5C73A892B8E26CE08F75FF801B6DEF041E1713BE6DF0EFB51587BE5FBEA727E00D717647DD539079DE18AE7BED12B91AF8DBB1B8B32D2860BAF40AF8A0BBFE02887EB5DBE7AB1AFC41DA79B016AA16EDA281321CAA5DA644FD8658A7B702181001431560DD63CB21E5FF75C3F7250456BE08C0D5E34C3BDE2F606A2BF3417768D24B23739EA86CBEFDDA34388BC1F918F951E15E43B1385A7BCC559F9492C7213A14227E093E929F32D1EFBE7F1EE57C49C9055623EA42EC6C79D7FCE71FA747607566DDA69F69DAF68115919C6322EBB42C8C089338C9E0C53565BCBE72FBE4726687B0787071806C5A6C149C82B668AA64A7BA0CCC1CC49A1EEE9453D04336E5DC811E03892F7F46688ECEFD04F1876F7111712B595ED62DA00678F9E3786B5C1A5095BE8710DCFA4165256509E00143A6F1172FABE8BF21E5FCE7C79C1A44B4B1525A076FFB8DD9066"""), + TestUtils.hexDecode(""" +3DE9C8CDA014784F23C8CB6D41294D39D27C9A5DF8F8D939B6F2D821824E584BC0BA516037E100C68C02480DAD436E12DD095DFFE293DF8E4AFFAFA0DA05516BD579B1B03B2A43307C7DF0D88624386593B226D4BA2EC5716A8C8B7A117C437DDACE31E6A902C403DD172DA7054A1BD679C01C1D822C3A075F5AB2002D2147A9"""), + TestUtils.hexDecode(""" +4A3C0683EE52A2E3703716E44D321208374CB0ECA74F9E6A624A1947B6788AD7F6AE68F320A580D35697E48B276779D4F5D2C8AF78177F12C9CD117875E0CB039293F140C24D80C895ECD7AE9C7C8AB72395A2736D7DAD6FE3EA57F21F9681806D821C91EB790BBD7F4AECA96100CA225A45CABE9372F48732B1A0745BBADAEA0594CD87875C05B703FDACEB441736811E2B6AAED172B6EDB8FDD087EF22D30CEEAA7F9E9A0DACD13D60749C0A04C376B804872A6C5056C37B9B64B4060CDBAC15B1C00CF9AC77DB99C506FDAE0AE16C198DE0BEFC4CABD6B38BC7E268112844B8ED5525A5624A36701A2F6AC6ACD2E4E40F01697E518B5F3107563865AE8537D04FAA57E1B71ECB1E2C2E36AEB3D8AA4674A04306E5179FB7A45CC6D57692BD787137DA3E6C5395D3F6A2EAAD0AF8F586912CC6E6DCD5DF34A6E4B0A574A350D760C646FB77C76377B6F88FACCD1B7187CC10E363FABDAB9D494E749E0EABE63D45901A54E06FCEA5A46487123C3C1107BBFFA87B7D7D92BC6793A7FA3CD18CA2E27DEE2213983D08863126FD79FADE804B48830AF687B02B4931357AC4247617AC13064804D3F780EE18A452613E9C1B188C0655FBA86F6ABD38E5F7D17267C747976C36EB37267759A9EDBD6624992F704684484FC562C8918788732DAEF29EC1386E73A2E2FD02BF7811E1D7A20822C8985AAF86B8E253AA7F0806BD6FA376557910497205393841BAFA34598B7E29EA9E67351CDA2966D0873BA914255649CDC89B2B64A751EB627F0C2D0963D391036C7297518A44C6783750C3CD6DF832AACA28FD5643F94A38571BCE04C3E29E2973CD6C6600C8102C1EA725DED21C50C90DCAEFF9D73756FF6BE91E8E766598EEBFC394F83C6D36FAD25B2DFC31D720E7E42763F10AD75D8C93775609CD7B0285F0247B52B797D11489CB4EC333C27E195ED8F7071E6C3E5E9220CAB46983B4013705F5934C0F1D61E70EFF9CD5FD293668BD3D0546A884D7AAED9EF7D2CA8E84A6BBDAF7FD8181FCC9D65FD74A4AA26DFBC42EC10484D7DC073E123F95CA705BF6CC3A803C186985721406994714949BD47161AC12AF72C0A358702CBA5A6AFF793D0DFDC7009861414CC3689E907D65BFE48751AE296D798912D49F4F849E43141E1BB050F9D17E5A0C4B7530E83463469F1D9443533AE36C57C6D80B915A3B3C8D9A3E43F5E6AD0187E8F828FFF7240EE9D4304255DA0528D0EF59FF1993731735245467B1BC5E6DFDE8895714F34562229E79AF8AB5E6269BD1C9DAC265D34C6CFECB2A4D02ACD092822E1EC0335EC1BA0ED22DD5D832B6349BCAE8194BC550537B814492DFB96EE870B26B3B535F2C79E24705E662C11CAF10E0E081573BD8B12A393F9AEE5A9426C22F2F14C7EEDFADD47ACFC4AA01E0282C7AC03B667302A98CBD84902DC6BF66FBEDA65B84115D652EB8C479808B3542567F2ECCDCE06692FF06C653714E65E202AE7363C4C32A71A636EDA410AA0B8F4614E3927BF5821AD2E30B5ACF30201F35028994A8568D68E8CA28C1E2C3D482C6609AC36AD5583485034931DAAC6183776935E42C4F02ADF19730260AE56BB8C2839B1DCAE85E6F81747AF80A55A8D20132D77BACCFA3963896E9C431714D3BFB78DC74CDBC743151615C325AC3BF0DCBDBDB8CBEDE8E71A002C20B89A0E7D732AD8934262C5F29D4B600F4BC690136CBEC1E93FC8F07F6C5CB789D06D89523DD1BD6D98A3015C4950B9AAA45427A3A923B15D2DF53F030DD8E07F9E2461C5676A09D6A7928B2334C2B621B28B82A45BE731FC8ECBB030C3F85B03B7877EEFCB1B7E5736698E8723B55385337C6DF877FC8842343100030E9876CB98FB12E1749D1D6A77DDC94BCFB67B0C61C589C805A79F2B69AF01B2456B5491D776ADBD9C60466F7D099DDC395E6E297677DB98C9DE5D2BC6C5D7772A2AE30916C21825EA848AECA3447766327552527687C702A8344D008C39CA26A9933320A93764F4D0EECA250208321A4E465251135D7FEE9C69FBBD6B8162A4321D3133A6F23FD8A459B05E9C9003B4AE86B538EF5E1B769E14ED84AB3C963B3F8C64A9FF5979277ACF32EC2A65E65327001836AD53D66D420E2F39B42CF1CFC0BBB95EEAAC57D64262FFEBF7D57D7EB86430C3EB5E25EB183DA1196D8BA5E16B106D874EBBEF5E90256CFEE4DADC26A65EF8FF340CAA19B99CC298456C558E54F8B3155E3BF457FE61B1871C8605347BA2B399030ED93A26AAB17711795873DE7C62C1ECECD61AA2F54DFFF5FF6CE074937F51AED1811CADD4BFCD9D9C9B9937E4D43F1054932BB81427FEE0AC894E0F9CA81F299A9DAFADE2F3735C756E89A4D3136AA5533F83AD4465FE212EC6A6C04C1A4006521145B762B2744D01331F92408A5620EDF3F33F004790F2AE2CBE6780D1F295BFCC0749BEA94900782F33F9807F7058439D17D09FCA9F78A50FA8231D6B90B6D3E2911643F08B68A7FEFA9CFA0F200EE15F36C5A38163DD7DBADBC496673E0DA0470E644341DC03969E9B88EA9BCE9D041F34CBD852798B388773FE2EA344B017B82EDB603B6364EAB0CCABF1A496C195F7073105EEE7E444A31E5B57DA2BA0C8627B15328D713ECFE8596FCD269B9549EE31D89890D05049152EE7B5466296963E52BC368A2B874B2991123B14302234B6493C3E927B2B96C2A39A78A7D0331D19CE9291037F91877E76739ADE0D0D4FC8F20A5749907D4012DC7F54C904180B5C98C1B3ECB0363E22582E9604BB6F1D837D797E65BB0C798A810A41D4DC26923B56B79B8B26746D691865210C15F4B222D8F158A65B3FBAED2E81F3EFBA36CEE2BD7082ED8FD0CAC3948CC52CC9567D33DB07BA6A715CD4E66AA376C477F105A471E6F9A2620013C5FDAB9F064232942108D42C0117F40505AA77CBD6597AA47EDC1025CF532C07C432311B40A32927A3FD2794B8D708DF6E93844040F0A26D8B12A32020D3C49EF16F68CFBD5009D82DE4147D6341CDD3868B478C93276752FD3A175E23E4DF15329C671E0462E502B894C53778BE77BD94EFF9C1F3FA2B40A94A1E219056C2CA86A217C35223BF0265C5425953761943D9A68292D69372248A219E410D1FEA3621612907E102438C6D7B92D0868C03B8E5FE9D6AED83C4B8221DA6078451343ACC86EC5B3776F986031A0963BA78DC2045D04F599780DFB1E8277C96AB84EE3A27D145F8EE7A86C04BDC4A6AFA0A8CA9F58C55C60E32101B517EE1B154F60290F635FD13E4FAC422EA874AC104202899E020832C15FCD829ABA48CB43AE8D151B2E3654ADB1B6DDDEF1FC27393B647274A6A8DC10181C24404C56606E8A8D8FA7ADB3E1F104080F1618263342646C85BEC5C6E3E700000000000000000000000000000000000000000000000000000C152636""") + ), + new SigVerTestCase( + TestUtils.hexDecode(""" +09B4887D97BCF6379CC59B6162C1E8BF0560BF44D61809170E6E28F70669A3E9496438E8915735ADAEB445CFDB7D89B38C048F4C3E00581514C5FD198B2D1739E883B878D56BB41264BE41D3D51565E2E9CAE33184A899F62DD57D07400E98E58687A9B22FA317EED134CA7214BFF021DD2162B183091D15F263B7298214423C6BB696D75C20D9EACD0A03E4262C4B08BE39FA2154BD6E5025FF791E885F2226E3CF48F7B5EB04FBE9ECF75B19E1D15C305E92260AB0D6AE7DBA7BBE73B6BC181CF933840CC10A00050228FA46A2636DD9A90947E9F13A93EF4C62BE374D76D1FDBBC5D8B55E729FA58665AA07B90C8CDDD61C566B0D7ED65770492EA0713E1ED46AC7AD1503C56D9052D2C94D49E4416AC92B70396F76F6FB481045681725A68CB356377FB231AB8F3EB9A4982FFF1836473BCBDAB6872D229467EFB9366261FEB148BA9B7DB9C4FE0BB88612ABB8FD61096F1819604D55DF6020464D3F092CFCA59812082218566899A56A3C633CC81F88ADB2E1414EF3850D10BF5A77ACE724D6C1F388928744B3E542AE491CD56A64213F1D3CC90B29105F43D237C83D5FB829325C83E654577776392F8536AA9DAE872407ABAAA9ACC22A6812CEA74C0BA67EAF4A410152975E9A83EE4469295317BED10551BA32E65AFC8C8E68DD55420C502D937DADD2EFA2CBFD1F739FC0AB2B2654FAE08C0C7F8EDD43CF9FF0B01D984D491852A372E9FEFDCC1BC16CDB5239AE1001155F89563051CE47996C5AEEB2190EA18F7F734042DE68E988367D89355D9D8377BAF9647978EB2E492AD021C569AE8BA69B15F1FCF7039A7E64AF10ABF3EA45B7222F9659E33373372E1DB186D2C2A0D75451C478AEF33E5949F240040C2AFC44B1D3A02A6D2F87902A280E27A20D4E57F889662700DB8A9D249957A7DB437CD480DDC05884FB23F868268EACE34EED274A927D9D84F1EA57EAB1A813B5E6AABE9ED2610BC6F72E320CDEC4F99523F93FA448DC1FBBDD259B102F5DC9955AFA0C41604D83DD1C2D2295EF4461456BAE86905C4C30D8A9FA48C90F37A19C41A2D5988F13D51344EC30A4A46219FE841137D5AA1F51E6C444168AF39890B6FA400D67F4806F5BBD444703074A7A1139C71746D7C4CEB3C911F5257E3E53EBFA5AA8F227809D44EE7DE13C027924DD60153B30AA76DD96A7C5ACC59B627919507BF14257AE7A26243C1683B28D1B14B501AD059B4D522A57991E5539CEF18CEB5C26D660B8822454C9C42A95E6F72B84F78AB99F51EC49789F9DB4C128B0318FFFC82D95CAD277F11E14F1EF871414881122A9B11BDFAE4A7ABC8E75755AB13741DFACD664293D1A326BF5ED5ABBB153EBE6996DD622F0A8CB473969A50366BD0B01C5C73A892B8E26CE08F75FF801B6DEF041E1713BE6DF0EFB51587BE5FBEA727E00D717647DD539079DE18AE7BED12B91AF8DBB1B8B32D2860BAF40AF8A0BBFE02887EB5DBE7AB1AFC41DA79B016AA16EDA281321CAA5DA644FD8658A7B702181001431560DD63CB21E5FF75C3F7250456BE08C0D5E34C3BDE2F606A2BF3417768D24B23739EA86CBEFDDA34388BC1F918F951E15E43B1385A7BCC559F9492C7213A14227E093E929F32D1EFBE7F1EE57C49C9055623EA42EC6C79D7FCE71FA747607566DDA69F69DAF68115919C6322EBB42C8C089338C9E0C53565BCBE72FBE4726687B0787071806C5A6C149C82B668AA64A7BA0CCC1CC49A1EEE9453D04336E5DC811E03892F7F46688ECEFD04F1876F7111712B595ED62DA00678F9E3786B5C1A5095BE8710DCFA4165256509E00143A6F1172FABE8BF21E5FCE7C79C1A44B4B1525A076FFB8DD9066"""), + TestUtils.hexDecode(""" +3AFD7FF8CAD3ACBDF97731261C7A1C969D5016F17D3E7F83D2441AF9014B63477B14A6413150FAD7C84439BC88662C5E931F06B9514190E13FB049C4AB74013233B98D48D9AFB6A30A67330E1FBE331B09C56D037E9701085D80F1E7F4043EFB53587ABB823624012384515249EE6130973DC9EA6F558BAE75107EFDB1D9285B"""), + TestUtils.hexDecode(""" +4A2B16CDB552F9297F8E391AD8F5ADC8CC5D2C56C46B800F9B3EE4BBD2F2E8A89D599D7B5CC2D88C80F271859BBC83043EC4E54812F5936B446C9513C855289C94B11551A0C7653E7BA74FFB6F72D4652C91D38DD1F90DFE4439BC21CA53E0CC7A7AA5B875A5B9BA42366EB8ECBA2436DAF08A91978DD093F20F1EFB6B0BCB90DA99CCA05E8F6F82B86D3C6EE24BA5D50AEA10B2307F57F89ED78DB4A74FBBF6EB332AFB08D074ACF0DE5CD7FEC12F76F3AB619C815B9EDD287EAD67F04F14797F8DCF2CDE9A8753B5AD0AFA12874197D1744092872521E868AF9E64452373FEB6FE25D5273D63C0EBD6D3B1028C1CD06AF32CECA2621310837C72788C8ADAB5A0F03817128EB7B766FA812C696CF886F00A1044CDD06BB28CB2E5780C8D8CC7E60AB699DD78668BE4FF9F4690C6FC98AAC9C02B66B9B9826A3061FD3222DA8482667960A31652EE88EB32B0469AB71CAA2519F23D1A2442D5B1316262131DCEC5F287E32FD343FEB4429E54258D690D9D20A10ABD75A536DFF8CF1D6DDF19291E2749A7D16EB90AB5093BAD38E116A86B730E65574C068C38BA9457C9D6D913EAFF57FE23BF3DD24D8CA511EFA376A5DF08467025FF51BEAD3EDE0A84EDC5321620998061E8A1A73D67B7021B810C7867FF39187B59D403BF7C7506300C7345B1FE07C11278B0ABA61DBB4F2B8C43E74FEFA55ED52C10A8C490882BBFE3E3B3CE579E8116A9B6686C1A100AA1F6591F191F772B5A5A50DD6CC155CB5A1BE5BA122E91F044420156CD63080F0A45D662E76DD57BD0F689D0B299042BFF485E8A382D865C26CD46B4A54728BD48458362D79AC3EB756FC6C518C9E2F0E7D5A303AF1159EE6DBE7DD56BA0712857A68836C3C78C6C9F7488572813C0F6A814709D2BC142FEF02527CAE7712358371C5426522CCC64300C2CD9FBE20C6562E34835205FCDD5A8982C920BB477FB881702827B4911871394C06B5FECD0C740AF7B27637BAC1A0CBCA537E4433EA847454C693897A32E4D1844195426A0C6AED67472BD2C4EEE179F3F6084A36A7689F4CB1F8E5DB2DDE54ACC0666BA98415431A4B202F402FB1F1BCCDC23BFF13148C7B8F61FBF6243B296A78EB698189DA95BDA85DBC11D15FFDC6BF46C53F6E472A871401E9A9AB7F9FB467EB4ECB1F0DA7E63EE8619CBC486EBB0F2120A7811BFB0557D13930574297C9464FC595B27569ADF5F4A8DF669C9EEA0A250F4D22C2E8C641BA3902BA80800489965F11AF1E1A85717C624E742F161550819D1F0372C5CAE8BC62B549EFE874461080D06346E1FA6F01514FBECCB06E34EE271A0F0031790BDABE0F02BBA4AEA4B7397FE3333EB8121820757281F96A5831F9E490366549D16763FF19FF773580ED5E3E1E2AA3E38F88474DE6D9BA6994F8E629160488CB4CD5B878CDA37AAEC9B56369A7E73F73B428639A05C1378448ADB7F074DC8154D92E13C6356B5F466D66477159B2A943799AD619A029F3010D037672DBB6820E51323ADA98881C6DE859DF875ABAF11DA5DDCA5A777622BDAE8FACE2E0CED3B6A77B88A8729FB7C50933DA6C52E3F4D948F9DC153B5B1299CD8621DDFBA48AF44E4B6F6106EE7779501DD5FB3C578EA4D32C5C2F036A7352703ADD135AB84460162417E50BF91E60797D59B9E18D324DA971F4FF428AEAF23AC0BA4E2E2FC7ABAA6C8984FE9E2D85B8ADA4086B3C13ABD43CFD1C711D8326B18ADC34CC14CF8957EC3959498FC2A7BE06BD1840DE170366566E50741957763C2DD27ACF8C3F1026FAEE1D2562FA1052E69AFDD42F446F0598866D5D306BF1B775042B035927372827F4386316534FA1B7EE633BA958CED8F0D241D4688E3C7918E2A75626377C342A590692BBFB827BF90514182D4090DF8D7323519A1AB6CD0227367410DD14D3786A26DDF91724FC82D06A25D5F56683953E8E0F20E3C1771DAF42E52024C116ED8A4C0A611680F5FE00ED9B148D15F12AA95B9BD5A9FD8101642B36911F310B0DE18171D6237D9BE1725DC299A1A3AAAE98540CEED26953D10CE8547F1C3E46A862BED428D1E10601BF328C727FD95343E2DB4D9ACD5D1CB4715F6004096EDA093D1B0A33B1E56F16D73ADB8732CB4A31160A4491FAA0C86E680E3D7C02CCEA8FE92F1E001016D220221DD10ED626017966C3450AD121365918C93091F14712BA477CF2E263296C778A2BAEEF5849455FA35CB617251E02A22DAF5C33E5AAA9F00E8ACDC50ECF47C521503C52F27D6B57C8F2B3D8F1222413E7FA4EC59296338098C9AB5A1D8A57884BD860041406D9655D17382949A03D50F1108D05BDB31CA08E66F2D8DE480C6793518D49A60D4762A9EDDC0249B422E84020ED539A14E2478F68BAB1F2B00E22A5CBB62979AC744E08B57D5B578C401A8D26D9ADD1505236082863672D911CF3A0966D303F8917093BF97AF90A7E1F9D59B09206B9CAC35110FA38D5890ED2116835CE37384F5630F1C428E213605872ECF911B014B91C2C600E8A40729D07BF918790742C9279F3114F68CDF6594CDA3CA6694223A82F66C2B4BDF3E51C6FFDC55E0FF51EFD6C934362BE7D6FABC11B8B0DADDD52108FA5FB5CA758A64377D386D45CE70605B460E8157037B5B1B2E0AEDD12A633115D6C43BC6C7C836FFF33E7D033F2E5800527164C0C4781C37DF50B66BBA5C819473A1C5302083A16F01437279D2F2DF14C878269A2F3FA40C1C761ED61501AC9EF141029038C819954089B738098708174393FEAEA7B02AE5CEF67B3C8CE6A970675CA1B8C856DCF5972508C7C6B25EE4D12D8212B98940B488EC402AC7AE3C70DF938D1288CDA7A319E085BC73A469B2D2A3303B11A683100AF6DB86937BA1182903616E3F0347BD68591B47BA65156B93F260DE59B3AEB289E2A73A3BFF38C2F3ADEDA29C7E90283AC7B86D036B47D5BA1A03EC783D250BACAE5847E41F829CB33DE08DF8F7D69C9AA4EDE8D7AB968407EED31A056BA0EF8816E127AA90065A679E1CA9550DEEF25AC5B7A34F70DCF2B116CF351F3BADA99F836C730DCC1AE03F496CF3F0387A0C2C702E2C13BDD9CF45A1CD53AB58731188B18EA8BE48D510C5812E90BCECBC6E198E708B1C08C8F864B124BB4CC0BDBBDF2C2F4E388FC19660D69CC2C0EBF91008C8243DB42DDAF57C024251C4231DF53790CE575613EE8E1C7A33C1561F3504DEAAED1E8408500623ECA5AE5A2845411749930D8E42078C032349957FC39A1DA0EAF9E87C31FFBF6AC0C1811EB28A41B1D86BD7D49AD1C468A49594956525A20A31700F122F4C4BB2252A2F3D5C5D6873838C909597BBCAD8E1333D5D617C87C8EE0F1B22383B424B4C5C627298A3BECC1B32475C9DB6B9BDC6D6DCF50000000000000000000000000000000000000000000000000000000011192834""") + ), + new SigVerTestCase( + TestUtils.hexDecode(""" +09B4887D97BCF6379CC59B6162C1E8BF0560BF44D61809170E6E28F70669A3E9496438E8915735ADAEB445CFDB7D89B38C048F4C3E00581514C5FD198B2D1739E883B878D56BB41264BE41D3D51565E2E9CAE33184A899F62DD57D07400E98E58687A9B22FA317EED134CA7214BFF021DD2162B183091D15F263B7298214423C6BB696D75C20D9EACD0A03E4262C4B08BE39FA2154BD6E5025FF791E885F2226E3CF48F7B5EB04FBE9ECF75B19E1D15C305E92260AB0D6AE7DBA7BBE73B6BC181CF933840CC10A00050228FA46A2636DD9A90947E9F13A93EF4C62BE374D76D1FDBBC5D8B55E729FA58665AA07B90C8CDDD61C566B0D7ED65770492EA0713E1ED46AC7AD1503C56D9052D2C94D49E4416AC92B70396F76F6FB481045681725A68CB356377FB231AB8F3EB9A4982FFF1836473BCBDAB6872D229467EFB9366261FEB148BA9B7DB9C4FE0BB88612ABB8FD61096F1819604D55DF6020464D3F092CFCA59812082218566899A56A3C633CC81F88ADB2E1414EF3850D10BF5A77ACE724D6C1F388928744B3E542AE491CD56A64213F1D3CC90B29105F43D237C83D5FB829325C83E654577776392F8536AA9DAE872407ABAAA9ACC22A6812CEA74C0BA67EAF4A410152975E9A83EE4469295317BED10551BA32E65AFC8C8E68DD55420C502D937DADD2EFA2CBFD1F739FC0AB2B2654FAE08C0C7F8EDD43CF9FF0B01D984D491852A372E9FEFDCC1BC16CDB5239AE1001155F89563051CE47996C5AEEB2190EA18F7F734042DE68E988367D89355D9D8377BAF9647978EB2E492AD021C569AE8BA69B15F1FCF7039A7E64AF10ABF3EA45B7222F9659E33373372E1DB186D2C2A0D75451C478AEF33E5949F240040C2AFC44B1D3A02A6D2F87902A280E27A20D4E57F889662700DB8A9D249957A7DB437CD480DDC05884FB23F868268EACE34EED274A927D9D84F1EA57EAB1A813B5E6AABE9ED2610BC6F72E320CDEC4F99523F93FA448DC1FBBDD259B102F5DC9955AFA0C41604D83DD1C2D2295EF4461456BAE86905C4C30D8A9FA48C90F37A19C41A2D5988F13D51344EC30A4A46219FE841137D5AA1F51E6C444168AF39890B6FA400D67F4806F5BBD444703074A7A1139C71746D7C4CEB3C911F5257E3E53EBFA5AA8F227809D44EE7DE13C027924DD60153B30AA76DD96A7C5ACC59B627919507BF14257AE7A26243C1683B28D1B14B501AD059B4D522A57991E5539CEF18CEB5C26D660B8822454C9C42A95E6F72B84F78AB99F51EC49789F9DB4C128B0318FFFC82D95CAD277F11E14F1EF871414881122A9B11BDFAE4A7ABC8E75755AB13741DFACD664293D1A326BF5ED5ABBB153EBE6996DD622F0A8CB473969A50366BD0B01C5C73A892B8E26CE08F75FF801B6DEF041E1713BE6DF0EFB51587BE5FBEA727E00D717647DD539079DE18AE7BED12B91AF8DBB1B8B32D2860BAF40AF8A0BBFE02887EB5DBE7AB1AFC41DA79B016AA16EDA281321CAA5DA644FD8658A7B702181001431560DD63CB21E5FF75C3F7250456BE08C0D5E34C3BDE2F606A2BF3417768D24B23739EA86CBEFDDA34388BC1F918F951E15E43B1385A7BCC559F9492C7213A14227E093E929F32D1EFBE7F1EE57C49C9055623EA42EC6C79D7FCE71FA747607566DDA69F69DAF68115919C6322EBB42C8C089338C9E0C53565BCBE72FBE4726687B0787071806C5A6C149C82B668AA64A7BA0CCC1CC49A1EEE9453D04336E5DC811E03892F7F46688ECEFD04F1876F7111712B595ED62DA00678F9E3786B5C1A5095BE8710DCFA4165256509E00143A6F1172FABE8BF21E5FCE7C79C1A44B4B1525A076FFB8DD9066"""), + TestUtils.hexDecode(""" +0B36AE74905A488C25C9BF47B4144E12E75A8F54555E1943E3CF738BBF0B9C4ACC270A71804B0D8FEEEB0451AB504027C853125BEC7E7216A82EC09EEA3778291A6B97F53B1766FAB67CD3C875C171A36D5DC23835B7B5641C4689E646C40CC2B379131DF4AE848B8C4713A1E38F5C31140662F6F92BA22E888CA3C0A2F242C9"""), + TestUtils.hexDecode(""" +279860C94C551A0A0788099AB39F1F25BEE8CC4622D20DA037005B8D6B5B7371B11BADFC236C9B0028868DFE74A9AE59642CDFB8D38BA5A79CD52278E554C25B07A07C77C1420F8F0CC08A035C99BC4F0C303F20CA1BFC0E46E9FC6F37FF1BA5E5653656B7FB488C3B600E0BEF9F4A553A3D2FE5F0D2B76EBC90C5A2A99B789B55316ABBBCEED0EC70325CE2E89890FB2A19E30E79C4E8E619101FC2428D9579737DCB3FD76947FA7BF257FAF2FCC360051F55912F051DB24C51619439369F13F34D669DCD5638D3565101A7A4D379105EA6D83163D046DE3A6F9D9036CCC347DDF8B363E873D959C33D1B56775914ABD50EB6FD2D096E669F11C288781681D693A3A52188E80D0D33784D2F5FA1954D72C35D8929A2223577F8119CF241317D0E95C615641F40EEA3368BDA7619EEE82BC4B78717CE9E9D7036E0DD7DFFFD56CCC29D4F0EF46DFD4D07E4838BB513B2EEFA72BBFA0E9FEEBD1D2B96D9B8DBCAB4241FF7AB080ADBE1099AD3CEDC4597B23171E3ACA2027CD1B6E519EF29FDC21CD54EEAC264F4B2CDFBBB8104FE81C3C65691B0C309C31B877BF0B0DB37C6F44B9A11DDAFFCC40CEB1E78D2F86C2A0F902699EC1680E46F94DECDE4EC119F7742D3D47A383391B8DFD614E375B8C32271CDC49F054D2C26DEE4BC60C3A474888642DCD4BA1AE30CC8CAAE80AA9FCCA55528AA33FD4F732677E7D1B9E320247B299D6AD384D23D4E478AC2450F676B9BA27E5D4CB01F0EA50A62A2136DC4C2E1219C0E749444B2943890F36AF1EC2C273C42F22E0AEAEBD31FA8E6C9D1B8305A0AA8C2BA6601CCF28F46904231E648AFF4D4A72849A8E1EEDCC774FFB1479897C1804BB035671E8F90D462E3D2665B2A75DBAAD3BDB00C13E642A23E84ED48CE3E9B1632ABD0B7D579E7D18F508F33DABD97083EABD3CDCD1C70523A969B9C25E4011742EFBA6B3A09CC6CE627CF95BD51856DDC8C295DBBE180C86E0097FCE5741B3F0F6662B486D1B17987C3C47ECB101DC165372CA696FC477860F3DB7A68E3102B5A91BAC2A256467873C233ED212C7537470BFE88B41C3C239B5E38230E20CE2C41EF2C355884CF7F46CCF0CD688DEBEE8554D118F9088B4F807F19FE17732AD3C145E634CFCDCFF32A54F1C1D7A7879E6C022281130FD5A8188C560658F1AB6AD3EB3FB622D52A1939FE8668F2116A05F6EF6E1AAD846A4279FC3C699373A2FE17A3E9823FAA11F088846B36F5DB4BB9930101D5025350462D2F4866BB3010D9474B5630BDB57E71AE4277247DFF67F37E3CD9BD1307035249EB1EC316D25F913AC4B0BBB21D60CE2F4ED5F08D48D0C707795C177E7044E55D438AC12C2DB918C7087388650AB4AB19095C0A480232B1BA0C794991E89A650E070A5B562D9965C467D6CE834167EB6189A41B58E91685A034C70CD7723840A5561F0F751AA8F382A3772B07864547C1862E2433811633C97F58F85B9B14D3875ADCE2494D8BFA2E0773BF4637EDBD96AF9BAE43497CE2D63D59640C7723761C8AFB534189509A44794BB98A6D8E4AA3C5C3C136AA1C31CF20EFF2F5968FE4E71415DF760A52EC88BA438EF6110CD7F3B7FBE53B13999DD3EC4FCB5CFB4F9744578CEB60F800FFF2BABF330DC20DA5C128282C924244D9E5A18C3AC59DCD0D953156E2020751B708C0B025768963EDCF0DBAD16DD68A792A5E30981F17A4C355AE3E8036F9E289EEE35D9EF136AE402B4AFC7DD04190A8F0C8F66A66B701F995F7869855F59B47634B4A1F9E715E5059371B74D65D9501CA814F255D6C4D861B5C5A903B7ED44BF55CC18DB3CEA98D7CE951CD241A661E823F0A0EA92FA33A23294338E6F96D273DAF63BE9D5D5BE92FFEAA6078A9E8C5CADCC8AE79A1D5FC384519DF06A5832CE1DED5C7A6E937E86B854ECB1043169041A4BAD0FFEB13B0017B5BE16091AAC3F5DEB017B01EA00CA323AB44CCB193063406C970257DE61FAF1EE51105A22A4703562DFF1230AE241D67803FC6D997A1B016A73CE4346DF97F8ACE220CCFC3585B8307CD4B3AF74F6E0CF49A33CD5F5E53D04A197B4AA55ECCF645447B6033FE38DFE155AA979B2D4586D5249450E01532334C8F342BF81AF35980639C7E0AD431F3D3277F21F33A0622568E08D75A97CF2560826EF3DDB8A1E421217EE28B82D3BBB6FC499AE696567EF24681D482B051CA65DF9EB7F59965F03A68976F8A2542A58837CD3DA9EF5F4F06F94313B63B6B25EA67B1ACB4A0015F026D6A683BF533C3F730CD4D8A0CEF6D63100B4D9A1ADA15305A441A71B829AB2D33D3D209B598E05F19916569FFD262EE5D4160B8DF16E3FE63AA48029FD4F080D07602DEDC1B383F286202C287844D4063584087F29E36D5C19E54CF37DD504DB01452340D937D438C0E63EC35F948A4681D74D54CD6AF91262B075F55999137B5B94A2FE4E2668FBE44F68A892A91F8B5AEDB265BC0464F62C768BF346BC91AD9F9733E3DB9B846E2DBB0FEB3D00D817DB052C69474D77AAF7DCABF21E137F4C4607CFACFBCC7AF1F27BAF377B261358C7CD69394C33C89ED66F2579F29815B1FD957553FBF4F9FA4A5C85C223BDE78BA0722375BB8E7B02FFAD17DD7410F384A88DC0A77CA6345AE26A87FBB4753FCFB7EEA6ACE2061694746C8BE7E645D8848C5742ADD8815DD48AF19021591C7D7DDBF2DED046E7DF36F092127AC47432555F2BE60060433B561E7CEE0DDD1C5650B92898C8D6E01531CD373271A24A489D95FF24F4B4BB06AA39F56375F4B5B5BEEA5F4E5DD3B918136FA98AA2580A691334F8082DBEBF34943B27024C69C897D31897C2690C3D72C22133AB467E0626A4618FAF403A63DF25E2DA82D1191787D6487D87A6985F619CD6F1B7937F06E448501498DF0A1005D408D1CBD943ECC4EE03D038C5ED1FE462540DC937F0E4301502228D3B3755E3D31EDAB96D03AD1AB3E0A631AE80F86C3AE9321F35AF90F8D4D9B2B431BD529E2D29A29FE066269FB90248265088FBBBDE99B24A0F38282847D8FF4022AE6B611743A5B5472A4BF054B95F2CB09EA5E088E8AB172B7C3B53BB32986FEC298F41E2FA9D53D6F85254ED489A3F1FF01C07D33DEB98CA4EE704F27FD68F47B2E995E6706FC8D02454D7F2A73E50CD2AB15F973C9297B3B4989393588BB6C6CAEFF67BF2E241A158EA96C1A2FAF13FFBA4358A38928C2FFD0A7E32137E83256941DE749DFED36C63F2D07C557C7AFDBA351329899CE6D96DFD3442725BB1F24EC43EA41B4DE9E4E39D17A6F26384168DB92BF9516D7DD8101B970B83F2A2F323B418385C3D20410122D414A586970737BB0B1BAC6DA0B183244494F7375799AB0BDC5D1E2ECF3F4010C0E0F3537434E5366C6CCD7F1F20000000000000000000000000000000000000000000009192B3A""") + ), + new SigVerTestCase( + TestUtils.hexDecode(""" +09B4887D97BCF6379CC59B6162C1E8BF0560BF44D61809170E6E28F70669A3E9496438E8915735ADAEB445CFDB7D89B38C048F4C3E00581514C5FD198B2D1739E883B878D56BB41264BE41D3D51565E2E9CAE33184A899F62DD57D07400E98E58687A9B22FA317EED134CA7214BFF021DD2162B183091D15F263B7298214423C6BB696D75C20D9EACD0A03E4262C4B08BE39FA2154BD6E5025FF791E885F2226E3CF48F7B5EB04FBE9ECF75B19E1D15C305E92260AB0D6AE7DBA7BBE73B6BC181CF933840CC10A00050228FA46A2636DD9A90947E9F13A93EF4C62BE374D76D1FDBBC5D8B55E729FA58665AA07B90C8CDDD61C566B0D7ED65770492EA0713E1ED46AC7AD1503C56D9052D2C94D49E4416AC92B70396F76F6FB481045681725A68CB356377FB231AB8F3EB9A4982FFF1836473BCBDAB6872D229467EFB9366261FEB148BA9B7DB9C4FE0BB88612ABB8FD61096F1819604D55DF6020464D3F092CFCA59812082218566899A56A3C633CC81F88ADB2E1414EF3850D10BF5A77ACE724D6C1F388928744B3E542AE491CD56A64213F1D3CC90B29105F43D237C83D5FB829325C83E654577776392F8536AA9DAE872407ABAAA9ACC22A6812CEA74C0BA67EAF4A410152975E9A83EE4469295317BED10551BA32E65AFC8C8E68DD55420C502D937DADD2EFA2CBFD1F739FC0AB2B2654FAE08C0C7F8EDD43CF9FF0B01D984D491852A372E9FEFDCC1BC16CDB5239AE1001155F89563051CE47996C5AEEB2190EA18F7F734042DE68E988367D89355D9D8377BAF9647978EB2E492AD021C569AE8BA69B15F1FCF7039A7E64AF10ABF3EA45B7222F9659E33373372E1DB186D2C2A0D75451C478AEF33E5949F240040C2AFC44B1D3A02A6D2F87902A280E27A20D4E57F889662700DB8A9D249957A7DB437CD480DDC05884FB23F868268EACE34EED274A927D9D84F1EA57EAB1A813B5E6AABE9ED2610BC6F72E320CDEC4F99523F93FA448DC1FBBDD259B102F5DC9955AFA0C41604D83DD1C2D2295EF4461456BAE86905C4C30D8A9FA48C90F37A19C41A2D5988F13D51344EC30A4A46219FE841137D5AA1F51E6C444168AF39890B6FA400D67F4806F5BBD444703074A7A1139C71746D7C4CEB3C911F5257E3E53EBFA5AA8F227809D44EE7DE13C027924DD60153B30AA76DD96A7C5ACC59B627919507BF14257AE7A26243C1683B28D1B14B501AD059B4D522A57991E5539CEF18CEB5C26D660B8822454C9C42A95E6F72B84F78AB99F51EC49789F9DB4C128B0318FFFC82D95CAD277F11E14F1EF871414881122A9B11BDFAE4A7ABC8E75755AB13741DFACD664293D1A326BF5ED5ABBB153EBE6996DD622F0A8CB473969A50366BD0B01C5C73A892B8E26CE08F75FF801B6DEF041E1713BE6DF0EFB51587BE5FBEA727E00D717647DD539079DE18AE7BED12B91AF8DBB1B8B32D2860BAF40AF8A0BBFE02887EB5DBE7AB1AFC41DA79B016AA16EDA281321CAA5DA644FD8658A7B702181001431560DD63CB21E5FF75C3F7250456BE08C0D5E34C3BDE2F606A2BF3417768D24B23739EA86CBEFDDA34388BC1F918F951E15E43B1385A7BCC559F9492C7213A14227E093E929F32D1EFBE7F1EE57C49C9055623EA42EC6C79D7FCE71FA747607566DDA69F69DAF68115919C6322EBB42C8C089338C9E0C53565BCBE72FBE4726687B0787071806C5A6C149C82B668AA64A7BA0CCC1CC49A1EEE9453D04336E5DC811E03892F7F46688ECEFD04F1876F7111712B595ED62DA00678F9E3786B5C1A5095BE8710DCFA4165256509E00143A6F1172FABE8BF21E5FCE7C79C1A44B4B1525A076FFB8DD9066"""), + TestUtils.hexDecode(""" +3DE9C8CDA014784F23C8CB6D41294D39D27C9A5DF8F8D939B6F2D821824E584BC0BA516037E100C68C02480DAD436E12DD095DFFE293DF8E4AFFAFA0DA05516BD579B1B03B2A43307C7DF0D88624386593B226D4BA2EC5716A8C8B7A117C437DDACE31E6A902C403DD172DA7054A1BD679C01C1D822C3A075F5AB2002D2147A9"""), + TestUtils.hexDecode(""" +4A3C0683EE52A2E3703716E44D321208374CB0ECA74F9E6A624A1947B6788AD7F6AE68F320A580D35697E48B276779D4F5D2C8AF78177F12C9CD117875E0CB039293F140C24D80C895ECD7AE9C7C8AB72395A2736D7DAD6FE3EA57F21F9681806D821C91EB790BBD7F4AECA96100CA225A45CABE9372F48732B1A0745BBADAEA0594CD87875C05B703FDACEB441736811E2B6AAED172B6EDB8FDD087EF22D30CEEAA7F9E9A0DACD13D60749C0A04C376B804872A6C5056C37B9B64B4060CDBAC15B1C00CF9AC77DB99C506FDAE0AE16C198DE0BEFC4CABD6B38BC7E268112844B8ED5525A5624A36701A2F6AC6ACD2E4E40F01697E518B5F3107563865AE8537D04FAA57E1B71ECB1E2C2E36AEB3D8AA4674A04306E5179FB7A45CC6D57692BD787137DA3E6C5395D3F6A2EAAD0AF8F586912CC6E6DCD5DF34A6E4B0A574A350D760C646FB77C76377B6F88FACCD1B7187CC10E363FABDAB9D494E749E0EABE63D45901A54E06FCEA5A46487123C3C1107BBFFA87B7D7D92BC6793A7FA3CD18CA2E27DEE2213983D08863126FD79FADE804B48830AF687B02B4931357AC4247617AC13064804D3F780EE18A452613E9C1B188C0655FBA86F6ABD38E5F7D17267C747976C36EB37267759A9EDBD6624992F704684484FC562C8918788732DAEF29EC1386E73A2E2FD02BF7811E1D7A20822C8985AAF86B8E253AA7F0806BD6FA376557910497205393841BAFA34598B7E29EA9E67351CDA2966D0873BA914255649CDC89B2B64A751EB627F0C2D0963D391036C7297518A44C6783750C3CD6DF832AACA28FD5643F94A38571BCE04C3E29E2973CD6C6600C8102C1EA725DED21C50C90DCAEFF9D73756FF6BE91E8E766598EEBFC394F83C6D36FAD25B2DFC31D720E7E42763F10AD75D8C93775609CD7B0285F0247B52B797D11489CB4EC333C27E195ED8F7071E6C3E5E9220CAB46983B4013705F5934C0F1D61E70EFF9CD5FD293668BD3D0546A884D7AAED9EF7D2CA8E84A6BBDAF7FD8181FCC9D65FD74A4AA26DFBC42EC10484D7DC073E123F95CA705BF6CC3A803C186985721406994714949BD47161AC12AF72C0A358702CBA5A6AFF793D0DFDC7009861414CC3689E907D65BFE48751AE296D798912D49F4F849E43141E1BB050F9D17E5A0C4B7530E83463469F1D9443533AE36C57C6D80B915A3B3C8D9A3E43F5E6AD0187E8F828FFF7240EE9D4304255DA0528D0EF59FF1993731735245467B1BC5E6DFDE8895714F34562229E79AF8AB5E6269BD1C9DAC265D34C6CFECB2A4D02ACD092822E1EC0335EC1BA0ED22DD5D832B6349BCAE8194BC550537B814492DFB96EE870B26B3B535F2C79E24705E662C11CAF10E0E081573BD8B12A393F9AEE5A9426C22F2F14C7EEDFADD47ACFC4AA01E0282C7AC03B667302A98CBD84902DC6BF66FBEDA65B84115D652EB8C479808B3542567F2ECCDCE06692FF06C653714E65E202AE7363C4C32A71A636EDA410AA0B8F4614E3927BF5821AD2E30B5ACF30201F35028994A8568D68E8CA28C1E2C3D482C6609AC36AD5583485034931DAAC6183776935E42C4F02ADF19730260AE56BB8C2839B1DCAE85E6F81747AF80A55A8D20132D77BACCFA3963896E9C431714D3BFB78DC74CDBC743151615C325AC3BF0DCBDBDB8CBEDE8E71A002C20B89A0E7D732AD8934262C5F29D4B600F4BC690136CBEC1E93FC8F07F6C5CB789D06D89523DD1BD6D98A3015C4950B9AAA45427A3A923B15D2DF53F030DD8E07F9E2461C5676A09D6A7928B2334C2B621B28B82A45BE731FC8ECBB030C3F85B03B7877EEFCB1B7E5736698E8723B55385337C6DF877FC8842343100030E9876CB98FB12E1749D1D6A77DDC94BCFB67B0C61C589C805A79F2B69AF01B2456B5491D776ADBD9C60466F7D099DDC395E6E297677DB98C9DE5D2BC6C5D7772A2AE30916C21825EA848AECA3447766327552527687C702A8344D008C39CA26A9933320A93764F4D0EECA250208321A4E465251135D7FEE9C69FBBD6B8162A4321D3133A6F23FD8A459B05E9C9003B4AE86B538EF5E1B769E14ED84AB3C963B3F8C64A9FF5979277ACF32EC2A65E65327001836AD53D66D420E2F39B42CF1CFC0BBB95EEAAC57D64262FFEBF7D57D7EB86430C3EB5E25EB183DA1196D8BA5E16B106D874EBBEF5E90256CFEE4DADC26A65EF8FF340CAA19B99CC298456C558E54F8B3155E3BF457FE61B1871C8605347BA2B399030ED93A26AAB17711795873DE7C62C1ECECD61AA2F54DFFF5FF6CE074937F51AED1811CADD4BFCD9D9C9B9937E4D43F1054932BB81427FEE0AC894E0F9CA81F299A9DAFADE2F3735C756E89A4D3136AA5533F83AD4465FE212EC6A6C04C1A4006521145B762B2744D01331F92408A5620EDF3F33F004790F2AE2CBE6780D1F295BFCC0749BEA94900782F33F9807F7058439D17D09FCA9F78A50FA8231D6B90B6D3E2911643F08B68A7FEFA9CFA0F200EE15F36C5A38163DD7DBADBC496673E0DA0470E644341DC03969E9B88EA9BCE9D041F34CBD852798B388773FE2EA344B017B82EDB603B6364EAB0CCABF1A496C195F7073105EEE7E444A31E5B57DA2BA0C8627B15328D713ECFE8596FCD269B9549EE31D89890D05049152EE7B5466296963E52BC368A2B874B2991123B14302234B6493C3E927B2B96C2A39A78A7D0331D19CE9291037F91877E76739ADE0D0D4FC8F20A5749907D4012DC7F54C904180B5C98C1B3ECB0363E22582E9604BB6F1D837D797E65BB0C798A810A41D4DC26923B56B79B8B26746D691865210C15F4B222D8F158A65B3FBAED2E81F3EFBA36CEE2BD7082ED8FD0CAC3948CC52CC9567D33DB07BA6A715CD4E66AA376C477F105A471E6F9A2620013C5FDAB9F064232942108D42C0117F40505AA77CBD6597AA47EDC1025CF532C07C432311B40A32927A3FD2794B8D708DF6E93844040F0A26D8B12A32020D3C49EF16F68CFBD5009D82DE4147D6341CDD3868B478C93276752FD3A175E23E4DF15329C671E0462E502B894C53778BE77BD94EFF9C1F3FA2B40A94A1E219056C2CA86A217C35223BF0265C5425953761943D9A68292D69372248A219E410D1FEA3621612907E102438C6D7B92D0868C03B8E5FE9D6AED83C4B8221DA6078451343ACC86EC5B3776F986031A0963BA78DC2045D04F599780DFB1E8277C96AB84EE3A27D145F8EE7A86C04BDC4A6AFA0A8CA9F58C55C60E32101B517EE1B154F60290F635FD13E4FAC422EA874AC104202899E020832C15FCD829ABA48CB43AE8D151B2E3654ADB1B6DDDEF1FC27393B647274A6A8DC10181C24404C56606E8A8D8FA7ADB3E1F104080F1618263342646C85BEC5C6E3E700000000000000000000000000000000000000000000000000000C152636""") + ), + new SigVerTestCase( + TestUtils.hexDecode(""" +09B4887D97BCF6379CC59B6162C1E8BF0560BF44D61809170E6E28F70669A3E9496438E8915735ADAEB445CFDB7D89B38C048F4C3E00581514C5FD198B2D1739E883B878D56BB41264BE41D3D51565E2E9CAE33184A899F62DD57D07400E98E58687A9B22FA317EED134CA7214BFF021DD2162B183091D15F263B7298214423C6BB696D75C20D9EACD0A03E4262C4B08BE39FA2154BD6E5025FF791E885F2226E3CF48F7B5EB04FBE9ECF75B19E1D15C305E92260AB0D6AE7DBA7BBE73B6BC181CF933840CC10A00050228FA46A2636DD9A90947E9F13A93EF4C62BE374D76D1FDBBC5D8B55E729FA58665AA07B90C8CDDD61C566B0D7ED65770492EA0713E1ED46AC7AD1503C56D9052D2C94D49E4416AC92B70396F76F6FB481045681725A68CB356377FB231AB8F3EB9A4982FFF1836473BCBDAB6872D229467EFB9366261FEB148BA9B7DB9C4FE0BB88612ABB8FD61096F1819604D55DF6020464D3F092CFCA59812082218566899A56A3C633CC81F88ADB2E1414EF3850D10BF5A77ACE724D6C1F388928744B3E542AE491CD56A64213F1D3CC90B29105F43D237C83D5FB829325C83E654577776392F8536AA9DAE872407ABAAA9ACC22A6812CEA74C0BA67EAF4A410152975E9A83EE4469295317BED10551BA32E65AFC8C8E68DD55420C502D937DADD2EFA2CBFD1F739FC0AB2B2654FAE08C0C7F8EDD43CF9FF0B01D984D491852A372E9FEFDCC1BC16CDB5239AE1001155F89563051CE47996C5AEEB2190EA18F7F734042DE68E988367D89355D9D8377BAF9647978EB2E492AD021C569AE8BA69B15F1FCF7039A7E64AF10ABF3EA45B7222F9659E33373372E1DB186D2C2A0D75451C478AEF33E5949F240040C2AFC44B1D3A02A6D2F87902A280E27A20D4E57F889662700DB8A9D249957A7DB437CD480DDC05884FB23F868268EACE34EED274A927D9D84F1EA57EAB1A813B5E6AABE9ED2610BC6F72E320CDEC4F99523F93FA448DC1FBBDD259B102F5DC9955AFA0C41604D83DD1C2D2295EF4461456BAE86905C4C30D8A9FA48C90F37A19C41A2D5988F13D51344EC30A4A46219FE841137D5AA1F51E6C444168AF39890B6FA400D67F4806F5BBD444703074A7A1139C71746D7C4CEB3C911F5257E3E53EBFA5AA8F227809D44EE7DE13C027924DD60153B30AA76DD96A7C5ACC59B627919507BF14257AE7A26243C1683B28D1B14B501AD059B4D522A57991E5539CEF18CEB5C26D660B8822454C9C42A95E6F72B84F78AB99F51EC49789F9DB4C128B0318FFFC82D95CAD277F11E14F1EF871414881122A9B11BDFAE4A7ABC8E75755AB13741DFACD664293D1A326BF5ED5ABBB153EBE6996DD622F0A8CB473969A50366BD0B01C5C73A892B8E26CE08F75FF801B6DEF041E1713BE6DF0EFB51587BE5FBEA727E00D717647DD539079DE18AE7BED12B91AF8DBB1B8B32D2860BAF40AF8A0BBFE02887EB5DBE7AB1AFC41DA79B016AA16EDA281321CAA5DA644FD8658A7B702181001431560DD63CB21E5FF75C3F7250456BE08C0D5E34C3BDE2F606A2BF3417768D24B23739EA86CBEFDDA34388BC1F918F951E15E43B1385A7BCC559F9492C7213A14227E093E929F32D1EFBE7F1EE57C49C9055623EA42EC6C79D7FCE71FA747607566DDA69F69DAF68115919C6322EBB42C8C089338C9E0C53565BCBE72FBE4726687B0787071806C5A6C149C82B668AA64A7BA0CCC1CC49A1EEE9453D04336E5DC811E03892F7F46688ECEFD04F1876F7111712B595ED62DA00678F9E3786B5C1A5095BE8710DCFA4165256509E00143A6F1172FABE8BF21E5FCE7C79C1A44B4B1525A076FFB8DD9066"""), + TestUtils.hexDecode(""" +3AFD7FF8CAD3ACBDF97731261C7A1C969D5016F17D3E7F83D2441AF9014B63477B14A6413150FAD7C84439BC88662C5E931F06B9514190E13FB049C4AB74013233B98D48D9AFB6A30A67330E1FBE331B09C56D037E9701085D80F1E7F4043EFB53587ABB823624012384515249EE6130973DC9EA6F558BAE75107EFDB1D9285B"""), + TestUtils.hexDecode(""" +4A2B16CDB552F9297F8E391AD8F5ADC8CC5D2C56C46B800F9B3EE4BBD2F2E8A89D599D7B5CC2D88C80F271859BBC83043EC4E54812F5936B446C9513C855289C94B11551A0C7653E7BA74FFB6F72D4652C91D38DD1F90DFE4439BC21CA53E0CC7A7AA5B875A5B9BA42366EB8ECBA2436DAF08A91978DD093F20F1EFB6B0BCB90DA99CCA05E8F6F82B86D3C6EE24BA5D50AEA10B2307F57F89ED78DB4A74FBBF6EB332AFB08D074ACF0DE5CD7FEC12F76F3AB619C815B9EDD287EAD67F04F14797F8DCF2CDE9A8753B5AD0AFA12874197D1744092872521E868AF9E64452373FEB6FE25D5273D63C0EBD6D3B1028C1CD06AF32CECA2621310837C72788C8ADAB5A0F03817128EB7B766FA812C696CF886F00A1044CDD06BB28CB2E5780C8D8CC7E60AB699DD78668BE4FF9F4690C6FC98AAC9C02B66B9B9826A3061FD3222DA8482667960A31652EE88EB32B0469AB71CAA2519F23D1A2442D5B1316262131DCEC5F287E32FD343FEB4429E54258D690D9D20A10ABD75A536DFF8CF1D6DDF19291E2749A7D16EB90AB5093BAD38E116A86B730E65574C068C38BA9457C9D6D913EAFF57FE23BF3DD24D8CA511EFA376A5DF08467025FF51BEAD3EDE0A84EDC5321620998061E8A1A73D67B7021B810C7867FF39187B59D403BF7C7506300C7345B1FE07C11278B0ABA61DBB4F2B8C43E74FEFA55ED52C10A8C490882BBFE3E3B3CE579E8116A9B6686C1A100AA1F6591F191F772B5A5A50DD6CC155CB5A1BE5BA122E91F044420156CD63080F0A45D662E76DD57BD0F689D0B299042BFF485E8A382D865C26CD46B4A54728BD48458362D79AC3EB756FC6C518C9E2F0E7D5A303AF1159EE6DBE7DD56BA0712857A68836C3C78C6C9F7488572813C0F6A814709D2BC142FEF02527CAE7712358371C5426522CCC64300C2CD9FBE20C6562E34835205FCDD5A8982C920BB477FB881702827B4911871394C06B5FECD0C740AF7B27637BAC1A0CBCA537E4433EA847454C693897A32E4D1844195426A0C6AED67472BD2C4EEE179F3F6084A36A7689F4CB1F8E5DB2DDE54ACC0666BA98415431A4B202F402FB1F1BCCDC23BFF13148C7B8F61FBF6243B296A78EB698189DA95BDA85DBC11D15FFDC6BF46C53F6E472A871401E9A9AB7F9FB467EB4ECB1F0DA7E63EE8619CBC486EBB0F2120A7811BFB0557D13930574297C9464FC595B27569ADF5F4A8DF669C9EEA0A250F4D22C2E8C641BA3902BA80800489965F11AF1E1A85717C624E742F161550819D1F0372C5CAE8BC62B549EFE874461080D06346E1FA6F01514FBECCB06E34EE271A0F0031790BDABE0F02BBA4AEA4B7397FE3333EB8121820757281F96A5831F9E490366549D16763FF19FF773580ED5E3E1E2AA3E38F88474DE6D9BA6994F8E629160488CB4CD5B878CDA37AAEC9B56369A7E73F73B428639A05C1378448ADB7F074DC8154D92E13C6356B5F466D66477159B2A943799AD619A029F3010D037672DBB6820E51323ADA98881C6DE859DF875ABAF11DA5DDCA5A777622BDAE8FACE2E0CED3B6A77B88A8729FB7C50933DA6C52E3F4D948F9DC153B5B1299CD8621DDFBA48AF44E4B6F6106EE7779501DD5FB3C578EA4D32C5C2F036A7352703ADD135AB84460162417E50BF91E60797D59B9E18D324DA971F4FF428AEAF23AC0BA4E2E2FC7ABAA6C8984FE9E2D85B8ADA4086B3C13ABD43CFD1C711D8326B18ADC34CC14CF8957EC3959498FC2A7BE06BD1840DE170366566E50741957763C2DD27ACF8C3F1026FAEE1D2562FA1052E69AFDD42F446F0598866D5D306BF1B775042B035927372827F4386316534FA1B7EE633BA958CED8F0D241D4688E3C7918E2A75626377C342A590692BBFB827BF90514182D4090DF8D7323519A1AB6CD0227367410DD14D3786A26DDF91724FC82D06A25D5F56683953E8E0F20E3C1771DAF42E52024C116ED8A4C0A611680F5FE00ED9B148D15F12AA95B9BD5A9FD8101642B36911F310B0DE18171D6237D9BE1725DC299A1A3AAAE98540CEED26953D10CE8547F1C3E46A862BED428D1E10601BF328C727FD95343E2DB4D9ACD5D1CB4715F6004096EDA093D1B0A33B1E56F16D73ADB8732CB4A31160A4491FAA0C86E680E3D7C02CCEA8FE92F1E001016D220221DD10ED626017966C3450AD121365918C93091F14712BA477CF2E263296C778A2BAEEF5849455FA35CB617251E02A22DAF5C33E5AAA9F00E8ACDC50ECF47C521503C52F27D6B57C8F2B3D8F1222413E7FA4EC59296338098C9AB5A1D8A57884BD860041406D9655D17382949A03D50F1108D05BDB31CA08E66F2D8DE480C6793518D49A60D4762A9EDDC0249B422E84020ED539A14E2478F68BAB1F2B00E22A5CBB62979AC744E08B57D5B578C401A8D26D9ADD1505236082863672D911CF3A0966D303F8917093BF97AF90A7E1F9D59B09206B9CAC35110FA38D5890ED2116835CE37384F5630F1C428E213605872ECF911B014B91C2C600E8A40729D07BF918790742C9279F3114F68CDF6594CDA3CA6694223A82F66C2B4BDF3E51C6FFDC55E0FF51EFD6C934362BE7D6FABC11B8B0DADDD52108FA5FB5CA758A64377D386D45CE70605B460E8157037B5B1B2E0AEDD12A633115D6C43BC6C7C836FFF33E7D033F2E5800527164C0C4781C37DF50B66BBA5C819473A1C5302083A16F01437279D2F2DF14C878269A2F3FA40C1C761ED61501AC9EF141029038C819954089B738098708174393FEAEA7B02AE5CEF67B3C8CE6A970675CA1B8C856DCF5972508C7C6B25EE4D12D8212B98940B488EC402AC7AE3C70DF938D1288CDA7A319E085BC73A469B2D2A3303B11A683100AF6DB86937BA1182903616E3F0347BD68591B47BA65156B93F260DE59B3AEB289E2A73A3BFF38C2F3ADEDA29C7E90283AC7B86D036B47D5BA1A03EC783D250BACAE5847E41F829CB33DE08DF8F7D69C9AA4EDE8D7AB968407EED31A056BA0EF8816E127AA90065A679E1CA9550DEEF25AC5B7A34F70DCF2B116CF351F3BADA99F836C730DCC1AE03F496CF3F0387A0C2C702E2C13BDD9CF45A1CD53AB58731188B18EA8BE48D510C5812E90BCECBC6E198E708B1C08C8F864B124BB4CC0BDBBDF2C2F4E388FC19660D69CC2C0EBF91008C8243DB42DDAF57C024251C4231DF53790CE575613EE8E1C7A33C1561F3504DEAAED1E8408500623ECA5AE5A2845411749930D8E42078C032349957FC39A1DA0EAF9E87C31FFBF6AC0C1811EB28A41B1D86BD7D49AD1C468A49594956525A20A31700F122F4C4BB2252A2F3D5C5D6873838C909597BBCAD8E1333D5D617C87C8EE0F1B22383B424B4C5C627298A3BECC1B32475C9DB6B9BDC6D6DCF50000000000000000000000000000000000000000000000000000000011192834""") + ), + new SigVerTestCase( + TestUtils.hexDecode(""" +09B4887D97BCF6379CC59B6162C1E8BF0560BF44D61809170E6E28F70669A3E9496438E8915735ADAEB445CFDB7D89B38C048F4C3E00581514C5FD198B2D1739E883B878D56BB41264BE41D3D51565E2E9CAE33184A899F62DD57D07400E98E58687A9B22FA317EED134CA7214BFF021DD2162B183091D15F263B7298214423C6BB696D75C20D9EACD0A03E4262C4B08BE39FA2154BD6E5025FF791E885F2226E3CF48F7B5EB04FBE9ECF75B19E1D15C305E92260AB0D6AE7DBA7BBE73B6BC181CF933840CC10A00050228FA46A2636DD9A90947E9F13A93EF4C62BE374D76D1FDBBC5D8B55E729FA58665AA07B90C8CDDD61C566B0D7ED65770492EA0713E1ED46AC7AD1503C56D9052D2C94D49E4416AC92B70396F76F6FB481045681725A68CB356377FB231AB8F3EB9A4982FFF1836473BCBDAB6872D229467EFB9366261FEB148BA9B7DB9C4FE0BB88612ABB8FD61096F1819604D55DF6020464D3F092CFCA59812082218566899A56A3C633CC81F88ADB2E1414EF3850D10BF5A77ACE724D6C1F388928744B3E542AE491CD56A64213F1D3CC90B29105F43D237C83D5FB829325C83E654577776392F8536AA9DAE872407ABAAA9ACC22A6812CEA74C0BA67EAF4A410152975E9A83EE4469295317BED10551BA32E65AFC8C8E68DD55420C502D937DADD2EFA2CBFD1F739FC0AB2B2654FAE08C0C7F8EDD43CF9FF0B01D984D491852A372E9FEFDCC1BC16CDB5239AE1001155F89563051CE47996C5AEEB2190EA18F7F734042DE68E988367D89355D9D8377BAF9647978EB2E492AD021C569AE8BA69B15F1FCF7039A7E64AF10ABF3EA45B7222F9659E33373372E1DB186D2C2A0D75451C478AEF33E5949F240040C2AFC44B1D3A02A6D2F87902A280E27A20D4E57F889662700DB8A9D249957A7DB437CD480DDC05884FB23F868268EACE34EED274A927D9D84F1EA57EAB1A813B5E6AABE9ED2610BC6F72E320CDEC4F99523F93FA448DC1FBBDD259B102F5DC9955AFA0C41604D83DD1C2D2295EF4461456BAE86905C4C30D8A9FA48C90F37A19C41A2D5988F13D51344EC30A4A46219FE841137D5AA1F51E6C444168AF39890B6FA400D67F4806F5BBD444703074A7A1139C71746D7C4CEB3C911F5257E3E53EBFA5AA8F227809D44EE7DE13C027924DD60153B30AA76DD96A7C5ACC59B627919507BF14257AE7A26243C1683B28D1B14B501AD059B4D522A57991E5539CEF18CEB5C26D660B8822454C9C42A95E6F72B84F78AB99F51EC49789F9DB4C128B0318FFFC82D95CAD277F11E14F1EF871414881122A9B11BDFAE4A7ABC8E75755AB13741DFACD664293D1A326BF5ED5ABBB153EBE6996DD622F0A8CB473969A50366BD0B01C5C73A892B8E26CE08F75FF801B6DEF041E1713BE6DF0EFB51587BE5FBEA727E00D717647DD539079DE18AE7BED12B91AF8DBB1B8B32D2860BAF40AF8A0BBFE02887EB5DBE7AB1AFC41DA79B016AA16EDA281321CAA5DA644FD8658A7B702181001431560DD63CB21E5FF75C3F7250456BE08C0D5E34C3BDE2F606A2BF3417768D24B23739EA86CBEFDDA34388BC1F918F951E15E43B1385A7BCC559F9492C7213A14227E093E929F32D1EFBE7F1EE57C49C9055623EA42EC6C79D7FCE71FA747607566DDA69F69DAF68115919C6322EBB42C8C089338C9E0C53565BCBE72FBE4726687B0787071806C5A6C149C82B668AA64A7BA0CCC1CC49A1EEE9453D04336E5DC811E03892F7F46688ECEFD04F1876F7111712B595ED62DA00678F9E3786B5C1A5095BE8710DCFA4165256509E00143A6F1172FABE8BF21E5FCE7C79C1A44B4B1525A076FFB8DD9066"""), + TestUtils.hexDecode(""" +0B36AE74905A488C25C9BF47B4144E12E75A8F54555E1943E3CF738BBF0B9C4ACC270A71804B0D8FEEEB0451AB504027C853125BEC7E7216A82EC09EEA3778291A6B97F53B1766FAB67CD3C875C171A36D5DC23835B7B5641C4689E646C40CC2B379131DF4AE848B8C4713A1E38F5C31140662F6F92BA22E888CA3C0A2F242C9"""), + TestUtils.hexDecode(""" +279860C94C551A0A0788099AB39F1F25BEE8CC4622D20DA037005B8D6B5B7371B11BADFC236C9B0028868DFE74A9AE59642CDFB8D38BA5A79CD52278E554C25B07A07C77C1420F8F0CC08A035C99BC4F0C303F20CA1BFC0E46E9FC6F37FF1BA5E5653656B7FB488C3B600E0BEF9F4A553A3D2FE5F0D2B76EBC90C5A2A99B789B55316ABBBCEED0EC70325CE2E89890FB2A19E30E79C4E8E619101FC2428D9579737DCB3FD76947FA7BF257FAF2FCC360051F55912F051DB24C51619439369F13F34D669DCD5638D3565101A7A4D379105EA6D83163D046DE3A6F9D9036CCC347DDF8B363E873D959C33D1B56775914ABD50EB6FD2D096E669F11C288781681D693A3A52188E80D0D33784D2F5FA1954D72C35D8929A2223577F8119CF241317D0E95C615641F40EEA3368BDA7619EEE82BC4B78717CE9E9D7036E0DD7DFFFD56CCC29D4F0EF46DFD4D07E4838BB513B2EEFA72BBFA0E9FEEBD1D2B96D9B8DBCAB4241FF7AB080ADBE1099AD3CEDC4597B23171E3ACA2027CD1B6E519EF29FDC21CD54EEAC264F4B2CDFBBB8104FE81C3C65691B0C309C31B877BF0B0DB37C6F44B9A11DDAFFCC40CEB1E78D2F86C2A0F902699EC1680E46F94DECDE4EC119F7742D3D47A383391B8DFD614E375B8C32271CDC49F054D2C26DEE4BC60C3A474888642DCD4BA1AE30CC8CAAE80AA9FCCA55528AA33FD4F732677E7D1B9E320247B299D6AD384D23D4E478AC2450F676B9BA27E5D4CB01F0EA50A62A2136DC4C2E1219C0E749444B2943890F36AF1EC2C273C42F22E0AEAEBD31FA8E6C9D1B8305A0AA8C2BA6601CCF28F46904231E648AFF4D4A72849A8E1EEDCC774FFB1479897C1804BB035671E8F90D462E3D2665B2A75DBAAD3BDB00C13E642A23E84ED48CE3E9B1632ABD0B7D579E7D18F508F33DABD97083EABD3CDCD1C70523A969B9C25E4011742EFBA6B3A09CC6CE627CF95BD51856DDC8C295DBBE180C86E0097FCE5741B3F0F6662B486D1B17987C3C47ECB101DC165372CA696FC477860F3DB7A68E3102B5A91BAC2A256467873C233ED212C7537470BFE88B41C3C239B5E38230E20CE2C41EF2C355884CF7F46CCF0CD688DEBEE8554D118F9088B4F807F19FE17732AD3C145E634CFCDCFF32A54F1C1D7A7879E6C022281130FD5A8188C560658F1AB6AD3EB3FB622D52A1939FE8668F2116A05F6EF6E1AAD846A4279FC3C699373A2FE17A3E9823FAA11F088846B36F5DB4BB9930101D5025350462D2F4866BB3010D9474B5630BDB57E71AE4277247DFF67F37E3CD9BD1307035249EB1EC316D25F913AC4B0BBB21D60CE2F4ED5F08D48D0C707795C177E7044E55D438AC12C2DB918C7087388650AB4AB19095C0A480232B1BA0C794991E89A650E070A5B562D9965C467D6CE834167EB6189A41B58E91685A034C70CD7723840A5561F0F751AA8F382A3772B07864547C1862E2433811633C97F58F85B9B14D3875ADCE2494D8BFA2E0773BF4637EDBD96AF9BAE43497CE2D63D59640C7723761C8AFB534189509A44794BB98A6D8E4AA3C5C3C136AA1C31CF20EFF2F5968FE4E71415DF760A52EC88BA438EF6110CD7F3B7FBE53B13999DD3EC4FCB5CFB4F9744578CEB60F800FFF2BABF330DC20DA5C128282C924244D9E5A18C3AC59DCD0D953156E2020751B708C0B025768963EDCF0DBAD16DD68A792A5E30981F17A4C355AE3E8036F9E289EEE35D9EF136AE402B4AFC7DD04190A8F0C8F66A66B701F995F7869855F59B47634B4A1F9E715E5059371B74D65D9501CA814F255D6C4D861B5C5A903B7ED44BF55CC18DB3CEA98D7CE951CD241A661E823F0A0EA92FA33A23294338E6F96D273DAF63BE9D5D5BE92FFEAA6078A9E8C5CADCC8AE79A1D5FC384519DF06A5832CE1DED5C7A6E937E86B854ECB1043169041A4BAD0FFEB13B0017B5BE16091AAC3F5DEB017B01EA00CA323AB44CCB193063406C970257DE61FAF1EE51105A22A4703562DFF1230AE241D67803FC6D997A1B016A73CE4346DF97F8ACE220CCFC3585B8307CD4B3AF74F6E0CF49A33CD5F5E53D04A197B4AA55ECCF645447B6033FE38DFE155AA979B2D4586D5249450E01532334C8F342BF81AF35980639C7E0AD431F3D3277F21F33A0622568E08D75A97CF2560826EF3DDB8A1E421217EE28B82D3BBB6FC499AE696567EF24681D482B051CA65DF9EB7F59965F03A68976F8A2542A58837CD3DA9EF5F4F06F94313B63B6B25EA67B1ACB4A0015F026D6A683BF533C3F730CD4D8A0CEF6D63100B4D9A1ADA15305A441A71B829AB2D33D3D209B598E05F19916569FFD262EE5D4160B8DF16E3FE63AA48029FD4F080D07602DEDC1B383F286202C287844D4063584087F29E36D5C19E54CF37DD504DB01452340D937D438C0E63EC35F948A4681D74D54CD6AF91262B075F55999137B5B94A2FE4E2668FBE44F68A892A91F8B5AEDB265BC0464F62C768BF346BC91AD9F9733E3DB9B846E2DBB0FEB3D00D817DB052C69474D77AAF7DCABF21E137F4C4607CFACFBCC7AF1F27BAF377B261358C7CD69394C33C89ED66F2579F29815B1FD957553FBF4F9FA4A5C85C223BDE78BA0722375BB8E7B02FFAD17DD7410F384A88DC0A77CA6345AE26A87FBB4753FCFB7EEA6ACE2061694746C8BE7E645D8848C5742ADD8815DD48AF19021591C7D7DDBF2DED046E7DF36F092127AC47432555F2BE60060433B561E7CEE0DDD1C5650B92898C8D6E01531CD373271A24A489D95FF24F4B4BB06AA39F56375F4B5B5BEEA5F4E5DD3B918136FA98AA2580A691334F8082DBEBF34943B27024C69C897D31897C2690C3D72C22133AB467E0626A4618FAF403A63DF25E2DA82D1191787D6487D87A6985F619CD6F1B7937F06E448501498DF0A1005D408D1CBD943ECC4EE03D038C5ED1FE462540DC937F0E4301502228D3B3755E3D31EDAB96D03AD1AB3E0A631AE80F86C3AE9321F35AF90F8D4D9B2B431BD529E2D29A29FE066269FB90248265088FBBBDE99B24A0F38282847D8FF4022AE6B611743A5B5472A4BF054B95F2CB09EA5E088E8AB172B7C3B53BB32986FEC298F41E2FA9D53D6F85254ED489A3F1FF01C07D33DEB98CA4EE704F27FD68F47B2E995E6706FC8D02454D7F2A73E50CD2AB15F973C9297B3B4989393588BB6C6CAEFF67BF2E241A158EA96C1A2FAF13FFBA4358A38928C2FFD0A7E32137E83256941DE749DFED36C63F2D07C557C7AFDBA351329899CE6D96DFD3442725BB1F24EC43EA41B4DE9E4E39D17A6F26384168DB92BF9516D7DD8101B970B83F2A2F323B418385C3D20410122D414A586970737BB0B1BAC6DA0B183244494F7375799AB0BDC5D1E2ECF3F4010C0E0F3537434E5366C6CCD7F1F20000000000000000000000000000000000000000000009192B3A""") + ), + new SigVerTestCase( + TestUtils.hexDecode(""" +09B4887D97BCF6379CC59B6162C1E8BF0560BF44D61809170E6E28F70669A3E9496438E8915735ADAEB445CFDB7D89B38C048F4C3E00581514C5FD198B2D1739E883B878D56BB41264BE41D3D51565E2E9CAE33184A899F62DD57D07400E98E58687A9B22FA317EED134CA7214BFF021DD2162B183091D15F263B7298214423C6BB696D75C20D9EACD0A03E4262C4B08BE39FA2154BD6E5025FF791E885F2226E3CF48F7B5EB04FBE9ECF75B19E1D15C305E92260AB0D6AE7DBA7BBE73B6BC181CF933840CC10A00050228FA46A2636DD9A90947E9F13A93EF4C62BE374D76D1FDBBC5D8B55E729FA58665AA07B90C8CDDD61C566B0D7ED65770492EA0713E1ED46AC7AD1503C56D9052D2C94D49E4416AC92B70396F76F6FB481045681725A68CB356377FB231AB8F3EB9A4982FFF1836473BCBDAB6872D229467EFB9366261FEB148BA9B7DB9C4FE0BB88612ABB8FD61096F1819604D55DF6020464D3F092CFCA59812082218566899A56A3C633CC81F88ADB2E1414EF3850D10BF5A77ACE724D6C1F388928744B3E542AE491CD56A64213F1D3CC90B29105F43D237C83D5FB829325C83E654577776392F8536AA9DAE872407ABAAA9ACC22A6812CEA74C0BA67EAF4A410152975E9A83EE4469295317BED10551BA32E65AFC8C8E68DD55420C502D937DADD2EFA2CBFD1F739FC0AB2B2654FAE08C0C7F8EDD43CF9FF0B01D984D491852A372E9FEFDCC1BC16CDB5239AE1001155F89563051CE47996C5AEEB2190EA18F7F734042DE68E988367D89355D9D8377BAF9647978EB2E492AD021C569AE8BA69B15F1FCF7039A7E64AF10ABF3EA45B7222F9659E33373372E1DB186D2C2A0D75451C478AEF33E5949F240040C2AFC44B1D3A02A6D2F87902A280E27A20D4E57F889662700DB8A9D249957A7DB437CD480DDC05884FB23F868268EACE34EED274A927D9D84F1EA57EAB1A813B5E6AABE9ED2610BC6F72E320CDEC4F99523F93FA448DC1FBBDD259B102F5DC9955AFA0C41604D83DD1C2D2295EF4461456BAE86905C4C30D8A9FA48C90F37A19C41A2D5988F13D51344EC30A4A46219FE841137D5AA1F51E6C444168AF39890B6FA400D67F4806F5BBD444703074A7A1139C71746D7C4CEB3C911F5257E3E53EBFA5AA8F227809D44EE7DE13C027924DD60153B30AA76DD96A7C5ACC59B627919507BF14257AE7A26243C1683B28D1B14B501AD059B4D522A57991E5539CEF18CEB5C26D660B8822454C9C42A95E6F72B84F78AB99F51EC49789F9DB4C128B0318FFFC82D95CAD277F11E14F1EF871414881122A9B11BDFAE4A7ABC8E75755AB13741DFACD664293D1A326BF5ED5ABBB153EBE6996DD622F0A8CB473969A50366BD0B01C5C73A892B8E26CE08F75FF801B6DEF041E1713BE6DF0EFB51587BE5FBEA727E00D717647DD539079DE18AE7BED12B91AF8DBB1B8B32D2860BAF40AF8A0BBFE02887EB5DBE7AB1AFC41DA79B016AA16EDA281321CAA5DA644FD8658A7B702181001431560DD63CB21E5FF75C3F7250456BE08C0D5E34C3BDE2F606A2BF3417768D24B23739EA86CBEFDDA34388BC1F918F951E15E43B1385A7BCC559F9492C7213A14227E093E929F32D1EFBE7F1EE57C49C9055623EA42EC6C79D7FCE71FA747607566DDA69F69DAF68115919C6322EBB42C8C089338C9E0C53565BCBE72FBE4726687B0787071806C5A6C149C82B668AA64A7BA0CCC1CC49A1EEE9453D04336E5DC811E03892F7F46688ECEFD04F1876F7111712B595ED62DA00678F9E3786B5C1A5095BE8710DCFA4165256509E00143A6F1172FABE8BF21E5FCE7C79C1A44B4B1525A076FFB8DD9066"""), + TestUtils.hexDecode(""" +3DE9C8CDA014784F23C8CB6D41294D39D27C9A5DF8F8D939B6F2D821824E584BC0BA516037E100C68C02480DAD436E12DD095DFFE293DF8E4AFFAFA0DA05516BD579B1B03B2A43307C7DF0D88624386593B226D4BA2EC5716A8C8B7A117C437DDACE31E6A902C403DD172DA7054A1BD679C01C1D822C3A075F5AB2002D2147A9"""), + TestUtils.hexDecode(""" +4A3C0683EE52A2E3703716E44D321208374CB0ECA74F9E6A624A1947B6788AD7F6AE68F320A580D35697E48B276779D4F5D2C8AF78177F12C9CD117875E0CB039293F140C24D80C895ECD7AE9C7C8AB72395A2736D7DAD6FE3EA57F21F9681806D821C91EB790BBD7F4AECA96100CA225A45CABE9372F48732B1A0745BBADAEA0594CD87875C05B703FDACEB441736811E2B6AAED172B6EDB8FDD087EF22D30CEEAA7F9E9A0DACD13D60749C0A04C376B804872A6C5056C37B9B64B4060CDBAC15B1C00CF9AC77DB99C506FDAE0AE16C198DE0BEFC4CABD6B38BC7E268112844B8ED5525A5624A36701A2F6AC6ACD2E4E40F01697E518B5F3107563865AE8537D04FAA57E1B71ECB1E2C2E36AEB3D8AA4674A04306E5179FB7A45CC6D57692BD787137DA3E6C5395D3F6A2EAAD0AF8F586912CC6E6DCD5DF34A6E4B0A574A350D760C646FB77C76377B6F88FACCD1B7187CC10E363FABDAB9D494E749E0EABE63D45901A54E06FCEA5A46487123C3C1107BBFFA87B7D7D92BC6793A7FA3CD18CA2E27DEE2213983D08863126FD79FADE804B48830AF687B02B4931357AC4247617AC13064804D3F780EE18A452613E9C1B188C0655FBA86F6ABD38E5F7D17267C747976C36EB37267759A9EDBD6624992F704684484FC562C8918788732DAEF29EC1386E73A2E2FD02BF7811E1D7A20822C8985AAF86B8E253AA7F0806BD6FA376557910497205393841BAFA34598B7E29EA9E67351CDA2966D0873BA914255649CDC89B2B64A751EB627F0C2D0963D391036C7297518A44C6783750C3CD6DF832AACA28FD5643F94A38571BCE04C3E29E2973CD6C6600C8102C1EA725DED21C50C90DCAEFF9D73756FF6BE91E8E766598EEBFC394F83C6D36FAD25B2DFC31D720E7E42763F10AD75D8C93775609CD7B0285F0247B52B797D11489CB4EC333C27E195ED8F7071E6C3E5E9220CAB46983B4013705F5934C0F1D61E70EFF9CD5FD293668BD3D0546A884D7AAED9EF7D2CA8E84A6BBDAF7FD8181FCC9D65FD74A4AA26DFBC42EC10484D7DC073E123F95CA705BF6CC3A803C186985721406994714949BD47161AC12AF72C0A358702CBA5A6AFF793D0DFDC7009861414CC3689E907D65BFE48751AE296D798912D49F4F849E43141E1BB050F9D17E5A0C4B7530E83463469F1D9443533AE36C57C6D80B915A3B3C8D9A3E43F5E6AD0187E8F828FFF7240EE9D4304255DA0528D0EF59FF1993731735245467B1BC5E6DFDE8895714F34562229E79AF8AB5E6269BD1C9DAC265D34C6CFECB2A4D02ACD092822E1EC0335EC1BA0ED22DD5D832B6349BCAE8194BC550537B814492DFB96EE870B26B3B535F2C79E24705E662C11CAF10E0E081573BD8B12A393F9AEE5A9426C22F2F14C7EEDFADD47ACFC4AA01E0282C7AC03B667302A98CBD84902DC6BF66FBEDA65B84115D652EB8C479808B3542567F2ECCDCE06692FF06C653714E65E202AE7363C4C32A71A636EDA410AA0B8F4614E3927BF5821AD2E30B5ACF30201F35028994A8568D68E8CA28C1E2C3D482C6609AC36AD5583485034931DAAC6183776935E42C4F02ADF19730260AE56BB8C2839B1DCAE85E6F81747AF80A55A8D20132D77BACCFA3963896E9C431714D3BFB78DC74CDBC743151615C325AC3BF0DCBDBDB8CBEDE8E71A002C20B89A0E7D732AD8934262C5F29D4B600F4BC690136CBEC1E93FC8F07F6C5CB789D06D89523DD1BD6D98A3015C4950B9AAA45427A3A923B15D2DF53F030DD8E07F9E2461C5676A09D6A7928B2334C2B621B28B82A45BE731FC8ECBB030C3F85B03B7877EEFCB1B7E5736698E8723B55385337C6DF877FC8842343100030E9876CB98FB12E1749D1D6A77DDC94BCFB67B0C61C589C805A79F2B69AF01B2456B5491D776ADBD9C60466F7D099DDC395E6E297677DB98C9DE5D2BC6C5D7772A2AE30916C21825EA848AECA3447766327552527687C702A8344D008C39CA26A9933320A93764F4D0EECA250208321A4E465251135D7FEE9C69FBBD6B8162A4321D3133A6F23FD8A459B05E9C9003B4AE86B538EF5E1B769E14ED84AB3C963B3F8C64A9FF5979277ACF32EC2A65E65327001836AD53D66D420E2F39B42CF1CFC0BBB95EEAAC57D64262FFEBF7D57D7EB86430C3EB5E25EB183DA1196D8BA5E16B106D874EBBEF5E90256CFEE4DADC26A65EF8FF340CAA19B99CC298456C558E54F8B3155E3BF457FE61B1871C8605347BA2B399030ED93A26AAB17711795873DE7C62C1ECECD61AA2F54DFFF5FF6CE074937F51AED1811CADD4BFCD9D9C9B9937E4D43F1054932BB81427FEE0AC894E0F9CA81F299A9DAFADE2F3735C756E89A4D3136AA5533F83AD4465FE212EC6A6C04C1A4006521145B762B2744D01331F92408A5620EDF3F33F004790F2AE2CBE6780D1F295BFCC0749BEA94900782F33F9807F7058439D17D09FCA9F78A50FA8231D6B90B6D3E2911643F08B68A7FEFA9CFA0F200EE15F36C5A38163DD7DBADBC496673E0DA0470E644341DC03969E9B88EA9BCE9D041F34CBD852798B388773FE2EA344B017B82EDB603B6364EAB0CCABF1A496C195F7073105EEE7E444A31E5B57DA2BA0C8627B15328D713ECFE8596FCD269B9549EE31D89890D05049152EE7B5466296963E52BC368A2B874B2991123B14302234B6493C3E927B2B96C2A39A78A7D0331D19CE9291037F91877E76739ADE0D0D4FC8F20A5749907D4012DC7F54C904180B5C98C1B3ECB0363E22582E9604BB6F1D837D797E65BB0C798A810A41D4DC26923B56B79B8B26746D691865210C15F4B222D8F158A65B3FBAED2E81F3EFBA36CEE2BD7082ED8FD0CAC3948CC52CC9567D33DB07BA6A715CD4E66AA376C477F105A471E6F9A2620013C5FDAB9F064232942108D42C0117F40505AA77CBD6597AA47EDC1025CF532C07C432311B40A32927A3FD2794B8D708DF6E93844040F0A26D8B12A32020D3C49EF16F68CFBD5009D82DE4147D6341CDD3868B478C93276752FD3A175E23E4DF15329C671E0462E502B894C53778BE77BD94EFF9C1F3FA2B40A94A1E219056C2CA86A217C35223BF0265C5425953761943D9A68292D69372248A219E410D1FEA3621612907E102438C6D7B92D0868C03B8E5FE9D6AED83C4B8221DA6078451343ACC86EC5B3776F986031A0963BA78DC2045D04F599780DFB1E8277C96AB84EE3A27D145F8EE7A86C04BDC4A6AFA0A8CA9F58C55C60E32101B517EE1B154F60290F635FD13E4FAC422EA874AC104202899E020832C15FCD829ABA48CB43AE8D151B2E3654ADB1B6DDDEF1FC27393B647274A6A8DC10181C24404C56606E8A8D8FA7ADB3E1F104080F1618263342646C85BEC5C6E3E700000000000000000000000000000000000000000000000000000C152636""") + ), + new SigVerTestCase( + TestUtils.hexDecode(""" +09B4887D97BCF6379CC59B6162C1E8BF0560BF44D61809170E6E28F70669A3E9496438E8915735ADAEB445CFDB7D89B38C048F4C3E00581514C5FD198B2D1739E883B878D56BB41264BE41D3D51565E2E9CAE33184A899F62DD57D07400E98E58687A9B22FA317EED134CA7214BFF021DD2162B183091D15F263B7298214423C6BB696D75C20D9EACD0A03E4262C4B08BE39FA2154BD6E5025FF791E885F2226E3CF48F7B5EB04FBE9ECF75B19E1D15C305E92260AB0D6AE7DBA7BBE73B6BC181CF933840CC10A00050228FA46A2636DD9A90947E9F13A93EF4C62BE374D76D1FDBBC5D8B55E729FA58665AA07B90C8CDDD61C566B0D7ED65770492EA0713E1ED46AC7AD1503C56D9052D2C94D49E4416AC92B70396F76F6FB481045681725A68CB356377FB231AB8F3EB9A4982FFF1836473BCBDAB6872D229467EFB9366261FEB148BA9B7DB9C4FE0BB88612ABB8FD61096F1819604D55DF6020464D3F092CFCA59812082218566899A56A3C633CC81F88ADB2E1414EF3850D10BF5A77ACE724D6C1F388928744B3E542AE491CD56A64213F1D3CC90B29105F43D237C83D5FB829325C83E654577776392F8536AA9DAE872407ABAAA9ACC22A6812CEA74C0BA67EAF4A410152975E9A83EE4469295317BED10551BA32E65AFC8C8E68DD55420C502D937DADD2EFA2CBFD1F739FC0AB2B2654FAE08C0C7F8EDD43CF9FF0B01D984D491852A372E9FEFDCC1BC16CDB5239AE1001155F89563051CE47996C5AEEB2190EA18F7F734042DE68E988367D89355D9D8377BAF9647978EB2E492AD021C569AE8BA69B15F1FCF7039A7E64AF10ABF3EA45B7222F9659E33373372E1DB186D2C2A0D75451C478AEF33E5949F240040C2AFC44B1D3A02A6D2F87902A280E27A20D4E57F889662700DB8A9D249957A7DB437CD480DDC05884FB23F868268EACE34EED274A927D9D84F1EA57EAB1A813B5E6AABE9ED2610BC6F72E320CDEC4F99523F93FA448DC1FBBDD259B102F5DC9955AFA0C41604D83DD1C2D2295EF4461456BAE86905C4C30D8A9FA48C90F37A19C41A2D5988F13D51344EC30A4A46219FE841137D5AA1F51E6C444168AF39890B6FA400D67F4806F5BBD444703074A7A1139C71746D7C4CEB3C911F5257E3E53EBFA5AA8F227809D44EE7DE13C027924DD60153B30AA76DD96A7C5ACC59B627919507BF14257AE7A26243C1683B28D1B14B501AD059B4D522A57991E5539CEF18CEB5C26D660B8822454C9C42A95E6F72B84F78AB99F51EC49789F9DB4C128B0318FFFC82D95CAD277F11E14F1EF871414881122A9B11BDFAE4A7ABC8E75755AB13741DFACD664293D1A326BF5ED5ABBB153EBE6996DD622F0A8CB473969A50366BD0B01C5C73A892B8E26CE08F75FF801B6DEF041E1713BE6DF0EFB51587BE5FBEA727E00D717647DD539079DE18AE7BED12B91AF8DBB1B8B32D2860BAF40AF8A0BBFE02887EB5DBE7AB1AFC41DA79B016AA16EDA281321CAA5DA644FD8658A7B702181001431560DD63CB21E5FF75C3F7250456BE08C0D5E34C3BDE2F606A2BF3417768D24B23739EA86CBEFDDA34388BC1F918F951E15E43B1385A7BCC559F9492C7213A14227E093E929F32D1EFBE7F1EE57C49C9055623EA42EC6C79D7FCE71FA747607566DDA69F69DAF68115919C6322EBB42C8C089338C9E0C53565BCBE72FBE4726687B0787071806C5A6C149C82B668AA64A7BA0CCC1CC49A1EEE9453D04336E5DC811E03892F7F46688ECEFD04F1876F7111712B595ED62DA00678F9E3786B5C1A5095BE8710DCFA4165256509E00143A6F1172FABE8BF21E5FCE7C79C1A44B4B1525A076FFB8DD9066"""), + TestUtils.hexDecode(""" +3AFD7FF8CAD3ACBDF97731261C7A1C969D5016F17D3E7F83D2441AF9014B63477B14A6413150FAD7C84439BC88662C5E931F06B9514190E13FB049C4AB74013233B98D48D9AFB6A30A67330E1FBE331B09C56D037E9701085D80F1E7F4043EFB53587ABB823624012384515249EE6130973DC9EA6F558BAE75107EFDB1D9285B"""), + TestUtils.hexDecode(""" +4A2B16CDB552F9297F8E391AD8F5ADC8CC5D2C56C46B800F9B3EE4BBD2F2E8A89D599D7B5CC2D88C80F271859BBC83043EC4E54812F5936B446C9513C855289C94B11551A0C7653E7BA74FFB6F72D4652C91D38DD1F90DFE4439BC21CA53E0CC7A7AA5B875A5B9BA42366EB8ECBA2436DAF08A91978DD093F20F1EFB6B0BCB90DA99CCA05E8F6F82B86D3C6EE24BA5D50AEA10B2307F57F89ED78DB4A74FBBF6EB332AFB08D074ACF0DE5CD7FEC12F76F3AB619C815B9EDD287EAD67F04F14797F8DCF2CDE9A8753B5AD0AFA12874197D1744092872521E868AF9E64452373FEB6FE25D5273D63C0EBD6D3B1028C1CD06AF32CECA2621310837C72788C8ADAB5A0F03817128EB7B766FA812C696CF886F00A1044CDD06BB28CB2E5780C8D8CC7E60AB699DD78668BE4FF9F4690C6FC98AAC9C02B66B9B9826A3061FD3222DA8482667960A31652EE88EB32B0469AB71CAA2519F23D1A2442D5B1316262131DCEC5F287E32FD343FEB4429E54258D690D9D20A10ABD75A536DFF8CF1D6DDF19291E2749A7D16EB90AB5093BAD38E116A86B730E65574C068C38BA9457C9D6D913EAFF57FE23BF3DD24D8CA511EFA376A5DF08467025FF51BEAD3EDE0A84EDC5321620998061E8A1A73D67B7021B810C7867FF39187B59D403BF7C7506300C7345B1FE07C11278B0ABA61DBB4F2B8C43E74FEFA55ED52C10A8C490882BBFE3E3B3CE579E8116A9B6686C1A100AA1F6591F191F772B5A5A50DD6CC155CB5A1BE5BA122E91F044420156CD63080F0A45D662E76DD57BD0F689D0B299042BFF485E8A382D865C26CD46B4A54728BD48458362D79AC3EB756FC6C518C9E2F0E7D5A303AF1159EE6DBE7DD56BA0712857A68836C3C78C6C9F7488572813C0F6A814709D2BC142FEF02527CAE7712358371C5426522CCC64300C2CD9FBE20C6562E34835205FCDD5A8982C920BB477FB881702827B4911871394C06B5FECD0C740AF7B27637BAC1A0CBCA537E4433EA847454C693897A32E4D1844195426A0C6AED67472BD2C4EEE179F3F6084A36A7689F4CB1F8E5DB2DDE54ACC0666BA98415431A4B202F402FB1F1BCCDC23BFF13148C7B8F61FBF6243B296A78EB698189DA95BDA85DBC11D15FFDC6BF46C53F6E472A871401E9A9AB7F9FB467EB4ECB1F0DA7E63EE8619CBC486EBB0F2120A7811BFB0557D13930574297C9464FC595B27569ADF5F4A8DF669C9EEA0A250F4D22C2E8C641BA3902BA80800489965F11AF1E1A85717C624E742F161550819D1F0372C5CAE8BC62B549EFE874461080D06346E1FA6F01514FBECCB06E34EE271A0F0031790BDABE0F02BBA4AEA4B7397FE3333EB8121820757281F96A5831F9E490366549D16763FF19FF773580ED5E3E1E2AA3E38F88474DE6D9BA6994F8E629160488CB4CD5B878CDA37AAEC9B56369A7E73F73B428639A05C1378448ADB7F074DC8154D92E13C6356B5F466D66477159B2A943799AD619A029F3010D037672DBB6820E51323ADA98881C6DE859DF875ABAF11DA5DDCA5A777622BDAE8FACE2E0CED3B6A77B88A8729FB7C50933DA6C52E3F4D948F9DC153B5B1299CD8621DDFBA48AF44E4B6F6106EE7779501DD5FB3C578EA4D32C5C2F036A7352703ADD135AB84460162417E50BF91E60797D59B9E18D324DA971F4FF428AEAF23AC0BA4E2E2FC7ABAA6C8984FE9E2D85B8ADA4086B3C13ABD43CFD1C711D8326B18ADC34CC14CF8957EC3959498FC2A7BE06BD1840DE170366566E50741957763C2DD27ACF8C3F1026FAEE1D2562FA1052E69AFDD42F446F0598866D5D306BF1B775042B035927372827F4386316534FA1B7EE633BA958CED8F0D241D4688E3C7918E2A75626377C342A590692BBFB827BF90514182D4090DF8D7323519A1AB6CD0227367410DD14D3786A26DDF91724FC82D06A25D5F56683953E8E0F20E3C1771DAF42E52024C116ED8A4C0A611680F5FE00ED9B148D15F12AA95B9BD5A9FD8101642B36911F310B0DE18171D6237D9BE1725DC299A1A3AAAE98540CEED26953D10CE8547F1C3E46A862BED428D1E10601BF328C727FD95343E2DB4D9ACD5D1CB4715F6004096EDA093D1B0A33B1E56F16D73ADB8732CB4A31160A4491FAA0C86E680E3D7C02CCEA8FE92F1E001016D220221DD10ED626017966C3450AD121365918C93091F14712BA477CF2E263296C778A2BAEEF5849455FA35CB617251E02A22DAF5C33E5AAA9F00E8ACDC50ECF47C521503C52F27D6B57C8F2B3D8F1222413E7FA4EC59296338098C9AB5A1D8A57884BD860041406D9655D17382949A03D50F1108D05BDB31CA08E66F2D8DE480C6793518D49A60D4762A9EDDC0249B422E84020ED539A14E2478F68BAB1F2B00E22A5CBB62979AC744E08B57D5B578C401A8D26D9ADD1505236082863672D911CF3A0966D303F8917093BF97AF90A7E1F9D59B09206B9CAC35110FA38D5890ED2116835CE37384F5630F1C428E213605872ECF911B014B91C2C600E8A40729D07BF918790742C9279F3114F68CDF6594CDA3CA6694223A82F66C2B4BDF3E51C6FFDC55E0FF51EFD6C934362BE7D6FABC11B8B0DADDD52108FA5FB5CA758A64377D386D45CE70605B460E8157037B5B1B2E0AEDD12A633115D6C43BC6C7C836FFF33E7D033F2E5800527164C0C4781C37DF50B66BBA5C819473A1C5302083A16F01437279D2F2DF14C878269A2F3FA40C1C761ED61501AC9EF141029038C819954089B738098708174393FEAEA7B02AE5CEF67B3C8CE6A970675CA1B8C856DCF5972508C7C6B25EE4D12D8212B98940B488EC402AC7AE3C70DF938D1288CDA7A319E085BC73A469B2D2A3303B11A683100AF6DB86937BA1182903616E3F0347BD68591B47BA65156B93F260DE59B3AEB289E2A73A3BFF38C2F3ADEDA29C7E90283AC7B86D036B47D5BA1A03EC783D250BACAE5847E41F829CB33DE08DF8F7D69C9AA4EDE8D7AB968407EED31A056BA0EF8816E127AA90065A679E1CA9550DEEF25AC5B7A34F70DCF2B116CF351F3BADA99F836C730DCC1AE03F496CF3F0387A0C2C702E2C13BDD9CF45A1CD53AB58731188B18EA8BE48D510C5812E90BCECBC6E198E708B1C08C8F864B124BB4CC0BDBBDF2C2F4E388FC19660D69CC2C0EBF91008C8243DB42DDAF57C024251C4231DF53790CE575613EE8E1C7A33C1561F3504DEAAED1E8408500623ECA5AE5A2845411749930D8E42078C032349957FC39A1DA0EAF9E87C31FFBF6AC0C1811EB28A41B1D86BD7D49AD1C468A49594956525A20A31700F122F4C4BB2252A2F3D5C5D6873838C909597BBCAD8E1333D5D617C87C8EE0F1B22383B424B4C5C627298A3BECC1B32475C9DB6B9BDC6D6DCF50000000000000000000000000000000000000000000000000000000011192834""") + ) + }; + + static KeyGenTestCase[] KeyGenTestCases65 = new KeyGenTestCase[] { + new KeyGenTestCase( + TestUtils.hexDecode(""" +70CEFB9AED5B68E018B079DA8284B9D5CAD5499ED9C265FF73588005D85C225C""") + ), + new KeyGenTestCase( + TestUtils.hexDecode(""" +4B4B71C5A1BC1074F2167A1D68729CDB9E16ABA3651FF02A0A0F4C883CAAC827""") + ), + new KeyGenTestCase( + TestUtils.hexDecode(""" +FB27DBBB4ED8F4F7D2700283C2B092866694246932EEACEE72DB730EFD172576""") + ), + new KeyGenTestCase( + TestUtils.hexDecode(""" +334ADAD056F76D74941FD87E5263E449D97C06D748A82018D0C794154C20A870""") + ), + new KeyGenTestCase( + TestUtils.hexDecode(""" +06C016CB8566F5B81F8457F56175AE77DD05C35EB37B687EAE89147DD7ED008D""") + ), + new KeyGenTestCase( + TestUtils.hexDecode(""" +AF5A2ECF442AF8C0371F89C499ABC337021992F221C1D3A66B551DEC917F1B1A""") + ), + new KeyGenTestCase( + TestUtils.hexDecode(""" +D85D7C2928288CD0B90D7269619F8D8B4EB3541F7E084CDE0E39CEFFECE9AF80""") + ), + new KeyGenTestCase( + TestUtils.hexDecode(""" +62E511A6731C2FA10DFB5F68A538CCDC1BC578C16E7EFFF458A82627438E78F2""") + ), + new KeyGenTestCase( + TestUtils.hexDecode(""" +BC4EF6C46CB18061966CD872D2CB9826B0220173E42F11B451DFF93C0577CDF5""") + ), + new KeyGenTestCase( + TestUtils.hexDecode(""" +135DF872744277E90019BD1E904DCBED63741D863E82388B61A2B069E509B25A""") + ) + }; + + static SigGenTestCase[] SigGenTestCases65 = new SigGenTestCase[] { + new SigGenTestCase( + TestUtils.hexDecode(""" +3E935D3B7DB7EE991CE774FA5B93D9BE0D108BE397EE176568296EE7F28786007CAF1156280D770245611B2D346A65FFC735A3A2E15BB20C05143D9256691B2AB41D75A90BC5E8F3B30B6F5CD05FD18992924A5B59A65AF06C0F000E74A219DD3E7604B58331DB0A0AE901C29391794417DD110BC8AAF7F62CFEFB34E00E1D1273224608140352203374007875256171864715361476150443076135107682417565754553623586606381220842166273341313626571127738336004603326033470801750142613464376064342020345044224040084303114570820783867267616511300688505780160364878830103711055618008111745151375375768600743812137557362365733331614323120366135554251746566185186844142405008812716203287601083143716200564576635047520177022180063752520164642714415327778151052008642808573380026883457436064234122618236025563058541674201723048788640112813150654403774841424453305303221148753008688031332254082078242584840286177301607176788017121684433040173755555750683651813041566084354588662418642250064747473031812374021673282486827605038055324710254455817626100000230664826103172488176531134306846024723448311740230680042148850536837730552571345643370461544610780183773451078171180104582147807556873670047488518654385284874451381580620113757112803083074314684320237100037477766105712118241161456212245656034186154017004464176334326740402832764308766445851504060640576124400281353647323214821033857545523610774625068106122683180221678260362521201302863406712350682475271635857220571525343258836275054827741877621326432020580784710353875772868341878363051856158443044548840053168838728704486521268772477031031715632770125821827468281545148686412467356360106478786427517182848466386616460707311675654327102528646248552175050554380133130605483627138568443074022187057484232375461550120577463002814013083534021237475850308467047435262471236266305063408115274535542164420053544842843632328232763503405306865145032688402018882073027571768370605424427643718688264801531460682254320658441480417081480173221048303526715882527870543270488733275488344414828021760801815571212201813874340356543310486026422086826301213865460574551547165833464571331342333324361541770188154256776002570452822671053622286151572588871378618203862708670032872331727751130056133838855585607876011010676275632625203121158641326875854128131672382381020353185780015705112326025800226563074580444604700207600183643031776082661220866111632103107372146823046820244455412421580875043257154231387817356100882747432501152565307267161430120118507744308574866233700326827552338466067211465546257660701674221148284153310844242634735382144183225241003471575543715561843716168715856042071108301012801652345045255016735805665612203238088225555235253071116306808173433031610572882372184860154863135212681745772538311183131358541040558574735410488454426065881446470864680188026246287815664520033268207530852644720764714770741540141065754171222385408035558637684376620487744584745736533387425473434280735546766515087150306388383873763030720286231050777658256536078013373573731543008080540837532054265732725301403185681580340556182751534152216780045272761136256556858461150186753280004488820172321265430428278876741152805304254EF2D2B2351896FA881A5F6022A2BD420A3D39B3B3C4A138A6F299A621979031111515B402D9040361D5C6E2DB187204FADC47A8AF07382C437E85536EABD12B61F0E50679A42EB886FDD3ABF04BB7C16FE949AEB66B30B685A0CBECBA90EC1340CBB5FE2382A534BA58AFE4A8A293079D51D7EC7C9EC515697726C23AAB9815DAC184696FF52AE3C02FF716081FD07AB10B653C3D4B47C32BFB5392D0CD22D5B99264C5B58F65A5E52C8D799C17A0473A962A6842CFD255CEBC0F20E9ACD7EFBC8A7226EA998F014C3E71535A6D8ABBEA5E8487EF2A4516A4B8354B19C03B971230BFADAE6C80DD3D234564553E2493153FD09AAFB5F06DB57B388E000D149C8AE52CB42886141316AA57FBDCEB78F815E31630C8A557FC5F54CCE95E1CB5F25AE1B62D2A1F390444FCD77EB745785F5B36CBE1433E55521165BAC3B2B0046224EBAFB4C9E74E6343AD94AA37AE932BFC770803786687392B26CA7C47124E88B8B99713453FB22C210EB6EFABBF4F07D47C01543564F6D3C6233B913EC4553E8075C97A6DEE1CF8CFEA5C167DDA8258CA69FEEDD8D46C52F3A51055E890B2351CC3A1898CF6FDF51F85F01453E64B1E6CC83E28A6C22C8BED80FB7B4D27D475BA41B9DF56EFDF8FC4EDDCB453F65D836F3BC96E43F0AC0B5645B4F8D306D7272D54F86C90FBBE4CA897DF1F56748AE6D0B0DB3277A7385EE7561B570D270C9ACE06D2A0044BE7C8BD01F3CE08EC36561911F0155922432E9045486A602AA4F06A02C300F8A71504A134EAFFFC051F1D4D42D881E30FDD5DFAAFBF9E9BF745AE0F70FC26FD404FA797D9EAA76D9065C649785F5FBC134690C7D8BD6392D4EE99C488B9EE15DEF9227868A199EF358BF08EF8DDC5E45365217A4ADE0D36AF7B0D3D744C3EA3BB26B56B9CEB374710F758BC7AA68BB346EC2DB5B5E7FFDD5F0B4CE9F25F03E72A9E2F5DB15E3B4E922CE09A57E2580CBC287903703E165BD7F42D4274AAB820EB71E8420CD47F87624727E79AC507B093D22C9E6E761DF4A3082AECE1095D3A5F101EC019F2B84ACD4BDD1F5379CAC8D7B8808485C6ED1ACD5B1A245595108B4836004D6A6D61294C1C8EBAD65A0E742B98CCC7D1D2760536B6EBD19A88D17C3598E86E5A22C0EA07BE671DE3AEF096AAE6D3B71AADB38839ACFA559818EB43A3418576F3B42DCD0E128AA022234218E616169F0BA3847F0EF62FFF4EF7D4DE803682D40A5C3B7D8F4D5FA1444470F1B66DE187B50FE42698128AA93350C20E7D37F619537C220D78C5EBEF89CA0F11C7C7A93D83F28D83A17216ADC450E25F3EB00D9F365C9F5ED69DD08B68E0BC9780F34D150329E4906D30A04E47B6B6D508DF9A945ED83E39DBFF9B0C136486D01A91D11D37B5ADB8A23D305B70609F126588C8F77B6D0614DB5364CF36EBBE9AC59D4AFA18DF530AC5ED8B58D68D0CB7BF91D65B0F392AD4B408992549F8A8FBECAF25652F0F6C4AB6F32D5B147E8D85286EBF96A5D57B17A9899E854EB4544BFCE30362F7BBA0D2FE40102EDE08EE9F43D0709CFC89B8E33FD5F3815A771C56DB8D7C788C49EEFF53AABC5E341F184F92ADAA225122D2D95E3BF03A27DA0C104C6F44A3E6EAC0CBC2F2066D17AA74A584644EAE6E2B69C32EA116C91D8D6D59C9744FC22D38EE5CFD0910DD305788BCA661463AF04090B57215E702850E85AA1C66075B15B9C9D6E9325A634CB04A6C7271CEFD9DEFDA2D4292EF1535998E5A6E65C4E51DB49E27FE2986AF02F4BEAFBE174BD75E8998651E610958188820845AAEB239D2D152B2C2597D04D7614A4439F6048D2B361FD9C558F40CE0D2D86D7F76846EB81DFB4E833127C87095DC2AAD0D7CA4FFD189C5E24A0F9CDAD4A5598F3273514703ADB5D12E7966E51A856A688CB6E25CF8C724BD9EDDCF555B90C65E28E07022BDB2D7569CC46DF613EA1E7FC1D88B02594A464387DAEBD0462A5F9C8BB46D525F9BF8B3AF7FC0D0B84DF55B2AF9E3E82A1305726B1C6D60396FD086B01BE69F91C752C5D0A587540C919FA8EAE2F5D3D72A14AE9D5E0B4DD4C8EE8084342033C93A86052ADE3A2A68E4C7B5DD599C568C9935BE59AB38ABE3556FE81306358D5F13C1C50C8E5D32F230242CF52E30C43D88C50FA030CA5FDFA88DA869F31B29A95299ECE1E4CE8575B6A633120EA76B43F30E9517728708DE1E73A27699D451C143DBF335684A643F544756B94C546593972C3543EC65EF687CA3F07302E675FE0065C1526D1353D027778E2BD04EEA31D4009701AE7B2241E32E1F9427BF820CF55A465248993114A7145615384CFB4A237C0C37F5C2C1B3AF7A62867F0DA8E4614DE7BFF6F00034AE628E64DB9FD96528A788D98FBE61211D1F22E37B978873EE78A6E871C52653D1EE0E0174699FF71B0788E7561931AA70939FE1D585D733509303507801B87189CA17BA3060A4BE85F9ABE6CCE142F8E16451EB3C51A4333827641A9361BF679E665F0E0E11F657AB9277D5E3A9EBB8DA33BCA8D37259166DC8C68A7A692B570883276450A56D984B774A10AF0BA766971DB3755AB5EDE5BB8CD6292555208B37872EFA2E7E42746576F725CA9E9FF5A6903945CB08E715D4BF468AB847210E30CD8B289D2FB745726D76A5802A4C74DF544E835D61DFEF680846EBC5F715F071FA0CF2BC3AD0B0F016C9A67162B4F926C32EA6DC7C548E859B72AB73C7A29C4F06D609C3284C784E40CD460EC149BDC17E614603F26BEB2E8AE8A0CE21E00EA3D18CE1865BE6EB0B9E9C79C170049492418CE009BAFBACD4B8AE55537D8CD8839EB42FA6921282B32EFD2A76B1A965DE1BE3CB0001069D4D80D6715F8E173BC8BB972F23020E0BA2DDF3A2D390F11F1F5BE9F6134F4276CF63C5DD6A154E133D9E1126FE55C5113F5E3485AD051B4C613E32AD3BC0793B0D955FEE79B1392AE2EDF048753BAF82EB4B739746C075CF84729A90EF60685C3F7833BB0D00895924E5A8BCBCB7BAF41C78C3705C48C28559968C947BC6FBA0E9640F8845A45C5AAA018842FCA46A25D68DCCBDE8BADEBA341F8969A3C83337EF3A6383CFA4CF9B093F7C81CD8947059CC6DB350BE20E8080A32C356BB813A714557AE66E6DF110AFFB7B11D95A82F4714D09C945554DCEE53B3A06F0860BE89E7B19459CD061154B9F86ED770AC271D7272A8D0F40BAC2BE0F95064DF20246FF3AAF3100DAA75F68CAA6C532E1181D670D94A68639A4557D5FA10AB8A016EBB94B3B367058AF40541FEF88F497EDA040B6D927A3C1F034D6C2472F8A90EACAFB61242E96FFA47D1598D6107C1B4B6703E83067A817EFA9640A6A1277E59FDAD28DEB29A70E31EC82BFDDF96DFBF7756FB6D8368F9E340065997B55B00B22057E7014CA555FBE5563EEEDD4B039835F60F753E9810B5410ADF699515080104AEC812C3EC299928C66C498B0E26B1719C690BF5A42415A6F63A9278DFA430380A821BAD0A2F8377235A260A0BC9B33E49FB980EFD770BA97FFE16183D6B1C24D0D1C3F437A1"""), + TestUtils.hexDecode(""" +E3D54DBA675DE7530D3854C8CDBD581C6E392F69CF9793D8C0BBAFEE7334C5878BF13B3BDCF1D993A47A7E8EDD4B6C3EC915A5E8FBF2071F112AAC41F08CCD8CC731143AFC223213212A5BD6B6A4026CFC9F7A41C08CB99F2B375D0E04FBBE00503533DFB869DE43566574B49232566E38B13CAF8C1EC1FA11CCA3DB66887996DFEE090D133B1D394F075F8286CA6CCE13C3977D929DEF5943461BD5A22D4BB5E8FB7EFE016932D02ECF4D7B7705412CA14508B13E61925EEC0B77460C4C089C83D687C8F70D141C75D6DF24FCDB64BB8C2721AAC9CE8C6FC4750C1686A7A70DF34957DCC0CE53C3F0D280CBD056D4F921FDEDB35AFCE5DBB348964AD105EEF5A1B07BD0D586B87ADA7CA7AFA93FB75AC0DE1C749C48BD6F192D6279482D3F9781290B88B095D73E728AFC186BFF0816C1DE78119D701FAD382C65ACC42B04D69412AEB255793839EFB9E5BBF6F69B7FDA27A44C04D3AA2FDC6101E9CEC6F75745F20E077EE23D652B7DE547A0FB0E3A153473BC824AC8A31A2C9493DE64B6D40185B60431B1B34EE32797CC77C45C71F4E04E849BF8DDFCF640B83130208DC2495C0CFC6C031B63B80FB45F47BFE3D25EC5B36C2700300D8223074C156C5D9887DE8C5A97BA36A84D7585CC065F20FE8DCE9E8EB814A1D5B7A3B7A3AB68D93EDBBBBF67BD70A0FC536C81C8D6E8B139C6B3B5EEAA3953464549CB38B78A15CE3D5BB4B798E6B142BC48C70C5BE61F82DB6E2EC03616999073574E6FB35D441B78DCAFF56B8CA8F473EC0543C9C69E93B97F95FCA58DAAED511F4440DB252EC18C90D2F97AD901716AD34EE103EAB0B7982994E21ED1AC4BD62ACE6DFE12C8C2CD092E7A7E37BD4E61B4CD51D980171F8D4253A4E7FCCABA0A513038276325372527621B0A3DFAECCD7CDFE98CB79C0662F5D0234AEEE9302438B778238BCA409D5908768779155D659E92D12CEEF3C2C954C3F1A4C2912E9EE994209B608A604D0CD87F79665A25E774E6DC1D8819B85852D9ADEB174C75D982DCE29FFDD24B7AAF5946A74C14A301AE09F1386AB17ACC341D6DAC040FA6527FCB8E095CD4F1651E47CE02E6ED76C085B2FABE9FF5A510E63E73EE386AC17D5C2C94C2D528B3A9C8902D10C1610BA70BA616C58D037F148E6332107DB9F64C579064F19481669C7888C21F0A3374194FF1A72FB6180DC01D29443BC52C318AB03843357A5A98B3D5CDDE9BC49D3ED29EF73CAF44A7849AC6DF4B2D353B6A562386BD480512108CA0ECD63BB3D3A0695679762F8254116D8049488BE6389FAC08916E6407944B1526BF03551504E40E6A3266D4E773E892EAC4DD5128374BA341EB4097E20A9BBD4E5EA26BE6FC325D9B71C232DCE1974928516EA2519974C82AEA5247627F802C6442B67FBC10E359672EEB9DFF768E9333A2166336FF0004DE5E7BCA55998C860FC1A86B75CBEB3FB5A5A2519D5227A6B5A7E0EE058FEE0CAE2B4AA75099FF098089F0261C443B13911CF3250CAE2F2906CB6454A20D0FFFE8C5AFB1DE7C5BA8CAAE00CD7C2D7219FC83FB158FD6D15EDC2924AB41C9B881566C538F5E38978C3182FBDD0C0C532A77A61E5B8E666B3C540DE976098D2BC68C0CDACF57E9BF1BDE8A7BFB13256BC69F2E386D8F458D303BAB781E537517AD7D0F0378D2F258B013AEA01C97A7E8CD2C3DEB203AA8D59084ACC2B09AD3C97EA613A2FBF297038B4E721665D512DDFE5C13F11DF4BDC0200BF610D57EA7232914752F75A544E01D5AE0DEFBC9E18695824058BDFCDDF4D5884840D2B55D6C2D6EDF475CA75F3EB4D0EDFAE99349684BC9C533EAD591085BD1D6D4E4F9B00A54C97244322D505AB52B2D4E0438C6AC5D2C3983BFB2359FB21174AC02156AE11EF233AF40A695854C84E620754419CF7ED9EA4FDACEFC8879B2EBC7B29CDF9C4CA2921E084486477C1452BC3BAF529DD92748E2B1B684B1103CF4C6EE11999E4121CFC7E2F3F6C7BB9C055F800DC46D78D9D94C3B20BD1B697411FF0B41E38173D2C9FF1CCA77B27384026ED2EE25223B0007D2930D700A20EC9159A66A4BBE0BD84DA52F006D7FAC6D59AB2BDE08FBCEB76A57FFEF59C077F9008A4A231FCC302E4DDAE9F3DAA55707C1EDCDE8042176DC7DC6377BEC58B236990AA6C5876D5A27942FFF7FD74B7DA1D2EC470CF71103A64FD2917AF4C45D4C59C13F58472AF408F9C5F907C7C6AE0F402B404AA40CF8D962EDEF7B7654EC8E36C645855BBECC1337EC18F0EA65933F4D07CEE15294139F479A16133D2BF412B5E46D5B06FB170F0C93DFB8AC3F7478002CA76B67A272A3224C8172CDD8A616A4C52F5FDE946CF5733583C53835EBC90DE3ECE34299D7E5434BF072F08A44905818EE9708815CED10E9043E88B6EF12BE72FC1169FF2F925C38E03B827CDE77740C7C2848AA3B09F555E2712B341E248772EFCF01B99CD5403642448B5243F35A3073A6DA7685AD42FECB05D46FC99F7D6B8EC56F39A7E7B3579FCD587E07C05BB7E1F5D49B9015375E09A9A14F2CDF049AC392139EAA3C2547426B8CBC0C4BA76C55014FCD3940FEA2631A75CD2FF5C22B8A65C9AF2DB1B831C30EDC8EB79B797E76D045EF0B8EFF8D41404F626DE8551FFA445885CA1E3C9BF05B5C39CD40E3B37CE3B58514BC70E2EA94CD694CA88C1F47AACF9B4FF6622C555AAB7C71EA210FAA9C0BF9089DC9C9DFA77C2C4A92F59BD7CD24EF4F8D5088DDBE22DE854F8966C017FB414464ED6B991E289F7E3FEA783831CCFB51E227A6DD4F5EF50963E80847FA6B350A2DCDA3C875D176342ED73BB42B416E58D1612C4D066F1207B6E16A955DCD557A9EA37A9F24CCB20E74AC4D6166ACEBCD7D651450E5D4AEA86DC89528DFEBE07B39A160160FEBBEE5B11122B4177FD04B0A49803E498F1BFFBA898BE3B26320966165E136F7F517FEA35EDF01D36831F9AB478CFF8241E01AD7570C26EA62439013F61D48797B92964903802AAAF356C6AF7645F5F4338C7EAD5AB2898C600123888AF42A2FE06FF03D81320FC08E7589E19887EC86CC1B08204C29E86CCF187B1240B81F7D375F3762CBC10F3BADCAD7431E59A4DC136440AA72628E17D2BCFF916DBC8A66B8A83A3C6400EA0CC57A82DB41BB28CEA9E9CECA1ED826719B9B62B6CED5B52FA518FE47274DC6E22E5F8398D42AB23572CD6623EC307FB7EF61892AE3196C48125605F4F09B9C0F0DBBFB9D9015D325C546CF3B1DC886AB0DEFE2C35CD39E2AFD13AEA74F787B410883EB72DB8CA7D225E6FE8143695BC0FE556C6CDDA493F92ED62A38E8F90CC4C713A4798984007A5CBF68F0CDCC01274C96A15C3C4355ADFC75F7DB0603918ED6CB4E4491A8569FB1A9AF32528F6E26B2303C7987E39015573521E024B2230BF1BB803BF2B358880F2840CC58ACE31E551C8E2A0F8349570741F8E93066C8F17608DE35AEC342415A4BFDD13A9757501F5246ECA49913D0F02EFF35F4B3D40DF97A64B0FD02709C0832C423543A850776ED9C0574C26CDAB8DB371F5F4B731E6F510BC09FCE3DBB58BBAE1074CCAC284D5F8068D2435E053A037E3ABDC957B74339EF0063D367F7556E49D2C7A7DE3616F5E8B703B7585F526E9306C59329A18E76B85303C31E3616831F2AA2B173CD0A43CDE76AE52EFB8CF3C381097D7A7598EC833A75E97AE4DD539C31B3E45216EF9C844008C28D12B12D3C7EA7FB89B3B5D20EF5C7636A8E83D6A9F8F7DF29C9716B7D92313048A7E14B9EDF77FEBA874B9410DCAEC4816D2FB57050696F5D4F0DB47C6183D447C5AFBCB948D09944F4271368542E377DEECD006779F6F7649B946E79BBF2E19AB4E93F142BB24E6D962F6648CD0BF1BE876F6F431E883105C3E86B973E30735A6FE17346ECBEED5D101EF0AAFBBB4C072BADAA2F4D517C272F2BD2190F5F8C87D961041A121D6B319EBC959AB0603096017BF7CBB74DBC74FB866358EF8C1AA5B9A10B2C524E822278627C0AC577AE9383C2A529054528E58D56699540E4931BC65A125EF4B459A7A5FC10E0324ACB641BA33C83A7E100CB00FFE0ABF6281F8942AE5490DCCA37BF464D0B061028E46E025FBD5F6DD6CA1BEBEE282B749FF5B002210916B9CDC4D903A95972FCECB9292A554AEBD821AB4CC50D5EA0A33A699FBF07F2CA520FC44D4A9581182290294A8FCC66DE3FB5B7F5EC5B267D1A0E6F84C27C02253649F5903389A0901797A7EC8B78AF12BF2B1CC22D291347A0F8D6EB2698AFCA7CB4C23EDF250A5B77E51EFFA3C675F1FA951D72467EDAF987D5B63DE4177535974BB2006AA9A8DD9E624108229B1C5735BB039CCE47162EB52DE88703A8BDB8ED409BC01DABADFD31EBB95CAD9026705DBAE5A2D06376320BCFAC17A7DAC957BFEE98480C7A111B5ED300447A21FE62448F62CCFF7DA68689A73A2EC70BD13130337EABF26A00BF86E52077EA00DA46FE7323780CF98B3E998BB30C3998017F4BEA455568FCD567086EC68ABC40113DB474C6C88B1C1C7588E7A8C8D2082D4C70DCB8FC3D8FBAC53CAE95286F13254253861567E4715B03E682E422C111169D96359EE18265C3CADBAB3AE61F03F86D096ADAE9A6C4820EBE3B61015995707695B42B67802FAC2D6FBB2B67801A3E48843EB83288AB52C29C1F112F9233860612BA015D4B7CABC19C6294F8871E2ECF6AF334DF9C8330971277E32CF1488F04B4B285AEEAA83BB81D54B6B8426439804B027822373AB99868EC068735C816521BD75DC19F79D2E2166B1A551C998318FE19F5079BAADB12732528BC8B522438AAD252C57D3899400913CD124D2DBE90A891D95900C0256D9DDBF939BADCF6E37E6783DA2A2BAAD872F6C8C11878ED6D5EE2988135A39F2DAC7CF127100C36D2D4E58B3A9B1D7341120FFCA0EED2E98E020A46F1AECBC809A21EF79E6DBCE76F96B6930107F078A5D4464CFEAC414CA41A5EE4F87CCD8868E7922A14C247885F0DA9E23A7604EDE703C2BE3633AF9CCC32B9E5F51CF51978F10A06F5D77C67927D80AE480E7E5E005401ED95467972ED87029029DA05DFBCF2F0B9D50441E8F15804B0A59D23CFC2E3C0FBFCB10B69AADF0B37C06DBF972E264C6CDE4142C04FFD9FA0AF2451F8BEC3FDE9723306085ECEFB17C591E691F9B4D4F796E293C0CD322F02B96938A5F7D1C8A7FEB94C031DE24E71020FF37E00590AE7CA48CA876AFCA2BE3723EAAD40FD27B90FE6EA039C9F3F6069FDBC70F16626A41678A31E8AD88DE9BCE8A25D43B86EBF80E5E426FE21606E67545FF8E55FA7D9802D65AFBDA79EF40DE924FD0DA7B5C8F6A2CF993FA6D27B2861C629CC9BD2E1E6AF04F88065614F7E24CDD19C88CF2D7D2B93B7408D898525E5141FF71D18DABAC186DCD432F3895A1027C92CF8613C80BD46E4758CA26C8CD92B74EEBC5FA5EDF9C9FEC54FEAC40F0944E3FA165E515A03DB57C205D383C04B2CBFF703939EF321DF8A49BC3F5B1409EA491062B7B9982277825B52C6CC8313BA05ABFFCDFA525445B1CFF773D28536A989D257967B50D7BEC4FDE5F338D2AE81BC8EC592BE93BDA0A7DD089057E675674E8B997B05D049CA3DBD60B7F3FB23BA5F4E5A48ED8535234E5C66C41B157C25B5D9EF5C8C0ED016D6B217F4B60BFD0DA223A5D40C2A403DE8268AD5E6207C54B217C2F009C5DD052266722DC21D4AD8314DE498692E3C77C9F8226A14F27D49E0DA1101E32E5B86BC0F0348A20A360A919EC863695D2EC318A61F654C9A1526AF1538F928DB76F9B14EF598F2551EE85D6E0429192C5F18D339DD5A280DD5B1A8F59EC1F2947996C7E190C87502FDF5004772224BBD1C4DD62A8DA1723EDB41176A9AF04B1F30D09050E73579364360DB4F98034FEC1B43E6E9E0226409E6AF1609FEB862D845994BC20E67010237B74DF1AB59EDF14B1623FDC990B87B929FB7E837B1ED905286A886F59B023F40B07A989EF7A99E974EBAEC49B45FEE1F405D11A641B2B150EBE854F7853F06026CB1287FD8BCEFB15D2AEA623D7C3ADAA00B35A105ABF2D8F9715BE65AFCC1381D29C5EF398F2B76FE1651348BAAC147CFAFF34778242B32A1620E0332EEC7AF5E750DFEC30A899452ADC530DD933A07748DD522AC20AE2B2889FAC3237D23C4472FC8C6B236D4A4D19F67264F54BB9B25318156B30EDF273BBF3598AF5B34BAD41585982F6039F6E488308B47EAEA5D21A91E5838F7D9CCC8F726EB2DB82D022BAF103AB2DD444489B94E8DDBA71E62AB6251DD5D5F69E44F377674A5C2B032150C32664C96C072867BB7A2DC29033E6BCCAEDDEA430E5E155DD0724FCBC0415B2AB6DFE68A2E59403B206BBE7F421FAAC53F66040C5CCCEB19F17BF000AEA7E775211E48AE04AB32B2EA470FF97707D9C073FE72A7B77D49FF8DEA36610C2A83306435861BE01DC4B20DBB8AA6CB780328DCFC2A32D74CABA83929CBC85E406E74EEDB727A2FB5BD9D304AF46225832858B295A17B9E710BD7B0B5D19DBBF4FD021EAF29F4D1B6BD7E78C8A3E3235B5D0BC687BD5B428D2318CF4330EC343566D42D17BE838EEEDF70F1E409C189DB1AE0A205D222C92A1ADD33B8E3B126AF62818A2DBE3E3C001098A986865C6B57D0B2F5579B97B6F101EB56FA839F8789F6774074185A8E0F383E9D8813CA1670D8B7586A3A1C27A3F5A3874C4E743EAE21BC519DCC430E281D2F73C23BAB948938A46FC24DA94647150DB72783AB3FAC01D834A8544F144779A51480643CB1ACCA0BF88D203F865664A5ECE18A88CE31B0D8FEEC585F9531329002D4FFABED01EF42AF52DDF08400C58D07E98046D77C7A142B513DA0EE795DD57EA43F4CE36C8F6D2862044945DC293C8D47D9F207B0344220E3177D6E17A4B39B22CCAE3C53D4E0DC87F70CBE9BF743CEACB8932DF8F84A527C9FB84C6CF5206EC2E43D1FF8E846DA06EBFFFB87BEC09C63E9633713768060ECA6259AAFE7C787F3947D5B94A6B80FF0A7A4785836F9A1396833347C13034040D1C6B1F83782AA6458328160FA04971DE04A16B6C031B2571DD131912CDF2515DD56983ED6EF3BBE5B3989E951BF0B99C5605C38181E96690487E87240059DE21BD220059E5D7E3C832FD4569BB7DF06437197CAC141E8FE5B369B542CBEED2F9025A030C54F0B5D2B1E79011CF2A0A0DB14312E352D07BC03E654AABAA95AFD30F1483B57BB1A74A0CDF8C9FDEBE4B0E156FE86BB1E21D861F8EBE0C4AB2B23E776EC01A281F6DA9BEC4C560668B4EEC71856E6CC41741DF2EBBD4E95B661EC24FE31B1DAABC9373CCBC82F3C13C31E478097259850221928C7AC6BB933A5631C896ACA87FB6F5E3EEF36EF5B9CE59F5676813A1A7E768FC9B8AD4A0A072672BA23CC21B21A95C9BBB1A40FDFEBD2D611B773DFA55F87E9AB1CE51CC42B0FE2FE15DA2D73F656CA56279AA16722ABAED5727519EA258794503F1808E4EBF056530B318B99A74886D05D042DF4D829C425C908B58162EE30A073D4BB7D27275B548E7A90E6D178DD27F67CD955270825FB96300C4645E4CD9C175C1185707D4D365955FCFD245A55D64EFB66308A47FC85592BFB755EB4AA8B78B541274E2C225DAD649C248E7F2792A56BFBEF704551588460B192DAFB9BF6798B7D4CECFA424AEAD675DCA081E60BBED670F9AB2316F5012E2290770D3323403DA5748BE6681565A713873A5386A6F1299F0E1EDB341FFF08325510A7F2FE5EB0302727D7355EE48ED5DF4316FD34833238690B91D47165CD4CC0454DA33B87569D38880AD92A92ABA0F24D99ED4CC977A2B4E37954FBE9B9320101C80A858122793062C7AC26E71BE2608DBD2A97CF4E884FD3255D008700FF3531C045750B2EAF7730BC9A51C675D94179DCFCE9EE63C1473D15B4319AA9EDFD19739CC05C5C3C8AA618FA9096C6648756F8AA74FD18A8CD81A2D248B856902B4D30182BFC2F392450F902973043EA0F5E6C872AD43A2D319F99F095808D83A8B02BD380D6C3F3DD227EAE2B4A4867713853D63CFF405621B1EEEEF00D5BA2FF254CDF97B4226334A9866A2B5BDF1F8E8AFDF1238DA9F48FC388A339F79D648CAA0A0A69D6F16E297663E5F4CF1AA95427E68D71E74C0A2FB6B689224BD9978F7A3A4505334774176FD87097D8AB454CABEE138F2CDFC6EF0F3DB14B09DD02E7FABE9F156654433B75B951AE3C196D670192004DC1924D1950AC597682EAD1C087ACB1461247DFAB3CD42279F9169B69B33435DB9D8994AC04B15D45007F0F98334AC5D783219B376D9ED7553F52CBADF159F69282050A4C843467AE7E4C4A142A61CCC4C48DC3AAC6B8E0A8D618E06C60DC924A943AF9000F896446CB62EF4E47AD6D1FBE2B8984A48ACD7C0519D6E87A33106E9A91C298808BF04E1267349334E6C2AC015A9F704B2DDB56D27A8B00D876AD00F62434095A6F7A5E9CD4B27FE09FF69019AE5F27330792CF9A1C07FBE98D23C4E615332A77DB5B6182D277DDFD7572DA75748DFB3B9315294EABE4B6D0FC3114B2AFF5537A6B05A7AA9ABB4930E17B7FD3D8F81AA2D674DB69AD967C8306FC3E1CA8BF78F446B26D8F2FD1AF6F7FD7E52867BCCC3B4DBD7227EA992DD995D77C4A2BC808C7A3E68FA433675F489BC503DB70115A824669E4B1861CDBD557A1F78F1A4B3582B2553AC23F12A4326EF943C56F847B8C679695614BBB1DDEA9CFB7D799CE42DF8B735FEB9DC119DBCA306DA4FA84A50F79905E5C2AC1F61241D88359EE6F62DC9D3E4A1593F41CC5F3C02241CE5EB62C28A547FCAADF1DD688F3DFBA870D9BED723B02B0B1CDB4C08D093C48977E0621930A668A5CD517A0EFFBE248B4AACF3009BAC0D47F49378F30A3D2C2800CD16B3C9464563DA4A7321082FAE95DE5645FCCBC5569E942B5F860A32F04082723E9E53F2D18099BEC5E23A916354198325FA8DAEAA3F6B7AB6AAD6EF12A03CBDC27B83C818F44"""), + TestUtils.hexDecode(""" +80A3AA584B532C5098947755BF88B40612446DC7D4CCA500DF34D9A91804FED988A4EC0F7124A5C42B7298D1784A5F6D364F7445E5F9090C0CA2C84902722A800B930AC58C45A46066A0D613DA411DF5511A5401183E2EB6B6C63486D3E2976D77D3319CAD88F01EC4429BB8C69036CF1BD891DAA369DCB525D33E9803485F666532CA7CA8321F983525E52AD2A3E363E30C7D7AC7ACC1F9A7EAEB76B7290B2DEE7C681C125AC33E9EB2B8EE080EFF7E8D3751E3C35FDB2CF58C2C9BF83DA0756A75BD92FDADF3E9F3E1637503C923802D7843787A6D947BAEB26FE64D0FCB52C2C29DDDCFAF2BFB4968E5938155F652145D00B410CAD920BCF74059908DFC0916637EE248E63C3EA0CDFBFE1B28388357206C6DBB8C0D9A23942938EB523A51774245567BE82401E8877048243D343E0D1F3F4503F8A4BE59BAAD3E76B7E2D1C2CB4234B62BAAA10642B903F5A644DF2B37E740DE63C82617C405B563BEE0008F70A33A59BCF17A38B0170F736D3D617469D39CC99E3FE9A49B94DD5E1ACD03877081658F4D0300CBD5E50B0AB094E4502BEEBBE4840CD5DE6FCB891203117980FFB033474E88AA07ED44A306115FB08440212D943C6E8896370D8FF97DD4E29ED631F05CD72B343698B8078DBA5523E471F20F4EE58ECDC30E3D4E0F0E130378B42E5521AE16088C18874703CB8A38D382FC89957F592C051749FAE68C14EA0B6E11677D65D7AFEA3516AB9B75D5F464B8E119E97ADC22CFC48729DFD3881AC6422A11E0FD883F44FDA7A7370F85FB80EED1A4D35AFD4597C173186BE56C94F275E4F2AAEA096AE8FFB8E5499DFF2A00AFAD19B40A0EE428EDBB3B64F34C4ED401BA5772D647DD20E4BCB393D053DFC6CBABE37D7544727DCD40A42E83AECC1BD8718D7B2F0A8B5E3E98A568F055A6EFD74E8D81851D745634AD5F7FFF96A5C832859F92A92E70249F38052CBAC2BE7DDD217786D5FEB80152DB1210421D53569B07346AFF582129AF9E35DE9C3A4CF2FBA7B6EFC9552503EA94A722F6F9A84E190C422883C71D60F4059F912CC773AEA6C52B2C5CDB496B056697F38F4EA2BEE6D5150E92650631DC3C35B7DDC063643F65726964575D34E0FBDBC3B144A829674BC26A21C3D7D873F70BFD2BE1F71D5BA2593C221DBD6A245045256738EE39251B1F433F4C8E0C1AEAC740952A677F72D11A0437A64188A5A8CE69A4BD56D98021B3DB19481D606BAA7263EC0ED9529B242A366B76C5EAC589BE4A3EE50B0A49852641F9102E2F63D75FE2C295D2CFF1554C77C742979F1DB719FD14D1FDD0303F5FBD3C96763CE56563D05EFF726FC1BDCC4C71257A8920A8D5777DEF74D2E175A7A2541AFCDB51249EE6010F19C9D428C774ECC455D23F7EB770B8F2AA09EB278A55AF0BE2EEF172FA12365E0D539C60FD5A5EDA381620C1775EB2F47146F1E2C5B854023C8711DDA05FF78E393D1273641CE6DA638006650439C5F32A45BE179B4CA0C4DA02D908BFAC72E47CE4A2E277991EFBDCF86BF28456A6FE93E671884EE309DDF746194369B49F76476830B242DCABB07203AC83CFF067ED83B74D201DFC633F63BB2039C82785C3A80AA6E79D303F02D134B141156C5ADC941F477E955C83B2EC1938DD6E491C1D5EB0E262F62589DB9F9BBB14856AB4AD10D450923ABE90E53D64667D87046B81CA2674A266A4F43C35A5DD0C8CA7BF90D9B8E7700970FED98BFC65D22F1D1AE7DA37709E291EDEBCE413A636FFD8FBC55D921E2C043401D68E837049C4469CB7542A3A4E3CAD8272301CF07EA827C7FC18766D43D5DE67C32CD0710963188A744B70D3EAB6950687EE42A9FBAD7FB7F1ABF8A623E0846CB9D3BF8FFE2C5B1D650E3086C809B08A01E0AB08AAD8808320B2E43F4EC80D71C1B1A9935C6755349AA3E723324FF334BB9BD2D6DEED275A1F779227BE29CF8D6302DE79776B2B59BC42837EBF82CFE344AEB2CCDBBCE412258ED39C321BF78E4D7F1350AD7070892C47A656A9579015FBC1EE340502E6592D0078293C79BF17F189F8D46AABE90C54FCBF3651A43B99A004D1FA260D7758413015EC3406B8D7E5C8A3C0D110F79A883CC13C2FE40047095A1E5D0DBF136A2D33FC04D1D5F7ABAC0D43FC083F87CEF760B4A278D90E1D5FE74E999A1A58BCE582B22807502A3135700688F8628FD12AE152A506038462F6A8B45E5CCB4440577374CB6032B75E9B92B8A4FBD2D080E2DBE7EF640370AAEDC4C75829201E17797A25EA8ECF81057F3F3BF50227ACA6B4039378BA480A07085598F249C890831A4A44A5D24AA33009A0DBBBFA5CE269F345876C7FF4B55D5ACA860DA86FFDE4EE9966C44A18A5C3A1FDAEEBE3BD0B3B9C2D92041BEE72990348993491C73BB4A813295422B4129595B359B3194010DF21F4D3FAD2CFEF725BD089AD68A2001B29D6DE815B9519850C99C5F0C8FF573B2553A4330DAF4CA5D4E98804EFD6B0D4642FE94D5835CEE0987209218E37921DEE6828F29C730AD5338B2C8550FED699D266E99651ABACA63DEACA113EF34378654EEE36D53846E5BC40C189073E85DF689612AC27215C7FF655F23273FA860CFDB866B7A40AC33A28A261BFF4434C3490292DBFE7DD54F54950ED3BAE86FB6C7B05AC2DB2D26946D0285BC571F4BADBC7944B9DC667133CD308B034B24BB5177306B73DBD7D506225ADBC8B12427E691F63D4DE76EA4C54434A57FE92FDAF6249D355D5E6F303BE70BC850520314755BC500E9C1AF6186FAC1522CF527158C491371D7596C3743A94E8ACA236600D6682EC7ACB87BEF47078722D8B7AC7EA48EEE37007E766214C0C27E97DA933913D33A02C522B26800C113336312D86E0FF38A67B09B344205062FBBF576532D22F027B79FE5CFCC50C3CE52CB6632190AF1406AC18C21183D61569E14981312744C15207124F410E8B769AE628CAFACF5CFA53421AC5E0F426D62A9BBCB8E275573941F876522085775C8B03CDCD3D67CBB50F4EFEDEC473DF28D2D881AE8CE3C1BF09F2CE9188035948C4A3693A05AFD3374EE58EAEDEFD90CD8C4FF0AE325AD8E78C38EA6EBF95D61CF46203DB6455176647D1A12CB7D7423E3871F42A8B13B1BB9C2C2D10FEC92C3F9E0B792C837C07C10AB815A359679DD22584E4EF1BE4C1DCB918A9B130C9A5E6023E6763FB8938D511DE761B7A4236015422D30C64BE39079EB5C66FD3E0BA97FE1FBB0F9F61CE878052C90435307112A2F83790DDD3C2A420ACB56C8E0D76753E3FEE5D73DFE901935A2313DCAC424200606E704F305E124A28FBC0E30E38AAF3F2ED11E27532C15664376741F70F59830D1ADBB56042F8C87DC2C989FBA6CD94AB7543D0EA696F74D1421F489F070C9A2C793CF48DB7BA4FC951CB47272E450017E3849BFF1308D3CF74D9515C04E889E424CF87D0B368DE99D9C31AA1A217DE12292040ABDF61AD972729B6B1892F72AA71A1803905B75CC61C87775BC4C721D94AD74E9916BE5758BAD7CB947CC9E250B42C9525829F070B0B0DF812B89A88ECB874E0C81F7B1FA95FDACF77C916CF8E72ECF00C319BF4093EB114465B321FD086B79832AB16F83E7253B031531288F70D94BD5C9531DB6AFD125A736B66EA40EDF68D020B49D2763B016B328D8959B08370C37CBCAAC5B12297C1F3320DD9885718B4B00DD6B10E2652A69360FC719B55723DBFA38749CFAFB440265DB48F5DA31A056A59428D3284F600E9CD497B1378451569BA3F8F1D32091642E65BB229A0E676E3A80B1E18C3A36C4D17F9901909DB8E5E2203E7DF5E02F152B1D302C31C91D8ECC3E13FBF864FADBA37AA645338597001F55C638E668A6E36794E83247DA88C84441EE126E43DEE6F3F1F201738E25E859118050647BEF46D042E14DBE46E2B189CA03245A7848FE104B08468220278E230FA454EF065BCB26CFB93B19B3B35A2C1D69E301300F50DFA168C54BCBF8673B63A7DC6AD7F56D33CACA83C1C77678777BC6239632917ADB4000D229E0ACBE4A8A243E6C57ADD4C728527A7051DFA5FC4B995A3FE3F3A6E5BB9A9D6FBEEE21CB1DFAD333F6C958C675126667F0C1CED9739F2499E79AEAEDA15DBA5C8C31986564E962FCF789608949F7FF91AD70B3431CB86D7F1A3E129BCEEA58BF56C5815C9E44B60DBF7D104B8C5D85CF05BFFD603A2F20843987A1A5B34B1182A014C5AA7F5EEF615F677AE07FD093E77CA4DE721B67760306C7565D5C764D2673E02B266921647BB5D16AC34644183BA29F3DEB5D494D063A41E7615F8DE9D8F300FFBC156B69D375D8C3881F873A98EA7F8759D5B287927D5F3EEE9A242831B7342CD495FAC2E76F25426D24BEE831557B622A3F7DA57759CB2DC91D107053CF2C3D81BF1F85D75FA9B8E6ABEBF976F9ADD4BB7F788F8592300F36AFBF1800DEC01FD44BE822CD2071E328C1F0E23F460EDF2ED9A6E6B68CBBC011A86439D8D110F56C57EF270D25C5B588BAF25684BF68CC02827A927F9902283D3F76DBF53E864C7B9E44A193D119B563385A603C3E89A3ADCC9B7B9257EA51F697E14F708419E3CAF455385585E461FBDC32C921D47BB7DC8991D01062E833A41535A6978A3E016585FA9C6E248676A7BB5BAD5070D149BC3C9DD1A5C5DB200000000000000000000000000000000000000040C12192024""") + ), + new SigGenTestCase( + TestUtils.hexDecode(""" +F392F98C9CDF8480C41F34A3BA6EECDAB55B7A7413B28B05B6D8DA29B455DA20C13C7ADADE697C19BD95F4181D9BB87ABC896C07446CC52B62F7C2883B3CCC61927D373DA98BB6B1463FCBDBC7C3A676D25788AB26706412FD08C05B130F826130DC142EBFDD884EB8FADE304455EE978A72A3A123A69246EA506F92140A8AAC301826517220457575500718444602606702737036246348057773753653026737530327720617356636110021487182406485883783500307652062837008037623504275143575413277805241337630721014485311207126464251365722038703047777860484650222507051720537247120624820142650776607686280727735633154433151782223422704163680716278603431812174820280568464342510822713206812416037802546378526410045560675630237304285416623454261283085572045668858060866837604282874804876254654326261578215675122020866578445072761231803362336526243078878567202715767743383861568417748622625301333140772280730350454860126812584207355072774075606603733422242068425724752175886643765751536756230433665412301147080035348337144751803325188375752442131056834846104747661738815140077787317821773203565820682216027654224806146185675613323671341833128465031767087642306567758113743515665083376682071584772645080206870431383757154651308356136765831320760126350481621267663254431456810768528220808107371083873767157585238851353083212225832367378252330145547815686824158782844746478735016774465466740401333310057727005121237645614476264226362084266800020031025007113888434744843115873163067161007831303825424463365517676765688324200684513347206713426521057202461184363017881817403710703264672680236531845142531570466384473731728758138705644753855655816742241364617142126084780008354140654801776325821685208137803465245450505341523100083408734674154335414845701708522128274506836754076625206872353746311412316312855531504102358752662137808638173521823133750654348485071110586741851463345337506614254157164306768776078885708514685148238201860867238133581485532340048788405422353860218008258548436878687253828241261050821015817420278763365687765514675058675166754736381757223055720684127776321362551252532374142887160764038838183424628018841887374712515033240300045651318782786054437184283851251186686603270668845482075874631015013706514675820635143655714764714156053721845140813850420508700657763114833577580426428065023467825688868337142277613856181714827028778062057570322170260362422631028183028112073851046204428683517685558417500601725657238741370857627730181360274563088823835144601056210101460602232722700431633184040618846384113624585660727717184113675546163610607728213513133205278237138625783833077538572741625110451321533127067244638480483667304517823113154663264021760688615102244052321747321612302751435786674345144462326132726376720328244761422741627313648020611868614763040681674853246228406044610051800751763205151834303188718047635724013221728118711424128888062074420703056187033803211250204407771300451054423223354033358307300448270140765437102400745208838204164114740002455888478168313785353187171180330311056851418840303151441514865342313468076524833442066721446046807704220124510652483242431018436830414063580815564337474054060760627544438122721145213236126348660A82C6DE4E1250965D63B99CEFF0EE2BF66C76EA5BD2275E36469F4F48A5C59613823B26EE15F377DD9AAED3625E4C402D971B2B83296DE5A8D861CB951ECE6BB06F787AA4275345917288245199B56E7F3093180FEB6D09F62FEF524E49F685082481B42648D09F71E623477F4D9E98E79386C060311CE9C063717B3F69C36391B555ECF819637BF03B370EB3B47B8F56EFDDAC66893EEA7DBA70BD28F35D1223829F0FE82FCBE7B0D47EDE3C72D9454CD323271ACD902A883811175068522C068B9C4CF6A819E6A141737177FA90149BCDE0E38221CE7508D32BDF4CD9605EDD630C5AB530DD0F36AF49EA3FC26BC6C0743EEB48581460BBC7836BF163E819671E821CEE4DA76177343369B9E48C73AEB48AD198E958303449D6FA0707BA74BCB777F8E9EEF95B782BF00AFF9114DC954AA6A943EBBABB85A486902222AA990E5CB09323BE672F4E96A1F0F97302300EF6B953425DFB55E8B12740E91C0684D38530B65B9D9D4A48795DD27F166860115831266455A4D29A2A928A11D17F42F56D5344C9F50BCD5066EC1B469984FE4F8B538825A016A029BC3FD608488C78805C3EC39954CB1B9EE1182D416E7658E038ED6D76099E8D9BC68E0149520AF9CBC6BE7B03F85A39726298195C58DD5DD70987ED894DA457339C0C9AEE5B1062C0F24A99DCC9D4FA5E426335449DEB5FF6FA03652EE49AB4091B79E83AD0B0F62D0392AECB0AC4C5FB3DB71E057588D4F777F4D21E3E5AA059543780A80294751338CBBC7566298EA8F067A919869BB321A09736E9DBF1EF1B825CFAE09CE2A0B0660D04B2BD78A69B48073CDDA437BD3F21B00CEE21D1B87BF3D731083CAEDA4D0835C5828B036E6471E5739DC2A7F874F8E5E2D0F66D5B01183A1AAD731B11414B304AADE217028C2D68644551BB1762D5400800709F13DB2B28A5203F0634ECFF934DF3FF920896D26FDF4D4EF9808F835DACD59BB5C44ECE1BD80034437786334910F23F208309943A3189EC42115A05CC2EC8C779F6FD9621AFD581423C2A6AD702A5A9AB15D632D9071D2E104A551218F65A44AA075B02DF27077A91C91FC1A19DDBBF4F793513AE1CFA323E72B6A01FD84FE50A27D2C3F02AED8AEBFF2D1FDCB1A16108D5655BB77C8B1D982CDCF19F82ACEC7EFD6921ECD285CBB2E45C0DE0D585A8C932943BC21160F34D7BFB6CA14CB0DBBBC9F2775ACD252E5B1279CAB1A4119B816F79BF0E46BC648D2E0FA569AB23B10C2D58DDE59C0494A9166EB882D66F6CBDB186A611F4C668F6C964453D5AA9567C48DEDEBAA84D295E46B1CB7C60462C1A9606521664F49E4DAEFAEE15BCCA53CF8FB9A16A38449F000D597072607466C4D7A2144DC520451DAAFB2CEFE1BEBE13B873409B1ED34E995E34BE5C345D408A421CBE8789D267504C923F8AD9EFABD6729FD28C0AAF9D34219C9E9E03D604335CC3224655CCB4E4DA0B60044C10E25584D6F1C434BBCDDDC2F98B2FD6D18640140972FB1D00C1F29929DFEF2822E000D6334E80CE73F453E05A13A80AECA16754A85AF59869635CC9C8805543557DD7D5081ED8C5DC0D71FB935CF8D2896915B406055B349811677F5370F1DD9B179E88DA3D6D43CC3D83220F3C79DE3817A070879A0BBBD5B0500E87EC15A2974C38997A4EAAC9967EE2DE66FDEF9CA9D340AFC5D12AA0A3287D8C9DEE1DFE957346EA23E40DB7625E8584F2F2FB610DBCCF1244646E31ED89EC62CE8FD792EA52DF83879925205F13D79CFD590C291659047811D3F97F9D1164F6087CF5A53EE97C1D7237885ACAFF30A657127F6480CF0980DA55B5FBD5E70F7F4C621F02025B1CDDAF1DCAE5BB6A60E046AEDBFD07F9B45C833039DF8F8E5FBAF5F8F1C1D7C9A3312298B557D49423C814F58D8759B53BDCCF4C34B72BD105302D23A1DC342FEC033871BB3C049826790373BA6DD72CF0EE7FACD730E801B47863D7744DC7E5EB38833134CE433611F333CB89C8392689A2CFA95792237FCE981F4C03AE35D6D8739091A0653521F3CC03B4CFAC824B6D2FF13C91C754758827ABBC642053F293F79FB04542A76DD0A65365B0AEC5B4D74D0E73E57A6CC8B4E29200A3115886185BCD42AB969D392CE9375BBBEA8FBA59AC8C4332682ED331F23BC1EAA9835318B9DD58CAD9C34A73B921EF8CEE4C33639490BDA62E12717D553745463124D5D8D71EFCE17F73E5C8F01374DBC88D5E54FEFB9D9D26070DFB675E01BE95C83D82313AFEB303F82E9AC49408D5D92B6B435570A809E0C286BFB7C18215C719D3E24406C067F90F3C20CEECFF1571781D6355A48A46235C31720631F9C8E30EB9DA0C82F7F9E9F4C58DECF6C5B3A0B1D940747F27AC0478A9B6C1360A5CAD9DBAFF568BF06C5084521EC5182CF156C57F85DF79D98AFA0F3385F01A5BD1863CF836D132DEAB0F1D0DE0BC55B66040CDF41866436C9C4459FC1921ED90D3D07965CF48AF319BAEB13F0900337D77624BF0EEF80BC93DA74599CB74AA4F921AA1AD522187AFBC3135B69866C26B7F197E791D2873C7C520CC3D8B9DD248BCCA4082FC1AA98F2E851A814D4C39FDADAF5F7FADEBC2E6CEBD684C86D82AEA07B6237E320B75E873B763E1D5D36DBEBDA522B361A2705B2CDF78BA8C5019D2DF67C41EF22A872D71CFD91F437FBA0D89FDDA36E0EBF588EBABDED491FCA8C5D0AC5F6E14FCD7D6B132CB831D1EFAE21B51BA867589AFADAE45D77054C0EED8025A4D53B04282FEC01E5D23B148C12EEDB3A5972381987BFBDCC44B0A00B35A33A546F9B05E6D77891C6FB299185017653D5673A9738666D596C83224BEE68DB80BD3519764FB0B3BA7117F17EAC1CF2F7DD9A145DA4EFC006A5779E7D66E69F9958B3D16E10671C1A9D2EF491F2544FCA21688308DFF9F5DF029CBC75ED44F0F8D2ECFAC218C498D4C0638B97F8D514B9FCC2F3ED943595F489F564C34C2AAE9072419983A15389612328648ECE830010293A281CDDF9AAD3688B75DF17B10D8836EEC5BABED4918C4E325322C91BDE46655630F45F33D88D224BC3B6C3040C86076E82C1915EDD39A00C8D38EB064D3A50E410E5A35A8415DDB0C7C942DE119059CC1ACF2A375AD3549F3C6453F1CDFB8F491512865EE8FB5A04AF38DB4F772136954FE156C98C81450396653980096676364F53617CF6740631C6D80724187EBDAFB593B48F9643A748DCAABB7E8E247CA1AB65540FEFAA6FADCB31AFEED56E7AC7B4CCA250174CA4C37F7A457171FF7BFDC2C0F4A76F159157D46DAF95C7792F5CDC668175F857121A405B595338FB04F8ECE42FE7BC5B0AFA27380AD56FA7E168B9179F560F08BE04E6F1B1F09C90FC8A94A1C6D70E7A37294D16D11D73F4BE278A99057D349D6E9F0438F037A06AE3956E3EC8B33C8CBB04CAD6DE4D8FAFBDC37F192A3EE01A10A4C499F7BC6ABDFC383EACDFA09C5451BD99A21A79E2041330C8936D17FBB8BE322DD81358AB56D858EFF712E3626319C25235CBC357050022CAC0A6968CF5FB29E9"""), + TestUtils.hexDecode(""" +DBB70175E063054DDA24BCFCAF671F820D674F1D09CA173D4A1440AAF50F1FC8FADC1810F390286AC101D60507DD285275C6F97C0D2B2CF3C7F50609CEC64EB029C3DAD8B9954807E35D4836BEDF32501D0E7143BF488CD5B4D1A53C980BC70A3794E4392E4560E609B9C49900E1C56D319E1495D085440DFD081D1A7C52C0A8F64917834C64EF32A441C9045689DDD2EC218F58B3BD534F18309E1D780528D3BD1B23DDB3B18FC1F7C85324D45C3E9B25961FA5257EC31927CA35DB25E6FAF7669D60952502680BC7B5D777D77B194D0CC40372FC8F711EB048E01BBD5676CE3F2A9FEEAA4B5F29081C34969C746208E6F2329CB53A22058C0AE0852B7127FC4C74EB3A8300403F60B8AD1F95FD2991CE0C8CE452C2432B6422EFEA8AC0E1B53BC994C606301473D7855EF86687287BF56B450D2762C5E03AF26A987317C4BFB013A6BD791EFD141AB34718A37D1DCFBB63014F7F92C9E2870DE503452E271E9D02768357E3DEF6BAC5A0F0444DEE1FF5AFC79B3562C12696FEA15815B7D9BAA38C66919D137F82FE36B140B960E02966FABA1EE9CBAA04941396D665DD2C6B0559502577541AB0CEB066E066553A2DD407354123DF14F4B1DDE6B8C34E3264161796F48DB5319B3CDDFDFDBF5CE17BCB5924984143839B4EDDDAA8F0568ECCAD253C48D00687F9A07785A67B62D28B86D70E511AE08A525F66FB15AFD112C184785F91E76852DAAA3E78CB96E20249F38979031712440DB723B022E1323818431B897DACC51400DB25635EEE41761089DC47E8EA56DD0DF60B56FC682D000E9D660D0CF38C263B716359F41F3B190D201950E140D67F50287C09D2008664341A829A074F9629DABD88BE69A6058900DE5782CC621A91376E5CA31C66E3C430CD00FAA83BF765A2E6B2FCD20EEEACCB996FB5C4B63235142BD5FFB4390F8CB95BCD5853D0226F931C38FE972FBD0D6E10DC2CF29D1FFD2653CACBAB8B81DBE44A2B8F1C5DBDA7C56252E4B35888DFF7808B3514F4D7E5EAE9B51078E8D2E600EC57200FB48EF946F021CA8209E7DC6443B37D7281C73C6A3B43AA570398E62CD5ED9A34ED23AAFEFDB7DB3141202D940C1411CEFFBCED878C0D325E8CF7FDCC520CA3377BE97855827D2E6F4EC8786EA1374E006539387924161D65782C7B2C262AF9BA8FCFCB5B1477083836129DA973AB8B082324F74BC6320646448DCC8AB56582EC72EB192D3F72255D85FFAC2B5C62F245B73191A9176BA5A9FC0ACD3AD48D37E23EFA0C65F0423AB5CD0EB76BDC035112C7A118ED47C0E67E510A6F7A28F26C3D6A882EAE74BAE6CF1FD969FEEAF6B36C85F62D40CAA26B6CA98120D612598F360CA2628F6FD608F4E1E290B32C90FF71E181D4B72978DFCD189D857DAFC7B2AF8C958EEA6894ED59AD56B9AA6F83092EFECF9EC4091BCC9B8CCA245C30B54B9B8DFF3636BEFD417F46DDD2F6136B983CFAB532FB623FAFC3CC4CE8A91434377F4DCD1607BF04E431"""), + TestUtils.hexDecode(""" +B6662CABCD010DBE21D9C8E04A2857E7C78EF2AE1D5D583D2E292257F5CF7ADFDA5AE6574FC79E58F254DE8E41D988D2EB72FFD336856AE6A0FA1BB06CB2A8A1BB588F1201B31E9E62996097FC84D41DB9A57112F3F02B2EBB572602F054551D313172B84E90E907EA6E293F1FF7446C5814CDFE2425D61F3DAD02BCC6262F816C73B87F68D2D4BC0EF41D3C659D9FCA7AE921547E442B3D0BB2620208D12932CA6F3232E98BFC2896B8FBBAA7524FAB1236298C6F743146C758AE32109CA3A1F77F96D18D7A87B608DEA8D1C83F705989D50EFC5BC2228D61C6533663B1FCE85669D0A02334831DE3F2A770D2077D4C79A5928B21596B464D7EF0ADFD463491458B1F151B2EB5A6BF87D5CD39C5CA162CB8B111336417910448CD63E074282E51E3DFF91342FEF98BFF2E40C055B57FB2BAEF5ABD42085AFD65E14B3C60A00985F3B4758C0DA6B43A8D54DFFEDC07A298F4CE70BFFB27967EC5D59B91A3F8DC79B9846AA5255B3199FA422694B9C5E6F1A1C8B494D1B2D6F093E6CEE2768B1195615DD350E9072E736911B67FC83BD6ADFA60F2DC9BAB479CC0BEB914A0E9F064ADCE261909A25DF629CD56BD3CBF8AB8107AF1E3DE33D772A4BD8100F83C91934FAAB8776CAD460CE912EE635672D3CD3B14210250BC3E742D34448F8EC576F502276549BFE3D46763875F701BCB01975FEE50157F16A652524BFA5BF6F69EF32AADC43430C7711029C88EACD391423693513127C0411E08D7B4952AD5075A09D1F14287E94B885A43A88EB3D602FD122CC1507EA88ACCBEAA3E939305C0092834F30D486FFF47D373A68B55A01934B2254FC911D122343BDAB0F2AB2278EC4CDD7D19565CFC62CC3D5937C12D313D77A5BA20A6708A43BD11480FB1C7598A55EE706E9AC6BAD2641A640B3B0DB06171E3E9CF2E4FFF16AC1719DD97CE3C21564C2410E9B03CC9792661C39677FA20757F53B859655052B6DC8923A172E1801FD2A5B309CE97B3DF50031130AB05C9A0A7E6985471BA8A92698AAB7F4CD35976AB007B4A43B8D51042514621CE3B8AE764E997C18C9E62E68C4340B03DC4C63C0C7472BAD4EE36FF470E1DB5F2CB6F136B51692A1836AE0B5A00CCBB7B81450BC51605EF4AB1717438DDB7C5F1543A59BBDB7A1C13980C227DC0A412B486481A24BBEEDCB379B1979EA058ADE841258A372AD0A25E5C0D11B87585119282E9EB471D1E944A07859B43A65396A3252F9DBDA5C5C5E52C38529EC4B9ABDBB936CD7146AA90A6E1B35864516CE15123C030853FFFCAC8E65FB30696A0D64C170A6D60918DB28B8DC763A7F31BF7F55D31C6C42BA2187E07BF8B25595435BCFF169EA715F31EB11DA382D6D1D1C20B747EE14F69C8F9D27C353EC651BE930C05AD02502AA296F01B11DFA4EAB1AB6B9E99A59561E8FDAC25DDB432890F9E383F54CD7FC530AAB05BC61500C5738B058F2DF8D789F51922A66B015BDA4420051C1E537390FC4F6C3F790329C963D907B67229CD75641F8B00D2AADE441D47763682686928AB0AF9D94736DA210B4D74259442D623058D3E8DC3B61731A9A3662182A47848B8CC7A8127826AAC45D2C03BE0B1D2697D7B2F85A774F891EB45AD17C58F532074AE1B70C3689401575C33D57CC2EC0C00B643109834D5A57D1B546DE93EBDCEBAD143D5C6AD7498335B45AAFF1AE6EEB4EEA739642A8F68E703E827DDA7EAF6FB674CE8638F50DBE7E4F1B2AA8B3300BAD6F802E3F0358F0BA8C1881104EAA8B4C9887B065EA7B0CDA8EF2354E2EC5B111750827CEA337DBC55FC88C6470FF87A8B7B50BAC4BC7CC5BBAAEDDC6BD1E9F22663602811AF94F49021C86F383E1C9E64C465D78F1C42427894012FDFBCF90916A3D38AE0095EAE52FD539FF857515EA396280099CB36167520B1EEA47AB0B1EBE680506ACD029B4DE61C7389500A5906BC56C30919BD753BABF4E6F822885F13476F1DEF4BD444C39CDF1AFA28558BA48A6F99CD0F065A18DA8281D94656D94736809EC626BCFFDDD1A777A1FA67C642D08FC30461AD69C1332FAB84B400161C3802F19E89C1E962D698C1AB1C8D61AC99987E3E7AC28A8FD42696928712A9E367CE28F48CC9D17D69463A81670E2AE088E0BE21E0A89EA9ABF1D1986DEDA702919A2C9C1CD6851B3356908FA62EC2DAC2817D5C6C874B8F6D5F92FE7617C9CC2C3C221AA2434E156FBFFE8B7C27646B93C866E2FCC1A32D2BFD859B432CC0EB4745B1145F482D03A2B22BD026BC6B37BC802D8621906DDE752AD414615296A403F9F1931EA80BD8B3928F25396166562E62C06B946853C17E30C93F67577B35E81E456952A4086907BB6049906D9E2F9D1927D0055AB0CBE11C0D82D899269D145255EC8F2DDA1FE481E3B15DE0A719391088C1647F330DA8AC990FF06CE0C957F8482C88127B2B82F68D115FFE880BBBE9D4C6DD2D9C872DD4B91A4B52C217848E38805B92507C9899484973EAC5A47C78A53A58E4219B86818DD90F5483CBBDA8B56E3A12739B7B287F29DB9ED987CE4E93079B577AB4FC421885E7951098B1B036AB3A93CD7F2FD65B75EFCB7007E8378D2BD18C13AF5CD6F8B0E5443A87649C2463BEDE2951FB7A963497668993A9ADB3690B9969596DA62549F0E5B597D3BCADA83E66F565E44A0C0B88DB3EFD076DD011141D8FE0348889F0455E3E1AD8FA47F5C8F28005C63FA4562C88AE0405A95069BCF1085909198826EEE7C86D379AAF244A7BACCE44F93D1611142421DB3C82860736016C36C89A3B6FC87509696C708C0DD2A1161F6748EA33D1989ED65D1DDB8878EF158BF1C1973060C00BC132E2407D1A4696C6CE911DD9BB4B231C961B7FB427E8577CB28960FB519C9F977B627B8A59400E72FBC12B1A207CFEF4C2D34592E0D2267D30BCA0AEA3E22C8B7A308B02652E726B2CA97179AD96C8165FE64F230E87923086431D55D1FE4208A987C61E9EA8F38CB56B7DC086A192FEEFA7AA0FE2B3975296B1EBF6604DA709B8A7169A3C610061A4E85EB42AE122A162275256DE631A54E7EC4E55DCFC3FC58FD0273333CD29731AA0E18FE0CEED334427EA9220F5E6401C68ED8B0A0BA69033CF6B9F1960DEF6BF9E5978AA7C1FD480AB685E44227A4B64651DA47AE3B27EB6029D59B2DFD1118A64A218FF7DA3779A1C0227A9E26F92DF3A7EE73382A807B71ECE108E5E46075981A2FF5152BBAE895C9B0CC66D86850DA85FA737E2F1AB80F8C2741190000793DBDF6C54482514704D09055F65F1730B05925CD1773D57849EEA88DE4A3DB8BBAF341BCAC5CCD3B56FE163249334861DF702729EF012659B8AAEE1E8D4E785767C3CB64D1319E23533164D6E789DF1501EB9A6FD7F0F14DCAB73875D4F2848EBA3329D6FD40F60C626406BAABB2B81C95DDB127D20F0FCA2422F74DC6BC3AA5256F3F9F5C80B81D1CE07D62712CA54662205B58E56B3E1684D69323B4E73D6C4F29D9F70F68D5FCC3D89965E5A1702523CCCBC08B3F6427A616C6DDE12C374643F3C7E97CF9483036835D4F928D00A673C6C22F16BE20AEA0E4DFDF88DD4172D4DA21D4200E3DAF7B3D7FDAA5659180BBB6CDA4AD79A9FCA6D5D2881826B40030314EEA07CD45539BD0BA04525DC79326B5AD649B343C23F2887226706D66899881B7CCB4CD46BAEB41E9D047E87AB8EDBE95E02672AFBEA25976319BF35C13C2C1BD042D3DFA527E69DE13C84DBE8410DDA13F38B3FAEB479ECA09F876095E5761ACF0144DD946D2DEB7BB70534E85BD2E23E1863DF685C7E873E9CE29930F3C2A8F78D77F16D4D34A91F1060B6F275DC9C57BFB49A6E5C547B9CA023E418BCAF73D8BAF604E91F5AE69F8CE08B36EC91CC920296577A83C32B07B56776E5311523C346D9590D57F036187AC1CAAB62A4ACABF360D6C4E49517E30726F26126AB405381E02F4C7CF794F8979D54E87B6FB082A8B8A0B1D0A26090A16F09E94D0CDD02886C6545F917D905A7EBDDD1EFA8E5C7763A32DECAA87ED7229C774DC4287B065D04218695B3142DB41AE748912797DDF08A4F8495334E15094B51B21734CAED59D5D2E6635DE144897575B5DD00D51F98715C220CEF67CB08FFA84AE2EB8491303D41F5EE405560930F93EF7A5D3420D203629AE0FEA310855EE7908C1346672C669025E49BA520C471FF6DF9D34FE3960A5A3957E5A007A636A457688AFECB68572B0F55EB90435578E1C75A30A18A17018A7B753E479C677995AD162E7D04AF4D4743A186031B37D9FE4FE23D274DE278FA30BC2C9EF5A5F1DBB431DDD23D8D908722350C3136D26382087BC7399C1CAA1ED4A5508AA0CD3FCD89A45119EAADB689B1D94B5F58DA23A650D52E5C77B739125E660D9836647D7371BC635690D77CF63500085A2FAE7C15ADA7654208FC88629307A2DF3916262523A61C177A7E1F8FBA729B6BCD401F8033302F83DCEF604B4C3F9A5F389C354AA4B938DD145B54A00994FCE1ECEAD40F8D819F232EFCC05FB812A764486D21295E56C4627BCD1F3EEE644DA4E32A8EA4EC4FD405B74BF49A238411AC85E15E4B6755E2EA566F2C38E858641B3486927C6428CB030D1E394A4D4F5B6B79BBF42343A74383A5C3F8FD2373C3FB2D31626ED8DE1C2B31637386CA00000000000000000000000000000000000C0F15191F26""") + ), + new SigGenTestCase( + TestUtils.hexDecode(""" +9BA12496D2759ABB2CE2C3FDB3FB71FCDD7C315B4C7C5AE5C6B4B4F6A97D2335B07CFC9C4B33D9147B6231C6B33CD876DD71889FEAE5C8875128BF0D75F72E380A1C51E6D56CCF1BB2FF2453BB7F09EC9E1FAD76A07CC6A4CD012726CF9309E9EBEC279BA77B159B515A954FEC69758F40EC0C3B3836B661E1FED121F712889B77512258675704133806066748826547111521115868474531585416005713338105507070205662844057632638535166351741357313537883572686500540128261085411603366201318374814306288785181752828400800470585613434710704510035385872517651333585207787188184062530114384673018530063727426246401400773237530844578751387817248277471125878621454431146683341406818333868760704701502761143473707860535758187372162868573323826480416420733630025672348726538053525024423653243546423514553071340770645158747722387267847757250586600731582661356526504140404107264574637750025462020601372686055328846034067308301012344312705314305867783080470360821015418216663460502701754763838654027628220553546644844707313784544085501508364158844217135802560352218345288786203528513537552882486255033112148517000583211241325641064030340235323380524631220275268447538464445758352140612704781828086872330585810217000036008674504425701420181180377803350424765338285178682720218181012520214517830318082227120513518322554881166140214761423438151247072168382748504452500004758363227304767704161305584642720280148873012060716368664714384685145586365736257431288024173772381536807648611435052307322366547752204377446868057638617731102741825234125865523273560843152782032533880776282206451272477621267326281383315581785515642825006261045510323376338070785444022023713881268480640885038174347552814543067652828245641383354501751610445443231755333835224563515134301511513821681374734335016003216522571455880410230421326311811338146248236660357671633348772574361832403770183010531215541634647651601211557845444264232368206771167634647778401370320484608854756652513571656277447284614256054125825545667871576431852286416638036374180758183634577548265761215082800487735370570835434878138206660513012214466631044531375060518448334384743777234256478821032557054374186280115238364375612238562440815877116541472770062087278326687024403300345343640711805831336621255213741538544438567453332843754315440442730654367534363248630360146213140072646271447800025357255281341257570554320245275102060221620818717848621585406508157876043725614243441752316510561605237486301154208628170146326444636374671281028428888054302763653254651680624433732312785052851001186422542016363135628821440082566635447837137437567738250604600438461732334063187876327123582736038000542537210170133043240437625172228545888471831032816233708717083020220534823336673537346268102842456807765246230548276186624233334504072552008188226324457005707040616360473678536233682028686415232708258156535400766767114686043413232745516072208330587043436465427087756584440822673872786114734048782500067420780002787748322508678107138016507217573854055248812267683351608427542745123578836475638204547465316772773558376364227627315732325112263147154784743851852416083411402663045461736077851483201053723540300740062572041704370051846EC468CE48A91039F26B5E7756BFD4A483E0805A91A1A5F54C7AB9507CC918DA35CE125C51BBB93614253ED63D269380A50B1804345C810218E0DF6EEF453AB0CD7BEBDC8AAA364E3C458E6AB8DD9E21BB72B0A499AF42763E3DAF541E0558E5E3A154C4F800CBFBB451CA73A620B3748B04C7D535088254D6267A28291CAA541EBAC426BAEB242E19EED2786BC26A40841229F2934DEF2A73A5C6F3670E681F111A3A1732CDC2813DF8772596A7D6FFD5F717F2EFAFB6BAA793C345FD4ECDA18B9202309C27D00BCCA6E51FDACDD9832A630340DA5CB703F2D68CB1C17EF8242B3F3D60579616E6102B08ED094C1D0E725E2985A0525CCBA21704364E9031E086EF875BEBD0D31A922B91E9B95F6E57985EF2948D9A7638A1C0C76145CDD9577C5585B434A790D6A87809FF6339388938E2283FE1552535DC30C3F073B7C8BC80EF42553D30FBE79BFDE391D9B7F87BD1F809FB671F49F159E4C653654239EB1E94B757E9D81E2809EFD283BD9BDE81A2D316F66BAFEDA9D4A524BB270EE43451434F5F61D33C6DCA6CE3194A3017B5DBA255E905302091D5F341293D20B89F1E5F81D5731014AB1A5EB022609FD6018662EB2EBCF6F3F823DDCB86A5C82B9BBA5741E1909CD60C1AF239FE3B930D0E8786F6ED24A6A8A26E03A05B0BA51AC54F87F845D680A1FA09291405E758712C00B9C0C8D4D698CA82641040521FCB063D5FBE2271965AFC1F4995EF47E4E307D8CF97D9D22A6BFDABCB726132FA7BBF5258226B384B7C06160AF1D0CD8CDAA4F16F68D618F417FD3E78DC8B5611052D2F9E770878D7351D52FA00847A426C9CF845711318FDE114934323D02F2C5F37B9FD93E22BC9433142095BE1D6DE07C7009162F4BBF057466E04DBF98C4DF770A2DB27A5735A4733604247E2C3AA1AF38B4D9D267EFAF31D2A3162391AF0284813D1184217F93221342D28CDF90F85F94D2F66024D1FDDFE6B95774128548611196000DEF8681CDA4555B626CF2D77A2A638AF6FFD0DF73787B955DDF5B9F0A6487C60D09A466D2F97C985CD58E4A8154CDA4CBA831ED2E386854B8EE5523DDE4D0018BD17BF03F02BE38328DE99F9424C01E6F2BCF9DA3C75CCE87558B977F5CE91C9CD3FE49A1DE4A45B162D7C4EBB4204FFDFA5A6AF4CC2DC14B7423DD9C819876E42A75709E72B18689427324ED0621AEFCE11CC766858D46ED7F1783949A8C5618AA1ECDDF332F2B6C92E5EEA5D5E7DC87908547656B65E26D9FB5B2068EA5C39CFC01021CC11C0845A3797541301E6B6C998BFFD7EB03F8B3CD7189635FB13A4E42AC5249F4398CF221C7DBE68863A8E05D3FEE54B905A64A4CB6AD5B9856081AA953D2F51C049E183C47EEAAE60F980B29680675867405F605B5FE8E13C0D3C5955F801F941CEF618F62AC6739A92A818A0F6F2B1D8E259040D190F371577AFB2289D13389579452FD1027E4CDD2BAD5F78A4E6ED722A5984665FEE58FC209AA232B38F45392970F89ECFBC0690785D87A7E54E5DF49EBD9175F530FE091624B281AB66535197122765DF0378ED4814A3A4FD60490C82517C98631C51BF9C4F0AF9F597BCFCC1C25866D2E9038D02CE583AF9D564EC7A7AC4AB7ABEA8F86269B6DA84050070CFCA06862E03039AFABEDE496FFF556031F083255CD1C46F3F94119FDB8414A6E80CFF99EAF2C5BDE4794C119D5F4A8DEB2936C2C4E249E3DBA13C0D938322A91E860D4C4D8C17AB6DE6271ABC5E4F99CE6ED0D728585A985068A0A388A51759CEA3B29CAA0FEEC27A2DB3A252AB4A18E8E477004F5522D308329197229382969DE75AA3BB3C775AB0F74FCE5E1051DCD2C2624A8EBF1F447F7417BA2B5E85EA0CE6678AE6FE0B113CAF257C7BB73D1A5D91AC0529CF7DE38792CA229D1CC519368CA4DB063FA95031F4EB0A5A647E092F59CF39C9A255957DE2EE92AE1FCC4D041DAE51BB04C6B8E5BC52CD73F31AC745DD79F27908E054A2E3906A84113FD7FD4E764AB0F21C97617A82197D1A4EF7E73408B667FF71138BA727CC26A400E5E5BBCA922B104D588640484EE4867EDBCCBC45AFEA42AFCF277A63CE6661B57B00ACC1C2F76D8C203FF2123F9079EAED0B0602BB1788595A9198568006166C61806B5D6ED03761C874E9788FBF180880F9853EEBFE2A933AFA6BE7CBE917C5919F9F17777F55A29E7CCA1455E38EBBBEDC83BB062E914F4A4A2CF1E7E32362FE97831FF33926F1CD9E99C80AAA205AC365173D5DD94B8D8F3922FB192F277A09BB7A92A5166C2CDF7F18E7DE7189ED838F7850B306576D10FF014774588865CB5EE3B161E54529B8E45B2FA435E36846E80D46CEE9BA5413BA950A448662FCC5A8BC8E42AD3A75326747A9C02A6A6C676266B580CA91AA4E9F892EC00EA64065D38063881024F5A898451623FEB3746B2108A24096F2290F98C9DAF9A4DF9746EFD5B5D9FADBC67C9C06F920E5042050CDD3A1B500764E7936124B4C742677300DAB0B2C56BA69B7CECA73A6F97C961AF46648381064764F48A5D16CFC82D9766A35171CCAE17F18C82B81BF91847766FA1C361312B0E532092F9CBEEC51A55E460B67E47E91C90013501CBE9C00E1D84985D6161691E0AB8FB540207991B3DC4A8B444F319235F3B22D03640A98C5DA08DCC417E0FC232316511447752044FDDEA962915109466284D94F7965C37F5E9518826C1BA1A94371B28DE026962AF755AA44035126E6CBDDA35A746728D6BE15618180C3EB460404696D59ED13BBB60BC71298659ECDE17F0264971C5158264D9E9006C627CCB58AC9B5AA5AEAC12105EA17AE78C1D9AA9C479917149E5CEB8C22910305F5CCFC2AA90012D2B6DFEADA3FDDE35EF41CDE929B88F7395CC6CEB401392DFAFDEE51B30A53B67969DF6AFFEACFCF455825675CC2A6F6CCE9BE60D23CC0D6ACD35E9C833A3C82CE16ABCF9E0C56A2C18D1C1F9C159867C933B6179856B9050D5AAB4A547594FCA0CFAE4969CD0B50875AD6476D9EB70674434F36935378BB00B4E50711BC0BC375449CA9FE75C0871063E5BC55567D4E082BD0B07043F9477EFC5F8DEFA13CDA03D3EEA1DEBC996B88E9F60B4909A7B3BD2DAFF53CE6B6046AC2F1463ABF3BCEF4C112AC1E625DEFDFB28BC0E0D67061492B0F64B7C66B89CD1039EFFF0546EDFFC69D14F7CE61FEA845CE360D8ECD01D1643AD4C9ECD76125CFB693DA425D877B7CA327261A0CE4AE49057C622DCFF48C6062E0AF24FF8280AAC3F21010C05B789D8FA371F48F18A2144FD1F8423112DED4DB1035B2F5E39329E680BDEEF5A37B3155BAD91DAF7B0CD8346917859D7CEEFDCA7E7C6983E09D789AD7EC35F9848B639EB1F3A1B44D78521CDAF980D6F52FF981C30605E8F5C0991A479EBFD92DBBD6CEF2FE4B0C70015943D2F1A072FFC126CFE6740DEC7DBD9DF059FA1C03A51ED2EBC7B892FF0F0D34C2DBC4C1561788CFD18F0B4A3E2C0B3EB57215C26CF7E28C544EE7372D7841D349F261660A3AD42968D98D0648975D488C2"""), + TestUtils.hexDecode(""" +5F8F32FE68B556ED1D2EB8D2BC20AA36DEC7900F8E5D4BD3715419B28771E5B0A080DEB2F3EA6CF415D40EDA46FCF8A439954471B7308D3E4226E9D5A96BC22B08FECEB4C5E3CC2239473F1C9B8DFA5A29C31D499CEEAF6E34A396BF0DA53B54F1AA674056216756DFE15F669FC2E1D8E6F67BE5BFB3D5703F25D62D3AAB0398AEDEDF7C65E051A4A8DDFC725EEE940BD0D06B103EEA32D027CC20A8C61034DC54BD5533CDB1A85107B9CFF283FC3C5FCD9C3D6F8857560311AC2E0E31585E77D0806F9A4E61A70D3FF36895ED447C55DB52002488045CC358A39475BFE8456F4FBC36005218B2CEC1C573E41BAFA7A622EDF776C8AD340680C1B3002F69D3B3D8844494EA9F42D2C9C9D2BC0BDD850BA3C4DE929C1DF49351219F95EA7B9794827FC1A1BB4A6A00809393BC41852820569D7BC6FD55339925FFDF55A0C2655C85144234FDDCA91E8BDCE8CFB7199330763F5750D71CA8C4B3BF7E6469F5DD68624BD6D5B69E5FAEEE53E3A61AE659A364484B7D2BC8A85BE9F8D35C8B97716E8202B610BDF878C1BD83187F7892BD861C09FCDA64606A185B93CD2F601C3107D35B38D76D75AD6023AFDD95E103EEB7283379BD9E44CABAD923856A599B719A18FA836749E5BA95C79B1F2F1B443CE1FD26CBD2B74A0156C381BC270B74FC42DFF8D91DE4ECDDF3053007A09B8E3C964B90DE55DE5193F218685327D8C0C6CE3BBABD57DA8772DB7CA9234A3D19BE16A895E7D14337FD9D50B4A556C75A9D287B44BA5AA4E52C3262218DDCEEE3A7BDBE1B8175E84113F515623C07BAD4FC0985112DE4D77D31290BD013562D12FF8CBC5F2BC463223AA82991D7D60E38037578BBEEED70631CEADFE49823EA3D87EC384B3FBD4974C474FF9D47F467110EA4F3FD94B5FF38D8FC1C75392896394671853FE71DDCF7730C70ED26485F395F180D2F5C31AE0C2C20691CB4BC81356225E6A72DC72A1CD3502E42C22B594118D131BA5EF95F2C18B3061139B047A24E32197F89780B91D36B28BB5EC6C03232A3CDFC5ECF687BA5701F3958FD87FC0C8D09825E8BE4E5CE9089C674049C38EC5E0FC1AD542F57B4770B6E5DDA215D319DBFFBFEAD9141647A508E271CF3B0DE7C137A5AB999CC88082FF0CD495F1F1FB1E367B57BB400D8697B4620B75FE467D9B8BDF9400E14047576B3AD6AABE0C0714686015B8A963A0DBB68CE9E41FFBBDD5A792920916538E4C33F12EF0E93D249E562B71BC1C252E1DD8AA646F8C7B489A2BCFE7D29A6D3FDA2C21DDD78179861AFC766F6885E9959F753C66462DAA6E01C8B06A6F581104B583F7A5B1B4935A4EF08219FA8D114A963F3FF3AF22C3D1C1E3927AEBC886AD0670FC89C08FD4DF68EB990A0F7C51A4439C32F5F51785B20DC82586940C35D80A91865C3154D6C925250B24D4C1A9E76A267711A0813E8CCD2DDE9748FA0464006DDBA963BBDABAADD377239442DFEC6F7E8098604645D63AEA080C1F749CAC589F77B4AE0955FABED757E6576966D539FE1BE5965D03882279B2C9B6899205C9DE8D0B1819DA8B5426E573CE785FEDA3BE95A18A667AD5AA8FCE7894BA11A44B266EB7571A93CF9FA64C1132AE07F0F24773C83DED2C2885D415ABD96A21A0381811D66952252786C39EB68EF0B9B03BA7E2B66A49BC6CFCD8097C321A932E5CDB11EC6E43A8E50DDE01EA5A28F08F5047C67C988E8B4A04701A0237330598ADE8EF8F801A07F2148B44E593B0ED16DA30BF37A341073C6A92066645BD7042C3A59B374FDAC00F7F69BDAFCAE5EC0AE65FCFB785C93E49102F5A5029876BC23B0FDB7FBBC376A9E834F0D19A276BC4E22FEDA18FAB529F15570AB674B844703B47D726AADE3AD4015F52D86843A01AD5DF086E07A71A0236765DE6A777F94B1D69253A424193FA9DF54899AD9915634DA23E6DF351E9608219684EC8C8C949E900718DB6FDCD144D0BBFE1079C1BAEC516BF60C1E24B8EE6DC380F55E0F65DD64025C937EA89FD12F0404ED0C03CBA18CE2FCF169F9A1EC9B96830FAD0149D4A90B13446347CE4E5C6005BF115385F1D22EF6A7E40EE87847BFDA4CF7FC3135C4164091F49DD08389E1005271E9AC76E27B0CDF360EEBEA9C08E233CA58305CB276A8BEC9686CDE0E2DB5CFF9858029F3A5A42759E4AC6DD40AF9617CDEB03FB1F9D7F112A01B87A265C4E27BBFF596695F127A97E1558A68BB5EE4EF0F44D20F318FEE1CE988051F3C09AF6E142932EFE970C1B0C07040E7F3DB9BA53BC4AB1433F7A4F1E480D920C23A07223D7E43570320B3BA590507D580D29CC3A8C85A442BECED5880350F9D2B1AB5C746C1B9909E446D9508D701204F2427F41E043A78024EE3F60EE19B71B5BC925A2557FAA8C7BAC7E3405C920FE3FB3A1BA7C559BD75DB1E4169804B6627AEF19AE6E41B8A40CFB977C1AF53208F4D775A48C220A756783F41E13B7780328992947D215C5B5682DEC76CB035B41C007CE1017EEFBA426EBC423F710C1E962528F7636F200C2E79D8377D621513BA7EB3EE5A0DA55B81F6039D2E8BD42EBA5B2A82C3F033CFEED6EFA7D970B1460CEACD13A0C67AC0A7EBE7963F0FE21D20B2A82EA922FD889253B5D4CE4D47698D43AC11A8F4E1638AD3A4C179C522A3ABBDF420DA3E89B9FB7608822904944CAD615C62B28EDB15D3826D33DCF9FF9BD5DFD8639AF4CAEAA55F9F8409B4E5F70681BB7861F88283218E15A4282E199BFA12360FFB9BCD68D9BE5A3411FCA4E8279562F595FAAE0CEED4FE675DA4A8FF94B180AE9D0C8C687650730F05715820F67248D02EAD4C7BC0D41C880444B94CCD60A66A1C9B5B6F6690A2E1766EE10B5D03AC16F175603A1B9D49F97CF3F91932E97DE67CB523A38839468EE7681909CE997BFE5EEB364B472220403EE4A9AC1F8A4A8F78AFA4D9010A0127C0A75D3CDD87DD269F19A47C78F696218F25AE8A61073644A4F791ABBF1B180267AE41DD44AF65EC6E0AB356CFEE86095B64F4190D69D60284A1EB42744C31536F736AFFFFF186833EBBF43709BBE6903A06F7F06E8776D2AE41CFCA33A3A86342BD11B67EC10F525563A1843C8443546C1EE61DAF7310802AE9C00F44DBE7E04030BC4D0F53AE2023A7647F08A0BC6F5013A61A84E994FE0A20092DE133FABAE3AA24F8F3946812396B0643721AA13417A2423F96CA8A6529B0E17766E88B2AEBD79AA9D4D31193533CE50E4EBDAEEC976F156D5DE5917D54F9CC0527BB4F1F795401210739A42D10A0242748DE5FF6B50932B507057EECF8A1E37800223378642DEDADB464F5CA251D73DCD28A1E3772CC285A33B34C6701B585FC03C94A847CF7B16616D1C3DD646669546D80A27E9DE6424AA7AF6F1694037E774259308E71E15D7408BC1EB517CF0AA2C9E16B802CC8553458BB66D96CBA233487DAAD6E093235D901CF46F31B9A060D88DBD0B7380652EFC73AC1A6BB5E434EB0394F1EDC937E9A99A3867EB71D6E19622137B009D36ED7F9890187CCCE7D884DFE118AB3682EC08CDA8BA6DD4B79C9C18E7438E6914DC1C403870A540B74244964CA31E730A7D7591E42569532DA8094559241F2C7EC182FF8BB5A3F88DFCE3020D8B8CC0D1F54CF67FFD3A97CBA7F5EC79333D9A545221C963E0685763E59F1EBD34FB2394727896CE638E909AE6DFF41D17EE1D0BA036F8AF11335A8C1B5A0E9DC58EAB9C12F46740493A8B5AD0EAA73AF462BDF43CE44BD0973688D9C8DFF8FED961758E1AF88FD5D249FFEC179FE5AA1D135C0448D80F4B0CB68492CA399A3916A2EAB684B44E407706CC3C2F48972BC9531353091F91B427FA32693906DCAE862F34AEBBAEFD30666523EA9C27354F2FCD99A6E810685B51965571E4B4B5AAE158636497B6F952FA0B73617AE35A8D7C272DFEA1CE06E983CC65A501F73BE9D69EDDE6A4A1764DCC4B74EF09EC27C74B677920AE8C49CF4F18160E04B5AE7EFA8D5D92BAA5E4E547CC8AFB9D55F1A9DA7A6AA06626673431889C9996BE0A473702450B960231A617DF4705B07B47DBA1BCCC0EFCD5713F88F394EC4BFCC49EC24B76D531A356A6796785D755F027C664D8966B5CDC82ADE776BEECA8AB0D9DB6ACF5E841BCB4381828DB8F7358A637D04D97598A8B3BC823B891F5EB6ECF54E6F9200C380813FC3210E68894A656796C9A5B780FF486E6A93DE055B8F658FEA17035D9C212D23BB5974E1161E4F6041E5AEC446D70D52CD2F21F1A33C9938032487D9ABA74C448EEB8F8D51169E8B848242F5C769B471F0AF04E965BB0F4AE7C6F7B4AAD4E283DA762DFA49FD01D21887ADB28781FEFBD931AD8E2A26BBBBE5D88B52E8B7133134CA76C6648EA39E3D2F102177F4237219E06CBD05174D503C9288EC9C3E0128A824A7ABF418DC45EEB3A67777F74D6EC52891EAE0BB56DC756ADF40D39151E3A68719C563E99BABCA4C785BF4C2BB1BD25C7EEE22A8B0C1E90B948FC3A691670E9A3A331320CA4416B492907C3FE70AF9A2E765F9607EE1BB2CE52D2DB15F5DDCF59BDCCCB5BEBAC2784FA0896BEECF38C24022046E5DAA7607E8D2DB8CBC65541CFC6A0F20CC3AC5EBD4560BF5E9A3FFC0BAE917B479D960ABFC99EF84A696CE5A95720FED90F3AC58D77D48BD5573A0D85681238AC0EA8F0B58A01378929C691C146068897C5642DE74D79E08E5B94B101182200FB3E2BBFEFC8B44D2D1203075862D77A184B25A7790D76D7CE88C979D73E599C212F04A8B01EC3CD6CED3B5E25487957C56BEF6AB4433FFFE6DBDEA396212A6870284FD1BAACD5F7A5D9FAB90D5DA39D3C5F9AF196D9C46100BF45861679A7679638BBC8E5B5A7606D863478B430BF2C61F52D3D88B0913BF12597620D337DEA52BEE9CC8A1592698D23B23815C596981152C99453FA16800545EE781F24841FBE5A3E5AD8D08F2B898127AF40A681DF9DB68681533C349109C29D19311BEAB4C2F2DE97A5345EA7E41CC0988B2042925F1F9409D947128CE1D38F278863385A19B2CF8338D0FF31B06FD865B9167488EA157C7965F4679286077894660F17BC7289BEFFA93CB7DB990A0E40D998945A77E536902FBAD3C8A278CFE0AC883BBEA0B20E5D70EC6E10B59C2449CD1A0B55F8252C91CDC87E70E72FEC175D6D67BD43CB5AE4EE9C7F9476F4589E2BBAF89E801D5E14458F8A0B96ECF9F080E5150E2A5004C5A89B735639621157C4056DD1106CFC727B921D5890F37051E2B906885C1CA3999C18FB8C9FC9B652D82AFF074EECA9976D612ADDE990DEA418031FEFC4E972B31CBCBDCA0469E3966FF6F97F9788650298DB71CEDFC04659D30FE673602659C19A869FB3EF4262EF3FFA9E3FFAB1A3FE7670061EBB0D49BC60AD0C774913910E26E4213B76DB72AEFA3CCC197CB6F6DF773F86F12480B5BBC2068F61E16D1C0C141AE6F1811B2E0D713AAF60B90BB2F00EEDD4651FB5191DE5A246A4D8F3E9999D85253FA705CD4B94A6A64D9E9B6E18BB6855CAF6B991494A8DF75E56C2A427883E0C27246E5854B8DB2EB0FE639BDD00AD678D1B61D799AC59ADFF6A8616B357A4B12A786EB612E5613CDE533D92E87D51D47D860BCC39687485EA814DC5F5A971EE915C193ED52AED98D7AB301E32342F3D207BC03546460D33B733E1008E48D80E716FD717BA82403DBB520246AC3BC9CB91CC0ECDB7E35E6863C3C11558A8EAE9E1DC49FBFFC0F92F397828A4AE7107785939B96932B9EACB6BC6D8B3A189B5D3F6B0C7A3A413054B25318792AEBA3F4C77629F1E8CE1AAA98FFE1EF50C2E60C11AD76EDDCD8EEAF858364ADD637AB97ACBE4D2124AC0AB559E85229F1B5D81701EEB1D6834FB215984E9DF3847392EB29D2A428DAE7FAC283F93C8FED86FD2377E8216922D46A51E628091F6F8EAF967740B0EFD84F002358D3ABEDA0993DA16D0D8233090A2CD9C27D78DA0A53962FE7DD282B276A30F91C2B734EAD2CCE5E03137205BD97739F6CD75A08491D4ECB22591A6FF840B5DF123FCA7DAA98B11C85C1F8591EB988024C206CDC4A4239E7A91DE75F49541FFB6D91BE4699C0C0D8B4A44A8204F7E90AB863C3183C2270D185643D6A7165C1D043FC5108C340650F38A8FFBB13BE4BE68858C50A2463F7BE998286FFD0F981B45F5E414FDE71637D6EE77B33E10A530C630D63F21A212E844C2F7A26BED4F7B4DCE0C566CBAEF4EB4BDF2B53E743EE13A845D3C7AD5E9525C50CFED35DAF5D993B6377CF1DFC5236D51151B046F4904A02D7D51B6E331754B0E3621DE4CAFC9D8F7247788DF0EA7E6141FAC4B24608282AE29D594CEC0C82DB05C0087AB377D0D504F64F1CBB2D9F3121087AB6F35A70ECDDD15C9AD2A185C16333BB901CA069BBB0B80CB6F505FB3F382CED72CDE60FC050241B1D32818D11AC4421B66CD85D0F7B479C021AC111F8EE8F1C60B2320585EA276879AFE4034DBA277806FEEACE548CA0A5D36CFAE7B99ECB0236CF4838254A20A13A2DEAAF201B09FD027BAFC3F0C5ECA9EB5850A58C6196645F051E57B82AF4B6C2DA9441358BFD2412864950022A07542601631A00E27BCE6E203B1D3F1B844CCBB2EEF71A12AA4E725188073004849A225D733C77C068B0D2AE53E0DA6F759A8E7A5486C529B29A3EDADA69924E7DC200158DB4B612C62039B321CDACE8294DBB1A56ADC685B0B0122A4F3DE0A264F47B00C903BD30B5E4281B0C75DAC5C48E18BB0BF642F8C2CA194AE56CF7EF3B4529FB9271774108C61198A6894FC9FAF896472D1CE78DF00E714045C5F7C77DCEA45B3ED5BE5AD545D8F3833206340A5E10DD3375BDE0A068D050CB4C87E0BA95CBACBE59280BD5CABCEAFC88F5C05E3D8DCDA6B15C487B62B467E093259230D47B79F36572972BB78F90BD384255CFB1E4F1DFB7B5360EBE1230F154C3645A7A233FDDC472432F6C845CE86B078D93A5BBA3F8800C5313593D66A8A103B01377FBC5C6D5FB8A55DC71EB0BC9904B24BAD2F505D6DB5640E914D84FC71FA058902578B72C47659AC07AD4D64C3D28328D2DC8425C4039EFB2F20E3B954BD0B0483848F2C2D9528214514510CB0932F7506E9B98D0E891D8183A907FCA7AEC068B9FDF7F3479A128C6982BED19512A4271D8B682525B5028B77D6B6301181B403E5F62F64BA3CF06F0EDF321114855839E9198E5BA2A65ED952B2204809215B9BA3C366FD5C9D409BD71ACB748E653DA82EBF617D2D57C74CE37BF20AD8D789DA53C086423D86F94A96ABA379F3425554BCF92F82FBBF5C2A15947455D7D7478A84BEC6E3B9FAA14E425D2C8971DCD157C1D9E210620E891AA4304CDEC54BA7B3352556C49A172EAF19919184CA005A526349918F9A7CBFEB83510AD899BAEFD3D1F689DC3F449153597C8D21FA1C7BAF18E689B51F89B9BEF196193B7A781B96B38B9145AF7338FCFEA109542BB1719C9C8540B551A35F733C394F7831900452C0B8D36BB90824699BDB587EFCF5E8410E4ACB8ECAEC5F96E74A5DD3DCD4C85720064A14028FE768041BA1A13A46CD8A0D2C4D09E724591ADCD5EB907038853D8C92C5BA7FF57D5B54B2B324073C7CD2EACE0C521254E9E5C0CA197FDB3C1AC73FA8EDA729A858098E6F5EC11A19D4F655C6DC9AFFC4E67A49EF62D80EFBCAA383DD3DDC22C2A9B7590C16F8CF23D52392186B95EF9E947D851079C35FA11595682DF4EF4D770EB16CBC3994326B8AB3B2C279149122D178BC7B53318406738290596449D797F61B3D0CC8B11750F8D841FDD9D333A5FECC67CC7733824BBE257D40E53B43CCA19C95ACCA8FFF393533AED57D423BE0C38584A81689248BC7F78CB7FA4C94A7BDBF3015B4072B83748E55ABBF4A334AED679D89E2F18BE1B249B3F61363C79AEF6E1FB09D1948610F77A9927AD6D57BEDA02BB1E77415DD7FDD3EFC683AFB1E20C08284B620EB091974FDF8CEFBCEE1461C210E81E86B61F2D5D1882261D60D60689E39C81B981EAEBD9A42E608A34155516E4E385B86BF0A4AA05E3F99B6B3B7E401724D1442A45A696A189765BCA3240111E9259DE161DADB4E0ACFF27818C631A8A2ABD752773A83DC29CD619A58556040A7B27CF56086BD499F8B8D283683377A21BE120374B8D4561AFE781F246AD987E828FB40306366B4BF4C0B4B909ECA91DC85F521ED5869A2F2AD58C74B6C959AC71DB6F11503F026DFFF6BDE6BD70363B5B38BCA0590A5AF2A1054209A36B41B2A671293F2805568400AB282F783C356DDE30E0F87C001D9B1B9716A7C4021928253622F2DD156B3C3038A077A5768AB8AC070BBD9467E9C9630754934186BDA122CEA503F5E274EAED746065CA81A2702B582E82A33CF6CB3917D451FF59B0909E6BF847E6B610DA89AFF98B3323E1385954EDF1175C0C1B158CB905BCFD9AE7FF9389ABB9FBC5194A45DEB0570C58F31D914F9941B0242717B243ABCF5A20676051978C16FFCAA8ED2EA23B8323CD58388860DD64FA39971F9FAB83A4B248EC8161D32565917B7E6EB4937B4743C6C236E75E1747A1C83377FD1D927D385D81A9EA7F4AE5034097A0A77E2D2EB1943D3128BC0134F2D600ABB929A5281C26EDE1C12CDC80F8EAF2E893091EA274EDA1A246AEA3263E43D6C60043CFF6282AAAC620A21B523783E0CBE33F78C89D00EF8920CD53C6EC0E83DD7E1303D9B6D5280BD2BBA26376C17099758F34C22054DA031C86CC50367C81C3059114A71C565B1702981D77040B0FEC1E89436ED1896E93BA202F11ED2BA4EF33A76F86AE8E23B8FD064C8FE894244C97BA7BDA6BB56B7517C236400F591E4F28050C2958A7A79964AF233CFF8655F1603F6A0C7ACCF440D0C82D5528876721434C163D86858B02C6F6A660F53B3E45185FC7777A629C3E4392AEE4A96D900B0F19783DCB6E5028B6E56E160A37D37FACD7C3B992773ABC8AE1ACD6AD41E7340CB198C9BBEA1CDC185AEEB51E2620F0695C2691A29CBCA8E23328E84B6882A59A8C3C2A273CDBD26965564F1F1DF0B2CAF83F30E782C049DBC00596BD85426EA90ED30ED8EAE8A88C0D1363E69868E8CAE56E8DD62CB36D9A15150FE567DF7DC93CE78706BA983885155C9AF05B5FF1D0EBFD9D020BAA9196D9C871236DBEE8A703BE458938D3C882719881BD49476386387DA3508780878271C0DA821BAA1E9719E437BEE6294D8E4E2483932D0257B44B8CCD8C55028B3B7D2BB3866216A7F52CAEBFA0FBAE120609F95213BC05AE24473C98C29F4A46D985336DF8305787A0374098DB279EF0E34E6DD79BDB106EEA24E4DEEAB6DF35C58AE73FEC926174E0942D242AF0D30825274FA1D510D1C0C41FFF59A4381CCE5C6B89AF30C41733EF42E76C9CD58DEA7E881706843BA04E3A170304C551B6C801CAF9B8DA52913D2DD4DC755E0BD7C723C4AA5B001D9855236401C1014507CCB84577749DB1AF29E318241D91C4B23BD80549CD1D6E0D793E966A8A7B755552F16D3A1146B0CC6D92C8C90E97D7EC8EEE7C365697F93AF257BE24691E41F2AD26BCF47D52A1B80F5BE1C658616537630088CB6E227B0EE6EB8DB2FEC0284E58202A73CF3AEC16BAEB59D2A6E0257F0ABDE5926D9A13D89A8B2F69695BA3682E87A77DE06FF54892F56581FB16991654F60EA22856D6FF9E0BE2C4837F0C1F6C54E840F67A75185F0DE9439AB1E37D4FB3E9757B0FBD17C89DF8568755567C390032DE93E9C93E6C89B2E66E9E9D96616919D9FB461F9F33"""), + TestUtils.hexDecode(""" +E2B72659B75C1F48D3ECCE4E6543C8C79DBA860CFFCBBEFB69AF338A4816ADBA6E6673112627712B5370954A29F9C896AF05012B290C6171DA9E894EA53A94F6C87D096F6DFDC0D77ED5BBD368E4F0CA642DCF6C89462C1E694F8B9C67F641CC2859EC7289A85FA82CC1984B5FE045DA7814CA6F693D144DA720D33F1619E74E9435DAEC3B4D64888CE2525FDB063FF6C4578A3C783B364C80CF09B10D2868DA846858E742E7F5E5845C49B4694E812C39D021CFBDEC8172A6F489C8D0A5D57241A8F676CBD02446725B6B2C0A51AEC4EE63339477F0D7B7DA74B7D343AC283B6BC38D79DE45FC28E20D4BAE6D7E9DB775E4801ACD3FA93E05818031BFD882905962BBAF1A6CB0543C68A6A1232E6BFC1B820C53DDB53CBD62A849FA24BF289589C860F32F35C42F0C04C24750A47307B07BC610E1B6D7BA61FA2DF526DD836A656FCE196A8FB708DAD7F85CCDFE288E2DF71F3BBF9C0CC6F48ECAAD507AEA35FFAEE1E7DBB53FA9617583EE72DEB3DBADA8208E19C584F034D75B50F0927DA9CF2793A1218298434C32726351A48428F94A19A7A286CD99141F97301024B6CB6823A199B3EC759ACC3A7CC20D43072A5E8112ABCDDA6A17C1D9DA1FEB4552B07575FCA4B697EB8165BD0DE2403AE19DE5CBD60FB21059010C3C4D2B0DCD918321DBD7F94D59E0B08825872083FF50847A3457ABB30C5C32E4DF9735553FECC558412A22D46A165AF38A07CE0E2E1F888A5DAA2F9D39870F008E38291208F7D2FE2D75BB4E5B6DBB16662A1DEFBE0C4145CF91BD2E66A670DA776993F60A4757CA5BA0C55BADBDB1C0BE86D290D3F00EE241243CBB9CDF5B3A93DAF95840C55320B931C6E3EC9389B117E7BBF23EB6192965AF97DFC89EA6D2580A9CA0C699A66E22FB7354F203FEFFDC4934251A8488A15C3491C3C6E5DAE8C828EE56D97723C83164AD15437B62F4B06133402A3F1A261D08F6091CC5C46C517DA95717FE632FCE49C659D93BE9417AD1507315915F1C48F20A66F5F08352C83E75775D27F76B1DD73961D50F289391FE376977817D12D7C9591FA2832AC84EB00A8286841812F8C120EBEF5FA71F79AC3CE6C77862D2121B4B21A33459566998CDFF4A0E614CD6CB72F5AA2643A3A61D8104CCFB041E94D433AC6D10352049B4C104005191284CC9B23942D90F3C53D05DF898394EEE9E041B735BBC85F20D454ADBC84D3769412F5E6B06303C503BF1C29E43F93AC993BCFC20250A38BD862E7348AEE4E693B1F99FAAD7B7E8D3F5AC1CF8A192D894AA3BDC356106F4C212954B25D86EDF4FE97ABA3030EB20A9DD48CAAB2955F830523745B0208EA35AE42AE06383F8CDAD8E66D5A988D95D1DCD310C9A6AC53DC448AA80B21B78C2CCF3E46B447EE9E9E0E090BB6DBC1AA4D5A6444283CCD5E01438CD92226A4FEFA67EBE63480AA072FAB17BFC0FB0E0901B5DADB7C29631B3E3022574889681478E02D5C81B7C676122A1E7AE441D16E090D5EE64A17033D0D0C6953324C5E476C652922FF1F1E47F833C3FB1705E5CAEC5B57AB93D192CDAF9CA712AC0BA70F36D71A37D366BD80A7BB3E382EA87EC5A1F6B281C01F8667C4100906D713B83DB6A50C8C527846EB728B173CEB9B6791845C7749AFFB6C72F362CF602D70452512C76DDE9D1E76988F3C6EB14B43EF02D1081E6FD446576CE727DE20F6B25214DAB404B4D77ED2DA703DFC0E4219D44CDE16F596025C9E90BC0B52649AE81E95990EAA115368A9C6B16F64099C8B928EA42168CFC544445847EC42FCFDE6095FFAECFEA31515FA4970B27649C81B49B4AEC86D1329EB1F5B5AD04851651BAE0236C267728F1B0B8939B0849D9CDA009535E066990C664F160F5B8387D93CCA6DC94C8AC8E5A161F0D4E71417F43775F7AAB83550BA7DF60AB7D58DA72205F6F52F98A5B73C6608EE34ED7758D15AE7360832F929B73E8041B35D4D428FFCA023781B26EB65C8D3A5394B8EDB1A23EF228850F32C19E8C8638F6E3E8D64BA7346AA7BE8356CD61C0648F19FF1E959951A2B92B635588FA51CFEDCE28FE0EFF9B00EE81675223A8EADE3476EDF74D688C57C68E78FE3557D97198D74648CB71FB218A056165590A03E4AE830E8DAE1FBDE2B65964A2A9DFDD75E7FEF4C11842DDD8DE5B7ED553940AD6C74EB10802F5607668192FA7138E385CA14C99DE873F48837FF593F5EAAC30FC7AEE7FD0CBAAE64447EFFBA244AA0DB2CF145030EA2CB6738D95DF990E8B6B981675ACF4C4CA0DA779BEF86116AEB5CA18010CCC8F971151C5B61E2C106C5DD38CB9F7122AC17222163EBEEF8FC9DB9FBFE8F9631996537DFB7B7080A466CE52EF5459315ADA3C8E8D748CE5BBC02D326D676247D8F6207AFCFF6B9877B4ED1082C283A27B8612EE26C9EC76415C14393ABF8FF2F8E54C62CD56AFAE745FA698EFAB0AE19C4F1BABBAB440B71DE8510B7B664A9B9F8F80C4DD125549C0546D4D42CC39022D1BB599BCE77D24B4AB8EB1392C7B0160C9BD376B3FCF822B3DB1DD6E61A3EA2C5369C7C1DDBE7238015196154B94201F935CDB203D8D82C29DB4846ECD7F99E8A8FAFA204C5C800D7A6D0E15791E197E86AF298116E2E4BBAA7365A51CE82AB819B2343B05DE001EAD2E0939F8D21CE2482F65686E5B1DB274DBD223E97F0D094CD4E69A198751CA2AEFA95C937EAF7A52245D560F9126EB4B9F5EE30A119584AABF46AF32D0507E1F7D78175A919CE7678B8A120E169D502B02D9802C02FAFBBD5437EBC4EC674E21DEFA246A471ED242326B523917DFE2E41C1D77AD867D64C09E711CECDCEA9028BA620FD799209A93BFCB7E36EEA2971F977E99326F2F54387752BD19EA29C90CA3C09D9A02740551EDA36D7687CEF24A6D35878B44235E8147D1B752C2BC56BDC86B41588522881E7A9E290B0B2D2B2EA2F56A3C770C7BC2C144F0CAC497C181B0823BC6BE8387FA22A448A9EA92BC4DF5F6CFC946705F20D4C1091CD96C67206DC804969225C0CB11A4A1B476EB557AFEE3AF5A18E763080E723A60359325053C16BADEE646244148DBED40C598A8DE738F5546CDE8ECF09FB14ECD37E7F9A5B622701D92147C32D324FF9525BFB30E85305D0A4EE82DE52BAD8AD6A5D66BECE7002C115B954DEF31F9DDC7E87AF4C37552CE4027606044AE792882750C8ADD98B6ACFBCA0C087ED65276884642FED7AA393B7ABB5C35EB7F3A4922D97EE16AFC0043A21495D1D1D269327F9DFA44195E205F6603234B067C20D09229772354041771CD1AFB30F11981B6027DA1B3A6F465300AC5C0E41FBDEF7D0DDB432DE67C814B76A7733C5A84637E56D7D620AB3B37EEB81DF16093B5612D784873F84E6AB6E28827625F1981AE31E3F78BC4F68F215F4145FFD9530DDA56FB1F67BFC6ACE5C647F0D3CCB2A8255449638A65E3F070FC200B7CEC52C370A86C02188B3F8BD809227F08021C1CFF8583DC561EC62CAF8C2CF878A25C8C62004E4803C15837F2A8FB76A2FF611CDB597B793363F9F1A02D2026E2A87FF4BAAD424D44B24BAAF7472E36ECCEB0AB87359AB317F880E5E112EAB060D8B1A6EAB5C135D5458E628F43F054C8CF2D19966319A9894135FFBDC0E5035A1D2B4418E466C8556DC71348A34082B07C6725B8963F97D2003BCC9E4208F4B28EBA007973C582E9FB315BA0AE288332B94495E2436CB94CB705C8763FFC696894CD2825ADF31FAEA196F6C23176FA6D2499944131F09F07A6F86B1518092B51DCCFF01969F669F5FF0F8E16FFFD044C2D2DCC0E76E7762C0A0109F7C9EEF834F1584220FAD95FB4CA00D649683D15454CE7E797B6F28F195878F5F42900EAE1C1B339489141D39EC56411AC205AF6B4E0D00A58AEA1B43BE74B5B5930ACC43BA774032E7E3868F4208C9420FD59D3CCE11AF933F964AF0A703F7D73A568C89AD1AA9297D82A606E94350C13819607711659F1972611AA5EDB0B061BE6E1C0FE17BED2D0A3AC80963DBA3A28F0ACFB9DF8852573B35EE8975364A9DBF85A32952488CE99CAFDAE4584ED43E00668E531C5CE7D69DB910CEC52DBAF374A73CA22CB194984F1BED01224372675B892A8FA7426BD2EABC723ABF439C15C1421357BB3296C5B4027A4E2873D5CDEB60176B299AA06A37A9E86B96C91EA0F4CE7A32D1A13F453526C38163291B7D1EB78A7C7509FD4AD09EE2B73EED7B48BD6B8864DFF71861165F7141DD3032EF27312753EEF75AA1CD075FA76756D54F1049B3FC7E2B6CCC5A40D8A77E38D1576CD95F9CC7CCF8083CBD348CA2C50DEEFF4D6BE391E49C8704AFFF70B0FD6C978B1688E000A254EDA045A682B27166645B17803AFE2E794545A7877909C584D3D8E58BB6B0BAE76B4700B9747AAF426266A65891516A276485EE9E0A570DA8AA36C5879B0E23C9D3B3165F46648ABFEBD65F1F82C6D8891D1FE47D51E777AAD299BFF8F5A636C30CFBBACDBE423FEA9D93250C6207121B0D7D2122C6D5E8F6877A6C05DDB2401E997FD18DFEA68993ECC9522E1D9FA0B2F4CA779B6B11EDD658A6AEC05CEADBE69CEC2792669F180558B235C295082EA9E20E65AF03638A50C000C657B8E919FD7E3F1F8265E99A2ACB9CDF93F4D72A615454F6D8EBBCC1D5D5E6CCD447579B2EF000000000000000000000000000000000A12161D2227""") + ), + new SigGenTestCase( + TestUtils.hexDecode(""" +C76D6626F120F0DC3DC1A840BFA94FFA317233CE5DA1323B24005FB7EE273AAB58D8935C11BA583F58DC10BF321EE6A9C86C1290EC27382858306C4DDC149661245F19CAC304C002479EBA3FBE8203B10F8EB866F84C4BA964C33BE17DEB9A3F70D0BEBB6D69931B7A5C8D7F4F453D4B7583D6648A2D9CCCF3BA555790EB3BD1367456382700517316272745263777343070578043772431812488504440335421634222648265848838121837353786020831856580712415333215302208147066378168632077260742828733501307547176277560372528436054511866171224212737853618516810286575524353052360560431827317050484274631523727443076623201205630176106647063024526654105775786876227221382811315183175187688715152251718801634644008352335346173270831466732388742751781744268285136885233676618075730644567376260056046801283118368127378730400864858860423178431432174024128156430042136886878305255512578456815567452271245453668030586055385062026711530033343383475108202713263083330656287828016636402607650813442327778368023726478448081481213123878572853738681808620411477010631062247480543800734826263723435866084563460834818022430110577037880375342662814256421633255877085434152814408536434148614146707002044162035858310133662324605536663662033473105060631775853077483602002225412581468165821865661211467268147103283132171232547477287443230241240757844153615762424741301722062267472747003826503885544682608118155735313865325848302455485634756018273820137345741727418745261488050677330138546833853508746107616788711375147727451830073522165114147383877083481400123163777662262788355285502510077451133068444362310516824714022346257785811584806148226560441060227752554564772478727583156451406704238688634583166663607688238257518812813555154445780176360300350404665741672685880004215010272888675646851148358423071453520360300388050250721351241676211305457044364015801141683044422561272606177463587455738363783408862388284722643833723114756406862376370330214001874826214622708084084002025636767831375160242480502832474732411157747428683178362313332364104274857216211278653233102730780172388640555127240368788380054832243460744682438112304407528808054840554628757808453602377264441116235321564084234171882453426885776378241812475187760357460162405285166613408735655768736813085162678146372876548208588416884845602213600238752455130070756438507443718730864058241676520223100778537466617861873171267335652236024385153037355153660707083178885813007345133271161552764051576616612614573437834476747524844652344312488386640172186252053064230424402062806207278026457241843213823223578630525753080343552186870662772512780561337726815780880748104546146704251635867710255085600275752004733518051655028507656643504277361001831655542464863821714055377458781574581878347750535822404730758788652635060486802627610003565431211741182688234752636126335334361107773262121051470658880873527267780287051622324420455244182713745723520882604160088777146578781102532430655862124224627601834385720032400151863686860466774444313130150443305816566373132477054681352205101436236160183731116027810540738716405756418031728372050026377227020873522458211520648153707830512024387354646073575114450322344315407165806830058732AE7BFDD687A48F0383438F5D34FA545227619047718BB592AAA4511C13CB8B554321352A460C2EFF5C24A42C8A397E0BFF652AF19AE7C99F1EACDA43AB86B4F77A6ADE00B473C7F268E999E76BF3B5355B2309CD95776C48D7E25EFE74BB83173C3B81BEBCB724E1315EEBE3D5DD2BCC834E74E411ABA98F9F0323AB583B41E42ACE6205B48BAD7CF266F639DD2C82208AF0EA64FF0C1EE76E13309140A42B755C21B8AEFB23C4FC79AED0B81DBB4031886982D1D9D218E6AA8C547D117B8B2C477318268AF238687527D4E30D7414E10922F58D7C71ABA68ADDC54F34DF14F7A405CAD7E407DC42113EC1B4161FFAC3CE571C1828B287D55A0FCAFC14C2CF1A0645DC8116B55E34BD9CA049CDB60C27D914D676D0869D33E0DDBDBEB7F31DDF7BEEB59AC7D6A62F7F42DCDAC5C0B20D1E7BB4DB4589E21089E541766C4BDCCCA807C3825AF0EE7AACC7390F7A8B689A825F9AAEC2F644E24920E95FBFB117866D67387C0A46A730423A80CEFAC3D164A3AF5EE17D84FF2E7B783D1AC74362D483EDB69EDDA4365CEC01271172A08BA2C88FE98D47F52684CD7351ABE2958AF5D3EF796AEA4A5B5EDFBC9BF3081E4DADB42BCEE2A6477B7C599BB40051532EC96D0FFA2930BCF1D6B077F619C4247FF89842BE8B3D72E62C0A1B6702ABCA1C1656F2BA66EF804207EE0DE06E1E4299198ECDA8E5A96A245EE9B717D5A79F5478AE5B5BCCF8B8D3629EBCA8258A2F00D88A12A34FD0B0AA5EAD5A74783617E9109C8596F605DF1038702966175AD2367B5B9B1AD40B4D49ADD943FFFC22717BB13AFEBB8CBEB3A7B769A5BBEE0891E03916507A0FF8297C4A91F73A9D03774BD41ECA62701B0A1D15A20CD5B4E9C156A004047A0D1E57F593E6C5C3DE54FFB17A60912AF5A5659339CF9D6969D3AD72EFFCC3160D8B4039DD6143D8C77F0EDB668E44991E2819FB01935BA4DFB5D48E1D8601C8D4D8A17F7A6007C92D95565369A88E1E1CCF781766CE012605607A7F75030E3829CA5F0774BA2F5F57C62FFB9A7522FC152F64C4862CC0C9E49A10B0013F19205E3DE1BFFB88CD76228B101180429B2CD679872E53C573BAACE27610F291FA2C021B0E5D1814A23ED34BD3190E3F6A2B6CCFFEF42EE2F0B5C669B6D23E7BC699D8E785A8436A852D6E8503C8165C27362F246BC26546D5CDEBD5E5C9C268ADA0A3ABAE1D7CD250BFC59CBA4B500D9118356AB49316D7C24AF1E1673E4970834132C5134F2F1B59C45ADD894935211F8026C714B0DD6B2C2DB08D3FFA5A347A3206BFA8D9F8F49A332912FA4DDA18B1301D004BBD6DFAB19DA9FB4F851E6622F99F62FD6008DAD1C03353B619646CC869A8396914D7B7D0065CC4A3539CCB833CCD62507DEAAE15A3A49D1ED997E53A86EBCF08C64FA9F724CDFA0F4D24DC8890F77793DC962BCC4EC48E1C2DB60C88CBB23E5E9D046AEF98341EBD2D30260CE8B318894C1E276EB7849FD777271B6471E716642DF70BDEAB121B03CBF901A171127E448F7E34C161D015BC661063156B702A5B08FE53A1899DC650C37ABB75F8BC4F0E2F03E84D6A7A2E882DE68BB78022F771EC6433D540912358E185AF67DBFC36713707B4DC0FDD6FD2EC615BEC33BE08C8C9E9E436BEB31FFF5EACA3F2661E64A0AB24D0D8B80271C5C658F5D224F98DA322FC68A21D3E547F0F4EC78566C172BE2683993EE8AE09920A412B04905D54AEDB5D92CB257E113AB3D4C4C1CD47DADDC09A00417D2E4A9923E5BD8EDAF73E4B89831ECDA7BF8299AA149383082CF1B0AE388063E115836AD8B1DFB9E6A1C9D254F02DB05D5099D6994EA253605DACC9A5AB52324324AB3B645CEC06C6F57514D2D03A4DB3474EF58EB37C86D27D2598DC58CFD2371A18D0D5EF241F1E5F5B100FEDC33B5677CED61B3DD091C5AA1252B1E681CBFC124CBBDBF5CAA841235296009AA08CD067EEFB12E403027DB735AC59231D6E1C068D180ACA2F3C8BC0D2ED552BC4F0AC5B5A401F52C7D66BA6D7E50EA96E66CFBFAE392840870720D14A4698E05E741605BFBE7EECD1B03657A10B180E253D23AA6750F1EAA6328F40A6864A30D2082C8CBB4AD86113C205CFCFBB93BB80108D63BF2CF7432EB1632D37441A92FB5953813CD740715C2D14EBB2B6D569CECD0AA2F3D4D681AF6EB9CCDFCA85E72A3B8DCAD00960154D350FAD1046F4A1C3893B0AD1B261BF669650C62A0EC134DA899B0136CABBCEFB31D9DF32D51B929148836200F9D51AE7EFCCB7C113B2DC8891F0593A464CC9906DCD18436366DEE53E87BE3153A241742FDF35EAEF168961400E150246DA42F8BF9804DEBFD51DEB5B4FE1681E44FFF181CE44D71A6204BFAD321B3ECFDDABC3DEE87D2C33C7AA2AD6B9C78E034A1E19F255400FC032AB7AFA02A002B9603EF7CA090117108183C49D5436FFBC7B471754915F5D9CC154FBAE4A9A9F0928A50C06020181DA8ADFCF371EF51903ACD6FD56EDFE624FEE35A63BDE5CBCA7DC3308176E599E3B95D7F137E9DE519B417661AF3DF7568FD76A1D34A8EB21038A23B9C62E5E46DA52DEC95EBF680CF8BE166CB674D65682BEE3FE368F082DC4F368738F83E2D333EA1DEE7B2A6F815403897F5AD6C1E710BD46EEFD5D743B79EDF135B0451A18FD60070278D852C302D0D026C2F2BEDE0EBB9D016F9B817D90914F1E3F875259B80D1DF60C28AC231155377D3A2341C4AC4A871857263B0C2DA6FAD157DB9F85CE3ABCD6F769F46249BAB9753339B2076C23549A68F5F29F8A74BA874DA2806D7E4EC1F61BCA6E11C2E15EA64E8728D9B9ED08246A31DF3087F8394A9D925551F4601AC957DA056FAD48919B10951E5CE56217B11C6DC89C25F2DD06095A820BF63E4B53CF80EA8C836062822A59BD726A19BE405854E232BC0D6DF7F9315793B89E9E10D00E9C48698328B170B9A7F95B2ED96CF0CE99E0D1F18D1C73E6545C8E9F717F722A07286025AC8DBD6C2567E21DB5968BB4D7F33A49079B2D4C3956508E58D812F687A7E4FF07065BA76846E70FB42733C56D948559E50CBAA00E1503D1EF447117994EB8FF0BCACA06F91FF312351632CD6755D0703A7E3B0DA03C37B98159078DC9B8F4CF17659B0773F0501E2BF177F882FD017FE74CF9C34A6F013D44C7D2986E9CD29D444B98E26584942747EAA79949EF3C6724A218DA9D820E68C62B64293EB1468E5CEF3A9BA007D5345EE1E5251E7075B84EE3B060B1E9AF2843AE46B4681753322D7906A6E849368EBE27A3C98F9BA0FC74D3CB472D511A78B50BACA9850C4E59620B35318B8978F697D79439E2E2A30BC41C67F41BFAFC6B9F8D8C2D8FFE8EBDC3910EAD15F01CD2B1A9571C02AE0FA9189A50CAF1D6864AF684FF0C9F05E0E8830A49BFA0872C92EA8F6D9445258EDB6FDCB437601B4EFA9CBE3AC1390995FE8BDC1D54073B16DF60018E904F2D23E029CEC4A4DE94A356CB99A44F2F314B9030683CA19AB7402701E8C4225BD284BA1166C3B181701F9A47B6C999D69AA5AB0"""), + TestUtils.hexDecode(""" +320D1B2976A4A4673900C7B75B23EDBC25B9AE867FBB79B55B29B3780EAE8C159A3AFAA47CF1D9E452CAA8EDDA3304BBAC47EFDCF96CE92DB1981A5088F731E1EDA1EA5FDE9A031595A8F268E92B4D75793C6F408F79B78599D93E80066F8C4432911828A87EF71C877F55B1F18207F01820C0153B647205CA93DDD6B78B94EB59E3EAF01B66953951ABA4027F811877B0F60C9A5AE6281D82348E3EB749C82C81D53309F9B7E624BB1BFC6382F43A58D1951F7FB716C08DEDE4A8028B50544D0F26F7B9DAEA0CD075C3B11B7315022A37198F0C96D752798E0EF406875CE86C367079841F717261A2B6570A8F4F9BE1EA305E73BC8BBD88AB162B4D4BAE86CCCD406A0FF6ED5A968D4C985460FD8FBA5B3FB40E29B6ACA07F70717A0700AD3A0BB7081E09F7219F3F8829692C3DF91C90334DF9E89284D65F7406188C9A1EB7B5C491591A20EDA9399DA1AE8C0C158588FE1426B763FE9D11223FF7A05A3DE036B67541C2811AA459045CE73096F89E6BA672CA7A546D2B0554DB35C547AD9585D14485AA812BFBC88F7B248E03F2EC57043F4DEFC2B27A3B20C2EE7CE334D428EAEB228350A3ABF4628C2DCFA84BC7435818F91CD67F70F3C7D54E2C205E55BC4ACCDACB354470FD5C246F32A542106EEE0EDB38F01FF5C4B657C7C1A00718D2BFD311B8BAB6523351E93CCB44274B8F96EE343830148F5C8594818777C1E798EFB45AF1D2A75D22470B4D7F7C7A5938DF3F8288A0088719C4E36018D9993F9E69B8469E5F2ACF1977D441B82E5340E5AD5B21B66051513553BA1BA1C1D5F788C47CD3BC60079300F6E3D9F13EDAD4DF8521EDD022031A3D74A6A5F32AC6FC51C67F920233C5079A2B44BA7B8EC6DCF9AD4667BD26BD07567E078267A1BF44B15E68B71AD38226EDDF138D2A599944F70D47B26F775BB97D9966845AB3E6AEB96E1414D3BDE94160B6DF19E03BA1BD0361354E5078B3C5733B740314E2DCCCF8F4C9CB179DA62D5C982B223CCEF5F29D7B673680DFA2823A2BB279EA45D98CD91BE7D52E3E386B98B62DF3FAEDF025B55F49EE6FB5E8DFC9F70A4F093EE3898B25102CF3AA52E669D6EC69BF6C79457BBBB7CECF65B1E948DA808025A242841FEC6073326BE16C2D1953209F31BA4A772FF24BC30376EB994398D4177FFFBCF78C9A79B7F1746D077AD146514A2DE0AF9800255F3A11BA661765A7D8E8E7FE5FA46BCD1269E278555186D4BDDD03FEEB70BDFF7E5F616259ACE39969CABE8D4F8F23544918516C977F84C09D6A6749B1CE719676378E82F9B4E563D67AF7D911233F2527B5CC5D0733360CE15A173F10B91360A3CFB08EB44A09157559A0CE8B661AB4A97803C52F156627C642CD02CA5BBC7648833F2CD7E99D2A7AFB736E5AFC4FAE5DE19ACD2F5CE3E3FC887852758411E8C7FBCADB1578964445332113F963AF3E944286DC448471125E55A46D2DE35E9C0F6DD10A3BE4F1E4BDDE51A16F4239A1F6A535D3202055990606C0065C542297D490553204A6E3CA16A7FC9A1D77191E5C01C1507A332C659FD6B11FAE088BBA796F18886195A2B8F5B0064D85F56FB7256F0FE70E9C06ED18B7C8A75ED97A1DF482908D2E3E8D6BE8D0EC8020451C687D10F829257F3D09FC47C7EF008B89E2312792A25EEDC71E9835674CA50235E0A6C832E7BBAB458725EE7BF65D26A0501C91835625C330B0F8B4D46A0762F7773D2415A0DCA573B47EB8658F9EBFD26D9F6EAE9D7A7304BC690F8D2F60C33F8A7D19B52F9340BFCB2FFDC92A7F9ABF85E3352E46ED7591F354A9E19B70A3B247E3E4295E45B6A2CEB59B120B6758654BAAFED2120B226FA778FAE5350E756741093083E4E56A84B64739695C1C09EE39DEEF11D7E5BB7866C90FC9C96CEA071FF82F145592443BBCD6B7CE848839B641C4522016945F711E86152820275A6E16BDF296D34AB38CFF06A63756DAFF7BF230F024DA00C4128F025F091F4341620E0EA883042BE731E82D21DBA6EE737D90346B6189697CBF41F7C2BA7C9CBA20E14D26CA578FB05E92798D57C0060951BDDCA5D96322AF35D80013B48A79AB7684E1E1B040315A350DCF84389E54C054AC4C3428123E01C2FD66FBB2C5BE2D16B22BAB805AB59DF205B71764E4AC9BD4B2D872B8905DA230623C65DD235FEC253468E53928722D1F04C486B46E63FE63441F11B1E3617E9765D4F388D4A2B68B6C86C8E20FE0F3C48A561A0FF5070455C43A7FDAEB58ACFD4BF51A1C37B7751ED37BBC73B9C29DC4FAFD0A8F5FC98C7FF02B404AC08A0728FA82A5ADA4EDC195E679D88187F58004844065F281A67FF0A2BE0AF94D5C97ACFD43683AC721045FEF8C36DEBA2E3EFA248DA65837046B62BD6CCEA84CB1211C5893B0C5F0A5922A989CF7ED093D5D706657AA6E79EF3FAD0959DF594B9CFBE779"""), + TestUtils.hexDecode(""" +84D8CFC8120CB598A6A1CED91FEAD8FFC224C59781A421E85F7A3309F74877B526A3A2576A41A17D71229A5864953B5591878A53BA64C10E88A4F77811D5641E03E445B7BC3AAD9526EC4ED3604A371D1170618F672520C76B18148D3895386C1B9ED1746E0977C32DA44425B4737668BAB427F516B4552F5F11EC62A824FFF1EE50F0F03E01E7412CDE699F8A135D9845C7F1C4D33B806527574920AF2381C4AFA8F7E0673D1D76F6D03BBB5C3BC027ADC84B7D34DFB4DAF2D9BAAA9AAD4D443B195F350DD83A96CA96DCFD2673AF4B3425FEF1928085FAFC728DAB0374CCB14FA411A5FA2F77308BD43D44DF732E0984F7076CCDF6C2C42D0876166CC47050983FEF8800160933B87733C0B766F013947382A3593DE93F604A9A5DDA9BA4EF09954EFC9A8E6C0D90454B7F5C79140206204091D82923054A5D7BC76BA2D8BB3B17A7BCD027209965E125CC8DA21C4EBDBB4E84C342735F4C15705261CD9055FB4FA98309B45C91B92DBE2872D6F95B83243F6F92533C8E52EDB05147AD030A7ED059A3D6E6645EACFFBE84387C88AF178EBBA7ACE86F8BED1F18C04B1DB3F81721CB005D92DAD11E3D03418D3319CFDC4FC31E41917D3B34B3ACC7DB8E4B1D77884F97AAE2D71B202623F95308609A890942936E0740F53A48D036CF3991047F98CAC74E8B753779AA1EC926CF23886E0F7088EC0F1FB6B0D3F8FE587BF56B00116E84FC8D50D663B542B096186CCDEE2C04CFEC253EB84CAA2CFCE5104B667EAA7ACC31FB1D91C16DABF1A5D60704F46AC26B2E6EE4F93817824714D472FDB8407B32622562757F2F845731F5525FDD975472829D1D98C47B8B2A74BA72756B807A0DF17F4095508D4944F4F5CA1447B056E952B0A49AC3FBEDEDB06967A27E452966A6EC426EBE72BCE9D73FEF60C2B7BE7427DA1890A56F2D88F744DCE406BBDFE360D7C08F71016D2A84607F655A862C0C9020550E1FB87C45B85FC1501EF062DBEC20A7256904F9D5309191536A8814E4DBCCA28C40F34897A49A98AFB645F3EF246E2CDF4DF43070E8E61377B6D70B146F955A4EFCC98BAEBC3F1C621810D796D7B1BA0E9A441E56DCCA92AF85CA2834AE49207ED3B36E10178A7DA4921AD35DCFE3C4FA522D138E015D2447A3DCD35A25772C3B1439C871745844E05D5A266AC1C7253935FC43B6EE1DA7988C0D1BCB775ACCD20DACF4CBAA0671171337BB71E7D95A625F1BB66E3298BD5B8130BACE336B34C3756F62A0932FACA9AC3BAECE59D77D79F85AC4582E527D3AD47D230B1AF26833EDF2968DE208553B3167D7185CF60B4B4C08A0587496B56D9133BBF3513C20EB29A334290C46FB8C4461E81DCAA82D2413F8522DD889A4189306AE720736C875EB797E794839DE3619DCB6AD8A548CE43EF71AA16559350CDDE6218D044A059A8BB4D9826503539306469BE45FDAF3917B0A3A6450DD11BE8EF9F59DB8BFF8A337155A63CD20910EF598B208C14A2774D2FC55301F9CD3C8FB73DC5C1D30CB072D7E098B92D6ACE1BA78B3A10168CA4E8C1D44D95052AB5C1A7439A99D98C50A924ECEEECABD1437E4DEA5E7BB83AA5A3FDE2C98E019749EE0AFCA2681EC2C799C69F581859B28D2D346EF2FB97102A69F030B6F53F21FD655EC0F5CB34B3D363586148C443167C6CA47DE98835DBA80A092B9410B26BD023DA9E053981898215FFA735599AD0DEE853D374D6BCF0A0171FA56459C4536A7D2FF8DE6EA0C362C157D594101F9A860B800E5307DA8411E0E1468BF025092CBD1C607D9780CA3DCF070F5D949BFDE60E0BCF8267AFB9E04D5C2CC339CDCB1876C818CFE60F89F78681A8E82D36F26FE6260AE1A9E74355C0049C84C39A0333C01E77D1AE8E87F6BC96B0EF90B825188F784859F5390989C212E5CC5B829FA184E5BCA76B0B402195F4EC532931C788416811A029F492CF5B2D633F06ACD8104155D947E88AC08CAE86DF2F64F79E3AF8C82B9FF3834875DF69F1D381971003E0771F64FB343FFAE807C9C0D4A0273EFC11AF203EADE2D9F2682C918E2662EF2D6AE1B6E8A397B3FB62130BD629E315C59D1F0EADCA1BAC8CB6F067F10F6B13D70F70C3881E8382F20026746C6175F14A2331FAD83ABF256734FF7A970495B1F6B5B1CB2505B621D406B944BB5CDCE22BD9E88FBFD41F8B49C794B0022A456493D411B1B8F59D6A52E7B9CA786814F215C39F0A4D53285FA10097C151293054632C326E210110CE3CD03B7432CE2B1133FDEAC806CAEFB45A37CFC12F98AD0BF76ACE2C347ABA12A77D5DFDF6658C2228304FCD265653894C6696AB17E8103A8E23C397DB684BF632FAFEBE420B3EC111C08BE7DF73A7F763A82F01B120D326A98E92EE34144CB6C7ED15472F2C860D25A6739D925734C2CB6EE02198E96DA851860489A5F9C056C5AA2B5A90D31E7E115F32EB8285339D96124D3830F60E2E91715BA1C12856C1E25B8C59AFBE7B446F43F1B4154F8F786935E5402DC55E7BCAAE8ABADE43435DBD01F78BB882418BE11FF1893D54B5A83D6220F4E86D7CAF49E1B2EDFD6CEB82DCAD8A982BACD2DB15A66E7D0FB4652A920C339DA25B19D37715ECCF886D900D785E5E77E9AF53589DC5E785B2D5279AAE870F86E4701125FC316EFEC0D5CBC411D5ADAC374124521469ECD10832AA4257E2D8906358BF2788654DEB5D9E70798571B965376250C33706E78441465CC2563A9D2F70DA579FF7C4C715296F72562DFD9951120AEBD94D4F08212647F08B4871B6C4E31CB869A8CE1301DF60F88A517356E56189D61ED484C32718A9D37B6BD1FAB1FA39AA1147735BABEFD166712AAA617516D8CE2A984D90C73565ABF5DB9A46346FBE7AC465C81934F5D92735D30594C71AE239B2FF5C2DB72920E7A59B487DB9E363C594E34D9F250D7FA3E8DF4F8A07FEABF07D7BE68D6E03333B6947B1EC087F16C1DE3B0C5596043D4DD62770605DD89F11360A10F2320170084EFE8DA7E10E128D0E90D25623324F8B32839A96690CB33F6FF05E584C860251AA02CE00825B9F775F24E75AA788F98FA5BB7400E31362534EF1E8D310FDC0272F4E84C820E799007AA5351717BE6B06711BF9DED0CC7F96A0AFF9DC4BAF7F1F2D19BED2F24A7DD8DD1A171649F19B134C0F27CC458AEB79274DC155A9E3A267E200EBD328C16AC4892EEDC748BF522C0964E003793C0A6283528CD09456476677FB152B6DD0EBD86A410231191D86A0C4C19027F79F4615C665A75E7350CBA43D5A43A609F9C4155B7D2991250A6AA4912532B2081AE7ED0E72CA8982A5E16FAF25D622E060FF7C7639A1401B39BBADDEF2D1BC3E600ADE38A5540015C6D99769175DA7948C1636FF28B8D739E65B0E3DD43D5F25853309CF5DA4722DB29184EDC0294BB966D023093BBB10FE6A9A17F8A37608FD3FEB1878C02068BFE295FB809DBA10046D57C50D1A5515A3F4099F98F8262DA6DA7E64C0A2B662DE9F58C7F0CBF6B95AFBF75708F3B70A73A7D30EEC7B2C897ED420275B1D3DA2B0D94D689E21166E3B42B942DA7566966C9C78BFA7C64A7D0CC3CE47213B2C1D3D0E75EE00AB186CEBF88BE2C1C042253F48E2642DF054EBECCD82A02DACF3CA849335AE09789A705D23C1B49ABA88BB60ECC05F70BF02B067470802447159456D4DBC7451E41D034306F3A40AA9280C63DC86D5ABE401B64B48293B49C3A4119A966F652CD00B32342CF603A3D02E8F829E97ABA53B035C3C72D2EAF8F9DBFBB83D61B5E13F721C719B3D6E963E68CD0A6FB792DEABFD08ED01ED50A407B4C3EA558BAD59A9EB0CF8D5501A75A11053DE46D2899323B2AEF99A6308D64ACDD681A256DEF931C7E5F488D8878950F0637D478BD665B9C8AD85816E3B8F9C586034E1DD2381BB2F8130CCAABEC2F43D455F5150F83F160F9E43DDD4247424ED273F31F07EA12099B0E5FC35998A6811C8CD1825F8A1687AF77836165DE0BA2438275DE291B65C90DA0CD5880F95C8C8CC0F256FD0B1A9F9209C659A031AACC5D0FE8B0DF5A4E9D9EFEF76ED7624E9ABD6361F0772ABE1CBD5F78FE6F872CE769A817F4F3195E65CCBC3FB2F9BA021023585EB4F43F471EF4307AF047142D79BDADC744EEAB4CFCF8FDC682462985F828A5CB69483076EF94D6C6634000BAC9B75529594261E3893F832DA297FA448EEB8D098166732671773CE215F777ED8B16C6511D47216BA200CB3082540D6323F9726BC4CBDC1A89D9698A49EFFC5B3928461746597F24991A5212547888DF1AA6F6BE3D1AB887190F3EECC6DC4E9B0B4E4672CED38B5DDBD3C00DF9461FD62637B3D7FCD361C41EEC7641024382C378F15BA8A14C1BE3E47C4301624C354EF8D10CD26E354385B7C477F355FFB8998E9AB2E2C0C2FB2E3E466A1971ADD49B31C6A6F1E9C0ED9348A337D995A08C65C1E58C950558A4139D3274872FEDACBBBF77B4EE9D2C54F9A6142AC8A2058C2EAD0606BB37A6B141CFD97C9780DDA16D54A5ECD9EAFC53576A00CCF909F3484B64E37AD1F63334F39B94EF033B647B68E1FBF3A0BFED69FD8877FC22C048D4C15A8282FC2B602D3B1021CA6B9A7E844B065C62B0CBD7FE328F9FB5DC23BCF50A11558290A8B5C1F642586C7A859194A0A7C2FDFE0F4352555C60637A86A6B1D800000000000000070C0F182430""") + ), + new SigGenTestCase( + TestUtils.hexDecode(""" +05F78DFB8DD95ECCB19A4E223909896CC6A32086977EF3ED299269E51878BE84D29086725EBC30BAACD7C10F04AC9B3037B7407C63D36864E577A8FFBE89D9174A2ACC4183D106E7F478109F5ECC2160C0583253D7287E39F2BE1E1FF6DBC0127A322CA8E2BD20BA4419405CD8950831BAE2E4F854DCE2828025369A1FB3F07E77878741641453852638027541273502161744187110423466885282676035866631880680212377455761475822537381311428256306028053075841275812862151082114225553333632208035118820600216464008332253350051356421018671288648082042327826524064231463461787457445340458144872151441075521254341210228484201564136088803605035560122810660262424606074018703052055371555875382226471026530180032600112827753232300073074181386480534164225448647716638448527736082708564276203618062484286666008357240756656266712700838805173838263510506272540177577752234807311255185168734122463815356405123855254518275503443802574060346470206813526234734131654288881363708638820352751020216175724418860014818114623484543247618186431467841145500584206376100245427354377078068051005766127458621211151260165633001348137530712602370312371232020175626206103837672301778747622163741706566121434014071278363537881306583436007681866270754208381518840617617808075330388482526180736260681245127862565373032388826478887465858427858051220613172202211345601088467637001415045874412557332067277484377551504066843600063121066341371643283786784761068601064575354243720165161606071462467454388636873636233778021648671534367133507427605374074416722337133601751734478484212371667138687221813155227282016661347012087060844717657163652206587018728132833730304737025362757761315052144646422630627111723456313173844406042412780701303413724368817117576255854668574228750452553070204351788025621430144242371001323737372064343217801782040275037004610781844438384742255584167536370662184616027251211143638677564508151383860530708048252122840866600333828445206788217648545821445206684478670700853248527254603327501006210154518503008755220176074648684464420077608424316613061505360032376774670110586687775170411382701487278646233746321110574082140788743715263036142246810378474651821327267878687767558532332766770770556676145510857677602768584841218228625328357130763700187376638323351202458842267224561707545685515711742787471041306204421583620103716561184185104727138066730485156405743817162476012062163020146660802807525251031404783027088628746507335166655450455814243664167181412115564530746315868643783184442146216216845873256853767015455878677678280687482518218081546136488640838635431565180552472320787367186616811775854673275284425445068256835580334212418571666556783641407770327517431140237301214478304666154718470055040784840142143820856651337364886780162504570540561687240205801871073843068104004486611083157177770070276412274284501525030180108545680011733761885871352405735268564864488888408546532680830132441854774703851551130551311212088487888340480334438028463403314317118862855268314010187431362037387131230675578024177157366237440614241826465088416751852758868580542326571477612173575680005143247771436458011248538443205703184858134812623530080474087351382103253482864316815ED9377443018FCEB94C82DAFD2C91A64AA5FA118DFEF2C915FB5C1C06E09A9915755FDE25B00C2D6A8382A8F9BD031F4F9CB0CD25CC035F5D38EDFF23E27941C7F38A6E958A5D7569D234DBD2A94B296446F553CA82466AE1F49CE4863D68462FE22DD7CA41E3B5223878FA372DAB34237763BCC0B9BEAED3FD27AF301D4BF779178571DDC3EFCA493D98DC24DFE77536701B08DBB76E3759B237EA3A0F9496E8C7587288EF7192DEC95A60FC480B9E1F533592962DA075833478222BE8B378E63506364B78ACE0D27A5017D15D58C018EC843375A5B07887FD25E1C30C0075F944A9762E59C94359728B04C38E9997448263150BA6E69FE461EC1AEB5FA47AEAD3AE1848CA696060462D29F331C02F80D22D8E3BA79E63924D2D4D3BD901BD79076852FC0B02FBF48BE9F772FC3332BA583228E55EBE8EDA94884CCDF80D17654E27FECDD237C0EE61E8DD35B1CCE3C388DE759B1FB7C3D143A153DBC41D2FD2E9D0F754273C21C19F5F13A63A7DFC479FD64D5F5FD008DEF079292629032111D2B16AD8D61566A73DCF219397939669A3B219F648DF45D541E47FA70833A785045B71A606DD4DE82902DB7C1899D44FE0D2413F886374FD1C19EAC8132F37A3AD31F8BC6F9582D58A494DEE3372DBE3C32E10B18B787D8E4D3B6E9679EC94CA86BFC2B23B9B4F92C1BADB21D5E5A58A9ED0FAAC419B51C1993983B5A7F6694FBFD5F1AF15A10057C6AC46E7034072A1A5D26D63B67ADBD3771B7E78DE3BFB9F6D5CE594B285991BA243BA22B3B54453E6F5413A2CA1D9AE75FC1FEF7E31A7A3B7CB087CBCF3F08FC9C34B1670E7F6D5C32F165D3796D1C369E7C50E9A122C116A8279997B0578625912829142D95C43DEA2165E0D3F9313592C8982FC1E107052DE326109433DCFC45A1BF14846D1F8F146D154CD5AAF417449788DD7E6D470E7C70C7DF7D8A1B62A503B1D4188AAA5C32BEA44C9D849D3F8B5C91D1BF97F47D83DC0D063639F79B9F08DB24A13A06C1ECDBCF73CDAF7510CABA36B890BBF7DC241AFAF317C24026A6F6CDC8426D99C0F90A2F1944B797DD68B792AF00B15D0C78F8528F0E055FF01E73E455BD5162389E0FF178312AF5DABCBFCB28AA2C0091862A010484C0930E7D9B6D703399D40B4D83C996E4CC415525CC895EB460EADBEAA104D6251FADABAD74DCE9FBBEC08F9D0899BECB3D6FCD573FA9FB94D9D18C59C724F39F0157AD6C8C01449DD56F37110F68BCDE8C3F66CAAE7968A2FEF4B0B20A7CF41AD9D40266EAEAA0C21951ADB946B78A3ADF6E81AF6DA0ED92749B119936AC4C7B798DFAE058A5F509D90ECC08EDDC2ED7234D3BF28ACBC7235AA971E4A3744AC9D47221EF2730A18A5411C85B6AC8DFB2396AE770A5D1D960D7EDD4CA6D0F9FFF6AB257B22FD5DBB3835D05D060369F01C65E58E2C143AA4FAAA554928531B9BE2D0E2B6D9F0D32AD9C9A12DF38F72A21D2906AB17AA5934F08EF87B42E40E46DC1C35DCE85B0501F256DC439C2B3A332E37F3A4E400304A6ADDB09153A7FF7EB8760AF870C252EB258EB658512BD8EF92A89FCBB50CF6F76BEBC46C97AC9DDBAA7450CAB49B4190A8B39767F36597F89027EB3C09DDCFAFDAB286863890EF528EDD073AEABD6A7C9C3D04EBD1A3CA3197249E7DADC74CE737CA5CB5A3C010FDE6267AE82BF9B8AC6210EBDB68BC5597E10D98F6B5DEA2777512710C58694785F544E4D886CD8CBC8E6875BB61DA19BC7FCCD76547C4ED44A935FEDCA88155AC0E428EE506B1BDAB6F00063EC1EB0D3D91B6D9EDFB85E8F90C42D9B058EE1FE208A54A5A14E4983E9C06A7F549647EB8EEE92B3C9A0B54912DA9185C7AC272C2DD4615C07140772CCA6CC3044FC59F7271259491BC9469BC1DD07868D6463740387DFA7D2ADD1346D6BDA59435B84F6AFEB3BEF20B007F8CBAB2DF46BD171362B7F7AD541A645EE4E62A520324617DD097622EADD7DA6939812673AB6D8E5A25FCF00EDB519ED4877B13EB0E57E9AEFC8B63F22C0816E70CBCE0383D689706FDB45EFB6474A7F194D6603B745F4D85577F79387733EB0975D783D7DD3864BC89111E1273D6CF9122B43EDF7F6757E2CBCB6C8AA3C9923E3E6870F9FA92AC02DB2B52491A1EDABC9600CDD515C665DC88889762A2012332035055C896145EA883A5D4EC485BB24B1F659804B8F10FAFB1B4C619742EF4BC5EB665C48BE5F5C5093ABF4E9E6E43D8E4D7E15F7D38DA74B567E4017FDF540BCB9492CD35C2A3ACE4CE579282837A8B55ADA428C1D190BC77764A4E44369BF90F24CA2CF566F7394978F28E24689323FB8C5B2D688578A9E5A34305D0EFB970490CB172D6FE786F5565CE921D92A2573C302DC9CD0431F8ACC8E0F1A44B586257080347F933387385429199F4A53851076447C6D2114CAFDFDD13C92D8C300F26CFEBAE984D7A021E9B462D30D19618AA72C58FAFA0FF74CA67699992B502BA0EDA7C6CD2FECCE6B51D6C704308ADB4B86F2ADF28FC43F03807C5B7391B3163FDB66C6EB76A78799682BE26C536059BC179E8F89D87469A57899C1E18E03F16DD6B5AEF7420990DF22CF4D3E905E1B5B1027DAF56DBAC8E9E3A54BAFB28A8FA5A51CCCC0872AB53884563C0B7876F68A48F1F51B1AA350C93A23FAE59B6BE2F8088F58FB9FDD432C10FEB6C79F9422F0AC6DA4F8288A23D16546715EB6104CB0499E5FEB2225C97287C19BEF3279B3871D6AD522B30DD96BDFE4BACD75CB108BD622605FBC0BC6F2212D76D8B50E22F98E34B6C53F53AD9E48F11FCB77769537756D20BFFD1D775B42625E6E7C4EF65D7FB3EC718B5FC0094273B29487759E8010FC317CB0F9AF34836426A4BD2B79A3F48E0F38447D96DF0FCC545FB51DDD3C6B849FF33BE3F9A9EBDEE04B422B6E032E134B7772C6D3D4430C67BB2B1B0FED7C801F5A58F23E08E1735DB1AB32D66A66A7F60E2F98B811950CEAEF309D6A2476105E165A673A4F9F49A94FF751DDCAF839D58CA66A78FB5BBBDD80C5B87A6817D329E5747EB580A7B1670B3B7F52CB5FCD6AB51D48E7F0D91434F6ECD742DB8286C2134713E6FD638891DAFAE78DFB0550E76A8A54DBB1AD4434786084BF17BABE7711BC40943A6BE4D6F9886802A078B00937170AE765CB3F5F71BB792FE3F0DE18085C3F402079F491B14CF2DF6AAA588DDA39B69A5DD267C95465350B261064AAB109D1D8781B399F0E0885BF2C646452D54504BBF5D5322C6F4A3C25F4AD945EBF079CB58A84B9309C32EB6FC35E92F526179DAAAB3526382B8F02EE2AB9D102AEC8F250348228437DBDECBAC81776D4F4A0CB88E1F19CF6A10F48F72BACE1D21BB213014280B788D4760D8FA471F9C35A2509D3BD86C1F0E3E92A74417BBF01D1455B64DC6ACB49001442C55D1105874773ACEB0AC4839BFDB021E1B653BE09EED14DCB9216BE75F0E2B8E9BB3D2804864BB92A618926D568DE28952354A7CED0384A9D21203A68111929E0B0F34191162D722A01F8B55DEC3F9DDC9D0DFB3E"""), + TestUtils.hexDecode(""" +C9ED9B897C34D7119115A0758332FE70D4A9E11FFB2D6A800AAE33F85FAC59E715AAD93BD79DC8D958079F3B5C2422F8FD1A1AF9406E8DA3297226440E30183051FC9AA52AFB8BEEA2228E88D193F231F2422977DDABE4AF4F0437628C6AFBE68F70CF4F56153A2691F7A4241EDCA760D4B3AE0A17A8A0214BF1BA65221DE64647AC6578F4C7E4A14C401F7DCC30A10A695A7F72B04393F4E9C4163AB68667B1757154BFE711BB54255F4DAA9D8AE6622C71EC8ACE5BB79C6B4C8AAF1B0A0099EBBD07B292CD7B55E44ECD68DFFF4173743145B71F536E7D23E78C63679FA2F3C72CAADEFD5A9471280CDD3DD8DB83F8AFF14FBEFDC8C5969B050D263EA462C28CA64362F7F165C3EF427FE5E90A83310DCB07C9612E9A0B8EA1D0631D84B4A7F1C7485B0C91C3B7BBB0EC98D353376B692BAAF24C5389D50250F3BBA82173DCDB52382176EC5CB8BD531DEA049C5B815D788491608FFA2AE8BF486849810AD89BF0352ED595E4EDBC0B81467D72944AB83C3CB2F90FCD10810EB65BDA18C43F9A9A5D98E714BE992B7DA02E9F7C389F1A22810DC0A473F8891C43932E0F6B5D3A21C3B611AF6C394AFC576C07572DC4A1E56B4576FE615E516F48544D099683EAA886CD41DA848567F70C2103C467D271919CC5935605C0EF05909635D431571E5A316E299E553EAAFE9C7CBF5063E2057D297F60B5DE1C17AF6B97192E840474CB7266A76D509A10FC7A71721D705A9DAAC5BAD8A52290C1D8DC7938663B24700F992FAB008CCB3801258245A0F5F329A4FE5553F4130DFB1D673338889B357FBF11681099FE9BFF18AEEBB31DAD290C1401D49CBBE38277AAC8A99C8BE4E6EDD8A0F3C901082A789A1037768AB7C3C704BF1C6E890D20B3DB6918C477350F4F25756BE1742DCB31705EA9DC975DE0C38C21D29B340C63438268F6CC399BD644EDCED36A7B50E8D65A507BEC51A31BD136525F4E7AFC1EF9E0E6325D032682EB4AFB7FB22F1716EC6F4C9852054429B5C5FAF3BC86213F6D800281913D5722F3A380307B59E1CC290EE66FB9699FFC627770B52619256C7B76D993FB4024D2DF0602F102A6A1257A200DE1F39DB54614FEC2B60F3728F59482D71C7E5BEC36F0D90D6FB0B4FA252E7FEC4F0FB9EF539257EFE87715ABEC75B2A5FCCBCFA5666F1C9BE2F0489E04E63ACBBB239EA8397FA2EC24C25C538BBBFEB74EB8E15FF93B0FEDB7F36FF67F7CB244CAA067EB2C005EDD2AC9E0765DD38E51E7C71AB72B056B230ECAA8985DCDB50439BA261A0DE57E68700C64655E1EB8608BCCC33480ECFFF1BB75D0AB69CEEA8F2E3E9515331A1EAAFB9BA32AF62798DF761267475DE343CFCF5A352C907A0314365B8CF6FD2E72F2142018C4BBCE4CF0A160266DE320EBBA359344A60D32CB135F5FF943173A3F9C7F4A68489E78621401425E5B8E6273309FA3313DCBF13D7C69B63C1EE34D3200BBB4CF57518A5E66D010984AAF34CA9B7DDC914A3AFB514FA1B9D3FCDF3324998D0D9058FEF10C30ED6B381C41DE363CB31C5107E7C00D4C0CCE485DBB4CD2092CD929E5717DB8CEE4790A48475E1DE9178E49B13C5173B6F301D5B7BFF1A9F8B3807A5FC84DCAFCCD8D585B77014EE285074E64448589A738F1323C7A865C3DD482499640A3F166F38E37C6F9ABA8263E4F3D1C2E7D7AFD16BB02B9B4BE8A055452071F278C32C3247DE2BF83A0633BABE7FA048BB18FDBA27022736615"""), + TestUtils.hexDecode(""" +2BF99640D1E8D1E76A3CFDE44072BB410AF19920F9FCA9F4EDCC534073063A5D196360CA825E70EF3574000607834DF6770604757CF5FB2E9F677530030988AE35E32C2AABA32FAB3E38B990CC1EDDE319E77E78A554161EF485FEFA16506826AFF3BBE5AF4A248A1ED0BE5049317E8148AD899E970A55191B2F31BEB20D0DFFFD774A5404026E95A04874429B59FE1FE29453AD21790F1F520657D657D175B8E4B8C497D2D271D904DAB7B93EE744B745BB50D310645FEBE6BA084686263F92A6550295822E84C3771010B4034602DAFE05447A858FB68A8B3F17B4539FE2A7839C7F2218888BB8FB8DFC54AAB71CC165B335C2F266984B1F402AC09F963016DCDF2FAB74E77D24B31CF35A36E2003228C0EDCD4E0639049C168E9A06D5646657D0580297C60F2F05318D039698482AE9F34501719251F82FE375D237D964221CD95CFADD4A3724A0C23DD3E860ACFC0637BA76159727F58E0220F31008E789E699C93593F2DBBEC88634AB2474B644699F90F56785F04044ED6FEBDFA8910A286919FE4A7B5AB253D578099152031E4EFC75094DCBDABCA8072443756B536E87B87114B354E4BA4452F540A9B197FAFA7C054085340F6358DFFE0FE4FA4C9ADDACF68C619A672E841117D1728EDEF147E797A9B3DEBD9D4469C71CBB684D134B18EF7ACBF66D52D2AB45CA47C7A1F7861E3EB59FE4CDA18A29C7C635E20CF68CF8C869A372866494C34F703E85B9F367E44D4AE42277BD8BF805DE61D988C848D6049DFF914B2CDCE4BA147127A9DEF6DD79BFEDAAC5AD4653C14D086A7CA154CED8860D12ECF86F351E558CB7C6542017E233005C1A7AF959D7E83CA03F3A07F1B9B7DCFE30D66D81B8D5C36C6BEB651D5A36E9330D2D585E36547F88A32241CF28014CC96A3E234ACDBA99ABB541FD370BFA65591EACE4D268D3EC17D86F4A37A359FB95CEC77A8BD4DEF36D23A46AA72906759A8F46D78CAC6D160F277E4C9E82F7BC3B48558E1607747D7BFBC8DE7E50BE365E62D003246F429E67340D1949C950957D7EEA52096B584192D935AB88E00F8AD54B0E1D7EABFACBE81E2C1282E9F5685F37A54EA44596516D9F5CC24AF26C88C91047E70A53CAB06A33D71B6E058ACF6FD7BB045FBA386F0E07BAC67A3EB256528680E4A0A31F91957FCE294C7EA84E7492CF8D265962164325A6536DC8AB542DED323FD2049930AFF783C466AFE9FE811716F6FE75ED28CAE3D768E7F73EE9C09547C40C3287ED5584AAB2BF801A3DA15CDB3D02A7267B131D22E6F1CCD23FBAD9D2446AB8B303E3B89D7331E8127E3BD909A6FFEDA8512057B86120D02F0AB0D8663AFF465451A4C8E29D8AAD0BEAF00B51C96C09A0568AFC3EB9C4FDB78E372669FDD78A296C6919602E4C9F60513E09F1F5D2BDC6D73AD9E48FB2A5DB13D6E935AE49DCFD455F017A41A0E70095A55DC012F15E94E438C266B081D25EA275FE2EDF7ED894779004063921AB3E84E44CD2638CF2EECA02BAB9978ECBD62D153FC4390A6F2117115508F355349603BF1DB25096D00C4E4B4296632F78C655BA6ABFFAA7B72292A1F71010D6743242E553D6326BB361364B44794164019ED114876FE166F331400EDBC665EA23AF4A178765731206A9F63950B3EB5B89922A565DFA8A23E47ACF14DA53D2AFAC6F5AA9FAA3DBE216E9AD2C07A32CC2A690B2CF1DE943000E87EB95D906C9E52FC103574C5C50548BD9EB8DEA4A0CD0BC3153A2193E30CB6385756FB0224F6392AB526CA21326B065C0C9C74F5203AC313B25F584491ED20C32F40A896F99088D07916D4F84396B67EEE7182B3600E418D353487083F58AEDEBAD6B9C73042748D2F3DF695A579611A41F4865329EE8E807F184ED2528AD1503A61B13D4EBF24D7A5371ABA6A053A4DDC63B0FE95462FAD2A62B9A23D50676D6F1B172F0E59DC0B77EA7C45E31CD89CB8B8BFB6AD07017B5E76D6798E08764B5BD293B27B48A392B382554EC877783099148E4C81401665AE7DAE8CB36716C56D0047BFCC5F57F5C6162ABF8700BB394CAC55D33E50FF43D20D2A1C27A1499ED068E40ABBF855213BCBABC2BBC71A3C7F8D11AED8CAB07C0BB8E5F10C5E46E726A353559265A0E511389C05760B4A6815EC4FD407486AEA685B37015BDB6E8DBEBA29636FD23DEF0BEAD64F38668244C56CD37517D586E08159F518512BA72CD86684768A42EDE0241C0EC6D286CF3DC133A64DFDB52E1E6C59743DA59FFBC28BF3C989A0B49248110871832DC53280A250D8C7704CF6D0A965BF74EB1E7610EF67C514C963DF6ADD4932CD7B6809F725FC65F32E5A8B7341C4587DB20A79F4BE0F42035B76FC1A7F8132A5C5D0CBBEA2E98006CC2847D11DEC848CEFEF19C29B45117859371166EFDFD9B1202BAF4183CCA16C2BCEDC391A01973B63AFE3389EB1E2520FA9C88063D038E9EC6F2A9429EAD33A559C79496A3DBC52E2CCF27DA58AD1A840207E7762A1F10F5ABF5F158B05FACA08CF40630E36E4044B69299835CB1EAB4DB06F33EEA1E1EE9692D427A04947FD1BA3D9A24C0C1ECC9CF203B25C11BC196AA12CAE8F8E1E2D37BD51002024F51BBB136EA9324B80B02A1D43B188A8334FAC96FE409CE4D056885D0AD5922F065772B895ABF623DFB4B0D956F68E65ADC37F34A10A1CCDA07A2603991F29598FD24D2C409FC1A3086892CD3EC9B22D7F01086BBBB12497A1B3EFE60E88F6E26FB4E2DE03B9FCC1856CB46B8D6617C8F6BB67993402A6AA24E9CC42A0E102BB46BF5D33F84A13355087B9B8B080FB8E82153ED8587F56A08226628178BEF5C7F139024B95D2854D8F37DE6068B4A717F4A8DB54E2CA731603E3AD6FFDE96E21A60A66B5F9F5F9B024116A999960D2893CF7CB3DF2781296E6B9D30FEB57842EDE5AFE2441AA32C8DFA2D3FA7BB1A3B0557AFA82B0D0ED8E088D587E4CC1CB6AB6C2FCD2826387FC289EF4E4B3D884A9D5DD354EC742D52962797AC5928A7419947699B10A46B69BE370AD481B2DCAD7ED5AECE4A7CF04032AC1445F6C867794ADA0FEF34E18FE0503A89619DA244E7FD4AEC38448147B49B8A312D3A6858BFC3AB91CE61ADD9456F4E231A55D0C134ACE6D43E142A40E0DD75D31C6EBEA609D2CEE42BF221B6B83176CB79AE6BF46181893DDF1527DBA791723752A78949E8767A194F6FA64C386D0B00F7EC3E22F2E059A37569B4B95ABE43A911D1AEBA678D9A15AB025B0171D48F17BDDC8501A04F907B9E6FD8DA942C728BF87A3EBCF82564ED11796E25FB861080A010DD2F0EE1CF8A7146520FF66F034479E2B8120E4A28FFCCCD0E4FA1E6A5E9E87A6B8B87DC8A3EF2D68D73F2317F294FC7A15A3A4E90564BABAB922B210878B64C20AC1F8BCB23756611BF042C201DA4D0697DB25E64C688572A3DC62C236555522127124608422BC9141BE17386F6423579697AF73CB0ED14513220AE13AA49A535AC241097190AE9B4AB6FB24E8200F75A7D3848A16DD3676E3E11BE281E04A9B642A1DB504948A56EA9A1C8D0A50F97F292560B12395A1B1138DEC127DE6679CBA8B849E33F888B1F595795321BDD543EAC2A28C4D89CFBC732E7CA6A7A04F66BFEBB4745D489A44FC4A5E255281AE35735D85DEE377AF98751BA4CB8835732DB983635B656F24FEB594F0C0EF5846B854BCED5EC137D8FC1471A41CE845D486E905BD247EE250E766A7F8624181263F2B184D07DF33614EF3BE0E0BBE3ECB0E3EEDE05AE25E2861269E0B0ABF9884A9DB377A360D9D3BF7E66EBCB490F02D0EB9B9F95CC59E7049C8F96F80D05B93AF90753930643422A047252B93FB9C0ACB4B88B0090AE098D1F103239C03D569DCDDD4D3E20EB00BED8F1C67F1F2D3A3A4F5F1E554B2E462564C6C1F4780007272ED5CBCCAAA46165B7978B206E3E099571DB7EAF27237B837884EBEC15DD26B40CB665CE45B29841B2DED76D9B0F1C9E3A0AEECE530A8A16F7FA1F45F9B9B7610A393D4580C5DB025B78B02261F5E4FB307AB6689934F3BFAC66ABF1C9FD202E07F20A1D82747E4ADA8EF9D5CBA6956434E94C9BEB21F32C74DA98F796C575B3B58F43B493D2D3568964580285CFEFB2E62B06588379EB296324ED06A7F1FD4F8790DF96D4A773E892AA0D9E17095D7329D9B31DB6FBE956D5061EF8611EBD39AF2E5903F2F36A75EF2BC9FBD833D8E8D2044D33B44B6B744FB66D0BBFD90CF7702567E92B9FF18A41582BEE4A15DE30290CB07A5E3528A9A27FE160617C351B8BB362A22C37F340F4C3B6FEA6289D7E4D637F6A1EB28A7D3C0EC52686D5A9AB790FBC2809F7F06F4871C4E3A24758975FB37C3D1733367024163EAA8F98CD93466FE9D53629E519176F349685F0E61D093801EC9A026648E72A13B8E4C05F906387553681D00719E572B06D304BD71DD1F5B36A45073127CAA88E68036BC26F9B6BF7265E86803373277BBC5BCA7762F7AFDA314949FEC84177FFBDC696A5497FB40C79E70E566E391F1BFC2B324D2B310A450D9807A5A72E0647DA940FA6BC3BFAAA4BAAB81245DBDD55942457B21DF8BD499A2E819A16BE59A6F7E6676CF3BCEDB9C646BE387279985182989FAAE983879BA0F0FD0ECDF712326A7385A7FC1B2C3F4F00000000000000000000000000000000000000000000000000040A10131A1E""") + ), + new SigGenTestCase( + TestUtils.hexDecode(""" +A4ED7F80956F1A44672C9030C85547B54619A313032627687F1F158976A2D28907900F84E3B9D5336FB661CDDEB5DA32408DDCCD61859AC66D5E623EAF745E858C1D51E75C98A689342747AFA7C22CA287DDFF2B30EE9E945EFC4FF74BD00914687AC4136597D0DBA2AEBB464A55C00007A397971F11CF922E5108F20B895B7941207013811437764076602057327650014846512521051134044721728840471240468158620851514470636303001350088771812801531688000733466441861513742525412601875458731315486847771662050347316344525702707057377764035718082720307174511475224256283107861781131553717714042076114552115453832756862775232773050805741536122157711646367700242428287222761460706108640730202305048004271137750473622514020882603385871776073866148241884265850313425124232184264815577340717562333801724206311260451483381762216524703666716683462381156603313541080053820757730826678818322826883061861335148373782208061718105775375826777672423588433254824486101823767282154027254361868335678543353805617821481162730652045145287554024323481137013167450247203075702807580765272817733061138110138050742533065402722575387148728268663883012058511436440708755322742756705443143872727618411601186033417307153814781410058448267271130100732602686516231834311238647026760152547113031066482361633044416843658581330423061736710024767084324838453061881648523633073145626613485686817505362474214104803222606853556234224865753748040484665857228745563151400065331467076364034001854708148516718643014448254581642662324580472540817760016334875431813615733342068658625221436633877448827353301133165100217143140503533081867240242288376423706818517408834337781383674383187725187780523321864245136772216405236663621124437888768426042072813436208810360206554680333862732263101403067212832824174614502520062327687743605156465476282370734160232624636614258885304101344844586018105357847251401285316763376185064183603001641775527412116344815872823276550347785718752750352857227783051142305354808613116667716627278876620522410851068428786657414384410663404801846405041631402661336873256432535608683333558305507630406032814477633143263257074135750334036686836723317701210415018766018220628550711780864682005421263438423340416413353070086841488211041250620327222208657643663862137722367033353738671553527108308134351574435151103425678758048472876854021260323038826835101538487847208802126638654312684104325807876770077436312012363386725511475331337542627020144121211014663122140658514307281185501024006018177482712312474614161700446687886722647162278322132585863401702314217876006468328164146581047085401421760440321582542441117553056048835224066102526308431765121152602773303251363080350616883864358271348413640038283567734581504521116644336856306352571210550150067264084884453428240000533610751625013670107040138826466331222242287483473037278656425874000521127357382325247351023460401842120860208858010418511736611802200174883450035706425872070364332078257248857812267664537025601262182676445510008434415815140885773555147384536274812741577500878000523602141344148306644333741235746141117460853768768473488606543427458420223345786350554613242521843216282474064647007816386531203354608282C7D03FD47511B27620F8A1E8CADF4475E865E001C554F08A3C8357B8D71825BF62A6312D4984FC343B28C5C2BFB5A945C0EBB5394EB69054F3FFCDA20339C801412E8F06680CF79416D0EFFE1A4A7568279FBE35302106FB0A2C7A991FC66627A0915DCD8C344D056A59846FBB72DC0F407B60E25ED5B855A70694548E4F89D9CE64F56D41F1F905F485D5ECEDB38A3921EBFEC726FC9DB03608BD182DB7D8E07A674929C406CF7151AA2C04A3BE99AF5257AB2A178E07820A15C69302A78314E804EA86D2C2E16761CA9D4D781CB18E5DAE5B671E48E9BDB2DF6C75F07FA0F285256007A891A6F50C49535C19D838966BE3A6195D3AB635E038312F222D164522B744A1BDD080CBB76B0D3F3F864CBA93AE9A8FE4FF6856BAC2E5E7B7BE9ACF80BA79ABF25DDF14F84355FB4C43EB83A532863B46E6E6E64BB64CFAAE4170C2498A4E61E8B270F27559D38EB709F2ABB04AF4DA3A4093400D5D79D4EA004C7DB83461F3C10ADEA1D25CA002DF5F238E0C1450801A700D0DFAD0661CC10AB6BCFBAE0DB95DE9F80F59B7B28D9C02D11788AD52DEF7F4A10A0A3F6C7DE7655371C5C4148B6F8444D4BDAD3AF25708517E4530CC22C4790A9BBC34999A2B186B4C8AD6D522610A3FA43766C42BECC3F9D32ADB22FB75DBD152E7E1D8D39F35F3DCFE8CB2F51C5537E16D0D231F6BC75BB925F14C2295437EEB2DC6FB906206B4AEFAD0CEB91F33BBD3C0E773B61984B781C39ED2EA1AA55D039BDF859B93B5F5618F565F6011EFECA254E516F5EBA19DDAAD7120A11591E81941EC42801B37AC0C362FE593907CF0C99AC6479646EF6C7E4093C38DC132C288F1C0184036652A7DC583B2F9FA2330155014E3E8841F659F910E93ADC4CF082C87CE9D5DDBC89593A99B2E4AE6C43565FBBAF606AE69ABA8EE6EC61FBB22FBC715969F08DF203CB83CA8EE911410A56AE22145211637D5BD82260C7FE5CC6CFD9CE9AFC86F1F1A67A129556E3E989694454C57D5BB6B24F33F5D81386187B0BC6F33734E5EEB3A2E148DFEEB5D3A0D3B771F77A010948BA781BDD7F75DF23123D0165BB263D25271FF6FE747F4DC953AD2EDEE4807A698BD1F1229ECD00714E18EF445279FBB1BFBE0FD7F0F80255690718293D67D27919C482FFC5CAD430FA4011416D883C3C3AC9E4B3DDA28C3BC0DFBB2D2C03BBD196CCF7BB896B5F0A026CCC3D9A36A41BB9DBC8F7C4887CDC64E8C6ED97719B03686C1F1A2888778584CF7702E74AA4730E1B56EE347118EE07CECFBE43555C77CB20F2519576C6D67665F3DCA0A3C436FA52DDC964AA0CB9EBE79E8BD5A2A0EE66510F40E53DEEC226A987C5219FB639A07C52E58FE5236BB4613CE4CC53A721C55BA0D5125ED860E340D882B6F2B0F68AA1EE6D2C1ADB9925780C153F58B8047B7533FDAFCA8CD67EC95B6FBBA84E94806220ED4AF1A2861F4B3FD3122591706B8B3F5519FB51A7A63ABDB03B411746A6E2351C499DEB6E023913BA4E2682424752C17610EFF3296E7C71D09AFBFC4E9921FB13CE3169331B774B322B1925FA1DFBBEFD745825CF01B9EB0A03F760C4343AF3AB8EB8664D7D04298CAABAD39845132763ADBFBB42D7779724BCFBD8A387466C16A1A4CCD9B40569765EAEA58C2C74B0BF2D045C57C267CF9D57D4B1ED237793B45BB947BB83D9EDC3DA763EEA702DEB209591ECA2B3B53CEF1A2C2C09DF4F3CA377857EE30F81C17E098C37AA6A852E759FDE07390973B41322E6F45E552D98309B6EA13E1BB53A0D0F4F6577C0E94AE96DC0E9B5FF47F7C0E57970C49E103F4880A3E9F3DC694FF4DEC024C662F42D44EEC975C7440100F09AC08F5AF04287D77C409A261E735A109AEEC92127991CA582ABB9C38AAF556C0BD7891F1D3E9F76756ED0F8641418204F5BCA432A3E15C446198666F9CCCF6320964A19D1A992570908B826AC75C67E1D877A1EF3522AE5952874377CA0C0BF6083EB8D3550E00F019DC7A909802217A97C7C4564309543326567FD57722DEEB12A3A6F37063CC5882825893B636B6959DD2E6CE24B2F762D59E473429F40D05579A66FEF7BCD812867312ECEE3DFE08691D7DE66DB3C9F6F7B80013FF92F1986CBA42A31EDEC08E3D71DD8F104A1CA29FA8CB4A7D46434E572CC6DAC54D73CA6C86AD04B948C904A14196D00DFAB1CFBFD366A594E5C8A398C849CE8B1E88BF37C09C48C89B4264265A7447E86FBB8DAC8EB39894F80C18D8E405FF15069EA8DCA779662993DA4C0C60537448A39DA002BA14E56CF148783D6F9A97E166A2CCE8A01B67DBD891F7E75A70798FECD48CBAFB97558CF2643E4CDDDE7380E6BA2178677C9A8F1352E75718922C97B1399A84A602DFFC5086DB40091F825467833F1BCF99B7A8EB719654BA1C7D3C57AC0C1E2A21B6C16C548B6BB148A3C4624C648F27B168E534ED0198FBA6D8A335FDF8CECD1E762412BCFCAAF484738982CDCBE17A2A4515E9152AE926BABF7023806A7208560E6C14FA56B06A736C3AAD6AE686101B0A09AF7221F66919709F37837F1DD496E4567EA2A7983179E9E86E252B67DB29D1899AA33953F71FB4A0FF655637E4C125FEABE278F55DBBCA569EAF05C2CFC9926353CDBE609A3325BE0B9934344B6EF5BDC26A70CC1796F594F74CC858F38C2435D692226131BB627DF3DDC507E50C6CA9E8270FA43833844A6B973D078653C1B2CE63E5DD83E888292CDE058CD57E9FEBB432FC177F0E5D7AA96557D0B6763F8801E04CEDB88BD9DD73B72372E309E89F8230FF1DFC1AF767F564AB6218910C9D8101601EC2E108C04F72467CAD035B8288F370720CCD840E5294962B6B8C34C8393AA2E84BDEA310B0D8C32C41A57B40B64F1761901171F958FD17A469EF879F566FD1C786E8D40F47A1444095E831ED353A754604B570F7D87430507A0DF27FCFB4896B503CCE146F4000FE5F20E7E48560B053A64B2ACEAB204EC523C13FC73FC857799F92AAAD7F66A8CC5C89C5685A31C603700720550818CBE3ECE24C0CB47A9B90E0EEBB36053B75A56E68252E95DDA53B876187EE2B1F8E273B27D0A955BFFB67D76D291D4160A7BD3A516BAD136E15F0428E01705941C37619BC4347CA00C5E5B7606D5B52721DCB5C4D167EBAEB2D2F33443B073E7C9AED9700D5B382D5F61281BE2F245F6F7323F6F449C4488BB8F3253E1DF2FDB709DB2484C03BA27E53071BA7C7B510D607F0548454026F960DF5C97A727350E0DBF51E7691A2A2175B57D377CF206E1A38EFBE2A3E81E688684C69B9F7847736C58F0526BBDE9AF4EC377DC8DCA89B97BE3A29A30B820DCC0C6FC54420A5F7553C62A83F2540E5AD504CDB15955034B8A850283DEB9FC413FD746797CB846025BFCF721D03DE7EB576C083D0597304102084DEBE13C73BA3EC43F1110510C7E135735364C181990A18E501F9B60D249DF5A97E9BBC94BCAA322A778D112C4A26CDF73DB7A4B5C195D4DBD8BAE251827F38E652642D12729B1C8E69E8B1C2282DAF805746B1CD"""), + TestUtils.hexDecode(""" +258FBC2A94EE48B415DDADDF470F14FF8DFC069CD949BB88812CD27B2BC3D9522E00F302C0B72533C9A612A251BCD292A291F3652695D318927CE1B922125B287FFF9B1AA2B79180622C32AC624E0463E5F48E86EB5952CA1A95BA51388760FC5374F0561FB8873018DEBF785FEDAE4CCD1A41820EAE9D7056BBD329E7A95F21A4919A109BD27D26779C3588C9A886EDBEA1FB97A8048DED858B299DDFFECD4D678820E5DB6CEEC8B1EA879C9C22FB7F59B227B4F7C6AAC577767D899B2F11FE39D1ABC527DFA0E656F25E53CA05630215C5CCF0FC071F124E48C57C5344BB103D51A1FF24114426A324BB16D8F80D3CF2D0CE573F4E50DBD1CFD66C05430A1109374CD84156D2E31C0C3F4DE2F1E225B5CAC05D56C4478929E356F7F46032E2719E07BB1EC207B32D241C87D87ABF28C7CBCD38267CB011F26A9B49090008389417C7A219A9F18203E6D907D63AF4C42C60F7FD99C7F9394021640F450A9A072BF2C1CC3EEC88BEC866FF1FB5F032567AE053A408342A56E3068EA168B9E902068EF808916EA58004FF31C31DDC3FCFC2CCC92E0DA09623FB523AE46C8CBEF92A1CFCF4C0F523430E60449E5825A81DEAFB2E26B3131F0383B8FEB4B1B4E1499E89E9C5FA2ACAF1F37C422CA41ADBF907EB984DD65D8314E2F71E8AE616C0518DE9B8331FB00983490483362802FBA242E4CB71056E3256BD097504AD13F577B36A2F9FBC1EDDD25D9DBC09B3401D58FBCC9DDC8E74BBBC897552FC826620060D3777455BF76EDFC059E5C02BBCCC0F05F86ACE1903AF2BB08A962BFE9E2C435EE8C580502351669AB7DF3D9F6B4720A0509BAEA97FEED3B8C769AC5D0997A097852C72DD6D5FA0A7144E08D667F21936F434953EC3C88B5BA2EDAFC4F87BE8BFB5A592847D15D5E5D972710A4A75A5772DA4D9F156563C17B1F0F242457A198658524B0D6A46DBCD26EB9400DF3C4C942FF53E1102411101B2FCCB58E3FBD16E725147960AD56C6CB6DB336857EF137C49D53D16E98CD7A0E856E2D6B391A95954ECEFF3B9956A6D0C279DD9E1FA5895D37EEA8C54255A6244002C7542789453B41463B084E7FB3361923C43EE1BA115CB254F47E55E6EB79C74DAB4C9CCFF486B8CF5830F23BA23C5CFEAC2DDF7D71EB5F54141C100E0AA9873D43F0AC1034C54193BC63A560A0C661047C508062A70B3E575CC185462A75230D91A3021330D95F3C807688B032AC15A9623A833DB718D04603ECE983F1D21A4513E80CC67FD34EFF8E377B775142344645872844BA46F5AE6971E68FD8ED640BFDE9F276E26B208A8F3D74ACB739C7EA6CB26165EE182F165EFF21905DCE3D02E432B1193CA108B6ED066CE95D549D9B12445E05E0583EBEF32F17EB121D80EC26C1F154C4DA2ECAC841BE1CC7224576EA43ADEEBA53C4D58785F36B6BC0F8AB23340B92CB87DEB0230869A52DC634F68A83BC1AB8A4102264CCDCA39A51C331F6DBE30C18C00A966E5692CA86399264399DBD3F02FF8706302462D62E4D16B5C2FFEEB02A7E8447C2CF1A3FBA5046C792FAE0B1079621D59C1D7AAD17CD6578964D1ADCF1256F2A4EB4D534C51313BAC17A9383B5BD02EDCCDFE59998D2FCA7F3EF52CE0B1842368EA66E0A83FEB581A7137004655957E91B25F5435BEDC0ACCF69238AA4CACE418F08ED0D961E13B2234187597FCC012769F798D969C13F6BB4042897B0D8C32E6CFFC06680B1E0A40F5F149B5974B0E7F0D45367E93B415F7F6DCF86C2131137DCD0DE30A3F1FBCD5F8214AB20BEC9738AEAAAC200900F4B2074688C8F3026140A354A22F83BC2ABA66407F87671C3E7EA4EC6F8272B6D16F3C66C76ADA231677A9B1CF496B3C241D2D1ED7DB703119CEB162EB097A0AF2729D0D6CA8DA57D83E1BEFB880EBEFE090F6E98D64296F7CA90EA1C2B26131676232BB394BCD1A06BA83004BEDDA287073154D3BE16C242DD65839C2E1125B3E66DC93A95C62F5DD31CAF9895646D5E2D183D40EA09843F5DB189B41AA4CD1B40C5792C2BCF9F44823EDD4246100457299E30EB2C66896F89F4FA250AB19CA06EF5B899CB96FC5E0369B773691E3447E68475A7552C10F96F44B3282D92AE49A246508A67EAEB9F4586074D6FE8A44D2D27C7B8FB4EF6BF701084B73641E41AA7275C1D6B517FBE3D60F64BEB9119F3FBE96A11AD45610E63CBDBD79929003BD1F2DE89DCA036973974FE5C5D5A8B5BF82DE0368DC60D75A138CD91E8A9233BBD439666ED1211EC2FE7D7BABB1247315DC480CC64CD8F7859BB9BFE8C668F112FA96EA48BD91088EA44F40D3E57314D3759F867BA52E52BE822400D9B0C2123F50601EC5F8E8B562C4B1F49F9779A99C926FABD8A74173195CE23173F4CC4098EED74C8E0FA74320772EBD1847AFA1B397F5A6F05A00179DEF2E6C3B092D9182CA3C4E382C4092396005D8BEDF6248C81D3AA0854F0AD43C1079CFA1E0A42650EC9D7B9077BEED377BF5FB2F3D2717BED04CDF2F7E7D1F45CCC6F71A780D2E5C3516E5F6211815FD691E036E4FA002079448AF0E005B67D2939CA88CBC57567F634BD0402EAB06805ADF8BE550B3E27452B372CF8C92A7055714A228986FDCF4045421321555BA06173CA0A761BEE635C541FC984C5BD3857DE696E9B21EBCFB87ECA437E9A7B54F4CBE2A601824EBEDFD5446556B64E1A88B0BD9CBA507C5419CB8CC4CACE48A0C9668FD2D045E9057B13BF0785F59B35338501B73B44CB749EC2EBEA97C9D29EECCA6AE1FB719F9A67E8E175D50B2705B6149E9D5D257B34487B547FD050FE5C998412AD0B4159C2225EECB67903FFE332CC3B86266C22FF7776334543C1E954AF5A89C4FE59C1F1AAB5097024E2AA7BC09831C9A5ADB713591106CD3304873BCF11A9138FB08B7485E123DD8F7C107E336659DAFDB866487E197589DE47D2DE8298EC3560EDE21A633F820BE6352CDE9AD51515D309C4BB4709F171CAFEB407ED1A02BC4AAB53588C2CD4C273BD527F8B4078925FCFF8954536E0B4366E474801F5B938A4B81F037764D5CBAF19F237CE37D00246C60DA652B76469BECABD51F873DC75E520A75B52BF585D664B4CB9A09F8EF3C03FCBDE6B9E595C1371C2CFC24C16EBC392C75D2BA04212947944BC0377DB718A7FAE0F6F9008AC7DD30B94C1FCC6BAF750217C0119736E4F3B7E744AD72F1F0694BC88F71E4BE51ED8669F0E814E12FD9F833286E2064708951DAB852774D4620A26100FB44A8A92B86E17507C036CE6F3ABCFAB91193CA4BC4D4198DEAD7CEFB71B01FE2506995F2ED3A02EBB0355E6B67A2294648B8D1C1445164D99B966588CC253D1EA1361163024372E2550E9D29AEB4234F5F9B20AECEC01862CC98365F1C57FA4D5E0C1F8BF189E169669F825DB43172D1F682DFC7729B2AC0C103ECE4ACD982D86C515A208519D23F62934AF981DA66B97DE2389F2F669EB92CA4A5C4C844FCB19903371AEAEFB32E210F2D1155576566C7B529A98A1CDBA36B450F3948F34F90A49F50E7412E6EA68BC3BB0B0A0AFE3BDDEDB718D5A150EAEA784859953FF1DD1B371C539243547FCDFF4ADB06C61CB49EA5783AD06BC8C1F3E32A95AD3CA6D69EC1D226BF9DE0562888839E6243CD150EF6953C158F9FEE5EDBF173997D08509EAD1ED4DC2AAA33E18DCA6F59269CE457C412B58C4483BC96AF5069D1C2E3F2F8DCC5FE2825DA21AB2280984C359DAE44C2367D6F002D64AB47F9B64B5656622517A5F7D5E1A78D4182B6BAA82E0490659CBF2724080A9ED39BDFCFB21BA362DC29C750C5034A04EA5A85799E01FF8B16ACD2EFB8328BEC686AFA20E591E7C7FC55BCA8BA1A3C388B785AB0F57208CEBBC5619AE3A0B799D1816B013BD67D440A7AECA7D0BA517846B68F70CB5D6ED46C36F663D6F242E8FD8C620C9383EE1BE9250D63467504B229378D2589B525348DFF852AF1676A18DE321DD46D7AAFD3DB1825F192FBD3F160E8CA400B201B1A61D0864257CA340F179F5F1967659AF4789846A4D086041441DCF4267681B83D4C8539086E276C21BDF677961015CE550E41C2C45D67A09AD8F56AC3ECF1058F366F2E35BAA9353A5CA40C7021DD09AC9FE0187C10EFAC7BBBF3B1A462C9C6C96699741AC16D3526BED3B30AE25B8E8A9ACD8CB2BB6C28AB89F0A3F0D0F40D10AFEFCCB067A37A2C93D3E8399A366B5FE4829870DA75B93249DBBE3C9AC9FAA70C4E414EBA720C323E6627759E7287472C3DB9CA9B1A5FF03E872374D6B893BA4887AB227E989D9D4D348B3965F7B96C5094F42D84432EB771BFE757105966C9A08D6C58DED7DC216B3D0ECAD2D0B025DF33CD3D813348B5E08AF95BBA08DB5BFE5D0A151C98A01ED27661CCF80F416A1AA260EBB56526AAA289F17FF5AE97CD0907D9143BCAC73F1F83A2A8DEEB3ED209EF0952D5E463D87145E0E4D8BFA1741E3FB737E14B5924F436D0183D98EF836DCA3F9623B50CC13EBB5F94EFBB76EF9BDF40CE6EAC9C49852D08E2A5A193D1DACFA04EAF3C545E0E25E37E94DF51FC1976BAD069CA530E19EED277141BE62239F47441B88F6555B0A998C1BAB53758A41CFD8CC4CDC54E1158DE15910408A6E79D33CC37F61917027E9D2F186466F704647B1CC1CEC06DC1AC37D1A668D44DD8B12621AC3CBD2039BF5A843A86FA492A847D6552E1570DBFE008F51652D65D03D8B613AD917B81CACDFD19DB7F4DC9A14E237CC6D7268FC5D3B228BD88ED36D8360488509C974E01433D78701CE07108C67D0489AE94076106B045DF7CC508466D35BCF156901E53AD2B5ADF8795751891A5839033A40EF3F5DFE0BBEBFB2C9D1C000691F902AE490D382EBC87FD40E76B30DAA963254674C7B6F304DA2C8BDBE8E1DCC87DE0486B4FE6B57A18D5A9E9E4BAE776D6147FF9C98372426EFD30C3B2479231E624A253A7B0BEE31E0FF739F862010AF03E227A12C3ED1F33EF1C0DC9D48A100FA24CE5C5D8B5F88F92BDB6A3A5328B0AFA983D57A1D3320A682B5CA94E75DCC69BDF2AED0C05887B791CE6F6F8885E4CC55C3FB050ABEFCD3AF2CA603172AC78B3AF2B047E506639498D0391A06DFD328B8E1BFAED8F76C6E4A93E733ED1097DAD8663F5BAEADBE1562D40C772D376786509323BF059FF17A5E6EF5A31BD668954766417E6633BBEC90B53ECA61BADD4037030A55A5EF4129D4958F6A8A5ECAA1AE7E220A87AE996AE8D9AE46B9C60FEDD98FF1E67807037970C92CFF9EA4B64F0BF8907198A6C038F9826CB968B1F301952E1F409DD6AA4EFFCAB157E792ED45830708ACD7A50BE8C08FCD12560344221104827BFA495604A57826A49F90B8B694B2BCACE4040627AA0989E3DB4FB7167F50E8A04982084FB3ECB0DDCCA5F24A7398620D19B37309A4DC0DF28909E16645F35A81EB3C5EF6BFD650571DAB03A7FC02FDCCA5FD09C9D2D3DCA888B8261433DE88D05DEE5D6165080A237D55ED718486AAAF1E2534CEC3A87048ADB40EB9F9DDACFB2C883EA6B20BE1EACBDD72432C7A6C97721FE1E0D9A5589C951F7D46F2C5F0FFA909FBE12E1CCF00161E741C4505681B0B018FFACD460528795CC3810BF7F94FF9B75884956798F21ABF36DEDDC1F95890894EFC15EAA6F19E9148C71EE9BF4CFD41EE3E5DF8A449FD95E5744793B9C223D26ACB44E691D7E5B68D49A19687F0237E7287841D3B0B4483E2A7C29CA81BDAFA5D96D9D2CB6FD9724B9903E8CDD03DA810EFBF94BC7179349E10566B5A314F81327F76C5A8346E222C408EA43FE29439132CDDE79D0D69C45C7217399205C2DA4D33DB521940C4EED74CA22645D5B6A549E8712D0B8CC50DC180067D13457ECE66D489F687DE218449D974620B3B5462FF3A7F00C439AEC73A53303AC51EB84BBEBD51AA48A5DFB8F93556BA540F5101CADB8BDB912D7BC87EC2AC67971AB99093C8616C4D1F3E7B06003E4FF22D99E6CAD7558EAF5C1410199EC97720E5C9278548E7EDE62BE9105A2B27A54D95673849CD5D60424ED97BB64798263F98A63DB58BD55965D3A4283797CD88C7CA67B1C4F90FC7237EA35AA24DB18A4420B827B3FF7FA5472C31499480EEF5A97BB967D1EC46E7B05A3D25212C75972D48A9269D67048132399E1BE0C02150A3D48717E4DEC2ED47458EB870A1EEE5381209B5D182DA2093AE46A4D99E3D4F12ADD71001BDB936FE8AA96797982F88EE67AA2E0F340E7AF498D5AE05C177F0BD2650A02ACD4CE23018F9E00DCEB9794C5C76418EFA65634E01ED5E9FF94FF86AA73641117BD554A9391874A75C7CD1E7759755B9D2A7F367621C0011F61B588D913C7AA0A0EEE3A2201426EDDCD56A020F54AB41CD899721D6E1F05F8774CD5FF6417CB68EE14C20D9234369C9CA59627B8796C37B4ECF1DE2F981ED0FBCD5737DF0B82637D599A61826909C978A2B68CEF01C5CF84B50BE77B49C1887544779BFEAE3F533286287E48F0ECC0D36C27F1209314726855E61E5EB5E9A5D7E3516E29DD369F94D72004742E246AD4699C64EE996BC7B2A079344ED32A528A9CAD6D5AC02970D0168A8B5BC713E28934F2880774418550AC2F534D06B61E627BCB8711AD9FC6F2A4D9301EBB74E1F3C73B05F28DCE5623BE1BFA871C14A947A947CFA806AAC43AE515D6CA65436BA6B66F62B0FDC8AA4A748DBB72D9AB087AA39561271A986229EC02BA3719CBB1798DD333248E4DDD0B6EEA4169D3B03C9F4DEF9616BDF97AE993F0FEDAD31834B6F78E23164B556A39AC1F209581F61AEADD8E504E81A808B1E97F79F987892A8F7FC35FED9B1A2E9D3E17BFC5AA64680DE98664FEA7B479567CBE307AF2A8516BE4CBF9EA030471428CF802FAFF85701AF96CA1D8F50F5A79AD63F20C5CBB954011BE4B1A7F627A8B5F5A0D022D27BA6FCB8D3587E8632A2FE5794C7E8FD09C9AFA3021B9F43BA82EF48A3B1F3E40F2FAE182DDF9558F7033773F5627906E159B794C4220219BF1A9878B175996A16F3CA1DDEDA56B16E63C504354E5E42FB90CE4D2C1AE7C93D8CE27480F3BCCC076CC253B574A7BFA6D3BFABEB3FA6A19F196C7E31A0D6E9477F828689FD951E0FB033DBEFED6C680F0FEDF2F43F48C0136C722601CC7C4B48B24121ECB6BF84D6B3DB240FBA1E014F7E3ABDFC1F9B98A16F4D39826BC1EAE44385FDFEBBD649BDDA129FC7EA3F50A5F481D3B7508EDEB04FDDB3006D6EE943930E3F0AB405D151F21E8AEE5BD87F225DA6E155158DE27290B2048D384BCC54F0EB905961AE4CE5E6E93543016F62445AFB5C39C3EA2F3367A0B8F0FBB83B37518C5DBE1CCA1DA9D0B54F34B15A1349A2F03563732DE14EA9BD238F481D9B262DF69D24A91534805ECF57A538D8F08B2FF11E96EE692DFEB106D3515A7C69386A781DB1D5434AC18713CCA12C92557D1E7DFBB15605AE3BA86267F3E6CBA42B6084478E460F092BA2649C8C94D66128FABA2D0EA7D9BCB20663B0DE6EED2623A061778DCB40373B8CA38B02B7A49F6940D6D11CEF549CE80212CE8D3A85CF2D774431343FA1FFDBC71C5334B1CEC4D4E0EB643E1AAD67D1A5B73FBB1BFE47EFD83CD17C798044A504FBBA5726429F41DDEA7B7265A76A48B0BAB4845704C771638977511092BF6C6DC9D574E6288C6A3B96BFD37FAB695F8DE20F28ECB27EDA70A07FB2ACDAD88DBDFB2DDF06E83ACFD3A136C5DF4811D34C242BF9206D579BA8DC6D20E8600B726C9F1B918EA573B9DB2F96444E17B6EDC15822B85D452CD99CBC847AA205EF79E574ED9625E33B6EDC793E5"""), + TestUtils.hexDecode(""" +0EECF0C5C5646C6C01CFCE8A4236C503F9C21F7A3FDF1B708851290611FCEC8D28234E40B9061C15212969D6BB647797B77E3CD2AE88051929E75E9A0D8EE4491E6E709DD1E43225C545CB3656C0F84520A56BFE0B3A26E2856A1661CC2BC5BD289FA800CE140070BE31080CA1245114624EA0C215E76C32921E54F83796F9CD9B5F0FC621AF39184C4857667414EAE4A2A7D18AFBE427B48441A99E9650344EBA609B879C42CF4DEB120FB5C44D542971182F83C87EAD8DF96ABBE1A7CDF1A75C538ADA01C1EF73E99F80B792F61A548D3A2154008B20AD71CE0C8AA42480D8CED5EE8099590057D15B339A8D22CB86E0E3FF8B9E902EF7603098B356CA6A3E8D8826B1B02376825B82420239F04AFC1088B16255EBF6030E183FF446745EDFC94B6DB334B4818F5421E58710703493859503559DE0AE797A4194E46AC916428FC84944B9F97BF2BE5DF2C3DC0E918F8AA58C73D92A052E59DA75AF1E3E30896AAECE657CC427857AC6EE80438C849B7D129726D27DE10043457BAC8B6CF88E91DF12ED3DD04B930ABCE64F4A140B551720FD7122C0C201D61F4856FD901673B59EDDAC1486563A7807CB94DA76A89E3B358A78BF8054D7657246200685FF47BECF5AC5852CF2AAB51CA8215CA1EDD6EB6B1B7CFC6D1E79E00692103FC124A48AEA58D21C1682761EC72712D2FAD386AD3153C1A07F40135F38D6E3BCA30F387DF057D4E26FE94E1B89FD1C63CAE97B0E0EB18D53C45F5A1C0332F35FEF2BCCF9192758BAC873D3C48506D23427332C89465C8A08516B1E0511C56DEFBDB891B15DE0A58771C31F398FB27BF63F3CBB9AC9713F75EDF32323DCA0D2CE330340B2B5946846AC0A0961CA3DF970B827C311F4E7D04A859BE995ED60092BB8FECC2B0C5498E9B0F88B4B70DCC50B6C01286494C91EA3390F162CEFCE4B83A5486AEA9FA866350A3A3EB411A601623F9D77585ADAA9DA360B0900EDF684095A9A581DE3949F85ABCBA9525398CD58A81E91AD655649FCD21CD40490A5892C0E8CE4709B1E8004223F8B842389306CD9640A3D32412B4DC53E3BF04FC39424156B3E797E7CA688AE6DA5A4113C8CBA7290315D6A6DEAFA09680857C18B696094FD67DEEDDF1D69A1A53F73696733CA54CF0BD144AF0873249CA50F897CC5B487247A1DD5AE8E7161BCE9C5723DCBCA44796CFCCB5D16B42A1EB3D2ECB6108DE4F2BE18AB41C287C6B4677E56802CD919EB1EE762306902C9D731EC5F0773F7CE7243BB6A9A832C4052F11E5E56D20BB6826AFCEDB7DBF9B4F72460BE0C45FFD628EF44F0BAF2CE179D9627E5CB1D10235D3AB21206EFD5E74A823DEEBAB0DA04BE8D9EAD7487BC96EDFB71737A15A27452792CDC237305E8537619930567AF51EA8E5848DFCAC9871C7B260695A340F03A48CCA700E60220A35A01B2E195BC3D73A5A8C6918567BAF8EC47B473DBB487F77CB37EC6E37D2D6F885208AAA845C5ECFBD2F128CF2D5A16C167D26B00CECB517E753A121CB4CA8EC8B3A5F735FE28BF6E0B988E03E6FC2DCE9569721E1A03D91760C0EC81B4C1DD31470DEEC860469DE3A74777B5A8148DB3E7BA6AF995BC8BC14F30C7567886CBBB1C6D40433D93D52D9D866D897727F55558CAD5871D461ED8756938048C877C9183AEFF67132CF8AE015F59BBD60DDA63B1C2DFEA4FB19ABA2019BB52A135935F73BA5FA359EEA99BCB8254B3A3D82BC2A8AABE2A653AD58B2F13609D762F2D7E89370BDD46E46E55B9B9217A5157BD696ECB992809D1DFB607F1E66B77E417CC0EF7F3CAC38705619BE39FA625EAE2615D9137C0F702A5206D95A2DFFD7ECBC308CC453CB29507B8582A1B200A33C24F6FCF9D3E37814D029DF14D9D7E8D6A98B36BB75A1FE45FEB1A61F212C03F28E9D45FFBCDA5796C2FB2B9BE9AA778BBAB82F9C2BC4DD45B64DDDB6FB1C71F57E11E49246606947A4863434C8CD23C0080F11B31DC7BC0FA92E45415C57314661C1ADC1358AA49EA4D69ABB9A230BCB0D85A8F2885D261584392656B15643323B270C68ADE3D7727B35FF8948B1501B8458FDBD59282E713072F0799C2EE69EBCBB441CC1200047A23DA61DDD7F73D59008D9A802DFF46490DA652B6EEB1BA3D3B38FA04FC2DF2235380B026AA69EE90DF21FC5045895581D27AE6A6D8F99215B116CEB03F9C667CE8DCA4B63F1B875A2B2686B30D1A59297CD7A491178E3A81C83B907A1C7850092C355E130C3C41BDE7839B115E8A51D729D252AC62CE03E8B9EA488338E6ABE1A1151FF037C94350FE5B89964069FFE68C238B901B72847385F937F148519C0653F932048D6B0E7B57092625A1B4BBD72DE1D16E7D96A509F39B3A9E50D1FFA7EFC5842DB79B8C15F2842502278F5125EBB082C5EF78BEC9E872DCAD120FBF2A3D544F15EB51E7C14155905C50503A3B12C24ACC6A37A051D54C6226E0FBCC5DBABEF1C0CD4A89463873379CD95B3708C5E56FCD03C71B3E5788AF19033DA37771AC10373544CC25696F0A342307EB92F58D95353F45B5B5791EB3EA3DAA88CF74B3331C21DD448D00A1DD026A0DA7443B0028D1E35A304B0D7DEF9B74C09C377A9A5B1439D64E7D22C687FE420E1E037D0C1AE5B2DD33093C1E130B5D8428AA2E430CB5FAB92B316439CC9E7593628D567D7055428B7E6326E7A004D0820C22C1CD015DF8F0082F2FF4D39A05A66382107C8467F00344639CD32F9A4BAF3DE73640F06344D64BBA6E4E830FFB98BB23C02D0DD9D1AF3B2E9224CFFA7B62CF7CD552DD26128DB065C1CA91083D7426195F9DB63061C20D9F8ED337437B4D69BD7AD9DD13349708FDE783E86BC1F81BD2A317F3B484DF3912A2FB97E8F5AC62D14ADEC7A7D1029FCA2DCD81EEE23CA87D66BF43E21273D57DA057B35D8FF70404C230989B15DBBF3B057367C005B5ABC61533C623D2D774546119AE87B2D5816B5E7D5039F2D1FA568E338D4EA9FE809126B46D2EC92EDAC8717FFA55D678BB94F0C061B0744F7006E8A0A703156E8884A81AC0D8BD86EA1BB7E682E43F99E2482EC27697293A00792676042A660598B8B54029E00D5F0C7D10B07E4275620C3D193D5323FAD46AFC4B8F4AC825618E872BC184AA97DDFD96BB395ECBA6C3D42580F4BB877E5AB7D96D985811B580417D6B006B1E6FCB3C14F84AFDCBC38D495674B8AA6976B036B5306EE593A0584A55DF7FF214C1C6930CAAE7AD69423CEEB46E95D0DE88317052C5C62B77C43CEA863AFFB22F0201E5C451BD9ACF2D8746346E776174BA21527EB5A32AF89F12F9E26A99F15AE8017FD9720E3CF71741C5D7A23DF373B0F229B89A1E1849D569E0461267267BFF654CCC010F135AD41EBFBC63A3BF4805405F3308095A90D4C541BD82BD62D8EFEDF4B9097AEF796C199521931156A3E7A59A7641F9A0D6542C05EF29CDAA28F5B733C7B30376C975FF08485C8CCE4393B5A8D3735A13FF6704544901B22FF2A239BE8EE2C8CC56175FC928E3676209A003DB9D7BE5DC0FA7C6B3A5CB92F2BB9EAAACFB740A8AB47A509D2BB76060196F26D54690794C5BFA48435B79C854E79A538F1A796F1D4323C016A72667E85DA2FB595E5F8B98E5BCB30FA0BD14EEA3055BC037B2D11B6C4C8522961ECF541E3F2A98185ED50E9EFA20516B0353B0DB96A6183AA9EA9C2C8CB7175158FAC07B08D5C01089B7E835D10ED00D7B3CA28C22FDBF1E0821297DF5EFEE9AB47BD245CC29ADE18C0D0529F9070A2F961D558012908E824B89D95474D0201612B474F7C2E4CF4D66AB165883089013A4A60DA26EBE8D7FF70AC279CB81A22229BB098FFC26EF456B49878913A354F66B8D8F730FCDF1FE01161E606FB890B9923ED849E6DAE68BB3364E6297B66682BA3CD3F0FA7EA4B41B8C96C70B16D606DE17BE72119251F6B64DC78A97924CADB77C228F4118F2C93CE007A4A60BCAC6950FD2526670A9ABCB6436F8239DDFEB8905B69E7CA52BD6FD1D3669B24689E4CF050C7760C0001B7875F76A195E043ACD6AEE609E76F1C800FD0ACFB96D93BCD5A0FFF5F979A96CC82A376DC443D694AB9D190A96EE34D6083702DA6FD73233AB5DC2CEFCBEF22B5B32F66565D0DC948297D83FD04E919CE4705C26506E896943C5B1CE8055434180CC62086FA39A12DE595949C40EE564E5010E22838ED76DA6CB72305F5A160B04777E10B24D7B502EDF16574484DF1872BB115FD6E91E0C0B0AE2FF35FF01F8016D8EFA6D5033E7EE3138769D88A96E20637AF1F435FAC584F94AF8F9C12E3DF67814EC28CB50C5C8C473EA39AEB6080E127FED93AF5CD75677003754C9E31120FEFDE2B23EC17520063884FA1CEE1D4C0FAF3EA7139CDA87C050CD26A349C55362401D311029BC2F21D29793FC8661DB90DC18D96079AFE00EF88B007DDA214BC8800BB7BD30C942CEBFBA0DEBF1E68E9903515C990C49D323A73A804B0EE4EF439BC5B67F298D63B9932C201634AF618DEB8C49DCA06A0FC865744501BF3804668F3331155CF61DB1DB6CDACDBA1119D3558F1A0BA05633AD518C563BCEE51937C0283F3516B812AB2CF2B80305F5DC15437811EEDCBA7D236E7E9AA8BA295A7E8412494E683F5985B920343891E4F44E585A6785E2E6000000000000000000000000000000000000000000000000060A0E12181F""") + ), + new SigGenTestCase( + TestUtils.hexDecode(""" +C8C32C98B4C3329B1E9F9B8B0A06F728FEC8DFC05CD45B51C28273061A7C84B44D03DEAA1D3D423DEF8D01DF94252EAFEE18AFD0B714F246A2AA8B22919F4A64E8254BC8DA58D79694F68A8B33FC23190C4D19E3D686EC528B46E14D752CBE218D0E18B655AA5332AAFFF4EEB5CFFD2BA6A03F60DC018CD23EC259AA4325EFCE08852158642851628354014253336656040034734085244624702650458046023414141653265662553257528848144434538583171237621870046622542527580662760688425754461883673651187381743864383543514734285686547356774154037857147010824422821820372371434640278657362264124415854343344041688413722261224658655223800244426352431335075843223847830638802787087632058358458134612063704650052330674634702657828852755171178100888071574872500003761125174467551513406085034688414064261281865718534556361580681066615474883681774570757571780007105873237730643787603255741251882778647716627735424330287653567230817703068376113812788174132853265501737207541765673284844633087711520768836556152784146844502445608448350455765277306601008336883210200716413782342871820515037658772672513172866057305014605013778856128828263337372405472843534375648655082510264478061188683265047702226038855710017543066112306303885632257413744062041317752202814804005205448814280410780017846728458263376183744528251332866682020484544067715461251381023268133503550626017320763011688141043558378413875642643444584351184365058376728644264005672381788337041681643525641530354046426331448556436657662128333156784163856374755524078102415500647382668666204378324674242332458875560880870446801506724870770075377623558535018066536113077736557373140121445368728505234510843712443083486066118634707435307287834841377048724203643811402168118565240877002038527641833114558786071676284684057368570785252016484650654480760442014125342136012513131513754542527403415643546752574520100488478715505263884185412513443846738708103777317714028531710677723682545550823825506760431583105357435861166168085225017870015035876442236026623862112188700714876376877706235072035840614340577178021553082422411251301420001307586123370726600337582487275247806637312456726385287223783713615774466050881878126110710021758600135101147142066365521572708410557043546161410781630038172422202645550360675605422888073255353264416833160257185872065350608713265217047530036306438828400667786630573535515217683235415121861604404228766416241310412807607544783206736820630303115444301271607246665073637418272420826411083048741645574851556481310322648258642846872020371271453707105300457683437487543257460657574378450022804404154248422852870054400115704171748041775074284552866412884625787625020238334401546627850511538557453800533335000553567035164313872271652448031663187004542613853645488711616002127354808730021575550780772055654173636682015662428213111586672337018624237806607430261432561653583383546454223153687813363744535756030611834227116883466042873648850082482071801637617701364885353218608856781116835784815225000572468806855765577805768462876401546171442778806140835684815656874817750328776567238860658770156531530633503227851364168542031232554515285878430550188057083146685505544383510160372216041617018142A2055798CD4A9FAED4129F4762117C2F9FECB68F55285D58DF9B1D97319AC4966C0BCC41CD28E76896A2CA0C448C002E606702A1D2716B18F92F3D248C5E576EE28DA7A4928CD072E2E06960D642D78C34A55DB793D4C6C27D68E2E7C2E05F3E997DB884F02DD4E294C0A37EF6655A74F98B3D118D63C8975645DD28E326540E289BCC194695E2962EB6F573FA010D9AE6DBC9DF30344189F87FA5A12E7F096B409CF4905A15010DD6CEF55A88E3A39ED196CF05DC1FC8A5B706452F4E49A2D07DAECE812F69207EB3E4D86289E956731033D6F0B90E9442840DD8ED3D4D7298836D086D4F171C0AF60644B7EB187EA185FBA5D04D6C42BAEC690B6F1D68764FFFEF1C719F690A2BDC241EA2A145A7B9193CDD67C671D14A676173F352AA90886919A765B2D89F46E9C13F35243982F81CEF10680967CA1D5AF9331BF64951F1C48CE1E0A24918FB07573F3899E19D3BB2C386C943D2732F5D287996C78C67DD2031BD6C635D53C51DDFC4B71A27DFEC7A308E568F2805F667B1A85F6436413A186571F99CC842C9CF43146B588DD7B0283C5FD1D09CDE662B510BD85FEDD31E3DDC957583FD08A1F8EFCF2CEBE014652E64E558EAA832822D089A3D82911D671543FE6F31812A435C1741BC2AC8C5B33CE4E3F546B970733BA7384152FDDE245FDD7989E1CCC430D134E36049DB88A3817AAA482BAE3B53D9A448FC536AE8F2D01919588A00A2A2CD1F1F48710F5FCA8709286B4B7E3F14FEFAECFBC830D3DF005FCB6612B782AF5DBFE7C2436DB6385A0F2C929849785ECE26D52EC9CC70837FF75C7E6D280CC9B3A61C8618C2E047BE4DB9A6A89E22EA3AEB8E2953B5336A388E3837DF09BABC71D308298D735D37FF4EF3D0D65247B72DC04E1B7A61BFE131E4264DA5A46B664FF4C44279852214BBF4867FE3B8AA274ABAE01EFCD237DB8D41F71DB2B386F596799C670C042149E289FBC3FBE0045994A5263E710EC3591C770717F5D6E4362ACBF5A2C133E9896AE4B59553353CBB626F854149A25728C4113686F16D0A6EA7BC54C8DFFBC8D7AD3892AD37048912B09648814B415D74408AB3868D6B1114FBF9739517D8AF886316E19BFC66D55AC4F76C6814E96C6A8F846961CFF17C8D6A1FE362D071D5013B2349724BAFE710D990C8CB0C6438535C5AB62AD3948140C1DDE116B7E552E3677C001DDA26E3D8B53BA7506EA0069B90A26FCC35FF94272C1C90B3D910FDBA5FE8E2AFB5B955847CFA4DF8460CBDE80DEE5DDADC25C00418C126F7D0C5B8C1B9D8710CD3C995500AA245C63D9497F6279130B23347A95A9D5694B512D4BC088290620738CA448B08ED871DADBF1725D2348FC4DD6FB64003E044B67595F64D3514B4CBEE61E9E12F1163B56C105EE952616A331B263330B29DEFF153306EF9CF27C9B178F671E998C07DA69C9D38B750308A7D78ACCD69EB30E1F04D86417B76360805576DFB5BB9022EF9D6FF249EF9D66255A03535CAC6323B084C5550BDB703159F570F47196115BD67DE8BDAD32C9BB29B7C6FF96EDF4313B101E28ED28C37AD1DF54FA6147F3CCFE8A890A423B047A2613CEDCAF70C0FA123BF1377482C1EFAC44C483539F54D3D54BCCF3CDA71AB23A7E27417C317F5B1DE41E99CC1F695CEBDA3A2ABCBACBBC7E87BD1252DEA50853F4C47053E10AD30490FD3244B0AF23B7F869E13F96591A363E05574808FDD2536E7887C0F621600B2352E3660FC80B7DBD09C4D06375CA6AD8227D60E19FD9532BD932A15CE6A79EE821447D6DCD26367CFE447C3FF99A408C2EF4E1EE16C0B63EBF1101FDC0E66C5F5F4E99D277876C7B007F26AD220741967A0023342B09CADC11C0821B4E3B42F708422E36449C37D197D4652260A29BC9DA316009DFD9DCF2FAD8E7C66E0856B16E2DC625DF9EFEEB36D17E56A97E85BD00988581F28A742A85D6EFCBCA370FBAF39F1AC123922CA40EC5B180D40F5EF9EF892E66AAE5AFE52AA7E0DFE6181A0565CA6FC3FA284DA2DD4F6FE76C5F3C89C38F8C635AAE6B006829BCA1EFAE1C06E35446AF3D64009BDD36C17E5B12B5A03A64E6BC2E83BBF6E6C3785933564343950D229072F11092DDF65DD267C9685574D6D8AD15DA4B9C835164E95215045F7BCDC7315374289AF7EB80D538F6484F5BCEDDB3AAFAF69E1A74B177DE4FFC6A869B9BD98F7A3E7109C9DEB78898FE57BBBBEDA72678E7035EB555478BA70E405BF2D3D8563B3AC065627BE1F4419E716A62095E6A7C5A54B22327ADA84530EB5761287967E6D6135F523F01C20349E337AEE6AB7D57379C4E919CDABCC46326E09EE6A254C08440713FE744CEE9BD8773783F27C28F657F277FF4D96FD0A1E0842529D1A55D1120E0B0087DECC8244A655C43D33019A9BFD54ABB232739A6D21DB35D8DB48B8F854E82FEB295005F55D9626532A8611AF392B67B0191530FC64422E02F9B99BB0E337C663230B5D7C92CC34EC68ABD6D9A32657247D4F4E90139DE57CBB0CA2AD179F75E244AD5B4D6A4A21179D5F423A125F3A52DC6E7E99959F3E3DAEF1C56EA39ACCAEE0B4E0EF1549763CEC5E1A138CE4A2B1375A370E04259E67ACA9E833C2D969934F9A494E03F10F3B843C1A24615BBDCD322DCD2E633960393DFAAC490E69ED03E9DA0E748EE1C30683034389D6291D6DF8ABEEB363F5323A20B8E09715EF0B406963FBD178D5F46954B356BF20B90C670F7946516A7EBDF67381BF26E5AE7AB0BB69084B3663E980F2C0F8E5180AF4897C6A0DC2DD052417CA772DB1F48F1336B49345759677AB31980F037FC4B6EB7546942659C5BB685FB2C862C7CA37505BFD34DDF9AE301BD9296F98C24E110E410068916F98D5B1F320D7D29B125FA3601A77DEC33458BE0875ECF4049996544D2A5B35C628CEBAF0370A8F8502FD349A3C431D4D8ED56281184723B569EB08A904CDE35647929AE39E6A112365058D618CD44DA7685D331B7A16AF87D735C6766E47EB49F2D93E05E9F0936E923AADD01DE901B70555FA8E4E16970D4272B29CBC34C1E3B57ACD0366DA6B3D0BE72DB205F8BA635F0B32A3A38B44E257382665C354DD0182C0B3956042A87F6F98ADC5A2E1E7CE21A4E21C8750913DC0FC955F2E482D41DB96C35DFFA5417233179EA6245BC10B69050B4074847C89DC5E8AF80747E9B4A44AD7ACD06D6D051A3EB7B0CB3D8383950BE581DA314518C85B9E5E727FD3136C7A1E5B35DAB57F4B6331F565C66A9753743C93FA31E8BED38A489B16ED62FAF78FE5D69FDAF311A1CB7FA4AA4F0F1E56E3797802AC6F2885CD7A1D38B2C944C47F4F1D937EC11DED2DC2D8893A651D1144629781BF77E94DBAFAB247B4955408FD4983CF62F106D93D49738DBA52AED82FF67A984C749C04CC1383DE98C0AFC8457B9B134B18084549B12F7C50949FC2E5C136EF2CD2A05B81EE1DADCA5658873E65D09E0DE3F6CCF51DC6EC5157EAA10BE575101D83614A4B679B196D19F351B4727DC4B67C5E32843A4A2FB41AD38741847F"""), + TestUtils.hexDecode(""" +7C29C0B8E2A111F457E2384845E7698DE4BC9BAEF093F15EB03828664AD31C387B247A525623282460D60290FC479A928024CF62571A57F77B17DB0AC572CB59723490DF79E9B1B31EF2C9488B6D758C43EDD9162D8F6C0B03F43B08D646172A1F8DFD71D4DD805A3AFCF1C4265BEBB71FB251DC9DEAE670A664BDF943ECB00FB7EFA37624953F94CA760013FF1270C1EE7FF58756CE19C204220713724AD03B10F1D6961CDA361539A8AAB6ADEA92AD782F441428C0018D85C0505BAA793C752DADFE92BFE8F033931D47575C9F83547DB18DAEC0FEE90E83967E0D0DC93281000755303F0F5F05DE041211CF842404CD5E24DDFA3C7C83DE3EA21EEECE37A52E16DC80A350B3A18E88EB3C81C74D25B56CDB446F6198DC88F981F2B1ED8DC94194D81CAAD971A9A3933E9319047C5F31530C7C98793A0633875A14FA5635CD1B0441FE267E79C1E874BEA968CB63E20E7C48E7BAA9CE8393FF9A239B5A1D613DA65F7DE78BDB793AC72566FDCD06CDAAF56E18B773737A82298902F7B4890EDABB766E990ED87C94005A2E2450AC1D0192D72468F81DB414F88CBF07707A95F549B7A9EA0760821AD710D52787730EE8917272497E5891656176F991F254A5D582B5975F95AF740421A3C18A82158AF11DB15C154F17ABE1163F997C64A3BD989A573D12642B9AEE87C1612A39A8A4FAF25E35AFED3F2DBFC8FC8A2F9DFBC683CDFA3227107C50526149557CD773DDA16E36782A278A93CD7F4D8FB47DFC37DC3E389D164913316A885C3A800DAD0C57B1082BD4D804BB6A117C3B41E7D8AE9CC9622AE3CA8EAA9A0B502FE3F5A449BA8E768D2C98013F681C68A5F4AD3CBBB83F302457679BCD3F35C4D6176DD8D2B670E87EA291EDCCEEB9917F98CDDF5EE1689DBBC85BBAA30D191F1965EFF8FA9B0073D30B1E2456FAF880110BA9E75E4E29C6106874D32944F49DC7E7E7C56ECB9D287F2C2E87A779052F9B84FF97AAE007012A5EC497C4809F0193C69E5B29940510A354C866505424D4FF3853C94687636543115A73DC407C47927EDBCC4E0567EF4E451F0E464A1385D2A0D740C7327F6E92EC6091845356C2620EB163D9F774D7781BFBC6F6F652A4A2DEC73203DF5643E1B4C3C3DCDF0B4A0B160598EFB56499D2DB1F1E76612356AF3D708F9D61D968A6A0193D9146B2983972271A4C02E2136E6593DC47FDE4FAF2540A8F7744BC3230529AD1C9D2FF65B7671B5A5B16AABACDE8D45A940ABA4171E21090AC6AFF54CD8230F7BCAFFC42C028E6023E55DD02E4B7F976998AB5614A5681C615BF8E9E6959B038188F71C75F6DE44A6B0498F2A9254F3B0968AE7DBB49872D775CB0A5725206D648862734F202DF470770AAD184F822C56400F16F30F8BE40C463CA3EB5ECBB15D51CEBCCEAB43BFAD7DE7679894B90419B65912D67DCF2335212E82EFDB6267EEA331C1439BE2AF62E584C222C1052AD91C7F5DB6AA649F230248A14AA6A532401A28ADCF822089140FCD3B1CF2358DC26939850DB2721750F1537424F6BF2020A1B4684ED79402917D1028C1B59076867DA809D6C5D3F47277755384C20624388EF0AD68BBFB6A63005AD1B6E48ED654E8362B2AF7BF114F2D144A420712FC4EC71D408BE55EBCA8C2F185E7132196B1B76AA7BE44EB55DF7C82C768943D649631E4D87B408DCF8FE470164D9E8DD1F48CEE7F6BA93E239F889119A4DEA118D93F1474E516139036D640EC788AEE708637A619BD1693BAB6C9EE9EE0C495C0D0F8912C0F14199AA69B960F53E4FD8E2771DE4AAF72117A5B2388FEA0CA3BDCD594D1760905F26482459BDE80EEDE3FC89F592CA16B65B27E9A21F1789BD0327A26EE2224C61D80AE8FA6053480048D15019A80FCB5F3B3C6F64C168690E4384AC05E856BF341531045D2952F2CA8BAA0B8926CC41AF2D8BC5A1576292DD67114D521DD4AB535A77E5E9BEF8EA01DDC7C65446D11F90D6CADA94AA1AACFB1BC3551353D09252FE515A465C1879071F6FBB035DADA0BD25A022B026AAA5B5BD420237FF097099CA2402E68E4530F97A003E50CF693D1DFB551DC4695C760138E88B8D11F3075DBF8A6D9BCB9B1242648C0C9DABDD9D49CF132B0766302437C0CD81A0889585869DE92E6CB30C31265C84F58E9437CEBA891422967AA546EEF720A8FCC16EC7591AA0D47998275DF1AAA5ACAD1E1C5868CA430F4FEFA0277262C69311FEDBCC083114AAEC9F99FD98631137A117A9B48B32A6D88E76F96DC58D741395BFC102E147C456D3A78A0FA3D186485D65B4E6755B53D301BD13CC88E75277AF3CCF1EAC6E9C56FE1F10DE05A796A14381551705234F65DD6E717E9EC275E38690B73973C9CAB27DB909C5C13041723BB18EFECAD808667643E87620191008E4D10F471AD153D27F1FF00D8AC6A8C5E59197AECA5AB496D8D10BC79C49D16DC7948C6AF62703D36059587F6EE038820A84C0F287D79C713B066E1DA5B32BD89E5FEEC248B34AA5841E8666CBF09C47EFB17BC82170CCB557D41D40CC87F2E6C0246F0B272733854CE162538DF34559473BA5979AEBFC0D6A16EA7B399687E672145A1149E382954815B41E7E37CC415057D7536E65FA1A35B8EFAABC7B9B0000E08B593496B01E8F14FC950632C659C0A7F7D59787C7FE6E8FA7FA0211A945ABBA5044918CE8482C6EDB366368A9DDB2F2BB66C146BB50251CE61DDEDD8D6A4A60FEAF0F794B7B0DB91C52D7ED1A54AC85D7907BF3A5A96A60BDDD08F60148C0B3237DBD56628982375A67F025B0E3F9EE13DF254E1D6DDDBB057203CEB267200C7788D01342C064FDDE996183646FD3C1ABBA5D2155383CF391FF16C78660D0BBEB549483A4A4A971017A8659616FBB1C3A8A2E83230B610C0C74B8EB32667765F3C2F31F8C0D4BDA3D812DB64448684AEB482DFEC5C37EDE742091EF7EE6F22E31CBA2C9B9A6656888F446A1E9D52D9E6437D22594A830958CACC6F175D4CE8423178B71E7CC81BD6DC2A7F6580A8A3A1207C34D6A1646BC3D89953A63D22A30EB9FAC74103FA527843D3BDA656D1F22E729C3A004B923D08C9CB18CF406FAA89D0D63782C7264D5A8C8078EE6D259EE168A415E7BC83E4F17D9E674154DF08CCB21ADBF5B35AC28883F6943083AA97210C6DAE492C6CA4ACCBFADD99AED15110B10C9904469B4F06ED32546130B0EC4B281622A5EFC9C94B1F2280F251AFCAE857C4E17FF5CF472F038E02E5B7B3CF5CFD2F3969B9B8D5A27C8EC38DCA4284F0280C24F01DD97A618FDC5EB57C45D9E2A05B44E69FE2E47CB50F596030C70B62437F2B91A67FB84205D95CAE259AB1D5FF0454C5B4D87F439DCB7FC62B704ADC7A84502E1BD8E6F52109BF0F36824834D574E07B9375E693AD477A9D74E94BC4E883206DCF875AEF7FE84B9B7C1C9B1858E4BF6735235FAAE21FA566C866ED7C952B1BC19A911984EC25AEE310D8A342AE32F46255E0E00444CB0EE90C37152EDB6C741F5F394B5D47154825279465F0F8B19DDD85B8D9194A7AFAE5FE609A245AD68786C9AC044C008A1B3EFA3A8F4FA0FD49A65B6FF562F33DCB63754BE76244326FB6E416EE3267F93D7B2BDC4705EE7021D5D2EE66BA8D7B9DA7EE6C354E05470B31406DCFD2C32C94C22A72DE90E5A9DFBA99ECA95F73A014A3E9B15EFCBB67FDFA6D3CAFBE3ABBB28C4DEA6AA21F87693D68F0A60331786DE02BFA9E85A8D2AC8524EE184EE738BB3FEFEAD7E19030AE883707DF67ED12E8757B86E6E5FBA26715DBFAE2BE0F90453868931629FDE97712E08A280FF8888007AC27DF2C7113C30604C5DB17538F026F17C7F07D2A94AD5AB367F9CEA87BDBA712363D11FF5CF0590030BE9B342A7ADA48C08BC42F923DE939DE79616CD346B3511F41CE695B3F939C101F687DE7292CC96691EF3F3CB653F4A67D2EE09C791F993C726D574440EABFBB00E5E6328FA70D69FDD5F2EFFFD37C9902AA45EF4E9D06059B0D8E3686C74C94CF2F0032ECF740B31E3F297F15343A0093EE0B8D7F8EDA1118D329D05A1B992755181429D410771E37B56E28AE2ED8C4DDE8422FFE91ACE348E443640578687C57D79DFDF917F8E60E0A2F1C6223056C373F58C297F0FEE3060D31DCF6851856D1D05BB38B1FF426BADA10FD84B2E08AC149F91DDF4A5CB38B290DED4EA3B02EF7A3DF42BDC6B6205D281CE4A48A1C13FA8080B6B4100AA123097A4140415EC7CEC57790D6EB0B4200AD3DD9FB7FBD056A5E3E9D7B7EF47F44A63DC908B6DD8B020854618F7662391DFC35A88F4F5750D282F81DDC50D0132707174914293E3655BD2942C09F88627C0AFE4B921B766BEF41E246FD23482B5B14F117E8EE340C47C7C405BB3692C4C9E541148C2B38281EF0274835860E19C2D48953545247BD1F7A76CA43956C069A17CCFB4D0B0FD478556A209B5376BE9207AB174D2CEC96E09E1F8C0FA07D8920B2ABAC3490216DEBC67030E9285B3EF6767AB11E8CC935C4019B7E68FB9AF8864358E6927D350CC8B9A40662A0987C1C8877AA9903CC89A93E1979ACFA279FCCD2E171A467B76E1103C4EB166273ED7B4878908B67DB77C4FD4E49DB46109DA4BA78D69E03B48518F302647B8186F787F4CFCD87CC5A45B98F7558ECD0612378306C9D69FBE23B06005CD5AD84F73A563B1A3C7988CE0157D2D2703ECA8575D8BFF972CBED32A231395655DDB2188BFFB413624639D361B3388A9C9E13645C563A87C610F6FE79AD50765CFA8149E27F7083A316EBA050860A69BA56D002A78640D71794980C83573A5DE69A697C2CF2E17C90BAFAAD3D421C6E1D8A55B3FB4700B666AE3CC3EC114E9DB428F27CE427E4101ADB49B84CA7855458841DD1F4FE76D9074D940102FC47EA633744C2A664E22B5C5AA2721017F3FAAF4FB033FBB1D508EB98E1D643406ABD4D69C030A2349408C80993D9F75271F913D7417DA995443377E6F73A7DBA24E034A9C4820117D1F0BD69C93FF55CFFD2D36F8078209F5711FBD1587435517291498926E7354558945F721D00A73014C06B2C9BF04B7E695B9109D769BC2172CA7A70700A1D5AFF6F5FCBE699FAE81BC34B0495A82BED01B983444224B4B860360C07F8C3035FC4F0C4B7DD4D37ECAFD32E8C121C677ED263338359E25BC4173D191E869ACB4A5F6D20FD16FE50454CDD269DF8CBE5795482A2B40D52BCE5FDEBA62D9274C9C67127580795BC01752740E606D849AFCD6ABB8340613C61A764B6B92863779622E40EE7A8994034E7D303F07EFA11ACB70419A53897ADD558CFE157CAA3D47917CFE0287500B3D70FE42AFE36853188BC815CFCEC9F56030C83E85C60401912C14A75A082DE2E0400F6348EAABA59312C51A7E3B6A5B39D606306A304B4DD3472C5B89FC65DDA54650392A02CC6761336FD114D848BD889DA4BFE6D32931793A6515510CD802E3D9F2C6F8F2F9DD96ED039462C587395C7E6861FF48B7980D492C23E0635464C7D1969C12A43BF0FFA3089E6B367AA65D4678A571A0D47A75056B34E3F8819F8B6ECBDD6BE580D423D902D3C22D9D787E0F1B6202DFD392AE028292795FCA0177CBCB09AFF8B579A87A854432827CF797E494ADF9F96A56777AD6215F284EA91D35563F25355D12BD155C6C364B0C8423E1BBC809E736CE0BF03E0C0B728F04E6BC8F3F07A0D952AC9D9530C77547B687E193EE2D3565AC755DDFFE880AB0524624E17E019466B7D0E8FD6E94AC2BEBEFC617BCC5D529C83A90D36D57A93BAA0C2ADCF360377C9E9D58C456FE9F3D49CA37A8C3B5BC7C231842B57D320310943FFC0ED2F5F622988ACC7842F8410BEF0E0671673E7BA61AFCD2EA83CF066A169BBD97098F4B4F3C9FE73F5CD779F502C584849D1AAB52D7059D1D4432C27FC9284FBBEE43D07493A38B139152ACB71A171D454FCF936656ABDBDA03DEF3C7B27891088F940C200AD454308001FEB2DFA0FC38FA74F85A30DF4FFA64DB48E7D40C158F058B58174F18BA482AC445A6A63FB54CC6C7D4C8089794E8AB5B38C41C7FF4C6A8A5F294EDC3FFCE3C01F2C5C7FB569CA06567C8D3BD34F82046DB4EE7F7491D890DA1FDDC55B12D90A7853D8FB52E86AA1FBC669C7ED349A2CEEA9EF18F76C23E817AF58101BC5CCB0346A607D6C60BE5CCDE5DB9889E040223FE98B17D31D64E8C1456C01353887D75EE3B82D66CA0679B1C2366C44E52D73B09D48A39D1BA3FC87D73772DA601EF442208DB763F0BF888D28338709FCB008B83671442CD9F7ECAB2C1E26428391E559306904FDE5BA21E1757D94F84F18A5FD8A067C556834AB257B9D2E1290FE0ABD3BD622A2AD92BEB2C6BC61852D58384A20B7409E4F212F630BB280A46CF89DD702B2508752D6A4DA94BB769797B6E7FC318B0B3ED50D7F8C5D8579526D536E4D43F93C055479D53BF6159BCEAD8CE87504EDF7DB35E1D03EC7B4F13802AAE0207A2414802BECEA39664110A54C37415EBD7BFD5D73E871587967F24EA34B7D06CAD805EEDB95F1023B7BC3A74A59A6C9F3A4737FA1BB087012E0162CFF15A539E86AFEE30144F320FBAF088C6884489F84F16458755561C9CB0723CEB6ECB134083C3B82E93BBB57FCE8D51374D38746BECD09A059AD6623EDE82EBCACE009C0C27D5FFFCAF76C9E91BDF5EB895FA1E9C3C0AEC0BD73B1582C067A45CA5D15E2D45E7316CD4B176D9DC7241B05922A682DF919B2D2DE2F45942D3AE254FA55C5D90B8DA3C7DFE2DD8381AEDCC9558566E8DF302022FEFE51F23AF6A018AAEF3C93FD608B0903376E193CB1C13021808ACD538D3426F9B3399686B6FF4DFC0A4552DEFE49D042BA76136719D62884D8B93A349C22E0320B823740DDB3794AD53312DA5608DABACF69767D76327BEA7A644A304A132F2D2FA8E7C8F4AFAC30E389A995C0A2F912E98447CB400FEAE35B3BE089F46CD48EC8E38D4F2BB44F1734C67D5125D7266AEE3E9D1E91F800ACF8038D43B6E10750DADF6CF70DE75176A2E9C340BCD2F6D87F976AFBCDAF5E35DA9B268D3AE1F0F8172A342CAF9602593A5ACDE03DDB482E80B825A7E91E8B0EFC1C8D00309BD170D9F12BF5017780A54F440A58BE4A5257AB67190C62DAF9332F3594303B419D44A38C3A8032E38599B49872D241AA44905CC851DDD0750D04815ED88711353DC2264C0302DAAF2FFD34E9716FDF8A81F7CCB5757913B380A68F153F62E0BA8335F8525CC3A20145C2416581612B9C29C0B1B941946B2624731FA50420716162C64AACFBF94B43B10E59E0AF3836A05B9335B0C44370CDD2E45BA817631FAFA2E0ADC801772F6F71860CC2623E1A802B370823D02442108E5C142B68CCC9CDD0BC2EB9B861D763C715D516540F19E70FB474E120F06BC19A6629E8DAF67556AC60D17C252A44901839143BE5EC76B834FF11DE13762EB23843D3FCF1FF9CEB41CB02DAC74ED6219288575FA294157E532BD877D1B711AF3B98CB0B4BD7286F88C6C00B6AD9E40D66F38525156A4AF35F2FD42A5F25A201C66DA4AB5C4D1517BD6CC9FD9764AE2756379D73C8D81CD044174860FEE5DC42B4576008F13A3504674E0D224A9F1AA780C3003B7856692676A5E581418C65BA9F049CA20C3EFA566315DA220E837639A899ED54A07B5741097C47FB90A81A41700BB5C0D8C3317E27A0A6CFA77292BE9186396BCDE5C654C565754DAD120719E571A4A14207CFD205BB4A66C02CB68EB9E50DA7B1FFC324AD07D8A8A54729621776FC5DF15CA39F3DEB6B810A735CAE0E1A84C6842E80D1CF95FDF5A6FDCD613C54DA1CCAB4994EBB81C632D192CA9AFD7FA662A865C6F193B7029A9B6F21041E3D13D50E5A1DA47D3D3C4B101488D2308954C801DBAE5029E866E869167BE7DCE6476A64FB245247A84E46B5F0D9FA9F7BB10756FDEA659788C032AC654CBB83F23BEA1F285DE190BBB5EC4135E8FA1B134DB5D1FFDA08C06682C2DCC51E0D848F8CAEEAF51DED21830730F6BACC2A4BACF7BA62D14B009116EF2D157F64A7ECBC971D50349712DDB0871D007B2FBF83A832416CFABA2B9CECD37207EB9DB8A017AC266A5FC28DFE64B52D0CD7FD7498F718B32804CF98D2F17D22C2957782DD83F4FDEFC8A6AC5B6A562C939D2D0A0FA6078F7E6B4C95159BEF010C1DF8448158BA29E1FD1AA076972E64A9D534B1F27930BADA08EB87BDE6FB0A691D4379DF0001D84F2F833050E18869F2FA7C00A6481E4F87C75483310949653D6B91FEF1116F25E5EB0A10C8C8723E9C1C80F75C2875FB0C448B3E25E7B359304C08C310148683E1D8391C432A8413057A7AF45289B1363EB203779550FE1F074D3B4CDB77B90700E3710D6EB4BD1FCC209F2406CAA67B98E44AC91B876762D597D0F03A404394AE81BEF8F54A1A898B2F0F0CC3D3B6D84D759D1F1C5788BFDC7657794E384ECB2D5307CD92F3E135F35720A44743D93D111F38791B60E7A64F51ECD6801DE0ABC356409D00D7F785EEB88FF3FDC801C94CD7972EE402217DF018958A79DFEE835B2E7C591D2604B83E2C8B3CEED7BED4DC66B66EA13BDA4FBF5DC3158035A279F57ECBBCACEE3FF346386ABE41D0DBB32E15B02C49D3F216DB19474D295AE0A8DADD1DBA9AECFA9C92F0429352B558F69AFC7070DE8D47032956A9978AC2F388DBBD63AAD776BFAE969EB990E72B7D74A0D2002CD3CC664E77E52"""), + TestUtils.hexDecode(""" +81D31B99FCF0F04C0B2292A8CF472AAE17A659C205B067FCDF9FB4158C42955886D10F4BE022BC564230D2CB21D9023DE837E9ACECE2AA7EFD77E8335367E9F43A4D4526F36F336293FD0D372E81669B04DFB4ADF2091D18C1B2649B751E1877BF3AE489862C22108B02242EFA218828F53B317CB6537B2794E9559D2F93E3BA9ECE302BA948DC7C6596FE4BABDC3CEFB7F750C8B4D041204AC0F185CCB264A76F81A1783FAB19EA236D41842D9DDFBD2028DB890A652FE07836FAA7312A287A920543B8C393000E03F82FB712391915D75DC5825D9494C6E64122202D002BF7AFC234B334B12C164911D63333A2060B8D44DEB4B7E1B3E24F8EF98C09872AE4BECEE4561316B16A90507B25A20769A7CC25DAE276BEF51364499020ACFF97E871AFBBD68854CDEA120840FA1BDC1AD62283159E19938BAE5B2CAC8A607EB2ACD1B77FCFACC7981E5DAEBA3986B2E918768204D2C0B61914FC6C14A5C36090E52084AE245D9C6082FB8C3B5FDBEEA0CB779A656C180A01C0F188C2B4C11010B562711C5A4F10CCC39BCF5F09509BAF83D98C61E3A35FD7F483342115D41D8DB382E7E5D161711B8F718A2730D73ED7EED07AE04313F3D29D7FD68A92A0706936565924473CFA0125CDB2A2E22238F28ABECFBC0BF8F5E6852E45F24A55E54B2F26C5B9D97A3FFD4CCB09AD244D2D0072C575CD59D01EAD49A55FC2AC8857375ED477BD9287AB0F03E83BB29F19A6C1FB8A6D4B510A55C57ADA1B108785A16C52C71549162B7ED916B8309EE880B9B203F8E24B16E3CB4C774353D9CC9AA100BA200F5D197640DF6E0C0FEB9361B6E59481CE285C3CF2A54489A48B568D115FDC3B182D8341AEC078BEB288F0916C651BAE7ECB5EF165686819CFF2516AA90FFE3FA621D24F43917C218319456D58B5EB1F00437CFDBB66266C15B85CF5C28B29B1C2877F551E5A0B3FDB4852AA17B83D93183E82280AE94DF3136A82BB09D21DA75C6228DFA56AC2E538050B1155DE4133B40EAF22C63DF128E5324B4DC3FDE208ED528D4772C1ECBA1D11107CC3B8258F2BFB9CAEBDDE1B808D1F909D834D3ABDB08A2129B15A81DD01B82CA4303902AAFC1FE21B7AEEFCA8AF1167205142C65B41A8124C8E2FB6978BCCEAEEB8C701A97A311B87C9F46F6B23F8547EA728D46DD907DDA37FB143A191E66906B9715E6FB4D027A6F2B4DC94A38DAFB229642310FBB0CB28BB8415A9AB0B16E78F9F77737D0BC377F6E39AC869743067A7CC49A0E6974D86346BD5F91BC3D747A659F35FC133B02907E0E0442F948E2124AA25209E61F5209680B2E2D8DDBDB1A7BF0B8F1D17726D21C8730875255A401C381157EFF65CECD067F05EE56A9CA6986601A0FFBB473228EE9A64EF04196A78D4B5EC68F9A4FD438DB71E9A8FA5D0AC28D35087ADDDB4341C25AF1A0148D50C5041C87A508BC0894F073505880A550C17079B255C3BA5F58447C51603A599AA7EE288299551D339611935C5EA7F07D51BA76A0A9873635CD7AB35F8EB5A25A2B4453A2EE917E7103FF62D9476AA1B0C64777F4D05AAA5240DBA6956E1E1DE3C0EC1774DB2742D5DF8A6BA8E287631AB41B948954C594A63B7156218EDF19680D863879D79A8E58A1D5F975A35D589805B734C6ACD3E23EA920C8C1A9D8389B739CC3EC34776D2E816CAD3D6AE89B29CAD96D707E7D31BA731749BFAD67FA376E743920E119C11E29421ED033A1E73F2F522EC23D097830FA05CD62C432C70B10B9843CE2D49A544664EBD22213EACBD40922F1C3EE99A3E393CDB38DAAE81027F64FCF273846A9A789A76A50C79FA50A436D84FFF7DAA38DDBD5D40370B02ECB6F202261C5B284419F06CF4947A319753B1132017F46890A129E13DFC62DE2AD552F0931036F5296BF394311A7347702EB998A8DD6643EAEACEAD0DAD94225623F8652BEF131B9D4B0A6F5E7F4ADE344AA1D99C764DD9F9BDE6CC040FDA976BEFF40F8F4B0C5E6B20497E209F08290006DA5DD81AA46C5A0DB7EE7241E2C11CC411E4953942E2BE4CA6A61FF7C21DF482C8737012879C2B3AC90DA6EFC2F27B8507D4393D1647C4331F307C41038755386C53218818A255C2632A6DCB9F589BA53ABDBB4F7A9684D8C622F0B5DBDD8BBA59F92F5AAAEC121939263810535AA0D61A67A344B7B98568C8567ADA14B09BD6E021B1F8A0CF9B6DA08F5A1D66CD1CA8B0641FB300F11E3C4B7236135F4B01E5A50416B9BF3B7D88317315D35FF88A1663965CC183E4E34E4130C3AAE8DB39F3491D85B38C68C1F818DA553FFEA24595F5897071C84EE46FAA74FE240225EE1E325D3070665EA89F70BFD998F080C330E4759B4E79018DAB231BEE7BC73C20117E77A76BBEEDA3578CC2B26F03591E314B0FD26DB529BB0E6D747058DEA808B45064B832F3B1008F675CA2A92B5D38B464C5CDE4E570029891F83975E063EDC4A9B1A731C36B5EDA5E8F5D7ACE5F0A9F9BCBCDA5549203A9268B156DBA17E38BDC3D964CF11373DC778A24FC27613D39E4ED6311AD3E307BFFB3A1E45FA8BD2268C0B674368FC583489473AB3D4CE941177A3EBB06E6273F3C90FC5734514C4D4284954F5ECC0853523DCC3681257C1EB15B3F7AB7FE42D70899418D43B0198C971F9B1C069A2B443DA2C8E463CE510EC8B40A366B4DE82E2A206D7812A9EEC1AEDF669A66AA4F76364DF2167FF1416DB7710EEBDA11B0E8065E8D8BACE915C5282E742E0F1969E8A2B3FE29DF8A9034A2C2172B234E39957E5BF6DD55EEC3C4EA1C694827CDE661870E4C858FE91AAFABEE9E28AC3469B156DF911E00E31B44C2DBB43FAA617DE7782E14566DF4A744D8255BB741EF9C5842DC5AA275C73A7BBC254CF6E9CD1ABEF1AB5427CAE5FC4867BFD1D55478C29510493BF720C03256FD7F10B9095BE2AD621D8C2A6A667EA12DB50A09A4CDF0EC604ECF6F73A371374059F00FE8F84BEB0EE5E45ED467F44479E7761A20A06ECCF795017D46D4F554E73F3B79B4BD7DBF44217938BAB271A50F40871C6AB4E3158B9BD4B12861E9865926D87D79508AA23C085B616938970924DCE2F403F0297420B3B8DD6EC376600B1787AE8756B5CC414EE213DFDA291C4C94E4C36C9530305BA904EC6C61EE75E5C4EBCF557DCA2F01643403B5F25611CFBF3DB4D64AD5FAD075DF9BC3C317E0E4E6BC398C6EA02C58F4CBDAEEE9C66BE30A0BBD3F23F2C9528A54C080129633AADDAC8CC27CBEC1CCDA9D6C6A5D6E1C15F9F59AD01BF1003913185BF93B398BE28269D04383A3EE314D69A07AE8BC1E036DA3430CF772EC00C1AEF7D7B73CBD2D296BF0064A53C75C24ADA36D60ABC93CB271EA846C950BE8A58126DACC14295629E08403DFD9479AADE091C5C71BD234DF9F35B411CA6107724BC00E6837EED6526AB76D3E1AE0EE47FECC134AF895235F5E5C42EA2FA02381550240ECFB60AE9A37D77FE8A057F28711D25C0BEA2550B32EE8E926E539C499ACC781F9C3675E2D6A0D81E10FA653635CBCDC6686A8B842718E327A50CFC15E68DCDEF46FB3137A6F867AA63F97F489745E735B1215669DE7388AAE461A01F9DF1EC3DB31B7588D2A18650C60FB08CFB59F11283321E208823597E9AE5384755B1D106ACAE8A1C3151E9AF98E252A10F068BAF2B6116D37BCE404910DF63DA5891B00F5C8968D1EA70E54F1BF8E495707197B086D0392EEDE6AD60C5D4B9B108467435C9E0ACAC31A7E590D6A36B22EF1582FDEE7CE7E378C089AB6B8588325AAF6063D075005AE65B09929F41DD70B45B53A50C53D779BD37923213AA91A2AE0CB6D979588EE8D0DCD15E89929526574A5F8AA538CAADDDDA257F15B1294E6C85A2BC8DC3FE08F0D87963341D630238F25516990A79E27F2564439EED4C359FA83C3B7519928EE4268836D8D45DDBF62E4A9A0DBEC3470261EC5CAE7D0791C0E976C287340724D88E676B79B33A035D93C5BDBBBCFC0B6BAB952DF2A1A975C8CF7380C98AD3428C795AD3DFF70E63B5792F993AB4642BAFE4EA0771BFA24020F0D17A65E2E6F4F77A0801AD4C59FF3BF6C8F837A9430BD76CA46EF919CE743F685570B95667EEA2BE078AC45C46A54FF51D89E01A3726B23B5158C914B7B7E6B33AD8242B32514F251873DEC8FDC8BA607D156440326D4B5A5C5D676D0098A73E2A25C84F09111493727FE5D04C8B1FB9554AC71A3101E4CF44328553A23DE7BA2AD3C2FA9E9539DC47A58CE3CEB6E51F20C87AC6B2B14CF803DDC55A2E4B5D37A322A49FA38BE1B8A562BA7D314FBFE2BC2F58B04A3722EBE4E90FA3AFE1E80E4A5602BAFB9EC70739F3C6CC223B790C603FDCD188CC5CB3853DE9161A2EFA4CF3553BE3E23C386C6AD5BCBB7C7E497C30A0BF906B6E35585A69E327ED95D25107911902A3024C8B404034450B19254CBD832DE3E6FD46B3C2C602C5CF5A93D8E966DB63D111938C3BCA92D98D40B6B023DCE484E6E958EE5B2EB5AC0275824391F54E424F4C46B7E572F263E3B727E680556AEF3579E1AD6A0A43E764BF519711B60CB41FB2B85E34BC970BB3F98DACE7C8C1CF3F7254DB18B5DB18AAD3BE4B098911484D323427F8897CBFE41508DB7D501818EE418690134485A7DBDF4177C82A8CFDBF00000000000000000000000000000000000000000000000070C10121920""") + ), + new SigGenTestCase( + TestUtils.hexDecode(""" +8BE522B4E26631EBD3EE598B51CFB44CC1BCE4693E87BB76EF1B3DBFFC2762169025689CB13EC243DCDB536B5592EEBA1C9FF9D3162BA69C6C8445C55561A1BDD5DAA73A89A567873FEEA609BAF57AAC39B28C9EBF0DB477CFF938EA069ABAC4C134644525C179B81B69A61400FC131632F9389409EFB2DAD28347B6E9DBC50333478537234180110216703713666267407332042117167285231861686761441210671057343688833122224741016000006637280104670885810336860677835038360856671708501706307554348172486017384536610442118411464278512074201323472226152744306444283276447347407701534240455752818374185812151275332674783343510375328081677738151215483531374201701647010142025428074334717432007611874182847823042007734883110521200373123872310064376640658218187215811731015263781030348654333721768352476037106520857001157228053468718674413501266737641245546154041643241410501404202331467303823172738661537631326412120620535147074330475675267385001422576156865466315087754081624344371427068152314726807147108662880315204371650357351315826372165054702134004232425418802463830782403784381115563683351588142725828012118040033543738720206011440856443223582817212677271158874776566724605581535176600567745870103826357027573672874654377285231557526888232382155662024100070470030473727043681088635050714638852408071501850808072334837044106823681822708546272403308813276035006162706663335231815226264468284147368331351772564002623064338284502177258683770086532412113081781761102623530322278262028713438163458525017410602014725837473653188830358083120808408517263643700355801282287367867716818464087758327804282311206361315488554266670483253832715616163087472867038811365080210210237462345637776788467178451732482673618811867731483512036158155276111185373836686408334604023734277527830555045716275074072450108113304336412220335448801703313347077660185246467603160827384258610827786040227788358515276647106422642717356782036318301654248323637160122662488623837433257521667160846766448032050502541655122882873257375732786387202663327831411364154328330125623422884575626558307557713473653281565632108110853544346667326373177215875188880426237318478516556653371343073506220865321058770816713770387242752781203737258042510133435774100138260342867165785468418463736503584203606438045376454072080283716557465775044371518453200301088283116123715262003810840120273260615472300483880225411134203712750473122131553667405410661065824344668381608711445062248365838180162845050471728814083565587567605831314536481816873614238866537046728070145831458843035350778852054744668616084188465173248757877750305585700014307233313471722355344716426435421467416072887431031342617388642656086537070667614703030736144320532164032037145102411420812042582084583621280125835662622287314366231327281824842763423073663418856204041328103787818034738187202808802170064570017265628525011080747850142683771068084483578052255237768183672270141750243375737386806347814658588856114864068441442642086057430676653065800650578614485827138703358681848874801543363582130444225273015665625525034606073587464023021552772813060801271401248635688136384706617355687552587855202183037066184600586417823285581816200837FB03CD1DC103C479132483591620A98B17B885473B466814BC26F9F52D1AEDBB07645BFD9D05B02CF3D37CAEBCB8DCE34EF4185699343A4DC07D7EDBF603AF8D3F4C79EF169BDDF5A0647F9D71732FF65A8142780E5ED3EFDD4FF8D496EA676516529564718CB376D9A8C922E038D84995A29661A54184BD3A32D2B962B3DBC167524DE2C4B07765B6BC71CD4A5510C646EE0AB6892992E341EB0E54160A8939AAAC4C424BE9D7D1B4CC1FB50B5731950D19B96E5EBAB09398CE0E476AD189004829896E131F1C0231CFCB374895A47684F063B821FE0C8DCEE3B2BD5DCE499422AE0C668C267A65735F7A21106FB7A584CC2D89A097DBE549B3FB84AB8351B6A5F61ACA27B4C38C3755BF1ABE272030333F976296E482776FBAF8DAE13A0BCB7FB2992F74F178C4CDEACC841B74A1A7355F6E09B0F58F9DB2461E26CE24DE7F8FD744AECD3A6053C49C7F23C8F7F34B35DA5D60B16B81AC9C9FCC14A5DC5DDAACD10634929E6540A5AE3BBCF8BF7A04F1ED438CA536279B58FB02E1BD481D9CFB6189BEE8FED30D46AAEB34F7C4DF8781A38B2C40A7C7C27347DF54728AD8B91C4B09CF48ABC5B392DC723E95157F1BD0DE34A76ED0C89905F4333318267E4BA6EECB1FF87F8AB78AEFF5A494B7323B34A019440CDAD40165146370E23928BF831BF0DB4A498AD2FD15A15EFC1A56F656E8CB58E93CAF38EAC61F3E030EB00EB2F9627514349C583E1E2D93CDF6775DCB56517F92D89530D29A55DF17135AF8014C34645BBA8D9DB19F28064B55AF5520841E3DBEAB3FC4A4AEBDB1C431B2F7A83D4968F120DF098B808DCC94D29D26B8211E489B8EDBB87A4CEA0750296E802796D1647A97093F5988024F92FAA1E857AFCFD5E43021B0AA190DA6D581D654DEE6B9223A31BDF5CCFC54178AAE8F4F72B6D9B43D758F95DA0E4E6EDA271E2C03F1BEC31924B827D933BE6634AAB033AD507ABE2EF144A9629C2CADE0B491042AA23005A25B163990CAE9E3F03F2B994CD1CF70716C4B0D1472185AE2630DB3A5A6F154A60FB7340087C554011D95300323AB37681931724326309355E5E767BCEA044DBF1F2BD2645A62D68448C1E978FE1AEF1A178D743DAC130CF4912F16D113C229764562FB8EB2D8496C1891487FB9985208E2DAE8EFCA29DB5788D7A623856F14E41F3232B048C794500DD52836C45AB7CAE336BA311DE88E1F108242DAA925FCBF4801A7D5D400E9E98B15323E7AF30566FDFD118011D1A6C8F795BD263BF38CBD66EE93F0D7DA35C276EBB3C7A2A511AA852C35E31D0F7EA0620214618B92A48A50262107D875DB22A5E6B33B7189F6F6918E036FEA3E7A918F59046B9ADB01B074DAEB58A775E9CF56E5ECA2D521298B355A8FECF7F8EC1586AE72E3F8AF3578048D735D8D750A28EE0EDCA3E3FC303613177DC3F9DE2DD92C583AB35866EB46DB11A4EFEBACF3CA6B9F87CC6C7819CCA4A3E2B7D6C5E9A61FAB9185B91CB90631051CB64E61EAD02D98F4361CE57A5BB54A21FEFEDA318CE8F384464374C8F4FE706CE462A38A2A340ED573E5F703B418D1EE2F71539A1339FBF89A553D4E3D6E309FA50FA08F9A3CA504E8A0066E0AFBB5186E5B3E7418DB1F14E73FD481B984B50595BD937E5AF3F735BE67B2F8E3821EB5B28A4A60A27B382B2D4E84C20F6CAD8DF9A200F819A664B560086BFDE6E6C0F76A651E286C4B0DA27DF31CCCA6D2101501250F251EF1D034B256BDB4C75ACCDD7E4A31EB13A71CB44187314EF2576383BD8E8AF0594E9FECE0738544571D241F7C0EAE00D9EBEEE2B63BCDCE13037CFD515A63541D93B3592FA483CB4E4121893BA48608C109358DFBE317FC21724FFE6F862EB5687A76F56A5DAEB3AF226DA6E66EDD79294595A7BCB4A1FB4A54132B8CD7EE4FBE8658355DC420F08B4C9412CB0A4ACC24CA5E174316A8B5692CA8569ECDFCB37452A48ADE1956C52FDA1FB81F507CD8654A716AAD3C9D8416B99390A190BFAFDCE5D2F054952795E13639CC0D509557793E64C2FDBFE16B19F28A67FB0787229D5BBE5C7F85BFD2D257415C4E024D72E7F7598DB32E61F91FD68A8ADC38D558D2AB6C0F748E7D0EC81BC0B3ADCAE6F9D098A1F43C1450581C2B084DAA7850ED84C76812DD7EF285F6A530EF7DF815A4BC54947CBD146296D615F5147C38EB5CD2BA842F1261542B5D75A41370860E8EA881E2E88FEEB020AD954420AB03ADF14DCF24E62DDE75B19568F06D9D418AD71E881613CC755FF3D11BF3DB0C0DEF57AF0668FC38F3FC9256DFBE28BA606441837B5B0EFCFEC92E6F658908CB4326200175B7388411EAC613A3A75EF8A1F856F3BA32DC777C668228232CC04F4FE6E9089C8B3EB9B4A74A9D4740AC8F14B5FA73C43B3ECBF1D37B50F89855DF3E899A2B3D277E6C72D284E075C3FF09024C3E5FB3B7349656197A468E75047402ABAE724094CD92170F4809160190D1F3844A0200E42E80D27A1A67DE1E2B8F2E10FB0B076D7827C0116E6A2319D99CC38E53A14F4B31BD4B2BF694AFD629C0B12F41744905C24886F2A7D1C23B6E3141632E1F1088A85CD9F6AF9A005576593C9CF6CA4F94BBBFE860D4F1C2388EC112961636CCAEF5D84157F8001BD3C156BC93C5B2FAFCFBB67406201FDE2ED395A83117E2735373E07C0BBA838ED01246022DA61299F080588E58CFE32BA6B0FAE8BA9B4B7C3DAF383EC14335A4CCBB7B1F2CA795A06C02BE537FDB9DEE0B46D54408AE45FC77DD54EBD248623E403217DE8C67B1B3993B23E14C5043F310FD87410699FE704440EB35903ACAB6CCD515880244C184EE43BCA31EE2DEEA3A5454801EB3BCE0255E85F6EFA63877DF43116EB900523AC48F662E61F7971F00CC0EB44D1E6F33EAAE274B8A618B0C0A402DEA2BC835962EB45A60DBABF55744B890301AD6FB863E84513F7022D52C9ECD758261C58525BB806FEC444D7BDF7D02C25EF70F9CC429EC33C7516FC84281684F6A9D63909A6419EA190028F20E301A3230E5E7CA25E86509DE71962E7BD91025E18B194F07DA2D32424AA734E94D8AE3E6F2099802700F37DC29405D2B7BE4CBF35FD58EB6C8DC6EF969114CF45DFF7B12FEB37B16DA34D133A95A6309D1CF28CC96D8D3D581E95B2CF94E737A757A36FE40EB11AA0F3F913C1B7506C11F59E046082046C906F5F25F310DCA23442E8423BFA4C977295509D6C8B2FC30C282CB561C60D44177A1F73E01A8E5F267BCA5A5C652F09E16C35AFD2655AE0DC738D70571C4E48EF34DBE632346F804DFF6D565A542BCAD86D0F6E52FB7F9771E850A39786689E1DD8E463E75D64E41456DA22D44D1BEDD3629D0C93143A1D67718C2863CAB7B63A6823BA00A6BBAB6C6089982D780A944B7455148D7DF8976D31CD9D13FD39216182453CE38B140AD2B621A71390CBFBEFB55FD66B9CEDC8F68C9504C0F28DFE00315A591AE709DFE9511269917CB4A89F89DC1E4470A162F89C45561A362A7A02F5FB4A8D82317CF61B533243BA755418729"""), + TestUtils.hexDecode(""" +F55B1A381D9258CAC6DD7B5A57899867FB659A56873F31F815716075DBDD56D6D0D1480AE1242A17485AD259BDA2533CBECE28A906271A3E65FB5D48AAA124993738FDAAC65736230FA07EA27D96F372B90A16FF778D0ECD7C0F62174839B8C7FC50F0B0150D47D5CE9F3715F5964DC712A681626821EA27E912B80D2D04C346B67439CB5E06193B6D7F2161B4F8E0341D8F1C0C7F6E3B351C4EB62E48B555EF00EC0DD5CA6A572FB201D1A4570676A04000C382F4C332C34A0436B535CB3C3F2378682A982034E01211CFB23285395204ECF985F478686817A5F6FF4B694082B3032990597A8C3A85B7FB5C2C49694103811F754DF0434D09C1A5245BBA980D6EFCFC9BC63DD42362477537C6712ABDC952BAE377AE7EAF9FF0CE2E9EEE82FBEFC1CE56063293BE659624CCA0E23DD7EF4412DDB587CF3C5302CE5AFB39BA8613151A04491901DC30706B46EBD1B26D4ACA67587595100AC51770080FC32ED0DC109D525088A2579D8873C6929554C30BDD1E2A0A9797B1676A8CEB719F64A336FDDC3F95BD4A68F472F00C4778745203E1A7736764CEB94F33109AF197C98D94BA3F07E857A5B251858ED850E7E578057E833A2CF95D7505C4973B709CEE834A40F32CF07AD1861CD46CC4DAD37DE66F8037DF1B14CD88E62F81B9DEC286BE4968ABCDCE54F83C5E9E4FFA8144A5877D75FDF75A38ECF60DC180E9B72F256BCEEE087F5AFA5C6D779117070ADB4A671839E8032E55AC52E806C82AC16FCE76A659D6CBABBEC066782C4C068AD4FCD5EC425885A5CBC5A4BAB43D1A60D499C497A2DC06B136A971BE8ECEF3FA6606252029FE5B33661883608702542F7EF44720466D91FA1CFEEB9D8CEBBE4E252CBC096D99551BB90A0534D723B02146FEA94D1C1926221092B97F1A143E6B4D5A8438239B2E2842633A6D90A18DD67D05B2CB560BA8A964E0A49BC1987FF47895D664F92E27F8C90059C5C38B02B42D7A179A09B70023BF7D664A94F7289B29FEF89356BB51959FBB82562F6827CA2A3892E934A9F271282C204BC3C6B34C57882EEB552DEDC0644B43FB28284FDFC82A1148447F2457E94EC0437CB5E0E3B6AB7F7E48F0F53C80D7695801DBC0E96F9C00A4A96AF8D60676DC4A6A6D97CEA344D7E911BE7CC9CEBBB23C562BCEC6992AB1148384278D94913DC4BAC4F73313BF83CFA2591420B18429D1F88D68443B960F61A1AB8E2713794225DF2D4EF88CAACABF6F095DA88C52C011AB3A07D7B71CF209BC84DEDD7FF2D8FF02A0727196D50CFF6520602D9FCBE57F890D19EB7845C6529EE5CD98AA2FDFCF37FD7472D1491FC5267F1D7E6E91EE891D880D5EC20FFC761344BAB59A327F829ECFBF8E550208976BDCFB75BCD996599B68CB29B27D9EF68BC975DAE08AA121F4D95805EB89F2E8B2BFDC61058740881E9B403C54745CF6D4AA1747EBBA56473D00FCFC62B5F5DBA4209E0E7473A0A311619437D2DF22F1D5BABAE064970850CD51D4A62A51E9B3D3121B766632B18F8B7CDEF40B249812A6274D4C69C9EEC096044026022B1FF055A05B6BF1C919230723A952589F540E77D7D24A413F542E7E0D3F7F55B8B335CF3693603210E979718E8CBDF76CCED68396DEB561EE27E9008D7BDB428BB293E1A1BF2675D8A4568D3339682854BCF9E8820A084C94D78E5D0938D66676ACAAF7B411B466B6588E9E2B4A387D84F23963E252EF36A948F25625DCCE664281D76BB6EC1B8E20DB3A7140B194872DB439D89F18E74E1861E3CF9FD442F1CACF4FBFD16532BECBD97CC9A007978D17922A68CE98369240A8D1E8AAE6679CA5DB79D83EAC1A571D0871D5AA28F6EA4A8EB60770E8CC43A78E6BEBBD4FC63CAE26F297F1E21BCE999A509BDCDD20AC938E38702215C398726ABA5A7AB3F26DA34DB3CBD58A7882FED91C33803FAE62E9E69FAFBD698962F2C7226A641AA7B6CED1DA8A400992333EF5DAAC77B55F94D51F74226AC03F7ED8F3D567BEB678D98694E9E0D483815D080A70FCE76255C82FE020DDF32D4BB7B1AE0EC1679B3DAEF2C20FCD7D8F74F6FC684FB678F02DE6B53D03FB656A9B9562666F49797EC658C0E8ED14480A0532DB85478FC2AD1E21F8883F2EF3FD97DFD757D883C1507C44F812639711256EF56BF6F8FC4A73EC3AEA3099F6C2BE6B2380FF3AB7007129D4829103AFE70851917E02EC5F2117DE110FD8F4EA25FED6FBC24BA063B7ECF7585519132884FC12DE1BBEF498B92D6E2062F1A4F7C97FEE96BA87ABFAE76C50729AA68C8F374102B3CFBD69139491836E4587D0085F92FFE2A94B6A87AFE29C84D289293D9CB4A733F90389C96198E2250F5BDC83F123FCC4E42844DF74FCB65986CBAB77B692CA210AC22B5B56E30BEE2BDE84663B22507E00E0D066D5B1F5245EDFAC6D860D0493C218A541A1FCA4B48F1A916921153933383284BA268C3AB003CD58FA979A08BC48A57C755688B0859AF7F21061F9F1B7DA44088ECA4D393E8DFCCA52823FAB812AF36212CD137741C14F0860CBC7ACCE1FDA39431C32AFABB84989CEC971D4A257BDD70EC71192148824C17AF8F18816CA94C457E1023E01012A245F28FF6582C9015153DD7662E4321B465B33B1D5DCA9B1CE2FF49EA3A811B5852AF5C42FCE7FF42BCECD31C798C3B8F685AB50B68654192357CEE577F5CF1F85A50F269C28A1F2ABEA382AF5CD089C146B9473C8965A945091ECD1C02BDF64F9C3FFD035D8238AF974E7111BA4AB10288F105659C9E2847544FEC0B29B6692FB53CEA0DD312B24C1ED3CAA1BCFD94E529F6C27BDDBB7C764DC0161FCE578361E02E0F5F3FDB095B6CD311190466177A5FBA62BD18595DC49C29E8EC7E1F2F3FFCDF17D477F4AF8CA3EAC53B7018A026BC942EED87704108027753DF67BD36221E9121B49CD40E8EA7FA2D6961604BE0095099A4413DC11E93B4A876834776D144269BBBF8A9875648702B589ED4CCBAFDD726DE8E8A58AA5D1A6E142A470EC342BC3E2E1B49C7203F283E99E81E38F1D8D2CD820AC98D8244A705BFD9B67E771A0366C7C6958DCB6921A81C0C9D5152DA37CAA8CE18D6B97404B399052051D7343B3739610329A37B8BAAD173018708400AE02B8DB2A2414CD7DAF038F94714031B1D83A5A15DBA53585B606A13814F04FC925C3454E251CEECEABECD8CFBD6FC04F504508C04E25724807004612E2796987D34D04318F82F7E1FBA83A4DEE3C86FD1884B17E77231629F5D5D11CFDE976E639C60B436DD9D302C380E3654E671ED81D44FC595FA34EDF90710A6384BB62DE0D89B50C14A44215DD1121C602A79A003955D860C88470EFD320E8AFEEB114E547E50CE967572DF5A5C4DED09222FF7821F91598A0A9C41A731D64429AE7D9BCE1B4E90120BBF94EED78098C9EE30C38628297C86DF59930E72CA561A61B6EAE517DB39F5A61FBB8C1838E3ADAAB46187F0B5D09962A39955343631B74BBD17BB2E338E5FC8C43BF8B2DF3A78BED744A481A1D789721928962AF2B9E2187E6B52A19274EF68F329C83F42A28B49C447FE284A25B71FC95D9322E752E28C7B4B656A743CF6C56CEEB758E742CFBC4B8D8DE5465D63D3D5D6EE993A4C47AA72BF82126ED6C7423D3475AE098CE6A7E6DD6F3EFD654BFD5DC4414B8F23F9E29CB0D5DDFAA689BABC7B5A925AB19817226DCD242EE46B588D7CB8E88183CD87C6D06FA1A40915A3F19E2368CDD97A16ACC2DF4CBBC0B30C6289D7004A8B48EFE4186BC4D844EA01BA78E4D1F0CDD2648D0363CA73A19032A537F68E0AC01CE6701426A03E071A109D42EE5BF358445907E1D05761B8F41AC8A9CBE2657754A8C4D83A3516EA465D5AD57367BC58DC712A5C055F68D1CEAA494D9A845474F610BAAAA4CFC96EB51D41493930534D58533E20575B980F4379A80393DBF797969405D6A514AC0A9171B79D6EBC5B66ADED19821BFB090BF76FBF50CA6AE07CAAAFF584A7013A71D54A2B60678F6F02DA726E7448A2379C28BCE7DF968154CCD22F1CDDBF25D91C616234539731B8DF4F55E21F37B29BC77DB4BA802D9BE419ADC292105EAE58CC81A636D479B550D33D057B7AAAF28F743F7B8C17E26AB2A846AE08E804E5D4BAC09D11C736DB32F9DC9CEAD0442AB7B6AAA70633692959A36D6DAFACAF2D7027E5BF9562A93A1B35AEE5313C1E2015E65AB805850DCA7A65FFCAF14200E1EF0DD8F8F05A11126EB02C13FDE38F496E5EBFB09E9E2B4920E619A67517FA4749ACD8B0857C7EC5A6E94630CE3EA0841C64D2EB895A9EB7CE5E757F2FB80BB4F0FA429E779BBE314A491B2D45F9A79655396E70CCEB319C3B405C33BDC91EC2169C3A75C4F5CD7AE5AFD6CAF6C9F81A9223484E7A12512B600794351693E1111401F74E1439C99D77E8932E069193DF7562C79EEA22C41DEA4EAF9E93456378CDDD6C8AA97D8D69C222614E203B6A1FA6377A7A0CAEFE709C90CB91939BCFE926B35970B13A06FFECD44DD8A360AEB5D0432A532E8A3C275E1DC4A07D6A3E100B04AEDEF14A52C09AA90438D65C8E6141490BD1ABCAFDD5925ACB040A91A8E11D242521C1F00EDC14D62E1C6FCE721921DF42164B4B34203660DEF02677A6B8C564075865B030936F472CEFFB3446714AE18BA14A6E45247C9AE1F2836E2341B61940A63FCCFAAD809C84906FA0CB1863625E59B96CC2161A4715606DB12FE3E79C90B64CB9D3A93B451E1C746F6B820B4FB3B3521ADE56DF9D50136635F29EA908FFDB32C6582715B06487B391A36A6A7B96505FD8ECE767C38CA4D0F9599FDCC1BE27C9C60D9190139C4F02461A5C42310CBFD5CF506720C9A13067F83AA1FF66CDCDFDF59B673B6C1FB0301DB118F3F49D1BAB49069A9FBC2D653D390DAFC3CC5CB35F0E50EF4CA808DC69F0134E3EEE697597FE7E5C2A2CDC5ED4E81F344879A0536BE0076D7A351A199530C77C0AF25D5C7D5629641FC8A3567BCB1456C1AE1D216C1E408C3AD6CBC1629E14DD834819F94EE0D255AB1C61BC7C324445F67CB7BA0E5AC424EB9C3D5FABC47081752F98B0011AD389581B8C20333C2878367795E31F99FD2C082B04126A3A61273C94E894BA7ABD8C6FD743FB76CC4FFFBEA78A1CFBBD266DB4432ACEA74350AC06F2EC832BD71FB09481A045F7A17F22F9AB65CAE6782A2928147BCA3B521E001D4BACE5FF499B1462709525D64E72201D5620B5537DF7A3E8DBCCC6EB822129B7768469D18C891A60B948DE2C12F4E4DB574C6C8BC586A1B57E727853FBCDBB4EB148DB234D8759B2AC8ADA2FAD225B5420C2B93D7FEAF051B7B768E64BC6EB83688B5E7E59059E1079DC66C5D8696CE758B42AE75123CA0FB72438DB97D39F1340B2891A19A4084BAA1A5149FAA785F09300B9DADA3C45F19568226151382ADB16617D5E59FFE8029F0513A7156F67D9859A13C2BEA574BE10E319F1B69740CDB176A962810B8AA6C368805EFA56E4AF69E908A205DC41CFC3FE69E4A6BB7B1F541DFE0A0EC1B29E3C199EF07538BC8AD7B0BD31B6A4DBAF70B83443A9C6C06268F597A6D1BC50171ABF56D18BB277F83203BB671DE404FBC4DFC66EE8DD4D92FB1AB2ED20FE8E9327CB15CB90908F37171D10E759BB8D1BE2C895604F87E2307AF7720AF99F0552FB15229B0FE7B45A3005E6CB0DC88A6D15AC7C364189A84A6615A344FABF4D0DD82EAFD42892C86EFEE6E9F7C248462E4C6CCA369CED819AE94B3DC856A3412A0DB90353E6C6D9DFE31913C3249195A3EDF9F84BE94AC6EB82969AF272AB8802BA0E8967EC342834B8A38163C90431844DB073DEB60B388710FF880EFB8283648CDCD75615D35451D8AE4711C1D7DB1AA59675061004EF8164AF3B4095F0E2FFC5433BA41ED72AC2C683D3959C9D265C302E0FEE7258B7C870F62D40961AE5AC43D3BEF8241B38A574F75EC7CD608781EFC16B7B9D36C3844B6FBF477CAFBA155B91061"""), + TestUtils.hexDecode(""" +B3AAA36B5B5A4676F1DFEAAE36203D94EC2E2092F4D46070C5C03089AFE6F991B0AEA0528999A8151E95DAA67815DAE9F7C21956CC4AB73395EB4B87F82FF033BA5BBBA94E238F7B6C184B5F2B1098ADA6FCAB8CA0206DBB3BF6548F932E522D5E17B2EBAB6B4A0A2AB6D25E86A071EB858832C2B8D4D718FAF28220A9801583DDAE046314A9A8D02EB15611E74994E87D555EA1BC1D10DB200A385AF09D1DF4A8D460189EE7FBCAC70862816A41B307F6DD179D990BF03C634E103E37CD9E254AA378602DECB325919E6C528F90D1EFA69E1815F481F22A3D0E58C9AC8018350304B887AB7F5509545E35334349C910C4B7CA7841288879CDEF8F222DAE22D5E18589DA715A5E35CDBCC9E79D3B6F6151B8F5972631EE4F015ACE124311355EC29CD3D4B9AD445E4B88BB961F9DE36DB01B1725AC1F0215DF909AC68362ED611E9EEC491BC6C01B3CA43C0C517267FA44C43FD4F195FBEB882E09BC2A0E13AA71706298AB6655408E8B8BAB108F772B6054EC543EA36E9382CAACE0EB62A5653B43C6868FA8AA6129F902310C6BB228941FCE346586A40B156E8572F6AD4E300F74F6FCBB9691C351B7F5E9BBDD8C6187085193DED352EF786AD96525E3B73DEA31E5468C8101190F57B9952B4D8CE57A3CB1A89A91C766785D6987E90BDB809A32B8EE7BD284C95F32173FBC55AF1EE56110DB65C2D6DA456659BF0B54184C348E6FAB7C397FF05A182ADD25345CC5B3B40FDDDB65F107F1A5227D93D6CC4AC4ADAC5720E5D3D801342FD06916229C61581F39A7FB0903F90FAE6F7DCED0F0804E003E584B51520A7A8E4232368D7B555F5A5F4AEDC83C408696CE2122CE6C8D42EEF94C6F6FABF71B34321B3C457016BC576F01B94410742B52A60634B6F57427F9B7508BF9DFF7665B8D8DF8D4F5A4EEA53F9A7DAF5BE52353DF441CD839B846FCE51338B74AB01149667AF5A74C42C6D9B324BE5338C69FF350292EE69DFD42D8D186247EFBC72423DE170753392F9EE3A851FF2C01E3E34C399163BC611785303DCDB61894E6E32DC4287C87782EB136D1B865A7563426D23FB354D373869F0F13A058B2F626951A2C5F4BAD5A14FEECD94A76DB50C69F434064682509E46C71D5076F00BC058A89CB669E253FEBC72AB42BCBAB6851B5DF111A06381609DF87972EDBA0F9A77EC972923AD6F49CE0F52F3309BA7E614DF4C3424473EBEF40EF15588D728F7609C4C2D4C691E54A09E6AD00DFAC07E69358A5C01EE4B9383CCCDF8E8B7E14DEE51D8B3B966F2C1BF547E1C58756FEC20278A8C4547250129516EE0EC1CBCFAA8C3154AE3AD9135D15B957174C1F380509065B035B1807FBF48196801831736B168E009E023616A73E7D709579676B0BF19AFF259BDA7F1313A46F15526B5D1048D853FF83A6BCB6F446F18BDA693D38A313C445FEB6C5979AC2CDBB750C536076D0E8E7EB728C3F01F9E4498671A34909959EB82A974BDC0AE784B6B514BB435D2FFA7B85416E56A4610BA354C3FC1118BE292B6799D4EAC3719AB8EF6040BE4C6BA12AACD9BDDA672452A04432FB09447C6A125F6FC27A589D3DA986152A0C3CCB72AB00ACA16885CE3A2E7F596706C7A81060A29A3DE21170BCFB1F6029C859489D58EC47B78717705795D5EE92C3504F4B0A5EB542D24C9F4A07F5FBFA1F5159F845997138296A18F9BE82B7E756E075F60D794243606BF1ED443B207816C854291CF3E2085957D52D6991345AB1150D46E62C6FE96F802D21D2A15D1266973FBF540570F0564C97CAF5F54CDC812FCD5C21C8654193376EFDCB5E7A9CB60BA929E00C933B685B9A789787212D1DF26C8E87347C923523190C89C7B20320AB9C1004B8148080954CDC8BC5D2EA91724C4284C21A289324EBC3F41438336144D8C8BAF5476A9AE92B522F88759F2774D9ECDC52960FE0C1A20B32451F4E51A1E73029572CDFC5E6E6F6CE2C0A712D4C4A74A26D7D8A14CDE65A4D277F8617A9A8BEE3F5EACAC1226B0C1D73609CFA4C937FD4B133ABDBF5357A771D80502A46B57A430F6BE8746F67448634BA215C7452011A62AA480C6F2464B1DB9F2096DE42C5E2EA1CC50A460D88B5F10692D29D9BFD03B8B8743CD0500C61BB7F7DA4CE336D25E68BD9A37841F5558C67AE45E3FF719F70E3CCEBB0128AB619C23AF8D82CC7E43041E7F6270DD8946987A090955B30C6152B2EDEF4269732C0D89817B9BDE594AE9E44945F947BA87C769F7F632AD3BE05CA6A749999027172230A8A36571534D151E0A0E3B99968C47F8FA9FC2FF4703789A15B363D40F57F2FF7CD3202D98E47ED13BBEFA9DE66BCC5979D7A57C91EF186DF2F2C8F02B474624E8F4729653414F6DEC7F763165164944BF7E9876686233AEFFA733426D63A3C4D31A4DFE5A6A4BA49CE45F0C9B0D85ADD85DACB28D4B75779F8A14B415F478E84D48A797F0C2AEFF842FBCDEBF9B03EA1A48760461DCF60592D8876BD967A1018FD85BEE5A31112628A0C6ABE9135C43757C2F1F70CF69C6E34BD5327E43838C33A2E01CF017EFFBE6C5CD676B7C2EB4462CB8EC2DF4810B759B5660F221EB8AAFD11E816E4EAE234AB54A4BA67F26C5787952A9CAA9504A4F26194355EDD7D7CC0755E70DF38F323603E1CC8738306A4FCDB7E6E9C5AC26F70EDC1D714D80ADD9628D1CB0F50751FBD7C4B4FB9987756248F7A5460B7BD30982CF3E60EEB075DA4C2054EFB0ECF972E67CB8350A1B8A836E285680BF8B59989E0CC9B0CDACABD8D4527940ECFE45E00300871992C69F23BCB4BB5F79295FD520E4E7D89C448F2FFA69AA40590A11F7F856FFBD486B53334B6537568D43039EE2FFCC2A0A840A4BCE03BA507DFFB7CFEF8762B8FA40E48390C94F4DC6B74960BF9B67801F7C461DD9DB9377EEC32753555BDA4BB5043021DC9C4FA543AA3F58CEBD08003069A8698CABD428C091F0B06220708EFBAF640975E09A58D6CEA83A719E49E9053BC67923951C4117108EEEB2C0818D988FD73697D14C2145734D6C65E0688F4FB65C8725D58BCE41C152D292BF9EEFA242AB204C77D7BEB511E62E893E255FD4DBB7C537E79B2DF6A445CBF67DAE85F6686807B356B7DC2AEE18F92ADBCB5D7CC4C80BD2CC2FBC2FB06436B1B088938BC7C7022357F51EBFD466AAE707D75186DF4D50390B1A3BD4FDADDDAE17D17EC36961799621BCED05C06C142094DC22D8AE2C70D8A2503FD7AA71E08E9726E1FC486B97AD3F2C490AACC6361CEF13400D34502E0CC7187BF226F35C09B784F5432FC44E0E6A913FE34A3E11EF957E668381AE4024FE33C264004E36DE439194DC5961EF2B8CCBCF0A2DCFD77366649CD20D73AC577898D593C1F769858CA8467E00C783597A49A70320BD6EF3EC56BF7F5BE745204D6EEE2C702860D6A4E8AD77F5B23EC389CA800CB4DFF1DFC22E29C1F4599EF131F5B993B8F9256795033309F8F3B73DDBB3280BEB2582D81FB9466CA18C5A028BD09F90C4A1A725C10E49856E07C2EA752FD019E7F4AF0CDE66B9A2FB9E22F4C962B81BBCCD218E916FCFD83A5CA2BDC582D0B2090F2172F581200BD0122FF6EE52BDB61EDE5DAE73542AB3C38E85B8F871AB1FF6C5FDE0EFB25ECA17C1D6F6777F5F9020B1826F0E309FB7476967A317A7D7BBD9E4EFE871E80A55F267D6FA3CD631250B594ABA0EC0D28619DAD9DF904F46098B5935298CD0B37EE80A58FEF57284A4CD061E093840C9D4CAA6DC3D2C1AD09AF739905A4CCB12CDA458BC9ED96774F49C5F9A1C43781C2A08BC99C0884BFD9C25545CF6B9F0F343EA84E8270C97BC47D706BC56B8E39B0DDA66D7A9E130E572586B9F1715AC35A4DA378E7B10CC998021593DBFD027001D2288DA1A6D72D9A66AC8930317E5154CDEA34C87980F16D1FC4EA87FDA2D47267CD5330B39FE941886FF642EAB1953CCA30ED21279365844C4F5043205D482485E45FCB6E52AD8B31A7076BC96FD88583B34720106DE1158FABD0A4F4422FEAA65B1C828A3D4918A36A99D34B99B052C7EDE5A9F6EDD59E1FBD2B2A025DF5457A9A3641EE8F65C13E7969911F5AD7C520F3C9F7357BFF13626262340429AEA5DE00798D73FB517185B259DD44BE7AECA1187D14F161C0D68FD44A272C38EE1686FF56F55202283714B763833EAC7654D3485509BEA34A669333AE9DB252DF82BCBB65E85ABCFDB0B23FC44BF4527E9C123AD4CFEF148F49178984BBE8DEEBE0BCD4564A333310F8BFC436810BE3BE1349371F35DEFB9A95AF245D92EB0DE9E44230C85ED86280493715F540ED2146EB903ECFBDC1AB2BD66BA8744B983EFF9437673A1D32DEFFFEBC94FF3E46D25B3565B71D7428C1C9E28FE9E191B79B490654762994D98EA1F75808914FA6D93A1CD216D17CAD2DCC519104244E2E9EC3E607A84142528FADACCCC6AE316A8BD0818413BAF7A90535EC2CDFADE973B1044FEB5568748C1EF7A1DF8A35597D2C8D86A159A0C9B88572569C50820D9C85C8FF52C072A81B8684C4EFC7900048FEFF31B4D4F144264EF77488CF854523303E418A5C42A1A0AC90AC5B6D4E84B51C9EC73E2ADA8EE053E81D629F5A5EE992B86B7984DBF7FA031A6BADD3D6191E266872B6E0F4154B7080BFF2F500000000000000000000000000000000000000000000000002040A10181F""") + ), + new SigGenTestCase( + TestUtils.hexDecode(""" +0297C0FA60D16D4A0D17A019F55A3F08EDAE88B98ACC1C7DFEF6BD42ABC7F9B95BDFACCEE817B390524985E281177E1F58D0D332D88A53ECC69D36CD3F2CDB5DB5165C52C2CE37612A4CDD2B62BA83BD66684F96B835670FD22E8ED003408BF9D1F52D90CF1D2D3EAE66D7D85DE8FF119E46F27EB01A4A88666B02B2C5CD7ECC71475126233751606406113524782512715333860324438760638762734863482074003581724563351353138370627434260445637442177740371643224671617725441344250077330875181226586513706860871721017807300117550675284633706413607083013276585716370368050360711636355585577030632744062432341561238384284175207553145658474417404154724103855270733216724328004787058212163440458651245376828170458827746751653134524478840643478264478207475568815633525051308106624207867342115378165346422073070271412006802582227512715153203088321004847547556737460264581323568705360343334431146566351401314880877404717661204337656538731582228565331786427057033465157483413750216317745537626715720244052725853713888388134843772034588472347173687745730066205583284724450000625141552705674515631427087434751825444380103432251711865645505836042741704560123523466822474632315045847723202654748142365813273005127174240207784056454887672623315657661530444776343656142117642778181763467027344577108463016407222826446461136448285450720774714430371008081132006480153606526463888054500118888003781136213148822370121275828340188141732881861617164087530333608831350247480601478725271843745774177873867312067462502403637155718413362531502661247285480024810234235400373287583667573412665140207568763110311725216005676866080753252314482804083063666176263420837737160682227765684481183417033821367724774461317852010100623286300633771066431466481720800788057135404721823251208256681603522737022068184055137381511425223830770027241631858506536650561586474834248364664527764288258583362258253611711468120685118836063400130368635701515801213185810606620114471462062014451636631838874230368660332432366768312320537254065462521272660077350618508423570831123312654084175610472468372463383236355463060552050638703827717733247850374664833535811821007341633446035721564215452045174715401058443708781470787635660678122871062520772570612807708024277164210323003680110227842476577255318133076620664182015776421146370080642876232368544572781206873058413012137383478200823323051100107156883162232725863430855777107357615856648065557274370204175012652058202246626757621404800874450550038325336061484681482363078018181432130234117583142652832864715748075227663747166702378321453044770646634388835406301744345204662683538438062348531701370655844554268761343776785460263714566588627783555812231322607824008010540740805513544233266705274246487108817323774438713754288718083217056316548462085815377128322036330530628018007677542067157424064876784444558815064151587171085581181235145012554740075736440276116856220542332347645738730270817668064813705460748025865533377527104018483583800012175176185223246188313570514482238856512801400078072461421870713162071176227243553400204034625862157643623617203115234046563256232806750543822670848323427755448215870168576404750227120773663868780623554673551445E94254DE0F4BDB570C48E4A4B84D39B8B491B4B272EE7207E36529E757A3EA9B5276ACDFE4AEA3CC6A05CABA81A46731C132A2EBAAE20587477129304990899FA1D512C5CE65287A6F8C0B1C8C27B44C21E70BAF94607D74A425ECB282990C7C05C66413809E6FC4211DDCD4A3DBB34B55359C85CDA312B23FC57448C8886B74B9DE589433DF4647066A32C4ADAB91470151FA69CA74E696575AC9E666B94568C1932554DB63A48FA9A44E9A34B0FD6C006148ADF69409885A99E32AF63FEB3EE8B7E8E25D207BFDE31CF17C2257A6100112B0512BC42DE1D38A9A292723CFB7F4ADBFA97EC6DB138F916CB479BD30617C74872E5000DECDE34884086D2640BA4E26A21FE0FC02F13F029A317D2C28BCD5C88323BB73C41536393234015DAFC26AFCEE2C42D8641C0054C6F8BD69CCC8EE136DFC1432DBFF2FA5239E032DDEAEB6CE6741D24DD87ECAE126A7B54DB76E505F93A6352BF154259AB84E0B6B3268DB1EBA038849E3C1E1A638CBCCD8C255BBDCE05E5A12951BAE8EECB62C4D8F69F89AFD2E57A216BE5FE914E82FF2FDB8DC8180FF798979766F95E06DE29907EA2BBEB325E3794773E1A1647F196F2A0D35778B1AE8F34B02A9851D132A0B6C349B3718231BEFFAD69739BE1CA60F863A91CB312AB3D9C3EDBA8D2EB3DA894FCFD91ACD00F1211239CF8922C5F970352B754C92A1A69D3B0EB1B1207F1E02487EA2CA8D1FC41578566E6760B9F65A29B77ED07491D9AFCA386CAD30B940BE4237115B4B335B080B77956019FFE5407081981C1A62ABE21EB27E5A74318021DAC60F710B5C310EE59EF7C4065C5B97E44639A1736A644A32AD09535B94A9E26407BE3DADC4BF50D27576151BFC5A57179EDE6DE8BB2A8E83AA215FAA3EADA0993FF66F2569CB5446C73BF3C5451FD3A0498579D945F23A26980426A3B9E8AA23FD26F9651D1E06BA56DA1F85B7C4C9408A6F074062DCE52FBF9C6A8147F86B793D41C09E3FF4317D68DCF0BA7A1104B30A2930CD8E248D3DA02AA931F4A3A6E46E20BF4E9B3EF671E0D5CA23BEB7527DBF6E36D622356867A870EE5D36F1496357897772C89D1D2C11F8CAB88F26F7CA6C941190DDB06C57001B70534F1092E23D43AEEE40483E4D3C4286AB6F51E07AB71DD86008F5B0268D8F3507ACF6FAB2C2650F1B43EB4B3E32A959CA23B2C1EEF2646DEAA03A81042B20B9A03A0595C86C5D8D85DE2DC31900E983AE122DD679ADEA13AD7C1820EB1D35E2237EBFE5E00A5ABA5DCFEF82E52E8AF34993D30160FE3866856BCEF955EC731D99B1962181A31602FC7E6746F9869F747ABA49C1804D742D6B072CCFFDEFF827E9F66B533173743FAF5D88798698BC2466D0AFCE77BE660CED7B90B43E4C81ECD9FE5E3CF23B27AC363A964C1EB4D2B75A60D439B6CA95E2F9DDE270FD722D4E14199EA6A5EF69D2D59446E8F2C8BC072C1488FED4C7CCE0B547B70F629E70FF7EAC26A56DC35190019BC5A141F2850DA2FBB79C847C338350A72E556B349CD82C2562D93C273A62815F6E17CF7D731224F9B4F0CB1CA6FEBFA28707A26A37A1CD6CF8793E34FD55865969AE291A23929FBA90EA6645AF179D92D65198E30AD5D7FDDA597FC097A021DB3CB85E1196F76A17AE1C8B907056E7263924400105359DFE7099C4BF08425F68C513714114CE9BF6505D4AB1A4C31743C62E11AFDDE423C9C4394731B892373B156BF828978C17D833867AED249B609C4107A43158C2EF607789922B6F72AC827998F7738D662E9A15CA66A1200D7F6FC9D8523E4D40BC70D8DB762437800114A6BD2E58F841B53DB842D345969DC31A8003402E6C2BDBB8782CA5198170662662C3701AC0F6C7C9E35FCE3DB31D363C594C7E2C98206F280DBDA61503CEBC145F73EB541913007394767E8FA21548FEAE6F29E3CEDB09AD37200D082635B3D87CCB2DBA9E56E00A50C5592EF3574D7F49EBC1DB5CD33A1DC46E5A26D80203A3AE44D346283217C72299370B254345409122A187F099ED7734863615F91E083CECD1D74CA49F4CD8142361C2378289CFDFDFFC5B54E837E41DFC9204D4905956312214EF384EC9A0D907F07A143228E3B950FFD27B85B43A1A5DF06736D57F91EF4CE7533B5DE81B2CF21006855FE5448E0071D40CFA25FA76C9482E7E59D09FECAD3FDC45BC640D36EED01AFEC01FEFBCA2E7EC71F36689EDD0661465F97628E817A9517311C5BCE985F40299148BD7F6187590E72FC8D56960A0886D93510D660AB96805E160D202FFF3752D6A1AFB68A5F06624F9A2127EB5C008DD5C43B3C6B4095A40F035BC095941CE8F89905A3C6AC8FE51879D9B5AF24847A52E1A5AF4548F3A70EEB3369E84558C16450CD9D49D2AC5CC6E022721F1420B93ADBE9FFFE2E91926FFC4F4E443CA2523AE8E7A96F10349D5792EE079FBED9E1BF96E1CE5F02FBB5F41AD564EBA9EBBA08C74C96132304FC0895DA7E6E34B5C99D333B97C062F343B249CE8A42C916C1E473AC763D0643063AD226EB9ECB4A51BC7B8291D58F8C1E1D331375667F0F80B71543B052A7CBB8B95BC267620FAF7CEA80D8CECE430BF1E515144817CDAE07802F5BF8416E41A179AF840A27D7E0449D8E7AB71D6A361E56DD57289A8638C16A6BD4C6B946D60C75533D343567107E67D12D1C7FEC1628F9C75C7F81033766162C4E3AE0635801EB74DA2EE0FE14B3EA5385154AF110657E7080A21A5CC50FA7ABA75D6C68BC002ECA08BDF02CE3A2675066FCBC846917365B988FF162866F19299ACC1E79EA08E36742B31953ADB3F7E1D38AF6D8B2072B35EDF4789639694EF82B0323743CFA075D839BBFDD66B6B6753D5EFE3FBDB97FF00F7BCCACDE4BA8EE392C4996FFF9A27F5E7EA34AAAB868983F2BC2127A3083CF3229E15D0CA9628D6F9CFCA04567434452594B5047767AC031CDCE5C0745340543584724282BE058DA5306D986C8A20CCF9229D40221A66CEA47E3FBE5B85E5989F464128F7941E29DFD73BC85D470141DD8845344DBC8A66F45CCAEA192B0904F58AEF8D78F39C4CEB4E289B75F2401B8036853188083C60AD910FEBDDC8FD7EF70F007B4B7EADC1F24E72B97AB441DC9B20323BE021C61C4708075B571A30D7E8C9A08FED5DFBCBE215345ADEFE946F44C9BA0F19C3D4D0589495864BBA958AE84888AAE853A59E274A07FC2452B082B84153888A5C15A5896EAA0CFF52BFC525DECE99AA476C465D5B53D175108A996812E21BEB615DC5EBF7AF1F4CA7DE7BCFC49356DD08224D08363EB068DDB19AC2A4B37053C0C347925AF4B5CD05C35413AC450E344A149FD32CDF9E37B38AC4230ED4D04232A21942780665C97F6BD893E438558F8A1A4865A9CD7DC0100B5DE099B163A3640B8DAFA75468BC0A93FF75CE9F58430810345124A8D4FA546376E8E56DB2610129A845F5351A31142973810DDDE9CAF498C7660BBBF3386C3AD4EEF7C3B5DB7AAA2C406605B60DC8710B94153884CA47A99D64DA2DB26D658C9DC3AE5E6CEE"""), + TestUtils.hexDecode(""" +DA2755DCE32D07B6D2C2DAD6BBF7CF5D4C26FF0C9B6FB9E064B51829A1ED51A712E26DF8047B487FF0755CBBA8FFB60DAC3C45E238608F48205A582BADF82C2E7E83D672057B9A9209386D2AB8D93BBDE0C522CD1BCF2AE95573749E0D51B85EA01494E3BD97D3CE0A61B26249E4BB94F9667D6556CC4313669409D94AA4F3BB9AB70F736D34245E2A789A5FE2917D5F4CBE43010C5215AF880118E1F5FD47A4C195F3C74307523C688AB76B7CCB157F75FFD79149B5508E7E527ABF718CE8E2E4162BF810F35E234F8CB65DE0930202C1896DDDE02BBBEC8D03BAA12AA1C91EE798FF7ECED608E3DDB7BD04A1DD9139F4A5613AABCF7AE495F9CE18D73BDA0C91583B72CCF6A722C319AD5B1051E65C1B91DD05AE5A77220BCC7576F9CBFC8A12CD55883AADCAD1AA109522F286B00B70C8E3D4C6EDDAE7E1752097C85233583BA0E1C05C5624FF65A3F3894158982B633EC92C24382AF48EB2DF5EAD30759E99D67B8BB1144939F4080DF0E1689AC0D4CDC73DF1CC2FB72B92D5A69019087294D5F2DB196CF82B7BBAF953F0568663596F78B5A309738BB294F7AA3FC5F3ED5BFD4768CCF3304C836B476458E14B233C156C8407636FDB3EBECF49B97C96C31F51353B79C378C6F47F1913E5B14A82DEB126D688133F9139C12C45BA24CC9C7E2C16A26329D463ECF59746F5A99C6B03896E851815EF36F499654E2764BB8BC60EBC821C4D0B4C363EEB7849332A9F1053A975B092AA3AAE33F06F760BA1D76DE07A1F48ADBEADFF1E17C34F9D69E409DC5AC83C296C402E042FDBFB0B6B4E023B15B318337B6A1CE69F1CD3D93FDD0FEB7AE259A41383939253C317DB949E3BEB9C8F7A79D083BFB46C50AC00D382C846B78FAAA7399ECB902CE8B73A1E89374B1DA65B0723C67B24899342DF13C07A0BFE3565CBEA5892F8979E404BA84847AF30BFC04D8EC77B1C5B9400CB97622E6D3360836639670BDDF4E9CF9FE3D6B98A5FDA42422DAD6C829B9E33F53686E2663D232162D3A78A7202EEFBFA4917BB8E89375279C96C9054C2570DC3D90DCCF0E418B69E6443C1B2540BAEBE022ED9A9620C030377C67FF4C186A59459DE7DB1ADFE2923C01D9B8D3AC940486052DB67EB67A257BE7AEE0D3C77BBFFD0FC7C94540F11DD96C5100463C27D65D3BB6B7D867590D573D1C1BEDCC0E8D122FE4FB82F1404CCD061DD7C3D15287F39CBCD2448DEFE1FB4ABA858DCE13F74414E1A8C41B730A1DFB45B859545811C2A9DA01C342A1F3C8B916F60B5E4802BE672C2BE31531DD9E7014E681A8AB1240B5E3D5C0D26E7040D4CE05F9017A32E1C760F466A8D7A68FAAD421B2E2D886BF0007858129DA2F6B92C4CACBC1786291D7C95A3F6A12483B750FAAF1DA03059F89C761641C0AAB21A05E78E1131B8F45C60BB5E8681086717B918BD4FBCFCA1BB5DDD740BE289D8DB1C24FE083B3DCF0E496B1941ECB7D51182F9CB9986CF3F04F0CA4E01C63EC879FD4A3D5619EA1085B1431FFC019286ACDF3B4AAB03D6265A7B18F24CC2815269681BD37263B44DCCA5CF6FAC2ABB1DE317118219A73095D1BDA10B66B6B55421F049B71E759DBE6154F1DB98A7E3FC877FA90217A242B21F39490F2116A2BE8067168F26439C8D1928255B5A50CE1ACCC222087536BC37806FFABA03B7E787B04C2C67C1B0BEAA871F39D3DAC2221AF44CC7089E520BADCFD840E5EE24AC53FCFF1E7D6AC26694CBC15B80E48B10C054E8DEB00AE387CEC9972A28448A6BE3A01D5EEA837703D2FCD1EB2521D444F900846F59074D715AEAA2F46E956365B7E67C5528841145C442E6FD7B3D7171BE05BF8BAA415260F645E2FBC93C46B9F94D2997929349B88C2FB1AC6743B73DE66B30B44E5DB3E07E0FE9713D9D7575EE4E40327A58DCEFBA0EE95E22D06FDFB720993EB134073A80A4F06F8303C7758DD37CD7236E5D80AAE2E9569834846E7F6C75051302486B2564A1D8D987D1A3648192A63EEF4C2D25AD41FAA02C9F227CC9F655A72CF7207ABBC66F9C822EEBDC89833757013776C11C310A22C226ECD33E5B0772AE2DE8B8E9A876650D4A57B863BCC6197261D7D06903D414AF0922312B7DE6D9E64F99509CAAB8D808DFC5F046BA2CE55817512535EDC2477D8462A1817E45D33B9D7390A11E30C3860CBE2C4B519812ABA3AF7050227759DF3B6FCD6D3EE5C60C1042DFCDD7880888A147AC47A282EC51D0DF664451E37D7C40672A27B965CDB805CECD3EEAE38A0AF4C2349FF39947659686D30B9ECBDADD80C9B06293FC4BD5E7A0E1E9E883D7A4EB05102CC1FE45F1C9BE23043BB458E6B8B6C1C187761004EEF59E398B1124B98B0EC0F7B29394418B38D8A3003ACB85D96CFA0C3C63B2ACFDC2BF5540D029A261243E06393253B2C3FE253A220DC7AE4BDE0AB4B386DECA15FA2A05465740B072FBB0C8E81663E320AE931A2DC7A627C805AD80819B9D12EC271D9D16736156195302C93490B4F85E8B4F5199CAF233974079A7AD590374C4E5589D0FC26F70FF2CE51FFB3E6742AD5BD9840F62F745C42D6085E46182FF73FD079BD2625338105FB39110B660F8C55D0830587671CC802AFF63FA7FCFB3BDF6D65B362CA0B68B31FB802E7870C3905B04B41440F549583EC87218DF6A0BE0E209807AF053CA121D704DC0C90A499D1742658BB096C776514C89F6B2D3FC7FBC4A38C10DDBD3C08F64AB076C9BA4C7BF24EBDCE9C82B1BCB8E55C4135976C878B95B6ED108C2031F4E53DBB19205A7109C50289C743818B90ACACFDEF20EE33F5C9A7142B5640F4D875122E0E5"""), + TestUtils.hexDecode(""" +583E9A28CB7C3FD65D84170B159188C12E7E77E0F39C678C2ADF349676BC5A4336041A2AF283D3A0F61BCEED4255E2A04749CABAE6811FC2471148869D81C708E4B56FFC353196CBE05205F737C91C80DB8FCA7C243DED5BC6113AFFA87E14E0DD0D3E7A70B2EECB847762F5521D372C51317C95B6EEA2785B552D9AB045E48C03321DD041053C328A0081D86323CB37683CBBCB3A68A2F850E5C7A4826E88B1AD51D6C1677DC2B081DDECC66A01D3D3CFE26531B4EF89528735A8CE75D4B710C0F3FF05FAC74C99585695BCAA1D1FEA42D6D5EF176B90649FA92D1F089FBB63882AB9CD539C88028B380E610421D3C09314AF44F6BAD1129107AD1B84624AEDA7F3BF3A7698C478EF5DD2639D9555E53F60F327CC66143438C589285006552FE249B3DE8F4768B9774591672541385018FB6683CF04C85CECA1A9FDB4F44EF31AD9B78B70296CACBB35A600C486202BB771C75E83E1A0429A31ABFB75558ACCF835FCB68FBA01F5B766F3BF18C23B3DDE511087E8AAE570979BBF17C8C1FD69953823B4FEC56EAC6AE11FC4292A40BA01717F3A6CD108BF94520955F978354D78347ECD4A0222D89D1D7D93ADAF7679AE101106AC49791B3D17B6391B85E55AD4A12ABBFAFCF1D50667B37E49CA69D3CE3AA6692F85420B246355ACB51848AD2EB94CBEEF5E32D455FCF42FE73562B5B149CCF01236BCBFAF656E85C1D9775217E51D4F650FED78D8BBF2B47C67BE41F69AB2C2B1904E86506A371602A8B84A50BA179781215C0B061522EA66AA7CCA390055D0A461805CAC87ED7AAD205777344B7573D76690B5B46AEC4665E36A9173D7732F5E67FA166BDDCD56685EA1A41D440E469B7B65D7869744B1776DCEA504B03F6057F9A2D916BBBE6A5032356F4C3D48A495455381292C52E78F8478A56FF0EE7B94B83F1EE690F7173729DED18DD712BDCE3CBD887771B1D87EE2946F1ABE293F3D7A7ED224F6969D31D2E1F71F4D45607D7EF59AD25A40B4A43EC95FF0C8691D4C41E97832F345CB50890865AE483A163966F5B45291556826DD061C30C8CEB552EF8BC2E987BF6C8F629370A72941893F549864389CBBDC3D38D9FE7AFF8682EA318BDE62A2D11E543051A88B01547728E30CE25784251B73B771EA65259E90C4A859828A65A87FECEAE332B9F51A986CABF15B622AFBFAA04C19678DD200BC0B338C29B65CB121B70DE6EF964360F2D54C4D34BF7270212452BECC9EFB2E225A6007B35C000D276D34AD19A966D49D98E140DEBE503215D716B243CC9387CE52DC10C5B40BC765C2E4D3CBCF8E1617A1F0133DF0C98D0AF71E18DB6362A6E4EA9E454E1D6D986D1DC50AA580DC7DD131E66EB543833FC42A575A84B652E63164BC3FF383040E6EFF2B7550C2AA0905FC7BB4258176585544DA49F48A844A13052B06676568244CC66660021FE78053CD4ED1118C05E517107F614294B97CD4ED6685D2FB44B8B01E538874186E6F8D27D1F8829243016B1D505D42204FDADD54BD985BD647EB79A1BAC18086FA8A3568343F58A8D46A6A35C28DF1575CCF1700160EDBAC0C66A406A26DE724E1CAD5AD52554CDE52EC6B5063918C4A137D758C08272E4C2ABD41B7EACA4C44A3A7CE60F8628F3B13CFABF50F16D02B375A7FAD7460C53A8008BE19D982E9794B060CAAB1AE6FDA80320EAB2E02708063F4721DBBD8B9FF951BB6129139E90E7C1754D4682D029DBFF5FA9E713330AFBD9DC2FD1148BB388F4F857B4E4C63FB107386DBCA20AE196CBAA995F522D6BA4D2645F724269CA1A5AD24D4F56804FDD9A305B30C46901B484CE8D23166A5036ED775CD192BD47D9AB6612CB6D9181C1472A1F11E02E7C82470E8C685E92F21996663B18F8738469D61D98336D7C53ED2670A8DC26C21BF0BB105F5C905D2AD7432681AE8EFE5D868ED0BE906474CDDE2BE7BF5B617463EF59BE4A210C3D5682AD4DE5C059F1136D2C455BE02AA1E276F135C5001388600FF2F6BC6DA8AD0B72D1F5301DA9A8410FDC410B54AD0BB2561B01D646214C867726D82D3919B4C76600DC065C5933F8C7D3C916C374A06D7F062889CECA4D0A98FE843F8BE1E724D88F6B6E8E066D7B660B0FEE10CE8E36C4E60269CFC3745AA960C8BD9F7AF8788C4CEA7C4BAD51A202162CED055B6B60F8CAF85ACE6F60851250B1BA0ABCF9DA2C7EA2BF074EAD9BF81D73ABEA3966D63D1E60809050B7249B7969AE420E40387C36C4757AEC7CB328466D118E3794903C33F230114AF1C0AEE0112197DF6624123146FB3CD30F6020378040A8546E20767B8537812D0941836A0651AC90E084ED6673BCBBF18348D0E4E52FAF06FD1A42DBB1EACA550553595A388BF27735E85FC4965E61CE82E96430F40EA3B35B874CBAAE2612A714BCE0DDCE94FB0F4D93DBD7F6B03C7099956710E5EFC5C996F8A7CFAD679B496044F5204056D594DE05B61CC143F834BDD5D8B9F89557FCC09702848EF9A391CC4C3F07F1CFAD203B172CD1F44E4EF08C35631DE23B8E0CEA4C4848663FDEA9C9ED8B97B5C7F9E94AF6A90E5079E40A791F1262BDBA96BFABDC30643E2C3159919EE5288FC75703FD0D03DAB0C36D0CF06F0450A5E6D710764085D0BEC8B26FEEA7E5C2665C7F514AEB5430F9C307E7D03B30401646A0D93561FADA21975D8BC4EE1F20329FFB4625B3A484CA08DA09C61B45E2BA9C88C29B14E9B650869EAFFDB7EA3697F4DCE2A72752B2459601E044B52F0DE99BBA5510128944C00357845F374D60E373CB35FC2868DB5B948EBF9BDD3C66C1740F00711965AD9549347CCB3B5221301159472AC8CE0B3186269FD1CE5CD0DD456222F10264B117BA250B391C840E51D8680BB622769ED264148649D3B954839AAB5B27546B8BB58A20BB52FC8772FACC04101148C99DE07B96BFE58CF2F04DD5541CA9D24873557902F0BADE63229CB8658E8E5F815719A73F29F81208D0EA8985BF2DD770177C4FA88CBABBD0C9181C0DDEF7CBCA5A6EF12367882621E64ED026A859C60D0B8690924EBBDE0C0E3562E10B63520D8C801A6814CB1AF9F03C3907FD9A7AB8567FDDBA869D7200E9284933A414FE681F04A45BC3D909267FE62FAE7A52F2F84D3C02A10AAD86A1C7A9686A2B7A81DEAE6A1289B7A0792BEB805A620A38F7610D9C3AD1CDE838DBED11A760F42A271020761BC41522EF370726A4683DB705C7CDB858AA8A8036DF1328AFAA0A4B31839DB7518164B11E6EFC15755D1E0D477EC004F5593CF7F862AD24295569E3D5095B8B0F1AD427C1CE7039DB9D881D5E6AA570144255939C22AE7EF4BBF9CE36FDEFE30E64ED373AAE944907F5BD02B70312F7150CDF487099468B19B94703358505F7A5DC9317B9B17C44685E5D609A0F5156A1D4EE517BB681CF5657AAC2A1A678687E9995F089CAD494A6C039774FE62AAD3D2BEDEF62681AD24884D1630909293B54C68D7CEBEE284EF9E70049748558DE03DA23B478566B42B8EB327DD8BDD473130F1D967BC0F6E4501DC64836EB877BA0AEBD241432C503E41DEC7B264E08006C006FCA366EAA277CC9F5FA6155C9E48E852B718A071082FEC580B4AA599CA7708AB4C1995B6DD0679264D8372B5CD0EDE9E40B6CC0C3DB14D00B2C7D2E9433F08C23ACB77F991A454A3D1D71379D08640FA5074EB5364A531587907607FACD9AD9036C8AF221650F01308F53B8D0E432E5529F435F40A40E66A5483115FF438107F88FE5F1D541C500F8B12C9DE69CD5B14C3FCC5B462153F9DD49974C34EB1C5604606E56C746BBA8D90E3DC4556DBC3BBC656A54E08ABD3FE1C39F24E99D3D022828F59B80C4DEC6EC1CFFAC05E388D3F62510AFABA69C5E3EDC898CC8BB842F3886A88AED03739C85DA459E8329D1AE249E26EB60BDD2EE30191099C96C397D88FAE9922C72A275BEC1C7734CAC893D906E976FC7C0AC8A090986EB4F5FD7E94F8B2694AFB4170CAD4F1896092A7F6EE01C300DA97538FD5FBBC6EC28D158D3AF40D3598753883156B0DF2143131C2751F2B26DB6FAE76773E55AED9D115E7FA60267DEDDA65F41CAC5FCB0CA296EAD1EC688C742DDDEC5292EBCD47B0570ABBDC2CB6EA301E58778E1C3352E393598470D2FD2C45BC3A611343ECFE61AD64E71033B6B7C053DC52AB1CB246682750E330560F15B3B2D83E63F33BF4EAF608393C1F5811B0D12244184F20EC0682D236F583CCA8C8D332318AFBC50C03873D68AC44CAE4C2826E966E35EDEEDF4B232DC4B3BA87F3478FADD0D8EE55B408AB929DDC85FAEC0AB503C2F8192DF7B719594C7706B98C593C598543565C27BD8A0A0CA7E802B86214889D8A08337C65BA31BA08BEF281FB69DED0B30AC13274E1D98FE3F2CADF6B6FF28334B338984516877D3070F379991A078E1D0D25CED600D2C52CC335711826066976251DD11AD21B1C852E05F3D9EB0D37E95F767108AD378770DFF10854754BDE53F8CDC14F6A48C66463053F8DE46B722EEFC6F2BC2495CB107F3ADB39BDB2AF497FA6AA2CCB4F9801964FC6B88C9656D76C0FBD9A436D1AB57D763A8B814D2957E6344312AC137B3B6FA74AAEA860186C02156CAFBD455E8B999AB52B70DD05112E5C94DF3352AAB3E2071C343F656E959FDB000000000000000000000000000000000000000000050B0E141922""") + ), + new SigGenTestCase( + TestUtils.hexDecode(""" +7D9BACA9C8D5E302BF5CE4C85B7685388CECD82D72EC259976F4CB65C360D74B7AA8B23CA3C9D786FA3D949A9DFC1600C821B808F0BEB38F815D7688928159D7D9E9C1F80FBEAEB0718B4A27E5AE16AF325F2362539164D1B0F282131684089E9C61442C8C6EF03818E4FAB383498A91F1A6BA3D1138FA2E6863E7BFC37C768B80881102106834535885567854243344502211757522267523162088466534441253602763327188226627581385652565414151784380762722456634142628231458738808653824328765256787544665871806531822248171715644617852253306323676053473565268176586832213365052846420073311447520430470886788436502856868764754304758685773064126124086602270614670066264160503303628808800428371124331158623773024150040258466354242631322182837265206682145238541377758026231302173751556168744863422724538416543335044260014140700080223635662746130854042515087002685102861285410486525326637353184253282228015078475041117212844878141825033873150751831805782170351465068071671207478634401484255326350633185463351180560737581677164273148337620650506318728817625581311474587143474200631175767306836700454673165201446440552351405570370765020236227650155735776370575127458246010022264663462424423213765310260018843165528661703717074062347113507035301545373865105171508624854887346415101230182053334304844180245311205556878267210221681707671130563111227840346163445346756381740517462567744211002860288204613256541014522561605650738111510652486113003236284705828187520165420710141265210772323357340165116445210432428531411538578270768734622774714255868725625185866516828826288225225382481362346231732171642643803148671271817471106245053755183045102417242701340831385358686761031752488155811285174784301446783814603452746400881104301515340323411220606187382848113531273238682142164176684773160428640811770836021008816722262735542177425024011656734742220208177654327651838237731115676205078445837425763855715746545685101718301140056042410640767435220144420781045324711834710612775235483708256718366036056834856355047187872866251726612854101127341052403064311315244428128784365157205414785337848650728144772332137377841026231712784787072708207440534642352015738400562513805485583235012405755534737647887617687056613236528823413687622035830161327666432826703008462403420246788067276833355848330825352627051271045102466531806664112101702762667023185287441052104507353315241367611074381635451018347836601447556273501604602706013545264275427561702133764222721520838326555538771678808754764612652255384672763068833424642760475458348132214166041671261184323442617226644673580125123380608502007202213714484438825036152616448882228853238503436651346737426226137454116521806224384547167800842813436447366152212332813016632406320458758564571656076278257144143508780111883350040472187651326241722885506068843614384407717837823233334577603583138607157753607181603248844021525518610382536002436628707660830482135508327523234521413058137640267365080463880375267721714644672516818385618535542842438636753417412616738466876353522248666700120623351178721720464482820874272415685137628481655455861246778640761403677012083646508583110082074453101204426410178432288412156182720465184485112240375BF8365FEE3A6C811138E1CF73BF1D0EA525F2BDD4988CC157A976B949022FFBCA93B2664028F9D0ADE28005C84CA7CC39EBABEA9C92075734D9F83990353AF6D72693CBE38659C9305C804B8A75C8BB1C5FFB6C5A681155A2A65F85C8DD4A14C6B61C45D6D2BE9411C00A29DAFDCF3D9F1EC1E2EF75214043AC120DCA4F22AA7354AC2B6443FED11A086B22630C1B45B2A372FF2F1D0660C41087F5CF818FEC1FF96F18CD710FA09F66589010708CF8D299EEAC86E1E989C2DDD60A2F68DEDB62B0E6421D4DF285AA2A32F442E35688826E0A9EF9FC32C32F09A28419F37DE7747DF9C86B5A54A558D374FC1C083A46321E7237BF37491214F54973CE3BA8D7229370DFB27DC68F33EE68BBEE33DDB63B3AC4E4346D6D96A6A300F49ADAEF370C98AB1A44A4D5E98C1B19ED433AC13C5A099894CA3481A36820E5548A04C632B0995BA976A359DA6F029DE8443D7AB197037AAACFCF2F61D33B604DD3BB09B26523B103B0AAD0D2163F09294A48042E8D23599DF7095E009F393C4CF5F295C3F5E49F2AED1F29926653C48FCD8D93DC39422405C38EA9E28FF5ABBA4FB699D158DB7F70E30716DBC1627A27E6A93F594F6241869332D4F3CF41731B84C17DF195B7C7CA7E4563AC9EC1CDAB2D1E52E5C6D38B4C63C3901BD860C038A34284E71834247D1D3854AEF49E2BF6F67FFE4256869A41BD44B0FA2E0CFE0345EB3886BC4356AEE11A26838D4F2279AC13D6CAA53F110ACBB1F6764BBE47BF3C4E1F0B9B99B00B6B9E0C50053FB32174BE392321A3E0A69BDC874D3F3A42AEB79C4BAB2753713A5DECE419E2BDBCFCAC6CB741425A64CC7D3180E097B5285E0B7BCBF9B7D97DE81DF3227C2DDAA369C87BBF3F876AD8B81E9208C2EAE363C3A0434BAD92F49EE7B6B805BCA9CD6C0A2C3E21E5D5DD9AC4F427F62EFC96C13F6EE1EC761CAB24E61DD6F509D08E8E5AD4EDAEAEF0679340677882BCDFCB6928AE7C2052DE7116CDBBAC3551CE0DAD8AE909D795393CB8A6292C7FB2C16EE62B8B5F05CFD5553A7303919D563B7612E65EE69C97AE80D3E407A448C88D508191B98821F03F3823DA8793054FB0D051D9BD12D090E2CFCCA4DB20C6AD515E5E8658233C095781D5BB1D40BC47D3BDE5A6379CF03511B2A3C06A2C315730A0349F83512778A5123F7CA9FAFC44F73B1259090F8746F1AE868DF6D158636EED34B8FF85CE3C07F7378ED5A3E7577A6FAE7CD3EA0DE0EE3576C48008E2E4F8C417F3606BB1E9DF468E40FE74A3C69A672B758F1C3AC570E44E9A08936788B44A769B28DCABBD3266A82CDA0CB6D2014B73BEACB33801007C40BF92B647FAE6631648F7E91DA022993A9198153B7B3C31B487C863A639ED7AD4B235FF3D44E3AD573036902E3C41A53D34704237304D2E4D72A3F41DB6BEFCE9DA8945CF5A9AA2217A2B36DD2956C3F4C811B3D2A95E1FA88FF2ED95A0950CDB1A14DFC89ED6E996C854C1FF056A73D7BFD1E8F08EBA003E3E834C71598E42430B15BC0F1FFF6791D639BD40923A28FC4B72636AFF01EF4F01C4894BC78A3AC69BC595760BEE8A227DC88AD1E633401B4EA43BFB070ABA4DDE38FE0EE6BC4958F1E6481BF478A9AEA4EC2AE56993CFC33975C06B571450DA0026DE58B99B6D44F2AFEDE582920436230A6E81BF051BB54A41AE6E6C34BFAF1C7F03A44B85ACDDE1B44DEAAB8299905FB5AD961FF224C717E96DFEDEC50D5CEA646D2FFC5F7B6017EC540924D1C9FDB8013F2957F271C85027985FD4184F22E790F91CC7C44C1890AE83932483AF25FBC0A9C740BAE467E2CA24AA7E86C41A9250260B3A4F805D6421B8772691F172FB63939606D50D03F7C4AA09EBCC2E5289BF4B9EC64A1307869CB4EBAB5C0ABA222C86E21D6EF32B82B7409B10C67F7A7D54C850C277728C15230C56E3B0AA375440AC0B55DEFFAEDE52C2F84BA5FD49A5AADA5AF6C9EADC0E413006F4149081EA8B06A3590E55D55051AEE474E416C7C76F0C41C372B593A5A22CF9D520C59F98942B2870408FDBFA063FD14B6615EBDA85ACD3020382E696B84B4E6E6E28B1F6E279EA4C5AC3444E670F5B1F01ADC3331B4E13B1387A082251FE63E391E3AF0FFC8CD5A77D2B77DDC75066E04F9BA89B65E62F3F74B5EB53068449A3A59A3CB8351B5F8012FDC5B3F7ACB10AF933DD9FB5C094BF085FEF0B27D9B01AFDC95B3B96633C5082369F03BEFA13D53FFE31836D1E02ADEFFEC0CAA084050CD5CF34E1362D4BC422418536A4F5048639A0F168743459733CC11EE616D810DC92B266BCB0B78F32269BA68F264B669302E8FC2E35F998E2B0438EFA2FCA0B14F0B337701A4FD5057AE3F1105526EB726381C54D605D21E9A1887DA4F8AA09C3D4CD0E617BC072F4050E125763812D4621F1AD8001AA027546E472F8317E9F37C27BFD4380D4A5A8C77FB426C3F13E462E06B6D7C59C8DAE7EC747E4C08822569421C70EB62DB7C3F1EE9CAF7CE384ED0B58A122A2C0C669DC843CD21F63E01CEED8CF7C63918CC7CD04B80556561582A4CA24732956700D5AD7E65E1F7D770EC84C6A8B7F7737F4B597E305199C8DE6F73F3CEB730CBF6E87E53114D931024DCC1F3EFC56BAC8BCB374C92E2D687E735DA892726B2E7B30135D1CCDFFA0F81B8986A9E646B9D875487D960FE87360C625557CD5ED7FD45D18CFDA97B410CA62BAEEE3C90C9EC02525D74606EC7EC1169B250E8FF4B94DE08AA95150E52715C18DD6A03F2A399956F3308B8CE72A96D2F41E2CD901D4D507F336354AC24DA68CF8F83B69F12E54BAC40F9A7BCB1D1165E456DDE5C60F5BDA4F8C435550B492B14642A329C90732E6618CC73B5A32C71CF306BD89B074C8174912556C3FB05DBD4216B246239B096CB8928162E3544FC40EAF652CC91004686FDE0A3FDFD80BF2770DD4FB79A7029B0DA6B01C8DB069414B26A05C180CCDFFE049401A348990E0247B542C7CFCDE012F3D6840F406F7BE782DBCF4F6080BAFC7BBB201EF6087D38C211727C15ECA30F003AD52CD540D8BC4DB81375F44E0E092A06F9E9891F6AAA178FC39B3E2868284330B3D2508B486836D9F1F5AF0464AE1DD2D696AC0EFAA4D9DEF2E5CD28A5E1D42E813D3F16DB85BF565EDEAE869A88D082EF43A33F936533D151E0BD06457135FA0450AAC65438C729AAC8598399FE8AC0042E3220E936F88295E45BAF653F405B12B2FA9D386BBCE3B46137253E7C64BCE7E998DCB4916390FF7E2F074FB1754B60C3418DC6C5728E2FA364ACB2C8BF63525849F2CEC268DAB24CA73C429EC350DA2900583D9C8B2BD0AA7F5458B00DE9E44209946F70BEF1C7ECA26CF08DEF56CDBD6C1816D52A373F822321468770A6C5D8BE130E6C752D63A72688B786168480AF505D914C13EAE57905AE47E10CFBD62C2097A7482432CFE5500B804E3715411AAB787FDCEE2F644F38EE9A0784E88DEC94FB9599A68A0105577162A6FD575EDBFAB3D6DA5D2CA2F086A8D55A325F8EBDA84E79D96D794097E62413CA"""), + TestUtils.hexDecode(""" +5870BB288AA6130708F7BBAD9FBDD6D41E249D620495ACFE90C61737B57DBA890213D4741718545CCD8B3FFFC2DB33C39AD631D5B5CC902DE4D340DF03E09248F67E89D28071AA50FA532E94C391D2D1A61B1847C6B1088BE555E5C2694EB0FC1F029095ACD9DEB21EF886BE577682CA96AA2EB3DCB24B871336AC5F23C8488011860B455B687BD4CEF5FA11381BC292B4098BB2CFC1822B48ECFD28AEADA71809BFDA190836D3215CFE755FDD9374115E5A0CCAE15240EBA0147C2F89D8D24454D7A5AC2D20ECC0D46C040FAD233FC51C870080F1FCEFAE6C073AF5F7A78D610E23831D5990985FDBFDC6D101ACF3DB0A74D71739E0"""), + TestUtils.hexDecode(""" +4795C93DA899DAAC44BB2F2CCF778D14AF2687E26D40A5A962084FB54F037362BE239723AFB994A15B17B6B779A80CA4C88FA1EB57DC4BF743734929201969C7DBCB295F9D5F994BBA406E24C4A0EEC73368785D9B2C8CA45CBD7AF0A772442692E69FB79AA17FDD80198870BDA0A1F0DD2C89D22BD6660E62802F0D5183A7A9CCF5136E6BB33AE991EEF920FD80EF911BB94AAFE0BE9CAB7C0AC60A8E763242C3E8B4099C7B8B1661E63F756A0B743CFED12484E70151E39CE81320A687286A3719ADF712D006AC81966286C1ADCBF874A359EF391B892D4A72FAA7BB43DC894D0BCD7B77BCFE845677DAC9252046C2578F15C5AFA19ADC9B5D5D6DAA9910F3DC0187F1B12F7F19ABC6ED9AE0CCEC15C76E6003D7F9040F2F6C61FB568C16FA69BFC87E228AB08092D2132E3F50D07FF7020B400601C603BE610F10F19F1014DF1C56D4953B9143BCE64809426F3643D37C99BF27582E4ED66ED8987CB16853148712F82C3E49A4B2C763C010E74347F816DE015F8568024C1B6272A4F0691CC4360ED0B4BB81B576F46A8AA38CDB39972C930CF0774CB5B59871EEE17821B30F58A25BB9702C1A4868CE50FC3C7102E23A75AA751556DE1BD3266084645C8F6AA90B2ED743FF39CBB951A64C5235F1255DA9117630C150E1870066D5DDE4721D2621417AEED53FC1EC5F89D5EC9BD7A6FF0C98E4A2006B0118B2848312ACF3E25AE401807B0CAB45BF54C186A85D096C71C4D14948547792C290212269D8ECFC79BC0FAA3D37F6364E3FE33B326C8135851B20A7D95FF10BCC765251ABD53F4B98B0FE2BB89FE5E15E06D130F35871B5492FFC3A1DDA21E7C6DF0392C714907B7CBB0C977880DE4BD44E3BD1C2B72729D071CC1FC0CC93870EC8996940C943C0209D3008B90F22A8597320B201100F131214CB43E6922168E574BB7C6E4F4A85CE11BFAF32256A649E5C95BFF1B83ECD8825CBE665C6FA98611EE7F4977512476010015DA2D3302F7CAD95FD70910974AC858006DBC3AD8F8995C99C8FCE87078CF218985CE6817336E501480B53F81C1058EE0F7BBDE9E212BB1B067FF34A3F8B55DAD9CD0DC963F8C8B835DE200C294EC402D01DEA0540F5CF92B55252EE651A4190714581ECF2C9617E4AED4BB0230C23AA16FA9502409B03E6A3FBA7D213BE13180EE2CF63B73D0809225F59D2FD14A12119F0A531D250BFF575DAD676F692E21604E2C83AF932BBB7DB4F3A4B15BCBB45CE3C52C622B14561A39BC6582BD2ED428FF05A50B57DD355469A5B36BD5CA04E731F688BFBBF30C450D35FA94E74F7E9172D7F66DBBDF13FA634F3BDC891CB49CD5B33DDE0FD7EC8C7E538ADE84B446781918DB26D363598DD54345FE4CF3673F69CF2A368EB3F6C6FC98E369D9A514F8359CCAA96C8E8B9565945D7C8894B6BFFBA4CB0FE2B1317C424A080A189A5AA8FC4F09E94CC90F3CD74626C519C2A99C39734F26E3FE99DB512896F881034580E2882914411AB3581D8DB80B46B4ED9B22FBAFFC29EC1DD88BCAAFF56A56DE5055245897764C3A45D511245C3523AD1DC7898DDBFFA290683412E8B7882514372240CD523908B0C92FB26AC669327F840A9496BAA63D1915D3D1D8BDBFE63BDCA662E1AA2F4BED11F07A4096A348598BB1E9A239B2DF0CC2C1A7D62F91A6D18B1175CFEC5B74D63154FF2141F82EE5C7DA9BBB4523001BCD174EEED70225F16C73F2F443079E9BEE77205D4928A05166CFBE014A2079661D8B609EB4E66F992EACC830D0FC61621D65E34DFE8EEFA5D782C56426E9EFEB253EB8233B08A3A6CA4AA8D3916CFFB7783C9ECAF0AA859CCCA99AA460DCC193D878D6643492C10101CE59809C5186E3459444C395B036390AFA2E75416EF6F04939710CF080790BF2C6E626BF9E872C7D13CF642E9D9C57EC8DC106721C04F13A8BAB6FD151C8416F523D4F2EC038A2525096EF495273976F3D1E7DCA57D5758A213FE5872F242A67F1C2065083B1BD0214642976155FCDD227265B6A4EB47E6C44F56179CF514CB6D0BD33349381CC4EE48CAA16318DD5DF500E7BDCBF5A46DD24D0A5D5DE106B0B3F66DD75D210379C47FB5CF11523CC42A77CD80423F41364D064427CD016565FE2F1F7F2192670FC6C17AB346DBC50EE30015D353239116BE68967C1ECCFB9632969B848C2C7A768CFA771C8557970D77EE918ADF6208C9D803B41B184814A3C99178E835D89BD47403764EDB366E6050D9B342B3B3D6409C577214BC7CAC261C989906A57A0B4BD9BC9778B1D74076CADD4ADC43C7E79F2A0CE5F2E81C36AFBC66B526D080B85E0372859D64C28DF6A7B60D3A066FD3DEB847DD2775A6636F4693F61361B9D84D19A40A0EFB2C8861D9B27E43BB504EA6B082AD62CB4FC1B6FC163AE7DAF8D6A54CE4E9D33B509D4D7936267A0D32389987DC33DE09ED37043816463DFB828BBBB3B6E4E5286C091A494ACE782507BE750537EE9F2E609AE4992B8FD53E0A38CCE7EF962B75F749B74103477AECF55497CA31741D70B1F207CBD694A8911653DCB4D1F919B728EB2C03177675136C11BC2B772C5E1C5F4BA0FE431BBF4C1755E8DBF54A6A111733E855925296C09DAE549E5AEC0B6E0D9DE07E077825941D970BBC9B7DA939DD2CBB373F75530CA30446F3DE199709A5E68BDE9D92C6A323933F214BD4F3826860A131F301DA7895F34EF35642926FBA61A8E1C17492C31D2D13C20DB60F9C6E90FC0152665A21100E034065A67E2E676C33DAF403218848859342991888DC47F12A2E7522B62B1845A123723639593543CAFCDE6D9FCB2547746C2A7DE5182FAFA8BE1C794E8E1C968B70C3BBD84899AAD7A2231706C108406A7BDD6931A70BE7441B57E70AC353B9E8127DED14FEEEA41124F0AB57C6A0A857E022BF717439A11919962445A480D18B2367AC9E483C3A0CA5C3AD667E7A1EEA7D50335950997959333169F8E76E07B051A89B1755AAED4C49E0532E9D0DF5C9AF99EDFEA49B83AF8147440CF93C4056551873EA11887DD9FCDEF04F7CF1F5EEC712B1E70124C6155975ED419F206F5C16C3D7CBB13321599A4DAB457848974B74087DCBBE990542FB6F7F36D22469E3F68EC189893452D6F4EB180E9A2D1D1F010524A1F501F8DE4C484B35E47E517E166D1F9394DC6CB394C1FB1DB6685F07ACD0D25AA4CA1E3BAE21588A5C9B4D229A4C399854EAB3AF379E3D4456102F021019A8097B06CCC6B6FF912158C3DDD27DE33AC093EE6EE76CA9F8A90C2AA8E07A61221FD9DDB6EF440D6DAB8FCC2138B396BA43DB70CDFC90031F424D4C917F4F4C04D6B7ED87FD103FD195F39C755500B8C4120CB62D3818680EFD3564D5626D6486FBF8CF96C3C179AE85E573D1CF858252DCAFDB03DDCA86FCC65DF85E5A10AB4C549E1289FA57EDB1B2899469701678810BC8E709563B4F99AC7943684F4C56056E26C788B3C8E87DEB10319D56A52B3D25CC491C6771496F4A94E5A67FA60777E899945E2F58C9D7D5759CE41733E6845D6247812B11336062C88FEE525C44EE8F73EB1A0BD66CC64330356C7F2DEA6D3465E2C6EF0505AC68502165F1701FD40E0D5F7DC41583C076A81E56775034124910BCEFF7DDE4A2FA0072D6A6BE8695A8440BCBCEE4A3FE9ABE0F0440A9090ADDC40915D2D33D88F1489888729BA0FD0433828257C44E0C4D46E9EC6C9586D5BA3B9D772ED20BAE620E8D4619E9C720632FC92E153D7068E67A6BEEE16A01731EDD5AA48DE29B083820DE5B1171BAF4E75262353CECF8E2C2174E530D4E3B84F12F2729CBEDB10B62902ED39156C32E2C68C7EEACD2DE88C50E9F6BC117707A0E931311EAC9F836CF4DBD7DC289ADCD4E8A536DD3C7C5DB082FEB4BAFB6B7A48FF9C129CE97FDEEE396502319F6CCEB8B5FA38478DF2C0619CC74E43BC22992A526968AFA9D147CF6A2828ACCCE98A97BB63AF3576670C5B61EB5EF7D30BE747E1668C6CF3226B5DFC8FEA39E9D1648003AF4EF2EA6DF3171F7C2230B9717939EC70E53CD9230BA1E77A1C07D4E6A3CA26455CA7B8B6096C49DDA4A9BFBB2E03C3B6F5D6EAF4C78B87FAFAA5B82C0CF7321F5B8B1D9FE67E765A2C073C844174A21E9E8E16656C0D3D888BE6EA17CD1827AAED796B716DB2B23473472A574BFDDCE1D9F92E179FFA2231E75D63DD2834C792211B4AF030FD4010DDFBA1109F1292C3063A65F612A6B40849717C6B35176A42FC5DE4EAF90943B398357AC5ADECB7E77F460732B712CB0EE509D880E2B6419C2E365EEB36477BBB110240F3B20A66CB39722E9986997642396316E7A23532B2D75389B4E39EA49DF5EE29FBB5EE6E0B4035CABC3ACBA0D85AA7214553A9E3ACA04C0C8B800495220A8E0BCE1D0EB6E650EA0FD8334FE24C5DB224F5CE49490F0EB8246183F844705CD75CFDA3CEC386BB2EEB63F14BA4BD86465C25C97DEECA55D14803EE1ACF6968D8820474F86554CF8A1DDA9209CD5162B158031020277870B55FB8BF5B7A961238546E8BC5FBEFCF4E004413AD9FF4671CBEFDC08EDDEA1690D37D29786157C2856D3A2D3D2AFA5CAA4AEA82A0906A4EBF88E661BAE0A1048687AA1A8ADAE0D1A1D4349526DD40A3A3C667791DBFC13344A6568B2B6BBC6DFF3F81C42638E8FE8F1396B8AA800000000000000091119252C30""") + ) + }; + + // Only three are expected to pass, so I repeat to get 10. + static SigVerTestCase[] SigVerTestCases65 = new SigVerTestCase[] { + new SigVerTestCase( + TestUtils.hexDecode(""" +6C9E7A1EE36625760E5D2F33DF2929DA56203234069160E5F2BF039C11062273073C237566CE055D871F38ACD1A9859A824467F19BE68E4F00645D225C42C85A557D2C5ECB442B0F028A6528898EE2B673D863F32EB9EC8164127541F32519BB88E034A03F46F7D193CD3DFBADF63557926C5C8F5B766A7FC5EC8B3F948BF7A821B54C9441AB0BD833FD6354CEC706FAA500ABB5289B90B1BF917677A29D115F0094BDB48DC72E261DBA120BA6FF5E52A01B178981DD8296444656D9442DF9CBB6BFDAE56A230F6F29F94CDCC265576AA8752ACED07E99895CAEF0168BF83D23FDADFBB928CBCDABA25FE2CD26ADDFB0DACD74940F351426942F176FFBC5F3456DB7C912AA16B86D0745F87C9F45370A8456A1ADB51DB4052B5C9EAF60AD7B80A42EA4BF92C841273AD761DEDB0D34BF579600B149FCCD42AB1549BA0ABEDA57EF71D1FCA5702AAD083299BB98300189C25F3B270A87658D0B2EA56524147F739EB6C676D7BE73DD3B95B10C55AB46FD01549C5168BF7DA13A499785F35A1E3B56F4C567F54EA9AA2817A336383643FA2EA31FB1B73E10248DFCA05C04131266498E1C9491135A50E63D02FADF4165FC9E15E3E1B32FAB8337684C49193E1BC4EDEAE373A267A714AC1F909CC657CD8066646327E0EEA041AC9F2AEFFC80691BF60D3C94C642557E4299D395922216C65E75B7E1A5028960384BF816C9F7054829E7985B5841A733F33FCE2455EFC89BAE84B47990E8D0AFC6193E4AF9BC680AE24FE591E88BA6A2AE12DA3858D21F492D24ABC4FE4FD52D5ABF24BD254687B918792F0A003A5222DF45038685C725CE7579E02CB168BBC666ABF669856E10537C9291692C0CB0CFA906270AC2C7B7DC31D4F9283CB2DB8A462AEC0B9807BBF4AB4576FEC6226B4179322B67AEA53BDDF9C9BE5E0DBC43F78743068AB5BE49F0E62F8E2EB1B6C6736C05C9413D065CE0CCB790548041D7E832881A839B5729AF94AB79FD8A16DFFF78CAAA141D97CC0650F86262F26159BE8B361A4A041E9A0B6511BBE3355A4BF57AC09848847EE0243C3BA774776F7E9A227275D74E6E3101D382818763ED1E1353AB9EECCD920CD28922D559A4048F40F062164CB661C4F4AFA81A3D55933C4791EDDAA3939E5AC342B0AD1F438A532C6CE786681A870D94EC88A334CCEFC6ACE7D988A1A82BC0ACCE785F123BE23A7C92AF108E5ED4F0869E22DAE273556D1DE386623A6C3F115BBD119271D3FBA796F618B53959FB98012E7D5B9AC688940B87E2C9C065524A00D3A4F4DBF52F4B1A63EF5C46193BADF7AD7F988D4464345B2C3E549684F2F905F6F89DD641473EC05108A52D8DBB91768C541DE520B17666970AAEB506E75D8EE9F4B4455B71E0088AB25655213B75859D25F559D3C324D283D397ABE6F0AAA386815768D03357D775964902413153E3560CCEF1FD44B65FF1B287A92A9693F034B7EE668934702D7501CAF6DA4EE98AF4E8E64B0340E0BB8BDC533B0EFEE1915A4B68B93C5E95321EEDC234AEFE71AE2E5DACEC2F52F83723A2392A7F8E13BC0301CD104D852E62A7F828AD329B3D9596C58E13FCC0ED96C1C48D82A2C0F4D9D24DD8421FDCCEFD497A9B05FFC50904770401373FEE7DC73773418AEB4A1F599A4BB38EDE8D10A3CC83A1C72DE921969E3CE3E8EF2F7DA89D344C80D61CF9C5A423B1A4F3567D96DB2DA3DB9B5B5FA68156BE7452C8A0181BB9F0DC75CD9750883D0DDAE53FC156D67A74200869046B41DF4BC4396993C08AA4897A0BDDEFB55F69CC1C4D7B5FB150408427B416F73183F2B3CC16E3B7DA63CEE1143ADA1A056626A077B6D21C3DD974ED907C5A094019225737EFB93319AD3B40A4F434AE49D28391C17A999C744A68C55A91B862729583D3DA46EE70C5CC461694167D32D21DE75327732C63BBFBD7B30DBF2057A0D681519F6E4AF608D4BCD0B4750726770E156AEDE85417BD759D5FFE401CB2996F34434DB428D9A417037201FCD260FAA98084502EED5C27A8916E44F5929819D21A69CE16BCDC3CC8141E285EF897B1402C15C952590119051E369A1B7BE443FEAE6E32BC8F3D647FC5315A5200CD5238DC6677466EA86EF8D18E5A79F262483E896B8277C741F516FC040C1090F2495BF1650B02AF30456733A071AF47D7A15BD8E32A49806455D3BEA74AEF5D00906AD2F0C045354EFDE7C9A276E73D9EDD11D1CA5C297B9A6851E7F67E21EB061BB55D9E673C4A75FEB84D52629EECC53C24BEA95153051AC206C87DF55410CA1FE6CFC3F403A6D9D43EA84C60C945E642B2836338B5AF9F69E52708B2E225933DB320BB3F790D397F22D7B6F8A433CDACE9810AA0E27C699555530C562DBF7517A4162628BF10D1B6DBACEF5C9ED51E55D9A89D60E0FC378C47A21D5E0F2DC3BCEF5E05C6E0261530FB027E5032558CA2B47005BDDE99909930391EAD7F3F0A96B3DEDA54A11145F530E51DEF892E5AB0204D614E6E38AFE79CA92C28158D570120353B7A4DE0889846D835294939557ED0AEDA270D4D73ED84D3D49F9F032D43457BF59BB7D66359DC53F9B46963B21784B06CBCF04BEC1E33A33371532716C9EDB3FBEDB81999B4372D0945C10AE826C60FFE93170B6D294B3891B0D2A7B35B28A8971845DC2FECE237B80F20B379CC4D136DAB3FBB3792C63EC61F5C755BC9DB35086FBF46D2B7970DCA2A8523FDB4C7A0B8E42F8AF9ACAD2A0EFC113602A4EA62E4EBB7D269C3A40BA2C44EDD2956"""), + TestUtils.hexDecode(""" +C4F59FA2DE30C8420A7E7F096BAF6AD69B1C15A5C6E61C9D82AFCFDB6EB8F275BF5787186AAE781F487F9F88758C9C61F35D5083EE70424B0D0A51575010C2A907F49608115D33EBA0031509322AA7D3061FEC3162F96A565F98769E9A19235D89D1B21D60A381DF8EB37D58C6A2E483A8EB70736E4B7BB911F7AB923DC29F1E"""), + TestUtils.hexDecode(""" +E895DB64C57BC3C2A97F0EC933410E98F6216103E3423CAF06A671964C514A694EB6F65CBD1137CCCF8881FA403C5FA0E0B2F36B9F4009C378210D29E54A7A5A9B793197CD6D2F38D7E1F3ACA69D48881389381C89FA676DE426D634F9A157055F17283ECE8248CAF14DCF11E2D56355B047DF632A18482E79CB2D5A743966BAA8A76121BB69C2E68155ACCB0A31DA6EDC73CB09A9E660FEB20F66C7BD967ADE32149C5552EAEB2EA175B56233F3B370EDD8679269CE0D2B43F6B2F65FE957E7AB37B982043754EAC8A30B36C10004EF13C692E219AA7AF0A4C5286910C7100DA41E17BBEF2DA2AB03ADF3074BA1DA15BCC84805B89B9DA88E9B400AFB7E3BC8338D354DA953AC0BAD822756CA92E5DD9507F42BFEFCCB32B4B91A2BE5EF34C2CF1177EAAFB250AC9ADEC4BE71807589F1003227F9B76B74E07BA67AC60819B2AF766A47FFFC7B76D3A7C077F5EC69AEEA3E963859B82C2ADE58BEC2152EC8205110975D37C6505E0DC776FDE071097E93013D1004F4E1A2FD79B877ED5025F527F3BFF137F041BB9BD001E949F08B4CF88DFD32FC7CDBCECCFDB0FA2DE7823E110BCFF58A412CEA2795753E9C89678C3AE24268F7489F72974B6955EDD04E190D99BB0D7A252FAD5BBA606C1A1F3ACA733BFAE3309EA0A6EB7D07E36D8CA336D2644FCE1A41895D014D1A60CB106F3F8075F9378461738D63D115D00B024C677801050A1B0B50DE057F85DB6AEB2C9D6BB7402A66E3AB4DB05C58BBDA12F695958B8AC7B4E45EC6C952F679C1EEBDF860E348982779AA6988EFC2AD1DC1EAE22A27A5B2C61C97B3B2493CB6C13C5F6E20A67B88D3C3ACCFAF0A425742DF240634D1EE593828FE6297446C076F979055988AB834B2BD82E14DC086400E1C956CC0C30CE7BFD962223D23FE9494964A811B93E8D7B8F34C89AAD45DD4113F2AE7BD94B53FC86E8B2AE82E51EC6F3EA4C30D60B86072748612D1607056B5FF6A4500EEE78A5A639C7B74169777626864DD9EAEF0E3AD8493D831F71DEA95BBFCF81423A266DE56F3A8FE8E6C3C0D612FB62BD642188CA71CB89834F30BCC28BD178845F1F6F46C03D306F7ED4E68759427AEC2701198C3C05D385DFAFD528CCE8425BC551469A0ED681BEE4D12A843E333B5A8E0517FC61906F9C4E7809BAED4D3D16EB22F1FA9AB402D988ED59F9FED0455E9260FD627A24A17FE7CB63E530B48F5FB6687A2E8C49DA79FBD69A3400056665DD11D19A2BC4DB1D374AB6A6E42472A27AC6B98F676E8EDAADD514F6D44DEECDAB5A6DFA0F84F139A803A2524BF335DC52EA58FA50D98FB5CD55D5D50A663CF647EEE56FE8E664B3BCAF9E333978A7946973FD113E4FD3924E6C09E60386444214DFA7A4D671FC23890637EB859134D79E265C59CA3ECCDDFA018223C9BAE1CCA103962078BC5F0DD02246FA28324F7CB2FCFAD07C25B4BC2D888069B0CF5F23C761C0E47109881CD31456A64B940B4BB9B4C2C3B8E6BA834AAAE69FDFC47D44B3C96887ABED36015E7B64E8542928F277CBD2D3C512C24DEEFE590E81C684E063E7AADCF117B48943DB771FC2207F57A745357555D419C9CDCA35CC1A7100A6913A3B6AACF796FE3F94DD2F818982716CE0316542A1B957E12DA43E231542CC14FCC66D728A68326B2BC311248330F3E98F81EA38CA924A8E4DA97CF673842C759F935BE88163CE97FE4D9457176F5B8908AF948F74D5D1DDBC521825D931C63CA8A8E12242626305AB6A2E0624564EE041983C18C2952EC3D9D159BDE3985CF77897EE2DC888112721D4854E914A5397E08B54F4A54323FF820821BE026EA091ECA6B7D80D91E3DCA2EF7848B86FCA6BB40CE48271E1008368E3EBB5E395E1CCD0D178F1A6257D26B6BA4B7CE532CAA1E76CE28FA4CF9E029E2482B94D3ACF97A326D235D1BDC89F70002198451D9F1F12CCD5BCAECDDE9E14AC80742EB31E6464C83210A39F35098BE0378D074CE1CCD1EBC1C7770F778D605F2BE59DB7EA07D80CCDF55F16E985B142FB7BDA07AA7DCA5B201E1950CF9A728F21E9A9D8AC4D1327E3BC0FF339A250522F631DF2E75955154893E4A1AAF9866FEE1637EE1AA5106D244E99E6F31FC5601BB7B79BAD82860B1D6059D9B132E026418020DB06EB8391FA15B7A0F29E36D966ABD3D2A2FF3F2AAC34C8B45C7D2355EDBB80B224BC106EBC6750E55070F85A7CB6003394E5161AE26F5ABF83F0DCCCF69B86139AF8694FE1DC00781EAE09CDB421814878043DC9B0530E5545A165E39A9B7DE88B4AD2AEB90D3C329412ED2FE1D97B732C8439DF4F83D228835B538DC278FF0A2DC42F41B00CE3ACA06B05C4839B896931515D78EA3673A378279F4E89CE08E3453FF2FB453BE031C6318628A731D029FC7BEA2BA5EAC4916278B938A6A6ACEF5BFE2158F2AF43D8E56A0649DF28A250D2F2536ABDE1E008EB631F4BD0EB55573A40539A6004181A9D2BF7A1E53504F11E014840733844131AC668946E5B827289AB6B21366C5D0E2649219B92C4760DFB705F7F61A96564C9E840D14B0BB0DA82DA50F8B8E752BBFEA3B0A337BE124F72D8F8249195BC19C3E0B62EAE496D38CF7500B4F10665FC2D28B9EA935F7E316472F4FF401267541BDB62301554B2009928C6445BBD0EF21D09972F35081ABA9091A6C23FED29F5CF9E0779F7EFBAD88E62A454442B30079BE0AC9C64826B98C1E1001CB0FB0F0A95F7965FE9312BFDAEC33F95065C8E59D3950F80ADC7FB334F202D3E5F8DA481C9B54A75983930FD1E5ACD16284F07193FBCB50D0DC00EFF8203144C11EC61420FC32D7982CE896406BE769A75DD8D3CAC753ABE5A278655BF54BE33A1B8374EBEEFF212C39CE514668F1C456EAA2532828C84293F1A5BC9EB5DEDF558A9B4C1239F77272C67E1AB28E1EFEC5893E09C10662B53C8B8255B1C8DC8F8E5120A25C75EEFE79C43F7A8B37DF9D1E4F32486933DA1CB0664C5DB39E21BC227B0CDFE7A5507F07F218A7A47DEBCD9DAD7247B4D045A13AD4F75EAD2D45C339D0DF04577F2E0FDC780392553033C738852B1BE4E63EA3897D6C9C4B11AD6B58D3E2D342D32840F649DD83E759866B7381A84C8ADDDF413FAE18E6431B1EEA73A56CD889B76BC9786BEDEDCA2541E4C9B24E28F58AD374C1D93DF2D3F2C37EC594A0498C574579A7332F72C0F9750877FAD5B90B968D88F11682C4071E4EA38B816AEAD6BE54D2F371324F2475B862C75424ECF9858AA4E200CFBA412D7E3E6C308D8DE11DD185331AF9D41AFE8879965D6746EF21FD98D3ED3806FB5C4619C98E347D76B8B89849395561EE286DFDFC6A04E1D47E9F5B5B49257784C39364DFA88AD630DFA59CCA3237F4A2B141A813D22C6FFE73C2D99ADC824D93E06A54B6DE62C3125D94B49E950DEC361F961F56D3671C9925377F6E670665322B8489E833D3830ECCDD0F53F4A4F9D68F1445F3AED5C9D766409B59BAE7A72912E98B3BB57342D29B6ACFD14336B7B8B6B7549AF8CC8845E10C2811287281985D5D47685FC589F2678ED893F57B85ACED75632E50DE5E074E6CEDCF1AD499BCE67A7F498564DEEC677C708388DE8FD7B099CFC116096C45FE28890B5EAF06169939FDA35E1215F238E8CDEDFE670065F5DE3272A232FD53C250F5D779B31694FBA91B554803676E4DEA288463FE1063009E9CB76C317DB400ACF4D2D2B6D16EDEBA4108913F60AEB252CDE413690CEEFDCFA638963DBD04F4CF21AD74DDE65F0F1E7CE70AF101A6DE9A59DB21D38027DBBF76167827950B69418266AFA444C728DE3624A1C81E5B1641DBE879CD822FB2303CC3A9FCEEFE3DDF7DBD0B7057248A28D6062D76EB13B92C9C9D003B69E1842A54C09CF6B484520815E2BB237288C64FC696FD3BC45DB30CB86465DF1188BF47956E5B916A8009715CC9A9A6DCE44C54F928816B41D018C5FE652FFE4E33F352D383A9C1365F02ABFD647BD6B42AD163730F8BFDA1E2BE5F614D79597825BA09F457D3CBE7561E7E89EAF059E977D1EE88848B781F21F723890FF1F9873928412C8F11EEDD2C0C39C9512790986A19E17B2B70A4D7CF49D9D18CAA0C2023134CACD169200D8817FA321F04ACC910613DFF250EB325DBEF29EB5611B2AD2A23EDD538049B3F43EFEB4D60983792B4BF05567944AADB7AC4D3A5D80A1B9D8448B4C0C115C3B5AD3885353F47D5FCB9B7D6446F1A7210BBC667FC411415F23CD40A2A3D64061D71C67191571A97D01088A24B6711567FC89106732D8892FF985B8E6CF70163829CC085BE4E408315361BB1B2003D6413220B134506D3C304C0BBBA9C9C45D3651E0571B6B115177213D8595E143DB90BD72F7EB974D8D0A0317409D64D5837EAEC9B8D44DD7ECFF6CDA9F729382A43B379CBDD43FFB18AEA35C1A996CEF1488D3B7A81EE7CFC0B9623418AB3919A6EDDB99F222F0DDDB2F32A20C8F84FBF4C49B4CB3EB50D9C4CD25A6F7175467066D25E6437B67F2DBC70C2E6EB0BDE2386D03014A789FB6DC08EE33C0C67951DA9D74B9C94845D2A99037E095FEF7919920FE526EB5DD0BA1F97DFBD2DDC31609C1B7B45EC3ADB586FE3030A0C7A9DD034A3C2E6F9849093CEE10A181953547F8BE328720A4A5A8290B5EE00000000000000000000000000000000000000000000060B10181A21""") + ), + new SigVerTestCase( + TestUtils.hexDecode(""" +6C9E7A1EE36625760E5D2F33DF2929DA56203234069160E5F2BF039C11062273073C237566CE055D871F38ACD1A9859A824467F19BE68E4F00645D225C42C85A557D2C5ECB442B0F028A6528898EE2B673D863F32EB9EC8164127541F32519BB88E034A03F46F7D193CD3DFBADF63557926C5C8F5B766A7FC5EC8B3F948BF7A821B54C9441AB0BD833FD6354CEC706FAA500ABB5289B90B1BF917677A29D115F0094BDB48DC72E261DBA120BA6FF5E52A01B178981DD8296444656D9442DF9CBB6BFDAE56A230F6F29F94CDCC265576AA8752ACED07E99895CAEF0168BF83D23FDADFBB928CBCDABA25FE2CD26ADDFB0DACD74940F351426942F176FFBC5F3456DB7C912AA16B86D0745F87C9F45370A8456A1ADB51DB4052B5C9EAF60AD7B80A42EA4BF92C841273AD761DEDB0D34BF579600B149FCCD42AB1549BA0ABEDA57EF71D1FCA5702AAD083299BB98300189C25F3B270A87658D0B2EA56524147F739EB6C676D7BE73DD3B95B10C55AB46FD01549C5168BF7DA13A499785F35A1E3B56F4C567F54EA9AA2817A336383643FA2EA31FB1B73E10248DFCA05C04131266498E1C9491135A50E63D02FADF4165FC9E15E3E1B32FAB8337684C49193E1BC4EDEAE373A267A714AC1F909CC657CD8066646327E0EEA041AC9F2AEFFC80691BF60D3C94C642557E4299D395922216C65E75B7E1A5028960384BF816C9F7054829E7985B5841A733F33FCE2455EFC89BAE84B47990E8D0AFC6193E4AF9BC680AE24FE591E88BA6A2AE12DA3858D21F492D24ABC4FE4FD52D5ABF24BD254687B918792F0A003A5222DF45038685C725CE7579E02CB168BBC666ABF669856E10537C9291692C0CB0CFA906270AC2C7B7DC31D4F9283CB2DB8A462AEC0B9807BBF4AB4576FEC6226B4179322B67AEA53BDDF9C9BE5E0DBC43F78743068AB5BE49F0E62F8E2EB1B6C6736C05C9413D065CE0CCB790548041D7E832881A839B5729AF94AB79FD8A16DFFF78CAAA141D97CC0650F86262F26159BE8B361A4A041E9A0B6511BBE3355A4BF57AC09848847EE0243C3BA774776F7E9A227275D74E6E3101D382818763ED1E1353AB9EECCD920CD28922D559A4048F40F062164CB661C4F4AFA81A3D55933C4791EDDAA3939E5AC342B0AD1F438A532C6CE786681A870D94EC88A334CCEFC6ACE7D988A1A82BC0ACCE785F123BE23A7C92AF108E5ED4F0869E22DAE273556D1DE386623A6C3F115BBD119271D3FBA796F618B53959FB98012E7D5B9AC688940B87E2C9C065524A00D3A4F4DBF52F4B1A63EF5C46193BADF7AD7F988D4464345B2C3E549684F2F905F6F89DD641473EC05108A52D8DBB91768C541DE520B17666970AAEB506E75D8EE9F4B4455B71E0088AB25655213B75859D25F559D3C324D283D397ABE6F0AAA386815768D03357D775964902413153E3560CCEF1FD44B65FF1B287A92A9693F034B7EE668934702D7501CAF6DA4EE98AF4E8E64B0340E0BB8BDC533B0EFEE1915A4B68B93C5E95321EEDC234AEFE71AE2E5DACEC2F52F83723A2392A7F8E13BC0301CD104D852E62A7F828AD329B3D9596C58E13FCC0ED96C1C48D82A2C0F4D9D24DD8421FDCCEFD497A9B05FFC50904770401373FEE7DC73773418AEB4A1F599A4BB38EDE8D10A3CC83A1C72DE921969E3CE3E8EF2F7DA89D344C80D61CF9C5A423B1A4F3567D96DB2DA3DB9B5B5FA68156BE7452C8A0181BB9F0DC75CD9750883D0DDAE53FC156D67A74200869046B41DF4BC4396993C08AA4897A0BDDEFB55F69CC1C4D7B5FB150408427B416F73183F2B3CC16E3B7DA63CEE1143ADA1A056626A077B6D21C3DD974ED907C5A094019225737EFB93319AD3B40A4F434AE49D28391C17A999C744A68C55A91B862729583D3DA46EE70C5CC461694167D32D21DE75327732C63BBFBD7B30DBF2057A0D681519F6E4AF608D4BCD0B4750726770E156AEDE85417BD759D5FFE401CB2996F34434DB428D9A417037201FCD260FAA98084502EED5C27A8916E44F5929819D21A69CE16BCDC3CC8141E285EF897B1402C15C952590119051E369A1B7BE443FEAE6E32BC8F3D647FC5315A5200CD5238DC6677466EA86EF8D18E5A79F262483E896B8277C741F516FC040C1090F2495BF1650B02AF30456733A071AF47D7A15BD8E32A49806455D3BEA74AEF5D00906AD2F0C045354EFDE7C9A276E73D9EDD11D1CA5C297B9A6851E7F67E21EB061BB55D9E673C4A75FEB84D52629EECC53C24BEA95153051AC206C87DF55410CA1FE6CFC3F403A6D9D43EA84C60C945E642B2836338B5AF9F69E52708B2E225933DB320BB3F790D397F22D7B6F8A433CDACE9810AA0E27C699555530C562DBF7517A4162628BF10D1B6DBACEF5C9ED51E55D9A89D60E0FC378C47A21D5E0F2DC3BCEF5E05C6E0261530FB027E5032558CA2B47005BDDE99909930391EAD7F3F0A96B3DEDA54A11145F530E51DEF892E5AB0204D614E6E38AFE79CA92C28158D570120353B7A4DE0889846D835294939557ED0AEDA270D4D73ED84D3D49F9F032D43457BF59BB7D66359DC53F9B46963B21784B06CBCF04BEC1E33A33371532716C9EDB3FBEDB81999B4372D0945C10AE826C60FFE93170B6D294B3891B0D2A7B35B28A8971845DC2FECE237B80F20B379CC4D136DAB3FBB3792C63EC61F5C755BC9DB35086FBF46D2B7970DCA2A8523FDB4C7A0B8E42F8AF9ACAD2A0EFC113602A4EA62E4EBB7D269C3A40BA2C44EDD2956"""), + TestUtils.hexDecode(""" +C1E665BF7B8BD0198F069CA17EFC55B7EBBF9CC9D41140BDD0B83AA08062FFC717D3F6C22DF38EEFAA6EEC91760CAE0B3DFEAB78B03A7AB7A993B2097B7B887B9812AE2D0892B696374C034FC9E95083C2B61B09DE97D9C500FE55E489C53CAEBDB57BC69071C15808890F8A007BB5FE773CCFB729463113D93E9EC9EABE2047"""), + TestUtils.hexDecode(""" +051F8A9A5DC6D35B1485288359F818DEB027E1231DA8C048E79E9FE228AA0E9F1C0B7F4C573B5DB8CCAEBBAE8EE38D8FAEFD3B8E7730BDC0E9DE365B20E5A0F9635A0B39C7C0D6163B7876ECC6ABCD8A5F608E7253537C1C94C209C8448E02806B2B5EAFAE2483170B4E4450380C2A87A51F82B179EE0F46509404A3A9BD74D04BD75635B797B500F656ACAE5DD76B04741792112579E24081A6C88BF4981346E2B3D38291026D3AE47BDA50AB0B23B0881148489CBD057CDE9A4F6FF108B7ECCEA44D599CE3ADED82AE0E8F74DB7D604161C8664B7389497EC9F35C46FEC064BB867E867E9309C10FBC07BD5E7B8A74BBEBC1BD0E4A9B36EFE297E9F2D23DE32ED704EAA377F5C3BC4BABCCAD5B4B6B9A137F23C46C0423ABA3F1AFF00C6071CBA51B7D0A8E677F5138DB7C013CAEE1F68501430F0F448AB283692A18D15D8A46BA620EA906A3032570A659F594236F0512389E1DE63B8E40AC22DB79DE60CCB9BCF0B20EBEF676A91AABCD01D3AF882931AFF8C86A8C946E09B8B5CFDE62D53A03DF07163B081B293EA0287AEB97D1762F34361DDE654D400DFAE5B351D90742A0A269865D49C9221DD89E42FFA63EDDF449B10458CFE2EA7E1A16BD22FE73F208B4472DA8094F28CB9DCAED6E843C57E9E3258BEADA48D7761FDE0104AC6F0CE09F95E1F4AFF00515AC2E3703D2FC6D757B12DFDC044E854E50FF2D897900B0B59BED90BA4201694E29E6A830D8039CD835C706EF59E7A6B0ACA7B7D0B40D264661711E0372BAB7410A74460D07FA988A8617D31074950838411037307B052FD536822608F9D15BAA780AFAE1A8D87BF844D3A4FB31A176BBCBEA46A72BA990FCF821AC3A73ACA01E09A20AB93FC737ED4C4DC482BF9BA21D7178D24DD5D6A29633386933A3E8F28982731F07606AF28BD2D81004B044B4EAAE67E29840BC78EA66FF840031D8B2894B603733E1A0398FB0E4952B2ABC567668443581C860F87A76774E6742807C39FE99269E3199DAD02B246D7AC24E5BD9DD91F7D16A76E72318882FA21672A7D5B1A4F212954BE2B19897243F60C18D1DED2AFDF69DAB8C9B10342471C633B33C52E95A85D3142F2E46C681AF373C5E92BC948FBD31207F015DD32DE2591DF4639E4E563344D440653592EF2685E1320AB9E51837F6C06D07E5462599FC6F8BB120826E738E2223CD4B8C7CE446ECE681DC6D6BEF1D6385B0AE7E404F502B87989D969B81CF42085A7B58A41EF73EDC73056DA72EF65A7AC8E284E7F51E723102CFEF903688F870CEF1C7E5264330E3033691680050E926E93A1C0C4161A7DCA14A0FF338D431D68FAC204DA28CCD1CE7BA3B7F3C45B4FC74D9E754A1A2F7F23F0FBE8D2FF01CE4683D8842E8A1528589E7D9260368A654CB514A85DA9C2EAB74C66FA17FDFB256D585D28C1DBA35E18779D7B6DB876CC0A98CFF752A0E8DFDD532ECB04C4101AF32E689D13874B9F20AF652069C1458D7FB382E317AF49083B5870078B39221464F376EC0BC2DC1C3FAF10EA4EA87A2F9D547B535F60406E8E68AD190CD4F00EFDCD9D54D4810F31B9F68F0D95E32CDF2747B9C20FCD1694FE034EF6B5460F163AC78BA235A441DB2B3AE84BC28CEEED7B3FC2A4D63330D14186658788DFD7652E477B1310317C86921394219D75FB6FC319575745589F9E2096801E57E6AED2369FE115C2D937EBEA3602194B7432B01F55E6C9572CD0FF8BE8A4796815914D5F64D93E0E709C3CF88741C851C8BFC4CCE6F0AE60A6D2F4DC6FD8AFC82E065956971FB8B4160AD68EF7BFCB3A9694CC7EDEF64FF08011B183BEB7A2D3D9024753B59900D27F52DF6D4B2576BABA673A0E33CC57B501E1C74F63A988E1A157078FA8B3F2A143CC9D41A35412B4E0CE6B1D9CFAE7470BF4C778D026A9AF86DF7F974E2414FD7C5F0FF6D62293C6E2A62D4C5268CD0B604047C9658F97D9A7B86E1C953FFF95CB478028FDCAE6E8F208AA208A282446B2CE8B4C7E893E269FA8E02C082F82966A4AE3FD86BE89A8CC8BB3D6B105A91DCF76FEF700E5AA4A15BA0F753129D3369915D7E896527CF6E71C363EF65B2218A5FCB8D8FD96D6A63A8BC547EFC942DCE1276E268841BA00E35769B4AC706BD65B275BABDD530771D854EC38AC0529729786A86C7C4161B3E7074023516C84B4B4776AC47C2ED1587861126A7A707978F2B2B2972C20F237FC223B56A67538F9241D926DB7C992A3FDFDF999884EF83EAC7DA0F6523F53CD40E473AD370C77B30DB2FE408783D24CF4C3512E3C6B677C41A67849FA1792313581EBBDB7BE0BB3EE85330FED8B5A1915F6343F3B7C928CD363463385436038B64BAB5D055BC39D18F9A1A8196AF8DDA5A1F428434958F5C89F07D7A53CFF2118E80060C5ACA71975C4C92A589EBF5746AC92C50FC1F915C146C2DEE7531B24970790A4AA7DAC425940AFC4C88ABEB998D549681C95ACBE9F7E274521D44E9EB759C2946504161AE7FFEDAD3E62D045AD77FE8C2B8ED529843DD341E2E50559A29AE26D431C9634C4C19A84FA0257F71CDF27C33F14D57347BE8B19D254E3C353CDCA10489F06214161AEB2A9D3049B3CE4689503621C46D192C1421B4B033775D9218DD2E216600E64D977CAB0E1675666A7CA773E4E139DD4EBE94CE35A28284755C52BE490514B25FFCA4174F54E8A5F715F924949C1467A282D7F2DB468DF363F9A55E5D7858D8F95D8083D6A594DC1B07A8C4FD4AAAEA0785EA3D9B50798F0A96AA386F17C2BFB94FA8EA3B5EF71012AF9285CADB1FE330A267555A942682F9333AF2E81515969B76FDC020F9CD29E848B94F26F4B53CA5144CBCDA1AB6CD2FACBAB0A2FC0F5B88DA0AC0EC08B9EDA7CAEF502FDA52006815743520F841CFEC3B4D9AA732DE408D6FB14739E8FE77CDDB68A5F6AA215B588F1491988B4460F6949AD647DE9105CA50CFB413A971BC8E6179F0724FC28D1A7D30C41180735F4FF6167810D9E88A5F7FDF791BFB474BB5478544EA74C9F07598D038CBBA17B83228A18B2AB09A8BBD2D2205EECDF01044D5A1B2BD50D2C8E3D5511450A4E594C1CE7067A6E14128BBB36E95C143EE6A51CA0EEBDBE47E9C5A87E81BB904013DC892D03F483B1DC82986DCE7A6E10192E6743283202D78D11B2169602A75C2A688DBAD50C9FDF1A1A15A470D882ED4B5207E659A94776ABC3D3583E1D2E85291D3726E75B7AEF9344180D325583A05266C196ED367E906121C33E701D428B46865BF32AEA4A90262866A024209A7663EDA4C340B5AF3E899F009EEB5E8D5003635EED501CC02D5D11F504C823C17E961D0BF611519961BF422647D97119F5745478888BCCE367639772953C5731434B28913F3F709AF455053F6B09519AEB6B755CB02CE74DD814714A2E0B477C05202092525EC03C5B365A75086E3281D4BB5C3AD9D742806E58B5CE4E1E95269AB18B68B2928BFCF7EA683967C0B88ADA99FF35E1D5A661CDFAD76774B42F858AA54626B88050D992FFDE16FAD3A8CA496CC6BE339977BE24D33E8BAB86B421F4BAA9C12A93117E43415929F0C4DBC9737EA5586780886A8EF4E4295DDBC967A2B5523FAEE0C060468F9704509C4CB14028E8A1672609A8CED43F1B06981FBFDFD52296D7BD3B4AE68E7D54BB2405799278AE29B66E258D3B9D276FD34E192BDE869092F6A7F761C6DDB0DE9454823256C7B17ABB91003B1A3B66CBCD4F9ED068409161635F6DF9459AC382044EC14FE8B2A586FE02C74232BBBF27800ECF627AD1C6ECC93C13EDA2DC20C8D6714C519D6A571E708787BF342DBCDE10EB1BCA5A7FCD971CA52BB68FB33ECB7F90AAF739F0C5B61BFED72CDB46A712DB6928F84892D3EC2F6C7023A6B664CE9CFDC33D2F09D38B5E4D182C73FF1D7B474C8AD6E883ABC78FEC75C8A390CEA561A86B92E2A4A1950997594C29A35E4A71B0E484FCDA63E5EC9666E0A463325DBCF7258D36B85099AB7C81E70FA66F1A471D4C1593AE68404F31AD2667017C9B5B3843FBC48D831F6A9B5FAF7C73A8478A7DADF28FBD9DDF979418870AE61E94C6BD47FF2C39073AAE16FF18B161B9B21413E66E489EF9F8784E5DCBBE29127B0C51A5C1E2A04E9C8794964D1823ACEB9ED0DD555964687848629EE06B0712483CA30D6D4A91E047EA33D30A062D8249278CDCBBA2A1B3C133D3E671FACB034AD0F9AA40628C0E2288B56F7A76DCDFEA762A8DB323B44925285557C3501999CBE145D15EA82169007A97EABABBE69479E03D40F2FE9217F14664726DCEA227107412B3CC742E4ED168E051D9AD4468131AB035708ABAD78659CCF5988F70680C124468CB80BD9924B0E41CB25AA69E7877CF5EA348403AD0899A5FCF35D4F22F3A73F0207E96785F4EB9AB93B6F10EE0B247D31F3D62A85B99C88CD3B19BB68E69C51AD5B0A8E9E34ED611E24FE2644F1697A8A11B64B578FEE1C5CB31A605CD987D765FB68D833E4BE9358D869F4DE0362E6889FBE8E95B861E078CE6CF0FF35768AD49803A71E8DC60296032E50A9D0A4E64A3D4661E7C55DAFC6FDD1B18EB1003D290BE486C520A2F8F0EFC1CD2CEFBF7E2459CC7BA88695D1122A7494A3A41C329EED2A8CD2282A607F93A2B7DADF0F32414C6BA9BEC0CB00000000000000000000000000000000000000000003090D101922""") + ), + new SigVerTestCase( + TestUtils.hexDecode(""" +6C9E7A1EE36625760E5D2F33DF2929DA56203234069160E5F2BF039C11062273073C237566CE055D871F38ACD1A9859A824467F19BE68E4F00645D225C42C85A557D2C5ECB442B0F028A6528898EE2B673D863F32EB9EC8164127541F32519BB88E034A03F46F7D193CD3DFBADF63557926C5C8F5B766A7FC5EC8B3F948BF7A821B54C9441AB0BD833FD6354CEC706FAA500ABB5289B90B1BF917677A29D115F0094BDB48DC72E261DBA120BA6FF5E52A01B178981DD8296444656D9442DF9CBB6BFDAE56A230F6F29F94CDCC265576AA8752ACED07E99895CAEF0168BF83D23FDADFBB928CBCDABA25FE2CD26ADDFB0DACD74940F351426942F176FFBC5F3456DB7C912AA16B86D0745F87C9F45370A8456A1ADB51DB4052B5C9EAF60AD7B80A42EA4BF92C841273AD761DEDB0D34BF579600B149FCCD42AB1549BA0ABEDA57EF71D1FCA5702AAD083299BB98300189C25F3B270A87658D0B2EA56524147F739EB6C676D7BE73DD3B95B10C55AB46FD01549C5168BF7DA13A499785F35A1E3B56F4C567F54EA9AA2817A336383643FA2EA31FB1B73E10248DFCA05C04131266498E1C9491135A50E63D02FADF4165FC9E15E3E1B32FAB8337684C49193E1BC4EDEAE373A267A714AC1F909CC657CD8066646327E0EEA041AC9F2AEFFC80691BF60D3C94C642557E4299D395922216C65E75B7E1A5028960384BF816C9F7054829E7985B5841A733F33FCE2455EFC89BAE84B47990E8D0AFC6193E4AF9BC680AE24FE591E88BA6A2AE12DA3858D21F492D24ABC4FE4FD52D5ABF24BD254687B918792F0A003A5222DF45038685C725CE7579E02CB168BBC666ABF669856E10537C9291692C0CB0CFA906270AC2C7B7DC31D4F9283CB2DB8A462AEC0B9807BBF4AB4576FEC6226B4179322B67AEA53BDDF9C9BE5E0DBC43F78743068AB5BE49F0E62F8E2EB1B6C6736C05C9413D065CE0CCB790548041D7E832881A839B5729AF94AB79FD8A16DFFF78CAAA141D97CC0650F86262F26159BE8B361A4A041E9A0B6511BBE3355A4BF57AC09848847EE0243C3BA774776F7E9A227275D74E6E3101D382818763ED1E1353AB9EECCD920CD28922D559A4048F40F062164CB661C4F4AFA81A3D55933C4791EDDAA3939E5AC342B0AD1F438A532C6CE786681A870D94EC88A334CCEFC6ACE7D988A1A82BC0ACCE785F123BE23A7C92AF108E5ED4F0869E22DAE273556D1DE386623A6C3F115BBD119271D3FBA796F618B53959FB98012E7D5B9AC688940B87E2C9C065524A00D3A4F4DBF52F4B1A63EF5C46193BADF7AD7F988D4464345B2C3E549684F2F905F6F89DD641473EC05108A52D8DBB91768C541DE520B17666970AAEB506E75D8EE9F4B4455B71E0088AB25655213B75859D25F559D3C324D283D397ABE6F0AAA386815768D03357D775964902413153E3560CCEF1FD44B65FF1B287A92A9693F034B7EE668934702D7501CAF6DA4EE98AF4E8E64B0340E0BB8BDC533B0EFEE1915A4B68B93C5E95321EEDC234AEFE71AE2E5DACEC2F52F83723A2392A7F8E13BC0301CD104D852E62A7F828AD329B3D9596C58E13FCC0ED96C1C48D82A2C0F4D9D24DD8421FDCCEFD497A9B05FFC50904770401373FEE7DC73773418AEB4A1F599A4BB38EDE8D10A3CC83A1C72DE921969E3CE3E8EF2F7DA89D344C80D61CF9C5A423B1A4F3567D96DB2DA3DB9B5B5FA68156BE7452C8A0181BB9F0DC75CD9750883D0DDAE53FC156D67A74200869046B41DF4BC4396993C08AA4897A0BDDEFB55F69CC1C4D7B5FB150408427B416F73183F2B3CC16E3B7DA63CEE1143ADA1A056626A077B6D21C3DD974ED907C5A094019225737EFB93319AD3B40A4F434AE49D28391C17A999C744A68C55A91B862729583D3DA46EE70C5CC461694167D32D21DE75327732C63BBFBD7B30DBF2057A0D681519F6E4AF608D4BCD0B4750726770E156AEDE85417BD759D5FFE401CB2996F34434DB428D9A417037201FCD260FAA98084502EED5C27A8916E44F5929819D21A69CE16BCDC3CC8141E285EF897B1402C15C952590119051E369A1B7BE443FEAE6E32BC8F3D647FC5315A5200CD5238DC6677466EA86EF8D18E5A79F262483E896B8277C741F516FC040C1090F2495BF1650B02AF30456733A071AF47D7A15BD8E32A49806455D3BEA74AEF5D00906AD2F0C045354EFDE7C9A276E73D9EDD11D1CA5C297B9A6851E7F67E21EB061BB55D9E673C4A75FEB84D52629EECC53C24BEA95153051AC206C87DF55410CA1FE6CFC3F403A6D9D43EA84C60C945E642B2836338B5AF9F69E52708B2E225933DB320BB3F790D397F22D7B6F8A433CDACE9810AA0E27C699555530C562DBF7517A4162628BF10D1B6DBACEF5C9ED51E55D9A89D60E0FC378C47A21D5E0F2DC3BCEF5E05C6E0261530FB027E5032558CA2B47005BDDE99909930391EAD7F3F0A96B3DEDA54A11145F530E51DEF892E5AB0204D614E6E38AFE79CA92C28158D570120353B7A4DE0889846D835294939557ED0AEDA270D4D73ED84D3D49F9F032D43457BF59BB7D66359DC53F9B46963B21784B06CBCF04BEC1E33A33371532716C9EDB3FBEDB81999B4372D0945C10AE826C60FFE93170B6D294B3891B0D2A7B35B28A8971845DC2FECE237B80F20B379CC4D136DAB3FBB3792C63EC61F5C755BC9DB35086FBF46D2B7970DCA2A8523FDB4C7A0B8E42F8AF9ACAD2A0EFC113602A4EA62E4EBB7D269C3A40BA2C44EDD2956"""), + TestUtils.hexDecode(""" +62C2A85A6AE40091AE35068EB3E5B54803F495D49BC177F7A29282DF0C900E86F66155B4026064E7D6CF7A171F8BBB33449232EB5D7DB2B776ABBACECCD660294C25196E19FADA35E0F3524D78EDA25D614FB56DBA5BAC10D06EAEDD9644DA291DF305C1E91C82FA00EC470A8E822525895113A6FF7D1D52E7038B9CF4DB2227"""), + TestUtils.hexDecode(""" +9B829A093EC253FF3D955EBA3C0FDA29CD14089C6D699F26FC62BCD40F43D1582F2B693138AACA59A162CEFBDA6328F1BD67690C63B903F5062DCDFFA840DC2DFD4051F82A557FFDAAE8F4A4FB340D6F4AF03A19AB928F42DFD29FF8D028333A0C336D253C826175C5A194C0441DAC1C5A4C4A3E0B8394E43678DC915BC98628BF565C9E751BF9801DD6AD4A3621B50C8DD1520F0CFE475F5BF843DC2568B263978587322FD1D2709ECD869A77F054C0A45D466D297ED9B63F10020826836F531A06DFBE20BFBA0B3F204033783C5505BD82DE732204917E3DA12316559D07366600CD18EE2A329AB3B20BB0C9C607D0660044D2A9ACC5D25806F89DFD5813C9E54E0CDFC190A206300FBC8E2561BF3F23D04052902E49CD5DA530A4D2BC2E5F47EE93D0588AA66EC8CAFDD4B353D73B6C1765211405C080A614129CF9346A1593503AD75EB9C3CCC99DBCE1D937AEB7929A1B5351BE262FB2B41FCA6DD965CE596DBE39D07D20281A2ED74C35FAA474EC425A897978FAD88D470502008D9A0E08DFA2F6C33A0B4CF2456951109BF4F877D74D7681CF287F6DCFAE24D1FCB0FC69D7C4D33E20536C64ACE18F04A2AA8E767C24068F4BA45C4C49DC3B43AF803610F300D01C5CD9ED92F33BAC270ECE09EBA2CA0FBA180CD135E420471A7C6CA249D877DE616F054711B3DA2DFA5D2D3FE774F802F4880E4400FBE4D12B8D678DB076020D356769060253E5D68F665FBCE0EC702F42B94E2B0C8359CF4D6EBCDEDA9FAC8F2FE95B9FDBB9346C06300F60FFD4FAEBA01929CEDF0F15021689B6EFF9298BFB8E514D925541CE2130EE1F25ED6EA895F432987AE4A2CAE01B5F4691DEBF12129EB19C2890A9D268774881F151A06FE42656CCAFEAFFF01E3EBF52C6716CB28BCB6719F7552731C275DA226914D733AEC1BD599AED7BC0646B8E3D9E0F3B771295D43391F00293401E6331E37E779EA8914E7F03B4CA3D1AFAD797617D9D0BBC6020E1B40B431B930D19E0888518D6ED2E6D32BD872B9A416E0B47133867FEC96A88C6B67449E8881B8A455D1816BE7DCB22287D63DBBD87E571F6887AD3D6DDC08C0B710395A12570AE985AB08393BF99DF1A1EDEA499BCBBC2F2EC05FA3EE982E34814F56373891282882A05711EE9A906CFE5952A6AF64379854A4DEBEC24C22F69065D6FC392B4A687D66528615AE301C82D6C694D358B71451A536039368D05C3C240062E455A119EF5A1737D732C1079C7CBA9A05D9D8119CD94497CBE2A275C69D6623628ADBCDEDEAAA143073C6EC43C40229606E6AEB982CE1827F875FF0A6921E0D6D08F605EBCF85EAF0C4AFBD067A14BF9FA6C7A657213C04FCB93630D892E8B340217EB07EFE9CD320DA3DE466169001566373F589A4C48BE25EAB1E6A612187F110661BCED6C2FE2583F424641A420A0DE61B39026172DDC93EF444EADF8ED5CB674F0586307F2886CAEECBBF78A4AFB96ADE18F0504734A082C168921005300431BAAA9FFBCFC96D272E8FD9A10B7F963BA868A273CADA8082353C0E1D7C8BD323779D9BB23CE678B3A5AAD2B6836F65C0F79E32D08006C72EB2431FF9797E7630F27B89635F08FC92203012EAF6B009A32437ED076D66E4CC6074B1CCD0D2176FBE508E43EDDA9185A91E2AFBD235EA8944B711B8C7D0A4132351FCAB1ABC338C3419C9993FD56FC3C89A08B0D8F28914FBB4840A7D02F209D1EFD208A8E47902E11C1FA92CBA1851FF0935D3EFA705FF4BA44A6D4A675BD979947CE8FAEC565B3BAA9D441AF91F429D42C3E3F683E0202C61318344C7865957131A1F9EB822999F137C0A930744CDC698B3D41226A32268C968F576AFB37D8BB4E533B077124626535AC470D649A817F42243CB7CC73F0837A6527C2890ABE5BB762174ECCEF9B2F9A3FC77866ED031947CE54EFB0DB647BC9AB219B974E0C42A53FF6C65C1A67924C1B0415C9B9CDE4887023FDA6DF9A2F3BBD7BE5FC23EDCB6CBF5CE5C0D6B75C2048F05C5AAD82C87F5D0E9A146C3CDF01A973E85ABB5DBF4B3834BCF7EC7FCA3636EA417B92E7838DE1A8527292FEC5183F21EED1485B4AEE3541C00E36E6D3AB5563F3DA1DB962B94FE6121D36273D2813E785E491BDCFC825B0E98539B7364BB73885EDDE73CBC41B7F680BB00D9EB3047956996B97A6994FDE741AF9D0B302E99D3573117B4B537B1A3C384589FBC24156141473FCDE30DBDD305A6E8FAFCECB98800348A5DC2940A8D5CF2005CEF09F49B5FD5B415BD63222BF23DBA151A0E1925FA6DF135075E02D5A7E734AF9B92E947191E7221F1122387DD17EC8A4D3582949B58C4EE75A0A83115D936F59653592A5F86FC2B7C277DE26526AB23AE4674417C9C9388B0338F81FEAA741C446CBCCAB5755F07A195325E708256AF861913F50AC03FF02DF181E414E185DD7CBA0714FBDA807D67C938CA36AD52BE1DA9CD4FEE14BF1961CC1C20D3268C5563BD5BCC10DCC0FA42F01B8E278D3B2F549D6A1B497C8DA54995D395CA6E761D3B776C1D012B1F9B39DD73CD831F6193847930AA15A4C3B139464E3F89AF3B1C583E4E986B80C4BF117DEDC1C09390560365754F402C35B06DE3DC45ADA558ABC7EB3A63580FD8C9F29D335A8D9797D1420D4E3EC0267078F68361B65DE8F6D153F38FFE6304F0B886E94AC959E71EF2AA546DEE0E00E39A3E8DB5869C4434E862E60AF5883DC6E905469ABE8A9DCFF2BC85D14F9CD6470F8B092DD622FDEE25678887B97B021013BDFC8CA38702A7F49BFE92A3BFFB8DAC66D888A070613BD09A6B2D6C2CBC9E61DF92BB128E8C87E241E83BDDBB294AA56A5B6E70742F6EFC321CBF8717DBB5EC7529E34B21C8A73CE9EE0B7D6A62C96137A19D4836D53BC4EB8C1551404CA5804C1CE2350EC41C117DEE4152B65F9BD050E5BDD4A8EC392624EB27927D21C6F3CCA0170EA9C74534C28EF5BB45FAA789A46C703A723A82EF4297F907A20FB4B91694D5598BFDF986E517D251A401D035C5995EF8CCE18BBCAA3C4320F0F90938F7D5D9B04E187BC72B7DF045AA554544368DD90F726115A48E3BE841086889FA99ED5ABCA67683D090A8F3002C164C7C431539C1C8FFA7B871F40B0F42237810E3F603C63DD59737AA7275862DFE9046D22D59754D3668826A410EDDAEDF804E16B8E6D01D7705F611123C3F6A3822479430AB3A10F79FE2295558B60DF5A7CB1F02ACF8EE05F74A38E025C1A6FE1C02EE50C2B5ACE98528523F5C16C620D78DBDD54B0D66BB1C2E832876C304D794DC28D1501840A94FE7ECB2A62C9B68EFCD6D60E9F12E79E6793424B66F1CDF7C16B0F39D03DC0A178F850B1BDDACB3629B456F6647D0B9AD45E0A635420C1E1081D0E99D8B5E912F295DFDD262100D5E95B030CDA6BE784F6D38ABC0AB5032B0D42C85ACF782D382BD0711A7B43CB7682E908D3E36132145A1FAEB6670B26A30917682E4BBBAAC884A7306192257E9ED98A771F707A1E14AEC44DB71359E49FE15529376DF4BE36A0D00241DFD320E93C8BD8BB651132C4917229A7E5284F83408E2FAC8588E3662F4AF09D4E3A8F97CC55B507A2374754B15B086175FB593B007ECD560F7AB9E7D6611D816FE58CBFD083D144E5D0BB7C4D76A510F56C7B3170ED5A4AF94D3042073F3720A8BD2DBE40A90AEC4765371C7F27036C75B3A05E08D3A0EA4EEE0C583196952636745A9556776489A46B7FE6884EC255032CA37CA59E33399206BDA71ECCDF7E901F57F7F11732FC86CD6F6BB761F612DCE82455C80382834A2F660D38CFEC1F63DE2AF8B1779394E23747980B3D4AE572409E03AEAB7A80FD951CFD64BFC061E4FABCB4BED38F1AB19C819A797E8C378010A56C3E7CE889DB8DCC832A637B4D1E04C2EEE52E2BBE8A64FE47EC9F3ACBB73D8AAF2DF8F14D67F92D2C80373D2180788FBEC28190CC824D90DD5DE2F4A95E0CD172C1D1D33D2E24B48A0611C908812BD1411DF363F40F317731DF586F7A156418F5EAD8C06E116F28B4D0A1D1E047FA249ED4CC653AFA03DF4631C80D529F886D1393C0E763C325FC3B1DB7DE834DC7A3775C5E0A8393256D9DF355D7B173BA5C0FA8C0807F8615E3EE5A5330F7CF408848188A46AA98BD6BBF5B6925667983D4354461B43E0E5A09FACEE9E285F2872F972F7121957C5A818BF45B7B4D8A83DBA07DB5D16F96B51A46B771213FE8810D53B1EE68EA8A2EF1870DAA7E9CB8570FA04DF817AD58EC6556929AE490B09463B663D899C0F01C5A30E31991812F60A686877C254084FA73C4E28D8267E43FC873BAC32A2EEF54CA235D2089C7BD98D90099EE3512B629BC63A69EAB96D2F60EA01D293DFFC6FC355A726B0EB91D66358834B1DFCDCF5738F929226A63BC8F861740D844E47E2D3B731D03A902F7627C0F287F1863CA4E29773E966C9BDE3D6EB2C83F1FEA43227BD9B556B9773378F3D5CBF571EB6877A334C438C8071B9CA6B8F2AD85E66CCA1312826FC0428FA80AF251D13E3BE157DE900203A2B2F09CD22ED5CB33A71A10154828784BC0D9093B731096BCB14FDD8A59C06BA7BBB6F46285EB75BE0F7E5143E16FDB3B0309303392E62E536299C825293E5764040833BCD0DBE3FF00122F56C1C2364B798293B9CBE3000000000000000000000000000000000000050A0F171D25""") + ), + new SigVerTestCase( + TestUtils.hexDecode(""" +6C9E7A1EE36625760E5D2F33DF2929DA56203234069160E5F2BF039C11062273073C237566CE055D871F38ACD1A9859A824467F19BE68E4F00645D225C42C85A557D2C5ECB442B0F028A6528898EE2B673D863F32EB9EC8164127541F32519BB88E034A03F46F7D193CD3DFBADF63557926C5C8F5B766A7FC5EC8B3F948BF7A821B54C9441AB0BD833FD6354CEC706FAA500ABB5289B90B1BF917677A29D115F0094BDB48DC72E261DBA120BA6FF5E52A01B178981DD8296444656D9442DF9CBB6BFDAE56A230F6F29F94CDCC265576AA8752ACED07E99895CAEF0168BF83D23FDADFBB928CBCDABA25FE2CD26ADDFB0DACD74940F351426942F176FFBC5F3456DB7C912AA16B86D0745F87C9F45370A8456A1ADB51DB4052B5C9EAF60AD7B80A42EA4BF92C841273AD761DEDB0D34BF579600B149FCCD42AB1549BA0ABEDA57EF71D1FCA5702AAD083299BB98300189C25F3B270A87658D0B2EA56524147F739EB6C676D7BE73DD3B95B10C55AB46FD01549C5168BF7DA13A499785F35A1E3B56F4C567F54EA9AA2817A336383643FA2EA31FB1B73E10248DFCA05C04131266498E1C9491135A50E63D02FADF4165FC9E15E3E1B32FAB8337684C49193E1BC4EDEAE373A267A714AC1F909CC657CD8066646327E0EEA041AC9F2AEFFC80691BF60D3C94C642557E4299D395922216C65E75B7E1A5028960384BF816C9F7054829E7985B5841A733F33FCE2455EFC89BAE84B47990E8D0AFC6193E4AF9BC680AE24FE591E88BA6A2AE12DA3858D21F492D24ABC4FE4FD52D5ABF24BD254687B918792F0A003A5222DF45038685C725CE7579E02CB168BBC666ABF669856E10537C9291692C0CB0CFA906270AC2C7B7DC31D4F9283CB2DB8A462AEC0B9807BBF4AB4576FEC6226B4179322B67AEA53BDDF9C9BE5E0DBC43F78743068AB5BE49F0E62F8E2EB1B6C6736C05C9413D065CE0CCB790548041D7E832881A839B5729AF94AB79FD8A16DFFF78CAAA141D97CC0650F86262F26159BE8B361A4A041E9A0B6511BBE3355A4BF57AC09848847EE0243C3BA774776F7E9A227275D74E6E3101D382818763ED1E1353AB9EECCD920CD28922D559A4048F40F062164CB661C4F4AFA81A3D55933C4791EDDAA3939E5AC342B0AD1F438A532C6CE786681A870D94EC88A334CCEFC6ACE7D988A1A82BC0ACCE785F123BE23A7C92AF108E5ED4F0869E22DAE273556D1DE386623A6C3F115BBD119271D3FBA796F618B53959FB98012E7D5B9AC688940B87E2C9C065524A00D3A4F4DBF52F4B1A63EF5C46193BADF7AD7F988D4464345B2C3E549684F2F905F6F89DD641473EC05108A52D8DBB91768C541DE520B17666970AAEB506E75D8EE9F4B4455B71E0088AB25655213B75859D25F559D3C324D283D397ABE6F0AAA386815768D03357D775964902413153E3560CCEF1FD44B65FF1B287A92A9693F034B7EE668934702D7501CAF6DA4EE98AF4E8E64B0340E0BB8BDC533B0EFEE1915A4B68B93C5E95321EEDC234AEFE71AE2E5DACEC2F52F83723A2392A7F8E13BC0301CD104D852E62A7F828AD329B3D9596C58E13FCC0ED96C1C48D82A2C0F4D9D24DD8421FDCCEFD497A9B05FFC50904770401373FEE7DC73773418AEB4A1F599A4BB38EDE8D10A3CC83A1C72DE921969E3CE3E8EF2F7DA89D344C80D61CF9C5A423B1A4F3567D96DB2DA3DB9B5B5FA68156BE7452C8A0181BB9F0DC75CD9750883D0DDAE53FC156D67A74200869046B41DF4BC4396993C08AA4897A0BDDEFB55F69CC1C4D7B5FB150408427B416F73183F2B3CC16E3B7DA63CEE1143ADA1A056626A077B6D21C3DD974ED907C5A094019225737EFB93319AD3B40A4F434AE49D28391C17A999C744A68C55A91B862729583D3DA46EE70C5CC461694167D32D21DE75327732C63BBFBD7B30DBF2057A0D681519F6E4AF608D4BCD0B4750726770E156AEDE85417BD759D5FFE401CB2996F34434DB428D9A417037201FCD260FAA98084502EED5C27A8916E44F5929819D21A69CE16BCDC3CC8141E285EF897B1402C15C952590119051E369A1B7BE443FEAE6E32BC8F3D647FC5315A5200CD5238DC6677466EA86EF8D18E5A79F262483E896B8277C741F516FC040C1090F2495BF1650B02AF30456733A071AF47D7A15BD8E32A49806455D3BEA74AEF5D00906AD2F0C045354EFDE7C9A276E73D9EDD11D1CA5C297B9A6851E7F67E21EB061BB55D9E673C4A75FEB84D52629EECC53C24BEA95153051AC206C87DF55410CA1FE6CFC3F403A6D9D43EA84C60C945E642B2836338B5AF9F69E52708B2E225933DB320BB3F790D397F22D7B6F8A433CDACE9810AA0E27C699555530C562DBF7517A4162628BF10D1B6DBACEF5C9ED51E55D9A89D60E0FC378C47A21D5E0F2DC3BCEF5E05C6E0261530FB027E5032558CA2B47005BDDE99909930391EAD7F3F0A96B3DEDA54A11145F530E51DEF892E5AB0204D614E6E38AFE79CA92C28158D570120353B7A4DE0889846D835294939557ED0AEDA270D4D73ED84D3D49F9F032D43457BF59BB7D66359DC53F9B46963B21784B06CBCF04BEC1E33A33371532716C9EDB3FBEDB81999B4372D0945C10AE826C60FFE93170B6D294B3891B0D2A7B35B28A8971845DC2FECE237B80F20B379CC4D136DAB3FBB3792C63EC61F5C755BC9DB35086FBF46D2B7970DCA2A8523FDB4C7A0B8E42F8AF9ACAD2A0EFC113602A4EA62E4EBB7D269C3A40BA2C44EDD2956"""), + TestUtils.hexDecode(""" +C4F59FA2DE30C8420A7E7F096BAF6AD69B1C15A5C6E61C9D82AFCFDB6EB8F275BF5787186AAE781F487F9F88758C9C61F35D5083EE70424B0D0A51575010C2A907F49608115D33EBA0031509322AA7D3061FEC3162F96A565F98769E9A19235D89D1B21D60A381DF8EB37D58C6A2E483A8EB70736E4B7BB911F7AB923DC29F1E"""), + TestUtils.hexDecode(""" +E895DB64C57BC3C2A97F0EC933410E98F6216103E3423CAF06A671964C514A694EB6F65CBD1137CCCF8881FA403C5FA0E0B2F36B9F4009C378210D29E54A7A5A9B793197CD6D2F38D7E1F3ACA69D48881389381C89FA676DE426D634F9A157055F17283ECE8248CAF14DCF11E2D56355B047DF632A18482E79CB2D5A743966BAA8A76121BB69C2E68155ACCB0A31DA6EDC73CB09A9E660FEB20F66C7BD967ADE32149C5552EAEB2EA175B56233F3B370EDD8679269CE0D2B43F6B2F65FE957E7AB37B982043754EAC8A30B36C10004EF13C692E219AA7AF0A4C5286910C7100DA41E17BBEF2DA2AB03ADF3074BA1DA15BCC84805B89B9DA88E9B400AFB7E3BC8338D354DA953AC0BAD822756CA92E5DD9507F42BFEFCCB32B4B91A2BE5EF34C2CF1177EAAFB250AC9ADEC4BE71807589F1003227F9B76B74E07BA67AC60819B2AF766A47FFFC7B76D3A7C077F5EC69AEEA3E963859B82C2ADE58BEC2152EC8205110975D37C6505E0DC776FDE071097E93013D1004F4E1A2FD79B877ED5025F527F3BFF137F041BB9BD001E949F08B4CF88DFD32FC7CDBCECCFDB0FA2DE7823E110BCFF58A412CEA2795753E9C89678C3AE24268F7489F72974B6955EDD04E190D99BB0D7A252FAD5BBA606C1A1F3ACA733BFAE3309EA0A6EB7D07E36D8CA336D2644FCE1A41895D014D1A60CB106F3F8075F9378461738D63D115D00B024C677801050A1B0B50DE057F85DB6AEB2C9D6BB7402A66E3AB4DB05C58BBDA12F695958B8AC7B4E45EC6C952F679C1EEBDF860E348982779AA6988EFC2AD1DC1EAE22A27A5B2C61C97B3B2493CB6C13C5F6E20A67B88D3C3ACCFAF0A425742DF240634D1EE593828FE6297446C076F979055988AB834B2BD82E14DC086400E1C956CC0C30CE7BFD962223D23FE9494964A811B93E8D7B8F34C89AAD45DD4113F2AE7BD94B53FC86E8B2AE82E51EC6F3EA4C30D60B86072748612D1607056B5FF6A4500EEE78A5A639C7B74169777626864DD9EAEF0E3AD8493D831F71DEA95BBFCF81423A266DE56F3A8FE8E6C3C0D612FB62BD642188CA71CB89834F30BCC28BD178845F1F6F46C03D306F7ED4E68759427AEC2701198C3C05D385DFAFD528CCE8425BC551469A0ED681BEE4D12A843E333B5A8E0517FC61906F9C4E7809BAED4D3D16EB22F1FA9AB402D988ED59F9FED0455E9260FD627A24A17FE7CB63E530B48F5FB6687A2E8C49DA79FBD69A3400056665DD11D19A2BC4DB1D374AB6A6E42472A27AC6B98F676E8EDAADD514F6D44DEECDAB5A6DFA0F84F139A803A2524BF335DC52EA58FA50D98FB5CD55D5D50A663CF647EEE56FE8E664B3BCAF9E333978A7946973FD113E4FD3924E6C09E60386444214DFA7A4D671FC23890637EB859134D79E265C59CA3ECCDDFA018223C9BAE1CCA103962078BC5F0DD02246FA28324F7CB2FCFAD07C25B4BC2D888069B0CF5F23C761C0E47109881CD31456A64B940B4BB9B4C2C3B8E6BA834AAAE69FDFC47D44B3C96887ABED36015E7B64E8542928F277CBD2D3C512C24DEEFE590E81C684E063E7AADCF117B48943DB771FC2207F57A745357555D419C9CDCA35CC1A7100A6913A3B6AACF796FE3F94DD2F818982716CE0316542A1B957E12DA43E231542CC14FCC66D728A68326B2BC311248330F3E98F81EA38CA924A8E4DA97CF673842C759F935BE88163CE97FE4D9457176F5B8908AF948F74D5D1DDBC521825D931C63CA8A8E12242626305AB6A2E0624564EE041983C18C2952EC3D9D159BDE3985CF77897EE2DC888112721D4854E914A5397E08B54F4A54323FF820821BE026EA091ECA6B7D80D91E3DCA2EF7848B86FCA6BB40CE48271E1008368E3EBB5E395E1CCD0D178F1A6257D26B6BA4B7CE532CAA1E76CE28FA4CF9E029E2482B94D3ACF97A326D235D1BDC89F70002198451D9F1F12CCD5BCAECDDE9E14AC80742EB31E6464C83210A39F35098BE0378D074CE1CCD1EBC1C7770F778D605F2BE59DB7EA07D80CCDF55F16E985B142FB7BDA07AA7DCA5B201E1950CF9A728F21E9A9D8AC4D1327E3BC0FF339A250522F631DF2E75955154893E4A1AAF9866FEE1637EE1AA5106D244E99E6F31FC5601BB7B79BAD82860B1D6059D9B132E026418020DB06EB8391FA15B7A0F29E36D966ABD3D2A2FF3F2AAC34C8B45C7D2355EDBB80B224BC106EBC6750E55070F85A7CB6003394E5161AE26F5ABF83F0DCCCF69B86139AF8694FE1DC00781EAE09CDB421814878043DC9B0530E5545A165E39A9B7DE88B4AD2AEB90D3C329412ED2FE1D97B732C8439DF4F83D228835B538DC278FF0A2DC42F41B00CE3ACA06B05C4839B896931515D78EA3673A378279F4E89CE08E3453FF2FB453BE031C6318628A731D029FC7BEA2BA5EAC4916278B938A6A6ACEF5BFE2158F2AF43D8E56A0649DF28A250D2F2536ABDE1E008EB631F4BD0EB55573A40539A6004181A9D2BF7A1E53504F11E014840733844131AC668946E5B827289AB6B21366C5D0E2649219B92C4760DFB705F7F61A96564C9E840D14B0BB0DA82DA50F8B8E752BBFEA3B0A337BE124F72D8F8249195BC19C3E0B62EAE496D38CF7500B4F10665FC2D28B9EA935F7E316472F4FF401267541BDB62301554B2009928C6445BBD0EF21D09972F35081ABA9091A6C23FED29F5CF9E0779F7EFBAD88E62A454442B30079BE0AC9C64826B98C1E1001CB0FB0F0A95F7965FE9312BFDAEC33F95065C8E59D3950F80ADC7FB334F202D3E5F8DA481C9B54A75983930FD1E5ACD16284F07193FBCB50D0DC00EFF8203144C11EC61420FC32D7982CE896406BE769A75DD8D3CAC753ABE5A278655BF54BE33A1B8374EBEEFF212C39CE514668F1C456EAA2532828C84293F1A5BC9EB5DEDF558A9B4C1239F77272C67E1AB28E1EFEC5893E09C10662B53C8B8255B1C8DC8F8E5120A25C75EEFE79C43F7A8B37DF9D1E4F32486933DA1CB0664C5DB39E21BC227B0CDFE7A5507F07F218A7A47DEBCD9DAD7247B4D045A13AD4F75EAD2D45C339D0DF04577F2E0FDC780392553033C738852B1BE4E63EA3897D6C9C4B11AD6B58D3E2D342D32840F649DD83E759866B7381A84C8ADDDF413FAE18E6431B1EEA73A56CD889B76BC9786BEDEDCA2541E4C9B24E28F58AD374C1D93DF2D3F2C37EC594A0498C574579A7332F72C0F9750877FAD5B90B968D88F11682C4071E4EA38B816AEAD6BE54D2F371324F2475B862C75424ECF9858AA4E200CFBA412D7E3E6C308D8DE11DD185331AF9D41AFE8879965D6746EF21FD98D3ED3806FB5C4619C98E347D76B8B89849395561EE286DFDFC6A04E1D47E9F5B5B49257784C39364DFA88AD630DFA59CCA3237F4A2B141A813D22C6FFE73C2D99ADC824D93E06A54B6DE62C3125D94B49E950DEC361F961F56D3671C9925377F6E670665322B8489E833D3830ECCDD0F53F4A4F9D68F1445F3AED5C9D766409B59BAE7A72912E98B3BB57342D29B6ACFD14336B7B8B6B7549AF8CC8845E10C2811287281985D5D47685FC589F2678ED893F57B85ACED75632E50DE5E074E6CEDCF1AD499BCE67A7F498564DEEC677C708388DE8FD7B099CFC116096C45FE28890B5EAF06169939FDA35E1215F238E8CDEDFE670065F5DE3272A232FD53C250F5D779B31694FBA91B554803676E4DEA288463FE1063009E9CB76C317DB400ACF4D2D2B6D16EDEBA4108913F60AEB252CDE413690CEEFDCFA638963DBD04F4CF21AD74DDE65F0F1E7CE70AF101A6DE9A59DB21D38027DBBF76167827950B69418266AFA444C728DE3624A1C81E5B1641DBE879CD822FB2303CC3A9FCEEFE3DDF7DBD0B7057248A28D6062D76EB13B92C9C9D003B69E1842A54C09CF6B484520815E2BB237288C64FC696FD3BC45DB30CB86465DF1188BF47956E5B916A8009715CC9A9A6DCE44C54F928816B41D018C5FE652FFE4E33F352D383A9C1365F02ABFD647BD6B42AD163730F8BFDA1E2BE5F614D79597825BA09F457D3CBE7561E7E89EAF059E977D1EE88848B781F21F723890FF1F9873928412C8F11EEDD2C0C39C9512790986A19E17B2B70A4D7CF49D9D18CAA0C2023134CACD169200D8817FA321F04ACC910613DFF250EB325DBEF29EB5611B2AD2A23EDD538049B3F43EFEB4D60983792B4BF05567944AADB7AC4D3A5D80A1B9D8448B4C0C115C3B5AD3885353F47D5FCB9B7D6446F1A7210BBC667FC411415F23CD40A2A3D64061D71C67191571A97D01088A24B6711567FC89106732D8892FF985B8E6CF70163829CC085BE4E408315361BB1B2003D6413220B134506D3C304C0BBBA9C9C45D3651E0571B6B115177213D8595E143DB90BD72F7EB974D8D0A0317409D64D5837EAEC9B8D44DD7ECFF6CDA9F729382A43B379CBDD43FFB18AEA35C1A996CEF1488D3B7A81EE7CFC0B9623418AB3919A6EDDB99F222F0DDDB2F32A20C8F84FBF4C49B4CB3EB50D9C4CD25A6F7175467066D25E6437B67F2DBC70C2E6EB0BDE2386D03014A789FB6DC08EE33C0C67951DA9D74B9C94845D2A99037E095FEF7919920FE526EB5DD0BA1F97DFBD2DDC31609C1B7B45EC3ADB586FE3030A0C7A9DD034A3C2E6F9849093CEE10A181953547F8BE328720A4A5A8290B5EE00000000000000000000000000000000000000000000060B10181A21""") + ), + new SigVerTestCase( + TestUtils.hexDecode(""" +6C9E7A1EE36625760E5D2F33DF2929DA56203234069160E5F2BF039C11062273073C237566CE055D871F38ACD1A9859A824467F19BE68E4F00645D225C42C85A557D2C5ECB442B0F028A6528898EE2B673D863F32EB9EC8164127541F32519BB88E034A03F46F7D193CD3DFBADF63557926C5C8F5B766A7FC5EC8B3F948BF7A821B54C9441AB0BD833FD6354CEC706FAA500ABB5289B90B1BF917677A29D115F0094BDB48DC72E261DBA120BA6FF5E52A01B178981DD8296444656D9442DF9CBB6BFDAE56A230F6F29F94CDCC265576AA8752ACED07E99895CAEF0168BF83D23FDADFBB928CBCDABA25FE2CD26ADDFB0DACD74940F351426942F176FFBC5F3456DB7C912AA16B86D0745F87C9F45370A8456A1ADB51DB4052B5C9EAF60AD7B80A42EA4BF92C841273AD761DEDB0D34BF579600B149FCCD42AB1549BA0ABEDA57EF71D1FCA5702AAD083299BB98300189C25F3B270A87658D0B2EA56524147F739EB6C676D7BE73DD3B95B10C55AB46FD01549C5168BF7DA13A499785F35A1E3B56F4C567F54EA9AA2817A336383643FA2EA31FB1B73E10248DFCA05C04131266498E1C9491135A50E63D02FADF4165FC9E15E3E1B32FAB8337684C49193E1BC4EDEAE373A267A714AC1F909CC657CD8066646327E0EEA041AC9F2AEFFC80691BF60D3C94C642557E4299D395922216C65E75B7E1A5028960384BF816C9F7054829E7985B5841A733F33FCE2455EFC89BAE84B47990E8D0AFC6193E4AF9BC680AE24FE591E88BA6A2AE12DA3858D21F492D24ABC4FE4FD52D5ABF24BD254687B918792F0A003A5222DF45038685C725CE7579E02CB168BBC666ABF669856E10537C9291692C0CB0CFA906270AC2C7B7DC31D4F9283CB2DB8A462AEC0B9807BBF4AB4576FEC6226B4179322B67AEA53BDDF9C9BE5E0DBC43F78743068AB5BE49F0E62F8E2EB1B6C6736C05C9413D065CE0CCB790548041D7E832881A839B5729AF94AB79FD8A16DFFF78CAAA141D97CC0650F86262F26159BE8B361A4A041E9A0B6511BBE3355A4BF57AC09848847EE0243C3BA774776F7E9A227275D74E6E3101D382818763ED1E1353AB9EECCD920CD28922D559A4048F40F062164CB661C4F4AFA81A3D55933C4791EDDAA3939E5AC342B0AD1F438A532C6CE786681A870D94EC88A334CCEFC6ACE7D988A1A82BC0ACCE785F123BE23A7C92AF108E5ED4F0869E22DAE273556D1DE386623A6C3F115BBD119271D3FBA796F618B53959FB98012E7D5B9AC688940B87E2C9C065524A00D3A4F4DBF52F4B1A63EF5C46193BADF7AD7F988D4464345B2C3E549684F2F905F6F89DD641473EC05108A52D8DBB91768C541DE520B17666970AAEB506E75D8EE9F4B4455B71E0088AB25655213B75859D25F559D3C324D283D397ABE6F0AAA386815768D03357D775964902413153E3560CCEF1FD44B65FF1B287A92A9693F034B7EE668934702D7501CAF6DA4EE98AF4E8E64B0340E0BB8BDC533B0EFEE1915A4B68B93C5E95321EEDC234AEFE71AE2E5DACEC2F52F83723A2392A7F8E13BC0301CD104D852E62A7F828AD329B3D9596C58E13FCC0ED96C1C48D82A2C0F4D9D24DD8421FDCCEFD497A9B05FFC50904770401373FEE7DC73773418AEB4A1F599A4BB38EDE8D10A3CC83A1C72DE921969E3CE3E8EF2F7DA89D344C80D61CF9C5A423B1A4F3567D96DB2DA3DB9B5B5FA68156BE7452C8A0181BB9F0DC75CD9750883D0DDAE53FC156D67A74200869046B41DF4BC4396993C08AA4897A0BDDEFB55F69CC1C4D7B5FB150408427B416F73183F2B3CC16E3B7DA63CEE1143ADA1A056626A077B6D21C3DD974ED907C5A094019225737EFB93319AD3B40A4F434AE49D28391C17A999C744A68C55A91B862729583D3DA46EE70C5CC461694167D32D21DE75327732C63BBFBD7B30DBF2057A0D681519F6E4AF608D4BCD0B4750726770E156AEDE85417BD759D5FFE401CB2996F34434DB428D9A417037201FCD260FAA98084502EED5C27A8916E44F5929819D21A69CE16BCDC3CC8141E285EF897B1402C15C952590119051E369A1B7BE443FEAE6E32BC8F3D647FC5315A5200CD5238DC6677466EA86EF8D18E5A79F262483E896B8277C741F516FC040C1090F2495BF1650B02AF30456733A071AF47D7A15BD8E32A49806455D3BEA74AEF5D00906AD2F0C045354EFDE7C9A276E73D9EDD11D1CA5C297B9A6851E7F67E21EB061BB55D9E673C4A75FEB84D52629EECC53C24BEA95153051AC206C87DF55410CA1FE6CFC3F403A6D9D43EA84C60C945E642B2836338B5AF9F69E52708B2E225933DB320BB3F790D397F22D7B6F8A433CDACE9810AA0E27C699555530C562DBF7517A4162628BF10D1B6DBACEF5C9ED51E55D9A89D60E0FC378C47A21D5E0F2DC3BCEF5E05C6E0261530FB027E5032558CA2B47005BDDE99909930391EAD7F3F0A96B3DEDA54A11145F530E51DEF892E5AB0204D614E6E38AFE79CA92C28158D570120353B7A4DE0889846D835294939557ED0AEDA270D4D73ED84D3D49F9F032D43457BF59BB7D66359DC53F9B46963B21784B06CBCF04BEC1E33A33371532716C9EDB3FBEDB81999B4372D0945C10AE826C60FFE93170B6D294B3891B0D2A7B35B28A8971845DC2FECE237B80F20B379CC4D136DAB3FBB3792C63EC61F5C755BC9DB35086FBF46D2B7970DCA2A8523FDB4C7A0B8E42F8AF9ACAD2A0EFC113602A4EA62E4EBB7D269C3A40BA2C44EDD2956"""), + TestUtils.hexDecode(""" +C1E665BF7B8BD0198F069CA17EFC55B7EBBF9CC9D41140BDD0B83AA08062FFC717D3F6C22DF38EEFAA6EEC91760CAE0B3DFEAB78B03A7AB7A993B2097B7B887B9812AE2D0892B696374C034FC9E95083C2B61B09DE97D9C500FE55E489C53CAEBDB57BC69071C15808890F8A007BB5FE773CCFB729463113D93E9EC9EABE2047"""), + TestUtils.hexDecode(""" +051F8A9A5DC6D35B1485288359F818DEB027E1231DA8C048E79E9FE228AA0E9F1C0B7F4C573B5DB8CCAEBBAE8EE38D8FAEFD3B8E7730BDC0E9DE365B20E5A0F9635A0B39C7C0D6163B7876ECC6ABCD8A5F608E7253537C1C94C209C8448E02806B2B5EAFAE2483170B4E4450380C2A87A51F82B179EE0F46509404A3A9BD74D04BD75635B797B500F656ACAE5DD76B04741792112579E24081A6C88BF4981346E2B3D38291026D3AE47BDA50AB0B23B0881148489CBD057CDE9A4F6FF108B7ECCEA44D599CE3ADED82AE0E8F74DB7D604161C8664B7389497EC9F35C46FEC064BB867E867E9309C10FBC07BD5E7B8A74BBEBC1BD0E4A9B36EFE297E9F2D23DE32ED704EAA377F5C3BC4BABCCAD5B4B6B9A137F23C46C0423ABA3F1AFF00C6071CBA51B7D0A8E677F5138DB7C013CAEE1F68501430F0F448AB283692A18D15D8A46BA620EA906A3032570A659F594236F0512389E1DE63B8E40AC22DB79DE60CCB9BCF0B20EBEF676A91AABCD01D3AF882931AFF8C86A8C946E09B8B5CFDE62D53A03DF07163B081B293EA0287AEB97D1762F34361DDE654D400DFAE5B351D90742A0A269865D49C9221DD89E42FFA63EDDF449B10458CFE2EA7E1A16BD22FE73F208B4472DA8094F28CB9DCAED6E843C57E9E3258BEADA48D7761FDE0104AC6F0CE09F95E1F4AFF00515AC2E3703D2FC6D757B12DFDC044E854E50FF2D897900B0B59BED90BA4201694E29E6A830D8039CD835C706EF59E7A6B0ACA7B7D0B40D264661711E0372BAB7410A74460D07FA988A8617D31074950838411037307B052FD536822608F9D15BAA780AFAE1A8D87BF844D3A4FB31A176BBCBEA46A72BA990FCF821AC3A73ACA01E09A20AB93FC737ED4C4DC482BF9BA21D7178D24DD5D6A29633386933A3E8F28982731F07606AF28BD2D81004B044B4EAAE67E29840BC78EA66FF840031D8B2894B603733E1A0398FB0E4952B2ABC567668443581C860F87A76774E6742807C39FE99269E3199DAD02B246D7AC24E5BD9DD91F7D16A76E72318882FA21672A7D5B1A4F212954BE2B19897243F60C18D1DED2AFDF69DAB8C9B10342471C633B33C52E95A85D3142F2E46C681AF373C5E92BC948FBD31207F015DD32DE2591DF4639E4E563344D440653592EF2685E1320AB9E51837F6C06D07E5462599FC6F8BB120826E738E2223CD4B8C7CE446ECE681DC6D6BEF1D6385B0AE7E404F502B87989D969B81CF42085A7B58A41EF73EDC73056DA72EF65A7AC8E284E7F51E723102CFEF903688F870CEF1C7E5264330E3033691680050E926E93A1C0C4161A7DCA14A0FF338D431D68FAC204DA28CCD1CE7BA3B7F3C45B4FC74D9E754A1A2F7F23F0FBE8D2FF01CE4683D8842E8A1528589E7D9260368A654CB514A85DA9C2EAB74C66FA17FDFB256D585D28C1DBA35E18779D7B6DB876CC0A98CFF752A0E8DFDD532ECB04C4101AF32E689D13874B9F20AF652069C1458D7FB382E317AF49083B5870078B39221464F376EC0BC2DC1C3FAF10EA4EA87A2F9D547B535F60406E8E68AD190CD4F00EFDCD9D54D4810F31B9F68F0D95E32CDF2747B9C20FCD1694FE034EF6B5460F163AC78BA235A441DB2B3AE84BC28CEEED7B3FC2A4D63330D14186658788DFD7652E477B1310317C86921394219D75FB6FC319575745589F9E2096801E57E6AED2369FE115C2D937EBEA3602194B7432B01F55E6C9572CD0FF8BE8A4796815914D5F64D93E0E709C3CF88741C851C8BFC4CCE6F0AE60A6D2F4DC6FD8AFC82E065956971FB8B4160AD68EF7BFCB3A9694CC7EDEF64FF08011B183BEB7A2D3D9024753B59900D27F52DF6D4B2576BABA673A0E33CC57B501E1C74F63A988E1A157078FA8B3F2A143CC9D41A35412B4E0CE6B1D9CFAE7470BF4C778D026A9AF86DF7F974E2414FD7C5F0FF6D62293C6E2A62D4C5268CD0B604047C9658F97D9A7B86E1C953FFF95CB478028FDCAE6E8F208AA208A282446B2CE8B4C7E893E269FA8E02C082F82966A4AE3FD86BE89A8CC8BB3D6B105A91DCF76FEF700E5AA4A15BA0F753129D3369915D7E896527CF6E71C363EF65B2218A5FCB8D8FD96D6A63A8BC547EFC942DCE1276E268841BA00E35769B4AC706BD65B275BABDD530771D854EC38AC0529729786A86C7C4161B3E7074023516C84B4B4776AC47C2ED1587861126A7A707978F2B2B2972C20F237FC223B56A67538F9241D926DB7C992A3FDFDF999884EF83EAC7DA0F6523F53CD40E473AD370C77B30DB2FE408783D24CF4C3512E3C6B677C41A67849FA1792313581EBBDB7BE0BB3EE85330FED8B5A1915F6343F3B7C928CD363463385436038B64BAB5D055BC39D18F9A1A8196AF8DDA5A1F428434958F5C89F07D7A53CFF2118E80060C5ACA71975C4C92A589EBF5746AC92C50FC1F915C146C2DEE7531B24970790A4AA7DAC425940AFC4C88ABEB998D549681C95ACBE9F7E274521D44E9EB759C2946504161AE7FFEDAD3E62D045AD77FE8C2B8ED529843DD341E2E50559A29AE26D431C9634C4C19A84FA0257F71CDF27C33F14D57347BE8B19D254E3C353CDCA10489F06214161AEB2A9D3049B3CE4689503621C46D192C1421B4B033775D9218DD2E216600E64D977CAB0E1675666A7CA773E4E139DD4EBE94CE35A28284755C52BE490514B25FFCA4174F54E8A5F715F924949C1467A282D7F2DB468DF363F9A55E5D7858D8F95D8083D6A594DC1B07A8C4FD4AAAEA0785EA3D9B50798F0A96AA386F17C2BFB94FA8EA3B5EF71012AF9285CADB1FE330A267555A942682F9333AF2E81515969B76FDC020F9CD29E848B94F26F4B53CA5144CBCDA1AB6CD2FACBAB0A2FC0F5B88DA0AC0EC08B9EDA7CAEF502FDA52006815743520F841CFEC3B4D9AA732DE408D6FB14739E8FE77CDDB68A5F6AA215B588F1491988B4460F6949AD647DE9105CA50CFB413A971BC8E6179F0724FC28D1A7D30C41180735F4FF6167810D9E88A5F7FDF791BFB474BB5478544EA74C9F07598D038CBBA17B83228A18B2AB09A8BBD2D2205EECDF01044D5A1B2BD50D2C8E3D5511450A4E594C1CE7067A6E14128BBB36E95C143EE6A51CA0EEBDBE47E9C5A87E81BB904013DC892D03F483B1DC82986DCE7A6E10192E6743283202D78D11B2169602A75C2A688DBAD50C9FDF1A1A15A470D882ED4B5207E659A94776ABC3D3583E1D2E85291D3726E75B7AEF9344180D325583A05266C196ED367E906121C33E701D428B46865BF32AEA4A90262866A024209A7663EDA4C340B5AF3E899F009EEB5E8D5003635EED501CC02D5D11F504C823C17E961D0BF611519961BF422647D97119F5745478888BCCE367639772953C5731434B28913F3F709AF455053F6B09519AEB6B755CB02CE74DD814714A2E0B477C05202092525EC03C5B365A75086E3281D4BB5C3AD9D742806E58B5CE4E1E95269AB18B68B2928BFCF7EA683967C0B88ADA99FF35E1D5A661CDFAD76774B42F858AA54626B88050D992FFDE16FAD3A8CA496CC6BE339977BE24D33E8BAB86B421F4BAA9C12A93117E43415929F0C4DBC9737EA5586780886A8EF4E4295DDBC967A2B5523FAEE0C060468F9704509C4CB14028E8A1672609A8CED43F1B06981FBFDFD52296D7BD3B4AE68E7D54BB2405799278AE29B66E258D3B9D276FD34E192BDE869092F6A7F761C6DDB0DE9454823256C7B17ABB91003B1A3B66CBCD4F9ED068409161635F6DF9459AC382044EC14FE8B2A586FE02C74232BBBF27800ECF627AD1C6ECC93C13EDA2DC20C8D6714C519D6A571E708787BF342DBCDE10EB1BCA5A7FCD971CA52BB68FB33ECB7F90AAF739F0C5B61BFED72CDB46A712DB6928F84892D3EC2F6C7023A6B664CE9CFDC33D2F09D38B5E4D182C73FF1D7B474C8AD6E883ABC78FEC75C8A390CEA561A86B92E2A4A1950997594C29A35E4A71B0E484FCDA63E5EC9666E0A463325DBCF7258D36B85099AB7C81E70FA66F1A471D4C1593AE68404F31AD2667017C9B5B3843FBC48D831F6A9B5FAF7C73A8478A7DADF28FBD9DDF979418870AE61E94C6BD47FF2C39073AAE16FF18B161B9B21413E66E489EF9F8784E5DCBBE29127B0C51A5C1E2A04E9C8794964D1823ACEB9ED0DD555964687848629EE06B0712483CA30D6D4A91E047EA33D30A062D8249278CDCBBA2A1B3C133D3E671FACB034AD0F9AA40628C0E2288B56F7A76DCDFEA762A8DB323B44925285557C3501999CBE145D15EA82169007A97EABABBE69479E03D40F2FE9217F14664726DCEA227107412B3CC742E4ED168E051D9AD4468131AB035708ABAD78659CCF5988F70680C124468CB80BD9924B0E41CB25AA69E7877CF5EA348403AD0899A5FCF35D4F22F3A73F0207E96785F4EB9AB93B6F10EE0B247D31F3D62A85B99C88CD3B19BB68E69C51AD5B0A8E9E34ED611E24FE2644F1697A8A11B64B578FEE1C5CB31A605CD987D765FB68D833E4BE9358D869F4DE0362E6889FBE8E95B861E078CE6CF0FF35768AD49803A71E8DC60296032E50A9D0A4E64A3D4661E7C55DAFC6FDD1B18EB1003D290BE486C520A2F8F0EFC1CD2CEFBF7E2459CC7BA88695D1122A7494A3A41C329EED2A8CD2282A607F93A2B7DADF0F32414C6BA9BEC0CB00000000000000000000000000000000000000000003090D101922""") + ), + new SigVerTestCase( + TestUtils.hexDecode(""" +6C9E7A1EE36625760E5D2F33DF2929DA56203234069160E5F2BF039C11062273073C237566CE055D871F38ACD1A9859A824467F19BE68E4F00645D225C42C85A557D2C5ECB442B0F028A6528898EE2B673D863F32EB9EC8164127541F32519BB88E034A03F46F7D193CD3DFBADF63557926C5C8F5B766A7FC5EC8B3F948BF7A821B54C9441AB0BD833FD6354CEC706FAA500ABB5289B90B1BF917677A29D115F0094BDB48DC72E261DBA120BA6FF5E52A01B178981DD8296444656D9442DF9CBB6BFDAE56A230F6F29F94CDCC265576AA8752ACED07E99895CAEF0168BF83D23FDADFBB928CBCDABA25FE2CD26ADDFB0DACD74940F351426942F176FFBC5F3456DB7C912AA16B86D0745F87C9F45370A8456A1ADB51DB4052B5C9EAF60AD7B80A42EA4BF92C841273AD761DEDB0D34BF579600B149FCCD42AB1549BA0ABEDA57EF71D1FCA5702AAD083299BB98300189C25F3B270A87658D0B2EA56524147F739EB6C676D7BE73DD3B95B10C55AB46FD01549C5168BF7DA13A499785F35A1E3B56F4C567F54EA9AA2817A336383643FA2EA31FB1B73E10248DFCA05C04131266498E1C9491135A50E63D02FADF4165FC9E15E3E1B32FAB8337684C49193E1BC4EDEAE373A267A714AC1F909CC657CD8066646327E0EEA041AC9F2AEFFC80691BF60D3C94C642557E4299D395922216C65E75B7E1A5028960384BF816C9F7054829E7985B5841A733F33FCE2455EFC89BAE84B47990E8D0AFC6193E4AF9BC680AE24FE591E88BA6A2AE12DA3858D21F492D24ABC4FE4FD52D5ABF24BD254687B918792F0A003A5222DF45038685C725CE7579E02CB168BBC666ABF669856E10537C9291692C0CB0CFA906270AC2C7B7DC31D4F9283CB2DB8A462AEC0B9807BBF4AB4576FEC6226B4179322B67AEA53BDDF9C9BE5E0DBC43F78743068AB5BE49F0E62F8E2EB1B6C6736C05C9413D065CE0CCB790548041D7E832881A839B5729AF94AB79FD8A16DFFF78CAAA141D97CC0650F86262F26159BE8B361A4A041E9A0B6511BBE3355A4BF57AC09848847EE0243C3BA774776F7E9A227275D74E6E3101D382818763ED1E1353AB9EECCD920CD28922D559A4048F40F062164CB661C4F4AFA81A3D55933C4791EDDAA3939E5AC342B0AD1F438A532C6CE786681A870D94EC88A334CCEFC6ACE7D988A1A82BC0ACCE785F123BE23A7C92AF108E5ED4F0869E22DAE273556D1DE386623A6C3F115BBD119271D3FBA796F618B53959FB98012E7D5B9AC688940B87E2C9C065524A00D3A4F4DBF52F4B1A63EF5C46193BADF7AD7F988D4464345B2C3E549684F2F905F6F89DD641473EC05108A52D8DBB91768C541DE520B17666970AAEB506E75D8EE9F4B4455B71E0088AB25655213B75859D25F559D3C324D283D397ABE6F0AAA386815768D03357D775964902413153E3560CCEF1FD44B65FF1B287A92A9693F034B7EE668934702D7501CAF6DA4EE98AF4E8E64B0340E0BB8BDC533B0EFEE1915A4B68B93C5E95321EEDC234AEFE71AE2E5DACEC2F52F83723A2392A7F8E13BC0301CD104D852E62A7F828AD329B3D9596C58E13FCC0ED96C1C48D82A2C0F4D9D24DD8421FDCCEFD497A9B05FFC50904770401373FEE7DC73773418AEB4A1F599A4BB38EDE8D10A3CC83A1C72DE921969E3CE3E8EF2F7DA89D344C80D61CF9C5A423B1A4F3567D96DB2DA3DB9B5B5FA68156BE7452C8A0181BB9F0DC75CD9750883D0DDAE53FC156D67A74200869046B41DF4BC4396993C08AA4897A0BDDEFB55F69CC1C4D7B5FB150408427B416F73183F2B3CC16E3B7DA63CEE1143ADA1A056626A077B6D21C3DD974ED907C5A094019225737EFB93319AD3B40A4F434AE49D28391C17A999C744A68C55A91B862729583D3DA46EE70C5CC461694167D32D21DE75327732C63BBFBD7B30DBF2057A0D681519F6E4AF608D4BCD0B4750726770E156AEDE85417BD759D5FFE401CB2996F34434DB428D9A417037201FCD260FAA98084502EED5C27A8916E44F5929819D21A69CE16BCDC3CC8141E285EF897B1402C15C952590119051E369A1B7BE443FEAE6E32BC8F3D647FC5315A5200CD5238DC6677466EA86EF8D18E5A79F262483E896B8277C741F516FC040C1090F2495BF1650B02AF30456733A071AF47D7A15BD8E32A49806455D3BEA74AEF5D00906AD2F0C045354EFDE7C9A276E73D9EDD11D1CA5C297B9A6851E7F67E21EB061BB55D9E673C4A75FEB84D52629EECC53C24BEA95153051AC206C87DF55410CA1FE6CFC3F403A6D9D43EA84C60C945E642B2836338B5AF9F69E52708B2E225933DB320BB3F790D397F22D7B6F8A433CDACE9810AA0E27C699555530C562DBF7517A4162628BF10D1B6DBACEF5C9ED51E55D9A89D60E0FC378C47A21D5E0F2DC3BCEF5E05C6E0261530FB027E5032558CA2B47005BDDE99909930391EAD7F3F0A96B3DEDA54A11145F530E51DEF892E5AB0204D614E6E38AFE79CA92C28158D570120353B7A4DE0889846D835294939557ED0AEDA270D4D73ED84D3D49F9F032D43457BF59BB7D66359DC53F9B46963B21784B06CBCF04BEC1E33A33371532716C9EDB3FBEDB81999B4372D0945C10AE826C60FFE93170B6D294B3891B0D2A7B35B28A8971845DC2FECE237B80F20B379CC4D136DAB3FBB3792C63EC61F5C755BC9DB35086FBF46D2B7970DCA2A8523FDB4C7A0B8E42F8AF9ACAD2A0EFC113602A4EA62E4EBB7D269C3A40BA2C44EDD2956"""), + TestUtils.hexDecode(""" +62C2A85A6AE40091AE35068EB3E5B54803F495D49BC177F7A29282DF0C900E86F66155B4026064E7D6CF7A171F8BBB33449232EB5D7DB2B776ABBACECCD660294C25196E19FADA35E0F3524D78EDA25D614FB56DBA5BAC10D06EAEDD9644DA291DF305C1E91C82FA00EC470A8E822525895113A6FF7D1D52E7038B9CF4DB2227"""), + TestUtils.hexDecode(""" +9B829A093EC253FF3D955EBA3C0FDA29CD14089C6D699F26FC62BCD40F43D1582F2B693138AACA59A162CEFBDA6328F1BD67690C63B903F5062DCDFFA840DC2DFD4051F82A557FFDAAE8F4A4FB340D6F4AF03A19AB928F42DFD29FF8D028333A0C336D253C826175C5A194C0441DAC1C5A4C4A3E0B8394E43678DC915BC98628BF565C9E751BF9801DD6AD4A3621B50C8DD1520F0CFE475F5BF843DC2568B263978587322FD1D2709ECD869A77F054C0A45D466D297ED9B63F10020826836F531A06DFBE20BFBA0B3F204033783C5505BD82DE732204917E3DA12316559D07366600CD18EE2A329AB3B20BB0C9C607D0660044D2A9ACC5D25806F89DFD5813C9E54E0CDFC190A206300FBC8E2561BF3F23D04052902E49CD5DA530A4D2BC2E5F47EE93D0588AA66EC8CAFDD4B353D73B6C1765211405C080A614129CF9346A1593503AD75EB9C3CCC99DBCE1D937AEB7929A1B5351BE262FB2B41FCA6DD965CE596DBE39D07D20281A2ED74C35FAA474EC425A897978FAD88D470502008D9A0E08DFA2F6C33A0B4CF2456951109BF4F877D74D7681CF287F6DCFAE24D1FCB0FC69D7C4D33E20536C64ACE18F04A2AA8E767C24068F4BA45C4C49DC3B43AF803610F300D01C5CD9ED92F33BAC270ECE09EBA2CA0FBA180CD135E420471A7C6CA249D877DE616F054711B3DA2DFA5D2D3FE774F802F4880E4400FBE4D12B8D678DB076020D356769060253E5D68F665FBCE0EC702F42B94E2B0C8359CF4D6EBCDEDA9FAC8F2FE95B9FDBB9346C06300F60FFD4FAEBA01929CEDF0F15021689B6EFF9298BFB8E514D925541CE2130EE1F25ED6EA895F432987AE4A2CAE01B5F4691DEBF12129EB19C2890A9D268774881F151A06FE42656CCAFEAFFF01E3EBF52C6716CB28BCB6719F7552731C275DA226914D733AEC1BD599AED7BC0646B8E3D9E0F3B771295D43391F00293401E6331E37E779EA8914E7F03B4CA3D1AFAD797617D9D0BBC6020E1B40B431B930D19E0888518D6ED2E6D32BD872B9A416E0B47133867FEC96A88C6B67449E8881B8A455D1816BE7DCB22287D63DBBD87E571F6887AD3D6DDC08C0B710395A12570AE985AB08393BF99DF1A1EDEA499BCBBC2F2EC05FA3EE982E34814F56373891282882A05711EE9A906CFE5952A6AF64379854A4DEBEC24C22F69065D6FC392B4A687D66528615AE301C82D6C694D358B71451A536039368D05C3C240062E455A119EF5A1737D732C1079C7CBA9A05D9D8119CD94497CBE2A275C69D6623628ADBCDEDEAAA143073C6EC43C40229606E6AEB982CE1827F875FF0A6921E0D6D08F605EBCF85EAF0C4AFBD067A14BF9FA6C7A657213C04FCB93630D892E8B340217EB07EFE9CD320DA3DE466169001566373F589A4C48BE25EAB1E6A612187F110661BCED6C2FE2583F424641A420A0DE61B39026172DDC93EF444EADF8ED5CB674F0586307F2886CAEECBBF78A4AFB96ADE18F0504734A082C168921005300431BAAA9FFBCFC96D272E8FD9A10B7F963BA868A273CADA8082353C0E1D7C8BD323779D9BB23CE678B3A5AAD2B6836F65C0F79E32D08006C72EB2431FF9797E7630F27B89635F08FC92203012EAF6B009A32437ED076D66E4CC6074B1CCD0D2176FBE508E43EDDA9185A91E2AFBD235EA8944B711B8C7D0A4132351FCAB1ABC338C3419C9993FD56FC3C89A08B0D8F28914FBB4840A7D02F209D1EFD208A8E47902E11C1FA92CBA1851FF0935D3EFA705FF4BA44A6D4A675BD979947CE8FAEC565B3BAA9D441AF91F429D42C3E3F683E0202C61318344C7865957131A1F9EB822999F137C0A930744CDC698B3D41226A32268C968F576AFB37D8BB4E533B077124626535AC470D649A817F42243CB7CC73F0837A6527C2890ABE5BB762174ECCEF9B2F9A3FC77866ED031947CE54EFB0DB647BC9AB219B974E0C42A53FF6C65C1A67924C1B0415C9B9CDE4887023FDA6DF9A2F3BBD7BE5FC23EDCB6CBF5CE5C0D6B75C2048F05C5AAD82C87F5D0E9A146C3CDF01A973E85ABB5DBF4B3834BCF7EC7FCA3636EA417B92E7838DE1A8527292FEC5183F21EED1485B4AEE3541C00E36E6D3AB5563F3DA1DB962B94FE6121D36273D2813E785E491BDCFC825B0E98539B7364BB73885EDDE73CBC41B7F680BB00D9EB3047956996B97A6994FDE741AF9D0B302E99D3573117B4B537B1A3C384589FBC24156141473FCDE30DBDD305A6E8FAFCECB98800348A5DC2940A8D5CF2005CEF09F49B5FD5B415BD63222BF23DBA151A0E1925FA6DF135075E02D5A7E734AF9B92E947191E7221F1122387DD17EC8A4D3582949B58C4EE75A0A83115D936F59653592A5F86FC2B7C277DE26526AB23AE4674417C9C9388B0338F81FEAA741C446CBCCAB5755F07A195325E708256AF861913F50AC03FF02DF181E414E185DD7CBA0714FBDA807D67C938CA36AD52BE1DA9CD4FEE14BF1961CC1C20D3268C5563BD5BCC10DCC0FA42F01B8E278D3B2F549D6A1B497C8DA54995D395CA6E761D3B776C1D012B1F9B39DD73CD831F6193847930AA15A4C3B139464E3F89AF3B1C583E4E986B80C4BF117DEDC1C09390560365754F402C35B06DE3DC45ADA558ABC7EB3A63580FD8C9F29D335A8D9797D1420D4E3EC0267078F68361B65DE8F6D153F38FFE6304F0B886E94AC959E71EF2AA546DEE0E00E39A3E8DB5869C4434E862E60AF5883DC6E905469ABE8A9DCFF2BC85D14F9CD6470F8B092DD622FDEE25678887B97B021013BDFC8CA38702A7F49BFE92A3BFFB8DAC66D888A070613BD09A6B2D6C2CBC9E61DF92BB128E8C87E241E83BDDBB294AA56A5B6E70742F6EFC321CBF8717DBB5EC7529E34B21C8A73CE9EE0B7D6A62C96137A19D4836D53BC4EB8C1551404CA5804C1CE2350EC41C117DEE4152B65F9BD050E5BDD4A8EC392624EB27927D21C6F3CCA0170EA9C74534C28EF5BB45FAA789A46C703A723A82EF4297F907A20FB4B91694D5598BFDF986E517D251A401D035C5995EF8CCE18BBCAA3C4320F0F90938F7D5D9B04E187BC72B7DF045AA554544368DD90F726115A48E3BE841086889FA99ED5ABCA67683D090A8F3002C164C7C431539C1C8FFA7B871F40B0F42237810E3F603C63DD59737AA7275862DFE9046D22D59754D3668826A410EDDAEDF804E16B8E6D01D7705F611123C3F6A3822479430AB3A10F79FE2295558B60DF5A7CB1F02ACF8EE05F74A38E025C1A6FE1C02EE50C2B5ACE98528523F5C16C620D78DBDD54B0D66BB1C2E832876C304D794DC28D1501840A94FE7ECB2A62C9B68EFCD6D60E9F12E79E6793424B66F1CDF7C16B0F39D03DC0A178F850B1BDDACB3629B456F6647D0B9AD45E0A635420C1E1081D0E99D8B5E912F295DFDD262100D5E95B030CDA6BE784F6D38ABC0AB5032B0D42C85ACF782D382BD0711A7B43CB7682E908D3E36132145A1FAEB6670B26A30917682E4BBBAAC884A7306192257E9ED98A771F707A1E14AEC44DB71359E49FE15529376DF4BE36A0D00241DFD320E93C8BD8BB651132C4917229A7E5284F83408E2FAC8588E3662F4AF09D4E3A8F97CC55B507A2374754B15B086175FB593B007ECD560F7AB9E7D6611D816FE58CBFD083D144E5D0BB7C4D76A510F56C7B3170ED5A4AF94D3042073F3720A8BD2DBE40A90AEC4765371C7F27036C75B3A05E08D3A0EA4EEE0C583196952636745A9556776489A46B7FE6884EC255032CA37CA59E33399206BDA71ECCDF7E901F57F7F11732FC86CD6F6BB761F612DCE82455C80382834A2F660D38CFEC1F63DE2AF8B1779394E23747980B3D4AE572409E03AEAB7A80FD951CFD64BFC061E4FABCB4BED38F1AB19C819A797E8C378010A56C3E7CE889DB8DCC832A637B4D1E04C2EEE52E2BBE8A64FE47EC9F3ACBB73D8AAF2DF8F14D67F92D2C80373D2180788FBEC28190CC824D90DD5DE2F4A95E0CD172C1D1D33D2E24B48A0611C908812BD1411DF363F40F317731DF586F7A156418F5EAD8C06E116F28B4D0A1D1E047FA249ED4CC653AFA03DF4631C80D529F886D1393C0E763C325FC3B1DB7DE834DC7A3775C5E0A8393256D9DF355D7B173BA5C0FA8C0807F8615E3EE5A5330F7CF408848188A46AA98BD6BBF5B6925667983D4354461B43E0E5A09FACEE9E285F2872F972F7121957C5A818BF45B7B4D8A83DBA07DB5D16F96B51A46B771213FE8810D53B1EE68EA8A2EF1870DAA7E9CB8570FA04DF817AD58EC6556929AE490B09463B663D899C0F01C5A30E31991812F60A686877C254084FA73C4E28D8267E43FC873BAC32A2EEF54CA235D2089C7BD98D90099EE3512B629BC63A69EAB96D2F60EA01D293DFFC6FC355A726B0EB91D66358834B1DFCDCF5738F929226A63BC8F861740D844E47E2D3B731D03A902F7627C0F287F1863CA4E29773E966C9BDE3D6EB2C83F1FEA43227BD9B556B9773378F3D5CBF571EB6877A334C438C8071B9CA6B8F2AD85E66CCA1312826FC0428FA80AF251D13E3BE157DE900203A2B2F09CD22ED5CB33A71A10154828784BC0D9093B731096BCB14FDD8A59C06BA7BBB6F46285EB75BE0F7E5143E16FDB3B0309303392E62E536299C825293E5764040833BCD0DBE3FF00122F56C1C2364B798293B9CBE3000000000000000000000000000000000000050A0F171D25""") + ), + new SigVerTestCase( + TestUtils.hexDecode(""" +6C9E7A1EE36625760E5D2F33DF2929DA56203234069160E5F2BF039C11062273073C237566CE055D871F38ACD1A9859A824467F19BE68E4F00645D225C42C85A557D2C5ECB442B0F028A6528898EE2B673D863F32EB9EC8164127541F32519BB88E034A03F46F7D193CD3DFBADF63557926C5C8F5B766A7FC5EC8B3F948BF7A821B54C9441AB0BD833FD6354CEC706FAA500ABB5289B90B1BF917677A29D115F0094BDB48DC72E261DBA120BA6FF5E52A01B178981DD8296444656D9442DF9CBB6BFDAE56A230F6F29F94CDCC265576AA8752ACED07E99895CAEF0168BF83D23FDADFBB928CBCDABA25FE2CD26ADDFB0DACD74940F351426942F176FFBC5F3456DB7C912AA16B86D0745F87C9F45370A8456A1ADB51DB4052B5C9EAF60AD7B80A42EA4BF92C841273AD761DEDB0D34BF579600B149FCCD42AB1549BA0ABEDA57EF71D1FCA5702AAD083299BB98300189C25F3B270A87658D0B2EA56524147F739EB6C676D7BE73DD3B95B10C55AB46FD01549C5168BF7DA13A499785F35A1E3B56F4C567F54EA9AA2817A336383643FA2EA31FB1B73E10248DFCA05C04131266498E1C9491135A50E63D02FADF4165FC9E15E3E1B32FAB8337684C49193E1BC4EDEAE373A267A714AC1F909CC657CD8066646327E0EEA041AC9F2AEFFC80691BF60D3C94C642557E4299D395922216C65E75B7E1A5028960384BF816C9F7054829E7985B5841A733F33FCE2455EFC89BAE84B47990E8D0AFC6193E4AF9BC680AE24FE591E88BA6A2AE12DA3858D21F492D24ABC4FE4FD52D5ABF24BD254687B918792F0A003A5222DF45038685C725CE7579E02CB168BBC666ABF669856E10537C9291692C0CB0CFA906270AC2C7B7DC31D4F9283CB2DB8A462AEC0B9807BBF4AB4576FEC6226B4179322B67AEA53BDDF9C9BE5E0DBC43F78743068AB5BE49F0E62F8E2EB1B6C6736C05C9413D065CE0CCB790548041D7E832881A839B5729AF94AB79FD8A16DFFF78CAAA141D97CC0650F86262F26159BE8B361A4A041E9A0B6511BBE3355A4BF57AC09848847EE0243C3BA774776F7E9A227275D74E6E3101D382818763ED1E1353AB9EECCD920CD28922D559A4048F40F062164CB661C4F4AFA81A3D55933C4791EDDAA3939E5AC342B0AD1F438A532C6CE786681A870D94EC88A334CCEFC6ACE7D988A1A82BC0ACCE785F123BE23A7C92AF108E5ED4F0869E22DAE273556D1DE386623A6C3F115BBD119271D3FBA796F618B53959FB98012E7D5B9AC688940B87E2C9C065524A00D3A4F4DBF52F4B1A63EF5C46193BADF7AD7F988D4464345B2C3E549684F2F905F6F89DD641473EC05108A52D8DBB91768C541DE520B17666970AAEB506E75D8EE9F4B4455B71E0088AB25655213B75859D25F559D3C324D283D397ABE6F0AAA386815768D03357D775964902413153E3560CCEF1FD44B65FF1B287A92A9693F034B7EE668934702D7501CAF6DA4EE98AF4E8E64B0340E0BB8BDC533B0EFEE1915A4B68B93C5E95321EEDC234AEFE71AE2E5DACEC2F52F83723A2392A7F8E13BC0301CD104D852E62A7F828AD329B3D9596C58E13FCC0ED96C1C48D82A2C0F4D9D24DD8421FDCCEFD497A9B05FFC50904770401373FEE7DC73773418AEB4A1F599A4BB38EDE8D10A3CC83A1C72DE921969E3CE3E8EF2F7DA89D344C80D61CF9C5A423B1A4F3567D96DB2DA3DB9B5B5FA68156BE7452C8A0181BB9F0DC75CD9750883D0DDAE53FC156D67A74200869046B41DF4BC4396993C08AA4897A0BDDEFB55F69CC1C4D7B5FB150408427B416F73183F2B3CC16E3B7DA63CEE1143ADA1A056626A077B6D21C3DD974ED907C5A094019225737EFB93319AD3B40A4F434AE49D28391C17A999C744A68C55A91B862729583D3DA46EE70C5CC461694167D32D21DE75327732C63BBFBD7B30DBF2057A0D681519F6E4AF608D4BCD0B4750726770E156AEDE85417BD759D5FFE401CB2996F34434DB428D9A417037201FCD260FAA98084502EED5C27A8916E44F5929819D21A69CE16BCDC3CC8141E285EF897B1402C15C952590119051E369A1B7BE443FEAE6E32BC8F3D647FC5315A5200CD5238DC6677466EA86EF8D18E5A79F262483E896B8277C741F516FC040C1090F2495BF1650B02AF30456733A071AF47D7A15BD8E32A49806455D3BEA74AEF5D00906AD2F0C045354EFDE7C9A276E73D9EDD11D1CA5C297B9A6851E7F67E21EB061BB55D9E673C4A75FEB84D52629EECC53C24BEA95153051AC206C87DF55410CA1FE6CFC3F403A6D9D43EA84C60C945E642B2836338B5AF9F69E52708B2E225933DB320BB3F790D397F22D7B6F8A433CDACE9810AA0E27C699555530C562DBF7517A4162628BF10D1B6DBACEF5C9ED51E55D9A89D60E0FC378C47A21D5E0F2DC3BCEF5E05C6E0261530FB027E5032558CA2B47005BDDE99909930391EAD7F3F0A96B3DEDA54A11145F530E51DEF892E5AB0204D614E6E38AFE79CA92C28158D570120353B7A4DE0889846D835294939557ED0AEDA270D4D73ED84D3D49F9F032D43457BF59BB7D66359DC53F9B46963B21784B06CBCF04BEC1E33A33371532716C9EDB3FBEDB81999B4372D0945C10AE826C60FFE93170B6D294B3891B0D2A7B35B28A8971845DC2FECE237B80F20B379CC4D136DAB3FBB3792C63EC61F5C755BC9DB35086FBF46D2B7970DCA2A8523FDB4C7A0B8E42F8AF9ACAD2A0EFC113602A4EA62E4EBB7D269C3A40BA2C44EDD2956"""), + TestUtils.hexDecode(""" +C4F59FA2DE30C8420A7E7F096BAF6AD69B1C15A5C6E61C9D82AFCFDB6EB8F275BF5787186AAE781F487F9F88758C9C61F35D5083EE70424B0D0A51575010C2A907F49608115D33EBA0031509322AA7D3061FEC3162F96A565F98769E9A19235D89D1B21D60A381DF8EB37D58C6A2E483A8EB70736E4B7BB911F7AB923DC29F1E"""), + TestUtils.hexDecode(""" +E895DB64C57BC3C2A97F0EC933410E98F6216103E3423CAF06A671964C514A694EB6F65CBD1137CCCF8881FA403C5FA0E0B2F36B9F4009C378210D29E54A7A5A9B793197CD6D2F38D7E1F3ACA69D48881389381C89FA676DE426D634F9A157055F17283ECE8248CAF14DCF11E2D56355B047DF632A18482E79CB2D5A743966BAA8A76121BB69C2E68155ACCB0A31DA6EDC73CB09A9E660FEB20F66C7BD967ADE32149C5552EAEB2EA175B56233F3B370EDD8679269CE0D2B43F6B2F65FE957E7AB37B982043754EAC8A30B36C10004EF13C692E219AA7AF0A4C5286910C7100DA41E17BBEF2DA2AB03ADF3074BA1DA15BCC84805B89B9DA88E9B400AFB7E3BC8338D354DA953AC0BAD822756CA92E5DD9507F42BFEFCCB32B4B91A2BE5EF34C2CF1177EAAFB250AC9ADEC4BE71807589F1003227F9B76B74E07BA67AC60819B2AF766A47FFFC7B76D3A7C077F5EC69AEEA3E963859B82C2ADE58BEC2152EC8205110975D37C6505E0DC776FDE071097E93013D1004F4E1A2FD79B877ED5025F527F3BFF137F041BB9BD001E949F08B4CF88DFD32FC7CDBCECCFDB0FA2DE7823E110BCFF58A412CEA2795753E9C89678C3AE24268F7489F72974B6955EDD04E190D99BB0D7A252FAD5BBA606C1A1F3ACA733BFAE3309EA0A6EB7D07E36D8CA336D2644FCE1A41895D014D1A60CB106F3F8075F9378461738D63D115D00B024C677801050A1B0B50DE057F85DB6AEB2C9D6BB7402A66E3AB4DB05C58BBDA12F695958B8AC7B4E45EC6C952F679C1EEBDF860E348982779AA6988EFC2AD1DC1EAE22A27A5B2C61C97B3B2493CB6C13C5F6E20A67B88D3C3ACCFAF0A425742DF240634D1EE593828FE6297446C076F979055988AB834B2BD82E14DC086400E1C956CC0C30CE7BFD962223D23FE9494964A811B93E8D7B8F34C89AAD45DD4113F2AE7BD94B53FC86E8B2AE82E51EC6F3EA4C30D60B86072748612D1607056B5FF6A4500EEE78A5A639C7B74169777626864DD9EAEF0E3AD8493D831F71DEA95BBFCF81423A266DE56F3A8FE8E6C3C0D612FB62BD642188CA71CB89834F30BCC28BD178845F1F6F46C03D306F7ED4E68759427AEC2701198C3C05D385DFAFD528CCE8425BC551469A0ED681BEE4D12A843E333B5A8E0517FC61906F9C4E7809BAED4D3D16EB22F1FA9AB402D988ED59F9FED0455E9260FD627A24A17FE7CB63E530B48F5FB6687A2E8C49DA79FBD69A3400056665DD11D19A2BC4DB1D374AB6A6E42472A27AC6B98F676E8EDAADD514F6D44DEECDAB5A6DFA0F84F139A803A2524BF335DC52EA58FA50D98FB5CD55D5D50A663CF647EEE56FE8E664B3BCAF9E333978A7946973FD113E4FD3924E6C09E60386444214DFA7A4D671FC23890637EB859134D79E265C59CA3ECCDDFA018223C9BAE1CCA103962078BC5F0DD02246FA28324F7CB2FCFAD07C25B4BC2D888069B0CF5F23C761C0E47109881CD31456A64B940B4BB9B4C2C3B8E6BA834AAAE69FDFC47D44B3C96887ABED36015E7B64E8542928F277CBD2D3C512C24DEEFE590E81C684E063E7AADCF117B48943DB771FC2207F57A745357555D419C9CDCA35CC1A7100A6913A3B6AACF796FE3F94DD2F818982716CE0316542A1B957E12DA43E231542CC14FCC66D728A68326B2BC311248330F3E98F81EA38CA924A8E4DA97CF673842C759F935BE88163CE97FE4D9457176F5B8908AF948F74D5D1DDBC521825D931C63CA8A8E12242626305AB6A2E0624564EE041983C18C2952EC3D9D159BDE3985CF77897EE2DC888112721D4854E914A5397E08B54F4A54323FF820821BE026EA091ECA6B7D80D91E3DCA2EF7848B86FCA6BB40CE48271E1008368E3EBB5E395E1CCD0D178F1A6257D26B6BA4B7CE532CAA1E76CE28FA4CF9E029E2482B94D3ACF97A326D235D1BDC89F70002198451D9F1F12CCD5BCAECDDE9E14AC80742EB31E6464C83210A39F35098BE0378D074CE1CCD1EBC1C7770F778D605F2BE59DB7EA07D80CCDF55F16E985B142FB7BDA07AA7DCA5B201E1950CF9A728F21E9A9D8AC4D1327E3BC0FF339A250522F631DF2E75955154893E4A1AAF9866FEE1637EE1AA5106D244E99E6F31FC5601BB7B79BAD82860B1D6059D9B132E026418020DB06EB8391FA15B7A0F29E36D966ABD3D2A2FF3F2AAC34C8B45C7D2355EDBB80B224BC106EBC6750E55070F85A7CB6003394E5161AE26F5ABF83F0DCCCF69B86139AF8694FE1DC00781EAE09CDB421814878043DC9B0530E5545A165E39A9B7DE88B4AD2AEB90D3C329412ED2FE1D97B732C8439DF4F83D228835B538DC278FF0A2DC42F41B00CE3ACA06B05C4839B896931515D78EA3673A378279F4E89CE08E3453FF2FB453BE031C6318628A731D029FC7BEA2BA5EAC4916278B938A6A6ACEF5BFE2158F2AF43D8E56A0649DF28A250D2F2536ABDE1E008EB631F4BD0EB55573A40539A6004181A9D2BF7A1E53504F11E014840733844131AC668946E5B827289AB6B21366C5D0E2649219B92C4760DFB705F7F61A96564C9E840D14B0BB0DA82DA50F8B8E752BBFEA3B0A337BE124F72D8F8249195BC19C3E0B62EAE496D38CF7500B4F10665FC2D28B9EA935F7E316472F4FF401267541BDB62301554B2009928C6445BBD0EF21D09972F35081ABA9091A6C23FED29F5CF9E0779F7EFBAD88E62A454442B30079BE0AC9C64826B98C1E1001CB0FB0F0A95F7965FE9312BFDAEC33F95065C8E59D3950F80ADC7FB334F202D3E5F8DA481C9B54A75983930FD1E5ACD16284F07193FBCB50D0DC00EFF8203144C11EC61420FC32D7982CE896406BE769A75DD8D3CAC753ABE5A278655BF54BE33A1B8374EBEEFF212C39CE514668F1C456EAA2532828C84293F1A5BC9EB5DEDF558A9B4C1239F77272C67E1AB28E1EFEC5893E09C10662B53C8B8255B1C8DC8F8E5120A25C75EEFE79C43F7A8B37DF9D1E4F32486933DA1CB0664C5DB39E21BC227B0CDFE7A5507F07F218A7A47DEBCD9DAD7247B4D045A13AD4F75EAD2D45C339D0DF04577F2E0FDC780392553033C738852B1BE4E63EA3897D6C9C4B11AD6B58D3E2D342D32840F649DD83E759866B7381A84C8ADDDF413FAE18E6431B1EEA73A56CD889B76BC9786BEDEDCA2541E4C9B24E28F58AD374C1D93DF2D3F2C37EC594A0498C574579A7332F72C0F9750877FAD5B90B968D88F11682C4071E4EA38B816AEAD6BE54D2F371324F2475B862C75424ECF9858AA4E200CFBA412D7E3E6C308D8DE11DD185331AF9D41AFE8879965D6746EF21FD98D3ED3806FB5C4619C98E347D76B8B89849395561EE286DFDFC6A04E1D47E9F5B5B49257784C39364DFA88AD630DFA59CCA3237F4A2B141A813D22C6FFE73C2D99ADC824D93E06A54B6DE62C3125D94B49E950DEC361F961F56D3671C9925377F6E670665322B8489E833D3830ECCDD0F53F4A4F9D68F1445F3AED5C9D766409B59BAE7A72912E98B3BB57342D29B6ACFD14336B7B8B6B7549AF8CC8845E10C2811287281985D5D47685FC589F2678ED893F57B85ACED75632E50DE5E074E6CEDCF1AD499BCE67A7F498564DEEC677C708388DE8FD7B099CFC116096C45FE28890B5EAF06169939FDA35E1215F238E8CDEDFE670065F5DE3272A232FD53C250F5D779B31694FBA91B554803676E4DEA288463FE1063009E9CB76C317DB400ACF4D2D2B6D16EDEBA4108913F60AEB252CDE413690CEEFDCFA638963DBD04F4CF21AD74DDE65F0F1E7CE70AF101A6DE9A59DB21D38027DBBF76167827950B69418266AFA444C728DE3624A1C81E5B1641DBE879CD822FB2303CC3A9FCEEFE3DDF7DBD0B7057248A28D6062D76EB13B92C9C9D003B69E1842A54C09CF6B484520815E2BB237288C64FC696FD3BC45DB30CB86465DF1188BF47956E5B916A8009715CC9A9A6DCE44C54F928816B41D018C5FE652FFE4E33F352D383A9C1365F02ABFD647BD6B42AD163730F8BFDA1E2BE5F614D79597825BA09F457D3CBE7561E7E89EAF059E977D1EE88848B781F21F723890FF1F9873928412C8F11EEDD2C0C39C9512790986A19E17B2B70A4D7CF49D9D18CAA0C2023134CACD169200D8817FA321F04ACC910613DFF250EB325DBEF29EB5611B2AD2A23EDD538049B3F43EFEB4D60983792B4BF05567944AADB7AC4D3A5D80A1B9D8448B4C0C115C3B5AD3885353F47D5FCB9B7D6446F1A7210BBC667FC411415F23CD40A2A3D64061D71C67191571A97D01088A24B6711567FC89106732D8892FF985B8E6CF70163829CC085BE4E408315361BB1B2003D6413220B134506D3C304C0BBBA9C9C45D3651E0571B6B115177213D8595E143DB90BD72F7EB974D8D0A0317409D64D5837EAEC9B8D44DD7ECFF6CDA9F729382A43B379CBDD43FFB18AEA35C1A996CEF1488D3B7A81EE7CFC0B9623418AB3919A6EDDB99F222F0DDDB2F32A20C8F84FBF4C49B4CB3EB50D9C4CD25A6F7175467066D25E6437B67F2DBC70C2E6EB0BDE2386D03014A789FB6DC08EE33C0C67951DA9D74B9C94845D2A99037E095FEF7919920FE526EB5DD0BA1F97DFBD2DDC31609C1B7B45EC3ADB586FE3030A0C7A9DD034A3C2E6F9849093CEE10A181953547F8BE328720A4A5A8290B5EE00000000000000000000000000000000000000000000060B10181A21""") + ), + new SigVerTestCase( + TestUtils.hexDecode(""" +6C9E7A1EE36625760E5D2F33DF2929DA56203234069160E5F2BF039C11062273073C237566CE055D871F38ACD1A9859A824467F19BE68E4F00645D225C42C85A557D2C5ECB442B0F028A6528898EE2B673D863F32EB9EC8164127541F32519BB88E034A03F46F7D193CD3DFBADF63557926C5C8F5B766A7FC5EC8B3F948BF7A821B54C9441AB0BD833FD6354CEC706FAA500ABB5289B90B1BF917677A29D115F0094BDB48DC72E261DBA120BA6FF5E52A01B178981DD8296444656D9442DF9CBB6BFDAE56A230F6F29F94CDCC265576AA8752ACED07E99895CAEF0168BF83D23FDADFBB928CBCDABA25FE2CD26ADDFB0DACD74940F351426942F176FFBC5F3456DB7C912AA16B86D0745F87C9F45370A8456A1ADB51DB4052B5C9EAF60AD7B80A42EA4BF92C841273AD761DEDB0D34BF579600B149FCCD42AB1549BA0ABEDA57EF71D1FCA5702AAD083299BB98300189C25F3B270A87658D0B2EA56524147F739EB6C676D7BE73DD3B95B10C55AB46FD01549C5168BF7DA13A499785F35A1E3B56F4C567F54EA9AA2817A336383643FA2EA31FB1B73E10248DFCA05C04131266498E1C9491135A50E63D02FADF4165FC9E15E3E1B32FAB8337684C49193E1BC4EDEAE373A267A714AC1F909CC657CD8066646327E0EEA041AC9F2AEFFC80691BF60D3C94C642557E4299D395922216C65E75B7E1A5028960384BF816C9F7054829E7985B5841A733F33FCE2455EFC89BAE84B47990E8D0AFC6193E4AF9BC680AE24FE591E88BA6A2AE12DA3858D21F492D24ABC4FE4FD52D5ABF24BD254687B918792F0A003A5222DF45038685C725CE7579E02CB168BBC666ABF669856E10537C9291692C0CB0CFA906270AC2C7B7DC31D4F9283CB2DB8A462AEC0B9807BBF4AB4576FEC6226B4179322B67AEA53BDDF9C9BE5E0DBC43F78743068AB5BE49F0E62F8E2EB1B6C6736C05C9413D065CE0CCB790548041D7E832881A839B5729AF94AB79FD8A16DFFF78CAAA141D97CC0650F86262F26159BE8B361A4A041E9A0B6511BBE3355A4BF57AC09848847EE0243C3BA774776F7E9A227275D74E6E3101D382818763ED1E1353AB9EECCD920CD28922D559A4048F40F062164CB661C4F4AFA81A3D55933C4791EDDAA3939E5AC342B0AD1F438A532C6CE786681A870D94EC88A334CCEFC6ACE7D988A1A82BC0ACCE785F123BE23A7C92AF108E5ED4F0869E22DAE273556D1DE386623A6C3F115BBD119271D3FBA796F618B53959FB98012E7D5B9AC688940B87E2C9C065524A00D3A4F4DBF52F4B1A63EF5C46193BADF7AD7F988D4464345B2C3E549684F2F905F6F89DD641473EC05108A52D8DBB91768C541DE520B17666970AAEB506E75D8EE9F4B4455B71E0088AB25655213B75859D25F559D3C324D283D397ABE6F0AAA386815768D03357D775964902413153E3560CCEF1FD44B65FF1B287A92A9693F034B7EE668934702D7501CAF6DA4EE98AF4E8E64B0340E0BB8BDC533B0EFEE1915A4B68B93C5E95321EEDC234AEFE71AE2E5DACEC2F52F83723A2392A7F8E13BC0301CD104D852E62A7F828AD329B3D9596C58E13FCC0ED96C1C48D82A2C0F4D9D24DD8421FDCCEFD497A9B05FFC50904770401373FEE7DC73773418AEB4A1F599A4BB38EDE8D10A3CC83A1C72DE921969E3CE3E8EF2F7DA89D344C80D61CF9C5A423B1A4F3567D96DB2DA3DB9B5B5FA68156BE7452C8A0181BB9F0DC75CD9750883D0DDAE53FC156D67A74200869046B41DF4BC4396993C08AA4897A0BDDEFB55F69CC1C4D7B5FB150408427B416F73183F2B3CC16E3B7DA63CEE1143ADA1A056626A077B6D21C3DD974ED907C5A094019225737EFB93319AD3B40A4F434AE49D28391C17A999C744A68C55A91B862729583D3DA46EE70C5CC461694167D32D21DE75327732C63BBFBD7B30DBF2057A0D681519F6E4AF608D4BCD0B4750726770E156AEDE85417BD759D5FFE401CB2996F34434DB428D9A417037201FCD260FAA98084502EED5C27A8916E44F5929819D21A69CE16BCDC3CC8141E285EF897B1402C15C952590119051E369A1B7BE443FEAE6E32BC8F3D647FC5315A5200CD5238DC6677466EA86EF8D18E5A79F262483E896B8277C741F516FC040C1090F2495BF1650B02AF30456733A071AF47D7A15BD8E32A49806455D3BEA74AEF5D00906AD2F0C045354EFDE7C9A276E73D9EDD11D1CA5C297B9A6851E7F67E21EB061BB55D9E673C4A75FEB84D52629EECC53C24BEA95153051AC206C87DF55410CA1FE6CFC3F403A6D9D43EA84C60C945E642B2836338B5AF9F69E52708B2E225933DB320BB3F790D397F22D7B6F8A433CDACE9810AA0E27C699555530C562DBF7517A4162628BF10D1B6DBACEF5C9ED51E55D9A89D60E0FC378C47A21D5E0F2DC3BCEF5E05C6E0261530FB027E5032558CA2B47005BDDE99909930391EAD7F3F0A96B3DEDA54A11145F530E51DEF892E5AB0204D614E6E38AFE79CA92C28158D570120353B7A4DE0889846D835294939557ED0AEDA270D4D73ED84D3D49F9F032D43457BF59BB7D66359DC53F9B46963B21784B06CBCF04BEC1E33A33371532716C9EDB3FBEDB81999B4372D0945C10AE826C60FFE93170B6D294B3891B0D2A7B35B28A8971845DC2FECE237B80F20B379CC4D136DAB3FBB3792C63EC61F5C755BC9DB35086FBF46D2B7970DCA2A8523FDB4C7A0B8E42F8AF9ACAD2A0EFC113602A4EA62E4EBB7D269C3A40BA2C44EDD2956"""), + TestUtils.hexDecode(""" +C1E665BF7B8BD0198F069CA17EFC55B7EBBF9CC9D41140BDD0B83AA08062FFC717D3F6C22DF38EEFAA6EEC91760CAE0B3DFEAB78B03A7AB7A993B2097B7B887B9812AE2D0892B696374C034FC9E95083C2B61B09DE97D9C500FE55E489C53CAEBDB57BC69071C15808890F8A007BB5FE773CCFB729463113D93E9EC9EABE2047"""), + TestUtils.hexDecode(""" +051F8A9A5DC6D35B1485288359F818DEB027E1231DA8C048E79E9FE228AA0E9F1C0B7F4C573B5DB8CCAEBBAE8EE38D8FAEFD3B8E7730BDC0E9DE365B20E5A0F9635A0B39C7C0D6163B7876ECC6ABCD8A5F608E7253537C1C94C209C8448E02806B2B5EAFAE2483170B4E4450380C2A87A51F82B179EE0F46509404A3A9BD74D04BD75635B797B500F656ACAE5DD76B04741792112579E24081A6C88BF4981346E2B3D38291026D3AE47BDA50AB0B23B0881148489CBD057CDE9A4F6FF108B7ECCEA44D599CE3ADED82AE0E8F74DB7D604161C8664B7389497EC9F35C46FEC064BB867E867E9309C10FBC07BD5E7B8A74BBEBC1BD0E4A9B36EFE297E9F2D23DE32ED704EAA377F5C3BC4BABCCAD5B4B6B9A137F23C46C0423ABA3F1AFF00C6071CBA51B7D0A8E677F5138DB7C013CAEE1F68501430F0F448AB283692A18D15D8A46BA620EA906A3032570A659F594236F0512389E1DE63B8E40AC22DB79DE60CCB9BCF0B20EBEF676A91AABCD01D3AF882931AFF8C86A8C946E09B8B5CFDE62D53A03DF07163B081B293EA0287AEB97D1762F34361DDE654D400DFAE5B351D90742A0A269865D49C9221DD89E42FFA63EDDF449B10458CFE2EA7E1A16BD22FE73F208B4472DA8094F28CB9DCAED6E843C57E9E3258BEADA48D7761FDE0104AC6F0CE09F95E1F4AFF00515AC2E3703D2FC6D757B12DFDC044E854E50FF2D897900B0B59BED90BA4201694E29E6A830D8039CD835C706EF59E7A6B0ACA7B7D0B40D264661711E0372BAB7410A74460D07FA988A8617D31074950838411037307B052FD536822608F9D15BAA780AFAE1A8D87BF844D3A4FB31A176BBCBEA46A72BA990FCF821AC3A73ACA01E09A20AB93FC737ED4C4DC482BF9BA21D7178D24DD5D6A29633386933A3E8F28982731F07606AF28BD2D81004B044B4EAAE67E29840BC78EA66FF840031D8B2894B603733E1A0398FB0E4952B2ABC567668443581C860F87A76774E6742807C39FE99269E3199DAD02B246D7AC24E5BD9DD91F7D16A76E72318882FA21672A7D5B1A4F212954BE2B19897243F60C18D1DED2AFDF69DAB8C9B10342471C633B33C52E95A85D3142F2E46C681AF373C5E92BC948FBD31207F015DD32DE2591DF4639E4E563344D440653592EF2685E1320AB9E51837F6C06D07E5462599FC6F8BB120826E738E2223CD4B8C7CE446ECE681DC6D6BEF1D6385B0AE7E404F502B87989D969B81CF42085A7B58A41EF73EDC73056DA72EF65A7AC8E284E7F51E723102CFEF903688F870CEF1C7E5264330E3033691680050E926E93A1C0C4161A7DCA14A0FF338D431D68FAC204DA28CCD1CE7BA3B7F3C45B4FC74D9E754A1A2F7F23F0FBE8D2FF01CE4683D8842E8A1528589E7D9260368A654CB514A85DA9C2EAB74C66FA17FDFB256D585D28C1DBA35E18779D7B6DB876CC0A98CFF752A0E8DFDD532ECB04C4101AF32E689D13874B9F20AF652069C1458D7FB382E317AF49083B5870078B39221464F376EC0BC2DC1C3FAF10EA4EA87A2F9D547B535F60406E8E68AD190CD4F00EFDCD9D54D4810F31B9F68F0D95E32CDF2747B9C20FCD1694FE034EF6B5460F163AC78BA235A441DB2B3AE84BC28CEEED7B3FC2A4D63330D14186658788DFD7652E477B1310317C86921394219D75FB6FC319575745589F9E2096801E57E6AED2369FE115C2D937EBEA3602194B7432B01F55E6C9572CD0FF8BE8A4796815914D5F64D93E0E709C3CF88741C851C8BFC4CCE6F0AE60A6D2F4DC6FD8AFC82E065956971FB8B4160AD68EF7BFCB3A9694CC7EDEF64FF08011B183BEB7A2D3D9024753B59900D27F52DF6D4B2576BABA673A0E33CC57B501E1C74F63A988E1A157078FA8B3F2A143CC9D41A35412B4E0CE6B1D9CFAE7470BF4C778D026A9AF86DF7F974E2414FD7C5F0FF6D62293C6E2A62D4C5268CD0B604047C9658F97D9A7B86E1C953FFF95CB478028FDCAE6E8F208AA208A282446B2CE8B4C7E893E269FA8E02C082F82966A4AE3FD86BE89A8CC8BB3D6B105A91DCF76FEF700E5AA4A15BA0F753129D3369915D7E896527CF6E71C363EF65B2218A5FCB8D8FD96D6A63A8BC547EFC942DCE1276E268841BA00E35769B4AC706BD65B275BABDD530771D854EC38AC0529729786A86C7C4161B3E7074023516C84B4B4776AC47C2ED1587861126A7A707978F2B2B2972C20F237FC223B56A67538F9241D926DB7C992A3FDFDF999884EF83EAC7DA0F6523F53CD40E473AD370C77B30DB2FE408783D24CF4C3512E3C6B677C41A67849FA1792313581EBBDB7BE0BB3EE85330FED8B5A1915F6343F3B7C928CD363463385436038B64BAB5D055BC39D18F9A1A8196AF8DDA5A1F428434958F5C89F07D7A53CFF2118E80060C5ACA71975C4C92A589EBF5746AC92C50FC1F915C146C2DEE7531B24970790A4AA7DAC425940AFC4C88ABEB998D549681C95ACBE9F7E274521D44E9EB759C2946504161AE7FFEDAD3E62D045AD77FE8C2B8ED529843DD341E2E50559A29AE26D431C9634C4C19A84FA0257F71CDF27C33F14D57347BE8B19D254E3C353CDCA10489F06214161AEB2A9D3049B3CE4689503621C46D192C1421B4B033775D9218DD2E216600E64D977CAB0E1675666A7CA773E4E139DD4EBE94CE35A28284755C52BE490514B25FFCA4174F54E8A5F715F924949C1467A282D7F2DB468DF363F9A55E5D7858D8F95D8083D6A594DC1B07A8C4FD4AAAEA0785EA3D9B50798F0A96AA386F17C2BFB94FA8EA3B5EF71012AF9285CADB1FE330A267555A942682F9333AF2E81515969B76FDC020F9CD29E848B94F26F4B53CA5144CBCDA1AB6CD2FACBAB0A2FC0F5B88DA0AC0EC08B9EDA7CAEF502FDA52006815743520F841CFEC3B4D9AA732DE408D6FB14739E8FE77CDDB68A5F6AA215B588F1491988B4460F6949AD647DE9105CA50CFB413A971BC8E6179F0724FC28D1A7D30C41180735F4FF6167810D9E88A5F7FDF791BFB474BB5478544EA74C9F07598D038CBBA17B83228A18B2AB09A8BBD2D2205EECDF01044D5A1B2BD50D2C8E3D5511450A4E594C1CE7067A6E14128BBB36E95C143EE6A51CA0EEBDBE47E9C5A87E81BB904013DC892D03F483B1DC82986DCE7A6E10192E6743283202D78D11B2169602A75C2A688DBAD50C9FDF1A1A15A470D882ED4B5207E659A94776ABC3D3583E1D2E85291D3726E75B7AEF9344180D325583A05266C196ED367E906121C33E701D428B46865BF32AEA4A90262866A024209A7663EDA4C340B5AF3E899F009EEB5E8D5003635EED501CC02D5D11F504C823C17E961D0BF611519961BF422647D97119F5745478888BCCE367639772953C5731434B28913F3F709AF455053F6B09519AEB6B755CB02CE74DD814714A2E0B477C05202092525EC03C5B365A75086E3281D4BB5C3AD9D742806E58B5CE4E1E95269AB18B68B2928BFCF7EA683967C0B88ADA99FF35E1D5A661CDFAD76774B42F858AA54626B88050D992FFDE16FAD3A8CA496CC6BE339977BE24D33E8BAB86B421F4BAA9C12A93117E43415929F0C4DBC9737EA5586780886A8EF4E4295DDBC967A2B5523FAEE0C060468F9704509C4CB14028E8A1672609A8CED43F1B06981FBFDFD52296D7BD3B4AE68E7D54BB2405799278AE29B66E258D3B9D276FD34E192BDE869092F6A7F761C6DDB0DE9454823256C7B17ABB91003B1A3B66CBCD4F9ED068409161635F6DF9459AC382044EC14FE8B2A586FE02C74232BBBF27800ECF627AD1C6ECC93C13EDA2DC20C8D6714C519D6A571E708787BF342DBCDE10EB1BCA5A7FCD971CA52BB68FB33ECB7F90AAF739F0C5B61BFED72CDB46A712DB6928F84892D3EC2F6C7023A6B664CE9CFDC33D2F09D38B5E4D182C73FF1D7B474C8AD6E883ABC78FEC75C8A390CEA561A86B92E2A4A1950997594C29A35E4A71B0E484FCDA63E5EC9666E0A463325DBCF7258D36B85099AB7C81E70FA66F1A471D4C1593AE68404F31AD2667017C9B5B3843FBC48D831F6A9B5FAF7C73A8478A7DADF28FBD9DDF979418870AE61E94C6BD47FF2C39073AAE16FF18B161B9B21413E66E489EF9F8784E5DCBBE29127B0C51A5C1E2A04E9C8794964D1823ACEB9ED0DD555964687848629EE06B0712483CA30D6D4A91E047EA33D30A062D8249278CDCBBA2A1B3C133D3E671FACB034AD0F9AA40628C0E2288B56F7A76DCDFEA762A8DB323B44925285557C3501999CBE145D15EA82169007A97EABABBE69479E03D40F2FE9217F14664726DCEA227107412B3CC742E4ED168E051D9AD4468131AB035708ABAD78659CCF5988F70680C124468CB80BD9924B0E41CB25AA69E7877CF5EA348403AD0899A5FCF35D4F22F3A73F0207E96785F4EB9AB93B6F10EE0B247D31F3D62A85B99C88CD3B19BB68E69C51AD5B0A8E9E34ED611E24FE2644F1697A8A11B64B578FEE1C5CB31A605CD987D765FB68D833E4BE9358D869F4DE0362E6889FBE8E95B861E078CE6CF0FF35768AD49803A71E8DC60296032E50A9D0A4E64A3D4661E7C55DAFC6FDD1B18EB1003D290BE486C520A2F8F0EFC1CD2CEFBF7E2459CC7BA88695D1122A7494A3A41C329EED2A8CD2282A607F93A2B7DADF0F32414C6BA9BEC0CB00000000000000000000000000000000000000000003090D101922""") + ), + new SigVerTestCase( + TestUtils.hexDecode(""" +6C9E7A1EE36625760E5D2F33DF2929DA56203234069160E5F2BF039C11062273073C237566CE055D871F38ACD1A9859A824467F19BE68E4F00645D225C42C85A557D2C5ECB442B0F028A6528898EE2B673D863F32EB9EC8164127541F32519BB88E034A03F46F7D193CD3DFBADF63557926C5C8F5B766A7FC5EC8B3F948BF7A821B54C9441AB0BD833FD6354CEC706FAA500ABB5289B90B1BF917677A29D115F0094BDB48DC72E261DBA120BA6FF5E52A01B178981DD8296444656D9442DF9CBB6BFDAE56A230F6F29F94CDCC265576AA8752ACED07E99895CAEF0168BF83D23FDADFBB928CBCDABA25FE2CD26ADDFB0DACD74940F351426942F176FFBC5F3456DB7C912AA16B86D0745F87C9F45370A8456A1ADB51DB4052B5C9EAF60AD7B80A42EA4BF92C841273AD761DEDB0D34BF579600B149FCCD42AB1549BA0ABEDA57EF71D1FCA5702AAD083299BB98300189C25F3B270A87658D0B2EA56524147F739EB6C676D7BE73DD3B95B10C55AB46FD01549C5168BF7DA13A499785F35A1E3B56F4C567F54EA9AA2817A336383643FA2EA31FB1B73E10248DFCA05C04131266498E1C9491135A50E63D02FADF4165FC9E15E3E1B32FAB8337684C49193E1BC4EDEAE373A267A714AC1F909CC657CD8066646327E0EEA041AC9F2AEFFC80691BF60D3C94C642557E4299D395922216C65E75B7E1A5028960384BF816C9F7054829E7985B5841A733F33FCE2455EFC89BAE84B47990E8D0AFC6193E4AF9BC680AE24FE591E88BA6A2AE12DA3858D21F492D24ABC4FE4FD52D5ABF24BD254687B918792F0A003A5222DF45038685C725CE7579E02CB168BBC666ABF669856E10537C9291692C0CB0CFA906270AC2C7B7DC31D4F9283CB2DB8A462AEC0B9807BBF4AB4576FEC6226B4179322B67AEA53BDDF9C9BE5E0DBC43F78743068AB5BE49F0E62F8E2EB1B6C6736C05C9413D065CE0CCB790548041D7E832881A839B5729AF94AB79FD8A16DFFF78CAAA141D97CC0650F86262F26159BE8B361A4A041E9A0B6511BBE3355A4BF57AC09848847EE0243C3BA774776F7E9A227275D74E6E3101D382818763ED1E1353AB9EECCD920CD28922D559A4048F40F062164CB661C4F4AFA81A3D55933C4791EDDAA3939E5AC342B0AD1F438A532C6CE786681A870D94EC88A334CCEFC6ACE7D988A1A82BC0ACCE785F123BE23A7C92AF108E5ED4F0869E22DAE273556D1DE386623A6C3F115BBD119271D3FBA796F618B53959FB98012E7D5B9AC688940B87E2C9C065524A00D3A4F4DBF52F4B1A63EF5C46193BADF7AD7F988D4464345B2C3E549684F2F905F6F89DD641473EC05108A52D8DBB91768C541DE520B17666970AAEB506E75D8EE9F4B4455B71E0088AB25655213B75859D25F559D3C324D283D397ABE6F0AAA386815768D03357D775964902413153E3560CCEF1FD44B65FF1B287A92A9693F034B7EE668934702D7501CAF6DA4EE98AF4E8E64B0340E0BB8BDC533B0EFEE1915A4B68B93C5E95321EEDC234AEFE71AE2E5DACEC2F52F83723A2392A7F8E13BC0301CD104D852E62A7F828AD329B3D9596C58E13FCC0ED96C1C48D82A2C0F4D9D24DD8421FDCCEFD497A9B05FFC50904770401373FEE7DC73773418AEB4A1F599A4BB38EDE8D10A3CC83A1C72DE921969E3CE3E8EF2F7DA89D344C80D61CF9C5A423B1A4F3567D96DB2DA3DB9B5B5FA68156BE7452C8A0181BB9F0DC75CD9750883D0DDAE53FC156D67A74200869046B41DF4BC4396993C08AA4897A0BDDEFB55F69CC1C4D7B5FB150408427B416F73183F2B3CC16E3B7DA63CEE1143ADA1A056626A077B6D21C3DD974ED907C5A094019225737EFB93319AD3B40A4F434AE49D28391C17A999C744A68C55A91B862729583D3DA46EE70C5CC461694167D32D21DE75327732C63BBFBD7B30DBF2057A0D681519F6E4AF608D4BCD0B4750726770E156AEDE85417BD759D5FFE401CB2996F34434DB428D9A417037201FCD260FAA98084502EED5C27A8916E44F5929819D21A69CE16BCDC3CC8141E285EF897B1402C15C952590119051E369A1B7BE443FEAE6E32BC8F3D647FC5315A5200CD5238DC6677466EA86EF8D18E5A79F262483E896B8277C741F516FC040C1090F2495BF1650B02AF30456733A071AF47D7A15BD8E32A49806455D3BEA74AEF5D00906AD2F0C045354EFDE7C9A276E73D9EDD11D1CA5C297B9A6851E7F67E21EB061BB55D9E673C4A75FEB84D52629EECC53C24BEA95153051AC206C87DF55410CA1FE6CFC3F403A6D9D43EA84C60C945E642B2836338B5AF9F69E52708B2E225933DB320BB3F790D397F22D7B6F8A433CDACE9810AA0E27C699555530C562DBF7517A4162628BF10D1B6DBACEF5C9ED51E55D9A89D60E0FC378C47A21D5E0F2DC3BCEF5E05C6E0261530FB027E5032558CA2B47005BDDE99909930391EAD7F3F0A96B3DEDA54A11145F530E51DEF892E5AB0204D614E6E38AFE79CA92C28158D570120353B7A4DE0889846D835294939557ED0AEDA270D4D73ED84D3D49F9F032D43457BF59BB7D66359DC53F9B46963B21784B06CBCF04BEC1E33A33371532716C9EDB3FBEDB81999B4372D0945C10AE826C60FFE93170B6D294B3891B0D2A7B35B28A8971845DC2FECE237B80F20B379CC4D136DAB3FBB3792C63EC61F5C755BC9DB35086FBF46D2B7970DCA2A8523FDB4C7A0B8E42F8AF9ACAD2A0EFC113602A4EA62E4EBB7D269C3A40BA2C44EDD2956"""), + TestUtils.hexDecode(""" +62C2A85A6AE40091AE35068EB3E5B54803F495D49BC177F7A29282DF0C900E86F66155B4026064E7D6CF7A171F8BBB33449232EB5D7DB2B776ABBACECCD660294C25196E19FADA35E0F3524D78EDA25D614FB56DBA5BAC10D06EAEDD9644DA291DF305C1E91C82FA00EC470A8E822525895113A6FF7D1D52E7038B9CF4DB2227"""), + TestUtils.hexDecode(""" +9B829A093EC253FF3D955EBA3C0FDA29CD14089C6D699F26FC62BCD40F43D1582F2B693138AACA59A162CEFBDA6328F1BD67690C63B903F5062DCDFFA840DC2DFD4051F82A557FFDAAE8F4A4FB340D6F4AF03A19AB928F42DFD29FF8D028333A0C336D253C826175C5A194C0441DAC1C5A4C4A3E0B8394E43678DC915BC98628BF565C9E751BF9801DD6AD4A3621B50C8DD1520F0CFE475F5BF843DC2568B263978587322FD1D2709ECD869A77F054C0A45D466D297ED9B63F10020826836F531A06DFBE20BFBA0B3F204033783C5505BD82DE732204917E3DA12316559D07366600CD18EE2A329AB3B20BB0C9C607D0660044D2A9ACC5D25806F89DFD5813C9E54E0CDFC190A206300FBC8E2561BF3F23D04052902E49CD5DA530A4D2BC2E5F47EE93D0588AA66EC8CAFDD4B353D73B6C1765211405C080A614129CF9346A1593503AD75EB9C3CCC99DBCE1D937AEB7929A1B5351BE262FB2B41FCA6DD965CE596DBE39D07D20281A2ED74C35FAA474EC425A897978FAD88D470502008D9A0E08DFA2F6C33A0B4CF2456951109BF4F877D74D7681CF287F6DCFAE24D1FCB0FC69D7C4D33E20536C64ACE18F04A2AA8E767C24068F4BA45C4C49DC3B43AF803610F300D01C5CD9ED92F33BAC270ECE09EBA2CA0FBA180CD135E420471A7C6CA249D877DE616F054711B3DA2DFA5D2D3FE774F802F4880E4400FBE4D12B8D678DB076020D356769060253E5D68F665FBCE0EC702F42B94E2B0C8359CF4D6EBCDEDA9FAC8F2FE95B9FDBB9346C06300F60FFD4FAEBA01929CEDF0F15021689B6EFF9298BFB8E514D925541CE2130EE1F25ED6EA895F432987AE4A2CAE01B5F4691DEBF12129EB19C2890A9D268774881F151A06FE42656CCAFEAFFF01E3EBF52C6716CB28BCB6719F7552731C275DA226914D733AEC1BD599AED7BC0646B8E3D9E0F3B771295D43391F00293401E6331E37E779EA8914E7F03B4CA3D1AFAD797617D9D0BBC6020E1B40B431B930D19E0888518D6ED2E6D32BD872B9A416E0B47133867FEC96A88C6B67449E8881B8A455D1816BE7DCB22287D63DBBD87E571F6887AD3D6DDC08C0B710395A12570AE985AB08393BF99DF1A1EDEA499BCBBC2F2EC05FA3EE982E34814F56373891282882A05711EE9A906CFE5952A6AF64379854A4DEBEC24C22F69065D6FC392B4A687D66528615AE301C82D6C694D358B71451A536039368D05C3C240062E455A119EF5A1737D732C1079C7CBA9A05D9D8119CD94497CBE2A275C69D6623628ADBCDEDEAAA143073C6EC43C40229606E6AEB982CE1827F875FF0A6921E0D6D08F605EBCF85EAF0C4AFBD067A14BF9FA6C7A657213C04FCB93630D892E8B340217EB07EFE9CD320DA3DE466169001566373F589A4C48BE25EAB1E6A612187F110661BCED6C2FE2583F424641A420A0DE61B39026172DDC93EF444EADF8ED5CB674F0586307F2886CAEECBBF78A4AFB96ADE18F0504734A082C168921005300431BAAA9FFBCFC96D272E8FD9A10B7F963BA868A273CADA8082353C0E1D7C8BD323779D9BB23CE678B3A5AAD2B6836F65C0F79E32D08006C72EB2431FF9797E7630F27B89635F08FC92203012EAF6B009A32437ED076D66E4CC6074B1CCD0D2176FBE508E43EDDA9185A91E2AFBD235EA8944B711B8C7D0A4132351FCAB1ABC338C3419C9993FD56FC3C89A08B0D8F28914FBB4840A7D02F209D1EFD208A8E47902E11C1FA92CBA1851FF0935D3EFA705FF4BA44A6D4A675BD979947CE8FAEC565B3BAA9D441AF91F429D42C3E3F683E0202C61318344C7865957131A1F9EB822999F137C0A930744CDC698B3D41226A32268C968F576AFB37D8BB4E533B077124626535AC470D649A817F42243CB7CC73F0837A6527C2890ABE5BB762174ECCEF9B2F9A3FC77866ED031947CE54EFB0DB647BC9AB219B974E0C42A53FF6C65C1A67924C1B0415C9B9CDE4887023FDA6DF9A2F3BBD7BE5FC23EDCB6CBF5CE5C0D6B75C2048F05C5AAD82C87F5D0E9A146C3CDF01A973E85ABB5DBF4B3834BCF7EC7FCA3636EA417B92E7838DE1A8527292FEC5183F21EED1485B4AEE3541C00E36E6D3AB5563F3DA1DB962B94FE6121D36273D2813E785E491BDCFC825B0E98539B7364BB73885EDDE73CBC41B7F680BB00D9EB3047956996B97A6994FDE741AF9D0B302E99D3573117B4B537B1A3C384589FBC24156141473FCDE30DBDD305A6E8FAFCECB98800348A5DC2940A8D5CF2005CEF09F49B5FD5B415BD63222BF23DBA151A0E1925FA6DF135075E02D5A7E734AF9B92E947191E7221F1122387DD17EC8A4D3582949B58C4EE75A0A83115D936F59653592A5F86FC2B7C277DE26526AB23AE4674417C9C9388B0338F81FEAA741C446CBCCAB5755F07A195325E708256AF861913F50AC03FF02DF181E414E185DD7CBA0714FBDA807D67C938CA36AD52BE1DA9CD4FEE14BF1961CC1C20D3268C5563BD5BCC10DCC0FA42F01B8E278D3B2F549D6A1B497C8DA54995D395CA6E761D3B776C1D012B1F9B39DD73CD831F6193847930AA15A4C3B139464E3F89AF3B1C583E4E986B80C4BF117DEDC1C09390560365754F402C35B06DE3DC45ADA558ABC7EB3A63580FD8C9F29D335A8D9797D1420D4E3EC0267078F68361B65DE8F6D153F38FFE6304F0B886E94AC959E71EF2AA546DEE0E00E39A3E8DB5869C4434E862E60AF5883DC6E905469ABE8A9DCFF2BC85D14F9CD6470F8B092DD622FDEE25678887B97B021013BDFC8CA38702A7F49BFE92A3BFFB8DAC66D888A070613BD09A6B2D6C2CBC9E61DF92BB128E8C87E241E83BDDBB294AA56A5B6E70742F6EFC321CBF8717DBB5EC7529E34B21C8A73CE9EE0B7D6A62C96137A19D4836D53BC4EB8C1551404CA5804C1CE2350EC41C117DEE4152B65F9BD050E5BDD4A8EC392624EB27927D21C6F3CCA0170EA9C74534C28EF5BB45FAA789A46C703A723A82EF4297F907A20FB4B91694D5598BFDF986E517D251A401D035C5995EF8CCE18BBCAA3C4320F0F90938F7D5D9B04E187BC72B7DF045AA554544368DD90F726115A48E3BE841086889FA99ED5ABCA67683D090A8F3002C164C7C431539C1C8FFA7B871F40B0F42237810E3F603C63DD59737AA7275862DFE9046D22D59754D3668826A410EDDAEDF804E16B8E6D01D7705F611123C3F6A3822479430AB3A10F79FE2295558B60DF5A7CB1F02ACF8EE05F74A38E025C1A6FE1C02EE50C2B5ACE98528523F5C16C620D78DBDD54B0D66BB1C2E832876C304D794DC28D1501840A94FE7ECB2A62C9B68EFCD6D60E9F12E79E6793424B66F1CDF7C16B0F39D03DC0A178F850B1BDDACB3629B456F6647D0B9AD45E0A635420C1E1081D0E99D8B5E912F295DFDD262100D5E95B030CDA6BE784F6D38ABC0AB5032B0D42C85ACF782D382BD0711A7B43CB7682E908D3E36132145A1FAEB6670B26A30917682E4BBBAAC884A7306192257E9ED98A771F707A1E14AEC44DB71359E49FE15529376DF4BE36A0D00241DFD320E93C8BD8BB651132C4917229A7E5284F83408E2FAC8588E3662F4AF09D4E3A8F97CC55B507A2374754B15B086175FB593B007ECD560F7AB9E7D6611D816FE58CBFD083D144E5D0BB7C4D76A510F56C7B3170ED5A4AF94D3042073F3720A8BD2DBE40A90AEC4765371C7F27036C75B3A05E08D3A0EA4EEE0C583196952636745A9556776489A46B7FE6884EC255032CA37CA59E33399206BDA71ECCDF7E901F57F7F11732FC86CD6F6BB761F612DCE82455C80382834A2F660D38CFEC1F63DE2AF8B1779394E23747980B3D4AE572409E03AEAB7A80FD951CFD64BFC061E4FABCB4BED38F1AB19C819A797E8C378010A56C3E7CE889DB8DCC832A637B4D1E04C2EEE52E2BBE8A64FE47EC9F3ACBB73D8AAF2DF8F14D67F92D2C80373D2180788FBEC28190CC824D90DD5DE2F4A95E0CD172C1D1D33D2E24B48A0611C908812BD1411DF363F40F317731DF586F7A156418F5EAD8C06E116F28B4D0A1D1E047FA249ED4CC653AFA03DF4631C80D529F886D1393C0E763C325FC3B1DB7DE834DC7A3775C5E0A8393256D9DF355D7B173BA5C0FA8C0807F8615E3EE5A5330F7CF408848188A46AA98BD6BBF5B6925667983D4354461B43E0E5A09FACEE9E285F2872F972F7121957C5A818BF45B7B4D8A83DBA07DB5D16F96B51A46B771213FE8810D53B1EE68EA8A2EF1870DAA7E9CB8570FA04DF817AD58EC6556929AE490B09463B663D899C0F01C5A30E31991812F60A686877C254084FA73C4E28D8267E43FC873BAC32A2EEF54CA235D2089C7BD98D90099EE3512B629BC63A69EAB96D2F60EA01D293DFFC6FC355A726B0EB91D66358834B1DFCDCF5738F929226A63BC8F861740D844E47E2D3B731D03A902F7627C0F287F1863CA4E29773E966C9BDE3D6EB2C83F1FEA43227BD9B556B9773378F3D5CBF571EB6877A334C438C8071B9CA6B8F2AD85E66CCA1312826FC0428FA80AF251D13E3BE157DE900203A2B2F09CD22ED5CB33A71A10154828784BC0D9093B731096BCB14FDD8A59C06BA7BBB6F46285EB75BE0F7E5143E16FDB3B0309303392E62E536299C825293E5764040833BCD0DBE3FF00122F56C1C2364B798293B9CBE3000000000000000000000000000000000000050A0F171D25""") + ), + new SigVerTestCase( + TestUtils.hexDecode(""" +6C9E7A1EE36625760E5D2F33DF2929DA56203234069160E5F2BF039C11062273073C237566CE055D871F38ACD1A9859A824467F19BE68E4F00645D225C42C85A557D2C5ECB442B0F028A6528898EE2B673D863F32EB9EC8164127541F32519BB88E034A03F46F7D193CD3DFBADF63557926C5C8F5B766A7FC5EC8B3F948BF7A821B54C9441AB0BD833FD6354CEC706FAA500ABB5289B90B1BF917677A29D115F0094BDB48DC72E261DBA120BA6FF5E52A01B178981DD8296444656D9442DF9CBB6BFDAE56A230F6F29F94CDCC265576AA8752ACED07E99895CAEF0168BF83D23FDADFBB928CBCDABA25FE2CD26ADDFB0DACD74940F351426942F176FFBC5F3456DB7C912AA16B86D0745F87C9F45370A8456A1ADB51DB4052B5C9EAF60AD7B80A42EA4BF92C841273AD761DEDB0D34BF579600B149FCCD42AB1549BA0ABEDA57EF71D1FCA5702AAD083299BB98300189C25F3B270A87658D0B2EA56524147F739EB6C676D7BE73DD3B95B10C55AB46FD01549C5168BF7DA13A499785F35A1E3B56F4C567F54EA9AA2817A336383643FA2EA31FB1B73E10248DFCA05C04131266498E1C9491135A50E63D02FADF4165FC9E15E3E1B32FAB8337684C49193E1BC4EDEAE373A267A714AC1F909CC657CD8066646327E0EEA041AC9F2AEFFC80691BF60D3C94C642557E4299D395922216C65E75B7E1A5028960384BF816C9F7054829E7985B5841A733F33FCE2455EFC89BAE84B47990E8D0AFC6193E4AF9BC680AE24FE591E88BA6A2AE12DA3858D21F492D24ABC4FE4FD52D5ABF24BD254687B918792F0A003A5222DF45038685C725CE7579E02CB168BBC666ABF669856E10537C9291692C0CB0CFA906270AC2C7B7DC31D4F9283CB2DB8A462AEC0B9807BBF4AB4576FEC6226B4179322B67AEA53BDDF9C9BE5E0DBC43F78743068AB5BE49F0E62F8E2EB1B6C6736C05C9413D065CE0CCB790548041D7E832881A839B5729AF94AB79FD8A16DFFF78CAAA141D97CC0650F86262F26159BE8B361A4A041E9A0B6511BBE3355A4BF57AC09848847EE0243C3BA774776F7E9A227275D74E6E3101D382818763ED1E1353AB9EECCD920CD28922D559A4048F40F062164CB661C4F4AFA81A3D55933C4791EDDAA3939E5AC342B0AD1F438A532C6CE786681A870D94EC88A334CCEFC6ACE7D988A1A82BC0ACCE785F123BE23A7C92AF108E5ED4F0869E22DAE273556D1DE386623A6C3F115BBD119271D3FBA796F618B53959FB98012E7D5B9AC688940B87E2C9C065524A00D3A4F4DBF52F4B1A63EF5C46193BADF7AD7F988D4464345B2C3E549684F2F905F6F89DD641473EC05108A52D8DBB91768C541DE520B17666970AAEB506E75D8EE9F4B4455B71E0088AB25655213B75859D25F559D3C324D283D397ABE6F0AAA386815768D03357D775964902413153E3560CCEF1FD44B65FF1B287A92A9693F034B7EE668934702D7501CAF6DA4EE98AF4E8E64B0340E0BB8BDC533B0EFEE1915A4B68B93C5E95321EEDC234AEFE71AE2E5DACEC2F52F83723A2392A7F8E13BC0301CD104D852E62A7F828AD329B3D9596C58E13FCC0ED96C1C48D82A2C0F4D9D24DD8421FDCCEFD497A9B05FFC50904770401373FEE7DC73773418AEB4A1F599A4BB38EDE8D10A3CC83A1C72DE921969E3CE3E8EF2F7DA89D344C80D61CF9C5A423B1A4F3567D96DB2DA3DB9B5B5FA68156BE7452C8A0181BB9F0DC75CD9750883D0DDAE53FC156D67A74200869046B41DF4BC4396993C08AA4897A0BDDEFB55F69CC1C4D7B5FB150408427B416F73183F2B3CC16E3B7DA63CEE1143ADA1A056626A077B6D21C3DD974ED907C5A094019225737EFB93319AD3B40A4F434AE49D28391C17A999C744A68C55A91B862729583D3DA46EE70C5CC461694167D32D21DE75327732C63BBFBD7B30DBF2057A0D681519F6E4AF608D4BCD0B4750726770E156AEDE85417BD759D5FFE401CB2996F34434DB428D9A417037201FCD260FAA98084502EED5C27A8916E44F5929819D21A69CE16BCDC3CC8141E285EF897B1402C15C952590119051E369A1B7BE443FEAE6E32BC8F3D647FC5315A5200CD5238DC6677466EA86EF8D18E5A79F262483E896B8277C741F516FC040C1090F2495BF1650B02AF30456733A071AF47D7A15BD8E32A49806455D3BEA74AEF5D00906AD2F0C045354EFDE7C9A276E73D9EDD11D1CA5C297B9A6851E7F67E21EB061BB55D9E673C4A75FEB84D52629EECC53C24BEA95153051AC206C87DF55410CA1FE6CFC3F403A6D9D43EA84C60C945E642B2836338B5AF9F69E52708B2E225933DB320BB3F790D397F22D7B6F8A433CDACE9810AA0E27C699555530C562DBF7517A4162628BF10D1B6DBACEF5C9ED51E55D9A89D60E0FC378C47A21D5E0F2DC3BCEF5E05C6E0261530FB027E5032558CA2B47005BDDE99909930391EAD7F3F0A96B3DEDA54A11145F530E51DEF892E5AB0204D614E6E38AFE79CA92C28158D570120353B7A4DE0889846D835294939557ED0AEDA270D4D73ED84D3D49F9F032D43457BF59BB7D66359DC53F9B46963B21784B06CBCF04BEC1E33A33371532716C9EDB3FBEDB81999B4372D0945C10AE826C60FFE93170B6D294B3891B0D2A7B35B28A8971845DC2FECE237B80F20B379CC4D136DAB3FBB3792C63EC61F5C755BC9DB35086FBF46D2B7970DCA2A8523FDB4C7A0B8E42F8AF9ACAD2A0EFC113602A4EA62E4EBB7D269C3A40BA2C44EDD2956"""), + TestUtils.hexDecode(""" +C4F59FA2DE30C8420A7E7F096BAF6AD69B1C15A5C6E61C9D82AFCFDB6EB8F275BF5787186AAE781F487F9F88758C9C61F35D5083EE70424B0D0A51575010C2A907F49608115D33EBA0031509322AA7D3061FEC3162F96A565F98769E9A19235D89D1B21D60A381DF8EB37D58C6A2E483A8EB70736E4B7BB911F7AB923DC29F1E"""), + TestUtils.hexDecode(""" +E895DB64C57BC3C2A97F0EC933410E98F6216103E3423CAF06A671964C514A694EB6F65CBD1137CCCF8881FA403C5FA0E0B2F36B9F4009C378210D29E54A7A5A9B793197CD6D2F38D7E1F3ACA69D48881389381C89FA676DE426D634F9A157055F17283ECE8248CAF14DCF11E2D56355B047DF632A18482E79CB2D5A743966BAA8A76121BB69C2E68155ACCB0A31DA6EDC73CB09A9E660FEB20F66C7BD967ADE32149C5552EAEB2EA175B56233F3B370EDD8679269CE0D2B43F6B2F65FE957E7AB37B982043754EAC8A30B36C10004EF13C692E219AA7AF0A4C5286910C7100DA41E17BBEF2DA2AB03ADF3074BA1DA15BCC84805B89B9DA88E9B400AFB7E3BC8338D354DA953AC0BAD822756CA92E5DD9507F42BFEFCCB32B4B91A2BE5EF34C2CF1177EAAFB250AC9ADEC4BE71807589F1003227F9B76B74E07BA67AC60819B2AF766A47FFFC7B76D3A7C077F5EC69AEEA3E963859B82C2ADE58BEC2152EC8205110975D37C6505E0DC776FDE071097E93013D1004F4E1A2FD79B877ED5025F527F3BFF137F041BB9BD001E949F08B4CF88DFD32FC7CDBCECCFDB0FA2DE7823E110BCFF58A412CEA2795753E9C89678C3AE24268F7489F72974B6955EDD04E190D99BB0D7A252FAD5BBA606C1A1F3ACA733BFAE3309EA0A6EB7D07E36D8CA336D2644FCE1A41895D014D1A60CB106F3F8075F9378461738D63D115D00B024C677801050A1B0B50DE057F85DB6AEB2C9D6BB7402A66E3AB4DB05C58BBDA12F695958B8AC7B4E45EC6C952F679C1EEBDF860E348982779AA6988EFC2AD1DC1EAE22A27A5B2C61C97B3B2493CB6C13C5F6E20A67B88D3C3ACCFAF0A425742DF240634D1EE593828FE6297446C076F979055988AB834B2BD82E14DC086400E1C956CC0C30CE7BFD962223D23FE9494964A811B93E8D7B8F34C89AAD45DD4113F2AE7BD94B53FC86E8B2AE82E51EC6F3EA4C30D60B86072748612D1607056B5FF6A4500EEE78A5A639C7B74169777626864DD9EAEF0E3AD8493D831F71DEA95BBFCF81423A266DE56F3A8FE8E6C3C0D612FB62BD642188CA71CB89834F30BCC28BD178845F1F6F46C03D306F7ED4E68759427AEC2701198C3C05D385DFAFD528CCE8425BC551469A0ED681BEE4D12A843E333B5A8E0517FC61906F9C4E7809BAED4D3D16EB22F1FA9AB402D988ED59F9FED0455E9260FD627A24A17FE7CB63E530B48F5FB6687A2E8C49DA79FBD69A3400056665DD11D19A2BC4DB1D374AB6A6E42472A27AC6B98F676E8EDAADD514F6D44DEECDAB5A6DFA0F84F139A803A2524BF335DC52EA58FA50D98FB5CD55D5D50A663CF647EEE56FE8E664B3BCAF9E333978A7946973FD113E4FD3924E6C09E60386444214DFA7A4D671FC23890637EB859134D79E265C59CA3ECCDDFA018223C9BAE1CCA103962078BC5F0DD02246FA28324F7CB2FCFAD07C25B4BC2D888069B0CF5F23C761C0E47109881CD31456A64B940B4BB9B4C2C3B8E6BA834AAAE69FDFC47D44B3C96887ABED36015E7B64E8542928F277CBD2D3C512C24DEEFE590E81C684E063E7AADCF117B48943DB771FC2207F57A745357555D419C9CDCA35CC1A7100A6913A3B6AACF796FE3F94DD2F818982716CE0316542A1B957E12DA43E231542CC14FCC66D728A68326B2BC311248330F3E98F81EA38CA924A8E4DA97CF673842C759F935BE88163CE97FE4D9457176F5B8908AF948F74D5D1DDBC521825D931C63CA8A8E12242626305AB6A2E0624564EE041983C18C2952EC3D9D159BDE3985CF77897EE2DC888112721D4854E914A5397E08B54F4A54323FF820821BE026EA091ECA6B7D80D91E3DCA2EF7848B86FCA6BB40CE48271E1008368E3EBB5E395E1CCD0D178F1A6257D26B6BA4B7CE532CAA1E76CE28FA4CF9E029E2482B94D3ACF97A326D235D1BDC89F70002198451D9F1F12CCD5BCAECDDE9E14AC80742EB31E6464C83210A39F35098BE0378D074CE1CCD1EBC1C7770F778D605F2BE59DB7EA07D80CCDF55F16E985B142FB7BDA07AA7DCA5B201E1950CF9A728F21E9A9D8AC4D1327E3BC0FF339A250522F631DF2E75955154893E4A1AAF9866FEE1637EE1AA5106D244E99E6F31FC5601BB7B79BAD82860B1D6059D9B132E026418020DB06EB8391FA15B7A0F29E36D966ABD3D2A2FF3F2AAC34C8B45C7D2355EDBB80B224BC106EBC6750E55070F85A7CB6003394E5161AE26F5ABF83F0DCCCF69B86139AF8694FE1DC00781EAE09CDB421814878043DC9B0530E5545A165E39A9B7DE88B4AD2AEB90D3C329412ED2FE1D97B732C8439DF4F83D228835B538DC278FF0A2DC42F41B00CE3ACA06B05C4839B896931515D78EA3673A378279F4E89CE08E3453FF2FB453BE031C6318628A731D029FC7BEA2BA5EAC4916278B938A6A6ACEF5BFE2158F2AF43D8E56A0649DF28A250D2F2536ABDE1E008EB631F4BD0EB55573A40539A6004181A9D2BF7A1E53504F11E014840733844131AC668946E5B827289AB6B21366C5D0E2649219B92C4760DFB705F7F61A96564C9E840D14B0BB0DA82DA50F8B8E752BBFEA3B0A337BE124F72D8F8249195BC19C3E0B62EAE496D38CF7500B4F10665FC2D28B9EA935F7E316472F4FF401267541BDB62301554B2009928C6445BBD0EF21D09972F35081ABA9091A6C23FED29F5CF9E0779F7EFBAD88E62A454442B30079BE0AC9C64826B98C1E1001CB0FB0F0A95F7965FE9312BFDAEC33F95065C8E59D3950F80ADC7FB334F202D3E5F8DA481C9B54A75983930FD1E5ACD16284F07193FBCB50D0DC00EFF8203144C11EC61420FC32D7982CE896406BE769A75DD8D3CAC753ABE5A278655BF54BE33A1B8374EBEEFF212C39CE514668F1C456EAA2532828C84293F1A5BC9EB5DEDF558A9B4C1239F77272C67E1AB28E1EFEC5893E09C10662B53C8B8255B1C8DC8F8E5120A25C75EEFE79C43F7A8B37DF9D1E4F32486933DA1CB0664C5DB39E21BC227B0CDFE7A5507F07F218A7A47DEBCD9DAD7247B4D045A13AD4F75EAD2D45C339D0DF04577F2E0FDC780392553033C738852B1BE4E63EA3897D6C9C4B11AD6B58D3E2D342D32840F649DD83E759866B7381A84C8ADDDF413FAE18E6431B1EEA73A56CD889B76BC9786BEDEDCA2541E4C9B24E28F58AD374C1D93DF2D3F2C37EC594A0498C574579A7332F72C0F9750877FAD5B90B968D88F11682C4071E4EA38B816AEAD6BE54D2F371324F2475B862C75424ECF9858AA4E200CFBA412D7E3E6C308D8DE11DD185331AF9D41AFE8879965D6746EF21FD98D3ED3806FB5C4619C98E347D76B8B89849395561EE286DFDFC6A04E1D47E9F5B5B49257784C39364DFA88AD630DFA59CCA3237F4A2B141A813D22C6FFE73C2D99ADC824D93E06A54B6DE62C3125D94B49E950DEC361F961F56D3671C9925377F6E670665322B8489E833D3830ECCDD0F53F4A4F9D68F1445F3AED5C9D766409B59BAE7A72912E98B3BB57342D29B6ACFD14336B7B8B6B7549AF8CC8845E10C2811287281985D5D47685FC589F2678ED893F57B85ACED75632E50DE5E074E6CEDCF1AD499BCE67A7F498564DEEC677C708388DE8FD7B099CFC116096C45FE28890B5EAF06169939FDA35E1215F238E8CDEDFE670065F5DE3272A232FD53C250F5D779B31694FBA91B554803676E4DEA288463FE1063009E9CB76C317DB400ACF4D2D2B6D16EDEBA4108913F60AEB252CDE413690CEEFDCFA638963DBD04F4CF21AD74DDE65F0F1E7CE70AF101A6DE9A59DB21D38027DBBF76167827950B69418266AFA444C728DE3624A1C81E5B1641DBE879CD822FB2303CC3A9FCEEFE3DDF7DBD0B7057248A28D6062D76EB13B92C9C9D003B69E1842A54C09CF6B484520815E2BB237288C64FC696FD3BC45DB30CB86465DF1188BF47956E5B916A8009715CC9A9A6DCE44C54F928816B41D018C5FE652FFE4E33F352D383A9C1365F02ABFD647BD6B42AD163730F8BFDA1E2BE5F614D79597825BA09F457D3CBE7561E7E89EAF059E977D1EE88848B781F21F723890FF1F9873928412C8F11EEDD2C0C39C9512790986A19E17B2B70A4D7CF49D9D18CAA0C2023134CACD169200D8817FA321F04ACC910613DFF250EB325DBEF29EB5611B2AD2A23EDD538049B3F43EFEB4D60983792B4BF05567944AADB7AC4D3A5D80A1B9D8448B4C0C115C3B5AD3885353F47D5FCB9B7D6446F1A7210BBC667FC411415F23CD40A2A3D64061D71C67191571A97D01088A24B6711567FC89106732D8892FF985B8E6CF70163829CC085BE4E408315361BB1B2003D6413220B134506D3C304C0BBBA9C9C45D3651E0571B6B115177213D8595E143DB90BD72F7EB974D8D0A0317409D64D5837EAEC9B8D44DD7ECFF6CDA9F729382A43B379CBDD43FFB18AEA35C1A996CEF1488D3B7A81EE7CFC0B9623418AB3919A6EDDB99F222F0DDDB2F32A20C8F84FBF4C49B4CB3EB50D9C4CD25A6F7175467066D25E6437B67F2DBC70C2E6EB0BDE2386D03014A789FB6DC08EE33C0C67951DA9D74B9C94845D2A99037E095FEF7919920FE526EB5DD0BA1F97DFBD2DDC31609C1B7B45EC3ADB586FE3030A0C7A9DD034A3C2E6F9849093CEE10A181953547F8BE328720A4A5A8290B5EE00000000000000000000000000000000000000000000060B10181A21""") + ) + }; + + static KeyGenTestCase[] KeyGenTestCases87 = new KeyGenTestCase[] { + new KeyGenTestCase( + TestUtils.hexDecode(""" +38359FBCD79582CFFE609E137EE2EFE8A8DBCBAD18BA92BB433AB4F09B49299D""") + ), + new KeyGenTestCase( + TestUtils.hexDecode(""" +29B4987C62218C19C77D695EB904AFFAA1BFEF6A52F138604CDAB1534E66DC10""") + ), + new KeyGenTestCase( + TestUtils.hexDecode(""" +9B54B9C91E0201251489E07D1442A42D0BF32189D0C0CA8A2D4871DB25F531FF""") + ), + new KeyGenTestCase( + TestUtils.hexDecode(""" +A5B67695D7DBBD6A7B25146E30DC3F577240AED2E4E20158D1E24143698D1178""") + ), + new KeyGenTestCase( + TestUtils.hexDecode(""" +1B87631F6ECC4BC8FFD14B2792F3D1691A46C22A26BBC98DEB2554D7FD2522AB""") + ), + new KeyGenTestCase( + TestUtils.hexDecode(""" +5C3E3EF0278EA9197F30C4DD9C4C06425C05401253E77DFB3E1D5315CB00915B""") + ), + new KeyGenTestCase( + TestUtils.hexDecode(""" +E3B2350AF8A1817D936FB7435C4C0CC758F79FF4696C46E4642670C5A78B30EE""") + ), + new KeyGenTestCase( + TestUtils.hexDecode(""" +75E70362235CC7CC4A08053BD887CDCC4E3D88F77E1C7DACAC972A9AF83C0CB2""") + ), + new KeyGenTestCase( + TestUtils.hexDecode(""" +45CCECBAFEAC42F2D9166A879175A6D6263C3F7F9B5F39F27A1578C859CECF89""") + ), + new KeyGenTestCase( + TestUtils.hexDecode(""" +4A74BED90EF52CF135555B622A50D1A4F5C53D97D3176A1B184CE55380DE6FDA""") + ) + }; + + static SigGenTestCase[] SigGenTestCases87 = new SigGenTestCase[] { + new SigGenTestCase( + TestUtils.hexDecode(""" +13FAAC5CAA1C92AF31DE6C25B147014BD7FE589A649FA0089AF0D606E4B869EC1E4519E3AEB57924B329B085EE7C80501241FEE198F3F41A94AEED9BFFCFC9F7250182F2FB7F56C145635D81FD4981B541AAF62A572520FE29FCC0AD050545BCD377EDA950D1DF476FD2B85C8C9E749807ECA53A51D6D0F4F42A339AA7C48181C83851A0A830D080651C3741E1A805D4324624272D21366D403652024250188488CA24804C842892360462109258844503326E13390E02928CA038044C348A52A46054082DCC329204822D5C9869E2246918914462A86560080A0C372010B9890CB92D63126D13986C21B02D20C52560340918C641A20872048684824026DCC26418165219223158928940A8408A3646491061E396690A2690CC042D41302119C06510872141400C83120D831205109905A42844DA06201AA30502150C04282521A430E03601CB804C1AA2618AB621610410649450E3C630C4226880343210C09021944589248118C7458B904402126250B400E2866800A2041BA68558080ECB228E59803192847159262A04216D13A00C0C452D518845834402C42846199345630069E2060E084528CB1271239484E2386E93446D1CA26D21C60561B228DC1406D19870DA9211CAB48DE1A20503376262B6014A284259948D80225010108C18354D13982912474DD3B8209A40120A398A88026A8B2280D99460E0A80491246D5B060D02012D13272D04154240860520948D9182215890688084115C0248C12012D0B68DE438666306258A884C9B0801DC087083445222404109252AC988851AB7491B899114244A8A043103408ADB3680593488410690DC084AA04830C9441198142E1B038124B06464209223B484A49631CB82648A9669A1C230C9A484A18420D9226A99A26513C168234404CB224940926C61066E83C8418332254AB48002067102007213A57123842908326E54828101920D83344A5020251B84718A182C64B064E31049E4C090243592A196308CB89109C3109336812399415402101C196153A68000022C8B10011018914318705AC20C1801665B341109836811B78998C6618C40910A430683204421284E41368C94202ADAA66541141213B9605B442901102499904C41342E24C28DC9082E11382E00018A9334455810009090316348610C2860D4262981280DDA10519C140C1B2308D29208C8464E10322E44A848633490810022501845DA420E24097162A04908194453C06144482622C42188320A01C00952046A1B25511BB185243809C2A86C603689608684448065D1226223C98DE400468CA0504800804A283044084A220640D800724A0062810425E2A22804C04C0A408E891089E0868DC2B4850C274843167291220C498061640488D1B605121721D1C231D4C2811B8271A4422A414212D9982589069110220C99886002B7219A1262D2C0219BC28412496A4B089022824011106603A749C1448063A65160380D84460CA4A28C9B162A09A388522426C3A25119A6802410860BB3888BC66C20A028D2A664A416721B05119CA42113932C1C86491CA30953380C92A67020C7244216280492714332221440406492514C448C8AB40188308611346560100CD0302D24B460A03870A0968920842924A88D58002010286EE1204C14286DD3402DDB38251C1381E4B465CBA645E082015A022CA01612C3322A14A36480124A01042A0895250C8440809051A1282524B86D08318AE0220E210692DB966C83124ADCA0692127065B1828C1882D133209434411C9462049C48481146C18956948C4480C492603080D18942000130901436118A60120474819111018A50023019022882818054213069191062509480E11456E8A00449914010020122092480B8320E4321210B429C290512139049BC411129890DA14661245048322049B442A942291C9A845CC408203C77181429223B670D924218BB08422392C4B2860A012905A807113462992C068CBB68D1C8064840482D9B82152202A1B0565018545D4462DC8B620D3404003C42051380AE3228541086C04C62C8B20051B091008A420E0906851B685083825E4428C504866CC98281B1171D2208E4C324E13424E02044984B20513B9059AC86500472E9220710A300CC13620DB8808803840188810A1A84D043582E404320B048061345208C5201B92401032121C426A231904949090CB9810B0D16BC03B32C91F22E9DC32FD1369B126053CEB625567AEBEA42D32F861AE27857C24814177623EE402427442714970674EA84BD573741F3ED9C297758E0666F718D5E61117BF138734FB56E3348CA54F05492294F52FC90C243BD836DE2D5B9797A189C7D38E6E35AD95E1533A32B5B589AB56941904BDE66124FA6CDFAB90C80A05A4EE8E50A5DE061DA6E11D3B40F218664631444651497AC3AC3E9A9114C9BA1E92D2FCEEEC9168E27296AF943472C8B4E251F753EF79F80948F2ED5BF690E0C0A074E8E0E4503410E8FAC6D8B022BCE3FAAD1C29681FE2223125F43FCE56DE461BA8264DC83CA1E690BA638E49052D0D05EC5176D12458159F2FABCA6556F15914598E014A4582C678C0F6ADD2F2AEAA330E816B0AC0BD5457948FA49FC4C954020070451143D8B4B4602BF9616BBD1D9F76B0EDD63F186BACCA0C0F861822E6AB56F771C6742106314D54EA9D0F1BDE66F4A504C6902D86B815F46F47E6D69A9DC16F290A8A9EFB06695670196D17E096543CFBB6927E25191B9538BDF5858B54EE4F69D35CFD511FAA422B6955F0EA87EBE5506DB4E7871C7FC5A2F974C736FF12AD545CE507AF4E430270E47EAD8663361CEFC3FFA2E3CD85982ADF648DE6F899056672D6CDC6841B1F2668CCEE9CC630AE9A91CEE7648AAABAFB09E4AC7ED0D7ED8165D851627A01919AF56FAD39CDFE838B5CF60E8FF5A2A7C91EE43F1AA3F81CC853B178E3481C32C2D6FD40B0EC924CC1887FC6DA4039FA0BA82D0A57472C9D6003BB3D819A0533D3FDBDE2CB06BE052AD7E56B92B431652D6D5991BBA6B564C15C1BAE95360A07DD76F0ECE8532376D0B71EB865933D3520EE7B3B35B7656ED684FBE914D01502EC4BD7FF39FADF06F6BB002B882213C4D42E6CA651BEEBA228BA93D825D618084917ABD3130C31B3B935A253D8D28BD45C5FAC4B05A42BD815B9CBFB6198DA4FAAB4DA6E9E95194E8084D66CD6B52BE2DE2A86DFEB25C254F59C4CB168185E00074E9CBF060639CA6ADDB7DE514CAFD5D1D3C74777C11957416932E8745C2B01AB7DEBE2E20FBA37476C0626140FCA24D3EF4F53148C51CA78C935C6C89233A6D4C57C317A19712A8040C1C4D3AAD221C1D375DB372FE07250FC3C1BEA8ECBA24D781492425702F35CEDE709AB063EC0804E71B8669B87DAD1563606E89EE0DD2A0B11B8836F5A2D375AC4B7F85FC5F80268FE26121210A4E1CD24BE3FF9E6D92A5437BF9019002140A42C317906D61D862200117FF0F8B8EE8D4C289C3950D083B5E5670D4ED32DA5C691F20CB648DDB715977ED6AC69F64DF8D5C99B4177E8B98876E7A5D29ED0C0F972CAE6256528233E15B13C69AB592C3AA260C77BA41BC608A57CAAE46AD240DDD5C2232E2297ECC90CE628DE5B83A551B06BB68FFCB152785B5AA6D1702DEAA8E92F704B0D31498692C537249D71DC6B1247948CC07413726DFAA43F53058807B77C4C73874EAA526EFDDFDD9116C98B0E2C5B7CAF9A25278761E2EC3B34B766877319243E138DFE6A3A03038D357516D9BF64955EB8B0A4975E026D0915BCB8637C769530458F242F65A68DCC78157CB30C4632938AC32781259BAA48F11B3949616E06C4D4E63F15B96E203D4B4A8110307D5CB3552810B9E1F3F4DA4209CF1BA98359F40E7055C7538ADD0AFB326E5F865B3F69E3D6C9F9F18358C0F6A47777B455B8CCE6C514CEB2235A7B376EF92482E2E86F42331511FB94A9038FF41FCFACBF353F3A43F3A79997167306DDC94A6D0628FC346B06166EE9D857D4B0C63990259AF271CDD8479F4B08633139663A1155340109B5FDAE255D1E4E21539C07249AECFE8E6AAC44A772B39596946BC8080D84453DBABF1E62843D179C1C38F1AEA5CF15BEC4A61810299632A2F3B9422DA99CB13C852B1CC6933DD52EA336A5A09D7D9F568CEDEF14CE1AECA48D92996CDB2CDA36A3C8E95F62DEE742CFF293037273E51F77BC208D5B345331E72C26BDCD0F51C9711BD899EE82128F834BB0B2A3DE473358F47EB2F98FBCEB2624A5D2697B86C7559FF40D14744C93AA2DD6570CC799C4B5669ECA0463AB0B4E1228032DC19A42E4F6C64D9EFB26E1B4E622AC06FD0C47B5A39123FF8F1085E4EADF768FBE9D5E12CBC5F380DBB414775E2836AB19CDEB19A0F653E7CCA9DE567D18020D19D24364E03C762EB54701E1893FFECA6D23A2163AA5CA9FC2DB681DD6E8AE2F42985C2D7E477225AC2F9C5274A5584E0FD90579B32D2143B89F9AD9576DF10A8E82D91C4987AF05F3E720D8557093A1DEC1D2699C2305651CAA0FD621EB48190751D74478381A499A61732B917E84B749A0465408014D249DC7D5C247AC0BF404B4311A25A55B2EC1301350B76E3F953EA2E67C90F1D5B9FC29BAAD30D07946AE1C2976A4FD32BEF26A2E93818913B36B237BE40EB7A907595B27E7BC80039683B3D28323F53B5521D244E3C87798478A8F9ACB55EC09E97BC5220F955057A889E7003B9DE288ACD5594AE65777F36D6C73FF5A17C7A8FAF039F60BC9E3EC54284384429C62EBCABCAE2E78F5B58DC7132994DFB16602A54B444B9A9C0FBA6F7AC3E357308CE2570743B8D2B5DE5F9FEA05A46307623E579195D6B5C946C47C57A14D5A6177636025FA555F700BD61FAE9822ED336AB21DA9E67F9E81CD815F2EB79F25AB194E8AFC564C43CB4CD8D681CD8F1BE41D9376668E45EA7E707EFE2E58BAF0CBC091DD427009B0716B819B857FE9841EC48248AA49EBCFAE706E5F8FC65076E6E871D6958EB1C7A357019950146CA8AB3821317C289C744450C293D3DB4B3006EDD727B5BFE7541F6817CF5467AF94232BAFE06E5AFB845C0216491DCEC3D603B32EA59AE651739D0E26138408A5E37A6E0BEBEE2956269A722AC36D7A3D2732486EAE6F8100C9A278988554895424EC080E282EAC6401129F51148DA16ACD7BFF0C1CAD9516F189AE1D1F4EC79110B942C026C6995A0AF85445AB9DADB1B2FBCA7BFCAAFE884AB6BA0717D3D7BAEF75D9A4507FDBBBBDBEA858EA7975118B94AF78E250F494205715B0EBC31755A38C1AA944F0D80452AD54639B2701462B2D82E522F8752110F44BD381E23C1EA52C15BF9A7DDEC0AB0AFE725B5993A0351737C1DB72989F48FB41AC479C777FD2E7808FDA72790640F9F741D643CCD0C1ADFDE90B9ACC84345E0B0739768ED8265455AF008BC09970B18D52D188AC387CC1DB7E47EF83A0108D39F7057BBC02E611DC34F9DE364B7ED9664A9C5C9D691DEF8E8FDE6C61484A097CF8A937FA55F353D439C380357BBD108933B6CC49CC5C5042D6E5FDF8F85BE9E4315E094EE569C5E3F38CBBED68948FC95226CE06ACF6D0C88408F3AC265B6B10BE10EF0467E011A5EF8F10026C7C54F8466E9E574FBAFF13FE9988E783BDCCD4B02BE46EECD77443F4CFE8969BF3551F2829FF2C0F8630DCF7B088C5BF1FDEAE2E81143D1573854D0D6D6F70FBB5ECB7C6E60F91B241E5543BD4F316C66A7F3C91491320587DA5CAA6345FC0D2240530BFC19AF88B43773FBB4A6369F540486BF74E3DC4DCDC4CD265C7C0D37213037CCCC1FA81D21EB4081C254C4096E044EB6BE48D07CCE2F460718164AE3B68B7298BB1B267FCC0AC3D0365437ED45C742A3FDD746910C1610E6CFEA9A17225DF2B577E790EB870F5A2190ECC166EBA09C171BD825D5E8EFFB3703746817908D299426DE95D605B368AF04D27B01FF5CAB91515096DE2986A0C575D14CF4224AA9523B661128740F19DF8072C917483746547EA422F8A3B40CB67FA87A7989A13C49262089A80B1E4113BB1EB9B469275D8BD336DE344318EB3310B3ACF8201A6F5F613CE0F2290AF5A8B9DD9A5B64AC8BB94AB56C36157C8EC8DBA4125321F30F753D489FA42C4881A3450DB8720892A8D3F52431B960A2404A748220A7305109A2E80EAD78B8D5C1F79D265B00C771129A2117DAFF0D24BDCEC32D53DF76A56CA24B6CFA0775F67614186D7513528FCBF2F7CC47D60C52580BE1797A62C17778DEE9FDC0B6D32585BD35C86276B363915D3D2E5A4BF58AA483891025522B572F4B635CBE94FF014ED19A017EFE0088CA05C54BBB6953BFCCD8D6F867769CFB02280ADE6C39BEE714EBBE252AE5AD84027F8F9C2CFF3FD01ECA4F051591B7FD9164C3C64386D177A74E17181CDD3C55C98AE89CC2C1A26B88D6FBD16DFB76742B631DD8F8D78B308D606B486071C30E81C25AEB864A822402CDDE0CF27FAE8B6CA16500775AD44733FEC8F10AE6677114A330E59FD52747B992113C53EC9A09AAC1C3646FC3760CA6024BF39B7DA597F8902CD605599779509E3F8CD8B03AB66C1993AD4B3317949578351B74055C7BAED3D7555B315765F1065414F39A7848DBACEA596C51D10BB0081381F7D5601DCD07D719BB9CA9A294E092376F6D4CC32B26A9A8FB5297CBE32CF4356EA70225CB302693A6DBD36C816AAD475815E9543F7DC8064C34870A799C32A6BF76D472797F1DCF908FC994604407B59C824AA76BAB6334CDDFE8D0227A383B0CFA2158CBC79DEFA98BC93A38DC0A0420C99B920BBA64DA16819A78F8BAD42355EFB42B4BF17C68AF75F7428B687334746245F7C5145B5272B9C504A9A0A3A985A9738BB1B42FAEEBDCE7E7962CF0AC6EC80F77CC5C9733E49DD1552812957E1FE30C4129A702E23DDEC09FD"""), + TestUtils.hexDecode(""" +67D7F4FE3CC57FC8BE9A3D06BCA0FE4A39F39E3A6158D3E4ADA9CCBABEB542CA67CAC48167928336993C569AB5AE55BF95C8291AE1A1AB2B595C90C0FB19041435F3B411609412630D80DB0C832D413D69C8D3C3CA78BD1BDC24167AF590B67449DAC7F6ECBF87698BF3929FBC874F6FD68551B28E4EEEFDE9A0D0E7FE9E569F1F9893D39C17C3BA7A6211B875A7BCAD0C14194C30D60CDDAD640EAF7A02CC9DAC074779345B83F0D282899B2B9B61F8504BEACA3C02A76611C82F2007953D04FD3C54D7A00DF8F6DE554FD83D1EA5DC841645B706C9D900DEE7862D526245215AC6B9D178E60F9602F1931503864D97F582834DB797CAB60DCDBDAFA3FAE8726B525E8BB69B5E0763FC4ED17FE7CD9C9629273AD5B073B9516F6CD7EE729351C213FDD122E3C11DBC58FD2A501B267AA4AB21364BAA856823816E77B81B6061279FEDA6617247B86073E55B19973BC0E725F34ED4BAF0AFB95E436A9B2290A2B316C18CDC0D9F98F9F6F13C5A3FC767EC0A9A49BE1378E92BC9B3010B41AE52AF409AE0FE27CB816EB2614DA41C796D5F4FAC4A743FE34EF7C0B3A78E0E4A5B439659D4AC27B698550E89A1626FAADF71420F559DF2E808144707B5C02090F754C3BD4EFCEBAF6FA4493C5D48F895FE7674C81F069E1F00E455BF5C965BE2926BD19AF76E20533A6115F4BCF2CC5DD3A49E10A2B3FCC9EEBB2B6E4F25118599062F2AA6CC3A9D86167B1BD08DDB2C53A5E46E1BF4E8C1967866320BA66AB67CE581981F2003B812BA058B75924254EE3715BADB8E6B1B9E4F4AA9844D578CA2F0AD12E1C964685FBFFC87108711E022EA7F63330CA72AF86262838863780F4115138672643E6D9B48C782B8637E01D3D20CFD5C98A1B57720762037FFB12742B4EA8E89E4B32EE7DBFCD5C11E4A6E839A83398ABBC32BA39C6A25922649971D88A102D1019B560C96B820C44551E14509468196CEAFE3B7BC8F253ABFC59FFBC01A13008F77C91B19083A9E7BE733C1A5E558C64557389CA19249CAB77014D0569BAC7812862A610DC6EE074C844A055ADCAAD496F6976C932587BAD9D7E2080F8623C5ED8D9D4FB9EFBDDCC4CCC1284D22A2997824577A619905B0D6E451CAA3B2D30DAD9728FC7623F9ED71F80599D65D9F2AA285BAE393D05C15891472B2DD2ED5CA669785EC4D441F3308EB4BBDAE8FC449962EF9787C39A533847540965601D8BCB6B4299AA636589BFE371D3904E18BC9AAC9B3B6EB8B7E8F322C22A6E01E6B26244F9E39586F124AE4E504FBC9D860A61B20B4C127FD0C55EE810AB9803D810233E6126488A6E95F8ADBB3F8E06D113DE6A3E361209E0D36B326E042CE9D2698DEE469DA15464AFF82D5603434C07CCFC4D956A7D55FE79CC127AAD2A56B34EB10E8B85C3CD5163C4BB8C1083BCE5E5EF986AE028837809641A6AF2B8295B743DD9B03931E755673DBDEDE56F6294270532D685DAF1187137CD7D29248F21B290EB8317E3EB28B62E45E140F4AFC6D1438F81E9EBFC6FC0F1A4146AAD83AD1F0EE2952643E7B6872CB2823AB21A155C281ABCD19E20A52611C6FFAA724578A070935B1A0BFEFBF061101A81227187E14E96B016242DA269FC91253FD827A73743A4BC49FB63E2D830D0FF409AA1C73706D7C2297CBC552CED567DFED72CD15060A522F9B88EC910B03CD2794A9FC07A8FFC5CB97817DC769E64D8C474A305035A49D05B1C572363913A315932E391B62AF291DC203B9A40F04F40EBF26A4AE186056CEC45EB7D21D88CF50258DCB5EF40CB2ECF949B18C72626469978FBE0964C8A25E8C2D27149C2266748F2B06746E8C9E7E2F0977BBBFE3FBEC7353F583FD5F7C2B0139EA928AE1F67004706F6D4ED7BD8D13BC68E0F4A49877C0B2F692936BE5FF99544B2B19B23A97EA6B5F585ABC9E69E689EFE25E15804C650444C479E0DC63C9CA2AEC41A316039EC7F675F1FD7C0476707370CFAEC9C3418CCF30B5D85FE0E15056D6C015DA59F9BE9028D9C2D93434F99DD8C1BDB41FA1EB021BFD0FC12EF0D038CA32B0FE1449342D83CD6BAE43A8CC4077074FB1191A8887BF29238D27415D93880682017470A42872D6CFA729AA2B3F8B37038C83583E4C33256FB871A704527594596FE858777A93D3095767BCAD2FE295352C93D227E1766A59ECEB38FB7C2E3664D6DA0DD4C063975FAB3AB4B68D125AF16D233389D96A337DBC18DA11F37F430C1E49BF8AD30258601CAC9215F32771C6FC2B7BC03B55AE9664E0D719C3B40C3E4FA7DEFED8571CE8E46FDE8701975D94319DC5FFBE93B4FC4898E2EFEB3CCFFB3494AC50BBA364C22A3953F052F62E46D0C35692AF40D2FBF899A23C1A4721375F307E2FDE2E588830753F908FAD96EBD5FC360D742E2CB2C38A7E142C95376ACAE29DE8E1034207D1CBC1DBF2968677AECED152B1EC1AFC195F3320352953F2503227152444BAA74EE8F98F2B4512F7ABB43D7F87889CF1F8C12D9BAB91EFCA5AED21058E322CEB4E59DB4DDE13BE46FBDFB225F4AEDF7137B548503008002A36D7A3E98C0ED65ED9322D66FAD4A741125EA4ABBB26A2FDD7AD136590061E7BC0D5228555D1A59F8A6E4B97ABB61F4B1AD9564E84C000585DF8BB31AE61CD25C9D91D1A1FC21A69AD286CBC7E00F592DFC1C65E2BE755DDF041486F3B52C8F72ACA97A149FE0CE1378236D99EF099A668F6847659F7EF617B66192CA452ECE3010AAC18A65D8964381F561B48D044096DECC22736C902D7E23EFFD26245018D9D7EA9E2F907932A1EBB405BCFD29F7A397C71A5E08962ABEDA5203988A81F787B25EDE84A7D85DE92A2B19974EF7D0378877B82BD7CB28B67F45F7EE625CCD054B44B4CD51802B4FE2E219315CA9F4C24065F5578732DC671C3004D31830DB435C763143CA209D7DDF3F5EA42244E68429102F4D90297B7C987EEDFF0DFA7F31964B76432E1DE27FA38570F2BF64D5FA3F12DD9772618ED2B95F51AC90410350320E19084F1596F6B791AF1EFC24DBFA2B7E30015AB14FAF43B568C5149A1152A47D278B5F01786F242858C210D28812147646A1A3A7CD69996809B784BB2F0053CFE18446F060622FE3B9181AE9175D6CFD8033AA752296016E7BBF639842DD4073AB282FF50F94B9E116C63DDED805277D4FD7987F740EF8118946851A5336A9F6F6E2FE3ECABCC518B31E741AA79AB500D9C6DEFCC437569966EAB1D4BD6CFF8AD0E5698D15F1342ED46CB6DA986F0C4B2B427752C18ADC5070043FFEEBA98569E90C79A3D5E0434119A077A097D69DA6E9AD7E32C6E8875A893F6D69424DCF4C0D4EA12605E5E8A9853E4B58E5659FED6D724CBAF582A89A228F99BE89D88F55095D0627B40B29365863C57F82B9EA22FDE731D1A2D8A9037665213F2C410D4AADCE12CF888DD4AF53FF839E962F0F53BEC60F97133D131C2C8EB588AA7D25EC025B9E821DA8E8FD8E550EC5E4D5923BFDDBAC522D1FA64C503078618B52F452B57874285AFD3F6B182CA6C979734C94F040EBAEDFEB547683E98F4D13F12A252E8839317A827CD97A7C3D81962A25DF7D8C62B57812EAFEA9EEAAD7D6A9E755AE4CF3AF42CA2152F663C1BADA0E653EB165F6FB56D86212378C0B9BD5733D4C37178FFB58E7357487B98DEA35127AB58A804B13E61E6D3E385C96884EA91C744DF6CD44B3EFBEFC79ED19C406AA6ECE144A44F1E78B33046C33EB17E3BF61A17D849493D08F0FCF8232AF2922D96213647A47A05A9A08D28AADD3B3BF412F29063C9D78CDD3385BFA9F8BF06DCDA23FF79A5912D867EE1B0D526718EAFA6F0E231CE6C51959BDCD8D201838A50634F1C6BEBE2E4F5235FD01A6D27B90C58C12D8210692BF68FEA5B8A8651E64EFC1DFCE07EE670D473F29AFA63E080F7675F23E7D2866E5F2F9A525BB657E8BE5933FBED1E206C7BA9FF097EC95B91E14612E16F0F4082F70A1B01EB6219D47C716455F4C1C60948CF3228557E787A3186B4758AD35922AF28BDB328693BAED15487F7448D1796BB9DB5C931EFABB4BE436B2710EA280368A8E20C5782A7FE986417003236BE9CADC560B3D7C2CA92341536CF67D412E855B92D0229C45B1C518D8BFC82DFC9F413D3FB23D37EBD96AA0CD0B39EF88B23609AE0FC2BD16FA9E934329558759F05C8D4C8F3F8728335B659D3986E44508322E47121E592C9DBC6F49656B473EF7DA53FF8EF7BAE07D1BBC68EF4AC369D7F8BE60948F34444C0C443A100443EFC444E7FCF0BC4DB6A2C2C64662A538D1F68F4DB95B0B83DFD744ABCCBE5DA343621F0E182CB9E915B2097C186F1B98E7D8F297C347B60EC26D04B6D9C1FFC01EDB2551FB8D11D49E52956F69CDE0E49E2E7DCC8E7C8E78C41A9B2A01483BAB11733A0943A9B765A5811451C07A195D87060F157D114358E478FBA2F2B755A2A455E9831B77EA9D33FAEDC1C562E1CFBD8DE156FAEFF10AF655713E36FB508342D9B4A239D6DB786CF9F57E1C39AE65A7329E434AA88C68F82359E6F057873968F9FB63D898F24BC13C0F7748F92E404C6185CE24C98D4E4D8D4B3C129CB46C614E773A89EAD73CF0C30CD7E6C9F6435F7C83A4C3F877E034755EAFC5F30ECE03F6413F4C7DCCD01649B6ACA9C1C3AC3D112F216AB852A27DB3B846CAED86B76FB699AA7623548EADFE6D16AAF5A3ECCC298D5CAA7E84ADA0B75290FC6ACE736051924DAE8FC5BA6DC9AFEF65F369D054A4A18950E71901F4483A4BDDB2584DEDC31A04C5F8916DA2DE33B37078E5DAF3304344A8AC368A6668464FFD7898A18D10685BDE6D0097F95A3587717F6A3A8827B46653D56E461EF861D6908AB7D865B532DAB37E02A7A6A72A06F25572D83ED6DAA540FE56BFFB2BC9D104A74F135127ECE457991152DD0564BA955971E8C9767DDFAE190052A98A63C4C0DFBD1B51BF60643E4C5EBCA678CE5150F03A6EF09AB0B1C2A0D2C19C2B30A645C7DB9B56B5AACFB862837A38407070DA9C7DDA20B99CAC7B03D10C8F28D6B1C686FD26F9A8FDCEDA6B188D472BC593AD51EA62DCF73D32EED5444484853AD0EFCAA60DD42DD2C50F5AD15DEC7B71BF585581B9F9C68C7C94C154CC7E0D19ABC90508C8EB2DE93F0BE4295973C1F443A1B2419E20F3D5F883912BBD5CDEB938A4452FE0BF2361A9E3B2ADDFBF000DB07EA19B2735CDF0E8E5C7EC5CC7CCE1A9C3E869718272E54CD9875C21DCCBB06FEDE38A4E787D111DC6A253A4604B314FE47A9B6F6FEBA3F8F013A456DBB78B497C4CA7F90CC6145F47C96D266BE5507DEE27E968052CAC85EC87049CDC68D723D8CF89B0C91F67CDE2908C0C71808004A070CFA2EB6408F5FD6108749406FFD3D5DEB6FBEA00FEADDAC4CC0E22A9F6F50B9893CC4CAD028FBB73C1B7BD4292AEAEBEB668859BAD444D0C5FEDE3C469CF28C5C726B59E828C473C8787453BAA3AB2BFC29C691FCAC2CF496ADF3949CC42FB16F3677D456E614B1F88406E6C9DA7DB9937B00764D61C3D347C140FDDABDF8CE5E3E2D385C3FA6FD9F13F3BF8073B5D6AACD5294938DEF9C6ED414FDE4B3C5EC43865A7FB02787E50F94033CFE32A85BBE24B09FAA3B55B8BDDE60E325B691A350F2F128CF74FB5B6DFCD0E946AC7BCFB839B3765616DF35AF29F3AC82F4E2DF7D4AE87A016094719A07B5897105E2B08AE3D807960FED396CF38863E69662238541EE295C06B290404985444F4B28388DD942E51867216C734580B3F1D5BB204B05D4993D6F8ACDC8F16FB77B607FEDA67939A2B6AE285ADB2C98E7D37A81AF0101A5CE39CEB2C67CF99441C1FD980C2C542E7284BD21F1D30E68EF3606C65D3230B5146DAB41D4ECBD5FD89FFC68441BCFED9AD8B4E0B616127A7AA39E84DBD1343E2A41B4DB1AEE0627657438034E890C8EBAE19791705BF6C948C630DB1423D310A34BF151AA8ACF3269253BADDF5B40AB7EB3A7AFE2D7891B925F65EA206F4CA121175E8F348B4162917A68FA768928AEB0504A60C4F42802DA25DCECEC60ACD21FB236080AF1FCC9146BA30AD964416F4B524ACC416B5357206980305555CE3485425EB8F87401FB1D8CCC184C486B5B563242BA9531147D6A2E7C0BEC1A56E083F05344BF97A18D0CE0FE56E8BE869C746D4AAB365225D8871D4F99020DDB1CE2B5D7D2E5DFC8A0DE780CBA0A9B9ABAC87F19C73639965AC2382488387F06199A08F283794E1B8D3580E5CCADE811ABA6881908277624D5395021016DFE21C345B9A21B474043E187403E5B0ECFABE43991865A424BD33D233AC4BD30A3CE73DCF49B58CC4A3D2CE25C54FAB3480FFE0D51A43B71FDB7E1126E66856D263DDC3BF1A31DCDB935DECCF858FA2CE5AC89BF32E36D8009657F11691201290A243B5680E060D2CE30F1BF2444D67DC94A24708F8F9261945D1B5275ECFEAAF40311CED5C3770A1C194EC44501DD25B7F5FE67BCF62D1BF31119F8EA7DEC1CF536C1026A8E72C7B2E167BCAA8673AE5506CF6208F3E1B6057B5D488B29EB84D6F94AB8AF322B8657075B9EAD3297505AA521D601C21540EE71349614CACE0E7F14EF42D6CD5377DDD0241E34CF273A1171135A376B98C53B218503A908577C268F6DD46CA9C26DFF5942998851627474DE9E6B46F49DEDE85CEB993A52D01F6AAD6F96439C18B0DD5A4FD559812227BBC0567A28C1299626B171855AA0C74E2F9B1AAA781D34CA58C72C708AC49F5AE1453902A1FFBB8458E8B4786771780ACAD999F8DB036CF4C3F77AE345817EDA2AD8F7D2AA9228C994F6AEE512F7C2D2AB72F2099EC932D818E495CAC8507B06CDC6702944237DBCE338C20EDC84D958C14233C1884BA09A023BF5284F0B0157048B6AEB508415DF337A553F6435140D0CE5D5CAA77F9137B2C1AD5A02B13738772743F192E53E970DDB401983535CB096F7D98644797F487CFCD18F1B22BA7494D892C1E5AA05E66B1A4326C70E348350C97DBC26CB110AE8289C97CCAAB150020827B7D7AC7913B4FF515583677018949D39CD73BC7DBB90696D5EBDBAE6BD6FC78E3826C8218996F079A387A17456875952B268211891404E80F8360F042EA3D9F7F7BEF772E64FA1EE8B4EBE0A1162A46EC1E9899766BF4D3099AF712A847CC86291B3D6FBF51B3B3CFF87D7DE71E73069619480F6056AAACDB9ED8E228BA075622C2FF242CB050342DF8F02118D071D27D1FDCBFADFF49184F5A100F95E1BCB019864E58E0F02672C8F5FEB97EFA06FBAE6EC3D57A10EC712BE0144323292A2CB27F1B1FCC104140F556D09A6074F853AD4328B00E6F2F24A61A7932311BC999805F2E774DB44ED72ED244A945928B9512556EFCB2BA7BE0E668C41AE7601339F0162CEC0A1AA91C3FEB6A8A40158D7A3560924455B9AFBD4B3881F6C08EC2895C84CEC30CB0F5B499B4A66267C719785F94A9B9F96FCEBEE939AD0FCF42D0E65DC241698DED0EDF1A9BB4147898E6E83851499175105BADFE4CB00B9000404DC92EFB4EBF41D9A9262EDA550DBD0B99353D001F90AA05591100BB678634FDE4E0B1C174222C253870DA3B8A797CAEA9B446309DE5210F9A932D6AD48A4A7361A943C1BC66BFDF75CAF5409034A8768BD535B20996A728A26E28340191E03DB17A7032FFF883EF664FD7351DD37DC2D72F0CC4B80BEDD1DC33BA3046162F5D0003140DF78FA588A9FDBDF778836C6CAE7E5A20FEF030C57867B295712DED14474FB87A301C31214FFBB4F8D166498ED93B6E233A669CB88D441A38A0E5846EF68F5DB20245980CA184878BA8BE1992A0638B058CD3A3A501CACFC818D2B5D7876DB6EB08E9F26430FB06EE0B9E834D1C331B66CD0BCCAD7A66ABF4A9D8F7A872932A3C0B25C5BBCA480159711E0BADCF69A1107B286AB199B210CE95BCBC4244780C074C42B6BD43869F27BD666F9B2541B1561B4C207E9A667EB1E31942697FCEBFD0B920EF80CFBC5CABA6F528187403D7E8262C110458B5382BC376799032362CE57ED39F0D29D7822C408923C29242385CA9749FACA43EB4483E095851E89D24CAC7BA5AAC60815CB5C8C5331CFD66352BC8623D5700F49FD98FFF9E869D5AE173961138D76E00CED6DBA09144083437CC8FF5ACDA10BAEC0081C8BD2F5838666A093B412532C521753C4E11ED0521923D1EE6BEF3B4FABED7467B9C8F75FB24FD8D96759A6146B34EF951C4DF92228C2E58231A8D25E3F08ED5A27BF6041AD7011DB41F815FEA503973D4E7B5798489B261A0AA4D0C32A19D17C584B1702713D1174E542BE4EDCEF27016BFC78118445A63FC1D17FBEE5F71DFF46F1EDCD050239C68DDBDEEFDAE7EB8963B5BB4819186D45191C05AA049E50C4319936C8788AB72744912AF28BBF5CC77C835C35BB4F987DBA6657BC2A7E58B7CE69AF37AF680DC0EA7797B29528AC70D92F295C561E2EE0D0E530854AA19EDC43C01A383035F6A5DFB354E9306962EAECA25EC85B9B78E8A1DF6CA50EEC733F60C81BF812981337F784F8CE07D0C03D8B3E72BEE1FFA55FB92DD0446CEE29D8825CBAF1A6ED295E613FC700FA31167224D99338C4F59B1BB9C1E63CF77476BF84F2001D42E4161F7737B47C1A5F219F6AC8B8E3ADAECA827AFCD6BC0CA09615BCE15F1BD0803BDCBD41E68F781517907EF3DD8E8A33A1E30ED09D7EC1D3605DC72C9232EF9F92475743164E92D953177B98906DFE5E414E134EBB63C79220D4907869CB2D93280F60DBECCC81B532CA336510E2A7F1D631F7BFC517AFF223430F9804C4A4877D8B7A385ED48F390ED9666A56EBD62F6C943D0E52AB1EA247BFB07C05908E99358A51E6111486133F4A6BE3BAF6B2D4C01529925ED911CE728B4CE4E8CF8379BD216108BF964496269BE76379912E94A4984B890A4BBB9692107D56AAADAF27ADE475E98A566C0C9E33DD1970A3DFF0E2F79197F6315E320BEB5E2CA3E3C904B557075981118B363042BA687DC682F13D213974B1647FB43DF7FA168C9D4F599C5BDFF2941C111C6C43FC75E69C290601EBC9F23D665F944A9B75932DF7792CB8A005A7CC83DD071376DB11F9C950B38B270E06C907FAA102AC76722325934755F53F3650B42D0FF293FA37086241C00E99B9C03FCE21F8D7555CFA93D09A0EAEE3733A8A5E4C45E74DD5EBFFD2F75EA60942BE34412BC82FC9959CFA155DC87FFA0AFFC1E7CA5057EE016B9751C16DF25610F1981A08B8E3352254AFA433E9B86D3CC13FE9B5B7FBDAD83CFA0FFE511E44412DFF1636BCBB49E9769FC52B302AFC7A96A3DFB233831007CFD6C302CCABC119DAD45EE63303DFA1F11C39C702AAAE00FCDCA913371F158BE5493A9B5C3B06AF66C8D5DE2BF9563FB617D1490FF6510971203DD25B27E1AFB289DF894396B8C26548BD53B320203AAF053B19CFC815C5D37E3115FD6CF8231B88FE4C330545F131A01124BB2487A3363B3E534BFD38B1D5138F8887EA63776D78783AC45675ED598617077AEAD86206B9FF61E3669C93C3C3A3A8F39E7848A88C0F94878E5D359C22BAE891FC7478BC8227FF320B047D0DFFC8218C1110136FA803EF6395E52DB8326CE8E3AA928CE42FBA04B1E7F1AC7B73296CBC1567090B9E92238859A87686D8E623B780F0376B8537F41B1BB102CC8C480C0B6C069F562468D4E1FE111B24D51F63E9BD38C47F35D8C2B5BE2E737274229974CC4CA63BD0E1F0446F6C4448EDB2498F2376EE26BDD8581242703715AD434E425908D61EAF865FAC5E82578EEB0525F54320B6C264F37DA36B55C2308D4FC6C7FB2F4D12A88CAFD93953193B7CC46804A0C464740B4972A71B7EAB5F6098FF78BDD452540AC5BAA894C10CD69A992217B422C88CC7849B4D8357D86234449B452AB4D49EDB1D2769512CF8A797F5FFF4E1E0A3FBDE292D91722D71322F0BD48C68A3CC998D03F7581EA7B5F5150E7AF58A076D09D103E9F64E61A2D375461007210DB511EA89FC4EEA75FFC71F7BF31400E7783F12F69A1EB5B7228952E2CD1D6FD57109237BDC024780006C229EAD71EBF4B543647FDD9216D98DC78B43CFEAE12166CDEDDE09B52BDCBFF089B1F7427EAECC21CCAF3FD5A35EE72C3107DF0670891E1AE12C1FB81581F3A45480F1FE06BECE6A494074FF3C47F90C961E371E8014707AB0FD004D19166140AF7B1C9D6B7E4B6826601AE104CE18E17939CF77C2A31F711D5C7D5126F4CB642178CE542973466696FAC1A0858ED62E4F2741E47B83B97DCF4610B1E4E262E700A06FDBFC6709BB1D4AFA7C20EFB72E0D623389DCCB049054CBBB322E63B09176E2903DBCE49083B01EB07F140D498B793E149573D8CA91DD2BBF8DEABAD9CECA0F896A7B306C22F8A761A65CE2BC1358A6ED07327AA0FF4C0B6E2906882A12C50D61D021A1316646461013D8169C4B54C61614CC9EDB2CE0AB0BAC96B36908BA3ABDF92D11D96EBBB9A60DA780AA58B804DC6F91E54D82068FE2FB10EC1FED54B794836F54503135A7F91921E2BBC2A61C99B6A0BDC04FBD2D4E7E430F16B5D3C7F06243517452BB7D2D51340BAF550D260A26A2F3B5451AD7D4E3A70CAF63F92E25D137C9E9B1433CAA5502DA269211F58AF2720FE3F899282C2C02B78E66D3302C5B9DC04B98197D3685EC4E6D4603D79B357282932689C2928361022E79C197A470212A69AC2BFC7505366CBB2BAB8D2E31314FFD77A04E85076D76948E836CF2A87918D43208CD856FFA33740FCAFFF9F690B2E6B33F1D89F65C71"""), + TestUtils.hexDecode(""" +6AE10E0133138AE0D51C77B5667D4C9180E04D0935EB5F282E696BBE794C8B96EB6A21A232C9366518132BD8EDFA9AC38142BB9CDCBA77C729BC4D1127A13933DCD44630D3CC6D1CF0242355A0DE121D15D7D4618F501E509C4E0BA296BC956571AF19BA6C8C2A75110DB6ABC3E7C682E87EB280DC29066E5D45C5D318DC3F14396AD3EE29A772117429E28A7B423B54470508A48D67CB6395190855A0D92B30E71B34CF7F508658E7268A27E2545E6B79E48F7C69ACCB09DCABF5BC5CCDB8CA8CA8CAA2F2869773349C666583702F3BDF94C40204514DA2B43A91443B119EDB0B421100AA587CAF238A87F916281435AA6FBF00BF16AA7BAD080D60B35C53792C438CA39A4BDC72BD7CEFCCFD877F82AD557B176DD5C28E78563D1DE719EBEA1099718B0F4129A493C11CBB2378F989D18A97074A2E0F3338CCB9A8A36C1B3749E7A99E7A765C70E5D60386C71BD4CAB64BFDB815509166D5F55CB4A380C8CF24E6BBF61AF3FE7BA3529D84B11FCD6BA6E18B87121857B00A737B0F3D9665720C38BB54C09C8D3917C5AD646E3D01359724534BC1910AD174761D64AE6F796900655E0B13AA3EF2282DFDCFBFA5B0F6585D33455D7D86DC6BDD252B040B66EC6A03FDFB4C06E54C734145817A20C42E408E7571FFB9D6D258E585D5904BCD45D16CA6E44FDE9A25E06CD3645A302EF8F3589D897181450C178E4DA1663F2F5960B4755A0107CE43A265E6EB0C9C267929CFB1A93ED1881798E9B8A1D91CAC83E63537FE0182D022548B60CF0BA47B6A7F90CBE86E1E5D39101C0D2FB333A82E2E99E9E0C1AD46DF3FE876D144FCD3B1D78424C6C5CF0F6E0BCB447A6E9CC337481F5C14D4FB74D764FB38B8EAA511951A50F41A4CE248E13E4694704A0554853A0AAB9405E2C274A4FCF8B5928667DE041E668B17AC577173B0F4CE34363A7C2AC9C3E0A45A39A46F0248BF3D45DBA806A230DB1DC7B0BEE80EC18BA8F042BD6FEE173177FC0194124AEB21BB06FA079A1BC80758B347E4B129D69EC6E8416BD89062BACE16F2288076469237231B6FF4902FEAC3BA7D884DB747DA6371E792827017778E43708A421931115EAAD9E4CA316814904009F1CCD36763FC63038641BBC4F6F93235E16884F8A12F8D71621354B0AE4A9EED64DC5462917D4B35370AD9EC8057ECBE3A6221FE8C39B11444D4BFC380F1F4D5AD18091059AA5089E109181247DE78DFC231401A3D517E9DB655EBB914385BAC1B2888E3837FDB08A9E7AEC206406B848D045593BB837DFC41DC283CAA753D8CB64CEDA3041B2330BAEBA2F1450F646BE15E0B2A46578B1F54A73FA4DE57FA1D632F3FD410C0E8B17C11E197B7A17C522EAC6FBB78001DF9F96CC5F6116635D404AB454BF4450D536250B80E813C8F397E038590011C66C5164E05FBDE695482185F02C4B6B566BF3FA564E9232F40594AF96C96CAEF18CBEABB292BA546EED3A1AEC1476A8418B25DCE79F12D7B4F89303688539815E05F96BEB3B1818472C7E4DA7435652DEB5FA4277F2A810831F88098899FE2EEE35C1B0E6F74DF159D0631C5683C2D7B86390BCECC534CF69F3AF74FEE59EAB25B634333470A55CC49C28C7252B1CF4C293EF500589805FBE5CC056573A10F188A02D050AA34289A21D8B7D587C0A288114E47F346DA3772FCAC58CBAC669DA616C9976C56D87CC275AD463F2131DF95460A151123C964B01A2B908AEEEB7DB3E2FE12EBA46321D7A3FCAEBDEA0FE11B78605E3C8390486CA5D484E6C413847BCD8C6BA1B00BD2322BE537B173647BB63BEF929223C6AEA687F8ABCC4A8B81C44F0FE24588D2C40BF76590AF7157E2E4409804A28AFD25E36275C34A976D22213D457C162ED9274BF52E20842ABC94B2A1D6A4A3F9C2AC544060974DD687C2BB96AFDF8C27522C0C438E7E0DD4DAD7AD640A4B3ECF50CB6250C0A97FDDF15D8865421E490F84650144AC489AE7920C4941895D7B2F1911513E428127562F9446BB706FC06F07BC6C9922987A970D4FC21937BC09F072BEB132BDF8014281BE75BBE6F8C74E337EABAA16A064EBC956C188787CB34A83D5698438AD22CD4FC80781AA1B66E5A2AE0180B50B77FBC07EB6EA60246DAB074494CC9381F6011C2ECE64F97B2F5CDA92FE91B5533518A7DAC9828FB33ED428890A7FEBD0906095094576CFBA1048665782B07194839CB86719DC91EE8C2F64D4576605C2B55804299F314DE8571D0C58C78F071FE810B2FDCD3D7AF0C635303B6ED0774637B1E563855D54D2A1B0FEB5CBF84E693E512F59A13A20E5FBDB77510E3356CF211DB09CB471DD1043D9940DC1BB6A26CEFFCA03F48BABE03C15226EF29E0DEAB6108BDDEE6462884F8708E79709775AFFB39303D78BC51C8B9EAB5D91A56F8BD1518708EF243AED01A637F525E25F297E0FEDE03F3136EF23C4B33DC1D256CC92E3B6AE64C368542AAF553B1605C94C255012D605D1291098D1F0B855D137BE49D198CDD3EBA0A9D9E7519B8A5BFB4DC3F338219CEA7C97251166B5004CEEC23606421A8F9248359E5346594080FAD04EEC15C56FAC9D55EAF4C399B1FC8D68501B88002212FC0E36DCAF5016371696AEE5EBE4396C36137C535B13F09D490564D38D1E0FFDF13902F7678FD06EBF8E34E81BF712D918348728BE21965F5956EC8AB1F5A8D8276E6A72B4A69FB7C5AF658C5DEE4C8BE285ABAFFE0EF41529AD44B31EA310C3665F2EE61B5817C1191549DA070A2BD4BC790E283BF81C11EA05A6E4652823EB3FA05283E784C4143F4C029A6A7D485A1B892F7462CC26B1879B4668D133DCF6B9827D3A91E069B25DFC72EF00FBD6FBEE4970E26222D81874C748C746DC5564732CABCD0FD99983034E4F5523A43831ACC1E6F3989FDE186D4BD07E15CEECD8E68375A5EC130AD93C0837A27F5EC5810F6C87CFD8E37BE6117496F7C283AEA1DD30A5FE5AF6F8A94867A5A7B336B4070B1B5539608BE8D10BF765F6984FB2D0AF376A7DD4E5E25922078782B77C4E5D5E086669D265C6306CB40BA5755E6D83D93D33C89F548FABB20DABFE7086B9E658F4A8BC22C11C8A12A106C534EAEA38F46FFC84C2A4D96C5DFC31F6F21B3FA32F988FB86A38D7103ACBCE69C5D143C33D1186C1FCA80A13C642487D5B221DC76556249EC81E42AD4DFF51EF86F2ABC45274AACE72A79A7B985412A3E94C92CB824E3B54F328FD2F06B49DB12338284DCCB5E03D063CAB73B939FB59A569E4E693E53B446279281BEF3637B55FA1C77DB77A389F43CA7E00B8711B32F98C9FFB2FA30D66075DA836CB528CDAF3FCF65B6EE3C0355E05A46DD0DF6B3D71E8C705B6C14514A537627FFCAF805F8545A86865D9EC83B243BDD4A444D6E09A7F26F5C30D824C39C65E1596BD506F70E793CD5E703159736F7A7C1B1A08A88E348FE12D0D74A190EE4C8CF1E2FF44B9FF40A28DB611296835E251E8451068C1016A3EDA063242D1DF3DDADE57998C1FCBF7B9F988392916D4D405F82ED894AD693FEB4206E1131911E3617F5A5325701D01AACD591469026E10585C1A73ABDE7ECA706C97F48B125A8E101E55D0262334750AB98A8C4D33F98763684402C16BC7BEDF35AC349AB471E3EEFF92A79AE0F11F3CF17EA1406FB6DB669537CC0E46F0A7C42695C4595FA2F0E604F048357125EEB01AE824FFB63B70F10DA410EB93933398C13B485493E4DD5AC42744B00D2F81BDB3C7030C3DEA36BDA258AD26D4540D1FB83C7E651E31C0A2F7D06A328820D85321B24E4B798153885D80111D17811D5ABB97C69B24E3E82B44649CB8C5E828A3D532DC8EF2C317890BCDEB43571EEFD97780E68E03C1F751F5EB823D75965ED7714397112774934F465F61C25271F1AB2EE80BAAF7049D1E0C78EB59BBC3594202F002E883B7B579B98D0D4865ED783AA0ADC84A4A37E73C3CFDB5F464812AEFC6081EF899B5F4C9F903279E77D39B2DD0939329B3C5060990BF8E0BBA6CCFB6F7BECA77F48585F44F8CE7293D121335939E3AD785BC66AB2C9DC955941EE85DB9D2A4F404B3F45C7A68452E6AD108530A1FAB8E35C9EB0AC7F647DABE0E0D50358A007DB71B6D76B9922797F9CC377D675E70D9E166B750FF457A5D3D649153C81CC1B659ECF3656BD864FDDB3C430AD6FE44B21DF23D0827D56899D8F0544472298FF1E12FDA44466822409222063A8BC27A2C2DF44B1C4F56C47062E7D717705967F8C10E0F1A35B0C4F1EDB14B4E3A2ED44163651179FAADB643E602F2C92DC144FD96871AD3CD194BC83951F18C77B92518F8F3013BCBB49E57A4338FDCEE5000EFB89A3DC2177ABEB2DC34C094476A8844CF072A17FECC8E87F8C3D85B776972CDD5EA7F8ED6DF4A123197F78150A2E9CF2E3CF88617E82FBA29410168DC261EF9516AD01187ABA8E189D59DE5E243CB019E5B7C34F5BD158B5E11E9D7BC75BDFC71B040EBFAEEAEFB7639355AD3BDD27AB9DD799BEDFA24D2AC5566DE15F46CF601E08A702B133D391B0E236951AAB4BBA409C5B8C49EA0D1E2DD2EB9D6EC67F76D12571C002C1E3448FDFD0FD6D5C070E6B749E9C3E6A86DE347E34A72DD2B19C51F405B8A4F4DC04E7A7F3E0BFCB51EDD253EBCF47171E0F57E7DC04C0B1ED1054D06B7DD2E8E6FBEDBB16D086E1975676B0B3D34F3D290495051DD8EDB5C6FD727C8A460668FA7EDDBAA5AC776727EC2A155770B5C98297C45F192C5817C0942C62FD9FF9BBB5085F7B197AAF21173E1B2313FD94DAEFE9B76E068E8D6A46F25D6E81E09F34D0337F22086EB2F32D4917A6B5D685E3FB94D919BD8D513BAADC61643AFCFF3B1DDAE63FD0562C3F60228C951217142269183F4D9BF65F438D86739219161F9C6AEE0F65244E85758C0BF3B137B30536129FF7557E5C52F05AF64883FEDD419DF69DD8B9C9EA6D4A6B018CF676E91855B58B37120D84D3ED06C7173BC3BFC65FA01CA02A01E2893FEFC9E0E708506C84698BE652909F0F9793C443635A032CDEC61C5ABBC097997A62BF2894133BC991A19567C9F4549B30EF4C081FE2FC52724CEA974DC6CDCD4042D3118AFFA2A7EBAB82ACB14BE405FD6A764C8405CCCD0D1BE12410855BDF950747EB26E948C7FADFD2089D26824F7100FE574815B487865090CA8D8307D27276C8C5FE813A22636672026C72B81290AE9917FDD5A314029D02BC37EA1C39B592EECD57883952907C4A2A4203CFD6498C19328E55500BA395947B0CE523836ADD259F92C358026CA86169D73D17044AF5F4B7EB42348764488FFEB8D34237F17BA80D5AEE6F5DB8977898B2BEB745B065FC20DC567CB4090D65D82003B466C21921FCC13C6291CEF5B18E6F6F77B8E07FE9F803F40EB4A015A76E18C03B40CBB8C8095AAD7AE64B52D6A1AAA31EE00C5E4EBD04597377DFF1037A0B12D2585E8C2FF784659F3A57CEF7732CFE93DC4A7F11E5124273A656CA234AAA7503246EE53F430A79A0F9ADA4B6C0A5AD6DF6054883339C013FAA1B6BE863DADD11B5443B5E4686C5CA6CC2BC43415A116D2B908F8949FB594A470B2D6017FAD537F066B8F2BF20AD2F376B33633F90BCB9D262EB23B399E8CC8D7632E17B49C4792B2217BBC020635CE2ABE63B1039463C7D069B2B004D0CB650CB917311A049B97560768EC46A793F19FEC3ECBF9493AE80D16FE24F00953348E522E28B2668FE430454AAAD914C385490786CA7D98E6A1CB345ACD0A67A6B57A175D8A51C2B51F8763861B027D29181655D5548E2B15986DD3835404A9A282DE523A045E5DF42FF092144ED9392D589DE70678FBDCACCE10C956AE96987A266AD001EE70422549F7F27BD92748CC06E7D24483CE0B83C3F2067D522E789D849250E7F7588A2DB9BA9D5F439D9369F04CE59A12474CB5FDFB08C2AD9E0889CB0F2056A7170428778D3BEC8F9084072D6C0FAA922400D8239119E44BD7266A43C55A70CFE0984F60A482D08F9E77426AA875AB50748161B48390A43DFF04534054C2A2D5E4A84C804C03128A0D7134BD3AB8E0A2BC7753F458A38B9B244FB654F9DA3C2784CCE6958DE3DC806DDDD84A8D2AA24A8382AF4D11E52E1F47733FF61B79895A9AA426BD060B4761EE687F1134A23EEC3EA828134C4B8108A6C5B9E3AE6913E955299DFBCE6488FE32036662FFB0CD451A98D97A1538F5BC34D527ACB9CE6D1DFB5862FA889422FF32319E35AB53102E566C710D4884BC3357280112F2C694D957D26BD3372D99CDFD00CF55098238994610D18A247BBA60650EC3AD7FCDB208B15C4AFD35A25735844D66A929037EAE673D66159185E4B2B79B48746BD9F046BA5828595CC6820EB8A860EC9C458E7AB183489C3ADA179C40A386B1F33F2D41C8B1AA5D571D1E7088B0ED0372C95824E870D63A4B95D87222C121766B270A3F5523BB6B69284B676C81F20D0F37418FB0B40240414E95B7CCD6E110658CC41F343F4F56BAD2D31A495D6BB2E9141E374AA7B2B8EFFA3E41434B4C4E6385BD0000000000000000000000000000000000060D161A2228313A""") + ), + new SigGenTestCase( + TestUtils.hexDecode(""" +6639A514256A8CA2D510FCACD916BDEC6245D3AC11A035B7C7095BA4DBB92C62A8D0C518807AD496B31228F96E1A2A23096EEABA09D37E615E24E5965E1073DD0192B175684B4F326189549EE36FE38AB2CB29380675306AF7FEB99B2BB8A07D5BDAA761EB9409F46E70EAE199F0B3A72568BF6964E6A58DDC6CC223FC89E27C104004C328694148109306900C0085913042D4B211E2922D60A80C91008512101118C04492344863824C81C20DC8200819C051640444C10470E42286618424149040C2344292161009400ED0203012B10991A404A4B24011A848191800DA128D83803003182C03A5201B4066D9462102442484880C09A20C1047689B140914B70C84B068D4282823885081128222326CA24882024150A4B04C44264059320498926924496950C0841910840C136E1AA10954A2889006864222665C026122304A20A36D12486181306992368509304A1416210B064EA3320403014D918885012051023701101411D33840E4206CC8A888582484444486D8A06C03C6499AA67140804518216024850001896522483222932D18052922344954900DA49890233351C434852025420B230122044D9A26604B266E8430011A2889C120240819461AB76503B50554B2605AB429091591E2122E1A320EE43808C8880D4AA264D3960042C06C24C92959C024A220208C942152B06513286D11B440DAB20104B84804A50D088650A4386049988488A28108490A81328442388EE440021BC811A1B204A1482E13B2842007501B288A24A9092109629BB465002966C44682D140459BA8400381108BC8051B826820466C40301111C77140C89112394444B60020992901178D624202549405D1320502872D02164598104249A0114A182ACB3802D0944552A441C11641C986255AB864D1184EE4B44D821224E3086A0CA30C5A18100BB3900C022C194780DC126264248801B9880A265110272C142025C4328659124423262D0BB590E28090A2385010042103876D61284618C38D08A10D922684D906501A33611B8468098830E3844C0A4424222640CC388A1C05110B460A24004C02132408067224C4611AA62409358AA4C6112322629C464E20964D580430CB388603B44C64C42C0000095A220DD206655040415A2864102510C4300E24A46DCCB28D89180D1407714AB8451413409B323011396C5882005890911293081122850BB94012050018C905C3248520B34D08964003852D8C220D109270D8464ADC34301424840CA480522282D1346D8CC810D4000C22850491B224D84688C084450AC30C1987111803618CA6644A384D09C8012092040301121A4722C1844823A1858AB24DCAA841A4160E8B34889C249280208849A0851C46290B1260D804604B4451C1C2911C0729013381E2C44019962062C28CE39220031824234202C24006C82264483466D2B630DC90880199054C242804424A5B0628D3866C1200896424492025050AC680192921E088812413204988448A368C20A36519006C00410E23304A18A04C0CB96C8A46210194105B82251B05840A15840A185059420E93C289D04611CB0242118100004606A4C28D1145114C186A922260093921A4941154C669534625898208C0080E4848061197411AA36CDAA80C0890655A2284DC380823A44CD04680011370C2840C8092249B1648C134801401445888215B4620A1A84D0BA04D4006061CA769D9380C1AB78D0019669212911C020E91A0909232515C224D243662113242CA081104A950E4C02020C069E3242E0C3109E4188518427261B84C840422A036605B1486120022D29881A3900542480613A54914228D4CC44D1B112994403112C6894C06665A384411499083904864C82D8B002DA3142CA2320261303044342CA2322E83464A923885C424690CC60C0926528844300416600C0741D0126244980888228CC214704B9069C1C84CE484440093449A226108850102C2212342282234650046698938660B371160840D58120C09102110B4451847480C434D1B33111C990459480D90260C0B464259B82C9A200D4416062139310BC38188120508806113396604318D8A928509372698380E21C925000384CC4228933031D2982C5332461BC10D5894451A47118490691B386083482D0A8921D8B82941928120156AD212414A90250C248202310DE1346950807101106864808004A5604488712216244FCA3DC070EAFADBB8E253BE1E85890557BA06F6FE596C9EFA6CADB19A6FF51D64B2F169E1FCAAA7761B8E4E94A6DDA9B390A96D7C0BD5AB3282F4F4E310FF1A7745741B15A80D1DB35B18090B1C35467939147179082650854D3481AC46C4D5F372ECACF58B439D2C8E9BE32AF5F647C4D1C8C06C5FBF01D95D35E4D7EB2D0D0FBA5B152CF08525006714C6A1DCC41281FEA9C16F1950B66DF989AD4671296C9BA6E565227A47EE10536BCCE94ED83E57092ADA82578FF23FE0C01268FEEDCC0953EEBEE12BE828BE36415712733E973D6A984747296AD5D24CB48002483869BEC1AB4AD0487BC6AA09CE9138577A5CFFAFE08119E3142803CE2C88D83CC9A102560B8A2BD01684F0C7FA1480421F4372F88CE04C3BDEB9A09FD541C17C67BF4D06781B6B8AB45A7C1DAF153B5CA37C1736A12B7999E05D213A2501AA67ECE2B92710749BBC902E550C33FD2A265CED7D3A88A961503E8C4A586867A9A2AC605849FCA19DDB92ACF22D481FE8A16B6BEA0E916119A83B8826B7B64EBDB9A8D7F5517A8812B9369EF1AF29818940FF4C1A41A8193BEE2685866B887E48DADC162929938202BBDA46D7FE090A185883192E45464E88026AD24C12B37FADFFC15956F0A2BC1AB5E4917EDC664D3B35E3C9E2CE2A73E9CF319AAE5A1EA8161B747989D2269B80E82086B677D417FACA39B64DE63AF8DEC028ED2713E7EA645A9367DBD8A4BF6E52BD45082712BD30A12D639DFF1069EB150941EB3204FB5F7D12C655F22594A70AABC428131168179AFD776579865A2BF65988276B9337B553EF75BCDB793B67FB602583A879747CE0169B72E2181C6BC1569A7353BF0476F7DCC04F7410F1C94C6C1E164E2ED651E90A3288EF61DC18B89BD8746C0491F680EAABDC51B68139E8EA42ED4CEC08CD60093D18EF38E26B1615789EE6206F8996B34EEC3773C098D61C0B4E4ACD835C98C16B0F3DD0A8145E1A74889297FDAF7FF20519A6184013E9773BACDE0705496D3B4103E5240759EDB954C9E77A05B20E4833F446F4CC447CF862778E97A388312D7AD5E0D2626B298BEAB7D27F5CA67EB73F3CDB03ED0239912590C787F9C3F4B04B170C6582DF1FA489C7F8FF48E78C3AB63EEB5CA0CAD4BA17AD57EB6181FABCE3D00D31602FC3ABDB1231EA961A5F64558D2678F963E603343FE35B4B97B60E102B95BCE07BA525F4122692A28F891A77A87F07C6444AE92C621875CCB9A973961C55D920BACE5050C42938B6FB81663DEA18FAE1625B13FA3225CC80FE23D557C35619214E140A55CE2ABE8BE2D82122BDD702B5263498B9C2957CD3B2D933F3C62A0696A0CC96D99BC106872F0E2B6E70BF9429530ED9B97E68C4ED660456D7A79E37622C0C854187985C9928850A15FCAEAB8D8D9A3A7CCA7C13C400458DB650B0B37C858F52B04FF135B6BAF86E4D91DBDFFBFD6CA957B3E1CBB1381AF4118D9FA13B70692030AB19C8D068ED620D8E7E150236B8B988C38B6D4002A3B4FD078F58B96A3C4A996A13F0C6190F783C6E6AADB8D69BA275D7045E1646C56C8024F8D1CDA3EBCDC42877674E480A070BC26C118504525595F034B4485CBB9C4C48E5B5AC4A250EE8A98A8D0448B5581F9AA1F92BCC10199A0A63AE5AAF39D6C2F82D64E6165C9878B3FDF4F3403ADA84A57202B94F4B65B4EFB551477FAC6338DEA7281962698CC54110B8F15D4BEB4C091B845306024445EE008933A8FFBE63AE3580E098A18FE33681D926D46AA99F5DCD9E9C6AF4CB2737036BE094EF63C0310A42DE5CCBCFC75AE57EDF5DEF3304BFD6854405781FA983BA2B582B631E4773A62CF8E3B222F9FB0C484653E7DC89851C989F62596377E35BA2A05F544D6C2AA1FFB71365BE259FA6AFDBB797D70C2E40474C2697A510E9C277133B26C2ABC03786589859134F5719314F392093125F15EC2334A2833BA6F4E634DE374AE5EE93E7C6FF37D978117122A19F5522E63D637E6109BBB80C95AA807B205B78821DE56BFD0BA9949BBF0A58E2D3803B89AC37DF91955536C5381D81377AE430C261992EF2501AB8FD653D715C93F63A98C7A00667AD74DE5548B685BAA6D301D4C6BD9E40F7B50434D8E88AFA19F73986CF55E5F318BC5264F909F8DCE692637FC09F62E9CFF2AE21FBF37698736557ACADB9E782B6E60A214216FEA674815507A12933B0A9DF9165180579072283F7351FD9696B1C7EF7713845B3EA3F618A0E52ED23273484EF1307E7082818903C5AE7A5EF2F11E5D1E813B8B2796D2E134C43EA733DEA8EC94CA03E64B0C06D7A52C38FD63658F549E49872BADB78020B9DD64055EF006D5D92FC0642EBBB025C44F436B9586C9453FDD9DF65B94ED020A5F647717881470C0C27C266AB56C3115E4336633E492893DC34359732740E954B74606232D2F6E988CE1FE565527395CDBF66F1CA04F42B34DDA2937857589E3DB5FAAE2B0CC97A68408B2D73089AD0098CBC66F03BEB12FF72A00AD72C5150BEB7760D700D634A0823988D20BBE9237B9E1E60737CFC7A97CA65AE467026E3664D2D2242E73C3D43AF26D33828358670BFB69A3480CC4483114FF22D93B452578CDEC1B93C732910438B66E30CEB14EF03CD044EB6D51E5AE1242EC49F176A4D888DCDBC6036163160D404B5B17F194BEC4A1A8FFE396B6A1E3500D2C1B17CC8CCA3F105A397D62B4462D3C09638B01B6A60AE76D93A4D7A204F8CD381C7ABB9C06F9B4F835D89A69A5F0424052C19D5AB4FED48B4CE549976F68BE60C54BBD5CD80E8A0DBF80A75A961332ADC8377CF2A286068B8E4C7F9BF85B2FFBC9FF2B9307BFE33070764C49EE7B2DA597BAA459C4C0C1D5BDA7DA4EDF5DF2ADE76F44A2C64576CAC913BBA0059027E98666DC03610189BD709BFE88F0AC93224DEF65D86FEB422563A83BA823F9F312CD13A7707275E3701369CB009EDBF95E966DB3DB9645F493852DD1F71B025102D2B5CBE6DC315DB57D4E47C9FFC1B65E0CFDA0FAFE7937459DEDBB5983FF57ECF7E1D38E9B67A0CEB91FD7CE01DAB9FA9CFF2A4DCB19C8F74A4DE51DF1D466A44FABFADED4CDA52FBA424B312A873D29DC420F8FF3C94DA1C896E0D54F8C882BAB83573716DEADC439904093EFB720A1120A7CD9E18DEE7B6674466737C36948A4EA961AD122E3C461FE6D5A3843262A3845CBC97E37EF41BA9274D0EE4E77CAC71DE5AA39E860959E353AC28D1A545BCDF977BB4BB7BCDED646BEED12A6E03ECDBD2FC3C1D845D5C9299882D15A295AD1D39888EC943216CC0175AFCC605938A2F72EA01F1B7BA77A954FE1CDE49A7B7E224D1807E81BD09634346DE0ABA64C0F5B3D2E6A9C47C497D28CD231A70347DC9B9713E1FE77CF42DE2AFECDFE081395AE1E2198E2C8D5FC05606D648F18D3B5E0D96BA194C1D9E4985506F6A96C48F1CA647D478EEDAE301E86DA2D916A41832D28A6315A2B95381632A3CFCE232621C8477680D4DC096A57163E4B570DC6AA475577A60166AB550437AEBD5810B523E4053AAFCA5D5F702F26C6FEFB18637B23606568C43AD1047AAA51E84178814319C6FE2CDA8128B7156F84ABF9D11D201390283801BBB87FC2AB6B050539D1DF5511893F809CA261303C54A7C8BF4D433E330ADFD495E3D36D61D469BACAE8F1F8814777B3D20B4F98EE5727C1826CFBFBA2E5BC624C4ADBC32519B731A666EC67D082570B1739066312284C1F560A9CE45EE0E576F5269EC5C325667D13C3A62EFBF24236A0598F973CA99C53DA3E5D4130FF8F4791E5A900B0B2FC93364B234F85926BDA82286AA1B04A2EE280357CB6D2A464E8DFE9AD6780BB2A6937F008DCDB8B64A904E9CAF6B75A4A3341D068381D6C8646992A7AFFC4C2749940FC7A51D4C7195F291F8A1E3C4E0C7AC189669269036A2996B9A7A1D696C35CEB82DEF7B4C19151E1DD8AC8706E38FFB945907D2D825B06F65EB460A5F51CC9B17310FB878D73A436788DDB87978BADE32BDDA761EDB2CABBF9D44B9E7112BD8D158B502AA34F7326244E2FF83C778B5AB05C2A8CAFA7E218EA97045C658152A21D8015B4A62B27ECB39B72CCAD51F52D3F323EF61F35304BF52FF7940642C38A0643181A6DC6042F8E4D87BBF40D04770899AE2165B39C2ABE3D00E41311FB1B3DD865567F9C60F5FD03AFEEFAA9EC299B50C1F378EBBA3700DF56C4EE64548C29A6ED299B8392DA122204FCB5CB990E898379DC6CFE26B6C37FA4F25066BFF6E296D1EDBDF8578A5E939CFB07EF8D5040DD3F46AA3152D5CD76285F9F864664E465FA66E338CCA55557467D6E7B443478CA00900A6E14FB8C7FE7F27984153A3A1CF070E91C8E520D1F6DC0D627AC966D6AE8B3B10B61BA99F642C0945174E3D62A3448A0F90C3B1F7104409FEFC05286B4AEC3BC389698D500E199F70F8374AFA60D2B4F83A22813F8121FD99E37BF310733F61635E4690B0C6D0498563287FFA83F2D677906A4CB0630CE3A768FA827125B8E37A5F5C855192762B8ABDB0DE0C94538E441620CA1B3F24425B37F7C13A9A55EF08117B8E5D2624A670473741449647E2997BB4F7A1E08A2D58ADA29E80F453C271BE545F2939E2F95342131C2C9C3E4FCD52C24F25D3D3C6B040BDF0B8BB0FF47B0E4A6EA11A3F3B10B68E4F2225D5A5E4946E6033926EA55A21531F7C344B06E42B49908C8F3D43439E949FA1"""), + TestUtils.hexDecode(""" +36DC7A310D995379B796EB8F9CA346EDF60DEC7F6C00AA311B3E09EF96A6795C4B077C1D371DD8D4A538AEB78B81927D08008E817A6FC6B3F9B14FE56EF9B2664E76112F214EEE848E67EF33B4A4E26A2378E9480CC7D25C369E6C25A2673B946B635B6EECB5F5F1499B484DCCFD5165D6F14CAA8E1EC9A9E4FDE417403720D7B4BB30060AB95C6F227767D671B75A1BB5AC5CC33EF0509C69652748251869B072B9042618071233B48A9BDEBA330F0C450A2FAAE79291B9E2480D1CED11FABE56210A80C39F25E5574356CFAA32E57782145920D6C0D27C3AC7C63DED6A770A5A45119FAA92209F2A066AB90FCB81A886FB87641C550368C1B412E43F4FECC2FD659B2BDA6B7309797575DA2893314DAB058DD92C7470F570EC0B1D9C9A149FE0934D40182CAD14D5B3D98C4B7454CDD2AE7E54EFCD554AA5B458888048BD5201C04E7D6004FC2A597DA781BF15AAC9748B6659EC16602F10AD44145607917C3599A1F53DC95839086A6A4FFD66F8EAC8AF8F11C4F2EBA3B58C46B93D0494C4CDA4E8B8FF7278049D2B4BD7BA16BC57678219EBCB5E211D51A168B5CDF66453412565B9BD606CE29A5A70E60F3D451D4214B0A258D6E9325EA5196C55125F0E115B14FF34FF6B172471C2B4917FC36B0DBDC82D0475AF56249AB9297790535C0F0265D2A853DB0B41B418072D0ECC17CF91FCA86F6E10762EBC520F0AADCC3C79EFC25E9692FC0A66389B15ECDD1377A9C3D744CCCC4BD160FC65A45D4144DDCA04E5408576DBA6D5C875BB4071729361B0514E8B96405E2F48D47138D2D2DCF4DC865F717428FA1262DB0D2B7B1A356E9E76301D38BA506456B4AD70ED09B0D5A1375AA6E132D7E06F8745E7A5B5E4F6455F4282A87D2B372C40A34C09699AA8C2B2E060107BCDE0F9D99B64F17DA5FA01B6DA87B1738882976B21AE12D1BA0AEB37644AAFE5AC20E7F3F631FFC2A24EEFB61DC37485DF27FD9045BD9BB5D3F00B9B2694CB94B01E7A4F0D909B8612DD28BD64E6C1C5A612CB30DF6004276FF58491B8129FCB0B539CDF891A97AB58DDF04AE40BAA5781C3AEC65FD7E84DFD0369A53CF36303270DC80E3E428854D82B08C7AD022BD99AC0851B16C7D8D462DA21126F70D661A59E4D0FE4441806DEC48E37AC4A271F15D916135408A2751CAD53564967196763B512D52240B2B0D3D924B83CF482B5316B7988D73A16B773705097F5ECE0027CCB2C2EFF598B8F61ED4D6BC015E56D4549432A6A95328FE3122EAED0149E2144E4CD2262C7FE7495E41E0AC9FAC9A11E21AC940D25E74AED8EF6FECD21747FF8166589B7038EF1DD504F51E01F1ED911FCCF44949638AA6E8526F0B9DBC5E536FE2AE7D4DA9DEE66402A45CF55D0137FAFDA9207AA7E22FE396455F2F43108961FA6B0339D89EB8ED7EF13B936E3D2DA18E5EAE45B05DCAF5D845DC62CC55553E37CB328AA2C649ABEED0D862E8083962B81B84A85EC12D3CE5B600123AA7CE4764139BA7AFE5CD02F70D06DD9AB0BBE868070A9AACB951D362E2606FD940A8F5BE632393E0A179C2A62151A094901F5625D952D39D7CAA87B77C4919A8633458AD9B6DAA16D1B1CAEAA8075741094FBC0C08D30D9956812C1D3A75926C546ABD78A2B9D44C1B6EF8D6EC2A2EA8B7C23D0EA57E1320ACFB576FB9C575DA98B714D6B01F03364E618A2C03BA84BDF0E5D2A0403B1379416D87B5E022BD958B0C9170E82F8E9A727D39C8F7549E34A14792776AF0D72A27FCF63EA985B3882A717091EF35F5835D4DA127554B6637AC313BA3BAE8170B9E70A6DDA2DBE813A49F045D8C3A65ECFB4D5F71FC75AADEDAA91A81A958273ECF0CDC4512F0D0ACCF9D9D001A30D0B6B2D50BD216D6086AC5C9DE7388A7B1319F2E9E6CE128B1F72F765804E060A8A92C93295A99C66D6D79BD7DD4F7F02317927D60B2E9FD59EC3F95A874337228339EC673BBBF53BF0FE1886A4B14F19CD7FA9B771894377F904EE8BE48D64EE5D40882C684C81DA3198604FA599DA8D4EDEE8EC3294620B6555B3BC9627D4514DBD1F7E3E9DF7B56BDB4CD395A8CCADC184B2B8DEB2AC7CBEC6C96001EDB67E6CF6F872469B110097C69EDE1121D22FB5B5AA4CA540474630651A4F9E8F7B0ABA5DF568D882626BD158F925F8DCE1D81668EF7CF770DC615ED0F5A807E25991EC97BBF2F9E997A532A1BD82A2A616250D2232F72067A17550EE516F28940D8EDA9CCC0E02EEFA496010E499E62C50B03F1D3C1571342DB8A5BDE1F432F7B6163BA3AEF35656434937A42C4E1F473331E38467DEAA483189902364463832ED8C5E04E0195D3435A6FCE75EA3BDBDDB0A0319262083141B1BBC0C278CFD40319647E90BFB51374B0AA5EBF3C564EE95B7AF618669C935756AFF3150A93EDA92F0ADC29253758A6C8A83EF55F97F1A4C0DB566668F30DE59D93D8185BDC1CFFAFAE472E0B0FC4B1E16F0B748220EB2EB85EF127838D576638E738E9F93A05D41CC1264AC6BA03B202D9E3B06946CCC68DC15261A029B0C5E91DD81EC1D79BC51F74BB5EF778F00AC091513443308410F60AC1850F2548C8101DB3B6B4D453541E36F0ED57C2C14F465196F8F1D0D3ACD49CE3252BAA0C10521311B8B8366C579A430526ED58BDE92FED3F0B359ADB31D67BFD212BEDA7236DEE4615ABF13C856CCC93DD02AA28D1CE1F12C2DD69FEA828BDB9F4CBC9242E1017D1063A7BF842B00C75243303EF9060C8EA501BC73B3EE470919443EC91D1F0D6D0F23A899AB86F2E8A0898D318BA520DD15D9B24F4F10A1B9FC52457714A151E075BBE419E4216857500B8354A8445B5FBB526A6E008229F33D8DBA14DD42F424DE3675E704DB308048B2D17904DE46B76622BA08C62F17EBA3E9F414A1B10921858832EEFBC282755B319E176ECCDC32A25CC5E76479AC112570AA86518BB1E6CA3F46E010E8132C0A1E8273403C5C4D7046A05398D461CB6843D70EEF8C94DEA5DF53CA1A4C7842AF5DBBC6451554FC7F9913E56957C51E0A602D882BC389C5E5C7899539DBE6832B0AAB5EF26B2C96CB03D1795179A62F748CA501CFA34D5ABBAE3271AC1F005112645F10863AABB062FD2C781E4573173935B5392CF9E88A1A31989E1B8E94F77CEFBEC591DF6529C6D2FAB72E678C534C4EFF40177C41D02AF0EFEB6371835CB55AE0AA99C0653876CCB56ECA127A0A1DFC0F9EEB49525C9A5786F618DBF57C41C5CAA971A9505BECEA8969D9DB28B0E707C659EDC42280035254E91C522300368F49F2C36211E455FD620DC956AFEE41A2493BDB2B0B8AB78E0B838DA6584FF753BF88CA6A523042A285F84ED90E0FD5E28F75A21B53F618145C16925486DBF6B1E7D76585D0D117EC562E22239E14A49ED714814F01DE2B250E9B3B6A1C99D1A71CEDEEB3ADADF611C4A4F97E1B26AF9780AFED5783129FD58B1232C7E2DB9050AD3D494EAC254DC46B0461A1B4B63840621D45ADE97EE5663C9BD8FB7261152545AE35536611B5C65DD6D66878DB71640EA429F801D6FFE291B06062EBAB9B416DDA7D261A46E58B154684E86176169CFDC4A60EA38300C3D44F9A4C9DCA0CE1BF37DF8F786F28B5B3CC7B0199D3322CFDFD2CF88C5B794C69F59543FB985890471DBC93A313992ABD33691CCF69B96A9396E5F55B54FF7BCA82A31199E5E81CE94B6B523EC5C3E2F2884D8BD744CF0C072E29E4B542DBB370FA5966F68CB20ABF40619E76C099BC7A9A373707707624E8999D4CF0A75D4AEAE113D7823D7D2ABF54FB4E68B8A6A57A198B128DC69584D2DBA473B6725FBB8EC9561D6614D606ADC4FD9CF449008C0D54BE4F62EC1441FF79EB59442AEFBDF1F0976844B4FA3969EEFEA10794FDBE35E89EA52F50AB26319BD1604D3FF5AC660431F1073575ABFAEEA00E1246DCD1D9399939D655C222E19E9DBA5FF42709FC11E7E365D7F7CE2274FBF1738DC5CF5631547549F2BD4DE896C8FE039720F5E0149BD81533022DAEE22B93A3AAB9AA9DA15180EA071D98E9FD176804A5B04D089E9C2D386271A8B13E7D668AA74BFFFFCDA3B4E528937C41D43A87DBB46C2B49B63BEEAAB978415536A87D845F6C2484F21D71D0F904438C46E7B0A3C6DE5ABC01C6F7CBCFF21D3E74AEE96C20C32884DE4EBA0F282C0FAD06BD9CD6B7B5031F149E4788F102D2AC2C99FD09B14A4AE3BD6859CAFE6F5A494EE8CEA29F49D871B79BB66AA6E6EC3718B97E83765E96D5603B209027BBBBCB09EE6FDE3AEB65AB1D73684820AB1FDEF88086B93B6338BEC7088E04F5F6E520E3D715C6C5E5B79E73B9E7AE1C5EDEEE4015860CDB9FA21FB434C3F28AD865042284A7FE9A5FF47E8C6158DD83EDF28BFB18DD5AFA07A48BD5AF25B9644400CC976A9B0FE9D9071E708113802A78CFDAED28378AA4FD6FBD9390D8A17D6500A0E1835652C7E0B332A382576AC4381CAD51A31E64E5E24FEDBC62EF9D0CABA0C8EBD8B94625207D0C8C1C6DF4EA2B20832EE44D1E2DEB799BC97B7245EC404F10764296E5BC4A919EC24B4F5F7D18692FA8DCDD5BBC170A81BE7590B7BF4058DC7BEA0C545BC85F0B3F0936386C37115A333285451CCAFB8397F1AE1B56D0A8F884BC968E729D622D21FA26B89BA2726C91E6886838DC9912797FF2BDF6800665C1D1DADFA4A240BB9BBE21B6DD750389AFA49C5C366ACA5E9C3B31B358FDEC42B0032D9E2C22112E43BED2023B364DAB334BBBE2C3B669EF700702B5D1837A6EC15CEC2B2036D56B8760129F593A669FF00237D26BAD9F9C2F4ED4018D998E555D2C3CA1D53EAD6A1E27906353983D4408904E5FD9D79AFEFEC26ACEA1F39218C36637977F6E2F3F6211AA06AB9D5F991C76F420B152BC95C4BC10047E107CC82E3B00B2325ABBFDB0FFB2966D5FBA0EC7E8DE1DBCC053C4186AF23A6BDF3F14A7186665AC2682FB94B0E10516D500B7F67BE4BD2523E194A1ADD8B5564FAD9105C86B6D16B08AABA604419D55F571F11F4989197144DD12867D1636D12800D54D36FA88C620008095560103366711B8E3AADD5624FBC7FF51318D17311F02A807770466AD559CFDA0AE1439442E4413944855D4D0074D529CA8DD621DA02FA98F46327A7BA600387EAE5E724D64A82E94ABB760C891EE39F27F0CAE8D1AACFE20629DEC5DD9BF4CA91E65BF413FD2A9566B7DCA9E500C2C328F533AF2A957E46D9FB11F0DFE99127656B1D4BE20C946BAFF58E5FE1A9ED282ABEBF6EB35A35AF324DF0A858CA8AF507CE43D228ED81D863F7096044A084DAA37ACB6AEE98E5A94D363963D4F852B955C2F076848092E6199E07990372E56BA1D590BB83D0C7F834C852CBC39B666B801CD32A0C36B034264F3BA6911A719001FD0F4B63D2D628FD0CAD34B4C9355534A8A38512E758B110F48E5A09B504D20D178508E09B1423A1E61164E7D138B4A9455B95EC8EA786F5FFE67806781F1E619505FD7DDE9A904E9003CA7E5EA1077C94C228D36667031502D78B3B52C3B5A09FC398D8B5497B6E3F0C5381BC99DD7B11DADA2DCFAE352DDEA2C749F8CF5AF39587083C2C19576EFFE871AB94D1C7CA2183FABDB74B27A80FC4F20CB86B46B0B7F86384540EFF1C888168F74634F2C0BF7FB54F7002EBF90B6C4B2B25DFF068DFC7D087A27749D6C36AB0A33423044AE027DCA8C42678987005FB9DE5C2774924AD2A5A8FD2E89C288975F89B5C0EF70A20EDAD1925060A12606A9B03626039635BFF332A0E6BDDC4F5DDDA209AF8DAA0FEF045FBEA9523D04458FBB0BD81F65396938436AFF5FA66E997AE58D64E7B5C1B589558B3DFF6D035E31008D2C76CA426B07F1644F609945909DBD16559B36461CE882A361D0415A9D93CB98A5370C56913A299B2DD1AA372CB75C7E590A9629CAA6C439CC5C7D94A21F36F998C6FDEC1C1721ECC500ECE1214EFFDE65E479D38C635EA223286DB326EF9B19B3CB862C96C162D3DE238C2948E7613A0FA4843E39EAC51EF293AD7EEAFF0F522934C982890F83E922B2BD52815136D0A758B33641C54E7D4E0F3B19AA85859B750E7A7FB80892C3DAC5048767132E2DAC5804709B8560A4B3828B1CD25DAF263A2466AF7FE328ABC84EBBA26902FFD92B0D765AACC0C0DCBEF962E1B35B1195676E8A67ED593B23B2B0305B611F9E16633E77E3F31794C58C5309BA07DB5CF9AA1CC108186318A3F16A7141854C2FC8B469BC0F54BCB22976A3CA05FC2C8E23F1B6A891E7527F204ECCA0A5400B68565906E795FE4DAF52ADA95A9883676F9110B14CEEA389CE9BFFBB5D040E60D3D03C4E6D6CBE9ED53EA44B1AB6ED7EDBACD0AE0613DBA5A5C673A534D48B539DC85F48175F13404016C5289348504141338FE958AC28331853AE80ADFEB49A6637936BF82FB26B95295B2E46F4F9534720A4E86FF18B31335877C9CBA96A9B450C1C8C9C9862E51CFEDBE3DE5C8B901D792A179AF9A782C330035A14CE6A710D398BD28416CD72373FE216744F6237B38B97351A77D5D0DEA1A26A0A9A24FE15503240933E1CB5AF458E6FCA8624669A0DF439CD7FC13F7A1F10A0CC7DB8C6AFAD9C99B5FC45A7C565B5DCB74FF0EF426FE7C260D3ACB1E9E83DD8E6E11A642145BFBB7566D582D0540D7931AA28B7F8F682E6E2D90B6E6812FF8B7F15FCD3DEE686DF06E8E6C456C99C6B4215C4E874BCEEE3B4F94BA825C6A45C2A2B4C6DC04F8FF5939C74E7DA37E02D8230340C6E2AB7CB82BD226DDC1A7C7BD0C0FB36F71F9C772233132B8871A0D76728C2A141741C2662438C5CC7B129A6C8FC587A0E475545D176818B51190F0F19E91E05C04477283A0A7D4D646EEDA3BE64459780BAC1862D83E6B99C5731DF91F0CAB454E70A0D94D934D0CD83C8B8301DE282F9A1FFE49E73EDCB520C016FDB4AD02C261DC1A1E73E38809E60F91A4E38C69EC70D2A621DF0D21588F24CCD59D331C69E16F0F6BCAA8F24031DD5718875BD9EDA5B420C116E4316137D4B77623C9D73D182900BD7A0F90A193CD16107E692D469AF09F74702492E22C796B6B4A960D47FDC571B4A264EE3528A0F5A9D66DDAA33FF20C3101D50299EDA3225834C9429976EC8E590C6D48A721A14972BE70955EC1A0348D2F84347C1E8E21EB0C1FE67223B42A6BCCAC43648F3BB5464121180F8E3E682B4B664D91584AF55FD1C7D2E6F79A93C680238D29CB7FF36D259CB703DE03B2EEF6DE0CB77AAA8F49C61EE482A8DAD30824E603411D5F09482DC84BE794BB6EB65A7BC1DA92C8BC8364AA88D4B8212561745BCF3CBA0D6AC8B8AF80373DE3F44EE39CA3CE4C5763F422CD4E8827B1E7BDFF79DB990A52530E4A1E21F6CCDF50A322A086AFDF24EB5FE4D99F1D1BB4D6DA965D168E9726FF7A4C82F327A748DDB1DA5A3D0E9C8E0B060872B009CC9F913D35D94FAA912B0D6FBF233DEA3AE3C2A4E35BBCACE21CA3E5F7A7B9A486AE9D7A7D2E0B79FDB11D87072F1B307402BDB22746B86A1A0E6B41433D5BAEB2048ECA53A1ECF895E9EB9BC5D6AB5D5DF72353566BB90578F12C6A16A163E95CD35DA27C79379756141DD05C315B466871E2B726B8821FB6FB439B49430CB3CA47CD211D03DF40AE4A0BE87B6000BC9C75AD23552E2129F47AB64BC9E5E1620C99405CEDF7BC059547D547E2868A6D470D813AA5095D0AA4BB18D91964988391EE6F05DD47CA1DA0423CA238C5E50D43CFB0527973506B9F1DA4A8055C47D1FA1E0DC783CE3CF75FFAADF574EC2849631E2551368291AFB5F2C40A4F1A184E37A19E511F482B7920F6D51B13065E6327F3C21DAA7F73986F2D1FBF375DFE2505C0FBD35F403D253BDFD0BA1B00CCC5A20B683D4F1E1F2374FD914C7D674901A0F01BDFDC007E8021013BB9A2F885F0699D16805F9F2511A0C7D3CDC06E36679983A2A0F12662C88BB7DC643FBFFB58CB51AAB3CED28553910D063ED8FA37FD756B79AE4151521450E552E4F2B62EB6F6BCC8086BBBD30331F3F2534AB3ADEEACCF2A6E66F205935A167FA1D5C747936050E276E8E4CCAFD9E0A056E4AC2AC08738BC3A598F07E933B0ED285BACE3D24AE6FF7574351758F983FD7EEB3944473EDB4EC9A9828A5FC656BBF04DC623C75F8B8038F3699BD5F255CCD3EEDE4FEFA12AFE8F64436DDB1FF2DF100B09BEC657DC5D2B18E5722D5AB30D075D9A52A576B6F9FC8C8BA3ACA6A92E6596F688FF5D2A7E3183B696AB277B0B17F004843E58760683F90BE0C61DD0D1BF9099A865CAFD1BD1D8AB1B7D4AF2F86D51C18D7868BEFF3F6C53EC68FC46EC9F23D1AE1FE85CD97D8CECFD57A562E7E574ED1D0A7005813EB980C2A46A98CEC602C0E022E87D4A6EDBFD7DE9FDA8C02EF85701BB1CEF6013F4869D32CBA56B0AD6EB007591D03C76A839F9D01985C546C39E49D59395B10346820324F3E298C5CD977FC2FF83BD422CA550DDF2A69607BB8125647B389246ADF0095F22692BF907EC86BF8D70D7E8F2C50E35DC6EF34FD1258E1FEBA0B254470D43C77CB0073AEB2D4CE5F6772D49A101052D8CE943E1C7760F2994071644D27D26BACA88EA07F29B2F2050BAC5E05F2226F1F584D17DB80E4056B7F9C60A5D9DA0CC577C6BC802FAB26E570BF017DCC7236A1173E273397E373640ED02B4F9863C40D2A2A7828C3875D8081AEBEF349143BAAECF9089EE736EFF0EF80078D2CA7942FB24A92071D229A1FDD0F6A87D362E5165D57F62D927757BC31964B5DA63B90EB3591552F2B9902E2269A163FF221863ADEADC9BC92CAC0087ABDA02004C0B9F34E5CA8599DC3C4261489F7527FD27AD2B6501E602FDE47DEEBF3F3EFC0166B1EED95116CF43C8AFC0EF89BDAA9ACFB6DAC613770DEA78960C99C9628C0D21FAF63A0FF7A3F2733EDC0FC07B83F107A811BB3C1DFC6CFBFEC105193272A4BF915B1DAEB232E16216E40FD3F9D9399B15CC4C073BAE8D08A4EC42D91609574EB009A9B52F06D3F428F6EA9B0511D8319A1B1299C154C94B103CB586370A58F18F04F5D21AD3B638660D6C04E99D356A7289E37EFAD643A5EBB488D54F4A0194FBC4283A8C4ABB8D9A1D70150AA50F991204C038AF54B5B74F722CD6515045D62276A9E936476F42B282C3B08D9328089AEA259510240B95BD5E81FB9D7E006DCE0DA832BD9A833799E05CAAFA6305D16DBA4461BE13D3CAA95773B98F09230F2DBE13936495C2DF5BE3A8F3EEB4FD211810F4B07D3E2BE1A11CC87079DF1B32D44B6FE7942DF2627AC19FD9F584E771D7ED98AA4C074A9DA5B7C156F83D90EBBDAE78D636D51EB0CB30C7C7CBC1A96273C0AE0ACAD8E15D1196BCB2EEBDA332896BABAEF76B4275F863732D646C24627AB014AB602A47594D6031795B17144E6E2C23F0341422886C1E2512222ECD530017DA02FC015EBD5BDFB319F3AE942D75A55C21BF347A44B300ACCED7A339007A2527EF4499E3BA5DE334BE58D59918DD0CB55B2F478837F71E9CEFCBBC90808E0BEF8CC7712A3B008B69476C61535FF0787B7833B70C69B1EF506EC4F445B72AA12FAC2589815874E9123BA13A17477D61E41163CB21ADB8151658C99F1422C71A8183B8D0B1D489EF436564C47ED8482A0DE9170CD1BC34D88CE76E1B47B84E770020125F718B4AFB1E4587668634FC7464114762A9D74A93E33A5C0CDFA824CACBEB097B5CAC3B554BC0D41C402812D8E43DB37C730A6219AB6F0BACD096BBF261C78E991DE0A2278DCA7D1BE0E5F2FED72CA38BAA86924A84275BFED3B91FC8DCC5024316EA0587C96E030544F631076DEF65F05F98C7641A958313686B8580CFC20221ED50DE4D2CF32461FAACD0174AC46A6949EF8ADEE6FFA3F537228AEDCFFDB2250D7BDBC848AFDFEA67AE53CE9ACA45F349557E81F70F9DB92926FD0CED8C104E6B7AD180C7B3BEB86171EE84A8DD2C243F6869E04C2DAFDF0C938C0768415C56330C9BB6EE756BB335BAAF96EEAA5CB52E554E39E2435B0731B0062376F4730108DD2F05824A798DA24C239724D19F12C6F2FBDB52652352021E0167F31E0F5941C4687DCD13A81A20A0AF05A55D2533280941865DB4D5715AEC293A64AA2E5151C8F44A14B72C0879499027E67E4E2B487612216F6122361E8D34E92C2163B0C88583E3887DA93A3AA0E77FFAE3FE8FD5455BC86AE6D6D5AC7CB7BDF156A960C98B0BE50E1370A43E7D183636DEB2C64B264FC5922D4BD46A8206F911E7A742E72E4EBDBA39B6151AEDF5A6CB4157B375D9A59899808F1838C61EB4388B923423D3879E8228AFE0CEE9561135849A89363F84B41BCB166EBCD0E65A2A74FE710F2B3B55CA9DE2FA9DC163BFFF4BE91F10493936FCA15F5F39422C75233DB22299456D1EA3BAC26F6671557B2A5FB0E9460997DCA797C67C49DF109CFD597BE34C8E0FA0353F28B815D0CEB31DA93E49EF29CEAF20FEB0A8F5924DCC62E830353463245899900304A8C8DB5830BC0E97AB83853D8EB05660D6A9303833D170E138FF6F1C30D9DD64574D5F875F974225DA81ADE3D97924A38F552276F46A5208403AEF82D1E92959675EA6B353E5C6091034A295D9C12C288241055A2334C30DF0A37D2590626A7D1787A4F591A6E494BF55ABC76842BBBD508FE54C5630D11C54386A487A756ECBFC0AE8957E7CA8678D5B9B044117365AEBE79AFF2E6678001D23624"""), + TestUtils.hexDecode(""" +58BC36248443BED9F1FA12DD93EF6FE7D89828D96315A0FBEF047B5D57BE38BF2BBAE0DF7E983151E879479E00046AB12BA8354A6F51F9C286B83560DF391BB7B1B2A495FF27E582D3D09412950CE565F2A800D18454C0C17181153091B57657ADD3EF44C97FDD8DE557FA590474BF804E569EB7FBC36357710A307F3D540F3457FF382730910BC41C20402449A0CBC5A93B5FF47DDA2D39E59DD58A862079FD60B24E8FD43BF8750AF3A463FF810E43CC4E84D9B54B716C8EDC3B00BFC0A8FA7210E30DC6FA7B8668078782643404736A7FCE53A870491E3CF91C38A9E761426FFE7ACA6D1DE13BA213273E899DDEBD4E0BAB8CA084525DBEAC382D0155421B800A1AA921BC4EA1990E19CE090696E081AF1D4145B5C6DAC1277FBC483500B80F1CFCF40F49F48D2D86531E98EB3D14D1F54E435E976F0C123B14A4D8111927C2B425A43316FB10F9DE9BAEC23D49F7CF37D2369ED11FC3801E84C981472DED8DA4D1AACE2F6F4050EB94A483F79F2551CE179B31D753072D02642873DFBE5C7E61C9FD32701C10847C6AC35F41A2DBD695DACE401814743B88C579BA7B188CC878150C71CB5C8AC5763A805801FDFE267D812F65FF31D958B857C41B06A738646E93AD2D9D0AD0E1678697C494FBB76CBD41FA63719A3331A96A4840F0DC65F890F7F81BE3D22CE8500CDA8E3AE5A6482DDFD749F363882353D2EE9BE0784BDA8BB2AE75A011869108FC9736E6E6B08D9F6F42DD42F4C06A561C5E8B585ECAFAC49BE7B17299BBFB4B74398D8A300C6447108FAEF5DB463454010217F01AE45F0282D4A3B9EAF23FE092EB750EC081D6EC0329A9A537A5C270C31B1499983A7C293EF72F0A4FD91CDBEA3F029DFB35FEA766C475A07BB4EB7297A9592A20E3FB15119F5A7A9E658D18C4EEB3E35963C122A1397456DCAC9DE8EC08DF9873C751A10E189B9C8DB3F63721910E930397C4CDE3D475AA7E5C56FA2B139690C20418DC40F9AC14BC29B419A45ADAD66AE2790EE4CF0233EFEF06E75CDCAD7A594BD9D64F0A030EAB8FD2C77B3AFC4E4737FB5682FEA678FFD75A794DA8E2A0348088A48D1321C9828E0CBE6F15A746DF22248B360F51B501A9BEDA1F7263D5BEE948C72C9ED854EEB7DB56E5885F6892BDBE019B8FFA9CA30DB9D1C82D3E13AFF7D75B0D0A713FCD4934B559A80F4F32062BC4883CBFE4B4F905B8B8E639A203D69AB8CF33B61A3092B38F03683EC64605DB4585C1E30021294BCC7C98D8DFD80940E82E65DDE8621A38638D6EFFA26E19CC215FDD0A305E6BD731ABA1CD14BD397ECD52BBE7CE7D84F88323A4C2D709D28333BF97DF22D24BF792EDE7B5F5DD1FCBEB169B625E36D2DFA95539188CE7B7BAD539C2BE1BA1971648478468AA3413DD6076A213EDDD1AB0FA85076B6D91DBFC858F1F935EF31DA87A24E3171B30AF8F03E8DF50A1781FAB6E3775E5D14B3025492B4E0309228AD41B68B278ADAD656EF83B0F8B1ED030835255A4A07C94A35D27B256AEC0381C35E640C1565A80D55D8905C7DD3BB69801DD362AFA95EE532714BAA8FF701E8F8F30A6165DFDF4FF260C6DE1135E66DAAA7EA771FDB07E07F818E4B2F7334850789F8FD0E385B23641F0D8A7C754A60B35A76389F5920A4DBC0E890A7207827F2B6368CA95241DB5C6664397D5A294FE3CADE660D80F69F0458171684A997B68E6CAD05417DC192638F9275DC093FBD4A72925DF8FBFC7B6777CD28F13658B4D3745DBBC82C88E42A16C31766A9ACBD13DE946054131FBCFF70677F2FE91078D9593F12423A3ACCCA5761830297971F6AD925455B9313683F01541B53543808D1E8C6ACBFB93D3B4C715880545B77AD0E7F1CFD6A3426815BCCE1F3E7EC720BA259046B06803110F12508B33D7C04C567BCB2069DAD995C590A2560C766185D7F2A186AD1B336A1A5BE702F6691F90978F1EB6F3403E00A2464F19AC7C76D2490CCAE4C0D117DB7543BDC73E6DCCC6AEE86D74984FBE575C10E6AAAC0028D61BBDD001BBA9186065A7BD1E7A8C13CDABB33F6F2FD03BE5E950793212CEAF82829142E7BC7E97CCC4F774892456870B23A1D6CBC5E1D2B797219AA1D4AEB332F2B38DC3B230E0EEDD600935523D9C05D7C750B485F32DF4BDD932676E6FA4A7AF63E12AA149AFA49ACE37B03DBEDFD502B97B36238DCB412E5D9C6AD0E8209119DD9BC5C22ACFB7FF53827CD2CBF259DA76D48CDC11C452FFE69D73354BA70D9CF566872011AB6D06D027C9B1DD93B97963F964B33F8F4FE51EE4E1F4436E5B3AA240320BF3CC6FE63B219553F6923A134D843C9B49F913525B4FDBB87F5F3235461E8DEBE849449BBDED39DE58BABF6BC66DCEA2115AED2582504E5FE394B9C2C346C5251E9F058C6447526CB3786A8A66E86747129EEBEA89F6F27AADACC5A97D6D9EDAF5533218C46BE6C8A108F8723F78576133FEEF95920D3B92CFA38B2547CC48B97087EC163FF9C244343F51683E8B1B7D29968A81423EB1346DDF5C4E638D796C8FFFFF6C482E47227327FB87885F52EA0840B06252E5DE252577838D869B074E6D0FEF4811866467B82121967283C2E47FF209D9E3860FC43681E0AFF54E6418443D5B3F769ADE3EF026F7E96762E1018326A0CBBAEF233996322E495DCC06693729D7C744ED8B7780161EE1277AD7C9C4B40481869AC463653E1E7F7F60AA5C352BF1F1A9CE483446F13DC6A26239A6D784B9F44DE97299ADB3CDCE3896081A7C93445C45D9ADDA1ED9FDC49E63202FA99D02B240C46DB1DABFD69AA70822333264064184BD583FC949B5134902767D003E6ED1D05581C1D6AA5AFD9A119B15F745E835CFC832011829AD48530C7C51AD17785B06748230985E77E2A2C4AC40313EF394052AF472A74044B8542261BE57136759FFCB1F42F349A464066BB4FF963D9517D4D82181B1851654B73203B16E302E7F7875067D2198E33F819270183ABC0AACAD3ADF227AA20314979F296AAE763E9934F15A6544FC5CAEBE33B6D51897ED5DD4094B377C51C931E9E62E5C05F340507C82C4E2788DC84E6B719F0C1A729AAECB019946C9DA7920DD20A7E7DF89EBA8BDC8E8EC1B03FE6ACC18E855C02408FE1EBEDB17066DBCFFDD0B1948FA53A45AB7A892C071EE692454D94453E2D5E8DC33E7B6C304154D3843C6FFACDCE3358F8D845546E2DE5C1E9641646702E6CB83AE5CBB07B35E9CD28DEE1C6CC88D8A614F262681FE0AC38B86AA792CFD0509A76928FE196ECA25D9A8A231A1DC659CB37C2D7EB3B7702443D879D6725FC633D503841F43B4EA7AE7155074B4DE876E2918339CC2BECA755F757183748F1E9FAB045C3F22DD5DC2EB5752A4EAF055F64F9BA6B3AA65EABEA3F585B72D712E40FD2B9BBF5F62ED5E9343D613A59A81B8D4172ED8837137DD07FB77C3D1B2095B9686F9ECB15E37C6C1B19267A5C0D299A1DDF368559F615733F451532554D0250D52E4C56242FDDCF6DF7F4C5E0F372B04AD24248687BF21243FFE82ADBF602204E9281C2BB4F47D5E3233A6CB0FAC7854BF4B298EAADD9242C085856126A1806D7B063C38D2D6F13CC617D22626BCDA228ACA22B798C0BBAD8D3BE108DBCF6ACAA304EC51C78BF2D06CFEFCF9B279B7677F78AE5055F77E0C8BDB8DEC635290D154F59E13DD6E45CB81BAA882A54B26D2447C8DCE935FD0A9E5EE20136C3FC643ADCD342EB901DD8A0C9A652DE28E552A73182616FD7AD0F662A465EC1D947A0442F5583811B7A921FE210DB41614A01B880C0F811BD74325967CB5361235E92C6941B4E5EFEBD38DB1F22A084C2AB64308BA1E47AA7223962DD65E7152C840AEF3B0607827B6E99F6037FFF6749A9B871ACD998F719A222F8ECFF7B060F586CA9CDD6D9ACF769DB558352F7ACA2A2CD8BCBD91915835D96F0B1770A88097C234D5D46AB064D9AC7B3A387280C9C8A16FC561A7585F6FAC747FA4091BDEB5AF963E9AC134B948FBFB32805C80FC5DA7798061D0B26CC8675E2FAD9AE52DB944FDCBCA68870B29E270D9D51A113B064FC6273CD3F86AB72CF31B20F0B72E1B964A2B2E42CB71129481AE61536DCD409B431E2859BCFA5734A47A05F149FF91181F081846D376730E4D492250DF165A2B542B39781977E96802A4AC38F450AB89EB87BC19E5F8C323F29F13394228C985DFE60A185728ED95DD62D764EDEB4F46C6D5F24EC9B105075ABECFD0A27A24D52DD0826B18F89BBFB55C27A42496F5408D283376C20807922609616B07425B4E180CC6E33BAE22186AC37E3775A6786BB6E930B928CD682632D687A2915094F520D76CD439DD125B3DE7295C5C3D1D1367C49954CD0B2B944F5CAC8CF765F39BA61B89B007CDB7D46ED1AF4ABB6E219C67534DF7AD50C422A0A34B2204633E4763A386E7235DA77CF46CD2388062028FF8832FFC74A4612886B0AE4554BFE6D82E604978101B413B5AB9478FF79B39F49ECC91FBB639DAC7A72B97B7693DC8647FB472AAB87CC9B28C0CC91AD51C557ADDB3B6D864903B98793C0E80AFE5F02A2FAD2CEDB1486BE609832DFD285D92E67D46FE19AE445F4FFD7C166EDDEA185666FCF0B4B9F75D169B440056DEF1E376B0F6166FBE07BFFB1925B69A2E85C25C7737F9FB48B87E7F66D2E1432E12BBC585E3D4E6C5ABD5E65326A67D1C944C67DCFBCBB0A017666187E71D2B1CAEDE13DB5A4576F2F0606E892B7C57296B95B009CB92137729786672E11E66CDAF1081E167B0AA0BE018711C8CF7D285359B6961CD04F79F95559801D1DFFD3AD1E712AACB0C121BAD5604C9A5B95782BFDE6F1A2DFC110579197D1C6E6686AF1CF312B95621C6B72B4A57CF8B1FC47B773EAC6392B6CE10F6ED1D9A0C2827A0B12D058FE72F99EEEE750CD4D41BD4A3D95B1B7880535F78E4942A7D83D3E2FB8C1892DAA7971E4A0092CEFC9786D69D689AD31D7AAEAD2CEFEA23E0CE14305BC745A472AE0782DD31F8F5484EB129696950B2CD00A8F401C19441FCD6A16BB2AC5A9AB36DE2B75EDFB5BFFEC0AFB37886F415D79DAFA24350BD01FE8B0824FBE6FDBF6B34DF81F0A75B5F5F87D94011014AE543B1B7F5C1F7BA542BC3F4B134E1D9EA6345339F4606D132998969FDE118BB0F305F2753D1D63EA33465199C5D04D2ED4889C19E180B68D2C5CAE8511F9C69A6539B1BC24EE28DA9C9C87D7C46887D01740262F7F2E76447C5CED2C8E23A43CF9B5A9EF603C14BF4FBF4578A1A316029B0C036D085EA7AC855516CFBC6F658923D54AD182AA66F6FC62812C49E0A209F5FCD343B1BEED407C74BD4499024DC312918B45FDDB307A8DCACE261D070F84CD26458B62D7F3E9BDCDF3946384AC7AA1C32A34A218EF6C9FF835FAE4508485D2A3F4E9C94425A5B3FF0422EC098A34CFF4583C722389ECCDED9ACC397D53985F362DBD0DD401CF830E206BC956439BAA66981F2EF63C30F9426A389CF72F144DB8FC4F7A245A7DE66F1594629FCBDD6CBF44CCAA2C4E3D45C0137F99CC69E08FF6BA2E835DEA3D9DAE61DB48E684BBAC10562B6587193DEB0E6980EAC9877A5F954E1AF915D02C8C394483DF6C8AC9840DEF57D7885E0A38E14E9D3B85EAFC94BBEC68BDF2CFE33C08CB3CB7A8530E8759D27EFE663724FAD3F23F6CB10655C0AED09BFFA78FB3C671770A2A9B928C4DA2B0852836730C1874F7A027C861A805DDCE2CA765D091ECDB3CDA874165B5B0B87A6D6B64A73A47DAC6B255AE65BBF445E1633440FFC2882D487CD30D5BE629A4DC58DF086A4C62116A64AD799E34BBC46CDE85EB71E7A7B279B6E50A13EFFB00EE7E86FB19541596D7CE82F028A26DD5C9D0D807F686492E0DD3FCEA572A1D1E544EF62C282A904803CC2C7B2CC0FF7804FA14060A1B7D8E06A61F5DC2FA43179286B4DA6EEB8065C3D6397E6CE850562DA4E614A44BF81C3442D00AC3AEBF682D5B1A9625BA462556CBDBE75CE951C3FA91F83105887C24AE3EB3ECCD05B4BF4D6C910A718C6BAAF44BE750CD008C2591638CCBA780807D02BC462B9A16967D2A5A927FD75AE048591B5CB40B3DF6F092469BB30B2939CE425A190847B904B631E08323B88E11958BC5C6FE6F97DEC18B7EB94D14089F9EFDECA3D20958780998A7DE03881BD99B7315465BE6CEDABA61F0D3935694D1FB6610E00BAD93E96ABFFBE51F653FAFD2353F3ECA0A65FE4CF7D5583A19D99CCA53C11A5E8E5450A2383C7222880062C1315D81C705F85ACCFED53B9E46DD9CC544F588BB7C7594E4EA2B7720984C23347BAEE26C015C065F732ADB6B71C772FF539D9AB8458917BFCD3D8B8F6F9A495A942DD429A91DB1BBBAA2CBFF201086B14B8104D6CD77655510EC4EB8C995B95B1939BD0602A893F631499C81B0DCF7D02293A839483BB697E7AB5B364B8A386D481648557206AF32F4C96DD05232B37536793BBCAD81B515E6E7D92B8C0173A5D8186DB189BAEE053B0DD4B4F678FDAEEFF14295C719EEAF1FE00000000000000000000000000000000000000000000000000040E161C20232A32""") + ), + new SigGenTestCase( + TestUtils.hexDecode(""" +5B62D37A8591CFB588DA48B3B1AA1570C3491210EFCB877AE913F5C98D06C5853C78D526C61C387FC6E15BC8E612762899056F844B324E4829E5DCE6E2144804682D4F5D3CEBEFA61305B64386107BAC5022DE119038F94F656ABE41A61717532E374C1196780C888EF1F7455BF502420F61FE9EC389C1BB6B75397622374EE00AC0856130828C806CE14840D9322440B02923822D53126A0221108B988822A191D43231D82831E2C80CD4A8705B086D83B001A0A64183180681027040220D223269DB940802958C8AB6500C056E2222311C91491B9451833064D4280A112750232610CC088054222ECB344511B90063128119C04CCC942914C36114C1049B1290A414460893242316665B184262B211E330868A280CD9920504009162A4605A926C1B28100C002E1C4491C3A869C246860200050B1888588664520625A0102158409090022288A468484685C3844CD428919BA0300381300C372191B2001C086C13142ECB30710B3021840864E44465A4B061E2144184808118B70DA4161201398C0436810C2970DAA029D840600282411290898C106A19140A6394711C256D18C08DC488249A881123418DA33491CBC801D010680B865090104161B0511A15501C0104C01605D2B825E02226D1A0708B98248BA22040426A529220941080D34006D3C86458B4651C1440DB168DD1A66DA0B67108325109128A92C869833400CC842004064ED9340502132D1992800424309B260E2319105AC669481061994028C3A29163024C52462A5030221496846280250A300862B26523282922292410436C10B11001120D993884A34661830430D0100A00318589444C5C28802330884C22445148248A083223C02C442682E3C86C5A0088622224C2444C0A854554B26D18452214214898464A1886610B26205330310A9840443669C3208424380D94C62911C445528249DCA431DB4211C3824CDAB885D800655C462E238288221980D93468118441E42609601488204486623445CB02411A266DC392514C142D1AA8515CB60DCAA22819286522368D4A0630DC44491B036641C231E0064CC08430918460142670E0000CDC10624036852348819334308230458A38300095319B082D608268911868C2C2109C048D9C084120B16C82804C14C61120C071D1B850930245A48420D8142A4C302663B29103932521466023094A0A076C14012190180E901012C2B62458C809D0A004429885834010820629D0102462C624D844021C054CC43841D4082D0A498C2425600047621B90001AB78C63A228A1A229121126828820D224028344285448640A3104CC166411A52520B0205BB61052422509C62912474CCA226289261222812D4A28428888210CA9210A0965CB948518929002C56D59C04DE0C04C54360063426D62206420C8815C484511037209100C14122964008508A225C8068E80062A84C89198A411DB302613851023C6681BB54D49066041268501B970E3B005C424458C8425DBC469A2A45011914DD1064261080212C9010AB1240035658C164A10358621A38050284021196543000C03174800394108B448049571912481A4982D1CA669511090928845194642094226D4B42842800021028423294A51284DDAC690D0262401B26161C0250C8265199290A136680B0689C9B84D02948002227053386A0C08885B962899988419060490964DD8C86119370C21986D8848515CA6294C042A2208441AA93111C2905218220C454EDA1404C42488C8280C20433259C668803891DA8000249301C094089A008C53321220C468CB928D623881E30426011505C2145181488D008244A4468011C38499A090E0A425133510D14088E394000A271108C44822362D8C004D4A86512430242405818C4624C9348598882CE0B841091612204968A1C830A096108348106332068022610CC491803062082301D88045DBC82510C18C6486601909910BB3480A244A8A9870813031532881C494111A88605B828C0315022017901383641046890103668BA451223840C002458A8011A032101C35514A481091488021990CD8949148B29112282A224440C3127281920C12B889524024C3B0655C8209D104712143710A326112389213042C9B00820431000CB344DC1010E2B82859982C032602CAB00CCB843113C6200331280AC061D2848C1A4110911430D3388CDC005262C0858AC660B6B814546CB4270B543A708AC86BC1CE481601287A65C59BE8D90379B0CAA51F6D98723C5BA4787DFF8F095CE307869084EB4783EDE6ECCF369F923E9F435FBC1E5AD11B5E20159EB53B41A0596BE86945FA60133274AF288DEC348188C166BEF153321723169E4BBB7CC6CC2DBD6158374E10891EB82EC47383F1BF3A103B912FC2A929461137DC00FFBFB8D5A8884B1702D329CE3EB967FC0B1847DBBD06C3CEF44CF4EDFDD34E9671A3B51572A7510174D26968B869F044919AC6CF766250953DC9F4F3D0B28FB6D7D0F973BD3944B6ADA312044A09EC59E008EE8F92329776708916B1301D2CA52F9F571EE458AB13D13EDB882305351E3A1B41FF9BDB54D1BD5B768B7AE758EC8CAC4668582073FEA7BAE86D6ADDA4A4F582E7C4C298178DB1A5038D9D337B1AC18BE442865444D24B0D2443D6200A6C938963A812F1600D3689D8EAE1D668A7A0C2A3745CFF5484D0E1AD2B25A9A70CA3FB16D423DB83318BDA289478A5C44C5F81253AF25A7EDC4B35BD73CBDF3C621B0DF2ACB9B1D9C5A87CFF528D0C04F77A31818BB36492F3445E250712BCD2A0C2D3CC3B1BEF6AE9D1F4653EEC35E2C34F14CD872172FA46ECAA5824507EDBC63A5D5E8222308044C6A0647924F9D1B8AD7584EF56467A4531004AB4AE1D48203E032A1B83CB53C8BABC556AA6163E7DB321E71E55DE72EA992BF47E0F70C2180325559C33F6A0F9677BB801D99525CCCD1738C19DE9AA91A85146761FE773255D8B6BD41DB2515C23444463616F14459536703096F595E841B93AE455B9F37AD2E1A5710C83042689944C5C4A39F944E98C07D898C59F4BBB9DC8A4AC6F3789286D8B61382994EEE1C7581B3F2D12309FAC0A1F5B5F02D0C4978231D52D57D3D56D8F12075F4145270A3DCAA543A008F8A39D95FB555E1EE9D2C9F1FF557FB6C38BF4050B6F59C51C02203046ABFFD51745EDEE1B5BBFCF7A9BE1017839CC6A4638F4316DC6CD63009360ABB2B6B02818C542124B280E18A74BAEB9273B3F2DB8111CDA487DB87A18DFD16D380B037DDC8E60B5F1874D37F704E1A8743D51259D9A778DE571EB1962ED8A07B641B21C274BA9D1385B6406CC3D8ED00B697FEA1BD10967FE481EDD332EA30619655E0A454D58E59672293694DED52C791ED09E2BB3126EF1FF977931C0116B67C91E038FC70C382B28DFD692B1ED75A3B3753D5859A46AB0159C7F9FCB7E6CE9CB91C13A0A3D243D53956E444E7EA734724D45EDA455ECC7C3C74B2A2C4214C7D2B6B66B1BE97C7D6057EE64794EE0130001CFB597BC8B5C0C3E4D159E76F6409CD2C8D6ADA7F8BE816992B191B80FBE9835BD3EDD60CE62A79141DDEE46673B189A0F1CD0B103A66A6B42A3D9319B92761BC8A54F416AA8942E780BE5B70262426B11E3AE9EF12B3FB3BB884E3E230471C020DE7FCB92091396817AB83B9A7C40D53F580AED146CAD8C64BE7E0B5F84F0CB35A2731B710A10D784874B5CA4FAA3FFF38536890F3E48C5B6BA96BDFD22A8C02FBB2668D16AB52BF742D79ACAA94893C81C108622AF5B4B0D1DDAA009A2B1205B02D1B8F754134AC4A92E0669278A0FA2119C62F9F75763FD76CD4712D04B00042C00BD8E4DF2176918F97D83C03DAEA19FA30FDD16E1F9FE534B444C7C4A3E01C2779135D773AF35ECE0A3CA8CD3F3530760059580980DCA09DEEE0740F5D83D69DAF36A5A92D9F4096CBEECAED0816CE1326EC1804C54584E8C28355E5D00795838907B20CDCFCA4FE18C0D3D6E0DE96EC0A6C502057AF96C61A265DDD8D874E4D42289FD04F9DCDA6C270E7C53C3A2B23B20AB13AA8E3FB8B0DC77C0CD0F00B6C2FB8A36D935356E10D51A20E53739A5BDE93F96B49ADC09AEEC0B35EBFEC815880A56DF5B1D110839A9BF7946576E33C226964F6075987489DF3A7C0B574E21A219B670E074713ADCE8E401969B6D1A5D2EDE0F725C0FD829AA435EB3F4B9E689061C92008547F4AE3430B259F557E1A2DA041643FE2FDBC8E03286B50EF73D6DCEF0B9C6C75AB40F1D2F8D4CCB6725AF56A37044A3933923FC2F32378855CC0FBBC0327F25C16C59285BD19627CEDA13CE715E35A689B67DBF61C3B45C48FE507B02C4C2689ED5CA3D76418E3C2FC5269E3525A7C122A0FDD0E00CF4F960D45513C049223084BC5519B028F17F94A3B7CC1C407618935F248C3FBF0678F2A7A05E8A1911059264409A8801BBB80A3AAF8E0B6D86CFB3775F7F9AE87152371C6216947E89BA04EF44E8AC304B876028DAAFB54C3FF067029F15AE768235BAB8F854009110645AA801B2904F6939014BD76E5AA510BAB9D5AC17BBD536FC32CB2B4505A47D8679AE67DA0304E4982F03E22E77068A23B32192A24569D40356FAD23B1D79E40F17F5D2B0DF23EA437EB2371CE2C7278653A884FE38AE0CE9D9C60F97CC88E3CFE5AF1AC3A1D22079BF9FC2B42435231F110DB596581B44FA7E31265BEC9FF7C86EFAE208B898F36302B66E409184EEF82DF40FD60D6A4796C071C088BCD95E8F8AE857047BF83CA41EC4A845B48E5631F85192FB998067B0B7172E575D6671917363064C08CDFF23CA8499F240738D730DED8A79CF015FD9FF34D53A0B6BD0D1DD38B32AD0B3585FB99AEEB5C11547B8AD365269FE96CC855E3E7E5508930A639D82BD105867396D6074A6C2330A35967B1914FB52AB94F44E3DE354D8349DBC86E444B5165ED20376B11DFC9FA5F51F6069FD743804BD04222E22A79B54603AB0983530E1101227F8BFFA3A24E084D452E1DBA5B5FEFFB23B9842395658C38C7970405E17E0E8451AA188BC920887B35917159F83D7B187227B26B659D168EA4A2C8FA6330D372DEAFACD8854852F313618DC847C56832CB2A3C8029C5770F7D7D63CD3109EFD2725F24016232028CB1666DC9F407040806AE63115BFE51D2BD2D74286B205557C7F58F7EFD4755C53E2BF24F3D9F97E48ED86E2B7689B385BE82849DE6CA634963F2782436ECBD35F58EA3CEAF50A452EFB16F6072FA1E9A10B3E948E5F2959C4DDDD89921D4CB0214AF3149B7FE5E2DACBD9632720CD06B4B210350435F663C4562424927197703D7ABCF4F278C4335C623C55D8021B7A5766854DA7AC210F25A326F84E0BBDA83495D44BB923FD32AF32528A68F11C7557F4DE631DCFD8C233F473ABD54C6ACF3B3E935CD6942495FA61211CC158B7C2FEC84F923D6C4F902A8A19B46A931C68F420260A477A6C3A28B3B4133634EB5751E3A7CC46022B706BFBE01A3E062284C2D4A8758ACE690514B137FA480676B09EDDDD309D6F52F94B2D0287270CFEB1A6E663B762080ED4C4769BAE6C168CBA07AD79B1A1690C5FBE0D9A05656D4E52466C906271CB7C023A72A2F015BF869446FF35E9BC1A59E23D9928CBD1285512AECD6C904CA47F63A8747FE79AC8438D6C26F13FC4549453349441D959B66DB25037127C036AB356C8CF79F99F10BE8502734CD91CA6ED2F543F2C2D5412CB6D16DF798204510CF5A17E6E33397B38BCF4BC57546AF7824C0B4DC7D107392B97730CDC0F1528648FED45BCE3443A44BDF1B28B31FC8FD17A1B4A737CD28F927559FE2564A3018DBE808D3AB4A4440527825D2013D487293AA875E5E911510CB8B56B04099F96CA23C62E72C2156EA08B6C7CF5E45C869BD2468AFA718C7E3B73C6D02C7FEAB0AE69C233F0E46E57945C4D4EFF7796285E8988B51280323A8E89CE7BD8C068B0828CC0BEB77C0F44E28C5E75A21853AB9D8159B0E2255C5DD8F5746F924E237A4A8FA3745F5CA39814EE64E7EB1C94DC7B4A2889CFE7A01690A89285DAE12AA6CEF45805714F05BF0FFF97ED82E51842B099FAFF2F0C0F2C608FB3CB6E069D276714A21D1AEF73A870159CF5C56CEB3403D96F4AD1D413D03583985068349F73524D66760A17AAAD749931870581BA8C576FF6549661A43529A2145739AFCB3BADA0EA472AEA14986670A97FEF749F520054CDF4820C191E5D94599D95A9050CB45B6E8E5FCD28816D331F21FF06EBA6C0DDC495AB8F1BC645386AD1EC65EAC1FB4C4AA5FB8A301BCF5A04A7D61A8310804475CA128824C767426E55EED148C766181E2F2573149C2AA36496563A4497DD9244F9B17791AF92489B0BE38BB5A778E679B93BE4BEDE0C06B60A048955A0F598FB16256799ACA1CFA818863EB852A7329FD13BB9177B8653E3EB32D6C40601AC61F69FC91468737480C6C8D422755D2AC35E410D7504E07DE414A7FAD9A00CE495C84452ED9EEE7817066DF613156995D4132CBE14F1607FF63BDCE71849C7E3A20B5F728EEE14DF98C950706E97F6C2E340300431EF2A6E0FDD9B2EE45139C2DC66FC4FCF8231A86B9F498FEBCCC3E87F19DA17D09FBC476C8CDF0870775891CDF0C94411FC686FBB54C9EBB8AC22BC43AB8A72528DBED5AEDFE87CC534E3127CFB22784BDB2811B39D20C29A0FE79061A0CD54787EE228013EFA979413F8BE983F7D9EEF5508DDCFBAD3F4AF8526291A1840BBBE247969C8EA5218778571891783F16D84E517B7CC7F1A50999A23085AEA463EDFA3AC16AAE8ACF4670C69437821C57349A12F561A87218BA746065666A7B76EF92EA8ADA926BEDC8F25F809F4E747F92B7F16FAE68EA88BE10542DB5ADD7042E8B26115E2A587C5BE310684AF723C6BA4BAE47725FA641BF4C0218F5315E5B2EA0D89F0EF"""), + TestUtils.hexDecode(""" +CA0104B9DF99E87474389167359968A307F63AA32F0C804A96B18FFBE00C748B1D6894CBE2B7BA06EF17B6947ECE31DDC9F614348F01995FCCE77099A0D88B2BCD1035667631991C2BCAA4C86B4D31074A2FD46C38429B52CF0BFD7CD3E5D194DF22E2B0D57C0C9D624C772B54686AC963447E716C6B4DAFC00AE383CFFC69A2F6F931D616954BC9A140D785F15C5DB28ECC793D88C78D11F8F8452046ADDD3AD26988B21BF895DC810739FA7C45A8062B2931AD363B0C7EAB4CCFAC71CDD0DA3B54CA9A6388DCBF79AF799446395DC7A5B7ED1788188E9D03EB3BF7B80F8CFB9B7F33DA0D4DBE1840B9C6C5D80F6AE64487BBFEC86C596E2ED8E721A11D783F7552A4B01FA24F60B5B683E287BD75EA0DDC15314E014D402F527C5DAD74CFC49B4D824EFA77C359B90AFF15AC89C1AA35959570E2148DF7A09E27E2FC096AB5CB306B4868AB80A24DF745DCF9EDDE57357866182A9AF50796EAF97A1A1051FFE6F9038BE1F6239CADBF0BD81B23E2991941F34D0851AFCEBC4D3F8B472D6259CF61FFDB87F79928C66E69D969B254D57541A87C692160E5D58A837A1FE90A1799758A70F958DBC1BE5D6E6836845940C75E745245FBCE59D1F83462B9578534D7A05DC3F21C34EA93ED78387B32DE09ED3CD2A51EE2B8F7387C8C2D426EAF3795E99B158D467D9A039234FDF207D65D2577D1688E1B1E72B5EB096FB6377DC8EB6B3F51900380BEA561C03D546EE242EB4264C0369AA2D53B2B190E0422FBC4CF896CD549C2A08A37070331F15A9ECFFA0E91B1FC4D5157418914308EB8C6A992B197F33DDD517DF4610E88F2E35E505BA7C7CACB8E76677CA9B39A4094EB4590F6154FAAFA76C1D95D4072B5CE01F42355C47AFE569FA80142EDB49E2ADB34D3C356F4D882A52021C5216B3678AA6A5D52C51CC8BF09E7EAEDD2501A9886FAC977EA5F385F46E8718D39073D8995D392074C2525A4ABBE228F531E6B16AD5BCD5EF5CC4C3C71AA77EAC1747E2B763D0B3D66C7F35458BE43369BAA0ABED23202B733B3C7A111F9CF407A7D62EFF5BE3A5DDC3E49AF130012BC6D5D3641EBF268236473EAB09BE87BAF7707546B7AB194D2ECF5B03A56662B1D6462898DA94747CEE9DDA08A9026538D799F163E1E771EF7EADF8833C0510104FE7AD7EE75F44F8D4572E299A87FB17429718C576B29983B50FF81F8D48D41CC764809429A7CFE05F68168B6B36FF66CD75DC0021D774D07BC716A74F9450EAD2995089FEB89D1EA73A9CEB83155ADBA737B3DE33B6B617EE7F5CB6C6672AFC439990B612A6AE71540FC6D7FF535FC88DED0E6A80A484735F63209D39F12E6E129C4ED2EDD8C8B5A24472B83A058B0F1C86B7F4C53D88927C7E9EDB5C40C5D6C7F0ED8A626C5F35E1D3981936F0F1FE4E8CEE0FC7F66F0016B14F3D1EAA993A5DB9B92C03D99C0A867FEB343D9F43BBBBBD85F58B2380811CF153FE66E5B5DD07D5A87ABCADBBD472692358777BF17AAFB622D487A100062465D9BFBE0E63B9D862A02F09E371EE820D969B29B4E6F6A1120CDA9F9E3FB804B26E2E9C3DE219044D1D6E62A28CBC90C262B76914B8929465FD901777F6F5C112D196A002A0F4C4FFAFD2578B5CAEA21452968400DAD6490E313D32A708A42F64E9CF412EC0E358F6B833EB0190C5933037202C266ABAD212B570E609FB7D338AD3F850EFDEE9347EBCFEBBBCE90E7F27372E244C3F035D4ABF1008055215E573F0C4001FFCDA5E6B6C5B29B7F59132CD86481FD0E1245EE4084DCA3D44A0C9E6B6B14E1BCBF56F470F15609DE76588795D5CB62BFC9C253EEFCC155C116D70CCF9112D8E0A801A3C640C7D16634EA02DA9DB9AC57DC2F7D43F48ABE631D3438C2BD3EC97832244E81223EEE47054878BB2472F64E9ACA0D5A8B0B04F783C5052E0ED6AFADA5274C94084621E989084EF9814128226346996CEB6FA07FB957C7432878505442FAFC4D945A953336F9C92B8ABE4E4A092DA65E2BF1A7A274E1EE9D7958E35334D9B7CF8B314F0AA5C45E93111460A8F5409C0BCB842DF9C9887FE4643BF8958CDB40EB66438BA53972E359EB712BF4C553D871ED702F74C41D1217D7887C891E49043C0826FCCEB2897BFAF9F217DC9F566DE1C416DE9118491162113E2EB56CDD4C024DCA4A33359D88CB0247BDD6802455063DE9666A4C52075359316B3B557D42B7C99700F55CABCB2B802AE4209C6B937C798433AF94159A4EC0A7DE00C809F6E6675A4213A1CE8A7099FB7FE6A0C7FB383233444B64AA120BABA1C4E61C6426001184E897A3C6B0BDCF9759A72146EF848EFA65EF09076A4FF2E6DA518C5A08F2A2A12D904C893297234E53CFFA04F285F350412456C9A13E153421D65DD30B236653AC13CCE3D5CF1EBCB8AB46808414BD3725987D6E464EB4F97321595153DBF9994F7E19AFBD19E9BE929D18563789567B28B1AF05BDB5D2C5C289FCBE8EB159D0017E09DA8FE5E9D49D3A231814778370DFE703ADABFB175859A895A6ED86F9B6B52CCDBBF936622C5E5A01D50E2B6D5730EA4588680EFCCF390211F211472F9E10314482CFB45A24706BBCA8CB515B6A9AA6EE1D2509E8F9AE9D6F545BD3971A02CC26699608FE1F076A925008AB6CA8576CC5A962326A369BDA8ACED3618F02BBC55337FAB2D66050514F904083D4386B43B6EAD553DF5603201C6D684F7156FBD2D3DDE3D7EB0D569AFD42886E57B747F21D44B88AD58FA2370FE6BF2DFA4D94D8FF983A1C2B89876E75AAE3828D1306DB9A639D052EFA6A0EFA0F61737CCC45E0C516815E92E256BA49E7853F9E9D4670593BF9402E59EE80F6CDFF8244D156FAEA8220D483601794A3CB5E1D7B60DCF991A545D2C72F62E5EA05BEAA77FA86A80400A07B97D8159F0EC170913ED885B578767CCA7A5BFB8BFDB7AC99002555145D9DF5011654700D6FBF2EC2BA609C969EBECFCC0EE346FA01B6CF07E6855F3C832BF1DB6E247448438BAEC055FD41CDBE921E5F62D93F4E7964258A9CB3991E8084BFFC2E5B29BD1E32A64E32BF5E27416CBA7FA3DFC143281F3797E1927AE9D9E07FB424833A7911C23F231D676EB0FB061C179C72FF0038E48068D43A805D56C3B6A16F5A2E5E8457F1A3E0F927A8880CD261F0D0AD8F82EF0E52E1BED003661F1D4510F7BCCE680CE84A0181F046366126A53EE67C7309C6982C28966B6CA1F324D03F5E09AEB111486C44B6551B1C36E84C2A72F78AEF5CA31AA66EDFB0792C00579C0C7C1FAE501735706CCFADE03E9A0847E498A24AC1DCBC7DB8FFC946B8D914633559B63E3031C214414BCC1921D2A53726695340648CF6C2BB4FDF132C77BC39E9CEB2E4D22EB138D807D7B79F78CD9713F5BE7512FD32E73E886DE16A9B1B19026B91EE6AB92DE4DE663D9774344B283149AF4890BFA57ABD1C9DFF128F9F169E4CECEBA0FEE1C33D4E34B877EF04DC887F7109B2BA65EF5732ED4B7C6B33131EB5867811D4A8A3536102F5AEFCACAA681A6A45A3BDCB24C4FDBF49A134244044E2B424996CF6F3C514C77EDF2AEC177B8F80A1AB77F6D3D920E508C76EB71ADFE2209A132839E9BB16BD9991A545AA0587B7594E0422647DC84CD355B20983AD582324D4F19E33E9CFA5CEDC739B26F43BBAD1F165720306F48CB15B23B961E5990C2DCC39E5BF58A9BFC10829590A7AA8F60E13EE1DBA85EF5EB9B1F6DDA891ADF7357E16CEEA4ACDC00E20F8F364AE3EA838CB4A0FDCCF8B439A242F8D18B8E0B9FB8E074922E0C25922CBEC46C98A82E93F0E95884BA9853CC738AFADA3F08BFB66C17DE7977EB7CE5495B8620B537B49D1D37EA4B3477B79759EC7D9AF17EFDB2EF89945D453BCBDB349CFC623FBDB8F125EC492CCBAF30006523B543B6A17245CDC5EE7E28EA895654A5EA74781CCB0F30343C73B4BB88CE07BD37DE9220712F11748EFACCE925626FFDD8447D37BD9CF2476437C093BA4CC0AB674E4CF9543CEA67BC25B9BD56946C0D077F0849796EFB74C7F66D5B86CD9A38B8138D816F677CE08DE6A6A911BA4DD1834751548578CEE4CFAC50C11D685E52DECB77A475FF5468C38DB23853BB2118C78AC3D52079042FB7F370B3D0406E402EFA6432D3055C572C81DD999876E8306021118BA87D5D430E4AB9C24670EAA1274ABF4BFB8149D9067C427DCC026A61C5B724CAE1858ADE366FB42CEE52C36F0F99AC02E8BDF784EBF311334B83B2B277982519DFFA3AC35D97F9F30635CC17BF8E017EC4E209EAD104B52C58E8762052CA62BA7A82FD011860E4F298D889A11F6A2BB1B4157CDA42AF9CCD0B5324329A92CB9FD6EB81DB3FC58431BC5C9A6DC1B07F7D2B00B32E5A39960C5E2CD69CA2914F23365B518ED746B27733D713E8ABEAF9D1FFC6D3D9B601FB386A6911F24CC818C0353658CB826F43FEEA792055720065601F1364BB6184699F16E3EE2B359CF0642C85E9115B18E55482356E2F91121C5884578F3D2C45462E47A3D477B3D63448A8C1679E68F9B7AE509100B7B2B142FB6BA20179E599259414520B02B745E592FD10D0D40D780A95C164D651E96A7052B69BBDA979216989A57506638F891336E2EA123303F997194B7AAB4F22CB192AB59A8BDA7CC88D0F43E4DD949146006CA3F91CF28535ED42662A61F630AD6E7319A7B98FF5C7200FECA768F14BFD43BD60DBEC814E22C26F1A8191ACC869A6BCE61991E4F36148908A5B1557A507C407D73A6FE75A548CBB8CACF13E57BA6B01FF0DF900051AE7C0C346D5DADE5F1C1BBFF967236BA5BAEF19A70FEB320BD76035F3A6B11383F13E6DCB8D1533A6529C98334A3F2A9105A5CF1C940659459C405C197130EBA44F0A2881B4614B7A0BBDAD5930DE5C3389A7349265629E29C0123CC89F3F540FE5C9019662A4383A38248F22201967D908EB48D530D17D50A08B35FCAB73AE8ADFDD72A8A7551EC28C7573E2B33EA4F61EE84C3DCA33DD5861B8FB7176C4AFBC174250D51F86B1452903191E39EF099C0CBCC15B3FB5DD30A2822F68AA37D59583BDC1CCDAB1B2E0337BF397647FEA9111A5B94C6A3369E90F3B86C266F4C11C9A7D9E24802B31B5F93B8EA9AEDC6C2944965D6B54601311D251E81C77AC1BB2159263D0A92F377F111DBC8D554C3AF747FE7E82A6E6BF0E4E3743B7AA42C3B5B8D3E5D9C3B427B3290452136E61592609826F4B61D4960B7C3784D0E2508363212AEEAE624489B739D0573CE23B35D30826182DB5F4D09772582E4D6B61938041344EA434614C21B01530327C08539A84F03275D0C4A77FDF230FBE6639CC7A12C34545C5CAD34AABF8E25D64AFCA8206948737DBA643867A146F17ABF81A926294E2368A5A2F0C381E2C244B21843E3ABBA680CC3F1F0509DFAFF4C70B68C82D3D7EF8EE053DBD154376FAAB5D561A19362314B037CFE18DD03BB817444FBF08D771A13B9D745DC066C89C10ACD53597B74916BA719F9EEEBA865252FE13EDDF97978092FDD1524CDD865FD6AE9C14329EB62B322F46905804AF1CFFC13B46B6AF4ABCB107D44DD27B460101F7A38DC786239E34CA9D1A444898673BB3DD92EE88478A3C539A563CEAF5CF499AE8E07BDAC0CD5419DEFE2977105B5E0138D84A8F9BFAD82F58884377B803C8B68164A3E678648C18127A832FA994EBEDCDE4FECE85DAFF8CD6F44F4CE57694522DC30BFC492BF62796D05A9B87BF13A7D538EE5C55E6898D50ED127E8C12F87D160AEEBD3CB126BC4144A51F685079E962DB6FDDE3BA6D0C8038BD6FD8377C4BEFC2EBF1A876833516D206C2E309C61E4CEAB5F86ED83FF20C8723BFE63D8E480798292E6EC6D418D3CEB623AC6983A3F8A3AD568F73E408F15AB88C8F56F3CCF5B32C76BDCEB1FA41357C42E1215CC503A316EA0A83FB341ED6ED20B1154E5001A754F92E97570F9DA7EA8AB7F2EFEE7B79A1DDA705645ABC5B1E04CE4F922BB03435D11FC83EB580CDFF7EDEB78F2CEBBB6053410E84477864C16D4CD7CD9D16B932372FDB99DBCCE2DC3B5CDCCF7DB86AEC9BDCB8E4F27B65ACA9A3FB985CF95C5BAE253797C8474D0C25F0FFBD151E6558E524C6E96267677EB7A3E128C918CD3B09F1DDE311401152C62B4C59EA1D408ACCC4A12A34664D7C0858D7E99A0327724AE9CA55A9322D865EFB4FBFD37FC79F8D7B2BF08B1824D44777153ED6604E05DB1FC9B1ACCE05F8C53C32594A84F32D97AE49E819029204AB7713AF2AF2C281448A34C69D5F3DC76345031D2CC05B6B26303198E182901FE65710EA95793DC8495F1995F0196DC9473B7AB922786BBC61A91868BB0BE05E2034EFFB288502DDFE2595887CCD144E98ECA4D1E0C044C642396F98473BFDEEE796530467F6B5EC0D5B79674EBDF5D1416F94A8EAC7F4833947F1DE610029779CD436729E55AE3D959F99D5438E0E4407D0A870A38AB31E08F16A06345B7BA730CCF55CF1FDA1E9D04833ADE5FD74A34E2629DCB75A3482312860404F7E75D94D7FD2C8215C6A21BD5FCAE81CF4467931A984AA24B927039526B95C2F5F39AB2040A23C76B64CD2D04E95DE6DD9B8EA849F9F7919A619EFAC498E7E3F4A70432E28B1C5DEDB08D122AE503E98D34D13A4E8A69FA267C3E20671077F977F71308D3EA1AAED5DC33B3F41E0ED981050B3B915EDA07AFD71CFD3AF13A2063813039BE85EF98706399299118D2427A7912A131DB7BA731D18DC2838A116E05C4CBC660895294A73D170C060CD83C9AA0884C5F3FE52F4891C2101997D688709F356A556CE202C571E1170BC339F3E2A75A5A13810E3A2F2133438C1705895523D03F00BBE4F4FA9BCE6D7A14517BD54E281F202BAB40DF35253961DC9E94DF5C2C5C3F0E420AC67A85BEC2ED70545B94202AACE5E58180104E42C5AA6F7F59915BEA69AC10F678D40506AD2B502D77EBE4D05CF8253B4795094F04BBDFCC8033EA131BE83F3F647D22D1212C16895F52FEA576EFB344A476D2A8EC74739BA62632C4B5B08076905BC0103CC9B2193EF6C4785685F2B3F79FC39B5ED09B258E5E9BD346557F24CB542B69A3ABE367123179879A02F941F9781935D44BCABCC563BB1F31C44BB77D5E7A4FC7EC2C11D597E7288C6088497DCC97910CFD8245A4F255CFBCB8FFF95905E8224B770E910A253356916EAF1B3277D831BEA5BD6681C6C7D57D363608EE78973B7BBBC156FE5536C963030B6BC8D306F3C1EE72F14163DE0DCD0CE741EF975A9DDA77EE386B991F3096FEC95FD394E26578269F491572B36AF42CEF1D86CDC82D63DF00AA397E1960378763F5CED239BD2A6D0EB7C5BD7CDA2228B684FA57B7FAF497310D510CD386DE6406924CD592ABB1E9753EC8BCC594ED52B70C04F7C53E19B0CB607DEBA79FABD6748A52692CDA34BB7CBF95D1ABBFF8AEF8F8AC7E5D52EF58FC79B0C7662DA90A0F737CBD42E64B648B624AB497162A7B27E41850A9BB4AF0489550773EBF1EC6742CE8D53A20921149563AA74337ED4CF1EE8685F41D36F748B6DED5F894BBC50A8DEC84621B6AAE690D6EE0B392A7266A480CF985295361B14AF0A5CEFC1EB737ED3AEA5E5894FDE80CAE477FE742395CACD1174CF2B345774BDDF71853BA1854EDC8F5CB03D33C5F58EC386ECBAC8E4209F8881473A4FFE306ED3194F455D4441D132B7685425435E58AF1F2964B657C71EB6E28FE3568183F7A0E570821EA49DECFBA3128002E77208749DCBD3F5E15453AB6DE9EB313D7445377B3BA74BD2F67AE31F560ABB628CA0DDB120CAC6CB62EC9CCC65051F70FC41BDCDF29F885FC9A558929F58CDE1200072F96C3D8F22032A0AB3F705884F0D827823FBDB62FFAA39EEBFECD9F57DA083D1ED541CF36465A999558F2299A865456C94D67E74F1EDC7166F91F4CBAC8F89E680BDED946A174E9260DD50C6B0A980A4B886850797149FCAF8871AB3080A76B645E333290A0DF319DE058981B8CFAD7A54FCD62345DFD9C3E6F7A26D212C97FA6F09866E23D5A19EB9CAE760E876B2AAF43BDF9004D5CFDC41570EABACACD4B57662087B6A91B6249CDAF905BC2B1AF5934F1A05D20E6C6784F0FFDA0A3E79A2C0939BF36C55EA0E31B1AE614D44CD413118EA165FA549026574D1549FF7D63B4C464A896C5C0E8D5569AB2B10D1DC56458FD1E069B5F91B1D084F7AE34F67ECDCBF33299B12C102F953CC48B0661AB4EFB493F7E4B2EA8F6FE59C3D5EF7D121B26B912B86BC0AE987B6A3543558F0B935AE62B4711A586DDAC9E5960C48B99CB80191B11F4053527905123D20C549457BA87608948933442CB06BEA0E73FE99E3C4198E9E7C51BBB7074DA46E752E46B3E419FAE2AD60D180303D710C0A59C6B980B24F0BFD39959368B5F56AB3845A2167F4683AA82A9613257BC801F5146CFCA857F2DF4FBEA85C54930D4373F70C083F661077567F1173819EBAA585EA3675F97951CF8C9997887BBEA9B99E17A1E0215DFC2B9A66760A277F68E747141AFE5CAB6B25D73D562B91BADDCC7938F2EA75F1C990E88311549F38FCE2C52933498B22E2810227D1EAFED4BEABCB153324622E107A6D96214F3C6D5DB91855005056A8D1BC5D5518867C373709D24DC1FCE21537C58999E26CDF4FE61ABE5E1225DE80F98D02253999F39A145FF3008F12880C173A7ADEE15025E3E186FF0C2090872A0A51505A09094FA2946AFA1840B0D6D526DEEEA95FD8E259E70B2E794C97F50E7833B165E7BEEAF5D3CAB7C3AA1CEF00003B94159F0F6DCBC74808E3FF237D5C3E94353FC0E700CAF48DA8BD94B991EFFF2DACC9E423A2AD63824CF879EF838C784C7D4C0CEE3DACF5884941BCC14E043082D382AFF598BBE0321DFE9406434DDF558EE2BDC272C2B04CBF8CEF92EF8180D0FEBD3D62E1F73F3B1E7FB0EDF9B50538D49C52CEE53F3000E581FCD7E6FEA1CEEC9DCB4876B3F1D1B1A301A2D395DEAC54D68181406D7ECA05A416D3D8E0EE10228483D8515A0F662D933C53F945B50C65C5B8D51EC45360661C92761A1F74EE06FAF8889244620DABA05593DDD4D6A82A30F34DCEF50B1B1D261CC357AB0673370A38DFEDEF3D591377CA29DF609682EFFA212092ABF84FCAD677DFAD758575CA35046467C6925B6185F9B734D5E194F5CA48DD10D0B84B7E9096703A9EEF0D3EFEFFC0F58C4D38D741F15AE766D06156B26E9C82B464C9F609F0A4FF699D52E0E11E054738476456CB81859ABE457F3595E9D7F1CFEE5D0437094CF093F468C79C093CD615F7409A505C610169010F46E148F3D264FEEA1DF42B3E78D1C4B33C92EE9BBD9C508E89BC4CE0BA0C412F75821EB54730FBB627C6C93694810CD741167D5288768165A68034CE2B16B0E73ABFBF75A905C9A9E577024EF2070EBE8A68076AE37BDF3507C7CB10EAE13D3A05BB3DA33F873F488150CE67AB892D61A11FAF5850B6A26862FF0CE85E4B0AB3EEBDC81F68BFDE39B0582185E4322404A0195BF5951BF7CDDAA6530DB0EFA0A2E6B2A9CF8DCD8B0D15447448847D1EB5FCCDC80EEDF166988D55DCF3BCE37E24A0A5F302F820C2782849E70BA47523A7AA1FF12F144148E9B5A1E05035A346FC4028BDA824B8D5FDECEC4036EB2C3A7DA612A703EFBE4D5E5E17CBCE1EBF546880C227EEE2D9CA4113D0ED61AFA70171700F0F9A1BC7CE7807A081EF09E9CEDA5DFFDDECADAA7CB5ACB2DBBE26550ED006C5B7DD89A2585EBED5995F8F76F3EF8F13B6AE77084727DC894C74268D4D91000155FDC94DEE049E54F4E4D2494EF926F23B73E60EE16CC3711B67B6F6B3A3BA6BA8CE602AE1BA87ACAD58650AA8F7F0F36AEA21080CA8DFC618AAF865B14BBD69FF7B413FFC81DC6C8BF2A7B122EC2C13DD7832610DB9E6EA0E5CACBE1703AF551997E6C51BCE7BAD4B3EB1F392EE12C5691F795090C6F1D6405D0E682F279B3DE64A9F45B1853346D8D337FF8037370CB4DBE5B241959FB8DD985A4F154470833E422AD9EAD7A14EC1CAF6308FCF7E9AAC13ACAFAAD98011148A2D52D40511CF13C7CF0ED1E320617B908BD1A6A442FAFB2E543703844B0D40FCBD1B392CDF5DAC9CE4C2CA69C8F04AA033F5D6D11DC1A5667FB352BE6BF88A9978AAD37B01BF8652A2C475E8516AE1A6E56F8CD596B9A780864ADC65A04F615ABB2BD4BA97301FB0CB7D9AB5423BB14C29030DCD5345C54D556ABB116051C04D79C81402B70AA9F32CD01B6C06FCFB416C4CB7709CEB12DF3E8BC541333C90E6D991B24D7D1D98D0839AA86614F3D91ABBEE5DF138A9DF2C0591204FEB3D9DD546305FD017B72FCA4DF01A7C1728606EDBA07EC101D7172971C9F4ACE7D6D09E06BF9E8552A4CB3ABF6FD84FD350F60A3E1826BBCBA484D4B5B284E2E1EF2A164FEDCD0D22AE77026C4A6596ABCCEBF6ACE68C11ED108BD3C"""), + TestUtils.hexDecode(""" +3F1A9B8C87C0A08481C482D90D252CBC687B25E613C6BDC311BED7FC59BCABBE5353E8094DF52017277C5EEF17A07D65A7DE47EC40E127A745EBCABE4E77AC5781ECE95BBEEDCAA01914F00B98F04A6147222843A4F9A4F4CA0DBB5C26B530DE04D304FEF6AA5F3EB1789858760CBCCD9AFECBC45E02EC93827149960F8EC0867CE9D2F2E46F6DD8AF4F959DDF9DF7177BFCD67C43CEBC559037CC88772567E6279CF261CDB891631CA68FC3B88F7A5EE03C964810E29943607F890FCD81F4AC0554EC8FD304741DAC4A0F156B66DDCDCC7D12BD563B2D54411891CA94CD44F6EB127A7BB3C0FC51A06597639C97FA4787D4C819817A8100D9463FE92ABC339426B7C57670962575B37934E890F6924F95CAF81E62D42821B1B4E669320B4DFDFD8D213C1CA405F9540D3AF7776A3265A717468685F0F3A08A22E60517C6DAADED6AD1365D90E7D91DFC8F0415810C7F98406CF0C24A583B13531B52F3F492969B198B4AFDDA5340F059D21E8F5A830E1DE4DA51E17BEBFE8BA1E3B9F6C5222BFE154516C1C1143B96A49E04DD99F56F047E781FE925171D83B3755DAD89C361CE5D4A11A7E9C37C245BC6B3315723EB2DD15DF385A108C719EBE636ECB6529D6B9D4817EB011FD6127270831A097ECDA206519842148B029A1505849118CA06FD01FCFE100B1644C44379AE47442DABC2BAE7F342ED79B26379D50C0E61A809EEF8B7EEED4B403407B44FDB7E683EE3F85881BB715266F87A96E6E3DC1FBAC1715D1581CC3691729979E97D577D8691A9AB21769AB550C258A15F4A432EDC1E18669999051A7594950EE013D95E269973762E66808BE560D9765A104D4351F118653BE7F425D0FA9D3581724604028FA8A4D35C6AE687DCC0B55C915D75E5C590366713AB78A2AEA5C1515F36651F85B2997D6027C8AD330D914F3DBDA26A1ECBD1A34125342A32B5F432ED6E8EAD0E1BC5796108F5784CAE34A3207973A13044699B496753D7CD4420A8F45D71017C2439B773771229633E08E076F1AE5092ABBE3461DE11AAFAF154587342D3CBF56939B19DEDBF0A612FD3880A5B6D2EC518BE04D81B9F183250D9EB3949EF4B7A7EEDC4021B1A4DE20AF1B5A1633A26F3D1789C1DB42F379E4E16F1C87922B095B5751F8FCD4E9415438AC7F546B1BC000927A06A4BDDD18AD62B2E829C5C2E464F178D1FD9CFFE82083FE84CD61F5AF373D10B0DD30B151BECDD8FAAB9E185EAAAD459EC55E905B56417F5AFA8024B6D5B971D3F070F5CD513E85712B171D7DAAD6A47351279D4D204E33D6479BF0747F7F895117DC9EEB22552CE829DB8AB67A44E035748BF41C5663A17A1AC141DEEA02C990858508C62BB05D8ABB8825713C954C509B67D7A56259172F25E3EDFF8EB356A818233DE470F543152FC9AB0C0F2530FAF9B1B0CE6BAFCE2FAA46DDC76FC90F6B658DAC93263CDDA34294269AFD2826B2BB6F71E1608A6232D3CDD09BD5201FC7589AF0059ECF3F0EE167289A6C7EF1F414532BC981AF7D44B1F8787C4446D9619505B11E6F60C0C861C66291952A054DFCCBCFBB0DD75C9A74B0CCB3C0AEDA3A6D1C1C1DE0E494FF26133CE52A64B397A7DCD547F88F4F327750039B2EC77AD56E4D1A793A539C0EECF501B8E8186CC5AE6DC5CCF0A14964D2CF1BB83A974780972B2AF75545B9266DB1B3E2F052E15758086BEDFC5CD42DFB3E1F2DF6DE49D9CDFCC990174F52C66993AB07E66B2658C9B430E92838E38ACDD02CB9302756EEC3CFD74D92B0D89C90281A93ED479B7A37AF9D37A47F8E04B5B261669083F97062DE23B6C52EDFEF09CCF65B8F32920E5586BDEC1634009D42EF43640C26CE938B2BB5A5E459B74ADCBACC76A2BF7712509553DBC30F9D73EFA20F95B225808F22101CF4A068D6E1C1C64EC656EE535C57785296755F757722E897A53264E63A0311A13C6E47120C3850992EC703E98AB8029B6E29EA7246882D9083989C093382551663C570012FD42DD97EB86FC434D359B85716D0084844D185A1FE8AF8C90F17510F0E1264EEF6709A2C0E9A840F49C6E7E2984241DE2A50DB152AA9D43CAC0E7C6707B55BA44D18F36E2F5F89BA46A5C1E195E0860CF5B3CFB1C4C71A0A53AA1A1A83DE888D8EB9CF7354B361EBC37DAD4F9D0F96CDD62D108DA793BBC84761C5F29F24910D736C8C9A70DD467DFCB46A53F880414CD2634C2E8AC379F2C29F52167894B6E9BB41636F93653FE4371555E061B711442BFF93D04E0AC20D7B4E92A23D1BC77387A7679C688436D34CF37132FE336FE29B57F8D792BCC76C9B4F2CF048A2C8F9B3AD2EBAD9DFEF954A55978078AD5DD59189C25411717BA0C59AD2C89C7D58C6758019B3A134EC32B8DD5A7C90DEF509DF31AC9DA19BF136DC49CC8518CBC0B193D2A8D7681A1A8A6E1B4FD96896CEB085374A81C082C3EA606C4113C85E78C7C72945EB436497E5DEF79340B64DF13AC56123980C2B4985AB0F3DC4F1AEC2CBCD47B4693AB4DBDBB270F5FA2B7BC4A69D77B96164DBD43055A930FE97296034718569D3DD151CE0440B94FE8A2656195AB1082BA64881CCB1B196BFFD86584BECC610F9751DD29B0985BAB0DDC4D0583C2A12BAADE088C6A021A437989BAC7B72709340B4BB12E6FB9BACEC05EBEADE26AEA86ABFC225121672F2687B08E8C6CD87C744C62F65AEAD52EF3063F8492CC7DB1FEF69CFA96532001430BF131064FE5B2EF71BD65FB69F2E1187B34EF659AC499FA178B969E49F494A9FE3D0B3DF5BBBEA9E852D4A9587815E199474DCD774F5A1A4922E9F403EF9A56D79BF8D20BFBD3D3296757A29EE30F3A8DAB3CD909E8A50A775EE2BF33D136DF4234E7D44A2F5A4B8EEC945C6BAE494D35D24BA70122CD9071F3F7B3B217BB4B0C1035301D4BDFA7FCABED5E223CFA7C5420376B53EB97FE945BAC67CE84DA6E9E3A6BF44DCF46B5FB35957A30E922793FC47FB59AEE2808BA559D422208180F437108128C741F181E3ED84742A122F30B420CE3063016D0B8B8EE07293DF269E5B4A427EBC108EC22FDC33BCD7F02230A49B6433BC4E981BA5C72027398085E36BF72C868D3FCCE0CB15C8AEDB801254ADDA850EE2AC97392E36084A8456626131441587F72CBFD1974C3780875EA246CE93FDBA8757591A30F00900B9B9E07A77469D03897DBB6F52F8D6ED02F77469A825BC1F1C276D75DAE5307C3A72F09825C761CF44A9F78A2085B7F339549F0905DD0413211BD3A82961C5AD4FE88B9CD776640E38434392DF1510FF9F416541502FF9C81D0B92E5F6A6265A982DDA7A457D943F05238F3EAF3EAF88A6C300F1E6F800BAD8FB08CA1EB1C5655A5ED869F3BB7DDCCE5EC591A2D19A043342D554EEDE81242A9A3F0FA55887EB621684235398C15C5AAA9962361E94C223BDAD1D69C87A684390771364A87FBB854371AD33E80AD569753A389D7496A1A7682F1265C77DF9AC5B629FB576A4C0FB7954EAC01F5A94E213D1ECA6389D8F4FF9C4B768812E675A38870729756A14A7A17EFBA62981F03BBFD55248E515BA5913B770576652CE2836471C0A831DB7ACB9CF451CAA0CBE56F6FE0C84EBC5A551FA3C68C9C444D19552697E65B7A5D9535E7A6E5B1D322CEEA4F7DBFEA175EA716E750FE8BBA057FAF26D03F83011E92672E4BF4F1336FB883CD21A2AC3AAE4D81731DB30D794B04A25CA4EF2E389C54C237B1B142987383AB6F6FD7C527E8D3886ADA4F3DA08A20F33E252BF946424F058BDD055338E9DE72068D5BE75A06A0371102C429E980233157BB1B0B5DD1DB65248A9AADB3DDEC4EC4563E6353CEB01B8991D7E9A6B8C80519CBD8B06380F61A920395E4D2AF2910184870619F5CCF4E8D4E05F81068D88834CA0C64D5B91147A876A569BA0E23D430DE76B1A0CFC70B22CF4110423328196D2083B03D5791D7D967A82FA7DCFDED446518CA4D29BFE3A9B0CDCAFBBD4C74A5AF9445721EA1798C0219E9041A2543F31D8CCE862454F0BD361FFE6BD0B95D51C777C430D78E226E124C7A0908895C78A55ED6B0E841DCB6B42C8093958699DFA5F0B82F0C94697BDF822B7A94E1607FE85A801DC9626117E3D2FA3D9D828706AD8FAF1FA130B65400A5256EF7A174953D2855BE3FF62633E0C3C533A322729D5327AA103EF255AA3FE75A173224085BF3984A9C0E1DE30D08B04FA841BB0CB0C2C3C63BB3B8BF8310673200F2881AC80A621AC51DBE999B8561164A3883F022DE646A95DF2EB6ADC8A773805A009FD8BC5F72A758A109E4C3A4841BA80F27789C29E23FDE6ECBF23DBBC3C12556BA32737A2D625045550536EDBBE859D02279DF1A8DDAB731E1B2AEBF3F84588B21D109D9351BAF83E1AC61F990C564E34768025FD6124B0D8007E5D4C0D00521684EDEB739DA51D3A793C6DB364CAD8AE59C8D479E66843204675C8A6A76193D5BD690E349A27E6E55FCE7D20BA1460DAF762A0033CC54D42F1F387DEFB6D5108A3153FB43E425471092E882A06D34A226EB259667D6C85AA63421048C17B2E4E0488F5E4038EAE9C5D4198ED477470E4E4C4D4734AA77DD93F7172009E4583857501511C9E40C6D22ACA8A16A968F3C037ABE0E31437A82150EFBBFD7251EABAD03D93B2DE6159CB2B432802054AD2615F96552AA978C8F8F5CCD0626DAE79BE0BEEC69BD34C6988F6056F4FFC5DC3989F14EA6A486BFB4ADD7DCB960D25F71EF515B024CC9898EAF414EF07744A98F0DC3C3CFC91C4BC381238DFD67A29BFC43593D3A38C245E5E2077034BA8A646202AE547115BB40A4B4CBFB7D47AA6CD628243768F2E2A4A3B47B96ACE2E8C3E23A646C129C9F8885215EF0F7D13AE8E64D613E84366653A5DF27A55D606F95B1A44C56F40BDCAA60405E1C02D42D72F391E7BED3C7455CB3A26519DB1AE24D99BE9DEC4AB2119A6F05405C026AE30FE263AE13623F9A81F746DF4A0563DB49C14BD19BFABF1FBBBCCD6B05B565D9BA16B86C1F61B24CFAAEF2EAEB52D92CBF130FF5E49D834244FB34D478BB20899FAAFDB97C8901B11E906263A3F353AA2F87D66BA6DD41337D2C1D05819BEE7D215CC2B3ECA5E0A3A3A71F7FC9845FA2751F25FD292C37EF96B0017101E3C250AF43DC4307C449069E9257BA1BDA5B823E2343A7B1AD61EEB1BE94EAC4E410D7782AE9E8A75BB54849C5764C45935C6E4B2948BC6F72C620574096D57C14508719C21B02F6F75291A669740283303DF20ADE6A5B3038E82DCB3EA9508BAA297D8E39C56E1E1F98A20D57AC893DE4C1B59DCB35F1B15D2B923CB2ECDD2D793DFD3254B4CA3F8878E04CD301A1AE8177103E2012D17314D9BA9DCE0A05FAB6A7E23740E713DDA18574C8BF8AF2D116A16BD17367D5FE9C0C6375260481AD70E31FFEC9F8B9F63E5BB0FE6A4CDEC6782A5C62779B0B1ED0956865D963F89541D0508EB31EE26ED55557687934D2DC9A1093A5ABD5D2357672578D1E914E9329BE8CC1C6ABB8F82F1A63044C3119AAB980C1659FC7CCD04041EB8749AF7222E4626A22DF729D0B878A9FC434F7AB431041EBF49963F7F283BB5CB3FD433BD75428AD445B281524CA08E5ABD1AF6DB75208F70B06036399AB66BA84A014377685275BA2672A5016CAFBEA373C6176987232967F81E97156E1057F45ECDD86FE18BC95C10B3EBC7665F879B100ACDC4989427835F9E1A778F3A1E39B4FF2BE81E9B30B4F605C4144FBD8312A879436C532A72E6308BB794A2D69B4A6ADE42EF39C484A494A624909AE942BBC0C36B0FA7EE3838459B3C829F8A636FDD8750793ECFA500D04F10E9075957EB063776CEB14048861912D60DF85E43FA2FEDA98BE9FAD55E1B5A177D82933AD17C5B5913816C90FEB8509C91BFE8199AC75D66AE907430CCAE09CB2BDFFDAF40FF4341EDD45F7EBB55DB6A8691632D06D1DF6AF6974110322BDE9ACBF7E07DA4FC7D6C6D300B4CDA1AF21CF5EF780053BC38C17D418411AB6574D4F3F5E9426014EDD74DBCE26C76A53A09C6666B399DF95307F82B98264E45A6C158C7DE95567E74D67E8AD591E296B67EA01AF48C01FF3A7141F817C9B12C2A73BAD5B36694DFBD15F7D98DB91848A373946D9A1CE2955BECC1AB0801FF4B2F00256E3F62AB684B7D5F251260454C97FF6979E8ECA36F2956876009F7FD24A4FFE9276544C40044CFFD26C7579734AEB496F4E10DB0C5664300684D5D8B84E7466A4F857560F0AA1ED6916EAAC996412B4CE27DF2D877CD899DB377276E500E89533A9B70934365850CCE9145811379B924846C45627521E34AB03366EE128EFAEC353C695A1D4F13255D1393722CC03252B814890F7281C5A4BEC52A39AE4AA2F07565BC810DB4C32606F6864618E549E496F8712D45BC2B289200776958040B6B47F8A93F341DCB375994474059F46767F34021E3F424768DDEE1D2C3F949ED5EF3D42568597E8F309171F2046B7CAF00D1F2C88B2B7BAC1EBF61B36484C71AAB9D6D94C4DE4F900000000000000000000000000000000000000000000080F10161E283135""") + ), + new SigGenTestCase( + TestUtils.hexDecode(""" +B6A445DC4F4638D109DAAB0B266BE84079A7536E8CC0598C04202D52A38D74A2663D2C880ADA729C99379BA01136A54B662CA0448D19740139F17FCD3D713992C3545BEA8BF149CC7EF5555BA739C80A9323261BD623B40C7844CC3B513FCE137AC51138544AF6C55F90EF757EA51472036D12F01E5D7EC3109C3E04C91E4F78209808DB8285C104884884019802924A9690DA0046C3A064600631212700E22264CB008191C42552422E100671A20884A080458288511CC66411B4315BA05121232024968192069010124859202583C6881132651B991041A668091871132322CA4449DB38021338622222869AA41113A73182100C9344808C107002A429CC1251191220591800828268093711480230A4221009271010B741190941C8924000822D88842941846490322CC8B840CC000C5B28908CA85124228CC416908A228ED0C445082760C9948C53C44C40480E8198515C8864C9B6200C172692063000004ADC8271C4304A0CC9250A098043040923002899A291831266C884640205000B94859218905AB0081C81491B156A0BB8401300119334011B26050A445092100D0245091000924A168980182E14244504446A143366620849A01400A3348583904D514480C39864483446122180A2484C1488095BA400841484D2248C649425D188690BB4519C181224992823316E194320110706839809CA30850C960150464DC3962CA3A471CB462C9C448E59C230D9C40C18972008C41018C7300238921217911CC3445C025220390861482164A26911C18853C24121130544482110306DA3A4904A462D20352CCB264A03985021B3055942681117262120716288705B024888940D99A061E44091888051E0B824CC086C2140514C10449C04002236820240104A082CDAB28D8324408C007120C589E4002DD8C08C9A24045382298A328060445122204C814871830628C416099AC289CB408E4C9801E0468A2011451834240B0790CC1406412882D146311B398ED3108C12A221DBA6201908861CC5400B090053367119A27101964D1C857012A605C83232A33861403490D8C2108B122958248154224693022E484060D24672223552C8120910264913802998926519458EC81864118688423022A14232C1880420454089288644064680C28DA3C0800B078012428DDA200E1B2080A4B691D4486A5BB4004BB85161B44102B32C0440724A209023822C4C46695344219844049C367019C1111B904814C605884289DC820D50946122B591D91009CA164ED3406C0C936D4C181001C4014B8824002112CA042809146A1C920C6244842034255920458BC671E4043150948458A48811C38D9C806504C9012016521B9821D93051884081232201D3488812014CDC9221C2183120006012995104B00993824123158120960C80C02D5B062108382219C72002B10099C424C21402D4000660306E0CC32DD2383113C9840314024C06490C219040262911382182A048C222724C28898334220C2846E30802DB4442221229C326111BA808208644E41620D8400013C80D83044D20283260080401074611018683442EC31804581206132342C998901134815A44901B26415A480A8430480CC89014B7858B002CDCC061122611C1422C44363199360420A9804A04605AA285E2B431E3086251166191824D41C02990046218B270404608221381C3B03064A441412292A3B0680CB80C00256AD34686919240D88029C41681001380D1288C1182811048690100301AB5901B0406D148425BC26523B08110152543006E8C268924A28CA342701140800C0126004406D026465C882DD148914A420E9100500B02318CA8008B38521C21520934121A498640B2210C9991222308E4B0314880699A8630DB40051C41259A32049314815400529094510A396811A68083160D830001603664CCA6242182850CA7600306661AB84993208560444E51948442122AE312100C0472E2184002B921C916464C868990B42420C20D03858519A068CC34044B308943B20913236524178548B060D42662DA0642604604110070D2121013C750D148716100099A049294102C23146D9BC86C848260D0B045C430222289695BC24C1880091B322D91A408440682A410641A256582C070A380298A48285A406C62140180486E083780249284A10042808888922082C9808840160551406423B16D24896DBCAB7827992C8BB6CB1790EFE735E25FA69A53857EF72C747691D235BDAA8FFB682A2A5835AAC37E5190412ADD9E5B91DC9513D2DBB8768978D32D3743156EDD38082F2C93C1C82994969F6719035478DAC4C0CD00380FFF08A9321B2E3A14B6A4CAA808A562B0D02AD7BB4DB593B318E55DE21EA3EA6828E15F150C0780097D0C576F3295C2E27B63139127E4302D7460D6443E1D5AE1B9B5B3B806F956C78606809347647DCB91331BC57D9C81B48C480138EC80A7EB9D623850C96843D604FDAFB611EB92201771CC4AF621C4CAE9A8D0CED827C6936BCB0CEE6E82C2A097CEECFFA25C62E713C9D9AFB571E42F1145E1D618B0A1395DFFF5F07291627EA5110185EE11B1DA3EB2DA29EC38596B47A70F34430C373E3A947E8848DAF8C269049C551FB61B25C704E5B98E44B39D34448E50DA0522F290328EFAC7BF9AD912579AFE639221AAA177673AC83563770A1DA92977DF8C7AD850437F0E77DA98747DD9968E965D5C1EDB47645907F0AB59C4374C0791C60A8BF3C447017E45A9BD4F2705A9598312B5AE0DEEB5C4F9011665BA56B733A2743EFCE0C9199D575EEEF740AE78C1254CC6D486509A26711742B5022DD0FEE1F440DBFD5C71C11FABA95006FB234E648395CB8B7F047D4112E08CC773043B848811E916520056F19198904B38831ABC6DE68D5E67AE340C08C1BD05E25E6325F5D0A38523DD12731F9FB134AA252376E24EF10CD7348BF0C2859257BAB1D09AD45023CD569C8ECA23C0E8C8F9159DA852A9B09407457F3AF0714C849D649275CF166344E6CD4367812C1ADB0E11F3DFE6A28FBADCA7AFB683E47A8FEFCC018FCB4D51061C8854E07EABBEAE2E0CBEF1F8D6302230982DAF37310E9D21F84C2D660C9D3C5D09DA8777634BDDCA0A1E720B8DC8132DAE59C3CF64D7EE262B49888EDBF98602E55F5B5A3D2CAD14438EBD8752D6C93579790860D47D5EF94567359A77E56B866DD04B77A86CD4A2EE6A21A476ED56B8A750B47907D65DE6F0FAFBCCA5397F125D519669E55BC5D03445594217141ECB649B0600FC257B8327F4389ADB0D6EB9080A444713CDE66D2509D9D8AEBDB3D6743580AB42568CF6D65D4F26F494D9F12AA89E5AE3146FF08A4EDB569E77CF7E7D238AD9F5FFA5082CD024676B010B245306582999936E9CED1DC493D8DF09F553A7F4E71540F10F75339E63EF17CCD3F9E857E17FBED81485C5F21672194DB806A66E4CEE58CB4BA9CE150506A8D139B044BFC1B985235AD526445F067BB4B458DD652475CE873B16BA403F4D2357825BF8F98D45DAC29376670C925616FF8FACBE01323607017A48E6D3CD18C78505BD0FECD7934D7448B5DABFD7C48D70A21B89CABA42ACF2FCF1C3EDB44A9E9C3CBBFF2A0B11330CC5E03BF8244F04F97A1014677BEDE221EB0E5BC64A8ED93224D517D8F525340DD0E2DB0227A56A3BD803E078285BFCB40B53F2980E3004ED1284D60A604D0FD420B83638020987E42433B52A31F052E5530029FDB0F52858D41D2DD6DFB85613D7BFC3413015CF544494A4EC1F21F5DE05EBFA829FC6811544F4B38E04BE93378F981006EEB92DFD62C58F2B8E89A8FEBD5F26C58B4D638D404382CB0084AFE425F056C6CC44CECB80E2247C51C20CA4AB9451060626C594CBB3CA5B1C3506E8D52906C0B5C064D35459B1D17CDE9B0A3A55DE2DCCEA8B71D13BEB28FAE7122F8F92355E247698FD95F5B954945D4DD7A80970C443A9577BABBB8886D7E08DF0EE7CA01935F46396061B3CA9126BFAE452235B04358E9574263FF5F0E052CC87095942C556C8C03A04FF808167780CCA0F0D9DBB9656BA066ADDE5BF6BB87DDDB4BB86E7CE778BDDC9CF467D621C529947DC47740AA21E275186F4DF83EEC4126590EE026C4874D67C60CE074E0F6CC3817965BE4BAABA2D4EB77D42DF37B792DB71882F5B10980F433B9DB158DA15E5EB9587AB568256342D82C1B8BBD4366730CE414AA25F7E97E4A0D27089C3A53EB451E51484C257F65D82A7F64D72267468E45EACA3BB5180694F842723E17901D4846BD5138F2F88DAAE1C79D84AC7C24E3CB72476AADA1AD0792DC4B031FFD4A35FD3F23960CE912693C67E0A3DB404979ECEF172CF8FE7D13D03D29CE3D57CC8D1C51690791682F68AF6ADDCE013D085107BF2674580D44E88D47B052576B6769607B7C285E85F5C4A18A3EC2CDC93C7C74289F769FE703D0D66231AF23631EB88411AB57E21FA1CBE2766B1DB69A6618DF0D9E85CB0D4D0AB001B47349FE49A23AEFCF72783B6FD9AF26F5863587CFDB320376F094D5DCBD6CC32631C9C564AA6A585C7F1CF2B4FB30F8ACB2A4C433B896D1FE2236584DE464BC17D680C1D4EEF6B561BE5516911299D7C7346228A41106A3DC9E5B4E75C8F04EEBA3D36227494B22B06D578DC99F8ED068220B4C4C791F6FCC4C8D9C2B94A7B3FD9930735A00675549E648CBD338157FF5163002E99CF94171849FDE5FF7530F552AF54A95E6CA4061A6556B30FB1385621253CE70FED7BDD09872165EA8740BC1E303E34F69ADFBA16CEA146C7ECFFD12906DE24947CBA94D068DA7F51B5E854CCC6DE513405A28D9CD3E409D33B70731040A7079CC3AFC2E502B3AB1C4EF1B2D514EF445EC99A530BB049D4F8AD7F58D55FA3909F76608CC23FF704586AEE0AE9050EE5F2634767997FB39D44688E949B9C82C3B605DB878D7E51941F8D9AEB66097FA206462F5CE7F17093389800B239B86D0ABD79B66DA99FD0C65E3A3183A143FE9B45FB85AFB57F2A101C9713CE6C4DDAAD90BE6731679DE7C72AB1EAD6CA954D350B9361FD143159B45C803420AE88363C327EF31BDA33D2B869857403615F20117AE708DB5235583E06B82B9A5E7B81AEBDEF1E696FA96D76C3F6388C4D1EB88EF3F9F7A95D5B9F446AC7C27D1915717FCADA4F22458FBCAF7D4377F2E743AEFA5246E840A96F017E139125851055A1B98A91D9217207DCBEC227D23666E76BCA0266566EFD0E2D735498A2102E4D52C6FD758568CEA164E0A28B67E2E2907BA6F63CC049DE87E61771B2095C6BD2D58D4A36055FAAFB51B63C3F9BC06F3B27F5514A9663950A6804A5D34C8E1BB6C924C8BFF44BC217423C5FAEC7CD56B61B746A0AEA7C37EF6C6351969AEF292178B75DC8922DDB935717C897098CC41E150E7633C91F6091969F19525FE257268AA74015EE2AC93163799B03785E14E69A87FD0776A438C01DD829348D6FB825DE7D2B01815C115ED418E5C132074904ECF4FF06775ABA0A498B1627CF49D8ABB68D3CA440517FF4B08B0C4B4845022A2462A0C1C5B706B061F406507094311D311ED0A5184AABF03B0B0BF06C3FF55D778F280E9F3376504DCEBE4B9FA4C4A55D93D7924EF9CB5849364CAF92DC3C5E198A3D1DE5B139C13AA39E9545959D6D738C1D88288A908A1E7DC3ADB26DCBF02D9F98BFD8FD61A6A96FC4534A2D212B208C48DF6BC95BB415932AF801B5519E8647AEADE54B68539484302C9B5A416848C2F10952D1A66078997E56AEF14FA8078FC8E35E1BF3BFEE35C3D91C31B0940E8218DD83BE1E633E649712241C61DE8FDB1B84C0BA60836F95444EC81A48E591BAE36FE7CC449C9B88F6298F9E9588FAE54C40F661A6914F001A75D4BC6280E05643F0A114C2DD71EE8FBF3D7D4FCE18CB8F61A6FF8B08FA1D20378922EDDBD2175A2F2920F434919F0F9F1AD7C6ED5E0FB13EDC924410708F7973270A03604A0043AADAB8F0368871040B418E74158CC4E7358BEBCDAE696EA38ED155E3599D06F86552D9556C39F6A435770AE62878C4FCAC7E8E558BB85EDA22D0DBA818AA3A6BEB5958D05520AEB2ACFB1BD403047DF27BA63B34A42ACD3CCAB700EFF0B6906D18672340F0B6E2842E8750366885E148AE0E5546D013427ADA215A4809C11590ED8A7547131880460A3179BED70FBED4A1C304452C1AAA8B0F6C5575C2F60B6E0AE93E0D7ED699A3B039A61BD63AAED95E4822D8D55452056A266D391E444819970CFB4BB767C6613CD0C65B259DF532D58B2E086BA9A36BE37537ED0562515B6AB8AF615ADDDFCBBA355363DCCA60F5EA2B07E59174053D6F29892CEBC4A44AAA4971D19171D2029854FDD977BD357D54E8DEB4DE463F251DC566DA73AED7170C402D3F4DF466CA5BCD8BD47AD1A499B176E39F4EE2FAB9C7225A3B98700787B73CBF36C42E934D0EF96B3859F980020679FFD83F106D609278C3DD780E2E5DBC262D9DD8250D7F4A24DD27F3937382B8E7B2C3269B6CA09B522D0DBE4CE098418E95C17FF32EF99F016AD4EC8EDFB7028CA9F85ACE4976A6D11E90E2990C762E7E4845CC7C447ACA8907C94E81CD6E7664755D378030DBA0208CF039005F433083E1E904F541B036E03F7C2686630D0E5F8785FBB33E03566E8CFD19056A4E6D1D277584EB20C8727D2C79D910F12610C003F90899CB6B5231D2B3A5EEDC0355DFA7FADBA5C949E9B9274E9DC69579C10DAD85552CABF32E90870D9D0CF579348F46874BBA064E918BF4A279F55984CEA32649111EE86059406CE0B0D50E4F52C7CCF110A5E34E01C414075CF5B31AAC9F504E9499BE75CB3EC35C2C19F7794769BBF34039F4AEC85C48E772075B887B63A5C81595EB4D17F2F25912C120623439E93482032C20F7CEFB0CDE27B2799EB945DC28EEA9B94A0C4C5592"""), + TestUtils.hexDecode(""" +D46F4482D570F26C7E9F0F74A354174CA145033097CED3896350DFCE8200CB9448F522B118698DAD51F6C672E1B12A412DB6B7B95CDBDAF6205DEB631E44634412F026CD95440258FE5F0C72C5F3E64FB3FD13E545DD856EC2B7F51AC28C0D5D698C66C700DD3E409BFD96E14A9DAE1677ADEF2CA2CCD178B826AAD3859E569541561073095EFCA329B5B216563D956D8B7BB918224FB479FF7025FD8168F54D14ED1FDF0B399130C6117B5645D0E8DD242C3C7AEC6A8361361CAD9A8FC3B5A40BF7E73F1BBA9AC7F5A583A5B0EB95AD0AB4C1360D0145FC2C3A9AA50186D649B72B41DB7EF392E663497B3166AF9BD0C1AE21650D6CD04DD36532AEA0FD1071D6E9554CBB575B2C1ACEA3DD4E18615FE83AA211F8AD330C78FD32D920ACB40627CA4AC80F840A64C019124079484B053F525A5403383C21B164D0C6BC1B462C0E1C269A1EA0B2438FA64934CEE47149C4EFF566D9C2234E656969C1C89A0B0A4DE124EB920FF534B934172686A18A1A269960C725940D3307B8A913D56B78A6CDCFD559FF97E225B61AFAE7F62B060E7D3E2D4040D8D9233A24827434AB4EB31B0D528CB0085953D9A1A0FFB748588A2DDEBF241F93B41F5C856159EBBBC6571AB12F4EB534ED3C624CD3F5F836A99C7E6E2FFA0369654A5C07C19D44BC9FAD96983660E4D6F95DD9C38D84DE11271D23A6158B685CF050121425AF91C6FFEFD0B2061F54CC4393F99857F3B9775F81B6526444AB705F9CB88A2D276AF2F530B646FC3D93DE7087EBC1FBC7F9A8DB3F3C8FA186F7B636CCEF99FDC4532E54F560519C94B79B1158D85BFBE23D4F36B64F8056BEE7558252DBB3D9A43748E2E6A338162F5E2BC0934E89DC79091180C93D340D3615F82E7780FABF782E5FE2B5D504F3BD1874EB5DB76CB616CC034D9B2B080319FEB8EB97F62FA4498878FF049FA97C56ACACD2414E0BEF018F25A6254448F02E64815E525AA06AEAB53969A66D453B732891E31C36679B5C0A4637611A5983F21F6D4ADA1DA5E890C909A9E968F947C686C17EC73A0F9BAE5C7BF7433133F35F22D2A0B40CC135A7591E2CD216F7D8018969940EB9A5C4BF21579C524C41AFF5DBC0E141FBD02F1BCF376DFFCFBD06F9CD4384E128CF1F03139C853CDD04DEC61EFB8F1DF1A6450E4ABDDDD8A9D85BA79479562A08CDF06BDDD2E740DE7AD9AD1016D72A649A73246E8DAE183AFCD6FBDC64B6B6B2EFDDF525F3B764CAB39BF8D617D47FD3380B4A30081AE6C3165E9437B2F37A73AFC5E596AA626FE5A32D8873712F99910DADD0DE296577D4749F88639D07F83B0F6A05B1668D8008EA749580EE5A629FC2313FAA2F8ADDB5764B242B6B595A39AD76CED4CE5BC34C580069071BED1F98CAF4BDF740A5B1DE3FD30C29DAD808537CB16D0EF22D937F297F50E1681C898375FE0374ADD6EA1B84C10261DBECCCA8E1D224A4709497CE696BCD2BC1369F4135E815A781EA26A055DEA28AFCFDEAF6AB1117085EBF6B8AA6845FD4763FF9274BFE5FC6E377B9F9DA8263DC1F3D53C83F446ABA5EEA4095AFF91F3BE30022B9BBC2C74FC52A3B15CC76F29E541A84C5BF42D499F9B5EA134E24F01E8D866FCD20B7F7A302120B13DE636F48FE8EB99F17ACC153CE4371B266CA61D13E19793CBEF12C0EBA9C728096A3DC6A6750DDB0F52E3807C22EBE4DC6B2407593A1B7BBCED799DC3EAFCE50B483818D903765A63FF572F5D4481357CD6ABD89EC260417306DA1CCF71DA568240D4FD6858BB7833B2C9C98B9E7286FA491F9E318F25D0459071848BBA0D3DB8D2BDDFCB7B8E9C64ED67B4A2B5E1E49B55C6DCBF93394010A078E6F52065AB777C7F6D831DDCC115CF316ACF3680BE8766B4E15574AA383030EDA83CA45B965836FB2374695B50472C4159CB7980FE48B58B40C6CDD2629FE3C6DE6E13ED6728FCE45024C96402B78BAF37E74A1C071F4BCC2A1B84933C872FFCD87C02DBE65438A3E770903A04DF96C569FA69828CCC32D13A0A419FCCE454F06EDE43A97CE5A9A169C6E849F075C66BAB418791778ECB2C158FC19FF5927ADFCA90BFDB3B4216E19BE11157E858610BAA373237B42F811EA97EEB93D735828B2ED092518160A2ED894BB108AD74AB0113A8D5882D99A06CE2313BEE3F902D5CE9CECC835974A47FCF6FD1648C635FE56D1B2404927C49EB53FBD625E0624D5AA04D6C0D5A082C37BD67F477850458B8672C408CEADD9A55CC268B75BC51D7B3D75668D52BB701BD980ED22CC20611EF618277B82624A1192287B46BB5C4468F94C68D96F3CA3ADED476A18BE6CCED70924139F2E16C8A54FD6C9F6695E624499AC8E9AF86A430AB856924A0899E75C1FE4A51DA0DE1588E66044B2465C04809272B2A5C8EDBCAE42B47E439FAE06938810526DDFF4B64C515787B41885BE369A31F90E2D6F6C71528412572A67DF6E155C3705929EB28B80DF15345E0E32540BA9AB7E1D1CF0C015E50C9180372C678CE6C34BDACADF45B0172A1D3082565E16938F57CE6B55D9A711CF72E362A2ABFD45B7B56D48E89A0079E973F597D2E457EFF423E229AD439C3193C264E0BF9A8A1FB50266AE4E0BB671817CAEF10A3BD43452A2FD2DCBB2481D63BB539E0C81F6986400D3A619AA92F250ADDCF661FFEDE7617162B532EE2088A87F58E1FD071F5D720FF1F72335A5B4582F1BEB3BF19DBC9D51A62CDF68A855F7F6DBBE5FEB226C9918E7FFBC8A38079E411EDB44177F843EB8CC1F73B9765A0EAD825B3C43F6760B5F03BB75DC7469701AE555C2B7037952180255612DCC9CD35DDB31F3A9218397E1924791D29C410D2E4C3F5549B7EADF75045EC78D579EA7948D121E8297BC5A3A9F7AA2E2EF5776CAE3B9CB73316170F9B48B657BBE365B352A8129130BF1E718B386AA27E493016ADA86C4B3D3D116B7252A747FD50DC14AA28676F1C25150A86C9F4547189523280A3A897F80FDBBA073EC645C9953B7F8CEC3BD08BC0CA5640545B08F728AA38A860ED38C068F0D"""), + TestUtils.hexDecode(""" +216B7639BAE886F93D92D1BCB33B6014E962751B281796AA6DB6724C8B546AB7D62CDA401D6B651C4BFDC699EC03DF4018489EA99B8BE6A2D2CE3E442AAB604A02FFA0641523F3EABC9BC8EDBF7C19CF9DDDAB6A81E4DD5EC6754DE75CD071CAF48AF49CAB50FEDD7218564A02EFB0224957FBA6115544ED19FEFC7AEDBAB4832C60B454564957C0CAFBEAB5F71F4AFCB68458A503E800D6807155E5D61D78EA973FBC45CDEE09F5503D428F547D0CEB07E42118D0537712CB2554F25F0EEBE0C5AF76F9A5E88B9966D1504B92EECFB267121F1A988EC42E675CD605D6E58CAF7E9588E7306F64C6F81BBCB0D7CEE234AD2595932E723123EA215AC877FBECAC9D096BF307F487B0C7648A678CD608FEA23162D9F6FF44DB6D953CA947EB16CB90AC9D156A8A9A60EB7781837A71FCA2F9D9835DB909368A5252C050051BD72BC5056797E866F041EE2221836D4BF341683977FC992270D3ABB95AB3665EF002467A136CE28077C9868680E4005EDD8FE15BB499DC2E95846A9266BA44ACCE9E425E6176149F17EAE5D6176651D2ABD7C1B6538A8F26AEEE04840EDD165C8114CA55D500E1B260B2F469D3AB5FB90F9E198ED5A5A7845BEC24C3DBC48B06D6D211941BF86018EE634B3CC7D060A1FC3A38662E704338A197383526D4E55F5C09B78FB7DDB9A38424130D0D9BB3487348FD9ED8D0181BA9DE43EA5B5701C5F9DE3FC88EDF84846C7733651D5653F75B7E6A5C87C4F236F64147C3361E790ECEB6E20CD2482DBE6F2CCE55437828F4F8E1AAD0307947FC33850E27FE568761AEDE63026C167830A20F247CABFD0A2AD01E5799E0D68FA5BC25F0D2F9B42A2B8411B995636D472498990C549E538101D0CD0E29A29FDD5913FAC1B40F8D9B7655B250900DAEADEB417FF471D5B52DAD310FACA606ED22E4C98868BCA788DFA0AA030EE3637B39B3AECEFFABA6B14C733E997C2130503349E6F4A5CC89431B063819DED0C718BB8F78FBF763A64B28D315B6B0B90D48F94B306F0B42A41242CF27315FC69A83DE094D2CB11FD307E1268F976FAEE2053AA41CC2CB6A8B878407076E237FCD378699F5E65856356FC9363F4202EBE78483C4B2C730DA86473CBE588356F353B7AE64AF874B824B8060EF6E4CB302AF8FB027A25606B68CC4B3803EC2FAE996E8FAF2A6D52FA226E684D1EF4E950FEC819515CE9EFFCAAF7B277C5247ACFB57DAA0812B2477B4A18683B98D2BD11143504BC181397ABCAC048989ABF0386A17B79BF73A12BCD2DF5CE96BCF5FB6904D7BFD5283DCFCBD922EC508FD8C591EDC5B34A123857EAE97FE3665B8109E4F29F5625F475199B57F425947F37069CF30017935FC68272A1B18DD7502DE0798CDDA5A0B21E0C24CC9D8CC15F1F774057E77A007BE721343DED110C56E5E80596273BC9507B392051CF19ACB15A3606C452DEB350056CEEFC12A4467813A37386B99C966FB508D0C2FD757E9C10DF490CF600DB6FB3CCEE68376BD7092C03A3F3F60DB1EDBA925FB5FF7802D9C4618E53DE0DE1D8397330D1167D63AF0545534DC5644C16E6531ECE69579013D51C7B98497100308C1750629C8DF81B45FBFAD69F37102D36308AC63AB2D78D2F711DDB691D59BF4C3483652C260CD1A7EDF1E01FFD4E5D8364C69CE247B9F0924E6BD35D358B63B18DBACC7CA1E8C786D1437A730CA2D24FCC92D59E90F4552D490D19A06E11B1AEDE338A3A8D3207688FB27D581FDFE28C42B66240B6C8F5A24D50403FA2FD34DAA370F0504A87F28A4DF44AA86AFBB6D67C9614CE5CDF5C599CDC2C6294B25B641DB59DD7D73DC21923EB8AD68EDB4D0B16B7C16F3161F7C8C0EC493FA9951251D1C5394678B656B332A9FAB7477F32BEE65407B3D2EF6EAF70C1B430B45E104142FA2EF72209FE29558485DD26BE8E1B526B7098F252F58046B6EEB17D7F0734201AD865E7A6B838980707AAC9A05DC8C34E5B36AB03CCB74570670967C3AECAA9800106ACFB0B8EB38AEF82114C2036677118317E339D19CA34BBB68B30E46DF3136481AF7EBBF8C45951C8733C0CAC97E518AEA69A41C641C14EB71D6DE67A5F7C5C77F75C98906A3E5F2A6E875E2B6D7C8BD2A54554E19616FE3E8C39FC7360749B5133650508E8254601A7B33B82C1BA537623D6DAC9C4C3006968EAF3EDB233453EC8DF00D02D022B6A552FBCE8F3694EFE49A7C6088F3080421D45DE8C2F06C312150FC0CC0DA4DD35D25E7F446932406269D45A8358CD1E2736FE2E1C366F24D5A6DC11016FE6BC73447B1562B1C021AA9BAEED212B0AC8AFC337E1CEFF1609EE3F0A7AAC747E185E3D860D1D828B6EEFB93B31C7D2386155612A9815DDD2411541D91B0F99DE4D762F69C91C527F6B5A1BBBF6C8D65E7437F0FE9CCC669EF9D1F36E6E0CC47B682449258673A02B12248FB784AA2B7F15FECC3753119AAB9F77B3C5C677EE4BD54BE29CA5722E37D744E145F9E08A8F8015BE8A56057ABADB987538C0A1E02A9DE66B7666A0F4061A4DECDC2179E3613DCFEF4AE67C66E8F6114AC74CD9464EF29BEB0830CD2E64E9E5D8B547C0DCD1D625FDBC87E8FEC987C5F5F5E3D0AF5BEB341D62789F77851BF2D7FACDF815E101F335944D6EBD0F06BBEEE92B5DA5F8F98B1F41A2463C6569834ECFDEEA395D6D26B6EEE7EA08D261970D2493B86DBEA68663C042FF7791725A58F6B062697AC0724F09660E2E630C39FB7E0568785158CE9A7EF643CB93026131A9EF900E16DBE4E5E286AF8CF89C69F75C6CB32F3BA9D3B779DEDA8BB75193DED6651F452EA9124947EE70D43BDE04965F5A64DACA8CAF2B5885FB75D1847DC07B4C631E57843EEF344FC4B7A3AF886209D77CE5841BBD664E898F939704B7AF6AAE6D55BF3243E7E85991BA8F0C40E843E50CBF16A34A4E67B0C115542D93849F3C511D977B6B916D59F2DC7FEF38542B6B24EF7D6AEA82263C02AE73BFF5DF8110BF1DED037CE296AC8AD076642EC79F76AC62A1B3637BB4F3078BF453ACB2BBD3A9F30A77D01574933E79EF3C64A316935E8B69BAF22FBCCBCB10A2AEE120FC9F15FF537E3C73F2B3E561F5F470311BA00528AC575DB40E162DC23B9BEB3BD1C916D7E83860557DA21EA6C0E55AFD0903FC9AE08011716D67EE6B879EB7395B6F791B6E946DB867F6E9B1F11EE9BFE04D6AB7F294D8CDC6055AF46AC33BDA8808785DA377DC45BF488A7257C1E7AA193438A67E3C667342FF120FA076DB4057E8AFB443C07C72610BAFF2359CA8269C1795C622B7FABACE8599D039593832B46473E8A823F79B973C67183C8ED8F9173604CBCE4F6964265B93954FE916940E540949950B72DB4EEE74C5EB386109C99537D1B0E6DA10F12977320CABCB53C47F62E89F2C275C8D310E078FF098E4D6550CB80BAF8DF93DD77E5B3D32D94E13889C2146EAC717C7FD4231406391ECBC51E9161626186D475AF3EEC30A3FF8D6458D01980BA72AF05F03DA6DFF245DF4D23D976DA87D1B92663B82EBE0DF8A104ED77BD121357160AFF118D76D5A232E92AA1FCBB93038DF7FF9319481E03B768B68804B1BFDFD0DE0E1C58CD7FAA6FAE5D0FDB51E594BE5863303216E65D27B1EBEF55B77E08B4B485576A1A8FFEE4FCF29F71783721B9A4D8BB50D26BE513CBC62C787C7DCCBF0E2601AFB6373C69FB4CF3E50F4542844A266CF19207389C833AC3A03728A4E70C5AC3B4B099482B1999550BB8A1D25DBB941B51B872422FA57DAC6035732CA3B2F30F947D7B8FC5EB53808795695A295D7BA74B558BD0175A8AD7F46CFD6BAE928DB33A9E3B7D0AD554CD8FA09088325E5620A06C824A809461C378823293E0E7CA10A0A1B345EE60780FC1559CA354126F30FDAA421DE4A3A21DE4F96D8CCAEE2E1F2F99F462470F8215A6BCEB923409CBE4CD24D37252A6950C4B12DB6F2942F547F8C646E0B5F4C1E614C5B6F8EA0E23B249ED920DB9DE3E001CCF5F99FB3B88EDF9391833B510DEFA73F26F9155909773188557E57BA3C5268B45933DF9ECC4381377F2883FA121BA0D11CA20F989E16B43BAE6FA5B0D9C74F8563CFAEA595DF4C887E7970CD883A95D9017C08838D81559A95490FAE1C3CCCA7381EFDACDDF486D158704BB8EE0D9A388487566712736FA9EC72ECCCC5F88348D39D07D38ADD76788B96716C5008717C0071C413C3618727C48D0956DDD43876B50BD63FEEBD2692A01A1494AB26EC9B76E428242973AC66E6221D7404223F8AA8DBF1075E703C7C002B67FD49BDC253D604FB7BD38E27A56B9D27E96301EFA75AA02309336AA79D83FEDA510055C21D3A167458E883D260E11ECB2FAF4468D7D648EEBBF4C48397EC3058C163B76C49729BBEF4AA88B37D9989CEEBF3FFF400A1B05860D921440B5AF5B58554E6367743CF61246302D2F0A1EE3BC26038FB52304EE8E9BE69A3E50E7076E17E2462B44F76D3EBAB9761013371436F2564B23BDACC1134499DA39C276ED99603288D6A0FB997882C3257FDFCB71304B942D77987919845437F7BF114D6FBE9992A5B38E4ECC366888A9AAEED48504AF753CB88EE458C7FCC54045D9B9165D2E052DDAEB3AE8F8633174A22231C0013135D824EFD8D4DCA97A86A46D4A64C9E046B6DBAF99C3047C06AA8C53F19283BF3D649819E8E86E749D2C74C740C0BA0251D3C77C6EC2FEB3153D09900C7198569E66D96F40B566FDCE24B09964671E1B150E2C4C587DC97D3DF2F03AF69D9F13B3A387D1FBCD8A4848D9136BAA520E4CD55D36BF78CBAB778FC8DA179B7E8FFEAC21E3A3BD2ED16F332C2A39841A825EC138BBACAA19AD846A01F15B07431DC989F3B870FD27FAE7DF63EC34319E95304CC86EE8C978DEA85A8ABD84F839F2563C7FA7D1C7198DDE5B40FFBAEE7627AF62D7F57E2DA0C08CD02A5DE110C7FC04DF6B493D4656FD03B80E86214AE5DC00D9BA1F34EC1CF95FDC16732422515CBAEA1051879B87C397B10B08BDCA1CBDA9B10A53DAD9B8A13AD05478A73E88A107C0AC73F6C4CC08E7038AD4E2C7F918CC0BCED92AD77D0CE9C7543B6BB8539D0E3B99A7C6BEBFB4F90094BE399DA1ACE5668F5752859388D796B0FDC2161EC01E64EC17FD22C52E6FA14E5D057C78CDC060A06D0B9DE3A4E46E7EFFBA743AB83C14C3CA19554B1AA7232B6724048EEB80A256C7DF100ACE744CAD137FFC541D75FBC0EC762DC9BF26CE87A52FFBC2DE6C079A50F4BCC209EF47A53D6CE5FF88E90DBA6BDDC707EB93501701CBE6263CB7CF6A6A2B69E25B23658CBC94889AEE51D6A16EADA5C84181CC35257ECC21D60D8CBAE2B46E3C69C48325E4785BEF9A119BAF392CB0469B23C75BDE002898B6896ACBCDA44744081479F99CEF23B70AAB1378AB9F98F76564D81565B380D8A994AF696ED2B317379227C28F880CF58ADD23F0D49F829C5D23865AB87A237FFF17DBD23E34E13848F5F0B4AC551D4865A50183751419B67F30E3292F96DB6821D1B788B21880B5D6F0F88C1A9098C5F07F06474B9AADD76733D329355EC6E4A4658C81D4095B8E1094BE2B1EA4D1DADD7B4877F144EA45D102AA0AE7B9962F7BC5B11CB3ED7E9DBF83BE020EBD4D733C448426E7549A5225357C0319F8A690E2FB2FFE33B73F26DCDD461BDA2EAF1CBDFCDE7CC90A5F94769DE9ECAB066CDD158E55F10C1CE3A9B3793417F85AF871AD9BFBC8B02E3A94200F2510C0E61F5DCE3638E6B87F2B299FF627F121CF8DBCC94479A2CCEA282597CD59BDE0294857C98BD6D9066741AA6E4E8BDF83E00911B1BFC947778826022F6AD5377ADF7495F483FB01D7B83C7319E08BC13E6F161A534F5337395477FB7F03B5051C90FDD486B4B6FBE0C963E9650047E32F666FC3C4F9C9B391FDB4FCCF24EC379639D65F676BD686C0030A5946F0193C11759275F23F4AA242F6BEB1BB7C6FF4176F589AAB96C1D8C2A8F73F1D87213CC2AE134DBE1A5EEDBB6155DAE672A01BB621CAD4E32507D00DBA534173F6207441E65118459303DC8510E996A854015C50CA5508B3D3E9596F242FFCDF2440AA7DA52BCDB0CBD6B9578E0CC2FDF1B880C0187E280C4E2FDE44F2365A9E858D6C5197B56588B89131387ABA1B4845E1E515B4CF3C92478B50933F3CFA42553011DB91B47B16B2151DDD6014787F7AB7DBC053AF93468DDE606965BEE41FE7ECE2EACDABBACC069E426320AA26353F6CAF896D024AD9C5C94FBADB6BC93C5579CD1D9F4CB3F195C919D985E61B56B58953BC69DD6DD3D27B7A943D6BFBD86F41334D82E9262F86FA58006DB66433F02284796DD668D27E0E6B4C97D8A6442502603CC859210CBDECA85DA3CAE4D7CF080F9AD820C6CB8B54222A71A13864754518DE2CDD0E168DA6E601AA863FE4C05B08B4FD4DEBA3508552AC014FC3D2C35D264B58871B92A5551A033E40A9ABBAF2066580EF080D2B49899411393F556583869BF11D2E7BC2FC0C263B4C7FB9D10104353B5E6D9BA4CE0613535DF50000000000000000000000000000000000000000000000070B111A1F262F34""") + ), + new SigGenTestCase( + TestUtils.hexDecode(""" +2C242C2E0E18E6E587ABBF3FEF52D5156E92A73F58F15E88501D7F6DD793D6513627423FCBD68B62D99650E4D4859A8562B9C868E08F2836C1DE1493CBD8E24937874DDBAB2564E8B6D5EB098B1A53F1117594BCD26FCC8A464843135BCB424E6AADEFE7FCC8DD6B27A966D7408C51872CE114D58FD4DC0F31EF954B71C322B8D2106E604801D8320A54B004D480500B179144B864590245C236660C064C924042E0904514282CC34482D82245D18290E01640DB428D1B1781233360D3026C12462501230A83084E9A088D0C299019388019366081360A14266E540648934206D1A28CCC300E04352018212224334888282C4832481A1272DA86519C4289118049C2C0411B484E43082D03934081400C01333153302100116E4C402C49268ADCB28022955140240614090188A66801A60860C46DC3A20D9B129299108A8AA668D8986CD9042C1C276C0A16259C4226108569D3866422A729A0240C9AA04804428189C00802C74014C75120B24122A56509058241B451141749882411E4A22118A40CDA306591C28419442D93B481934064000729CB86898AB06920148C0841520B3412088190D2380604B380D0186561904C802045E0400801A07008250102C90D82C4081221620436088B3845CC20664190402429821A458CE430051123251B250220A16D1CA53003244C4C84410033684C984CA120520986481133249BC271513682A4808084346E60004D2194650146501044611815029102405236904A3649DA168209364E5B8889CA120800308040221104A629DA30650C2329499829A0444DC0128E0A106A019028613850820611D9020D13C190184149404430CC226989A24C99343122082004B6098320296098891C30620909880BC7650B847021A0705A928198B05012261120290D2146281930460CA80844B049C0202684C04480A611C248924C140D9C260444244D50A408C8265281B42118A22449204598B8009A9848233400A24288A2360240368044B26981A24D58101043902543B4919CB60D1C414A94902D4428228B368E64048AD4188A9818281BC830A4402A1B0308CA8611CAC405C2C69121204D208460C3180E22264653961119982000988011A51160286A23037109A584C39849E0188DC80651E3127112A88102158CD3868D50020DC8422842C809D2246EC83888DA82812101609AA28DA242651C1205C2042E08830884A26D420608D38888C8146C90C4440B076CE1824C08394618C63181046409418D0C002A231041A23482003408E32051D2C26904B249D1364943C6840AC2245802319934495C106208310C232384C1B26922B781414641E1860CC4180E2349260A094A10031103926CA2A00018130120968DE3366518176519284C50126203296841B0211B04920497116388099334448320880B444E9B000CC2A6518304650428205146898812444BA68C54882409088454400C8BC20D1395915C260918328552204D91B0442029299C920022208662C6810C95291A466C9AC871A1B02D2049098A123118A20C9B322E5388518B387211820109022010390019337249C04113305061046410094420C568C1C48CA3C2489A342D9AA460CC326E4C30450AC90193462ADC025151268444000993A08100C784D80262510206A4046EE4A6481C29609808319328215A289283222524378449B66D64C4450C179101B54191226582824804A024018329D2004593A64064202513B42510200D4C8410DB901099466ADCB845CB46114B208210802DDCA28821A88921920500000AE4A84810B66D18A269E484814434728A244E82322204C270010324E234504C428111220600460101218A20274D1A39259442098C1405CC8660A2B84802300D093490D3080A0080688A2029123008D49891CA48828A82411C002120460CC0B8214232818C482A9308800C928C89082920266419116210454E61104CA0348AE02404A38410D9007080104CD2464921B304C4B02C9BA80583304D8094711221506420925B244944C49023207243202593C60521234243B04901232E5CC60CD3460252C669A0A04D193809101130C9466D5B324A09230A4B168522056612B97004C96C08178D13916CC232001C469082143183220418A76D40C4415C1001C8180EA0A684E2A2411128918B02450CA6098AC48C5A0890A1A801C1428E04B041803452D9A22152B86CFEEC2BACC5DD2E71A2B1C8A14D54A95430380F6D2F08A08E638EA94C74186CCEC154CE3B78A6B0E275C08A5979473509BB06EE8FA6A81AC2995E8373933A5BE90E0BCCB82D192BD1847A7319F3D61D040C12327370BF046773DFBDA9943C3B35CBEA6AA0FAFF2CCCA040BF38616ADF6EBD43D5DBAE2929DA15E0E26EEE338FDBF503D5F6681692C199A67F29A5938CF32E69EE7516B0C57F73C8C4C686B2AAF8350FD84FBA13AB611DBAD7728353276B0DFC78022BEAA249E4EB008447EE55C47492F6ADB6FA22CA3F924CDD0D2AFD8E4C5427DAA832192A3E36EF85808836AB4FEA9E5544461625A956CBC30B086D0FEBF21609361E0E690563DD39BEA5FF7138726AF93D868FAC9FED7866EF2AF190F7D3173ED949A76152993DBC8FBF3DE466A0C56E0AE069B8666F02EB5D7146718769DD2481E3BEF3E5F54B9F900AE8533090C904CB08633CBDB01054D6267954A315BF0BF748824BD7865DDF8C70A6BC0B47D4667C059F75C758AE56DC9939AFC7D71C2F7D12C4AD0BAF3CCDE9BDF0ACF2739FB0311BBD22B3D62381C64C9337EC0A735B7A02EE3E92939F63ED1A290F3D4A495682A3804C3587855610D2DBA663FB73E220952B6C1C4024E4A9163C853C4686C508B600C6022A4CD7793DF69F3F323807E4623302FF751ED61877221FC25D763A18574F1E0D11ECD755E6883318187D621932E0B30627E023CB5EB88C50D8642D1EAEC03F8FA7FC0179F602AB147522F818B993EF6938C02834E8D328B88D304CE8BDD502045888D337FE490CDF2AAC5237CFAFC3308DDE202F593FE3816B95561BD774F25A7EB0E302D08443D100C28B9EDA8995E5FD9C739D348C01FBE2A4DAD5038C052549010A8C8BC4CE40D76DB2CEA946775C5E46938AB65199ED491FF7F57956AC842C4EEA2A19F50E13FCC7F7A5B71247FB7C6B58F1B244EA25472321ED86A5498F914B243C135C8438E26859063201205901F45ECACDC37105ECA9606164D44A6EB2C9E26FD0017E7B6669C08BEFE43EA0F0A737D2A2F375B21E076BE884689477DE6507211BF8C34BD92D54738E7A41F33332B33E6655B66E4EBF48E415F6D6724272A232F85F59AA9B58F3B2E6F43DA613AF54872105FD116F4E24AB77DAA2D91994B45F89B7B79454A0FA77F1B369BFBBAA873D7DDE82562854CC987B45B3AA38B746F05E30301DE0B9E799B4976446D8D08469F00E9D64EE9D7A38854D9C9A6E6A747E77A9D2C526E6FF2678920B8F35C80BF488A87CE9053DDBF829E409A5375A4DFE0AFCB9D3D4CD8555E66E8FDE5438C234A579C631C7190D875EC6FAB628374018A31DB01795761401B45DE5744F86AD954474DD783B37E4942F5D90364DFE365A38F0566322743313F3E75299635E70B7C02EF7A1D36CAAAB4556C26AABC654E9BC194DE867C3DD89F8EFD710ED04AD115F5EF4E11BE33B67EC709DFE2D4ED3BB257624C463DBB5B24F0653ABF18736C6275E716A474F2E48271A5623F80F89EDFED811E5D0F807B3112B53D3E8D8BA71B7AE531A005B1A1BE3CBB87931E7DF937B2A78AEDC30E9543156074434F390BCD8DC83C43F7858750AC113F360DC1B73C7BC3D61BFEB2BA1D417E2A4774A166F3AE220417EA7DF29CC53ED50A1477EB003D3C00F95EEFBAD9D0EEA92AAC088AF47A94D847F79C5E43D999AA75728C9D80A0BEA59AC3407F1E41A0D46ADF15E51AB89A43056B1F578B31FD389C29936246266B7CA17706BBD0DC7678B26C199ED792E0D8488C5E79625018CD65564A77E6A9CD9838F066E431C312E17769875CAD6B77829E39D42A7A0AC220BFE22987D8FB3FABD9955F94965DCE2F5E534D87A1C2CE9962A6B346953651240A005E6D7A3919DDC1F34BF3AEDFF39FA895C842D33BC9B3C86636516F6ACD063FF512121E4F175F4E3F7C5E3449E6CACE385E05814F0B80831757A93C2C680F5682D0441892CB440BD50443F2EB3DDC6C76AFE8919D0DA754FA617F4BB3F07375AFD8BCC6D06E7249D6EABAE6F46226CF9FA61AAEDA3C85E16835E65556131B103B7CFD32FC1BDA2685951418FEE53FE2D0E13452E912F5E53812642DEEE6043C1390D8290D01EFBCD6E49C860BA552F993902277EA1A1C276005504FE5FAA377D4BAE7A41EEBF2EE689A7176E64D3627C8E01BECBE180629F63625D070697F6140F175CB4D61CFD527D3205BDDC38C2E5E3CA1C64C8F3023B172EBDC9C43B228E521584EC2319567DF0736A2262F1E4987981494AB775856D9E382B6A011B61F1FA4C14F4A063D725D5EB1059C3B10DD8108A689268B5A29780BB72499D758D70ED2548879F3223D410F098127179B3F8AFDEBB8C92E7E2E9F5BC3CA594752DAA602179E25524550D55CE8EC4B819B54CED54AAFB27231FF1FBE701CADF649B4CAAB181F786DCCB6B6F9448CCB080F47B58FB209B135B96B34A95A0F29AD629315205EAA1510BDCE86F3588E981FAEBC2476040B2A255917347FEF6BD984163360DC13BFA71642715CB6D75E3B06EF05823F827591236ADF211FD12EA3E9EDF7C33B95266BB4909EDA767B4312DDF1085E3E687E2A5210CAD2F1BFCBBF9D1098D4843B16597D914F2D17807D4743ED9530FBFE3010D834A552146A928B5142C427131EE73E8C1AEF179E70A05B1214BEFC391287E1D2F63F8FF12A5440129FD97B11FB4263CB92E54DACBB6B692CFC93ABA5D281DA468B81A607EED89B02312607648D35767DD52A031FDDC3787660DC772A3B1CD888AE7775E10A483AB1815C6CC07F7C4D959594B2B81010153D242AC9E9E77A4CD4A14A6F2E2A193EF320AD28F718745E3B68B32B97492D1D690C7494430F24EBF7DB4F1F18F94546DAAEB9CF43A2695D420582EA5413A57E2E03C6A276CF2A6E65CAE1D338E3945BCE4477BB8A702F584EB5DFC68EEAA082950878AD334F63FB91107D7763651622179C732B067E1C31B8A48559CB70FF7C31A7BA0A75671882D8831A925289E394C8CBF0AB0D001ACDA20D010CF4FDE387995D4151EB77309B7A6B6A1BDAB20113803046A48AE6D94F0C5CCEEE406315B4CA43D5418777E3C76DDA4F2E7C7A987977107E26F15238220BEB5EC511E749A6296C81DB3442C6E404E085232FF5B412357081251321337770C376F6919FE30C25EEEC062CA4EBE571D81B2A8E5E531971B7EA917C739B81658BD70F00A7A0F19C2CFBA5F2880CF9A311E4E67B3C54C0652D0834C3CA7924DCD9B82AB4A4B3B2FCF87409E547FAF41F40B95D7310CA5ED638E1CBCEDEE449934B222F189D19A653D9FFF4C567EFB366D614AEB8B4B885E401285154BCFD9D3207F166962C25475184B432837E698C4E4F6E7683485291B1E24A0D8A7F3316425BEA502F4DC9D9B4ED205699C92BAD86AB07D6F94A07D9DFF43F6AB0048942DAD6007DCC146DFF6B54DF61A21C77DC01E1F5C06E8B0C72C72DE39ED01F215F7C2A4D8DC15EDF2C26A7D5EF41876DCA11690032A756CB240AEBF823052E450415A957970947536D08A4481FE2D59507CC1A875F3DB2A1503CAB2E10D47AE301B86EE4872DBB814CBF04A536771EE820590434D066CBA98F05E04F067C12C5E04215CD68260383BDCC210C6CF84518BD630C2690193D69BEA8EE69ED4B1743B5F9E9AF874B37B6890E6A0A7DD660F4701E726D323A77A324F80CBF3800AC10A4CEC4AE1C67C65F5AA31E141DC3B4BEA82333F8A75417BDBB8590BAFC66384574DE632740E5DD2B393A4DAD98AA275D14751B7E0CDD81A651403F6B8BE9ADB0B5E6B1E02EAF0A6C0D9AD0CB7D2A3044872B124CC826834427951C48AF0C81488C046F7668528C7F53A322A9285C93F9B2E15D1A988B213827BC607FA79F6136D4A17BA580D4F16ACECFFF037B8C692B32818F5943479121189D2C8BF01674172B7A709E798FB5D903BBF93827887328865FBB40F247EC85D953714315EE33DA40BD74C0BD805E0C3A180FB5D039493730698178BEA7E4E7B1DDF9017835D8F00D5AB81B9F4C81199C5672E54F0FB9A81004F4E7C3FDD51F5852F72ED8F7003718178657A1688200375E419B47021221F6C0DFE0670DB8D6A9094C9D74A1C335E394809ADB6C101CB7A6FF49B894BCAC5AF8F5B866AB8BD50213A2D43F4FB1606AB30642546D071F38AE5DBFC348A8C8B9B606D493FB6A4B0E3833A52CE308C5E0E659292DD69BAFCC5FC8BD480A53306E9CB8CE71FFA1EB96791A18DBC6FB1DE53A3CD50E70225D1E5A386226F3A83D0630DEB8BC954DFA6569FDA606C51150D741B017BEC309E7B6BAB57367DE8CE7526F19C2FE78BBD4091E7419BBF7CFD94606B6C89FC9ACFA3D8D9E1A404CD93CE933A45A920AED24562CBEDB34D3C117361E7ECFF847D61BD8B46E351569B2561BA7EF25E4C9B2BF562A0A97B1105B8664F6F5408D4109632F23862267867E41CE805A1CAB1226CBE7535D1C7A155D03F3885BB1077E8013EB8B685291CF3355FDBD2F1DB43FD6D8E33320BEC59C6C7AB34FFAACDB152CC01899713AA5B6EC98743F8BEBE45A095B0C67F1FCA064C6727A509C79F2FD46F91972D17B52A192186F7F1E6E58654EE8585D2DAEA8CAE2E8900C598A8AB10B56D66A34020D291F21A8A41AFAC85BB5FB10F10B991F772CBA37F7786DE37172ACFA8EBE6C57DCE0A8DF0C44FA5968E2295B5154922C142CA5E2B7B45CD102D33C260D6CCF0DFEF41C26070"""), + TestUtils.hexDecode(""" +78A2B7A4C8441C36E0A9831F65D41773FE6B81B3FA6259A320AB03D460D7E38F4AAB2B93C6142FB0F9584E4D47074670B07F3CC4513675A4367EB8F7F4168F2EF7CA26AC45C8F23B2FD3E970068F21D9A3F7EAF005DB5A7157715CB94F5E83E3C955DD68E0EA689B6F419FACA7CD159237085678FA5883D5330796AD64627CCE7F913D1C2259E1F970E44988B08E78ED1EC01CCC2D0274067100C1C1E3D880B9CA4F3A1FBB345354D4837A6E5FF4D5F5C87985E51C471EB9B0F85075ADB57DEB53A87D85834167A4A538134CBC24FEC2756F7760C3D46248D5BD6022D8F88CE7D037935DB74A6440DA49B97E8FF376101B296E3A9D4D22E70634CFE88142EE5FB6A33F323519EBE3A915AEE5BB687DA4A5E264C657438B0F6AC977A22D0E56882F74E70D981CF37FF0C57D285D8CB07ED7FDF6D7CB1DD39EB0D84F2999DBA9273E0B716CE754A29CBA2FE32BE13BE8B9F2117DD7359494A0E0CE623AB9ADAFD3F15F644545A39055D42C6C5FBDB46D121308D649AF9B86A350B70F77A977C8268FA1E04F4EFBC2C95A2D72BC37E558F0460BB281D33F75D2AEB240086CEB8246E8A44416A5B31EC58AAA88246D355591BF7C622CBEB1CAD3B785026CC04C73E352DFF28D77186CA93870339E132D57B11F0154E0CED426DB31BB2E125C5635BD489B52C5E77593145D3100E48CFC8FE6975FC3F60ABC7FA4A4D9030A2CCADA3854BF9AA213EF11E2F85E9D4E79CBB434C65ADC378F8A7DE33E66B4F8588B73FA7F79AF4130554173975280879FBE0A59D25B969FC45AB20401CBF85463A83578E63D0C8324878F5CFAA191428E7EAE37BB17A18D0459378CFDD4C8C0B23B1429950F054DF5C67174E99AF9FCE6B0D8C98BAA9078D2CA87EB8A014995FB79F7F49D78F2674839E14C8F74588B45C28E4769C439A930B2A187764D87D71200E841263EBF74F7428EC554C12A7352FD3912D95C96E4BB1D325DECEAA9D6FE360DBAE7AB897ED467A300A8F4C6630F8E721F24860D1FBBCFEDAFBD94DC9B4237B91B243A01C41D5E98E67B52B4A8CDF0F1C985EC0EB85131F5E970A6DD6D4E1F525D9D94530157F70B333F5E50B1B95D569A012ABA959456AF773B59BC2891D745CC036D06238AF3F34081A20F00A831422CCF6E4593EB56CAA3B7DDF44B388CD54E5EF9E3FB8A260847BEA5EB5FF9665530A4F4B56726A4C5E669904A933AB1E56C020967FE61E72185D56B38B03D343302712FFC1DF9D857C6F744E3ABABDEB3F65628932D69C65FA112AE3F7D6ABD2B4C3CF572EDA73C959637D0C5C188343415E9A26E698170F8E31CA45A8E6E8E96BD066BDFDFF49C98C491149D61AA7C456D3DAE0C017A32B81CD5668A400127ABD4316F3DCEA171C3F6A3E99B398CCD4AA7E45BB51963C82C43398050B8923CAE2D4E2A2FF5232AC8F2C770C9A775F29C261E1C7DAF54F9FF606560F869638B666C90112B29F469C3620B0912622892A432EAB443F8A93E3E7953235EE78CD3FCDAD3F1391A2487DA621526EE92735284C347853D5F65395ECA2B50B0CFCBD988F99C86B5AC56ECB82813A93208096ACA04F22AC015CD9860889E9006DDAFEE0B472FF7FC3D5677EE089B0AF7C6C2FD5A322D60BED621B8F099C30C2344F453320B6FF405639CF764B101E1CDBD312495C2D4FB30E2FA7B3C345B9935BB28EFEA69C829EB57BF2E2E5E42B8515DED4C32F9C84C33DEBDFB345A4BC592CA56A769533FBA0A631D5D0E07DAEEDD2FD588FAEE648B6391422924D28D08B4CE36084C20E827E6E73A97852BDD7508E1CDC1630094C9D3A2C8517A25A244FBA388EC7DE2CFABF139888EB7372E2BE3BC4FC71788AC3CBBB3EA1CCBD9616E76F2CEB356C13257A8E5490F3C4F7DBEBF942BDB941937C956DFADAF3A78903B49C5DE34F5EDBF0E98E3E04E51021B686325955C14AA335427C4A116CFCB3B89349B1258B8E0E354F13F86C86E5E8EF8F57D7B7501C5D75B1D9615D942B04E1FAC4EACE0FA10E6DE9B9721EB0651EB3C9DE4C61EEAE7D7E17C0D699EBF7EEB122B8C1A599A2CDCBB9B665DD9A653698735D5572EC379ACC6A8470CD7CC8245F871C83E6FD92111F5128A9797AE802889E4362104775CDB69FCF37AAC22EE4532FD0B5ACFDC4DBD56D9CE8B9EE2A8B923F42FC512B54204CB971BBC9677EBC49D287A3F68A31DB8AA49D6477B287285B88AF298E68C6EAC3C73FDEC94F7062D204AB310686144168C155281627F78C883AFB49DA50C0F5139E2A0ACB9A9CEFCCA39C6F4F0F5356D2898A4F5DEA78FDD20B79662F4D066E73EA4069DCE6CAE300B3028F15C98801912A86E0CF34DF53F7F6E1868DAD92DF22A238C710F471596A49843D3E60E4C381F713C21C3910ACB1515E5E30252C94F040F00A9D1A08A4FCA329DFE190B5464521BBAA32932022BCC5E119A96DFC941965CDF3B739F53DA156553C6BCD72927B07CC3CC945FABE44B7348257A9FB41EF85AD5423304E016E74E03D5164D9F15838C3A4BFDC29C6B9F134054B53B29183A6A145CECACB3EAC7C18E31CB4BF78BC8FE60A3B8EF880CB6C1EFE7EFA8D77580CE200ED96713E32FF23B86CF532D8EFA2FFC8DB1A9E65A78EDC30090E3DC02475D84F8D9F2BBC48B114C9E4A01FA79C17FCACCAB1FD304C7F901942B9EF57C918588C9CCEF0DC5FCA7AC84ADAD547982EF9E855F6E88D02751E8E7B8B76C3796F94C9F7B7C6860042A3A33EFFA55AFE1B94C97D68B76DD240346355012F036DA9C7E025C3633CE867510D54CACD36D8638FAA8EE47D315FCA9D5AE4BEFD6150086DFC368DCE8DC623ADEAAA07287F9B291252628F1BDBA5FE6DE45129509651FB048D3A686FFAC5F2299AB0133FCDBEEE8445555F5C649598649678847FFFCE6E0DD9C4E75E2F6E77B1CEE3A1740A94E678C1191EF46FC4D9648887DE6277B11D4C242DC4A427AFAD5459BF213E0A20EC74EB0C210D0A922B9E690EFDCCC2C160E011AB94F709C174F22629969B6332738654A133E8A13EF7C914CE75ACA1C37DE05A84708DA741161EE4D23C025B405CDEBBAF9040A1CB7492294C381FD069C4622BE1EBB0113F25F4E1D5A415C121055CDE5616662599C2364481BCDD35F7E498E80D2350AD3B34C205C5EA73F1B923E6197E07C502BC6F4F4288EB46013BBACC49A5DEE5071ECAE62B192294E904BF3FD7BE08F0C43E3EC6E23A7F68115FEB285AD388A0F8FB94126EDC0331834179C1F10CA5EC54159FC256D7E0AB3129B22E5AA5D662C6A03C7D9A6D066400859EC2D5B091C37E35DE31365F5125793E7F653013C722045F7292C014123246D611A7FD59E9B09EF24221C7EAB249330C91BC9F4D3A223D9C2CBF7130C5C057961BE89894221AFB1EB27A4604BE310EE3C395E479D852CEBA4C2F74D4DF416C8836861BC13D0692863667AFF8EC89BB9194407222589E1C27B9D59AC49131765273228E79C2933445B83D07E48A789FD6E406064593EFBAC4FFEE64614C5AB34E5C2A717C50AFA79A96161203531C161E46D71F447FD28CE4AEEF197A3DCA6BCA306AF09086D6BDF35A861820C469A40958923BA824F3A95CCAF8531E930210BE46D66CF7156EA0728F3448292F47ECF20DAC7C5E78A2A0AD5215FF37594D37A2AF4778B15BB1B5C4E0A44AD5910B62CA3FAC5BCAA4CFF5BF97C8B8CB239126CA09E92492121C9E6977111E6E5248661AD122C87007318BD3D98ADDFA1B2CD60F12AD1E072643FCF82C630C2093CF4A75B2D3F809A0496727E04AD60F14CADC7331B23D9CBE28EEC92C68C97E597C2EBF99F2B"""), + TestUtils.hexDecode(""" +9DD91BA5CCF4431DF756B1D23F47C0CCF24F869A2935340E59CD015E04D6F524A0F40C05247F5C8E4E0EC6DC0237B948D25679FB1BEF9435F248A20B4C2449409FC6E7AB855DE8F42423C83192DFE5EAEAE504ED4A490BC1FA3A84E66EB522327AB8741605348BE8C74040FAAF4F4B63D17B2157C3B216F20774412B70ECB568968BCDA52B6D3823DA6126FCDAC3837395CB0A22A6F4C704828ACF0E0B48A29400973B9C3567A0B4C0453F875A3DC82ACDDA5106895EB2B7AC33CD2982B1407E0259EB05E0DF60EC4AFC471D9FF5A4FADBDFD82FDEC3A3832A8F2A0776D650620B1DC4BBA31CD1EA10A93AC38DA5E22D9A0BA83FDB8C8E0F1C5751A11866E5C3E7BE5FB2147D7F67FAE52278BB4FF1486CD3BBA2FCD0544C71C1A5717AAAF6D1BD279CD97530BB1BE3D692CEE23A0069138D1F7AEB88C6A7A136763C132CE5C6F036E703D91FD76F3BC200656B61912576CD729540616FC49754E3371624137E39346BCD74990099A20A32FC20E7C2A8E23A3C0B3FE200F0402B2F79B825B3636C4746A283DBA0072B8D77CFE67B9EBC45350FD96B6F8C94247F98B90645A06166029C4B8F44DC998C0FA8DC5A0915CBC0EC139DCF1C75FCC68FA18DC365A198F46FD5B6C6FB69C9CF6D57586A0586511A16E4E1F94474337D31F97AF17C49E2283BC610F65E3AAEA08FC8DBAAE8A7D5D9573C46EF3445E46207536F57B7D69D5D0B61FEC95C883288EBFDD33947145FBA259B9C2947F7B837113303CA88DB7E0B8945F0ED413658CB0B1A200991D28D69D138A096803D964F2BE8E4BA04705F5F7E8F805871B7CBA8953B24DAFB9C1E25C272430B7F514DFAFE7A5194186AD8FD464015E09BE097F257DAEEDBE5CAC479E517A011E7059CE0FF415B42524F7CFEB49A5EBC68B0A44E54AFD136CB6EE143A2C6E8001FFFCA92AA4EF2579DCC06BA93A921DC261003C6CFBBFE4A8FFE70442C5652137FFB849B383022702FBF3A6197E13996C323D385234089234634777A9CED6A9E97DE805E78FEE580BCE6EB074B1174952608E05EFA173EAE7E929DDDBDB68985040775946BD70223D404E427ECD91188AA0632BF107EFD0A7296C4E100DBDB8EAB415181A4C12B43BAF42EF14A6B6ED171CFF05F96F919C0A5AADF18CE68381571250E59630C0D0967CE8B90FC4E075F03CAFD851EC009630001034D81B1CF2CD864D6CE6B4741B056E1E3769C34E82296B4B856B8523E5372DECD8FF62E289EDEB8368280D74239FF203BD4EE9A1D05438BF325408E199D28980DC8D3847B412D0CA652E419DCE0C42ADB52E5F33691304C0CA16551A4224E9ABABCEC514E0D183230937ACAA3125688F7F47EF9FC7BAD92DAFEB157EF880DDCB4BD1E1F8AB5E88641B1C087EE49824C2EFE263F149D353DF8FDB8B784438E74A17180A66792E02D84F1E7BAD76DAE2C5EA63E76C31CDEF083524912C73430C21E2A8E04509621A612FDD5DAD1213424FDC2518D116E93795F726210AA627AFCCFA7CFE3E563C5B97E5B0C276001325A13211EDDBB19017A0E8F0DAB523B5ACDD88D4FBA45CEA00ABD38FCFB98910A3330438BE4944EDDF55C9F2A3AB31406A26392340BD9907F1CBFFF78B320B1F9DF7150B215401B65DD46EF1A5912EEDD90ADD53F43E44FA8AC1BF010BC5130DFE9229FC93F36E4121D0E2767A88591001408D60C8507AC3315C74B72AD9CA05CA4CE9B81DF98771693A6CA084F8FDA0BD556FBB15F76D179494892EEEA3F961EC47BFA0826CC936451E66224045C82ABF55875F02658C82AED63E486941D37144E1CF3386844E2CA24C469B4344775C0A59FD2CE6091F575A260260395C52B3CBB0E65F5C3C540A8F9F8438370B57435A1F2FB465C66797B0B03F874FDEA6700C0831A18A7B50AA7B18D424BFA9887B3AC955E97C80FE176DB27EFB6E8FF0BD4172EB49D984B12A210C30F5D4A6AA3B28460EF2A32F8AE7D057D76E7A111F8CB2116F266F3070EDA1BC98AA52BE181903C2882F4739DAA06C21B4031A732375FBF23BC51A4E9695118113723BB1BB1C351E8D72D9A847A434467B90ABA082556980B92A146BCD3E13D9BEE551C14863AEE87CB56F7002BFF857AC9BC5E2156CCCE21724DB781179564290392CB47CB3148844F3159246F39665B69CE6F52316D0AFDBECBF8BF2B2A5F9CE79821B2E7471E97748D190268E8BCBEFDADE82F3D5C8F75768269EC41A4648C5BC86B267E680156D41163BF787278F3BBD9BD2AD483CEEBB9624FE531F76906C12AD16D151FB4AD5F08BD277C2B55650A86C060D38EF3C54DBAE10B65345BDC4CAC61376A5D052ED0D930E6BD8E9F4C08F257AE7D2ED672E82DD8FEBE17CAE8F3829D353638B2B104D49B7A7E62DA46C642CC3646CCA36DAB8D9D65AF695BBFDBDEB65DC07FF7F6599D5CAA6BB1F6694A8FC62BB3479D1889B2663CE704F4099C99186D504C3651331CE06E627FAB29B1B254B159435AD6A8CB6A678F6CEFFFA7988512328D8D868CC439812FDC8C4BC7D086A1C6532A62AC517D0EDA6005C16EEC0C93BDD9223AF2CF5D3E272416DB60561DD0B106AD25B23E00232BE30B9EFB7C82F97DA6C564AF92E5E16227CBB94EBD50E06CC34A2D22C948EF264E5A1B4420A36AE83901C346792FF99829A40714454757FA1CB0D7681798102AA90BA5D37FE7C29C64B86005713711D5890279CB0844536C0F974A46802320C33431588E42CC0F35D5BAF2C828441538843B185C4D93F57BB90ED1261B980C6B33B121D5C8F1B87C2D05442C34AB56512F40B06D326F8F7EBC5FB29D06AD907E687856D558AB423C72CC3B85D683814824DFD9CF34B810861B4E33E41F15569159FD4C6622A6FC797CA97E8D0B0D2824B199A2EB5B6FF06976A92775FF8B66763C1A430DC452F0CA701357A00F3A7C1A29412F1C308EAC4896F55EAECEF88D89F6BCAF7A02714F68E8D412C591A2C5F11033F7FBD2F29A0DB8B4171AA8D4C7E4A708B9742B51F80DD6F9DBB7242EC438CABE48E39F1C12AD886B7750FEBC9C3C4CAE1F6D016C412EB6812815267590F94794C90FE793DB920A4C6C0ADA4E80D2B64B81F04084B65A8251076073A84C2B4B1209655847420223A0A87C7612CE67C1B9540C8ABE46A0EFA9312C0C1FE5AD3165B90E6973F0FF8DB7FEAFA2E01EFA3ACD58AABAA0DDFB30AE7AA819F5D5E9FF72402117FB8CD9BA3CCA0BD2B8F52AED5A435E1F705ACE8E18D60845B8F0B13C967C39AE8D1A6D1EF3BF875BC32B21839077DC0FDF2A4D02A0D1554C2128E55A370168D0698438B21D02DB8C3A5691712B439D4E51E5E31DB45148977A8B184AA5FB63F41C2EC48A7C9C64EDF88E6B480956D9B0A63FC1149D85966D045312A3BD3AF480FD4A3C3F09DCAAD041427B3355B4C1F072A6A12301A1F91880F16A3B3B425BF150E01C6F369C84655D6F167E94613C052D73ACDB2A04CBD4EDC141E9633568485603E5D0339743E030066AE49FE5AF1BC28CFD6F4053348FDF7356EDA04AD72F17376339FF0F7AF432EFE60F3B4325E7C692A79C5099C29405ACB84DC6C991F70E73E1F93B4DCF749B5776A8D5E4A34744192D48E6450B39FD74F162BDE7EAEE2DB13061547169B627F3209B4D06E2C0F71C8D05F64A6245C9097FB0931BB838DDE1F26A211C27710900DCED962114CD51646E5DE093C7B4A3D18FC99EDD501DE8EA5695DBB9581322F903BA408E74D859EF91CB1082EE68BBB997ABC44BAAD87C51A82FFBADB819743FD0D06341666624FD88EEE897168E2EE35CA6DC71FACD98E754B7AF4FEE2B77E4B49E718877C5EBA1706EED84049DBE7019FC42698BD5E0696732C61828FFF5D15DB72654595C2F2B90D12E79691B69F2EDA1C137D2E69E396AD1862F1625AFB9ABD111D495D8FF41CA4896D2A83AD8D00D49B15F1BF0D160AF3CDC637BA2E32015ACB2299A13FBF43D054B420CE97361CB38022C684B695C4164D0CEE286DD1E6E34C483BFB5F91049351762D9D2609580B64425C06084275AB7ED3C3CEB8863F713FCFC091F460DA2351D54CD4A59261BA01B3A0D5F97C04A4A598DD6BB45CDD6049F2BB52D68A9B219F6474751C655F404DB8F75DA6AAA2609BBAF77E7F67BF27D721517A7E128DC4180F0612EA7FFC343501E048BC030A85089BD2F2542FFDDEF0F4B98B7A45376D9B33EC082C17C8815042C5DDC3DCE0CD64CCBD3E8AAF9AA70475E845E8FB4C0EDCDAE5CF67C2384737D602EE1CDCA0238E5F2F0D676E3C9564F9C1D4D9CCAA85BA8B1621C8E3161714256D6200A61642C1E3034A2E072E6D32FD941B87BAF22DD2715FDD8B50D0D366E20F1E9ABF312F989930145FB158D4A1CF607B507C1D3C43C6FA130F36B2355F24DDA2856149357AD1FB9D608E6F25C57B61CFE450EE9393042952AD2BB04EB4C1E7EC92A19BAF7FFAD5FB4CFAC804A0E18AC98AD1462E384DDE80F22E457FD9DDD58615FF9FB4A731F85B1510FD18FD30FFC74F56CCB569002B85AF3B593B4B117E6927E8475AE2C9406C383F686B8E79F22CC4DABA9759DDC9B1CC6BD91C13E451D5D30FFD1AD0D1BBF5F888AFC54783CF930DFF4EBFDEC0B1D0DEC4F781966BBAE1B9D0358F23BD5A83F0DC43699F30ABE458C7FD2E1B3B5B04DB570C598EA1C9FCC0BE0E607418FD5F2B375DDE950CC9E416868F0D582268632EA4F6777AFD49EFEBF7DF61B1F6AF5B8915A3DA8A4BD5D7501426AF0C99795BDE3D65317175FDD10BA8BA957824D45EC0B2653FFAB6BF4207798833D6CF875A87A181CE8B7188F09A69A8987C836EA923188D59B02C0CD2483B03654120794459B92228A8E029D149D6854DA86AA59C7C906F06E314C193C5BB1E94FFB4101B2AC1AD22F520F6E2D1B877E2CEF0CEE8FEEBBCEAC4DC6E66E270250FD77ACDE3E05EFAF41029645891521C0A471F268173EE36F5A6DCDA14D1F5D30CA8C2F772AD1CA92A5AD9C6B111793F38D62FD5734DD9148308344C5EF4D2D7F524576D3DE03543054FE8AB8E317660BC23513D4100FC1F3479984E1F8BD8D18F2097640A1CA2DE7956BA400AA5F06BD13AED8D54703029E7B927AF48A1FEB1317ACBC7DA9F3B0421611252ED708515FED233615C98943B9B1D4337EA182CEAB73B704C162812677B9F96B41922479DA97BBD7C83E6A588B0EA87B53FD80024877037FA98C058E3CCE7027A425957F87B0CEB5129DC8DE0D14461646864B7E69C862B9C4EB1C2240F35FCC0FEBB3E24F98A182737515BCC65A95E53ED42CD15FAE2F3329D61BB0CEB24FAA956A33F358C8E29BC610D02F1F9F3B92C5A6B2B4F1E00B3494DD37814CE79956CF2706BD3B1F92D6E262CFCA492FE20C2DE75D1B8C20CCA8146237536BAC89DBEC536F00B780A906BCAB0F3669CF0CEDEDF8314E3ED4811B2C8336A7CC94FE79D97E4B65CB6240820C88B785CA79D630C06E9575C9A2EF67B49A150B481BBC873BEC1F07769808953695AC1B4A2F971233C9506827E439C37040FD31FC49E76EFF585E9157F83798FF4C7CA1D95258BAB04AF860805C554D44584A478D3274E0C564594EED9343E3349370D30164EF7B2E2D104B7978E8CE758CE8C086D8F108BD3F925040552CAB65853B05A51B3510743B70F4120150E062773071EBA75E5DFC774CE13261DDF18FAA0A7741FCDBC1618D1874C8F7876B200F8A8E5158B65F8E015970B0C3C3283778DCED0E2FA6255BC5E0BF24CDA13F6A47CDF2452783C46209623A7C425DF9845EAD1E854BB810183512043A66046996C19AD1D89C1E32C1C3D9C697E7405E6CBC0E5642816F8D9C72E9DFD7222A6FEE81C9971657B6F06F9A0C8E9550CEBBC44C2593C60B1EC54E5DD2D93501FB9EE42B8CFD29DE790CB8A15A6BCA3F61163D39F186E771769D2B7BA9ED1DC0FEB03DEE86834038116C5B00D117B2EFC56C283436EDBE48A61C2C7DABF5DB3CC638F14D28AEDFF375AE638A3E05FD871D56D86413477BFB8D902DB263ED841367D29C4A95B03D758CE9F2E4781915755990A4C4D5CE8AF77376F7F2CD050CBE42BAA3DB923CD90665FACE9034087F56115858441C9E060B05542053324A0722FF12E6DFAC3330C12F20679466CCE4C4A24D7AC09A04302B95509A42F5538EFFD1BF3DBF1E9537614ED865CA9390854F286C243F2E7AA7311B40E5B3DD2208156B37FCE086CF064C41593BAC8C6B00DCF6386BED761551315BEA7F4E1600FA1FDD2D0B20B26613A312E1C03D82D3FEAA24D3B948730698C1342B4FE97B7085B192573FAA393BF62437C57362706B17B22ADF289BB31B32079C9D9DC9AA1E8FF63B25C8EEF97F13A628FA5CD151596E67AF80A4B1A71443501F6B6C8B6825F8AC7B5A6520F056D589E849949E93F0C2E52AE89CB81F3EB7C31388A56D15B25EAF35F9570379EDF4E8923B4F1C6666BF646DE202359CFA3C8E10434A5A8DC3DEFF104298B3C0FB507EA1B3C9D8F300617487C3E93CB6CAD5FF4D535E92CCD1D8E3000000000000000000000000000000000000000000000000000000000004060E141B21262E""") + ), + new SigGenTestCase( + TestUtils.hexDecode(""" +CBCA46632F51931999369241A839BB7E57DA0237BC70ACEDE33B32FD3A66B20FB4EC73B8DF3E9EEB22782E3359A9CB10EB8CF52422CE70C71824C705B7862DDD926DD53A787E5B80EACCFC8BFA1BDCAECBBCC0F697558C85BF745C0741CE0C818A1A2159B5E2D645CFD5FD8A7914D64095C4B2EC86549121848871229F27D91D58847013928851224411090690A28493166A994460490891E4065221B98942B44C03850564C071C92472834244E086650B377010102924382922458601B224149085D44622D43231C3284010182DA2288C1AA10990082A542286D4042680400103196A019780D2A86DCC062AA422680B492854327123C36440180C61B070DBC02DD2300A644009A2922548262658200C14912994464813046D0842008B989144400511474DD4180598C67142B42880C62163C020143265C40241C21624DB420D03068A8A382448484DD0A40DD3924489306D09A52012856C1A4450113125412820421692D34012583481092912028684C094040136451C200C84B48C00932512190294A07108A388838064CBA88484022A13418299C48D5386848A4692188890233820DC88519B16469398000B046D10A45012B14D81A20454468E9C240ACCA028DC420611295102A4608A968DA2264E0C2931C13272614280A2A28C9A285288B40150A28118024919970814A7110891680A8644E048921BC68DE3C04923C261DCC00822C08840A030134972802844D3920C1C304620012500C64DA33485134140A12406E1226022130648006022C309543491A20881498425804240C240640A456D04226112106983C22D53344C42902120048192B80020238D23022ED094901C33685B16500CC7440826720081481294200A9148C9C0050C13109130650924300B0889110461C3908481B06C22044AD1B63181021091362C54C60DE13691C106084146508182240B20020C416A53340A132822440026C92089C48660D4300962B0600A274100C664E4A084098788D11646E28010C0444924444ED32471C4A851D9300DCB884C81488A1B3025D8802464982411C42DCC022A5C38869284311A1610A2164A0483601C33510B336020180D4394441B07480A21104940321C28804A402A81C840C3106E12C8456288819C10654294715482082045892048461439864C068A0AC585E4148AE2B02424400288342052464C53064A84226C932850C2187061244182487011061180A668883649C22220D4982054420E1C070194C04814A72D9226268108810B03651A210ECAB44D0020026140122202308AA48D24B74C0986416388804C1871C8226624C249003971A0164401246002810DD4C4845C32701999919A90702297712348019318025AB429029785E4B4080A300954B80923434E232888909268DC92440CC525508680621069143989C4282E919248E298059C308564201208B520E43225524668488809C12868D928442193045140401903095AA84C8148288B224A04B369C4028452360043442A004800C40445CA304418181292320888C690C8284E20B101A310268A1490E2464DDB260609498E1930260BB58D5A3866A0C60D4998619BB06864300483226D194071D048520AC829D4903004246010258AD428860A320A10C3091C4661E3C0806428686480815A12024A4610C8360A9C2442909489140401190409142721D8020998128C5BC84DA29409A28271CA322DE226825B16080CA00912384E8C84891B3748C08848DB980D04A84808982C24A59094246C2113669B102611162A13C96890485220B96513394CD2A26CC9320D14952C0202651C3980A0B62C18988483242A623269C20202C8446A82062A0300255294880C18259A128618C6401A310684066D18430D88C06024416281C06000380622378D02096E83440621372E50C629E148819C882D03400C5C48301B0384221061921490D446858944110C2431144051CAB421198444CCB284538050A1006C23418C8896298C300C50A60C8820848CA2509CB43124356D0C21120A3749C2C06014B44844108A41146E1281045B32080181088400054230900B344E03A048C834450C3290CB88044BB6844800901C946D1192100C1600E2366AC04866504890C34892A31830118600528871CB26400C44684312665B380C19852010228C8B928D8B40308A900C03C90D1C036D1C2652922032030120928248EA7FD68A0C62DB31279B2CEADE3F558AE9E6AFD3849A6FDF95B9F0C219B6155FB29921A667B0130D8B21493847393DE153BD4ADEEA031270DB812F827F974A2CD6520E7BDB2ECD99916FDD5C439EEB41514044ED8F02361EDEEE74F03C183B6E3F3194FD522321188ABA2B3D8C7B6BB4B6F2473ABB3E5337BCA906E716A6DF660DD51B543F02D35CD9A78B9D58312F62AA96635B8B65844500413B3D52BAF6E671487E6D882ABB2473AA4F321CED5A1F57072AEA093A6D51EA0C701FA0B915B14D5EC6F16E4C559C85FA9DC465044097ECC21498E3D6F919D75F8C364BE6371753D2CAA90166BEB726118266D8D7C5C3AC81307E74C0F796E1B038F7660E770D1707F10EECC95694A2C17A6306F661855DAA243033E624D208268461860E39936BC6915A86CCEF098B4D687AE1C1B22BF476C2AB753C8F5F528C7F749749372AEABF9724FC7E3F554B483D10EB78F3099A7ADF6CC4CC03E4EF1B6D0219DECDF5AF99FFE4B2D4CD18BA98C2D62B93555A2989C753BAB1D4BF34A982A71E0B10328E165BFF69A18F494F5F40DD2AA52B23CE544F7FE4B5632A0FA4C879D221A84CED7E097DF3A17F4E4731F87EBAFA97428C0CF9B51200A0126ED983C6FCBBD52C64E109A809C1353C3ED3A214C07A29BD3047D0E69D00B8BDA5242BCEDE709961CE83D1112F19BFA1C6C68FBCBB1B3045FD681E3EE1AB7EA91BD5F501F2D9CA88F9E6E040516D1DD238ED79A84C3E4E8318427A41ECDEA73CA4E12E575403FE4BB9AC0CC9FD8A7A1877F09612B8C8746274117D7930A0DB55EB493907822208DD541CF3BDB71635BFA364B01F293A3439AA6DA458ABA62F063500D2222A6CFCA9E545BC61624E1097031219D61DBCBF8C8D32E345058DDAFCE284B23BE63B5F3AB979C35F4B5AAB9BE0CC37DCFECD168298B744C37D08CCC0DF515AFB01461ED24850BA5D84977D4352E0838EEB9ADA60BF0862971A83A0DE929C06F4A4513E3E01F93EDA9CA7408233ADEE110DD0E1270AD957A296F8842134178893D39C0AA07496EDDBEA015A1E8F42F4CCA571D1AAB376556156863FB00BF1F4B329964B98505B0FF71D39D35EAF9D23A8589188F872D555A55BC37E364C0BC41468130B2ABC8F43EC7F3C39BF0579692CB04DF4A29C4E71AC4921A79B7D722A005C226A4CEC49967AE22E2FED24CABA43D915522E59778BA66F5D2E3604AFBD076DCB7ADF9CE9CC26711EFB4EA190A6660F5F7BA77E2A165912E2AC8C6A4756B5A305EBB92F00294F771B75F1B005E7E042D4FE23EF90C564E385A6968B0A61CA8940E8C67ABFDB4B57F16FF6EAB60ABF48866479C6B891C5A7787AF18906B528F8CCA98EF2D1CBBB5516B95033CCB060B8C66FB1B0049AB88CA15776971FAD4903639A1B354923E13E1322DC220ECC967C581334F8FC2FD10B7B8EA6517427637FD2A967DE71C49F24ED2FF2A72A43CA839D8893472CFD453AD66864AA73C002875C4A09F631321485D3E8C3403406E2462030EDBCE21E7BADBEC4774CDFB7914DA8099E846D69C6A7D58451864F5205D1854EE420B2915B84A933DD381D9152E4FD6C0795CBB90F506A4234AC4128A4AE863D68B06DA74EE36BA3AF8A35B30AD5AC6CD7DC29C467A088CC733AA88055F2246B3370947687E2F6A825555C5E8C6B6577EC2C3A9777882BDEA26F8F8E1871E1664F702DA4B580DACF7DDCD6E29763F5737B000BA424528D197937EAB91CD31504D626A3C33ACA17757DC65C7311AFFC35731272B18AA49CD9452C7497958089FFD021A8D234F80CC693B286C12AF252C9B32C8884CAA75569DAB60F2E3A0CC8CC9ED8615FC67866B54E2762B69F3F81DB13B510208974897A62EF4192BDDC9A7B8AA27DA597C5BD59131195D2FF648F4D13DA5E25B2FE99F1604FAD38759DBFDEF52D8B5E93706C0BEBD16048A496C8A95609A4D370F131B3094C928F650311FFF864AC94F6A2AA18C7E203DEA188B9DBD20FA08EBDC4A2A59095CF7E64BD16F1BDCB44CEDF7409DFA209B1698E70F0EBE387DC40B45C47B621961A34BE1F53A7CD634A538740799A3CC17B69579B34168D1D7C601CCA733B4774F3BA611D38DC44D3A7FF829577304B76B3A2A3BB5A3AB0FCA3CEAE0C4E50B985C7A18CD37D517C4C53F91C8BAB32B90A4F157B09CF14A0536E01BC382C55DC83DC27289EA546326D7F7D91DF5F9145C4590D1A83494D2C3B29AF79844F0658B453A8C3E44EDA25198B108703584DFECC3686C0BABD1078E26FEA2292591054A5D9B555D4B056CA7536CB81F8F7D7B5A2B6028540E9CD21B2458F1B2A5572C373E31922408B26AB3D5184038A7CFD9B506AD4D3CDB5B6AC8DCBCF56332C042441C79B9CFB71D057303BFD6DC98AFA0B312B04EFB0ECC4479CC1A35D53C13ACE0D77C600D43BB79319ABEF7531FEEC9E42270DB58F8692A51E023614D8ABE7744E5B822DC883FFB7C11E2CF2B9CEF5A1E0EDD47688B653A0B2DCA55A7F46BC2355B0EF5981C1672D09A7A74B93E1A92C8D8797322E67492C2025D6EF89A2DAD153F261BD967D5D63A1285F134077FA25E1714108444F76F1212C11B4EE73E448256F93470A44D1E0F7D9941BA5689D3121A47546C6B40014397927720937C6FCB50D283BE16EF175BBA7E1759A1801CFAE26E2D00D0CCB9C155FA15D9D269A880A5B1A769FF4C74005407BD7CA73DD3DCD09F0E940B7D84A1876ECB65F0D712993B5F2EBB9BE0699F6C2F79DDFCCA8ABAC2C88B0A02BE72065AD98C017ACDB90FF3F90BBBCC7C8C34146272CFB36C2D04D073049AAB6BE66266046E975FCC31C6050BAB10243F774B75B12986F97BEB30E659B2EFCBD53001654BFFB603B6B9CFE03ECC41F1B46571688D33DF1932AD1B82DF9535D12FF964618A2F76C6FE4153D53264982466D1EA1101B3A4225387330289EF0ECE4F11A8F2CE5643DBA7089BC1482A754A000B53BA46DE6F55C13B4B4C858C0D494ED768DF9A366A2021157908D696FD95750AEF985D7A7A2C56766BFC1AF0DD3591A63068FA1C6E1BA9F13B0C08FCC71C6EE02C0A2AFAE2A9C7C35F0DCEDC5E9823F28D5C1BE4E1B656469C2551704DB934E9FE139C2E9897553424AD74D68AB31CDAD48ADAC6F0C89EAE8BFFC8C4CEFA2F0D09E2C96A134FC158CDCF62B1CDDBB072F62BA0930755C9759047553672FE03D21270CD5BFCFA6F30E9BB67CF9FA9D02F8A30C5B977BE4E52D71AAFE6D3D1223F73EC5481DA72491F7C906FF6642D9731B396C4F26BE506B23084421A527DCA74AFC6BE1F15084078DC1DF2D813AE5595F40A94C15A7FBBBF4EC05F0608B28F283E29F8E730268981DAF3AE4CFC111F57CAB46588F4E58EF2C1536B0629021D6A599648F8A5382EDE2A4452E9EF6F5A7A221D35E9C2BFA134D11D5C5DE65F5F0500A1DA11B0DC055D0C2C2789F14F8002A487478D1F989578AC6961E262A08B31D913042410A39C4F9F71D1E70C2B1951732346E79A0CBACB0D63FC4D78D45A0D17A2BFEA3B81A7F14E3C680B4B9B967447B95E0F4E06DEC7226BA245597D2A39FCE4D1CFAC9B204DF917CA3CB8F827AB9718EFA69DDE17458EF3B0C0FE1CC611955FBC64A436B77C33C28A690CDEA44E0EE82B346E2461C6A1A1DBA39A12FEC61A892CB27027C57C1F72CEF1F190ECCC686DDFC043CFB2FB0EA8CB280928139731D88DD257A7C5554EAB6279EA0D0B819595DFF68E1612B71304D007633EE49100823E90EB41211848ADC7A0821A4B3A9113383E8217F16C11B331867AEEA9CF4CBF8310F0EA0A477F5EE1B2CED3EEDC4D0B300BA19BB95E4455EBF195F5E12374D5B6FED2A0E5D6F98C2B187B03E6B4CBAC7C4B446BA02D057D20CB3FD80CE79CE0D74856834228FB07273F4FD4446B8350A8D7C8AA11C64B89329886FB1327253FA162E4757D9CE08968A5C31612328D24D881F8A9E81711C7778B26EBA4E93AB00F3AB996F3BFA79269BAF026F33F5D616A4B306A100BE5899609BEAFCDF981C9EFBDAB444AE7A5982BD925E6B82603B8F9388D7AF9474B8AD18348121AB3E5DF4E7A9151D91F7D724CB2D6AD60A2FEC17D29DF3DD2628D6022711E7D4EB486F90419E66EA2C1479BCD02D2543807ADB8D75226E8B7386CB4C4057590B466B4FF7A244759C5724910A7CD569DEA50E8520387BBFAC32DCED5575B6155BC66C82F6132A780AD670A8C91A6813C89DB6D900F17285DE4DDF110579FB1E28B323CFF7164961B014C82EC825B25AF70EDD5D0BF74331B8FAC3A69913D7030DC1A142FE2FDA1D4CC5C83A747024DE772BBFAEB89CDC880851020A9D4C5D03267CBF996691A7FC1399BF265E985BEDBC9BB5B79487B97E9BB2DA935579BC5AB555EF633F2FF85E51392FAEA07A664F329CD923D4460423BB6C74BD63A4AB0DB1E3BB7C0EFBDABDB95AF5727CD5DFF90878AF51EAA0648845AF99A2286479E7125F867B31B3166AF309102A05F60158A968484FE5F1C0275E67DA8A84AF33A1ECAC4D49DE5D925748FF1E7A5BB442DFA88E5A3797A10E4CB044EDECAD83324986DE44A5A3896FA6EC6C71C646C2B4431AF55A3C2F325C6A62460C7C9BE6235A503A2301333F0261D97AC6692BA5B9B8BA375149685F85A443FF8BCC240409B6A959C1045CAD6EDF0EE593F8C3FF535B46125E00EA4C4A96446BB3E261429BC6B656B401598BB83E365C438EF16C8CB2C25017"""), + TestUtils.hexDecode(""" +B5CD00AE06396DEB95C9BE213BEA279AF0D10F1423B5A71854413E99F7216D9EAE76C8AB884545496559B14AC9A69801EE3FD2EEECCC557D7988F34B82D244461388C7D4EB16DAC3C0FCE0783321A1488DC16C3C688126754BB4C26308054545D2E46C6BEE26C25A7C3B701341A0323BEBFC50C718162B7FF3B6FAAE7156FE300F2219655D8D44DE89845393011A2B466233B907355467EC49C9F832044BDFCFCF722D6DE7946FA503861C80037549ECE8FFF95026CDA33C9000FACC334765A60456084A0614455C83E0D5D991F7ED43952B7A69F1E326D7BD33822CF1F286D85FAE78F0B8DE186368EB334CA56070122DEBBEB920C5547C46C1291E78AE48B72C7A39020A1A2E54E59A2E46606C99E652FADB39AAB25399B0830AE733FDFD973294B93F47C30D0824686C735E05FF51A95C1C76467A4BE6BA80C5182353BD510E8D4B60BD43436F7021B3F5980D1A769B2E3BF04E0C257EF577828B327E2AD85E0581787B9B7FE44D6B826BF8405D3D0BF8974D2B1C569006C7FC3D2891DAF38DAC36F64A256E337B660CA59D2B45F1B4AA1C0C72B78495FBCC9EE9CFFA4B5A101F973E3211E728040904B0B2515DA4B1CB3774EBEA1324EB6907324E733C7F17BEF6FAD0F6BCEC1F08F785DC6FFE02FFED5C0B7A631907196835EFFD0730FC8FE020B0545C920DD7B2D705F22D8D205804397F6FCC60386F4A576204949EF60DEAB269905707396CCCD8DA9B895270CB39839BFD3EE64149B0085B96FEDAAF8C738E449E585ADBA037BD560EAAE978A6ED61DF432B6A9C2E50C2EA33A8702A23E6848401F85E2C18C7C767DB15920C9B3B030728FD9511F8903DFC8572A3679F986CA1B684B3AAF489DCD93C622C6C4D475DD60F10C390873B09B5A352B6F5A104C90782E053F8121317EB8D1D4C0145E04E3B68446B69A0EF81097CC6BD0B756AF78963724D9C83C61B7B79647F0844867B605E2B60988D2D7AD07CD6BE2D8F904F0D269187C141AC67C9DCF9961BBFFDDF3BF34D9CC5781D1BEA348F49EA8FF7750F7F3E0624C16FAEFAF1D8B6A818AF5FC5C04E2504A0CF4C2DB54930EFA759A292A2AECA1EC3A08918513D95C44BD133657FF043318A17BE4A5DCAC54B87FF38869D017A4B14DEB60480AF1C5F19A9F87B94B8EFE0DF3F931CFADFFD7AA50AC86D9CAF6D434CC81E6ED123711E34B8295A446B554F6DD5350B44C614324D8727F1CE501743043DE6EA085DB5154AD8E30E114A02CDFC96BEB4F2718033B227CB8638BCF617C73BA4473851E62C8A287CC4F9C659190E60AEC468DE7EA8841E3CEF893F3DC79DDDD56B63102EAA5B2793711A0451EE1655C6768393F59CA6085866FB41541D9997C94BB56F6ED5D731585E7B25B1DC853830DE5DD75F66298BDBD2E505DCB3850F96CCE0D7274633234EE2FA1E2782DA3D6CD8F5DA2C3063A923DCB6A2F82614527CA2A88C1AF21025B88A08C3104C679175DE2CF00602B13E58FAC9376BECAE56A60A6A8F144F1C98C8FBDCDE6FBCA4ED13228FA77CBA5CE631BCDB368AD9219568777FB4397BB40485A9AB63E9E3FB343154108D8117CE25BEA30BC854A241745FC6C26AF0D64124AF10BE4BE01B8A3D842FD9CC4D805B2BE26F8B7BA0631443F48C7F74207F640B215E0DDC42B1954A1EAB2C68E63601DE3AE3EA54E16282BDED00FC7665A9E8B098BF034F5E950ECDC46CDD22210244F102E41E0930FDCB24AD6C72507E5AB6FCCD4D6B2A2703C358EC1B51AC87302A5F507BD01CA6B5FE04EA2A5322EDFAE8161965524C61956CD201C4BF2F01B54F008F5F4B6770D0622099CDBF94D6C41DAB4A5362D630B9BF9CE240ED08D698D1AABF29E60BA533697C3C830521314F13EECD95C7D2600E2A756AF19AD94D9EA39FEEF0E3EAB3EB401225C2E55B2F2A8D7D1A3AA77A38BF9BA31399F6E6458F3F21DE354BBECC2E29740FFF91FBB23E0F61D7E0698CBF82D439AFB018DC5F5011B7BE98993E8B655D83C666FC0CF84A532C7655365746FDB97874D62329B1EFDB0B0C8A46056A85B60E38AF8979FA4910D2D9CACC3B5C1E42049D04C44273953350E0F756081D2DF6429193768802577C381897BFE540BC036293643360C848A1AE388CD17781296A99AF0CF75F81D568D0648C8A15436BDCB16FD83287C6A54F88F2F75E6B28E1C5A3AC03501D6D723AC5EBF90517D194A596F7F95947CC169CFF2A65D2BC9B54CA6AA45BA9E901D4AAC81FFE9E62A479EEC5B3F9BFF24C69FF56EC52F1183B5AC48A5BAA90BF595990B6EBA5B1CB6D88511C7D0D165FDF2615351B0343918B966ED1CA0CEBF6956BD2CA599E18619E1A5930E47CAEA92B8E9647A0262A2B24E955040750E6C7B935982CB742EE756DB65B462F677AE09A7521B0D3A42C2E97890C47148618FA6089975F5D491F4D3F69EBCD54C2B53130698A1F4A47505194F675D68F2DDF5983B008E498AB4A25956CF724F5C1250D5F9C75F3DF9BAA696E300AA86FB4B9378EE18E79D015CDA55D6ABBF5B0BE819F9EE58B49656D3B112AD8FA6651A8905061A8E37760C3F2EBE6DA611BADD44268975B5000051BDF7158EE3DC200B47FBF8568C9F22719FBEFE5906444DE9300689BFA1AD167"""), + TestUtils.hexDecode(""" +B2E661C2BE985A4DAA72B12734EE09DE1C78621F91D7E247553F39BFBEF28BEEE7F11654775416E4694086B0A640960D1DF784E8F62E16FB831097DD07A1121B00251D35E4275ED3312C22B41CCE76851A48D9BB0C46A64243110A4CB759675CA7D1B724CFD94255F11EEAD5AD01C88F70E2CC02001D6F44357BFDC159C4CE44E042FB429CC7D32968C5CA8BEED69C6C3769BF2A83AF75A7831B76232BE271B33A43A8B69A91D23E762280E2880559392B4752D29BA296BCE607AEBC0771AA0A92A30B72282611A693E828D068B04C34EC01634488AA8D1862239015BC437A23807FC2BB1B27CB9EC45DB5BAF866858F1D69A3005D4D5F210E0C25092D658CA9224B49FB147CF891C5127FAB6674FECD864A1C26E4881803BA3F8E6394BA98D70330F5D1221DA1D1E966EDB682FE3BC4F7CECBF7326AF5EB7C582B085B4B7F603212C3C8C6E59524A09227DFA93A44D532650F617470D9D250689538ABC832F38503392A96B0E7BFA01323A85696F3E80AC0A860C685AB4E248CB646A107562008358B53842123593E5FCF233951D43D33B110FFE33EFDA0D4A0CCA3F112F94C85F967F0C6A0F7E20B6836664B70522F962C395971692B29F659F0418FF753BD862966D10E44B406F4CA1DB909FE01B6F9F1B60715360D4617E7C0FC4B37692707ECB68B50D38DEB8F40B8C304080D81B84F60D49B7E4EC50B02E36E063FE28BE9A23E6BF17693B8B5C909B5B136BCBC6A3832D53E83A29ED9F933A8BDC8E318BDCEFBC10113888C1CBF39464AE16E2B30FD7F94AE1A0FE8B965CA8DB4667BD41B52E497D60C31277AB70C19350B2C410AB302754BBF7C126C1C9C8C298927AB39E9B4A024C0F47691880E11C0F8F7D5710D480FBADE860D72F43D1C676118E3F83A76FD6CBC7093B7BC18F851CD93D81B0564D4BE4BD39135BA2ADDC6A6DA8AB8F7B15284794E935A339E234E8452F766DDAAA0532DDE46FE6E4C727856CC29D7E78FFEE115147769543175546B8A838A0F831CBE16BE864C733C63F37E6FBC1CE2A36123BED296103FFDCF8F3BC36A7775A9C17F69193DEE0ED7C1423FAF6AE7CD99EF943BA174A6262916B78F9516B0464E8BFBCF512B80340C489B9857798EEB539062F40E39AC8EA3649E787C0A87FC548F0CCB801AF8C2B2156FE3FF69BBD30574D8C11D887A98231B7C6F24C662A48329DBD3DD410A019715DBB61F72D14883FE891731975DBDE9BAD0C2A85FFD773297E399B55D78C3A2C25C27E4FD0BDBBABAD85EA6BD6A3EC8931E0130EE4D068ECAD5BDAB22865A537B3ED2312D1462EA6E36E14D5E49F742F2A232E5216FBBBB1802B5ED89E361CDC0D2FBEA4555A895FDDA03597F2B8966D147FA586BB53316DAC62568CC823447B24052680CF67D8BC8D6399F928781A682A8BDDDCFF8785163A3615809D1D10E14ADF471CB1D93052434CF9D98F9D0D849283079FE431B8114EE9292E52F49C9868A013F0403A20BE45A2E157803CAB01F9C93701402595BBC90132E9FFF845165C799443F8B38E360F660AABB901485569D2B0081D00978B8A1B059BE9E4E98EBC19B027592E453FCA390F7C9DA085255D6A7436C8F1A857C547545FF0130A9F1E6A1B2DCD1EB03F7CDEBF39CAC153817CB450E501A62A1B93C450FD18CA956659D17A31310D517A81DC62640D8102DF1F79794CB7C096B5E37C2AE352E0BAF1A17DC8794D597A258BEFC66F26131298FAAB9EBD6AE3FBFB6DAE24AD74496BD1F077ED87BD1728D1809E96F70AB8254A9B8E3D30432700BC61FB747141609D4B9057BED02338233EE71B26364DFB9492A08933A2D3392C6453D34F33940C54B956BED2C11D9D1C68DD135AFF9165F3F2C801E0FD1480EF0BF99B95C68773CD2D765C1ECF04E1CCF68E659FAC8CDC03B44B5376EC888A485F7F71EF2E24195D75016CA6A9229C2D0FEAAFCAEFE07C46D3DA5942A15AD5EDFA8FCAD9A46ECFEF23A31F342071DA70A138BF5AA5003B70FEE1C00514EE0A3A2D5988F5EC5C279D7BEF153844DEDED0222DB3EF8A4579AF641444ADEFA07AC6CF37F58513771B8C7E406585296A7A2B6649B2FC1619BADF31951AA902EE48D5A9AE8DFD14A160538FF861FF64BC8E577C6E77F79672BC0273549D14AE1895479F8941AB0BF3093C5C439591F8A4FA453A9784A1F76FB792732405F05A8660740D329F2F68CCB6167D12958CC58AD567746667048C696FFBA426D40027820C4C740E66666E50DFD07C0ED76DD4C2080FF1C29794D6F17570A1B9D3D9AEB90AD34626B94A08202289A6409145D820C962183C58CB0345B287BE9EA15C5C443CE113270ACD15A075399DEE56E95E4DB23EB19E87C3E29BEF00D00A5442E67A7EBC5E12A096090C6AB5576DB5BECC84B8000D382540F98C41EDFEEB99D3DAA561FFA0C7FD6CC16FBEB6C514B45A70B2358EF4A53268612BF022FCFA354A80697225BC2AB988322DF31640FDBD05EE154F7C79A89463B2BF0C218749A454CA38DC8B5D1105183B7108E64EF8DB8FDDFA6BEF048C14CE5620A456DA5CB576F0BFFE4FFEB8333A9211707F5617628C2459A2104F8D5FB7B9581EDDDA27AD3BDCAAA7D037A3F996EB765237CF1C42B090F3B0453DABF26F9C92DBA120BFB577350705736EE295BE77CF70A7D3CC6AD388A526CAAFBDEAF67614224B6363E14B3DFCF2B6F4A0E8E2A8947D64437FF0E90DB68DA40D87AE431C02E9BBC647814C60F3CE5BE422C2BF3AA8529B8D706A5F6C3512979BA6E54401F405E6A8097CD0156A8B9D4C434014C2BCCD0DEC4559A87ECA3CC06200D77C02718330CA621F4F1B58ED3493B9126482BC941CD34A5BDC4BC3268C780479453CDD932C421229246D9BEDAD0B734F8B4D06A3780155FE9A88DB8C540FBB8677DF962FD0E0E4C39197479A68E42D9AAF4D1A1F56071F994B1C0FB4B9E6D150220DA7FDA2205E4729FC5517DBE0BFD9256EC717F0CCCE43C2862957E8630C10061D36AD371629912E9C1FA2A01B45AE331508D42630B39E5DAB3F141DEA254F1C6EE0A934B4CEBC4FEDB5B1BF6EDAD35810B836AC2A76EA9233D12E39553D77D1AFA964F8B104C48BE49A65CAC8EB3C352EE1ACD5EE14127340D6747886FE47DCABC13CCCB3410BAC0F96C718CE69DAD106C3D6F3565781EFF03812306F65C82613DC032F10ACABCA0E560D5A673F427FB231362D46BD40BD0B811903C259C2622E893DC4B91F21787BF0FDB976C4A6286D799EFE8269F9E8DA6870C9CF1A3A29897AA5C9D2C75D7C9FB29E467DAFE12A414398C6CE08917BB2A322057FF7BACE20782256624C1B7DDCBEC3AC680429497E06C022578A7D8CFEE14D20122C955005C0C4D3851C3D9D009334EC9B036AD7E1B08CED43DF8D148D5F6C72BB87F52A458910B0829B2848D082E3AAED3251818F7991136BF2E9433E025DB193C2581D1BD438F180CAFFE618CA88E677D0798DDEE55C4CC1776DBAEEB564770567432D34BCBAF6BFABC62E75C714BC76EFB785A37F91446E338546B5A1CFD83BE448405705D7F86B2E56F10FD54E6B3A047EC215DEC3F787EAA157D317C309B37BBA666810167EDC9079A4303D7402B8ABDB03383EC7A37964AF35C3C18D7713F22CA9D278A3F49FFE6C7D158DD97FB23AF1F23916E88539DBF6176F76A4DBFE11CBE3F914880AD2EE49FCA530E483859BF41DA5E42F01B0503A39D9C7A8F0A86B3A8184D87AD5F5CDCAD88BDBFF3C66907E7A448CE0C98260507CE656DA3316186A19B902DF6D1EBC77693BBFAA8121F2D679394772A7A1D127BCC51B140867EE4DABFF35E303BCDE2493D5CD02D302833AC464E34EBF202542AD81F38855BFC1C369F25C1AE2B3DAB609461BF7870D68D2E96D78176C2875F0C277D2493F5653CBA632CF655125D01CF48E2773C67EA58AADB857EF6CB50614AC3D1925C016E9112F36A28E142DCB5F2C1CFECEE0B974D254C764EF65C496D9489F65C976ADEAB8A21C2FB447FD7568C7E7D76617C67C812DDE31108200E5FD20182A393F2E2D6970195F7EE3C57DCF6392755991951F5471E402F88AC6200023E4B9E4EB49AE838F2289039664EC744C544994EF66DB2B86B970D20317C8A853AE532FEB55C5B3C09239435E1024565FB50B0C91A9896B2369F9CABC190C3131BBDA5C8673BA8C748A5FC49EA8E671C424F39E0162A9E479C3C611B5F5940C297050122978FCFF573100FA891CFD64D9825319EE01086D12A81F1D10FE77C8422DEE9E518F37A74FD8D1AA0070C99647B758D7EB8648618EEBB22A2049BC18A6FD41D3D9F712448AC3322B4F9BA2330E61AAD6FB3048AED745198ACA0598A97DC5B7A8BCE9803E0A62E19A2F54BB2C3EF80472AA5E27EE039B7B4E722358A242BBE7874EABFC76FB3ACF9D7F00C7AE2BC5B841DE02A8388DC800855340CD4B0A861B4E7C04FC5F50DA66FD845BCE7CC8269D81D7FB5D4968566A7EB7C984F71B9B5CB3B1D5AB3D6669472E92CDFA16B2C6B5E67BEA9FC54ED393121BC887BF0B099BA46082DF688126891D06808D2F2905B4F1607182745975A5752D890C4023BAD18A5FF8B4A4FA529B4EBC1244D715F186440EB3EFD5B6930C58DEDCD071384A1519B73F2EEADCFAEC130FA6DD6A6F0233BD1FE25AE7CB268405457EE6507DED9202544E0B5ACCCC830180D4DDBFC65DB3E32C16FEF0C1CB73949C2FB02ADB9A22C5727F911D308B3389A520441D5B5A7CFCCBF1656E6CF5B4B1D10B638E3D84440BFC32E45A74C0D428FB9517D765166973D25EB5BE2A5385AA6335975A4C8F3E94421E7DE1DDDA6E9BE97857C70F8C339485B5A85245180A317302A2E58404A1DA5D5583A806E8A7C8CF766F29A816C25BFE9EB6DBC2567C0D1D4D971FD95B7CECE133B6CF6B98CCC6C18DDB84B4B23FEE7BBA2FA00EF32110AE0B525F39DA0B0A7DD8C7DBF2A7F8B3CC90420B5EBCDC46A2367D236BB993ECE7FB1059453D08DF84ED0E1CB17C357BCD681765F8A6126C36ED49ADA5C82273143906B8FF421EC0B4DF20E9012B896DC3EF63FEF1DD1ADC09C93FA301C906FCB38F28A36EB13B4CD4FF9A6AC5D2E146595236047005814048A31226CB80E2ED09DAD75F95D5981AAC594B8C2EEE9D02D9C7383CB7EF4108EFE0FA7BED68F3E4B0972F2FC78373D7FBDFA91BA0A1982D47A7E6FFCD7DFE17CB23EFDF20B10460676EACDA5D46EB5EE83BD48B77C4F4559C460FB78CC3D7EF8D3016DA618D1866B69A99882812BCD6F2E72C679D894C97465EEB5EDE357FC34597F2490EE3CA813237AE80C55C86AFDB734627D188819E56C884286B51C5609C027D9E410B5B7ABDF45E539FC23B71F9068DD1E51C6A1DC922CB90716862B2F60532F34ED97627B43EA6D6D6A770DDA98E53C9358767B364386B549DB2B91219F17632BB02DD407969CA28CD8412B7FC8455A9C028A63930786FE41FAA360D240005F915EDA9E68B559113AD23F66541EE22632ED38187D4BBF77C15CC9F873105A749711382E202B5B66E9DABD165F3B296CD2A712C82BCDF9C3F0B9DA1C9BC0A34D6E9EC01397008492BEF118B3771BBD5756B42817BE46166C4CD13C8BD6D9B75D73A147AAD5F4863D664CF84A84BFE465855D7F373FCCF6EA3CFCC0E28BD76E5A5EFD85EEADFB15E7AF47ECE44DA1367C90C30092271964FF524909B97D2592742832933A0B04DC59CF62387AE581A2D7E13756C1D93855B8839F7965A46D830A083036FF30E42FC5F32F9E0021F79DA5C62E16BB2BF0AAE7769270704676A9257F62B0956EA742D8A3D176188029358F90BD91373ECFEE5B46AA23373CE75627B0C45C9A4F15D07425B5C1C1E1A3882499F030775A3CC6B5E2C91F48DA0BCC98CBD74691D7513E3817798AC0AFDF0C6B349829DCA9B9742ED77B4EC779366979829555FEF4BCF7270328773C850BC9348542113EF19012168BEA1BA4C1F607FC941A1B9BAB11F89D5033FE873D302CE0AAA51BAF328F74448E70907C302690385BC3C5E32AB5DFCDD887294377CEC6E1BA90EBF9204C28DE77CA85C7E870C3C74B91DCBC88CB30D07847912100B081578CAAEDD44CF9F79736E91EF4F0D8C3555D347ECB2AD272607AFAC189D3F8AD3C7594A66F2614133658D9FEA2DF536F6A11AE1B2DA795EC55FEA5435761F7A2E8F76563AA346F00CEEEB41B0E5D43A99BBBA029988D792FCF7B9E085C1052D319B5ECFEA85E84D354B832D84E370880D0552AB9DD31822D29E6476873E22E98EBE74A14B72437F5EF7E36987E905722B781B451053DD5A5D3CCDCF5ED40BFF1AB4D43921DD019C1F41B0A9E75CF740B6646380DA9A1372C4771E29C4772F67F0EDBA8FFA3D907ABDCC881F5D76E68EB8124A45478E9B66B061CE302D1605B708224A7DDFD25709F4F28E803F0E9FB3E90739CB3BC84CC84621A19F4050C4E93CBE089A2ADC1CAD12894C1E1000B6C9495ADB0B1BDC6DEE4F21B20689FF0F70317181A475F61626E717EC7DC48555E63A23C494C5D5E5FE0F60000000000000000000000000000060C101D2330353D""") + ), + new SigGenTestCase( + TestUtils.hexDecode(""" +8411ECF640CB9A3AA61EA95BB60D5A31B099D67046A1A1953EDA3CC207F8009EB1C0CA1A40A71137B98854F470CB52EF825FC9D08CCAB2A406388DD22421DBA0A99CCACA95CE95F9E32BEA8AB715A39A8271B7789699217B8452188F4AA078C4F481339C532A2C2DE5535CC7665237D357BF547A7A051B0E1F47270231F00029A1B204049189CCB20923322024468D5C086052461120334D4A06461BA9518C148922933190A460D9B4852107929220310B31061A284AC2122894A2300A048D1A9609E444319000269886681244841397006312056118219424602142868AB86489C2218C302EE3C2611A366DC1405093304221A24409B1901C20821A8624A12800913430C816860B49614A44090AB84DD2B25100948CCB040442040911407108812909886C442082C22401CC2209E194484C263040082660422A03C08D12B90D91220220172820474981806020B27000018518C90C0A95051B224053A040233830123246C0908D990201C4426900954594A070E218112409251AC5908C2602830225D0487124B90D9C024689B08461146C62404D1B45440C886DA2080A9826895AA46980004E8A308E19032DD8C88511394549948101B225D330690B440C52862D12979048206A0C041163C808D8A60189B0691A858118882511158E0337108B200D82B229E184718304300B298A00A4610A1522091748D13006DA262560342E133461A2182A12B885502810989408C3941118A10D0A102A91162849906924348AD9C441A004010CA521E10610110968DAB28D08A801C4A24421C37122B570D394710BA700A1962194886D0A1802A2240C10900910A57020A86D6130918A04290B474020C6288490204B4648518420CAC404D186440A257010460282A6101A0166534804E1A04CC2423208C54148C07080160093B220083382584440D490648234868C04309244628120620A154198122803340520084AE4122D189349149565A4C8015B184299800502A330600486DC026C8A488184085103298188928DA2480D624065213371C0088699822CA332920402821244649A4260100131A34040C3B8291B130142801022C2200CB131142885E390858C24664834451CA231CB1408232506D0982DCA166A1A982950C26D128065C2306824174414496400B36CC9022A0C1704531225E32808C114021B18049C340D44488904302D4A242E1036325B34104B401044A8881080290AB16C1C9871C44606CCC81042268062248058B08024476189A43020C67093042C94986523496689C481A1446EA3866C5B46325236509BC28C23248622B39120228D13040E98B28519B02D1440681A230E03C92D521829003170D410441CB760C132490385305412058336021394911815204A106A6218259A883143064C839028D9B06C42482E4C286CE4C88018148D4B06514B8280DBC67001A8280A394908B86DC106451C0866C892091024521408621A27901200691249658B4852C1140E24488ED4446CE096715A347241800964884D53A4708A36890CB964244391082305098325A0000652965010054DC93671C1B0444338824C42914C16901A314101014212232A09882C9826300189440293312484281B8525A3468448141081A065043169811872910402A4364C5B348821354982209083C02123942943282043A8092437881B454D48880840122521004A93367012840D14A0055A188A43168601828C11352C04312A00046409054D1816300A0849A2B67124128410B545DA228DDA380E44B44C61002452A46CD406122484604B148480428EE14400DCB288C200915C141011334151980158084ED1887058B02904810544C84449B6881005310C132DD2145114008959282D63404204042A84160D9C1245481091A4482D9A1032E1883101302E14120409B25109B084E486600B4429D4A88003932CD822001CA721DC8680921849D80242021844204601CB2090C43428C314500B18090B9061424426CB288DCCB845839431C010304124319C304ED4C82CE3440E24427201230D23C80524216C8CA48D528669C2060808140A0098201B13684218655C381004C31121B5715B242EA216698B1040530490030441A4164DCB483049286860200DC84412030324CA060D242202DC3082132511119411DA36905224468C286421C3505324859A462A13C72C403272DC9260508240D20624E833A3104705DC227A3AD315484B9EC824A82F500712D61D5693BEB0E024505429B4D136758D53F67E6A5C66C247B3D03D763B77C17CA1632E2B0FEA3CBAD528695E70753FB16A0727C6031DA837CE9D9F7AE12A7F091E8E246CFAE2955424255667155384E6BE2A03689BFCA5E1C58C7F16187AFADB4CE28E2F9432F2419173A4CCB0154D7F3443A15DA2687E608C02D6392EE3942159C2996700070C00A194D27BCB61945E04A94E95F60709E59DD49CE955044CADEDA9EE37FC28ED3F3EF89FB5F03B77C6EFE685706B85A1ED1E810195507A55023A2D1CF2A0A9E78801DE90E1C7B80133B0A7AA8E17C022B574B3D9503EC2E152A4C04564C9CD4F84B8B8342359EDC28A7578F5AA73F5A480DAF80F9831E3A1C102BFE8DCCDC4621AE89409FCF986B53DF21425C9CE4C9744B65F706AD99B975E9907F2C8B5228E072241CC1C25111F5455FDCDE4D72A28402C2DBE6D730F588387E7265DF3E8B3B6C78E0AC3A5A2839F1E2E021843BD0BFF9C71C47A0BB0DE3AEB0E99845821B10949EA2C72447C64BFAA143220156FB54C9A62F6EAD3D534CA9568457277AB8EBA9E8EE5F3F42849C8E661AF178461663FFBE17F78D41C830F3342EF799F97C6B0E848A96C4606F4B404C382F5CE9B36E3CE90361C4E8A7665736E0C5ABD625BC4E1D1F3FAF90A366E3D3D9606C8FDBFDEE49DF2CED8FA268E6CA4CE20E3F4C962CF85E37BCA06F6385072280E5F5533711B2E676946813083FEC5D6E2CDCE4F4DA6F58A6BAA13FB159C6D8F33B6FA8ECDC0E792F72F64766027DE385C3060F38466BD93C8ED981CD3F7EF7B81FB78D76E6BBFDD565DCE1B018372102D0BB8537C1E60B1BBB564D6D98E45108D45139C71A96AC788CA14F08837E200DC1F593A19337E518C18E40C4382ABCB486677804D44B31DAE664959D908C4611ECD2F657D46B72F009AFE3501AD50BC49AB94EA2CB36A07FBFE8E87D5337841BA123FD8AA72CC9A4AFF0235F4EC2B08796DB4878A9F3939834C324E4E0D37A9C5C59153811F21AB57B260E9E57441298EE7032C819DCC475236ADC4EBFC1C5B26778B7156C3D37667C8EBEA75477F3FAC495FFFE7651627C6C87EC7CDCB60A3692EF2AC72A8820225DA85A5161B4C7274DB3698F5F1A92E197F99689B8FF5970DAD8776550038EF55825E4E0C00CC148DAEFDE552BE9BE94C351069153A3148B30C1FD9E9FB6E962A9A8824A1FFF238395B61C422CF56013BEF428638F961BCA565E5F4BBED2831769EABDC0BB3F5729BA331CAF666DBCB7AA15463A4D0CBCB26132F598789C96314F5B51F34B9A0F48DE75DDA95E2D294589EF30D43E7C44CFA63865123DD3ED045038A8ED261007374D096A46758138B7E112A58482BC3F7B14A83B7CE7B5C219B8A16ABA3514E779DAD6BF06A3B530E6C2A2E5C81D1C6152A63AE3D1159F4BEEAF8D57F6670CB15091CA10200D7A76364D1A48582DF316B7C65FD0816096FE238360B291772F8EDDC6380465261108B53F3C7EEE33C5950C76A87ECC41E86432AC231966DAB8A0C1FF9FE593F98FE34625901CFDF163E113730232E98F00FBBFC068028CAA132F071A828BCFE78F52713DF0F7EF903D5EE10F272CA06EF94BB1AACEEE6A9B89D459B48A5D580B085E844AE3DD20B866796492B526FAC2028DECC362A7FF42CDF73A827E2EBC3712A15DDAE09EB26E57CE61211A7E108B8C588EDAAAA165C2AD916EE80162024A29B6546AC6CA73FA09EC898E93FC399ABFF13DE4E4DD22227105E207DB1C50855079FD96383B3BD50C32C3D1E37B8BDE972683453C3F9632749A84A93CB34CC130070E51FC0D00CF504D9FEB9A8F068D4A1D7AC648C8AE47DC54824A69506189861E6838A0B08E13A13FDEC95F9148F2610084E4BD56BAA4E30B39862F86CA9600B9A3A945A7499F391879390419782D2934D45636013AF6B23A7E072B393E6F4E62140146AB55C9766B872050E085C152C79DFFE2240CAAE43FECE88B4C44791ABAC91635CD3BF47981B65215F36AFC2ED63F6A9F56AF736C2A0651A6C9208C3720C8D5F48A0B42C7ADC7F6161DEE6EB2AF5270612932F7ED33E2EDDDC61C4F3B291D42FD90D2F28B64D26863B07E5A2C445167C7EA3CA8E9D07FF0D44795903416110051D4DD9C481124A99ED2DBEA7F59C714AF50A15F6FE518277A3C9B17D71B4265BFD2ABE06FEE2E27109BE2E53D1D5C9D287B383FE32500148C5158CBC6932F6684B07FA33E122D1406A1E313C0F5A9901E82CE5224E31CCD04D31058B4BF53D2E15322C0C8EC177C6D15A250FBD3474EB9D255F548253505C979E65E671A6B7D1A60876254314F1329BFAA0E5E8BC8882F6BAA9D5442C38E0A5C15C2A61F92D2063385827CF052553A352922F9CB6C035D1CC5E15E2625FAAA6FFA2E4954F31CA10B18A3ACE08C122F826CB33F9D6995C12CEA96766CAFAE5F32A381958EDED4904C12EF43D66BFC7B08CE8FD61D42FA3F6F91ED1453AFFF2819559A385B932C484530D33BCB406BB87BAC9EB3F338D77B506CE59C6CD59CEA376ADE92B9D2587D8987FAEA9F0C707900BD649C5B81E0D46C17D467928A2CB9C53AAF0C55CF27FA09673BC6A6A031402126A163C4EDA10AFA09477F8ABECC81A49334B14CCFDE2FE4759EE15FF7D7D0D60111269ACA4ED68FAB56DE7B6F10CFE2C7A0E6DC968C8F90444D535AA34C1DCEA03C84F1DDC7C392868EB07289C4DE14CD53D5C7A1B768B312F6E238E2FA6B93BBF14FF286DA3DCF9CF95583917AADC02DDAE785299907BBCB06D559A04FE1DBCC75FEDAB0E42231F6225C9C5761E4F7603F87DDCA8AF1CA9424D36324659E2D249D7A83FC187B41434CB7FDB08F7AAD100DD2D29E66CF8188EFD1B3ACDE47B281BE8974C255FDA49CBD06E55596CF3E387430FC67F8FCC4B82101CFC11184B3E16E62F18A4355AC5C6F84BEFF3AFC12075B3BA48ADDA38CD6FBC04346EEA24AC60F2B527AE8F3B61EC32EDF64D273322326C2BDFD441BA40ED87852A0E8FD197A7E7E05117AAA639692C35CA5AC4DF9B590DABB9806122B31047AA33B30BA68CB405E539CF9927B6F942465DADB9F4F70218FA95565E2290FFCE4D77D122C1148E0AFACF3C1CF89AAF85DB4F06C48566166AAD370EFA52A95FDB52BF5E55FCF577D43B0C2C5DFCEBEE16BD4A0A426E84AB1FB018B6D701EF4981DE257E2D1096E206435DB0E52DDEC81CA2F8E16DEF12D411329A1B0CC3C3E5474F452D20C2EBE9B219DA00CA07B8FE5A14E56E8DA3EFEB1539EA9F2ED9C7474DB12B93C744322746AE42D777F22E1435D5B9C867F29C2BE6316A0941BAA39BCCAB41C9A7B5FB4C918F6BFA1FA76FF242A2514AB5E4A7B8D65CF15BD4336D151BB374D7906DBD3A187D02C4BDC33BF26448085F7D66ACED1BD6E8E67F4B3DA551CC68A4C493AE35AF18F7DB09133EC0692AB08D6DF34F1FBE23491467B5457BD831BE4F76830774BCA5131CD539F47FBC5E6F041B01EFB6A7E586A02742D50AFE17986A3AD7B20524F9C1D2825BEECC5A2AA757A299C46F852D46834EC67AA048832BB46D76C7D752150854B8689A5D0A501D419E5269E34C13464F37FEF2613BA45EAEF5083F7F699213121456E5AAD50722E8965B78843280DBD07CE3267912BA2FC59AED7540CB9C6B464B1F983892C34C1E2149ED712F8A56B2C6AEF7996D45A4AA3A6EA833D5DC471BF3E9A47E83572EBDAFA3D3DA7D930A05501F0C9B6EEE0FBC9CDF86190C52851AC7961C36688F8BC11A39251ED1E2F1528F98FA360CAFF6C1F2DEEBD712DC1EE31A4B5BC819AE169338E4DE7BAA00224CE4F460E25D2586BE63AF29705D98705840930E64EA0A9D7FFFFABA09869D78A0E3866A137A412AF4FD5A5E671B735FF456C79E24BEE529DC0706C065E0C6D8BE32535DBA578F36630E6C3EBC3C69B6FAB135A530B4281D40CEFF4FAFA364CA274CCFFE3F8D16DCC2AA7835C7F7E7A376E16ADFB940A2725B64EC782FC5F0C36E5F990807DB90E6D1C6869D6406A07CFC0B84A2A3C1A4E1585D854BDC2B506EC8427940299A9B19B2FE3116FD4A0BDEDE83EF42741262E7A9CF4393C2DD8A7E60297CB76157C861ADE284D44E73447186AC00B064B5E02568716565648CA88623E16EBB81C00D4377FDDE04259AD5CDB9C8FF75C4C8AC2D4F96485FBD353130548637235D100A646FADD5341927CCD114CD6095E97C622F02AADF7FB634879DD0614EF0ED2BECDB5A15F2B05100D97BFB128407FD8D54A6FB35DAF2B206DCB2634C2B14B33A96F7DEBC9925052B075340F48A096BCEB99E4A0DD1F9A35E8CC14EC724AC3ED3EB512E1CCFBDE1D755B1B3A3F63A66573946052022A89838A61DDC0D4E2A34F3C2067BC51AC14DB95DA6EB7C31505C7872620DB5C1B623A92C91B895A65EAE4938D3F823DF37FEF1964A71DFA1F6EE034F7C07772835CBB43465AFB6EF5BCAC326FADF26F762DEBE12432EDC8E53390EA89334E9BE32E535C5077D6E77684A1F51B1BE2F28BA4DFC42FDD63E88296262CF0C66220DB4A88169CA24B4F8F1135A50F9696C0ACBF3C2D3B345010E43230DD4F3044B2C39B91A242505EE5B2F690972FEA4526A3F473839763021A620830384645B9BBA9947BA6BAB37A1727DD94BA14AA9EF039023BBB46DE81337011DCC78B8BA6F9BF3F92EDBDF55B0F9C7B0942E397EEE1EC85719C4"""), + TestUtils.hexDecode(""" +506462786389055DE2E4AA2A7C80388315711A7B5DCC73F2039DB99380D48D9A3DD8CC8B929B0AB224DAE74EA90808C302197EE9D847261DEFF4136D3B2A37CA32533384443B9D935AF2C384EA63E7160BF4BEB89EC0EE705D10C72F2F65A4E75ED2B1901F14B8C1D21DA9C6B8842DB62443D3DF12969CE4E45298FCFD6FB103B87B0817190C5ADED4D04E3BA4D2C3F60CC49FE0695D6366EACB9C79F28C9121584D997B7A3A7AC3243C3C75FC86AF81CC8B888E90095051F7825294CF7E1A11464BC153548F8195522FEAB9AF5AE93C5F6CF80D9ED76C19A0ED0BFBCFCDF30FF6EBD0E5C20EEEC4992765FD23F13F027E2261C38D11FD1631846142541ABCB82C0EABEE5D675EC130861F9BEE9D9E02305F168C85201DA1DA2E4D21CF1E4BB8C2539BC1F3706194AEE7E3ABB2D7447EA531619FD27F0CC7D09E5FBFFB0DA81432D173321C433391FEE90B92E8EE3F39ED492E78327D8A3586B7052602607EBA79CC9AF21132C7D3A9931D5DB4937FD5C5611F79C722E0CDC48564E416DD251C46C02567C4059A0DC2F59A124A4EBAEB9B1B04277CC47A9F345FF8AC3F8AC844A668AC6F7E1BF1C9889C3E42C1142CBC31A46EDE21CC84F230A483B5CE23A901375B27770BEC8F0AFA25F301B7AB43B714C6D0E98B009FCDDFB75C0E26EBEF7C9DF5ED04CB4183028DFADFC09963AA8CB3A9A1BDA047F62460F2B88FEE1C05D9E68D646137F660B68470308225FFC097474B2B2BC5D50A025724FB2CF70873BE7D04C05AFBF1D7DED56693AA4A4E495B1FAF9762DB83DDA6E75F530ED5351D171B7BD06E5ADF46DEAD06AEA37CF262AA33D062141F8E394E731B3942D084E583090F9CADF87C2B81C4B7F114D150C221A12393BAB92727B828C9EB86600B969E1B80F33E1304CEC68A1B3B474762175EA19A4D67220004FD4EB0B2C643B69C00FF3876E9AF63BBEF8AB6BBBE247668DA8F2E3CFD0B95D6926AA3A2CFF4587C45DA60BDB03DA78DDD9758FCF9926FA1F080A61FC0FC7660BDE9B4913C40534887B04E2DC666E981AEEE38746C52BF46FCE0E2233CE02C9307262499BE567C150CC54FB9D96B81D3A3E200EC8F7E87E28272E7B956600DD7692799473A8C63AEDBC8F3F43542B9E399398349B896BBA16E5F26210558DDFFB984FC924E1B0D272CB8834B1FF641A894EC113460C65C66BAE86248B48F675F1313EA76EB4DD0AB6EE41014FD7589D1A7DAB16CB8F113A3FBE7E01EC67B0B3CCD81C0A8C7E9824658C926736A574E9A0729C3BFCC34E0D4BCB1606E93287494577A6C4B1090FA6B997DA098C6CF555B5574473B1063B739CCD139C2541CC3F962EC42BFB3A40F4E64D322836EADA5F574B48B5722D7809A3A20EF1FDF5F3EBC000E466BC4CA10E0CC6A1390FDF159BCF0182293D9C408A8570789C485DBB977642074C869960E9648641C2A80D8A1C4E474FB98D7A3DD75D7AF01D2605945E89493699EB53E30EBB0F936B63ADF5859D9EA1DCAC44D0BCDBF2A069982BE907F1B560AD8327BAE013FBFE6E2709C9FDD498491F1D8603F9F6C9B1A643F6FAB97DCA752D9BDA1DD6BDBF52B03ED7768D98E46092D556C266E30C77A10E68AF76AC3D359D8752E2453B2E75DFECE6F66E6AB00EF37DA6E6A367FC808E1F4905339F4FA73545D13DA7E7DE49CC0A2A63639A96EA039C4EB643627B7EC4FACA1374EA800A505A80F554B3AB3233FA492ED6C17B5832BDEFB3A99FF1C64B35F1531A023415290124EEE2C9A7E34FE8563528B6A4B64DE425A8FFA91B753973CF0C96FB2A8A3F71D58B77C93C5866DF5CB5152B3A0A32884E349C63870E9CACA82F121EC2ACAD7B6052B0D74E9C28B20C76A7A821D192E11B59A7C8059FC49662C655551A7356046D46FCCCEB4DE1F5FC91F35B950F630D743C8218A10AB25D2FAC25308225540FC24CA794EF171DAD7258C2B7FCF43297F6E77A6E83184114DBDBE408EB644ECF49E04FD79769E4FE9B0530F21F8E3913A51094D0E49DF012144EFEC415B8B2A34AE2462607E7B89BB86F0C733A5553CAAFF9B19E0799A1901657BF4FF5AD6DA7886B477358E90D56BEAC6A963E0669C38EF47173503B0E9255AF1F153E673813053A899418E2BF217D01D9162C073F256CEDB73DC062D201FF6056180A8A6887B286AD6D3BD6B1462231D6223D0DF2BBB7299FA6FEFAA9A297C56ACA28E163533406141EB2E65F0C94A6286A0579C76A3A8EF96DDDAC9DC6A550538AD345FC4AABEBAC04682D4AB0977D439CB14F02FB504E10252C1F3ED01A7C4BFDA6E689D842D9B9086517A84AA4257D1C8CB842E15DFA615D2E3F2464E4012C0067EEE60489C044F43050E5B1AB3E54507422E1368CB3EC8CFB03A887DDF9695AD95378F875F14F7DEECFA54A775C60C6B7025E5D6C0563E0E76C05C93E33C3E5AB6D1E1C051B52D2805D3BE0A4D3E8F0DCE6BBA1DF04C7F76F7E13D8C3CFCB2AB04A1E605D4DAD72A43D5223FCC36EFB34D999095E742FB9DD7B69A28E070FD28138B403DF1DCA75E00A160ECE9562C92091DFD3A24C53645DED8E17B39D8CCA4C20C96F9C9F9D14AD3B45A1E87DA75B831D400AC14BF34A9840936C3277A135BC0E8C65E0F5E670AC912FA586FBB4E149B09F64D338C8C886BA65730039B5DCD0DCAD9D6EF11C228213438A1489F4FDC39395E8447212599BEB570D186883E02B442F8BF97884EF98D3D6E59254B3DDB77DEB8429D110F0689715F3E0A4F65908E5EEC867AC7BBF27CFB965727AF0A1EF37B21EC18CD60A1C87287527BCBF5249596083069315699CAD10FFEB2D87810C4DA090074FB26978E56B7D06186C48BFA4830A0BFCEF8FC7B95E73F64EFF78043E8D93F57EF6DC636C8FF612ED22FB21174EDAA59BCF89D1A60F0E1C15C5F8EB8E6A39139D500E8F28A5DB86C125C6C76A99BC47DAF66E679121557D85F5093806B748B3EA65CAC386B59C0A372AF2FB7C84111F0E0FA2C71E137958239534C4A012B1B421435B7BB8CA577DCD8C8B0A798902BAC9B95AB87B6A0735D1839DEE336996C2357C748F4EDAD858C81E2115595ADBC173782E36D4E720A5D29A5681231F9BEE91D455554A8632F7F02FAFAC0FD9D03804B10DDF4828A69AC1CF0581D2C88877BA30EF2982E0827147766F8B71E264E82C3949BB87562F810DE835CCF78A7E5FAB219E64B1FC615E7C952577B9B482F78C0D0C512833994895A125F43EFF066CEE293004E9E0E5288A61EF209EC52233EC64BC0DE76C78EB2678559724FBC05BB5B43CDBE86F6C481AF3BDA11EBFC0FB384AE00F4ABC212B0518644638F01C38030DD05FB06A7EDC6406CA18878DF38ACE8E974123D3699613ED46673BD04ED51C352F124A8F89DF8C13D2B44245084B7FA02677D5287D22102AEF4A4A0AE046BB1C6D9FC9733AE5066C69A10589B0F33780622C1709F179D4E8857564804BF5C4D83E03484FDBD1CC4D71C6A2421AA59043DA85F0B51EF91FA5DF9555072278331BF3102F5147021662D135F3011FA48DDA7C97087F01B7F86D549F41E244AD7374C7C1F698801CEAD305026D17666435217799A4A5FD0ADDF9B8BF6E31E51B654E4D697554D5F574213CF579EFB1B11CB2C136FDB9EBC0DE4D16DC9DF43E17D88EE22EC88326F65875439066CB47E4C656A3AC59BD9A576D05ECAC5B3E7AB7B1A3C0C1C48807C06F1AE4881158D6BAE9620B08BBFFCB9940B6A6D04396014CFD54E93D863156D16F6F9C1556DB1E13E630326C8B681CAAD146F32B6977200B204B632F6CBCFB2BCE9670D89A9CE043E2004773913188608455FA715D1577E03826A2471EF0143DB3C39E03D890F0CBC85040D1675821D282822F80EAAEFF5CAA49699B68B89422D1BEDBC3041AE2A3D6D5205C72123991B21AFFB312F5EC8F96922EBB44D7A0F8ACC2E390F9E3FD82353276D73E85FEC904AE6319B140E5C54FD5B6F19D17E65DAC5EE270DB3E402534B0F408BB3C554D93BBD32B255D478F33BEDF4A192233294B320393D38284D7D9987708C019742F2FC023C041219FBFE2B603501629BDABB9C4223F5B751DB78C144CC50D3A35370EE563D6DDECFD6D715F08E14A00FC265D8433055083048396F1BD4E9F010EFB974D6102401B2FECD972C26008A4B94952EBC61C35DC846FF7B3E20DD9C6E033BF1185F35A5F02139068E1D4F30C4778FF87057F34CE1D2D40BB61423EC055BB57B56C502DB8D0685B0ADA42F9C52B590610CE2F8237F92B71B3AC2AB75D2E6ABBDBAA1E554D99CDB687B72DE98ED0FCD618AF5D2B0196F1D3C19DB77686F01228C3D1DAB1F171A56DF9311939CCED0F7B22A1B77F473E8DB65C0FD6E307B6F7A0F0FAD69E5C1F87D01EA4699F4D5DE39880CF2D8E910313AA6026C17941C41252C06687A085903A502048726AE8EDDD2D8918B71A19B807889B6C2E866FB818810F427D2A7B6CB137D94746A88BBF068EAD31216A5511A54D81031D36C8139776E0FE29EF7C8A5EAA730C3BBF05988BB892F699F72F098F2931F9B4DA17243404F64C311767A98547284063D44AE74735DD246B0C189DB322058198F1D176EAE6E076965CDE68DD0DF2B284D23B94BADAFB8650F21B148B9C990F7044A777F9BD229F7905B242CC2E267610A42A5C3185C64079DB340D86598C589F9A96F3741356BF3E6D2A811B6551850F917E07E5289A07382B8B506C510C9396DDA81DB336179EAC1F84DB9D0E7BF52B906E82FD132647A84A299BA202DEB338B79F976A8D257E246B2B1B60425161C72D534B04355B2665129AD8A44C09D73AF51DEE7043228EDB62B858399B5A4312DDD7ABDA09A846A60FDA8D0C00E0ECC364A6CA95643FAED93D44BC8BF1264FAFA6D98528CD3BD1BFA352BFE1FBCC202F44496FDAF9F9EC53007915EB67F9F8BFBC88D82100210CD471C48F5092AF4253302475F9E60C287F0A8549DA00538432A342814E1F6043BA4355D72268F6E84A43264EEC3CAC024DD6E79143EB502A58E6F8478AE985797F00A295E84A0F669BD9252A3AAC6B2AFACD7AD398DF546"""), + TestUtils.hexDecode(""" +C1023740D113A2AA12CAC8BC94DFF2FDD05E5A70F45818FE3113DA3D727C8F99F9268FB99F75F98D3F9487A4084175064A4C06548D37E8FB76ECAE0B8613BB804C9C04ABC54570FDDFA0C938A339F5134C5C37D7FAA2037118ABB9D1FBC522A334AFE43E529EF3DA76AEE24B27EDCF98430CBEDB46EFF55E9F53FA479F60C95ED0FCDC31666CF15AF8EB6D4B870BF0FBED290860ABF033C9743CC8544B02C8F85BEEA3817909B39D3D68049E6383EFF3677D2B94830073AAA44EF9B056FC1C316A2B9B94D347EC2A551F65F540068D6F787786BFE45EE254663D6B99DC1A8E32620451A839C9C7B6D637B993F2906287EC8A0F270EB23E99263510BBD7364561D56FA3E73D87F0C5632983B63C9915CA85A6C38970CD6EE1041E7307A797094EDEC1F84D947EE2E4542B3865237C60AC5125F7515C805730F07D2562D76EEB5DEED5E3AA000E38D00A64E754163A42CD2508E496E02F7FB7C1078AEB7D673680EF47EC7D8F1130E4D61F631D6B6D43244345322F3766F1E246DA51438C265F66BFAD6C20A4FA0A462395BF7408B14A0791C21BA5C307FD38414B2B8DE07D4B134342A9C12CF170D3DDBA18BE378D52963514ADE5F9EBE135D86F0AEEEDCCED7729E2AA25456CA85ACBD18BCB8B79E97DB56AD29D94BC295F1F89EB9D8E71FA14B1BCAA46B8035C4AA25D14DE7C35BB5A02CABEA4EDF9F090873906906F68A13396CD2124410EECADCF085D5925BF6308DDAC2242CE240893CA7054C4B4C19332F4ACA897BE8F998D83E82944DAB9D65125085176CF5CDBF60EEF8954428EA0ACCC6A7FBBBAA9DB34AE72B93BF5D3A709CE3CA346644D5FAFAF3FDBF9D9D7C504E86371E0DEC5B3E2EE120E064CBF4FCD455E99207549D27E233D06FCAE3699BD34D5D7F195509601154044EB3EAA0527DAB3F9BEDBB316023AD53FEB71249F0BCD3A08F0CDB9878403C1812D36883DC444089999FAF16A40B75679E2F053E6EA2B835DB463C1202050FAE236134BCC8703397E1CC344CA7901295D3AF28B39853758D086561AB9A6A9904BAEB37C2AF4D973B702850BF0FCB08CDC48D582238A0FA0AAADF832AE76420439BF29A9B32FDE6D67D3D6B25EEB521218B013AD3408AF36C466F67FC5722D4EB2E57D0E58D045D46592BB1FE907D56E0B378FF59DF68B2819D21BFC686364DFE074764DB8613DF0BD35A919048A2CFAFDED34CD3331124E8C5F8811D730803845C7CE568E66F9E50A1EE2DF92450321BA09AD2C4D75D1D92CACA21A2737672559B1B1894130472F40C177F1CEB1C348EE8AAD47B5D1ABFE148877C39A0A46B8F9E4D3FBEF95B774AB5D768FE130711A9DD9EA2B8F4DB4E7F938352772ECB46E9A00A9479C409A4F9E4526DC307BAF5C3A0493EC9E1816D11CE212E0054501D2CD9865F6E942856D32B971E83C81D94DA4F584B230491D2013E84C898386F55C8F224BB09FFE58CBD0D9E9D7E21BDC2AC4335E2FF94EC95CE2D509CFA5EE33BA848D75D046D8F576237417701A7B11B3E67BB9740B7BA3D7A37784E6CE081D3F41E8AF21CB46D46B083796A08721B7E80F0A157E86BE0F08D3125A12F4733F8C27236AA898E6E950BE190A931D07A08597633F5187767D3CFC095D1886769E1CBDF6C20FFE471E9396476660DCD21877D799A124A2F0251128F08F9D45AD45F0DF38FC9A42CBF4EC4BE10ED87FD86B63DFFC5246239517690696EE839A501EE221C16A153C0800E7D6B4385F6ACFBCDA62981CD22F06A12497B97D13C6EC1F39879B2432BFE6FC7CB3CFA78DEC8B3B800916CE777BE327641DEA9E7F156EF6E943161F78466C0300A29B1B5EE8CB68F532176DF4FCCF606738A95B3224573D5DC26F90DA69146BC8FA37D1917E3CF3336FE8D444B606979D9650B2649B1F016F6B9543E31C6E9F48594F538CBECE25C4EB8F78955BDC88EB9540BF7AA4AAF1E51DA958EA818A8DC9008FFAD91529B4D8AD5576EE1CB21216136A0C85BA87C01B8A0E8B9B31F7826537A0F920F335CE24053500CCC4EFDFE3742B9403ED950D61BB27FABD1E397BCD6CDF885DA0E3559B21197BE6FC71B25DAE1C4B51DB765C154E4F313A6EA4BD79144CDDEAA94AAA9AD40D0167C5779F022116E56154F74F42D67540D8D0988A5869FB30ED2EAEBC4B0D80E1A547551BFA5D77A695094162557B76D52472A1601884331C9A0EBE0405FA61E5F5B38278EE11A315B20633F534115C02114B24D07A343003E2730BC17BE1F4432B617D0BC160BC2249E7B87A4A4C0B8DA3C6F082C8D515DA2E90FEB30852FB35D2A19A0A39C4C44561703C97C0B660A05FDC553DBFB21271011BBA5D4ABD2C8B757BF022C6225D401A56A33C901961DC765626B1607443368D2BC37886EA65B35A9378923B9F6D2962B1DA2A4DB3250928E2DE09DDB7C2B6D27EFA33A21FBD7C3C38B6B193A1AEFCEEF9AF68FAB8F87D20E1FA1DE0AF8E40BD00AB5C88573F2FB1FAE76028EF40793EFB36D92091A353F6B044603711514C4E5288BDA0DFE9BB6E10BE6FF42705FAC7C05DF1E49C7C93B464C4F3571821378B3AB9BF020999B2421F6BDD98DCAE5F976EF507B9E0A02E1F7C7BCCEE1849403F2FA5851D8000AB7933AD568313771A436CDF40909360A33D83D42ED1D2D5DD1D1BF4AF704646DF4178D83B3031D9DEF090CC6271DF522FC4013E049D031DD504856D217E9E79F5359421EC1D3F77138F3E2CA07FC83FCF72066AD407C27A80D48A484285ADCB8114BB6D98CE6863428D3D378E5C1132E0139CF6DD841230AC0D5F0240C589FA66D6EF1380C9C2F5D9482C0E387DFDCF966EC364FC614CE707EDF8E16C783E22F8FF29A31791861F70B3DD487B4C72D5658D436FA5B3426CE337214E705489798753666B47CF8591B608A28871239BECF722BD726C0029DD7B8C72BB2F7D60CA8D2A8091749686B62BD642F55AEC9777AFA52BE3ABEE6FE5ED2258D6FA3A9A1B55B7A263287A8A52EFDAA0A817F410FE325B16A1BE3B70CCBC50EEC72A70C27CFEA321005FD982EC093D87286FE7A46822D640893334BFA932BB62AD41B4BC88D87EF1890C24907BCA4136C5BCCE546B5470038E5D70D177E7F33B0571FAEB48165F94AFF353CFD315C303CDE5098093BA39052FB1ADF904F1C117503C58A7A991F9FA1422190E0A4952374D624C7D9ADCEB0F124111000047CB5662EB71B6325528C72C1D82F0459A2BED71982CCF84DE2434A4A7DEF2C1210308DC1FAE705360DE9BBE42E9F9204044C99EFE50361BB84DB15657E3B85C7E7E4D298A34933FFB5754CE06B2CA1F6F7599790962B0E77641567AD3DFF95DAD0315DC6CBB3D29EBC8F3B68089140BA87063B21E45C3B1AD5DC6972A7A65C711301C05AB5E48F31F031EE939740EAB8CB8DE627445EC5219116D3A43FDDDD91A967A400F149399B9A82FC54C0D629A349C84085A3D30EFE9AC4381B7C8B24501BCE8F827F27CD507BE20018DFDC9343DC5282F61D74E4B4CBFEDFBE33A3CC67A210BE8E012C8277FB202608E96C355BFFD3B4FBBCECB65B7D4A61C1B9463A7F6F732B5F73A51B01596CC650EBAEC8DD40C7C3ECA3F95AC010DD275D6CB419BE78CC107B6D0DC2C060F57A8D7E4BCD53289CC57F5FE0B0831F93024148D60CB87201335F4DDEC3EAA0D749C04D08C345C0ED169DD4AF598169990CC2C8CA3986660712D615C084331030FEAA5078C0C28D3432E9B1DC5B4F48F508417D588A5CAB2DEF9DB601E0FB6975FA0E9D681C84AED7B5364E192F4847D1090924E6463E527B1185DEBFC376E0EF221D55D0DD556C6468E56D09609484391981DFAA3558CA8B35806E4CBF48489EBE0D23A9A035C52BCB4839DA20BCC6939463E4B03FBB7382E435B97C7A53A48183AAE0A8095D9E04D750535292E6F5293B5E75E6065510537DA2E919E2172D232586865070551EC02ACE7DB95E75D3B321CBC233D5D48B5EEED7E93D9FCFAA378DA92B704F9FF3C992DE34713BAFCC3C38D672194D314A3CCE47DF297C739CF7DB273EFA474D436CFE109BE692E1EA8786F703D81ED2928CA69F38F45D819B08FB8BF9213DDCB2AA24B9E50CE9421ADFF3FDA75A95E3948803FEA3AF80E59C7AECC594B2E11F35A37B9B9C684B5977E5A4A0F9DB7C89772DC17B2D2902DC6B409937934CAF22C27FC38EA4E35F2AA64D6193AB2B340B63201C82F91C20E4BB631D684321C0EED29925FFE916CCE3F403C6364F827497350274F12B405D8BDD2E9FA56F088117B1F682D98AF2A8BFAE4F4B3B1A0626632F55E747A40B1CDD8DF9665834BAA353413DF698C5AFA6AD56EB8AFA9EA22E6B042F6016F803201E974E8E1A19FB5DC9B6210C192196C97B2B4FC0FB24441A6CFF898691E948D0082DD19F72BE037BD4F48D553280708F41A7DF37C6C6130C9C02D540DB3F6CF1AF3E1878E57F267D08F4E761B5DDD7D0276726FA942328A4393A2AA9FC25F6F4B531CD5C32E92D1436DF8E1491283318445D4F0BC81830B3A1B016E02A885751C65044610D24771A9E5F72BB3B62AF913B923DD1FF09DDC7E5077F6B91B19B9E7D552372E81C05B34799814E839C4C62FD8F7A010073DFE851F273E1AD4516B4D8F8389951E47B10BE213B553C76F6BAD8F19EC88A8D6D098F7CACA69DE23B9BA40AE8862981F3DE150207A55FC474ED195A596D96C64FB3A6CE439A89F350FA24B93EC74D4AB8793AA28C3C7701B0E6A301B00C4B384B49CE713F439F853CF204CE46A330695D640F1243165AE0721E2499483E879636CD5C6126EFAF822A21A4BD77FC6B067345715D879F29B41D53B3CCE27C21B68B2A46D14D99B34AF1A6317439E52C8BC1F3A6A83B108381BB2EB80991A1EA80687D61ABAEC2895BFD9DCFBD45E3B34FCBD031446AEBDEA38179533EA7E3D15C579D3B485EDD7778105717DCB70A727A572A978DEA742C0BD05836497AD40A39BD5AA945C942512654884015B32B920EFCCE1EB74BE65B50FFB9FEE543C953A8D586B718746C4214F0544E66D60E6E78F8C3EF6FA35344E5147CF861AD2A928C451D00B35FB6FAC2CB3910F214FAEEFE59CFC099B8E020CEC68ED87957512BAB2CECFA9AE8D5244A6637CE8B2ECC60417D674C10665DE5DC64392E3E0E525CE8CE3877E9C0C9A34B2768AD41206C3E172671E9D89556013CC22BC06B74BE25C6856E89EED22D7D9BF8E3F6AD3B43D9BF966EC521BC6424A9F45E5D459B5D6370CE73312EB766BC89B2C283FB59FAD9F857FDD67F599D71E78827834AFE8CF5A002659CE0B4CC03609321C8398B651C6D1EEA2224A0E54B819C9C867116D5C7E00C588C38AFECBBF35CBF5894130F9FEA689D6389CE65D77B16DB62AE9B8E2E68AC9299AA3AF4DD65FB70F2DC3F01B1EDE3D75D61FF92F8FC3E0FCB6C2F3D06A401AA67C445CB80F045B9A7B79DE15BB997A5ADE3BCFFD8F70738E61415A252E91FEAD291303EDA176D9B9004A6107F8C0C4CC29AD478099BBDE92A5C95B35559065AFFE7B5A2D65E7A85E95FD79302B229EA40A516CA45D320DF15E7F835B0A1F05813A5706B6B73E50121758259DAA790DC21EBFC25C45934717792B46215088AC8CF99857FDB20D985C3DC1BF052F4183D895A55237C34B2F0893F091BBED221B68902A469CD505E6F3EC768823135666DBFAC1CCAD86C149D68BF8D86CF9EFD6007EBEEF7973F6DE09C298637C7FA4ADF1A2159B07425B1636DC4CCA613278CAAAC7B6071C8ADC69DE93DDEC276443C8B284B7A0BB8B38B648171A9066CB6A7F868B6204AEEFB10C26D3774DC290C39CF87E7E9B9FC164E4D52CF5E3F48381C0E9E606FD0B2EBEFF0888F94B3EDCF2414F9D922AC26C75894E61721C18B6C381CCFDB847419CDAB84F3FD033ADA263777F36E07C38EAB79C28ECD65C3623E25479E3E3CCC109F7AB3F1FC3FB2D3529D722AF9A14B3A1D553F009364EFC462B3629E077E918674DABB948CB879430010E829AB6072C25CE6FA44439173026D0487D6F89337C40CFA28D4131D4D107CD8A44D677CD5256CE7A18DB338DD8FDF2159B5F1AD1E980E76DC0FADF27A970449A5059F4BDD6BF1D16A22F11062974AD2F8B267AAC4A3F2F1607CBCD91D0B55895825016E6D721B51DAA94E49BA45C1EDA32610ACAA0E5DDCB146C72FE55964F7CF76ED809749741D6DD1894C083BFD787FAC25149C0D9F095A9383B0256A4680A81B4BC4E86997EA0051C8805456D572ECFAA60E868A58F05B6BE4DD28BA59E64143CBD7FDF75C33D545F2845DA1496DF3BDB3D76268648245C00D8B6272F1C4A986649DD66574BEC036588508519F4ED9FA08874AC1561F7A54BBE7E29DCABC1499FE71467CF0F278E792CA6942F145011BDCDB73C63541B0C9CB7B005EF6243349471EE711C2D086C3984FE00887A408015787522D0037FB7AA0774F946526DF6FC0D1925325B5E67AFDCFB113D42A1ADB854717283C9FB020306262F3C718B98BAC1CCEB0F535FA5B5C4D4FC03151D46556E7293ACD2161B336FA2AA0000000000000000000000050F151B28303A40""") + ), + new SigGenTestCase( + TestUtils.hexDecode(""" +823FFC401BBCE83F04D9EC178826A5BB4894DBCEE86C43B44F2D9F93DEDF2A58F1FF2BD5F907D42D6C18DCFE32F644C301C36F572570E985327F49254E9F4138562EAB80024CD250525C4C7FAAB88132E1BF3141E5CE354AA95574F75C48FEB3B742B08859BB4462738E5EA9ADE997A97129059FB937F7C5CD57884AE12AD95DA11289A00206CB068663C804501851D834812226451B4912C126048C281192464850900C18B54024B08823C02552904101B8280139664840882410015C9620D98001D40252E44811089601E33410C2A60108120212108A9012919038655B2431422065229468E4306A9A988C543450C8284160C28109251191064DA3440DA0B0499C182550A891A1A24D1133681B16280343504A2248CB28106498098212322423604300299B0869D8B80414890C0417721B18920A05859B14884B0071C3126184048000190C8B244D001349C13688DC046D2139068432305832905C828D94466EC93446C9282D48A00C4248119B806CA1244D100861C9B640C4127124337201260C02A241C2029113962C1CC16C60284E0C382C23190D01A22520836552B291E022800B3442DA2066043152E12846442024C1404558204A0B974119132A0BC3294C38000B21525B140A2319221A428E40124444362248A27084A048934891E1088E41020842C45063146020C12104A1455C228909108221012E42C0250B0569E1C68193B84089B605C0B6081016810199101B28204B386D04874C14C14912419000A58419900CD410110499250992005484010447015B3248244771A046214914640B024D084140D10022A0404604C4002037441825059908641C310DA2C02D23436221A76419B3455B261103C64CD1824818C420618051A024485022064AC09108338E1A92454C986C88407011403120410541089019B38C5A3284C92045132452998468C3422211B6914CA2450BA95064380862168A54040E4984100CB78923444104364A04A9110207211A202922034D888830604049C3486150984518801092960C18B22D24828562188453443088C62DD2B041C1202204312A02270D0821095390440A475088988121A04051426109C18983122CE3C49108496808172D81A6282235040220294C928818940911A9881A210AA3A44D0110890B4544523480D04085C8189011B2905A84058A92895CC051D9C42C94304EE126719242860B312DD3100821804120196EA4460D4B12101C002C92308A219961D1440AE3A00C9B206DD3B688DB4045634621D3C04084986102942D60420E242609CC424608C04C61900511308160386C438070A34209A3366D01850CD3144102C205D1C080A4202CD8A65142484D9C106E42C4091C304684C42D621260C33044C8A6640B043094448823B6711893655B30095A028E84A02D82204481066A1805301C082A20B1685C22298B46221C9204DBA285132622DB460510415180B60D249171E3202C04140A13382C9A8410A2140699B2318B207002B35002B080E20632901025513631641089982885DA4430113048E0024CD3008623916952C24D981824222185A33690D4948D9A028DD91888E0882482086DE2486502972C1C962519428519130A03A82493088613458808306C0B030EC1B828E0104AD1C680613826081588620805234588093781622028D2B610C3204283086D1116702481250C324124258411266124028A09158E4B34108A949092C40D24997084B48092B600C100641B292890003289426CE3A0299332701C910544028414097293900D1A424522434A04978512C22021156164226A00B9212439508B1492D9C625232449039201818690D208460016681A364209B3905C06268880701B166E1420281A03601B45618282908810091C258512820C83144ECA146022A080A41226884652C04849D13226C9186C9A2481124021C31881981048A1022188164D54962553222118C548E49610239509D03050221681A134284AA824D81022C114494A2681E2184E1A444401A64D2048848980410B820063A66D4B46251A96299932464C464003110852244519292A1010068808411B114824228404B30C53A08884967002342120A929183049603446D4846049829010954510B22853C01002020E00A00491286E1319258C822C19330E0C874D130610C0164A91160593C609E44072CB18709A02620A170994A291666064069F3922967BF867A52B7F48CCA1475730371BAE7D3CA391B017ACE1FE2B9E67D4F8EA687910569EF4CE84372DDC13FDB1DA2EB9E2634F9AA71E87CFFC9E28F1BFC862E08671CB976A54EA31AAE67F4EF5E7391CCF4F6614920057B8617E6B7743F7795E3D8FF767D908614D9FB5FA029AD4B9289CFB78D4A8084DB261F67F281523C1E191004FB18D7605A5E1B61B2ECB0543C153173C981B86EE4B47602D5478FA02DEF589E0B4CBE9A95ED74E25253A882E50C64C8BDD131487E02AA035B47E2B11CF723971CC44DDFEB02C6A112E2A5BC929E53D6A4C8A197C14C2995550E9CDDDEC38E9E09A5C4F8AA97DEEAF1BE0A5DF604230916128ED49ACBD9F59A4E0F4144391A8D718D3F7C0CEA8AB31B04CB0E6E5415AA6E0F2111601EE1C98E6A6B670B265EBF325208036407D3E768B7D68C0D9FA7DB1830A95BC2E41D60273CD0E0E9C8DB63BC1A3ADC3F126475596DDC43FC64C9FFD82B92E2D7BE1E095DFC89B18BD5DB3E601A1F1033888730CDABCBF13C2C7309E4B14E687236B11CAD4853D367B146DAA251CDF595858F4190C01A95292A94F43FF7BB3FB0D7E6747029BED764134CCBCA8C517DD44A0DBF59D135C9E7562A64FAED25AB711AA7578DB087BF8DD5EC7DBB7FBE54B6F7EE9E0C4D0625DDB0379D1949FCDF2F93B49D7949E81A1DA000461FC3F5DB8152E63F37D3DDD885DA6CDABFDEE4DC620159DA78CAD3C9E407BAA84226824C142A893D7A44B73172BE3D0DE12CAB4C247DEB9575EB2040A180E7C8155933396AB69E5C1F6995A3C85D1FE0FFC3F09522ECEC1CE40B033424CD27E22C8DDCC9BEB01796524CF433D9DAA4895D0EF1FDE770446EC32C2DD87D3B42CE75F4146F7528EB68ED027B9D789405C41E4B35B3557967480909696E00B6BF1AD7903D97A58422EE4A4DD9F2EE8AE163C930530CE93DCD6DBF475A245932F0C7EDA1DE3D7BDD6CBE66F93C0BC79250606AD329554F94CEFBC7C1DA08C4B1FBBCE1C4C68F36787F730262CFFBCA4CE3794178F08402890FE3948E0C9CD5DFED68C83D40AEB2C05BDAB5EEDD980F9783F6E29DB2058D3ED5E6D1952FAB5BB9DB63BDCD1BC2F02B81A7AC09FEAC6716FE18120D48DBFADE9A919AAAC8757488B2CB53CE83AC2F9A3DA3549649200F2402F574B1A636A40AAC099E8F25E22CA2949380F53D2A8AA9DBAA36088C6CCFE95B453F3CB39D147E25836B789A33031A850E16CD99C11CB8856D0ED82CA8078417D73C1C716672030257EC839D379E9095FCB0E83406DA139C9F93C0546B476899303B333609DFD11AB6788C650EE06BCA3948651C315F12EB518D843E8A718C04C53C968B2A951085E0E5A28037427C72C851467C8E737E72AC2156E4FDDF491097062126BAF36CDF7ED41C8BA4081937567618BFA869C2A21B0046269731BEE0BB1686B2966E3658651E259151A6A98B1958C5F37DD8C5CADE9504D1211A77773A78DA9E9A60070250443773B7943E0FF672C77219D5F76ADE6625802C9A7221B10A5DBF9F3BF5019983280ED3AF23BE20721564CCD7868DE7DB9A83A80AAAEDF357B215DCF9095F79F0DA5D4C3BB98740E6BE09070829C33767A52CDB97E3EEEDFE6E43199EB09881C2F3A18B43EDB5BC835AC7C3DCAA7D3E638C07E0CBF68DE1E6D14A2C3DEC77F26D890127EF9C42FBBEFD04E9C74D4B9C80A4E4B3FCDC8C8D9AB2CD4875DEA9D5AEA72BDE1E5C558B4753E480ED410FDBF2946104DCEF40525BB445EBA4FA77C4C65B0507FD0C9542919B3B367EF4F4ADC5A1DEFBD3092188758B4437B7F7B27D8D2285C24E4DACAF513391A8CB6733DAD32EE0E00710E278072DB19A2330ECA56D923DAB749A671214E812B324161DBAFBB2ADCC33C96ED14CF04A300255DF22ADFC618C405B718988E5DFA30255B75F8F0357A57761642811E3180C18D7D167E5DDA6D05B1FE2392240B62ABF2705DE27360061F10F6F98A0ED9CA604A3F1494AE66E4A8D637472EC8674BCD95B4915511BA70F5DE8A26EA034388AAC5BD8990A99FC3BCCB61612F99708A307C0BB966D198F603A777109A6416565C9AF7D06F620F48B44A9B2F32E034D2E5EF6B6CC9012BEC98CD1F89ECE7B3E5B3A1D61DEC92FBFAAAB32D668892BB315498DD208016E7AB0EB95B6FFD2059DB926E89053D78293E1F17E07D8404FDC24B4E2B4C3B3BFFAED8539FF095CF7B7BC97A4FB06B245E0D2C0823BC869F935CBF844AC346F0E3D5976D815FB6A484D7F5E72A1C1A6E8FB0F0BC209196B0F016E672D17771E04EA919EFFEBD317604A0FB5D4327D74DF07CC1AD6165733ECBB32623D0FB6A3B1EABAEE89100FE1B7F2185CE041E030A4271DF421D5FFDDC55F846F670498B59B4397BDCBEF252EFEA81BB4B3E4EFF3756E8B2A46CE51A84AE69B774374B1995DD2D9E5E656B0573D16676397BBD9955EFE959539080E11268B071F33E125BF2F6F90FD8BD166567ED9AEEAAE0D47F5CB9BB2262EA1C07943B4413E39470B97A2B5E8C92C083AFFD1BE622C1A00B436CACCD75C81ECE9262A737E3BE3558058A330C7C570F85CCDFDAAD6962503B91D16AFC1DBCA076F8023127FF0BDCBE1C343588B60653C6BD695E954EC4ECE6D034B4DF63A92F2D7FC212FA36C88E8137B3892DBA87C2396A9FCF539098F73B043C09AE38D0730356A0E90516DDF0300FEDE1FDD0B4C84E61616F9BDA41F50388BE8D5BAC92DC42759023679B05D02A536777947E3D1F24A91D935E2AE76B9AB5A865F83E2340DDF3AB0B9A56A5B08FD648B7900A48D2D65954F51D43CA39925A75E16F32DC1ADBD22301B0EC93DA01F06ECAA8EDA6F770D4DED24D512BB1764CC515D69D87966F0BDA86769149D38DDA1BDB3EDB7EED89C603235CA16890189F560A0542455E8E4A09BCB02DE7D5FB06DF64DDCDE70F0381C98466BA48A69436DA9BF3DD713EF802B214872A397CBE53D5C573890F9E9D2212FBEB99231D1DFB98241A9B10F10704C91E313115BCA7F3663F7203482CF6696E04567DB6AEA8E8D7B29492A0EBDBD4A97A7E6F0965A84B37D55E9F88777A968BEBFCD4A3C5C94A732F5C74BA11C7B4A57648909610C89D27A3A273A0D5DA2B3331E7036161807F1162B602EA5D7B83984C0EF08868571046673112D4CFA652EB927109DAF76A728DAE6437A6DE15027514983FC1C1CB08DECD7B31C609B0F7AFAF8D183F2588D4F60A1C7E80BED6D0FB64F05AD8C7AF5B6B5E861666761D53A6109310C11AAC7CCFCAD51CC54222B88FB7644C2625397D5745E4B282F8500AD496CDAC91078124E5416C3CE66FA8C82385A3DFD549ADFCA317A3DAB331D203EAFCC3DFCB7536FE8981FDD6C00912DFDB2B0D708C162440C5CACD1EE593F4FA891DCBDDD18EA0BCB1987152B3FE0CFDDF75DD31751E8F74AE01231BF3164D4917A9EA2372D5AD19523F657FC24C4A6D0C2BBCE794D2CC270B6585A4F7E2153E6E41CA9BE747D0348E68D7269084BFE188E4324E4FFC55AFC7D8DBDC2A47B6923556C9BE84CF29B1C6A3AF1B82B723D79F65810C767C140430DFAC14968F2581259CBE74475BF427A5012F93DAD6846B976846EC308903C489DD1733BE7193431EC09F70CAF0C14D539584F58E23A0B93CAE93128D1B52A68059D4D3FA6C4F7568C991B3FEBAB081498EC59EF340F91C2640596C7C8A69230354346C1BDD89DD99CFAB4EEDC3C2B0FB8A70C5391BE2D533D26F6A3BEAD450C05C93A43D07162068DCAD467FF6EDCCE1E1C594B01717E8345EAC25887EDB71A221BAD69E5F3E9B62A7C0303DC62CFA8CCD93659FF50F2A446A797026C0DFDD5D1D50B0D0297AF09402B570196DED70CFB7088E2ECC5D474D7D382E4C073130F12D4C23A7071D93BD7E66E2D6DC1FA98307C44D013F6C1335D321620591377FB5622AD625AE9AF030BCF3F6F32608AB45E2C15E78ED195488E5995D933FD54ADC6C73A02F105CC03D19EED13F3733389CD42F07F7D900FFEC6179CFED21C5AC4CE31691578805D2E6BEDD06953D0EA004CF9B630CA71FED339FBC6D465E69397919B3FC508A3CAE49A9B3276D1B0A75C78D8686DB7184BFE2878C0944256F98AB6C25DCC67C90F1DA7720ABE159C8743C15B3BD3469708879FE4C915A63AAEF01E5407DE35B1772513CD33D2678A9A34F430ADD7B41623DA000578A24E5737DA976DBA5C69569296FAD87A5E6E8DF5C7C2C1EDBB7085C046106C50FF4B4A3500A00E7E730D8E9B0627E10ADDCE06C296A6F5BEF4E99C411BB8218F6304311FAC1218ABB847D8FBDF5CDB74CBDDEE983FAD3A9447BB80C60C58AB0CA05FFA8875275C6E973EF9F80917F11B4C76EAFD58AAA34650A438B18246A4D87ACDFA57DCAB2209F65AACAB4730D6DF6CFF2E87FBA14B720B16ABE927590EB015D288DDED8DFF500FFA2E0ED288CA86CC76DD7FC7F84F5F926CBBF026C7E6D5D85D3DDD25EA103B7FA98946E4CD8D450D457E85ACA4311F8B52F27B4EB8AB2F993CE5C81583021CD385C2589073F997A21BAE447D3B4D3BEA154F188F7FA7A19C7B4E9315BA358F5FFF6D9FE9023C8EEEF0A240F10E698102A19FE48900C304E049C5A5C3C476D224815AE298520CD4CD889B44E5DE0C052F76AFC2F7A9F068D5A81E38CA8FD5D4D9ADB47D9D385E5B5C4BA54B8DFB42DE493D5080B326AAD8D41104D7EE98F51A147A9DD8130ECFD817A7A"""), + TestUtils.hexDecode(""" +701B8AE25CD8187095349A4D41A067D4FD48732E62547E491D38845B3507A7A6AD8F8AFC53D139E47FC5AF2723B1BB057FC797519AC93CFB18DEB496BD9735455CBDFFFCA5E69C95990EF89F509728D1CE41F36A4C0364AC8C30E3EF67D3F3776400BF4C838A477231E455FF76C92CFCCE1B69B00F99451B0A8287ED59CD79EF0D6E697C93F7ED38F20204921E6E2F141D3DBDE1C201E5CE7C524370C339753676746DA5DE4A398CFC2CB1F568C16D4DF34A27CF04F0637B1447C6CC83E965A3F86C538CBC235E440CC2D1257CF916421EC75928DD6DA3CA002AC93C8F464ECD522EEF7E048C154D73053DA7BB63A5DD845512D2B6B7D1E7EB5818D170D14A4A698C8922D69A98319A10E0AF558E2318FC390ED990B75ADB50C6199DBEAF5D53B49235DE7CA116932EA38A109322AD05F5D681CE25FFDC9F6A05C4ED2EC6D4242173D2039318EF7D0733D86D57C4E114B3476392D47FC68796C9F66B1F1EC70610E1D57436614D5969564DEB8673686170E40BF5CDE506F7E70964E07258D4551F5EE0BF2651F8BF3D3177DA76AE90FAAA69C4F373E664F0A1FCC62F208A8BE130C499166D13CB34D77FDB32D5A7F3AD38856BFD3A0419B8744DD2F186D03E18634D826A5BC87F1566FEF88D9ED93E74ED4C005EA3EE2EB22FF5DEED283132D00C7A0B131BE1FA38E30EEC68B748AD533BFB23B9A14A936F609D4C560163235367B0D64C2C796F1106A1A9365E8F507B4BE0514C849A81E2C7388C8AF300D98D444BF808C4F9338C47A853222D5AA8ED283F57DBF0689E5FB89A456005B6B95AC3D791077C79BAA2BB42B423F93A7D0D999241AC5B9D64D65274817F9BEFCEFBCB4D5CAA67427F69ECB279553EF0D33A19E14FD4B284A72081F949FBE2A7543497F314CD7496EEE866F33102BEE5CF9C706426EF2365EFDF1AD141552BE65D1DB4373B0E8D449F3FD1733AA164C1F2C24F74E240C5096CD201A11113D6BF5CA19595C4B0A81E1153A4EBF88F38F1812BE517158787F2B378E8E32C9F97432BC9027292E5EDD7DA64FC6A32788154B62E40A85701895E13287BB18883820DBDD7647AE4EE1FC1D43C199EE69B1A2E2A7067AFAC541A8F44E660B2A7C114F402E2054DA7ACC41DDDEDFD7291CD4573DA22739C7785EFC2240B27A90BFCAFD1AFAB6C2B0EF5509D0DDF349C173E9A6C906BAF5692C39F6E0D1442F84AD2FC118A14B12C3AD5DF8A79056017F4FDD76603717B080E3AE560D7A601EE7FCAA36DF7289AEEA59EDD0B73BE91782377150F03C2C2ED40F33A250356CA17E153480A7E848F090DDA29C65FBBFB495FE9B7A2BEE342C7D422F28631A8C9CF643DC76F07F162DA1AD3F24589971032796BCDCD262F55A8C34FFCE05FA9DC001FB35D6FEE75B42DB6DDD2138C0517D003512F0EA8E982C2ADB5E5BC1F19B8ECE67E4AA1681383A97976B6A8F2025EA80B1BFA1796C27F6A54C583711E2EA46D85C515EAAD22ECFD68C5D02853D688302704EAC4863DB1FC69F8C35411EC6F4A9F0A7E7B3385ACF6DF805447BFE863181A945E8E7944770340496F5A19CB7DBD0D9010B7EEA3C585926408FD40F245D852DD208EA97CDAB0C16C1EF80B3E5BE77D953A04C1B6F53A23080B54F439705E417B9874B3FB524794D26DE3DDE88E9DB9FC36B1508754EB51D389FCC46F822F50FCE199DC14E4B4468B8B15A2460EAD05D0C47668C05A2315748897AF99D320E70F2AEB96936D7D739F72ABAA6960DA6A3996988F6A3F7AE7772D49915753B936367E022179E69B6853E1A83B429B42BE19EE03520A5666124B657D2FD6D15447AEEE45AB1FF4593DE9A2E6D152C64DF45C1F62AB9B67257B2A2115D224850A3AB2FA028F8F9FDE7C9A9FBA2FD291346037A1B4E00B0642B07ED54BFD70F3DCA3D1B8628627859611006DB2DD17A351751F85C60028DCF21481291526B1DEEA4C7CD2D3230653E6FEA1DDBDFE1BC3DA93FBFCDC5A405975A5DC68DA0D8338EFBD6CCDA1F2374D72FBE007599E81CF7D5C37985EA09C561A1EC40A70784FC606FB7C3FCD981F112C599C78B15B7739AF4DE129D489336BFD3966C10363A60E749162D1D8311C5E850B22910B999080DFC86D1787C35768CD5470E9F7A51D4EEBA71241DB57021D6569ED2BF201C06E235D6621B292B686D23E29DA4E81C873371593CB07B3DE46E91FAA3D4A2AA6F62FBF6BBF1954647E731AF4B99EEB3C0FA6385699F8EF2D8E1D7F75161129A1C7F8C7C68B906EAB8DAE8BBB3541FBC65F36BB67ECF19EBEF54BFC2EC4E1130A2E4F36B5644A73CB0E244738B6E5788A4B4457291B57F1FDAD2C11FE5C7DCFD4E742A0AECC460BB660D7BFDDEE4CEA074958AB94B6FA4CCEFE02FC7001D3A2CD013684A1ECC2E2F6D90D246726EFFFA99C12D1FE4AD10A6BE38D70AE3DE5C4843FE6CCEEF587191B56F666C1662F5C6FB03955C557E1B4CE247A2806DE39EC40CF8B97835EB0E3F2D829E0FEA02FE60C934FE72A25930FD6692B9ED979F14536F406F04C3CF0BE98647A5967B81DFAC353A2F8236FE147BFD7D3731C49476C3191981C9AF239AE8C72570C6C53E7AADD48E721E623D6CF11A1E386EA7C30F070E7AC4F63FB42AB74881BFA3FF3E8A35EBEF04D39B853DDE0FB17DD9DAE37A76C96FF55F64669CD9521DA3900B7CB297E813521239D87703CA395CDC8D8CC4EC21CB10A1C672493E013EAC0298F8076C8E0B56AFDF9C31EA01CBC1BDA4AE17FE103C9812E940A34EB321BE7BB288CF8BE7017AA58AD528C9DE09E269B10C6FBFBA5E8B6883FE7E08A0D184F8561FE3F43582CA045DC25CABA52C0157495410382A048BA67D051EA115D867D780CDE5EF512BCDD14489C43604F86D929F83D118B905C63BFF451FF3540E9E220851A402BEA0DB1A7CD94DE0407AEB9CF862BFA3FA703924D0A4803C463AAA827A04B0F09556054F27DB98E22A96D07F81662E0E910836B9423968C3F002E605BB688720FA7CF3167140BC21398B5E4968804F3C3065FAF125BB6D887C869FE3FCC27D88E048FFD0925E748C096C74BFB1E54A8FF6E2C838F16769FA4D8564E5CCC58DAE3B102EA300361EF89EEC689FB5BB0DE16C5CA98A60B8990EEC0006A147036871FC2A6ACFC6A6EC907D28E18A76560A5436BBF9353789C8A5DFE559FCD68C117066EEE5B00F349D6591E104295E78F445FCDD3D6883DF50D1DA6A04541C7E8171523FF36A9C072164147D14985BA30FD449667B580D73B06A5971B720A8B1D2A6896FDC5E4D4DAC78353ADC3449AA53919AAD15EF250AE12E9E40B8487F66AEF0B15E42BF34AA816F559062EEA24EBB01BA369747B29404DC1F1108DEAD021898298E72F4BC1DD821E4C88329D6F03F971F554A87FEC87F34430ECD1CCC6627D8CA49EEE1D5DA6704CE960021C847DAEC2DD544D4EAD2E2086058CF131296B7F4FA4B71A1DC6D6C642A256AE0C0EF9D1211EFA3845B12243BFBCB4F423E913A2976C1015569ECCBC159AFE70F1EDDC3AFAAFDA45CC02EB60BA0DB9EA83EC604113479BE848F381FC63C63B3111DC5179A637E0832A26EA32555908D79B308351CB104C43668371DB32056BB63540B9C3E5551A063D2B525F8A016BBACEB402CE7D7072CB9F37CEC13E1EAF7D867534C013D78B9DFE01C13DDCEC7A3444AFF9E182F12B6901CD9A70F21908FE692E4C0536B069C89685BFA9D973983AA8C1DA461D18ABD27A6A717D9F2122BEAA9BB1742622F51FF616FA2EC3A6D4724A3A9215D7B29A1BA372282CCF60DE90B3834FADE6E3743AD6B2F9B7344F45A29740DD7DB2D642F94998579A5DCCD2EFCD2F7D08486BB327B844EB19ACE3B4FB0D85F8A24FACBF318C98199A0B2C7FC2CCA59AE84A522890E22C2A7207CE91623362C7DD8E9F946817C75B71FB9654E2B7F2E83E46E75ED5638741E414D7F8E70914315F0E37B5B4E3E1CFA8288B1724113E4A00B59B7764C2D61443537849E77083FD13BA652001F39DD9BD4B20AB77CB945C5EBE686A0627ECC52F38A852BC9E1AC8D303E3B96D9D086920A19E5088054DECA635E802385600F673D3BD0A5CBE7A5B9BA8B1C4B73B9246C1A1C1071E5F98ED42041037FAB67184C89BF4FFE3CA0AE2A9BCB020F390F0B76DE2B8AADBC99268D3A1D467A024184CC9A455A8F2FF287A4C9DD1B0C86C8E176BB15B12023B291D44E7FF0C44577F7A6D788D82A75C68C9F5BBE504E7D64FD2AD18BE209E85C45627FC045BC81E3531A2B886173F3C3029D1FA98C792501A4942C72A7A892232F390CCBFD7863AC38D837755011F919AD8934742D0795523E6D48A958BACB9A9F7B9A5A9D914C37114CB111CB536EED3D753D6333219EC993AA5D39BF74E8E9FA02D8BEFF369EDAEC67A5CBD128FC9BA6F82E31A4C59D783A99912C7C389EC708824AC7FF05D56BA6D228C0A9D96324C6D9725E3BE17C44CAC7C4D49235BD15384F95345DC36519466A13110A58300F7E3362295DD7069DC6A88B542F2BC5C9F33328D9D8D1683902C025427F32FD562BE3F0680FA05851296E15C5FC67E96BAC924407AE6BE37E9B61D9A6383FFBDC6E77CC0887726C474AD735BC50039AEC665D827B0F6BCDF7EC87EA6BF793386F2A65C997545FB93F0D53737C53D00685DDC13960AF2632380F105840A1699ABE53999C568978ADAFBE21913193DD0844D89BD582418BF8B6BC430FF1FF7750AE8507495C14DF21A3437AFCA7DCEE7B1F1247C802081FC5ACE5B125AB2BF11ABAC97E201EEC2A8C90ADED920728EE77E1FE2BF31A222A1CA5263586A16FCF80E582258654D0793B1551EA3C24C4EBD27C52956ABCE6ACD05FC2F088273FEE8ADA0256F30B5ADA8768D8E9B70279DF95AE5CC68FFA99934C7520E12F57D213FF18ECA6046A9A3F32E280044023220140E2485A3B3EF7778006B18D4A9DCD177D190CD903CAC1EE0897F58762299A0E026B8EEC6F4F3D0BE1F070C648A2D73869F22DDA21246CCFDEB7A9784AE967F0DD0A2011C637099AF33E0D608AA0A5B2103060CA1A6718328D451368EA3049FF60FB66FE54E778DABC48413966EA14E22083A884E8C8EC33F885093F01B5E34477745A9F82C645C8C5498306AB00B78684252ECD74C163BB8AF9B49AA03E244F4EFC4A2E7099074F512D465C84773DBD1FA96D26053230C192DB289A1596E60B96178DD8CDD72FF14B340FB5830696B393CA319649BA56DCD517F5A08A528350E2D9531B3AC187414FA6E06C0F05D9987BB2FC98F7C8D4F922B8AA45287FA83B900ECB6C9F02669063296F1EA389858F6D2E10228E136FAE35F21DA151EA7AAEC593E5948536B68BE58ABC57771AEB406A0C3F931E7DCF85A350A3558E5C1B1F70E6299EC9FF8B9CC13E905D9902FED957ABFD7D09FB84FF22BF8410D387BA85D8555A75F432EC5789498EA36CF235276176ED48D1E374DB5C2DD1A64714D64FD20D4FDE2A605034E4DF607EC6E11D0465DB25B9D79C83182384D64477C126E9B8558489F69AF29730B4D5650B9860326249777DFE9EA5669736692D0780E9BA346C1727138F5DDD4914487CF32A4E9CB1DDD5617B6B45CF8C981944684BBB7921C88F5A25120047BAF2D9346E220EA08AD168B30A1B82B3B63C4913C708C02258B6AEF1CAC96E2A90EF7D0E1EFC0BC5BBE05D286E143FC0CA4A23833CA12727F0F83079F7BA80D809D6C739EC4D0DD9CF75C4FE30B12A892096BC4B9167F16819694B2CD5DB4B80DE8DE988AD50677695C4FB3E0940913C250645333B6F55E36F649A43C3A39ECAA3DE3EC1FD4F9F65D9F7AAF75B60DCA3BD1EC06495FF5F1D4FD6D83CC6316E40BC469EE5F44E5AE56ADB229A7CA5CA37A1508531E44B0142B4330048350A40FC82279D25A87E043240B4BFA7321340502F0D37073DF068596C4753F8709BAA2A7264ADBCF5F934E857B3225CA47D8A182B80D3DF24C3612FE4931EED565BE563115414CC2B6BD102DC6BCA9F104CEC8B24BA5465FEBB7E9730C928D6FC1144224232A990F8BED27FE6D28AA35A91F90D6A0AFE9A7E37A5BAE51D8AFDEBB7D5670F2521095A56862354D2AD946663B4BBC7049ED1884347734BF3E78ED227428476F1070F4DB011F8DC86EDC5BAE1BEDC9C5D253E4C5C6816347EC96C5F62AA3298588625304118EC32DB2DE0597BF2056046E17C69EAECFD26475066AC54D40A673741BCE72F138DD98F1939598E5D94D565C1337D1179DA057D4453DEE27B5C04777EA710D77B317A6E8DD3B4F26A6A9B3F4917A0E881E5EE528462508DEC6762DE2BC3F8F8C42E8D721BFEF7583C99DFA4D1CB49DE2A303B67AFD505F8A3865D853BF19C4A0F7CFA92F5CB18CD5D8E378A5B041449EC9ECFB80E0865CEC1734D34BC44E664243AA8F605366CE9F849700593C76BE0CB19CA1255B074A8630FC962B50106CD93DB41C6E4DF53B6B1257872B0D8CE9AD5F245C3027A3F75F19DC568ED1E0F60CC20DE625241D300DCDC8C953676363868B680B471C2EE623DA408C7E030833DBAAEE8E701374156A6B785E0EC7D1A0A55A599605BCA0FB517EF99939889C862CD790240709BEE0226DC7E8177F641C747A151A89340A6CCFF6982EF39683325390DE72E4451BBA74E3CB102870F1E9ACED30BDBBEF160A49746A23C432C3ED7EEF580969110AA438D00AA03F54E039195D61B7840222AC994784EEEA538B7E830A6508AA0B460DA4B4C0DD9CB052CE6254774FB147F7E4F80214AF1FAE59F8ADA6509123438E90AC13FF7CE71AAEAEF7A39C434C3824D49B894C389CF320A430A7F84A5F4972FF98C388D61C936E453BB1A340528A9FA5F0B0DA9543275435E91B0F5560E95F9AE4EFCDECDE1584761F8F60F0280ABF40FC5834BFE456EF66AF66ECA1098DD49BA2CC4B12CA9CFE256FBEEC328D049BD6BD19E2358502672F029888DC3AF3350BC2EDF5C4E07D59DF8DB9C14B86F1FE384227953E98978997902C8F237C8BDF300A72248B3DDEFD52577BCC0F99F75B92BC056719243F7EE67932A2DECFB15B59C95B43E183BA3DAA41B97E177D03CA320A5FD5D7E5A88C4D54A8467B883E0CD5924912642A65F191DD4DC2B08DD28EC0AD2B1CDB86EEA3DBBF6D47754B1BF7036A0BE90CC3775D263A5BC688844BBB9B1D9296804176E17C55D6DB888C2BEDA3D546FC496EAC5243AB5D51686AF9B29BF6D4A138BECD49665458B816BB09848CC4318136E6B170BECA544E8ADC35D40DED979111B8B1D4577DE2FADE6A1D97F9E82E9D3F069F3287E559E99224C6494F36233453036DBA617088D619395518B4E6725125850B3121EA957E721244DF53FB343483D27E6C3A53224B38C11C1D64CBFCD7041A44836AA606D170A80E84BBC0973556B9E4B1BD776C6A0876D727BB0526809700A0EB318BED67843CE4A6BE2BC10FE9D8228A4C94D7A506760E580E8A0E544ECCB07DD0810D79443046951C72E017CEE5B2C959754D477D706C3E043298CAD200189F4390F59BA27B0099DC551673B5138AA654E054676BF30DC61CAFF444CA22EB32E5952A598C07AAAEDDB83B8B3789EEF97663ECBD33FE356DE981A24C29DD5217E14DFCA30C0109419D8765A061F747BFFC1E221D3ACC7FE239375A9548483543599C837F48EA189880278AB2E06EA44417EB945F20ACB464CC458E249A8969273A460F063C5FAA907E42C9EE304B27C85BF41FB170708969A2BFDEF37B97DB4A16BBFE07370039369D04D0A9155623AA390ABB75D47FE2394E4606759648954FECDF4554F660D3176AF33153A9D7B0A935753B11E6C7295B0FF5680A18A42ACE577981C500581F741CA23DFDDBF22EB6511E19C016EDC96DA545AD16D5EFB9A8F10C45D78E01C74E3552FFAF35CFA1BC0C3DF9D14C1BDA9D510FC7C7A755C71B5273CD7CAF3AF44AF066DCF18B1B7D6C0D546C9C0B0B1BBE88F512824CB8B512438ACBB23CAE1178DA05DD67DA6392649213805D680AA61D26092BC1B2CE50CECEB7541D7F10808DB2D4A6B12841C8B4B6C5519C8683C998A74AC3BC3CC44D81B606A9A3174929E4AF06E032A24E67E9C66885004F07D4775A6C66A8F42F94920749FF902A8F1C3BC5A1A35BFA24040EF3B7ECD05654CAB696D3323485EF855361DB57A65C5AA0B238DC551ABD6B4A8DA0EB987A82F56E5EF05CEBCB4155181BBC61C645B2A4FA8B316FC6C5B3BA12829E74899D0A42B42821094B57E6D221FFA108D5D0EDE9012A88A2BC361D90673BB3D19D6355B9239131B42FB3CE832DEEA6E4551BF6C6533CD8DE572ED3E5DC51BC1ADA13C0C7E4F723CB964125DA08E0D08F1CFAE124568DE55E2B39B1475DC8F6558ED763FD7EC2DE373F4C54399A0317087630AED2A64BF13D113E8AC32E6318EB7BC0DE20E846C0CACD876F47CBF79DB6FCDFAB75B371156CF74B443E8DACBEAF94203037BA14E821A66244BBB7E989567D176FED12AD0BACF79834D067662C11422631554D1ACD6BCCBE23BF1D0C042C1CACA4B9BD01D6C5757E52877FB5DFC92161C8BB15A60222D12CEEE973812B4920B38547304E720AE246FB503C9F97BBA79640485624DFA2F4D508300BB80C70CF8E271770876062AA1EE0F548F6F7D95CFAA17FF1FAD847CBF6CF90B01D29C33B43473379F4B5491532432F6CAB98C365B84D357B48B416C2A00B25D07594ED4E4CA0E1BA5C92AA2F1DC7A6109AE8D71B9F06440A770FDC2501900B9EE466DDD853CA5482B4636BFD58AD8B24D91852ABAA0A37536D4118A122951DC78F02DDA8EC8029ED938125D759B24C90B0FEBA1F589AA1C10FC9597CB7E703D93AC4AFA43D3C239337AA454BCC471CC6BECF89266F588C3EA71AE50F146097D9CCF21E75790A5F3A252977E4D848DCF5D96DDD4FC1D0CB583A28AF9D7648BDAF8F1E94A83CF5349B1F4AF63AB1C66757B75C58D10F27F8619A5A6BADA67E841B6429AB40A09451313EED76B93166B3A5D5561CFB6421D83A5E343C8D277389950328A1646C3DAED357BCF2E8615695D7E8922030148844058D177D4E68A8EE31D5D810C73D9B38F6863083A8266652DB82A43615A45E6D14EFDF00A4333404DB65194EB432187C1EA7C48F819C34E48EBCB0836C84534A238C42E0B9BADFBB15B220DD0BF40F8C0511BA69EF82FA57D099BA84EE4AB6FC422442C3BE1E8DD910B4117BF4047D49419FCD2380966F665001FE4793F06F272E14E1893D502BD3343AFF5EE94A58CEE04E745E72E51124AE8013EAF2C2141012FAC54CD25E97B6FD3F0891BA1DE663EBF009A7008222F461B4E7D50628133DCCBA7CD0AE44BFE9F675E094D972D896551A1205FFE0CA8FCB739192488D2BDDD4E10493B43C7EFEF60888CB11ED68F34630623206E81ED04D300C2C43B6F27E41F18241651FC6B84C19EE1EB018BFD7A0D4483B0B6DCF57236AB27BF4CA17E52739E4D1C508C78F6B6E9FD53F423AFFAB01F75A9B1AB725C247492DAE3227ECEE2D60EB186BD8972FE455C393919E6D9760AD1BB706138824FC3C9EA0F673C1323366DEAFD260591DAE60AEA2DC22FFE5EA2421F35920550C0FBD78C4F6469092F89FB6908457BC81A175D75B1F97E2750194E68705B9D1E9F762068EE2FA9286BCCD3ABE98007AD1AB27AD2A094C6E164C5BBF88CD4C5F325E4E91FE2867A94E9FE1A78DAE2ED1C11CB4D365EC2F3888612FF58B493268645BE9ED69C196857F8C995A42D5CF4542E609BB35B0BB1B4BB85295ADE635E8FA237C5DF471B8CAD7E98420077BF1DBF6DCDCC1322C8BE1B8DD5E228B6E6E04ADA1D533B0C6221FA83BE7C19273F9AADADE041CEAE389D0572D2317906005BFAA17940026CCBAFAF8C7A4BBFCE30EDBF4EF82902E181B41A1FC006AC01BE64CF6E4A4A14FED995D6F323405242BCC5797E43276ADFBA44EB8E3EEC029292D2DCDC8E6C93AA6C02766308CD367D3"""), + TestUtils.hexDecode(""" +367CAC590EE6829B0FE910294F23515114CBA0A04D39CBBAE3BF908DC1A13ABBCD5CE2A9DDD0FDD2A011068C48EEF6BE5B4524ADCBB6F51E9A5B0F57068385D42704B0B48B3CB8D1AB011B8F13AE83726E0EDEA0A5880590AB8FBD689E6495AD68379993C44AB4308D0FB19D3F0E6D98E61BD2EAE1B49EF4229AB10D18CAC1750A60F1CFA9430649A7DE0BE1330A180106BFCC165CF60ED91711E5033E7B8FF29812CAE5A8900CD31A4B254CDF41ED4C5B4506F6FEEE43B389218191246A661CBB86F6C8F790D3D87343A37108E1D79C2DBD9A1533542A5766D56C9D013D74E2D7CB1EE7AABF50221ED657D8C2AABDB26DC3F7662CFBDF5F6484BB9B04060280AB53F0D22093967A19E754EC5180024F3AA2A615A45A0A43AF44D6204BB8BF512CF9F5DFBB8C9E6CA594FA9875E9801B1A3BE7983DC4865F649E3AF8AC28B0780C65314006024569774E8C7909A92539F9A647BE2CA6874B4438E0FDAA7691105C3D6CBE3F355FA37676C65C3508047A521454FC3A5F13F028465FDC9074BDD506365AECE7120980AA4622A7353C366202046CC2EFDC87459641CD56FC9AA723174DF368EF63517CA839813E16072951F53F4A2AC0B54F0E7A5A21683B81ED562358DA14794A798C1C14AA2B51B2F87637446F235316F0B047E757F84D8EA86B35A9F24115387DEC18FA8FDD6F0DF4A918EFFAD381EC87727578185A214B334C77FC5545923463D2601A302BDB21067FBBA672B7E33F3974FE1C2206A0EC233DCC44412A9440D7A09EC3A8ACFC99EC24F9BF021BF3298831AF56F272FC1C7A06DA01B1B38E8C421865EB8092CEDBE376E836B9D8181D853BCD48E97740E8AC046FFD2013691587461DA91FEAD7C840D923B0ED227F5389536FF871859F459FE2FBF24C84A8D290189BDAB6EA31BC1BBD98D64958106FAEED0E8B9BA1C10B66AEB7836063030E641A8E00422E2827D8DF1BD982773E0F13D17BAC5CE3DB813F712C95CEEB0E7CFCA45FD27289EBF6C7269EF58A5E4135A6F651B2139AAE3E1068E19C4EF3191DF10F37872DA952E95B2A831333742864D6FCEA8C0E37BD1CDC2EC902D210E7693D30E36595892CA5724853510B6C01E91763F376F20D650BD1C3A647FD2C29FB3ED1B8A8D15624E60837F55F65E0D0D8B0CEBA1A903293BDDA52B354196A1B138677235E41CC894DB5B1FB474463B168E25E7F55EA5AC0572428768DB4CE75255C47422B2D92C99F8AC8F296F1F823E59591DDEC09DD4440BFB9007B8BC04EBA7A7A959BAA624E2165D6C5C3873DF0589A377C6157A4EC57773F98763745627A51FB36CB82279EB9514E452F381AA65B3EE860D0EA2DFBFC838C98821907C1A99C0C18AC49BCBB6FF01127C46C439BEFE217AB080337B66F6FFBF934FB5A6D16118DDA48CC987A13D52416F7FB4D10C7F22D8F97A9E380C8A3902C2014F3C6B2F36702EBCAD5182E33641FE6D65A2BDC1729FD8230D5814545EE15D6D02907D2615E9DE534EB49D638FE0CCF5497D351C421C7F25FE57A507749640328EDDE3DFD807DACDB335971FC46AA37177C78D179DF12F187B531CD5B02A08A12A0C5B7CDAFEB636A1EFB6CDAFF16F4D128A0C1EC96FB97083C622C94F3F65105F865B1FDC81F69A56427B900EC13EDFA938C0E8FB31DFA821F04CFBADD892B1EEA6F596A6D02947F50B3B66A3F0323B9A1FF95C33F68EC2B833D2CE958552A8205B5BF0E554FDC441EAB46DB0E8FC319C7FFDE01BB3F118413C8FF941C37CFB39A60606780EDB9F5818CA4A26E1240EE6AD117745F173DA5B2936F1B25FF1AB49E10913E9144F6A1C0C547A93408C5C5E1155F02D5C90DC5E750F06BA51746536E351814F1639AE3C845BA88EC3FA60111C7F8285284AD1CBA5997BED7FDD71205032180050C4010FE353CE4695AC49DB104CCAF5309949E2D6B4485C10E92656FA130C7D0A2C424F98683A8A2F4ACCD31EDDE5B11DFE71057983A79DEF73DF46427A00952A69C0403C73707F151EF1C1B3C39121181FBDFEE8EEEFFC74BDCA8DE6078ED56A7968E2B13426CC387776CCE40411220FF01E2ADE27EA9F9445A635EB8C0D073232FEF7F580143EDACE3954AEDF5FD01756102F639FA9643173146FAFD50CA4FE2338584632D433640FCF619D141541B0C15D39C89CE07A47F24F59B3DA68A42E7FF5394A02B77A35DA7A61C2B7C430678FC9956211038CC2EFFC9D7C8E04EB0CD6277210F49940B39395022A226553DB46292774276CE5CC184B29CB598CD85672BDDABE25B8F20486C775DA97B9C3B97B4EB9B729854120555C25F130FE3807BC886A43BF605FDA29898BB7160DE95B927AA7EC5D5A5249E82D4D50ADBE591FBE49C927EDD94E557FB64F73643464E7AF168201C57A16C6A6FF6ABF1FF392F8561A66AFE569E51F820591C0A7A43D841CD13AEE08FC15A8BD8C0EA63C69EC331881697EBEF2C1646660E34B775BF497C9432394393A7E3200E63E477169D9C3FD737BB79C1155ECBCAA73B0C54A5C0A2B8ED6DB93504C5ACD7FBB15181696C9B6EF1A93C002FEFA46007D8DB5DF3A7F659AC032BC3780D8A7C7FF485761E632573E96D052183B287174E96B230025543288C37DEE87D6EB3C44FF58544C598EDD123CABA17B0C17C1D129BD90D72382FA5644FC94CEE6BAA9C152A04F6A1B5F6D167E8B27E2665D861D5E439F2425B562DB155DAF1573B3F69649BFFCCC73DC72F3E3A40900D56A810BB99DBC75A6594840006909E78299F4C56E451147C3FF9F069A65399B296C2B906E5B493FE4DDE19B4831F43BC2F0221A833EE99938E60BB2A71CE0E4E47140D73D5BBA00952E01883D9CD3FDDC0430B9C413455F732FB0AC226BB59DC0A65C73C915023C035C6C62CD6D1F3D5C27F473A0AB4C2D946D726A0B8742E8FCAB04D2CC23DDE5B0BD952D5223501DA188822F481B8F8CC377903EE38A740AE1125F4789777D94176042C70317528ADF14DCE224FF871105257DF7F1385D1508C04F46ECD2C2E1F3E49783181ABB0E2E503FD5DECF38461C9D6E093CC55850DC0239B7F550D7C054097CBB554CB53C3F43FE1E7EDBED3B55491AB564EE3AD7A9CF330BC4D42F2837E56F15E9676A838489F0908E1DC59DCE7AD7E72F57017BF6F610F486FAD183C714F99226889020534972BF58D414E6DB20F22FD60EF8359438FFE56C20F28D966B41717D3B63250DD0B5A961E73E06793AAD1836F8341C5504C15990B1DA9F37DDF87EA2046AB57D894998725CBE7CDBCC1B5F4EF0B48B05E545AB5125CD4A9C883BFB58BD3136F03E3CFE3F225284E17798A1F4B38A91747DC5A2D64AE13E2C72CBC24D25F809AE19100FF0C9B9E9063BBDB08DD776F7CF2900C56201F56269F3BD8C3EF15BAB0821E1330DA0C441CF3A5D0EFDDD4B2B48C0F567C00346B97F8EF9D377A7A590FFE77A6BB2D6FB6AFEFDB7C8260CC1EC3A3EACEFF8AD086CDEA49C39C961DCAC0BC22FE446FD1F7099425D559CBFBFD68EEF03525B01DECB52D5ECB1DE9FF4427C8C607428CD43E33F5DE8DF9D995D033DF6A41F69BF623F36451E53E422BE18F5F9667F5AC1FAE21B4106CDFF91333749AD32978EF6FE73D7AF88D4DE4D9E2BFEACE96D8DB08DA9ADF8BB51A16D326378B3394AE7307587F98FAD697BA01C1B78387DABB5D6E8A1F2CAB663A3ED1B8A833E4F76D11E0AA38CCF4476847741AC8ADEC7A5C4DD802604F690CEF94B014A1CC2FBE8F2F71247F426AA5CFE3745706E744DF24BB7BDB8BBE8BC8EEA92E46F8BFD515D52B3CFFAF81F127C5CB65B1AE5D4925161610CF562B660CCECABB35EB7F8BE085761EFB4A8F29EBECEF2726938606D2562B4ED69044AC08769EC112DCD7D7D54331549C41D7A9A9D9F5B004E4490ED183DF65D917DD1AA8A2B50E86F59576A304606FD527079F60A3D0EC2E36A12D354B6187D1A5301FB1977EA5E5011F3CC02B84BD6A5F21D411B4BB276129A81AE6471EFF6432427A191134542EF23CBFA2E32D2007C2637A189D7AF0A7D3990BAE139BCD2E225A671740F83856825ABC24F6CE908C4AC1FC3A61AAD816281985AB215AFFD2AB0060B66885168260028090FCFF612A034C68E0B2BC83F33585C3FE403A094DA453ECB21CBEFC03B69AFA16942691759701F101BE11478DD5A4DA021781642D9646040D6539A8A8B15868852E8E233178BF9DF56D048D17A88CC5C5FF875B2AEF274D18164B16CBACF4D2C12C2DE37EDF89A76E4273C7F888820B5C56699AFA1D2322D399010926DD5363B6755F75EF1AA5C0DB58D92FFDC0D666E2F466490B7FBDD01D2282B014F08581682A8070F48E69670446E0E8A22D388F2C36FE6B4A0958BC20EBD7D6471D89CC45C01CBCF09F3EB54ECFE1C1211F5A5C27D7C12FE983CB1CB02ECA7E7400F700B78346B9A4B669FE0D7B6DD805BA558DB32952C90EFA3E1DAFD68D8A00F5406A9B127B8BABDBE01FD099549A8F006DD30D20E7773027A3A402D8972FF70A02E33F6285D55990F0D378A56F5CB27F22904A37241C23B2284DFF79EC41895ED8D37EAA794D45C1AD60F6730F423F874AC4F2DCD82539E0EEBA01FA3B1EA2042E31999291E470606C96C23CFF97270972D0CA855DCF5BAA7CAE8205932D42012B0DE47201218528A76C21E5C0685FF03306656A6E5BB15494AA2BE9F01CB9FD740B8B0FF27C852665087EEE29806EF19265EE458275AF2BBEB9848D2E1825E617AE07D14A8B3C1C270F0FB607EA823EED616B90065F2BD545A0F6782E4491994A57D785D40CC92742AE7CCCCF12459461415449C8E59F44A8799CBADB6EB8AC5E0DE34DE602FD536BECA0C2A5DCACB9AA8A46843921A382DFFAF4381776C2EC6A588437D908F0639FA2F23C997FEF001262C996B7E28E074B7A1D2B217FC28E9C72333C89577CE807333F1255095E624530DF50FFF3E3FCF5CC25505E294A022E439611827C869E5D13540348EC4BAEEDF3DCCDD78D771AFB3978D82DA1799A930EEF91CFB315521CD70B194E413FDD1635DBCD193916C3C659F61DAC973A879F189D696D3F175FBBBF0FFAE496A5668A6E20458C9920794B0DDE8D06627AD4E224E112AEFD59BD32AE37BA750624D5AB84611D8031A3C3A377B10E2BCBA5E12AA23D3DFFE6BAF03FFC5BE4EE39E6612F917DA9215CE479AD49F59A34353EF65E82DBE07FC3E9C8D92EE011A5879DC5C9AB26EAC415D520DD2B72DA37E948C56AA177CDDD4B7DA86D1F6E739FEBD5EF78EBDCABEDF4E159D15DC81F2C9EB46079E1DF3010B133CE46CAD6350FB83833D4C33AE8FE4653B4A441800AFE90D4F0CF74C4716FDAC1FA292DA454791CA823136EE844CDC153FF4AB5B2FBBD2924B822A2EA96254CA33C2837041B70B20A3B15830EF876008BE6A8E412CFA7207B35EA6185A7A1AC2B81B4A6EF72A1C2B105836D49B7F96CC9E219D3511FBECCB704DB704961E669EB3FA517A7686DD118AEF575BD351AEC67477283344ED69C0F5308F8B1F82E3DC7A5029542E2F991242B179E92201AB8AE951C0198410A5A5C7C4CAD7CA714D9D706D2F7E0F9E4E2F04CFCDB4A3316F7984AF20F4D2A5BFD44D1B1D043954DA9D6DAD6A53E6B9F3574FD8D98B3DD7C207ACC73118C6C76EDFDE760E87AC11AC8B45F5B654C256FE61CC7F19DBF91E17CAC7261A9D3FED328E2DEAEB1EC2E8AC6865D339922892C680C84C66FAE7CA866468A67BD7AC99E532BDB02A687F3E7DC1DF7B6321598C0CDB20C994F2C1D84B601D8C497264396040670710A7FACB3F245E32044F988F6534766081480EB66208A03BC1B39DAA90200A98A0CB3965FD17031252F9D8E1BA3E5A555195BBFF408C899B138E5EF0F5F83B80AF8B9EE51C7264B2EA53A429CDD28C67020FA23E5D84165409B5EB01D091918648BD630DFF02CB082DF2FFF46E7674EC85F8630D38F5814879EA3B4634B2B60E73AD8540904A4D1AA123F2B21C3607EBD8BC49C4CFB36059E0AB14A528152552611A3B542A31A11FC238BD954A38D671DEB393D8953F0232A5FC11FC99E169B0B47928FE5342C3759CF052DA0C40CC39CBDA11D9C7FC05ACE2AB35454B2BB3F44C647499CC55174085BAC97FC4051E18E48D93F35FCD6DE8CA0FB468B7A5429C3A5845EFD379686F59B5FEBD931CD9AE932336AACC05E2840A8C599A560C25570C1F4B0D4638FF832628A7D9BD88FAB4E94A185C05FD8919C91B9D44FA4B52DCF678DD0182B9F2D3628E751DDB91F3B60C29D5A0B29E745EA2A99C84471E1B0957F1B2C591032BECD263038ACF0AE3BFEF0F28CCA64453CA4A02CB58752AE9C1E3AB98363FCBDA22A23C4B070AE3B92B9145B3C5BBF3B08BE93C42632A54ED8D728F84C5522B313C007B74605BC965A5B2B2C556A12B4D8CBAD54F370E86052C63CF26BB83EB430AD5482C8EC7DAAF302063A455878DAF56D8C93A4C6D34F82ADB4CBFD4A8BB8E3E6E7FC1F2627416ED0021E43516C81B4B6CCF5F822455860779D032033719DC80000000000000000000000000000000000000000070D131A202B3137""") + ), + new SigGenTestCase( + TestUtils.hexDecode(""" +435FA0487592C90055BDC2DA68F33959F690A4F2724A4363262E2DF99A6073EF6EA41B044DA7B536B18FB802026B7A0DBFE4A80D41CAC87FD98B09A9AE370EF97FA99BD302424B43DA240CF31FD918246429B393D5EA9E01963E7B03547A6E19282B86CBB267B1038DFBBC3AD915C4997F7547CA709F68F4E8534A0E54FDBCC650B690D12005CC14444CC088E2120E43C0511BC391D844721BC6900A0744D930215C082E83066590462164245003A720422209044308129740424888C226615CB831800432983464C844051A3268D148501B326020970008C10101810D0BA41054300299204D0045662245494832104A844D09B9500438701BB889C80248844202191701C0B805422048DAA245A202060A4021DC006A110085A238092496494000411C968181808024B7696086480288701C9811900209A012814AA084CB122481300008314C49124940A62098286D99326E0906299C3804E082294AB09140A84508019011237019171023A45018B491C01601CCC609012601A1884991A06CE4268561120E1CA840CC120D0CA920491048A0A261E3047089460519B6248B446C5C306D5B8608C388444A428123144243C669DC44080CA660DC826D99C885A31092E0446D1BA605C9C870D9A085633269921866DC34508B305158C4211A496049384DA438294192045AA24CC31090DC366180C420D930041C0511C3B085098080D9C25121014C63186E4A16262129510A9185C1886D5B48921AA94121C14998162C98844841B444CB1062CC18324400460315440B252E80348092960422B74458004A12010E4106628B486481389012952109377002B008000651883672C1382ECC24201912700234461C2182092421241150A4B28553165101B2710A8770CC983149224E8C1630993046DCA6704A240944324D521224D2907111436923164A24394C18203223970491B0014AA87140A01011394002302812A365199065114521D882640B30061BA220D3082449402599366D22C06101B34199225223B460D8226818100944282218468AC11406DC46864AC005540260A1C02080304E21417050342001342A0A382590186018154522284418C94898A43092323012004C0192619A102CC816004C906524064A44028954144E21B55084B451E2366C12018D42826C233260DC240EA1A8081A896812359224854818352C9B1492532430203192123390A48228D3B281581849D3A6895C086A90A28C610806D0486CA3242A00076911B831030932211026828288022286D2A87193142C64047200B7088C80114398840C058E803265243631049889DA4881E0825000A765C94401A01648909885588628C8142E1A8380102185A3964903B8480A996C4C92319AA269CC864CD088095400260A80510824250083894B02481B108E12304D908449644490CB289012158A1AA724CC384A59360A42422858128E13804CE1124A51B691D0A46CC4328C1B8861080849239584CB9260200661401840E438204A2070C838888C3852214761A308604B04465194914C82010AB4442385612225024186809C2271D2B689D012691CA2458C420A8BB0885A040E9A926509A22881A220DB42695C42224A325050382D9C362A12262C241446212212CA922D9A166224108AD20825CA9844DC0825919045DB402D09A86504201188A629E014310836491489401B4520492449E2203122B46DD3184D600242981400449610C0880481A65188B0804CA4110A2650133802D0960D1B17264A48410807309396218A086610B29101B32459962094968411818118A090A29210D4806158903103018C893850A4B44140C004C0184200210E13012D0249649C14084A2646CA046C0C316DA1882904C02C4B9621082208A404325B264E9CB20D1AA549198484CC10626106291A1481039964C3124481186640326A220402999611A3902C1B097011206C5A342DE1128A88A4801A49401342849B82911A4391082525A3346DD0B2051A852C4800720800840C376510930050A22D5C04711B426D91804C82C241142632C8C86D8B824800B69090C088509060E3420DC41066640640A18401C202210CB32DA0A824919051A1906189202A12806590182149244683B645E19208C212095B96050942682122905AA020CB98091B302D09C410CB368CE3420623226122B070D4A290440841541208D3326694860C0CCA61EB683B44A65D855C8A8CD65BB1DD44C7E676ED115E302FAE539B8D26405CDB80C936C02CA3ADCB2D45237F170BF28E29C52598FD7B1C389A1A03C415B2B5CB096E345354FB26AC5DE65678CFA22BC9EADE8B1AB9863CA97848EC9D5E343F1C6936186D3C9DE36342175D26A5611E46F424D3319F65787FA40EC6E0C29162F572DAD37CCA44005DA35F5C85920C0463C266C502D2BBD9A697C0E69336290C5818A692CA61F1D60487043756B9F8FB16B807E918C4DA8B0F3360FAC63809682839FA7B52296BCD67F98B5FC0691184670D463143AD983A1ADB5F1AFC845A6FFF947DE0A98CBA74D06387F0BA27FB7F45BF49E89BA49EE6BE6D8F712F976C0C0971B766AD7AACC39C0ECCC4D2F2046E3390076989789C4E8C9FEE60567BB71DEE7CAB410CC1A9AB8D0751E5204D2AE85E38786FE3F436E8818FF7DA12949B52E9D4A3ACFE5E738163BFDDA76965FBD9FE49FE834A0B8C27AD5A00522D0B515E019E4CE8808A828597F25F2973DCAEA91F99F4EAAA101C41B9D9E303C22349FB39E7DFFB916443FBF9F9F231D6A615ABB5DAC5C63636B36D0E493A66930CD8C18B8E30B51E2F35B19B7D0C6118C9CA787F65148A3953DBA871A2B2105052DAF29C09DED9D838448E7459948501A6612013C599F51EA8BFAFDAEE41C94AECA8643623F46CC19A33A20191A9EB4FF98F484A86F7FB60864D5B4DB538A0FE14D6D12FDA1629B2D6BE674A242FF199F3567623C7BB649E229281C2BC355CD19C577A38614267471EAF4A46DE3FED534E150EA30D14E4CCB2C10B5F8CA2B8086B5B6748CC76065CEE5E96B4BB75649247164DCB67750B9597CF7F0C4A883B8D255375B048FB156F4B1E587B7387BA3B5452204F76CDA6DDBA7668284EEEEDFF0A504E19B737D733CAD1503DB662ACF2BBC9B64542EB1EE2D3A589A2DB224188FAF5BB8369245839449AE58C84D907E0F34FA83FABB302ED92BEDF217903C5769581AE4D783D545A8F3DC924119BD7998CE47919824AB5590A74C5AFD2D0A484232408710EED75ACD8E2671CAD9FC7A65788D6E988A621AB764E2B8B7C35D77ADAA684DDAB63B72316861F593609768AC761782E40B4C81D84169E04EF527B631269EC3F787143623311C7181B383FA6ECE49E11722A6C5A5900193E2427B56E961449874240E4E23523BA8B321BE7A0D984E1E84BC51D3844593CC56E61A6EB08F9107A097CDB8CE39FAB34DDD12DCC3475171FE0145152F44B4AE66E4D0226ED9BE6DA532C04DEE1162AE6692F8F94DBFF4A8141CA11936F1D2FD56CD9244036C73CE0B6EE0203CD328A5E1A04E0F6DEBB5FA6D648598EF1F0EFB0D05A16EFF32D527BBABD964425135105E67D0418BB17C3C5E4C53597C5CC9B6CC27B0139B61EF053DE290F511D7C39393A6B8C5D8FA46119C93E79AD18657B199A35A01CC48AD090CD6A68F84CD512A44514F997353A43F1807221B29BFEA62B5FEECC1F9388CB72FEBD181C49BA1DD96FCF24A6116A62563F8088148D5CF697CDF140EB000FBBE2B54FFCC36CD5B90E92AB4BC8B5D6D4C47C74C5329E70D87D8361A3484DCECB0C018C1A9EB6DB8094B8C7E0F8E5B1682948F76BBCFAA1D80C5CDAA1650428E2E1409DECFA7A1AD4AD428469B6A750C74297C46C7F216827197F775CD8D12280193E0471BC7449D8EB97A4B6EE40C5D73DE0C14293DA0B4C40C9543C284F251C2D4ACD332289D10442B72C3FBC564C092F3D0FC86F71E4E4228D7E746EF2153CF2A2FDCFE50E8699A7F5374B872EE9494D5A00BC50D7D9B356F9DBCB7DF82475AC89A88C6515ECF1F2989745EE765D4B347CF8A2BB358579B7C09C797A339CD744E8A69646B122F7C5386634B5F69C2CFE791DDE0EA8540DBD30187C9AA5737B728011160DA202D96D56E21BD38DD33EEA68CF5BF69FC64985FDAD57F329CDEDACE0C8103AACEAFE3AA1CC3F0A79934F6E57B8B5EA73F2DCBD0B4FBA7A7FE06C6707DC5549E0567FA09D1FF4829D127A5B427F2ED0C071A3FB317088B689DE3585240E74CF8920AFAC2E82F16541863DBBFB7FFCDCEF75F43C186DD87C91D917F4B9A25E8AD13FD4D771A427BC43A27054CCA599AFD0F5864B3C92EF3D0F29A5B43079C09BC6BD9A7F8C6757BBC2C99A944AF3A0C34D56C91637B6CD7331FFCDEE817DB1F91F30B5685361DC8C58007FC2A95DE3BE0EE011859652F72A0892DE1FF0B21E81F6155613D0A6A58A5F91272EC3FA864EE9BBCF875405D9CC9F103D0BE1F4CFEE618EB7C9F872FC1DB88DE967CE96B9C6ED273D1916D25A07702CD27D61162FEE2646F7B147EED996F817B0CF5EF4939FE7D13D653D3A8FF35427B50C0FA54E1788CBBFF7EFE8CFD7B7FC17963CFBC817FA2D75E9FE199AD0A92CA95A0AE769D40E71B7D61D4EC90A69FE28003844A0117538FC5CBE6F1B4C65B41D9161477C23D9F601B7B40A8AD23D79699A8A28271C000F160998FFFCEA6B0242ED8449C692AE85B64D3FB0C0DD3F0EEC1FDE20143504043D63EB4DB27DB8C3FB1A9605D1C13EDAB1025784FAA92BE63714F8A013AF297BC0C56AA291A0236E444B197704A03577AE59246F46EE4AC61A0FD9781F13DBFA5BA07E956DC9F7018EF0814B9C5F6F5EE95654D6D222BF1CD75843FC1482A8445C73AA2A82345904FEDEFF0EAABDF4F1936765A2FEE895F8A933A88C485FB39F1D36C9C6C3194B46E9DDF80B5F0C3F63A10C4E2C064D6D81FB4C9243A2C8449272C1B2066BC8E8662DC7130F940EA2B5BE2E7A5E31E1C7919F09FE277B7C0425C4477AC534E083789AD5FD06976D13DD229E93DF2EA8FCD22B501EA1D6A31BDCC34C225C858E6C307368F09071963A431F5DAA9C9CA5C5195AD9545DF69989E23871DB3D6BC793E5CCFEF6D9FF60912CD554416052E3D72865BD9AED12F48FFC38F6E9F0349566692D0E1711005C5925D3F679D6B118EFFA63CFE7C0892BC58A98FC64E1D0853F515CEB10693BC9D25960038A3F0F12D108D0094F0D4AB855847DB4F8B9D334D76589CE2A0F9C17A297FF5429F239DF27899C38C6BB426E459572A4620802BB55210E74D0B23334AB8686F2F0A078BA7668235E60E487F494165BE8BAA98565D7312357E7123443D9E161E663EA4E1F6F46BF36FE77D06A220D6CC7741C96C20925A99D7919588A21AE79F6F279E23D54CFC3BBB14A189974AA6E74853A494E780492F466AB4B49678F66A4C619C3E9BE8B904E9E6B3A0BAA7539C975E23FABE9BC401A4EC308239C73E9419C686A12741D5E75D940F6C59425C20137FC8F7A36E12241CCB1C3C97CC2C6D593C3FA81BF431C976C3369BEC74785BAEC41F8A671B983775416978AB2A779B907D76BEC0B25202ACCFAC15C9EC0CE171C330A1D2079892A4F5AE3F203A941F643C3C50CFF426BEF5833996312D8E34F4C606A9183A9B959136B7CB151E4EEB84361DA76A518285790BA43ECDED59377AB75B2E221D23C8CE880528A24C0E237A7A64FCC4D90BC0508C092D25F3F429A49F8FBE908497122BD8D2DE287FFA11273B61534448061426D37F960CD06A94E374AB6D7F3C69125F2FAA9B76F8A82E32AD4905BA7925415F0BB497F546191F4C6F5283E73D826733F1B6EA5B73A9C3874887E46D7F5BAA12BBAE84474CA1EABD2A5E83DBA51145D723B670187A2D54467ECB82C83F08636586D962147AF49C5AF9971B2F0F391F79FB96E2714C3D559D196511627487DAC91F0C011C8E3D73A6274DE801BE34762FFE9D030AD0282CE0DB79F1FF2543BD92E9EBC0317189C7883450EAF7DC8CAA45554D5E1359BAB98EF23E75A832B1477AFC4BE66C5160FF49E6F50B88EEF8DFC5F4C97BCCEB5BE1A1E9D0866DC8477C6C6F937D7D458CD7356A8770B4513767B2B4D9A8D29D763EF80698CE2605D0716DB6793FC46F46DD361AAB79DDC2EF6E41A1EA9D0A912BBCDA555DF3DE04C09F6AE1154306BCF9BD366FA43A1FC73CBDF41C0D46978C4BE84E999A94F9B36FDF1ECD0F6DD24A974E7719C3D63D6637BC317589EAC60BDEDE1208E05EC87FE382D0EA7179B713EF9C5DE38631081181C8D2E86A6957E5D75B2DB09CA1C1A6A6F6797F059760866B7585F0E2C6754237980B0973486C63DCD260E5846A23A7C9C45053078E0A1CCB4535F3CEADB65CACF20E74755179AA370F4214D81E9425261CBD181D25F192454B1E3BD890518C56D43CF46B2E57662E1BF523D864A6A705EC23F3B57578283807349261BC38FBB0D856BDEEBB18B545C96530722039F129D79F9784B99A960D32598C54FDD6D3F62248EB61DE26BFD73C584FAB4ED339AD7ED4062596E7908C2111E367352338AA3FDCA8248A6958CD153C395546C258DAD42C0FFAE0E5145F14F9883706EA9DA06AEBF193F02B03F27E261DA3A46E13DBE6F20A319230BE1A6E480C159B85261C74A0A4956799D03C70396F9B0F7605A54E4F2A928C7F68A2D4EBC5F930BC381EC7E347706F27C44CDA560A75623324B6C0415B4E78CEB6467BC987845917F63849F2DC6467154E65C8F14BD7D5FDD23547EA2E10DE39EC26C13AA36AC27728826CFB29723EEF5F3CB62809BF3FCBB0DBE718704CAD9AACE7EEAF4E56FF90DBB3E0F383B3F71166C25923580BF42364DD5050DDEF64B48337E0AECE1384DAFD79A00D7903E7B16885AE76134750B9E9E4654C819979E94296EAAA6EA011BC6D6"""), + TestUtils.hexDecode(""" +14A8B812B4C9129CED02A09C8AB19443D34DBCEE85AA12528B61F84A2AA9D9DA49011C8E2C3C3856FCF761EA9C9882FB18666F3EC2C8543037E54FEC1F0F944FED3D350CACADA9428B7FB7D9DA4937DA4D1859BEF8C6177F0EC93BD67FC3D5B3D13C34D472D01372246704DA4763FA73BBCEB0F4C3658B2111A7DDC01FCEAA9059FE3DD5BDF2A9FE0D1C2384E82926EB895AA529532FB20E12F1C61BCE208E48ECED036E4F84CD60F8042475749E13D8C3ABE0AE17967D5C6D8C598A53A10231929822FB01EA976A08BCC0D18B1F9B6C7C1ABDD15121E00EE80459E6EFD61CB8D5AF950F0A8FF2807C32CFF7A56661C67348617059D7E128A72C8AF36B149DD8B46537EDE60EB5DE8A16A93349883B73F7C4FB8CAFD01E0C9D7B1EBF6D7C9725651980E0DA598A6ED5114178E47EA4C6ECF870033A03F134461146717C8AEFCB8E8DB1ED4E286C68C7358FA105641EE3ED9B4A5D4826B31706CF0946C152A365B246DC036191613655B829ED1AF8044F5707C320EFA1126B90137EB05FC220F122AA990AB476EBB0BB3AFF5B92442A857F6808E144C60F4B5190794C411C705513BC32447D83B760E907E6FEED63FC0A60C0CCD01734AD55EE178E6BD6D4B8A238ECBE8E4F8A464C381F16F11BFE62DFFC5021FABEA941D24B81CFC3D0F07F00F902FC5042F95A81BB8B795907F8D6BEDB5E5C56D4B2A4353D0188A90C01D7B2781EEAF2BC3D3D58A6F6AD63DF7FD4D32ADBC5A7A2F81EE3F5B98E8052017868EE59D8DCCC0199A006FE4FF39699EECC82DBAA846AC60B51FAB6F456DE4357F5EA43FDCE4B57AED55F2F6EAE49199AE90F6CC4AAF662ACEC2724337AD7F9CF74AC990D3083FE384685A1E616B233752E31CC4FAEB8048EF77480CC849D3376464621E2BF48CBB55E1A7CAE855A216DF4A8D1AE4E4016958F5855FC395C53C23327403720271EFFDF1A90C44E93E74D71BA29D860679E877E410ADE48ABD0EFDECA426DA792271D813116ECC894D799369EA8094C328D7694E8CA47459F31F5065858252C1EEB1AC4750AEDDD327048894F7D79A1D64737EF6E8B93ADEB938C1EF31E38DD60E8B4174AE093697DE4207C7733D82B4FE92590358515D30264A408746AC252ECC0BC28A9C98BFCD76C75845E9611909B0089B571259D1D115EE0D5DC6BD6F3697E1289C4742CD99F97B5D3A22631E33A81734A5D2BD1FF4A819CD6A22A938D3F18AA90794C120F4BE7E14324E89EAD34820070F8160B140E8CD5D68378C081DADABB41D365663AF26C606940E08B20581F4E63AC6E68FB5A7EF5DF86047BAC502223AF08F6CD82E6ACDE60116593046B5CDBFE2411A3FE89C438A1E84CE6D1CD72CFD3E5F67C331E72754F6CF2BF921FDE2C6DD5481F20F509A6852AEBF55BFB4B52D1F8B3E397C9B147433198073049638DDEA7E21C2043C786C88E45E566B6A7E8742209F5ADBCD34FF26962E87CD235CA1052AC02E4BF75DAEE60A06B19A4B0A61A15D9651473DF8AAAC6DB951EB6E669FA5F89175DC1FD4D881D688C477D16CEFE809E623B2F2A996909C3E10CFEF756ECE8E93072AF27B87715953E0C48946DA8E893160CD351E48FFCC6847975621E5C75D5DBEBBFB79297AB368D13BA95308E3D576F1C54CCC1C4D5EF2A41BE63AEA2A9F9A27822ABFF58B06AD99515B97F260843DD2304C855184EFE96BF10420184CBA2CD3ABC38D11B7A74E4A9E40FC26CAF3A84BFE8794477335EB1F4C67ACC9513BDA5D8252E608D03C69D493F8876FFF25D39DCD71442707AF2681CC6D5E117BD24315B0FB5C9E8175CD42AEABF699B7B77C9A8918AB94518B48DEE1777EAD8F18709A824F277BC06CB67915A5A2508E18094B0ADD29FC7CD554D8671CFB47EED2F850FC84B1C0F27767B3052869B653BFFBECBF6D8077697D1F440019E3381FCB917F5C06008A04C8A88B4493698C1964E25A551B03805244570D0EB6999AF2BC467EA4732B460A40F7C2EDD2CBB07A2DFA99B4E5F4663A45F2774C1ACB0C8B965E1053E3AA140E973049714DD644CB9317D9B3252150CC9A525E8729ED4A9A7900B417875391F7BDCEE646B1009CA479A1295555759C5A7597A775A1D1CD8D870A71DA7ACE7CCC7D2F38B18BD66441D80068F76AC194FADB3ED5F4201F26F670621D254264A4D2A88426FA6077895B9BD794C8C84DEF942FC43F2FA115509429A939052200196CC921454A65C4BF1A6E871970A3409FB9773F356BC17E03EDDE8CBF2F91E7D2B548380967F756D36520009DA5032F20D8C8CAFCF4B561A4C2894CA13929DF2AFC2C1C9FC41968746433FACD66309D2A7FB5D90EBCE40ED1E80C12D07BCB075FED76DE423D9EE6B1C787E1039749A0E559B86C4079CCA1CA7E4A3EAACB300C453782071725F6E2DC0652DB5EBE7D1C16B6EE0078004ED1F49DF439107AED04A2E69F70A35057C36A307C8F5BC13FCEA76AA997DFD2E2E4B835677EE961234895BE9C9E7D1486C04ECDE36AF4F7075C0CED9A33C372C33F751C953A2096815D9B6186632D3CAC31AE6D0A931258014D6F88157ABEBEBA1C11B9CB2956253D4950F5B2F64476E4125848F27D9ED4F93035FB5F5DEFE2435E67DADA015F048A90EAA9780B983748CED6056D021D21F6FBCB1A2DE0C627F2D9015B3D9D35CA17C54B0FAF85D0C45A53DC2575E2CB54B9A5681FDB66C9D5A09A3F48DFF29B24E45BE82856C6C76F0B9680F7B666B22221E14DD8B22A15FFFDA1D666F4EC6ADB5B929C2804ED36077E1A39F166C777770124253ADDE6B77083ED159CCE35894597E7BF3DEDB346571C2BBF69AAA9ED133E94AC7E31F2C30AD079EB4B4452232D83E49B43DAB60BBD92673D90F187FA6F3859EEE1630D3A232B99F3F960E8BE49CCA0F1A519156D2D861F8B6C15FEA4C4635C23F2ABEFDE8589A45947D391CD1DC3439F965C6DBB5C5C9AD14192B3D784D1C78B3DF6719D5C474E02D471B9B857611E2FED83869BFE8A2A74493C25D39C78DB019BE93E3BE331131CE85C4586C0D40D676640405FE363646C2264DE6F64365F19F87A8C54C884703DD369FF52F65CD9179B8A09EB92C38C284E06B0537EE686D7BF3BD399FBA8E1703BE3236F8BA262E2C84D55EB1E1E55DC14780DBA04BC1106D98B05593F9164F1651809E8AFA0A04BB0B51F9FFD5062B495133B509A569845CBC3003BFE23A7D7ED433B70C2EAFF5FD898009CF1ECD9E9B6F37CD7794234A098CCC39EF078E3C152017CC73A19B811FAB4A2CEF721029F6200A4D1E4F9E95A0A758A7AFCFA047B6707CE048C3BEA6BC561D152AC4F161347C098F4F44AD92006090324757D73DC074F1E1D445A500AF5A92CBE19EF631D99FFF870C60BCA8515125EEC36D004F22FFB420F5CB01330315F00CECFEE3254E54A047A7FA3C7495E6ACD579A9159F667FCAC4C4448579E7A68148D5518EFE269E97D90D67CEEDC378657A45E9DA855EC55E7BFD0AC3E52DADAF76E800ECFA61F2BF532E7365C4FBC8CE882AB327961C6A48C24CF0F0E6F2C54D732BC9B592008F2E6C80F7EFA788AA6BEEF0B6AB7B21DA3F9D92ED8A8F5F3F4B1D1BED6F66B6BF3ED52E49715C07DBAFD67F4F253DE368619A306C513E645CB5F154F7823781EB3E15F38EE482757009E42CEEEC1530A0159D25F052F4D4326412CBE6CD11C0DCC56B6556DDF806868B83602671C96F81D8210842144757A36CD187EA0900F36A0A9DB85B9609C11DE03A38A9984003EBFDD4E7C07CCA7A7DC7FB5F9F16E6C0C32CF86774B46C56BFE2840D8EC51E9FCB719DD1CAC4206372126DC8EDC9A4A2EDC8FDC8370C7589CE9FABE0DF3C8CEA90E82944B8D489C0F52F73EA3E3BF56BC3644A1BB0AF88F4B556A554851593E5FCAB03E235670638E4AD77BF012AE074F331F67222899694CB5EABBF0D6E6E6CEF75151FAFE89DB9D66DA4464353526116B3C2F382825B11CAB3CBD221DDA588F4BA13548CF627B52478F47D9B61479730CD9CB3F6622702C9A115D69EC232CBEB3FA88AEB832EB266B855A98424B2E08A699453A891C89C45FED7BBA98D6E7A2179A24D41D201C4214444BFFE6D01A15CBE640C3C54458E8DEA5DED484FF7AA78541686C60F9FEE76D1A7ED1F5686A2EC1F0AA037E6CE38FF695DE0C17895C9326415840FEDC1675E9CF30B8C45F8EACA1E65DD18290E8ED826738876FE8B69DC3432174151C051FD23CA4675A75E73F1D3DE4CE172FD657B57D5D03FBF8B29E268B3EBB8E9BEA96A4750168E8AE5AEF6B34701276DD18F1FEB01FFFA2A984D3A59D05A56552639D506BAB3021D507D56D0FBD80DC582B3C20940DF2393AF24FA5233DF073C7FF28B54C7A921949960CB2593AA4F93A06D38D896D547B28E9CAFDB479B7D1BA2EA7B4A6BAD33BA8B59DF8792B22F5FFF41EDB1FAA926FA3CF602FA63ACED78E85DD7C3094ED48D1F3381BCD084A9909613873513657879AD8599403A52ED0D16AF0B3B43C672867700167323D37FD6373C4D51B90327F4981A897CD54C8E35A6A5904F5AE0CDE36440393A59119437016E8CC88894B2A6FF661C10AAD7C7B03B7085B70A8145C305D5E66CAA265AB42B34539CFCC9A62B5D9BD09FA4D3B94BACE361B4C6BF6B550B89922EC01041CF05C0E4632274949D244B7776D6504C9803A67CECF65F750F9876109167CA77D412A7EFF06CBCF129D057143BCF03CB1C1AFAF937E55477F5B15020149D64F53887467AA16C6692FDDE61406D552660B88AADF65C03FE1B8D485C57FEBACF8B11C569622FBC56CA1056FD3600E1BF51084FDAE32876BAA1E97637F73677E8FA1462222DA72FB0936ED66C16A5E892C44093CFE7B4E3EE33F21091E04FC4A07C6CA21E93A500E5D7378EC716A9ACB27A5687BCD7F4559C32F6C82E8C06E82135ED16C35762E94BFD6BC33D5116E4FB209C98C871FA8E9230FA807CF1FD509A75DFDDFBA5CD4F131FF8B666878697B372B92CDDA15D0113E8BB91A7750843B3D14AC4E8C956B44C7A3A26720E774EC1A1F68435B122E539C8A7515A1AC94D456BC4DDD54839AAF6EEDDFF8797C9BA3A15AC70C34DAF78AF1F0C21734DA32A79C1BD3CC8B2636E12B9D2E42AD10446EA1A9FFD45430E03A78D8F38B64B64C9D308D18CDDB4D5DA13F1B4D15157063E58C36DD71677334B4D9BF09D8C765FC68B233B31105D0957F1B675798E5B9E982B1BAF1611EFED0E39E1E9E70BC790886A422DEFEF325A07D97FC603866C2C3682FC651CFFCA09B8122B636A65E2D6B8B9FBE6BB9220959038AEE11AA7003A9C4C4EC9E27F4A8350FEBF1084C292B6BA9A6E03C00979854CDFE566831B077823B025FD1B9C7127BDBBEF34186C74759E32FC222023EAC24A6A6653A7073F4033D77CF83831E8B6BC8F26AACBC3EFB2328C6EC35C3A509FA85E2E04532DB6E466BBF8071FA6020CF5585C70C29320786EBA815EECA6FB2BDF9C9F3A3DDD0F1800E93DEC3C5E6DB4EA5A695865303C48986CE26346B6CEA4A734668D5BED675EB0C2A1FFDBB9E5511EC715BB4BA3604629FA28A53CC0DBA1E819A521AF8B7BFF16B4FBC6766543C0111E232157B7BE4D561618D6ED7D13AC8817641E7AF77042E96C7209F1B65C42D115234F6C63B84D381F1820CD656C88BDEC7CD2A814D6346E90841005F66D6E36E63C5906D19904EA0D33502BDED36E7D77FF5E2592290D6F29200668A25A6B6F44FEA1D3EA00BD4BA165D122455E8F97EDB36061DCB335870F44068EE4A64FDE5695896D6A5B30D7613BD8C8B11DB330AEEB0EF239C105CE6C0B2E1BD81E867A2D823FF88E3E82FCA69923E281A2933D5FDFAC6B217D60958D18ACED57D670851D5A6A445A120F5B563070995793E618F885F149A3A3D498C69A0B9D99D92C16327B7568BA8CC35128500FF515273099B645C683EDA30092C225D01E6337AC652586C0872C9C5EBF09DFECA43697BD97B86FD5463F529CF303A105194BCC3014F4458CD3BEE8088B8B05D58A960334C73E1CEA934CA0ABB2597F703428EAC5DF6983A76A5EFBB4A20221E6EA04F67273D52D0311AB99979CB0EBCE738B0BAD72F0DA80097609F4422D962DE43D5B9E27F2FB3FD55DB5B9E98C1E74533DE23930052446A31E656E150261C6658324BB243E0C55C43BB397367D9E6EE51FF7A3F4FBB008F87FDC3448C07B88F4EC3788FB04944AE1D734E00E1CC58052AD2F908B55B39C0B1FBFB889EE2CF91CC1B3FCFEF11C14B083F8A898BB28B838662274B9974AA8E83579181944CEDA7FCD9C36D5FEE67522E828D6FD9CD28537D9FD57C8ACC7B8F888FAE4673FFDD859F6446B41609135BEEB20804F4331E31AE057171D27D1C338DD976634A460436977192E7FED668FF01B7F996F00958FEF2F89C78367507225C458A7EF81513D849081E4D22013A4A8DA7E6E9AF687918486E785E2E5D4EA5CEC4F92910E6A6F89198FF7911A16D7B46BAC5752AD5F7457E9B65AF0DB57148812FFE9F7C70F5531D11CF96ADF7A3AE1D86039FA5CFD5BD5465AA1649C40A513FAD60B54F7AF15A5A6B34F0935BAB28A1AF631816A0F5F1E53E1A7DDB5FCE521252E25910555D70AE1A309BB1BAFB7ED3856618161CB41206810AACFB9F748B06F6BB8ECA8EAE07B77934CAB2FC72FFDB061D5FEAC548CDD1BCE7CE5D04E9D2E4F38834AAD674F0D540DD6EEA85CEEE4F67B1D572597E9F2B66554F7F835894E81F4081EAB2578CEB8FA95964742436FC6741A5A9D1F2257572E7026360708EAA41D31ECCCB55811D5BB7648EF4021268C8AFF001F2D6BB3E1D4D304374E892E4384D66869CFFAC575398808D2042B2A33A874BF364B6E7A859BBCC67ACD4B5DC3494C1A6B55CE004A354C8EA8F14E9D9A4ED282AC4D78909F42BD38D044FBC1C730F921A1C678062A200CAEDB0EBD42D48C0B758F138EBD6BEEE1E45BF92157E3279C6534232AA6C361953A0AE37E81261832F29CDEE864962D44CC6C3C68C05B16915A8FE35B067EA754777725EAB0BB4E20C3BA7D6E75812C498F29A94D18D90D60F49339CF46DCEC6F0A546A90E0BD6E75B95441CEBC0B25945F2A38F3EEB1A9E20805A81E3008750588397A9A168C73C81C97FEC1BC16659DB16AD7BCE275A884EF801D53868B0DB816FDE421A9D7FE37E61B699736986325592EA93DC18B036D5B237115C35AE3862E355A1F3CBECC5BA89947E6E304A86196E0AD6A113BED701D21E07532A6D02D014C9BDEF9F9060799BB79AFFB218F3B98A4BC9488E5D2CA13531842C6651621484207723F41055274364FE30601C33663A6DA49C8187008BFDB1FFF4B7B3DE89F7FB0BF57F2E273EE84ACF8EE91A5335364BD034DB6A1F8025E6522B4F3D6212F3E75AB34179B21AA28FF6911736724FDD4F3229C6C26142BE5D6F2148C9BEDEEBE6C56B6A20746875A6F74CACCDED95179AF50E1C5E09B942B4E3C5E227C1A9DCA36F04CB89EAC24D5E87D07BB407922341590A739B825AFB80F544F2B1B70D877300B46000E660A568999EB8F54A3809D6879935492CDD67DF15A1FA902AE6ED30D5C5EC1178AAEA8E539068EA2A0132EFE51DA8A43E5D48ECD5D8BBD0FEF8F90288E3068D17EEF4204D639665BA3DB7C172E99913E97613DC4304006CCB37F1E9F62327E1C2B5D97E31822A52298BE0D6457708E0E2EF25A0C4C932F16D25A277C5BFE1AB13FD488BDA7BF30F26E89585F56D827DAFC799D7DE3BEF0B41A3EA3491514ABF11E633D7F4B8A88CB6F3ECA3D48495475A33C9107EF39157D53D447308BA03139C7A1A9AB4ECB178D818DB6F83B4489626E2EE9464D7392C80F8B4B6317095926370681D1ABC3A48D82DE7A810124099E375F39E5C6683F4972556FF258996BFB0FB81C44E3C0C1A814AFAE8CBC041D7E7EA4FD830568DE534B65926D6CB83D306A36861FA2874234E33F4EA5BB8AAE05C3DBAB96CAD63295D7BECC26F5A4E862546A166A09E059293AC85937FEB612178B8812541A929B81A090FFFBB17DFC3C774C5BCEA1398DD530C5286658D326D7BA7DA3F2E15FAEB038B8A397B68AEF622EB10B248DCC942E7BF4B4C942D33A4427B685A0DF2BEE8271E89A366708C9E48F6A3992174E8D401D821DCFE12099D3EF0BA0806E7ECD674422731B0DB2B198C495E9DBA6294FC736F41EAD9232A5E404A8E918A18D7A7846E0BB6716C4343C2FB00286049D7BD823410EE8F71347008A89DF42EFE049C61CEE782102730944DD15C0DA322F6DE4EAD8F9EA549767BF02BEDB1F091252F08B34B6728165B11D2C62805ED24ABE65A8E95441D1D5FBD361FA87B39135A75D749325F09416CD3E1ACBC04F6AC8B989716C55B06FC784B0254A884EA4CCE8ECB2EA278CD32FD1FD99C3085585201EE9492B7F7A2259479B1FF820661466022321457088B202B5F1E67709B763A3A945B19CB5A6EF0A322272D98F8921B775A37B6CF92F66CF86FFD26F84547BBA75AE82411E890A7D8F1B74D657380287606ACC8572D8522B87CF26C0247F25A7F8CA12911081224128ED444C5AED9EADBFF6EEA9FB7485884093C340CB326BD467CFC4F6E6C17D4F13C7F9F76192BF4A10F2F28F538C76BDC1F8528ED1360922E5A6DF1A38AF9FB28542357231478192219477D554507A47E9FCA585730292493A2B3EE225E0DF87C747E0CED460BA677EC691637F444D248805FA183666FA65110AD3ECAEFF59B2F8F619A275034CE415DCEC6E68A3530D17EDE27E93D87EE1EA55D22045CF436A34F907D35264116A848DF0B448E4BBE32A18BBF16A8DAC00CA6B07876ED0720591345223877E26D2DF4C0C3FD8484DF1DC40F1B7D4D49E871D8F527837F1B790CDC9FD95D698231CD090C60915C98F1CE43F7825613FCF8EC929BBAB9BF663A555210868653131556553F7A36368B0D83AED6F9A970CB2D63163C607ED896FC7342A71C6A1C90A53DA0F32141600F28F31A9340ABE97D0C6E8AA3270850B6598670DA455F8E2816EF82D3267D39A8163D34B135221D7D5D98069A8233802810C7605AF9764C6DB44FB55E29470503090CE6A720617DC9D17A5091CD3267DC4DBC1A2B7032B50CE46522A2FBFEE7BE29C3DCFA1FCDD43AE2E09DAE7330D2E6F2B15D10F53EC6D607066504AC50AA7F18D3C290296A8D9ACD1F5A3708BC035979CF03966E0081FC53F654AD68A15A3D17A65A768A4CA5F647BB21872B1ACC5BA3DDB5F69DC215735A5CDCCF50D555FE968551D507A7272FB591587383DC5930C5A572BE9FE0C2797B622DA16C6B87A03EA563845B8201168C45E7603B80E5780E493AE87584A40A09AD6718CDA3759CF1940479545789F08DE83333FACC26D28AEB54E2088934332EB7DBD5829F0ECF89D22C62636063532B4361B9C7C2B1D582E9A7DC72FF7F2DF667D9B7BAA543FFA20AF6BCA1A9CC22B7D7D177B73AAB087F868AC68EA0CA808EDE0C2F931B3B0CCB28E472CB316C0DB0367D4D7FFE0C02977CD2E5B20F28867DB1EE0DA77C5935155175B33D3275426C3CC5B73748426CEBB3ABFC50405E30EC21A53073C83A85EDB485B26AE7B633692326003004A822F261D5E20246F99B03D0AAE36"""), + TestUtils.hexDecode(""" +82A8419E4D978417C3C821D056A9393685833E38237A688EBAE52F9D22F6204C7AA8F8BD5898702532B6A56388041730123C978F23EC29A03340C162C9486044FE5263C5BBCB894F856153000923BD19369563F96DBB4E44D2EE7FF2ACFACD81CE7057D8F82DA68C4C06718732002C3441CB07FD7F01F72E28BC170DC10054F8C8F75F0BC4757E2F97B0C8721B8B8462A0452D3E8A9D55EB9342B9D747019A05EA83C6548905F72B2C9D62ECF92103DF350C926D46C4994F35E54D436B51E1B165B5FFA4AB85D5276270CB94973BB49A5589F2CC9919546E51DC629D81573D9A0FFA2D52D31A1CC81A7FDB76FA7A84FD312804BA266A5882E82E71DBDB8C816ABD9A631F8619BB85E91BE69C88ADFF9DB36794D7F97617E7C118BEF10AD3178BAACC2104E11BBDF22642A79F05B56B5827D1790EBE998BBE2821CA1D0D69D5091FCB2677565BB6E50AC4F7F3D1B4DBE411692F289FC0E8DD072C3D93A2D617EFB8E3C914941792E39480391A8033DFCBECBA8710439D83A821D3224965CD0B95EF31A160334458F22C9FE4DAD9126399D2E02D6D539DB4865A780F0A5CC125537B00B581778BF1FC8125C09B319DB6DF5F9AB2DB766589DC7DDADD62CB3E67215B37C34B3D019D85E4E94E4557EB934519679947F09FC5A80AC5EDF04549B4089F14AE3768914D05E22F6FE2AD7D098C90F13E6763E8B230570A13B15F0779525EDCC704F43D8E15EED9E1FD7EE39BE339A3FBB7FE91EC51855BA72859BCE0F78983FD0CE5ED5AEB6FD5F1380507DC37F893FADEB653A5693E16397D1566AACCBD9853FEFDB2FCF300452330D3353344C51ECDFEC3D055B7B113A337A94B43F0CAD1C74FB3317EB9E08D5CF252584D7B3DFBC9577D7E440D5B70D6C2DAB679B9ACDA3545A9AE523EECB01F403F3AB123A3A6A79E89E5D4DAA2D1DE6652C09E4A62EFCD924CEBD48B854A2F17BDDCB2E332F035EAA85810CE6DAC97297129EB4827228F360D4A30F83FE0E5F05A69F115A4315E83A9355D3F02819FAED553EB1AC05C67E89B095D1B09689F1F30F6E5B1E3281C52919866F0E297A6E70A507AA3643C5A7B1217BCE36851BE4A45C2E690FEFFA210A93C8EACD644BBACA1B3668B61612CC299ECAF8413AC3DF9493FB99F1FCF7CD4F261907B6A7E823F5D7DF62856EA94351AC0B1BD24532E8A58B7E9F49BE2C0C8C6D102327CA90FB2A20AA533BBA2CD56AC0222F697914AB7DB037E53975821F4A4D12FA24D5C8E0981B02475ECEE9DEDFD7EBD71A3D8FBD9940717A70681D3A5766082D2012D534949D5EE31E9CDE629B12523C4CE1BBF0EAF468A871C06E4CE30C05D5D5CBC7B75604F0288ED84C49FA80897281F4C1BD56D3ADBEA4532F6DACCA40CAC34575BEA447DA7EB2D7BAA676971D5D6C1B6EAE7F4704E46F9EB0F90A38BA3D4E308A685E0EBC44DD79EAC9E93CD94EBF8E6557C877F5A06F11C9AE05882D653E9214C6BFE82BD52B2E74B6BDB1FC72150720DC9F92B8BBCD96B0FC6AE0C8C51CB35A167FB93E755C7BBF39914D5BF1AD32AF8E2A53C4AD96B73F6BF5987389C4A089FAFC2527779FA3DDFD9C23AF408EB7637B0FC9FE1937B153F63FF3502C70DCBFC15E1E2817F3AF7DA6552F46696EB0E71D992B391B3A550E0C2078FD17994F8F9913ABEC08E8AC2812D2DB1BC7C1A3E718F665158BE3D92199EA226E5C1E2CD56A8B0D7A780A50E2E519A81E13909016A920CC7D557CC10AE56274FD6137C292CF4527172093E8268E1E4ACE29F9635E34EB83799F9E3901D5DB653807BCB6AA5217923A7FFC77D941A878383CFE455E5D84823A5642155097F60768F494C6C4D8737423FC66575940AAA46E62DA5F0EC6F20F517CC5D7F3FF12F7E127E0EAF8CFCACA2A198FA9EE5A0329926B3AD63F2D8EAD33877D8346965E93FA5E985E5171498A4DC3E6FB5CD914595D8FDF971EE1F63B5ED27B4D74D302ED11D518004D4B68A3666658FB3636952387055D0187FFBD7C18B29AC28C8A06B284EB0E9543CEE183BB5E98E4BB4CBE2291964689C98F21FBC4505F309B1EAD2FD6431CE913EC4415C01E3FE2B75586041092E77E2F2D1BEEE3084BF9F5D9E7D035F4E789924396B52EE47C502FE881520895C0026297F7336A50CD0FB46E966D32E5098C665AEF52AB2EFC89FF5D7378B2E6972291A57D4A82629F3F14D98B707B60704B18B48F0093AA2477C297E5798D34E1EAA25E8F440D8B2E2A4C556B8DFFB7D08FC690E15291FA768C960A8C7B962C03632452AC7888F20170CABC04B091D5A173592EFFFCC7860A870691AC48D44AC35F29CB7D57971E5051349D699DD8B511DEA73816A592B7D4E1C66B8406608ACFFC09F872AE6C2B13B0C8DBAA51186CF9BC3EA3AAD2DE618E13F0079984B11CB092CD1C938D3774AD4708ABA354880F98F0B3AE28E6BB4C8E5964FA69ADB78A68B075C30E08DCC8E8849C0631B8C9236E986D2E6FC6C3982F5F1C4683D7C61B8B469B617EC0976876A69C22180C37D9DAABC654A91E991122EC08BE674E9A02CEF4D0EFAB94EF5590D5E797490810BBA7894DF86219E813108BEE6541AB9E43F68AD43477AAF5FC5670FA2FAE1B3A559AC418E674994CF8E57BDD99D2CB349E09C1C68E5568282DF501B34BEA35D00613FE208334573A9E88710BB32E68363EB76F6B9F29297DF743609622345E4395BB52B9E36EBFB5A5A5F7F8EBDDB081C36AF9C26C9078DC7833FA7ECD78A4DD3CDBAE9C56ACCC711E29CDD03B740ECBA5D0A53E3F0F9379B96B9561F80186C4F0C8EE7BE11FE864B6F2E21379698820C32C12B8D8D4AF2E5781830E84F03A9E84B66335A3A454C269976BE5CAECC27894BC71AAD3AD6A6F0774D4DFCE48D6882E2BA9259AC6460801256101A35CC1C56955D8589C91542B9CF947EC7504FAC304C57C8D862A292DB0351DBF5B5B100D037479A401AA81320680C4EBE9E3A954CBE168B24F930E9928E1DA3714BFCA4C2D55DD971EDA243A92122F3648B9E1DAFB6FA303E4C48D4085260984AA0334713C4CED4116BDB3BD10C004451071AEBC2635ED8D401AC9801C694041B8A25398C50D0C1A7A14EC42A403ED3572AEC00CEC00F51C170E3E3738F7DEA1D64CB61270E38172760A71B7A9B52ABC0571541FAC7B96A9C0B3F8682E8BDBAC16E049BD38396787004F4BF722B6ABED9C5B3B058D06D92311EA9D2C67496551F2BEB1D353B52AE714723B1693C7CA78B1D0E5F212D2DD95C34DA583C95ABE1BB4ED435C5CC4105390825F0548D2D960B31AAE5558071DA276F28AF4F96B1FDD20A51499858839C80BDB845F3F799855AEF0069D20F3C9D455F34FF718B953B6B3AD111CC5ED7AF7F0B37969A0E474B21B1908F54806ABB8F6CE24F147C7767D10D1C42EE17FEC645253BD993E85DD82C77483667748E9AD17E463925EF4756A90EEEA62E0B9984CDA389D9B784ADDEFAE9CDE3279BC9DA177D842B9C1964FADF4694D9E1519D40D49D194089D1561FF729B41C6A111B749A14B2F84718892EEE595CCC97CD64048379024D76F04D31AB78348887B53DF69AD1F376C69D7FD86D919C98CF8B6D974C425D6C0F9DCC70DF596C8025E1D60C1D0C240B02DCABF093A7CB2287A5596FA1C0170645D4646584B4A27D65452AB91F79A9AC938B0058C7BD069DF24F5982E923CE56B070C84109C11ABF5BBA299DDC0E9E78E0D34488A564D4313562530828D732D98EA08E73DF307184470E3A010B8A0662BDEDE5CBBD15AA4438552D809164BB6C3D2B2F0A8AE13C3D78305A7D3140925D0A5D7E5F14CC168673E682C5779C9A325D3AF591B88BE881C47A313395FA88B2680DA2625AFE996BCD98748C2E82EDC20A3EBED94CD3FCF8FDBBA910D6EFDF22B66B955FA84D5476686EBF6F8A29D90F679773FC237211A4958FADACAA5C24ECC9A95A3E6D077966577159A32D44DA9FCE2689326C56F748774551E9F121E43D336AA2A2766E0A1E8745B4348BD36169D11A7046A98A22C866B2FB05EFD40BF95543FFC25993F2B516937DFAF8C9211D6CD6E10EE1FC1C4A6CF29999E7A63222433A4C54B98F00941DBB2A8B0AC62FA5C32E9436F9B2A88E1E683E04E36ECACA272B9515DE52A1B5ACBBB0C5946DC21665DC7DC6CDF9FDF40C9A0273BAF5D5F052F955528441311D12A7B92F306BCB08687CBAA3C094BEC781D3A05A3AECB65F22F086382CCD76827F03F1FC251428776FB4BE1AA65FB12A07F288FC4522E3BDA80C0195A2AA683F18BABB2DEA6B8A030A4FBE833300D1F19CD52FA250C178E214484B528BF01CB674607F5D5C36A7F7FC8EB52A25645AB38610104DB09DA179748AD16E35CF972BA3014B683029DE092F966F730124EDDF09F91D145024C74DD7D48A28F5111B73D3566C1F1FEEEFE06AC83D805CA81346C85B07D80559747A94C7AC24DEB3E54CC75A73235453DE3DCE3EB31382E83E398EE877375CFAF27199B51BABB70DAA700B8D0137B46AD7AB1AD0DBCF1686481C770305B2FAB0AF378C9BD4FBF9C11FC744970B5E2716FDD7E79E2FC57749120AD92292750011360A51987CF58998911AC914EE82C56CF3ADD2B8DF00EECEE9FA4C5D1905CC1A97A7223CB86EC5F1ED278141A681D772CE3D5063754C549BEECDDCC422A9C5C7832155D0EAA42D455D7F7D916AAEDB7DE3575345C9B22F6584E169167D818A8BC670B9E2303332B91D52CEA5F26674B819927B6374429FC5AF1BF08E8D9848E92BE742A93118606601D8BD2E42E1783224962DFFB826770D960FC9E0E5F3D68B635AB2C277FE0145CC03523FD06F52597A3D4AAFBB191B9C2BB59CB4E89557D801E77D491BA4A1FF81FADAFB2AA137A1AD099F839F60F74986A4E69E73595F10B7CC6A2FF94DF6D6887FFC45E3F1A39B2B0AE850862022CA4A3495FC0944964E0C5B517130DF7C7ECFFC8327AE8C3AFB665C751471863D3E59D79D8BA048E5C07772705024396930188C65CA8C2A3B9888B9D651483F7C2E96EFFE962CD5C3C26B781C506977D761A3C0E3752F1E45889AF1A74BC14643D44E79120323D0C649AAD09FA903478C7F8A4DB3F96514F78B6D8D46195EE66443B11569170CDC7898B3514B7AD9E7165CA58110EB58801E5E10466DF42E347CC690F6C9B95196F143AF84E3A81BC412F7BFDFDF222F8EA0D6F742C37BD4DBB77EA9BB0A942B10442285BC11F631A19A25C34B01C11552544981A3A6D0BB4DE21FBAAA2FCEAB1D65B961FE7D546C7942FABABD25F3E605100AAB09A0B389F7AB58668D31FC54EEB0433DF42D64869FD5662233DD5D48F7A9495E30068F9C80D4A66FD9BF1C7CBECB9944C6B79DBBA18981F7D0ED9F2945BD2646464D7DA473B2B64A9CC1388A0A7B588328577B644EB7EFF0E62A413B56B422D9FE36AA6B2D0B7F609E11085C4EE889CEA76E41B4B0DCF8CC0E19C656A17EC184FBAA22AA3D6E5DE5EFF0C212FC82BE6BA92653BBD044726D4E87AB68A1CF0A80D0F8B8860EFEEA3A257605578EFFBC43E50A8E86C9663DCAFA6793BA37B116272F8DCC803B5E9A819827B84EE975CAF6367E421B9970175D9593402B7394EA56703B1BB241592830EF0D168A4FCB54C0F3D88A90D5A1C2F977789C2DA3ED638C08F5932E91AE20341FF9CB9F65E0C07656D9F79420EE20AFE7F5C9F49DF3C87B8D23E709D1FD3ABF9375E095ED34BD768F8C07EC0FFE9A9C93453197738E16B76D7E02163B489C6F6426AE9BB86AA9A653F527A1D93FF780411ED5E59C478FEBA710D2C475FE2B2649E1FD940BC1223CDDFB566D94C9D2B4D0C91D3DC2BCC6F73B4C586A5C0BE72DA7B1B5FC1164B3E3091C58BB89529B83C3578A82B11542FD27B33D2ABD1E3D4A45EF0340D912BF8EC24C2D315F6C9F58F68AD0DA46920F896241EFD7F98DA1D10ED22BCBEB6A273CD7B29BF273F8B6895C05A622687B2BE13B3CEBDF6175CE25607CB83E46924C5CB00BFDD6F73F2C5DE790A87DC10FD1C77CCD9C9630C57A1973AF48EE1D283964891859D64D3FFFF8EE500DC4744D8871F7C2A735AC4366DDE9F03690AB740566F611C78D3E238365A017020C3959AFD4E152588F5825F5D8DB0A840FF6C7BB1F7BB87BB7BD1BFACCC806975190166EACB26FD8C388D940591A68C489D32BBE4E607541D05A6381157D53AA2120216C971B94E2FCF834E8D37EFE65EC5F086F30C316C889DB23FFF9B152718897AE049E4A191A043ABE2BBAFA94CE73F1CE17DC47EADAF8C8882D40000E2AA0C703C04D5332F54A0BABB7641A1F4C3376345B5800D737EFF9D99BEB908EE59069F504B6B8625A2343F070E6DAF42BA24FB48B9795332CD5A9EB317FB7DFE4B2663A17F6270BF75F888BCEFB51844E711A1ADBB9A935543ED5BCF134C1F52E8CE1404F789D0BBAB14CD229F8267CD5F631B9BA284F6D633576B6BFEDF1394A5673CBEFF90F172B3256799FBC0239567DB1BDEBFE05ADB6C71E5B7E9DB4B9E0E1015E7CA4CBF706073341750000000000000000000000000000000000000000000000060D151D21292F34""") + ), + new SigGenTestCase( + TestUtils.hexDecode(""" +7377D2CE98A125D2293896EA97285838DF426EF6D3E06D3EDBBA7C6BF034FE0C3DA0A5CCB79ED5176DC24ABCE7EE76E7C1CD259CC05A4A784C8E7DE70FE1F4C1CDB96CBC97A40CAE2D0F29CBC084E65111808FC3BF9FAF728738346768C481B8DD506B9845F3A22B533A384D394FA268F6B8C863112AEB94D469DA66C7AEC36703035149C02D0B124CC89825A2A644D4A089010549DBA0885B82898B042094064D209988DA0432D2A80D8CA08922955013A79064222401202D9C144422B16892820D0B821180B66C62284EA2B40C08A35122C760DC20510CB77104446194006523B68058820449064199920D18170C02106E12146D40024D5BC40113056AA310284AC0302180292226455A384E8C040A08980812436ED838491318295A90651B094909B7248CB04909B28C18C34D044989420645A2922191A42019409198246C1B877103B40102048201B14801212D14130C1A204D0B176CCB046A03485112316E0B4572E2325013192C8AA640D98064022001C9320209100E134849429030A114120392445CC84CE24212C00844E0B62918A00514200241080E04456858B0101C1930113320111280028689D84684121168A3A0211009718BA42C0BA1450C279214972D01354E0B230C88C0418320492047660A908889064EC2B8449B206911B20413C32C40322E53162011096611072CE2420CE0106D1947720285254B264E58A4815848861B068E12126453865013338D8298500892285120111019708024214234080C1306CBB46CD808000CB3659042124C82612219296102411A94410980490A2580431450DAA684403249C18008A1067101C38514102EE1B60C99244459006863201104134A0B4104242352929845941872892249D038494C8490200164DCC864D43440A428060BC009E482104C82411BA088192649C4B64822208911986CC9C240A03442D340710492708200651A032C0CC4118CB42CC032051938280AA30D63A04D24C03012864DA4088559380659B868013852C8C4044C900C4A026582283101A7091402449AB8691C85701C414113148E0B4084A012120BC88559C82C22876912A10122950D64B06150120A23344DA1A64151C28408C20DC3825120A96420B325E0829118C94423924C03256EA28444A0000C0A4712A226621B43311C17464BA6458A340E228830C3368518106E09038E01322C01866010C4100AC4204C2282C8C07120B848D1200200426C081200E4A8040C444063A4718A304CC8B421E406521C92509B4889842082CC406108155020B171C2184A4A246C218421A3B004D2B608A1880D63B02C02B4455AC881143606C8C410DA86615B3466203131D9240D20B530021206E0264151040EDA048E4B2822A444319B008ADA822023086D1090888AB411CAC44C980282A016002128928C44325C262159182D101571CB406840C22DCB10669B30024AC00023B84C138724A4B030241764E1120604961161068084000104840D204461C8A610A00469A20285CC14880886481002620895240840401B421120A328D30401E4381051901091948459C8299B40895498681C3712C4A0905A180D04312003B5800BA6699B28244486509B3242930680E04251E2320A99420DD4A248CC929004B9310C366C09185200238600B14C24B7014A887108A1511B850023A328C846529C40848A8045D4C6715344290AC8650B22304C28268B462922008D8844691B230110C0480B492064148024223104466E21448A09430A22056601896989228C24866D23337062288E5082708CC031130341C1022D23007188247141102E09A684133266024661C9B491C0B08403B90CD0821012312249B00C11356A83A6444BB64562A84199444C63A645DAB42DC38601609680441206DAB840233170C338925B1271C8A660A04402A026068A305283A0458A14825B268C43445222272510332E8CC6414BB025521025A0142940486522982811194E14267102336420A80043124C6128241B3952E2C8459C086C90B6050B3452C1C06024210921A06053C68013360202802C80486808A54160488E1B2784518420834244C8C88C443690CB04860A42269CA62D9132101AA9515A320800A5845A8831A2B8641434605A146414152C00C90C02B510D3A229021728E40826E482014B280690B6851B428D10C225D38409C8B029E110882024200C280512454DA807B179BE146E96EC60914E74B78099DC2BB667ED709C1DC39DAE07760FAE0FBB086016F3BE0FD574560A68A9DCAC7A44629362330AE6293A88276F4B82BEAA2A42482D9C708EC75E60DC52DE3B70EF0F8EBAA0F591197273AF0DEAD7CA2BE5F6B7F67C99AAE59A016938F035DAF644ED94B5E9B64E153EB0DC49EFEC8F61BDFCE44B28532FAE0FAA09F430F4DCBDF34CAB952FD7E7C61C8FF1C36D9CB8330B556BAC79C4286331D7BC0023B643325C4E23B6E544D62F8D1E3B8B5F1241BE69A9AAC2F124DEBBDA3127093F4EA42E9DF7C7BA388E44197FB95FA17DCD6E6562D22C933C32A73F0D3FB9081DE04E513C9047F4DBB0F1A085CCBDF80BC0B6BCB652C302400F2D4C0C67B3698C23FC888D4BF06CCACFC202830D84ECD416189D0107B2F27B173D7541335004AAE5DFFC0DC60854298B1FD961D96BB8672A679E0D360150BA1E510B7151A440AD4BCE9A997B5D330DF5EEB6449264BDD4AEE6A86B8B00E0173838F2A645C9D8C4673908F6DBFD634034D840B378B185B21C92BBDCCCA0804ED6286FBC375473C46AEC46415B468CAEB97797FD03C374E422461F0807AA53D4C6CAE6FB5AF4C5EA616D295C5DC7D6886E5816FE47313A90BE1A7B8D528B96B351F1F0379F7F4301D7C669C0D27813EFA58827C26F04A09B4D9FF4B6007FF8BCCD3CB91E7CED0CBC1D0CDAC5F9205E6C9F3A1CD17FDF88CBD0C2554D162BD6BAC9AF0390A80745C6221B1CCAC44C6FD5F68DE32A9613AC4D4F77640A04141CA967061228F4E2D7C514C9FFA349004C0251E631C10B45BE25F148D37B05E14C3DF976B20EA5C26925818058584DF8428A8ADBA8377F74658834B3A72B938DC6C9FF8F923B22E99990730CA9723F531A5BAE5D619725CDEBA78FEF75ACB0C9D3BCD9C5BAAD600282F4145BF3E3BEB2A1BA7AE035659CB10F70D11D7F0A5DF5671466CF6554766C024AF1B9914F87BD74719DEB89014A9FD6247D089063D1578471B5BEDA5907825CD0A024716C21B186F3147F3C1309968782D8AF9CF40024BFC067111A68E27FF2E93D640657F422FC45537D9EFD2383B770E3702E2DCE1BE4530D17E4FC4C3755D47963B6E0184D277ADAB8037117DED146924DB13A05ACA3D7694CEDF95A0603F7B833ABAF05EEFBFC2585FD1E332070F63B486D93FA9D5457A09D9D27F84E80D49DB6548326D5F82A56B259271AD9EA4E90875D38718B2EC45E97F556FBB48FFDEAE2FA95A2A8FE1979DD2F48047685A3362C5F08B4C119305364293A498B4871CB7F5DB4E6B62E909960FC7495AA997EE6B885D5DD0BDAFC89BE1B4FFFE06789F6AA25497BF225B9AEB737F3C21BE2C7FDAF84F495E8EDABECCCDE3B0D60AB7E5958AAF5D0C5C062ED8775DBFC07E7A54EF47C8CEB59004FA347F1799481607497CB029C0A3981E564D4290C61BDE180CFC82F5ED40F6C89AB93635AAD175D488C1BF1C9A787DD3586EE49C028D65BFF792842D76F20E643E4E14312B1A52958DCCA1D9F7E0AEECAAA07B8BE1612AB2D5076A7F079F3872D8CDB5B128835436D14323732FA806B82014022F68E04862315FE6F16EE9254789DB98420BBA3F0DCC51159CFB7EA79E248CA2D21879E262DDBDE7F9C10757164A7096F5343AFA7ED777B8E2F0D13DD0A03ECA6F064EBB01E2FF84DA3542E1DCF62E7F911CE8CF632DEC6E376690C5D05CDDB42F7B0ABB6101D164D2A7CE931A12BCAF8E6BFB3D80E6E4CFD5ACAB85D4807054C406B7A93FA29F3589D5693CA4294834542884BB92BC1C88BC27AEEDD69E3D836130DD467F5CDD6CB82C2529B1E82837864188F6BEA25ECD031A55CF035A9F8523C30D30F93D2AB7BBC53E3E632B8F432BCA0D45F85FCD007CDAD638749DD09F7EC85C8C6B6FC7A4A3D87347515C73F64900C9B788B9E27C73469823C9FB6DAA6760D95626E74F18EDE6CF3E5888AFBE5D4CE686DF584AE67B5C300E8352288BFD55E5B8337A4CCB872BB999E86AAC9EFBC559437B10DC290D9A745692795D178B9134592232A696C5F0FDD653CD10EDABDEDDB746082AE54A800B43235DFD791BF7AA582155794D67204F87D9CCC52E51DF8ABFD24A4769C423C70B256C2E150844659F68E974B277840E98A6879333966F79B7A41ACEB1110E7E8B9DEB3D09C18285BE31A833AF62923E81B2499AC91F6273916B8E067892FC407074D2A99F287E78212194CB3862AC1F48D4B520B592D3BAB72D0101FE8FAF11564C88DDE8856FDA56AEBEFEA67B7F0BC4836190A8E6433F3698C0837F049F04AFFA2313FCCA95D22744C2C6FE08FD296E884E4D8BF1C05C0A7792F077900647B7D496CE3E2FC2690F2EB4402E853DE1BC21BBED13BC4930F1F3672702D9E676EFCFC6DBE120C398D6B335CB7F0C2483E1334FF4D526D59E5DB66E2B6BD865CAFD3A7EAE254536B07B67F7D883B92E0A0F59FB17F1B116626479117418F09F2C158EFE88F082A89957F1A4A625474C970B0C7BDB0AE0552BECE8485640C4BBDBE3E57D23F8D2419D8D5FE63CEFA90B239F611A13D2768212AD616025F3989FECB6834F3644ED914D75F08B3DFBFE497731FAEC81F84136A312BD91EC337E82524FC5E00EDDC07F59823320FF38DB34224BCC5502FD7BD572ADCB0EF53E4C16A35F37AB8B90E908016A649588AD1917FD5FB489C105CD2E59470EED23C90C7D9370F6406BF7EBDE494A658CFA1B93515C9894085DEAD882195E381BDE00DE045D1E1D4378D0DD80076C647C12DFE6441768CA16424331A8E8694C8442280BBD5CB6C1B6D504AE2DA853D089F56100E2ACC709A43FADF2FF110DDE85D2AD3F9F74854931CFD1A45CC769A444CEE253817D66AC7D8D2E0088A63D86608DBE29D1147AE85BB7F8EC87564D70FB2BFE0EB6D130EAECE850E9E030E1714D9E9A5BBA7EEC0FDF5BC660813B7893342B3959D137253F43EFDC6214D20B3C3C905A4813522091FD9D35D41193ED8E8478AAB5CC2650C19E4278EE10FC1F0EF3872C4CEC40DB39DB6384193E67E7E105A781BFAFCDFA8E88E1C85C5B893B8A442B4BEC0ED103F2F01C756B92A8ED8BC184632F9344C16EA3062457171CEC635DF6B1994CD1737C23CB37C32529B8A810DB30AF3376378F3F230BF58FDC564654ACF8AEB082E3C4DF005516D1522A7683F7A7092874861D46C44F605DA94DE8B004141B30152AFADFBE54744B0C1DEAF8F13221C050A9F4C967C1E5BA7BF78F579133C47767DDA12CFA827E76FE8E4CF31483E883ADD009639ED4EED93F4956D93449659C83EC23A7BD30AF8A55C8E6921A3B16959B3F1386A517A8C9416C838362E9AE08827F45BB10C1D222694AEF09B15D79140F8C0AEBCFD88394FB764371B67EF88E64C4140F34012179A394DCACD9E1CACE336BF723BE8FEA3D5E52E455E4F49F3900BED703ACBA38F27BFA3319445C4EC2EDDBF9DE7F9A1168CDC603C2C642764DDD0ACCD7809E98E4D36C838C2A57CDAA9444CAE82CE4DE5CED4377CEEE1922D10C96392262B4A57875A95FC4418A5953BE192580854EE92AF29E0949D4FDDD15AC811279E8E8EFC95183679117FE9C43A26AD455960A07FBA34FAB01386EA50072A0C5C026D1FBDA924525F3DFABAC3BCB69A7D2F800CA81872707D4EE0AF663768506C54A9A036D4D9C3FC3C20F8CC2203CA5F8DE285F70F4919A8044D39FCA06F484084F4F29471C2DFD3DF9E6D1E1AB2DE12287DCEA64E91EAA7C9C4CAA063710F4637983E66269D4C55CF24A1CCD1F02A08FD00EF4154DDDD104040CD15F588C93D030AFB06B35D7B06C3150E00FE3421DD24BCC0BEAEDB8185BB36D4E2F7A4493B98FE5613AB335475DE06B3E75766E9C662973A3BA91C0071606E4FD56EF9CF9E174BE2A42D8158207DCB81EEBDE31DACCC1EBC3BEFCEDF6316F929740C1F54C9C95E1E890D0A12CA2EDD0F265B5C3381DC8B1C2E719A4382862481E9D990F70ACAB53DC63BD502D9C99473CA00C452A604C137921E7BC050A776F03EDEDF95634FAD43D1DF4A239F047595EF220882097B282BBDEBD72AE26AB6DB46930E9ED585943A7CFD3597B134EBD74EA45BED2E3E06601DF441D7C2C9032E182B15E6B82276D4A450146B533BDCC662C9EB3D78EF75CE870272C0271C949DDE533FFA6CB4B9C70224FD877054B500D2D6192126F4659D11DFF75F624CF2304C92CFDCC1FBF02D57BEF75C69AD9502E387AB0F3C8A225D8486BDDF480C5B10F9442BD52A0DA149E1AD34185767A663A721218C7D06AF3E6AE29F5DA9BDB16E70856C3341DC58B8AB7CC133CFCACE0798123CE6C4735477CCD8E10499A0BC2D992E084A5E438605FE967DA5A24D0F66F769F78E2B321282717FFFECE8347B3AA78FCDD633E53B6709C2025C89A6DA9538AA643B833718A85477817AD8AF7B5986034CDAE1A4816C7449C11A628577AF65AD999EB00D08AC57053ADF533B2563001D08B001A65D46970E00DF0F83B692FB8683FBD62211B706E53C4AA30DB159D14235D0AC88FE1FC4FC994277A3838CDD84A0A08061F85CC1575831E7B56B87FFEB5E404E64B72C36966323F98E8A19202FA7F3C187E925DA291FE4C3E34A06C0C5CEB76BB7F8CCC0436A0001DB12B261BD47675C2490C914401694FDC04118372678AD2AE171F40B51C6CB4D40C849320F58B877CB72B222F2E4562AFC4C2FF91267F81BCF6D31DB8BF838F6EC3A3C45"""), + TestUtils.hexDecode(""" +4F4C7E0134BE5200C4512299D134770A64A76B73A82463FD8C86594939DCFD9DC55B895B32A2E96B8AFDB8CA83AB857679C372CD88754CD8A7B0A31D2ADDFD7D1BA64556AAF1CDD674F3E8F5FC0BAD2FA38326365918430AB2344CFF785D5F73F2B5D631DB29FAA0F9CCE5CB7FFE0CF4AF1C7A8950EF32F1D72080A492C7A25ABF67F409FF5D4B1E0D77268C0A1B2A32D9DEC61BB71EDAE6BFD58F274707182058F0E6AA31E6D3763732A82BD6F2C76647C7ACAAE7FB4AA51125F0D2D48351B6A3FC7FD18172FA8689AE1602C4EC0CAFA863AA98BDBB1CD8C2681C2B6C5C254E346C18E2A270CAF2606A6504D30C0E2E505C2FF9D18523BBDF21424C645AF0EFB2EA0FD21B5D0CD85C7C1EE176FCF904B481855C4CD739443F3340AE48276E7F4BDC00CD11C2B0D6B97BD00AC962EE1FCF8A73D3DA3CCBB3B72095CB33C5542D86E843641CC98E27545F99188AF064D5FE74739C54F5678F411D96A0EA043652935BFB2E37EC934327C7C841CB0CD04EC17FD06A18E88882177B51B00DB6EF1DA164245A3F2554CEDE8C84DD777F0B92CDA456D922D8B7B8B63B548CBB72CFACA540C0D69F9EF21759F243CFA03EBD6B080D23DD62945E623BC4F8323DAEC1215B251C35EA13A0F081B86E803BF37DAE6D913B7D942BD1C276ABEA3F8F74D0C8727EC21EED2AFD438BB7"""), + TestUtils.hexDecode(""" +EC857FE47C6764CF4EBC33AFB24BCB47BD927916A484087D8C0770EB6B0E09427AFC3C3D41F83FAC1FDD609BFEB217C6DA6F54792F0B7C7BD05251CB34001A4B77F1DA65BEBF1C8CC8778C0DD44E8EE655279A96860E333F8EAFA468F3B2C3CDABB00E4444EB8F6E11F4284B17979010335493869C1DAD4D88293C629900A5AF6EFCEE9D0A685D712139FB5CEEDFDF5212C4DD6436376DA5890165B11F47B45251FF9F83F5218B966C0A6CB2C3FBC25D50950D9552DF6AFDDDFB6FFF40CAAFDA74A3A6E697142CFB3F3327293B45528B3D46CE998A24DF46D9BAC9450E64D73FDA9A14307E7CEDCFF2874E65E8CCDCFE66E93A6D07BE6E27494EA75170C4028173C638D7CF1125D3F2FC66025A3B0FB83F80EFD11B483B7CFAF05B86AFA62C2E85C4DEF6049A11C4B76E9CB0E9A959669B8376359D21C26DE603C0CCA5F99BE34872B9279E50A1504C20FA0DEE99BF757F68C0759E1287618F86F157DDF2F8D532D19F77C42914FB6C3E88EED0E52A939BDF22D548937C19185516B9358B4EB34E03D150B0B4AFB629E754BC5E4067284AE7133D0D5EFB3BE5DA06F567A2A4B1E91E8D1E7AF50B463E1ED8967131D6D1C33FEB94011E8ED1074D4EB2E4D30952FB76145541E5CB643750223F6952C196D51393B3184AB35F7E7B4929647721139F7D115A9F02745B46C22BC5C5ED151C7F764064C453179B221935EC48128026525EAF5287311AB4FB87824B772C093CC21DE77E660186B8D5A4493DCF0B4EA7A751187C9AC73953F22785371312FC4D12421A17EAE731FEFAE466BD923E08BF2196A820E94E1D0334B2B86994CACACE28256CFE1B1CC5E56102D16CDF512D5135668803AC9BC931B20162D17B1861C8D5A7584056E462815E9726AE29CE5BE9547FE2A698E366865949169F30430B8CA0D73037223B6D2D97F6552ED21A2FC0A9804A5B12F07AF98D44FBE3CF12927AD586AB80953B25D308E3863D5AC23A54AEA7A0EA0786198F6DDB4CACBC2EEF4987913FA6CFCC6AB0354EE7A226CA9F46FE5C8EFEF7B9D1B3718D27FA1227A47F213794116ACBF4F120175A189DFB83D786C2F89A7CACF23825DE573274F7A964B3A070D66D049C7245D7739611FDBDFFAC21373A1B52D9DD3068A814EC08599EECD46ED0C775AEF19513622DEE75DF2792D7F123A45025378912A35B303708D0B3426C65C69B24358ADDA1708989E2D1217EC7F7BE32C37449BE2D1B843C77555EADC7B29878B71D95C420A9A744CA247E3382DDA1996A4E749F7315942E47EB1383339A1C20A7943543531A9EF0309EA7114AB0B3DC4ED9EDA988D6E978092EB9938815A355087C63149ABF9FE4D1F1B2A37FE3404F7587246F42758BBC7F8B111136092C28400D45D28E50F685240019A30574ABDC1906CDEA07B29155A71700731904CB3B49A3DE0626003E6D903C22FE058F47D8CABF213BECE4C4371A0DBF0EE89C6C018EBD8C6D0C74B548931514AA46B6AFCEDFDC5BEC48A5333476CF48704DD3F8E031F62937214FCE74DB483740CEB6898426635C38C740939EEF69B4E009F8C3D208769AC3017C827BC2073911C3B1AF2BBCDF14334BC9265A38A494B033FB887E7FF7D1C3931C483CD8AB4E5B1374D03C325D7E266F6E9D9ACD06E341AE9E4C4F18E9CF15FFE0DAC5FBBF65F6ECACB4798BEA3AE6C4123B7BDFF4A9B34DBDAC333E3ECF74F892BB91BAADF533161764824970683AD1D513C98063779BBE2F1C80B90B29F9A333CF5FB391354F1838AD2650F3B8C3519A0CDF69E359D73379FC11022EB256FD1DB270EEBED9A0FC2E25F59DA828F8B0D0A756ADCF7F1BD3ACE22811062219CB9DD16FF101BC879B7B057D8C3A53E028469CE476B136B0CC929EFCAE217CC49C941F22953084C50C31F75B9F7E309CCA6AC26A33A66EE8F4FF4B3363D8748C89115D38CB895C653D07BB99677DC919BD6DB824A31FD90BB56BA5C62546E45360AB276729F070456CDF89B5F48B50AA534C8EE341CAE2CBE2A79689464C2CF7D65318C6AB8ACAB5FDA822F132F2B5637963174A628156E1D166654A11C77B3A428B41CC7C618E03C97EA13E8489E3BDEF8AF3EC98B74EB68474191E15019EC80649A04DE49136384EF7C0831E9B3F4582402D5F07F0D75C12B57220C7E762243996065366F5F6663A8621DDE3819A0BD52AB1E64A07FB0006B9FB458761C3255E88BF794141647E7A42A422328C87F6BCCA09B8CA3D435B5815491ECC58B874A264E61EA49BAF9D0F8C75CDF72A68B1DE29BFBC0EC715E2C4B9EAD89B30315D8C5D554ABF4D862CE78EC051D635D6771388B00E50AB1C1FD412FC592ECB7A7C0F36EDB8E9C3EBA02B3FB4784199D7C3984DC56B5B19847CFBF6A889BBD98F3105CE8A4039DAEAB3CE4784DE71E3AE19C2355C09982653A5A85C554F7B86A3839B7928B2E3433BE19C4C4C2B2A23D0BB99FF2297AFF64CA4983CA89F450D5E173F930733F63E83914D771022353D8DB88A28401F785ACB7D6BC3FD5293F600299E22871422C5DC47DEFD4D818AA741E64E8DAB7354CC927FA2A93397218823340CC695998B073DF31808C41A0DA96540B64C10C929FE54C62C99319F628CBF8004977BD13DBDDF029D2902C2DA2C0A0658D85D336CBED91B1A5813C63A5149BA4771E2EBEDFEAE4FBBEE78FADE02E8F1E03BCDDC1C07C6F9C402CEAC52A98FC6CB51D3EFF91F909DADCBC8E469E2E5585DA9914A93CF36838D737CEC90718BFD30CA4E0AD7EF7BB2C6C0A6E26D0C54E2A3C038177057B079B241CC886EA58E145496C932EEF5461D2D68FAA6FEF92BB8A0EB10544E81DE7C3C1FE3BDC25FD0F60DF0B21D55F005AC9F2D0C4E9D39FBF213359AC59FE2C6489149661688918CE6521BA46491296EABA965F6109D3E521B74556CE80ACE4F8A34B57D0FD6913BA3F1C68D56E41735F8D0EDF9E2C293659A73455829F1ACDA870E9F36051DC977C828946B3B89C640340051447B2F67CD5DC2A5AD3B298E655D49019B8A8AD0CE4BB3A3BA7DC10E8A619B12A394027E27060C9CB9C890206114A3F688C154703D468461A9D4A3FCDA140101035923B27498BAF3EE7F0D38A870E85839899052C48809C54D266830EDE8B5BA0F85C7BA5CC857DDC41D6013D51CB64B7F7F1258C9B70C9A2109DEE3416880253E05B4AB7191A4E4411154E84F623138D755CBD55F9CE28CB6560A4B9D8B2D391CB52FF989A147F48BB17587E1C382ACE220619E5DDE43EA51F711CDAAED45F9CC10EC1713DB50FB7DE410CD39F97A6779AFFC4A0B2C889A15C606382F431BDDA0186889DDD99FFC7EF6A871DE751BD0D3825F1290C0853C488675B4F29DB3EE7B6D14BBE454D8BCB005815725CE413F03DE990AD6F2AFAB259E70074CE4B7F9800FF680715F3FD20A605366B32CC7632C2E703F0084A1D821B7F760A324B3AD5E65D9098DACB039C75F9DB9F9A85820CDC9A779D3722E3C35480D8A7286E2D36FEE7E8A14D32F3C192C39E67ECD7693B3280266CA07A06A3BF118DC9EAE1A23F4034CD976B32D334365058AB3C8DF0BF69879C8FDF90FE33F61205ABB6A89369DF4C96476D77B6C79C370F853E4FA49C186C221411F7C504D5CECD66114649119C26FF8000433F4F7392CDC073D51B3D15210ED8BEB5A2EB60645F8A4FA228B971F347D94B9ACD102605968AB2F7ED6635B0A90A7AE75F3E526F86F6A062C77BE9B0391BFA87C219D258E5C3FD64D3CB360F96DEB05311DCAB0B5A0BD9AB1BD36E4F9C4AA62BDAADA7404B08FF4328FF5AA0D9651B676B23855845DF4712980E04262C6D7B6CA5B4F4941EC0F8DC4835355559FEC78D06E41EC597B47B74C1E5AD7C61A987B5A88D1ED4362B3C132967EC09182E4BE876BD86F1D5C3B1632A8F56E13125C0387454E66C6BA34412E509F1736FA4FC9694AC550979AB064389577038662628922316BD7F042B6A69B516F46A56C28C2139A3506AB7B4283BC8A383748C9BC24504993C2B2B42A83C362CFC1798B342A9510BF37654FFC41A2DD3B14AE1F23F349CF7F920A07923AAF8E106A83929A85200E2CCF4BF4D78418A37DE65A5B4F9D270DD3213910E765F8C8FC567B2BA1062153F9DFA639779418EB343924567B0E42D85015BF2F3379027973C080107285650AF8CAEF9B892E607DD3321914EEE134B3DF7282ED9EC79FCAB130A15357A2B858FA77108D9B086263A08B482DCC375F0C4CFC5084D3F1181FD4F64C04B3B8088E9E4D18FB75B376890798DE7BB1E85132A7D92E2E0EACDC92EA04B847FD07B9DB141F0CD1C823C39EB20C0C8F53724DD314305A2849044EFC32F0F0535DB38219C98FD8BBE0A8CD897FE00DC500D9F44288468B03C8E0301E2555E863128FF3F9649F03275EF56204EDAD48B20E05558EA52A2813E998E9BCDBA3426E53D2A3B3C047F42FEE803C5561392887C3FA2449444D6CDFE4A89A9396F7F6BE56747961C021CDED77CDA3230D30CFF132A8A6FF524FF7E1E6335D6C97D5769FD62B1BE97675770286712A4B72D8FD3B3674EB8E71491D70508F9B9A1624C8A4F9EDE2EE27CD3205E6890FF8314D840CD3C270DAB6A4CCF896A7C3195E766F96E67381AF09D303A22C62CB1D6C66DD51028508971E2916DBA5DADF4DDF6AED606B16A34DFFFD8BD79072281351AE4C55A9136683A9B78A240254CF3AE877A9061CD17B33487944BEB504D03DC2F0FA8CDD563E45E4FBBE5DA3AD9B9D5E27A8962915B40997FD64F1A10EAB864DE75F67E948B116384DCC14CC27D8964AE7E8D70BB9B8928883E435E34B923BE01F35140CF7EC5D1CBCD0B8FADF0399453F4C048B9D4009A82B8864359B9A5BB53B98934656DD05CC8B677B87740A84D3DE64C49D802E81F5AE95321DC249A466D87CC6F64C2DCB666B4437A75C42D68E1DB5CCCEB1CCE9C68A6E1F47F920CC7299DE922A18D95CC894823B38A900CFC2AE9F23AFAE8675F89D590B0E9BB69C8BE83B9F9EBEF273D0A7EA30690F66CAA88DAF29CDA9BFD3C88A11B02763602F978500BC2DFA0898D83898C09D4FDBFF5928D2DFE9CF6E058BCC1DD30508E58ED1ED170090E523C9413734AD74CE5CAC2732E012FFA6ABF04C6B689CF70F10C04938CAEF9946973F36B3AC4EAF643FA5922BBBCF32C6B648488207D7E7E236351BA4085EDCCC8C6F3BAF37C2B532A5DFE4AF3F65F65E321AB14E3F7F75B6F2930F47BC93FA683842F45B7AE9B432E9D160F67B45413DC31C319ADCB4E075954C7E5C353AB7DB1E422F123C97B83EE25F8A8A66A8F1880819365A8E53BD398D8C73A5EDC546B84780E0BB633C082AE93B0B03ED6C8CC900FDBCF386062516103F618CD8EDDE18F8885ADC860405234121CAF7AA1F9C31AE56B8BE807D8A51C67DA0370FF637D085CE08BE04834FDD95525164A1741117A6F15795D70585BC8355636448504A5DF0576D94FD542F8103D418E99413873D52D11EBD6E46B23CAACBA7898FDA32B33D0CF8B7A4A25611834F309B1AF06DE37B3993CC77EA755466AC4535C5970DAC912D0F8DF0DB18FFC17F8B9882F1DD7E01583B85662C8003E0F694AD2FC72732490A090D25F5933AE71185ACA1260F4719880BB46F1E22F56661BB341AD226814C73FAAAEA6E054D01A5E0A66B525DA998C8CEB1D90125B54D5599BF4714F5D6CAB9D7D205D90D1D0A1CEF7D241CC987F6F9767E73DBE3D734393DA178C72B1F24DC9C2F1E5ADCF10EB893AF6ABF157477A88DA0853E01B7F7D34DD77F429E76814C4974B8D8C2BA4CD8977FDD1156C5CAD5C75FA438876AC8C4BDD8E44843BED62F649E7C993096D26A77B067B4505B9FF6336E30D2B36D1B0C7FA8202F1FB584E47F8C02D5663AAE87575287C5896E3E6EFD143F7E0DEFEE4389EC579EBC9C8D75BDE56B2F7AC703AC85E97EBC6C08B55A29BA3A06C8165FB2D03889E300E39364BC4CD856D67291524C81E884B5153A45D7B53C66751E863594D40CC00A9B23B9B22E40AEAC1D9F12F4D4EC0A73A1456506AEFC318F8AEBBAFA5F8467209F03AFAEF0571863F7735C858776CA4016370AC39794B42509668791F614ABED4F3B31FD92E52E5790E0EBB47344D62E4254935EC21FD3443B62C6CF46FA9E82CDC3A2B58958FEB91AF1E26537BF98734112E2F8C70A4CDB3AF63F60F746339915AAA60CA846C4E2DA28B43018BA24D9A34D348335A4261CBA82A7C390F86B51FA5478E1053A5D7EDC07F2322AC52E0BCAF24FC665928979A9E51079F71A61144A8F13B7F979303271397998B349F1AD62B53EC90D0DED31B429A9448ACE6672AC28A74FF45CD596CE60D64AC247467AEB4E54C6C9A46719DD4D98D37642BF87AF933EE2D0492115392AA79373948D7D4E3BBF67C46E52B1CAB534FCD662F40C0B1F8EE5465FA0C40D6D49DC0DE315BD972B3EB87CF6BB182D507C8F97FA061BA7AE4FC2E5484C5D769AB5BFED418B95AFC1D2D5EC1B243D40586974A1CBE403092438565E8E90AFC4F0F30C474C507BC9CCFE000000000000000000000000000000070B0E161E28343C""") + ) + }; + + // Only three are expected to pass, so I repeat to get 10. + static SigVerTestCase[] SigVerTestCases87 = new SigVerTestCase[] { + new SigVerTestCase( + TestUtils.hexDecode(""" +59B2371FE7BACC207FE1FEE88A8B3805A7052865691789BB90542FA47F7EF2B75FCA13DBA5888BEC320514DCB05FD26EB5541F6E572ECEA6C4F1D38AA70259094AA945F19FED0D980E65DBF65DB80F564FE29D836C5479288B55CF07F4E00159B6955DABDECC8C4D66AE688728BA6D5C0442F3C1232C782C465B9B7C5014B1464065CCD8A56D6B1C16510869E014E6933998EF725520B400913D93B0EC75E2FB725DC1AEC0C0CC7343B9E544BAA4D679860E347B2E947D8D2436F09298A7BB8336B9DE9CFD5CDBCD91C7249268CA03EFAC273AF52968D501406CD9C96159D7C15AA2900330C1189CFC2CD8B912C480E458297EF14DB694A3F1E72C1DFA3A3D2A8A69E011602B93020BACD1C2F3AD06C95A7F36EBF5261F6EC106816BB3303CC00BF4E8688D2E8548F10490D9EB23C56793B34B8406CBE443D8356BCD0F4F61D0D017D54831B9BA329F8948F25C3122F9DEDE8CECBA51569EDFFF895FA020862C5DF79F864078486B5FB228FD789C35FDE1C54BFFBF4A025A7FE7D8C3490A5D4E62D04F79F4183CA68379F4648BD5B2416DBE5B845C9F4B7A7E2339C0506D58539EAEA9451C9B2FE2A18C849DCA7EED9DACC058D005FB7375C4EF45B001543FC68E47DDB6D14FF937D1AA0D4D7489DFFA6210679CCCECF9B8551DCF682D2AF1E5BD869F3E8D400D5C861AE51FE7EBBB5457F2EAAFD093A9598EC721C69327C51930F4B9FFB2AA7F1A28436B6D808D75392BC43C1B5B859C66C54FA515C7A615A69E60921434AA9CF9F9E03C3CA35B5EBC6A409E822FE76E0924C6C062F1724C382FF3C8ACB5C1666C2EC26B7628E3D7C13DA8D758890E6CC017B7892582E95EDD04BA9345DF70FAD56EA68BF8875B932C28B32807C86371E17DCC04725CB597B524467963E1D4A61B5FBF9EC504D5DDB61793DD4E34AE082A5990EFCE801E938CCAE738E02E90599D971C2D7C64E5B6F8639F758ED621C1F21073C03EDB782C7A0F5D7C66F5CE161DED55B3E92DC27183AB083DBC1F3930AE56EDB8C53E9A7E020FFF0C4042F518B26F390C96C8183B79B53C7C7BC515187B3DE8CAB08769C5DD6FF5492112E8B0F28D09F4067ADB04194F60250E75ADE331A5C25593BCD92A6D1350439585860BB6FEEDBD2F839F317A01358876C88E898AC0C85378F572F23CDE931D47DE71D3353DAB1F810A61B18D24CD83DDAB8D53BA9C7B8274B0FE82AFF30C57072F643787CA1DF03B99EB57DBDA8C8EE8EB201F2847CBC9D34FD80CE6BC5E1E328EB6EFC83C4BD9D52F324E30EE4B5E86351E5C8C4C5456836D5A452203B3C372C787AE3332C8A5E9DC2197D9C341B9756BB1E63C75BBD5CF3E5CD4BF47BD1FEBC3E3710912D63032F6B97DC19C4DE196ACD9157715E2C14E054A9317BF96A684BB96CEFB7D8FDCA8AA477A2AF6F726D2CAC1A603CF1360EC11CA897E5BC735AB69B8647F30CED4947BA9F635D9CB2D82A662FF17A0E12D4D06D641EE76EB8B45C71EDE38C905C52BE76C6109F2612FEE6C3194465C19BA5D3EBCF1F0B5E534E0F0F1D31CB1E7A36C4303F283DBA8591CC609311A809E444E33A893880CDBAE29119146A368E4D2EDD91FE471647FFE821AA6D31C9FA49695EB9941B08F7BE3F06CDDF2739B8CAD2AB0DA4F5A3C0A26DF6A17B137CAAB3B919AB636D6C89BEDA3058898628721F2770315FEEE881595E24CF48B441660D0B2E9D5B90928C381F2B0FA26342E4C9B88C0887A4687124C012D969E1AFD8532754BA12125E9433DCF6D7BC1A36A83E6A10BA1CB7652A81350899C2DFC6E4FED38D009E6D0F1D44CCCB95E551B3AD54B3AC81E8BA4665EA428B3C861E8677890CF5F625C19A7C5943A9401CB78E7026BAE92B60A8B6807C17745415CD8E030C64C56E822139A35DA423F264336E0AFDF167430DD36E0064B2F6E8D8BB6BE99C5A9FB551CC63E508DB636667DDA53F611F02FCD1F99410F1A7A82882F9623ADDC50EB01E1F39978BF68506C71DBBEE42E4A80069B0E4C7FC4CC1471F4F1028DB25C4687B60DF4255DEC9148197A74796EC760A66AFC7884038651920973A69C203516222632EC5875EA6D838096E7FE9B5B4FB69C5E9407E70D27FA34B0CDBD6E119D87CE38581DF1D3E0DF3AE029042A3B20E923EBCE19A4958755EE2F98FD234C4413E2DBC93559A428DC37F2D1235BD4419B099E0F0DE542C46935991BE0692A6D80B8FD9886E0FA1769B49E8AE6307CB0BC1B49732D26E25CA1CD9D407E0D8864040941611F9333B6367E8300FD646AC5A71AD913EEFD808D5CAFBF1521A3062EC184E52165501E005556DE4DEE46F9E53D7DEF9909F3D5D98CA80D87707F7BC0FF8D879D65D4D783D196F2460693811CDF33358E082D81F4DB8F6C20486183A36D4FBCC8A1C6DA21AA4DD136E19FEF2EA993972BB9989AC1C38A79F31852178004123C46277D38A88FC1589F257332284CD8A873C25A1A6D40265B285DF09370E88F72FF70E434E8F66084CCFEBDBBC4B99EDFBC750CC5DEA63617F647F5F021D57D64D5EFF048634DB2209D7C8B82FB63B8823E4CA057168BAE88D9715291240B3758D7684501F861867B7A241C063B05D5E8CA6B4C79CB2435D7F994CB76915B4A548708B11B29449685941D43E60A8976F9A96072F91041F4C3DF7C73969012AE1B30E4B9C4E133558DABC46C103C0CB1DFB99B585374A54F9BA56B7248B8C3F66F1D55760D6ABB430375774DFBA2059C5DDDB659FD2E1DA9C3F0B80868C92BCAC10403DCD140D6A3D3F35F8EF1A2DD98DE1A4334238599EDAD920DC0AA698E9FE6106A0780C9C245F2C65A0C3E5CD5366110B1760FCD414D450DB9D76A22A9EAEA0C9FB72ED543CE9FA3314BAB17687E9DE5ADAD7561F1A5BEC16339269A87E09ACB29E4C439605E9572AA9B7D0E8371A30E41A0A7BDC02DA3A6121BF261EAA016A2074E4432CF63AF96BE81CEB6E0C2676A8545C66D2F30C98B5424F0FEF04B3C6C7064E2D2E11CBE60F85723FFC0B770D6866FFA589E3F9B2ABF75104019AA69CB58895B474A0ADE2B60A4AB077C3A6DF615334EBBE732E95220213994D3BDC443C8EF94AD515F45418355183314485857AC12BA1D62CF4FD4F4DE2A7FFF1ECF0D290C4CDFFA88D8F48C5B837D3A94CD17B3D169966EB038FE5A6E85DFC60A00233F10731973DC475D53BC7B9E60320BA7905D88519FA325DF5AB02B40F2ABBDB37D2261CB8148277B87AE3297976C80C35134E5F786904564C1469947F620FE09FDF3862C4057A3BCEF70750CB727F031283A1826F1381B3348E3EA4688609ECB193AFAAEE1CD97E4DDAA02C0C30E49F137D08285941528101759A7422AA499C900A379DD73B307284CCDDAF1FA1B0C4B280E3F9F1DB6D38ECF8A841F9D4E40ECA86247D6CD9B31EACD6A46F0E333B9E83D690D7E13467619B46AF9AFCFDC4AA9A049B180260D70D9EEDB8A533051AB83517AADC2CD900B3EA51260F464AFC5D2DC411029779B21CE2CBD160218DF41F661DA1AD95AD40B8C353C7F10FC23F830D117BCAEF8CECEBCBFA49D79D8D9391E8D08281F000A55E92DB331BDECD73183E058FF3FE5839AF50D8C55F22F6AFF5A33DA774BA1B3E643F5877CF549C4F908EA64A37DF3BFA4CD5F70F8CD154476D34BC853C9E8F7979E5F4EBB888AF761"""), + TestUtils.hexDecode(""" +4AC4675C96D9117D1EDEB80D7CD284A3E1E1FE038E301205B4C408EB965235AD1C85F8BE3F77CA486FD207F7C75F4121CD3CA2B23D6BCE4382A6D36121815025D5806CBEF452E083933C6E5C7394AC88262A6DE7770B2D8843EC101FFB5E84DE2F7A8B74E7674B3B2319BD6BF4112F92C5CFC0A55F7FA061F45325408D039D51"""), + TestUtils.hexDecode(""" +4B3F52F081B3D914BC7C6C073B182B268ADF5189E298A869BFB991B199993C1042DEF5B59270B6CD3FF8F907A1CB0D3B6FEDCA143838F8F81E0C370FFEEE6B25CD07035641A051944EAB516CFBB801536B4F262B16198E7DDB1D61C35A64D90D3948CEAAC8EE580DCEF540ED99D912BBA2BC4F5145BB949C73CCBD582613B10EAAE863ACA34683EB922B3DADFC74F76F47E4978602592402D9154394EB09FBC2EBCCC594732F2D8BC38350E5535A4412A77ADD7916604576FD6A3631E515BAF26A6F9CA4061EBBDD3BEC7179AD58552A5B508F31348A56AD1ADA7A05352C72C004B94C47E7049A10B3A59BF238A8DFC6C7019A17F05D5BFCB9D93D9D1CCBCB47F8C438098FDBDFE23F9F78BC28069908C6B9898B434CBF37787E1AF6A6B827E830E9F7629CD8F51070C4C8A8DEB260D07C3E41D8490484877491B39AA6D9E10D91748B64E33160629D8AE43EFD5F85781E69F76B6895C141EBCDDFEEB485A00BDBA4F7C991F53F2F84933926AF39E6964ABF2DFEBBC19A7E31C50797B8DA2931E10F3DAC493F198DFD785D21ADB2C062B097E889A20737F186008F2928F6B84D6E09E975A8F2AAADC785234234FDA03703A7C21F812D650BD2510B30F0550081047A155C848586A96F100D774F3E39E029B0777CD33E68318A11C1980293FAD3E787D20DFE7EEE7053C05EEB6A159BAAD4020B9EC3F537DA4DADAFB3B1BB1DBEB2D5B8F9D05A019798EAE0ED099DB066D73EE8E9A56DE368E878A7FF39140D8021D50085E6252941AB315309CB53AAA49E86347FBAD54A1F873E0CB4B86A8D5B1B2A95D485F37A9FB6105DF8440FDB8578F2624C079329569A75F36F2C55D8D030FBFEAA8889AD746C323B1AC4EC8C403E775A6FBE596E7E6A5A2863576625149940976F7CC93617B43FB13489074ECAC5BEB1A4DFE58B9AD2E0C6A15B76A7C2D208725A3123CA4E6F2C5847EE5FA8384919EF89011D219B257B3E4DC4F2095160844CAEEAFCF857260F1C63D3B05A67D3D0F2B0EC9DCC2723F13755750BAE62FCC361CFB584F774C09ADF9A0431B23E488C359C0AEF5B1C9787BD8F52B083BC9DBCC9B3039F777C7E8EABC80078050CE6D49C3BB70168FA2177298FB0A8F72C1CD28D662A07DAE6C7ACB7FB8E7FDD01DFB27C62EE683F4E5F88C7C1DDDD5EECC1C3AF853F1FF6B1D9DE672F1BF6473AF0021D8A3D4DD04A2FCA2325C721CF1C821676D0A0D574186625DE831C8411F64179F9167F78BCB22FB41C2CDB63C4DB5E138766D3803589598F114F41BA42CDB1341020449BA99656113990B4E022D8DA20D744491C6EEAB67B918E80FFF343CC5B4C8E58C3484B0125A60C36AEF763894D35148B578F417C3A98A143EDFE9F8C95BCC346C6F5EAF97AAD11DAE01C477C227A88D10ECFDCF450B37F881968027849D9B43E2BFF90C6A34AE41B8BBD743083D3C58786B036671CD6EED94DAE51F7613247EF8607ACF74A3CCE932F1C3869BDB35CA17FC6BA9F9C956FF1D4D88094325CABCE41233FB1D808EF41010396DEB0ECF50734D818DDAB70015A0ABDD1926DFA491F711AA85DA2A8EC60E3255CCF975C23CC4E8DAFDDED9FEC60A6467C45B03CA476499AA331B0E3999576CEC3191A9A62BC1BEAC1EAF20E18CFC3216127DE4AAE2E75201F9E427E39BF921150EAB949559C022D876FA242C2A845BCA7235F721B0056788A44ECC3EB98F0F502B89F8E7410EA5679AE7C0434F13AD816421D2FEE30CBCB2DAA6B851CD1B6E996DA7A757E4C4D8572C8B600DE85DDB65320D1CB71D9378349C0C401AD4F9E91272139228A8DA2F4FD2F48891A4DCB066D501D447483B611BB3C80550A90EA0B732D639D8B3926B6E7C35453ED3CC110BAF556CF46D8FC2177E76FB2663B8BDD171E94C0ACAF25B9153B22BCA749916756FB3ED3018E0944B6C3B9B6BFA15B9BE803AC79333CD2C3A27A26BC17CDA257798AE16B28B463B6DF3FA87C2D742D0F6885BEE0BEC6E20D01E5DADC86823E92D60FEC79B0D240248753E42048384C804289604821A57F4F9F50AE0C38527FE5A34938DDBCDCD9A1D020839BEBB62F9F41FBA08052ABB82FADA884CBE563791103AA585546EBFEB11272CC2E87A3B75B3C6BB1853AE7F9CF5585B2653CF5EEA244D204EB269C56A20985160659CB0725EE13CE35D55EB095A53414F232DF8108B18024EB0DBF345EB5CDAD0BCE7263509A341D54A7D534E553EAEFFE4E242EA23BCFE59A58A60425882CB7E3B0C9E4AFE8698E3DF56AFD6D611E9168747D8735CF9246D94F2126BE727FB42B2241A83B34F0B9EB47938D726502C54E4572766331628FA5CDA893C35376AB4538FF8717C2795B0F51F08E1137612B89B0C1E2CD1F099E88556923AE57A1DAD2AFB1230B5094A1B21BAD7DBBC333A97F179304718F3289B6DE31315B74C1A73AC7756FAA4D7EB568BBC6F7E788CD089B395564D2176B0056DFFE952C7748B048306720F602B67E8F6ADCC91F8E3AA4B8C4D7FAC233AAF93653AD2209E2FF92DA30C2D53FDEF6F4C90EAA0DE60D594ADA3915DB24279D867476EAD757B4C0264A1DB8A1F57A1B5D7173BB1A960CE02FDEFEF160D512667D655268FCC3A153A4314782A0EBFF84F65F14A0E3E12A13250C07D08C225B11A6831BC25C40467B768004DDE0E874A51144C18920BDF286090B59F51564EA4070FBBF61E3696435F28F63332B64496DF3EC8B65D54E1CF4789DDAB122DA6B264D312A711C129E3B07F4C6DA25A56173AF58B90A71B7ACFA3161A81F59D17914C99BBAC4F9A314977A89CEF7696943609BB4827964FB2976403BD4996F1E842BF5AAAE1ECCA11255B9E6001C20F72F1FD5E32CDA32D8A7AC5F62B09A0E615847CA746F489515CF8F183162859F53B97E9E5CA800EE624F729843A0009164A4A9FF76EB34E4704184848A139AD97D909F7A7ED114F087A4B2E1B4A3032391160B6F3A3649FF15AEA2B7107AF8A3B5FCAD61D43D602E6286A900870CC8CE24E39E78F0397A0D7E27E8E2D4776A44CBA218EBCD88B3C28C182A7C9F4DBB2DBB5E981563D66CEEB77E7F9034BD429D27637CF797DE82E01FEBBCE2171EFD016E402A42D78EA1ACE2CB370E75C90ADFA1A793B2169CC26522DB2F546AC1DE34C9087120C42A9F10C00D493C25730166F9D219FBDAD222C8B28115543313210848FB2F04BFDCE15D320C3634A8E4D63755515900C75BFD090AD78DD588659FBF97C96E0D0ACC8E815E608F9E861D79AF3051B942B52570B6292BF48C2BFAA9077DC76FE902683217B8BF809ED7A0050ADDBB65FDDFBD24019C9181B5AC81566113D6694EA6291D7F4A7F56A41EB91F76368DF82B164B4859259D7189240F1D8803F8107296D378BAB4D24FE6D10EF788367BCE16C5AB77FBC168B857F7BA5CDCBE5067C864F879809FE5217DEF0294BFAFDF809ABCE9532DD9DAB3448F4DA68ECA51609476278EB8C4F69EA29673F69418041D26857EBC24A487BB4B0BA63AF848545EE9BE89F139D502099B9D35DB3807B925CBA576E27170EAEC48CC2CC15B043677825D0EE81EB2CEE3A8ED14A798B879530220E50CE8C003A305382A24D23C277B99D1F4C54F9A8D33FA3D1E337E18D7CBBA5E5A47F2D5E096CF4551B23B1B86436E81B4A09D1E3D38492EC8B2A00967016AB76B9A9B1864671421DA56F57D008D5CE1B892A7E9C1F69F6C722CF109DB500E53F6BC07837AD1CD4CF4A64DA763B4A9C4929B0DCDDF7C7E1186BE3FF0C321158437820C81E74FF316AE3254E972FC197A7F0E620242AC05A4E43E987C2A8355B0357745CA79E6AE48AB29ED4FA63D3A1F19B999DE251FDE0640DD87876D55762878AD1DB12D65BAFD14B6A9A7081BF23F9F06D90CE273C5A26E012CA94DD481D32E10938C165163E89BE8A93A63034D345B74E2A94EF643D06AF9E1F5C9F104930DA00E61E061EE8C3BB17C11E05D45C1682E4D593C9198238D2BA289779E7D0F227BCB0B09972B19770FF011BF6C60D9D193CFAB32747A0095E1A4AD32514C782EF3DE7A26EA771F5530D9DE9736D0F6AE1AFB78EC7CE4884A1BB436CFCE459CD99358260906AAC99716A536CC7687A0375FDA11007618E553534E54D5B214F7AA6FC7DBE37C2BD2B64850AE469A9858987F3FA4B1FD26D954BFEC365DBE06DDCD615E1FED58A88676402D1D6B581485498B5ADFFFC42D47D61DF99384E22C5157F0178A6FDAF8F4A9491DAF298B2C3EC88085022C0A7CF245ED0FB5A38CD16F30D37DA5C4959A55501DAD50F1B48BBBDD86AB8BB522A936DDF0003B81BE16231A04E7A589C56FFFB51B07927B4AFA1DB7D48BC6FBC3F3675637184B7ADB9BADF4DE7C085BCA1D428DC9FC8277CBD85884A5921B52BB05B710615508261BB4546BD6E1FC730D16B049EA12798CE2E6DF43F5B8F3EF9AC8FBAE31B011E10C4FC62FFD7F39D16EC32CA8210ED16E041DA43D9274229514054A0F82D462FE080C6FFD7BBDBFBF0BFFC6D5ECC432A3256C0BE0DDFD5D9080C676C7955D66E44D1CE51FCC2382F868D732E85851721B48A01D08C639626EE0509CB581EFF5628FA6CCD1089AC0E12DEBE0851782E64C5049CBD6501013965CC0CA25ACAB176EF7CAB92940985DDB49021DF6C60D6C4A489116311E86BA19EDF00D74797358207CDE50506D007FE03C8804C66451F02A0182D387B759894096F65232952D183DBAAABB6BC0E191DC2C3F75FC72BD61BAB2EF19B6532B231C4AFB1A9C2CB2F3D6C451E8440D6A923CF72A63E2ED8554773887910CA5C671AD4FD5923CB95EC73FFDFBDA4B6655F55DBFD1317D024422301ED66A6E4C672085CED1F4C7B05030A100C4788FEF4CD3E494A853BDE63E9D449AE3BB6BA1083238DA3F4090515D143C67DBE53D8D507A5229FFEB2072D0BD092FC9AE52DEAAACD1F0F14B5AC84752BFD0025E5F55B869350F4B2719C5C05AC1669BB0FD3C614ACE02A270613FD3309706DDCD5B1A6AD26F359ADA80B30E50A7E50BBD3AA45D0654DD7D058B0BBF4D0D92135142214EE70511F3676AE643B5F245063B9419CF6B49FD647F27D7C41C866E6CAD9D5E2E3E331BF6B9F72ACA329BB64259C3E79783A26674B7D38EBDE8318411F4764EBDC4C7E41ACFF85BBB30318D59C42C9203ABD6636BA3F772B6725121C052DE99910D55158C6F3EF8BB7FEDE2F81E58A7AEB25E2E46FD7232302FAFA8FC37FC8B55D594B76EC4A53EB11EB3FD634428AAA5D86F839D089ABE2FEFE2AE5262FEFC7348D836692EDB215D6F8F548B885290C2403C51C3E269D493FBD339B5DFB0A38EEDA7754DAFFA16E5BCA5A9BBDE04B014B7AEA8988F3749D52D2FC1C9F7C7B2C2D692E7896E4C34F57C558CFE8317A8374409D566879A08628F644FB45B818455BCA6042B4E6187C1DD177E9E5146319904B1505F3EE00CD7FEAF0E83C3024956F77659ACC56D8D917A37E8FF7EB88713CCA334EA04B8E258C9345DA9DE26A0A366519451E1012DE6AABF4697C9DE821D70021C3250A106CF4C23A1B1785F549D3C8CD71B05FEA753E0046A3AE0A9B1F40277CF453A2BA14CBA923CC6269706DFFFD517C1E5930079912E05A5571897A06865516C86699F707E00CB38CE193490AEE30BA47DDDF3A5B4FBCEBA73DC13D0A160EA642D30D63A02964EDFDB2F29DCD32CA9974F89C32D1FA9A83C94A2770FCFCF86E64646882BD550DDD65B4E2D287AF6C196F42DBD39B020D7CDFBB6E6E75FFAAB26099EC1D25E3234F70DD972286AEA0C3436595FE49FCA898BFA421604C82D3E94856D186905076D186C684174BF4290DF31769EDC97A1DF2DFED03CF45CE678C8A1429EB978D02A79D4F8CF0168DAAB482C6C612F04B1C93637FE77B302CEFA788C11356C52C54F37A9DCFDA55927A8EF0A0CEA7CC4ADCEE459EB64DF08ED0FC29FDC3C7B762B399332063340D473966219BFC87B4A3C91C80F0E4BA86AA1879C76625C8680A227AB22780659D4B5D30E0E9A0DCE094DAF537679273A9B277ED2A2E250EEA0938204C9E963D338522A3D1A4440E2A12397A5B97D35657307BEC94CC0C72C5C6B09DAF2BAF0020B7D8CA560BF6596929AC8D4E5460F7837B41B4AE6FF12339DB8EBD7028AACFE0B42E02CDE906783ABFF694E7CBE0897ED6ED438ACDB00A4709CFEF7150EBEB08C8FF6C1543815F4B8951C3CACE499586458A73C8572389AFC9703A7FEAF673445FB4B0CCAA511D4A2CF463F57E3A6D72DA04B256699A30212E7C5768EFC151B71744156575A2E9443319232D159C6CC006FDB57C58173AD8D2C866C8887437C223888E21EF67E1A332C1FDFCC15EF17476FE0FB57D4229894725E1474C1BA1216562817F16C53ECE01C7F9E3664EEDBBA94952987431AA2A57D330EB11B28E6BF770E349ECE350C83E90DA6FE0D0A4AB9715DB28BDD397FAFA1428302151E1F222B4469879EB5D0F018606A7594BFC82C394E91B9264495C9063D505262799B9FCBE6316BBCC8D8093053636A74D4FA000000000000000000000000000000000000000000020F161B1F292E36""") + ), + new SigVerTestCase( + TestUtils.hexDecode(""" +59B2371FE7BACC207FE1FEE88A8B3805A7052865691789BB90542FA47F7EF2B75FCA13DBA5888BEC320514DCB05FD26EB5541F6E572ECEA6C4F1D38AA70259094AA945F19FED0D980E65DBF65DB80F564FE29D836C5479288B55CF07F4E00159B6955DABDECC8C4D66AE688728BA6D5C0442F3C1232C782C465B9B7C5014B1464065CCD8A56D6B1C16510869E014E6933998EF725520B400913D93B0EC75E2FB725DC1AEC0C0CC7343B9E544BAA4D679860E347B2E947D8D2436F09298A7BB8336B9DE9CFD5CDBCD91C7249268CA03EFAC273AF52968D501406CD9C96159D7C15AA2900330C1189CFC2CD8B912C480E458297EF14DB694A3F1E72C1DFA3A3D2A8A69E011602B93020BACD1C2F3AD06C95A7F36EBF5261F6EC106816BB3303CC00BF4E8688D2E8548F10490D9EB23C56793B34B8406CBE443D8356BCD0F4F61D0D017D54831B9BA329F8948F25C3122F9DEDE8CECBA51569EDFFF895FA020862C5DF79F864078486B5FB228FD789C35FDE1C54BFFBF4A025A7FE7D8C3490A5D4E62D04F79F4183CA68379F4648BD5B2416DBE5B845C9F4B7A7E2339C0506D58539EAEA9451C9B2FE2A18C849DCA7EED9DACC058D005FB7375C4EF45B001543FC68E47DDB6D14FF937D1AA0D4D7489DFFA6210679CCCECF9B8551DCF682D2AF1E5BD869F3E8D400D5C861AE51FE7EBBB5457F2EAAFD093A9598EC721C69327C51930F4B9FFB2AA7F1A28436B6D808D75392BC43C1B5B859C66C54FA515C7A615A69E60921434AA9CF9F9E03C3CA35B5EBC6A409E822FE76E0924C6C062F1724C382FF3C8ACB5C1666C2EC26B7628E3D7C13DA8D758890E6CC017B7892582E95EDD04BA9345DF70FAD56EA68BF8875B932C28B32807C86371E17DCC04725CB597B524467963E1D4A61B5FBF9EC504D5DDB61793DD4E34AE082A5990EFCE801E938CCAE738E02E90599D971C2D7C64E5B6F8639F758ED621C1F21073C03EDB782C7A0F5D7C66F5CE161DED55B3E92DC27183AB083DBC1F3930AE56EDB8C53E9A7E020FFF0C4042F518B26F390C96C8183B79B53C7C7BC515187B3DE8CAB08769C5DD6FF5492112E8B0F28D09F4067ADB04194F60250E75ADE331A5C25593BCD92A6D1350439585860BB6FEEDBD2F839F317A01358876C88E898AC0C85378F572F23CDE931D47DE71D3353DAB1F810A61B18D24CD83DDAB8D53BA9C7B8274B0FE82AFF30C57072F643787CA1DF03B99EB57DBDA8C8EE8EB201F2847CBC9D34FD80CE6BC5E1E328EB6EFC83C4BD9D52F324E30EE4B5E86351E5C8C4C5456836D5A452203B3C372C787AE3332C8A5E9DC2197D9C341B9756BB1E63C75BBD5CF3E5CD4BF47BD1FEBC3E3710912D63032F6B97DC19C4DE196ACD9157715E2C14E054A9317BF96A684BB96CEFB7D8FDCA8AA477A2AF6F726D2CAC1A603CF1360EC11CA897E5BC735AB69B8647F30CED4947BA9F635D9CB2D82A662FF17A0E12D4D06D641EE76EB8B45C71EDE38C905C52BE76C6109F2612FEE6C3194465C19BA5D3EBCF1F0B5E534E0F0F1D31CB1E7A36C4303F283DBA8591CC609311A809E444E33A893880CDBAE29119146A368E4D2EDD91FE471647FFE821AA6D31C9FA49695EB9941B08F7BE3F06CDDF2739B8CAD2AB0DA4F5A3C0A26DF6A17B137CAAB3B919AB636D6C89BEDA3058898628721F2770315FEEE881595E24CF48B441660D0B2E9D5B90928C381F2B0FA26342E4C9B88C0887A4687124C012D969E1AFD8532754BA12125E9433DCF6D7BC1A36A83E6A10BA1CB7652A81350899C2DFC6E4FED38D009E6D0F1D44CCCB95E551B3AD54B3AC81E8BA4665EA428B3C861E8677890CF5F625C19A7C5943A9401CB78E7026BAE92B60A8B6807C17745415CD8E030C64C56E822139A35DA423F264336E0AFDF167430DD36E0064B2F6E8D8BB6BE99C5A9FB551CC63E508DB636667DDA53F611F02FCD1F99410F1A7A82882F9623ADDC50EB01E1F39978BF68506C71DBBEE42E4A80069B0E4C7FC4CC1471F4F1028DB25C4687B60DF4255DEC9148197A74796EC760A66AFC7884038651920973A69C203516222632EC5875EA6D838096E7FE9B5B4FB69C5E9407E70D27FA34B0CDBD6E119D87CE38581DF1D3E0DF3AE029042A3B20E923EBCE19A4958755EE2F98FD234C4413E2DBC93559A428DC37F2D1235BD4419B099E0F0DE542C46935991BE0692A6D80B8FD9886E0FA1769B49E8AE6307CB0BC1B49732D26E25CA1CD9D407E0D8864040941611F9333B6367E8300FD646AC5A71AD913EEFD808D5CAFBF1521A3062EC184E52165501E005556DE4DEE46F9E53D7DEF9909F3D5D98CA80D87707F7BC0FF8D879D65D4D783D196F2460693811CDF33358E082D81F4DB8F6C20486183A36D4FBCC8A1C6DA21AA4DD136E19FEF2EA993972BB9989AC1C38A79F31852178004123C46277D38A88FC1589F257332284CD8A873C25A1A6D40265B285DF09370E88F72FF70E434E8F66084CCFEBDBBC4B99EDFBC750CC5DEA63617F647F5F021D57D64D5EFF048634DB2209D7C8B82FB63B8823E4CA057168BAE88D9715291240B3758D7684501F861867B7A241C063B05D5E8CA6B4C79CB2435D7F994CB76915B4A548708B11B29449685941D43E60A8976F9A96072F91041F4C3DF7C73969012AE1B30E4B9C4E133558DABC46C103C0CB1DFB99B585374A54F9BA56B7248B8C3F66F1D55760D6ABB430375774DFBA2059C5DDDB659FD2E1DA9C3F0B80868C92BCAC10403DCD140D6A3D3F35F8EF1A2DD98DE1A4334238599EDAD920DC0AA698E9FE6106A0780C9C245F2C65A0C3E5CD5366110B1760FCD414D450DB9D76A22A9EAEA0C9FB72ED543CE9FA3314BAB17687E9DE5ADAD7561F1A5BEC16339269A87E09ACB29E4C439605E9572AA9B7D0E8371A30E41A0A7BDC02DA3A6121BF261EAA016A2074E4432CF63AF96BE81CEB6E0C2676A8545C66D2F30C98B5424F0FEF04B3C6C7064E2D2E11CBE60F85723FFC0B770D6866FFA589E3F9B2ABF75104019AA69CB58895B474A0ADE2B60A4AB077C3A6DF615334EBBE732E95220213994D3BDC443C8EF94AD515F45418355183314485857AC12BA1D62CF4FD4F4DE2A7FFF1ECF0D290C4CDFFA88D8F48C5B837D3A94CD17B3D169966EB038FE5A6E85DFC60A00233F10731973DC475D53BC7B9E60320BA7905D88519FA325DF5AB02B40F2ABBDB37D2261CB8148277B87AE3297976C80C35134E5F786904564C1469947F620FE09FDF3862C4057A3BCEF70750CB727F031283A1826F1381B3348E3EA4688609ECB193AFAAEE1CD97E4DDAA02C0C30E49F137D08285941528101759A7422AA499C900A379DD73B307284CCDDAF1FA1B0C4B280E3F9F1DB6D38ECF8A841F9D4E40ECA86247D6CD9B31EACD6A46F0E333B9E83D690D7E13467619B46AF9AFCFDC4AA9A049B180260D70D9EEDB8A533051AB83517AADC2CD900B3EA51260F464AFC5D2DC411029779B21CE2CBD160218DF41F661DA1AD95AD40B8C353C7F10FC23F830D117BCAEF8CECEBCBFA49D79D8D9391E8D08281F000A55E92DB331BDECD73183E058FF3FE5839AF50D8C55F22F6AFF5A33DA774BA1B3E643F5877CF549C4F908EA64A37DF3BFA4CD5F70F8CD154476D34BC853C9E8F7979E5F4EBB888AF761"""), + TestUtils.hexDecode(""" +EA707F27A8896AA860FDF5D5897B58538D1CB6096CDF2AD5F583C5D4FCC2C91839C1AD44920216F8D027AAEE2E563D779E86FAC4B2502497B41229BE823ACF0BEB232CC6F3F7DA88E0685A9176DFE71E42470FCCCDB43C6688A03B6D8AF6612AB821CD16757FBEAE52C779EFB6AC38EF7FB4B5E365882CB83AA246B2A52D5059"""), + TestUtils.hexDecode(""" +372BF9FD2061BD26939A23C3DB128746EA3346F0C0E75C4C358405C12CAC9636D241A5E555ADF1B8C448152326F9248EBE31E8C171B3CE7C0079610C6C715BF8DA26F4344C0F043EAE26E749E56BAA190E502BCBE70740A8CDED41CF2FAB99AF00A6D788FF05C30CB8B9ACC125FEAC8C7CDFC1DD7226C819BE3A237BEE81FDA6B1DEBB83207B53BBD1E3FE07D3919AA9B3505F3DA78B7AF7A61979B9C8290563B7ADFB676D06C7AAF545452D3D7C9262AD40456D0333B362A68207D0273F488AA60F87543B4E4F4B0BFA36AAB42D523AC1D6691B680C673832888480CFF337B1590A8544A3663515198481B17D0839944754E14D565A8C32CA1D2BD4863EAEE16AC0BF8D52EFAA731CDB0A3A25D2583424F0F57E08E2018247B610F843B1ACBC54B3AE0E880B994254B4DADD9652EF5E36D3F1CCAE76DB8FF110CB3AEF24EA7B00E32278A05267C3A3319EB58E92172DC5C7EE748739C5E19AE54F7A8D714CA642958B820CF8C71F20E03730641CBCAD74E1956A1C50562E27F21FB03F44A3F032519E2E20577D4611764159405D7BB138F34126A4E5C8B3AC1A8F19817061BFE1C50A8A6767053677F1B507D70B56BAECB8BBE2F54DAACC13AD373020C13B103D2079B140ACD18D3824C03205C6198AC1603CE63602EE853B08395BC749B0DA7ACCA6DE54D1D742442C81ADA46C3A21F8F8B4A1E3C212315E6D19D290D139E70C037D4E64D3630996606E443414A371A96B19433B1DB4B5EE677113DE2005ABB42CC8DF12C33DC7791FC7AEE807E7946B023FE451ED32FF21ECA246AF26B535A11B4C6F380EF56DBFFF984ED15818EEB08578D045F2FCF39C3CB456C73EFB76C66AA09E6F9458AF39BC5A9E1E9D6E8826AD3ED681DE22E9AEE77FAACE34385376EFFA306098EDDF4F122106EEBDF32AC04884554BE6945753E6B831FAF701B4AEA4F48A8D490BDCF33B0E1630C94F756A1C565D2554F5081EE3B4EA5C33EAE04F06BD44CA0D0671708E9392EEB6C4EB80AE8A17911B27CAC8980A87A3ADD2F5E2FEC71FF711D89A6F96EA423411E81B292668F60AF44F0CC83BCF835E78F2F6BC503F54C2C6CE827D97023B98F23A85D269238013F29E9AE8BE2FB54C9AA69BB6FCCD96916918B8E534D3CDFE506A2AE474B59589CCC730A0A857BEE1F4CFAD0433BA4D34E8888FE2785A7B6331C1CE3F66E0DCC2F801C112DEE85EB869567C387305922B252073023259E1C042D3A245D141DFB0F2A1A5CE0FB772B12A0AD875DE56A8A0151891D4D4D2E2DD4E025D8BA25E63E44AD8798D495CD099B57CF73623A2FBEDBCAF1ECEE43AA0882E553F5058C50AD9C4FFCC59D93F51DA653DDDA17B14EF03D86EE7234A3808B54A1BAB7FE12154816735D62BF3ED4CA9C180D6BC050EA3937EBA6F8AEB4A7811A7307FC7A0BDB24360AA517A2333FE86CFD05E5924923AD390E6F0DC4E757AC78A754BC6B3C15954674F4AD41D05007BB984C89C198C4E4109683BFD1A1E59FD8CA36040090764B81A747ED14CED83ABE341473BCBA6B5629044DB6CCD65CF6DE91C91AC20875565440194FDB3D21CA637E019636B44F69D578C1E1CB12312FB109242C228B02A70FF001095801CC2D308A5E802C34B102F174C6C0A44D14A76B9D82D8B97C01205BDB22AEA9B2F0DE6507C0FADD1321BA71157C203DFF28207B5CD7AE18923DAB57AE263BD26A97210DAC238427857AFF7639195EC13CB74D511B40A5C5855E1EC1223B6B44C5B630AD94050B573FDF919FEA24AEAE8095AA8136D15294D876D1ACA1F862B038F35265BE879A0F1FCCE07FB76884DDE073E73785B46DC0EC95B7859594119D272CBDCEC3FFF7A1AF8B5076C977B76C7FD640B834B92066257EEF27ECA1699A7BE3ADD1746624C27256BFF5F9177C01147585D1D5CBF576F381DD6DF2320F24293F32BAD164E474CE9C741EF87302331AA9B67D64E95527C4BCFB601699D68F1F712222BF00262BF4AE8C49E098A8EADD108288EC0995D068315CE39C6429CCCB00E1D94477B76D866AD7B7968B5AA98A590782354EA512344FE58290DB10717E5C6102BC7EDC1CF85D634439D5D82C1B5A2A9928FE389BDBE4FE9AA859DCCDE68392AD6B35F516AEA70220B0D6DD2A91239EBC0D15B5930937207E0CC5AFD925A4B8BF5A0A4DB25BF87294CCD7E148684F331508A752386A0811B606B91283D865B58B347084CC01C874C046861ED3FD8DF8C5B07E8A2F27176685A39A9BCD955645F1EA58B4811DFBA16C98BA52BC0EA443D592756B00CC4CA428511A7F8051E94C5C273CC6E8652F3E9132E0ABB003C31DC61A8802D2CA650EC0B5AF5BC3E983C2746F4747AEB1F6624F010C5104F7A577E58D5D527CA58BC838C60049C99270A66C846258D32A5A5E4245088E7C6F824671AC80571DEFB07A21B64A688100F0BCC7F28B985DD9B0A1F6780B561BAA8616909555E6BF656F1E02691EF83E475E90FCE338195A88FC1DF0864B5375496B5D8FCEED265163ED2EDA2CE6CAEF6583800F225084662591706E1F8AACE331689219268A591379219CEAEF219A02CA85AFED70C96CDC7B50905EB6C2BD0E1B09DB19CC8728EB108123228628212EC1A591148DEDCEB7F4938F0A99B727B79F230BFB96B82E03AD90B6EF858CB899AA2549E0FB1E8919AADE94580A530479C140641D6620676927DFCE0DC4374AF05B379AEDAF0BFAFB0A4EF6FE04E2CD93DC6F0F4B8B680804F296FF8703219988FFD69110830F3C66555A33026EB524E75F9D4AAAFD385BEAF64BB448B2CAF9546ED326E0690948EC06BC7FC9204315D68161EAC551F228373C86BE56208DAFF85C71053355C6FBC677C87E1BEEB1D0F03B8B77F86315F98CBB8FE07B17762D9FA93E484A6E991D616E95476FCF1EF1659DAE67FA92A30CE609127DFA818CB109B5C33615BFDC647B7CB8F74581BC90EA05071E7F4E542EC1940D0E8B0BA4772DC4AB89A3F0989BD4EECC4D026BACDB44AAC9524828EE59DA8F9AEA5323F54FA60633F676B4A6537BAEDAD0B8492695D7333AFFD413DB2134328568B5B7B892585ECE9E5618F7573F014EACD05289DE2404E2A2B7CAE0E79E7AC7AFFA74CAE66B956A7F6BD9FEC4D4E10F3ED7CDD8433A35D785CA2217C5D963A29E9389928FBC1BF380E37CF1242C47342B58AF18CF83F209CD1932378C02538A5C07D369120B3B493B28AC4202971A0D2C7ED6B65E3098107ED5B20BBFF10ADBB33710DC13064C1ED6A289559FF7CC3CE77FD7A7C8701D4F9606FBC7E554E0047883EC6CD106616BF8CB821E0D17792622310BD3FDA8C5C7088C395C6272D8BF06F8F33DB65333F097211A05E2DA3E07FD05331241DD2A1DB878124F57237F5DFFC021263197B10B9352B6BA8061C58BC1BEF2DF186C376E3059862CD9AE36DEEFE6F8DC72D43BD043DAFBD54FBBB93EE72D0E792BCA927E785C9330E79C39581F408A4DA9CB0B4FEEDEB5DD9D8DBF08A736C0418284C41E9195EC680D5A9B56843E87DD76A7519CF03C5A447E407386FA81A38FDCAB479F7F239202DA95D64EA059C05DBE730A5AC672FD3D7C854FE0DDED4340F4FF0E7536F640ABBF7FB1E12DDC7CEEA34FD46BC24918A52EA55FA6FB1B91456932BA95897C92CF3B805994EA5B4C7FA069135F19CBA85E3BB73F55336A9B6113B798BCD3758E1CBBE09E7207345B6DAC55E358C60B6C9768AE2E6DDC15CBBE058B6EC06F1E99D4797E66AB0935B340D392A4C4726D8265B9C5D58B0C7FC77B367495D81518492650D37EB852E8B4672453330E30727F200646E6BDD6D70CE290739A06081F433E27D87C09ADD00E217CAEC0CAA9493AA681C777307E70EEF7184FD658F4B77B88FFDFF539E9284047787AB974CAD538FED6AFB978A38959D02217774C1B3BBCF36C805C17AC104EB27AD4E40A3F46BA2B08ADC30B713F224C18D13F83CC60B59CFBCBFE0E7864BC7A7CAD976D3BDB8CF71DD5888169E85639304D759BBF6FE7C3C6CBEBEEDA02E819A4DCBA188407295AB2D885B34EE22572518BFC0E9749192A839CC08D4A160794AE52113AA94A09258DF03A7A4DCA3EDEF6CCDC720A780DDB561B319B574F2A22A15341746B4DD6281328B3667786AF8B729C135BA418DEC122D3E119F3950FD6ADB0B0C773B90ADBC4B9E8B27043BC5D287BA5B92727FF4759F4F64B620BB226646F08414A0513F72FAA4401E371465EC7E6F4A867A47183ACD434159BBE352FE1C2D8E30BB3D7E08E25D15F1C3D996C811B9AD35A8D5B4B6D0A9A606895E4044E9ADB7A6427DF47C48614C6431F72897E5052B878996C520E9D33AF693BC69F879B8BE87BAE0564701438A51CCFAA342663927F9B2D2271ADA3CF44D8C4016020368C25FD56CECC6EE192734753D66A97E13C2327AC71E5726560D4800B26C604F1A9629F451454C86B6F5AF4CC3419AAA120BCF19671D577927E1A88185D0457DBAEE168A9A45F9BDF0DEE2A35D5E66C2DDA27D6B4EA492BB88D4EEC6CB68B23FA2338530009D9C9CD1041BB0592E83EBA03D39C7FDCEAB5C1654470399E6B85E63616CA705FDA4EAAECA06AB3F87857F15D2EBA75A3A2EEC060177F74009F5943244913E1959820D0D92A0C2AF7844881BD408F4A0CAD81AD6EC9243C8CBA108C8F58A23D5971807233173F1B98AB5C3C73B72706131C9AE644F46FDA74839D497236F152D15B97B93BCC9ACF405C1A1CEDDB9C2F03CE111977426D3438F929219E859CFF3EAFB5D2BBE48E00DF7A4B627E181A8982A3D0E640677B6F3B419B5E2AEC12B8E306253236B5D3B0C7252C2D2F7637610F07094570431E129FC23B631DAA0B6A2A6CB3C75FF8D2ED1CB906EA9CBB20956306E4EA261E10DF1FB7B3FE1D63CA8EA742104DC678AB572D0792DE89CEBFAC8E541E91CF2F7E8CF7A767365FB99A57D2C259DECB1957EF6AFAEDAAD93AB7DBBDD7341C73AC40D25161A103888C8CA74CA0EB52E195848A006E872D0BE5F5A6B5E972444E925B5DA4A3F8F81AA168B836F17F38977ECC7AF48839978A1EAD106E0C3A8A715C86448E9CF4D23703273F4CF00FCA36DAF8834DCD97655B95E6ACF495D4CFC9A7F7D5499260794107B331BFBBD211021B9B7E4C9F947BB9D338C6385B9BF73F0FF6C97C7BD8EA33228EE939BB17E11B3C9D182F818055F753C5356C5BF371E21EAF1CF14B0CE8E3EBFEEB28010DA0B7EA9E0A4285E435FC06B70F4E6DE1DA12D871C3BC8D0C884A7A99DCF2A2C8561CD445B852ADE1A11217A9658D210050AEED89DC18D71D7906389D4056E7DF99DAA462D4C77E7F93874883F33BD13BBBB5E1AA8CB86A981B5491DFCFE2B474F63EB68D923F2D43FDC21E9A56A535347C021B65E54D7935B8EBC249903C7BDC69419E683F3E1BA7450DBEB2F175E2A5593A202543E0655B909D6614290DF1792FCD7B17CDBDFF0E9121D185A082EDBB630369AECBA8C6D4C642ED0AA644832A234DBD48B4C6D8037BF97AFB75626FF28EE1206DA462ED05FF43B23D98D1790106D88C3103232B82DFEDD8B62C8006E2717C921C1695E49B742281AF1CC870CDACA295F867BD72BDAC03CFF02D406A1DD6C3A3E59E8DCF93A5BD54ABB022F9952EF1906FA66ADD7124AC3CB35209BA7958C246AE6AAEF91C5C85F844AFA38335AB67C0735F634203AACA2272994B719B655629E54537A1E75B316E22FCAE758EC85D4D968CB3242510CCBAEAE4AAEC63303EA8E1DB841893CA1BEA38EF797C756A2A75D8C7A823C2DA46FB9996C3C2BA27E19BC5D23005D97BE4D2B899CBD0748811D6E920D535BA9BBA33C4D08868E70AAB6731982181C784EA4D4CFF1D20137645CAEACB27D295F14334D102A5508DD586CDFCE93CFE4D6B5B948D16AC6363B4DF5D7DA3E61D9E0966BD23D46B2263277363524437F18FDCC302540A58823990DF6A6214CBE9FD47F336534E89BC307FB0B030FF063748DEE749FC7907F78588DE4E099CE3D9DBC4ED4F254E7B4B297F5A11999450E485B462C83E9D6519FA1BA4FA39B25D195ADC14C1B862DB6A2222FEC7A4DD09A5472410758B85AA8AC57BDFC80BB4786B2A5C3091B7D24B6854EBACFAA87FA6895E81554AE08D5EF4B3144F872CA9644FD8E7A0C613CFEA146275A72CA3F68AA2F67FF49ECA257FD912F48C6637473EEBADAFBEECB7019B99FD5FA050811ACC255F02307835771417C782D43497C7D2B39B00220396E3C5B02696A16AE562E2E57D227E71502A3DE95D88BF98492035DAE2D468795DA1C32DE795717D43B1BB0DED8C450C34CEEC27AB138D303A083980F535D9F63EEF8D8200A52EE84802B5C6D4CB14D75CC8A719202363F97878B3E719FB607897C49752875A4C9CA7CAAD5511DB6523AFDF0CEF8BCFD96AB239044FB53EEBF3A70001C62E9B86E1A604709082330081EE7538C474D94B0C5FB2664787C85CCED00080E1349869EA6AACDF321546FE415268A8D9195B6C8DDEB337887A9BCE20C2C4178B2C2CAD9386F7C000000000000000000000000000000000000000000050C171B252B3336""") + ), + new SigVerTestCase( + TestUtils.hexDecode(""" +59B2371FE7BACC207FE1FEE88A8B3805A7052865691789BB90542FA47F7EF2B75FCA13DBA5888BEC320514DCB05FD26EB5541F6E572ECEA6C4F1D38AA70259094AA945F19FED0D980E65DBF65DB80F564FE29D836C5479288B55CF07F4E00159B6955DABDECC8C4D66AE688728BA6D5C0442F3C1232C782C465B9B7C5014B1464065CCD8A56D6B1C16510869E014E6933998EF725520B400913D93B0EC75E2FB725DC1AEC0C0CC7343B9E544BAA4D679860E347B2E947D8D2436F09298A7BB8336B9DE9CFD5CDBCD91C7249268CA03EFAC273AF52968D501406CD9C96159D7C15AA2900330C1189CFC2CD8B912C480E458297EF14DB694A3F1E72C1DFA3A3D2A8A69E011602B93020BACD1C2F3AD06C95A7F36EBF5261F6EC106816BB3303CC00BF4E8688D2E8548F10490D9EB23C56793B34B8406CBE443D8356BCD0F4F61D0D017D54831B9BA329F8948F25C3122F9DEDE8CECBA51569EDFFF895FA020862C5DF79F864078486B5FB228FD789C35FDE1C54BFFBF4A025A7FE7D8C3490A5D4E62D04F79F4183CA68379F4648BD5B2416DBE5B845C9F4B7A7E2339C0506D58539EAEA9451C9B2FE2A18C849DCA7EED9DACC058D005FB7375C4EF45B001543FC68E47DDB6D14FF937D1AA0D4D7489DFFA6210679CCCECF9B8551DCF682D2AF1E5BD869F3E8D400D5C861AE51FE7EBBB5457F2EAAFD093A9598EC721C69327C51930F4B9FFB2AA7F1A28436B6D808D75392BC43C1B5B859C66C54FA515C7A615A69E60921434AA9CF9F9E03C3CA35B5EBC6A409E822FE76E0924C6C062F1724C382FF3C8ACB5C1666C2EC26B7628E3D7C13DA8D758890E6CC017B7892582E95EDD04BA9345DF70FAD56EA68BF8875B932C28B32807C86371E17DCC04725CB597B524467963E1D4A61B5FBF9EC504D5DDB61793DD4E34AE082A5990EFCE801E938CCAE738E02E90599D971C2D7C64E5B6F8639F758ED621C1F21073C03EDB782C7A0F5D7C66F5CE161DED55B3E92DC27183AB083DBC1F3930AE56EDB8C53E9A7E020FFF0C4042F518B26F390C96C8183B79B53C7C7BC515187B3DE8CAB08769C5DD6FF5492112E8B0F28D09F4067ADB04194F60250E75ADE331A5C25593BCD92A6D1350439585860BB6FEEDBD2F839F317A01358876C88E898AC0C85378F572F23CDE931D47DE71D3353DAB1F810A61B18D24CD83DDAB8D53BA9C7B8274B0FE82AFF30C57072F643787CA1DF03B99EB57DBDA8C8EE8EB201F2847CBC9D34FD80CE6BC5E1E328EB6EFC83C4BD9D52F324E30EE4B5E86351E5C8C4C5456836D5A452203B3C372C787AE3332C8A5E9DC2197D9C341B9756BB1E63C75BBD5CF3E5CD4BF47BD1FEBC3E3710912D63032F6B97DC19C4DE196ACD9157715E2C14E054A9317BF96A684BB96CEFB7D8FDCA8AA477A2AF6F726D2CAC1A603CF1360EC11CA897E5BC735AB69B8647F30CED4947BA9F635D9CB2D82A662FF17A0E12D4D06D641EE76EB8B45C71EDE38C905C52BE76C6109F2612FEE6C3194465C19BA5D3EBCF1F0B5E534E0F0F1D31CB1E7A36C4303F283DBA8591CC609311A809E444E33A893880CDBAE29119146A368E4D2EDD91FE471647FFE821AA6D31C9FA49695EB9941B08F7BE3F06CDDF2739B8CAD2AB0DA4F5A3C0A26DF6A17B137CAAB3B919AB636D6C89BEDA3058898628721F2770315FEEE881595E24CF48B441660D0B2E9D5B90928C381F2B0FA26342E4C9B88C0887A4687124C012D969E1AFD8532754BA12125E9433DCF6D7BC1A36A83E6A10BA1CB7652A81350899C2DFC6E4FED38D009E6D0F1D44CCCB95E551B3AD54B3AC81E8BA4665EA428B3C861E8677890CF5F625C19A7C5943A9401CB78E7026BAE92B60A8B6807C17745415CD8E030C64C56E822139A35DA423F264336E0AFDF167430DD36E0064B2F6E8D8BB6BE99C5A9FB551CC63E508DB636667DDA53F611F02FCD1F99410F1A7A82882F9623ADDC50EB01E1F39978BF68506C71DBBEE42E4A80069B0E4C7FC4CC1471F4F1028DB25C4687B60DF4255DEC9148197A74796EC760A66AFC7884038651920973A69C203516222632EC5875EA6D838096E7FE9B5B4FB69C5E9407E70D27FA34B0CDBD6E119D87CE38581DF1D3E0DF3AE029042A3B20E923EBCE19A4958755EE2F98FD234C4413E2DBC93559A428DC37F2D1235BD4419B099E0F0DE542C46935991BE0692A6D80B8FD9886E0FA1769B49E8AE6307CB0BC1B49732D26E25CA1CD9D407E0D8864040941611F9333B6367E8300FD646AC5A71AD913EEFD808D5CAFBF1521A3062EC184E52165501E005556DE4DEE46F9E53D7DEF9909F3D5D98CA80D87707F7BC0FF8D879D65D4D783D196F2460693811CDF33358E082D81F4DB8F6C20486183A36D4FBCC8A1C6DA21AA4DD136E19FEF2EA993972BB9989AC1C38A79F31852178004123C46277D38A88FC1589F257332284CD8A873C25A1A6D40265B285DF09370E88F72FF70E434E8F66084CCFEBDBBC4B99EDFBC750CC5DEA63617F647F5F021D57D64D5EFF048634DB2209D7C8B82FB63B8823E4CA057168BAE88D9715291240B3758D7684501F861867B7A241C063B05D5E8CA6B4C79CB2435D7F994CB76915B4A548708B11B29449685941D43E60A8976F9A96072F91041F4C3DF7C73969012AE1B30E4B9C4E133558DABC46C103C0CB1DFB99B585374A54F9BA56B7248B8C3F66F1D55760D6ABB430375774DFBA2059C5DDDB659FD2E1DA9C3F0B80868C92BCAC10403DCD140D6A3D3F35F8EF1A2DD98DE1A4334238599EDAD920DC0AA698E9FE6106A0780C9C245F2C65A0C3E5CD5366110B1760FCD414D450DB9D76A22A9EAEA0C9FB72ED543CE9FA3314BAB17687E9DE5ADAD7561F1A5BEC16339269A87E09ACB29E4C439605E9572AA9B7D0E8371A30E41A0A7BDC02DA3A6121BF261EAA016A2074E4432CF63AF96BE81CEB6E0C2676A8545C66D2F30C98B5424F0FEF04B3C6C7064E2D2E11CBE60F85723FFC0B770D6866FFA589E3F9B2ABF75104019AA69CB58895B474A0ADE2B60A4AB077C3A6DF615334EBBE732E95220213994D3BDC443C8EF94AD515F45418355183314485857AC12BA1D62CF4FD4F4DE2A7FFF1ECF0D290C4CDFFA88D8F48C5B837D3A94CD17B3D169966EB038FE5A6E85DFC60A00233F10731973DC475D53BC7B9E60320BA7905D88519FA325DF5AB02B40F2ABBDB37D2261CB8148277B87AE3297976C80C35134E5F786904564C1469947F620FE09FDF3862C4057A3BCEF70750CB727F031283A1826F1381B3348E3EA4688609ECB193AFAAEE1CD97E4DDAA02C0C30E49F137D08285941528101759A7422AA499C900A379DD73B307284CCDDAF1FA1B0C4B280E3F9F1DB6D38ECF8A841F9D4E40ECA86247D6CD9B31EACD6A46F0E333B9E83D690D7E13467619B46AF9AFCFDC4AA9A049B180260D70D9EEDB8A533051AB83517AADC2CD900B3EA51260F464AFC5D2DC411029779B21CE2CBD160218DF41F661DA1AD95AD40B8C353C7F10FC23F830D117BCAEF8CECEBCBFA49D79D8D9391E8D08281F000A55E92DB331BDECD73183E058FF3FE5839AF50D8C55F22F6AFF5A33DA774BA1B3E643F5877CF549C4F908EA64A37DF3BFA4CD5F70F8CD154476D34BC853C9E8F7979E5F4EBB888AF761"""), + TestUtils.hexDecode(""" +EBDA4B4198C041F515BA16E227F1491F54109B04C5836855038149B60978EA146DF46299A38794D61DA89DCB74A46E3EFED16C832884194E74EEC82C965E9DB2858B87962F48F0C094C389DFD1DD44CBAEDF14A62A709FF48A92E193472899A6876EA8B9701C1D137896F3C779A4E056820F55300524202E44F8B24D5B685787"""), + TestUtils.hexDecode(""" +A2E6DFCDB93DAEF3A2B0A3A548EA48D51157F45034134ACCA15A29E5417475AFE72F571B34545F92DE26B06F141B1A18545CB06D547A1E3D19F9006D7C0E9640273AE424EE20CDC0AB8CCD680AD1CA98047108ED0FFADBD8B568753E4FA7C74CE79F7980297426BEF9ED2C88ED43B45B92E77D47480DEB54993BB03A956F617FBC9E40EE1F726A1E095BF25AA2B8BAD9578506A624E018287DE7A844D4ED1AFFD8B013131272948ADBFB1B40477CE56FA0C94E1DA951049268F26B7544FC1CB0F24F14C2D7A51EE5AA9BCB8A0237231F7ED5F7D2DF14184DFB66CE0336233A506193D6CDDACCD1E2D32A449459DB55DB87080603330CD1A865B719C0C389B19C18ECBB240EFD582A0AA372C47CD00DA92CD0549AA7F7C41FEA9A348D6B7BB78F46DD2998767ECC6CF9F7E2545CA2CB1A18503167A85EA96523C537EE2FCFBE870E40E00E25E7C092A2AD5D5936AAC869D167D9D76BF2AB47185A6F3F64D0557D78D553379ED2542EF2A3CE45E5D97EB7046219E9A9F4A0021EBF5B87A95056F3D14F8A67130B8BDDDB7F5F6C41E189E070A914BF69154F06E45109E2725C5516D1FDCD93A610D3328E2758D5BF0FE58B51E05075D7DFF949E9285924CB3773C8A16CC09F86A0F14925ECADC6FE687C5F864B93868E17D5D3CF218B8E49B991A8CD7879194C425DB3ABAF41B9FCD5E0DDFABD24369EEAA68E50932F6C1C81A72D12DB8EF868B4CAD837EAF5FA0B5915C9BC48FD089F365485A92A6153D1A48B4B28682921C432DFF4B09D63EF3C9A692DCB8FF2D48A5EF0FA63FBC24C9CA2E26AC2ABBA339D2DED6EECC6784C1ECF9F0D39BA10AC8688408AF5B85D4FBC09B73D9DEEA0101146ADBC08004DAF9BC68E66515BA9E103EC4B062A45E733485FAFD9262CC7737999C76305E1106553E495B26F0B22EA7F093B4A543AE8CEB0DB3607F4CC023E45EF9F957563DEDF945CD88FDDDDE42826ADF24D95C314BA718A1C81462C2A4D1BBC2E9418A11954D972D386899B65A2D7D8FBB170A91EE0EA02D18DF1541D95BB64CC54AE8DB48E7B66A633051C04767D708C98BE328EF865431B29348D7306D389287BE9F41BB23BBD3D7A7A3C5D4C3A5F171D574B0640EE6927C1E96F2E9CD0A1BD90430D42A330C93CE66DFDC65B067D8F173EFC0EED00EF24F108B143F589AD94D0A6FC98798C1B63510734A7853D2EDF70A1918D2780C23B12CF5B1EF279604304160364651965646E0E223562381B36CD81FAB31D436F53A9D65EFB3A7EA2092CE202C1ED7FB9EA64AAB6FE7FE107424014E5AB946A3EFBAFDA9619CB7A603F11E9AE507098AFF80331075B06AC4936A711BDAAE97057E31521D5479E046EAD7E8F024E3B9C49A8A253C81A283FBFFCB0C1D896D99E881314C04FA7E0C9DF25B6166F57D97065E9166B37EF612F702E6FF1C9E81F0189E22ADD54B9F2880B23F1D3F88E120B89BEC9C699BFF18DCF870362F9B4D0F66D7416198864484393156D16A7069C0D385910DB49DC9FE8015851DC43E8B03132444BEB19B60DB6052379E5F41109354C0350A2078D397389228726C33DC492DEAD0D55DB917C6E212ACEEAE78A8530DB6A53C7A566E91E1AB62D3AA16F2736CDCD965D38D945E8A15EB68CC2B50A9C5E88F5C40B8F67AF4C36F241F3DE9EC66911937739F8F5C56C28CEC16FB453818178A3698D639A7E9A215D2F7400F5FA0772485BD75A58CA574CAC9BEF89F8F3B554A92687EEA5C6AE9651D9CEC267E13F84FB98D43FC7D24895296D78FEC1B2012F732092511930FF78664E926A57F23D3CF17BF19EEE27D833B88B6E30BF5AE5498FA55EC0D14FB127D5E6EE80560F540FBE26FD81AA62B006A139A065C11B7B48B2AB038B522168748A57DDB6C0A6CA0D7B4B79527673E58617F22F3C1B32FEFC787B41DDE9399549B0608478487126611634E5166BE7AFAEAB42F348B2691A1978CE61C753A049767A02E7055DBBFE771ECD8613B3AA29622F2FBC06F9BDCD9C94D0FB8C75310E2D4100C5248FFCDA8A898AD331BB4ECA6939FF31094F418BB8BAEC58AEF7B6FA33ED8588A21B437F4AD5EA5F2D86C4DCF1C4A559BE9B0C384AD2AA778EE93CA70989BD2ED681666CA8B082B7B83272F8A10E2D245628C8E1B5FF3BF8C5FA9C6E09C238482679888827D0E3D0B9A8CC36027649B0798E14390AD84D3D766DCEBEEB670E3560C6378F90A411196365F4FA6D332244EEF1016085C9B51614D8BF3BB44A67C906E7241213318B714824C03D9E8927AB2ADFFF50494D3F398F37E6BFAB3F8E0B89643FD220DA424BF2D751D07B5F335944462B374F297726DBBBF8C3A2D7B26BBACF192C05FF89F0878E26ACF8275644CB85C7D81022D1E85FDE63E7055E1202B85E0118687994931DE1617BA91CE9054327D3DC9DA0135DB676E9A4388DBDC3727DFCE71FCA2CEE2B2331DD836086D86C3F36767BD2F210B7B8CB1458CE8252DE845F507D78C93F7ECA7FD8CADA3DDDFEA34D2FA9AD31F10F02430C884F65346840E4CA5CC54572D6533A4E2417CF859185CA5B905BF83135BCBD88C0D86CB7C3344674F8A9A09BFD460CA828BACBE12B661459123201A5CACEBB6EF6E449B049552AEB5EA305B870055201B4686CB255E12BB1CA67DB46AED1890716672A898F71B5109A5C253276C42A22ACAEAD6E4F0798067FE983494752574A612969F1C923AD5718362E2AA1C4E5255A777DC6CBD53F553B0953BB464EBC29AA36E3F72B5C6614FAB08CC65F540D662599D45269754C0D6BE109BD7E0DF04D5EFF30000D8D6AF25B5AAD51057C31C4C134C59C3356B34638692222273144CE9D768196749FCE54DC7A7A1E2E36192FD7E756994E37D0078850E81D2D9C40670B77A02C9F708DA28CF2CCF478309B4279A6C45B9FF854A5F5B553CB291FEF5D1970883A064200D2C99597829F15DB4D9506C82154EACC4FEB0800D268902B462FE9D3284D89D83A7009AF5BDEFBCB310608151430B779A6FA4CBF6DF1E13C4A9DEE96D6BBC0CF989C48888BA58316FFA0114020B5C326D723960FC20DCFB01DC50982FD824F9512AE73E3676ED8040481CB536F851274087BFCB77A0EC7DA2BE274288D2212471DC7949EEF77A8333AABAFB57581CB43774E07F192B825F14AD564658792A0E235F4DB5EA6E3A84403492E209484542C2C2881042F54CD56CC00F2C31810EEC70D8386D0C8B7E4756A77B11563A42BC3A5D2A495D0C8278810D55EE7CB38D80C34E4DC58F0A8B1EC6E2193E6184E5F0793AB882051EBBDB3303D86F4A0E22090C7A957BE5F7BDF4652FC8F38DAC71257B2570D5B1DFA95BFEEB7E377DD581A8975D72398B4D258B1B9E7DA60217FF77BAD7008FBCCDAF7479573F9ED6BA8D13F83C233166D8D7A400F00840887BE510EAF1CF2E30B244C9EB6E166C98156C27A5FF0DB563A204B830C8FFC64D6685C9E3BF8968F3A2D2B329AA6AAB0D49EDEC26C2B5D7462AB465381D5431C85268EFB89F4E04DC660EBF4A0962F9C9F4EBB7F2A1EC5B3262DE971219FB56CF42CD720811EAF66DC2C428F94E1DE4ECE5F2116533B25E65D732A4BBD5221D28EFA946DAF52437AD6657703A9B454422C7DADEBF063E5FC433536CBA84E07F7086FE031A0A2B4DACDC99E5D3486E77D41D949EBE69E14BDF21090646CD9FF8E9F0FBF5E737DD38C0EED3D73D22A7C23AC781341109997594B3D1D4153AA1A35FF7AAD5636BFA9BE09E3329FB61950CB6DA58600E05DC2782B2EF58466AC9A4BBF6264D0D616968C6BAFC496F859EE9512072180172E91E3B581FF5CE9B8AC0624F221D111BBAAD988A530C0CADE0C4CC399EFAE9ECD624F55D93F9D0F0FC915292419ED119E177095880FBCE058783D85380F1F6673B7ED6702446098693F3FEBB9C9D7906391608453158C695D073B259518AA7DC5125B51E58A5170D1A68CF6CFC1A705B344911A63875080B4FACD9835AE85294D03EFF6D3B02888BC1D094B9E7374CAABBD1D0C32F1786B8CC12D0E4C76BC99694A1862A73ADB58A20908A601ABC4015ACC17E5B0AC28F3D8896F8BF0AA344B814D63CF558E0CED39D1F7B16D411E014BCB594F37CF18BCF46EBDEEDF1AECBD13ED97AD65A0674275868F34148D6E03E7D802258987937DBAA69215216F1CDF8BA2BCDA245D42A5D9891CF0ABC804595B320A774F1DE69F8ED595007A59F1FB570D6D024ADC97B121C28542E3043C3F99EA5EA4BE47E3DC0B66E297477537041CF880B5FAF2828E3DA2D2F9414297C59F17ED60E2DBA0502E8FE6B8E5B13FE2E945B2E78277C568082F678E4F4FF2E323D1E0AF996364E2AF2FC95C53F83953028D38BB168A1FE68C02E4477CF567DF6C2A72AF3F56EFFC99C0F5223E4CF32CA3B97C700A40803E3C91DA686DDF45A47208FC904B2384730F050A9E3440CF9A010044F7E8B6B0FEDA288F810E27AAC5DAF358046D8AE85AFB6020C22986C4788E07EFB41B2C18C482C72027673E9695CAB29FA04ABC0D7C790D3F32565A859696B6C036ACB5A6D1E444CC7D9D23B3A8FBE6E2E851914711EF790E8CBB097ACAE791825EEBA70C3AF28E6E8EFCCA38CF6B6F466D568100ECA07BF3B4B8E18EB791A2431A7FC2A795B4CDE07A38E1662044E81E85667BE36058095C7F0573D930CACEFE4C97B3393F8400451AAC6B55C5399826D8C7746BDE6484D4377BDFAD25CC5CC17C774B4623BE25184DD627CE8E6547788BD7CA2FABC9B7D4A602C457FE9EFD82B79E9322F99962FC7DAD35BFAF85A03D67DC7E83FD3C627160DC96640683AAD733B3D1EB59646A2533B99EAEA4E5CFDB2C94A8724B03FC4B72BB5BC5D90B0D4A136E44D64F3985A7EF7C6D7C55B61486CE529475F21630DD824F8AD4D3FBF0CB2C48CCC0DC27516733FF5BDC1F459B00B88883006AEDE6602DC51A316959DEBEDC0F36BBE8D017207225C1C2BD94CFC1CC60933CEA2ADE45BB4425578F4D28E0AA36DA346E2BA4B34B65BD7E71B9FCC3B52F8C425AD44B5CCD006E26857FC5BAD79D8345C5FACEAA4DC3A7C613D085826F82F10961AB2BB7C087FDB490B5A082B2F5DA5D9E6210D6E8B37ADB10DF510990F3ACD81CF93965CAAB334F1B2A76D9B17D758F273860B074B2FFFB88D9B5E6991EDBFC5FFB54325BFFC0C66092E7729C9971101D7CBF74491CC4F54D535936CBC5455E3215215E836500F411382CB8658BBB60636BAC343A645741FCD6C5E23433EFEF4F14967C5B742BDA45B2FAE1946FD0042229A1E462E172102124540CB203D58DF1EB8ADEBC4DCB37F8450DBD0FEC87CB4A56696141C9513F7D6E61BB117B0E35E1DD314837965004C6C86388C2D3EA57EA4C0CE9C563C68F5B3CA20043742BB5060935C23FC7FD5368EABE5C1A1B715B99B96E1B434229D3ADE0129AAD85710596DF9AA2D86C7EC88B9552F876861DBAD135B4EB318FC6FFBC3AF0C98EC57468A0F4BC3A29CF1625B03E33360D152B0B5F5706C169B68C7470379BA15D9188F13DFCF789C18A9DA14EAB56DB261F978D9BD894C84C1BD203A777DF785C82B87FF975BAE11437F9A243627A1715CBFFEED727B405C545542A7BED9395ADE1A671807954EAC7C9BFB8785F18D5D5C31A01320E7D863743BFC7852E251631A03EB671912F6138C21E1D62D88E1941095A8DFDF3B052A0104E72C186BFEA9CAF32B2FCA121FCF6A3D85FCBB9D7978EF2E227F321C1BD932A4DB007CB2DFE3BFD9578BD7AA6844611E4F3ED7E5370205A07B6CBBFCA7AA204D76CC8DCB9A1CB6FE6C4AFC5E5A79E59C6934D473BF834F69B89073DEC0D9ABD347B12BA21E308D42D1576F03CE4BE6EF8F07EA08CF1846C27ECEE7F8415C0FA756A540E42738892C7E6D0F90520FEAC6160911BB18BDEA2A1D925CDFBA7C585DAA3A3D27B12E4880A9B8C87B0EB5EFD7C07507D8C3B274738C90EB4A745C1AB3749ED000075E99277B927B1CAF2E19E8D588AFD3CF9BC0302724E71F129E3E3BE9D114542B16C4DB65AC8529CF95CAF7A2EED53548D1769F809F1780E5102D80B7E52B99203F5CA6F2A2A7608171190EF391A4EF5384D15C101895B5402E8D4FEA052872FBAF6DC9FFDCD3FF9EA884ABA4D90E202206E861B9785AC572A0013765C24B5E3AB9C4E31A6B7F958A4D3DE78CA4D4C097AB9AD50E588BDEC45528EC7B248BAA3BD3DF31F8FEB29F823123421388A2A021F37426188CF830BDD10C75BFFFDA15623B33F89567EBD2EC66EC7DF533CE8F33C32EBD6D074606380F37F3E9D186E4A93EB098B6EC0455843E7784A9CCC67E0326920223993CEEF7E4AE399E21993CCD078084804EAB9881B6C40CE2B20BEC97DF60381E930CBCC038A4A9153B2AF6AC6F743FE6E2FDA9A0FBD4C00D93C972333C8A8D99041D8C93718CA0CB864B5E50059D73978FA3FF33115880D43D93B8512246D82CF104A4B525F6F8B95AAB9C8DF02649497A9AAF01EB4C7EB1E232738557175E6090C2F657E9DBAD6F90860BBDEE0F701236C8489A7C200000000000000000000000000000000000511181C242D333A""") + ), + new SigVerTestCase( + TestUtils.hexDecode(""" +59B2371FE7BACC207FE1FEE88A8B3805A7052865691789BB90542FA47F7EF2B75FCA13DBA5888BEC320514DCB05FD26EB5541F6E572ECEA6C4F1D38AA70259094AA945F19FED0D980E65DBF65DB80F564FE29D836C5479288B55CF07F4E00159B6955DABDECC8C4D66AE688728BA6D5C0442F3C1232C782C465B9B7C5014B1464065CCD8A56D6B1C16510869E014E6933998EF725520B400913D93B0EC75E2FB725DC1AEC0C0CC7343B9E544BAA4D679860E347B2E947D8D2436F09298A7BB8336B9DE9CFD5CDBCD91C7249268CA03EFAC273AF52968D501406CD9C96159D7C15AA2900330C1189CFC2CD8B912C480E458297EF14DB694A3F1E72C1DFA3A3D2A8A69E011602B93020BACD1C2F3AD06C95A7F36EBF5261F6EC106816BB3303CC00BF4E8688D2E8548F10490D9EB23C56793B34B8406CBE443D8356BCD0F4F61D0D017D54831B9BA329F8948F25C3122F9DEDE8CECBA51569EDFFF895FA020862C5DF79F864078486B5FB228FD789C35FDE1C54BFFBF4A025A7FE7D8C3490A5D4E62D04F79F4183CA68379F4648BD5B2416DBE5B845C9F4B7A7E2339C0506D58539EAEA9451C9B2FE2A18C849DCA7EED9DACC058D005FB7375C4EF45B001543FC68E47DDB6D14FF937D1AA0D4D7489DFFA6210679CCCECF9B8551DCF682D2AF1E5BD869F3E8D400D5C861AE51FE7EBBB5457F2EAAFD093A9598EC721C69327C51930F4B9FFB2AA7F1A28436B6D808D75392BC43C1B5B859C66C54FA515C7A615A69E60921434AA9CF9F9E03C3CA35B5EBC6A409E822FE76E0924C6C062F1724C382FF3C8ACB5C1666C2EC26B7628E3D7C13DA8D758890E6CC017B7892582E95EDD04BA9345DF70FAD56EA68BF8875B932C28B32807C86371E17DCC04725CB597B524467963E1D4A61B5FBF9EC504D5DDB61793DD4E34AE082A5990EFCE801E938CCAE738E02E90599D971C2D7C64E5B6F8639F758ED621C1F21073C03EDB782C7A0F5D7C66F5CE161DED55B3E92DC27183AB083DBC1F3930AE56EDB8C53E9A7E020FFF0C4042F518B26F390C96C8183B79B53C7C7BC515187B3DE8CAB08769C5DD6FF5492112E8B0F28D09F4067ADB04194F60250E75ADE331A5C25593BCD92A6D1350439585860BB6FEEDBD2F839F317A01358876C88E898AC0C85378F572F23CDE931D47DE71D3353DAB1F810A61B18D24CD83DDAB8D53BA9C7B8274B0FE82AFF30C57072F643787CA1DF03B99EB57DBDA8C8EE8EB201F2847CBC9D34FD80CE6BC5E1E328EB6EFC83C4BD9D52F324E30EE4B5E86351E5C8C4C5456836D5A452203B3C372C787AE3332C8A5E9DC2197D9C341B9756BB1E63C75BBD5CF3E5CD4BF47BD1FEBC3E3710912D63032F6B97DC19C4DE196ACD9157715E2C14E054A9317BF96A684BB96CEFB7D8FDCA8AA477A2AF6F726D2CAC1A603CF1360EC11CA897E5BC735AB69B8647F30CED4947BA9F635D9CB2D82A662FF17A0E12D4D06D641EE76EB8B45C71EDE38C905C52BE76C6109F2612FEE6C3194465C19BA5D3EBCF1F0B5E534E0F0F1D31CB1E7A36C4303F283DBA8591CC609311A809E444E33A893880CDBAE29119146A368E4D2EDD91FE471647FFE821AA6D31C9FA49695EB9941B08F7BE3F06CDDF2739B8CAD2AB0DA4F5A3C0A26DF6A17B137CAAB3B919AB636D6C89BEDA3058898628721F2770315FEEE881595E24CF48B441660D0B2E9D5B90928C381F2B0FA26342E4C9B88C0887A4687124C012D969E1AFD8532754BA12125E9433DCF6D7BC1A36A83E6A10BA1CB7652A81350899C2DFC6E4FED38D009E6D0F1D44CCCB95E551B3AD54B3AC81E8BA4665EA428B3C861E8677890CF5F625C19A7C5943A9401CB78E7026BAE92B60A8B6807C17745415CD8E030C64C56E822139A35DA423F264336E0AFDF167430DD36E0064B2F6E8D8BB6BE99C5A9FB551CC63E508DB636667DDA53F611F02FCD1F99410F1A7A82882F9623ADDC50EB01E1F39978BF68506C71DBBEE42E4A80069B0E4C7FC4CC1471F4F1028DB25C4687B60DF4255DEC9148197A74796EC760A66AFC7884038651920973A69C203516222632EC5875EA6D838096E7FE9B5B4FB69C5E9407E70D27FA34B0CDBD6E119D87CE38581DF1D3E0DF3AE029042A3B20E923EBCE19A4958755EE2F98FD234C4413E2DBC93559A428DC37F2D1235BD4419B099E0F0DE542C46935991BE0692A6D80B8FD9886E0FA1769B49E8AE6307CB0BC1B49732D26E25CA1CD9D407E0D8864040941611F9333B6367E8300FD646AC5A71AD913EEFD808D5CAFBF1521A3062EC184E52165501E005556DE4DEE46F9E53D7DEF9909F3D5D98CA80D87707F7BC0FF8D879D65D4D783D196F2460693811CDF33358E082D81F4DB8F6C20486183A36D4FBCC8A1C6DA21AA4DD136E19FEF2EA993972BB9989AC1C38A79F31852178004123C46277D38A88FC1589F257332284CD8A873C25A1A6D40265B285DF09370E88F72FF70E434E8F66084CCFEBDBBC4B99EDFBC750CC5DEA63617F647F5F021D57D64D5EFF048634DB2209D7C8B82FB63B8823E4CA057168BAE88D9715291240B3758D7684501F861867B7A241C063B05D5E8CA6B4C79CB2435D7F994CB76915B4A548708B11B29449685941D43E60A8976F9A96072F91041F4C3DF7C73969012AE1B30E4B9C4E133558DABC46C103C0CB1DFB99B585374A54F9BA56B7248B8C3F66F1D55760D6ABB430375774DFBA2059C5DDDB659FD2E1DA9C3F0B80868C92BCAC10403DCD140D6A3D3F35F8EF1A2DD98DE1A4334238599EDAD920DC0AA698E9FE6106A0780C9C245F2C65A0C3E5CD5366110B1760FCD414D450DB9D76A22A9EAEA0C9FB72ED543CE9FA3314BAB17687E9DE5ADAD7561F1A5BEC16339269A87E09ACB29E4C439605E9572AA9B7D0E8371A30E41A0A7BDC02DA3A6121BF261EAA016A2074E4432CF63AF96BE81CEB6E0C2676A8545C66D2F30C98B5424F0FEF04B3C6C7064E2D2E11CBE60F85723FFC0B770D6866FFA589E3F9B2ABF75104019AA69CB58895B474A0ADE2B60A4AB077C3A6DF615334EBBE732E95220213994D3BDC443C8EF94AD515F45418355183314485857AC12BA1D62CF4FD4F4DE2A7FFF1ECF0D290C4CDFFA88D8F48C5B837D3A94CD17B3D169966EB038FE5A6E85DFC60A00233F10731973DC475D53BC7B9E60320BA7905D88519FA325DF5AB02B40F2ABBDB37D2261CB8148277B87AE3297976C80C35134E5F786904564C1469947F620FE09FDF3862C4057A3BCEF70750CB727F031283A1826F1381B3348E3EA4688609ECB193AFAAEE1CD97E4DDAA02C0C30E49F137D08285941528101759A7422AA499C900A379DD73B307284CCDDAF1FA1B0C4B280E3F9F1DB6D38ECF8A841F9D4E40ECA86247D6CD9B31EACD6A46F0E333B9E83D690D7E13467619B46AF9AFCFDC4AA9A049B180260D70D9EEDB8A533051AB83517AADC2CD900B3EA51260F464AFC5D2DC411029779B21CE2CBD160218DF41F661DA1AD95AD40B8C353C7F10FC23F830D117BCAEF8CECEBCBFA49D79D8D9391E8D08281F000A55E92DB331BDECD73183E058FF3FE5839AF50D8C55F22F6AFF5A33DA774BA1B3E643F5877CF549C4F908EA64A37DF3BFA4CD5F70F8CD154476D34BC853C9E8F7979E5F4EBB888AF761"""), + TestUtils.hexDecode(""" +4AC4675C96D9117D1EDEB80D7CD284A3E1E1FE038E301205B4C408EB965235AD1C85F8BE3F77CA486FD207F7C75F4121CD3CA2B23D6BCE4382A6D36121815025D5806CBEF452E083933C6E5C7394AC88262A6DE7770B2D8843EC101FFB5E84DE2F7A8B74E7674B3B2319BD6BF4112F92C5CFC0A55F7FA061F45325408D039D51"""), + TestUtils.hexDecode(""" +4B3F52F081B3D914BC7C6C073B182B268ADF5189E298A869BFB991B199993C1042DEF5B59270B6CD3FF8F907A1CB0D3B6FEDCA143838F8F81E0C370FFEEE6B25CD07035641A051944EAB516CFBB801536B4F262B16198E7DDB1D61C35A64D90D3948CEAAC8EE580DCEF540ED99D912BBA2BC4F5145BB949C73CCBD582613B10EAAE863ACA34683EB922B3DADFC74F76F47E4978602592402D9154394EB09FBC2EBCCC594732F2D8BC38350E5535A4412A77ADD7916604576FD6A3631E515BAF26A6F9CA4061EBBDD3BEC7179AD58552A5B508F31348A56AD1ADA7A05352C72C004B94C47E7049A10B3A59BF238A8DFC6C7019A17F05D5BFCB9D93D9D1CCBCB47F8C438098FDBDFE23F9F78BC28069908C6B9898B434CBF37787E1AF6A6B827E830E9F7629CD8F51070C4C8A8DEB260D07C3E41D8490484877491B39AA6D9E10D91748B64E33160629D8AE43EFD5F85781E69F76B6895C141EBCDDFEEB485A00BDBA4F7C991F53F2F84933926AF39E6964ABF2DFEBBC19A7E31C50797B8DA2931E10F3DAC493F198DFD785D21ADB2C062B097E889A20737F186008F2928F6B84D6E09E975A8F2AAADC785234234FDA03703A7C21F812D650BD2510B30F0550081047A155C848586A96F100D774F3E39E029B0777CD33E68318A11C1980293FAD3E787D20DFE7EEE7053C05EEB6A159BAAD4020B9EC3F537DA4DADAFB3B1BB1DBEB2D5B8F9D05A019798EAE0ED099DB066D73EE8E9A56DE368E878A7FF39140D8021D50085E6252941AB315309CB53AAA49E86347FBAD54A1F873E0CB4B86A8D5B1B2A95D485F37A9FB6105DF8440FDB8578F2624C079329569A75F36F2C55D8D030FBFEAA8889AD746C323B1AC4EC8C403E775A6FBE596E7E6A5A2863576625149940976F7CC93617B43FB13489074ECAC5BEB1A4DFE58B9AD2E0C6A15B76A7C2D208725A3123CA4E6F2C5847EE5FA8384919EF89011D219B257B3E4DC4F2095160844CAEEAFCF857260F1C63D3B05A67D3D0F2B0EC9DCC2723F13755750BAE62FCC361CFB584F774C09ADF9A0431B23E488C359C0AEF5B1C9787BD8F52B083BC9DBCC9B3039F777C7E8EABC80078050CE6D49C3BB70168FA2177298FB0A8F72C1CD28D662A07DAE6C7ACB7FB8E7FDD01DFB27C62EE683F4E5F88C7C1DDDD5EECC1C3AF853F1FF6B1D9DE672F1BF6473AF0021D8A3D4DD04A2FCA2325C721CF1C821676D0A0D574186625DE831C8411F64179F9167F78BCB22FB41C2CDB63C4DB5E138766D3803589598F114F41BA42CDB1341020449BA99656113990B4E022D8DA20D744491C6EEAB67B918E80FFF343CC5B4C8E58C3484B0125A60C36AEF763894D35148B578F417C3A98A143EDFE9F8C95BCC346C6F5EAF97AAD11DAE01C477C227A88D10ECFDCF450B37F881968027849D9B43E2BFF90C6A34AE41B8BBD743083D3C58786B036671CD6EED94DAE51F7613247EF8607ACF74A3CCE932F1C3869BDB35CA17FC6BA9F9C956FF1D4D88094325CABCE41233FB1D808EF41010396DEB0ECF50734D818DDAB70015A0ABDD1926DFA491F711AA85DA2A8EC60E3255CCF975C23CC4E8DAFDDED9FEC60A6467C45B03CA476499AA331B0E3999576CEC3191A9A62BC1BEAC1EAF20E18CFC3216127DE4AAE2E75201F9E427E39BF921150EAB949559C022D876FA242C2A845BCA7235F721B0056788A44ECC3EB98F0F502B89F8E7410EA5679AE7C0434F13AD816421D2FEE30CBCB2DAA6B851CD1B6E996DA7A757E4C4D8572C8B600DE85DDB65320D1CB71D9378349C0C401AD4F9E91272139228A8DA2F4FD2F48891A4DCB066D501D447483B611BB3C80550A90EA0B732D639D8B3926B6E7C35453ED3CC110BAF556CF46D8FC2177E76FB2663B8BDD171E94C0ACAF25B9153B22BCA749916756FB3ED3018E0944B6C3B9B6BFA15B9BE803AC79333CD2C3A27A26BC17CDA257798AE16B28B463B6DF3FA87C2D742D0F6885BEE0BEC6E20D01E5DADC86823E92D60FEC79B0D240248753E42048384C804289604821A57F4F9F50AE0C38527FE5A34938DDBCDCD9A1D020839BEBB62F9F41FBA08052ABB82FADA884CBE563791103AA585546EBFEB11272CC2E87A3B75B3C6BB1853AE7F9CF5585B2653CF5EEA244D204EB269C56A20985160659CB0725EE13CE35D55EB095A53414F232DF8108B18024EB0DBF345EB5CDAD0BCE7263509A341D54A7D534E553EAEFFE4E242EA23BCFE59A58A60425882CB7E3B0C9E4AFE8698E3DF56AFD6D611E9168747D8735CF9246D94F2126BE727FB42B2241A83B34F0B9EB47938D726502C54E4572766331628FA5CDA893C35376AB4538FF8717C2795B0F51F08E1137612B89B0C1E2CD1F099E88556923AE57A1DAD2AFB1230B5094A1B21BAD7DBBC333A97F179304718F3289B6DE31315B74C1A73AC7756FAA4D7EB568BBC6F7E788CD089B395564D2176B0056DFFE952C7748B048306720F602B67E8F6ADCC91F8E3AA4B8C4D7FAC233AAF93653AD2209E2FF92DA30C2D53FDEF6F4C90EAA0DE60D594ADA3915DB24279D867476EAD757B4C0264A1DB8A1F57A1B5D7173BB1A960CE02FDEFEF160D512667D655268FCC3A153A4314782A0EBFF84F65F14A0E3E12A13250C07D08C225B11A6831BC25C40467B768004DDE0E874A51144C18920BDF286090B59F51564EA4070FBBF61E3696435F28F63332B64496DF3EC8B65D54E1CF4789DDAB122DA6B264D312A711C129E3B07F4C6DA25A56173AF58B90A71B7ACFA3161A81F59D17914C99BBAC4F9A314977A89CEF7696943609BB4827964FB2976403BD4996F1E842BF5AAAE1ECCA11255B9E6001C20F72F1FD5E32CDA32D8A7AC5F62B09A0E615847CA746F489515CF8F183162859F53B97E9E5CA800EE624F729843A0009164A4A9FF76EB34E4704184848A139AD97D909F7A7ED114F087A4B2E1B4A3032391160B6F3A3649FF15AEA2B7107AF8A3B5FCAD61D43D602E6286A900870CC8CE24E39E78F0397A0D7E27E8E2D4776A44CBA218EBCD88B3C28C182A7C9F4DBB2DBB5E981563D66CEEB77E7F9034BD429D27637CF797DE82E01FEBBCE2171EFD016E402A42D78EA1ACE2CB370E75C90ADFA1A793B2169CC26522DB2F546AC1DE34C9087120C42A9F10C00D493C25730166F9D219FBDAD222C8B28115543313210848FB2F04BFDCE15D320C3634A8E4D63755515900C75BFD090AD78DD588659FBF97C96E0D0ACC8E815E608F9E861D79AF3051B942B52570B6292BF48C2BFAA9077DC76FE902683217B8BF809ED7A0050ADDBB65FDDFBD24019C9181B5AC81566113D6694EA6291D7F4A7F56A41EB91F76368DF82B164B4859259D7189240F1D8803F8107296D378BAB4D24FE6D10EF788367BCE16C5AB77FBC168B857F7BA5CDCBE5067C864F879809FE5217DEF0294BFAFDF809ABCE9532DD9DAB3448F4DA68ECA51609476278EB8C4F69EA29673F69418041D26857EBC24A487BB4B0BA63AF848545EE9BE89F139D502099B9D35DB3807B925CBA576E27170EAEC48CC2CC15B043677825D0EE81EB2CEE3A8ED14A798B879530220E50CE8C003A305382A24D23C277B99D1F4C54F9A8D33FA3D1E337E18D7CBBA5E5A47F2D5E096CF4551B23B1B86436E81B4A09D1E3D38492EC8B2A00967016AB76B9A9B1864671421DA56F57D008D5CE1B892A7E9C1F69F6C722CF109DB500E53F6BC07837AD1CD4CF4A64DA763B4A9C4929B0DCDDF7C7E1186BE3FF0C321158437820C81E74FF316AE3254E972FC197A7F0E620242AC05A4E43E987C2A8355B0357745CA79E6AE48AB29ED4FA63D3A1F19B999DE251FDE0640DD87876D55762878AD1DB12D65BAFD14B6A9A7081BF23F9F06D90CE273C5A26E012CA94DD481D32E10938C165163E89BE8A93A63034D345B74E2A94EF643D06AF9E1F5C9F104930DA00E61E061EE8C3BB17C11E05D45C1682E4D593C9198238D2BA289779E7D0F227BCB0B09972B19770FF011BF6C60D9D193CFAB32747A0095E1A4AD32514C782EF3DE7A26EA771F5530D9DE9736D0F6AE1AFB78EC7CE4884A1BB436CFCE459CD99358260906AAC99716A536CC7687A0375FDA11007618E553534E54D5B214F7AA6FC7DBE37C2BD2B64850AE469A9858987F3FA4B1FD26D954BFEC365DBE06DDCD615E1FED58A88676402D1D6B581485498B5ADFFFC42D47D61DF99384E22C5157F0178A6FDAF8F4A9491DAF298B2C3EC88085022C0A7CF245ED0FB5A38CD16F30D37DA5C4959A55501DAD50F1B48BBBDD86AB8BB522A936DDF0003B81BE16231A04E7A589C56FFFB51B07927B4AFA1DB7D48BC6FBC3F3675637184B7ADB9BADF4DE7C085BCA1D428DC9FC8277CBD85884A5921B52BB05B710615508261BB4546BD6E1FC730D16B049EA12798CE2E6DF43F5B8F3EF9AC8FBAE31B011E10C4FC62FFD7F39D16EC32CA8210ED16E041DA43D9274229514054A0F82D462FE080C6FFD7BBDBFBF0BFFC6D5ECC432A3256C0BE0DDFD5D9080C676C7955D66E44D1CE51FCC2382F868D732E85851721B48A01D08C639626EE0509CB581EFF5628FA6CCD1089AC0E12DEBE0851782E64C5049CBD6501013965CC0CA25ACAB176EF7CAB92940985DDB49021DF6C60D6C4A489116311E86BA19EDF00D74797358207CDE50506D007FE03C8804C66451F02A0182D387B759894096F65232952D183DBAAABB6BC0E191DC2C3F75FC72BD61BAB2EF19B6532B231C4AFB1A9C2CB2F3D6C451E8440D6A923CF72A63E2ED8554773887910CA5C671AD4FD5923CB95EC73FFDFBDA4B6655F55DBFD1317D024422301ED66A6E4C672085CED1F4C7B05030A100C4788FEF4CD3E494A853BDE63E9D449AE3BB6BA1083238DA3F4090515D143C67DBE53D8D507A5229FFEB2072D0BD092FC9AE52DEAAACD1F0F14B5AC84752BFD0025E5F55B869350F4B2719C5C05AC1669BB0FD3C614ACE02A270613FD3309706DDCD5B1A6AD26F359ADA80B30E50A7E50BBD3AA45D0654DD7D058B0BBF4D0D92135142214EE70511F3676AE643B5F245063B9419CF6B49FD647F27D7C41C866E6CAD9D5E2E3E331BF6B9F72ACA329BB64259C3E79783A26674B7D38EBDE8318411F4764EBDC4C7E41ACFF85BBB30318D59C42C9203ABD6636BA3F772B6725121C052DE99910D55158C6F3EF8BB7FEDE2F81E58A7AEB25E2E46FD7232302FAFA8FC37FC8B55D594B76EC4A53EB11EB3FD634428AAA5D86F839D089ABE2FEFE2AE5262FEFC7348D836692EDB215D6F8F548B885290C2403C51C3E269D493FBD339B5DFB0A38EEDA7754DAFFA16E5BCA5A9BBDE04B014B7AEA8988F3749D52D2FC1C9F7C7B2C2D692E7896E4C34F57C558CFE8317A8374409D566879A08628F644FB45B818455BCA6042B4E6187C1DD177E9E5146319904B1505F3EE00CD7FEAF0E83C3024956F77659ACC56D8D917A37E8FF7EB88713CCA334EA04B8E258C9345DA9DE26A0A366519451E1012DE6AABF4697C9DE821D70021C3250A106CF4C23A1B1785F549D3C8CD71B05FEA753E0046A3AE0A9B1F40277CF453A2BA14CBA923CC6269706DFFFD517C1E5930079912E05A5571897A06865516C86699F707E00CB38CE193490AEE30BA47DDDF3A5B4FBCEBA73DC13D0A160EA642D30D63A02964EDFDB2F29DCD32CA9974F89C32D1FA9A83C94A2770FCFCF86E64646882BD550DDD65B4E2D287AF6C196F42DBD39B020D7CDFBB6E6E75FFAAB26099EC1D25E3234F70DD972286AEA0C3436595FE49FCA898BFA421604C82D3E94856D186905076D186C684174BF4290DF31769EDC97A1DF2DFED03CF45CE678C8A1429EB978D02A79D4F8CF0168DAAB482C6C612F04B1C93637FE77B302CEFA788C11356C52C54F37A9DCFDA55927A8EF0A0CEA7CC4ADCEE459EB64DF08ED0FC29FDC3C7B762B399332063340D473966219BFC87B4A3C91C80F0E4BA86AA1879C76625C8680A227AB22780659D4B5D30E0E9A0DCE094DAF537679273A9B277ED2A2E250EEA0938204C9E963D338522A3D1A4440E2A12397A5B97D35657307BEC94CC0C72C5C6B09DAF2BAF0020B7D8CA560BF6596929AC8D4E5460F7837B41B4AE6FF12339DB8EBD7028AACFE0B42E02CDE906783ABFF694E7CBE0897ED6ED438ACDB00A4709CFEF7150EBEB08C8FF6C1543815F4B8951C3CACE499586458A73C8572389AFC9703A7FEAF673445FB4B0CCAA511D4A2CF463F57E3A6D72DA04B256699A30212E7C5768EFC151B71744156575A2E9443319232D159C6CC006FDB57C58173AD8D2C866C8887437C223888E21EF67E1A332C1FDFCC15EF17476FE0FB57D4229894725E1474C1BA1216562817F16C53ECE01C7F9E3664EEDBBA94952987431AA2A57D330EB11B28E6BF770E349ECE350C83E90DA6FE0D0A4AB9715DB28BDD397FAFA1428302151E1F222B4469879EB5D0F018606A7594BFC82C394E91B9264495C9063D505262799B9FCBE6316BBCC8D8093053636A74D4FA000000000000000000000000000000000000000000020F161B1F292E36""") + ), + new SigVerTestCase( + TestUtils.hexDecode(""" +59B2371FE7BACC207FE1FEE88A8B3805A7052865691789BB90542FA47F7EF2B75FCA13DBA5888BEC320514DCB05FD26EB5541F6E572ECEA6C4F1D38AA70259094AA945F19FED0D980E65DBF65DB80F564FE29D836C5479288B55CF07F4E00159B6955DABDECC8C4D66AE688728BA6D5C0442F3C1232C782C465B9B7C5014B1464065CCD8A56D6B1C16510869E014E6933998EF725520B400913D93B0EC75E2FB725DC1AEC0C0CC7343B9E544BAA4D679860E347B2E947D8D2436F09298A7BB8336B9DE9CFD5CDBCD91C7249268CA03EFAC273AF52968D501406CD9C96159D7C15AA2900330C1189CFC2CD8B912C480E458297EF14DB694A3F1E72C1DFA3A3D2A8A69E011602B93020BACD1C2F3AD06C95A7F36EBF5261F6EC106816BB3303CC00BF4E8688D2E8548F10490D9EB23C56793B34B8406CBE443D8356BCD0F4F61D0D017D54831B9BA329F8948F25C3122F9DEDE8CECBA51569EDFFF895FA020862C5DF79F864078486B5FB228FD789C35FDE1C54BFFBF4A025A7FE7D8C3490A5D4E62D04F79F4183CA68379F4648BD5B2416DBE5B845C9F4B7A7E2339C0506D58539EAEA9451C9B2FE2A18C849DCA7EED9DACC058D005FB7375C4EF45B001543FC68E47DDB6D14FF937D1AA0D4D7489DFFA6210679CCCECF9B8551DCF682D2AF1E5BD869F3E8D400D5C861AE51FE7EBBB5457F2EAAFD093A9598EC721C69327C51930F4B9FFB2AA7F1A28436B6D808D75392BC43C1B5B859C66C54FA515C7A615A69E60921434AA9CF9F9E03C3CA35B5EBC6A409E822FE76E0924C6C062F1724C382FF3C8ACB5C1666C2EC26B7628E3D7C13DA8D758890E6CC017B7892582E95EDD04BA9345DF70FAD56EA68BF8875B932C28B32807C86371E17DCC04725CB597B524467963E1D4A61B5FBF9EC504D5DDB61793DD4E34AE082A5990EFCE801E938CCAE738E02E90599D971C2D7C64E5B6F8639F758ED621C1F21073C03EDB782C7A0F5D7C66F5CE161DED55B3E92DC27183AB083DBC1F3930AE56EDB8C53E9A7E020FFF0C4042F518B26F390C96C8183B79B53C7C7BC515187B3DE8CAB08769C5DD6FF5492112E8B0F28D09F4067ADB04194F60250E75ADE331A5C25593BCD92A6D1350439585860BB6FEEDBD2F839F317A01358876C88E898AC0C85378F572F23CDE931D47DE71D3353DAB1F810A61B18D24CD83DDAB8D53BA9C7B8274B0FE82AFF30C57072F643787CA1DF03B99EB57DBDA8C8EE8EB201F2847CBC9D34FD80CE6BC5E1E328EB6EFC83C4BD9D52F324E30EE4B5E86351E5C8C4C5456836D5A452203B3C372C787AE3332C8A5E9DC2197D9C341B9756BB1E63C75BBD5CF3E5CD4BF47BD1FEBC3E3710912D63032F6B97DC19C4DE196ACD9157715E2C14E054A9317BF96A684BB96CEFB7D8FDCA8AA477A2AF6F726D2CAC1A603CF1360EC11CA897E5BC735AB69B8647F30CED4947BA9F635D9CB2D82A662FF17A0E12D4D06D641EE76EB8B45C71EDE38C905C52BE76C6109F2612FEE6C3194465C19BA5D3EBCF1F0B5E534E0F0F1D31CB1E7A36C4303F283DBA8591CC609311A809E444E33A893880CDBAE29119146A368E4D2EDD91FE471647FFE821AA6D31C9FA49695EB9941B08F7BE3F06CDDF2739B8CAD2AB0DA4F5A3C0A26DF6A17B137CAAB3B919AB636D6C89BEDA3058898628721F2770315FEEE881595E24CF48B441660D0B2E9D5B90928C381F2B0FA26342E4C9B88C0887A4687124C012D969E1AFD8532754BA12125E9433DCF6D7BC1A36A83E6A10BA1CB7652A81350899C2DFC6E4FED38D009E6D0F1D44CCCB95E551B3AD54B3AC81E8BA4665EA428B3C861E8677890CF5F625C19A7C5943A9401CB78E7026BAE92B60A8B6807C17745415CD8E030C64C56E822139A35DA423F264336E0AFDF167430DD36E0064B2F6E8D8BB6BE99C5A9FB551CC63E508DB636667DDA53F611F02FCD1F99410F1A7A82882F9623ADDC50EB01E1F39978BF68506C71DBBEE42E4A80069B0E4C7FC4CC1471F4F1028DB25C4687B60DF4255DEC9148197A74796EC760A66AFC7884038651920973A69C203516222632EC5875EA6D838096E7FE9B5B4FB69C5E9407E70D27FA34B0CDBD6E119D87CE38581DF1D3E0DF3AE029042A3B20E923EBCE19A4958755EE2F98FD234C4413E2DBC93559A428DC37F2D1235BD4419B099E0F0DE542C46935991BE0692A6D80B8FD9886E0FA1769B49E8AE6307CB0BC1B49732D26E25CA1CD9D407E0D8864040941611F9333B6367E8300FD646AC5A71AD913EEFD808D5CAFBF1521A3062EC184E52165501E005556DE4DEE46F9E53D7DEF9909F3D5D98CA80D87707F7BC0FF8D879D65D4D783D196F2460693811CDF33358E082D81F4DB8F6C20486183A36D4FBCC8A1C6DA21AA4DD136E19FEF2EA993972BB9989AC1C38A79F31852178004123C46277D38A88FC1589F257332284CD8A873C25A1A6D40265B285DF09370E88F72FF70E434E8F66084CCFEBDBBC4B99EDFBC750CC5DEA63617F647F5F021D57D64D5EFF048634DB2209D7C8B82FB63B8823E4CA057168BAE88D9715291240B3758D7684501F861867B7A241C063B05D5E8CA6B4C79CB2435D7F994CB76915B4A548708B11B29449685941D43E60A8976F9A96072F91041F4C3DF7C73969012AE1B30E4B9C4E133558DABC46C103C0CB1DFB99B585374A54F9BA56B7248B8C3F66F1D55760D6ABB430375774DFBA2059C5DDDB659FD2E1DA9C3F0B80868C92BCAC10403DCD140D6A3D3F35F8EF1A2DD98DE1A4334238599EDAD920DC0AA698E9FE6106A0780C9C245F2C65A0C3E5CD5366110B1760FCD414D450DB9D76A22A9EAEA0C9FB72ED543CE9FA3314BAB17687E9DE5ADAD7561F1A5BEC16339269A87E09ACB29E4C439605E9572AA9B7D0E8371A30E41A0A7BDC02DA3A6121BF261EAA016A2074E4432CF63AF96BE81CEB6E0C2676A8545C66D2F30C98B5424F0FEF04B3C6C7064E2D2E11CBE60F85723FFC0B770D6866FFA589E3F9B2ABF75104019AA69CB58895B474A0ADE2B60A4AB077C3A6DF615334EBBE732E95220213994D3BDC443C8EF94AD515F45418355183314485857AC12BA1D62CF4FD4F4DE2A7FFF1ECF0D290C4CDFFA88D8F48C5B837D3A94CD17B3D169966EB038FE5A6E85DFC60A00233F10731973DC475D53BC7B9E60320BA7905D88519FA325DF5AB02B40F2ABBDB37D2261CB8148277B87AE3297976C80C35134E5F786904564C1469947F620FE09FDF3862C4057A3BCEF70750CB727F031283A1826F1381B3348E3EA4688609ECB193AFAAEE1CD97E4DDAA02C0C30E49F137D08285941528101759A7422AA499C900A379DD73B307284CCDDAF1FA1B0C4B280E3F9F1DB6D38ECF8A841F9D4E40ECA86247D6CD9B31EACD6A46F0E333B9E83D690D7E13467619B46AF9AFCFDC4AA9A049B180260D70D9EEDB8A533051AB83517AADC2CD900B3EA51260F464AFC5D2DC411029779B21CE2CBD160218DF41F661DA1AD95AD40B8C353C7F10FC23F830D117BCAEF8CECEBCBFA49D79D8D9391E8D08281F000A55E92DB331BDECD73183E058FF3FE5839AF50D8C55F22F6AFF5A33DA774BA1B3E643F5877CF549C4F908EA64A37DF3BFA4CD5F70F8CD154476D34BC853C9E8F7979E5F4EBB888AF761"""), + TestUtils.hexDecode(""" +EA707F27A8896AA860FDF5D5897B58538D1CB6096CDF2AD5F583C5D4FCC2C91839C1AD44920216F8D027AAEE2E563D779E86FAC4B2502497B41229BE823ACF0BEB232CC6F3F7DA88E0685A9176DFE71E42470FCCCDB43C6688A03B6D8AF6612AB821CD16757FBEAE52C779EFB6AC38EF7FB4B5E365882CB83AA246B2A52D5059"""), + TestUtils.hexDecode(""" +372BF9FD2061BD26939A23C3DB128746EA3346F0C0E75C4C358405C12CAC9636D241A5E555ADF1B8C448152326F9248EBE31E8C171B3CE7C0079610C6C715BF8DA26F4344C0F043EAE26E749E56BAA190E502BCBE70740A8CDED41CF2FAB99AF00A6D788FF05C30CB8B9ACC125FEAC8C7CDFC1DD7226C819BE3A237BEE81FDA6B1DEBB83207B53BBD1E3FE07D3919AA9B3505F3DA78B7AF7A61979B9C8290563B7ADFB676D06C7AAF545452D3D7C9262AD40456D0333B362A68207D0273F488AA60F87543B4E4F4B0BFA36AAB42D523AC1D6691B680C673832888480CFF337B1590A8544A3663515198481B17D0839944754E14D565A8C32CA1D2BD4863EAEE16AC0BF8D52EFAA731CDB0A3A25D2583424F0F57E08E2018247B610F843B1ACBC54B3AE0E880B994254B4DADD9652EF5E36D3F1CCAE76DB8FF110CB3AEF24EA7B00E32278A05267C3A3319EB58E92172DC5C7EE748739C5E19AE54F7A8D714CA642958B820CF8C71F20E03730641CBCAD74E1956A1C50562E27F21FB03F44A3F032519E2E20577D4611764159405D7BB138F34126A4E5C8B3AC1A8F19817061BFE1C50A8A6767053677F1B507D70B56BAECB8BBE2F54DAACC13AD373020C13B103D2079B140ACD18D3824C03205C6198AC1603CE63602EE853B08395BC749B0DA7ACCA6DE54D1D742442C81ADA46C3A21F8F8B4A1E3C212315E6D19D290D139E70C037D4E64D3630996606E443414A371A96B19433B1DB4B5EE677113DE2005ABB42CC8DF12C33DC7791FC7AEE807E7946B023FE451ED32FF21ECA246AF26B535A11B4C6F380EF56DBFFF984ED15818EEB08578D045F2FCF39C3CB456C73EFB76C66AA09E6F9458AF39BC5A9E1E9D6E8826AD3ED681DE22E9AEE77FAACE34385376EFFA306098EDDF4F122106EEBDF32AC04884554BE6945753E6B831FAF701B4AEA4F48A8D490BDCF33B0E1630C94F756A1C565D2554F5081EE3B4EA5C33EAE04F06BD44CA0D0671708E9392EEB6C4EB80AE8A17911B27CAC8980A87A3ADD2F5E2FEC71FF711D89A6F96EA423411E81B292668F60AF44F0CC83BCF835E78F2F6BC503F54C2C6CE827D97023B98F23A85D269238013F29E9AE8BE2FB54C9AA69BB6FCCD96916918B8E534D3CDFE506A2AE474B59589CCC730A0A857BEE1F4CFAD0433BA4D34E8888FE2785A7B6331C1CE3F66E0DCC2F801C112DEE85EB869567C387305922B252073023259E1C042D3A245D141DFB0F2A1A5CE0FB772B12A0AD875DE56A8A0151891D4D4D2E2DD4E025D8BA25E63E44AD8798D495CD099B57CF73623A2FBEDBCAF1ECEE43AA0882E553F5058C50AD9C4FFCC59D93F51DA653DDDA17B14EF03D86EE7234A3808B54A1BAB7FE12154816735D62BF3ED4CA9C180D6BC050EA3937EBA6F8AEB4A7811A7307FC7A0BDB24360AA517A2333FE86CFD05E5924923AD390E6F0DC4E757AC78A754BC6B3C15954674F4AD41D05007BB984C89C198C4E4109683BFD1A1E59FD8CA36040090764B81A747ED14CED83ABE341473BCBA6B5629044DB6CCD65CF6DE91C91AC20875565440194FDB3D21CA637E019636B44F69D578C1E1CB12312FB109242C228B02A70FF001095801CC2D308A5E802C34B102F174C6C0A44D14A76B9D82D8B97C01205BDB22AEA9B2F0DE6507C0FADD1321BA71157C203DFF28207B5CD7AE18923DAB57AE263BD26A97210DAC238427857AFF7639195EC13CB74D511B40A5C5855E1EC1223B6B44C5B630AD94050B573FDF919FEA24AEAE8095AA8136D15294D876D1ACA1F862B038F35265BE879A0F1FCCE07FB76884DDE073E73785B46DC0EC95B7859594119D272CBDCEC3FFF7A1AF8B5076C977B76C7FD640B834B92066257EEF27ECA1699A7BE3ADD1746624C27256BFF5F9177C01147585D1D5CBF576F381DD6DF2320F24293F32BAD164E474CE9C741EF87302331AA9B67D64E95527C4BCFB601699D68F1F712222BF00262BF4AE8C49E098A8EADD108288EC0995D068315CE39C6429CCCB00E1D94477B76D866AD7B7968B5AA98A590782354EA512344FE58290DB10717E5C6102BC7EDC1CF85D634439D5D82C1B5A2A9928FE389BDBE4FE9AA859DCCDE68392AD6B35F516AEA70220B0D6DD2A91239EBC0D15B5930937207E0CC5AFD925A4B8BF5A0A4DB25BF87294CCD7E148684F331508A752386A0811B606B91283D865B58B347084CC01C874C046861ED3FD8DF8C5B07E8A2F27176685A39A9BCD955645F1EA58B4811DFBA16C98BA52BC0EA443D592756B00CC4CA428511A7F8051E94C5C273CC6E8652F3E9132E0ABB003C31DC61A8802D2CA650EC0B5AF5BC3E983C2746F4747AEB1F6624F010C5104F7A577E58D5D527CA58BC838C60049C99270A66C846258D32A5A5E4245088E7C6F824671AC80571DEFB07A21B64A688100F0BCC7F28B985DD9B0A1F6780B561BAA8616909555E6BF656F1E02691EF83E475E90FCE338195A88FC1DF0864B5375496B5D8FCEED265163ED2EDA2CE6CAEF6583800F225084662591706E1F8AACE331689219268A591379219CEAEF219A02CA85AFED70C96CDC7B50905EB6C2BD0E1B09DB19CC8728EB108123228628212EC1A591148DEDCEB7F4938F0A99B727B79F230BFB96B82E03AD90B6EF858CB899AA2549E0FB1E8919AADE94580A530479C140641D6620676927DFCE0DC4374AF05B379AEDAF0BFAFB0A4EF6FE04E2CD93DC6F0F4B8B680804F296FF8703219988FFD69110830F3C66555A33026EB524E75F9D4AAAFD385BEAF64BB448B2CAF9546ED326E0690948EC06BC7FC9204315D68161EAC551F228373C86BE56208DAFF85C71053355C6FBC677C87E1BEEB1D0F03B8B77F86315F98CBB8FE07B17762D9FA93E484A6E991D616E95476FCF1EF1659DAE67FA92A30CE609127DFA818CB109B5C33615BFDC647B7CB8F74581BC90EA05071E7F4E542EC1940D0E8B0BA4772DC4AB89A3F0989BD4EECC4D026BACDB44AAC9524828EE59DA8F9AEA5323F54FA60633F676B4A6537BAEDAD0B8492695D7333AFFD413DB2134328568B5B7B892585ECE9E5618F7573F014EACD05289DE2404E2A2B7CAE0E79E7AC7AFFA74CAE66B956A7F6BD9FEC4D4E10F3ED7CDD8433A35D785CA2217C5D963A29E9389928FBC1BF380E37CF1242C47342B58AF18CF83F209CD1932378C02538A5C07D369120B3B493B28AC4202971A0D2C7ED6B65E3098107ED5B20BBFF10ADBB33710DC13064C1ED6A289559FF7CC3CE77FD7A7C8701D4F9606FBC7E554E0047883EC6CD106616BF8CB821E0D17792622310BD3FDA8C5C7088C395C6272D8BF06F8F33DB65333F097211A05E2DA3E07FD05331241DD2A1DB878124F57237F5DFFC021263197B10B9352B6BA8061C58BC1BEF2DF186C376E3059862CD9AE36DEEFE6F8DC72D43BD043DAFBD54FBBB93EE72D0E792BCA927E785C9330E79C39581F408A4DA9CB0B4FEEDEB5DD9D8DBF08A736C0418284C41E9195EC680D5A9B56843E87DD76A7519CF03C5A447E407386FA81A38FDCAB479F7F239202DA95D64EA059C05DBE730A5AC672FD3D7C854FE0DDED4340F4FF0E7536F640ABBF7FB1E12DDC7CEEA34FD46BC24918A52EA55FA6FB1B91456932BA95897C92CF3B805994EA5B4C7FA069135F19CBA85E3BB73F55336A9B6113B798BCD3758E1CBBE09E7207345B6DAC55E358C60B6C9768AE2E6DDC15CBBE058B6EC06F1E99D4797E66AB0935B340D392A4C4726D8265B9C5D58B0C7FC77B367495D81518492650D37EB852E8B4672453330E30727F200646E6BDD6D70CE290739A06081F433E27D87C09ADD00E217CAEC0CAA9493AA681C777307E70EEF7184FD658F4B77B88FFDFF539E9284047787AB974CAD538FED6AFB978A38959D02217774C1B3BBCF36C805C17AC104EB27AD4E40A3F46BA2B08ADC30B713F224C18D13F83CC60B59CFBCBFE0E7864BC7A7CAD976D3BDB8CF71DD5888169E85639304D759BBF6FE7C3C6CBEBEEDA02E819A4DCBA188407295AB2D885B34EE22572518BFC0E9749192A839CC08D4A160794AE52113AA94A09258DF03A7A4DCA3EDEF6CCDC720A780DDB561B319B574F2A22A15341746B4DD6281328B3667786AF8B729C135BA418DEC122D3E119F3950FD6ADB0B0C773B90ADBC4B9E8B27043BC5D287BA5B92727FF4759F4F64B620BB226646F08414A0513F72FAA4401E371465EC7E6F4A867A47183ACD434159BBE352FE1C2D8E30BB3D7E08E25D15F1C3D996C811B9AD35A8D5B4B6D0A9A606895E4044E9ADB7A6427DF47C48614C6431F72897E5052B878996C520E9D33AF693BC69F879B8BE87BAE0564701438A51CCFAA342663927F9B2D2271ADA3CF44D8C4016020368C25FD56CECC6EE192734753D66A97E13C2327AC71E5726560D4800B26C604F1A9629F451454C86B6F5AF4CC3419AAA120BCF19671D577927E1A88185D0457DBAEE168A9A45F9BDF0DEE2A35D5E66C2DDA27D6B4EA492BB88D4EEC6CB68B23FA2338530009D9C9CD1041BB0592E83EBA03D39C7FDCEAB5C1654470399E6B85E63616CA705FDA4EAAECA06AB3F87857F15D2EBA75A3A2EEC060177F74009F5943244913E1959820D0D92A0C2AF7844881BD408F4A0CAD81AD6EC9243C8CBA108C8F58A23D5971807233173F1B98AB5C3C73B72706131C9AE644F46FDA74839D497236F152D15B97B93BCC9ACF405C1A1CEDDB9C2F03CE111977426D3438F929219E859CFF3EAFB5D2BBE48E00DF7A4B627E181A8982A3D0E640677B6F3B419B5E2AEC12B8E306253236B5D3B0C7252C2D2F7637610F07094570431E129FC23B631DAA0B6A2A6CB3C75FF8D2ED1CB906EA9CBB20956306E4EA261E10DF1FB7B3FE1D63CA8EA742104DC678AB572D0792DE89CEBFAC8E541E91CF2F7E8CF7A767365FB99A57D2C259DECB1957EF6AFAEDAAD93AB7DBBDD7341C73AC40D25161A103888C8CA74CA0EB52E195848A006E872D0BE5F5A6B5E972444E925B5DA4A3F8F81AA168B836F17F38977ECC7AF48839978A1EAD106E0C3A8A715C86448E9CF4D23703273F4CF00FCA36DAF8834DCD97655B95E6ACF495D4CFC9A7F7D5499260794107B331BFBBD211021B9B7E4C9F947BB9D338C6385B9BF73F0FF6C97C7BD8EA33228EE939BB17E11B3C9D182F818055F753C5356C5BF371E21EAF1CF14B0CE8E3EBFEEB28010DA0B7EA9E0A4285E435FC06B70F4E6DE1DA12D871C3BC8D0C884A7A99DCF2A2C8561CD445B852ADE1A11217A9658D210050AEED89DC18D71D7906389D4056E7DF99DAA462D4C77E7F93874883F33BD13BBBB5E1AA8CB86A981B5491DFCFE2B474F63EB68D923F2D43FDC21E9A56A535347C021B65E54D7935B8EBC249903C7BDC69419E683F3E1BA7450DBEB2F175E2A5593A202543E0655B909D6614290DF1792FCD7B17CDBDFF0E9121D185A082EDBB630369AECBA8C6D4C642ED0AA644832A234DBD48B4C6D8037BF97AFB75626FF28EE1206DA462ED05FF43B23D98D1790106D88C3103232B82DFEDD8B62C8006E2717C921C1695E49B742281AF1CC870CDACA295F867BD72BDAC03CFF02D406A1DD6C3A3E59E8DCF93A5BD54ABB022F9952EF1906FA66ADD7124AC3CB35209BA7958C246AE6AAEF91C5C85F844AFA38335AB67C0735F634203AACA2272994B719B655629E54537A1E75B316E22FCAE758EC85D4D968CB3242510CCBAEAE4AAEC63303EA8E1DB841893CA1BEA38EF797C756A2A75D8C7A823C2DA46FB9996C3C2BA27E19BC5D23005D97BE4D2B899CBD0748811D6E920D535BA9BBA33C4D08868E70AAB6731982181C784EA4D4CFF1D20137645CAEACB27D295F14334D102A5508DD586CDFCE93CFE4D6B5B948D16AC6363B4DF5D7DA3E61D9E0966BD23D46B2263277363524437F18FDCC302540A58823990DF6A6214CBE9FD47F336534E89BC307FB0B030FF063748DEE749FC7907F78588DE4E099CE3D9DBC4ED4F254E7B4B297F5A11999450E485B462C83E9D6519FA1BA4FA39B25D195ADC14C1B862DB6A2222FEC7A4DD09A5472410758B85AA8AC57BDFC80BB4786B2A5C3091B7D24B6854EBACFAA87FA6895E81554AE08D5EF4B3144F872CA9644FD8E7A0C613CFEA146275A72CA3F68AA2F67FF49ECA257FD912F48C6637473EEBADAFBEECB7019B99FD5FA050811ACC255F02307835771417C782D43497C7D2B39B00220396E3C5B02696A16AE562E2E57D227E71502A3DE95D88BF98492035DAE2D468795DA1C32DE795717D43B1BB0DED8C450C34CEEC27AB138D303A083980F535D9F63EEF8D8200A52EE84802B5C6D4CB14D75CC8A719202363F97878B3E719FB607897C49752875A4C9CA7CAAD5511DB6523AFDF0CEF8BCFD96AB239044FB53EEBF3A70001C62E9B86E1A604709082330081EE7538C474D94B0C5FB2664787C85CCED00080E1349869EA6AACDF321546FE415268A8D9195B6C8DDEB337887A9BCE20C2C4178B2C2CAD9386F7C000000000000000000000000000000000000000000050C171B252B3336""") + ), + new SigVerTestCase( + TestUtils.hexDecode(""" +59B2371FE7BACC207FE1FEE88A8B3805A7052865691789BB90542FA47F7EF2B75FCA13DBA5888BEC320514DCB05FD26EB5541F6E572ECEA6C4F1D38AA70259094AA945F19FED0D980E65DBF65DB80F564FE29D836C5479288B55CF07F4E00159B6955DABDECC8C4D66AE688728BA6D5C0442F3C1232C782C465B9B7C5014B1464065CCD8A56D6B1C16510869E014E6933998EF725520B400913D93B0EC75E2FB725DC1AEC0C0CC7343B9E544BAA4D679860E347B2E947D8D2436F09298A7BB8336B9DE9CFD5CDBCD91C7249268CA03EFAC273AF52968D501406CD9C96159D7C15AA2900330C1189CFC2CD8B912C480E458297EF14DB694A3F1E72C1DFA3A3D2A8A69E011602B93020BACD1C2F3AD06C95A7F36EBF5261F6EC106816BB3303CC00BF4E8688D2E8548F10490D9EB23C56793B34B8406CBE443D8356BCD0F4F61D0D017D54831B9BA329F8948F25C3122F9DEDE8CECBA51569EDFFF895FA020862C5DF79F864078486B5FB228FD789C35FDE1C54BFFBF4A025A7FE7D8C3490A5D4E62D04F79F4183CA68379F4648BD5B2416DBE5B845C9F4B7A7E2339C0506D58539EAEA9451C9B2FE2A18C849DCA7EED9DACC058D005FB7375C4EF45B001543FC68E47DDB6D14FF937D1AA0D4D7489DFFA6210679CCCECF9B8551DCF682D2AF1E5BD869F3E8D400D5C861AE51FE7EBBB5457F2EAAFD093A9598EC721C69327C51930F4B9FFB2AA7F1A28436B6D808D75392BC43C1B5B859C66C54FA515C7A615A69E60921434AA9CF9F9E03C3CA35B5EBC6A409E822FE76E0924C6C062F1724C382FF3C8ACB5C1666C2EC26B7628E3D7C13DA8D758890E6CC017B7892582E95EDD04BA9345DF70FAD56EA68BF8875B932C28B32807C86371E17DCC04725CB597B524467963E1D4A61B5FBF9EC504D5DDB61793DD4E34AE082A5990EFCE801E938CCAE738E02E90599D971C2D7C64E5B6F8639F758ED621C1F21073C03EDB782C7A0F5D7C66F5CE161DED55B3E92DC27183AB083DBC1F3930AE56EDB8C53E9A7E020FFF0C4042F518B26F390C96C8183B79B53C7C7BC515187B3DE8CAB08769C5DD6FF5492112E8B0F28D09F4067ADB04194F60250E75ADE331A5C25593BCD92A6D1350439585860BB6FEEDBD2F839F317A01358876C88E898AC0C85378F572F23CDE931D47DE71D3353DAB1F810A61B18D24CD83DDAB8D53BA9C7B8274B0FE82AFF30C57072F643787CA1DF03B99EB57DBDA8C8EE8EB201F2847CBC9D34FD80CE6BC5E1E328EB6EFC83C4BD9D52F324E30EE4B5E86351E5C8C4C5456836D5A452203B3C372C787AE3332C8A5E9DC2197D9C341B9756BB1E63C75BBD5CF3E5CD4BF47BD1FEBC3E3710912D63032F6B97DC19C4DE196ACD9157715E2C14E054A9317BF96A684BB96CEFB7D8FDCA8AA477A2AF6F726D2CAC1A603CF1360EC11CA897E5BC735AB69B8647F30CED4947BA9F635D9CB2D82A662FF17A0E12D4D06D641EE76EB8B45C71EDE38C905C52BE76C6109F2612FEE6C3194465C19BA5D3EBCF1F0B5E534E0F0F1D31CB1E7A36C4303F283DBA8591CC609311A809E444E33A893880CDBAE29119146A368E4D2EDD91FE471647FFE821AA6D31C9FA49695EB9941B08F7BE3F06CDDF2739B8CAD2AB0DA4F5A3C0A26DF6A17B137CAAB3B919AB636D6C89BEDA3058898628721F2770315FEEE881595E24CF48B441660D0B2E9D5B90928C381F2B0FA26342E4C9B88C0887A4687124C012D969E1AFD8532754BA12125E9433DCF6D7BC1A36A83E6A10BA1CB7652A81350899C2DFC6E4FED38D009E6D0F1D44CCCB95E551B3AD54B3AC81E8BA4665EA428B3C861E8677890CF5F625C19A7C5943A9401CB78E7026BAE92B60A8B6807C17745415CD8E030C64C56E822139A35DA423F264336E0AFDF167430DD36E0064B2F6E8D8BB6BE99C5A9FB551CC63E508DB636667DDA53F611F02FCD1F99410F1A7A82882F9623ADDC50EB01E1F39978BF68506C71DBBEE42E4A80069B0E4C7FC4CC1471F4F1028DB25C4687B60DF4255DEC9148197A74796EC760A66AFC7884038651920973A69C203516222632EC5875EA6D838096E7FE9B5B4FB69C5E9407E70D27FA34B0CDBD6E119D87CE38581DF1D3E0DF3AE029042A3B20E923EBCE19A4958755EE2F98FD234C4413E2DBC93559A428DC37F2D1235BD4419B099E0F0DE542C46935991BE0692A6D80B8FD9886E0FA1769B49E8AE6307CB0BC1B49732D26E25CA1CD9D407E0D8864040941611F9333B6367E8300FD646AC5A71AD913EEFD808D5CAFBF1521A3062EC184E52165501E005556DE4DEE46F9E53D7DEF9909F3D5D98CA80D87707F7BC0FF8D879D65D4D783D196F2460693811CDF33358E082D81F4DB8F6C20486183A36D4FBCC8A1C6DA21AA4DD136E19FEF2EA993972BB9989AC1C38A79F31852178004123C46277D38A88FC1589F257332284CD8A873C25A1A6D40265B285DF09370E88F72FF70E434E8F66084CCFEBDBBC4B99EDFBC750CC5DEA63617F647F5F021D57D64D5EFF048634DB2209D7C8B82FB63B8823E4CA057168BAE88D9715291240B3758D7684501F861867B7A241C063B05D5E8CA6B4C79CB2435D7F994CB76915B4A548708B11B29449685941D43E60A8976F9A96072F91041F4C3DF7C73969012AE1B30E4B9C4E133558DABC46C103C0CB1DFB99B585374A54F9BA56B7248B8C3F66F1D55760D6ABB430375774DFBA2059C5DDDB659FD2E1DA9C3F0B80868C92BCAC10403DCD140D6A3D3F35F8EF1A2DD98DE1A4334238599EDAD920DC0AA698E9FE6106A0780C9C245F2C65A0C3E5CD5366110B1760FCD414D450DB9D76A22A9EAEA0C9FB72ED543CE9FA3314BAB17687E9DE5ADAD7561F1A5BEC16339269A87E09ACB29E4C439605E9572AA9B7D0E8371A30E41A0A7BDC02DA3A6121BF261EAA016A2074E4432CF63AF96BE81CEB6E0C2676A8545C66D2F30C98B5424F0FEF04B3C6C7064E2D2E11CBE60F85723FFC0B770D6866FFA589E3F9B2ABF75104019AA69CB58895B474A0ADE2B60A4AB077C3A6DF615334EBBE732E95220213994D3BDC443C8EF94AD515F45418355183314485857AC12BA1D62CF4FD4F4DE2A7FFF1ECF0D290C4CDFFA88D8F48C5B837D3A94CD17B3D169966EB038FE5A6E85DFC60A00233F10731973DC475D53BC7B9E60320BA7905D88519FA325DF5AB02B40F2ABBDB37D2261CB8148277B87AE3297976C80C35134E5F786904564C1469947F620FE09FDF3862C4057A3BCEF70750CB727F031283A1826F1381B3348E3EA4688609ECB193AFAAEE1CD97E4DDAA02C0C30E49F137D08285941528101759A7422AA499C900A379DD73B307284CCDDAF1FA1B0C4B280E3F9F1DB6D38ECF8A841F9D4E40ECA86247D6CD9B31EACD6A46F0E333B9E83D690D7E13467619B46AF9AFCFDC4AA9A049B180260D70D9EEDB8A533051AB83517AADC2CD900B3EA51260F464AFC5D2DC411029779B21CE2CBD160218DF41F661DA1AD95AD40B8C353C7F10FC23F830D117BCAEF8CECEBCBFA49D79D8D9391E8D08281F000A55E92DB331BDECD73183E058FF3FE5839AF50D8C55F22F6AFF5A33DA774BA1B3E643F5877CF549C4F908EA64A37DF3BFA4CD5F70F8CD154476D34BC853C9E8F7979E5F4EBB888AF761"""), + TestUtils.hexDecode(""" +EBDA4B4198C041F515BA16E227F1491F54109B04C5836855038149B60978EA146DF46299A38794D61DA89DCB74A46E3EFED16C832884194E74EEC82C965E9DB2858B87962F48F0C094C389DFD1DD44CBAEDF14A62A709FF48A92E193472899A6876EA8B9701C1D137896F3C779A4E056820F55300524202E44F8B24D5B685787"""), + TestUtils.hexDecode(""" +A2E6DFCDB93DAEF3A2B0A3A548EA48D51157F45034134ACCA15A29E5417475AFE72F571B34545F92DE26B06F141B1A18545CB06D547A1E3D19F9006D7C0E9640273AE424EE20CDC0AB8CCD680AD1CA98047108ED0FFADBD8B568753E4FA7C74CE79F7980297426BEF9ED2C88ED43B45B92E77D47480DEB54993BB03A956F617FBC9E40EE1F726A1E095BF25AA2B8BAD9578506A624E018287DE7A844D4ED1AFFD8B013131272948ADBFB1B40477CE56FA0C94E1DA951049268F26B7544FC1CB0F24F14C2D7A51EE5AA9BCB8A0237231F7ED5F7D2DF14184DFB66CE0336233A506193D6CDDACCD1E2D32A449459DB55DB87080603330CD1A865B719C0C389B19C18ECBB240EFD582A0AA372C47CD00DA92CD0549AA7F7C41FEA9A348D6B7BB78F46DD2998767ECC6CF9F7E2545CA2CB1A18503167A85EA96523C537EE2FCFBE870E40E00E25E7C092A2AD5D5936AAC869D167D9D76BF2AB47185A6F3F64D0557D78D553379ED2542EF2A3CE45E5D97EB7046219E9A9F4A0021EBF5B87A95056F3D14F8A67130B8BDDDB7F5F6C41E189E070A914BF69154F06E45109E2725C5516D1FDCD93A610D3328E2758D5BF0FE58B51E05075D7DFF949E9285924CB3773C8A16CC09F86A0F14925ECADC6FE687C5F864B93868E17D5D3CF218B8E49B991A8CD7879194C425DB3ABAF41B9FCD5E0DDFABD24369EEAA68E50932F6C1C81A72D12DB8EF868B4CAD837EAF5FA0B5915C9BC48FD089F365485A92A6153D1A48B4B28682921C432DFF4B09D63EF3C9A692DCB8FF2D48A5EF0FA63FBC24C9CA2E26AC2ABBA339D2DED6EECC6784C1ECF9F0D39BA10AC8688408AF5B85D4FBC09B73D9DEEA0101146ADBC08004DAF9BC68E66515BA9E103EC4B062A45E733485FAFD9262CC7737999C76305E1106553E495B26F0B22EA7F093B4A543AE8CEB0DB3607F4CC023E45EF9F957563DEDF945CD88FDDDDE42826ADF24D95C314BA718A1C81462C2A4D1BBC2E9418A11954D972D386899B65A2D7D8FBB170A91EE0EA02D18DF1541D95BB64CC54AE8DB48E7B66A633051C04767D708C98BE328EF865431B29348D7306D389287BE9F41BB23BBD3D7A7A3C5D4C3A5F171D574B0640EE6927C1E96F2E9CD0A1BD90430D42A330C93CE66DFDC65B067D8F173EFC0EED00EF24F108B143F589AD94D0A6FC98798C1B63510734A7853D2EDF70A1918D2780C23B12CF5B1EF279604304160364651965646E0E223562381B36CD81FAB31D436F53A9D65EFB3A7EA2092CE202C1ED7FB9EA64AAB6FE7FE107424014E5AB946A3EFBAFDA9619CB7A603F11E9AE507098AFF80331075B06AC4936A711BDAAE97057E31521D5479E046EAD7E8F024E3B9C49A8A253C81A283FBFFCB0C1D896D99E881314C04FA7E0C9DF25B6166F57D97065E9166B37EF612F702E6FF1C9E81F0189E22ADD54B9F2880B23F1D3F88E120B89BEC9C699BFF18DCF870362F9B4D0F66D7416198864484393156D16A7069C0D385910DB49DC9FE8015851DC43E8B03132444BEB19B60DB6052379E5F41109354C0350A2078D397389228726C33DC492DEAD0D55DB917C6E212ACEEAE78A8530DB6A53C7A566E91E1AB62D3AA16F2736CDCD965D38D945E8A15EB68CC2B50A9C5E88F5C40B8F67AF4C36F241F3DE9EC66911937739F8F5C56C28CEC16FB453818178A3698D639A7E9A215D2F7400F5FA0772485BD75A58CA574CAC9BEF89F8F3B554A92687EEA5C6AE9651D9CEC267E13F84FB98D43FC7D24895296D78FEC1B2012F732092511930FF78664E926A57F23D3CF17BF19EEE27D833B88B6E30BF5AE5498FA55EC0D14FB127D5E6EE80560F540FBE26FD81AA62B006A139A065C11B7B48B2AB038B522168748A57DDB6C0A6CA0D7B4B79527673E58617F22F3C1B32FEFC787B41DDE9399549B0608478487126611634E5166BE7AFAEAB42F348B2691A1978CE61C753A049767A02E7055DBBFE771ECD8613B3AA29622F2FBC06F9BDCD9C94D0FB8C75310E2D4100C5248FFCDA8A898AD331BB4ECA6939FF31094F418BB8BAEC58AEF7B6FA33ED8588A21B437F4AD5EA5F2D86C4DCF1C4A559BE9B0C384AD2AA778EE93CA70989BD2ED681666CA8B082B7B83272F8A10E2D245628C8E1B5FF3BF8C5FA9C6E09C238482679888827D0E3D0B9A8CC36027649B0798E14390AD84D3D766DCEBEEB670E3560C6378F90A411196365F4FA6D332244EEF1016085C9B51614D8BF3BB44A67C906E7241213318B714824C03D9E8927AB2ADFFF50494D3F398F37E6BFAB3F8E0B89643FD220DA424BF2D751D07B5F335944462B374F297726DBBBF8C3A2D7B26BBACF192C05FF89F0878E26ACF8275644CB85C7D81022D1E85FDE63E7055E1202B85E0118687994931DE1617BA91CE9054327D3DC9DA0135DB676E9A4388DBDC3727DFCE71FCA2CEE2B2331DD836086D86C3F36767BD2F210B7B8CB1458CE8252DE845F507D78C93F7ECA7FD8CADA3DDDFEA34D2FA9AD31F10F02430C884F65346840E4CA5CC54572D6533A4E2417CF859185CA5B905BF83135BCBD88C0D86CB7C3344674F8A9A09BFD460CA828BACBE12B661459123201A5CACEBB6EF6E449B049552AEB5EA305B870055201B4686CB255E12BB1CA67DB46AED1890716672A898F71B5109A5C253276C42A22ACAEAD6E4F0798067FE983494752574A612969F1C923AD5718362E2AA1C4E5255A777DC6CBD53F553B0953BB464EBC29AA36E3F72B5C6614FAB08CC65F540D662599D45269754C0D6BE109BD7E0DF04D5EFF30000D8D6AF25B5AAD51057C31C4C134C59C3356B34638692222273144CE9D768196749FCE54DC7A7A1E2E36192FD7E756994E37D0078850E81D2D9C40670B77A02C9F708DA28CF2CCF478309B4279A6C45B9FF854A5F5B553CB291FEF5D1970883A064200D2C99597829F15DB4D9506C82154EACC4FEB0800D268902B462FE9D3284D89D83A7009AF5BDEFBCB310608151430B779A6FA4CBF6DF1E13C4A9DEE96D6BBC0CF989C48888BA58316FFA0114020B5C326D723960FC20DCFB01DC50982FD824F9512AE73E3676ED8040481CB536F851274087BFCB77A0EC7DA2BE274288D2212471DC7949EEF77A8333AABAFB57581CB43774E07F192B825F14AD564658792A0E235F4DB5EA6E3A84403492E209484542C2C2881042F54CD56CC00F2C31810EEC70D8386D0C8B7E4756A77B11563A42BC3A5D2A495D0C8278810D55EE7CB38D80C34E4DC58F0A8B1EC6E2193E6184E5F0793AB882051EBBDB3303D86F4A0E22090C7A957BE5F7BDF4652FC8F38DAC71257B2570D5B1DFA95BFEEB7E377DD581A8975D72398B4D258B1B9E7DA60217FF77BAD7008FBCCDAF7479573F9ED6BA8D13F83C233166D8D7A400F00840887BE510EAF1CF2E30B244C9EB6E166C98156C27A5FF0DB563A204B830C8FFC64D6685C9E3BF8968F3A2D2B329AA6AAB0D49EDEC26C2B5D7462AB465381D5431C85268EFB89F4E04DC660EBF4A0962F9C9F4EBB7F2A1EC5B3262DE971219FB56CF42CD720811EAF66DC2C428F94E1DE4ECE5F2116533B25E65D732A4BBD5221D28EFA946DAF52437AD6657703A9B454422C7DADEBF063E5FC433536CBA84E07F7086FE031A0A2B4DACDC99E5D3486E77D41D949EBE69E14BDF21090646CD9FF8E9F0FBF5E737DD38C0EED3D73D22A7C23AC781341109997594B3D1D4153AA1A35FF7AAD5636BFA9BE09E3329FB61950CB6DA58600E05DC2782B2EF58466AC9A4BBF6264D0D616968C6BAFC496F859EE9512072180172E91E3B581FF5CE9B8AC0624F221D111BBAAD988A530C0CADE0C4CC399EFAE9ECD624F55D93F9D0F0FC915292419ED119E177095880FBCE058783D85380F1F6673B7ED6702446098693F3FEBB9C9D7906391608453158C695D073B259518AA7DC5125B51E58A5170D1A68CF6CFC1A705B344911A63875080B4FACD9835AE85294D03EFF6D3B02888BC1D094B9E7374CAABBD1D0C32F1786B8CC12D0E4C76BC99694A1862A73ADB58A20908A601ABC4015ACC17E5B0AC28F3D8896F8BF0AA344B814D63CF558E0CED39D1F7B16D411E014BCB594F37CF18BCF46EBDEEDF1AECBD13ED97AD65A0674275868F34148D6E03E7D802258987937DBAA69215216F1CDF8BA2BCDA245D42A5D9891CF0ABC804595B320A774F1DE69F8ED595007A59F1FB570D6D024ADC97B121C28542E3043C3F99EA5EA4BE47E3DC0B66E297477537041CF880B5FAF2828E3DA2D2F9414297C59F17ED60E2DBA0502E8FE6B8E5B13FE2E945B2E78277C568082F678E4F4FF2E323D1E0AF996364E2AF2FC95C53F83953028D38BB168A1FE68C02E4477CF567DF6C2A72AF3F56EFFC99C0F5223E4CF32CA3B97C700A40803E3C91DA686DDF45A47208FC904B2384730F050A9E3440CF9A010044F7E8B6B0FEDA288F810E27AAC5DAF358046D8AE85AFB6020C22986C4788E07EFB41B2C18C482C72027673E9695CAB29FA04ABC0D7C790D3F32565A859696B6C036ACB5A6D1E444CC7D9D23B3A8FBE6E2E851914711EF790E8CBB097ACAE791825EEBA70C3AF28E6E8EFCCA38CF6B6F466D568100ECA07BF3B4B8E18EB791A2431A7FC2A795B4CDE07A38E1662044E81E85667BE36058095C7F0573D930CACEFE4C97B3393F8400451AAC6B55C5399826D8C7746BDE6484D4377BDFAD25CC5CC17C774B4623BE25184DD627CE8E6547788BD7CA2FABC9B7D4A602C457FE9EFD82B79E9322F99962FC7DAD35BFAF85A03D67DC7E83FD3C627160DC96640683AAD733B3D1EB59646A2533B99EAEA4E5CFDB2C94A8724B03FC4B72BB5BC5D90B0D4A136E44D64F3985A7EF7C6D7C55B61486CE529475F21630DD824F8AD4D3FBF0CB2C48CCC0DC27516733FF5BDC1F459B00B88883006AEDE6602DC51A316959DEBEDC0F36BBE8D017207225C1C2BD94CFC1CC60933CEA2ADE45BB4425578F4D28E0AA36DA346E2BA4B34B65BD7E71B9FCC3B52F8C425AD44B5CCD006E26857FC5BAD79D8345C5FACEAA4DC3A7C613D085826F82F10961AB2BB7C087FDB490B5A082B2F5DA5D9E6210D6E8B37ADB10DF510990F3ACD81CF93965CAAB334F1B2A76D9B17D758F273860B074B2FFFB88D9B5E6991EDBFC5FFB54325BFFC0C66092E7729C9971101D7CBF74491CC4F54D535936CBC5455E3215215E836500F411382CB8658BBB60636BAC343A645741FCD6C5E23433EFEF4F14967C5B742BDA45B2FAE1946FD0042229A1E462E172102124540CB203D58DF1EB8ADEBC4DCB37F8450DBD0FEC87CB4A56696141C9513F7D6E61BB117B0E35E1DD314837965004C6C86388C2D3EA57EA4C0CE9C563C68F5B3CA20043742BB5060935C23FC7FD5368EABE5C1A1B715B99B96E1B434229D3ADE0129AAD85710596DF9AA2D86C7EC88B9552F876861DBAD135B4EB318FC6FFBC3AF0C98EC57468A0F4BC3A29CF1625B03E33360D152B0B5F5706C169B68C7470379BA15D9188F13DFCF789C18A9DA14EAB56DB261F978D9BD894C84C1BD203A777DF785C82B87FF975BAE11437F9A243627A1715CBFFEED727B405C545542A7BED9395ADE1A671807954EAC7C9BFB8785F18D5D5C31A01320E7D863743BFC7852E251631A03EB671912F6138C21E1D62D88E1941095A8DFDF3B052A0104E72C186BFEA9CAF32B2FCA121FCF6A3D85FCBB9D7978EF2E227F321C1BD932A4DB007CB2DFE3BFD9578BD7AA6844611E4F3ED7E5370205A07B6CBBFCA7AA204D76CC8DCB9A1CB6FE6C4AFC5E5A79E59C6934D473BF834F69B89073DEC0D9ABD347B12BA21E308D42D1576F03CE4BE6EF8F07EA08CF1846C27ECEE7F8415C0FA756A540E42738892C7E6D0F90520FEAC6160911BB18BDEA2A1D925CDFBA7C585DAA3A3D27B12E4880A9B8C87B0EB5EFD7C07507D8C3B274738C90EB4A745C1AB3749ED000075E99277B927B1CAF2E19E8D588AFD3CF9BC0302724E71F129E3E3BE9D114542B16C4DB65AC8529CF95CAF7A2EED53548D1769F809F1780E5102D80B7E52B99203F5CA6F2A2A7608171190EF391A4EF5384D15C101895B5402E8D4FEA052872FBAF6DC9FFDCD3FF9EA884ABA4D90E202206E861B9785AC572A0013765C24B5E3AB9C4E31A6B7F958A4D3DE78CA4D4C097AB9AD50E588BDEC45528EC7B248BAA3BD3DF31F8FEB29F823123421388A2A021F37426188CF830BDD10C75BFFFDA15623B33F89567EBD2EC66EC7DF533CE8F33C32EBD6D074606380F37F3E9D186E4A93EB098B6EC0455843E7784A9CCC67E0326920223993CEEF7E4AE399E21993CCD078084804EAB9881B6C40CE2B20BEC97DF60381E930CBCC038A4A9153B2AF6AC6F743FE6E2FDA9A0FBD4C00D93C972333C8A8D99041D8C93718CA0CB864B5E50059D73978FA3FF33115880D43D93B8512246D82CF104A4B525F6F8B95AAB9C8DF02649497A9AAF01EB4C7EB1E232738557175E6090C2F657E9DBAD6F90860BBDEE0F701236C8489A7C200000000000000000000000000000000000511181C242D333A""") + ), + new SigVerTestCase( + TestUtils.hexDecode(""" +59B2371FE7BACC207FE1FEE88A8B3805A7052865691789BB90542FA47F7EF2B75FCA13DBA5888BEC320514DCB05FD26EB5541F6E572ECEA6C4F1D38AA70259094AA945F19FED0D980E65DBF65DB80F564FE29D836C5479288B55CF07F4E00159B6955DABDECC8C4D66AE688728BA6D5C0442F3C1232C782C465B9B7C5014B1464065CCD8A56D6B1C16510869E014E6933998EF725520B400913D93B0EC75E2FB725DC1AEC0C0CC7343B9E544BAA4D679860E347B2E947D8D2436F09298A7BB8336B9DE9CFD5CDBCD91C7249268CA03EFAC273AF52968D501406CD9C96159D7C15AA2900330C1189CFC2CD8B912C480E458297EF14DB694A3F1E72C1DFA3A3D2A8A69E011602B93020BACD1C2F3AD06C95A7F36EBF5261F6EC106816BB3303CC00BF4E8688D2E8548F10490D9EB23C56793B34B8406CBE443D8356BCD0F4F61D0D017D54831B9BA329F8948F25C3122F9DEDE8CECBA51569EDFFF895FA020862C5DF79F864078486B5FB228FD789C35FDE1C54BFFBF4A025A7FE7D8C3490A5D4E62D04F79F4183CA68379F4648BD5B2416DBE5B845C9F4B7A7E2339C0506D58539EAEA9451C9B2FE2A18C849DCA7EED9DACC058D005FB7375C4EF45B001543FC68E47DDB6D14FF937D1AA0D4D7489DFFA6210679CCCECF9B8551DCF682D2AF1E5BD869F3E8D400D5C861AE51FE7EBBB5457F2EAAFD093A9598EC721C69327C51930F4B9FFB2AA7F1A28436B6D808D75392BC43C1B5B859C66C54FA515C7A615A69E60921434AA9CF9F9E03C3CA35B5EBC6A409E822FE76E0924C6C062F1724C382FF3C8ACB5C1666C2EC26B7628E3D7C13DA8D758890E6CC017B7892582E95EDD04BA9345DF70FAD56EA68BF8875B932C28B32807C86371E17DCC04725CB597B524467963E1D4A61B5FBF9EC504D5DDB61793DD4E34AE082A5990EFCE801E938CCAE738E02E90599D971C2D7C64E5B6F8639F758ED621C1F21073C03EDB782C7A0F5D7C66F5CE161DED55B3E92DC27183AB083DBC1F3930AE56EDB8C53E9A7E020FFF0C4042F518B26F390C96C8183B79B53C7C7BC515187B3DE8CAB08769C5DD6FF5492112E8B0F28D09F4067ADB04194F60250E75ADE331A5C25593BCD92A6D1350439585860BB6FEEDBD2F839F317A01358876C88E898AC0C85378F572F23CDE931D47DE71D3353DAB1F810A61B18D24CD83DDAB8D53BA9C7B8274B0FE82AFF30C57072F643787CA1DF03B99EB57DBDA8C8EE8EB201F2847CBC9D34FD80CE6BC5E1E328EB6EFC83C4BD9D52F324E30EE4B5E86351E5C8C4C5456836D5A452203B3C372C787AE3332C8A5E9DC2197D9C341B9756BB1E63C75BBD5CF3E5CD4BF47BD1FEBC3E3710912D63032F6B97DC19C4DE196ACD9157715E2C14E054A9317BF96A684BB96CEFB7D8FDCA8AA477A2AF6F726D2CAC1A603CF1360EC11CA897E5BC735AB69B8647F30CED4947BA9F635D9CB2D82A662FF17A0E12D4D06D641EE76EB8B45C71EDE38C905C52BE76C6109F2612FEE6C3194465C19BA5D3EBCF1F0B5E534E0F0F1D31CB1E7A36C4303F283DBA8591CC609311A809E444E33A893880CDBAE29119146A368E4D2EDD91FE471647FFE821AA6D31C9FA49695EB9941B08F7BE3F06CDDF2739B8CAD2AB0DA4F5A3C0A26DF6A17B137CAAB3B919AB636D6C89BEDA3058898628721F2770315FEEE881595E24CF48B441660D0B2E9D5B90928C381F2B0FA26342E4C9B88C0887A4687124C012D969E1AFD8532754BA12125E9433DCF6D7BC1A36A83E6A10BA1CB7652A81350899C2DFC6E4FED38D009E6D0F1D44CCCB95E551B3AD54B3AC81E8BA4665EA428B3C861E8677890CF5F625C19A7C5943A9401CB78E7026BAE92B60A8B6807C17745415CD8E030C64C56E822139A35DA423F264336E0AFDF167430DD36E0064B2F6E8D8BB6BE99C5A9FB551CC63E508DB636667DDA53F611F02FCD1F99410F1A7A82882F9623ADDC50EB01E1F39978BF68506C71DBBEE42E4A80069B0E4C7FC4CC1471F4F1028DB25C4687B60DF4255DEC9148197A74796EC760A66AFC7884038651920973A69C203516222632EC5875EA6D838096E7FE9B5B4FB69C5E9407E70D27FA34B0CDBD6E119D87CE38581DF1D3E0DF3AE029042A3B20E923EBCE19A4958755EE2F98FD234C4413E2DBC93559A428DC37F2D1235BD4419B099E0F0DE542C46935991BE0692A6D80B8FD9886E0FA1769B49E8AE6307CB0BC1B49732D26E25CA1CD9D407E0D8864040941611F9333B6367E8300FD646AC5A71AD913EEFD808D5CAFBF1521A3062EC184E52165501E005556DE4DEE46F9E53D7DEF9909F3D5D98CA80D87707F7BC0FF8D879D65D4D783D196F2460693811CDF33358E082D81F4DB8F6C20486183A36D4FBCC8A1C6DA21AA4DD136E19FEF2EA993972BB9989AC1C38A79F31852178004123C46277D38A88FC1589F257332284CD8A873C25A1A6D40265B285DF09370E88F72FF70E434E8F66084CCFEBDBBC4B99EDFBC750CC5DEA63617F647F5F021D57D64D5EFF048634DB2209D7C8B82FB63B8823E4CA057168BAE88D9715291240B3758D7684501F861867B7A241C063B05D5E8CA6B4C79CB2435D7F994CB76915B4A548708B11B29449685941D43E60A8976F9A96072F91041F4C3DF7C73969012AE1B30E4B9C4E133558DABC46C103C0CB1DFB99B585374A54F9BA56B7248B8C3F66F1D55760D6ABB430375774DFBA2059C5DDDB659FD2E1DA9C3F0B80868C92BCAC10403DCD140D6A3D3F35F8EF1A2DD98DE1A4334238599EDAD920DC0AA698E9FE6106A0780C9C245F2C65A0C3E5CD5366110B1760FCD414D450DB9D76A22A9EAEA0C9FB72ED543CE9FA3314BAB17687E9DE5ADAD7561F1A5BEC16339269A87E09ACB29E4C439605E9572AA9B7D0E8371A30E41A0A7BDC02DA3A6121BF261EAA016A2074E4432CF63AF96BE81CEB6E0C2676A8545C66D2F30C98B5424F0FEF04B3C6C7064E2D2E11CBE60F85723FFC0B770D6866FFA589E3F9B2ABF75104019AA69CB58895B474A0ADE2B60A4AB077C3A6DF615334EBBE732E95220213994D3BDC443C8EF94AD515F45418355183314485857AC12BA1D62CF4FD4F4DE2A7FFF1ECF0D290C4CDFFA88D8F48C5B837D3A94CD17B3D169966EB038FE5A6E85DFC60A00233F10731973DC475D53BC7B9E60320BA7905D88519FA325DF5AB02B40F2ABBDB37D2261CB8148277B87AE3297976C80C35134E5F786904564C1469947F620FE09FDF3862C4057A3BCEF70750CB727F031283A1826F1381B3348E3EA4688609ECB193AFAAEE1CD97E4DDAA02C0C30E49F137D08285941528101759A7422AA499C900A379DD73B307284CCDDAF1FA1B0C4B280E3F9F1DB6D38ECF8A841F9D4E40ECA86247D6CD9B31EACD6A46F0E333B9E83D690D7E13467619B46AF9AFCFDC4AA9A049B180260D70D9EEDB8A533051AB83517AADC2CD900B3EA51260F464AFC5D2DC411029779B21CE2CBD160218DF41F661DA1AD95AD40B8C353C7F10FC23F830D117BCAEF8CECEBCBFA49D79D8D9391E8D08281F000A55E92DB331BDECD73183E058FF3FE5839AF50D8C55F22F6AFF5A33DA774BA1B3E643F5877CF549C4F908EA64A37DF3BFA4CD5F70F8CD154476D34BC853C9E8F7979E5F4EBB888AF761"""), + TestUtils.hexDecode(""" +4AC4675C96D9117D1EDEB80D7CD284A3E1E1FE038E301205B4C408EB965235AD1C85F8BE3F77CA486FD207F7C75F4121CD3CA2B23D6BCE4382A6D36121815025D5806CBEF452E083933C6E5C7394AC88262A6DE7770B2D8843EC101FFB5E84DE2F7A8B74E7674B3B2319BD6BF4112F92C5CFC0A55F7FA061F45325408D039D51"""), + TestUtils.hexDecode(""" +4B3F52F081B3D914BC7C6C073B182B268ADF5189E298A869BFB991B199993C1042DEF5B59270B6CD3FF8F907A1CB0D3B6FEDCA143838F8F81E0C370FFEEE6B25CD07035641A051944EAB516CFBB801536B4F262B16198E7DDB1D61C35A64D90D3948CEAAC8EE580DCEF540ED99D912BBA2BC4F5145BB949C73CCBD582613B10EAAE863ACA34683EB922B3DADFC74F76F47E4978602592402D9154394EB09FBC2EBCCC594732F2D8BC38350E5535A4412A77ADD7916604576FD6A3631E515BAF26A6F9CA4061EBBDD3BEC7179AD58552A5B508F31348A56AD1ADA7A05352C72C004B94C47E7049A10B3A59BF238A8DFC6C7019A17F05D5BFCB9D93D9D1CCBCB47F8C438098FDBDFE23F9F78BC28069908C6B9898B434CBF37787E1AF6A6B827E830E9F7629CD8F51070C4C8A8DEB260D07C3E41D8490484877491B39AA6D9E10D91748B64E33160629D8AE43EFD5F85781E69F76B6895C141EBCDDFEEB485A00BDBA4F7C991F53F2F84933926AF39E6964ABF2DFEBBC19A7E31C50797B8DA2931E10F3DAC493F198DFD785D21ADB2C062B097E889A20737F186008F2928F6B84D6E09E975A8F2AAADC785234234FDA03703A7C21F812D650BD2510B30F0550081047A155C848586A96F100D774F3E39E029B0777CD33E68318A11C1980293FAD3E787D20DFE7EEE7053C05EEB6A159BAAD4020B9EC3F537DA4DADAFB3B1BB1DBEB2D5B8F9D05A019798EAE0ED099DB066D73EE8E9A56DE368E878A7FF39140D8021D50085E6252941AB315309CB53AAA49E86347FBAD54A1F873E0CB4B86A8D5B1B2A95D485F37A9FB6105DF8440FDB8578F2624C079329569A75F36F2C55D8D030FBFEAA8889AD746C323B1AC4EC8C403E775A6FBE596E7E6A5A2863576625149940976F7CC93617B43FB13489074ECAC5BEB1A4DFE58B9AD2E0C6A15B76A7C2D208725A3123CA4E6F2C5847EE5FA8384919EF89011D219B257B3E4DC4F2095160844CAEEAFCF857260F1C63D3B05A67D3D0F2B0EC9DCC2723F13755750BAE62FCC361CFB584F774C09ADF9A0431B23E488C359C0AEF5B1C9787BD8F52B083BC9DBCC9B3039F777C7E8EABC80078050CE6D49C3BB70168FA2177298FB0A8F72C1CD28D662A07DAE6C7ACB7FB8E7FDD01DFB27C62EE683F4E5F88C7C1DDDD5EECC1C3AF853F1FF6B1D9DE672F1BF6473AF0021D8A3D4DD04A2FCA2325C721CF1C821676D0A0D574186625DE831C8411F64179F9167F78BCB22FB41C2CDB63C4DB5E138766D3803589598F114F41BA42CDB1341020449BA99656113990B4E022D8DA20D744491C6EEAB67B918E80FFF343CC5B4C8E58C3484B0125A60C36AEF763894D35148B578F417C3A98A143EDFE9F8C95BCC346C6F5EAF97AAD11DAE01C477C227A88D10ECFDCF450B37F881968027849D9B43E2BFF90C6A34AE41B8BBD743083D3C58786B036671CD6EED94DAE51F7613247EF8607ACF74A3CCE932F1C3869BDB35CA17FC6BA9F9C956FF1D4D88094325CABCE41233FB1D808EF41010396DEB0ECF50734D818DDAB70015A0ABDD1926DFA491F711AA85DA2A8EC60E3255CCF975C23CC4E8DAFDDED9FEC60A6467C45B03CA476499AA331B0E3999576CEC3191A9A62BC1BEAC1EAF20E18CFC3216127DE4AAE2E75201F9E427E39BF921150EAB949559C022D876FA242C2A845BCA7235F721B0056788A44ECC3EB98F0F502B89F8E7410EA5679AE7C0434F13AD816421D2FEE30CBCB2DAA6B851CD1B6E996DA7A757E4C4D8572C8B600DE85DDB65320D1CB71D9378349C0C401AD4F9E91272139228A8DA2F4FD2F48891A4DCB066D501D447483B611BB3C80550A90EA0B732D639D8B3926B6E7C35453ED3CC110BAF556CF46D8FC2177E76FB2663B8BDD171E94C0ACAF25B9153B22BCA749916756FB3ED3018E0944B6C3B9B6BFA15B9BE803AC79333CD2C3A27A26BC17CDA257798AE16B28B463B6DF3FA87C2D742D0F6885BEE0BEC6E20D01E5DADC86823E92D60FEC79B0D240248753E42048384C804289604821A57F4F9F50AE0C38527FE5A34938DDBCDCD9A1D020839BEBB62F9F41FBA08052ABB82FADA884CBE563791103AA585546EBFEB11272CC2E87A3B75B3C6BB1853AE7F9CF5585B2653CF5EEA244D204EB269C56A20985160659CB0725EE13CE35D55EB095A53414F232DF8108B18024EB0DBF345EB5CDAD0BCE7263509A341D54A7D534E553EAEFFE4E242EA23BCFE59A58A60425882CB7E3B0C9E4AFE8698E3DF56AFD6D611E9168747D8735CF9246D94F2126BE727FB42B2241A83B34F0B9EB47938D726502C54E4572766331628FA5CDA893C35376AB4538FF8717C2795B0F51F08E1137612B89B0C1E2CD1F099E88556923AE57A1DAD2AFB1230B5094A1B21BAD7DBBC333A97F179304718F3289B6DE31315B74C1A73AC7756FAA4D7EB568BBC6F7E788CD089B395564D2176B0056DFFE952C7748B048306720F602B67E8F6ADCC91F8E3AA4B8C4D7FAC233AAF93653AD2209E2FF92DA30C2D53FDEF6F4C90EAA0DE60D594ADA3915DB24279D867476EAD757B4C0264A1DB8A1F57A1B5D7173BB1A960CE02FDEFEF160D512667D655268FCC3A153A4314782A0EBFF84F65F14A0E3E12A13250C07D08C225B11A6831BC25C40467B768004DDE0E874A51144C18920BDF286090B59F51564EA4070FBBF61E3696435F28F63332B64496DF3EC8B65D54E1CF4789DDAB122DA6B264D312A711C129E3B07F4C6DA25A56173AF58B90A71B7ACFA3161A81F59D17914C99BBAC4F9A314977A89CEF7696943609BB4827964FB2976403BD4996F1E842BF5AAAE1ECCA11255B9E6001C20F72F1FD5E32CDA32D8A7AC5F62B09A0E615847CA746F489515CF8F183162859F53B97E9E5CA800EE624F729843A0009164A4A9FF76EB34E4704184848A139AD97D909F7A7ED114F087A4B2E1B4A3032391160B6F3A3649FF15AEA2B7107AF8A3B5FCAD61D43D602E6286A900870CC8CE24E39E78F0397A0D7E27E8E2D4776A44CBA218EBCD88B3C28C182A7C9F4DBB2DBB5E981563D66CEEB77E7F9034BD429D27637CF797DE82E01FEBBCE2171EFD016E402A42D78EA1ACE2CB370E75C90ADFA1A793B2169CC26522DB2F546AC1DE34C9087120C42A9F10C00D493C25730166F9D219FBDAD222C8B28115543313210848FB2F04BFDCE15D320C3634A8E4D63755515900C75BFD090AD78DD588659FBF97C96E0D0ACC8E815E608F9E861D79AF3051B942B52570B6292BF48C2BFAA9077DC76FE902683217B8BF809ED7A0050ADDBB65FDDFBD24019C9181B5AC81566113D6694EA6291D7F4A7F56A41EB91F76368DF82B164B4859259D7189240F1D8803F8107296D378BAB4D24FE6D10EF788367BCE16C5AB77FBC168B857F7BA5CDCBE5067C864F879809FE5217DEF0294BFAFDF809ABCE9532DD9DAB3448F4DA68ECA51609476278EB8C4F69EA29673F69418041D26857EBC24A487BB4B0BA63AF848545EE9BE89F139D502099B9D35DB3807B925CBA576E27170EAEC48CC2CC15B043677825D0EE81EB2CEE3A8ED14A798B879530220E50CE8C003A305382A24D23C277B99D1F4C54F9A8D33FA3D1E337E18D7CBBA5E5A47F2D5E096CF4551B23B1B86436E81B4A09D1E3D38492EC8B2A00967016AB76B9A9B1864671421DA56F57D008D5CE1B892A7E9C1F69F6C722CF109DB500E53F6BC07837AD1CD4CF4A64DA763B4A9C4929B0DCDDF7C7E1186BE3FF0C321158437820C81E74FF316AE3254E972FC197A7F0E620242AC05A4E43E987C2A8355B0357745CA79E6AE48AB29ED4FA63D3A1F19B999DE251FDE0640DD87876D55762878AD1DB12D65BAFD14B6A9A7081BF23F9F06D90CE273C5A26E012CA94DD481D32E10938C165163E89BE8A93A63034D345B74E2A94EF643D06AF9E1F5C9F104930DA00E61E061EE8C3BB17C11E05D45C1682E4D593C9198238D2BA289779E7D0F227BCB0B09972B19770FF011BF6C60D9D193CFAB32747A0095E1A4AD32514C782EF3DE7A26EA771F5530D9DE9736D0F6AE1AFB78EC7CE4884A1BB436CFCE459CD99358260906AAC99716A536CC7687A0375FDA11007618E553534E54D5B214F7AA6FC7DBE37C2BD2B64850AE469A9858987F3FA4B1FD26D954BFEC365DBE06DDCD615E1FED58A88676402D1D6B581485498B5ADFFFC42D47D61DF99384E22C5157F0178A6FDAF8F4A9491DAF298B2C3EC88085022C0A7CF245ED0FB5A38CD16F30D37DA5C4959A55501DAD50F1B48BBBDD86AB8BB522A936DDF0003B81BE16231A04E7A589C56FFFB51B07927B4AFA1DB7D48BC6FBC3F3675637184B7ADB9BADF4DE7C085BCA1D428DC9FC8277CBD85884A5921B52BB05B710615508261BB4546BD6E1FC730D16B049EA12798CE2E6DF43F5B8F3EF9AC8FBAE31B011E10C4FC62FFD7F39D16EC32CA8210ED16E041DA43D9274229514054A0F82D462FE080C6FFD7BBDBFBF0BFFC6D5ECC432A3256C0BE0DDFD5D9080C676C7955D66E44D1CE51FCC2382F868D732E85851721B48A01D08C639626EE0509CB581EFF5628FA6CCD1089AC0E12DEBE0851782E64C5049CBD6501013965CC0CA25ACAB176EF7CAB92940985DDB49021DF6C60D6C4A489116311E86BA19EDF00D74797358207CDE50506D007FE03C8804C66451F02A0182D387B759894096F65232952D183DBAAABB6BC0E191DC2C3F75FC72BD61BAB2EF19B6532B231C4AFB1A9C2CB2F3D6C451E8440D6A923CF72A63E2ED8554773887910CA5C671AD4FD5923CB95EC73FFDFBDA4B6655F55DBFD1317D024422301ED66A6E4C672085CED1F4C7B05030A100C4788FEF4CD3E494A853BDE63E9D449AE3BB6BA1083238DA3F4090515D143C67DBE53D8D507A5229FFEB2072D0BD092FC9AE52DEAAACD1F0F14B5AC84752BFD0025E5F55B869350F4B2719C5C05AC1669BB0FD3C614ACE02A270613FD3309706DDCD5B1A6AD26F359ADA80B30E50A7E50BBD3AA45D0654DD7D058B0BBF4D0D92135142214EE70511F3676AE643B5F245063B9419CF6B49FD647F27D7C41C866E6CAD9D5E2E3E331BF6B9F72ACA329BB64259C3E79783A26674B7D38EBDE8318411F4764EBDC4C7E41ACFF85BBB30318D59C42C9203ABD6636BA3F772B6725121C052DE99910D55158C6F3EF8BB7FEDE2F81E58A7AEB25E2E46FD7232302FAFA8FC37FC8B55D594B76EC4A53EB11EB3FD634428AAA5D86F839D089ABE2FEFE2AE5262FEFC7348D836692EDB215D6F8F548B885290C2403C51C3E269D493FBD339B5DFB0A38EEDA7754DAFFA16E5BCA5A9BBDE04B014B7AEA8988F3749D52D2FC1C9F7C7B2C2D692E7896E4C34F57C558CFE8317A8374409D566879A08628F644FB45B818455BCA6042B4E6187C1DD177E9E5146319904B1505F3EE00CD7FEAF0E83C3024956F77659ACC56D8D917A37E8FF7EB88713CCA334EA04B8E258C9345DA9DE26A0A366519451E1012DE6AABF4697C9DE821D70021C3250A106CF4C23A1B1785F549D3C8CD71B05FEA753E0046A3AE0A9B1F40277CF453A2BA14CBA923CC6269706DFFFD517C1E5930079912E05A5571897A06865516C86699F707E00CB38CE193490AEE30BA47DDDF3A5B4FBCEBA73DC13D0A160EA642D30D63A02964EDFDB2F29DCD32CA9974F89C32D1FA9A83C94A2770FCFCF86E64646882BD550DDD65B4E2D287AF6C196F42DBD39B020D7CDFBB6E6E75FFAAB26099EC1D25E3234F70DD972286AEA0C3436595FE49FCA898BFA421604C82D3E94856D186905076D186C684174BF4290DF31769EDC97A1DF2DFED03CF45CE678C8A1429EB978D02A79D4F8CF0168DAAB482C6C612F04B1C93637FE77B302CEFA788C11356C52C54F37A9DCFDA55927A8EF0A0CEA7CC4ADCEE459EB64DF08ED0FC29FDC3C7B762B399332063340D473966219BFC87B4A3C91C80F0E4BA86AA1879C76625C8680A227AB22780659D4B5D30E0E9A0DCE094DAF537679273A9B277ED2A2E250EEA0938204C9E963D338522A3D1A4440E2A12397A5B97D35657307BEC94CC0C72C5C6B09DAF2BAF0020B7D8CA560BF6596929AC8D4E5460F7837B41B4AE6FF12339DB8EBD7028AACFE0B42E02CDE906783ABFF694E7CBE0897ED6ED438ACDB00A4709CFEF7150EBEB08C8FF6C1543815F4B8951C3CACE499586458A73C8572389AFC9703A7FEAF673445FB4B0CCAA511D4A2CF463F57E3A6D72DA04B256699A30212E7C5768EFC151B71744156575A2E9443319232D159C6CC006FDB57C58173AD8D2C866C8887437C223888E21EF67E1A332C1FDFCC15EF17476FE0FB57D4229894725E1474C1BA1216562817F16C53ECE01C7F9E3664EEDBBA94952987431AA2A57D330EB11B28E6BF770E349ECE350C83E90DA6FE0D0A4AB9715DB28BDD397FAFA1428302151E1F222B4469879EB5D0F018606A7594BFC82C394E91B9264495C9063D505262799B9FCBE6316BBCC8D8093053636A74D4FA000000000000000000000000000000000000000000020F161B1F292E36""") + ), + new SigVerTestCase( + TestUtils.hexDecode(""" +59B2371FE7BACC207FE1FEE88A8B3805A7052865691789BB90542FA47F7EF2B75FCA13DBA5888BEC320514DCB05FD26EB5541F6E572ECEA6C4F1D38AA70259094AA945F19FED0D980E65DBF65DB80F564FE29D836C5479288B55CF07F4E00159B6955DABDECC8C4D66AE688728BA6D5C0442F3C1232C782C465B9B7C5014B1464065CCD8A56D6B1C16510869E014E6933998EF725520B400913D93B0EC75E2FB725DC1AEC0C0CC7343B9E544BAA4D679860E347B2E947D8D2436F09298A7BB8336B9DE9CFD5CDBCD91C7249268CA03EFAC273AF52968D501406CD9C96159D7C15AA2900330C1189CFC2CD8B912C480E458297EF14DB694A3F1E72C1DFA3A3D2A8A69E011602B93020BACD1C2F3AD06C95A7F36EBF5261F6EC106816BB3303CC00BF4E8688D2E8548F10490D9EB23C56793B34B8406CBE443D8356BCD0F4F61D0D017D54831B9BA329F8948F25C3122F9DEDE8CECBA51569EDFFF895FA020862C5DF79F864078486B5FB228FD789C35FDE1C54BFFBF4A025A7FE7D8C3490A5D4E62D04F79F4183CA68379F4648BD5B2416DBE5B845C9F4B7A7E2339C0506D58539EAEA9451C9B2FE2A18C849DCA7EED9DACC058D005FB7375C4EF45B001543FC68E47DDB6D14FF937D1AA0D4D7489DFFA6210679CCCECF9B8551DCF682D2AF1E5BD869F3E8D400D5C861AE51FE7EBBB5457F2EAAFD093A9598EC721C69327C51930F4B9FFB2AA7F1A28436B6D808D75392BC43C1B5B859C66C54FA515C7A615A69E60921434AA9CF9F9E03C3CA35B5EBC6A409E822FE76E0924C6C062F1724C382FF3C8ACB5C1666C2EC26B7628E3D7C13DA8D758890E6CC017B7892582E95EDD04BA9345DF70FAD56EA68BF8875B932C28B32807C86371E17DCC04725CB597B524467963E1D4A61B5FBF9EC504D5DDB61793DD4E34AE082A5990EFCE801E938CCAE738E02E90599D971C2D7C64E5B6F8639F758ED621C1F21073C03EDB782C7A0F5D7C66F5CE161DED55B3E92DC27183AB083DBC1F3930AE56EDB8C53E9A7E020FFF0C4042F518B26F390C96C8183B79B53C7C7BC515187B3DE8CAB08769C5DD6FF5492112E8B0F28D09F4067ADB04194F60250E75ADE331A5C25593BCD92A6D1350439585860BB6FEEDBD2F839F317A01358876C88E898AC0C85378F572F23CDE931D47DE71D3353DAB1F810A61B18D24CD83DDAB8D53BA9C7B8274B0FE82AFF30C57072F643787CA1DF03B99EB57DBDA8C8EE8EB201F2847CBC9D34FD80CE6BC5E1E328EB6EFC83C4BD9D52F324E30EE4B5E86351E5C8C4C5456836D5A452203B3C372C787AE3332C8A5E9DC2197D9C341B9756BB1E63C75BBD5CF3E5CD4BF47BD1FEBC3E3710912D63032F6B97DC19C4DE196ACD9157715E2C14E054A9317BF96A684BB96CEFB7D8FDCA8AA477A2AF6F726D2CAC1A603CF1360EC11CA897E5BC735AB69B8647F30CED4947BA9F635D9CB2D82A662FF17A0E12D4D06D641EE76EB8B45C71EDE38C905C52BE76C6109F2612FEE6C3194465C19BA5D3EBCF1F0B5E534E0F0F1D31CB1E7A36C4303F283DBA8591CC609311A809E444E33A893880CDBAE29119146A368E4D2EDD91FE471647FFE821AA6D31C9FA49695EB9941B08F7BE3F06CDDF2739B8CAD2AB0DA4F5A3C0A26DF6A17B137CAAB3B919AB636D6C89BEDA3058898628721F2770315FEEE881595E24CF48B441660D0B2E9D5B90928C381F2B0FA26342E4C9B88C0887A4687124C012D969E1AFD8532754BA12125E9433DCF6D7BC1A36A83E6A10BA1CB7652A81350899C2DFC6E4FED38D009E6D0F1D44CCCB95E551B3AD54B3AC81E8BA4665EA428B3C861E8677890CF5F625C19A7C5943A9401CB78E7026BAE92B60A8B6807C17745415CD8E030C64C56E822139A35DA423F264336E0AFDF167430DD36E0064B2F6E8D8BB6BE99C5A9FB551CC63E508DB636667DDA53F611F02FCD1F99410F1A7A82882F9623ADDC50EB01E1F39978BF68506C71DBBEE42E4A80069B0E4C7FC4CC1471F4F1028DB25C4687B60DF4255DEC9148197A74796EC760A66AFC7884038651920973A69C203516222632EC5875EA6D838096E7FE9B5B4FB69C5E9407E70D27FA34B0CDBD6E119D87CE38581DF1D3E0DF3AE029042A3B20E923EBCE19A4958755EE2F98FD234C4413E2DBC93559A428DC37F2D1235BD4419B099E0F0DE542C46935991BE0692A6D80B8FD9886E0FA1769B49E8AE6307CB0BC1B49732D26E25CA1CD9D407E0D8864040941611F9333B6367E8300FD646AC5A71AD913EEFD808D5CAFBF1521A3062EC184E52165501E005556DE4DEE46F9E53D7DEF9909F3D5D98CA80D87707F7BC0FF8D879D65D4D783D196F2460693811CDF33358E082D81F4DB8F6C20486183A36D4FBCC8A1C6DA21AA4DD136E19FEF2EA993972BB9989AC1C38A79F31852178004123C46277D38A88FC1589F257332284CD8A873C25A1A6D40265B285DF09370E88F72FF70E434E8F66084CCFEBDBBC4B99EDFBC750CC5DEA63617F647F5F021D57D64D5EFF048634DB2209D7C8B82FB63B8823E4CA057168BAE88D9715291240B3758D7684501F861867B7A241C063B05D5E8CA6B4C79CB2435D7F994CB76915B4A548708B11B29449685941D43E60A8976F9A96072F91041F4C3DF7C73969012AE1B30E4B9C4E133558DABC46C103C0CB1DFB99B585374A54F9BA56B7248B8C3F66F1D55760D6ABB430375774DFBA2059C5DDDB659FD2E1DA9C3F0B80868C92BCAC10403DCD140D6A3D3F35F8EF1A2DD98DE1A4334238599EDAD920DC0AA698E9FE6106A0780C9C245F2C65A0C3E5CD5366110B1760FCD414D450DB9D76A22A9EAEA0C9FB72ED543CE9FA3314BAB17687E9DE5ADAD7561F1A5BEC16339269A87E09ACB29E4C439605E9572AA9B7D0E8371A30E41A0A7BDC02DA3A6121BF261EAA016A2074E4432CF63AF96BE81CEB6E0C2676A8545C66D2F30C98B5424F0FEF04B3C6C7064E2D2E11CBE60F85723FFC0B770D6866FFA589E3F9B2ABF75104019AA69CB58895B474A0ADE2B60A4AB077C3A6DF615334EBBE732E95220213994D3BDC443C8EF94AD515F45418355183314485857AC12BA1D62CF4FD4F4DE2A7FFF1ECF0D290C4CDFFA88D8F48C5B837D3A94CD17B3D169966EB038FE5A6E85DFC60A00233F10731973DC475D53BC7B9E60320BA7905D88519FA325DF5AB02B40F2ABBDB37D2261CB8148277B87AE3297976C80C35134E5F786904564C1469947F620FE09FDF3862C4057A3BCEF70750CB727F031283A1826F1381B3348E3EA4688609ECB193AFAAEE1CD97E4DDAA02C0C30E49F137D08285941528101759A7422AA499C900A379DD73B307284CCDDAF1FA1B0C4B280E3F9F1DB6D38ECF8A841F9D4E40ECA86247D6CD9B31EACD6A46F0E333B9E83D690D7E13467619B46AF9AFCFDC4AA9A049B180260D70D9EEDB8A533051AB83517AADC2CD900B3EA51260F464AFC5D2DC411029779B21CE2CBD160218DF41F661DA1AD95AD40B8C353C7F10FC23F830D117BCAEF8CECEBCBFA49D79D8D9391E8D08281F000A55E92DB331BDECD73183E058FF3FE5839AF50D8C55F22F6AFF5A33DA774BA1B3E643F5877CF549C4F908EA64A37DF3BFA4CD5F70F8CD154476D34BC853C9E8F7979E5F4EBB888AF761"""), + TestUtils.hexDecode(""" +EA707F27A8896AA860FDF5D5897B58538D1CB6096CDF2AD5F583C5D4FCC2C91839C1AD44920216F8D027AAEE2E563D779E86FAC4B2502497B41229BE823ACF0BEB232CC6F3F7DA88E0685A9176DFE71E42470FCCCDB43C6688A03B6D8AF6612AB821CD16757FBEAE52C779EFB6AC38EF7FB4B5E365882CB83AA246B2A52D5059"""), + TestUtils.hexDecode(""" +372BF9FD2061BD26939A23C3DB128746EA3346F0C0E75C4C358405C12CAC9636D241A5E555ADF1B8C448152326F9248EBE31E8C171B3CE7C0079610C6C715BF8DA26F4344C0F043EAE26E749E56BAA190E502BCBE70740A8CDED41CF2FAB99AF00A6D788FF05C30CB8B9ACC125FEAC8C7CDFC1DD7226C819BE3A237BEE81FDA6B1DEBB83207B53BBD1E3FE07D3919AA9B3505F3DA78B7AF7A61979B9C8290563B7ADFB676D06C7AAF545452D3D7C9262AD40456D0333B362A68207D0273F488AA60F87543B4E4F4B0BFA36AAB42D523AC1D6691B680C673832888480CFF337B1590A8544A3663515198481B17D0839944754E14D565A8C32CA1D2BD4863EAEE16AC0BF8D52EFAA731CDB0A3A25D2583424F0F57E08E2018247B610F843B1ACBC54B3AE0E880B994254B4DADD9652EF5E36D3F1CCAE76DB8FF110CB3AEF24EA7B00E32278A05267C3A3319EB58E92172DC5C7EE748739C5E19AE54F7A8D714CA642958B820CF8C71F20E03730641CBCAD74E1956A1C50562E27F21FB03F44A3F032519E2E20577D4611764159405D7BB138F34126A4E5C8B3AC1A8F19817061BFE1C50A8A6767053677F1B507D70B56BAECB8BBE2F54DAACC13AD373020C13B103D2079B140ACD18D3824C03205C6198AC1603CE63602EE853B08395BC749B0DA7ACCA6DE54D1D742442C81ADA46C3A21F8F8B4A1E3C212315E6D19D290D139E70C037D4E64D3630996606E443414A371A96B19433B1DB4B5EE677113DE2005ABB42CC8DF12C33DC7791FC7AEE807E7946B023FE451ED32FF21ECA246AF26B535A11B4C6F380EF56DBFFF984ED15818EEB08578D045F2FCF39C3CB456C73EFB76C66AA09E6F9458AF39BC5A9E1E9D6E8826AD3ED681DE22E9AEE77FAACE34385376EFFA306098EDDF4F122106EEBDF32AC04884554BE6945753E6B831FAF701B4AEA4F48A8D490BDCF33B0E1630C94F756A1C565D2554F5081EE3B4EA5C33EAE04F06BD44CA0D0671708E9392EEB6C4EB80AE8A17911B27CAC8980A87A3ADD2F5E2FEC71FF711D89A6F96EA423411E81B292668F60AF44F0CC83BCF835E78F2F6BC503F54C2C6CE827D97023B98F23A85D269238013F29E9AE8BE2FB54C9AA69BB6FCCD96916918B8E534D3CDFE506A2AE474B59589CCC730A0A857BEE1F4CFAD0433BA4D34E8888FE2785A7B6331C1CE3F66E0DCC2F801C112DEE85EB869567C387305922B252073023259E1C042D3A245D141DFB0F2A1A5CE0FB772B12A0AD875DE56A8A0151891D4D4D2E2DD4E025D8BA25E63E44AD8798D495CD099B57CF73623A2FBEDBCAF1ECEE43AA0882E553F5058C50AD9C4FFCC59D93F51DA653DDDA17B14EF03D86EE7234A3808B54A1BAB7FE12154816735D62BF3ED4CA9C180D6BC050EA3937EBA6F8AEB4A7811A7307FC7A0BDB24360AA517A2333FE86CFD05E5924923AD390E6F0DC4E757AC78A754BC6B3C15954674F4AD41D05007BB984C89C198C4E4109683BFD1A1E59FD8CA36040090764B81A747ED14CED83ABE341473BCBA6B5629044DB6CCD65CF6DE91C91AC20875565440194FDB3D21CA637E019636B44F69D578C1E1CB12312FB109242C228B02A70FF001095801CC2D308A5E802C34B102F174C6C0A44D14A76B9D82D8B97C01205BDB22AEA9B2F0DE6507C0FADD1321BA71157C203DFF28207B5CD7AE18923DAB57AE263BD26A97210DAC238427857AFF7639195EC13CB74D511B40A5C5855E1EC1223B6B44C5B630AD94050B573FDF919FEA24AEAE8095AA8136D15294D876D1ACA1F862B038F35265BE879A0F1FCCE07FB76884DDE073E73785B46DC0EC95B7859594119D272CBDCEC3FFF7A1AF8B5076C977B76C7FD640B834B92066257EEF27ECA1699A7BE3ADD1746624C27256BFF5F9177C01147585D1D5CBF576F381DD6DF2320F24293F32BAD164E474CE9C741EF87302331AA9B67D64E95527C4BCFB601699D68F1F712222BF00262BF4AE8C49E098A8EADD108288EC0995D068315CE39C6429CCCB00E1D94477B76D866AD7B7968B5AA98A590782354EA512344FE58290DB10717E5C6102BC7EDC1CF85D634439D5D82C1B5A2A9928FE389BDBE4FE9AA859DCCDE68392AD6B35F516AEA70220B0D6DD2A91239EBC0D15B5930937207E0CC5AFD925A4B8BF5A0A4DB25BF87294CCD7E148684F331508A752386A0811B606B91283D865B58B347084CC01C874C046861ED3FD8DF8C5B07E8A2F27176685A39A9BCD955645F1EA58B4811DFBA16C98BA52BC0EA443D592756B00CC4CA428511A7F8051E94C5C273CC6E8652F3E9132E0ABB003C31DC61A8802D2CA650EC0B5AF5BC3E983C2746F4747AEB1F6624F010C5104F7A577E58D5D527CA58BC838C60049C99270A66C846258D32A5A5E4245088E7C6F824671AC80571DEFB07A21B64A688100F0BCC7F28B985DD9B0A1F6780B561BAA8616909555E6BF656F1E02691EF83E475E90FCE338195A88FC1DF0864B5375496B5D8FCEED265163ED2EDA2CE6CAEF6583800F225084662591706E1F8AACE331689219268A591379219CEAEF219A02CA85AFED70C96CDC7B50905EB6C2BD0E1B09DB19CC8728EB108123228628212EC1A591148DEDCEB7F4938F0A99B727B79F230BFB96B82E03AD90B6EF858CB899AA2549E0FB1E8919AADE94580A530479C140641D6620676927DFCE0DC4374AF05B379AEDAF0BFAFB0A4EF6FE04E2CD93DC6F0F4B8B680804F296FF8703219988FFD69110830F3C66555A33026EB524E75F9D4AAAFD385BEAF64BB448B2CAF9546ED326E0690948EC06BC7FC9204315D68161EAC551F228373C86BE56208DAFF85C71053355C6FBC677C87E1BEEB1D0F03B8B77F86315F98CBB8FE07B17762D9FA93E484A6E991D616E95476FCF1EF1659DAE67FA92A30CE609127DFA818CB109B5C33615BFDC647B7CB8F74581BC90EA05071E7F4E542EC1940D0E8B0BA4772DC4AB89A3F0989BD4EECC4D026BACDB44AAC9524828EE59DA8F9AEA5323F54FA60633F676B4A6537BAEDAD0B8492695D7333AFFD413DB2134328568B5B7B892585ECE9E5618F7573F014EACD05289DE2404E2A2B7CAE0E79E7AC7AFFA74CAE66B956A7F6BD9FEC4D4E10F3ED7CDD8433A35D785CA2217C5D963A29E9389928FBC1BF380E37CF1242C47342B58AF18CF83F209CD1932378C02538A5C07D369120B3B493B28AC4202971A0D2C7ED6B65E3098107ED5B20BBFF10ADBB33710DC13064C1ED6A289559FF7CC3CE77FD7A7C8701D4F9606FBC7E554E0047883EC6CD106616BF8CB821E0D17792622310BD3FDA8C5C7088C395C6272D8BF06F8F33DB65333F097211A05E2DA3E07FD05331241DD2A1DB878124F57237F5DFFC021263197B10B9352B6BA8061C58BC1BEF2DF186C376E3059862CD9AE36DEEFE6F8DC72D43BD043DAFBD54FBBB93EE72D0E792BCA927E785C9330E79C39581F408A4DA9CB0B4FEEDEB5DD9D8DBF08A736C0418284C41E9195EC680D5A9B56843E87DD76A7519CF03C5A447E407386FA81A38FDCAB479F7F239202DA95D64EA059C05DBE730A5AC672FD3D7C854FE0DDED4340F4FF0E7536F640ABBF7FB1E12DDC7CEEA34FD46BC24918A52EA55FA6FB1B91456932BA95897C92CF3B805994EA5B4C7FA069135F19CBA85E3BB73F55336A9B6113B798BCD3758E1CBBE09E7207345B6DAC55E358C60B6C9768AE2E6DDC15CBBE058B6EC06F1E99D4797E66AB0935B340D392A4C4726D8265B9C5D58B0C7FC77B367495D81518492650D37EB852E8B4672453330E30727F200646E6BDD6D70CE290739A06081F433E27D87C09ADD00E217CAEC0CAA9493AA681C777307E70EEF7184FD658F4B77B88FFDFF539E9284047787AB974CAD538FED6AFB978A38959D02217774C1B3BBCF36C805C17AC104EB27AD4E40A3F46BA2B08ADC30B713F224C18D13F83CC60B59CFBCBFE0E7864BC7A7CAD976D3BDB8CF71DD5888169E85639304D759BBF6FE7C3C6CBEBEEDA02E819A4DCBA188407295AB2D885B34EE22572518BFC0E9749192A839CC08D4A160794AE52113AA94A09258DF03A7A4DCA3EDEF6CCDC720A780DDB561B319B574F2A22A15341746B4DD6281328B3667786AF8B729C135BA418DEC122D3E119F3950FD6ADB0B0C773B90ADBC4B9E8B27043BC5D287BA5B92727FF4759F4F64B620BB226646F08414A0513F72FAA4401E371465EC7E6F4A867A47183ACD434159BBE352FE1C2D8E30BB3D7E08E25D15F1C3D996C811B9AD35A8D5B4B6D0A9A606895E4044E9ADB7A6427DF47C48614C6431F72897E5052B878996C520E9D33AF693BC69F879B8BE87BAE0564701438A51CCFAA342663927F9B2D2271ADA3CF44D8C4016020368C25FD56CECC6EE192734753D66A97E13C2327AC71E5726560D4800B26C604F1A9629F451454C86B6F5AF4CC3419AAA120BCF19671D577927E1A88185D0457DBAEE168A9A45F9BDF0DEE2A35D5E66C2DDA27D6B4EA492BB88D4EEC6CB68B23FA2338530009D9C9CD1041BB0592E83EBA03D39C7FDCEAB5C1654470399E6B85E63616CA705FDA4EAAECA06AB3F87857F15D2EBA75A3A2EEC060177F74009F5943244913E1959820D0D92A0C2AF7844881BD408F4A0CAD81AD6EC9243C8CBA108C8F58A23D5971807233173F1B98AB5C3C73B72706131C9AE644F46FDA74839D497236F152D15B97B93BCC9ACF405C1A1CEDDB9C2F03CE111977426D3438F929219E859CFF3EAFB5D2BBE48E00DF7A4B627E181A8982A3D0E640677B6F3B419B5E2AEC12B8E306253236B5D3B0C7252C2D2F7637610F07094570431E129FC23B631DAA0B6A2A6CB3C75FF8D2ED1CB906EA9CBB20956306E4EA261E10DF1FB7B3FE1D63CA8EA742104DC678AB572D0792DE89CEBFAC8E541E91CF2F7E8CF7A767365FB99A57D2C259DECB1957EF6AFAEDAAD93AB7DBBDD7341C73AC40D25161A103888C8CA74CA0EB52E195848A006E872D0BE5F5A6B5E972444E925B5DA4A3F8F81AA168B836F17F38977ECC7AF48839978A1EAD106E0C3A8A715C86448E9CF4D23703273F4CF00FCA36DAF8834DCD97655B95E6ACF495D4CFC9A7F7D5499260794107B331BFBBD211021B9B7E4C9F947BB9D338C6385B9BF73F0FF6C97C7BD8EA33228EE939BB17E11B3C9D182F818055F753C5356C5BF371E21EAF1CF14B0CE8E3EBFEEB28010DA0B7EA9E0A4285E435FC06B70F4E6DE1DA12D871C3BC8D0C884A7A99DCF2A2C8561CD445B852ADE1A11217A9658D210050AEED89DC18D71D7906389D4056E7DF99DAA462D4C77E7F93874883F33BD13BBBB5E1AA8CB86A981B5491DFCFE2B474F63EB68D923F2D43FDC21E9A56A535347C021B65E54D7935B8EBC249903C7BDC69419E683F3E1BA7450DBEB2F175E2A5593A202543E0655B909D6614290DF1792FCD7B17CDBDFF0E9121D185A082EDBB630369AECBA8C6D4C642ED0AA644832A234DBD48B4C6D8037BF97AFB75626FF28EE1206DA462ED05FF43B23D98D1790106D88C3103232B82DFEDD8B62C8006E2717C921C1695E49B742281AF1CC870CDACA295F867BD72BDAC03CFF02D406A1DD6C3A3E59E8DCF93A5BD54ABB022F9952EF1906FA66ADD7124AC3CB35209BA7958C246AE6AAEF91C5C85F844AFA38335AB67C0735F634203AACA2272994B719B655629E54537A1E75B316E22FCAE758EC85D4D968CB3242510CCBAEAE4AAEC63303EA8E1DB841893CA1BEA38EF797C756A2A75D8C7A823C2DA46FB9996C3C2BA27E19BC5D23005D97BE4D2B899CBD0748811D6E920D535BA9BBA33C4D08868E70AAB6731982181C784EA4D4CFF1D20137645CAEACB27D295F14334D102A5508DD586CDFCE93CFE4D6B5B948D16AC6363B4DF5D7DA3E61D9E0966BD23D46B2263277363524437F18FDCC302540A58823990DF6A6214CBE9FD47F336534E89BC307FB0B030FF063748DEE749FC7907F78588DE4E099CE3D9DBC4ED4F254E7B4B297F5A11999450E485B462C83E9D6519FA1BA4FA39B25D195ADC14C1B862DB6A2222FEC7A4DD09A5472410758B85AA8AC57BDFC80BB4786B2A5C3091B7D24B6854EBACFAA87FA6895E81554AE08D5EF4B3144F872CA9644FD8E7A0C613CFEA146275A72CA3F68AA2F67FF49ECA257FD912F48C6637473EEBADAFBEECB7019B99FD5FA050811ACC255F02307835771417C782D43497C7D2B39B00220396E3C5B02696A16AE562E2E57D227E71502A3DE95D88BF98492035DAE2D468795DA1C32DE795717D43B1BB0DED8C450C34CEEC27AB138D303A083980F535D9F63EEF8D8200A52EE84802B5C6D4CB14D75CC8A719202363F97878B3E719FB607897C49752875A4C9CA7CAAD5511DB6523AFDF0CEF8BCFD96AB239044FB53EEBF3A70001C62E9B86E1A604709082330081EE7538C474D94B0C5FB2664787C85CCED00080E1349869EA6AACDF321546FE415268A8D9195B6C8DDEB337887A9BCE20C2C4178B2C2CAD9386F7C000000000000000000000000000000000000000000050C171B252B3336""") + ), + new SigVerTestCase( + TestUtils.hexDecode(""" +59B2371FE7BACC207FE1FEE88A8B3805A7052865691789BB90542FA47F7EF2B75FCA13DBA5888BEC320514DCB05FD26EB5541F6E572ECEA6C4F1D38AA70259094AA945F19FED0D980E65DBF65DB80F564FE29D836C5479288B55CF07F4E00159B6955DABDECC8C4D66AE688728BA6D5C0442F3C1232C782C465B9B7C5014B1464065CCD8A56D6B1C16510869E014E6933998EF725520B400913D93B0EC75E2FB725DC1AEC0C0CC7343B9E544BAA4D679860E347B2E947D8D2436F09298A7BB8336B9DE9CFD5CDBCD91C7249268CA03EFAC273AF52968D501406CD9C96159D7C15AA2900330C1189CFC2CD8B912C480E458297EF14DB694A3F1E72C1DFA3A3D2A8A69E011602B93020BACD1C2F3AD06C95A7F36EBF5261F6EC106816BB3303CC00BF4E8688D2E8548F10490D9EB23C56793B34B8406CBE443D8356BCD0F4F61D0D017D54831B9BA329F8948F25C3122F9DEDE8CECBA51569EDFFF895FA020862C5DF79F864078486B5FB228FD789C35FDE1C54BFFBF4A025A7FE7D8C3490A5D4E62D04F79F4183CA68379F4648BD5B2416DBE5B845C9F4B7A7E2339C0506D58539EAEA9451C9B2FE2A18C849DCA7EED9DACC058D005FB7375C4EF45B001543FC68E47DDB6D14FF937D1AA0D4D7489DFFA6210679CCCECF9B8551DCF682D2AF1E5BD869F3E8D400D5C861AE51FE7EBBB5457F2EAAFD093A9598EC721C69327C51930F4B9FFB2AA7F1A28436B6D808D75392BC43C1B5B859C66C54FA515C7A615A69E60921434AA9CF9F9E03C3CA35B5EBC6A409E822FE76E0924C6C062F1724C382FF3C8ACB5C1666C2EC26B7628E3D7C13DA8D758890E6CC017B7892582E95EDD04BA9345DF70FAD56EA68BF8875B932C28B32807C86371E17DCC04725CB597B524467963E1D4A61B5FBF9EC504D5DDB61793DD4E34AE082A5990EFCE801E938CCAE738E02E90599D971C2D7C64E5B6F8639F758ED621C1F21073C03EDB782C7A0F5D7C66F5CE161DED55B3E92DC27183AB083DBC1F3930AE56EDB8C53E9A7E020FFF0C4042F518B26F390C96C8183B79B53C7C7BC515187B3DE8CAB08769C5DD6FF5492112E8B0F28D09F4067ADB04194F60250E75ADE331A5C25593BCD92A6D1350439585860BB6FEEDBD2F839F317A01358876C88E898AC0C85378F572F23CDE931D47DE71D3353DAB1F810A61B18D24CD83DDAB8D53BA9C7B8274B0FE82AFF30C57072F643787CA1DF03B99EB57DBDA8C8EE8EB201F2847CBC9D34FD80CE6BC5E1E328EB6EFC83C4BD9D52F324E30EE4B5E86351E5C8C4C5456836D5A452203B3C372C787AE3332C8A5E9DC2197D9C341B9756BB1E63C75BBD5CF3E5CD4BF47BD1FEBC3E3710912D63032F6B97DC19C4DE196ACD9157715E2C14E054A9317BF96A684BB96CEFB7D8FDCA8AA477A2AF6F726D2CAC1A603CF1360EC11CA897E5BC735AB69B8647F30CED4947BA9F635D9CB2D82A662FF17A0E12D4D06D641EE76EB8B45C71EDE38C905C52BE76C6109F2612FEE6C3194465C19BA5D3EBCF1F0B5E534E0F0F1D31CB1E7A36C4303F283DBA8591CC609311A809E444E33A893880CDBAE29119146A368E4D2EDD91FE471647FFE821AA6D31C9FA49695EB9941B08F7BE3F06CDDF2739B8CAD2AB0DA4F5A3C0A26DF6A17B137CAAB3B919AB636D6C89BEDA3058898628721F2770315FEEE881595E24CF48B441660D0B2E9D5B90928C381F2B0FA26342E4C9B88C0887A4687124C012D969E1AFD8532754BA12125E9433DCF6D7BC1A36A83E6A10BA1CB7652A81350899C2DFC6E4FED38D009E6D0F1D44CCCB95E551B3AD54B3AC81E8BA4665EA428B3C861E8677890CF5F625C19A7C5943A9401CB78E7026BAE92B60A8B6807C17745415CD8E030C64C56E822139A35DA423F264336E0AFDF167430DD36E0064B2F6E8D8BB6BE99C5A9FB551CC63E508DB636667DDA53F611F02FCD1F99410F1A7A82882F9623ADDC50EB01E1F39978BF68506C71DBBEE42E4A80069B0E4C7FC4CC1471F4F1028DB25C4687B60DF4255DEC9148197A74796EC760A66AFC7884038651920973A69C203516222632EC5875EA6D838096E7FE9B5B4FB69C5E9407E70D27FA34B0CDBD6E119D87CE38581DF1D3E0DF3AE029042A3B20E923EBCE19A4958755EE2F98FD234C4413E2DBC93559A428DC37F2D1235BD4419B099E0F0DE542C46935991BE0692A6D80B8FD9886E0FA1769B49E8AE6307CB0BC1B49732D26E25CA1CD9D407E0D8864040941611F9333B6367E8300FD646AC5A71AD913EEFD808D5CAFBF1521A3062EC184E52165501E005556DE4DEE46F9E53D7DEF9909F3D5D98CA80D87707F7BC0FF8D879D65D4D783D196F2460693811CDF33358E082D81F4DB8F6C20486183A36D4FBCC8A1C6DA21AA4DD136E19FEF2EA993972BB9989AC1C38A79F31852178004123C46277D38A88FC1589F257332284CD8A873C25A1A6D40265B285DF09370E88F72FF70E434E8F66084CCFEBDBBC4B99EDFBC750CC5DEA63617F647F5F021D57D64D5EFF048634DB2209D7C8B82FB63B8823E4CA057168BAE88D9715291240B3758D7684501F861867B7A241C063B05D5E8CA6B4C79CB2435D7F994CB76915B4A548708B11B29449685941D43E60A8976F9A96072F91041F4C3DF7C73969012AE1B30E4B9C4E133558DABC46C103C0CB1DFB99B585374A54F9BA56B7248B8C3F66F1D55760D6ABB430375774DFBA2059C5DDDB659FD2E1DA9C3F0B80868C92BCAC10403DCD140D6A3D3F35F8EF1A2DD98DE1A4334238599EDAD920DC0AA698E9FE6106A0780C9C245F2C65A0C3E5CD5366110B1760FCD414D450DB9D76A22A9EAEA0C9FB72ED543CE9FA3314BAB17687E9DE5ADAD7561F1A5BEC16339269A87E09ACB29E4C439605E9572AA9B7D0E8371A30E41A0A7BDC02DA3A6121BF261EAA016A2074E4432CF63AF96BE81CEB6E0C2676A8545C66D2F30C98B5424F0FEF04B3C6C7064E2D2E11CBE60F85723FFC0B770D6866FFA589E3F9B2ABF75104019AA69CB58895B474A0ADE2B60A4AB077C3A6DF615334EBBE732E95220213994D3BDC443C8EF94AD515F45418355183314485857AC12BA1D62CF4FD4F4DE2A7FFF1ECF0D290C4CDFFA88D8F48C5B837D3A94CD17B3D169966EB038FE5A6E85DFC60A00233F10731973DC475D53BC7B9E60320BA7905D88519FA325DF5AB02B40F2ABBDB37D2261CB8148277B87AE3297976C80C35134E5F786904564C1469947F620FE09FDF3862C4057A3BCEF70750CB727F031283A1826F1381B3348E3EA4688609ECB193AFAAEE1CD97E4DDAA02C0C30E49F137D08285941528101759A7422AA499C900A379DD73B307284CCDDAF1FA1B0C4B280E3F9F1DB6D38ECF8A841F9D4E40ECA86247D6CD9B31EACD6A46F0E333B9E83D690D7E13467619B46AF9AFCFDC4AA9A049B180260D70D9EEDB8A533051AB83517AADC2CD900B3EA51260F464AFC5D2DC411029779B21CE2CBD160218DF41F661DA1AD95AD40B8C353C7F10FC23F830D117BCAEF8CECEBCBFA49D79D8D9391E8D08281F000A55E92DB331BDECD73183E058FF3FE5839AF50D8C55F22F6AFF5A33DA774BA1B3E643F5877CF549C4F908EA64A37DF3BFA4CD5F70F8CD154476D34BC853C9E8F7979E5F4EBB888AF761"""), + TestUtils.hexDecode(""" +EBDA4B4198C041F515BA16E227F1491F54109B04C5836855038149B60978EA146DF46299A38794D61DA89DCB74A46E3EFED16C832884194E74EEC82C965E9DB2858B87962F48F0C094C389DFD1DD44CBAEDF14A62A709FF48A92E193472899A6876EA8B9701C1D137896F3C779A4E056820F55300524202E44F8B24D5B685787"""), + TestUtils.hexDecode(""" +A2E6DFCDB93DAEF3A2B0A3A548EA48D51157F45034134ACCA15A29E5417475AFE72F571B34545F92DE26B06F141B1A18545CB06D547A1E3D19F9006D7C0E9640273AE424EE20CDC0AB8CCD680AD1CA98047108ED0FFADBD8B568753E4FA7C74CE79F7980297426BEF9ED2C88ED43B45B92E77D47480DEB54993BB03A956F617FBC9E40EE1F726A1E095BF25AA2B8BAD9578506A624E018287DE7A844D4ED1AFFD8B013131272948ADBFB1B40477CE56FA0C94E1DA951049268F26B7544FC1CB0F24F14C2D7A51EE5AA9BCB8A0237231F7ED5F7D2DF14184DFB66CE0336233A506193D6CDDACCD1E2D32A449459DB55DB87080603330CD1A865B719C0C389B19C18ECBB240EFD582A0AA372C47CD00DA92CD0549AA7F7C41FEA9A348D6B7BB78F46DD2998767ECC6CF9F7E2545CA2CB1A18503167A85EA96523C537EE2FCFBE870E40E00E25E7C092A2AD5D5936AAC869D167D9D76BF2AB47185A6F3F64D0557D78D553379ED2542EF2A3CE45E5D97EB7046219E9A9F4A0021EBF5B87A95056F3D14F8A67130B8BDDDB7F5F6C41E189E070A914BF69154F06E45109E2725C5516D1FDCD93A610D3328E2758D5BF0FE58B51E05075D7DFF949E9285924CB3773C8A16CC09F86A0F14925ECADC6FE687C5F864B93868E17D5D3CF218B8E49B991A8CD7879194C425DB3ABAF41B9FCD5E0DDFABD24369EEAA68E50932F6C1C81A72D12DB8EF868B4CAD837EAF5FA0B5915C9BC48FD089F365485A92A6153D1A48B4B28682921C432DFF4B09D63EF3C9A692DCB8FF2D48A5EF0FA63FBC24C9CA2E26AC2ABBA339D2DED6EECC6784C1ECF9F0D39BA10AC8688408AF5B85D4FBC09B73D9DEEA0101146ADBC08004DAF9BC68E66515BA9E103EC4B062A45E733485FAFD9262CC7737999C76305E1106553E495B26F0B22EA7F093B4A543AE8CEB0DB3607F4CC023E45EF9F957563DEDF945CD88FDDDDE42826ADF24D95C314BA718A1C81462C2A4D1BBC2E9418A11954D972D386899B65A2D7D8FBB170A91EE0EA02D18DF1541D95BB64CC54AE8DB48E7B66A633051C04767D708C98BE328EF865431B29348D7306D389287BE9F41BB23BBD3D7A7A3C5D4C3A5F171D574B0640EE6927C1E96F2E9CD0A1BD90430D42A330C93CE66DFDC65B067D8F173EFC0EED00EF24F108B143F589AD94D0A6FC98798C1B63510734A7853D2EDF70A1918D2780C23B12CF5B1EF279604304160364651965646E0E223562381B36CD81FAB31D436F53A9D65EFB3A7EA2092CE202C1ED7FB9EA64AAB6FE7FE107424014E5AB946A3EFBAFDA9619CB7A603F11E9AE507098AFF80331075B06AC4936A711BDAAE97057E31521D5479E046EAD7E8F024E3B9C49A8A253C81A283FBFFCB0C1D896D99E881314C04FA7E0C9DF25B6166F57D97065E9166B37EF612F702E6FF1C9E81F0189E22ADD54B9F2880B23F1D3F88E120B89BEC9C699BFF18DCF870362F9B4D0F66D7416198864484393156D16A7069C0D385910DB49DC9FE8015851DC43E8B03132444BEB19B60DB6052379E5F41109354C0350A2078D397389228726C33DC492DEAD0D55DB917C6E212ACEEAE78A8530DB6A53C7A566E91E1AB62D3AA16F2736CDCD965D38D945E8A15EB68CC2B50A9C5E88F5C40B8F67AF4C36F241F3DE9EC66911937739F8F5C56C28CEC16FB453818178A3698D639A7E9A215D2F7400F5FA0772485BD75A58CA574CAC9BEF89F8F3B554A92687EEA5C6AE9651D9CEC267E13F84FB98D43FC7D24895296D78FEC1B2012F732092511930FF78664E926A57F23D3CF17BF19EEE27D833B88B6E30BF5AE5498FA55EC0D14FB127D5E6EE80560F540FBE26FD81AA62B006A139A065C11B7B48B2AB038B522168748A57DDB6C0A6CA0D7B4B79527673E58617F22F3C1B32FEFC787B41DDE9399549B0608478487126611634E5166BE7AFAEAB42F348B2691A1978CE61C753A049767A02E7055DBBFE771ECD8613B3AA29622F2FBC06F9BDCD9C94D0FB8C75310E2D4100C5248FFCDA8A898AD331BB4ECA6939FF31094F418BB8BAEC58AEF7B6FA33ED8588A21B437F4AD5EA5F2D86C4DCF1C4A559BE9B0C384AD2AA778EE93CA70989BD2ED681666CA8B082B7B83272F8A10E2D245628C8E1B5FF3BF8C5FA9C6E09C238482679888827D0E3D0B9A8CC36027649B0798E14390AD84D3D766DCEBEEB670E3560C6378F90A411196365F4FA6D332244EEF1016085C9B51614D8BF3BB44A67C906E7241213318B714824C03D9E8927AB2ADFFF50494D3F398F37E6BFAB3F8E0B89643FD220DA424BF2D751D07B5F335944462B374F297726DBBBF8C3A2D7B26BBACF192C05FF89F0878E26ACF8275644CB85C7D81022D1E85FDE63E7055E1202B85E0118687994931DE1617BA91CE9054327D3DC9DA0135DB676E9A4388DBDC3727DFCE71FCA2CEE2B2331DD836086D86C3F36767BD2F210B7B8CB1458CE8252DE845F507D78C93F7ECA7FD8CADA3DDDFEA34D2FA9AD31F10F02430C884F65346840E4CA5CC54572D6533A4E2417CF859185CA5B905BF83135BCBD88C0D86CB7C3344674F8A9A09BFD460CA828BACBE12B661459123201A5CACEBB6EF6E449B049552AEB5EA305B870055201B4686CB255E12BB1CA67DB46AED1890716672A898F71B5109A5C253276C42A22ACAEAD6E4F0798067FE983494752574A612969F1C923AD5718362E2AA1C4E5255A777DC6CBD53F553B0953BB464EBC29AA36E3F72B5C6614FAB08CC65F540D662599D45269754C0D6BE109BD7E0DF04D5EFF30000D8D6AF25B5AAD51057C31C4C134C59C3356B34638692222273144CE9D768196749FCE54DC7A7A1E2E36192FD7E756994E37D0078850E81D2D9C40670B77A02C9F708DA28CF2CCF478309B4279A6C45B9FF854A5F5B553CB291FEF5D1970883A064200D2C99597829F15DB4D9506C82154EACC4FEB0800D268902B462FE9D3284D89D83A7009AF5BDEFBCB310608151430B779A6FA4CBF6DF1E13C4A9DEE96D6BBC0CF989C48888BA58316FFA0114020B5C326D723960FC20DCFB01DC50982FD824F9512AE73E3676ED8040481CB536F851274087BFCB77A0EC7DA2BE274288D2212471DC7949EEF77A8333AABAFB57581CB43774E07F192B825F14AD564658792A0E235F4DB5EA6E3A84403492E209484542C2C2881042F54CD56CC00F2C31810EEC70D8386D0C8B7E4756A77B11563A42BC3A5D2A495D0C8278810D55EE7CB38D80C34E4DC58F0A8B1EC6E2193E6184E5F0793AB882051EBBDB3303D86F4A0E22090C7A957BE5F7BDF4652FC8F38DAC71257B2570D5B1DFA95BFEEB7E377DD581A8975D72398B4D258B1B9E7DA60217FF77BAD7008FBCCDAF7479573F9ED6BA8D13F83C233166D8D7A400F00840887BE510EAF1CF2E30B244C9EB6E166C98156C27A5FF0DB563A204B830C8FFC64D6685C9E3BF8968F3A2D2B329AA6AAB0D49EDEC26C2B5D7462AB465381D5431C85268EFB89F4E04DC660EBF4A0962F9C9F4EBB7F2A1EC5B3262DE971219FB56CF42CD720811EAF66DC2C428F94E1DE4ECE5F2116533B25E65D732A4BBD5221D28EFA946DAF52437AD6657703A9B454422C7DADEBF063E5FC433536CBA84E07F7086FE031A0A2B4DACDC99E5D3486E77D41D949EBE69E14BDF21090646CD9FF8E9F0FBF5E737DD38C0EED3D73D22A7C23AC781341109997594B3D1D4153AA1A35FF7AAD5636BFA9BE09E3329FB61950CB6DA58600E05DC2782B2EF58466AC9A4BBF6264D0D616968C6BAFC496F859EE9512072180172E91E3B581FF5CE9B8AC0624F221D111BBAAD988A530C0CADE0C4CC399EFAE9ECD624F55D93F9D0F0FC915292419ED119E177095880FBCE058783D85380F1F6673B7ED6702446098693F3FEBB9C9D7906391608453158C695D073B259518AA7DC5125B51E58A5170D1A68CF6CFC1A705B344911A63875080B4FACD9835AE85294D03EFF6D3B02888BC1D094B9E7374CAABBD1D0C32F1786B8CC12D0E4C76BC99694A1862A73ADB58A20908A601ABC4015ACC17E5B0AC28F3D8896F8BF0AA344B814D63CF558E0CED39D1F7B16D411E014BCB594F37CF18BCF46EBDEEDF1AECBD13ED97AD65A0674275868F34148D6E03E7D802258987937DBAA69215216F1CDF8BA2BCDA245D42A5D9891CF0ABC804595B320A774F1DE69F8ED595007A59F1FB570D6D024ADC97B121C28542E3043C3F99EA5EA4BE47E3DC0B66E297477537041CF880B5FAF2828E3DA2D2F9414297C59F17ED60E2DBA0502E8FE6B8E5B13FE2E945B2E78277C568082F678E4F4FF2E323D1E0AF996364E2AF2FC95C53F83953028D38BB168A1FE68C02E4477CF567DF6C2A72AF3F56EFFC99C0F5223E4CF32CA3B97C700A40803E3C91DA686DDF45A47208FC904B2384730F050A9E3440CF9A010044F7E8B6B0FEDA288F810E27AAC5DAF358046D8AE85AFB6020C22986C4788E07EFB41B2C18C482C72027673E9695CAB29FA04ABC0D7C790D3F32565A859696B6C036ACB5A6D1E444CC7D9D23B3A8FBE6E2E851914711EF790E8CBB097ACAE791825EEBA70C3AF28E6E8EFCCA38CF6B6F466D568100ECA07BF3B4B8E18EB791A2431A7FC2A795B4CDE07A38E1662044E81E85667BE36058095C7F0573D930CACEFE4C97B3393F8400451AAC6B55C5399826D8C7746BDE6484D4377BDFAD25CC5CC17C774B4623BE25184DD627CE8E6547788BD7CA2FABC9B7D4A602C457FE9EFD82B79E9322F99962FC7DAD35BFAF85A03D67DC7E83FD3C627160DC96640683AAD733B3D1EB59646A2533B99EAEA4E5CFDB2C94A8724B03FC4B72BB5BC5D90B0D4A136E44D64F3985A7EF7C6D7C55B61486CE529475F21630DD824F8AD4D3FBF0CB2C48CCC0DC27516733FF5BDC1F459B00B88883006AEDE6602DC51A316959DEBEDC0F36BBE8D017207225C1C2BD94CFC1CC60933CEA2ADE45BB4425578F4D28E0AA36DA346E2BA4B34B65BD7E71B9FCC3B52F8C425AD44B5CCD006E26857FC5BAD79D8345C5FACEAA4DC3A7C613D085826F82F10961AB2BB7C087FDB490B5A082B2F5DA5D9E6210D6E8B37ADB10DF510990F3ACD81CF93965CAAB334F1B2A76D9B17D758F273860B074B2FFFB88D9B5E6991EDBFC5FFB54325BFFC0C66092E7729C9971101D7CBF74491CC4F54D535936CBC5455E3215215E836500F411382CB8658BBB60636BAC343A645741FCD6C5E23433EFEF4F14967C5B742BDA45B2FAE1946FD0042229A1E462E172102124540CB203D58DF1EB8ADEBC4DCB37F8450DBD0FEC87CB4A56696141C9513F7D6E61BB117B0E35E1DD314837965004C6C86388C2D3EA57EA4C0CE9C563C68F5B3CA20043742BB5060935C23FC7FD5368EABE5C1A1B715B99B96E1B434229D3ADE0129AAD85710596DF9AA2D86C7EC88B9552F876861DBAD135B4EB318FC6FFBC3AF0C98EC57468A0F4BC3A29CF1625B03E33360D152B0B5F5706C169B68C7470379BA15D9188F13DFCF789C18A9DA14EAB56DB261F978D9BD894C84C1BD203A777DF785C82B87FF975BAE11437F9A243627A1715CBFFEED727B405C545542A7BED9395ADE1A671807954EAC7C9BFB8785F18D5D5C31A01320E7D863743BFC7852E251631A03EB671912F6138C21E1D62D88E1941095A8DFDF3B052A0104E72C186BFEA9CAF32B2FCA121FCF6A3D85FCBB9D7978EF2E227F321C1BD932A4DB007CB2DFE3BFD9578BD7AA6844611E4F3ED7E5370205A07B6CBBFCA7AA204D76CC8DCB9A1CB6FE6C4AFC5E5A79E59C6934D473BF834F69B89073DEC0D9ABD347B12BA21E308D42D1576F03CE4BE6EF8F07EA08CF1846C27ECEE7F8415C0FA756A540E42738892C7E6D0F90520FEAC6160911BB18BDEA2A1D925CDFBA7C585DAA3A3D27B12E4880A9B8C87B0EB5EFD7C07507D8C3B274738C90EB4A745C1AB3749ED000075E99277B927B1CAF2E19E8D588AFD3CF9BC0302724E71F129E3E3BE9D114542B16C4DB65AC8529CF95CAF7A2EED53548D1769F809F1780E5102D80B7E52B99203F5CA6F2A2A7608171190EF391A4EF5384D15C101895B5402E8D4FEA052872FBAF6DC9FFDCD3FF9EA884ABA4D90E202206E861B9785AC572A0013765C24B5E3AB9C4E31A6B7F958A4D3DE78CA4D4C097AB9AD50E588BDEC45528EC7B248BAA3BD3DF31F8FEB29F823123421388A2A021F37426188CF830BDD10C75BFFFDA15623B33F89567EBD2EC66EC7DF533CE8F33C32EBD6D074606380F37F3E9D186E4A93EB098B6EC0455843E7784A9CCC67E0326920223993CEEF7E4AE399E21993CCD078084804EAB9881B6C40CE2B20BEC97DF60381E930CBCC038A4A9153B2AF6AC6F743FE6E2FDA9A0FBD4C00D93C972333C8A8D99041D8C93718CA0CB864B5E50059D73978FA3FF33115880D43D93B8512246D82CF104A4B525F6F8B95AAB9C8DF02649497A9AAF01EB4C7EB1E232738557175E6090C2F657E9DBAD6F90860BBDEE0F701236C8489A7C200000000000000000000000000000000000511181C242D333A""") + ), + new SigVerTestCase( + TestUtils.hexDecode(""" +59B2371FE7BACC207FE1FEE88A8B3805A7052865691789BB90542FA47F7EF2B75FCA13DBA5888BEC320514DCB05FD26EB5541F6E572ECEA6C4F1D38AA70259094AA945F19FED0D980E65DBF65DB80F564FE29D836C5479288B55CF07F4E00159B6955DABDECC8C4D66AE688728BA6D5C0442F3C1232C782C465B9B7C5014B1464065CCD8A56D6B1C16510869E014E6933998EF725520B400913D93B0EC75E2FB725DC1AEC0C0CC7343B9E544BAA4D679860E347B2E947D8D2436F09298A7BB8336B9DE9CFD5CDBCD91C7249268CA03EFAC273AF52968D501406CD9C96159D7C15AA2900330C1189CFC2CD8B912C480E458297EF14DB694A3F1E72C1DFA3A3D2A8A69E011602B93020BACD1C2F3AD06C95A7F36EBF5261F6EC106816BB3303CC00BF4E8688D2E8548F10490D9EB23C56793B34B8406CBE443D8356BCD0F4F61D0D017D54831B9BA329F8948F25C3122F9DEDE8CECBA51569EDFFF895FA020862C5DF79F864078486B5FB228FD789C35FDE1C54BFFBF4A025A7FE7D8C3490A5D4E62D04F79F4183CA68379F4648BD5B2416DBE5B845C9F4B7A7E2339C0506D58539EAEA9451C9B2FE2A18C849DCA7EED9DACC058D005FB7375C4EF45B001543FC68E47DDB6D14FF937D1AA0D4D7489DFFA6210679CCCECF9B8551DCF682D2AF1E5BD869F3E8D400D5C861AE51FE7EBBB5457F2EAAFD093A9598EC721C69327C51930F4B9FFB2AA7F1A28436B6D808D75392BC43C1B5B859C66C54FA515C7A615A69E60921434AA9CF9F9E03C3CA35B5EBC6A409E822FE76E0924C6C062F1724C382FF3C8ACB5C1666C2EC26B7628E3D7C13DA8D758890E6CC017B7892582E95EDD04BA9345DF70FAD56EA68BF8875B932C28B32807C86371E17DCC04725CB597B524467963E1D4A61B5FBF9EC504D5DDB61793DD4E34AE082A5990EFCE801E938CCAE738E02E90599D971C2D7C64E5B6F8639F758ED621C1F21073C03EDB782C7A0F5D7C66F5CE161DED55B3E92DC27183AB083DBC1F3930AE56EDB8C53E9A7E020FFF0C4042F518B26F390C96C8183B79B53C7C7BC515187B3DE8CAB08769C5DD6FF5492112E8B0F28D09F4067ADB04194F60250E75ADE331A5C25593BCD92A6D1350439585860BB6FEEDBD2F839F317A01358876C88E898AC0C85378F572F23CDE931D47DE71D3353DAB1F810A61B18D24CD83DDAB8D53BA9C7B8274B0FE82AFF30C57072F643787CA1DF03B99EB57DBDA8C8EE8EB201F2847CBC9D34FD80CE6BC5E1E328EB6EFC83C4BD9D52F324E30EE4B5E86351E5C8C4C5456836D5A452203B3C372C787AE3332C8A5E9DC2197D9C341B9756BB1E63C75BBD5CF3E5CD4BF47BD1FEBC3E3710912D63032F6B97DC19C4DE196ACD9157715E2C14E054A9317BF96A684BB96CEFB7D8FDCA8AA477A2AF6F726D2CAC1A603CF1360EC11CA897E5BC735AB69B8647F30CED4947BA9F635D9CB2D82A662FF17A0E12D4D06D641EE76EB8B45C71EDE38C905C52BE76C6109F2612FEE6C3194465C19BA5D3EBCF1F0B5E534E0F0F1D31CB1E7A36C4303F283DBA8591CC609311A809E444E33A893880CDBAE29119146A368E4D2EDD91FE471647FFE821AA6D31C9FA49695EB9941B08F7BE3F06CDDF2739B8CAD2AB0DA4F5A3C0A26DF6A17B137CAAB3B919AB636D6C89BEDA3058898628721F2770315FEEE881595E24CF48B441660D0B2E9D5B90928C381F2B0FA26342E4C9B88C0887A4687124C012D969E1AFD8532754BA12125E9433DCF6D7BC1A36A83E6A10BA1CB7652A81350899C2DFC6E4FED38D009E6D0F1D44CCCB95E551B3AD54B3AC81E8BA4665EA428B3C861E8677890CF5F625C19A7C5943A9401CB78E7026BAE92B60A8B6807C17745415CD8E030C64C56E822139A35DA423F264336E0AFDF167430DD36E0064B2F6E8D8BB6BE99C5A9FB551CC63E508DB636667DDA53F611F02FCD1F99410F1A7A82882F9623ADDC50EB01E1F39978BF68506C71DBBEE42E4A80069B0E4C7FC4CC1471F4F1028DB25C4687B60DF4255DEC9148197A74796EC760A66AFC7884038651920973A69C203516222632EC5875EA6D838096E7FE9B5B4FB69C5E9407E70D27FA34B0CDBD6E119D87CE38581DF1D3E0DF3AE029042A3B20E923EBCE19A4958755EE2F98FD234C4413E2DBC93559A428DC37F2D1235BD4419B099E0F0DE542C46935991BE0692A6D80B8FD9886E0FA1769B49E8AE6307CB0BC1B49732D26E25CA1CD9D407E0D8864040941611F9333B6367E8300FD646AC5A71AD913EEFD808D5CAFBF1521A3062EC184E52165501E005556DE4DEE46F9E53D7DEF9909F3D5D98CA80D87707F7BC0FF8D879D65D4D783D196F2460693811CDF33358E082D81F4DB8F6C20486183A36D4FBCC8A1C6DA21AA4DD136E19FEF2EA993972BB9989AC1C38A79F31852178004123C46277D38A88FC1589F257332284CD8A873C25A1A6D40265B285DF09370E88F72FF70E434E8F66084CCFEBDBBC4B99EDFBC750CC5DEA63617F647F5F021D57D64D5EFF048634DB2209D7C8B82FB63B8823E4CA057168BAE88D9715291240B3758D7684501F861867B7A241C063B05D5E8CA6B4C79CB2435D7F994CB76915B4A548708B11B29449685941D43E60A8976F9A96072F91041F4C3DF7C73969012AE1B30E4B9C4E133558DABC46C103C0CB1DFB99B585374A54F9BA56B7248B8C3F66F1D55760D6ABB430375774DFBA2059C5DDDB659FD2E1DA9C3F0B80868C92BCAC10403DCD140D6A3D3F35F8EF1A2DD98DE1A4334238599EDAD920DC0AA698E9FE6106A0780C9C245F2C65A0C3E5CD5366110B1760FCD414D450DB9D76A22A9EAEA0C9FB72ED543CE9FA3314BAB17687E9DE5ADAD7561F1A5BEC16339269A87E09ACB29E4C439605E9572AA9B7D0E8371A30E41A0A7BDC02DA3A6121BF261EAA016A2074E4432CF63AF96BE81CEB6E0C2676A8545C66D2F30C98B5424F0FEF04B3C6C7064E2D2E11CBE60F85723FFC0B770D6866FFA589E3F9B2ABF75104019AA69CB58895B474A0ADE2B60A4AB077C3A6DF615334EBBE732E95220213994D3BDC443C8EF94AD515F45418355183314485857AC12BA1D62CF4FD4F4DE2A7FFF1ECF0D290C4CDFFA88D8F48C5B837D3A94CD17B3D169966EB038FE5A6E85DFC60A00233F10731973DC475D53BC7B9E60320BA7905D88519FA325DF5AB02B40F2ABBDB37D2261CB8148277B87AE3297976C80C35134E5F786904564C1469947F620FE09FDF3862C4057A3BCEF70750CB727F031283A1826F1381B3348E3EA4688609ECB193AFAAEE1CD97E4DDAA02C0C30E49F137D08285941528101759A7422AA499C900A379DD73B307284CCDDAF1FA1B0C4B280E3F9F1DB6D38ECF8A841F9D4E40ECA86247D6CD9B31EACD6A46F0E333B9E83D690D7E13467619B46AF9AFCFDC4AA9A049B180260D70D9EEDB8A533051AB83517AADC2CD900B3EA51260F464AFC5D2DC411029779B21CE2CBD160218DF41F661DA1AD95AD40B8C353C7F10FC23F830D117BCAEF8CECEBCBFA49D79D8D9391E8D08281F000A55E92DB331BDECD73183E058FF3FE5839AF50D8C55F22F6AFF5A33DA774BA1B3E643F5877CF549C4F908EA64A37DF3BFA4CD5F70F8CD154476D34BC853C9E8F7979E5F4EBB888AF761"""), + TestUtils.hexDecode(""" +4AC4675C96D9117D1EDEB80D7CD284A3E1E1FE038E301205B4C408EB965235AD1C85F8BE3F77CA486FD207F7C75F4121CD3CA2B23D6BCE4382A6D36121815025D5806CBEF452E083933C6E5C7394AC88262A6DE7770B2D8843EC101FFB5E84DE2F7A8B74E7674B3B2319BD6BF4112F92C5CFC0A55F7FA061F45325408D039D51"""), + TestUtils.hexDecode(""" +4B3F52F081B3D914BC7C6C073B182B268ADF5189E298A869BFB991B199993C1042DEF5B59270B6CD3FF8F907A1CB0D3B6FEDCA143838F8F81E0C370FFEEE6B25CD07035641A051944EAB516CFBB801536B4F262B16198E7DDB1D61C35A64D90D3948CEAAC8EE580DCEF540ED99D912BBA2BC4F5145BB949C73CCBD582613B10EAAE863ACA34683EB922B3DADFC74F76F47E4978602592402D9154394EB09FBC2EBCCC594732F2D8BC38350E5535A4412A77ADD7916604576FD6A3631E515BAF26A6F9CA4061EBBDD3BEC7179AD58552A5B508F31348A56AD1ADA7A05352C72C004B94C47E7049A10B3A59BF238A8DFC6C7019A17F05D5BFCB9D93D9D1CCBCB47F8C438098FDBDFE23F9F78BC28069908C6B9898B434CBF37787E1AF6A6B827E830E9F7629CD8F51070C4C8A8DEB260D07C3E41D8490484877491B39AA6D9E10D91748B64E33160629D8AE43EFD5F85781E69F76B6895C141EBCDDFEEB485A00BDBA4F7C991F53F2F84933926AF39E6964ABF2DFEBBC19A7E31C50797B8DA2931E10F3DAC493F198DFD785D21ADB2C062B097E889A20737F186008F2928F6B84D6E09E975A8F2AAADC785234234FDA03703A7C21F812D650BD2510B30F0550081047A155C848586A96F100D774F3E39E029B0777CD33E68318A11C1980293FAD3E787D20DFE7EEE7053C05EEB6A159BAAD4020B9EC3F537DA4DADAFB3B1BB1DBEB2D5B8F9D05A019798EAE0ED099DB066D73EE8E9A56DE368E878A7FF39140D8021D50085E6252941AB315309CB53AAA49E86347FBAD54A1F873E0CB4B86A8D5B1B2A95D485F37A9FB6105DF8440FDB8578F2624C079329569A75F36F2C55D8D030FBFEAA8889AD746C323B1AC4EC8C403E775A6FBE596E7E6A5A2863576625149940976F7CC93617B43FB13489074ECAC5BEB1A4DFE58B9AD2E0C6A15B76A7C2D208725A3123CA4E6F2C5847EE5FA8384919EF89011D219B257B3E4DC4F2095160844CAEEAFCF857260F1C63D3B05A67D3D0F2B0EC9DCC2723F13755750BAE62FCC361CFB584F774C09ADF9A0431B23E488C359C0AEF5B1C9787BD8F52B083BC9DBCC9B3039F777C7E8EABC80078050CE6D49C3BB70168FA2177298FB0A8F72C1CD28D662A07DAE6C7ACB7FB8E7FDD01DFB27C62EE683F4E5F88C7C1DDDD5EECC1C3AF853F1FF6B1D9DE672F1BF6473AF0021D8A3D4DD04A2FCA2325C721CF1C821676D0A0D574186625DE831C8411F64179F9167F78BCB22FB41C2CDB63C4DB5E138766D3803589598F114F41BA42CDB1341020449BA99656113990B4E022D8DA20D744491C6EEAB67B918E80FFF343CC5B4C8E58C3484B0125A60C36AEF763894D35148B578F417C3A98A143EDFE9F8C95BCC346C6F5EAF97AAD11DAE01C477C227A88D10ECFDCF450B37F881968027849D9B43E2BFF90C6A34AE41B8BBD743083D3C58786B036671CD6EED94DAE51F7613247EF8607ACF74A3CCE932F1C3869BDB35CA17FC6BA9F9C956FF1D4D88094325CABCE41233FB1D808EF41010396DEB0ECF50734D818DDAB70015A0ABDD1926DFA491F711AA85DA2A8EC60E3255CCF975C23CC4E8DAFDDED9FEC60A6467C45B03CA476499AA331B0E3999576CEC3191A9A62BC1BEAC1EAF20E18CFC3216127DE4AAE2E75201F9E427E39BF921150EAB949559C022D876FA242C2A845BCA7235F721B0056788A44ECC3EB98F0F502B89F8E7410EA5679AE7C0434F13AD816421D2FEE30CBCB2DAA6B851CD1B6E996DA7A757E4C4D8572C8B600DE85DDB65320D1CB71D9378349C0C401AD4F9E91272139228A8DA2F4FD2F48891A4DCB066D501D447483B611BB3C80550A90EA0B732D639D8B3926B6E7C35453ED3CC110BAF556CF46D8FC2177E76FB2663B8BDD171E94C0ACAF25B9153B22BCA749916756FB3ED3018E0944B6C3B9B6BFA15B9BE803AC79333CD2C3A27A26BC17CDA257798AE16B28B463B6DF3FA87C2D742D0F6885BEE0BEC6E20D01E5DADC86823E92D60FEC79B0D240248753E42048384C804289604821A57F4F9F50AE0C38527FE5A34938DDBCDCD9A1D020839BEBB62F9F41FBA08052ABB82FADA884CBE563791103AA585546EBFEB11272CC2E87A3B75B3C6BB1853AE7F9CF5585B2653CF5EEA244D204EB269C56A20985160659CB0725EE13CE35D55EB095A53414F232DF8108B18024EB0DBF345EB5CDAD0BCE7263509A341D54A7D534E553EAEFFE4E242EA23BCFE59A58A60425882CB7E3B0C9E4AFE8698E3DF56AFD6D611E9168747D8735CF9246D94F2126BE727FB42B2241A83B34F0B9EB47938D726502C54E4572766331628FA5CDA893C35376AB4538FF8717C2795B0F51F08E1137612B89B0C1E2CD1F099E88556923AE57A1DAD2AFB1230B5094A1B21BAD7DBBC333A97F179304718F3289B6DE31315B74C1A73AC7756FAA4D7EB568BBC6F7E788CD089B395564D2176B0056DFFE952C7748B048306720F602B67E8F6ADCC91F8E3AA4B8C4D7FAC233AAF93653AD2209E2FF92DA30C2D53FDEF6F4C90EAA0DE60D594ADA3915DB24279D867476EAD757B4C0264A1DB8A1F57A1B5D7173BB1A960CE02FDEFEF160D512667D655268FCC3A153A4314782A0EBFF84F65F14A0E3E12A13250C07D08C225B11A6831BC25C40467B768004DDE0E874A51144C18920BDF286090B59F51564EA4070FBBF61E3696435F28F63332B64496DF3EC8B65D54E1CF4789DDAB122DA6B264D312A711C129E3B07F4C6DA25A56173AF58B90A71B7ACFA3161A81F59D17914C99BBAC4F9A314977A89CEF7696943609BB4827964FB2976403BD4996F1E842BF5AAAE1ECCA11255B9E6001C20F72F1FD5E32CDA32D8A7AC5F62B09A0E615847CA746F489515CF8F183162859F53B97E9E5CA800EE624F729843A0009164A4A9FF76EB34E4704184848A139AD97D909F7A7ED114F087A4B2E1B4A3032391160B6F3A3649FF15AEA2B7107AF8A3B5FCAD61D43D602E6286A900870CC8CE24E39E78F0397A0D7E27E8E2D4776A44CBA218EBCD88B3C28C182A7C9F4DBB2DBB5E981563D66CEEB77E7F9034BD429D27637CF797DE82E01FEBBCE2171EFD016E402A42D78EA1ACE2CB370E75C90ADFA1A793B2169CC26522DB2F546AC1DE34C9087120C42A9F10C00D493C25730166F9D219FBDAD222C8B28115543313210848FB2F04BFDCE15D320C3634A8E4D63755515900C75BFD090AD78DD588659FBF97C96E0D0ACC8E815E608F9E861D79AF3051B942B52570B6292BF48C2BFAA9077DC76FE902683217B8BF809ED7A0050ADDBB65FDDFBD24019C9181B5AC81566113D6694EA6291D7F4A7F56A41EB91F76368DF82B164B4859259D7189240F1D8803F8107296D378BAB4D24FE6D10EF788367BCE16C5AB77FBC168B857F7BA5CDCBE5067C864F879809FE5217DEF0294BFAFDF809ABCE9532DD9DAB3448F4DA68ECA51609476278EB8C4F69EA29673F69418041D26857EBC24A487BB4B0BA63AF848545EE9BE89F139D502099B9D35DB3807B925CBA576E27170EAEC48CC2CC15B043677825D0EE81EB2CEE3A8ED14A798B879530220E50CE8C003A305382A24D23C277B99D1F4C54F9A8D33FA3D1E337E18D7CBBA5E5A47F2D5E096CF4551B23B1B86436E81B4A09D1E3D38492EC8B2A00967016AB76B9A9B1864671421DA56F57D008D5CE1B892A7E9C1F69F6C722CF109DB500E53F6BC07837AD1CD4CF4A64DA763B4A9C4929B0DCDDF7C7E1186BE3FF0C321158437820C81E74FF316AE3254E972FC197A7F0E620242AC05A4E43E987C2A8355B0357745CA79E6AE48AB29ED4FA63D3A1F19B999DE251FDE0640DD87876D55762878AD1DB12D65BAFD14B6A9A7081BF23F9F06D90CE273C5A26E012CA94DD481D32E10938C165163E89BE8A93A63034D345B74E2A94EF643D06AF9E1F5C9F104930DA00E61E061EE8C3BB17C11E05D45C1682E4D593C9198238D2BA289779E7D0F227BCB0B09972B19770FF011BF6C60D9D193CFAB32747A0095E1A4AD32514C782EF3DE7A26EA771F5530D9DE9736D0F6AE1AFB78EC7CE4884A1BB436CFCE459CD99358260906AAC99716A536CC7687A0375FDA11007618E553534E54D5B214F7AA6FC7DBE37C2BD2B64850AE469A9858987F3FA4B1FD26D954BFEC365DBE06DDCD615E1FED58A88676402D1D6B581485498B5ADFFFC42D47D61DF99384E22C5157F0178A6FDAF8F4A9491DAF298B2C3EC88085022C0A7CF245ED0FB5A38CD16F30D37DA5C4959A55501DAD50F1B48BBBDD86AB8BB522A936DDF0003B81BE16231A04E7A589C56FFFB51B07927B4AFA1DB7D48BC6FBC3F3675637184B7ADB9BADF4DE7C085BCA1D428DC9FC8277CBD85884A5921B52BB05B710615508261BB4546BD6E1FC730D16B049EA12798CE2E6DF43F5B8F3EF9AC8FBAE31B011E10C4FC62FFD7F39D16EC32CA8210ED16E041DA43D9274229514054A0F82D462FE080C6FFD7BBDBFBF0BFFC6D5ECC432A3256C0BE0DDFD5D9080C676C7955D66E44D1CE51FCC2382F868D732E85851721B48A01D08C639626EE0509CB581EFF5628FA6CCD1089AC0E12DEBE0851782E64C5049CBD6501013965CC0CA25ACAB176EF7CAB92940985DDB49021DF6C60D6C4A489116311E86BA19EDF00D74797358207CDE50506D007FE03C8804C66451F02A0182D387B759894096F65232952D183DBAAABB6BC0E191DC2C3F75FC72BD61BAB2EF19B6532B231C4AFB1A9C2CB2F3D6C451E8440D6A923CF72A63E2ED8554773887910CA5C671AD4FD5923CB95EC73FFDFBDA4B6655F55DBFD1317D024422301ED66A6E4C672085CED1F4C7B05030A100C4788FEF4CD3E494A853BDE63E9D449AE3BB6BA1083238DA3F4090515D143C67DBE53D8D507A5229FFEB2072D0BD092FC9AE52DEAAACD1F0F14B5AC84752BFD0025E5F55B869350F4B2719C5C05AC1669BB0FD3C614ACE02A270613FD3309706DDCD5B1A6AD26F359ADA80B30E50A7E50BBD3AA45D0654DD7D058B0BBF4D0D92135142214EE70511F3676AE643B5F245063B9419CF6B49FD647F27D7C41C866E6CAD9D5E2E3E331BF6B9F72ACA329BB64259C3E79783A26674B7D38EBDE8318411F4764EBDC4C7E41ACFF85BBB30318D59C42C9203ABD6636BA3F772B6725121C052DE99910D55158C6F3EF8BB7FEDE2F81E58A7AEB25E2E46FD7232302FAFA8FC37FC8B55D594B76EC4A53EB11EB3FD634428AAA5D86F839D089ABE2FEFE2AE5262FEFC7348D836692EDB215D6F8F548B885290C2403C51C3E269D493FBD339B5DFB0A38EEDA7754DAFFA16E5BCA5A9BBDE04B014B7AEA8988F3749D52D2FC1C9F7C7B2C2D692E7896E4C34F57C558CFE8317A8374409D566879A08628F644FB45B818455BCA6042B4E6187C1DD177E9E5146319904B1505F3EE00CD7FEAF0E83C3024956F77659ACC56D8D917A37E8FF7EB88713CCA334EA04B8E258C9345DA9DE26A0A366519451E1012DE6AABF4697C9DE821D70021C3250A106CF4C23A1B1785F549D3C8CD71B05FEA753E0046A3AE0A9B1F40277CF453A2BA14CBA923CC6269706DFFFD517C1E5930079912E05A5571897A06865516C86699F707E00CB38CE193490AEE30BA47DDDF3A5B4FBCEBA73DC13D0A160EA642D30D63A02964EDFDB2F29DCD32CA9974F89C32D1FA9A83C94A2770FCFCF86E64646882BD550DDD65B4E2D287AF6C196F42DBD39B020D7CDFBB6E6E75FFAAB26099EC1D25E3234F70DD972286AEA0C3436595FE49FCA898BFA421604C82D3E94856D186905076D186C684174BF4290DF31769EDC97A1DF2DFED03CF45CE678C8A1429EB978D02A79D4F8CF0168DAAB482C6C612F04B1C93637FE77B302CEFA788C11356C52C54F37A9DCFDA55927A8EF0A0CEA7CC4ADCEE459EB64DF08ED0FC29FDC3C7B762B399332063340D473966219BFC87B4A3C91C80F0E4BA86AA1879C76625C8680A227AB22780659D4B5D30E0E9A0DCE094DAF537679273A9B277ED2A2E250EEA0938204C9E963D338522A3D1A4440E2A12397A5B97D35657307BEC94CC0C72C5C6B09DAF2BAF0020B7D8CA560BF6596929AC8D4E5460F7837B41B4AE6FF12339DB8EBD7028AACFE0B42E02CDE906783ABFF694E7CBE0897ED6ED438ACDB00A4709CFEF7150EBEB08C8FF6C1543815F4B8951C3CACE499586458A73C8572389AFC9703A7FEAF673445FB4B0CCAA511D4A2CF463F57E3A6D72DA04B256699A30212E7C5768EFC151B71744156575A2E9443319232D159C6CC006FDB57C58173AD8D2C866C8887437C223888E21EF67E1A332C1FDFCC15EF17476FE0FB57D4229894725E1474C1BA1216562817F16C53ECE01C7F9E3664EEDBBA94952987431AA2A57D330EB11B28E6BF770E349ECE350C83E90DA6FE0D0A4AB9715DB28BDD397FAFA1428302151E1F222B4469879EB5D0F018606A7594BFC82C394E91B9264495C9063D505262799B9FCBE6316BBCC8D8093053636A74D4FA000000000000000000000000000000000000000000020F161B1F292E36""") + ) + }; +} From 5154b71637e685807952e3e776e4583f0a6280f6 Mon Sep 17 00:00:00 2001 From: Nizar Benalla <nbenalla@openjdk.org> Date: Fri, 22 Nov 2024 17:59:12 +0000 Subject: [PATCH 190/311] 8343598: Since Checker can mark some preview elements as new even if bytecode reference is identical Reviewed-by: hannesw --- test/jdk/tools/sincechecker/SinceChecker.java | 20 ++++++++----------- 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/test/jdk/tools/sincechecker/SinceChecker.java b/test/jdk/tools/sincechecker/SinceChecker.java index 860db6a2798..ebd946f3436 100644 --- a/test/jdk/tools/sincechecker/SinceChecker.java +++ b/test/jdk/tools/sincechecker/SinceChecker.java @@ -515,11 +515,7 @@ private static String getElementName(Element owner, Element element, Types types .collect(Collectors.joining(",", "(", ")")); suffix = ": " + returnType + " " + te.getQualifiedName() + "." + methodName + descriptor; } else if (kind.isDeclaredType()) { - if (kind.isClass()) { - prefix = "class"; - } else if (kind.isInterface()) { - prefix = "interface"; - } + prefix = "class"; suffix = ": " + ((TypeElement) element).getQualifiedName(); } else if (kind == ElementKind.PACKAGE) { prefix = "package"; @@ -562,7 +558,7 @@ private static String getElementName(Element owner, Element element, Types types "field: com.sun.source.tree.CaseTree.CaseKind:STATEMENT", "field: com.sun.source.tree.CaseTree.CaseKind:RULE", "field: com.sun.source.tree.Tree.Kind:SWITCH_EXPRESSION", - "interface: com.sun.source.tree.SwitchExpressionTree", + "class: com.sun.source.tree.SwitchExpressionTree", "method: com.sun.source.tree.ExpressionTree com.sun.source.tree.SwitchExpressionTree.getExpression()", "method: java.util.List com.sun.source.tree.SwitchExpressionTree.getCases()", "method: java.lang.Object com.sun.source.tree.TreeVisitor.visitSwitchExpression(com.sun.source.tree.SwitchExpressionTree,java.lang.Object)", @@ -580,7 +576,7 @@ private static String getElementName(Element owner, Element element, Types types "field: com.sun.source.tree.CaseTree.CaseKind:STATEMENT", "field: com.sun.source.tree.CaseTree.CaseKind:RULE", "field: com.sun.source.tree.Tree.Kind:SWITCH_EXPRESSION", - "interface: com.sun.source.tree.SwitchExpressionTree", + "class: com.sun.source.tree.SwitchExpressionTree", "method: com.sun.source.tree.ExpressionTree com.sun.source.tree.SwitchExpressionTree.getExpression()", "method: java.util.List com.sun.source.tree.SwitchExpressionTree.getCases()", "method: java.lang.Object com.sun.source.tree.TreeVisitor.visitSwitchExpression(com.sun.source.tree.SwitchExpressionTree,java.lang.Object)", @@ -591,7 +587,7 @@ private static String getElementName(Element owner, Element element, Types types "method: java.lang.String java.lang.String.formatted(java.lang.Object[])", "class: javax.swing.plaf.basic.motif.MotifLookAndFeel", "field: com.sun.source.tree.Tree.Kind:YIELD", - "interface: com.sun.source.tree.YieldTree", + "class: com.sun.source.tree.YieldTree", "method: com.sun.source.tree.ExpressionTree com.sun.source.tree.YieldTree.getValue()", "method: java.lang.Object com.sun.source.tree.TreeVisitor.visitYield(com.sun.source.tree.YieldTree,java.lang.Object)", "method: java.lang.Object com.sun.source.util.SimpleTreeVisitor.visitYield(com.sun.source.tree.YieldTree,java.lang.Object)", @@ -625,10 +621,10 @@ private static String getElementName(Element owner, Element element, Types types "method: boolean java.lang.Class.isRecord()", "method: java.lang.reflect.RecordComponent[] java.lang.Class.getRecordComponents()", "class: java.lang.Record", - "interface: com.sun.source.tree.PatternTree", + "class: com.sun.source.tree.PatternTree", "field: com.sun.source.tree.Tree.Kind:BINDING_PATTERN", "method: com.sun.source.tree.PatternTree com.sun.source.tree.InstanceOfTree.getPattern()", - "interface: com.sun.source.tree.BindingPatternTree", + "class: com.sun.source.tree.BindingPatternTree", "method: java.lang.Object com.sun.source.tree.TreeVisitor.visitBindingPattern(com.sun.source.tree.BindingPatternTree,java.lang.Object)" )); @@ -664,10 +660,10 @@ private static String getElementName(Element owner, Element element, Types types "method: java.util.List com.sun.source.tree.ClassTree.getPermitsClause()", "method: boolean java.lang.Class.isSealed()", "method: java.lang.constant.ClassDesc[] java.lang.Class.permittedSubclasses()", - "interface: com.sun.source.tree.PatternTree", + "class: com.sun.source.tree.PatternTree", "field: com.sun.source.tree.Tree.Kind:BINDING_PATTERN", "method: com.sun.source.tree.PatternTree com.sun.source.tree.InstanceOfTree.getPattern()", - "interface: com.sun.source.tree.BindingPatternTree", + "class: com.sun.source.tree.BindingPatternTree", "method: java.lang.Object com.sun.source.tree.TreeVisitor.visitBindingPattern(com.sun.source.tree.BindingPatternTree,java.lang.Object)" )); From 4b1653056d39db2c85989c787364e2646e5ef463 Mon Sep 17 00:00:00 2001 From: Phil Race <prr@openjdk.org> Date: Fri, 22 Nov 2024 18:00:10 +0000 Subject: [PATCH 191/311] 8344795: Remove uses of AccessControlContext in java.desktop module Reviewed-by: azvegint --- .../sun/beans/decoder/DocumentHandler.java | 37 +++++----------- .../share/classes/java/awt/AWTEvent.java | 25 ----------- .../share/classes/java/awt/Component.java | 28 ------------ .../share/classes/java/awt/MenuComponent.java | 24 ----------- .../share/classes/java/awt/TrayIcon.java | 22 ---------- .../classes/javax/swing/TransferHandler.java | 43 ------------------- .../share/classes/javax/swing/UIDefaults.java | 6 --- .../share/classes/sun/awt/AWTAccessor.java | 14 ------ 8 files changed, 11 insertions(+), 188 deletions(-) diff --git a/src/java.desktop/share/classes/com/sun/beans/decoder/DocumentHandler.java b/src/java.desktop/share/classes/com/sun/beans/decoder/DocumentHandler.java index a4b7981d0e6..51f84b7b172 100644 --- a/src/java.desktop/share/classes/com/sun/beans/decoder/DocumentHandler.java +++ b/src/java.desktop/share/classes/com/sun/beans/decoder/DocumentHandler.java @@ -38,9 +38,6 @@ import java.util.HashMap; import java.util.List; import java.util.Map; -import java.security.AccessControlContext; -import java.security.AccessController; -import java.security.PrivilegedAction; import javax.xml.parsers.ParserConfigurationException; import javax.xml.parsers.SAXParserFactory; @@ -62,8 +59,6 @@ * @see ElementHandler */ public final class DocumentHandler extends DefaultHandler { - @SuppressWarnings("removal") - private final AccessControlContext acc = AccessController.getContext(); private final Map<String, Class<? extends ElementHandler>> handlers = new HashMap<>(); private final Map<String, Object> environment = new HashMap<>(); private final List<Object> objects = new ArrayList<>(); @@ -367,30 +362,20 @@ public void handleException(Exception exception) { * * @param input the input source to parse */ - @SuppressWarnings("removal") public void parse(final InputSource input) { - if ((this.acc == null) && (null != System.getSecurityManager())) { - throw new SecurityException("AccessControlContext is not set"); + try { + SAXParserFactory.newInstance().newSAXParser().parse(input, DocumentHandler.this); } - AccessControlContext stack = AccessController.getContext(); - SharedSecrets.getJavaSecurityAccess().doIntersectionPrivilege(new PrivilegedAction<Void>() { - public Void run() { - try { - SAXParserFactory.newInstance().newSAXParser().parse(input, DocumentHandler.this); - } - catch (ParserConfigurationException | IOException exception) { - handleException(exception); - } - catch (SAXException wrapper) { - Exception exception = wrapper.getException(); - if (exception == null) { - exception = wrapper; - } - handleException(exception); - } - return null; + catch (ParserConfigurationException | IOException exception) { + handleException(exception); + } + catch (SAXException wrapper) { + Exception exception = wrapper.getException(); + if (exception == null) { + exception = wrapper; } - }, stack, this.acc); + handleException(exception); + } } /** diff --git a/src/java.desktop/share/classes/java/awt/AWTEvent.java b/src/java.desktop/share/classes/java/awt/AWTEvent.java index 93def2fadc9..fe9d30deaeb 100644 --- a/src/java.desktop/share/classes/java/awt/AWTEvent.java +++ b/src/java.desktop/share/classes/java/awt/AWTEvent.java @@ -39,8 +39,6 @@ import java.awt.peer.ComponentPeer; import java.awt.peer.LightweightPeer; import java.io.Serial; -import java.security.AccessControlContext; -import java.security.AccessController; import java.util.EventObject; import sun.awt.AWTAccessor; @@ -112,24 +110,6 @@ public abstract class AWTEvent extends EventObject { */ protected boolean consumed = false; - /* - * The event's AccessControlContext. - */ - @SuppressWarnings("removal") - private transient volatile AccessControlContext acc = - AccessController.getContext(); - - /* - * Returns the acc this event was constructed with. - */ - @SuppressWarnings("removal") - final AccessControlContext getAccessControlContext() { - if (acc == null) { - throw new SecurityException("AWTEvent is missing AccessControlContext"); - } - return acc; - } - transient boolean focusManagerIsDispatching = false; transient boolean isPosted; @@ -281,11 +261,6 @@ public boolean isSystemGenerated(AWTEvent ev) { return ev.isSystemGenerated; } - @SuppressWarnings("removal") - public AccessControlContext getAccessControlContext(AWTEvent ev) { - return ev.getAccessControlContext(); - } - public byte[] getBData(AWTEvent ev) { return ev.bdata; } diff --git a/src/java.desktop/share/classes/java/awt/Component.java b/src/java.desktop/share/classes/java/awt/Component.java index 36683ff2813..8bfe16619bb 100644 --- a/src/java.desktop/share/classes/java/awt/Component.java +++ b/src/java.desktop/share/classes/java/awt/Component.java @@ -69,8 +69,6 @@ import java.io.PrintWriter; import java.io.Serial; import java.io.Serializable; -import java.security.AccessControlContext; -import java.security.AccessController; import java.util.Collections; import java.util.EventListener; import java.util.HashSet; @@ -501,13 +499,6 @@ public abstract class Component implements ImageObserver, MenuContainer, static final Object LOCK = new AWTTreeLock(); static class AWTTreeLock {} - /* - * The component's AccessControlContext. - */ - @SuppressWarnings("removal") - private transient volatile AccessControlContext acc = - AccessController.getContext(); - /** * Minimum size. * (This field perhaps should have been transient). @@ -706,17 +697,6 @@ Object getObjectLock() { return objectLock; } - /* - * Returns the acc this component was constructed with. - */ - @SuppressWarnings("removal") - final AccessControlContext getAccessControlContext() { - if (acc == null) { - throw new SecurityException("Component is missing AccessControlContext"); - } - return acc; - } - /** * Whether the component is packed or not; */ @@ -972,11 +952,6 @@ public void processEvent(Component comp, AWTEvent e) { comp.processEvent(e); } - @SuppressWarnings("removal") - public AccessControlContext getAccessControlContext(Component comp) { - return comp.getAccessControlContext(); - } - public void revalidateSynchronously(Component comp) { comp.revalidateSynchronously(); } @@ -8967,15 +8942,12 @@ private void writeObject(ObjectOutputStream s) * @throws IOException if an I/O error occurs * @see #writeObject(ObjectOutputStream) */ - @SuppressWarnings("removal") @Serial private void readObject(ObjectInputStream s) throws ClassNotFoundException, IOException { objectLock = new Object(); - acc = AccessController.getContext(); - s.defaultReadObject(); appContext = AppContext.getAppContext(); diff --git a/src/java.desktop/share/classes/java/awt/MenuComponent.java b/src/java.desktop/share/classes/java/awt/MenuComponent.java index b2bc22c2e93..12a24e92842 100644 --- a/src/java.desktop/share/classes/java/awt/MenuComponent.java +++ b/src/java.desktop/share/classes/java/awt/MenuComponent.java @@ -30,8 +30,6 @@ import java.io.IOException; import java.io.ObjectInputStream; import java.io.Serial; -import java.security.AccessControlContext; -import java.security.AccessController; import javax.accessibility.Accessible; import javax.accessibility.AccessibleComponent; @@ -103,25 +101,6 @@ public abstract class MenuComponent implements java.io.Serializable { */ volatile boolean newEventsOnly; - /* - * The menu's AccessControlContext. - */ - @SuppressWarnings("removal") - private transient volatile AccessControlContext acc = - AccessController.getContext(); - - /* - * Returns the acc this menu component was constructed with. - */ - @SuppressWarnings("removal") - final AccessControlContext getAccessControlContext() { - if (acc == null) { - throw new SecurityException( - "MenuComponent is missing AccessControlContext"); - } - return acc; - } - /* * Internal constants for serialization. */ @@ -442,15 +421,12 @@ protected final Object getTreeLock() { * * @see java.awt.GraphicsEnvironment#isHeadless */ - @SuppressWarnings("removal") @Serial private void readObject(ObjectInputStream s) throws ClassNotFoundException, IOException, HeadlessException { GraphicsEnvironment.checkHeadless(); - acc = AccessController.getContext(); - s.defaultReadObject(); appContext = AppContext.getAppContext(); diff --git a/src/java.desktop/share/classes/java/awt/TrayIcon.java b/src/java.desktop/share/classes/java/awt/TrayIcon.java index cabb5dac3cf..3323818eeb1 100644 --- a/src/java.desktop/share/classes/java/awt/TrayIcon.java +++ b/src/java.desktop/share/classes/java/awt/TrayIcon.java @@ -32,8 +32,6 @@ import sun.awt.AWTAccessor; import sun.awt.HeadlessToolkit; import java.util.EventObject; -import java.security.AccessControlContext; -import java.security.AccessController; /** * A {@code TrayIcon} object represents a tray icon that can be @@ -102,26 +100,6 @@ public class TrayIcon { transient MouseMotionListener mouseMotionListener; transient ActionListener actionListener; - /* - * The tray icon's AccessControlContext. - * - * Unlike the acc in Component, this field is made final - * because TrayIcon is not serializable. - */ - @SuppressWarnings("removal") - private final AccessControlContext acc = AccessController.getContext(); - - /* - * Returns the acc this tray icon was constructed with. - */ - @SuppressWarnings("removal") - final AccessControlContext getAccessControlContext() { - if (acc == null) { - throw new SecurityException("TrayIcon is missing AccessControlContext"); - } - return acc; - } - static { Toolkit.loadLibraries(); if (!GraphicsEnvironment.isHeadless()) { diff --git a/src/java.desktop/share/classes/javax/swing/TransferHandler.java b/src/java.desktop/share/classes/javax/swing/TransferHandler.java index d12c393d66a..613d9d570b5 100644 --- a/src/java.desktop/share/classes/javax/swing/TransferHandler.java +++ b/src/java.desktop/share/classes/javax/swing/TransferHandler.java @@ -42,16 +42,6 @@ import sun.swing.*; import sun.awt.SunToolkit; -import java.security.AccessController; -import java.security.PrivilegedAction; - -import java.security.AccessControlContext; - -import jdk.internal.access.SharedSecrets; -import jdk.internal.access.JavaSecurityAccess; - -import sun.awt.AWTAccessor; - /** * This class is used to handle the transfer of a <code>Transferable</code> * to and from Swing components. The <code>Transferable</code> is used to @@ -1701,40 +1691,7 @@ public boolean accept(Object sender) { && ((JComponent)sender).getTransferHandler() == null); } - private static final JavaSecurityAccess javaSecurityAccess = - SharedSecrets.getJavaSecurityAccess(); - public void actionPerformed(final ActionEvent e) { - final Object src = e.getSource(); - - final PrivilegedAction<Void> action = new PrivilegedAction<Void>() { - public Void run() { - actionPerformedImpl(e); - return null; - } - }; - - @SuppressWarnings("removal") - final AccessControlContext stack = AccessController.getContext(); - @SuppressWarnings("removal") - final AccessControlContext srcAcc = AWTAccessor.getComponentAccessor().getAccessControlContext((Component)src); - @SuppressWarnings("removal") - final AccessControlContext eventAcc = AWTAccessor.getAWTEventAccessor().getAccessControlContext(e); - - if (srcAcc == null) { - javaSecurityAccess.doIntersectionPrivilege(action, stack, eventAcc); - } else { - javaSecurityAccess.doIntersectionPrivilege( - new PrivilegedAction<Void>() { - public Void run() { - javaSecurityAccess.doIntersectionPrivilege(action, eventAcc); - return null; - } - }, stack, srcAcc); - } - } - - private void actionPerformedImpl(ActionEvent e) { Object src = e.getSource(); if (src instanceof JComponent) { JComponent c = (JComponent) src; diff --git a/src/java.desktop/share/classes/javax/swing/UIDefaults.java b/src/java.desktop/share/classes/javax/swing/UIDefaults.java index 62939b90e70..c8d294f4fbf 100644 --- a/src/java.desktop/share/classes/javax/swing/UIDefaults.java +++ b/src/java.desktop/share/classes/javax/swing/UIDefaults.java @@ -49,8 +49,6 @@ import java.awt.Insets; import java.awt.Dimension; import java.beans.PropertyChangeListener; -import java.security.AccessController; -import java.security.AccessControlContext; import sun.reflect.misc.MethodUtil; import sun.reflect.misc.ReflectUtil; @@ -1062,8 +1060,6 @@ public interface ActiveValue { * @since 1.3 */ public static class ProxyLazyValue implements LazyValue { - @SuppressWarnings("removal") - private AccessControlContext acc; private String className; private String methodName; private Object[] args; @@ -1117,9 +1113,7 @@ public ProxyLazyValue(String c, Object[] o) { * @param o an array of <code>Objects</code> to be passed as * parameters to the static method in class c */ - @SuppressWarnings("removal") public ProxyLazyValue(String c, String m, Object[] o) { - acc = AccessController.getContext(); className = c; methodName = m; if (o != null) { diff --git a/src/java.desktop/share/classes/sun/awt/AWTAccessor.java b/src/java.desktop/share/classes/sun/awt/AWTAccessor.java index 5a3d2c46773..db107fc309c 100644 --- a/src/java.desktop/share/classes/sun/awt/AWTAccessor.java +++ b/src/java.desktop/share/classes/sun/awt/AWTAccessor.java @@ -44,7 +44,6 @@ import java.awt.peer.MenuComponentPeer; import java.lang.invoke.MethodHandles; import java.lang.reflect.InvocationTargetException; -import java.security.AccessControlContext; import java.io.File; import java.util.ResourceBundle; @@ -244,13 +243,6 @@ public interface ComponentAccessor { */ void processEvent(Component comp, AWTEvent e); - - /* - * Returns the acc this component was constructed with. - */ - @SuppressWarnings("removal") - AccessControlContext getAccessControlContext(Component comp); - /** * Revalidates the component synchronously. */ @@ -353,12 +345,6 @@ public interface AWTEventAccessor { */ boolean isSystemGenerated(AWTEvent ev); - /** - * Returns the acc this event was constructed with. - */ - @SuppressWarnings("removal") - AccessControlContext getAccessControlContext(AWTEvent ev); - /** * Returns binary data associated with this event; */ From 51763b67004a8b37d9bf4b8efef8aa1fa7bc9f4a Mon Sep 17 00:00:00 2001 From: Justin Lu <jlu@openjdk.org> Date: Fri, 22 Nov 2024 18:18:22 +0000 Subject: [PATCH 192/311] 8344525: Fix leftover ExceptionOccurred in java.base Reviewed-by: lbourges, alanb, naoto, iris --- src/java.base/share/native/libjli/java.c | 2 +- src/java.base/share/native/libzip/Deflater.c | 10 +++++----- src/java.base/share/native/libzip/Inflater.c | 8 ++++---- src/java.base/windows/native/libjava/io_util_md.c | 4 ++-- src/java.base/windows/native/libnet/net_util_md.c | 4 ++-- .../windows/native/libnio/ch/UnixDomainSockets.c | 4 ++-- 6 files changed, 16 insertions(+), 16 deletions(-) diff --git a/src/java.base/share/native/libjli/java.c b/src/java.base/share/native/libjli/java.c index 4f9a6426dff..3ceef480b47 100644 --- a/src/java.base/share/native/libjli/java.c +++ b/src/java.base/share/native/libjli/java.c @@ -650,7 +650,7 @@ JavaMain(void* _args) * The launcher's exit code (in the absence of calls to * System.exit) will be non-zero if main threw an exception. */ - if (ret && (*env)->ExceptionOccurred(env) == NULL) { + if (ret && !(*env)->ExceptionCheck(env)) { // main method was invoked and no exception was thrown from it, // return success. ret = 0; diff --git a/src/java.base/share/native/libzip/Deflater.c b/src/java.base/share/native/libzip/Deflater.c index 1ed1994d471..00d4e4125c3 100644 --- a/src/java.base/share/native/libzip/Deflater.c +++ b/src/java.base/share/native/libzip/Deflater.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -197,14 +197,14 @@ Java_java_util_zip_Deflater_deflateBytesBytes(JNIEnv *env, jobject this, jlong a jint res; if (input == NULL) { - if (inputLen != 0 && (*env)->ExceptionOccurred(env) == NULL) + if (inputLen != 0 && !(*env)->ExceptionCheck(env)) JNU_ThrowOutOfMemoryError(env, 0); return 0L; } output = (*env)->GetPrimitiveArrayCritical(env, outputArray, 0); if (output == NULL) { (*env)->ReleasePrimitiveArrayCritical(env, inputArray, input, 0); - if (outputLen != 0 && (*env)->ExceptionOccurred(env) == NULL) + if (outputLen != 0 && !(*env)->ExceptionCheck(env)) JNU_ThrowOutOfMemoryError(env, 0); return 0L; } @@ -231,7 +231,7 @@ Java_java_util_zip_Deflater_deflateBytesBuffer(JNIEnv *env, jobject this, jlong jlong retVal; jint res; if (input == NULL) { - if (inputLen != 0 && (*env)->ExceptionOccurred(env) == NULL) + if (inputLen != 0 && !(*env)->ExceptionCheck(env)) JNU_ThrowOutOfMemoryError(env, 0); return 0L; } @@ -257,7 +257,7 @@ Java_java_util_zip_Deflater_deflateBufferBytes(JNIEnv *env, jobject this, jlong jlong retVal; jint res; if (output == NULL) { - if (outputLen != 0 && (*env)->ExceptionOccurred(env) == NULL) + if (outputLen != 0 && !(*env)->ExceptionCheck(env)) JNU_ThrowOutOfMemoryError(env, 0); return 0L; } diff --git a/src/java.base/share/native/libzip/Inflater.c b/src/java.base/share/native/libzip/Inflater.c index 1f43d3d1abf..2919c3959f7 100644 --- a/src/java.base/share/native/libzip/Inflater.c +++ b/src/java.base/share/native/libzip/Inflater.c @@ -194,14 +194,14 @@ Java_java_util_zip_Inflater_inflateBytesBytes(JNIEnv *env, jobject this, jlong a jlong retVal; if (input == NULL) { - if (inputLen != 0 && (*env)->ExceptionOccurred(env) == NULL) + if (inputLen != 0 && !(*env)->ExceptionCheck(env)) JNU_ThrowOutOfMemoryError(env, 0); return 0L; } output = (*env)->GetPrimitiveArrayCritical(env, outputArray, 0); if (output == NULL) { (*env)->ReleasePrimitiveArrayCritical(env, inputArray, input, 0); - if (outputLen != 0 && (*env)->ExceptionOccurred(env) == NULL) + if (outputLen != 0 && !(*env)->ExceptionCheck(env)) JNU_ThrowOutOfMemoryError(env, 0); return 0L; } @@ -227,7 +227,7 @@ Java_java_util_zip_Inflater_inflateBytesBuffer(JNIEnv *env, jobject this, jlong jlong retVal; if (input == NULL) { - if (inputLen != 0 && (*env)->ExceptionOccurred(env) == NULL) + if (inputLen != 0 && !(*env)->ExceptionCheck(env)) JNU_ThrowOutOfMemoryError(env, 0); return 0L; } @@ -252,7 +252,7 @@ Java_java_util_zip_Inflater_inflateBufferBytes(JNIEnv *env, jobject this, jlong jlong retVal; if (output == NULL) { - if (outputLen != 0 && (*env)->ExceptionOccurred(env) == NULL) + if (outputLen != 0 && !(*env)->ExceptionCheck(env)) JNU_ThrowOutOfMemoryError(env, 0); return 0L; } diff --git a/src/java.base/windows/native/libjava/io_util_md.c b/src/java.base/windows/native/libjava/io_util_md.c index 6a8bd434280..4709bbbae24 100644 --- a/src/java.base/windows/native/libjava/io_util_md.c +++ b/src/java.base/windows/native/libjava/io_util_md.c @@ -537,7 +537,7 @@ fileDescriptorClose(JNIEnv *env, jobject this) { FD fd = (*env)->GetLongField(env, this, IO_handle_fdID); HANDLE h = (HANDLE)fd; - if ((*env)->ExceptionOccurred(env)) { + if ((*env)->ExceptionCheck(env)) { return; } @@ -552,7 +552,7 @@ fileDescriptorClose(JNIEnv *env, jobject this) * taking extra precaution over here. */ (*env)->SetLongField(env, this, IO_handle_fdID, -1); - if ((*env)->ExceptionOccurred(env)) { + if ((*env)->ExceptionCheck(env)) { return; } diff --git a/src/java.base/windows/native/libnet/net_util_md.c b/src/java.base/windows/native/libnet/net_util_md.c index 5305a02f1c2..36927beff3c 100644 --- a/src/java.base/windows/native/libnet/net_util_md.c +++ b/src/java.base/windows/native/libnet/net_util_md.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -143,7 +143,7 @@ NET_ThrowNew(JNIEnv *env, int errorNum, char *msg) /* * If exception already throw then don't overwrite it. */ - if ((*env)->ExceptionOccurred(env)) { + if ((*env)->ExceptionCheck(env)) { return; } diff --git a/src/java.base/windows/native/libnio/ch/UnixDomainSockets.c b/src/java.base/windows/native/libnio/ch/UnixDomainSockets.c index bc185b3aa18..e29d8e28efc 100644 --- a/src/java.base/windows/native/libnio/ch/UnixDomainSockets.c +++ b/src/java.base/windows/native/libnio/ch/UnixDomainSockets.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -48,7 +48,7 @@ jbyteArray sockaddrToUnixAddressBytes(JNIEnv *env, struct sockaddr_un *sa, sockl jbyteArray name = (*env)->NewByteArray(env, namelen); if (name != NULL) { (*env)->SetByteArrayRegion(env, name, 0, namelen, (jbyte*)sa->sun_path); - if ((*env)->ExceptionOccurred(env)) { + if ((*env)->ExceptionCheck(env)) { return NULL; } } From 079f503d962ad9e5ae4394c083e6877828c798ec Mon Sep 17 00:00:00 2001 From: Sonia Zaldana Calles <szaldana@openjdk.org> Date: Fri, 22 Nov 2024 18:55:31 +0000 Subject: [PATCH 193/311] 8344568: Renaming ceil_log2 to log2i_ceil Reviewed-by: kbarrett --- src/hotspot/share/classfile/dictionary.cpp | 2 +- src/hotspot/share/classfile/stringTable.cpp | 2 +- src/hotspot/share/classfile/symbolTable.cpp | 2 +- .../share/services/finalizerService.cpp | 2 +- src/hotspot/share/services/threadIdTable.cpp | 2 +- src/hotspot/share/utilities/powerOfTwo.hpp | 14 +++--- .../gtest/utilities/test_powerOfTwo.cpp | 48 +++++++++---------- 7 files changed, 36 insertions(+), 36 deletions(-) diff --git a/src/hotspot/share/classfile/dictionary.cpp b/src/hotspot/share/classfile/dictionary.cpp index 92f362860eb..a6df19ef915 100644 --- a/src/hotspot/share/classfile/dictionary.cpp +++ b/src/hotspot/share/classfile/dictionary.cpp @@ -44,7 +44,7 @@ const size_t REHASH_LEN = 100; Dictionary::Dictionary(ClassLoaderData* loader_data, size_t table_size) : _number_of_entries(0), _loader_data(loader_data) { - size_t start_size_log_2 = MAX2(ceil_log2(table_size), 2); // 2 is minimum size even though some dictionaries only have one entry + size_t start_size_log_2 = MAX2(log2i_ceil(table_size), 2); // 2 is minimum size even though some dictionaries only have one entry size_t current_size = ((size_t)1) << start_size_log_2; log_info(class, loader, data)("Dictionary start size: " SIZE_FORMAT " (" SIZE_FORMAT ")", current_size, start_size_log_2); diff --git a/src/hotspot/share/classfile/stringTable.cpp b/src/hotspot/share/classfile/stringTable.cpp index 4de4b8e333c..d6aedcbb157 100644 --- a/src/hotspot/share/classfile/stringTable.cpp +++ b/src/hotspot/share/classfile/stringTable.cpp @@ -309,7 +309,7 @@ class StringTableLookupOop : public StringTableLookup { }; void StringTable::create_table() { - size_t start_size_log_2 = ceil_log2(StringTableSize); + size_t start_size_log_2 = log2i_ceil(StringTableSize); _current_size = ((size_t)1) << start_size_log_2; log_trace(stringtable)("Start size: " SIZE_FORMAT " (" SIZE_FORMAT ")", _current_size, start_size_log_2); diff --git a/src/hotspot/share/classfile/symbolTable.cpp b/src/hotspot/share/classfile/symbolTable.cpp index 50453cee61d..040ba4795e4 100644 --- a/src/hotspot/share/classfile/symbolTable.cpp +++ b/src/hotspot/share/classfile/symbolTable.cpp @@ -212,7 +212,7 @@ class SymbolTableConfig : public AllStatic { }; void SymbolTable::create_table () { - size_t start_size_log_2 = ceil_log2(SymbolTableSize); + size_t start_size_log_2 = log2i_ceil(SymbolTableSize); _current_size = ((size_t)1) << start_size_log_2; log_trace(symboltable)("Start size: " SIZE_FORMAT " (" SIZE_FORMAT ")", _current_size, start_size_log_2); diff --git a/src/hotspot/share/services/finalizerService.cpp b/src/hotspot/share/services/finalizerService.cpp index fd46827ee00..92d1111ce26 100644 --- a/src/hotspot/share/services/finalizerService.cpp +++ b/src/hotspot/share/services/finalizerService.cpp @@ -266,7 +266,7 @@ void FinalizerService::do_concurrent_work(JavaThread* service_thread) { void FinalizerService::init() { assert(_table == nullptr, "invariant"); - const size_t start_size_log_2 = ceil_log2(DEFAULT_TABLE_SIZE); + const size_t start_size_log_2 = log2i_ceil(DEFAULT_TABLE_SIZE); _table = new FinalizerHashtable(start_size_log_2, MAX_SIZE, FinalizerHashtable::DEFAULT_GROW_HINT); } diff --git a/src/hotspot/share/services/threadIdTable.cpp b/src/hotspot/share/services/threadIdTable.cpp index 0a9c1233971..90d17532c4d 100644 --- a/src/hotspot/share/services/threadIdTable.cpp +++ b/src/hotspot/share/services/threadIdTable.cpp @@ -112,7 +112,7 @@ void ThreadIdTable::lazy_initialize(const ThreadsList *threads) { void ThreadIdTable::create_table(size_t size) { assert(_local_table == nullptr, "Thread table is already created"); - size_t size_log = ceil_log2(size); + size_t size_log = log2i_ceil(size); size_t start_size_log = size_log > DEFAULT_TABLE_SIZE_LOG ? size_log : DEFAULT_TABLE_SIZE_LOG; _current_size = (size_t)1 << start_size_log; diff --git a/src/hotspot/share/utilities/powerOfTwo.hpp b/src/hotspot/share/utilities/powerOfTwo.hpp index 6c1e413f403..b40c3fb7404 100644 --- a/src/hotspot/share/utilities/powerOfTwo.hpp +++ b/src/hotspot/share/utilities/powerOfTwo.hpp @@ -79,6 +79,13 @@ inline int log2i_exact(T value) { return count_trailing_zeros(value); } +// Ceiling of log2 of a positive, integral value, i.e., smallest i such that value <= 2^i. +template <typename T, ENABLE_IF(std::is_integral<T>::value)> +inline int log2i_ceil(T value) { + assert(value > 0, "Invalid value"); + return log2i_graceful(value - 1) + 1; +} + // Preconditions: value != 0, and the unsigned representation of value is a power of two inline int exact_log2(intptr_t value) { return log2i_exact((uintptr_t)value); @@ -120,13 +127,6 @@ inline T next_power_of_2(T value) { return T(round_up_power_of_2(value + 1)); } -// Find log2 value greater than this input -template <typename T, ENABLE_IF(std::is_integral<T>::value)> -inline int ceil_log2(T value) { - assert(value > 0, "Invalid value"); - return log2i_graceful(value - 1) + 1; -} - // Return the largest power of two that is a submultiple of the given value. // This is the same as the numeric value of the least-significant set bit. // For unsigned values, it replaces the old trick of (value & -value). diff --git a/test/hotspot/gtest/utilities/test_powerOfTwo.cpp b/test/hotspot/gtest/utilities/test_powerOfTwo.cpp index fc4080bcefd..850421a5517 100644 --- a/test/hotspot/gtest/utilities/test_powerOfTwo.cpp +++ b/test/hotspot/gtest/utilities/test_powerOfTwo.cpp @@ -306,43 +306,43 @@ TEST(power_of_2, log2i) { check_log2i_variants_for((jlong)0); } -template <typename T> void test_ceil_log2() { - EXPECT_EQ(ceil_log2(T(1)), 0) << "value = " << T(1); - EXPECT_EQ(ceil_log2(T(2)), 1) << "value = " << T(2); - EXPECT_EQ(ceil_log2(T(3)), 2) << "value = " << T(3); - EXPECT_EQ(ceil_log2(T(4)), 2) << "value = " << T(4); - EXPECT_EQ(ceil_log2(T(5)), 3) << "value = " << T(5); - EXPECT_EQ(ceil_log2(T(6)), 3) << "value = " << T(6); - EXPECT_EQ(ceil_log2(T(7)), 3) << "value = " << T(7); - EXPECT_EQ(ceil_log2(T(8)), 3) << "value = " << T(8); - EXPECT_EQ(ceil_log2(T(9)), 4) << "value = " << T(9); - EXPECT_EQ(ceil_log2(T(10)), 4) << "value = " << T(10); +template <typename T> void test_log2i_ceil() { + EXPECT_EQ(log2i_ceil(T(1)), 0) << "value = " << T(1); + EXPECT_EQ(log2i_ceil(T(2)), 1) << "value = " << T(2); + EXPECT_EQ(log2i_ceil(T(3)), 2) << "value = " << T(3); + EXPECT_EQ(log2i_ceil(T(4)), 2) << "value = " << T(4); + EXPECT_EQ(log2i_ceil(T(5)), 3) << "value = " << T(5); + EXPECT_EQ(log2i_ceil(T(6)), 3) << "value = " << T(6); + EXPECT_EQ(log2i_ceil(T(7)), 3) << "value = " << T(7); + EXPECT_EQ(log2i_ceil(T(8)), 3) << "value = " << T(8); + EXPECT_EQ(log2i_ceil(T(9)), 4) << "value = " << T(9); + EXPECT_EQ(log2i_ceil(T(10)), 4) << "value = " << T(10); // Test max values if (std::is_unsigned<T>::value) { - EXPECT_EQ(ceil_log2(std::numeric_limits<T>::max()), + EXPECT_EQ(log2i_ceil(std::numeric_limits<T>::max()), (int)(sizeof(T) * 8)) << "value = " << std::numeric_limits<T>::max(); } else { - EXPECT_EQ(ceil_log2(std::numeric_limits<T>::max()), + EXPECT_EQ(log2i_ceil(std::numeric_limits<T>::max()), (int)(sizeof(T) * 8 - 1)) << "value = " << std::numeric_limits<T>::max(); } } -TEST(power_of_2, ceil_log2) { - test_ceil_log2<int8_t>(); - test_ceil_log2<int16_t>(); - test_ceil_log2<int32_t>(); - test_ceil_log2<int64_t>(); - test_ceil_log2<uint8_t>(); - test_ceil_log2<uint16_t>(); - test_ceil_log2<uint32_t>(); - test_ceil_log2<uint64_t>(); +TEST(power_of_2, log2i_ceil) { + test_log2i_ceil<int8_t>(); + test_log2i_ceil<int16_t>(); + test_log2i_ceil<int32_t>(); + test_log2i_ceil<int64_t>(); + test_log2i_ceil<uint8_t>(); + test_log2i_ceil<uint16_t>(); + test_log2i_ceil<uint32_t>(); + test_log2i_ceil<uint64_t>(); } #ifdef ASSERT -TEST_VM_ASSERT_MSG(power_of_2, ceil_log2_invalid, +TEST_VM_ASSERT_MSG(power_of_2, log2i_ceil_invalid, ".*Invalid value") { - ceil_log2(0); + log2i_ceil(0); } #endif // ASSERT From 6aec2dcf76322ee92b62b5a063354057351d65e1 Mon Sep 17 00:00:00 2001 From: Sean Mullan <mullan@openjdk.org> Date: Fri, 22 Nov 2024 19:14:02 +0000 Subject: [PATCH 194/311] 8344788: Specify that the access control context parameters of Subject.doAsPrivileged are ignored Reviewed-by: alanb --- .../share/classes/javax/security/auth/Subject.java | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/src/java.base/share/classes/javax/security/auth/Subject.java b/src/java.base/share/classes/javax/security/auth/Subject.java index f6cc6e5e346..5c5726ca38f 100644 --- a/src/java.base/share/classes/javax/security/auth/Subject.java +++ b/src/java.base/share/classes/javax/security/auth/Subject.java @@ -474,8 +474,8 @@ public static <T> T doAs(final Subject subject, /** * Perform privileged work as a particular {@code Subject}. * - * <p> This method ignores the {@code acc} argument, launches {@code action}, - * and binds {@code subject} to the period of its execution. + * <p> This method launches {@code action} and binds {@code subject} to + * the period of its execution. * * @param subject the {@code Subject} that the specified * {@code action} will run as. This parameter @@ -487,8 +487,7 @@ public static <T> T doAs(final Subject subject, * @param action the code to be run as the specified * {@code Subject}. * - * @param acc the {@code AccessControlContext} to be tied to the - * specified <i>subject</i> and <i>action</i>. + * @param acc ignored * * @return the value returned by the PrivilegedAction's * {@code run} method. @@ -540,8 +539,8 @@ public static <T> T doAsPrivileged(final Subject subject, /** * Perform privileged work as a particular {@code Subject}. * - * <p> This method ignores the {@code acc} argument, launches {@code action}, - * and binds {@code subject} to the period of its execution. + * <p> This method launches {@code action} and binds {@code subject} to + * the period of its execution. * * @param subject the {@code Subject} that the specified * {@code action} will run as. This parameter @@ -553,8 +552,7 @@ public static <T> T doAsPrivileged(final Subject subject, * @param action the code to be run as the specified * {@code Subject}. * - * @param acc the {@code AccessControlContext} to be tied to the - * specified <i>subject</i> and <i>action</i>. + * @param acc ignored * * @return the value returned by the * PrivilegedExceptionAction's {@code run} method. From 1b2d9cad532d9b047b8556ed8c9d75f83f75efe0 Mon Sep 17 00:00:00 2001 From: Harshitha Onkar <honkar@openjdk.org> Date: Fri, 22 Nov 2024 19:16:54 +0000 Subject: [PATCH 195/311] 8344881: Problemlist java/awt/Robot/InfiniteLoopException.java on Linux Reviewed-by: prr, dnguyen --- test/jdk/ProblemList.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/jdk/ProblemList.txt b/test/jdk/ProblemList.txt index 65fe0e71a2f..90a6dc18e6d 100644 --- a/test/jdk/ProblemList.txt +++ b/test/jdk/ProblemList.txt @@ -466,7 +466,7 @@ java/awt/event/MouseEvent/FrameMouseEventAbsoluteCoordsTest/FrameMouseEventAbsol # Several tests which fail sometimes on macos11 java/awt/Window/MainKeyWindowTest/TestMainKeyWindow.java 8265985 macosx-all java/awt/Robot/Delay/InterruptOfDelay.java 8265986 macosx-all -java/awt/Robot/InfiniteLoopException.java 8342638 windows-all +java/awt/Robot/InfiniteLoopException.java 8342638 windows-all,linux-all java/awt/MenuBar/TestNoScreenMenuBar.java 8265987 macosx-all java/awt/Graphics2D/DrawString/DrawRotatedStringUsingRotatedFont.java 8266283 generic-all From 98b667834c4a8f0d0ab54b8133061bc475674732 Mon Sep 17 00:00:00 2001 From: Leonid Mesnik <lmesnik@openjdk.org> Date: Fri, 22 Nov 2024 19:21:09 +0000 Subject: [PATCH 196/311] 8343741: SA jstack --mixed should print information about VM locks Reviewed-by: cjplummer --- src/hotspot/share/prims/whitebox.cpp | 11 +++ src/hotspot/share/runtime/mutex.cpp | 65 ++++++++++++++ src/hotspot/share/runtime/mutex.hpp | 11 +++ src/hotspot/share/runtime/mutexLocker.cpp | 68 +-------------- src/hotspot/share/runtime/mutexLocker.hpp | 5 -- src/hotspot/share/runtime/vmOperations.hpp | 12 +++ src/hotspot/share/runtime/vmStructs.cpp | 10 ++- src/hotspot/share/utilities/vmError.cpp | 2 +- .../sun/jvm/hotspot/runtime/Mutex.java | 75 ++++++++++++++++ .../sun/jvm/hotspot/runtime/Thread.java | 9 +- .../jvm/hotspot/runtime/VMLocksPrinter.java | 70 +++++++++++++++ .../classes/sun/jvm/hotspot/tools/PStack.java | 7 ++ test/hotspot/jtreg/ProblemList-zgc.txt | 1 + .../jtreg/serviceability/sa/ClhsdbField.java | 4 +- .../sa/ClhsdbVmStructsDump.java | 4 +- .../sa/LingeredAppWithLockInVM.java | 55 ++++++++++++ .../sa/TestJhsdbJstackPrintVMLocks.java | 85 +++++++++++++++++++ test/lib/jdk/test/lib/apps/LingeredApp.java | 7 ++ test/lib/jdk/test/whitebox/WhiteBox.java | 2 + 19 files changed, 424 insertions(+), 79 deletions(-) create mode 100644 src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/Mutex.java create mode 100644 src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/VMLocksPrinter.java create mode 100644 test/hotspot/jtreg/serviceability/sa/LingeredAppWithLockInVM.java create mode 100644 test/hotspot/jtreg/serviceability/sa/TestJhsdbJstackPrintVMLocks.java diff --git a/src/hotspot/share/prims/whitebox.cpp b/src/hotspot/share/prims/whitebox.cpp index a8607bb2efd..93c1acea1db 100644 --- a/src/hotspot/share/prims/whitebox.cpp +++ b/src/hotspot/share/prims/whitebox.cpp @@ -186,6 +186,16 @@ WB_ENTRY(jstring, WB_PrintString(JNIEnv* env, jobject wb, jstring str, jint max_ return (jstring) JNIHandles::make_local(THREAD, result); WB_END +WB_ENTRY(jint, WB_TakeLockAndHangInSafepoint(JNIEnv* env, jobject wb)) + JavaThread* self = JavaThread::current(); + // VMStatistic_lock is used to minimize interference with VM locking + MutexLocker mu(VMStatistic_lock); + VM_HangInSafepoint force_safepoint_stuck_op; + VMThread::execute(&force_safepoint_stuck_op); + ShouldNotReachHere(); + return 0; +WB_END + class WBIsKlassAliveClosure : public LockedClassesDo { Symbol* _name; int _count; @@ -2988,6 +2998,7 @@ static JNINativeMethod methods[] = { {CC"cleanMetaspaces", CC"()V", (void*)&WB_CleanMetaspaces}, {CC"rss", CC"()J", (void*)&WB_Rss}, {CC"printString", CC"(Ljava/lang/String;I)Ljava/lang/String;", (void*)&WB_PrintString}, + {CC"lockAndStuckInSafepoint", CC"()V", (void*)&WB_TakeLockAndHangInSafepoint}, {CC"wordSize", CC"()J", (void*)&WB_WordSize}, {CC"rootChunkWordSize", CC"()J", (void*)&WB_RootChunkWordSize} }; diff --git a/src/hotspot/share/runtime/mutex.cpp b/src/hotspot/share/runtime/mutex.cpp index 6466d18e538..0b1a79307f1 100644 --- a/src/hotspot/share/runtime/mutex.cpp +++ b/src/hotspot/share/runtime/mutex.cpp @@ -267,6 +267,16 @@ bool Monitor::wait(uint64_t timeout) { return wait_status != 0; // return true IFF timeout } +static const int MAX_NUM_MUTEX = 1204; +static Mutex* _internal_mutex_arr[MAX_NUM_MUTEX]; +Mutex** Mutex::_mutex_array = _internal_mutex_arr; +int Mutex::_num_mutex = 0; + +void Mutex::add_mutex(Mutex* var) { + assert(Mutex::_num_mutex < MAX_NUM_MUTEX, "increase MAX_NUM_MUTEX"); + Mutex::_mutex_array[_num_mutex++] = var; +} + Mutex::~Mutex() { assert_owner(nullptr); os::free(const_cast<char*>(_name)); @@ -524,6 +534,61 @@ void Mutex::set_owner_implementation(Thread *new_owner) { } #endif // ASSERT +// Print all mutexes/monitors that are currently owned by a thread; called +// by fatal error handler. +void Mutex::print_owned_locks_on_error(outputStream* st) { + st->print("VM Mutex/Monitor currently owned by a thread: "); + bool none = true; + for (int i = 0; i < _num_mutex; i++) { + // see if it has an owner + if (_mutex_array[i]->owner() != nullptr) { + if (none) { + // print format used by Mutex::print_on_error() + st->print_cr(" ([mutex/lock_event])"); + none = false; + } + _mutex_array[i]->print_on_error(st); + st->cr(); + } + } + if (none) st->print_cr("None"); +} + +void Mutex::print_lock_ranks(outputStream* st) { + st->print_cr("VM Mutex/Monitor ranks: "); + +#ifdef ASSERT + // Be extra defensive and figure out the bounds on + // ranks right here. This also saves a bit of time + // in the #ranks*#mutexes loop below. + int min_rank = INT_MAX; + int max_rank = INT_MIN; + for (int i = 0; i < _num_mutex; i++) { + Mutex* m = _mutex_array[i]; + int r = (int) m->rank(); + if (min_rank > r) min_rank = r; + if (max_rank < r) max_rank = r; + } + + // Print the listings rank by rank + for (int r = min_rank; r <= max_rank; r++) { + bool first = true; + for (int i = 0; i < _num_mutex; i++) { + Mutex* m = _mutex_array[i]; + if (r != (int) m->rank()) continue; + + if (first) { + st->cr(); + st->print_cr("Rank \"%s\":", m->rank_name()); + first = false; + } + st->print_cr(" %s", m->name()); + } + } +#else + st->print_cr(" Only known in debug builds."); +#endif // ASSERT +} RecursiveMutex::RecursiveMutex() : _sem(1), _owner(nullptr), _recursions(0) {} diff --git a/src/hotspot/share/runtime/mutex.hpp b/src/hotspot/share/runtime/mutex.hpp index 8818447e5dd..5ed73507150 100644 --- a/src/hotspot/share/runtime/mutex.hpp +++ b/src/hotspot/share/runtime/mutex.hpp @@ -51,6 +51,7 @@ class Mutex : public CHeapObj<mtSynchronizer> { + friend class VMStructs; public: // Special low level locks are given names and ranges avoid overlap. enum class Rank { @@ -103,6 +104,9 @@ class Mutex : public CHeapObj<mtSynchronizer> { #ifndef PRODUCT bool _allow_vm_block; #endif + static Mutex** _mutex_array; + static int _num_mutex; + #ifdef ASSERT Rank _rank; // rank (to avoid/detect potential deadlocks) Mutex* _next; // Used by a Thread to link up owned locks @@ -194,11 +198,18 @@ class Mutex : public CHeapObj<mtSynchronizer> { const char *name() const { return _name; } + static void add_mutex(Mutex* var); + void print_on_error(outputStream* st) const; #ifndef PRODUCT void print_on(outputStream* st) const; void print() const; #endif + + // Print all mutexes/monitors that are currently owned by a thread; called + // by fatal error handler. + static void print_owned_locks_on_error(outputStream* st); + static void print_lock_ranks(outputStream* st); }; class Monitor : public Mutex { diff --git a/src/hotspot/share/runtime/mutexLocker.cpp b/src/hotspot/share/runtime/mutexLocker.cpp index a0a6e5626e4..3d5b49f56ce 100644 --- a/src/hotspot/share/runtime/mutexLocker.cpp +++ b/src/hotspot/share/runtime/mutexLocker.cpp @@ -158,10 +158,6 @@ Monitor* JVMCIRuntime_lock = nullptr; // Only one RecursiveMutex RecursiveMutex* MultiArray_lock = nullptr; -#define MAX_NUM_MUTEX 128 -static Mutex* _mutex_array[MAX_NUM_MUTEX]; -static int _num_mutex; - #ifdef ASSERT void assert_locked_or_safepoint(const Mutex* lock) { if (DebuggingContext::is_enabled() || VMError::is_error_reported()) return; @@ -182,18 +178,13 @@ void assert_lock_strong(const Mutex* lock) { } #endif -static void add_mutex(Mutex* var) { - assert(_num_mutex < MAX_NUM_MUTEX, "increase MAX_NUM_MUTEX"); - _mutex_array[_num_mutex++] = var; -} - #define MUTEX_STORAGE_NAME(name) name##_storage #define MUTEX_STORAGE(name, type) alignas(type) static uint8_t MUTEX_STORAGE_NAME(name)[sizeof(type)] #define MUTEX_DEF(name, type, pri, ...) { \ assert(name == nullptr, "Mutex/Monitor initialized twice"); \ MUTEX_STORAGE(name, type); \ name = ::new(static_cast<void*>(MUTEX_STORAGE_NAME(name))) type((pri), #name, ##__VA_ARGS__); \ - add_mutex(name); \ + Mutex::add_mutex(name); \ } #define MUTEX_DEFN(name, type, pri, ...) MUTEX_DEF(name, type, Mutex::pri, ##__VA_ARGS__) @@ -371,7 +362,7 @@ void MutexLockerImpl::post_initialize() { if (lt.is_enabled()) { ResourceMark rm; LogStream ls(lt); - print_lock_ranks(&ls); + Mutex::print_lock_ranks(&ls); } } @@ -385,58 +376,3 @@ GCMutexLocker::GCMutexLocker(Mutex* mutex) { } } -// Print all mutexes/monitors that are currently owned by a thread; called -// by fatal error handler. -void print_owned_locks_on_error(outputStream* st) { - st->print("VM Mutex/Monitor currently owned by a thread: "); - bool none = true; - for (int i = 0; i < _num_mutex; i++) { - // see if it has an owner - if (_mutex_array[i]->owner() != nullptr) { - if (none) { - // print format used by Mutex::print_on_error() - st->print_cr(" ([mutex/lock_event])"); - none = false; - } - _mutex_array[i]->print_on_error(st); - st->cr(); - } - } - if (none) st->print_cr("None"); -} - -void print_lock_ranks(outputStream* st) { - st->print_cr("VM Mutex/Monitor ranks: "); - -#ifdef ASSERT - // Be extra defensive and figure out the bounds on - // ranks right here. This also saves a bit of time - // in the #ranks*#mutexes loop below. - int min_rank = INT_MAX; - int max_rank = INT_MIN; - for (int i = 0; i < _num_mutex; i++) { - Mutex* m = _mutex_array[i]; - int r = (int) m->rank(); - if (min_rank > r) min_rank = r; - if (max_rank < r) max_rank = r; - } - - // Print the listings rank by rank - for (int r = min_rank; r <= max_rank; r++) { - bool first = true; - for (int i = 0; i < _num_mutex; i++) { - Mutex* m = _mutex_array[i]; - if (r != (int) m->rank()) continue; - - if (first) { - st->cr(); - st->print_cr("Rank \"%s\":", m->rank_name()); - first = false; - } - st->print_cr(" %s", m->name()); - } - } -#else - st->print_cr(" Only known in debug builds."); -#endif // ASSERT -} diff --git a/src/hotspot/share/runtime/mutexLocker.hpp b/src/hotspot/share/runtime/mutexLocker.hpp index 7cca1d94bf2..0e0c0435443 100644 --- a/src/hotspot/share/runtime/mutexLocker.hpp +++ b/src/hotspot/share/runtime/mutexLocker.hpp @@ -171,11 +171,6 @@ extern Mutex* tty_lock; // lock to synchronize output // order. If their implementations change such that these assumptions // are violated, a whole lot of code will break. -// Print all mutexes/monitors that are currently owned by a thread; called -// by fatal error handler. -void print_owned_locks_on_error(outputStream* st); -void print_lock_ranks(outputStream* st); - // for debugging: check that we're already owning this lock (or are at a safepoint / handshake) #ifdef ASSERT void assert_locked_or_safepoint(const Mutex* lock); diff --git a/src/hotspot/share/runtime/vmOperations.hpp b/src/hotspot/share/runtime/vmOperations.hpp index ea7f62df37d..baeea722dce 100644 --- a/src/hotspot/share/runtime/vmOperations.hpp +++ b/src/hotspot/share/runtime/vmOperations.hpp @@ -60,6 +60,18 @@ class VM_ForceSafepoint: public VM_EmptyOperation { VMOp_Type type() const { return VMOp_ForceSafepoint; } }; +// used by whitebox API to emulate VM issues +// when VM can't operate and doesn't respond to jcmd +class VM_HangInSafepoint: public VM_Operation { +public: + VMOp_Type type() const { return VMOp_ForceSafepoint; } + void doit() { + while(true) { + os::naked_short_sleep(10); + } + } +}; + class VM_ClearICs: public VM_Operation { private: bool _preserve_static_stubs; diff --git a/src/hotspot/share/runtime/vmStructs.cpp b/src/hotspot/share/runtime/vmStructs.cpp index a1c1551ae09..6fa57acf3ce 100644 --- a/src/hotspot/share/runtime/vmStructs.cpp +++ b/src/hotspot/share/runtime/vmStructs.cpp @@ -659,7 +659,6 @@ volatile_nonstatic_field(JavaThread, _is_method_handle_return, int) \ nonstatic_field(JavaThread, _saved_exception_pc, address) \ volatile_nonstatic_field(JavaThread, _thread_state, JavaThreadState) \ - nonstatic_field(JavaThread, _osthread, OSThread*) \ nonstatic_field(JavaThread, _stack_base, address) \ nonstatic_field(JavaThread, _stack_size, size_t) \ nonstatic_field(JavaThread, _vframe_array_head, vframeArray*) \ @@ -667,6 +666,7 @@ nonstatic_field(JavaThread, _active_handles, JNIHandleBlock*) \ nonstatic_field(JavaThread, _lock_id, int64_t) \ volatile_nonstatic_field(JavaThread, _terminated, JavaThread::TerminatedTypes) \ + nonstatic_field(Thread, _osthread, OSThread*) \ nonstatic_field(Thread, _resource_area, ResourceArea*) \ nonstatic_field(CompilerThread, _env, ciEnv*) \ \ @@ -1022,7 +1022,12 @@ nonstatic_field(elapsedTimer, _active, bool) \ nonstatic_field(InvocationCounter, _counter, unsigned int) \ \ - nonstatic_field(UpcallStub::FrameData, jfa, JavaFrameAnchor) + nonstatic_field(UpcallStub::FrameData, jfa, JavaFrameAnchor) \ + \ + nonstatic_field(Mutex, _name, const char*) \ + static_field(Mutex, _mutex_array, Mutex**) \ + static_field(Mutex, _num_mutex, int) \ + volatile_nonstatic_field(Mutex, _owner, Thread*) //-------------------------------------------------------------------------------- // VM_TYPES @@ -1936,6 +1941,7 @@ declare_toplevel_type(JNIid) \ declare_toplevel_type(JNIid*) \ declare_toplevel_type(jmethodID*) \ + declare_toplevel_type(Mutex) \ declare_toplevel_type(Mutex*) \ declare_toplevel_type(nmethod*) \ COMPILER2_PRESENT(declare_unsigned_integer_type(node_idx_t)) \ diff --git a/src/hotspot/share/utilities/vmError.cpp b/src/hotspot/share/utilities/vmError.cpp index 23db59f766a..cdece538cba 100644 --- a/src/hotspot/share/utilities/vmError.cpp +++ b/src/hotspot/share/utilities/vmError.cpp @@ -1223,7 +1223,7 @@ void VMError::report(outputStream* st, bool _verbose) { STEP_IF("printing owned locks on error", _verbose) // mutexes/monitors that currently have an owner - print_owned_locks_on_error(st); + Mutex::print_owned_locks_on_error(st); st->cr(); STEP_IF("printing number of OutOfMemoryError and StackOverflow exceptions", diff --git a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/Mutex.java b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/Mutex.java new file mode 100644 index 00000000000..bcd08f0d52c --- /dev/null +++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/Mutex.java @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +package sun.jvm.hotspot.runtime; + +import sun.jvm.hotspot.debugger.Address; +import sun.jvm.hotspot.types.AddressField; +import sun.jvm.hotspot.types.Type; +import sun.jvm.hotspot.types.TypeDataBase; +import sun.jvm.hotspot.types.WrongTypeException; +import sun.jvm.hotspot.utilities.*; + +public class Mutex extends VMObject { + private static long nameFieldOffset; + private static long ownerFieldOffset; + + private static AddressField mutex_array; + private static int maxNum; + + private static final long addrSize = VM.getVM().getAddressSize(); + + static { + VM.registerVMInitializedObserver(new Observer() { + public void update(Observable o, Object data) { + initialize(VM.getVM().getTypeDataBase()); + } + }); + } + + private static synchronized void initialize(TypeDataBase db) throws WrongTypeException { + Type type = db.lookupType("Mutex"); + + sun.jvm.hotspot.types.Field nameField = type.getField("_name"); + nameFieldOffset = nameField.getOffset(); + sun.jvm.hotspot.types.Field ownerField = type.getField("_owner"); + ownerFieldOffset = ownerField.getOffset(); + + mutex_array = type.getAddressField("_mutex_array"); + maxNum = type.getCIntegerField("_num_mutex").getJInt(); + } + + public Mutex(Address addr) { + super(addr); + } + + public String name() { return CStringUtilities.getString(addr.getAddressAt(nameFieldOffset)); } + + public Address owner() { return addr.getAddressAt(ownerFieldOffset); } + + public static Address at(int i) { return mutex_array.getValue().getAddressAt(i * addrSize); } + + public static int maxNum() { return maxNum; } + +} diff --git a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/Thread.java b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/Thread.java index 8267f12a9e9..d9828b06e26 100644 --- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/Thread.java +++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/Thread.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -37,6 +37,7 @@ public class Thread extends VMObject { private static AddressField currentPendingMonitorField; private static AddressField currentWaitingMonitorField; + private static AddressField osThreadField; private static JLongField allocatedBytesField; @@ -53,6 +54,8 @@ private static synchronized void initialize(TypeDataBase db) { Type typeJavaThread = db.lookupType("JavaThread"); suspendFlagsField = typeJavaThread.getCIntegerField("_suspend_flags"); + osThreadField = typeThread.getAddressField("_osthread"); + tlabFieldOffset = typeThread.getField("_tlab").getOffset(); currentPendingMonitorField = typeJavaThread.getAddressField("_current_pending_monitor"); @@ -123,6 +126,10 @@ public boolean isInStack(Address a) { return false; } + public OSThread osThread() { + return new OSThread(osThreadField.getValue(addr)); + } + /** Assistance for ObjectMonitor implementation */ Address threadObjectAddress() { return addr; } } diff --git a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/VMLocksPrinter.java b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/VMLocksPrinter.java new file mode 100644 index 00000000000..4fa0feeb6ce --- /dev/null +++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/runtime/VMLocksPrinter.java @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +package sun.jvm.hotspot.runtime; + +import sun.jvm.hotspot.debugger.Address; +import sun.jvm.hotspot.memory.SystemDictionary; +import sun.jvm.hotspot.oops.DefaultHeapVisitor; +import sun.jvm.hotspot.oops.Klass; +import sun.jvm.hotspot.oops.ObjectHeap; +import sun.jvm.hotspot.oops.Oop; +import sun.jvm.hotspot.oops.OopUtilities; + +import java.io.PrintStream; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class VMLocksPrinter { + private PrintStream tty; + private Threads threads = VM.getVM().getThreads(); + + public VMLocksPrinter(PrintStream tty) { + this.tty = tty; + } + + private String ownerThreadName(Address addr) { + try { + JavaThread thread = VM.getVM().getThreads().createJavaThreadWrapper(addr); + return thread.getThreadName(); + } catch (Exception e) { + return "Unknown thread"; + } + } + + public void printVMLocks() { + int maxNum = Mutex.maxNum(); + for (int i = 0; i < maxNum; i++) { + Mutex mutex = new Mutex(Mutex.at(i)); + if (mutex.owner() != null) { + sun.jvm.hotspot.runtime.Thread t = new sun.jvm.hotspot.runtime.Thread(mutex.owner()); + int nativeThreadId = t.osThread().threadId(); + tty.println("Internal VM Mutex " + mutex.name() + " is owned by " + ownerThreadName(mutex.owner()) + + ", nid=" + nativeThreadId + ", address=" + mutex.owner()); + } + } + } +} diff --git a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/tools/PStack.java b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/tools/PStack.java index 8f09dcc48ef..2f48c75eb78 100644 --- a/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/tools/PStack.java +++ b/src/jdk.hotspot.agent/share/classes/sun/jvm/hotspot/tools/PStack.java @@ -81,6 +81,13 @@ public void run(PrintStream out, Debugger dbg) { out.println("can't print deadlock information: " + exp); } + try { + VMLocksPrinter vmLocksPrinter = new VMLocksPrinter(out); + vmLocksPrinter.printVMLocks(); + } catch (Exception e) { + out.println("can't print VM locks information: " + e); + } + List<ThreadProxy> l = cdbg.getThreadList(); if (l.isEmpty() && PlatformInfo.getOS().equals("darwin")) { // If the list is empty, we assume we attached to a process, and on OSX we can only diff --git a/test/hotspot/jtreg/ProblemList-zgc.txt b/test/hotspot/jtreg/ProblemList-zgc.txt index 0d4cfe1cbb6..1366096f346 100644 --- a/test/hotspot/jtreg/ProblemList-zgc.txt +++ b/test/hotspot/jtreg/ProblemList-zgc.txt @@ -92,6 +92,7 @@ serviceability/sa/TestIntConstant.java 8307393 generic- serviceability/sa/TestJhsdbJstackLineNumbers.java 8307393 generic-all serviceability/sa/TestJhsdbJstackLock.java 8307393 generic-all serviceability/sa/TestJhsdbJstackMixed.java 8307393 generic-all +serviceability/sa/TestJhsdbJstackPrintVMLocks.java 8307393 generic-all serviceability/sa/TestJhsdbJstackUpcall.java 8307393 generic-all serviceability/sa/TestJmapCore.java 8307393 generic-all serviceability/sa/TestJmapCoreMetaspace.java 8307393 generic-all diff --git a/test/hotspot/jtreg/serviceability/sa/ClhsdbField.java b/test/hotspot/jtreg/serviceability/sa/ClhsdbField.java index 2ed557f8e94..18f40603505 100644 --- a/test/hotspot/jtreg/serviceability/sa/ClhsdbField.java +++ b/test/hotspot/jtreg/serviceability/sa/ClhsdbField.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -55,7 +55,7 @@ public static void main(String[] args) throws Exception { "field InstanceKlass _methods Array<Method*>*", "field InstanceKlass _constants ConstantPool*", "field Klass _name Symbol*", - "field JavaThread _osthread OSThread*", + "field Thread _osthread OSThread*", "field TenuredGeneration _the_space ContiguousSpace*", "field VirtualSpace _low_boundary char*", "field MethodCounters _backedge_counter InvocationCounter", diff --git a/test/hotspot/jtreg/serviceability/sa/ClhsdbVmStructsDump.java b/test/hotspot/jtreg/serviceability/sa/ClhsdbVmStructsDump.java index 050ec9c05d6..8ca5b5e6e38 100644 --- a/test/hotspot/jtreg/serviceability/sa/ClhsdbVmStructsDump.java +++ b/test/hotspot/jtreg/serviceability/sa/ClhsdbVmStructsDump.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -56,7 +56,7 @@ public static void main(String[] args) throws Exception { "field InstanceKlass _constants ConstantPool*", "field Klass _name Symbol*", "type ClassLoaderData* null", - "field JavaThread _osthread OSThread*", + "field Thread _osthread OSThread*", "type TenuredGeneration Generation", "type Universe null", "type ConstantPoolCache MetaspaceObj")); diff --git a/test/hotspot/jtreg/serviceability/sa/LingeredAppWithLockInVM.java b/test/hotspot/jtreg/serviceability/sa/LingeredAppWithLockInVM.java new file mode 100644 index 00000000000..686cdfc4f2b --- /dev/null +++ b/test/hotspot/jtreg/serviceability/sa/LingeredAppWithLockInVM.java @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import jdk.test.whitebox.WhiteBox; +import jdk.test.lib.apps.LingeredApp; + +public class LingeredAppWithLockInVM extends LingeredApp { + + private static class LockerThread implements Runnable { + public void run() { + while (!isReady()) { + try { + Thread.sleep(100); + } catch (InterruptedException e) { + } + } + WhiteBox wb = WhiteBox.getWhiteBox(); + wb.lockAndStuckInSafepoint(); + } + } + + + public static void main(String args[]) { + if (args.length != 1) { + System.err.println("Lock file name is not specified"); + System.exit(7); + } + + Thread t = new Thread(new LockerThread()); + t.setName("LockerThread"); + t.start(); + + LingeredApp.main(args); + } + } diff --git a/test/hotspot/jtreg/serviceability/sa/TestJhsdbJstackPrintVMLocks.java b/test/hotspot/jtreg/serviceability/sa/TestJhsdbJstackPrintVMLocks.java new file mode 100644 index 00000000000..ff1cc4b96bd --- /dev/null +++ b/test/hotspot/jtreg/serviceability/sa/TestJhsdbJstackPrintVMLocks.java @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import jdk.test.lib.JDKToolLauncher; +import jdk.test.lib.SA.SATestUtils; +import jdk.test.lib.apps.LingeredApp; +import jdk.test.lib.process.OutputAnalyzer; +import jtreg.SkippedException; + +/** + * @test + * @summary Test verifies that jstack --mixed prints information about VM locks + * @requires vm.hasSA + * @library /test/lib + * @build jdk.test.whitebox.WhiteBox + * @run driver jdk.test.lib.helpers.ClassFileInstaller jdk.test.whitebox.WhiteBox + * @run driver TestJhsdbJstackPrintVMLocks + */ + +public class TestJhsdbJstackPrintVMLocks { + + final static int MAX_ATTEMPTS = 5; + public static void main(String[] args) throws Exception { + SATestUtils.skipIfCannotAttach(); // throws SkippedException if attach not expected to work. + + LingeredApp theApp = null; + try { + theApp = new LingeredAppWithLockInVM(); + LingeredApp.startApp(theApp, + "-XX:+UnlockDiagnosticVMOptions", + "-XX:+WhiteBoxAPI", + "-Xbootclasspath/a:."); + + System.out.println("Started LingeredApp with pid " + theApp.getPid()); + theApp.waitAppReadyOrCrashed(); + + for (int attempt = 0; attempt < MAX_ATTEMPTS; attempt++) { + JDKToolLauncher launcher = JDKToolLauncher + .createUsingTestJDK("jhsdb"); + launcher.addToolArg("jstack"); + launcher.addToolArg("--mixed"); + launcher.addToolArg("--pid"); + launcher.addToolArg(Long.toString(theApp.getPid())); + + ProcessBuilder pb = SATestUtils.createProcessBuilder(launcher); + Process jhsdb = pb.start(); + OutputAnalyzer out = new OutputAnalyzer(jhsdb); + + jhsdb.waitFor(); + + System.out.println(out.getStdout()); + System.err.println(out.getStderr()); + + if (out.contains("Mutex VMStatistic_lock is owned by LockerThread")) { + System.out.println("Test PASSED"); + return; + } + Thread.sleep(attempt * 2000); + } + throw new RuntimeException("Not able to find lock"); + } finally { + theApp.getProcess().destroyForcibly(); + } + } +} diff --git a/test/lib/jdk/test/lib/apps/LingeredApp.java b/test/lib/jdk/test/lib/apps/LingeredApp.java index d0b97b695d0..73904b81848 100644 --- a/test/lib/jdk/test/lib/apps/LingeredApp.java +++ b/test/lib/jdk/test/lib/apps/LingeredApp.java @@ -589,6 +589,12 @@ public void run() { static class SteadyStateLock {}; + private static volatile boolean isReady = false; + + protected static boolean isReady() { + return isReady; + } + /** * This part is the application itself. First arg is optional "forceCrash". * Following arg is the lock file name. @@ -627,6 +633,7 @@ public static void main(String args[]) { while (Files.exists(path)) { // Touch the lock to indicate our readiness setLastModified(theLockFileName, epoch()); + isReady = true; Thread.sleep(spinDelay); } } diff --git a/test/lib/jdk/test/whitebox/WhiteBox.java b/test/lib/jdk/test/whitebox/WhiteBox.java index 2e723d91267..f68eb978912 100644 --- a/test/lib/jdk/test/whitebox/WhiteBox.java +++ b/test/lib/jdk/test/whitebox/WhiteBox.java @@ -99,6 +99,8 @@ public long getObjectSize(Object o) { // printed by the VM. public native String printString(String str, int maxLength); + public native void lockAndStuckInSafepoint(); + public int countAliveClasses(String name) { // Make sure class name is in the correct format return countAliveClasses0(name.replace('.', '/')); From 11147046aa6102bc6e132d7b8c9d4e11db802002 Mon Sep 17 00:00:00 2001 From: Damon Nguyen <dnguyen@openjdk.org> Date: Fri, 22 Nov 2024 19:29:41 +0000 Subject: [PATCH 197/311] 6672644: JComboBox still scrolling if switch to another window and return back Reviewed-by: abhiscxk, psadhukhan --- .../swing/plaf/basic/BasicScrollBarUI.java | 45 +++++++++++ .../JComboBox/JComboBoxScrollFocusTest.java | 75 +++++++++++++++++++ 2 files changed, 120 insertions(+) create mode 100644 test/jdk/javax/swing/JComboBox/JComboBoxScrollFocusTest.java diff --git a/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicScrollBarUI.java b/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicScrollBarUI.java index 60274d766cd..9fc9b64314c 100644 --- a/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicScrollBarUI.java +++ b/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicScrollBarUI.java @@ -31,6 +31,7 @@ import java.awt.Dimension; import java.awt.Graphics; import java.awt.Insets; +import java.awt.KeyboardFocusManager; import java.awt.LayoutManager; import java.awt.Point; import java.awt.Rectangle; @@ -122,6 +123,8 @@ public class BasicScrollBarUI protected ArrowButtonListener buttonListener; /** Model listener */ protected ModelListener modelListener; + /** KeyboardFocusListener */ + protected KeyboardFocusListener keyboardFocusListener; /** Thumb rectangle */ protected Rectangle thumbRect; @@ -356,12 +359,15 @@ protected void installListeners(){ buttonListener = createArrowButtonListener(); modelListener = createModelListener(); propertyChangeListener = createPropertyChangeListener(); + keyboardFocusListener = createKeyboardFocusListener(); scrollbar.addMouseListener(trackListener); scrollbar.addMouseMotionListener(trackListener); scrollbar.getModel().addChangeListener(modelListener); scrollbar.addPropertyChangeListener(propertyChangeListener); scrollbar.addFocusListener(getHandler()); + KeyboardFocusManager.getCurrentKeyboardFocusManager() + .addPropertyChangeListener(keyboardFocusListener); if (incrButton != null) { incrButton.addMouseListener(buttonListener); @@ -443,6 +449,8 @@ protected void uninstallListeners() { incrButton.removeMouseListener(buttonListener); } + KeyboardFocusManager.getCurrentKeyboardFocusManager() + .removePropertyChangeListener(keyboardFocusListener); scrollbar.getModel().removeChangeListener(modelListener); scrollbar.removeMouseListener(trackListener); scrollbar.removeMouseMotionListener(trackListener); @@ -509,6 +517,14 @@ protected PropertyChangeListener createPropertyChangeListener() { return getHandler(); } + /** + * Creates a keyboard focus listener. + * @return a keyboard focus listener + */ + protected KeyboardFocusListener createKeyboardFocusListener() { + return new KeyboardFocusListener(); + } + private void updateThumbState(int x, int y) { Rectangle rect = getThumbBounds(); @@ -1202,6 +1218,35 @@ public boolean getSupportsAbsolutePositioning() { return supportsAbsolutePositioning; } + /** + * A listener to listen for keyboard focus changes. + */ + protected class KeyboardFocusListener implements PropertyChangeListener { + /** + * Constructs a {@code KeyboardFocusListener}. + */ + protected KeyboardFocusListener() {} + + @Override + public void propertyChange(PropertyChangeEvent e) { + String propertyName = e.getPropertyName(); + + if ("focusOwner" == propertyName) { + // Stop scrolling if no longer focus owner + if (e.getNewValue() == null && scrollTimer.isRunning()) { + scrollTimer.stop(); + buttonListener.handledEvent = false; + scrollbar.setValueIsAdjusting(false); + if (incrButton.getModel().isPressed()) { + incrButton.getModel().setPressed(false); + } else if (decrButton.getModel().isPressed()) { + decrButton.getModel().setPressed(false); + } + } + } + } + } + /** * A listener to listen for model changes. */ diff --git a/test/jdk/javax/swing/JComboBox/JComboBoxScrollFocusTest.java b/test/jdk/javax/swing/JComboBox/JComboBoxScrollFocusTest.java new file mode 100644 index 00000000000..4d2c3bd19cc --- /dev/null +++ b/test/jdk/javax/swing/JComboBox/JComboBoxScrollFocusTest.java @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import javax.swing.JComboBox; +import javax.swing.JFrame; + +/* + * @test + * @bug 6672644 + * @library /java/awt/regtesthelpers + * @build PassFailJFrame + * @summary Tests JComboBox scrollbar behavior when alt-tabbing + * @requires os.family != "mac" + * @run main/manual JComboBoxScrollFocusTest + */ + +public class JComboBoxScrollFocusTest { + private static final String INSTRUCTIONS = + """ + Click on the dropdown button for the JComboBox in the test frame. + Then, press and hold the left click button on the down arrow button + in the popup list. While holding the left click button, the list + should be scrolling down. Press ALT + TAB while holding down the + left click to switch focus to a different window. Then release the + left click button. Focus the test frame again and click the + dropdown button for the JComboBox again. The list should be + stationary and not be automatically scrolling. + + If you are able to execute all steps successfully then the test + passes, otherwise it fails. + """; + + public static void main(String[] args) throws Exception { + PassFailJFrame + .builder() + .title("JComboBoxScrollFocusTest Test Instructions") + .instructions(INSTRUCTIONS) + .columns(40) + .testUI(JComboBoxScrollFocusTest::createAndShowGUI) + .build() + .awaitAndCheck(); + } + + private static JFrame createAndShowGUI() { + JFrame frame = new JFrame("JComboBoxScrollFocusTest Test Frame"); + JComboBox<String> combobox = new JComboBox<>(); + for (int i = 0; i < 100; i++) { + combobox.addItem(String.valueOf(i)); + } + frame.add(combobox); + frame.setSize(400, 200); + frame.setLocationRelativeTo(null); + return frame; + } +} From 70c4e2c0cc9e741355396abc1be0f64cc77ec3e0 Mon Sep 17 00:00:00 2001 From: Alexey Semenyuk <asemenyuk@openjdk.org> Date: Fri, 22 Nov 2024 23:33:49 +0000 Subject: [PATCH 198/311] 8344587: Reduce number of "jdk.jpackage.internal" classes used from other packages Reviewed-by: almatvee --- .../jdk/jpackage/internal/AppImageFile.java | 2 +- .../jdk/jpackage/internal/IOUtils.java | 2 +- .../jdk/jpackage/internal/PackageFile.java | 2 +- .../jdk/jpackage/internal/util/PathUtils.java | 9 +- .../jdk/jpackage/internal/util/XmlUtils.java | 3 +- .../jdk/jpackage/test/AppImageFile.java | 122 +++++++++++++++++ .../jdk/jpackage/test/ApplicationLayout.java | 126 ++++++++++++++++++ .../helpers/jdk/jpackage/test/Functional.java | 1 - .../jdk/jpackage/test/JPackageCommand.java | 63 ++------- .../jdk/jpackage/test/LinuxHelper.java | 1 - .../jdk/jpackage/test/PackageFile.java | 37 +++++ .../jdk/jpackage/test/PackageTest.java | 1 - ...SigningPackageFromTwoStepAppImageTest.java | 2 +- .../jpackage/macosx/SigningPackageTest.java | 2 +- .../macosx/SigningPackageTwoStepTest.java | 2 +- .../jpackage/share/AppImagePackageTest.java | 4 +- .../tools/jpackage/share/AppVersionTest.java | 11 +- .../tools/jpackage/share/InOutPathTest.java | 6 +- .../tools/jpackage/share/ModulePathTest3.java | 12 +- .../share/PredefinedAppImageErrorTest.java | 3 +- .../share/RuntimeImageSymbolicLinksTest.java | 2 +- 21 files changed, 320 insertions(+), 93 deletions(-) create mode 100644 test/jdk/tools/jpackage/helpers/jdk/jpackage/test/AppImageFile.java create mode 100644 test/jdk/tools/jpackage/helpers/jdk/jpackage/test/ApplicationLayout.java create mode 100644 test/jdk/tools/jpackage/helpers/jdk/jpackage/test/PackageFile.java diff --git a/src/jdk.jpackage/share/classes/jdk/jpackage/internal/AppImageFile.java b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/AppImageFile.java index 256d292350a..a8032979bb2 100644 --- a/src/jdk.jpackage/share/classes/jdk/jpackage/internal/AppImageFile.java +++ b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/AppImageFile.java @@ -61,7 +61,7 @@ import static jdk.jpackage.internal.StandardBundlerParam.APP_STORE; import jdk.jpackage.internal.util.XmlUtils; -public final class AppImageFile { +final class AppImageFile { // These values will be loaded from AppImage xml file. private final String appVersion; diff --git a/src/jdk.jpackage/share/classes/jdk/jpackage/internal/IOUtils.java b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/IOUtils.java index 534786ada13..cb8ef227901 100644 --- a/src/jdk.jpackage/share/classes/jdk/jpackage/internal/IOUtils.java +++ b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/IOUtils.java @@ -40,7 +40,7 @@ * * A collection of static utility methods. */ -public class IOUtils { +final class IOUtils { public static void copyFile(Path sourceFile, Path destFile) throws IOException { diff --git a/src/jdk.jpackage/share/classes/jdk/jpackage/internal/PackageFile.java b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/PackageFile.java index 87935a9287c..e8bc0cb6655 100644 --- a/src/jdk.jpackage/share/classes/jdk/jpackage/internal/PackageFile.java +++ b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/PackageFile.java @@ -31,7 +31,7 @@ import java.util.Objects; import java.util.Optional; -public final class PackageFile { +final class PackageFile { /** * Returns path to package file. diff --git a/src/jdk.jpackage/share/classes/jdk/jpackage/internal/util/PathUtils.java b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/util/PathUtils.java index 267062a2031..26d49519291 100644 --- a/src/jdk.jpackage/share/classes/jdk/jpackage/internal/util/PathUtils.java +++ b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/util/PathUtils.java @@ -26,24 +26,23 @@ import java.nio.file.Path; import java.util.Optional; -import jdk.jpackage.internal.IOUtils; public final class PathUtils { public static String getSuffix(Path path) { - String filename = replaceSuffix(IOUtils.getFileName(path), null).toString(); - return IOUtils.getFileName(path).toString().substring(filename.length()); + String filename = replaceSuffix(path.getFileName(), null).toString(); + return path.getFileName().toString().substring(filename.length()); } public static Path addSuffix(Path path, String suffix) { Path parent = path.getParent(); - String filename = IOUtils.getFileName(path).toString() + suffix; + String filename = path.getFileName().toString() + suffix; return parent != null ? parent.resolve(filename) : Path.of(filename); } public static Path replaceSuffix(Path path, String suffix) { Path parent = path.getParent(); - String filename = IOUtils.getFileName(path).toString().replaceAll("\\.[^.]*$", + String filename = path.getFileName().toString().replaceAll("\\.[^.]*$", "") + Optional.ofNullable(suffix).orElse(""); return parent != null ? parent.resolve(filename) : Path.of(filename); } diff --git a/src/jdk.jpackage/share/classes/jdk/jpackage/internal/util/XmlUtils.java b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/util/XmlUtils.java index 8012384b679..ff4168e5d0c 100644 --- a/src/jdk.jpackage/share/classes/jdk/jpackage/internal/util/XmlUtils.java +++ b/src/jdk.jpackage/share/classes/jdk/jpackage/internal/util/XmlUtils.java @@ -39,7 +39,6 @@ import javax.xml.transform.TransformerException; import javax.xml.transform.TransformerFactory; import javax.xml.transform.stax.StAXResult; -import jdk.jpackage.internal.IOUtils; public final class XmlUtils { @@ -47,7 +46,7 @@ public final class XmlUtils { public static void createXml(Path dstFile, XmlConsumer xmlConsumer) throws IOException { XMLOutputFactory xmlFactory = XMLOutputFactory.newInstance(); - Files.createDirectories(IOUtils.getParent(dstFile)); + Files.createDirectories(dstFile.getParent()); try (Writer w = Files.newBufferedWriter(dstFile)) { // Wrap with pretty print proxy XMLStreamWriter xml = (XMLStreamWriter) Proxy.newProxyInstance(XMLStreamWriter.class.getClassLoader(), diff --git a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/AppImageFile.java b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/AppImageFile.java new file mode 100644 index 00000000000..2381aecec2e --- /dev/null +++ b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/AppImageFile.java @@ -0,0 +1,122 @@ +/* + * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.jpackage.test; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.Map; +import java.util.Optional; +import javax.xml.xpath.XPath; +import javax.xml.xpath.XPathFactory; +import jdk.internal.util.OperatingSystem; +import jdk.jpackage.internal.util.XmlUtils; +import static jdk.jpackage.internal.util.function.ThrowingSupplier.toSupplier; +import org.w3c.dom.Document; + +public record AppImageFile(String mainLauncherName, String mainLauncherClassName, + String version, boolean macSigned, boolean macAppStore) { + + public static Path getPathInAppImage(Path appImageDir) { + return ApplicationLayout.platformAppImage() + .resolveAt(appImageDir) + .appDirectory() + .resolve(FILENAME); + } + + public AppImageFile(String mainLauncherName, String mainLauncherClassName) { + this(mainLauncherName, mainLauncherClassName, "1.0", false, false); + } + + public void save(Path appImageDir) throws IOException { + XmlUtils.createXml(getPathInAppImage(appImageDir), xml -> { + xml.writeStartElement("jpackage-state"); + xml.writeAttribute("version", getVersion()); + xml.writeAttribute("platform", getPlatform()); + + xml.writeStartElement("app-version"); + xml.writeCharacters(version); + xml.writeEndElement(); + + xml.writeStartElement("main-launcher"); + xml.writeCharacters(mainLauncherName); + xml.writeEndElement(); + + xml.writeStartElement("main-class"); + xml.writeCharacters(mainLauncherClassName); + xml.writeEndElement(); + + xml.writeStartElement("signed"); + xml.writeCharacters(Boolean.toString(macSigned)); + xml.writeEndElement(); + + xml.writeStartElement("app-store"); + xml.writeCharacters(Boolean.toString(macAppStore)); + xml.writeEndElement(); + }); + } + + public static AppImageFile load(Path appImageDir) { + return toSupplier(() -> { + Document doc = XmlUtils.initDocumentBuilder().parse( + Files.newInputStream(getPathInAppImage(appImageDir))); + + XPath xPath = XPathFactory.newInstance().newXPath(); + + var version = xPath.evaluate("/jpackage-state/app-version/text()", doc); + + var mainLauncherName = xPath.evaluate( + "/jpackage-state/main-launcher/text()", doc); + + var mainLauncherClassName = xPath.evaluate( + "/jpackage-state/main-class/text()", doc); + + var macSigned = Optional.ofNullable(xPath.evaluate( + "/jpackage-state/signed/text()", doc)).map( + Boolean::parseBoolean).orElse(false); + + var macAppStore = Optional.ofNullable(xPath.evaluate( + "/jpackage-state/app-store/text()", doc)).map( + Boolean::parseBoolean).orElse(false); + + return new AppImageFile(mainLauncherName, mainLauncherClassName, + version, macSigned, macAppStore); + + }).get(); + } + + private static String getVersion() { + return System.getProperty("java.version"); + } + + private static String getPlatform() { + return PLATFORM_LABELS.get(OperatingSystem.current()); + } + + private static final String FILENAME = ".jpackage.xml"; + + private static final Map<OperatingSystem, String> PLATFORM_LABELS = Map.of( + OperatingSystem.LINUX, "linux", + OperatingSystem.WINDOWS, "windows", + OperatingSystem.MACOS, "macOS"); +} diff --git a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/ApplicationLayout.java b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/ApplicationLayout.java new file mode 100644 index 00000000000..88ce7169da7 --- /dev/null +++ b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/ApplicationLayout.java @@ -0,0 +1,126 @@ +/* + * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.jpackage.test; + +import java.nio.file.Path; +import java.util.Optional; + +public record ApplicationLayout(Path launchersDirectory, Path appDirectory, + Path runtimeDirectory, Path runtimeHomeDirectory, Path appModsDirectory, + Path destktopIntegrationDirectory, Path contentDirectory) { + + public ApplicationLayout resolveAt(Path root) { + return new ApplicationLayout( + resolve(root, launchersDirectory), + resolve(root, appDirectory), + resolve(root, runtimeDirectory), + resolve(root, runtimeHomeDirectory), + resolve(root, appModsDirectory), + resolve(root, destktopIntegrationDirectory), + resolve(root, contentDirectory)); + } + + public static ApplicationLayout linuxAppImage() { + return new ApplicationLayout( + Path.of("bin"), + Path.of("lib/app"), + Path.of("lib/runtime"), + Path.of("lib/runtime"), + Path.of("lib/app/mods"), + Path.of("lib"), + Path.of("lib") + ); + } + + public static ApplicationLayout windowsAppImage() { + return new ApplicationLayout( + Path.of(""), + Path.of("app"), + Path.of("runtime"), + Path.of("runtime"), + Path.of("app/mods"), + Path.of(""), + Path.of("") + ); + } + + public static ApplicationLayout macAppImage() { + return new ApplicationLayout( + Path.of("Contents/MacOS"), + Path.of("Contents/app"), + Path.of("Contents/runtime"), + Path.of("Contents/runtime/Contents/Home"), + Path.of("Contents/app/mods"), + Path.of("Contents/Resources"), + Path.of("Contents") + ); + } + + public static ApplicationLayout platformAppImage() { + if (TKit.isWindows()) { + return windowsAppImage(); + } + + if (TKit.isLinux()) { + return linuxAppImage(); + } + + if (TKit.isOSX()) { + return macAppImage(); + } + + throw new IllegalArgumentException("Unknown platform"); + } + + public static ApplicationLayout javaRuntime() { + return new ApplicationLayout( + null, + null, + Path.of(""), + null, + null, + null, + null + ); + } + + public static ApplicationLayout linuxUsrTreePackageImage(Path prefix, + String packageName) { + final Path lib = prefix.resolve(Path.of("lib", packageName)); + return new ApplicationLayout( + prefix.resolve("bin"), + lib.resolve("app"), + lib.resolve("runtime"), + lib.resolve("runtime"), + lib.resolve("app/mods"), + lib, + lib + ); + } + + private static Path resolve(Path base, Path path) { + return Optional.ofNullable(path).map(base::resolve).orElse(null); + } +} diff --git a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/Functional.java b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/Functional.java index a974670b8e4..28b35742681 100644 --- a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/Functional.java +++ b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/Functional.java @@ -22,7 +22,6 @@ */ package jdk.jpackage.test; -import java.lang.reflect.InvocationTargetException; import java.util.function.BiConsumer; import java.util.function.Consumer; import java.util.function.Function; diff --git a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/JPackageCommand.java b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/JPackageCommand.java index 4239d8a87c8..68f26bfb261 100644 --- a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/JPackageCommand.java +++ b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/JPackageCommand.java @@ -45,10 +45,6 @@ import java.util.regex.Pattern; import java.util.stream.Collectors; import java.util.stream.Stream; -import jdk.jpackage.internal.AppImageFile; -import jdk.jpackage.internal.ApplicationLayout; -import jdk.jpackage.internal.PackageFile; -import jdk.jpackage.internal.util.XmlUtils; import static jdk.jpackage.test.AdditionalLauncher.forEachAdditionalLauncher; import jdk.jpackage.internal.util.function.ThrowingConsumer; import jdk.jpackage.internal.util.function.ThrowingFunction; @@ -157,8 +153,10 @@ public String getArgumentValue(String argName, public <T> T getArgumentValue(String argName, Supplier<T> defaultValueSupplier, Function<String, T> stringConverter) { - return getArgumentValue(argName, (unused) -> defaultValueSupplier.get(), - stringConverter); + return getArgumentValue(argName, + Optional.ofNullable(defaultValueSupplier).map(supplier -> { + return (Function<JPackageCommand, T>)unused -> supplier.get(); + }).orElse(null), stringConverter); } public String getArgumentValue(String argName, @@ -217,9 +215,9 @@ public String version() { } public String name() { - String appImage = getArgumentValue("--app-image", () -> null); + String appImage = getArgumentValue("--app-image"); if (appImage != null) { - String name = AppImageFile.extractAppName(Path.of(appImage)); + String name = AppImageFile.load(Path.of(appImage)).mainLauncherName(); // can be null if using foreign app-image return ((name != null) ? name : getArgumentValue("--name")); } @@ -233,7 +231,7 @@ public String installerName() { if (installerName == null) { String appImage = getArgumentValue("--app-image"); if (appImage != null) { - installerName = AppImageFile.extractAppName(Path.of(appImage)); + installerName = AppImageFile.load(Path.of(appImage)).mainLauncherName(); } } return installerName; @@ -306,42 +304,6 @@ public JPackageCommand setFakeRuntime() { return this; } - public void createJPackageXMLFile(String mainLauncher, String mainClass) - throws IOException { - Path jpackageXMLFile = AppImageFile.getPathInAppImage( - Optional.ofNullable(getArgumentValue("--app-image")).map( - Path::of).orElseThrow(() -> { - return new RuntimeException( - "Error: --app-image expected"); - })); - - XmlUtils.createXml(jpackageXMLFile, xml -> { - xml.writeStartElement("jpackage-state"); - xml.writeAttribute("version", AppImageFile.getVersion()); - xml.writeAttribute("platform", AppImageFile.getPlatform()); - - xml.writeStartElement("app-version"); - xml.writeCharacters("1.0"); - xml.writeEndElement(); - - xml.writeStartElement("main-launcher"); - xml.writeCharacters(mainLauncher); - xml.writeEndElement(); - - xml.writeStartElement("main-class"); - xml.writeCharacters(mainClass); - xml.writeEndElement(); - - xml.writeStartElement("signed"); - xml.writeCharacters("false"); - xml.writeEndElement(); - - xml.writeStartElement("app-store"); - xml.writeCharacters("false"); - xml.writeEndElement(); - }); - } - JPackageCommand addPrerequisiteAction(ThrowingConsumer<JPackageCommand> action) { verifyMutable(); prerequisiteActions.add(action); @@ -935,7 +897,7 @@ JPackageCommand assertAppLayout() { private void assertAppImageFile() { Path appImageDir = Path.of(""); if (isImagePackageType() && hasArgument("--app-image")) { - appImageDir = Path.of(getArgumentValue("--app-image", () -> null)); + appImageDir = Path.of(getArgumentValue("--app-image")); } final Path lookupPath = AppImageFile.getPathInAppImage(appImageDir); @@ -956,12 +918,12 @@ private void assertAppImageFile() { AppImageFile aif = AppImageFile.load(rootDir); boolean expectedValue = hasArgument("--mac-sign"); - boolean actualValue = aif.isSigned(); + boolean actualValue = aif.macSigned(); TKit.assertEquals(Boolean.toString(expectedValue), Boolean.toString(actualValue), "Check for unexptected value in app image file for <signed>"); expectedValue = hasArgument("--mac-app-store"); - actualValue = aif.isAppStore(); + actualValue = aif.macAppStore(); TKit.assertEquals(Boolean.toString(expectedValue), Boolean.toString(actualValue), "Check for unexptected value in app image file for <app-store>"); } @@ -975,9 +937,8 @@ private void assertPackageFile() { assertFileInAppImage(lookupPath, null); } else { if (TKit.isOSX() && hasArgument("--app-image")) { - String appImage = getArgumentValue("--app-image", - () -> null); - if (AppImageFile.load(Path.of(appImage)).isSigned()) { + String appImage = getArgumentValue("--app-image"); + if (AppImageFile.load(Path.of(appImage)).macSigned()) { assertFileInAppImage(lookupPath, null); } else { assertFileInAppImage(lookupPath, lookupPath); diff --git a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/LinuxHelper.java b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/LinuxHelper.java index 35baff3d5db..ddbbee4aa60 100644 --- a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/LinuxHelper.java +++ b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/LinuxHelper.java @@ -40,7 +40,6 @@ import java.util.regex.Pattern; import java.util.stream.Collectors; import java.util.stream.Stream; -import jdk.jpackage.internal.ApplicationLayout; import jdk.jpackage.internal.util.PathUtils; import jdk.jpackage.internal.util.function.ThrowingConsumer; import jdk.jpackage.test.PackageTest.PackageHandlers; diff --git a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/PackageFile.java b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/PackageFile.java new file mode 100644 index 00000000000..6307ccabda5 --- /dev/null +++ b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/PackageFile.java @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package jdk.jpackage.test; + +import java.nio.file.Path; + +public final class PackageFile { + + public static Path getPathInAppImage(Path appImageDir) { + return ApplicationLayout.platformAppImage() + .resolveAt(appImageDir) + .appDirectory() + .resolve(FILENAME); + } + + private static final String FILENAME = ".package"; +} diff --git a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/PackageTest.java b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/PackageTest.java index 7c6aab29fee..fd6d5e2da6b 100644 --- a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/PackageTest.java +++ b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/PackageTest.java @@ -45,7 +45,6 @@ import java.util.stream.Collectors; import java.util.stream.Stream; import java.util.stream.StreamSupport; -import jdk.jpackage.internal.ApplicationLayout; import jdk.jpackage.internal.util.function.ThrowingBiConsumer; import static jdk.jpackage.internal.util.function.ThrowingBiConsumer.toBiConsumer; import jdk.jpackage.internal.util.function.ThrowingConsumer; diff --git a/test/jdk/tools/jpackage/macosx/SigningPackageFromTwoStepAppImageTest.java b/test/jdk/tools/jpackage/macosx/SigningPackageFromTwoStepAppImageTest.java index 0f4f2e77476..f6408d21eba 100644 --- a/test/jdk/tools/jpackage/macosx/SigningPackageFromTwoStepAppImageTest.java +++ b/test/jdk/tools/jpackage/macosx/SigningPackageFromTwoStepAppImageTest.java @@ -22,7 +22,7 @@ */ import java.nio.file.Path; -import jdk.jpackage.internal.ApplicationLayout; +import jdk.jpackage.test.ApplicationLayout; import jdk.jpackage.test.JPackageCommand; import jdk.jpackage.test.TKit; import jdk.jpackage.test.PackageTest; diff --git a/test/jdk/tools/jpackage/macosx/SigningPackageTest.java b/test/jdk/tools/jpackage/macosx/SigningPackageTest.java index 621fac1cd19..46a3dad2af8 100644 --- a/test/jdk/tools/jpackage/macosx/SigningPackageTest.java +++ b/test/jdk/tools/jpackage/macosx/SigningPackageTest.java @@ -22,7 +22,7 @@ */ import java.nio.file.Path; -import jdk.jpackage.internal.ApplicationLayout; +import jdk.jpackage.test.ApplicationLayout; import jdk.jpackage.test.JPackageCommand; import jdk.jpackage.test.PackageTest; import jdk.jpackage.test.PackageType; diff --git a/test/jdk/tools/jpackage/macosx/SigningPackageTwoStepTest.java b/test/jdk/tools/jpackage/macosx/SigningPackageTwoStepTest.java index 65211e8c29e..84af48f6efb 100644 --- a/test/jdk/tools/jpackage/macosx/SigningPackageTwoStepTest.java +++ b/test/jdk/tools/jpackage/macosx/SigningPackageTwoStepTest.java @@ -22,7 +22,7 @@ */ import java.nio.file.Path; -import jdk.jpackage.internal.ApplicationLayout; +import jdk.jpackage.test.ApplicationLayout; import jdk.jpackage.test.JPackageCommand; import jdk.jpackage.test.TKit; import jdk.jpackage.test.PackageTest; diff --git a/test/jdk/tools/jpackage/share/AppImagePackageTest.java b/test/jdk/tools/jpackage/share/AppImagePackageTest.java index 62d5e974f86..7185e63145f 100644 --- a/test/jdk/tools/jpackage/share/AppImagePackageTest.java +++ b/test/jdk/tools/jpackage/share/AppImagePackageTest.java @@ -25,7 +25,7 @@ import java.nio.file.Files; import java.io.IOException; import java.util.List; -import jdk.jpackage.internal.AppImageFile; +import jdk.jpackage.test.AppImageFile; import jdk.jpackage.test.Annotations.Parameter; import jdk.jpackage.test.TKit; import jdk.jpackage.test.JPackageCommand; @@ -87,7 +87,7 @@ public static void testEmpty(boolean withIcon) throws IOException { cmd.addArguments("--icon", iconPath("icon")); } cmd.removeArgumentWithValue("--input"); - cmd.createJPackageXMLFile("EmptyAppImagePackageTest", "Hello"); + new AppImageFile("EmptyAppImagePackageTest", "Hello").save(appImageDir); // on mac, with --app-image and without --mac-package-identifier, // will try to infer it from the image, so foreign image needs it. diff --git a/test/jdk/tools/jpackage/share/AppVersionTest.java b/test/jdk/tools/jpackage/share/AppVersionTest.java index efd025590d2..3fdddf56e2e 100644 --- a/test/jdk/tools/jpackage/share/AppVersionTest.java +++ b/test/jdk/tools/jpackage/share/AppVersionTest.java @@ -26,17 +26,13 @@ import java.util.Collection; import java.util.ArrayList; import java.util.List; -import javax.xml.xpath.XPathConstants; import javax.xml.xpath.XPathExpressionException; -import javax.xml.xpath.XPathFactory; -import jdk.jpackage.internal.AppImageFile; +import jdk.jpackage.test.AppImageFile; import jdk.jpackage.test.Annotations.Parameters; import jdk.jpackage.test.Annotations.Test; import jdk.jpackage.test.JPackageCommand; import jdk.jpackage.test.PackageTest; import jdk.jpackage.test.TKit; -import jdk.jpackage.internal.AppImageFile; -import org.w3c.dom.Document; /* * @test @@ -116,10 +112,7 @@ public void test() throws XPathExpressionException, IOException { } cmd.executeAndAssertHelloAppImageCreated(); - Document xml = AppImageFile.readXml(cmd.outputBundle()); - String actualVersion = XPathFactory.newInstance().newXPath().evaluate( - "/jpackage-state/app-version/text()", xml, XPathConstants.STRING).toString(); - + String actualVersion = AppImageFile.load(cmd.outputBundle()).version(); TKit.assertEquals(expectedVersion, actualVersion, "Check application version"); } diff --git a/test/jdk/tools/jpackage/share/InOutPathTest.java b/test/jdk/tools/jpackage/share/InOutPathTest.java index b2579133148..46da5e9939b 100644 --- a/test/jdk/tools/jpackage/share/InOutPathTest.java +++ b/test/jdk/tools/jpackage/share/InOutPathTest.java @@ -31,9 +31,9 @@ import java.util.function.Predicate; import java.util.stream.Stream; import jdk.internal.util.OperatingSystem; -import jdk.jpackage.internal.AppImageFile; -import jdk.jpackage.internal.ApplicationLayout; -import jdk.jpackage.internal.PackageFile; +import jdk.jpackage.test.AppImageFile; +import jdk.jpackage.test.ApplicationLayout; +import jdk.jpackage.test.PackageFile; import jdk.jpackage.test.Annotations.Parameters; import jdk.jpackage.test.Annotations.Test; import jdk.jpackage.internal.util.function.ThrowingConsumer; diff --git a/test/jdk/tools/jpackage/share/ModulePathTest3.java b/test/jdk/tools/jpackage/share/ModulePathTest3.java index b4b51e1adfc..118dc2e5ed0 100644 --- a/test/jdk/tools/jpackage/share/ModulePathTest3.java +++ b/test/jdk/tools/jpackage/share/ModulePathTest3.java @@ -29,20 +29,16 @@ import java.util.Collection; import java.util.List; import javax.xml.xpath.XPathExpressionException; -import javax.xml.xpath.XPathConstants; -import javax.xml.xpath.XPathFactory; -import jdk.jpackage.internal.AppImageFile; +import jdk.jpackage.test.AppImageFile; import jdk.jpackage.test.HelloApp; import jdk.jpackage.test.JavaAppDesc; import jdk.jpackage.test.Annotations.Test; -import jdk.jpackage.test.Annotations.Parameter; import jdk.jpackage.test.Annotations.Parameters; import jdk.jpackage.test.Executor; import jdk.jpackage.test.JPackageCommand; import jdk.jpackage.test.JavaTool; import jdk.jpackage.test.PackageType; import jdk.jpackage.test.TKit; -import org.w3c.dom.Document; /* @@ -105,11 +101,7 @@ private void testIt(String mainAppDesc) throws XPathExpressionException, cmd.executeAndAssertHelloAppImageCreated(); if (appDesc.moduleVersion() != null) { - Document xml = AppImageFile.readXml(cmd.outputBundle()); - String actualVersion = XPathFactory.newInstance().newXPath().evaluate( - "/jpackage-state/app-version/text()", xml, - XPathConstants.STRING).toString(); - + String actualVersion = AppImageFile.load(cmd.outputBundle()).version(); TKit.assertEquals(appDesc.moduleVersion(), actualVersion, "Check application version"); } diff --git a/test/jdk/tools/jpackage/share/PredefinedAppImageErrorTest.java b/test/jdk/tools/jpackage/share/PredefinedAppImageErrorTest.java index bdb4f6bfbd7..0e1d358dae4 100644 --- a/test/jdk/tools/jpackage/share/PredefinedAppImageErrorTest.java +++ b/test/jdk/tools/jpackage/share/PredefinedAppImageErrorTest.java @@ -28,6 +28,7 @@ import java.util.Collection; import java.util.List; +import jdk.jpackage.test.AppImageFile; import jdk.jpackage.test.Annotations.Parameters; import jdk.jpackage.test.Annotations.Test; import jdk.jpackage.test.JPackageCommand; @@ -111,7 +112,7 @@ private void getDummyAppImage(JPackageCommand cmd) throws IOException { Files.createFile(dummyAppFile); cmd.addArguments("--app-image", dummyAppFolder.toString()); - cmd.createJPackageXMLFile("PredefinedAppImageErrorTest", "Hello"); + new AppImageFile("PredefinedAppImageErrorTest", "Hello").save(dummyAppFolder); } } diff --git a/test/jdk/tools/jpackage/share/RuntimeImageSymbolicLinksTest.java b/test/jdk/tools/jpackage/share/RuntimeImageSymbolicLinksTest.java index 649ac0a3695..404cd3b6d3a 100644 --- a/test/jdk/tools/jpackage/share/RuntimeImageSymbolicLinksTest.java +++ b/test/jdk/tools/jpackage/share/RuntimeImageSymbolicLinksTest.java @@ -23,7 +23,7 @@ import java.nio.file.Files; import java.nio.file.Path; -import jdk.jpackage.internal.ApplicationLayout; +import jdk.jpackage.test.ApplicationLayout; import jdk.jpackage.test.TKit; import jdk.jpackage.test.Annotations.Test; import jdk.jpackage.test.JPackageCommand; From effee122dd74241db4ec2b6bfd99f1450741b804 Mon Sep 17 00:00:00 2001 From: Evgeny Nikitin <enikitin@openjdk.org> Date: Sat, 23 Nov 2024 03:55:58 +0000 Subject: [PATCH 199/311] 8344533: CTW: Add option to remove clinits before loading Reviewed-by: thartmann, lmesnik --- .../sun/hotspot/tools/ctw/PathHandler.java | 22 +++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/test/hotspot/jtreg/testlibrary/ctw/src/sun/hotspot/tools/ctw/PathHandler.java b/test/hotspot/jtreg/testlibrary/ctw/src/sun/hotspot/tools/ctw/PathHandler.java index 5ab94b0a356..5e36cf0f7f9 100644 --- a/test/hotspot/jtreg/testlibrary/ctw/src/sun/hotspot/tools/ctw/PathHandler.java +++ b/test/hotspot/jtreg/testlibrary/ctw/src/sun/hotspot/tools/ctw/PathHandler.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -24,6 +24,9 @@ package sun.hotspot.tools.ctw; import java.io.Closeable; +import java.lang.classfile.ClassFile; +import java.lang.classfile.ClassTransform; +import java.lang.classfile.MethodModel; import java.net.URI; import java.nio.file.FileSystems; import java.nio.file.Files; @@ -92,7 +95,22 @@ private static class PathEntryClassLoader extends java.lang.ClassLoader { private final Function<String, byte[]> findByteCode; private PathEntryClassLoader(Function<String, byte[]> findByteCode) { - this.findByteCode = findByteCode; + boolean allowClinits = "true".equals( + System.getProperty("sun.hotspot.tools.ctwrunner.allow_clinits", "true")); + + this.findByteCode = allowClinits ? findByteCode + : findByteCode.andThen(PathEntryClassLoader::sterilizeClinits); + } + + /** + * Removes 'clinit' methods to prevent code execution + */ + private static byte[] sterilizeClinits(byte[] src) { + ClassFile classFile = ClassFile.of(); + return classFile.transformClass(classFile.parse(src), + ClassTransform.dropping( + element -> element instanceof MethodModel mm + && mm.methodName().stringValue().equals("<clinit>"))); } @Override From d00f31156a9ab9efcee492dfd0aaed1515df1f00 Mon Sep 17 00:00:00 2001 From: Jaikiran Pai <jpai@openjdk.org> Date: Sat, 23 Nov 2024 07:26:04 +0000 Subject: [PATCH 200/311] 8343150: Change URLClassLoader.getPermissions to return empty PermissionCollection Reviewed-by: dfuchs, alanb, michaelm --- .../classes/java/net/URLClassLoader.java | 91 ++----------------- 1 file changed, 9 insertions(+), 82 deletions(-) diff --git a/src/java.base/share/classes/java/net/URLClassLoader.java b/src/java.base/share/classes/java/net/URLClassLoader.java index d867b7e2b62..90bb1c56f11 100644 --- a/src/java.base/share/classes/java/net/URLClassLoader.java +++ b/src/java.base/share/classes/java/net/URLClassLoader.java @@ -26,13 +26,11 @@ package java.net; import java.io.Closeable; -import java.io.File; -import java.io.FilePermission; import java.io.IOException; import java.io.InputStream; import java.security.CodeSigner; import java.security.CodeSource; -import java.security.Permission; +import java.security.Permissions; import java.security.PermissionCollection; import java.security.SecureClassLoader; import java.util.Enumeration; @@ -50,8 +48,6 @@ import jdk.internal.loader.URLClassPath; import jdk.internal.access.SharedSecrets; import jdk.internal.perf.PerfCounter; -import sun.net.www.ParseUtil; -import sun.security.util.SecurityConstants; /** * This class loader is used to load classes and resources from a search @@ -573,84 +569,15 @@ public boolean hasMoreElements() { } /** - * Returns the permissions for the given codesource object. - * The implementation of this method first calls super.getPermissions - * and then adds permissions based on the URL of the codesource. - * <p> - * If the protocol of this URL is "jar", then the permission returned - * is based on the permission that is required by the URL of the Jar - * file. - * <p> - * If the protocol is "file" and there is an authority component, then - * permission to connect to and accept connections from that authority - * may be returned. If the protocol is "file" - * and the path specifies a file, then permission to read that - * file is returned. If protocol is "file" and the path is - * a directory, then permission is returned to read all files - * and (recursively) all files and subdirectories contained in - * that directory. - * <p> - * If the protocol is not "file", then permission - * to connect to and accept connections from the URL's host is returned. - * @param codesource the codesource - * @throws NullPointerException if {@code codesource} is {@code null}. - * @return the permissions for the codesource + * {@return an {@linkplain PermissionCollection empty Permission collection}} + * + * @param codesource the {@code CodeSource} + * @throws NullPointerException if {@code codesource} is {@code null}. */ - protected PermissionCollection getPermissions(CodeSource codesource) - { - PermissionCollection perms = super.getPermissions(codesource); - - URL url = codesource.getLocation(); - - Permission p; - URLConnection urlConnection; - - try { - urlConnection = url.openConnection(); - p = urlConnection.getPermission(); - } catch (java.io.IOException ioe) { - p = null; - urlConnection = null; - } - - if (p instanceof FilePermission) { - // if the permission has a separator char on the end, - // it means the codebase is a directory, and we need - // to add an additional permission to read recursively - String path = p.getName(); - if (path.endsWith(File.separator)) { - path += "-"; - p = new FilePermission(path, SecurityConstants.FILE_READ_ACTION); - } - } else if ((p == null) && (url.getProtocol().equals("file"))) { - String path = url.getFile().replace('/', File.separatorChar); - path = ParseUtil.decode(path); - if (path.endsWith(File.separator)) - path += "-"; - p = new FilePermission(path, SecurityConstants.FILE_READ_ACTION); - } else { - /** - * Not loading from a 'file:' URL so we want to give the class - * permission to connect to and accept from the remote host - * after we've made sure the host is the correct one and is valid. - */ - URL locUrl = url; - if (urlConnection instanceof JarURLConnection) { - locUrl = ((JarURLConnection)urlConnection).getJarFileURL(); - } - String host = locUrl.getHost(); - if (host != null && !host.isEmpty()) - p = new SocketPermission(host, - SecurityConstants.SOCKET_CONNECT_ACCEPT_ACTION); - } - - // make sure the person that created this class loader - // would have this permission - - if (p != null) { - perms.add(p); - } - return perms; + @Override + protected PermissionCollection getPermissions(CodeSource codesource) { + Objects.requireNonNull(codesource); + return new Permissions(); } /** From 822a1554cb059580ab76bae7963827146b8f5aee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stig=20Rohde=20D=C3=B8ssing?= <stigdoessing@gmail.com> Date: Sat, 23 Nov 2024 15:58:39 +0000 Subject: [PATCH 201/311] 8341427: JFR: Adjust object sampler span handling Reviewed-by: egahlin --- .../leakprofiler/sampling/objectSampler.cpp | 28 +++++++++++++++---- .../leakprofiler/sampling/objectSampler.hpp | 1 + 2 files changed, 23 insertions(+), 6 deletions(-) diff --git a/src/hotspot/share/jfr/leakprofiler/sampling/objectSampler.cpp b/src/hotspot/share/jfr/leakprofiler/sampling/objectSampler.cpp index c80d93619a5..e4f822a407f 100644 --- a/src/hotspot/share/jfr/leakprofiler/sampling/objectSampler.cpp +++ b/src/hotspot/share/jfr/leakprofiler/sampling/objectSampler.cpp @@ -258,12 +258,25 @@ void ObjectSampler::add(HeapWord* obj, size_t allocated, traceid thread_id, bool // quick reject, will not fit return; } - sample = _list->reuse(_priority_queue->pop()); + ObjectSample* popped = _priority_queue->pop(); + size_t popped_span = popped->span(); + ObjectSample* previous = popped->prev(); + sample = _list->reuse(popped); + assert(sample != nullptr, "invariant"); + if (previous != nullptr) { + push_span(previous, popped_span); + sample->set_span(span); + } else { + // The removed sample was the youngest sample in the list, which means the new sample is now the youngest + // sample. It should cover the spans of both. + sample->set_span(span + popped_span); + } } else { sample = _list->get(); + assert(sample != nullptr, "invariant"); + sample->set_span(span); } - assert(sample != nullptr, "invariant"); signal_unresolved_entry(); sample->set_thread_id(thread_id); if (virtual_thread) { @@ -278,7 +291,6 @@ void ObjectSampler::add(HeapWord* obj, size_t allocated, traceid thread_id, bool sample->set_stack_trace_hash(stacktrace_hash); } - sample->set_span(allocated); sample->set_object(cast_to_oop(obj)); sample->set_allocated(allocated); sample->set_allocation_time(JfrTicks::now()); @@ -305,14 +317,18 @@ void ObjectSampler::remove_dead(ObjectSample* sample) { ObjectSample* const previous = sample->prev(); // push span onto previous if (previous != nullptr) { - _priority_queue->remove(previous); - previous->add_span(sample->span()); - _priority_queue->push(previous); + push_span(previous, sample->span()); } _priority_queue->remove(sample); _list->release(sample); } +void ObjectSampler::push_span(ObjectSample* sample, size_t span) { + _priority_queue->remove(sample); + sample->add_span(span); + _priority_queue->push(sample); +} + ObjectSample* ObjectSampler::last() const { return _list->last(); } diff --git a/src/hotspot/share/jfr/leakprofiler/sampling/objectSampler.hpp b/src/hotspot/share/jfr/leakprofiler/sampling/objectSampler.hpp index e6bb16506c9..25b5a67dd2a 100644 --- a/src/hotspot/share/jfr/leakprofiler/sampling/objectSampler.hpp +++ b/src/hotspot/share/jfr/leakprofiler/sampling/objectSampler.hpp @@ -64,6 +64,7 @@ class ObjectSampler : public CHeapObj<mtTracing> { void add(HeapWord* object, size_t size, traceid thread_id, bool virtual_thread, const JfrBlobHandle& bh, JavaThread* thread); void scavenge(); void remove_dead(ObjectSample* sample); + void push_span(ObjectSample* sample, size_t span); const ObjectSample* item_at(int index) const; ObjectSample* item_at(int index); From 7be94d043dd225fcf801c2dc9b0825598415a88f Mon Sep 17 00:00:00 2001 From: Phil Race <prr@openjdk.org> Date: Sat, 23 Nov 2024 23:20:15 +0000 Subject: [PATCH 202/311] 8344891: Remove uses of sun.misc.ReflectUtil in java.desktop Reviewed-by: kizune, azvegint --- .../macosx/classes/com/apple/laf/AquaUtils.java | 2 -- .../share/classes/com/sun/beans/finder/ClassFinder.java | 4 ---- .../classes/com/sun/beans/finder/ConstructorFinder.java | 3 +-- .../share/classes/com/sun/beans/finder/FieldFinder.java | 4 +--- .../share/classes/com/sun/beans/finder/MethodFinder.java | 5 ++--- .../share/classes/com/sun/beans/introspect/ClassInfo.java | 3 --- .../classes/com/sun/media/sound/JARSoundbankReader.java | 3 --- .../classes/java/beans/DefaultPersistenceDelegate.java | 5 +---- .../share/classes/java/beans/EventHandler.java | 2 -- .../share/classes/java/beans/Introspector.java | 4 ---- src/java.desktop/share/classes/java/beans/MetaData.java | 4 +--- src/java.desktop/share/classes/java/beans/MethodRef.java | 4 +--- .../share/classes/java/beans/PropertyDescriptor.java | 4 +--- src/java.desktop/share/classes/java/beans/Statement.java | 7 ------- src/java.desktop/share/classes/javax/print/SimpleDoc.java | 1 - .../share/classes/javax/swing/JEditorPane.java | 3 --- src/java.desktop/share/classes/javax/swing/JTable.java | 2 -- .../share/classes/javax/swing/SwingUtilities.java | 2 -- src/java.desktop/share/classes/javax/swing/UIDefaults.java | 3 --- .../share/classes/javax/swing/event/EventListenerList.java | 3 --- .../share/classes/javax/swing/plaf/synth/SynthParser.java | 3 +-- .../share/classes/javax/swing/text/DefaultFormatter.java | 2 -- .../share/classes/javax/swing/text/NumberFormatter.java | 2 -- .../share/classes/javax/swing/text/html/ObjectView.java | 2 -- 24 files changed, 9 insertions(+), 68 deletions(-) diff --git a/src/java.desktop/macosx/classes/com/apple/laf/AquaUtils.java b/src/java.desktop/macosx/classes/com/apple/laf/AquaUtils.java index d40d50b1b5c..d07e4992094 100644 --- a/src/java.desktop/macosx/classes/com/apple/laf/AquaUtils.java +++ b/src/java.desktop/macosx/classes/com/apple/laf/AquaUtils.java @@ -38,7 +38,6 @@ import sun.awt.AppContext; import sun.lwawt.macosx.CPlatformWindow; -import sun.reflect.misc.ReflectUtil; import sun.swing.SwingUtilities2; import com.apple.laf.AquaImageFactory.SlicedImageControl; @@ -174,7 +173,6 @@ static class RecyclableSingletonFromDefaultConstructor<T> extends RecyclableSing @SuppressWarnings("deprecation") T getInstance() { try { - ReflectUtil.checkPackageAccess(clazz); return clazz.newInstance(); } catch (ReflectiveOperationException ignored) { } diff --git a/src/java.desktop/share/classes/com/sun/beans/finder/ClassFinder.java b/src/java.desktop/share/classes/com/sun/beans/finder/ClassFinder.java index 616d6a5f55c..cdd022fcaf7 100644 --- a/src/java.desktop/share/classes/com/sun/beans/finder/ClassFinder.java +++ b/src/java.desktop/share/classes/com/sun/beans/finder/ClassFinder.java @@ -24,8 +24,6 @@ */ package com.sun.beans.finder; -import static sun.reflect.misc.ReflectUtil.checkPackageAccess; - /** * This is utility class that provides {@code static} methods * to find a class with the specified name using the specified class loader. @@ -56,7 +54,6 @@ public final class ClassFinder { * @see Thread#getContextClassLoader() */ public static Class<?> findClass(String name) throws ClassNotFoundException { - checkPackageAccess(name); try { ClassLoader loader = Thread.currentThread().getContextClassLoader(); if (loader == null) { @@ -95,7 +92,6 @@ public static Class<?> findClass(String name) throws ClassNotFoundException { * @see Class#forName(String,boolean,ClassLoader) */ public static Class<?> findClass(String name, ClassLoader loader) throws ClassNotFoundException { - checkPackageAccess(name); if (loader != null) { try { return Class.forName(name, false, loader); diff --git a/src/java.desktop/share/classes/com/sun/beans/finder/ConstructorFinder.java b/src/java.desktop/share/classes/com/sun/beans/finder/ConstructorFinder.java index d0315ada6bf..842afab25dd 100644 --- a/src/java.desktop/share/classes/com/sun/beans/finder/ConstructorFinder.java +++ b/src/java.desktop/share/classes/com/sun/beans/finder/ConstructorFinder.java @@ -30,7 +30,6 @@ import java.lang.reflect.Modifier; import static com.sun.beans.util.Cache.Kind.SOFT; -import static sun.reflect.misc.ReflectUtil.isPackageAccessible; /** * This utility class provides {@code static} methods @@ -81,7 +80,7 @@ public static Constructor<?> findConstructor(Class<?> type, Class<?>...args) thr throw new NoSuchMethodException("Abstract class cannot be instantiated: " + type.getName()); } - if (!Modifier.isPublic(type.getModifiers()) || !isPackageAccessible(type)) { + if (!Modifier.isPublic(type.getModifiers())) { throw new NoSuchMethodException("Class is not accessible: " + type.getName()); } PrimitiveWrapperMap.replacePrimitivesWithWrappers(args); diff --git a/src/java.desktop/share/classes/com/sun/beans/finder/FieldFinder.java b/src/java.desktop/share/classes/com/sun/beans/finder/FieldFinder.java index 5a4766dfb25..368be094ae3 100644 --- a/src/java.desktop/share/classes/com/sun/beans/finder/FieldFinder.java +++ b/src/java.desktop/share/classes/com/sun/beans/finder/FieldFinder.java @@ -27,8 +27,6 @@ import java.lang.reflect.Field; import java.lang.reflect.Modifier; -import static sun.reflect.misc.ReflectUtil.isPackageAccessible; - /** * This utility class provides {@code static} methods * to find a public field with specified name @@ -62,7 +60,7 @@ public static Field findField(Class<?> type, String name) throws NoSuchFieldExce throw new NoSuchFieldException("Field '" + name + "' is not public"); } type = field.getDeclaringClass(); - if (!Modifier.isPublic(type.getModifiers()) || !isPackageAccessible(type)) { + if (!Modifier.isPublic(type.getModifiers())) { throw new NoSuchFieldException("Field '" + name + "' is not accessible"); } return field; diff --git a/src/java.desktop/share/classes/com/sun/beans/finder/MethodFinder.java b/src/java.desktop/share/classes/com/sun/beans/finder/MethodFinder.java index eafc216c0e5..02b41058677 100644 --- a/src/java.desktop/share/classes/com/sun/beans/finder/MethodFinder.java +++ b/src/java.desktop/share/classes/com/sun/beans/finder/MethodFinder.java @@ -34,7 +34,6 @@ import java.util.Arrays; import static com.sun.beans.util.Cache.Kind.SOFT; -import static sun.reflect.misc.ReflectUtil.isPackageAccessible; /** * This utility class provides {@code static} methods @@ -79,7 +78,7 @@ public static Method findMethod(Class<?> type, String name, Class<?>...args) thr try { Method method = CACHE.get(signature); - return (method == null) || isPackageAccessible(method.getDeclaringClass()) ? method : CACHE.create(signature); + return (method == null) ? method : CACHE.create(signature); } catch (SignatureException exception) { throw exception.toNoSuchMethodException("Method '" + name + "' is not found"); @@ -138,7 +137,7 @@ public static Method findAccessibleMethod(Method method) throws NoSuchMethodExce if (!FinderUtils.isExported(type)) { throw new NoSuchMethodException("Method '" + method.getName() + "' is not accessible"); } - if (Modifier.isPublic(type.getModifiers()) && isPackageAccessible(type)) { + if (Modifier.isPublic(type.getModifiers())) { return method; } if (Modifier.isStatic(method.getModifiers())) { diff --git a/src/java.desktop/share/classes/com/sun/beans/introspect/ClassInfo.java b/src/java.desktop/share/classes/com/sun/beans/introspect/ClassInfo.java index afd42a26e58..dce0469c7c9 100644 --- a/src/java.desktop/share/classes/com/sun/beans/introspect/ClassInfo.java +++ b/src/java.desktop/share/classes/com/sun/beans/introspect/ClassInfo.java @@ -31,8 +31,6 @@ import com.sun.beans.util.Cache; -import static sun.reflect.misc.ReflectUtil.checkPackageAccess; - public final class ClassInfo { private static final ClassInfo DEFAULT = new ClassInfo(null); private static final Cache<Class<?>,ClassInfo> CACHE @@ -48,7 +46,6 @@ public static ClassInfo get(Class<?> type) { return DEFAULT; } try { - checkPackageAccess(type); return CACHE.get(type); } catch (SecurityException exception) { return DEFAULT; diff --git a/src/java.desktop/share/classes/com/sun/media/sound/JARSoundbankReader.java b/src/java.desktop/share/classes/com/sun/media/sound/JARSoundbankReader.java index 8b492fa7782..15eb82665e6 100644 --- a/src/java.desktop/share/classes/com/sun/media/sound/JARSoundbankReader.java +++ b/src/java.desktop/share/classes/com/sun/media/sound/JARSoundbankReader.java @@ -39,8 +39,6 @@ import javax.sound.midi.Soundbank; import javax.sound.midi.spi.SoundbankReader; -import sun.reflect.misc.ReflectUtil; - /** * JarSoundbankReader is used to read soundbank object from jar files. * @@ -95,7 +93,6 @@ public Soundbank getSoundbank(URL url) try { Class<?> c = Class.forName(line.trim(), false, ucl); if (Soundbank.class.isAssignableFrom(c)) { - ReflectUtil.checkPackageAccess(c); Object o = c.newInstance(); soundbanks.add((Soundbank) o); } diff --git a/src/java.desktop/share/classes/java/beans/DefaultPersistenceDelegate.java b/src/java.desktop/share/classes/java/beans/DefaultPersistenceDelegate.java index 3ca672d75b2..6a8a8239663 100644 --- a/src/java.desktop/share/classes/java/beans/DefaultPersistenceDelegate.java +++ b/src/java.desktop/share/classes/java/beans/DefaultPersistenceDelegate.java @@ -27,7 +27,7 @@ import java.util.*; import java.lang.reflect.*; import java.util.Objects; -import sun.reflect.misc.*; +import sun.reflect.misc.MethodUtil; /** @@ -222,9 +222,6 @@ static void invokeStatement(Object instance, String methodName, Object[] args, E // Write out the properties of this instance. private void initBean(Class<?> type, Object oldInstance, Object newInstance, Encoder out) { for (Field field : type.getFields()) { - if (!ReflectUtil.isPackageAccessible(field.getDeclaringClass())) { - continue; - } int mod = field.getModifiers(); if (Modifier.isFinal(mod) || Modifier.isStatic(mod) || Modifier.isTransient(mod)) { continue; diff --git a/src/java.desktop/share/classes/java/beans/EventHandler.java b/src/java.desktop/share/classes/java/beans/EventHandler.java index eb892f34985..64ae9972f6c 100644 --- a/src/java.desktop/share/classes/java/beans/EventHandler.java +++ b/src/java.desktop/share/classes/java/beans/EventHandler.java @@ -30,7 +30,6 @@ import java.lang.reflect.Method; import sun.reflect.misc.MethodUtil; -import sun.reflect.misc.ReflectUtil; /** * The {@code EventHandler} class provides @@ -691,7 +690,6 @@ public static <T> T create(Class<T> listenerInterface, } private static ClassLoader getClassLoader(Class<?> type) { - ReflectUtil.checkPackageAccess(type); ClassLoader loader = type.getClassLoader(); if (loader == null) { loader = Thread.currentThread().getContextClassLoader(); // avoid use of BCP diff --git a/src/java.desktop/share/classes/java/beans/Introspector.java b/src/java.desktop/share/classes/java/beans/Introspector.java index 29d783eeac6..7dfd2e60a8e 100644 --- a/src/java.desktop/share/classes/java/beans/Introspector.java +++ b/src/java.desktop/share/classes/java/beans/Introspector.java @@ -47,7 +47,6 @@ import com.sun.beans.introspect.PropertyInfo; import jdk.internal.access.JavaBeansAccess; import jdk.internal.access.SharedSecrets; -import sun.reflect.misc.ReflectUtil; /** * The Introspector class provides a standard way for tools to learn about @@ -186,9 +185,6 @@ public String[] getConstructorPropertiesValue(Constructor<?> ctr) { public static BeanInfo getBeanInfo(Class<?> beanClass) throws IntrospectionException { - if (!ReflectUtil.isPackageAccessible(beanClass)) { - return (new Introspector(beanClass, null, USE_ALL_BEANINFO)).getBeanInfo(); - } ThreadGroupContext context = ThreadGroupContext.getContext(); BeanInfo beanInfo = context.getBeanInfo(beanClass); if (beanInfo == null) { diff --git a/src/java.desktop/share/classes/java/beans/MetaData.java b/src/java.desktop/share/classes/java/beans/MetaData.java index 0a12e7dcee8..e073afbe040 100644 --- a/src/java.desktop/share/classes/java/beans/MetaData.java +++ b/src/java.desktop/share/classes/java/beans/MetaData.java @@ -50,8 +50,6 @@ import sun.swing.PrintColorUIResource; -import static sun.reflect.misc.ReflectUtil.isPackageAccessible; - /* * Like the {@code Introspector}, the {@code MetaData} class * contains <em>meta</em> objects that describe the way @@ -749,7 +747,7 @@ protected Expression instantiate(Object oldInstance, Encoder out) { static class StaticFieldsPersistenceDelegate extends PersistenceDelegate { protected void installFields(Encoder out, Class<?> cls) { - if (Modifier.isPublic(cls.getModifiers()) && isPackageAccessible(cls)) { + if (Modifier.isPublic(cls.getModifiers())) { Field[] fields = cls.getFields(); for(int i = 0; i < fields.length; i++) { Field field = fields[i]; diff --git a/src/java.desktop/share/classes/java/beans/MethodRef.java b/src/java.desktop/share/classes/java/beans/MethodRef.java index 6be617f2951..7ddba2a4461 100644 --- a/src/java.desktop/share/classes/java/beans/MethodRef.java +++ b/src/java.desktop/share/classes/java/beans/MethodRef.java @@ -29,8 +29,6 @@ import java.lang.ref.WeakReference; import java.lang.reflect.Method; -import static sun.reflect.misc.ReflectUtil.isPackageAccessible; - final class MethodRef { private String signature; private SoftReference<Method> methodRef; @@ -68,7 +66,7 @@ Method get() { } this.methodRef = new SoftReference<>(method); } - return isPackageAccessible(method.getDeclaringClass()) ? method : null; + return method; } private static Method find(Class<?> type, String signature) { diff --git a/src/java.desktop/share/classes/java/beans/PropertyDescriptor.java b/src/java.desktop/share/classes/java/beans/PropertyDescriptor.java index ae4bb69c18c..0ce8591ba52 100644 --- a/src/java.desktop/share/classes/java/beans/PropertyDescriptor.java +++ b/src/java.desktop/share/classes/java/beans/PropertyDescriptor.java @@ -30,7 +30,6 @@ import java.util.Map.Entry; import com.sun.beans.introspect.PropertyInfo; -import sun.reflect.misc.ReflectUtil; /** * A PropertyDescriptor describes one property that a Java Bean @@ -467,8 +466,7 @@ public PropertyEditor createPropertyEditor(Object bean) { Object editor = null; final Class<?> cls = getPropertyEditorClass(); - if (cls != null && PropertyEditor.class.isAssignableFrom(cls) - && ReflectUtil.isPackageAccessible(cls)) { + if (cls != null && PropertyEditor.class.isAssignableFrom(cls)) { Constructor<?> ctor = null; if (bean != null) { try { diff --git a/src/java.desktop/share/classes/java/beans/Statement.java b/src/java.desktop/share/classes/java/beans/Statement.java index bf1c62be78b..117aef7f22b 100644 --- a/src/java.desktop/share/classes/java/beans/Statement.java +++ b/src/java.desktop/share/classes/java/beans/Statement.java @@ -35,8 +35,6 @@ import com.sun.beans.finder.MethodFinder; import sun.reflect.misc.MethodUtil; -import static sun.reflect.misc.ReflectUtil.checkPackageAccess; - /** * A {@code Statement} object represents a primitive statement * in which a single method is applied to a target and @@ -189,13 +187,8 @@ Object invoke() throws Exception { // Class.forName(String className) won't load classes outside // of core from a class inside core. Special // case this method. - // checkPackageAccess(name) will be called by ClassFinder return ClassFinder.resolveClass(name, this.loader); } - // The 3 args Class.forName(String className, boolean, classloader) - // requires getClassLoader permission, but we will be stricter and - // will require access to the package as well. - checkPackageAccess(name); } Class<?>[] argClasses = new Class<?>[arguments.length]; for(int i = 0; i < arguments.length; i++) { diff --git a/src/java.desktop/share/classes/javax/print/SimpleDoc.java b/src/java.desktop/share/classes/javax/print/SimpleDoc.java index 5a42fc9b472..dd4dfdbe485 100644 --- a/src/java.desktop/share/classes/javax/print/SimpleDoc.java +++ b/src/java.desktop/share/classes/javax/print/SimpleDoc.java @@ -108,7 +108,6 @@ public SimpleDoc(Object printData, Class<?> repClass = null; try { String className = flavor.getRepresentationClassName(); - sun.reflect.misc.ReflectUtil.checkPackageAccess(className); repClass = Class.forName(className, false, Thread.currentThread().getContextClassLoader()); } catch (Throwable e) { diff --git a/src/java.desktop/share/classes/javax/swing/JEditorPane.java b/src/java.desktop/share/classes/javax/swing/JEditorPane.java index cdcbb7feaf0..ff23b4f5589 100644 --- a/src/java.desktop/share/classes/javax/swing/JEditorPane.java +++ b/src/java.desktop/share/classes/javax/swing/JEditorPane.java @@ -94,8 +94,6 @@ import javax.swing.text.html.HTMLDocument; import javax.swing.text.html.HTMLEditorKit; -import sun.reflect.misc.ReflectUtil; - /** * A text component to edit various kinds of content. * You can find how-to information and examples of using editor panes in @@ -1238,7 +1236,6 @@ public static EditorKit createEditorKitForContentType(String type) { try { Class<?> c; if (loader != null) { - ReflectUtil.checkPackageAccess(classname); c = loader.loadClass(classname); } else { // Will only happen if developer has invoked diff --git a/src/java.desktop/share/classes/javax/swing/JTable.java b/src/java.desktop/share/classes/javax/swing/JTable.java index 179e06c4ebd..0ff490d45ea 100644 --- a/src/java.desktop/share/classes/javax/swing/JTable.java +++ b/src/java.desktop/share/classes/javax/swing/JTable.java @@ -113,7 +113,6 @@ import sun.awt.AWTAccessor; import sun.awt.AWTAccessor.MouseEventAccessor; -import sun.reflect.misc.ReflectUtil; import sun.swing.PrintingStatus; import sun.swing.SwingUtilities2; import sun.swing.SwingUtilities2.Section; @@ -5585,7 +5584,6 @@ public Component getTableCellEditorComponent(JTable table, Object value, if (type == Object.class) { type = String.class; } - ReflectUtil.checkPackageAccess(type); SwingUtilities2.checkAccess(type.getModifiers()); constructor = type.getConstructor(argTypes); } diff --git a/src/java.desktop/share/classes/javax/swing/SwingUtilities.java b/src/java.desktop/share/classes/javax/swing/SwingUtilities.java index 89fe8970531..8d944187418 100644 --- a/src/java.desktop/share/classes/javax/swing/SwingUtilities.java +++ b/src/java.desktop/share/classes/javax/swing/SwingUtilities.java @@ -24,7 +24,6 @@ */ package javax.swing; -import sun.reflect.misc.ReflectUtil; import sun.swing.SwingUtilities2; import sun.swing.UIAction; @@ -2033,7 +2032,6 @@ static void appContextRemove(Object key) { static Class<?> loadSystemClass(String className) throws ClassNotFoundException { - ReflectUtil.checkPackageAccess(className); return Class.forName(className, true, Thread.currentThread(). getContextClassLoader()); } diff --git a/src/java.desktop/share/classes/javax/swing/UIDefaults.java b/src/java.desktop/share/classes/javax/swing/UIDefaults.java index c8d294f4fbf..53eb870d3e6 100644 --- a/src/java.desktop/share/classes/javax/swing/UIDefaults.java +++ b/src/java.desktop/share/classes/javax/swing/UIDefaults.java @@ -51,7 +51,6 @@ import java.beans.PropertyChangeListener; import sun.reflect.misc.MethodUtil; -import sun.reflect.misc.ReflectUtil; import sun.swing.SwingAccessor; import sun.swing.SwingUtilities2; @@ -702,7 +701,6 @@ public Dimension getDimension(Object key, Locale l) { try { String className = (String)get(uiClassID); if (className != null) { - ReflectUtil.checkPackageAccess(className); Class<?> cls = (Class)get(className); if (cls == null) { @@ -1142,7 +1140,6 @@ public Object createValue(final UIDefaults table) { cl = ClassLoader.getSystemClassLoader(); } } - ReflectUtil.checkPackageAccess(className); c = Class.forName(className, true, (ClassLoader)cl); SwingUtilities2.checkAccess(c.getModifiers()); if (methodName != null) { diff --git a/src/java.desktop/share/classes/javax/swing/event/EventListenerList.java b/src/java.desktop/share/classes/javax/swing/event/EventListenerList.java index 7960e1a471e..3ed3b73094b 100644 --- a/src/java.desktop/share/classes/javax/swing/event/EventListenerList.java +++ b/src/java.desktop/share/classes/javax/swing/event/EventListenerList.java @@ -33,8 +33,6 @@ import java.lang.reflect.Array; import java.util.EventListener; -import sun.reflect.misc.ReflectUtil; - /** * A class that holds a list of EventListeners. A single instance * can be used to hold all listeners (of all types) for the instance @@ -303,7 +301,6 @@ private void readObject(ObjectInputStream s) ClassLoader cl = Thread.currentThread().getContextClassLoader(); EventListener l = (EventListener)s.readObject(); String name = (String) listenerTypeOrNull; - ReflectUtil.checkPackageAccess(name); @SuppressWarnings("unchecked") Class<EventListener> tmp = (Class<EventListener>)Class.forName(name, true, cl); add(tmp, l); diff --git a/src/java.desktop/share/classes/javax/swing/plaf/synth/SynthParser.java b/src/java.desktop/share/classes/javax/swing/plaf/synth/SynthParser.java index c660665d10b..e9ad49c391d 100644 --- a/src/java.desktop/share/classes/javax/swing/plaf/synth/SynthParser.java +++ b/src/java.desktop/share/classes/javax/swing/plaf/synth/SynthParser.java @@ -67,7 +67,6 @@ import org.xml.sax.helpers.DefaultHandler; import com.sun.beans.decoder.DocumentHandler; -import sun.reflect.misc.ReflectUtil; class SynthParser extends DefaultHandler { // @@ -646,7 +645,7 @@ else if (key.equals(ATTRIBUTE_TYPE)) { } else { try { - typeClass = ReflectUtil.forName(typeName.substring( + typeClass = Class.forName(typeName.substring( 0, classIndex)); } catch (ClassNotFoundException cnfe) { throw new SAXException("Unknown class: " + diff --git a/src/java.desktop/share/classes/javax/swing/text/DefaultFormatter.java b/src/java.desktop/share/classes/javax/swing/text/DefaultFormatter.java index df7417ccf13..38ea1cda125 100644 --- a/src/java.desktop/share/classes/javax/swing/text/DefaultFormatter.java +++ b/src/java.desktop/share/classes/javax/swing/text/DefaultFormatter.java @@ -24,7 +24,6 @@ */ package javax.swing.text; -import sun.reflect.misc.ReflectUtil; import sun.swing.SwingUtilities2; import java.io.Serializable; @@ -248,7 +247,6 @@ public Object stringToValue(String string) throws ParseException { Constructor<?> cons; try { - ReflectUtil.checkPackageAccess(vc); SwingUtilities2.checkAccess(vc.getModifiers()); cons = vc.getConstructor(new Class<?>[]{String.class}); diff --git a/src/java.desktop/share/classes/javax/swing/text/NumberFormatter.java b/src/java.desktop/share/classes/javax/swing/text/NumberFormatter.java index 48b68ace5d5..f3e9a8d2a58 100644 --- a/src/java.desktop/share/classes/javax/swing/text/NumberFormatter.java +++ b/src/java.desktop/share/classes/javax/swing/text/NumberFormatter.java @@ -33,7 +33,6 @@ import java.text.ParseException; import java.util.Map; -import sun.reflect.misc.ReflectUtil; import sun.swing.SwingUtilities2; /** @@ -437,7 +436,6 @@ private Object toggleSign(boolean positive) throws ParseException { valueClass = value.getClass(); } try { - ReflectUtil.checkPackageAccess(valueClass); SwingUtilities2.checkAccess(valueClass.getModifiers()); Constructor<?> cons = valueClass.getConstructor( new Class<?>[] { String.class }); diff --git a/src/java.desktop/share/classes/javax/swing/text/html/ObjectView.java b/src/java.desktop/share/classes/javax/swing/text/html/ObjectView.java index 050a79fe85e..bdc73d85c3e 100644 --- a/src/java.desktop/share/classes/javax/swing/text/html/ObjectView.java +++ b/src/java.desktop/share/classes/javax/swing/text/html/ObjectView.java @@ -31,7 +31,6 @@ import java.lang.reflect.*; import sun.reflect.misc.MethodUtil; -import sun.reflect.misc.ReflectUtil; /** * Component decorator that implements the view interface @@ -100,7 +99,6 @@ protected Component createComponent() { AttributeSet attr = getElement().getAttributes(); String classname = (String) attr.getAttribute(HTML.Attribute.CLASSID); try { - ReflectUtil.checkPackageAccess(classname); Class<?> c = Class.forName(classname, false,Thread.currentThread(). getContextClassLoader()); if (Component.class.isAssignableFrom(c)) { From a6220fa90362980fce2fc56e70c7c9a7ed7e11c5 Mon Sep 17 00:00:00 2001 From: Harshitha Onkar <honkar@openjdk.org> Date: Sun, 24 Nov 2024 06:22:45 +0000 Subject: [PATCH 203/311] 8344303: Remove usage of URLUtil.getConnectPermission from sun.awt.SunToolkit and sun.awt.image.URLImageSource Reviewed-by: prr, azvegint --- src/java.base/share/classes/module-info.java | 1 - .../share/classes/sun/net/util/URLUtil.java | 25 ------------------- .../share/classes/sun/awt/SunToolkit.java | 20 --------------- .../classes/sun/awt/image/URLImageSource.java | 15 ----------- 4 files changed, 61 deletions(-) diff --git a/src/java.base/share/classes/module-info.java b/src/java.base/share/classes/module-info.java index 057bae02efc..5a44adeb294 100644 --- a/src/java.base/share/classes/module-info.java +++ b/src/java.base/share/classes/module-info.java @@ -291,7 +291,6 @@ java.security.jgss, jdk.naming.dns; exports sun.net.util to - java.desktop, java.net.http, jdk.jconsole, jdk.sctp; diff --git a/src/java.base/share/classes/sun/net/util/URLUtil.java b/src/java.base/share/classes/sun/net/util/URLUtil.java index 055742baf2f..3a7800394b6 100644 --- a/src/java.base/share/classes/sun/net/util/URLUtil.java +++ b/src/java.base/share/classes/sun/net/util/URLUtil.java @@ -25,10 +25,7 @@ package sun.net.util; -import java.io.IOException; import java.net.URL; -import java.net.URLPermission; -import java.security.Permission; import java.util.Locale; /** @@ -87,27 +84,5 @@ public static String urlNoFragString(URL url) { return strForm.toString(); } - - public static Permission getConnectPermission(URL url) throws IOException { - String urlStringLowerCase = url.toString().toLowerCase(Locale.ROOT); - if (urlStringLowerCase.startsWith("http:") || urlStringLowerCase.startsWith("https:")) { - return getURLConnectPermission(url); - } else if (urlStringLowerCase.startsWith("jar:http:") || urlStringLowerCase.startsWith("jar:https:")) { - String urlString = url.toString(); - int bangPos = urlString.indexOf("!/"); - urlString = urlString.substring(4, bangPos > -1 ? bangPos : urlString.length()); - @SuppressWarnings("deprecation") - URL u = new URL(urlString); - return getURLConnectPermission(u); - // If protocol is HTTP or HTTPS than use URLPermission object - } else { - return url.openConnection().getPermission(); - } - } - - private static Permission getURLConnectPermission(URL url) { - String urlString = url.getProtocol() + "://" + url.getAuthority() + url.getPath(); - return new URLPermission(urlString); - } } diff --git a/src/java.desktop/share/classes/sun/awt/SunToolkit.java b/src/java.desktop/share/classes/sun/awt/SunToolkit.java index 1dc6c2f3920..439167d6642 100644 --- a/src/java.desktop/share/classes/sun/awt/SunToolkit.java +++ b/src/java.desktop/share/classes/sun/awt/SunToolkit.java @@ -98,7 +98,6 @@ import sun.awt.image.ToolkitImage; import sun.awt.image.URLImageSource; import sun.font.FontDesignMetrics; -import sun.net.util.URLUtil; import sun.util.logging.PlatformLogger; import static java.awt.RenderingHints.KEY_TEXT_ANTIALIASING; @@ -686,7 +685,6 @@ public static boolean getSunAwtErasebackgroundonresize() { static final SoftCache urlImgCache = new SoftCache(); static Image getImageFromHash(Toolkit tk, URL url) { - checkPermissions(url); synchronized (urlImgCache) { String key = url.toString(); Image img = (Image)urlImgCache.get(key); @@ -765,7 +763,6 @@ public Image createImage(String filename) { @Override public Image createImage(URL url) { - checkPermissions(url); return createImage(new URLImageSource(url)); } @@ -882,7 +879,6 @@ protected static boolean imageExists(String filename) { @SuppressWarnings("try") protected static boolean imageExists(URL url) { if (url != null) { - checkPermissions(url); try (InputStream is = url.openStream()) { return true; }catch(IOException e){ @@ -900,22 +896,6 @@ private static void checkPermissions(String filename) { } } - private static void checkPermissions(URL url) { - @SuppressWarnings("removal") - SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - try { - java.security.Permission perm = - URLUtil.getConnectPermission(url); - if (perm != null) { - sm.checkPermission(perm); - } - } catch (java.io.IOException ioe) { - sm.checkConnect(url.getHost(), url.getPort()); - } - } - } - /** * Scans {@code imageList} for best-looking image of specified dimensions. * Image can be scaled and/or padded with transparency. diff --git a/src/java.desktop/share/classes/sun/awt/image/URLImageSource.java b/src/java.desktop/share/classes/sun/awt/image/URLImageSource.java index 0cb44ae64b0..93d339e3fe1 100644 --- a/src/java.desktop/share/classes/sun/awt/image/URLImageSource.java +++ b/src/java.desktop/share/classes/sun/awt/image/URLImageSource.java @@ -31,7 +31,6 @@ import java.net.URL; import java.net.URLConnection; import java.net.MalformedURLException; -import sun.net.util.URLUtil; public class URLImageSource extends InputStreamImageSource { URL url; @@ -40,21 +39,7 @@ public class URLImageSource extends InputStreamImageSource { int actualPort; public URLImageSource(URL u) { - @SuppressWarnings("removal") - SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - try { - java.security.Permission perm = - URLUtil.getConnectPermission(u); - if (perm != null) { - sm.checkPermission(perm); - } - } catch (java.io.IOException ioe) { - sm.checkConnect(u.getHost(), u.getPort()); - } - } this.url = u; - } public URLImageSource(String href) throws MalformedURLException { From 6711e1327a76782c8315b9e85525e1408657727b Mon Sep 17 00:00:00 2001 From: Damon Nguyen <dnguyen@openjdk.org> Date: Sun, 24 Nov 2024 08:54:17 +0000 Subject: [PATCH 204/311] 8344914: OOME in several tests since JDK-6672644 - JComboBox still scrolling Reviewed-by: prr --- .../swing/plaf/basic/BasicScrollBarUI.java | 45 ----------- .../JComboBox/JComboBoxScrollFocusTest.java | 75 ------------------- 2 files changed, 120 deletions(-) delete mode 100644 test/jdk/javax/swing/JComboBox/JComboBoxScrollFocusTest.java diff --git a/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicScrollBarUI.java b/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicScrollBarUI.java index 9fc9b64314c..60274d766cd 100644 --- a/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicScrollBarUI.java +++ b/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicScrollBarUI.java @@ -31,7 +31,6 @@ import java.awt.Dimension; import java.awt.Graphics; import java.awt.Insets; -import java.awt.KeyboardFocusManager; import java.awt.LayoutManager; import java.awt.Point; import java.awt.Rectangle; @@ -123,8 +122,6 @@ public class BasicScrollBarUI protected ArrowButtonListener buttonListener; /** Model listener */ protected ModelListener modelListener; - /** KeyboardFocusListener */ - protected KeyboardFocusListener keyboardFocusListener; /** Thumb rectangle */ protected Rectangle thumbRect; @@ -359,15 +356,12 @@ protected void installListeners(){ buttonListener = createArrowButtonListener(); modelListener = createModelListener(); propertyChangeListener = createPropertyChangeListener(); - keyboardFocusListener = createKeyboardFocusListener(); scrollbar.addMouseListener(trackListener); scrollbar.addMouseMotionListener(trackListener); scrollbar.getModel().addChangeListener(modelListener); scrollbar.addPropertyChangeListener(propertyChangeListener); scrollbar.addFocusListener(getHandler()); - KeyboardFocusManager.getCurrentKeyboardFocusManager() - .addPropertyChangeListener(keyboardFocusListener); if (incrButton != null) { incrButton.addMouseListener(buttonListener); @@ -449,8 +443,6 @@ protected void uninstallListeners() { incrButton.removeMouseListener(buttonListener); } - KeyboardFocusManager.getCurrentKeyboardFocusManager() - .removePropertyChangeListener(keyboardFocusListener); scrollbar.getModel().removeChangeListener(modelListener); scrollbar.removeMouseListener(trackListener); scrollbar.removeMouseMotionListener(trackListener); @@ -517,14 +509,6 @@ protected PropertyChangeListener createPropertyChangeListener() { return getHandler(); } - /** - * Creates a keyboard focus listener. - * @return a keyboard focus listener - */ - protected KeyboardFocusListener createKeyboardFocusListener() { - return new KeyboardFocusListener(); - } - private void updateThumbState(int x, int y) { Rectangle rect = getThumbBounds(); @@ -1218,35 +1202,6 @@ public boolean getSupportsAbsolutePositioning() { return supportsAbsolutePositioning; } - /** - * A listener to listen for keyboard focus changes. - */ - protected class KeyboardFocusListener implements PropertyChangeListener { - /** - * Constructs a {@code KeyboardFocusListener}. - */ - protected KeyboardFocusListener() {} - - @Override - public void propertyChange(PropertyChangeEvent e) { - String propertyName = e.getPropertyName(); - - if ("focusOwner" == propertyName) { - // Stop scrolling if no longer focus owner - if (e.getNewValue() == null && scrollTimer.isRunning()) { - scrollTimer.stop(); - buttonListener.handledEvent = false; - scrollbar.setValueIsAdjusting(false); - if (incrButton.getModel().isPressed()) { - incrButton.getModel().setPressed(false); - } else if (decrButton.getModel().isPressed()) { - decrButton.getModel().setPressed(false); - } - } - } - } - } - /** * A listener to listen for model changes. */ diff --git a/test/jdk/javax/swing/JComboBox/JComboBoxScrollFocusTest.java b/test/jdk/javax/swing/JComboBox/JComboBoxScrollFocusTest.java deleted file mode 100644 index 4d2c3bd19cc..00000000000 --- a/test/jdk/javax/swing/JComboBox/JComboBoxScrollFocusTest.java +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -import javax.swing.JComboBox; -import javax.swing.JFrame; - -/* - * @test - * @bug 6672644 - * @library /java/awt/regtesthelpers - * @build PassFailJFrame - * @summary Tests JComboBox scrollbar behavior when alt-tabbing - * @requires os.family != "mac" - * @run main/manual JComboBoxScrollFocusTest - */ - -public class JComboBoxScrollFocusTest { - private static final String INSTRUCTIONS = - """ - Click on the dropdown button for the JComboBox in the test frame. - Then, press and hold the left click button on the down arrow button - in the popup list. While holding the left click button, the list - should be scrolling down. Press ALT + TAB while holding down the - left click to switch focus to a different window. Then release the - left click button. Focus the test frame again and click the - dropdown button for the JComboBox again. The list should be - stationary and not be automatically scrolling. - - If you are able to execute all steps successfully then the test - passes, otherwise it fails. - """; - - public static void main(String[] args) throws Exception { - PassFailJFrame - .builder() - .title("JComboBoxScrollFocusTest Test Instructions") - .instructions(INSTRUCTIONS) - .columns(40) - .testUI(JComboBoxScrollFocusTest::createAndShowGUI) - .build() - .awaitAndCheck(); - } - - private static JFrame createAndShowGUI() { - JFrame frame = new JFrame("JComboBoxScrollFocusTest Test Frame"); - JComboBox<String> combobox = new JComboBox<>(); - for (int i = 0; i < 100; i++) { - combobox.addItem(String.valueOf(i)); - } - frame.add(combobox); - frame.setSize(400, 200); - frame.setLocationRelativeTo(null); - return frame; - } -} From a83cfe26583db078ecd754d9609111c0c6dac6a4 Mon Sep 17 00:00:00 2001 From: Kim Barrett <kbarrett@openjdk.org> Date: Sun, 24 Nov 2024 17:10:31 +0000 Subject: [PATCH 205/311] 8344917: Fix recent NULL usage backsliding Reviewed-by: jsjolen --- .../cpu/aarch64/templateInterpreterGenerator_aarch64.cpp | 2 +- src/hotspot/cpu/riscv/templateInterpreterGenerator_riscv.cpp | 2 +- src/hotspot/cpu/x86/templateInterpreterGenerator_x86.cpp | 2 +- src/hotspot/share/cds/archiveUtils.hpp | 2 +- src/hotspot/share/cds/metaspaceShared.cpp | 2 +- src/hotspot/share/gc/shared/locationPrinter.inline.hpp | 4 ++-- src/hotspot/share/oops/constantPool.cpp | 4 ++-- 7 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/hotspot/cpu/aarch64/templateInterpreterGenerator_aarch64.cpp b/src/hotspot/cpu/aarch64/templateInterpreterGenerator_aarch64.cpp index 8eefcba7ba2..f70450b7222 100644 --- a/src/hotspot/cpu/aarch64/templateInterpreterGenerator_aarch64.cpp +++ b/src/hotspot/cpu/aarch64/templateInterpreterGenerator_aarch64.cpp @@ -620,7 +620,7 @@ address TemplateInterpreterGenerator::generate_cont_resume_interpreter_adapter() // Restore Java expression stack pointer __ ldr(rscratch1, Address(rfp, frame::interpreter_frame_last_sp_offset * wordSize)); __ lea(esp, Address(rfp, rscratch1, Address::lsl(Interpreter::logStackElementSize))); - // and NULL it as marker that esp is now tos until next java call + // and null it as marker that esp is now tos until next java call __ str(zr, Address(rfp, frame::interpreter_frame_last_sp_offset * wordSize)); // Restore machine SP diff --git a/src/hotspot/cpu/riscv/templateInterpreterGenerator_riscv.cpp b/src/hotspot/cpu/riscv/templateInterpreterGenerator_riscv.cpp index ac28f4b3514..2e062cab605 100644 --- a/src/hotspot/cpu/riscv/templateInterpreterGenerator_riscv.cpp +++ b/src/hotspot/cpu/riscv/templateInterpreterGenerator_riscv.cpp @@ -552,7 +552,7 @@ address TemplateInterpreterGenerator::generate_cont_resume_interpreter_adapter() // Restore Java expression stack pointer __ ld(t0, Address(fp, frame::interpreter_frame_last_sp_offset * wordSize)); __ shadd(esp, t0, fp, t0, Interpreter::logStackElementSize); - // and NULL it as marker that esp is now tos until next java call + // and null it as marker that esp is now tos until next java call __ sd(zr, Address(fp, frame::interpreter_frame_last_sp_offset * wordSize)); // Restore machine SP diff --git a/src/hotspot/cpu/x86/templateInterpreterGenerator_x86.cpp b/src/hotspot/cpu/x86/templateInterpreterGenerator_x86.cpp index beb80d83e2e..823b965a09b 100644 --- a/src/hotspot/cpu/x86/templateInterpreterGenerator_x86.cpp +++ b/src/hotspot/cpu/x86/templateInterpreterGenerator_x86.cpp @@ -400,7 +400,7 @@ address TemplateInterpreterGenerator::generate_cont_resume_interpreter_adapter() // Restore stack bottom __ movptr(rcx, Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize)); __ lea(rsp, Address(rbp, rcx, Address::times_ptr)); - // and NULL it as marker that esp is now tos until next java call + // and null it as marker that esp is now tos until next java call __ movptr(Address(rbp, frame::interpreter_frame_last_sp_offset * wordSize), NULL_WORD); __ jmp(rax); diff --git a/src/hotspot/share/cds/archiveUtils.hpp b/src/hotspot/share/cds/archiveUtils.hpp index 606f5137e9d..ee1135b70fa 100644 --- a/src/hotspot/share/cds/archiveUtils.hpp +++ b/src/hotspot/share/cds/archiveUtils.hpp @@ -162,7 +162,7 @@ class DumpRegion { DumpRegion(const char* name, uintx max_delta = 0) : _name(name), _base(nullptr), _top(nullptr), _end(nullptr), _max_delta(max_delta), _is_packed(false), - _rs(NULL), _vs(NULL) {} + _rs(nullptr), _vs(nullptr) {} char* expand_top_to(char* newtop); char* allocate(size_t num_bytes, size_t alignment = 0); diff --git a/src/hotspot/share/cds/metaspaceShared.cpp b/src/hotspot/share/cds/metaspaceShared.cpp index b2f5f420365..3ea2f54cfa9 100644 --- a/src/hotspot/share/cds/metaspaceShared.cpp +++ b/src/hotspot/share/cds/metaspaceShared.cpp @@ -315,7 +315,7 @@ static GrowableArrayCHeap<OopHandle, mtClassShared>* _extra_interned_strings = n // Extra Symbols to be added to the archive static GrowableArrayCHeap<Symbol*, mtClassShared>* _extra_symbols = nullptr; // Methods managed by SystemDictionary::find_method_handle_intrinsic() to be added to the archive -static GrowableArray<Method*>* _pending_method_handle_intrinsics = NULL; +static GrowableArray<Method*>* _pending_method_handle_intrinsics = nullptr; void MetaspaceShared::read_extra_data(JavaThread* current, const char* filename) { _extra_interned_strings = new GrowableArrayCHeap<OopHandle, mtClassShared>(10000); diff --git a/src/hotspot/share/gc/shared/locationPrinter.inline.hpp b/src/hotspot/share/gc/shared/locationPrinter.inline.hpp index ae873d52cb5..bb79bf80a5b 100644 --- a/src/hotspot/share/gc/shared/locationPrinter.inline.hpp +++ b/src/hotspot/share/gc/shared/locationPrinter.inline.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -54,7 +54,7 @@ bool BlockLocationPrinter<CollectedHeapT>::print_location(outputStream* st, void // Check if addr points into Java heap. bool in_heap = CollectedHeapT::heap()->is_in(addr); if (in_heap) { - // base_oop_or_null() might be unimplemented and return NULL for some GCs/generations + // base_oop_or_null() might be unimplemented and return null for some GCs/generations oop o = base_oop_or_null(addr); if (o != nullptr) { if ((void*)o == addr) { diff --git a/src/hotspot/share/oops/constantPool.cpp b/src/hotspot/share/oops/constantPool.cpp index 73cc16bc122..015ec32700a 100644 --- a/src/hotspot/share/oops/constantPool.cpp +++ b/src/hotspot/share/oops/constantPool.cpp @@ -428,7 +428,7 @@ void ConstantPool::restore_unshareable_info(TRAPS) { assert(is_shared(), "should always be set for shared constant pools"); if (is_for_method_handle_intrinsic()) { // See the same check in remove_unshareable_info() below. - assert(cache() == NULL, "must not have cpCache"); + assert(cache() == nullptr, "must not have cpCache"); return; } assert(_cache != nullptr, "constant pool _cache should not be null"); @@ -474,7 +474,7 @@ void ConstantPool::remove_unshareable_info() { // This CP was created by Method::make_method_handle_intrinsic() and has nothing // that need to be removed/restored. It has no cpCache since the intrinsic methods // don't have any bytecodes. - assert(cache() == NULL, "must not have cpCache"); + assert(cache() == nullptr, "must not have cpCache"); return; } From 8f08020fa452b15709f68a702abb5edec191dee2 Mon Sep 17 00:00:00 2001 From: SendaoYan <syan@openjdk.org> Date: Mon, 25 Nov 2024 01:31:16 +0000 Subject: [PATCH 206/311] 8344903: Improve error handling TestJhsdbJstackPrintVMLocks.java Reviewed-by: lmesnik, dholmes --- .../jtreg/serviceability/sa/TestJhsdbJstackPrintVMLocks.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/test/hotspot/jtreg/serviceability/sa/TestJhsdbJstackPrintVMLocks.java b/test/hotspot/jtreg/serviceability/sa/TestJhsdbJstackPrintVMLocks.java index ff1cc4b96bd..e46306cf8d3 100644 --- a/test/hotspot/jtreg/serviceability/sa/TestJhsdbJstackPrintVMLocks.java +++ b/test/hotspot/jtreg/serviceability/sa/TestJhsdbJstackPrintVMLocks.java @@ -79,7 +79,10 @@ public static void main(String[] args) throws Exception { } throw new RuntimeException("Not able to find lock"); } finally { - theApp.getProcess().destroyForcibly(); + if (theApp.getProcess() != null) { + theApp.deleteLock(); + theApp.getProcess().destroyForcibly(); + } } } } From 6f622da7fbae67d8c1cd9e795127adac58a246a9 Mon Sep 17 00:00:00 2001 From: Phil Race <prr@openjdk.org> Date: Mon, 25 Nov 2024 03:33:17 +0000 Subject: [PATCH 207/311] 8344923: Problem list on java/awt/Robot/ScreenCaptureRobotTest.java on macOS Reviewed-by: dholmes --- test/jdk/ProblemList.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/test/jdk/ProblemList.txt b/test/jdk/ProblemList.txt index 90a6dc18e6d..63cfb2a338f 100644 --- a/test/jdk/ProblemList.txt +++ b/test/jdk/ProblemList.txt @@ -468,6 +468,7 @@ java/awt/Window/MainKeyWindowTest/TestMainKeyWindow.java 8265985 macosx-all java/awt/Robot/Delay/InterruptOfDelay.java 8265986 macosx-all java/awt/Robot/InfiniteLoopException.java 8342638 windows-all,linux-all java/awt/MenuBar/TestNoScreenMenuBar.java 8265987 macosx-all +java/awt/Robot/ScreenCaptureRobotTest.java 8344581 macosx-all java/awt/Graphics2D/DrawString/DrawRotatedStringUsingRotatedFont.java 8266283 generic-all java/awt/Graphics2D/DrawString/RotTransText.java 8316878 linux-all From 68ba7ee5c8f152a268b1e95d52417783346d12b7 Mon Sep 17 00:00:00 2001 From: Per Minborg <pminborg@openjdk.org> Date: Mon, 25 Nov 2024 07:42:57 +0000 Subject: [PATCH 208/311] 8340205: Native linker allows MemoryLayout consisting of only PaddingLayout Reviewed-by: jvernee, mcimadamore --- .../classes/java/lang/foreign/Linker.java | 56 ++++----- .../internal/foreign/abi/AbstractLinker.java | 71 +++++++++-- test/jdk/java/foreign/TestLinker.java | 115 +++++++++++++++++- 3 files changed, 191 insertions(+), 51 deletions(-) diff --git a/src/java.base/share/classes/java/lang/foreign/Linker.java b/src/java.base/share/classes/java/lang/foreign/Linker.java index 5474fef66da..bfa205e2fad 100644 --- a/src/java.base/share/classes/java/lang/foreign/Linker.java +++ b/src/java.base/share/classes/java/lang/foreign/Linker.java @@ -241,50 +241,40 @@ * </tbody> * </table></blockquote> * <p> - * All native linker implementations support a well-defined subset of layouts. More formally, - * a layout {@code L} is supported by a native linker {@code NL} if: + * A native linker only supports function descriptors whose argument/return layouts are + * <em>well-formed</em> layouts. More formally, a layout `L` is well-formed if: * <ul> - * <li>{@code L} is a value layout {@code V} and {@code V.withoutName()} is a canonical layout</li> + * <li>{@code L} is a value layout and {@code L} is derived from a canonical layout + * {@code C} such that {@code L.byteAlignment() <= C.byteAlignment()}</li> * <li>{@code L} is a sequence layout {@code S} and all the following conditions hold: * <ol> - * <li>the alignment constraint of {@code S} is set to its - * <a href="MemoryLayout.html#layout-align">natural alignment</a>, and</li> - * <li>{@code S.elementLayout()} is a layout supported by {@code NL}.</li> + * <li>{@code L.byteAlignment()} is equal to the sequence layout's <em>natural alignment</em> + * , and</li> + * <li>{@code S.elementLayout()} is a well-formed layout.</li> * </ol> * </li> * <li>{@code L} is a group layout {@code G} and all the following conditions hold: * <ol> - * <li>the alignment constraint of {@code G} is set to its - * <a href="MemoryLayout.html#layout-align">natural alignment</a>;</li> - * <li>the size of {@code G} is a multiple of its alignment constraint;</li> - * <li>each member layout in {@code G.memberLayouts()} is either a padding layout or - * a layout supported by {@code NL}, and</li> - * <li>{@code G} does not contain padding other than what is strictly required to align - * its non-padding layout elements, or to satisfy (2).</li> + * <li>{@code G.byteAlignment()} is equal to the group layout's <em>natural alignment</em></li> + * <li>{@code G.byteSize()} is a multiple of {@code G.byteAlignment()}</li> + * <li>Each member layout in {@code G.memberLayouts()} is either a padding layout or a + * well-formed layout</li> + * <li>Each non-padding member layout {@code E} in {@code G.memberLayouts()} follows an + * optional padding member layout, whose size is the minimum size required to + * align {@code E}</li> + * <li>{@code G} contains an optional trailing padding member layout, whose size is the + * minimum size that satisfies (2)</li> * </ol> * </li> * </ul> - * - * Linker implementations may optionally support additional layouts, such as - * <em>packed</em> struct layouts. A packed struct is a struct in which there is - * at least one member layout {@code L} that has an alignment constraint less strict - * than its natural alignment. This allows to avoid padding between member layouts, - * as well as avoiding padding at the end of the struct layout. For example: - - * {@snippet lang = java: - * // No padding between the 2 element layouts: - * MemoryLayout noFieldPadding = MemoryLayout.structLayout( - * ValueLayout.JAVA_INT, - * ValueLayout.JAVA_DOUBLE.withByteAlignment(4)); - * - * // No padding at the end of the struct: - * MemoryLayout noTrailingPadding = MemoryLayout.structLayout( - * ValueLayout.JAVA_DOUBLE.withByteAlignment(4), - * ValueLayout.JAVA_INT); - * } * <p> - * A native linker only supports function descriptors whose argument/return layouts are - * layouts supported by that linker and are not sequence layouts. + * A function descriptor is well-formed if its argument and return layouts are + * well-formed and are not sequence layouts. A native linker is guaranteed to reject + * function descriptors that are not well-formed. However, a native linker can still + * reject well-formed function descriptors, according to platform-specific rules. + * For example, some native linkers may reject <em>packed</em> struct layouts -- struct + * layouts whose member layouts feature relaxed alignment constraints, to avoid + * the insertion of additional padding. * * <h3 id="function-pointers">Function pointers</h3> * diff --git a/src/java.base/share/classes/jdk/internal/foreign/abi/AbstractLinker.java b/src/java.base/share/classes/jdk/internal/foreign/abi/AbstractLinker.java index 28391df7a0b..5b40ac17750 100644 --- a/src/java.base/share/classes/jdk/internal/foreign/abi/AbstractLinker.java +++ b/src/java.base/share/classes/jdk/internal/foreign/abi/AbstractLinker.java @@ -57,7 +57,6 @@ import java.lang.invoke.MethodType; import java.util.HashSet; import java.util.List; -import java.nio.ByteOrder; import java.util.Objects; import java.util.Set; @@ -189,6 +188,7 @@ private void checkLayoutRecursive(MemoryLayout layout) { checkHasNaturalAlignment(layout); long offset = 0; long lastUnpaddedOffset = 0; + PaddingLayout preceedingPadding = null; for (MemoryLayout member : sl.memberLayouts()) { // check element offset before recursing so that an error points at the // outermost layout first @@ -196,29 +196,65 @@ private void checkLayoutRecursive(MemoryLayout layout) { checkStructMember(member, offset); offset += member.byteSize(); - if (!(member instanceof PaddingLayout)) { + if (!(member instanceof PaddingLayout pl)) { lastUnpaddedOffset = offset; + if (preceedingPadding != null) { + preceedingPadding = null; + } + } else { + if (preceedingPadding != null) { + throw new IllegalArgumentException("The padding layout " + pl + + " was preceded by another padding layout " + preceedingPadding + + inMessage(sl)); + } + preceedingPadding = pl; } } - checkGroupSize(sl, lastUnpaddedOffset); + checkNotAllPadding(sl); + checkGroup(sl, lastUnpaddedOffset); } else if (layout instanceof UnionLayout ul) { checkHasNaturalAlignment(layout); - long maxUnpaddedLayout = 0; + // We need to know this up front + long maxUnpaddedLayout = ul.memberLayouts().stream() + .filter(l -> !(l instanceof PaddingLayout)) + .mapToLong(MemoryLayout::byteSize) + .max() + .orElse(0); + + boolean hasPadding = false; + for (MemoryLayout member : ul.memberLayouts()) { checkLayoutRecursive(member); - if (!(member instanceof PaddingLayout)) { - maxUnpaddedLayout = Long.max(maxUnpaddedLayout, member.byteSize()); + if (member instanceof PaddingLayout pl) { + if (hasPadding) { + throw new IllegalArgumentException("More than one padding" + inMessage(ul)); + } + hasPadding = true; + if (pl.byteSize() <= maxUnpaddedLayout) { + throw new IllegalArgumentException("Superfluous padding " + pl + inMessage(ul)); + } } } - checkGroupSize(ul, maxUnpaddedLayout); + checkGroup(ul, maxUnpaddedLayout); } else if (layout instanceof SequenceLayout sl) { checkHasNaturalAlignment(layout); + if (sl.elementLayout() instanceof PaddingLayout pl) { + throw memberException(sl, pl, + "not supported because a sequence of a padding layout is not allowed"); + } checkLayoutRecursive(sl.elementLayout()); } } - // check for trailing padding - private void checkGroupSize(GroupLayout gl, long maxUnpaddedOffset) { + // check elements are not all padding layouts + private static void checkNotAllPadding(StructLayout sl) { + if (!sl.memberLayouts().isEmpty() && sl.memberLayouts().stream().allMatch(e -> e instanceof PaddingLayout)) { + throw new IllegalArgumentException("Layout '" + sl + "' is non-empty and only has padding layouts"); + } + } + + // check trailing padding + private static void checkGroup(GroupLayout gl, long maxUnpaddedOffset) { long expectedSize = Utils.alignUp(maxUnpaddedOffset, gl.byteAlignment()); if (gl.byteSize() != expectedSize) { throw new IllegalArgumentException("Layout '" + gl + "' has unexpected size: " @@ -226,17 +262,28 @@ private void checkGroupSize(GroupLayout gl, long maxUnpaddedOffset) { } } + private static String inMessage(GroupLayout gl) { + return " in " + gl; + } + // checks both that there is no excess padding between 'memberLayout' and // the previous layout - private void checkMemberOffset(StructLayout parent, MemoryLayout memberLayout, + private static void checkMemberOffset(StructLayout parent, MemoryLayout memberLayout, long lastUnpaddedOffset, long offset) { long expectedOffset = Utils.alignUp(lastUnpaddedOffset, memberLayout.byteAlignment()); if (expectedOffset != offset) { - throw new IllegalArgumentException("Member layout '" + memberLayout + "', of '" + parent + "'" + - " found at unexpected offset: " + offset + " != " + expectedOffset); + throw memberException(parent, memberLayout, + "found at unexpected offset: " + offset + " != " + expectedOffset); } } + private static IllegalArgumentException memberException(MemoryLayout parent, + MemoryLayout member, + String info) { + return new IllegalArgumentException( + "Member layout '" + member + "', of '" + parent + "' " + info); + } + private void checkSupported(ValueLayout valueLayout) { valueLayout = valueLayout.withoutName(); if (valueLayout instanceof AddressLayout addressLayout) { diff --git a/test/jdk/java/foreign/TestLinker.java b/test/jdk/java/foreign/TestLinker.java index 82d58300088..4bc19965f19 100644 --- a/test/jdk/java/foreign/TestLinker.java +++ b/test/jdk/java/foreign/TestLinker.java @@ -35,6 +35,9 @@ import java.lang.foreign.FunctionDescriptor; import java.lang.foreign.Linker; import java.lang.foreign.MemoryLayout; +import java.lang.foreign.PaddingLayout; +import java.lang.foreign.SequenceLayout; +import java.lang.foreign.StructLayout; import java.lang.foreign.ValueLayout; import java.lang.invoke.MethodHandle; import java.util.ArrayList; @@ -42,12 +45,8 @@ import java.util.List; import static java.lang.foreign.MemoryLayout.*; -import static java.lang.foreign.ValueLayout.JAVA_CHAR; -import static java.lang.foreign.ValueLayout.JAVA_SHORT; -import static org.testng.Assert.assertNotNull; -import static org.testng.Assert.assertSame; -import static org.testng.Assert.assertNotSame; -import static org.testng.Assert.assertTrue; +import static java.lang.foreign.ValueLayout.*; +import static org.testng.Assert.*; public class TestLinker extends NativeTestHelper { @@ -150,6 +149,110 @@ public void testCanonicalLayouts(String typeName) { assertTrue(layout instanceof ValueLayout); } + @Test + public void embeddedPaddingLayout() { + PaddingLayout padding = MemoryLayout.paddingLayout(64).withByteAlignment(64); + SequenceLayout sequence = MemoryLayout.sequenceLayout(2, padding); + StructLayout struct = MemoryLayout.structLayout(sequence); + FunctionDescriptor fd = FunctionDescriptor.of(struct, struct); + Linker linker = Linker.nativeLinker(); + var x = expectThrows(IllegalArgumentException.class, () -> linker.downcallHandle(fd)); + assertTrue(x.getMessage().contains("not supported because a sequence of a padding layout is not allowed")); + } + + @Test + public void groupLayoutWithOnlyPadding() { + PaddingLayout padding = MemoryLayout.paddingLayout(1); + StructLayout struct = MemoryLayout.structLayout(padding); + FunctionDescriptor fd = FunctionDescriptor.of(struct, struct); + Linker linker = Linker.nativeLinker(); + var x = expectThrows(IllegalArgumentException.class, () -> linker.downcallHandle(fd)); + assertTrue(x.getMessage().contains("is non-empty and only has padding layouts")); + } + + @Test + public void interwovenPadding() { + Linker linker = Linker.nativeLinker(); + var padding1 = MemoryLayout.paddingLayout(1); + var padding2 = MemoryLayout.paddingLayout(2).withByteAlignment(2); + + var struct = MemoryLayout.structLayout(JAVA_BYTE, padding1, padding2, JAVA_INT); + + var fd = FunctionDescriptor.of(struct, struct, struct); + var e = expectThrows(IllegalArgumentException.class, () -> linker.downcallHandle(fd)); + assertEquals(e.getMessage(), + "The padding layout x2 was preceded by another padding layout x1 in [b1x1x2i4]"); + } + + @Test + public void stackedPadding() { + Linker linker = Linker.nativeLinker(); + var struct32 = MemoryLayout.structLayout(MemoryLayout.sequenceLayout(4, JAVA_LONG)); + var padding1 = MemoryLayout.paddingLayout(1); + var padding2 = MemoryLayout.paddingLayout(2).withByteAlignment(2); + var padding4 = MemoryLayout.paddingLayout(4).withByteAlignment(4); + var padding8 = MemoryLayout.paddingLayout(8).withByteAlignment(8); + var padding16 = MemoryLayout.paddingLayout(16).withByteAlignment(16); + var padding32 = MemoryLayout.paddingLayout(32).withByteAlignment(32); + var union = MemoryLayout.unionLayout(struct32, padding32); + var struct = MemoryLayout.structLayout(JAVA_BYTE, padding1, padding2, padding4, padding8, padding16, union); + var fd = FunctionDescriptor.of(struct, struct, struct); + var e = expectThrows(IllegalArgumentException.class, () -> linker.downcallHandle(fd)); + assertEquals(e.getMessage(), + "The padding layout x2 was preceded by another padding layout x1 in [b1x1x2x4x8x16[[[4:j8]]|x32]]"); + } + + @Test + public void paddingUnionByteSize3() { + Linker linker = Linker.nativeLinker(); + var union = MemoryLayout.unionLayout(MemoryLayout.paddingLayout(3), ValueLayout.JAVA_INT); + var fd = FunctionDescriptor.of(union, union, union); + var e = expectThrows(IllegalArgumentException.class, () -> linker.downcallHandle(fd)); + assertEquals(e.getMessage(), "Superfluous padding x3 in [x3|i4]"); + } + + @Test + public void paddingUnionByteSize4() { + Linker linker = Linker.nativeLinker(); + var union = MemoryLayout.unionLayout(MemoryLayout.paddingLayout(4), ValueLayout.JAVA_INT); + var fd = FunctionDescriptor.of(union, union, union); + var e = expectThrows(IllegalArgumentException.class, () -> linker.downcallHandle(fd)); + assertEquals(e.getMessage(), "Superfluous padding x4 in [x4|i4]"); + } + + @Test + public void paddingUnionByteSize5() { + Linker linker = Linker.nativeLinker(); + var union = MemoryLayout.unionLayout(MemoryLayout.paddingLayout(5), ValueLayout.JAVA_INT); + var fd = FunctionDescriptor.of(union, union, union); + var e = expectThrows(IllegalArgumentException.class, () -> linker.downcallHandle(fd)); + assertEquals(e.getMessage(), "Layout '[x5|i4]' has unexpected size: 5 != 4"); + } + + @Test + public void paddingUnionSeveral() { + Linker linker = Linker.nativeLinker(); + var union = MemoryLayout.unionLayout( + MemoryLayout.sequenceLayout(3, ValueLayout.JAVA_INT), + ValueLayout.JAVA_LONG, + MemoryLayout.paddingLayout(16), + MemoryLayout.paddingLayout(16)); + var fd = FunctionDescriptor.of(union, union, union); + var e = expectThrows(IllegalArgumentException.class, () -> linker.downcallHandle(fd)); + assertEquals(e.getMessage(), "More than one padding in [[3:i4]|j8|x16|x16]"); + } + + @Test + public void sequenceOfZeroElements() { + Linker linker = Linker.nativeLinker(); + var sequence0a8 = MemoryLayout.sequenceLayout(0, JAVA_LONG); + var sequence3a1 = MemoryLayout.sequenceLayout(3, JAVA_BYTE); + var padding5a1 = MemoryLayout.paddingLayout(5); + var struct8a8 = MemoryLayout.structLayout(sequence0a8, sequence3a1, padding5a1); + var fd = FunctionDescriptor.of(struct8a8, struct8a8, struct8a8); + linker.downcallHandle(fd); + } + @DataProvider public static Object[][] canonicalTypeNames() { return new Object[][]{ From 9576546b9c0f22b0784c4f845f2694050cae2f16 Mon Sep 17 00:00:00 2001 From: Matthias Baesken <mbaesken@openjdk.org> Date: Mon, 25 Nov 2024 07:57:13 +0000 Subject: [PATCH 209/311] 8343698: Linux x86_64 lto build gives a lot of warnings and fails lto-wrapper: fatal error: make returned 2 exit status Reviewed-by: ihse, jwaters --- make/hotspot/lib/JvmOverrideFiles.gmk | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/make/hotspot/lib/JvmOverrideFiles.gmk b/make/hotspot/lib/JvmOverrideFiles.gmk index 63169b4d672..6a513e10c61 100644 --- a/make/hotspot/lib/JvmOverrideFiles.gmk +++ b/make/hotspot/lib/JvmOverrideFiles.gmk @@ -37,6 +37,10 @@ ifeq ($(TOOLCHAIN_TYPE), gcc) # Need extra inlining to collapse shared marking code into the hot marking loop BUILD_LIBJVM_shenandoahMark.cpp_CXXFLAGS := --param inline-unit-growth=1000 endif + # disable lto in g1ParScanThreadState because of special inlining/flattening used there + ifeq ($(call check-jvm-feature, link-time-opt), true) + BUILD_LIBJVM_g1ParScanThreadState.cpp_CXXFLAGS := -fno-lto + endif endif LIBJVM_FDLIBM_COPY_OPT_FLAG := $(CXX_O_FLAG_NONE) From 333a9973f1e99faa665e96c30bcfac7877cbdc1c Mon Sep 17 00:00:00 2001 From: Prasanta Sadhukhan <psadhukhan@openjdk.org> Date: Mon, 25 Nov 2024 08:57:54 +0000 Subject: [PATCH 210/311] 8335231: [macos] Test java/awt/print/PrinterJob/Cancel/PrinterJobCancel.java failed on macOS because the case didn't get the expected PrintAbortException Reviewed-by: tr, abhiscxk --- .../classes/sun/lwawt/macosx/CPrinterJob.java | 27 ++++++++++++------- .../native/libawt_lwawt/awt/PrinterView.m | 19 ++++++++++--- .../PrinterJob/Cancel/PrinterJobCancel.java | 2 +- 3 files changed, 33 insertions(+), 15 deletions(-) diff --git a/src/java.desktop/macosx/classes/sun/lwawt/macosx/CPrinterJob.java b/src/java.desktop/macosx/classes/sun/lwawt/macosx/CPrinterJob.java index cbb39e24c1a..95cca2d3ea8 100644 --- a/src/java.desktop/macosx/classes/sun/lwawt/macosx/CPrinterJob.java +++ b/src/java.desktop/macosx/classes/sun/lwawt/macosx/CPrinterJob.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -71,6 +71,8 @@ public final class CPrinterJob extends RasterPrinterJob { private String outputBin = null; + private Throwable printerAbortExcpn; + // This is the NSPrintInfo for this PrinterJob. Protect multi thread // access to it. It is used by the pageDialog, jobDialog, and printLoop. // This way the state of these items is shared across these calls. @@ -245,7 +247,7 @@ protected void cancelDoc() throws PrinterAbortException { } } - private void completePrintLoop() { + private void completePrintLoop(Throwable excpn) { Runnable r = new Runnable() { public void run() { synchronized(this) { performingPrinting = false; @@ -255,6 +257,10 @@ private void completePrintLoop() { } }}; + if (excpn != null && excpn.toString().contains("PrinterAbortException")) { + printerAbortExcpn = excpn; + } + if (onEventThread) { try { EventQueue.invokeAndWait(r); } catch (Exception e) { e.printStackTrace(); } } else { @@ -364,6 +370,9 @@ public void print(PrintRequestAttributeSet attributes) throws PrinterException { } catch (Exception e) { e.printStackTrace(); } + if (printerAbortExcpn != null) { + throw (PrinterAbortException) printerAbortExcpn; + } } if (++loopi < prMembers.length) { firstPage = prMembers[loopi][0]-1; @@ -741,15 +750,13 @@ private boolean cancelCheck() { // but that will block the AppKit thread against whomever is holding the synchronized lock boolean cancelled = (performingPrinting && userCancelled); if (cancelled) { - try { - LWCToolkit.invokeLater(new Runnable() { public void run() { - try { + EventQueue.invokeLater(() -> { + try { cancelDoc(); - } catch (PrinterAbortException pae) { - // no-op, let the native side handle it - } - }}, null); - } catch (java.lang.reflect.InvocationTargetException ite) {} + } catch (PrinterAbortException pae) { + // no-op, let the native side handle it + } + }); } return cancelled; } diff --git a/src/java.desktop/macosx/native/libawt_lwawt/awt/PrinterView.m b/src/java.desktop/macosx/native/libawt_lwawt/awt/PrinterView.m index 17feca9fd7e..f39ca25a08f 100644 --- a/src/java.desktop/macosx/native/libawt_lwawt/awt/PrinterView.m +++ b/src/java.desktop/macosx/native/libawt_lwawt/awt/PrinterView.m @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -33,8 +33,10 @@ #import "JNIUtilities.h" static jclass sjc_CPrinterJob = NULL; +static jclass sjc_PAbortEx = NULL; #define GET_CPRINTERJOB_CLASS() (sjc_CPrinterJob, "sun/lwawt/macosx/CPrinterJob"); #define GET_CPRINTERJOB_CLASS_RETURN(ret) GET_CLASS_RETURN(sjc_CPrinterJob, "sun/lwawt/macosx/CPrinterJob", ret); +#define GET_PRINERABORTEXCEPTION_CLASS(ret) GET_CLASS_RETURN(sjc_PAbortEx, "java/awt/print/PrinterAbortException", ret); @implementation PrinterView @@ -260,7 +262,12 @@ - (BOOL)cancelCheck:(JNIEnv*)env DECLARE_METHOD_RETURN(jm_cancelCheck, sjc_CPrinterJob, "cancelCheck", "()Z", NO); BOOL b = (*env)->CallBooleanMethod(env, fPrinterJob, jm_cancelCheck); // AWT_THREADING Safe (known object) - CHECK_EXCEPTION(); + if (b) { + GET_PRINERABORTEXCEPTION_CLASS(b); + (*env)->ThrowNew(env, sjc_PAbortEx, "Printer Job cancelled"); + } else { + CHECK_EXCEPTION(); + } return b; } @@ -269,8 +276,12 @@ - (void)complete:(JNIEnv*)env { AWT_ASSERT_NOT_APPKIT_THREAD; - DECLARE_METHOD(jf_completePrintLoop, sjc_CPrinterJob, "completePrintLoop", "()V"); - (*env)->CallVoidMethod(env, fPrinterJob, jf_completePrintLoop); + jthrowable excpn = (*env)->ExceptionOccurred(env); + if (excpn != NULL) { + (*env)->ExceptionClear(env); + } + DECLARE_METHOD(jf_completePrintLoop, sjc_CPrinterJob, "completePrintLoop", "(Ljava/lang/Throwable;)V"); + (*env)->CallVoidMethod(env, fPrinterJob, jf_completePrintLoop, excpn); CHECK_EXCEPTION(); // Clean up after ourselves diff --git a/test/jdk/java/awt/print/PrinterJob/Cancel/PrinterJobCancel.java b/test/jdk/java/awt/print/PrinterJob/Cancel/PrinterJobCancel.java index a55e0eeb999..7735053b0f0 100644 --- a/test/jdk/java/awt/print/PrinterJob/Cancel/PrinterJobCancel.java +++ b/test/jdk/java/awt/print/PrinterJob/Cancel/PrinterJobCancel.java @@ -32,7 +32,7 @@ /* * @test - * @bug 4245280 + * @bug 4245280 8335231 * @key printer * @summary PrinterJob not cancelled when PrinterJob.cancel() is used * @library /java/awt/regtesthelpers From da4b7a8c56f56c6051d463bc34e51e35781fe1a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20L=C3=B6vdahl?= <sebastian.lovdahl@hibox.tv> Date: Mon, 25 Nov 2024 09:13:10 +0000 Subject: [PATCH 211/311] 8341436: containers/docker/TestJcmdWithSideCar.java takes needlessly long to run Reviewed-by: kevinw, lmesnik --- .../containers/docker/EventGeneratorLoop.java | 13 +++- .../docker/TestJcmdWithSideCar.java | 69 +++++++++---------- .../containers/docker/DockerTestUtils.java | 2 +- 3 files changed, 45 insertions(+), 39 deletions(-) diff --git a/test/hotspot/jtreg/containers/docker/EventGeneratorLoop.java b/test/hotspot/jtreg/containers/docker/EventGeneratorLoop.java index de7605b4457..efb1690ea75 100644 --- a/test/hotspot/jtreg/containers/docker/EventGeneratorLoop.java +++ b/test/hotspot/jtreg/containers/docker/EventGeneratorLoop.java @@ -24,6 +24,8 @@ import jdk.jfr.Description; import jdk.jfr.Label; +import java.util.concurrent.TimeUnit; + // This class generates simple event in a loop for a specified time. public class EventGeneratorLoop { @@ -44,16 +46,21 @@ public static void main(String[] args) throws Exception { throw new IllegalArgumentException("Expecting one argument: time to run (seconds)"); } int howLong = Integer.parseInt(args[0]); + long endTime = System.nanoTime() + TimeUnit.SECONDS.toNanos(howLong); System.out.println(MAIN_METHOD_STARTED + ", argument is " + howLong); - for (int i=0; i < howLong; i++) { + int count = 0; + while (System.nanoTime() < endTime) { SimpleEvent ev = new SimpleEvent(); ev.msg = "Hello"; - ev.count = i; + ev.count = count++; ev.commit(); - try { Thread.sleep(1000); } catch (InterruptedException e) {} + try { + Thread.sleep(1000); + } catch (InterruptedException ignore) { + } System.out.print("."); } diff --git a/test/hotspot/jtreg/containers/docker/TestJcmdWithSideCar.java b/test/hotspot/jtreg/containers/docker/TestJcmdWithSideCar.java index de27f4d24e2..9feeda6f4ad 100644 --- a/test/hotspot/jtreg/containers/docker/TestJcmdWithSideCar.java +++ b/test/hotspot/jtreg/containers/docker/TestJcmdWithSideCar.java @@ -48,10 +48,10 @@ import java.util.EnumSet; import java.util.List; import java.util.Optional; +import java.util.Random; import java.util.concurrent.TimeUnit; import java.util.function.Consumer; import java.util.regex.Pattern; -import java.util.stream.Collectors; import jdk.test.lib.Container; import jdk.test.lib.Platform; @@ -67,7 +67,6 @@ public class TestJcmdWithSideCar { private static final String IMAGE_NAME = Common.imageName("jfr-jcmd"); private static final int TIME_TO_RUN_MAIN_PROCESS = (int) (30 * Utils.TIMEOUT_FACTOR); // seconds private static final long TIME_TO_WAIT_FOR_MAIN_METHOD_START = 50 * 1000; // milliseconds - private static final String MAIN_CONTAINER_NAME = "test-container-main"; private static final String UID = "uid"; private static final String GID = "gid"; @@ -115,19 +114,19 @@ public static void main(String[] args) throws Exception { // Elevated attach via proc/root not yet supported. continue; } - long mainProcPid = testCase01(attachStrategy, elevated); + long mainProcPid = testCase01(mainContainer, attachStrategy, elevated); // Excluding the test case below until JDK-8228850 is fixed // JDK-8228850: jhsdb jinfo fails with ClassCastException: // s.j.h.oops.TypeArray cannot be cast to s.j.h.oops.Instance // mainContainer.assertIsAlive(); - // testCase02(mainProcPid, attachStrategy, elevated); + // testCase02(mainContainer, mainProcPid, attachStrategy, elevated); mainContainer.assertIsAlive(); - testCase03(mainProcPid, attachStrategy, elevated); + testCase03(mainContainer, mainProcPid, attachStrategy, elevated); } - mainContainer.waitForAndCheck(TIME_TO_RUN_MAIN_PROCESS * 1000); + mainContainer.stop(); } } finally { DockerTestUtils.removeDockerImage(IMAGE_NAME); @@ -136,8 +135,8 @@ public static void main(String[] args) throws Exception { // Run "jcmd -l" in a sidecar container, find a target process. - private static long testCase01(AttachStrategy attachStrategy, boolean elevated) throws Exception { - OutputAnalyzer out = runSideCar(MAIN_CONTAINER_NAME, attachStrategy, elevated, "/jdk/bin/jcmd", "-l") + private static long testCase01(MainContainer mainContainer, AttachStrategy attachStrategy, boolean elevated) throws Exception { + OutputAnalyzer out = runSideCar(mainContainer, attachStrategy, elevated, "/jdk/bin/jcmd", "-l") .shouldHaveExitValue(0) .shouldContain("sun.tools.jcmd.JCmd"); long pid = findProcess(out, "EventGeneratorLoop"); @@ -149,8 +148,8 @@ private static long testCase01(AttachStrategy attachStrategy, boolean elevated) } // run jhsdb jinfo <PID> (jhsdb uses PTRACE) - private static void testCase02(long pid, AttachStrategy attachStrategy, boolean elevated) throws Exception { - runSideCar(MAIN_CONTAINER_NAME, attachStrategy, elevated, "/jdk/bin/jhsdb", "jinfo", "--pid", "" + pid) + private static void testCase02(MainContainer mainContainer, long pid, AttachStrategy attachStrategy, boolean elevated) throws Exception { + runSideCar(mainContainer, attachStrategy, elevated, "/jdk/bin/jhsdb", "jinfo", "--pid", "" + pid) .shouldHaveExitValue(0) .shouldContain("Java System Properties") .shouldContain("VM Flags"); @@ -158,11 +157,11 @@ private static void testCase02(long pid, AttachStrategy attachStrategy, boolean // test jcmd with some commands (help, start JFR recording) // JCMD will use signal mechanism and Unix Socket - private static void testCase03(long pid, AttachStrategy attachStrategy, boolean elevated) throws Exception { - runSideCar(MAIN_CONTAINER_NAME, attachStrategy, elevated, "/jdk/bin/jcmd", "" + pid, "help") + private static void testCase03(MainContainer mainContainer, long pid, AttachStrategy attachStrategy, boolean elevated) throws Exception { + runSideCar(mainContainer, attachStrategy, elevated, "/jdk/bin/jcmd", "" + pid, "help") .shouldHaveExitValue(0) .shouldContain("VM.version"); - runSideCar(MAIN_CONTAINER_NAME, attachStrategy, elevated, "/jdk/bin/jcmd", "" + pid, "JFR.start") + runSideCar(mainContainer, attachStrategy, elevated, "/jdk/bin/jcmd", "" + pid, "JFR.start") .shouldHaveExitValue(0) .shouldContain("Started recording"); } @@ -174,18 +173,18 @@ private static void testCase03(long pid, AttachStrategy attachStrategy, boolean // we have two options: // 1. mount /tmp from the main container using --volumes-from. // 2. access /tmp from the main container via /proc/<pid>/root/tmp. - private static OutputAnalyzer runSideCar(String mainContainerName, AttachStrategy attachStrategy, boolean elevated, String whatToRun, String... args) throws Exception { + private static OutputAnalyzer runSideCar(MainContainer mainContainer, AttachStrategy attachStrategy, boolean elevated, String whatToRun, String... args) throws Exception { System.out.println("Attach strategy " + attachStrategy); List<String> initialCommands = List.of( Container.ENGINE_COMMAND, "run", "--tty=true", "--rm", "--cap-add=SYS_PTRACE", "--sig-proxy=true", - "--pid=container:" + mainContainerName + "--pid=container:" + mainContainer.name() ); List<String> attachStrategyCommands = switch (attachStrategy) { - case TMP_MOUNTED_INTO_SIDECAR -> List.of("--volumes-from", mainContainerName); + case TMP_MOUNTED_INTO_SIDECAR -> List.of("--volumes-from", mainContainer.name()); case ACCESS_TMP_VIA_PROC_ROOT -> List.of(); }; @@ -209,11 +208,11 @@ private static long findProcess(OutputAnalyzer out, String name) throws Exceptio List<String> l = out.asLines() .stream() .filter(s -> s.contains(name)) - .collect(Collectors.toList()); + .toList(); if (l.isEmpty()) { return -1; } - String psInfo = l.get(0); + String psInfo = l.getFirst(); System.out.println("findProcess(): psInfo: " + psInfo); String pid = psInfo.substring(0, psInfo.indexOf(' ')); System.out.println("findProcess(): pid: " + pid); @@ -236,6 +235,10 @@ private static void sleep(long delay) { static class MainContainer { + private static final String MAIN_CONTAINER_NAME_PREFIX = "test-container-main"; + private static final Random RANDOM = Utils.getRandomInstance(); + + String name; boolean mainMethodStarted; Process p; @@ -255,8 +258,11 @@ public Process start(final boolean elevated) throws Exception { opts.addDockerOpts(NET_BIND_SERVICE); } + name = MAIN_CONTAINER_NAME_PREFIX + "-elevated-" + elevated + "-" + RANDOM.nextInt(); + opts.addDockerOpts("--cap-add=SYS_PTRACE") - .addDockerOpts("--name", MAIN_CONTAINER_NAME) + .addDockerOpts("--init") + .addDockerOpts("--name", name) .addDockerOpts("--volume", "/tmp") .addDockerOpts("--volume", Paths.get(".").toAbsolutePath() + ":/workdir/") .addJavaOpts("-XX:+UsePerfData") @@ -296,25 +302,18 @@ public void waitFor(long timeout) throws Exception { p.waitFor(timeout, TimeUnit.MILLISECONDS); } - public void waitForAndCheck(long timeout) throws Exception { - int exitValue = -1; - int retryCount = 3; - - do { - waitFor(timeout); - try { - exitValue = p.exitValue(); - } catch(IllegalThreadStateException ex) { - System.out.println("IllegalThreadStateException occurred when calling exitValue()"); - retryCount--; - } - } while (exitValue == -1 && retryCount > 0); - - if (exitValue != 0) { - throw new RuntimeException("DockerThread stopped unexpectedly, non-zero exit value is " + exitValue); + public void stop() throws Exception { + OutputAnalyzer out = DockerTestUtils.execute(Container.ENGINE_COMMAND, "ps") + .shouldHaveExitValue(0); + if (out.contains(name)) { + DockerTestUtils.execute(Container.ENGINE_COMMAND, "stop", name) + .shouldHaveExitValue(0); } } + public String name() { + return name; + } } private enum AttachStrategy { diff --git a/test/lib/jdk/test/lib/containers/docker/DockerTestUtils.java b/test/lib/jdk/test/lib/containers/docker/DockerTestUtils.java index 4a8915d4631..d459e4b2818 100644 --- a/test/lib/jdk/test/lib/containers/docker/DockerTestUtils.java +++ b/test/lib/jdk/test/lib/containers/docker/DockerTestUtils.java @@ -289,7 +289,7 @@ public static OutputAnalyzer execute(String... command) throws Exception { System.out.println("[ELAPSED: " + (System.currentTimeMillis() - started) + " ms]"); System.out.println("[STDERR]\n" + output.getStderr()); System.out.println("[STDOUT]\n" + stdoutLimited); - if (stdout != stdoutLimited) { + if (!stdout.equals(stdoutLimited)) { System.out.printf("Child process STDOUT is limited to %d lines\n", max); } From d112f35d92a5b5f3e0248fa0fb447fc8c14da2d4 Mon Sep 17 00:00:00 2001 From: Daniel Fuchs <dfuchs@openjdk.org> Date: Mon, 25 Nov 2024 09:56:07 +0000 Subject: [PATCH 212/311] 8344855: Remove calls to SecurityManager and doPrivileged in HTTP related implementation classes in the sun.net and sun.net.www.http packages after JEP 486 integration Reviewed-by: jpai --- .../share/classes/sun/net/NetProperties.java | 28 ++------- .../share/classes/sun/net/NetworkClient.java | 49 +++++----------- .../classes/sun/net/www/http/HttpCapture.java | 11 +--- .../classes/sun/net/www/http/HttpClient.java | 58 +++++-------------- .../sun/net/www/http/KeepAliveCache.java | 26 ++------- .../sun/net/www/http/KeepAliveStream.java | 16 ++--- .../net/www/http/KeepAliveStreamCleaner.java | 28 +++------ 7 files changed, 51 insertions(+), 165 deletions(-) diff --git a/src/java.base/share/classes/sun/net/NetProperties.java b/src/java.base/share/classes/sun/net/NetProperties.java index eb4fec2d8ad..c0a20c4a19f 100644 --- a/src/java.base/share/classes/sun/net/NetProperties.java +++ b/src/java.base/share/classes/sun/net/NetProperties.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -27,8 +27,6 @@ import jdk.internal.util.StaticProperty; import java.io.*; -import java.security.AccessController; -import java.security.PrivilegedAction; import java.util.Properties; /* @@ -39,18 +37,8 @@ * @author Jean-Christophe Collet * */ - -@SuppressWarnings("removal") public class NetProperties { - private static Properties props = new Properties(); - static { - AccessController.doPrivileged( - new PrivilegedAction<Void>() { - public Void run() { - loadDefaultProperties(); - return null; - }}); - } + private static final Properties props = loadDefaultProperties(new Properties()); private NetProperties() { }; @@ -59,7 +47,7 @@ public Void run() { * Loads the default networking system properties * the file is in jre/lib/net.properties */ - private static void loadDefaultProperties() { + private static Properties loadDefaultProperties(Properties props) { String fname = StaticProperty.javaHome(); if (fname == null) { throw new Error("Can't find java.home ??"); @@ -75,6 +63,7 @@ private static void loadDefaultProperties() { // Do nothing. We couldn't find or access the file // so we won't have default properties... } + return props; } /** @@ -82,9 +71,6 @@ private static void loadDefaultProperties() { * returns the default value, if it exists, otherwise returns * <code>null</code>. * @param key the property name. - * @throws SecurityException if a security manager exists and its - * <code>checkPropertiesAccess</code> method doesn't allow access - * to the system properties. * @return the <code>String</code> value for the property, * or <code>null</code> */ @@ -103,9 +89,6 @@ public static String get(String key) { * <code>null</code>. * @param key the property name. * @param defval the default value to use if the property is not found - * @throws SecurityException if a security manager exists and its - * <code>checkPropertiesAccess</code> method doesn't allow access - * to the system properties. * @return the <code>Integer</code> value for the property, * or <code>null</code> */ @@ -131,9 +114,6 @@ public static Integer getInteger(String key, int defval) { * defined returns the default value, if it exists, otherwise returns * <code>null</code>. * @param key the property name. - * @throws SecurityException if a security manager exists and its - * <code>checkPropertiesAccess</code> method doesn't allow access - * to the system properties. * @return the <code>Boolean</code> value for the property, * or <code>null</code> */ diff --git a/src/java.base/share/classes/sun/net/NetworkClient.java b/src/java.base/share/classes/sun/net/NetworkClient.java index 94cf05e60fb..4f6ec73660d 100644 --- a/src/java.base/share/classes/sun/net/NetworkClient.java +++ b/src/java.base/share/classes/sun/net/NetworkClient.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1994, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1994, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -28,18 +28,14 @@ import java.net.Socket; import java.net.InetAddress; import java.net.InetSocketAddress; -import java.net.UnknownHostException; import java.net.Proxy; import java.util.Arrays; -import java.security.AccessController; -import java.security.PrivilegedAction; /** * This is the base class for network clients. * * @author Jonathan Payne */ -@SuppressWarnings("removal") public class NetworkClient { /* Default value of read timeout, if not specified (infinity) */ public static final int DEFAULT_READ_TIMEOUT = -1; @@ -66,26 +62,17 @@ public class NetworkClient { protected static String encoding; static { - final int vals[] = {0, 0}; - final String encs[] = { null }; - - AccessController.doPrivileged( - new PrivilegedAction<>() { - public Void run() { - vals[0] = Integer.getInteger("sun.net.client.defaultReadTimeout", 0).intValue(); - vals[1] = Integer.getInteger("sun.net.client.defaultConnectTimeout", 0).intValue(); - encs[0] = System.getProperty("file.encoding", "ISO8859_1"); - return null; - } - }); - if (vals[0] != 0) { - defaultSoTimeout = vals[0]; + int soTimeout = Integer.getInteger("sun.net.client.defaultReadTimeout", 0); + if (soTimeout != 0) { + defaultSoTimeout = soTimeout; } - if (vals[1] != 0) { - defaultConnectTimeout = vals[1]; + + int connTimeout = Integer.getInteger("sun.net.client.defaultConnectTimeout", 0); + if (connTimeout != 0) { + defaultConnectTimeout = connTimeout; } - encoding = encs[0]; + encoding = System.getProperty("file.encoding", "ISO8859_1"); try { if (!isASCIISuperset (encoding)) { encoding = "ISO8859_1"; @@ -131,7 +118,7 @@ private static boolean isASCIISuperset (String encoding) throws Exception { /** Open a connection to the server. */ public void openServer(String server, int port) - throws IOException, UnknownHostException { + throws IOException { if (serverSocket != null) closeServer(); serverSocket = doConnect (server, port); @@ -150,15 +137,11 @@ public void openServer(String server, int port) * appropriate options pre-established */ protected Socket doConnect (String server, int port) - throws IOException, UnknownHostException { + throws IOException { Socket s; if (proxy != null) { if (proxy.type() == Proxy.Type.SOCKS) { - s = AccessController.doPrivileged( - new PrivilegedAction<>() { - public Socket run() { - return new Socket(proxy); - }}); + s = new Socket(proxy); } else if (proxy.type() == Proxy.Type.DIRECT) { s = createSocket(); } else { @@ -203,13 +186,7 @@ protected Socket createSocket() throws IOException { protected InetAddress getLocalAddress() throws IOException { if (serverSocket == null) throw new IOException("not connected"); - return AccessController.doPrivileged( - new PrivilegedAction<>() { - public InetAddress run() { - return serverSocket.getLocalAddress(); - - } - }); + return serverSocket.getLocalAddress(); } /** Close an open connection to the server. */ diff --git a/src/java.base/share/classes/sun/net/www/http/HttpCapture.java b/src/java.base/share/classes/sun/net/www/http/HttpCapture.java index ba7e5af6cdf..7d0254e24f6 100644 --- a/src/java.base/share/classes/sun/net/www/http/HttpCapture.java +++ b/src/java.base/share/classes/sun/net/www/http/HttpCapture.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -65,13 +65,8 @@ public class HttpCapture { private static synchronized void init() { initialized = true; - @SuppressWarnings("removal") - String rulesFile = java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction<>() { - public String run() { - return NetProperties.get("sun.net.http.captureRules"); - } - }); + + String rulesFile = NetProperties.get("sun.net.http.captureRules"); if (rulesFile != null && !rulesFile.isEmpty()) { BufferedReader in; try { diff --git a/src/java.base/share/classes/sun/net/www/http/HttpClient.java b/src/java.base/share/classes/sun/net/www/http/HttpClient.java index 01c341401d8..1ab7396ad06 100644 --- a/src/java.base/share/classes/sun/net/www/http/HttpClient.java +++ b/src/java.base/share/classes/sun/net/www/http/HttpClient.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1994, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1994, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -42,7 +42,6 @@ import sun.net.www.protocol.http.HttpURLConnection; import sun.util.logging.PlatformLogger; import static sun.net.www.protocol.http.HttpURLConnection.TunnelState.*; -import sun.security.action.GetPropertyAction; /** * @author Herb Jellinek @@ -70,10 +69,10 @@ public class HttpClient extends NetworkClient { /** Response code for CONTINUE */ private boolean ignoreContinue = true; - private static final int HTTP_CONTINUE = 100; + private static final int HTTP_CONTINUE = 100; /** Default port number for http daemons. REMIND: make these private */ - static final int httpPortNumber = 80; + static final int httpPortNumber = 80; /** return default port number (subclasses may override) */ protected int getDefaultPort () { return httpPortNumber; } @@ -194,7 +193,7 @@ static String normalizeCBT(String s) { } static { - Properties props = GetPropertyAction.privilegedGetProperties(); + Properties props = System.getProperties(); String keepAlive = props.getProperty("http.keepAlive"); String retryPost = props.getProperty("sun.net.http.retryPost"); String cacheNTLM = props.getProperty("jdk.ntlm.cache"); @@ -243,11 +242,6 @@ public String getSpnegoCBT() { protected HttpClient() { } - private HttpClient(URL url) - throws IOException { - this(url, (String)null, -1, false); - } - protected HttpClient(URL url, boolean proxyDisabled) throws IOException { this(url, null, -1, proxyDisabled); @@ -388,15 +382,6 @@ public static HttpClient New(URL url, Proxy p, int to, boolean useCache, ret.authcache = httpuc.getAuthCache(); } } else { - @SuppressWarnings("removal") - SecurityManager security = System.getSecurityManager(); - if (security != null) { - if (ret.proxy == Proxy.NO_PROXY || ret.proxy == null) { - security.checkConnect(InetAddress.getByName(url.getHost()).getHostAddress(), url.getPort()); - } else { - security.checkConnect(url.getHost(), url.getPort()); - } - } ret.url = url; } return ret; @@ -571,29 +556,18 @@ public boolean isCachedConnection() { * be done; for proxy tunneling, the socket needs to be converted * into an SSL socket before ssl handshake can take place. */ - public void afterConnect() throws IOException, UnknownHostException { + public void afterConnect() throws IOException { // NO-OP. Needs to be overwritten by HttpsClient } /* - * call openServer in a privileged block + * call openServer */ - @SuppressWarnings("removal") - private void privilegedOpenServer(final InetSocketAddress server) + private void openServer(final InetSocketAddress server) throws IOException { assert clientLock.isHeldByCurrentThread(); - try { - java.security.AccessController.doPrivileged( - new java.security.PrivilegedExceptionAction<>() { - public Void run() throws IOException { - openServer(server.getHostString(), server.getPort()); - return null; - } - }); - } catch (java.security.PrivilegedActionException pae) { - throw (IOException) pae.getException(); - } + openServer(server.getHostString(), server.getPort()); } /* @@ -601,7 +575,7 @@ public Void run() throws IOException { */ private void superOpenServer(final String proxyHost, final int proxyPort) - throws IOException, UnknownHostException + throws IOException { super.openServer(proxyHost, proxyPort); } @@ -610,14 +584,8 @@ private void superOpenServer(final String proxyHost, */ protected void openServer() throws IOException { - @SuppressWarnings("removal") - SecurityManager security = System.getSecurityManager(); - lock(); try { - if (security != null) { - security.checkConnect(host, port); - } if (keepingAlive) { // already opened return; @@ -628,7 +596,7 @@ protected void openServer() throws IOException { if ((proxy != null) && (proxy.type() == Proxy.Type.HTTP)) { sun.net.www.URLConnection.setProxiedHost(host); - privilegedOpenServer((InetSocketAddress) proxy.address()); + openServer((InetSocketAddress) proxy.address()); usingProxy = true; return; } else { @@ -644,7 +612,7 @@ protected void openServer() throws IOException { */ if ((proxy != null) && (proxy.type() == Proxy.Type.HTTP)) { sun.net.www.URLConnection.setProxiedHost(host); - privilegedOpenServer((InetSocketAddress) proxy.address()); + openServer((InetSocketAddress) proxy.address()); usingProxy = true; return; } else { @@ -663,7 +631,7 @@ public String getURLFile() throws IOException { String fileName; - /** + /* * proxyDisabled is set by subclass HttpsClient! */ if (usingProxy && !proxyDisabled) { @@ -817,7 +785,7 @@ private boolean parseHTTPHeader(MessageHeader responses, HttpURLConnection httpu keepAliveConnections = -1; keepAliveTimeout = 0; - boolean ret = false; + boolean ret; byte[] b = new byte[8]; try { diff --git a/src/java.base/share/classes/sun/net/www/http/KeepAliveCache.java b/src/java.base/share/classes/sun/net/www/http/KeepAliveCache.java index 153de588938..41e1e3d0003 100644 --- a/src/java.base/share/classes/sun/net/www/http/KeepAliveCache.java +++ b/src/java.base/share/classes/sun/net/www/http/KeepAliveCache.java @@ -30,8 +30,6 @@ import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.net.URL; -import java.security.AccessController; -import java.security.PrivilegedAction; import java.util.ArrayDeque; import java.util.ArrayList; import java.util.HashMap; @@ -39,7 +37,6 @@ import java.util.concurrent.locks.ReentrantLock; import jdk.internal.misc.InnocuousThread; -import sun.security.action.GetIntegerAction; import sun.net.www.protocol.http.HttpURLConnection; import sun.util.logging.PlatformLogger; @@ -69,10 +66,8 @@ public class KeepAliveCache static final PlatformLogger logger = HttpURLConnection.getHttpLogger(); - @SuppressWarnings("removal") static int getUserKeepAliveSeconds(String type) { - int v = AccessController.doPrivileged( - new GetIntegerAction(keepAliveProp+type, -1)).intValue(); + int v = Integer.getInteger(keepAliveProp+type, -1); return v < -1 ? -1 : v; } @@ -89,12 +84,9 @@ static int getUserKeepAliveSeconds(String type) { */ static final int MAX_CONNECTIONS = 5; static int result = -1; - @SuppressWarnings("removal") static int getMaxConnections() { if (result == -1) { - result = AccessController.doPrivileged( - new GetIntegerAction("http.maxConnections", MAX_CONNECTIONS)) - .intValue(); + result = Integer.getInteger("http.maxConnections", MAX_CONNECTIONS); if (result <= 0) { result = MAX_CONNECTIONS; } @@ -119,7 +111,6 @@ public KeepAliveCache() {} * @param url The URL contains info about the host and port * @param http The HttpClient to be cached */ - @SuppressWarnings("removal") public void put(final URL url, Object obj, HttpClient http) { // this method may need to close an HttpClient, either because // it is not cacheable, or because the cache is at its capacity. @@ -144,15 +135,10 @@ public void put(final URL url, Object obj, HttpClient http) { * The robustness to get around this is in HttpClient.parseHTTP() */ final KeepAliveCache cache = this; - AccessController.doPrivileged(new PrivilegedAction<>() { - public Void run() { - keepAliveTimer = InnocuousThread.newSystemThread("Keep-Alive-Timer", cache); - keepAliveTimer.setDaemon(true); - keepAliveTimer.setPriority(Thread.MAX_PRIORITY - 2); - keepAliveTimer.start(); - return null; - } - }); + keepAliveTimer = InnocuousThread.newSystemThread("Keep-Alive-Timer", cache); + keepAliveTimer.setDaemon(true); + keepAliveTimer.setPriority(Thread.MAX_PRIORITY - 2); + keepAliveTimer.start(); } KeepAliveKey key = new KeepAliveKey(url, obj); diff --git a/src/java.base/share/classes/sun/net/www/http/KeepAliveStream.java b/src/java.base/share/classes/sun/net/www/http/KeepAliveStream.java index 2006dc71de2..4ec81e42c37 100644 --- a/src/java.base/share/classes/sun/net/www/http/KeepAliveStream.java +++ b/src/java.base/share/classes/sun/net/www/http/KeepAliveStream.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -176,16 +176,10 @@ private static void queueForCleanup(KeepAliveCleanerEntry kace) { } if (startCleanupThread) { - java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction<Void>() { - public Void run() { - cleanerThread = InnocuousThread.newSystemThread("Keep-Alive-SocketCleaner", queue); - cleanerThread.setDaemon(true); - cleanerThread.setPriority(Thread.MAX_PRIORITY - 2); - cleanerThread.start(); - return null; - } - }); + cleanerThread = InnocuousThread.newSystemThread("Keep-Alive-SocketCleaner", queue); + cleanerThread.setDaemon(true); + cleanerThread.setPriority(Thread.MAX_PRIORITY - 2); + cleanerThread.start(); } } finally { queue.unlock(); diff --git a/src/java.base/share/classes/sun/net/www/http/KeepAliveStreamCleaner.java b/src/java.base/share/classes/sun/net/www/http/KeepAliveStreamCleaner.java index 79bdb8cc64f..66b039d6c4d 100644 --- a/src/java.base/share/classes/sun/net/www/http/KeepAliveStreamCleaner.java +++ b/src/java.base/share/classes/sun/net/www/http/KeepAliveStreamCleaner.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -28,18 +28,16 @@ import java.io.IOException; import java.util.LinkedList; import sun.net.NetProperties; -import java.security.AccessController; -import java.security.PrivilegedAction; import java.util.concurrent.TimeUnit; import java.util.concurrent.locks.Condition; import java.util.concurrent.locks.ReentrantLock; /** - * This class is used to cleanup any remaining data that may be on a KeepAliveStream + * This class is used to clean up any remaining data that may be on a KeepAliveStream * so that the connection can be cached in the KeepAliveCache. * Instances of this class can be used as a FIFO queue for KeepAliveCleanerEntry objects. * Executing this Runnable removes each KeepAliveCleanerEntry from the Queue, reads - * the reamining bytes on its KeepAliveStream, and if successful puts the connection in + * the remaining bytes on its KeepAliveStream, and if successful puts the connection in * the KeepAliveCache. * * @author Chris Hegarty @@ -50,8 +48,8 @@ class KeepAliveStreamCleaner extends LinkedList<KeepAliveCleanerEntry> implements Runnable { - // maximum amount of remaining data that we will try to cleanup - protected static final int MAX_DATA_REMAINING; + // maximum amount of remaining data that we will try to clean up + protected static final long MAX_DATA_REMAINING; // maximum amount of KeepAliveStreams to be queued protected static final int MAX_CAPACITY; @@ -64,22 +62,10 @@ class KeepAliveStreamCleaner static { final String maxDataKey = "http.KeepAlive.remainingData"; - @SuppressWarnings("removal") - int maxData = AccessController.doPrivileged( - new PrivilegedAction<Integer>() { - public Integer run() { - return NetProperties.getInteger(maxDataKey, 512); - }}).intValue() * 1024; - MAX_DATA_REMAINING = maxData; + MAX_DATA_REMAINING = NetProperties.getInteger(maxDataKey, 512) * 1024L; final String maxCapacityKey = "http.KeepAlive.queuedConnections"; - @SuppressWarnings("removal") - int maxCapacity = AccessController.doPrivileged( - new PrivilegedAction<Integer>() { - public Integer run() { - return NetProperties.getInteger(maxCapacityKey, 10); - }}).intValue(); - MAX_CAPACITY = maxCapacity; + MAX_CAPACITY = NetProperties.getInteger(maxCapacityKey, 10); } From 519bb268a0687ba2b75738e961a72d84b7f49ade Mon Sep 17 00:00:00 2001 From: Daniel Fuchs <dfuchs@openjdk.org> Date: Mon, 25 Nov 2024 10:08:47 +0000 Subject: [PATCH 213/311] 8344217: Remove calls to SecurityManager and doPrivileged in java.net.DatagramSocket and java.net.NetMulticastSocket after JEP 486 integration Reviewed-by: alanb, rriggs, jpai --- .../classes/java/net/DatagramSocket.java | 16 +-- .../classes/java/net/NetMulticastSocket.java | 116 ++---------------- 2 files changed, 12 insertions(+), 120 deletions(-) diff --git a/src/java.base/share/classes/java/net/DatagramSocket.java b/src/java.base/share/classes/java/net/DatagramSocket.java index 2de5f9b8ae6..87b52699993 100644 --- a/src/java.base/share/classes/java/net/DatagramSocket.java +++ b/src/java.base/share/classes/java/net/DatagramSocket.java @@ -387,14 +387,9 @@ public void bind(SocketAddress addr) throws SocketException { * this socket is unknown - it may or may not be connected to the address * that it was previously connected to. * - * <p> Care should be taken to ensure that a connected datagram socket - * is not shared with untrusted code. When a socket is connected, - * {@link #receive receive} and {@link #send send} <b>will not perform - * any security checks</b> on incoming and outgoing packets, other than - * matching the packet's and the socket's address and port. On a send - * operation, if the packet's address is set and the packet's address - * and the socket's address do not match, an {@code IllegalArgumentException} - * will be thrown. A socket connected to a multicast address may only + * <p> When the socket is connected, the send method checks that the + * packet's address matches the remote address that the socket is + * connected to. A socket connected to a multicast address may only * be used to send packets. Datagrams in the socket's {@linkplain * java.net.StandardSocketOptions#SO_RCVBUF socket receive buffer}, which * have not been {@linkplain #receive(DatagramPacket) received} before invoking @@ -1087,11 +1082,6 @@ public DatagramChannel getChannel() { if (factory != null) { throw new SocketException("factory already defined"); } - @SuppressWarnings("removal") - SecurityManager security = System.getSecurityManager(); - if (security != null) { - security.checkSetFactory(); - } factory = fac; } diff --git a/src/java.base/share/classes/java/net/NetMulticastSocket.java b/src/java.base/share/classes/java/net/NetMulticastSocket.java index e7aed881fee..bce2e945335 100644 --- a/src/java.base/share/classes/java/net/NetMulticastSocket.java +++ b/src/java.base/share/classes/java/net/NetMulticastSocket.java @@ -27,9 +27,6 @@ import java.io.IOException; import java.io.UncheckedIOException; -import java.nio.channels.DatagramChannel; -import java.security.AccessController; -import java.security.PrivilegedExceptionAction; import java.util.Enumeration; import java.util.Objects; import java.util.Set; @@ -110,16 +107,6 @@ private synchronized void connectInternal(InetAddress address, int port) throws checkAddress(address, "connect"); if (isClosed()) return; - @SuppressWarnings("removal") - SecurityManager security = System.getSecurityManager(); - if (security != null) { - if (address.isMulticastAddress()) { - security.checkMulticast(address); - } else { - security.checkConnect(address.getHostAddress(), port); - security.checkAccept(address.getHostAddress(), port); - } - } if (port == 0) { throw new SocketException("Can't connect to port 0"); @@ -181,11 +168,7 @@ public synchronized void bind(SocketAddress addr) throws SocketException { InetAddress iaddr = epoint.getAddress(); int port = epoint.getPort(); checkAddress(iaddr, "bind"); - @SuppressWarnings("removal") - SecurityManager sec = System.getSecurityManager(); - if (sec != null) { - sec.checkListen(port); - } + try { getImpl().bind(port, iaddr); } catch (SocketException e) { @@ -289,22 +272,7 @@ public void send(DatagramPacket p) throws IOException { } if (packetPort < 0 || packetPort > 0xFFFF) throw new IllegalArgumentException("port out of range: " + packetPort); - // check the address is ok with the security manager on every send. - @SuppressWarnings("removal") - SecurityManager security = System.getSecurityManager(); - - // The reason you want to synchronize on datagram packet - // is because you don't want an applet to change the address - // while you are trying to send the packet for example - // after the security check but before the send. - if (security != null) { - if (packetAddress.isMulticastAddress()) { - security.checkMulticast(packetAddress); - } else { - security.checkConnect(packetAddress.getHostAddress(), - packetPort); - } - } + if (packetPort == 0) { throw new SocketException("Can't send to port 0"); } @@ -333,41 +301,13 @@ public synchronized void receive(DatagramPacket p) throws IOException { synchronized (p) { if (!isBound()) bind(new InetSocketAddress(0)); - if (connectState == ST_NOT_CONNECTED) { - // check the address is ok with the security manager before every recv. - @SuppressWarnings("removal") - SecurityManager security = System.getSecurityManager(); - if (security != null) { - while (true) { - int peekPort = 0; - // peek at the packet to see who it is from. - DatagramPacket peekPacket = new DatagramPacket(new byte[1], 1); - peekPort = getImpl().peekData(peekPacket); - String peekAd = peekPacket.getAddress().getHostAddress(); - try { - security.checkAccept(peekAd, peekPort); - // security check succeeded - so now break - // and recv the packet. - break; - } catch (SecurityException se) { - // Throw away the offending packet by consuming - // it in a tmp buffer. - DatagramPacket tmp = new DatagramPacket(new byte[1], 1); - getImpl().receive(tmp); - - // silently discard the offending packet - // and continue: unknown/malicious - // entities on nets should not make - // runtime throw security exception and - // disrupt the applet by sending random - // datagram packets. - continue; - } - } // end of while - } - } DatagramPacket tmp = null; + // explicitFilter may be set to 'true' at connect() time and will + // be set to 'false' in disconnect() - or when there's no more + // pending packets to filter. If explicitFilter is true, + // it means we're connected. if (explicitFilter) { + assert connectState == ST_CONNECTED; // We have to do the filtering the old fashioned way since // the native impl doesn't support connect or the connect // via the impl failed, or .. "explicitFilter" may be set when @@ -394,8 +334,7 @@ public synchronized void receive(DatagramPacket p) throws IOException { } } } - // If the security check succeeds, or the datagram is - // connected then receive the packet + // receive the packet getImpl().receive(p); if (explicitFilter && tmp == null) { // packet was not filtered, account for it here @@ -423,11 +362,6 @@ public InetAddress getLocalAddress() { if (in.isAnyLocalAddress()) { in = InetAddress.anyLocalAddress(); } - @SuppressWarnings("removal") - SecurityManager s = System.getSecurityManager(); - if (s != null) { - s.checkConnect(in.getHostAddress(), -1); - } } catch (Exception e) { in = InetAddress.anyLocalAddress(); // "0.0.0.0" } @@ -691,11 +625,6 @@ public void joinGroup(InetAddress mcastaddr) throws IOException { } checkAddress(mcastaddr, "joinGroup"); - @SuppressWarnings("removal") - SecurityManager security = System.getSecurityManager(); - if (security != null) { - security.checkMulticast(mcastaddr); - } if (!mcastaddr.isMulticastAddress()) { throw new SocketException("Not a multicast address"); @@ -722,11 +651,6 @@ public void leaveGroup(InetAddress mcastaddr) throws IOException { } checkAddress(mcastaddr, "leaveGroup"); - @SuppressWarnings("removal") - SecurityManager security = System.getSecurityManager(); - if (security != null) { - security.checkMulticast(mcastaddr); - } if (!mcastaddr.isMulticastAddress()) { throw new SocketException("Not a multicast address"); @@ -745,11 +669,6 @@ public void joinGroup(SocketAddress mcastaddr, NetworkInterface netIf) throw new IllegalArgumentException("Unsupported address type"); checkAddress(addr.getAddress(), "joinGroup"); - @SuppressWarnings("removal") - SecurityManager security = System.getSecurityManager(); - if (security != null) { - security.checkMulticast(addr.getAddress()); - } if (!addr.getAddress().isMulticastAddress()) { throw new SocketException("Not a multicast address"); @@ -768,11 +687,6 @@ public void leaveGroup(SocketAddress mcastaddr, NetworkInterface netIf) throw new IllegalArgumentException("Unsupported address type"); checkAddress(addr.getAddress(), "leaveGroup"); - @SuppressWarnings("removal") - SecurityManager security = System.getSecurityManager(); - if (security != null) { - security.checkMulticast(addr.getAddress()); - } if (!addr.getAddress().isMulticastAddress()) { throw new SocketException("Not a multicast address"); @@ -893,22 +807,10 @@ public void send(DatagramPacket p, byte ttl) synchronized(p) { InetAddress packetAddress = p.getAddress(); checkAddress(packetAddress, "send"); - if (connectState == NetMulticastSocket.ST_NOT_CONNECTED) { + if (connectState == ST_NOT_CONNECTED) { if (packetAddress == null) { throw new IllegalArgumentException("Address not set"); } - // Security manager makes sure that the multicast address - // is allowed one and that the ttl used is less - // than the allowed maxttl. - SecurityManager security = System.getSecurityManager(); - if (security != null) { - if (packetAddress.isMulticastAddress()) { - security.checkMulticast(packetAddress, ttl); - } else { - security.checkConnect(packetAddress.getHostAddress(), - p.getPort()); - } - } } else { // we're connected if (packetAddress == null) { From 811d08c0a4e0da55f306686423aec40d29fabf00 Mon Sep 17 00:00:00 2001 From: Emanuel Peter <epeter@openjdk.org> Date: Mon, 25 Nov 2024 10:39:36 +0000 Subject: [PATCH 214/311] 8340010: Fix vectorization tests with compact headers Reviewed-by: chagedorn, rkennke, mli --- .../c2/TestCastX2NotProcessedIGVN.java | 21 +- .../c2/irTests/TestVectorConditionalMove.java | 22 +- .../TestVectorizationMismatchedAccess.java | 120 ++++++++--- .../c2/irTests/TestVectorizationNotRun.java | 25 ++- .../loopopts/superword/TestAlignVector.java | 168 +++++++++++++-- ...tIndependentPacksWithCyclicDependency.java | 49 ++++- .../loopopts/superword/TestMulAddS2I.java | 61 ++++-- .../TestScheduleReordersScalarMemops.java | 36 +++- .../loopopts/superword/TestSplitPacks.java | 200 +++++++++++++++--- ...norderedReductionPartialVectorization.java | 11 +- .../TestFloatConversionsVector.java | 37 +++- .../runner/ArrayTypeConvertTest.java | 93 +++++++- .../runner/LoopCombinedOpTest.java | 198 +++++++++++++++-- .../runner/VectorizationTestRunner.java | 10 +- .../ir_framework/examples/IRExample.java | 4 +- 15 files changed, 915 insertions(+), 140 deletions(-) diff --git a/test/hotspot/jtreg/compiler/c2/TestCastX2NotProcessedIGVN.java b/test/hotspot/jtreg/compiler/c2/TestCastX2NotProcessedIGVN.java index 086711085b4..ca5a754f296 100644 --- a/test/hotspot/jtreg/compiler/c2/TestCastX2NotProcessedIGVN.java +++ b/test/hotspot/jtreg/compiler/c2/TestCastX2NotProcessedIGVN.java @@ -1,5 +1,6 @@ /* * Copyright (c) 2024, Red Hat, Inc. All rights reserved. + * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -42,7 +43,19 @@ public class TestCastX2NotProcessedIGVN { public static void main(String[] args) { - TestFramework.runWithFlags("--add-modules", "java.base", "--add-exports", "java.base/jdk.internal.misc=ALL-UNNAMED"); + // Cross-product: +-AlignVector and +-UseCompactObjectHeaders + TestFramework.runWithFlags("--add-modules", "java.base", "--add-exports", "java.base/jdk.internal.misc=ALL-UNNAMED", + "-XX:+UnlockExperimentalVMOptions", "-XX:-UseCompactObjectHeaders", + "-XX:-AlignVector"); + TestFramework.runWithFlags("--add-modules", "java.base", "--add-exports", "java.base/jdk.internal.misc=ALL-UNNAMED", + "-XX:+UnlockExperimentalVMOptions", "-XX:-UseCompactObjectHeaders", + "-XX:+AlignVector"); + TestFramework.runWithFlags("--add-modules", "java.base", "--add-exports", "java.base/jdk.internal.misc=ALL-UNNAMED", + "-XX:+UnlockExperimentalVMOptions", "-XX:+UseCompactObjectHeaders", + "-XX:-AlignVector"); + TestFramework.runWithFlags("--add-modules", "java.base", "--add-exports", "java.base/jdk.internal.misc=ALL-UNNAMED", + "-XX:+UnlockExperimentalVMOptions", "-XX:+UseCompactObjectHeaders", + "-XX:+AlignVector"); } @Test @@ -63,6 +76,7 @@ public static void test1Runner() { @Test @IR(counts = {IRNode.LOAD_VECTOR_I, "> 1"}, + applyIfOr = {"UseCompactObjectHeaders", "false", "AlignVector", "false"}, applyIfPlatformOr = {"x64", "true", "aarch64", "true"}) public static int test2(int stop, int[] array) { int v = 0; @@ -70,6 +84,11 @@ public static int test2(int stop, int[] array) { for (int i = 0; i < stop; i++) { long offset = ((long)i) * 4; array[i] = UNSAFE.getInt(null, offset + base); + // With AlignVector, we need 8-byte alignment of vector loads/stores. + // UseCompactObjectHeaders=false UseCompactObjectHeaders=true + // I_adr = base + 16 + 4*i -> i % 2 = 0 B_adr = base + 12 + 4*i -> i % 2 = 1 + // N_adr = base + 4*i -> i % 2 = 0 N_adr = base + 4*i -> i % 2 = 0 + // -> vectorize -> no vectorization } return v; } diff --git a/test/hotspot/jtreg/compiler/c2/irTests/TestVectorConditionalMove.java b/test/hotspot/jtreg/compiler/c2/irTests/TestVectorConditionalMove.java index 6f6b7f5bd30..c8b3e5a3aa6 100644 --- a/test/hotspot/jtreg/compiler/c2/irTests/TestVectorConditionalMove.java +++ b/test/hotspot/jtreg/compiler/c2/irTests/TestVectorConditionalMove.java @@ -1,6 +1,6 @@ /* * Copyright (c) 2022, Arm Limited. All rights reserved. - * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -43,7 +43,15 @@ public class TestVectorConditionalMove { private static final Random RANDOM = Utils.getRandomInstance(); public static void main(String[] args) { - TestFramework.runWithFlags("-XX:+UseCMoveUnconditionally", "-XX:+UseVectorCmov"); + // Cross-product: +-AlignVector and +-UseCompactObjectHeaders + TestFramework.runWithFlags("-XX:+UseCMoveUnconditionally", "-XX:+UseVectorCmov", + "-XX:+UnlockExperimentalVMOptions", "-XX:-UseCompactObjectHeaders", "-XX:-AlignVector"); + TestFramework.runWithFlags("-XX:+UseCMoveUnconditionally", "-XX:+UseVectorCmov", + "-XX:+UnlockExperimentalVMOptions", "-XX:-UseCompactObjectHeaders", "-XX:+AlignVector"); + TestFramework.runWithFlags("-XX:+UseCMoveUnconditionally", "-XX:+UseVectorCmov", + "-XX:+UnlockExperimentalVMOptions", "-XX:+UseCompactObjectHeaders", "-XX:-AlignVector"); + TestFramework.runWithFlags("-XX:+UseCMoveUnconditionally", "-XX:+UseVectorCmov", + "-XX:+UnlockExperimentalVMOptions", "-XX:+UseCompactObjectHeaders", "-XX:+AlignVector"); } // Compare 2 values, and pick one of them @@ -400,11 +408,16 @@ private static void testCMoveFNEQforFConst(float[] a, float[] b, float[] c) { IRNode.VECTOR_MASK_CMP_F, ">0", IRNode.VECTOR_BLEND_F, ">0", IRNode.STORE_VECTOR, ">0"}, + applyIfOr = {"UseCompactObjectHeaders", "false", "AlignVector", "false"}, applyIfCPUFeatureOr = {"avx", "true", "asimd", "true"}) private static void testCMoveFLTforFConstH2(float[] a, float[] b, float[] c) { for (int i = 0; i < a.length; i+=2) { c[i+0] = (a[i+0] < b[i+0]) ? 0.1f : -0.1f; c[i+1] = (a[i+1] < b[i+1]) ? 0.1f : -0.1f; + // With AlignVector, we need 8-byte alignment of vector loads/stores. + // UseCompactObjectHeaders=false UseCompactObjectHeaders=true + // adr = base + 16 + 8*i -> always adr = base + 12 + 8*i -> never + // -> vectorize -> no vectorization } } @@ -413,11 +426,16 @@ private static void testCMoveFLTforFConstH2(float[] a, float[] b, float[] c) { IRNode.VECTOR_MASK_CMP_F, ">0", IRNode.VECTOR_BLEND_F, ">0", IRNode.STORE_VECTOR, ">0"}, + applyIfOr = {"UseCompactObjectHeaders", "false", "AlignVector", "false"}, applyIfCPUFeatureOr = {"avx", "true", "asimd", "true"}) private static void testCMoveFLEforFConstH2(float[] a, float[] b, float[] c) { for (int i = 0; i < a.length; i+=2) { c[i+0] = (a[i+0] <= b[i+0]) ? 0.1f : -0.1f; c[i+1] = (a[i+1] <= b[i+1]) ? 0.1f : -0.1f; + // With AlignVector, we need 8-byte alignment of vector loads/stores. + // UseCompactObjectHeaders=false UseCompactObjectHeaders=true + // adr = base + 16 + 8*i -> always adr = base + 12 + 8*i -> never + // -> vectorize -> no vectorization } } diff --git a/test/hotspot/jtreg/compiler/c2/irTests/TestVectorizationMismatchedAccess.java b/test/hotspot/jtreg/compiler/c2/irTests/TestVectorizationMismatchedAccess.java index b511476bf52..c891145b08d 100644 --- a/test/hotspot/jtreg/compiler/c2/irTests/TestVectorizationMismatchedAccess.java +++ b/test/hotspot/jtreg/compiler/c2/irTests/TestVectorizationMismatchedAccess.java @@ -50,7 +50,19 @@ public class TestVectorizationMismatchedAccess { private final static WhiteBox wb = WhiteBox.getWhiteBox(); public static void main(String[] args) { - TestFramework.runWithFlags("--add-modules", "java.base", "--add-exports", "java.base/jdk.internal.misc=ALL-UNNAMED"); + // Cross-product: +-AlignVector and +-UseCompactObjectHeaders + TestFramework.runWithFlags("--add-modules", "java.base", "--add-exports", "java.base/jdk.internal.misc=ALL-UNNAMED", + "-XX:+UnlockExperimentalVMOptions", "-XX:-UseCompactObjectHeaders", + "-XX:-AlignVector"); + TestFramework.runWithFlags("--add-modules", "java.base", "--add-exports", "java.base/jdk.internal.misc=ALL-UNNAMED", + "-XX:+UnlockExperimentalVMOptions", "-XX:-UseCompactObjectHeaders", + "-XX:+AlignVector"); + TestFramework.runWithFlags("--add-modules", "java.base", "--add-exports", "java.base/jdk.internal.misc=ALL-UNNAMED", + "-XX:+UnlockExperimentalVMOptions", "-XX:+UseCompactObjectHeaders", + "-XX:-AlignVector"); + TestFramework.runWithFlags("--add-modules", "java.base", "--add-exports", "java.base/jdk.internal.misc=ALL-UNNAMED", + "-XX:+UnlockExperimentalVMOptions", "-XX:+UseCompactObjectHeaders", + "-XX:+AlignVector"); } static int size = 1024; @@ -153,8 +165,7 @@ static private void runAndVerify3(Runnable test, int offset) { @Test @IR(counts = { IRNode.LOAD_VECTOR_L, ">=1", IRNode.STORE_VECTOR, ">=1" }, - // This test fails with compact headers, but only with UseSSE<=3. - applyIf = { "UseCompactObjectHeaders", "false" }, + applyIfOr = {"UseCompactObjectHeaders", "false", "AlignVector", "false"}, applyIfCPUFeatureOr = {"sse2", "true", "asimd", "true"}, applyIfPlatform = {"64-bit", "true"}) // 32-bit: offsets are badly aligned (UNSAFE.ARRAY_BYTE_BASE_OFFSET is 4 byte aligned, but not 8 byte aligned). @@ -162,38 +173,48 @@ static private void runAndVerify3(Runnable test, int offset) { public static void testByteLong1a(byte[] dest, long[] src) { for (int i = 0; i < src.length; i++) { UNSAFE.putLongUnaligned(dest, UNSAFE.ARRAY_BYTE_BASE_OFFSET + 8 * i, handleByteOrder(src[i])); + // With AlignVector, we need 8-byte alignment of vector loads/stores. + // UseCompactObjectHeaders=false UseCompactObjectHeaders=true + // B_adr = base + 16 + 8*i -> always B_adr = base + 12 + 8*i -> never + // L_adr = base + 16 + 8*i -> always L_adr = base + 16 + 8*i -> always + // -> vectorize -> no vectorization } } @Test @IR(counts = { IRNode.LOAD_VECTOR_L, ">=1", IRNode.STORE_VECTOR, ">=1" }, - // This test fails with compact headers, but only with UseSSE<=3. - applyIf = { "UseCompactObjectHeaders", "false" }, + applyIfOr = {"UseCompactObjectHeaders", "false", "AlignVector", "false"}, applyIfCPUFeatureOr = {"sse2", "true", "asimd", "true"}, applyIfPlatform = {"64-bit", "true"}) // 32-bit: address has ConvL2I for cast of long to address, not supported. public static void testByteLong1b(byte[] dest, long[] src) { for (int i = 0; i < src.length; i++) { UNSAFE.putLongUnaligned(dest, UNSAFE.ARRAY_BYTE_BASE_OFFSET + 8L * i, handleByteOrder(src[i])); + // With AlignVector, we need 8-byte alignment of vector loads/stores. + // UseCompactObjectHeaders=false UseCompactObjectHeaders=true + // B_adr = base + 16 + 8*i -> always B_adr = base + 12 + 8*i -> never + // L_adr = base + 16 + 8*i -> always L_adr = base + 16 + 8*i -> always + // -> vectorize -> no vectorization } } @Test @IR(counts = { IRNode.LOAD_VECTOR_L, ">=1", IRNode.STORE_VECTOR, ">=1" }, - // This test fails with compact headers, but only with UseSSE<=3. - applyIf = { "UseCompactObjectHeaders", "false" }, applyIfCPUFeatureOr = {"sse2", "true", "asimd", "true"}) public static void testByteLong1c(byte[] dest, long[] src) { long base = 64; // make sure it is big enough and 8 byte aligned (required for 32-bit) for (int i = 0; i < src.length - 8; i++) { UNSAFE.putLongUnaligned(dest, base + 8 * i, handleByteOrder(src[i])); + // With AlignVector, we need 8-byte alignment of vector loads/stores. + // UseCompactObjectHeaders=false UseCompactObjectHeaders=true + // B_adr = base + 64 + 8*i -> always B_adr = base + 64 + 8*i -> always + // L_adr = base + 16 + 8*i -> always L_adr = base + 16 + 8*i -> always + // -> vectorize -> vectorize } } @Test @IR(counts = { IRNode.LOAD_VECTOR_L, ">=1", IRNode.STORE_VECTOR, ">=1" }, - // This test fails with compact headers, but only with UseSSE<=3. - applyIf = { "UseCompactObjectHeaders", "false" }, applyIfCPUFeatureOr = {"sse2", "true", "asimd", "true"}, applyIfPlatform = {"64-bit", "true"}) // 32-bit: address has ConvL2I for cast of long to address, not supported. @@ -201,6 +222,11 @@ public static void testByteLong1d(byte[] dest, long[] src) { long base = 64; // make sure it is big enough and 8 byte aligned (required for 32-bit) for (int i = 0; i < src.length - 8; i++) { UNSAFE.putLongUnaligned(dest, base + 8L * i, handleByteOrder(src[i])); + // With AlignVector, we need 8-byte alignment of vector loads/stores. + // UseCompactObjectHeaders=false UseCompactObjectHeaders=true + // B_adr = base + 64 + 8*i -> always B_adr = base + 64 + 8*i -> always + // L_adr = base + 16 + 8*i -> always L_adr = base + 16 + 8*i -> always + // -> vectorize -> vectorize } } @@ -214,6 +240,7 @@ public static void testByteLong1_runner() { @Test @IR(counts = { IRNode.LOAD_VECTOR_L, ">=1", IRNode.STORE_VECTOR, ">=1" }, + applyIfOr = {"UseCompactObjectHeaders", "false", "AlignVector", "false"}, applyIfCPUFeatureOr = {"sse2", "true", "asimd", "true"}, applyIfPlatform = {"64-bit", "true"}) // 32-bit: offsets are badly aligned (UNSAFE.ARRAY_BYTE_BASE_OFFSET is 4 byte aligned, but not 8 byte aligned). @@ -221,17 +248,28 @@ public static void testByteLong1_runner() { public static void testByteLong2a(byte[] dest, long[] src) { for (int i = 1; i < src.length; i++) { UNSAFE.putLongUnaligned(dest, UNSAFE.ARRAY_BYTE_BASE_OFFSET + 8 * (i - 1), handleByteOrder(src[i])); + // With AlignVector, we need 8-byte alignment of vector loads/stores. + // UseCompactObjectHeaders=false UseCompactObjectHeaders=true + // B_adr = base + 16 + 8*(i-1) -> always B_adr = base + 12 + 8*(i-1) -> never + // L_adr = base + 16 + 8*i -> always L_adr = base + 16 + 8*i -> always + // -> vectorize -> no vectorization } } @Test @IR(counts = { IRNode.LOAD_VECTOR_L, ">=1", IRNode.STORE_VECTOR, ">=1" }, + applyIfOr = {"UseCompactObjectHeaders", "false", "AlignVector", "false"}, applyIfCPUFeatureOr = {"sse2", "true", "asimd", "true"}, applyIfPlatform = {"64-bit", "true"}) // 32-bit: address has ConvL2I for cast of long to address, not supported. public static void testByteLong2b(byte[] dest, long[] src) { for (int i = 1; i < src.length; i++) { UNSAFE.putLongUnaligned(dest, UNSAFE.ARRAY_BYTE_BASE_OFFSET + 8L * (i - 1), handleByteOrder(src[i])); + // With AlignVector, we need 8-byte alignment of vector loads/stores. + // UseCompactObjectHeaders=false UseCompactObjectHeaders=true + // B_adr = base + 16 + 8*(i-1) -> always B_adr = base + 12 + 8*(i-1) -> never + // L_adr = base + 16 + 8*i -> always L_adr = base + 16 + 8*i -> always + // -> vectorize -> no vectorization } } @@ -243,8 +281,7 @@ public static void testByteLong2_runner() { @Test @IR(counts = { IRNode.LOAD_VECTOR_L, ">=1", IRNode.STORE_VECTOR, ">=1" }, - // This test fails with compact headers, but only with UseSSE<=3. - applyIf = { "UseCompactObjectHeaders", "false" }, + applyIfOr = {"UseCompactObjectHeaders", "false", "AlignVector", "false"}, applyIfCPUFeatureOr = {"sse2", "true", "asimd", "true"}, applyIfPlatform = {"64-bit", "true"}) // 32-bit: offsets are badly aligned (UNSAFE.ARRAY_BYTE_BASE_OFFSET is 4 byte aligned, but not 8 byte aligned). @@ -252,19 +289,28 @@ public static void testByteLong2_runner() { public static void testByteLong3a(byte[] dest, long[] src) { for (int i = 0; i < src.length - 1; i++) { UNSAFE.putLongUnaligned(dest, UNSAFE.ARRAY_BYTE_BASE_OFFSET + 8 * (i + 1), handleByteOrder(src[i])); + // With AlignVector, we need 8-byte alignment of vector loads/stores. + // UseCompactObjectHeaders=false UseCompactObjectHeaders=true + // B_adr = base + 16 + 8*(i+1) -> always B_adr = base + 12 + 8*(i+1) -> never + // L_adr = base + 16 + 8*i -> always L_adr = base + 16 + 8*i -> always + // -> vectorize -> no vectorization } } @Test @IR(counts = { IRNode.LOAD_VECTOR_L, ">=1", IRNode.STORE_VECTOR, ">=1" }, - // This test fails with compact headers, but only with UseSSE<=3. - applyIf = { "UseCompactObjectHeaders", "false" }, + applyIfOr = {"UseCompactObjectHeaders", "false", "AlignVector", "false"}, applyIfCPUFeatureOr = {"sse2", "true", "asimd", "true"}, applyIfPlatform = {"64-bit", "true"}) // 32-bit: address has ConvL2I for cast of long to address, not supported. public static void testByteLong3b(byte[] dest, long[] src) { for (int i = 0; i < src.length - 1; i++) { UNSAFE.putLongUnaligned(dest, UNSAFE.ARRAY_BYTE_BASE_OFFSET + 8L * (i + 1), handleByteOrder(src[i])); + // With AlignVector, we need 8-byte alignment of vector loads/stores. + // UseCompactObjectHeaders=false UseCompactObjectHeaders=true + // B_adr = base + 16 + 8*(i+1) -> always B_adr = base + 12 + 8*(i+1) -> never + // L_adr = base + 16 + 8*i -> always L_adr = base + 16 + 8*i -> always + // -> vectorize -> no vectorization } } @@ -310,8 +356,7 @@ public static void testByteLong4_runner() { @Test @IR(counts = { IRNode.LOAD_VECTOR_L, ">=1", IRNode.STORE_VECTOR, ">=1" }, - // This test fails with compact headers, but only with UseSSE<=3. - applyIf = { "UseCompactObjectHeaders", "false" }, + applyIfOr = {"UseCompactObjectHeaders", "false", "AlignVector", "false"}, applyIfCPUFeatureOr = {"sse2", "true", "asimd", "true"}, applyIfPlatform = {"64-bit", "true"}) // 32-bit: offsets are badly aligned (UNSAFE.ARRAY_BYTE_BASE_OFFSET is 4 byte aligned, but not 8 byte aligned). @@ -319,19 +364,28 @@ public static void testByteLong4_runner() { public static void testByteLong5a(byte[] dest, long[] src, int start, int stop) { for (int i = start; i < stop; i++) { UNSAFE.putLongUnaligned(dest, UNSAFE.ARRAY_BYTE_BASE_OFFSET + 8 * (i + baseOffset), handleByteOrder(src[i])); + // With AlignVector, we need 8-byte alignment of vector loads/stores. + // UseCompactObjectHeaders=false UseCompactObjectHeaders=true + // B_adr = base + 16 + 8*(i+x) -> always B_adr = base + 12 + 8*(i+x) -> never + // L_adr = base + 16 + 8*i -> always L_adr = base + 16 + 8*i -> always + // -> vectorize -> no vectorization } } @Test @IR(counts = { IRNode.LOAD_VECTOR_L, ">=1", IRNode.STORE_VECTOR, ">=1" }, - // This test fails with compact headers, but only with UseSSE<=3. - applyIf = { "UseCompactObjectHeaders", "false" }, + applyIfOr = {"UseCompactObjectHeaders", "false", "AlignVector", "false"}, applyIfCPUFeatureOr = {"sse2", "true", "asimd", "true"}, applyIfPlatform = {"64-bit", "true"}) // 32-bit: address has ConvL2I for cast of long to address, not supported. public static void testByteLong5b(byte[] dest, long[] src, int start, int stop) { for (int i = start; i < stop; i++) { UNSAFE.putLongUnaligned(dest, UNSAFE.ARRAY_BYTE_BASE_OFFSET + 8L * (i + baseOffset), handleByteOrder(src[i])); + // With AlignVector, we need 8-byte alignment of vector loads/stores. + // UseCompactObjectHeaders=false UseCompactObjectHeaders=true + // B_adr = base + 16 + 8*(i+x) -> always B_adr = base + 12 + 8*(i+x) -> never + // L_adr = base + 16 + 8*i -> always L_adr = base + 16 + 8*i -> always + // -> vectorize -> no vectorization } } @@ -344,8 +398,7 @@ public static void testByteLong5_runner() { @Test @IR(counts = { IRNode.LOAD_VECTOR_L, ">=1", IRNode.STORE_VECTOR, ">=1" }, - // This test fails with compact headers, but only with UseSSE<=3. - applyIf = { "UseCompactObjectHeaders", "false" }, + applyIfOr = {"UseCompactObjectHeaders", "false", "AlignVector", "false"}, applyIfCPUFeatureOr = {"sse2", "true", "asimd", "true"}, applyIfPlatform = {"64-bit", "true"}) // 32-bit: offsets are badly aligned (UNSAFE.ARRAY_BYTE_BASE_OFFSET is 4 byte aligned, but not 8 byte aligned). @@ -353,19 +406,28 @@ public static void testByteLong5_runner() { public static void testByteByte1a(byte[] dest, byte[] src) { for (int i = 0; i < src.length / 8; i++) { UNSAFE.putLongUnaligned(dest, UNSAFE.ARRAY_BYTE_BASE_OFFSET + 8 * i, UNSAFE.getLongUnaligned(src, UNSAFE.ARRAY_BYTE_BASE_OFFSET + 8 * i)); + // With AlignVector, we need 8-byte alignment of vector loads/stores. + // UseCompactObjectHeaders=false UseCompactObjectHeaders=true + // src_adr = base + 16 + 8*i -> always src_adr = base + 12 + 8*i -> never + // dst_adr = base + 16 + 8*i -> always dst_adr = base + 12 + 8*i -> never + // -> vectorize -> no vectorization } } @Test @IR(counts = { IRNode.LOAD_VECTOR_L, ">=1", IRNode.STORE_VECTOR, ">=1" }, - // This test fails with compact headers, but only with UseSSE<=3. - applyIf = { "UseCompactObjectHeaders", "false" }, + applyIfOr = {"UseCompactObjectHeaders", "false", "AlignVector", "false"}, applyIfCPUFeatureOr = {"sse2", "true", "asimd", "true"}, applyIfPlatform = {"64-bit", "true"}) // 32-bit: address has ConvL2I for cast of long to address, not supported. public static void testByteByte1b(byte[] dest, byte[] src) { for (int i = 0; i < src.length / 8; i++) { UNSAFE.putLongUnaligned(dest, UNSAFE.ARRAY_BYTE_BASE_OFFSET + 8L * i, UNSAFE.getLongUnaligned(src, UNSAFE.ARRAY_BYTE_BASE_OFFSET + 8L * i)); + // With AlignVector, we need 8-byte alignment of vector loads/stores. + // UseCompactObjectHeaders=false UseCompactObjectHeaders=true + // src_adr = base + 16 + 8*i -> always src_adr = base + 12 + 8*i -> never + // dst_adr = base + 16 + 8*i -> always dst_adr = base + 12 + 8*i -> never + // -> vectorize -> no vectorization } } @@ -377,8 +439,7 @@ public static void testByteByte1_runner() { @Test @IR(counts = { IRNode.LOAD_VECTOR_L, ">=1", IRNode.STORE_VECTOR, ">=1" }, - // This test fails with compact headers, but only with UseSSE<=3. - applyIf = { "UseCompactObjectHeaders", "false" }, + applyIfOr = {"UseCompactObjectHeaders", "false", "AlignVector", "false"}, applyIfCPUFeatureOr = {"sse2", "true", "asimd", "true"}, applyIfPlatform = {"64-bit", "true"}) // 32-bit: offsets are badly aligned (UNSAFE.ARRAY_BYTE_BASE_OFFSET is 4 byte aligned, but not 8 byte aligned). @@ -386,19 +447,28 @@ public static void testByteByte1_runner() { public static void testByteByte2a(byte[] dest, byte[] src) { for (int i = 1; i < src.length / 8; i++) { UNSAFE.putLongUnaligned(dest, UNSAFE.ARRAY_BYTE_BASE_OFFSET + 8 * (i - 1), UNSAFE.getLongUnaligned(src, UNSAFE.ARRAY_BYTE_BASE_OFFSET + 8 * i)); + // With AlignVector, we need 8-byte alignment of vector loads/stores. + // UseCompactObjectHeaders=false UseCompactObjectHeaders=true + // src_adr = base + 16 + 8*i -> always src_adr = base + 12 + 8*i -> never + // dst_adr = base + 16 + 8*(i-1) -> always dst_adr = base + 12 + 8*(i-1) -> never + // -> vectorize -> no vectorization } } @Test @IR(counts = { IRNode.LOAD_VECTOR_L, ">=1", IRNode.STORE_VECTOR, ">=1" }, - // This test fails with compact headers, but only with UseSSE<=3. - applyIf = { "UseCompactObjectHeaders", "false" }, + applyIfOr = {"UseCompactObjectHeaders", "false", "AlignVector", "false"}, applyIfCPUFeatureOr = {"sse2", "true", "asimd", "true"}, applyIfPlatform = {"64-bit", "true"}) // 32-bit: address has ConvL2I for cast of long to address, not supported. public static void testByteByte2b(byte[] dest, byte[] src) { for (int i = 1; i < src.length / 8; i++) { UNSAFE.putLongUnaligned(dest, UNSAFE.ARRAY_BYTE_BASE_OFFSET + 8L * (i - 1), UNSAFE.getLongUnaligned(src, UNSAFE.ARRAY_BYTE_BASE_OFFSET + 8L * i)); + // With AlignVector, we need 8-byte alignment of vector loads/stores. + // UseCompactObjectHeaders=false UseCompactObjectHeaders=true + // src_adr = base + 16 + 8*i -> always src_adr = base + 12 + 8*i -> never + // dst_adr = base + 16 + 8*(i-1) -> always dst_adr = base + 12 + 8*(i-1) -> never + // -> vectorize -> no vectorization } } diff --git a/test/hotspot/jtreg/compiler/c2/irTests/TestVectorizationNotRun.java b/test/hotspot/jtreg/compiler/c2/irTests/TestVectorizationNotRun.java index d61b8c658d6..27456bf9200 100644 --- a/test/hotspot/jtreg/compiler/c2/irTests/TestVectorizationNotRun.java +++ b/test/hotspot/jtreg/compiler/c2/irTests/TestVectorizationNotRun.java @@ -32,7 +32,6 @@ /* * @test * @bug 8300256 - * @requires (os.simpleArch == "x64") | (os.simpleArch == "aarch64") * @modules java.base/jdk.internal.misc * @library /test/lib / * @run driver compiler.c2.irTests.TestVectorizationNotRun @@ -42,7 +41,19 @@ public class TestVectorizationNotRun { private static final Unsafe UNSAFE = Unsafe.getUnsafe(); public static void main(String[] args) { - TestFramework.runWithFlags("--add-modules", "java.base", "--add-exports", "java.base/jdk.internal.misc=ALL-UNNAMED"); + // Cross-product: +-AlignVector and +-UseCompactObjectHeaders + TestFramework.runWithFlags("--add-modules", "java.base", "--add-exports", "java.base/jdk.internal.misc=ALL-UNNAMED", + "-XX:+UnlockExperimentalVMOptions", "-XX:-UseCompactObjectHeaders", + "-XX:-AlignVector"); + TestFramework.runWithFlags("--add-modules", "java.base", "--add-exports", "java.base/jdk.internal.misc=ALL-UNNAMED", + "-XX:+UnlockExperimentalVMOptions", "-XX:-UseCompactObjectHeaders", + "-XX:+AlignVector"); + TestFramework.runWithFlags("--add-modules", "java.base", "--add-exports", "java.base/jdk.internal.misc=ALL-UNNAMED", + "-XX:+UnlockExperimentalVMOptions", "-XX:+UseCompactObjectHeaders", + "-XX:-AlignVector"); + TestFramework.runWithFlags("--add-modules", "java.base", "--add-exports", "java.base/jdk.internal.misc=ALL-UNNAMED", + "-XX:+UnlockExperimentalVMOptions", "-XX:+UseCompactObjectHeaders", + "-XX:+AlignVector"); } static int size = 1024; @@ -52,14 +63,19 @@ public static void main(String[] args) { @Test @IR(counts = { IRNode.LOAD_VECTOR_L, ">=1", IRNode.STORE_VECTOR, ">=1" }, - // This test fails with compact headers, but only with UseSSE<=3. - applyIf = { "UseCompactObjectHeaders", "false" }) + applyIfOr = { "UseCompactObjectHeaders", "false", "AlignVector", "false" }, + applyIfPlatform = {"64-bit", "true"}, + applyIfCPUFeatureOr = {"sse4.1", "true", "asimd", "true"}) public static void test(byte[] dest, long[] src) { for (int i = 0; i < src.length; i++) { if ((i < 0) || (8 > sizeBytes - i)) { throw new IndexOutOfBoundsException(); } UNSAFE.putLongUnaligned(dest, UNSAFE.ARRAY_BYTE_BASE_OFFSET + i * 8, src[i]); + // For UseCompactObjectHeaders and AlignVector, we must 8-byte align all vector loads/stores. + // But the long-stores to the byte-array are never aligned: + // adr = base + UNSAFE.ARRAY_BYTE_BASE_OFFSET + 8*iter + // = 16 (or 12 if UseCompactObjectHeaders=true) } } @@ -67,5 +83,4 @@ public static void test(byte[] dest, long[] src) { public static void test_runner() { test(byteArray, longArray); } - } diff --git a/test/hotspot/jtreg/compiler/loopopts/superword/TestAlignVector.java b/test/hotspot/jtreg/compiler/loopopts/superword/TestAlignVector.java index 60d753ee75f..cb9484f2668 100644 --- a/test/hotspot/jtreg/compiler/loopopts/superword/TestAlignVector.java +++ b/test/hotspot/jtreg/compiler/loopopts/superword/TestAlignVector.java @@ -60,6 +60,24 @@ * @run driver compiler.loopopts.superword.TestAlignVector VerifyAlignVector */ +/* + * @test id=NoAlignVector-COH + * @bug 8310190 + * @summary Test AlignVector with various loop init, stride, scale, invar, etc. + * @modules java.base/jdk.internal.misc + * @library /test/lib / + * @run driver compiler.loopopts.superword.TestAlignVector NoAlignVector-COH + */ + +/* + * @test id=VerifyAlignVector-COH + * @bug 8310190 + * @summary Test AlignVector with various loop init, stride, scale, invar, etc. + * @modules java.base/jdk.internal.misc + * @library /test/lib / + * @run driver compiler.loopopts.superword.TestAlignVector VerifyAlignVector-COH + */ + public class TestAlignVector { static int RANGE = 1024*8; static int RANGE_FINAL = 1024*8; @@ -96,9 +114,11 @@ public static void main(String[] args) { "-XX:+IgnoreUnrecognizedVMOptions", "-XX:LoopUnrollLimit=250"); switch (args[0]) { - case "NoAlignVector" -> { framework.addFlags("-XX:-AlignVector"); } - case "AlignVector" -> { framework.addFlags("-XX:+AlignVector"); } - case "VerifyAlignVector" -> { framework.addFlags("-XX:+AlignVector", "-XX:+IgnoreUnrecognizedVMOptions", "-XX:+VerifyAlignVector"); } + case "NoAlignVector" -> { framework.addFlags("-XX:+UnlockExperimentalVMOptions", "-XX:-UseCompactObjectHeaders", "-XX:-AlignVector"); } + case "AlignVector" -> { framework.addFlags("-XX:+UnlockExperimentalVMOptions", "-XX:-UseCompactObjectHeaders", "-XX:+AlignVector"); } + case "VerifyAlignVector" -> { framework.addFlags("-XX:+UnlockExperimentalVMOptions", "-XX:-UseCompactObjectHeaders", "-XX:+AlignVector", "-XX:+IgnoreUnrecognizedVMOptions", "-XX:+VerifyAlignVector"); } + case "NoAlignVector-COH" -> { framework.addFlags("-XX:+UnlockExperimentalVMOptions", "-XX:+UseCompactObjectHeaders", "-XX:-AlignVector"); } + case "VerifyAlignVector-COH" -> { framework.addFlags("-XX:+UnlockExperimentalVMOptions", "-XX:+UseCompactObjectHeaders", "-XX:+AlignVector", "-XX:+IgnoreUnrecognizedVMOptions", "-XX:+VerifyAlignVector"); } default -> { throw new RuntimeException("Test argument not recognized: " + args[0]); } } framework.start(); @@ -117,7 +137,8 @@ public TestAlignVector() { // Add all tests to list tests.put("test0", () -> { return test0(aB.clone(), bB.clone(), mB); }); - tests.put("test1", () -> { return test1(aB.clone(), bB.clone(), mB); }); + tests.put("test1a", () -> { return test1a(aB.clone(), bB.clone(), mB); }); + tests.put("test1b", () -> { return test1b(aB.clone(), bB.clone(), mB); }); tests.put("test2", () -> { return test2(aB.clone(), bB.clone(), mB); }); tests.put("test3", () -> { return test3(aB.clone(), bB.clone(), mB); }); tests.put("test4", () -> { return test4(aB.clone(), bB.clone(), mB); }); @@ -132,6 +153,7 @@ public TestAlignVector() { tests.put("test10b", () -> { return test10b(aB.clone(), bB.clone(), mB); }); tests.put("test10c", () -> { return test10c(aS.clone(), bS.clone(), mS); }); tests.put("test10d", () -> { return test10d(aS.clone(), bS.clone(), mS); }); + tests.put("test10e", () -> { return test10e(aS.clone(), bS.clone(), mS); }); tests.put("test11aB", () -> { return test11aB(aB.clone(), bB.clone(), mB); }); tests.put("test11aS", () -> { return test11aS(aS.clone(), bS.clone(), mS); }); @@ -201,7 +223,8 @@ public TestAlignVector() { @Warmup(100) @Run(test = {"test0", - "test1", + "test1a", + "test1b", "test2", "test3", "test4", @@ -214,6 +237,7 @@ public TestAlignVector() { "test10b", "test10c", "test10d", + "test10e", "test11aB", "test11aS", "test11aI", @@ -404,13 +428,37 @@ static Object[] test0(byte[] a, byte[] b, byte mask) { @IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", IRNode.AND_VB, "> 0", IRNode.STORE_VECTOR, "> 0"}, - applyIf = {"UseCompactObjectHeaders", "false"}, + applyIfOr = {"UseCompactObjectHeaders", "false", "AlignVector", "false"}, + // UNSAFE.ARRAY_BYTE_BASE_OFFSET = 16, but with compact object headers UNSAFE.ARRAY_BYTE_BASE_OFFSET=12. + // If AlignVector=true, we need the offset to be 8-byte aligned, else the vectors are filtered out. applyIfPlatform = {"64-bit", "true"}, applyIfCPUFeatureOr = {"avx2", "true", "asimd", "true"}) - static Object[] test1(byte[] a, byte[] b, byte mask) { + static Object[] test1a(byte[] a, byte[] b, byte mask) { for (int i = 0; i < RANGE; i+=8) { - // Safe to vectorize with AlignVector - b[i+0] = (byte)(a[i+0] & mask); // offset 0, align 0 + b[i+0] = (byte)(a[i+0] & mask); // adr = base + UNSAFE.ARRAY_BYTE_BASE_OFFSET + 0 + iter*8 + b[i+1] = (byte)(a[i+1] & mask); + b[i+2] = (byte)(a[i+2] & mask); + b[i+3] = (byte)(a[i+3] & mask); + b[i+4] = (byte)(a[i+4] & mask); + b[i+5] = (byte)(a[i+5] & mask); + b[i+6] = (byte)(a[i+6] & mask); + b[i+7] = (byte)(a[i+7] & mask); + } + return new Object[]{ a, b }; + } + + @Test + @IR(counts = {IRNode.LOAD_VECTOR_B, "> 0", + IRNode.AND_VB, "> 0", + IRNode.STORE_VECTOR, "> 0"}, + applyIfOr = {"UseCompactObjectHeaders", "true", "AlignVector", "false"}, + // UNSAFE.ARRAY_BYTE_BASE_OFFSET = 16, but with compact object headers UNSAFE.ARRAY_BYTE_BASE_OFFSET=12. + // If AlignVector=true, we need the offset to be 8-byte aligned, else the vectors are filtered out. + applyIfPlatform = {"64-bit", "true"}, + applyIfCPUFeatureOr = {"avx2", "true", "asimd", "true"}) + static Object[] test1b(byte[] a, byte[] b, byte mask) { + for (int i = 4; i < RANGE-8; i+=8) { + b[i+0] = (byte)(a[i+0] & mask); // adr = base + UNSAFE.ARRAY_BYTE_BASE_OFFSET + 4 + iter*8 b[i+1] = (byte)(a[i+1] & mask); b[i+2] = (byte)(a[i+2] & mask); b[i+3] = (byte)(a[i+3] & mask); @@ -714,11 +762,33 @@ static Object[] test10c(short[] a, short[] b, short mask) { IRNode.AND_VS, IRNode.VECTOR_SIZE_4, "> 0", IRNode.STORE_VECTOR, "> 0"}, applyIfAnd = {"MaxVectorSize", ">=16", "UseCompactObjectHeaders", "false"}, + // UNSAFE.ARRAY_BYTE_BASE_OFFSET = 16, but with compact object headers UNSAFE.ARRAY_BYTE_BASE_OFFSET=12. + // If AlignVector=true, we need the offset to be 8-byte aligned, else the vectors are filtered out. applyIfPlatform = {"64-bit", "true"}, applyIfCPUFeatureOr = {"avx2", "true", "asimd", "true"}) static Object[] test10d(short[] a, short[] b, short mask) { for (int i = 13; i < RANGE-16; i+=8) { - // init + offset -> aligned + // adr = base + UNSAFE.ARRAY_SHORT_BASE_OFFSET + 2*(3 + 13) + iter*16 + b[i+0+3] = (short)(a[i+0+3] & mask); + b[i+1+3] = (short)(a[i+1+3] & mask); + b[i+2+3] = (short)(a[i+2+3] & mask); + b[i+3+3] = (short)(a[i+3+3] & mask); + } + return new Object[]{ a, b }; + } + + @Test + @IR(counts = {IRNode.LOAD_VECTOR_S, IRNode.VECTOR_SIZE_4, "> 0", + IRNode.AND_VS, IRNode.VECTOR_SIZE_4, "> 0", + IRNode.STORE_VECTOR, "> 0"}, + applyIfAnd = {"MaxVectorSize", ">=16", "UseCompactObjectHeaders", "true"}, + // UNSAFE.ARRAY_BYTE_BASE_OFFSET = 16, but with compact object headers UNSAFE.ARRAY_BYTE_BASE_OFFSET=12. + // If AlignVector=true, we need the offset to be 8-byte aligned, else the vectors are filtered out. + applyIfPlatform = {"64-bit", "true"}, + applyIfCPUFeatureOr = {"avx2", "true", "asimd", "true"}) + static Object[] test10e(short[] a, short[] b, short mask) { + for (int i = 11; i < RANGE-16; i+=8) { + // adr = base + UNSAFE.ARRAY_SHORT_BASE_OFFSET + 2*(3 + 11) + iter*16 b[i+0+3] = (short)(a[i+0+3] & mask); b[i+1+3] = (short)(a[i+1+3] & mask); b[i+2+3] = (short)(a[i+2+3] & mask); @@ -1008,13 +1078,26 @@ static Object[] test13aIL(int[] a, long[] b) { IRNode.ADD_VB, "> 0", IRNode.ADD_VI, "> 0", IRNode.STORE_VECTOR, "> 0"}, - applyIf = {"UseCompactObjectHeaders", "false"}, + applyIfOr = {"UseCompactObjectHeaders", "false", "AlignVector", "false"}, applyIfPlatform = {"64-bit", "true"}, applyIfCPUFeatureOr = {"avx2", "true", "asimd", "true"}) static Object[] test13aIB(int[] a, byte[] b) { for (int i = 0; i < RANGE; i++) { + // adr = base + UNSAFE.ARRAY_BYTE_BASE_OFFSET + 1*iter + // = 16 (or 12 if UseCompactObjectHeaders=true) a[i]++; + // adr = base + UNSAFE.ARRAY_INT_BASE_OFFSET + 4*iter + // = 16 (or 12 if UseCompactObjectHeaders=true) b[i]++; + // For AlignVector, all adr must be 8-byte aligned. Let's see for which iteration this can hold: + // If UseCompactObjectHeaders=false: + // a: 0, 8, 16, 24, 32, ... + // b: 0, 2, 4, 6, 8, ... + // -> Ok, aligns every 8th iteration. + // If UseCompactObjectHeaders=true: + // a: 4, 12, 20, 28, 36, ... + // b: 1, 3, 5, 7, 9, ... + // -> we can never align both vectors! } return new Object[]{ a, b }; } @@ -1025,13 +1108,26 @@ static Object[] test13aIB(int[] a, byte[] b) { IRNode.ADD_VI, "> 0", IRNode.ADD_VS, "> 0", IRNode.STORE_VECTOR, "> 0"}, - applyIf = {"UseCompactObjectHeaders", "false"}, + applyIfOr = {"UseCompactObjectHeaders", "false", "AlignVector", "false"}, applyIfPlatform = {"64-bit", "true"}, applyIfCPUFeatureOr = {"avx2", "true", "asimd", "true"}) static Object[] test13aIS(int[] a, short[] b) { for (int i = 0; i < RANGE; i++) { + // adr = base + UNSAFE.ARRAY_BYTE_BASE_OFFSET + 4*iter + // = 16 (or 12 if UseCompactObjectHeaders=true) a[i]++; + // adr = base + UNSAFE.ARRAY_SHORT_BASE_OFFSET + 2*iter + // = 16 (or 12 if UseCompactObjectHeaders=true) b[i]++; + // For AlignVector, all adr must be 8-byte aligned. Let's see for which iteration this can hold: + // If UseCompactObjectHeaders=false: + // a: iter % 2 == 0 + // b: iter % 4 == 0 + // -> Ok, aligns every 4th iteration. + // If UseCompactObjectHeaders=true: + // a: iter % 2 = 1 + // b: iter % 4 = 2 + // -> we can never align both vectors! } return new Object[]{ a, b }; } @@ -1046,15 +1142,27 @@ static Object[] test13aIS(int[] a, short[] b) { IRNode.ADD_VI, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"}, - applyIf = {"UseCompactObjectHeaders", "false"}, + applyIfOr = {"UseCompactObjectHeaders", "false", "AlignVector", "false"}, applyIfPlatform = {"64-bit", "true"}, applyIfCPUFeatureOr = {"avx2", "true", "asimd", "true"}) static Object[] test13aBSIL(byte[] a, short[] b, int[] c, long[] d) { for (int i = 0; i < RANGE; i++) { + // adr = base + UNSAFE.ARRAY_BYTE_BASE_OFFSET + 1*iter + // = 16 (or 12 if UseCompactObjectHeaders=true) a[i]++; + // adr = base + UNSAFE.ARRAY_SHORT_BASE_OFFSET + 2*iter + // = 16 (or 12 if UseCompactObjectHeaders=true) b[i]++; + // adr = base + UNSAFE.ARRAY_INT_BASE_OFFSET + 4*iter + // = 16 (or 12 if UseCompactObjectHeaders=true) c[i]++; + // adr = base + UNSAFE.ARRAY_LONG_BASE_OFFSET + 8*iter + // = 16 (always) d[i]++; + // If AlignVector and UseCompactObjectHeaders, and we want all adr 8-byte aligned: + // a: iter % 8 = 4 + // c: iter % 2 = 1 + // -> can never align both vectors! } return new Object[]{ a, b, c, d }; } @@ -1082,13 +1190,21 @@ static Object[] test13bIL(int[] a, long[] b) { IRNode.ADD_VB, "> 0", IRNode.ADD_VI, "> 0", IRNode.STORE_VECTOR, "> 0"}, - applyIf = {"UseCompactObjectHeaders", "false"}, + applyIfOr = {"UseCompactObjectHeaders", "false", "AlignVector", "false"}, applyIfPlatform = {"64-bit", "true"}, applyIfCPUFeatureOr = {"avx2", "true", "asimd", "true"}) static Object[] test13bIB(int[] a, byte[] b) { for (int i = 1; i < RANGE; i++) { + // adr = base + UNSAFE.ARRAY_INT_BASE_OFFSET + 4 + 4*iter + // = 16 (or 12 if UseCompactObjectHeaders=true) a[i]++; + // adr = base + UNSAFE.ARRAY_BYTE_BASE_OFFSET + 1 + 1*iter + // = 16 (or 12 if UseCompactObjectHeaders=true) b[i]++; + // If AlignVector and UseCompactObjectHeaders, and we want all adr 8-byte aligned: + // a: iter % 2 = 0 + // b: iter % 8 = 3 + // -> can never align both vectors! } return new Object[]{ a, b }; } @@ -1099,13 +1215,21 @@ static Object[] test13bIB(int[] a, byte[] b) { IRNode.ADD_VI, "> 0", IRNode.ADD_VS, "> 0", IRNode.STORE_VECTOR, "> 0"}, - applyIf = {"UseCompactObjectHeaders", "false"}, + applyIfOr = {"UseCompactObjectHeaders", "false", "AlignVector", "false"}, applyIfPlatform = {"64-bit", "true"}, applyIfCPUFeatureOr = {"avx2", "true", "asimd", "true"}) static Object[] test13bIS(int[] a, short[] b) { for (int i = 1; i < RANGE; i++) { + // adr = base + UNSAFE.ARRAY_INT_BASE_OFFSET + 4 + 4*iter + // = 16 (or 12 if UseCompactObjectHeaders=true) a[i]++; + // adr = base + UNSAFE.ARRAY_SHORT_BASE_OFFSET + 2 + 2*iter + // = 16 (or 12 if UseCompactObjectHeaders=true) b[i]++; + // If AlignVector and UseCompactObjectHeaders, and we want all adr 8-byte aligned: + // a: iter % 2 = 0 + // b: iter % 4 = 1 + // -> can never align both vectors! } return new Object[]{ a, b }; } @@ -1120,15 +1244,27 @@ static Object[] test13bIS(int[] a, short[] b) { IRNode.ADD_VI, "> 0", IRNode.ADD_VL, "> 0", IRNode.STORE_VECTOR, "> 0"}, - applyIf = {"UseCompactObjectHeaders", "false"}, + applyIfOr = {"UseCompactObjectHeaders", "false", "AlignVector", "false"}, applyIfPlatform = {"64-bit", "true"}, applyIfCPUFeatureOr = {"avx2", "true", "asimd", "true"}) static Object[] test13bBSIL(byte[] a, short[] b, int[] c, long[] d) { for (int i = 1; i < RANGE; i++) { + // adr = base + UNSAFE.ARRAY_BYTE_BASE_OFFSET + 1 + 1*iter + // = 16 (or 12 if UseCompactObjectHeaders=true) a[i]++; + // adr = base + UNSAFE.ARRAY_SHORT_BASE_OFFSET + 2 + 2*iter + // = 16 (or 12 if UseCompactObjectHeaders=true) b[i]++; + // adr = base + UNSAFE.ARRAY_INT_BASE_OFFSET + 4 + 4*iter + // = 16 (or 12 if UseCompactObjectHeaders=true) c[i]++; + // adr = base + UNSAFE.ARRAY_LONG_BASE_OFFSET + 8 + 8*iter + // = 16 (always) d[i]++; + // If AlignVector and UseCompactObjectHeaders, and we want all adr 8-byte aligned: + // a: iter % 8 = 3 + // c: iter % 2 = 0 + // -> can never align both vectors! } return new Object[]{ a, b, c, d }; } diff --git a/test/hotspot/jtreg/compiler/loopopts/superword/TestIndependentPacksWithCyclicDependency.java b/test/hotspot/jtreg/compiler/loopopts/superword/TestIndependentPacksWithCyclicDependency.java index 197ae08b6d8..9edd9d28dd8 100644 --- a/test/hotspot/jtreg/compiler/loopopts/superword/TestIndependentPacksWithCyclicDependency.java +++ b/test/hotspot/jtreg/compiler/loopopts/superword/TestIndependentPacksWithCyclicDependency.java @@ -29,7 +29,10 @@ * between the packs. * @modules java.base/jdk.internal.misc * @library /test/lib / - * @run driver compiler.loopopts.superword.TestIndependentPacksWithCyclicDependency + * @run driver compiler.loopopts.superword.TestIndependentPacksWithCyclicDependency nCOH_nAV + * @run driver compiler.loopopts.superword.TestIndependentPacksWithCyclicDependency nCOH_yAV + * @run driver compiler.loopopts.superword.TestIndependentPacksWithCyclicDependency yCOH_nAV + * @run driver compiler.loopopts.superword.TestIndependentPacksWithCyclicDependency yCOH_yAV */ package compiler.loopopts.superword; @@ -72,11 +75,20 @@ public class TestIndependentPacksWithCyclicDependency { long[] goldL10 = new long[RANGE]; public static void main(String args[]) { - TestFramework.runWithFlags("--add-modules", "java.base", "--add-exports", "java.base/jdk.internal.misc=ALL-UNNAMED", - "-XX:CompileCommand=compileonly,compiler.loopopts.superword.TestIndependentPacksWithCyclicDependency::test*", - "-XX:CompileCommand=compileonly,compiler.loopopts.superword.TestIndependentPacksWithCyclicDependency::verify", - "-XX:CompileCommand=compileonly,compiler.loopopts.superword.TestIndependentPacksWithCyclicDependency::init", - "-XX:+IgnoreUnrecognizedVMOptions", "-XX:LoopUnrollLimit=1000"); + TestFramework framework = new TestFramework(TestIndependentPacksWithCyclicDependency.class); + framework.addFlags("--add-modules", "java.base", "--add-exports", "java.base/jdk.internal.misc=ALL-UNNAMED", + "-XX:CompileCommand=compileonly,compiler.loopopts.superword.TestIndependentPacksWithCyclicDependency::test*", + "-XX:CompileCommand=compileonly,compiler.loopopts.superword.TestIndependentPacksWithCyclicDependency::verify", + "-XX:CompileCommand=compileonly,compiler.loopopts.superword.TestIndependentPacksWithCyclicDependency::init", + "-XX:+IgnoreUnrecognizedVMOptions", "-XX:LoopUnrollLimit=1000"); + switch (args[0]) { + case "nCOH_nAV" -> { framework.addFlags("-XX:+UnlockExperimentalVMOptions", "-XX:-UseCompactObjectHeaders", "-XX:-AlignVector"); } + case "nCOH_yAV" -> { framework.addFlags("-XX:+UnlockExperimentalVMOptions", "-XX:-UseCompactObjectHeaders", "-XX:+AlignVector"); } + case "yCOH_nAV" -> { framework.addFlags("-XX:+UnlockExperimentalVMOptions", "-XX:+UseCompactObjectHeaders", "-XX:-AlignVector"); } + case "yCOH_yAV" -> { framework.addFlags("-XX:+UnlockExperimentalVMOptions", "-XX:+UseCompactObjectHeaders", "-XX:+AlignVector"); } + default -> { throw new RuntimeException("Test argument not recognized: " + args[0]); } + }; + framework.start(); } TestIndependentPacksWithCyclicDependency() { @@ -118,6 +130,7 @@ public void runTest0() { @Test @IR(counts = {IRNode.ADD_VI, "> 0", IRNode.MUL_VF, "> 0"}, + applyIfOr = {"UseCompactObjectHeaders", "false", "AlignVector", "false"}, applyIfPlatform = {"64-bit", "true"}, applyIfCPUFeatureOr = {"sse4.1", "true", "asimd", "true"}) static void test0(int[] dataIa, int[] dataIb, float[] dataFa, float[] dataFb) { @@ -127,6 +140,10 @@ static void test0(int[] dataIa, int[] dataIb, float[] dataFa, float[] dataFb) { dataIb[i+1] = dataIa[i+1] + 3; dataFb[i+0] = dataFa[i+0] * 1.3f; dataFb[i+1] = dataFa[i+1] * 1.3f; + // With AlignVector, we need 8-byte alignment of vector loads/stores. + // UseCompactObjectHeaders=false UseCompactObjectHeaders=true + // adr = base + 16 + 8*i -> always adr = base + 12 + 8*i -> never + // -> vectorize -> no vectorization } } @@ -143,6 +160,7 @@ public void runTest1() { @Test @IR(counts = {IRNode.ADD_VI, "> 0", IRNode.MUL_VF, "> 0", IRNode.VECTOR_CAST_F2I, "> 0", IRNode.VECTOR_CAST_I2F, "> 0"}, + applyIfOr = {"UseCompactObjectHeaders", "false", "AlignVector", "false"}, applyIfPlatform = {"64-bit", "true"}, applyIfCPUFeatureOr = {"avx2", "true", "asimd", "true"}) static void test1(int[] dataIa, int[] dataIb, float[] dataFa, float[] dataFb) { @@ -152,6 +170,10 @@ static void test1(int[] dataIa, int[] dataIb, float[] dataFa, float[] dataFb) { dataFa[i+1] = dataIa[i+1] + 3; dataIb[i+0] = (int)(dataFb[i+0] * 1.3f); dataIb[i+1] = (int)(dataFb[i+1] * 1.3f); + // With AlignVector, we need 8-byte alignment of vector loads/stores. + // UseCompactObjectHeaders=false UseCompactObjectHeaders=true + // adr = base + 16 + 8*i -> always adr = base + 12 + 8*i -> never + // -> vectorize -> no vectorization } } @@ -167,6 +189,7 @@ public void runTest2() { @Test @IR(counts = {IRNode.ADD_VI, "> 0", IRNode.MUL_VI, "> 0"}, + applyIfOr = {"UseCompactObjectHeaders", "false", "AlignVector", "false"}, applyIfPlatform = {"64-bit", "true"}, applyIfCPUFeatureOr = {"sse4.1", "true", "asimd", "true"}) static void test2(int[] dataIa, int[] dataIb, float[] dataFa, float[] dataFb) { @@ -176,6 +199,10 @@ static void test2(int[] dataIa, int[] dataIb, float[] dataFa, float[] dataFb) { unsafe.putInt(dataFa, unsafe.ARRAY_FLOAT_BASE_OFFSET + 4L * i + 4, dataIa[i+1] + 1); dataIb[i+0] = 11 * unsafe.getInt(dataFb, unsafe.ARRAY_INT_BASE_OFFSET + 4L * i + 0); dataIb[i+1] = 11 * unsafe.getInt(dataFb, unsafe.ARRAY_INT_BASE_OFFSET + 4L * i + 4); + // With AlignVector, we need 8-byte alignment of vector loads/stores. + // UseCompactObjectHeaders=false UseCompactObjectHeaders=true + // adr = base + 16 + 8*i -> always adr = base + 12 + 8*i -> never + // -> vectorize -> no vectorization } } @@ -192,6 +219,7 @@ public void runTest3() { @Test @IR(counts = {IRNode.ADD_VI, "> 0", IRNode.MUL_VF, "> 0"}, + applyIfOr = {"UseCompactObjectHeaders", "false", "AlignVector", "false"}, applyIfPlatform = {"64-bit", "true"}, applyIfCPUFeatureOr = {"sse4.1", "true", "asimd", "true"}) static void test3(int[] dataIa, int[] dataIb, float[] dataFa, float[] dataFb) { @@ -203,6 +231,10 @@ static void test3(int[] dataIa, int[] dataIb, float[] dataFa, float[] dataFb) { dataFb[i+1] = dataFa[i+1] * 1.3f; dataFb[i+0] = dataFa[i+0] * 1.3f; dataIb[i+1] = dataIa[i+1] + 3; + // With AlignVector, we need 8-byte alignment of vector loads/stores. + // UseCompactObjectHeaders=false UseCompactObjectHeaders=true + // adr = base + 16 + 8*i -> always adr = base + 12 + 8*i -> never + // -> vectorize -> no vectorization } } @@ -269,6 +301,7 @@ public void runTest6() { @Test @IR(counts = {IRNode.ADD_VI, "> 0", IRNode.MUL_VI, "> 0", IRNode.ADD_VF, "> 0"}, + applyIfOr = {"UseCompactObjectHeaders", "false", "AlignVector", "false"}, applyIfPlatform = {"64-bit", "true"}, applyIfCPUFeatureOr = {"sse4.1", "true", "asimd", "true"}) static void test6(int[] dataIa, int[] dataIb, float[] dataFa, float[] dataFb, @@ -287,6 +320,10 @@ static void test6(int[] dataIa, int[] dataIb, float[] dataFa, float[] dataFb, float v21 = unsafe.getFloat(dataLb, unsafe.ARRAY_LONG_BASE_OFFSET + 4L * i + 4) + 0.55f; unsafe.putFloat(dataIb, unsafe.ARRAY_INT_BASE_OFFSET + 4L * i + 0, v20); unsafe.putFloat(dataIb, unsafe.ARRAY_INT_BASE_OFFSET + 4L * i + 4, v21); + // With AlignVector, we need 8-byte alignment of vector loads/stores. + // UseCompactObjectHeaders=false UseCompactObjectHeaders=true + // adr = base + 16 + 8*i -> always adr = base + 12 + 8*i -> never + // -> vectorize -> no vectorization } } diff --git a/test/hotspot/jtreg/compiler/loopopts/superword/TestMulAddS2I.java b/test/hotspot/jtreg/compiler/loopopts/superword/TestMulAddS2I.java index 9aaa7cdd8a9..5c7ff6c524d 100644 --- a/test/hotspot/jtreg/compiler/loopopts/superword/TestMulAddS2I.java +++ b/test/hotspot/jtreg/compiler/loopopts/superword/TestMulAddS2I.java @@ -77,8 +77,10 @@ public class TestMulAddS2I { public static void main(String[] args) { - TestFramework.runWithFlags("-XX:+IgnoreUnrecognizedVMOptions", "-XX:+AlignVector"); - TestFramework.runWithFlags("-XX:+IgnoreUnrecognizedVMOptions", "-XX:-AlignVector"); + TestFramework.runWithFlags("-XX:+IgnoreUnrecognizedVMOptions", "-XX:-AlignVector", "-XX:+UnlockExperimentalVMOptions", "-XX:-UseCompactObjectHeaers"); + TestFramework.runWithFlags("-XX:+IgnoreUnrecognizedVMOptions", "-XX:+AlignVector", "-XX:+UnlockExperimentalVMOptions", "-XX:-UseCompactObjectHeaers"); + TestFramework.runWithFlags("-XX:+IgnoreUnrecognizedVMOptions", "-XX:-AlignVector", "-XX:+UnlockExperimentalVMOptions", "-XX:+UseCompactObjectHeaers"); + TestFramework.runWithFlags("-XX:+IgnoreUnrecognizedVMOptions", "-XX:+AlignVector", "-XX:+UnlockExperimentalVMOptions", "-XX:+UseCompactObjectHeaers"); } @Run(test = {"testa", "testb", "testc", "testd", "teste", "testf", "testg", "testh", @@ -163,19 +165,26 @@ public static int[] testc(int[] out) { @Test @IR(applyIfCPUFeature = {"sse2", "true"}, applyIfPlatform = {"64-bit", "true"}, - applyIf = { "UseCompactObjectHeaders", "false" }, + applyIfOr = { "UseCompactObjectHeaders", "false", "AlignVector", "false" }, counts = {IRNode.MUL_ADD_S2I, "> 0", IRNode.MUL_ADD_VS2VI, "> 0"}) @IR(applyIfCPUFeature = {"asimd", "true"}, applyIfAnd = {"MaxVectorSize", "16", "UseCompactObjectHeaders", "false"}, // AD file requires vector_length = 16 counts = {IRNode.MUL_ADD_S2I, "> 0", IRNode.MUL_ADD_VS2VI, "> 0"}) @IR(applyIfCPUFeature = {"avx512_vnni", "true"}, - applyIf = { "UseCompactObjectHeaders", "false" }, + applyIfOr = { "UseCompactObjectHeaders", "false", "AlignVector", "false" }, counts = {IRNode.MUL_ADD_S2I, "> 0", IRNode.MUL_ADD_VS2VI_VNNI, "> 0"}) public static int[] testd(int[] out) { for (int i = 0; i < ITER-2; i+=2) { // Unrolled, with the same structure. out[i+0] += ((sArr1[2*i+0] * sArr2[2*i+0]) + (sArr1[2*i+1] * sArr2[2*i+1])); out[i+1] += ((sArr1[2*i+2] * sArr2[2*i+2]) + (sArr1[2*i+3] * sArr2[2*i+3])); + // Hand-unrolling can mess with AlignVector and UseCompactObjectHeaders. + // We need all addresses 8-byte aligned. + // + // out: + // adr = base + UNSAFE.ARRAY_INT_BASE_OFFSET + 8*iter + // = 16 (or 12 if UseCompactObjectHeaders=true) + // -> never aligned! } return out; } @@ -183,19 +192,26 @@ public static int[] testd(int[] out) { @Test @IR(applyIfCPUFeature = {"sse2", "true"}, applyIfPlatform = {"64-bit", "true"}, - applyIf = { "UseCompactObjectHeaders", "false" }, + applyIfOr = { "UseCompactObjectHeaders", "false", "AlignVector", "false" }, counts = {IRNode.MUL_ADD_S2I, "> 0", IRNode.MUL_ADD_VS2VI, "> 0"}) @IR(applyIfCPUFeature = {"asimd", "true"}, applyIfAnd = {"MaxVectorSize", "16", "UseCompactObjectHeaders", "false" }, // AD file requires vector_length = 16 counts = {IRNode.MUL_ADD_S2I, "> 0", IRNode.MUL_ADD_VS2VI, "> 0"}) @IR(applyIfCPUFeature = {"avx512_vnni", "true"}, - applyIf = { "UseCompactObjectHeaders", "false" }, + applyIfOr = { "UseCompactObjectHeaders", "false", "AlignVector", "false" }, counts = {IRNode.MUL_ADD_S2I, "> 0", IRNode.MUL_ADD_VS2VI_VNNI, "> 0"}) public static int[] teste(int[] out) { for (int i = 0; i < ITER-2; i+=2) { // Unrolled, with some swaps. out[i+0] += ((sArr1[2*i+0] * sArr2[2*i+0]) + (sArr1[2*i+1] * sArr2[2*i+1])); out[i+1] += ((sArr2[2*i+2] * sArr1[2*i+2]) + (sArr1[2*i+3] * sArr2[2*i+3])); // swap(1 2) + // Hand-unrolling can mess with AlignVector and UseCompactObjectHeaders. + // We need all addresses 8-byte aligned. + // + // out: + // adr = base + UNSAFE.ARRAY_INT_BASE_OFFSET + 8*iter + // = 16 (or 12 if UseCompactObjectHeaders=true) + // -> never aligned! } return out; } @@ -203,19 +219,26 @@ public static int[] teste(int[] out) { @Test @IR(applyIfCPUFeature = {"sse2", "true"}, applyIfPlatform = {"64-bit", "true"}, - applyIf = { "UseCompactObjectHeaders", "false" }, + applyIfOr = { "UseCompactObjectHeaders", "false", "AlignVector", "false" }, counts = {IRNode.MUL_ADD_S2I, "> 0", IRNode.MUL_ADD_VS2VI, "> 0"}) @IR(applyIfCPUFeature = {"asimd", "true"}, applyIfAnd = {"MaxVectorSize", "16", "UseCompactObjectHeaders", "false" }, // AD file requires vector_length = 16 counts = {IRNode.MUL_ADD_S2I, "> 0", IRNode.MUL_ADD_VS2VI, "> 0"}) @IR(applyIfCPUFeature = {"avx512_vnni", "true"}, - applyIf = { "UseCompactObjectHeaders", "false" }, + applyIfOr = { "UseCompactObjectHeaders", "false", "AlignVector", "false" }, counts = {IRNode.MUL_ADD_S2I, "> 0", IRNode.MUL_ADD_VS2VI_VNNI, "> 0"}) public static int[] testf(int[] out) { for (int i = 0; i < ITER-2; i+=2) { // Unrolled, with some swaps. out[i+0] += ((sArr1[2*i+0] * sArr2[2*i+0]) + (sArr1[2*i+1] * sArr2[2*i+1])); out[i+1] += ((sArr2[2*i+2] * sArr1[2*i+2]) + (sArr2[2*i+3] * sArr1[2*i+3])); // swap(1 2), swap(3 4) + // Hand-unrolling can mess with AlignVector and UseCompactObjectHeaders. + // We need all addresses 8-byte aligned. + // + // out: + // adr = base + UNSAFE.ARRAY_INT_BASE_OFFSET + 8*iter + // = 16 (or 12 if UseCompactObjectHeaders=true) + // -> never aligned! } return out; } @@ -223,19 +246,26 @@ public static int[] testf(int[] out) { @Test @IR(applyIfCPUFeature = {"sse2", "true"}, applyIfPlatform = {"64-bit", "true"}, - applyIf = { "UseCompactObjectHeaders", "false" }, + applyIfOr = { "UseCompactObjectHeaders", "false", "AlignVector", "false" }, counts = {IRNode.MUL_ADD_S2I, "> 0", IRNode.MUL_ADD_VS2VI, "> 0"}) @IR(applyIfCPUFeature = {"asimd", "true"}, applyIfAnd = {"MaxVectorSize", "16", "UseCompactObjectHeaders", "false" }, // AD file requires vector_length = 16 counts = {IRNode.MUL_ADD_S2I, "> 0", IRNode.MUL_ADD_VS2VI, "> 0"}) @IR(applyIfCPUFeature = {"avx512_vnni", "true"}, - applyIf = { "UseCompactObjectHeaders", "false" }, + applyIfOr = { "UseCompactObjectHeaders", "false", "AlignVector", "false" }, counts = {IRNode.MUL_ADD_S2I, "> 0", IRNode.MUL_ADD_VS2VI_VNNI, "> 0"}) public static int[] testg(int[] out) { for (int i = 0; i < ITER-2; i+=2) { // Unrolled, with some swaps. out[i+0] += ((sArr1[2*i+0] * sArr2[2*i+0]) + (sArr1[2*i+1] * sArr2[2*i+1])); out[i+1] += ((sArr1[2*i+3] * sArr2[2*i+3]) + (sArr1[2*i+2] * sArr2[2*i+2])); // swap(1 3), swap(2 4) + // Hand-unrolling can mess with AlignVector and UseCompactObjectHeaders. + // We need all addresses 8-byte aligned. + // + // out: + // adr = base + UNSAFE.ARRAY_INT_BASE_OFFSET + 8*iter + // = 16 (or 12 if UseCompactObjectHeaders=true) + // -> never aligned! } return out; } @@ -243,19 +273,26 @@ public static int[] testg(int[] out) { @Test @IR(applyIfCPUFeature = {"sse2", "true"}, applyIfPlatform = {"64-bit", "true"}, - applyIf = { "UseCompactObjectHeaders", "false" }, + applyIfOr = { "UseCompactObjectHeaders", "false", "AlignVector", "false" }, counts = {IRNode.MUL_ADD_S2I, "> 0", IRNode.MUL_ADD_VS2VI, "> 0"}) @IR(applyIfCPUFeature = {"asimd", "true"}, applyIfAnd = {"MaxVectorSize", "16", "UseCompactObjectHeaders", "false" }, // AD file requires vector_length = 16 counts = {IRNode.MUL_ADD_S2I, "> 0", IRNode.MUL_ADD_VS2VI, "> 0"}) @IR(applyIfCPUFeature = {"avx512_vnni", "true"}, - applyIf = { "UseCompactObjectHeaders", "false" }, + applyIfOr = { "UseCompactObjectHeaders", "false", "AlignVector", "false" }, counts = {IRNode.MUL_ADD_S2I, "> 0", IRNode.MUL_ADD_VS2VI_VNNI, "> 0"}) public static int[] testh(int[] out) { for (int i = 0; i < ITER-2; i+=2) { // Unrolled, with some swaps. out[i+0] += ((sArr1[2*i+0] * sArr2[2*i+0]) + (sArr1[2*i+1] * sArr2[2*i+1])); out[i+1] += ((sArr2[2*i+3] * sArr1[2*i+3]) + (sArr2[2*i+2] * sArr1[2*i+2])); // swap(1 4), swap(2 3) + // Hand-unrolling can mess with AlignVector and UseCompactObjectHeaders. + // We need all addresses 8-byte aligned. + // + // out: + // adr = base + UNSAFE.ARRAY_INT_BASE_OFFSET + 8*iter + // = 16 (or 12 if UseCompactObjectHeaders=true) + // -> never aligned! } return out; } diff --git a/test/hotspot/jtreg/compiler/loopopts/superword/TestScheduleReordersScalarMemops.java b/test/hotspot/jtreg/compiler/loopopts/superword/TestScheduleReordersScalarMemops.java index c54a684c691..0512442c896 100644 --- a/test/hotspot/jtreg/compiler/loopopts/superword/TestScheduleReordersScalarMemops.java +++ b/test/hotspot/jtreg/compiler/loopopts/superword/TestScheduleReordersScalarMemops.java @@ -30,7 +30,10 @@ * be reordered during SuperWord::schedule. * @modules java.base/jdk.internal.misc * @library /test/lib / - * @run driver compiler.loopopts.superword.TestScheduleReordersScalarMemops + * @run driver compiler.loopopts.superword.TestScheduleReordersScalarMemops nCOH_nAV + * @run driver compiler.loopopts.superword.TestScheduleReordersScalarMemops nCOH_yAV + * @run driver compiler.loopopts.superword.TestScheduleReordersScalarMemops yCOH_nAV + * @run driver compiler.loopopts.superword.TestScheduleReordersScalarMemops yCOH_yAV */ package compiler.loopopts.superword; @@ -50,12 +53,21 @@ public class TestScheduleReordersScalarMemops { float[] goldF1 = new float[RANGE]; public static void main(String args[]) { - TestFramework.runWithFlags("--add-modules", "java.base", "--add-exports", "java.base/jdk.internal.misc=ALL-UNNAMED", - "-XX:CompileCommand=compileonly,compiler.loopopts.superword.TestScheduleReordersScalarMemops::test*", - "-XX:CompileCommand=compileonly,compiler.loopopts.superword.TestScheduleReordersScalarMemops::verify", - "-XX:CompileCommand=compileonly,compiler.loopopts.superword.TestScheduleReordersScalarMemops::init", - "-XX:-TieredCompilation", "-Xbatch", - "-XX:+IgnoreUnrecognizedVMOptions", "-XX:LoopUnrollLimit=1000"); + TestFramework framework = new TestFramework(TestScheduleReordersScalarMemops.class); + framework.addFlags("--add-modules", "java.base", "--add-exports", "java.base/jdk.internal.misc=ALL-UNNAMED", + "-XX:CompileCommand=compileonly,compiler.loopopts.superword.TestScheduleReordersScalarMemops::test*", + "-XX:CompileCommand=compileonly,compiler.loopopts.superword.TestScheduleReordersScalarMemops::verify", + "-XX:CompileCommand=compileonly,compiler.loopopts.superword.TestScheduleReordersScalarMemops::init", + "-XX:-TieredCompilation", "-Xbatch", + "-XX:+IgnoreUnrecognizedVMOptions", "-XX:LoopUnrollLimit=1000"); + switch (args[0]) { + case "nCOH_nAV" -> { framework.addFlags("-XX:+UnlockExperimentalVMOptions", "-XX:-UseCompactObjectHeaders", "-XX:-AlignVector"); } + case "nCOH_yAV" -> { framework.addFlags("-XX:+UnlockExperimentalVMOptions", "-XX:-UseCompactObjectHeaders", "-XX:+AlignVector"); } + case "yCOH_nAV" -> { framework.addFlags("-XX:+UnlockExperimentalVMOptions", "-XX:+UseCompactObjectHeaders", "-XX:-AlignVector"); } + case "yCOH_yAV" -> { framework.addFlags("-XX:+UnlockExperimentalVMOptions", "-XX:+UseCompactObjectHeaders", "-XX:+AlignVector"); } + default -> { throw new RuntimeException("Test argument not recognized: " + args[0]); } + }; + framework.start(); } TestScheduleReordersScalarMemops() { @@ -79,6 +91,7 @@ public void runTest0() { @Test @IR(counts = {IRNode.MUL_VI, "> 0"}, + applyIfOr = {"UseCompactObjectHeaders", "false", "AlignVector", "false"}, applyIfCPUFeatureOr = {"avx2", "true", "asimd", "true"}) static void test0(int[] dataIa, int[] dataIb, float[] dataFa, float[] dataFb) { for (int i = 0; i < RANGE; i+=2) { @@ -103,6 +116,10 @@ static void test0(int[] dataIa, int[] dataIb, float[] dataFa, float[] dataFb) { dataIb[i + 0] = (int)dataFb[i + 0] * 11; // X *11 dataIb[i + 1] = (int)dataFb[i + 1] * 11; // Y *11 dataFa[i + 1] = dataIa[i + 1] + 1.2f; // B +1.2 + // With AlignVector, we need 8-byte alignment of vector loads/stores. + // UseCompactObjectHeaders=false UseCompactObjectHeaders=true + // adr = base + 16 + 8*i -> always adr = base + 12 + 8*i -> never + // -> vectorize -> no vectorization } } @@ -119,6 +136,7 @@ public void runTest1() { @Test @IR(counts = {IRNode.MUL_VI, "> 0"}, + applyIfOr = {"UseCompactObjectHeaders", "false", "AlignVector", "false"}, applyIfCPUFeatureOr = {"avx2", "true", "asimd", "true"}) static void test1(int[] dataIa, int[] dataIb, float[] dataFa, float[] dataFb) { for (int i = 0; i < RANGE; i+=2) { @@ -128,6 +146,10 @@ static void test1(int[] dataIa, int[] dataIb, float[] dataFa, float[] dataFb) { dataIb[i+0] = 11 * unsafe.getInt(dataFb, unsafe.ARRAY_INT_BASE_OFFSET + 4L * i + 0); // X dataIb[i+1] = 11 * unsafe.getInt(dataFb, unsafe.ARRAY_INT_BASE_OFFSET + 4L * i + 4); // Y unsafe.putInt(dataFa, unsafe.ARRAY_FLOAT_BASE_OFFSET + 4L * i + 4, dataIa[i+1] * 11); // B *11 + // With AlignVector, we need 8-byte alignment of vector loads/stores. + // UseCompactObjectHeaders=false UseCompactObjectHeaders=true + // adr = base + 16 + 8*i -> always adr = base + 12 + 8*i -> never + // -> vectorize -> no vectorization } } diff --git a/test/hotspot/jtreg/compiler/loopopts/superword/TestSplitPacks.java b/test/hotspot/jtreg/compiler/loopopts/superword/TestSplitPacks.java index 1824f18c8ff..bd47f7b9331 100644 --- a/test/hotspot/jtreg/compiler/loopopts/superword/TestSplitPacks.java +++ b/test/hotspot/jtreg/compiler/loopopts/superword/TestSplitPacks.java @@ -37,7 +37,10 @@ * @bug 8326139 * @summary Test splitting packs in SuperWord * @library /test/lib / - * @run driver compiler.loopopts.superword.TestSplitPacks + * @run driver compiler.loopopts.superword.TestSplitPacks nCOH_nAV + * @run driver compiler.loopopts.superword.TestSplitPacks nCOH_yAV + * @run driver compiler.loopopts.superword.TestSplitPacks yCOH_nAV + * @run driver compiler.loopopts.superword.TestSplitPacks yCOH_yAV */ public class TestSplitPacks { @@ -70,7 +73,16 @@ interface TestFunction { } public static void main(String[] args) { - TestFramework.runWithFlags("-XX:+IgnoreUnrecognizedVMOptions", "-XX:LoopUnrollLimit=1000"); + TestFramework framework = new TestFramework(TestSplitPacks.class); + framework.addFlags("-XX:+IgnoreUnrecognizedVMOptions", "-XX:LoopUnrollLimit=1000"); + switch (args[0]) { + case "nCOH_nAV" -> { framework.addFlags("-XX:+UnlockExperimentalVMOptions", "-XX:-UseCompactObjectHeaders", "-XX:-AlignVector"); } + case "nCOH_yAV" -> { framework.addFlags("-XX:+UnlockExperimentalVMOptions", "-XX:-UseCompactObjectHeaders", "-XX:+AlignVector"); } + case "yCOH_nAV" -> { framework.addFlags("-XX:+UnlockExperimentalVMOptions", "-XX:+UseCompactObjectHeaders", "-XX:-AlignVector"); } + case "yCOH_yAV" -> { framework.addFlags("-XX:+UnlockExperimentalVMOptions", "-XX:+UseCompactObjectHeaders", "-XX:+AlignVector"); } + default -> { throw new RuntimeException("Test argument not recognized: " + args[0]); } + }; + framework.start(); } public TestSplitPacks() { @@ -266,7 +278,15 @@ static void verifyL(String name, int i, long[] g, long[] r) { IRNode.AND_VI, IRNode.VECTOR_SIZE_2, "> 0", IRNode.AND_VI, IRNode.VECTOR_SIZE_4, "> 0", IRNode.STORE_VECTOR, "> 0"}, - applyIf = {"MaxVectorSize", ">=32"}, + applyIfAnd = {"MaxVectorSize", ">=32", "AlignVector", "false"}, + applyIfPlatform = {"64-bit", "true"}, + applyIfCPUFeatureOr = {"sse4.1", "true", "asimd", "true"}) + @IR(counts = {IRNode.LOAD_VECTOR_I, IRNode.VECTOR_SIZE_2, "> 0", + IRNode.LOAD_VECTOR_I, IRNode.VECTOR_SIZE_4, "> 0", + IRNode.AND_VI, IRNode.VECTOR_SIZE_2, "> 0", + IRNode.AND_VI, IRNode.VECTOR_SIZE_4, "> 0", + IRNode.STORE_VECTOR, "> 0"}, + applyIfAnd = {"MaxVectorSize", ">=32", "UseCompactObjectHeaders", "false"}, applyIfPlatform = {"64-bit", "true"}, applyIfCPUFeatureOr = {"sse4.1", "true", "asimd", "true"}) // Load and store are already split @@ -291,6 +311,10 @@ static Object[] test0(int[] a, int[] b, int mask) { b[i+5] = b5; b[i+6] = b6; b[i+7] = b7; + // With AlignVector, we need 8-byte alignment of vector loads/stores. + // UseCompactObjectHeaders=false UseCompactObjectHeaders=true + // adr = base + 16 + 32*i -> always adr = base + 12 + 32*i -> never + // -> vectorize -> no vectorization } return new Object[]{ a, b }; } @@ -301,7 +325,15 @@ static Object[] test0(int[] a, int[] b, int mask) { IRNode.ADD_VI, IRNode.VECTOR_SIZE_4, "> 0", IRNode.MUL_VI, IRNode.VECTOR_SIZE_2, "> 0", IRNode.STORE_VECTOR, "> 0"}, - applyIf = {"MaxVectorSize", ">=32"}, + applyIfAnd = {"MaxVectorSize", ">=32", "AlignVector", "false"}, + applyIfPlatform = {"64-bit", "true"}, + applyIfCPUFeatureOr = {"sse4.1", "true", "asimd", "true"}) + @IR(counts = {IRNode.LOAD_VECTOR_I, IRNode.VECTOR_SIZE_2, "> 0", + IRNode.LOAD_VECTOR_I, IRNode.VECTOR_SIZE_4, "> 0", + IRNode.ADD_VI, IRNode.VECTOR_SIZE_4, "> 0", + IRNode.MUL_VI, IRNode.VECTOR_SIZE_2, "> 0", + IRNode.STORE_VECTOR, "> 0"}, + applyIfAnd = {"MaxVectorSize", ">=32", "UseCompactObjectHeaders", "false"}, applyIfPlatform = {"64-bit", "true"}, applyIfCPUFeatureOr = {"sse4.1", "true", "asimd", "true"}) // Adjacent Load and Store, but split by Add/Mul @@ -314,6 +346,10 @@ static Object[] test1a(int[] a, int[] b, int mask) { b[i+4] = a[i+4] * mask; // Mul b[i+5] = a[i+5] * mask; + // With AlignVector, we need 8-byte alignment of vector loads/stores. + // UseCompactObjectHeaders=false UseCompactObjectHeaders=true + // adr = base + 16 + 32*i -> always adr = base + 12 + 32*i -> never + // -> vectorize -> no vectorization } return new Object[]{ a, b }; } @@ -324,7 +360,15 @@ static Object[] test1a(int[] a, int[] b, int mask) { IRNode.ADD_VI, IRNode.VECTOR_SIZE_2, "> 0", IRNode.MUL_VI, IRNode.VECTOR_SIZE_4, "> 0", IRNode.STORE_VECTOR, "> 0"}, - applyIf = {"MaxVectorSize", ">=32"}, + applyIfAnd = {"MaxVectorSize", ">=32", "AlignVector", "false"}, + applyIfPlatform = {"64-bit", "true"}, + applyIfCPUFeatureOr = {"sse4.1", "true", "asimd", "true"}) + @IR(counts = {IRNode.LOAD_VECTOR_I, IRNode.VECTOR_SIZE_2, "> 0", + IRNode.LOAD_VECTOR_I, IRNode.VECTOR_SIZE_4, "> 0", + IRNode.ADD_VI, IRNode.VECTOR_SIZE_2, "> 0", + IRNode.MUL_VI, IRNode.VECTOR_SIZE_4, "> 0", + IRNode.STORE_VECTOR, "> 0"}, + applyIfAnd = {"MaxVectorSize", ">=32", "UseCompactObjectHeaders", "false"}, applyIfPlatform = {"64-bit", "true"}, applyIfCPUFeatureOr = {"sse4.1", "true", "asimd", "true"}) // Adjacent Load and Store, but split by Add/Mul @@ -337,6 +381,10 @@ static Object[] test1b(int[] a, int[] b, int mask) { b[i+4] = a[i+4] + mask; // Add b[i+5] = a[i+5] + mask; + // With AlignVector, we need 8-byte alignment of vector loads/stores. + // UseCompactObjectHeaders=false UseCompactObjectHeaders=true + // adr = base + 16 + 32*i -> always adr = base + 12 + 32*i -> never + // -> vectorize -> no vectorization } return new Object[]{ a, b }; } @@ -347,7 +395,15 @@ static Object[] test1b(int[] a, int[] b, int mask) { IRNode.ADD_VI, IRNode.VECTOR_SIZE_2, "> 0", IRNode.MUL_VI, IRNode.VECTOR_SIZE_4, "> 0", IRNode.STORE_VECTOR, "> 0"}, - applyIf = {"MaxVectorSize", ">=32"}, + applyIfAnd = {"MaxVectorSize", ">=32", "AlignVector", "false"}, + applyIfPlatform = {"64-bit", "true"}, + applyIfCPUFeatureOr = {"avx2", "true", "asimd", "true"}) + @IR(counts = {IRNode.LOAD_VECTOR_I, IRNode.VECTOR_SIZE_2, "> 0", + IRNode.LOAD_VECTOR_I, IRNode.VECTOR_SIZE_4, "> 0", + IRNode.ADD_VI, IRNode.VECTOR_SIZE_2, "> 0", + IRNode.MUL_VI, IRNode.VECTOR_SIZE_4, "> 0", + IRNode.STORE_VECTOR, "> 0"}, + applyIfAnd = {"MaxVectorSize", ">=32", "UseCompactObjectHeaders", "false"}, applyIfPlatform = {"64-bit", "true"}, applyIfCPUFeatureOr = {"avx2", "true", "asimd", "true"}) // Adjacent Load and Store, but split by Add/Mul @@ -360,6 +416,10 @@ static Object[] test1c(int[] a, int[] b, int mask) { b[i+3] = a[i+3] * mask; b[i+4] = a[i+4] * mask; b[i+5] = a[i+5] * mask; + // With AlignVector, we need 8-byte alignment of vector loads/stores. + // UseCompactObjectHeaders=false UseCompactObjectHeaders=true + // adr = base + 16 + 32*i -> always adr = base + 12 + 32*i -> never + // -> vectorize -> no vectorization } return new Object[]{ a, b }; } @@ -370,7 +430,15 @@ static Object[] test1c(int[] a, int[] b, int mask) { IRNode.ADD_VI, IRNode.VECTOR_SIZE_4, "> 0", IRNode.MUL_VI, IRNode.VECTOR_SIZE_2, "> 0", IRNode.STORE_VECTOR, "> 0"}, - applyIf = {"MaxVectorSize", ">=32"}, + applyIfAnd = {"MaxVectorSize", ">=32", "AlignVector", "false"}, + applyIfPlatform = {"64-bit", "true"}, + applyIfCPUFeatureOr = {"avx2", "true", "asimd", "true"}) + @IR(counts = {IRNode.LOAD_VECTOR_I, IRNode.VECTOR_SIZE_2, "> 0", + IRNode.LOAD_VECTOR_I, IRNode.VECTOR_SIZE_4, "> 0", + IRNode.ADD_VI, IRNode.VECTOR_SIZE_4, "> 0", + IRNode.MUL_VI, IRNode.VECTOR_SIZE_2, "> 0", + IRNode.STORE_VECTOR, "> 0"}, + applyIfAnd = {"MaxVectorSize", ">=32", "UseCompactObjectHeaders", "false"}, applyIfPlatform = {"64-bit", "true"}, applyIfCPUFeatureOr = {"avx2", "true", "asimd", "true"}) // Adjacent Load and Store, but split by Add/Mul @@ -383,6 +451,10 @@ static Object[] test1d(int[] a, int[] b, int mask) { b[i+3] = a[i+3] + mask; b[i+4] = a[i+4] + mask; b[i+5] = a[i+5] + mask; + // With AlignVector, we need 8-byte alignment of vector loads/stores. + // UseCompactObjectHeaders=false UseCompactObjectHeaders=true + // adr = base + 16 + 32*i -> always adr = base + 12 + 32*i -> never + // -> vectorize -> no vectorization } return new Object[]{ a, b }; } @@ -393,7 +465,15 @@ static Object[] test1d(int[] a, int[] b, int mask) { IRNode.AND_VI, IRNode.VECTOR_SIZE_2, "> 0", IRNode.AND_VI, IRNode.VECTOR_SIZE_4, "> 0", IRNode.STORE_VECTOR, "> 0"}, - applyIf = {"MaxVectorSize", ">=32"}, + applyIfAnd = {"MaxVectorSize", ">=32", "AlignVector", "false"}, + applyIfPlatform = {"64-bit", "true"}, + applyIfCPUFeatureOr = {"sse4.1", "true", "asimd", "true"}) + @IR(counts = {IRNode.LOAD_VECTOR_I, IRNode.VECTOR_SIZE_2, "> 0", + IRNode.LOAD_VECTOR_I, IRNode.VECTOR_SIZE_4, "> 0", + IRNode.AND_VI, IRNode.VECTOR_SIZE_2, "> 0", + IRNode.AND_VI, IRNode.VECTOR_SIZE_4, "> 0", + IRNode.STORE_VECTOR, "> 0"}, + applyIfAnd = {"MaxVectorSize", ">=32", "UseCompactObjectHeaders", "false"}, applyIfPlatform = {"64-bit", "true"}, applyIfCPUFeatureOr = {"sse4.1", "true", "asimd", "true"}) // Split the load @@ -420,6 +500,10 @@ static Object[] test2a(int[] a, int[] b, int mask) { b[i+5] = b3; b[i+6] = b4; b[i+7] = b5; + // With AlignVector, we need 8-byte alignment of vector loads/stores. + // UseCompactObjectHeaders=false UseCompactObjectHeaders=true + // adr = base + 16 + 32*i -> always adr = base + 12 + 32*i -> never + // -> vectorize -> no vectorization } return new Object[]{ a, b }; } @@ -430,7 +514,15 @@ static Object[] test2a(int[] a, int[] b, int mask) { IRNode.AND_VI, IRNode.VECTOR_SIZE_2, "> 0", IRNode.AND_VI, IRNode.VECTOR_SIZE_4, "> 0", IRNode.STORE_VECTOR, "> 0"}, - applyIf = {"MaxVectorSize", ">=32"}, + applyIfAnd = {"MaxVectorSize", ">=32", "AlignVector", "false"}, + applyIfPlatform = {"64-bit", "true"}, + applyIfCPUFeatureOr = {"sse4.1", "true", "asimd", "true"}) + @IR(counts = {IRNode.LOAD_VECTOR_I, IRNode.VECTOR_SIZE_2, "> 0", + IRNode.LOAD_VECTOR_I, IRNode.VECTOR_SIZE_4, "> 0", + IRNode.AND_VI, IRNode.VECTOR_SIZE_2, "> 0", + IRNode.AND_VI, IRNode.VECTOR_SIZE_4, "> 0", + IRNode.STORE_VECTOR, "> 0"}, + applyIfAnd = {"MaxVectorSize", ">=32", "UseCompactObjectHeaders", "false"}, applyIfPlatform = {"64-bit", "true"}, applyIfCPUFeatureOr = {"sse4.1", "true", "asimd", "true"}) // Split the load @@ -457,6 +549,10 @@ static Object[] test2b(int[] a, int[] b, int mask) { b[i+6] = b4; b[i+7] = b5; + // With AlignVector, we need 8-byte alignment of vector loads/stores. + // UseCompactObjectHeaders=false UseCompactObjectHeaders=true + // adr = base + 16 + 32*i -> always adr = base + 12 + 32*i -> never + // -> vectorize -> no vectorization } return new Object[]{ a, b }; } @@ -467,7 +563,15 @@ static Object[] test2b(int[] a, int[] b, int mask) { IRNode.AND_VI, IRNode.VECTOR_SIZE_2, "> 0", IRNode.AND_VI, IRNode.VECTOR_SIZE_4, "> 0", IRNode.STORE_VECTOR, "> 0"}, - applyIf = {"MaxVectorSize", ">=32"}, + applyIfAnd = {"MaxVectorSize", ">=32", "AlignVector", "false"}, + applyIfPlatform = {"64-bit", "true"}, + applyIfCPUFeatureOr = {"sse4.1", "true", "asimd", "true"}) + @IR(counts = {IRNode.LOAD_VECTOR_I, IRNode.VECTOR_SIZE_2, "> 0", + IRNode.LOAD_VECTOR_I, IRNode.VECTOR_SIZE_4, "> 0", + IRNode.AND_VI, IRNode.VECTOR_SIZE_2, "> 0", + IRNode.AND_VI, IRNode.VECTOR_SIZE_4, "> 0", + IRNode.STORE_VECTOR, "> 0"}, + applyIfAnd = {"MaxVectorSize", ">=32", "UseCompactObjectHeaders", "false"}, applyIfPlatform = {"64-bit", "true"}, applyIfCPUFeatureOr = {"sse4.1", "true", "asimd", "true"}) // Split the load @@ -494,6 +598,10 @@ static Object[] test2c(int[] a, int[] b, int mask) { b[i+3] = b5; b[i+4] = b6; b[i+5] = b7; + // With AlignVector, we need 8-byte alignment of vector loads/stores. + // UseCompactObjectHeaders=false UseCompactObjectHeaders=true + // adr = base + 16 + 32*i -> always adr = base + 12 + 32*i -> never + // -> vectorize -> no vectorization } return new Object[]{ a, b }; } @@ -504,7 +612,15 @@ static Object[] test2c(int[] a, int[] b, int mask) { IRNode.AND_VI, IRNode.VECTOR_SIZE_2, "> 0", IRNode.AND_VI, IRNode.VECTOR_SIZE_4, "> 0", IRNode.STORE_VECTOR, "> 0"}, - applyIf = {"MaxVectorSize", ">=32"}, + applyIfAnd = {"MaxVectorSize", ">=32", "AlignVector", "false"}, + applyIfPlatform = {"64-bit", "true"}, + applyIfCPUFeatureOr = {"sse4.1", "true", "asimd", "true"}) + @IR(counts = {IRNode.LOAD_VECTOR_I, IRNode.VECTOR_SIZE_2, "> 0", + IRNode.LOAD_VECTOR_I, IRNode.VECTOR_SIZE_4, "> 0", + IRNode.AND_VI, IRNode.VECTOR_SIZE_2, "> 0", + IRNode.AND_VI, IRNode.VECTOR_SIZE_4, "> 0", + IRNode.STORE_VECTOR, "> 0"}, + applyIfAnd = {"MaxVectorSize", ">=32", "UseCompactObjectHeaders", "false"}, applyIfPlatform = {"64-bit", "true"}, applyIfCPUFeatureOr = {"sse4.1", "true", "asimd", "true"}) // Split the load @@ -531,6 +647,10 @@ static Object[] test2d(int[] a, int[] b, int mask) { b[i+3] = b3; b[i+4] = b6; b[i+5] = b7; + // With AlignVector, we need 8-byte alignment of vector loads/stores. + // UseCompactObjectHeaders=false UseCompactObjectHeaders=true + // adr = base + 16 + 32*i -> always adr = base + 12 + 32*i -> never + // -> vectorize -> no vectorization } return new Object[]{ a, b }; } @@ -538,7 +658,12 @@ static Object[] test2d(int[] a, int[] b, int mask) { @Test @IR(counts = {IRNode.LOAD_VECTOR_S, IRNode.VECTOR_SIZE_4, "> 0", IRNode.STORE_VECTOR, "> 0"}, - applyIf = {"MaxVectorSize", ">=32"}, + applyIfAnd = {"MaxVectorSize", ">=32", "AlignVector", "false"}, + applyIfPlatform = {"64-bit", "true"}, + applyIfCPUFeatureOr = {"sse4.1", "true", "asimd", "true"}) + @IR(counts = {IRNode.LOAD_VECTOR_S, IRNode.VECTOR_SIZE_4, "> 0", + IRNode.STORE_VECTOR, "> 0"}, + applyIfAnd = {"MaxVectorSize", ">=32", "UseCompactObjectHeaders", "false"}, applyIfPlatform = {"64-bit", "true"}, applyIfCPUFeatureOr = {"sse4.1", "true", "asimd", "true"}) // 0 1 2 3 4 5 6 7 - @@ -551,30 +676,35 @@ static Object[] test2d(int[] a, int[] b, int mask) { static Object[] test3a(short[] a, short[] b, short val) { int sum = 0; for (int i = 0; i < RANGE; i+=16) { - short a0 = a[i+0]; // required for alignment / offsets, technical limitation. + short a0 = a[i+0]; // required for alignment / offsets, technical limitation. + + short a1 = a[i+1]; // adjacent to 4-pack, but need to be split off + short a2 = a[i+2]; + short a3 = a[i+3]; - short a1 = a[i+1]; // adjacent to 4-pack, but need to be split off - short a2 = a[i+2]; - short a3 = a[i+3]; + short a4 = a[i+4]; // 4-pack + short a5 = a[i+5]; + short a6 = a[i+6]; + short a7 = a[i+7]; - short a4 = a[i+4]; // 4-pack - short a5 = a[i+5]; - short a6 = a[i+6]; - short a7 = a[i+7]; + b[i+0] = a0; // required for alignment / offsets, technical limitation. - b[i+0] = a0; // required for alignment / offsets, technical limitation. + sum += a1 + a2 + a3; // not packed - sum += a1 + a2 + a3; // not packed + b[i+3] = val; // adjacent to 4-pack but needs to be split off - b[i+3] = val; // adjacent to 4-pack but needs to be split off + b[i+4] = a4; // 4-pack + b[i+5] = a5; + b[i+6] = a6; + b[i+7] = a7; - b[i+4] = a4; // 4-pack - b[i+5] = a5; - b[i+6] = a6; - b[i+7] = a7; + b[i+8] = val; // adjacent to 4-pack but needs to be split off - b[i+8] = val; // adjacent to 4-pack but needs to be split off + // With AlignVector, we need 8-byte alignment of vector loads/stores. + // UseCompactObjectHeaders=false UseCompactObjectHeaders=true + // adr = base + 16 + 8 + 32*i -> always adr = base + 12 + 8 + 32*i -> never + // -> vectorize -> no vectorization } return new Object[]{ a, b, new int[]{ sum } }; } @@ -718,7 +848,15 @@ static Object[] test5a(short[] a, short[] b, short val) { IRNode.AND_VI, IRNode.VECTOR_SIZE_4, "> 0", IRNode.ADD_VI, IRNode.VECTOR_SIZE_4, "> 0", // reduction moved out of loop IRNode.ADD_REDUCTION_V, "> 0"}, - applyIf = {"MaxVectorSize", ">=32"}, + applyIfAnd = {"MaxVectorSize", ">=32", "AlignVector", "false"}, + applyIfPlatform = {"64-bit", "true"}, + applyIfCPUFeatureOr = {"sse4.1", "true", "asimd", "true"}) + @IR(counts = {IRNode.LOAD_VECTOR_I, IRNode.VECTOR_SIZE_4, "> 0", + IRNode.MUL_VI, IRNode.VECTOR_SIZE_4, "> 0", + IRNode.AND_VI, IRNode.VECTOR_SIZE_4, "> 0", + IRNode.ADD_VI, IRNode.VECTOR_SIZE_4, "> 0", // reduction moved out of loop + IRNode.ADD_REDUCTION_V, "> 0"}, + applyIfAnd = {"MaxVectorSize", ">=32", "UseCompactObjectHeaders", "false"}, applyIfPlatform = {"64-bit", "true"}, applyIfCPUFeatureOr = {"sse4.1", "true", "asimd", "true"}) // Split packs including reductions @@ -734,6 +872,10 @@ static Object[] test6a(int[] a, int[] b) { s += a[i+5] & b[i+5]; s += a[i+6] & b[i+6]; s += a[i+7] & b[i+7]; + // With AlignVector, we need 8-byte alignment of vector loads/stores. + // UseCompactObjectHeaders=false UseCompactObjectHeaders=true + // adr = base + 16 + 32*i -> always adr = base + 12 + 32*i -> never + // -> vectorize -> no vectorization } return new Object[]{ a, b, new int[]{ s } }; } diff --git a/test/hotspot/jtreg/compiler/loopopts/superword/TestUnorderedReductionPartialVectorization.java b/test/hotspot/jtreg/compiler/loopopts/superword/TestUnorderedReductionPartialVectorization.java index 0d4a4e7b5d8..6150e24cc5e 100644 --- a/test/hotspot/jtreg/compiler/loopopts/superword/TestUnorderedReductionPartialVectorization.java +++ b/test/hotspot/jtreg/compiler/loopopts/superword/TestUnorderedReductionPartialVectorization.java @@ -39,7 +39,10 @@ public class TestUnorderedReductionPartialVectorization { static final int ITER = 10; public static void main(String[] args) { - TestFramework.run(); + TestFramework.runWithFlags("-XX:+UnlockExperimentalVMOptions", "-XX:-UseCompactObjectHeaders", "-XX:-AlignVector"); + TestFramework.runWithFlags("-XX:+UnlockExperimentalVMOptions", "-XX:-UseCompactObjectHeaders", "-XX:+AlignVector"); + TestFramework.runWithFlags("-XX:+UnlockExperimentalVMOptions", "-XX:+UseCompactObjectHeaders", "-XX:-AlignVector"); + TestFramework.runWithFlags("-XX:+UnlockExperimentalVMOptions", "-XX:+UseCompactObjectHeaders", "-XX:+AlignVector"); } @Run(test = {"test1"}) @@ -61,6 +64,7 @@ public void runTests() throws Exception { @IR(counts = {IRNode.LOAD_VECTOR_I, IRNode.VECTOR_SIZE + "min(max_int, max_long)", "> 0", IRNode.VECTOR_CAST_I2L, IRNode.VECTOR_SIZE + "min(max_int, max_long)", "> 0", IRNode.OR_REDUCTION_V, "> 0",}, + applyIfOr = {"AlignVector", "false", "UseCompactObjectHeaders", "false"}, applyIfPlatform = {"64-bit", "true"}, applyIfCPUFeatureOr = {"avx2", "true"}) static long test1(int[] data, long sum) { @@ -88,6 +92,11 @@ static long test1(int[] data, long sum) { // no vectorization. We now ensure there are again 2 packs per operation with a 2x hand unroll. int v2 = data[i + 1]; sum |= v2; + + // With AlignVector, we need 8-byte alignment of vector loads/stores. + // UseCompactObjectHeaders=false UseCompactObjectHeaders=true + // adr = base + 16 + 8*i -> always adr = base + 12 + 8*i -> never + // -> vectorize -> no vectorization } return sum; } diff --git a/test/hotspot/jtreg/compiler/vectorization/TestFloatConversionsVector.java b/test/hotspot/jtreg/compiler/vectorization/TestFloatConversionsVector.java index 2fd5364a78b..3eb3f3eebe9 100644 --- a/test/hotspot/jtreg/compiler/vectorization/TestFloatConversionsVector.java +++ b/test/hotspot/jtreg/compiler/vectorization/TestFloatConversionsVector.java @@ -27,7 +27,10 @@ * @summary Auto-vectorize Float.floatToFloat16, Float.float16ToFloat APIs * @requires vm.compiler2.enabled * @library /test/lib / - * @run driver compiler.vectorization.TestFloatConversionsVector + * @run driver compiler.vectorization.TestFloatConversionsVector nCOH_nAV + * @run driver compiler.vectorization.TestFloatConversionsVector nCOH_yAV + * @run driver compiler.vectorization.TestFloatConversionsVector yCOH_nAV + * @run driver compiler.vectorization.TestFloatConversionsVector yCOH_yAV */ package compiler.vectorization; @@ -44,18 +47,32 @@ public class TestFloatConversionsVector { private static float [] fout; public static void main(String args[]) { - TestFramework.runWithFlags("-XX:-TieredCompilation", - "-XX:CompileThresholdScaling=0.3"); + TestFramework framework = new TestFramework(TestFloatConversionsVector.class); + framework.addFlags("-XX:-TieredCompilation", "-XX:CompileThresholdScaling=0.3"); + switch (args[0]) { + case "nCOH_nAV" -> { framework.addFlags("-XX:+UnlockExperimentalVMOptions", "-XX:-UseCompactObjectHeaders", "-XX:-AlignVector"); } + case "nCOH_yAV" -> { framework.addFlags("-XX:+UnlockExperimentalVMOptions", "-XX:-UseCompactObjectHeaders", "-XX:+AlignVector"); } + case "yCOH_nAV" -> { framework.addFlags("-XX:+UnlockExperimentalVMOptions", "-XX:+UseCompactObjectHeaders", "-XX:-AlignVector"); } + case "yCOH_yAV" -> { framework.addFlags("-XX:+UnlockExperimentalVMOptions", "-XX:+UseCompactObjectHeaders", "-XX:+AlignVector"); } + default -> { throw new RuntimeException("Test argument not recognized: " + args[0]); } + }; + framework.start(); System.out.println("PASSED"); } @Test @IR(counts = {IRNode.VECTOR_CAST_F2HF, IRNode.VECTOR_SIZE + "min(max_float, max_short)", "> 0"}, - applyIfPlatformOr = {"x64", "true", "aarch64", "true", "riscv64", "true"}, - applyIfCPUFeatureOr = {"f16c", "true", "avx512f", "true", "zvfh", "true", "asimd", "true", "sve", "true"}) + applyIfOr = {"UseCompactObjectHeaders", "false", "AlignVector", "false"}, + applyIfPlatformOr = {"x64", "true", "aarch64", "true", "riscv64", "true"}, + applyIfCPUFeatureOr = {"f16c", "true", "avx512f", "true", "zvfh", "true", "asimd", "true", "sve", "true"}) public void test_float_float16(short[] sout, float[] finp) { for (int i = 0; i < finp.length; i++) { sout[i] = Float.floatToFloat16(finp[i]); + // With AlignVector, we need 8-byte alignment of vector loads/stores. + // UseCompactObjectHeaders=false UseCompactObjectHeaders=true + // F_adr = base + 16 + 4*i -> i % 2 = 0 F_adr = base + 12 + 4*i -> i % 2 = 1 + // S_adr = base + 16 + 2*i -> i % 4 = 0 S_adr = base + 12 + 2*i -> i % 4 = 2 + // -> vectorize -> no vectorization } } @@ -114,11 +131,17 @@ public void kernel_test_float_float16() { @Test @IR(counts = {IRNode.VECTOR_CAST_HF2F, IRNode.VECTOR_SIZE + "min(max_float, max_short)", "> 0"}, - applyIfPlatformOr = {"x64", "true", "aarch64", "true", "riscv64", "true"}, - applyIfCPUFeatureOr = {"f16c", "true", "avx512f", "true", "zvfh", "true", "asimd", "true", "sve", "true"}) + applyIfOr = {"UseCompactObjectHeaders", "false", "AlignVector", "false"}, + applyIfPlatformOr = {"x64", "true", "aarch64", "true", "riscv64", "true"}, + applyIfCPUFeatureOr = {"f16c", "true", "avx512f", "true", "zvfh", "true", "asimd", "true", "sve", "true"}) public void test_float16_float(float[] fout, short[] sinp) { for (int i = 0; i < sinp.length; i++) { fout[i] = Float.float16ToFloat(sinp[i]); + // With AlignVector, we need 8-byte alignment of vector loads/stores. + // UseCompactObjectHeaders=false UseCompactObjectHeaders=true + // F_adr = base + 16 + 4*i -> i % 2 = 0 F_adr = base + 12 + 4*i -> i % 2 = 1 + // S_adr = base + 16 + 2*i -> i % 4 = 0 S_adr = base + 12 + 2*i -> i % 4 = 2 + // -> vectorize -> no vectorization } } diff --git a/test/hotspot/jtreg/compiler/vectorization/runner/ArrayTypeConvertTest.java b/test/hotspot/jtreg/compiler/vectorization/runner/ArrayTypeConvertTest.java index 60d3c05dab6..0da101a8fb7 100644 --- a/test/hotspot/jtreg/compiler/vectorization/runner/ArrayTypeConvertTest.java +++ b/test/hotspot/jtreg/compiler/vectorization/runner/ArrayTypeConvertTest.java @@ -1,5 +1,6 @@ /* * Copyright (c) 2022, 2023, Arm Limited. All rights reserved. + * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -29,21 +30,53 @@ * @build jdk.test.whitebox.WhiteBox * compiler.vectorization.runner.VectorizationTestRunner * + * @requires vm.compiler2.enabled + * * @run driver jdk.test.lib.helpers.ClassFileInstaller jdk.test.whitebox.WhiteBox + * * @run main/othervm -Xbootclasspath/a:. * -XX:+UnlockDiagnosticVMOptions * -XX:+WhiteBoxAPI - * compiler.vectorization.runner.ArrayTypeConvertTest + * compiler.vectorization.runner.ArrayTypeConvertTest nCOH_nAV * - * @requires vm.compiler2.enabled + * @run main/othervm -Xbootclasspath/a:. + * -XX:+UnlockDiagnosticVMOptions + * -XX:+WhiteBoxAPI + * compiler.vectorization.runner.ArrayTypeConvertTest nCOH_yAV + * + * @run main/othervm -Xbootclasspath/a:. + * -XX:+UnlockDiagnosticVMOptions + * -XX:+WhiteBoxAPI + * compiler.vectorization.runner.ArrayTypeConvertTest yCOH_nAV + * + * @run main/othervm -Xbootclasspath/a:. + * -XX:+UnlockDiagnosticVMOptions + * -XX:+WhiteBoxAPI + * compiler.vectorization.runner.ArrayTypeConvertTest yCOH_yAV */ package compiler.vectorization.runner; import compiler.lib.ir_framework.*; +// Explanation about AlignVector: we require 8-byte alignment of all addresses. +// But the array base offset changes with UseCompactObjectHeaders. +// This means it affects the alignment constraints. + public class ArrayTypeConvertTest extends VectorizationTestRunner { + // We must pass the flags directly to the test-VM, and not the driver vm in the @run above. + @Override + protected String[] testVMFlags(String[] args) { + return switch (args[0]) { + case "nCOH_nAV" -> new String[]{"-XX:+UnlockExperimentalVMOptions", "-XX:-UseCompactObjectHeaders", "-XX:-AlignVector"}; + case "nCOH_yAV" -> new String[]{"-XX:+UnlockExperimentalVMOptions", "-XX:-UseCompactObjectHeaders", "-XX:+AlignVector"}; + case "yCOH_nAV" -> new String[]{"-XX:+UnlockExperimentalVMOptions", "-XX:+UseCompactObjectHeaders", "-XX:-AlignVector"}; + case "yCOH_yAV" -> new String[]{"-XX:+UnlockExperimentalVMOptions", "-XX:+UseCompactObjectHeaders", "-XX:+AlignVector"}; + default -> { throw new RuntimeException("Test argument not recognized: " + args[0]); } + }; + } + private static final int SIZE = 543; private byte[] bytes; @@ -75,6 +108,10 @@ public ArrayTypeConvertTest() { // ---------------- Integer Extension ---------------- @Test + @IR(failOn = {IRNode.STORE_VECTOR}) + // Subword vector casts do not work currently, see JDK-8342095. + // Assert the vectorization failure so that we are reminded to update + // the test when this limitation is addressed in the future. public int[] signExtension() { int[] res = new int[SIZE]; for (int i = 0; i < SIZE; i++) { @@ -84,6 +121,10 @@ public int[] signExtension() { } @Test + @IR(failOn = {IRNode.STORE_VECTOR}) + // Subword vector casts do not work currently, see JDK-8342095. + // Assert the vectorization failure so that we are reminded to update + // the test when this limitation is addressed in the future. public int[] zeroExtension() { int[] res = new int[SIZE]; for (int i = 0; i < SIZE; i++) { @@ -93,6 +134,10 @@ public int[] zeroExtension() { } @Test + @IR(failOn = {IRNode.STORE_VECTOR}) + // Subword vector casts do not work currently, see JDK-8342095. + // Assert the vectorization failure so that we are reminded to update + // the test when this limitation is addressed in the future. public int[] signExtensionFromByte() { int[] res = new int[SIZE]; for (int i = 0; i < SIZE; i++) { @@ -103,6 +148,10 @@ public int[] signExtensionFromByte() { // ---------------- Integer Narrow ---------------- @Test + @IR(failOn = {IRNode.STORE_VECTOR}) + // Subword vector casts do not work currently, see JDK-8342095. + // Assert the vectorization failure so that we are reminded to update + // the test when this limitation is addressed in the future. public short[] narrowToSigned() { short[] res = new short[SIZE]; for (int i = 0; i < SIZE; i++) { @@ -112,6 +161,10 @@ public short[] narrowToSigned() { } @Test + @IR(failOn = {IRNode.STORE_VECTOR}) + // Subword vector casts do not work currently, see JDK-8342095. + // Assert the vectorization failure so that we are reminded to update + // the test when this limitation is addressed in the future. public char[] narrowToUnsigned() { char[] res = new char[SIZE]; for (int i = 0; i < SIZE; i++) { @@ -121,6 +174,10 @@ public char[] narrowToUnsigned() { } @Test + @IR(failOn = {IRNode.STORE_VECTOR}) + // Subword vector casts do not work currently, see JDK-8342095. + // Assert the vectorization failure so that we are reminded to update + // the test when this limitation is addressed in the future. public byte[] NarrowToByte() { byte[] res = new byte[SIZE]; for (int i = 0; i < SIZE; i++) { @@ -177,11 +234,19 @@ public double[] convertLongToDouble() { // ---------------- Convert Subword-I to F/D ---------------- @Test @IR(applyIfCPUFeatureOr = {"asimd", "true", "avx2", "true"}, + applyIfOr = {"AlignVector", "false", "UseCompactObjectHeaders", "false"}, counts = {IRNode.VECTOR_CAST_S2F, IRNode.VECTOR_SIZE + "min(max_short, max_float)", ">0"}) public float[] convertShortToFloat() { float[] res = new float[SIZE]; for (int i = 0; i < SIZE; i++) { res[i] = (float) shorts[i]; + // AlignVector=true requires that all vector load/store are 8-byte aligned. + // F_adr = base + UNSAFE.ARRAY_FLOAT_BASE_OFFSET + 4*i + // = 16 (UseCompactObjectHeaders=false) -> i % 2 = 0 + // = 12 (UseCompactObjectHeaders=true ) -> i % 2 = 1 + // S_adr = base + UNSAFE.ARRAY_SHORT_BASE_OFFSET + 2*i + // = 16 (UseCompactObjectHeaders=false) -> i % 4 = 0 -> can align both + // = 12 (UseCompactObjectHeaders=true ) -> i % 4 = 2 -> cannot align both } return res; } @@ -199,6 +264,10 @@ public double[] convertShortToDouble() { } @Test + @IR(failOn = {IRNode.STORE_VECTOR}) + // Subword vector casts do not work currently, see JDK-8342095. + // Assert the vectorization failure so that we are reminded to update + // the test when this limitation is addressed in the future. public float[] convertCharToFloat() { float[] res = new float[SIZE]; for (int i = 0; i < SIZE; i++) { @@ -208,6 +277,10 @@ public float[] convertCharToFloat() { } @Test + @IR(failOn = {IRNode.STORE_VECTOR}) + // Subword vector casts do not work currently, see JDK-8342095. + // Assert the vectorization failure so that we are reminded to update + // the test when this limitation is addressed in the future. public double[] convertCharToDouble() { double[] res = new double[SIZE]; for (int i = 0; i < SIZE; i++) { @@ -264,22 +337,38 @@ public long[] convertDoubleToLong() { // ---------------- Convert F/D to Subword-I ---------------- @Test @IR(applyIfCPUFeatureOr = {"asimd", "true", "avx2", "true"}, + applyIfOr = {"AlignVector", "false", "UseCompactObjectHeaders", "false"}, counts = {IRNode.VECTOR_CAST_F2S, IRNode.VECTOR_SIZE + "min(max_float, max_short)", ">0"}) public short[] convertFloatToShort() { short[] res = new short[SIZE]; for (int i = 0; i < SIZE; i++) { res[i] = (short) floats[i]; + // AlignVector=true requires that all vector load/store are 8-byte aligned. + // F_adr = base + UNSAFE.ARRAY_FLOAT_BASE_OFFSET + 4*i + // = 16 (UseCompactObjectHeaders=false) -> i % 2 = 0 + // = 12 (UseCompactObjectHeaders=true ) -> i % 2 = 1 + // S_adr = base + UNSAFE.ARRAY_SHORT_BASE_OFFSET + 2*i + // = 16 (UseCompactObjectHeaders=false) -> i % 4 = 0 -> can align both + // = 12 (UseCompactObjectHeaders=true ) -> i % 4 = 2 -> cannot align both } return res; } @Test @IR(applyIfCPUFeatureOr = {"asimd", "true", "avx2", "true"}, + applyIfOr = {"AlignVector", "false", "UseCompactObjectHeaders", "false"}, counts = {IRNode.VECTOR_CAST_F2S, IRNode.VECTOR_SIZE + "min(max_float, max_char)", ">0"}) public char[] convertFloatToChar() { char[] res = new char[SIZE]; for (int i = 0; i < SIZE; i++) { res[i] = (char) floats[i]; + // AlignVector=true requires that all vector load/store are 8-byte aligned. + // F_adr = base + UNSAFE.ARRAY_FLOAT_BASE_OFFSET + 4*i + // = 16 (UseCompactObjectHeaders=false) -> i % 2 = 0 + // = 12 (UseCompactObjectHeaders=true ) -> i % 2 = 1 + // S_adr = base + UNSAFE.ARRAY_SHORT_BASE_OFFSET + 2*i + // = 16 (UseCompactObjectHeaders=false) -> i % 4 = 0 -> can align both + // = 12 (UseCompactObjectHeaders=true ) -> i % 4 = 2 -> cannot align both } return res; } diff --git a/test/hotspot/jtreg/compiler/vectorization/runner/LoopCombinedOpTest.java b/test/hotspot/jtreg/compiler/vectorization/runner/LoopCombinedOpTest.java index 8a0715eadfe..2fd6a053de7 100644 --- a/test/hotspot/jtreg/compiler/vectorization/runner/LoopCombinedOpTest.java +++ b/test/hotspot/jtreg/compiler/vectorization/runner/LoopCombinedOpTest.java @@ -30,13 +30,29 @@ * @build jdk.test.whitebox.WhiteBox * compiler.vectorization.runner.VectorizationTestRunner * + * @requires vm.compiler2.enabled + * * @run driver jdk.test.lib.helpers.ClassFileInstaller jdk.test.whitebox.WhiteBox + * * @run main/othervm -Xbootclasspath/a:. * -XX:+UnlockDiagnosticVMOptions * -XX:+WhiteBoxAPI - * compiler.vectorization.runner.LoopCombinedOpTest + * compiler.vectorization.runner.LoopCombinedOpTest nCOH_nAV * - * @requires vm.compiler2.enabled + * @run main/othervm -Xbootclasspath/a:. + * -XX:+UnlockDiagnosticVMOptions + * -XX:+WhiteBoxAPI + * compiler.vectorization.runner.LoopCombinedOpTest nCOH_yAV + * + * @run main/othervm -Xbootclasspath/a:. + * -XX:+UnlockDiagnosticVMOptions + * -XX:+WhiteBoxAPI + * compiler.vectorization.runner.LoopCombinedOpTest yCOH_nAV + * + * @run main/othervm -Xbootclasspath/a:. + * -XX:+UnlockDiagnosticVMOptions + * -XX:+WhiteBoxAPI + * compiler.vectorization.runner.LoopCombinedOpTest yCOH_yAV */ package compiler.vectorization.runner; @@ -47,6 +63,18 @@ public class LoopCombinedOpTest extends VectorizationTestRunner { + // We must pass the flags directly to the test-VM, and not the driver vm in the @run above. + @Override + protected String[] testVMFlags(String[] args) { + return switch (args[0]) { + case "nCOH_nAV" -> new String[]{"-XX:+UnlockExperimentalVMOptions", "-XX:-UseCompactObjectHeaders", "-XX:-AlignVector"}; + case "nCOH_yAV" -> new String[]{"-XX:+UnlockExperimentalVMOptions", "-XX:-UseCompactObjectHeaders", "-XX:+AlignVector"}; + case "yCOH_nAV" -> new String[]{"-XX:+UnlockExperimentalVMOptions", "-XX:+UseCompactObjectHeaders", "-XX:-AlignVector"}; + case "yCOH_yAV" -> new String[]{"-XX:+UnlockExperimentalVMOptions", "-XX:+UseCompactObjectHeaders", "-XX:+AlignVector"}; + default -> { throw new RuntimeException("Test argument not recognized: " + args[0]); } + }; + } + private static final int SIZE = 543; private int[] a; @@ -84,7 +112,8 @@ public LoopCombinedOpTest() { @Test @IR(applyIfCPUFeatureOr = {"asimd", "true", "sse2", "true"}, - counts = {IRNode.STORE_VECTOR, ">0"}) + counts = {IRNode.STORE_VECTOR, ">0", + IRNode.LOAD_VECTOR_I, "> 0"}) public int[] opWithConstant() { int[] res = new int[SIZE]; for (int i = 0; i < SIZE; i++) { @@ -95,7 +124,8 @@ public int[] opWithConstant() { @Test @IR(applyIfCPUFeatureOr = {"asimd", "true", "sse4.1", "true"}, - counts = {IRNode.STORE_VECTOR, ">0"}) + counts = {IRNode.STORE_VECTOR, ">0", + IRNode.LOAD_VECTOR_I, "> 0"}) public int[] opWithLoopInvariant() { int[] res = new int[SIZE]; for (int i = 0; i < SIZE; i++) { @@ -106,7 +136,8 @@ public int[] opWithLoopInvariant() { @Test @IR(applyIfCPUFeatureOr = {"asimd", "true", "sse4.1", "true"}, - counts = {IRNode.STORE_VECTOR, ">0"}) + counts = {IRNode.STORE_VECTOR, ">0", + IRNode.LOAD_VECTOR_I, "> 0"}) public int[] opWithConstantAndLoopInvariant() { int[] res = new int[SIZE]; for (int i = 0; i < SIZE; i++) { @@ -117,7 +148,8 @@ public int[] opWithConstantAndLoopInvariant() { @Test @IR(applyIfCPUFeatureOr = {"asimd", "true", "sse2", "true"}, - counts = {IRNode.STORE_VECTOR, ">0"}) + counts = {IRNode.STORE_VECTOR, ">0", + IRNode.LOAD_VECTOR_I, "> 0"}) public int[] multipleOps() { int[] res = new int[SIZE]; for (int i = 0; i < SIZE; i++) { @@ -128,7 +160,8 @@ public int[] multipleOps() { @Test @IR(applyIfCPUFeatureOr = {"asimd", "true", "sse4.1", "true"}, - counts = {IRNode.STORE_VECTOR, ">0"}) + counts = {IRNode.STORE_VECTOR, ">0", + IRNode.LOAD_VECTOR_I, "> 0"}) public int[] multipleOpsWithMultipleConstants() { int[] res = new int[SIZE]; for (int i = 0; i < SIZE; i++) { @@ -139,7 +172,8 @@ public int[] multipleOpsWithMultipleConstants() { @Test @IR(applyIfCPUFeatureOr = {"asimd", "true", "sse4.1", "true"}, - counts = {IRNode.STORE_VECTOR, ">0"}) + counts = {IRNode.STORE_VECTOR, ">0", + IRNode.LOAD_VECTOR_I, "> 0"}) // With sse2, the MulI does not vectorize. This means we have vectorized stores // to res1, but scalar loads from res1. The store-to-load-forwarding failure // detection catches this and rejects vectorization. @@ -157,7 +191,8 @@ public int[] multipleStores() { @Test @IR(applyIfCPUFeatureOr = {"asimd", "true", "sse4.1", "true"}, - counts = {IRNode.STORE_VECTOR, ">0"}) + counts = {IRNode.STORE_VECTOR, ">0", + IRNode.LOAD_VECTOR_I, "> 0"}) public int[] multipleStoresWithCommonSubExpression() { int[] res1 = new int[SIZE]; int[] res2 = new int[SIZE]; @@ -172,20 +207,43 @@ public int[] multipleStoresWithCommonSubExpression() { @Test @IR(applyIfCPUFeatureOr = {"asimd", "true", "sse2", "true"}, - counts = {IRNode.STORE_VECTOR, ">0"}) + applyIfOr = { "UseCompactObjectHeaders", "false", "AlignVector", "false"}, + counts = {IRNode.STORE_VECTOR, ">0", + IRNode.LOAD_VECTOR_S, "> 0", + IRNode.LOAD_VECTOR_I, "> 0"}) public int[] multipleOpsWith2DifferentTypes() { short[] res1 = new short[SIZE]; int[] res2 = new int[SIZE]; for (int i = 0; i < SIZE; i++) { res1[i] = (short) (s1[i] + s2[i]); res2[i] = a[i] + b[i]; + // We have a mix of int and short loads/stores. + // With UseCompactObjectHeaders and AlignVector, + // we must 8-byte align all vector loads/stores. + // + // int: + // adr = base + UNSAFE.ARRAY_INT_BASE_OFFSET + 4*iter + // = 16 (or 12 if UseCompactObjectHeaders=true) + // If UseCompactObjectHeaders=false: iter % 2 = 0 + // If UseCompactObjectHeaders=true: iter % 2 = 1 + // + // byte: + // adr = base + UNSAFE.ARRAY_BYTE_BASE_OFFSET + 1*iter + // = 16 (or 12 if UseCompactObjectHeaders=true) + // If UseCompactObjectHeaders=false: iter % 8 = 0 + // If UseCompactObjectHeaders=true: iter % 8 = 4 + // + // -> we cannot align both if UseCompactObjectHeaders=true. } return res2; } @Test @IR(applyIfCPUFeatureOr = {"asimd", "true", "sse2", "true"}, - counts = {IRNode.STORE_VECTOR, ">0"}) + applyIfOr = { "UseCompactObjectHeaders", "false", "AlignVector", "false"}, + counts = {IRNode.STORE_VECTOR, ">0", + IRNode.LOAD_VECTOR_I, IRNode.VECTOR_SIZE_ANY, "> 0", + IRNode.LOAD_VECTOR_L, "> 0"}) public long[] multipleOpsWith3DifferentTypes() { short[] res1 = new short[SIZE]; int[] res2 = new int[SIZE]; @@ -194,13 +252,32 @@ public long[] multipleOpsWith3DifferentTypes() { res1[i] = (short) (s1[i] + s2[i]); res2[i] = a[i] + b[i]; res3[i] = l1[i] + l2[i]; + // We have a mix of int and short loads/stores. + // With UseCompactObjectHeaders and AlignVector, + // we must 8-byte align all vector loads/stores. + // + // int: + // adr = base + UNSAFE.ARRAY_INT_BASE_OFFSET + 4*iter + // = 16 (or 12 if UseCompactObjectHeaders=true) + // If UseCompactObjectHeaders=false: iter % 2 = 0 + // If UseCompactObjectHeaders=true: iter % 2 = 1 + // + // byte: + // adr = base + UNSAFE.ARRAY_BYTE_BASE_OFFSET + 1*iter + // = 16 (or 12 if UseCompactObjectHeaders=true) + // If UseCompactObjectHeaders=false: iter % 8 = 0 + // If UseCompactObjectHeaders=true: iter % 8 = 4 + // + // -> we cannot align both if UseCompactObjectHeaders=true. } return res3; } @Test @IR(applyIfCPUFeatureOr = {"asimd", "true", "sse2", "true"}, - counts = {IRNode.STORE_VECTOR, ">0"}) + counts = {IRNode.STORE_VECTOR, ">0", + IRNode.LOAD_VECTOR_S, IRNode.VECTOR_SIZE_ANY, "> 0", + IRNode.LOAD_VECTOR_L, "> 0"}) public long[] multipleOpsWith2NonAdjacentTypes() { short[] res1 = new short[SIZE]; long[] res2 = new long[SIZE]; @@ -213,50 +290,93 @@ public long[] multipleOpsWith2NonAdjacentTypes() { @Test @IR(applyIfCPUFeatureOr = {"asimd", "true", "sse2", "true"}, - counts = {IRNode.STORE_VECTOR, ">0"}) + applyIfOr = { "UseCompactObjectHeaders", "false", "AlignVector", "false"}, + counts = {IRNode.STORE_VECTOR, ">0", + IRNode.LOAD_VECTOR_S, "> 0", + IRNode.LOAD_VECTOR_I, "> 0"}) public int[] multipleOpsWith2DifferentTypesAndConstant() { short[] res1 = new short[SIZE]; int[] res2 = new int[SIZE]; for (int i = 0; i < SIZE; i++) { res1[i] = (short) (s1[i] + s2[i]); res2[i] = a[i] + 88888888;; + // We have a mix of int and short loads/stores. + // With UseCompactObjectHeaders and AlignVector, + // we must 8-byte align all vector loads/stores. + // + // int: + // adr = base + UNSAFE.ARRAY_INT_BASE_OFFSET + 4*iter + // = 16 (or 12 if UseCompactObjectHeaders=true) + // If UseCompactObjectHeaders=false: iter % 2 = 0 + // If UseCompactObjectHeaders=true: iter % 2 = 1 + // + // byte: + // adr = base + UNSAFE.ARRAY_BYTE_BASE_OFFSET + 1*iter + // = 16 (or 12 if UseCompactObjectHeaders=true) + // If UseCompactObjectHeaders=false: iter % 8 = 0 + // If UseCompactObjectHeaders=true: iter % 8 = 4 + // + // -> we cannot align both if UseCompactObjectHeaders=true. } return res2; } @Test - @IR(applyIfCPUFeatureOr = {"asimd", "true", "sse2", "true"}, - // This test fails with compact headers, but only with UseSSE<=3. - applyIf = { "UseCompactObjectHeaders", "false" }, - counts = {IRNode.STORE_VECTOR, ">0"}) + @IR(applyIfCPUFeatureOr = {"asimd", "true", "sse4.1", "true"}, + applyIfOr = { "UseCompactObjectHeaders", "false", "AlignVector", "false"}, + counts = {IRNode.STORE_VECTOR, ">0", + IRNode.LOAD_VECTOR_S, "> 0", + IRNode.LOAD_VECTOR_I, "> 0"}) public int[] multipleOpsWith2DifferentTypesAndInvariant() { short[] res1 = new short[SIZE]; int[] res2 = new int[SIZE]; for (int i = 0; i < SIZE; i++) { res1[i] = (short) (s1[i] + s2[i]); res2[i] = a[i] * intInv; + // We have a mix of int and short loads/stores. + // With UseCompactObjectHeaders and AlignVector, + // we must 8-byte align all vector loads/stores. + // + // int: + // adr = base + UNSAFE.ARRAY_INT_BASE_OFFSET + 4*iter + // = 16 (or 12 if UseCompactObjectHeaders=true) + // If UseCompactObjectHeaders=false: iter % 2 = 0 + // If UseCompactObjectHeaders=true: iter % 2 = 1 + // + // byte: + // adr = base + UNSAFE.ARRAY_BYTE_BASE_OFFSET + 1*iter + // = 16 (or 12 if UseCompactObjectHeaders=true) + // If UseCompactObjectHeaders=false: iter % 8 = 0 + // If UseCompactObjectHeaders=true: iter % 8 = 4 + // + // -> we cannot align both if UseCompactObjectHeaders=true. } return res2; } @Test - @IR(applyIfCPUFeatureOr = {"asimd", "true", "sse2", "true"}, - // This test fails with compact headers, but only with UseSSE<=3. - applyIf = { "UseCompactObjectHeaders", "false" }, - counts = {IRNode.STORE_VECTOR, ">0"}) + @IR(applyIfCPUFeatureOr = {"asimd", "true", "sse4.1", "true"}, + applyIfOr = { "UseCompactObjectHeaders", "false", "AlignVector", "false"}, + counts = {IRNode.STORE_VECTOR, ">0", + IRNode.LOAD_VECTOR_S, "> 0", + IRNode.LOAD_VECTOR_I, "> 0"}) public int[] multipleOpsWith2DifferentTypesAndComplexExpression() { short[] res1 = new short[SIZE]; int[] res2 = new int[SIZE]; for (int i = 0; i < SIZE; i++) { res1[i] = (short) (s1[i] + s2[i]); res2[i] = a[i] * (b[i] + intInv * c[i] & 0xfffffa); + // same argument as in multipleOpsWith2DifferentTypesAndInvariant. } return res2; } @Test @IR(applyIfCPUFeatureOr = {"asimd", "true", "sse3", "true"}, - counts = {IRNode.STORE_VECTOR, ">0"}) + applyIfOr = { "UseCompactObjectHeaders", "false", "AlignVector", "false"}, + counts = {IRNode.STORE_VECTOR, ">0", + IRNode.LOAD_VECTOR_S, "> 0", + IRNode.LOAD_VECTOR_I, "> 0"}) public int[] multipleOpsWith2DifferentTypesAndSharedOp() { int i = 0, sum = 0; int[] res1 = new int[SIZE]; @@ -264,11 +384,29 @@ public int[] multipleOpsWith2DifferentTypesAndSharedOp() { while (++i < SIZE) { sum += (res1[i]--); res2[i]++; + // We have a mix of int and short loads/stores. + // With UseCompactObjectHeaders and AlignVector, + // we must 8-byte align all vector loads/stores. + // + // int: + // adr = base + UNSAFE.ARRAY_INT_BASE_OFFSET + 4*iter + // = 16 (or 12 if UseCompactObjectHeaders=true) + // If UseCompactObjectHeaders=false: iter % 2 = 0 + // If UseCompactObjectHeaders=true: iter % 2 = 1 + // + // byte: + // adr = base + UNSAFE.ARRAY_BYTE_BASE_OFFSET + 1*iter + // = 16 (or 12 if UseCompactObjectHeaders=true) + // If UseCompactObjectHeaders=false: iter % 8 = 0 + // If UseCompactObjectHeaders=true: iter % 8 = 4 + // + // -> we cannot align both if UseCompactObjectHeaders=true. } return res1; } @Test + // POPULATE_INDEX seems to mess with vectorization, see JDK-8332878. public int[] fillIndexPlusStride() { int[] res = new int[SIZE]; for (int i = 0; i < SIZE; i++) { @@ -278,6 +416,7 @@ public int[] fillIndexPlusStride() { } @Test + // POPULATE_INDEX seems to mess with vectorization, see JDK-8332878. public int[] addArrayWithIndex() { int[] res = new int[SIZE]; for (int i = 0; i < SIZE; i++) { @@ -287,6 +426,7 @@ public int[] addArrayWithIndex() { } @Test + // POPULATE_INDEX seems to mess with vectorization, see JDK-8332878. public short[] multiplyAddShortIndex() { short[] res = new short[SIZE]; for (int i = 0; i < SIZE; i++) { @@ -296,6 +436,7 @@ public short[] multiplyAddShortIndex() { } @Test + // POPULATE_INDEX seems to mess with vectorization, see JDK-8332878. public int[] multiplyBySumOfIndexAndInvariant() { int[] res = new int[SIZE]; for (int i = 0; i < SIZE; i++) { @@ -306,19 +447,30 @@ public int[] multiplyBySumOfIndexAndInvariant() { @Test @IR(applyIfCPUFeatureOr = {"asimd", "true", "sse4.1", "true"}, + applyIfOr = { "UseCompactObjectHeaders", "false", "AlignVector", "false"}, counts = {IRNode.STORE_VECTOR, ">0"}) public int[] manuallyUnrolledStride2() { int[] res = new int[SIZE]; for (int i = 0; i < SIZE - 1; i += 2) { res[i] = a[i] * b[i]; res[i + 1] = a[i + 1] * b[i + 1]; + // Hand-unrolling can mess with alignment! + // + // With UseCompactObjectHeaders and AlignVector, + // we must 8-byte align all vector loads/stores. + // + // adr = base + UNSAFE.ARRAY_INT_BASE_OFFSET + 8*iter + // = 16 (or 12 if UseCompactObjectHeaders=true) + // If UseCompactObjectHeaders=false: 16 divisible by 8 -> vectorize + // If UseCompactObjectHeaders=true: 12 not divisibly by 8 -> not vectorize } return res; } @Test @IR(applyIfCPUFeatureOr = {"asimd", "true", "sse4.1", "true"}, - counts = {IRNode.STORE_VECTOR, ">0"}) + counts = {IRNode.STORE_VECTOR, ">0", + IRNode.LOAD_VECTOR_I, "> 0"}) public int partialVectorizableLoop() { int[] res = new int[SIZE]; int k = 9; diff --git a/test/hotspot/jtreg/compiler/vectorization/runner/VectorizationTestRunner.java b/test/hotspot/jtreg/compiler/vectorization/runner/VectorizationTestRunner.java index ff8787eb913..7f8e4ec3b39 100644 --- a/test/hotspot/jtreg/compiler/vectorization/runner/VectorizationTestRunner.java +++ b/test/hotspot/jtreg/compiler/vectorization/runner/VectorizationTestRunner.java @@ -44,7 +44,7 @@ public class VectorizationTestRunner { private static final int NMETHOD_COMP_LEVEL_IDX = 1; private static final int NMETHOD_INSTS_IDX = 2; - protected void run() { + protected void run(String[] args) { Class klass = getClass(); // 1) Vectorization correctness test @@ -68,9 +68,15 @@ protected void run() { // To test vectorizability, invoke the IR test framework to check existence of // expected C2 IR node. TestFramework irTest = new TestFramework(klass); + irTest.addFlags(testVMFlags(args)); irTest.start(); } + // Override this to add extra flags. + protected String[] testVMFlags(String[] args) { + return new String[0]; // by default no extra flags + } + private void verifyTestMethod(Method method) { // Check method parameter count if (method.getParameterCount() > 0) { @@ -191,6 +197,6 @@ private static void fail(String reason) { public static void main(String[] args) { VectorizationTestRunner testObj = createTestInstance(Utils.TEST_NAME); - testObj.run(); + testObj.run(args); } } diff --git a/test/hotspot/jtreg/testlibrary_tests/ir_framework/examples/IRExample.java b/test/hotspot/jtreg/testlibrary_tests/ir_framework/examples/IRExample.java index 539673a6c28..6a0a605e4ab 100644 --- a/test/hotspot/jtreg/testlibrary_tests/ir_framework/examples/IRExample.java +++ b/test/hotspot/jtreg/testlibrary_tests/ir_framework/examples/IRExample.java @@ -179,7 +179,7 @@ static float[] testVectorNodeExactSize1() { @Test // In some cases, we can know the exact size, here 4 @IR(counts = {IRNode.LOAD_VECTOR_F, IRNode.VECTOR_SIZE_4, "> 0"}, - applyIf = {"MaxVectorSize", ">=16"}, + applyIfAnd = {"MaxVectorSize", ">=16", "AlignVector", "false"}, applyIfCPUFeatureOr = {"sse2", "true", "asimd", "true"}) // Hence, we know any other sizes are impossible. // We can also specify that explicitly for failOn @@ -206,7 +206,7 @@ static float[] testVectorNodeExactSize2() { // Here, we can pack at most 8 given the 8-blocks and 8-gaps. // But we can also never pack more than max_float @IR(counts = {IRNode.LOAD_VECTOR_F, IRNode.VECTOR_SIZE + "min(8, max_float)", "> 0"}, - applyIf = {"MaxVectorSize", ">=16"}, + applyIfAnd = {"MaxVectorSize", ">=16", "AlignVector", "false"}, applyIfCPUFeatureOr = {"sse2", "true", "asimd", "true"}) static float[] testVectorNodeSizeMinClause() { float[] a = new float[1024*8]; From 965aace297154ab08ee41a4d988553707cae8b32 Mon Sep 17 00:00:00 2001 From: Alexander Zvegintsev <azvegint@openjdk.org> Date: Mon, 25 Nov 2024 11:11:28 +0000 Subject: [PATCH 215/311] 8335468: [XWayland] JavaFX hangs when calling java.awt.Robot.getPixelColor Reviewed-by: kcr, honkar --- .../unix/native/libawt_xawt/awt/fp_pipewire.h | 3 +- .../native/libawt_xawt/awt/gtk3_interface.c | 8 +++- .../native/libawt_xawt/awt/gtk3_interface.h | 3 ++ .../native/libawt_xawt/awt/gtk_interface.h | 4 +- .../libawt_xawt/awt/screencast_pipewire.c | 18 +++++---- .../libawt_xawt/awt/screencast_portal.c | 39 ++++++++++++++----- 6 files changed, 55 insertions(+), 20 deletions(-) diff --git a/src/java.desktop/unix/native/libawt_xawt/awt/fp_pipewire.h b/src/java.desktop/unix/native/libawt_xawt/awt/fp_pipewire.h index e5985af5eee..d39f7c833b7 100644 --- a/src/java.desktop/unix/native/libawt_xawt/awt/fp_pipewire.h +++ b/src/java.desktop/unix/native/libawt_xawt/awt/fp_pipewire.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -58,7 +58,6 @@ void (*fp_pw_stream_destroy)(struct pw_stream *stream); void (*fp_pw_init)(int *argc, char **argv[]); -void (*fp_pw_deinit)(void); struct pw_core * (*fp_pw_context_connect_fd)(struct pw_context *context, diff --git a/src/java.desktop/unix/native/libawt_xawt/awt/gtk3_interface.c b/src/java.desktop/unix/native/libawt_xawt/awt/gtk3_interface.c index ff637430edf..3b115780acf 100644 --- a/src/java.desktop/unix/native/libawt_xawt/awt/gtk3_interface.c +++ b/src/java.desktop/unix/native/libawt_xawt/awt/gtk3_interface.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -285,6 +285,9 @@ GtkApi* gtk3_load(JNIEnv *env, const char* lib_name) fp_g_main_context_iteration = dl_symbol("g_main_context_iteration"); + fp_g_main_context_default = dl_symbol("g_main_context_default"); + fp_g_main_context_is_owner = dl_symbol("g_main_context_is_owner"); + fp_g_value_init = dl_symbol("g_value_init"); fp_g_type_is_a = dl_symbol("g_type_is_a"); @@ -556,6 +559,7 @@ GtkApi* gtk3_load(JNIEnv *env, const char* lib_name) fp_g_signal_connect_data = dl_symbol("g_signal_connect_data"); fp_gtk_widget_show = dl_symbol("gtk_widget_show"); fp_gtk_main = dl_symbol("gtk_main"); + fp_gtk_main_level = dl_symbol("gtk_main_level"); fp_g_path_get_dirname = dl_symbol("g_path_get_dirname"); @@ -3125,6 +3129,8 @@ static void gtk3_init(GtkApi* gtk) { gtk->g_uuid_string_is_valid = fp_g_uuid_string_is_valid; gtk->g_main_context_iteration = fp_g_main_context_iteration; + gtk->g_main_context_default = fp_g_main_context_default; + gtk->g_main_context_is_owner = fp_g_main_context_is_owner; gtk->g_error_free = fp_g_error_free; gtk->g_unix_fd_list_get = fp_g_unix_fd_list_get; diff --git a/src/java.desktop/unix/native/libawt_xawt/awt/gtk3_interface.h b/src/java.desktop/unix/native/libawt_xawt/awt/gtk3_interface.h index 054510d488b..6849645784d 100644 --- a/src/java.desktop/unix/native/libawt_xawt/awt/gtk3_interface.h +++ b/src/java.desktop/unix/native/libawt_xawt/awt/gtk3_interface.h @@ -392,6 +392,9 @@ static void (*fp_g_object_set)(gpointer object, ...); static gboolean (*fp_g_main_context_iteration)(GMainContext *context, gboolean may_block); +static GMainContext *(*fp_g_main_context_default)(); +static gboolean (*fp_g_main_context_is_owner)(GMainContext* context); + static gboolean (*fp_g_str_has_prefix)(const gchar *str, const gchar *prefix); static gchar** (*fp_g_strsplit)(const gchar *string, const gchar *delimiter, gint max_tokens); diff --git a/src/java.desktop/unix/native/libawt_xawt/awt/gtk_interface.h b/src/java.desktop/unix/native/libawt_xawt/awt/gtk_interface.h index 33bd4a6cee8..ac6d2d7fdf6 100644 --- a/src/java.desktop/unix/native/libawt_xawt/awt/gtk_interface.h +++ b/src/java.desktop/unix/native/libawt_xawt/awt/gtk_interface.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -792,6 +792,8 @@ typedef struct GtkApi { gboolean (*g_main_context_iteration)(GMainContext *context, gboolean may_block); + GMainContext *(*g_main_context_default)(); + gboolean (*g_main_context_is_owner)(GMainContext* context); void (*g_error_free)(GError *error); diff --git a/src/java.desktop/unix/native/libawt_xawt/awt/screencast_pipewire.c b/src/java.desktop/unix/native/libawt_xawt/awt/screencast_pipewire.c index 6884b939ae7..e81bd5410b3 100644 --- a/src/java.desktop/unix/native/libawt_xawt/awt/screencast_pipewire.c +++ b/src/java.desktop/unix/native/libawt_xawt/awt/screencast_pipewire.c @@ -49,6 +49,7 @@ static GString *activeSessionToken; struct ScreenSpace screenSpace = {0}; static struct PwLoopData pw = {0}; +volatile bool isGtkMainThread = FALSE; jclass tokenStorageClass = NULL; jmethodID storeTokenMethodID = NULL; @@ -132,10 +133,6 @@ static void doCleanup() { screenSpace.screenCount = 0; } - if (!sessionClosed) { - fp_pw_deinit(); - } - gtk->g_string_set_size(activeSessionToken, 0); sessionClosed = TRUE; } @@ -581,6 +578,13 @@ static gboolean doLoop(GdkRectangle requestedArea) { if (!pw.loop && !sessionClosed) { pw.loop = fp_pw_thread_loop_new("AWT Pipewire Thread", NULL); + if (!pw.loop) { + // in case someone called the pw_deinit before + DEBUG_SCREENCAST("pw_init\n", NULL); + fp_pw_init(NULL, NULL); + pw.loop = fp_pw_thread_loop_new("AWT Pipewire Thread", NULL); + } + if (!pw.loop) { DEBUG_SCREENCAST("!!! Could not create a loop\n", NULL); doCleanup(); @@ -711,7 +715,6 @@ static gboolean loadSymbols() { LOAD_SYMBOL(fp_pw_stream_disconnect, "pw_stream_disconnect"); LOAD_SYMBOL(fp_pw_stream_destroy, "pw_stream_destroy"); LOAD_SYMBOL(fp_pw_init, "pw_init"); - LOAD_SYMBOL(fp_pw_deinit, "pw_deinit"); LOAD_SYMBOL(fp_pw_context_connect_fd, "pw_context_connect_fd"); LOAD_SYMBOL(fp_pw_core_disconnect, "pw_core_disconnect"); LOAD_SYMBOL(fp_pw_context_new, "pw_context_new"); @@ -945,9 +948,10 @@ JNIEXPORT jint JNICALL Java_sun_awt_screencast_ScreencastHelper_getRGBPixelsImpl ? (*env)->GetStringUTFChars(env, jtoken, NULL) : NULL; + isGtkMainThread = gtk->g_main_context_is_owner(gtk->g_main_context_default()); DEBUG_SCREENCAST( - "taking screenshot at \n\tx: %5i y %5i w %5i h %5i with token |%s|\n", - jx, jy, jwidth, jheight, token + "taking screenshot at \n\tx: %5i y %5i w %5i h %5i\n\twith token |%s| isGtkMainThread %d\n", + jx, jy, jwidth, jheight, token, isGtkMainThread ); int attemptResult = makeScreencast( diff --git a/src/java.desktop/unix/native/libawt_xawt/awt/screencast_portal.c b/src/java.desktop/unix/native/libawt_xawt/awt/screencast_portal.c index 8590cf27da2..45c1b55942f 100644 --- a/src/java.desktop/unix/native/libawt_xawt/awt/screencast_portal.c +++ b/src/java.desktop/unix/native/libawt_xawt/awt/screencast_portal.c @@ -32,6 +32,7 @@ #include "screencast_pipewire.h" #include "screencast_portal.h" +extern volatile bool isGtkMainThread; extern struct ScreenSpace screenSpace; @@ -67,6 +68,27 @@ gboolean validateToken(const gchar *token) { return isValid; } +void waitForCallback(struct DBusCallbackHelper *helper) { + if (!helper) { + return; + } + + if (isGtkMainThread) { + gtk->gtk_main(); + } else { + while (!helper->isDone) { + // do not block if there is a GTK loop running + gtk->g_main_context_iteration(NULL, gtk->gtk_main_level() == 0); + } + } +} + +void callbackEnd() { + if (isGtkMainThread) { + gtk->gtk_main_quit(); + } +} + /** * @return TRUE on success */ @@ -362,6 +384,7 @@ static void callbackScreenCastCreateSession( } helper->isDone = TRUE; + callbackEnd(); } gboolean portalScreenCastCreateSession() { @@ -426,9 +449,7 @@ gboolean portalScreenCastCreateSession() { err->message); ERR_HANDLE(err); } else { - while (!helper.isDone) { - gtk->g_main_context_iteration(NULL, TRUE); - } + waitForCallback(&helper); } unregisterScreenCastCallback(&helper); @@ -472,6 +493,8 @@ static void callbackScreenCastSelectSources( if (result) { gtk->g_variant_unref(result); } + + callbackEnd(); } gboolean portalScreenCastSelectSources(const gchar *token) { @@ -552,9 +575,7 @@ gboolean portalScreenCastSelectSources(const gchar *token) { DEBUG_SCREENCAST("Failed to call SelectSources: %s\n", err->message); ERR_HANDLE(err); } else { - while (!helper.isDone) { - gtk->g_main_context_iteration(NULL, TRUE); - } + waitForCallback(&helper); } unregisterScreenCastCallback(&helper); @@ -640,6 +661,8 @@ static void callbackScreenCastStart( if (streams) { gtk->g_variant_unref(streams); } + + callbackEnd(); } ScreenCastResult portalScreenCastStart(const gchar *token) { @@ -693,9 +716,7 @@ ScreenCastResult portalScreenCastStart(const gchar *token) { DEBUG_SCREENCAST("Failed to start session: %s\n", err->message); ERR_HANDLE(err); } else { - while (!helper.isDone) { - gtk->g_main_context_iteration(NULL, TRUE); - } + waitForCallback(&helper); } unregisterScreenCastCallback(&helper); From ddc8a9d5da28f67071a0d6bed981ab4ad70337be Mon Sep 17 00:00:00 2001 From: Sean Mullan <mullan@openjdk.org> Date: Mon, 25 Nov 2024 13:10:59 +0000 Subject: [PATCH 216/311] 8344366: Remove Security Manager dependencies from javax.net.ssl and sun.security.ssl packages Reviewed-by: coffeys, ascarpino, hchao --- .../javax/net/ssl/HttpsURLConnection.java | 15 --- .../javax/net/ssl/KeyManagerFactory.java | 8 +- .../classes/javax/net/ssl/SSLContext.java | 5 - .../javax/net/ssl/SSLSocketFactory.java | 21 ++-- .../javax/net/ssl/TrustManagerFactory.java | 8 +- .../action/OpenFileInputStreamAction.java | 53 ---------- .../sun/security/ssl/AlpnExtension.java | 9 +- .../sun/security/ssl/DHKeyExchange.java | 6 +- .../classes/sun/security/ssl/NamedGroup.java | 6 +- .../ssl/PredefinedDHParameterSpecs.java | 10 +- .../classes/sun/security/ssl/SSLCipher.java | 11 +-- .../sun/security/ssl/SSLConfiguration.java | 31 +++--- .../sun/security/ssl/SSLContextImpl.java | 47 +++------ .../sun/security/ssl/SSLEngineImpl.java | 55 ++++------- .../sun/security/ssl/SSLExtension.java | 3 +- .../classes/sun/security/ssl/SSLLogger.java | 5 +- .../security/ssl/SSLSessionContextImpl.java | 10 +- .../sun/security/ssl/SSLSessionImpl.java | 87 ++-------------- .../security/ssl/ServerHandshakeContext.java | 9 +- .../security/ssl/SessionTicketExtension.java | 6 +- .../security/ssl/StatusResponseManager.java | 28 ++---- .../classes/sun/security/ssl/SunJSSE.java | 12 +-- .../sun/security/ssl/TransportContext.java | 31 ++---- .../sun/security/ssl/TrustStoreManager.java | 98 +++++++++---------- .../classes/sun/security/ssl/Utilities.java | 7 +- test/jdk/sun/security/action/Generify.java | 12 +-- 26 files changed, 150 insertions(+), 443 deletions(-) delete mode 100644 src/java.base/share/classes/sun/security/action/OpenFileInputStreamAction.java diff --git a/src/java.base/share/classes/javax/net/ssl/HttpsURLConnection.java b/src/java.base/share/classes/javax/net/ssl/HttpsURLConnection.java index d3308741ece..61bd8d140d2 100644 --- a/src/java.base/share/classes/javax/net/ssl/HttpsURLConnection.java +++ b/src/java.base/share/classes/javax/net/ssl/HttpsURLConnection.java @@ -227,11 +227,6 @@ public static void setDefaultHostnameVerifier(HostnameVerifier v) { "no default HostnameVerifier specified"); } - @SuppressWarnings("removal") - SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - sm.checkPermission(new SSLPermission("setHostnameVerifier")); - } defaultHostnameVerifier = v; } @@ -306,11 +301,6 @@ public static void setDefaultSSLSocketFactory(SSLSocketFactory sf) { "no default SSLSocketFactory specified"); } - @SuppressWarnings("removal") - SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - sm.checkSetFactory(); - } defaultSSLSocketFactory = sf; } @@ -353,11 +343,6 @@ public void setSSLSocketFactory(SSLSocketFactory sf) { "no SSLSocketFactory specified"); } - @SuppressWarnings("removal") - SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - sm.checkSetFactory(); - } sslSocketFactory = sf; } diff --git a/src/java.base/share/classes/javax/net/ssl/KeyManagerFactory.java b/src/java.base/share/classes/javax/net/ssl/KeyManagerFactory.java index 5f7c7135fa8..4ff8d35f717 100644 --- a/src/java.base/share/classes/javax/net/ssl/KeyManagerFactory.java +++ b/src/java.base/share/classes/javax/net/ssl/KeyManagerFactory.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,7 +25,6 @@ package javax.net.ssl; -import java.security.Security; import java.security.*; import java.util.Objects; @@ -62,11 +61,8 @@ public class KeyManagerFactory { * {@code ssl.KeyManagerFactory.algorithm} security property, or an * implementation-specific default if no such property exists. */ - @SuppressWarnings("removal") public static final String getDefaultAlgorithm() { - String type; - type = AccessController.doPrivileged((PrivilegedAction<String>) () -> - Security.getProperty("ssl.KeyManagerFactory.algorithm")); + String type = Security.getProperty("ssl.KeyManagerFactory.algorithm"); if (type == null) { type = "SunX509"; } diff --git a/src/java.base/share/classes/javax/net/ssl/SSLContext.java b/src/java.base/share/classes/javax/net/ssl/SSLContext.java index fe6d00daf4a..0c2087efa88 100644 --- a/src/java.base/share/classes/javax/net/ssl/SSLContext.java +++ b/src/java.base/share/classes/javax/net/ssl/SSLContext.java @@ -129,11 +129,6 @@ public static void setDefault(SSLContext context) { if (context == null) { throw new NullPointerException(); } - @SuppressWarnings("removal") - SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - sm.checkPermission(new SSLPermission("setDefaultSSLContext")); - } defaultContext = context; } diff --git a/src/java.base/share/classes/javax/net/ssl/SSLSocketFactory.java b/src/java.base/share/classes/javax/net/ssl/SSLSocketFactory.java index cb5e3318052..b90a9d4c25c 100644 --- a/src/java.base/share/classes/javax/net/ssl/SSLSocketFactory.java +++ b/src/java.base/share/classes/javax/net/ssl/SSLSocketFactory.java @@ -33,8 +33,6 @@ import java.security.*; import java.util.Locale; -import sun.security.action.GetPropertyAction; - /** * <code>SSLSocketFactory</code>s create <code>SSLSocket</code>s. * @@ -46,7 +44,7 @@ public abstract class SSLSocketFactory extends SocketFactory { static final boolean DEBUG; static { - String s = GetPropertyAction.privilegedGetProperty( + String s = System.getProperty( "javax.net.debug", "").toLowerCase(Locale.ENGLISH); DEBUG = s.contains("all") || s.contains("ssl"); } @@ -86,18 +84,15 @@ public static SocketFactory getDefault() { } } - @SuppressWarnings("removal") static String getSecurityProperty(final String name) { - return AccessController.doPrivileged((PrivilegedAction<String>) () -> { - String s = Security.getProperty(name); - if (s != null) { - s = s.trim(); - if (s.isEmpty()) { - s = null; - } + String s = Security.getProperty(name); + if (s != null) { + s = s.trim(); + if (s.isEmpty()) { + s = null; } - return s; - }); + } + return s; } /** diff --git a/src/java.base/share/classes/javax/net/ssl/TrustManagerFactory.java b/src/java.base/share/classes/javax/net/ssl/TrustManagerFactory.java index 429800ab169..af08d97f0d2 100644 --- a/src/java.base/share/classes/javax/net/ssl/TrustManagerFactory.java +++ b/src/java.base/share/classes/javax/net/ssl/TrustManagerFactory.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,7 +25,6 @@ package javax.net.ssl; -import java.security.Security; import java.security.*; import java.util.Objects; @@ -74,11 +73,8 @@ public class TrustManagerFactory { * {@code ssl.TrustManagerFactory.algorithm} security property, or an * implementation-specific default if no such property exists. */ - @SuppressWarnings("removal") public static final String getDefaultAlgorithm() { - String type; - type = AccessController.doPrivileged((PrivilegedAction<String>) () -> - Security.getProperty( "ssl.TrustManagerFactory.algorithm")); + String type = Security.getProperty("ssl.TrustManagerFactory.algorithm"); if (type == null) { type = "SunX509"; } diff --git a/src/java.base/share/classes/sun/security/action/OpenFileInputStreamAction.java b/src/java.base/share/classes/sun/security/action/OpenFileInputStreamAction.java deleted file mode 100644 index 4692a22eb41..00000000000 --- a/src/java.base/share/classes/sun/security/action/OpenFileInputStreamAction.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright (c) 2002, 2004, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package sun.security.action; - -import java.io.*; - -import java.security.PrivilegedExceptionAction; - -/** - * A convenience class for opening a FileInputStream as a privileged action. - * - * @author Andreas Sterbenz - */ -public class OpenFileInputStreamAction - implements PrivilegedExceptionAction<FileInputStream> { - - private final File file; - - public OpenFileInputStreamAction(File file) { - this.file = file; - } - - public OpenFileInputStreamAction(String filename) { - this.file = new File(filename); - } - - public FileInputStream run() throws Exception { - return new FileInputStream(file); - } -} diff --git a/src/java.base/share/classes/sun/security/ssl/AlpnExtension.java b/src/java.base/share/classes/sun/security/ssl/AlpnExtension.java index 45e911a73bf..d44ec034411 100644 --- a/src/java.base/share/classes/sun/security/ssl/AlpnExtension.java +++ b/src/java.base/share/classes/sun/security/ssl/AlpnExtension.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -28,8 +28,6 @@ import java.io.IOException; import java.nio.ByteBuffer; import java.nio.charset.Charset; -import java.security.AccessController; -import java.security.PrivilegedAction; import java.security.Security; import java.util.*; import javax.net.ssl.SSLEngine; @@ -63,10 +61,7 @@ final class AlpnExtension { static final Charset alpnCharset; static { - @SuppressWarnings("removal") - String alpnCharsetString = AccessController.doPrivileged( - (PrivilegedAction<String>) () - -> Security.getProperty("jdk.tls.alpnCharset")); + String alpnCharsetString = Security.getProperty("jdk.tls.alpnCharset"); if ((alpnCharsetString == null) || (alpnCharsetString.length() == 0)) { alpnCharsetString = "ISO_8859_1"; diff --git a/src/java.base/share/classes/sun/security/ssl/DHKeyExchange.java b/src/java.base/share/classes/sun/security/ssl/DHKeyExchange.java index 6706e24e22a..1fc9d07cdd8 100644 --- a/src/java.base/share/classes/sun/security/ssl/DHKeyExchange.java +++ b/src/java.base/share/classes/sun/security/ssl/DHKeyExchange.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -40,7 +40,6 @@ import javax.crypto.interfaces.DHPublicKey; import javax.crypto.spec.DHParameterSpec; import javax.crypto.spec.DHPublicKeySpec; -import sun.security.action.GetPropertyAction; import sun.security.ssl.NamedGroup.NamedGroupSpec; import sun.security.ssl.X509Authentication.X509Possession; import sun.security.util.KeyUtil; @@ -261,8 +260,7 @@ public PrivateKey getPrivateKey() { private final boolean exportable; static { - String property = GetPropertyAction.privilegedGetProperty( - "jdk.tls.ephemeralDHKeySize"); + String property = System.getProperty("jdk.tls.ephemeralDHKeySize"); if (property == null || property.isEmpty()) { useLegacyEphemeralDHKeys = false; useSmartEphemeralDHKeys = false; diff --git a/src/java.base/share/classes/sun/security/ssl/NamedGroup.java b/src/java.base/share/classes/sun/security/ssl/NamedGroup.java index 2a6c966a254..46280a05355 100644 --- a/src/java.base/share/classes/sun/security/ssl/NamedGroup.java +++ b/src/java.base/share/classes/sun/security/ssl/NamedGroup.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -39,7 +39,6 @@ import javax.crypto.spec.DHParameterSpec; import sun.security.ssl.ECDHKeyExchange.ECDHEPossession; import sun.security.util.CurveDB; -import sun.security.action.GetPropertyAction; /** * An enum containing all known named groups for use in TLS. @@ -752,8 +751,7 @@ static final class SupportedGroups { // // If the System Property is not defined or the value is empty, the // default groups and preferences will be used. - String property = GetPropertyAction - .privilegedGetProperty("jdk.tls.namedGroups"); + String property = System.getProperty("jdk.tls.namedGroups"); if (property != null && !property.isEmpty()) { // remove double quote marks from beginning/end of the property if (property.length() > 1 && property.charAt(0) == '"' && diff --git a/src/java.base/share/classes/sun/security/ssl/PredefinedDHParameterSpecs.java b/src/java.base/share/classes/sun/security/ssl/PredefinedDHParameterSpecs.java index 14f4a9b4d90..e510fe92b0e 100644 --- a/src/java.base/share/classes/sun/security/ssl/PredefinedDHParameterSpecs.java +++ b/src/java.base/share/classes/sun/security/ssl/PredefinedDHParameterSpecs.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -230,13 +230,7 @@ final class PredefinedDHParameterSpecs { static final Map<Integer, DHParameterSpec> ffdheParams; static { - @SuppressWarnings("removal") - String property = AccessController.doPrivileged( - new PrivilegedAction<String>() { - public String run() { - return Security.getProperty(PROPERTY_NAME); - } - }); + String property = Security.getProperty(PROPERTY_NAME); if (property != null && !property.isEmpty()) { // remove double quote marks from beginning/end of the property diff --git a/src/java.base/share/classes/sun/security/ssl/SSLCipher.java b/src/java.base/share/classes/sun/security/ssl/SSLCipher.java index fa6bfe0bed6..d11ffc96b47 100644 --- a/src/java.base/share/classes/sun/security/ssl/SSLCipher.java +++ b/src/java.base/share/classes/sun/security/ssl/SSLCipher.java @@ -36,13 +36,11 @@ import javax.crypto.spec.GCMParameterSpec; import javax.crypto.spec.IvParameterSpec; import java.nio.ByteBuffer; -import java.security.AccessController; import java.security.GeneralSecurityException; import java.security.InvalidAlgorithmParameterException; import java.security.InvalidKeyException; import java.security.Key; import java.security.NoSuchAlgorithmException; -import java.security.PrivilegedAction; import java.security.SecureRandom; import java.security.Security; import java.security.spec.AlgorithmParameterSpec; @@ -380,14 +378,7 @@ enum SSLCipher { static { final long max = 4611686018427387904L; // 2^62 - @SuppressWarnings("removal") - String prop = AccessController.doPrivileged( - new PrivilegedAction<String>() { - @Override - public String run() { - return Security.getProperty("jdk.tls.keyLimits"); - } - }); + String prop = Security.getProperty("jdk.tls.keyLimits"); if (prop != null) { String[] propvalue = prop.split(","); diff --git a/src/java.base/share/classes/sun/security/ssl/SSLConfiguration.java b/src/java.base/share/classes/sun/security/ssl/SSLConfiguration.java index 421867aa4c4..bb032e019d3 100644 --- a/src/java.base/share/classes/sun/security/ssl/SSLConfiguration.java +++ b/src/java.base/share/classes/sun/security/ssl/SSLConfiguration.java @@ -25,8 +25,6 @@ package sun.security.ssl; -import java.security.AccessControlContext; -import java.security.AccessController; import java.security.AlgorithmConstraints; import java.security.NoSuchAlgorithmException; import java.util.*; @@ -38,8 +36,6 @@ import javax.net.ssl.SSLEngine; import javax.net.ssl.SSLParameters; import javax.net.ssl.SSLSocket; -import sun.security.action.GetIntegerAction; -import sun.security.action.GetPropertyAction; import sun.security.ssl.SSLExtension.ClientExtensions; import sun.security.ssl.SSLExtension.ServerExtensions; @@ -78,9 +74,7 @@ final class SSLConfiguration implements Cloneable { BiFunction<SSLSocket, List<String>, String> socketAPSelector; BiFunction<SSLEngine, List<String>, String> engineAPSelector; - @SuppressWarnings("removal") - HashMap<HandshakeCompletedListener, AccessControlContext> - handshakeListeners; + HashSet<HandshakeCompletedListener> handshakeListeners; boolean noSniExtension; boolean noSniMatcher; @@ -105,7 +99,7 @@ final class SSLConfiguration implements Cloneable { "jdk.tls.acknowledgeCloseNotify", false); // Set the max size limit for Handshake Message to 2^15 - static final int maxHandshakeMessageSize = GetIntegerAction.privilegedGetProperty( + static final int maxHandshakeMessageSize = Integer.getInteger( "jdk.tls.maxHandshakeMessageSize", 32768); // Limit the certificate chain length accepted from clients @@ -147,7 +141,7 @@ final class SSLConfiguration implements Cloneable { * jdk.tls.maxCertificateChainLength system property works for both * server and client modes. */ - Integer maxCertificateChainLength = GetIntegerAction.privilegedGetProperty( + Integer maxCertificateChainLength = Integer.getInteger( "jdk.tls.maxCertificateChainLength"); if (maxCertificateChainLength != null && maxCertificateChainLength >= 0) { globalPropSet = true; @@ -164,7 +158,7 @@ final class SSLConfiguration implements Cloneable { * property is set and its value >= 0, it uses that value. * - Otherwise it is set to a default value of 8. */ - Integer inboundClientLen = GetIntegerAction.privilegedGetProperty( + Integer inboundClientLen = Integer.getInteger( "jdk.tls.server.maxInboundCertificateChainLength"); // Default for jdk.tls.server.maxInboundCertificateChainLength is 8 @@ -186,7 +180,7 @@ final class SSLConfiguration implements Cloneable { * property is set and its value >= 0, it uses that value. * - Otherwise it is set to a default value of 10. */ - Integer inboundServerLen = GetIntegerAction.privilegedGetProperty( + Integer inboundServerLen = Integer.getInteger( "jdk.tls.client.maxInboundCertificateChainLength"); // Default for jdk.tls.client.maxInboundCertificateChainLength is 10 @@ -203,7 +197,7 @@ final class SSLConfiguration implements Cloneable { * client. The value must be between 0 and 10. Default is defined by * SERVER_NST_DEFAULT. */ - Integer nstServerCount = GetIntegerAction.privilegedGetProperty( + Integer nstServerCount = Integer.getInteger( "jdk.tls.server.newSessionTicketCount"); if (nstServerCount == null || nstServerCount < 0 || nstServerCount > 10) { @@ -384,15 +378,14 @@ void setSSLParameters(SSLParameters params) { } // SSLSocket only - @SuppressWarnings("removal") void addHandshakeCompletedListener( HandshakeCompletedListener listener) { if (handshakeListeners == null) { - handshakeListeners = new HashMap<>(4); + handshakeListeners = new HashSet<>(4); } - handshakeListeners.put(listener, AccessController.getContext()); + handshakeListeners.add(listener); } // SSLSocket only @@ -403,7 +396,7 @@ void removeHandshakeCompletedListener( throw new IllegalArgumentException("no listeners"); } - if (handshakeListeners.remove(listener) == null) { + if (!handshakeListeners.remove(listener)) { throw new IllegalArgumentException("listener not registered"); } @@ -532,14 +525,14 @@ void toggleClientMode() { } @Override - @SuppressWarnings({"removal","unchecked", "CloneDeclaresCloneNotSupported"}) + @SuppressWarnings({"unchecked", "CloneDeclaresCloneNotSupported"}) public Object clone() { // Note that only references to the configurations are copied. try { SSLConfiguration config = (SSLConfiguration)super.clone(); if (handshakeListeners != null) { config.handshakeListeners = - (HashMap<HandshakeCompletedListener, AccessControlContext>) + (HashSet<HandshakeCompletedListener>) handshakeListeners.clone(); } @@ -573,7 +566,7 @@ private static final class CustomizedServerSignatureSchemes { * system property. */ private static String[] getCustomizedSignatureScheme(String propertyName) { - String property = GetPropertyAction.privilegedGetProperty(propertyName); + String property = System.getProperty(propertyName); if (SSLLogger.isOn && SSLLogger.isOn("ssl,sslctx")) { SSLLogger.fine( "System property " + propertyName + " is set to '" + diff --git a/src/java.base/share/classes/sun/security/ssl/SSLContextImpl.java b/src/java.base/share/classes/sun/security/ssl/SSLContextImpl.java index 04bca94f0c0..f09270aa9e6 100644 --- a/src/java.base/share/classes/sun/security/ssl/SSLContextImpl.java +++ b/src/java.base/share/classes/sun/security/ssl/SSLContextImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -32,7 +32,6 @@ import java.util.*; import java.util.concurrent.locks.ReentrantLock; import javax.net.ssl.*; -import sun.security.action.GetPropertyAction; import sun.security.provider.certpath.AlgorithmChecker; import sun.security.validator.Validator; @@ -409,7 +408,7 @@ private static List<CipherSuite> getApplicableCipherSuites( private static Collection<CipherSuite> getCustomizedCipherSuites( String propertyName) { - String property = GetPropertyAction.privilegedGetProperty(propertyName); + String property = System.getProperty(propertyName); if (SSLLogger.isOn && SSLLogger.isOn("ssl,sslctx")) { SSLLogger.fine( "System property " + propertyName + " is set to '" + @@ -742,7 +741,7 @@ private static class CustomizedSSLProtocols { private static void populate(String propname, ArrayList<ProtocolVersion> arrayList) { - String property = GetPropertyAction.privilegedGetProperty(propname); + String property = System.getProperty(propname); if (property == null) { return; } @@ -957,28 +956,20 @@ private static TrustManager[] getTrustManagers() throws Exception { return tmf.getTrustManagers(); } - @SuppressWarnings("removal") private static KeyManager[] getKeyManagers() throws Exception { - final Map<String,String> props = new HashMap<>(); - AccessController.doPrivileged( - new PrivilegedExceptionAction<Object>() { - @Override - public Object run() { - props.put("keyStore", System.getProperty( - "javax.net.ssl.keyStore", "")); - props.put("keyStoreType", System.getProperty( - "javax.net.ssl.keyStoreType", - KeyStore.getDefaultType())); - props.put("keyStoreProvider", System.getProperty( - "javax.net.ssl.keyStoreProvider", "")); - props.put("keyStorePasswd", System.getProperty( - "javax.net.ssl.keyStorePassword", "")); - return null; - } - }); - - final String defaultKeyStore = props.get("keyStore"); + Map<String,String> props = new HashMap<>(); + props.put("keyStore", System.getProperty( + "javax.net.ssl.keyStore", "")); + props.put("keyStoreType", System.getProperty( + "javax.net.ssl.keyStoreType", + KeyStore.getDefaultType())); + props.put("keyStoreProvider", System.getProperty( + "javax.net.ssl.keyStoreProvider", "")); + props.put("keyStorePasswd", System.getProperty( + "javax.net.ssl.keyStorePassword", "")); + + String defaultKeyStore = props.get("keyStore"); String defaultKeyStoreType = props.get("keyStoreType"); String defaultKeyStoreProvider = props.get("keyStoreProvider"); if (SSLLogger.isOn && SSLLogger.isOn("ssl,defaultctx")) { @@ -1001,13 +992,7 @@ public Object run() { try { if (!defaultKeyStore.isEmpty() && !NONE.equals(defaultKeyStore)) { - fs = AccessController.doPrivileged( - new PrivilegedExceptionAction<FileInputStream>() { - @Override - public FileInputStream run() throws Exception { - return new FileInputStream(defaultKeyStore); - } - }); + fs = new FileInputStream(defaultKeyStore); } String defaultKeyStorePassword = props.get("keyStorePasswd"); diff --git a/src/java.base/share/classes/sun/security/ssl/SSLEngineImpl.java b/src/java.base/share/classes/sun/security/ssl/SSLEngineImpl.java index 36b5bd4a78c..4b19f5a9d7b 100644 --- a/src/java.base/share/classes/sun/security/ssl/SSLEngineImpl.java +++ b/src/java.base/share/classes/sun/security/ssl/SSLEngineImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -28,9 +28,6 @@ import java.io.IOException; import java.nio.ByteBuffer; import java.nio.ReadOnlyBufferException; -import java.security.AccessController; -import java.security.PrivilegedActionException; -import java.security.PrivilegedExceptionAction; import java.util.List; import java.util.Map; import java.util.concurrent.locks.ReentrantLock; @@ -1202,17 +1199,25 @@ public void run() { } try { - @SuppressWarnings("removal") - var dummy = AccessController.doPrivileged( - new DelegatedAction(hc), engine.conContext.acc); - } catch (PrivilegedActionException pae) { + while (!hc.delegatedActions.isEmpty()) { + Map.Entry<Byte, ByteBuffer> me = + hc.delegatedActions.poll(); + if (me != null) { + try { + hc.dispatch(me.getKey(), me.getValue()); + } catch (Exception e) { + throw hc.conContext.fatal(Alert.INTERNAL_ERROR, + "Unhandled exception", e); + } + } + } + } catch (SSLException se) { // Get the handshake context again in case the // handshaking has completed. - Exception reportedException = pae.getException(); // Report to both the TransportContext... if (engine.conContext.delegatedThrown == null) { - engine.conContext.delegatedThrown = reportedException; + engine.conContext.delegatedThrown = se; } // ...and the HandshakeContext in case condition @@ -1220,11 +1225,10 @@ public void run() { // around. hc = engine.conContext.handshakeContext; if (hc != null) { - hc.delegatedThrown = reportedException; + hc.delegatedThrown = se; } else if (engine.conContext.closeReason != null) { // Update the reason in case there was a previous. - engine.conContext.closeReason = - getTaskThrown(reportedException); + engine.conContext.closeReason = getTaskThrown(se); } } catch (RuntimeException rte) { // Get the handshake context again in case the @@ -1257,30 +1261,5 @@ public void run() { engine.engineLock.unlock(); } } - - private static class DelegatedAction - implements PrivilegedExceptionAction<Void> { - final HandshakeContext context; - DelegatedAction(HandshakeContext context) { - this.context = context; - } - - @Override - public Void run() throws Exception { - while (!context.delegatedActions.isEmpty()) { - Map.Entry<Byte, ByteBuffer> me = - context.delegatedActions.poll(); - if (me != null) { - try { - context.dispatch(me.getKey(), me.getValue()); - } catch (Exception e) { - throw context.conContext.fatal(Alert.INTERNAL_ERROR, - "Unhandled exception", e); - } - } - } - return null; - } - } } } diff --git a/src/java.base/share/classes/sun/security/ssl/SSLExtension.java b/src/java.base/share/classes/sun/security/ssl/SSLExtension.java index 2cb74fb1056..b28ef763796 100644 --- a/src/java.base/share/classes/sun/security/ssl/SSLExtension.java +++ b/src/java.base/share/classes/sun/security/ssl/SSLExtension.java @@ -30,7 +30,6 @@ import java.text.MessageFormat; import java.util.*; -import sun.security.action.GetPropertyAction; import sun.security.ssl.SSLHandshake.HandshakeMessage; import sun.security.util.HexDumpEncoder; @@ -820,7 +819,7 @@ static final class ServerExtensions { // Get disabled extensions, which could be customized with System Properties. private static Collection<String> getDisabledExtensions( String propertyName) { - String property = GetPropertyAction.privilegedGetProperty(propertyName); + String property = System.getProperty(propertyName); if (SSLLogger.isOn && SSLLogger.isOn("ssl,sslctx")) { SSLLogger.fine( "System property " + propertyName + " is set to '" + diff --git a/src/java.base/share/classes/sun/security/ssl/SSLLogger.java b/src/java.base/share/classes/sun/security/ssl/SSLLogger.java index 7783967836b..9736bfaba0d 100644 --- a/src/java.base/share/classes/sun/security/ssl/SSLLogger.java +++ b/src/java.base/share/classes/sun/security/ssl/SSLLogger.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -41,7 +41,6 @@ import java.time.format.DateTimeFormatter; import java.util.*; -import sun.security.action.GetPropertyAction; import sun.security.util.HexDumpEncoder; import sun.security.util.Debug; import sun.security.x509.*; @@ -64,7 +63,7 @@ public final class SSLLogger { public static final boolean isOn; static { - String p = GetPropertyAction.privilegedGetProperty("javax.net.debug"); + String p = System.getProperty("javax.net.debug"); if (p != null) { if (p.isEmpty()) { property = ""; diff --git a/src/java.base/share/classes/sun/security/ssl/SSLSessionContextImpl.java b/src/java.base/share/classes/sun/security/ssl/SSLSessionContextImpl.java index f3e22633ab4..0ff80f0c76c 100644 --- a/src/java.base/share/classes/sun/security/ssl/SSLSessionContextImpl.java +++ b/src/java.base/share/classes/sun/security/ssl/SSLSessionContextImpl.java @@ -36,8 +36,6 @@ import javax.net.ssl.SSLSession; import javax.net.ssl.SSLSessionContext; -import sun.security.action.GetIntegerAction; -import sun.security.action.GetPropertyAction; import sun.security.util.Cache; @@ -324,10 +322,10 @@ private int getDefaults(boolean server) { // Property for Session Cache state if (server) { - st = GetPropertyAction.privilegedGetProperty( + st = System.getProperty( "jdk.tls.server.enableSessionTicketExtension", "true"); } else { - st = GetPropertyAction.privilegedGetProperty( + st = System.getProperty( "jdk.tls.client.enableSessionTicketExtension", "true"); } @@ -337,7 +335,7 @@ private int getDefaults(boolean server) { // Property for Session Ticket Timeout. The value can be changed // by SSLSessionContext.setSessionTimeout(int) - String s = GetPropertyAction.privilegedGetProperty( + String s = System.getProperty( "jdk.tls.server.sessionTicketTimeout"); if (s != null) { try { @@ -364,7 +362,7 @@ private int getDefaults(boolean server) { } } - int defaultCacheLimit = GetIntegerAction.privilegedGetProperty( + int defaultCacheLimit = Integer.getInteger( "javax.net.ssl.sessionCacheSize", DEFAULT_MAX_CACHE_SIZE); if (defaultCacheLimit >= 0) { diff --git a/src/java.base/share/classes/sun/security/ssl/SSLSessionImpl.java b/src/java.base/share/classes/sun/security/ssl/SSLSessionImpl.java index b887eedd8dc..f02709bc31d 100644 --- a/src/java.base/share/classes/sun/security/ssl/SSLSessionImpl.java +++ b/src/java.base/share/classes/sun/security/ssl/SSLSessionImpl.java @@ -49,7 +49,6 @@ import javax.net.ssl.SNIServerName; import javax.net.ssl.SSLException; import javax.net.ssl.SSLPeerUnverifiedException; -import javax.net.ssl.SSLPermission; import javax.net.ssl.SSLSessionBindingEvent; import javax.net.ssl.SSLSessionBindingListener; import javax.net.ssl.SSLSessionContext; @@ -913,24 +912,8 @@ public byte[] getId() { * are currently valid in this process. For client sessions, * this returns null. */ - @SuppressWarnings("removal") @Override public SSLSessionContext getSessionContext() { - /* - * An interim security policy until we can do something - * more specific in 1.2. Only allow trusted code (code which - * can set system properties) to get an - * SSLSessionContext. This is to limit the ability of code to - * look up specific sessions or enumerate over them. Otherwise, - * code can only get session objects from successful SSL - * connections which implies that they must have had permission - * to make the network connection in the first place. - */ - SecurityManager sm; - if ((sm = System.getSecurityManager()) != null) { - sm.checkPermission(new SSLPermission("getSSLSessionContext")); - } - return context; } @@ -1236,10 +1219,9 @@ public void invalidate() { /* * Table of application-specific session data indexed by an application - * key and the calling security context. This is important since - * sessions can be shared across different protection domains. + * key. */ - private final ConcurrentHashMap<SecureKey, Object> boundValues; + private final ConcurrentHashMap<String, Object> boundValues; /** * Assigns a session value. Session change events are given if @@ -1251,8 +1233,7 @@ public void putValue(String key, Object value) { throw new IllegalArgumentException("arguments can not be null"); } - SecureKey secureKey = new SecureKey(key); - Object oldValue = boundValues.put(secureKey, value); + Object oldValue = boundValues.put(key, value); if (oldValue instanceof SSLSessionBindingListener) { SSLSessionBindingEvent e; @@ -1280,8 +1261,7 @@ public Object getValue(String key) { throw new IllegalArgumentException("argument can not be null"); } - SecureKey secureKey = new SecureKey(key); - return boundValues.get(secureKey); + return boundValues.get(key); } @@ -1295,8 +1275,7 @@ public void removeValue(String key) { throw new IllegalArgumentException("argument can not be null"); } - SecureKey secureKey = new SecureKey(key); - Object value = boundValues.remove(secureKey); + Object value = boundValues.remove(key); if (value instanceof SSLSessionBindingListener) { SSLSessionBindingEvent e; @@ -1315,15 +1294,7 @@ public void removeValue(String key) { */ @Override public String[] getValueNames() { - ArrayList<Object> v = new ArrayList<>(); - Object securityCtx = SecureKey.getCurrentSecurityContext(); - for (SecureKey key : boundValues.keySet()) { - if (securityCtx.equals(key.getSecurityContext())) { - v.add(key.getAppKey()); - } - } - - return v.toArray(new String[0]); + return boundValues.keySet().toArray(new String[0]); } /** @@ -1522,49 +1493,3 @@ public String toString() { return "Session(" + creationTime + "|" + getCipherSuite() + ")"; } } - -/** - * This "struct" class serves as a Hash Key that combines an - * application-specific key and a security context. - */ -class SecureKey { - private static final Object nullObject = new Object(); - private final Object appKey; - private final Object securityCtx; - - static Object getCurrentSecurityContext() { - @SuppressWarnings("removal") - SecurityManager sm = System.getSecurityManager(); - Object context = null; - - if (sm != null) - context = sm.getSecurityContext(); - if (context == null) - context = nullObject; - return context; - } - - SecureKey(Object key) { - this.appKey = key; - this.securityCtx = getCurrentSecurityContext(); - } - - Object getAppKey() { - return appKey; - } - - Object getSecurityContext() { - return securityCtx; - } - - @Override - public int hashCode() { - return appKey.hashCode() ^ securityCtx.hashCode(); - } - - @Override - public boolean equals(Object o) { - return o instanceof SecureKey && ((SecureKey)o).appKey.equals(appKey) - && ((SecureKey)o).securityCtx.equals(securityCtx); - } -} diff --git a/src/java.base/share/classes/sun/security/ssl/ServerHandshakeContext.java b/src/java.base/share/classes/sun/security/ssl/ServerHandshakeContext.java index 11b625e5791..8bb7def0f57 100644 --- a/src/java.base/share/classes/sun/security/ssl/ServerHandshakeContext.java +++ b/src/java.base/share/classes/sun/security/ssl/ServerHandshakeContext.java @@ -27,9 +27,7 @@ import java.io.IOException; import java.security.AlgorithmConstraints; -import java.security.AccessController; import sun.security.util.LegacyAlgorithmConstraints; -import sun.security.action.GetLongAction; class ServerHandshakeContext extends HandshakeContext { // To prevent the TLS renegotiation issues, by setting system property @@ -61,10 +59,9 @@ class ServerHandshakeContext extends HandshakeContext { ServerHandshakeContext(SSLContextImpl sslContext, TransportContext conContext) throws IOException { super(sslContext, conContext); - @SuppressWarnings("removal") - long respTimeOut = AccessController.doPrivileged( - new GetLongAction("jdk.tls.stapling.responseTimeout", - DEFAULT_STATUS_RESP_DELAY)); + long respTimeOut = Long.getLong( + "jdk.tls.stapling.responseTimeout", + DEFAULT_STATUS_RESP_DELAY); statusRespTimeout = respTimeOut >= 0 ? respTimeOut : DEFAULT_STATUS_RESP_DELAY; handshakeConsumers.put( diff --git a/src/java.base/share/classes/sun/security/ssl/SessionTicketExtension.java b/src/java.base/share/classes/sun/security/ssl/SessionTicketExtension.java index acf2b175f55..e143dcb302e 100644 --- a/src/java.base/share/classes/sun/security/ssl/SessionTicketExtension.java +++ b/src/java.base/share/classes/sun/security/ssl/SessionTicketExtension.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -41,7 +41,6 @@ import static sun.security.ssl.SSLExtension.CH_SESSION_TICKET; import static sun.security.ssl.SSLExtension.SH_SESSION_TICKET; -import sun.security.action.GetPropertyAction; import sun.security.ssl.SSLExtension.ExtensionConsumer; import sun.security.ssl.SSLExtension.SSLExtensionSpec; import sun.security.ssl.SSLHandshake.HandshakeMessage; @@ -78,8 +77,7 @@ final class SessionTicketExtension { private static final int KEYLEN = 256; static { - String s = GetPropertyAction.privilegedGetProperty( - "jdk.tls.server.statelessKeyTimeout"); + String s = System.getProperty("jdk.tls.server.statelessKeyTimeout"); if (s != null) { int kt; try { diff --git a/src/java.base/share/classes/sun/security/ssl/StatusResponseManager.java b/src/java.base/share/classes/sun/security/ssl/StatusResponseManager.java index 1baf3264122..1383db1ce82 100644 --- a/src/java.base/share/classes/sun/security/ssl/StatusResponseManager.java +++ b/src/java.base/share/classes/sun/security/ssl/StatusResponseManager.java @@ -27,14 +27,10 @@ import java.io.IOException; import java.net.URI; import java.net.URISyntaxException; -import java.security.AccessController; import java.security.cert.Extension; import java.security.cert.X509Certificate; import java.util.*; import java.util.concurrent.*; -import sun.security.action.GetBooleanAction; -import sun.security.action.GetIntegerAction; -import sun.security.action.GetPropertyAction; import sun.security.provider.certpath.CertId; import sun.security.provider.certpath.OCSP; import sun.security.provider.certpath.OCSPResponse; @@ -63,20 +59,17 @@ final class StatusResponseManager { * Create a StatusResponseManager with default parameters. */ StatusResponseManager() { - @SuppressWarnings("removal") - int cap = AccessController.doPrivileged( - new GetIntegerAction("jdk.tls.stapling.cacheSize", - DEFAULT_CACHE_SIZE)); + int cap = Integer.getInteger( + "jdk.tls.stapling.cacheSize", + DEFAULT_CACHE_SIZE); cacheCapacity = cap > 0 ? cap : 0; - @SuppressWarnings("removal") - int life = AccessController.doPrivileged( - new GetIntegerAction("jdk.tls.stapling.cacheLifetime", - DEFAULT_CACHE_LIFETIME)); + int life = Integer.getInteger( + "jdk.tls.stapling.cacheLifetime", + DEFAULT_CACHE_LIFETIME); cacheLifetime = life > 0 ? life : 0; - String uriStr = GetPropertyAction - .privilegedGetProperty("jdk.tls.stapling.responderURI"); + String uriStr = System.getProperty("jdk.tls.stapling.responderURI"); URI tmpURI; try { tmpURI = ((uriStr != null && !uriStr.isEmpty()) ? @@ -86,10 +79,9 @@ final class StatusResponseManager { } defaultResponder = tmpURI; - respOverride = GetBooleanAction - .privilegedGetProperty("jdk.tls.stapling.responderOverride"); - ignoreExtensions = GetBooleanAction - .privilegedGetProperty("jdk.tls.stapling.ignoreExtensions"); + respOverride = Boolean.getBoolean("jdk.tls.stapling.responderOverride"); + ignoreExtensions = Boolean.getBoolean + ("jdk.tls.stapling.ignoreExtensions"); threadMgr = new ScheduledThreadPoolExecutor(DEFAULT_CORE_THREADS, r -> { diff --git a/src/java.base/share/classes/sun/security/ssl/SunJSSE.java b/src/java.base/share/classes/sun/security/ssl/SunJSSE.java index dce2aad8400..611a6588b4c 100644 --- a/src/java.base/share/classes/sun/security/ssl/SunJSSE.java +++ b/src/java.base/share/classes/sun/security/ssl/SunJSSE.java @@ -25,7 +25,7 @@ package sun.security.ssl; -import java.security.*; +import java.security.Provider; import java.util.*; import static sun.security.util.SecurityConstants.PROVIDER_VER; @@ -46,20 +46,12 @@ public SunJSSE() { registerAlgorithms(); } - @SuppressWarnings("removal") - private void registerAlgorithms() { - AccessController.doPrivileged((PrivilegedAction<Void>) () -> { - doRegister(); - return null; - }); - } - private void ps(String type, String algo, String cn, List<String> a, HashMap<String, String> attrs) { putService(new Provider.Service(this, type, algo, cn, a, attrs)); } - private void doRegister() { + private void registerAlgorithms() { ps("Signature", "MD5andSHA1withRSA", "sun.security.ssl.RSASignature", null, null); diff --git a/src/java.base/share/classes/sun/security/ssl/TransportContext.java b/src/java.base/share/classes/sun/security/ssl/TransportContext.java index f65a08dfcfe..717c81723ff 100644 --- a/src/java.base/share/classes/sun/security/ssl/TransportContext.java +++ b/src/java.base/share/classes/sun/security/ssl/TransportContext.java @@ -27,9 +27,6 @@ import java.io.IOException; import java.net.SocketException; -import java.security.AccessControlContext; -import java.security.AccessController; -import java.security.PrivilegedAction; import java.util.HashMap; import java.util.HashSet; import java.util.List; @@ -49,8 +46,6 @@ final class TransportContext implements ConnectionContext { // registered plaintext consumers final Map<Byte, SSLConsumer> consumers; - @SuppressWarnings("removal") - final AccessControlContext acc; final SSLContextImpl sslContext; final SSLConfiguration sslConfig; @@ -134,7 +129,6 @@ final class TransportContext implements ConnectionContext { inputRecord, outputRecord, false); } - @SuppressWarnings("removal") private TransportContext(SSLContextImpl sslContext, SSLTransport transport, SSLConfiguration sslConfig, InputRecord inputRecord, OutputRecord outputRecord, boolean isUnsureMode) { @@ -154,7 +148,6 @@ private TransportContext(SSLContextImpl sslContext, SSLTransport transport, this.clientVerifyData = emptyByteArray; this.serverVerifyData = emptyByteArray; - this.acc = AccessController.getContext(); this.consumers = new HashMap<>(); if (inputRecord instanceof DTLSInputRecord dtlsInputRecord) { @@ -677,34 +670,22 @@ HandshakeStatus finishPostHandshake() { // A separate thread is allocated to deliver handshake completion // events. private static class NotifyHandshake implements Runnable { - @SuppressWarnings("removal") - private final Set<Map.Entry<HandshakeCompletedListener, - AccessControlContext>> targets; // who gets notified + private final Set<HandshakeCompletedListener> + targets; // who gets notified private final HandshakeCompletedEvent event; // the notification NotifyHandshake( - @SuppressWarnings("removal") - Map<HandshakeCompletedListener,AccessControlContext> listeners, + Set<HandshakeCompletedListener> listeners, HandshakeCompletedEvent event) { - this.targets = new HashSet<>(listeners.entrySet()); // clone + this.targets = new HashSet<>(listeners); // clone this.event = event; } - @SuppressWarnings("removal") @Override public void run() { // Don't need to synchronize, as it only runs in one thread. - for (Map.Entry<HandshakeCompletedListener, - AccessControlContext> entry : targets) { - final HandshakeCompletedListener listener = entry.getKey(); - AccessControlContext acc = entry.getValue(); - AccessController.doPrivileged(new PrivilegedAction<Void>() { - @Override - public Void run() { - listener.handshakeCompleted(event); - return null; - } - }, acc); + for (HandshakeCompletedListener listener : targets) { + listener.handshakeCompleted(event); } } } diff --git a/src/java.base/share/classes/sun/security/ssl/TrustStoreManager.java b/src/java.base/share/classes/sun/security/ssl/TrustStoreManager.java index 79ac35397f8..8f464e058e2 100644 --- a/src/java.base/share/classes/sun/security/ssl/TrustStoreManager.java +++ b/src/java.base/share/classes/sun/security/ssl/TrustStoreManager.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -27,11 +27,10 @@ import java.io.*; import java.lang.ref.WeakReference; -import java.security.*; +import java.security.KeyStore; import java.security.cert.*; import java.util.*; import java.util.concurrent.locks.ReentrantLock; -import sun.security.action.*; import sun.security.util.FilePaths; import sun.security.validator.TrustStoreUtil; @@ -75,7 +74,7 @@ public static KeyStore getTrustedKeyStore() throws Exception { private static final class TrustStoreDescriptor { private static final String fileSep = File.separator; private static final String defaultStorePath = - GetPropertyAction.privilegedGetProperty("java.home") + + System.getProperty("java.home") + fileSep + "lib" + fileSep + "security"; private static final String defaultStore = FilePaths.cacerts(); private static final String jsseDefaultStore = @@ -122,57 +121,50 @@ private TrustStoreDescriptor(String storeName, String storeType, * Create an instance of TrustStoreDescriptor for the default * trusted KeyStore. */ - @SuppressWarnings({"removal","Convert2Lambda"}) + @SuppressWarnings("Convert2Lambda") static TrustStoreDescriptor createInstance() { - return AccessController.doPrivileged( - new PrivilegedAction<TrustStoreDescriptor>() { - - @Override - public TrustStoreDescriptor run() { - // Get the system properties for trust store. - String storePropName = System.getProperty( - "javax.net.ssl.trustStore", jsseDefaultStore); - String storePropType = System.getProperty( - "javax.net.ssl.trustStoreType", - KeyStore.getDefaultType()); - String storePropProvider = System.getProperty( - "javax.net.ssl.trustStoreProvider", ""); - String storePropPassword = System.getProperty( - "javax.net.ssl.trustStorePassword", ""); - - String temporaryName = ""; - File temporaryFile = null; - long temporaryTime = 0L; - if (!"NONE".equals(storePropName)) { - String[] fileNames = - new String[] {storePropName, defaultStore}; - for (String fileName : fileNames) { - File f = new File(fileName); - if (f.isFile() && f.canRead()) { - temporaryName = fileName; - temporaryFile = f; - temporaryTime = f.lastModified(); - - break; - } - - // Not break, the file is inaccessible. - if (SSLLogger.isOn && - SSLLogger.isOn("trustmanager")) { - SSLLogger.fine( - "Inaccessible trust store: " + - fileName); - } - } - } else { - temporaryName = storePropName; + // Get the system properties for trust store. + String storePropName = System.getProperty( + "javax.net.ssl.trustStore", jsseDefaultStore); + String storePropType = System.getProperty( + "javax.net.ssl.trustStoreType", + KeyStore.getDefaultType()); + String storePropProvider = System.getProperty( + "javax.net.ssl.trustStoreProvider", ""); + String storePropPassword = System.getProperty( + "javax.net.ssl.trustStorePassword", ""); + + String temporaryName = ""; + File temporaryFile = null; + long temporaryTime = 0L; + if (!"NONE".equals(storePropName)) { + String[] fileNames = + new String[] {storePropName, defaultStore}; + for (String fileName : fileNames) { + File f = new File(fileName); + if (f.isFile() && f.canRead()) { + temporaryName = fileName; + temporaryFile = f; + temporaryTime = f.lastModified(); + + break; } - return new TrustStoreDescriptor( - temporaryName, storePropType, storePropProvider, - storePropPassword, temporaryFile, temporaryTime); + // Not break, the file is inaccessible. + if (SSLLogger.isOn && + SSLLogger.isOn("trustmanager")) { + SSLLogger.fine( + "Inaccessible trust store: " + + fileName); + } } - }); + } else { + temporaryName = storePropName; + } + + return new TrustStoreDescriptor( + temporaryName, storePropType, storePropProvider, + storePropPassword, temporaryFile, temporaryTime); } @Override @@ -384,8 +376,8 @@ private static KeyStore loadKeyStore( } if (!"NONE".equals(descriptor.storeName)) { - try (@SuppressWarnings("removal") FileInputStream fis = AccessController.doPrivileged( - new OpenFileInputStreamAction(descriptor.storeFile))) { + try (FileInputStream fis = + new FileInputStream(descriptor.storeFile)) { ks.load(fis, password); } catch (FileNotFoundException fnfe) { // No file available, no KeyStore available. diff --git a/src/java.base/share/classes/sun/security/ssl/Utilities.java b/src/java.base/share/classes/sun/security/ssl/Utilities.java index f2a17323486..3ed022db382 100644 --- a/src/java.base/share/classes/sun/security/ssl/Utilities.java +++ b/src/java.base/share/classes/sun/security/ssl/Utilities.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -30,7 +30,6 @@ import java.util.regex.Pattern; import javax.net.ssl.*; import sun.net.util.IPAddressUtil; -import sun.security.action.GetPropertyAction; /** * A utility class to share the static methods. @@ -128,12 +127,10 @@ private static SNIHostName rawToSNIHostName(String hostname) { /** * Return the value of the boolean System property propName. - * - * Note use of privileged action. Do NOT make accessible to applications. */ static boolean getBooleanProperty(String propName, boolean defaultValue) { // if set, require value of either true or false - String b = GetPropertyAction.privilegedGetProperty(propName); + String b = System.getProperty(propName); if (b == null) { return defaultValue; } else if (b.equalsIgnoreCase("false")) { diff --git a/test/jdk/sun/security/action/Generify.java b/test/jdk/sun/security/action/Generify.java index 55b0e7735db..09cbb3fbb42 100644 --- a/test/jdk/sun/security/action/Generify.java +++ b/test/jdk/sun/security/action/Generify.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -28,7 +28,6 @@ * @modules java.base/sun.security.action */ -import java.io.*; import java.security.*; import sun.security.action.*; @@ -74,14 +73,5 @@ public static void main(String[] args) throws Exception { } else { throw new SecurityException("property test failed"); } - - File f = new File(System.getProperty("test.src", "."), "Generify.java"); - FileInputStream fis = AccessController.doPrivileged - (new OpenFileInputStreamAction(f)); - if (fis != null) { - System.out.println("file test passed"); - } else { - throw new SecurityException("file test failed"); - } } } From c6b14c62f609ee0539893fa3778eb5d0277748c0 Mon Sep 17 00:00:00 2001 From: Adam Sotona <asotona@openjdk.org> Date: Mon, 25 Nov 2024 13:45:34 +0000 Subject: [PATCH 217/311] 8344841: ClassPrinter prints confusing value for null Reviewed-by: liach --- .../classfile/impl/ClassPrinterImpl.java | 37 ++++++++++++++----- test/jdk/jdk/classfile/ClassPrinterTest.java | 4 +- 2 files changed, 29 insertions(+), 12 deletions(-) diff --git a/src/java.base/share/classes/jdk/internal/classfile/impl/ClassPrinterImpl.java b/src/java.base/share/classes/jdk/internal/classfile/impl/ClassPrinterImpl.java index 1ded017f2a2..183ee323b52 100644 --- a/src/java.base/share/classes/jdk/internal/classfile/impl/ClassPrinterImpl.java +++ b/src/java.base/share/classes/jdk/internal/classfile/impl/ClassPrinterImpl.java @@ -53,6 +53,7 @@ import static java.lang.classfile.constantpool.PoolEntry.TAG_LONG; import static java.lang.classfile.constantpool.PoolEntry.TAG_STRING; import static java.lang.classfile.constantpool.PoolEntry.*; +import static java.lang.constant.ConstantDescs.BSM_NULL_CONSTANT; import static java.util.Objects.requireNonNull; import static jdk.internal.classfile.impl.ClassPrinterImpl.Style.BLOCK; import static jdk.internal.classfile.impl.ClassPrinterImpl.Style.FLOW; @@ -274,7 +275,12 @@ public static void toYaml(Node node, Consumer<String> out) { private static void toYaml(int indent, boolean skipFirstIndent, Node node, Consumer<String> out) { switch (node) { case LeafNode leaf -> { - out.accept(quoteAndEscapeYaml(leaf.value())); + var v = leaf.value(); + if (BSM_NULL_CONSTANT.equals(v)) { + out.accept("null"); + } else { + out.accept(quoteAndEscapeYaml(v)); + } } case ListNodeImpl list -> { switch (list.style()) { @@ -329,6 +335,7 @@ private static String quoteAndEscapeYaml(ConstantDesc value) { String s = String.valueOf(value); if (value instanceof Number) return s; if (s.length() == 0) return "''"; + if (s.equalsIgnoreCase("null")) return "'" + s + "'"; var sb = new StringBuilder(s.length() << 1); s.chars().forEach(c -> { switch (c) { @@ -358,7 +365,12 @@ public static void toJson(Node node, Consumer<String> out) { private static void toJson(int indent, boolean skipFirstIndent, Node node, Consumer<String> out) { switch (node) { case LeafNode leaf -> { - out.accept(quoteAndEscapeJson(leaf.value())); + var v = leaf.value(); + if (BSM_NULL_CONSTANT.equals(v)) { + out.accept("null"); + } else { + out.accept(quoteAndEscapeJson(v)); + } } case ListNodeImpl list -> { out.accept("["); @@ -434,7 +446,12 @@ private static void toXml(int indent, boolean skipFirstIndent, Node node, Consum switch (node) { case LeafNode leaf -> { out.accept("<" + name + ">"); - out.accept(xmlEscape(leaf.value())); + var v = leaf.value(); + if (BSM_NULL_CONSTANT.equals(v)) { + out.accept("<null/>"); + } else { + out.accept(xmlEscape(v)); + } } case ListNodeImpl list -> { switch (list.style()) { @@ -542,7 +559,7 @@ private static Stream<ConstantDesc> convertVTIs(CodeAttribute lr, List<Verificat ret.accept("long"); ret.accept("long2"); } - case NULL -> ret.accept("null"); + case NULL -> ret.accept(BSM_NULL_CONSTANT); case TOP -> ret.accept("?"); case UNINITIALIZED_THIS -> ret.accept("THIS"); } @@ -929,9 +946,9 @@ private static Node[] attributesToTree(List<Attribute<?>> attributes, Verbosity nodes.add(map("enclosing method", "class", ema.enclosingClass().name().stringValue(), "method name", ema.enclosingMethodName() - .map(Utf8Entry::stringValue).orElse("null"), + .<ConstantDesc>map(Utf8Entry::stringValue).orElse(BSM_NULL_CONSTANT), "method type", ema.enclosingMethodType() - .map(Utf8Entry::stringValue).orElse("null"))); + .<ConstantDesc>map(Utf8Entry::stringValue).orElse(BSM_NULL_CONSTANT))); case ExceptionsAttribute exa -> nodes.add(list("exceptions", "exc", exa.exceptions().stream() .map(e -> e.name().stringValue()))); @@ -940,15 +957,15 @@ private static Node[] attributesToTree(List<Attribute<?>> attributes, Verbosity .map(ic -> new MapNodeImpl(FLOW, "cls").with( leaf("inner class", ic.innerClass().name().stringValue()), leaf("outer class", ic.outerClass() - .map(cle -> cle.name().stringValue()).orElse("null")), - leaf("inner name", ic.innerName().map(Utf8Entry::stringValue).orElse("null")), + .map(cle -> (ConstantDesc)cle.name().stringValue()).orElse(BSM_NULL_CONSTANT)), + leaf("inner name", ic.innerName().<ConstantDesc>map(Utf8Entry::stringValue).orElse(BSM_NULL_CONSTANT)), list("flags", "flag", ic.flags().stream().map(AccessFlag::name)))))); case MethodParametersAttribute mpa -> { var n = new MapNodeImpl(BLOCK, "method parameters"); for (int i = 0; i < mpa.parameters().size(); i++) { var p = mpa.parameters().get(i); n.with(new MapNodeImpl(FLOW, i + 1).with( - leaf("name", p.name().map(Utf8Entry::stringValue).orElse("null")), + leaf("name", p.name().<ConstantDesc>map(Utf8Entry::stringValue).orElse(BSM_NULL_CONSTANT)), list("flags", "flag", p.flags().stream().map(AccessFlag::name)))); } } @@ -956,7 +973,7 @@ private static Node[] attributesToTree(List<Attribute<?>> attributes, Verbosity nodes.add(new MapNodeImpl(BLOCK, "module") .with(leaf("name", ma.moduleName().name().stringValue()), list("flags","flag", ma.moduleFlags().stream().map(AccessFlag::name)), - leaf("version", ma.moduleVersion().map(Utf8Entry::stringValue).orElse("null")), + leaf("version", ma.moduleVersion().<ConstantDesc>map(Utf8Entry::stringValue).orElse(BSM_NULL_CONSTANT)), list("uses", "class", ma.uses().stream().map(ce -> ce.name().stringValue())), new ListNodeImpl(BLOCK, "requires", ma.requires().stream().map(req -> new MapNodeImpl(FLOW, "req").with( diff --git a/test/jdk/jdk/classfile/ClassPrinterTest.java b/test/jdk/jdk/classfile/ClassPrinterTest.java index bd95075a08e..7ea69f58889 100644 --- a/test/jdk/jdk/classfile/ClassPrinterTest.java +++ b/test/jdk/jdk/classfile/ClassPrinterTest.java @@ -472,7 +472,7 @@ void testPrintJsonTraceAll() throws IOException { "source file": "Foo.java", "inner classes": [ {"inner class": "Phee", "outer class": "Phoo", "inner name": "InnerName", "flags": ["PROTECTED"]}, - {"inner class": "Phoo", "outer class": "null", "inner name": "null", "flags": ["PRIVATE"]}], + {"inner class": "Phoo", "outer class": null, "inner name": null, "flags": ["PRIVATE"]}], "enclosing method": {"class": "Phee", "method name": "enclosingMethod", "method type": "(Ljava/util/Collection;)Ljava/lang/Double;"}, "signature": "LBoo;LPhee;LPhoo;", "nest host": "Phee", @@ -725,7 +725,7 @@ void testPrintXmlTraceAll() throws IOException { <source_file>Foo.java</source_file> <inner_classes> <cls><inner_class>Phee</inner_class><outer_class>Phoo</outer_class><inner_name>InnerName</inner_name><flags><flag>PROTECTED</flag></flags></cls> - <cls><inner_class>Phoo</inner_class><outer_class>null</outer_class><inner_name>null</inner_name><flags><flag>PRIVATE</flag></flags></cls></inner_classes> + <cls><inner_class>Phoo</inner_class><outer_class><null/></outer_class><inner_name><null/></inner_name><flags><flag>PRIVATE</flag></flags></cls></inner_classes> <enclosing_method><class>Phee</class><method_name>enclosingMethod</method_name><method_type>(Ljava/util/Collection;)Ljava/lang/Double;</method_type></enclosing_method> <signature>LBoo;LPhee;LPhoo;</signature> <nest_host>Phee</nest_host> From cb1c73663e91e632d643c23e6c5acc1c5118ac8b Mon Sep 17 00:00:00 2001 From: Roman Kennke <rkennke@openjdk.org> Date: Mon, 25 Nov 2024 13:48:02 +0000 Subject: [PATCH 218/311] 8344363: FullGCForwarding::initialize_flags is called after ObjLayout::initialize Reviewed-by: stefank, shade, ayang --- src/hotspot/share/gc/g1/g1Arguments.cpp | 3 --- src/hotspot/share/gc/g1/g1Arguments.hpp | 1 - .../share/gc/parallel/parallelArguments.cpp | 3 ++- .../share/gc/serial/serialArguments.cpp | 6 +++--- .../share/gc/serial/serialArguments.hpp | 2 +- .../gc/shenandoah/shenandoahArguments.cpp | 7 ++----- .../gc/shenandoah/shenandoahArguments.hpp | 1 - src/hotspot/share/memory/universe.cpp | 3 +++ src/hotspot/share/runtime/arguments.cpp | 18 +++++++++++------- src/hotspot/share/runtime/arguments.hpp | 1 + src/hotspot/share/runtime/threads.cpp | 3 --- 11 files changed, 23 insertions(+), 25 deletions(-) diff --git a/src/hotspot/share/gc/g1/g1Arguments.cpp b/src/hotspot/share/gc/g1/g1Arguments.cpp index 35dfbb7290e..1ae5f2ce76f 100644 --- a/src/hotspot/share/gc/g1/g1Arguments.cpp +++ b/src/hotspot/share/gc/g1/g1Arguments.cpp @@ -244,10 +244,7 @@ void G1Arguments::initialize() { if (max_parallel_refinement_threads > UINT_MAX / divisor) { vm_exit_during_initialization("Too large parallelism for remembered sets."); } -} -void G1Arguments::initialize_heap_flags_and_sizes() { - GCArguments::initialize_heap_flags_and_sizes(); FullGCForwarding::initialize_flags(heap_reserved_size_bytes()); } diff --git a/src/hotspot/share/gc/g1/g1Arguments.hpp b/src/hotspot/share/gc/g1/g1Arguments.hpp index 234e61d4ff0..73fa0557f7d 100644 --- a/src/hotspot/share/gc/g1/g1Arguments.hpp +++ b/src/hotspot/share/gc/g1/g1Arguments.hpp @@ -39,7 +39,6 @@ class G1Arguments : public GCArguments { static void parse_verification_type(const char* type); virtual void initialize_alignments(); - virtual void initialize_heap_flags_and_sizes(); virtual void initialize(); virtual size_t conservative_max_heap_alignment(); diff --git a/src/hotspot/share/gc/parallel/parallelArguments.cpp b/src/hotspot/share/gc/parallel/parallelArguments.cpp index 4035259e6d6..d9972ccc146 100644 --- a/src/hotspot/share/gc/parallel/parallelArguments.cpp +++ b/src/hotspot/share/gc/parallel/parallelArguments.cpp @@ -83,6 +83,8 @@ void ParallelArguments::initialize() { if (FLAG_IS_DEFAULT(ParallelRefProcEnabled) && ParallelGCThreads > 1) { FLAG_SET_DEFAULT(ParallelRefProcEnabled, true); } + + FullGCForwarding::initialize_flags(heap_reserved_size_bytes()); } // The alignment used for boundary between young gen and old gen @@ -128,7 +130,6 @@ void ParallelArguments::initialize_heap_flags_and_sizes() { // Redo everything from the start initialize_heap_flags_and_sizes_one_pass(); } - FullGCForwarding::initialize_flags(heap_reserved_size_bytes()); } size_t ParallelArguments::heap_reserved_size_bytes() { diff --git a/src/hotspot/share/gc/serial/serialArguments.cpp b/src/hotspot/share/gc/serial/serialArguments.cpp index f8efa192807..c9d2caf9063 100644 --- a/src/hotspot/share/gc/serial/serialArguments.cpp +++ b/src/hotspot/share/gc/serial/serialArguments.cpp @@ -24,12 +24,12 @@ #include "precompiled.hpp" #include "gc/shared/fullGCForwarding.hpp" -#include "gc/shared/genArguments.hpp" +#include "gc/shared/gcArguments.hpp" #include "gc/serial/serialArguments.hpp" #include "gc/serial/serialHeap.hpp" -void SerialArguments::initialize_heap_flags_and_sizes() { - GenArguments::initialize_heap_flags_and_sizes(); +void SerialArguments::initialize() { + GCArguments::initialize(); FullGCForwarding::initialize_flags(MaxHeapSize); } diff --git a/src/hotspot/share/gc/serial/serialArguments.hpp b/src/hotspot/share/gc/serial/serialArguments.hpp index d12bd7d8e59..90c3225ff8d 100644 --- a/src/hotspot/share/gc/serial/serialArguments.hpp +++ b/src/hotspot/share/gc/serial/serialArguments.hpp @@ -31,8 +31,8 @@ class CollectedHeap; class SerialArguments : public GenArguments { private: + virtual void initialize(); virtual CollectedHeap* create_heap(); - virtual void initialize_heap_flags_and_sizes(); }; #endif // SHARE_GC_SERIAL_SERIALARGUMENTS_HPP diff --git a/src/hotspot/share/gc/shenandoah/shenandoahArguments.cpp b/src/hotspot/share/gc/shenandoah/shenandoahArguments.cpp index ca95cde83b1..4376e9d1150 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahArguments.cpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahArguments.cpp @@ -176,6 +176,8 @@ void ShenandoahArguments::initialize() { if (FLAG_IS_DEFAULT(TLABAllocationWeight)) { FLAG_SET_DEFAULT(TLABAllocationWeight, 90); } + + FullGCForwarding::initialize_flags(MaxHeapSize); } size_t ShenandoahArguments::conservative_max_heap_alignment() { @@ -199,11 +201,6 @@ void ShenandoahArguments::initialize_alignments() { HeapAlignment = align; } -void ShenandoahArguments::initialize_heap_flags_and_sizes() { - GCArguments::initialize_heap_flags_and_sizes(); - FullGCForwarding::initialize_flags(MaxHeapSize); -} - CollectedHeap* ShenandoahArguments::create_heap() { return new ShenandoahHeap(new ShenandoahCollectorPolicy()); } diff --git a/src/hotspot/share/gc/shenandoah/shenandoahArguments.hpp b/src/hotspot/share/gc/shenandoah/shenandoahArguments.hpp index ad54b1d235c..bc73d9a2d12 100644 --- a/src/hotspot/share/gc/shenandoah/shenandoahArguments.hpp +++ b/src/hotspot/share/gc/shenandoah/shenandoahArguments.hpp @@ -35,7 +35,6 @@ class ShenandoahArguments : public GCArguments { virtual void initialize(); virtual size_t conservative_max_heap_alignment(); - virtual void initialize_heap_flags_and_sizes(); virtual CollectedHeap* create_heap(); }; diff --git a/src/hotspot/share/memory/universe.cpp b/src/hotspot/share/memory/universe.cpp index 6daeb2f1045..ad4dd045bcb 100644 --- a/src/hotspot/share/memory/universe.cpp +++ b/src/hotspot/share/memory/universe.cpp @@ -62,6 +62,7 @@ #include "oops/instanceMirrorKlass.hpp" #include "oops/klass.inline.hpp" #include "oops/objArrayOop.inline.hpp" +#include "oops/objLayout.hpp" #include "oops/oop.inline.hpp" #include "oops/oopHandle.inline.hpp" #include "oops/typeArrayKlass.hpp" @@ -868,6 +869,8 @@ jint universe_init() { // Initialize CPUTimeCounters object, which must be done before creation of the heap. CPUTimeCounters::initialize(); + ObjLayout::initialize(); + #ifdef _LP64 MetaspaceShared::adjust_heap_sizes_for_dumping(); #endif // _LP64 diff --git a/src/hotspot/share/runtime/arguments.cpp b/src/hotspot/share/runtime/arguments.cpp index 0b16a634489..1917108519e 100644 --- a/src/hotspot/share/runtime/arguments.cpp +++ b/src/hotspot/share/runtime/arguments.cpp @@ -3654,33 +3654,35 @@ jint Arguments::parse(const JavaVMInitArgs* initial_cmd_args) { Arguments::print_on(&st); } + return JNI_OK; +} + +void Arguments::set_compact_headers_flags() { #ifdef _LP64 if (UseCompactObjectHeaders && FLAG_IS_CMDLINE(UseCompressedClassPointers) && !UseCompressedClassPointers) { warning("Compact object headers require compressed class pointers. Disabling compact object headers."); FLAG_SET_DEFAULT(UseCompactObjectHeaders, false); } - if (UseCompactObjectHeaders && LockingMode != LM_LIGHTWEIGHT) { - FLAG_SET_DEFAULT(LockingMode, LM_LIGHTWEIGHT); - } if (UseCompactObjectHeaders && !UseObjectMonitorTable) { // If UseCompactObjectHeaders is on the command line, turn on UseObjectMonitorTable. if (FLAG_IS_CMDLINE(UseCompactObjectHeaders)) { FLAG_SET_DEFAULT(UseObjectMonitorTable, true); - // If UseObjectMonitorTable is on the command line, turn off UseCompactObjectHeaders. + // If UseObjectMonitorTable is on the command line, turn off UseCompactObjectHeaders. } else if (FLAG_IS_CMDLINE(UseObjectMonitorTable)) { FLAG_SET_DEFAULT(UseCompactObjectHeaders, false); - // If neither on the command line, the defaults are incompatible, but turn on UseObjectMonitorTable. + // If neither on the command line, the defaults are incompatible, but turn on UseObjectMonitorTable. } else { FLAG_SET_DEFAULT(UseObjectMonitorTable, true); } } + if (UseCompactObjectHeaders && LockingMode != LM_LIGHTWEIGHT) { + FLAG_SET_DEFAULT(LockingMode, LM_LIGHTWEIGHT); + } if (UseCompactObjectHeaders && !UseCompressedClassPointers) { FLAG_SET_DEFAULT(UseCompressedClassPointers, true); } #endif - - return JNI_OK; } jint Arguments::apply_ergo() { @@ -3693,6 +3695,8 @@ jint Arguments::apply_ergo() { GCConfig::arguments()->initialize(); + set_compact_headers_flags(); + if (UseCompressedClassPointers) { CompressedKlassPointers::pre_initialize(); } diff --git a/src/hotspot/share/runtime/arguments.hpp b/src/hotspot/share/runtime/arguments.hpp index 2105d21430a..0b4d89f3ad2 100644 --- a/src/hotspot/share/runtime/arguments.hpp +++ b/src/hotspot/share/runtime/arguments.hpp @@ -264,6 +264,7 @@ class Arguments : AllStatic { static void set_conservative_max_heap_alignment(); static void set_use_compressed_oops(); static jint set_ergonomics_flags(); + static void set_compact_headers_flags(); // Limits the given heap size by the maximum amount of virtual // memory this process is currently allowed to use. It also takes // the virtual-to-physical ratio of the current GC into account. diff --git a/src/hotspot/share/runtime/threads.cpp b/src/hotspot/share/runtime/threads.cpp index 73f2e87f5c7..f6b7b7956e2 100644 --- a/src/hotspot/share/runtime/threads.cpp +++ b/src/hotspot/share/runtime/threads.cpp @@ -497,9 +497,6 @@ jint Threads::create_vm(JavaVMInitArgs* args, bool* canTryAgain) { // Timing (must come after argument parsing) TraceTime timer("Create VM", TRACETIME_LOG(Info, startuptime)); - // Initialize object layout after parsing the args - ObjLayout::initialize(); - // Initialize the os module after parsing the args jint os_init_2_result = os::init_2(); if (os_init_2_result != JNI_OK) return os_init_2_result; From e29b0edc9739801c8371ac601a466428916d60b4 Mon Sep 17 00:00:00 2001 From: Kevin Walls <kevinw@openjdk.org> Date: Mon, 25 Nov 2024 13:50:58 +0000 Subject: [PATCH 219/311] 8344181: Remove SecurityManager and related calls from jdk.management and jdk.management.agent Reviewed-by: amenkov, cjplummer --- .../classes/jdk/internal/agent/Agent.java | 4 +- .../jdk/internal/agent/FileSystemImpl.java | 10 +--- .../jdk/internal/agent/FileSystemImpl.java | 10 +--- .../internal/DiagnosticCommandImpl.java | 7 --- .../com/sun/management/internal/Flag.java | 11 +---- ...rbageCollectionNotifInfoCompositeData.java | 28 +++++------ .../internal/GcInfoCompositeData.java | 48 ++++++++----------- .../internal/HotSpotDiagnostic.java | 38 +-------------- .../internal/PlatformMBeanProviderImpl.java | 7 +-- .../internal/VirtualThreadSchedulerImpls.java | 15 ++---- 10 files changed, 45 insertions(+), 133 deletions(-) diff --git a/src/jdk.management.agent/share/classes/jdk/internal/agent/Agent.java b/src/jdk.management.agent/share/classes/jdk/internal/agent/Agent.java index d80f36b6793..442f909f3de 100644 --- a/src/jdk.management.agent/share/classes/jdk/internal/agent/Agent.java +++ b/src/jdk.management.agent/share/classes/jdk/internal/agent/Agent.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -36,8 +36,6 @@ import java.net.MalformedURLException; import java.net.UnknownHostException; import java.nio.BufferUnderflowException; -import java.security.AccessController; -import java.security.PrivilegedAction; import java.text.MessageFormat; import java.util.HashMap; import java.util.Map; diff --git a/src/jdk.management.agent/unix/classes/jdk/internal/agent/FileSystemImpl.java b/src/jdk.management.agent/unix/classes/jdk/internal/agent/FileSystemImpl.java index a11b580d443..9f9ac5f0c06 100644 --- a/src/jdk.management.agent/unix/classes/jdk/internal/agent/FileSystemImpl.java +++ b/src/jdk.management.agent/unix/classes/jdk/internal/agent/FileSystemImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -53,12 +53,6 @@ public boolean isAccessUserOnly(File f) throws IOException { // Initialization static { - java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction<Void>() { - public Void run() { - System.loadLibrary("management_agent"); - return null; - } - }); + System.loadLibrary("management_agent"); } } diff --git a/src/jdk.management.agent/windows/classes/jdk/internal/agent/FileSystemImpl.java b/src/jdk.management.agent/windows/classes/jdk/internal/agent/FileSystemImpl.java index 5a913f9c0aa..fa4e69b2c16 100644 --- a/src/jdk.management.agent/windows/classes/jdk/internal/agent/FileSystemImpl.java +++ b/src/jdk.management.agent/windows/classes/jdk/internal/agent/FileSystemImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -64,13 +64,7 @@ public boolean isAccessUserOnly(File f) throws IOException { // Initialization static { - java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction<Void>() { - public Void run() { - System.loadLibrary("management_agent"); - return null; - } - }); + System.loadLibrary("management_agent"); init0(); } } diff --git a/src/jdk.management/share/classes/com/sun/management/internal/DiagnosticCommandImpl.java b/src/jdk.management/share/classes/com/sun/management/internal/DiagnosticCommandImpl.java index eee0ea051d4..6e456c7ad02 100644 --- a/src/jdk.management/share/classes/com/sun/management/internal/DiagnosticCommandImpl.java +++ b/src/jdk.management/share/classes/com/sun/management/internal/DiagnosticCommandImpl.java @@ -149,13 +149,6 @@ private class Wrapper { } public String execute(String[] args) { - if (permission != null) { - @SuppressWarnings("removal") - SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - sm.checkPermission(permission); - } - } if(args == null) { return executeDiagnosticCommand(cmd); } else { diff --git a/src/jdk.management/share/classes/com/sun/management/internal/Flag.java b/src/jdk.management/share/classes/com/sun/management/internal/Flag.java index bf83f40f722..10d97465b1a 100644 --- a/src/jdk.management/share/classes/com/sun/management/internal/Flag.java +++ b/src/jdk.management/share/classes/com/sun/management/internal/Flag.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -28,7 +28,6 @@ import java.util.*; import com.sun.management.VMOption; import com.sun.management.VMOption.Origin; -import java.security.AccessController; /** * Flag class is a helper class for constructing a VMOption. @@ -117,13 +116,7 @@ private static List<Flag> getFlags(String[] names, int numFlags) { static synchronized native void setStringValue(String name, String value); static { - AccessController.doPrivileged( - new java.security.PrivilegedAction<Void>() { - public Void run() { - System.loadLibrary("management"); - return null; - } - }); + System.loadLibrary("management"); initialize(); } private static native void initialize(); diff --git a/src/jdk.management/share/classes/com/sun/management/internal/GarbageCollectionNotifInfoCompositeData.java b/src/jdk.management/share/classes/com/sun/management/internal/GarbageCollectionNotifInfoCompositeData.java index 98285f34ddb..ebbda8db70c 100644 --- a/src/jdk.management/share/classes/com/sun/management/internal/GarbageCollectionNotifInfoCompositeData.java +++ b/src/jdk.management/share/classes/com/sun/management/internal/GarbageCollectionNotifInfoCompositeData.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -33,8 +33,6 @@ import javax.management.openmbean.OpenDataException; import javax.management.openmbean.OpenType; import javax.management.openmbean.SimpleType; -import java.security.AccessController; -import java.security.PrivilegedAction; import java.lang.reflect.Field; import java.util.HashMap; import sun.management.LazyCompositeData; @@ -65,19 +63,17 @@ public static CompositeData toCompositeData(GarbageCollectionNotificationInfo in } private CompositeType getCompositeTypeByBuilder() { - @SuppressWarnings("removal") - final GcInfoBuilder builder = AccessController.doPrivileged (new PrivilegedAction<GcInfoBuilder>() { - public GcInfoBuilder run() { - try { - Class<?> cl = Class.forName("com.sun.management.GcInfo"); - Field f = cl.getDeclaredField("builder"); - f.setAccessible(true); - return (GcInfoBuilder)f.get(gcNotifInfo.getGcInfo()); - } catch(ClassNotFoundException | NoSuchFieldException | IllegalAccessException e) { - return null; - } - } - }); + + GcInfoBuilder builder = null; + try { + Class<?> cl = Class.forName("com.sun.management.GcInfo"); + Field f = cl.getDeclaredField("builder"); + f.setAccessible(true); + builder = (GcInfoBuilder) f.get(gcNotifInfo.getGcInfo()); + } catch (ClassNotFoundException | NoSuchFieldException | IllegalAccessException e) { + // ignore + } + CompositeType gict = null; synchronized(compositeTypeByBuilder) { gict = compositeTypeByBuilder.get(builder); diff --git a/src/jdk.management/share/classes/com/sun/management/internal/GcInfoCompositeData.java b/src/jdk.management/share/classes/com/sun/management/internal/GcInfoCompositeData.java index fc99cb6737f..6b3d2cc7bb9 100644 --- a/src/jdk.management/share/classes/com/sun/management/internal/GcInfoCompositeData.java +++ b/src/jdk.management/share/classes/com/sun/management/internal/GcInfoCompositeData.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -38,8 +38,6 @@ import javax.management.openmbean.OpenType; import javax.management.openmbean.OpenDataException; import com.sun.management.GcInfo; -import java.security.AccessController; -import java.security.PrivilegedAction; import sun.management.LazyCompositeData; import static sun.management.LazyCompositeData.getLong; import sun.management.MappedMXBeanType; @@ -71,32 +69,24 @@ public GcInfo getGcInfo() { } public static CompositeData toCompositeData(final GcInfo info) { - @SuppressWarnings("removal") - final GcInfoBuilder builder = AccessController.doPrivileged (new PrivilegedAction<GcInfoBuilder>() { - public GcInfoBuilder run() { - try { - Class<?> cl = Class.forName("com.sun.management.GcInfo"); - Field f = cl.getDeclaredField("builder"); - f.setAccessible(true); - return (GcInfoBuilder)f.get(info); - } catch(ClassNotFoundException | NoSuchFieldException | IllegalAccessException e) { - return null; - } - } - }); - @SuppressWarnings("removal") - final Object[] extAttr = AccessController.doPrivileged (new PrivilegedAction<Object[]>() { - public Object[] run() { - try { - Class<?> cl = Class.forName("com.sun.management.GcInfo"); - Field f = cl.getDeclaredField("extAttributes"); - f.setAccessible(true); - return (Object[])f.get(info); - } catch(ClassNotFoundException | NoSuchFieldException | IllegalAccessException e) { - return null; - } - } - }); + GcInfoBuilder builder = null; + try { + Class<?> cl = Class.forName("com.sun.management.GcInfo"); + Field f = cl.getDeclaredField("builder"); + f.setAccessible(true); + builder = (GcInfoBuilder)f.get(info); + } catch(ClassNotFoundException | NoSuchFieldException | IllegalAccessException e) { + // ignore + } + Object[] extAttr = null; + try { + Class<?> cl = Class.forName("com.sun.management.GcInfo"); + Field f = cl.getDeclaredField("extAttributes"); + f.setAccessible(true); + extAttr = (Object[])f.get(info); + } catch(ClassNotFoundException | NoSuchFieldException | IllegalAccessException e) { + // ignore + } GcInfoCompositeData gcicd = new GcInfoCompositeData(info,builder,extAttr); return gcicd.getCompositeData(); diff --git a/src/jdk.management/share/classes/com/sun/management/internal/HotSpotDiagnostic.java b/src/jdk.management/share/classes/com/sun/management/internal/HotSpotDiagnostic.java index 45051020fd4..855e800a794 100644 --- a/src/jdk.management/share/classes/com/sun/management/internal/HotSpotDiagnostic.java +++ b/src/jdk.management/share/classes/com/sun/management/internal/HotSpotDiagnostic.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -29,10 +29,6 @@ import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.StandardOpenOption; -import java.security.AccessController; -import java.security.PrivilegedAction; -import java.security.PrivilegedActionException; -import java.security.PrivilegedExceptionAction; import java.util.ArrayList; import java.util.List; import javax.management.ObjectName; @@ -53,20 +49,11 @@ public HotSpotDiagnostic() { public void dumpHeap(String outputFile, boolean live) throws IOException { String propertyName = "jdk.management.heapdump.allowAnyFileSuffix"; - PrivilegedAction<Boolean> pa = () -> Boolean.parseBoolean(System.getProperty(propertyName, "false")); - @SuppressWarnings("removal") - boolean allowAnyFileSuffix = AccessController.doPrivileged(pa); + boolean allowAnyFileSuffix = Boolean.getBoolean(propertyName); if (!allowAnyFileSuffix && !outputFile.endsWith(".hprof")) { throw new IllegalArgumentException("heapdump file must have .hprof extension"); } - @SuppressWarnings("removal") - SecurityManager security = System.getSecurityManager(); - if (security != null) { - security.checkWrite(outputFile); - Util.checkControlAccess(); - } - dumpHeap0(outputFile, live); } @@ -107,7 +94,6 @@ public void setVMOption(String name, String value) { throw new NullPointerException("value cannot be null"); } - Util.checkControlAccess(); Flag flag = Flag.getFlag(name); if (flag == null) { throw new IllegalArgumentException("VM option \"" + @@ -161,33 +147,13 @@ public ObjectName getObjectName() { } @Override - @SuppressWarnings("removal") public void dumpThreads(String outputFile, ThreadDumpFormat format) throws IOException { Path file = Path.of(outputFile); if (!file.isAbsolute()) throw new IllegalArgumentException("'outputFile' not absolute path"); - // need ManagementPermission("control") - @SuppressWarnings("removal") - SecurityManager sm = System.getSecurityManager(); - if (sm != null) - Util.checkControlAccess(); - try (OutputStream out = Files.newOutputStream(file, StandardOpenOption.CREATE_NEW)) { - PrivilegedExceptionAction<Void> pa = () -> { dumpThreads(out, format); - return null; - }; - try { - AccessController.doPrivileged(pa); - } catch (PrivilegedActionException pae) { - Throwable cause = pae.getCause(); - if (cause instanceof IOException ioe) - throw ioe; - if (cause instanceof RuntimeException e) - throw e; - throw new RuntimeException(cause); - } } } diff --git a/src/jdk.management/share/classes/com/sun/management/internal/PlatformMBeanProviderImpl.java b/src/jdk.management/share/classes/com/sun/management/internal/PlatformMBeanProviderImpl.java index 721f03e7de1..3a64fe6b858 100644 --- a/src/jdk.management/share/classes/com/sun/management/internal/PlatformMBeanProviderImpl.java +++ b/src/jdk.management/share/classes/com/sun/management/internal/PlatformMBeanProviderImpl.java @@ -30,8 +30,6 @@ import java.lang.management.ManagementFactory; import java.lang.management.MemoryManagerMXBean; import java.lang.management.OperatingSystemMXBean; -import java.security.AccessController; -import java.security.PrivilegedAction; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; @@ -55,10 +53,7 @@ public final class PlatformMBeanProviderImpl extends PlatformMBeanProvider { private static OperatingSystemMXBean osMBean = null; static { - AccessController.doPrivileged((PrivilegedAction<Void>) () -> { - System.loadLibrary("management_ext"); - return null; - }); + System.loadLibrary("management_ext"); } public PlatformMBeanProviderImpl() { diff --git a/src/jdk.management/share/classes/com/sun/management/internal/VirtualThreadSchedulerImpls.java b/src/jdk.management/share/classes/com/sun/management/internal/VirtualThreadSchedulerImpls.java index 8787237f903..97c03cb79e4 100644 --- a/src/jdk.management/share/classes/com/sun/management/internal/VirtualThreadSchedulerImpls.java +++ b/src/jdk.management/share/classes/com/sun/management/internal/VirtualThreadSchedulerImpls.java @@ -55,14 +55,6 @@ public static VirtualThreadSchedulerMXBean create() { private abstract static class BaseVirtualThreadSchedulerImpl implements VirtualThreadSchedulerMXBean { - abstract void implSetParallelism(int size); - - @Override - public final void setParallelism(int size) { - Util.checkControlAccess(); - implSetParallelism(size); - } - @Override public final ObjectName getObjectName() { return Util.newObjectName("jdk.management:type=VirtualThreadScheduler"); @@ -114,7 +106,7 @@ public int getParallelism() { } @Override - void implSetParallelism(int size) { + public void setParallelism(int size) { if (Scheduler.instance() instanceof ForkJoinPool pool) { pool.setParallelism(size); if (pool.getPoolSize() < size) { @@ -163,7 +155,7 @@ public int getParallelism() { } @Override - void implSetParallelism(int size) { + public void setParallelism(int size) { throw new UnsupportedOperationException(); } @@ -182,4 +174,5 @@ public long getQueuedVirtualThreadCount() { return -1L; } } -} \ No newline at end of file +} + From 133419177d8ddcfafe0b2bd25ee918bdb3b16d3f Mon Sep 17 00:00:00 2001 From: Hamlin Li <mli@openjdk.org> Date: Mon, 25 Nov 2024 13:54:44 +0000 Subject: [PATCH 220/311] 8334474: RISC-V: verify perf of ExpandBits/CompressBits (rvv) Reviewed-by: fyang, rehn, luhenry --- .../cpu/riscv/c2_MacroAssembler_riscv.cpp | 77 ------------ .../cpu/riscv/c2_MacroAssembler_riscv.hpp | 10 -- src/hotspot/cpu/riscv/riscv.ad | 63 ---------- src/hotspot/cpu/riscv/riscv_v.ad | 110 ------------------ .../intrinsics/TestBitShuffleOpers.java | 3 +- 5 files changed, 1 insertion(+), 262 deletions(-) diff --git a/src/hotspot/cpu/riscv/c2_MacroAssembler_riscv.cpp b/src/hotspot/cpu/riscv/c2_MacroAssembler_riscv.cpp index bf553b35770..49efb619093 100644 --- a/src/hotspot/cpu/riscv/c2_MacroAssembler_riscv.cpp +++ b/src/hotspot/cpu/riscv/c2_MacroAssembler_riscv.cpp @@ -2339,83 +2339,6 @@ void C2_MacroAssembler::signum_fp_v(VectorRegister dst, VectorRegister one, Basi vfsgnj_vv(dst, one, dst, v0_t); } -void C2_MacroAssembler::compress_bits_v(Register dst, Register src, Register mask, bool is_long) { - Assembler::SEW sew = is_long ? Assembler::e64 : Assembler::e32; - // intrinsic is enabled when MaxVectorSize >= 16 - Assembler::LMUL lmul = is_long ? Assembler::m4 : Assembler::m2; - long len = is_long ? 64 : 32; - - // load the src data(in bits) to be compressed. - vsetivli(x0, 1, sew, Assembler::m1); - vmv_s_x(v0, src); - // reset the src data(in bytes) to zero. - mv(t0, len); - vsetvli(x0, t0, Assembler::e8, lmul); - vmv_v_i(v4, 0); - // convert the src data from bits to bytes. - vmerge_vim(v4, v4, 1); // v0 as the implicit mask register - // reset the dst data(in bytes) to zero. - vmv_v_i(v8, 0); - // load the mask data(in bits). - vsetivli(x0, 1, sew, Assembler::m1); - vmv_s_x(v0, mask); - // compress the src data(in bytes) to dst(in bytes). - vsetvli(x0, t0, Assembler::e8, lmul); - vcompress_vm(v8, v4, v0); - // convert the dst data from bytes to bits. - vmseq_vi(v0, v8, 1); - // store result back. - vsetivli(x0, 1, sew, Assembler::m1); - vmv_x_s(dst, v0); -} - -void C2_MacroAssembler::compress_bits_i_v(Register dst, Register src, Register mask) { - compress_bits_v(dst, src, mask, /* is_long */ false); -} - -void C2_MacroAssembler::compress_bits_l_v(Register dst, Register src, Register mask) { - compress_bits_v(dst, src, mask, /* is_long */ true); -} - -void C2_MacroAssembler::expand_bits_v(Register dst, Register src, Register mask, bool is_long) { - Assembler::SEW sew = is_long ? Assembler::e64 : Assembler::e32; - // intrinsic is enabled when MaxVectorSize >= 16 - Assembler::LMUL lmul = is_long ? Assembler::m4 : Assembler::m2; - long len = is_long ? 64 : 32; - - // load the src data(in bits) to be expanded. - vsetivli(x0, 1, sew, Assembler::m1); - vmv_s_x(v0, src); - // reset the src data(in bytes) to zero. - mv(t0, len); - vsetvli(x0, t0, Assembler::e8, lmul); - vmv_v_i(v4, 0); - // convert the src data from bits to bytes. - vmerge_vim(v4, v4, 1); // v0 as implicit mask register - // reset the dst data(in bytes) to zero. - vmv_v_i(v12, 0); - // load the mask data(in bits). - vsetivli(x0, 1, sew, Assembler::m1); - vmv_s_x(v0, mask); - // expand the src data(in bytes) to dst(in bytes). - vsetvli(x0, t0, Assembler::e8, lmul); - viota_m(v8, v0); - vrgather_vv(v12, v4, v8, VectorMask::v0_t); // v0 as implicit mask register - // convert the dst data from bytes to bits. - vmseq_vi(v0, v12, 1); - // store result back. - vsetivli(x0, 1, sew, Assembler::m1); - vmv_x_s(dst, v0); -} - -void C2_MacroAssembler::expand_bits_i_v(Register dst, Register src, Register mask) { - expand_bits_v(dst, src, mask, /* is_long */ false); -} - -void C2_MacroAssembler::expand_bits_l_v(Register dst, Register src, Register mask) { - expand_bits_v(dst, src, mask, /* is_long */ true); -} - // j.l.Math.round(float) // Returns the closest int to the argument, with ties rounding to positive infinity. // We need to handle 3 special cases defined by java api spec: diff --git a/src/hotspot/cpu/riscv/c2_MacroAssembler_riscv.hpp b/src/hotspot/cpu/riscv/c2_MacroAssembler_riscv.hpp index 8736294e72c..2d14f98780d 100644 --- a/src/hotspot/cpu/riscv/c2_MacroAssembler_riscv.hpp +++ b/src/hotspot/cpu/riscv/c2_MacroAssembler_riscv.hpp @@ -39,9 +39,6 @@ VectorRegister vrs, bool is_latin, Label& DONE, Assembler::LMUL lmul); - void compress_bits_v(Register dst, Register src, Register mask, bool is_long); - void expand_bits_v(Register dst, Register src, Register mask, bool is_long); - public: // Code used by cmpFastLock and cmpFastUnlock mach instructions in .ad file. void fast_lock(Register object, Register box, @@ -184,13 +181,6 @@ // intrinsic methods implemented by rvv instructions - // compress bits, i.e. j.l.Integer/Long::compress. - void compress_bits_i_v(Register dst, Register src, Register mask); - void compress_bits_l_v(Register dst, Register src, Register mask); - // expand bits, i.e. j.l.Integer/Long::expand. - void expand_bits_i_v(Register dst, Register src, Register mask); - void expand_bits_l_v(Register dst, Register src, Register mask); - void java_round_float_v(VectorRegister dst, VectorRegister src, FloatRegister ftmp, BasicType bt, uint vector_length); void java_round_double_v(VectorRegister dst, VectorRegister src, FloatRegister ftmp, BasicType bt, uint vector_length); diff --git a/src/hotspot/cpu/riscv/riscv.ad b/src/hotspot/cpu/riscv/riscv.ad index ae8565e1bcf..d0085125c76 100644 --- a/src/hotspot/cpu/riscv/riscv.ad +++ b/src/hotspot/cpu/riscv/riscv.ad @@ -942,26 +942,6 @@ reg_class v11_reg( V11, V11_H, V11_J, V11_K ); -// class for vector register v12 -reg_class v12_reg( - V12, V12_H, V12_J, V12_K -); - -// class for vector register v13 -reg_class v13_reg( - V13, V13_H, V13_J, V13_K -); - -// class for vector register v14 -reg_class v14_reg( - V14, V14_H, V14_J, V14_K -); - -// class for vector register v15 -reg_class v15_reg( - V15, V15_H, V15_J, V15_K -); - // class for condition codes reg_class reg_flags(RFLAGS); @@ -1896,9 +1876,6 @@ bool Matcher::match_rule_supported(int opcode) { } break; - case Op_ExpandBits: // fall through - case Op_CompressBits: // fall through - guarantee(UseRVV == (MaxVectorSize >= 16), "UseRVV and MaxVectorSize not matched"); case Op_StrCompressedCopy: // fall through case Op_StrInflatedCopy: // fall through case Op_CountPositives: // fall through @@ -3541,46 +3518,6 @@ operand vReg_V11() interface(REG_INTER); %} -operand vReg_V12() -%{ - constraint(ALLOC_IN_RC(v12_reg)); - match(VecA); - match(vReg); - op_cost(0); - format %{ %} - interface(REG_INTER); -%} - -operand vReg_V13() -%{ - constraint(ALLOC_IN_RC(v13_reg)); - match(VecA); - match(vReg); - op_cost(0); - format %{ %} - interface(REG_INTER); -%} - -operand vReg_V14() -%{ - constraint(ALLOC_IN_RC(v14_reg)); - match(VecA); - match(vReg); - op_cost(0); - format %{ %} - interface(REG_INTER); -%} - -operand vReg_V15() -%{ - constraint(ALLOC_IN_RC(v15_reg)); - match(VecA); - match(vReg); - op_cost(0); - format %{ %} - interface(REG_INTER); -%} - operand vRegMask() %{ constraint(ALLOC_IN_RC(vmask_reg)); diff --git a/src/hotspot/cpu/riscv/riscv_v.ad b/src/hotspot/cpu/riscv/riscv_v.ad index 510c0ff5d46..6894f3ce9fd 100644 --- a/src/hotspot/cpu/riscv/riscv_v.ad +++ b/src/hotspot/cpu/riscv/riscv_v.ad @@ -3843,116 +3843,6 @@ instruct vclearArray_reg_reg(iRegL_R29 cnt, iRegP_R28 base, Universe dummy, ins_pipe(pipe_class_memory); %} -// CompressBits of Long & Integer - -instruct compressBitsI(iRegINoSp dst, iRegIorL2I src, iRegIorL2I mask, vRegMask_V0 v0, - vReg_V4 v4, vReg_V5 v5, vReg_V8 v8, vReg_V9 v9) %{ - match(Set dst (CompressBits src mask)); - effect(TEMP v0, TEMP v4, TEMP v5, TEMP v8, TEMP v9); - format %{ "vsetivli x0, 1, e32, m1, tu, mu\t#@compressBitsI\n\t" - "vmv.s.x $v0, $src\n\t" - "mv t0, 32\n\t" - "vsetvli x0, t0, e8, m2, tu, mu\n\t" - "vmv.v.i $v4, 0\n\t" - "vmerge.vim $v4, $v4, 1, $v0\n\t" - "vmv.v.i $v8, 0\n\t" - "vsetivli x0, 1, e32, m1, tu, mu\n\t" - "vmv.s.x $v0, $mask\n\t" - "vsetvli x0, t0, e8, m2, tu, mu\n\t" - "vcompress.vm $v8, $v4, $v0\n\t" - "vmseq.vi $v0, $v8, 1\n\t" - "vsetivli x0, 1, e32, m1, tu, mu\n\t" - "vmv.x.s $dst, $v0\t#@compressBitsI\n\t" - %} - ins_encode %{ - __ compress_bits_i_v(as_Register($dst$$reg), as_Register($src$$reg), as_Register($mask$$reg)); - %} - ins_pipe(pipe_slow); -%} - -instruct compressBitsL(iRegLNoSp dst, iRegL src, iRegL mask, vRegMask_V0 v0, - vReg_V4 v4, vReg_V5 v5, vReg_V6 v6, vReg_V7 v7, - vReg_V8 v8, vReg_V9 v9, vReg_V10 v10, vReg_V11 v11) %{ - match(Set dst (CompressBits src mask)); - effect(TEMP v0, TEMP v4, TEMP v5, TEMP v6, TEMP v7, TEMP v8, TEMP v9, TEMP v10, TEMP v11); - format %{ "vsetivli x0, 1, e64, m1, tu, mu\t#@compressBitsL\n\t" - "vmv.s.x $v0, $src\n\t" - "mv t0, 64\n\t" - "vsetvli x0, t0, e8, m4, tu, mu\n\t" - "vmv.v.i $v4, 0\n\t" - "vmerge.vim $v4, $v4, 1, $v0\n\t" - "vmv.v.i $v8, 0\n\t" - "vsetivli x0, 1, e64, m1, tu, mu\n\t" - "vmv.s.x $v0, $mask\n\t" - "vsetvli x0, t0, e8, m4, tu, mu\n\t" - "vcompress.vm $v8, $v4, $v0\n\t" - "vmseq.vi $v0, $v8, 1\n\t" - "vsetivli x0, 1, e64, m1, tu, mu\n\t" - "vmv.x.s $dst, $v0\t#@compressBitsL\n\t" - %} - ins_encode %{ - __ compress_bits_l_v(as_Register($dst$$reg), as_Register($src$$reg), as_Register($mask$$reg)); - %} - ins_pipe(pipe_slow); -%} - -// ExpandBits of Long & Integer - -instruct expandBitsI(iRegINoSp dst, iRegIorL2I src, iRegIorL2I mask, vRegMask_V0 v0, - vReg_V4 v4, vReg_V5 v5, vReg_V8 v8, vReg_V9 v9, vReg_V12 v12, vReg_V13 v13) %{ - match(Set dst (ExpandBits src mask)); - effect(TEMP v0, TEMP v4, TEMP v5, TEMP v8, TEMP v9, TEMP v12, TEMP v13); - format %{ "vsetivli x0, 1, e32, m1, tu, mu\t#@expandBitsI\n\t" - "vmv.s.x $v0, $src\n\t" - "mv t0, 32\n\t" - "vsetvli x0, t0, e8, m2, tu, mu\n\t" - "vmv.v.i $v4, 0\n\t" - "vmerge.vim $v4, $v4, 1, $v0\n\t" - "vmv.v.i $v12, 0\n\t" - "vsetivli x0, 1, e32, m1, tu, mu\n\t" - "vmv.s.x $v0, $mask\n\t" - "vsetvli x0, t0, e8, m2, tu, mu\n\t" - "viota.m $v8, $v0\n\t" - "vrgather.vv $v12, $v4, $v8, $v0.t\n\t" - "vmseq.vi $v0, $v12, 1\n\t" - "vsetivli x0, 1, e32, m1, tu, mu\n\t" - "vmv.x.s $dst, $v0\t#@expandBitsI\n\t" - %} - ins_encode %{ - __ expand_bits_i_v(as_Register($dst$$reg), as_Register($src$$reg), as_Register($mask$$reg)); - %} - ins_pipe(pipe_slow); -%} - -instruct expandBitsL(iRegLNoSp dst, iRegL src, iRegL mask, vRegMask_V0 v0, - vReg_V4 v4, vReg_V5 v5, vReg_V6 v6, vReg_V7 v7, - vReg_V8 v8, vReg_V9 v9, vReg_V10 v10, vReg_V11 v11, - vReg_V12 v12, vReg_V13 v13, vReg_V14 v14, vReg_V15 v15) %{ - match(Set dst (ExpandBits src mask)); - effect(TEMP v0, TEMP v4, TEMP v5, TEMP v6, TEMP v7, TEMP v8, TEMP v9, TEMP v10, TEMP v11, - TEMP v12, TEMP v13, TEMP v14, TEMP v15); - format %{ "vsetivli x0, 1, e64, m1, tu, mu\t#@expandBitsL\n\t" - "vmv.s.x $v0, $src\n\t" - "mv t0, 64\n\t" - "vsetvli x0, t0, e8, m4, tu, mu\n\t" - "vmv.v.i $v4, 0\n\t" - "vmerge.vim $v4, $v4, 1, $v0\n\t" - "vmv.v.i $v12, 0\n\t" - "vsetivli x0, 1, e64, m1, tu, mu\n\t" - "vmv.s.x $v0, $mask\n\t" - "vsetvli x0, t0, e8, m4, tu, mu\n\t" - "viota.m $v8, $v0\n\t" - "vrgather.vv $v12, $v4, $v8, $v0.t\n\t" - "vmseq.vi $v0, $v12, 1\n\t" - "vsetivli x0, 1, e64, m1, tu, mu\n\t" - "vmv.x.s $dst, $v0\t#@expandBitsL\n\t" - %} - ins_encode %{ - __ expand_bits_l_v(as_Register($dst$$reg), as_Register($src$$reg), as_Register($mask$$reg)); - %} - ins_pipe(pipe_slow); -%} - // Vector Load Const instruct vloadcon(vReg dst, immI0 src) %{ match(Set dst (VectorLoadConst src)); diff --git a/test/hotspot/jtreg/compiler/intrinsics/TestBitShuffleOpers.java b/test/hotspot/jtreg/compiler/intrinsics/TestBitShuffleOpers.java index 064ffeb41fb..e94d7bcc95b 100644 --- a/test/hotspot/jtreg/compiler/intrinsics/TestBitShuffleOpers.java +++ b/test/hotspot/jtreg/compiler/intrinsics/TestBitShuffleOpers.java @@ -30,8 +30,7 @@ * @requires (((os.arch=="x86" | os.arch=="amd64" | os.arch=="x86_64") & * (vm.cpu.features ~= ".*bmi2.*" & vm.cpu.features ~= ".*bmi1.*" & * vm.cpu.features ~= ".*sse2.*")) | - * (os.arch=="aarch64" & vm.cpu.features ~= ".*svebitperm.*") | - * (os.arch=="riscv64" & vm.cpu.features ~= ".*rvv.*")) + * (os.arch=="aarch64" & vm.cpu.features ~= ".*svebitperm.*")) * @library /test/lib / * @run driver compiler.intrinsics.TestBitShuffleOpers */ From 4110d3925c8bfc3256b01d835faa111c2c21b8db Mon Sep 17 00:00:00 2001 From: Roger Riggs <rriggs@openjdk.org> Date: Mon, 25 Nov 2024 14:34:27 +0000 Subject: [PATCH 221/311] 8344865: SM cleanup in sun/reflect/annotation Reviewed-by: liach, jpai --- .../AnnotationInvocationHandler.java | 15 ++++---------- .../reflect/annotation/AnnotationParser.java | 15 +++++--------- .../reflect/annotation/AnnotationSupport.java | 20 +++---------------- .../reflect/annotation/AnnotationType.java | 15 ++++---------- 4 files changed, 16 insertions(+), 49 deletions(-) diff --git a/src/java.base/share/classes/sun/reflect/annotation/AnnotationInvocationHandler.java b/src/java.base/share/classes/sun/reflect/annotation/AnnotationInvocationHandler.java index 16869b019e7..fcee641458e 100644 --- a/src/java.base/share/classes/sun/reflect/annotation/AnnotationInvocationHandler.java +++ b/src/java.base/share/classes/sun/reflect/annotation/AnnotationInvocationHandler.java @@ -31,8 +31,6 @@ import java.io.Serializable; import java.util.*; import java.util.stream.*; -import java.security.AccessController; -import java.security.PrivilegedAction; /** * InvocationHandler for dynamic proxy implementation of Annotation. @@ -481,16 +479,11 @@ private Method[] getMemberMethods() { return value; } - @SuppressWarnings("removal") private Method[] computeMemberMethods() { - return AccessController.doPrivileged( - new PrivilegedAction<Method[]>() { - public Method[] run() { - final Method[] methods = type.getDeclaredMethods(); - validateAnnotationMethods(methods); - AccessibleObject.setAccessible(methods, true); - return methods; - }}); + final Method[] methods = type.getDeclaredMethods(); + validateAnnotationMethods(methods); + AccessibleObject.setAccessible(methods, true); + return methods; } private transient volatile Method[] memberMethods; diff --git a/src/java.base/share/classes/sun/reflect/annotation/AnnotationParser.java b/src/java.base/share/classes/sun/reflect/annotation/AnnotationParser.java index 1e8c5401231..e5a3e636c2c 100644 --- a/src/java.base/share/classes/sun/reflect/annotation/AnnotationParser.java +++ b/src/java.base/share/classes/sun/reflect/annotation/AnnotationParser.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -31,8 +31,7 @@ import java.nio.ByteBuffer; import java.util.*; import java.util.function.Supplier; -import java.security.AccessController; -import java.security.PrivilegedAction; + import jdk.internal.reflect.ConstantPool; import sun.reflect.generics.parser.SignatureParser; @@ -292,16 +291,12 @@ private static Annotation parseAnnotation2(ByteBuffer buf, * Returns an annotation of the given type backed by the given * member {@literal ->} value map. */ - @SuppressWarnings("removal") public static Annotation annotationForMap(final Class<? extends Annotation> type, final Map<String, Object> memberValues) { - return AccessController.doPrivileged(new PrivilegedAction<Annotation>() { - public Annotation run() { - return (Annotation) Proxy.newProxyInstance( - type.getClassLoader(), new Class<?>[] { type }, - new AnnotationInvocationHandler(type, memberValues)); - }}); + return (Annotation) Proxy.newProxyInstance( + type.getClassLoader(), new Class<?>[] { type }, + new AnnotationInvocationHandler(type, memberValues)); } /** diff --git a/src/java.base/share/classes/sun/reflect/annotation/AnnotationSupport.java b/src/java.base/share/classes/sun/reflect/annotation/AnnotationSupport.java index a70ffafd363..fd76eedfbcd 100644 --- a/src/java.base/share/classes/sun/reflect/annotation/AnnotationSupport.java +++ b/src/java.base/share/classes/sun/reflect/annotation/AnnotationSupport.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -27,8 +27,6 @@ import java.lang.annotation.*; import java.lang.reflect.*; -import java.security.AccessController; -import java.security.PrivilegedAction; import java.util.ArrayList; import java.util.Arrays; import java.util.List; @@ -181,7 +179,6 @@ public static <A extends Annotation> A[] getAssociatedAnnotations( /* Reflectively invoke the values-method of the given annotation * (container), cast it to an array of annotations and return the result. */ - @SuppressWarnings("removal") private static <A extends Annotation> A[] getValueArray(Annotation container) { try { // According to JLS the container must have an array-valued value @@ -225,19 +222,8 @@ private static <A extends Annotation> A[] getValueArray(Annotation container) { // Interface might not be public though final Method toInvoke; if (!Modifier.isPublic(iface.getModifiers())) { - if (System.getSecurityManager() != null) { - toInvoke = AccessController.doPrivileged(new PrivilegedAction<Method>() { - @Override - public Method run() { - Method res = ReflectionFactory.getReflectionFactory().leafCopyMethod(m); - res.setAccessible(true); - return res; - } - }); - } else { - toInvoke = ReflectionFactory.getReflectionFactory().leafCopyMethod(m); - toInvoke.setAccessible(true); - } + toInvoke = ReflectionFactory.getReflectionFactory().leafCopyMethod(m); + toInvoke.setAccessible(true); } else { toInvoke = m; } diff --git a/src/java.base/share/classes/sun/reflect/annotation/AnnotationType.java b/src/java.base/share/classes/sun/reflect/annotation/AnnotationType.java index 89aff8a954a..3a4bd80b014 100644 --- a/src/java.base/share/classes/sun/reflect/annotation/AnnotationType.java +++ b/src/java.base/share/classes/sun/reflect/annotation/AnnotationType.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -28,8 +28,7 @@ import java.lang.annotation.*; import java.lang.reflect.*; import java.util.*; -import java.security.AccessController; -import java.security.PrivilegedAction; + import jdk.internal.access.SharedSecrets; import jdk.internal.access.JavaLangAccess; @@ -105,14 +104,8 @@ private AnnotationType(final Class<? extends Annotation> annotationClass) { if (!annotationClass.isAnnotation()) throw new IllegalArgumentException("Not an annotation type"); - @SuppressWarnings("removal") - Method[] methods = - AccessController.doPrivileged(new PrivilegedAction<>() { - public Method[] run() { - // Initialize memberTypes and defaultValues - return annotationClass.getDeclaredMethods(); - } - }); + // Initialize memberTypes and defaultValues + Method[] methods = annotationClass.getDeclaredMethods(); memberTypes = new HashMap<>(methods.length+1, 1.0f); memberDefaults = new HashMap<>(0); From a032de2904baf83143415858ed7191549c659035 Mon Sep 17 00:00:00 2001 From: Alan Bateman <alanb@openjdk.org> Date: Mon, 25 Nov 2024 15:34:13 +0000 Subject: [PATCH 222/311] 8344577: Virtual thread tests are timing out on some macOS systems Reviewed-by: jpai --- .../stress/GetStackTraceALotWhenBlocking.java | 10 ++++- .../stress/GetStackTraceALotWhenPinned.java | 11 +++++- .../GetStackTraceALotWithTimedWait.java | 4 +- .../stress/LotsOfContendedMonitorEnter.java | 2 +- .../stress/LotsOfUncontendedMonitorEnter.java | 2 +- .../lang/Thread/virtual/stress/ParkALot.java | 37 ++++++++++++++----- .../lang/Thread/virtual/stress/SleepALot.java | 2 +- .../Thread/virtual/stress/TimedWaitALot.java | 8 ++-- 8 files changed, 56 insertions(+), 20 deletions(-) diff --git a/test/jdk/java/lang/Thread/virtual/stress/GetStackTraceALotWhenBlocking.java b/test/jdk/java/lang/Thread/virtual/stress/GetStackTraceALotWhenBlocking.java index b68496bc7db..17b63573d85 100644 --- a/test/jdk/java/lang/Thread/virtual/stress/GetStackTraceALotWhenBlocking.java +++ b/test/jdk/java/lang/Thread/virtual/stress/GetStackTraceALotWhenBlocking.java @@ -42,6 +42,7 @@ import java.time.Instant; import java.util.concurrent.ThreadLocalRandom; import java.util.concurrent.atomic.AtomicBoolean; +import jdk.test.lib.Platform; import jdk.test.lib.thread.VThreadRunner; // ensureParallelism requires jdk.management public class GetStackTraceALotWhenBlocking { @@ -50,7 +51,14 @@ public static void main(String[] args) throws Exception { // need at least two carriers VThreadRunner.ensureParallelism(2); - int iterations = args.length > 0 ? Integer.parseInt(args[0]) : 100_000; + int iterations; + int value = Integer.parseInt(args[0]); + if (Platform.isOSX() && Platform.isX64()) { + // reduced iterations on macosx-x64 + iterations = Math.max(value / 4, 1); + } else { + iterations = value; + } var done = new AtomicBoolean(); var lock = new Object(); diff --git a/test/jdk/java/lang/Thread/virtual/stress/GetStackTraceALotWhenPinned.java b/test/jdk/java/lang/Thread/virtual/stress/GetStackTraceALotWhenPinned.java index 9d9d3eddce1..0b5cabab7d5 100644 --- a/test/jdk/java/lang/Thread/virtual/stress/GetStackTraceALotWhenPinned.java +++ b/test/jdk/java/lang/Thread/virtual/stress/GetStackTraceALotWhenPinned.java @@ -42,6 +42,7 @@ import java.time.Instant; import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.locks.LockSupport; +import jdk.test.lib.Platform; import jdk.test.lib.thread.VThreadRunner; // ensureParallelism requires jdk.management import jdk.test.lib.thread.VThreadPinner; @@ -53,7 +54,15 @@ public static void main(String[] args) throws Exception { VThreadRunner.ensureParallelism(2); } - int iterations = Integer.parseInt(args[0]); + int iterations; + int value = Integer.parseInt(args[0]); + if (Platform.isOSX() && Platform.isX64()) { + // reduced iterations on macosx-x64 + iterations = Math.max(value / 4, 1); + } else { + iterations = value; + } + var barrier = new Barrier(2); // Start a virtual thread that loops doing Thread.yield and parking while pinned. diff --git a/test/jdk/java/lang/Thread/virtual/stress/GetStackTraceALotWithTimedWait.java b/test/jdk/java/lang/Thread/virtual/stress/GetStackTraceALotWithTimedWait.java index 3f8f1c464a6..ad3fbdf0565 100644 --- a/test/jdk/java/lang/Thread/virtual/stress/GetStackTraceALotWithTimedWait.java +++ b/test/jdk/java/lang/Thread/virtual/stress/GetStackTraceALotWithTimedWait.java @@ -25,13 +25,13 @@ * @test * @summary Stress test Thread.getStackTrace on a virtual thread in timed-Object.wait * @requires vm.debug != true - * @run main/othervm GetStackTraceALotWithTimedWait 100000 + * @run main GetStackTraceALotWithTimedWait 100000 */ /* * @test * @requires vm.debug == true - * @run main/othervm GetStackTraceALotWithTimedWait 50000 + * @run main GetStackTraceALotWithTimedWait 50000 */ import java.time.Instant; diff --git a/test/jdk/java/lang/Thread/virtual/stress/LotsOfContendedMonitorEnter.java b/test/jdk/java/lang/Thread/virtual/stress/LotsOfContendedMonitorEnter.java index 86096156b91..c63a4b0c947 100644 --- a/test/jdk/java/lang/Thread/virtual/stress/LotsOfContendedMonitorEnter.java +++ b/test/jdk/java/lang/Thread/virtual/stress/LotsOfContendedMonitorEnter.java @@ -26,7 +26,7 @@ * @summary Test virtual threads entering a lot of monitors with contention * @requires vm.opt.LockingMode != 1 * @library /test/lib - * @run main/othervm LotsOfContendedMonitorEnter + * @run main LotsOfContendedMonitorEnter */ /* diff --git a/test/jdk/java/lang/Thread/virtual/stress/LotsOfUncontendedMonitorEnter.java b/test/jdk/java/lang/Thread/virtual/stress/LotsOfUncontendedMonitorEnter.java index e72fc12eb88..da5fdd1161d 100644 --- a/test/jdk/java/lang/Thread/virtual/stress/LotsOfUncontendedMonitorEnter.java +++ b/test/jdk/java/lang/Thread/virtual/stress/LotsOfUncontendedMonitorEnter.java @@ -25,7 +25,7 @@ * @test id=default * @summary Test virtual thread entering (and reentering) a lot of monitors with no contention * @library /test/lib - * @run main/othervm LotsOfUncontendedMonitorEnter + * @run main LotsOfUncontendedMonitorEnter */ /* diff --git a/test/jdk/java/lang/Thread/virtual/stress/ParkALot.java b/test/jdk/java/lang/Thread/virtual/stress/ParkALot.java index ccba3fe1b4d..882e0b881bc 100644 --- a/test/jdk/java/lang/Thread/virtual/stress/ParkALot.java +++ b/test/jdk/java/lang/Thread/virtual/stress/ParkALot.java @@ -25,29 +25,35 @@ * @test * @summary Stress test parking and unparking * @requires vm.debug != true - * @run main/othervm ParkALot 500000 + * @library /test/lib + * @run main/othervm/timeout=300 ParkALot 300000 */ /* * @test * @requires vm.debug == true - * @run main/othervm ParkALot 100000 + * @library /test/lib + * @run main/othervm/timeout=300 ParkALot 100000 */ import java.time.Instant; import java.util.concurrent.Executors; import java.util.concurrent.ThreadFactory; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.locks.LockSupport; +import jdk.test.lib.Platform; public class ParkALot { - private static final int ITERATIONS = 1_000_000; - public static void main(String[] args) { + public static void main(String[] args) throws Exception { int iterations; - if (args.length > 0) { - iterations = Integer.parseInt(args[0]); + int value = Integer.parseInt(args[0]); + if (Platform.isOSX() && Platform.isX64()) { + // reduced iterations on macosx-x64 + iterations = Math.max(value / 4, 1); } else { - iterations = ITERATIONS; + iterations = value; } int maxThreads = Math.clamp(Runtime.getRuntime().availableProcessors() / 2, 1, 4); @@ -55,8 +61,18 @@ public static void main(String[] args) { System.out.format("%s %d thread(s) ...%n", Instant.now(), nthreads); ThreadFactory factory = Thread.ofPlatform().factory(); try (var executor = Executors.newThreadPerTaskExecutor(factory)) { + var totalIterations = new AtomicInteger(); for (int i = 0; i < nthreads; i++) { - executor.submit(() -> parkALot(iterations)); + executor.submit(() -> parkALot(iterations, totalIterations::incrementAndGet)); + } + + // shutdown, await for all threads to finish with progress output + executor.shutdown(); + boolean terminated = false; + while (!terminated) { + terminated = executor.awaitTermination(1, TimeUnit.SECONDS); + System.out.format("%s => %d of %d%n", + Instant.now(), totalIterations.get(), iterations * nthreads); } } System.out.format("%s %d thread(s) done%n", Instant.now(), nthreads); @@ -66,8 +82,10 @@ public static void main(String[] args) { /** * Creates a virtual thread that alternates between untimed and timed parking. * A platform thread spins unparking the virtual thread. + * @param iterations number of iterations + * @param afterIteration the task to run after each iteration */ - private static void parkALot(int iterations) { + private static void parkALot(int iterations, Runnable afterIteration) { Thread vthread = Thread.ofVirtual().start(() -> { int i = 0; boolean timed = false; @@ -80,6 +98,7 @@ private static void parkALot(int iterations) { timed = true; } i++; + afterIteration.run(); } }); diff --git a/test/jdk/java/lang/Thread/virtual/stress/SleepALot.java b/test/jdk/java/lang/Thread/virtual/stress/SleepALot.java index ed1c985ba7c..d10897629c4 100644 --- a/test/jdk/java/lang/Thread/virtual/stress/SleepALot.java +++ b/test/jdk/java/lang/Thread/virtual/stress/SleepALot.java @@ -25,7 +25,7 @@ * @test * @summary Stress test Thread.sleep * @requires vm.debug != true & vm.continuations - * @run main/othervm SleepALot 500000 + * @run main SleepALot 500000 */ /* diff --git a/test/jdk/java/lang/Thread/virtual/stress/TimedWaitALot.java b/test/jdk/java/lang/Thread/virtual/stress/TimedWaitALot.java index 2a2fce62d62..6a81a7c5fee 100644 --- a/test/jdk/java/lang/Thread/virtual/stress/TimedWaitALot.java +++ b/test/jdk/java/lang/Thread/virtual/stress/TimedWaitALot.java @@ -24,28 +24,28 @@ /* * @test id=timeout * @summary Stress test timed-Object.wait - * @run main/othervm TimedWaitALot 200 + * @run main TimedWaitALot 200 */ /* * @test id=timeout-notify * @summary Test timed-Object.wait where the waiting thread is awakened with Object.notify * at around the same time that the timeout expires. - * @run main/othervm TimedWaitALot 200 true false + * @run main TimedWaitALot 150 true false */ /* * @test id=timeout-interrupt * @summary Test timed-Object.wait where the waiting thread is awakened with Thread.interrupt * at around the same time that the timeout expires. - * @run main/othervm TimedWaitALot 200 false true + * @run main TimedWaitALot 150 false true */ /* * @test id=timeout-notify-interrupt * @summary Test timed-Object.wait where the waiting thread is awakened with Object.notify * and Thread.interrupt at around the same time that the timeout expires. - * @run main/othervm TimedWaitALot 100 true true + * @run main TimedWaitALot 100 true true */ import java.time.Instant; From 15ae8d02eeb9c80f5453b88d38081debf956cb65 Mon Sep 17 00:00:00 2001 From: Naoto Sato <naoto@openjdk.org> Date: Mon, 25 Nov 2024 15:54:23 +0000 Subject: [PATCH 223/311] 8319993: Update Unicode Data Files to 16.0.0 8319992: Update ICU4J to Version 76.1 Reviewed-by: jlu, joehw, iris --- .../share/classes/java/lang/Character.java | 467 +- .../java/lang/CharacterData00.java.template | 8 +- .../jdk/internal/icu/impl/NormalizerImpl.java | 178 +- .../internal/icu/impl/UCharacterProperty.java | 41 +- .../internal/icu/impl/data/icudt74b/nfc.nrm | Bin 35392 -> 0 bytes .../icu/impl/data/icudt74b/uprops.icu | Bin 141616 -> 0 bytes .../internal/icu/impl/data/icudt76b/nfc.nrm | Bin 0 -> 36224 bytes .../impl/data/{icudt74b => icudt76b}/nfkc.nrm | Bin 55120 -> 56032 bytes .../data/{icudt74b => icudt76b}/ubidi.icu | Bin 27584 -> 28464 bytes .../icu/impl/data/icudt76b/uprops.icu | Bin 0 -> 146880 bytes .../jdk/internal/icu/util/VersionInfo.java | 12 +- .../jdk/internal/util/regex/Grapheme.java | 12 +- .../share/data/unicodedata/Blocks.txt | 19 +- .../unicodedata/DerivedCoreProperties.txt | 834 ++- .../data/unicodedata/NormalizationTest.txt | 905 ++- .../share/data/unicodedata/PropList.txt | 147 +- .../data/unicodedata/PropertyValueAliases.txt | 65 +- .../share/data/unicodedata/ReadMe.txt | 11 +- .../share/data/unicodedata/Scripts.txt | 153 +- .../share/data/unicodedata/SpecialCasing.txt | 22 +- .../share/data/unicodedata/UnicodeData.txt | 5203 ++++++++++++++++- .../auxiliary/GraphemeBreakProperty.txt | 96 +- .../auxiliary/GraphemeBreakTest.txt | 464 +- .../data/unicodedata/emoji/emoji-data.txt | 42 +- src/java.base/share/legal/icu.md | 87 +- src/java.base/share/legal/unicode.md | 277 +- .../java/lang/String/UnicodeCasingTest.java | 5 +- 27 files changed, 8147 insertions(+), 901 deletions(-) delete mode 100644 src/java.base/share/classes/jdk/internal/icu/impl/data/icudt74b/nfc.nrm delete mode 100644 src/java.base/share/classes/jdk/internal/icu/impl/data/icudt74b/uprops.icu create mode 100644 src/java.base/share/classes/jdk/internal/icu/impl/data/icudt76b/nfc.nrm rename src/java.base/share/classes/jdk/internal/icu/impl/data/{icudt74b => icudt76b}/nfkc.nrm (50%) rename src/java.base/share/classes/jdk/internal/icu/impl/data/{icudt74b => icudt76b}/ubidi.icu (58%) create mode 100644 src/java.base/share/classes/jdk/internal/icu/impl/data/icudt76b/uprops.icu diff --git a/src/java.base/share/classes/java/lang/Character.java b/src/java.base/share/classes/java/lang/Character.java index 8368adf5403..f5a9ab77b52 100644 --- a/src/java.base/share/classes/java/lang/Character.java +++ b/src/java.base/share/classes/java/lang/Character.java @@ -63,7 +63,7 @@ * from the Unicode Consortium at * <a href="http://www.unicode.org">http://www.unicode.org</a>. * <p> - * Character information is based on the Unicode Standard, version 15.1. + * Character information is based on the Unicode Standard, version 16.0. * <p> * The Java platform has supported different versions of the Unicode * Standard over time. Upgrades to newer versions of the Unicode Standard @@ -75,6 +75,8 @@ * <th scope="col">Unicode version</th></tr> * </thead> * <tbody> + * <tr><th scope="row" style="text-align:left">Java SE 24</th> + * <td>Unicode 16.0</td></tr> * <tr><th scope="row" style="text-align:left">Java SE 22</th> * <td>Unicode 15.1</td></tr> * <tr><th scope="row" style="text-align:left">Java SE 20</th> @@ -745,7 +747,7 @@ public static final class UnicodeBlock extends Subset { * It should be adjusted whenever the Unicode Character Database * is upgraded. */ - private static final int NUM_ENTITIES = 759; + private static final int NUM_ENTITIES = 782; private static Map<String, UnicodeBlock> map = HashMap.newHashMap(NUM_ENTITIES); /** @@ -3622,6 +3624,99 @@ private UnicodeBlock(String idName, String... aliases) { "CJK UNIFIED IDEOGRAPHS EXTENSION I", "CJKUNIFIEDIDEOGRAPHSEXTENSIONI"); + /** + * Constant for the "Todhri" Unicode + * character block. + * @since 24 + */ + public static final UnicodeBlock TODHRI = + new UnicodeBlock("TODHRI"); + + /** + * Constant for the "Garay" Unicode + * character block. + * @since 24 + */ + public static final UnicodeBlock GARAY = + new UnicodeBlock("GARAY"); + + /** + * Constant for the "Tulu-Tigalari" Unicode + * character block. + * @since 24 + */ + public static final UnicodeBlock TULU_TIGALARI = + new UnicodeBlock("TULU_TIGALARI", + "TULU-TIGALARI"); + + /** + * Constant for the "Myanmar Extended-C" Unicode + * character block. + * @since 24 + */ + public static final UnicodeBlock MYANMAR_EXTENDED_C = + new UnicodeBlock("MYANMAR_EXTENDED_C", + "MYANMAR EXTENDED-C", + "MYANMAREXTENDED-C"); + + /** + * Constant for the "Sunuwar" Unicode + * character block. + * @since 24 + */ + public static final UnicodeBlock SUNUWAR = + new UnicodeBlock("SUNUWAR"); + + /** + * Constant for the "Egyptian Hieroglyphs Extended-A" Unicode + * character block. + * @since 24 + */ + public static final UnicodeBlock EGYPTIAN_HIEROGLYPHS_EXTENDED_A = + new UnicodeBlock("EGYPTIAN_HIEROGLYPHS_EXTENDED_A", + "EGYPTIAN HIEROGLYPHS EXTENDED-A", + "EGYPTIANHIEROGLYPHSEXTENDED-A"); + + /** + * Constant for the "Gurung Khema" Unicode + * character block. + * @since 24 + */ + public static final UnicodeBlock GURUNG_KHEMA = + new UnicodeBlock("GURUNG_KHEMA", + "GURUNG KHEMA", + "GURUNGKHEMA"); + + /** + * Constant for the "Kirat Rai" Unicode + * character block. + * @since 24 + */ + public static final UnicodeBlock KIRAT_RAI = + new UnicodeBlock("KIRAT_RAI", + "KIRAT RAI", + "KIRATRAI"); + + /** + * Constant for the "Symbols for Legacy Computing Supplement" Unicode + * character block. + * @since 24 + */ + public static final UnicodeBlock SYMBOLS_FOR_LEGACY_COMPUTING_SUPPLEMENT = + new UnicodeBlock("SYMBOLS_FOR_LEGACY_COMPUTING_SUPPLEMENT", + "SYMBOLS FOR LEGACY COMPUTING SUPPLEMENT", + "SYMBOLSFORLEGACYCOMPUTINGSUPPLEMENT"); + + /** + * Constant for the "Ol Onal" Unicode + * character block. + * @since 24 + */ + public static final UnicodeBlock OL_ONAL = + new UnicodeBlock("OL_ONAL", + "OL ONAL", + "OLONAL"); + private static final int[] blockStarts = { 0x0000, // 0000..007F; Basic Latin 0x0080, // 0080..00FF; Latin-1 Supplement @@ -3811,7 +3906,7 @@ private UnicodeBlock(String idName, String... aliases) { 0x10500, // 10500..1052F; Elbasan 0x10530, // 10530..1056F; Caucasian Albanian 0x10570, // 10570..105BF; Vithkuqi - 0x105C0, // unassigned + 0x105C0, // 105C0..105FF; Todhri 0x10600, // 10600..1077F; Linear A 0x10780, // 10780..107BF; Latin Extended-F 0x107C0, // unassigned @@ -3840,7 +3935,8 @@ private UnicodeBlock(String idName, String... aliases) { 0x10C50, // unassigned 0x10C80, // 10C80..10CFF; Old Hungarian 0x10D00, // 10D00..10D3F; Hanifi Rohingya - 0x10D40, // unassigned + 0x10D40, // 10D40..10D8F; Garay + 0x10D90, // unassigned 0x10E60, // 10E60..10E7F; Rumi Numeral Symbols 0x10E80, // 10E80..10EBF; Yezidi 0x10EC0, // 10EC0..10EFF; Arabic Extended-C @@ -3861,7 +3957,7 @@ private UnicodeBlock(String idName, String... aliases) { 0x11280, // 11280..112AF; Multani 0x112B0, // 112B0..112FF; Khudawadi 0x11300, // 11300..1137F; Grantha - 0x11380, // unassigned + 0x11380, // 11380..113FF; Tulu-Tigalari 0x11400, // 11400..1147F; Newa 0x11480, // 11480..114DF; Tirhuta 0x114E0, // unassigned @@ -3869,7 +3965,7 @@ private UnicodeBlock(String idName, String... aliases) { 0x11600, // 11600..1165F; Modi 0x11660, // 11660..1167F; Mongolian Supplement 0x11680, // 11680..116CF; Takri - 0x116D0, // unassigned + 0x116D0, // 116D0..116FF; Myanmar Extended-C 0x11700, // 11700..1174F; Ahom 0x11750, // unassigned 0x11800, // 11800..1184F; Dogra @@ -3884,6 +3980,7 @@ private UnicodeBlock(String idName, String... aliases) { 0x11AC0, // 11AC0..11AFF; Pau Cin Hau 0x11B00, // 11B00..11B5F; Devanagari Extended-A 0x11B60, // unassigned + 0x11BC0, // 11BC0..11BFF; Sunuwar 0x11C00, // 11C00..11C6F; Bhaiksuki 0x11C70, // 11C70..11CBF; Marchen 0x11CC0, // unassigned @@ -3902,15 +3999,19 @@ private UnicodeBlock(String idName, String... aliases) { 0x12F90, // 12F90..12FFF; Cypro-Minoan 0x13000, // 13000..1342F; Egyptian Hieroglyphs 0x13430, // 13430..1345F; Egyptian Hieroglyph Format Controls - 0x13460, // unassigned + 0x13460, // 13460..143FF; Egyptian Hieroglyphs Extended-A 0x14400, // 14400..1467F; Anatolian Hieroglyphs 0x14680, // unassigned + 0x16100, // 16100..1613F; Gurung Khema + 0x16140, // unassigned 0x16800, // 16800..16A3F; Bamum Supplement 0x16A40, // 16A40..16A6F; Mro 0x16A70, // 16A70..16ACF; Tangsa 0x16AD0, // 16AD0..16AFF; Bassa Vah 0x16B00, // 16B00..16B8F; Pahawh Hmong 0x16B90, // unassigned + 0x16D40, // 16D40..16D7F; Kirat Rai + 0x16D80, // unassigned 0x16E40, // 16E40..16E9F; Medefaidrin 0x16EA0, // unassigned 0x16F00, // 16F00..16F9F; Miao @@ -3930,6 +4031,8 @@ private UnicodeBlock(String idName, String... aliases) { 0x1BC00, // 1BC00..1BC9F; Duployan 0x1BCA0, // 1BCA0..1BCAF; Shorthand Format Controls 0x1BCB0, // unassigned + 0x1CC00, // 1CC00..1CEBF; Symbols for Legacy Computing Supplement + 0x1CEC0, // unassigned 0x1CF00, // 1CF00..1CFCF; Znamenny Musical Notation 0x1CFD0, // unassigned 0x1D000, // 1D000..1D0FF; Byzantine Musical Symbols @@ -3955,6 +4058,8 @@ private UnicodeBlock(String idName, String... aliases) { 0x1E300, // unassigned 0x1E4D0, // 1E4D0..1E4FF; Nag Mundari 0x1E500, // unassigned + 0x1E5D0, // 1E5D0..1E5FF; Ol Onal + 0x1E600, // unassigned 0x1E7E0, // 1E7E0..1E7FF; Ethiopic Extended-B 0x1E800, // 1E800..1E8DF; Mende Kikakui 0x1E8E0, // unassigned @@ -4193,7 +4298,7 @@ private UnicodeBlock(String idName, String... aliases) { ELBASAN, CAUCASIAN_ALBANIAN, VITHKUQI, - null, + TODHRI, LINEAR_A, LATIN_EXTENDED_F, null, @@ -4222,6 +4327,7 @@ private UnicodeBlock(String idName, String... aliases) { null, OLD_HUNGARIAN, HANIFI_ROHINGYA, + GARAY, null, RUMI_NUMERAL_SYMBOLS, YEZIDI, @@ -4243,7 +4349,7 @@ private UnicodeBlock(String idName, String... aliases) { MULTANI, KHUDAWADI, GRANTHA, - null, + TULU_TIGALARI, NEWA, TIRHUTA, null, @@ -4251,7 +4357,7 @@ private UnicodeBlock(String idName, String... aliases) { MODI, MONGOLIAN_SUPPLEMENT, TAKRI, - null, + MYANMAR_EXTENDED_C, AHOM, null, DOGRA, @@ -4266,6 +4372,7 @@ private UnicodeBlock(String idName, String... aliases) { PAU_CIN_HAU, DEVANAGARI_EXTENDED_A, null, + SUNUWAR, BHAIKSUKI, MARCHEN, null, @@ -4284,15 +4391,19 @@ private UnicodeBlock(String idName, String... aliases) { CYPRO_MINOAN, EGYPTIAN_HIEROGLYPHS, EGYPTIAN_HIEROGLYPH_FORMAT_CONTROLS, - null, + EGYPTIAN_HIEROGLYPHS_EXTENDED_A, ANATOLIAN_HIEROGLYPHS, null, + GURUNG_KHEMA, + null, BAMUM_SUPPLEMENT, MRO, TANGSA, BASSA_VAH, PAHAWH_HMONG, null, + KIRAT_RAI, + null, MEDEFAIDRIN, null, MIAO, @@ -4312,6 +4423,8 @@ private UnicodeBlock(String idName, String... aliases) { DUPLOYAN, SHORTHAND_FORMAT_CONTROLS, null, + SYMBOLS_FOR_LEGACY_COMPUTING_SUPPLEMENT, + null, ZNAMENNY_MUSICAL_NOTATION, null, BYZANTINE_MUSICAL_SYMBOLS, @@ -4337,6 +4450,8 @@ private UnicodeBlock(String idName, String... aliases) { null, NAG_MUNDARI, null, + OL_ONAL, + null, ETHIOPIC_EXTENDED_B, MENDE_KIKAKUI, null, @@ -4508,6 +4623,7 @@ public static final UnicodeBlock forName(String blockName) { * @since 1.7 */ public static enum UnicodeScript { + /** * Unicode script "Common". */ @@ -5391,6 +5507,48 @@ public static enum UnicodeScript { */ NAG_MUNDARI, + /** + * Unicode script "Todhri". + * @since 24 + */ + TODHRI, + + /** + * Unicode script "Garay". + * @since 24 + */ + GARAY, + + /** + * Unicode script "Tulu Tigalari". + * @since 24 + */ + TULU_TIGALARI, + + /** + * Unicode script "Sunuwar". + * @since 24 + */ + SUNUWAR, + + /** + * Unicode script "Gurung Khema". + * @since 24 + */ + GURUNG_KHEMA, + + /** + * Unicode script "Kirat Rai". + * @since 24 + */ + KIRAT_RAI, + + /** + * Unicode script "Ol Onal". + * @since 24 + */ + OL_ONAL, + /** * Unicode script "Unknown". */ @@ -5495,8 +5653,8 @@ public static enum UnicodeScript { 0x0870, // 0870..088E; ARABIC 0x088F, // 088F ; UNKNOWN 0x0890, // 0890..0891; ARABIC - 0x0892, // 0892..0897; UNKNOWN - 0x0898, // 0898..08E1; ARABIC + 0x0892, // 0892..0896; UNKNOWN + 0x0897, // 0897..08E1; ARABIC 0x08E2, // 08E2 ; COMMON 0x08E3, // 08E3..08FF; ARABIC 0x0900, // 0900..0950; DEVANAGARI @@ -5909,9 +6067,8 @@ public static enum UnicodeScript { 0x1AB0, // 1AB0..1ACE; INHERITED 0x1ACF, // 1ACF..1AFF; UNKNOWN 0x1B00, // 1B00..1B4C; BALINESE - 0x1B4D, // 1B4D..1B4F; UNKNOWN - 0x1B50, // 1B50..1B7E; BALINESE - 0x1B7F, // 1B7F ; UNKNOWN + 0x1B4D, // 1B4D ; UNKNOWN + 0x1B4E, // 1B4E..1B7F; BALINESE 0x1B80, // 1B80..1BBF; SUNDANESE 0x1BC0, // 1BC0..1BF3; BATAK 0x1BF4, // 1BF4..1BFB; UNKNOWN @@ -5922,8 +6079,8 @@ public static enum UnicodeScript { 0x1C4A, // 1C4A..1C4C; UNKNOWN 0x1C4D, // 1C4D..1C4F; LEPCHA 0x1C50, // 1C50..1C7F; OL_CHIKI - 0x1C80, // 1C80..1C88; CYRILLIC - 0x1C89, // 1C89..1C8F; UNKNOWN + 0x1C80, // 1C80..1C8A; CYRILLIC + 0x1C8B, // 1C8B..1C8F; UNKNOWN 0x1C90, // 1C90..1CBA; GEORGIAN 0x1CBB, // 1CBB..1CBC; UNKNOWN 0x1CBD, // 1CBD..1CBF; GEORGIAN @@ -6016,8 +6173,8 @@ public static enum UnicodeScript { 0x2160, // 2160..2188; LATIN 0x2189, // 2189..218B; COMMON 0x218C, // 218C..218F; UNKNOWN - 0x2190, // 2190..2426; COMMON - 0x2427, // 2427..243F; UNKNOWN + 0x2190, // 2190..2429; COMMON + 0x242A, // 242A..243F; UNKNOWN 0x2440, // 2440..244A; COMMON 0x244B, // 244B..245F; UNKNOWN 0x2460, // 2460..27FF; COMMON @@ -6098,8 +6255,8 @@ public static enum UnicodeScript { 0x318F, // 318F ; UNKNOWN 0x3190, // 3190..319F; COMMON 0x31A0, // 31A0..31BF; BOPOMOFO - 0x31C0, // 31C0..31E3; COMMON - 0x31E4, // 31E4..31EE; UNKNOWN + 0x31C0, // 31C0..31E5; COMMON + 0x31E6, // 31E6..31EE; UNKNOWN 0x31EF, // 31EF ; COMMON 0x31F0, // 31F0..31FF; KATAKANA 0x3200, // 3200..321E; HANGUL @@ -6127,14 +6284,14 @@ public static enum UnicodeScript { 0xA700, // A700..A721; COMMON 0xA722, // A722..A787; LATIN 0xA788, // A788..A78A; COMMON - 0xA78B, // A78B..A7CA; LATIN - 0xA7CB, // A7CB..A7CF; UNKNOWN + 0xA78B, // A78B..A7CD; LATIN + 0xA7CE, // A7CE..A7CF; UNKNOWN 0xA7D0, // A7D0..A7D1; LATIN 0xA7D2, // A7D2 ; UNKNOWN 0xA7D3, // A7D3 ; LATIN 0xA7D4, // A7D4 ; UNKNOWN - 0xA7D5, // A7D5..A7D9; LATIN - 0xA7DA, // A7DA..A7F1; UNKNOWN + 0xA7D5, // A7D5..A7DC; LATIN + 0xA7DD, // A7DD..A7F1; UNKNOWN 0xA7F2, // A7F2..A7FF; LATIN 0xA800, // A800..A82C; SYLOTI_NAGRI 0xA82D, // A82D..A82F; UNKNOWN @@ -6355,7 +6512,9 @@ public static enum UnicodeScript { 0x105B3, // 105B3..105B9; VITHKUQI 0x105BA, // 105BA ; UNKNOWN 0x105BB, // 105BB..105BC; VITHKUQI - 0x105BD, // 105BD..105FF; UNKNOWN + 0x105BD, // 105BD..105BF; UNKNOWN + 0x105C0, // 105C0..105F3; TODHRI + 0x105F4, // 105F4..105FF; UNKNOWN 0x10600, // 10600..10736; LINEAR_A 0x10737, // 10737..1073F; UNKNOWN 0x10740, // 10740..10755; LINEAR_A @@ -6453,7 +6612,13 @@ public static enum UnicodeScript { 0x10D00, // 10D00..10D27; HANIFI_ROHINGYA 0x10D28, // 10D28..10D2F; UNKNOWN 0x10D30, // 10D30..10D39; HANIFI_ROHINGYA - 0x10D3A, // 10D3A..10E5F; UNKNOWN + 0x10D3A, // 10D3A..10D3F; UNKNOWN + 0x10D40, // 10D40..10D65; GARAY + 0x10D66, // 10D66..10D68; UNKNOWN + 0x10D69, // 10D69..10D85; GARAY + 0x10D86, // 10D86..10D8D; UNKNOWN + 0x10D8E, // 10D8E..10D8F; GARAY + 0x10D90, // 10D90..10E5F; UNKNOWN 0x10E60, // 10E60..10E7E; ARABIC 0x10E7F, // 10E7F ; UNKNOWN 0x10E80, // 10E80..10EA9; YEZIDI @@ -6461,8 +6626,10 @@ public static enum UnicodeScript { 0x10EAB, // 10EAB..10EAD; YEZIDI 0x10EAE, // 10EAE..10EAF; UNKNOWN 0x10EB0, // 10EB0..10EB1; YEZIDI - 0x10EB2, // 10EB2..10EFC; UNKNOWN - 0x10EFD, // 10EFD..10EFF; ARABIC + 0x10EB2, // 10EB2..10EC1; UNKNOWN + 0x10EC2, // 10EC2..10EC4; ARABIC + 0x10EC5, // 10EC5..10EFB; UNKNOWN + 0x10EFC, // 10EFC..10EFF; ARABIC 0x10F00, // 10F00..10F27; OLD_SOGDIAN 0x10F28, // 10F28..10F2F; UNKNOWN 0x10F30, // 10F30..10F59; SOGDIAN @@ -6544,7 +6711,29 @@ public static enum UnicodeScript { 0x11366, // 11366..1136C; GRANTHA 0x1136D, // 1136D..1136F; UNKNOWN 0x11370, // 11370..11374; GRANTHA - 0x11375, // 11375..113FF; UNKNOWN + 0x11375, // 11375..1137F; UNKNOWN + 0x11380, // 11380..11389; TULU_TIGALARI + 0x1138A, // 1138A ; UNKNOWN + 0x1138B, // 1138B ; TULU_TIGALARI + 0x1138C, // 1138C..1138D; UNKNOWN + 0x1138E, // 1138E ; TULU_TIGALARI + 0x1138F, // 1138F ; UNKNOWN + 0x11390, // 11390..113B5; TULU_TIGALARI + 0x113B6, // 113B6 ; UNKNOWN + 0x113B7, // 113B7..113C0; TULU_TIGALARI + 0x113C1, // 113C1 ; UNKNOWN + 0x113C2, // 113C2 ; TULU_TIGALARI + 0x113C3, // 113C3..113C4; UNKNOWN + 0x113C5, // 113C5 ; TULU_TIGALARI + 0x113C6, // 113C6 ; UNKNOWN + 0x113C7, // 113C7..113CA; TULU_TIGALARI + 0x113CB, // 113CB ; UNKNOWN + 0x113CC, // 113CC..113D5; TULU_TIGALARI + 0x113D6, // 113D6 ; UNKNOWN + 0x113D7, // 113D7..113D8; TULU_TIGALARI + 0x113D9, // 113D9..113E0; UNKNOWN + 0x113E1, // 113E1..113E2; TULU_TIGALARI + 0x113E3, // 113E3..113FF; UNKNOWN 0x11400, // 11400..1145B; NEWA 0x1145C, // 1145C ; UNKNOWN 0x1145D, // 1145D..11461; NEWA @@ -6566,7 +6755,9 @@ public static enum UnicodeScript { 0x11680, // 11680..116B9; TAKRI 0x116BA, // 116BA..116BF; UNKNOWN 0x116C0, // 116C0..116C9; TAKRI - 0x116CA, // 116CA..116FF; UNKNOWN + 0x116CA, // 116CA..116CF; UNKNOWN + 0x116D0, // 116D0..116E3; MYANMAR + 0x116E4, // 116E4..116FF; UNKNOWN 0x11700, // 11700..1171A; AHOM 0x1171B, // 1171B..1171C; UNKNOWN 0x1171D, // 1171D..1172B; AHOM @@ -6608,7 +6799,11 @@ public static enum UnicodeScript { 0x11AC0, // 11AC0..11AF8; PAU_CIN_HAU 0x11AF9, // 11AF9..11AFF; UNKNOWN 0x11B00, // 11B00..11B09; DEVANAGARI - 0x11B0A, // 11B0A..11BFF; UNKNOWN + 0x11B0A, // 11B0A..11BBF; UNKNOWN + 0x11BC0, // 11BC0..11BE1; SUNUWAR + 0x11BE2, // 11BE2..11BEF; UNKNOWN + 0x11BF0, // 11BF0..11BF9; SUNUWAR + 0x11BFA, // 11BFA..11BFF; UNKNOWN 0x11C00, // 11C00..11C08; BHAIKSUKI 0x11C09, // 11C09 ; UNKNOWN 0x11C0A, // 11C0A..11C36; BHAIKSUKI @@ -6655,8 +6850,8 @@ public static enum UnicodeScript { 0x11F11, // 11F11 ; UNKNOWN 0x11F12, // 11F12..11F3A; KAWI 0x11F3B, // 11F3B..11F3D; UNKNOWN - 0x11F3E, // 11F3E..11F59; KAWI - 0x11F5A, // 11F5A..11FAF; UNKNOWN + 0x11F3E, // 11F3E..11F5A; KAWI + 0x11F5B, // 11F5B..11FAF; UNKNOWN 0x11FB0, // 11FB0 ; LISU 0x11FB1, // 11FB1..11FBF; UNKNOWN 0x11FC0, // 11FC0..11FF1; TAMIL @@ -6673,9 +6868,13 @@ public static enum UnicodeScript { 0x12F90, // 12F90..12FF2; CYPRO_MINOAN 0x12FF3, // 12FF3..12FFF; UNKNOWN 0x13000, // 13000..13455; EGYPTIAN_HIEROGLYPHS - 0x13456, // 13456..143FF; UNKNOWN + 0x13456, // 13456..1345F; UNKNOWN + 0x13460, // 13460..143FA; EGYPTIAN_HIEROGLYPHS + 0x143FB, // 143FB..143FF; UNKNOWN 0x14400, // 14400..14646; ANATOLIAN_HIEROGLYPHS - 0x14647, // 14647..167FF; UNKNOWN + 0x14647, // 14647..160FF; UNKNOWN + 0x16100, // 16100..16139; GURUNG_KHEMA + 0x1613A, // 1613A..167FF; UNKNOWN 0x16800, // 16800..16A38; BAMUM 0x16A39, // 16A39..16A3F; UNKNOWN 0x16A40, // 16A40..16A5E; MRO @@ -6700,7 +6899,9 @@ public static enum UnicodeScript { 0x16B63, // 16B63..16B77; PAHAWH_HMONG 0x16B78, // 16B78..16B7C; UNKNOWN 0x16B7D, // 16B7D..16B8F; PAHAWH_HMONG - 0x16B90, // 16B90..16E3F; UNKNOWN + 0x16B90, // 16B90..16D3F; UNKNOWN + 0x16D40, // 16D40..16D79; KIRAT_RAI + 0x16D7A, // 16D7A..16E3F; UNKNOWN 0x16E40, // 16E40..16E9A; MEDEFAIDRIN 0x16E9B, // 16E9B..16EFF; UNKNOWN 0x16F00, // 16F00..16F4A; MIAO @@ -6720,7 +6921,8 @@ public static enum UnicodeScript { 0x187F8, // 187F8..187FF; UNKNOWN 0x18800, // 18800..18AFF; TANGUT 0x18B00, // 18B00..18CD5; KHITAN_SMALL_SCRIPT - 0x18CD6, // 18CD6..18CFF; UNKNOWN + 0x18CD6, // 18CD6..18CFE; UNKNOWN + 0x18CFF, // 18CFF ; KHITAN_SMALL_SCRIPT 0x18D00, // 18D00..18D08; TANGUT 0x18D09, // 18D09..1AFEF; UNKNOWN 0x1AFF0, // 1AFF0..1AFF3; KATAKANA @@ -6753,7 +6955,11 @@ public static enum UnicodeScript { 0x1BC9A, // 1BC9A..1BC9B; UNKNOWN 0x1BC9C, // 1BC9C..1BC9F; DUPLOYAN 0x1BCA0, // 1BCA0..1BCA3; COMMON - 0x1BCA4, // 1BCA4..1CEFF; UNKNOWN + 0x1BCA4, // 1BCA4..1CBFF; UNKNOWN + 0x1CC00, // 1CC00..1CCF9; COMMON + 0x1CCFA, // 1CCFA..1CCFF; UNKNOWN + 0x1CD00, // 1CD00..1CEB3; COMMON + 0x1CEB4, // 1CEB4..1CEFF; UNKNOWN 0x1CF00, // 1CF00..1CF2D; INHERITED 0x1CF2E, // 1CF2E..1CF2F; UNKNOWN 0x1CF30, // 1CF30..1CF46; INHERITED @@ -6864,7 +7070,11 @@ public static enum UnicodeScript { 0x1E2FF, // 1E2FF ; WANCHO 0x1E300, // 1E300..1E4CF; UNKNOWN 0x1E4D0, // 1E4D0..1E4F9; NAG_MUNDARI - 0x1E4FA, // 1E4FA..1E7DF; UNKNOWN + 0x1E4FA, // 1E4FA..1E5CF; UNKNOWN + 0x1E5D0, // 1E5D0..1E5FA; OL_ONAL + 0x1E5FB, // 1E5FB..1E5FE; UNKNOWN + 0x1E5FF, // 1E5FF ; OL_ONAL + 0x1E600, // 1E600..1E7DF; UNKNOWN 0x1E7E0, // 1E7E0..1E7E6; ETHIOPIC 0x1E7E7, // 1E7E7 ; UNKNOWN 0x1E7E8, // 1E7E8..1E7EB; ETHIOPIC @@ -7005,31 +7215,29 @@ public static enum UnicodeScript { 0x1F888, // 1F888..1F88F; UNKNOWN 0x1F890, // 1F890..1F8AD; COMMON 0x1F8AE, // 1F8AE..1F8AF; UNKNOWN - 0x1F8B0, // 1F8B0..1F8B1; COMMON - 0x1F8B2, // 1F8B2..1F8FF; UNKNOWN + 0x1F8B0, // 1F8B0..1F8BB; COMMON + 0x1F8BC, // 1F8BC..1F8BF; UNKNOWN + 0x1F8C0, // 1F8C0..1F8C1; COMMON + 0x1F8C2, // 1F8C2..1F8FF; UNKNOWN 0x1F900, // 1F900..1FA53; COMMON 0x1FA54, // 1FA54..1FA5F; UNKNOWN 0x1FA60, // 1FA60..1FA6D; COMMON 0x1FA6E, // 1FA6E..1FA6F; UNKNOWN 0x1FA70, // 1FA70..1FA7C; COMMON 0x1FA7D, // 1FA7D..1FA7F; UNKNOWN - 0x1FA80, // 1FA80..1FA88; COMMON - 0x1FA89, // 1FA89..1FA8F; UNKNOWN - 0x1FA90, // 1FA90..1FABD; COMMON - 0x1FABE, // 1FABE ; UNKNOWN - 0x1FABF, // 1FABF..1FAC5; COMMON - 0x1FAC6, // 1FAC6..1FACD; UNKNOWN - 0x1FACE, // 1FACE..1FADB; COMMON - 0x1FADC, // 1FADC..1FADF; UNKNOWN - 0x1FAE0, // 1FAE0..1FAE8; COMMON - 0x1FAE9, // 1FAE9..1FAEF; UNKNOWN + 0x1FA80, // 1FA80..1FA89; COMMON + 0x1FA8A, // 1FA8A..1FA8E; UNKNOWN + 0x1FA8F, // 1FA8F..1FAC6; COMMON + 0x1FAC7, // 1FAC7..1FACD; UNKNOWN + 0x1FACE, // 1FACE..1FADC; COMMON + 0x1FADD, // 1FADD..1FADE; UNKNOWN + 0x1FADF, // 1FADF..1FAE9; COMMON + 0x1FAEA, // 1FAEA..1FAEF; UNKNOWN 0x1FAF0, // 1FAF0..1FAF8; COMMON 0x1FAF9, // 1FAF9..1FAFF; UNKNOWN 0x1FB00, // 1FB00..1FB92; COMMON 0x1FB93, // 1FB93 ; UNKNOWN - 0x1FB94, // 1FB94..1FBCA; COMMON - 0x1FBCB, // 1FBCB..1FBEF; UNKNOWN - 0x1FBF0, // 1FBF0..1FBF9; COMMON + 0x1FB94, // 1FB94..1FBF9; COMMON 0x1FBFA, // 1FBFA..1FFFF; UNKNOWN 0x20000, // 20000..2A6DF; HAN 0x2A6E0, // 2A6E0..2A6FF; UNKNOWN @@ -7156,8 +7364,8 @@ public static enum UnicodeScript { ARABIC, // 0870..088E UNKNOWN, // 088F ARABIC, // 0890..0891 - UNKNOWN, // 0892..0897 - ARABIC, // 0898..08E1 + UNKNOWN, // 0892..0896 + ARABIC, // 0897..08E1 COMMON, // 08E2 ARABIC, // 08E3..08FF DEVANAGARI, // 0900..0950 @@ -7570,9 +7778,8 @@ public static enum UnicodeScript { INHERITED, // 1AB0..1ACE UNKNOWN, // 1ACF..1AFF BALINESE, // 1B00..1B4C - UNKNOWN, // 1B4D..1B4F - BALINESE, // 1B50..1B7E - UNKNOWN, // 1B7F + UNKNOWN, // 1B4D + BALINESE, // 1B4E..1B7F SUNDANESE, // 1B80..1BBF BATAK, // 1BC0..1BF3 UNKNOWN, // 1BF4..1BFB @@ -7583,8 +7790,8 @@ public static enum UnicodeScript { UNKNOWN, // 1C4A..1C4C LEPCHA, // 1C4D..1C4F OL_CHIKI, // 1C50..1C7F - CYRILLIC, // 1C80..1C88 - UNKNOWN, // 1C89..1C8F + CYRILLIC, // 1C80..1C8A + UNKNOWN, // 1C8B..1C8F GEORGIAN, // 1C90..1CBA UNKNOWN, // 1CBB..1CBC GEORGIAN, // 1CBD..1CBF @@ -7677,8 +7884,8 @@ public static enum UnicodeScript { LATIN, // 2160..2188 COMMON, // 2189..218B UNKNOWN, // 218C..218F - COMMON, // 2190..2426 - UNKNOWN, // 2427..243F + COMMON, // 2190..2429 + UNKNOWN, // 242A..243F COMMON, // 2440..244A UNKNOWN, // 244B..245F COMMON, // 2460..27FF @@ -7759,8 +7966,8 @@ public static enum UnicodeScript { UNKNOWN, // 318F COMMON, // 3190..319F BOPOMOFO, // 31A0..31BF - COMMON, // 31C0..31E3 - UNKNOWN, // 31E4..31EE + COMMON, // 31C0..31E5 + UNKNOWN, // 31E6..31EE COMMON, // 31EF KATAKANA, // 31F0..31FF HANGUL, // 3200..321E @@ -7788,14 +7995,14 @@ public static enum UnicodeScript { COMMON, // A700..A721 LATIN, // A722..A787 COMMON, // A788..A78A - LATIN, // A78B..A7CA - UNKNOWN, // A7CB..A7CF + LATIN, // A78B..A7CD + UNKNOWN, // A7CE..A7CF LATIN, // A7D0..A7D1 UNKNOWN, // A7D2 LATIN, // A7D3 UNKNOWN, // A7D4 - LATIN, // A7D5..A7D9 - UNKNOWN, // A7DA..A7F1 + LATIN, // A7D5..A7DC + UNKNOWN, // A7DD..A7F1 LATIN, // A7F2..A7FF SYLOTI_NAGRI, // A800..A82C UNKNOWN, // A82D..A82F @@ -8016,7 +8223,9 @@ public static enum UnicodeScript { VITHKUQI, // 105B3..105B9 UNKNOWN, // 105BA VITHKUQI, // 105BB..105BC - UNKNOWN, // 105BD..105FF + UNKNOWN, // 105BD..105BF + TODHRI, // 105C0..105F3 + UNKNOWN, // 105F4..105FF LINEAR_A, // 10600..10736 UNKNOWN, // 10737..1073F LINEAR_A, // 10740..10755 @@ -8114,7 +8323,13 @@ public static enum UnicodeScript { HANIFI_ROHINGYA, // 10D00..10D27 UNKNOWN, // 10D28..10D2F HANIFI_ROHINGYA, // 10D30..10D39 - UNKNOWN, // 10D3A..10E5F + UNKNOWN, // 10D3A..10D3F + GARAY, // 10D40..10D65 + UNKNOWN, // 10D66..10D68 + GARAY, // 10D69..10D85 + UNKNOWN, // 10D86..10D8D + GARAY, // 10D8E..10D8F + UNKNOWN, // 10D90..10E5F ARABIC, // 10E60..10E7E UNKNOWN, // 10E7F YEZIDI, // 10E80..10EA9 @@ -8122,8 +8337,10 @@ public static enum UnicodeScript { YEZIDI, // 10EAB..10EAD UNKNOWN, // 10EAE..10EAF YEZIDI, // 10EB0..10EB1 - UNKNOWN, // 10EB2..10EFC - ARABIC, // 10EFD..10EFF + UNKNOWN, // 10EB2..10EC1 + ARABIC, // 10EC2..10EC4 + UNKNOWN, // 10EC5..10EFB + ARABIC, // 10EFC..10EFF OLD_SOGDIAN, // 10F00..10F27 UNKNOWN, // 10F28..10F2F SOGDIAN, // 10F30..10F59 @@ -8205,7 +8422,29 @@ public static enum UnicodeScript { GRANTHA, // 11366..1136C UNKNOWN, // 1136D..1136F GRANTHA, // 11370..11374 - UNKNOWN, // 11375..113FF + UNKNOWN, // 11375..1137F + TULU_TIGALARI, // 11380..11389 + UNKNOWN, // 1138A + TULU_TIGALARI, // 1138B + UNKNOWN, // 1138C..1138D + TULU_TIGALARI, // 1138E + UNKNOWN, // 1138F + TULU_TIGALARI, // 11390..113B5 + UNKNOWN, // 113B6 + TULU_TIGALARI, // 113B7..113C0 + UNKNOWN, // 113C1 + TULU_TIGALARI, // 113C2 + UNKNOWN, // 113C3..113C4 + TULU_TIGALARI, // 113C5 + UNKNOWN, // 113C6 + TULU_TIGALARI, // 113C7..113CA + UNKNOWN, // 113CB + TULU_TIGALARI, // 113CC..113D5 + UNKNOWN, // 113D6 + TULU_TIGALARI, // 113D7..113D8 + UNKNOWN, // 113D9..113E0 + TULU_TIGALARI, // 113E1..113E2 + UNKNOWN, // 113E3..113FF NEWA, // 11400..1145B UNKNOWN, // 1145C NEWA, // 1145D..11461 @@ -8227,7 +8466,9 @@ public static enum UnicodeScript { TAKRI, // 11680..116B9 UNKNOWN, // 116BA..116BF TAKRI, // 116C0..116C9 - UNKNOWN, // 116CA..116FF + UNKNOWN, // 116CA..116CF + MYANMAR, // 116D0..116E3 + UNKNOWN, // 116E4..116FF AHOM, // 11700..1171A UNKNOWN, // 1171B..1171C AHOM, // 1171D..1172B @@ -8269,7 +8510,11 @@ public static enum UnicodeScript { PAU_CIN_HAU, // 11AC0..11AF8 UNKNOWN, // 11AF9..11AFF DEVANAGARI, // 11B00..11B09 - UNKNOWN, // 11B0A..11BFF + UNKNOWN, // 11B0A..11BBF + SUNUWAR, // 11BC0..11BE1 + UNKNOWN, // 11BE2..11BEF + SUNUWAR, // 11BF0..11BF9 + UNKNOWN, // 11BFA..11BFF BHAIKSUKI, // 11C00..11C08 UNKNOWN, // 11C09 BHAIKSUKI, // 11C0A..11C36 @@ -8316,8 +8561,8 @@ public static enum UnicodeScript { UNKNOWN, // 11F11 KAWI, // 11F12..11F3A UNKNOWN, // 11F3B..11F3D - KAWI, // 11F3E..11F59 - UNKNOWN, // 11F5A..11FAF + KAWI, // 11F3E..11F5A + UNKNOWN, // 11F5B..11FAF LISU, // 11FB0 UNKNOWN, // 11FB1..11FBF TAMIL, // 11FC0..11FF1 @@ -8334,9 +8579,13 @@ public static enum UnicodeScript { CYPRO_MINOAN, // 12F90..12FF2 UNKNOWN, // 12FF3..12FFF EGYPTIAN_HIEROGLYPHS, // 13000..13455 - UNKNOWN, // 13456..143FF + UNKNOWN, // 13456..1345F + EGYPTIAN_HIEROGLYPHS, // 13460..143FA + UNKNOWN, // 143FB..143FF ANATOLIAN_HIEROGLYPHS, // 14400..14646 - UNKNOWN, // 14647..167FF + UNKNOWN, // 14647..160FF + GURUNG_KHEMA, // 16100..16139 + UNKNOWN, // 1613A..167FF BAMUM, // 16800..16A38 UNKNOWN, // 16A39..16A3F MRO, // 16A40..16A5E @@ -8361,7 +8610,9 @@ public static enum UnicodeScript { PAHAWH_HMONG, // 16B63..16B77 UNKNOWN, // 16B78..16B7C PAHAWH_HMONG, // 16B7D..16B8F - UNKNOWN, // 16B90..16E3F + UNKNOWN, // 16B90..16D3F + KIRAT_RAI, // 16D40..16D79 + UNKNOWN, // 16D7A..16E3F MEDEFAIDRIN, // 16E40..16E9A UNKNOWN, // 16E9B..16EFF MIAO, // 16F00..16F4A @@ -8381,7 +8632,8 @@ public static enum UnicodeScript { UNKNOWN, // 187F8..187FF TANGUT, // 18800..18AFF KHITAN_SMALL_SCRIPT, // 18B00..18CD5 - UNKNOWN, // 18CD6..18CFF + UNKNOWN, // 18CD6..18CFE + KHITAN_SMALL_SCRIPT, // 18CFF TANGUT, // 18D00..18D08 UNKNOWN, // 18D09..1AFEF KATAKANA, // 1AFF0..1AFF3 @@ -8414,7 +8666,11 @@ public static enum UnicodeScript { UNKNOWN, // 1BC9A..1BC9B DUPLOYAN, // 1BC9C..1BC9F COMMON, // 1BCA0..1BCA3 - UNKNOWN, // 1BCA4..1CEFF + UNKNOWN, // 1BCA4..1CBFF + COMMON, // 1CC00..1CCF9 + UNKNOWN, // 1CCFA..1CCFF + COMMON, // 1CD00..1CEB3 + UNKNOWN, // 1CEB4..1CEFF INHERITED, // 1CF00..1CF2D UNKNOWN, // 1CF2E..1CF2F INHERITED, // 1CF30..1CF46 @@ -8525,7 +8781,11 @@ public static enum UnicodeScript { WANCHO, // 1E2FF UNKNOWN, // 1E300..1E4CF NAG_MUNDARI, // 1E4D0..1E4F9 - UNKNOWN, // 1E4FA..1E7DF + UNKNOWN, // 1E4FA..1E5CF + OL_ONAL, // 1E5D0..1E5FA + UNKNOWN, // 1E5FB..1E5FE + OL_ONAL, // 1E5FF + UNKNOWN, // 1E600..1E7DF ETHIOPIC, // 1E7E0..1E7E6 UNKNOWN, // 1E7E7 ETHIOPIC, // 1E7E8..1E7EB @@ -8666,31 +8926,29 @@ public static enum UnicodeScript { UNKNOWN, // 1F888..1F88F COMMON, // 1F890..1F8AD UNKNOWN, // 1F8AE..1F8AF - COMMON, // 1F8B0..1F8B1 - UNKNOWN, // 1F8B2..1F8FF + COMMON, // 1F8B0..1F8BB + UNKNOWN, // 1F8BC..1F8BF + COMMON, // 1F8C0..1F8C1 + UNKNOWN, // 1F8C2..1F8FF COMMON, // 1F900..1FA53 UNKNOWN, // 1FA54..1FA5F COMMON, // 1FA60..1FA6D UNKNOWN, // 1FA6E..1FA6F COMMON, // 1FA70..1FA7C UNKNOWN, // 1FA7D..1FA7F - COMMON, // 1FA80..1FA88 - UNKNOWN, // 1FA89..1FA8F - COMMON, // 1FA90..1FABD - UNKNOWN, // 1FABE - COMMON, // 1FABF..1FAC5 - UNKNOWN, // 1FAC6..1FACD - COMMON, // 1FACE..1FADB - UNKNOWN, // 1FADC..1FADF - COMMON, // 1FAE0..1FAE8 - UNKNOWN, // 1FAE9..1FAEF + COMMON, // 1FA80..1FA89 + UNKNOWN, // 1FA8A..1FA8E + COMMON, // 1FA8F..1FAC6 + UNKNOWN, // 1FAC7..1FACD + COMMON, // 1FACE..1FADC + UNKNOWN, // 1FADD..1FADE + COMMON, // 1FADF..1FAE9 + UNKNOWN, // 1FAEA..1FAEF COMMON, // 1FAF0..1FAF8 UNKNOWN, // 1FAF9..1FAFF COMMON, // 1FB00..1FB92 UNKNOWN, // 1FB93 - COMMON, // 1FB94..1FBCA - UNKNOWN, // 1FBCB..1FBEF - COMMON, // 1FBF0..1FBF9 + COMMON, // 1FB94..1FBF9 UNKNOWN, // 1FBFA..1FFFF HAN, // 20000..2A6DF UNKNOWN, // 2A6E0..2A6FF @@ -8758,6 +9016,7 @@ public static enum UnicodeScript { aliases.put("ELBA", ELBASAN); aliases.put("ELYM", ELYMAIC); aliases.put("ETHI", ETHIOPIC); + aliases.put("GARA", GARAY); aliases.put("GEOR", GEORGIAN); aliases.put("GLAG", GLAGOLITIC); aliases.put("GONG", GUNJALA_GONDI); @@ -8766,6 +9025,7 @@ public static enum UnicodeScript { aliases.put("GRAN", GRANTHA); aliases.put("GREK", GREEK); aliases.put("GUJR", GUJARATI); + aliases.put("GUKH", GURUNG_KHEMA); aliases.put("GURU", GURMUKHI); aliases.put("HANG", HANGUL); aliases.put("HANI", HAN); @@ -8787,6 +9047,7 @@ public static enum UnicodeScript { aliases.put("KHOJ", KHOJKI); aliases.put("KITS", KHITAN_SMALL_SCRIPT); aliases.put("KNDA", KANNADA); + aliases.put("KRAI", KIRAT_RAI); aliases.put("KTHI", KAITHI); aliases.put("LANA", TAI_THAM); aliases.put("LAOO", LAO); @@ -8823,6 +9084,7 @@ public static enum UnicodeScript { aliases.put("NSHU", NUSHU); aliases.put("OGAM", OGHAM); aliases.put("OLCK", OL_CHIKI); + aliases.put("ONAO", OL_ONAL); aliases.put("ORKH", OLD_TURKIC); aliases.put("ORYA", ORIYA); aliases.put("OSGE", OSAGE); @@ -8854,6 +9116,7 @@ public static enum UnicodeScript { aliases.put("SORA", SORA_SOMPENG); aliases.put("SOYO", SOYOMBO); aliases.put("SUND", SUNDANESE); + aliases.put("SUNU", SUNUWAR); aliases.put("SYLO", SYLOTI_NAGRI); aliases.put("SYRC", SYRIAC); aliases.put("TAGB", TAGBANWA); @@ -8871,7 +9134,9 @@ public static enum UnicodeScript { aliases.put("TIBT", TIBETAN); aliases.put("TIRH", TIRHUTA); aliases.put("TNSA", TANGSA); + aliases.put("TODR", TODHRI); aliases.put("TOTO", TOTO); + aliases.put("TUTG", TULU_TIGALARI); aliases.put("UGAR", UGARITIC); aliases.put("VAII", VAI); aliases.put("VITH", VITHKUQI); diff --git a/src/java.base/share/classes/java/lang/CharacterData00.java.template b/src/java.base/share/classes/java/lang/CharacterData00.java.template index 2b16b410e61..db496250201 100644 --- a/src/java.base/share/classes/java/lang/CharacterData00.java.template +++ b/src/java.base/share/classes/java/lang/CharacterData00.java.template @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -382,6 +382,8 @@ class CharacterData00 extends CharacterData { case 0xA7B3: mapChar = 0xAB53; break; case 0xA7C5: mapChar = 0x0282; break; case 0xA7C6: mapChar = 0x1D8E; break; + case 0xA7CB: mapChar = 0x0264; break; + case 0xA7DC: mapChar = 0x019B; break; // default mapChar is already set, so no // need to redo it here. // default : mapChar = ch; @@ -403,6 +405,7 @@ class CharacterData00 extends CharacterData { if ((val & $$maskCaseOffset) == $$maskCaseOffset) { switch(ch) { case 0x017F: mapChar = 0x0053; break; + case 0x019B: mapChar = 0xA7DC; break; case 0x023F: mapChar = 0x2C7E; break; case 0x0240: mapChar = 0x2C7F; break; case 0x0250: mapChar = 0x2C6F; break; @@ -410,6 +413,7 @@ class CharacterData00 extends CharacterData { case 0x0252: mapChar = 0x2C70; break; case 0x025C: mapChar = 0xA7AB; break; case 0x0261: mapChar = 0xA7AC; break; + case 0x0264: mapChar = 0xA7CB; break; case 0x0265: mapChar = 0xA78D; break; case 0x0266: mapChar = 0xA7AA; break; case 0x026A: mapChar = 0xA7AE; break; @@ -857,6 +861,7 @@ class CharacterData00 extends CharacterData { else { switch(ch) { case 0x017F: mapChar = 0x0053; break; + case 0x019B: mapChar = 0xA7DC; break; case 0x023F: mapChar = 0x2C7E; break; case 0x0240: mapChar = 0x2C7F; break; case 0x0250: mapChar = 0x2C6F; break; @@ -864,6 +869,7 @@ class CharacterData00 extends CharacterData { case 0x0252: mapChar = 0x2C70; break; case 0x025C: mapChar = 0xA7AB; break; case 0x0261: mapChar = 0xA7AC; break; + case 0x0264: mapChar = 0xA7CB; break; case 0x0265: mapChar = 0xA78D; break; case 0x0266: mapChar = 0xA7AA; break; case 0x026A: mapChar = 0xA7AE; break; diff --git a/src/java.base/share/classes/jdk/internal/icu/impl/NormalizerImpl.java b/src/java.base/share/classes/jdk/internal/icu/impl/NormalizerImpl.java index 291653f9995..82f294c31cf 100644 --- a/src/java.base/share/classes/jdk/internal/icu/impl/NormalizerImpl.java +++ b/src/java.base/share/classes/jdk/internal/icu/impl/NormalizerImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -172,7 +172,7 @@ public void append(CharSequence s, int start, int limit, boolean isNFD, start+=Character.charCount(c); if(start<limit) { if (isNFD) { - leadCC = getCCFromYesOrMaybe(impl.getNorm16(c)); + leadCC = getCCFromYesOrMaybeYes(impl.getNorm16(c)); } else { leadCC = impl.getCC(impl.getNorm16(c)); } @@ -308,7 +308,7 @@ private int previousCC() { // Returns 0 if there is no previous character. } int c=str.codePointBefore(codePointStart); codePointStart-=Character.charCount(c); - return impl.getCCFromYesOrMaybeCP(c); + return impl.getCCFromYesOrMaybeYesCP(c); } private int codePointStart, codePointLimit; } @@ -363,7 +363,7 @@ public NormalizerImpl() {} private static final class IsAcceptable implements ICUBinary.Authenticate { public boolean isDataVersionAcceptable(byte version[]) { - return version[0]==4; + return version[0]==5; } } private static final IsAcceptable IS_ACCEPTABLE = new IsAcceptable(); @@ -393,9 +393,11 @@ public NormalizerImpl load(ByteBuffer bytes) { minNoNoCompNoMaybeCC=inIndexes[IX_MIN_NO_NO_COMP_NO_MAYBE_CC]; minNoNoEmpty=inIndexes[IX_MIN_NO_NO_EMPTY]; limitNoNo=inIndexes[IX_LIMIT_NO_NO]; + minMaybeNo=inIndexes[IX_MIN_MAYBE_NO]; + minMaybeNoCombinesFwd=inIndexes[IX_MIN_MAYBE_NO_COMBINES_FWD]; minMaybeYes=inIndexes[IX_MIN_MAYBE_YES]; - assert((minMaybeYes&7)==0); // 8-aligned for noNoDelta bit fields - centerNoNoDelta=(minMaybeYes>>DELTA_SHIFT)-MAX_DELTA-1; + assert((minMaybeNo&7)==0); // 8-aligned for noNoDelta bit fields + centerNoNoDelta=(minMaybeNo>>DELTA_SHIFT)-MAX_DELTA-1; // Read the normTrie. int offset=inIndexes[IX_NORM_TRIE_OFFSET]; @@ -413,8 +415,7 @@ public NormalizerImpl load(ByteBuffer bytes) { nextOffset=inIndexes[IX_SMALL_FCD_OFFSET]; int numChars=(nextOffset-offset)/2; if(numChars!=0) { - maybeYesCompositions=ICUBinary.getString(bytes, numChars, 0); - extraData=maybeYesCompositions.substring((MIN_NORMAL_MAYBE_YES-minMaybeYes)>>OFFSET_SHIFT); + extraData=ICUBinary.getString(bytes, numChars, 0); } // smallFCD: new in formatVersion 2 @@ -437,8 +438,8 @@ public int getNorm16(int c) { return UTF16Plus.isLeadSurrogate(c) ? INERT : normTrie.get(c); } public int getRawNorm16(int c) { return normTrie.get(c); } - public boolean isAlgorithmicNoNo(int norm16) { return limitNoNo<=norm16 && norm16<minMaybeYes; } - public boolean isCompNo(int norm16) { return minNoNo<=norm16 && norm16<minMaybeYes; } + public boolean isAlgorithmicNoNo(int norm16) { return limitNoNo<=norm16 && norm16<minMaybeNo; } + public boolean isCompNo(int norm16) { return minNoNo<=norm16 && norm16<minMaybeNo; } public boolean isDecompYes(int norm16) { return norm16<minYesNo || minMaybeYes<=norm16; } public int getCC(int norm16) { @@ -453,12 +454,12 @@ public int getCC(int norm16) { public static int getCCFromNormalYesOrMaybe(int norm16) { return (norm16 >> OFFSET_SHIFT) & 0xff; } - public static int getCCFromYesOrMaybe(int norm16) { + public static int getCCFromYesOrMaybeYes(int norm16) { return norm16>=MIN_NORMAL_MAYBE_YES ? getCCFromNormalYesOrMaybe(norm16) : 0; } - public int getCCFromYesOrMaybeCP(int c) { + public int getCCFromYesOrMaybeYesCP(int c) { if (c < minCompNoMaybeCP) { return 0; } - return getCCFromYesOrMaybe(getNorm16(c)); + return getCCFromYesOrMaybeYes(getNorm16(c)); } /** @@ -492,7 +493,7 @@ public int getFCD16FromNormData(int c) { return norm16|(norm16<<8); } else if(norm16>=minMaybeYes) { return 0; - } else { // isDecompNoAlgorithmic(norm16) + } else if(norm16<minMaybeNo) { // isDecompNoAlgorithmic(norm16) int deltaTrailCC = norm16 & DELTA_TCCC_MASK; if (deltaTrailCC <= DELTA_TCCC_1) { return deltaTrailCC >> OFFSET_SHIFT; @@ -507,7 +508,7 @@ public int getFCD16FromNormData(int c) { return 0; } // c decomposes, get everything from the variable-length extra data - int mapping=norm16>>OFFSET_SHIFT; + int mapping=getData(norm16); int firstUnit=extraData.charAt(mapping); int fcd16=firstUnit>>8; // tccc if((firstUnit&MAPPING_HAS_CCC_LCCC_WORD)!=0) { @@ -516,6 +517,24 @@ public int getFCD16FromNormData(int c) { return fcd16; } + private int getFCD16FromMaybeOrNonZeroCC(int norm16) { + assert norm16 >= minMaybeNo; + if (norm16 >= MIN_NORMAL_MAYBE_YES) { + // combining mark + norm16 = getCCFromNormalYesOrMaybe(norm16); + return norm16 | (norm16<<8); + } else if (norm16 >= minMaybeYes) { + return 0; + } + // c decomposes, get everything from the variable-length extra data + int mapping = getDataForMaybe(norm16); + int firstUnit = extraData.charAt(mapping); + // maybeNo has lccc = 0 + assert (firstUnit & MAPPING_HAS_CCC_LCCC_WORD) == 0 || + (extraData.charAt(mapping - 1) & 0xff00) == 0; + return firstUnit >> 8; // tccc + } + /** * Gets the decomposition for one code point. * @param c code point @@ -523,7 +542,7 @@ public int getFCD16FromNormData(int c) { */ public String getDecomposition(int c) { int norm16; - if(c<minDecompNoCP || isMaybeOrNonZeroCC(norm16=getNorm16(c))) { + if(c<minDecompNoCP || isMaybeYesOrNonZeroCC(norm16=getNorm16(c))) { // c does not decompose return null; } @@ -547,7 +566,7 @@ public String getDecomposition(int c) { return buffer.toString(); } // c decomposes, get everything from the variable-length extra data - int mapping=norm16>>OFFSET_SHIFT; + int mapping=getData(norm16); int length=extraData.charAt(mapping++)&MAPPING_LENGTH_MASK; return extraData.substring(mapping, mapping+length); } @@ -603,7 +622,13 @@ public String getDecomposition(int c) { public static final int IX_MIN_NO_NO_EMPTY=17; public static final int IX_MIN_LCCC_CP=18; - public static final int IX_COUNT=20; + + /** Two-way mappings; each starts with a character that combines backward. */ + public static final int IX_MIN_MAYBE_NO=20; + /** Two-way mappings & compositions. */ + public static final int IX_MIN_MAYBE_NO_COMBINES_FWD=21; + + //blic static final int IX_COUNT=22; public static final int MAPPING_HAS_CCC_LCCC_WORD=0x80; public static final int MAPPING_HAS_RAW_MAPPING=0x40; @@ -693,7 +718,7 @@ public int decompose(CharSequence s, int src, int limit, decompose(c, norm16, buffer); } else { if(isDecompYes(norm16)) { - int cc=getCCFromYesOrMaybe(norm16); + int cc=getCCFromYesOrMaybeYes(norm16); if(prevCC<=cc || cc==0) { prevCC=cc; if(cc<=1) { @@ -780,12 +805,12 @@ public boolean compose(CharSequence s, int src, int limit, } // isCompYesAndZeroCC(norm16) is false, that is, norm16>=minNoNo. // The current character is either a "noNo" (has a mapping) - // or a "maybeYes" (combines backward) + // or a "maybeYes" / "maybeNo" (combines backward) // or a "yesYes" with ccc!=0. // It is not a Hangul syllable or Jamo L because those have "yes" properties. // Medium-fast path: Handle cases that do not require full decomposition and recomposition. - if (!isMaybeOrNonZeroCC(norm16)) { // minNoNo <= norm16 < minMaybeYes + if (norm16 < minMaybeNo) { // minNoNo <= norm16 < minMaybeNo if (!doCompose) { return false; } @@ -810,7 +835,7 @@ public boolean compose(CharSequence s, int src, int limit, if (prevBoundary != prevSrc) { buffer.append(s, prevBoundary, prevSrc); } - int mapping = norm16 >> OFFSET_SHIFT; + int mapping = getDataForYesOrNo(norm16); int length = extraData.charAt(mapping++) & MAPPING_LENGTH_MASK; buffer.append(extraData, mapping, mapping + length); prevBoundary = src; @@ -1016,7 +1041,7 @@ public int composeQuickCheck(CharSequence s, int src, int limit, } // isCompYesAndZeroCC(norm16) is false, that is, norm16>=minNoNo. // The current character is either a "noNo" (has a mapping) - // or a "maybeYes" (combines backward) + // or a "maybeYes" / "maybeNo" (combines backward) // or a "yesYes" with ccc!=0. // It is not a Hangul syllable or Jamo L because those have "yes" properties. @@ -1033,8 +1058,9 @@ public int composeQuickCheck(CharSequence s, int src, int limit, } } - if(isMaybeOrNonZeroCC(norm16)) { - int cc=getCCFromYesOrMaybe(norm16); + if (norm16 >= minMaybeNo) { + int fcd16 = getFCD16FromMaybeOrNonZeroCC(norm16); + int cc = (fcd16 >> 8) & 0xff; if (onlyContiguous /* FCC */ && cc != 0 && getTrailCCFromCompYesAndZeroCC(prevNorm16) > cc) { // The [prevBoundary..prevSrc[ character @@ -1054,11 +1080,12 @@ public int composeQuickCheck(CharSequence s, int src, int limit, if (src == limit) { return (src<<1) | qcResult; // "yes" or "maybe" } - int prevCC = cc; + int prevCC = fcd16 & 0xff; c = Character.codePointAt(s, src); norm16 = getNorm16(c); - if (isMaybeOrNonZeroCC(norm16)) { - cc = getCCFromYesOrMaybe(norm16); + if (norm16 >= minMaybeNo) { + fcd16 = getFCD16FromMaybeOrNonZeroCC(norm16); + cc = (fcd16 >> 8) & 0xff; if (!(prevCC <= cc || cc == 0)) { break; } @@ -1244,7 +1271,7 @@ public boolean norm16HasDecompBoundaryBefore(int norm16) { return norm16 <= MIN_NORMAL_MAYBE_YES || norm16 == JAMO_VT; } // c decomposes, get everything from the variable-length extra data - int mapping=norm16>>OFFSET_SHIFT; + int mapping=getDataForYesOrNo(norm16); int firstUnit=extraData.charAt(mapping); // true if leadCC==0 (hasFCDBoundaryBefore()) return (firstUnit&MAPPING_HAS_CCC_LCCC_WORD)==0 || (extraData.charAt(mapping-1)&0xff00)==0; @@ -1263,14 +1290,15 @@ public boolean norm16HasDecompBoundaryAfter(int norm16) { return true; } if (norm16 >= limitNoNo) { - if (isMaybeOrNonZeroCC(norm16)) { + if (isMaybeYesOrNonZeroCC(norm16)) { return norm16 <= MIN_NORMAL_MAYBE_YES || norm16 == JAMO_VT; + } else if (norm16 < minMaybeNo) { + // Maps to an isCompYesAndZeroCC. + return (norm16 & DELTA_TCCC_MASK) <= DELTA_TCCC_1; } - // Maps to an isCompYesAndZeroCC. - return (norm16 & DELTA_TCCC_MASK) <= DELTA_TCCC_1; } // c decomposes, get everything from the variable-length extra data - int mapping=norm16>>OFFSET_SHIFT; + int mapping=getData(norm16); int firstUnit=extraData.charAt(mapping); // decomp after-boundary: same as hasFCDBoundaryAfter(), // fcd16<=1 || trailCC==0 @@ -1293,8 +1321,8 @@ public boolean hasCompBoundaryAfter(int c, boolean onlyContiguous) { return norm16HasCompBoundaryAfter(getNorm16(c), onlyContiguous); } - private boolean isMaybe(int norm16) { return minMaybeYes<=norm16 && norm16<=JAMO_VT; } - private boolean isMaybeOrNonZeroCC(int norm16) { return norm16>=minMaybeYes; } + private boolean isMaybe(int norm16) { return minMaybeNo<=norm16 && norm16<=JAMO_VT; } + private boolean isMaybeYesOrNonZeroCC(int norm16) { return norm16>=minMaybeYes; } private static boolean isInert(int norm16) { return norm16==INERT; } private static boolean isJamoVT(int norm16) { return norm16==JAMO_VT; } private int hangulLVT() { return minYesNoMappingsOnly|HAS_COMP_BOUNDARY_AFTER; } @@ -1307,7 +1335,7 @@ private boolean isHangulLVT(int norm16) { // return norm16>=MIN_YES_YES_WITH_CC || norm16<minNoNo; // } // UBool isCompYesOrMaybe(uint16_t norm16) const { - // return norm16<minNoNo || minMaybeYes<=norm16; + // return norm16<minNoNo || minMaybeNo<=norm16; // } // private boolean hasZeroCCFromDecompYes(int norm16) { // return norm16<=MIN_NORMAL_MAYBE_YES || norm16==JAMO_VT; @@ -1320,12 +1348,14 @@ private boolean isDecompYesAndZeroCC(int norm16) { /** * A little faster and simpler than isDecompYesAndZeroCC() but does not include * the MaybeYes which combine-forward and have ccc=0. - * (Standard Unicode 10 normalization does not have such characters.) */ private boolean isMostDecompYesAndZeroCC(int norm16) { return norm16<minYesNo || norm16==MIN_NORMAL_MAYBE_YES || norm16==JAMO_VT; } - private boolean isDecompNoAlgorithmic(int norm16) { return norm16>=limitNoNo; } + /** Since formatVersion 5: same as isAlgorithmicNoNo() */ + private boolean isDecompNoAlgorithmic(int norm16) { + return limitNoNo<=norm16 && norm16<minMaybeNo; + } // For use with isCompYes(). // Perhaps the compiler can combine the two tests for MIN_YES_YES_WITH_CC. @@ -1333,7 +1363,7 @@ private boolean isMostDecompYesAndZeroCC(int norm16) { // return norm16>=MIN_YES_YES_WITH_CC ? getCCFromNormalYesOrMaybe(norm16) : 0; // } private int getCCFromNoNo(int norm16) { - int mapping=norm16>>OFFSET_SHIFT; + int mapping=getDataForYesOrNo(norm16); if((extraData.charAt(mapping)&MAPPING_HAS_CCC_LCCC_WORD)!=0) { return extraData.charAt(mapping-1)&0xff; } else { @@ -1345,7 +1375,7 @@ int getTrailCCFromCompYesAndZeroCC(int norm16) { return 0; // yesYes and Hangul LV have ccc=tccc=0 } else { // For Hangul LVT we harmlessly fetch a firstUnit with tccc=0 here. - return extraData.charAt(norm16>>OFFSET_SHIFT)>>8; // tccc from yesNo + return extraData.charAt(getDataForYesOrNo(norm16))>>8; // tccc from yesNo } } @@ -1354,23 +1384,28 @@ private int mapAlgorithmic(int c, int norm16) { return c+(norm16>>DELTA_SHIFT)-centerNoNoDelta; } - // Requires minYesNo<norm16<limitNoNo. - // private int getMapping(int norm16) { return extraData+(norm16>>OFFSET_SHIFT); } + private int getDataForYesOrNo(int norm16) { + return norm16>>OFFSET_SHIFT; + } + private int getDataForMaybe(int norm16) { + return (norm16-minMaybeNo+limitNoNo)>>OFFSET_SHIFT; + } + private int getData(int norm16) { + if(norm16>=minMaybeNo) { + norm16=norm16-minMaybeNo+limitNoNo; + } + return norm16>>OFFSET_SHIFT; + } /** - * @return index into maybeYesCompositions, or -1 + * @return index into extraData, or -1 */ private int getCompositionsListForDecompYes(int norm16) { if(norm16<JAMO_L || MIN_NORMAL_MAYBE_YES<=norm16) { return -1; } else { - if((norm16-=minMaybeYes)<0) { - // norm16<minMaybeYes: index into extraData which is a substring at - // maybeYesCompositions[MIN_NORMAL_MAYBE_YES-minMaybeYes] - // same as (MIN_NORMAL_MAYBE_YES-minMaybeYes)+norm16 - norm16+=MIN_NORMAL_MAYBE_YES; // for yesYes; if Jamo L: harmless empty list - } - return norm16>>OFFSET_SHIFT; + // if yesYes: if Jamo L: harmless empty list + return getData(norm16); } } /** @@ -1378,8 +1413,8 @@ private int getCompositionsListForDecompYes(int norm16) { */ private int getCompositionsListForComposite(int norm16) { // A composite has both mapping & compositions list. - int list=((MIN_NORMAL_MAYBE_YES-minMaybeYes)+norm16)>>OFFSET_SHIFT; - int firstUnit=maybeYesCompositions.charAt(list); + int list=getData(norm16); + int firstUnit=extraData.charAt(list); return list+ // mapping in maybeYesCompositions 1+ // +1 to skip the first unit with the mapping length (firstUnit&MAPPING_LENGTH_MASK); // + mapping length @@ -1414,13 +1449,14 @@ private int decomposeShort( private void decompose(int c, int norm16, ReorderingBuffer buffer) { // get the decomposition and the lead and trail cc's if (norm16 >= limitNoNo) { - if (isMaybeOrNonZeroCC(norm16)) { - buffer.append(c, getCCFromYesOrMaybe(norm16)); + if (isMaybeYesOrNonZeroCC(norm16)) { + buffer.append(c, getCCFromYesOrMaybeYes(norm16)); return; + } else if (norm16 < minMaybeNo) { + // Maps to an isCompYesAndZeroCC. + c=mapAlgorithmic(c, norm16); + norm16 = getRawNorm16(c); } - // Maps to an isCompYesAndZeroCC. - c=mapAlgorithmic(c, norm16); - norm16=getRawNorm16(c); } if (norm16 < minYesNo) { // c does not decompose @@ -1430,7 +1466,7 @@ private void decompose(int c, int norm16, ReorderingBuffer buffer) { Hangul.decompose(c, buffer); } else { // c decomposes, get everything from the variable-length extra data - int mapping=norm16>>OFFSET_SHIFT; + int mapping=getData(norm16); int firstUnit=extraData.charAt(mapping); int length=firstUnit&MAPPING_LENGTH_MASK; int leadCC, trailCC; @@ -1469,20 +1505,20 @@ private void decompose(int c, int norm16, ReorderingBuffer buffer) { * <p>See normalizer2impl.h for a more detailed description * of the compositions list format. */ - private static int combine(String compositions, int list, int trail) { + private int combine(int list, int trail) { int key1, firstUnit; if(trail<COMP_1_TRAIL_LIMIT) { // trail character is 0..33FF // result entry may have 2 or 3 units key1=(trail<<1); - while(key1>(firstUnit=compositions.charAt(list))) { + while(key1>(firstUnit=extraData.charAt(list))) { list+=2+(firstUnit&COMP_1_TRIPLE); } if(key1==(firstUnit&COMP_1_TRAIL_MASK)) { if((firstUnit&COMP_1_TRIPLE)!=0) { - return (compositions.charAt(list+1)<<16)|compositions.charAt(list+2); + return (extraData.charAt(list+1)<<16)|extraData.charAt(list+2); } else { - return compositions.charAt(list+1); + return extraData.charAt(list+1); } } } else { @@ -1492,17 +1528,17 @@ private static int combine(String compositions, int list, int trail) { int key2=(trail<<COMP_2_TRAIL_SHIFT)&0xffff; int secondUnit; for(;;) { - if(key1>(firstUnit=compositions.charAt(list))) { + if(key1>(firstUnit=extraData.charAt(list))) { list+=2+(firstUnit&COMP_1_TRIPLE); } else if(key1==(firstUnit&COMP_1_TRAIL_MASK)) { - if(key2>(secondUnit=compositions.charAt(list+1))) { + if(key2>(secondUnit=extraData.charAt(list+1))) { if((firstUnit&COMP_1_LAST_TUPLE)!=0) { break; } else { list+=3; } } else if(key2==(secondUnit&COMP_2_TRAIL_MASK)) { - return ((secondUnit&~COMP_2_TRAIL_MASK)<<16)|compositions.charAt(list+2); + return ((secondUnit&~COMP_2_TRAIL_MASK)<<16)|extraData.charAt(list+2); } else { break; } @@ -1550,7 +1586,7 @@ private void recompose(ReorderingBuffer buffer, int recomposeStartIndex, c=sb.codePointAt(p); p+=Character.charCount(c); norm16=getNorm16(c); - cc=getCCFromYesOrMaybe(norm16); + cc=getCCFromYesOrMaybeYes(norm16); if( // this character combines backward and isMaybe(norm16) && // we have seen a starter that combines forward and @@ -1591,7 +1627,7 @@ private void recompose(ReorderingBuffer buffer, int recomposeStartIndex, } compositionsList=-1; continue; - } else if((compositeAndFwd=combine(maybeYesCompositions, compositionsList, c))>=0) { + } else if((compositeAndFwd=combine(compositionsList, c))>=0) { // The starter and the combining mark (c) do combine. int composite=compositeAndFwd>>1; @@ -1696,7 +1732,8 @@ private boolean hasCompBoundaryAfter(CharSequence s, int start, int p, boolean o /** For FCC: Given norm16 HAS_COMP_BOUNDARY_AFTER, does it have tccc<=1? */ private boolean isTrailCC01ForCompBoundaryAfter(int norm16) { return isInert(norm16) || (isDecompNoAlgorithmic(norm16) ? - (norm16 & DELTA_TCCC_MASK) <= DELTA_TCCC_1 : extraData.charAt(norm16 >> OFFSET_SHIFT) <= 0x1ff); + (norm16 & DELTA_TCCC_MASK) <= DELTA_TCCC_1 : + extraData.charAt(getDataForYesOrNo(norm16)) <= 0x1ff); } private int findPreviousCompBoundary(CharSequence s, int p, boolean onlyContiguous) { @@ -2184,10 +2221,11 @@ private int getPreviousTrailCC(CharSequence s, int start, int p) { private int minNoNoEmpty; private int limitNoNo; private int centerNoNoDelta; + private int minMaybeNo; + private int minMaybeNoCombinesFwd; private int minMaybeYes; private CodePointTrie.Fast16 normTrie; - private String maybeYesCompositions; - private String extraData; // mappings and/or compositions for yesYes, yesNo & noNo characters + private String extraData; // mappings and/or compositions private byte[] smallFCD; // [0x100] one bit per 32 BMP code points, set if any FCD!=0 } diff --git a/src/java.base/share/classes/jdk/internal/icu/impl/UCharacterProperty.java b/src/java.base/share/classes/jdk/internal/icu/impl/UCharacterProperty.java index 474b169e6e2..f439ae23d0f 100644 --- a/src/java.base/share/classes/jdk/internal/icu/impl/UCharacterProperty.java +++ b/src/java.base/share/classes/jdk/internal/icu/impl/UCharacterProperty.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -40,6 +40,7 @@ import jdk.internal.icu.lang.UCharacter.NumericType; import jdk.internal.icu.text.UTF16; import jdk.internal.icu.text.UnicodeSet; +import jdk.internal.icu.util.CodePointTrie; import jdk.internal.icu.util.VersionInfo; /** @@ -136,10 +137,8 @@ public int getAdditional(int codepoint, int column) { */ public VersionInfo getAge(int codepoint) { - int version = getAdditional(codepoint, 0) >> AGE_SHIFT_; - return VersionInfo.getInstance( - (version >> FIRST_NIBBLE_SHIFT_) & LAST_NIBBLE_MASK_, - version & LAST_NIBBLE_MASK_, 0, 0); + int version = getAdditional(codepoint, 0) >>> AGE_SHIFT_; + return VersionInfo.getInstance(version >> 2, version & 3, 0, 0); } // int-value and enumerated properties --------------------------------- *** @@ -150,7 +149,11 @@ public int getType(int c) { /* * Map some of the Grapheme Cluster Break values to Hangul Syllable Types. - * Hangul_Syllable_Type is fully redundant with a subset of Grapheme_Cluster_Break. + * Hangul_Syllable_Type used to be fully redundant with a subset of Grapheme_Cluster_Break. + * + * Starting with Unicode 16, this is no longer true for HST=V vs. GCB=V in some cases: + * Some Kirat Rai vowels are given GCB=V for proper grapheme clustering, but + * they are of course not related to Hangul syllables. */ private static final int /* UHangulSyllableType */ gcbToHst[]={ HangulSyllableType.NOT_APPLICABLE, /* U_GCB_OTHER */ @@ -310,11 +313,16 @@ public int digit(int c) { * 0 */ int m_maxJTGValue_; + /** maximum values for other code values */ + int m_maxValuesOther_; + /** * Script_Extensions data */ public char[] m_scriptExtensions_; + CodePointTrie m_blockTrie_; + // private variables ------------------------------------------------- /** @@ -534,12 +542,13 @@ private UCharacterProperty() throws IOException int additionalVectorsOffset = bytes.getInt(); m_additionalColumnsCount_ = bytes.getInt(); int scriptExtensionsOffset = bytes.getInt(); - int reservedOffset7 = bytes.getInt(); - /* reservedOffset8 = */ bytes.getInt(); + int blockTrieOffset = bytes.getInt(); + int reservedOffset8 = bytes.getInt(); /* dataTopOffset = */ bytes.getInt(); m_maxBlockScriptValue_ = bytes.getInt(); m_maxJTGValue_ = bytes.getInt(); - ICUBinary.skipBytes(bytes, (16 - 12) << 2); + m_maxValuesOther_ = bytes.getInt(); + ICUBinary.skipBytes(bytes, (16 - 13) << 2); // read the main properties trie m_trie_ = Trie2_16.createFromSerialized(bytes); @@ -574,19 +583,29 @@ private UCharacterProperty() throws IOException } // Script_Extensions - int numChars = (reservedOffset7 - scriptExtensionsOffset) * 2; + int numChars = (blockTrieOffset - scriptExtensionsOffset) * 2; if(numChars > 0) { m_scriptExtensions_ = new char[numChars]; for(int i = 0; i < numChars; ++i) { m_scriptExtensions_[i] = bytes.getChar(); } } + + // Read the blockTrie. + int partLength = (reservedOffset8 - blockTrieOffset) * 4; + int triePosition = bytes.position(); + m_blockTrie_ = CodePointTrie.fromBinary(null, CodePointTrie.ValueWidth.BITS_16, bytes); + trieLength = bytes.position() - triePosition; + if (trieLength > partLength) { + throw new IOException("uprops.icu: not enough bytes for blockTrie"); + } + ICUBinary.skipBytes(bytes, partLength - trieLength); // skip padding after trie bytes } private static final class IsAcceptable implements ICUBinary.Authenticate { // @Override when we switch to Java 6 public boolean isDataVersionAcceptable(byte version[]) { - return version[0] == 7; + return version[0] == 9; } } diff --git a/src/java.base/share/classes/jdk/internal/icu/impl/data/icudt74b/nfc.nrm b/src/java.base/share/classes/jdk/internal/icu/impl/data/icudt74b/nfc.nrm deleted file mode 100644 index 9228eebbd170eed49290c974311d494f4ea22ec0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 35392 zcmeIb2Yi!N_XqwwdD1lL-c6gd>7Z@e>^4c0v}G44dzHNk6exR@jWR1k6p$?-sPKZa z1p%3|QA9-0f*s&MP*g-5D763YJ!#T{;EUsZ-~a#f|M7gzx#xcGx#ygF?tShvk`ylH zauOH9aXcsDT8<o&D&{!Op9ib{*P7#+@8P)FF&sDN5yTzlI04#TpK@IC6^_g7$8q;i z51Pes87omYJ29riaqUMIq;Z_&p32A_6D9Ib0jkSQ<o0pD@eY0hzk|OmN))vREfQT2 zf`xX%3&MG^zqlokMDZ-~De*5JMp2^2aF3Tf%256wF-dw#o{=1o-1l^NcJW;9Su72e znx!K=yGUP?7R$n=W?38A0NDoFAz6he(aY@B-s^d<7rj36s_@S6p6I>H`<y7z#~akl zXQ0m-pHk+>dH8ZJ=~1PxmZ83R#Gi(=(W&M8g`bCCw%-iDLw=S1Y5qN>c82@E;B58( zFd#UfUBC+g9|i^owhMeA@WY^B))LepXf*h%K_3T)1h)%*A^3Fg&(0oyjfccN*w5!% zQDR6P5F&l>2sspTH#9wT?1Sk4)&4I7|CfRPcV-~;&CokxA+FfMXlD!?6Sg7jBWYIH z4Tgu^4X0fP=X;y*@!?a$XNNBcpBz3jeBS@n{?SYv7bVI)<aJ$h@&D&iK1F^wf{Umd zF(u+~Bo|pXvQOkIkIF~n(Fak<Q<CQ->m|n}m+8PY{qG#?O8)r6qt(N0VxNbR$e$RZ zkUWgDy6+QRlNDi)>g&Y9JY8*)K`u!V<BUsz`<j}ERLN=ztS&`sMR!Gkt4)k^Uol!S z!&#RGx^TrJr=)nvh14t+>s>X)cEw>?lH#m5$c4B{MTzHWmkb{_6~9&29+qUDN<m5Y zE}}%)*AKQTqiWWr;WcXy%F4(G>krqIy6W*&w@IIJ%F<}5!i7pBT+)-24@dm_K0Y2U ztlEbQd0goueO!wZS7td&f4X=4W8FV$RkrwjtMYei`}aE4h_Z)rsB)5WwkT1#Sow<b z4Ofe=JD)D($x7u><-5vD)w<%l)pE7;_;I_|o%mk0_Twbw=Z|Zt#+7%fWl>_(WA5am z0-|D~j8S!?T1WMY8Xh$zYJSw3sBKY)qs~QLiMkcdMF&L3L>r^)Mz@ac6+Jw9O7#5b zHPPFm4@aMiz7l;)#i;^RF*W`CSy?O<tGQ$B5H}Hb6b}*47Oxi{5tobac_=(=9&Md% zPr^O=bH_X;K8fbzbUa>sxW!|=$I+UY$7ddQCEnaINpwy0ugH?xk{)>A{NEg6PRjX^ z?*Ohf*Nq#_&En2*=eV1^lyAs4;k)sp`6>LX{O26c-xT?X)S`x>`J!c_ZK6G*lA1A# z?g(a~uFzf>ENl~Y3g?7dVzt;PZYb_19w2^Je1_x27sPiw0z8Z!lRRd4tnt|3ajs_n ze?s=S{^zU&%?X<C^?A?|uV1~z9(TO`f>s8->@5%45VR#|XV6>TdX5h|9CRY+jJM6Z zrFSom_qZ2yKBzdT%zI!E@`2W`f^K<F3Hr%<iT4@_=lxpHy<m~|&R}V<AD&wyz2D*Z z;F#dVV6FEB@2|Y?alAwtoEmHkuI(cUZiu#~!L5Tk_$Yl+gS!X!2_6tUG<bCIgy1Q` zMZwPoFAQE5yqfv&Y2wo%_|@Rog0}^~8GIo4Xz;1vv%wdFF9%-<z7~8l_;&E!;K~qj zh!@ih2?z-bQHI2Ys6+H2mXM5)y3TxrG!AJI(k`SkG<t;e4H*<NB4kX+q^h=QA+tiB z4_O?tB4mvd@#*U`GGu+orjQ*Wd&ug+kYge5hI|n6QAml;6rVXEpN3oy`7Y!~pG7{a zLw*b8LnWcKf_ygk?C{y|b0Rb-R2~`~S}Qaq)QD&4tkC+QO+s6Swh!$R+AFkQ=-|+i zq2ofIk~ml0-&plN=X}0$M*Jx5EB1}9iAw@%)*h5YXN1lPogca+bY<wvp<C;F;oZ z=sTeoLd!z0hu#jw%!Nt90>UE0YK7^-(pcXxTUhO|hG9*8ZNBxx+J$uw%MTkAHo|EY zPal-quxVkl!sdsq2zw=LW7yWPU14v99S%DYb|&n6SaDcc*ymwih20AKDePXjC|nxu z7akHG86Fd!7_JRZ4Y!5Y4sRIVG`w|qhwyI9YIyJP0X1XxZSLE_x0mn0@ZsST!e@j( z=R4Z>sqkgtFNePtzOAO-|3a38{O7#hKjS(o-I5cjJi`zdK{{8tr|LL&f16w0Q@N;e z(fvJD$D;d-TrCW#B%C1?BIj{W<Z5U3E6-$FGc)g>$*iB*<o*@ZogS!#$sF(0s?o<8 z#hJ?Ul^1ZhxU<J2xGQtXS6xzdnfyhy9KJjJK=O_7qv5B+-^c2>2>K-aYWNL_+^Him zW4FN`Bk5G#M=~1q8CC7Gs>(It--rL~J1hLY??SmC_m=Fe!Y@D<dz=Jo-*tE@Io?z2 zta-vdJ3QO_uJqj^50*#x9<D+L%T@9Or~FTIxkhf{czHT`9xcyu*_Stv=g3<jnsL-J z1=0-9`JT%>SIToeH#xOD-RFg8)fhdGRkfUg{u$~?S0vA3)Jr_Cd*1TABkw8|JGG?J zs<LX|k|G=Ikj8*&F-e{$?+-qNP_=xNvmMBI`P1^5uG+sZrCO;`K3BfrVa=+wg;n!# z%YV8qUn*bqcpvgt<QwH%<-3@Me4qSnyl=M2Ps-nue<;5sFPGD*m47Y&UjDQEeuNMq zlV(cmM)*gBMkpd;Ba$L?5or<jh&mD35zQjnFdGpaBf3A{o2v!qnCtv;N&9PHtj&3L zR-dCzz5SJ^D$i7eRD@N?D<UhD710$j6>$}{DiU$1D^e=79AAMee}%CkmColqkZFEh zp8p%Adu&x>tjMgWT~YTz&k?;N21E>tD2$jWZTMizzpqJKW7W2=uvXYA98TL6^(z|E zPRjD-$}GzvW%A!ytZ4Md8WB^aog$w3V;yO?h<S*rR}Js*&HA_zMB}OheZtsSkBTOL z?E8;f;lIk4GaIO}x{FhWs&t%qRos7U^`B~`m{<(X0}=e*GP^cC`QfrvBl9lnu<dMh zm8|yUmR*{ZyFV3^tLLLi#87>f|D|{ywCWna+wOzsggX~5z3R0{h;yw}#pFE4sx+M~ z4_JH9^WU#Y`$oJ_(~5LJ#B!WfgCkz5iE{iszX$6zYZXDx8jatb&*YoQx08QKu1FE5 zc%=lSgw^cv-;^s5IX+Q+U_DERJL?haB3^ezUsI!6KSh}m$MGrZnyr6U{wpi~&-!5c zDYy=SSKVtdnT`E%$D_tg{T(TFQ)quqY5usr|7rZM#Qo34BpnyAomq_79dY3InYzb5 zqp!+rO52o9F8S}2(i!k}^zT@Bbl>VoS-W(WbUrI1PDi{Saq;&f`~A7{Xsdq)l`ew6 zPh347_F1vv-kYwr|90tIXVPU6SF6V@T^aFZ#5Wx8`%c7<ID@M8HdkadXWoVVcgl(& z7Ry7kxk0*(d5^dsDMZR1j+M1MsQ*tyde5DaN7<I{jPytDE<}b$svgz;Pekx|8x?19 zxZ`u_Rea<;T=oA}S#cA`@1wa>LC1e93U;sa*L=|%3iPd{HRiIB($ghXmnr!!Ic1Pr z8sV14x}=B8l*tbwm7+><X6s66W~Y>CxRT9+Z?W@WdT67&eU?*phxA}yS1sjvmsDM* zEOyB$FS@0*Zs}hx>ESYEb4}#0=CP)YKPyWQM?Um+<o9P4+r^x_!{e;~mm(M8YjFSm zz)b#UjtcHckAK?#llpb({nP%R+@ABv;>q<Nt@+2R?a_T|qQBo2Yqq-NM{7Oqym$5b zD`n-WztZdP^{L#?o|pcdjX&Sx-`Rh3jvv*_xpJyG)A_UUKg#YOW7Ynup4qFP+}V}s z5l_ff*ki8`f9&tiwMvggYNV$kP0}-w>C$tNS<(xU4VVRKab(V)v-BwK3cu>TURn~_ zN_r(SSNgg1dSutgJn7BI{!c!4kFx$S#@1GiZ2yPy_jh-WhogSnlj4*3agG+(&gxHX zs@D^}bzyBa5101`*S%{;V)k4btR(vn<+Lit7b-VFTJ&JP|5oiB-cz4~&7H7vp1kad z92_|^a$Mw7kuxLbMlOh48u?P>#>j1vZ$|EqJQ8^-@@(YA$WJ1#L|%*hHu4vRNa3Rh zQA8?Y6p0Fh!mg;NXsl?iXshU?=%MJV7^oPo7^9f1n68+mcuuiMu|n~(Vv}O0;w{Bt z#R<h3#d+T{-|LFYiqG-Ar`w8O6ctLb(n}ej3{yra<CSWqUTIc3ly#Mjl+BfGm0gs5 z@eP`B%4y1Hl}nUslpB>>mAjPtl!uikd~f^SQ=U~8E3YW8DQ_xo`$_x)l)pxaqx_=e zQE^e)D07qp-#KX%)jX<gRHvvOQGKHZ;@c-<q9#R6i<%R)C~9@o27C+U&8P!WN25+f zosGH>bs67BxfXRZ>UPxKsLE)MXz%F2=<sM|bX>GLS|4qR&WNrT-8i~=bld1o(fDRX zwEJGxFVasPJrLhr85cb*`q}6u`2Nak(L19LMxTm4A6*iCE&5jUuPU+1PbF8yskADq zpVhCfs<x`3s;R2As*|d>YOrdIYKm%(YLRNSYJ+Nr>Mhk_)d|%ZzovfeRp(X3sw=9m zRCiPrG18cz7-dXij4{R$(=euGOsAOMF@s~q#7v2q6SF90b<FyhO))!S_QV{Hc_-#V zOj*qJnA<V;VkNNwv5~QHvFcbutR>bFTQ{~*>;rFX{CfC}_IuWEh2I9hH~o(Jo%bvA zyW{WUAL+05xB55qZ|mQ~e{gJWY|q$&So-wIe}ez4*vYZa#4d=XyJY_*{+s-d`JeZ{ z;{UDxy#TL(umEj9!+^E{y#j^?ObVD2uq0qZ?7G;kv3p~W#=aN(all&vXJW6$ejWQ` zY-OA*E;yhp;AUJ@TvD7VE`yy90lx-H<Feyg#dVJB!|H)yf$F#+abx4A#?6ge9EUfK zfewz3+X#9CbRe*KVDG>QfwKaa1il)$Bk*wGnZQp2e+`lbg$30LN)4(T)I4K#-0_U{ zK^-!-#J!vGX50rE2jf1@I1$t<<1DiuR~C0Y?&o;V`0)6o`1JV3@onR~#Se;~7(X}u z#rW6b_r;%xKNnvf|6P1#E&p1oT83JVS`BNptJSC0s9Mu&y-@3wT3c%Esdci}$F;t! z^>cz}LU=-4f;J%|p;<!Lgh2@t6Xqr?PIxilm4w$45N*)FgaZl36W&euAmgKikMQiW zLwbwj6G{`lNVu7R_Xt6w6DkuuGs+TuGp;2DB}OEw5)%?NiKaw*2J|>Sv0h?MVw=Q{ ziQO}PMXgU_LE^B)!o-P*(=)}1a}yUNE=_zX@n4CX6W_@6OWd1yC^IZ&H}yN2csB84 z*ncYVYT}K|=)~_b6BF;G?33b?*k5J8%9zgo>R|gB+dW<TnsX;*HCIF~sY(lbB}vX} zJZdhzf1*q|=(Lh@B$M8gK8a14l;dSSpnz)a#NU#hD5FW9)qNf(CHW==Cq>9Y;6V<m z`i%H-+J6<7#U!bmePy+h@H8n?Cu#nSEtxjSBr_(_=jcz?PgeB~Itib-%WO#vWSJbF zlq0K~giqbsA$y`vAd_-sO_I7oySc3OgMO3plKLkNNg9<jUe;dLDe38?nX+!OUP*J4 z7RdVI_ez6h!<l~4(xg?g(Xw$#uOw}hO_EJX+L}b4I#=70&5+?8!yg^8XRBLf^JRFG zDO;AbFX`>1lS%Kf7THSK8riF|4b@tIO-lMO=~7a8(ib&*Cw-mtebUcK_iJMRjGS^Z z<=ww(DdqjY+Vh|3_xJC5UHj2rE&rKuJZJ^?ZKv=Zr2UnLD-S=|^81=>lM9n=Qwy@4 zYME@0+F!O`9V$DlR>+R2V`Zn*NwPC)o$Q=CO?E+Tmldn)$V$}NSg%*q&19de+sLk~ zJG!g@y{Yc5?jyUSE>I7X-BTB;Cwht1Q`OIS`KafqANYK*y3g+=H9k3X9`^$7(T?dA zqJHReL@(@f&cjQoUgs5~e%-5<db^iez1vHxKHz0kAN4Y;PkY(a?|WscFM8Egf8y0p zebuXp`b&=YYOemqtF`(EulDM@E-OGgsVkE`ym}>jCkJ{BNDfbq@*18TpPcM9F4>T5 zsn&a(<Tb@>hSw}Foaf1Omy%pBxp8uf<aSKoYko4m1^J&ms;_a6T8)3lbIt4Q-?8&Y zegB=0zkjY)d;hDp9+lUJv1%{>q=ct198YHPua54?tp9s0whk#P6z_xc>a10-)PHa7 z?`b?L7hazR&HgLL|5y6`)r{fy;(TVm>f=f5FzqMNW0qZdF3IW1h5j$fjHP(Gx|nh) zr8MPg$`>g&Qoc#~9><R<cT?_bc#Vffrt#GTYC<&;nkY@ICP9;|(P>N?i^i_W($v#r zYjQL#G;K7wn$DW;nmkRura&`9GeT3S8LyeFnW~wonXQ?pS)f_0S*}^7S*uy6*{Ip9 z*{<28*{eCAd0TT_b6WGB<^#<|%_U8#=Bnlk%?-^rn(s9~YVK<8Yk94QR;KmU25LjK z5!xtitTsWLtkr2vT8q}M&C<kb>uIyKIocN5HriZmXKi<Fo;F`wpdF$ep)J&o*G|?> z)y~w;*3Q!|&@R?4*RIm8)vnWS)Na;p*Y48p)gI8ktv#+it$k1Xf%c;IlD1TPRr`hZ zhV~on_u3z|ceVF*yv{=>)A{NGb)mWlU6d|Xm!M15>2xNYMQ7J#>FVjSbve2g+S$4` zx?EjnU3XocE?-xm8=}q8jnEb9#_J~Qrs`(uX6xqZ7U&l1mg`pO*6P;jHtII(w(EB3 z_UaC3Vs&rpj_XeA-qU@cyQsUQE7e`qeWAOd`$qS@?nm8S-F-c;_t4AqzWP9Ys6Ij; zrH|Do=##Z=^g6vsZ_(TJS^9eVY<-Ttg}#kGSKnFRU7x4V*B9uA=tt-a_2c!E^;7jT z^|ST!^b7Qh^~?3E^lSC&^c(e?_1pEk^n3LO^l$5r>rd<7(|@49sK2By)nC<rp}(R3 zM*lrqlX^UH>**drf8W3xJPa~}uOZM7YKSmI8Dcr!fTtisGSf8Z3?}C)HdqXHLzbbQ zA={8+Xkln$$Tf5}bT{M~@(l%sA%+o#Lc@5&WW!X$Ov7x$Ji`LRV#9L7D#KdCI>Sc8 zX2W*FF2i2K0mIvd<A&3Q_Y5BxE*dTwN)1;HU+5AHHw@nxzBl}6xNEp?xNqc*9!8nb z*BEFFHAWbt3_4@1F~OK@)EP}iddf0p80#1t7#ka#8Cx0K89N&Cja`jBjeYb#8v7du z8HX818OItY8lN^!H$G#WYkc1Lf?>9CsbQY+MdM4xSB(EMzOKKkDKu_1zG2+0ou|8D z+-E#w*l0Xz*lav$eAoECfj53={Mh)3vE2BX!Nd5a@oVFE#vhD78-Fu=VXQO>x&)J_ z;YX9V$=?)g3O6Z?GLy=XY>GGfYU`PjjDaSNF~VdprJ2%A8KyeMSVM%Vfic0<*qCf; zmh!!+l_}TM)s$z-Hx-zMm`0h#o1QjJ|0nkfQ&EN4RO894+O}z-X_;w_={3_1(;m}7 z(=pRKrgNr`OeLmIIo@>L^sVWR>DN?zcPCW>@=3)f$*J;G{PH8UR%%MBG1Z!ynOZ-! zNovc~_SH83Q_@3sA+EO`&a%c^lE?XH_ZGjuDzkSe)ps4$*HV|ahpo|F3cTT9@2cJR zEUx;)`mA1U^+{X37A5!eT9I5(t?#v_T23BSExV+OpohP6Sp8`T(@CD3jBf~gt@qmW z_;>w}inHb?2I%>SZ^%{nJ*pq`i5BQT7zbk5;fy(XLGp_a_N1&jbL*Z@m&T(!KWrJc z58mUF*ClTS-%AlZGGeEHuXA1>B_B<u_Y!Q59_7KQ>Ew^nsE)v^glQ#z?CRmnvhy7t z<1YNcvcjjr=RxGb+T;2;wNksJ_Dvm^IzM$o>fzMl%59a~oc^4xmB$$J;I~m&i*wB~ zPBnMFU5K-HHFwQQHBwVby_R|_O`N7oGp9ALiT_@9*>RRt_s`Ydt7g1f%c)UQ@Ao#H z2;Ky+UjkK~jjr+iUc1^h&iWcFIjw72&$K>i{nLgRTBMCgD@+@oHrdc7ZED)gwAqH- zwCB@aNL!lrV%plYb!i*ZHmALjwmWTK+96||w4-UK)80$_Anjt>rL@wtt7%^t+p(*l zv18hev~RSX)4n(4rTv(8H|@Ter^CbSZT2?@o5Rgf=2&xrIoYf;o6Huo-JE5vXU;a~ zm|K`z7<-!Am~+jY&D{+J<~(!0xj=uwJj6W0TxcF|o@}0Ko@t(Ko@ai+ywv=n`6cr! z=6{)AH*YuZHt#bZG9NXcG{0+p-~6HZV;rBDubRKm=9q7ozcK${{@MJSxzZw7JPngA z-WGpLuqDD0Wr?>WSu_@dCC!p<$*|P1G_W+bG_$m_<XSpgx?A!zBP{urL6%`S3N7Pt zOtwt5JY$(>SzuXgS#DWnS!-Em*=X5p*>0F>*=5;hIb=C%eBN@@a?&u{@~-85%ZHYa z4f8Y}mQO6@md`9-TE4b?XZgW$*K*&=TRp5YtFJZK8g5lsRn~ZGl2v0hSknv(tm)Pa zYdveWHOJb*u-w|lnrrQB?QYGp=35J_L)f+2I>K6L9dDg%oo;=`I@kKVVU_g->vHQV z>snKub)9vib+dK5b(eLY^^o<b^`!MZ>j&10)=S!X)>7+L>zCGVtUp+Pw%$+Y(>>B< z>Ar@wx*O?%>7nTn=~3zN=}GCDbc69wdRlsVdRBV9^z8Iz>21<;jYrcvr*}`!OV3X) zNFS0uB7JQ7#Pq4@Gt=i9-%Wo${e|@9>8sM$rvEE_bNcr5UFmz%58!w^{kZYN^wa6@ zrGJoqG5u0{dHQGC-1Hmi-=+VMemA|+=3$c=zqa|>f^88tl`X-RY)dwNXDYDiY$lt< zX1CSR95DWDYhY_^c+b|t*3J-W>ul?8D7EF;@@)mSVK@qH<86~|({0b#=GvaOEw(MU zt+K7Pt+Q>kZMD5&+ilxtJ7ha*J865*_Mz=#TdD1;?MvI&h97O;*?zSBW~;P&*kyKq zd$2v+uCS}@@%ALU&YotsTMF%U><#RV?al11?CtCw?Op9X?S1V1?Sr(d>?7=j_VM<~ z_Nn%nM&3T#KF_|uzSzFp{*ry2{dN0R`y2M%_I>uZ?Z@r!+TXW-Xuo7Hw|}PDX#djw zwf#H$5B8t!znOyVl@7t->F{>=JAxhI4uwPIh<7AAbPkil;;=ii91R>fjuwtKrX-Wb zk?ZK}=;`R==<gWh80IK+OmsZ$nC^JSG0$XhEO0D!ta7Y%taEI1Y<0Zh*zMToIOI6$ zIO%xT@qy!_<C3G)@tNaG$JdVU96vbjIw~`S49^VjjKGXgQ)5%(3`K@2BOxO>LziL7 zuw>XXvNGzKnq@T3XqM3`qg_VFjIJ4Z8TlE5GDc*K&6t?+bjI|IXENqyJfHCbd%D67 zg?~lE8<v0$gUWETG({rfr%A;8Oo@aql1N3I#7E>I@e{X@1n{#ZL0JtYA^cp4Tv#EA z7ITs~u~^b5tDdB3CRfy2B$fDOqMj)&>YeE$5s7>xVo`v^PZT1Ni{wQu`RCEjWF>Uu zl9rh<k}jFGpsR%6`S80Ceiut5S>xb00e;o!tA*bs@H-m)%<w6NPapUkA!#XYBWW!% z!iKS^SEjkhFEdjj60XCiO(M;#i~gDDUl*~SDQYQd2)qgWH<ScqHkZi7nTVkYVrX5| zEwerRFN6OT@V`<b5w(W@_UPXU{d>XxOYlD*c2>iG0Q`r*|04MA2EUz(#G(NbQD!f+ zpM%Z5l9r;u7!xqjNW?q=*brc25a&4HqoF$qaZD*{lsQAf3AdnEgj~N2Y!>vNgZ{J7 zp9B3x(4UXkUPWx{5!*)Sy^h$HBes>8lkSLZGh$mQ2@|b>|CbS;9Pue7R-qnZTwc^# zxCnn6kef~LvjIM~!N)e}#XzqXeC>j-P4KfH?YoepJ<vG}oww0;T+&=@ENUs*59|W4 zQ^1OWnbGGM;=6)=C5Uea;@gS%-bC&`KztVwUom3ai`dRcLPRBq?+W5u55H>o)gr#0 zi0_o7N#^Is<L9t-6S=%Dk!1c-)F|_wgv;V2qAW4uxi0a`@{t5&NsAg~VJ&5a6a{3- z(f&DnzJ>OiSTDCEQgL6jDJ21-Tkv@ky4NwD+Y)hB4Ce4B#QrP%VXbAU5$|F2J%V_T zBcCS_uL$vaBA=}g^J(;Ngf;#y;$4Y&MTl2|z74R(MOfor$OY<|UKqO{eE1=TAovJ_ zk4UWX_tDPeXy`;@eZ^sHiO`LP-*fPL9)2$(<_Ykd1ivZhtB2o@;CBrAS>e+QKK<Zx z6xMh<<R=w2Qjs5PkzZzQtnshl(}6W!AN^~ie|^My7W32ycvJXqgf-q0YrHmMXo?ux zO1fosz}U5jp%^h-MhqpGtG0-t18j7G|8n?W2s>-wKM4NA;C~5x_kiCnusg6wE?mJ{ z>J6Rqu-gx7U?|2l5IJDy<|JUlfQ>_}6M&C_?o)_mT2Z6SBCPY<(3^#Pe+q04^yfqW zIp{wN{Uy*}h}hViUPEj*p!YRmdl9j%#=P`IeBU6x)mTR_!~d&@F%mIGV;wa>oG)UX ze++-GAwOH-=Qa4)0UtY{7YDsW_}UF$Tj1v)+IM3-Z$ak>bdI9!B-V6lQA^Q5U>{+v z>4Cok{4#JW`kg?GpQ10@A2AO84r2TX`TGztevB9|Bfh(c?=04O8DjhtF>ZkG6!_L7 z#yrIM4%YfL<ntPAeT$rag|+@`QKQTXtYs0_x&$$Og*EI4|6Y=iEMrllEUc@nFs%1T z=v;%}U!n6Y*3NCL_kL)LhTjVK{TBME(Ekc!Lu^@bSQEcs4ENv{YcDHB!qvGf5qWwQ z&8RaC>*tpusc@`FB;14iE94W9D~kNGteE2x5XM;t`;@1TL|SL0#HY@1Nn-6liMn=h z(VRNt(1yL*GXR*WNL@P(^+l)$q22~M?Vz&^*iK*}=)VK~w@Cs#+oOF1^hco$d!DBp z^#!QEP^7L?4D13hCG^ij{~Yu?pzRIdcYsGj_XF7e5Vn7jaJ8=j>kQrA(Cvjb9&LhT zMx7yO?}v7*BhN0tV__p6^&6;nN4*~O8bEIz^spvt-vr(Rc3y^^HSoC@I(g9PgFJ0Q zJBxD}u&J;!U6NSm6k>e`IE!fo`W->P!|1mZI&0DI74$oU_Pc0b1?+8LN8#@q_{02p zt}hDk+)xxC^^^F>))WQEUM<2UQ-VLWg8C-lB9zmB?*Z)x9x0K^j!Ar^si>cVt{mkV zU?sq?*U7FFg~>h#b{%vJRE+*Fqg)T&_2|C_^)0ZA@yTWYe+zUF_*<}X0yajX{tk4R zzq7!~fbEwA$UcSLYrwt&-3DETjV(pd(wm@fQQrxA6LbOek<WUchWHyFjh=nYr|GjB ze42ooKfA$q253EK%EEC$Z9%<31A-?7FL_~0@UpN;VN1d`h0R~GC2ZN!E#d0$N#To7 zE?YV&e95v+^7+eO!(T|75wSSpwTS1IZ;F^7IVp0{iY<}LR!oXqf^VhmRIFC)ees}T z|C(+w&EFho^#KKdLO^nm5>yK`1~dUQ1vCwWIj^%qBC4|z^RycBTafodK3Fuoff-~4 zbpx#ctp=^cJ&_a?1d@ZAfSQA*fo6f811$ty1|0)k0euR(4*Cjo3v|0^cs2(TfpCwN zeFOxX*<PRk5Nv0oZ}tgLCr}p<V#w|Rx&ZnJR1CU&H8oFtHMQ3=&`Qu6(5s*gpiQ7{ zpq-#Sp#7l3pkttSKxaYc^HO_VxoYn9DavaoucN$)@>`U*QQkrM3(8;NClhoX)CtrL z)C<%XGypUhG#oS<G!8TgGzByRGzat?XklJz-kPiCyq8g~N4WvzCX`!H?m)Q{<sOu8 zT}{pV7IX`A8*~SBZ|7|Nv{*B78}SZ1XXhM=>qfkXdG`C$5|`|peep=*GV@%mD0!TD zu6|nbn4NPC^^+&<oIB`<W;F3JJLfeQr4Hvr*F;=BL4+N&Id<75*ge}91!c7+REoWC zKS^HL0q?vc;u;7^MWW0AVA<4X3i?b!pIPWL189yQMSC|$t*9M$W?5^{z6tFc2o-Q0 zT890(Q&B+XN<!d8+#XV{AjNg?P3*Z_BvRou?6W(7=8>J2u+tQFI>1g_LRoAFNn)}6 zgxLB}Y(c>CsSkGYtf$at4*C=UEuh$XKpIBv>(Tx)+P9$nH9}cz*tf)85Zh`(SZp02 z6;f<_5ZgAywh6KA1X@qP?v&LFcDljN0NCjZG>_2UKzjfk2(%y2Y(XsHGS$eA7PWk; zrJ$xqtrgYQp!O<i!>IN$YU@#JC-AsxpMo@sq<0AO0d|HkCY^<pD+uUu3sNCTw+Rzt zBzFj7(oe<AmjW?kBw0HV-C;>k)_z<WkD+B4wcwo3!hLGi5wsjc%L%mPQVXs?S?ADF zf|g>mTtQ1AwS0t@^JpnU%Vo5DirHu-s4+vukcN?T8Bx>|Jb@jClt<DLv}R-0d@^m2 z@=0=_wH0d>_kuKxq~6y=!gh>)PMraec9S#<(q1+zb+E=fW3WqY0dky>V?cTVL0*K@ zq<x(e`JC`Mf_-xdC-S}I`~HiI6mOM?xaLB9ku-BSq`@SOgw&R#J&;C{#Pr%h^2<C2 zX%tE4A=MM&aWB!S$R}$sYI#)ag4$5jvY{o;dKOYXNzXxQMbb7%!$`vF#;AgEJ@k-> zYRe=uYWre@9HAjVJ%M@y^#>|aan~9!ZGl5gtm3H_LN$rIjb%vcZeukscUyhbeB5oU z<_Av;$bTq2MZi-OP@LO9ng4L03ZN>WK`JRcLYq8>sAN=g`VVurF^_V08>>aS+n7hC zyN%VN;b|B7uT><ft)?3Dn}}KpYKy7OjGB#Vtj&rVRtVMr%UiZYR67R|wt%%5LYYou zpv{1`0ve}^L8Q>8xNE6mspgD3(cQ)(RlD0*Eydl&BGtOvSWOR4OUZvOJavYr?m&%% zGXEWcb_LoKXsSvLkI*LnW>qrPoc^uuHs;ahZeulvyN!9wbhoiuZFt&C{`<nyfT9_- z2NS}4_X9Ez$WS25NoO>WaX=;!!gTQDQF{WAr+^$Hof$=<+U$HfMDt#R+8oqgqP9h- zEu$Liy9Birs2!&^oO!i3z|tl{SUdLA+OGlG0%RRo!+u`-Eg%PhoTgsKft;4isQn(s zQkPKH^CZxBfxZv4zN#1U1Z~P%LscHtoLOt+Zew|B;%;NLrtUVDr{?Z9R%;1Q8_EAg zc)A2nr9fK~%KU!}^b?@vK-;PYz$3KDe|uE{)tvr2xZ9Y=PVP2V>*8)>9=o~QSgi*< zZ6|xUMqov<^LPfN(<FUPtxS*2+-`wM&rvIrzU2hkJvrh$afW0I49ON4k}XKVa|p>H zBu5YdX(=$xR)n`AJeTC$Dw*kYCOMDryegUX$|oeBkbJUVKu7^01!R9H*&jyuFv1H- zF07K7{qZD^CkyoiF_1h#j2*w8pa#zqaPH&If{mgN@djkM5Ag<qC*h1Y5PV2xydlYb ziDwHEAo;|zNk3okq-zVapHKF)Ni&~#W3t?zcw_3-pLk>H+n@S27Lw4nzmNpWO-OS9 z@f;d&0r4CfO9Am5vQQvM&?|?=RX~1o$YxXOJ5UgzwHa9+M3$S=cn1qS@aBXMuEN<E z2UD~yNoOeOv?QIOq|=gGhZ1i^-iHxyC3vInFyd{g??~#~mimsQzHO=3NaF1%wow#Y zJJK0Nygl*Jq~D%2M-$H_FNMT&1uyt2B%Vti3k7eCC6_W#NEzrz_Qw+MOniKm%vNj{ zif{t)E|jYY#JiBM3B>CW&m*2gynuKs;=_pN5-${dxRPrP*uA76=I%klof{+<#=9}z zjrq8->c05TC#w2#+%ZV?$jaxC@|Yw_B+L_15@C=qmJ`IU5pPWK^e5ho_#nZD{|ef; zGZMu7*N|{$#B}-HtX;H_v<4DyO!??fyd|AaL-9Xf94D_{0?&OxULlcJ#;=iFO#Bz( z^#p(5dBp1pfh04YO-MfRY{K)2=MYjrJcp11;;jf7M!Xdv!-%&fWF+yngp4GfOGqK{ zTtW(kK-~4T6B5Bk5pPd?w2+8+n$U;`VCFue?6CRziL%3_i-ZY~ek2T%NKY8czJV}j z_B&JF#}nVcGJyLP#upP`N_;u-mx!+;zER+Xcd)<XUb0F9s}k2P#&;327aH$E1NW9x zKScaE@$*$2+Tu_)PvA@rX1G{FawN%eYK>=SjaW|HM%+TUg*4MhvjfQvl5N!5fHX(5 zjEX6*;xIz2!~=*Mt7PWgNESi~u@EmN<Pz~P;#T6}#M6n(S?0tx;&MW4#G{GVCVrjx z4dOcDEr`ccuLi{9329J;V=odnU^|02iIB#`HN=}SE=iKKBaUZ4NfSx?5{BeLZYp8O zMdEK0KQC$TDUzvWnczm^Y4}BjNOn?okod=($h)z32jaDfcLZPP&F~Z6(D6P={Dk+% zT}3{Pe4y!b$mb$G8#wt#KJRc1*pmW7eH;10if?1$jeI-G*ptIMz9q5-><Pm69eR=| z=R^Ss0eViP@K9L5J&DVRdlUC19!T6lJd=2B;&q7ES6Fav)DsfG^MnMP74>Ns>@9c# zsV~HX_a<InFp+HHPGarjc^tdJmyq!E%T^4oi|k6-m-;oN9({>7q<(z`6L#l@w6pgW zl3=N!pabtK==dO5!BeV$Kd}o5PpFVw81Ke-XlGNOeB#-H5lFsZ6yZ)6ElGkzgu7fI zkPt~Dil-m(#%z7yn#y<+LIzNrO(?<vLOkJE6Wjnnia484oC7G%CW0P*1`y97p9O-E zdmo<g&H*|24icX5DF@An4-#0c&B*p3;>{=rg9KBw720_A6U5Q!knrp$h@sn@+6NPF zPNN$v=nzc{vNwcy3yOOP#odCe4xzYP5<ZmhmV^%_-jb{hCEk*34i$9nU5$6|YP=hh zx-lu=9MR$J0A`{EB)l1b<idD2#^${>MK_#yYl>w!@wUWA3ZBtjU;)pz7;{%hc($c6 zx24EN3MSZSN4lc~PoC-G%>yK+i#HFDa8C}*2NLebfkBGyO;|jnK7>Jno%X~>Q!d(5 z7Df|qPrgPIZ%?@xO*~hqh3pp+&!xF7B%VvHg;<-oA7^hk1fIveI5e3wkT9_z<p&W4 z3BEhfo!J;cfW;2vbqvi<N4Ar4V~Ka9ER7}Jk$R0K-jU)SOL2FkzGJCxC&I@O??js8 zh<7GrJn=4cPcuOf!EYDpJArr?8tnw)11QU*t30whr}6C0iGP|b)DvVt@&p-o1mnRw zIjrhWA>j=eBp1fHG0u(2+*oyA!Ho&gYsg-_Ac|f~_8{>h!X(I}Kp2x;80W?~Hzspq zGB<{0QPsEFhs5oJo&DJ~rhMYrG&A{vz~Op}7B(t&KZLh+kX#t&#yB@7b7L|$Cb%&n zdJoxS<J(L2Ai;MIc`XoRn2{WsivpU>R)h~jo-aTf?<wK^4kWx4gyh0FH^#X!nH#I_ zE4VQs`V84)alA+NSe{w#@y-p|Wx2;YHb^dvb7PzvlesaO8x!1^z^^HB+KcDcLSpvV zwIP>yA&oDW##boF_^t4WcX#l(4HDkfL2_Z78{^!V%#Bs|72KG>Z-qx@FP`59iP>X2 zc4s=L#tR(c=uB~pufo}S9#7G9rnw(42&w?wN#U)Jz^MXB!c(;y<J}mqlA{%GfY2I2 z64P^Gyc^?HMzrE>2wF`fF+CT?yRmA$`fjYg%7z|zOM)JDl2~6C#=9}zjn#K!^;LDz z18+~zqaI1DuM6Yd7_VxAR=i0;YYs_F&xP@Bj90ZrE8eQ0wGBy3&xP@BtXi+W8>_GC zj2?K~f*vl3cT4r@J{Ef)vc&iy;>V%O-EzKB%vSLvg$UUyk&w-aZZ&kiX+&Lc*I^xX zvAd2tT+}_>^$@B{-1T6gKH5Fq^$@B{;fcLP%vQ-rVm`g9bm;9O>fY|U)2ENS?)2&F zt~-7Dx$91!{_eWdXAC^CH-OoySdy5}xGEibGl+V;yYBQ^%UyT+OmNqoJ`>$_r_UsJ z-RV;ePwcH<wknw<<};;Ahu#LFu5s6$KDF+;)2Gf|cly-3>rS5rciri;7d)|dX4$Gd zl9<olRXX%84fQ_my3=Q0cirhT-(7e5?B}jKefD?PojwP^6MIjVttudi`5aiKL+{T} zALOn(eGYcloj!-S>rS6T-F2tWVeUHl#2Vht?kvH@s^Rd8w`xN6EmqGKHc_3e%r{BG z8ieKo(qF*tJ0Ww>UBGZ|gHT^J8hUseM;3O&!WODC3nxf&T3AeH%~I;Sl=W57c?6Do zFK~92?IkaJagT;;89h%r&${~VI@4NCTFWVx<;<$8qKY$16=dl+=^Te8*K;Sc^tKR8 zJOunW&L&qIv$~FYtRt)IDAu(C^e{qBH3{RuTSgk;X^ikJ)!7JtBFQ<zm#Ei98sSDE zn-|5-7i{1Qi7z64j`#)Q=NXR^h)aok6OSjJKs=Lp1LE1ln=sC0k(@`o1tFx#)h47b z@qFSViH{;ahWJ?G6NpbFK8^Tv;zh)tA^tM)4a7GRf1UUw;**IlAWmb9+d=Xh#CH<k zCD^1Q{PtuycnjjKh_@l$j(9Hdj>J0??@GKo@t(x<i1#JlkN5!M!>afS*dIyqNF$RA zNiHOL9LeKIo=EaUk{gk{iumiqHxu7Vd^_<si0>l4oA_Sh`-mSPeu((n#E%g_LHrc) z_p3OI>O9Hk$@@i;FOpnLaxuxDko*bB>q-8O_$}h!6TeOTzHzyyxL91W9P}1RFS@05 zOyba5Y62yZl<Jbo8yAbqYcq_bj*vV`_JUXsr?ky29bi)F9?({jphuFV)KV-dHRAS` z{hEON-g!6PDTLBHg)rjb#FfNjiN_Jw5H}ECE8CA=FB9L&xL2wd-c5Mfh=&mmC$1!} zVca{`oAEeryt(kN@4p+oIq^2cI}q<mysrPQX(Im}{!_r;@Sg(Bg@mspzLxlU;;$2* z?~lLhAg~ej0_}v1zahgl<9H+feuokF?J1>#jpLtf!twp?aQt)lpLU)-#qmQw;P{rQ z9N!Lqb>XFz9N)PO$1ebui{F)WhHl<Z96tuXSb2IT#~0P%_-EeY_*uW;E2;PklLPVl zhan1%AAX7BN0o8>4E&{w1p_&L`S-Aizg^j`kmCo5IesK`igX;m8ox2>j=y3t>}!sn ziC<{U?#uDLPjmd#V%WrA=jef$`iH|NY>d1IA7?qfRT0Ox+0F57VZZM&`1}xU_+9-N z{1$!+zNL$=t?)(NIDX!D9KRIfcySoVufkuC8HZm+jenZsC*v13)8XR<#IYLnIrzIY zoys}BC+d@ssVPsvUT^5Ld>rBUB|oDb@pJ<=Fc`61M!f#8W8nCw($S8Lwmpx2a}gJQ z9n$6u$4^kA{UH2c+)FU#xl=H%_u;Dod9ZVQSH#*Y2suJd3x^{w7~{C#Ft$U81GCi9 zm*WS+PX0L9i9`EQ#L$D|$6|ala$x5*<Pmv)ejD^=!8Ytp!+iC@*b4K}e+%L$0AZX1 zrea+1Hw}51gE$u;j<)zEVEg)*PyE8D$4&S-jxoW;_!N#`yqV)yAm6K(f{^dFFJgV1 zfWNWuhaB`6jWsYIJ~`xn1^UHv{0PJ}dN%qaXOpp(roh+piHP-E%o*BWXbL+RW7}8Y z_W;%h*4eBhu!Z<~B9=ZAVIMJ1s*Ri=UoAi9_zrimHZaCs$mOUVuwQ^R2Y*u<ar{Cv z@``o16zg%B9C<_T$D{v(oxt~?&sEqc;`r8=k!!@ztq#Vx9C4n-I>ESS+(TTGu)gPE zY{=gdJz_)r{Sin1A27%Da2~9LPZ{#r8FMoT<H8zShB;_61Y?K(63k6&4PuOd{#O`p z3dVvs@){!N80!-FZ<~zq`ollwq#xE!|CVUmfH}iljh4Xnrx??C<N|Xt3o$RioG$^^ z4)G4f*xN@T=5x?phV$cBv>|^hJ7Qj5f~}?S`!3Fv>sW6nC&nOu3$b<&Bfl8y+)l^= z<mpz#;Q)Ce-|G?khtR{C?>ZCxqY)Q!_Iw8XH;4TeI0rF?9?)r17w0_scj^M2(WsYU z9x%o+?;zKiAmm~^#x?$V%tHs*JczMiZi}$4=lp{F+CcY_v+qF2_i{DPL-?8xJ4<$B z&bA<bSeI?!v+ZdR=DZ#Dn%q^Gd*r6W0Qg1>osh3?eL+JpuZxgh;Cau1Zevbcfsn6$ z3y@bfp0UVVB-Ugc@&^5p8srZ0IJA$i4axyE0ksAp=JDM@SOeo>ZvuQxz_~IJV}1(r z{uI{0(<8CoJdopWaQ<MPW+3;ou?}W0L4J9V9eV_FHBX8hzKL;thFnx)yvS#-LQYiN zy6ju@lw&3mG16TiMBi!(%4`tIwkJWD+1y+ZW-S+^>GTH9Ost~L?K!?nZ_Jb$Gjbku z2`j7sv>Dcmk%5*Vc+TsESvBJ<I)*b+32KY1V08TzAe4g;`Or^5SS7=wv5Wi*nX!Pj zB0D3n3fW3T#ABjBDiCzX+<{(GP+epXt8&72%<x2<1znL9WO6!uOvlVV1KYEaso6!C z^+O=|n1gK1or8?96@Uybz_=EUL3Sn~JFvaX8@qB4veUGrDe;Ej&C4%xd<N#eF0xhE z4y1iq4tU3sbKpJ8kmZ*efS&Ucd0g_?87T6&?Xg=f^0?vgb_C-`e#?<JK)K)J?cZ`D zoYE0!o%7fo#Q2_2#`lANK>R%M4~btOev$Y`#EXevB7T|pC&WvLml3~0{3`L!h<{G} z8u2fQUnh>J;P)$!{lOxSiynK!Sqz83KOz3P$Dv|zvAMJ(D4(QGB$-Qlq8!SJiyNVI zVM8G^eAq+yuqu4`L-_D2e8fZeh$?*KL-<IFU@uyovAji+xpW^&S1is})Pe1<fxC1W z&h%X|y7XC$Oy7mO^oQa6$O2)#w5*5Ou3L(8wiQ-&t9{rbM4$;EtfJQMbG&&qH0qT( zaQ@)@XoH=h%~*z%V&$9nqShZYkC0}NuuHai6?U<P+iU{bx3nD6k2vcD=tFLs0cr%o zN^Oh%!xD;p2<Ln|oE7b`U$pB28U>mRdKwn$muYbx4Mz<-VLN={Q(V8i52UX_-($~4 zzxJy^7)|>oAe`~-Uk3ezvm1LyZaWb4b7z2F2jOhbJ;L!F!$9HK_u7C)V;8{A(eW$@ zXJRK`lygz0f=nPblI)VtA>9W3jJ*P0J4b?$xz4>=YuN_kU!i^z`-lRR1i2VxKaRJ; zx)r-}SL`2M@wrxUqta85j)I`k^#_KO%OO=_=Y{Q_h`JkWr(=ighMDPh7{s#NxD-)z zZ$Q#DNJBw`KseXCUj=>2@iqg>``EwKAk1?Q>|r(*W0TV9kf7OP8wh#m@g~p#<qIKI zu=a9{bsF~Bp73lt38Z=19`H`3mx1*L!ISMXlq*2*fj$P^#qNkG?GBI<+BszxfMB1^ zYXWKxngH4X!n(-Y3M#|?iJ9q*9QE!F+73dWKCRKaX}J$1MBN+N>N5a@nEQNAE#G6W zMPz-BgEn%!LytPf*7qsUDiBtaV=(sO!O(7A;spt@_WK2db(IkTl0pOdYl9KDS&ZG9 zL)%JRbFjlVxP*Evs0XMWvrv8%J<zlNub`Q@;<W|ZqGSl9=RhisF9-qE2fYHq%nxL1 zphX#K13$svEx~*aiUrcL1XqAT?SZsJITG{|Xdi1SbIz$Z$?!9{C8Sm*`ym|yA;*Jp zehtA|9a0;F(GD30n#r_Eqam4boxyw$#X87JL&;{XRoMq<!MqF`%4+33h$H4<CvYa& zLCAd85|m9rlR?Pb@XgSwSDJt;Io?9zO4<j~N+y-#tQm>5G?L9vn=<5Z<P^|iRx8J+ zuElLjkcUy2<xx0iYHvch4&@$P?HYr+fsnn??{It__${o39_>o3kl1<9u4Ey2lTu`4 zOaQBwuO-gbUHg)T=!11oS4uT@mb5Rq&3I`9ag2B@vM?5NF&4h-HUi;0rp37>Q5-)G z*{=H;tCb}ZUqSph?mxcf_<G3N1dM+|E1(@pCox`zd7AJo$JfW-k1y`P#yt@kn|K;X z5|EB1826;}sI5VH9rPKl&>U+iFM@=OHNe?3`6TXUM4)Wc&1mgZrY4STH0Vqc*4on( zn1p9({%Nelr+-DQbIE1KOXIO3dy%vO(r`%4%X^~lMbvN}O%*u4p*KqO?XrvMmH&%4 zlbe^nKpd-jni%&4tD!px@&eFY5YCgfIP<6BoSVkV1E6c@(WN{ScNoapbc|v;&WGuU zVmex<e+g;_!u(A?11f=bSIi%H=^&C3SGERsYdAk={D3>>FreMap+B=PYcJQLy*nt6 zYTH?B39^`txQbeX`h&2ti#CF0;U32i<)<jsAm}`U+-75^dFCqanvvgZtn696Kz(4T zdl`DqLhGzDj&Ec^iL=Pe&aECLTNp3x2mB!DB<_?jZ_nle?OB4%KKnZ8ZQM;_RnBAA zw4UV#@cJdl+q`!{`$4w|f$irmK*}pUPy8F)X)OX_#0vr$Qm%&tI}2?fM6<9MGzm{) zh;>mYG<ugKuEldXJ_obC81Eg5`;_9W%ejX8w4>OsF|SMGf%YwBXJ6m4NRDqh6f_3- z6(IR+KWn;!B%Ha+l9^QcCM0C4SsL#5lR^Ii9RXDUI}43|<wiWg)CJwgN7rXTh<sIl zv<xU=wO^Q2>cM!KA91Xc)%);)cL$V+eKjn-<N@*rg@H1lRZzwWo37QzJ6~Sdj1u3} z5w@Vjcf*CPDA{**&Y;BmS>ZjD__mI47UgM_MJVyjAYm3td^bp#jS}Au66SM!)q7iB zm;(&o6%w`)M&JAqo&$#O3<)!@)yI2PUU(LDe3M9c9woj-#2p7-51;2=yN1()I8Qtn zd>Z>^!c=bBH2)F)Bd2mRSUI|?K852Be<wU$KK%V>KEBqk5st1w94F>Du0f2bV9Sxi rm6eA_9zvD<tIJK9#o_;V_+R{6#vSc<Wy+uNjPI=dyMLb8ytw}d`f6#K diff --git a/src/java.base/share/classes/jdk/internal/icu/impl/data/icudt74b/uprops.icu b/src/java.base/share/classes/jdk/internal/icu/impl/data/icudt74b/uprops.icu deleted file mode 100644 index 2cfd5a784e52d8229878756ffe0ba08d325c9e52..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 141616 zcmeF41^g7n`}p@_cW>ijZ?EqYDt0TN*cd4AF;KBlQ4DNsFtG`-0~-UyP80*X;De3b z-CfxK=h?Zrne7X|`v1LN-utyX&pb7=vwM4cwIeL_+7d!e5F$cU*lO582gnIQNJj+j zvD~JDz%Tm^17l1OCf*<jlh&;-+TbUmKX1Ph7ifvY587*GLC6lzCe(r1`O$^q=f*FI zPmkXie=Pn~{Kfd2@eku)#=npMCdNcfG{vg8u(*`ClDL|<rnrH)u{c~DA?_xQ6i16= z#IfSh;z{BZ@m%o&@pAE6@mBF}@gZ@x_?S3Xd|rG-d`J95{6<_L2~tAJNO`GKT1Z+_ zT2UGxtu1XR4U#sIwvu*~_LFv(4wa6UP5{5NrODEj(sb!Y=^|;i^oZ0e&6Hl3-jzO; zUXXr~{*q<sTe&EA%8SWqxxc)YJV;(n-b&s<9wl!gA1sfPkCXS2&y>%TFO?_CH_0>Q z+49xWy7FW4Q}LPdi}D-t2T*<?{~-UKh$NImCQ*vdl!U}Wi6s*&CI*O85`z;1p%*R^ z!@z6X#E8UhQ0@)On8et`c-ZnOi3y1_-2QG&;@rd~s7*{y+?be|n4NeG<fjrZCf-bZ z3DS>=pA&y2K9mF{suUDe$tqnSFRm=B^i$RZX=7!$GD6uv**88@IYc>JIab+CIbAsg zEa$;8UAa`bQJJaStvsa65&J98Df5-rly{Z+u&+kI{<Kg&t(Cv15miwQwXAlkiz(l# zYpH|O<<$P_ChAt|j_U5}(dvHcq3TKM6!l{Da`hbbS_ikPcPstW`_xC(UiDe^6_DRn z-%`I;zk|N^Q$NNvL5paL`b$ktQEjcB(>j!X+M?Prc0FXMwWsw}uhmx9)}?h?Levm# zm^NJ7o<v&5Uw>^^vUS?tVt?%*Nzle>6SVQ#cyWYwhBj537N4ojK!5FKzCG<OZMOE5 z_L#ITM7)T5QhQVTQ2P}3l=c;jY(MQs^;PW;JqFSry2i&+SvSev)~oKl-k3&TxG_KG zr7zCp|0Mqrz<s1IulLtil>~hqeUQG1zLmZ``s+K9D1A45AA7tGM~^;EKi00b*K~O1 zA^PcdeOOIDGt^^hm`7`N{W21#U#;KNS_X{LZ`Ws8<%6x~;3M@%`P$zj>vMwh=uZUO z8@1}sHR_3e`pf#;&G=Ja9bOau8T2n&ZAbsM)yTg$PXCGI(^vjG^Xe}&noa-R+cOzY zYRPo1Z@u0=|DHApR~ml@$%4`^xwvwpGgoq%WZ(FQ$@P<Kpe5Op+%h=|>Z6lml7}Ua zPVSIADLDo7=O(8oXCyC4-Xd+4oRxea@so6A@|oll$(O<QcJkxo*HHeP{3|7=(y3yq zn(8C=7yC;>Y8hvH|JDB+f&UvLkm{RSC$(yPW_zSIYLm@U|MCCP2#{kpwGCV|%uDT* z8da-XSE))QJ~MS(>cG@E)TSn;Jg+BH=P3igdMPYdrDmjVNzF<<kg8qvq@GHB7@wZ{ zGWBEXSEZ18G4*DfN6$vt`Punq&Kz!@W6sOzxs7ut<{r&`lV34ECO<y^VE%_fzrt>X zs|p_!ekd+k99f)Je5bTfX?SUT>A}*1a;`jF9j`v93EDt-w|2euxjIl!sRIf6rjgep zuj{AjPuJ={Cs$2wqYi{ujoHaRQfsA-PR&mJkzOl(2>PX`rsu)>2b7V_!c?l&`-5)3 z%#E;~RnvT>4m6fW+1MYJGikg3mH&;v|D6#qo@=kKvd|7$qn&73$Qtdv`n4aOj;56~ z^n#pc)8+J1>4nn+(<`M1qz7xW)5B;Ba78Mlw@r_P_2~4N^dae^Ksqr#6Fz@BKYc35 zXTTX~MtT}Zx4?2&`ib-d7)$c<Yi)uOO+S-<JN+`+(_g1QPJfq%vvDRGpP5lJ*-VAR zWtPsYoLMBZUS>#U^~~m(?ZCQMW*14w?3+0xb5!QU%&9bg<{a!t=3=pb<|?q?fO<Qb zJ3xOQWOyhuC-Yq9m5h{m2bNE?37G}bDu$5xMmgO`7#X8rEN^rfiyJFLeLZ7!W2mvK zv4ydHe5SFNaiFxVG0vE1oNk<N97pp@f^nH~P3A!;Z#M3tTHJ2q0pkg)e8za$fOo&f z*T%>3nTavR&&FT8UsfhH7|H(GbhbOYShk3oZ2#<P+2yjEXV=XRk%a8d+3nzy(x0;j zuvp9M=<M;?J+p^r&&p1+>X&DyXD`Uk%-)EtImzCgos)e!`;g`NQud?lTl}7BM#k4- zE6Y#WKTRnMpB6IAl(XG`s-BUs7iNL=rB%u7G8b>R*NwEz9}CX*!s8P^D}^Myr&bE) z@@8My^7YLgb4zm#XD0tT9(Cpp#E$Kmqs-Cf{#Z8;3vd5_>0uu8cV<`c>;mVBe-raW z_ZFF_nrE6mpL(|c?#Q{dq<!;J^Gfr2r|o}T7e|=)nh%rj4b0o&o1FSLB`9fkDgDej zusmzNV!j36gTMl{k4Ue~ugtHouD)*mMEjYOa>-maSIRAvTQav|PR$L-4a^PBZIbJ@ zEDBh*%E`HH!7?&8IyWYFcy3f~pWMN@BXWD>jyM0bx9_frBXVcKazSod&N{Qwc3UlT zH|Mz5hxp9gHMs|r`MGCu@G5~wLhkLH^_pmJAtU8J2HV$mt-S_5Kif57wcKC)v6zR~ zAaP2*m`{hrIqmuG{0jLcP@7*TzbbFdZ<gOCzjJ=i`~msH!MYJ|Ls{vUKNd$_yV-mq ze~NZj{&czzw7bFo{QPD4EA!Xq;YcA+D=G8$+Uvo!{8jl!YH__-=AX~MhOOt{gXOcl zHMU+Ew43uk7lcB*pyz+5_CgMiPUC&ruU5-K2kwDFAF>|`@JU_)&fxzX`juAu*5{JW zRtxJFdYroU>VMa#(uFPB>qn!}1-RP!J1LC(JF|u7^1AX4k800DiSY61hJG2qNBq5V zVRU=>3S%0HPoLrc{HO7SL#SjggJS)&Hg2)E)?n@E2K^d%b~JMx>c3Tm6AMQn)B}Ij z!6;bo0;%nPQU1H14;RjfTL|ek(S@Q#xmM<cJV+&2OiMFFm?+GND3KwNiIF)`B|0QJ z(bAW|2fd2$ldR^+L0n#_2nAT8Es%q@^RT3yzvKGH>wm}imjyx<Mx`QD1ySgLZOed! zwNk7nHrW~{9PLU>1AAw`-hMr6_BK8GCC9#McI->8eT6^B`zIH7Yi`Zo+aEp~ju#&7 zv`r!r4Y5$G-NK?+EYp#!tWI-KO%(Px#vx*j2>iAY?fe?+{)@kbk77Ad;(O9qJfEu> znQR?d(^fH_w(8dxKJI@Zi&h_+&m0%Rslc-u@$;m1uad>st#K=#UFTK%`(Dml%S4Y2 z>@Ujrh}Xs%UsLD<`yQ#E=kN!>xR7XaO!%*fr`_J%o}@=0X%S;-zZ)%Sd+3j6U-GOX zne09L-_&UPt(J{$XOLf&yC}pjMuL3*ep^t+=J#h%HZPmkF&Mt5@#v4kQO{^~|FJl{ zqQgfOC_~xW^R|&F6LJ@={A_JC&8_I`SaT&!K%;PcydN33exk5zRdSV!BjCLqMTj9| zPFrZTjMrbO`3&BzdTITxyRmneQS!{sxAo7+*c*HQ@w%1Q;42l@nHGEIwSA<=xOc?b zUSP*RFA1=h+8qJDhyF4iTmQ^BVk_SL5WNrZn$~|D+v&HvC%6~!{RtAc+Lo+$E!30j zW2v^Ui5A`X{pOaN8(n8xSZ{tS`M&wJUmIK~!tz&a9(ZJCSTIPm&wQEj)bbwwvb#TY z<o#oK3&vv|_l4K7gL~KA2GfvSi9jFb?JdC<*3bhH)(GD_l!+GgC^?@MUKue8A70yo z{_yU4)!zQS>-6^PU9(r|f#bLgT6}H7{Y%<$?`h14(X{kxnb_?Xj3N)J$C`V4QHxth zOZ0F)h!wT8CEmkpdvPpCySR_N9%PK|+e`gOD|Q>*3R*g?tZ&$VngPd_>`A(Junj6> zN%k4)><_*jl8^d&ZEw-Kmf<tlj~LP>jw8*>N~)tJv+$DBO6t58TX*kY+%D`nwv8h} zw$r_jF`7NF<)H0_*GBT$4>_V)U|srO9M5#ml5xSN$o67e*jw6T`|(`wk|m%|)5o*i z+to7`pRtTG$o2<$=GgZcdeGid3yH!S+UR~nEzwbl?jsuKEYS}iWUta~rpG%iz4kZT zev*N-Oh?b__@;iOEQ&qiWU*J$$Qnk1>}}i&?p_iNX~St{^)Ndb4a`sWGj1>0W>P0d zIo$@<U!tLXz*g{qb?WQAz3AZ{Cz=<dv2}74%(jB=Pge3aUiRKzUW;w9<D1`Jvfa3* z+d%t8_ByMPe4*P*j&IvD8n1pC*bcVGG*qHJrX|%kQ(|`K>o7fjX^9@}8Aq}w=4o@a z-kv$yDm`<0`r{|k{KI>{l6>B;Nf=GGv$3rqtu?x(UO7>R4|@)hm%Sp9eUGC=&gOJX zh~9g@*fZksiW-uGu1PzBbsfU|-B)sc*J%7GVm#RzmdUwY%;J=sk<9MZZ|uKw-0+hM zb`Bt0=zT4QTg~#5GrIdd0k6S#9K;Xvve$sB*R>veBhs@$&&EB&dq(u^*0XQVAwA3D zD+hV!i6wrwg^SmI<9o*X7$o7=;Dhc{uadnw(oaNKMlXMIlzCek)sjzm__4B&9I>-e zrk<!_57tj!!jYr>U=nIbjoQ86-?KLDXKxlo+9EB`^AhUNgTZ@|qm=I>lgSx{^o~Vi zM8fO%skJ~xi+yg^jD+u=h(G@sANkapjxG6YJ1i^P3M#Q96f;pRDY4FUZaaE~+3gvF z{TpeI&&S&4wRV~Lc=zA#?Onr2a`f=WnkC0H{2n#d8`t7J@yYRCQImVs9=$i+WAx^F z3ccl?Dqd?&#uV`I&d;>;S;LnklC1gtA0}f2e>`B_4DA8yi?@X5PHzjZ)f@2P{fUfc zQSxxxP-Bg_GD(@Ms;>OCz`%HWR<cLEt_kgael>Ciz&^Pjelffr<NY4IpIxTM5IG{7 zkGE$d+dxKwuGu+_NbGz^Jy=Pe5A-_){QQG#li#&kt-tjBhSUT1py`!0xkskY5aMC) zCD!N_f}h<ULHb43<QFF>lYZmpWFh^l9bLhnS=n23*6e$RS+NhS){JD&NNQw@=pMrw zk*P1%sE+PU^r8=X1&*WRH73pU&+SW(RksB-_+S>=BYVm0c8Pk~wca)Ai>1dl!Y^OQ zgFolCDtq_9PfPa~*&qBdOJw@IA~ozK+27u48LWOSx%K3@uxG;j^mwsbypAEe2kD*1 z_>#e`t;6i}y4*hg_Li__w_^>*D0qC>QE%&#twLM!dS~n&L$`*EAIrjz8<Cwcq<OD# z;g1Krwq#j}Of{I%E1qu&V_V%Onul&1J&(}#vF?1(zI*kH_>!z%cG@16q%F3lV?ax^ zpiCaL)kdyR_*O)?zGh$+{<?|C_ALy%_VTu44q{<FC6YZmJ&x%s7TsFDq@z!DbbIXQ z08%5q<cv#Na&I5euu*77^2;8rzmM_v2(qv~dHp8BPv^{teool_BEM?FQ6fI1r1lv6 zZm3eXu`JY1OJ*UzL85vrS#IXV+fil~A_dtoA8+@{Pu?q%Upb-NOn#@YSN<6MVvxrf z!`o11cK7&3tudy*;C0(^572np7rOmIEw*629^fyI$uEzc&o`{&?~JLR-L6~Tx02s^ zkndjUZ$4^ev=@$Kc<}H0ARmJ5#Rc6Hmc@j3Viat<L+FIaj(TbDPf<t;DXvfS*VVii zW}x*#wAcN<l<OaUw&n+J7Jh=*E+miNnx3`XCH;%LRQs#E+k<HQG7~+$K8V1T0b9sX zQiY?39xv>duTkro0*@=Sk$s74_FRGAOxJv>{U@&ipHcUlJYaHvZ8dEzZC$N@&!C?E zy=(Oj>fNMQoNW1Fy96T9R%siUne+}b(;ivA;v{jdq)J1jNzz<dm50ic<hcnoG1Qpb zHFT;vc4(M=?9i!0$4<h&OLL96Qzwm`E0S-!=%}&nqkY6aknLj{e~HCAC5$0?oY|ap zzwERh=<gTfY_-|Cvu%9V;^Nf%)oCA@y_skhMJ2!Or1s#l@vRTe<8S3#@b_xeLXX16 zOOMRa-h`IuNlZ@kDw@)xOjdeTP3>`?_vBu$v!UE@v{x$)A1Acm{P?+#9qQ#*dL12J zI=^^7eRvM~yznT!M!Hd*@A$EC!WLPr8Ofus4QBF+^wTxdBj!u9F->z4#$$xv9;N#5 ztmw&m(a6S1eC9Uh$-KNG@HLRU@{w0XtkH$)QA2cC67cH9ZfEV_Ybx<4R|;5TkJ>d- zzaHyqiRQx+uQb_%$n;&6U&;JY!q01h9`^TU{C6QFKmU0cYQpM%y`p+|UvTU3N|9YH z5{cF6H6)hglT%z%JC^hqrX`E8e_loPc%94SBE-|0yTrXnv@|;{*{{s`J>7`xb=>*I zxkrp>{QSN2emQu(SDa1fzQVJ8{$q02?+_=?Rfp<xL5JUwU>^Dop^7?jsB53$sG=Vo zU0Rx!CJ%X<0k;gFYxvF#pP9|X^1k>zCy8fc#oHT~ozEQaNbATTzj>1EzXqfGg7t%! z?7yY)$W3#yZ#U##YrJXRkka`bqEJ;QtG$}0^=Ol|UR~3B^vQZJ-08L_IXT&z(!z76 zdQy{9y=g7olb)RJ&1jjP%;Ze3p&32KWTThuG3g{GH!F#cH5<YEH`lW4G3tCaB8%46 zP~WjolNySnncCYT%pzMop!uAoGe3@jG|1`2>PH4<qkiK~k{_dTE9F>M51Jb_Y_qYw z+2v}<*<a@fIqmLx^AUnL?j(1fMm6JLYnumqDG!2ig0c~CkB%Lr4$^J@=|PReqK{Og zQGYMLpd*v|lV=>Q!E4V+Om0qUJ(9E|pQQSZ4$P$T7#`D&9xL<=(%cr<y>Sovfk#54 zwA&Z4iMFs$@=1;M%-b*gInKw84;hDXkMZ6?awA8pGag?d8igG@OmfFIJ9_SOuRCY3 zM&d@Oxv^(?`5a7ZlgRZ@$aRb@B6wuIuNv+7`D-vD2j|4^^~k%4Fh9TVA>A!{Yv?=9 zW=p)<#VhBaIQ;Dk`BdEd`#{HktK9D#;QAli;NNXIw}O1@)##dBrSofNKCe3Q$1Nq_ zx3bUPMeChI&=}zR^B_C5(cek3_x03*pBA`t;C%wfodVEG?uUU=aC_vF2a=DM-TCcS zHYylPK5t+#%u3$9&`%3!Nqz$rb|mw5`t5k4{{Eo$O}XQr0r<}~`b!|v3qDJbOphtP z?<mu6?D4pBJ}}1X`NsQUd{Db#Hrl?k#QucA=cZ>5@{0ntC(y^42YvZif7uyH>eyHB zM-eP^q}?Tc?i4hh&GZZVKzm1JEZMf;e{orjN?z?#oBMMtw9r<t<XghJ`$2Nq$Dd>& zW9HR9W}&0S`r<9ww~4&!kl)<!+wL7p`a!pd)cBs_7Ln(!d%J=)n2WrEdACgV6^<U+ z$9RTCo!5iUfcCJuJqPdY-k;<<dUnojRATq2aYv9dGwp@jZr70hk>iN1@p(f=!|(W@ z`RVr2y0fJAW=opK9_OvK``Bw)p*;+tJ?y=y)tsLSuy;5?SH!j>Pm~^O{5`NelGIq6 zURFzoqwU#$o3>=D+5P!=lu4am+x^39_M?{`56+T#F$+19gttJhse-TQSXOVTkyiYD z@Edi1E3sg^K|c0=*{@OTHd6D;h1WL-|El99)7J}9;-}*FZ*;t3cpZLcV#2SA3a(Gq z=_l-%ndBvHpfCLu5_`QOpTqMp_<JR@_Kh9-k$cY2F<{#rJf6(YPr{7kUK6|rY8$Jg zC;9zQ39hX1$`bDi#J+39z2NmAzl~y6GCHl^Ka%}Ij6H|KC3^oyvVZ7a;<ua1_Ui?z zZLY*uYrhElX#06leWTvQFU%YF4$bUUhS|Mhh_1fhZ_#FHV|&K;Oz1hIXKK&1o*6y2 z^vr^PNsXU8Ve%Q1r%s+WdB)^hCeNb(2_es2eoc;!T0XCDTipM_8V{4yTGP{NGc<WF zMTg%<5xRy>P^Z?xUr<StjJf@K`t=N$4EMz3Terz#Pd{o6`liw9Yrnbu;I~_t7g`!R z6(kv2C%@^!_E>G~q^VGY_wvYGf;7qJxl<q4P{G!7|84THkn1S_eM>FDU67jJS9q+@ zq~c_0vfK;bSGgaw{gARc*LiHuQn_Ry(Y9E2-e(D#iFf+qS)J-=Mp~z35swD^wzq32 zb+MIU=Qx_Dl@c2YyN;%xclecI{qwWajr7aw)Kh<FKIe8*KUzBN&N}t8mwtCEX1~kE zeuTYCa@t9qwB+1AQfK-3x-$>9-Pm^6w~DXvpY?gmUcV`38Tc44Pu}h&JNqA0r>}C@ zI$o<gU(JZdsSV0VZ1DUfXD|GA9`7Fm|LP5o;yvK(%g%q8#p+#sRky*vB1s!{lb^t6 z_m}w*flTBqirdgk|HWFL@IEoM?y&Qff7@;g+m@pLEC1Nu@x2pz&*+`nJFRy{?=8Kv zdROV~53jWSCT|G$sNS>}Uy}zl)qiVSYi;iYIj~+I@%q0|?Z3Q0_pToP%E5l+LVxc_ zj|j+We~{}Ger>nYPmRd$XPAw?w$Ra|M=LF<zL65Ml6*8j|LIgC88{yie=XA5ez&ra zqli21uxGUgcU<x#W`74pe7PQ3xk7)D!?j3bNhW(s)YeD|@$~qi``@D#uS~V=Z85$c zZ3(phc5S_8?_pi-C%Aj-=jpBYew}h^y<<`9e7*Lr+v4dpp>;<u+JE}|v3Wuz<obm^ zpM&q_;5;9|djvQy4VVo1Y5ROho_*x^i>Pn!LAH#~-;_*`2l5J|!@Vi2GoiCjjpU?b zY%A%j1e_x%d~VE3{k`nGua{i!7u}8qUngt1xI1$6cpeMn%!obo+E3&ku#J5qQ17Yj zn4sHEN;(3hto1SI7_{Z`Y5_m{c7KC|`RN^q$^9waW9$CR$1A^cR6?Flj{dT(XMLnP z@8>2RA@WaPXY1b2H@@E_JFjU)Cf}XATgUG?X+GLhx;^B(2e0wL-{{uvWm1o(S-ea8 zUZpMI(O7>4;(uxC{_F$pb?E)@Zjb)&nzTf}Pr(}9N-XJf#XECjTEF&refVBR59Y-r zJ`0n*?e?n-=It$c?-91mUi+O{Ne?gwKG^<5i9DFDrf?K!C-Khyp(E;O>9o_ja};P4 zwPOZsg&Yf{HQHmoB->zrZV;W-1*<PCXSjs9-Dd};LmSP)jz+KXMk{`%!u)BRyL7jT z?GP>L4OwF(K6{-Hul9K#cZ<Bn-a5v)TV~tZh(xo~BZ}7jN_!9J(T7?b1+0@+-CIt! zGHm<(`^=A$zZ{m|KayCyx0`Gm*-E<2M2CBsfABtJJcvK_@#r63nbbzj`R;^9HC}r6 z-+rEETfp`iZNaC1_WP7kXIF{s;6jfAmxJfE6z^s4KU&C<WY?n(HO_OB(~E95IcmwX z1#{vEU@yscr1(7L&qV0a=)>6}#yNGtb<#JwPcWYJj_8A9sg*{PNcWX9eOA#|4Qz!x zm@jRW<f57FcG?cJhDoGl+M2rzi$^<c)m_@pIM^1wUP9UH;c<M^cL;c8RC^xM@e1p` zs|9k0GJHncpE2+W8hMaD25oh-#}DS>&onqn_G<;Fm3TO{q)yhZ?Fv1nF~Yrn>>AvY z&WFeTu({Yrs?ldXAI0~9q^9G8J?1^BOrCkTCfh{L8}y7}>z*yXmEMsyv5(lE`=}+Y z+K)%R7B+sE8IKRTZSJzU;|+VsMwE;N87cd?IBR~_1JsZH?jq=WN9yY?i%)6uv|jC5 zxGVHCa9`+W;m**j_O9By3fyU9PR}~M{Wbg@E6!N>l=~lW*8NNR&Fw!FzH^0dUHeTM zFeyFMn9JW&0~%yw?rt44&bx5f@5#aE!tdqmR;IBmw!3-MY?ki9Ne@}y@j^85A>~lW zKGeGVhicscWGLJN#DcX`ZvnnJmaO(sgIhYt+TQ-`yH3xoYe4BfuACb8vCXG-dOPdv zjyT?u{h7>;P%nvZm&#$!BWHiS>X?hQ=l%NQ702snfBZ_`*Gp#Yqr{F{`n;mwnc=^G zy&j(9VBIBt@;GhW<Ri2r{64+(>J9&_x9nc`^YpsI26;`c_n-ANxD|4)!}C$Quoh9G zqe@55yTt!jxL@H&rm%CQ_jdVf?frAtXb+v=p^`d1=ey&04ZrtzJuj0UqQ={sZUG-d zys0IqWKsTJ%*QV;>d7zq@Y79#J*x2<eI7L)VfUm*l2?hIUV69Ao)c@dU%_SLo-7X@ zxugd~$3L^^XwuTzQ;e|dSl)1nMuvM5586xj=!9w-Jumqs;@?B~y$4`E_)U~OlQplk z*SWV*o%5TsM(W<*nR#o2^4TN2zncq+_p{maHddqav*PfQJ1AmyQX}m+e+xtZ#l`+- z#kb_WHTYkwU}z4~I`!rI!E{t2rC*CQqj!n1Y|EHLwAKJPdK}!2y-&e4?;ZtfgEO*y zf?2#qEi4}I%op4PFRMK!ybY&^J>IJYrnCDxGdb%d&KX0-rh#(=3?V(6dY9w~@n3sK z`Dy7H+s}@A>O)Jn1}#L(u4Dash!$siZjIA}T(2=L+doWdd=75DcPyUlCEn&QV^2u0 z`MxuMdR^yNGEXnb@9LEK`sGD^BM+}*k;d`!I8mLm47<)_dkQ6cZ!wpDyw|5s&er|o zX}dw&=bTT8^@Yu>6ddntpVf)P>MS=e@pc>xYpyoi+zE6$Na@~wdeqwe*uD?yKR!$G zyhU@gQo4KO(73mW|Fm^%@3@}hdfYxjmHd-gD5Guc<gvYuw6!XohsF8JoksqHfWJfx z{EtEve-X*=4Y~IWZJIV7ejnPer+@7eVt3#9?F;Ll_f~OQypvzhgC0%%kwkTklq3$< z_`tPS6w^{4%e}T@?<7e)^}$Rel4z*jS<)!t%c59Myeu>e^P&>-rW$w2`cG_p3@^JQ zsXxg;Uk#ll&F|DZ>tXK%L+nw{d!WL*qaN4mwX<bXr~Smz+oKUJpT#aW67A(fv$$>4 zLQ1p;J^1(_KR+8E-?+^Fo#`J#T5R3!6-l?k%NDMq(OCL<Q=i~bcgNE>T6*QDHY}ZX z-sWX@`eU8?Ib->{R~*&Rcv`oYd=__qo#SJVZLa3bZg1IXwdbb3cCBB{KbP3v-Kko+ zXA^xTYA3eQ`_<95yi5DN+0ZBK{%k>Z=`rtC>{{o4@a<OrT5EBwMbTaaMK`hc=&|Zm z`n?V_y;l^|F+Wc!^lo1C6Vp~p`rm8Tqvj<0^}V|mmaUz;L~yx>AGFuXf{<HKc}N|Y z9~)grTwB~w+*I6J++RFQJVrcOJWV`Lyi~keyh*%MykC4=d`f&#d{g{T{6zdlTmaop zNExXlEhH@|ttbtU21<jaVbV6z&eERJ0n*{pvC=8h>C!pU#nP41_0sLqz0xC6uk?cS zy7Zp(ne?6Xs~m;zOtW%DUPNA6URhqfx_<KX)DFg3+2=a7uIoBu<~KRP{KQ<4NGI}% z&ctGg<q~}pYb4f(`^j&f*e<b4Vz0yjiNh1eCQeD5o;W{oY2xa{4T(Dv_az=p%uPI> zcrEc>E|K^w@m=CqC88*bp_G+QWie%0rJu5<vVpR3u}^UsWw<gz*-hD3IYc?KII%dc zcwFU}%E`HsazZXs*caG8w`^{?+(NlUa*GzvES{}QhUIK!sxqxORk<4E8<acr1B%m% z)0F#)w-j$}fEmi8#k-4lEAzDTwac_?w3~}_iVrFCl{b_RiZ2vjSH37dr~FXuNuICW zr9GfMq0K9Qpr5B-QXZ&pRNXRpS@N3X&B?pcyQlZ6Y)~1Zzo@@ixu^1QN1xQF%G_k1 z<T91#4b`|Oy;kyp^2qYw^0wt+<=@Lcly9l5nd@I;fK?7ue$Ne71vLTdj9O9`%59q) zmK&)qsjiqCtqxEJ=Emg4=EmnHsDpE7<j&7smb)f*bMCI(1Gy)1Pv>6By_NeY_f_uO z-1o)zOD~n)s4ScNO&z9gTUfZTcwwo+3i()J)xxTIGq2^V`9Aq&@_qAb<k!#l<hLw+ zP##b@t@?R>RDQ4gf%$Ry9rDMOz9@ZP{M=6IH$pj9R?B+XELY3jz#`UqNm!4r^sAhw z&DUP*+^ln(uKwlu<tNMYDw~&QA^JAu2lc}%IsGwxXMIn7&&q3+c;!<4Mt!C_viN=R zdv$d2H-<V!Uav5`aF{x_aEv;>aB|_a!g=ZhbxPsV!gTelQmnG5zL|O<yvddeHx|=H zvoN!8cj0+pe&M0Q9AIv-TGIaG|I-mjmB*CF6yErc|3=`y5%_Ne{u=?u2)tiiqq|Tl zlsf(n)GJDhs@GL_sC?w$y=33YPnEAK3#y~4qmoaQ->7U?xv6qn<?4>A{-ORwMb~Fn zcF});H?*<j8r6NOW>rhBpM0izaP{!y%b8rY3U|`qvU+Uw^y(?ex6{egKB<E{r>7t7 z+M;WV>iNl!i~AJ!E$&y`zj#1#O!2_~YX6PI|COUay)F55@;h;-_9(939))%O<NvD> z_`G1}o5F(fismJij!K7lxj93<M}1hGo4-6iBY%tfe12B`Ctza!%>0A-FY{mJ|I9y` ze=7fC{!R6@{D<m$`3v-?3X=Mn`duMa$Q8=!ubNsIQP{1pQDI{(t5vjUv2Tm4QMAa9 z1!m<J6b2N=7G@O|6#Eqqfp^C5lol$DEKMuDQ(mY%qI@x&^*buVDyLTFRrTt|)d|%n zI}#m(J0^5Inc7YruRf>=+CXie^abj`)T`=1f_A<6qxoaHoUUoK&(quK%cukO&Gj?& z=aNQp^V9{&IcERH$dt`PjlGTQ%$dea@{TyOUFOuxyxgI=LyaGEGYuVTO=B!gd)r!> zoY-0%jruR1jznwa|NZexDXDU6+m2DmiP@QL(LeiRTO8Wnt6%%k`m*{8$zMBv%yh^@ z#ho&D>c1zC#H^jwbUxkLwU&OYezJaA^|H<vK{qq~MfI9gG^M7pnGNJE(64%P^=5f{ zai^}mGf#Kznt7>vYvWmWuTquno3eAv9&_XF!;A&SUs=gan0j`6w$QOm$8xD7Q^!~D zsy>ifB;CK$O#P7-(;sy9?Oe5Uoy>0OJ37ymcZHtapLx9VlJtG)^U@cmuS(xQ+vs|& z>v?0KF}SO<E1x-)YN0=3X5-B8%!tmXIv-2_ZVc$$C_PBt8}eM7xk^5W`E_q<+$JA^ z^{(Z*7R#KIosc~(dmh%aUD-vlOLwQbCF8=bKf8W1CUyRiS<@V0?riSN;xk`mzR&z- zM2)456;W&KZyaPCVLWU+DId?gsARlj9$+3~9))%J<nHsbV=8;K#Qw=R%&`Sj4nvY= z*Y*tgG}_)jUCL*5Ki>U#_SKI5VWcKy;u*dBX)|Ybq&MmOvh%~tvYCGJg^l;Pd;jh| zjBkj4=Q5qkq!;V#lU@$%#v+Yp`CoX-m$sX=^JpY}VEQom>UMKA8{hqwxu&^(_e+R; zlekl92#>a6X*+E|Y5UUVrCm#-OJlTw<*DVV@|~m=b5G-w@`UmPebr=@wp+TqG(#I) zx?UTmZL5teP1i<iW3;iQ>q@twrF2#4`qJ&CD@xab<=E2L()iLTrPE4BmQE;5DxImF zQo5k)_z({2I<)JcuA?$<$@kMX+bQ9E{s)}^9ZMr?RJuPhhs%$Xtlg(&SC*f4w;(@n zF4}!*cC6dNH1ccaiLBO$lzq2zHY5E5oTuh?J)HTdkyzeGey@8c;}z6oSI@2?f5vR7 zhf{M?&!=8Xy_fnd^=;}$X8AWH`K!#nUCGQrupE&&HgjU;#ICctZtJ?Id-1LdyN~I* zqI>!7le<qgt}w34Zjs$KJ2E@E`)We=hVHAgw`K2?e`<@LwbM)YBJy8^@)<k{nd<+o zQhQJPRQp!@r92kVBf6sN<r(E^`Z~!Sk~=3y(Y==3r`jiZaC*nmvf3irl9@&IT=@%q zIy|4(E%hs{Rvxc+=!+V|jIBFQN*~jCXnHGiS+gI;cHZbDJuf{!{YLiF?3ZY-E|WZ= z+PB&_c}nW6)P<=ls=rm=?}&A1)$dbFr<PCkPpy?&H#H=+d1^~S$G#nhz;Z;#@g19V zOzJob<O@5l=(x7y){d<}zO!S;j@>%$?|8IxkIwx%ckbxzc%kF<j`us??D)Ln`_y%* z+d9@lQulOD>70^2Io<YaTi2ifh7w!mh76qfyy<%H-^AFdV^DXOjkS$Evg>Duc5mo~ z;c*q>y<LrJt4}n*9PoM0<~N_Ky`D`q+M3(1>$9f#s{4L_vX^GB%HE%S2ywUMttmb7 z5AwKqYKLj3dzE%DpY8rB9P=IX)PI-K)4`ax{7?HgrTeQ^G0**<_AGqAOtBv?|3uB4 z)$tp{e6VZMzlr&z=QHHa?xrzcY4s>@#}#+@SLrE^`d8WVU)_2f`+s-)NBx7Z8lJCE z|HOG9sEvQ~j9|6>uU@xxz2|vOYU{PU$&5{({hB{t21c~}it0X>wxSW&LZa`v_%Qla z^b_E7m&NV-p8T3TU%p$uRK8BW2G)1VSIM_P*(*OR-!8u_-zZ<?!2|Mr@?#eB!S^GM zcjU&n3fj9xeome$KP|t{@uu7uSIJMxm&=bu-{XD?`>%-6Zz(Z>N==nNNImk`@^{ka z@^|tV(jaNg=&#cD(LdxLrM}W&`BQ0A_%-foz&g>N!MdKbCdgoyR<Y=bNepQelc{9a zNyGWNG)mf08Yzv8)gIE0u^84-L-kZgTp+#{Vflc6EGz95%f=MnB`xjY_VJE^UmSxk z=Hl(r9@0V5zBE7eAT6SWM9~OoFX>RbCZ@2w0sVw_nIFyO>CbPi9?QoT25`+Jq9Ju^ zrFJY4s$Vo#a>Wxn`VcGirBV4<mlcD4T{V`7EfK52!q$sQV`D)}-pY<G&^}O^FH5zY zpi`a!o>%7C;&|Tx8RM+w8D$QZ+G+YJkZq2&P@6}opMoUETbz(Q0ZOulGWAgE(Hbb( zme|tLk+G$N2(t&pf^E4Fd%bPtMT$O2pA=iq#cDC0Rbs2e`o{W7$H96v>BQKY(uoL` z=qH^LTL<kF=@>$6Md_GWUoFmMulp!(0k12sD6i{N!od5R{i{rorYOrvxL#3%8^PFt z&jg3sNu5+<LUI#CIzu``Q}q-5NFR{i7nj(kv2Cyv6hVpYn0f+<4a&{Jx~1DbHaNC# ztOphVe5?iJQPO!~2#Vdq$}uWdLpnQ**hsqvjf{;-9}q(hvN9eJ+e3L5{(o>zY%k?q z+cG@1dCYIY_&s7HwGFlPwKMgz^)ujq39wF{oScX#-$+-)j)@%y3qnhfly9&mUFPBn zm&WbGG#5xtE_P|09#B_4lP->pjU5RKLQ9a8&#c-pplx(H4kEmK4^>u!f0cA8T}FrU zf%1WNiFTp#rSdT@p8j4rTG!Qjg{@+1e3_aHV}GQzV1C+vstc$q-@y3rejq1LPo9dp z)Kl<HNo~<%x)8Laeog(1OZv0)$3cs+m9d4ng1IdGtK@Tjf#hd5kAR&zFLt8EBv_wP z`Xx5yZ{Q5bbAj?b=Fi=myVrbKNGl`5NS@{I5xdw;>e-rZ29%ds^7YE7<hjYI$#aFY zo!CvSKy#FSuSHLfT|ssBQoo*HzLvW`J=WsT^r1=kzm+~+zXG^`kv@o$xH31hnoeGx zxHkJ!Y)))mojFizfb@}+#0_5l%A$6(wGimZW%|X*ix}DOm37?29*I2|n;p9cZUHe( zS=h?|BCMaO(Ln#a`qZ9I`9=AKWdL~|)Nt{n?mJIe4?OO$ack_J*j)hCJ|BDDl8F}d z`V4(W>~S~P2jC~=Cw+zrKW+gM4n(MnLRK|YP5E8bT0y@FQKP{qe|dp(Y?JuppRJSr zJsh?8H<D95(5{5Ji+xFFJ;=jvk=jE^J1M10X&p$XyV6zRFX1ovrDmUUpRhN@S^+2n zSaNi12@LBP7I~8g{uSsTEPv!vCxxAP!s4@ookT|SgvD3CtbP`Gz@M=A+?j47S24ok ztNZdq{&W%+AKfsRu=w)+ZlW7A!s070L?;AM+=UR0dlQzwdQ32dO@ax{|6<i5dI>4% zn$)A06dof)zVIeA|E*Pv=xyGF#V3CRzO(pIc;17M1knuq-#LJga3MM?h>p-%9V&~t ziS9?JELmA3to`crV8Y@%1_TopAKjvSLJ-k0!Gz@xvMW0(I|{M(vGTa@K+u#Xxn(e} zI|Dkh=N^rH6Z<Rnmr#m}cHn+lmX4NoE2}vpv5qlJk8<pL{SML+tSv09)iQX(NhtPH z@){Dy*0FD>98bg(;FrL5F&_2GU^kZi_t@{TU+REtECat3+@=IuDOB~l;+lSsP>mNE z^e#E5L77?HlGAF{E8Lo7NP#A2p~dU>-iKKeEg8$WL0V0pNLwdm9R4Z~K$bXU<xzUv zSedLXNuOAb^4>MME8Yn#E_B70;?W<8FGY2<<n2s$T1lPP3SCfJ2qG4@!1gRaOWQ_E zAIlF~4I;jj{)j$XpN&4srf$qP^#|?oh1W_uT8xB$x{MSSjxQTuBfbWd>)H_(COTT$ zt*qvZq*40g)W^!O0@RkZ+QRj+=~FE28u7KQa_#uq@s&|xRQ5wZT90oK-+;E1KBX2t zAnvBW{<s-s(D-_}sIX{!qxhDv-jX4JmTGF{*62gEs3Uq_N3Fak%NgG?c^#>d7>M5} zzKOMLQp>Ul)Ip99vlxon^d#zyWqc#PM&;D~a3>Han=3%_2z^eSdHNh0AuO7EBECCP z7UQGs2uqMUE$voT^S0;a@*ctx)ol9g_;wand-2^N4(lUo<#zF%g(Y~<DlCycJAHQH zP1INOxW=sMDd{PeyldPApFvon{9O7BJH<<KPsI<6A6QPr54R&MP3p9?TUpK9&TECG zg{Adp^yi_Sed32$YiJQXuyzQPum*X5^kaZ#A665Vu9o75ldP$iQZJ!J*~X2qbn4aA ztJT-}NM0_D$~_xDA$~$-OnjmpVL4K#rQKSuoe)0)NuLLPkSBfulqXvpZ6=D-gyjgu zE0OpSco!K);T_Ba|M7rmh#T)FeF1~S!T&)nV+bo&4p#f9eS{U&rNR+bM8f@uhnFYn z+&OA_J4p#X73>qN0j$A-^~J4aaVSB<$i3hOtyauJ%+DtEjbGI!r$hYZ@zXiZ75Wn5 zr^c_Vb5;DB_*opMgFH2UsRtLuFQOS*E?0@)9lu+EwXjP0Wt4GE<nqf5v`{OR`8vsf z(JV{N??x!^jNiy8&$nb~1)?6NfcyX~x74|@`WDo0cVorf7rzgFMfncO?Vwz2aapar zSXhlpN?jKskqm5onK~eSefoM~HG;ASu$Q&$r5p;<p_T@<dno5w`U8{$l!KHb;f_)J z($-DG)R3Al#_ypntLy>&BatL0ku9sGw@K=<NZsG^h5BAZFRZ5a2Ug}-fs<DjR!d)@ zuAICvd1HEddPe#RV|jv^GE;QhS})^IGK4kFkAyWTM2<fejJhjN@;-G}VI8Uw)?qTy zVV&vR_ON)G*;$6gHPSAhll76;GC8b0v^N5d0Q@s7m%KB1w>m=IUEQw6?jY~%Vr$g{ z%mMu!-6(~Rg!P2=3hy(pt{$Nt-2#WJhX{iZ^#o7G!@s`A6ARo`%!V+SN4<*UWJ{i? zIyn_IHv*Tc*Qn>JXQ>ydQ`Kwq7lj_7N4?w)>M8mwZm11Q^=|cUZ6&Rr`hd2)dLPst zR-aQJQ|DXUQmv{_x)C;IsJ+cm)>te`9?`d_=P)1Rq+sG7IrubghqDWt3!C#+tIpXm z6MFEABl|~uyd^v0d4I3`{_)T%=3>2n2WsyCZ<3rY`<q~?*|6VsJJf7;lEaqYve)Bq z%kAyIAAd*KT)S4g0ZBhE4A0$0h=0cr*V676wh^|GULn7~v)1d2TZ!w7n~6iD*TvPP z7YX9(bq0!Chy%rq#SMjRl8;f$q8-dCY*XzLwhuzw&6iz7!fxt2>O0z_FqPk2xbvVz zvN!bx!6*wm1|gn<sGp`jOus_N9$NUK@P#mv0QY-zAx;A>sqv6lL;X(uP8iiJ;-g*& zdo+smCt~tf;)d74UiGL<T?&rQ2zz;BT||&eiO{vMuLlPt7D;rtmX1U>Xd7AJMjVcK zqM=$^>()o<ql5#51C&*iRT6&yizSxSM+yf~605g{A(x&n-zOZJSSuXiP(=a)9*GTG z1^zp@voKa$%n#v6L|Y~deP7~%rErWB<Az|A2MNM)-eeaJ28V|soal}CGlkjJKgD0+ zLt58E{KN6lE%(u`a3ZszOzQla*)1t1<)yT>WZ^EdC_74XDRZgn!on%R*dl4hyroS; zPRvTzS&*?t$}Hxka@~iIp)!d|+xt;nSQ`>dVyDEI#D2Kw$LYr<_eqY1d)5*TP9T#L zrzI{CCMC{HoRgRaOn`gYj;k+6C60o-+Mb`d&|04le&;7nN*td!N|;2D7M7Ni7S{fd z78a%u8SC7#oV2vGsI&xVyh_yZdRm84m;xEQ<elYR<-_G8<n5r`RXAH-SKgq;y7Ich z*}@r4v<RX+BCi2=1YQv$Cd#9&=$&D`k32%&8p^}v{pH=|lR-McgG1y4!2_8n50y7+ z9q1px$2VRlvD(H2;XEg$0}ySCMi4Hb6#56F?a(;F#cs4cd4$V^%hDh4nlQQWos;UK z)kQH+V`#?)aFoU&T*24sGRAXW4a>(uK8O{rz>=(4Ni43O)!M<Hu-@q3W1Fn*=t0o- z@qM@YLR+N$p>?nR__i248jf~Y3y{wm2P}Dl+eyBeeABD9d<IXM^ztx%v{FB$zO{0} z#I<1v)3uX?>8+#tKB`OCO_DC@N_7cgh7<6~Hvs-XCaWK+A1Yk$M28!hg;LT>!cE@j z3;QA5N-R)z>0QFD-Xz6VfxCBqE8L;~ge0Q`CJT2EP|xgE?H3)OcK!F7Um}^%|8f(2 zIZUj=UBX?=4{L66KQxALk8n?8p3F<Qr*asp5h=NXH^OXhy|=beZ{io`EzAz~Kzq9+ zS8fI2K}zyK;Bes)LUR9Rsl^?VbTS~>GQ#7@{>gP)N0=kbNv`b%^^{WIV3Hd!gn7ce z<OaAj2Z_LF5^vQvN;ZM;jFaR7FLFQUelA{HyjFNI^N}}|lOl^F<Y%G{uOq2QN(Lgr zE5a+Ocq(qd2k40Kx)&W=>jwps>PVHXrJTwzj9rYKtYrrSFuyjx5Z<Ds3h===lCdPX zv038??>e!^3hy>uUn~{OA}JTb2aME`4B=z*JK<vrkyFQpFfi2*5k4bp;WGl!!g?S9 z?3P4Jst+s6xpEFOrdC4g*;h@iZl`QeTdn=I;Ql$3^;7GoR(IGpOSv%iH1-s}ByiR( zQV4pJwJVOsV42$3jj>xT=McD`&$a~N8v?D@%dP6tw$z6&;mxU@S4zW+H^V)?YLqMG zV!6{=-mHv6s%rwPz}<!TWi{dZ_DLOOF)lSOH3k@$I*d>`O85!M&a-$Xi#!j!n0-Dn zl))cO=AY)D!Y@3j<IOerx>Gg>=!1eu-JF^RcT>6{b#3ZO;I`BysjG$G8R=Dkg<)AO zy(Uj}ok$c(ujs*g>Gje}r<a5Edg&!Va<gdKiOZ+DUUj`lwAxc0RDQqw4lF?B_{y=k zL_`YOBO+N)CUt5JE~|qP%$LvS<eY4-ovD-Fyg@ciZ<-#S9v(^9N$=PM+oUawF~%6{ zO}&=h9_Ddrl41l;_U)411IaJ!O~go#BILUwh8O9*!YMDy6Up&pcCWE(#?F=*J80c5 zvvs71WJUucEOySgsQHl0`()hgpJ9y8xH%znLZs3dnd@p?Rh${=w3E37xW*0dm3i96 z!x=B0%=AVU@*?wC<{cN$Wf-qzUbAYoGSbIM=1q&|Y9*=R`nk+&=$m=jjisNTc^}Cy zN3K&^U1vURnJ*$sMV88Z-71k~k<52tL{<nQv!Hn*D^oH*W`6S~(w~s|voRtAyfF@| zajc^}%s4o*Mq~}+C>zH^4Hx8i<9M)#eDBHIBWt@crZvnZ#smWwj>x*knZ|{nxzJj3 z7R&b%@F$?<G&_-XA$qcLz8kbq+*ad!YQxev$HtY$)ipqm_WZs9>{U5G`*HTc>{~V- z&pwj92l&8RqckUXb?%1TwYh6c-xr=NJXzT-vH``oH-y`a+l-mU{l+Yd`y(6K$zI<o zkxdZe4dYpk7mW9SnkF(V`?~Rxo5(N%`eg;<hpZ6UvN?=Dj6bq5<7ea7Y{?=E4+U4X zbv2vM>XEG@TYLSD3-uKHw>XjQ2yoBk7O7`gI@>Uj5!ofOi#k{>+c1%xk!;`WDje%% z8z!=AWY_GP4hCf#AhJ6pyPkudY#T)O$&Sj7s%{$D-%Ytc>T)LqQ(DE3%7n;)e-Gx+ z=E>dxcMQBGa)=+<Tf@N&c1o+!eA%0vPzx!|`R07P#$GGE!mwLftC?Fi%_b%gIXrT> zISiKFIktv-o^J=hozE?a)V4EsHFu31VF&JyZV@@!9L<Ov9bQKt28%_>9*y<<Gr^eq zaO`iM031Szj3<}}hH$v)qB^{~4X`<|4b8*K{F>&;%@R3*$D9~M<mAZ7LH7JQ!FKcR z5c|aZI*o(9abiAg_EKQp%Q}Szh+I6gv>tF|>B!24m2WHGMkW$E)~-H?un1l%+*i1d z_))EuWxdi{rMJot^O+jG_h$72ByuW&)Nq|!k`OtaO3jrd4%d;>$=WNPWv4#qO(C%? zp88-W5=k^v?<|QIi6^a-DAp5Jw@a+Xd}*7!#x2vn(+spkPhNIM5)F%QP0B5nTP!Ft zx0a1%a+K9US{@+vm2xXZ&dROoLBHHUq`Yo<?ef}{(;{ct$-f&+Zeve|<kkm<09ybX z=Qaa|<Ti|)>m;{Tb3~>RiiKhUBe4tuy@TwzT`1+R8Ig+!<xj!7QxN4Z?9fP3=60yD zTh0&Hbw}h<p4{<nZ1xE`8<ETHWZ#AN0`F#L!}<f@V{7>gY99meJ|TCZCzEsM<Z!_? z<NVxd<?pJa*uUN*SLJu~Cvr{Xn*8>4Mq=Gbeh)(AIxq60syBHNy_sqYy@iKcA#x+3 za(;C$Pxhz+kz3lunnw%g(y|e`onqJXHR?f1-a=)x<PXgskUuDYWd0aCkvr|sarP~b z%Qr}Q148xV$lZ*}5O1hQ^${w0m&IiYPv<8U=11<!pJyj>AJNg$Ze=xRB#q)d%1;-b z%b%S;F+a&#CP6vL%1g^B`6>A`P*YqU*OdH;RD!G*=Pv-Tmo(~>JO}Y)8Wzb*`CG$@ zJP_dXNFKS1<DUHN$iozvH_ipMVOd;>09Tvy%0HHWtXxu=R=KcpVdODFai?HlF1jX& zJn5vp=*W}KcxV2wdhn}S-TF%Y_554;cO$({^54|?Apb$+X+r+vI$!3$EW8YJ_aUEA zJ1g_QP$JJop0j5A!x{e=-{(2d$4>rtnE5YNh!(WSd@l;38{Q9Q4QzwR%LT(t<YfZB zAXhI7rm#?*N}*3(X4=kzo4Pgf8q7-H29Y;|f4%3hu3V@Qd52=%jbvD1SYgY;29fvO z6o$HqykFRW2kIerHDPwvLQOXU=6h_4$VWVd-NUipv8S*rfoKck0~uX70vJt*d>#4P zsvliA+R_|R*uSt(;lRQPz#+il7AF)}4`9_Ip<l5d=4+ep3MV&4<U2146TON2Nbt5Y zE%l=%voML;uw+^y@is5J(;w^TSGlrsr8Bmbdg0W<MTN5prxz{<&MjOXSzxCy)eY}a zxW<F43JxN_c~iKtxLNa*H^RFv71y#DQXEo~)+%mXmj=@NG8H%UV11aAcMFU4i(Bzn zUsaPYtXo_c_iTiyj9%=IH^trR>|NxDs>Qu=Aux$*?4^%=KmL|(`NxAP9@Yr8pC!_t zCvs)+;6|{=!_44}ql$!aR(Wjk_~Nm^QPE5g+#Qo%EfStBB6EvRA>{@1RvE>Y+|+F^ z6kjO*;3QgbY8t42TYQ@ba`5$Ui|;{>pMlSdpA<id!ppyt;#VGgSPXz<D8)(={H)cN z;;&AkWuEfx!4&`CiFWWcZ#mlG^dfa$i#~)7_|aGprJmBql`Se;RsM)}dr|qd@~fAg z>ikEBSfYzW7lB&{`2tqOVI_5IjnQ`SHh$hj7i)yl5<toNGHZ!azO;0W<x0zy7A|#_ zs-;EURIV;999^<hEe|dKR=KuvZFI@j3I6pYvqqO8lvZqwdi<s(AIiOy%C?N?@^-58 zkmyRj92`BkW8EmMy(vxMiT1-9S@Zfp`M6S@Xg{QM94>SX(uuH~0-S+5J20!H3*Mvj zO>0C~C6q3Mxh$`UuI@*5MlhvYy@;+wsU8|kX?E$s(lfw=FyGAV(mm0Ec3{TMvpJ@h zrq^mSzydV*^O{I>eQ(Oc{K1IIE`(~VV<V(id#3tK^f08ns}DPuku6>9T;8s{b$JB6 z>tpcQ)z2Co5*<>r9a63n-56!EX4(d%1Islac650(tg${CmVGcEPx)wIJa9N6x|yBw z5pH-7-+S?$T(i*fgy<Gtl+S8_)5{ZqQ-O2K=SH{U!P#FMA-b(M<%^o)((*OvAKigc zzRt#t(Vgs+?`(iu%3j=FCfr@F5#1%6>UkmjQvHkL_i6yq-P}}?%@EzwNu|S1bnoci zc1>svezpr_2v$7GL|d+y5MO|$jF#qsdtmxdyGLesg@^erQ(4CH7*kokU93A;`n-P8 zSGCFx2-Z3_pgO*+>_p&oD2Khe(6eI|CMO~1NOE4JYkK~~lK8mRa4tp2`PE^y*`kMa zY*e#9Uj=9zw8RWv@u;Uhq%F2)7UF?<8687AhSEq<R#vU76h?HMAC-QU^?g{qLKs+a z5j~1hS*vn$of|3~(PJB<GM6WMeDwIrT(ai%sKYv0+bxdTZIy>8;QdhLQ7hYRmD?&$ zRAyD40u3%RE6-N$tvri1JC*z0@E%pAaiS-+PvxaXh)xdnicW5n%BybpSofb6qo@5H zRNiwFJ+tx#@OJb}kid?mAFivqgLqB!oa)%>*yuTo>H!Wy?h6ffjXtt^Wb}MLs>ks} zFQhdhu{zb;OR%3<odleMM5mFmxwThRbQ+~P#e*|EbY6Z_qE|BNZ-wCvG1ImxS+DkI zR|ywXEuvR9PW|k|&O<gS_}hUnYxLUc#crb4GW@@lCYHdvO<xhcAq@Kcv%O^BOA|e* z!}@wJ{Pfh<X(#pQ%}DhQfA9|E{#M@NzE?T9i@E<gI<s9mL<_CM3+pqSpgWOMTZiE$ zdT;x5<QgM-zc(F4VA+m79ZUHUeaO$^sqX{1FsDWIAp|t2TO2NVR{%OaS*XJWiLT}F zyI=as9fbZJE~1ZeJP~ahykB|8Cc%WYq95Qzb~+NB8=advzj-jOU9`!q6MZWBRQ9e$ zsm>;JtPy>dVLsP7(HEjG6wfK16Me~_(q~~rUk##TyI`u47tuE;!AA{PL-GgNqi;vw zj(r?^-NDD8L*6wO%l;nwOj$x%I`&HJ6=RX?FWFyWU)nJiv7$fLZ;gG{GSGv>&57HT zL2hCnq>oD<ll_a5d&pSQSTglO>V@Q0xb|rCONWlsIW26*@3FVQ3%0U;-{bn-l1<UA zvujMTv`1-=^ks0L<P(DLBI>kiS8G=%Z%^Kyn3=rAd>>(VDQ!`DIu00XQR2PrW30}I zKZp7M240KLkGH$bhaAYu$`$E(z%%K2t>nZwy43HRNbmE=?$1ahs;8yHE=>n!h;iu- z=~mz-ad~n1_!ksyRp~A<BRwNMFD?d>3B<*2v0IuhE+Z}}T_685{v)uU&Tlp8YjIVv zpSY5^lJtmJ77NmY(roD-X`U!cbEG+NVbLu;E<KJV{DGHDDX|FLP({`5RbK;MCTO?S zn5Dm^zn**``LH%K`EU)WLH%ZN2OHapJIQN{J1EnY$JI9x?IG=<<dXzrLt}_B#H{3Q z&b^v@Blkw()6!nz-oWwF2jZU6TOb_^<p<(8@py}IRFXau_XMwxVSQN5h8}wY`$=y} z@1hkVzqHCR;sog%%j@7;{7Fz7CmuymKT_Y<-%UQJy`;Sgyr4Z><5kcQp3<I8KAn0y z^<Mf#V`D`6N%~%#ES^S@z6TBJPLqE3Mm(P&{o+PElY`y|l9m_N?+kef+$ECKE`$;R zAL%dYFDi4MG#X31yQFo0NjWNBf{P8zLi5#fiWk;$UZ{TIM0>*<Sro67MOa@gUdbd@ zN1b?^c(YZ42l1l5R-_dtUX3wWuc3+8g63MF7DM!;R%?mmvsxzYlPs(a8cU<xrJNvr zrR|bf&|L|+5^@6a(){+4v<+UQ*L>-2g=8gqD>sdX(ox6uXq%juJ*Oka*Uuhht9iA< zbT^={_O?IbO!aGVCdd8ay&^80PEPSPai;vI{AXP=OPp1gtr(bKCSupLUQ@r;K2*O( z=v`G?E#;yc@d<ss#z+p6I~zlsD?a6gUo`dgv)A<t$$^N^iqBFH?Grch;_~9+3vwSG z@r4>Mi58X*NW_=e{B&|3u!ARhK~BgHGG?JUJxcIFPb-qNNF(Gv>W_A`&nf!$`u5uA z;u|$yl~<5g5MLEvm6yUbk(iv^F1eldmG)KgHFW_-$jgdv!}138ZK5PC(l($?(k{sW zrxZ{8@>{)r57tXzUtzs$U0Oi|y}CeMpndC2^5xWN;)f0LiFp+weqty0p7<4^W`mk} zjd_ju1K{xWs=G6Kd7)13?`J_h=3%*LU$d9hV!jnE%*D;cLGwBA6|rbPYd`oc^2%;% z`FyvG^});2ybA8U+B$HXzB*~^uB=V3gYU|!4Z+?i+dKLQt!lp}kFG9UT^Q~O>v=!g zhV|?&wB-J_v>uk1zXvWa(>T!KJ#qbjEn@9q3>Rm!QNOIErR!3Yqg}g;F0?`k-|J!f zl4c?${JhKtY@Je4s<@AWfd16)@oV*s-2<533z&E?J@$+0s6>3J59vA8g>47*CjKll z)7!VSl^PzS?O`9?pqh6(wU1lU?;^Pmc?w?_zE13x*c&(u*c0xB>{{UN!`wZG>oUDx zvGd-<RPQXEIh^*U>u}qp#xUgesmS4YTz}cF$Qr!9s$UN|{RhZxp$|?xk+?r`Z{nfE zqw*&5FeizpK-(sXxrw>*mWekKZzn#438@Q-UlV5Hg~YSg@@nFx1TI+5fSu}T`FY~o z#8-*0;EvPha-1$V#t66<_15yy@_4ut_E{XK%8fzd57&F-1?`i)fFl0}+iE&d`Vtal z;FHA9HGY6wv%W{ZJkfX5kJQI%t0!jF<^;ew1NhkiI;>d$aNS+g6RUIGp&yf2DY1-e zSthYOXd7QJ2k*TM)CtSi^u+31Q!l;`R7ZM6Ys*6)SAtv?ilD?2{SvF{dxXz15aKZ~ z#O^nX!H`5tBzH~jnmRMFzM^}R96?BI+zyq!6}W*-Fp13=$=wM`p2BRcOPDjUMSD26 zA+c5aq|Rv^LnS1({TtXJu>)iw3$EQb?HEz_%uUNp^ZM3{*LfdRjcc>7)Hp6{BRN9f zD+uRw^v&0Uvg>;}kAvpw$=zX|w_|FIwaPQB^^wXc%9J{1C}WiqVL@<iI3kht*@_$9 zPGy``4x@3Iq#S207bq7fGuq^Or9Ey^+T$*zb#7H|RqknnJCr-xXr1)Co%S(yHl4|( z$+E>bbrW@y^y9b&hEX{^Tir-qqsCBmjr2_j)Yk_6y6HR84+5xrTpQ>{-4fWK2FXm; zLsiHH*&eTfIeB|4vTa_xM(4>3n@g{OJPpr}=QEGq{;D7Qs0TW2#`-P>I(=HKd(X4i zxb_;DJMS9xI)F%i>(kZKVHUoVZQvYze*TT>**tl7s&{(KddKX|NKdz%$@&zXe3st$ zTKkZq{?;B1&MU^IPjE`1vx$YwJl3r>g?SxP`H-S5(ms_>-1yDT<)L5FL+3lYm#;6( z_oeSk=k)TQ`^(p3Gp!ABpJ>}M^l$WUw5^&)|5E=lxkfOol@_HY<}vb|@n~<2vWvE# zcCf{s*6c-NwB73Lq}d^UxF){st+5BJWtO|y{4~<PH*{OE^!Ey};LJ@hH;-)&9)3Qa z0NEa6n=i<7wjZa5JwABGBD=3MlYiYF7u?2CVe<`z+Wq_CZwc!YZ}-pQZ{gz`m1(x) zwf2~x{S8#U;;G(Ky{GkGJJurWudwu$HlTbDZ0`l3f1rPyobN^IbAs15jQVGG;QPkO z$(Nm^U(b%sj!nK(=cDBNsXqwjr|B=vPtBFhmGwm%U~_#_y|x%}Ba;3;{f)jv2uthj zv7C<d)mPNF(T7_l%0UZ>Xm?FpXf+SUW9%wEtm&io^Y_!QsUv>YaQ$kvSkK=j^PkX! z$e$&*b{=`D$@b$h^;P<HH`$AUBa^8%=}a<mNs5tN++v|xNos7(^!RtqJ~fI-N@wy5 zA3k;HSx&daT5;PJul<pf^}aP}siZ$&C+nmI9wTWa(?21}W!t2sdAqo|zCx}GgRdIF zx>1{KnQV_AlkM?avQZXz&6w42v`;IkdjWU~rei$T&1ghir~eAZngff@h1E*Q%_GHT zlxjj+J{3T9#ndwGP+cx4dqcLFDLWgc0-#^<XW(l#0ym$OYyPN)Y}>MVp<0r5Nwvcc zshwJawYhi7pFLA{c1!J-$-#7Nof!?IG8&XP@6?#u>{AEVN~S?;Fk$nUh1py9Uytpd zK(kVT(0T0q%G!10C#f37X68jTI!)wKb0Of;+}k|Gs|lrj>#rKts|9(@u&sYd2V*;b z<bDm{kJ6#QPo+bvuM}@E`y1O@XQYK;)-9wj%(}IX$AYtQp}tWTt>q(G$(&w&A^YI; zAXtz=mV`BH$*h1F`(+k~a`BpN5Yz}uWtKJeGxkgOq<b>!W(N2!0|IOi*WfH${<Cq7 zO#cmp&$UJ7#cE>>pY^9_ryl|E)BD*q8S6yzIQfnMzZ3A~CWs>68<04%z7_l*N#Enf zSQY4JtdzbBc#A-;KC?#x@Gi;XNb_>5j+!IEUene*h~JUi(T>ju?${^ux6<pX^iSCt z*%Jx;9Iw`GJBk@2!!L9K$v&BdGAUzk^G9<5@ME3d%-{0qd<+m=$5;Q%$^aZe=DOzE zh2L<Ui{~PFm<T3caxbp<pkvm{wgw!>c9<7R8vsKy!`fh|m4oCV@+NRuujW)M=SCS9 zIXLN4>hq?NS<aeYvl-ADlMc)vhgj>wGlyr6XcL%Y&6ATeM`upWO!TyQM|f(@jm!-) zmu9AVE*BZynbR%K&6##GX94GCF87S{%jcobFOgr=T9(c)U5w{UYnHehGp$4CnRAx+ zWf-?-D0gN6qmX&PHoKgCt~pY>JL86B442&V&o!qBoqsK4ezw~DX-39-9<@+ygY&ET z&B8{1hmyU*PVSQ8Nlr>Hx-pJz0-Vcj96;xC!+I0*vw8Y9K0lkc=M6^dTx;AMGP_yW z>}U5H4~3Ea(s&~KjqyZ{M-Ai&_}QmgUb(!2G1uZ%<L$P1%6JtZx#reo)O{YpS2p{H z2J*S_Nq)tA-~1~1Rd6P>K)wa*w+Q~snUpYh8p^2uAuu*Lvt_N#zeZ+ZYh}G+wpEtP zA`Q=y=Hody+a8-{H_dLJ-LWY~f;TSyFzfb^eS2twfb#I{=Gkq4J#db+>|SkhKo;58 zg67({mJ{{3P<?YH$r>0_eb?~=Y_$@vesA$p^_waz*-4&E$sz}p2bfc{=b2NzKz;T+ zyplEhWXGC)2-ejsy{4sCw$>-G)|D<^2Om?r=7mpXA@*E1*;5GSjppguGhpq4%{}MY z`$_rL@~c%QAl`PS#Vw;-STE1W)-cbq_bz*OaGh9jB7yQpq<y<T)-Xr*Y?2AehVN_P z?TOdn&LtOzD{`QCTX}IT3x8THfc1j%Qsu>K^E=}l&+l-vzwtA{H7*|k^RFFYjt7oz ziG8^F+fZ(LUNuL=sg2GI=Hqv#d3)*g)-fMwnETB8IA1DbNf(;y;kqBOP+w~2OU%mP zEnYJ7WRjO3(J>#JlwU8uUcHC@(IJ-nAa9Bj5I%o?5MOIn&JS|rW25WQLsy?*TTy4V z`mhNUZU>p<csM^804wP;u3ho9tqkuqi7ebs%38+B#Tw!9K_1wDSg`-N&DM6f)*hqb z$mt#D)RH`Gl!=|TYHtO-n5W$qShMzm<w3?jS0>=GS%>YHq+?55x&8JV-NR@vt>f!e z+smAt^#YC`)_U$r^RZy42bTPTQPf5<<gR3O;%TpYw^O*gaCh;v;%VlS7Nj>shIL^; zFmw*cHcM_cNuNwl!;F(&UTxgh3GWD1ycd{N%;dT`_*<UwdY7EvG`C28^V}j{<Tqy& z&7xV|vG|ak%H+!A+I)oeSqqz~ZJTS4z}ftQX8J>0`3pK*V9Vv6xjl0S=f<_k!I0x% z$mHbU++mRUC}3RfSYYqme#J7md0c**$~l!Yb7S1(hZh$qE>`R=E?HdCb2h*Wo6!Ei ze=6IUTuvc=zU9}PmeN5a!fVZ)f!yaLUc;ZCQ08r3vh_NLUWGdgce=exYr1s}X=?Ky z`p(N2X1C2NNM{CYqIAp~XrD!}fm(yJ2Kvq}=r<4E^?Bqn3nJZ=zXED^05h!h^x~t{ zFN0^L3ANr8JlnFbbx!{I8cocC=bW?7s<V0Ii1cxNUOA`5yI!A1j?O37Tv^aUfWPM! z68Ycl5FP0M3W*NOt`$~jnPm$|$m_MuzIFjw!-B?z&A_&9foDsY?`<P~4mUPKTZ__m zg=W~g;ABK|v%tB$gXeJzw@&n$X{-qy&L0*8&NFrq%r?fr+NA)lPYsL>%1dq6724yL zLR)yfhM}(TBf-yJ)4vupw{b%@+dO9coMuhPI~2DK^$wX&G<ddAu<p_(4b3kWFbCOT zjm&Qr;4_Y!YpiwosQN5t{yC@*Ey;{%wAN|~_k(SR(lOptey(f`Y*swq!G)#493L=i zX^=1Pmg<xrvr{}D>sDLX9_5GX<CV=2i2T48$cpb>c&a;AM^?9YQeLBYzc;o%4~AO3 zr!{G?)jGe;;8lErj6r2%J|47e4BjQ%$!VC4N$(cl0O%Zdt&|ww2K5=p=uBk(CC*&7 zgzKvxfB(iTKC^@Q%^K#?Z(jNvs0x0NS*l7i%72#sEL~rNpV7)LPcNNUx}bD%>88?6 z<xOC2uFGhA%jKL>BivECr*v11$4m3-@*@yU^?cb#PU7S7U3KZj@&lC0=YCZ0LR$X> zyB6tuKGy2&ECT0@A7~BET5#sT^9j}1pU+g=co}v#?NIxdr8cO}37fws%<eP0ncu8u z|F5=lfwQZs?*Be#p4^#aW<uTx=1yh?0tqm=fIuK{E<~}xKg_)-52f{v8B70G;ZhZO zR5>9)i1HXf2v8ma;Vm`;gol85BM4}1odR01S}y`x5q0=uEv?x9|F_oOYp;cZ*!uZT zKFT*MYp=cb+Iz44IOop&T{(SU*dOy}!<&9%*dO*U*Dv_v{@l3WkNfk51^?4O{+q&h zy<7N8{E@Yd{!4#ni5ZDcEO-Kc!~f&okBr*M!aweheq+`DjNa<ol1^B70=`d){`cE| z_QiKC?fWL*mh@)dqV&7+Kj`~>e$Ti0yutV6{O&jByt(9!e%t+jOZMOR{-Zbirlhz2 zo}J&X@fP3r{#M`U^5)+-@(2FQ@A*Cy`;8}W#=q~oW5d6_(f5_8>@B{>;{WIO70`DX zIQ=<6(RpsN<OJ8r|1CP#X><yPyA01TJkxNm;XcE&4DV=ow&6L3=Ng`8c)sBUh8G%M zWOygTOAHqcFEu=1c+l{W;av<bGjZG1$aiB-Y82DuM!vh@l_wzB;iqJHmC-rC@Ii(% z!)3#348P0ppBP?ic*JnU@Ouou*YMG%y~h~&v4)Q`{C>m78~#(nHDmLGM!wGQnBfl@ zKFM(1@W)I%KVjsj82+T;Qw^VP_zc5;ZTQoM&osQ=@L7h>HhhlZa}94ayvguq4WDoL zLes{JjC|bi#fC32e5v8f3}0?|v*9ZYUupO%!&e)=&hYhyw-~<B@J)tqHhhcWTMgf4 z_;$}tno6HHe23Bbg5ke4yw&iXhVL@G&G0>j?=yVA;V&9~!0<zczhwAf!(TSsFudLH zBc8dvj~af==sa%t3BzAA{B^_M@XR*9X?V);Q%3)3!{0LeZNuL&{9VKUZ1{VIzi;?o z4FAAz)9|x~e`xqQ&)k;hjr;|}KQjDd!~bgdCx%}%{8Pg(8UC5!pBw&#;g=1+V))+- z|H|;c8-CUBe;EEx&)nW$8~JO7e`EN+l#|48YPiL4tKoLT9fms%?_juKxXW<2VY8P= z%w8htF*?15&Hf=V`-fzX(V1&_p5gh17kH+)B@2ywk>SOLcQX7o!%GYo4fh*fYIwl# zpy46II~(4`@G`@@8s5z_w`IAJuP|)(9?70YK5TfU;gaFK4DW4tAH#1qyszQ?4DWAv zmEi*nA82^B;e!olhRcQzHN3{~I}E?m@L|dY=b2(yIMVP341d+|KPq>bvRz@XOLn^U zFgovw+~*SfBYwtRkvPK$bZZQc4Xga7iA;2oxwlUAxs;3gvZ-sOvX8nhl6N#<cWG-% zJV;ta=K^;oCwtDIpFA}Q`{{z9pF|#N1-BS^WY`Qm)C!xCq2DU{kVm$1lnwF$DjS&X zL{|MF^1sd449sQQ(O$H;=%6D^HrvtmHfp<a&}aEkBA?-$m%~2m_w?c51B<<hn++d` z**<f7?s{FZmznhkC_bGXA#SKEFt??1W++Q?VffiOv%_&+o_!y&j>aE4UamU9Cd;{B zSf}XwH!#O)hfa7*F@en;I@Pzx@HsHsj0}09#h0b{2=^-QLN*I6YBMtY49qr((MFDK zp{1MR+4?z@?b<QThn%~7utuzY3R7Kyxh!)^6C%hFf6wGYx^6$nyIt-uh)Y+(W_OzA z{lPx*U}UYUJ0(s^<d5(b$|GdIJ4IhZ$IH3B>`!+Z7_o|swi8Qx!Ba_SdrzW1^c2)L zV)2c5Ecn?|P(OPL?K$jRK9u#jo`U)i89wy3s!d|CNh~&dTh*rLgxlELs`ew7$)?s7 z8FlsbYF)%q7qQgU*Q+-Bdeu&3*qPO%c8J9evDlf_qjqNXsGS{`Xjx(@ODtt~T+)jE z_2Xp6CEAa~63@tJ?~Y5X{lM^Z_JGz!EcRy)sGZ2LGkZYoM24L?gK8)8sF#b)IfLpa zvG_S>P;Jhgqjrd;?A$r39~u74oug&vE!48aQg+@#t(REpjSM^U7OI^Elnq@{qdBr* zXR?``OLLic(C}zv()WF_U}tcz%Y0d_cfrmbs5jY=971-eu4IGP>1gbr+!Xo3`C2cr z)VpxL+FUqaZGxlC$e6RlVjmps@6=8DK6eG?oc6X^Bu@w0(DuN4wH2A4fSh?}S*OtN zkx^G*&fB}lS^%BM&<Q-^Sk68yrS)YOzZP)WWw?$*JTE>E^?FXW=bq=Q9C60};aHSi zM*T$$`+<3Hu*^}cTyZhl!dw&{gxL4jG8dT3GOwq8@$#f>nDa@HkI-7o9P&1EyKB&% zgt^m{4f_z57qRAw{UUM{+gU+t$6(I#z%0+GUF&Gyvdm=~lO#RQx%B3vNe(WCyt*ro zTeNFtpNovOo*8YAa$=RQH}dr=hyP-y2p0XN#tt#$yZQOT@d;d`xJ5==mM0F%eob7C z^`cnxyh412eq`uJhJ9x8nRPlEj!lsqY~%^;6WY8SJV1LY(gE|HAu{RsG0bB=GRD&G z-k)CA9=XUYV;(kl_dG!Rhrn!q4;f34GY8)y!~UM66XcPt9QK2Jn%e6*sYPDudDzs& z9Bc+&Px_wyI9zG;ONRH7_O|r7y}i7b$_6eH?_>1e{@Wbt-PgziH>s@WG>;tg_mg^| zv!5v&c#`x3vmMU~@8>;xn<FhDhahevX5TeJ`!1>reLb=x=d^YEA<mImKgdbP^lv5Y za0%tc&OQfjFt-}+Fl=>p=yO%G7kV$}vE*6GWA8OK!O>=9*o+LDkzw;_oT1Pu_~}bi zvf1j&un9&R>7UvS_jty?^dh&g4w&)`xIL#`D)yh?L0?w6=<Sm{$qbJeu0<}AOTkW& z$7CALR<l~k2Z<-?2q%$g-lg%JWf?kA4xi(hOLb_jk(~CQbnZ*d`71SNs5G3FI1c9A z1Uc_xF+%#7aXw=1(7sC}kM;>ahCM(U&nze#nA;N19gs&xTjIGx<+R47ycSR&K^~an z9~tcmoKb%To~C{jz9Ta4b-g?_Hd9PLDVw^(BDXv4U$*1dCSMl3Li9ubvJS0NQO;{t z8rGLytP#rS_g#Ho^B4#@oZ}xEI-b3qz%^=D$j`Ho!_yVIA4o%fo<ngn`B|9qa~ksS zEE*4i=MbBm>^Zb6<XDb>WY~|4vLVN^PRx^#M{e<qaX710c@DA3rD@2YY$xPT<={`q znJhQ?Gi44sCTFH0H}aS{!r!qt>Z7A2C%C@Wxc-8V@$#Z81TH$yyx()rwUT^R2ljY@ z=W>pEuAAh{=~3YJ)nteET77-(!RC6W+*HQ86Xob@<yz!+_v6T&PRoK<h<>lzI6HDu zG`vf%$ctJQ-bFjDQQn>-IL*bZ56;{VuVAKZ=<++1x8=ls4F9lI`Gv?RYnbGniS9E! zH~35q<{V3XB)ndk*X1Bbe4<WLGd!uBmLs>je~OGbd!UpBXTrU_&-C_tlMdvN$k=~+ zrZJ$LDXR~NXVgJF1JfSWZOgeV?^oR&%xf?<k{gdDmYlCldD6=p$lJ;+r?rghO8Yv^ zJziiRA20X5F?)Xs;heH#Yu-ov1kNeUVg5GJt^ycy%dN+`BQW9*4s(s#Rp7Br<HvGJ za_&bj@9Su^V2-d37-uWm2NqV(is$sgL9_kbA)Uym%X4~^$f@k>7&-^byhGW@QI0tn z<W%-`44tga*GvACWnRO7Fk*sv4PN8(0Jmk$EJU2zOLE~B@LVtN2ERk}XMjZxKCG|f zQHjHm5)=3Uj`E{?+4ZisuMn8)iX7$W3*i(wLAVqB6<KuJbMkpHd_Kz0yXIo(yhrNl zj@)#SQC4}xa4j;`D>{^Ol#LwuC(4sudWDOKq43UPC*&5EGjGeg`?BtC#J1Pbybhdn zU_NHu^MVfX+h|<z**xnxoaJkB$a_AZywm5nkBVex^*2I4y1q5XYzI@^3c_f+FxurA zF>FmJ|3jZ`o}Ckay#@D{$<BixChlm=aGdkkuHHU~ki(|y3k;jWR99ppr@C0ag4%m_ zPW(80^YaVLHk+(NobtT$@-!(%x!5Nif2Ll$8onVumty=2KgaxyI5*cG^z{ymh@{w^ z_N_g5duT8850-X;57D?O_w=n@BXX3D+|sx99Y!8`M&C$fM{WznAuz`w-$Cy`^X^^Z z-4t`UAI^J9F>mBO2S+}u!@Zt^{%2PIeUyLZpsz=6?4b9ejU75w-o1k63$I5F{JwC> z+l`)6Ro?q4<-YaGv(8bTy{XmVr-(K-W^YpY+zTR4RpxR2!MO=)Cs0-NQ{?+_L<slc zo_$-2Zc&Vh;Ze_`PdZkAEZBj3yr1}kq%Xcj&ZyoXA2Gb%Fy>&?!M%+z^<7||r;!_8 zF6|{b-zC0tDDw<2aF0zK;=pzSCq=m*!+lp#??#|=IAVo98YlbjHvGQ~f7HbDMCFv^ z{->CdJaAzx=l|rD*6qc>X-n&~{Vwbe>(2G3x<4G2=Tlgh4JVPYMjM7)&soFfnG~@+ zBLKJgHJ!@pxoH^BWvHbz9*8+UTyJF9*K?C$$oY8<&M#!sKi42r#1iviH)E;HHP3^g zE|UAPL~<E3fqT838B47lo-czr?9W)5JN)#Y1D|IOshycasz1M9>m?ow_0I3ty5{%G z{qwMkTqagKIxmJXmSipytDV3ZwOz;Cuv@%X?u|YBdt=XId|yqhb`~!te{jDIJHkU5 zG5JGx)P@oN#fv#6YbYj5y3`JHh+$y%ZAll+7a!XtUE0PaT^ieBJIi^D^)FMK{mWFp zf0^np-HCP9lW(4B&IYEl3A2_RpuGX#$q&1MqRI#7X{?APR>Tr3Fz#3B{vSKYdFoqW zZlmX<Mm{iyx;!UEFPFSQIzHwU=RwYyKF(m=X$WhahZgaD`1bRP!)|Dij<KOdEsg## z#)cNDZ_Mqu^MOCi!JokQiQG>^(ox@r7HNEl{XT?r*q?1V+nj}%IG(@ZE`r;*47aU( zkByVF%`JNOI}8o=lh6BfhtoE!_o%S1XZB(IZP4L|?du)pu+w|U;c&<3b@tyw_2XS1 z#_iE$g`X)5<Iack(g<>h-0e_XgdYPJR`s=}&~GAE%IR?70Fi?agq=L-fD_SQE&E~U z92)oJ!-aRoz4372UAuCepMwv~{v0t}_>)~ZK2&cubQRe5oiOzsIQB)h>>=pjU5Le9 z!)tXPIBfPC!;Qt4NdK<%d6@3W)5y3_Tj?rsO<C!VeH;5wbdFfY!%BDD4CVLjz>F-q z(gnu+UFqH*`*)=~p6@^DISw)I{CUiH9*nGY9WP}Q(jlK|J@pJN&+(3KrTbITFXB%d zG4zYr=P<)JYNPTHaSi?yL%rbeENNxo&tku<EPO!vE-A^Hh<26u-3G3US=vr=X4Z-8 z7j$&}Dw(yZgtde9ab_$zeFj&;^BtPwbXOd>==wdQjg-?;k`Frkpb5e_7mJ+Yz;c;` zB^U1EmbUhk%zP}FXEDUmFM*3RuS;g01`hUl{t~y5T;d!VaW0u>A0>H~!M^ESF8O&K zZ0hrclAqT>u6JT3GsjEvTwp!5H#`?86IW8i${{A5CA~j~d^GMcB6ELza5u@NB}Y8Q zV}n@xXx(zvS+~4B&v+b`+`8qeGqyr?##X5OL%XZ|L%XZ|2n8&5F&7l!}$?=rX7 z%W1tUxepti$QZYg(-P%0%GJneCB3(FrSv0-<nWTY#}kJAzEWrKlj;r3^>zl|SZ@3& za8CB^Do_qg_->@6cObpODegc@dcOgAyq9PxnH*T6`viaAl9UR6Dff`Bl&!m*bKsiX zmDaBQCiOezYT{Tg&U%oiI0Hg{R6K8%&Z4{hBKLJBa~ydrGke<1>}fNZ<E*3eJ<5?k zGt6=6YtQIm%p=c!&q>UFqH19}`xDF9AkH1eFy8aYobE+4^KMLL-d)Me`zpk;x6I7@ zC&W~5QlonHJ(JA56O!S*4)x8m*Qa+dq%HccMTUKg?3akOtUhzke7;Iuk?M`>ewvvz zJur`%%*^pj))bDpt}hw#JYvPUJ#!}wYs`to&y$ALpOc2$bBgB`@PRnt`Ae)ZKPjGz zGgsf6#}D?snLF9E>#t%C$=qMbduz}kZlgWSOv63kc>n2{bx0rbs4ootkI`IqK2{%> zbrAZWSgC%VV))d3&_>=HWbV{`ROht4lus|U$F`qdQu!HsD*v_CCHo&5x5CI9ndFTk zVv>F;=8eqUokng#N9Xbku-q%AhFdaoub9c*Any8vk!O0dkxwp&{W$VTe`d*Gf8>+# z-KWST$Gt?<$6bVQ+060C$p2+CuOqWu*YUDh$IE<=fgm70p8F$nU6T$rH4hMzobIlP zWzU9JDGCyQG_zGXzE1^xy}KyOJ^|}^WX#qw&R;U-iM73Y&MKQdLuACNtb2o*WwSRZ z`~5)Cw=vFH=<8ZvHuJY^=4|99+1Ghmc7Gn%smSX|$IEF=DZ4no&_<m*Wiv0z?$a|R zZxd^K&wL$gJo8j}{l1bb%5MF>T6X=uk`qX-`WxaJQFdo{sD5CMVPNj}vpcvf@)hYb z^H@43o_WjeT+>JA8u>>5E*6(PZ$GsYnC)!ZU)xSBV~@BN#^I*@)z84}=cfI&U7Plo zb+ha~gSn3qMe_Nx2T<80r@r{?0g^X}sVtpInVZ7ruZBM7pRzlDwc5WxawGcjf|vsh zLw;e*b&=UmFQ<1rf}EdIm)%9Hw7tZ&(B6wyX?rhPrTuu(D)ndlz&GHYGUvCVw<C;P zS2j5<aufb&9&0I^XCGy=KPeY3_PI32SEmRgr$ydqc+&8+GM?E*eLS->Y~)B9<?J(0 z`o4p2YtNE<X;;oS#B)~J+|!Pj92gnn3R`9AFR<pl$gHF9Gmn_uHG+39rC*38&Lbv= zjOe-#`{6l0#`%bx_nGxvFk;RHBPO?un0yi$XN?iFw~x#|Yt9)lIb_7qydLC!AHn#S zyUG!F$uTOw<QN%OB&Tss`!r&i7sT3LVyx-N$zJa7Oo%1tkGM+@(pV9T50@Uqbz%II z4l~AEV4h#ZR4<-cvs}ixmnUe;P}%bum;P!fBPQR{yUCx(ScWb=Nap^C`&^uxkvVRc z#hftWE`J~UgY}D8+k5%@v|XFu&pJiYVGcfTe!uEp@ge0aKLq`tbEV3&tNa*-or)Qg zk>Oj#tgXaUFRiVCi;m0cUb<q&s%PIv6|-lqU=J+)QZer~SIqm&#L`A$X-fs~3~SkW z3suLn_f6j`uE?6se(L>glyh73F1LcaR<cibkDl>tF0#L$Bss?+r#R64t>5c<PWWC| zc_{PT7Uk3y%Iy{0?-A1&uIO_LWsX1JQSiM)#mwu9%w;aC&(kY1f16}q-;1l@ZbxIK zXY-28Wv)x-Z$<VG>&cFn)1IMX=5^pO26Wx8@O($Wv1ju<_<Bapub4bgF>6!gjOq$& z7W)v^DI@p(==v4(Q-`WO%h<aRk;C}kmP4*{(C|#dJ&`#kIyWosGAB6)9OtrOlnrw3 zm%wc2Z%)>6`!^@+m?2ImpJWwBye6`ajjO9#mRRCRynBf4)m8K_&+&@8x~lex#s1Y* zYg6)4#a;7J)xYMWszWR>B*r^?+^%ars%5XmbI<<Z!*%P_hwIj<&Fj{wO=6#`EAF~= zY9}!F(S*Mw=kYTUpQ~2fL?`S!-@g;_Y)EpoADClKEdF1AlH4^_-1R4^Z^ROx>rYZU z*Po=m-EgF~kyzq?!;xy|h9kA?4M%F(EhlQ(Ehnn~TTaw^iPwaF-*Tebx$zJ!d*dNo zwn=0A#zUxHTAMtJ|2H1OWe=r%;yHcFv-)$B$pbfAj(hKlyX7y{hg<(b`L>U!|F?Za z<+pn~?Azy+&0SW-++|hFJ2Mrtud5XFJYFdnn`W<78M(oK#vwx-^5qZ9{=CxA=kJw< zj+rXfBZ(og#GF|Cui`vN?MiCSRq>nAq>WXx77$ZedS>U@=kuz3UIU-qh`d)@vFiHi znOf@LC$ZKQp3z|4shTrjRo;QedzDpl)~iZ>UfK%%khd|mt7cDC#o0&3Br(^;`g$g+ z%K0Lvdi8u!l^n}{hTO>Zb&pYXcYIpn?AgzE&x1VoiP2tu7D=q_z2nn7_6Bp*`vnt+ zzx^=v3$3kHM=W+ctGpI<V4u%Qq%ZT%a}xT6<itZ6$;k&=XFcOtPhj#VIh*{M+`v9_ z+b1`WKIJ!(%Y3Q2JI_+z?mUZpa7D7o%=wmB%iejGmc1KePug{N{QO<j-EGF+JxA#H zBo_U9j^MhQR2Oro>z*TI?vq@{GqK-`lAQdZy(qEzb8p<YRNcK8&oYMZjnAD)PWjo# z>b^6zkBI%V+N!(nO!6(s$v5U+VX9ZkQtnk&n;lKjx&LF@cH*%xmhS(U_Ajx|Z&gQ( znz2?AQ(eBl?*Ev!@r(Qp27Q*Q>H_n8eBk38PwqSB5YGobu67<gM|B=NN97NFg5?>t zmpPPu=o6~*rB7+uFMUeo51+2`hfi1emycC$q^h(1RE-JoV2BCvSY)fO@!5W=+Kil3 z-S$&8KHE=4x8ZK~%39TZ<uKI`j2R*F<WS;ABp<d^<=t<5_Mz(Ek)|2%A~%)kLcN-X z=L@V8ayxUd`Fc*PX_TX`$TK{nujjxYmNU<&ns-pEa)&@Z6vBJjWZ$eWRda7pm9>U- zw)ruG_gAZhM}2$o&ZJ?~_2_JldDDTv8lPQOv#nRh7-n0qm-_+8x5TjuHacH0yjA(G zr(>UHcRgqLWy7x#(;25~-jS=0+=J&e*i%t|<y)_gV<z8vjo~eZZ!&yK<f*&kUaLBF zx4$17XmvGn1|$}rYi4aFmT^d|I{KN}n)$q^a$Bv2Gn$NfVs3B4p<X?g)y%zX&D^8b z%o<uV>t<w(hnk#;ip1gBCGNXw;n}5Qxt@t?W}U6cIf!+_JqFG%H8*~s+=&sh&l%a& zb3tURr#0E5VqK2RazD<~`aXHhJ@y`1XNh5x*HdDR=i_)^5zb(5Tyw<zk=Y0K^YMeV zFNiaj{%9y8eX>J)!kT*`-i6lO*UD;#cno(MWdCbrw%Me1G56B*K4Qwx>62Fk#(YFh zCOO;3x)b>k&ys&??(1=_thsN<T!a3U<QZ2><J`AA!^=?@@_^wPHF~$);im}Sgqy^A zF0M&VU>!dOC`Z-IyCSuMsaNv=?EhVSw;UYb6|WVH|AoI-|ApBHFZXr*gSNNe*~`Ca z<et6!A7h@Wt$ozr)ihnpX!!jJNzJ)Y%tthX^Z96a=16fE<<B4|y#9{Lvkc7T$QXO0 zW^9j|ePd+S(R=by*(<XBa5m4VF6I=|53F~;qh>BdW}7rea4y5Ml~J5|W$bw#<MB)^ zV}2BKM|DCU6&=cI%tzgmcovLNfO+A0D6-mliq_epkIz$-$BNiLw2iu_Pf`1kN4;G9 zdHNKT#RD&D<I|_m_^0Qao)aGb#9G(Wr^uKeb>E8n9M59&TXAngaxF{j&&VWKJKw%Q zb^hsS<?kFX??#Tg?;J04pV;ciS$Nbvvsv5w%w}#^k=hlQ+xX08Z6mR?k$6pL?=zd# zzHl4j|IB9f`MX!Bo$p?u`u}{g*89CH)gR))(0AXvQp*yH55(fb_pXdK&00Td*80&f z*C=<5VvUaaW?df5w_Ypte$cEb>%u!i^gh+PM)w?kClFkh`%;YOdYF$iuIlD@hSbeE zSU1lc>*k)5Sp2D*yZySk=dANPtA4!I&AXI!@e})j$Teckhjn>x2W_vL`@p(+$E+^v z9oDAE+%A1yUpM!Db*In%>U<9E=l=5S`>t+sMdXZp2)RO;KVJ~!yssu+L2KWd9QwMR zMn)cs%zo-!cirh-H?hVx+zW9V^^T~{>$1;9b$3&Irdh{1h~^ZXLy6_AL`*j6TvM05 zG4_yktbM#6z}}#4*0s9HQIWYXbX}-B&Hr`IV-n9N<6f(dIi+n0^J|de^Zj#W+!CwK z_s^9%Sa<(&oy;|2)oEfvNq;qQ|0DeDM%iQ39kKZH>_)Zo>_)Zo>_)BYhv%vMxwt0Q z-SeB&4zbkrJU-U|H?V&ooxo+!{ya;}HV>tK_e^Ko$k@+#_Iu#Edjb1i@tIiadf^)N zpPBbpq^~{@uL=IVaE-R*g=@5pKe|}$6N`P~u`m~Ybg|^Fx+9i0{^(-0`D4Tf9u>*| zAIE2c;CQ#}S;ptT9;Ib}GNJYUWCB)ThsI%G&Iv!6Q2iHAQ~eiDQ~kixRF*l+!52@{ zvOhgv%l`CyE&J2+Rp%v~FC^x~V<8SNZBhM~a3+#GMl3OTX^XX^asJt5s{gagROe@x zsm{;MJpDQ5so4LynWx15{-N%EagqA-i;L9e^o1&)zEI^aAE)hl`8bvTAL_XfbI(bU zVi*|bi@JN|aE;q5hpRqwi1RCltIw|-uJ(!j9)Rp<dw)5uc78do`u}#5@~_TN9p*63 ze|3iHyn3^?i+C{f7x7qRw!>rT)tkZm*_^r~_E+@8+K-Vje_y@X)}{XcM?c%-SpBDo z;jgj&%J?B33_cK#Mb@&vzE<N#EMqA$eE9XX>ceZ7XxZ1|yV-U3+9j;R>q6iGnva2L zeKGraVcK-p&Ay^uFgZLh>x}$B+dJ~_yT<)PzV-Up#_=EYN1l2<o`vhoAr9c!#;F(K z75XA`E;sKM=4LOEo3nQA!e>3u#>lXcoBczs_s@`5<2^ubo*U+750IO6IWpoFneFSk zoSQv-j{DD6haZe9V(Ft?*2*TyX+Q7x@WiU~?F+bUk#uMu3&5V=^I&Aw$-E9T*QIMH z>C2eR&Dumvb<r6)H+eY6c$V==tp2=uv)cI$`m~?-47nrr&x?u4ha@L|esjHyTh9sU z2RZRjMsl)GdkkW=|6f;=obEhx7kGm*-Ph&r|F*LZ^>vcO{ZF2xH?+bBSA<P)w3D>l zXgSuEw7y&QTi>lV15^Jd?e!Rcu<A4W@d<gfY4+#2nNz~)IQr4dsocz|yvxP2aNgDC zxUMGJ5}4-NxOpFD9OGa7A(l3do4xV4*~gBX=PBc|cg@JAKEoZyb3+*e<L*g^D*4<E z##k-#*z?>US?kq3$#|mvk0%|sM4QZmzAW>K$kdi3gFleV_#u{liHv?3PdaZ^o5W+m zPUo#;hsFTuFtbf&?k|$7ec}XVhcc4Kwt%Hi#}j>jX*?<Hr}cK<W|`~492`%&Zv*o> zLag??Z&Uj-{O77zf9CCKhj=iwg?KD7+vj%8yq%fb#T?o-^LA|)v9xRE?ON~5+qGRi zpV!z1rr4Uhsc~~hG;YSTFpo(yhR4mg6=t2TuB&)|G64Hsz2Fx9T?gY`eahK|?PxjQ zKTL$@mDG>K;{OEJ0*RGplt6BrFlR~6V?iFCMb^lUo*5_1*>J+-{0TEhCd?d}Fz1&E z8QbJrGJ9+EhdKDe9DD#vzmR@xOXRlNL^5|$?GWRg7-|>G#m?NxR)oi8RBvF6pTIl@ zh^60&wJu>_myCglWZqKMnSZCu@ri`EKlnf_KFq(9ec-kSW`6>+KlATYALid_?RzF4 z=HD58Fwe>-O#YnEvF9et{p5rhZxd#`3DbC+=<2#$#@j^Kte96Px^|5BoD*GhpyS8k zM7H&d@+@N_-|&FU!AbeOtXOL%@t!vMPro-6uUX=A@dyI?XcF&zNlYfqy~iYSHOmo` zN%J1mq#19MPT#F1mRL>7*h3YO5$C|%*OPb;P<`<47A7^)(ffqRnAel;D!-<%O?qzY z`*+gpPbTpkEq6ZWPs-V!^)>%b^4(y9whv{*>T@^?H^~QG-zO8wV=zLoGGlTw@xKp~ z?yM%0g?B}Nm<NMC$;TqcI73Iq7?q7aB#XM07vHTmiN((1yJbF3Cd8pFU@g1Ty|Oo( zOm@0g^>@10>d1ZLWb!tRZQz9ZJz26%eOR(h>sqpn?Hr1Jfetb4$B1QKOeRHRv;Q7# zJF_1HN&h`;hsLKc^)*=SEWKaLF1=s<AGj}$^JL&Y)fu?Y>ad-`+)bK!I%($Vq?wPC zW<Cnje4I2ne=>hQ-n}$1U$|bxs)74_>La?3A|@Ybf7medrQzoVx4mJ;d1SP`q2sov zf%{>JKe5E0SlZZddcWE*`{9P{JqBPCV>s%^G2B*b$QUld&t&j0M?dS&D@Mj=tA&#? z@z595&dv`;-xA_69_I~kj0rgU4A!!{#2nQ~c6mVhj#$PjvDKHeb|c~6W$GOJyd15= zkL8To;^j1k8_9}?WSkI_KIIu=t!u?Yu`V+n8U@V>4Kp@`(;RlXy875=(X-_3h8Z)B zu3b5A)93rZbEz)+okfi<zrIrrX=GdfEc&p0dHl@Ic72XKV~XF)UBPjlGJEDJ+&@cS zOquaEW%BS8e_j9$M;@CpV=pqs-jvgK&!%J?!nY}NzMC>RbBfP*{lTU_gP3x3S1EG2 zLnAwSZ|1qp(KDtg7w#FTE{s*gljjJr#AGVj{Y%o<#46wO;aFEfJm~#l_RmSDz+5&X z`+Gi2{Z8-Zc}}1|lo>92UK8cqU%1aCIrAfJHDbw8Q_0E=>Q5==y(xU^G>oyfsbuel z`nh)l{_wkJB#&jyv(72=x%erQucplBvZu^goigK7n8xQ6#wXp4a~r$5zMSSu`E##R zX74&>#^F@g9&x`h)iwNO-eU}qoxS2-w~1$(-1cobhA#bHYaerBX-m_b^_ti}$meRC z=1!w&p6@r!Jw_9sHI_SGVzsHC18O?`98gon`Fi@eYk1$d9GT-xa?Bil$GEBQ|3hEj z|8JUkVYnwU=13EJ4C%)vKU47I-18WZJ!0~i?!cRT_LTVOJqgKW{cR$LV?1ykYnr*^ zS<333q?zm!pQRGVvfvmiFuI@5zs=<B+g0c7+f`@Z_>Ms{*?&QJ<_ixZ_ju;_iovU( zgZYB>Ix;eFGdbWZaSVXf{sCX%aWa@g=fFoK-x90N>PNNg>PJ<6P<$7$nH>C8tv4|B zMUut221d>au`=_eY357Qycg6obEj$YeACRMrrB?UId41sPOYYyFTxb;X4ihu!CV`F zPQGE8_%n^UAnV{X?-Po=PnZtxchSAjG_oW2QPY8S-I+GeN{A&s(`LPnjP+WW)@x$f zyL$HVAyzxur_)I}j;rb9P~0*4u}vJt#!SOK)5)56PdJ^tBlg8~^3KP!EOCwBS0Q<9 zBbdemy`w_%7$4@0^A*X-Pnt)Ok$Z_H_f98=J+5s$>~R@mB#&)0{XT8_ecG(c;J7YN zoBkE1{+;eRB<9AK`S+YSbh>k%p}>3=;t;s&T~R-unJ;ji`Ej^kPVwLU@ZWa)cLDyk z)D5{~+`V~&7+0#Pn-!(Eh}^x$o#xJP_`AC=|B9nDp1L6}vn&2~FaEX%DlWJl<hVI* zfm`U7xB)llHo49DwQu|{ualF0KbKgAG8elm-L<%M*y`?bcjph9@~SuN-bl0HPIVLc zUGRiHu)Qij1^<7#>&<V3UuU|W{2F+;!42e_P}fE`2e#+9&$`8KZ)h%d7rAc4WH-0m zt-uE-7Ul2D3taac=oj$6R{Xt?Z-(_bzJ-|bh2Wo;^mCi9%^%G12n11DkS~Jv0+gj+ z-aiY!W`1tIt8hLy#}~}tfA|WAe6H(5-4eltXvf8FGvaU!M`DY+3-!pqzWKk=zr->e z2kMdE(r5V=cs}3?3A}TQ^CR89`4Q;JWAHzWfn*MTNyy6lDE|NLZqIxr<Q?ub^!;hc OfZOCY<{NJ}KmQNE(fuv} diff --git a/src/java.base/share/classes/jdk/internal/icu/impl/data/icudt76b/nfc.nrm b/src/java.base/share/classes/jdk/internal/icu/impl/data/icudt76b/nfc.nrm new file mode 100644 index 0000000000000000000000000000000000000000..114da46498df3ff787c0e42d58a4b309863f91c4 GIT binary patch literal 36224 zcmeHw2Y6J)_x8PeH=Et`o=rB{O(Si4vb)(N8z6xIp_hc-Lhqq>r5dXAD&2x0NJl`B zCQU$^AQ2Lxf{3DmilTtY_s-euCLk!5-|zo@&-dp(=ggUR&YW}R%-q>~@7@hu#FaQM zfa7>h#5Eq=KgosTI3G}zf2}#L@nnvh*_q>BehP61IZlAOy9dW5_Tf0&U5<NrgyZ}U zLyiUQw_{9){d)-W4_D?6?w!nWu8mZOxFe!i{zWv@<i>D&xrcljKbqgh{~(GL<$@N7 zE(-oa3t_%+LF_GV3?x=OReVDHi;F=N>oU+~mCH4hKT3>}PLipT{gN`*bk}ySueg39 z4U(FrgI(K6H%LE`$)#plb6IcMdf7o)xhU4n?3U*?$8EXWWw&y7oBLSzcihj5Vm&-S z4L$mLtnq+N$KlC4q^FghT84UdAwC|`TXrqan_d#HI$ke%9rWhBP2QcQX$<#XU~l!l z=o8?R>$AY;qHln2uI~chi+%yD#jm#CFz`40iu?opbNv_ipY;F5-sA7_fau5jdE61j z2Gj&0(#Ma0g8>f$t$`ySNB_6>zZv-74E*1jfxumXKLrIkVhd`*q@WQ&>w_*!s|S5e zwFkkp>)?EE9y~gDV(|3fdBHCR7Y5Jz-`c;LiDRNzxkR4nn2Z0POZf!(p%6YKGh{-@ zp-?_FGqhXi>rcx^C_eS89+I<?QptVSAXhaV`l@YzU1p!;&puq}T&dbF{zLt$nor81 z4;3;6&O${fYf&UV+0N>o&-EFus5n;@Sx>VOBz2&Yz79#z)IJhLX9r?0rQxhp3<Ql= zysTL2XcglcL-D#|M}?N316Nech2pFOsah&NcGMJ~DelVR6=h<-Fpsb>QEXUDSdw&{ zqctqc^`t{aTl28|%G#5XOd8fZY?K|9ee-y0*rcj;sl00KaXIXFS20ht&zCyKSlQx; zSgMj@4E94xv*)P&S@~qdzt{JWIIv0|4&+&-hwND`m3Y{zVOuL}Pm{t9*->x0E`6HD z)3C5JPeY#{3#)Ry?C2HtsY806GVD%RdAMgd<{>;b+!S8h(Z|y{M-Jrq%JAIq_Thah zb;Z9{%9YZyv*cLI;zyO*&yvD%&HhJ+OU0Z#O(*=Ns%ZG!s<lcvd`<Y)@I&F}!#@lE zUdbzcm61xLGE>=1nXeqAoS>YmT%+8oJfu9Y{7m`1idXrnB2`9JrmC4LUo}WIK{Z#k zM)fD_rqb8bB(YQ+FRsZQ;f{zqiwnes;#b87#3kYfF2ODqmliJlS<4?CE)yNCE(=}O zyBu`X{!Z!g>65)&ZcC(9F-g3nx}+(0L{d-{{X4Q`wq!GIjsIs3F(>6b$hQyIlxxoo z<fd|`xpUk%yp*ra*W=ssL;3Oi>--Il=f4qoh~h=HMRP<;L|a6=Ma5NP7Tps}LQNr8 z=qGFub_nN$yO>RbxVE^xxR-dQ_%z3hFN*KE__!Ec#=1;)S?#jU<y_VN|Ay>x>#tey zJK}fJ-OKNsdyKoz<(|9M?_<AW_bk89{cibv=XcM&HOKos@aOy`?p@qRx=-hLmq-2{ z{(k;)_XYk+=E*<CKhgaye}nr$_mdLN{i46c-{yYJKg++Ke`Eh#_j}N2>)+YGhkKbv zfJZFHOQin&{0IAw^f36ph_=c8)BWdo)bVKVzu13;|EvD%{5SdU@PF6;p#L%d)BYFy zi<l3O!5-uNule8b|Jwhq|9$`80z?7Q0Iz_6fY5-5fY<;{KypB8K=pvyOgEr@K+}Mh z0qq021oR3h2pASH+MbVq2?0|AUJjTKjU@pq1KtSO5U?fSor<=70fz%V2sj&XG2n_F z@tEbYJmAxSn*rYh{6JQJ2`CG633Lzi2@LXh%VS4iSYT9OLZIGbzsHF{b6|R4&A>WL z&*OqevByo1yMYY@n+LWI>=@WBuutHiz!8CC11APf4V)FYAn=vI)q!gRHwJDC+%2)M zI`sRyhsOiYfM@sh)Opsc+A8s>T6<g$+#h%(@MPe*z>foq13wSE6?ixBL6A7eD@Yy` z6{HEWaC}hBp!z|%K^=p72K8rsg9ZnU40<tWvS%01enBq>Ee={0^hVGIyVamAL6qB| zeL;tVP6k~JDhawC^i|NEpnE|Ng1KNxut%_8usm29921-vYzVdl+k&%#>jgIs&JAuG z+&Q>MaKGTe!6R`GH5vC(bAlH!tHH~IU#%Lm=Wx&Qp3^-S1iux$BY1!C3D1?D>w+%? z7YE-6{<^B(|AZ|0gIW2f@%(n$ag;kHJ5qj{Ar69cu6%dJaqhP*PI-6vg7O8w?XEZ$ z{I<Z+!jN*p8B!*)ACE+ic4oi)wC$kn*l(w8r)?L0`xJG%2Wnw5$J@24^sz^Ay8J@< zMH~)p@9`Aw$WLNlhg4Z67F5c?-v{4M91{GST#(B+UhWMFlq=-X61iPRV#02NJwbv! z%yCGDqCUBzeQHIyTCSEGJ-5kIJom{n<k^xP75GKyV$YX6a`fhS*D#RAUU!9kcDUwx z9`h`cH<GvTtXOxh{p4-rohp0%o07b{9C?usBF{tRBOJEnFUTj!ry-h=)G{8@WY;;a zOI(-BXS;5+Yq@T5XuDR7(e+40%L(Y?^9h_jkz9))6}#SYz3X~UzECQ*Ye}UQWyQWF zMK;(WjR3_kNxn?J2K-Gz<K=JL+ktGC?~xyH)c(AbYNQ7FQTeGSH7nK@R?U+w|LMB? zy!`UBeaK7X*X3Wy?=TJdPx6OSlhlg4bJq~h5dV;n5Ea8is)eXSj3Fr@86mZ#Hfha} zoRB6Vc_HmW@<V!t^bZ*lGAd+T$V(wJNOx|?;%9qvwBQ_boIeg}UlokC+0V|(bJVW4 zulz*$>9T;bpfY(`Xjxd9vMi!3sw}1~7Ds$pVwr~H%XA<^SrVPkyCKv3Iz0b3O6S-r z##m-6t6o;~anB*kLtYJ8AF?@Qr?mFtEq`8<HpQyVEwhwa%hK$&%d*O9(@x6r<;X0{ zA!YK<ESAv~z_YbN_DWla9C~&;Ymv4OIS$^rig);CElvc{IO;&3Gd9+v?6GSBhWwQS z{wsXhvw<3`J2+*iLdT9*#Qj%%{C!=DiN#<)5W(+lvCpRGKODBIWZq#Nw(YHslGUEy zvO|+{_m^UF^n6-L5mlb&e=DNL?K(1m(r(v2*Ul_dX(z05HCDu8*QCDov#g?rV;$Mc zioTEg{--r*w~!C3+K~1N`3UD#zmQL=q8$Io>+yQkTA81{M&n16_FCfb#IcDJ6Q?H5 zN?efmO5*COJ^q_=86tngJ?>FD&|VKI4f(<meN~N0{lvA28#z94Th-RTDmyarSNr`{ z{X{xP68Bg3V`G2T@w9O>-NYk_Cll$~Ch_BE_5Dxde<$vLHzw)GklV~+$oC=lf1jyG zT$L44ocQ^_;afTx-hTTxEIn?cGE#<1r%LCrGE@kag?j&fWWPUG9=G;)YSIPp7wG8u zq|dT-kLV8A(f;2o?dwdsBves3Zt3#S$j~^B_q-RX$F)Gk-sXs^>dZT^|4v!v$6|S6 zHrGkFFz=x$p&6mIo{W{XJg)z5MEb~?k*C>~?g-66?#e=&g|>NG`@a#vvu%`}!QqV0 zp;z{?{czO(TV>fdIDQ|^y)rufTT!rUlE3GRo>8E0Iju2=jl{1UQe~M)_j9bC_>%)o zeCUwWz@L7oT_4BGMdf1Km2#==bF~M@tC72MvHf6rX#1L78L^zQ^6|conmWWGRhDYH zuVi&~H3zCzJ0+t-da_ifR7L)79;@2;tFrW9=o8OJet%Z6UCh2aJj?ojDRL2B+57Y3 z8EfHLu|Gdv#y#)x{5GFY^LhO`^q$Y^e?rTCXYo%h|M6=3bL+p~6`$7U=~~Y^@1JJj zd9iXl)%$NB<@?zE(qHrX*L(b#{io;nX}#<#r;;<BzZ(D3?EW!U>95MYb;W%#^H1%M z-)}qbmjBrDztJi^653sQBDAmcbm$=IxzG{Pi=i(tyV9c2N&nn_nOEgrFD(w8CjB&Y zw)BSdR_MaeWzug#*F68+Jx?siq%(8&tUph$zpC?3caA6hJ?l>KdHgs=SyuVIP33x` zHHFXBitl#prNjH<>)x>=F?$XTR+9ZEa$1q&i{%?3EwD%MukdqtQhfq8cfi^O^0GU0 zZRp0(ZK1nE4}=~KJr#OB^pnu*p<jpI4gERvkwT=9D!dheicm#_B3_ZCuqo;&8Y^-Y zZ55pry%j?gV-yn<g^HPqd5R^9m3T+%EyWhaF2#F_!-^A%Gm49fV#Q6xcZz$82Vq>8 zB+SE0>g5*}5T*=^4by}rg;~R@ht&?NAJ#OiRal3xE@8dG280a_8yz-2tT1e5*n+T? zVe7)Sh3yMF7IrS|O4#+Vukg0bPhk(jIj=CU*l=mMUwCME1m3&Rcp1FX@b*ph@Ot6R z@%~JY@B!gN!$*gY4=)U#89pz3N%+d}*Tdfm-xB^#_`dKX;b+2&!aooHI{a?<{qWzE zBBfO6r3_GpDkGG!N{upEnX0Uz%vLtQdnzrJ?Uh}Wy_5yYVahRhW2I0zQ#nt$gyWT~ z9CPSZ+pD?qb>&;iZOVPhW6E>NE6N+n@07o&L@EzekSaozs4}UltLmwmtJ<r2s0Mm< z_UfY=sd`a0Sv6fXPqkdNR<%X-uIh;DjH*cWx#}C$J=KE<E<)lp)a%6vj|jhr(1@4_ zU4%6vE23dU%ZSbqeIkZNycjVxVqV1Zh_w-0BHoQS5^*M?DB{zIn-Skc{1EXVQXJ_O zDUXbb)I?e$Yev?O%#Cax*(I`fWI^Q6$kCDGBMTj|v(js-*GjK<ypDKX@cPv2JFiFH zQg5ZV#k;n5bMMaH1H8w2PxW3DIXiM`<ZF@i{ge0W-rFK~MIMSg6?uvE_de+TvG;f0 zk9^#G<UX-JCZC!<Eqw;~jP;rBv&3hu&kmo1J{KZOBfpCLG4i)4*C=0~8$LfrDWa-H z>7!DkYDG2jmHGxnwTjA*>KiqT+4GI@O^O;9H7#m>)C#KC^lcvXX4KZGy-`P_&PL&h zqi;8kkGc-}7IfctxbIBg*L}D79`rrqTkQL_@6Uc7eldPYel`6X`?dG$<2T$EA60HM z_>H$&qg`w@qup)wqJ3>m{ifSmGyBo<=%{F8bY^t3==|tG(G#L)MlXtfBYJ1_(dbLj zUqt^D!^OD8gv2Doq{igLw2A2*Gc@MKn3rQ##JnBzUd)FvB{8>ReyGM*^Q{(H%~&n7 zTC-~HtM#ZhtlCS}7FK(s+Rkc6tDUWOsai?38`Ti4--2rQtCh#P#Jbx$$NJzt!zR7U z@v*_Ns@T|AJV)?b8JilLY3mhR*ETS=VQh=oHnE*zyT|s89b%*RE@H>TPKuooJ2!T* z4bOpMSH!*+yFPYv?9SNtY_npI#-55jANxt{XR%+#ersD2`(x~{w$<uPHpVzUP8#P6 z`|IKqanZJQaS669aXNLj6yL@E8uIH??uA&d|IWeoHMVa$_BZ<;%4!b(4yi&5dnHNq zB%JMG4!wV)R9Aefqi$$>?yD{tzQ>h$fH0$uBhDO`?vVeejLZC^R(o4q-MB_^Eo1@k zAO}@^OZ?~k{+fm?BCd_Shb$%zcayUCxbA<&f=m<FS7wN#Z_=NypRD2=|2TZ>F0;nH zAhThmPLkD(!}sp&kUiITka4qR_2L#nyP>S<<9_3o#jS~ZGw$uU?Xp~1>$p8}2W0JK zo#T$iosxBv^^*0I4P^Rp=i@HRhRR09mBd|_jg^g$`zp@)oT4I*$+D@BTYj=8n^}p- z=E(3QQ??}Tr?`jld^|n7kS&+3mc1@pSE=>)q<GJG|M-x2=W_~XCB9m`I^G!n*fWT~ zXZ^`u>SpS^C$Z<Pt1H&h^XmWGdjI^Y*Rdb{-SXca5wnNuwi9>@X<zxl@`Hb7U$)Vq zA=?t4A=?pOOSU^cN477%iR@r}p6p0`JK2f&eA(&vp0acC{bd*9hscWJN6Cug$6@t; z8vl~)M*Ixft@ybPD?q=AUmU+eb}#<5`1P_!@tfm!x{2fW#vgL?h(8|x*!P2#eSR;+ z<C{bK@yO>9?U-%>@%U7)dbnYqvmb6@@uhAN@n5*b#NT#{kN@6H6Mx^$5dWK-DM4_v zCdk}u3Epls69V08Cn((NB}8((Tf>Anx26eNx7>tehZUf$6H*guxOGm*PH5oPE1_9J zE4P6O9TK{_jZEmBP*AD&EXi%W+hn(?ZaB{q=qe>)Ou~eODG4t#eYZIYcn|VFc~pMJ zJ#97q6VFvYXa9+vKkEBuKK}W+TIv1o+Im`EpTsJ?{F@T4U~oL2#lJhc=d=FjT5KIs zRw&-b=ha@TT&aI<?Vo8pEf?+{e((RC<NuX@e>Y>cy9ujpcPo!SvxDEl^Gy5C^z7}G zdJf6%>G^v9XS8hiBv5x!cUAXP_f;3Dhp0!W$KV*Jo}`|lo}r$tp08f4UZ!59eog(R zdV_kidb@g;dawF``hE3r^(pmP^+)Q<>Z|Hf^>y`^>f7o&>L1nj)eqI>8bRZ#ao2cj z{58QEg+`@`*2HPl8oef2lcGu2)X>z@)YUZ5G|{xsw9>TGbkcOy^wjj#6ljKMMrg)p z#%U&Lrf6npW^3ka7HgJiR%u?-ys6os*{s>F*`?X5IiPu8b6mYab4qho^O5GV=BlPt zb6xYL=C<aJ=10wa%|lJOR?xa?-L>9Ye{HZ<p;c+4wQ*XtR<BLgrfAc(HMF&~b+rw& zO|&hvt+eg5owQxGJ+*zc1==Cn5!x}@aoS1RDcTv@+1mNq#oA@sRod6IZ)!JaH*2?R zcWL)(4`|=l9@n1Ip4EP&y$l~$wWZqY+Ap=YwRf~XYVT`4(mvFd>ja&v&RyrN^VbFI z6grhIT8G<7onDu$OVOq4YUpa|>Z&*B8t9tnTIgEo+UYv!y6SrB`sxaFLv$l_V|3$m zlXO#bGjy|c^L2}L%XF)Buj$^@ZP0DjZP#4Y?b7Yl9nih6JFYvWJFELhcUgB;SE{?N z`%-sXcSrZ5?!NA!u3RtZUG?sIZ@s@hSg+8l^wIh_y;`r=C+k!6>G~S_TKc;B2KpxY z7W!8DcKS~GuKJ$(zWM_F5d8@K7`E#4xYE(n6IlHe{S5tV{e1mm{WAS3{cHL+^&8N( z8MK`=cj@=q*Qx%1{(b#%{VDxf{YU!C`m6d<{dN79`rG<D`XBZ8^$+#s2EpKJa5s1x z{0+edg+XPAHpCg!2E8HKkYY$T)G*XC)HO6PG%>U=v@*0abTV``^fdG}6lgaah8RW| z#u&yKCK;ySm|>W0m~U8YSY}vdc+K#pewSf`VY6YoVV7aA;Sh_)aMbXD;X}iD!zIHf zh7!YP`a6a%3||?()sHiLZ}`dZtKl~zZ*(!rjGjhcW1um_7;f-4MjC>R)r<*7t<h*S z>nEwpjj6^AW2QD(H^i82%rPVz8yQlJ&5U`*Hu@RH4#s?AcVlm3fBkIZAmcFODB}yp z3C5QU1;%N{m$jRXa}DE+3yn*SD~xN5Zy4qq*Xy?%-!?4PoHA}TEHmyjyk^{Ee9w5u zc+~iTVT1lP<A;XL#`A{l#!Kok#!rl;#xIPwjdzSc8t)r_OA?Y~NuKsB|2sU%r_7WT z^fX&ZVM$R*iAkm;TT)h1y`;uTxk+u4Iw$o=>c{a(gOf%ky_hsP3BS%sngd#tv>g1^ zB;36vZA#ja^ls9@q+>~^lP)9`C0%=(^?w(8;wr@P)Wcp@c}nsuuL(=5wz%QmwCdsZ zN@Xo!O{M&##I8_&|Jlx-#8h6pRDL2mVt&#}#nl6%e%uya0};xe=Tu%1k^GGBzbd`` z-plXb$YDBes}t6{txcda+TO>_d5?ta`uBcsr_ArkHySIyYhl_6#}m%O?l!mG&;BOi zX>nHlJ_0?T^8Q_!*VFnjpJ;i?yNYfV@AD;GO?cv6MaNv&%ZhQIOt|BAF5%b85xdb_ ze2D@^Q=IsRXQ4d<m3hG5%t2HSaVPgM^kGaT?#PH^98Vi%rM4pyx6dDOiNT4H;PmFj z)3Z}CihFJk63vM<?6p7Ae6~hq1n%_qXCmH9a%%tXtsF-iD<6LR2!9Xg;f{y8ht`K# z4_iJQ@UZaVca<85$N8;LC0bQ-m)L6$?>$`Lw=J<lWm}m?nMY;q_fnbY_gE#8bR+4z zWKnWxa#C{r<Syk~%D31fv1^ncVaVfe>#!F4S;sil>}Mn6&$v5rtgA}DRi)&C$)l5J zC9h51pZq89hdS&y*5~7OR(m`i`yTSFouq0Ecv8ZCD^;<dIL231!!B3#Sap>qf06uE z^0&#~C*Rj!PJWnNZW2tc`l}{)lefuVUup_5g_|Nx)l6!W-jr-gF=d!CP1&X#!w05D zrWU4Frgo-Irmm)*roN^ELkYV|FnnejVj7{jZW^P%Z5n5qWSU}{LC0*<Leo;y3ey_X zo2Ct>&8F?9U8cRJ1E%*)$4#e9XH6fOE}JeJzA{}km71=bzSRF{x^22+`cYrkbl>#Q zRBjf`u4Z?$x7ptuYz{X^nyZ-;%v!V2Y&NHxGtJrN9CIUcGjpD~jk$w4A4hj{Uvq)x zBl8gR2=fc(3Feo~)66fM=Neqi3(ZT-E6lH%-!#8%-fG@y-eZ2xe8_y%{DJvH^Lg_n z^C#v~^L6u==G*Fr<~!z}%)jC&w+J{~E$$XyORz;@QCXrbaTc{jZ%MYKSkevdmKv69 zOOB<HF~riy(#+s*$+NVvbg<+bg4MGv-7UQ>{Vjtm!z`mLFIXm7rdVcJW?SZ47F$+W z)>z)Kthc;v*=pHo*<*Rnps*aW9JQRXoV9#pxon8GT(y*1u3Nse+_v1Y{Ajt)u4OC_ zE#)afiff8zif>9_N{AsYB|IfMB`!s6yq%&?Nlr;gNl&SflAV&1(kP`_N~@H1DV<Wf zYJ*dHru0o2lrkdag_H>?Q&MK6%ubn~ve=;34M|y+vMS}Zls8k}PT88WGi8r4C*{4A zLn+5oPNkepxs-A>rPSCc<$B7ODYsMZr2Lq2Kjop7x4Kx}t=`r^W1cm{8g7lY##z-? zqcz2vZmnUhWvz>&fwhUTgSCaVm9?F<leMe0x3#~f)H=jE%KCzJl69JOwspR7n02vr zh4nS-dh2HEcI$Rref?<NW!-B%V13{Efu^o;g7rh|c|$AfWowCkmG!#yOG8iVZR;KD zkJevtl&1=*uBo1>zNvw!A*rg==+wAWb*er!IW;vkBQ-NMJ2fY@QEIc)R;e9Q^HY1K z_Dvm>I?OOGbyVuO)R$7HrOr;BpSm=4Me3T=H&WN9zMZ-?byw<psqdT1Q$I-kF!g-u zrPNPSOHw~e{UY_N)NfP2PyI<7m-;ZZJWWV*O><B4Hq1!#PYX^{q^Z)P(-PA3Y38)l zw2ZXOwCuD7X-(4d(%PhTNb8!`JFUMaIc-qdu(VNWFQiRKd&#&WZCcvPX>-#SrY%id zk+vr7jkNV?Z>Mcf+m*IA?LgZ5X~)w(O#3M9a@tknR^!gJ(zNSoU!{GU_I=t<X}_kG zr@N%f(mm6C(}RtB(iQ2E>2c}mbbWeqdTM$`dS-fddQN(y^k(UK>Fv@xrFTv5nchEr zQ2Ma+QRy$FPfDMb{&M=<^o8lm(pMSJ8_%b|k-k2CbNcr5UFmz%52U}Jemwn@@lyKv z^h@cVq?e?Bmi|Th?esh8Kczpk@irHm%;stHwFTNjY~k$g6FU_C6%MRj3_1w9hV6d5 zM8r>&i20W!624F(6>$;|k&DDj+(_cXPm}m%)RqMBGbD216^T;JNutDJNu7*LNqrkv z*i<Byc-c_5NejE!@P|4?9ul$0N8%+4kjO>y!p8h;v@<yjI&w*4TZE*oEe5(_@H+>7 z=fUqni6mnr{8oeCc=Xl4?;`jeihd^el)|S6d=8Q{7B`bL6&YZ|P}tdKD)h41BqHG! zd|D+^TTS%0p?^)pdb+T&s5bC=@LyZvV{0gpi*1OZ9%5)(*xr^4|4ZQi75HB+k%*eY ze=hpBM*q(6zY6~6z|Kne_ksTa_+J3u?cuj|p;**QBC>Tx`#IR`CTT3{hcN*Y4MxnP zf%OMA9C3~WJ`}oR5y$w#I=0CYPPhxbLge~YU{j$#3;HvmKOOoDpg#w(y^h${BDVF= z+kn`XBDUq2lMaaOZN#=*5+qs;|F0rGIpPbGScFW(xU{gTa0&j_AvYW0XB~WOfsZZF zi-2AXeC>p<jqtM%?K_d9-OxD*okM6lDrqP-6gC#^19lPE31CIQOz3k2@qLPZ#fWbk z;@g4v-a+opBfd+BuL!a2L2Rcb0it5W_bK9A3%~L3t3iC75Z?(&J=+cB@dj*tgIwN{ zNNm3p*0DX3a2cFLlp#huw<KN}9ul7nX<?lVtfh>ALZ1vd+Hb(;yJ-Ig>*cOQD(;51 zFo}=oE_{9i-CG#X4-#<(UQ-bLjMyK*AJ$q%JmNiwzK0R-QRMR&;uRrYSLCw^V*UXA z>tKzaLcGfnuL$u<(6<)WxCm?94Y@$w=7zC*!G{-O@Pm&a_z1-sKZ|xIE1?sL^%aG& z#X?sJzvtlh0{mV=%%kBq4t^8SR|mfz!|!nPv%sete0ss>5UlYQ$WIb%Bq2YRLN8l& ztnshmGYxAz3;nC3e->grgL$e0ygvNb!5VLjHC`Pt)JF`>CGBl3F?J1NC_)TZ5JNHM zsySk42^($UzZCxG!Om*<_k;f+_+JFy9pSev?Di>?3!h>wb%D+W*zJKeFaYD~gB-AP zb1bj|U?UOhXyC)4`yyhQSXjqah;{x0^rj-;p97l?{W;K|1^t=OUj+Smh>gwZO~m#U z^zfHQM9UD{O3X_q#P==YTZwh_D*V5W7()@G66>fI;#`Jxei{DWLVh;E&s*@Z4L-I( zFA93G@U;uRHo?z+wC}=r-i6L#=)8}%<5<&4g^fk~fqjg%rUQNw_!Zz5^gD(aKSy7- zKVlsGJ;eAk^7j#9yo?yHAiiG_-x;j+Yl!i4#JCQ=6X9Ej81oV1Nv!po$mdPi`VKk$ z8f*PQVI5l;*0Km|U4odt#v1m5e>X`$hM}-d2G&(Z5Y~GrbZ)}$1L%B*wethkdk?fJ z;kOKazk_}f^uNZ~5L-qR*2FIu!z1{`+RI3ka5b(-M6PaylWR=G`uU|$DjX>k36CH@ zfP4&cS)o^k1#?^s!Z>SSpK|q(NNWt1c+?muiLLG{iLdToIK9S5v|+Dy^#NuqjIW-I z`U2GbP;UmE7SLG&YzMFa^xua5TO>ZNxo95*{UK<>p64n@eJ<+r3*&1P0lNq+4Eh(K ze-8RB(Y77<J>W{{o`>y^VEY#dSN$_!ZJ^r)x}DL+qfL-ZuF)UuJ<yJI<k}W^By2>Z z{uSySP|t*3E$F=rJ*>&<-vI9jJFmjdYWQ3ToqXtYMV>aIoyEBX*aX;_B#EtY0<q$6 zo>XTsy@Gy+(eEJoEr!k-^m`5cPNV%-w66em2-y4Z_bvQk{#@4<`nawu^pSc=JY=g2 zePpi};v-XnKSqQ4M&Kfp6M^pr?E@Yvk;;xpJfumepMb6$<!NBWz_8cJJ}nHA-2iqA zbQe^F{;#533*EKozZ&&Tu#54@CIf#Lv>*7puyG7F2BUrwy3F4hVAp`{llaI!huxdN zz6SjOx&j-U3YF4tK;NOh1N08)BIsj}wH~!S)_K&K`Iblhnd?02ff~+S=Q$a)7Bqg| zNWbQwE}&liWBnJ+-{ij}Xl&4;pp8Lu7HtYzvUpQ)eDK)d1t^y+9vi%9$wv8{rEi6d z51AaYFyyU}SxYyD%n2PEy5N;fp-WyF8@fobK(PaF^6go+U$Jj>`-q0`^s#t=d_Vyp zIVcPi0~!t*4H^%c2*RA#cts+ru^jWX67su{_d(uYIIxxpWC67Yy#iVZT8?WXDaa2b z2h{^L1Wg1@1<eA@16=_f0euSk9CQoxHRvwrhr)r`97qJhHCFav5Nu|<fqX!)osGWP z$3U$?Z9#}3yCdi#=wnb3=*nkF`SG76bzTBm4q6R*9kdR#5wr!g1GF2o4|EW81auN~ z26Q1msq?3wnL2-t@+Qh#D8E7Z9m*e2-b48d$_Mac1Kk3(2DJxu26Y4V0`&t81Puj^ z1dRoa2TcY|2h9S_%TLN*{h2BMRg`N{u0y#I<tCKdQ0_pv8|Ay7CFOqyx(oUNbPx2X z(3=yv&m(?f$28r<NE2}@@s>NL<s6P`PrRdP+S!S*i*`)AbU1d&j%hz+#YuKd`|fa@ z+m2~>C&q;l5@nj95haW?&CpFu7`|hMJ}Y7Djv0LqtA`RFzT@SFqNIU4cC|Tt<s(jX zQ^aKoBJ8ydu^-pNKAT(Um(i3^DR#+yB)MU)ymwN>)e_<gMK&K`+0<t|`iw=NspvBq zXpSI7dwWPts2$gE8LQF05$)>;74V6*1Uq@_LLb|5Lf}Q53n@>K;uG^7?9Q7cQsFJ^ z$lHMClbyz}Qy+F(!cKESS#0}BVzK><*t$||e!#j@AME)VFQU(M^eF_|n_}w-seszo zqWx90Z$kT9gtFMM!-?A>wv~ji*jhpwMzQTiY+Df9M#Q!QXr_RDETc2*w1=Huu+t4_ zKA~NJb_Ci7Xb+&-f>^@Y;*lK<YTc=ph?)+yCRAIE+UuwlQ0-OJ)}q!z;PLr>0@4tY zP7>w;>@;CaIs++B5YXc;q+uleK$sXKxknh2elB9Z6o?rk$=HGD4odto_Te-12wDoL z1-nBAu4pq3qh&u@j-e%wTJTwwaSkoTXemO=r)U{QEgz%h0$Q%2<qBFp$80na;xR)- zkP1k;f+#WtS6~Mr<&$(6t=X7051SQIcaqZ3+Jv==J3}fUsmo1~uoa`9UZWSJT_jC~ zw1>?~4XiQO2<&H@fE*>{2$0S|kQd<t(!RxsJdSxB#tyrP6M25(d3M<X#k<8KuAvZJ zD76iQ)Q_aWkeZXU8`5Bsm|hD=Ubb_PhLCgtQl=1%tB%%%9vS^m%cojf)CQoI4J~oT zOi0~Hngyu|Nn0Qlkc8EZQTgMO(?uexE|W~I?uij{ga!b01?mpe8>mRd-K@p51r9Z_ zil<rt)g;a~mLaLLjn&+oZCR*!INMmw3!dhZ|3G*Ofv0ewIJbc^|G_{NKvh8fR8n|^ zHhBzC$*5-cALMLf9_7w9Rtt5uF^^%+Hda%@(@ydqQz)t)Pc`N@7PUmw7E+rDH7nIv zn*}wj5Uc@~w`_^1dJZCN1Zxq5GM&0W8vtzrG)fhLNTE$}$EYHyW{*48*~TJ`ceb%w zqO*-fs&Tflnhu^8lm9$;Y6DLlfEoy8{#yZU2ecE=Bvm{-LYw@XR0&kG`?omTm`AI# zjn&eeZOo(1*~V(s;b{-~?*>o33MW_ZM+o!X14thr1Ar_gouNQR0vSsP)4@GT_0d3H z1ag3MCKrmTv-9Zy&3hqg(@|SRZ3|FaLN(TR5o)iXc9hz1=2c$@OB)Gc?buVRzXfCy zkT=L0_VeoR0@)Ab1L}1Y$On?i)jz~oY7)wN9tU~~=vkmys?Nw0v?*(~Rryr2XRVI2 zjpeDHvyIj2JKI>E8amrptuZ{UC;yk==@WP=0os&M=KnI#t3XSEHdpn6M`)A(TvczX z+5NY4wlR;boo%ev*4f59ws*F%T1R-=O7`#>ffdQl<H?XdAn69RGCekPy96f9qE;q- z$BBy+C0#*1=~Me6C(v%n5$B0BBwJuew!n~VK?<HjNDd)6f(S@sfoV1&yb0lXB<EGg zOs5UW`Gn_J$gEd)Lb?;uo$U7}q&FeG$^HPcUqE;P;loHCRv|O{qevb_7BU4fkbFUm zPk>Az9z0*bUVtkNHj1vqYmw!y#A^wzgfm`C@F1D-+9Y=)o-Ig#bSIuo`rQTm0aoOM z+3!yFvq`f%@w#NWC-J(}t0(cg)VC+~tt-T#Z%-i(mg|vbFXA~g-rmG>Xe_;n=a7Zo zf&{&C$Zv1*n?pA1Q{O&<2(1msa$mCCkjC3j;DI+Jyk7;*#@LUdZA>}?NT)IB3?QAx z)H;B86Y^d_younBz6HdaQ{TbVw>kA4OnsYEuffDyP;5gewicu_gm^CTp`@QnnnQ`_ zk(Xh_^8`2e8b&;iJPs4wF_t{az%a@{E3!X=cpKuQDrB}|+fsz1iMOR(jV9ife2pfa zNj#r;4)NZ^n-DJ`o=1F`;K3E&ti`S^1u^#s60YPRIWXRd@lMRciB<OHoEXO)ft5_M zasyI6lSHwExk8E~3=+n2jQCCBbt#^n#2XOrD|ql<LmO90f|$Pz30F!?m*2(OMe|6j z5AnK`kDkOE)A=+2|NqHR^6Dn=+!y2(5_x6(Cdoy_e<7YJcmvNTo+<c}%y>2--HB%t z-ko?3A-##`5Yn4?6G94zHzA~ecymGq6K_t)VB&d%3?rUL$S}bdS3xa=SnwglbBPZX zVi8Y08gVbo+{ct1HeWwec9?XDFagp}gh3MN2xHmT6K2nT8_N4A;_FxjaQ(vgLgI^w zFD1T;_#4F63%qa=`#r8LD>Sew@ma?BPD1uT;}kS-tx5F*#E%lcP{E-s4rKEL&SZav zizOt7k}RjzXm-|!<;1PT&4imtGnq77lAK1em0D|&=1`VVG38YpM2LmB4{<|<%)A@O zLLeb#;zfjfLOh7Lg?KRW6ykE0IkA<voDeH<CGqOSZxR2BxR!V$;?dNr7V&68YE|Ia zi^R3q&LEB>q%Lta@dk`b;v_AI<DO7bPm){AkUYrsB@DSl{1EXAl3Z7jEM8^<HxN(8 zZ&gIH<Fft4FXNuNu6s-3)rq%aciHX?Kjsb{_v6HmxnFK4!e8fwrpEz~OLVVb=O25V z<Z7`y2Znmq@q`u6y2R^vwvw?siIbkivRdqp!t*5ES(I`jpK3ljPNZ;An896%%ZR%Z z_ayF1JdL=Gcy;16h-WFxI5#qdYT)@oHJlY$v<r3-T!CZ>(coQ(X9-4<jofjpecYd8 zH~10~?uOZl!RI3Tr0hohYEzGH#A{Q(Zh{fJb8Xt$y9sfyR9n!3cN4U{AFSZ66|bK7 zL&6;^BnQSjF&^64)TcY~Y{3AeyI>IE$`>thf<%O?ULcSVNgax(2l2XWec&^d@p^>x zqB!eOguR4l!m%c}UV;>H)}uIkQJnPz9sKkno<lx+3kL2iJmDDxa&QL{?)WJO4T$#@ zSgZ}mc3<KRC<lE7qtXIx+zSd~WeOzR3kqWBHl+4`#2eD+`UzS@(}?W#C*FwS?oV+y zBCGu=?#6@<AiOc*1Bf>!YXgWkCYu8Ut#eo7ox2+E#H3D4$~Q!Gcv^s&XaosQ3LrT! z-ifh!Z%WY(B;J%_8A!Z2@xg+tvMns&UKe9-2MPDOH0I_M*<is48!bq8h~UaIT|9|^ z#B}i_0urv#fq6i}^*Jy|$}WUOL+VNxB-qI%K9q8iOIa97JePb8C7w&U7)m@(h(Y#; z5znK!9Y#ElT8Ck6;`*FD@ep_(*XGb<QXj&^f|Tz|7$o>^NmpjW1pyXYlGouhKdsnK z%8el2in26<cq{5Pf_N*6dj!SZiu#VAzO4x#NxU^_jwIfOkWs|j(lyO!K?J{Tsqbjw zZE3WliT9!`53TUXuAD}(D<^&&S;!P*K=K6{cNpWrGdis5&mrN77$gVAIWf+O$(&ea zU%`n9%GG2qS`aDMkUdDeh%gEAC=kXZ2gW%u&WXvKn9PY`Syc3`^dWKjU}t|ejj22F zY?_(wg23VP7A<U4?0N`K?;tra&WUkOOy<O7PE2rOf^s+6W8>RH_8`G`4teb@$S@;0 zG#9;THk%M$fIMG>HlAC;`#nf_N(jk;aZZeLVlpRI*;jC4g7P%kV{v>)_E?@-?(qx` z*=4!MGdD;MjB{d~6O%bHnG+M7n82?tw%d#5*Fa+S*k?l?@nJN+JR09HLB?-}M?A}e z$1RZX><*Fx<D3}h#AHsavajI81b#C-GJDbd7D&t<+p*iwIW<b)5Jww|V^jss*7GQe zrVY*gC_zy9;7STlfdo$FOA_v~of!V-i3*HY$sys15L!b>VtNjYcVfKCfL1&mL93A@ zrsu$TCswJK<;1d7R`kGA6ZA+WiS>10yc6S{Se6sZQq@EcJWWB5Op;h%2gW-wUR4jR zc(Q`l9Fmxx1LK_-uWE``JY_*^Gm@B|1LK`orCyd3%Tl#L4?KNA4~N7%r7XIR#omW3 zF@AvfQRs4a?N1o9RXj-nLbggIWOJgswe3$HQ5T$bSVvv#tm6t7br)wnfa(%w-CxK; zyQ{MvKy@iRv8RgJDj7-4r(1;%J#9qY-C4K$^l;YgK0TdvyH77?-R{%dS-1O)fG74u zFk2N#67v~Vp+ip!QIB@k?LK3ib-T}M&br-atg~+S8Rx9qea6ERdkUDXN+5~(OsvqM zr-P`goprlUjk9j|sdd)vK6TEz-KXAJxBKi2PwW|5wkn?_=CezM4n12#y{ofs_u0)^ zxBKkwtlNF|aMtZUdphfOpS|FTJvYl%^(Kk=>{Fpb&(l!v>#W;-_H)+lKKncCcAo>B zb-T|3XPtav4R2*vmf&L5KzPMdHX-{it7i)vsm@mBJ0xKZLUS(Z&t=!0kU8kiWjMD^ z$Wjf39-hvTg<Y_)iR#S4F_P>S7SdU>nEEbeeN}WGf#cc>oSkKR$jcsFqv5lR?kDYM zU6!-Xw3d?AQi^3Mv#Khq;LK7PSvpEOM`6iv-^nZ;68wn=fFH%#<Y;47-=H3EkkvOR z)-?k3FhWi>7URHEM;hS=7~vVJvl0GGl6{1$sMmTL;d&vP7e&qytl;yAFCc!7_(kFu z7>^Q&ONqM^k0xG?xQ%!%;@QOOG0tU>oKL(FA*9JwC!`zk?!*TZA3}UM@e#yF6CXo- zBJoMY3yDu5{wncx#McwwKzuCm7l_X#PGgMPM)G#zJBaTTtWptvBeWE}5%DI(n-On8 zJdb!Q;%$hxBi?~{C*t|UyAkg}ych9;3jPZ04<>oAfyu*29!By=l1Gv}hU76M*CBZY z@eRb^Ccc^YR^r=<?<Bs9_#WbWiN8nu0P#b_j}Sjb`~>l{6`VzNf#eJ1{SwKSNG>9| zh~%pzUnO}h$#;m~CH_6}ABg{ESb9?^;!7^z+Lx7A1Xovak+^s%=v|VQIi)w4glFR7 z5+f*%q$Gz_TDM4CTAg7ewIXREY9Ej^8PZ;oW<WYj(wvG`m*PD|E@as*Z9%JDdXGsZ zyFr^tf*whd5_6HH#DFLBz1h=wPR!MDJgKKTFWQ4QPT5}^*@b5mf%J?bh<GsZFyfKK zqll}C>xr+C?L)6uiEn1yEy)efI^3+pgNO$c4<oK-+&$8r@hEpZ3GvSI-UZ%}cr)TH ziMJzO(|hMck@q(5@!;FN$3t@-;me7yA-<OQ2I6zPcj8unji@td2julA8{ijj_)9AW z+y^9<2v&}tS&!p;+~fFJCn2BU_yPDWPU9qwZ}A1kuflJ(+BD<%xxn(KK!$Gq&m2Fz zH^+~AiQ^0LtC1=1a{Sa^@N(>Ij_-qCRP<MH{J>8*eh7ZmH8}%)`*8fy?_qNyY~ok{ zeZ?F<7&?Voj$f(d_zq1uzTh^;zw{x;PwU3<T|VIW2}Q7};`ok;sb?^3!p7i7@NtIY zn-p?<vt1nD9QM26S2KM+LK}WJGyF@u7>xIY@d6EB*q-BG#@`=VjBzZ(-z8Y_fa6Eb z<oHqet>O!-Ierp+%tst6QJ;=qR<thV_)e&gMW)8T2zy<i&+>7Y;}_jWJK|{%tdBop zxq^7TVMovLFXHcoEJ8+`UqHVZh^rWcUs{X~L;HUC!MGP;%rnMgTxa2{40%Z9_;!f3 zGkzB{1UVfx5P88EM?S>Z4j>N9Qe*sfs2}Wf9|=2AXn!9ubmaIE7~kX^*m(<iMBZm_ zf!<WuhTVynudW!|u<q!;332oWVVu1tU|jGw5qX%7IOigc=09<KZWiWq2y*-l{2axY zU}IDw$1i-F<6l9(S1tx2-_4g{eH??o5%7l`bR3E`Fb6(4<o^})i{|)2h-v6F^heHK zz*-s)U$bKoD}Ko{2krCg!w$yS{5AN+FT@67olQLqTZpd{V(B^t_7U^g>c|Q5)%XU- zxBL}r17qxrTn^a=`@ON|;BR~#j-O{jUa<}rV?8dBBX7w4DD<DZ1Nd(A`3yD+Ilk!? z<Qg%wuYoZxMVx1_PB8Atj}X^btnZgGHso)S4zVHro`|F8kC@|3oCnL{Q-*xD!QAx4 zxUj~SU=Et~$Jn922y@d^jTl3q|24*&h_N7!{MyJl#<~dpn<rqr-tdn(>4CM=voYG% zVa_mDLnW~NImR>!xxk!EMa*+C=Zk=~K)eGm_S|s9d=9!xaDF^M8}hfj73O6XY%PZ0 zQ#e;{VZEUo6M_8A!`eNF{9>##S|bOLCs`0j8psv-UW?d2f*#g<yO+>kiMWun+3E1# z5cV749K;wpLZ?|xob%}4x-E2uqJ9nYfH4j~iCo)2$i*m(Yt(GaLrd7)kFj8G3$d=J z|APElLBAnqcR<MZ(s-PQ@HGc^7VW~EZ9@LAE}Ow;^AA9n^A^}^@>XE(k(-vi;2SZt zM!wp20}a5uE<k>P=g$KDfH`dfLcV&;MPAu>Mj&sYSd&r68}tXOkvqsE(LSm=C<jyz z)D(o6M|A*U4UB@l(eO1I=gJt2`9;k8i&z8W24lUsAjjY0{J}g;M((F!9ZXw<{PLhw z>=DS-%Tna<9gOQba#4=)BA=ayaiXH8*S<qfIc6djBi#u?^i9U2%m$%sejJ3E&C3H} z*77i#*4uGrVimQ?<@mN;FjMiEkqe+tu)=zS-iGxeWS}t!p7T3nR!umIj^K<812soh zFuI-!5X!!Ye85!@R>?pmc9A!c88c`zvNH&)kgY^SJUkqv0zr59J?Pa3)kOBNDo1a{ z43EKC&<<HaCMUtiB+Tp-*q(+=O)JE#9{|C}bYyGBbYz6B0Az43#x-v^vNIOhf$b&k z*p>Z|o%+S~iPr{iSbB-$(=qook*%7kKyt6;fVV0>2j1x#vb?GmXqK1A<r9}3z9N?& zTz1JtE?>DE3Ss>4!yI`nl>1x`J<JKQONXI#&SjS$<GTYH-v@r4_yyu05x+?M67i3T z7ZLx2_!Z(;i5C;UM*LIapAo-K{08xx#J?ndi#Vc!->+Tv`HNgGx$FsMF&qHDO8kb) zfg*8{siYOCJ4vlcGL>{fIe-%v)j{dN20&(b!4r5v1wQZzd|(AW=m~sK1wQx*d@x0@ z2d(y4-X+OYvKOTz7JDn|!1h(a9l8u>`i>YK`YcAK@4y}U1vo!4Kv*x0GcnsWOK{FM z!K!Yu7kh*VG#Z3e)buRJn^r<2^I96tADkb}uro9p!H^QHeA6D(dV*diqyZ%ClFeR+ zU990|8-aE!DTVYC&N>15kejE2>VU9Pn`8el2Vx(>Io|?jMGNc~E!u*HfL;KNgN3YX z8k|Q1QNvEy0^cANWtDb?bQ|<N_H6XaT?xWya_fO`#^=5Y`Wa_8_Kv(3An4~!25kW0 zY|lH)@vVYD!Pxhjfreriz|PU?3<zgpYfqFjP$q$lAU2Zh;v0~D0Nux40k3UBLC9R2 zF0A$1I^tiW{tfmK1t<=35y~DMZ-I3ScI9^1Kic7YvZ6XACm_8Kf=0U^8B!{TRF0h& zwmTu}_OP9T9kM-Uru{(>%W~ZkMA4xZNjD)40QCjoT<`E1=yQ&@>QVlN{VN`XdG3fk z%*tY{S276_G&^nqArBqj0oto{9;7nXUW&0!#6H^zo~_4$G`zMOymiSHU|m4)WWA2^ z70`#E%b;JeJ0i-|G*B3{bFN(kf_*l>9;hK`G-w+L>mq+M=o<D<%uE;Ls7nXXRuKAh zZHnIYOFbYV>MqDu*IppR-1P>ve2={rk##)^TF>!mI@B??ZZCpXfUug<`e85b2knN% zZjcabk6%DoSLq=jDKwD3W*Bj^h1jh*v@OSH4tDrjpP(KI>IiDVER?>F9_ZQg0q7-s z;xz}_sJK6*Ss)e1_YMGMfnEb)=KHWU(C8X!eXinf(O^FNMgnPEj8A~Rxj-7D91L0o z+RIw5+2_=qWccaV7*dnseUJ`-kmG(hzxrdX_OA}YX#0-@y~MOil#opLoWXn#z&glC zM#*Na$+h!n!Mqd<V71bY#1V7BF`P-MAY?vc5z6|Y7eL6|z_+25SyBz3<anxyPtvZC zmNTgoXU$-&rNL}|nq5N<2ag9WWVKR!i(AyZ7<m|iSssFOrus&dZ=l?bPrJIH_8??$ z=t+*R0l&jy(4$4M1rj?CS`^O%uUCSM4EJI6(lx}{y2~xDjXqchHKkNzXGw1H4~&<D z5XXo|APXZf7bD=iW*rdTVJ*rl4(Irh$ac-^tadGy_$$PZ;`-w@$7dpIqcQ%`O@Ov6 z8O!)J%+u)aI6e!1>A$EY8}}GwY|IBh;()X&#<<5`Ky5Y3TcGRsgyvXFX(1$JtQO9m z7mnj<Mg+=6-GtWG*W!sI8@1YygtazqG?Q>I&X2=N9QOdVHpN#MFNwyA>`c-+NCP1? zEbWB8mr%obG(q6_+U_XPx9v`*SNbM#CO0gdPaLayq8Qf%E1}yL@?6ji5YCh4IP)js zoSVqX_dqw%qiv}TR~X3JB#dGb&WA~eViH;>eF<s-!u(A-4Jw9qJIo(=Nner?SGF2g zYdAkA|A;H+AfW9_q5o1h)?TVXdk0WH)wZ(MVq`HJaTPWN^#oyM7p@0Q#Wju>%Fj{8 zgP=17xy{B-GvzZ}H6y>-SlLrMgSx^}him9P6|GaRaeN&!N}NR|c5Zbn-o$uG58(Sj z$8n{Ed7GIBv{NxMJ97i*5UwV%Dqm)wX`M>-;914U+smgw`#^UIf$dorA?24`ApR|` zv=)Fc;<>&IDb+!Ooq1LeqM26&8jCwI#JV658eK{e*TNYbpM%+6i02MPT}yD*<=n(| z+WXkAF|UiGfp#llXJ5B#p&Va-0BAVyPl0r2`&s>MB;m|mlE9>rcOW5C4U%!ap8$Fj zbQn|y><lz|lp1gcQxo(Xz6w7BLgXuYqNP_ctNp^H5*Nm=c@f7tS-BTqptnSc*jK{R zDi@G9C<v4et=`u-VdKp#JVWM%w^8EFA7K+pyn8NeM#<g*I*k&~dxZ~C;_V;d49X8s z7NW$PM#5B-c-Kgnh7xZZ33E8U;yExcOb3Q{kAy9R(VIlVEMRyCNqFgI7M|1c!c5fh zW|A-)CEiNnjsnlb_ro`D;`AWS6ZZ$7$li3Az)hU!J;;0T1a2}bhgQ_b<9ZBFx|~nD zn6%r8v8Q745+z7QQi4-rSOh52j^N3bU5|7jM?Ha4Phd<xf}Vs`>Z8t{huNQzp`F=K znzq(Ge7NC`t@T8Qn>wRN*ul`orfJ`a;%1rHZ(63)Z(8O+d*b0*)TfS#^{KyOYyGUl z*`!~O-itlQaR=`R<4OmfopSkRk2*No`EiJZ<7!2SdT%;>u)O@>-~*_#e>J)BQ#t&f cBmWcsmT>R)_;mbV@r<|q{_LMCwrTGF0Gtqxf&c&j literal 0 HcmV?d00001 diff --git a/src/java.base/share/classes/jdk/internal/icu/impl/data/icudt74b/nfkc.nrm b/src/java.base/share/classes/jdk/internal/icu/impl/data/icudt76b/nfkc.nrm similarity index 50% rename from src/java.base/share/classes/jdk/internal/icu/impl/data/icudt74b/nfkc.nrm rename to src/java.base/share/classes/jdk/internal/icu/impl/data/icudt76b/nfkc.nrm index 001a2c5ca752432d046317e53d334b28d09ff907..66421d6f29f65ae3e96ca6a5db716eb86da56a29 100644 GIT binary patch delta 15311 zcmcI~2Y8cJ`*+eolkPTqHR;Sw+GaIPN1ENF=}6M1*-1;=R7Avz1rfp!Dk95AKtKdU zC`&f76a<ulh=7PJu^=KKF9ISKEZFZn2}Shv{eR!}UjHw@>*Sp0KKFf}bMCXp@%7Oc zw?&5#jB`u`7J)z_q7c<D3@?mDAP}j*J@souAVyFTh_hP}h;#qo5K93saPi+F5bR$N zi1u{|ME|D<MEaWuL=y*r2o8zRq93d52kQIZwY|_TLLgAl*+SWzmreGALmtMJ#Epqt z5O)SeK-o|osEu(8P}k7}bOWjbJsaJPzKZ@MzBGy(-w_YRe;I#10iR$@=t}5GL?%+B zxQX_}mc$i_pC<mEB#Yt>BFPDDL{dXZQ(;2V?(qNFC~k6egdw>+*_XT|`MVTSiX&x4 z%1+d1n4WSom6_U>x-|7-8Y9i0wlwWxIwRemzBK(JhJo>6mSB!yQ?NDIS=jy90bChw zJZ>xQ`-r|ME<Oow#?Ki1dhA2OC{itcAO6cIE+O{MI6@Z4lL65Dz%7O8go{K3QAwOY z{Dg!cDM@2VJ4p}7a`G7R&L}SV0Yy$3L)l4rK$TO+P<L)&L_yJ^2Q(SY9>t|i18x`X zS6E2~HKRJ?71S#kv%+6XGJ2!9bUdJ6qc_mK^j7+FbSJ%u{>=ZzSLlC7&3~;W^uJPy z|2p|+uzxY)d%)1&GcrNV#2^if0Am^BQf6jmAahyfrL4@XK-RLX-t4sOy6idGCvwtq z>T+h~9Lr6~t;&5P_lvxQJY(MLd7m@Uaqq;fi~BV0G71?+EHoQcj<iF^QGO^Ni5kLG zGOL-+H_-)zcIFu7H0FZA_QZT24l%bv3?w!xxej7P<-{{Tjl?p)fT^vtR|c7ftR4(8 z&&7tDEAyv8O2kLGV4wMW6qgmxBCxUtV`D6UB4Cw0=Bgc}v#KK@mIF?zm<8JOW5O`j z%jj0tYcaK~d90N{cs=VQ)W=U^zd)e|!yxWk)(y~M$vm`<b(j6Plg4xYWPn5Lq^G}8 z4X{8IJ05r$JT?vWBu9U84JL>3pqztLR3oquFDjk`<QR#Gbx-I{KxaiI+JKi8!{)IS zu;O^ODZ-F4H7v%4rOWW_;Go!_KKmJ%V+eZ;eg=CQ2y)15h`pS>iM<D8{d4vi_O(IY zq*0JEQ5Kqvhw#hU_wlnhC=L-n9lwaf;uLWVoJM>&hBK7&B7O<S&v}*e76*&(!q3Nd zM`B<Z5EGI4OAP0I&Q{K+oUb`QaCUJ%=bYng<b1+8&bi3>kaLjp4QCzaBhD9`U%4^d zc<zvNE}5If&F3n)wOl{<`6zCzEZl_Pk|K%mgVhsT49WrqtnsipqGAVtM^5F=94rg$ za~A>$JdwMGyNmld_Z;^c_dXBBBl1|hBA%XC1msyfo}Jgm>%>pybwzP`^I<7o_tQFf z+j%{_)4Z#^K7Je!DATd0@d<n;U&hz-?ff==C%=n7pWn^j&hO!$=3nLa3E~6<0aG9o z=mmB`o1jzBC73Vh7Hk*v2u=&G3i^a`LV}P9RFyDdP%*3+WsDDTJSG$~GiF81zL@V~ z9>$VlrLpy~FT}p_W(p%Ub{XP$1hHFV55@LE`6*&3H3d}`J1`gl`$N)!%NkNX#5W`~ zNFTCf$hILpfc_&)i5n7!kCR5?;z}N?NsNhe$Grk6v11@#>YmVDFy}r6_HPIz`{5u3 z%$p#N6URy5By(`#Fp)#&WC0qJBjm^s$n>|;7sh{=zBK;V_&;K=C7{w*rmss#Pv4xr zBYjW$rwJ^;@p=03^luUh6ATGX1Tyw^`nT!dr(a7Ln*KAaFO>dk`tJ!ZV-N|m6Bfq) zn(#hm2qrOMJtiGP#AIM{5<W#BF&s=jMw;+t!Vd``bFmLGB^VXPkchxkgE$+;iSZ}m z6M2|6%y7&Ln9-Q=m{&2cV`gLKVcx;Khgk(DlBi0o#jM9{#q7d-g6Y8=#e9W1gZU2g z1Lh}8=r-mz%tLH67L85DVqs=18Oy-tVR_g>Y!S8`tHl~YY0EeoY#r8)^<bL;M-clQ zb`*9jb^>-P$Hb`%OTB@86T1Mr1p7XA4W}WTs5kLh>_+T|*pIOL!yJdOUt&*T&torQ ze@uKi@m1`<u)km*sIUWxGZWv&#o`ihsW^OC@V&%!i616@f}`THa4ehvC&m@yDsXyS z70!Zd#CdT;anInM$GwDm1vd%z8pjQ)QW=x@dEyVy#dLB^;vY#ws0@=4YRYdaYpMc$ zww3cN=LODa&UoBR+*`PXxTUz2xOKSAxE;7paG&G8#(jsohWiEg5I+Qg#HZrP_#C_d zFT<C@S;4FD27EQ%mQ<Kjg7@It@FVb}@MFO!@H%HUegb}KnCA`roA`zJ_wgU#x8Qf; z_u@are~v$n4}63F7XLl|8vbYeulU~y2*MCTA|ahXBxDeB2pmE_K}skgs0ao^HNi%3 z68wZ#SQ+72!V9oJh$LN7ZIUx-DB)$otAv?^x09Yr8cleQu#T{munUy?73g+)4D=DU zG;JPd5$9dbdwm6c^1c9PC1(vVMn0Ld9*jY|z_@de^98Jua}ta^ZZH=0f@mr9I&MOI z5EV>*^hFRGBtuxdPj-1QWx)JnB+R)vNCTbV7s5VHKcR<klyDN{_AGF{ge!!b&>Flb z=^mj!X%Z2c^ae4Gm;(KT7m?;Ats)YLw4_}K<bBfpioT^y&ZgG;bM8Ap@`biON8f9G z(?CK4eW*wh+~~oiV4s*xWP^Vp9FB7nC4+H91+jvt2Q+^;CI~{$#*L1f5cew441Gi> zM_QqW1TNJ<^a1G>m<N?g9QH(dB(akSO(bD}?T9E87DXgZCQgGc(#X(k;>hS(#JO-g z3K16(ml3;(AHZV7EySHDDvCkeOZ<#@gm{8@ns^~hzf8PNyhXf6>?a{nIVct>j+8{g zkVqstDVM}06_8}4Qj(ff3G<R_NcDqRi1^&Nzkb7C13L!32m@M7`W@{g`AKc0;iL{| zDfta5H;IeklDPE0N|DB(l%x>Iaz+eFLz=SX8Hzk=%Q9Lrk}&;gMpP|n4zPobG#@&c zp-koGa5-SUk#bA8Dz1TB4cgLZXeON&y_mEdn$5yOGqd7RTpJgRSX@6)UIL{uf+%jd zjdGubCNRnpxi4@>bH~GJa9<6Jzs?Xtwb<%Jl%KR3CX+Uhwn4`;>CvxqX9EV!5Y)4P zxElm5Ks_OLAE}3QG@RI;EIaZfRLdnog6t`9qk0$~cR_w%CH0c7AdpF)l5RquXRnUA zN9rd-mv}g6PnHGxE{Bmw21ZQ!lAJ;&JVXG^tx??h&<nY<kc*+HJbm<X?rJz?<OAqZ zIssahS0~!=v{52q?zTZ1clVRfz9*p`C_j%RJ39Cs@du&?VuD!%s33>?756*tkKA7d zVj_U!L0lnRi+`j;w~bUWxBsug@D~rb2zXDL0WawZ4FhaWjN*}?rK|}ts8wVdv@weT zz0O)3hmP<-`Rv>+R`#(NGC3Qyk<3PIB@0nI$P&~?WChHD`h;8oE#;}9kRUltk2*v) zqrN~LCtJx5)YoJmusRjgRpFad^p<;qxyTSNgO|n21KHy61UwN>$}8rT@l-q=&&aFh zSpdC(=i+&JO}tj#GrZ^64|yHDPTpAFc-|!5RNi#nEFQ$02e=mU-sLUlWbwNDNPQ&U z8s2)|<~}x9PVDNd<L%`g0LzLaykoqtIPdW`^LB+P-@p_Es2)-j?>s29)X3}QeGk?i zH-O5Yd3SkzynfyQKbjxcx0;{8PwBhF$AHBMg-_>agCz-<FXW5B!bHI@=c~c;#Kf=R zTfid4#rN`?q4x_WhK7=#AwN%ki9C)xnLLd=i#(sajJ%4xp1hU3i~I@sAo(cyB>4>a zJMxd@+vMLVF_c6~I)zBdpfD)~V6RtB(NK((T1o@OO=+S8DbG<xQN~gxP^MDepu9<0 zNO_;Kj<T7ugR+P6DdqE|GfCf5zM_0f`GN8i<u>Iv%0p^Yh>D^nQ*l%Zl|jv;@~DN> zB5D~`Lp4$@R5!Ji`aJbz>Z{b5)VHb2sNK{Ls9UHzsC$zBmGm3+AoV!)4D~ze57eKM z5y|n?U#JghLujcqGA)P3qZQJMXk|1F%}A@IHPGC&CR&j89PLHg%d|<fH)!){OKGcU z>uK9)q207kXa{Lu(7vLbp?ydDf%X&a4y}*&C?h%posp7(%^+tmGV(I`8KMk%MtO!N z!<bQ<(ZFwOdNK_qW0SKo+!;+7&t$xqF+St9j5jmh$yk}OF=JQ8rx{;noXPk;<6jxS z(Gm1`I+mV6XC>z+7t{0UQhEtpMK^}%Hn86f(qEvzLZ3>XO<zcVpT3U1nZAR*Cs~tR zP5+esIsGg8xAY(Bx9Pt#Vi?H`A|s2zV@MfFhLK@oco{*)3yfD7QyH@vZ!_Lyyw6y} z*v$BdagcGGagOl=<7dYG%&5%7Ol&3@Z1b3zyv)MPqRg_vj)Vw-zL4CQ{9N+X<hPRF zOWv5gC;5xyGs!=v3`xPJWToV%l%-UqG^Vs>>ND#yU76w8BIU)DNtq)u$7D{<oB=CJ znVqsSWlzc%Dd$qIrTmr}lbV{Ems*xumFi3lroNQ=YU=FN_cG^$9p>81ZJB#B52tQT zJ(zhi^Frp;%sZjX{;b&4GpRpjrDTz^va|TG!qi{WqOxRJ6<MaN@SKpAnwFL2%WBW+ z$QqZ`l?4XsG%*61wFtNsz->s=rMc5yOq-N8JMG=Hb!ofO4yJvZ_G@}ndTM$`IxoFA zUDxz-*7l}J>9tL-XMNoCX4ZkGg;|H2-b;5jh1S3cW*yHumvuesK{h&@l+DhTXKS*n zvpw0vv&Uu6$X=ZNLH3U9{n;n7FJ<4!L4sXzW)3e$nxoCB&uPgSl`|!0ZqCx2H90$T z4(FWBxt{YN7oCgE&B*2FmgbssJ-Nek$K`hA&d8mc`%W&%Zu-#N4Y}KMKh8bSv^n=s zi2p4A1>j!dkIy}kdnWf1V0bR~M(*9FUAYgM_UHb=e~tep|DC*8u=&O`g%>G#l)UUb zZeBs2tmzvBlE0F_k-saiG*6vpYPy(b&2!}W^4ju7<c-Q3+w@c3ME<Az<9sk>Adq>} z@@D5P0QyJgEzeuq^h@5Rrr+~qAM(HB{{Yn7;`g!d{vEK`ARask0q)=7@z*Fo3StEb zgA9W{`|*}RfDw=oNI|B6IT#}VOBDgAxu+pe2r2}6ppKj_Fh3mu_8E5pnc)=Jd0)X1 z0++xiXa@VIVS*8Y4zP=QSr8IT7EBe`!IlGTLH;=&-mdVba<Vw*c+)xacndk-@ZJ?n z<*nhkdFz3Ce3amI;0d7H)EH=`%oCa|cw4Yk@IFXxjbO82H}LoH=7HfJfHP0<85s7< zct#E|JkKIH1ZRuq6&wQtKR`H>UkT0#E&?gAI28O8@p-!DC|;gmDd3&T69~Y*hF8tW z65JK^3Hk*CaN&ee!UWy{VTuqF5)uZD0OlHa_V|kP?jQyBg%n}7kSml3ONCmYSy(Uh z2wQ~1g`<Sygj0kwgmZai!iB=6!d1fc!p*`R!cT;s3y%xG7M|l71xta(YTj4E?}gWd zw|TpSzX>1a$K)q-&gEmlQurG%txV$K{*qWE;rwg}FVBqrIPU<kR8CahVaPAfjy;xl zD(^h>n!GvfQiKilYu;5bvEI+S3D|g4)Wf{HXhhzFKQo`t%`ZS8^X2*Fu;DY&F_Eae z0R$3_V#cBq5lChNI+d9gp`#(B9A1Q`+n5A2kx2twR5asHb#RE8&15r$ObJtg&Ox)7 z6-+&vht6l3nO3wIU4$+{E5lq4rVp(_8<;K3VdyG!EpsHZ6Z*AS8#j(Q85~c|f|Lp~ zWiE3Oa~ZSyY5mL(m|K`TnS0?SSxmk@-vk26(7(5~{F?mwd{=%Tzb$`wen<Y8{80Xs z{OS2~@)zVU%U_+pDSv1FzWl@aC-TqcU(Uao-&cSvNGQM+&<ofFqJq)_eSx{aTHq+~ z6|@u#D;QbOSun0(O2LeRxdn?0Rup_tu&v<Zg3k($7Mv=$P;jLnbhF@I!K1?1!lXi6 zA+0dCkY6Y%EG^U)nhWa-J%ufW!wW|hjw_r}IHPcG;bO3G0WA++wg`Uy`?3WrTEcC& z@O^mMB3#dVPI$a<mEcFvVaA6W!&I=sm<KuyXo7<shm%F*tttF~^B&xP;8hCPOP%Aa z;adcDP^p}#!cEYG()QS0h5HK+0YXt!;R#^0(J`ENh3i4U8+CsH<mZY(weq0jEs4<c z<sHb=Afh#@5MJI8LxsJCmkX~J-YC3Pc(<^xu)lCX6fKGqC5Tc)7!g545z$52BBqEd z5{g73nMffj7pX;hkx5h|vWn~?m&hk-7PX0niAIPzM4h6sqL65^s7o|mG)n}D=8G1I zmWY;%x<zY68$??~+eN!YdqoFCJ)$F`W1^Fy)1uIMQLpH-=&I<3=$7cNs87@{8W2Z| z<HQN#6fs6j5L3i-akiK#=8A=4kys{Hh|9%lv0iKv*NClRyVxc6iJQf3;$h+u;tp}A zc&s=io-FPXPZ!S;L*n`3MdBsm<>GGfTJZ+)7V&oRZt-660dbG`i1?WJr1*45d|uou zzAU~fz9GIPzANq%_lpN4(ULexf+R(Pkq{&l30;ycVM@3Xp+qE+NfeTDiCUtUm?Sk4 ztHdsGNqmxKNt<MtWQ3$c(kU4$2}vePx+K#jvm}sYzGRVPiDbE?Te4QNL9#`%U9wxU zS8_noBRL{DCOIh)o|c@K^hz#Eu1ao5Zb|M+`Xv350co@}PMRQ1kz%9-DMd<`W=ok; zu2d)$L8+>G<XtGAZ-sWM2%)~~2&70Ml}W>k?7_Z-e&tDM0`oKUtIQ+l*O({JZ!k}z zXEQIL-(p@yzs<akeusGry_9(m{XVlFy^4iIuVaCwKYAl83B8qtLGNIJ*<=vtk63h8 zF8WgzmsNoNf+b^>qQ7RTS#g!<Z&@|0deD+sA(m^9`(f(CRB4%1gZ_aPkeUXmu#dhr z_=Wx#s||gdH5~mbs{?(XH3t2V6^ci&ro_jvrpKdLbK(<O^W#%li{r7Z<?%!o*ulk9 zSsUURtZnf*EHF(BBA&(C$LfjCXW@>rPR19p&a!&rm8>hQ8}SC#9abO6SyonjZM-eM zG2V?pvL3;5>}WQcox;Y!;dnorBCQ2IqA4V8kUE1!Qg5&%sFXHITcytgH9<qLDp(t| z1skO!q%TNclD;erNhe9CN?(`Gl)fpQCtWCgSNfiGWzZe;2ZsiO!DoZd2VV@14!#nc z5PUWGTJVkF?BH9$w}bBlmj>Stt_rS`u9a?(Zjo-6?w0PA9+37(k4TS6PfAZqedndU z(#z7T(i_rS(!0_=X}@$p7A=dDCCE}_7#TrEk<n$@GNz0x6Usy~nM@%om#JlXnMqb7 zvqtOzdUK!5E_2CzvSwMEY*^tf*$7#OtW!3&Z~&B18Ipx$U9wrS`LZRlZrKLecG+H8 zkL;N2w5(TlwHe)vX{I$Zn+uv1&D!RgW=C^#^YG@*=84VIo98w!X$G5B*)3V0Y@jHv zD5Z!{L@#0%35#S!<wg3Unj(9Vuc)nPL{Vo^sHm%GR?+;TB}Lsu8;Z6U?JeplI#zVL zsJAF|wdht+U(tX(PM#vih_1??%)W#5DJRRb<!rf7E|Dwb6>`1YEVs%Xa-Y0KK1@DR z-U%wn3o7TCaAiyiSHqJ^X#S{qfAgW{FPpz^KG%G)`N!seHUH9lzxj`$F+<~rrVgbJ z%?lxrgC>%XlTVaS5hci{i4<VO5rOd~PSObmw0`*v`5gIN`2zW3`7-$m`D*zG@=c-+ z`8N4Z`N#5o^3UXl<wxZwA|{rflAo1dkYAEtkzbeJl;4rxlRuC@DvmBj7pD~CiYdjJ z#mr)Uv8Y&HTwbg#4w;JUitWXo;^yM^;t|E8ipLgDEbc0vQ9QSJaq;`bYl=4)?<n3^ z{8{m#;-keUioY&CQ~Yi5#o`}|uND8R_;&HH#rKOJDiDeo1xk^qNK@bxBn3^8smM{V z6g)+~LadN0N);6ft)fz4R@5o#6%K_*5m2-!+7-_#o>#mWQjAuN8!A;y9%@$17}}(G zOR;$9%Ze3>^@{C^y^4d16GNvDoj-Kt&@GDdLwgighF((KP~0DSXXv9ALP=~%atWb@ zS3)mgw<t@*B_%D@EzXvf5^ag8q_(87<++yeEz?^Tw5)E~+OoIhs}g_9<&t3~9WB4K zJS-XCifSddvRXspR#iz?tF2^4$=s5~CEX?KOFk^wTXLl2RO|5839V4c`PP*sS4wV{ z+$$Mq-PwAyG`96hX?!WBlvGMD%`N4Y7L>|LOH0+Im8CVM_EKMITj_|>&eBk6SLv+M z`K3!ryGu8eZZF+ida(4%(yvR;m407(t@P*8M`cN6*fL64W~hu=#xE0<m6WN<3}w}2 zwlZg#zpS<F*|HbQ#+SWX_IlauvUz3il)YEBs%&G~j<Qe6zAQUe_G8&EW%tYeD32+R zFHbGUm*<vC%GKp{<$>~%<)QK!<!_aDmv1cpuzXMX!SXN5zbU^{{)aL~8Lv!L;+0fo zmXf6uD8<TRrBWHvDXWwgWuwxo9I70q9Ho3&IYBv9IY;@n@?GWo$~DT3$`6$vDfcT6 zDZf;Ht^8K`z4Ds!w(`DmpaNBqT7j>iR%BJMD)KAj73CG$3R6X0g}uU4(Ol79F`}Zg zB2>{;F{@&J#gdBdiVYRpEB03OR2-`~UC~={wc=JqU&R1Q6{kv35mXtFlIn+~Mq7-E zsp3NU)S=-8`ESMmRDo?t1uOEO1;-*?QYBQ0pxHhKbek=Qe3`Px%Lw9@2~~%XRF$mn ztV(fz*<knm(^tW(PF^Vf+jQu^!T*w6;Qu-C|29ET%A(Zvb@lG{b$<d787T1N0SS}9 zM;-(IfKj-reVttjha%ke?}7-hZ5aVZ=T|~axd^06t<p>EDwC>4WmVb1oG(<lB%Las zs#(>h8m1bd>QHs6#;QW9$*L~Zbk!^sq?)f<q*|g{uIg5;Rc%mhQEgZ4R_#?CQ1z&e zsE(;ls!prUt9n(JRaaFvRJT-jReh>{)qwbzI$9m4PEe<)F=~REqNb}u*=nYmE4ix{ zszqv<TA?mitJQk7NnNA1s_kl*+NW+-x2cDzN2oj0o$9gbkb1JZOFdmZOAV>#t0t=# zsh6mitGm@})f?1X)Z5j&)qB+k)II7W>SOAY>eK4;>R$C_^;L;aeM5aqeOKM5?pF_J zqBU`v1Wk$t6Vebg6b)UIE$YxPHC&BQBhtt;3Qf62En;f)8k43*W7XI-E{#vqtZCB> z(~Qt`XgW1xH6hJpO_yf6W|juh%-1YZU)C(qEZ1~v)@n9rwrI9%cB_|b_G%7jdNfBg z$22E3r#0s_y_(CKtC|~{TbjF?K25)7KpTqI#%U8&leH;YjFzCKNV!_NHe1Woa<xLO zNGsDSwB=g0R<AY5Cu(c7R;^v@()zT`+BWSl?FjW+ZHKl~J60RgPS$p5r)y_vA?<wa zBJC3Ga!H4_Tf0`fLAyn}UAtSmS9?I)qdlTMrah@WE#9C#ukF=d)?N*1Z)k66?`r$B z{n`Otv@TAUpi9wVbYKyxqez%Kx-MH6-rVcB2&4{d?!muEC(|i(<vO)auQTatbXM^Z zK(zxGUXJN}I&ec4=4{gq(~Zz|=sI;{bs^nkU6*dUZk7(x&DSl`EzvF4b?ZWFMYD7p zbX#=Wb-Q(Ybq91kx+A({x|6!oy7RhT-DTZX`CQ!%-7Vc+U7vh~u3tBxkJiWO6Eq$A z6g@^y&{OnueKr77&(#a{BE3wn(3k7gI-g#zH|cBiR=r*Cfit5I=v(yd`r-PK`ce8Z z`f<AX`ic4}A^kKRS3g5PM?Y7;K)+bOOus_ETK|E5lYX0ir*6CcW8H53KK*C<!}_E8 z6FQ;lwEmR-tQe!dsuk%k=r8F`>#yj}>#yr?>hI`e`g{5Z`bP$&Ay%g_pbbfeGy~2+ zGSKu1hD<}Qro+J2Qw)4Vfk9%B8%p&;Lxrx~WzgzH>P3c1z06?NmmBH~^#+H*V+iQ= zx*9`^-ehRk*BFLNg@%!aPQy6EWJ8x>x?z@Ku3?d3nPCO!!&S+KRfhG3t%hBO{f6U) zZ$RHCh71=Bmkrkqw+#0pRRRASe*Z&UiKvVN#}WgT36&|8m`Xw=rIIe_sLZNlRpwU~ zSE?!vmDQEDN@u0NvbFNrN^k^PIl6Lu<*SviSI!3EdBD9>`5yRRRk<GgZ>`)_`AOx$ z$}cLvsytKqUF8pzH!AM{gzi;F@Srk+N0nh1k&h8;i~wznAjud(nlS>LF#?h?0&vP3 zMy4^-m<zxL-~$u@NC4yjrH@fztSB*pKcn_BDvc4Cjb>wA1g*ce{%W*6hQk<v+vsk6 z*!mD2JVVC7W3(7sjO_r!0XmFh0LB4K1eo#|(~Q&FVgQl>hyd9D;Eg~VSPi#Tgkfp} zFwTget-j6I)($8y80Q%08y6dw8&@0G8@CyE8}}J|j7N=M8P6I+y~ZoXpNw~mea1(o zXcO9$V#1jyrc4vl#5ajda#OiUYciSYOm>sU)NE=ujWCTejWta)b(v<EAkzZVyQUSU zwWdv`4^1DL4ww#`j+suG&YLcoel*=Q-8DTh4OGQe#aE?O5vpia*;VW+L6xLRQB_f; zuQFFzsvMyzUsX%hGgTw2I;+N2O|F_&HM8ois)bcct5#O6ullfRPu0PyFWbhob%B!1 zfy+{Ly6S>)dDUgOELGR5ZW(*3?!jfL>Ng{ez2-Q$IN@wXvNV{Pa5l_|RoP~YnN+1W z)5FOxHHUJ|+^Wgu0yyEY!4`ppRty@<EE_bJxzyPEl$D;cky-s0EB(8TVEg=Ona5T! zS4M0S0!Ddk5OYnHqsnKt4cfx&3TI_G$V3mEyg6Xvo7>F8%^hJA4}enCfULXBqs<e{ zubJnV=b0Cq-!rc^uQzWq?=tT*A2c5|e`P*v{?2^G{FC{P`8V^U>ZodTbxJkPJiMAx zomtJScJcp9LH?j3kfjdLHo|QtLW5gMbzyZOyiy2N%d0B@Dy!?N9o2#A_Ue%UqpK%Y zPph6&y`Xv-!0PHv06PKpRUZa8UVRqe62SH9I{*)=AJiagP&H{a;AXcbvxZ%hUn8%n z0H~~~t8vu$Yual@0*nEe2r#W?PR-jj%W78FY^n+Egh!;BeKm(`PSl*Oxm0r<;7-l` zT4XI6AhniQn_0`MEvPN3t*ABB*3~*{1GT~0=W9pTPN;pYc6ROCwM%PP)o!fa0TOf6 zeo}j=_C)QO+Do<9fjd!qyY_w^q7GG;T6?`Ft$JS_vF>lDicmFHMXqDj<=4sU)OF@M zdtIPzSly_)P+eEu2X%X46JhHP*Bz}pQFn@Sv+iu&g}O_1SL$v;8=d@6U)>`M(h_Tl zg-@p~XiJhM&4RO#EHq1|B^N$Kw6HCFOMyiKm(e1(lv-4e0c0$(uwDU(0eVjXy=Utl z{Y6iu#cZh)bXe*wjTX1yWuPHoX|c3hh7XS9A<OfYmn`7G#WD%F*DNzFZ&?;vmReR? z)>$@Nc3AdUK5JVK@FBn+fP(;EMqoJvaP%=wSWZ|@J;qr}1Q#q3T(U%P#S+1F%XQ05 zfI9%8dzO2a2aoZ{5{4D|7_n9u=*LL1Mv!KW0B4PWWQ~AkjUdw+L9R6dwlxC2H3D#W z8U{FjGfoQ`r&)_4XgddR4dA!7->fCpl8A}w&RW%$%COPQR(;sGz@T-9E%gGV)$~u7 z32-G_8U-&~+;tZ$!~ZWQs-b^8QU&!Ku#{SBEV2Bv|MT(cKcB8z&{nG@$!fQ{tiHMv za0{wCYHe1GwzgS^Sw~nqtew`e){u3wwJT(u{{L&kZk-j}9Nb}@Z++LgGWdygeeh85 zxb;Kp9_zv2nc&6XwczdG{q_*Tdd&Kb^*ig2)?3!!tbf>s*ph8{TZS#qCa_6u;hV>H zRC{VWv7OP*YR`u&rM;+K*=}gBZEtM%hrfgE&$o|mpV0nVJ6KnM__y1awy%m*pG|Gk z+f24vo89KJ`4C83v#r%O%=VnE!`5jVi$Fr(r!#o$%m{PjKYr-bU*L%CnLoeTZ0M5! zAr!JrwoSE7x6J|yA=`Z0BHI$%a$C1;t!;yCi*37Yw{5TOfUQUHneB+}nC+zPwC%jD z*LK-<-FDM<$JS@-uSe9!)}sqQs86a-t0&Y`>gn~_^~`#1y|7+X58lDmE9%SZ)%E&% zQ+-XnwccJIUUm-V1Nv8bG8E&}K|j+H!7H0Y$mnaMKhG|Re~GOa<N^79a*PU&47Jd4 zp9o#Ub^!XM_}8GBEHZRE0|gG(6QN?iHECu<j@`^2{zv+od@}ThU<f0AA-gkvDSP5m zI#<GB_H>|S9UFexLj`Y7hU5)CFhL-}8+pJ0Uc)2%$^AKh(*H;YuQxvQixM_JM6j2z zSA+j8kTO67C;KQ={HO7svp;6{KuSLq5E3DsKk{TI{&+aK6HqFbmDT^vL-54De`~*> zzo=i;-_ZYD|I~hPJ2nWAz~}%YH6C2H!RY_B|E=^%>?_dBKoRSodf`9yUARQa^-cB9 z)=#K^yMAN+q56x^4}s2vpX={8BsSzUlr-1?OGaq$8snezhM#%Bmt*1k5O90<m-~=^ z?y!H?10H?+<FyGd18laJ@<JTAguL)R9DY|4{<1_aXuux*KU~lN31F_jUeEyAe@JNX z{R(^$6xRRb{R*!k1m6VxJ)!W`>G(e%x&YM;u;72-dt#x#W@yl|4b2U0ux!IK4I_jp z4IK?HHH>W-&lzZ#)X>!sn%*$00cx1vuuzC;c(<XO8{M$BVSU4vhV2cz1wS?HZP*`q zAJcHK;Yh=m{AT_O4JR8;b8rpk8+seQ2bZVcG+b@C(QvEb7x=wQLtn%14FmQe_7pq8 zPPgaTh5wl7<1}G@!`}t$B0K1{pl<%@a`}ItL4Q#3Z_<*X@stFpZzwHfFSeK4)pniT zWUsbc><xCO-D_{Qx7nYukFa;xJMClb<L#5}UH0krnRduN&%V&U#J=3V(!R#N!M@qP z-M;%jXn^HApO#fIf%IM=cfj6bKVm;-2M-Vt(B*U-w5p{d1W)W2EZ}y=DhBiOB`^aQ zfmt;d%%ptF12F%Rzzj_T)Au7V<(~!9`b{uTCs}d!(?+xXyuBAJC4fAT1{b&>d<lg9 zK_0|BmIv{%z=dx#V2Kbc96>}FM1r%WNaDZ;iNnHS<yXM>V__qB5%BMcM=}q%{*w8> zCLYN=kUkIShb*CR>A@=DN$G+3|F!f_vixthds^Cl*?!%A%YM(^--v9CYfNgyG?E(W zgR%%@V{Rkg-6&}+ZPYfJ8|xcAjV+DC8%H&cYn;+Jqj7HI;>Hz?A2e=j{J8P6#-oj= z8ZR_nX}sBZ4~z;;jSn4Bpbdie1%Dp`94MvOk?g=a$c`*9fMJszEQi4H_-%!w7#`Dx zIFt@u@ih=6heYQcW=CBRQP}6GcQ|C74v!<?XwfD(+8x6kBORk0V;tke!yFSGQykMA zGaPdqa|?TAcE<wwDOt1ptYfjn<XGld;aKhXz_Cd_M;z_g=Gf`@*s*W0l#b6FM;)ge z7aUg{Hy!sJkDQ<apF%9sndD3ZIiZG}I48+Tb7nf3x{#CW6govtnQpRE;VgHmbzRO% zr`cKOtarMcKF3IBv$Nef+&R)YO5frfBceM)&dJU$=XA$T=PW0r9|Ip4>Bl+eI~S?9 zIG5-k=W=JabFFhj7+ah>ogX{*IX`nAaUOG?be?veclJ6%mz`IgH=MVecb$FCerLaa zigUmf?TT|H=oYzBTo@NY+wY>d=&o!R)5UcOT_TsvrEpcaw601=z02&XbJe?Cu7In> z)$SVZ8tEG48si%0ng}q(HQhB!z1#)4=DQZVmbq4lx?HPWABbkTHo3OBcDnYu4!917 zTt{6eT&G-TT^C%JTvuGzT{m5KT=!i4t^s$nJ5F`dogmuo2G5z?1UGn7=cc=}-E6ne zEpp4;3U|3%?bf?Z?i#mMx4~_9d)xtci+-EC#oeyk?jG(Q=^o`CquZ@&bB}XRbWd?l zbI)+kanE%xaxZZ&cXzwjx<eb>+uS?dAG`OtKXV^;A9bH_pVIAhpLJhwUv^)0-*Dg3 z^|<f4``rER0Z+6i&XeFtfzP!(7!Sci@z6cF9=3<?DbOA9NIVKpxkqi7?9qEno*IwU zWA}JG0Z)sk-7~_|;py~@RbTalJd-`sJhMD=JqtWbJj+9#ZqHiJ2Hi2O$g{<>-Lu=X z*Yla@u;-}fg#MD}l;^Cc*K^r()pOHx*VCuJ;_3Gcc%!{>-UM%o7vm*)Y2Iuv)63W2 z^cHv}UWK>ZtM*oUYrIyk-RtuD0GhpR`g`7C-VxpoZ>M*xccOQSdV_bmcaC?icab-= z%-ii<Ye@2L@NV<&_U`lcc#n9GfU~&i-ecaA-qYUm-b-qVf#kj7y{_x?-tyklnY{g8 zaIol$_Qm-Ud}#m#AH_%a<@(q@zOTS1^C^7gKDAHpGx_R#^*)Es;|us&eC@swzEQq0 zzL0OSZ<=q0p5mM1n;-Hm_AT>u`_}q4`L_9X`absU^L^$!>^tT=<vZ^t_%8Xb_^$hI z`tJDd`5yQl`H}uuKiZ$9zU#;M34V&7?$7o!^-Mq4FZ7H2GQYxK;n(}k{yKlX-{JT8 zoBeJ6;r@~SQU0<1iT)|-IR7;N4F4SeT>k?9VuQpVTIOHjU+w?EzsbMNztjJ*gzn$x z@9`h;AM>B|pZ1^kU-Dn|-|*iuR2s|@h5xSqf&Wne8Hf#_11SMqfE1twG6PIQU4R=X z2*?78KzTqNs0^3`b%FYTBj5=H0xf}Iff0d@KxbfFU}9iOU|L{C017M!EDkIStk4A3 z1~wSLVn47gurshXa3IhVI1)G(I2kw{IByspxD>b&xE{C}xD&V+=no7u#Wp2K`kT_E z2~D^rQWLEyQ%Y~j-NG0ij8B}Jf{03ZGyH!DdaaW~+&b+S6?4eeX+Q60#&4Z=dlHix zrer~zJ9CC?-R{_b?&OwlI=kaiV$M)5Gy~TbCVsu;mC#Il>W|T9kQcs+jtl$eqT`_W zd6l^_y_3$w^d3gUfd5y4+Z_%~2ciAp&}=vss-0It1nSyhm53OGZcsh^z2%L0yURnc z{Qf6WaA-$Z9uC3Ui5D_}qlZK6Cn1=|04_5^0g5AhVO|i<`Wrng31~1sBb<@P{GkW| z&QBzd;2TzwA>O3lzrSkhCPUQz+9%myZ-uGV;%PreF=vWlL%tq1<ZQq_X}>xwqZ7k2 t#;u!-s{Pt9zaebQ;|RpXTk25n^T)bQ|JbSnaHS&<kn5X!F>Ao@{{ZQ)PwfBz delta 14624 zcmcI~33!vm)_>B4Cf(aC&Dthy)9gu`txejr&Av5llcw3%mTqEEzzT>ZRH$6U0yS3P zVnGDtBC=FOKm@Fah)~%?L_|PDtXLEQX@$Z!X{gA(-tYTA_qqT4o;Ne^nRCvZIq&Q< z7q&+q+Z-K)kiMcqkPrwI5(TN8+RBT8Kp-hl@b~an4S}=*@)tA+<n&)Wkk<e!c;erN zK<Ld7NJ};Zau<-&?GQ)+(3_r((4qki0<lbO;X@#C+c>Kr$D)|f?)hrlfeClwisNR) zEsHx1L&IudQ(;@;mcf32qv5r%sqn?{H{jpHN8?MPnDJBNUy2`y|0)5Mpi6i@;p0R| zB0h?lXic1$xHfTr;z*JxiaCxXM`$aQ5KQU}6O!H=`~NbEnH&{iNG?tGCa+9Bmx4*L zr@WZ56E;0ePx&b|FSRjsRqFY)tTbQRs<iXzS?Rv?Rq5vuSqLv;CE_z=GO`l62-%Ok zhmxY&QQJ@#Bl@D4=tOh{`o;0L2VrO*6j${DdLW9K5%Vx9gA7d40GbaxtHSh*^BMOs zWtbplALc%`4EqdrCw3TDgqwle8O6j6<BRY!@H_Ftgd)NW!p?2^Q7=S?K7hi4gkhqH zXpLeL{|262#2aBvnfOd&<}BE(%td2wD>J`|VrHQL{YqACmM5zrt2N7!707D&FT4f+ zJ8J%8Ey4dvDgNW^vrvyZaW!!CMG^^oo*1Z><R`sGx<Dq8{p8ok7qUs&{_NMXzsX6> zsm@uFb1XMCw>o!G?q`%_ih;6_ayTzOPnWkK?+_Ih$BHY7v&2n{>mEZ-C_kz+D$yFQ z%b}YvC5Eb@+Ne#`vDzB`z|`l){$BzN$f)FM5adQtUk3rMfjBFi6vl)N<1y-6v0dRf z_5E>5B!oG~s7FA`*VIAkt?|?ta}<*Xp`||Hsv4)$NRb#V)CWb0XuLn@Qd$MPf#!^< z9;b|lv}Rb`cpT`QL7N{ok_A`M7SqO>0BGLyhYaBu?GLlVZ?M|1Koso_5M;7wyI_A9 z^H2)*pja?B%rQ=d*?<pOQSo#jM@mfm!!Vd5^jZQPS`$_mPdgN0Pw5Oh98EhjF8wg1 zoek^3(SD@;PKVJ!i=vb1Tzc6!L()^B)TF}TbLf}QuhXm0i|9W36X+Mvf2RlOi|MQA zThNh|-SorgmGm9-v-GR<N$BU%ub|&}kOE{tN<`+-lsk+B2A;uW6f@EoWJUoaj*-Ej zG71?<3?hTgh-M%dISd2C#RxDw>5M6inT+|2rHu8A9gKrf%-BLuK4cUq*H$Pde*6=} zO2BJ&6ysDlNM&3eFGM(GTn9unh6!b+G0DsVW*M`J>0>^@3^ErpS27oaL>h~^nYoww z8TvUU=v<iB!cxq8f7ZcDW@WNCtWs7b%Nus6nl+g<o3)6wlC_z&m-QLz8`d?}J$5oX zlg(k5vMbqM_GI>K_9FI5_Gb28_Gj#G*w@(iILVw$4u@09spNP$lR2|Fi-4+<&<80o z1jw<Na`5<Lo`~s;Ssk-C=Bt?7vB+3{Y<28oq105ygxDbDSZoMHrP6JXV~-+sZ|vFF zI}`BZ)Ct8COcUxM$0j@-rc8Kc!W$Dlj-*XE0yLC_eo2Xmp72v#Xmvd?bRpFf(xmMT zwtxZiPoO^zfzqdrQ|M2JWAt`<2YnuW;aGeTy@$RG(0b|X=$jzWbZ5Fh{+;y3_)p_M zkNqM3oAk%ir^f$~J|lg0`n>cP;_m^DCF!rEznTC`$V|wGKx2PNe?9#l>6;TI>F<Q~ z1=HV4{~)0{{o{njgePNfCOngVB>hCfy!0>Aze)ct{l|pA0|mdN|CW9?VQs>D2}gi} zyND<R43V7h1p*0yB5(*2A}`^m#3%$C!ABG!N)bwg9#M_3BHV~NL^EP?IFm$7Vjkit z#50IFi02Vqh!A2K7y;KJ-b8Fg1m8uxkN6OA2yqngIpV7@GvWf`d&EzOUlGHId&pR1 z0x}hp_8t0r$P6SAnS-Q5phyl<fGkGJkZNQFy`O$CEQK^9?MNT80r?p6NjfkSWGYCM zBcDb-i+m3Gw=s@I$d{2TkgJhzAm2)?PIMyQM(#xJlOqp+L4PvxF!DI^3*^^hf-@4I zOMEf$738<bACT9OH<7=iAgDN05-J^qL1m(HQ4CZ*N`xvw$x&KVCH+L`SZaAp;%kZT zfe0=p@$<xMp*&<}Fz`m;oxq3mFX&&>zoq{`zec}_vY?zOKdKS+IBF_t25L6ydDIfr z-%)E(n^8MaAEJQOs4q|#P(Pw>qDIltVN=jBbTS%=#wEd$($P6+Hd=@-M$72GGa!r! zXf?WGjK_?&qy6Z|(9_T}(Lr=4=qr|h-XQQQ`gQa_(3{ckpx;A(fc_YL1bqViCHfom zcjzC{zo36Z-_3~1fMq0SATw|oq>Q`_R#;gEFQX_Njw6YXl$VsBB*`ex&}UdOyh+NW z%8cfWsTt2?%mKxn9y*^253NN>(-J|Kf@ENZ$;0$v6NA7Yg|?y!u(=EdBcCB+lrZFB zjSL;5f_{Qg&8P*kqR>?IocN~MP4h;NG`-NYBy<<;D|C!!44B=KIHP`?MxV!M&X~`b zlF^kB%2*DJT?L+X85=XUg<i_wC+*JYPqJqmOsdNm$T$@`k-^74o-{k-T*jrOB@pNc ze57D_N#I!E>yeHT9mt+%8P*NY7@i3-YP&uBAS>|p5E+9RKZ6Wzg(-3Fj635g7$_zV zlLTn~v6N;IdmKzU=fus!AVO;~Wl(JBI}DSUg`q&87-pCUmWnC(L%I+n#VA5c@XR<Q z41>{OszP4u!suFzD_nghVgi^ZOe<zum>n|{6NC|9Bupn}A*LI%6w`}YGe+Nl*@D@Q z*^TMP9E9b<XqW-aNz56{dCX<ZRm^qFZOkY(8Vkp!gn6+jEPg!eNXTg4_81NYO(0?O zuxu<JD~7Q^&iSGD@J<3_E@J^>F{9^E32Ygx9IFcD6Ub1*HZwsSwXG{N5t?E8GZ(BH zYXb$fU_GI&S>>sWzcXHAyuo;j@it>8V=v<)ki+!QbW&z?J+>vZgp3TmMT(DOe9AZm z+#l-5lZIxqETBt7!Wd&sknwHkF>+}l;|Iny#?5dxjNivJv<H$xbI3HnS(ym)W1k2o zVcW2?Lhof~MMIbq0FyFA%87+`fS5U)NoWowCK>i5Y{nStd~6psG@d_5(oTRq3p6Z$ zDYq97Dic_20EM6!^RVl%8zIo7zhk#Sp!d>4d$VyNJ#%uXoI;G<jqS%C{F9F61ndA{ zU5h=1J$E-GV>W>)dB~l&7>Wq}l&6WtGPA-~MU7ks0Xp=7F(&j1)yM~R<DbDCt1DqD z^N-rXEF9-zN`X9v$5f0HBH{h0`!P++?!%g1V``ZerkmM(KPG~3I!OCR$WP1RPkB@- z{KlL<PGh$J5u5u*Y(Y4?C@@SPqdgaey%btW!T^WCLQm0qp(ESU8NbKiu!FFz*q>qV zU~j>8V(-A-$Bh*U_5m&~bc~@0wQ!Tul3<_U5U?Y#V>m1>3-&pV0vw0g_8RwdXps3b za~bnhV8?6Bwag97x0qX*?=W{V-)DZn{D}DppdVo#XMWE7lKD0B0`oiiROTRah<TlP zlR3=1%Yw3ES#VY&1j<TfAz4`ZG8S<dJ`87(Sh+0PFqXw;<qykPLY9~%Wyx47mX?8G z(OCIol!`C~5;~rWjbfQVDMfl#Ez8dGumV8kL{<x{l{JOc#+u1$A70MtV08{3XDwiL zvAS73tmUj;)@s%|)&|xlRv&9SYZq$|tDkj%^$BZ$b)5A%>r7}7uOrC7<>N%S5}X33 z!&TvGaUNU~ZZhsE+%vd2xaV;%;zGFPxRtoIxVLcc;y%EAiaUY(688=6JKPZNHts$? z79WpK#iQ{Ad^Vnj=imkSV!RBm##i9Ycst&Ye+)krEaGP4=iy(#FG<>*v=hG!|2qCn z{8s$C`1kQ2;y(%EKf`~HKa0PJ{~rGn{#X1k{vIKQ5Kl-YU<la+7C}TPC+G<lf|t-l zXeCS|%p}Yv%uD((=?LLP!YhQ8gtde>30srCNV-7SN%)X(gzyF70^vu(uY_U3Jz@+o zo|sBR6A8p@B8|u)3WyS7IZ;bA6Wzo{;$-4e#972(2l090i^P|R%ZMw9Yl&|Xw-R>{ z_Yn6J4-t<NPZ7T&ULbx?{E2vjI6}Oi8JiiOnVN~tB(Tl}ei*NONk1kHXJ%*8GV?Pf znaa${OnYWs=Hr=9XU@rdA@k+Tm6`v@d^_{~%#SmVWqy_UUFNmq3CXFMzh&Odipqjz zr3SNbS-Dx9tfDM=Rz;RI%b)dF*3_&SS+ld|CF7EFvtGzrlC>=B^{ltD-p%?T>(i{y zv%bmtA?w$yyQB%ER1%JqOX84<NODpI$x8B)CXyZ_JxQ8DdXDrW=@qaPdz17IX)oy$ z(h1U6qzj}gq#@F;q+!xMa?H5#kRWIV$(&?mvOD>)<Qd7&C%>Hhdh+JvkCMMm{xNwt zWkL!vB|C+aQbJB5XOPL{u~wg=PqCAQ<TA33ToYE5(wOpW%F8LQr)*8xn{p)OtCa6k z?xrGBvs3d^OH(USonUWa2H8VyB2OXDB6pG(r@oN-DtS414S5rJN08i4KAgHa^?mXw z@_F(g`9@e_>Zhq+l1H=SveUB1#)H)FQ-`xD+1zY#wj$e@4f^i1cnCB*0G>(UX-gxd z@zV5Z_O!;dr_!EFTaxx_+S_TLrhS?AecH|RsPxoyLg1I|_P}s@UL7QRZXGOpL0xM0 z;yO%veqE3h&M^BGuuk2Qy)XM{_WA6ev+w7`=OA-(a`-uloSK~aoM}0;bN-gIG-rLz zj+}!zr*p34{F-w&Hz60F%gim#HRQT-8*`t`4dyP+U6s2fcVF(&+^=%K%e_H~rXVOe z6h1{kF;Z$ME=nB*n42!4v{BkAb14hzXp}`k*0-!5!1EL9CS@sQC1pKeP*VCRyXx{O z`|64)AAuDEjGaz7OgT<DQ#Up-p<JX4Qm#{OQ%38+oQh3g=dttiqVwQ+X?4~-Y+hC# zC6Apa%qz~5)%o)@YzbS<t_l}2uPV=)=L7mH^IGzz)HUZ#uX{4D@L9Hn?F4EX*sb)I ze@0kr93$7qV}Sd~aEGgBPiN0!cRVCVV)O^A1oi^<V!*nT-8;^~UI*Ua9Dj?1>^}Am z_8y=Pm(Je*XcD~zkV#JV081NAU>|3nVxM83V_#%nW)HH5*uSuEu}9c<*#lse0ahJ< zogQAHFz?crF{)WmMj|VfQNcp8@3Khr6RcdI9u4J$`Wf8Ni$#Ip1hDo(b8rwShs2?A zz_7*<uo6K}55P#|6oVfB9p(oN;B)3DoYJsG%+EP0(B}h$-#A*ZX0w72%mq1Mx)lzY z@7K*>zRE#^*j?sY&O{J?L|?{f;k0t5aN5G<;>_T5u*95B&VnGPYrOnmm<bOYS_W9P zJOrnkvz)V<vyronvzxP@bC`3IbCz?7bCq+0bB7zvO<=ymP35AwncQ41jmzPRxaC|m zSI@0xe!xKkjUTbJTszmxZDi$hALmZxKEs{IsOG-FT>@NUXAZMak7O3fmb?5V2|0Rh zUU-1bjmiT9ENIqwJ$WngR>Qsna}Ur9!hQloD-!lg9;mxvz;5P&wH|CZZyQKp5ny-o zcEKTe`yQ5qyP6AFxm&o~0RtKbf6yD{9e_aLu)M=?FjD3nho|P94ta}N6Y|c%F?p9l zONx<_yurMm^KRwcp+e!ga2hp^ngnOT^Qj0b7A}An!As!f;Y_GmR0>=P*HW3(0(b?y znp#MehQ29Q#VM#dY8ACM#3(W1UDN>BP-=Z>6p))nok<N+JAqN=815c!KZukE|Fv#$ z4{#52k8@9R&v7qt2f06UZ*lMBL-XVEQ}Q$Nv+}9=-2B4)vV2W`RlXy?KEE}8dVWX# z!u+26Rrwq8x8?82-=BXd|7iZH{ImHN^RMI&<=@D^QxIK{P=F}F7vvN$3-|@a1&RVg zK}~_HAXr~8sbE^ctb(}(3kyO8D+<;WY%JJTu)AP?!Qq0F1!oH`6<jU2QE-PB%}d}R zz%&I^w(ul{Gx47%DPW2+R$Y0x@Fazs%lwY3=4Eo+pn2R3e}7QlCbAMi69KhuyqVCK zVOS(y4g(WzE#Wx{SS(dDNUTrT1Hd_qC>|9A%@cU}ydqvHh!#chG$5EB3uPd=;pXLy z8VOgO%<xPqv^7&08Y0Gp{N=4sBcL`$@xoIYOpsU0bMQR80Iz}9!fWMC;kEH*^4fVF zyiVQ%UKg*M*TY-R>*cNHt>bOrZQ}Luw)1xJ_VD_72Y82g1H9wBQ@k_0bG(bZ%e+C} z5brwg7H@<%%7^k}`EY&`KaG##WBEirnNQ)<`D}gxU&t5prF<D*#n<tT{Gf?n%XjcS z`~bg!-@<R@PvN)mXY$+m9sExI0)7|2o8QA<&hO=~=C9*#;BVsh@wfAL@%Qli`3Lxi z_yhdo{8Rih{B!(^{LB17{t*8<{}z9QKPrF<Vg+zPk|0fh5?}>H0a-v1&;@Kkfj}q_ z3#0;>Kqb%#j6s1(P%Cf<Jc59rLC_*-6-*Jd31$k~1s#G;!2&^-pj*%*ST5)ltQM>j zY!GY`^a-{Lb_w<f`UM9BhXezH<APIyGlFx1i-OC7LBWvVy5N>zL@+9Z3S)(EVUjRS zh!SFjL?Ky75z>WhVS!L66bq$7nNTIv3Ask0Nmwg%2tC4putC@&Y!yxswh3nn+l3v% zPT>M!m#|ydBU~=*6|NSp6K(+C%n~)$Ih#YTD=@*~GY}}RPq<0g_vhvW2aA;m;B%-8 z;q$27@V`-)!e6BJ!k19jz+a|rfG?wNfxk-K4u6fh8@`s>5B~@CAp9*VSfIeSQcuF) zp`L;7q@Eww0;um(FH^6=KcZfz-i9Bcj?$vxpVQ#9xD@!;G!zXVDp%4o$m8sHQ}3n< z-x0nC|Bgl#_J`&uvGr{DFEl><CQS?<rj^0((p2#fnjt=hW{QW=Z1IUSPkbt^J|0PH ziO0~uYAv2XYl|n*X2s{yI>xmEDvdUu))k*m3(=Ox7tvPH*2S08Hq!dywX_|y@Hmzo z%2Xv}j16V9L$sr`Q?#>T>3BcwqVQvoUKbP|5gu#WEd0Fb?WT8yUkbk#UTAu+X>Zeq zO&>RX+Vq+5vhWAtPr_e>w}ivOyCR4vMg$Wjic&>L5k^F4I??n+(^pO3G=1CjebbLk z*P4E9`mO2rrhCm%%@dmAo0FT<o6*g<=FH}75m`hL(M4=gfk-G4i=-l%NF~yVj3S>& zR4a0bJfeW8LDV8@6-^PfiDru0MIE9}(E?GIs9V${S}y7ptro2lZ4hk|^@+BNc8T_g z`b7ssha#Q;Ew)uOAUZBOB|0NIC%VXM5M34xiiSkjd2OJK<w4Oc(P&|8VNxNgkXT45 zWETnxrG=_OV_|Kfr!H8xpe|I`TerThuWonUfx4r0XX-B14b|PQht?<5qw2wWv#_DC zwXm(Qy|A;etFWiAw{TtIro!!odkPN}4iug$JXd(RaH#NB;b>88QBo1Ah*(4^ViyUE zq(!PCV^M8U&{Nb<)LPV5)LztCw1Dp^`eSGv|B^*Zik26xDq2^xv8b<TN70_5{Y8h0 zjuxFNI$LzH=t|KL_(-3Fk8@${V+@adhCe<+J+Ho~zO-IhudlDJx7NGs>*|~9C)Yn! z|4jXy`seFks(&>ITEqhv72PPhU37=nQFNcz2YQtapbu#m4DpWhr--A)apDAViWniz z5aY#J;v6xRHz;O`xnjP!P+Tl76D!1;h>OJrah146Y!kc0K5@OcNjypXgm{{GrZ_0> z6fYEai<gRf#cRYH#9PGM#k<A9e(^!^fcT{NjQG6xviPd_y7;zuR1z&okRT*D2}wee za3qD2Vo9k)A<;<ml1hnLVwE^0UP+y#QSz8%vSg~{X~{E^*^=iZ^Cb%<izOk+Qpw*X zD<!W>-jKX0*&^8{*&*32*(cdAIVd?SIVw3RIW0LWIWPHE^1bB8pyZn5M*Ulok^23` z(e+;z#}^~&e<{Wn=N7Yzg~cVsnu*YfNfQYZ>BXjr(qh*{TXCRx^2DZz(<XKm&nli* z+%@s_;-2DF6W=X<v-s_aA5A<q@oe$#;{M`~i$9zA-Nc&>(1w(TtOiDdut8h=MT4XG zV)0-@bHmi)n+>xYmNcwv2)@~{vv{=O(~{_tgc3vvu_U*IRU#~rl^7Z>HT>2HFEKR| zN?axNC6h|p8o7;%l39(ek~t*{N*0&&l&mOOU9!GpQ^~fHT_yWU4wMX(oGLk2a=B!v z<W|Y3G*+4<MM;TLij*xCN=u|lsa{$wwM)IyiPCA(xzZP;-O{B&X|HsRbc6J5=}zfh z=||E}rN^XSNWYeTEB#S=Q~G-;q;x`QVrhCQrZlrOuar|NDpi(Nm%2-vODC5;Rr*Zn zoYLn@Uo2fwy0LUu>A}*|rB_OCl|`4uml4bI%2;KBvXU}oSw&e>*;8fDl+7u7zU;-a zm&%rvtt?wx_Ga1EvUkgZ@0Wd8_DR`iWuKRQRd%uLYS}Mkzm?rBk1J0uN0#HtN#%Lv zta4s?QF&>(vRq$oF1MF^%Nxrlm$#MAE`PrK#qyWRmzA$9f1`X$`S$YN<^AOc%LmF& zmY*p<Uw*lKsQgy>s4P~NBtyxFGK!2X6UwAAmCPusm3d?hvQ}9eOx7;zly%8o4t=11 zCq~vQTOHcVRD!KAQs`?#12nw7G%*!SwkL8_kp?MSC)*IZV6=}-6vAwk<+-6n<)xty zh}ckZCi4NkDKx3_AVIci_>in`q<g$AKMZBzDJ3fy|8~0LKf!-VF7W@H`G1-rC}mM< zOSa`iOZGzmVs1?M6-4q#;6lQK@wX-0`c^m|;j~$rz(EcBGGGeth{py4D<DwWF4-Qz zfUIA3Kz2wr00#MWvg3jw*(uo>**V!o*=5<FY)E!pc1t!Q8<j)lv2wUPNuDN0$+2>x zoGhov>2kKbKrWPv<x;s!u9EBIM!88|D|g5}@_@WS-Xd?6Pm#9?RPvefc6o=qQ@%jn zCGVE^$b-w}z4Fz<7Wq2)2Kgp=pM1M~mwb=BUw%M-NIoDxE<YtdBR?m<D8DQpln=?T z%Wug?<f96xB31!cB*{h;X$q7As~{@K3W|cRU@Hm~LWNi%Rmc=7g-&5qm=v`Nhr%N` zr3fe*6fKHY#S}%GVy2>9(V^&6EC?#P6y1s*#d6-DqF1q6u}-l;u}RUV*sj>c>s9Pg z^eYZ14k-o{#}%g(XB6iY7ZsNkgNh-=b;T{kh+<R;RmLje$|Pl)!l6Vdu}Y$ntfVOE zO182<fmI5XVx?3mQ>v6YrBP{8)+!xJk20WaP_`&rl~a^$%HT|8yRt(zqU=;IP<AQ1 zg{zf4%H_&l<!a?R<p$*@WuJ1pa+h+CvcKrI@__P?azJ@pc}jUkc}{szd09bL4l0L~ z*Oj-FBg#<~R28d&tCCb{DwGN<7*r8eWEDk4SFu$EDxpfOlB#4Xl}e{F3MeX*s#fJt zd4j5dszKGFYE?~9wW(&R+EpE@PSpYxn02bU1-+^s)pFI?3SPAu0#$((Jow+B+NA1J zZCCA5?NRls4yX<ZWPl1LZmQ#B>8Dg+N;nofr@E-RtQu4esjjPTsYX<zYN$F^4Ob_r z)6^(6R!vj~$^2L~MNL<;)dgyyTCA3;WongLr#7lh>RPo!?GY!a1L_8Ki@H^eS5Hy5 zsb{L&)g6jKb*FlPx=Y=y?olrX=vA*)uTyVOZ<Ex2t!lPO0~(`_%{3htvb=lVM}j zr`2cG=hc_gSJYS4KdWy5BW|nj1l9Ldt2NP@I8A~kMT5{}Xz-dWO^$}DVQRQ)wuY}R z&=hKlHDwxwMx$CMH);%;D*gh6N4Y^$qp_)t8kgFn@oDNcO{z_rNt!1#(=^jHvs8VW zpk}USzGk6ju_mPM&@9!gPz-8Tsk=36H0w1RHCr^>)ax`mRAt9CyVV;MX_|fNO`84c z?V5v{!<wU-lbX}&J*oqmv+91$dG!I!CE+^F70r<5hGs-Fs)cG}wF%lZZH5*P+Hpm) zHdC9cWoYxYMOwAC0+294ZH?BU^=TWlV9#kB+9&S`v`=f>!3IQ|wnN*gU7+pKc58ds zgW6@<mD)G7TeUm2d$k{FKh+-7exdzZ`>htN@U_>pH?_a(Ai4<<s17X7b?G_`_|Mek zf`5iCUnkO)=;S)Bu2N^wIduVD6F_j1E`ld?5lquXFkKhHEL{XaT?BJ=5zN;`uuvDl zVqF9wT?9*YOLZ#%RspO5SP!rfU<<&u2iT$8QKAEXy4?@3PZz;{-G1G{2pS)2d`$Q0 z102;wa6)&Yacbk#a0eRHoqm9`y0g0T0G9v;bw2~#0Jsfs=K=2P?l(RIFb`l6z;b{! z0Gj}IjG?~~Kp!1J<Kf0rjpqU72YsAANsrKD^;!B{JyTzxFVsu*3cXfer4QEXU3$O1 zN#ClUrk|+~>O1ud_1*fV`d<AS{RaIO{dWCseZT&oen5Xxe@1^^e_4N3e_elDKWd0J zzzrz|qycXr8>j}BfoBjK$_y%l!C*4j3~occp~dioq0KPMFvl?8&}9f2mK#<X)*3b% z`V2b^dkp&xpBRn?4W|re4Hpbo3`2$+h7rU4ikOP{iqr~p1)(Chf>j}?D5+33-e??c zJl_--E=z^6qDGIcaD>ZJ;j3uSODiUY%Th6=V!FPzqCH%kF|#5jjT<v&M#Xc6<rNDm z78~|d^n|kqxdc~KtTv2PtPf`#c34vy$Ou2~u!>FN?yA_Pul<vk{^X;IU5|L_Uwstz z&qL2V@JhwLh);sRDGwY{almlYaH`_dabHv%A2S6DjF5)2uQ;t=Q*o~1QpMnyi`zgc z4gk}SS6r+3t>T_B&X{OK7%|2yW3G{D%r_PqON<Jm)>vh<7+prcvB~(jahh?4F=*^G zF08m@>^3en_8MJl{zJhv<BEVugP?AV)tLw_TvLqyF#ZG7Z&J{>#kd1tpYfpasPVM% zyzvUaHREmL{mQt?l*$Z%tV${X7of1R3_x931z-d4RW<=U0WiICcIEua#Q;kyS5>}I zxutRkz`n|Zl}9VTs61bJ1>k3Z+W_~g;;NFXGODtws8vC3xL2wwtSYP0R8>{ks(b)V zRg<fxR|Nr{uUb^Kv}$G5`l`)UJF50p9jrQ9b-L=Cs_(0=RsB|VuX;jtay7a-vpTPu z12Q{WEvhc9)>Kzk+p2xw(Ns59Pp*EtdUo~m)jnWeVfCWwSH^q6NErGiRgSA(S^Y-! zmg-&A`>O}4Pgh^8zFK{&deoF-5{6xbG?keYCXLC!s5e!aYD_kh%Tyoob237GE_ATf zG|e>KG|MzAybWy%n&z73n--cDn?k0grWN7+L(?kL8q<2y#&CY7Ev9XzoeuzH0Dx{b zIMxKZ4M2C5Y1$)t_L=sZ4zdSLhfSZEPOyIg8cv(en$DXpjh7;5`rh=D=~s{dE(DnF znPbfH=2SD<OfYAgX=aXDU@mUT1z-UP07?Lq5tvH>6c3;=Ys`iRs4_=TV~)UPj=*J( zz-RWE>j9bof|JaX%uhVPG;;*g%@NEphY@^$x#kGwn<H3gj$pAlf{;0arRE4$m?Kza zj$n;Bg7xMI-Za0dyC2luH*b!hsT#lw@OabX=C{pnM_gp8GVe0&8*|!z^PVy1h8<dF zI?SGK?*FS(gRu|&8T%L03GhKK{U4jD!N1&11>gC!X`A@~s1;TJ`_AfLZ>*Yv=0m2r z<^l6@^C?jC!Zk=?J|nqiK4-pYzHA;e51Fr<Z<$BTqrn>J|F0E%O>8r*nNyQggRCJm zi)wP4OPkd-tQtX0Npoehwb|R;*gUy8_;ih`rlQ7D<F09_dA#PSnrCa~)x22qa?PtX zYir)Bc_;i4nrAmZ-@K^#mFAVrZ;ZWfZhp6UZ}Z2^pEZ9m_Wn)t_s!Rue`~(i0_GNA zg_7KYZpjSCAkdm!HG69MYd)?Ss5xG93cR1G`MTy}&383}HA6MmA<)nX(1+FBsu`)d zYk^u~Ay5n4l4MD<pe$Gm(L%OREOZOoQeY8U#1<*1*dnv2EINzPVzSg)92TFY-qK`g zwM?-*ZJA{W@^UP5E%Pm1mTpUrWx1u-vf8rFvca+mXzjCXx9qa)vGiLGSPoeREMrs2 zh>4KU+0>L!zF!S)N`QNJ{<^G*v@7wC(SUX1h<|cC27%J<gpdI~JeHmUwgaDze>PMd z=tz1ll1|6cbHLq=aNn}993BOtlgYTTJ0VNz;0cTFLg;LIA^4YteyPKNbu<hX|62ST zbOXIMbgd2t2+5%r0%JE-NbzHfJ-Tl^<9q4%(!s@$sBwUv4INrp&k22<nwo6+((<k4 zx7y^|yxP)QYbbN#^n{7ElWU)={d?`(wVwjk%;5N*|G#Sw4-XH(4Tnb#5B|D}|Fa%& zAL1|17?>}E(=jwN_*%Fi%&|g+uUw41eG)m%0K07e<}?GCG7<ExkDO)z+P}$Y{Ax$| z)MQNmA6Gk=M}pyFlYh==>{RjQ!#g0rz#|cVKWb2f@1chtHE7(kwP$M2g{5mR)L!Ov z)(+PGRC~SlCZnx(xOUVUgj!>*aBGq^m9xN#v=SLJtz>Jim2PEQ3pjqO&{`C^I$|xc z%B)J(8P*S0oz+NRXf;`Dt#)v@SYh>81J(v>bNDKWwblBhwaxmhwbR;V?XkXUUH6xn zKFBl7ul;8M>jo=m7hntFug+cn7g{K)sUm3IYTa(#Wqse;Z~e&niS>x}nDuk(8S6Rg z1?y$&pmoT4-FnkHVjZ<XZ80{uEzy>0L)ox4f{kRO*l0Gkt>E8i2+I%sSyt8yq=i6E zY?In#HkC~Wj1FzfM~5yol?TJ)UyT{G5%Zg17_)(aYBLyoR)7I#4H(kqgMn!}7?hg8 zux0>bq6>_9v%ny>&}P)_x0!6UKn}=*|FJVqGq{oPSMq@RKpw<qfoEZ)j)0r2Vc`fO z!XOcB!$dL%A;=v3PYZLHUEp~jtOLgi|C)Kkc)<0D@nQLh@nQLh@j%)H-b&5EvC@O# z^pDa5^8Z=-KTQ4?-~CzI=CJu}4Yo<PDYoghcH3Or0^4HSpKj^dR@m0KZ5wUdY`bmy zZHH|qZD(zlY*%eJY<KL@_5?e^j<@I7nRdRt*sib}>@{|mz1}_vbOm49r`o~YxbUI- zqs@%tw$Cnm(>~Asf_;g78R)f;$@Z1@we|;h4eVRP9oYo?yY}}bUJ%6v`6l~*`@yEC zd9C)t_M@U9`$_w0`&ng&{k;8>{fhmn{b&0P{zdz3`yKmzN3<i(k-)1J4LDN72GJRD zl>;H@cVsy5jx0xxgDQ^W&vY;yTnFD#IPM`wu|wf7IBFa&N4;Z`W10hez&{}t>X_@8 z4=f=B|Ed-Ji4*Er=veFsIhHzlRks|g9qSw$9Gg@ljy}hB$1c^VW1nNc<DlcP<GACL z{fgs^<GkaN<BH>|`mEz;UXSCJW5hA)ggUs+SSK88d4%^~Za9;iX$ra%rG`7P&LGiA zc2dSbcXFM4XQ8v$DRZivI;YWTa@IN>PLDI-Y;d+XTb)y!Q`C2yZO)m_c4vn=&DrT( z;OtUOadta<oXefP&ehI!&JE5@&OYZ3=Wgdd`(fvP=RxOT=W*w0=UL}@=OyPA=T+y= z&Ku6#0C!waS8Py$b-`UpE`%$?h3AdBvRpa*SQpjBba7omm)KS2Qn)lOgR9C_<FdJ2 zE}yI3)#RGwn&N76&2+WPb*>IR+ch7c%he6g<67=o<yz<3;M(Nsb8UC+a_w>TyAHSx zsVS}j*GboD*I5nIb=GxW&30XKU2z4kx_(v{$j-TLxNf`dxbC~7-Er;&cbXgJ#=41a zvYX;&y18z?yU<<iE^{l~8n;0$bXU1++zz+L9dI|OrS2AYt9y#O%{|lI?(T4RhPQ~^ z3*24qZg-D+g?p8IjeEUX=HBS;b8mO=(u}zGxcl7)+=tu)?vp|HY4=(8dG}@apnJ%D zUEy)xa*w$0dtyBao)iztgY^(SWDiBHQf~0jJ#0^bN9ZZ`lz9{$jmG9Nc&a?L9*4){ zsrR&aS~V`u6i=IHrl;N0;py}&@GSO(Jj*@3o;8|!&w9^BPoHPIXP0N6=YZ#sXTWpZ zbIKDu<vHUyr<vrr=(+3}^bC2fdv1H~C@5a2H_n^jP4i}WiC(g1u9xCvdJDXTUa42+ zm1*W{p<b0&=QVmwUYopIv)JqM`qZu72Ja+Qzjulk?9q8=dfUAn-uVDs-fnM?cZGMA zca3+wcayizyWP9XyT{w_Js9*J_8#?~^q%&f^`7@$_Fnb=?7ih3@!t1EtGj)1z9b*Q zm*FG&$Udr%>ErtNzCvHIugs_N8GI&Jm(S*N`Fy^5Uz2Z=?+M>D-*n$BU(h#K(c)X+ z>+*H`dVI@$z3N`yYTr8F2Hz%MpKph6k8i*4pzpBnsPCjNc*b|mcgc6fchz^@ciVSI z-tN2akM_s;6Z|QDgl3~Z!;kl8`E&eKKhw|k^94QrLci26^Q-(iztL~<+x#AXz~7+R zr`a#)^SAh)@K5tk_s{YN{hj`W{>A=~f2qG$bI`xqzuv#e-{;@%-{s%u-|s)@KkPs1 zKiTL%?LX_k=)deA^bh%O_;35~`0odz1Momf01?Ot-~;3UMRQ(rKEMoc1HynfAPvX@ zs(>zF445>R0=9rF;0x3TngWvoQvz*)S%D7Wl)!vpM_^%KaUc{}D(ngG?{6!5qB%bF p)=Wm|+RWT-m}l0<Z9Cf0g$_NwOcy%0OuUV=e0SNllV{-2{{c0Em1h6| diff --git a/src/java.base/share/classes/jdk/internal/icu/impl/data/icudt74b/ubidi.icu b/src/java.base/share/classes/jdk/internal/icu/impl/data/icudt76b/ubidi.icu similarity index 58% rename from src/java.base/share/classes/jdk/internal/icu/impl/data/icudt74b/ubidi.icu rename to src/java.base/share/classes/jdk/internal/icu/impl/data/icudt76b/ubidi.icu index d5c81de1b1948d5c8a9a26b746d0d552a94b99fe..a333bde075702293e5759a31f295c1ca59aa9f04 100644 GIT binary patch literal 28464 zcmeHQ3y@uPc|Z4__v7wvc9R%m(%szf*j;uhq)1S)>=J0nLNu6I0@bo<1(F#U@dY}* z66s6KI@?+*>fl^P<3usSqHE*S)?@~&4$#t)iq@27z}L`eMnREErTxD1-EaSo^FNP! z7lfhv|8vgw{(ay7JCD8h+>^l?`nOZ9<(5^m>el(YFW6nLTUMW?3=rQOSk^V~1nsb8 zc|(>J+-udM!&a^5>x!o??5clx`&)N!u&kc#;f`9X=V*P%zQw-H-fthYzi!`e|EvA) z_PqUf#_du2KkX;%rybjg9pCA7Ug8WotDPqMI-|}8=8-z*I1|oA&Q@oKGwtkhu6J&5 z-sk+O^I_+&oliQSc0TWX$@!{tk8_{%9p|WX-1)Kd6W4Nm=P9?>UFN>jUFVLtqwWUx zmG1dKr`*@3^fLEK&|l-e8SFRO^X~iIo7@k%Gwv<!ZJ^)p9(30^W9}TpK|I*M0+r0W zUvs~a(tF(pL3+r281_GOPq;sKZ%FmO@?5Xstw6ro^w!$*-pS<ajaQ6$dE5Wh?%6m2 zVUu^Uce1zB+Xi#DcfEIc+vA<yo;LRZ?`H2W!SiF@?Xdr>n?U7PdvorM-dCJ4?+EC= z3ETZ#f%l;IJ?4?Zv9e`Z<-JF|$Gj81=O^Bi-ZTDke~mxnKIISlXZYvX^Zo?nhUsth zclgu(F8@0J9sYa$i~K+FXTbUq|Knr_k6FJ3`vZvX{TXYs)W1vU{4XQ#|GobYYE6KU zW(C`~{fGS@`v2%Z=|2;AK_gfmtO<tv6J!sDgVT`<&Qjxpb4d;^AnMq`CBgRKGJ8I_ zGL4*J{51ON;M(9l!Q0U{_~Z0Q9+U9^f1mvr*scv`VSj7TVr%ee<h&2qO265<L|+&k zz+?QvsAQ>%r4B50V5tKy-VOxUdN;eD%C0ZC19ib&!6BsXcj2DAH`N>_-{70UKY81N zhf?dE!GD17kAf56*&93o`(cou4sCbTo)3L@B<!WAa7CN0A-c3*>cCP5mOAj_??8A) zcv3hF-=1@4cuqJ$*6_k`b9iZZdHBZgs<vi#_!fJA_^vR$2g5z}gNyB0&(WTvy~}&I zBjwq<ulK&bq;E~%8~S#kuI~U@`i?IfS~k6`wd_0ntNM5J&-Ons&=*Zad!ob9|JGWy zR(u}rX~s9k3q0$<<9Mx=c*$h4H#yR%H6|N-g{>Q|aip6l5wjF8deIHH)W2@JCSn># zdTKq(gxo3j{P$nK|Ac=*&w#>@;qw?5pD#)?gy!}MvBZ0VMFrqmhUrOAiFud*h* zFTBT@3Xh^39t$5~y-dT$!^fg}_)A&mOhplF{ZTVo4Rka*GujxP7j23zcBb5sXj^ne zw9^@jcBjuYd!y^^`RE3a-yPkAtBU>{pJn0<E{JB+=bQVYkAnWTXuo?t&~4Gd)Nek* zC$|eTIud;=)&H}*FZwR{!DnmO{~-D=;REvHvIO#f$2HQ#j=L{T;=Xv5Js%IMUP6jb zK|Ve!KD`}vZuBU~?dNa84>|XX&RBRL`a;|D()be9-i;Jr9`EcXj$(pC@$T-UJCBU7 zgWkNY^Efpkf@k0HyHFRm|BkEnZX|b8yy(vY>a*2YdDbf1fS<t{9Xr0o?J-vy-xlwW z;k#ozhmmpmB%eG}`G`5HOdEg8J{CU^e>=X<ekgu0{zm+8{76|0RQVWeKaHPCtTNwj z>`9RHVH_S+nt5kPG-uBzE7;3S6ZmaHo{4q`m2Je!cdBI6nMyXme1)v7!nZ$@;@uQJ znMS8bG0G>^WKy!A_mp>YvN=6FW|G$=uM4hDuCU>0Kr#*6RiauS{w~l=ec_zwW+vCc z-<32nc{|eN-N{XuJ^2u9A4zV-XA?%;nWU8*0G~UPzhQgwwG`nVuB$tm+}mB;vlW%x zn|v>MFrCMebmFf@VkX}w?en*{{|cwopP7N>TY(kAK5G*iAME58S&`+W6Sy;@$5FN| zFWo%&xivdIE7}TP51?nH|Cm}uz7*pAg`yW1-(Mx$bLt~^RPfa~=w-Y6PTI}1qqDfb zJC*Us;1R$+QODqy@6=9GXN&8q+fs_f#!FC@*|Z~yH?7>fM@O@Tv;rvWRUAqFbJp`a zxqhrhAF_t*vPSoQ?&SQeYVV%A3e3n<7k0*h7fIAwo=pj{3194Mp!s!9cx_~1;))yT zU8Vu|^+tMqnAh6~4uT!$7T9Lma|=+~wgAN`EUeM#c-xcpGpTIOYSN181?QwIYP6B4 zhQ>mToQWt`SVYx`#Yr=1RoQG?q~4*m0h_vB7mkOl!S16hv>2EDD_n1Pn2#3Hym>Iq zs&|H0OtrJbURxlBHr&e<=JS}}goc<i=_K^LJ^HW>IUx&<?0GBgMsHqEF_P(8p0pM_ zvz1^Tynb=6OYb0fZxMGd=9nUaskR~=XO%JbN^99`p(Ja>I>~|_gu;2Yz?r~DvXLHD zJc6R9D3#A~3nyX;v@IzP-W3EIuRx`4#j{q8B8h94Db?G6{HR4qwaSv<>1sCR$k&<w zepS`Zfg^4-^ejSeva?mDh|v95Osr`gdL`BI%hrLPwbel~WhjeQBeRkm&pcADpJ_Hy z)|C4bCiw|(xsx)UiI=0YcD+Z4EN0ffnudEU(DXRHKlxSao;p&IoFAKS$>Q-H8!3LT z6N6Eh3QK1k##7ft9Lsz(gax^xepRnVUYWcuHCMSr8C!~@Eag|Lgyaat(fVqsU)Z54 zgS;q)_Z+8R8*FFFenr%TkMZWg$VAOPMcRDiyeO<B-SAma`n)L5Q`M`LsuG{eRE=7b z>dBHE!Me_<T3uFRG&K`R=#BQyha5#2$}mJ7d7e~<jEtUT)s@-vva!Be_3HhCBt}5G zn0pAuhq&u>ba2)pbhVYLMbOcpNZzX+e1zDlQq>plD|Eajti{ebK&U>{<2MDzE3!u0 z9qBJU$E+@@)oa7PbiQWlCS#$L9jZ=^;PVpKyV#-jusf-<8hE|x3d=Cio4UYzI_n69 zbxdV6*2xs@<@x0Z6E9~e;?>&AGG{XtW0ODnAV>T1wJ|0~kjzqXyj~&3Qf@{yQ?68x z7cy7R8pcuUVF|q!H}LwQbKZ<oWW$ImcJ_)aul);FXIEJWzqat~hksMGA{Yo(E@;qF zZx=5=hqK`~GX4Y<!e657yxZw_HUzEU_Vz0BtAgL_f;)mQz#HM85AKAgwDgM{?%OeE zL_d+E<vN&`>oNCQXa#<E9G^XT6l)bng*cI2aKcO0iIrlc*vLo!l+BTpGnM*e1li6$ z!fxg`Mo{u&*&MZ?#iNzC;SojKY&!eed!nqfqQ3T|<9~gG^R9G~23Ba}*)a=#tf3gx z(L@fB$SyD$TUf}eFRe>h5gRu#5sxRYk7Ys8pAgxHDQcN7qEs1s2xK`wYtajNtQ6NR z*USh^<#?)+QJAWpjEz>d$dsd)E_^3SD`IUv&DKzG|KfA6b6T;Qv`%r=W}~WS)?@h| zRYp039?x=7b?gI_kAsPtj)pkjsQ+}_x5ByffP{)iOFkp;oD(vi7gckrbzlXEFDg;( zB=Nb;S*cp~G-ZBEv?2Owba$pB7&F_>h^UyIR>Q00^>8lELXomW*9OOth1P+*xZ=qV zbzG_NqWrUIO#&NpV{J6qn=3<^b?hT3)>A$afhI-@MC3S+z|?zza()FOPUSG4s*!O; zJ?zI6W4NYggHjbbQs+6uS`cwoTbr;NIK19F@kigzBa{qjeSDu$u~<u=YFHwwV5p{! zCH!@F;YiZ@=?tKKen;4jl&>MC`B5edM==E-9O^2oNu5SjX;*pXEDC=XrF959Vu?Y> z;lfH&3wJ@L=poC<t5E{90*BR!N(7Qz8^f4%Y%8XOTkJztxq>X8hrphBcC)@p6#1Cr zbuAxh@s0#*)Gq6B)nvrbM>j`=QJCU4@9Kl9;Lhbm;<q<>RC!W14FQZR$09HHF^|_{ zgsfJn#|ytQPLCwHEK1m^4n{#e^5(%_?4eUrR2D0%F~!jtKpD}_xyV<Q)OeFEFDD+` z>Vr@Omf(so_&pCn?T+3%5$|r8xuV>~HhhbvCcPVC#xK(HwNXTi;)N|Ld<Prf5*EHX zN7?CI$={o5l>3t(NfuMQti$({Jpjags+a#Fwx3SHbEo#_67-{IR$PO=s?OxQ)6D#a zG~{pp4gNK~pHA5p{_gXdI-%4J>>S;x<=)~|ntfCJa~4kYLmPH<F+<HKON1(GRG#c} z@Z__b*-6df92HUGzS0dBExaK|@3aXF&LuR}IErK6x%7QFl<2)T*7JLDdrR+y?1}Hy zAqs93wKL^V!guRv?p)v|+uB-b2HitFx`ZQVp=`KEE$(#$Ri;>qQY|J4--nxljr*_P z2gF;xf|Gr&Q{J@`Z`W1jvNdrf_^CW=)it6j!RbClvWV)2%R|OB<k?ic+{;dQ?h?k} z@!L}H7pn+YttKncaik2y>-)U-C^@nyyRc2RuOvFhSyCylIa_79W)hAEqS4iXJZIXQ z>V<}}P`|U{QLKp@WJQkGqEd6PdWXnLrYQdOX#Uh_)@E_II<z3K54NL4@Wko9MRFFo z*t<$D_Ccho_@Z)Nkz9vBVQi+dS2@p7BAeX3^7woY8M(-dIwIC%_T~D@{PgJR{%XA< z4)xR%9lH~m(dC%MB2&DKSj2M$OwpHCmc5EuQ-r762#ZiThtTQX)npORh~1x^j3DUZ zjw<3%2Wc%RbvL*oj3!jZVGGh0Ox4O>#Z<;XPnPv4Q~m7Ac}dnIWmGwWy*b(xC+pN$ zQ7OgK>Sdp7UW(zpjGf2JcsidKBlL0vY3ZC$&kW(Oau_W~saC7~&6%%7Gu2~?WgP>* zZ>rA*P4Rf<6-{0R#mYU&@+SPO7bB9z6eH_IysXXVg+Fp-gT0IW@EdqJmKlTJDl%Kk zwWjahaulz?MA6Trmvu50d#gH>coj@#1mtn3x>Qwh$C1_C@jS0S(3|i(i4yqwRaGpD zIKg$17k)*pJUa1BK?|^RuuSJ*r#e2y)hMsN$eVqbny*l^mSc1(^6BTZun?z5>ayxz zhKAlaOi{8{&yp`QQoaXT^8Y?mizjrhz9<)e+s&h#k7(9wGX3`4{a(etz4G^M@#MhF z;r+mDA#L9Mf_s%`SM}(vYILd0ZoXax3fEIag?GU{WC5UxPg&J+M&cPhYbnxn7sZGi zjg)mdWuLND=f#P5-9tsxtsKWxx0_`2HR(~uBhSu0`F27u*%>=OyB;MXkkhTIobMr{ zs4*z1BWpKl%4&&>znQ3+I+yVGApQi_Ek%UvZ%&<S)ca{xDnsPe4_S8r`?t<ebA@xf zIcOhm4%w~dI{R?5=^SpJR3B<?s!cR6tPM3UajfR8&P4Mw&YtE0XS(@Wr`5c}-qSo( zvzqtUk2fE;t>zQ<Q1fT@MDs~|y7`OxMDv&R>E_e*J<b2Ax0=7IA8tNVw@y7~wMIT+ z9Uf^}dqzH0n;to2O^p1!wrBL=+TqbhYpv1m*N%_=z&bv9!kRwqnO&A`kJ;lk{C|9$ zMx)_*gM;hWuUj`fT&u<L#*G`TaP7d#Rjd2P#>aU@1=Lv!aPVvC*x0z!9sr8N<1xr% zeVV5hrep2e_>_2HU?5J%N*JqQoU@`ax@=j`SbJ>z&5cmT>8HcL&&nCzpfIdo2M?21 z2${IL<tB;m_nx|;|FqN2ICJ?+Uiz|=qF~KX^EdpHN8H5M{T2D;XZ_Z~s-RQrYc(hz zDqgh;id_kvYc$pmHf($2#__SSv(Ij<Uq7J4zX*jlUNQYge{kjHJAeNTf0(Wg4!=G? zf3;<;ZVV5{*JL^XXWekPcIB$^@xifISl+t$^@Fv6wb13k@!#8V8PG;t+tFyOj4kVx z=bk$;@oMXJ*7og|HTl|Yn>KB_;J3G4_&b-p>QxtAbn)iRo2M-J^(Gy^d){j<JwKCc lN%8-@16R@d+hm~`Z?debtT(~L|CYuJw*%hrz~|cI{{T10IH>>t literal 27584 zcmeHQ36LE{8SeMyK3;aS8$t|8cJnq$ve`upM-*1s5Thg*B?uZoLV{e8Qo-92N#ccw zDN?9_;ITl-A`v9fLex@XS&DcdB3eL2YfGV|EDuB?;sO5u{O{lHp6NN>TM-JkyJr6T z`~U8qnVmN?1kwM%fnt^rHBlEwZ+`jadR>UFnowJ}5a*5wapo<cTr7m!FNFVNQ49Bo zT4RywnBmW^-+IE^HZK!m#=Ky-Ha6ok^?vIj>r(3q>+{yvtlO<Ste;xr)|ZXjFRWi# z4_SY-_F4b7p0I0nV9&H;dlviJ^Xx^;Bee(ZW%d#F(e@hqc>84gbo(6pJo`QNR{Nv& z4*PQZbN2Q2&GxPKx9uO=-?#6vAFzL8KWaZ=|K6!NmJ>O>&H>ImXOT1H913*AS&`7y z&N|Sa<ZJ@_W^3Fz-+8C=erJnwk#i~NuW&x^^x6xY>mUx|!M+nJ8FzL$Ur*?_obQ2j zr*k*#?{g-c-#O<b`ae65J5RYD^3}TAWsST0lds!XG3LOQ{|lYP*a6`%_oeRs?rYsu z&`)tscaLp(yvcoAi+hKAf%_rwyu|$k?60<;gv!^u*EyTro%RCvE1>%ZY`1d-?)TiE zFrUzUuv)oea_@Ebx)bi--6!3L-A6pvo8k31zxU>PO>fW|_m)9!=-$!Z8t-`TWbZWZ zZ11h!5#GDKEnxky_i?hj7dW5tE(5=-Fq8XU)@G@9t<-rpAn)Dc-IlJ8eY_udcYF7F zd%TCeN4&p#Px-Dt!|(AX$nMYe`;qfspvU_Mk?bGd((m(M=D)&UZH@culE^KLpG2?s zH~4Sy&q81SUCBz`rQ!kph1OoMZSX$;`;YmTvDLpEIrklwKHs35?$4eXz%_pMR5M-4 z^bAbT!1N3}H)p`#fOi7fvH71xoqw%=BU0x_a7})DqS;Np{x|&ZxU2j-6YDkp&%pP7 ze*!#f{zI^z3-TZRea<|fPdEnzHHr$n7M($KdOtk_(=#wV1JC^#2%5p{U@rW6&h5cq zu#Bw1^5Do|WpHfpn&9;<%_+eftt*0agX9`)jR)_W>Wt0!4D`KS^Ad_Y^sW=SKG}6| z*Mr@Qx(`OV`#jQj-_ZT=%*8X$nK?FdqNl%Seb1FW_l2Y3)^JbwRBfy_79E9q?$J5S zNgCY%UU$VoygI%(zOxZDR!dtaT;t+SqGZf;yqt?pxas-pWY%O%<Ko7hjr*nCF89pO zfBO0pd=Q?i!0-0p5_}%x;PXYL2k;yWdyqVBQZ1eG_K4ntYg6)#!Og4*z8&0Zj|AUG zIk+phm-Q+Q9t`%XGV#G5AmTCm`ru#oNN9&qI5T`+I6r*8J>nb?4u^+^N7@U*mB};B zTDZm<503-+#PC!cRd_l+%f#*<9=<7gzIkDIz8o*azc=yQ7G5m15Vt){?#IK=Iv0jt z06BRY>UM?j+)(x~^#m@wJ-mag;SVA1p7599uOSxh#mznZ1M0(ngpZLusz;$U9vSb; zoiEr6f~%t0Ezf~yff=(MZL~Bxq#b|VH+l)wdX%nfUkcX&$|{VD*0vvQj&Kf(PBdGd zM(w`nR7aTcqcfv7M{w5=B~N&xZPE+R)<`?@q^*pLE(Jt*mKwp6)#%f(T@%5PTGIDL zH(C3luSVaDzFXp1hGeuyKZ<^ixVWm+^Nx`4{ZR3J>}94A{FZI6t5=WcVS6Nc1p4Eu zwhG_6M}#XC-uXpODKXleW9%sw^d509h`Vr2-7WE~c#gk5?ziCAc??h5<E3&W9$crX zC%)+4L5~lC>wFRyAAvMp0e5zgJ%*?C@k#Lp%wWXb5}y^nHGX^izW7|W#~*|@3YW!~ za9y3zc=8#4XYo^wiZ6?=jju}jb#c<+9gfoDouqx{_SQ$Ri=IsPg(rLwz&>k}8V~H` z7m85WNeAvl;iD*9!c8_8UVmo0E5hTz>u&T6GjBI5DAqyTJrq5)_?`;Mo?aJqMkQaJ zgSl+YzMafwGNU_izdMm}WpD*>o@mD4O>|->slCy4G}}swsm3c%mDyxQG;bQYd5?}} z3uz@#)~h&@{CA0GwsZYhO}eQXva6c3_tPimXVvHK>8rquOm*SR*zjS8Udw+|LTtj9 z`x<Eem)#Mv<A@u{Ri**g^+s}jn8(}jZvs2^wXkh(^|e50TMHDsw6G>khg+Vk-=4_k ztR}6jUUGIarbY{iYG_Q>$eD<8g+)}4n3}XbsVbXotul9LZNR3F*Map=H8}eyOD)D_ z{|eVzGt8@nG_T*3WKGWukC<v_iM`fB3~jhqE6nFHzX=U7w<n#@^Y-Y&Hsqu%IkM-C zv=hB~JjF<+b9sfBYR^`JdGP$jzA(9h;I&0wy_jQ)2&USKbevVi*rtqSn?Om`$Z?Vd zJqU&Ktc4?iSF(|;Dz2cMQ<Td4u)vO35^ZgQgI5KKMrRC<gQ-*TsAYeZa_uUmdK-`* zwJ7OURg%29HZ@n4H~;;rs@(;SxKT@^OTEd?R+S<`=WQynrg5Yzsg7SZ4!qaa8_ATR zELxAuN@_gwNV$Hd*+^AW?oXKHC%x5~RPju_8kM!D=LnHy&-z!>@El9DbX<CV@~cdH zrjd%|{MdX;7LTvkNbz@_Y>dKGTH50<o@QOfvCOL>EyxwkSM_Stk*VX-bCpY!aZGbm zrTl8OkQ|{nIz3vNFPxz&jl3v^_Z*i#H`vaU{fejwALGr9k%^jpinRI2c~MwNvf;C$ z<atq^r>@s4)g?ZbsT#c|-IFCXf_3dty}GQ#XnH1+&>QXTH#Leflwrs^@;s>y6&XFt zsw=bSWn+D{>h<ddNsNGWD%TK<4{+CRYvZUz=xQU?i=fq@NZ#unyh3c%sqTx{6<V)R zG1a~c5UMwQ{no&Gg<`NZBR!?ZnCPI|bZs~<?T?veld(|BHeIJj@NtRboodtPursN> z8hE_=2+J_gn`VLcbkq?F>zJx&tWzo4%k!%dCSJ`_#Ot+}WzJ?Q#wLICL5}w2V`EH? zAep7&_;iIBOSu`<Ou5o@yp*|m)-aA<4@>AZwT9;p9rI?KA{$0jv9nhw+}0bc_Rg{Z z-nMY>@n`w_`Mv(^Nex=+t>V?^a2C8H<2#@L{t{*TZo9``=8yT;v__F%6}+$WcltN` zxA<T3zYI@l>5UxjTQLWRkEqdV9n7osnCDt*C4OfdA3b>#Yn7`)oXjpc>80xANHJ1w z<deS3=19t!NZl%eYG)s5H**{#DfzK%j+)fsYUORXqG;QZ^zPQ4DC<Pn-RiXd=Y`mB zNjhm@gccqhJHU@M6oWeI$RQHhB_?A_3wd=XbxA8?<0d=eap&=|EGhaEBKt5!ALffF zRmL6?S<TN{^g<ph#c``OGXhgJo~mRNrn)C%qm?Zx<tV0;zloBHSes9?H56RG_}FWo zR;(teQ=YZisOp*1v3!jxqnsff&vH?9>;sh7!9-1~A&)nje_HqB;8?m_LB-Wlj|e>G zq|C=f)tq`ASOMb8N_0C(d~9=8s+K)Xna>ZGg?|ZmXJ!OrcC<1gDrTqA@F;maoQtzi zq$<(5!Et1vaUf4~MktKMl}azlzayzhVxvFSremTOH;h&h*pI!jqOy(%)G<mTBFA|o zE^4I2<5o3Qc+98!skpKp_G5}MT+@GpQWa^W_H)RwAmWbH*re6K;rZT<Kl-*Gp=C(w z<Liu$#ag<nVTq`Qp_|&4@a^v8O49i02%vrbjIbRkpF>RZqf8c#VhTRk^ifum+Ks9* zUFDgxD10wU<B)d5l8umq$&n@&o&}YnhbkklM@i5M99AbQVI*^)TCdq7PfNIYR#ndx zn5pWi^6ahZ%K0i$<Wr7?9=y`>8wu9vvs?`=?S&ZW*2#)63RA4RdZQ|M=JF!(*PGg^ zJSp1<0gS80BCpP49-oepvR-96Uiy`B=}3~xqNJVbU=-9NZ*J_x9%*Wd%3@_TrZ_qR zC?ncA7y0Uv9&fVc<;1nE-UvlvNv;Tkzw?mPYU{fb_1g^-UzEGphF`JNv~NR9_(eKC zH;QOcytIXd-(cfc!qPX*QFc03^7p11)%nSfB#S9t)#3NaE&$>_(W`$ETTiFpxl`-D z1pVll71xj+ReSR8Br|^@4f$Jtga1e0r&G4czxzC<b|}pT&KzB-)w#v9H2bCajRHIR zp$%trDoxL)N`$Ivbe`<H;K^qvy`7rnF)E|vb)^$7ocuzLzG;&foJ(q|aTLeCyOQtW zP@?bNSkK?ZZ7aPNvL}95hbXvF)TV?(3BRqQzG;$M(bCpRGo(HA)g>G?3uVJSYH^=N z&}E9HDBWU`@O!xJu<`t-uLJTcU&*OHZ`QuGlV8_W<s@n+oM}X;!_nl~biF#3_IUls z(@~{F^RT^Omh!$s<j87Ot!N#Ibd0d1Q(j|PU3G2+%qODJ(S<x`+Lq|0hA~mUsp2Z= z|AM2u+T?RQ7M+^?^)oChnWFga%Y4^m)@E_II<z34Zfr-3<cUlB7Rg!UV(%)s*awlS z;>*f;L~0!pg|V5cUgbPT$!zNE<;SzXtRvr7wN&?4D^q6;^;DyZ+b+-OYTQ(jDPBb^ z;<*B*=u0EZo>i<V!b{r-i%>a-)MdTNr`qbLqtjVbER$~)9b)L~UM0%p!=pzVp|TfS zkd8sut?X4yRSfiGIUR+gNjLW8yd<Z+P*y#4K0PK=H0exntP`!#vy2p*D${z%J)suw z^>|$>jzp{KPu?=SY9nnqp6-DNDynY9?6jrzRprU=8j@c+d=BfhDi-<avHY8{3<Hns zqRz8GIQqP%rLtUTmoZhmRe!l6`H_sC?|~NlMX8Ug*k85sS2C)u9iA&RQN%InRh^!T zEV>RQu9B&WfIK!`m#8Z4II@~M9+%Y{dJ}#-Q4&9W78J`et}PDU@>Oo__%ditOefDF z(lNYt)hHKK<jp=z&1aTb%Q0yx^QDhdX(28hnU;0`GBotYW{Og^=`8s&BjtObMSq8( z`c{j_f2hB>GY-+L?~3HtW#@Yx|C*9&Wd5>W-O|&{mBr)vU*wZ_ec(07v+H{F)-`FV z%$`0^NtP&FPZ5>gRjyA}e9Ed;GZN4BWi3UT&Y~ERqmi;MP1&bx)Om3-KJB3+rmY;u zG;KG@=!^QIW{P7S$Fr<c9aXoXq_?cSx+c9EI&#{o<Fc==&6D!67$=XK&bvI{s(O5H z!FOJrQbfqU8);voUzf8|86uClU+e_-n|6P5KYOCtXH7Kwt+D1pYfrOj?`bZo_cvG8 zMw_c@{moa|qIsn~+PvQ0+PuNu*!-eB*4$}rZQfQB&7agKnvYtd`B$sI`It4@{F}A0 z`FMS_`H%X>=0EFOoByhhHUC}T(|ocn4%{oomRv3NEEyA9mt0rdxa2l5x@2E%>)@|z zdj@}78ykGEHZk~+m>B$%*tqn`VPRQA*02TtzZbjFXt-`)-@w4ag^L&0YEiU&`En7= z@0~qoZuijeFpsE!+VcSp-s%kv4cn~-px9h)ecT3;JhdQc^XEq|h<bZ_qomD-HW%89 z_iGH!oH=8t)t0|-Ih1kGLGa%Z<utcX8U_}^L)-nNOk7<!aqM|r2QKSby7b@|&D#HY z2P_KxdHu}=-t(6@v6uGO<iid<WO7t6Qv<acln)ipnFGbnhM8+L2KpM7wS4*T(9q$B zHwFfJwfN_taO%k$-?-tllQy05hSQVL!SbgY=+6>jZe#J{=<Li4z)`n2m_K{Y@NnPI zON6^HI<c?TJ0E7bZ}@fVUk|hq)z&u}vm=N+Vq|1=^rhl>al#2gta#09SFT+7@|PXA z>J_g#^2lS3Id=8x)oTR2#z@*Lk9zgGqch2-760cma3+nvMJ6ZX4EVosi8G*!GyVfg C6Ju=v diff --git a/src/java.base/share/classes/jdk/internal/icu/impl/data/icudt76b/uprops.icu b/src/java.base/share/classes/jdk/internal/icu/impl/data/icudt76b/uprops.icu new file mode 100644 index 0000000000000000000000000000000000000000..ca241674dbb90c1150fc7fe95ed0b3a1a8aab837 GIT binary patch literal 146880 zcmeFa1>6<I_dkAX_uh@Wad&S#iGhJ&Az)&F7(8|db}M#aV;~3yHg<xjn22Hrpu&UQ zVj&h{cl$qQ=gytkyv0Yqzt`V=zjo)$sW~&-H4|In?d4*2EEbO?V%u+Z)ZtPr7BgUG z(@N*ZV*GsQeIQH5VrM@ei;aFQ7Q5g8GH>-l;^$pf1y9>B+gNP7qYmmDi{;MET`8|` zsfi_0H>GY*O-((VdL=b4wIH=9^?mAhAudRQDYOVn3cZAth1G@igpGxv!ZyM#!rsEc z!coFu!g0c>!r8(&;bP$`;U?i0;V$6;;c?*^;RT^vctv<q_(1qX_)7Rm_)8Q;O)Q9= z;?iPoaV2qpxURU7xS6<}xUIOWxQ}><c#?Ruc&0c`yb$zm5U&vL5vPg|i?@p1;!EON z;tX-2__g@6I6s|EXVZD{@ANY1-s#oS9qGa8uJpF)wbT2g4@w`I-Zg!CdUX1N^a<(f z(l@84q%TiDlAe+7PTwbPnSLcbFEt~*ApLpzJ4k=aBr<YF&lEGAnPpQmL@l#YW<X}$ z%tpdhnH@4)KomY?b_cEfGY4mmf^-DTr)JL1oDVg>Dsx%pTED)ZlesB#J90BqGY@BG zWV$o206j0WAhRg*yQoP?NszLc?}0L;o>EC#Lh1u_KWQy#kTeviU8KFGgQabx6H_y! zGo(?{dD2nRHPWRZxf$lE(iG`oX@>NS^n&z;Fj#tD`cV2z`da!B*44qVJ{?FulT=R2 zx?Gfd$jiyS<<+FW<t}+!d2M;HysNyAe29FsJWf7IK2yF}zDmALzDvGQe!zpr<!7Wp z@*MeP`7QZ9`4gbOkbh88N*ZDvB>#a+0;QmIDq5LdnsUqeUdpP{AZ1NueK#LGl*>~# zksnaDRCb_wnu68t%6`g0%HhP)+5QGA$CKJArwN0V(W0iDr(C04s$41@tV~qyP^P73 zD37APGLtV)UZ~7g-cnu?w*-s%xF(f_%D2joxTcifpk)WCaaB@HwFs1{_TX(Ptu9B_ zwz{%^t=Gm;``4z&wA8g2{T~(H0=SOULF%Szm#C@RsynNDsRyZtp}q=xvXhQbPjlO= zXM^-S^<p>Iol~zOdG#hYzgkY6SXE<6HI2sP>QrK<KBPX?m<O~{pHb&J>8p+V;4RfR z`P|~6)pw))sPm%bwMx~GYt=+Ob&(23_xhp!TE9(W7TH*1cA}OQ8ns-!c3GMDQ#V?i ze$`KF^_De)HM6B`kL=Rr*xnD;`S-ZlzKf^q><ZGL>{`;pUT@j;vKyzq&+eFob1ZBt zdt?vD!nrzoa`vq3*zASb!?RapZvg(S*$1<aWbet&6!*!_&AuX~#Cx&}vh%WwK=yt1 zcP%Munxa`+o3^ypTU%LMT^KA32Htw!^8U;J*8=}<w1Bp;wyoBcn$aAzU7N%{+JE>z z)B<GN)eeDch7Yu(wByTp=PFgwQ!}(nwNcu6$kndV0<R~v+ax#xYWKoCU3)~Esm;}1 z(aKjn+I;QT)KopLOS&fY)D~*rHo5ieYN>$DtaGiocFNw+KFfZ@{v*G9{=od?{Pg@U zg+7Jhg{uqi6x)k^ihC9(6yGeBN;{R#Eln@|(y~g+W-aH+BjqQQn6kbyQn_7O6rZPR z^7;sMBlYa~Jjg$t6$vN1GMp_gkk`*n%l@eK*N)YuX+P@y^<(uZsHeYZq~i08K1d^s zohen$9}2vQ#>cSyhH%Vf<@L?|kv1p6Je!pA-}1i}_<yMda#C~Aren<@w`nuh=~!;l z=FWc2Tk8eALth4;10wVl^?`6q*-js#Z>A4ZX6yUX65xtd(}(NF!184MEPaeV9;gYa z8SwmRqJBNlH|taMNA&xEnhA5aK2LuI(gnmXzf`V~4E+=RC;cn*ZHW3`hGdvhPoo8L zOB%h5Rgo`h#s<cw#+t^?#-7I3#(~BWARTGI(?{b>W1MlZag}is(F4xy7>6-c7;M1x zw=u(b+vql4rja|Pd<gu{jh~ILjla#bsTmz+0p?ES8gnIaLvw(+taOdJuDOx9nYpjI zojJ@r5b`6;Bg~QJ1apizJ~hL<&b&q3-@MCw+?-`TXFg!QYtA<pny-nP`K|e@@s+6M z;yH<x33)RIHG*`>T(8`!kZzD$Gq-7OuiVzTon3kdksP$-;M|e9({rP9Cm<(xdG4y* z1-YrYn{x2%H1}i<>Lv-f*)H3ca-ZhD$i0=DpZg>C14=B#(ygSmoK>`XFilEXy{)ya z^{v$$%}uPGtgZMpQxA>jV#mvY))CeSYfs+R8cEChr&FT?<FLl?(KJR|<E;seSyC%~ zMM_1b{I=k2EpdD6dN1#PnU9K-$ly7B&n(=-OFgZdty`g`@39`Vp42}IkIH(<;<i}l zcrn;|i|C_IYrge~^#$gwAF7xCztph)Se)J^!%pCF>EDE1ej>!z%g)(FyOZZIy7{{? zZ*7ThyQkgDc8=;^c|Cdh#(|{vn(jQGQ)Z%H;b41Hd#kec2Jq&n@@57pd7(7O-Vx^A z?fvcHkpBU>_Aw+P`(*oMCx4cGE{)N?+P=x2Y~N|$Z$D-~ZC`IcZ@+H8XD_g)Ig;x@ zvdF&1{t6^N*?;B5eAfOoAJ0p91MUb)_9gD}{W;;_{PHlboF9;1f|l7#njezioVU*p z%x^D!nBOnI8{vvt{@DDXyau6-j{GSg8|9ZU4(Oc6a&Ttu$Y09m{dE2sww;0ZiFhQ) zPs`uo*No=mAI(3PpM^U4ck{3Dy7@2jKj!}|2!(7R57Li$8Pd|ALI<|GGSl9^u#CL0 zup(Ut@}ks?LjS_R!Uly+3tLk=DkW)QXLmk2R~S^-t88}=rt)WnBe3+s2$)9}Mirp- zf;=cQ3zrtI0iBx*Q>eUfA5!+3G_FR|!Xvl_3gs)kLO0NGh4#-ueZVQdd?)TMx3Hi9 zPdXPT7S~ho!gq@^s&HS0#r&qD*zo&|@ED^c^bR6QXK~9Uo%g82w*dbpikaq0FNVB7 zaeLKo4&VQ&X3?gUJB_jp_gcHeU0RK~aW(4Iux_KSLu;=^u_rvO15gY6iiDxqhw}ed z>A(9ty4WvuBO<0Z2{l%9&{9tASRSYn%$CF1G<HsGc3g^Y8b2pKJ0T@DO`PNKOQ3^V zMfe1)e%N4_kF~}MFee&-4Q1zH*7<M7{uO$0w0}#Cpbc83HP#jrV(m~j11QXul3mGh zPCH?1w<Z;kcl7J-*R@V}-K}5ptgCw4zT{h1_yOQQIr~fVa~5wryf<tw+}dfGgd!Xw zp;EVmSutD2BVJja`k<TytZ}qM2xY|KTS}DkOU#GQ;S%18`9zA3q&9orS3NYT9a+*+ z(VmtX77K6pzn}#thWb6HV%5<Kdo?0VlgfiqX5*Ho9Di<JP)>~fyP(?!#)~vgsd8K6 zIfYIbd%SX-!w-&eCe~z|2wxISx4gbJNw+{!BHGfpYfWi+sE<cqvR4sL?#TW(Ia+?B zX|45)(re?kHGB~hrMviLQ6B4GpHbd|WI@|t^)-!Ke+ssGhDO&Pv%@PooZ0{_kpA!X ze+zuWjje0x6wNK@d91#aI-pkAKEaa#*H0AeT9sVoVhaS<z6ds?&1ngZrm4!An)eV~ zY7jT<x*MZIk7A&IzN~+S#%SE}<8>>~!7~-+85bi9svn6M*N#wL3vB!6Dg4!>*%sg< z45xA1`e)h^O9_rc2;RWU-0*g6CT@QuxEAsL1d(#e7M;5ms!7(dSYFqJi)#FO^V9XU zuD2}A*I!FMwy^TcjSERN|E(?!+%oy!plHPI)CgJAZmr;)KOWlh!TMe<+9MCwMbNf` zYu8@};}CzDNFAmfOo_3Kv*t38BIO3*A|EO5UJ>LG?QsgK59-6+_3GXIyVvXP*S$`+ z)CJpd3vlrah3l7;<6qP05v^$&R5FpfC1^z^%EugTsqXqB7dbRV4evyx$fYIm8bS5N zwjkx=Iu4pp1O3wIh-acnX<p`~-If?LvEr9lUs5}=eu;N-&4Dyo<Ah7r9o1moks`UM z^;>kVWtcTu5bv}MOuh9bb)sd_)LT=x7L^ih-UdteuV1VeEgRP}si%J(^RW}JXoXYI z`h{~NdG<rLXt%MG`(JF&bWP9}q4mYGNIR2=-P^M}INBD3i=MEy{1i~%ba!Xh2;5^C zT7Y&>WY3}Nhj>N}8ZDI&D<Y>g;(5Fcqp3AZi4EDlX=@{o?B6sETHkDcrasVX)cU4+ zBrOVE@HcC>sE{SJ1Suca0*jAO{`z}0+<L)M<l=<>$(km$#F~&iO-X$nWoJQZMa!V; z8uQWhMGb#DQNL)75s<53;+>Y^PI(zm({|x`bZej<`0bmoFVb|qd+SSNG)__qSw_^C zY~QXu8n1pC&=x&24y9;4XiE9@r0Cs$ULrMS+p)myam0IOt};jI?wYL(=$hTtAD>9` zQ^0=gh|zEGISIvdPpTz;Qd%vVs1wve$ivC)!(l-rbRsQ*t%N+B35PA+_CYzaXA&QD zN&Vw>2!sDhF6<hOZ$-2xwPBvT^<ok)<+Wt;ptv!9Z@b}>3U&-2H4Hv?VXc{eazyvv z6Yw0o;~;wImz@LJg3gWbMx<-QuFbl(>l)UzZ`bgyW4ij_nS<PUVv6s!aK^RA;vf_s znO7E^$J*dT*J)77&W`kn2=f)BPqwmPNv&M+goke{cgqnuYh|j595%5yc?w&O#=$7$ zkQ|i<-`}$`-A8X`Mam*2(Bl&FP=kTjB3mgRBcsU?g+#}!(IOMH{gg`}t;L?3)kERk z6Vd0N@sX$2v~9_=?P^|GEhxpdQ1nE(B*i@A`Q@lpP44y>tzS!dygybp&vnyGCpdn$ zc5n_Y$=1VfYYv@M@I7j>JEf$$QsYwHf|Bl*yVP#I%j~wh3f(PTZFsFY4qd<$?4NPz zUc;xvk}Uc4UyVi!etW>YRW$+@OE87U&R_}8Rcp}U^$CqfQ8M{u$Z=X+8Y|6_WuO1D zVWhp=D_NsK*Mx4pupBu8U`+lg%!cQqeb~h7xoNr$ku9=*d$%`I2htLB$&P7+V#hnG z!BVn6(02-W-9hRUcCA*9m)>uPUC{SUcUpnoZ0H_BG~7{Qj$R>z$=wztF0v$FoFGl& z#^+>J;wx`m(a)^hC3<u2HN&JB1IyJzxjm8`sS#acm?JdR#T@0)wTW7EqW8SmIzeqx zPkeq|x~=*p$iaz8XhiOm$=wvya&v=oR2S2LI>MJPWa5vxjncspgmLNmBI|?SW(iIA zE0V(~$@&gnra>B3lAlku3%4iqPq!DhBxoCQYmn#y+LttLd09<Pugl%-?=A^*ZaL;i z8~HVPjw_VF4Au5u$@^O{h(p?sdEwiQ&|WL@E+eR2`0W9&EtywBQx19zvgb=e+eYg| z{m{D6;|MJu^WKTZ9uybRC0>K%v^-2nS!_w$fTk!xnoP9RTCPy|QUtiZW<W3ebrZev zCSQ|~lB!*M1<TQvNLZwVB3{{&)Q_IAXl?nFwm#+2`nZn)Bu8|~5to$VuOH#CR%nI_ z^PZ^O$AoJ{Nmxul-$aD*ydF`{3%0(<S54STM2DnQo`mm)S}QW<h01BlBxI|hd`y{d zrp3#VW)eb0$<ZG#5Asj$70FjlNY~@vs~hA$311BI@Y?V)q?z2`z6qy|=@-0yIj#X} zPh+9=kCkl;<?}(wc{1bO+ejY2Gp2fO4b^$yO1|?T?_TLQALTUB4O=oy{CyvMhlRj< zm{d#+1oL9Sofrj{-5%=z%l1m@j;9#Q#xyP_`gJw0g&t_Wkm&Z`mvZspv$Zf_wPMaY zc>4WtV=3_ywxmZbe@cI;7t6oq`!xtB%roKB>w`F48L*jbC2g?v(CvkN`I>O9DR8?& z8CjROWcvzyGhNnc>pyM)JfrS6ZjEvMp&Q46$_7gRt|49hy9ag;>E66s80Y9=xdeow zrP4CcGl>p8(})~hVXQDml*OUqSaD8TP7h6wP0xXTJBONcI)_e>M+~hdA2D>o&=F%X zc5#k5XTsPKa|H6Xi?$l8AB_=XAoXLMaEjS`DYPMeyxzR|Fz+-D)DN@qmRfJ#TQ+@$ z>*a^#X^c#c9$2nkDy*Kh`Ki73wfXaF@g?}B^>OGnSW6o0xfV;J6JVd{&M29#%(zUq zq)1)TIH_A!<Szg5GTj|?6iwG`9aKu)TL|Co{%tOxcCHeFwyGdrH9uZ?bsuzp3P^)m zx>la6c6?N<ov=iftA`4RwMI`tmSMblB4WDK8{^bRp*>pgZ5BjV_lj1$R*;u)9`2Rl z(qKuD1)e*}8Izn%F-K?0M-Jg(N`O~AZaH5j^+B#MFvq6ywN<|^=PHZ(!xXPj*+gi1 zHx`yMeWdU?Pt@eTr{mwD5dZvhG~`svhebvC{#dZ~c!kNXG6}`<^x6|s^28OFRE{a# zhH1(y+|RivAFq!YT?BiY^QX8L372}ODf>E|U(>bFLEBxJoxjE0oG`lz-+x8tdfsDk z*Xv-Do+A%c=Kv4iiJ%X9N6>~mVW_XIu{BVSwhB!xhm!|C^#JRJ`v~5N;T~0wEw793 zHHkfIEnZ$b?cL&oEuA$=zHt)WUw>8B1GJHUa(_D$<eRszpN`R(*xQhFx3j)#^yPi$ z7;A%`?7J03=~Bii-KwH?spHh{tdi}@j>~pyN_F2_mo`r8))l==AE$R4iqQrAZgrcA z*=3G1yV)8SM=`oyN|;rz1+QOU$?2fA=Hm%YZK&=D$ca83J_aw{T#e9M+KIsHm*&0x zu?@r_RO(Mpiu6YHPZ*V+Md?P;5xxlOYc(vhwzb*mE6E$Lw}rfNf4+W;m~g@<zn@w; zCqQlM2S%A50__B8Ex<K8Vu(CMb?NIvYOzHfv5Z>vgY=@dOsY@zIGTfV*C<BUM>TFq z%1MusLt94}CCtKYy4G!l9zp7>fm<8bU>I;qs1?n|BGge9#*`jaYh=NC)%S7UZe*2q zIAIpA9Yxo&wR-LG3{flCw!<jDZN07MKlb{4Msq~2h3ad2=9l-uxGsuZRaLv5skt>n zt~%ZR{a13;{L?#;YI<SsE&U}1bLgFBy(wNT<CS-m9eyiAo}vf8KlJ>I<-hZQ`v)w8 zzsvI0g1jZGbxE%B`K8xiP@d>xP09ON_N-oT?mVK}0PoAA<Wxq#t7P}{RDw?l{64T> z0n)PoN=g42NJW=No;VPHJni@Im7)z!Bqh%ph#zW8S`N2Y`jmjCj8koErgHi=JyW?q zD8E_v{7Ha+y1DO@sE2AP-KI#?Y)Rkn<96qr&?abq<Mq(KTG>%@TD~{Mc&dT-OX`Pr z<;Z1gg5=zuP?xt2r`>imhp`4vMUc>z_NVx~DXKl|i3?-k<3SpEtS<QPF3V9WsC+8( zKfgi=ErpiAr~XzTzTE9kypT2vDj&Vj)?%>)Q|>yEvkv)2hp&6EEs2BHh~)T4v1Vl3 z@z*PwgTBZaEVyK{u5kU3b&N+?<ONN<2b5RKyM6H5{`E=T>9b>QtrY9i#&1E6%rpwW z+|42Jk*$|4alaw05w?9$|FnKI?@g(^-jw=r+XZvoI__L9)*Q@Ob8tsf&Uv2-usfWn zD`MA{Cy29ZzXx_(k{l~DNb2ygwFBdKaZ9e8Tc5W_n&kPVTfchFz4g-V!J9HICh?wy z!po|DHOIULQ{ldAk>Foc)%393C>?iP?rRjcjO4<6;q?uIKkEe1^n5{5e5&q#lM`ga z^YC4X1z#Z*d{5@-6MFPa{E{+ImwvUx&R66)K5v7)En4L_b*M-BsG)7Z>K)ylOfQT= zkECx3UIV$c<x!J-Z&ZRSYrL|=UWC{?MqCR)6Zw{kNlEK8+TSGmqKxfB)hXIvBw0Un zE%EiHwEKF2a_dX+Y#nCdZtXBF%CA+M=vC9kwL?7zrPbs?HiTDM?{_QHl@VPdyT){l z@0!qceb?l!ySt{tUsWT=jTtw7+=Ox0kDEO1?s3!UKO|(|<(FjZDEkX~+v5LcYoszp z8Lv!Gu2&{2={XcCd{0HtIdqIXp#uEkN*rs>>DSe-YmITxhbCXTix#^2QEAj0Mkm&O zbNa!zUg#G}8ae@}G?Y%h0mJfGZp7FLkb`@9#2f-~Y{<S-Y1gWREAsF<1xUzsRQS53 zlIRe``qve1E7YklP8^r+hWAzeiI!g_ZJXoWwx`RSvntjuTXx)M4(hS@>f%wI@~B6e zr)d$l27FuGIh3ln(rU*z>Zg$u3#xV<O`ms!rPbmKlhaCu`StRtzSp0(-c*mKUb#0< z_1tM#@5byqZj7VaU6NN$@}wkh{Yakq=ks1aShlwwVR?7Gs^|D;fWdUox5>;eZxf`+ z%Y*2!dIa(5*$+#{Yk2Qjj&Qu(AWv={?6>5ohHve$9~$^O*sW152S;UgTtqKUbd^O# z27gzQGAg1lqFRYW&bJ77B1c!OLp|{e<(RO)nQ}PnI96L6G#Xl)V)zxoi0+ZyW4gz8 zPw2kBdvf>P-P5}VboYldaKCXIL0{KfbmO^tNL}$ebuE{?JNUqSrNt|Mv%0^?K=sZp z{))nVMMJ-Tq+0}dbx-8_g<rbm^l6g!uV8x4q3ueyR+>_NEh&~r{L!-cr&hIi;B*B1 zilnji?sy?v5x3o8WaWw5F8LO7-<c6zE+WTQ^)G$A7Uaml?!-umeywm0L_)V8y8gL( zh1=1R8?`UDRym<9<>pp$?g%UFFv1^om}W3P`26MN2HPUndmazYyX@(;qSG@Nji2s6 zE=|bPb6rDhsV5Qc%KdMhg5vX*iC^7Tn}Xt^b-}wwZwq?z^f(mVn}zo{2KPL0JY8cP z1V_u_Q*zWG-(e!ZnTfU{`XFUA=8cc9E}HHK<jkr<-yY5xz#By^K51QCDLp&Fv5|uJ zjee<qket^IqAPLHdenG*Q1-?3Xwnt950EngMi{i7$sfeEy&<VYT3*j2PwP%n+5#jk z#~8H@yL<(efbRnQZ?w=q?ZKJ!@9A$_|1+>4|K3&!+FyC!ZXc}nEJn%;J|@u?B7ahQ zOQ-vgyA(c0yz`t!X!0$AzjW;PjQXRI()y5hF+uG^-mVgTY8{=r*D5Umx5mnum;dtC z|11dliVU8@%H>NWTNGJiw3e9CeI?j)ZQQW(d4Bb^j2cXfQM?yM2g}`8S4=yY;@gL< z4_4=(_0FUu0`!3svqy?dj8|rO5|k5rZ+xhTJeqptH1BN%YDMMf0ZSo!9x07R%%`Ld z?tO#soDiH?s4v24WXYmp6h@2_E*ZBvh1ysH_b~|fWt?zHq?95@eexa(w|jD}jJj;9 zUMkh_mrU0sS?3rP)n$8I(Dp=QVfxh0pZZJ1a%eqC1Y~WKqZ6wcp@Pcib^Imr9Cztx z=P#MnwHAtc$Cz=V`LNU-0cmMcf3kMz*JAGN*m3PFs?|R{X67S`s^&jP&hbL(PwIws zr!~fuY+<hBU1bcjs2HPUd>MRc)P{?dmW5Yt<!eOmT`RS!Jq=s$(R}nz+ap*rc)MZS z42>|Pe(rwssIo7`;}OnuEA%M@UaRt2?&wiMkBwdl=4;(wNbSkqiay!agU1|v`oSOR zQKQz$9aV6wULAMdy=Jgn5*^{Yb;EM*y~2NILicKVR%W$hy0lc{i<QLtrZkgQqe#iD zJTFzv9_6%De@gaHQU<QaV0g=n%A=R4DPaF_sq;~|1m#SCJ-q{rzVa>GV-2I*tolCT zx95*^*ve!Zr0wmM5)Chx<jK-sbAOp`4qDLi!cyE4yi-7Xx>UTSV7|T<;-ew1Y5QQr zZvP}l_FP<&I+5cJJwCg_t9m?iYx{G2`J`U;)sEO>9Wh?qy4(|qI(WZAZczL4YY9D* zvjQI}PuCYOM#<I)iIudpJ8o}|9GSgbmZ#qtMZITd+Fq*ooHAGGR$hc&(_eso(_e(1 z(^v0ay?X%kL^Hc<z3%=Bez%PydOqj><J0NYr{A3ZL*W|(_{yN)*fqxLL(MsSpEFP# zTLa#*oxHb~8h4*Hyf1tY?Upi*BXRY1Q<gcrC&oVMeA58dM2Dn9!TV6BcO2R2A!jJ` zk>h}sQz-$yln|Zrk%KiI;?%c4d$%80yBe7M78OkUw{6~Sunps~9;1RO_mO~Yp+OX1 zE~SI?aJ!~kd(eJHZ82q$hEu4=%JJ^$D6Q^?*(1faO1j_BcfI&Ge9#nF4`-BwaVIDz zj5|>|G3@DeaJ^U=!E(aIs7S1V<ufOshluhODGTaPH>jr?a?Y=`9}6JZJC&1TDcLTX zTT+iCrE8V0z2Fr8SK^QDybp{fY6`AbI5)~yby>BeJ^NyTQKZf!Pxpi9lB$=&`w7;j zE#NJQ@}pB`6|Tp0kP6a6KKa5HpRN-iuaSu!2g1^7`yaJyq-?aITXIlZP0nomrPH{g zQ?!fL@Jrb-p2+z9nyw9+vIq%<7H*#3e>jI)hHJPbv`l~NROQrqTnu&Oj-*=7=cbl> zET)5RpxrJKn<mZ)yw(lco`ZOv_q)~J|2p!ZchO<IDF1Go;CJ#-_F*!&-`a9?d}nN4 z(gQ1cCpl7%_uDx9%aQ;i_eSr{Q{AwbDWBJ4CGv4lO(v!BQQLY_v}K+cMYvcl&m-DV z{%Lfzq)~ptWYzrgcK+C_S);sES+BgWXxeR4ODS$0xBcQQi}-T;r~eEG9S=M_XhM24 z4o<O+qo!c1FfKiQhRKmnb!h76poDPQeLz%<{yO?O{)o^c;|8rWq2?`#kB;}m^P_2u zgv7%~#cYDFoEevC22o*G*G!jr@>5JJobqgU&UuY$^W(r#o;MA;ek44i$<`E7?if)c z+&<{(p11UHds=Q({qXOm;PTnXY|-}N<)dGWA$SA;S`Y8DTjq~YEFT;vFUQ7o#)@=} z-9p=eq_kX?(yiXDM@D=`t*H9rUXI68>Z6gAMG`{!>xA#u==-M;-6wRN-sRVcwUM3? zVl5~eF>XY6uzNZVl=sWITK;LmFPJ0$d1}Kisrj{$?j8?+Esccl%KLToFMqk>kDaey zwfKT-#c`{Bn@G1SeoLafT2f+%OPp{SWW~5t$5AgY*qt!3r#k3~SP~B9dsAvfbeR>4 zBuGNNFfB?kZOZYdEPf*6ZFt&mN%e^bdN%c@)W4VS%~!j>tRhbY_N5GWXI;MYy|-kN zr*UE$tWgV>_u{5&u@2IqUi>mDAt}nECf+_uFHFYU*G{uPzQb)uiH*yHENLx*WQ4~w zC>5M~J$SXea?JCSSI*0j_R53uQF_#$w_M7vH4Q44@}kP8wWYdz%F5=sQ8crNE)#u( zYw%wDrSa0*+8@jE`ym{mx!&&@=@X8gnVPY!wLeT+R&eU>`w?}j_5T<p7iR^R;^un$ z_;5?ZbB)<GW<{fjvaVz8xwlw%F6_L__-=h~j_CzbReKAhPjDMeY2OasxN6P2ulN1A zYJQsOg@*IJ-BAbijm7L^T91*}w|_`1A#@1K2rCNxh0TTSh24bxghPd6g;SuH&+~*! zg=>U~!W7{?;Sph`Fjsh0ct`k1_(J$W_(M#Is%VStVo$M;*iT$r91K_8+lsr2`-q2# zM~frGk>Y6a0`YS3I`J0qF7W~Jaq(&KdGU4eJ@FIqEAc1sue6xf(uH(q+Y;$z(<`M1 zq}OR5*12x`_4#e{JLmVxccnLkv0k=G?~>j-ePH^C^oaDx^x5h2)0d^MP2ZfJlD;qf zNP1>^Zu*t<y!8C^!t}T4U(<hQ(iuHd%-@~qky$RYa%Mng-ONUrEi&6=b`b_<_Rbuf zIZ7B<c&acbb7JO<%-GCDnJa~X#Vv{(71wQDvvt+{k(nFw2NkvgY?D7Pe}4Y-{F(Vt z#Y|Do+y?W#nFlhD7xm06pu01#Wai<`SY|<S|Kb5PVE4?T;ts_fGT&!@my$5rhE?oQ zEJ|(C(o*l@a>bRU)rte8wOgN%){{1twv=|1hP50Z?JFHpdPO?A^%v<R=}Z`%<6`M5 zVPMPSEi<K?S{`T}-#Vu4T<P}KousMK!>z|kGo)vv7o;~z^GXkwx=S-!2Dhx;azV@d z{G>82bJEGu`}q^31=1o|elPtlC#`F(%dFR7+z-ooEcb`pX5DGsZ#|#CR$kir#QM_u z(LUKe%Rbk>#J<|T$-dp5YW-;ocE*+qzm&Eq?bLFeow4#(NB)WYto*b2=dGvnujgO4 zbJlxy!S1w|wO6tS*z4LG*;|zMEZyF!v<<g+u!q_E+QY3$_A#XcONSRdC>>qKNsyjV zI;V7@lfTqiUIojkEw{A%ZY^W=ZhyV~y^gb6c5LZt*|O!X77HQwZfTQOYdKtAOCBT- zm4~)o-=ef8t<|ix<!y?m6;G3QDUN24_m&SVB=ghdBMJw}BMPGn7Zfg+N6MoLyA<}4 z#}<!o87*HVUs<@WFsYyv?k_x4II?hT;S|7Wg|@=dfS!drix>Qd|D!E%QR(~A_k|7q z!+$OCUkm)#0{^vurv)}?ozQt)@y6oh#R2)o;+67kZR@n|=fR%xy{&DnR%=IFzqWqz zLoLac%UhRe?bY&q+gb8c@|>1E<d<9K%5S%x(mGQ9u=VcNO<T8;KbOC2{iyXb`8Ore zx`84qxz_1z%eVDWT9u`g6_md1&ns(noZoSNTTB^L_`I;F@I~Rv!dHc_3*Y>g`>!Sb zU)c(jp~}|EcEZ5sP<XjH<lp-b|Cd^z(8q&S3u~5cvIe)D)^eJ)v9*OVOxaf%Zogu` zZGWg7V}G7sJHNL5usy^6F5fr5T7IzooBek_o!6C<^F`$>yIVQ8U@4a<SLb`=m&vc7 z+^kH=f1m$7|4Dw4a-Z^uGPAj@r|`1<gZ)FkU;dc<efb{>{R+nv?k;>&T%~wK@$TX` zrBzBtl<qEl(bA`7c*~TQ4_ez>hqYea`c7M^ZKt*gZEv=h+INEcttXV2vc57>xm{Ug z_f<7{eT2G^dbZWq>Z?AT6$vN1a`y1-1@ijYY1tpO{@StHH2qlZ$J|l1!4Puy8Uu|} za^D$atfLUdW5&1Us@A>Mz2=eDcjhI=xAnukm&DfSQt#iWC9(U@{{Qdor%%&oHQok# z|6Jc@V1Cz(b*``ZU2|u@=B?qkp;wf7!obo3gt9<cq<qz~TFcVPPs(3vLKSHVs@8g_ zT2MPnE33<@ebiOdHCm2W*9W`hO0A_HrA6u{>Q?G@>Mk9cx_8I!>OtzE>ajh>sHe35 z<b^s)Jx{$<y+*wOeXF;sQ`Gx9mQ^27XF_hS`l|X4^4s@SKT^Nwn5F)p{+>;?ZP?KX zyuY$aTPAB|+p<e%duLZez1DA9zsasG4D7fzJGkSrY**(4*=>6qnB6tIH;o+A?7^LX zW{=9Am_51k@$6YJ^4&$*E3?;TCuZ+xyQJ+hIHEoR$7CZrGdrjK<m}7Yx3llHpW8mZ z{jBUK*{?b_%Kii%{?f#bl{8H&Xzf~0t&i4ETT|OW+q83q&ZV@iwVgY5=-5Kri<Q}N zs&<feB*b-C$Nt(0+Ue~Rv~#ozwF%nw+GOo+rq_9$Hl5@;*6kReJ)u3TJ+Hlv9PK^r zL+$g<-8*;CzU$ngb0h7yj^p%%E;HL6BlVo#s`t>B(^t}0)7M0azJWeO-(25b-&Nm- zX;Ml*L_b;|p^tPlM|ZxVU(oVuLwHNSocJWx`gI+X81!3cdH-~(-`-=H9?R%=wLV(| z=77%2F1^>d+&lUMJ@#w{`r{qXMc`#3)1L`%qaH`-FN8}MzohNjYS7=%-`79wv7)|6 z|6c#4{j2s*;B`{QFv4T$F~TVE($2d&Z!wl2oc3edk1>{SA8xFId1H;vzW*kS_3JEs zKo7X641=+Wv4yb%U-N&SHg;*>uJddcMjLw@2N;KSUJwKW-VZHabchJ!MB_ALbhDm& zY|mjQ;{q<nOMo_<V^fd*#&yP|9vukd4tUcworf{4INf-(_#j-TKUsXH_<}L3rFTnj z<2e$g@tW~2K0P-+Hol~B!-s8Y<HwS0{Amhiwv;mSW{0^<Nh+BrDJ4sCDOZY@G9c+w ze53e&@sr}0#kY$e78e%3G5ZyN>A15Be(Siu<F}4S&2`KTX_?KW=4Phr?%Et??%QLa zIoyP^5~A~c^91vBe+lL&b8P3Q=0$!9<Cs^P*Rh;1(41u6&gcEKIkls}U_K1xw|3^t z8Gg-Zj@jLLx%ndMm~WbI@w(=GbD{aI`D-qolZ1ge-!UmyYJVWt3G=eK-Z{8-=y<y` z(J6QC-|=DRGaa9I9@hCn=L@;#a<Apy?IGko&VAYWH9>A|NPo-?&Yjp4e&A#M=jq(g zmW8=(S{Ah|%I%QbJ-2`Eu(s`5C$|l2+qZ4A+;LE|({tzK&dXhzyN1@XZC2ZJFu&3^ zuWeG>g0@9Kf8X|dd!k)#yR&UpyWVzx+oSEp_Kx<)+n;Wq+}^XjPkX=ib=vO+*@n4^ zxjWiUM&zcoKLBn1Xl|C3Dh)+g0zv6_9#)p}|E;vN-am*z))sBY{L`>@Xy1&%+P&ku ze-qaJou@Vf>#!c1R|h=l*y7(sY4vDWC;m_4JEKRoepq9B3|U;T&i|j*ulm|OqwwLs zinssO(xLAE;BhVR82V2i=e*_pn@2e;yUzQH#eWyn)N!_%V>Gd?|M;_*Ef(9ctifYq zQ_m5ac?Lmjg?6DmU=+abV}Hkf1^f{p^NkspS~s;usv{+&%#;SpC7@sMBBU#)mQJ;% z)=t@}L;#irX)gzBfbLKZ8>VW50_7D`{gZ#E`ldGKutBOeD5*ZFOsW^u@ZX*)EgDbM z(%wFuuA~kvZzl85B0^G3{1%&-+&?xq)hqFOQcC`j%q7=Ld<OV4c2-hMo|X75@fpe! zA0m=^Vjx5EBt}!p%}Wm8^U0Hv$0kQ4M<iA!NFJM59rMVce99|p44@W{4(KNa0yPlR zka;ce;L{1V!FY%tUJfN5l{}pKry8U*ln^Uw0db$|=0II4enVm`$IkSqw?KWqro9t| z#4>=T$}^z|ryY1}RiwORDMz1h(3{sDZpO+yB6XKwfV77rZ%-JBmNHgNteWTzGg~^X zjx`CHm!fUzq!<HVGfJ;s_6hm)8i1kcjRW<len^UT&b&stKc<;Q(tYqP^ajpMWdW&l z4?=$2!Bg;M&EqiR5>jP~a#tBhx#mP6xhJff<pFfr&!GyibWoPlJkg{%lA<j^djLgc zG-cX6r=?;^xdm8%jIL1WwJEU1iS@mRT?V*1G0sUZi(L#D9vhzc8J3qN$HuNmjzvIv z9%>|$vFlJykT^f_TXHlUJAR8D1@rLq8_YY^i47M&1-vHC6<?P2sRrRI;am7({x{)I z_~bt+ilQX^4ByV{VouD9ZNeh4Bz6k#i%SZNg!hGyVJ5(w1F<J?KNeRIR}_~69R!uE z0-X27)x-gg-Nzt7drrgA{7m>vTvNd1I`B2T2hxu6+HNQ(E5|uFL0(thP+nK~Q1~#j zskB=d)UoPloD&x&?!^>OGx2McD-p3R%xmarCq5x|c>Mm@i1_^o&~av<rzUr+hFHw4 z;rN&uFC)22HN@|BYf#JhRQ0_0gMdfkcK{xY-<H-gpJhId-;h>Z^M3KY<6$$}-xj|) zb42FQ%!lxe{&?vMT*_1B`w`+#$?f8Dx6peaz|Pnb(??Zb9Hj$emyx{_XO;p2EU zATNHC+#-H_{6v@$GzCih#>pKSKO|o3d`$eXK-~j{x8R?VIl`Rm8|lB&e`Vguyd{1w zeu*=*#qs~+c_h>WO2JaSsd5Rl{fW+uag;SHyofyfyYh`o4|L^A<%^J~Tn=B_l;_Or z@Q+BuO!d^0)Dcm0_OI;k`V;!2=7r|@<~VbVGXo8K(B}2S**mw2uj^n#SZ<KtF+OxL zVB`FbiD}|T=-)iUJi|B_I_J2q8kC*FHH1sbxUxcBqDq90e;`~Ee*@|G0`W#=SNTC@ zcY2(mY5coJK&|upl&#;5zfF1WR63QwILACe-N(V6>YnmpiOZ!C(y`L9@)8X2w!MtR zCFW+u&E#VeSL*l0`^NiM&=+zwK;54raZQlE@S+=;!3c<CS$Sz?O9o?TV!9vkV%(0K zaV_&)<~iXx$N$=}T)K?v@huS)laE)MR=G5BzBr$G0J=Zqa1KO8w}0Z{cwgZN9`Q_E z6OIOyx$!mPYam_b0w4afIw{`j2gU$+Pkc{0DSeBB8`5rE3;AnfvGi@}n=`AzA8HLi zdIFJIy$bqe0)X2lv6qi*9CX`?O4D~NK4jJk#JBD}&7Fg<b^Lf;X&i4U0JYN#<sHCt zfESeymG?1*{5ScN@+ZO9BM!7%-6`abMJ;U-hnuu1ki!`<MVkUYkt%iLKm&lj4d~(1 zekKSgB@_J37>)ILIdp5hWpPVt8;g}bhqu8ln4^T_;ycH8hV#uHZlD!%Xew+J4CtK0 zCBZx?k@7JooFJV}N)nDEaQr$YLpj6Z!^AH6cw)zv!f})q1`C71%V3NM?UA2&(hn>% zz5`&}3V_ajXFq8_mj4v3<UYa}X)=`A&47HIkV8`@byIFj)Cc*q+|uzNj04UrgfK=J z<2Z)}r7;yQB-|_<SNJLZtON85Uim38(+}`-K8Y`TZGKN)o6^D=!Wr?$!P`?jq>1sT zD37GVHo<_XT@sS#xmc1g3cNp#!14%yOUnknxHalwsZmq>DQTkIOYVg_iD&#Uu9a?d z+goqsOZiTi+YnIZU5V`z+k^G4Za5x+M^j<fV1Ngggydnn>7ab{Al#eSRk#bw!liIm z_72DI_KBUGbf?5l;*LnMshCAQniqBwKvQsH%-&J9-X`J4mU4&w9s{-KQ(;<SU#RcC z3`9!uWyt}kgA;ObNh!vo6tBsACia!PsYld==%*!i$2n2HIztNS#9jztI_jt|<C0Fo zG)nQQ(vo=2hdBv=^auR+O!2fdgIVRiNgRsEf0;PK4JhB?&{Wtx7!ZGeB=-X2Vrj)^ z)Hj8P5v07tp<svk$I9u$;w~&Iq)-}*!MB(vTF$j)5iCe7*}JoMJM_T`ACS+cLVxu& zH|#?0qxg^UAM^Xie|H1+DThN-x0L0A<vbV5msgf<kN*fg16+?wED>r1IpKOpVF~n2 zG1ml~%2NOo6t|E6LcFRlAt&*oAF-HnjdD%#E0hOK`6Y9oCN@fJRG5|6%nk78aA*qs z8U!G*5%g>T$ld^Y;3om+B<PC|Aa1A6v)gHzb`OLw#ct<e9gk&XZ$N9X8|;UA9|N&e zA5b4+fOas_7o{(PYsRYrFd;pG=aOi6jzhb2m^8>I^3V&@LW=m!tVB{6CZjjTl<AGY z9Oy$neW^2Fn!Yr%Jk`Y1oaqPhLHmL<+yMqpiPM^c@FduuEIi5KnMz43Bt}(mTH*}o zw}RnGVP@j!#0dd7E>XFTfVG)Uq;VOG6*`c{C84<wxEu+UVoE`5s0XxWUWkq`3DUSQ ziJ@=-(r5$aW+{M{VV}CSf=Q*-V88jx562E(KN&X|H;Css7+X%ygZps8IS)pDsEwjp zG##71AHGHZh_<mf88FeACyEaN^^n6s?qu;Shku`VAN2XLzjzOz>_z{`*cMUNMf=H_ zf#PI{k603)gm$D3-$i8xA}achF61W?K5TbW0e3TG)@O7Yj;!ju^xg9F^7HC@>U?!x z_FV#fzCNGU4chkt2Dsub?;$8Bbo`=dq@kZB2Kg%Jbty*k=!McG#XRHr<<;!n-dL`h zT`lD@Z+whAm(kVALwPO07BIFlwo<l{Cy0NiGvXfvY3SOevWwAOEg}9I1oQ#tsjI4B zg6spaBunx0T4C*n7S`Sjm`|Sx{ngZuk?B*=8tl&r#H=*Jk(rOVLG0)<^FtVlM^lM3 z1h7eQ4z*z^==@wAQWszgDJC()3YGb-I;5>7=bFD_#1WZ4!vN<cM+Q$kwv)EwOk5=N zDpWxxj&vql0d7v&jGQqtsdQh!66rqa*0i1ONEg$6Wau9W+J9+3_yVLm{ov*4tpMHW z=hHi+pG|KI^v=+a(XdQABE5NWW_k}lT=siI&qsA2e-v*G@%wBu1@%#;qb*ZAm=&X> z*BXWSjQI@gpZyWi%LI(3B_N;4o!lBSpdz13DCteW3jz34stWYLw5VryD*x_>)?0%s zBQkN)zhngJlcmp++F&aG;)hngx{`kcyipI7y_CJ=SLIigy&T^!$uDWU){LF>T{M_^ z#A5nB+V;TT9+z%tJ25ztJ#`l_0)01a8$VD&C%;tNhRQJ2wsc{4ZLczbkMi7`5qP;M z10D;6^A`kqh@O-ul_ynQ&8cn5OdiFP;VIcsrK6OG126}MADgC3hvgjo8wO*T{-v?A zv9taq0#nQZ_As2MXM803=LA`$jLJc)eE51K>jui7%EI#-oU$5#TtEt0AIdt!bKk5V z{j(L=h8Ly%OZyNHxXka?2$-euh#Sl^q4cr(Xnm~qJ}l1zjCbaXAvYc{8dL2<Cq>$U z_L=sv_Kx<BejY9zEHcyPU=uzVvj4O;v^Fdp!%AWAfXkHgUYfj}cE4YaPem(Ea=(+W zyniP4sKL)Q_`d~o0_PzAeEIJ9pj3>7#D52*6Ts^Pz@;RHiX3G)U+RFwe@msTvOQ?K z<iv-|zay{MLF+g=#5elC3f}d{GUsP5M5s%~By&@OSSN?|GS0ny;<MO#73>&0D7Is4 zpV)5j<<>fhj|pPyRIpua|JZi1J!9}hMV>{Wzvc!;2KP;S3HzphPya5hBMkzqN1$w` zCJC~y61}h`d^rS2ud7_IUQD2?*0$ERR3E+&^C9*!-~|HtZ23%QK2tuCA^S`AN1XLR z@R#Zk<09h%>JMsku6z#Q6wn?C%WE0nn)p(tM`$Hp9mXAo^VE^qDk=R_mh)4_4ppw2 zJy+F!4{m#?mCK@fKK*X}fU6y9^+AQAoZ$2Wf8>Od{-Ab*`QZ8K?*KmnFy&C%8n8ua z3mER~rBt_X?oK@q+*;;t&~w`p4&~C^^HNW#Cq^a?5r+sZLQCq^)Em;0EY{R5jUjtv zUd+#fdOTGfuwO0%ST!8k;|WTimIAia($>;)(MUbmDDaX2wxln@Kw1j=8m$6pMWTTz zYh6ldFGeG42cR|EO6{wq+B4D6&(hD*p48@OGadNu{fc`PcP;cPEDJN@@xmiGmxcol z!m?2gOJ_zJXOxwOSBs3vi#s8pN6o3`O~!4;ZTidf7^_|^f9K$9`D^7+<xu%+`3r)g zMeMb29sHmneg^!e{meYWQ{&HS#K+3V(AUEv-WKWX=4Eu-=lf*aX1C1_^@G>TZtTLW zY!Eigdfwbo57`Z%AA<%#eCRuBt8-XO+XztRz*Y61+CV>O>8NMkOOgBBoNi9@VT$QT zMGKy>eeXqfDueo^`X%OQN=s&``V9g!oRlrm2DQ}B{c!l7sy`vL>H6uK^Ja<ptWIgu z01s<-Y4;kl0`Zi&jJb^Q6rdY0%Xk*>l<9gJPD{~eGa!%U^w~jqYDZFD8}+?;^ZIC5 zhY^6*m9Q5tTX+z9JieviT<2j4>?u_+r5)<v0PO&Mf333Aj?fO)o&8_i*AKo1;?)E^ zkEihlr8=mECN~P|0lxL-K)K#DzA*)pq)p-S_`>+tK70b)5Wux?MS?WR^Ghaos4wDu z;>$X7ulUMAseX@sPjN7dDwuLvQjdKc?y}&2*?6zYvKP>pBWW-6N9l?VZ$oKfwXD1R z;^52)(U5kDhSCGDlCr$AjIt`Ax6-aG#g~!VA$4Nvc$}qGq*Y*Z$fR~I<AN08l+?%+ zTpg#*PMw*W05~$WUuxURJS;UVbq?TMXL%0jos&8&bx3L$EhF9m?cR}jG2Q{~;Lw=o z=D@WAEk^jXt-X2RJ0-Nix65B9=O!OY&PYB1%NLT5CLe%wUh?JS?BwS_eHwt*l5c_r z;>+aK$txNMsU>fZoZ9kb+b1CMdCB*j8q5IOi<6g?adGlu(2=|lXE=B?@m69?VvIB| z7+@G83F6nPP4ud1W6gp}p}cBxs^?G9l1$LM`uEbWmE1Q{ohW<xN%BCxB?#u_=H<3! z!!?rHGZ=-NiAVEt8dGDbx<aGKI&U_zy&46HH@j>#MAysO82Vyp0Mu*dXabsNsXY?` zqYTslW@Wx#J958LFnj6C#sPc5=g_;Z1L~3HD`~ny!P{v6B+YLe=uLXh555%p;MzcK z>;oDDwa>vLUmlcCQ|Koo5>(Hf=1wi%6a=`Fa`8zXme&U%j8ApFa*`*Jl%6PKMunmr zSL%+N<;-{L0kfl2bJp;!iKl$(x7M_{Z}DJ&Ggb$*OD$t|cyxlSSn1Mi2INY!ajp-< zg7`#x%tPOKH3RPNj?<2IBezO3AhEDzZbdJcESRz$uLW>l0(#7Y^$3OXLml`^aiDFc zZAN@4-$Jjkb%Vu`?PI)KAE>Q$k#!MTVj2b1kCMxuK!3jgc(UOvsei&%_LV;&fG4XC zMN`VJmgYy~N1#vT07S+6!SV-g<d3B?lFAD>ER+|@AGqbv6IB_xKXQLinfX}-UzuO! zo-knv@I8frE%}VvLA+}xYo~Fz9(tOr5ooVn<H40$4WRV``^()hf2$5=jg<K_ft$;6 z<_|m=KbX=s^&(g=jBAao1!2~(O`lQ=-1g8DPzCu%0Z-(gC}arSn(+SdAwPJX(r5<4 zhyLt-Dt+T%L}_g4^y=XKAzeDDbds0n&1b)E2JoHXkAA?JXPM$Mh3~K|lzPkb=3%TQ zfR|fezVvx%MMQqC3om%R<e#n%7(FQf`59%*&X?i!9h5I#SOZ=!5?oSr5acI}S9rTB z-Y9Sg^W)_gwyg(VYj^{=H;4TU!4UMHD5y5{Ng9n`bsvf^7S8}Y2RMWJVQKDr=(G32 z;wy~9sQg(-8^2TovvBl(G<@JSj5m0gy(x@Wfm#VbIIEhgLfJ0`;CbV11dQHxYW~!M z?>T#JY%Q?*=FZBE&W+_GqqO;CZJ_$@G<Q&Sz}GFITF}qtI&P2k<*cW8z;PP>x1k(H zQI0zek<a2I$gNie>*N6NsDhzrac{SBYx=?ax4y83=JXsqiONBDqdZUx^EBmUJngll zR!j$uvYNGdE^lRWI?e=+U!a{dm&;iiQWp0HA95Mwktx@iYXe}6Wh+bJL9`f$+PTxx zYYyIoCC(1uO!OLRmEJ@O_%GB4u$tSFDa|g;ZpkpjVl7VeEecQy05m`owQNAK^m2;{ zqYJ)QdJniym!5XV2{u}b(;{AeZFzflz!ZBDV0Zggd#^I~g|Py6vbVRlv3K>O@RGd~ z{1LfL{`<n_g;xtzzUYXK!|Ihg)>_%>lRF7;c+Pj84;p2H_n5mg3f9`W$+^ka+5~8a z`P}Wf+mQp34Xkx@*X8a3+z6QH;2x_x0?%3mzgxefKdXQ43cz`}%P{Aka^wBrwd|$B zz-xumCj2-afVGUjOqg-WVSRI8VdLT`-kb5eAH2MDcr<w3dT1E!vTo!@V+q!e)>N49 z2K-nC<_UhGF<5s5;5O?v>p=&%702+PR<)=3i$gFzkNC-l@%caUzvkh;5HjV41Yl6k z1FG#!b6tgnJWyU(NR~Vwd6*|lx5S+*wiFgnfcApIC+Mx%0_ag(3P$=`fOD}OM*DiV z@HNWZQ{e+Yc#Xn=ZlKJ~shZobfS5qw*dtB2`xUMN`@Lay{tDnru8p=ovlqb_KEJ{8 zEBmwjdR{C0{roBn_B-}FBxk>0#_RT5_FG;nmWPpfB9XhgUNGNC6&Ly8)`-rP9xXi( zrBQmw4_@D1-wQZH_;^)01MO>gfDb-D(7ql#3<j)j_p|%)<x|>TD*&t75g?W@R_><u zmeqmUFd}a#K)RVnO7hN<M#)n9IUZmQd9vjBQFMMe2I4or9Neb^mn?x=0p=C+E7~t2 z&pp|5{NOe6S2KV=$dM)E)<9j6F9U4<&i@Td%>SLgqL4s;{FJ}U4_;o4&QGiXHx`6~ zkiQNvIX~I$(dn}`S5ixQ7~m=_R2Cpn!B?esT2dBpkT<9_qy)dmm!K=M07%fozZcGz zIPQ48xk9&><IWfQdd4~Pj(Y}qw*{XotZaT<FRU|p56W+dFdy(d^k)L|L*9zf)|mv1 zQy*14zbeKR$A$YW4JiJ}P+BtzL0(G7HUj3!x`7Ad*GiRsE&buauceC}{0g$aOXL0E zeH&W6;H}~Md%I=;_FMZwOUUh*+p&0MGl28x<$h5An3{i92kPbit^l*X$$SOyI^ZqS z_bn(Yn=kqS+&MfTk6vm53!q+oX30~f>m1xzNhg*NlL1$hZU<cL2XCLhy)N9De*pEF z2jhN<!iEe~UbqOPQ={M+lXnAZNm8?&z<4kW_G$TCVPxUVVsE!4%@vm~E>G#8)IK>3 z`S}!ua~Zroitx*1t?=5`pD%q>gzk{tsLxAr8UgHKWs1)O_g+M_&yw%z#jjsD8-e`N z3VtcvbDTrqmF4xuK>g&PV^Ke-6pjZ0Qo>_8NCoLR{G^qzgq)PSkHBqJd#<!&73@;- zf%jh8t~T&CJY9S^9H<vA<t4mFLKjz!hToz#PG+0h5#-TrjT-8TZeDcG+Sv=NXHZGO zJoz^HHf4K+d|R+aG#AE`stI9U@<VDvn7u621HTvL&+5p(TmeMu_L12u0=s88z`u7~ zu0o@I5WgA^{wT(hF&esLDUtXhEBnMqSTxc>SU$^pqKT>>AG;F^Es;b;b0oz$d4!f2 zU2{)4%p>|I>xS`=iY`aqO5Q3cTDOmY9Eox#zO|Gwiu3F=vukx&XP2?iNzbv)wax)J zXC_jMpry5t0-keL=pZV{n&-hELVoNX!1HSX$K~nUVg)=unzqOBfF~NRd{7Skx%ni| zb6J_i&#K_#Vh|iF=A{}{TBVvsVOSW5W#Lj6nD!opJy4^tvmdlf@Vo=1!_wk4H6Y@- zB=uW3G6dHa2o5XwKy9HGhcG&rD#1Xvk=Ud}Q1VZ~9^Ks1eboU&5eT4lj~~=m>CWOd zJm7kyoF^2^Q@%Te>$jd1=rgyZ7naF`mdjGRcNtgOh)e9t5rv^t!(QHxifkEs8A^wz zRnEs<WjRef=R@YVU^WZ%Wt>gGD9WiVC3d(Z-h%xwF3}{~v@R@%6q_*uVoA8XjHjsu z(PdVw20;?)foV~SX;Y3rrLj|8nxZC8`z;BF*#}d`NMmHMgmBGmf<bM9rHo7UXv!pv zqB2Ywmr%ScNbc3gJn9v0F5Db+2Sfd#jM9yy=)XEh96@?PvGKgZZGJQoCvPKOEMBZG z7mQevAXw_>Qhjf#UmXS1j*^?(N6U?+qviV5=JvJ28$0IhBf<cG_>|kI*;K!=0SqvD z8NI?w)_Yb5dT_%&fqK-J^nyxAYHVO^;O4k<`51#+Qd`bg)>xW?UxT^XBxgNu9}T$I zzPE5<;g`ZM)N84;I0?bqFgo{i?rEY)d5)K(omgMvJ?U4}1{iM{Kuae%Tm~J7f_eE( z2$&c22C)R9Qqm+!1*f&1ql2wuNg7p9iZ+$#ekpY#NFH0Bcr43d%^)0|`K+wc{E9u+ zvaID#i?<?5oF)2j%5&L}b<RpD%_khT1ewbV@l2PcB}+@P=o+Q)cv@U3CPqQnHxzq8 zA3A%*q|BDyKRg@B%Ns<as?UkBGQ>B<H%q%AVrm_z*i%1FTC)f9;M#x@)uzd`Vrt<I zmMc?7=N>YTvk$e?_QMqUt@B&tx5K&6TDSvI90=%FT-`OVRY$9Y)?exjg1#amrpI(; zt@?p>%|c(LRurcYlzQ@I8f!ET^kcnhy~_LZ(s`*GycX_!sjG3Ir_9NX!yQTeIp=r- zgUI;7e3g1egJ}j+Ft($Zlwj<~O_FVZ&e%_Y%Bem5QZg62FS$-~NbFOfo&ZdY&5g}X zim`8EUnWbjV`D=An^e$Mrb=-|I5aNAh2#pcr(-jc%O!gzmrM?bJ(^r4xms*CcvvyH zBBrq=Ys5sO55je{!DG+>!1%<XSkJ^eK%EEaqS)xzcn6~?m5jxDg4S2CJiRPKjh=w@ z67N8tX&{aDOzs$45z?&_D<uzdv`!`V2@7(gV`B-#7sRKfJ>{)3H)SSeCdF28VY%3# z<oMVM;%?#-;%r3b^33J(P=f3S*#+4J`gP_;=C0=M=I+*3_O!&ee#BOh#M&SyGS_FW zDPs~uL~u#w8hK;oH0Wz>h3qE?9J4dF8UyAX-kPzK$}KuCc28__<{5Dw0L}=A%oHh^ znF5$D9WL!JZ!7PSnI`Wc@1bO2IZQDif2Fhi;5JkRu^WABj+{Zt{kzeA-aw0SUM}b8 zxdtRKHYseaE-j`{sF!KKaj?C;fU^tepZcSICYF6pq%~)0W_mDUpzHGUUhK6P&YW-9 zOSoKYV(Qw|wG|FV<(A%@y1~t9JO}G;I;lh0dZE6<<dlzkly<fS+#Wb!uYF8|Xj0#_ z-5njMFVQ8^FrL$9xYkIyPM?5|A6HvdN^rQ~OT-zt{JM5Lur*02wl?u2tjzS-on=g< z(Xq9LwV@@+wrpo^&D<*Q0P7uWl4|TBnD3<Wurzg*8=yx@EZ4_rJ*T$BgIk;B!u*qV zbXovng@{!WHMR)0IM$k9Upy^utE_GwQI6-%^05`7Gx{2RV-Eo$+MLP)j>sWabRVOZ z?iBqnU-Ve7FIU!jAm%{7UB4YTw*$&8pSd@4SJ(_arug74)t_TA_+=O&X;oM{JySZZ z4;0Hg^yjhpPFmg?(FXGbgpR$8Hk1eHpx8&i`3T@xQ3>6mF<+)hpP1z(dMSIXZ2J|> z3Ws`uDAptvy#KQAmqE5BJ$Cw1>I;spjy{(%?>t4LpedDk^5keuYD3HLr5+ofocfMP zgUVsNH_?(E8~haX{nR)*pa&!h(*IN4%jjOAGACekiB~)^LYbL4(%;3w#le*xmT1pP z^`^9ECU08J59(7Lp5}PiCs!DtMx;M4YRlQVWK^%0!==lWoj$l~Z|z={zPl(@eXUpX zPCb!yW$5XO2h=VxC2<$7qbNXJl|IIt7+D`=v@bHE!T1;#<xz_0QXLXG<yET()h7DP zGvQ-9u{A|$er*NOlt)u)M^nmgJaxBzqdDxItU2)OJem$J=bZRC!pXwPiR%+LB_8u5 zex`bsdb<8JMQ*OXj=qixk1mvraH(&C*738Y^Wxws3c_X~*wVu%d5&vruFnuo1K(#O zusj}w8$VmzLQCm0pf;}vuL}nV2k4s^n;V-8o4OG_DvTpNH(o*J{mlFF&GOBON%9TG z1Oyv(ra{WnA35~H?M5~EOK||}nKAx+^Wgh#jK7Nhn@3_`V)dHm)j=20TijE<0&tId zMRIsB5~~s<_wj@8L9*tuBjQxAhFHq8e{3>iLqE^WF*eNi%=c6u5~d_Jf_t>vybw1j zV~{uqK3nTiMtf>!A(dW$klLg*r2*+*61OJauMzLSbBAW}L!vqYo-goE9Pn<TDV&~c z3X+t(CpkGeF?oCP&g6B;8-2JBxJ^P_Ph1cBTl|&7_sQDuDD>6%KyrTaBj~a5Cl22v zYXh;LC#lJ&Q-8tZuyktk)KsBg>TY2zVRd1BVPNX_)GyBbW9qxqwIIion_<ui3w~-c zQjatSxm9je)=zCE91O==n6u|*&&i&fdoMSS&DJN@g4EurV*nQc4un2JeY3E9HKg`n zD0hOV2rE%AS>qIXP2I5=aDVE4@Iq!>`r(zMMMcxhn%SVI`8?0jCsqwFm4US*dkjJ9 z@#evL%uYR9y$|{-8ndd%!+N<Vef48s{(P_fwD*1F5`OTqJ8WyETW0F*W>B~x^=@<U z#wV?o`Xu#%Z~h>)0Jyc!=!4h(0P+M2%6uaAE~yqD1LcvZXl?<-_zCzT_*z&hwJ`OC zw1T%j_2%_8%Sh@j$V&7JpnA)3>&uGJyIDlX2jev!RK`9|daAP=As#E9RKcm@KH}jp zBW?!}iY!kT{ov)4#?c}7appV4qr~CPJX#zrj&Bl|iH!r^mp5Te%Dsa2fL>?XsGalX z!~4{@TAn>Gs&$mZFg^FEj<t^S=(h6bYVgws#_a2pUKv2BUgebJD$9(Ov0&`KI1guJ zz=}q&T~)4cd_Dh&do^(Ot3fBEB<#AU0qa-Oew>&-F?~oG$D|pKOdpx)k?EnnK#;vT zdoxPa7s@)vQ(ApGeHdyY&;~WLH$!eI;4hQCO`WaIMoz_&l~FGhJT7MK+(*)3crg9A zR~9fv;!<9n2J=s)o5S1bx?uE26#k;9ah#-gL-jtWeVn8~%}>%z!~dN@F^*&JNGsAY zc*4i(3Dx)_Z2TV||7#zocH4?(X8Q_8WkzMjIUxV~jma=<mT`mV;j)hZ0z-8%239ij zU9W#?86Fd>?e?M3gj<&-_$MO#DdqYnivK?<f_B@u{u2xM_sTDK+eiOF=GOK53gfu# zqRZI5`X69bG{T~Y;#Z4_mq+;tlkxVo($v=hnF^$_(%8(t^+OsB_$V5zlm@BeGEKmI zxbd&N%9f{P76Uv-VEE!Lb4HU0`F@36v2qlA>BD~?;HRbG(oygoPymz*3H&yhDYD4` z9)`nr2mSm$)B)K2j=Wz5hsXy~uf{3r*2XFNo%)?zw4pVVa*|Hx?19<+)E(9BYO$+9 z=dsMg=s5#v)j2f2$a1LX#;m71QAOF#j4a)6IWvRs^K0ciNo@INV-3;6VH@&ncS=9^ zcBGuI4)8-?0nmoqT^M-3%K1F9hh+~V9;JIYTqaSRB|YlkfpSW6Y{~f7N!Ljam2tI1 zagY2+2rh8*L;OdVPNZ1!b^g)S>*VnDZ-lO6bRz#aK)|VT{-`Fer?-JX-74SPM}Lhk zZ{Y2)Ti!eh$~XdbH41s}2<(AhWpWs%Sn42kO?3-(fV{K3Gj73^@pI`oy7i{q__=H( z-8!f{<XRCpA`|v^(G+SeJxuRexf$H;-kWRAu`=J4BTzg+e!CeIkBjnNlMKcgh4Dq5 z(MFXc%A<}}I5Z!T{w_C#>Z3PT(V#B|8ciGcf5Y|1$6zHAbR6HXR5=>3sj{gm@_=`J z@U|~|0W3#m&jg$u2IUOp4E09!y3l#NI$pgjd@f(9RnDH-FUU8XMjw45!dO|KtWP#p zcK?@Sr^=X4&$|BecbT)b8VTiAWfIJYNe(qdxl3_oh#H_7BzEO`<tCUXIo~hfHw?F{ zcVgFf%Du`oKd?hbH~c!q(~75+j#703<uPTZ@=U-yv&_S^2B>-J(MfZ#%z^L6Y8;LC zvrs*!pGMMKW8=%PejXX$y`AM=i@>}*PJ{CK;yd;k#>V=3&K6w$Z#jF2|6k;WINoh{ zHFXuhWObtcrv9>Zr2c|F*SN*F*%=LX5-dG4xAoyQCbun;Et*~@!d=XAv>Q==TUR#$ z3{lr{&0Q+NZt5=CJ+!Zk<Bekg#~VjFINmtXI5GEtc_`pubv*)dHLJG)Xs4uYu#aIL zIc*>(e5yh8+VqF?2h?NL!vp7|vTtWEMX1Bg7B{k2Wv@~XQcn%E3-cGiH^-S{ocR*- z66*uACF)pGlk85|pWR?<7%6zh4$sG*E<Y!qt5%S`1!Qy88Gb;A`z=~Q-$H#teFC4Y zgEd;=)B2~&H1Xm*zbDV+9li4Nd`FYg-+RYxt~39u>c<~yUC7>F!Gl@E-s<13(X`!T zYm=OkZ4Sk3FgoC)iKVkkWMS-eK(J0d+^XYNRvFi_f3`lXkwvWSEZ5Dh>x^o?Rkm?# zUKttPO%2QLoPEBGoy+t~=2B)4vqyFqU<W^p#~B>UogGcot{>&^NW6cAng;%<=|<3> znb`@=K^Fr74|H@XyD&e*Xw~yZYY>nRojrC{#bsJrk7?;L;u<1t9cUer-zERK)?NiY zTyjf8v}-N7FU`AfZ1;dST+7tOTS;pU{WQd?4ydP9%RZ5hGv(Kp60eaqrC4EY7uGGT zQT*A#Z^a*qFzZ_*wDq;Y%|PD{JgiTAIo=!^dEQal>dx<~H3u@@d*jPG#_0<j(Qlj< zg!3!hF&aQ0PT<f->4$5h0GHs{RLBQzkdJU4dZ#7as?`jA1mGn7B<)s*!rTaLT654( z)u!pEBDBY}$I9t6q#ge0+A~e!MXhl>r@f-R)i7Sy07lUd`o)ydVVJrOOCMMtH-Sf2 z(cIG9lJr^>EN5Ii^3o%4CDrL<*zV}`Ty(xHJ<K?)V3YFQ`j|r>IAj!|o$K6*aE<HS zRl*XlcIh=Qz4CRQ_&Qv?3hpe+;VCen=Kc;sG;8cPCbV}MxX-|Q4SqImfx8WW-I6~D zQ|lN9hr#l&{NefGg{2Ei&{_YcN&I2#t^Z*pjD-GoBj85OBO~b5-EX|7pZQ8JK(sfY z&~yo72~I|7OzBL0vA%_fgz8c`pQ2X=UJ^tzO-2Rj5gyZVQP@uqSCer2ND1xX$eUWv zBY6Mj_I$2h+T7mbkF{<<eBNlBK9Qi0E~nIGq1UHnb58?Jd@O733jisJ8J9l$a{pe{ zqb8QQr%77&_?J~ib^9m{j2~u<AM5PY!?z4*4Uf-YJ1>{`VXaK$v{ZK~sKqqhvdEmX z790)I{>C8$u0E{TdfCBK6QA#}^+wk)%I)JqwaROmlk@!$a@(&dSB<2sftvh`c5Z8Y zEls@<O?RHk+$r`k=Ijx4y<l5Z)}gEY_&Sv7vajmvjQ7sBb`$;WI6d{OYpk7zhl`EE zIMY1MI5P<5$rYSt?P2Xv+{n(lQMkKsx6v#jM}LSK83JX64e00+jizM0RDMj=`e<`? z;|t?!z!%1MfDeoX*4Nf|h}>?4=Zgj76F+jhSQD(PtV^wHt!vGGW<O&gST~1-;A0{B zaszllqYl==vqu4B>s?nTvV7OLksa6N=5t2?|1p8*c=s(T^YWwedzpxx97O5WBBSMp zrOtT{YnPi%`#9w5Y9Gz#>Y%T8o><qrJixrQj2io4<DX?ik7)p&!_$Q#pF`T7PAr0! z)kdw!{lo)C)p^T&jvp(hntfIIJ7#nE)^y`DPu?x{<#M6phtw!hbIqaBuQl!8y3TZk zT%%YnhZs;7R?B%&ZG7ZNxn<`zX%buHn!`aMV^i;+16Uo1GPSI=gtc^TIA9-Vxu<<$ zDd~)_i(~AD0LS5lk$8JCU@kWzHv*S1huGE3KRwqRF3UyZ;vB&0?*`!ke~l{E(Y{ey z_xPM1i^y?`qsA~MvY=xk@~mM5VRFJR6s^6R#3@#D7-=<!^0<F={J*+WIvz)(Y2;`e zz7aZTDN$Bbho)qt5SpXuMOJfgjTgv|9asl_i*<7~ZTqfZ6n=Ml_&tT)xtFPz?Bf{n zNhT*fF$XOx-A!W0ldrj9J&$=;Z^BNG!o^92QxIU03<daezp-i{7qzBqkh$u6oK1S7 zW*uzC?Bg(c)?yBIv>hj$!ig^XILpzNVw@l<AG22i(6J{PNzuL;(2?h>r#NE$?#_ty zlelGdyJ(Hj@%X~V=?mh!N66!Icu&itxKVM_;*(zFKeES!pghiWVXMMc_J;&)JZdim zqf@VzA7H;?e{6r8A8Wr3pyO0Gn*Lzdfc%>I_44Zw*x%YeSLm<oA1KYIwfH1Du6>`| zFW6B4`wyo%IO_aToP@^%%JJBHjvf`QaDMRb+wbMe@cfYx=kiW}$U*PG>*6*1B!+*2 zQ@pFOQ4Tq)8pm@B9cAX?d~>)b-yH7CH-|^_&EbW7qnMjVI9sUGLq0z)0O<uEINX-} zX8ujc!4me2Qz~ahGxEVob!otO(XJ7tk1re#d7QoI3u90B4I3@1W`5W>RkiYK7@Z|( zToyNvACV=RF8tUe$eQJrbSwjBl!H$9SP5=fX+DgC!5@hlp=%yxHe@u~Rinq{tSYTO zUU#%cQ{zFySke*WmDVJ4Mx2Wrt1f7qx(YA4*Y+BuP4sK;^oU>Mc(0LrLC~194UL1& zjh%jK$&a&21m{6Ix(Y5UH4Yppos56o`0~+Gb9kcU#S9<EtHI^D@t+Rx(H}S*hacaw zOlO>Q30NM03o>m*Y(I#_1j-s8Tf(71f98c_D)g);M>2YTnO};<o+#_2z&>RVKMuVF zqXihj6MZ6I*ptyJr}L~4OHv)6#R|PdEWyz{U*q^XrDyM1(T_j7;ZE@~A8G0*{_M<{ zQsx`8(>B#v;{Pk|T)^zAsyx5Xt#j($dL=hd6%!KVRB|f`AxQC(fB|oXil`t|0}<o1 zkkEsu7#d+fTR0&F0UsD`3`7NjJVfvjAb^Tup&?d~*R-up&qJ$?wlnRtogQ0-?m*A~ zzt-OStg3{HBl8Wcuc%+GT6^t%_E~%F$2qr>mhH*Mau@uQga3SNt<kS7^*aViJvi9U zGk(ZkpSm<peV?Qbdfx_NX=iJJe+4d|D>mTzSY8(!Fy1jxeRY&J+Mi(P11D~5UMha7 zqe%|Vc)h~&jlORJdz;MF=V{xjqu}|5&nS6!)OSUj2I>egAne;CyjI&Lyv6W%$=QHm zA2YPiE-dxz7hVhX=r_4W@{Xa%m9!acTE|B9Uc;tl{MU@nJluEKkfoo6%QolfuIMw* zTz6<gZhYn;wprG+EjMkO7i^Z`)@6-C{E&Av3b__EJxK?33<{sK1@$>6yt=>SJ2p3i zKAU;h=Ey(v_GbJRD4!j%X&5$1<(k}W+t?siQs~oMu1h#O;(8bK*%3FEtoNeAzJK29 zs}3<XKdsRoaph_n55my%S^}qrtA=A)*tZ3}k1Ht)=Dh%CF6y62+^E*oqV1QM^jv3~ zmGN)Qli4;u7KC?eY%BL^S>r!7eIo30SK3-6ZuiE%CVU1SAk)8ZTa{d>e`WPwqfejf zYSLF~6PVYi?Cr&-Pp)0`zRiK7{cd9qroP>@zumOC-L$h){A(X7s~=&1Ez^*pLS72Y zd#XGnV`N$tJ?#5-nr}1vTzHmVqcCjPw!q?t_G8*+(fex*9PRyeQO`UU%H}9bo^Gyj zI(_=~*Nwg|b!jXKdz<~JZ=avB&B{k+x$s!xwkz*%`cwGXTw+XF`;Z)R4!NG{m?AR| zFt6^<x*k7gDX%Lq+aEaEyl~D^wx`FmzlUZ0_!9Q*pJm45tZI?C9qW?iC_9VxJJv}) z6n=i4j0JF;i#(nLo-O|Mekp4_2>ZD}S+7^v-(O{;&yAnl_~|!#e;=i+kAcAK6JZ|@ zf!S}$#;1=B=p_z0w;o{n1RTd~-~rn3dVL=rWbW@lrYty?4a~9!nX>bZO<>y0w>F;H z{)X`nj{Y0Qet~HZx$ft(1*Yr*bFUY$tiPw=cz+jE$D<x=ygD)vV<1KRhg_P@;TYF- zNP3<0p^TCAR;hQ3*b8S>&UfioI@zAB1^EHir7@ZQT=avY|3k^yVdb@CpA#OZ&+OR- z+R`m^t8$Ob`<)xuo@aB~;Pa`dD@!>ab$+kB_RjB@ZRpys)OWqY@EpVDo^~Nh!+h6; z`xWN0u0@7-vp+E(VQxa7)m*x5fNR}4T86Sv1;!c`v8sAqyGF(uH8R$akrAKDx*qU6 z9Q>f({Zg!fsR#E24)=(9<m6Z{Sk^pshc@RZiyT76dJLI|%zh4S7S6T(!s8`pO~XTm zhfCJ=jQSkgrER94XPeB2qOX{`D(Nw?Y$ZJ@a_h5YU49KFWx-2=pW1UJ=f)=)<4Ejt zotHhA?aV{}plyELRd-7eOJlpf%=;DQP}UWgK9wc6M5bQmBh69DnwLDQz2qg$lXYR- z3)U5w_g%S%^I+uCM&>oImw8Ru*Cl1av8>Mfuz3b+AuWqBuK#gu+FEqFXY0H#-LEKP zru!8f;~E>?@EJIl*w%HaGVXPI=7c$ak!5}y+nFk3e%z)!Q^w2APU?jpKZD%2HpS?{ zUMVv6M1kvL>y<I?(jDTzZ!O35*hoQ}O^jjn(=Tm<pBb6+JYF(<Mm@$<$-|Mk?+g0Y zv0p`fZLIVIUJ`83w(iI~7S;_%eO{Ku7>s_>sAoPI8=os>!OgLs-zY5CSbVwUtp!<Q z<L7C~zl@BshDG1hJdkq?HgT_=+b#P+;Za?mH+Agi9Cw~2-zw{##j}ie&%>pCwx#4& z$<Jcb`s`1l9%Hr{{A0{63tZRvLhS3$RT+oEd0Mt7*Lh9#8hd2sy5Ju(lV^@!op+it zmY;K97N3LI&t$j1g&f96$uc%YKdR%%v*?E;uF`SVrQB^8@zxpi;Cke7_PN^QzLz%R zuFL47J>oOkfJ^<5(GN$iAU=aVIoNX?MK*pItHHi*%GMFLQNLqhv|)S({eoc6_(817 zb$OP$e5{JS@YX_@IbZL~kj9wrw+80M(Y4Ia(1RZx5YCt%cJJhTG&G|++T!XvrO$=O zc8ZPg?x@EaM%I(C-`0Y%V!t2q3EC<B9~g7xkgnVJPm93FQM{J@s+yxBZ&#acZIAd2 z%r*<Za7NIx4HK9)Gqnw!tT!<4yX3vyJ3D!efyJJ6y>Ld*)8_<+&C0dt^Ypo#b*)@0 zeJkTsS;whxEiLu_9Ao8r*w@qbQuaC-BO?X<Y-BsranWxSpCwm}zLMq9Citg)@Gsn{ z^=_(S#O%mB(Vr`kpW9shuXrt<<=V+z{(4uM^`5fcyU6In$mqk!m@8L)j&Y**edXt+ z{n`d$-zT>ly|C&F*^guWhQ3wSb$%iHU#~ZNVb#Ni_GbTBm_0%vYkptWtpAI0-JZC_ zx!iU0Tm@Vy^1L3o;U@5QZ*z@v+wXjH4*N=_=ykc;gByWU>UXOi+z8xm^x&wUZuH=& zuNyts>JJV+p<f+%|4Pvp+92GoZ4mbD=`lV7pN(q)M?bS@^ZeCvz2HXR15DY2CUR`s ze4__PpADlA%z774@9P4`y1?gpeeJW<&ys7YJyQB1_xWqD?VwFfZGK#G=k<nfEdA7R zufzTIEcaJg@2T?G#s=D{tbI7^K$i8~XZTRVhZ#QH@T(0EkhQK^CmH?8hR-zoPQzy# zKG*PhWbaehxAT1JHJ)d^&)9#!@I}T(*q6Q7*nG(F<%ZW99x?pUi5%`%-=-GayB!M} z=V!^#ezej1yJ}Nuzv?SwZF7Nf6k@5s*olns5*hIs8Sxnz@urNURarl9-2&G28`kIG zg(-iByc)S_7;CMlM^1~3wN_x}vA{gL4$OU%=XzS&*V9qebMEHak2Z3)@VdUHa*7yJ z=6u9FMm?Fi5iEO$WP|tt*B$?>xq94F)cidA{BP4o1HaIc{#`9`$O#%J%9=O83pu_R z^MM%y%6cyXGsXg!HhO<m@B5rSH}tyEjg5D=p?%WNYn;PO6z>JrDe_;6XHw*FF9P#^ zDRZ5f3QM2h`3Uv0CqkbDX8(|7uF19R5_HgxMp1#jLjOFkAcy`0w?L15u9VGCQ>d$z zHqAcK*Tf!YVz3XKM7B0KBZa=hTno9*81s5LBO)^fYF=;J(}CaB(?&si+0WLrUSaNA zp%3SftP6Wajp4w)-$dWplzPdbUg1pZjpr~d%Q$@g>b@qK?P*)5Wyw6V5<T{?k9x+> z^>k3$DPzjFQ(5~&*tc1DmeKR<5k5rEv&X>PJ4e?3oWsE1_Nc@O&cU1;(e{&DM~0+r z<oZa{@I!%X(Vl(27UK^7=kU4;jTvxTWc;o^vQ@5YF6;95Zm#xEgJnHSU(GfB6PWFv zOFzDU4wN<{hd?KM74nAXWMuFy!lpgB;a<~*Ubdkh`2l5xnJWwrkXg20uS?jE3-q>g zgSpg8t_P-lQ|;%We0{JX*FLYHeeYGn(Dl*A`-wRddgZ40j5!MWMW(Jr#{VMY|5Xk6 z@6K5^JA&=edzT%v2g`lTj$v87FWI|bgXh9?F;=<`4Y{;aatp@q5Mya5lQ!=Zo{?5? zAIDkOkTBP`WUgJYuTl2<7w8X$e>bT12TS|a54g<@NMEhIB6WrL2~L84T^mbXiGx<x znVonfK<-5T1ivDzf0P@p4ePGJGYro*%=MDmtd=#B@HM%6O!af<bF=!N(=yuY3eWq& zhR+aTKiAX?)^(Taqt9O2a19B)F!Q{!=63Kr+B8)UZn&YyeL;^klFkdTm-)r}0XJkF z)tQv*x=z2=;=CVudt<l@_d&)!<_KZ`4g;C@i18D6EO&`#d5%LyY~(wRxG^K+KFYK8 z$bBjGZM?sH4j37^2;3!l+-op%uRPC+jB`KmE7^vTT-xwTV;|?`t}@2ZwsMc$g~(v? z=Y1h#4<c(GWu0@u3HyqDG7aYJhsW?Phv$4-uQJ<^=4d3p<0~7EEbmcxeQs=|f2jA@ zl|@FMkQ?~oS#IRq@Y<5O{s}fbC-)rdf}cDs?dAD<u;KkOEM=EqjB~z*zQSvP&l;J1 zTf@Bw%=a9?G8c2+iHv&}nCD25Ro_WJ%wy2w*{HlfAT0jXUguo3k8>03h4CzGIymM- z@M4zbJOVz%@Djs^mYf|ad2FzNefDnYXX#sA7j;XY_se}8!#V0Sr;KwXu%5rA(x1xO z|3hj&?pmhtJSSck^IPI(NZVqrL!ayU3G!Y&FwauJavsu-GmyYzJ3DC;^Wij{SFp|9 z<FsG734K_3E~ov<uYn~Wl4HGzOVAwIYfl4*IQN`OY$t9p^9l16^x)Nj4>5Xh)Gsl5 z?7u=;?AMs<kT<3wpM<<OEtw^ITkaFlz1ml~t0?PwkIZ=_$Js0y?U!6Z=Jj&yc&-?h zIEP+h)$4_Mrb<2gf$>Hz;D_&ZfK#KF80H!Y`k0F%BM!mw3<Rw4srJfhBkcVM^O?Ka z%k$Q0hNpw4^L{Z`kWG8yvv}y^^J_5IjiDc8Ecm)~jA(nncurv$<AwE#o?{0*k9Bdq z0mlEMPhsDl!)U`X1)F}_4Cd0#e%_-2tly~TTBy0PuSqsO`(=%>wV=)6#?KKf%e5c$ zM;QH)hL0i-V0{alqfxJ{Nyw#5_5#~8BJF8SgqyT)mG@7)URm_zbIiKy+D&`TS#?Os zI(}8}$1={4>ln+l!CIv&Fwc|84d^xA%5z=l!&xitd*qh7(=#!NLvwyr7uNltvhD}L z*kAX`91X@<Q)HYM>D&!H)-Vmn^$ED2He3%VH$3b43CDOn%<mYR<S;ht$*hmb90&aj zUX#DBz>Ejw6#bS8<6g+vq(1aR<Z-p9p6`qWeP?dCS@MCUjf`b)FLPF4=2&orZR2xH zGUI{$NoKsITMKd=*WfDc84r=QUe#|=y~Gv93vGlkmdRm`h^+o4S8yCbFU&bEvX+f| zPv|>LJ7w;xslBlGBkZq*bE3o*$_o2_(>$ZstGPwnAne<qtZm@CG_F&xG3E;RjJYDR z+KV3TnHKcEZSma<=yk6#B>l!cLg?FLm<I~v0oWWPeW>kRYWh}L>pIqyRo44*tSNh} z>Hp(sKbT9s$Az4Ox{jkg^BDLwv{_Mz&1*uAqMkO)C&J^AmzlD{IOpL#Jsy4}=a9?x zWUCwS-`S*}?0mx)f?HG7-^a5Hy<g?~5;H;$K|YDR-texHcPzAAkM_(tEXzI_8!1ZO zs?7E<7tuy|TsZ8l66oWzA#li1Ei?Rc1n!k)xOlejW+b{!;Mt&OSto$w**mx+<Rb7i zt}DDf&bV^7NXvqICvd;&kD;FH4U|20A~%d)*Bh`oF61}m)so+4BsH9KhI*Ona#^d- zkX#35PD^H;Lw%0Ay4g?s$}tBB>)L~ido4LFGS=bBndBLA=x5K8ufQ=6L`Iy0<Jbhp zc^oWbjd>ul+KZlZchJ|3o@X^d&$Alv3A~oUrd*5ic;tG}b1W?X>l?*Bj2)KsJV0ig zFTY=XdQPZkybTT(EPIyJm5YCJeFfH6)Q7P~W?7EMz^{*tC(e=ET+oYu<W<<emHv5- zM5Z6EJ;=1-nFIK3Vxw&!%Q&Up*q>|k=azbZCLm?YIPXp*&Ly^$8xlWY#I4T7;PAX= z7<@vAL&Ik)>zo^Si18-&tKIV73!laD!a2GJ*NVNQ>>tUzF2-c!@sgQOg1$Sl#x3<+ z?{V%RH}Dnw2sgE?@LI#;C1=Kl^K9_LxjQiPo@ZHmdzSc*T>6(irt0xFns3_@+^<gD zN9ZfOUe4p5gP%C3Loe?D`)i5s15?j?%CQq!{i`11BIr3MMvnT}S8+WL8*tRinDzdZ zwX875Bkbe&jjU}@y|Lj~4mP$d-vteNp2r5}7>{i9n2V<cJ$QOxzSjgkfc@$FO4#>p zd?pK<c-9J*Gu5n+{>M40J_n(mIRR%}^cl}rm9wa4|MM&w`nWa#H%uEEwDB>iYld9x zm79h&1{NCo<@7T+E;h?U?t*`??ls7?Z=NXEF1-AQ${}CD=CqKP$YQVe=rm(<I_i=< z37gZ6Jvi2Nx+#0QDSM77dyXl4j<FYJu7iJYo8&;U^&_m~;yjjR-h<714Zn|lGLlQ5 zywB+0Z|Z%&sTZvI7Jk58q2BkKdM_|OFW~iZ{RaCBjQ<Z9|KQjsA24-&!1%n-*n^|} zg{6IVQG?gg<h5kK<$5U<ZZdbtn!m>>YcA6L7uP2}VQrHOXY|SUWT200n;x^C>2dnL zL5=;H=z50d4}rNS3e0tja<8mmlyxqMjI~5yZy(n}(8sf7GUo_i7g+aq(91rK>ku%W znfA(>1RT$VmHXsuSy|77!SdYSm&J3{Sax}sk6?4!MD}w{;!Zbuu+<-`^HJh1piQA| z1M9jAKJlD-b+Eb6_yGrf8|-tLH+z!K_^dxL+dR{ib6jBNsK~=5<9*cDpvU=S3z;#) z{06QtZat^uY*_TVcSHV!jWTj0Smp)J1(8)RpZnn43cY;pqqecHNoHIzX2ANc)cmaE zBeNX(nCHPUmy#Lt%%94dGs*PHoT;quoP+s{rZU(R{UX|MjRbw%zmTct{snvznfW2| zx{}wPD10jWg!vOTWXW%2j!muum33^A>62?eav00tx0t%(x(oXA>3;=$k;8abMmzP| zp(jg!o^RR@#<Lr}mh)NHijjhTE;4?=v2EZKu_t~mq95Ns7nyc`knLe^gdei33CX7Y z7mH0(Y{<dpVq<fu@pCELz<dZlms%Uo3H5Bl$e^_U(!x1+70wl*|B&(XAyf7vM*k6` zzuf4_b$>0FTN|mXA$8%ISL}as-QSBVXz%+LoEeUNenoXW+FVILgSqqxImF48^yB;a zO4HAXv}m)=*sL=)SJ9_$|5auCvt!9RrZVi)b&ovLW!Qt@eG2L4O!gq&=Jm$@jfO97 zz(3cbD7%$)rMd7n!&nJK{ZGl7XR_Zj_J(DQbp3PbvyRrlzD_^Nd>`I0@=w$wFGcQB zPF&i<u|vIl20`=<<5PHC{gWB%GsBs{IO`gcHt>v*T$U~O^3c!l&q)z`<$MR$9EEo^ z!QCnRtDpFOAlhH<cV;G>2X$TpSINxzfj21QJs+K4pa<*wUEnxRflm!{fwImi%DUeH zpHCa)1o{U@8{tyFI@nxfe1dg;LD@^G_w5A7HiK6OJ>H4R4M%%<SIU>Y!n6n62=!iB zwyh0k5#f5<aOMyh`@YCc!<c`AzUv<Y;}NOGRgMpr1s*S%b5_u|t~t6O%YDyPFYN8f z+>3deoG}ls@LqR&W;}Df4ZX~F+`mM|d>5GWU}V+D&pbjebD#GU&n=;k`<=*IR`lHC z1U>gDfw?yU`#nfD3_gf$_U+fbz^GiyLeu_bwBeix`_~HR%3)rhp7vbxg9m6cGA=gc zdSH&TD>2{ECggK6%U+53F7o%3Lq3Q8O!^trde5Xi^C9#xH_q~TfO#V@@<x}k=7hlb zToUv;#?{`l`1dUBS7y6|J;yS+;X=QaIU(r1eOwPiAJ@a+ZnnR+Q+&=;?u7p`Kg@FF zySuXzpC7Q+1y?v;xPAj85A@3O2yi_21IPCYz{@Jdu&foqucduc%Yt?6s~-8`@5Sc; zZ8$ce2d{Ql{$BV@j%Aje&Fl8p9vExF>EzHSk(&rqujjhXb0zJMEMo_Hj-ANt6UIFC z;CyU;nvo0m;<G|<3){dk3y$l|$cS^Wp5bFGL{^`wR~vcW$M}cMEY{04Ay~!{$7W=; zhh9IY34J`T2EUnQxef%sJ&X%7^^8?z-2;LzWcwM<WMdQ8TF}S!m9p+t$zgs6Um|{* z;^z{^9iIbIZ`yE)@qdXa`w7$L8|Y_5+oP;LZ=g>;AB0aZu5n{ulWfZ>XT#KoF$=!Y zl)cf|Z!&st^tq|DDc2seUAB^Xu0v*rF+0xdE$3fh|DMup^ZZU(&kVtF4+wrc&k`k` z6BqYT(8oO#IL>{_I`@Gu3FFA{*~-!8hA@tx2kV>&#yh>eGQN~`-c$}YZE_~bz3Kr@ z#~R~&4miB?Gskt_6L_w-VIGT|8y+t?GkUJUf<665#=I7o_eojLHpvZqalAxs8Xk{a zNlU$a7K8Q$zBqot9M^JB19QBCTNsDlzdSeOeTP2Ip^-5j19O~4j(Q!Z(91JB?^DkY z)m~ZcXG?ojudMYdN1Nyq`$|2dgMYB@E6Mc3cSHj-pD4EleS9Yh`keO68{l4Z?Y;Eh zhH(ddKW&&pz$ep&<J7b4o5*2Ik&REVzQaj<7@OcTjLj;;=fZ#Rd9Kl4X6jYmC2b%F z`^${|hmAd1_E4zz!^Y-n%cgDXP1*IvX1%ew#^|pNIRyR#50J&?MCmtSt}%lCN~~3s z(LZYQaZ~TdjsNS6{yL-oq|txU=r<Vs2BZI!xkq5!cjQvE;Zw%u)28gFjs2&^M&nai z<3U;D^E0%+Rb%EewBM{YpE3Ow^ET?$T-_+x4>y^5$>Dz8WZHR?Y3EJG=gp?<&8E%Z zc#VO1Uv4&jZZTzVG5XC$udMlMv$46&*xY971;=`Cv-YOVcNqPh;z#|H>myqvw!!+2 zG}?Tp@fn!ca;NoE`cL0c=I8VsOXzcu{ha+}1FX5RwUza9T{PEC<Jp%VN7Fi47vEu? zYv#Mayw16P|ERgKJX4*UxP%!x#oR&WT*EU}W!)16wt7C3g+8t=!SZ~Ka}Ze0MLlD` z*(dMiLNCnsZ^3f@>20uX9Cn5JJeliEt|wu$D$IT0%Z&bN!|TJI5jNo7Q1;r19DPEs zYgE{O-1zyFu?I(cu+FovzscBuqYe1rP%k*z-)!u`(H<OaHXHqI#vUAP?lgLE^aBny zZ7ZqQ{%mh8d0HpS@}1$i30dDeLI^p=66f^54M61al8^Fw#G&&xG8gCbQ`)yOo}0)s zk&#=#ayGj}{mY(ok=o1r$Y*4*QMP(5EBj5xDr`<+J2`)mW$b8KWwnp<4s6yKd$NoX z>cdzAYi>tA2Y<rY$8{|9%G&;z1F1KDJ}>Rjb}FwEpTa!Lh5fDce^nvvzcu6>>N#fD z;;gmgz9yMI*J2GoHg$c$wDSw5-rFr3`<Q3o=gv}J?p1T2E7&G*+;8UoGogBaHCG7B zc-OUY?$^eP5Le0#dDlHM#xi(K7@OcY9>G}Oq82R+)_8{gR>ms&gk{021IPH!6TiRS z&=_twjp1}$*O>A%E|%YgoBF-L&s;-7CvnSlBRH-P!EwC@?qPp=8;MUo^MyV>pCucc zIVt?}od@W@NM6xYX1{W8MLq2~Mk1@vyJ*kYhF)3Ak|l1b4>6;hpx^qMWcn=hTJ8$> z7y2)y^r`J3%iKhLn2*S&?A^2<)HWz<8_05=4EwvywSaLg+J?L3y0i^<vkilT1+V2E zbG^!Py_jWC7w0mZUP}Jq9t59yP#!Ot^#wi8Pr#q$*=ey;^x!tPmh~p(StuCuQ7&g4 z%DsV?hWrUVo`v<wJ`No7Irxi457x5|)h`M5cNsrm&AqVslF{F7{D7k$u<rF1u@Cr_ z<Ka=@@shJ)W$7z#6Z#GIsVSSXpP472k9!30yl`K@UkmX=rk*iVayAU!LZ2f|saF~C z<Mk4U<Pbk(<Hxi532_LUd&Q@=Us?SttN(kA&wGte&*Jmm(r5Oz@T_5xiJ8E>PH;v) zwVk}iGN*y#85($Fh$Ur>rA0{@OW^qKuCmUX%KG_nu&i@9w<@oe`4{}P5D&_l-;_0G zz*~$Bc#-5o)km9qL!N{l+#77b!KMx868bD)i7VqO^0;$>IoFdVmU6?*$g<9aO$+;w zXTo5ayBT9(JqJ^+hd6|Of7<hJxPkE`1?|wfG=Hj}IPb$o894zQ-)RBsd!*X7W9gHz z3jJC1xnfw_8PBPpkLOh2OAFZW`5pLHmgO7@j<E{9kA9eM$szX0rmp)#u7e(|xsFVm zrnYCRDZ5q5o+#}U<~|YjTRWM12Mh88re3m)De9%H_K&jm$pfbBgQh(Xnl^y-Y!H4P zGX5VDpW4oc#7{%o@O5MJ_0q=YUg?uE4=*um1F(!KzNZ0>>jZGj$xBS`1*eQ#jtj7y zIdfeKmNmcE<IGCWhoMJqjC@~+bLhc3c9b>d!S~aKXK~7!SHW9N*$2aU9rO>Ce%gA; zY(u{*$4g+IOOqS?9s0zxj0<o)?*+%$j*NR3nCDB8RgXIoeJVG_zc9xp>>FaEd=kvv z$l7ai=#}xg-N0832*-0{=-(b<1H38RU$Cw{PzyND*Wj49!QU|U-((xO9)SLvA@<0| zKUmL}p?{e6TyK!WxF8#!-=Yo2FZACsKEGA^%-&Gim!I|MH+eoV%Y$doXO=6oJ#BK0 z<=?b{%}n~_-=YD>SnW^TEap${L&3<O8cX1BGBy}j;D<vjDQoP3zZGl_FQ3139fh{A zJ&YM;o_{K{z5MJX^$mP^eO!w|FR{eueUT9}ftiN`Gp-^>8$Dx${s3O@Ec637=0<RQ z)(?(n^5D3}BZqqd{x+{=B$xJoJKPuO9}#_1^pEhm_-u~)aNi9NkXe>zXpz5{4U<ED z1CPRIg=-ITSy!2hjxxCj9CHyk<|1&szu@o4{5~H(lk!Xhd{CuWB4ZznJfLSCU_2w% z90JCEq*vxy@FNphbCK#b9s={37kIR^ADY4Z!#s0TGW4BFF;C7nmO70Sj`zTP{!3<T zWCJC)mRw1jsz<Ju&&a^O!h6A33he#FxT2nO1otvz_IbLs5H3)bdm`vN*yr9R?tP$_ znB;q^ff;*|)u-6-8L{d!$9;X^vTPUs{s#RtOkIn}oKK-&Oy*n<UMj49l-2(U)bkxD z*u;0*!2{GY#=x5-KDAG7rJid5=pQxuN5#L^^<B$hu7v&f7~6b?MK(6u3_m8U?NpX_ zmT|k(#4R|+D!7|v`L~|HlB4){w3N|@^TCP6ZI1X+)-_&Wug89;A$uI?=Y-FKfichO z90y(;){5YP5TD8#!(hCF(JL_z{w~WFTJN@!Yab*JLB9;K6Jjs&I38}wo?3FzG{e)u z?P8CZ2gkqh3)c8SAA;k27a8+iV9s~s(EovX#sZG#%;4>EueCkfLyn?8<R~)zFlHhn zFOfrD0)Icm0J*HUyuZuL{RPMS3zqxK&jN$v9JEZ<NP54(@@$d$0gU-5m-z^M5}Ez4 ztoH&O_p0FS;eILWeGJT81pa>TbG&KW@s59Q0rwC6qg)6#spD7fTwtt)GBW#t^B1{+ zFK;7xCdW8}zQ+FH*pG~{0G9jf^~$Q3XJNe<U$BW|8658~cn8`e^MdD`^AWkV(6LFD z`=a$KYkQQnE^wRV7PapR{5bt^{(>HypwIi7WQmO*O8bAnKJoSbz|{ML5D&2ToaKgl zm9tRS4?<i)|Ag`Rgz@==@%f~&dD7TCX>6X_3n%dZw3Ho}zIxhR*VAIZQ?5&x@lSi| zuSEPu)@xV&4^#2U_s<JoR<7k21<ICV0UYPtrg?w6DKXzGISP!p)p!Q)n8<w+^QvDG z`0)_u&<8$SSz{jjgz*E8WuG=>1G6kRwgGJIqfhAd8G)<f<9c2ASpE#WK5!&b^eT6r zd!M`5t#{YB&Bgr~G&R?b-z{+Kift|{X1m$NI(#i~tteYV$=O)gtSX+w&*7(g+>^yq z^7HIs8Gb(xrI(5YORzTTmbqKpJ+P}nGZUJn#Wm`oSOwkwVsjL%R=M@CYVjq5epRua z7WhBwon736@3V`e@b#qYC}xZ9DXD1{O3%jfq*ZFs5?Ye~XS?;cUGTTS-BLVRuzk0% zWuR&9I#)xBYVOncz7*d#;`?m0rxQQ5xX-%^uBFeN<sNjS#SZ?2Wl_c574=^%f8)+{ zm$?r+Y91=S>$qsDxV~Z(|HoJHAih6_9&dNkaeUZ=Rvh3Ca`Tatu5~vQH}Cy76ZEw2 zl@iCH%%|KYceC5<zUJ<8_q&ISCya;Evfu5+);$jEc6TXa;6B%mKLwGx<BCgMn&8hB z6t}y2GTTirZgSI;1Ks@MS~oxGMSCAEo_0M+A0EaX1>3pFV#L<$Vky%7Vt0sJQXJ~$ z6mKosr4>CWm4e%g8&FS=UMT{%y?9uEFPdJt_M63XJ4(><+T!VgQOUbDn;y|~Uqnqy z-6`%Z?!4l?xM!!hHy7u@dN#^bakt)5Tnvj-d~9D@T#lYT1*K*bpLH2xe?NS1Zzdjb zMTXxAKe>ZZkN<5kv%tq|Ln*w5vT%~^LRhcESeXHvZoKk311$*m^Z@kfr`!#=GdIb- zxefP*{T6;d)o=N`SdRBa;$%_@=n+BmnEV62&&T(FLO;zdPIJc;r=qXU!WSYm`B!(C zJG?kU{{N^utT-I{s=Ewvd0D0Au1$K+{EPP->6$Hvcl^5YuIeu21BaAYxY5KV&7??1 zE3VS46qV5y*U~hyx@F{#lx;2lmcAza@Lr@yNAVZsn?}}TcT|2>d9LzYOIypqXi44W z*z__*54$yJ)ds}*7L1~2+_>9?7S@wI=|?+<lHp_xTDu|HoNP%(lV_6gWEWaqujG|} zw122FTv>yw*ihMA*-{y;JX0C3?7|h*Tk@8ET-8v^aLbxKzOQciAg=Lx`MSMj>!196 zTg%_H{G#Pw&<`E>yZwitH%?C9mcAD~^0D-D={@`WUZfk+&FPkOG<_x=Pj{iu>iD-V z`q6Jg*>JYzkN&<UE3ysQ=IoB_f$XvDN7*m4-?e6~J*|DMN4KtMeN*c@THoLLk=9SN z-qiY))`wcZ-};l*U$y?BTE#y?*H=Bdx}v(WdT#aN>Q&XxRPU&6sg72k@iJchb#>Ps z@`qa0OLy&ny~^U+;@S~=l-twOBu#C(EmJ!k^3K`?)m^m@)vm5>tlhZ}d9X&=4*9Y5 z^I}~4Y3(<)7uvEtf8W-#r%p9(eUO9Oj%|BG+p4zrv|ZMAt(Q%0o7!#;rP{vQ_DI`P zZ9l5+YWro|@2b1nv-Y0$KK{1-RqZFVpNjAAY`>uW^7iXQZf^f-`y=g7wg0sJH^D>u z3olJNTt|H$GPh%K$C4@J@Q!8sl;b;2fxJ1iy8Pbp=a3JYpGP|W82Mz!^)DiuN?(5( zb$qGg8-H3!E!DB(CCcA+yd-fe+__kNTnqV<d%*q3{VwTA4o7}GFS#t)m^_&LILfX{ zTjiCN6Dn`3yz3>(6_d)}Qkf{<sZ0=u#63Zfs3!;#^913?boMU%=YN8<x*%0&rG{0+ zM8P5JlybJCVAT=@1I0)uRvA-C7uLEe1?H>*D;1SbV|7XSvX|{{JN{A7qbcsMjZDXk zZ>5fT&<a-^R`$cn#>)O!S6ks9N3b&KpJT>~d7`|+O_W)9N#6=~2NUD~tm3T9!D?wL znTxgKWI524@=7<g9EA1n|BYPjuEsi|lwPc!|6j^H><#7{dAEDFI|s5FaxSDXN&2vp z*i*jZf_%UQS%X#28uu|H7rG1GTF6)Tka4VuRQ}3Ml+QVp?>m*xV?U#E6V|6UC2h$Z ziu<qFLs0%=l6=CctaB<0u!EXP7P_fr5guxna<HQ;7C8hv2<#!E9O_hF<*Xcr)$CN# zk2T{|a=24D!X1I#@SbuM_PSP%c1OEc8#%^JElaUW*_-^iqx=VV>^|f?>|m_C$4!*; z-PCfCn_8~HDnH2e?s_*eN!H_BU_I8_L9TM8+>HIqb(7>c>@BUl#=W@kF!6XVC%95x z>q=>2#ou%TMwYu1Ay<mL*A4DNR$vyKN?zw)UiqL?ISHr5FQ>fTy}a@Ur?Lfmx-B>- z`r~9X_JBd|b)|gNebjws3i+g?+=r7Lm0MjY_v7T`3nI5U%2vn&Mt<Xd<8C+dAkTJ; z{0J+pF_B+6m4A0ZzV1}s=w4p=h6{4C`~NGa;7rEKo7~GQr@EI{PIE6!hHxID@@MX) z$@_5Dbh<kOawcTu9=JYQVij1%OEa*3NL|Iw*j;ey=ZRPJ<?$^U&3r>1v#`I-9} zPWmXTApb0KDbCeC?uBLF8s#$VdM<Mxq9oIUxSxys)QKdojq+!Si2EN?OLDAAZ03h? zu1onQ<X<5FBqF~~DoF(=em7v>^`&V46ZaGMV<X&`1$o##>~=x;-#>WymQ(q*`?h-o z@_Ui!&V46}=#q4j9GIxQG4WCs6&l64-ceo#5|w!gWxki!Br1m{l)eQ2K*uC`)CKu3 zj`BBA{->k-t&!*4bMBW>w9PFE#QlAgU$_a9oIXjWB@@K`n~_PE=boJ;|I0;5x{@yU z--0A>qPXXyO!lO0Js|O7e!bg8Ne(L|SR@OK%u0gHOiDSy{Z1trEG3lZ_vAD$wZuwi z;w9K7-A3jnUcztp_B}ZW^14z=8=MjxqT+7chit<6w2@@ef2Gg8Q}Svn?z>Y<(hzw= zGNrf|_92s+lANqENnQT<xSLx3(Ls`BrMUkt@>@4qN}r(Q6qN}|>U&F>@Vo!)_7rcB zbU^C+kQvF;(vS1=spQCHf=p=J9zP^Y-4CXgWPg!^6O|sEPE8^1@Ae{pD67S})|3(~ z@r2+-#9O@0O)YPCQ_JNpNT^c2Co3R%lDoe&@>%!U2}b<k9aBrvI<=JklH>Lv?Fr?? zQp&QVWMPnr`tVb7yvUM7Bxv{io}5J4Qy(<Rsg&^3-o7WtB*(a4Pa!CjR7=^bk5?vM z!f%sBL4sz|_aC~c<!(p0XM#N8O8K6fTDG~V<w-ZSJmrG?Z%280l01WFV^(&$iSn;* zN=dSP$n3<*;$*TMkxVJ>o%;~pj>q;P|H<uDCLSv9<){6Uspa*_lrkw&^v8F(sb#N) oRGGYLAF@1|QjF_iJRh}UekJ%3H<jQoGwwq!a8nB^xf}oeA6$>hod5s; literal 0 HcmV?d00001 diff --git a/src/java.base/share/classes/jdk/internal/icu/util/VersionInfo.java b/src/java.base/share/classes/jdk/internal/icu/util/VersionInfo.java index 12228446e54..b7a52b74ae1 100644 --- a/src/java.base/share/classes/jdk/internal/icu/util/VersionInfo.java +++ b/src/java.base/share/classes/jdk/internal/icu/util/VersionInfo.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -36,7 +36,7 @@ package jdk.internal.icu.util; -import java.util.HashMap; +import java.util.concurrent.ConcurrentHashMap; /** * Class to store version numbers of the form major.minor.milli.micro. @@ -48,13 +48,13 @@ public final class VersionInfo // public data members ------------------------------------------------- /** - * Data version string for ICU's internal data. - * Used for appending to data path (e.g. icudt43b) + * Data version string for ICU's data file. + * Not used when loading from resources packaged in the .jar. * @internal * @deprecated This API is ICU internal only. */ @Deprecated - public static final String ICU_DATA_VERSION_PATH = "74b"; + public static final String ICU_DATA_VERSION_PATH = "76b"; // public methods ------------------------------------------------------ @@ -171,7 +171,7 @@ public int compareTo(VersionInfo other) /** * Map of singletons */ - private static final HashMap<Integer, Object> MAP_ = new HashMap<>(); + private static final ConcurrentHashMap<Integer, Object> MAP_ = new ConcurrentHashMap<>(); /** * Error statement string */ diff --git a/src/java.base/share/classes/jdk/internal/util/regex/Grapheme.java b/src/java.base/share/classes/jdk/internal/util/regex/Grapheme.java index ef392612929..34a69c3045f 100644 --- a/src/java.base/share/classes/jdk/internal/util/regex/Grapheme.java +++ b/src/java.base/share/classes/jdk/internal/util/regex/Grapheme.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -35,9 +35,9 @@ public final class Grapheme { * <p> * See Unicode Standard Annex #29 Unicode Text Segmentation for the specification * for the extended grapheme cluster boundary rules. The following implementation - * is based on the annex for Unicode version 15.1. + * is based on the annex for Unicode version 16.0. * - * @spec http://www.unicode.org/reports/tr29/tr29-43.html + * @spec http://www.unicode.org/reports/tr29/tr29-45.html * @param src the {@code CharSequence} to be scanned * @param off offset to start looking for the next boundary in the src * @param limit limit offset in the src (exclusive) @@ -267,7 +267,10 @@ static int getType(int cp) { if (cp >= 0xA960 && cp <= 0xA97C) return L; // hangul jamo_extended B - if (cp >= 0xD7B0 && cp <= 0xD7C6) + // Kirat Rai vowel sign + if (cp >= 0xD7B0 && cp <= 0xD7C6 || + cp == 0x16D63 || + cp >= 0x16D67 && cp <= 0x16D6A) return V; if (cp >= 0xD7CB && cp <= 0xD7FB) return T; @@ -277,6 +280,7 @@ static int getType(int cp) { case 0x0D4E: case 0x111C2: case 0x111C3: + case 0x113D1: case 0x1193F: case 0x11941: case 0x11A3A: diff --git a/src/java.base/share/data/unicodedata/Blocks.txt b/src/java.base/share/data/unicodedata/Blocks.txt index 4060634e5e3..19460657ac9 100644 --- a/src/java.base/share/data/unicodedata/Blocks.txt +++ b/src/java.base/share/data/unicodedata/Blocks.txt @@ -1,7 +1,8 @@ -# Blocks-15.1.0.txt -# Date: 2023-07-28, 15:47:20 GMT -# Copyright (c) 2023 Unicode, Inc. -# For terms of use, see https://www.unicode.org/terms_of_use.html +# Blocks-16.0.0.txt +# Date: 2024-02-02 +# Copyright (c) 2024 Unicode, Inc. +# Unicode and the Unicode Logo are registered trademarks of Unicode, Inc. in the U.S. and other countries. +# For terms of use and license, see https://www.unicode.org/terms_of_use.html # # Unicode Character Database # For documentation, see https://www.unicode.org/reports/tr44/ @@ -217,6 +218,7 @@ FFF0..FFFF; Specials 10500..1052F; Elbasan 10530..1056F; Caucasian Albanian 10570..105BF; Vithkuqi +105C0..105FF; Todhri 10600..1077F; Linear A 10780..107BF; Latin Extended-F 10800..1083F; Cypriot Syllabary @@ -239,6 +241,7 @@ FFF0..FFFF; Specials 10C00..10C4F; Old Turkic 10C80..10CFF; Old Hungarian 10D00..10D3F; Hanifi Rohingya +10D40..10D8F; Garay 10E60..10E7F; Rumi Numeral Symbols 10E80..10EBF; Yezidi 10EC0..10EFF; Arabic Extended-C @@ -258,12 +261,14 @@ FFF0..FFFF; Specials 11280..112AF; Multani 112B0..112FF; Khudawadi 11300..1137F; Grantha +11380..113FF; Tulu-Tigalari 11400..1147F; Newa 11480..114DF; Tirhuta 11580..115FF; Siddham 11600..1165F; Modi 11660..1167F; Mongolian Supplement 11680..116CF; Takri +116D0..116FF; Myanmar Extended-C 11700..1174F; Ahom 11800..1184F; Dogra 118A0..118FF; Warang Citi @@ -274,6 +279,7 @@ FFF0..FFFF; Specials 11AB0..11ABF; Unified Canadian Aboriginal Syllabics Extended-A 11AC0..11AFF; Pau Cin Hau 11B00..11B5F; Devanagari Extended-A +11BC0..11BFF; Sunuwar 11C00..11C6F; Bhaiksuki 11C70..11CBF; Marchen 11D00..11D5F; Masaram Gondi @@ -288,12 +294,15 @@ FFF0..FFFF; Specials 12F90..12FFF; Cypro-Minoan 13000..1342F; Egyptian Hieroglyphs 13430..1345F; Egyptian Hieroglyph Format Controls +13460..143FF; Egyptian Hieroglyphs Extended-A 14400..1467F; Anatolian Hieroglyphs +16100..1613F; Gurung Khema 16800..16A3F; Bamum Supplement 16A40..16A6F; Mro 16A70..16ACF; Tangsa 16AD0..16AFF; Bassa Vah 16B00..16B8F; Pahawh Hmong +16D40..16D7F; Kirat Rai 16E40..16E9F; Medefaidrin 16F00..16F9F; Miao 16FE0..16FFF; Ideographic Symbols and Punctuation @@ -308,6 +317,7 @@ FFF0..FFFF; Specials 1B170..1B2FF; Nushu 1BC00..1BC9F; Duployan 1BCA0..1BCAF; Shorthand Format Controls +1CC00..1CEBF; Symbols for Legacy Computing Supplement 1CF00..1CFCF; Znamenny Musical Notation 1D000..1D0FF; Byzantine Musical Symbols 1D100..1D1FF; Musical Symbols @@ -325,6 +335,7 @@ FFF0..FFFF; Specials 1E290..1E2BF; Toto 1E2C0..1E2FF; Wancho 1E4D0..1E4FF; Nag Mundari +1E5D0..1E5FF; Ol Onal 1E7E0..1E7FF; Ethiopic Extended-B 1E800..1E8DF; Mende Kikakui 1E900..1E95F; Adlam diff --git a/src/java.base/share/data/unicodedata/DerivedCoreProperties.txt b/src/java.base/share/data/unicodedata/DerivedCoreProperties.txt index dcedbcdf776..43d7af85c29 100644 --- a/src/java.base/share/data/unicodedata/DerivedCoreProperties.txt +++ b/src/java.base/share/data/unicodedata/DerivedCoreProperties.txt @@ -1,8 +1,8 @@ -# DerivedCoreProperties-15.1.0.txt -# Date: 2023-08-07, 15:21:24 GMT -# Copyright (c) 2023 Unicode, Inc. +# DerivedCoreProperties-16.0.0.txt +# Date: 2024-05-31, 18:09:32 GMT +# Copyright (c) 2024 Unicode, Inc. # Unicode and the Unicode Logo are registered trademarks of Unicode, Inc. in the U.S. and other countries. -# For terms of use, see https://www.unicode.org/terms_of_use.html +# For terms of use and license, see https://www.unicode.org/terms_of_use.html # # Unicode Character Database # For documentation, see https://www.unicode.org/reports/tr44/ @@ -177,6 +177,7 @@ FF5C ; Math # Sm FULLWIDTH VERTICAL LINE FF5E ; Math # Sm FULLWIDTH TILDE FFE2 ; Math # Sm FULLWIDTH NOT SIGN FFE9..FFEC ; Math # Sm [4] HALFWIDTH LEFTWARDS ARROW..HALFWIDTH DOWNWARDS ARROW +10D8E..10D8F ; Math # Sm [2] GARAY PLUS SIGN..GARAY MINUS SIGN 1D400..1D454 ; Math # L& [85] MATHEMATICAL BOLD CAPITAL A..MATHEMATICAL ITALIC SMALL G 1D456..1D49C ; Math # L& [71] MATHEMATICAL ITALIC SMALL I..MATHEMATICAL SCRIPT CAPITAL A 1D49E..1D49F ; Math # L& [2] MATHEMATICAL SCRIPT CAPITAL C..MATHEMATICAL SCRIPT CAPITAL D @@ -253,7 +254,7 @@ FFE9..FFEC ; Math # Sm [4] HALFWIDTH LEFTWARDS ARROW..HALFWIDTH DOWNWARDS A 1EEAB..1EEBB ; Math # Lo [17] ARABIC MATHEMATICAL DOUBLE-STRUCK LAM..ARABIC MATHEMATICAL DOUBLE-STRUCK GHAIN 1EEF0..1EEF1 ; Math # Sm [2] ARABIC MATHEMATICAL OPERATOR MEEM WITH HAH WITH TATWEEL..ARABIC MATHEMATICAL OPERATOR HAH WITH DAL -# Total code points: 2310 +# Total code points: 2312 # ================================================ @@ -280,6 +281,7 @@ FFE9..FFEC ; Math # Sm [4] HALFWIDTH LEFTWARDS ARROW..HALFWIDTH DOWNWARDS A 02EC ; Alphabetic # Lm MODIFIER LETTER VOICING 02EE ; Alphabetic # Lm MODIFIER LETTER DOUBLE APOSTROPHE 0345 ; Alphabetic # Mn COMBINING GREEK YPOGEGRAMMENI +0363..036F ; Alphabetic # Mn [13] COMBINING LATIN SMALL LETTER A..COMBINING LATIN SMALL LETTER X 0370..0373 ; Alphabetic # L& [4] GREEK CAPITAL LETTER HETA..GREEK SMALL LETTER ARCHAIC SAMPI 0374 ; Alphabetic # Lm GREEK NUMERAL SIGN 0376..0377 ; Alphabetic # L& [2] GREEK CAPITAL LETTER PAMPHYLIAN DIGAMMA..GREEK SMALL LETTER PAMPHYLIAN DIGAMMA @@ -343,6 +345,7 @@ FFE9..FFEC ; Math # Sm [4] HALFWIDTH LEFTWARDS ARROW..HALFWIDTH DOWNWARDS A 0860..086A ; Alphabetic # Lo [11] SYRIAC LETTER MALAYALAM NGA..SYRIAC LETTER MALAYALAM SSA 0870..0887 ; Alphabetic # Lo [24] ARABIC LETTER ALEF WITH ATTACHED FATHA..ARABIC BASELINE ROUND DOT 0889..088E ; Alphabetic # Lo [6] ARABIC LETTER NOON WITH INVERTED SMALL V..ARABIC VERTICAL TAIL +0897 ; Alphabetic # Mn ARABIC PEPET 08A0..08C8 ; Alphabetic # Lo [41] ARABIC LETTER BEH WITH SMALL V BELOW..ARABIC LETTER GRAF 08C9 ; Alphabetic # Lm ARABIC SMALL FARSI YEH 08D4..08DF ; Alphabetic # Mn [12] ARABIC SMALL HIGH WORD AR-RUB..ARABIC SMALL HIGH WORD WAQFA @@ -710,7 +713,7 @@ FFE9..FFEC ; Math # Sm [4] HALFWIDTH LEFTWARDS ARROW..HALFWIDTH DOWNWARDS A 1C4D..1C4F ; Alphabetic # Lo [3] LEPCHA LETTER TTA..LEPCHA LETTER DDA 1C5A..1C77 ; Alphabetic # Lo [30] OL CHIKI LETTER LA..OL CHIKI LETTER OH 1C78..1C7D ; Alphabetic # Lm [6] OL CHIKI MU TTUDDAG..OL CHIKI AHAD -1C80..1C88 ; Alphabetic # L& [9] CYRILLIC SMALL LETTER ROUNDED VE..CYRILLIC SMALL LETTER UNBLENDED UK +1C80..1C8A ; Alphabetic # L& [11] CYRILLIC SMALL LETTER ROUNDED VE..CYRILLIC SMALL LETTER TJE 1C90..1CBA ; Alphabetic # L& [43] GEORGIAN MTAVRULI CAPITAL LETTER AN..GEORGIAN MTAVRULI CAPITAL LETTER AIN 1CBD..1CBF ; Alphabetic # L& [3] GEORGIAN MTAVRULI CAPITAL LETTER AEN..GEORGIAN MTAVRULI CAPITAL LETTER LABIAL SIGN 1CE9..1CEC ; Alphabetic # Lo [4] VEDIC SIGN ANUSVARA ANTARGOMUKHA..VEDIC SIGN ANUSVARA VAMAGOMUKHA WITH TAIL @@ -723,7 +726,7 @@ FFE9..FFEC ; Math # Sm [4] HALFWIDTH LEFTWARDS ARROW..HALFWIDTH DOWNWARDS A 1D78 ; Alphabetic # Lm MODIFIER LETTER CYRILLIC EN 1D79..1D9A ; Alphabetic # L& [34] LATIN SMALL LETTER INSULAR G..LATIN SMALL LETTER EZH WITH RETROFLEX HOOK 1D9B..1DBF ; Alphabetic # Lm [37] MODIFIER LETTER SMALL TURNED ALPHA..MODIFIER LETTER SMALL THETA -1DE7..1DF4 ; Alphabetic # Mn [14] COMBINING LATIN SMALL LETTER ALPHA..COMBINING LATIN SMALL LETTER U WITH DIAERESIS +1DD3..1DF4 ; Alphabetic # Mn [34] COMBINING LATIN SMALL LETTER FLATTENED OPEN A ABOVE..COMBINING LATIN SMALL LETTER U WITH DIAERESIS 1E00..1F15 ; Alphabetic # L& [278] LATIN CAPITAL LETTER A WITH RING BELOW..GREEK SMALL LETTER EPSILON WITH DASIA AND OXIA 1F18..1F1D ; Alphabetic # L& [6] GREEK CAPITAL LETTER EPSILON WITH PSILI..GREEK CAPITAL LETTER EPSILON WITH DASIA AND OXIA 1F20..1F45 ; Alphabetic # L& [38] GREEK SMALL LETTER ETA WITH PSILI..GREEK SMALL LETTER OMICRON WITH DASIA AND OXIA @@ -830,10 +833,10 @@ A771..A787 ; Alphabetic # L& [23] LATIN SMALL LETTER DUM..LATIN SMALL LETTER A788 ; Alphabetic # Lm MODIFIER LETTER LOW CIRCUMFLEX ACCENT A78B..A78E ; Alphabetic # L& [4] LATIN CAPITAL LETTER SALTILLO..LATIN SMALL LETTER L WITH RETROFLEX HOOK AND BELT A78F ; Alphabetic # Lo LATIN LETTER SINOLOGICAL DOT -A790..A7CA ; Alphabetic # L& [59] LATIN CAPITAL LETTER N WITH DESCENDER..LATIN SMALL LETTER S WITH SHORT STROKE OVERLAY +A790..A7CD ; Alphabetic # L& [62] LATIN CAPITAL LETTER N WITH DESCENDER..LATIN SMALL LETTER S WITH DIAGONAL STROKE A7D0..A7D1 ; Alphabetic # L& [2] LATIN CAPITAL LETTER CLOSED INSULAR G..LATIN SMALL LETTER CLOSED INSULAR G A7D3 ; Alphabetic # L& LATIN SMALL LETTER DOUBLE THORN -A7D5..A7D9 ; Alphabetic # L& [5] LATIN SMALL LETTER DOUBLE WYNN..LATIN SMALL LETTER SIGMOID S +A7D5..A7DC ; Alphabetic # L& [8] LATIN SMALL LETTER DOUBLE WYNN..LATIN CAPITAL LETTER LAMBDA WITH STROKE A7F2..A7F4 ; Alphabetic # Lm [3] MODIFIER LETTER CAPITAL C..MODIFIER LETTER CAPITAL Q A7F5..A7F6 ; Alphabetic # L& [2] LATIN CAPITAL LETTER REVERSED HALF H..LATIN SMALL LETTER REVERSED HALF H A7F7 ; Alphabetic # Lo LATIN EPIGRAPHIC LETTER SIDEWAYS I @@ -998,6 +1001,7 @@ FFDA..FFDC ; Alphabetic # Lo [3] HALFWIDTH HANGUL LETTER EU..HALFWIDTH HANG 105A3..105B1 ; Alphabetic # L& [15] VITHKUQI SMALL LETTER HA..VITHKUQI SMALL LETTER RE 105B3..105B9 ; Alphabetic # L& [7] VITHKUQI SMALL LETTER SE..VITHKUQI SMALL LETTER XE 105BB..105BC ; Alphabetic # L& [2] VITHKUQI SMALL LETTER Y..VITHKUQI SMALL LETTER ZE +105C0..105F3 ; Alphabetic # Lo [52] TODHRI LETTER A..TODHRI LETTER OO 10600..10736 ; Alphabetic # Lo [311] LINEAR A SIGN AB001..LINEAR A SIGN A664 10740..10755 ; Alphabetic # Lo [22] LINEAR A SIGN A701 A..LINEAR A SIGN A732 JE 10760..10767 ; Alphabetic # Lo [8] LINEAR A SIGN A800..LINEAR A SIGN A807 @@ -1038,9 +1042,18 @@ FFDA..FFDC ; Alphabetic # Lo [3] HALFWIDTH HANGUL LETTER EU..HALFWIDTH HANG 10CC0..10CF2 ; Alphabetic # L& [51] OLD HUNGARIAN SMALL LETTER A..OLD HUNGARIAN SMALL LETTER US 10D00..10D23 ; Alphabetic # Lo [36] HANIFI ROHINGYA LETTER A..HANIFI ROHINGYA MARK NA KHONNA 10D24..10D27 ; Alphabetic # Mn [4] HANIFI ROHINGYA SIGN HARBAHAY..HANIFI ROHINGYA SIGN TASSI +10D4A..10D4D ; Alphabetic # Lo [4] GARAY VOWEL SIGN A..GARAY VOWEL SIGN EE +10D4E ; Alphabetic # Lm GARAY VOWEL LENGTH MARK +10D4F ; Alphabetic # Lo GARAY SUKUN +10D50..10D65 ; Alphabetic # L& [22] GARAY CAPITAL LETTER A..GARAY CAPITAL LETTER OLD NA +10D69 ; Alphabetic # Mn GARAY VOWEL SIGN E +10D6F ; Alphabetic # Lm GARAY REDUPLICATION MARK +10D70..10D85 ; Alphabetic # L& [22] GARAY SMALL LETTER A..GARAY SMALL LETTER OLD NA 10E80..10EA9 ; Alphabetic # Lo [42] YEZIDI LETTER ELIF..YEZIDI LETTER ET 10EAB..10EAC ; Alphabetic # Mn [2] YEZIDI COMBINING HAMZA MARK..YEZIDI COMBINING MADDA MARK 10EB0..10EB1 ; Alphabetic # Lo [2] YEZIDI LETTER LAM WITH DOT ABOVE..YEZIDI LETTER YOT WITH CIRCUMFLEX ABOVE +10EC2..10EC4 ; Alphabetic # Lo [3] ARABIC LETTER DAL WITH TWO DOTS VERTICALLY BELOW..ARABIC LETTER KAF WITH TWO DOTS VERTICALLY BELOW +10EFC ; Alphabetic # Mn ARABIC COMBINING ALEF OVERLAY 10F00..10F1C ; Alphabetic # Lo [29] OLD SOGDIAN LETTER ALEPH..OLD SOGDIAN LETTER FINAL TAW WITH VERTICAL TAIL 10F27 ; Alphabetic # Lo OLD SOGDIAN LIGATURE AYIN-DALETH 10F30..10F45 ; Alphabetic # Lo [22] SOGDIAN LETTER ALEPH..SOGDIAN INDEPENDENT SHIN @@ -1121,6 +1134,19 @@ FFDA..FFDC ; Alphabetic # Lo [3] HALFWIDTH HANGUL LETTER EU..HALFWIDTH HANG 11357 ; Alphabetic # Mc GRANTHA AU LENGTH MARK 1135D..11361 ; Alphabetic # Lo [5] GRANTHA SIGN PLUTA..GRANTHA LETTER VOCALIC LL 11362..11363 ; Alphabetic # Mc [2] GRANTHA VOWEL SIGN VOCALIC L..GRANTHA VOWEL SIGN VOCALIC LL +11380..11389 ; Alphabetic # Lo [10] TULU-TIGALARI LETTER A..TULU-TIGALARI LETTER VOCALIC LL +1138B ; Alphabetic # Lo TULU-TIGALARI LETTER EE +1138E ; Alphabetic # Lo TULU-TIGALARI LETTER AI +11390..113B5 ; Alphabetic # Lo [38] TULU-TIGALARI LETTER OO..TULU-TIGALARI LETTER LLLA +113B7 ; Alphabetic # Lo TULU-TIGALARI SIGN AVAGRAHA +113B8..113BA ; Alphabetic # Mc [3] TULU-TIGALARI VOWEL SIGN AA..TULU-TIGALARI VOWEL SIGN II +113BB..113C0 ; Alphabetic # Mn [6] TULU-TIGALARI VOWEL SIGN U..TULU-TIGALARI VOWEL SIGN VOCALIC LL +113C2 ; Alphabetic # Mc TULU-TIGALARI VOWEL SIGN EE +113C5 ; Alphabetic # Mc TULU-TIGALARI VOWEL SIGN AI +113C7..113CA ; Alphabetic # Mc [4] TULU-TIGALARI VOWEL SIGN OO..TULU-TIGALARI SIGN CANDRA ANUNASIKA +113CC..113CD ; Alphabetic # Mc [2] TULU-TIGALARI SIGN ANUSVARA..TULU-TIGALARI SIGN VISARGA +113D1 ; Alphabetic # Lo TULU-TIGALARI REPHA +113D3 ; Alphabetic # Lo TULU-TIGALARI SIGN PLUTA 11400..11434 ; Alphabetic # Lo [53] NEWA LETTER A..NEWA LETTER HA 11435..11437 ; Alphabetic # Mc [3] NEWA VOWEL SIGN AA..NEWA VOWEL SIGN II 11438..1143F ; Alphabetic # Mn [8] NEWA VOWEL SIGN U..NEWA VOWEL SIGN AI @@ -1163,7 +1189,9 @@ FFDA..FFDC ; Alphabetic # Lo [3] HALFWIDTH HANGUL LETTER EU..HALFWIDTH HANG 116B0..116B5 ; Alphabetic # Mn [6] TAKRI VOWEL SIGN U..TAKRI VOWEL SIGN AU 116B8 ; Alphabetic # Lo TAKRI LETTER ARCHAIC KHA 11700..1171A ; Alphabetic # Lo [27] AHOM LETTER KA..AHOM LETTER ALTERNATE BA -1171D..1171F ; Alphabetic # Mn [3] AHOM CONSONANT SIGN MEDIAL LA..AHOM CONSONANT SIGN MEDIAL LIGATING RA +1171D ; Alphabetic # Mn AHOM CONSONANT SIGN MEDIAL LA +1171E ; Alphabetic # Mc AHOM CONSONANT SIGN MEDIAL RA +1171F ; Alphabetic # Mn AHOM CONSONANT SIGN MEDIAL LIGATING RA 11720..11721 ; Alphabetic # Mc [2] AHOM VOWEL SIGN A..AHOM VOWEL SIGN AA 11722..11725 ; Alphabetic # Mn [4] AHOM VOWEL SIGN I..AHOM VOWEL SIGN UU 11726 ; Alphabetic # Mc AHOM VOWEL SIGN E @@ -1211,6 +1239,7 @@ FFDA..FFDC ; Alphabetic # Lo [3] HALFWIDTH HANGUL LETTER EU..HALFWIDTH HANG 11A97 ; Alphabetic # Mc SOYOMBO SIGN VISARGA 11A9D ; Alphabetic # Lo SOYOMBO MARK PLUTA 11AB0..11AF8 ; Alphabetic # Lo [73] CANADIAN SYLLABICS NATTILIK HI..PAU CIN HAU GLOTTAL STOP FINAL +11BC0..11BE0 ; Alphabetic # Lo [33] SUNUWAR LETTER DEVI..SUNUWAR LETTER KLOKO 11C00..11C08 ; Alphabetic # Lo [9] BHAIKSUKI LETTER A..BHAIKSUKI LETTER VOCALIC L 11C0A..11C2E ; Alphabetic # Lo [37] BHAIKSUKI LETTER E..BHAIKSUKI LETTER HA 11C2F ; Alphabetic # Mc BHAIKSUKI VOWEL SIGN AA @@ -1264,7 +1293,12 @@ FFDA..FFDC ; Alphabetic # Lo [3] HALFWIDTH HANGUL LETTER EU..HALFWIDTH HANG 12F90..12FF0 ; Alphabetic # Lo [97] CYPRO-MINOAN SIGN CM001..CYPRO-MINOAN SIGN CM114 13000..1342F ; Alphabetic # Lo [1072] EGYPTIAN HIEROGLYPH A001..EGYPTIAN HIEROGLYPH V011D 13441..13446 ; Alphabetic # Lo [6] EGYPTIAN HIEROGLYPH FULL BLANK..EGYPTIAN HIEROGLYPH WIDE LOST SIGN +13460..143FA ; Alphabetic # Lo [3995] EGYPTIAN HIEROGLYPH-13460..EGYPTIAN HIEROGLYPH-143FA 14400..14646 ; Alphabetic # Lo [583] ANATOLIAN HIEROGLYPH A001..ANATOLIAN HIEROGLYPH A530 +16100..1611D ; Alphabetic # Lo [30] GURUNG KHEMA LETTER A..GURUNG KHEMA LETTER SA +1611E..16129 ; Alphabetic # Mn [12] GURUNG KHEMA VOWEL SIGN AA..GURUNG KHEMA VOWEL LENGTH MARK +1612A..1612C ; Alphabetic # Mc [3] GURUNG KHEMA CONSONANT SIGN MEDIAL YA..GURUNG KHEMA CONSONANT SIGN MEDIAL HA +1612D..1612E ; Alphabetic # Mn [2] GURUNG KHEMA SIGN ANUSVARA..GURUNG KHEMA CONSONANT SIGN MEDIAL RA 16800..16A38 ; Alphabetic # Lo [569] BAMUM LETTER PHASE-A NGKUE MFON..BAMUM LETTER PHASE-F VUEQ 16A40..16A5E ; Alphabetic # Lo [31] MRO LETTER TA..MRO LETTER TEK 16A70..16ABE ; Alphabetic # Lo [79] TANGSA LETTER OZ..TANGSA LETTER ZA @@ -1273,6 +1307,9 @@ FFDA..FFDC ; Alphabetic # Lo [3] HALFWIDTH HANGUL LETTER EU..HALFWIDTH HANG 16B40..16B43 ; Alphabetic # Lm [4] PAHAWH HMONG SIGN VOS SEEV..PAHAWH HMONG SIGN IB YAM 16B63..16B77 ; Alphabetic # Lo [21] PAHAWH HMONG SIGN VOS LUB..PAHAWH HMONG SIGN CIM NRES TOS 16B7D..16B8F ; Alphabetic # Lo [19] PAHAWH HMONG CLAN SIGN TSHEEJ..PAHAWH HMONG CLAN SIGN VWJ +16D40..16D42 ; Alphabetic # Lm [3] KIRAT RAI SIGN ANUSVARA..KIRAT RAI SIGN VISARGA +16D43..16D6A ; Alphabetic # Lo [40] KIRAT RAI LETTER A..KIRAT RAI VOWEL SIGN AU +16D6B..16D6C ; Alphabetic # Lm [2] KIRAT RAI SIGN VIRAMA..KIRAT RAI SIGN SAAT 16E40..16E7F ; Alphabetic # L& [64] MEDEFAIDRIN CAPITAL LETTER M..MEDEFAIDRIN SMALL LETTER Y 16F00..16F4A ; Alphabetic # Lo [75] MIAO LETTER PA..MIAO LETTER RTE 16F4F ; Alphabetic # Mn MIAO SIGN CONSONANT MODIFIER BAR @@ -1285,7 +1322,7 @@ FFDA..FFDC ; Alphabetic # Lo [3] HALFWIDTH HANGUL LETTER EU..HALFWIDTH HANG 16FF0..16FF1 ; Alphabetic # Mc [2] VIETNAMESE ALTERNATE READING MARK CA..VIETNAMESE ALTERNATE READING MARK NHAY 17000..187F7 ; Alphabetic # Lo [6136] TANGUT IDEOGRAPH-17000..TANGUT IDEOGRAPH-187F7 18800..18CD5 ; Alphabetic # Lo [1238] TANGUT COMPONENT-001..KHITAN SMALL SCRIPT CHARACTER-18CD5 -18D00..18D08 ; Alphabetic # Lo [9] TANGUT IDEOGRAPH-18D00..TANGUT IDEOGRAPH-18D08 +18CFF..18D08 ; Alphabetic # Lo [10] KHITAN SMALL SCRIPT CHARACTER-18CFF..TANGUT IDEOGRAPH-18D08 1AFF0..1AFF3 ; Alphabetic # Lm [4] KATAKANA LETTER MINNAN TONE-2..KATAKANA LETTER MINNAN TONE-5 1AFF5..1AFFB ; Alphabetic # Lm [7] KATAKANA LETTER MINNAN TONE-7..KATAKANA LETTER MINNAN NASALIZED TONE-5 1AFFD..1AFFE ; Alphabetic # Lm [2] KATAKANA LETTER MINNAN NASALIZED TONE-7..KATAKANA LETTER MINNAN NASALIZED TONE-8 @@ -1348,6 +1385,8 @@ FFDA..FFDC ; Alphabetic # Lo [3] HALFWIDTH HANGUL LETTER EU..HALFWIDTH HANG 1E2C0..1E2EB ; Alphabetic # Lo [44] WANCHO LETTER AA..WANCHO LETTER YIH 1E4D0..1E4EA ; Alphabetic # Lo [27] NAG MUNDARI LETTER O..NAG MUNDARI LETTER ELL 1E4EB ; Alphabetic # Lm NAG MUNDARI SIGN OJOD +1E5D0..1E5ED ; Alphabetic # Lo [30] OL ONAL LETTER O..OL ONAL LETTER EG +1E5F0 ; Alphabetic # Lo OL ONAL SIGN HODDOND 1E7E0..1E7E6 ; Alphabetic # Lo [7] ETHIOPIC SYLLABLE HHYA..ETHIOPIC SYLLABLE HHYO 1E7E8..1E7EB ; Alphabetic # Lo [4] ETHIOPIC SYLLABLE GURAGE HHWA..ETHIOPIC SYLLABLE HHWE 1E7ED..1E7EE ; Alphabetic # Lo [2] ETHIOPIC SYLLABLE GURAGE MWI..ETHIOPIC SYLLABLE GURAGE MWEE @@ -1402,7 +1441,7 @@ FFDA..FFDC ; Alphabetic # Lo [3] HALFWIDTH HANGUL LETTER EU..HALFWIDTH HANG 30000..3134A ; Alphabetic # Lo [4939] CJK UNIFIED IDEOGRAPH-30000..CJK UNIFIED IDEOGRAPH-3134A 31350..323AF ; Alphabetic # Lo [4192] CJK UNIFIED IDEOGRAPH-31350..CJK UNIFIED IDEOGRAPH-323AF -# Total code points: 138387 +# Total code points: 142759 # ================================================ @@ -1691,6 +1730,7 @@ FFDA..FFDC ; Alphabetic # Lo [3] HALFWIDTH HANGUL LETTER EU..HALFWIDTH HANG 10FD..10FF ; Lowercase # L& [3] GEORGIAN LETTER AEN..GEORGIAN LETTER LABIAL SIGN 13F8..13FD ; Lowercase # L& [6] CHEROKEE SMALL LETTER YE..CHEROKEE SMALL LETTER MV 1C80..1C88 ; Lowercase # L& [9] CYRILLIC SMALL LETTER ROUNDED VE..CYRILLIC SMALL LETTER UNBLENDED UK +1C8A ; Lowercase # L& CYRILLIC SMALL LETTER TJE 1D00..1D2B ; Lowercase # L& [44] LATIN LETTER SMALL CAPITAL A..CYRILLIC LETTER SMALL CAPITAL EL 1D2C..1D6A ; Lowercase # Lm [63] MODIFIER LETTER CAPITAL A..GREEK SUBSCRIPT SMALL LETTER CHI 1D6B..1D77 ; Lowercase # L& [13] LATIN SMALL LETTER UE..LATIN SMALL LETTER TURNED G @@ -2032,11 +2072,13 @@ A7C1 ; Lowercase # L& LATIN SMALL LETTER OLD POLISH O A7C3 ; Lowercase # L& LATIN SMALL LETTER ANGLICANA W A7C8 ; Lowercase # L& LATIN SMALL LETTER D WITH SHORT STROKE OVERLAY A7CA ; Lowercase # L& LATIN SMALL LETTER S WITH SHORT STROKE OVERLAY +A7CD ; Lowercase # L& LATIN SMALL LETTER S WITH DIAGONAL STROKE A7D1 ; Lowercase # L& LATIN SMALL LETTER CLOSED INSULAR G A7D3 ; Lowercase # L& LATIN SMALL LETTER DOUBLE THORN A7D5 ; Lowercase # L& LATIN SMALL LETTER DOUBLE WYNN A7D7 ; Lowercase # L& LATIN SMALL LETTER MIDDLE SCOTS S A7D9 ; Lowercase # L& LATIN SMALL LETTER SIGMOID S +A7DB ; Lowercase # L& LATIN SMALL LETTER LAMBDA A7F2..A7F4 ; Lowercase # Lm [3] MODIFIER LETTER CAPITAL C..MODIFIER LETTER CAPITAL Q A7F6 ; Lowercase # L& LATIN SMALL LETTER REVERSED HALF H A7F8..A7F9 ; Lowercase # Lm [2] MODIFIER LETTER CAPITAL H WITH STROKE..MODIFIER LETTER SMALL LIGATURE OE @@ -2060,6 +2102,7 @@ FF41..FF5A ; Lowercase # L& [26] FULLWIDTH LATIN SMALL LETTER A..FULLWIDTH L 10787..107B0 ; Lowercase # Lm [42] MODIFIER LETTER SMALL DZ DIGRAPH..MODIFIER LETTER SMALL V WITH RIGHT HOOK 107B2..107BA ; Lowercase # Lm [9] MODIFIER LETTER SMALL CAPITAL Y..MODIFIER LETTER SMALL S WITH CURL 10CC0..10CF2 ; Lowercase # L& [51] OLD HUNGARIAN SMALL LETTER A..OLD HUNGARIAN SMALL LETTER US +10D70..10D85 ; Lowercase # L& [22] GARAY SMALL LETTER A..GARAY SMALL LETTER OLD NA 118C0..118DF ; Lowercase # L& [32] WARANG CITI SMALL LETTER NGAA..WARANG CITI SMALL LETTER VIYO 16E60..16E7F ; Lowercase # L& [32] MEDEFAIDRIN SMALL LETTER M..MEDEFAIDRIN SMALL LETTER Y 1D41A..1D433 ; Lowercase # L& [26] MATHEMATICAL BOLD SMALL A..MATHEMATICAL BOLD SMALL Z @@ -2096,7 +2139,7 @@ FF41..FF5A ; Lowercase # L& [26] FULLWIDTH LATIN SMALL LETTER A..FULLWIDTH L 1E030..1E06D ; Lowercase # Lm [62] MODIFIER LETTER CYRILLIC SMALL A..MODIFIER LETTER CYRILLIC SMALL STRAIGHT U WITH STROKE 1E922..1E943 ; Lowercase # L& [34] ADLAM SMALL LETTER ALIF..ADLAM SMALL LETTER SHA -# Total code points: 2544 +# Total code points: 2569 # ================================================ @@ -2379,6 +2422,7 @@ FF41..FF5A ; Lowercase # L& [26] FULLWIDTH LATIN SMALL LETTER A..FULLWIDTH L 10C7 ; Uppercase # L& GEORGIAN CAPITAL LETTER YN 10CD ; Uppercase # L& GEORGIAN CAPITAL LETTER AEN 13A0..13F5 ; Uppercase # L& [86] CHEROKEE LETTER A..CHEROKEE LETTER MV +1C89 ; Uppercase # L& CYRILLIC CAPITAL LETTER TJE 1C90..1CBA ; Uppercase # L& [43] GEORGIAN MTAVRULI CAPITAL LETTER AN..GEORGIAN MTAVRULI CAPITAL LETTER AIN 1CBD..1CBF ; Uppercase # L& [3] GEORGIAN MTAVRULI CAPITAL LETTER AEN..GEORGIAN MTAVRULI CAPITAL LETTER LABIAL SIGN 1E00 ; Uppercase # L& LATIN CAPITAL LETTER A WITH RING BELOW @@ -2705,9 +2749,12 @@ A7C0 ; Uppercase # L& LATIN CAPITAL LETTER OLD POLISH O A7C2 ; Uppercase # L& LATIN CAPITAL LETTER ANGLICANA W A7C4..A7C7 ; Uppercase # L& [4] LATIN CAPITAL LETTER C WITH PALATAL HOOK..LATIN CAPITAL LETTER D WITH SHORT STROKE OVERLAY A7C9 ; Uppercase # L& LATIN CAPITAL LETTER S WITH SHORT STROKE OVERLAY +A7CB..A7CC ; Uppercase # L& [2] LATIN CAPITAL LETTER RAMS HORN..LATIN CAPITAL LETTER S WITH DIAGONAL STROKE A7D0 ; Uppercase # L& LATIN CAPITAL LETTER CLOSED INSULAR G A7D6 ; Uppercase # L& LATIN CAPITAL LETTER MIDDLE SCOTS S A7D8 ; Uppercase # L& LATIN CAPITAL LETTER SIGMOID S +A7DA ; Uppercase # L& LATIN CAPITAL LETTER LAMBDA +A7DC ; Uppercase # L& LATIN CAPITAL LETTER LAMBDA WITH STROKE A7F5 ; Uppercase # L& LATIN CAPITAL LETTER REVERSED HALF H FF21..FF3A ; Uppercase # L& [26] FULLWIDTH LATIN CAPITAL LETTER A..FULLWIDTH LATIN CAPITAL LETTER Z 10400..10427 ; Uppercase # L& [40] DESERET CAPITAL LETTER LONG I..DESERET CAPITAL LETTER EW @@ -2717,6 +2764,7 @@ FF21..FF3A ; Uppercase # L& [26] FULLWIDTH LATIN CAPITAL LETTER A..FULLWIDTH 1058C..10592 ; Uppercase # L& [7] VITHKUQI CAPITAL LETTER SE..VITHKUQI CAPITAL LETTER XE 10594..10595 ; Uppercase # L& [2] VITHKUQI CAPITAL LETTER Y..VITHKUQI CAPITAL LETTER ZE 10C80..10CB2 ; Uppercase # L& [51] OLD HUNGARIAN CAPITAL LETTER A..OLD HUNGARIAN CAPITAL LETTER US +10D50..10D65 ; Uppercase # L& [22] GARAY CAPITAL LETTER A..GARAY CAPITAL LETTER OLD NA 118A0..118BF ; Uppercase # L& [32] WARANG CITI CAPITAL LETTER NGAA..WARANG CITI CAPITAL LETTER VIYO 16E40..16E5F ; Uppercase # L& [32] MEDEFAIDRIN CAPITAL LETTER M..MEDEFAIDRIN CAPITAL LETTER Y 1D400..1D419 ; Uppercase # L& [26] MATHEMATICAL BOLD CAPITAL A..MATHEMATICAL BOLD CAPITAL Z @@ -2755,7 +2803,7 @@ FF21..FF3A ; Uppercase # L& [26] FULLWIDTH LATIN CAPITAL LETTER A..FULLWIDTH 1F150..1F169 ; Uppercase # So [26] NEGATIVE CIRCLED LATIN CAPITAL LETTER A..NEGATIVE CIRCLED LATIN CAPITAL LETTER Z 1F170..1F189 ; Uppercase # So [26] NEGATIVE SQUARED LATIN CAPITAL LETTER A..NEGATIVE SQUARED LATIN CAPITAL LETTER Z -# Total code points: 1951 +# Total code points: 1978 # ================================================ @@ -2800,7 +2848,7 @@ FF21..FF3A ; Uppercase # L& [26] FULLWIDTH LATIN CAPITAL LETTER A..FULLWIDTH 10FD..10FF ; Cased # L& [3] GEORGIAN LETTER AEN..GEORGIAN LETTER LABIAL SIGN 13A0..13F5 ; Cased # L& [86] CHEROKEE LETTER A..CHEROKEE LETTER MV 13F8..13FD ; Cased # L& [6] CHEROKEE SMALL LETTER YE..CHEROKEE SMALL LETTER MV -1C80..1C88 ; Cased # L& [9] CYRILLIC SMALL LETTER ROUNDED VE..CYRILLIC SMALL LETTER UNBLENDED UK +1C80..1C8A ; Cased # L& [11] CYRILLIC SMALL LETTER ROUNDED VE..CYRILLIC SMALL LETTER TJE 1C90..1CBA ; Cased # L& [43] GEORGIAN MTAVRULI CAPITAL LETTER AN..GEORGIAN MTAVRULI CAPITAL LETTER AIN 1CBD..1CBF ; Cased # L& [3] GEORGIAN MTAVRULI CAPITAL LETTER AEN..GEORGIAN MTAVRULI CAPITAL LETTER LABIAL SIGN 1D00..1D2B ; Cased # L& [44] LATIN LETTER SMALL CAPITAL A..CYRILLIC LETTER SMALL CAPITAL EL @@ -2863,10 +2911,10 @@ A722..A76F ; Cased # L& [78] LATIN CAPITAL LETTER EGYPTOLOGICAL ALEF..LATIN A770 ; Cased # Lm MODIFIER LETTER US A771..A787 ; Cased # L& [23] LATIN SMALL LETTER DUM..LATIN SMALL LETTER INSULAR T A78B..A78E ; Cased # L& [4] LATIN CAPITAL LETTER SALTILLO..LATIN SMALL LETTER L WITH RETROFLEX HOOK AND BELT -A790..A7CA ; Cased # L& [59] LATIN CAPITAL LETTER N WITH DESCENDER..LATIN SMALL LETTER S WITH SHORT STROKE OVERLAY +A790..A7CD ; Cased # L& [62] LATIN CAPITAL LETTER N WITH DESCENDER..LATIN SMALL LETTER S WITH DIAGONAL STROKE A7D0..A7D1 ; Cased # L& [2] LATIN CAPITAL LETTER CLOSED INSULAR G..LATIN SMALL LETTER CLOSED INSULAR G A7D3 ; Cased # L& LATIN SMALL LETTER DOUBLE THORN -A7D5..A7D9 ; Cased # L& [5] LATIN SMALL LETTER DOUBLE WYNN..LATIN SMALL LETTER SIGMOID S +A7D5..A7DC ; Cased # L& [8] LATIN SMALL LETTER DOUBLE WYNN..LATIN CAPITAL LETTER LAMBDA WITH STROKE A7F2..A7F4 ; Cased # Lm [3] MODIFIER LETTER CAPITAL C..MODIFIER LETTER CAPITAL Q A7F5..A7F6 ; Cased # L& [2] LATIN CAPITAL LETTER REVERSED HALF H..LATIN SMALL LETTER REVERSED HALF H A7F8..A7F9 ; Cased # Lm [2] MODIFIER LETTER CAPITAL H WITH STROKE..MODIFIER LETTER SMALL LIGATURE OE @@ -2897,6 +2945,8 @@ FF41..FF5A ; Cased # L& [26] FULLWIDTH LATIN SMALL LETTER A..FULLWIDTH LATIN 107B2..107BA ; Cased # Lm [9] MODIFIER LETTER SMALL CAPITAL Y..MODIFIER LETTER SMALL S WITH CURL 10C80..10CB2 ; Cased # L& [51] OLD HUNGARIAN CAPITAL LETTER A..OLD HUNGARIAN CAPITAL LETTER US 10CC0..10CF2 ; Cased # L& [51] OLD HUNGARIAN SMALL LETTER A..OLD HUNGARIAN SMALL LETTER US +10D50..10D65 ; Cased # L& [22] GARAY CAPITAL LETTER A..GARAY CAPITAL LETTER OLD NA +10D70..10D85 ; Cased # L& [22] GARAY SMALL LETTER A..GARAY SMALL LETTER OLD NA 118A0..118DF ; Cased # L& [64] WARANG CITI CAPITAL LETTER NGAA..WARANG CITI SMALL LETTER VIYO 16E40..16E7F ; Cased # L& [64] MEDEFAIDRIN CAPITAL LETTER M..MEDEFAIDRIN SMALL LETTER Y 1D400..1D454 ; Cased # L& [85] MATHEMATICAL BOLD CAPITAL A..MATHEMATICAL ITALIC SMALL G @@ -2938,7 +2988,7 @@ FF41..FF5A ; Cased # L& [26] FULLWIDTH LATIN SMALL LETTER A..FULLWIDTH LATIN 1F150..1F169 ; Cased # So [26] NEGATIVE CIRCLED LATIN CAPITAL LETTER A..NEGATIVE CIRCLED LATIN CAPITAL LETTER Z 1F170..1F189 ; Cased # So [26] NEGATIVE SQUARED LATIN CAPITAL LETTER A..NEGATIVE SQUARED LATIN CAPITAL LETTER Z -# Total code points: 4526 +# Total code points: 4578 # ================================================ @@ -3015,7 +3065,7 @@ FF41..FF5A ; Cased # L& [26] FULLWIDTH LATIN SMALL LETTER A..FULLWIDTH LATIN 0859..085B ; Case_Ignorable # Mn [3] MANDAIC AFFRICATION MARK..MANDAIC GEMINATION MARK 0888 ; Case_Ignorable # Sk ARABIC RAISED ROUND DOT 0890..0891 ; Case_Ignorable # Cf [2] ARABIC POUND MARK ABOVE..ARABIC PIASTRE MARK ABOVE -0898..089F ; Case_Ignorable # Mn [8] ARABIC SMALL HIGH WORD AL-JUZ..ARABIC HALF MADDA OVER MADDA +0897..089F ; Case_Ignorable # Mn [9] ARABIC PEPET..ARABIC HALF MADDA OVER MADDA 08C9 ; Case_Ignorable # Lm ARABIC SMALL FARSI YEH 08CA..08E1 ; Case_Ignorable # Mn [24] ARABIC SMALL HIGH FARSI YEH..ARABIC SMALL HIGH SIGN SAFHA 08E2 ; Case_Ignorable # Cf ARABIC DISPUTED END OF AYAH @@ -3296,8 +3346,11 @@ FFF9..FFFB ; Case_Ignorable # Cf [3] INTERLINEAR ANNOTATION ANCHOR..INTERLI 10A3F ; Case_Ignorable # Mn KHAROSHTHI VIRAMA 10AE5..10AE6 ; Case_Ignorable # Mn [2] MANICHAEAN ABBREVIATION MARK ABOVE..MANICHAEAN ABBREVIATION MARK BELOW 10D24..10D27 ; Case_Ignorable # Mn [4] HANIFI ROHINGYA SIGN HARBAHAY..HANIFI ROHINGYA SIGN TASSI +10D4E ; Case_Ignorable # Lm GARAY VOWEL LENGTH MARK +10D69..10D6D ; Case_Ignorable # Mn [5] GARAY VOWEL SIGN E..GARAY CONSONANT NASALIZATION MARK +10D6F ; Case_Ignorable # Lm GARAY REDUPLICATION MARK 10EAB..10EAC ; Case_Ignorable # Mn [2] YEZIDI COMBINING HAMZA MARK..YEZIDI COMBINING MADDA MARK -10EFD..10EFF ; Case_Ignorable # Mn [3] ARABIC SMALL LOW WORD SAKTA..ARABIC SMALL LOW WORD MADDA +10EFC..10EFF ; Case_Ignorable # Mn [4] ARABIC COMBINING ALEF OVERLAY..ARABIC SMALL LOW WORD MADDA 10F46..10F50 ; Case_Ignorable # Mn [11] SOGDIAN COMBINING DOT BELOW..SOGDIAN COMBINING STROKE BELOW 10F82..10F85 ; Case_Ignorable # Mn [4] OLD UYGHUR COMBINING DOT ABOVE..OLD UYGHUR COMBINING TWO DOTS BELOW 11001 ; Case_Ignorable # Mn BRAHMI SIGN ANUSVARA @@ -3330,6 +3383,11 @@ FFF9..FFFB ; Case_Ignorable # Cf [3] INTERLINEAR ANNOTATION ANCHOR..INTERLI 11340 ; Case_Ignorable # Mn GRANTHA VOWEL SIGN II 11366..1136C ; Case_Ignorable # Mn [7] COMBINING GRANTHA DIGIT ZERO..COMBINING GRANTHA DIGIT SIX 11370..11374 ; Case_Ignorable # Mn [5] COMBINING GRANTHA LETTER A..COMBINING GRANTHA LETTER PA +113BB..113C0 ; Case_Ignorable # Mn [6] TULU-TIGALARI VOWEL SIGN U..TULU-TIGALARI VOWEL SIGN VOCALIC LL +113CE ; Case_Ignorable # Mn TULU-TIGALARI SIGN VIRAMA +113D0 ; Case_Ignorable # Mn TULU-TIGALARI CONJOINER +113D2 ; Case_Ignorable # Mn TULU-TIGALARI GEMINATION MARK +113E1..113E2 ; Case_Ignorable # Mn [2] TULU-TIGALARI VEDIC TONE SVARITA..TULU-TIGALARI VEDIC TONE ANUDATTA 11438..1143F ; Case_Ignorable # Mn [8] NEWA VOWEL SIGN U..NEWA VOWEL SIGN AI 11442..11444 ; Case_Ignorable # Mn [3] NEWA SIGN VIRAMA..NEWA SIGN ANUSVARA 11446 ; Case_Ignorable # Mn NEWA SIGN NUKTA @@ -3349,7 +3407,8 @@ FFF9..FFFB ; Case_Ignorable # Cf [3] INTERLINEAR ANNOTATION ANCHOR..INTERLI 116AD ; Case_Ignorable # Mn TAKRI VOWEL SIGN AA 116B0..116B5 ; Case_Ignorable # Mn [6] TAKRI VOWEL SIGN U..TAKRI VOWEL SIGN AU 116B7 ; Case_Ignorable # Mn TAKRI SIGN NUKTA -1171D..1171F ; Case_Ignorable # Mn [3] AHOM CONSONANT SIGN MEDIAL LA..AHOM CONSONANT SIGN MEDIAL LIGATING RA +1171D ; Case_Ignorable # Mn AHOM CONSONANT SIGN MEDIAL LA +1171F ; Case_Ignorable # Mn AHOM CONSONANT SIGN MEDIAL LIGATING RA 11722..11725 ; Case_Ignorable # Mn [4] AHOM VOWEL SIGN I..AHOM VOWEL SIGN UU 11727..1172B ; Case_Ignorable # Mn [5] AHOM VOWEL SIGN AW..AHOM SIGN KILLER 1182F..11837 ; Case_Ignorable # Mn [9] DOGRA VOWEL SIGN U..DOGRA SIGN ANUSVARA @@ -3388,12 +3447,17 @@ FFF9..FFFB ; Case_Ignorable # Cf [3] INTERLINEAR ANNOTATION ANCHOR..INTERLI 11F36..11F3A ; Case_Ignorable # Mn [5] KAWI VOWEL SIGN I..KAWI VOWEL SIGN VOCALIC R 11F40 ; Case_Ignorable # Mn KAWI VOWEL SIGN EU 11F42 ; Case_Ignorable # Mn KAWI CONJOINER +11F5A ; Case_Ignorable # Mn KAWI SIGN NUKTA 13430..1343F ; Case_Ignorable # Cf [16] EGYPTIAN HIEROGLYPH VERTICAL JOINER..EGYPTIAN HIEROGLYPH END WALLED ENCLOSURE 13440 ; Case_Ignorable # Mn EGYPTIAN HIEROGLYPH MIRROR HORIZONTALLY 13447..13455 ; Case_Ignorable # Mn [15] EGYPTIAN HIEROGLYPH MODIFIER DAMAGED AT TOP START..EGYPTIAN HIEROGLYPH MODIFIER DAMAGED +1611E..16129 ; Case_Ignorable # Mn [12] GURUNG KHEMA VOWEL SIGN AA..GURUNG KHEMA VOWEL LENGTH MARK +1612D..1612F ; Case_Ignorable # Mn [3] GURUNG KHEMA SIGN ANUSVARA..GURUNG KHEMA SIGN THOLHOMA 16AF0..16AF4 ; Case_Ignorable # Mn [5] BASSA VAH COMBINING HIGH TONE..BASSA VAH COMBINING HIGH-LOW TONE 16B30..16B36 ; Case_Ignorable # Mn [7] PAHAWH HMONG MARK CIM TUB..PAHAWH HMONG MARK CIM TAUM 16B40..16B43 ; Case_Ignorable # Lm [4] PAHAWH HMONG SIGN VOS SEEV..PAHAWH HMONG SIGN IB YAM +16D40..16D42 ; Case_Ignorable # Lm [3] KIRAT RAI SIGN ANUSVARA..KIRAT RAI SIGN VISARGA +16D6B..16D6C ; Case_Ignorable # Lm [2] KIRAT RAI SIGN VIRAMA..KIRAT RAI SIGN SAAT 16F4F ; Case_Ignorable # Mn MIAO SIGN CONSONANT MODIFIER BAR 16F8F..16F92 ; Case_Ignorable # Mn [4] MIAO TONE RIGHT..MIAO TONE BELOW 16F93..16F9F ; Case_Ignorable # Lm [13] MIAO LETTER TONE-2..MIAO LETTER REFORMED TONE-8 @@ -3432,6 +3496,7 @@ FFF9..FFFB ; Case_Ignorable # Cf [3] INTERLINEAR ANNOTATION ANCHOR..INTERLI 1E2EC..1E2EF ; Case_Ignorable # Mn [4] WANCHO TONE TUP..WANCHO TONE KOINI 1E4EB ; Case_Ignorable # Lm NAG MUNDARI SIGN OJOD 1E4EC..1E4EF ; Case_Ignorable # Mn [4] NAG MUNDARI SIGN MUHOR..NAG MUNDARI SIGN SUTUH +1E5EE..1E5EF ; Case_Ignorable # Mn [2] OL ONAL SIGN MU..OL ONAL SIGN IKIR 1E8D0..1E8D6 ; Case_Ignorable # Mn [7] MENDE KIKAKUI COMBINING NUMBER TEENS..MENDE KIKAKUI COMBINING NUMBER MILLIONS 1E944..1E94A ; Case_Ignorable # Mn [7] ADLAM ALIF LENGTHENER..ADLAM NUKTA 1E94B ; Case_Ignorable # Lm ADLAM NASALIZATION MARK @@ -3440,7 +3505,7 @@ E0001 ; Case_Ignorable # Cf LANGUAGE TAG E0020..E007F ; Case_Ignorable # Cf [96] TAG SPACE..CANCEL TAG E0100..E01EF ; Case_Ignorable # Mn [240] VARIATION SELECTOR-17..VARIATION SELECTOR-256 -# Total code points: 2707 +# Total code points: 2749 # ================================================ @@ -3724,6 +3789,7 @@ E0100..E01EF ; Case_Ignorable # Mn [240] VARIATION SELECTOR-17..VARIATION SELEC 10C7 ; Changes_When_Lowercased # L& GEORGIAN CAPITAL LETTER YN 10CD ; Changes_When_Lowercased # L& GEORGIAN CAPITAL LETTER AEN 13A0..13F5 ; Changes_When_Lowercased # L& [86] CHEROKEE LETTER A..CHEROKEE LETTER MV +1C89 ; Changes_When_Lowercased # L& CYRILLIC CAPITAL LETTER TJE 1C90..1CBA ; Changes_When_Lowercased # L& [43] GEORGIAN MTAVRULI CAPITAL LETTER AN..GEORGIAN MTAVRULI CAPITAL LETTER AIN 1CBD..1CBF ; Changes_When_Lowercased # L& [3] GEORGIAN MTAVRULI CAPITAL LETTER AEN..GEORGIAN MTAVRULI CAPITAL LETTER LABIAL SIGN 1E00 ; Changes_When_Lowercased # L& LATIN CAPITAL LETTER A WITH RING BELOW @@ -4043,9 +4109,12 @@ A7C0 ; Changes_When_Lowercased # L& LATIN CAPITAL LETTER OLD POLI A7C2 ; Changes_When_Lowercased # L& LATIN CAPITAL LETTER ANGLICANA W A7C4..A7C7 ; Changes_When_Lowercased # L& [4] LATIN CAPITAL LETTER C WITH PALATAL HOOK..LATIN CAPITAL LETTER D WITH SHORT STROKE OVERLAY A7C9 ; Changes_When_Lowercased # L& LATIN CAPITAL LETTER S WITH SHORT STROKE OVERLAY +A7CB..A7CC ; Changes_When_Lowercased # L& [2] LATIN CAPITAL LETTER RAMS HORN..LATIN CAPITAL LETTER S WITH DIAGONAL STROKE A7D0 ; Changes_When_Lowercased # L& LATIN CAPITAL LETTER CLOSED INSULAR G A7D6 ; Changes_When_Lowercased # L& LATIN CAPITAL LETTER MIDDLE SCOTS S A7D8 ; Changes_When_Lowercased # L& LATIN CAPITAL LETTER SIGMOID S +A7DA ; Changes_When_Lowercased # L& LATIN CAPITAL LETTER LAMBDA +A7DC ; Changes_When_Lowercased # L& LATIN CAPITAL LETTER LAMBDA WITH STROKE A7F5 ; Changes_When_Lowercased # L& LATIN CAPITAL LETTER REVERSED HALF H FF21..FF3A ; Changes_When_Lowercased # L& [26] FULLWIDTH LATIN CAPITAL LETTER A..FULLWIDTH LATIN CAPITAL LETTER Z 10400..10427 ; Changes_When_Lowercased # L& [40] DESERET CAPITAL LETTER LONG I..DESERET CAPITAL LETTER EW @@ -4055,11 +4124,12 @@ FF21..FF3A ; Changes_When_Lowercased # L& [26] FULLWIDTH LATIN CAPITAL LETTE 1058C..10592 ; Changes_When_Lowercased # L& [7] VITHKUQI CAPITAL LETTER SE..VITHKUQI CAPITAL LETTER XE 10594..10595 ; Changes_When_Lowercased # L& [2] VITHKUQI CAPITAL LETTER Y..VITHKUQI CAPITAL LETTER ZE 10C80..10CB2 ; Changes_When_Lowercased # L& [51] OLD HUNGARIAN CAPITAL LETTER A..OLD HUNGARIAN CAPITAL LETTER US +10D50..10D65 ; Changes_When_Lowercased # L& [22] GARAY CAPITAL LETTER A..GARAY CAPITAL LETTER OLD NA 118A0..118BF ; Changes_When_Lowercased # L& [32] WARANG CITI CAPITAL LETTER NGAA..WARANG CITI CAPITAL LETTER VIYO 16E40..16E5F ; Changes_When_Lowercased # L& [32] MEDEFAIDRIN CAPITAL LETTER M..MEDEFAIDRIN CAPITAL LETTER Y 1E900..1E921 ; Changes_When_Lowercased # L& [34] ADLAM CAPITAL LETTER ALIF..ADLAM CAPITAL LETTER SHA -# Total code points: 1433 +# Total code points: 1460 # ================================================ @@ -4140,7 +4210,7 @@ FF21..FF3A ; Changes_When_Lowercased # L& [26] FULLWIDTH LATIN CAPITAL LETTE 018C ; Changes_When_Uppercased # L& LATIN SMALL LETTER D WITH TOPBAR 0192 ; Changes_When_Uppercased # L& LATIN SMALL LETTER F WITH HOOK 0195 ; Changes_When_Uppercased # L& LATIN SMALL LETTER HV -0199..019A ; Changes_When_Uppercased # L& [2] LATIN SMALL LETTER K WITH HOOK..LATIN SMALL LETTER L WITH BAR +0199..019B ; Changes_When_Uppercased # L& [3] LATIN SMALL LETTER K WITH HOOK..LATIN SMALL LETTER LAMBDA WITH STROKE 019E ; Changes_When_Uppercased # L& LATIN SMALL LETTER N WITH LONG RIGHT LEG 01A1 ; Changes_When_Uppercased # L& LATIN SMALL LETTER O WITH HORN 01A3 ; Changes_When_Uppercased # L& LATIN SMALL LETTER OI @@ -4216,8 +4286,7 @@ FF21..FF3A ; Changes_When_Lowercased # L& [26] FULLWIDTH LATIN CAPITAL LETTE 0259 ; Changes_When_Uppercased # L& LATIN SMALL LETTER SCHWA 025B..025C ; Changes_When_Uppercased # L& [2] LATIN SMALL LETTER OPEN E..LATIN SMALL LETTER REVERSED OPEN E 0260..0261 ; Changes_When_Uppercased # L& [2] LATIN SMALL LETTER G WITH HOOK..LATIN SMALL LETTER SCRIPT G -0263 ; Changes_When_Uppercased # L& LATIN SMALL LETTER GAMMA -0265..0266 ; Changes_When_Uppercased # L& [2] LATIN SMALL LETTER TURNED H..LATIN SMALL LETTER H WITH HOOK +0263..0266 ; Changes_When_Uppercased # L& [4] LATIN SMALL LETTER GAMMA..LATIN SMALL LETTER H WITH HOOK 0268..026C ; Changes_When_Uppercased # L& [5] LATIN SMALL LETTER I WITH STROKE..LATIN SMALL LETTER L WITH BELT 026F ; Changes_When_Uppercased # L& LATIN SMALL LETTER TURNED M 0271..0272 ; Changes_When_Uppercased # L& [2] LATIN SMALL LETTER M WITH HOOK..LATIN SMALL LETTER N WITH LEFT HOOK @@ -4357,6 +4426,7 @@ FF21..FF3A ; Changes_When_Lowercased # L& [26] FULLWIDTH LATIN CAPITAL LETTE 10FD..10FF ; Changes_When_Uppercased # L& [3] GEORGIAN LETTER AEN..GEORGIAN LETTER LABIAL SIGN 13F8..13FD ; Changes_When_Uppercased # L& [6] CHEROKEE SMALL LETTER YE..CHEROKEE SMALL LETTER MV 1C80..1C88 ; Changes_When_Uppercased # L& [9] CYRILLIC SMALL LETTER ROUNDED VE..CYRILLIC SMALL LETTER UNBLENDED UK +1C8A ; Changes_When_Uppercased # L& CYRILLIC SMALL LETTER TJE 1D79 ; Changes_When_Uppercased # L& LATIN SMALL LETTER INSULAR G 1D7D ; Changes_When_Uppercased # L& LATIN SMALL LETTER P WITH STROKE 1D8E ; Changes_When_Uppercased # L& LATIN SMALL LETTER Z WITH PALATAL HOOK @@ -4676,9 +4746,11 @@ A7C1 ; Changes_When_Uppercased # L& LATIN SMALL LETTER OLD POLISH A7C3 ; Changes_When_Uppercased # L& LATIN SMALL LETTER ANGLICANA W A7C8 ; Changes_When_Uppercased # L& LATIN SMALL LETTER D WITH SHORT STROKE OVERLAY A7CA ; Changes_When_Uppercased # L& LATIN SMALL LETTER S WITH SHORT STROKE OVERLAY +A7CD ; Changes_When_Uppercased # L& LATIN SMALL LETTER S WITH DIAGONAL STROKE A7D1 ; Changes_When_Uppercased # L& LATIN SMALL LETTER CLOSED INSULAR G A7D7 ; Changes_When_Uppercased # L& LATIN SMALL LETTER MIDDLE SCOTS S A7D9 ; Changes_When_Uppercased # L& LATIN SMALL LETTER SIGMOID S +A7DB ; Changes_When_Uppercased # L& LATIN SMALL LETTER LAMBDA A7F6 ; Changes_When_Uppercased # L& LATIN SMALL LETTER REVERSED HALF H AB53 ; Changes_When_Uppercased # L& LATIN SMALL LETTER CHI AB70..ABBF ; Changes_When_Uppercased # L& [80] CHEROKEE SMALL LETTER A..CHEROKEE SMALL LETTER YA @@ -4692,11 +4764,12 @@ FF41..FF5A ; Changes_When_Uppercased # L& [26] FULLWIDTH LATIN SMALL LETTER 105B3..105B9 ; Changes_When_Uppercased # L& [7] VITHKUQI SMALL LETTER SE..VITHKUQI SMALL LETTER XE 105BB..105BC ; Changes_When_Uppercased # L& [2] VITHKUQI SMALL LETTER Y..VITHKUQI SMALL LETTER ZE 10CC0..10CF2 ; Changes_When_Uppercased # L& [51] OLD HUNGARIAN SMALL LETTER A..OLD HUNGARIAN SMALL LETTER US +10D70..10D85 ; Changes_When_Uppercased # L& [22] GARAY SMALL LETTER A..GARAY SMALL LETTER OLD NA 118C0..118DF ; Changes_When_Uppercased # L& [32] WARANG CITI SMALL LETTER NGAA..WARANG CITI SMALL LETTER VIYO 16E60..16E7F ; Changes_When_Uppercased # L& [32] MEDEFAIDRIN SMALL LETTER M..MEDEFAIDRIN SMALL LETTER Y 1E922..1E943 ; Changes_When_Uppercased # L& [34] ADLAM SMALL LETTER ALIF..ADLAM SMALL LETTER SHA -# Total code points: 1525 +# Total code points: 1552 # ================================================ @@ -4777,7 +4850,7 @@ FF41..FF5A ; Changes_When_Uppercased # L& [26] FULLWIDTH LATIN SMALL LETTER 018C ; Changes_When_Titlecased # L& LATIN SMALL LETTER D WITH TOPBAR 0192 ; Changes_When_Titlecased # L& LATIN SMALL LETTER F WITH HOOK 0195 ; Changes_When_Titlecased # L& LATIN SMALL LETTER HV -0199..019A ; Changes_When_Titlecased # L& [2] LATIN SMALL LETTER K WITH HOOK..LATIN SMALL LETTER L WITH BAR +0199..019B ; Changes_When_Titlecased # L& [3] LATIN SMALL LETTER K WITH HOOK..LATIN SMALL LETTER LAMBDA WITH STROKE 019E ; Changes_When_Titlecased # L& LATIN SMALL LETTER N WITH LONG RIGHT LEG 01A1 ; Changes_When_Titlecased # L& LATIN SMALL LETTER O WITH HORN 01A3 ; Changes_When_Titlecased # L& LATIN SMALL LETTER OI @@ -4854,8 +4927,7 @@ FF41..FF5A ; Changes_When_Uppercased # L& [26] FULLWIDTH LATIN SMALL LETTER 0259 ; Changes_When_Titlecased # L& LATIN SMALL LETTER SCHWA 025B..025C ; Changes_When_Titlecased # L& [2] LATIN SMALL LETTER OPEN E..LATIN SMALL LETTER REVERSED OPEN E 0260..0261 ; Changes_When_Titlecased # L& [2] LATIN SMALL LETTER G WITH HOOK..LATIN SMALL LETTER SCRIPT G -0263 ; Changes_When_Titlecased # L& LATIN SMALL LETTER GAMMA -0265..0266 ; Changes_When_Titlecased # L& [2] LATIN SMALL LETTER TURNED H..LATIN SMALL LETTER H WITH HOOK +0263..0266 ; Changes_When_Titlecased # L& [4] LATIN SMALL LETTER GAMMA..LATIN SMALL LETTER H WITH HOOK 0268..026C ; Changes_When_Titlecased # L& [5] LATIN SMALL LETTER I WITH STROKE..LATIN SMALL LETTER L WITH BELT 026F ; Changes_When_Titlecased # L& LATIN SMALL LETTER TURNED M 0271..0272 ; Changes_When_Titlecased # L& [2] LATIN SMALL LETTER M WITH HOOK..LATIN SMALL LETTER N WITH LEFT HOOK @@ -4993,6 +5065,7 @@ FF41..FF5A ; Changes_When_Uppercased # L& [26] FULLWIDTH LATIN SMALL LETTER 0561..0587 ; Changes_When_Titlecased # L& [39] ARMENIAN SMALL LETTER AYB..ARMENIAN SMALL LIGATURE ECH YIWN 13F8..13FD ; Changes_When_Titlecased # L& [6] CHEROKEE SMALL LETTER YE..CHEROKEE SMALL LETTER MV 1C80..1C88 ; Changes_When_Titlecased # L& [9] CYRILLIC SMALL LETTER ROUNDED VE..CYRILLIC SMALL LETTER UNBLENDED UK +1C8A ; Changes_When_Titlecased # L& CYRILLIC SMALL LETTER TJE 1D79 ; Changes_When_Titlecased # L& LATIN SMALL LETTER INSULAR G 1D7D ; Changes_When_Titlecased # L& LATIN SMALL LETTER P WITH STROKE 1D8E ; Changes_When_Titlecased # L& LATIN SMALL LETTER Z WITH PALATAL HOOK @@ -5312,9 +5385,11 @@ A7C1 ; Changes_When_Titlecased # L& LATIN SMALL LETTER OLD POLISH A7C3 ; Changes_When_Titlecased # L& LATIN SMALL LETTER ANGLICANA W A7C8 ; Changes_When_Titlecased # L& LATIN SMALL LETTER D WITH SHORT STROKE OVERLAY A7CA ; Changes_When_Titlecased # L& LATIN SMALL LETTER S WITH SHORT STROKE OVERLAY +A7CD ; Changes_When_Titlecased # L& LATIN SMALL LETTER S WITH DIAGONAL STROKE A7D1 ; Changes_When_Titlecased # L& LATIN SMALL LETTER CLOSED INSULAR G A7D7 ; Changes_When_Titlecased # L& LATIN SMALL LETTER MIDDLE SCOTS S A7D9 ; Changes_When_Titlecased # L& LATIN SMALL LETTER SIGMOID S +A7DB ; Changes_When_Titlecased # L& LATIN SMALL LETTER LAMBDA A7F6 ; Changes_When_Titlecased # L& LATIN SMALL LETTER REVERSED HALF H AB53 ; Changes_When_Titlecased # L& LATIN SMALL LETTER CHI AB70..ABBF ; Changes_When_Titlecased # L& [80] CHEROKEE SMALL LETTER A..CHEROKEE SMALL LETTER YA @@ -5328,11 +5403,12 @@ FF41..FF5A ; Changes_When_Titlecased # L& [26] FULLWIDTH LATIN SMALL LETTER 105B3..105B9 ; Changes_When_Titlecased # L& [7] VITHKUQI SMALL LETTER SE..VITHKUQI SMALL LETTER XE 105BB..105BC ; Changes_When_Titlecased # L& [2] VITHKUQI SMALL LETTER Y..VITHKUQI SMALL LETTER ZE 10CC0..10CF2 ; Changes_When_Titlecased # L& [51] OLD HUNGARIAN SMALL LETTER A..OLD HUNGARIAN SMALL LETTER US +10D70..10D85 ; Changes_When_Titlecased # L& [22] GARAY SMALL LETTER A..GARAY SMALL LETTER OLD NA 118C0..118DF ; Changes_When_Titlecased # L& [32] WARANG CITI SMALL LETTER NGAA..WARANG CITI SMALL LETTER VIYO 16E60..16E7F ; Changes_When_Titlecased # L& [32] MEDEFAIDRIN SMALL LETTER M..MEDEFAIDRIN SMALL LETTER Y 1E922..1E943 ; Changes_When_Titlecased # L& [34] ADLAM SMALL LETTER ALIF..ADLAM SMALL LETTER SHA -# Total code points: 1452 +# Total code points: 1479 # ================================================ @@ -5623,7 +5699,7 @@ FF41..FF5A ; Changes_When_Titlecased # L& [26] FULLWIDTH LATIN SMALL LETTER 10C7 ; Changes_When_Casefolded # L& GEORGIAN CAPITAL LETTER YN 10CD ; Changes_When_Casefolded # L& GEORGIAN CAPITAL LETTER AEN 13F8..13FD ; Changes_When_Casefolded # L& [6] CHEROKEE SMALL LETTER YE..CHEROKEE SMALL LETTER MV -1C80..1C88 ; Changes_When_Casefolded # L& [9] CYRILLIC SMALL LETTER ROUNDED VE..CYRILLIC SMALL LETTER UNBLENDED UK +1C80..1C89 ; Changes_When_Casefolded # L& [10] CYRILLIC SMALL LETTER ROUNDED VE..CYRILLIC CAPITAL LETTER TJE 1C90..1CBA ; Changes_When_Casefolded # L& [43] GEORGIAN MTAVRULI CAPITAL LETTER AN..GEORGIAN MTAVRULI CAPITAL LETTER AIN 1CBD..1CBF ; Changes_When_Casefolded # L& [3] GEORGIAN MTAVRULI CAPITAL LETTER AEN..GEORGIAN MTAVRULI CAPITAL LETTER LABIAL SIGN 1E00 ; Changes_When_Casefolded # L& LATIN CAPITAL LETTER A WITH RING BELOW @@ -5945,9 +6021,12 @@ A7C0 ; Changes_When_Casefolded # L& LATIN CAPITAL LETTER OLD POLI A7C2 ; Changes_When_Casefolded # L& LATIN CAPITAL LETTER ANGLICANA W A7C4..A7C7 ; Changes_When_Casefolded # L& [4] LATIN CAPITAL LETTER C WITH PALATAL HOOK..LATIN CAPITAL LETTER D WITH SHORT STROKE OVERLAY A7C9 ; Changes_When_Casefolded # L& LATIN CAPITAL LETTER S WITH SHORT STROKE OVERLAY +A7CB..A7CC ; Changes_When_Casefolded # L& [2] LATIN CAPITAL LETTER RAMS HORN..LATIN CAPITAL LETTER S WITH DIAGONAL STROKE A7D0 ; Changes_When_Casefolded # L& LATIN CAPITAL LETTER CLOSED INSULAR G A7D6 ; Changes_When_Casefolded # L& LATIN CAPITAL LETTER MIDDLE SCOTS S A7D8 ; Changes_When_Casefolded # L& LATIN CAPITAL LETTER SIGMOID S +A7DA ; Changes_When_Casefolded # L& LATIN CAPITAL LETTER LAMBDA +A7DC ; Changes_When_Casefolded # L& LATIN CAPITAL LETTER LAMBDA WITH STROKE A7F5 ; Changes_When_Casefolded # L& LATIN CAPITAL LETTER REVERSED HALF H AB70..ABBF ; Changes_When_Casefolded # L& [80] CHEROKEE SMALL LETTER A..CHEROKEE SMALL LETTER YA FB00..FB06 ; Changes_When_Casefolded # L& [7] LATIN SMALL LIGATURE FF..LATIN SMALL LIGATURE ST @@ -5960,11 +6039,12 @@ FF21..FF3A ; Changes_When_Casefolded # L& [26] FULLWIDTH LATIN CAPITAL LETTE 1058C..10592 ; Changes_When_Casefolded # L& [7] VITHKUQI CAPITAL LETTER SE..VITHKUQI CAPITAL LETTER XE 10594..10595 ; Changes_When_Casefolded # L& [2] VITHKUQI CAPITAL LETTER Y..VITHKUQI CAPITAL LETTER ZE 10C80..10CB2 ; Changes_When_Casefolded # L& [51] OLD HUNGARIAN CAPITAL LETTER A..OLD HUNGARIAN CAPITAL LETTER US +10D50..10D65 ; Changes_When_Casefolded # L& [22] GARAY CAPITAL LETTER A..GARAY CAPITAL LETTER OLD NA 118A0..118BF ; Changes_When_Casefolded # L& [32] WARANG CITI CAPITAL LETTER NGAA..WARANG CITI CAPITAL LETTER VIYO 16E40..16E5F ; Changes_When_Casefolded # L& [32] MEDEFAIDRIN CAPITAL LETTER M..MEDEFAIDRIN CAPITAL LETTER Y 1E900..1E921 ; Changes_When_Casefolded # L& [34] ADLAM CAPITAL LETTER ALIF..ADLAM CAPITAL LETTER SHA -# Total code points: 1506 +# Total code points: 1533 # ================================================ @@ -5980,8 +6060,7 @@ FF21..FF3A ; Changes_When_Casefolded # L& [26] FULLWIDTH LATIN CAPITAL LETTE 00D8..00F6 ; Changes_When_Casemapped # L& [31] LATIN CAPITAL LETTER O WITH STROKE..LATIN SMALL LETTER O WITH DIAERESIS 00F8..0137 ; Changes_When_Casemapped # L& [64] LATIN SMALL LETTER O WITH STROKE..LATIN SMALL LETTER K WITH CEDILLA 0139..018C ; Changes_When_Casemapped # L& [84] LATIN CAPITAL LETTER L WITH ACUTE..LATIN SMALL LETTER D WITH TOPBAR -018E..019A ; Changes_When_Casemapped # L& [13] LATIN CAPITAL LETTER REVERSED E..LATIN SMALL LETTER L WITH BAR -019C..01A9 ; Changes_When_Casemapped # L& [14] LATIN CAPITAL LETTER TURNED M..LATIN CAPITAL LETTER ESH +018E..01A9 ; Changes_When_Casemapped # L& [28] LATIN CAPITAL LETTER REVERSED E..LATIN CAPITAL LETTER ESH 01AC..01B9 ; Changes_When_Casemapped # L& [14] LATIN CAPITAL LETTER T WITH HOOK..LATIN SMALL LETTER EZH REVERSED 01BC..01BD ; Changes_When_Casemapped # L& [2] LATIN CAPITAL LETTER TONE FIVE..LATIN SMALL LETTER TONE FIVE 01BF ; Changes_When_Casemapped # L& LATIN LETTER WYNN @@ -5992,8 +6071,7 @@ FF21..FF3A ; Changes_When_Casefolded # L& [26] FULLWIDTH LATIN CAPITAL LETTE 0259 ; Changes_When_Casemapped # L& LATIN SMALL LETTER SCHWA 025B..025C ; Changes_When_Casemapped # L& [2] LATIN SMALL LETTER OPEN E..LATIN SMALL LETTER REVERSED OPEN E 0260..0261 ; Changes_When_Casemapped # L& [2] LATIN SMALL LETTER G WITH HOOK..LATIN SMALL LETTER SCRIPT G -0263 ; Changes_When_Casemapped # L& LATIN SMALL LETTER GAMMA -0265..0266 ; Changes_When_Casemapped # L& [2] LATIN SMALL LETTER TURNED H..LATIN SMALL LETTER H WITH HOOK +0263..0266 ; Changes_When_Casemapped # L& [4] LATIN SMALL LETTER GAMMA..LATIN SMALL LETTER H WITH HOOK 0268..026C ; Changes_When_Casemapped # L& [5] LATIN SMALL LETTER I WITH STROKE..LATIN SMALL LETTER L WITH BELT 026F ; Changes_When_Casemapped # L& LATIN SMALL LETTER TURNED M 0271..0272 ; Changes_When_Casemapped # L& [2] LATIN SMALL LETTER M WITH HOOK..LATIN SMALL LETTER N WITH LEFT HOOK @@ -6027,7 +6105,7 @@ FF21..FF3A ; Changes_When_Casefolded # L& [26] FULLWIDTH LATIN CAPITAL LETTE 10FD..10FF ; Changes_When_Casemapped # L& [3] GEORGIAN LETTER AEN..GEORGIAN LETTER LABIAL SIGN 13A0..13F5 ; Changes_When_Casemapped # L& [86] CHEROKEE LETTER A..CHEROKEE LETTER MV 13F8..13FD ; Changes_When_Casemapped # L& [6] CHEROKEE SMALL LETTER YE..CHEROKEE SMALL LETTER MV -1C80..1C88 ; Changes_When_Casemapped # L& [9] CYRILLIC SMALL LETTER ROUNDED VE..CYRILLIC SMALL LETTER UNBLENDED UK +1C80..1C8A ; Changes_When_Casemapped # L& [11] CYRILLIC SMALL LETTER ROUNDED VE..CYRILLIC SMALL LETTER TJE 1C90..1CBA ; Changes_When_Casemapped # L& [43] GEORGIAN MTAVRULI CAPITAL LETTER AN..GEORGIAN MTAVRULI CAPITAL LETTER AIN 1CBD..1CBF ; Changes_When_Casemapped # L& [3] GEORGIAN MTAVRULI CAPITAL LETTER AEN..GEORGIAN MTAVRULI CAPITAL LETTER LABIAL SIGN 1D79 ; Changes_When_Casemapped # L& LATIN SMALL LETTER INSULAR G @@ -6078,9 +6156,9 @@ A779..A787 ; Changes_When_Casemapped # L& [15] LATIN CAPITAL LETTER INSULAR A78B..A78D ; Changes_When_Casemapped # L& [3] LATIN CAPITAL LETTER SALTILLO..LATIN CAPITAL LETTER TURNED H A790..A794 ; Changes_When_Casemapped # L& [5] LATIN CAPITAL LETTER N WITH DESCENDER..LATIN SMALL LETTER C WITH PALATAL HOOK A796..A7AE ; Changes_When_Casemapped # L& [25] LATIN CAPITAL LETTER B WITH FLOURISH..LATIN CAPITAL LETTER SMALL CAPITAL I -A7B0..A7CA ; Changes_When_Casemapped # L& [27] LATIN CAPITAL LETTER TURNED K..LATIN SMALL LETTER S WITH SHORT STROKE OVERLAY +A7B0..A7CD ; Changes_When_Casemapped # L& [30] LATIN CAPITAL LETTER TURNED K..LATIN SMALL LETTER S WITH DIAGONAL STROKE A7D0..A7D1 ; Changes_When_Casemapped # L& [2] LATIN CAPITAL LETTER CLOSED INSULAR G..LATIN SMALL LETTER CLOSED INSULAR G -A7D6..A7D9 ; Changes_When_Casemapped # L& [4] LATIN CAPITAL LETTER MIDDLE SCOTS S..LATIN SMALL LETTER SIGMOID S +A7D6..A7DC ; Changes_When_Casemapped # L& [7] LATIN CAPITAL LETTER MIDDLE SCOTS S..LATIN CAPITAL LETTER LAMBDA WITH STROKE A7F5..A7F6 ; Changes_When_Casemapped # L& [2] LATIN CAPITAL LETTER REVERSED HALF H..LATIN SMALL LETTER REVERSED HALF H AB53 ; Changes_When_Casemapped # L& LATIN SMALL LETTER CHI AB70..ABBF ; Changes_When_Casemapped # L& [80] CHEROKEE SMALL LETTER A..CHEROKEE SMALL LETTER YA @@ -6101,11 +6179,13 @@ FF41..FF5A ; Changes_When_Casemapped # L& [26] FULLWIDTH LATIN SMALL LETTER 105BB..105BC ; Changes_When_Casemapped # L& [2] VITHKUQI SMALL LETTER Y..VITHKUQI SMALL LETTER ZE 10C80..10CB2 ; Changes_When_Casemapped # L& [51] OLD HUNGARIAN CAPITAL LETTER A..OLD HUNGARIAN CAPITAL LETTER US 10CC0..10CF2 ; Changes_When_Casemapped # L& [51] OLD HUNGARIAN SMALL LETTER A..OLD HUNGARIAN SMALL LETTER US +10D50..10D65 ; Changes_When_Casemapped # L& [22] GARAY CAPITAL LETTER A..GARAY CAPITAL LETTER OLD NA +10D70..10D85 ; Changes_When_Casemapped # L& [22] GARAY SMALL LETTER A..GARAY SMALL LETTER OLD NA 118A0..118DF ; Changes_When_Casemapped # L& [64] WARANG CITI CAPITAL LETTER NGAA..WARANG CITI SMALL LETTER VIYO 16E40..16E7F ; Changes_When_Casemapped # L& [64] MEDEFAIDRIN CAPITAL LETTER M..MEDEFAIDRIN SMALL LETTER Y 1E900..1E943 ; Changes_When_Casemapped # L& [68] ADLAM CAPITAL LETTER ALIF..ADLAM SMALL LETTER SHA -# Total code points: 2927 +# Total code points: 2981 # ================================================ @@ -6364,7 +6444,7 @@ FF41..FF5A ; Changes_When_Casemapped # L& [26] FULLWIDTH LATIN SMALL LETTER 1C4D..1C4F ; ID_Start # Lo [3] LEPCHA LETTER TTA..LEPCHA LETTER DDA 1C5A..1C77 ; ID_Start # Lo [30] OL CHIKI LETTER LA..OL CHIKI LETTER OH 1C78..1C7D ; ID_Start # Lm [6] OL CHIKI MU TTUDDAG..OL CHIKI AHAD -1C80..1C88 ; ID_Start # L& [9] CYRILLIC SMALL LETTER ROUNDED VE..CYRILLIC SMALL LETTER UNBLENDED UK +1C80..1C8A ; ID_Start # L& [11] CYRILLIC SMALL LETTER ROUNDED VE..CYRILLIC SMALL LETTER TJE 1C90..1CBA ; ID_Start # L& [43] GEORGIAN MTAVRULI CAPITAL LETTER AN..GEORGIAN MTAVRULI CAPITAL LETTER AIN 1CBD..1CBF ; ID_Start # L& [3] GEORGIAN MTAVRULI CAPITAL LETTER AEN..GEORGIAN MTAVRULI CAPITAL LETTER LABIAL SIGN 1CE9..1CEC ; ID_Start # Lo [4] VEDIC SIGN ANUSVARA ANTARGOMUKHA..VEDIC SIGN ANUSVARA VAMAGOMUKHA WITH TAIL @@ -6481,10 +6561,10 @@ A771..A787 ; ID_Start # L& [23] LATIN SMALL LETTER DUM..LATIN SMALL LETTER I A788 ; ID_Start # Lm MODIFIER LETTER LOW CIRCUMFLEX ACCENT A78B..A78E ; ID_Start # L& [4] LATIN CAPITAL LETTER SALTILLO..LATIN SMALL LETTER L WITH RETROFLEX HOOK AND BELT A78F ; ID_Start # Lo LATIN LETTER SINOLOGICAL DOT -A790..A7CA ; ID_Start # L& [59] LATIN CAPITAL LETTER N WITH DESCENDER..LATIN SMALL LETTER S WITH SHORT STROKE OVERLAY +A790..A7CD ; ID_Start # L& [62] LATIN CAPITAL LETTER N WITH DESCENDER..LATIN SMALL LETTER S WITH DIAGONAL STROKE A7D0..A7D1 ; ID_Start # L& [2] LATIN CAPITAL LETTER CLOSED INSULAR G..LATIN SMALL LETTER CLOSED INSULAR G A7D3 ; ID_Start # L& LATIN SMALL LETTER DOUBLE THORN -A7D5..A7D9 ; ID_Start # L& [5] LATIN SMALL LETTER DOUBLE WYNN..LATIN SMALL LETTER SIGMOID S +A7D5..A7DC ; ID_Start # L& [8] LATIN SMALL LETTER DOUBLE WYNN..LATIN CAPITAL LETTER LAMBDA WITH STROKE A7F2..A7F4 ; ID_Start # Lm [3] MODIFIER LETTER CAPITAL C..MODIFIER LETTER CAPITAL Q A7F5..A7F6 ; ID_Start # L& [2] LATIN CAPITAL LETTER REVERSED HALF H..LATIN SMALL LETTER REVERSED HALF H A7F7 ; ID_Start # Lo LATIN EPIGRAPHIC LETTER SIDEWAYS I @@ -6603,6 +6683,7 @@ FFDA..FFDC ; ID_Start # Lo [3] HALFWIDTH HANGUL LETTER EU..HALFWIDTH HANGUL 105A3..105B1 ; ID_Start # L& [15] VITHKUQI SMALL LETTER HA..VITHKUQI SMALL LETTER RE 105B3..105B9 ; ID_Start # L& [7] VITHKUQI SMALL LETTER SE..VITHKUQI SMALL LETTER XE 105BB..105BC ; ID_Start # L& [2] VITHKUQI SMALL LETTER Y..VITHKUQI SMALL LETTER ZE +105C0..105F3 ; ID_Start # Lo [52] TODHRI LETTER A..TODHRI LETTER OO 10600..10736 ; ID_Start # Lo [311] LINEAR A SIGN AB001..LINEAR A SIGN A664 10740..10755 ; ID_Start # Lo [22] LINEAR A SIGN A701 A..LINEAR A SIGN A732 JE 10760..10767 ; ID_Start # Lo [8] LINEAR A SIGN A800..LINEAR A SIGN A807 @@ -6639,8 +6720,15 @@ FFDA..FFDC ; ID_Start # Lo [3] HALFWIDTH HANGUL LETTER EU..HALFWIDTH HANGUL 10C80..10CB2 ; ID_Start # L& [51] OLD HUNGARIAN CAPITAL LETTER A..OLD HUNGARIAN CAPITAL LETTER US 10CC0..10CF2 ; ID_Start # L& [51] OLD HUNGARIAN SMALL LETTER A..OLD HUNGARIAN SMALL LETTER US 10D00..10D23 ; ID_Start # Lo [36] HANIFI ROHINGYA LETTER A..HANIFI ROHINGYA MARK NA KHONNA +10D4A..10D4D ; ID_Start # Lo [4] GARAY VOWEL SIGN A..GARAY VOWEL SIGN EE +10D4E ; ID_Start # Lm GARAY VOWEL LENGTH MARK +10D4F ; ID_Start # Lo GARAY SUKUN +10D50..10D65 ; ID_Start # L& [22] GARAY CAPITAL LETTER A..GARAY CAPITAL LETTER OLD NA +10D6F ; ID_Start # Lm GARAY REDUPLICATION MARK +10D70..10D85 ; ID_Start # L& [22] GARAY SMALL LETTER A..GARAY SMALL LETTER OLD NA 10E80..10EA9 ; ID_Start # Lo [42] YEZIDI LETTER ELIF..YEZIDI LETTER ET 10EB0..10EB1 ; ID_Start # Lo [2] YEZIDI LETTER LAM WITH DOT ABOVE..YEZIDI LETTER YOT WITH CIRCUMFLEX ABOVE +10EC2..10EC4 ; ID_Start # Lo [3] ARABIC LETTER DAL WITH TWO DOTS VERTICALLY BELOW..ARABIC LETTER KAF WITH TWO DOTS VERTICALLY BELOW 10F00..10F1C ; ID_Start # Lo [29] OLD SOGDIAN LETTER ALEPH..OLD SOGDIAN LETTER FINAL TAW WITH VERTICAL TAIL 10F27 ; ID_Start # Lo OLD SOGDIAN LIGATURE AYIN-DALETH 10F30..10F45 ; ID_Start # Lo [22] SOGDIAN LETTER ALEPH..SOGDIAN INDEPENDENT SHIN @@ -6679,6 +6767,13 @@ FFDA..FFDC ; ID_Start # Lo [3] HALFWIDTH HANGUL LETTER EU..HALFWIDTH HANGUL 1133D ; ID_Start # Lo GRANTHA SIGN AVAGRAHA 11350 ; ID_Start # Lo GRANTHA OM 1135D..11361 ; ID_Start # Lo [5] GRANTHA SIGN PLUTA..GRANTHA LETTER VOCALIC LL +11380..11389 ; ID_Start # Lo [10] TULU-TIGALARI LETTER A..TULU-TIGALARI LETTER VOCALIC LL +1138B ; ID_Start # Lo TULU-TIGALARI LETTER EE +1138E ; ID_Start # Lo TULU-TIGALARI LETTER AI +11390..113B5 ; ID_Start # Lo [38] TULU-TIGALARI LETTER OO..TULU-TIGALARI LETTER LLLA +113B7 ; ID_Start # Lo TULU-TIGALARI SIGN AVAGRAHA +113D1 ; ID_Start # Lo TULU-TIGALARI REPHA +113D3 ; ID_Start # Lo TULU-TIGALARI SIGN PLUTA 11400..11434 ; ID_Start # Lo [53] NEWA LETTER A..NEWA LETTER HA 11447..1144A ; ID_Start # Lo [4] NEWA SIGN AVAGRAHA..NEWA SIDDHI 1145F..11461 ; ID_Start # Lo [3] NEWA LETTER VEDIC ANUSVARA..NEWA SIGN UPADHMANIYA @@ -6713,6 +6808,7 @@ FFDA..FFDC ; ID_Start # Lo [3] HALFWIDTH HANGUL LETTER EU..HALFWIDTH HANGUL 11A5C..11A89 ; ID_Start # Lo [46] SOYOMBO LETTER KA..SOYOMBO CLUSTER-INITIAL LETTER SA 11A9D ; ID_Start # Lo SOYOMBO MARK PLUTA 11AB0..11AF8 ; ID_Start # Lo [73] CANADIAN SYLLABICS NATTILIK HI..PAU CIN HAU GLOTTAL STOP FINAL +11BC0..11BE0 ; ID_Start # Lo [33] SUNUWAR LETTER DEVI..SUNUWAR LETTER KLOKO 11C00..11C08 ; ID_Start # Lo [9] BHAIKSUKI LETTER A..BHAIKSUKI LETTER VOCALIC L 11C0A..11C2E ; ID_Start # Lo [37] BHAIKSUKI LETTER E..BHAIKSUKI LETTER HA 11C40 ; ID_Start # Lo BHAIKSUKI SIGN AVAGRAHA @@ -6736,7 +6832,9 @@ FFDA..FFDC ; ID_Start # Lo [3] HALFWIDTH HANGUL LETTER EU..HALFWIDTH HANGUL 12F90..12FF0 ; ID_Start # Lo [97] CYPRO-MINOAN SIGN CM001..CYPRO-MINOAN SIGN CM114 13000..1342F ; ID_Start # Lo [1072] EGYPTIAN HIEROGLYPH A001..EGYPTIAN HIEROGLYPH V011D 13441..13446 ; ID_Start # Lo [6] EGYPTIAN HIEROGLYPH FULL BLANK..EGYPTIAN HIEROGLYPH WIDE LOST SIGN +13460..143FA ; ID_Start # Lo [3995] EGYPTIAN HIEROGLYPH-13460..EGYPTIAN HIEROGLYPH-143FA 14400..14646 ; ID_Start # Lo [583] ANATOLIAN HIEROGLYPH A001..ANATOLIAN HIEROGLYPH A530 +16100..1611D ; ID_Start # Lo [30] GURUNG KHEMA LETTER A..GURUNG KHEMA LETTER SA 16800..16A38 ; ID_Start # Lo [569] BAMUM LETTER PHASE-A NGKUE MFON..BAMUM LETTER PHASE-F VUEQ 16A40..16A5E ; ID_Start # Lo [31] MRO LETTER TA..MRO LETTER TEK 16A70..16ABE ; ID_Start # Lo [79] TANGSA LETTER OZ..TANGSA LETTER ZA @@ -6745,6 +6843,9 @@ FFDA..FFDC ; ID_Start # Lo [3] HALFWIDTH HANGUL LETTER EU..HALFWIDTH HANGUL 16B40..16B43 ; ID_Start # Lm [4] PAHAWH HMONG SIGN VOS SEEV..PAHAWH HMONG SIGN IB YAM 16B63..16B77 ; ID_Start # Lo [21] PAHAWH HMONG SIGN VOS LUB..PAHAWH HMONG SIGN CIM NRES TOS 16B7D..16B8F ; ID_Start # Lo [19] PAHAWH HMONG CLAN SIGN TSHEEJ..PAHAWH HMONG CLAN SIGN VWJ +16D40..16D42 ; ID_Start # Lm [3] KIRAT RAI SIGN ANUSVARA..KIRAT RAI SIGN VISARGA +16D43..16D6A ; ID_Start # Lo [40] KIRAT RAI LETTER A..KIRAT RAI VOWEL SIGN AU +16D6B..16D6C ; ID_Start # Lm [2] KIRAT RAI SIGN VIRAMA..KIRAT RAI SIGN SAAT 16E40..16E7F ; ID_Start # L& [64] MEDEFAIDRIN CAPITAL LETTER M..MEDEFAIDRIN SMALL LETTER Y 16F00..16F4A ; ID_Start # Lo [75] MIAO LETTER PA..MIAO LETTER RTE 16F50 ; ID_Start # Lo MIAO LETTER NASALIZATION @@ -6753,7 +6854,7 @@ FFDA..FFDC ; ID_Start # Lo [3] HALFWIDTH HANGUL LETTER EU..HALFWIDTH HANGUL 16FE3 ; ID_Start # Lm OLD CHINESE ITERATION MARK 17000..187F7 ; ID_Start # Lo [6136] TANGUT IDEOGRAPH-17000..TANGUT IDEOGRAPH-187F7 18800..18CD5 ; ID_Start # Lo [1238] TANGUT COMPONENT-001..KHITAN SMALL SCRIPT CHARACTER-18CD5 -18D00..18D08 ; ID_Start # Lo [9] TANGUT IDEOGRAPH-18D00..TANGUT IDEOGRAPH-18D08 +18CFF..18D08 ; ID_Start # Lo [10] KHITAN SMALL SCRIPT CHARACTER-18CFF..TANGUT IDEOGRAPH-18D08 1AFF0..1AFF3 ; ID_Start # Lm [4] KATAKANA LETTER MINNAN TONE-2..KATAKANA LETTER MINNAN TONE-5 1AFF5..1AFFB ; ID_Start # Lm [7] KATAKANA LETTER MINNAN TONE-7..KATAKANA LETTER MINNAN NASALIZED TONE-5 1AFFD..1AFFE ; ID_Start # Lm [2] KATAKANA LETTER MINNAN NASALIZED TONE-7..KATAKANA LETTER MINNAN NASALIZED TONE-8 @@ -6809,6 +6910,8 @@ FFDA..FFDC ; ID_Start # Lo [3] HALFWIDTH HANGUL LETTER EU..HALFWIDTH HANGUL 1E2C0..1E2EB ; ID_Start # Lo [44] WANCHO LETTER AA..WANCHO LETTER YIH 1E4D0..1E4EA ; ID_Start # Lo [27] NAG MUNDARI LETTER O..NAG MUNDARI LETTER ELL 1E4EB ; ID_Start # Lm NAG MUNDARI SIGN OJOD +1E5D0..1E5ED ; ID_Start # Lo [30] OL ONAL LETTER O..OL ONAL LETTER EG +1E5F0 ; ID_Start # Lo OL ONAL SIGN HODDOND 1E7E0..1E7E6 ; ID_Start # Lo [7] ETHIOPIC SYLLABLE HHYA..ETHIOPIC SYLLABLE HHYO 1E7E8..1E7EB ; ID_Start # Lo [4] ETHIOPIC SYLLABLE GURAGE HHWA..ETHIOPIC SYLLABLE HHWE 1E7ED..1E7EE ; ID_Start # Lo [2] ETHIOPIC SYLLABLE GURAGE MWI..ETHIOPIC SYLLABLE GURAGE MWEE @@ -6859,7 +6962,7 @@ FFDA..FFDC ; ID_Start # Lo [3] HALFWIDTH HANGUL LETTER EU..HALFWIDTH HANGUL 30000..3134A ; ID_Start # Lo [4939] CJK UNIFIED IDEOGRAPH-30000..CJK UNIFIED IDEOGRAPH-3134A 31350..323AF ; ID_Start # Lo [4192] CJK UNIFIED IDEOGRAPH-31350..CJK UNIFIED IDEOGRAPH-323AF -# Total code points: 136967 +# Total code points: 141269 # ================================================ @@ -6966,7 +7069,7 @@ FFDA..FFDC ; ID_Start # Lo [3] HALFWIDTH HANGUL LETTER EU..HALFWIDTH HANGUL 0860..086A ; ID_Continue # Lo [11] SYRIAC LETTER MALAYALAM NGA..SYRIAC LETTER MALAYALAM SSA 0870..0887 ; ID_Continue # Lo [24] ARABIC LETTER ALEF WITH ATTACHED FATHA..ARABIC BASELINE ROUND DOT 0889..088E ; ID_Continue # Lo [6] ARABIC LETTER NOON WITH INVERTED SMALL V..ARABIC VERTICAL TAIL -0898..089F ; ID_Continue # Mn [8] ARABIC SMALL HIGH WORD AL-JUZ..ARABIC HALF MADDA OVER MADDA +0897..089F ; ID_Continue # Mn [9] ARABIC PEPET..ARABIC HALF MADDA OVER MADDA 08A0..08C8 ; ID_Continue # Lo [41] ARABIC LETTER BEH WITH SMALL V BELOW..ARABIC LETTER GRAF 08C9 ; ID_Continue # Lm ARABIC SMALL FARSI YEH 08CA..08E1 ; ID_Continue # Mn [24] ARABIC SMALL HIGH FARSI YEH..ARABIC SMALL HIGH SIGN SAFHA @@ -7399,7 +7502,7 @@ FFDA..FFDC ; ID_Start # Lo [3] HALFWIDTH HANGUL LETTER EU..HALFWIDTH HANGUL 1C50..1C59 ; ID_Continue # Nd [10] OL CHIKI DIGIT ZERO..OL CHIKI DIGIT NINE 1C5A..1C77 ; ID_Continue # Lo [30] OL CHIKI LETTER LA..OL CHIKI LETTER OH 1C78..1C7D ; ID_Continue # Lm [6] OL CHIKI MU TTUDDAG..OL CHIKI AHAD -1C80..1C88 ; ID_Continue # L& [9] CYRILLIC SMALL LETTER ROUNDED VE..CYRILLIC SMALL LETTER UNBLENDED UK +1C80..1C8A ; ID_Continue # L& [11] CYRILLIC SMALL LETTER ROUNDED VE..CYRILLIC SMALL LETTER TJE 1C90..1CBA ; ID_Continue # L& [43] GEORGIAN MTAVRULI CAPITAL LETTER AN..GEORGIAN MTAVRULI CAPITAL LETTER AIN 1CBD..1CBF ; ID_Continue # L& [3] GEORGIAN MTAVRULI CAPITAL LETTER AEN..GEORGIAN MTAVRULI CAPITAL LETTER LABIAL SIGN 1CD0..1CD2 ; ID_Continue # Mn [3] VEDIC TONE KARSHANA..VEDIC TONE PRENKHA @@ -7543,10 +7646,10 @@ A771..A787 ; ID_Continue # L& [23] LATIN SMALL LETTER DUM..LATIN SMALL LETTE A788 ; ID_Continue # Lm MODIFIER LETTER LOW CIRCUMFLEX ACCENT A78B..A78E ; ID_Continue # L& [4] LATIN CAPITAL LETTER SALTILLO..LATIN SMALL LETTER L WITH RETROFLEX HOOK AND BELT A78F ; ID_Continue # Lo LATIN LETTER SINOLOGICAL DOT -A790..A7CA ; ID_Continue # L& [59] LATIN CAPITAL LETTER N WITH DESCENDER..LATIN SMALL LETTER S WITH SHORT STROKE OVERLAY +A790..A7CD ; ID_Continue # L& [62] LATIN CAPITAL LETTER N WITH DESCENDER..LATIN SMALL LETTER S WITH DIAGONAL STROKE A7D0..A7D1 ; ID_Continue # L& [2] LATIN CAPITAL LETTER CLOSED INSULAR G..LATIN SMALL LETTER CLOSED INSULAR G A7D3 ; ID_Continue # L& LATIN SMALL LETTER DOUBLE THORN -A7D5..A7D9 ; ID_Continue # L& [5] LATIN SMALL LETTER DOUBLE WYNN..LATIN SMALL LETTER SIGMOID S +A7D5..A7DC ; ID_Continue # L& [8] LATIN SMALL LETTER DOUBLE WYNN..LATIN CAPITAL LETTER LAMBDA WITH STROKE A7F2..A7F4 ; ID_Continue # Lm [3] MODIFIER LETTER CAPITAL C..MODIFIER LETTER CAPITAL Q A7F5..A7F6 ; ID_Continue # L& [2] LATIN CAPITAL LETTER REVERSED HALF H..LATIN SMALL LETTER REVERSED HALF H A7F7 ; ID_Continue # Lo LATIN EPIGRAPHIC LETTER SIDEWAYS I @@ -7735,6 +7838,7 @@ FFDA..FFDC ; ID_Continue # Lo [3] HALFWIDTH HANGUL LETTER EU..HALFWIDTH HAN 105A3..105B1 ; ID_Continue # L& [15] VITHKUQI SMALL LETTER HA..VITHKUQI SMALL LETTER RE 105B3..105B9 ; ID_Continue # L& [7] VITHKUQI SMALL LETTER SE..VITHKUQI SMALL LETTER XE 105BB..105BC ; ID_Continue # L& [2] VITHKUQI SMALL LETTER Y..VITHKUQI SMALL LETTER ZE +105C0..105F3 ; ID_Continue # Lo [52] TODHRI LETTER A..TODHRI LETTER OO 10600..10736 ; ID_Continue # Lo [311] LINEAR A SIGN AB001..LINEAR A SIGN A664 10740..10755 ; ID_Continue # Lo [22] LINEAR A SIGN A701 A..LINEAR A SIGN A732 JE 10760..10767 ; ID_Continue # Lo [8] LINEAR A SIGN A800..LINEAR A SIGN A807 @@ -7779,10 +7883,19 @@ FFDA..FFDC ; ID_Continue # Lo [3] HALFWIDTH HANGUL LETTER EU..HALFWIDTH HAN 10D00..10D23 ; ID_Continue # Lo [36] HANIFI ROHINGYA LETTER A..HANIFI ROHINGYA MARK NA KHONNA 10D24..10D27 ; ID_Continue # Mn [4] HANIFI ROHINGYA SIGN HARBAHAY..HANIFI ROHINGYA SIGN TASSI 10D30..10D39 ; ID_Continue # Nd [10] HANIFI ROHINGYA DIGIT ZERO..HANIFI ROHINGYA DIGIT NINE +10D40..10D49 ; ID_Continue # Nd [10] GARAY DIGIT ZERO..GARAY DIGIT NINE +10D4A..10D4D ; ID_Continue # Lo [4] GARAY VOWEL SIGN A..GARAY VOWEL SIGN EE +10D4E ; ID_Continue # Lm GARAY VOWEL LENGTH MARK +10D4F ; ID_Continue # Lo GARAY SUKUN +10D50..10D65 ; ID_Continue # L& [22] GARAY CAPITAL LETTER A..GARAY CAPITAL LETTER OLD NA +10D69..10D6D ; ID_Continue # Mn [5] GARAY VOWEL SIGN E..GARAY CONSONANT NASALIZATION MARK +10D6F ; ID_Continue # Lm GARAY REDUPLICATION MARK +10D70..10D85 ; ID_Continue # L& [22] GARAY SMALL LETTER A..GARAY SMALL LETTER OLD NA 10E80..10EA9 ; ID_Continue # Lo [42] YEZIDI LETTER ELIF..YEZIDI LETTER ET 10EAB..10EAC ; ID_Continue # Mn [2] YEZIDI COMBINING HAMZA MARK..YEZIDI COMBINING MADDA MARK 10EB0..10EB1 ; ID_Continue # Lo [2] YEZIDI LETTER LAM WITH DOT ABOVE..YEZIDI LETTER YOT WITH CIRCUMFLEX ABOVE -10EFD..10EFF ; ID_Continue # Mn [3] ARABIC SMALL LOW WORD SAKTA..ARABIC SMALL LOW WORD MADDA +10EC2..10EC4 ; ID_Continue # Lo [3] ARABIC LETTER DAL WITH TWO DOTS VERTICALLY BELOW..ARABIC LETTER KAF WITH TWO DOTS VERTICALLY BELOW +10EFC..10EFF ; ID_Continue # Mn [4] ARABIC COMBINING ALEF OVERLAY..ARABIC SMALL LOW WORD MADDA 10F00..10F1C ; ID_Continue # Lo [29] OLD SOGDIAN LETTER ALEPH..OLD SOGDIAN LETTER FINAL TAW WITH VERTICAL TAIL 10F27 ; ID_Continue # Lo OLD SOGDIAN LIGATURE AYIN-DALETH 10F30..10F45 ; ID_Continue # Lo [22] SOGDIAN LETTER ALEPH..SOGDIAN INDEPENDENT SHIN @@ -7878,6 +7991,24 @@ FFDA..FFDC ; ID_Continue # Lo [3] HALFWIDTH HANGUL LETTER EU..HALFWIDTH HAN 11362..11363 ; ID_Continue # Mc [2] GRANTHA VOWEL SIGN VOCALIC L..GRANTHA VOWEL SIGN VOCALIC LL 11366..1136C ; ID_Continue # Mn [7] COMBINING GRANTHA DIGIT ZERO..COMBINING GRANTHA DIGIT SIX 11370..11374 ; ID_Continue # Mn [5] COMBINING GRANTHA LETTER A..COMBINING GRANTHA LETTER PA +11380..11389 ; ID_Continue # Lo [10] TULU-TIGALARI LETTER A..TULU-TIGALARI LETTER VOCALIC LL +1138B ; ID_Continue # Lo TULU-TIGALARI LETTER EE +1138E ; ID_Continue # Lo TULU-TIGALARI LETTER AI +11390..113B5 ; ID_Continue # Lo [38] TULU-TIGALARI LETTER OO..TULU-TIGALARI LETTER LLLA +113B7 ; ID_Continue # Lo TULU-TIGALARI SIGN AVAGRAHA +113B8..113BA ; ID_Continue # Mc [3] TULU-TIGALARI VOWEL SIGN AA..TULU-TIGALARI VOWEL SIGN II +113BB..113C0 ; ID_Continue # Mn [6] TULU-TIGALARI VOWEL SIGN U..TULU-TIGALARI VOWEL SIGN VOCALIC LL +113C2 ; ID_Continue # Mc TULU-TIGALARI VOWEL SIGN EE +113C5 ; ID_Continue # Mc TULU-TIGALARI VOWEL SIGN AI +113C7..113CA ; ID_Continue # Mc [4] TULU-TIGALARI VOWEL SIGN OO..TULU-TIGALARI SIGN CANDRA ANUNASIKA +113CC..113CD ; ID_Continue # Mc [2] TULU-TIGALARI SIGN ANUSVARA..TULU-TIGALARI SIGN VISARGA +113CE ; ID_Continue # Mn TULU-TIGALARI SIGN VIRAMA +113CF ; ID_Continue # Mc TULU-TIGALARI SIGN LOOPED VIRAMA +113D0 ; ID_Continue # Mn TULU-TIGALARI CONJOINER +113D1 ; ID_Continue # Lo TULU-TIGALARI REPHA +113D2 ; ID_Continue # Mn TULU-TIGALARI GEMINATION MARK +113D3 ; ID_Continue # Lo TULU-TIGALARI SIGN PLUTA +113E1..113E2 ; ID_Continue # Mn [2] TULU-TIGALARI VEDIC TONE SVARITA..TULU-TIGALARI VEDIC TONE ANUDATTA 11400..11434 ; ID_Continue # Lo [53] NEWA LETTER A..NEWA LETTER HA 11435..11437 ; ID_Continue # Mc [3] NEWA VOWEL SIGN AA..NEWA VOWEL SIGN II 11438..1143F ; ID_Continue # Mn [8] NEWA VOWEL SIGN U..NEWA VOWEL SIGN AI @@ -7929,8 +8060,11 @@ FFDA..FFDC ; ID_Continue # Lo [3] HALFWIDTH HANGUL LETTER EU..HALFWIDTH HAN 116B7 ; ID_Continue # Mn TAKRI SIGN NUKTA 116B8 ; ID_Continue # Lo TAKRI LETTER ARCHAIC KHA 116C0..116C9 ; ID_Continue # Nd [10] TAKRI DIGIT ZERO..TAKRI DIGIT NINE +116D0..116E3 ; ID_Continue # Nd [20] MYANMAR PAO DIGIT ZERO..MYANMAR EASTERN PWO KAREN DIGIT NINE 11700..1171A ; ID_Continue # Lo [27] AHOM LETTER KA..AHOM LETTER ALTERNATE BA -1171D..1171F ; ID_Continue # Mn [3] AHOM CONSONANT SIGN MEDIAL LA..AHOM CONSONANT SIGN MEDIAL LIGATING RA +1171D ; ID_Continue # Mn AHOM CONSONANT SIGN MEDIAL LA +1171E ; ID_Continue # Mc AHOM CONSONANT SIGN MEDIAL RA +1171F ; ID_Continue # Mn AHOM CONSONANT SIGN MEDIAL LIGATING RA 11720..11721 ; ID_Continue # Mc [2] AHOM VOWEL SIGN A..AHOM VOWEL SIGN AA 11722..11725 ; ID_Continue # Mn [4] AHOM VOWEL SIGN I..AHOM VOWEL SIGN UU 11726 ; ID_Continue # Mc AHOM VOWEL SIGN E @@ -7988,6 +8122,8 @@ FFDA..FFDC ; ID_Continue # Lo [3] HALFWIDTH HANGUL LETTER EU..HALFWIDTH HAN 11A98..11A99 ; ID_Continue # Mn [2] SOYOMBO GEMINATION MARK..SOYOMBO SUBJOINER 11A9D ; ID_Continue # Lo SOYOMBO MARK PLUTA 11AB0..11AF8 ; ID_Continue # Lo [73] CANADIAN SYLLABICS NATTILIK HI..PAU CIN HAU GLOTTAL STOP FINAL +11BC0..11BE0 ; ID_Continue # Lo [33] SUNUWAR LETTER DEVI..SUNUWAR LETTER KLOKO +11BF0..11BF9 ; ID_Continue # Nd [10] SUNUWAR DIGIT ZERO..SUNUWAR DIGIT NINE 11C00..11C08 ; ID_Continue # Lo [9] BHAIKSUKI LETTER A..BHAIKSUKI LETTER VOCALIC L 11C0A..11C2E ; ID_Continue # Lo [37] BHAIKSUKI LETTER E..BHAIKSUKI LETTER HA 11C2F ; ID_Continue # Mc BHAIKSUKI VOWEL SIGN AA @@ -8041,6 +8177,7 @@ FFDA..FFDC ; ID_Continue # Lo [3] HALFWIDTH HANGUL LETTER EU..HALFWIDTH HAN 11F41 ; ID_Continue # Mc KAWI SIGN KILLER 11F42 ; ID_Continue # Mn KAWI CONJOINER 11F50..11F59 ; ID_Continue # Nd [10] KAWI DIGIT ZERO..KAWI DIGIT NINE +11F5A ; ID_Continue # Mn KAWI SIGN NUKTA 11FB0 ; ID_Continue # Lo LISU LETTER YHA 12000..12399 ; ID_Continue # Lo [922] CUNEIFORM SIGN A..CUNEIFORM SIGN U U 12400..1246E ; ID_Continue # Nl [111] CUNEIFORM NUMERIC SIGN TWO ASH..CUNEIFORM NUMERIC SIGN NINE U VARIANT FORM @@ -8050,7 +8187,13 @@ FFDA..FFDC ; ID_Continue # Lo [3] HALFWIDTH HANGUL LETTER EU..HALFWIDTH HAN 13440 ; ID_Continue # Mn EGYPTIAN HIEROGLYPH MIRROR HORIZONTALLY 13441..13446 ; ID_Continue # Lo [6] EGYPTIAN HIEROGLYPH FULL BLANK..EGYPTIAN HIEROGLYPH WIDE LOST SIGN 13447..13455 ; ID_Continue # Mn [15] EGYPTIAN HIEROGLYPH MODIFIER DAMAGED AT TOP START..EGYPTIAN HIEROGLYPH MODIFIER DAMAGED +13460..143FA ; ID_Continue # Lo [3995] EGYPTIAN HIEROGLYPH-13460..EGYPTIAN HIEROGLYPH-143FA 14400..14646 ; ID_Continue # Lo [583] ANATOLIAN HIEROGLYPH A001..ANATOLIAN HIEROGLYPH A530 +16100..1611D ; ID_Continue # Lo [30] GURUNG KHEMA LETTER A..GURUNG KHEMA LETTER SA +1611E..16129 ; ID_Continue # Mn [12] GURUNG KHEMA VOWEL SIGN AA..GURUNG KHEMA VOWEL LENGTH MARK +1612A..1612C ; ID_Continue # Mc [3] GURUNG KHEMA CONSONANT SIGN MEDIAL YA..GURUNG KHEMA CONSONANT SIGN MEDIAL HA +1612D..1612F ; ID_Continue # Mn [3] GURUNG KHEMA SIGN ANUSVARA..GURUNG KHEMA SIGN THOLHOMA +16130..16139 ; ID_Continue # Nd [10] GURUNG KHEMA DIGIT ZERO..GURUNG KHEMA DIGIT NINE 16800..16A38 ; ID_Continue # Lo [569] BAMUM LETTER PHASE-A NGKUE MFON..BAMUM LETTER PHASE-F VUEQ 16A40..16A5E ; ID_Continue # Lo [31] MRO LETTER TA..MRO LETTER TEK 16A60..16A69 ; ID_Continue # Nd [10] MRO DIGIT ZERO..MRO DIGIT NINE @@ -8064,6 +8207,10 @@ FFDA..FFDC ; ID_Continue # Lo [3] HALFWIDTH HANGUL LETTER EU..HALFWIDTH HAN 16B50..16B59 ; ID_Continue # Nd [10] PAHAWH HMONG DIGIT ZERO..PAHAWH HMONG DIGIT NINE 16B63..16B77 ; ID_Continue # Lo [21] PAHAWH HMONG SIGN VOS LUB..PAHAWH HMONG SIGN CIM NRES TOS 16B7D..16B8F ; ID_Continue # Lo [19] PAHAWH HMONG CLAN SIGN TSHEEJ..PAHAWH HMONG CLAN SIGN VWJ +16D40..16D42 ; ID_Continue # Lm [3] KIRAT RAI SIGN ANUSVARA..KIRAT RAI SIGN VISARGA +16D43..16D6A ; ID_Continue # Lo [40] KIRAT RAI LETTER A..KIRAT RAI VOWEL SIGN AU +16D6B..16D6C ; ID_Continue # Lm [2] KIRAT RAI SIGN VIRAMA..KIRAT RAI SIGN SAAT +16D70..16D79 ; ID_Continue # Nd [10] KIRAT RAI DIGIT ZERO..KIRAT RAI DIGIT NINE 16E40..16E7F ; ID_Continue # L& [64] MEDEFAIDRIN CAPITAL LETTER M..MEDEFAIDRIN SMALL LETTER Y 16F00..16F4A ; ID_Continue # Lo [75] MIAO LETTER PA..MIAO LETTER RTE 16F4F ; ID_Continue # Mn MIAO SIGN CONSONANT MODIFIER BAR @@ -8077,7 +8224,7 @@ FFDA..FFDC ; ID_Continue # Lo [3] HALFWIDTH HANGUL LETTER EU..HALFWIDTH HAN 16FF0..16FF1 ; ID_Continue # Mc [2] VIETNAMESE ALTERNATE READING MARK CA..VIETNAMESE ALTERNATE READING MARK NHAY 17000..187F7 ; ID_Continue # Lo [6136] TANGUT IDEOGRAPH-17000..TANGUT IDEOGRAPH-187F7 18800..18CD5 ; ID_Continue # Lo [1238] TANGUT COMPONENT-001..KHITAN SMALL SCRIPT CHARACTER-18CD5 -18D00..18D08 ; ID_Continue # Lo [9] TANGUT IDEOGRAPH-18D00..TANGUT IDEOGRAPH-18D08 +18CFF..18D08 ; ID_Continue # Lo [10] KHITAN SMALL SCRIPT CHARACTER-18CFF..TANGUT IDEOGRAPH-18D08 1AFF0..1AFF3 ; ID_Continue # Lm [4] KATAKANA LETTER MINNAN TONE-2..KATAKANA LETTER MINNAN TONE-5 1AFF5..1AFFB ; ID_Continue # Lm [7] KATAKANA LETTER MINNAN TONE-7..KATAKANA LETTER MINNAN NASALIZED TONE-5 1AFFD..1AFFE ; ID_Continue # Lm [2] KATAKANA LETTER MINNAN NASALIZED TONE-7..KATAKANA LETTER MINNAN NASALIZED TONE-8 @@ -8092,6 +8239,7 @@ FFDA..FFDC ; ID_Continue # Lo [3] HALFWIDTH HANGUL LETTER EU..HALFWIDTH HAN 1BC80..1BC88 ; ID_Continue # Lo [9] DUPLOYAN AFFIX HIGH ACUTE..DUPLOYAN AFFIX HIGH VERTICAL 1BC90..1BC99 ; ID_Continue # Lo [10] DUPLOYAN AFFIX LOW ACUTE..DUPLOYAN AFFIX LOW ARROW 1BC9D..1BC9E ; ID_Continue # Mn [2] DUPLOYAN THICK LETTER SELECTOR..DUPLOYAN DOUBLE MARK +1CCF0..1CCF9 ; ID_Continue # Nd [10] OUTLINED DIGIT ZERO..OUTLINED DIGIT NINE 1CF00..1CF2D ; ID_Continue # Mn [46] ZNAMENNY COMBINING MARK GORAZDO NIZKO S KRYZHEM ON LEFT..ZNAMENNY COMBINING MARK KRYZH ON LEFT 1CF30..1CF46 ; ID_Continue # Mn [23] ZNAMENNY COMBINING TONAL RANGE MARK MRACHNO..ZNAMENNY PRIZNAK MODIFIER ROG 1D165..1D166 ; ID_Continue # Mc [2] MUSICAL SYMBOL COMBINING STEM..MUSICAL SYMBOL COMBINING SPRECHGESANG STEM @@ -8163,6 +8311,10 @@ FFDA..FFDC ; ID_Continue # Lo [3] HALFWIDTH HANGUL LETTER EU..HALFWIDTH HAN 1E4EB ; ID_Continue # Lm NAG MUNDARI SIGN OJOD 1E4EC..1E4EF ; ID_Continue # Mn [4] NAG MUNDARI SIGN MUHOR..NAG MUNDARI SIGN SUTUH 1E4F0..1E4F9 ; ID_Continue # Nd [10] NAG MUNDARI DIGIT ZERO..NAG MUNDARI DIGIT NINE +1E5D0..1E5ED ; ID_Continue # Lo [30] OL ONAL LETTER O..OL ONAL LETTER EG +1E5EE..1E5EF ; ID_Continue # Mn [2] OL ONAL SIGN MU..OL ONAL SIGN IKIR +1E5F0 ; ID_Continue # Lo OL ONAL SIGN HODDOND +1E5F1..1E5FA ; ID_Continue # Nd [10] OL ONAL DIGIT ZERO..OL ONAL DIGIT NINE 1E7E0..1E7E6 ; ID_Continue # Lo [7] ETHIOPIC SYLLABLE HHYA..ETHIOPIC SYLLABLE HHYO 1E7E8..1E7EB ; ID_Continue # Lo [4] ETHIOPIC SYLLABLE GURAGE HHWA..ETHIOPIC SYLLABLE HHWE 1E7ED..1E7EE ; ID_Continue # Lo [2] ETHIOPIC SYLLABLE GURAGE MWI..ETHIOPIC SYLLABLE GURAGE MWEE @@ -8218,7 +8370,7 @@ FFDA..FFDC ; ID_Continue # Lo [3] HALFWIDTH HANGUL LETTER EU..HALFWIDTH HAN 31350..323AF ; ID_Continue # Lo [4192] CJK UNIFIED IDEOGRAPH-31350..CJK UNIFIED IDEOGRAPH-323AF E0100..E01EF ; ID_Continue # Mn [240] VARIATION SELECTOR-17..VARIATION SELECTOR-256 -# Total code points: 140108 +# Total code points: 144541 # ================================================ @@ -8474,7 +8626,7 @@ E0100..E01EF ; ID_Continue # Mn [240] VARIATION SELECTOR-17..VARIATION SELECTOR 1C4D..1C4F ; XID_Start # Lo [3] LEPCHA LETTER TTA..LEPCHA LETTER DDA 1C5A..1C77 ; XID_Start # Lo [30] OL CHIKI LETTER LA..OL CHIKI LETTER OH 1C78..1C7D ; XID_Start # Lm [6] OL CHIKI MU TTUDDAG..OL CHIKI AHAD -1C80..1C88 ; XID_Start # L& [9] CYRILLIC SMALL LETTER ROUNDED VE..CYRILLIC SMALL LETTER UNBLENDED UK +1C80..1C8A ; XID_Start # L& [11] CYRILLIC SMALL LETTER ROUNDED VE..CYRILLIC SMALL LETTER TJE 1C90..1CBA ; XID_Start # L& [43] GEORGIAN MTAVRULI CAPITAL LETTER AN..GEORGIAN MTAVRULI CAPITAL LETTER AIN 1CBD..1CBF ; XID_Start # L& [3] GEORGIAN MTAVRULI CAPITAL LETTER AEN..GEORGIAN MTAVRULI CAPITAL LETTER LABIAL SIGN 1CE9..1CEC ; XID_Start # Lo [4] VEDIC SIGN ANUSVARA ANTARGOMUKHA..VEDIC SIGN ANUSVARA VAMAGOMUKHA WITH TAIL @@ -8590,10 +8742,10 @@ A771..A787 ; XID_Start # L& [23] LATIN SMALL LETTER DUM..LATIN SMALL LETTER A788 ; XID_Start # Lm MODIFIER LETTER LOW CIRCUMFLEX ACCENT A78B..A78E ; XID_Start # L& [4] LATIN CAPITAL LETTER SALTILLO..LATIN SMALL LETTER L WITH RETROFLEX HOOK AND BELT A78F ; XID_Start # Lo LATIN LETTER SINOLOGICAL DOT -A790..A7CA ; XID_Start # L& [59] LATIN CAPITAL LETTER N WITH DESCENDER..LATIN SMALL LETTER S WITH SHORT STROKE OVERLAY +A790..A7CD ; XID_Start # L& [62] LATIN CAPITAL LETTER N WITH DESCENDER..LATIN SMALL LETTER S WITH DIAGONAL STROKE A7D0..A7D1 ; XID_Start # L& [2] LATIN CAPITAL LETTER CLOSED INSULAR G..LATIN SMALL LETTER CLOSED INSULAR G A7D3 ; XID_Start # L& LATIN SMALL LETTER DOUBLE THORN -A7D5..A7D9 ; XID_Start # L& [5] LATIN SMALL LETTER DOUBLE WYNN..LATIN SMALL LETTER SIGMOID S +A7D5..A7DC ; XID_Start # L& [8] LATIN SMALL LETTER DOUBLE WYNN..LATIN CAPITAL LETTER LAMBDA WITH STROKE A7F2..A7F4 ; XID_Start # Lm [3] MODIFIER LETTER CAPITAL C..MODIFIER LETTER CAPITAL Q A7F5..A7F6 ; XID_Start # L& [2] LATIN CAPITAL LETTER REVERSED HALF H..LATIN SMALL LETTER REVERSED HALF H A7F7 ; XID_Start # Lo LATIN EPIGRAPHIC LETTER SIDEWAYS I @@ -8717,6 +8869,7 @@ FFDA..FFDC ; XID_Start # Lo [3] HALFWIDTH HANGUL LETTER EU..HALFWIDTH HANGU 105A3..105B1 ; XID_Start # L& [15] VITHKUQI SMALL LETTER HA..VITHKUQI SMALL LETTER RE 105B3..105B9 ; XID_Start # L& [7] VITHKUQI SMALL LETTER SE..VITHKUQI SMALL LETTER XE 105BB..105BC ; XID_Start # L& [2] VITHKUQI SMALL LETTER Y..VITHKUQI SMALL LETTER ZE +105C0..105F3 ; XID_Start # Lo [52] TODHRI LETTER A..TODHRI LETTER OO 10600..10736 ; XID_Start # Lo [311] LINEAR A SIGN AB001..LINEAR A SIGN A664 10740..10755 ; XID_Start # Lo [22] LINEAR A SIGN A701 A..LINEAR A SIGN A732 JE 10760..10767 ; XID_Start # Lo [8] LINEAR A SIGN A800..LINEAR A SIGN A807 @@ -8753,8 +8906,15 @@ FFDA..FFDC ; XID_Start # Lo [3] HALFWIDTH HANGUL LETTER EU..HALFWIDTH HANGU 10C80..10CB2 ; XID_Start # L& [51] OLD HUNGARIAN CAPITAL LETTER A..OLD HUNGARIAN CAPITAL LETTER US 10CC0..10CF2 ; XID_Start # L& [51] OLD HUNGARIAN SMALL LETTER A..OLD HUNGARIAN SMALL LETTER US 10D00..10D23 ; XID_Start # Lo [36] HANIFI ROHINGYA LETTER A..HANIFI ROHINGYA MARK NA KHONNA +10D4A..10D4D ; XID_Start # Lo [4] GARAY VOWEL SIGN A..GARAY VOWEL SIGN EE +10D4E ; XID_Start # Lm GARAY VOWEL LENGTH MARK +10D4F ; XID_Start # Lo GARAY SUKUN +10D50..10D65 ; XID_Start # L& [22] GARAY CAPITAL LETTER A..GARAY CAPITAL LETTER OLD NA +10D6F ; XID_Start # Lm GARAY REDUPLICATION MARK +10D70..10D85 ; XID_Start # L& [22] GARAY SMALL LETTER A..GARAY SMALL LETTER OLD NA 10E80..10EA9 ; XID_Start # Lo [42] YEZIDI LETTER ELIF..YEZIDI LETTER ET 10EB0..10EB1 ; XID_Start # Lo [2] YEZIDI LETTER LAM WITH DOT ABOVE..YEZIDI LETTER YOT WITH CIRCUMFLEX ABOVE +10EC2..10EC4 ; XID_Start # Lo [3] ARABIC LETTER DAL WITH TWO DOTS VERTICALLY BELOW..ARABIC LETTER KAF WITH TWO DOTS VERTICALLY BELOW 10F00..10F1C ; XID_Start # Lo [29] OLD SOGDIAN LETTER ALEPH..OLD SOGDIAN LETTER FINAL TAW WITH VERTICAL TAIL 10F27 ; XID_Start # Lo OLD SOGDIAN LIGATURE AYIN-DALETH 10F30..10F45 ; XID_Start # Lo [22] SOGDIAN LETTER ALEPH..SOGDIAN INDEPENDENT SHIN @@ -8793,6 +8953,13 @@ FFDA..FFDC ; XID_Start # Lo [3] HALFWIDTH HANGUL LETTER EU..HALFWIDTH HANGU 1133D ; XID_Start # Lo GRANTHA SIGN AVAGRAHA 11350 ; XID_Start # Lo GRANTHA OM 1135D..11361 ; XID_Start # Lo [5] GRANTHA SIGN PLUTA..GRANTHA LETTER VOCALIC LL +11380..11389 ; XID_Start # Lo [10] TULU-TIGALARI LETTER A..TULU-TIGALARI LETTER VOCALIC LL +1138B ; XID_Start # Lo TULU-TIGALARI LETTER EE +1138E ; XID_Start # Lo TULU-TIGALARI LETTER AI +11390..113B5 ; XID_Start # Lo [38] TULU-TIGALARI LETTER OO..TULU-TIGALARI LETTER LLLA +113B7 ; XID_Start # Lo TULU-TIGALARI SIGN AVAGRAHA +113D1 ; XID_Start # Lo TULU-TIGALARI REPHA +113D3 ; XID_Start # Lo TULU-TIGALARI SIGN PLUTA 11400..11434 ; XID_Start # Lo [53] NEWA LETTER A..NEWA LETTER HA 11447..1144A ; XID_Start # Lo [4] NEWA SIGN AVAGRAHA..NEWA SIDDHI 1145F..11461 ; XID_Start # Lo [3] NEWA LETTER VEDIC ANUSVARA..NEWA SIGN UPADHMANIYA @@ -8827,6 +8994,7 @@ FFDA..FFDC ; XID_Start # Lo [3] HALFWIDTH HANGUL LETTER EU..HALFWIDTH HANGU 11A5C..11A89 ; XID_Start # Lo [46] SOYOMBO LETTER KA..SOYOMBO CLUSTER-INITIAL LETTER SA 11A9D ; XID_Start # Lo SOYOMBO MARK PLUTA 11AB0..11AF8 ; XID_Start # Lo [73] CANADIAN SYLLABICS NATTILIK HI..PAU CIN HAU GLOTTAL STOP FINAL +11BC0..11BE0 ; XID_Start # Lo [33] SUNUWAR LETTER DEVI..SUNUWAR LETTER KLOKO 11C00..11C08 ; XID_Start # Lo [9] BHAIKSUKI LETTER A..BHAIKSUKI LETTER VOCALIC L 11C0A..11C2E ; XID_Start # Lo [37] BHAIKSUKI LETTER E..BHAIKSUKI LETTER HA 11C40 ; XID_Start # Lo BHAIKSUKI SIGN AVAGRAHA @@ -8850,7 +9018,9 @@ FFDA..FFDC ; XID_Start # Lo [3] HALFWIDTH HANGUL LETTER EU..HALFWIDTH HANGU 12F90..12FF0 ; XID_Start # Lo [97] CYPRO-MINOAN SIGN CM001..CYPRO-MINOAN SIGN CM114 13000..1342F ; XID_Start # Lo [1072] EGYPTIAN HIEROGLYPH A001..EGYPTIAN HIEROGLYPH V011D 13441..13446 ; XID_Start # Lo [6] EGYPTIAN HIEROGLYPH FULL BLANK..EGYPTIAN HIEROGLYPH WIDE LOST SIGN +13460..143FA ; XID_Start # Lo [3995] EGYPTIAN HIEROGLYPH-13460..EGYPTIAN HIEROGLYPH-143FA 14400..14646 ; XID_Start # Lo [583] ANATOLIAN HIEROGLYPH A001..ANATOLIAN HIEROGLYPH A530 +16100..1611D ; XID_Start # Lo [30] GURUNG KHEMA LETTER A..GURUNG KHEMA LETTER SA 16800..16A38 ; XID_Start # Lo [569] BAMUM LETTER PHASE-A NGKUE MFON..BAMUM LETTER PHASE-F VUEQ 16A40..16A5E ; XID_Start # Lo [31] MRO LETTER TA..MRO LETTER TEK 16A70..16ABE ; XID_Start # Lo [79] TANGSA LETTER OZ..TANGSA LETTER ZA @@ -8859,6 +9029,9 @@ FFDA..FFDC ; XID_Start # Lo [3] HALFWIDTH HANGUL LETTER EU..HALFWIDTH HANGU 16B40..16B43 ; XID_Start # Lm [4] PAHAWH HMONG SIGN VOS SEEV..PAHAWH HMONG SIGN IB YAM 16B63..16B77 ; XID_Start # Lo [21] PAHAWH HMONG SIGN VOS LUB..PAHAWH HMONG SIGN CIM NRES TOS 16B7D..16B8F ; XID_Start # Lo [19] PAHAWH HMONG CLAN SIGN TSHEEJ..PAHAWH HMONG CLAN SIGN VWJ +16D40..16D42 ; XID_Start # Lm [3] KIRAT RAI SIGN ANUSVARA..KIRAT RAI SIGN VISARGA +16D43..16D6A ; XID_Start # Lo [40] KIRAT RAI LETTER A..KIRAT RAI VOWEL SIGN AU +16D6B..16D6C ; XID_Start # Lm [2] KIRAT RAI SIGN VIRAMA..KIRAT RAI SIGN SAAT 16E40..16E7F ; XID_Start # L& [64] MEDEFAIDRIN CAPITAL LETTER M..MEDEFAIDRIN SMALL LETTER Y 16F00..16F4A ; XID_Start # Lo [75] MIAO LETTER PA..MIAO LETTER RTE 16F50 ; XID_Start # Lo MIAO LETTER NASALIZATION @@ -8867,7 +9040,7 @@ FFDA..FFDC ; XID_Start # Lo [3] HALFWIDTH HANGUL LETTER EU..HALFWIDTH HANGU 16FE3 ; XID_Start # Lm OLD CHINESE ITERATION MARK 17000..187F7 ; XID_Start # Lo [6136] TANGUT IDEOGRAPH-17000..TANGUT IDEOGRAPH-187F7 18800..18CD5 ; XID_Start # Lo [1238] TANGUT COMPONENT-001..KHITAN SMALL SCRIPT CHARACTER-18CD5 -18D00..18D08 ; XID_Start # Lo [9] TANGUT IDEOGRAPH-18D00..TANGUT IDEOGRAPH-18D08 +18CFF..18D08 ; XID_Start # Lo [10] KHITAN SMALL SCRIPT CHARACTER-18CFF..TANGUT IDEOGRAPH-18D08 1AFF0..1AFF3 ; XID_Start # Lm [4] KATAKANA LETTER MINNAN TONE-2..KATAKANA LETTER MINNAN TONE-5 1AFF5..1AFFB ; XID_Start # Lm [7] KATAKANA LETTER MINNAN TONE-7..KATAKANA LETTER MINNAN NASALIZED TONE-5 1AFFD..1AFFE ; XID_Start # Lm [2] KATAKANA LETTER MINNAN NASALIZED TONE-7..KATAKANA LETTER MINNAN NASALIZED TONE-8 @@ -8923,6 +9096,8 @@ FFDA..FFDC ; XID_Start # Lo [3] HALFWIDTH HANGUL LETTER EU..HALFWIDTH HANGU 1E2C0..1E2EB ; XID_Start # Lo [44] WANCHO LETTER AA..WANCHO LETTER YIH 1E4D0..1E4EA ; XID_Start # Lo [27] NAG MUNDARI LETTER O..NAG MUNDARI LETTER ELL 1E4EB ; XID_Start # Lm NAG MUNDARI SIGN OJOD +1E5D0..1E5ED ; XID_Start # Lo [30] OL ONAL LETTER O..OL ONAL LETTER EG +1E5F0 ; XID_Start # Lo OL ONAL SIGN HODDOND 1E7E0..1E7E6 ; XID_Start # Lo [7] ETHIOPIC SYLLABLE HHYA..ETHIOPIC SYLLABLE HHYO 1E7E8..1E7EB ; XID_Start # Lo [4] ETHIOPIC SYLLABLE GURAGE HHWA..ETHIOPIC SYLLABLE HHWE 1E7ED..1E7EE ; XID_Start # Lo [2] ETHIOPIC SYLLABLE GURAGE MWI..ETHIOPIC SYLLABLE GURAGE MWEE @@ -8973,7 +9148,7 @@ FFDA..FFDC ; XID_Start # Lo [3] HALFWIDTH HANGUL LETTER EU..HALFWIDTH HANGU 30000..3134A ; XID_Start # Lo [4939] CJK UNIFIED IDEOGRAPH-30000..CJK UNIFIED IDEOGRAPH-3134A 31350..323AF ; XID_Start # Lo [4192] CJK UNIFIED IDEOGRAPH-31350..CJK UNIFIED IDEOGRAPH-323AF -# Total code points: 136944 +# Total code points: 141246 # ================================================ @@ -9076,7 +9251,7 @@ FFDA..FFDC ; XID_Start # Lo [3] HALFWIDTH HANGUL LETTER EU..HALFWIDTH HANGU 0860..086A ; XID_Continue # Lo [11] SYRIAC LETTER MALAYALAM NGA..SYRIAC LETTER MALAYALAM SSA 0870..0887 ; XID_Continue # Lo [24] ARABIC LETTER ALEF WITH ATTACHED FATHA..ARABIC BASELINE ROUND DOT 0889..088E ; XID_Continue # Lo [6] ARABIC LETTER NOON WITH INVERTED SMALL V..ARABIC VERTICAL TAIL -0898..089F ; XID_Continue # Mn [8] ARABIC SMALL HIGH WORD AL-JUZ..ARABIC HALF MADDA OVER MADDA +0897..089F ; XID_Continue # Mn [9] ARABIC PEPET..ARABIC HALF MADDA OVER MADDA 08A0..08C8 ; XID_Continue # Lo [41] ARABIC LETTER BEH WITH SMALL V BELOW..ARABIC LETTER GRAF 08C9 ; XID_Continue # Lm ARABIC SMALL FARSI YEH 08CA..08E1 ; XID_Continue # Mn [24] ARABIC SMALL HIGH FARSI YEH..ARABIC SMALL HIGH SIGN SAFHA @@ -9509,7 +9684,7 @@ FFDA..FFDC ; XID_Start # Lo [3] HALFWIDTH HANGUL LETTER EU..HALFWIDTH HANGU 1C50..1C59 ; XID_Continue # Nd [10] OL CHIKI DIGIT ZERO..OL CHIKI DIGIT NINE 1C5A..1C77 ; XID_Continue # Lo [30] OL CHIKI LETTER LA..OL CHIKI LETTER OH 1C78..1C7D ; XID_Continue # Lm [6] OL CHIKI MU TTUDDAG..OL CHIKI AHAD -1C80..1C88 ; XID_Continue # L& [9] CYRILLIC SMALL LETTER ROUNDED VE..CYRILLIC SMALL LETTER UNBLENDED UK +1C80..1C8A ; XID_Continue # L& [11] CYRILLIC SMALL LETTER ROUNDED VE..CYRILLIC SMALL LETTER TJE 1C90..1CBA ; XID_Continue # L& [43] GEORGIAN MTAVRULI CAPITAL LETTER AN..GEORGIAN MTAVRULI CAPITAL LETTER AIN 1CBD..1CBF ; XID_Continue # L& [3] GEORGIAN MTAVRULI CAPITAL LETTER AEN..GEORGIAN MTAVRULI CAPITAL LETTER LABIAL SIGN 1CD0..1CD2 ; XID_Continue # Mn [3] VEDIC TONE KARSHANA..VEDIC TONE PRENKHA @@ -9652,10 +9827,10 @@ A771..A787 ; XID_Continue # L& [23] LATIN SMALL LETTER DUM..LATIN SMALL LETT A788 ; XID_Continue # Lm MODIFIER LETTER LOW CIRCUMFLEX ACCENT A78B..A78E ; XID_Continue # L& [4] LATIN CAPITAL LETTER SALTILLO..LATIN SMALL LETTER L WITH RETROFLEX HOOK AND BELT A78F ; XID_Continue # Lo LATIN LETTER SINOLOGICAL DOT -A790..A7CA ; XID_Continue # L& [59] LATIN CAPITAL LETTER N WITH DESCENDER..LATIN SMALL LETTER S WITH SHORT STROKE OVERLAY +A790..A7CD ; XID_Continue # L& [62] LATIN CAPITAL LETTER N WITH DESCENDER..LATIN SMALL LETTER S WITH DIAGONAL STROKE A7D0..A7D1 ; XID_Continue # L& [2] LATIN CAPITAL LETTER CLOSED INSULAR G..LATIN SMALL LETTER CLOSED INSULAR G A7D3 ; XID_Continue # L& LATIN SMALL LETTER DOUBLE THORN -A7D5..A7D9 ; XID_Continue # L& [5] LATIN SMALL LETTER DOUBLE WYNN..LATIN SMALL LETTER SIGMOID S +A7D5..A7DC ; XID_Continue # L& [8] LATIN SMALL LETTER DOUBLE WYNN..LATIN CAPITAL LETTER LAMBDA WITH STROKE A7F2..A7F4 ; XID_Continue # Lm [3] MODIFIER LETTER CAPITAL C..MODIFIER LETTER CAPITAL Q A7F5..A7F6 ; XID_Continue # L& [2] LATIN CAPITAL LETTER REVERSED HALF H..LATIN SMALL LETTER REVERSED HALF H A7F7 ; XID_Continue # Lo LATIN EPIGRAPHIC LETTER SIDEWAYS I @@ -9850,6 +10025,7 @@ FFDA..FFDC ; XID_Continue # Lo [3] HALFWIDTH HANGUL LETTER EU..HALFWIDTH HA 105A3..105B1 ; XID_Continue # L& [15] VITHKUQI SMALL LETTER HA..VITHKUQI SMALL LETTER RE 105B3..105B9 ; XID_Continue # L& [7] VITHKUQI SMALL LETTER SE..VITHKUQI SMALL LETTER XE 105BB..105BC ; XID_Continue # L& [2] VITHKUQI SMALL LETTER Y..VITHKUQI SMALL LETTER ZE +105C0..105F3 ; XID_Continue # Lo [52] TODHRI LETTER A..TODHRI LETTER OO 10600..10736 ; XID_Continue # Lo [311] LINEAR A SIGN AB001..LINEAR A SIGN A664 10740..10755 ; XID_Continue # Lo [22] LINEAR A SIGN A701 A..LINEAR A SIGN A732 JE 10760..10767 ; XID_Continue # Lo [8] LINEAR A SIGN A800..LINEAR A SIGN A807 @@ -9894,10 +10070,19 @@ FFDA..FFDC ; XID_Continue # Lo [3] HALFWIDTH HANGUL LETTER EU..HALFWIDTH HA 10D00..10D23 ; XID_Continue # Lo [36] HANIFI ROHINGYA LETTER A..HANIFI ROHINGYA MARK NA KHONNA 10D24..10D27 ; XID_Continue # Mn [4] HANIFI ROHINGYA SIGN HARBAHAY..HANIFI ROHINGYA SIGN TASSI 10D30..10D39 ; XID_Continue # Nd [10] HANIFI ROHINGYA DIGIT ZERO..HANIFI ROHINGYA DIGIT NINE +10D40..10D49 ; XID_Continue # Nd [10] GARAY DIGIT ZERO..GARAY DIGIT NINE +10D4A..10D4D ; XID_Continue # Lo [4] GARAY VOWEL SIGN A..GARAY VOWEL SIGN EE +10D4E ; XID_Continue # Lm GARAY VOWEL LENGTH MARK +10D4F ; XID_Continue # Lo GARAY SUKUN +10D50..10D65 ; XID_Continue # L& [22] GARAY CAPITAL LETTER A..GARAY CAPITAL LETTER OLD NA +10D69..10D6D ; XID_Continue # Mn [5] GARAY VOWEL SIGN E..GARAY CONSONANT NASALIZATION MARK +10D6F ; XID_Continue # Lm GARAY REDUPLICATION MARK +10D70..10D85 ; XID_Continue # L& [22] GARAY SMALL LETTER A..GARAY SMALL LETTER OLD NA 10E80..10EA9 ; XID_Continue # Lo [42] YEZIDI LETTER ELIF..YEZIDI LETTER ET 10EAB..10EAC ; XID_Continue # Mn [2] YEZIDI COMBINING HAMZA MARK..YEZIDI COMBINING MADDA MARK 10EB0..10EB1 ; XID_Continue # Lo [2] YEZIDI LETTER LAM WITH DOT ABOVE..YEZIDI LETTER YOT WITH CIRCUMFLEX ABOVE -10EFD..10EFF ; XID_Continue # Mn [3] ARABIC SMALL LOW WORD SAKTA..ARABIC SMALL LOW WORD MADDA +10EC2..10EC4 ; XID_Continue # Lo [3] ARABIC LETTER DAL WITH TWO DOTS VERTICALLY BELOW..ARABIC LETTER KAF WITH TWO DOTS VERTICALLY BELOW +10EFC..10EFF ; XID_Continue # Mn [4] ARABIC COMBINING ALEF OVERLAY..ARABIC SMALL LOW WORD MADDA 10F00..10F1C ; XID_Continue # Lo [29] OLD SOGDIAN LETTER ALEPH..OLD SOGDIAN LETTER FINAL TAW WITH VERTICAL TAIL 10F27 ; XID_Continue # Lo OLD SOGDIAN LIGATURE AYIN-DALETH 10F30..10F45 ; XID_Continue # Lo [22] SOGDIAN LETTER ALEPH..SOGDIAN INDEPENDENT SHIN @@ -9993,6 +10178,24 @@ FFDA..FFDC ; XID_Continue # Lo [3] HALFWIDTH HANGUL LETTER EU..HALFWIDTH HA 11362..11363 ; XID_Continue # Mc [2] GRANTHA VOWEL SIGN VOCALIC L..GRANTHA VOWEL SIGN VOCALIC LL 11366..1136C ; XID_Continue # Mn [7] COMBINING GRANTHA DIGIT ZERO..COMBINING GRANTHA DIGIT SIX 11370..11374 ; XID_Continue # Mn [5] COMBINING GRANTHA LETTER A..COMBINING GRANTHA LETTER PA +11380..11389 ; XID_Continue # Lo [10] TULU-TIGALARI LETTER A..TULU-TIGALARI LETTER VOCALIC LL +1138B ; XID_Continue # Lo TULU-TIGALARI LETTER EE +1138E ; XID_Continue # Lo TULU-TIGALARI LETTER AI +11390..113B5 ; XID_Continue # Lo [38] TULU-TIGALARI LETTER OO..TULU-TIGALARI LETTER LLLA +113B7 ; XID_Continue # Lo TULU-TIGALARI SIGN AVAGRAHA +113B8..113BA ; XID_Continue # Mc [3] TULU-TIGALARI VOWEL SIGN AA..TULU-TIGALARI VOWEL SIGN II +113BB..113C0 ; XID_Continue # Mn [6] TULU-TIGALARI VOWEL SIGN U..TULU-TIGALARI VOWEL SIGN VOCALIC LL +113C2 ; XID_Continue # Mc TULU-TIGALARI VOWEL SIGN EE +113C5 ; XID_Continue # Mc TULU-TIGALARI VOWEL SIGN AI +113C7..113CA ; XID_Continue # Mc [4] TULU-TIGALARI VOWEL SIGN OO..TULU-TIGALARI SIGN CANDRA ANUNASIKA +113CC..113CD ; XID_Continue # Mc [2] TULU-TIGALARI SIGN ANUSVARA..TULU-TIGALARI SIGN VISARGA +113CE ; XID_Continue # Mn TULU-TIGALARI SIGN VIRAMA +113CF ; XID_Continue # Mc TULU-TIGALARI SIGN LOOPED VIRAMA +113D0 ; XID_Continue # Mn TULU-TIGALARI CONJOINER +113D1 ; XID_Continue # Lo TULU-TIGALARI REPHA +113D2 ; XID_Continue # Mn TULU-TIGALARI GEMINATION MARK +113D3 ; XID_Continue # Lo TULU-TIGALARI SIGN PLUTA +113E1..113E2 ; XID_Continue # Mn [2] TULU-TIGALARI VEDIC TONE SVARITA..TULU-TIGALARI VEDIC TONE ANUDATTA 11400..11434 ; XID_Continue # Lo [53] NEWA LETTER A..NEWA LETTER HA 11435..11437 ; XID_Continue # Mc [3] NEWA VOWEL SIGN AA..NEWA VOWEL SIGN II 11438..1143F ; XID_Continue # Mn [8] NEWA VOWEL SIGN U..NEWA VOWEL SIGN AI @@ -10044,8 +10247,11 @@ FFDA..FFDC ; XID_Continue # Lo [3] HALFWIDTH HANGUL LETTER EU..HALFWIDTH HA 116B7 ; XID_Continue # Mn TAKRI SIGN NUKTA 116B8 ; XID_Continue # Lo TAKRI LETTER ARCHAIC KHA 116C0..116C9 ; XID_Continue # Nd [10] TAKRI DIGIT ZERO..TAKRI DIGIT NINE +116D0..116E3 ; XID_Continue # Nd [20] MYANMAR PAO DIGIT ZERO..MYANMAR EASTERN PWO KAREN DIGIT NINE 11700..1171A ; XID_Continue # Lo [27] AHOM LETTER KA..AHOM LETTER ALTERNATE BA -1171D..1171F ; XID_Continue # Mn [3] AHOM CONSONANT SIGN MEDIAL LA..AHOM CONSONANT SIGN MEDIAL LIGATING RA +1171D ; XID_Continue # Mn AHOM CONSONANT SIGN MEDIAL LA +1171E ; XID_Continue # Mc AHOM CONSONANT SIGN MEDIAL RA +1171F ; XID_Continue # Mn AHOM CONSONANT SIGN MEDIAL LIGATING RA 11720..11721 ; XID_Continue # Mc [2] AHOM VOWEL SIGN A..AHOM VOWEL SIGN AA 11722..11725 ; XID_Continue # Mn [4] AHOM VOWEL SIGN I..AHOM VOWEL SIGN UU 11726 ; XID_Continue # Mc AHOM VOWEL SIGN E @@ -10103,6 +10309,8 @@ FFDA..FFDC ; XID_Continue # Lo [3] HALFWIDTH HANGUL LETTER EU..HALFWIDTH HA 11A98..11A99 ; XID_Continue # Mn [2] SOYOMBO GEMINATION MARK..SOYOMBO SUBJOINER 11A9D ; XID_Continue # Lo SOYOMBO MARK PLUTA 11AB0..11AF8 ; XID_Continue # Lo [73] CANADIAN SYLLABICS NATTILIK HI..PAU CIN HAU GLOTTAL STOP FINAL +11BC0..11BE0 ; XID_Continue # Lo [33] SUNUWAR LETTER DEVI..SUNUWAR LETTER KLOKO +11BF0..11BF9 ; XID_Continue # Nd [10] SUNUWAR DIGIT ZERO..SUNUWAR DIGIT NINE 11C00..11C08 ; XID_Continue # Lo [9] BHAIKSUKI LETTER A..BHAIKSUKI LETTER VOCALIC L 11C0A..11C2E ; XID_Continue # Lo [37] BHAIKSUKI LETTER E..BHAIKSUKI LETTER HA 11C2F ; XID_Continue # Mc BHAIKSUKI VOWEL SIGN AA @@ -10156,6 +10364,7 @@ FFDA..FFDC ; XID_Continue # Lo [3] HALFWIDTH HANGUL LETTER EU..HALFWIDTH HA 11F41 ; XID_Continue # Mc KAWI SIGN KILLER 11F42 ; XID_Continue # Mn KAWI CONJOINER 11F50..11F59 ; XID_Continue # Nd [10] KAWI DIGIT ZERO..KAWI DIGIT NINE +11F5A ; XID_Continue # Mn KAWI SIGN NUKTA 11FB0 ; XID_Continue # Lo LISU LETTER YHA 12000..12399 ; XID_Continue # Lo [922] CUNEIFORM SIGN A..CUNEIFORM SIGN U U 12400..1246E ; XID_Continue # Nl [111] CUNEIFORM NUMERIC SIGN TWO ASH..CUNEIFORM NUMERIC SIGN NINE U VARIANT FORM @@ -10165,7 +10374,13 @@ FFDA..FFDC ; XID_Continue # Lo [3] HALFWIDTH HANGUL LETTER EU..HALFWIDTH HA 13440 ; XID_Continue # Mn EGYPTIAN HIEROGLYPH MIRROR HORIZONTALLY 13441..13446 ; XID_Continue # Lo [6] EGYPTIAN HIEROGLYPH FULL BLANK..EGYPTIAN HIEROGLYPH WIDE LOST SIGN 13447..13455 ; XID_Continue # Mn [15] EGYPTIAN HIEROGLYPH MODIFIER DAMAGED AT TOP START..EGYPTIAN HIEROGLYPH MODIFIER DAMAGED +13460..143FA ; XID_Continue # Lo [3995] EGYPTIAN HIEROGLYPH-13460..EGYPTIAN HIEROGLYPH-143FA 14400..14646 ; XID_Continue # Lo [583] ANATOLIAN HIEROGLYPH A001..ANATOLIAN HIEROGLYPH A530 +16100..1611D ; XID_Continue # Lo [30] GURUNG KHEMA LETTER A..GURUNG KHEMA LETTER SA +1611E..16129 ; XID_Continue # Mn [12] GURUNG KHEMA VOWEL SIGN AA..GURUNG KHEMA VOWEL LENGTH MARK +1612A..1612C ; XID_Continue # Mc [3] GURUNG KHEMA CONSONANT SIGN MEDIAL YA..GURUNG KHEMA CONSONANT SIGN MEDIAL HA +1612D..1612F ; XID_Continue # Mn [3] GURUNG KHEMA SIGN ANUSVARA..GURUNG KHEMA SIGN THOLHOMA +16130..16139 ; XID_Continue # Nd [10] GURUNG KHEMA DIGIT ZERO..GURUNG KHEMA DIGIT NINE 16800..16A38 ; XID_Continue # Lo [569] BAMUM LETTER PHASE-A NGKUE MFON..BAMUM LETTER PHASE-F VUEQ 16A40..16A5E ; XID_Continue # Lo [31] MRO LETTER TA..MRO LETTER TEK 16A60..16A69 ; XID_Continue # Nd [10] MRO DIGIT ZERO..MRO DIGIT NINE @@ -10179,6 +10394,10 @@ FFDA..FFDC ; XID_Continue # Lo [3] HALFWIDTH HANGUL LETTER EU..HALFWIDTH HA 16B50..16B59 ; XID_Continue # Nd [10] PAHAWH HMONG DIGIT ZERO..PAHAWH HMONG DIGIT NINE 16B63..16B77 ; XID_Continue # Lo [21] PAHAWH HMONG SIGN VOS LUB..PAHAWH HMONG SIGN CIM NRES TOS 16B7D..16B8F ; XID_Continue # Lo [19] PAHAWH HMONG CLAN SIGN TSHEEJ..PAHAWH HMONG CLAN SIGN VWJ +16D40..16D42 ; XID_Continue # Lm [3] KIRAT RAI SIGN ANUSVARA..KIRAT RAI SIGN VISARGA +16D43..16D6A ; XID_Continue # Lo [40] KIRAT RAI LETTER A..KIRAT RAI VOWEL SIGN AU +16D6B..16D6C ; XID_Continue # Lm [2] KIRAT RAI SIGN VIRAMA..KIRAT RAI SIGN SAAT +16D70..16D79 ; XID_Continue # Nd [10] KIRAT RAI DIGIT ZERO..KIRAT RAI DIGIT NINE 16E40..16E7F ; XID_Continue # L& [64] MEDEFAIDRIN CAPITAL LETTER M..MEDEFAIDRIN SMALL LETTER Y 16F00..16F4A ; XID_Continue # Lo [75] MIAO LETTER PA..MIAO LETTER RTE 16F4F ; XID_Continue # Mn MIAO SIGN CONSONANT MODIFIER BAR @@ -10192,7 +10411,7 @@ FFDA..FFDC ; XID_Continue # Lo [3] HALFWIDTH HANGUL LETTER EU..HALFWIDTH HA 16FF0..16FF1 ; XID_Continue # Mc [2] VIETNAMESE ALTERNATE READING MARK CA..VIETNAMESE ALTERNATE READING MARK NHAY 17000..187F7 ; XID_Continue # Lo [6136] TANGUT IDEOGRAPH-17000..TANGUT IDEOGRAPH-187F7 18800..18CD5 ; XID_Continue # Lo [1238] TANGUT COMPONENT-001..KHITAN SMALL SCRIPT CHARACTER-18CD5 -18D00..18D08 ; XID_Continue # Lo [9] TANGUT IDEOGRAPH-18D00..TANGUT IDEOGRAPH-18D08 +18CFF..18D08 ; XID_Continue # Lo [10] KHITAN SMALL SCRIPT CHARACTER-18CFF..TANGUT IDEOGRAPH-18D08 1AFF0..1AFF3 ; XID_Continue # Lm [4] KATAKANA LETTER MINNAN TONE-2..KATAKANA LETTER MINNAN TONE-5 1AFF5..1AFFB ; XID_Continue # Lm [7] KATAKANA LETTER MINNAN TONE-7..KATAKANA LETTER MINNAN NASALIZED TONE-5 1AFFD..1AFFE ; XID_Continue # Lm [2] KATAKANA LETTER MINNAN NASALIZED TONE-7..KATAKANA LETTER MINNAN NASALIZED TONE-8 @@ -10207,6 +10426,7 @@ FFDA..FFDC ; XID_Continue # Lo [3] HALFWIDTH HANGUL LETTER EU..HALFWIDTH HA 1BC80..1BC88 ; XID_Continue # Lo [9] DUPLOYAN AFFIX HIGH ACUTE..DUPLOYAN AFFIX HIGH VERTICAL 1BC90..1BC99 ; XID_Continue # Lo [10] DUPLOYAN AFFIX LOW ACUTE..DUPLOYAN AFFIX LOW ARROW 1BC9D..1BC9E ; XID_Continue # Mn [2] DUPLOYAN THICK LETTER SELECTOR..DUPLOYAN DOUBLE MARK +1CCF0..1CCF9 ; XID_Continue # Nd [10] OUTLINED DIGIT ZERO..OUTLINED DIGIT NINE 1CF00..1CF2D ; XID_Continue # Mn [46] ZNAMENNY COMBINING MARK GORAZDO NIZKO S KRYZHEM ON LEFT..ZNAMENNY COMBINING MARK KRYZH ON LEFT 1CF30..1CF46 ; XID_Continue # Mn [23] ZNAMENNY COMBINING TONAL RANGE MARK MRACHNO..ZNAMENNY PRIZNAK MODIFIER ROG 1D165..1D166 ; XID_Continue # Mc [2] MUSICAL SYMBOL COMBINING STEM..MUSICAL SYMBOL COMBINING SPRECHGESANG STEM @@ -10278,6 +10498,10 @@ FFDA..FFDC ; XID_Continue # Lo [3] HALFWIDTH HANGUL LETTER EU..HALFWIDTH HA 1E4EB ; XID_Continue # Lm NAG MUNDARI SIGN OJOD 1E4EC..1E4EF ; XID_Continue # Mn [4] NAG MUNDARI SIGN MUHOR..NAG MUNDARI SIGN SUTUH 1E4F0..1E4F9 ; XID_Continue # Nd [10] NAG MUNDARI DIGIT ZERO..NAG MUNDARI DIGIT NINE +1E5D0..1E5ED ; XID_Continue # Lo [30] OL ONAL LETTER O..OL ONAL LETTER EG +1E5EE..1E5EF ; XID_Continue # Mn [2] OL ONAL SIGN MU..OL ONAL SIGN IKIR +1E5F0 ; XID_Continue # Lo OL ONAL SIGN HODDOND +1E5F1..1E5FA ; XID_Continue # Nd [10] OL ONAL DIGIT ZERO..OL ONAL DIGIT NINE 1E7E0..1E7E6 ; XID_Continue # Lo [7] ETHIOPIC SYLLABLE HHYA..ETHIOPIC SYLLABLE HHYO 1E7E8..1E7EB ; XID_Continue # Lo [4] ETHIOPIC SYLLABLE GURAGE HHWA..ETHIOPIC SYLLABLE HHWE 1E7ED..1E7EE ; XID_Continue # Lo [2] ETHIOPIC SYLLABLE GURAGE MWI..ETHIOPIC SYLLABLE GURAGE MWEE @@ -10333,7 +10557,7 @@ FFDA..FFDC ; XID_Continue # Lo [3] HALFWIDTH HANGUL LETTER EU..HALFWIDTH HA 31350..323AF ; XID_Continue # Lo [4192] CJK UNIFIED IDEOGRAPH-31350..CJK UNIFIED IDEOGRAPH-323AF E0100..E01EF ; XID_Continue # Mn [240] VARIATION SELECTOR-17..VARIATION SELECTOR-256 -# Total code points: 140089 +# Total code points: 144522 # ================================================ @@ -10418,7 +10642,7 @@ E01F0..E0FFF ; Default_Ignorable_Code_Point # Cn [3600] <reserved-E01F0>..<rese 0825..0827 ; Grapheme_Extend # Mn [3] SAMARITAN VOWEL SIGN SHORT A..SAMARITAN VOWEL SIGN U 0829..082D ; Grapheme_Extend # Mn [5] SAMARITAN VOWEL SIGN LONG I..SAMARITAN MARK NEQUDAA 0859..085B ; Grapheme_Extend # Mn [3] MANDAIC AFFRICATION MARK..MANDAIC GEMINATION MARK -0898..089F ; Grapheme_Extend # Mn [8] ARABIC SMALL HIGH WORD AL-JUZ..ARABIC HALF MADDA OVER MADDA +0897..089F ; Grapheme_Extend # Mn [9] ARABIC PEPET..ARABIC HALF MADDA OVER MADDA 08CA..08E1 ; Grapheme_Extend # Mn [24] ARABIC SMALL HIGH FARSI YEH..ARABIC SMALL HIGH SIGN SAFHA 08E3..0902 ; Grapheme_Extend # Mn [32] ARABIC TURNED DAMMA BELOW..DEVANAGARI SIGN ANUSVARA 093A ; Grapheme_Extend # Mn DEVANAGARI VOWEL SIGN OE @@ -10475,8 +10699,11 @@ E01F0..E0FFF ; Default_Ignorable_Code_Point # Cn [3600] <reserved-E01F0>..<rese 0C81 ; Grapheme_Extend # Mn KANNADA SIGN CANDRABINDU 0CBC ; Grapheme_Extend # Mn KANNADA SIGN NUKTA 0CBF ; Grapheme_Extend # Mn KANNADA VOWEL SIGN I +0CC0 ; Grapheme_Extend # Mc KANNADA VOWEL SIGN II 0CC2 ; Grapheme_Extend # Mc KANNADA VOWEL SIGN UU 0CC6 ; Grapheme_Extend # Mn KANNADA VOWEL SIGN E +0CC7..0CC8 ; Grapheme_Extend # Mc [2] KANNADA VOWEL SIGN EE..KANNADA VOWEL SIGN AI +0CCA..0CCB ; Grapheme_Extend # Mc [2] KANNADA VOWEL SIGN O..KANNADA VOWEL SIGN OO 0CCC..0CCD ; Grapheme_Extend # Mn [2] KANNADA VOWEL SIGN AU..KANNADA SIGN VIRAMA 0CD5..0CD6 ; Grapheme_Extend # Mc [2] KANNADA LENGTH MARK..KANNADA AI LENGTH MARK 0CE2..0CE3 ; Grapheme_Extend # Mn [2] KANNADA VOWEL SIGN VOCALIC L..KANNADA VOWEL SIGN VOCALIC LL @@ -10522,7 +10749,9 @@ E01F0..E0FFF ; Default_Ignorable_Code_Point # Cn [3600] <reserved-E01F0>..<rese 109D ; Grapheme_Extend # Mn MYANMAR VOWEL SIGN AITON AI 135D..135F ; Grapheme_Extend # Mn [3] ETHIOPIC COMBINING GEMINATION AND VOWEL LENGTH MARK..ETHIOPIC COMBINING GEMINATION MARK 1712..1714 ; Grapheme_Extend # Mn [3] TAGALOG VOWEL SIGN I..TAGALOG SIGN VIRAMA +1715 ; Grapheme_Extend # Mc TAGALOG SIGN PAMUDPOD 1732..1733 ; Grapheme_Extend # Mn [2] HANUNOO VOWEL SIGN I..HANUNOO VOWEL SIGN U +1734 ; Grapheme_Extend # Mc HANUNOO SIGN PAMUDPOD 1752..1753 ; Grapheme_Extend # Mn [2] BUHID VOWEL SIGN I..BUHID VOWEL SIGN U 1772..1773 ; Grapheme_Extend # Mn [2] TAGBANWA VOWEL SIGN I..TAGBANWA VOWEL SIGN U 17B4..17B5 ; Grapheme_Extend # Mn [2] KHMER VOWEL INHERENT AQ..KHMER VOWEL INHERENT AA @@ -10554,17 +10783,22 @@ E01F0..E0FFF ; Default_Ignorable_Code_Point # Cn [3600] <reserved-E01F0>..<rese 1B34 ; Grapheme_Extend # Mn BALINESE SIGN REREKAN 1B35 ; Grapheme_Extend # Mc BALINESE VOWEL SIGN TEDUNG 1B36..1B3A ; Grapheme_Extend # Mn [5] BALINESE VOWEL SIGN ULU..BALINESE VOWEL SIGN RA REPA +1B3B ; Grapheme_Extend # Mc BALINESE VOWEL SIGN RA REPA TEDUNG 1B3C ; Grapheme_Extend # Mn BALINESE VOWEL SIGN LA LENGA +1B3D ; Grapheme_Extend # Mc BALINESE VOWEL SIGN LA LENGA TEDUNG 1B42 ; Grapheme_Extend # Mn BALINESE VOWEL SIGN PEPET +1B43..1B44 ; Grapheme_Extend # Mc [2] BALINESE VOWEL SIGN PEPET TEDUNG..BALINESE ADEG ADEG 1B6B..1B73 ; Grapheme_Extend # Mn [9] BALINESE MUSICAL SYMBOL COMBINING TEGEH..BALINESE MUSICAL SYMBOL COMBINING GONG 1B80..1B81 ; Grapheme_Extend # Mn [2] SUNDANESE SIGN PANYECEK..SUNDANESE SIGN PANGLAYAR 1BA2..1BA5 ; Grapheme_Extend # Mn [4] SUNDANESE CONSONANT SIGN PANYAKRA..SUNDANESE VOWEL SIGN PANYUKU 1BA8..1BA9 ; Grapheme_Extend # Mn [2] SUNDANESE VOWEL SIGN PAMEPET..SUNDANESE VOWEL SIGN PANEULEUNG +1BAA ; Grapheme_Extend # Mc SUNDANESE SIGN PAMAAEH 1BAB..1BAD ; Grapheme_Extend # Mn [3] SUNDANESE SIGN VIRAMA..SUNDANESE CONSONANT SIGN PASANGAN WA 1BE6 ; Grapheme_Extend # Mn BATAK SIGN TOMPI 1BE8..1BE9 ; Grapheme_Extend # Mn [2] BATAK VOWEL SIGN PAKPAK E..BATAK VOWEL SIGN EE 1BED ; Grapheme_Extend # Mn BATAK VOWEL SIGN KARO O 1BEF..1BF1 ; Grapheme_Extend # Mn [3] BATAK VOWEL SIGN U FOR SIMALUNGUN SA..BATAK CONSONANT SIGN H +1BF2..1BF3 ; Grapheme_Extend # Mc [2] BATAK PANGOLAT..BATAK PANONGONAN 1C2C..1C33 ; Grapheme_Extend # Mn [8] LEPCHA VOWEL SIGN E..LEPCHA CONSONANT SIGN T 1C36..1C37 ; Grapheme_Extend # Mn [2] LEPCHA SIGN RAN..LEPCHA SIGN NUKTA 1CD0..1CD2 ; Grapheme_Extend # Mn [3] VEDIC TONE KARSHANA..VEDIC TONE PRENKHA @@ -10601,10 +10835,12 @@ A8E0..A8F1 ; Grapheme_Extend # Mn [18] COMBINING DEVANAGARI DIGIT ZERO..COMB A8FF ; Grapheme_Extend # Mn DEVANAGARI VOWEL SIGN AY A926..A92D ; Grapheme_Extend # Mn [8] KAYAH LI VOWEL UE..KAYAH LI TONE CALYA PLOPHU A947..A951 ; Grapheme_Extend # Mn [11] REJANG VOWEL SIGN I..REJANG CONSONANT SIGN R +A953 ; Grapheme_Extend # Mc REJANG VIRAMA A980..A982 ; Grapheme_Extend # Mn [3] JAVANESE SIGN PANYANGGA..JAVANESE SIGN LAYAR A9B3 ; Grapheme_Extend # Mn JAVANESE SIGN CECAK TELU A9B6..A9B9 ; Grapheme_Extend # Mn [4] JAVANESE VOWEL SIGN WULU..JAVANESE VOWEL SIGN SUKU MENDUT A9BC..A9BD ; Grapheme_Extend # Mn [2] JAVANESE VOWEL SIGN PEPET..JAVANESE CONSONANT SIGN KERET +A9C0 ; Grapheme_Extend # Mc JAVANESE PANGKON A9E5 ; Grapheme_Extend # Mn MYANMAR SIGN SHAN SAW AA29..AA2E ; Grapheme_Extend # Mn [6] CHAM VOWEL SIGN AA..CHAM VOWEL SIGN OE AA31..AA32 ; Grapheme_Extend # Mn [2] CHAM VOWEL SIGN AU..CHAM VOWEL SIGN UE @@ -10636,8 +10872,9 @@ FF9E..FF9F ; Grapheme_Extend # Lm [2] HALFWIDTH KATAKANA VOICED SOUND MARK. 10A3F ; Grapheme_Extend # Mn KHAROSHTHI VIRAMA 10AE5..10AE6 ; Grapheme_Extend # Mn [2] MANICHAEAN ABBREVIATION MARK ABOVE..MANICHAEAN ABBREVIATION MARK BELOW 10D24..10D27 ; Grapheme_Extend # Mn [4] HANIFI ROHINGYA SIGN HARBAHAY..HANIFI ROHINGYA SIGN TASSI +10D69..10D6D ; Grapheme_Extend # Mn [5] GARAY VOWEL SIGN E..GARAY CONSONANT NASALIZATION MARK 10EAB..10EAC ; Grapheme_Extend # Mn [2] YEZIDI COMBINING HAMZA MARK..YEZIDI COMBINING MADDA MARK -10EFD..10EFF ; Grapheme_Extend # Mn [3] ARABIC SMALL LOW WORD SAKTA..ARABIC SMALL LOW WORD MADDA +10EFC..10EFF ; Grapheme_Extend # Mn [4] ARABIC COMBINING ALEF OVERLAY..ARABIC SMALL LOW WORD MADDA 10F46..10F50 ; Grapheme_Extend # Mn [11] SOGDIAN COMBINING DOT BELOW..SOGDIAN COMBINING STROKE BELOW 10F82..10F85 ; Grapheme_Extend # Mn [4] OLD UYGHUR COMBINING DOT ABOVE..OLD UYGHUR COMBINING TWO DOTS BELOW 11001 ; Grapheme_Extend # Mn BRAHMI SIGN ANUSVARA @@ -10654,10 +10891,12 @@ FF9E..FF9F ; Grapheme_Extend # Lm [2] HALFWIDTH KATAKANA VOICED SOUND MARK. 11173 ; Grapheme_Extend # Mn MAHAJANI SIGN NUKTA 11180..11181 ; Grapheme_Extend # Mn [2] SHARADA SIGN CANDRABINDU..SHARADA SIGN ANUSVARA 111B6..111BE ; Grapheme_Extend # Mn [9] SHARADA VOWEL SIGN U..SHARADA VOWEL SIGN O +111C0 ; Grapheme_Extend # Mc SHARADA SIGN VIRAMA 111C9..111CC ; Grapheme_Extend # Mn [4] SHARADA SANDHI MARK..SHARADA EXTRA SHORT VOWEL MARK 111CF ; Grapheme_Extend # Mn SHARADA SIGN INVERTED CANDRABINDU 1122F..11231 ; Grapheme_Extend # Mn [3] KHOJKI VOWEL SIGN U..KHOJKI VOWEL SIGN AI 11234 ; Grapheme_Extend # Mn KHOJKI SIGN ANUSVARA +11235 ; Grapheme_Extend # Mc KHOJKI SIGN VIRAMA 11236..11237 ; Grapheme_Extend # Mn [2] KHOJKI SIGN NUKTA..KHOJKI SIGN SHADDA 1123E ; Grapheme_Extend # Mn KHOJKI SIGN SUKUN 11241 ; Grapheme_Extend # Mn KHOJKI VOWEL SIGN VOCALIC R @@ -10667,9 +10906,20 @@ FF9E..FF9F ; Grapheme_Extend # Lm [2] HALFWIDTH KATAKANA VOICED SOUND MARK. 1133B..1133C ; Grapheme_Extend # Mn [2] COMBINING BINDU BELOW..GRANTHA SIGN NUKTA 1133E ; Grapheme_Extend # Mc GRANTHA VOWEL SIGN AA 11340 ; Grapheme_Extend # Mn GRANTHA VOWEL SIGN II +1134D ; Grapheme_Extend # Mc GRANTHA SIGN VIRAMA 11357 ; Grapheme_Extend # Mc GRANTHA AU LENGTH MARK 11366..1136C ; Grapheme_Extend # Mn [7] COMBINING GRANTHA DIGIT ZERO..COMBINING GRANTHA DIGIT SIX 11370..11374 ; Grapheme_Extend # Mn [5] COMBINING GRANTHA LETTER A..COMBINING GRANTHA LETTER PA +113B8 ; Grapheme_Extend # Mc TULU-TIGALARI VOWEL SIGN AA +113BB..113C0 ; Grapheme_Extend # Mn [6] TULU-TIGALARI VOWEL SIGN U..TULU-TIGALARI VOWEL SIGN VOCALIC LL +113C2 ; Grapheme_Extend # Mc TULU-TIGALARI VOWEL SIGN EE +113C5 ; Grapheme_Extend # Mc TULU-TIGALARI VOWEL SIGN AI +113C7..113C9 ; Grapheme_Extend # Mc [3] TULU-TIGALARI VOWEL SIGN OO..TULU-TIGALARI AU LENGTH MARK +113CE ; Grapheme_Extend # Mn TULU-TIGALARI SIGN VIRAMA +113CF ; Grapheme_Extend # Mc TULU-TIGALARI SIGN LOOPED VIRAMA +113D0 ; Grapheme_Extend # Mn TULU-TIGALARI CONJOINER +113D2 ; Grapheme_Extend # Mn TULU-TIGALARI GEMINATION MARK +113E1..113E2 ; Grapheme_Extend # Mn [2] TULU-TIGALARI VEDIC TONE SVARITA..TULU-TIGALARI VEDIC TONE ANUDATTA 11438..1143F ; Grapheme_Extend # Mn [8] NEWA VOWEL SIGN U..NEWA VOWEL SIGN AI 11442..11444 ; Grapheme_Extend # Mn [3] NEWA SIGN VIRAMA..NEWA SIGN ANUSVARA 11446 ; Grapheme_Extend # Mn NEWA SIGN NUKTA @@ -10691,14 +10941,17 @@ FF9E..FF9F ; Grapheme_Extend # Lm [2] HALFWIDTH KATAKANA VOICED SOUND MARK. 116AB ; Grapheme_Extend # Mn TAKRI SIGN ANUSVARA 116AD ; Grapheme_Extend # Mn TAKRI VOWEL SIGN AA 116B0..116B5 ; Grapheme_Extend # Mn [6] TAKRI VOWEL SIGN U..TAKRI VOWEL SIGN AU +116B6 ; Grapheme_Extend # Mc TAKRI SIGN VIRAMA 116B7 ; Grapheme_Extend # Mn TAKRI SIGN NUKTA -1171D..1171F ; Grapheme_Extend # Mn [3] AHOM CONSONANT SIGN MEDIAL LA..AHOM CONSONANT SIGN MEDIAL LIGATING RA +1171D ; Grapheme_Extend # Mn AHOM CONSONANT SIGN MEDIAL LA +1171F ; Grapheme_Extend # Mn AHOM CONSONANT SIGN MEDIAL LIGATING RA 11722..11725 ; Grapheme_Extend # Mn [4] AHOM VOWEL SIGN I..AHOM VOWEL SIGN UU 11727..1172B ; Grapheme_Extend # Mn [5] AHOM VOWEL SIGN AW..AHOM SIGN KILLER 1182F..11837 ; Grapheme_Extend # Mn [9] DOGRA VOWEL SIGN U..DOGRA SIGN ANUSVARA 11839..1183A ; Grapheme_Extend # Mn [2] DOGRA SIGN VIRAMA..DOGRA SIGN NUKTA 11930 ; Grapheme_Extend # Mc DIVES AKURU VOWEL SIGN AA 1193B..1193C ; Grapheme_Extend # Mn [2] DIVES AKURU SIGN ANUSVARA..DIVES AKURU SIGN CANDRABINDU +1193D ; Grapheme_Extend # Mc DIVES AKURU SIGN HALANTA 1193E ; Grapheme_Extend # Mn DIVES AKURU VIRAMA 11943 ; Grapheme_Extend # Mn DIVES AKURU SIGN NUKTA 119D4..119D7 ; Grapheme_Extend # Mn [4] NANDINAGARI VOWEL SIGN U..NANDINAGARI VOWEL SIGN VOCALIC RR @@ -10731,20 +10984,25 @@ FF9E..FF9F ; Grapheme_Extend # Lm [2] HALFWIDTH KATAKANA VOICED SOUND MARK. 11F00..11F01 ; Grapheme_Extend # Mn [2] KAWI SIGN CANDRABINDU..KAWI SIGN ANUSVARA 11F36..11F3A ; Grapheme_Extend # Mn [5] KAWI VOWEL SIGN I..KAWI VOWEL SIGN VOCALIC R 11F40 ; Grapheme_Extend # Mn KAWI VOWEL SIGN EU +11F41 ; Grapheme_Extend # Mc KAWI SIGN KILLER 11F42 ; Grapheme_Extend # Mn KAWI CONJOINER +11F5A ; Grapheme_Extend # Mn KAWI SIGN NUKTA 13440 ; Grapheme_Extend # Mn EGYPTIAN HIEROGLYPH MIRROR HORIZONTALLY 13447..13455 ; Grapheme_Extend # Mn [15] EGYPTIAN HIEROGLYPH MODIFIER DAMAGED AT TOP START..EGYPTIAN HIEROGLYPH MODIFIER DAMAGED +1611E..16129 ; Grapheme_Extend # Mn [12] GURUNG KHEMA VOWEL SIGN AA..GURUNG KHEMA VOWEL LENGTH MARK +1612D..1612F ; Grapheme_Extend # Mn [3] GURUNG KHEMA SIGN ANUSVARA..GURUNG KHEMA SIGN THOLHOMA 16AF0..16AF4 ; Grapheme_Extend # Mn [5] BASSA VAH COMBINING HIGH TONE..BASSA VAH COMBINING HIGH-LOW TONE 16B30..16B36 ; Grapheme_Extend # Mn [7] PAHAWH HMONG MARK CIM TUB..PAHAWH HMONG MARK CIM TAUM 16F4F ; Grapheme_Extend # Mn MIAO SIGN CONSONANT MODIFIER BAR 16F8F..16F92 ; Grapheme_Extend # Mn [4] MIAO TONE RIGHT..MIAO TONE BELOW 16FE4 ; Grapheme_Extend # Mn KHITAN SMALL SCRIPT FILLER +16FF0..16FF1 ; Grapheme_Extend # Mc [2] VIETNAMESE ALTERNATE READING MARK CA..VIETNAMESE ALTERNATE READING MARK NHAY 1BC9D..1BC9E ; Grapheme_Extend # Mn [2] DUPLOYAN THICK LETTER SELECTOR..DUPLOYAN DOUBLE MARK 1CF00..1CF2D ; Grapheme_Extend # Mn [46] ZNAMENNY COMBINING MARK GORAZDO NIZKO S KRYZHEM ON LEFT..ZNAMENNY COMBINING MARK KRYZH ON LEFT 1CF30..1CF46 ; Grapheme_Extend # Mn [23] ZNAMENNY COMBINING TONAL RANGE MARK MRACHNO..ZNAMENNY PRIZNAK MODIFIER ROG -1D165 ; Grapheme_Extend # Mc MUSICAL SYMBOL COMBINING STEM +1D165..1D166 ; Grapheme_Extend # Mc [2] MUSICAL SYMBOL COMBINING STEM..MUSICAL SYMBOL COMBINING SPRECHGESANG STEM 1D167..1D169 ; Grapheme_Extend # Mn [3] MUSICAL SYMBOL COMBINING TREMOLO-1..MUSICAL SYMBOL COMBINING TREMOLO-3 -1D16E..1D172 ; Grapheme_Extend # Mc [5] MUSICAL SYMBOL COMBINING FLAG-1..MUSICAL SYMBOL COMBINING FLAG-5 +1D16D..1D172 ; Grapheme_Extend # Mc [6] MUSICAL SYMBOL COMBINING AUGMENTATION DOT..MUSICAL SYMBOL COMBINING FLAG-5 1D17B..1D182 ; Grapheme_Extend # Mn [8] MUSICAL SYMBOL COMBINING ACCENT..MUSICAL SYMBOL COMBINING LOURE 1D185..1D18B ; Grapheme_Extend # Mn [7] MUSICAL SYMBOL COMBINING DOIT..MUSICAL SYMBOL COMBINING TRIPLE TONGUE 1D1AA..1D1AD ; Grapheme_Extend # Mn [4] MUSICAL SYMBOL COMBINING DOWN BOW..MUSICAL SYMBOL COMBINING SNAP PIZZICATO @@ -10765,12 +11023,13 @@ FF9E..FF9F ; Grapheme_Extend # Lm [2] HALFWIDTH KATAKANA VOICED SOUND MARK. 1E2AE ; Grapheme_Extend # Mn TOTO SIGN RISING TONE 1E2EC..1E2EF ; Grapheme_Extend # Mn [4] WANCHO TONE TUP..WANCHO TONE KOINI 1E4EC..1E4EF ; Grapheme_Extend # Mn [4] NAG MUNDARI SIGN MUHOR..NAG MUNDARI SIGN SUTUH +1E5EE..1E5EF ; Grapheme_Extend # Mn [2] OL ONAL SIGN MU..OL ONAL SIGN IKIR 1E8D0..1E8D6 ; Grapheme_Extend # Mn [7] MENDE KIKAKUI COMBINING NUMBER TEENS..MENDE KIKAKUI COMBINING NUMBER MILLIONS 1E944..1E94A ; Grapheme_Extend # Mn [7] ADLAM ALIF LENGTHENER..ADLAM NUKTA E0020..E007F ; Grapheme_Extend # Cf [96] TAG SPACE..CANCEL TAG E0100..E01EF ; Grapheme_Extend # Mn [240] VARIATION SELECTOR-17..VARIATION SELECTOR-256 -# Total code points: 2125 +# Total code points: 2193 # ================================================ @@ -11062,10 +11321,8 @@ E0100..E01EF ; Grapheme_Extend # Mn [240] VARIATION SELECTOR-17..VARIATION SELE 0CB5..0CB9 ; Grapheme_Base # Lo [5] KANNADA LETTER VA..KANNADA LETTER HA 0CBD ; Grapheme_Base # Lo KANNADA SIGN AVAGRAHA 0CBE ; Grapheme_Base # Mc KANNADA VOWEL SIGN AA -0CC0..0CC1 ; Grapheme_Base # Mc [2] KANNADA VOWEL SIGN II..KANNADA VOWEL SIGN U +0CC1 ; Grapheme_Base # Mc KANNADA VOWEL SIGN U 0CC3..0CC4 ; Grapheme_Base # Mc [2] KANNADA VOWEL SIGN VOCALIC R..KANNADA VOWEL SIGN VOCALIC RR -0CC7..0CC8 ; Grapheme_Base # Mc [2] KANNADA VOWEL SIGN EE..KANNADA VOWEL SIGN AI -0CCA..0CCB ; Grapheme_Base # Mc [2] KANNADA VOWEL SIGN O..KANNADA VOWEL SIGN OO 0CDD..0CDE ; Grapheme_Base # Lo [2] KANNADA LETTER NAKAARA POLLU..KANNADA LETTER FA 0CE0..0CE1 ; Grapheme_Base # Lo [2] KANNADA LETTER VOCALIC RR..KANNADA LETTER VOCALIC LL 0CE6..0CEF ; Grapheme_Base # Nd [10] KANNADA DIGIT ZERO..KANNADA DIGIT NINE @@ -11214,9 +11471,7 @@ E0100..E01EF ; Grapheme_Extend # Mn [240] VARIATION SELECTOR-17..VARIATION SELE 16EE..16F0 ; Grapheme_Base # Nl [3] RUNIC ARLAUG SYMBOL..RUNIC BELGTHOR SYMBOL 16F1..16F8 ; Grapheme_Base # Lo [8] RUNIC LETTER K..RUNIC LETTER FRANKS CASKET AESC 1700..1711 ; Grapheme_Base # Lo [18] TAGALOG LETTER A..TAGALOG LETTER HA -1715 ; Grapheme_Base # Mc TAGALOG SIGN PAMUDPOD 171F..1731 ; Grapheme_Base # Lo [19] TAGALOG LETTER ARCHAIC RA..HANUNOO LETTER HA -1734 ; Grapheme_Base # Mc HANUNOO SIGN PAMUDPOD 1735..1736 ; Grapheme_Base # Po [2] PHILIPPINE SINGLE PUNCTUATION..PHILIPPINE DOUBLE PUNCTUATION 1740..1751 ; Grapheme_Base # Lo [18] BUHID LETTER A..BUHID LETTER HA 1760..176C ; Grapheme_Base # Lo [13] TAGBANWA LETTER A..TAGBANWA LETTER YA @@ -11274,27 +11529,24 @@ E0100..E01EF ; Grapheme_Extend # Mn [240] VARIATION SELECTOR-17..VARIATION SELE 1AA8..1AAD ; Grapheme_Base # Po [6] TAI THAM SIGN KAAN..TAI THAM SIGN CAANG 1B04 ; Grapheme_Base # Mc BALINESE SIGN BISAH 1B05..1B33 ; Grapheme_Base # Lo [47] BALINESE LETTER AKARA..BALINESE LETTER HA -1B3B ; Grapheme_Base # Mc BALINESE VOWEL SIGN RA REPA TEDUNG -1B3D..1B41 ; Grapheme_Base # Mc [5] BALINESE VOWEL SIGN LA LENGA TEDUNG..BALINESE VOWEL SIGN TALING REPA TEDUNG -1B43..1B44 ; Grapheme_Base # Mc [2] BALINESE VOWEL SIGN PEPET TEDUNG..BALINESE ADEG ADEG +1B3E..1B41 ; Grapheme_Base # Mc [4] BALINESE VOWEL SIGN TALING..BALINESE VOWEL SIGN TALING REPA TEDUNG 1B45..1B4C ; Grapheme_Base # Lo [8] BALINESE LETTER KAF SASAK..BALINESE LETTER ARCHAIC JNYA +1B4E..1B4F ; Grapheme_Base # Po [2] BALINESE INVERTED CARIK SIKI..BALINESE INVERTED CARIK PAREREN 1B50..1B59 ; Grapheme_Base # Nd [10] BALINESE DIGIT ZERO..BALINESE DIGIT NINE 1B5A..1B60 ; Grapheme_Base # Po [7] BALINESE PANTI..BALINESE PAMENENG 1B61..1B6A ; Grapheme_Base # So [10] BALINESE MUSICAL SYMBOL DONG..BALINESE MUSICAL SYMBOL DANG GEDE 1B74..1B7C ; Grapheme_Base # So [9] BALINESE MUSICAL SYMBOL RIGHT-HAND OPEN DUG..BALINESE MUSICAL SYMBOL LEFT-HAND OPEN PING -1B7D..1B7E ; Grapheme_Base # Po [2] BALINESE PANTI LANTANG..BALINESE PAMADA LANTANG +1B7D..1B7F ; Grapheme_Base # Po [3] BALINESE PANTI LANTANG..BALINESE PANTI BAWAK 1B82 ; Grapheme_Base # Mc SUNDANESE SIGN PANGWISAD 1B83..1BA0 ; Grapheme_Base # Lo [30] SUNDANESE LETTER A..SUNDANESE LETTER HA 1BA1 ; Grapheme_Base # Mc SUNDANESE CONSONANT SIGN PAMINGKAL 1BA6..1BA7 ; Grapheme_Base # Mc [2] SUNDANESE VOWEL SIGN PANAELAENG..SUNDANESE VOWEL SIGN PANOLONG -1BAA ; Grapheme_Base # Mc SUNDANESE SIGN PAMAAEH 1BAE..1BAF ; Grapheme_Base # Lo [2] SUNDANESE LETTER KHA..SUNDANESE LETTER SYA 1BB0..1BB9 ; Grapheme_Base # Nd [10] SUNDANESE DIGIT ZERO..SUNDANESE DIGIT NINE 1BBA..1BE5 ; Grapheme_Base # Lo [44] SUNDANESE AVAGRAHA..BATAK LETTER U 1BE7 ; Grapheme_Base # Mc BATAK VOWEL SIGN E 1BEA..1BEC ; Grapheme_Base # Mc [3] BATAK VOWEL SIGN I..BATAK VOWEL SIGN O 1BEE ; Grapheme_Base # Mc BATAK VOWEL SIGN U -1BF2..1BF3 ; Grapheme_Base # Mc [2] BATAK PANGOLAT..BATAK PANONGONAN 1BFC..1BFF ; Grapheme_Base # Po [4] BATAK SYMBOL BINDU NA METEK..BATAK SYMBOL BINDU PANGOLAT 1C00..1C23 ; Grapheme_Base # Lo [36] LEPCHA LETTER KA..LEPCHA LETTER A 1C24..1C2B ; Grapheme_Base # Mc [8] LEPCHA SUBJOINED LETTER YA..LEPCHA VOWEL SIGN UU @@ -11306,7 +11558,7 @@ E0100..E01EF ; Grapheme_Extend # Mn [240] VARIATION SELECTOR-17..VARIATION SELE 1C5A..1C77 ; Grapheme_Base # Lo [30] OL CHIKI LETTER LA..OL CHIKI LETTER OH 1C78..1C7D ; Grapheme_Base # Lm [6] OL CHIKI MU TTUDDAG..OL CHIKI AHAD 1C7E..1C7F ; Grapheme_Base # Po [2] OL CHIKI PUNCTUATION MUCAAD..OL CHIKI PUNCTUATION DOUBLE MUCAAD -1C80..1C88 ; Grapheme_Base # L& [9] CYRILLIC SMALL LETTER ROUNDED VE..CYRILLIC SMALL LETTER UNBLENDED UK +1C80..1C8A ; Grapheme_Base # L& [11] CYRILLIC SMALL LETTER ROUNDED VE..CYRILLIC SMALL LETTER TJE 1C90..1CBA ; Grapheme_Base # L& [43] GEORGIAN MTAVRULI CAPITAL LETTER AN..GEORGIAN MTAVRULI CAPITAL LETTER AIN 1CBD..1CBF ; Grapheme_Base # L& [3] GEORGIAN MTAVRULI CAPITAL LETTER AEN..GEORGIAN MTAVRULI CAPITAL LETTER LABIAL SIGN 1CC0..1CC7 ; Grapheme_Base # Po [8] SUNDANESE PUNCTUATION BINDU SURYA..SUNDANESE PUNCTUATION BINDU BA SATANGA @@ -11461,7 +11713,7 @@ E0100..E01EF ; Grapheme_Extend # Mn [240] VARIATION SELECTOR-17..VARIATION SELE 239B..23B3 ; Grapheme_Base # Sm [25] LEFT PARENTHESIS UPPER HOOK..SUMMATION BOTTOM 23B4..23DB ; Grapheme_Base # So [40] TOP SQUARE BRACKET..FUSE 23DC..23E1 ; Grapheme_Base # Sm [6] TOP PARENTHESIS..BOTTOM TORTOISE SHELL BRACKET -23E2..2426 ; Grapheme_Base # So [69] WHITE TRAPEZIUM..SYMBOL FOR SUBSTITUTE FORM TWO +23E2..2429 ; Grapheme_Base # So [72] WHITE TRAPEZIUM..SYMBOL FOR DELETE MEDIUM SHADE FORM 2440..244A ; Grapheme_Base # So [11] OCR HOOK..OCR DOUBLE BACKSLASH 2460..249B ; Grapheme_Base # No [60] CIRCLED DIGIT ONE..NUMBER TWENTY FULL STOP 249C..24E9 ; Grapheme_Base # So [78] PARENTHESIZED LATIN SMALL LETTER A..CIRCLED LATIN SMALL LETTER Z @@ -11676,7 +11928,7 @@ E0100..E01EF ; Grapheme_Extend # Mn [240] VARIATION SELECTOR-17..VARIATION SELE 3192..3195 ; Grapheme_Base # No [4] IDEOGRAPHIC ANNOTATION ONE MARK..IDEOGRAPHIC ANNOTATION FOUR MARK 3196..319F ; Grapheme_Base # So [10] IDEOGRAPHIC ANNOTATION TOP MARK..IDEOGRAPHIC ANNOTATION MAN MARK 31A0..31BF ; Grapheme_Base # Lo [32] BOPOMOFO LETTER BU..BOPOMOFO LETTER AH -31C0..31E3 ; Grapheme_Base # So [36] CJK STROKE T..CJK STROKE Q +31C0..31E5 ; Grapheme_Base # So [38] CJK STROKE T..CJK STROKE SZP 31EF ; Grapheme_Base # So IDEOGRAPHIC DESCRIPTION CHARACTER SUBTRACTION 31F0..31FF ; Grapheme_Base # Lo [16] KATAKANA LETTER SMALL KU..KATAKANA LETTER SMALL RO 3200..321E ; Grapheme_Base # So [31] PARENTHESIZED HANGUL KIYEOK..PARENTHESIZED KOREAN CHARACTER O HU @@ -11725,10 +11977,10 @@ A788 ; Grapheme_Base # Lm MODIFIER LETTER LOW CIRCUMFLEX ACCENT A789..A78A ; Grapheme_Base # Sk [2] MODIFIER LETTER COLON..MODIFIER LETTER SHORT EQUALS SIGN A78B..A78E ; Grapheme_Base # L& [4] LATIN CAPITAL LETTER SALTILLO..LATIN SMALL LETTER L WITH RETROFLEX HOOK AND BELT A78F ; Grapheme_Base # Lo LATIN LETTER SINOLOGICAL DOT -A790..A7CA ; Grapheme_Base # L& [59] LATIN CAPITAL LETTER N WITH DESCENDER..LATIN SMALL LETTER S WITH SHORT STROKE OVERLAY +A790..A7CD ; Grapheme_Base # L& [62] LATIN CAPITAL LETTER N WITH DESCENDER..LATIN SMALL LETTER S WITH DIAGONAL STROKE A7D0..A7D1 ; Grapheme_Base # L& [2] LATIN CAPITAL LETTER CLOSED INSULAR G..LATIN SMALL LETTER CLOSED INSULAR G A7D3 ; Grapheme_Base # L& LATIN SMALL LETTER DOUBLE THORN -A7D5..A7D9 ; Grapheme_Base # L& [5] LATIN SMALL LETTER DOUBLE WYNN..LATIN SMALL LETTER SIGMOID S +A7D5..A7DC ; Grapheme_Base # L& [8] LATIN SMALL LETTER DOUBLE WYNN..LATIN CAPITAL LETTER LAMBDA WITH STROKE A7F2..A7F4 ; Grapheme_Base # Lm [3] MODIFIER LETTER CAPITAL C..MODIFIER LETTER CAPITAL Q A7F5..A7F6 ; Grapheme_Base # L& [2] LATIN CAPITAL LETTER REVERSED HALF H..LATIN SMALL LETTER REVERSED HALF H A7F7 ; Grapheme_Base # Lo LATIN EPIGRAPHIC LETTER SIDEWAYS I @@ -11761,14 +12013,14 @@ A900..A909 ; Grapheme_Base # Nd [10] KAYAH LI DIGIT ZERO..KAYAH LI DIGIT NIN A90A..A925 ; Grapheme_Base # Lo [28] KAYAH LI LETTER KA..KAYAH LI LETTER OO A92E..A92F ; Grapheme_Base # Po [2] KAYAH LI SIGN CWI..KAYAH LI SIGN SHYA A930..A946 ; Grapheme_Base # Lo [23] REJANG LETTER KA..REJANG LETTER A -A952..A953 ; Grapheme_Base # Mc [2] REJANG CONSONANT SIGN H..REJANG VIRAMA +A952 ; Grapheme_Base # Mc REJANG CONSONANT SIGN H A95F ; Grapheme_Base # Po REJANG SECTION MARK A960..A97C ; Grapheme_Base # Lo [29] HANGUL CHOSEONG TIKEUT-MIEUM..HANGUL CHOSEONG SSANGYEORINHIEUH A983 ; Grapheme_Base # Mc JAVANESE SIGN WIGNYAN A984..A9B2 ; Grapheme_Base # Lo [47] JAVANESE LETTER A..JAVANESE LETTER HA A9B4..A9B5 ; Grapheme_Base # Mc [2] JAVANESE VOWEL SIGN TARUNG..JAVANESE VOWEL SIGN TOLONG A9BA..A9BB ; Grapheme_Base # Mc [2] JAVANESE VOWEL SIGN TALING..JAVANESE VOWEL SIGN DIRGA MURE -A9BE..A9C0 ; Grapheme_Base # Mc [3] JAVANESE CONSONANT SIGN PENGKAL..JAVANESE PANGKON +A9BE..A9BF ; Grapheme_Base # Mc [2] JAVANESE CONSONANT SIGN PENGKAL..JAVANESE CONSONANT SIGN CAKRA A9C1..A9CD ; Grapheme_Base # Po [13] JAVANESE LEFT RERENGGAN..JAVANESE TURNED PADA PISELEH A9CF ; Grapheme_Base # Lm JAVANESE PANGRANGKEP A9D0..A9D9 ; Grapheme_Base # Nd [10] JAVANESE DIGIT ZERO..JAVANESE DIGIT NINE @@ -12000,6 +12252,7 @@ FFFC..FFFD ; Grapheme_Base # So [2] OBJECT REPLACEMENT CHARACTER..REPLACEME 105A3..105B1 ; Grapheme_Base # L& [15] VITHKUQI SMALL LETTER HA..VITHKUQI SMALL LETTER RE 105B3..105B9 ; Grapheme_Base # L& [7] VITHKUQI SMALL LETTER SE..VITHKUQI SMALL LETTER XE 105BB..105BC ; Grapheme_Base # L& [2] VITHKUQI SMALL LETTER Y..VITHKUQI SMALL LETTER ZE +105C0..105F3 ; Grapheme_Base # Lo [52] TODHRI LETTER A..TODHRI LETTER OO 10600..10736 ; Grapheme_Base # Lo [311] LINEAR A SIGN AB001..LINEAR A SIGN A664 10740..10755 ; Grapheme_Base # Lo [22] LINEAR A SIGN A701 A..LINEAR A SIGN A732 JE 10760..10767 ; Grapheme_Base # Lo [8] LINEAR A SIGN A800..LINEAR A SIGN A807 @@ -12063,10 +12316,20 @@ FFFC..FFFD ; Grapheme_Base # So [2] OBJECT REPLACEMENT CHARACTER..REPLACEME 10CFA..10CFF ; Grapheme_Base # No [6] OLD HUNGARIAN NUMBER ONE..OLD HUNGARIAN NUMBER ONE THOUSAND 10D00..10D23 ; Grapheme_Base # Lo [36] HANIFI ROHINGYA LETTER A..HANIFI ROHINGYA MARK NA KHONNA 10D30..10D39 ; Grapheme_Base # Nd [10] HANIFI ROHINGYA DIGIT ZERO..HANIFI ROHINGYA DIGIT NINE +10D40..10D49 ; Grapheme_Base # Nd [10] GARAY DIGIT ZERO..GARAY DIGIT NINE +10D4A..10D4D ; Grapheme_Base # Lo [4] GARAY VOWEL SIGN A..GARAY VOWEL SIGN EE +10D4E ; Grapheme_Base # Lm GARAY VOWEL LENGTH MARK +10D4F ; Grapheme_Base # Lo GARAY SUKUN +10D50..10D65 ; Grapheme_Base # L& [22] GARAY CAPITAL LETTER A..GARAY CAPITAL LETTER OLD NA +10D6E ; Grapheme_Base # Pd GARAY HYPHEN +10D6F ; Grapheme_Base # Lm GARAY REDUPLICATION MARK +10D70..10D85 ; Grapheme_Base # L& [22] GARAY SMALL LETTER A..GARAY SMALL LETTER OLD NA +10D8E..10D8F ; Grapheme_Base # Sm [2] GARAY PLUS SIGN..GARAY MINUS SIGN 10E60..10E7E ; Grapheme_Base # No [31] RUMI DIGIT ONE..RUMI FRACTION TWO THIRDS 10E80..10EA9 ; Grapheme_Base # Lo [42] YEZIDI LETTER ELIF..YEZIDI LETTER ET 10EAD ; Grapheme_Base # Pd YEZIDI HYPHENATION MARK 10EB0..10EB1 ; Grapheme_Base # Lo [2] YEZIDI LETTER LAM WITH DOT ABOVE..YEZIDI LETTER YOT WITH CIRCUMFLEX ABOVE +10EC2..10EC4 ; Grapheme_Base # Lo [3] ARABIC LETTER DAL WITH TWO DOTS VERTICALLY BELOW..ARABIC LETTER KAF WITH TWO DOTS VERTICALLY BELOW 10F00..10F1C ; Grapheme_Base # Lo [29] OLD SOGDIAN LETTER ALEPH..OLD SOGDIAN LETTER FINAL TAW WITH VERTICAL TAIL 10F1D..10F26 ; Grapheme_Base # No [10] OLD SOGDIAN NUMBER ONE..OLD SOGDIAN FRACTION ONE HALF 10F27 ; Grapheme_Base # Lo OLD SOGDIAN LIGATURE AYIN-DALETH @@ -12107,7 +12370,7 @@ FFFC..FFFD ; Grapheme_Base # So [2] OBJECT REPLACEMENT CHARACTER..REPLACEME 11182 ; Grapheme_Base # Mc SHARADA SIGN VISARGA 11183..111B2 ; Grapheme_Base # Lo [48] SHARADA LETTER A..SHARADA LETTER HA 111B3..111B5 ; Grapheme_Base # Mc [3] SHARADA VOWEL SIGN AA..SHARADA VOWEL SIGN II -111BF..111C0 ; Grapheme_Base # Mc [2] SHARADA VOWEL SIGN AU..SHARADA SIGN VIRAMA +111BF ; Grapheme_Base # Mc SHARADA VOWEL SIGN AU 111C1..111C4 ; Grapheme_Base # Lo [4] SHARADA SIGN AVAGRAHA..SHARADA OM 111C5..111C8 ; Grapheme_Base # Po [4] SHARADA DANDA..SHARADA SEPARATOR 111CD ; Grapheme_Base # Po SHARADA SUTRA MARK @@ -12122,7 +12385,6 @@ FFFC..FFFD ; Grapheme_Base # So [2] OBJECT REPLACEMENT CHARACTER..REPLACEME 11213..1122B ; Grapheme_Base # Lo [25] KHOJKI LETTER NYA..KHOJKI LETTER LLA 1122C..1122E ; Grapheme_Base # Mc [3] KHOJKI VOWEL SIGN AA..KHOJKI VOWEL SIGN II 11232..11233 ; Grapheme_Base # Mc [2] KHOJKI VOWEL SIGN O..KHOJKI VOWEL SIGN AU -11235 ; Grapheme_Base # Mc KHOJKI SIGN VIRAMA 11238..1123D ; Grapheme_Base # Po [6] KHOJKI DANDA..KHOJKI ABBREVIATION SIGN 1123F..11240 ; Grapheme_Base # Lo [2] KHOJKI LETTER QA..KHOJKI LETTER SHORT I 11280..11286 ; Grapheme_Base # Lo [7] MULTANI LETTER A..MULTANI LETTER GA @@ -12145,10 +12407,22 @@ FFFC..FFFD ; Grapheme_Base # So [2] OBJECT REPLACEMENT CHARACTER..REPLACEME 1133F ; Grapheme_Base # Mc GRANTHA VOWEL SIGN I 11341..11344 ; Grapheme_Base # Mc [4] GRANTHA VOWEL SIGN U..GRANTHA VOWEL SIGN VOCALIC RR 11347..11348 ; Grapheme_Base # Mc [2] GRANTHA VOWEL SIGN EE..GRANTHA VOWEL SIGN AI -1134B..1134D ; Grapheme_Base # Mc [3] GRANTHA VOWEL SIGN OO..GRANTHA SIGN VIRAMA +1134B..1134C ; Grapheme_Base # Mc [2] GRANTHA VOWEL SIGN OO..GRANTHA VOWEL SIGN AU 11350 ; Grapheme_Base # Lo GRANTHA OM 1135D..11361 ; Grapheme_Base # Lo [5] GRANTHA SIGN PLUTA..GRANTHA LETTER VOCALIC LL 11362..11363 ; Grapheme_Base # Mc [2] GRANTHA VOWEL SIGN VOCALIC L..GRANTHA VOWEL SIGN VOCALIC LL +11380..11389 ; Grapheme_Base # Lo [10] TULU-TIGALARI LETTER A..TULU-TIGALARI LETTER VOCALIC LL +1138B ; Grapheme_Base # Lo TULU-TIGALARI LETTER EE +1138E ; Grapheme_Base # Lo TULU-TIGALARI LETTER AI +11390..113B5 ; Grapheme_Base # Lo [38] TULU-TIGALARI LETTER OO..TULU-TIGALARI LETTER LLLA +113B7 ; Grapheme_Base # Lo TULU-TIGALARI SIGN AVAGRAHA +113B9..113BA ; Grapheme_Base # Mc [2] TULU-TIGALARI VOWEL SIGN I..TULU-TIGALARI VOWEL SIGN II +113CA ; Grapheme_Base # Mc TULU-TIGALARI SIGN CANDRA ANUNASIKA +113CC..113CD ; Grapheme_Base # Mc [2] TULU-TIGALARI SIGN ANUSVARA..TULU-TIGALARI SIGN VISARGA +113D1 ; Grapheme_Base # Lo TULU-TIGALARI REPHA +113D3 ; Grapheme_Base # Lo TULU-TIGALARI SIGN PLUTA +113D4..113D5 ; Grapheme_Base # Po [2] TULU-TIGALARI DANDA..TULU-TIGALARI DOUBLE DANDA +113D7..113D8 ; Grapheme_Base # Po [2] TULU-TIGALARI SIGN OM PUSHPIKA..TULU-TIGALARI SIGN SHRII PUSHPIKA 11400..11434 ; Grapheme_Base # Lo [53] NEWA LETTER A..NEWA LETTER HA 11435..11437 ; Grapheme_Base # Mc [3] NEWA VOWEL SIGN AA..NEWA VOWEL SIGN II 11440..11441 ; Grapheme_Base # Mc [2] NEWA VOWEL SIGN O..NEWA VOWEL SIGN AU @@ -12186,11 +12460,12 @@ FFFC..FFFD ; Grapheme_Base # So [2] OBJECT REPLACEMENT CHARACTER..REPLACEME 11680..116AA ; Grapheme_Base # Lo [43] TAKRI LETTER A..TAKRI LETTER RRA 116AC ; Grapheme_Base # Mc TAKRI SIGN VISARGA 116AE..116AF ; Grapheme_Base # Mc [2] TAKRI VOWEL SIGN I..TAKRI VOWEL SIGN II -116B6 ; Grapheme_Base # Mc TAKRI SIGN VIRAMA 116B8 ; Grapheme_Base # Lo TAKRI LETTER ARCHAIC KHA 116B9 ; Grapheme_Base # Po TAKRI ABBREVIATION SIGN 116C0..116C9 ; Grapheme_Base # Nd [10] TAKRI DIGIT ZERO..TAKRI DIGIT NINE +116D0..116E3 ; Grapheme_Base # Nd [20] MYANMAR PAO DIGIT ZERO..MYANMAR EASTERN PWO KAREN DIGIT NINE 11700..1171A ; Grapheme_Base # Lo [27] AHOM LETTER KA..AHOM LETTER ALTERNATE BA +1171E ; Grapheme_Base # Mc AHOM CONSONANT SIGN MEDIAL RA 11720..11721 ; Grapheme_Base # Mc [2] AHOM VOWEL SIGN A..AHOM VOWEL SIGN AA 11726 ; Grapheme_Base # Mc AHOM VOWEL SIGN E 11730..11739 ; Grapheme_Base # Nd [10] AHOM DIGIT ZERO..AHOM DIGIT NINE @@ -12212,7 +12487,6 @@ FFFC..FFFD ; Grapheme_Base # So [2] OBJECT REPLACEMENT CHARACTER..REPLACEME 11918..1192F ; Grapheme_Base # Lo [24] DIVES AKURU LETTER DDA..DIVES AKURU LETTER ZA 11931..11935 ; Grapheme_Base # Mc [5] DIVES AKURU VOWEL SIGN I..DIVES AKURU VOWEL SIGN E 11937..11938 ; Grapheme_Base # Mc [2] DIVES AKURU VOWEL SIGN AI..DIVES AKURU VOWEL SIGN O -1193D ; Grapheme_Base # Mc DIVES AKURU SIGN HALANTA 1193F ; Grapheme_Base # Lo DIVES AKURU PREFIXED NASAL SIGN 11940 ; Grapheme_Base # Mc DIVES AKURU MEDIAL YA 11941 ; Grapheme_Base # Lo DIVES AKURU INITIAL RA @@ -12241,6 +12515,9 @@ FFFC..FFFD ; Grapheme_Base # So [2] OBJECT REPLACEMENT CHARACTER..REPLACEME 11A9E..11AA2 ; Grapheme_Base # Po [5] SOYOMBO HEAD MARK WITH MOON AND SUN AND TRIPLE FLAME..SOYOMBO TERMINAL MARK-2 11AB0..11AF8 ; Grapheme_Base # Lo [73] CANADIAN SYLLABICS NATTILIK HI..PAU CIN HAU GLOTTAL STOP FINAL 11B00..11B09 ; Grapheme_Base # Po [10] DEVANAGARI HEAD MARK..DEVANAGARI SIGN MINDU +11BC0..11BE0 ; Grapheme_Base # Lo [33] SUNUWAR LETTER DEVI..SUNUWAR LETTER KLOKO +11BE1 ; Grapheme_Base # Po SUNUWAR SIGN PVO +11BF0..11BF9 ; Grapheme_Base # Nd [10] SUNUWAR DIGIT ZERO..SUNUWAR DIGIT NINE 11C00..11C08 ; Grapheme_Base # Lo [9] BHAIKSUKI LETTER A..BHAIKSUKI LETTER VOCALIC L 11C0A..11C2E ; Grapheme_Base # Lo [37] BHAIKSUKI LETTER E..BHAIKSUKI LETTER HA 11C2F ; Grapheme_Base # Mc BHAIKSUKI VOWEL SIGN AA @@ -12276,7 +12553,6 @@ FFFC..FFFD ; Grapheme_Base # So [2] OBJECT REPLACEMENT CHARACTER..REPLACEME 11F12..11F33 ; Grapheme_Base # Lo [34] KAWI LETTER KA..KAWI LETTER JNYA 11F34..11F35 ; Grapheme_Base # Mc [2] KAWI VOWEL SIGN AA..KAWI VOWEL SIGN ALTERNATE AA 11F3E..11F3F ; Grapheme_Base # Mc [2] KAWI VOWEL SIGN E..KAWI VOWEL SIGN AI -11F41 ; Grapheme_Base # Mc KAWI SIGN KILLER 11F43..11F4F ; Grapheme_Base # Po [13] KAWI DANDA..KAWI PUNCTUATION CLOSING SPIRAL 11F50..11F59 ; Grapheme_Base # Nd [10] KAWI DIGIT ZERO..KAWI DIGIT NINE 11FB0 ; Grapheme_Base # Lo LISU LETTER YHA @@ -12293,7 +12569,11 @@ FFFC..FFFD ; Grapheme_Base # So [2] OBJECT REPLACEMENT CHARACTER..REPLACEME 12FF1..12FF2 ; Grapheme_Base # Po [2] CYPRO-MINOAN SIGN CM301..CYPRO-MINOAN SIGN CM302 13000..1342F ; Grapheme_Base # Lo [1072] EGYPTIAN HIEROGLYPH A001..EGYPTIAN HIEROGLYPH V011D 13441..13446 ; Grapheme_Base # Lo [6] EGYPTIAN HIEROGLYPH FULL BLANK..EGYPTIAN HIEROGLYPH WIDE LOST SIGN +13460..143FA ; Grapheme_Base # Lo [3995] EGYPTIAN HIEROGLYPH-13460..EGYPTIAN HIEROGLYPH-143FA 14400..14646 ; Grapheme_Base # Lo [583] ANATOLIAN HIEROGLYPH A001..ANATOLIAN HIEROGLYPH A530 +16100..1611D ; Grapheme_Base # Lo [30] GURUNG KHEMA LETTER A..GURUNG KHEMA LETTER SA +1612A..1612C ; Grapheme_Base # Mc [3] GURUNG KHEMA CONSONANT SIGN MEDIAL YA..GURUNG KHEMA CONSONANT SIGN MEDIAL HA +16130..16139 ; Grapheme_Base # Nd [10] GURUNG KHEMA DIGIT ZERO..GURUNG KHEMA DIGIT NINE 16800..16A38 ; Grapheme_Base # Lo [569] BAMUM LETTER PHASE-A NGKUE MFON..BAMUM LETTER PHASE-F VUEQ 16A40..16A5E ; Grapheme_Base # Lo [31] MRO LETTER TA..MRO LETTER TEK 16A60..16A69 ; Grapheme_Base # Nd [10] MRO DIGIT ZERO..MRO DIGIT NINE @@ -12312,6 +12592,11 @@ FFFC..FFFD ; Grapheme_Base # So [2] OBJECT REPLACEMENT CHARACTER..REPLACEME 16B5B..16B61 ; Grapheme_Base # No [7] PAHAWH HMONG NUMBER TENS..PAHAWH HMONG NUMBER TRILLIONS 16B63..16B77 ; Grapheme_Base # Lo [21] PAHAWH HMONG SIGN VOS LUB..PAHAWH HMONG SIGN CIM NRES TOS 16B7D..16B8F ; Grapheme_Base # Lo [19] PAHAWH HMONG CLAN SIGN TSHEEJ..PAHAWH HMONG CLAN SIGN VWJ +16D40..16D42 ; Grapheme_Base # Lm [3] KIRAT RAI SIGN ANUSVARA..KIRAT RAI SIGN VISARGA +16D43..16D6A ; Grapheme_Base # Lo [40] KIRAT RAI LETTER A..KIRAT RAI VOWEL SIGN AU +16D6B..16D6C ; Grapheme_Base # Lm [2] KIRAT RAI SIGN VIRAMA..KIRAT RAI SIGN SAAT +16D6D..16D6F ; Grapheme_Base # Po [3] KIRAT RAI SIGN YUPI..KIRAT RAI DOUBLE DANDA +16D70..16D79 ; Grapheme_Base # Nd [10] KIRAT RAI DIGIT ZERO..KIRAT RAI DIGIT NINE 16E40..16E7F ; Grapheme_Base # L& [64] MEDEFAIDRIN CAPITAL LETTER M..MEDEFAIDRIN SMALL LETTER Y 16E80..16E96 ; Grapheme_Base # No [23] MEDEFAIDRIN DIGIT ZERO..MEDEFAIDRIN DIGIT THREE ALTERNATE FORM 16E97..16E9A ; Grapheme_Base # Po [4] MEDEFAIDRIN COMMA..MEDEFAIDRIN EXCLAMATION OH @@ -12322,10 +12607,9 @@ FFFC..FFFD ; Grapheme_Base # So [2] OBJECT REPLACEMENT CHARACTER..REPLACEME 16FE0..16FE1 ; Grapheme_Base # Lm [2] TANGUT ITERATION MARK..NUSHU ITERATION MARK 16FE2 ; Grapheme_Base # Po OLD CHINESE HOOK MARK 16FE3 ; Grapheme_Base # Lm OLD CHINESE ITERATION MARK -16FF0..16FF1 ; Grapheme_Base # Mc [2] VIETNAMESE ALTERNATE READING MARK CA..VIETNAMESE ALTERNATE READING MARK NHAY 17000..187F7 ; Grapheme_Base # Lo [6136] TANGUT IDEOGRAPH-17000..TANGUT IDEOGRAPH-187F7 18800..18CD5 ; Grapheme_Base # Lo [1238] TANGUT COMPONENT-001..KHITAN SMALL SCRIPT CHARACTER-18CD5 -18D00..18D08 ; Grapheme_Base # Lo [9] TANGUT IDEOGRAPH-18D00..TANGUT IDEOGRAPH-18D08 +18CFF..18D08 ; Grapheme_Base # Lo [10] KHITAN SMALL SCRIPT CHARACTER-18CFF..TANGUT IDEOGRAPH-18D08 1AFF0..1AFF3 ; Grapheme_Base # Lm [4] KATAKANA LETTER MINNAN TONE-2..KATAKANA LETTER MINNAN TONE-5 1AFF5..1AFFB ; Grapheme_Base # Lm [7] KATAKANA LETTER MINNAN TONE-7..KATAKANA LETTER MINNAN NASALIZED TONE-5 1AFFD..1AFFE ; Grapheme_Base # Lm [2] KATAKANA LETTER MINNAN NASALIZED TONE-7..KATAKANA LETTER MINNAN NASALIZED TONE-8 @@ -12341,13 +12625,14 @@ FFFC..FFFD ; Grapheme_Base # So [2] OBJECT REPLACEMENT CHARACTER..REPLACEME 1BC90..1BC99 ; Grapheme_Base # Lo [10] DUPLOYAN AFFIX LOW ACUTE..DUPLOYAN AFFIX LOW ARROW 1BC9C ; Grapheme_Base # So DUPLOYAN SIGN O WITH CROSS 1BC9F ; Grapheme_Base # Po DUPLOYAN PUNCTUATION CHINOOK FULL STOP +1CC00..1CCEF ; Grapheme_Base # So [240] UP-POINTING GO-KART..OUTLINED LATIN CAPITAL LETTER Z +1CCF0..1CCF9 ; Grapheme_Base # Nd [10] OUTLINED DIGIT ZERO..OUTLINED DIGIT NINE +1CD00..1CEB3 ; Grapheme_Base # So [436] BLOCK OCTANT-3..BLACK RIGHT TRIANGLE CARET 1CF50..1CFC3 ; Grapheme_Base # So [116] ZNAMENNY NEUME KRYUK..ZNAMENNY NEUME PAUK 1D000..1D0F5 ; Grapheme_Base # So [246] BYZANTINE MUSICAL SYMBOL PSILI..BYZANTINE MUSICAL SYMBOL GORGON NEO KATO 1D100..1D126 ; Grapheme_Base # So [39] MUSICAL SYMBOL SINGLE BARLINE..MUSICAL SYMBOL DRUM CLEF-2 1D129..1D164 ; Grapheme_Base # So [60] MUSICAL SYMBOL MULTIPLE MEASURE REST..MUSICAL SYMBOL ONE HUNDRED TWENTY-EIGHTH NOTE -1D166 ; Grapheme_Base # Mc MUSICAL SYMBOL COMBINING SPRECHGESANG STEM 1D16A..1D16C ; Grapheme_Base # So [3] MUSICAL SYMBOL FINGERED TREMOLO-1..MUSICAL SYMBOL FINGERED TREMOLO-3 -1D16D ; Grapheme_Base # Mc MUSICAL SYMBOL COMBINING AUGMENTATION DOT 1D183..1D184 ; Grapheme_Base # So [2] MUSICAL SYMBOL ARPEGGIATO UP..MUSICAL SYMBOL ARPEGGIATO DOWN 1D18C..1D1A9 ; Grapheme_Base # So [30] MUSICAL SYMBOL RINFORZANDO..MUSICAL SYMBOL DEGREE SLASH 1D1AE..1D1EA ; Grapheme_Base # So [61] MUSICAL SYMBOL PEDAL MARK..MUSICAL SYMBOL KORON @@ -12421,6 +12706,10 @@ FFFC..FFFD ; Grapheme_Base # So [2] OBJECT REPLACEMENT CHARACTER..REPLACEME 1E4D0..1E4EA ; Grapheme_Base # Lo [27] NAG MUNDARI LETTER O..NAG MUNDARI LETTER ELL 1E4EB ; Grapheme_Base # Lm NAG MUNDARI SIGN OJOD 1E4F0..1E4F9 ; Grapheme_Base # Nd [10] NAG MUNDARI DIGIT ZERO..NAG MUNDARI DIGIT NINE +1E5D0..1E5ED ; Grapheme_Base # Lo [30] OL ONAL LETTER O..OL ONAL LETTER EG +1E5F0 ; Grapheme_Base # Lo OL ONAL SIGN HODDOND +1E5F1..1E5FA ; Grapheme_Base # Nd [10] OL ONAL DIGIT ZERO..OL ONAL DIGIT NINE +1E5FF ; Grapheme_Base # Po OL ONAL ABBREVIATION SIGN 1E7E0..1E7E6 ; Grapheme_Base # Lo [7] ETHIOPIC SYLLABLE HHYA..ETHIOPIC SYLLABLE HHYO 1E7E8..1E7EB ; Grapheme_Base # Lo [4] ETHIOPIC SYLLABLE GURAGE HHWA..ETHIOPIC SYLLABLE HHWE 1E7ED..1E7EE ; Grapheme_Base # Lo [2] ETHIOPIC SYLLABLE GURAGE MWI..ETHIOPIC SYLLABLE GURAGE MWEE @@ -12500,18 +12789,18 @@ FFFC..FFFD ; Grapheme_Base # So [2] OBJECT REPLACEMENT CHARACTER..REPLACEME 1F850..1F859 ; Grapheme_Base # So [10] LEFTWARDS SANS-SERIF ARROW..UP DOWN SANS-SERIF ARROW 1F860..1F887 ; Grapheme_Base # So [40] WIDE-HEADED LEFTWARDS LIGHT BARB ARROW..WIDE-HEADED SOUTH WEST VERY HEAVY BARB ARROW 1F890..1F8AD ; Grapheme_Base # So [30] LEFTWARDS TRIANGLE ARROWHEAD..WHITE ARROW SHAFT WIDTH TWO THIRDS -1F8B0..1F8B1 ; Grapheme_Base # So [2] ARROW POINTING UPWARDS THEN NORTH WEST..ARROW POINTING RIGHTWARDS THEN CURVING SOUTH WEST +1F8B0..1F8BB ; Grapheme_Base # So [12] ARROW POINTING UPWARDS THEN NORTH WEST..SOUTH WEST ARROW FROM BAR +1F8C0..1F8C1 ; Grapheme_Base # So [2] LEFTWARDS ARROW FROM DOWNWARDS ARROW..RIGHTWARDS ARROW FROM DOWNWARDS ARROW 1F900..1FA53 ; Grapheme_Base # So [340] CIRCLED CROSS FORMEE WITH FOUR DOTS..BLACK CHESS KNIGHT-BISHOP 1FA60..1FA6D ; Grapheme_Base # So [14] XIANGQI RED GENERAL..XIANGQI BLACK SOLDIER 1FA70..1FA7C ; Grapheme_Base # So [13] BALLET SHOES..CRUTCH -1FA80..1FA88 ; Grapheme_Base # So [9] YO-YO..FLUTE -1FA90..1FABD ; Grapheme_Base # So [46] RINGED PLANET..WING -1FABF..1FAC5 ; Grapheme_Base # So [7] GOOSE..PERSON WITH CROWN -1FACE..1FADB ; Grapheme_Base # So [14] MOOSE..PEA POD -1FAE0..1FAE8 ; Grapheme_Base # So [9] MELTING FACE..SHAKING FACE +1FA80..1FA89 ; Grapheme_Base # So [10] YO-YO..HARP +1FA8F..1FAC6 ; Grapheme_Base # So [56] SHOVEL..FINGERPRINT +1FACE..1FADC ; Grapheme_Base # So [15] MOOSE..ROOT VEGETABLE +1FADF..1FAE9 ; Grapheme_Base # So [11] SPLATTER..FACE WITH BAGS UNDER EYES 1FAF0..1FAF8 ; Grapheme_Base # So [9] HAND WITH INDEX FINGER AND THUMB CROSSED..RIGHTWARDS PUSHING HAND 1FB00..1FB92 ; Grapheme_Base # So [147] BLOCK SEXTANT-1..UPPER HALF INVERSE MEDIUM SHADE AND LOWER HALF BLOCK -1FB94..1FBCA ; Grapheme_Base # So [55] LEFT HALF INVERSE MEDIUM SHADE AND RIGHT HALF BLOCK..WHITE UP-POINTING CHEVRON +1FB94..1FBEF ; Grapheme_Base # So [92] LEFT HALF INVERSE MEDIUM SHADE AND RIGHT HALF BLOCK..TOP LEFT JUSTIFIED LOWER RIGHT QUARTER BLACK CIRCLE 1FBF0..1FBF9 ; Grapheme_Base # Nd [10] SEGMENTED DIGIT ZERO..SEGMENTED DIGIT NINE 20000..2A6DF ; Grapheme_Base # Lo [42720] CJK UNIFIED IDEOGRAPH-20000..CJK UNIFIED IDEOGRAPH-2A6DF 2A700..2B739 ; Grapheme_Base # Lo [4154] CJK UNIFIED IDEOGRAPH-2A700..CJK UNIFIED IDEOGRAPH-2B739 @@ -12523,7 +12812,7 @@ FFFC..FFFD ; Grapheme_Base # So [2] OBJECT REPLACEMENT CHARACTER..REPLACEME 30000..3134A ; Grapheme_Base # Lo [4939] CJK UNIFIED IDEOGRAPH-30000..CJK UNIFIED IDEOGRAPH-3134A 31350..323AF ; Grapheme_Base # Lo [4192] CJK UNIFIED IDEOGRAPH-31350..CJK UNIFIED IDEOGRAPH-323AF -# Total code points: 147613 +# Total code points: 152730 # ================================================ @@ -12573,6 +12862,9 @@ ABED ; Grapheme_Link # Mn MEETEI MAYEK APUN IYEK 11235 ; Grapheme_Link # Mc KHOJKI SIGN VIRAMA 112EA ; Grapheme_Link # Mn KHUDAWADI SIGN VIRAMA 1134D ; Grapheme_Link # Mc GRANTHA SIGN VIRAMA +113CE ; Grapheme_Link # Mn TULU-TIGALARI SIGN VIRAMA +113CF ; Grapheme_Link # Mc TULU-TIGALARI SIGN LOOPED VIRAMA +113D0 ; Grapheme_Link # Mn TULU-TIGALARI CONJOINER 11442 ; Grapheme_Link # Mn NEWA SIGN VIRAMA 114C2 ; Grapheme_Link # Mn TIRHUTA SIGN VIRAMA 115BF ; Grapheme_Link # Mn SIDDHAM SIGN VIRAMA @@ -12591,8 +12883,9 @@ ABED ; Grapheme_Link # Mn MEETEI MAYEK APUN IYEK 11D97 ; Grapheme_Link # Mn GUNJALA GONDI VIRAMA 11F41 ; Grapheme_Link # Mc KAWI SIGN KILLER 11F42 ; Grapheme_Link # Mn KAWI CONJOINER +1612F ; Grapheme_Link # Mn GURUNG KHEMA SIGN THOLHOMA -# Total code points: 65 +# Total code points: 69 # ================================================ @@ -12656,9 +12949,9 @@ ABED ; Grapheme_Link # Mn MEETEI MAYEK APUN IYEK # Indic_Conjunct_Break=Extend -0300..034E ; InCB; Extend # Mn [79] COMBINING GRAVE ACCENT..COMBINING UPWARDS ARROW BELOW -0350..036F ; InCB; Extend # Mn [32] COMBINING RIGHT ARROWHEAD ABOVE..COMBINING LATIN SMALL LETTER X +0300..036F ; InCB; Extend # Mn [112] COMBINING GRAVE ACCENT..COMBINING LATIN SMALL LETTER X 0483..0487 ; InCB; Extend # Mn [5] COMBINING CYRILLIC TITLO..COMBINING CYRILLIC POKRYTIE +0488..0489 ; InCB; Extend # Me [2] COMBINING CYRILLIC HUNDRED THOUSANDS SIGN..COMBINING CYRILLIC MILLIONS SIGN 0591..05BD ; InCB; Extend # Mn [45] HEBREW ACCENT ETNAHTA..HEBREW POINT METEG 05BF ; InCB; Extend # Mn HEBREW POINT RAFE 05C1..05C2 ; InCB; Extend # Mn [2] HEBREW POINT SHIN DOT..HEBREW POINT SIN DOT @@ -12673,6 +12966,7 @@ ABED ; Grapheme_Link # Mn MEETEI MAYEK APUN IYEK 06EA..06ED ; InCB; Extend # Mn [4] ARABIC EMPTY CENTRE LOW STOP..ARABIC SMALL LOW MEEM 0711 ; InCB; Extend # Mn SYRIAC LETTER SUPERSCRIPT ALAPH 0730..074A ; InCB; Extend # Mn [27] SYRIAC PTHAHA ABOVE..SYRIAC BARREKH +07A6..07B0 ; InCB; Extend # Mn [11] THAANA ABAFILI..THAANA SUKUN 07EB..07F3 ; InCB; Extend # Mn [9] NKO COMBINING SHORT HIGH TONE..NKO COMBINING DOUBLE DOT ABOVE 07FD ; InCB; Extend # Mn NKO DANTAYALAN 0816..0819 ; InCB; Extend # Mn [4] SAMARITAN MARK IN..SAMARITAN MARK DAGESH @@ -12680,55 +12974,160 @@ ABED ; Grapheme_Link # Mn MEETEI MAYEK APUN IYEK 0825..0827 ; InCB; Extend # Mn [3] SAMARITAN VOWEL SIGN SHORT A..SAMARITAN VOWEL SIGN U 0829..082D ; InCB; Extend # Mn [5] SAMARITAN VOWEL SIGN LONG I..SAMARITAN MARK NEQUDAA 0859..085B ; InCB; Extend # Mn [3] MANDAIC AFFRICATION MARK..MANDAIC GEMINATION MARK -0898..089F ; InCB; Extend # Mn [8] ARABIC SMALL HIGH WORD AL-JUZ..ARABIC HALF MADDA OVER MADDA +0897..089F ; InCB; Extend # Mn [9] ARABIC PEPET..ARABIC HALF MADDA OVER MADDA 08CA..08E1 ; InCB; Extend # Mn [24] ARABIC SMALL HIGH FARSI YEH..ARABIC SMALL HIGH SIGN SAFHA -08E3..08FF ; InCB; Extend # Mn [29] ARABIC TURNED DAMMA BELOW..ARABIC MARK SIDEWAYS NOON GHUNNA +08E3..0902 ; InCB; Extend # Mn [32] ARABIC TURNED DAMMA BELOW..DEVANAGARI SIGN ANUSVARA +093A ; InCB; Extend # Mn DEVANAGARI VOWEL SIGN OE 093C ; InCB; Extend # Mn DEVANAGARI SIGN NUKTA -0951..0954 ; InCB; Extend # Mn [4] DEVANAGARI STRESS SIGN UDATTA..DEVANAGARI ACUTE ACCENT +0941..0948 ; InCB; Extend # Mn [8] DEVANAGARI VOWEL SIGN U..DEVANAGARI VOWEL SIGN AI +0951..0957 ; InCB; Extend # Mn [7] DEVANAGARI STRESS SIGN UDATTA..DEVANAGARI VOWEL SIGN UUE +0962..0963 ; InCB; Extend # Mn [2] DEVANAGARI VOWEL SIGN VOCALIC L..DEVANAGARI VOWEL SIGN VOCALIC LL +0981 ; InCB; Extend # Mn BENGALI SIGN CANDRABINDU 09BC ; InCB; Extend # Mn BENGALI SIGN NUKTA +09BE ; InCB; Extend # Mc BENGALI VOWEL SIGN AA +09C1..09C4 ; InCB; Extend # Mn [4] BENGALI VOWEL SIGN U..BENGALI VOWEL SIGN VOCALIC RR +09D7 ; InCB; Extend # Mc BENGALI AU LENGTH MARK +09E2..09E3 ; InCB; Extend # Mn [2] BENGALI VOWEL SIGN VOCALIC L..BENGALI VOWEL SIGN VOCALIC LL 09FE ; InCB; Extend # Mn BENGALI SANDHI MARK +0A01..0A02 ; InCB; Extend # Mn [2] GURMUKHI SIGN ADAK BINDI..GURMUKHI SIGN BINDI 0A3C ; InCB; Extend # Mn GURMUKHI SIGN NUKTA +0A41..0A42 ; InCB; Extend # Mn [2] GURMUKHI VOWEL SIGN U..GURMUKHI VOWEL SIGN UU +0A47..0A48 ; InCB; Extend # Mn [2] GURMUKHI VOWEL SIGN EE..GURMUKHI VOWEL SIGN AI +0A4B..0A4D ; InCB; Extend # Mn [3] GURMUKHI VOWEL SIGN OO..GURMUKHI SIGN VIRAMA +0A51 ; InCB; Extend # Mn GURMUKHI SIGN UDAAT +0A70..0A71 ; InCB; Extend # Mn [2] GURMUKHI TIPPI..GURMUKHI ADDAK +0A75 ; InCB; Extend # Mn GURMUKHI SIGN YAKASH +0A81..0A82 ; InCB; Extend # Mn [2] GUJARATI SIGN CANDRABINDU..GUJARATI SIGN ANUSVARA 0ABC ; InCB; Extend # Mn GUJARATI SIGN NUKTA +0AC1..0AC5 ; InCB; Extend # Mn [5] GUJARATI VOWEL SIGN U..GUJARATI VOWEL SIGN CANDRA E +0AC7..0AC8 ; InCB; Extend # Mn [2] GUJARATI VOWEL SIGN E..GUJARATI VOWEL SIGN AI +0AE2..0AE3 ; InCB; Extend # Mn [2] GUJARATI VOWEL SIGN VOCALIC L..GUJARATI VOWEL SIGN VOCALIC LL +0AFA..0AFF ; InCB; Extend # Mn [6] GUJARATI SIGN SUKUN..GUJARATI SIGN TWO-CIRCLE NUKTA ABOVE +0B01 ; InCB; Extend # Mn ORIYA SIGN CANDRABINDU 0B3C ; InCB; Extend # Mn ORIYA SIGN NUKTA +0B3E ; InCB; Extend # Mc ORIYA VOWEL SIGN AA +0B3F ; InCB; Extend # Mn ORIYA VOWEL SIGN I +0B41..0B44 ; InCB; Extend # Mn [4] ORIYA VOWEL SIGN U..ORIYA VOWEL SIGN VOCALIC RR +0B55..0B56 ; InCB; Extend # Mn [2] ORIYA SIGN OVERLINE..ORIYA AI LENGTH MARK +0B57 ; InCB; Extend # Mc ORIYA AU LENGTH MARK +0B62..0B63 ; InCB; Extend # Mn [2] ORIYA VOWEL SIGN VOCALIC L..ORIYA VOWEL SIGN VOCALIC LL +0B82 ; InCB; Extend # Mn TAMIL SIGN ANUSVARA +0BBE ; InCB; Extend # Mc TAMIL VOWEL SIGN AA +0BC0 ; InCB; Extend # Mn TAMIL VOWEL SIGN II +0BCD ; InCB; Extend # Mn TAMIL SIGN VIRAMA +0BD7 ; InCB; Extend # Mc TAMIL AU LENGTH MARK +0C00 ; InCB; Extend # Mn TELUGU SIGN COMBINING CANDRABINDU ABOVE +0C04 ; InCB; Extend # Mn TELUGU SIGN COMBINING ANUSVARA ABOVE 0C3C ; InCB; Extend # Mn TELUGU SIGN NUKTA +0C3E..0C40 ; InCB; Extend # Mn [3] TELUGU VOWEL SIGN AA..TELUGU VOWEL SIGN II +0C46..0C48 ; InCB; Extend # Mn [3] TELUGU VOWEL SIGN E..TELUGU VOWEL SIGN AI +0C4A..0C4C ; InCB; Extend # Mn [3] TELUGU VOWEL SIGN O..TELUGU VOWEL SIGN AU 0C55..0C56 ; InCB; Extend # Mn [2] TELUGU LENGTH MARK..TELUGU AI LENGTH MARK +0C62..0C63 ; InCB; Extend # Mn [2] TELUGU VOWEL SIGN VOCALIC L..TELUGU VOWEL SIGN VOCALIC LL +0C81 ; InCB; Extend # Mn KANNADA SIGN CANDRABINDU 0CBC ; InCB; Extend # Mn KANNADA SIGN NUKTA +0CBF ; InCB; Extend # Mn KANNADA VOWEL SIGN I +0CC0 ; InCB; Extend # Mc KANNADA VOWEL SIGN II +0CC2 ; InCB; Extend # Mc KANNADA VOWEL SIGN UU +0CC6 ; InCB; Extend # Mn KANNADA VOWEL SIGN E +0CC7..0CC8 ; InCB; Extend # Mc [2] KANNADA VOWEL SIGN EE..KANNADA VOWEL SIGN AI +0CCA..0CCB ; InCB; Extend # Mc [2] KANNADA VOWEL SIGN O..KANNADA VOWEL SIGN OO +0CCC..0CCD ; InCB; Extend # Mn [2] KANNADA VOWEL SIGN AU..KANNADA SIGN VIRAMA +0CD5..0CD6 ; InCB; Extend # Mc [2] KANNADA LENGTH MARK..KANNADA AI LENGTH MARK +0CE2..0CE3 ; InCB; Extend # Mn [2] KANNADA VOWEL SIGN VOCALIC L..KANNADA VOWEL SIGN VOCALIC LL +0D00..0D01 ; InCB; Extend # Mn [2] MALAYALAM SIGN COMBINING ANUSVARA ABOVE..MALAYALAM SIGN CANDRABINDU 0D3B..0D3C ; InCB; Extend # Mn [2] MALAYALAM SIGN VERTICAL BAR VIRAMA..MALAYALAM SIGN CIRCULAR VIRAMA -0E38..0E3A ; InCB; Extend # Mn [3] THAI CHARACTER SARA U..THAI CHARACTER PHINTHU -0E48..0E4B ; InCB; Extend # Mn [4] THAI CHARACTER MAI EK..THAI CHARACTER MAI CHATTAWA -0EB8..0EBA ; InCB; Extend # Mn [3] LAO VOWEL SIGN U..LAO SIGN PALI VIRAMA -0EC8..0ECB ; InCB; Extend # Mn [4] LAO TONE MAI EK..LAO TONE MAI CATAWA +0D3E ; InCB; Extend # Mc MALAYALAM VOWEL SIGN AA +0D41..0D44 ; InCB; Extend # Mn [4] MALAYALAM VOWEL SIGN U..MALAYALAM VOWEL SIGN VOCALIC RR +0D57 ; InCB; Extend # Mc MALAYALAM AU LENGTH MARK +0D62..0D63 ; InCB; Extend # Mn [2] MALAYALAM VOWEL SIGN VOCALIC L..MALAYALAM VOWEL SIGN VOCALIC LL +0D81 ; InCB; Extend # Mn SINHALA SIGN CANDRABINDU +0DCA ; InCB; Extend # Mn SINHALA SIGN AL-LAKUNA +0DCF ; InCB; Extend # Mc SINHALA VOWEL SIGN AELA-PILLA +0DD2..0DD4 ; InCB; Extend # Mn [3] SINHALA VOWEL SIGN KETTI IS-PILLA..SINHALA VOWEL SIGN KETTI PAA-PILLA +0DD6 ; InCB; Extend # Mn SINHALA VOWEL SIGN DIGA PAA-PILLA +0DDF ; InCB; Extend # Mc SINHALA VOWEL SIGN GAYANUKITTA +0E31 ; InCB; Extend # Mn THAI CHARACTER MAI HAN-AKAT +0E34..0E3A ; InCB; Extend # Mn [7] THAI CHARACTER SARA I..THAI CHARACTER PHINTHU +0E47..0E4E ; InCB; Extend # Mn [8] THAI CHARACTER MAITAIKHU..THAI CHARACTER YAMAKKAN +0EB1 ; InCB; Extend # Mn LAO VOWEL SIGN MAI KAN +0EB4..0EBC ; InCB; Extend # Mn [9] LAO VOWEL SIGN I..LAO SEMIVOWEL SIGN LO +0EC8..0ECE ; InCB; Extend # Mn [7] LAO TONE MAI EK..LAO YAMAKKAN 0F18..0F19 ; InCB; Extend # Mn [2] TIBETAN ASTROLOGICAL SIGN -KHYUD PA..TIBETAN ASTROLOGICAL SIGN SDONG TSHUGS 0F35 ; InCB; Extend # Mn TIBETAN MARK NGAS BZUNG NYI ZLA 0F37 ; InCB; Extend # Mn TIBETAN MARK NGAS BZUNG SGOR RTAGS 0F39 ; InCB; Extend # Mn TIBETAN MARK TSA -PHRU -0F71..0F72 ; InCB; Extend # Mn [2] TIBETAN VOWEL SIGN AA..TIBETAN VOWEL SIGN I -0F74 ; InCB; Extend # Mn TIBETAN VOWEL SIGN U -0F7A..0F7D ; InCB; Extend # Mn [4] TIBETAN VOWEL SIGN E..TIBETAN VOWEL SIGN OO -0F80 ; InCB; Extend # Mn TIBETAN VOWEL SIGN REVERSED I -0F82..0F84 ; InCB; Extend # Mn [3] TIBETAN SIGN NYI ZLA NAA DA..TIBETAN MARK HALANTA +0F71..0F7E ; InCB; Extend # Mn [14] TIBETAN VOWEL SIGN AA..TIBETAN SIGN RJES SU NGA RO +0F80..0F84 ; InCB; Extend # Mn [5] TIBETAN VOWEL SIGN REVERSED I..TIBETAN MARK HALANTA 0F86..0F87 ; InCB; Extend # Mn [2] TIBETAN SIGN LCI RTAGS..TIBETAN SIGN YANG RTAGS +0F8D..0F97 ; InCB; Extend # Mn [11] TIBETAN SUBJOINED SIGN LCE TSA CAN..TIBETAN SUBJOINED LETTER JA +0F99..0FBC ; InCB; Extend # Mn [36] TIBETAN SUBJOINED LETTER NYA..TIBETAN SUBJOINED LETTER FIXED-FORM RA 0FC6 ; InCB; Extend # Mn TIBETAN SYMBOL PADMA GDAN -1037 ; InCB; Extend # Mn MYANMAR SIGN DOT BELOW +102D..1030 ; InCB; Extend # Mn [4] MYANMAR VOWEL SIGN I..MYANMAR VOWEL SIGN UU +1032..1037 ; InCB; Extend # Mn [6] MYANMAR VOWEL SIGN AI..MYANMAR SIGN DOT BELOW 1039..103A ; InCB; Extend # Mn [2] MYANMAR SIGN VIRAMA..MYANMAR SIGN ASAT +103D..103E ; InCB; Extend # Mn [2] MYANMAR CONSONANT SIGN MEDIAL WA..MYANMAR CONSONANT SIGN MEDIAL HA +1058..1059 ; InCB; Extend # Mn [2] MYANMAR VOWEL SIGN VOCALIC L..MYANMAR VOWEL SIGN VOCALIC LL +105E..1060 ; InCB; Extend # Mn [3] MYANMAR CONSONANT SIGN MON MEDIAL NA..MYANMAR CONSONANT SIGN MON MEDIAL LA +1071..1074 ; InCB; Extend # Mn [4] MYANMAR VOWEL SIGN GEBA KAREN I..MYANMAR VOWEL SIGN KAYAH EE +1082 ; InCB; Extend # Mn MYANMAR CONSONANT SIGN SHAN MEDIAL WA +1085..1086 ; InCB; Extend # Mn [2] MYANMAR VOWEL SIGN SHAN E ABOVE..MYANMAR VOWEL SIGN SHAN FINAL Y 108D ; InCB; Extend # Mn MYANMAR SIGN SHAN COUNCIL EMPHATIC TONE +109D ; InCB; Extend # Mn MYANMAR VOWEL SIGN AITON AI 135D..135F ; InCB; Extend # Mn [3] ETHIOPIC COMBINING GEMINATION AND VOWEL LENGTH MARK..ETHIOPIC COMBINING GEMINATION MARK -1714 ; InCB; Extend # Mn TAGALOG SIGN VIRAMA -17D2 ; InCB; Extend # Mn KHMER SIGN COENG +1712..1714 ; InCB; Extend # Mn [3] TAGALOG VOWEL SIGN I..TAGALOG SIGN VIRAMA +1715 ; InCB; Extend # Mc TAGALOG SIGN PAMUDPOD +1732..1733 ; InCB; Extend # Mn [2] HANUNOO VOWEL SIGN I..HANUNOO VOWEL SIGN U +1734 ; InCB; Extend # Mc HANUNOO SIGN PAMUDPOD +1752..1753 ; InCB; Extend # Mn [2] BUHID VOWEL SIGN I..BUHID VOWEL SIGN U +1772..1773 ; InCB; Extend # Mn [2] TAGBANWA VOWEL SIGN I..TAGBANWA VOWEL SIGN U +17B4..17B5 ; InCB; Extend # Mn [2] KHMER VOWEL INHERENT AQ..KHMER VOWEL INHERENT AA +17B7..17BD ; InCB; Extend # Mn [7] KHMER VOWEL SIGN I..KHMER VOWEL SIGN UA +17C6 ; InCB; Extend # Mn KHMER SIGN NIKAHIT +17C9..17D3 ; InCB; Extend # Mn [11] KHMER SIGN MUUSIKATOAN..KHMER SIGN BATHAMASAT 17DD ; InCB; Extend # Mn KHMER SIGN ATTHACAN +180B..180D ; InCB; Extend # Mn [3] MONGOLIAN FREE VARIATION SELECTOR ONE..MONGOLIAN FREE VARIATION SELECTOR THREE +180F ; InCB; Extend # Mn MONGOLIAN FREE VARIATION SELECTOR FOUR +1885..1886 ; InCB; Extend # Mn [2] MONGOLIAN LETTER ALI GALI BALUDA..MONGOLIAN LETTER ALI GALI THREE BALUDA 18A9 ; InCB; Extend # Mn MONGOLIAN LETTER ALI GALI DAGALGA +1920..1922 ; InCB; Extend # Mn [3] LIMBU VOWEL SIGN A..LIMBU VOWEL SIGN U +1927..1928 ; InCB; Extend # Mn [2] LIMBU VOWEL SIGN E..LIMBU VOWEL SIGN O +1932 ; InCB; Extend # Mn LIMBU SMALL LETTER ANUSVARA 1939..193B ; InCB; Extend # Mn [3] LIMBU SIGN MUKPHRENG..LIMBU SIGN SA-I 1A17..1A18 ; InCB; Extend # Mn [2] BUGINESE VOWEL SIGN I..BUGINESE VOWEL SIGN U +1A1B ; InCB; Extend # Mn BUGINESE VOWEL SIGN AE +1A56 ; InCB; Extend # Mn TAI THAM CONSONANT SIGN MEDIAL LA +1A58..1A5E ; InCB; Extend # Mn [7] TAI THAM SIGN MAI KANG LAI..TAI THAM CONSONANT SIGN SA 1A60 ; InCB; Extend # Mn TAI THAM SIGN SAKOT -1A75..1A7C ; InCB; Extend # Mn [8] TAI THAM SIGN TONE-1..TAI THAM SIGN KHUEN-LUE KARAN +1A62 ; InCB; Extend # Mn TAI THAM VOWEL SIGN MAI SAT +1A65..1A6C ; InCB; Extend # Mn [8] TAI THAM VOWEL SIGN I..TAI THAM VOWEL SIGN OA BELOW +1A73..1A7C ; InCB; Extend # Mn [10] TAI THAM VOWEL SIGN OA ABOVE..TAI THAM SIGN KHUEN-LUE KARAN 1A7F ; InCB; Extend # Mn TAI THAM COMBINING CRYPTOGRAMMIC DOT 1AB0..1ABD ; InCB; Extend # Mn [14] COMBINING DOUBLED CIRCUMFLEX ACCENT..COMBINING PARENTHESES BELOW +1ABE ; InCB; Extend # Me COMBINING PARENTHESES OVERLAY 1ABF..1ACE ; InCB; Extend # Mn [16] COMBINING LATIN SMALL LETTER W BELOW..COMBINING LATIN SMALL LETTER INSULAR T +1B00..1B03 ; InCB; Extend # Mn [4] BALINESE SIGN ULU RICEM..BALINESE SIGN SURANG 1B34 ; InCB; Extend # Mn BALINESE SIGN REREKAN +1B35 ; InCB; Extend # Mc BALINESE VOWEL SIGN TEDUNG +1B36..1B3A ; InCB; Extend # Mn [5] BALINESE VOWEL SIGN ULU..BALINESE VOWEL SIGN RA REPA +1B3B ; InCB; Extend # Mc BALINESE VOWEL SIGN RA REPA TEDUNG +1B3C ; InCB; Extend # Mn BALINESE VOWEL SIGN LA LENGA +1B3D ; InCB; Extend # Mc BALINESE VOWEL SIGN LA LENGA TEDUNG +1B42 ; InCB; Extend # Mn BALINESE VOWEL SIGN PEPET +1B43..1B44 ; InCB; Extend # Mc [2] BALINESE VOWEL SIGN PEPET TEDUNG..BALINESE ADEG ADEG 1B6B..1B73 ; InCB; Extend # Mn [9] BALINESE MUSICAL SYMBOL COMBINING TEGEH..BALINESE MUSICAL SYMBOL COMBINING GONG -1BAB ; InCB; Extend # Mn SUNDANESE SIGN VIRAMA +1B80..1B81 ; InCB; Extend # Mn [2] SUNDANESE SIGN PANYECEK..SUNDANESE SIGN PANGLAYAR +1BA2..1BA5 ; InCB; Extend # Mn [4] SUNDANESE CONSONANT SIGN PANYAKRA..SUNDANESE VOWEL SIGN PANYUKU +1BA8..1BA9 ; InCB; Extend # Mn [2] SUNDANESE VOWEL SIGN PAMEPET..SUNDANESE VOWEL SIGN PANEULEUNG +1BAA ; InCB; Extend # Mc SUNDANESE SIGN PAMAAEH +1BAB..1BAD ; InCB; Extend # Mn [3] SUNDANESE SIGN VIRAMA..SUNDANESE CONSONANT SIGN PASANGAN WA 1BE6 ; InCB; Extend # Mn BATAK SIGN TOMPI -1C37 ; InCB; Extend # Mn LEPCHA SIGN NUKTA +1BE8..1BE9 ; InCB; Extend # Mn [2] BATAK VOWEL SIGN PAKPAK E..BATAK VOWEL SIGN EE +1BED ; InCB; Extend # Mn BATAK VOWEL SIGN KARO O +1BEF..1BF1 ; InCB; Extend # Mn [3] BATAK VOWEL SIGN U FOR SIMALUNGUN SA..BATAK CONSONANT SIGN H +1BF2..1BF3 ; InCB; Extend # Mc [2] BATAK PANGOLAT..BATAK PANONGONAN +1C2C..1C33 ; InCB; Extend # Mn [8] LEPCHA VOWEL SIGN E..LEPCHA CONSONANT SIGN T +1C36..1C37 ; InCB; Extend # Mn [2] LEPCHA SIGN RAN..LEPCHA SIGN NUKTA 1CD0..1CD2 ; InCB; Extend # Mn [3] VEDIC TONE KARSHANA..VEDIC TONE PRENKHA 1CD4..1CE0 ; InCB; Extend # Mn [13] VEDIC SIGN YAJURVEDIC MIDLINE SVARITA..VEDIC TONE RIGVEDIC KASHMIRI INDEPENDENT SVARITA 1CE2..1CE8 ; InCB; Extend # Mn [7] VEDIC SIGN VISARGA SVARITA..VEDIC SIGN VISARGA ANUDATTA WITH TAIL @@ -12738,7 +13137,9 @@ ABED ; Grapheme_Link # Mn MEETEI MAYEK APUN IYEK 1DC0..1DFF ; InCB; Extend # Mn [64] COMBINING DOTTED GRAVE ACCENT..COMBINING RIGHT ARROWHEAD AND DOWN ARROWHEAD BELOW 200D ; InCB; Extend # Cf ZERO WIDTH JOINER 20D0..20DC ; InCB; Extend # Mn [13] COMBINING LEFT HARPOON ABOVE..COMBINING FOUR DOTS ABOVE +20DD..20E0 ; InCB; Extend # Me [4] COMBINING ENCLOSING CIRCLE..COMBINING ENCLOSING CIRCLE BACKSLASH 20E1 ; InCB; Extend # Mn COMBINING LEFT RIGHT ARROW ABOVE +20E2..20E4 ; InCB; Extend # Me [3] COMBINING ENCLOSING SCREEN..COMBINING ENCLOSING UPWARD POINTING TRIANGLE 20E5..20F0 ; InCB; Extend # Mn [12] COMBINING REVERSE SOLIDUS OVERLAY..COMBINING ASTERISK ABOVE 2CEF..2CF1 ; InCB; Extend # Mn [3] COPTIC COMBINING NI ABOVE..COPTIC COMBINING SPIRITUS LENIS 2D7F ; InCB; Extend # Mn TIFINAGH CONSONANT JOINER @@ -12747,73 +13148,198 @@ ABED ; Grapheme_Link # Mn MEETEI MAYEK APUN IYEK 302E..302F ; InCB; Extend # Mc [2] HANGUL SINGLE DOT TONE MARK..HANGUL DOUBLE DOT TONE MARK 3099..309A ; InCB; Extend # Mn [2] COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK..COMBINING KATAKANA-HIRAGANA SEMI-VOICED SOUND MARK A66F ; InCB; Extend # Mn COMBINING CYRILLIC VZMET +A670..A672 ; InCB; Extend # Me [3] COMBINING CYRILLIC TEN MILLIONS SIGN..COMBINING CYRILLIC THOUSAND MILLIONS SIGN A674..A67D ; InCB; Extend # Mn [10] COMBINING CYRILLIC LETTER UKRAINIAN IE..COMBINING CYRILLIC PAYEROK A69E..A69F ; InCB; Extend # Mn [2] COMBINING CYRILLIC LETTER EF..COMBINING CYRILLIC LETTER IOTIFIED E A6F0..A6F1 ; InCB; Extend # Mn [2] BAMUM COMBINING MARK KOQNDON..BAMUM COMBINING MARK TUKWENTIS +A802 ; InCB; Extend # Mn SYLOTI NAGRI SIGN DVISVARA +A806 ; InCB; Extend # Mn SYLOTI NAGRI SIGN HASANTA +A80B ; InCB; Extend # Mn SYLOTI NAGRI SIGN ANUSVARA +A825..A826 ; InCB; Extend # Mn [2] SYLOTI NAGRI VOWEL SIGN U..SYLOTI NAGRI VOWEL SIGN E A82C ; InCB; Extend # Mn SYLOTI NAGRI SIGN ALTERNATE HASANTA +A8C4..A8C5 ; InCB; Extend # Mn [2] SAURASHTRA SIGN VIRAMA..SAURASHTRA SIGN CANDRABINDU A8E0..A8F1 ; InCB; Extend # Mn [18] COMBINING DEVANAGARI DIGIT ZERO..COMBINING DEVANAGARI SIGN AVAGRAHA -A92B..A92D ; InCB; Extend # Mn [3] KAYAH LI TONE PLOPHU..KAYAH LI TONE CALYA PLOPHU +A8FF ; InCB; Extend # Mn DEVANAGARI VOWEL SIGN AY +A926..A92D ; InCB; Extend # Mn [8] KAYAH LI VOWEL UE..KAYAH LI TONE CALYA PLOPHU +A947..A951 ; InCB; Extend # Mn [11] REJANG VOWEL SIGN I..REJANG CONSONANT SIGN R +A953 ; InCB; Extend # Mc REJANG VIRAMA +A980..A982 ; InCB; Extend # Mn [3] JAVANESE SIGN PANYANGGA..JAVANESE SIGN LAYAR A9B3 ; InCB; Extend # Mn JAVANESE SIGN CECAK TELU +A9B6..A9B9 ; InCB; Extend # Mn [4] JAVANESE VOWEL SIGN WULU..JAVANESE VOWEL SIGN SUKU MENDUT +A9BC..A9BD ; InCB; Extend # Mn [2] JAVANESE VOWEL SIGN PEPET..JAVANESE CONSONANT SIGN KERET +A9C0 ; InCB; Extend # Mc JAVANESE PANGKON +A9E5 ; InCB; Extend # Mn MYANMAR SIGN SHAN SAW +AA29..AA2E ; InCB; Extend # Mn [6] CHAM VOWEL SIGN AA..CHAM VOWEL SIGN OE +AA31..AA32 ; InCB; Extend # Mn [2] CHAM VOWEL SIGN AU..CHAM VOWEL SIGN UE +AA35..AA36 ; InCB; Extend # Mn [2] CHAM CONSONANT SIGN LA..CHAM CONSONANT SIGN WA +AA43 ; InCB; Extend # Mn CHAM CONSONANT SIGN FINAL NG +AA4C ; InCB; Extend # Mn CHAM CONSONANT SIGN FINAL M +AA7C ; InCB; Extend # Mn MYANMAR SIGN TAI LAING TONE-2 AAB0 ; InCB; Extend # Mn TAI VIET MAI KANG AAB2..AAB4 ; InCB; Extend # Mn [3] TAI VIET VOWEL I..TAI VIET VOWEL U AAB7..AAB8 ; InCB; Extend # Mn [2] TAI VIET MAI KHIT..TAI VIET VOWEL IA AABE..AABF ; InCB; Extend # Mn [2] TAI VIET VOWEL AM..TAI VIET TONE MAI EK AAC1 ; InCB; Extend # Mn TAI VIET TONE MAI THO +AAEC..AAED ; InCB; Extend # Mn [2] MEETEI MAYEK VOWEL SIGN UU..MEETEI MAYEK VOWEL SIGN AAI AAF6 ; InCB; Extend # Mn MEETEI MAYEK VIRAMA +ABE5 ; InCB; Extend # Mn MEETEI MAYEK VOWEL SIGN ANAP +ABE8 ; InCB; Extend # Mn MEETEI MAYEK VOWEL SIGN UNAP ABED ; InCB; Extend # Mn MEETEI MAYEK APUN IYEK FB1E ; InCB; Extend # Mn HEBREW POINT JUDEO-SPANISH VARIKA +FE00..FE0F ; InCB; Extend # Mn [16] VARIATION SELECTOR-1..VARIATION SELECTOR-16 FE20..FE2F ; InCB; Extend # Mn [16] COMBINING LIGATURE LEFT HALF..COMBINING CYRILLIC TITLO RIGHT HALF +FF9E..FF9F ; InCB; Extend # Lm [2] HALFWIDTH KATAKANA VOICED SOUND MARK..HALFWIDTH KATAKANA SEMI-VOICED SOUND MARK 101FD ; InCB; Extend # Mn PHAISTOS DISC SIGN COMBINING OBLIQUE STROKE 102E0 ; InCB; Extend # Mn COPTIC EPACT THOUSANDS MARK 10376..1037A ; InCB; Extend # Mn [5] COMBINING OLD PERMIC LETTER AN..COMBINING OLD PERMIC LETTER SII -10A0D ; InCB; Extend # Mn KHAROSHTHI SIGN DOUBLE RING BELOW -10A0F ; InCB; Extend # Mn KHAROSHTHI SIGN VISARGA +10A01..10A03 ; InCB; Extend # Mn [3] KHAROSHTHI VOWEL SIGN I..KHAROSHTHI VOWEL SIGN VOCALIC R +10A05..10A06 ; InCB; Extend # Mn [2] KHAROSHTHI VOWEL SIGN E..KHAROSHTHI VOWEL SIGN O +10A0C..10A0F ; InCB; Extend # Mn [4] KHAROSHTHI VOWEL LENGTH MARK..KHAROSHTHI SIGN VISARGA 10A38..10A3A ; InCB; Extend # Mn [3] KHAROSHTHI SIGN BAR ABOVE..KHAROSHTHI SIGN DOT BELOW 10A3F ; InCB; Extend # Mn KHAROSHTHI VIRAMA 10AE5..10AE6 ; InCB; Extend # Mn [2] MANICHAEAN ABBREVIATION MARK ABOVE..MANICHAEAN ABBREVIATION MARK BELOW 10D24..10D27 ; InCB; Extend # Mn [4] HANIFI ROHINGYA SIGN HARBAHAY..HANIFI ROHINGYA SIGN TASSI +10D69..10D6D ; InCB; Extend # Mn [5] GARAY VOWEL SIGN E..GARAY CONSONANT NASALIZATION MARK 10EAB..10EAC ; InCB; Extend # Mn [2] YEZIDI COMBINING HAMZA MARK..YEZIDI COMBINING MADDA MARK -10EFD..10EFF ; InCB; Extend # Mn [3] ARABIC SMALL LOW WORD SAKTA..ARABIC SMALL LOW WORD MADDA +10EFC..10EFF ; InCB; Extend # Mn [4] ARABIC COMBINING ALEF OVERLAY..ARABIC SMALL LOW WORD MADDA 10F46..10F50 ; InCB; Extend # Mn [11] SOGDIAN COMBINING DOT BELOW..SOGDIAN COMBINING STROKE BELOW 10F82..10F85 ; InCB; Extend # Mn [4] OLD UYGHUR COMBINING DOT ABOVE..OLD UYGHUR COMBINING TWO DOTS BELOW +11001 ; InCB; Extend # Mn BRAHMI SIGN ANUSVARA +11038..11046 ; InCB; Extend # Mn [15] BRAHMI VOWEL SIGN AA..BRAHMI VIRAMA 11070 ; InCB; Extend # Mn BRAHMI SIGN OLD TAMIL VIRAMA -1107F ; InCB; Extend # Mn BRAHMI NUMBER JOINER -110BA ; InCB; Extend # Mn KAITHI SIGN NUKTA +11073..11074 ; InCB; Extend # Mn [2] BRAHMI VOWEL SIGN OLD TAMIL SHORT E..BRAHMI VOWEL SIGN OLD TAMIL SHORT O +1107F..11081 ; InCB; Extend # Mn [3] BRAHMI NUMBER JOINER..KAITHI SIGN ANUSVARA +110B3..110B6 ; InCB; Extend # Mn [4] KAITHI VOWEL SIGN U..KAITHI VOWEL SIGN AI +110B9..110BA ; InCB; Extend # Mn [2] KAITHI SIGN VIRAMA..KAITHI SIGN NUKTA +110C2 ; InCB; Extend # Mn KAITHI VOWEL SIGN VOCALIC R 11100..11102 ; InCB; Extend # Mn [3] CHAKMA SIGN CANDRABINDU..CHAKMA SIGN VISARGA -11133..11134 ; InCB; Extend # Mn [2] CHAKMA VIRAMA..CHAKMA MAAYYAA +11127..1112B ; InCB; Extend # Mn [5] CHAKMA VOWEL SIGN A..CHAKMA VOWEL SIGN UU +1112D..11134 ; InCB; Extend # Mn [8] CHAKMA VOWEL SIGN AI..CHAKMA MAAYYAA 11173 ; InCB; Extend # Mn MAHAJANI SIGN NUKTA -111CA ; InCB; Extend # Mn SHARADA SIGN NUKTA -11236 ; InCB; Extend # Mn KHOJKI SIGN NUKTA -112E9..112EA ; InCB; Extend # Mn [2] KHUDAWADI SIGN NUKTA..KHUDAWADI SIGN VIRAMA +11180..11181 ; InCB; Extend # Mn [2] SHARADA SIGN CANDRABINDU..SHARADA SIGN ANUSVARA +111B6..111BE ; InCB; Extend # Mn [9] SHARADA VOWEL SIGN U..SHARADA VOWEL SIGN O +111C0 ; InCB; Extend # Mc SHARADA SIGN VIRAMA +111C9..111CC ; InCB; Extend # Mn [4] SHARADA SANDHI MARK..SHARADA EXTRA SHORT VOWEL MARK +111CF ; InCB; Extend # Mn SHARADA SIGN INVERTED CANDRABINDU +1122F..11231 ; InCB; Extend # Mn [3] KHOJKI VOWEL SIGN U..KHOJKI VOWEL SIGN AI +11234 ; InCB; Extend # Mn KHOJKI SIGN ANUSVARA +11235 ; InCB; Extend # Mc KHOJKI SIGN VIRAMA +11236..11237 ; InCB; Extend # Mn [2] KHOJKI SIGN NUKTA..KHOJKI SIGN SHADDA +1123E ; InCB; Extend # Mn KHOJKI SIGN SUKUN +11241 ; InCB; Extend # Mn KHOJKI VOWEL SIGN VOCALIC R +112DF ; InCB; Extend # Mn KHUDAWADI SIGN ANUSVARA +112E3..112EA ; InCB; Extend # Mn [8] KHUDAWADI VOWEL SIGN U..KHUDAWADI SIGN VIRAMA +11300..11301 ; InCB; Extend # Mn [2] GRANTHA SIGN COMBINING ANUSVARA ABOVE..GRANTHA SIGN CANDRABINDU 1133B..1133C ; InCB; Extend # Mn [2] COMBINING BINDU BELOW..GRANTHA SIGN NUKTA +1133E ; InCB; Extend # Mc GRANTHA VOWEL SIGN AA +11340 ; InCB; Extend # Mn GRANTHA VOWEL SIGN II +1134D ; InCB; Extend # Mc GRANTHA SIGN VIRAMA +11357 ; InCB; Extend # Mc GRANTHA AU LENGTH MARK 11366..1136C ; InCB; Extend # Mn [7] COMBINING GRANTHA DIGIT ZERO..COMBINING GRANTHA DIGIT SIX 11370..11374 ; InCB; Extend # Mn [5] COMBINING GRANTHA LETTER A..COMBINING GRANTHA LETTER PA +113B8 ; InCB; Extend # Mc TULU-TIGALARI VOWEL SIGN AA +113BB..113C0 ; InCB; Extend # Mn [6] TULU-TIGALARI VOWEL SIGN U..TULU-TIGALARI VOWEL SIGN VOCALIC LL +113C2 ; InCB; Extend # Mc TULU-TIGALARI VOWEL SIGN EE +113C5 ; InCB; Extend # Mc TULU-TIGALARI VOWEL SIGN AI +113C7..113C9 ; InCB; Extend # Mc [3] TULU-TIGALARI VOWEL SIGN OO..TULU-TIGALARI AU LENGTH MARK +113CE ; InCB; Extend # Mn TULU-TIGALARI SIGN VIRAMA +113CF ; InCB; Extend # Mc TULU-TIGALARI SIGN LOOPED VIRAMA +113D0 ; InCB; Extend # Mn TULU-TIGALARI CONJOINER +113D2 ; InCB; Extend # Mn TULU-TIGALARI GEMINATION MARK +113E1..113E2 ; InCB; Extend # Mn [2] TULU-TIGALARI VEDIC TONE SVARITA..TULU-TIGALARI VEDIC TONE ANUDATTA +11438..1143F ; InCB; Extend # Mn [8] NEWA VOWEL SIGN U..NEWA VOWEL SIGN AI +11442..11444 ; InCB; Extend # Mn [3] NEWA SIGN VIRAMA..NEWA SIGN ANUSVARA 11446 ; InCB; Extend # Mn NEWA SIGN NUKTA 1145E ; InCB; Extend # Mn NEWA SANDHI MARK -114C3 ; InCB; Extend # Mn TIRHUTA SIGN NUKTA -115C0 ; InCB; Extend # Mn SIDDHAM SIGN NUKTA +114B0 ; InCB; Extend # Mc TIRHUTA VOWEL SIGN AA +114B3..114B8 ; InCB; Extend # Mn [6] TIRHUTA VOWEL SIGN U..TIRHUTA VOWEL SIGN VOCALIC LL +114BA ; InCB; Extend # Mn TIRHUTA VOWEL SIGN SHORT E +114BD ; InCB; Extend # Mc TIRHUTA VOWEL SIGN SHORT O +114BF..114C0 ; InCB; Extend # Mn [2] TIRHUTA SIGN CANDRABINDU..TIRHUTA SIGN ANUSVARA +114C2..114C3 ; InCB; Extend # Mn [2] TIRHUTA SIGN VIRAMA..TIRHUTA SIGN NUKTA +115AF ; InCB; Extend # Mc SIDDHAM VOWEL SIGN AA +115B2..115B5 ; InCB; Extend # Mn [4] SIDDHAM VOWEL SIGN U..SIDDHAM VOWEL SIGN VOCALIC RR +115BC..115BD ; InCB; Extend # Mn [2] SIDDHAM SIGN CANDRABINDU..SIDDHAM SIGN ANUSVARA +115BF..115C0 ; InCB; Extend # Mn [2] SIDDHAM SIGN VIRAMA..SIDDHAM SIGN NUKTA +115DC..115DD ; InCB; Extend # Mn [2] SIDDHAM VOWEL SIGN ALTERNATE U..SIDDHAM VOWEL SIGN ALTERNATE UU +11633..1163A ; InCB; Extend # Mn [8] MODI VOWEL SIGN U..MODI VOWEL SIGN AI +1163D ; InCB; Extend # Mn MODI SIGN ANUSVARA +1163F..11640 ; InCB; Extend # Mn [2] MODI SIGN VIRAMA..MODI SIGN ARDHACANDRA +116AB ; InCB; Extend # Mn TAKRI SIGN ANUSVARA +116AD ; InCB; Extend # Mn TAKRI VOWEL SIGN AA +116B0..116B5 ; InCB; Extend # Mn [6] TAKRI VOWEL SIGN U..TAKRI VOWEL SIGN AU +116B6 ; InCB; Extend # Mc TAKRI SIGN VIRAMA 116B7 ; InCB; Extend # Mn TAKRI SIGN NUKTA -1172B ; InCB; Extend # Mn AHOM SIGN KILLER -1183A ; InCB; Extend # Mn DOGRA SIGN NUKTA +1171D ; InCB; Extend # Mn AHOM CONSONANT SIGN MEDIAL LA +1171F ; InCB; Extend # Mn AHOM CONSONANT SIGN MEDIAL LIGATING RA +11722..11725 ; InCB; Extend # Mn [4] AHOM VOWEL SIGN I..AHOM VOWEL SIGN UU +11727..1172B ; InCB; Extend # Mn [5] AHOM VOWEL SIGN AW..AHOM SIGN KILLER +1182F..11837 ; InCB; Extend # Mn [9] DOGRA VOWEL SIGN U..DOGRA SIGN ANUSVARA +11839..1183A ; InCB; Extend # Mn [2] DOGRA SIGN VIRAMA..DOGRA SIGN NUKTA +11930 ; InCB; Extend # Mc DIVES AKURU VOWEL SIGN AA +1193B..1193C ; InCB; Extend # Mn [2] DIVES AKURU SIGN ANUSVARA..DIVES AKURU SIGN CANDRABINDU +1193D ; InCB; Extend # Mc DIVES AKURU SIGN HALANTA 1193E ; InCB; Extend # Mn DIVES AKURU VIRAMA 11943 ; InCB; Extend # Mn DIVES AKURU SIGN NUKTA -11A34 ; InCB; Extend # Mn ZANABAZAR SQUARE SIGN VIRAMA +119D4..119D7 ; InCB; Extend # Mn [4] NANDINAGARI VOWEL SIGN U..NANDINAGARI VOWEL SIGN VOCALIC RR +119DA..119DB ; InCB; Extend # Mn [2] NANDINAGARI VOWEL SIGN E..NANDINAGARI VOWEL SIGN AI +119E0 ; InCB; Extend # Mn NANDINAGARI SIGN VIRAMA +11A01..11A0A ; InCB; Extend # Mn [10] ZANABAZAR SQUARE VOWEL SIGN I..ZANABAZAR SQUARE VOWEL LENGTH MARK +11A33..11A38 ; InCB; Extend # Mn [6] ZANABAZAR SQUARE FINAL CONSONANT MARK..ZANABAZAR SQUARE SIGN ANUSVARA +11A3B..11A3E ; InCB; Extend # Mn [4] ZANABAZAR SQUARE CLUSTER-FINAL LETTER YA..ZANABAZAR SQUARE CLUSTER-FINAL LETTER VA 11A47 ; InCB; Extend # Mn ZANABAZAR SQUARE SUBJOINER -11A99 ; InCB; Extend # Mn SOYOMBO SUBJOINER -11D42 ; InCB; Extend # Mn MASARAM GONDI SIGN NUKTA -11D44..11D45 ; InCB; Extend # Mn [2] MASARAM GONDI SIGN HALANTA..MASARAM GONDI VIRAMA +11A51..11A56 ; InCB; Extend # Mn [6] SOYOMBO VOWEL SIGN I..SOYOMBO VOWEL SIGN OE +11A59..11A5B ; InCB; Extend # Mn [3] SOYOMBO VOWEL SIGN VOCALIC R..SOYOMBO VOWEL LENGTH MARK +11A8A..11A96 ; InCB; Extend # Mn [13] SOYOMBO FINAL CONSONANT SIGN G..SOYOMBO SIGN ANUSVARA +11A98..11A99 ; InCB; Extend # Mn [2] SOYOMBO GEMINATION MARK..SOYOMBO SUBJOINER +11C30..11C36 ; InCB; Extend # Mn [7] BHAIKSUKI VOWEL SIGN I..BHAIKSUKI VOWEL SIGN VOCALIC L +11C38..11C3D ; InCB; Extend # Mn [6] BHAIKSUKI VOWEL SIGN E..BHAIKSUKI SIGN ANUSVARA +11C3F ; InCB; Extend # Mn BHAIKSUKI SIGN VIRAMA +11C92..11CA7 ; InCB; Extend # Mn [22] MARCHEN SUBJOINED LETTER KA..MARCHEN SUBJOINED LETTER ZA +11CAA..11CB0 ; InCB; Extend # Mn [7] MARCHEN SUBJOINED LETTER RA..MARCHEN VOWEL SIGN AA +11CB2..11CB3 ; InCB; Extend # Mn [2] MARCHEN VOWEL SIGN U..MARCHEN VOWEL SIGN E +11CB5..11CB6 ; InCB; Extend # Mn [2] MARCHEN SIGN ANUSVARA..MARCHEN SIGN CANDRABINDU +11D31..11D36 ; InCB; Extend # Mn [6] MASARAM GONDI VOWEL SIGN AA..MASARAM GONDI VOWEL SIGN VOCALIC R +11D3A ; InCB; Extend # Mn MASARAM GONDI VOWEL SIGN E +11D3C..11D3D ; InCB; Extend # Mn [2] MASARAM GONDI VOWEL SIGN AI..MASARAM GONDI VOWEL SIGN O +11D3F..11D45 ; InCB; Extend # Mn [7] MASARAM GONDI VOWEL SIGN AU..MASARAM GONDI VIRAMA +11D47 ; InCB; Extend # Mn MASARAM GONDI RA-KARA +11D90..11D91 ; InCB; Extend # Mn [2] GUNJALA GONDI VOWEL SIGN EE..GUNJALA GONDI VOWEL SIGN AI +11D95 ; InCB; Extend # Mn GUNJALA GONDI SIGN ANUSVARA 11D97 ; InCB; Extend # Mn GUNJALA GONDI VIRAMA +11EF3..11EF4 ; InCB; Extend # Mn [2] MAKASAR VOWEL SIGN I..MAKASAR VOWEL SIGN U +11F00..11F01 ; InCB; Extend # Mn [2] KAWI SIGN CANDRABINDU..KAWI SIGN ANUSVARA +11F36..11F3A ; InCB; Extend # Mn [5] KAWI VOWEL SIGN I..KAWI VOWEL SIGN VOCALIC R +11F40 ; InCB; Extend # Mn KAWI VOWEL SIGN EU +11F41 ; InCB; Extend # Mc KAWI SIGN KILLER 11F42 ; InCB; Extend # Mn KAWI CONJOINER +11F5A ; InCB; Extend # Mn KAWI SIGN NUKTA +13440 ; InCB; Extend # Mn EGYPTIAN HIEROGLYPH MIRROR HORIZONTALLY +13447..13455 ; InCB; Extend # Mn [15] EGYPTIAN HIEROGLYPH MODIFIER DAMAGED AT TOP START..EGYPTIAN HIEROGLYPH MODIFIER DAMAGED +1611E..16129 ; InCB; Extend # Mn [12] GURUNG KHEMA VOWEL SIGN AA..GURUNG KHEMA VOWEL LENGTH MARK +1612D..1612F ; InCB; Extend # Mn [3] GURUNG KHEMA SIGN ANUSVARA..GURUNG KHEMA SIGN THOLHOMA 16AF0..16AF4 ; InCB; Extend # Mn [5] BASSA VAH COMBINING HIGH TONE..BASSA VAH COMBINING HIGH-LOW TONE 16B30..16B36 ; InCB; Extend # Mn [7] PAHAWH HMONG MARK CIM TUB..PAHAWH HMONG MARK CIM TAUM -1BC9E ; InCB; Extend # Mn DUPLOYAN DOUBLE MARK -1D165 ; InCB; Extend # Mc MUSICAL SYMBOL COMBINING STEM +16F4F ; InCB; Extend # Mn MIAO SIGN CONSONANT MODIFIER BAR +16F8F..16F92 ; InCB; Extend # Mn [4] MIAO TONE RIGHT..MIAO TONE BELOW +16FE4 ; InCB; Extend # Mn KHITAN SMALL SCRIPT FILLER +16FF0..16FF1 ; InCB; Extend # Mc [2] VIETNAMESE ALTERNATE READING MARK CA..VIETNAMESE ALTERNATE READING MARK NHAY +1BC9D..1BC9E ; InCB; Extend # Mn [2] DUPLOYAN THICK LETTER SELECTOR..DUPLOYAN DOUBLE MARK +1CF00..1CF2D ; InCB; Extend # Mn [46] ZNAMENNY COMBINING MARK GORAZDO NIZKO S KRYZHEM ON LEFT..ZNAMENNY COMBINING MARK KRYZH ON LEFT +1CF30..1CF46 ; InCB; Extend # Mn [23] ZNAMENNY COMBINING TONAL RANGE MARK MRACHNO..ZNAMENNY PRIZNAK MODIFIER ROG +1D165..1D166 ; InCB; Extend # Mc [2] MUSICAL SYMBOL COMBINING STEM..MUSICAL SYMBOL COMBINING SPRECHGESANG STEM 1D167..1D169 ; InCB; Extend # Mn [3] MUSICAL SYMBOL COMBINING TREMOLO-1..MUSICAL SYMBOL COMBINING TREMOLO-3 -1D16E..1D172 ; InCB; Extend # Mc [5] MUSICAL SYMBOL COMBINING FLAG-1..MUSICAL SYMBOL COMBINING FLAG-5 +1D16D..1D172 ; InCB; Extend # Mc [6] MUSICAL SYMBOL COMBINING AUGMENTATION DOT..MUSICAL SYMBOL COMBINING FLAG-5 1D17B..1D182 ; InCB; Extend # Mn [8] MUSICAL SYMBOL COMBINING ACCENT..MUSICAL SYMBOL COMBINING LOURE 1D185..1D18B ; InCB; Extend # Mn [7] MUSICAL SYMBOL COMBINING DOIT..MUSICAL SYMBOL COMBINING TRIPLE TONGUE 1D1AA..1D1AD ; InCB; Extend # Mn [4] MUSICAL SYMBOL COMBINING DOWN BOW..MUSICAL SYMBOL COMBINING SNAP PIZZICATO 1D242..1D244 ; InCB; Extend # Mn [3] COMBINING GREEK MUSICAL TRISEME..COMBINING GREEK MUSICAL PENTASEME +1DA00..1DA36 ; InCB; Extend # Mn [55] SIGNWRITING HEAD RIM..SIGNWRITING AIR SUCKING IN +1DA3B..1DA6C ; InCB; Extend # Mn [50] SIGNWRITING MOUTH CLOSED NEUTRAL..SIGNWRITING EXCITEMENT +1DA75 ; InCB; Extend # Mn SIGNWRITING UPPER BODY TILTING FROM HIP JOINTS +1DA84 ; InCB; Extend # Mn SIGNWRITING LOCATION HEAD NECK +1DA9B..1DA9F ; InCB; Extend # Mn [5] SIGNWRITING FILL MODIFIER-2..SIGNWRITING FILL MODIFIER-6 +1DAA1..1DAAF ; InCB; Extend # Mn [15] SIGNWRITING ROTATION MODIFIER-2..SIGNWRITING ROTATION MODIFIER-16 1E000..1E006 ; InCB; Extend # Mn [7] COMBINING GLAGOLITIC LETTER AZU..COMBINING GLAGOLITIC LETTER ZHIVETE 1E008..1E018 ; InCB; Extend # Mn [17] COMBINING GLAGOLITIC LETTER ZEMLJA..COMBINING GLAGOLITIC LETTER HERU 1E01B..1E021 ; InCB; Extend # Mn [7] COMBINING GLAGOLITIC LETTER SHTA..COMBINING GLAGOLITIC LETTER YATI @@ -12824,9 +13350,13 @@ FE20..FE2F ; InCB; Extend # Mn [16] COMBINING LIGATURE LEFT HALF..COMBINING 1E2AE ; InCB; Extend # Mn TOTO SIGN RISING TONE 1E2EC..1E2EF ; InCB; Extend # Mn [4] WANCHO TONE TUP..WANCHO TONE KOINI 1E4EC..1E4EF ; InCB; Extend # Mn [4] NAG MUNDARI SIGN MUHOR..NAG MUNDARI SIGN SUTUH +1E5EE..1E5EF ; InCB; Extend # Mn [2] OL ONAL SIGN MU..OL ONAL SIGN IKIR 1E8D0..1E8D6 ; InCB; Extend # Mn [7] MENDE KIKAKUI COMBINING NUMBER TEENS..MENDE KIKAKUI COMBINING NUMBER MILLIONS 1E944..1E94A ; InCB; Extend # Mn [7] ADLAM ALIF LENGTHENER..ADLAM NUKTA +1F3FB..1F3FF ; InCB; Extend # Sk [5] EMOJI MODIFIER FITZPATRICK TYPE-1-2..EMOJI MODIFIER FITZPATRICK TYPE-6 +E0020..E007F ; InCB; Extend # Cf [96] TAG SPACE..CANCEL TAG +E0100..E01EF ; InCB; Extend # Mn [240] VARIATION SELECTOR-17..VARIATION SELECTOR-256 -# Total code points: 884 +# Total code points: 2192 # EOF diff --git a/src/java.base/share/data/unicodedata/NormalizationTest.txt b/src/java.base/share/data/unicodedata/NormalizationTest.txt index 968386d3672..093de82c565 100644 --- a/src/java.base/share/data/unicodedata/NormalizationTest.txt +++ b/src/java.base/share/data/unicodedata/NormalizationTest.txt @@ -1,8 +1,8 @@ -# NormalizationTest-15.1.0.txt -# Date: 2023-01-05, 20:34:44 GMT -# Copyright (c) 2023 Unicode, Inc. +# NormalizationTest-16.0.0.txt +# Date: 2024-04-30, 21:48:23 GMT +# Copyright (c) 2024 Unicode, Inc. # Unicode and the Unicode Logo are registered trademarks of Unicode, Inc. in the U.S. and other countries. -# For terms of use, see https://www.unicode.org/terms_of_use.html +# For terms of use and license, see https://www.unicode.org/terms_of_use.html # # Unicode Character Database # For documentation, see https://www.unicode.org/reports/tr44/ @@ -66,6 +66,26 @@ 0592 05B7 05BC 05A5 05B0 05C0 05C4 05AD;05B0 05B7 05BC 05A5 0592 05C0 05AD 05C4;05B0 05B7 05BC 05A5 0592 05C0 05AD 05C4;05B0 05B7 05BC 05A5 0592 05C0 05AD 05C4;05B0 05B7 05BC 05A5 0592 05C0 05AD 05C4; # (◌֒◌ַ◌ּ◌֥◌ְ׀◌ׄ◌֭; ◌ְ◌ַ◌ּ◌֥◌֒׀◌֭◌ׄ; ◌ְ◌ַ◌ּ◌֥◌֒׀◌֭◌ׄ; ◌ְ◌ַ◌ּ◌֥◌֒׀◌֭◌ׄ; ◌ְ◌ַ◌ּ◌֥◌֒׀◌֭◌ׄ; ) HEBREW ACCENT SEGOL, HEBREW POINT PATAH, HEBREW POINT DAGESH OR MAPIQ, HEBREW ACCENT MERKHA, HEBREW POINT SHEVA, HEBREW PUNCTUATION PASEQ, HEBREW MARK UPPER DOT, HEBREW ACCENT DEHI 1100 AC00 11A8;1100 AC01;1100 1100 1161 11A8;1100 AC01;1100 1100 1161 11A8; # (ᄀ각; ᄀ각; ᄀ각; ᄀ각; ᄀ각; ) HANGUL CHOSEONG KIYEOK, HANGUL SYLLABLE GA, HANGUL JONGSEONG KIYEOK 1100 AC00 11A8 11A8;1100 AC01 11A8;1100 1100 1161 11A8 11A8;1100 AC01 11A8;1100 1100 1161 11A8 11A8; # (ᄀ각ᆨ; ᄀ각ᆨ; ᄀ각ᆨ; ᄀ각ᆨ; ᄀ각ᆨ; ) HANGUL CHOSEONG KIYEOK, HANGUL SYLLABLE GA, HANGUL JONGSEONG KIYEOK, HANGUL JONGSEONG KIYEOK +01C4 0323;01C4 0323;01C4 0323;0044 1E92 030C;0044 005A 0323 030C; # (DŽ◌̣; DŽ◌̣; DŽ◌̣; DẒ◌̌; DZ◌̣◌̌; ) LATIN CAPITAL LETTER DZ WITH CARON, COMBINING DOT BELOW +01C5 0323;01C5 0323;01C5 0323;0044 1E93 030C;0044 007A 0323 030C; # (Dž◌̣; Dž◌̣; Dž◌̣; Dẓ◌̌; Dz◌̣◌̌; ) LATIN CAPITAL LETTER D WITH SMALL LETTER Z WITH CARON, COMBINING DOT BELOW +01C6 0323;01C6 0323;01C6 0323;0064 1E93 030C;0064 007A 0323 030C; # (dž◌̣; dž◌̣; dž◌̣; dẓ◌̌; dz◌̣◌̌; ) LATIN SMALL LETTER DZ WITH CARON, COMBINING DOT BELOW +0DDD 0334;0DDD 0334;0DD9 0DCF 0334 0DCA;0DDD 0334;0DD9 0DCF 0334 0DCA; # (ෝ◌̴; ෝ◌̴; ො◌̴◌්; ෝ◌̴; ො◌̴◌්; ) SINHALA VOWEL SIGN KOMBUVA HAA DIGA AELA-PILLA, COMBINING TILDE OVERLAY +3304 0334;3304 0334;3304 0334;30A4 30CB 30F3 30B0 0334;30A4 30CB 30F3 30AF 0334 3099; # (㌄◌̴; ㌄◌̴; ㌄◌̴; イニング◌̴; イニンク◌̴◌゙; ) SQUARE ININGU, COMBINING TILDE OVERLAY +3307 0334;3307 0334;3307 0334;30A8 30B9 30AF 30FC 30C9 0334;30A8 30B9 30AF 30FC 30C8 0334 3099; # (㌇◌̴; ㌇◌̴; ㌇◌̴; エスクード◌̴; エスクート◌̴◌゙; ) SQUARE ESUKUUDO, COMBINING TILDE OVERLAY +3310 0334;3310 0334;3310 0334;30AE 30AC 0334;30AD 3099 30AB 0334 3099; # (㌐◌̴; ㌐◌̴; ㌐◌̴; ギガ◌̴; キ◌゙カ◌̴◌゙; ) SQUARE GIGA, COMBINING TILDE OVERLAY +331E 0334;331E 0334;331E 0334;30B3 30FC 30DD 0334;30B3 30FC 30DB 0334 309A; # (㌞◌̴; ㌞◌̴; ㌞◌̴; コーポ◌̴; コーホ◌̴◌゚; ) SQUARE KOOPO, COMBINING TILDE OVERLAY +3321 0334;3321 0334;3321 0334;30B7 30EA 30F3 30B0 0334;30B7 30EA 30F3 30AF 0334 3099; # (㌡◌̴; ㌡◌̴; ㌡◌̴; シリング◌̴; シリンク◌̴◌゙; ) SQUARE SIRINGU, COMBINING TILDE OVERLAY +3332 0334;3332 0334;3332 0334;30D5 30A1 30E9 30C3 30C9 0334;30D5 30A1 30E9 30C3 30C8 0334 3099; # (㌲◌̴; ㌲◌̴; ㌲◌̴; ファラッド◌̴; ファラット◌̴◌゙; ) SQUARE HUARADDO, COMBINING TILDE OVERLAY +333B 0334;333B 0334;333B 0334;30DA 30FC 30B8 0334;30D8 309A 30FC 30B7 0334 3099; # (㌻◌̴; ㌻◌̴; ㌻◌̴; ページ◌̴; ヘ◌゚ーシ◌̴◌゙; ) SQUARE PEEZI, COMBINING TILDE OVERLAY +3340 0334;3340 0334;3340 0334;30DD 30F3 30C9 0334;30DB 309A 30F3 30C8 0334 3099; # (㍀◌̴; ㍀◌̴; ㍀◌̴; ポンド◌̴; ホ◌゚ント◌̴◌゙; ) SQUARE PONDO, COMBINING TILDE OVERLAY +334B 0334;334B 0334;334B 0334;30E1 30AC 0334;30E1 30AB 0334 3099; # (㍋◌̴; ㍋◌̴; ㍋◌̴; メガ◌̴; メカ◌̴◌゙; ) SQUARE MEGA, COMBINING TILDE OVERLAY +334E 0334;334E 0334;334E 0334;30E4 30FC 30C9 0334;30E4 30FC 30C8 0334 3099; # (㍎◌̴; ㍎◌̴; ㍎◌̴; ヤード◌̴; ヤート◌̴◌゙; ) SQUARE YAADO, COMBINING TILDE OVERLAY +FEF5 0656;FEF5 0656;FEF5 0656;0644 0622 0656;0644 0627 0656 0653; # (ﻵ◌ٖ; ﻵ◌ٖ; ﻵ◌ٖ; لآ◌ٖ; لا◌ٖ◌ٓ; ) ARABIC LIGATURE LAM WITH ALEF WITH MADDA ABOVE ISOLATED FORM, ARABIC SUBSCRIPT ALEF +FEF6 0656;FEF6 0656;FEF6 0656;0644 0622 0656;0644 0627 0656 0653; # (ﻶ◌ٖ; ﻶ◌ٖ; ﻶ◌ٖ; لآ◌ٖ; لا◌ٖ◌ٓ; ) ARABIC LIGATURE LAM WITH ALEF WITH MADDA ABOVE FINAL FORM, ARABIC SUBSCRIPT ALEF +FEF7 0656;FEF7 0656;FEF7 0656;0644 0623 0656;0644 0627 0656 0654; # (ﻷ◌ٖ; ﻷ◌ٖ; ﻷ◌ٖ; لأ◌ٖ; لا◌ٖ◌ٔ; ) ARABIC LIGATURE LAM WITH ALEF WITH HAMZA ABOVE ISOLATED FORM, ARABIC SUBSCRIPT ALEF +FEF8 0656;FEF8 0656;FEF8 0656;0644 0623 0656;0644 0627 0656 0654; # (ﻸ◌ٖ; ﻸ◌ٖ; ﻸ◌ٖ; لأ◌ٖ; لا◌ٖ◌ٔ; ) ARABIC LIGATURE LAM WITH ALEF WITH HAMZA ABOVE FINAL FORM, ARABIC SUBSCRIPT ALEF +FEF9 0334;FEF9 0334;FEF9 0334;0644 0625 0334;0644 0627 0334 0655; # (ﻹ◌̴; ﻹ◌̴; ﻹ◌̴; لإ◌̴; لا◌̴◌ٕ; ) ARABIC LIGATURE LAM WITH ALEF WITH HAMZA BELOW ISOLATED FORM, COMBINING TILDE OVERLAY +FEFA 0334;FEFA 0334;FEFA 0334;0644 0625 0334;0644 0627 0334 0655; # (ﻺ◌̴; ﻺ◌̴; ﻺ◌̴; لإ◌̴; لا◌̴◌ٕ; ) ARABIC LIGATURE LAM WITH ALEF WITH HAMZA BELOW FINAL FORM, COMBINING TILDE OVERLAY # @Part1 # Character by character test # All characters not explicitly occurring in c1 of Part 1 have identical NFC, D, KC, KD forms. @@ -15130,6 +15150,8 @@ FFEB;FFEB;FFEB;2192;2192; # (→; →; →; →; →; ) HALFWIDTH RIGHTWARDS ARR FFEC;FFEC;FFEC;2193;2193; # (↓; ↓; ↓; ↓; ↓; ) HALFWIDTH DOWNWARDS ARROW FFED;FFED;FFED;25A0;25A0; # (■; ■; ■; ■; ■; ) HALFWIDTH BLACK SQUARE FFEE;FFEE;FFEE;25CB;25CB; # (○; ○; ○; ○; ○; ) HALFWIDTH WHITE CIRCLE +105C9;105C9;105D2 0307;105C9;105D2 0307; # (𐗉; 𐗉; 𐗒◌̇; 𐗉; 𐗒◌̇; ) TODHRI LETTER EI +105E4;105E4;105DA 0307;105E4;105DA 0307; # (𐗤; 𐗤; 𐗚◌̇; 𐗤; 𐗚◌̇; ) TODHRI LETTER U 10781;10781;10781;02D0;02D0; # (𐞁; 𐞁; 𐞁; ː; ː; ) MODIFIER LETTER SUPERSCRIPT TRIANGULAR COLON 10782;10782;10782;02D1;02D1; # (𐞂; 𐞂; 𐞂; ˑ; ˑ; ) MODIFIER LETTER SUPERSCRIPT HALF TRIANGULAR COLON 10783;10783;10783;00E6;00E6; # (𐞃; 𐞃; 𐞃; æ; æ; ) MODIFIER LETTER SMALL AE @@ -15193,12 +15215,66 @@ FFEE;FFEE;FFEE;25CB;25CB; # (○; ○; ○; ○; ○; ) HALFWIDTH WHITE CIRCLE 1112F;1112F;11132 11127;1112F;11132 11127; # (◌𑄯; ◌𑄯; ◌𑄲◌𑄧; ◌𑄯; ◌𑄲◌𑄧; ) CHAKMA VOWEL SIGN AU 1134B;1134B;11347 1133E;1134B;11347 1133E; # (𑍋; 𑍋; 𑍋; 𑍋; 𑍋; ) GRANTHA VOWEL SIGN OO 1134C;1134C;11347 11357;1134C;11347 11357; # (𑍌; 𑍌; 𑍌; 𑍌; 𑍌; ) GRANTHA VOWEL SIGN AU +11383;11383;11382 113C9;11383;11382 113C9; # (𑎃; 𑎃; 𑎃; 𑎃; 𑎃; ) TULU-TIGALARI LETTER II +11385;11385;11384 113BB;11385;11384 113BB; # (𑎅; 𑎅; 𑎄◌𑎻; 𑎅; 𑎄◌𑎻; ) TULU-TIGALARI LETTER UU +1138E;1138E;1138B 113C2;1138E;1138B 113C2; # (𑎎; 𑎎; 𑎎; 𑎎; 𑎎; ) TULU-TIGALARI LETTER AI +11391;11391;11390 113C9;11391;11390 113C9; # (𑎑; 𑎑; 𑎑; 𑎑; 𑎑; ) TULU-TIGALARI LETTER AU +113C5;113C5;113C2 113C2;113C5;113C2 113C2; # (𑏅; 𑏅; 𑏅; 𑏅; 𑏅; ) TULU-TIGALARI VOWEL SIGN AI +113C7;113C7;113C2 113B8;113C7;113C2 113B8; # (𑏇; 𑏇; 𑏇; 𑏇; 𑏇; ) TULU-TIGALARI VOWEL SIGN OO +113C8;113C8;113C2 113C9;113C8;113C2 113C9; # (𑏈; 𑏈; 𑏈; 𑏈; 𑏈; ) TULU-TIGALARI VOWEL SIGN AU 114BB;114BB;114B9 114BA;114BB;114B9 114BA; # (𑒻; 𑒻; 𑒹◌𑒺; 𑒻; 𑒹◌𑒺; ) TIRHUTA VOWEL SIGN AI 114BC;114BC;114B9 114B0;114BC;114B9 114B0; # (𑒼; 𑒼; 𑒼; 𑒼; 𑒼; ) TIRHUTA VOWEL SIGN O 114BE;114BE;114B9 114BD;114BE;114B9 114BD; # (𑒾; 𑒾; 𑒾; 𑒾; 𑒾; ) TIRHUTA VOWEL SIGN AU 115BA;115BA;115B8 115AF;115BA;115B8 115AF; # (𑖺; 𑖺; 𑖺; 𑖺; 𑖺; ) SIDDHAM VOWEL SIGN O 115BB;115BB;115B9 115AF;115BB;115B9 115AF; # (𑖻; 𑖻; 𑖻; 𑖻; 𑖻; ) SIDDHAM VOWEL SIGN AU 11938;11938;11935 11930;11938;11935 11930; # (𑤸; 𑤸; 𑤸; 𑤸; 𑤸; ) DIVES AKURU VOWEL SIGN O +16121;16121;1611E 1611E;16121;1611E 1611E; # (◌𖄡; ◌𖄡; ◌𖄞◌𖄞; ◌𖄡; ◌𖄞◌𖄞; ) GURUNG KHEMA VOWEL SIGN U +16122;16122;1611E 16129;16122;1611E 16129; # (◌𖄢; ◌𖄢; ◌𖄞◌𖄩; ◌𖄢; ◌𖄞◌𖄩; ) GURUNG KHEMA VOWEL SIGN UU +16123;16123;1611E 1611F;16123;1611E 1611F; # (◌𖄣; ◌𖄣; ◌𖄞◌𖄟; ◌𖄣; ◌𖄞◌𖄟; ) GURUNG KHEMA VOWEL SIGN E +16124;16124;16129 1611F;16124;16129 1611F; # (◌𖄤; ◌𖄤; ◌𖄩◌𖄟; ◌𖄤; ◌𖄩◌𖄟; ) GURUNG KHEMA VOWEL SIGN EE +16125;16125;1611E 16120;16125;1611E 16120; # (◌𖄥; ◌𖄥; ◌𖄞◌𖄠; ◌𖄥; ◌𖄞◌𖄠; ) GURUNG KHEMA VOWEL SIGN AI +16126;16126;1611E 1611E 1611F;16126;1611E 1611E 1611F; # (◌𖄦; ◌𖄦; ◌𖄞◌𖄞◌𖄟; ◌𖄦; ◌𖄞◌𖄞◌𖄟; ) GURUNG KHEMA VOWEL SIGN O +16127;16127;1611E 16129 1611F;16127;1611E 16129 1611F; # (◌𖄧; ◌𖄧; ◌𖄞◌𖄩◌𖄟; ◌𖄧; ◌𖄞◌𖄩◌𖄟; ) GURUNG KHEMA VOWEL SIGN OO +16128;16128;1611E 1611E 16120;16128;1611E 1611E 16120; # (◌𖄨; ◌𖄨; ◌𖄞◌𖄞◌𖄠; ◌𖄨; ◌𖄞◌𖄞◌𖄠; ) GURUNG KHEMA VOWEL SIGN AU +16D68;16D68;16D67 16D67;16D68;16D67 16D67; # (𖵨; 𖵨; 𖵨; 𖵨; 𖵨; ) KIRAT RAI VOWEL SIGN AI +16D69;16D69;16D63 16D67;16D69;16D63 16D67; # (𖵩; 𖵩; 𖵩; 𖵩; 𖵩; ) KIRAT RAI VOWEL SIGN O +16D6A;16D6A;16D63 16D67 16D67;16D6A;16D63 16D67 16D67; # (𖵪; 𖵪; 𖵪; 𖵪; 𖵪; ) KIRAT RAI VOWEL SIGN AU +1CCD6;1CCD6;1CCD6;0041;0041; # (𜳖; 𜳖; 𜳖; A; A; ) OUTLINED LATIN CAPITAL LETTER A +1CCD7;1CCD7;1CCD7;0042;0042; # (𜳗; 𜳗; 𜳗; B; B; ) OUTLINED LATIN CAPITAL LETTER B +1CCD8;1CCD8;1CCD8;0043;0043; # (𜳘; 𜳘; 𜳘; C; C; ) OUTLINED LATIN CAPITAL LETTER C +1CCD9;1CCD9;1CCD9;0044;0044; # (𜳙; 𜳙; 𜳙; D; D; ) OUTLINED LATIN CAPITAL LETTER D +1CCDA;1CCDA;1CCDA;0045;0045; # (𜳚; 𜳚; 𜳚; E; E; ) OUTLINED LATIN CAPITAL LETTER E +1CCDB;1CCDB;1CCDB;0046;0046; # (𜳛; 𜳛; 𜳛; F; F; ) OUTLINED LATIN CAPITAL LETTER F +1CCDC;1CCDC;1CCDC;0047;0047; # (𜳜; 𜳜; 𜳜; G; G; ) OUTLINED LATIN CAPITAL LETTER G +1CCDD;1CCDD;1CCDD;0048;0048; # (𜳝; 𜳝; 𜳝; H; H; ) OUTLINED LATIN CAPITAL LETTER H +1CCDE;1CCDE;1CCDE;0049;0049; # (𜳞; 𜳞; 𜳞; I; I; ) OUTLINED LATIN CAPITAL LETTER I +1CCDF;1CCDF;1CCDF;004A;004A; # (𜳟; 𜳟; 𜳟; J; J; ) OUTLINED LATIN CAPITAL LETTER J +1CCE0;1CCE0;1CCE0;004B;004B; # (𜳠; 𜳠; 𜳠; K; K; ) OUTLINED LATIN CAPITAL LETTER K +1CCE1;1CCE1;1CCE1;004C;004C; # (𜳡; 𜳡; 𜳡; L; L; ) OUTLINED LATIN CAPITAL LETTER L +1CCE2;1CCE2;1CCE2;004D;004D; # (𜳢; 𜳢; 𜳢; M; M; ) OUTLINED LATIN CAPITAL LETTER M +1CCE3;1CCE3;1CCE3;004E;004E; # (𜳣; 𜳣; 𜳣; N; N; ) OUTLINED LATIN CAPITAL LETTER N +1CCE4;1CCE4;1CCE4;004F;004F; # (𜳤; 𜳤; 𜳤; O; O; ) OUTLINED LATIN CAPITAL LETTER O +1CCE5;1CCE5;1CCE5;0050;0050; # (𜳥; 𜳥; 𜳥; P; P; ) OUTLINED LATIN CAPITAL LETTER P +1CCE6;1CCE6;1CCE6;0051;0051; # (𜳦; 𜳦; 𜳦; Q; Q; ) OUTLINED LATIN CAPITAL LETTER Q +1CCE7;1CCE7;1CCE7;0052;0052; # (𜳧; 𜳧; 𜳧; R; R; ) OUTLINED LATIN CAPITAL LETTER R +1CCE8;1CCE8;1CCE8;0053;0053; # (𜳨; 𜳨; 𜳨; S; S; ) OUTLINED LATIN CAPITAL LETTER S +1CCE9;1CCE9;1CCE9;0054;0054; # (𜳩; 𜳩; 𜳩; T; T; ) OUTLINED LATIN CAPITAL LETTER T +1CCEA;1CCEA;1CCEA;0055;0055; # (𜳪; 𜳪; 𜳪; U; U; ) OUTLINED LATIN CAPITAL LETTER U +1CCEB;1CCEB;1CCEB;0056;0056; # (𜳫; 𜳫; 𜳫; V; V; ) OUTLINED LATIN CAPITAL LETTER V +1CCEC;1CCEC;1CCEC;0057;0057; # (𜳬; 𜳬; 𜳬; W; W; ) OUTLINED LATIN CAPITAL LETTER W +1CCED;1CCED;1CCED;0058;0058; # (𜳭; 𜳭; 𜳭; X; X; ) OUTLINED LATIN CAPITAL LETTER X +1CCEE;1CCEE;1CCEE;0059;0059; # (𜳮; 𜳮; 𜳮; Y; Y; ) OUTLINED LATIN CAPITAL LETTER Y +1CCEF;1CCEF;1CCEF;005A;005A; # (𜳯; 𜳯; 𜳯; Z; Z; ) OUTLINED LATIN CAPITAL LETTER Z +1CCF0;1CCF0;1CCF0;0030;0030; # (𜳰; 𜳰; 𜳰; 0; 0; ) OUTLINED DIGIT ZERO +1CCF1;1CCF1;1CCF1;0031;0031; # (𜳱; 𜳱; 𜳱; 1; 1; ) OUTLINED DIGIT ONE +1CCF2;1CCF2;1CCF2;0032;0032; # (𜳲; 𜳲; 𜳲; 2; 2; ) OUTLINED DIGIT TWO +1CCF3;1CCF3;1CCF3;0033;0033; # (𜳳; 𜳳; 𜳳; 3; 3; ) OUTLINED DIGIT THREE +1CCF4;1CCF4;1CCF4;0034;0034; # (𜳴; 𜳴; 𜳴; 4; 4; ) OUTLINED DIGIT FOUR +1CCF5;1CCF5;1CCF5;0035;0035; # (𜳵; 𜳵; 𜳵; 5; 5; ) OUTLINED DIGIT FIVE +1CCF6;1CCF6;1CCF6;0036;0036; # (𜳶; 𜳶; 𜳶; 6; 6; ) OUTLINED DIGIT SIX +1CCF7;1CCF7;1CCF7;0037;0037; # (𜳷; 𜳷; 𜳷; 7; 7; ) OUTLINED DIGIT SEVEN +1CCF8;1CCF8;1CCF8;0038;0038; # (𜳸; 𜳸; 𜳸; 8; 8; ) OUTLINED DIGIT EIGHT +1CCF9;1CCF9;1CCF9;0039;0039; # (𜳹; 𜳹; 𜳹; 9; 9; ) OUTLINED DIGIT NINE 1D15E;1D157 1D165;1D157 1D165;1D157 1D165;1D157 1D165; # (𝅗𝅥; 𝅗𝅥; 𝅗𝅥; 𝅗𝅥; 𝅗𝅥; ) MUSICAL SYMBOL HALF NOTE 1D15F;1D158 1D165;1D158 1D165;1D158 1D165;1D158 1D165; # (𝅘𝅥; 𝅘𝅥; 𝅘𝅥; 𝅘𝅥; 𝅘𝅥; ) MUSICAL SYMBOL QUARTER NOTE 1D160;1D158 1D165 1D16E;1D158 1D165 1D16E;1D158 1D165 1D16E;1D158 1D165 1D16E; # (𝅘𝅥𝅮; 𝅘𝅥𝅮; 𝅘𝅥𝅮; 𝅘𝅥𝅮; 𝅘𝅥𝅮; ) MUSICAL SYMBOL EIGHTH NOTE @@ -17664,6 +17740,8 @@ FFEE;FFEE;FFEE;25CB;25CB; # (○; ○; ○; ○; ○; ) HALFWIDTH WHITE CIRCLE 0061 085A 059A 0316 1DFA 0062;0061 1DFA 085A 0316 059A 0062;0061 1DFA 085A 0316 059A 0062;0061 1DFA 085A 0316 059A 0062;0061 1DFA 085A 0316 059A 0062; # (a◌࡚◌֚◌̖◌᷺b; a◌᷺◌࡚◌̖◌֚b; a◌᷺◌࡚◌̖◌֚b; a◌᷺◌࡚◌̖◌֚b; a◌᷺◌࡚◌̖◌֚b; ) LATIN SMALL LETTER A, MANDAIC VOCALIZATION MARK, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, COMBINING DOT BELOW LEFT, LATIN SMALL LETTER B 0061 059A 0316 1DFA 085B 0062;0061 1DFA 0316 085B 059A 0062;0061 1DFA 0316 085B 059A 0062;0061 1DFA 0316 085B 059A 0062;0061 1DFA 0316 085B 059A 0062; # (a◌֚◌̖◌᷺◌࡛b; a◌᷺◌̖◌࡛◌֚b; a◌᷺◌̖◌࡛◌֚b; a◌᷺◌̖◌࡛◌֚b; a◌᷺◌̖◌࡛◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, COMBINING DOT BELOW LEFT, MANDAIC GEMINATION MARK, LATIN SMALL LETTER B 0061 085B 059A 0316 1DFA 0062;0061 1DFA 085B 0316 059A 0062;0061 1DFA 085B 0316 059A 0062;0061 1DFA 085B 0316 059A 0062;0061 1DFA 085B 0316 059A 0062; # (a◌࡛◌֚◌̖◌᷺b; a◌᷺◌࡛◌̖◌֚b; a◌᷺◌࡛◌̖◌֚b; a◌᷺◌࡛◌̖◌֚b; a◌᷺◌࡛◌̖◌֚b; ) LATIN SMALL LETTER A, MANDAIC GEMINATION MARK, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, COMBINING DOT BELOW LEFT, LATIN SMALL LETTER B +0061 0315 0300 05AE 0897 0062;00E0 05AE 0897 0315 0062;0061 05AE 0300 0897 0315 0062;00E0 05AE 0897 0315 0062;0061 05AE 0300 0897 0315 0062; # (a◌̕◌̀◌֮◌ࢗb; à◌֮◌ࢗ◌̕b; a◌֮◌̀◌ࢗ◌̕b; à◌֮◌ࢗ◌̕b; a◌֮◌̀◌ࢗ◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, ARABIC PEPET, LATIN SMALL LETTER B +0061 0897 0315 0300 05AE 0062;0061 05AE 0897 0300 0315 0062;0061 05AE 0897 0300 0315 0062;0061 05AE 0897 0300 0315 0062;0061 05AE 0897 0300 0315 0062; # (a◌ࢗ◌̕◌̀◌֮b; a◌֮◌ࢗ◌̀◌̕b; a◌֮◌ࢗ◌̀◌̕b; a◌֮◌ࢗ◌̀◌̕b; a◌֮◌ࢗ◌̀◌̕b; ) LATIN SMALL LETTER A, ARABIC PEPET, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B 0061 0315 0300 05AE 0898 0062;00E0 05AE 0898 0315 0062;0061 05AE 0300 0898 0315 0062;00E0 05AE 0898 0315 0062;0061 05AE 0300 0898 0315 0062; # (a◌̕◌̀◌֮◌࢘b; à◌֮◌࢘◌̕b; a◌֮◌̀◌࢘◌̕b; à◌֮◌࢘◌̕b; a◌֮◌̀◌࢘◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, ARABIC SMALL HIGH WORD AL-JUZ, LATIN SMALL LETTER B 0061 0898 0315 0300 05AE 0062;0061 05AE 0898 0300 0315 0062;0061 05AE 0898 0300 0315 0062;0061 05AE 0898 0300 0315 0062;0061 05AE 0898 0300 0315 0062; # (a◌࢘◌̕◌̀◌֮b; a◌֮◌࢘◌̀◌̕b; a◌֮◌࢘◌̀◌̕b; a◌֮◌࢘◌̀◌̕b; a◌֮◌࢘◌̀◌̕b; ) LATIN SMALL LETTER A, ARABIC SMALL HIGH WORD AL-JUZ, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B 0061 059A 0316 1DFA 0899 0062;0061 1DFA 0316 0899 059A 0062;0061 1DFA 0316 0899 059A 0062;0061 1DFA 0316 0899 059A 0062;0061 1DFA 0316 0899 059A 0062; # (a◌֚◌̖◌᷺◌࢙b; a◌᷺◌̖◌࢙◌֚b; a◌᷺◌̖◌࢙◌֚b; a◌᷺◌̖◌࢙◌֚b; a◌᷺◌̖◌࢙◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, COMBINING DOT BELOW LEFT, ARABIC SMALL LOW WORD ISHMAAM, LATIN SMALL LETTER B @@ -18554,6 +18632,16 @@ FFEE;FFEE;FFEE;25CB;25CB; # (○; ○; ○; ○; ○; ) HALFWIDTH WHITE CIRCLE 0061 10D26 0315 0300 05AE 0062;0061 05AE 10D26 0300 0315 0062;0061 05AE 10D26 0300 0315 0062;0061 05AE 10D26 0300 0315 0062;0061 05AE 10D26 0300 0315 0062; # (a◌𐴦◌̕◌̀◌֮b; a◌֮◌𐴦◌̀◌̕b; a◌֮◌𐴦◌̀◌̕b; a◌֮◌𐴦◌̀◌̕b; a◌֮◌𐴦◌̀◌̕b; ) LATIN SMALL LETTER A, HANIFI ROHINGYA SIGN TANA, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B 0061 0315 0300 05AE 10D27 0062;00E0 05AE 10D27 0315 0062;0061 05AE 0300 10D27 0315 0062;00E0 05AE 10D27 0315 0062;0061 05AE 0300 10D27 0315 0062; # (a◌̕◌̀◌֮◌𐴧b; à◌֮◌𐴧◌̕b; a◌֮◌̀◌𐴧◌̕b; à◌֮◌𐴧◌̕b; a◌֮◌̀◌𐴧◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, HANIFI ROHINGYA SIGN TASSI, LATIN SMALL LETTER B 0061 10D27 0315 0300 05AE 0062;0061 05AE 10D27 0300 0315 0062;0061 05AE 10D27 0300 0315 0062;0061 05AE 10D27 0300 0315 0062;0061 05AE 10D27 0300 0315 0062; # (a◌𐴧◌̕◌̀◌֮b; a◌֮◌𐴧◌̀◌̕b; a◌֮◌𐴧◌̀◌̕b; a◌֮◌𐴧◌̀◌̕b; a◌֮◌𐴧◌̀◌̕b; ) LATIN SMALL LETTER A, HANIFI ROHINGYA SIGN TASSI, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B +0061 0315 0300 05AE 10D69 0062;00E0 05AE 10D69 0315 0062;0061 05AE 0300 10D69 0315 0062;00E0 05AE 10D69 0315 0062;0061 05AE 0300 10D69 0315 0062; # (a◌̕◌̀◌֮◌𐵩b; à◌֮◌𐵩◌̕b; a◌֮◌̀◌𐵩◌̕b; à◌֮◌𐵩◌̕b; a◌֮◌̀◌𐵩◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, GARAY VOWEL SIGN E, LATIN SMALL LETTER B +0061 10D69 0315 0300 05AE 0062;0061 05AE 10D69 0300 0315 0062;0061 05AE 10D69 0300 0315 0062;0061 05AE 10D69 0300 0315 0062;0061 05AE 10D69 0300 0315 0062; # (a◌𐵩◌̕◌̀◌֮b; a◌֮◌𐵩◌̀◌̕b; a◌֮◌𐵩◌̀◌̕b; a◌֮◌𐵩◌̀◌̕b; a◌֮◌𐵩◌̀◌̕b; ) LATIN SMALL LETTER A, GARAY VOWEL SIGN E, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B +0061 0315 0300 05AE 10D6A 0062;00E0 05AE 10D6A 0315 0062;0061 05AE 0300 10D6A 0315 0062;00E0 05AE 10D6A 0315 0062;0061 05AE 0300 10D6A 0315 0062; # (a◌̕◌̀◌֮◌𐵪b; à◌֮◌𐵪◌̕b; a◌֮◌̀◌𐵪◌̕b; à◌֮◌𐵪◌̕b; a◌֮◌̀◌𐵪◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, GARAY CONSONANT GEMINATION MARK, LATIN SMALL LETTER B +0061 10D6A 0315 0300 05AE 0062;0061 05AE 10D6A 0300 0315 0062;0061 05AE 10D6A 0300 0315 0062;0061 05AE 10D6A 0300 0315 0062;0061 05AE 10D6A 0300 0315 0062; # (a◌𐵪◌̕◌̀◌֮b; a◌֮◌𐵪◌̀◌̕b; a◌֮◌𐵪◌̀◌̕b; a◌֮◌𐵪◌̀◌̕b; a◌֮◌𐵪◌̀◌̕b; ) LATIN SMALL LETTER A, GARAY CONSONANT GEMINATION MARK, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B +0061 0315 0300 05AE 10D6B 0062;00E0 05AE 10D6B 0315 0062;0061 05AE 0300 10D6B 0315 0062;00E0 05AE 10D6B 0315 0062;0061 05AE 0300 10D6B 0315 0062; # (a◌̕◌̀◌֮◌𐵫b; à◌֮◌𐵫◌̕b; a◌֮◌̀◌𐵫◌̕b; à◌֮◌𐵫◌̕b; a◌֮◌̀◌𐵫◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, GARAY COMBINING DOT ABOVE, LATIN SMALL LETTER B +0061 10D6B 0315 0300 05AE 0062;0061 05AE 10D6B 0300 0315 0062;0061 05AE 10D6B 0300 0315 0062;0061 05AE 10D6B 0300 0315 0062;0061 05AE 10D6B 0300 0315 0062; # (a◌𐵫◌̕◌̀◌֮b; a◌֮◌𐵫◌̀◌̕b; a◌֮◌𐵫◌̀◌̕b; a◌֮◌𐵫◌̀◌̕b; a◌֮◌𐵫◌̀◌̕b; ) LATIN SMALL LETTER A, GARAY COMBINING DOT ABOVE, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B +0061 0315 0300 05AE 10D6C 0062;00E0 05AE 10D6C 0315 0062;0061 05AE 0300 10D6C 0315 0062;00E0 05AE 10D6C 0315 0062;0061 05AE 0300 10D6C 0315 0062; # (a◌̕◌̀◌֮◌𐵬b; à◌֮◌𐵬◌̕b; a◌֮◌̀◌𐵬◌̕b; à◌֮◌𐵬◌̕b; a◌֮◌̀◌𐵬◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, GARAY COMBINING DOUBLE DOT ABOVE, LATIN SMALL LETTER B +0061 10D6C 0315 0300 05AE 0062;0061 05AE 10D6C 0300 0315 0062;0061 05AE 10D6C 0300 0315 0062;0061 05AE 10D6C 0300 0315 0062;0061 05AE 10D6C 0300 0315 0062; # (a◌𐵬◌̕◌̀◌֮b; a◌֮◌𐵬◌̀◌̕b; a◌֮◌𐵬◌̀◌̕b; a◌֮◌𐵬◌̀◌̕b; a◌֮◌𐵬◌̀◌̕b; ) LATIN SMALL LETTER A, GARAY COMBINING DOUBLE DOT ABOVE, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B +0061 0315 0300 05AE 10D6D 0062;00E0 05AE 10D6D 0315 0062;0061 05AE 0300 10D6D 0315 0062;00E0 05AE 10D6D 0315 0062;0061 05AE 0300 10D6D 0315 0062; # (a◌̕◌̀◌֮◌𐵭b; à◌֮◌𐵭◌̕b; a◌֮◌̀◌𐵭◌̕b; à◌֮◌𐵭◌̕b; a◌֮◌̀◌𐵭◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, GARAY CONSONANT NASALIZATION MARK, LATIN SMALL LETTER B +0061 10D6D 0315 0300 05AE 0062;0061 05AE 10D6D 0300 0315 0062;0061 05AE 10D6D 0300 0315 0062;0061 05AE 10D6D 0300 0315 0062;0061 05AE 10D6D 0300 0315 0062; # (a◌𐵭◌̕◌̀◌֮b; a◌֮◌𐵭◌̀◌̕b; a◌֮◌𐵭◌̀◌̕b; a◌֮◌𐵭◌̀◌̕b; a◌֮◌𐵭◌̀◌̕b; ) LATIN SMALL LETTER A, GARAY CONSONANT NASALIZATION MARK, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B 0061 0315 0300 05AE 10EAB 0062;00E0 05AE 10EAB 0315 0062;0061 05AE 0300 10EAB 0315 0062;00E0 05AE 10EAB 0315 0062;0061 05AE 0300 10EAB 0315 0062; # (a◌̕◌̀◌֮◌𐺫b; à◌֮◌𐺫◌̕b; a◌֮◌̀◌𐺫◌̕b; à◌֮◌𐺫◌̕b; a◌֮◌̀◌𐺫◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, YEZIDI COMBINING HAMZA MARK, LATIN SMALL LETTER B 0061 10EAB 0315 0300 05AE 0062;0061 05AE 10EAB 0300 0315 0062;0061 05AE 10EAB 0300 0315 0062;0061 05AE 10EAB 0300 0315 0062;0061 05AE 10EAB 0300 0315 0062; # (a◌𐺫◌̕◌̀◌֮b; a◌֮◌𐺫◌̀◌̕b; a◌֮◌𐺫◌̀◌̕b; a◌֮◌𐺫◌̀◌̕b; a◌֮◌𐺫◌̀◌̕b; ) LATIN SMALL LETTER A, YEZIDI COMBINING HAMZA MARK, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B 0061 0315 0300 05AE 10EAC 0062;00E0 05AE 10EAC 0315 0062;0061 05AE 0300 10EAC 0315 0062;00E0 05AE 10EAC 0315 0062;0061 05AE 0300 10EAC 0315 0062; # (a◌̕◌̀◌֮◌𐺬b; à◌֮◌𐺬◌̕b; a◌֮◌̀◌𐺬◌̕b; à◌֮◌𐺬◌̕b; a◌֮◌̀◌𐺬◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, YEZIDI COMBINING MADDA MARK, LATIN SMALL LETTER B @@ -18658,6 +18746,12 @@ FFEE;FFEE;FFEE;25CB;25CB; # (○; ○; ○; ○; ○; ) HALFWIDTH WHITE CIRCLE 0061 11373 0315 0300 05AE 0062;0061 05AE 11373 0300 0315 0062;0061 05AE 11373 0300 0315 0062;0061 05AE 11373 0300 0315 0062;0061 05AE 11373 0300 0315 0062; # (a◌𑍳◌̕◌̀◌֮b; a◌֮◌𑍳◌̀◌̕b; a◌֮◌𑍳◌̀◌̕b; a◌֮◌𑍳◌̀◌̕b; a◌֮◌𑍳◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING GRANTHA LETTER VI, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B 0061 0315 0300 05AE 11374 0062;00E0 05AE 11374 0315 0062;0061 05AE 0300 11374 0315 0062;00E0 05AE 11374 0315 0062;0061 05AE 0300 11374 0315 0062; # (a◌̕◌̀◌֮◌𑍴b; à◌֮◌𑍴◌̕b; a◌֮◌̀◌𑍴◌̕b; à◌֮◌𑍴◌̕b; a◌֮◌̀◌𑍴◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, COMBINING GRANTHA LETTER PA, LATIN SMALL LETTER B 0061 11374 0315 0300 05AE 0062;0061 05AE 11374 0300 0315 0062;0061 05AE 11374 0300 0315 0062;0061 05AE 11374 0300 0315 0062;0061 05AE 11374 0300 0315 0062; # (a◌𑍴◌̕◌̀◌֮b; a◌֮◌𑍴◌̀◌̕b; a◌֮◌𑍴◌̀◌̕b; a◌֮◌𑍴◌̀◌̕b; a◌֮◌𑍴◌̀◌̕b; ) LATIN SMALL LETTER A, COMBINING GRANTHA LETTER PA, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B +0061 05B0 094D 3099 113CE 0062;0061 3099 094D 113CE 05B0 0062;0061 3099 094D 113CE 05B0 0062;0061 3099 094D 113CE 05B0 0062;0061 3099 094D 113CE 05B0 0062; # (a◌ְ◌्◌゙◌𑏎b; a◌゙◌्◌𑏎◌ְb; a◌゙◌्◌𑏎◌ְb; a◌゙◌्◌𑏎◌ְb; a◌゙◌्◌𑏎◌ְb; ) LATIN SMALL LETTER A, HEBREW POINT SHEVA, DEVANAGARI SIGN VIRAMA, COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, TULU-TIGALARI SIGN VIRAMA, LATIN SMALL LETTER B +0061 113CE 05B0 094D 3099 0062;0061 3099 113CE 094D 05B0 0062;0061 3099 113CE 094D 05B0 0062;0061 3099 113CE 094D 05B0 0062;0061 3099 113CE 094D 05B0 0062; # (a◌𑏎◌ְ◌्◌゙b; a◌゙◌𑏎◌्◌ְb; a◌゙◌𑏎◌्◌ְb; a◌゙◌𑏎◌्◌ְb; a◌゙◌𑏎◌्◌ְb; ) LATIN SMALL LETTER A, TULU-TIGALARI SIGN VIRAMA, HEBREW POINT SHEVA, DEVANAGARI SIGN VIRAMA, COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, LATIN SMALL LETTER B +0061 05B0 094D 3099 113CF 0062;0061 3099 094D 113CF 05B0 0062;0061 3099 094D 113CF 05B0 0062;0061 3099 094D 113CF 05B0 0062;0061 3099 094D 113CF 05B0 0062; # (a◌ְ◌्◌゙𑏏b; a◌゙◌्𑏏◌ְb; a◌゙◌्𑏏◌ְb; a◌゙◌्𑏏◌ְb; a◌゙◌्𑏏◌ְb; ) LATIN SMALL LETTER A, HEBREW POINT SHEVA, DEVANAGARI SIGN VIRAMA, COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, TULU-TIGALARI SIGN LOOPED VIRAMA, LATIN SMALL LETTER B +0061 113CF 05B0 094D 3099 0062;0061 3099 113CF 094D 05B0 0062;0061 3099 113CF 094D 05B0 0062;0061 3099 113CF 094D 05B0 0062;0061 3099 113CF 094D 05B0 0062; # (a𑏏◌ְ◌्◌゙b; a◌゙𑏏◌्◌ְb; a◌゙𑏏◌्◌ְb; a◌゙𑏏◌्◌ְb; a◌゙𑏏◌्◌ְb; ) LATIN SMALL LETTER A, TULU-TIGALARI SIGN LOOPED VIRAMA, HEBREW POINT SHEVA, DEVANAGARI SIGN VIRAMA, COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, LATIN SMALL LETTER B +0061 05B0 094D 3099 113D0 0062;0061 3099 094D 113D0 05B0 0062;0061 3099 094D 113D0 05B0 0062;0061 3099 094D 113D0 05B0 0062;0061 3099 094D 113D0 05B0 0062; # (a◌ְ◌्◌゙◌𑏐b; a◌゙◌्◌𑏐◌ְb; a◌゙◌्◌𑏐◌ְb; a◌゙◌्◌𑏐◌ְb; a◌゙◌्◌𑏐◌ְb; ) LATIN SMALL LETTER A, HEBREW POINT SHEVA, DEVANAGARI SIGN VIRAMA, COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, TULU-TIGALARI CONJOINER, LATIN SMALL LETTER B +0061 113D0 05B0 094D 3099 0062;0061 3099 113D0 094D 05B0 0062;0061 3099 113D0 094D 05B0 0062;0061 3099 113D0 094D 05B0 0062;0061 3099 113D0 094D 05B0 0062; # (a◌𑏐◌ְ◌्◌゙b; a◌゙◌𑏐◌्◌ְb; a◌゙◌𑏐◌्◌ְb; a◌゙◌𑏐◌्◌ְb; a◌゙◌𑏐◌्◌ְb; ) LATIN SMALL LETTER A, TULU-TIGALARI CONJOINER, HEBREW POINT SHEVA, DEVANAGARI SIGN VIRAMA, COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, LATIN SMALL LETTER B 0061 05B0 094D 3099 11442 0062;0061 3099 094D 11442 05B0 0062;0061 3099 094D 11442 05B0 0062;0061 3099 094D 11442 05B0 0062;0061 3099 094D 11442 05B0 0062; # (a◌ְ◌्◌゙◌𑑂b; a◌゙◌्◌𑑂◌ְb; a◌゙◌्◌𑑂◌ְb; a◌゙◌्◌𑑂◌ְb; a◌゙◌्◌𑑂◌ְb; ) LATIN SMALL LETTER A, HEBREW POINT SHEVA, DEVANAGARI SIGN VIRAMA, COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, NEWA SIGN VIRAMA, LATIN SMALL LETTER B 0061 11442 05B0 094D 3099 0062;0061 3099 11442 094D 05B0 0062;0061 3099 11442 094D 05B0 0062;0061 3099 11442 094D 05B0 0062;0061 3099 11442 094D 05B0 0062; # (a◌𑑂◌ְ◌्◌゙b; a◌゙◌𑑂◌्◌ְb; a◌゙◌𑑂◌्◌ְb; a◌゙◌𑑂◌्◌ְb; a◌゙◌𑑂◌्◌ְb; ) LATIN SMALL LETTER A, NEWA SIGN VIRAMA, HEBREW POINT SHEVA, DEVANAGARI SIGN VIRAMA, COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, LATIN SMALL LETTER B 0061 3099 093C 16FF0 11446 0062;0061 16FF0 093C 11446 3099 0062;0061 16FF0 093C 11446 3099 0062;0061 16FF0 093C 11446 3099 0062;0061 16FF0 093C 11446 3099 0062; # (a◌゙◌𖿰़◌𑑆b; a𖿰◌़◌𑑆◌゙b; a𖿰◌़◌𑑆◌゙b; a𖿰◌़◌𑑆◌゙b; a𖿰◌़◌𑑆◌゙b; ) LATIN SMALL LETTER A, COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, DEVANAGARI SIGN NUKTA, VIETNAMESE ALTERNATE READING MARK CA, NEWA SIGN NUKTA, LATIN SMALL LETTER B @@ -18712,6 +18806,8 @@ FFEE;FFEE;FFEE;25CB;25CB; # (○; ○; ○; ○; ○; ) HALFWIDTH WHITE CIRCLE 0061 11F41 05B0 094D 3099 0062;0061 3099 11F41 094D 05B0 0062;0061 3099 11F41 094D 05B0 0062;0061 3099 11F41 094D 05B0 0062;0061 3099 11F41 094D 05B0 0062; # (a𑽁◌ְ◌्◌゙b; a◌゙𑽁◌्◌ְb; a◌゙𑽁◌्◌ְb; a◌゙𑽁◌्◌ְb; a◌゙𑽁◌्◌ְb; ) LATIN SMALL LETTER A, KAWI SIGN KILLER, HEBREW POINT SHEVA, DEVANAGARI SIGN VIRAMA, COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, LATIN SMALL LETTER B 0061 05B0 094D 3099 11F42 0062;0061 3099 094D 11F42 05B0 0062;0061 3099 094D 11F42 05B0 0062;0061 3099 094D 11F42 05B0 0062;0061 3099 094D 11F42 05B0 0062; # (a◌ְ◌्◌゙◌𑽂b; a◌゙◌्◌𑽂◌ְb; a◌゙◌्◌𑽂◌ְb; a◌゙◌्◌𑽂◌ְb; a◌゙◌्◌𑽂◌ְb; ) LATIN SMALL LETTER A, HEBREW POINT SHEVA, DEVANAGARI SIGN VIRAMA, COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, KAWI CONJOINER, LATIN SMALL LETTER B 0061 11F42 05B0 094D 3099 0062;0061 3099 11F42 094D 05B0 0062;0061 3099 11F42 094D 05B0 0062;0061 3099 11F42 094D 05B0 0062;0061 3099 11F42 094D 05B0 0062; # (a◌𑽂◌ְ◌्◌゙b; a◌゙◌𑽂◌्◌ְb; a◌゙◌𑽂◌्◌ְb; a◌゙◌𑽂◌्◌ְb; a◌゙◌𑽂◌्◌ְb; ) LATIN SMALL LETTER A, KAWI CONJOINER, HEBREW POINT SHEVA, DEVANAGARI SIGN VIRAMA, COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, LATIN SMALL LETTER B +0061 05B0 094D 3099 1612F 0062;0061 3099 094D 1612F 05B0 0062;0061 3099 094D 1612F 05B0 0062;0061 3099 094D 1612F 05B0 0062;0061 3099 094D 1612F 05B0 0062; # (a◌ְ◌्◌゙◌𖄯b; a◌゙◌्◌𖄯◌ְb; a◌゙◌्◌𖄯◌ְb; a◌゙◌्◌𖄯◌ְb; a◌゙◌्◌𖄯◌ְb; ) LATIN SMALL LETTER A, HEBREW POINT SHEVA, DEVANAGARI SIGN VIRAMA, COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, GURUNG KHEMA SIGN THOLHOMA, LATIN SMALL LETTER B +0061 1612F 05B0 094D 3099 0062;0061 3099 1612F 094D 05B0 0062;0061 3099 1612F 094D 05B0 0062;0061 3099 1612F 094D 05B0 0062;0061 3099 1612F 094D 05B0 0062; # (a◌𖄯◌ְ◌्◌゙b; a◌゙◌𖄯◌्◌ְb; a◌゙◌𖄯◌्◌ְb; a◌゙◌𖄯◌्◌ְb; a◌゙◌𖄯◌्◌ְb; ) LATIN SMALL LETTER A, GURUNG KHEMA SIGN THOLHOMA, HEBREW POINT SHEVA, DEVANAGARI SIGN VIRAMA, COMBINING KATAKANA-HIRAGANA VOICED SOUND MARK, LATIN SMALL LETTER B 0061 16FF0 0334 16AF0 0062;0061 0334 16AF0 16FF0 0062;0061 0334 16AF0 16FF0 0062;0061 0334 16AF0 16FF0 0062;0061 0334 16AF0 16FF0 0062; # (a𖿰◌̴◌𖫰b; a◌̴◌𖫰𖿰b; a◌̴◌𖫰𖿰b; a◌̴◌𖫰𖿰b; a◌̴◌𖫰𖿰b; ) LATIN SMALL LETTER A, VIETNAMESE ALTERNATE READING MARK CA, COMBINING TILDE OVERLAY, BASSA VAH COMBINING HIGH TONE, LATIN SMALL LETTER B 0061 16AF0 16FF0 0334 0062;0061 16AF0 0334 16FF0 0062;0061 16AF0 0334 16FF0 0062;0061 16AF0 0334 16FF0 0062;0061 16AF0 0334 16FF0 0062; # (a◌𖫰𖿰◌̴b; a◌𖫰◌̴𖿰b; a◌𖫰◌̴𖿰b; a◌𖫰◌̴𖿰b; a◌𖫰◌̴𖿰b; ) LATIN SMALL LETTER A, BASSA VAH COMBINING HIGH TONE, VIETNAMESE ALTERNATE READING MARK CA, COMBINING TILDE OVERLAY, LATIN SMALL LETTER B 0061 16FF0 0334 16AF1 0062;0061 0334 16AF1 16FF0 0062;0061 0334 16AF1 16FF0 0062;0061 0334 16AF1 16FF0 0062;0061 0334 16AF1 16FF0 0062; # (a𖿰◌̴◌𖫱b; a◌̴◌𖫱𖿰b; a◌̴◌𖫱𖿰b; a◌̴◌𖫱𖿰b; a◌̴◌𖫱𖿰b; ) LATIN SMALL LETTER A, VIETNAMESE ALTERNATE READING MARK CA, COMBINING TILDE OVERLAY, BASSA VAH COMBINING LOW TONE, LATIN SMALL LETTER B @@ -18918,6 +19014,10 @@ FFEE;FFEE;FFEE;25CB;25CB; # (○; ○; ○; ○; ○; ) HALFWIDTH WHITE CIRCLE 0061 1E4EE 059A 0316 1DFA 0062;0061 1DFA 1E4EE 0316 059A 0062;0061 1DFA 1E4EE 0316 059A 0062;0061 1DFA 1E4EE 0316 059A 0062;0061 1DFA 1E4EE 0316 059A 0062; # (a◌𞓮◌֚◌̖◌᷺b; a◌᷺◌𞓮◌̖◌֚b; a◌᷺◌𞓮◌̖◌֚b; a◌᷺◌𞓮◌̖◌֚b; a◌᷺◌𞓮◌̖◌֚b; ) LATIN SMALL LETTER A, NAG MUNDARI SIGN IKIR, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, COMBINING DOT BELOW LEFT, LATIN SMALL LETTER B 0061 0315 0300 05AE 1E4EF 0062;00E0 05AE 1E4EF 0315 0062;0061 05AE 0300 1E4EF 0315 0062;00E0 05AE 1E4EF 0315 0062;0061 05AE 0300 1E4EF 0315 0062; # (a◌̕◌̀◌֮◌𞓯b; à◌֮◌𞓯◌̕b; a◌֮◌̀◌𞓯◌̕b; à◌֮◌𞓯◌̕b; a◌֮◌̀◌𞓯◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, NAG MUNDARI SIGN SUTUH, LATIN SMALL LETTER B 0061 1E4EF 0315 0300 05AE 0062;0061 05AE 1E4EF 0300 0315 0062;0061 05AE 1E4EF 0300 0315 0062;0061 05AE 1E4EF 0300 0315 0062;0061 05AE 1E4EF 0300 0315 0062; # (a◌𞓯◌̕◌̀◌֮b; a◌֮◌𞓯◌̀◌̕b; a◌֮◌𞓯◌̀◌̕b; a◌֮◌𞓯◌̀◌̕b; a◌֮◌𞓯◌̀◌̕b; ) LATIN SMALL LETTER A, NAG MUNDARI SIGN SUTUH, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B +0061 0315 0300 05AE 1E5EE 0062;00E0 05AE 1E5EE 0315 0062;0061 05AE 0300 1E5EE 0315 0062;00E0 05AE 1E5EE 0315 0062;0061 05AE 0300 1E5EE 0315 0062; # (a◌̕◌̀◌֮◌𞗮b; à◌֮◌𞗮◌̕b; a◌֮◌̀◌𞗮◌̕b; à◌֮◌𞗮◌̕b; a◌֮◌̀◌𞗮◌̕b; ) LATIN SMALL LETTER A, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, OL ONAL SIGN MU, LATIN SMALL LETTER B +0061 1E5EE 0315 0300 05AE 0062;0061 05AE 1E5EE 0300 0315 0062;0061 05AE 1E5EE 0300 0315 0062;0061 05AE 1E5EE 0300 0315 0062;0061 05AE 1E5EE 0300 0315 0062; # (a◌𞗮◌̕◌̀◌֮b; a◌֮◌𞗮◌̀◌̕b; a◌֮◌𞗮◌̀◌̕b; a◌֮◌𞗮◌̀◌̕b; a◌֮◌𞗮◌̀◌̕b; ) LATIN SMALL LETTER A, OL ONAL SIGN MU, COMBINING COMMA ABOVE RIGHT, COMBINING GRAVE ACCENT, HEBREW ACCENT ZINOR, LATIN SMALL LETTER B +0061 059A 0316 1DFA 1E5EF 0062;0061 1DFA 0316 1E5EF 059A 0062;0061 1DFA 0316 1E5EF 059A 0062;0061 1DFA 0316 1E5EF 059A 0062;0061 1DFA 0316 1E5EF 059A 0062; # (a◌֚◌̖◌᷺◌𞗯b; a◌᷺◌̖◌𞗯◌֚b; a◌᷺◌̖◌𞗯◌֚b; a◌᷺◌̖◌𞗯◌֚b; a◌᷺◌̖◌𞗯◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, COMBINING DOT BELOW LEFT, OL ONAL SIGN IKIR, LATIN SMALL LETTER B +0061 1E5EF 059A 0316 1DFA 0062;0061 1DFA 1E5EF 0316 059A 0062;0061 1DFA 1E5EF 0316 059A 0062;0061 1DFA 1E5EF 0316 059A 0062;0061 1DFA 1E5EF 0316 059A 0062; # (a◌𞗯◌֚◌̖◌᷺b; a◌᷺◌𞗯◌̖◌֚b; a◌᷺◌𞗯◌̖◌֚b; a◌᷺◌𞗯◌̖◌֚b; a◌᷺◌𞗯◌̖◌֚b; ) LATIN SMALL LETTER A, OL ONAL SIGN IKIR, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, COMBINING DOT BELOW LEFT, LATIN SMALL LETTER B 0061 059A 0316 1DFA 1E8D0 0062;0061 1DFA 0316 1E8D0 059A 0062;0061 1DFA 0316 1E8D0 059A 0062;0061 1DFA 0316 1E8D0 059A 0062;0061 1DFA 0316 1E8D0 059A 0062; # (a◌֚◌̖◌᷺◌𞣐b; a◌᷺◌̖◌𞣐◌֚b; a◌᷺◌̖◌𞣐◌֚b; a◌᷺◌̖◌𞣐◌֚b; a◌᷺◌̖◌𞣐◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, COMBINING DOT BELOW LEFT, MENDE KIKAKUI COMBINING NUMBER TEENS, LATIN SMALL LETTER B 0061 1E8D0 059A 0316 1DFA 0062;0061 1DFA 1E8D0 0316 059A 0062;0061 1DFA 1E8D0 0316 059A 0062;0061 1DFA 1E8D0 0316 059A 0062;0061 1DFA 1E8D0 0316 059A 0062; # (a◌𞣐◌֚◌̖◌᷺b; a◌᷺◌𞣐◌̖◌֚b; a◌᷺◌𞣐◌̖◌֚b; a◌᷺◌𞣐◌̖◌֚b; a◌᷺◌𞣐◌̖◌֚b; ) LATIN SMALL LETTER A, MENDE KIKAKUI COMBINING NUMBER TEENS, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, COMBINING DOT BELOW LEFT, LATIN SMALL LETTER B 0061 059A 0316 1DFA 1E8D1 0062;0061 1DFA 0316 1E8D1 059A 0062;0061 1DFA 0316 1E8D1 059A 0062;0061 1DFA 0316 1E8D1 059A 0062;0061 1DFA 0316 1E8D1 059A 0062; # (a◌֚◌̖◌᷺◌𞣑b; a◌᷺◌̖◌𞣑◌֚b; a◌᷺◌̖◌𞣑◌֚b; a◌᷺◌̖◌𞣑◌֚b; a◌᷺◌̖◌𞣑◌֚b; ) LATIN SMALL LETTER A, HEBREW ACCENT YETIV, COMBINING GRAVE ACCENT BELOW, COMBINING DOT BELOW LEFT, MENDE KIKAKUI COMBINING NUMBER TENS, LATIN SMALL LETTER B @@ -19119,11 +19219,808 @@ D750 0334 11B5;D750 0334 11B5;1112 1173 0334 11B5;D750 0334 11B5;1112 1173 0334 11132 0334 11127;11132 0334 11127;11132 0334 11127;11132 0334 11127;11132 0334 11127; # (◌𑄲◌̴◌𑄧; ◌𑄲◌̴◌𑄧; ◌𑄲◌̴◌𑄧; ◌𑄲◌̴◌𑄧; ◌𑄲◌̴◌𑄧; ) CHAKMA AU MARK, COMBINING TILDE OVERLAY, CHAKMA VOWEL SIGN A 11347 0334 1133E;11347 0334 1133E;11347 0334 1133E;11347 0334 1133E;11347 0334 1133E; # (𑍇◌̴𑌾; 𑍇◌̴𑌾; 𑍇◌̴𑌾; 𑍇◌̴𑌾; 𑍇◌̴𑌾; ) GRANTHA VOWEL SIGN EE, COMBINING TILDE OVERLAY, GRANTHA VOWEL SIGN AA 11347 0334 11357;11347 0334 11357;11347 0334 11357;11347 0334 11357;11347 0334 11357; # (𑍇◌̴𑍗; 𑍇◌̴𑍗; 𑍇◌̴𑍗; 𑍇◌̴𑍗; 𑍇◌̴𑍗; ) GRANTHA VOWEL SIGN EE, COMBINING TILDE OVERLAY, GRANTHA AU LENGTH MARK +11382 0334 113C9;11382 0334 113C9;11382 0334 113C9;11382 0334 113C9;11382 0334 113C9; # (𑎂◌̴𑏉; 𑎂◌̴𑏉; 𑎂◌̴𑏉; 𑎂◌̴𑏉; 𑎂◌̴𑏉; ) TULU-TIGALARI LETTER I, COMBINING TILDE OVERLAY, TULU-TIGALARI AU LENGTH MARK +11384 0334 113BB;11384 0334 113BB;11384 0334 113BB;11384 0334 113BB;11384 0334 113BB; # (𑎄◌̴◌𑎻; 𑎄◌̴◌𑎻; 𑎄◌̴◌𑎻; 𑎄◌̴◌𑎻; 𑎄◌̴◌𑎻; ) TULU-TIGALARI LETTER U, COMBINING TILDE OVERLAY, TULU-TIGALARI VOWEL SIGN U +1138B 0334 113C2;1138B 0334 113C2;1138B 0334 113C2;1138B 0334 113C2;1138B 0334 113C2; # (𑎋◌̴𑏂; 𑎋◌̴𑏂; 𑎋◌̴𑏂; 𑎋◌̴𑏂; 𑎋◌̴𑏂; ) TULU-TIGALARI LETTER EE, COMBINING TILDE OVERLAY, TULU-TIGALARI VOWEL SIGN EE +11390 0334 113C9;11390 0334 113C9;11390 0334 113C9;11390 0334 113C9;11390 0334 113C9; # (𑎐◌̴𑏉; 𑎐◌̴𑏉; 𑎐◌̴𑏉; 𑎐◌̴𑏉; 𑎐◌̴𑏉; ) TULU-TIGALARI LETTER OO, COMBINING TILDE OVERLAY, TULU-TIGALARI AU LENGTH MARK +113C2 0334 113B8;113C2 0334 113B8;113C2 0334 113B8;113C2 0334 113B8;113C2 0334 113B8; # (𑏂◌̴𑎸; 𑏂◌̴𑎸; 𑏂◌̴𑎸; 𑏂◌̴𑎸; 𑏂◌̴𑎸; ) TULU-TIGALARI VOWEL SIGN EE, COMBINING TILDE OVERLAY, TULU-TIGALARI VOWEL SIGN AA +113C2 0334 113C2;113C2 0334 113C2;113C2 0334 113C2;113C2 0334 113C2;113C2 0334 113C2; # (𑏂◌̴𑏂; 𑏂◌̴𑏂; 𑏂◌̴𑏂; 𑏂◌̴𑏂; 𑏂◌̴𑏂; ) TULU-TIGALARI VOWEL SIGN EE, COMBINING TILDE OVERLAY, TULU-TIGALARI VOWEL SIGN EE +113C2 0334 113C9;113C2 0334 113C9;113C2 0334 113C9;113C2 0334 113C9;113C2 0334 113C9; # (𑏂◌̴𑏉; 𑏂◌̴𑏉; 𑏂◌̴𑏉; 𑏂◌̴𑏉; 𑏂◌̴𑏉; ) TULU-TIGALARI VOWEL SIGN EE, COMBINING TILDE OVERLAY, TULU-TIGALARI AU LENGTH MARK 114B9 0334 114B0;114B9 0334 114B0;114B9 0334 114B0;114B9 0334 114B0;114B9 0334 114B0; # (𑒹◌̴𑒰; 𑒹◌̴𑒰; 𑒹◌̴𑒰; 𑒹◌̴𑒰; 𑒹◌̴𑒰; ) TIRHUTA VOWEL SIGN E, COMBINING TILDE OVERLAY, TIRHUTA VOWEL SIGN AA 114B9 0334 114BA;114B9 0334 114BA;114B9 0334 114BA;114B9 0334 114BA;114B9 0334 114BA; # (𑒹◌̴◌𑒺; 𑒹◌̴◌𑒺; 𑒹◌̴◌𑒺; 𑒹◌̴◌𑒺; 𑒹◌̴◌𑒺; ) TIRHUTA VOWEL SIGN E, COMBINING TILDE OVERLAY, TIRHUTA VOWEL SIGN SHORT E 114B9 0334 114BD;114B9 0334 114BD;114B9 0334 114BD;114B9 0334 114BD;114B9 0334 114BD; # (𑒹◌̴𑒽; 𑒹◌̴𑒽; 𑒹◌̴𑒽; 𑒹◌̴𑒽; 𑒹◌̴𑒽; ) TIRHUTA VOWEL SIGN E, COMBINING TILDE OVERLAY, TIRHUTA VOWEL SIGN SHORT O 115B8 0334 115AF;115B8 0334 115AF;115B8 0334 115AF;115B8 0334 115AF;115B8 0334 115AF; # (𑖸◌̴𑖯; 𑖸◌̴𑖯; 𑖸◌̴𑖯; 𑖸◌̴𑖯; 𑖸◌̴𑖯; ) SIDDHAM VOWEL SIGN E, COMBINING TILDE OVERLAY, SIDDHAM VOWEL SIGN AA 115B9 0334 115AF;115B9 0334 115AF;115B9 0334 115AF;115B9 0334 115AF;115B9 0334 115AF; # (𑖹◌̴𑖯; 𑖹◌̴𑖯; 𑖹◌̴𑖯; 𑖹◌̴𑖯; 𑖹◌̴𑖯; ) SIDDHAM VOWEL SIGN AI, COMBINING TILDE OVERLAY, SIDDHAM VOWEL SIGN AA 11935 0334 11930;11935 0334 11930;11935 0334 11930;11935 0334 11930;11935 0334 11930; # (𑤵◌̴𑤰; 𑤵◌̴𑤰; 𑤵◌̴𑤰; 𑤵◌̴𑤰; 𑤵◌̴𑤰; ) DIVES AKURU VOWEL SIGN E, COMBINING TILDE OVERLAY, DIVES AKURU VOWEL SIGN AA +1611E 0334 1611E;1611E 0334 1611E;1611E 0334 1611E;1611E 0334 1611E;1611E 0334 1611E; # (◌𖄞◌̴◌𖄞; ◌𖄞◌̴◌𖄞; ◌𖄞◌̴◌𖄞; ◌𖄞◌̴◌𖄞; ◌𖄞◌̴◌𖄞; ) GURUNG KHEMA VOWEL SIGN AA, COMBINING TILDE OVERLAY, GURUNG KHEMA VOWEL SIGN AA +1611E 0334 1611F;1611E 0334 1611F;1611E 0334 1611F;1611E 0334 1611F;1611E 0334 1611F; # (◌𖄞◌̴◌𖄟; ◌𖄞◌̴◌𖄟; ◌𖄞◌̴◌𖄟; ◌𖄞◌̴◌𖄟; ◌𖄞◌̴◌𖄟; ) GURUNG KHEMA VOWEL SIGN AA, COMBINING TILDE OVERLAY, GURUNG KHEMA VOWEL SIGN I +1611E 0334 16120;1611E 0334 16120;1611E 0334 16120;1611E 0334 16120;1611E 0334 16120; # (◌𖄞◌̴◌𖄠; ◌𖄞◌̴◌𖄠; ◌𖄞◌̴◌𖄠; ◌𖄞◌̴◌𖄠; ◌𖄞◌̴◌𖄠; ) GURUNG KHEMA VOWEL SIGN AA, COMBINING TILDE OVERLAY, GURUNG KHEMA VOWEL SIGN II +1611E 0334 16129;1611E 0334 16129;1611E 0334 16129;1611E 0334 16129;1611E 0334 16129; # (◌𖄞◌̴◌𖄩; ◌𖄞◌̴◌𖄩; ◌𖄞◌̴◌𖄩; ◌𖄞◌̴◌𖄩; ◌𖄞◌̴◌𖄩; ) GURUNG KHEMA VOWEL SIGN AA, COMBINING TILDE OVERLAY, GURUNG KHEMA VOWEL LENGTH MARK +16121 0334 1611F;16121 0334 1611F;1611E 1611E 0334 1611F;16121 0334 1611F;1611E 1611E 0334 1611F; # (◌𖄡◌̴◌𖄟; ◌𖄡◌̴◌𖄟; ◌𖄞◌𖄞◌̴◌𖄟; ◌𖄡◌̴◌𖄟; ◌𖄞◌𖄞◌̴◌𖄟; ) GURUNG KHEMA VOWEL SIGN U, COMBINING TILDE OVERLAY, GURUNG KHEMA VOWEL SIGN I +16121 0334 16120;16121 0334 16120;1611E 1611E 0334 16120;16121 0334 16120;1611E 1611E 0334 16120; # (◌𖄡◌̴◌𖄠; ◌𖄡◌̴◌𖄠; ◌𖄞◌𖄞◌̴◌𖄠; ◌𖄡◌̴◌𖄠; ◌𖄞◌𖄞◌̴◌𖄠; ) GURUNG KHEMA VOWEL SIGN U, COMBINING TILDE OVERLAY, GURUNG KHEMA VOWEL SIGN II +16122 0334 1611F;16122 0334 1611F;1611E 16129 0334 1611F;16122 0334 1611F;1611E 16129 0334 1611F; # (◌𖄢◌̴◌𖄟; ◌𖄢◌̴◌𖄟; ◌𖄞◌𖄩◌̴◌𖄟; ◌𖄢◌̴◌𖄟; ◌𖄞◌𖄩◌̴◌𖄟; ) GURUNG KHEMA VOWEL SIGN UU, COMBINING TILDE OVERLAY, GURUNG KHEMA VOWEL SIGN I +16129 0334 1611F;16129 0334 1611F;16129 0334 1611F;16129 0334 1611F;16129 0334 1611F; # (◌𖄩◌̴◌𖄟; ◌𖄩◌̴◌𖄟; ◌𖄩◌̴◌𖄟; ◌𖄩◌̴◌𖄟; ◌𖄩◌̴◌𖄟; ) GURUNG KHEMA VOWEL LENGTH MARK, COMBINING TILDE OVERLAY, GURUNG KHEMA VOWEL SIGN I +16D63 0334 16D67;16D63 0334 16D67;16D63 0334 16D67;16D63 0334 16D67;16D63 0334 16D67; # (𖵣◌̴𖵧; 𖵣◌̴𖵧; 𖵣◌̴𖵧; 𖵣◌̴𖵧; 𖵣◌̴𖵧; ) KIRAT RAI VOWEL SIGN AA, COMBINING TILDE OVERLAY, KIRAT RAI VOWEL SIGN E +16D67 0334 16D67;16D67 0334 16D67;16D67 0334 16D67;16D67 0334 16D67;16D67 0334 16D67; # (𖵧◌̴𖵧; 𖵧◌̴𖵧; 𖵧◌̴𖵧; 𖵧◌̴𖵧; 𖵧◌̴𖵧; ) KIRAT RAI VOWEL SIGN E, COMBINING TILDE OVERLAY, KIRAT RAI VOWEL SIGN E +16D69 0334 16D67;16D69 0334 16D67;16D63 16D67 0334 16D67;16D69 0334 16D67;16D63 16D67 0334 16D67; # (𖵩◌̴𖵧; 𖵩◌̴𖵧; 𖵩◌̴𖵧; 𖵩◌̴𖵧; 𖵩◌̴𖵧; ) KIRAT RAI VOWEL SIGN O, COMBINING TILDE OVERLAY, KIRAT RAI VOWEL SIGN E +# +@Part4 # Canonical closures (excluding Hangul) +# +00DC 0304;01D5;0055 0308 0304;01D5;0055 0308 0304; # (Ü◌̄; Ǖ; U◌̈◌̄; Ǖ; U◌̈◌̄; ) LATIN CAPITAL LETTER U WITH DIAERESIS, COMBINING MACRON +00FC 0304;01D6;0075 0308 0304;01D6;0075 0308 0304; # (ü◌̄; ǖ; u◌̈◌̄; ǖ; u◌̈◌̄; ) LATIN SMALL LETTER U WITH DIAERESIS, COMBINING MACRON +0055 0344;01D7;0055 0308 0301;01D7;0055 0308 0301; # (U◌̈́; Ǘ; U◌̈◌́; Ǘ; U◌̈◌́; ) LATIN CAPITAL LETTER U, COMBINING GREEK DIALYTIKA TONOS +00DC 0301;01D7;0055 0308 0301;01D7;0055 0308 0301; # (Ü◌́; Ǘ; U◌̈◌́; Ǘ; U◌̈◌́; ) LATIN CAPITAL LETTER U WITH DIAERESIS, COMBINING ACUTE ACCENT +00DC 0341;01D7;0055 0308 0301;01D7;0055 0308 0301; # (Ü◌́; Ǘ; U◌̈◌́; Ǘ; U◌̈◌́; ) LATIN CAPITAL LETTER U WITH DIAERESIS, COMBINING ACUTE TONE MARK +0075 0344;01D8;0075 0308 0301;01D8;0075 0308 0301; # (u◌̈́; ǘ; u◌̈◌́; ǘ; u◌̈◌́; ) LATIN SMALL LETTER U, COMBINING GREEK DIALYTIKA TONOS +00FC 0301;01D8;0075 0308 0301;01D8;0075 0308 0301; # (ü◌́; ǘ; u◌̈◌́; ǘ; u◌̈◌́; ) LATIN SMALL LETTER U WITH DIAERESIS, COMBINING ACUTE ACCENT +00FC 0341;01D8;0075 0308 0301;01D8;0075 0308 0301; # (ü◌́; ǘ; u◌̈◌́; ǘ; u◌̈◌́; ) LATIN SMALL LETTER U WITH DIAERESIS, COMBINING ACUTE TONE MARK +00DC 030C;01D9;0055 0308 030C;01D9;0055 0308 030C; # (Ü◌̌; Ǚ; U◌̈◌̌; Ǚ; U◌̈◌̌; ) LATIN CAPITAL LETTER U WITH DIAERESIS, COMBINING CARON +00FC 030C;01DA;0075 0308 030C;01DA;0075 0308 030C; # (ü◌̌; ǚ; u◌̈◌̌; ǚ; u◌̈◌̌; ) LATIN SMALL LETTER U WITH DIAERESIS, COMBINING CARON +00DC 0300;01DB;0055 0308 0300;01DB;0055 0308 0300; # (Ü◌̀; Ǜ; U◌̈◌̀; Ǜ; U◌̈◌̀; ) LATIN CAPITAL LETTER U WITH DIAERESIS, COMBINING GRAVE ACCENT +00DC 0340;01DB;0055 0308 0300;01DB;0055 0308 0300; # (Ü◌̀; Ǜ; U◌̈◌̀; Ǜ; U◌̈◌̀; ) LATIN CAPITAL LETTER U WITH DIAERESIS, COMBINING GRAVE TONE MARK +00FC 0300;01DC;0075 0308 0300;01DC;0075 0308 0300; # (ü◌̀; ǜ; u◌̈◌̀; ǜ; u◌̈◌̀; ) LATIN SMALL LETTER U WITH DIAERESIS, COMBINING GRAVE ACCENT +00FC 0340;01DC;0075 0308 0300;01DC;0075 0308 0300; # (ü◌̀; ǜ; u◌̈◌̀; ǜ; u◌̈◌̀; ) LATIN SMALL LETTER U WITH DIAERESIS, COMBINING GRAVE TONE MARK +00C4 0304;01DE;0041 0308 0304;01DE;0041 0308 0304; # (Ä◌̄; Ǟ; A◌̈◌̄; Ǟ; A◌̈◌̄; ) LATIN CAPITAL LETTER A WITH DIAERESIS, COMBINING MACRON +00E4 0304;01DF;0061 0308 0304;01DF;0061 0308 0304; # (ä◌̄; ǟ; a◌̈◌̄; ǟ; a◌̈◌̄; ) LATIN SMALL LETTER A WITH DIAERESIS, COMBINING MACRON +0226 0304;01E0;0041 0307 0304;01E0;0041 0307 0304; # (Ȧ◌̄; Ǡ; A◌̇◌̄; Ǡ; A◌̇◌̄; ) LATIN CAPITAL LETTER A WITH DOT ABOVE, COMBINING MACRON +0227 0304;01E1;0061 0307 0304;01E1;0061 0307 0304; # (ȧ◌̄; ǡ; a◌̇◌̄; ǡ; a◌̇◌̄; ) LATIN SMALL LETTER A WITH DOT ABOVE, COMBINING MACRON +014C 0328;01EC;004F 0328 0304;01EC;004F 0328 0304; # (Ō◌̨; Ǭ; O◌̨◌̄; Ǭ; O◌̨◌̄; ) LATIN CAPITAL LETTER O WITH MACRON, COMBINING OGONEK +01EA 0304;01EC;004F 0328 0304;01EC;004F 0328 0304; # (Ǫ◌̄; Ǭ; O◌̨◌̄; Ǭ; O◌̨◌̄; ) LATIN CAPITAL LETTER O WITH OGONEK, COMBINING MACRON +014D 0328;01ED;006F 0328 0304;01ED;006F 0328 0304; # (ō◌̨; ǭ; o◌̨◌̄; ǭ; o◌̨◌̄; ) LATIN SMALL LETTER O WITH MACRON, COMBINING OGONEK +01EB 0304;01ED;006F 0328 0304;01ED;006F 0328 0304; # (ǫ◌̄; ǭ; o◌̨◌̄; ǭ; o◌̨◌̄; ) LATIN SMALL LETTER O WITH OGONEK, COMBINING MACRON +00C5 0301;01FA;0041 030A 0301;01FA;0041 030A 0301; # (Å◌́; Ǻ; A◌̊◌́; Ǻ; A◌̊◌́; ) LATIN CAPITAL LETTER A WITH RING ABOVE, COMBINING ACUTE ACCENT +00C5 0341;01FA;0041 030A 0301;01FA;0041 030A 0301; # (Å◌́; Ǻ; A◌̊◌́; Ǻ; A◌̊◌́; ) LATIN CAPITAL LETTER A WITH RING ABOVE, COMBINING ACUTE TONE MARK +212B 0301;01FA;0041 030A 0301;01FA;0041 030A 0301; # (Å◌́; Ǻ; A◌̊◌́; Ǻ; A◌̊◌́; ) ANGSTROM SIGN, COMBINING ACUTE ACCENT +212B 0341;01FA;0041 030A 0301;01FA;0041 030A 0301; # (Å◌́; Ǻ; A◌̊◌́; Ǻ; A◌̊◌́; ) ANGSTROM SIGN, COMBINING ACUTE TONE MARK +00E5 0301;01FB;0061 030A 0301;01FB;0061 030A 0301; # (å◌́; ǻ; a◌̊◌́; ǻ; a◌̊◌́; ) LATIN SMALL LETTER A WITH RING ABOVE, COMBINING ACUTE ACCENT +00E5 0341;01FB;0061 030A 0301;01FB;0061 030A 0301; # (å◌́; ǻ; a◌̊◌́; ǻ; a◌̊◌́; ) LATIN SMALL LETTER A WITH RING ABOVE, COMBINING ACUTE TONE MARK +00D6 0304;022A;004F 0308 0304;022A;004F 0308 0304; # (Ö◌̄; Ȫ; O◌̈◌̄; Ȫ; O◌̈◌̄; ) LATIN CAPITAL LETTER O WITH DIAERESIS, COMBINING MACRON +00F6 0304;022B;006F 0308 0304;022B;006F 0308 0304; # (ö◌̄; ȫ; o◌̈◌̄; ȫ; o◌̈◌̄; ) LATIN SMALL LETTER O WITH DIAERESIS, COMBINING MACRON +00D5 0304;022C;004F 0303 0304;022C;004F 0303 0304; # (Õ◌̄; Ȭ; O◌̃◌̄; Ȭ; O◌̃◌̄; ) LATIN CAPITAL LETTER O WITH TILDE, COMBINING MACRON +00F5 0304;022D;006F 0303 0304;022D;006F 0303 0304; # (õ◌̄; ȭ; o◌̃◌̄; ȭ; o◌̃◌̄; ) LATIN SMALL LETTER O WITH TILDE, COMBINING MACRON +022E 0304;0230;004F 0307 0304;0230;004F 0307 0304; # (Ȯ◌̄; Ȱ; O◌̇◌̄; Ȱ; O◌̇◌̄; ) LATIN CAPITAL LETTER O WITH DOT ABOVE, COMBINING MACRON +022F 0304;0231;006F 0307 0304;0231;006F 0307 0304; # (ȯ◌̄; ȱ; o◌̇◌̄; ȱ; o◌̇◌̄; ) LATIN SMALL LETTER O WITH DOT ABOVE, COMBINING MACRON +03B9 0344;0390;03B9 0308 0301;0390;03B9 0308 0301; # (ι◌̈́; ΐ; ι◌̈◌́; ΐ; ι◌̈◌́; ) GREEK SMALL LETTER IOTA, COMBINING GREEK DIALYTIKA TONOS +03CA 0301;0390;03B9 0308 0301;0390;03B9 0308 0301; # (ϊ◌́; ΐ; ι◌̈◌́; ΐ; ι◌̈◌́; ) GREEK SMALL LETTER IOTA WITH DIALYTIKA, COMBINING ACUTE ACCENT +03CA 0341;0390;03B9 0308 0301;0390;03B9 0308 0301; # (ϊ◌́; ΐ; ι◌̈◌́; ΐ; ι◌̈◌́; ) GREEK SMALL LETTER IOTA WITH DIALYTIKA, COMBINING ACUTE TONE MARK +1FBE 0344;0390;03B9 0308 0301;0390;03B9 0308 0301; # (ι◌̈́; ΐ; ι◌̈◌́; ΐ; ι◌̈◌́; ) GREEK PROSGEGRAMMENI, COMBINING GREEK DIALYTIKA TONOS +03C5 0344;03B0;03C5 0308 0301;03B0;03C5 0308 0301; # (υ◌̈́; ΰ; υ◌̈◌́; ΰ; υ◌̈◌́; ) GREEK SMALL LETTER UPSILON, COMBINING GREEK DIALYTIKA TONOS +03CB 0301;03B0;03C5 0308 0301;03B0;03C5 0308 0301; # (ϋ◌́; ΰ; υ◌̈◌́; ΰ; υ◌̈◌́; ) GREEK SMALL LETTER UPSILON WITH DIALYTIKA, COMBINING ACUTE ACCENT +03CB 0341;03B0;03C5 0308 0301;03B0;03C5 0308 0301; # (ϋ◌́; ΰ; υ◌̈◌́; ΰ; υ◌̈◌́; ) GREEK SMALL LETTER UPSILON WITH DIALYTIKA, COMBINING ACUTE TONE MARK +0CCA 0CD5;0CCB;0CC6 0CC2 0CD5;0CCB;0CC6 0CC2 0CD5; # (ೋ; ೋ; ◌ೋ; ೋ; ◌ೋ; ) KANNADA VOWEL SIGN O, KANNADA LENGTH MARK +0DDC 0DCA;0DDD;0DD9 0DCF 0DCA;0DDD;0DD9 0DCF 0DCA; # (ො◌්; ෝ; ො◌්; ෝ; ො◌්; ) SINHALA VOWEL SIGN KOMBUVA HAA AELA-PILLA, SINHALA SIGN AL-LAKUNA +00C7 0301;1E08;0043 0327 0301;1E08;0043 0327 0301; # (Ç◌́; Ḉ; C◌̧◌́; Ḉ; C◌̧◌́; ) LATIN CAPITAL LETTER C WITH CEDILLA, COMBINING ACUTE ACCENT +00C7 0341;1E08;0043 0327 0301;1E08;0043 0327 0301; # (Ç◌́; Ḉ; C◌̧◌́; Ḉ; C◌̧◌́; ) LATIN CAPITAL LETTER C WITH CEDILLA, COMBINING ACUTE TONE MARK +0106 0327;1E08;0043 0327 0301;1E08;0043 0327 0301; # (Ć◌̧; Ḉ; C◌̧◌́; Ḉ; C◌̧◌́; ) LATIN CAPITAL LETTER C WITH ACUTE, COMBINING CEDILLA +00E7 0301;1E09;0063 0327 0301;1E09;0063 0327 0301; # (ç◌́; ḉ; c◌̧◌́; ḉ; c◌̧◌́; ) LATIN SMALL LETTER C WITH CEDILLA, COMBINING ACUTE ACCENT +00E7 0341;1E09;0063 0327 0301;1E09;0063 0327 0301; # (ç◌́; ḉ; c◌̧◌́; ḉ; c◌̧◌́; ) LATIN SMALL LETTER C WITH CEDILLA, COMBINING ACUTE TONE MARK +0107 0327;1E09;0063 0327 0301;1E09;0063 0327 0301; # (ć◌̧; ḉ; c◌̧◌́; ḉ; c◌̧◌́; ) LATIN SMALL LETTER C WITH ACUTE, COMBINING CEDILLA +0112 0300;1E14;0045 0304 0300;1E14;0045 0304 0300; # (Ē◌̀; Ḕ; E◌̄◌̀; Ḕ; E◌̄◌̀; ) LATIN CAPITAL LETTER E WITH MACRON, COMBINING GRAVE ACCENT +0112 0340;1E14;0045 0304 0300;1E14;0045 0304 0300; # (Ē◌̀; Ḕ; E◌̄◌̀; Ḕ; E◌̄◌̀; ) LATIN CAPITAL LETTER E WITH MACRON, COMBINING GRAVE TONE MARK +0113 0300;1E15;0065 0304 0300;1E15;0065 0304 0300; # (ē◌̀; ḕ; e◌̄◌̀; ḕ; e◌̄◌̀; ) LATIN SMALL LETTER E WITH MACRON, COMBINING GRAVE ACCENT +0113 0340;1E15;0065 0304 0300;1E15;0065 0304 0300; # (ē◌̀; ḕ; e◌̄◌̀; ḕ; e◌̄◌̀; ) LATIN SMALL LETTER E WITH MACRON, COMBINING GRAVE TONE MARK +0112 0301;1E16;0045 0304 0301;1E16;0045 0304 0301; # (Ē◌́; Ḗ; E◌̄◌́; Ḗ; E◌̄◌́; ) LATIN CAPITAL LETTER E WITH MACRON, COMBINING ACUTE ACCENT +0112 0341;1E16;0045 0304 0301;1E16;0045 0304 0301; # (Ē◌́; Ḗ; E◌̄◌́; Ḗ; E◌̄◌́; ) LATIN CAPITAL LETTER E WITH MACRON, COMBINING ACUTE TONE MARK +0113 0301;1E17;0065 0304 0301;1E17;0065 0304 0301; # (ē◌́; ḗ; e◌̄◌́; ḗ; e◌̄◌́; ) LATIN SMALL LETTER E WITH MACRON, COMBINING ACUTE ACCENT +0113 0341;1E17;0065 0304 0301;1E17;0065 0304 0301; # (ē◌́; ḗ; e◌̄◌́; ḗ; e◌̄◌́; ) LATIN SMALL LETTER E WITH MACRON, COMBINING ACUTE TONE MARK +0114 0327;1E1C;0045 0327 0306;1E1C;0045 0327 0306; # (Ĕ◌̧; Ḝ; E◌̧◌̆; Ḝ; E◌̧◌̆; ) LATIN CAPITAL LETTER E WITH BREVE, COMBINING CEDILLA +0228 0306;1E1C;0045 0327 0306;1E1C;0045 0327 0306; # (Ȩ◌̆; Ḝ; E◌̧◌̆; Ḝ; E◌̧◌̆; ) LATIN CAPITAL LETTER E WITH CEDILLA, COMBINING BREVE +0115 0327;1E1D;0065 0327 0306;1E1D;0065 0327 0306; # (ĕ◌̧; ḝ; e◌̧◌̆; ḝ; e◌̧◌̆; ) LATIN SMALL LETTER E WITH BREVE, COMBINING CEDILLA +0229 0306;1E1D;0065 0327 0306;1E1D;0065 0327 0306; # (ȩ◌̆; ḝ; e◌̧◌̆; ḝ; e◌̧◌̆; ) LATIN SMALL LETTER E WITH CEDILLA, COMBINING BREVE +0049 0344;1E2E;0049 0308 0301;1E2E;0049 0308 0301; # (I◌̈́; Ḯ; I◌̈◌́; Ḯ; I◌̈◌́; ) LATIN CAPITAL LETTER I, COMBINING GREEK DIALYTIKA TONOS +00CF 0301;1E2E;0049 0308 0301;1E2E;0049 0308 0301; # (Ï◌́; Ḯ; I◌̈◌́; Ḯ; I◌̈◌́; ) LATIN CAPITAL LETTER I WITH DIAERESIS, COMBINING ACUTE ACCENT +00CF 0341;1E2E;0049 0308 0301;1E2E;0049 0308 0301; # (Ï◌́; Ḯ; I◌̈◌́; Ḯ; I◌̈◌́; ) LATIN CAPITAL LETTER I WITH DIAERESIS, COMBINING ACUTE TONE MARK +0069 0344;1E2F;0069 0308 0301;1E2F;0069 0308 0301; # (i◌̈́; ḯ; i◌̈◌́; ḯ; i◌̈◌́; ) LATIN SMALL LETTER I, COMBINING GREEK DIALYTIKA TONOS +00EF 0301;1E2F;0069 0308 0301;1E2F;0069 0308 0301; # (ï◌́; ḯ; i◌̈◌́; ḯ; i◌̈◌́; ) LATIN SMALL LETTER I WITH DIAERESIS, COMBINING ACUTE ACCENT +00EF 0341;1E2F;0069 0308 0301;1E2F;0069 0308 0301; # (ï◌́; ḯ; i◌̈◌́; ḯ; i◌̈◌́; ) LATIN SMALL LETTER I WITH DIAERESIS, COMBINING ACUTE TONE MARK +1E36 0304;1E38;004C 0323 0304;1E38;004C 0323 0304; # (Ḷ◌̄; Ḹ; L◌̣◌̄; Ḹ; L◌̣◌̄; ) LATIN CAPITAL LETTER L WITH DOT BELOW, COMBINING MACRON +1E37 0304;1E39;006C 0323 0304;1E39;006C 0323 0304; # (ḷ◌̄; ḹ; l◌̣◌̄; ḹ; l◌̣◌̄; ) LATIN SMALL LETTER L WITH DOT BELOW, COMBINING MACRON +00D5 0301;1E4C;004F 0303 0301;1E4C;004F 0303 0301; # (Õ◌́; Ṍ; O◌̃◌́; Ṍ; O◌̃◌́; ) LATIN CAPITAL LETTER O WITH TILDE, COMBINING ACUTE ACCENT +00D5 0341;1E4C;004F 0303 0301;1E4C;004F 0303 0301; # (Õ◌́; Ṍ; O◌̃◌́; Ṍ; O◌̃◌́; ) LATIN CAPITAL LETTER O WITH TILDE, COMBINING ACUTE TONE MARK +00F5 0301;1E4D;006F 0303 0301;1E4D;006F 0303 0301; # (õ◌́; ṍ; o◌̃◌́; ṍ; o◌̃◌́; ) LATIN SMALL LETTER O WITH TILDE, COMBINING ACUTE ACCENT +00F5 0341;1E4D;006F 0303 0301;1E4D;006F 0303 0301; # (õ◌́; ṍ; o◌̃◌́; ṍ; o◌̃◌́; ) LATIN SMALL LETTER O WITH TILDE, COMBINING ACUTE TONE MARK +00D5 0308;1E4E;004F 0303 0308;1E4E;004F 0303 0308; # (Õ◌̈; Ṏ; O◌̃◌̈; Ṏ; O◌̃◌̈; ) LATIN CAPITAL LETTER O WITH TILDE, COMBINING DIAERESIS +00F5 0308;1E4F;006F 0303 0308;1E4F;006F 0303 0308; # (õ◌̈; ṏ; o◌̃◌̈; ṏ; o◌̃◌̈; ) LATIN SMALL LETTER O WITH TILDE, COMBINING DIAERESIS +014C 0300;1E50;004F 0304 0300;1E50;004F 0304 0300; # (Ō◌̀; Ṑ; O◌̄◌̀; Ṑ; O◌̄◌̀; ) LATIN CAPITAL LETTER O WITH MACRON, COMBINING GRAVE ACCENT +014C 0340;1E50;004F 0304 0300;1E50;004F 0304 0300; # (Ō◌̀; Ṑ; O◌̄◌̀; Ṑ; O◌̄◌̀; ) LATIN CAPITAL LETTER O WITH MACRON, COMBINING GRAVE TONE MARK +014D 0300;1E51;006F 0304 0300;1E51;006F 0304 0300; # (ō◌̀; ṑ; o◌̄◌̀; ṑ; o◌̄◌̀; ) LATIN SMALL LETTER O WITH MACRON, COMBINING GRAVE ACCENT +014D 0340;1E51;006F 0304 0300;1E51;006F 0304 0300; # (ō◌̀; ṑ; o◌̄◌̀; ṑ; o◌̄◌̀; ) LATIN SMALL LETTER O WITH MACRON, COMBINING GRAVE TONE MARK +014C 0301;1E52;004F 0304 0301;1E52;004F 0304 0301; # (Ō◌́; Ṓ; O◌̄◌́; Ṓ; O◌̄◌́; ) LATIN CAPITAL LETTER O WITH MACRON, COMBINING ACUTE ACCENT +014C 0341;1E52;004F 0304 0301;1E52;004F 0304 0301; # (Ō◌́; Ṓ; O◌̄◌́; Ṓ; O◌̄◌́; ) LATIN CAPITAL LETTER O WITH MACRON, COMBINING ACUTE TONE MARK +014D 0301;1E53;006F 0304 0301;1E53;006F 0304 0301; # (ō◌́; ṓ; o◌̄◌́; ṓ; o◌̄◌́; ) LATIN SMALL LETTER O WITH MACRON, COMBINING ACUTE ACCENT +014D 0341;1E53;006F 0304 0301;1E53;006F 0304 0301; # (ō◌́; ṓ; o◌̄◌́; ṓ; o◌̄◌́; ) LATIN SMALL LETTER O WITH MACRON, COMBINING ACUTE TONE MARK +1E5A 0304;1E5C;0052 0323 0304;1E5C;0052 0323 0304; # (Ṛ◌̄; Ṝ; R◌̣◌̄; Ṝ; R◌̣◌̄; ) LATIN CAPITAL LETTER R WITH DOT BELOW, COMBINING MACRON +1E5B 0304;1E5D;0072 0323 0304;1E5D;0072 0323 0304; # (ṛ◌̄; ṝ; r◌̣◌̄; ṝ; r◌̣◌̄; ) LATIN SMALL LETTER R WITH DOT BELOW, COMBINING MACRON +015A 0307;1E64;0053 0301 0307;1E64;0053 0301 0307; # (Ś◌̇; Ṥ; S◌́◌̇; Ṥ; S◌́◌̇; ) LATIN CAPITAL LETTER S WITH ACUTE, COMBINING DOT ABOVE +015B 0307;1E65;0073 0301 0307;1E65;0073 0301 0307; # (ś◌̇; ṥ; s◌́◌̇; ṥ; s◌́◌̇; ) LATIN SMALL LETTER S WITH ACUTE, COMBINING DOT ABOVE +0160 0307;1E66;0053 030C 0307;1E66;0053 030C 0307; # (Š◌̇; Ṧ; S◌̌◌̇; Ṧ; S◌̌◌̇; ) LATIN CAPITAL LETTER S WITH CARON, COMBINING DOT ABOVE +0161 0307;1E67;0073 030C 0307;1E67;0073 030C 0307; # (š◌̇; ṧ; s◌̌◌̇; ṧ; s◌̌◌̇; ) LATIN SMALL LETTER S WITH CARON, COMBINING DOT ABOVE +1E60 0323;1E68;0053 0323 0307;1E68;0053 0323 0307; # (Ṡ◌̣; Ṩ; S◌̣◌̇; Ṩ; S◌̣◌̇; ) LATIN CAPITAL LETTER S WITH DOT ABOVE, COMBINING DOT BELOW +1E62 0307;1E68;0053 0323 0307;1E68;0053 0323 0307; # (Ṣ◌̇; Ṩ; S◌̣◌̇; Ṩ; S◌̣◌̇; ) LATIN CAPITAL LETTER S WITH DOT BELOW, COMBINING DOT ABOVE +1E61 0323;1E69;0073 0323 0307;1E69;0073 0323 0307; # (ṡ◌̣; ṩ; s◌̣◌̇; ṩ; s◌̣◌̇; ) LATIN SMALL LETTER S WITH DOT ABOVE, COMBINING DOT BELOW +1E63 0307;1E69;0073 0323 0307;1E69;0073 0323 0307; # (ṣ◌̇; ṩ; s◌̣◌̇; ṩ; s◌̣◌̇; ) LATIN SMALL LETTER S WITH DOT BELOW, COMBINING DOT ABOVE +0168 0301;1E78;0055 0303 0301;1E78;0055 0303 0301; # (Ũ◌́; Ṹ; U◌̃◌́; Ṹ; U◌̃◌́; ) LATIN CAPITAL LETTER U WITH TILDE, COMBINING ACUTE ACCENT +0168 0341;1E78;0055 0303 0301;1E78;0055 0303 0301; # (Ũ◌́; Ṹ; U◌̃◌́; Ṹ; U◌̃◌́; ) LATIN CAPITAL LETTER U WITH TILDE, COMBINING ACUTE TONE MARK +0169 0301;1E79;0075 0303 0301;1E79;0075 0303 0301; # (ũ◌́; ṹ; u◌̃◌́; ṹ; u◌̃◌́; ) LATIN SMALL LETTER U WITH TILDE, COMBINING ACUTE ACCENT +0169 0341;1E79;0075 0303 0301;1E79;0075 0303 0301; # (ũ◌́; ṹ; u◌̃◌́; ṹ; u◌̃◌́; ) LATIN SMALL LETTER U WITH TILDE, COMBINING ACUTE TONE MARK +016A 0308;1E7A;0055 0304 0308;1E7A;0055 0304 0308; # (Ū◌̈; Ṻ; U◌̄◌̈; Ṻ; U◌̄◌̈; ) LATIN CAPITAL LETTER U WITH MACRON, COMBINING DIAERESIS +016B 0308;1E7B;0075 0304 0308;1E7B;0075 0304 0308; # (ū◌̈; ṻ; u◌̄◌̈; ṻ; u◌̄◌̈; ) LATIN SMALL LETTER U WITH MACRON, COMBINING DIAERESIS +00C2 0301;1EA4;0041 0302 0301;1EA4;0041 0302 0301; # (Â◌́; Ấ; A◌̂◌́; Ấ; A◌̂◌́; ) LATIN CAPITAL LETTER A WITH CIRCUMFLEX, COMBINING ACUTE ACCENT +00C2 0341;1EA4;0041 0302 0301;1EA4;0041 0302 0301; # (Â◌́; Ấ; A◌̂◌́; Ấ; A◌̂◌́; ) LATIN CAPITAL LETTER A WITH CIRCUMFLEX, COMBINING ACUTE TONE MARK +00E2 0301;1EA5;0061 0302 0301;1EA5;0061 0302 0301; # (â◌́; ấ; a◌̂◌́; ấ; a◌̂◌́; ) LATIN SMALL LETTER A WITH CIRCUMFLEX, COMBINING ACUTE ACCENT +00E2 0341;1EA5;0061 0302 0301;1EA5;0061 0302 0301; # (â◌́; ấ; a◌̂◌́; ấ; a◌̂◌́; ) LATIN SMALL LETTER A WITH CIRCUMFLEX, COMBINING ACUTE TONE MARK +00C2 0300;1EA6;0041 0302 0300;1EA6;0041 0302 0300; # (Â◌̀; Ầ; A◌̂◌̀; Ầ; A◌̂◌̀; ) LATIN CAPITAL LETTER A WITH CIRCUMFLEX, COMBINING GRAVE ACCENT +00C2 0340;1EA6;0041 0302 0300;1EA6;0041 0302 0300; # (Â◌̀; Ầ; A◌̂◌̀; Ầ; A◌̂◌̀; ) LATIN CAPITAL LETTER A WITH CIRCUMFLEX, COMBINING GRAVE TONE MARK +00E2 0300;1EA7;0061 0302 0300;1EA7;0061 0302 0300; # (â◌̀; ầ; a◌̂◌̀; ầ; a◌̂◌̀; ) LATIN SMALL LETTER A WITH CIRCUMFLEX, COMBINING GRAVE ACCENT +00E2 0340;1EA7;0061 0302 0300;1EA7;0061 0302 0300; # (â◌̀; ầ; a◌̂◌̀; ầ; a◌̂◌̀; ) LATIN SMALL LETTER A WITH CIRCUMFLEX, COMBINING GRAVE TONE MARK +00C2 0309;1EA8;0041 0302 0309;1EA8;0041 0302 0309; # (Â◌̉; Ẩ; A◌̂◌̉; Ẩ; A◌̂◌̉; ) LATIN CAPITAL LETTER A WITH CIRCUMFLEX, COMBINING HOOK ABOVE +00E2 0309;1EA9;0061 0302 0309;1EA9;0061 0302 0309; # (â◌̉; ẩ; a◌̂◌̉; ẩ; a◌̂◌̉; ) LATIN SMALL LETTER A WITH CIRCUMFLEX, COMBINING HOOK ABOVE +00C2 0303;1EAA;0041 0302 0303;1EAA;0041 0302 0303; # (Â◌̃; Ẫ; A◌̂◌̃; Ẫ; A◌̂◌̃; ) LATIN CAPITAL LETTER A WITH CIRCUMFLEX, COMBINING TILDE +00E2 0303;1EAB;0061 0302 0303;1EAB;0061 0302 0303; # (â◌̃; ẫ; a◌̂◌̃; ẫ; a◌̂◌̃; ) LATIN SMALL LETTER A WITH CIRCUMFLEX, COMBINING TILDE +00C2 0323;1EAC;0041 0323 0302;1EAC;0041 0323 0302; # (Â◌̣; Ậ; A◌̣◌̂; Ậ; A◌̣◌̂; ) LATIN CAPITAL LETTER A WITH CIRCUMFLEX, COMBINING DOT BELOW +1EA0 0302;1EAC;0041 0323 0302;1EAC;0041 0323 0302; # (Ạ◌̂; Ậ; A◌̣◌̂; Ậ; A◌̣◌̂; ) LATIN CAPITAL LETTER A WITH DOT BELOW, COMBINING CIRCUMFLEX ACCENT +00E2 0323;1EAD;0061 0323 0302;1EAD;0061 0323 0302; # (â◌̣; ậ; a◌̣◌̂; ậ; a◌̣◌̂; ) LATIN SMALL LETTER A WITH CIRCUMFLEX, COMBINING DOT BELOW +1EA1 0302;1EAD;0061 0323 0302;1EAD;0061 0323 0302; # (ạ◌̂; ậ; a◌̣◌̂; ậ; a◌̣◌̂; ) LATIN SMALL LETTER A WITH DOT BELOW, COMBINING CIRCUMFLEX ACCENT +0102 0301;1EAE;0041 0306 0301;1EAE;0041 0306 0301; # (Ă◌́; Ắ; A◌̆◌́; Ắ; A◌̆◌́; ) LATIN CAPITAL LETTER A WITH BREVE, COMBINING ACUTE ACCENT +0102 0341;1EAE;0041 0306 0301;1EAE;0041 0306 0301; # (Ă◌́; Ắ; A◌̆◌́; Ắ; A◌̆◌́; ) LATIN CAPITAL LETTER A WITH BREVE, COMBINING ACUTE TONE MARK +0103 0301;1EAF;0061 0306 0301;1EAF;0061 0306 0301; # (ă◌́; ắ; a◌̆◌́; ắ; a◌̆◌́; ) LATIN SMALL LETTER A WITH BREVE, COMBINING ACUTE ACCENT +0103 0341;1EAF;0061 0306 0301;1EAF;0061 0306 0301; # (ă◌́; ắ; a◌̆◌́; ắ; a◌̆◌́; ) LATIN SMALL LETTER A WITH BREVE, COMBINING ACUTE TONE MARK +0102 0300;1EB0;0041 0306 0300;1EB0;0041 0306 0300; # (Ă◌̀; Ằ; A◌̆◌̀; Ằ; A◌̆◌̀; ) LATIN CAPITAL LETTER A WITH BREVE, COMBINING GRAVE ACCENT +0102 0340;1EB0;0041 0306 0300;1EB0;0041 0306 0300; # (Ă◌̀; Ằ; A◌̆◌̀; Ằ; A◌̆◌̀; ) LATIN CAPITAL LETTER A WITH BREVE, COMBINING GRAVE TONE MARK +0103 0300;1EB1;0061 0306 0300;1EB1;0061 0306 0300; # (ă◌̀; ằ; a◌̆◌̀; ằ; a◌̆◌̀; ) LATIN SMALL LETTER A WITH BREVE, COMBINING GRAVE ACCENT +0103 0340;1EB1;0061 0306 0300;1EB1;0061 0306 0300; # (ă◌̀; ằ; a◌̆◌̀; ằ; a◌̆◌̀; ) LATIN SMALL LETTER A WITH BREVE, COMBINING GRAVE TONE MARK +0102 0309;1EB2;0041 0306 0309;1EB2;0041 0306 0309; # (Ă◌̉; Ẳ; A◌̆◌̉; Ẳ; A◌̆◌̉; ) LATIN CAPITAL LETTER A WITH BREVE, COMBINING HOOK ABOVE +0103 0309;1EB3;0061 0306 0309;1EB3;0061 0306 0309; # (ă◌̉; ẳ; a◌̆◌̉; ẳ; a◌̆◌̉; ) LATIN SMALL LETTER A WITH BREVE, COMBINING HOOK ABOVE +0102 0303;1EB4;0041 0306 0303;1EB4;0041 0306 0303; # (Ă◌̃; Ẵ; A◌̆◌̃; Ẵ; A◌̆◌̃; ) LATIN CAPITAL LETTER A WITH BREVE, COMBINING TILDE +0103 0303;1EB5;0061 0306 0303;1EB5;0061 0306 0303; # (ă◌̃; ẵ; a◌̆◌̃; ẵ; a◌̆◌̃; ) LATIN SMALL LETTER A WITH BREVE, COMBINING TILDE +0102 0323;1EB6;0041 0323 0306;1EB6;0041 0323 0306; # (Ă◌̣; Ặ; A◌̣◌̆; Ặ; A◌̣◌̆; ) LATIN CAPITAL LETTER A WITH BREVE, COMBINING DOT BELOW +1EA0 0306;1EB6;0041 0323 0306;1EB6;0041 0323 0306; # (Ạ◌̆; Ặ; A◌̣◌̆; Ặ; A◌̣◌̆; ) LATIN CAPITAL LETTER A WITH DOT BELOW, COMBINING BREVE +0103 0323;1EB7;0061 0323 0306;1EB7;0061 0323 0306; # (ă◌̣; ặ; a◌̣◌̆; ặ; a◌̣◌̆; ) LATIN SMALL LETTER A WITH BREVE, COMBINING DOT BELOW +1EA1 0306;1EB7;0061 0323 0306;1EB7;0061 0323 0306; # (ạ◌̆; ặ; a◌̣◌̆; ặ; a◌̣◌̆; ) LATIN SMALL LETTER A WITH DOT BELOW, COMBINING BREVE +00CA 0301;1EBE;0045 0302 0301;1EBE;0045 0302 0301; # (Ê◌́; Ế; E◌̂◌́; Ế; E◌̂◌́; ) LATIN CAPITAL LETTER E WITH CIRCUMFLEX, COMBINING ACUTE ACCENT +00CA 0341;1EBE;0045 0302 0301;1EBE;0045 0302 0301; # (Ê◌́; Ế; E◌̂◌́; Ế; E◌̂◌́; ) LATIN CAPITAL LETTER E WITH CIRCUMFLEX, COMBINING ACUTE TONE MARK +00EA 0301;1EBF;0065 0302 0301;1EBF;0065 0302 0301; # (ê◌́; ế; e◌̂◌́; ế; e◌̂◌́; ) LATIN SMALL LETTER E WITH CIRCUMFLEX, COMBINING ACUTE ACCENT +00EA 0341;1EBF;0065 0302 0301;1EBF;0065 0302 0301; # (ê◌́; ế; e◌̂◌́; ế; e◌̂◌́; ) LATIN SMALL LETTER E WITH CIRCUMFLEX, COMBINING ACUTE TONE MARK +00CA 0300;1EC0;0045 0302 0300;1EC0;0045 0302 0300; # (Ê◌̀; Ề; E◌̂◌̀; Ề; E◌̂◌̀; ) LATIN CAPITAL LETTER E WITH CIRCUMFLEX, COMBINING GRAVE ACCENT +00CA 0340;1EC0;0045 0302 0300;1EC0;0045 0302 0300; # (Ê◌̀; Ề; E◌̂◌̀; Ề; E◌̂◌̀; ) LATIN CAPITAL LETTER E WITH CIRCUMFLEX, COMBINING GRAVE TONE MARK +00EA 0300;1EC1;0065 0302 0300;1EC1;0065 0302 0300; # (ê◌̀; ề; e◌̂◌̀; ề; e◌̂◌̀; ) LATIN SMALL LETTER E WITH CIRCUMFLEX, COMBINING GRAVE ACCENT +00EA 0340;1EC1;0065 0302 0300;1EC1;0065 0302 0300; # (ê◌̀; ề; e◌̂◌̀; ề; e◌̂◌̀; ) LATIN SMALL LETTER E WITH CIRCUMFLEX, COMBINING GRAVE TONE MARK +00CA 0309;1EC2;0045 0302 0309;1EC2;0045 0302 0309; # (Ê◌̉; Ể; E◌̂◌̉; Ể; E◌̂◌̉; ) LATIN CAPITAL LETTER E WITH CIRCUMFLEX, COMBINING HOOK ABOVE +00EA 0309;1EC3;0065 0302 0309;1EC3;0065 0302 0309; # (ê◌̉; ể; e◌̂◌̉; ể; e◌̂◌̉; ) LATIN SMALL LETTER E WITH CIRCUMFLEX, COMBINING HOOK ABOVE +00CA 0303;1EC4;0045 0302 0303;1EC4;0045 0302 0303; # (Ê◌̃; Ễ; E◌̂◌̃; Ễ; E◌̂◌̃; ) LATIN CAPITAL LETTER E WITH CIRCUMFLEX, COMBINING TILDE +00EA 0303;1EC5;0065 0302 0303;1EC5;0065 0302 0303; # (ê◌̃; ễ; e◌̂◌̃; ễ; e◌̂◌̃; ) LATIN SMALL LETTER E WITH CIRCUMFLEX, COMBINING TILDE +00CA 0323;1EC6;0045 0323 0302;1EC6;0045 0323 0302; # (Ê◌̣; Ệ; E◌̣◌̂; Ệ; E◌̣◌̂; ) LATIN CAPITAL LETTER E WITH CIRCUMFLEX, COMBINING DOT BELOW +1EB8 0302;1EC6;0045 0323 0302;1EC6;0045 0323 0302; # (Ẹ◌̂; Ệ; E◌̣◌̂; Ệ; E◌̣◌̂; ) LATIN CAPITAL LETTER E WITH DOT BELOW, COMBINING CIRCUMFLEX ACCENT +00EA 0323;1EC7;0065 0323 0302;1EC7;0065 0323 0302; # (ê◌̣; ệ; e◌̣◌̂; ệ; e◌̣◌̂; ) LATIN SMALL LETTER E WITH CIRCUMFLEX, COMBINING DOT BELOW +1EB9 0302;1EC7;0065 0323 0302;1EC7;0065 0323 0302; # (ẹ◌̂; ệ; e◌̣◌̂; ệ; e◌̣◌̂; ) LATIN SMALL LETTER E WITH DOT BELOW, COMBINING CIRCUMFLEX ACCENT +00D4 0301;1ED0;004F 0302 0301;1ED0;004F 0302 0301; # (Ô◌́; Ố; O◌̂◌́; Ố; O◌̂◌́; ) LATIN CAPITAL LETTER O WITH CIRCUMFLEX, COMBINING ACUTE ACCENT +00D4 0341;1ED0;004F 0302 0301;1ED0;004F 0302 0301; # (Ô◌́; Ố; O◌̂◌́; Ố; O◌̂◌́; ) LATIN CAPITAL LETTER O WITH CIRCUMFLEX, COMBINING ACUTE TONE MARK +00F4 0301;1ED1;006F 0302 0301;1ED1;006F 0302 0301; # (ô◌́; ố; o◌̂◌́; ố; o◌̂◌́; ) LATIN SMALL LETTER O WITH CIRCUMFLEX, COMBINING ACUTE ACCENT +00F4 0341;1ED1;006F 0302 0301;1ED1;006F 0302 0301; # (ô◌́; ố; o◌̂◌́; ố; o◌̂◌́; ) LATIN SMALL LETTER O WITH CIRCUMFLEX, COMBINING ACUTE TONE MARK +00D4 0300;1ED2;004F 0302 0300;1ED2;004F 0302 0300; # (Ô◌̀; Ồ; O◌̂◌̀; Ồ; O◌̂◌̀; ) LATIN CAPITAL LETTER O WITH CIRCUMFLEX, COMBINING GRAVE ACCENT +00D4 0340;1ED2;004F 0302 0300;1ED2;004F 0302 0300; # (Ô◌̀; Ồ; O◌̂◌̀; Ồ; O◌̂◌̀; ) LATIN CAPITAL LETTER O WITH CIRCUMFLEX, COMBINING GRAVE TONE MARK +00F4 0300;1ED3;006F 0302 0300;1ED3;006F 0302 0300; # (ô◌̀; ồ; o◌̂◌̀; ồ; o◌̂◌̀; ) LATIN SMALL LETTER O WITH CIRCUMFLEX, COMBINING GRAVE ACCENT +00F4 0340;1ED3;006F 0302 0300;1ED3;006F 0302 0300; # (ô◌̀; ồ; o◌̂◌̀; ồ; o◌̂◌̀; ) LATIN SMALL LETTER O WITH CIRCUMFLEX, COMBINING GRAVE TONE MARK +00D4 0309;1ED4;004F 0302 0309;1ED4;004F 0302 0309; # (Ô◌̉; Ổ; O◌̂◌̉; Ổ; O◌̂◌̉; ) LATIN CAPITAL LETTER O WITH CIRCUMFLEX, COMBINING HOOK ABOVE +00F4 0309;1ED5;006F 0302 0309;1ED5;006F 0302 0309; # (ô◌̉; ổ; o◌̂◌̉; ổ; o◌̂◌̉; ) LATIN SMALL LETTER O WITH CIRCUMFLEX, COMBINING HOOK ABOVE +00D4 0303;1ED6;004F 0302 0303;1ED6;004F 0302 0303; # (Ô◌̃; Ỗ; O◌̂◌̃; Ỗ; O◌̂◌̃; ) LATIN CAPITAL LETTER O WITH CIRCUMFLEX, COMBINING TILDE +00F4 0303;1ED7;006F 0302 0303;1ED7;006F 0302 0303; # (ô◌̃; ỗ; o◌̂◌̃; ỗ; o◌̂◌̃; ) LATIN SMALL LETTER O WITH CIRCUMFLEX, COMBINING TILDE +00D4 0323;1ED8;004F 0323 0302;1ED8;004F 0323 0302; # (Ô◌̣; Ộ; O◌̣◌̂; Ộ; O◌̣◌̂; ) LATIN CAPITAL LETTER O WITH CIRCUMFLEX, COMBINING DOT BELOW +1ECC 0302;1ED8;004F 0323 0302;1ED8;004F 0323 0302; # (Ọ◌̂; Ộ; O◌̣◌̂; Ộ; O◌̣◌̂; ) LATIN CAPITAL LETTER O WITH DOT BELOW, COMBINING CIRCUMFLEX ACCENT +00F4 0323;1ED9;006F 0323 0302;1ED9;006F 0323 0302; # (ô◌̣; ộ; o◌̣◌̂; ộ; o◌̣◌̂; ) LATIN SMALL LETTER O WITH CIRCUMFLEX, COMBINING DOT BELOW +1ECD 0302;1ED9;006F 0323 0302;1ED9;006F 0323 0302; # (ọ◌̂; ộ; o◌̣◌̂; ộ; o◌̣◌̂; ) LATIN SMALL LETTER O WITH DOT BELOW, COMBINING CIRCUMFLEX ACCENT +00D3 031B;1EDA;004F 031B 0301;1EDA;004F 031B 0301; # (Ó◌̛; Ớ; O◌̛◌́; Ớ; O◌̛◌́; ) LATIN CAPITAL LETTER O WITH ACUTE, COMBINING HORN +01A0 0301;1EDA;004F 031B 0301;1EDA;004F 031B 0301; # (Ơ◌́; Ớ; O◌̛◌́; Ớ; O◌̛◌́; ) LATIN CAPITAL LETTER O WITH HORN, COMBINING ACUTE ACCENT +01A0 0341;1EDA;004F 031B 0301;1EDA;004F 031B 0301; # (Ơ◌́; Ớ; O◌̛◌́; Ớ; O◌̛◌́; ) LATIN CAPITAL LETTER O WITH HORN, COMBINING ACUTE TONE MARK +00F3 031B;1EDB;006F 031B 0301;1EDB;006F 031B 0301; # (ó◌̛; ớ; o◌̛◌́; ớ; o◌̛◌́; ) LATIN SMALL LETTER O WITH ACUTE, COMBINING HORN +01A1 0301;1EDB;006F 031B 0301;1EDB;006F 031B 0301; # (ơ◌́; ớ; o◌̛◌́; ớ; o◌̛◌́; ) LATIN SMALL LETTER O WITH HORN, COMBINING ACUTE ACCENT +01A1 0341;1EDB;006F 031B 0301;1EDB;006F 031B 0301; # (ơ◌́; ớ; o◌̛◌́; ớ; o◌̛◌́; ) LATIN SMALL LETTER O WITH HORN, COMBINING ACUTE TONE MARK +00D2 031B;1EDC;004F 031B 0300;1EDC;004F 031B 0300; # (Ò◌̛; Ờ; O◌̛◌̀; Ờ; O◌̛◌̀; ) LATIN CAPITAL LETTER O WITH GRAVE, COMBINING HORN +01A0 0300;1EDC;004F 031B 0300;1EDC;004F 031B 0300; # (Ơ◌̀; Ờ; O◌̛◌̀; Ờ; O◌̛◌̀; ) LATIN CAPITAL LETTER O WITH HORN, COMBINING GRAVE ACCENT +01A0 0340;1EDC;004F 031B 0300;1EDC;004F 031B 0300; # (Ơ◌̀; Ờ; O◌̛◌̀; Ờ; O◌̛◌̀; ) LATIN CAPITAL LETTER O WITH HORN, COMBINING GRAVE TONE MARK +00F2 031B;1EDD;006F 031B 0300;1EDD;006F 031B 0300; # (ò◌̛; ờ; o◌̛◌̀; ờ; o◌̛◌̀; ) LATIN SMALL LETTER O WITH GRAVE, COMBINING HORN +01A1 0300;1EDD;006F 031B 0300;1EDD;006F 031B 0300; # (ơ◌̀; ờ; o◌̛◌̀; ờ; o◌̛◌̀; ) LATIN SMALL LETTER O WITH HORN, COMBINING GRAVE ACCENT +01A1 0340;1EDD;006F 031B 0300;1EDD;006F 031B 0300; # (ơ◌̀; ờ; o◌̛◌̀; ờ; o◌̛◌̀; ) LATIN SMALL LETTER O WITH HORN, COMBINING GRAVE TONE MARK +01A0 0309;1EDE;004F 031B 0309;1EDE;004F 031B 0309; # (Ơ◌̉; Ở; O◌̛◌̉; Ở; O◌̛◌̉; ) LATIN CAPITAL LETTER O WITH HORN, COMBINING HOOK ABOVE +1ECE 031B;1EDE;004F 031B 0309;1EDE;004F 031B 0309; # (Ỏ◌̛; Ở; O◌̛◌̉; Ở; O◌̛◌̉; ) LATIN CAPITAL LETTER O WITH HOOK ABOVE, COMBINING HORN +01A1 0309;1EDF;006F 031B 0309;1EDF;006F 031B 0309; # (ơ◌̉; ở; o◌̛◌̉; ở; o◌̛◌̉; ) LATIN SMALL LETTER O WITH HORN, COMBINING HOOK ABOVE +1ECF 031B;1EDF;006F 031B 0309;1EDF;006F 031B 0309; # (ỏ◌̛; ở; o◌̛◌̉; ở; o◌̛◌̉; ) LATIN SMALL LETTER O WITH HOOK ABOVE, COMBINING HORN +00D5 031B;1EE0;004F 031B 0303;1EE0;004F 031B 0303; # (Õ◌̛; Ỡ; O◌̛◌̃; Ỡ; O◌̛◌̃; ) LATIN CAPITAL LETTER O WITH TILDE, COMBINING HORN +01A0 0303;1EE0;004F 031B 0303;1EE0;004F 031B 0303; # (Ơ◌̃; Ỡ; O◌̛◌̃; Ỡ; O◌̛◌̃; ) LATIN CAPITAL LETTER O WITH HORN, COMBINING TILDE +00F5 031B;1EE1;006F 031B 0303;1EE1;006F 031B 0303; # (õ◌̛; ỡ; o◌̛◌̃; ỡ; o◌̛◌̃; ) LATIN SMALL LETTER O WITH TILDE, COMBINING HORN +01A1 0303;1EE1;006F 031B 0303;1EE1;006F 031B 0303; # (ơ◌̃; ỡ; o◌̛◌̃; ỡ; o◌̛◌̃; ) LATIN SMALL LETTER O WITH HORN, COMBINING TILDE +01A0 0323;1EE2;004F 031B 0323;1EE2;004F 031B 0323; # (Ơ◌̣; Ợ; O◌̛◌̣; Ợ; O◌̛◌̣; ) LATIN CAPITAL LETTER O WITH HORN, COMBINING DOT BELOW +1ECC 031B;1EE2;004F 031B 0323;1EE2;004F 031B 0323; # (Ọ◌̛; Ợ; O◌̛◌̣; Ợ; O◌̛◌̣; ) LATIN CAPITAL LETTER O WITH DOT BELOW, COMBINING HORN +01A1 0323;1EE3;006F 031B 0323;1EE3;006F 031B 0323; # (ơ◌̣; ợ; o◌̛◌̣; ợ; o◌̛◌̣; ) LATIN SMALL LETTER O WITH HORN, COMBINING DOT BELOW +1ECD 031B;1EE3;006F 031B 0323;1EE3;006F 031B 0323; # (ọ◌̛; ợ; o◌̛◌̣; ợ; o◌̛◌̣; ) LATIN SMALL LETTER O WITH DOT BELOW, COMBINING HORN +00DA 031B;1EE8;0055 031B 0301;1EE8;0055 031B 0301; # (Ú◌̛; Ứ; U◌̛◌́; Ứ; U◌̛◌́; ) LATIN CAPITAL LETTER U WITH ACUTE, COMBINING HORN +01AF 0301;1EE8;0055 031B 0301;1EE8;0055 031B 0301; # (Ư◌́; Ứ; U◌̛◌́; Ứ; U◌̛◌́; ) LATIN CAPITAL LETTER U WITH HORN, COMBINING ACUTE ACCENT +01AF 0341;1EE8;0055 031B 0301;1EE8;0055 031B 0301; # (Ư◌́; Ứ; U◌̛◌́; Ứ; U◌̛◌́; ) LATIN CAPITAL LETTER U WITH HORN, COMBINING ACUTE TONE MARK +00FA 031B;1EE9;0075 031B 0301;1EE9;0075 031B 0301; # (ú◌̛; ứ; u◌̛◌́; ứ; u◌̛◌́; ) LATIN SMALL LETTER U WITH ACUTE, COMBINING HORN +01B0 0301;1EE9;0075 031B 0301;1EE9;0075 031B 0301; # (ư◌́; ứ; u◌̛◌́; ứ; u◌̛◌́; ) LATIN SMALL LETTER U WITH HORN, COMBINING ACUTE ACCENT +01B0 0341;1EE9;0075 031B 0301;1EE9;0075 031B 0301; # (ư◌́; ứ; u◌̛◌́; ứ; u◌̛◌́; ) LATIN SMALL LETTER U WITH HORN, COMBINING ACUTE TONE MARK +00D9 031B;1EEA;0055 031B 0300;1EEA;0055 031B 0300; # (Ù◌̛; Ừ; U◌̛◌̀; Ừ; U◌̛◌̀; ) LATIN CAPITAL LETTER U WITH GRAVE, COMBINING HORN +01AF 0300;1EEA;0055 031B 0300;1EEA;0055 031B 0300; # (Ư◌̀; Ừ; U◌̛◌̀; Ừ; U◌̛◌̀; ) LATIN CAPITAL LETTER U WITH HORN, COMBINING GRAVE ACCENT +01AF 0340;1EEA;0055 031B 0300;1EEA;0055 031B 0300; # (Ư◌̀; Ừ; U◌̛◌̀; Ừ; U◌̛◌̀; ) LATIN CAPITAL LETTER U WITH HORN, COMBINING GRAVE TONE MARK +00F9 031B;1EEB;0075 031B 0300;1EEB;0075 031B 0300; # (ù◌̛; ừ; u◌̛◌̀; ừ; u◌̛◌̀; ) LATIN SMALL LETTER U WITH GRAVE, COMBINING HORN +01B0 0300;1EEB;0075 031B 0300;1EEB;0075 031B 0300; # (ư◌̀; ừ; u◌̛◌̀; ừ; u◌̛◌̀; ) LATIN SMALL LETTER U WITH HORN, COMBINING GRAVE ACCENT +01B0 0340;1EEB;0075 031B 0300;1EEB;0075 031B 0300; # (ư◌̀; ừ; u◌̛◌̀; ừ; u◌̛◌̀; ) LATIN SMALL LETTER U WITH HORN, COMBINING GRAVE TONE MARK +01AF 0309;1EEC;0055 031B 0309;1EEC;0055 031B 0309; # (Ư◌̉; Ử; U◌̛◌̉; Ử; U◌̛◌̉; ) LATIN CAPITAL LETTER U WITH HORN, COMBINING HOOK ABOVE +1EE6 031B;1EEC;0055 031B 0309;1EEC;0055 031B 0309; # (Ủ◌̛; Ử; U◌̛◌̉; Ử; U◌̛◌̉; ) LATIN CAPITAL LETTER U WITH HOOK ABOVE, COMBINING HORN +01B0 0309;1EED;0075 031B 0309;1EED;0075 031B 0309; # (ư◌̉; ử; u◌̛◌̉; ử; u◌̛◌̉; ) LATIN SMALL LETTER U WITH HORN, COMBINING HOOK ABOVE +1EE7 031B;1EED;0075 031B 0309;1EED;0075 031B 0309; # (ủ◌̛; ử; u◌̛◌̉; ử; u◌̛◌̉; ) LATIN SMALL LETTER U WITH HOOK ABOVE, COMBINING HORN +0168 031B;1EEE;0055 031B 0303;1EEE;0055 031B 0303; # (Ũ◌̛; Ữ; U◌̛◌̃; Ữ; U◌̛◌̃; ) LATIN CAPITAL LETTER U WITH TILDE, COMBINING HORN +01AF 0303;1EEE;0055 031B 0303;1EEE;0055 031B 0303; # (Ư◌̃; Ữ; U◌̛◌̃; Ữ; U◌̛◌̃; ) LATIN CAPITAL LETTER U WITH HORN, COMBINING TILDE +0169 031B;1EEF;0075 031B 0303;1EEF;0075 031B 0303; # (ũ◌̛; ữ; u◌̛◌̃; ữ; u◌̛◌̃; ) LATIN SMALL LETTER U WITH TILDE, COMBINING HORN +01B0 0303;1EEF;0075 031B 0303;1EEF;0075 031B 0303; # (ư◌̃; ữ; u◌̛◌̃; ữ; u◌̛◌̃; ) LATIN SMALL LETTER U WITH HORN, COMBINING TILDE +01AF 0323;1EF0;0055 031B 0323;1EF0;0055 031B 0323; # (Ư◌̣; Ự; U◌̛◌̣; Ự; U◌̛◌̣; ) LATIN CAPITAL LETTER U WITH HORN, COMBINING DOT BELOW +1EE4 031B;1EF0;0055 031B 0323;1EF0;0055 031B 0323; # (Ụ◌̛; Ự; U◌̛◌̣; Ự; U◌̛◌̣; ) LATIN CAPITAL LETTER U WITH DOT BELOW, COMBINING HORN +01B0 0323;1EF1;0075 031B 0323;1EF1;0075 031B 0323; # (ư◌̣; ự; u◌̛◌̣; ự; u◌̛◌̣; ) LATIN SMALL LETTER U WITH HORN, COMBINING DOT BELOW +1EE5 031B;1EF1;0075 031B 0323;1EF1;0075 031B 0323; # (ụ◌̛; ự; u◌̛◌̣; ự; u◌̛◌̣; ) LATIN SMALL LETTER U WITH DOT BELOW, COMBINING HORN +1F00 0300;1F02;03B1 0313 0300;1F02;03B1 0313 0300; # (ἀ◌̀; ἂ; α◌̓◌̀; ἂ; α◌̓◌̀; ) GREEK SMALL LETTER ALPHA WITH PSILI, COMBINING GRAVE ACCENT +1F00 0340;1F02;03B1 0313 0300;1F02;03B1 0313 0300; # (ἀ◌̀; ἂ; α◌̓◌̀; ἂ; α◌̓◌̀; ) GREEK SMALL LETTER ALPHA WITH PSILI, COMBINING GRAVE TONE MARK +1F01 0300;1F03;03B1 0314 0300;1F03;03B1 0314 0300; # (ἁ◌̀; ἃ; α◌̔◌̀; ἃ; α◌̔◌̀; ) GREEK SMALL LETTER ALPHA WITH DASIA, COMBINING GRAVE ACCENT +1F01 0340;1F03;03B1 0314 0300;1F03;03B1 0314 0300; # (ἁ◌̀; ἃ; α◌̔◌̀; ἃ; α◌̔◌̀; ) GREEK SMALL LETTER ALPHA WITH DASIA, COMBINING GRAVE TONE MARK +1F00 0301;1F04;03B1 0313 0301;1F04;03B1 0313 0301; # (ἀ◌́; ἄ; α◌̓◌́; ἄ; α◌̓◌́; ) GREEK SMALL LETTER ALPHA WITH PSILI, COMBINING ACUTE ACCENT +1F00 0341;1F04;03B1 0313 0301;1F04;03B1 0313 0301; # (ἀ◌́; ἄ; α◌̓◌́; ἄ; α◌̓◌́; ) GREEK SMALL LETTER ALPHA WITH PSILI, COMBINING ACUTE TONE MARK +1F01 0301;1F05;03B1 0314 0301;1F05;03B1 0314 0301; # (ἁ◌́; ἅ; α◌̔◌́; ἅ; α◌̔◌́; ) GREEK SMALL LETTER ALPHA WITH DASIA, COMBINING ACUTE ACCENT +1F01 0341;1F05;03B1 0314 0301;1F05;03B1 0314 0301; # (ἁ◌́; ἅ; α◌̔◌́; ἅ; α◌̔◌́; ) GREEK SMALL LETTER ALPHA WITH DASIA, COMBINING ACUTE TONE MARK +1F00 0342;1F06;03B1 0313 0342;1F06;03B1 0313 0342; # (ἀ◌͂; ἆ; α◌̓◌͂; ἆ; α◌̓◌͂; ) GREEK SMALL LETTER ALPHA WITH PSILI, COMBINING GREEK PERISPOMENI +1F01 0342;1F07;03B1 0314 0342;1F07;03B1 0314 0342; # (ἁ◌͂; ἇ; α◌̔◌͂; ἇ; α◌̔◌͂; ) GREEK SMALL LETTER ALPHA WITH DASIA, COMBINING GREEK PERISPOMENI +1F08 0300;1F0A;0391 0313 0300;1F0A;0391 0313 0300; # (Ἀ◌̀; Ἂ; Α◌̓◌̀; Ἂ; Α◌̓◌̀; ) GREEK CAPITAL LETTER ALPHA WITH PSILI, COMBINING GRAVE ACCENT +1F08 0340;1F0A;0391 0313 0300;1F0A;0391 0313 0300; # (Ἀ◌̀; Ἂ; Α◌̓◌̀; Ἂ; Α◌̓◌̀; ) GREEK CAPITAL LETTER ALPHA WITH PSILI, COMBINING GRAVE TONE MARK +1F09 0300;1F0B;0391 0314 0300;1F0B;0391 0314 0300; # (Ἁ◌̀; Ἃ; Α◌̔◌̀; Ἃ; Α◌̔◌̀; ) GREEK CAPITAL LETTER ALPHA WITH DASIA, COMBINING GRAVE ACCENT +1F09 0340;1F0B;0391 0314 0300;1F0B;0391 0314 0300; # (Ἁ◌̀; Ἃ; Α◌̔◌̀; Ἃ; Α◌̔◌̀; ) GREEK CAPITAL LETTER ALPHA WITH DASIA, COMBINING GRAVE TONE MARK +1F08 0301;1F0C;0391 0313 0301;1F0C;0391 0313 0301; # (Ἀ◌́; Ἄ; Α◌̓◌́; Ἄ; Α◌̓◌́; ) GREEK CAPITAL LETTER ALPHA WITH PSILI, COMBINING ACUTE ACCENT +1F08 0341;1F0C;0391 0313 0301;1F0C;0391 0313 0301; # (Ἀ◌́; Ἄ; Α◌̓◌́; Ἄ; Α◌̓◌́; ) GREEK CAPITAL LETTER ALPHA WITH PSILI, COMBINING ACUTE TONE MARK +1F09 0301;1F0D;0391 0314 0301;1F0D;0391 0314 0301; # (Ἁ◌́; Ἅ; Α◌̔◌́; Ἅ; Α◌̔◌́; ) GREEK CAPITAL LETTER ALPHA WITH DASIA, COMBINING ACUTE ACCENT +1F09 0341;1F0D;0391 0314 0301;1F0D;0391 0314 0301; # (Ἁ◌́; Ἅ; Α◌̔◌́; Ἅ; Α◌̔◌́; ) GREEK CAPITAL LETTER ALPHA WITH DASIA, COMBINING ACUTE TONE MARK +1F08 0342;1F0E;0391 0313 0342;1F0E;0391 0313 0342; # (Ἀ◌͂; Ἆ; Α◌̓◌͂; Ἆ; Α◌̓◌͂; ) GREEK CAPITAL LETTER ALPHA WITH PSILI, COMBINING GREEK PERISPOMENI +1F09 0342;1F0F;0391 0314 0342;1F0F;0391 0314 0342; # (Ἁ◌͂; Ἇ; Α◌̔◌͂; Ἇ; Α◌̔◌͂; ) GREEK CAPITAL LETTER ALPHA WITH DASIA, COMBINING GREEK PERISPOMENI +1F10 0300;1F12;03B5 0313 0300;1F12;03B5 0313 0300; # (ἐ◌̀; ἒ; ε◌̓◌̀; ἒ; ε◌̓◌̀; ) GREEK SMALL LETTER EPSILON WITH PSILI, COMBINING GRAVE ACCENT +1F10 0340;1F12;03B5 0313 0300;1F12;03B5 0313 0300; # (ἐ◌̀; ἒ; ε◌̓◌̀; ἒ; ε◌̓◌̀; ) GREEK SMALL LETTER EPSILON WITH PSILI, COMBINING GRAVE TONE MARK +1F11 0300;1F13;03B5 0314 0300;1F13;03B5 0314 0300; # (ἑ◌̀; ἓ; ε◌̔◌̀; ἓ; ε◌̔◌̀; ) GREEK SMALL LETTER EPSILON WITH DASIA, COMBINING GRAVE ACCENT +1F11 0340;1F13;03B5 0314 0300;1F13;03B5 0314 0300; # (ἑ◌̀; ἓ; ε◌̔◌̀; ἓ; ε◌̔◌̀; ) GREEK SMALL LETTER EPSILON WITH DASIA, COMBINING GRAVE TONE MARK +1F10 0301;1F14;03B5 0313 0301;1F14;03B5 0313 0301; # (ἐ◌́; ἔ; ε◌̓◌́; ἔ; ε◌̓◌́; ) GREEK SMALL LETTER EPSILON WITH PSILI, COMBINING ACUTE ACCENT +1F10 0341;1F14;03B5 0313 0301;1F14;03B5 0313 0301; # (ἐ◌́; ἔ; ε◌̓◌́; ἔ; ε◌̓◌́; ) GREEK SMALL LETTER EPSILON WITH PSILI, COMBINING ACUTE TONE MARK +1F11 0301;1F15;03B5 0314 0301;1F15;03B5 0314 0301; # (ἑ◌́; ἕ; ε◌̔◌́; ἕ; ε◌̔◌́; ) GREEK SMALL LETTER EPSILON WITH DASIA, COMBINING ACUTE ACCENT +1F11 0341;1F15;03B5 0314 0301;1F15;03B5 0314 0301; # (ἑ◌́; ἕ; ε◌̔◌́; ἕ; ε◌̔◌́; ) GREEK SMALL LETTER EPSILON WITH DASIA, COMBINING ACUTE TONE MARK +1F18 0300;1F1A;0395 0313 0300;1F1A;0395 0313 0300; # (Ἐ◌̀; Ἒ; Ε◌̓◌̀; Ἒ; Ε◌̓◌̀; ) GREEK CAPITAL LETTER EPSILON WITH PSILI, COMBINING GRAVE ACCENT +1F18 0340;1F1A;0395 0313 0300;1F1A;0395 0313 0300; # (Ἐ◌̀; Ἒ; Ε◌̓◌̀; Ἒ; Ε◌̓◌̀; ) GREEK CAPITAL LETTER EPSILON WITH PSILI, COMBINING GRAVE TONE MARK +1F19 0300;1F1B;0395 0314 0300;1F1B;0395 0314 0300; # (Ἑ◌̀; Ἓ; Ε◌̔◌̀; Ἓ; Ε◌̔◌̀; ) GREEK CAPITAL LETTER EPSILON WITH DASIA, COMBINING GRAVE ACCENT +1F19 0340;1F1B;0395 0314 0300;1F1B;0395 0314 0300; # (Ἑ◌̀; Ἓ; Ε◌̔◌̀; Ἓ; Ε◌̔◌̀; ) GREEK CAPITAL LETTER EPSILON WITH DASIA, COMBINING GRAVE TONE MARK +1F18 0301;1F1C;0395 0313 0301;1F1C;0395 0313 0301; # (Ἐ◌́; Ἔ; Ε◌̓◌́; Ἔ; Ε◌̓◌́; ) GREEK CAPITAL LETTER EPSILON WITH PSILI, COMBINING ACUTE ACCENT +1F18 0341;1F1C;0395 0313 0301;1F1C;0395 0313 0301; # (Ἐ◌́; Ἔ; Ε◌̓◌́; Ἔ; Ε◌̓◌́; ) GREEK CAPITAL LETTER EPSILON WITH PSILI, COMBINING ACUTE TONE MARK +1F19 0301;1F1D;0395 0314 0301;1F1D;0395 0314 0301; # (Ἑ◌́; Ἕ; Ε◌̔◌́; Ἕ; Ε◌̔◌́; ) GREEK CAPITAL LETTER EPSILON WITH DASIA, COMBINING ACUTE ACCENT +1F19 0341;1F1D;0395 0314 0301;1F1D;0395 0314 0301; # (Ἑ◌́; Ἕ; Ε◌̔◌́; Ἕ; Ε◌̔◌́; ) GREEK CAPITAL LETTER EPSILON WITH DASIA, COMBINING ACUTE TONE MARK +1F20 0300;1F22;03B7 0313 0300;1F22;03B7 0313 0300; # (ἠ◌̀; ἢ; η◌̓◌̀; ἢ; η◌̓◌̀; ) GREEK SMALL LETTER ETA WITH PSILI, COMBINING GRAVE ACCENT +1F20 0340;1F22;03B7 0313 0300;1F22;03B7 0313 0300; # (ἠ◌̀; ἢ; η◌̓◌̀; ἢ; η◌̓◌̀; ) GREEK SMALL LETTER ETA WITH PSILI, COMBINING GRAVE TONE MARK +1F21 0300;1F23;03B7 0314 0300;1F23;03B7 0314 0300; # (ἡ◌̀; ἣ; η◌̔◌̀; ἣ; η◌̔◌̀; ) GREEK SMALL LETTER ETA WITH DASIA, COMBINING GRAVE ACCENT +1F21 0340;1F23;03B7 0314 0300;1F23;03B7 0314 0300; # (ἡ◌̀; ἣ; η◌̔◌̀; ἣ; η◌̔◌̀; ) GREEK SMALL LETTER ETA WITH DASIA, COMBINING GRAVE TONE MARK +1F20 0301;1F24;03B7 0313 0301;1F24;03B7 0313 0301; # (ἠ◌́; ἤ; η◌̓◌́; ἤ; η◌̓◌́; ) GREEK SMALL LETTER ETA WITH PSILI, COMBINING ACUTE ACCENT +1F20 0341;1F24;03B7 0313 0301;1F24;03B7 0313 0301; # (ἠ◌́; ἤ; η◌̓◌́; ἤ; η◌̓◌́; ) GREEK SMALL LETTER ETA WITH PSILI, COMBINING ACUTE TONE MARK +1F21 0301;1F25;03B7 0314 0301;1F25;03B7 0314 0301; # (ἡ◌́; ἥ; η◌̔◌́; ἥ; η◌̔◌́; ) GREEK SMALL LETTER ETA WITH DASIA, COMBINING ACUTE ACCENT +1F21 0341;1F25;03B7 0314 0301;1F25;03B7 0314 0301; # (ἡ◌́; ἥ; η◌̔◌́; ἥ; η◌̔◌́; ) GREEK SMALL LETTER ETA WITH DASIA, COMBINING ACUTE TONE MARK +1F20 0342;1F26;03B7 0313 0342;1F26;03B7 0313 0342; # (ἠ◌͂; ἦ; η◌̓◌͂; ἦ; η◌̓◌͂; ) GREEK SMALL LETTER ETA WITH PSILI, COMBINING GREEK PERISPOMENI +1F21 0342;1F27;03B7 0314 0342;1F27;03B7 0314 0342; # (ἡ◌͂; ἧ; η◌̔◌͂; ἧ; η◌̔◌͂; ) GREEK SMALL LETTER ETA WITH DASIA, COMBINING GREEK PERISPOMENI +1F28 0300;1F2A;0397 0313 0300;1F2A;0397 0313 0300; # (Ἠ◌̀; Ἢ; Η◌̓◌̀; Ἢ; Η◌̓◌̀; ) GREEK CAPITAL LETTER ETA WITH PSILI, COMBINING GRAVE ACCENT +1F28 0340;1F2A;0397 0313 0300;1F2A;0397 0313 0300; # (Ἠ◌̀; Ἢ; Η◌̓◌̀; Ἢ; Η◌̓◌̀; ) GREEK CAPITAL LETTER ETA WITH PSILI, COMBINING GRAVE TONE MARK +1F29 0300;1F2B;0397 0314 0300;1F2B;0397 0314 0300; # (Ἡ◌̀; Ἣ; Η◌̔◌̀; Ἣ; Η◌̔◌̀; ) GREEK CAPITAL LETTER ETA WITH DASIA, COMBINING GRAVE ACCENT +1F29 0340;1F2B;0397 0314 0300;1F2B;0397 0314 0300; # (Ἡ◌̀; Ἣ; Η◌̔◌̀; Ἣ; Η◌̔◌̀; ) GREEK CAPITAL LETTER ETA WITH DASIA, COMBINING GRAVE TONE MARK +1F28 0301;1F2C;0397 0313 0301;1F2C;0397 0313 0301; # (Ἠ◌́; Ἤ; Η◌̓◌́; Ἤ; Η◌̓◌́; ) GREEK CAPITAL LETTER ETA WITH PSILI, COMBINING ACUTE ACCENT +1F28 0341;1F2C;0397 0313 0301;1F2C;0397 0313 0301; # (Ἠ◌́; Ἤ; Η◌̓◌́; Ἤ; Η◌̓◌́; ) GREEK CAPITAL LETTER ETA WITH PSILI, COMBINING ACUTE TONE MARK +1F29 0301;1F2D;0397 0314 0301;1F2D;0397 0314 0301; # (Ἡ◌́; Ἥ; Η◌̔◌́; Ἥ; Η◌̔◌́; ) GREEK CAPITAL LETTER ETA WITH DASIA, COMBINING ACUTE ACCENT +1F29 0341;1F2D;0397 0314 0301;1F2D;0397 0314 0301; # (Ἡ◌́; Ἥ; Η◌̔◌́; Ἥ; Η◌̔◌́; ) GREEK CAPITAL LETTER ETA WITH DASIA, COMBINING ACUTE TONE MARK +1F28 0342;1F2E;0397 0313 0342;1F2E;0397 0313 0342; # (Ἠ◌͂; Ἦ; Η◌̓◌͂; Ἦ; Η◌̓◌͂; ) GREEK CAPITAL LETTER ETA WITH PSILI, COMBINING GREEK PERISPOMENI +1F29 0342;1F2F;0397 0314 0342;1F2F;0397 0314 0342; # (Ἡ◌͂; Ἧ; Η◌̔◌͂; Ἧ; Η◌̔◌͂; ) GREEK CAPITAL LETTER ETA WITH DASIA, COMBINING GREEK PERISPOMENI +1F30 0300;1F32;03B9 0313 0300;1F32;03B9 0313 0300; # (ἰ◌̀; ἲ; ι◌̓◌̀; ἲ; ι◌̓◌̀; ) GREEK SMALL LETTER IOTA WITH PSILI, COMBINING GRAVE ACCENT +1F30 0340;1F32;03B9 0313 0300;1F32;03B9 0313 0300; # (ἰ◌̀; ἲ; ι◌̓◌̀; ἲ; ι◌̓◌̀; ) GREEK SMALL LETTER IOTA WITH PSILI, COMBINING GRAVE TONE MARK +1F31 0300;1F33;03B9 0314 0300;1F33;03B9 0314 0300; # (ἱ◌̀; ἳ; ι◌̔◌̀; ἳ; ι◌̔◌̀; ) GREEK SMALL LETTER IOTA WITH DASIA, COMBINING GRAVE ACCENT +1F31 0340;1F33;03B9 0314 0300;1F33;03B9 0314 0300; # (ἱ◌̀; ἳ; ι◌̔◌̀; ἳ; ι◌̔◌̀; ) GREEK SMALL LETTER IOTA WITH DASIA, COMBINING GRAVE TONE MARK +1F30 0301;1F34;03B9 0313 0301;1F34;03B9 0313 0301; # (ἰ◌́; ἴ; ι◌̓◌́; ἴ; ι◌̓◌́; ) GREEK SMALL LETTER IOTA WITH PSILI, COMBINING ACUTE ACCENT +1F30 0341;1F34;03B9 0313 0301;1F34;03B9 0313 0301; # (ἰ◌́; ἴ; ι◌̓◌́; ἴ; ι◌̓◌́; ) GREEK SMALL LETTER IOTA WITH PSILI, COMBINING ACUTE TONE MARK +1F31 0301;1F35;03B9 0314 0301;1F35;03B9 0314 0301; # (ἱ◌́; ἵ; ι◌̔◌́; ἵ; ι◌̔◌́; ) GREEK SMALL LETTER IOTA WITH DASIA, COMBINING ACUTE ACCENT +1F31 0341;1F35;03B9 0314 0301;1F35;03B9 0314 0301; # (ἱ◌́; ἵ; ι◌̔◌́; ἵ; ι◌̔◌́; ) GREEK SMALL LETTER IOTA WITH DASIA, COMBINING ACUTE TONE MARK +1F30 0342;1F36;03B9 0313 0342;1F36;03B9 0313 0342; # (ἰ◌͂; ἶ; ι◌̓◌͂; ἶ; ι◌̓◌͂; ) GREEK SMALL LETTER IOTA WITH PSILI, COMBINING GREEK PERISPOMENI +1F31 0342;1F37;03B9 0314 0342;1F37;03B9 0314 0342; # (ἱ◌͂; ἷ; ι◌̔◌͂; ἷ; ι◌̔◌͂; ) GREEK SMALL LETTER IOTA WITH DASIA, COMBINING GREEK PERISPOMENI +1F38 0300;1F3A;0399 0313 0300;1F3A;0399 0313 0300; # (Ἰ◌̀; Ἲ; Ι◌̓◌̀; Ἲ; Ι◌̓◌̀; ) GREEK CAPITAL LETTER IOTA WITH PSILI, COMBINING GRAVE ACCENT +1F38 0340;1F3A;0399 0313 0300;1F3A;0399 0313 0300; # (Ἰ◌̀; Ἲ; Ι◌̓◌̀; Ἲ; Ι◌̓◌̀; ) GREEK CAPITAL LETTER IOTA WITH PSILI, COMBINING GRAVE TONE MARK +1F39 0300;1F3B;0399 0314 0300;1F3B;0399 0314 0300; # (Ἱ◌̀; Ἳ; Ι◌̔◌̀; Ἳ; Ι◌̔◌̀; ) GREEK CAPITAL LETTER IOTA WITH DASIA, COMBINING GRAVE ACCENT +1F39 0340;1F3B;0399 0314 0300;1F3B;0399 0314 0300; # (Ἱ◌̀; Ἳ; Ι◌̔◌̀; Ἳ; Ι◌̔◌̀; ) GREEK CAPITAL LETTER IOTA WITH DASIA, COMBINING GRAVE TONE MARK +1F38 0301;1F3C;0399 0313 0301;1F3C;0399 0313 0301; # (Ἰ◌́; Ἴ; Ι◌̓◌́; Ἴ; Ι◌̓◌́; ) GREEK CAPITAL LETTER IOTA WITH PSILI, COMBINING ACUTE ACCENT +1F38 0341;1F3C;0399 0313 0301;1F3C;0399 0313 0301; # (Ἰ◌́; Ἴ; Ι◌̓◌́; Ἴ; Ι◌̓◌́; ) GREEK CAPITAL LETTER IOTA WITH PSILI, COMBINING ACUTE TONE MARK +1F39 0301;1F3D;0399 0314 0301;1F3D;0399 0314 0301; # (Ἱ◌́; Ἵ; Ι◌̔◌́; Ἵ; Ι◌̔◌́; ) GREEK CAPITAL LETTER IOTA WITH DASIA, COMBINING ACUTE ACCENT +1F39 0341;1F3D;0399 0314 0301;1F3D;0399 0314 0301; # (Ἱ◌́; Ἵ; Ι◌̔◌́; Ἵ; Ι◌̔◌́; ) GREEK CAPITAL LETTER IOTA WITH DASIA, COMBINING ACUTE TONE MARK +1F38 0342;1F3E;0399 0313 0342;1F3E;0399 0313 0342; # (Ἰ◌͂; Ἶ; Ι◌̓◌͂; Ἶ; Ι◌̓◌͂; ) GREEK CAPITAL LETTER IOTA WITH PSILI, COMBINING GREEK PERISPOMENI +1F39 0342;1F3F;0399 0314 0342;1F3F;0399 0314 0342; # (Ἱ◌͂; Ἷ; Ι◌̔◌͂; Ἷ; Ι◌̔◌͂; ) GREEK CAPITAL LETTER IOTA WITH DASIA, COMBINING GREEK PERISPOMENI +1F40 0300;1F42;03BF 0313 0300;1F42;03BF 0313 0300; # (ὀ◌̀; ὂ; ο◌̓◌̀; ὂ; ο◌̓◌̀; ) GREEK SMALL LETTER OMICRON WITH PSILI, COMBINING GRAVE ACCENT +1F40 0340;1F42;03BF 0313 0300;1F42;03BF 0313 0300; # (ὀ◌̀; ὂ; ο◌̓◌̀; ὂ; ο◌̓◌̀; ) GREEK SMALL LETTER OMICRON WITH PSILI, COMBINING GRAVE TONE MARK +1F41 0300;1F43;03BF 0314 0300;1F43;03BF 0314 0300; # (ὁ◌̀; ὃ; ο◌̔◌̀; ὃ; ο◌̔◌̀; ) GREEK SMALL LETTER OMICRON WITH DASIA, COMBINING GRAVE ACCENT +1F41 0340;1F43;03BF 0314 0300;1F43;03BF 0314 0300; # (ὁ◌̀; ὃ; ο◌̔◌̀; ὃ; ο◌̔◌̀; ) GREEK SMALL LETTER OMICRON WITH DASIA, COMBINING GRAVE TONE MARK +1F40 0301;1F44;03BF 0313 0301;1F44;03BF 0313 0301; # (ὀ◌́; ὄ; ο◌̓◌́; ὄ; ο◌̓◌́; ) GREEK SMALL LETTER OMICRON WITH PSILI, COMBINING ACUTE ACCENT +1F40 0341;1F44;03BF 0313 0301;1F44;03BF 0313 0301; # (ὀ◌́; ὄ; ο◌̓◌́; ὄ; ο◌̓◌́; ) GREEK SMALL LETTER OMICRON WITH PSILI, COMBINING ACUTE TONE MARK +1F41 0301;1F45;03BF 0314 0301;1F45;03BF 0314 0301; # (ὁ◌́; ὅ; ο◌̔◌́; ὅ; ο◌̔◌́; ) GREEK SMALL LETTER OMICRON WITH DASIA, COMBINING ACUTE ACCENT +1F41 0341;1F45;03BF 0314 0301;1F45;03BF 0314 0301; # (ὁ◌́; ὅ; ο◌̔◌́; ὅ; ο◌̔◌́; ) GREEK SMALL LETTER OMICRON WITH DASIA, COMBINING ACUTE TONE MARK +1F48 0300;1F4A;039F 0313 0300;1F4A;039F 0313 0300; # (Ὀ◌̀; Ὂ; Ο◌̓◌̀; Ὂ; Ο◌̓◌̀; ) GREEK CAPITAL LETTER OMICRON WITH PSILI, COMBINING GRAVE ACCENT +1F48 0340;1F4A;039F 0313 0300;1F4A;039F 0313 0300; # (Ὀ◌̀; Ὂ; Ο◌̓◌̀; Ὂ; Ο◌̓◌̀; ) GREEK CAPITAL LETTER OMICRON WITH PSILI, COMBINING GRAVE TONE MARK +1F49 0300;1F4B;039F 0314 0300;1F4B;039F 0314 0300; # (Ὁ◌̀; Ὃ; Ο◌̔◌̀; Ὃ; Ο◌̔◌̀; ) GREEK CAPITAL LETTER OMICRON WITH DASIA, COMBINING GRAVE ACCENT +1F49 0340;1F4B;039F 0314 0300;1F4B;039F 0314 0300; # (Ὁ◌̀; Ὃ; Ο◌̔◌̀; Ὃ; Ο◌̔◌̀; ) GREEK CAPITAL LETTER OMICRON WITH DASIA, COMBINING GRAVE TONE MARK +1F48 0301;1F4C;039F 0313 0301;1F4C;039F 0313 0301; # (Ὀ◌́; Ὄ; Ο◌̓◌́; Ὄ; Ο◌̓◌́; ) GREEK CAPITAL LETTER OMICRON WITH PSILI, COMBINING ACUTE ACCENT +1F48 0341;1F4C;039F 0313 0301;1F4C;039F 0313 0301; # (Ὀ◌́; Ὄ; Ο◌̓◌́; Ὄ; Ο◌̓◌́; ) GREEK CAPITAL LETTER OMICRON WITH PSILI, COMBINING ACUTE TONE MARK +1F49 0301;1F4D;039F 0314 0301;1F4D;039F 0314 0301; # (Ὁ◌́; Ὅ; Ο◌̔◌́; Ὅ; Ο◌̔◌́; ) GREEK CAPITAL LETTER OMICRON WITH DASIA, COMBINING ACUTE ACCENT +1F49 0341;1F4D;039F 0314 0301;1F4D;039F 0314 0301; # (Ὁ◌́; Ὅ; Ο◌̔◌́; Ὅ; Ο◌̔◌́; ) GREEK CAPITAL LETTER OMICRON WITH DASIA, COMBINING ACUTE TONE MARK +1F50 0300;1F52;03C5 0313 0300;1F52;03C5 0313 0300; # (ὐ◌̀; ὒ; υ◌̓◌̀; ὒ; υ◌̓◌̀; ) GREEK SMALL LETTER UPSILON WITH PSILI, COMBINING GRAVE ACCENT +1F50 0340;1F52;03C5 0313 0300;1F52;03C5 0313 0300; # (ὐ◌̀; ὒ; υ◌̓◌̀; ὒ; υ◌̓◌̀; ) GREEK SMALL LETTER UPSILON WITH PSILI, COMBINING GRAVE TONE MARK +1F51 0300;1F53;03C5 0314 0300;1F53;03C5 0314 0300; # (ὑ◌̀; ὓ; υ◌̔◌̀; ὓ; υ◌̔◌̀; ) GREEK SMALL LETTER UPSILON WITH DASIA, COMBINING GRAVE ACCENT +1F51 0340;1F53;03C5 0314 0300;1F53;03C5 0314 0300; # (ὑ◌̀; ὓ; υ◌̔◌̀; ὓ; υ◌̔◌̀; ) GREEK SMALL LETTER UPSILON WITH DASIA, COMBINING GRAVE TONE MARK +1F50 0301;1F54;03C5 0313 0301;1F54;03C5 0313 0301; # (ὐ◌́; ὔ; υ◌̓◌́; ὔ; υ◌̓◌́; ) GREEK SMALL LETTER UPSILON WITH PSILI, COMBINING ACUTE ACCENT +1F50 0341;1F54;03C5 0313 0301;1F54;03C5 0313 0301; # (ὐ◌́; ὔ; υ◌̓◌́; ὔ; υ◌̓◌́; ) GREEK SMALL LETTER UPSILON WITH PSILI, COMBINING ACUTE TONE MARK +1F51 0301;1F55;03C5 0314 0301;1F55;03C5 0314 0301; # (ὑ◌́; ὕ; υ◌̔◌́; ὕ; υ◌̔◌́; ) GREEK SMALL LETTER UPSILON WITH DASIA, COMBINING ACUTE ACCENT +1F51 0341;1F55;03C5 0314 0301;1F55;03C5 0314 0301; # (ὑ◌́; ὕ; υ◌̔◌́; ὕ; υ◌̔◌́; ) GREEK SMALL LETTER UPSILON WITH DASIA, COMBINING ACUTE TONE MARK +1F50 0342;1F56;03C5 0313 0342;1F56;03C5 0313 0342; # (ὐ◌͂; ὖ; υ◌̓◌͂; ὖ; υ◌̓◌͂; ) GREEK SMALL LETTER UPSILON WITH PSILI, COMBINING GREEK PERISPOMENI +1F51 0342;1F57;03C5 0314 0342;1F57;03C5 0314 0342; # (ὑ◌͂; ὗ; υ◌̔◌͂; ὗ; υ◌̔◌͂; ) GREEK SMALL LETTER UPSILON WITH DASIA, COMBINING GREEK PERISPOMENI +1F59 0300;1F5B;03A5 0314 0300;1F5B;03A5 0314 0300; # (Ὑ◌̀; Ὓ; Υ◌̔◌̀; Ὓ; Υ◌̔◌̀; ) GREEK CAPITAL LETTER UPSILON WITH DASIA, COMBINING GRAVE ACCENT +1F59 0340;1F5B;03A5 0314 0300;1F5B;03A5 0314 0300; # (Ὑ◌̀; Ὓ; Υ◌̔◌̀; Ὓ; Υ◌̔◌̀; ) GREEK CAPITAL LETTER UPSILON WITH DASIA, COMBINING GRAVE TONE MARK +1F59 0301;1F5D;03A5 0314 0301;1F5D;03A5 0314 0301; # (Ὑ◌́; Ὕ; Υ◌̔◌́; Ὕ; Υ◌̔◌́; ) GREEK CAPITAL LETTER UPSILON WITH DASIA, COMBINING ACUTE ACCENT +1F59 0341;1F5D;03A5 0314 0301;1F5D;03A5 0314 0301; # (Ὑ◌́; Ὕ; Υ◌̔◌́; Ὕ; Υ◌̔◌́; ) GREEK CAPITAL LETTER UPSILON WITH DASIA, COMBINING ACUTE TONE MARK +1F59 0342;1F5F;03A5 0314 0342;1F5F;03A5 0314 0342; # (Ὑ◌͂; Ὗ; Υ◌̔◌͂; Ὗ; Υ◌̔◌͂; ) GREEK CAPITAL LETTER UPSILON WITH DASIA, COMBINING GREEK PERISPOMENI +1F60 0300;1F62;03C9 0313 0300;1F62;03C9 0313 0300; # (ὠ◌̀; ὢ; ω◌̓◌̀; ὢ; ω◌̓◌̀; ) GREEK SMALL LETTER OMEGA WITH PSILI, COMBINING GRAVE ACCENT +1F60 0340;1F62;03C9 0313 0300;1F62;03C9 0313 0300; # (ὠ◌̀; ὢ; ω◌̓◌̀; ὢ; ω◌̓◌̀; ) GREEK SMALL LETTER OMEGA WITH PSILI, COMBINING GRAVE TONE MARK +1F61 0300;1F63;03C9 0314 0300;1F63;03C9 0314 0300; # (ὡ◌̀; ὣ; ω◌̔◌̀; ὣ; ω◌̔◌̀; ) GREEK SMALL LETTER OMEGA WITH DASIA, COMBINING GRAVE ACCENT +1F61 0340;1F63;03C9 0314 0300;1F63;03C9 0314 0300; # (ὡ◌̀; ὣ; ω◌̔◌̀; ὣ; ω◌̔◌̀; ) GREEK SMALL LETTER OMEGA WITH DASIA, COMBINING GRAVE TONE MARK +1F60 0301;1F64;03C9 0313 0301;1F64;03C9 0313 0301; # (ὠ◌́; ὤ; ω◌̓◌́; ὤ; ω◌̓◌́; ) GREEK SMALL LETTER OMEGA WITH PSILI, COMBINING ACUTE ACCENT +1F60 0341;1F64;03C9 0313 0301;1F64;03C9 0313 0301; # (ὠ◌́; ὤ; ω◌̓◌́; ὤ; ω◌̓◌́; ) GREEK SMALL LETTER OMEGA WITH PSILI, COMBINING ACUTE TONE MARK +1F61 0301;1F65;03C9 0314 0301;1F65;03C9 0314 0301; # (ὡ◌́; ὥ; ω◌̔◌́; ὥ; ω◌̔◌́; ) GREEK SMALL LETTER OMEGA WITH DASIA, COMBINING ACUTE ACCENT +1F61 0341;1F65;03C9 0314 0301;1F65;03C9 0314 0301; # (ὡ◌́; ὥ; ω◌̔◌́; ὥ; ω◌̔◌́; ) GREEK SMALL LETTER OMEGA WITH DASIA, COMBINING ACUTE TONE MARK +1F60 0342;1F66;03C9 0313 0342;1F66;03C9 0313 0342; # (ὠ◌͂; ὦ; ω◌̓◌͂; ὦ; ω◌̓◌͂; ) GREEK SMALL LETTER OMEGA WITH PSILI, COMBINING GREEK PERISPOMENI +1F61 0342;1F67;03C9 0314 0342;1F67;03C9 0314 0342; # (ὡ◌͂; ὧ; ω◌̔◌͂; ὧ; ω◌̔◌͂; ) GREEK SMALL LETTER OMEGA WITH DASIA, COMBINING GREEK PERISPOMENI +1F68 0300;1F6A;03A9 0313 0300;1F6A;03A9 0313 0300; # (Ὠ◌̀; Ὢ; Ω◌̓◌̀; Ὢ; Ω◌̓◌̀; ) GREEK CAPITAL LETTER OMEGA WITH PSILI, COMBINING GRAVE ACCENT +1F68 0340;1F6A;03A9 0313 0300;1F6A;03A9 0313 0300; # (Ὠ◌̀; Ὢ; Ω◌̓◌̀; Ὢ; Ω◌̓◌̀; ) GREEK CAPITAL LETTER OMEGA WITH PSILI, COMBINING GRAVE TONE MARK +1F69 0300;1F6B;03A9 0314 0300;1F6B;03A9 0314 0300; # (Ὡ◌̀; Ὣ; Ω◌̔◌̀; Ὣ; Ω◌̔◌̀; ) GREEK CAPITAL LETTER OMEGA WITH DASIA, COMBINING GRAVE ACCENT +1F69 0340;1F6B;03A9 0314 0300;1F6B;03A9 0314 0300; # (Ὡ◌̀; Ὣ; Ω◌̔◌̀; Ὣ; Ω◌̔◌̀; ) GREEK CAPITAL LETTER OMEGA WITH DASIA, COMBINING GRAVE TONE MARK +1F68 0301;1F6C;03A9 0313 0301;1F6C;03A9 0313 0301; # (Ὠ◌́; Ὤ; Ω◌̓◌́; Ὤ; Ω◌̓◌́; ) GREEK CAPITAL LETTER OMEGA WITH PSILI, COMBINING ACUTE ACCENT +1F68 0341;1F6C;03A9 0313 0301;1F6C;03A9 0313 0301; # (Ὠ◌́; Ὤ; Ω◌̓◌́; Ὤ; Ω◌̓◌́; ) GREEK CAPITAL LETTER OMEGA WITH PSILI, COMBINING ACUTE TONE MARK +1F69 0301;1F6D;03A9 0314 0301;1F6D;03A9 0314 0301; # (Ὡ◌́; Ὥ; Ω◌̔◌́; Ὥ; Ω◌̔◌́; ) GREEK CAPITAL LETTER OMEGA WITH DASIA, COMBINING ACUTE ACCENT +1F69 0341;1F6D;03A9 0314 0301;1F6D;03A9 0314 0301; # (Ὡ◌́; Ὥ; Ω◌̔◌́; Ὥ; Ω◌̔◌́; ) GREEK CAPITAL LETTER OMEGA WITH DASIA, COMBINING ACUTE TONE MARK +1F68 0342;1F6E;03A9 0313 0342;1F6E;03A9 0313 0342; # (Ὠ◌͂; Ὦ; Ω◌̓◌͂; Ὦ; Ω◌̓◌͂; ) GREEK CAPITAL LETTER OMEGA WITH PSILI, COMBINING GREEK PERISPOMENI +1F69 0342;1F6F;03A9 0314 0342;1F6F;03A9 0314 0342; # (Ὡ◌͂; Ὧ; Ω◌̔◌͂; Ὧ; Ω◌̔◌͂; ) GREEK CAPITAL LETTER OMEGA WITH DASIA, COMBINING GREEK PERISPOMENI +1F00 0345;1F80;03B1 0313 0345;1F80;03B1 0313 0345; # (ἀ◌ͅ; ᾀ; α◌̓◌ͅ; ᾀ; α◌̓◌ͅ; ) GREEK SMALL LETTER ALPHA WITH PSILI, COMBINING GREEK YPOGEGRAMMENI +1FB3 0313;1F80;03B1 0313 0345;1F80;03B1 0313 0345; # (ᾳ◌̓; ᾀ; α◌̓◌ͅ; ᾀ; α◌̓◌ͅ; ) GREEK SMALL LETTER ALPHA WITH YPOGEGRAMMENI, COMBINING COMMA ABOVE +1FB3 0343;1F80;03B1 0313 0345;1F80;03B1 0313 0345; # (ᾳ◌̓; ᾀ; α◌̓◌ͅ; ᾀ; α◌̓◌ͅ; ) GREEK SMALL LETTER ALPHA WITH YPOGEGRAMMENI, COMBINING GREEK KORONIS +1F01 0345;1F81;03B1 0314 0345;1F81;03B1 0314 0345; # (ἁ◌ͅ; ᾁ; α◌̔◌ͅ; ᾁ; α◌̔◌ͅ; ) GREEK SMALL LETTER ALPHA WITH DASIA, COMBINING GREEK YPOGEGRAMMENI +1FB3 0314;1F81;03B1 0314 0345;1F81;03B1 0314 0345; # (ᾳ◌̔; ᾁ; α◌̔◌ͅ; ᾁ; α◌̔◌ͅ; ) GREEK SMALL LETTER ALPHA WITH YPOGEGRAMMENI, COMBINING REVERSED COMMA ABOVE +1F02 0345;1F82;03B1 0313 0300 0345;1F82;03B1 0313 0300 0345; # (ἂ◌ͅ; ᾂ; α◌̓◌̀◌ͅ; ᾂ; α◌̓◌̀◌ͅ; ) GREEK SMALL LETTER ALPHA WITH PSILI AND VARIA, COMBINING GREEK YPOGEGRAMMENI +1F80 0300;1F82;03B1 0313 0300 0345;1F82;03B1 0313 0300 0345; # (ᾀ◌̀; ᾂ; α◌̓◌̀◌ͅ; ᾂ; α◌̓◌̀◌ͅ; ) GREEK SMALL LETTER ALPHA WITH PSILI AND YPOGEGRAMMENI, COMBINING GRAVE ACCENT +1F80 0340;1F82;03B1 0313 0300 0345;1F82;03B1 0313 0300 0345; # (ᾀ◌̀; ᾂ; α◌̓◌̀◌ͅ; ᾂ; α◌̓◌̀◌ͅ; ) GREEK SMALL LETTER ALPHA WITH PSILI AND YPOGEGRAMMENI, COMBINING GRAVE TONE MARK +1F00 0300 0345;1F82;03B1 0313 0300 0345;1F82;03B1 0313 0300 0345; # (ἀ◌̀◌ͅ; ᾂ; α◌̓◌̀◌ͅ; ᾂ; α◌̓◌̀◌ͅ; ) GREEK SMALL LETTER ALPHA WITH PSILI, COMBINING GRAVE ACCENT, COMBINING GREEK YPOGEGRAMMENI +1F00 0340 0345;1F82;03B1 0313 0300 0345;1F82;03B1 0313 0300 0345; # (ἀ◌̀◌ͅ; ᾂ; α◌̓◌̀◌ͅ; ᾂ; α◌̓◌̀◌ͅ; ) GREEK SMALL LETTER ALPHA WITH PSILI, COMBINING GRAVE TONE MARK, COMBINING GREEK YPOGEGRAMMENI +1F00 0345 0300;1F82;03B1 0313 0300 0345;1F82;03B1 0313 0300 0345; # (ἀ◌ͅ◌̀; ᾂ; α◌̓◌̀◌ͅ; ᾂ; α◌̓◌̀◌ͅ; ) GREEK SMALL LETTER ALPHA WITH PSILI, COMBINING GREEK YPOGEGRAMMENI, COMBINING GRAVE ACCENT +1F00 0345 0340;1F82;03B1 0313 0300 0345;1F82;03B1 0313 0300 0345; # (ἀ◌ͅ◌̀; ᾂ; α◌̓◌̀◌ͅ; ᾂ; α◌̓◌̀◌ͅ; ) GREEK SMALL LETTER ALPHA WITH PSILI, COMBINING GREEK YPOGEGRAMMENI, COMBINING GRAVE TONE MARK +1FB3 0313 0300;1F82;03B1 0313 0300 0345;1F82;03B1 0313 0300 0345; # (ᾳ◌̓◌̀; ᾂ; α◌̓◌̀◌ͅ; ᾂ; α◌̓◌̀◌ͅ; ) GREEK SMALL LETTER ALPHA WITH YPOGEGRAMMENI, COMBINING COMMA ABOVE, COMBINING GRAVE ACCENT +1FB3 0313 0340;1F82;03B1 0313 0300 0345;1F82;03B1 0313 0300 0345; # (ᾳ◌̓◌̀; ᾂ; α◌̓◌̀◌ͅ; ᾂ; α◌̓◌̀◌ͅ; ) GREEK SMALL LETTER ALPHA WITH YPOGEGRAMMENI, COMBINING COMMA ABOVE, COMBINING GRAVE TONE MARK +1FB3 0343 0300;1F82;03B1 0313 0300 0345;1F82;03B1 0313 0300 0345; # (ᾳ◌̓◌̀; ᾂ; α◌̓◌̀◌ͅ; ᾂ; α◌̓◌̀◌ͅ; ) GREEK SMALL LETTER ALPHA WITH YPOGEGRAMMENI, COMBINING GREEK KORONIS, COMBINING GRAVE ACCENT +1FB3 0343 0340;1F82;03B1 0313 0300 0345;1F82;03B1 0313 0300 0345; # (ᾳ◌̓◌̀; ᾂ; α◌̓◌̀◌ͅ; ᾂ; α◌̓◌̀◌ͅ; ) GREEK SMALL LETTER ALPHA WITH YPOGEGRAMMENI, COMBINING GREEK KORONIS, COMBINING GRAVE TONE MARK +1F03 0345;1F83;03B1 0314 0300 0345;1F83;03B1 0314 0300 0345; # (ἃ◌ͅ; ᾃ; α◌̔◌̀◌ͅ; ᾃ; α◌̔◌̀◌ͅ; ) GREEK SMALL LETTER ALPHA WITH DASIA AND VARIA, COMBINING GREEK YPOGEGRAMMENI +1F81 0300;1F83;03B1 0314 0300 0345;1F83;03B1 0314 0300 0345; # (ᾁ◌̀; ᾃ; α◌̔◌̀◌ͅ; ᾃ; α◌̔◌̀◌ͅ; ) GREEK SMALL LETTER ALPHA WITH DASIA AND YPOGEGRAMMENI, COMBINING GRAVE ACCENT +1F81 0340;1F83;03B1 0314 0300 0345;1F83;03B1 0314 0300 0345; # (ᾁ◌̀; ᾃ; α◌̔◌̀◌ͅ; ᾃ; α◌̔◌̀◌ͅ; ) GREEK SMALL LETTER ALPHA WITH DASIA AND YPOGEGRAMMENI, COMBINING GRAVE TONE MARK +1F01 0300 0345;1F83;03B1 0314 0300 0345;1F83;03B1 0314 0300 0345; # (ἁ◌̀◌ͅ; ᾃ; α◌̔◌̀◌ͅ; ᾃ; α◌̔◌̀◌ͅ; ) GREEK SMALL LETTER ALPHA WITH DASIA, COMBINING GRAVE ACCENT, COMBINING GREEK YPOGEGRAMMENI +1F01 0340 0345;1F83;03B1 0314 0300 0345;1F83;03B1 0314 0300 0345; # (ἁ◌̀◌ͅ; ᾃ; α◌̔◌̀◌ͅ; ᾃ; α◌̔◌̀◌ͅ; ) GREEK SMALL LETTER ALPHA WITH DASIA, COMBINING GRAVE TONE MARK, COMBINING GREEK YPOGEGRAMMENI +1F01 0345 0300;1F83;03B1 0314 0300 0345;1F83;03B1 0314 0300 0345; # (ἁ◌ͅ◌̀; ᾃ; α◌̔◌̀◌ͅ; ᾃ; α◌̔◌̀◌ͅ; ) GREEK SMALL LETTER ALPHA WITH DASIA, COMBINING GREEK YPOGEGRAMMENI, COMBINING GRAVE ACCENT +1F01 0345 0340;1F83;03B1 0314 0300 0345;1F83;03B1 0314 0300 0345; # (ἁ◌ͅ◌̀; ᾃ; α◌̔◌̀◌ͅ; ᾃ; α◌̔◌̀◌ͅ; ) GREEK SMALL LETTER ALPHA WITH DASIA, COMBINING GREEK YPOGEGRAMMENI, COMBINING GRAVE TONE MARK +1FB3 0314 0300;1F83;03B1 0314 0300 0345;1F83;03B1 0314 0300 0345; # (ᾳ◌̔◌̀; ᾃ; α◌̔◌̀◌ͅ; ᾃ; α◌̔◌̀◌ͅ; ) GREEK SMALL LETTER ALPHA WITH YPOGEGRAMMENI, COMBINING REVERSED COMMA ABOVE, COMBINING GRAVE ACCENT +1FB3 0314 0340;1F83;03B1 0314 0300 0345;1F83;03B1 0314 0300 0345; # (ᾳ◌̔◌̀; ᾃ; α◌̔◌̀◌ͅ; ᾃ; α◌̔◌̀◌ͅ; ) GREEK SMALL LETTER ALPHA WITH YPOGEGRAMMENI, COMBINING REVERSED COMMA ABOVE, COMBINING GRAVE TONE MARK +1F04 0345;1F84;03B1 0313 0301 0345;1F84;03B1 0313 0301 0345; # (ἄ◌ͅ; ᾄ; α◌̓◌́◌ͅ; ᾄ; α◌̓◌́◌ͅ; ) GREEK SMALL LETTER ALPHA WITH PSILI AND OXIA, COMBINING GREEK YPOGEGRAMMENI +1F80 0301;1F84;03B1 0313 0301 0345;1F84;03B1 0313 0301 0345; # (ᾀ◌́; ᾄ; α◌̓◌́◌ͅ; ᾄ; α◌̓◌́◌ͅ; ) GREEK SMALL LETTER ALPHA WITH PSILI AND YPOGEGRAMMENI, COMBINING ACUTE ACCENT +1F80 0341;1F84;03B1 0313 0301 0345;1F84;03B1 0313 0301 0345; # (ᾀ◌́; ᾄ; α◌̓◌́◌ͅ; ᾄ; α◌̓◌́◌ͅ; ) GREEK SMALL LETTER ALPHA WITH PSILI AND YPOGEGRAMMENI, COMBINING ACUTE TONE MARK +1F00 0301 0345;1F84;03B1 0313 0301 0345;1F84;03B1 0313 0301 0345; # (ἀ◌́◌ͅ; ᾄ; α◌̓◌́◌ͅ; ᾄ; α◌̓◌́◌ͅ; ) GREEK SMALL LETTER ALPHA WITH PSILI, COMBINING ACUTE ACCENT, COMBINING GREEK YPOGEGRAMMENI +1F00 0341 0345;1F84;03B1 0313 0301 0345;1F84;03B1 0313 0301 0345; # (ἀ◌́◌ͅ; ᾄ; α◌̓◌́◌ͅ; ᾄ; α◌̓◌́◌ͅ; ) GREEK SMALL LETTER ALPHA WITH PSILI, COMBINING ACUTE TONE MARK, COMBINING GREEK YPOGEGRAMMENI +1F00 0345 0301;1F84;03B1 0313 0301 0345;1F84;03B1 0313 0301 0345; # (ἀ◌ͅ◌́; ᾄ; α◌̓◌́◌ͅ; ᾄ; α◌̓◌́◌ͅ; ) GREEK SMALL LETTER ALPHA WITH PSILI, COMBINING GREEK YPOGEGRAMMENI, COMBINING ACUTE ACCENT +1F00 0345 0341;1F84;03B1 0313 0301 0345;1F84;03B1 0313 0301 0345; # (ἀ◌ͅ◌́; ᾄ; α◌̓◌́◌ͅ; ᾄ; α◌̓◌́◌ͅ; ) GREEK SMALL LETTER ALPHA WITH PSILI, COMBINING GREEK YPOGEGRAMMENI, COMBINING ACUTE TONE MARK +1FB3 0313 0301;1F84;03B1 0313 0301 0345;1F84;03B1 0313 0301 0345; # (ᾳ◌̓◌́; ᾄ; α◌̓◌́◌ͅ; ᾄ; α◌̓◌́◌ͅ; ) GREEK SMALL LETTER ALPHA WITH YPOGEGRAMMENI, COMBINING COMMA ABOVE, COMBINING ACUTE ACCENT +1FB3 0313 0341;1F84;03B1 0313 0301 0345;1F84;03B1 0313 0301 0345; # (ᾳ◌̓◌́; ᾄ; α◌̓◌́◌ͅ; ᾄ; α◌̓◌́◌ͅ; ) GREEK SMALL LETTER ALPHA WITH YPOGEGRAMMENI, COMBINING COMMA ABOVE, COMBINING ACUTE TONE MARK +1FB3 0343 0301;1F84;03B1 0313 0301 0345;1F84;03B1 0313 0301 0345; # (ᾳ◌̓◌́; ᾄ; α◌̓◌́◌ͅ; ᾄ; α◌̓◌́◌ͅ; ) GREEK SMALL LETTER ALPHA WITH YPOGEGRAMMENI, COMBINING GREEK KORONIS, COMBINING ACUTE ACCENT +1FB3 0343 0341;1F84;03B1 0313 0301 0345;1F84;03B1 0313 0301 0345; # (ᾳ◌̓◌́; ᾄ; α◌̓◌́◌ͅ; ᾄ; α◌̓◌́◌ͅ; ) GREEK SMALL LETTER ALPHA WITH YPOGEGRAMMENI, COMBINING GREEK KORONIS, COMBINING ACUTE TONE MARK +1F05 0345;1F85;03B1 0314 0301 0345;1F85;03B1 0314 0301 0345; # (ἅ◌ͅ; ᾅ; α◌̔◌́◌ͅ; ᾅ; α◌̔◌́◌ͅ; ) GREEK SMALL LETTER ALPHA WITH DASIA AND OXIA, COMBINING GREEK YPOGEGRAMMENI +1F81 0301;1F85;03B1 0314 0301 0345;1F85;03B1 0314 0301 0345; # (ᾁ◌́; ᾅ; α◌̔◌́◌ͅ; ᾅ; α◌̔◌́◌ͅ; ) GREEK SMALL LETTER ALPHA WITH DASIA AND YPOGEGRAMMENI, COMBINING ACUTE ACCENT +1F81 0341;1F85;03B1 0314 0301 0345;1F85;03B1 0314 0301 0345; # (ᾁ◌́; ᾅ; α◌̔◌́◌ͅ; ᾅ; α◌̔◌́◌ͅ; ) GREEK SMALL LETTER ALPHA WITH DASIA AND YPOGEGRAMMENI, COMBINING ACUTE TONE MARK +1F01 0301 0345;1F85;03B1 0314 0301 0345;1F85;03B1 0314 0301 0345; # (ἁ◌́◌ͅ; ᾅ; α◌̔◌́◌ͅ; ᾅ; α◌̔◌́◌ͅ; ) GREEK SMALL LETTER ALPHA WITH DASIA, COMBINING ACUTE ACCENT, COMBINING GREEK YPOGEGRAMMENI +1F01 0341 0345;1F85;03B1 0314 0301 0345;1F85;03B1 0314 0301 0345; # (ἁ◌́◌ͅ; ᾅ; α◌̔◌́◌ͅ; ᾅ; α◌̔◌́◌ͅ; ) GREEK SMALL LETTER ALPHA WITH DASIA, COMBINING ACUTE TONE MARK, COMBINING GREEK YPOGEGRAMMENI +1F01 0345 0301;1F85;03B1 0314 0301 0345;1F85;03B1 0314 0301 0345; # (ἁ◌ͅ◌́; ᾅ; α◌̔◌́◌ͅ; ᾅ; α◌̔◌́◌ͅ; ) GREEK SMALL LETTER ALPHA WITH DASIA, COMBINING GREEK YPOGEGRAMMENI, COMBINING ACUTE ACCENT +1F01 0345 0341;1F85;03B1 0314 0301 0345;1F85;03B1 0314 0301 0345; # (ἁ◌ͅ◌́; ᾅ; α◌̔◌́◌ͅ; ᾅ; α◌̔◌́◌ͅ; ) GREEK SMALL LETTER ALPHA WITH DASIA, COMBINING GREEK YPOGEGRAMMENI, COMBINING ACUTE TONE MARK +1FB3 0314 0301;1F85;03B1 0314 0301 0345;1F85;03B1 0314 0301 0345; # (ᾳ◌̔◌́; ᾅ; α◌̔◌́◌ͅ; ᾅ; α◌̔◌́◌ͅ; ) GREEK SMALL LETTER ALPHA WITH YPOGEGRAMMENI, COMBINING REVERSED COMMA ABOVE, COMBINING ACUTE ACCENT +1FB3 0314 0341;1F85;03B1 0314 0301 0345;1F85;03B1 0314 0301 0345; # (ᾳ◌̔◌́; ᾅ; α◌̔◌́◌ͅ; ᾅ; α◌̔◌́◌ͅ; ) GREEK SMALL LETTER ALPHA WITH YPOGEGRAMMENI, COMBINING REVERSED COMMA ABOVE, COMBINING ACUTE TONE MARK +1F06 0345;1F86;03B1 0313 0342 0345;1F86;03B1 0313 0342 0345; # (ἆ◌ͅ; ᾆ; α◌̓◌͂◌ͅ; ᾆ; α◌̓◌͂◌ͅ; ) GREEK SMALL LETTER ALPHA WITH PSILI AND PERISPOMENI, COMBINING GREEK YPOGEGRAMMENI +1F80 0342;1F86;03B1 0313 0342 0345;1F86;03B1 0313 0342 0345; # (ᾀ◌͂; ᾆ; α◌̓◌͂◌ͅ; ᾆ; α◌̓◌͂◌ͅ; ) GREEK SMALL LETTER ALPHA WITH PSILI AND YPOGEGRAMMENI, COMBINING GREEK PERISPOMENI +1F00 0342 0345;1F86;03B1 0313 0342 0345;1F86;03B1 0313 0342 0345; # (ἀ◌͂◌ͅ; ᾆ; α◌̓◌͂◌ͅ; ᾆ; α◌̓◌͂◌ͅ; ) GREEK SMALL LETTER ALPHA WITH PSILI, COMBINING GREEK PERISPOMENI, COMBINING GREEK YPOGEGRAMMENI +1F00 0345 0342;1F86;03B1 0313 0342 0345;1F86;03B1 0313 0342 0345; # (ἀ◌ͅ◌͂; ᾆ; α◌̓◌͂◌ͅ; ᾆ; α◌̓◌͂◌ͅ; ) GREEK SMALL LETTER ALPHA WITH PSILI, COMBINING GREEK YPOGEGRAMMENI, COMBINING GREEK PERISPOMENI +1FB3 0313 0342;1F86;03B1 0313 0342 0345;1F86;03B1 0313 0342 0345; # (ᾳ◌̓◌͂; ᾆ; α◌̓◌͂◌ͅ; ᾆ; α◌̓◌͂◌ͅ; ) GREEK SMALL LETTER ALPHA WITH YPOGEGRAMMENI, COMBINING COMMA ABOVE, COMBINING GREEK PERISPOMENI +1FB3 0343 0342;1F86;03B1 0313 0342 0345;1F86;03B1 0313 0342 0345; # (ᾳ◌̓◌͂; ᾆ; α◌̓◌͂◌ͅ; ᾆ; α◌̓◌͂◌ͅ; ) GREEK SMALL LETTER ALPHA WITH YPOGEGRAMMENI, COMBINING GREEK KORONIS, COMBINING GREEK PERISPOMENI +1F07 0345;1F87;03B1 0314 0342 0345;1F87;03B1 0314 0342 0345; # (ἇ◌ͅ; ᾇ; α◌̔◌͂◌ͅ; ᾇ; α◌̔◌͂◌ͅ; ) GREEK SMALL LETTER ALPHA WITH DASIA AND PERISPOMENI, COMBINING GREEK YPOGEGRAMMENI +1F81 0342;1F87;03B1 0314 0342 0345;1F87;03B1 0314 0342 0345; # (ᾁ◌͂; ᾇ; α◌̔◌͂◌ͅ; ᾇ; α◌̔◌͂◌ͅ; ) GREEK SMALL LETTER ALPHA WITH DASIA AND YPOGEGRAMMENI, COMBINING GREEK PERISPOMENI +1F01 0342 0345;1F87;03B1 0314 0342 0345;1F87;03B1 0314 0342 0345; # (ἁ◌͂◌ͅ; ᾇ; α◌̔◌͂◌ͅ; ᾇ; α◌̔◌͂◌ͅ; ) GREEK SMALL LETTER ALPHA WITH DASIA, COMBINING GREEK PERISPOMENI, COMBINING GREEK YPOGEGRAMMENI +1F01 0345 0342;1F87;03B1 0314 0342 0345;1F87;03B1 0314 0342 0345; # (ἁ◌ͅ◌͂; ᾇ; α◌̔◌͂◌ͅ; ᾇ; α◌̔◌͂◌ͅ; ) GREEK SMALL LETTER ALPHA WITH DASIA, COMBINING GREEK YPOGEGRAMMENI, COMBINING GREEK PERISPOMENI +1FB3 0314 0342;1F87;03B1 0314 0342 0345;1F87;03B1 0314 0342 0345; # (ᾳ◌̔◌͂; ᾇ; α◌̔◌͂◌ͅ; ᾇ; α◌̔◌͂◌ͅ; ) GREEK SMALL LETTER ALPHA WITH YPOGEGRAMMENI, COMBINING REVERSED COMMA ABOVE, COMBINING GREEK PERISPOMENI +1F08 0345;1F88;0391 0313 0345;1F88;0391 0313 0345; # (Ἀ◌ͅ; ᾈ; Α◌̓◌ͅ; ᾈ; Α◌̓◌ͅ; ) GREEK CAPITAL LETTER ALPHA WITH PSILI, COMBINING GREEK YPOGEGRAMMENI +1FBC 0313;1F88;0391 0313 0345;1F88;0391 0313 0345; # (ᾼ◌̓; ᾈ; Α◌̓◌ͅ; ᾈ; Α◌̓◌ͅ; ) GREEK CAPITAL LETTER ALPHA WITH PROSGEGRAMMENI, COMBINING COMMA ABOVE +1FBC 0343;1F88;0391 0313 0345;1F88;0391 0313 0345; # (ᾼ◌̓; ᾈ; Α◌̓◌ͅ; ᾈ; Α◌̓◌ͅ; ) GREEK CAPITAL LETTER ALPHA WITH PROSGEGRAMMENI, COMBINING GREEK KORONIS +1F09 0345;1F89;0391 0314 0345;1F89;0391 0314 0345; # (Ἁ◌ͅ; ᾉ; Α◌̔◌ͅ; ᾉ; Α◌̔◌ͅ; ) GREEK CAPITAL LETTER ALPHA WITH DASIA, COMBINING GREEK YPOGEGRAMMENI +1FBC 0314;1F89;0391 0314 0345;1F89;0391 0314 0345; # (ᾼ◌̔; ᾉ; Α◌̔◌ͅ; ᾉ; Α◌̔◌ͅ; ) GREEK CAPITAL LETTER ALPHA WITH PROSGEGRAMMENI, COMBINING REVERSED COMMA ABOVE +1F0A 0345;1F8A;0391 0313 0300 0345;1F8A;0391 0313 0300 0345; # (Ἂ◌ͅ; ᾊ; Α◌̓◌̀◌ͅ; ᾊ; Α◌̓◌̀◌ͅ; ) GREEK CAPITAL LETTER ALPHA WITH PSILI AND VARIA, COMBINING GREEK YPOGEGRAMMENI +1F88 0300;1F8A;0391 0313 0300 0345;1F8A;0391 0313 0300 0345; # (ᾈ◌̀; ᾊ; Α◌̓◌̀◌ͅ; ᾊ; Α◌̓◌̀◌ͅ; ) GREEK CAPITAL LETTER ALPHA WITH PSILI AND PROSGEGRAMMENI, COMBINING GRAVE ACCENT +1F88 0340;1F8A;0391 0313 0300 0345;1F8A;0391 0313 0300 0345; # (ᾈ◌̀; ᾊ; Α◌̓◌̀◌ͅ; ᾊ; Α◌̓◌̀◌ͅ; ) GREEK CAPITAL LETTER ALPHA WITH PSILI AND PROSGEGRAMMENI, COMBINING GRAVE TONE MARK +1F08 0300 0345;1F8A;0391 0313 0300 0345;1F8A;0391 0313 0300 0345; # (Ἀ◌̀◌ͅ; ᾊ; Α◌̓◌̀◌ͅ; ᾊ; Α◌̓◌̀◌ͅ; ) GREEK CAPITAL LETTER ALPHA WITH PSILI, COMBINING GRAVE ACCENT, COMBINING GREEK YPOGEGRAMMENI +1F08 0340 0345;1F8A;0391 0313 0300 0345;1F8A;0391 0313 0300 0345; # (Ἀ◌̀◌ͅ; ᾊ; Α◌̓◌̀◌ͅ; ᾊ; Α◌̓◌̀◌ͅ; ) GREEK CAPITAL LETTER ALPHA WITH PSILI, COMBINING GRAVE TONE MARK, COMBINING GREEK YPOGEGRAMMENI +1F08 0345 0300;1F8A;0391 0313 0300 0345;1F8A;0391 0313 0300 0345; # (Ἀ◌ͅ◌̀; ᾊ; Α◌̓◌̀◌ͅ; ᾊ; Α◌̓◌̀◌ͅ; ) GREEK CAPITAL LETTER ALPHA WITH PSILI, COMBINING GREEK YPOGEGRAMMENI, COMBINING GRAVE ACCENT +1F08 0345 0340;1F8A;0391 0313 0300 0345;1F8A;0391 0313 0300 0345; # (Ἀ◌ͅ◌̀; ᾊ; Α◌̓◌̀◌ͅ; ᾊ; Α◌̓◌̀◌ͅ; ) GREEK CAPITAL LETTER ALPHA WITH PSILI, COMBINING GREEK YPOGEGRAMMENI, COMBINING GRAVE TONE MARK +1FBC 0313 0300;1F8A;0391 0313 0300 0345;1F8A;0391 0313 0300 0345; # (ᾼ◌̓◌̀; ᾊ; Α◌̓◌̀◌ͅ; ᾊ; Α◌̓◌̀◌ͅ; ) GREEK CAPITAL LETTER ALPHA WITH PROSGEGRAMMENI, COMBINING COMMA ABOVE, COMBINING GRAVE ACCENT +1FBC 0313 0340;1F8A;0391 0313 0300 0345;1F8A;0391 0313 0300 0345; # (ᾼ◌̓◌̀; ᾊ; Α◌̓◌̀◌ͅ; ᾊ; Α◌̓◌̀◌ͅ; ) GREEK CAPITAL LETTER ALPHA WITH PROSGEGRAMMENI, COMBINING COMMA ABOVE, COMBINING GRAVE TONE MARK +1FBC 0343 0300;1F8A;0391 0313 0300 0345;1F8A;0391 0313 0300 0345; # (ᾼ◌̓◌̀; ᾊ; Α◌̓◌̀◌ͅ; ᾊ; Α◌̓◌̀◌ͅ; ) GREEK CAPITAL LETTER ALPHA WITH PROSGEGRAMMENI, COMBINING GREEK KORONIS, COMBINING GRAVE ACCENT +1FBC 0343 0340;1F8A;0391 0313 0300 0345;1F8A;0391 0313 0300 0345; # (ᾼ◌̓◌̀; ᾊ; Α◌̓◌̀◌ͅ; ᾊ; Α◌̓◌̀◌ͅ; ) GREEK CAPITAL LETTER ALPHA WITH PROSGEGRAMMENI, COMBINING GREEK KORONIS, COMBINING GRAVE TONE MARK +1F0B 0345;1F8B;0391 0314 0300 0345;1F8B;0391 0314 0300 0345; # (Ἃ◌ͅ; ᾋ; Α◌̔◌̀◌ͅ; ᾋ; Α◌̔◌̀◌ͅ; ) GREEK CAPITAL LETTER ALPHA WITH DASIA AND VARIA, COMBINING GREEK YPOGEGRAMMENI +1F89 0300;1F8B;0391 0314 0300 0345;1F8B;0391 0314 0300 0345; # (ᾉ◌̀; ᾋ; Α◌̔◌̀◌ͅ; ᾋ; Α◌̔◌̀◌ͅ; ) GREEK CAPITAL LETTER ALPHA WITH DASIA AND PROSGEGRAMMENI, COMBINING GRAVE ACCENT +1F89 0340;1F8B;0391 0314 0300 0345;1F8B;0391 0314 0300 0345; # (ᾉ◌̀; ᾋ; Α◌̔◌̀◌ͅ; ᾋ; Α◌̔◌̀◌ͅ; ) GREEK CAPITAL LETTER ALPHA WITH DASIA AND PROSGEGRAMMENI, COMBINING GRAVE TONE MARK +1F09 0300 0345;1F8B;0391 0314 0300 0345;1F8B;0391 0314 0300 0345; # (Ἁ◌̀◌ͅ; ᾋ; Α◌̔◌̀◌ͅ; ᾋ; Α◌̔◌̀◌ͅ; ) GREEK CAPITAL LETTER ALPHA WITH DASIA, COMBINING GRAVE ACCENT, COMBINING GREEK YPOGEGRAMMENI +1F09 0340 0345;1F8B;0391 0314 0300 0345;1F8B;0391 0314 0300 0345; # (Ἁ◌̀◌ͅ; ᾋ; Α◌̔◌̀◌ͅ; ᾋ; Α◌̔◌̀◌ͅ; ) GREEK CAPITAL LETTER ALPHA WITH DASIA, COMBINING GRAVE TONE MARK, COMBINING GREEK YPOGEGRAMMENI +1F09 0345 0300;1F8B;0391 0314 0300 0345;1F8B;0391 0314 0300 0345; # (Ἁ◌ͅ◌̀; ᾋ; Α◌̔◌̀◌ͅ; ᾋ; Α◌̔◌̀◌ͅ; ) GREEK CAPITAL LETTER ALPHA WITH DASIA, COMBINING GREEK YPOGEGRAMMENI, COMBINING GRAVE ACCENT +1F09 0345 0340;1F8B;0391 0314 0300 0345;1F8B;0391 0314 0300 0345; # (Ἁ◌ͅ◌̀; ᾋ; Α◌̔◌̀◌ͅ; ᾋ; Α◌̔◌̀◌ͅ; ) GREEK CAPITAL LETTER ALPHA WITH DASIA, COMBINING GREEK YPOGEGRAMMENI, COMBINING GRAVE TONE MARK +1FBC 0314 0300;1F8B;0391 0314 0300 0345;1F8B;0391 0314 0300 0345; # (ᾼ◌̔◌̀; ᾋ; Α◌̔◌̀◌ͅ; ᾋ; Α◌̔◌̀◌ͅ; ) GREEK CAPITAL LETTER ALPHA WITH PROSGEGRAMMENI, COMBINING REVERSED COMMA ABOVE, COMBINING GRAVE ACCENT +1FBC 0314 0340;1F8B;0391 0314 0300 0345;1F8B;0391 0314 0300 0345; # (ᾼ◌̔◌̀; ᾋ; Α◌̔◌̀◌ͅ; ᾋ; Α◌̔◌̀◌ͅ; ) GREEK CAPITAL LETTER ALPHA WITH PROSGEGRAMMENI, COMBINING REVERSED COMMA ABOVE, COMBINING GRAVE TONE MARK +1F0C 0345;1F8C;0391 0313 0301 0345;1F8C;0391 0313 0301 0345; # (Ἄ◌ͅ; ᾌ; Α◌̓◌́◌ͅ; ᾌ; Α◌̓◌́◌ͅ; ) GREEK CAPITAL LETTER ALPHA WITH PSILI AND OXIA, COMBINING GREEK YPOGEGRAMMENI +1F88 0301;1F8C;0391 0313 0301 0345;1F8C;0391 0313 0301 0345; # (ᾈ◌́; ᾌ; Α◌̓◌́◌ͅ; ᾌ; Α◌̓◌́◌ͅ; ) GREEK CAPITAL LETTER ALPHA WITH PSILI AND PROSGEGRAMMENI, COMBINING ACUTE ACCENT +1F88 0341;1F8C;0391 0313 0301 0345;1F8C;0391 0313 0301 0345; # (ᾈ◌́; ᾌ; Α◌̓◌́◌ͅ; ᾌ; Α◌̓◌́◌ͅ; ) GREEK CAPITAL LETTER ALPHA WITH PSILI AND PROSGEGRAMMENI, COMBINING ACUTE TONE MARK +1F08 0301 0345;1F8C;0391 0313 0301 0345;1F8C;0391 0313 0301 0345; # (Ἀ◌́◌ͅ; ᾌ; Α◌̓◌́◌ͅ; ᾌ; Α◌̓◌́◌ͅ; ) GREEK CAPITAL LETTER ALPHA WITH PSILI, COMBINING ACUTE ACCENT, COMBINING GREEK YPOGEGRAMMENI +1F08 0341 0345;1F8C;0391 0313 0301 0345;1F8C;0391 0313 0301 0345; # (Ἀ◌́◌ͅ; ᾌ; Α◌̓◌́◌ͅ; ᾌ; Α◌̓◌́◌ͅ; ) GREEK CAPITAL LETTER ALPHA WITH PSILI, COMBINING ACUTE TONE MARK, COMBINING GREEK YPOGEGRAMMENI +1F08 0345 0301;1F8C;0391 0313 0301 0345;1F8C;0391 0313 0301 0345; # (Ἀ◌ͅ◌́; ᾌ; Α◌̓◌́◌ͅ; ᾌ; Α◌̓◌́◌ͅ; ) GREEK CAPITAL LETTER ALPHA WITH PSILI, COMBINING GREEK YPOGEGRAMMENI, COMBINING ACUTE ACCENT +1F08 0345 0341;1F8C;0391 0313 0301 0345;1F8C;0391 0313 0301 0345; # (Ἀ◌ͅ◌́; ᾌ; Α◌̓◌́◌ͅ; ᾌ; Α◌̓◌́◌ͅ; ) GREEK CAPITAL LETTER ALPHA WITH PSILI, COMBINING GREEK YPOGEGRAMMENI, COMBINING ACUTE TONE MARK +1FBC 0313 0301;1F8C;0391 0313 0301 0345;1F8C;0391 0313 0301 0345; # (ᾼ◌̓◌́; ᾌ; Α◌̓◌́◌ͅ; ᾌ; Α◌̓◌́◌ͅ; ) GREEK CAPITAL LETTER ALPHA WITH PROSGEGRAMMENI, COMBINING COMMA ABOVE, COMBINING ACUTE ACCENT +1FBC 0313 0341;1F8C;0391 0313 0301 0345;1F8C;0391 0313 0301 0345; # (ᾼ◌̓◌́; ᾌ; Α◌̓◌́◌ͅ; ᾌ; Α◌̓◌́◌ͅ; ) GREEK CAPITAL LETTER ALPHA WITH PROSGEGRAMMENI, COMBINING COMMA ABOVE, COMBINING ACUTE TONE MARK +1FBC 0343 0301;1F8C;0391 0313 0301 0345;1F8C;0391 0313 0301 0345; # (ᾼ◌̓◌́; ᾌ; Α◌̓◌́◌ͅ; ᾌ; Α◌̓◌́◌ͅ; ) GREEK CAPITAL LETTER ALPHA WITH PROSGEGRAMMENI, COMBINING GREEK KORONIS, COMBINING ACUTE ACCENT +1FBC 0343 0341;1F8C;0391 0313 0301 0345;1F8C;0391 0313 0301 0345; # (ᾼ◌̓◌́; ᾌ; Α◌̓◌́◌ͅ; ᾌ; Α◌̓◌́◌ͅ; ) GREEK CAPITAL LETTER ALPHA WITH PROSGEGRAMMENI, COMBINING GREEK KORONIS, COMBINING ACUTE TONE MARK +1F0D 0345;1F8D;0391 0314 0301 0345;1F8D;0391 0314 0301 0345; # (Ἅ◌ͅ; ᾍ; Α◌̔◌́◌ͅ; ᾍ; Α◌̔◌́◌ͅ; ) GREEK CAPITAL LETTER ALPHA WITH DASIA AND OXIA, COMBINING GREEK YPOGEGRAMMENI +1F89 0301;1F8D;0391 0314 0301 0345;1F8D;0391 0314 0301 0345; # (ᾉ◌́; ᾍ; Α◌̔◌́◌ͅ; ᾍ; Α◌̔◌́◌ͅ; ) GREEK CAPITAL LETTER ALPHA WITH DASIA AND PROSGEGRAMMENI, COMBINING ACUTE ACCENT +1F89 0341;1F8D;0391 0314 0301 0345;1F8D;0391 0314 0301 0345; # (ᾉ◌́; ᾍ; Α◌̔◌́◌ͅ; ᾍ; Α◌̔◌́◌ͅ; ) GREEK CAPITAL LETTER ALPHA WITH DASIA AND PROSGEGRAMMENI, COMBINING ACUTE TONE MARK +1F09 0301 0345;1F8D;0391 0314 0301 0345;1F8D;0391 0314 0301 0345; # (Ἁ◌́◌ͅ; ᾍ; Α◌̔◌́◌ͅ; ᾍ; Α◌̔◌́◌ͅ; ) GREEK CAPITAL LETTER ALPHA WITH DASIA, COMBINING ACUTE ACCENT, COMBINING GREEK YPOGEGRAMMENI +1F09 0341 0345;1F8D;0391 0314 0301 0345;1F8D;0391 0314 0301 0345; # (Ἁ◌́◌ͅ; ᾍ; Α◌̔◌́◌ͅ; ᾍ; Α◌̔◌́◌ͅ; ) GREEK CAPITAL LETTER ALPHA WITH DASIA, COMBINING ACUTE TONE MARK, COMBINING GREEK YPOGEGRAMMENI +1F09 0345 0301;1F8D;0391 0314 0301 0345;1F8D;0391 0314 0301 0345; # (Ἁ◌ͅ◌́; ᾍ; Α◌̔◌́◌ͅ; ᾍ; Α◌̔◌́◌ͅ; ) GREEK CAPITAL LETTER ALPHA WITH DASIA, COMBINING GREEK YPOGEGRAMMENI, COMBINING ACUTE ACCENT +1F09 0345 0341;1F8D;0391 0314 0301 0345;1F8D;0391 0314 0301 0345; # (Ἁ◌ͅ◌́; ᾍ; Α◌̔◌́◌ͅ; ᾍ; Α◌̔◌́◌ͅ; ) GREEK CAPITAL LETTER ALPHA WITH DASIA, COMBINING GREEK YPOGEGRAMMENI, COMBINING ACUTE TONE MARK +1FBC 0314 0301;1F8D;0391 0314 0301 0345;1F8D;0391 0314 0301 0345; # (ᾼ◌̔◌́; ᾍ; Α◌̔◌́◌ͅ; ᾍ; Α◌̔◌́◌ͅ; ) GREEK CAPITAL LETTER ALPHA WITH PROSGEGRAMMENI, COMBINING REVERSED COMMA ABOVE, COMBINING ACUTE ACCENT +1FBC 0314 0341;1F8D;0391 0314 0301 0345;1F8D;0391 0314 0301 0345; # (ᾼ◌̔◌́; ᾍ; Α◌̔◌́◌ͅ; ᾍ; Α◌̔◌́◌ͅ; ) GREEK CAPITAL LETTER ALPHA WITH PROSGEGRAMMENI, COMBINING REVERSED COMMA ABOVE, COMBINING ACUTE TONE MARK +1F0E 0345;1F8E;0391 0313 0342 0345;1F8E;0391 0313 0342 0345; # (Ἆ◌ͅ; ᾎ; Α◌̓◌͂◌ͅ; ᾎ; Α◌̓◌͂◌ͅ; ) GREEK CAPITAL LETTER ALPHA WITH PSILI AND PERISPOMENI, COMBINING GREEK YPOGEGRAMMENI +1F88 0342;1F8E;0391 0313 0342 0345;1F8E;0391 0313 0342 0345; # (ᾈ◌͂; ᾎ; Α◌̓◌͂◌ͅ; ᾎ; Α◌̓◌͂◌ͅ; ) GREEK CAPITAL LETTER ALPHA WITH PSILI AND PROSGEGRAMMENI, COMBINING GREEK PERISPOMENI +1F08 0342 0345;1F8E;0391 0313 0342 0345;1F8E;0391 0313 0342 0345; # (Ἀ◌͂◌ͅ; ᾎ; Α◌̓◌͂◌ͅ; ᾎ; Α◌̓◌͂◌ͅ; ) GREEK CAPITAL LETTER ALPHA WITH PSILI, COMBINING GREEK PERISPOMENI, COMBINING GREEK YPOGEGRAMMENI +1F08 0345 0342;1F8E;0391 0313 0342 0345;1F8E;0391 0313 0342 0345; # (Ἀ◌ͅ◌͂; ᾎ; Α◌̓◌͂◌ͅ; ᾎ; Α◌̓◌͂◌ͅ; ) GREEK CAPITAL LETTER ALPHA WITH PSILI, COMBINING GREEK YPOGEGRAMMENI, COMBINING GREEK PERISPOMENI +1FBC 0313 0342;1F8E;0391 0313 0342 0345;1F8E;0391 0313 0342 0345; # (ᾼ◌̓◌͂; ᾎ; Α◌̓◌͂◌ͅ; ᾎ; Α◌̓◌͂◌ͅ; ) GREEK CAPITAL LETTER ALPHA WITH PROSGEGRAMMENI, COMBINING COMMA ABOVE, COMBINING GREEK PERISPOMENI +1FBC 0343 0342;1F8E;0391 0313 0342 0345;1F8E;0391 0313 0342 0345; # (ᾼ◌̓◌͂; ᾎ; Α◌̓◌͂◌ͅ; ᾎ; Α◌̓◌͂◌ͅ; ) GREEK CAPITAL LETTER ALPHA WITH PROSGEGRAMMENI, COMBINING GREEK KORONIS, COMBINING GREEK PERISPOMENI +1F0F 0345;1F8F;0391 0314 0342 0345;1F8F;0391 0314 0342 0345; # (Ἇ◌ͅ; ᾏ; Α◌̔◌͂◌ͅ; ᾏ; Α◌̔◌͂◌ͅ; ) GREEK CAPITAL LETTER ALPHA WITH DASIA AND PERISPOMENI, COMBINING GREEK YPOGEGRAMMENI +1F89 0342;1F8F;0391 0314 0342 0345;1F8F;0391 0314 0342 0345; # (ᾉ◌͂; ᾏ; Α◌̔◌͂◌ͅ; ᾏ; Α◌̔◌͂◌ͅ; ) GREEK CAPITAL LETTER ALPHA WITH DASIA AND PROSGEGRAMMENI, COMBINING GREEK PERISPOMENI +1F09 0342 0345;1F8F;0391 0314 0342 0345;1F8F;0391 0314 0342 0345; # (Ἁ◌͂◌ͅ; ᾏ; Α◌̔◌͂◌ͅ; ᾏ; Α◌̔◌͂◌ͅ; ) GREEK CAPITAL LETTER ALPHA WITH DASIA, COMBINING GREEK PERISPOMENI, COMBINING GREEK YPOGEGRAMMENI +1F09 0345 0342;1F8F;0391 0314 0342 0345;1F8F;0391 0314 0342 0345; # (Ἁ◌ͅ◌͂; ᾏ; Α◌̔◌͂◌ͅ; ᾏ; Α◌̔◌͂◌ͅ; ) GREEK CAPITAL LETTER ALPHA WITH DASIA, COMBINING GREEK YPOGEGRAMMENI, COMBINING GREEK PERISPOMENI +1FBC 0314 0342;1F8F;0391 0314 0342 0345;1F8F;0391 0314 0342 0345; # (ᾼ◌̔◌͂; ᾏ; Α◌̔◌͂◌ͅ; ᾏ; Α◌̔◌͂◌ͅ; ) GREEK CAPITAL LETTER ALPHA WITH PROSGEGRAMMENI, COMBINING REVERSED COMMA ABOVE, COMBINING GREEK PERISPOMENI +1F20 0345;1F90;03B7 0313 0345;1F90;03B7 0313 0345; # (ἠ◌ͅ; ᾐ; η◌̓◌ͅ; ᾐ; η◌̓◌ͅ; ) GREEK SMALL LETTER ETA WITH PSILI, COMBINING GREEK YPOGEGRAMMENI +1FC3 0313;1F90;03B7 0313 0345;1F90;03B7 0313 0345; # (ῃ◌̓; ᾐ; η◌̓◌ͅ; ᾐ; η◌̓◌ͅ; ) GREEK SMALL LETTER ETA WITH YPOGEGRAMMENI, COMBINING COMMA ABOVE +1FC3 0343;1F90;03B7 0313 0345;1F90;03B7 0313 0345; # (ῃ◌̓; ᾐ; η◌̓◌ͅ; ᾐ; η◌̓◌ͅ; ) GREEK SMALL LETTER ETA WITH YPOGEGRAMMENI, COMBINING GREEK KORONIS +1F21 0345;1F91;03B7 0314 0345;1F91;03B7 0314 0345; # (ἡ◌ͅ; ᾑ; η◌̔◌ͅ; ᾑ; η◌̔◌ͅ; ) GREEK SMALL LETTER ETA WITH DASIA, COMBINING GREEK YPOGEGRAMMENI +1FC3 0314;1F91;03B7 0314 0345;1F91;03B7 0314 0345; # (ῃ◌̔; ᾑ; η◌̔◌ͅ; ᾑ; η◌̔◌ͅ; ) GREEK SMALL LETTER ETA WITH YPOGEGRAMMENI, COMBINING REVERSED COMMA ABOVE +1F22 0345;1F92;03B7 0313 0300 0345;1F92;03B7 0313 0300 0345; # (ἢ◌ͅ; ᾒ; η◌̓◌̀◌ͅ; ᾒ; η◌̓◌̀◌ͅ; ) GREEK SMALL LETTER ETA WITH PSILI AND VARIA, COMBINING GREEK YPOGEGRAMMENI +1F90 0300;1F92;03B7 0313 0300 0345;1F92;03B7 0313 0300 0345; # (ᾐ◌̀; ᾒ; η◌̓◌̀◌ͅ; ᾒ; η◌̓◌̀◌ͅ; ) GREEK SMALL LETTER ETA WITH PSILI AND YPOGEGRAMMENI, COMBINING GRAVE ACCENT +1F90 0340;1F92;03B7 0313 0300 0345;1F92;03B7 0313 0300 0345; # (ᾐ◌̀; ᾒ; η◌̓◌̀◌ͅ; ᾒ; η◌̓◌̀◌ͅ; ) GREEK SMALL LETTER ETA WITH PSILI AND YPOGEGRAMMENI, COMBINING GRAVE TONE MARK +1F20 0300 0345;1F92;03B7 0313 0300 0345;1F92;03B7 0313 0300 0345; # (ἠ◌̀◌ͅ; ᾒ; η◌̓◌̀◌ͅ; ᾒ; η◌̓◌̀◌ͅ; ) GREEK SMALL LETTER ETA WITH PSILI, COMBINING GRAVE ACCENT, COMBINING GREEK YPOGEGRAMMENI +1F20 0340 0345;1F92;03B7 0313 0300 0345;1F92;03B7 0313 0300 0345; # (ἠ◌̀◌ͅ; ᾒ; η◌̓◌̀◌ͅ; ᾒ; η◌̓◌̀◌ͅ; ) GREEK SMALL LETTER ETA WITH PSILI, COMBINING GRAVE TONE MARK, COMBINING GREEK YPOGEGRAMMENI +1F20 0345 0300;1F92;03B7 0313 0300 0345;1F92;03B7 0313 0300 0345; # (ἠ◌ͅ◌̀; ᾒ; η◌̓◌̀◌ͅ; ᾒ; η◌̓◌̀◌ͅ; ) GREEK SMALL LETTER ETA WITH PSILI, COMBINING GREEK YPOGEGRAMMENI, COMBINING GRAVE ACCENT +1F20 0345 0340;1F92;03B7 0313 0300 0345;1F92;03B7 0313 0300 0345; # (ἠ◌ͅ◌̀; ᾒ; η◌̓◌̀◌ͅ; ᾒ; η◌̓◌̀◌ͅ; ) GREEK SMALL LETTER ETA WITH PSILI, COMBINING GREEK YPOGEGRAMMENI, COMBINING GRAVE TONE MARK +1FC3 0313 0300;1F92;03B7 0313 0300 0345;1F92;03B7 0313 0300 0345; # (ῃ◌̓◌̀; ᾒ; η◌̓◌̀◌ͅ; ᾒ; η◌̓◌̀◌ͅ; ) GREEK SMALL LETTER ETA WITH YPOGEGRAMMENI, COMBINING COMMA ABOVE, COMBINING GRAVE ACCENT +1FC3 0313 0340;1F92;03B7 0313 0300 0345;1F92;03B7 0313 0300 0345; # (ῃ◌̓◌̀; ᾒ; η◌̓◌̀◌ͅ; ᾒ; η◌̓◌̀◌ͅ; ) GREEK SMALL LETTER ETA WITH YPOGEGRAMMENI, COMBINING COMMA ABOVE, COMBINING GRAVE TONE MARK +1FC3 0343 0300;1F92;03B7 0313 0300 0345;1F92;03B7 0313 0300 0345; # (ῃ◌̓◌̀; ᾒ; η◌̓◌̀◌ͅ; ᾒ; η◌̓◌̀◌ͅ; ) GREEK SMALL LETTER ETA WITH YPOGEGRAMMENI, COMBINING GREEK KORONIS, COMBINING GRAVE ACCENT +1FC3 0343 0340;1F92;03B7 0313 0300 0345;1F92;03B7 0313 0300 0345; # (ῃ◌̓◌̀; ᾒ; η◌̓◌̀◌ͅ; ᾒ; η◌̓◌̀◌ͅ; ) GREEK SMALL LETTER ETA WITH YPOGEGRAMMENI, COMBINING GREEK KORONIS, COMBINING GRAVE TONE MARK +1F23 0345;1F93;03B7 0314 0300 0345;1F93;03B7 0314 0300 0345; # (ἣ◌ͅ; ᾓ; η◌̔◌̀◌ͅ; ᾓ; η◌̔◌̀◌ͅ; ) GREEK SMALL LETTER ETA WITH DASIA AND VARIA, COMBINING GREEK YPOGEGRAMMENI +1F91 0300;1F93;03B7 0314 0300 0345;1F93;03B7 0314 0300 0345; # (ᾑ◌̀; ᾓ; η◌̔◌̀◌ͅ; ᾓ; η◌̔◌̀◌ͅ; ) GREEK SMALL LETTER ETA WITH DASIA AND YPOGEGRAMMENI, COMBINING GRAVE ACCENT +1F91 0340;1F93;03B7 0314 0300 0345;1F93;03B7 0314 0300 0345; # (ᾑ◌̀; ᾓ; η◌̔◌̀◌ͅ; ᾓ; η◌̔◌̀◌ͅ; ) GREEK SMALL LETTER ETA WITH DASIA AND YPOGEGRAMMENI, COMBINING GRAVE TONE MARK +1F21 0300 0345;1F93;03B7 0314 0300 0345;1F93;03B7 0314 0300 0345; # (ἡ◌̀◌ͅ; ᾓ; η◌̔◌̀◌ͅ; ᾓ; η◌̔◌̀◌ͅ; ) GREEK SMALL LETTER ETA WITH DASIA, COMBINING GRAVE ACCENT, COMBINING GREEK YPOGEGRAMMENI +1F21 0340 0345;1F93;03B7 0314 0300 0345;1F93;03B7 0314 0300 0345; # (ἡ◌̀◌ͅ; ᾓ; η◌̔◌̀◌ͅ; ᾓ; η◌̔◌̀◌ͅ; ) GREEK SMALL LETTER ETA WITH DASIA, COMBINING GRAVE TONE MARK, COMBINING GREEK YPOGEGRAMMENI +1F21 0345 0300;1F93;03B7 0314 0300 0345;1F93;03B7 0314 0300 0345; # (ἡ◌ͅ◌̀; ᾓ; η◌̔◌̀◌ͅ; ᾓ; η◌̔◌̀◌ͅ; ) GREEK SMALL LETTER ETA WITH DASIA, COMBINING GREEK YPOGEGRAMMENI, COMBINING GRAVE ACCENT +1F21 0345 0340;1F93;03B7 0314 0300 0345;1F93;03B7 0314 0300 0345; # (ἡ◌ͅ◌̀; ᾓ; η◌̔◌̀◌ͅ; ᾓ; η◌̔◌̀◌ͅ; ) GREEK SMALL LETTER ETA WITH DASIA, COMBINING GREEK YPOGEGRAMMENI, COMBINING GRAVE TONE MARK +1FC3 0314 0300;1F93;03B7 0314 0300 0345;1F93;03B7 0314 0300 0345; # (ῃ◌̔◌̀; ᾓ; η◌̔◌̀◌ͅ; ᾓ; η◌̔◌̀◌ͅ; ) GREEK SMALL LETTER ETA WITH YPOGEGRAMMENI, COMBINING REVERSED COMMA ABOVE, COMBINING GRAVE ACCENT +1FC3 0314 0340;1F93;03B7 0314 0300 0345;1F93;03B7 0314 0300 0345; # (ῃ◌̔◌̀; ᾓ; η◌̔◌̀◌ͅ; ᾓ; η◌̔◌̀◌ͅ; ) GREEK SMALL LETTER ETA WITH YPOGEGRAMMENI, COMBINING REVERSED COMMA ABOVE, COMBINING GRAVE TONE MARK +1F24 0345;1F94;03B7 0313 0301 0345;1F94;03B7 0313 0301 0345; # (ἤ◌ͅ; ᾔ; η◌̓◌́◌ͅ; ᾔ; η◌̓◌́◌ͅ; ) GREEK SMALL LETTER ETA WITH PSILI AND OXIA, COMBINING GREEK YPOGEGRAMMENI +1F90 0301;1F94;03B7 0313 0301 0345;1F94;03B7 0313 0301 0345; # (ᾐ◌́; ᾔ; η◌̓◌́◌ͅ; ᾔ; η◌̓◌́◌ͅ; ) GREEK SMALL LETTER ETA WITH PSILI AND YPOGEGRAMMENI, COMBINING ACUTE ACCENT +1F90 0341;1F94;03B7 0313 0301 0345;1F94;03B7 0313 0301 0345; # (ᾐ◌́; ᾔ; η◌̓◌́◌ͅ; ᾔ; η◌̓◌́◌ͅ; ) GREEK SMALL LETTER ETA WITH PSILI AND YPOGEGRAMMENI, COMBINING ACUTE TONE MARK +1F20 0301 0345;1F94;03B7 0313 0301 0345;1F94;03B7 0313 0301 0345; # (ἠ◌́◌ͅ; ᾔ; η◌̓◌́◌ͅ; ᾔ; η◌̓◌́◌ͅ; ) GREEK SMALL LETTER ETA WITH PSILI, COMBINING ACUTE ACCENT, COMBINING GREEK YPOGEGRAMMENI +1F20 0341 0345;1F94;03B7 0313 0301 0345;1F94;03B7 0313 0301 0345; # (ἠ◌́◌ͅ; ᾔ; η◌̓◌́◌ͅ; ᾔ; η◌̓◌́◌ͅ; ) GREEK SMALL LETTER ETA WITH PSILI, COMBINING ACUTE TONE MARK, COMBINING GREEK YPOGEGRAMMENI +1F20 0345 0301;1F94;03B7 0313 0301 0345;1F94;03B7 0313 0301 0345; # (ἠ◌ͅ◌́; ᾔ; η◌̓◌́◌ͅ; ᾔ; η◌̓◌́◌ͅ; ) GREEK SMALL LETTER ETA WITH PSILI, COMBINING GREEK YPOGEGRAMMENI, COMBINING ACUTE ACCENT +1F20 0345 0341;1F94;03B7 0313 0301 0345;1F94;03B7 0313 0301 0345; # (ἠ◌ͅ◌́; ᾔ; η◌̓◌́◌ͅ; ᾔ; η◌̓◌́◌ͅ; ) GREEK SMALL LETTER ETA WITH PSILI, COMBINING GREEK YPOGEGRAMMENI, COMBINING ACUTE TONE MARK +1FC3 0313 0301;1F94;03B7 0313 0301 0345;1F94;03B7 0313 0301 0345; # (ῃ◌̓◌́; ᾔ; η◌̓◌́◌ͅ; ᾔ; η◌̓◌́◌ͅ; ) GREEK SMALL LETTER ETA WITH YPOGEGRAMMENI, COMBINING COMMA ABOVE, COMBINING ACUTE ACCENT +1FC3 0313 0341;1F94;03B7 0313 0301 0345;1F94;03B7 0313 0301 0345; # (ῃ◌̓◌́; ᾔ; η◌̓◌́◌ͅ; ᾔ; η◌̓◌́◌ͅ; ) GREEK SMALL LETTER ETA WITH YPOGEGRAMMENI, COMBINING COMMA ABOVE, COMBINING ACUTE TONE MARK +1FC3 0343 0301;1F94;03B7 0313 0301 0345;1F94;03B7 0313 0301 0345; # (ῃ◌̓◌́; ᾔ; η◌̓◌́◌ͅ; ᾔ; η◌̓◌́◌ͅ; ) GREEK SMALL LETTER ETA WITH YPOGEGRAMMENI, COMBINING GREEK KORONIS, COMBINING ACUTE ACCENT +1FC3 0343 0341;1F94;03B7 0313 0301 0345;1F94;03B7 0313 0301 0345; # (ῃ◌̓◌́; ᾔ; η◌̓◌́◌ͅ; ᾔ; η◌̓◌́◌ͅ; ) GREEK SMALL LETTER ETA WITH YPOGEGRAMMENI, COMBINING GREEK KORONIS, COMBINING ACUTE TONE MARK +1F25 0345;1F95;03B7 0314 0301 0345;1F95;03B7 0314 0301 0345; # (ἥ◌ͅ; ᾕ; η◌̔◌́◌ͅ; ᾕ; η◌̔◌́◌ͅ; ) GREEK SMALL LETTER ETA WITH DASIA AND OXIA, COMBINING GREEK YPOGEGRAMMENI +1F91 0301;1F95;03B7 0314 0301 0345;1F95;03B7 0314 0301 0345; # (ᾑ◌́; ᾕ; η◌̔◌́◌ͅ; ᾕ; η◌̔◌́◌ͅ; ) GREEK SMALL LETTER ETA WITH DASIA AND YPOGEGRAMMENI, COMBINING ACUTE ACCENT +1F91 0341;1F95;03B7 0314 0301 0345;1F95;03B7 0314 0301 0345; # (ᾑ◌́; ᾕ; η◌̔◌́◌ͅ; ᾕ; η◌̔◌́◌ͅ; ) GREEK SMALL LETTER ETA WITH DASIA AND YPOGEGRAMMENI, COMBINING ACUTE TONE MARK +1F21 0301 0345;1F95;03B7 0314 0301 0345;1F95;03B7 0314 0301 0345; # (ἡ◌́◌ͅ; ᾕ; η◌̔◌́◌ͅ; ᾕ; η◌̔◌́◌ͅ; ) GREEK SMALL LETTER ETA WITH DASIA, COMBINING ACUTE ACCENT, COMBINING GREEK YPOGEGRAMMENI +1F21 0341 0345;1F95;03B7 0314 0301 0345;1F95;03B7 0314 0301 0345; # (ἡ◌́◌ͅ; ᾕ; η◌̔◌́◌ͅ; ᾕ; η◌̔◌́◌ͅ; ) GREEK SMALL LETTER ETA WITH DASIA, COMBINING ACUTE TONE MARK, COMBINING GREEK YPOGEGRAMMENI +1F21 0345 0301;1F95;03B7 0314 0301 0345;1F95;03B7 0314 0301 0345; # (ἡ◌ͅ◌́; ᾕ; η◌̔◌́◌ͅ; ᾕ; η◌̔◌́◌ͅ; ) GREEK SMALL LETTER ETA WITH DASIA, COMBINING GREEK YPOGEGRAMMENI, COMBINING ACUTE ACCENT +1F21 0345 0341;1F95;03B7 0314 0301 0345;1F95;03B7 0314 0301 0345; # (ἡ◌ͅ◌́; ᾕ; η◌̔◌́◌ͅ; ᾕ; η◌̔◌́◌ͅ; ) GREEK SMALL LETTER ETA WITH DASIA, COMBINING GREEK YPOGEGRAMMENI, COMBINING ACUTE TONE MARK +1FC3 0314 0301;1F95;03B7 0314 0301 0345;1F95;03B7 0314 0301 0345; # (ῃ◌̔◌́; ᾕ; η◌̔◌́◌ͅ; ᾕ; η◌̔◌́◌ͅ; ) GREEK SMALL LETTER ETA WITH YPOGEGRAMMENI, COMBINING REVERSED COMMA ABOVE, COMBINING ACUTE ACCENT +1FC3 0314 0341;1F95;03B7 0314 0301 0345;1F95;03B7 0314 0301 0345; # (ῃ◌̔◌́; ᾕ; η◌̔◌́◌ͅ; ᾕ; η◌̔◌́◌ͅ; ) GREEK SMALL LETTER ETA WITH YPOGEGRAMMENI, COMBINING REVERSED COMMA ABOVE, COMBINING ACUTE TONE MARK +1F26 0345;1F96;03B7 0313 0342 0345;1F96;03B7 0313 0342 0345; # (ἦ◌ͅ; ᾖ; η◌̓◌͂◌ͅ; ᾖ; η◌̓◌͂◌ͅ; ) GREEK SMALL LETTER ETA WITH PSILI AND PERISPOMENI, COMBINING GREEK YPOGEGRAMMENI +1F90 0342;1F96;03B7 0313 0342 0345;1F96;03B7 0313 0342 0345; # (ᾐ◌͂; ᾖ; η◌̓◌͂◌ͅ; ᾖ; η◌̓◌͂◌ͅ; ) GREEK SMALL LETTER ETA WITH PSILI AND YPOGEGRAMMENI, COMBINING GREEK PERISPOMENI +1F20 0342 0345;1F96;03B7 0313 0342 0345;1F96;03B7 0313 0342 0345; # (ἠ◌͂◌ͅ; ᾖ; η◌̓◌͂◌ͅ; ᾖ; η◌̓◌͂◌ͅ; ) GREEK SMALL LETTER ETA WITH PSILI, COMBINING GREEK PERISPOMENI, COMBINING GREEK YPOGEGRAMMENI +1F20 0345 0342;1F96;03B7 0313 0342 0345;1F96;03B7 0313 0342 0345; # (ἠ◌ͅ◌͂; ᾖ; η◌̓◌͂◌ͅ; ᾖ; η◌̓◌͂◌ͅ; ) GREEK SMALL LETTER ETA WITH PSILI, COMBINING GREEK YPOGEGRAMMENI, COMBINING GREEK PERISPOMENI +1FC3 0313 0342;1F96;03B7 0313 0342 0345;1F96;03B7 0313 0342 0345; # (ῃ◌̓◌͂; ᾖ; η◌̓◌͂◌ͅ; ᾖ; η◌̓◌͂◌ͅ; ) GREEK SMALL LETTER ETA WITH YPOGEGRAMMENI, COMBINING COMMA ABOVE, COMBINING GREEK PERISPOMENI +1FC3 0343 0342;1F96;03B7 0313 0342 0345;1F96;03B7 0313 0342 0345; # (ῃ◌̓◌͂; ᾖ; η◌̓◌͂◌ͅ; ᾖ; η◌̓◌͂◌ͅ; ) GREEK SMALL LETTER ETA WITH YPOGEGRAMMENI, COMBINING GREEK KORONIS, COMBINING GREEK PERISPOMENI +1F27 0345;1F97;03B7 0314 0342 0345;1F97;03B7 0314 0342 0345; # (ἧ◌ͅ; ᾗ; η◌̔◌͂◌ͅ; ᾗ; η◌̔◌͂◌ͅ; ) GREEK SMALL LETTER ETA WITH DASIA AND PERISPOMENI, COMBINING GREEK YPOGEGRAMMENI +1F91 0342;1F97;03B7 0314 0342 0345;1F97;03B7 0314 0342 0345; # (ᾑ◌͂; ᾗ; η◌̔◌͂◌ͅ; ᾗ; η◌̔◌͂◌ͅ; ) GREEK SMALL LETTER ETA WITH DASIA AND YPOGEGRAMMENI, COMBINING GREEK PERISPOMENI +1F21 0342 0345;1F97;03B7 0314 0342 0345;1F97;03B7 0314 0342 0345; # (ἡ◌͂◌ͅ; ᾗ; η◌̔◌͂◌ͅ; ᾗ; η◌̔◌͂◌ͅ; ) GREEK SMALL LETTER ETA WITH DASIA, COMBINING GREEK PERISPOMENI, COMBINING GREEK YPOGEGRAMMENI +1F21 0345 0342;1F97;03B7 0314 0342 0345;1F97;03B7 0314 0342 0345; # (ἡ◌ͅ◌͂; ᾗ; η◌̔◌͂◌ͅ; ᾗ; η◌̔◌͂◌ͅ; ) GREEK SMALL LETTER ETA WITH DASIA, COMBINING GREEK YPOGEGRAMMENI, COMBINING GREEK PERISPOMENI +1FC3 0314 0342;1F97;03B7 0314 0342 0345;1F97;03B7 0314 0342 0345; # (ῃ◌̔◌͂; ᾗ; η◌̔◌͂◌ͅ; ᾗ; η◌̔◌͂◌ͅ; ) GREEK SMALL LETTER ETA WITH YPOGEGRAMMENI, COMBINING REVERSED COMMA ABOVE, COMBINING GREEK PERISPOMENI +1F28 0345;1F98;0397 0313 0345;1F98;0397 0313 0345; # (Ἠ◌ͅ; ᾘ; Η◌̓◌ͅ; ᾘ; Η◌̓◌ͅ; ) GREEK CAPITAL LETTER ETA WITH PSILI, COMBINING GREEK YPOGEGRAMMENI +1FCC 0313;1F98;0397 0313 0345;1F98;0397 0313 0345; # (ῌ◌̓; ᾘ; Η◌̓◌ͅ; ᾘ; Η◌̓◌ͅ; ) GREEK CAPITAL LETTER ETA WITH PROSGEGRAMMENI, COMBINING COMMA ABOVE +1FCC 0343;1F98;0397 0313 0345;1F98;0397 0313 0345; # (ῌ◌̓; ᾘ; Η◌̓◌ͅ; ᾘ; Η◌̓◌ͅ; ) GREEK CAPITAL LETTER ETA WITH PROSGEGRAMMENI, COMBINING GREEK KORONIS +1F29 0345;1F99;0397 0314 0345;1F99;0397 0314 0345; # (Ἡ◌ͅ; ᾙ; Η◌̔◌ͅ; ᾙ; Η◌̔◌ͅ; ) GREEK CAPITAL LETTER ETA WITH DASIA, COMBINING GREEK YPOGEGRAMMENI +1FCC 0314;1F99;0397 0314 0345;1F99;0397 0314 0345; # (ῌ◌̔; ᾙ; Η◌̔◌ͅ; ᾙ; Η◌̔◌ͅ; ) GREEK CAPITAL LETTER ETA WITH PROSGEGRAMMENI, COMBINING REVERSED COMMA ABOVE +1F2A 0345;1F9A;0397 0313 0300 0345;1F9A;0397 0313 0300 0345; # (Ἢ◌ͅ; ᾚ; Η◌̓◌̀◌ͅ; ᾚ; Η◌̓◌̀◌ͅ; ) GREEK CAPITAL LETTER ETA WITH PSILI AND VARIA, COMBINING GREEK YPOGEGRAMMENI +1F98 0300;1F9A;0397 0313 0300 0345;1F9A;0397 0313 0300 0345; # (ᾘ◌̀; ᾚ; Η◌̓◌̀◌ͅ; ᾚ; Η◌̓◌̀◌ͅ; ) GREEK CAPITAL LETTER ETA WITH PSILI AND PROSGEGRAMMENI, COMBINING GRAVE ACCENT +1F98 0340;1F9A;0397 0313 0300 0345;1F9A;0397 0313 0300 0345; # (ᾘ◌̀; ᾚ; Η◌̓◌̀◌ͅ; ᾚ; Η◌̓◌̀◌ͅ; ) GREEK CAPITAL LETTER ETA WITH PSILI AND PROSGEGRAMMENI, COMBINING GRAVE TONE MARK +1F28 0300 0345;1F9A;0397 0313 0300 0345;1F9A;0397 0313 0300 0345; # (Ἠ◌̀◌ͅ; ᾚ; Η◌̓◌̀◌ͅ; ᾚ; Η◌̓◌̀◌ͅ; ) GREEK CAPITAL LETTER ETA WITH PSILI, COMBINING GRAVE ACCENT, COMBINING GREEK YPOGEGRAMMENI +1F28 0340 0345;1F9A;0397 0313 0300 0345;1F9A;0397 0313 0300 0345; # (Ἠ◌̀◌ͅ; ᾚ; Η◌̓◌̀◌ͅ; ᾚ; Η◌̓◌̀◌ͅ; ) GREEK CAPITAL LETTER ETA WITH PSILI, COMBINING GRAVE TONE MARK, COMBINING GREEK YPOGEGRAMMENI +1F28 0345 0300;1F9A;0397 0313 0300 0345;1F9A;0397 0313 0300 0345; # (Ἠ◌ͅ◌̀; ᾚ; Η◌̓◌̀◌ͅ; ᾚ; Η◌̓◌̀◌ͅ; ) GREEK CAPITAL LETTER ETA WITH PSILI, COMBINING GREEK YPOGEGRAMMENI, COMBINING GRAVE ACCENT +1F28 0345 0340;1F9A;0397 0313 0300 0345;1F9A;0397 0313 0300 0345; # (Ἠ◌ͅ◌̀; ᾚ; Η◌̓◌̀◌ͅ; ᾚ; Η◌̓◌̀◌ͅ; ) GREEK CAPITAL LETTER ETA WITH PSILI, COMBINING GREEK YPOGEGRAMMENI, COMBINING GRAVE TONE MARK +1FCC 0313 0300;1F9A;0397 0313 0300 0345;1F9A;0397 0313 0300 0345; # (ῌ◌̓◌̀; ᾚ; Η◌̓◌̀◌ͅ; ᾚ; Η◌̓◌̀◌ͅ; ) GREEK CAPITAL LETTER ETA WITH PROSGEGRAMMENI, COMBINING COMMA ABOVE, COMBINING GRAVE ACCENT +1FCC 0313 0340;1F9A;0397 0313 0300 0345;1F9A;0397 0313 0300 0345; # (ῌ◌̓◌̀; ᾚ; Η◌̓◌̀◌ͅ; ᾚ; Η◌̓◌̀◌ͅ; ) GREEK CAPITAL LETTER ETA WITH PROSGEGRAMMENI, COMBINING COMMA ABOVE, COMBINING GRAVE TONE MARK +1FCC 0343 0300;1F9A;0397 0313 0300 0345;1F9A;0397 0313 0300 0345; # (ῌ◌̓◌̀; ᾚ; Η◌̓◌̀◌ͅ; ᾚ; Η◌̓◌̀◌ͅ; ) GREEK CAPITAL LETTER ETA WITH PROSGEGRAMMENI, COMBINING GREEK KORONIS, COMBINING GRAVE ACCENT +1FCC 0343 0340;1F9A;0397 0313 0300 0345;1F9A;0397 0313 0300 0345; # (ῌ◌̓◌̀; ᾚ; Η◌̓◌̀◌ͅ; ᾚ; Η◌̓◌̀◌ͅ; ) GREEK CAPITAL LETTER ETA WITH PROSGEGRAMMENI, COMBINING GREEK KORONIS, COMBINING GRAVE TONE MARK +1F2B 0345;1F9B;0397 0314 0300 0345;1F9B;0397 0314 0300 0345; # (Ἣ◌ͅ; ᾛ; Η◌̔◌̀◌ͅ; ᾛ; Η◌̔◌̀◌ͅ; ) GREEK CAPITAL LETTER ETA WITH DASIA AND VARIA, COMBINING GREEK YPOGEGRAMMENI +1F99 0300;1F9B;0397 0314 0300 0345;1F9B;0397 0314 0300 0345; # (ᾙ◌̀; ᾛ; Η◌̔◌̀◌ͅ; ᾛ; Η◌̔◌̀◌ͅ; ) GREEK CAPITAL LETTER ETA WITH DASIA AND PROSGEGRAMMENI, COMBINING GRAVE ACCENT +1F99 0340;1F9B;0397 0314 0300 0345;1F9B;0397 0314 0300 0345; # (ᾙ◌̀; ᾛ; Η◌̔◌̀◌ͅ; ᾛ; Η◌̔◌̀◌ͅ; ) GREEK CAPITAL LETTER ETA WITH DASIA AND PROSGEGRAMMENI, COMBINING GRAVE TONE MARK +1F29 0300 0345;1F9B;0397 0314 0300 0345;1F9B;0397 0314 0300 0345; # (Ἡ◌̀◌ͅ; ᾛ; Η◌̔◌̀◌ͅ; ᾛ; Η◌̔◌̀◌ͅ; ) GREEK CAPITAL LETTER ETA WITH DASIA, COMBINING GRAVE ACCENT, COMBINING GREEK YPOGEGRAMMENI +1F29 0340 0345;1F9B;0397 0314 0300 0345;1F9B;0397 0314 0300 0345; # (Ἡ◌̀◌ͅ; ᾛ; Η◌̔◌̀◌ͅ; ᾛ; Η◌̔◌̀◌ͅ; ) GREEK CAPITAL LETTER ETA WITH DASIA, COMBINING GRAVE TONE MARK, COMBINING GREEK YPOGEGRAMMENI +1F29 0345 0300;1F9B;0397 0314 0300 0345;1F9B;0397 0314 0300 0345; # (Ἡ◌ͅ◌̀; ᾛ; Η◌̔◌̀◌ͅ; ᾛ; Η◌̔◌̀◌ͅ; ) GREEK CAPITAL LETTER ETA WITH DASIA, COMBINING GREEK YPOGEGRAMMENI, COMBINING GRAVE ACCENT +1F29 0345 0340;1F9B;0397 0314 0300 0345;1F9B;0397 0314 0300 0345; # (Ἡ◌ͅ◌̀; ᾛ; Η◌̔◌̀◌ͅ; ᾛ; Η◌̔◌̀◌ͅ; ) GREEK CAPITAL LETTER ETA WITH DASIA, COMBINING GREEK YPOGEGRAMMENI, COMBINING GRAVE TONE MARK +1FCC 0314 0300;1F9B;0397 0314 0300 0345;1F9B;0397 0314 0300 0345; # (ῌ◌̔◌̀; ᾛ; Η◌̔◌̀◌ͅ; ᾛ; Η◌̔◌̀◌ͅ; ) GREEK CAPITAL LETTER ETA WITH PROSGEGRAMMENI, COMBINING REVERSED COMMA ABOVE, COMBINING GRAVE ACCENT +1FCC 0314 0340;1F9B;0397 0314 0300 0345;1F9B;0397 0314 0300 0345; # (ῌ◌̔◌̀; ᾛ; Η◌̔◌̀◌ͅ; ᾛ; Η◌̔◌̀◌ͅ; ) GREEK CAPITAL LETTER ETA WITH PROSGEGRAMMENI, COMBINING REVERSED COMMA ABOVE, COMBINING GRAVE TONE MARK +1F2C 0345;1F9C;0397 0313 0301 0345;1F9C;0397 0313 0301 0345; # (Ἤ◌ͅ; ᾜ; Η◌̓◌́◌ͅ; ᾜ; Η◌̓◌́◌ͅ; ) GREEK CAPITAL LETTER ETA WITH PSILI AND OXIA, COMBINING GREEK YPOGEGRAMMENI +1F98 0301;1F9C;0397 0313 0301 0345;1F9C;0397 0313 0301 0345; # (ᾘ◌́; ᾜ; Η◌̓◌́◌ͅ; ᾜ; Η◌̓◌́◌ͅ; ) GREEK CAPITAL LETTER ETA WITH PSILI AND PROSGEGRAMMENI, COMBINING ACUTE ACCENT +1F98 0341;1F9C;0397 0313 0301 0345;1F9C;0397 0313 0301 0345; # (ᾘ◌́; ᾜ; Η◌̓◌́◌ͅ; ᾜ; Η◌̓◌́◌ͅ; ) GREEK CAPITAL LETTER ETA WITH PSILI AND PROSGEGRAMMENI, COMBINING ACUTE TONE MARK +1F28 0301 0345;1F9C;0397 0313 0301 0345;1F9C;0397 0313 0301 0345; # (Ἠ◌́◌ͅ; ᾜ; Η◌̓◌́◌ͅ; ᾜ; Η◌̓◌́◌ͅ; ) GREEK CAPITAL LETTER ETA WITH PSILI, COMBINING ACUTE ACCENT, COMBINING GREEK YPOGEGRAMMENI +1F28 0341 0345;1F9C;0397 0313 0301 0345;1F9C;0397 0313 0301 0345; # (Ἠ◌́◌ͅ; ᾜ; Η◌̓◌́◌ͅ; ᾜ; Η◌̓◌́◌ͅ; ) GREEK CAPITAL LETTER ETA WITH PSILI, COMBINING ACUTE TONE MARK, COMBINING GREEK YPOGEGRAMMENI +1F28 0345 0301;1F9C;0397 0313 0301 0345;1F9C;0397 0313 0301 0345; # (Ἠ◌ͅ◌́; ᾜ; Η◌̓◌́◌ͅ; ᾜ; Η◌̓◌́◌ͅ; ) GREEK CAPITAL LETTER ETA WITH PSILI, COMBINING GREEK YPOGEGRAMMENI, COMBINING ACUTE ACCENT +1F28 0345 0341;1F9C;0397 0313 0301 0345;1F9C;0397 0313 0301 0345; # (Ἠ◌ͅ◌́; ᾜ; Η◌̓◌́◌ͅ; ᾜ; Η◌̓◌́◌ͅ; ) GREEK CAPITAL LETTER ETA WITH PSILI, COMBINING GREEK YPOGEGRAMMENI, COMBINING ACUTE TONE MARK +1FCC 0313 0301;1F9C;0397 0313 0301 0345;1F9C;0397 0313 0301 0345; # (ῌ◌̓◌́; ᾜ; Η◌̓◌́◌ͅ; ᾜ; Η◌̓◌́◌ͅ; ) GREEK CAPITAL LETTER ETA WITH PROSGEGRAMMENI, COMBINING COMMA ABOVE, COMBINING ACUTE ACCENT +1FCC 0313 0341;1F9C;0397 0313 0301 0345;1F9C;0397 0313 0301 0345; # (ῌ◌̓◌́; ᾜ; Η◌̓◌́◌ͅ; ᾜ; Η◌̓◌́◌ͅ; ) GREEK CAPITAL LETTER ETA WITH PROSGEGRAMMENI, COMBINING COMMA ABOVE, COMBINING ACUTE TONE MARK +1FCC 0343 0301;1F9C;0397 0313 0301 0345;1F9C;0397 0313 0301 0345; # (ῌ◌̓◌́; ᾜ; Η◌̓◌́◌ͅ; ᾜ; Η◌̓◌́◌ͅ; ) GREEK CAPITAL LETTER ETA WITH PROSGEGRAMMENI, COMBINING GREEK KORONIS, COMBINING ACUTE ACCENT +1FCC 0343 0341;1F9C;0397 0313 0301 0345;1F9C;0397 0313 0301 0345; # (ῌ◌̓◌́; ᾜ; Η◌̓◌́◌ͅ; ᾜ; Η◌̓◌́◌ͅ; ) GREEK CAPITAL LETTER ETA WITH PROSGEGRAMMENI, COMBINING GREEK KORONIS, COMBINING ACUTE TONE MARK +1F2D 0345;1F9D;0397 0314 0301 0345;1F9D;0397 0314 0301 0345; # (Ἥ◌ͅ; ᾝ; Η◌̔◌́◌ͅ; ᾝ; Η◌̔◌́◌ͅ; ) GREEK CAPITAL LETTER ETA WITH DASIA AND OXIA, COMBINING GREEK YPOGEGRAMMENI +1F99 0301;1F9D;0397 0314 0301 0345;1F9D;0397 0314 0301 0345; # (ᾙ◌́; ᾝ; Η◌̔◌́◌ͅ; ᾝ; Η◌̔◌́◌ͅ; ) GREEK CAPITAL LETTER ETA WITH DASIA AND PROSGEGRAMMENI, COMBINING ACUTE ACCENT +1F99 0341;1F9D;0397 0314 0301 0345;1F9D;0397 0314 0301 0345; # (ᾙ◌́; ᾝ; Η◌̔◌́◌ͅ; ᾝ; Η◌̔◌́◌ͅ; ) GREEK CAPITAL LETTER ETA WITH DASIA AND PROSGEGRAMMENI, COMBINING ACUTE TONE MARK +1F29 0301 0345;1F9D;0397 0314 0301 0345;1F9D;0397 0314 0301 0345; # (Ἡ◌́◌ͅ; ᾝ; Η◌̔◌́◌ͅ; ᾝ; Η◌̔◌́◌ͅ; ) GREEK CAPITAL LETTER ETA WITH DASIA, COMBINING ACUTE ACCENT, COMBINING GREEK YPOGEGRAMMENI +1F29 0341 0345;1F9D;0397 0314 0301 0345;1F9D;0397 0314 0301 0345; # (Ἡ◌́◌ͅ; ᾝ; Η◌̔◌́◌ͅ; ᾝ; Η◌̔◌́◌ͅ; ) GREEK CAPITAL LETTER ETA WITH DASIA, COMBINING ACUTE TONE MARK, COMBINING GREEK YPOGEGRAMMENI +1F29 0345 0301;1F9D;0397 0314 0301 0345;1F9D;0397 0314 0301 0345; # (Ἡ◌ͅ◌́; ᾝ; Η◌̔◌́◌ͅ; ᾝ; Η◌̔◌́◌ͅ; ) GREEK CAPITAL LETTER ETA WITH DASIA, COMBINING GREEK YPOGEGRAMMENI, COMBINING ACUTE ACCENT +1F29 0345 0341;1F9D;0397 0314 0301 0345;1F9D;0397 0314 0301 0345; # (Ἡ◌ͅ◌́; ᾝ; Η◌̔◌́◌ͅ; ᾝ; Η◌̔◌́◌ͅ; ) GREEK CAPITAL LETTER ETA WITH DASIA, COMBINING GREEK YPOGEGRAMMENI, COMBINING ACUTE TONE MARK +1FCC 0314 0301;1F9D;0397 0314 0301 0345;1F9D;0397 0314 0301 0345; # (ῌ◌̔◌́; ᾝ; Η◌̔◌́◌ͅ; ᾝ; Η◌̔◌́◌ͅ; ) GREEK CAPITAL LETTER ETA WITH PROSGEGRAMMENI, COMBINING REVERSED COMMA ABOVE, COMBINING ACUTE ACCENT +1FCC 0314 0341;1F9D;0397 0314 0301 0345;1F9D;0397 0314 0301 0345; # (ῌ◌̔◌́; ᾝ; Η◌̔◌́◌ͅ; ᾝ; Η◌̔◌́◌ͅ; ) GREEK CAPITAL LETTER ETA WITH PROSGEGRAMMENI, COMBINING REVERSED COMMA ABOVE, COMBINING ACUTE TONE MARK +1F2E 0345;1F9E;0397 0313 0342 0345;1F9E;0397 0313 0342 0345; # (Ἦ◌ͅ; ᾞ; Η◌̓◌͂◌ͅ; ᾞ; Η◌̓◌͂◌ͅ; ) GREEK CAPITAL LETTER ETA WITH PSILI AND PERISPOMENI, COMBINING GREEK YPOGEGRAMMENI +1F98 0342;1F9E;0397 0313 0342 0345;1F9E;0397 0313 0342 0345; # (ᾘ◌͂; ᾞ; Η◌̓◌͂◌ͅ; ᾞ; Η◌̓◌͂◌ͅ; ) GREEK CAPITAL LETTER ETA WITH PSILI AND PROSGEGRAMMENI, COMBINING GREEK PERISPOMENI +1F28 0342 0345;1F9E;0397 0313 0342 0345;1F9E;0397 0313 0342 0345; # (Ἠ◌͂◌ͅ; ᾞ; Η◌̓◌͂◌ͅ; ᾞ; Η◌̓◌͂◌ͅ; ) GREEK CAPITAL LETTER ETA WITH PSILI, COMBINING GREEK PERISPOMENI, COMBINING GREEK YPOGEGRAMMENI +1F28 0345 0342;1F9E;0397 0313 0342 0345;1F9E;0397 0313 0342 0345; # (Ἠ◌ͅ◌͂; ᾞ; Η◌̓◌͂◌ͅ; ᾞ; Η◌̓◌͂◌ͅ; ) GREEK CAPITAL LETTER ETA WITH PSILI, COMBINING GREEK YPOGEGRAMMENI, COMBINING GREEK PERISPOMENI +1FCC 0313 0342;1F9E;0397 0313 0342 0345;1F9E;0397 0313 0342 0345; # (ῌ◌̓◌͂; ᾞ; Η◌̓◌͂◌ͅ; ᾞ; Η◌̓◌͂◌ͅ; ) GREEK CAPITAL LETTER ETA WITH PROSGEGRAMMENI, COMBINING COMMA ABOVE, COMBINING GREEK PERISPOMENI +1FCC 0343 0342;1F9E;0397 0313 0342 0345;1F9E;0397 0313 0342 0345; # (ῌ◌̓◌͂; ᾞ; Η◌̓◌͂◌ͅ; ᾞ; Η◌̓◌͂◌ͅ; ) GREEK CAPITAL LETTER ETA WITH PROSGEGRAMMENI, COMBINING GREEK KORONIS, COMBINING GREEK PERISPOMENI +1F2F 0345;1F9F;0397 0314 0342 0345;1F9F;0397 0314 0342 0345; # (Ἧ◌ͅ; ᾟ; Η◌̔◌͂◌ͅ; ᾟ; Η◌̔◌͂◌ͅ; ) GREEK CAPITAL LETTER ETA WITH DASIA AND PERISPOMENI, COMBINING GREEK YPOGEGRAMMENI +1F99 0342;1F9F;0397 0314 0342 0345;1F9F;0397 0314 0342 0345; # (ᾙ◌͂; ᾟ; Η◌̔◌͂◌ͅ; ᾟ; Η◌̔◌͂◌ͅ; ) GREEK CAPITAL LETTER ETA WITH DASIA AND PROSGEGRAMMENI, COMBINING GREEK PERISPOMENI +1F29 0342 0345;1F9F;0397 0314 0342 0345;1F9F;0397 0314 0342 0345; # (Ἡ◌͂◌ͅ; ᾟ; Η◌̔◌͂◌ͅ; ᾟ; Η◌̔◌͂◌ͅ; ) GREEK CAPITAL LETTER ETA WITH DASIA, COMBINING GREEK PERISPOMENI, COMBINING GREEK YPOGEGRAMMENI +1F29 0345 0342;1F9F;0397 0314 0342 0345;1F9F;0397 0314 0342 0345; # (Ἡ◌ͅ◌͂; ᾟ; Η◌̔◌͂◌ͅ; ᾟ; Η◌̔◌͂◌ͅ; ) GREEK CAPITAL LETTER ETA WITH DASIA, COMBINING GREEK YPOGEGRAMMENI, COMBINING GREEK PERISPOMENI +1FCC 0314 0342;1F9F;0397 0314 0342 0345;1F9F;0397 0314 0342 0345; # (ῌ◌̔◌͂; ᾟ; Η◌̔◌͂◌ͅ; ᾟ; Η◌̔◌͂◌ͅ; ) GREEK CAPITAL LETTER ETA WITH PROSGEGRAMMENI, COMBINING REVERSED COMMA ABOVE, COMBINING GREEK PERISPOMENI +1F60 0345;1FA0;03C9 0313 0345;1FA0;03C9 0313 0345; # (ὠ◌ͅ; ᾠ; ω◌̓◌ͅ; ᾠ; ω◌̓◌ͅ; ) GREEK SMALL LETTER OMEGA WITH PSILI, COMBINING GREEK YPOGEGRAMMENI +1FF3 0313;1FA0;03C9 0313 0345;1FA0;03C9 0313 0345; # (ῳ◌̓; ᾠ; ω◌̓◌ͅ; ᾠ; ω◌̓◌ͅ; ) GREEK SMALL LETTER OMEGA WITH YPOGEGRAMMENI, COMBINING COMMA ABOVE +1FF3 0343;1FA0;03C9 0313 0345;1FA0;03C9 0313 0345; # (ῳ◌̓; ᾠ; ω◌̓◌ͅ; ᾠ; ω◌̓◌ͅ; ) GREEK SMALL LETTER OMEGA WITH YPOGEGRAMMENI, COMBINING GREEK KORONIS +1F61 0345;1FA1;03C9 0314 0345;1FA1;03C9 0314 0345; # (ὡ◌ͅ; ᾡ; ω◌̔◌ͅ; ᾡ; ω◌̔◌ͅ; ) GREEK SMALL LETTER OMEGA WITH DASIA, COMBINING GREEK YPOGEGRAMMENI +1FF3 0314;1FA1;03C9 0314 0345;1FA1;03C9 0314 0345; # (ῳ◌̔; ᾡ; ω◌̔◌ͅ; ᾡ; ω◌̔◌ͅ; ) GREEK SMALL LETTER OMEGA WITH YPOGEGRAMMENI, COMBINING REVERSED COMMA ABOVE +1F62 0345;1FA2;03C9 0313 0300 0345;1FA2;03C9 0313 0300 0345; # (ὢ◌ͅ; ᾢ; ω◌̓◌̀◌ͅ; ᾢ; ω◌̓◌̀◌ͅ; ) GREEK SMALL LETTER OMEGA WITH PSILI AND VARIA, COMBINING GREEK YPOGEGRAMMENI +1FA0 0300;1FA2;03C9 0313 0300 0345;1FA2;03C9 0313 0300 0345; # (ᾠ◌̀; ᾢ; ω◌̓◌̀◌ͅ; ᾢ; ω◌̓◌̀◌ͅ; ) GREEK SMALL LETTER OMEGA WITH PSILI AND YPOGEGRAMMENI, COMBINING GRAVE ACCENT +1FA0 0340;1FA2;03C9 0313 0300 0345;1FA2;03C9 0313 0300 0345; # (ᾠ◌̀; ᾢ; ω◌̓◌̀◌ͅ; ᾢ; ω◌̓◌̀◌ͅ; ) GREEK SMALL LETTER OMEGA WITH PSILI AND YPOGEGRAMMENI, COMBINING GRAVE TONE MARK +1F60 0300 0345;1FA2;03C9 0313 0300 0345;1FA2;03C9 0313 0300 0345; # (ὠ◌̀◌ͅ; ᾢ; ω◌̓◌̀◌ͅ; ᾢ; ω◌̓◌̀◌ͅ; ) GREEK SMALL LETTER OMEGA WITH PSILI, COMBINING GRAVE ACCENT, COMBINING GREEK YPOGEGRAMMENI +1F60 0340 0345;1FA2;03C9 0313 0300 0345;1FA2;03C9 0313 0300 0345; # (ὠ◌̀◌ͅ; ᾢ; ω◌̓◌̀◌ͅ; ᾢ; ω◌̓◌̀◌ͅ; ) GREEK SMALL LETTER OMEGA WITH PSILI, COMBINING GRAVE TONE MARK, COMBINING GREEK YPOGEGRAMMENI +1F60 0345 0300;1FA2;03C9 0313 0300 0345;1FA2;03C9 0313 0300 0345; # (ὠ◌ͅ◌̀; ᾢ; ω◌̓◌̀◌ͅ; ᾢ; ω◌̓◌̀◌ͅ; ) GREEK SMALL LETTER OMEGA WITH PSILI, COMBINING GREEK YPOGEGRAMMENI, COMBINING GRAVE ACCENT +1F60 0345 0340;1FA2;03C9 0313 0300 0345;1FA2;03C9 0313 0300 0345; # (ὠ◌ͅ◌̀; ᾢ; ω◌̓◌̀◌ͅ; ᾢ; ω◌̓◌̀◌ͅ; ) GREEK SMALL LETTER OMEGA WITH PSILI, COMBINING GREEK YPOGEGRAMMENI, COMBINING GRAVE TONE MARK +1FF3 0313 0300;1FA2;03C9 0313 0300 0345;1FA2;03C9 0313 0300 0345; # (ῳ◌̓◌̀; ᾢ; ω◌̓◌̀◌ͅ; ᾢ; ω◌̓◌̀◌ͅ; ) GREEK SMALL LETTER OMEGA WITH YPOGEGRAMMENI, COMBINING COMMA ABOVE, COMBINING GRAVE ACCENT +1FF3 0313 0340;1FA2;03C9 0313 0300 0345;1FA2;03C9 0313 0300 0345; # (ῳ◌̓◌̀; ᾢ; ω◌̓◌̀◌ͅ; ᾢ; ω◌̓◌̀◌ͅ; ) GREEK SMALL LETTER OMEGA WITH YPOGEGRAMMENI, COMBINING COMMA ABOVE, COMBINING GRAVE TONE MARK +1FF3 0343 0300;1FA2;03C9 0313 0300 0345;1FA2;03C9 0313 0300 0345; # (ῳ◌̓◌̀; ᾢ; ω◌̓◌̀◌ͅ; ᾢ; ω◌̓◌̀◌ͅ; ) GREEK SMALL LETTER OMEGA WITH YPOGEGRAMMENI, COMBINING GREEK KORONIS, COMBINING GRAVE ACCENT +1FF3 0343 0340;1FA2;03C9 0313 0300 0345;1FA2;03C9 0313 0300 0345; # (ῳ◌̓◌̀; ᾢ; ω◌̓◌̀◌ͅ; ᾢ; ω◌̓◌̀◌ͅ; ) GREEK SMALL LETTER OMEGA WITH YPOGEGRAMMENI, COMBINING GREEK KORONIS, COMBINING GRAVE TONE MARK +1F63 0345;1FA3;03C9 0314 0300 0345;1FA3;03C9 0314 0300 0345; # (ὣ◌ͅ; ᾣ; ω◌̔◌̀◌ͅ; ᾣ; ω◌̔◌̀◌ͅ; ) GREEK SMALL LETTER OMEGA WITH DASIA AND VARIA, COMBINING GREEK YPOGEGRAMMENI +1FA1 0300;1FA3;03C9 0314 0300 0345;1FA3;03C9 0314 0300 0345; # (ᾡ◌̀; ᾣ; ω◌̔◌̀◌ͅ; ᾣ; ω◌̔◌̀◌ͅ; ) GREEK SMALL LETTER OMEGA WITH DASIA AND YPOGEGRAMMENI, COMBINING GRAVE ACCENT +1FA1 0340;1FA3;03C9 0314 0300 0345;1FA3;03C9 0314 0300 0345; # (ᾡ◌̀; ᾣ; ω◌̔◌̀◌ͅ; ᾣ; ω◌̔◌̀◌ͅ; ) GREEK SMALL LETTER OMEGA WITH DASIA AND YPOGEGRAMMENI, COMBINING GRAVE TONE MARK +1F61 0300 0345;1FA3;03C9 0314 0300 0345;1FA3;03C9 0314 0300 0345; # (ὡ◌̀◌ͅ; ᾣ; ω◌̔◌̀◌ͅ; ᾣ; ω◌̔◌̀◌ͅ; ) GREEK SMALL LETTER OMEGA WITH DASIA, COMBINING GRAVE ACCENT, COMBINING GREEK YPOGEGRAMMENI +1F61 0340 0345;1FA3;03C9 0314 0300 0345;1FA3;03C9 0314 0300 0345; # (ὡ◌̀◌ͅ; ᾣ; ω◌̔◌̀◌ͅ; ᾣ; ω◌̔◌̀◌ͅ; ) GREEK SMALL LETTER OMEGA WITH DASIA, COMBINING GRAVE TONE MARK, COMBINING GREEK YPOGEGRAMMENI +1F61 0345 0300;1FA3;03C9 0314 0300 0345;1FA3;03C9 0314 0300 0345; # (ὡ◌ͅ◌̀; ᾣ; ω◌̔◌̀◌ͅ; ᾣ; ω◌̔◌̀◌ͅ; ) GREEK SMALL LETTER OMEGA WITH DASIA, COMBINING GREEK YPOGEGRAMMENI, COMBINING GRAVE ACCENT +1F61 0345 0340;1FA3;03C9 0314 0300 0345;1FA3;03C9 0314 0300 0345; # (ὡ◌ͅ◌̀; ᾣ; ω◌̔◌̀◌ͅ; ᾣ; ω◌̔◌̀◌ͅ; ) GREEK SMALL LETTER OMEGA WITH DASIA, COMBINING GREEK YPOGEGRAMMENI, COMBINING GRAVE TONE MARK +1FF3 0314 0300;1FA3;03C9 0314 0300 0345;1FA3;03C9 0314 0300 0345; # (ῳ◌̔◌̀; ᾣ; ω◌̔◌̀◌ͅ; ᾣ; ω◌̔◌̀◌ͅ; ) GREEK SMALL LETTER OMEGA WITH YPOGEGRAMMENI, COMBINING REVERSED COMMA ABOVE, COMBINING GRAVE ACCENT +1FF3 0314 0340;1FA3;03C9 0314 0300 0345;1FA3;03C9 0314 0300 0345; # (ῳ◌̔◌̀; ᾣ; ω◌̔◌̀◌ͅ; ᾣ; ω◌̔◌̀◌ͅ; ) GREEK SMALL LETTER OMEGA WITH YPOGEGRAMMENI, COMBINING REVERSED COMMA ABOVE, COMBINING GRAVE TONE MARK +1F64 0345;1FA4;03C9 0313 0301 0345;1FA4;03C9 0313 0301 0345; # (ὤ◌ͅ; ᾤ; ω◌̓◌́◌ͅ; ᾤ; ω◌̓◌́◌ͅ; ) GREEK SMALL LETTER OMEGA WITH PSILI AND OXIA, COMBINING GREEK YPOGEGRAMMENI +1FA0 0301;1FA4;03C9 0313 0301 0345;1FA4;03C9 0313 0301 0345; # (ᾠ◌́; ᾤ; ω◌̓◌́◌ͅ; ᾤ; ω◌̓◌́◌ͅ; ) GREEK SMALL LETTER OMEGA WITH PSILI AND YPOGEGRAMMENI, COMBINING ACUTE ACCENT +1FA0 0341;1FA4;03C9 0313 0301 0345;1FA4;03C9 0313 0301 0345; # (ᾠ◌́; ᾤ; ω◌̓◌́◌ͅ; ᾤ; ω◌̓◌́◌ͅ; ) GREEK SMALL LETTER OMEGA WITH PSILI AND YPOGEGRAMMENI, COMBINING ACUTE TONE MARK +1F60 0301 0345;1FA4;03C9 0313 0301 0345;1FA4;03C9 0313 0301 0345; # (ὠ◌́◌ͅ; ᾤ; ω◌̓◌́◌ͅ; ᾤ; ω◌̓◌́◌ͅ; ) GREEK SMALL LETTER OMEGA WITH PSILI, COMBINING ACUTE ACCENT, COMBINING GREEK YPOGEGRAMMENI +1F60 0341 0345;1FA4;03C9 0313 0301 0345;1FA4;03C9 0313 0301 0345; # (ὠ◌́◌ͅ; ᾤ; ω◌̓◌́◌ͅ; ᾤ; ω◌̓◌́◌ͅ; ) GREEK SMALL LETTER OMEGA WITH PSILI, COMBINING ACUTE TONE MARK, COMBINING GREEK YPOGEGRAMMENI +1F60 0345 0301;1FA4;03C9 0313 0301 0345;1FA4;03C9 0313 0301 0345; # (ὠ◌ͅ◌́; ᾤ; ω◌̓◌́◌ͅ; ᾤ; ω◌̓◌́◌ͅ; ) GREEK SMALL LETTER OMEGA WITH PSILI, COMBINING GREEK YPOGEGRAMMENI, COMBINING ACUTE ACCENT +1F60 0345 0341;1FA4;03C9 0313 0301 0345;1FA4;03C9 0313 0301 0345; # (ὠ◌ͅ◌́; ᾤ; ω◌̓◌́◌ͅ; ᾤ; ω◌̓◌́◌ͅ; ) GREEK SMALL LETTER OMEGA WITH PSILI, COMBINING GREEK YPOGEGRAMMENI, COMBINING ACUTE TONE MARK +1FF3 0313 0301;1FA4;03C9 0313 0301 0345;1FA4;03C9 0313 0301 0345; # (ῳ◌̓◌́; ᾤ; ω◌̓◌́◌ͅ; ᾤ; ω◌̓◌́◌ͅ; ) GREEK SMALL LETTER OMEGA WITH YPOGEGRAMMENI, COMBINING COMMA ABOVE, COMBINING ACUTE ACCENT +1FF3 0313 0341;1FA4;03C9 0313 0301 0345;1FA4;03C9 0313 0301 0345; # (ῳ◌̓◌́; ᾤ; ω◌̓◌́◌ͅ; ᾤ; ω◌̓◌́◌ͅ; ) GREEK SMALL LETTER OMEGA WITH YPOGEGRAMMENI, COMBINING COMMA ABOVE, COMBINING ACUTE TONE MARK +1FF3 0343 0301;1FA4;03C9 0313 0301 0345;1FA4;03C9 0313 0301 0345; # (ῳ◌̓◌́; ᾤ; ω◌̓◌́◌ͅ; ᾤ; ω◌̓◌́◌ͅ; ) GREEK SMALL LETTER OMEGA WITH YPOGEGRAMMENI, COMBINING GREEK KORONIS, COMBINING ACUTE ACCENT +1FF3 0343 0341;1FA4;03C9 0313 0301 0345;1FA4;03C9 0313 0301 0345; # (ῳ◌̓◌́; ᾤ; ω◌̓◌́◌ͅ; ᾤ; ω◌̓◌́◌ͅ; ) GREEK SMALL LETTER OMEGA WITH YPOGEGRAMMENI, COMBINING GREEK KORONIS, COMBINING ACUTE TONE MARK +1F65 0345;1FA5;03C9 0314 0301 0345;1FA5;03C9 0314 0301 0345; # (ὥ◌ͅ; ᾥ; ω◌̔◌́◌ͅ; ᾥ; ω◌̔◌́◌ͅ; ) GREEK SMALL LETTER OMEGA WITH DASIA AND OXIA, COMBINING GREEK YPOGEGRAMMENI +1FA1 0301;1FA5;03C9 0314 0301 0345;1FA5;03C9 0314 0301 0345; # (ᾡ◌́; ᾥ; ω◌̔◌́◌ͅ; ᾥ; ω◌̔◌́◌ͅ; ) GREEK SMALL LETTER OMEGA WITH DASIA AND YPOGEGRAMMENI, COMBINING ACUTE ACCENT +1FA1 0341;1FA5;03C9 0314 0301 0345;1FA5;03C9 0314 0301 0345; # (ᾡ◌́; ᾥ; ω◌̔◌́◌ͅ; ᾥ; ω◌̔◌́◌ͅ; ) GREEK SMALL LETTER OMEGA WITH DASIA AND YPOGEGRAMMENI, COMBINING ACUTE TONE MARK +1F61 0301 0345;1FA5;03C9 0314 0301 0345;1FA5;03C9 0314 0301 0345; # (ὡ◌́◌ͅ; ᾥ; ω◌̔◌́◌ͅ; ᾥ; ω◌̔◌́◌ͅ; ) GREEK SMALL LETTER OMEGA WITH DASIA, COMBINING ACUTE ACCENT, COMBINING GREEK YPOGEGRAMMENI +1F61 0341 0345;1FA5;03C9 0314 0301 0345;1FA5;03C9 0314 0301 0345; # (ὡ◌́◌ͅ; ᾥ; ω◌̔◌́◌ͅ; ᾥ; ω◌̔◌́◌ͅ; ) GREEK SMALL LETTER OMEGA WITH DASIA, COMBINING ACUTE TONE MARK, COMBINING GREEK YPOGEGRAMMENI +1F61 0345 0301;1FA5;03C9 0314 0301 0345;1FA5;03C9 0314 0301 0345; # (ὡ◌ͅ◌́; ᾥ; ω◌̔◌́◌ͅ; ᾥ; ω◌̔◌́◌ͅ; ) GREEK SMALL LETTER OMEGA WITH DASIA, COMBINING GREEK YPOGEGRAMMENI, COMBINING ACUTE ACCENT +1F61 0345 0341;1FA5;03C9 0314 0301 0345;1FA5;03C9 0314 0301 0345; # (ὡ◌ͅ◌́; ᾥ; ω◌̔◌́◌ͅ; ᾥ; ω◌̔◌́◌ͅ; ) GREEK SMALL LETTER OMEGA WITH DASIA, COMBINING GREEK YPOGEGRAMMENI, COMBINING ACUTE TONE MARK +1FF3 0314 0301;1FA5;03C9 0314 0301 0345;1FA5;03C9 0314 0301 0345; # (ῳ◌̔◌́; ᾥ; ω◌̔◌́◌ͅ; ᾥ; ω◌̔◌́◌ͅ; ) GREEK SMALL LETTER OMEGA WITH YPOGEGRAMMENI, COMBINING REVERSED COMMA ABOVE, COMBINING ACUTE ACCENT +1FF3 0314 0341;1FA5;03C9 0314 0301 0345;1FA5;03C9 0314 0301 0345; # (ῳ◌̔◌́; ᾥ; ω◌̔◌́◌ͅ; ᾥ; ω◌̔◌́◌ͅ; ) GREEK SMALL LETTER OMEGA WITH YPOGEGRAMMENI, COMBINING REVERSED COMMA ABOVE, COMBINING ACUTE TONE MARK +1F66 0345;1FA6;03C9 0313 0342 0345;1FA6;03C9 0313 0342 0345; # (ὦ◌ͅ; ᾦ; ω◌̓◌͂◌ͅ; ᾦ; ω◌̓◌͂◌ͅ; ) GREEK SMALL LETTER OMEGA WITH PSILI AND PERISPOMENI, COMBINING GREEK YPOGEGRAMMENI +1FA0 0342;1FA6;03C9 0313 0342 0345;1FA6;03C9 0313 0342 0345; # (ᾠ◌͂; ᾦ; ω◌̓◌͂◌ͅ; ᾦ; ω◌̓◌͂◌ͅ; ) GREEK SMALL LETTER OMEGA WITH PSILI AND YPOGEGRAMMENI, COMBINING GREEK PERISPOMENI +1F60 0342 0345;1FA6;03C9 0313 0342 0345;1FA6;03C9 0313 0342 0345; # (ὠ◌͂◌ͅ; ᾦ; ω◌̓◌͂◌ͅ; ᾦ; ω◌̓◌͂◌ͅ; ) GREEK SMALL LETTER OMEGA WITH PSILI, COMBINING GREEK PERISPOMENI, COMBINING GREEK YPOGEGRAMMENI +1F60 0345 0342;1FA6;03C9 0313 0342 0345;1FA6;03C9 0313 0342 0345; # (ὠ◌ͅ◌͂; ᾦ; ω◌̓◌͂◌ͅ; ᾦ; ω◌̓◌͂◌ͅ; ) GREEK SMALL LETTER OMEGA WITH PSILI, COMBINING GREEK YPOGEGRAMMENI, COMBINING GREEK PERISPOMENI +1FF3 0313 0342;1FA6;03C9 0313 0342 0345;1FA6;03C9 0313 0342 0345; # (ῳ◌̓◌͂; ᾦ; ω◌̓◌͂◌ͅ; ᾦ; ω◌̓◌͂◌ͅ; ) GREEK SMALL LETTER OMEGA WITH YPOGEGRAMMENI, COMBINING COMMA ABOVE, COMBINING GREEK PERISPOMENI +1FF3 0343 0342;1FA6;03C9 0313 0342 0345;1FA6;03C9 0313 0342 0345; # (ῳ◌̓◌͂; ᾦ; ω◌̓◌͂◌ͅ; ᾦ; ω◌̓◌͂◌ͅ; ) GREEK SMALL LETTER OMEGA WITH YPOGEGRAMMENI, COMBINING GREEK KORONIS, COMBINING GREEK PERISPOMENI +1F67 0345;1FA7;03C9 0314 0342 0345;1FA7;03C9 0314 0342 0345; # (ὧ◌ͅ; ᾧ; ω◌̔◌͂◌ͅ; ᾧ; ω◌̔◌͂◌ͅ; ) GREEK SMALL LETTER OMEGA WITH DASIA AND PERISPOMENI, COMBINING GREEK YPOGEGRAMMENI +1FA1 0342;1FA7;03C9 0314 0342 0345;1FA7;03C9 0314 0342 0345; # (ᾡ◌͂; ᾧ; ω◌̔◌͂◌ͅ; ᾧ; ω◌̔◌͂◌ͅ; ) GREEK SMALL LETTER OMEGA WITH DASIA AND YPOGEGRAMMENI, COMBINING GREEK PERISPOMENI +1F61 0342 0345;1FA7;03C9 0314 0342 0345;1FA7;03C9 0314 0342 0345; # (ὡ◌͂◌ͅ; ᾧ; ω◌̔◌͂◌ͅ; ᾧ; ω◌̔◌͂◌ͅ; ) GREEK SMALL LETTER OMEGA WITH DASIA, COMBINING GREEK PERISPOMENI, COMBINING GREEK YPOGEGRAMMENI +1F61 0345 0342;1FA7;03C9 0314 0342 0345;1FA7;03C9 0314 0342 0345; # (ὡ◌ͅ◌͂; ᾧ; ω◌̔◌͂◌ͅ; ᾧ; ω◌̔◌͂◌ͅ; ) GREEK SMALL LETTER OMEGA WITH DASIA, COMBINING GREEK YPOGEGRAMMENI, COMBINING GREEK PERISPOMENI +1FF3 0314 0342;1FA7;03C9 0314 0342 0345;1FA7;03C9 0314 0342 0345; # (ῳ◌̔◌͂; ᾧ; ω◌̔◌͂◌ͅ; ᾧ; ω◌̔◌͂◌ͅ; ) GREEK SMALL LETTER OMEGA WITH YPOGEGRAMMENI, COMBINING REVERSED COMMA ABOVE, COMBINING GREEK PERISPOMENI +1F68 0345;1FA8;03A9 0313 0345;1FA8;03A9 0313 0345; # (Ὠ◌ͅ; ᾨ; Ω◌̓◌ͅ; ᾨ; Ω◌̓◌ͅ; ) GREEK CAPITAL LETTER OMEGA WITH PSILI, COMBINING GREEK YPOGEGRAMMENI +1FFC 0313;1FA8;03A9 0313 0345;1FA8;03A9 0313 0345; # (ῼ◌̓; ᾨ; Ω◌̓◌ͅ; ᾨ; Ω◌̓◌ͅ; ) GREEK CAPITAL LETTER OMEGA WITH PROSGEGRAMMENI, COMBINING COMMA ABOVE +1FFC 0343;1FA8;03A9 0313 0345;1FA8;03A9 0313 0345; # (ῼ◌̓; ᾨ; Ω◌̓◌ͅ; ᾨ; Ω◌̓◌ͅ; ) GREEK CAPITAL LETTER OMEGA WITH PROSGEGRAMMENI, COMBINING GREEK KORONIS +1F69 0345;1FA9;03A9 0314 0345;1FA9;03A9 0314 0345; # (Ὡ◌ͅ; ᾩ; Ω◌̔◌ͅ; ᾩ; Ω◌̔◌ͅ; ) GREEK CAPITAL LETTER OMEGA WITH DASIA, COMBINING GREEK YPOGEGRAMMENI +1FFC 0314;1FA9;03A9 0314 0345;1FA9;03A9 0314 0345; # (ῼ◌̔; ᾩ; Ω◌̔◌ͅ; ᾩ; Ω◌̔◌ͅ; ) GREEK CAPITAL LETTER OMEGA WITH PROSGEGRAMMENI, COMBINING REVERSED COMMA ABOVE +1F6A 0345;1FAA;03A9 0313 0300 0345;1FAA;03A9 0313 0300 0345; # (Ὢ◌ͅ; ᾪ; Ω◌̓◌̀◌ͅ; ᾪ; Ω◌̓◌̀◌ͅ; ) GREEK CAPITAL LETTER OMEGA WITH PSILI AND VARIA, COMBINING GREEK YPOGEGRAMMENI +1FA8 0300;1FAA;03A9 0313 0300 0345;1FAA;03A9 0313 0300 0345; # (ᾨ◌̀; ᾪ; Ω◌̓◌̀◌ͅ; ᾪ; Ω◌̓◌̀◌ͅ; ) GREEK CAPITAL LETTER OMEGA WITH PSILI AND PROSGEGRAMMENI, COMBINING GRAVE ACCENT +1FA8 0340;1FAA;03A9 0313 0300 0345;1FAA;03A9 0313 0300 0345; # (ᾨ◌̀; ᾪ; Ω◌̓◌̀◌ͅ; ᾪ; Ω◌̓◌̀◌ͅ; ) GREEK CAPITAL LETTER OMEGA WITH PSILI AND PROSGEGRAMMENI, COMBINING GRAVE TONE MARK +1F68 0300 0345;1FAA;03A9 0313 0300 0345;1FAA;03A9 0313 0300 0345; # (Ὠ◌̀◌ͅ; ᾪ; Ω◌̓◌̀◌ͅ; ᾪ; Ω◌̓◌̀◌ͅ; ) GREEK CAPITAL LETTER OMEGA WITH PSILI, COMBINING GRAVE ACCENT, COMBINING GREEK YPOGEGRAMMENI +1F68 0340 0345;1FAA;03A9 0313 0300 0345;1FAA;03A9 0313 0300 0345; # (Ὠ◌̀◌ͅ; ᾪ; Ω◌̓◌̀◌ͅ; ᾪ; Ω◌̓◌̀◌ͅ; ) GREEK CAPITAL LETTER OMEGA WITH PSILI, COMBINING GRAVE TONE MARK, COMBINING GREEK YPOGEGRAMMENI +1F68 0345 0300;1FAA;03A9 0313 0300 0345;1FAA;03A9 0313 0300 0345; # (Ὠ◌ͅ◌̀; ᾪ; Ω◌̓◌̀◌ͅ; ᾪ; Ω◌̓◌̀◌ͅ; ) GREEK CAPITAL LETTER OMEGA WITH PSILI, COMBINING GREEK YPOGEGRAMMENI, COMBINING GRAVE ACCENT +1F68 0345 0340;1FAA;03A9 0313 0300 0345;1FAA;03A9 0313 0300 0345; # (Ὠ◌ͅ◌̀; ᾪ; Ω◌̓◌̀◌ͅ; ᾪ; Ω◌̓◌̀◌ͅ; ) GREEK CAPITAL LETTER OMEGA WITH PSILI, COMBINING GREEK YPOGEGRAMMENI, COMBINING GRAVE TONE MARK +1FFC 0313 0300;1FAA;03A9 0313 0300 0345;1FAA;03A9 0313 0300 0345; # (ῼ◌̓◌̀; ᾪ; Ω◌̓◌̀◌ͅ; ᾪ; Ω◌̓◌̀◌ͅ; ) GREEK CAPITAL LETTER OMEGA WITH PROSGEGRAMMENI, COMBINING COMMA ABOVE, COMBINING GRAVE ACCENT +1FFC 0313 0340;1FAA;03A9 0313 0300 0345;1FAA;03A9 0313 0300 0345; # (ῼ◌̓◌̀; ᾪ; Ω◌̓◌̀◌ͅ; ᾪ; Ω◌̓◌̀◌ͅ; ) GREEK CAPITAL LETTER OMEGA WITH PROSGEGRAMMENI, COMBINING COMMA ABOVE, COMBINING GRAVE TONE MARK +1FFC 0343 0300;1FAA;03A9 0313 0300 0345;1FAA;03A9 0313 0300 0345; # (ῼ◌̓◌̀; ᾪ; Ω◌̓◌̀◌ͅ; ᾪ; Ω◌̓◌̀◌ͅ; ) GREEK CAPITAL LETTER OMEGA WITH PROSGEGRAMMENI, COMBINING GREEK KORONIS, COMBINING GRAVE ACCENT +1FFC 0343 0340;1FAA;03A9 0313 0300 0345;1FAA;03A9 0313 0300 0345; # (ῼ◌̓◌̀; ᾪ; Ω◌̓◌̀◌ͅ; ᾪ; Ω◌̓◌̀◌ͅ; ) GREEK CAPITAL LETTER OMEGA WITH PROSGEGRAMMENI, COMBINING GREEK KORONIS, COMBINING GRAVE TONE MARK +1F6B 0345;1FAB;03A9 0314 0300 0345;1FAB;03A9 0314 0300 0345; # (Ὣ◌ͅ; ᾫ; Ω◌̔◌̀◌ͅ; ᾫ; Ω◌̔◌̀◌ͅ; ) GREEK CAPITAL LETTER OMEGA WITH DASIA AND VARIA, COMBINING GREEK YPOGEGRAMMENI +1FA9 0300;1FAB;03A9 0314 0300 0345;1FAB;03A9 0314 0300 0345; # (ᾩ◌̀; ᾫ; Ω◌̔◌̀◌ͅ; ᾫ; Ω◌̔◌̀◌ͅ; ) GREEK CAPITAL LETTER OMEGA WITH DASIA AND PROSGEGRAMMENI, COMBINING GRAVE ACCENT +1FA9 0340;1FAB;03A9 0314 0300 0345;1FAB;03A9 0314 0300 0345; # (ᾩ◌̀; ᾫ; Ω◌̔◌̀◌ͅ; ᾫ; Ω◌̔◌̀◌ͅ; ) GREEK CAPITAL LETTER OMEGA WITH DASIA AND PROSGEGRAMMENI, COMBINING GRAVE TONE MARK +1F69 0300 0345;1FAB;03A9 0314 0300 0345;1FAB;03A9 0314 0300 0345; # (Ὡ◌̀◌ͅ; ᾫ; Ω◌̔◌̀◌ͅ; ᾫ; Ω◌̔◌̀◌ͅ; ) GREEK CAPITAL LETTER OMEGA WITH DASIA, COMBINING GRAVE ACCENT, COMBINING GREEK YPOGEGRAMMENI +1F69 0340 0345;1FAB;03A9 0314 0300 0345;1FAB;03A9 0314 0300 0345; # (Ὡ◌̀◌ͅ; ᾫ; Ω◌̔◌̀◌ͅ; ᾫ; Ω◌̔◌̀◌ͅ; ) GREEK CAPITAL LETTER OMEGA WITH DASIA, COMBINING GRAVE TONE MARK, COMBINING GREEK YPOGEGRAMMENI +1F69 0345 0300;1FAB;03A9 0314 0300 0345;1FAB;03A9 0314 0300 0345; # (Ὡ◌ͅ◌̀; ᾫ; Ω◌̔◌̀◌ͅ; ᾫ; Ω◌̔◌̀◌ͅ; ) GREEK CAPITAL LETTER OMEGA WITH DASIA, COMBINING GREEK YPOGEGRAMMENI, COMBINING GRAVE ACCENT +1F69 0345 0340;1FAB;03A9 0314 0300 0345;1FAB;03A9 0314 0300 0345; # (Ὡ◌ͅ◌̀; ᾫ; Ω◌̔◌̀◌ͅ; ᾫ; Ω◌̔◌̀◌ͅ; ) GREEK CAPITAL LETTER OMEGA WITH DASIA, COMBINING GREEK YPOGEGRAMMENI, COMBINING GRAVE TONE MARK +1FFC 0314 0300;1FAB;03A9 0314 0300 0345;1FAB;03A9 0314 0300 0345; # (ῼ◌̔◌̀; ᾫ; Ω◌̔◌̀◌ͅ; ᾫ; Ω◌̔◌̀◌ͅ; ) GREEK CAPITAL LETTER OMEGA WITH PROSGEGRAMMENI, COMBINING REVERSED COMMA ABOVE, COMBINING GRAVE ACCENT +1FFC 0314 0340;1FAB;03A9 0314 0300 0345;1FAB;03A9 0314 0300 0345; # (ῼ◌̔◌̀; ᾫ; Ω◌̔◌̀◌ͅ; ᾫ; Ω◌̔◌̀◌ͅ; ) GREEK CAPITAL LETTER OMEGA WITH PROSGEGRAMMENI, COMBINING REVERSED COMMA ABOVE, COMBINING GRAVE TONE MARK +1F6C 0345;1FAC;03A9 0313 0301 0345;1FAC;03A9 0313 0301 0345; # (Ὤ◌ͅ; ᾬ; Ω◌̓◌́◌ͅ; ᾬ; Ω◌̓◌́◌ͅ; ) GREEK CAPITAL LETTER OMEGA WITH PSILI AND OXIA, COMBINING GREEK YPOGEGRAMMENI +1FA8 0301;1FAC;03A9 0313 0301 0345;1FAC;03A9 0313 0301 0345; # (ᾨ◌́; ᾬ; Ω◌̓◌́◌ͅ; ᾬ; Ω◌̓◌́◌ͅ; ) GREEK CAPITAL LETTER OMEGA WITH PSILI AND PROSGEGRAMMENI, COMBINING ACUTE ACCENT +1FA8 0341;1FAC;03A9 0313 0301 0345;1FAC;03A9 0313 0301 0345; # (ᾨ◌́; ᾬ; Ω◌̓◌́◌ͅ; ᾬ; Ω◌̓◌́◌ͅ; ) GREEK CAPITAL LETTER OMEGA WITH PSILI AND PROSGEGRAMMENI, COMBINING ACUTE TONE MARK +1F68 0301 0345;1FAC;03A9 0313 0301 0345;1FAC;03A9 0313 0301 0345; # (Ὠ◌́◌ͅ; ᾬ; Ω◌̓◌́◌ͅ; ᾬ; Ω◌̓◌́◌ͅ; ) GREEK CAPITAL LETTER OMEGA WITH PSILI, COMBINING ACUTE ACCENT, COMBINING GREEK YPOGEGRAMMENI +1F68 0341 0345;1FAC;03A9 0313 0301 0345;1FAC;03A9 0313 0301 0345; # (Ὠ◌́◌ͅ; ᾬ; Ω◌̓◌́◌ͅ; ᾬ; Ω◌̓◌́◌ͅ; ) GREEK CAPITAL LETTER OMEGA WITH PSILI, COMBINING ACUTE TONE MARK, COMBINING GREEK YPOGEGRAMMENI +1F68 0345 0301;1FAC;03A9 0313 0301 0345;1FAC;03A9 0313 0301 0345; # (Ὠ◌ͅ◌́; ᾬ; Ω◌̓◌́◌ͅ; ᾬ; Ω◌̓◌́◌ͅ; ) GREEK CAPITAL LETTER OMEGA WITH PSILI, COMBINING GREEK YPOGEGRAMMENI, COMBINING ACUTE ACCENT +1F68 0345 0341;1FAC;03A9 0313 0301 0345;1FAC;03A9 0313 0301 0345; # (Ὠ◌ͅ◌́; ᾬ; Ω◌̓◌́◌ͅ; ᾬ; Ω◌̓◌́◌ͅ; ) GREEK CAPITAL LETTER OMEGA WITH PSILI, COMBINING GREEK YPOGEGRAMMENI, COMBINING ACUTE TONE MARK +1FFC 0313 0301;1FAC;03A9 0313 0301 0345;1FAC;03A9 0313 0301 0345; # (ῼ◌̓◌́; ᾬ; Ω◌̓◌́◌ͅ; ᾬ; Ω◌̓◌́◌ͅ; ) GREEK CAPITAL LETTER OMEGA WITH PROSGEGRAMMENI, COMBINING COMMA ABOVE, COMBINING ACUTE ACCENT +1FFC 0313 0341;1FAC;03A9 0313 0301 0345;1FAC;03A9 0313 0301 0345; # (ῼ◌̓◌́; ᾬ; Ω◌̓◌́◌ͅ; ᾬ; Ω◌̓◌́◌ͅ; ) GREEK CAPITAL LETTER OMEGA WITH PROSGEGRAMMENI, COMBINING COMMA ABOVE, COMBINING ACUTE TONE MARK +1FFC 0343 0301;1FAC;03A9 0313 0301 0345;1FAC;03A9 0313 0301 0345; # (ῼ◌̓◌́; ᾬ; Ω◌̓◌́◌ͅ; ᾬ; Ω◌̓◌́◌ͅ; ) GREEK CAPITAL LETTER OMEGA WITH PROSGEGRAMMENI, COMBINING GREEK KORONIS, COMBINING ACUTE ACCENT +1FFC 0343 0341;1FAC;03A9 0313 0301 0345;1FAC;03A9 0313 0301 0345; # (ῼ◌̓◌́; ᾬ; Ω◌̓◌́◌ͅ; ᾬ; Ω◌̓◌́◌ͅ; ) GREEK CAPITAL LETTER OMEGA WITH PROSGEGRAMMENI, COMBINING GREEK KORONIS, COMBINING ACUTE TONE MARK +1F6D 0345;1FAD;03A9 0314 0301 0345;1FAD;03A9 0314 0301 0345; # (Ὥ◌ͅ; ᾭ; Ω◌̔◌́◌ͅ; ᾭ; Ω◌̔◌́◌ͅ; ) GREEK CAPITAL LETTER OMEGA WITH DASIA AND OXIA, COMBINING GREEK YPOGEGRAMMENI +1FA9 0301;1FAD;03A9 0314 0301 0345;1FAD;03A9 0314 0301 0345; # (ᾩ◌́; ᾭ; Ω◌̔◌́◌ͅ; ᾭ; Ω◌̔◌́◌ͅ; ) GREEK CAPITAL LETTER OMEGA WITH DASIA AND PROSGEGRAMMENI, COMBINING ACUTE ACCENT +1FA9 0341;1FAD;03A9 0314 0301 0345;1FAD;03A9 0314 0301 0345; # (ᾩ◌́; ᾭ; Ω◌̔◌́◌ͅ; ᾭ; Ω◌̔◌́◌ͅ; ) GREEK CAPITAL LETTER OMEGA WITH DASIA AND PROSGEGRAMMENI, COMBINING ACUTE TONE MARK +1F69 0301 0345;1FAD;03A9 0314 0301 0345;1FAD;03A9 0314 0301 0345; # (Ὡ◌́◌ͅ; ᾭ; Ω◌̔◌́◌ͅ; ᾭ; Ω◌̔◌́◌ͅ; ) GREEK CAPITAL LETTER OMEGA WITH DASIA, COMBINING ACUTE ACCENT, COMBINING GREEK YPOGEGRAMMENI +1F69 0341 0345;1FAD;03A9 0314 0301 0345;1FAD;03A9 0314 0301 0345; # (Ὡ◌́◌ͅ; ᾭ; Ω◌̔◌́◌ͅ; ᾭ; Ω◌̔◌́◌ͅ; ) GREEK CAPITAL LETTER OMEGA WITH DASIA, COMBINING ACUTE TONE MARK, COMBINING GREEK YPOGEGRAMMENI +1F69 0345 0301;1FAD;03A9 0314 0301 0345;1FAD;03A9 0314 0301 0345; # (Ὡ◌ͅ◌́; ᾭ; Ω◌̔◌́◌ͅ; ᾭ; Ω◌̔◌́◌ͅ; ) GREEK CAPITAL LETTER OMEGA WITH DASIA, COMBINING GREEK YPOGEGRAMMENI, COMBINING ACUTE ACCENT +1F69 0345 0341;1FAD;03A9 0314 0301 0345;1FAD;03A9 0314 0301 0345; # (Ὡ◌ͅ◌́; ᾭ; Ω◌̔◌́◌ͅ; ᾭ; Ω◌̔◌́◌ͅ; ) GREEK CAPITAL LETTER OMEGA WITH DASIA, COMBINING GREEK YPOGEGRAMMENI, COMBINING ACUTE TONE MARK +1FFC 0314 0301;1FAD;03A9 0314 0301 0345;1FAD;03A9 0314 0301 0345; # (ῼ◌̔◌́; ᾭ; Ω◌̔◌́◌ͅ; ᾭ; Ω◌̔◌́◌ͅ; ) GREEK CAPITAL LETTER OMEGA WITH PROSGEGRAMMENI, COMBINING REVERSED COMMA ABOVE, COMBINING ACUTE ACCENT +1FFC 0314 0341;1FAD;03A9 0314 0301 0345;1FAD;03A9 0314 0301 0345; # (ῼ◌̔◌́; ᾭ; Ω◌̔◌́◌ͅ; ᾭ; Ω◌̔◌́◌ͅ; ) GREEK CAPITAL LETTER OMEGA WITH PROSGEGRAMMENI, COMBINING REVERSED COMMA ABOVE, COMBINING ACUTE TONE MARK +1F6E 0345;1FAE;03A9 0313 0342 0345;1FAE;03A9 0313 0342 0345; # (Ὦ◌ͅ; ᾮ; Ω◌̓◌͂◌ͅ; ᾮ; Ω◌̓◌͂◌ͅ; ) GREEK CAPITAL LETTER OMEGA WITH PSILI AND PERISPOMENI, COMBINING GREEK YPOGEGRAMMENI +1FA8 0342;1FAE;03A9 0313 0342 0345;1FAE;03A9 0313 0342 0345; # (ᾨ◌͂; ᾮ; Ω◌̓◌͂◌ͅ; ᾮ; Ω◌̓◌͂◌ͅ; ) GREEK CAPITAL LETTER OMEGA WITH PSILI AND PROSGEGRAMMENI, COMBINING GREEK PERISPOMENI +1F68 0342 0345;1FAE;03A9 0313 0342 0345;1FAE;03A9 0313 0342 0345; # (Ὠ◌͂◌ͅ; ᾮ; Ω◌̓◌͂◌ͅ; ᾮ; Ω◌̓◌͂◌ͅ; ) GREEK CAPITAL LETTER OMEGA WITH PSILI, COMBINING GREEK PERISPOMENI, COMBINING GREEK YPOGEGRAMMENI +1F68 0345 0342;1FAE;03A9 0313 0342 0345;1FAE;03A9 0313 0342 0345; # (Ὠ◌ͅ◌͂; ᾮ; Ω◌̓◌͂◌ͅ; ᾮ; Ω◌̓◌͂◌ͅ; ) GREEK CAPITAL LETTER OMEGA WITH PSILI, COMBINING GREEK YPOGEGRAMMENI, COMBINING GREEK PERISPOMENI +1FFC 0313 0342;1FAE;03A9 0313 0342 0345;1FAE;03A9 0313 0342 0345; # (ῼ◌̓◌͂; ᾮ; Ω◌̓◌͂◌ͅ; ᾮ; Ω◌̓◌͂◌ͅ; ) GREEK CAPITAL LETTER OMEGA WITH PROSGEGRAMMENI, COMBINING COMMA ABOVE, COMBINING GREEK PERISPOMENI +1FFC 0343 0342;1FAE;03A9 0313 0342 0345;1FAE;03A9 0313 0342 0345; # (ῼ◌̓◌͂; ᾮ; Ω◌̓◌͂◌ͅ; ᾮ; Ω◌̓◌͂◌ͅ; ) GREEK CAPITAL LETTER OMEGA WITH PROSGEGRAMMENI, COMBINING GREEK KORONIS, COMBINING GREEK PERISPOMENI +1F6F 0345;1FAF;03A9 0314 0342 0345;1FAF;03A9 0314 0342 0345; # (Ὧ◌ͅ; ᾯ; Ω◌̔◌͂◌ͅ; ᾯ; Ω◌̔◌͂◌ͅ; ) GREEK CAPITAL LETTER OMEGA WITH DASIA AND PERISPOMENI, COMBINING GREEK YPOGEGRAMMENI +1FA9 0342;1FAF;03A9 0314 0342 0345;1FAF;03A9 0314 0342 0345; # (ᾩ◌͂; ᾯ; Ω◌̔◌͂◌ͅ; ᾯ; Ω◌̔◌͂◌ͅ; ) GREEK CAPITAL LETTER OMEGA WITH DASIA AND PROSGEGRAMMENI, COMBINING GREEK PERISPOMENI +1F69 0342 0345;1FAF;03A9 0314 0342 0345;1FAF;03A9 0314 0342 0345; # (Ὡ◌͂◌ͅ; ᾯ; Ω◌̔◌͂◌ͅ; ᾯ; Ω◌̔◌͂◌ͅ; ) GREEK CAPITAL LETTER OMEGA WITH DASIA, COMBINING GREEK PERISPOMENI, COMBINING GREEK YPOGEGRAMMENI +1F69 0345 0342;1FAF;03A9 0314 0342 0345;1FAF;03A9 0314 0342 0345; # (Ὡ◌ͅ◌͂; ᾯ; Ω◌̔◌͂◌ͅ; ᾯ; Ω◌̔◌͂◌ͅ; ) GREEK CAPITAL LETTER OMEGA WITH DASIA, COMBINING GREEK YPOGEGRAMMENI, COMBINING GREEK PERISPOMENI +1FFC 0314 0342;1FAF;03A9 0314 0342 0345;1FAF;03A9 0314 0342 0345; # (ῼ◌̔◌͂; ᾯ; Ω◌̔◌͂◌ͅ; ᾯ; Ω◌̔◌͂◌ͅ; ) GREEK CAPITAL LETTER OMEGA WITH PROSGEGRAMMENI, COMBINING REVERSED COMMA ABOVE, COMBINING GREEK PERISPOMENI +1F70 0345;1FB2;03B1 0300 0345;1FB2;03B1 0300 0345; # (ὰ◌ͅ; ᾲ; α◌̀◌ͅ; ᾲ; α◌̀◌ͅ; ) GREEK SMALL LETTER ALPHA WITH VARIA, COMBINING GREEK YPOGEGRAMMENI +1FB3 0300;1FB2;03B1 0300 0345;1FB2;03B1 0300 0345; # (ᾳ◌̀; ᾲ; α◌̀◌ͅ; ᾲ; α◌̀◌ͅ; ) GREEK SMALL LETTER ALPHA WITH YPOGEGRAMMENI, COMBINING GRAVE ACCENT +1FB3 0340;1FB2;03B1 0300 0345;1FB2;03B1 0300 0345; # (ᾳ◌̀; ᾲ; α◌̀◌ͅ; ᾲ; α◌̀◌ͅ; ) GREEK SMALL LETTER ALPHA WITH YPOGEGRAMMENI, COMBINING GRAVE TONE MARK +03AC 0345;1FB4;03B1 0301 0345;1FB4;03B1 0301 0345; # (ά◌ͅ; ᾴ; α◌́◌ͅ; ᾴ; α◌́◌ͅ; ) GREEK SMALL LETTER ALPHA WITH TONOS, COMBINING GREEK YPOGEGRAMMENI +1F71 0345;1FB4;03B1 0301 0345;1FB4;03B1 0301 0345; # (ά◌ͅ; ᾴ; α◌́◌ͅ; ᾴ; α◌́◌ͅ; ) GREEK SMALL LETTER ALPHA WITH OXIA, COMBINING GREEK YPOGEGRAMMENI +1FB3 0301;1FB4;03B1 0301 0345;1FB4;03B1 0301 0345; # (ᾳ◌́; ᾴ; α◌́◌ͅ; ᾴ; α◌́◌ͅ; ) GREEK SMALL LETTER ALPHA WITH YPOGEGRAMMENI, COMBINING ACUTE ACCENT +1FB3 0341;1FB4;03B1 0301 0345;1FB4;03B1 0301 0345; # (ᾳ◌́; ᾴ; α◌́◌ͅ; ᾴ; α◌́◌ͅ; ) GREEK SMALL LETTER ALPHA WITH YPOGEGRAMMENI, COMBINING ACUTE TONE MARK +1FB3 0342;1FB7;03B1 0342 0345;1FB7;03B1 0342 0345; # (ᾳ◌͂; ᾷ; α◌͂◌ͅ; ᾷ; α◌͂◌ͅ; ) GREEK SMALL LETTER ALPHA WITH YPOGEGRAMMENI, COMBINING GREEK PERISPOMENI +1FB6 0345;1FB7;03B1 0342 0345;1FB7;03B1 0342 0345; # (ᾶ◌ͅ; ᾷ; α◌͂◌ͅ; ᾷ; α◌͂◌ͅ; ) GREEK SMALL LETTER ALPHA WITH PERISPOMENI, COMBINING GREEK YPOGEGRAMMENI +1F74 0345;1FC2;03B7 0300 0345;1FC2;03B7 0300 0345; # (ὴ◌ͅ; ῂ; η◌̀◌ͅ; ῂ; η◌̀◌ͅ; ) GREEK SMALL LETTER ETA WITH VARIA, COMBINING GREEK YPOGEGRAMMENI +1FC3 0300;1FC2;03B7 0300 0345;1FC2;03B7 0300 0345; # (ῃ◌̀; ῂ; η◌̀◌ͅ; ῂ; η◌̀◌ͅ; ) GREEK SMALL LETTER ETA WITH YPOGEGRAMMENI, COMBINING GRAVE ACCENT +1FC3 0340;1FC2;03B7 0300 0345;1FC2;03B7 0300 0345; # (ῃ◌̀; ῂ; η◌̀◌ͅ; ῂ; η◌̀◌ͅ; ) GREEK SMALL LETTER ETA WITH YPOGEGRAMMENI, COMBINING GRAVE TONE MARK +03AE 0345;1FC4;03B7 0301 0345;1FC4;03B7 0301 0345; # (ή◌ͅ; ῄ; η◌́◌ͅ; ῄ; η◌́◌ͅ; ) GREEK SMALL LETTER ETA WITH TONOS, COMBINING GREEK YPOGEGRAMMENI +1F75 0345;1FC4;03B7 0301 0345;1FC4;03B7 0301 0345; # (ή◌ͅ; ῄ; η◌́◌ͅ; ῄ; η◌́◌ͅ; ) GREEK SMALL LETTER ETA WITH OXIA, COMBINING GREEK YPOGEGRAMMENI +1FC3 0301;1FC4;03B7 0301 0345;1FC4;03B7 0301 0345; # (ῃ◌́; ῄ; η◌́◌ͅ; ῄ; η◌́◌ͅ; ) GREEK SMALL LETTER ETA WITH YPOGEGRAMMENI, COMBINING ACUTE ACCENT +1FC3 0341;1FC4;03B7 0301 0345;1FC4;03B7 0301 0345; # (ῃ◌́; ῄ; η◌́◌ͅ; ῄ; η◌́◌ͅ; ) GREEK SMALL LETTER ETA WITH YPOGEGRAMMENI, COMBINING ACUTE TONE MARK +1FC3 0342;1FC7;03B7 0342 0345;1FC7;03B7 0342 0345; # (ῃ◌͂; ῇ; η◌͂◌ͅ; ῇ; η◌͂◌ͅ; ) GREEK SMALL LETTER ETA WITH YPOGEGRAMMENI, COMBINING GREEK PERISPOMENI +1FC6 0345;1FC7;03B7 0342 0345;1FC7;03B7 0342 0345; # (ῆ◌ͅ; ῇ; η◌͂◌ͅ; ῇ; η◌͂◌ͅ; ) GREEK SMALL LETTER ETA WITH PERISPOMENI, COMBINING GREEK YPOGEGRAMMENI +03CA 0300;1FD2;03B9 0308 0300;1FD2;03B9 0308 0300; # (ϊ◌̀; ῒ; ι◌̈◌̀; ῒ; ι◌̈◌̀; ) GREEK SMALL LETTER IOTA WITH DIALYTIKA, COMBINING GRAVE ACCENT +03CA 0340;1FD2;03B9 0308 0300;1FD2;03B9 0308 0300; # (ϊ◌̀; ῒ; ι◌̈◌̀; ῒ; ι◌̈◌̀; ) GREEK SMALL LETTER IOTA WITH DIALYTIKA, COMBINING GRAVE TONE MARK +03B9 0344;0390;03B9 0308 0301;0390;03B9 0308 0301; # (ι◌̈́; ΐ; ι◌̈◌́; ΐ; ι◌̈◌́; ) GREEK SMALL LETTER IOTA, COMBINING GREEK DIALYTIKA TONOS +03CA 0301;0390;03B9 0308 0301;0390;03B9 0308 0301; # (ϊ◌́; ΐ; ι◌̈◌́; ΐ; ι◌̈◌́; ) GREEK SMALL LETTER IOTA WITH DIALYTIKA, COMBINING ACUTE ACCENT +03CA 0341;0390;03B9 0308 0301;0390;03B9 0308 0301; # (ϊ◌́; ΐ; ι◌̈◌́; ΐ; ι◌̈◌́; ) GREEK SMALL LETTER IOTA WITH DIALYTIKA, COMBINING ACUTE TONE MARK +1FBE 0344;0390;03B9 0308 0301;0390;03B9 0308 0301; # (ι◌̈́; ΐ; ι◌̈◌́; ΐ; ι◌̈◌́; ) GREEK PROSGEGRAMMENI, COMBINING GREEK DIALYTIKA TONOS +03CA 0342;1FD7;03B9 0308 0342;1FD7;03B9 0308 0342; # (ϊ◌͂; ῗ; ι◌̈◌͂; ῗ; ι◌̈◌͂; ) GREEK SMALL LETTER IOTA WITH DIALYTIKA, COMBINING GREEK PERISPOMENI +03CB 0300;1FE2;03C5 0308 0300;1FE2;03C5 0308 0300; # (ϋ◌̀; ῢ; υ◌̈◌̀; ῢ; υ◌̈◌̀; ) GREEK SMALL LETTER UPSILON WITH DIALYTIKA, COMBINING GRAVE ACCENT +03CB 0340;1FE2;03C5 0308 0300;1FE2;03C5 0308 0300; # (ϋ◌̀; ῢ; υ◌̈◌̀; ῢ; υ◌̈◌̀; ) GREEK SMALL LETTER UPSILON WITH DIALYTIKA, COMBINING GRAVE TONE MARK +03C5 0344;03B0;03C5 0308 0301;03B0;03C5 0308 0301; # (υ◌̈́; ΰ; υ◌̈◌́; ΰ; υ◌̈◌́; ) GREEK SMALL LETTER UPSILON, COMBINING GREEK DIALYTIKA TONOS +03CB 0301;03B0;03C5 0308 0301;03B0;03C5 0308 0301; # (ϋ◌́; ΰ; υ◌̈◌́; ΰ; υ◌̈◌́; ) GREEK SMALL LETTER UPSILON WITH DIALYTIKA, COMBINING ACUTE ACCENT +03CB 0341;03B0;03C5 0308 0301;03B0;03C5 0308 0301; # (ϋ◌́; ΰ; υ◌̈◌́; ΰ; υ◌̈◌́; ) GREEK SMALL LETTER UPSILON WITH DIALYTIKA, COMBINING ACUTE TONE MARK +03CB 0342;1FE7;03C5 0308 0342;1FE7;03C5 0308 0342; # (ϋ◌͂; ῧ; υ◌̈◌͂; ῧ; υ◌̈◌͂; ) GREEK SMALL LETTER UPSILON WITH DIALYTIKA, COMBINING GREEK PERISPOMENI +1F7C 0345;1FF2;03C9 0300 0345;1FF2;03C9 0300 0345; # (ὼ◌ͅ; ῲ; ω◌̀◌ͅ; ῲ; ω◌̀◌ͅ; ) GREEK SMALL LETTER OMEGA WITH VARIA, COMBINING GREEK YPOGEGRAMMENI +1FF3 0300;1FF2;03C9 0300 0345;1FF2;03C9 0300 0345; # (ῳ◌̀; ῲ; ω◌̀◌ͅ; ῲ; ω◌̀◌ͅ; ) GREEK SMALL LETTER OMEGA WITH YPOGEGRAMMENI, COMBINING GRAVE ACCENT +1FF3 0340;1FF2;03C9 0300 0345;1FF2;03C9 0300 0345; # (ῳ◌̀; ῲ; ω◌̀◌ͅ; ῲ; ω◌̀◌ͅ; ) GREEK SMALL LETTER OMEGA WITH YPOGEGRAMMENI, COMBINING GRAVE TONE MARK +03CE 0345;1FF4;03C9 0301 0345;1FF4;03C9 0301 0345; # (ώ◌ͅ; ῴ; ω◌́◌ͅ; ῴ; ω◌́◌ͅ; ) GREEK SMALL LETTER OMEGA WITH TONOS, COMBINING GREEK YPOGEGRAMMENI +1F7D 0345;1FF4;03C9 0301 0345;1FF4;03C9 0301 0345; # (ώ◌ͅ; ῴ; ω◌́◌ͅ; ῴ; ω◌́◌ͅ; ) GREEK SMALL LETTER OMEGA WITH OXIA, COMBINING GREEK YPOGEGRAMMENI +1FF3 0301;1FF4;03C9 0301 0345;1FF4;03C9 0301 0345; # (ῳ◌́; ῴ; ω◌́◌ͅ; ῴ; ω◌́◌ͅ; ) GREEK SMALL LETTER OMEGA WITH YPOGEGRAMMENI, COMBINING ACUTE ACCENT +1FF3 0341;1FF4;03C9 0301 0345;1FF4;03C9 0301 0345; # (ῳ◌́; ῴ; ω◌́◌ͅ; ῴ; ω◌́◌ͅ; ) GREEK SMALL LETTER OMEGA WITH YPOGEGRAMMENI, COMBINING ACUTE TONE MARK +1FF3 0342;1FF7;03C9 0342 0345;1FF7;03C9 0342 0345; # (ῳ◌͂; ῷ; ω◌͂◌ͅ; ῷ; ω◌͂◌ͅ; ) GREEK SMALL LETTER OMEGA WITH YPOGEGRAMMENI, COMBINING GREEK PERISPOMENI +1FF6 0345;1FF7;03C9 0342 0345;1FF7;03C9 0342 0345; # (ῶ◌ͅ; ῷ; ω◌͂◌ͅ; ῷ; ω◌͂◌ͅ; ) GREEK SMALL LETTER OMEGA WITH PERISPOMENI, COMBINING GREEK YPOGEGRAMMENI +FB2A 05BC;05E9 05BC 05C1;05E9 05BC 05C1;05E9 05BC 05C1;05E9 05BC 05C1; # (שׁ◌ּ; ש◌ּ◌ׁ; ש◌ּ◌ׁ; ש◌ּ◌ׁ; ש◌ּ◌ׁ; ) HEBREW LETTER SHIN WITH SHIN DOT, HEBREW POINT DAGESH OR MAPIQ +FB49 05C1;05E9 05BC 05C1;05E9 05BC 05C1;05E9 05BC 05C1;05E9 05BC 05C1; # (שּ◌ׁ; ש◌ּ◌ׁ; ש◌ּ◌ׁ; ש◌ּ◌ׁ; ש◌ּ◌ׁ; ) HEBREW LETTER SHIN WITH DAGESH, HEBREW POINT SHIN DOT +FB2B 05BC;05E9 05BC 05C2;05E9 05BC 05C2;05E9 05BC 05C2;05E9 05BC 05C2; # (שׂ◌ּ; ש◌ּ◌ׂ; ש◌ּ◌ׂ; ש◌ּ◌ׂ; ש◌ּ◌ׂ; ) HEBREW LETTER SHIN WITH SIN DOT, HEBREW POINT DAGESH OR MAPIQ +FB49 05C2;05E9 05BC 05C2;05E9 05BC 05C2;05E9 05BC 05C2;05E9 05BC 05C2; # (שּ◌ׂ; ש◌ּ◌ׂ; ש◌ּ◌ׂ; ש◌ּ◌ׂ; ש◌ּ◌ׂ; ) HEBREW LETTER SHIN WITH DAGESH, HEBREW POINT SIN DOT +1611E 16123;16126;1611E 1611E 1611F;16126;1611E 1611E 1611F; # (◌𖄞◌𖄣; ◌𖄦; ◌𖄞◌𖄞◌𖄟; ◌𖄦; ◌𖄞◌𖄞◌𖄟; ) GURUNG KHEMA VOWEL SIGN AA, GURUNG KHEMA VOWEL SIGN E +16121 1611F;16126;1611E 1611E 1611F;16126;1611E 1611E 1611F; # (◌𖄡◌𖄟; ◌𖄦; ◌𖄞◌𖄞◌𖄟; ◌𖄦; ◌𖄞◌𖄞◌𖄟; ) GURUNG KHEMA VOWEL SIGN U, GURUNG KHEMA VOWEL SIGN I +1611E 16124;16127;1611E 16129 1611F;16127;1611E 16129 1611F; # (◌𖄞◌𖄤; ◌𖄧; ◌𖄞◌𖄩◌𖄟; ◌𖄧; ◌𖄞◌𖄩◌𖄟; ) GURUNG KHEMA VOWEL SIGN AA, GURUNG KHEMA VOWEL SIGN EE +16122 1611F;16127;1611E 16129 1611F;16127;1611E 16129 1611F; # (◌𖄢◌𖄟; ◌𖄧; ◌𖄞◌𖄩◌𖄟; ◌𖄧; ◌𖄞◌𖄩◌𖄟; ) GURUNG KHEMA VOWEL SIGN UU, GURUNG KHEMA VOWEL SIGN I +1611E 16125;16128;1611E 1611E 16120;16128;1611E 1611E 16120; # (◌𖄞◌𖄥; ◌𖄨; ◌𖄞◌𖄞◌𖄠; ◌𖄨; ◌𖄞◌𖄞◌𖄠; ) GURUNG KHEMA VOWEL SIGN AA, GURUNG KHEMA VOWEL SIGN AI +16121 16120;16128;1611E 1611E 16120;16128;1611E 1611E 16120; # (◌𖄡◌𖄠; ◌𖄨; ◌𖄞◌𖄞◌𖄠; ◌𖄨; ◌𖄞◌𖄞◌𖄠; ) GURUNG KHEMA VOWEL SIGN U, GURUNG KHEMA VOWEL SIGN II +16D63 16D68;16D6A;16D63 16D67 16D67;16D6A;16D63 16D67 16D67; # (𖵪; 𖵪; 𖵪; 𖵪; 𖵪; ) KIRAT RAI VOWEL SIGN AA, KIRAT RAI VOWEL SIGN AI +16D69 16D67;16D6A;16D63 16D67 16D67;16D6A;16D63 16D67 16D67; # (𖵪; 𖵪; 𖵪; 𖵪; 𖵪; ) KIRAT RAI VOWEL SIGN O, KIRAT RAI VOWEL SIGN E +1D15F 1D16E;1D158 1D165 1D16E;1D158 1D165 1D16E;1D158 1D165 1D16E;1D158 1D165 1D16E; # (𝅘𝅥𝅮; 𝅘𝅥𝅮; 𝅘𝅥𝅮; 𝅘𝅥𝅮; 𝅘𝅥𝅮; ) MUSICAL SYMBOL QUARTER NOTE, MUSICAL SYMBOL COMBINING FLAG-1 +1D15F 1D16F;1D158 1D165 1D16F;1D158 1D165 1D16F;1D158 1D165 1D16F;1D158 1D165 1D16F; # (𝅘𝅥𝅯; 𝅘𝅥𝅯; 𝅘𝅥𝅯; 𝅘𝅥𝅯; 𝅘𝅥𝅯; ) MUSICAL SYMBOL QUARTER NOTE, MUSICAL SYMBOL COMBINING FLAG-2 +1D15F 1D170;1D158 1D165 1D170;1D158 1D165 1D170;1D158 1D165 1D170;1D158 1D165 1D170; # (𝅘𝅥𝅰; 𝅘𝅥𝅰; 𝅘𝅥𝅰; 𝅘𝅥𝅰; 𝅘𝅥𝅰; ) MUSICAL SYMBOL QUARTER NOTE, MUSICAL SYMBOL COMBINING FLAG-3 +1D15F 1D171;1D158 1D165 1D171;1D158 1D165 1D171;1D158 1D165 1D171;1D158 1D165 1D171; # (𝅘𝅥𝅱; 𝅘𝅥𝅱; 𝅘𝅥𝅱; 𝅘𝅥𝅱; 𝅘𝅥𝅱; ) MUSICAL SYMBOL QUARTER NOTE, MUSICAL SYMBOL COMBINING FLAG-4 +1D15F 1D172;1D158 1D165 1D172;1D158 1D165 1D172;1D158 1D165 1D172;1D158 1D165 1D172; # (𝅘𝅥𝅲; 𝅘𝅥𝅲; 𝅘𝅥𝅲; 𝅘𝅥𝅲; 𝅘𝅥𝅲; ) MUSICAL SYMBOL QUARTER NOTE, MUSICAL SYMBOL COMBINING FLAG-5 +1D1BB 1D16E;1D1B9 1D165 1D16E;1D1B9 1D165 1D16E;1D1B9 1D165 1D16E;1D1B9 1D165 1D16E; # (𝆹𝅥𝅮; 𝆹𝅥𝅮; 𝆹𝅥𝅮; 𝆹𝅥𝅮; 𝆹𝅥𝅮; ) MUSICAL SYMBOL MINIMA, MUSICAL SYMBOL COMBINING FLAG-1 +1D1BC 1D16E;1D1BA 1D165 1D16E;1D1BA 1D165 1D16E;1D1BA 1D165 1D16E;1D1BA 1D165 1D16E; # (𝆺𝅥𝅮; 𝆺𝅥𝅮; 𝆺𝅥𝅮; 𝆺𝅥𝅮; 𝆺𝅥𝅮; ) MUSICAL SYMBOL MINIMA BLACK, MUSICAL SYMBOL COMBINING FLAG-1 +1D1BB 1D16F;1D1B9 1D165 1D16F;1D1B9 1D165 1D16F;1D1B9 1D165 1D16F;1D1B9 1D165 1D16F; # (𝆹𝅥𝅯; 𝆹𝅥𝅯; 𝆹𝅥𝅯; 𝆹𝅥𝅯; 𝆹𝅥𝅯; ) MUSICAL SYMBOL MINIMA, MUSICAL SYMBOL COMBINING FLAG-2 +1D1BC 1D16F;1D1BA 1D165 1D16F;1D1BA 1D165 1D16F;1D1BA 1D165 1D16F;1D1BA 1D165 1D16F; # (𝆺𝅥𝅯; 𝆺𝅥𝅯; 𝆺𝅥𝅯; 𝆺𝅥𝅯; 𝆺𝅥𝅯; ) MUSICAL SYMBOL MINIMA BLACK, MUSICAL SYMBOL COMBINING FLAG-2 +# +@Part5 # Chained primary composites +# +1138B 113C7;1138E 113B8;1138B 113C2 113B8;1138E 113B8;1138B 113C2 113B8; # (𑎎𑎸; 𑎎𑎸; 𑎎𑎸; 𑎎𑎸; 𑎎𑎸; ) TULU-TIGALARI LETTER EE, TULU-TIGALARI VOWEL SIGN OO +113C2 113C7;113C5 113B8;113C2 113C2 113B8;113C5 113B8;113C2 113C2 113B8; # (𑏅𑎸; 𑏅𑎸; 𑏅𑎸; 𑏅𑎸; 𑏅𑎸; ) TULU-TIGALARI VOWEL SIGN EE, TULU-TIGALARI VOWEL SIGN OO +1138B 113C5;1138E 113C2;1138B 113C2 113C2;1138E 113C2;1138B 113C2 113C2; # (𑎎𑏂; 𑎎𑏂; 𑎎𑏂; 𑎎𑏂; 𑎎𑏂; ) TULU-TIGALARI LETTER EE, TULU-TIGALARI VOWEL SIGN AI +1138B 113C5 113C2;1138E 113C5;1138B 113C2 113C2 113C2;1138E 113C5;1138B 113C2 113C2 113C2; # (𑎎𑏅; 𑎎𑏅; 𑎎𑏅; 𑎎𑏅; 𑎎𑏅; ) TULU-TIGALARI LETTER EE, TULU-TIGALARI VOWEL SIGN AI, TULU-TIGALARI VOWEL SIGN EE +1138B 113C5 113B8;1138E 113C7;1138B 113C2 113C2 113B8;1138E 113C7;1138B 113C2 113C2 113B8; # (𑎎𑏇; 𑎎𑏇; 𑎎𑏇; 𑎎𑏇; 𑎎𑏇; ) TULU-TIGALARI LETTER EE, TULU-TIGALARI VOWEL SIGN AI, TULU-TIGALARI VOWEL SIGN AA +1138B 113C5 113C9;1138E 113C8;1138B 113C2 113C2 113C9;1138E 113C8;1138B 113C2 113C2 113C9; # (𑎎𑏈; 𑎎𑏈; 𑎎𑏈; 𑎎𑏈; 𑎎𑏈; ) TULU-TIGALARI LETTER EE, TULU-TIGALARI VOWEL SIGN AI, TULU-TIGALARI AU LENGTH MARK +113C2 113C5;113C5 113C2;113C2 113C2 113C2;113C5 113C2;113C2 113C2 113C2; # (𑏅𑏂; 𑏅𑏂; 𑏅𑏂; 𑏅𑏂; 𑏅𑏂; ) TULU-TIGALARI VOWEL SIGN EE, TULU-TIGALARI VOWEL SIGN AI +113C2 113C5 113C2;113C5 113C5;113C2 113C2 113C2 113C2;113C5 113C5;113C2 113C2 113C2 113C2; # (𑏅𑏅; 𑏅𑏅; 𑏅𑏅; 𑏅𑏅; 𑏅𑏅; ) TULU-TIGALARI VOWEL SIGN EE, TULU-TIGALARI VOWEL SIGN AI, TULU-TIGALARI VOWEL SIGN EE +113C2 113C5 113B8;113C5 113C7;113C2 113C2 113C2 113B8;113C5 113C7;113C2 113C2 113C2 113B8; # (𑏅𑏇; 𑏅𑏇; 𑏅𑏇; 𑏅𑏇; 𑏅𑏇; ) TULU-TIGALARI VOWEL SIGN EE, TULU-TIGALARI VOWEL SIGN AI, TULU-TIGALARI VOWEL SIGN AA +113C2 113C5 113C9;113C5 113C8;113C2 113C2 113C2 113C9;113C5 113C8;113C2 113C2 113C2 113C9; # (𑏅𑏈; 𑏅𑏈; 𑏅𑏈; 𑏅𑏈; 𑏅𑏈; ) TULU-TIGALARI VOWEL SIGN EE, TULU-TIGALARI VOWEL SIGN AI, TULU-TIGALARI AU LENGTH MARK +1138B 113C8;1138E 113C9;1138B 113C2 113C9;1138E 113C9;1138B 113C2 113C9; # (𑎎𑏉; 𑎎𑏉; 𑎎𑏉; 𑎎𑏉; 𑎎𑏉; ) TULU-TIGALARI LETTER EE, TULU-TIGALARI VOWEL SIGN AU +113C2 113C8;113C5 113C9;113C2 113C2 113C9;113C5 113C9;113C2 113C2 113C9; # (𑏅𑏉; 𑏅𑏉; 𑏅𑏉; 𑏅𑏉; 𑏅𑏉; ) TULU-TIGALARI VOWEL SIGN EE, TULU-TIGALARI VOWEL SIGN AU +16121 1611E 1611F;16121 16123;1611E 1611E 1611E 1611F;16121 16123;1611E 1611E 1611E 1611F; # (◌𖄡◌𖄞◌𖄟; ◌𖄡◌𖄣; ◌𖄞◌𖄞◌𖄞◌𖄟; ◌𖄡◌𖄣; ◌𖄞◌𖄞◌𖄞◌𖄟; ) GURUNG KHEMA VOWEL SIGN U, GURUNG KHEMA VOWEL SIGN AA, GURUNG KHEMA VOWEL SIGN I +16121 16129 1611F;16121 16124;1611E 1611E 16129 1611F;16121 16124;1611E 1611E 16129 1611F; # (◌𖄡◌𖄩◌𖄟; ◌𖄡◌𖄤; ◌𖄞◌𖄞◌𖄩◌𖄟; ◌𖄡◌𖄤; ◌𖄞◌𖄞◌𖄩◌𖄟; ) GURUNG KHEMA VOWEL SIGN U, GURUNG KHEMA VOWEL LENGTH MARK, GURUNG KHEMA VOWEL SIGN I +16121 1611E 16120;16121 16125;1611E 1611E 1611E 16120;16121 16125;1611E 1611E 1611E 16120; # (◌𖄡◌𖄞◌𖄠; ◌𖄡◌𖄥; ◌𖄞◌𖄞◌𖄞◌𖄠; ◌𖄡◌𖄥; ◌𖄞◌𖄞◌𖄞◌𖄠; ) GURUNG KHEMA VOWEL SIGN U, GURUNG KHEMA VOWEL SIGN AA, GURUNG KHEMA VOWEL SIGN II +1611E 16121;16121 1611E;1611E 1611E 1611E;16121 1611E;1611E 1611E 1611E; # (◌𖄞◌𖄡; ◌𖄡◌𖄞; ◌𖄞◌𖄞◌𖄞; ◌𖄡◌𖄞; ◌𖄞◌𖄞◌𖄞; ) GURUNG KHEMA VOWEL SIGN AA, GURUNG KHEMA VOWEL SIGN U +1611E 16121 1611E;16121 16121;1611E 1611E 1611E 1611E;16121 16121;1611E 1611E 1611E 1611E; # (◌𖄞◌𖄡◌𖄞; ◌𖄡◌𖄡; ◌𖄞◌𖄞◌𖄞◌𖄞; ◌𖄡◌𖄡; ◌𖄞◌𖄞◌𖄞◌𖄞; ) GURUNG KHEMA VOWEL SIGN AA, GURUNG KHEMA VOWEL SIGN U, GURUNG KHEMA VOWEL SIGN AA +1611E 16121 16129;16121 16122;1611E 1611E 1611E 16129;16121 16122;1611E 1611E 1611E 16129; # (◌𖄞◌𖄡◌𖄩; ◌𖄡◌𖄢; ◌𖄞◌𖄞◌𖄞◌𖄩; ◌𖄡◌𖄢; ◌𖄞◌𖄞◌𖄞◌𖄩; ) GURUNG KHEMA VOWEL SIGN AA, GURUNG KHEMA VOWEL SIGN U, GURUNG KHEMA VOWEL LENGTH MARK +1611E 16126;16121 16123;1611E 1611E 1611E 1611F;16121 16123;1611E 1611E 1611E 1611F; # (◌𖄞◌𖄦; ◌𖄡◌𖄣; ◌𖄞◌𖄞◌𖄞◌𖄟; ◌𖄡◌𖄣; ◌𖄞◌𖄞◌𖄞◌𖄟; ) GURUNG KHEMA VOWEL SIGN AA, GURUNG KHEMA VOWEL SIGN O +1611E 16121 1611F;16121 16123;1611E 1611E 1611E 1611F;16121 16123;1611E 1611E 1611E 1611F; # (◌𖄞◌𖄡◌𖄟; ◌𖄡◌𖄣; ◌𖄞◌𖄞◌𖄞◌𖄟; ◌𖄡◌𖄣; ◌𖄞◌𖄞◌𖄞◌𖄟; ) GURUNG KHEMA VOWEL SIGN AA, GURUNG KHEMA VOWEL SIGN U, GURUNG KHEMA VOWEL SIGN I +1611E 16128;16121 16125;1611E 1611E 1611E 16120;16121 16125;1611E 1611E 1611E 16120; # (◌𖄞◌𖄨; ◌𖄡◌𖄥; ◌𖄞◌𖄞◌𖄞◌𖄠; ◌𖄡◌𖄥; ◌𖄞◌𖄞◌𖄞◌𖄠; ) GURUNG KHEMA VOWEL SIGN AA, GURUNG KHEMA VOWEL SIGN AU +1611E 16121 16120;16121 16125;1611E 1611E 1611E 16120;16121 16125;1611E 1611E 1611E 16120; # (◌𖄞◌𖄡◌𖄠; ◌𖄡◌𖄥; ◌𖄞◌𖄞◌𖄞◌𖄠; ◌𖄡◌𖄥; ◌𖄞◌𖄞◌𖄞◌𖄠; ) GURUNG KHEMA VOWEL SIGN AA, GURUNG KHEMA VOWEL SIGN U, GURUNG KHEMA VOWEL SIGN II +1611E 16121 16123;16121 16126;1611E 1611E 1611E 1611E 1611F;16121 16126;1611E 1611E 1611E 1611E 1611F; # (◌𖄞◌𖄡◌𖄣; ◌𖄡◌𖄦; ◌𖄞◌𖄞◌𖄞◌𖄞◌𖄟; ◌𖄡◌𖄦; ◌𖄞◌𖄞◌𖄞◌𖄞◌𖄟; ) GURUNG KHEMA VOWEL SIGN AA, GURUNG KHEMA VOWEL SIGN U, GURUNG KHEMA VOWEL SIGN E +1611E 16121 1611E 1611F;16121 16126;1611E 1611E 1611E 1611E 1611F;16121 16126;1611E 1611E 1611E 1611E 1611F; # (◌𖄞◌𖄡◌𖄞◌𖄟; ◌𖄡◌𖄦; ◌𖄞◌𖄞◌𖄞◌𖄞◌𖄟; ◌𖄡◌𖄦; ◌𖄞◌𖄞◌𖄞◌𖄞◌𖄟; ) GURUNG KHEMA VOWEL SIGN AA, GURUNG KHEMA VOWEL SIGN U, GURUNG KHEMA VOWEL SIGN AA, GURUNG KHEMA VOWEL SIGN I +1611E 16121 16124;16121 16127;1611E 1611E 1611E 16129 1611F;16121 16127;1611E 1611E 1611E 16129 1611F; # (◌𖄞◌𖄡◌𖄤; ◌𖄡◌𖄧; ◌𖄞◌𖄞◌𖄞◌𖄩◌𖄟; ◌𖄡◌𖄧; ◌𖄞◌𖄞◌𖄞◌𖄩◌𖄟; ) GURUNG KHEMA VOWEL SIGN AA, GURUNG KHEMA VOWEL SIGN U, GURUNG KHEMA VOWEL SIGN EE +1611E 16121 16129 1611F;16121 16127;1611E 1611E 1611E 16129 1611F;16121 16127;1611E 1611E 1611E 16129 1611F; # (◌𖄞◌𖄡◌𖄩◌𖄟; ◌𖄡◌𖄧; ◌𖄞◌𖄞◌𖄞◌𖄩◌𖄟; ◌𖄡◌𖄧; ◌𖄞◌𖄞◌𖄞◌𖄩◌𖄟; ) GURUNG KHEMA VOWEL SIGN AA, GURUNG KHEMA VOWEL SIGN U, GURUNG KHEMA VOWEL LENGTH MARK, GURUNG KHEMA VOWEL SIGN I +1611E 16121 16125;16121 16128;1611E 1611E 1611E 1611E 16120;16121 16128;1611E 1611E 1611E 1611E 16120; # (◌𖄞◌𖄡◌𖄥; ◌𖄡◌𖄨; ◌𖄞◌𖄞◌𖄞◌𖄞◌𖄠; ◌𖄡◌𖄨; ◌𖄞◌𖄞◌𖄞◌𖄞◌𖄠; ) GURUNG KHEMA VOWEL SIGN AA, GURUNG KHEMA VOWEL SIGN U, GURUNG KHEMA VOWEL SIGN AI +1611E 16121 1611E 16120;16121 16128;1611E 1611E 1611E 1611E 16120;16121 16128;1611E 1611E 1611E 1611E 16120; # (◌𖄞◌𖄡◌𖄞◌𖄠; ◌𖄡◌𖄨; ◌𖄞◌𖄞◌𖄞◌𖄞◌𖄠; ◌𖄡◌𖄨; ◌𖄞◌𖄞◌𖄞◌𖄞◌𖄠; ) GURUNG KHEMA VOWEL SIGN AA, GURUNG KHEMA VOWEL SIGN U, GURUNG KHEMA VOWEL SIGN AA, GURUNG KHEMA VOWEL SIGN II +1611E 16127;16121 16124;1611E 1611E 16129 1611F;16121 16124;1611E 1611E 16129 1611F; # (◌𖄞◌𖄧; ◌𖄡◌𖄤; ◌𖄞◌𖄞◌𖄩◌𖄟; ◌𖄡◌𖄤; ◌𖄞◌𖄞◌𖄩◌𖄟; ) GURUNG KHEMA VOWEL SIGN AA, GURUNG KHEMA VOWEL SIGN OO +1611E 16122 1611F;16121 16124;1611E 1611E 16129 1611F;16121 16124;1611E 1611E 16129 1611F; # (◌𖄞◌𖄢◌𖄟; ◌𖄡◌𖄤; ◌𖄞◌𖄞◌𖄩◌𖄟; ◌𖄡◌𖄤; ◌𖄞◌𖄞◌𖄩◌𖄟; ) GURUNG KHEMA VOWEL SIGN AA, GURUNG KHEMA VOWEL SIGN UU, GURUNG KHEMA VOWEL SIGN I +1611E 16122;16121 16129;1611E 1611E 16129;16121 16129;1611E 1611E 16129; # (◌𖄞◌𖄢; ◌𖄡◌𖄩; ◌𖄞◌𖄞◌𖄩; ◌𖄡◌𖄩; ◌𖄞◌𖄞◌𖄩; ) GURUNG KHEMA VOWEL SIGN AA, GURUNG KHEMA VOWEL SIGN UU +16D67 16D68;16D68 16D67;16D67 16D67 16D67;16D68 16D67;16D67 16D67 16D67; # (𖵨𖵧; 𖵨𖵧; 𖵨𖵧; 𖵨𖵧; 𖵨𖵧; ) KIRAT RAI VOWEL SIGN E, KIRAT RAI VOWEL SIGN AI +16D67 16D68 16D67;16D68 16D68;16D67 16D67 16D67 16D67;16D68 16D68;16D67 16D67 16D67 16D67; # (𖵨𖵨; 𖵨𖵨; 𖵨𖵨; 𖵨𖵨; 𖵨𖵨; ) KIRAT RAI VOWEL SIGN E, KIRAT RAI VOWEL SIGN AI, KIRAT RAI VOWEL SIGN E +16D63 16D68 16D67;16D6A 16D67;16D63 16D67 16D67 16D67;16D6A 16D67;16D63 16D67 16D67 16D67; # (𖵪𖵧; 𖵪𖵧; 𖵪𖵧; 𖵪𖵧; 𖵪𖵧; ) KIRAT RAI VOWEL SIGN AA, KIRAT RAI VOWEL SIGN AI, KIRAT RAI VOWEL SIGN E +16D69 16D68;16D6A 16D67;16D63 16D67 16D67 16D67;16D6A 16D67;16D63 16D67 16D67 16D67; # (𖵪𖵧; 𖵪𖵧; 𖵪𖵧; 𖵪𖵧; 𖵪𖵧; ) KIRAT RAI VOWEL SIGN O, KIRAT RAI VOWEL SIGN AI +16D63 16D67 16D68;16D6A 16D67;16D63 16D67 16D67 16D67;16D6A 16D67;16D63 16D67 16D67 16D67; # (𖵪𖵧; 𖵪𖵧; 𖵪𖵧; 𖵪𖵧; 𖵪𖵧; ) KIRAT RAI VOWEL SIGN AA, KIRAT RAI VOWEL SIGN E, KIRAT RAI VOWEL SIGN AI +16D69 16D68 16D67;16D6A 16D68;16D63 16D67 16D67 16D67 16D67;16D6A 16D68;16D63 16D67 16D67 16D67 16D67; # (𖵪𖵨; 𖵪𖵨; 𖵪𖵨; 𖵪𖵨; 𖵪𖵨; ) KIRAT RAI VOWEL SIGN O, KIRAT RAI VOWEL SIGN AI, KIRAT RAI VOWEL SIGN E +16D63 16D67 16D68 16D67;16D6A 16D68;16D63 16D67 16D67 16D67 16D67;16D6A 16D68;16D63 16D67 16D67 16D67 16D67; # (𖵪𖵨; 𖵪𖵨; 𖵪𖵨; 𖵪𖵨; 𖵪𖵨; ) KIRAT RAI VOWEL SIGN AA, KIRAT RAI VOWEL SIGN E, KIRAT RAI VOWEL SIGN AI, KIRAT RAI VOWEL SIGN E # # EOF diff --git a/src/java.base/share/data/unicodedata/PropList.txt b/src/java.base/share/data/unicodedata/PropList.txt index 0b6964229f6..41fdbad7045 100644 --- a/src/java.base/share/data/unicodedata/PropList.txt +++ b/src/java.base/share/data/unicodedata/PropList.txt @@ -1,8 +1,8 @@ -# PropList-15.1.0.txt -# Date: 2023-08-01, 21:56:53 GMT -# Copyright (c) 2023 Unicode, Inc. +# PropList-16.0.0.txt +# Date: 2024-05-31, 18:09:48 GMT +# Copyright (c) 2024 Unicode, Inc. # Unicode and the Unicode Logo are registered trademarks of Unicode, Inc. in the U.S. and other countries. -# For terms of use, see https://www.unicode.org/terms_of_use.html +# For terms of use and license, see https://www.unicode.org/terms_of_use.html # # Unicode Character Database # For documentation, see https://www.unicode.org/reports/tr44/ @@ -62,9 +62,10 @@ FE31..FE32 ; Dash # Pd [2] PRESENTATION FORM FOR VERTICAL EM DASH..PRESENTA FE58 ; Dash # Pd SMALL EM DASH FE63 ; Dash # Pd SMALL HYPHEN-MINUS FF0D ; Dash # Pd FULLWIDTH HYPHEN-MINUS +10D6E ; Dash # Pd GARAY HYPHEN 10EAD ; Dash # Pd YEZIDI HYPHENATION MARK -# Total code points: 30 +# Total code points: 31 # ================================================ @@ -132,7 +133,8 @@ FF63 ; Quotation_Mark # Pe HALFWIDTH RIGHT CORNER BRACKET 0700..070A ; Terminal_Punctuation # Po [11] SYRIAC END OF PARAGRAPH..SYRIAC CONTRACTION 070C ; Terminal_Punctuation # Po SYRIAC HARKLEAN METOBELUS 07F8..07F9 ; Terminal_Punctuation # Po [2] NKO COMMA..NKO EXCLAMATION MARK -0830..083E ; Terminal_Punctuation # Po [15] SAMARITAN PUNCTUATION NEQUDAA..SAMARITAN PUNCTUATION ANNAAU +0830..0835 ; Terminal_Punctuation # Po [6] SAMARITAN PUNCTUATION NEQUDAA..SAMARITAN PUNCTUATION SHIYYAALAA +0837..083E ; Terminal_Punctuation # Po [8] SAMARITAN PUNCTUATION MELODIC QITSA..SAMARITAN PUNCTUATION ANNAAU 085E ; Terminal_Punctuation # Po MANDAIC PUNCTUATION 0964..0965 ; Terminal_Punctuation # Po [2] DEVANAGARI DANDA..DEVANAGARI DOUBLE DANDA 0E5A..0E5B ; Terminal_Punctuation # Po [2] THAI CHARACTER ANGKHANKHU..THAI CHARACTER KHOMUT @@ -149,13 +151,16 @@ FF63 ; Quotation_Mark # Pe HALFWIDTH RIGHT CORNER BRACKET 1808..1809 ; Terminal_Punctuation # Po [2] MONGOLIAN MANCHU COMMA..MONGOLIAN MANCHU FULL STOP 1944..1945 ; Terminal_Punctuation # Po [2] LIMBU EXCLAMATION MARK..LIMBU QUESTION MARK 1AA8..1AAB ; Terminal_Punctuation # Po [4] TAI THAM SIGN KAAN..TAI THAM SIGN SATKAANKUU +1B4E..1B4F ; Terminal_Punctuation # Po [2] BALINESE INVERTED CARIK SIKI..BALINESE INVERTED CARIK PAREREN 1B5A..1B5B ; Terminal_Punctuation # Po [2] BALINESE PANTI..BALINESE PAMADA 1B5D..1B5F ; Terminal_Punctuation # Po [3] BALINESE CARIK PAMUNGKAH..BALINESE CARIK PAREREN -1B7D..1B7E ; Terminal_Punctuation # Po [2] BALINESE PANTI LANTANG..BALINESE PAMADA LANTANG +1B7D..1B7F ; Terminal_Punctuation # Po [3] BALINESE PANTI LANTANG..BALINESE PANTI BAWAK 1C3B..1C3F ; Terminal_Punctuation # Po [5] LEPCHA PUNCTUATION TA-ROL..LEPCHA PUNCTUATION TSHOOK 1C7E..1C7F ; Terminal_Punctuation # Po [2] OL CHIKI PUNCTUATION MUCAAD..OL CHIKI PUNCTUATION DOUBLE MUCAAD +2024 ; Terminal_Punctuation # Po ONE DOT LEADER 203C..203D ; Terminal_Punctuation # Po [2] DOUBLE EXCLAMATION MARK..INTERROBANG 2047..2049 ; Terminal_Punctuation # Po [3] DOUBLE QUESTION MARK..EXCLAMATION QUESTION MARK +2CF9..2CFB ; Terminal_Punctuation # Po [3] COPTIC OLD NUBIAN FULL STOP..COPTIC OLD NUBIAN INDIRECT QUESTION MARK 2E2E ; Terminal_Punctuation # Po REVERSED QUESTION MARK 2E3C ; Terminal_Punctuation # Po STENOGRAPHIC FULL STOP 2E41 ; Terminal_Punctuation # Po REVERSED COMMA @@ -174,6 +179,8 @@ AA5D..AA5F ; Terminal_Punctuation # Po [3] CHAM PUNCTUATION DANDA..CHAM PUN AADF ; Terminal_Punctuation # Po TAI VIET SYMBOL KOI KOI AAF0..AAF1 ; Terminal_Punctuation # Po [2] MEETEI MAYEK CHEIKHAN..MEETEI MAYEK AHANG KHUDAM ABEB ; Terminal_Punctuation # Po MEETEI MAYEK CHEIKHEI +FE12 ; Terminal_Punctuation # Po PRESENTATION FORM FOR VERTICAL IDEOGRAPHIC FULL STOP +FE15..FE16 ; Terminal_Punctuation # Po [2] PRESENTATION FORM FOR VERTICAL EXCLAMATION MARK..PRESENTATION FORM FOR VERTICAL QUESTION MARK FE50..FE52 ; Terminal_Punctuation # Po [3] SMALL COMMA..SMALL FULL STOP FE54..FE57 ; Terminal_Punctuation # Po [4] SMALL SEMICOLON..SMALL EXCLAMATION MARK FF01 ; Terminal_Punctuation # Po FULLWIDTH EXCLAMATION MARK @@ -201,6 +208,7 @@ FF64 ; Terminal_Punctuation # Po HALFWIDTH IDEOGRAPHIC COMMA 111DE..111DF ; Terminal_Punctuation # Po [2] SHARADA SECTION MARK-1..SHARADA SECTION MARK-2 11238..1123C ; Terminal_Punctuation # Po [5] KHOJKI DANDA..KHOJKI DOUBLE SECTION MARK 112A9 ; Terminal_Punctuation # Po MULTANI SECTION MARK +113D4..113D5 ; Terminal_Punctuation # Po [2] TULU-TIGALARI DANDA..TULU-TIGALARI DOUBLE DANDA 1144B..1144D ; Terminal_Punctuation # Po [3] NEWA DANDA..NEWA COMMA 1145A..1145B ; Terminal_Punctuation # Po [2] NEWA DOUBLE COMMA..NEWA PLACEHOLDER MARK 115C2..115C5 ; Terminal_Punctuation # Po [4] SIDDHAM DANDA..SIDDHAM SEPARATOR BAR @@ -221,11 +229,12 @@ FF64 ; Terminal_Punctuation # Po HALFWIDTH IDEOGRAPHIC COMMA 16AF5 ; Terminal_Punctuation # Po BASSA VAH FULL STOP 16B37..16B39 ; Terminal_Punctuation # Po [3] PAHAWH HMONG SIGN VOS THOM..PAHAWH HMONG SIGN CIM CHEEM 16B44 ; Terminal_Punctuation # Po PAHAWH HMONG SIGN XAUS +16D6E..16D6F ; Terminal_Punctuation # Po [2] KIRAT RAI DANDA..KIRAT RAI DOUBLE DANDA 16E97..16E98 ; Terminal_Punctuation # Po [2] MEDEFAIDRIN COMMA..MEDEFAIDRIN FULL STOP 1BC9F ; Terminal_Punctuation # Po DUPLOYAN PUNCTUATION CHINOOK FULL STOP 1DA87..1DA8A ; Terminal_Punctuation # Po [4] SIGNWRITING COMMA..SIGNWRITING COLON -# Total code points: 278 +# Total code points: 291 # ================================================ @@ -430,6 +439,7 @@ FF41..FF46 ; Hex_Digit # L& [6] FULLWIDTH LATIN SMALL LETTER A..FULLWIDTH L # ================================================ 0345 ; Other_Alphabetic # Mn COMBINING GREEK YPOGEGRAMMENI +0363..036F ; Other_Alphabetic # Mn [13] COMBINING LATIN SMALL LETTER A..COMBINING LATIN SMALL LETTER X 05B0..05BD ; Other_Alphabetic # Mn [14] HEBREW POINT SHEVA..HEBREW POINT METEG 05BF ; Other_Alphabetic # Mn HEBREW POINT RAFE 05C1..05C2 ; Other_Alphabetic # Mn [2] HEBREW POINT SHIN DOT..HEBREW POINT SIN DOT @@ -450,6 +460,7 @@ FF41..FF46 ; Hex_Digit # L& [6] FULLWIDTH LATIN SMALL LETTER A..FULLWIDTH L 081B..0823 ; Other_Alphabetic # Mn [9] SAMARITAN MARK EPENTHETIC YUT..SAMARITAN VOWEL SIGN A 0825..0827 ; Other_Alphabetic # Mn [3] SAMARITAN VOWEL SIGN SHORT A..SAMARITAN VOWEL SIGN U 0829..082C ; Other_Alphabetic # Mn [4] SAMARITAN VOWEL SIGN LONG I..SAMARITAN VOWEL SIGN SUKUN +0897 ; Other_Alphabetic # Mn ARABIC PEPET 08D4..08DF ; Other_Alphabetic # Mn [12] ARABIC SMALL HIGH WORD AR-RUB..ARABIC SMALL HIGH WORD WAQFA 08E3..08E9 ; Other_Alphabetic # Mn [7] ARABIC TURNED DAMMA BELOW..ARABIC CURLY KASRATAN 08F0..0902 ; Other_Alphabetic # Mn [19] ARABIC OPEN FATHATAN..DEVANAGARI SIGN ANUSVARA @@ -634,7 +645,7 @@ FF41..FF46 ; Hex_Digit # L& [6] FULLWIDTH LATIN SMALL LETTER A..FULLWIDTH L 1C2C..1C33 ; Other_Alphabetic # Mn [8] LEPCHA VOWEL SIGN E..LEPCHA CONSONANT SIGN T 1C34..1C35 ; Other_Alphabetic # Mc [2] LEPCHA CONSONANT SIGN NYIN-DO..LEPCHA CONSONANT SIGN KANG 1C36 ; Other_Alphabetic # Mn LEPCHA SIGN RAN -1DE7..1DF4 ; Other_Alphabetic # Mn [14] COMBINING LATIN SMALL LETTER ALPHA..COMBINING LATIN SMALL LETTER U WITH DIAERESIS +1DD3..1DF4 ; Other_Alphabetic # Mn [34] COMBINING LATIN SMALL LETTER FLATTENED OPEN A ABOVE..COMBINING LATIN SMALL LETTER U WITH DIAERESIS 24B6..24E9 ; Other_Alphabetic # So [52] CIRCLED LATIN CAPITAL LETTER A..CIRCLED LATIN SMALL LETTER Z 2DE0..2DFF ; Other_Alphabetic # Mn [32] COMBINING CYRILLIC LETTER BE..COMBINING CYRILLIC LETTER IOTIFIED BIG YUS A674..A67B ; Other_Alphabetic # Mn [8] COMBINING CYRILLIC LETTER UKRAINIAN IE..COMBINING CYRILLIC LETTER OMEGA @@ -689,7 +700,9 @@ FB1E ; Other_Alphabetic # Mn HEBREW POINT JUDEO-SPANISH VARIKA 10A05..10A06 ; Other_Alphabetic # Mn [2] KHAROSHTHI VOWEL SIGN E..KHAROSHTHI VOWEL SIGN O 10A0C..10A0F ; Other_Alphabetic # Mn [4] KHAROSHTHI VOWEL LENGTH MARK..KHAROSHTHI SIGN VISARGA 10D24..10D27 ; Other_Alphabetic # Mn [4] HANIFI ROHINGYA SIGN HARBAHAY..HANIFI ROHINGYA SIGN TASSI +10D69 ; Other_Alphabetic # Mn GARAY VOWEL SIGN E 10EAB..10EAC ; Other_Alphabetic # Mn [2] YEZIDI COMBINING HAMZA MARK..YEZIDI COMBINING MADDA MARK +10EFC ; Other_Alphabetic # Mn ARABIC COMBINING ALEF OVERLAY 11000 ; Other_Alphabetic # Mc BRAHMI SIGN CANDRABINDU 11001 ; Other_Alphabetic # Mn BRAHMI SIGN ANUSVARA 11002 ; Other_Alphabetic # Mc BRAHMI SIGN VISARGA @@ -732,6 +745,12 @@ FB1E ; Other_Alphabetic # Mn HEBREW POINT JUDEO-SPANISH VARIKA 1134B..1134C ; Other_Alphabetic # Mc [2] GRANTHA VOWEL SIGN OO..GRANTHA VOWEL SIGN AU 11357 ; Other_Alphabetic # Mc GRANTHA AU LENGTH MARK 11362..11363 ; Other_Alphabetic # Mc [2] GRANTHA VOWEL SIGN VOCALIC L..GRANTHA VOWEL SIGN VOCALIC LL +113B8..113BA ; Other_Alphabetic # Mc [3] TULU-TIGALARI VOWEL SIGN AA..TULU-TIGALARI VOWEL SIGN II +113BB..113C0 ; Other_Alphabetic # Mn [6] TULU-TIGALARI VOWEL SIGN U..TULU-TIGALARI VOWEL SIGN VOCALIC LL +113C2 ; Other_Alphabetic # Mc TULU-TIGALARI VOWEL SIGN EE +113C5 ; Other_Alphabetic # Mc TULU-TIGALARI VOWEL SIGN AI +113C7..113CA ; Other_Alphabetic # Mc [4] TULU-TIGALARI VOWEL SIGN OO..TULU-TIGALARI SIGN CANDRA ANUNASIKA +113CC..113CD ; Other_Alphabetic # Mc [2] TULU-TIGALARI SIGN ANUSVARA..TULU-TIGALARI SIGN VISARGA 11435..11437 ; Other_Alphabetic # Mc [3] NEWA VOWEL SIGN AA..NEWA VOWEL SIGN II 11438..1143F ; Other_Alphabetic # Mn [8] NEWA VOWEL SIGN U..NEWA VOWEL SIGN AI 11440..11441 ; Other_Alphabetic # Mc [2] NEWA VOWEL SIGN O..NEWA VOWEL SIGN AU @@ -761,7 +780,9 @@ FB1E ; Other_Alphabetic # Mn HEBREW POINT JUDEO-SPANISH VARIKA 116AD ; Other_Alphabetic # Mn TAKRI VOWEL SIGN AA 116AE..116AF ; Other_Alphabetic # Mc [2] TAKRI VOWEL SIGN I..TAKRI VOWEL SIGN II 116B0..116B5 ; Other_Alphabetic # Mn [6] TAKRI VOWEL SIGN U..TAKRI VOWEL SIGN AU -1171D..1171F ; Other_Alphabetic # Mn [3] AHOM CONSONANT SIGN MEDIAL LA..AHOM CONSONANT SIGN MEDIAL LIGATING RA +1171D ; Other_Alphabetic # Mn AHOM CONSONANT SIGN MEDIAL LA +1171E ; Other_Alphabetic # Mc AHOM CONSONANT SIGN MEDIAL RA +1171F ; Other_Alphabetic # Mn AHOM CONSONANT SIGN MEDIAL LIGATING RA 11720..11721 ; Other_Alphabetic # Mc [2] AHOM VOWEL SIGN A..AHOM VOWEL SIGN AA 11722..11725 ; Other_Alphabetic # Mn [4] AHOM VOWEL SIGN I..AHOM VOWEL SIGN UU 11726 ; Other_Alphabetic # Mc AHOM VOWEL SIGN E @@ -818,6 +839,9 @@ FB1E ; Other_Alphabetic # Mn HEBREW POINT JUDEO-SPANISH VARIKA 11F36..11F3A ; Other_Alphabetic # Mn [5] KAWI VOWEL SIGN I..KAWI VOWEL SIGN VOCALIC R 11F3E..11F3F ; Other_Alphabetic # Mc [2] KAWI VOWEL SIGN E..KAWI VOWEL SIGN AI 11F40 ; Other_Alphabetic # Mn KAWI VOWEL SIGN EU +1611E..16129 ; Other_Alphabetic # Mn [12] GURUNG KHEMA VOWEL SIGN AA..GURUNG KHEMA VOWEL LENGTH MARK +1612A..1612C ; Other_Alphabetic # Mc [3] GURUNG KHEMA CONSONANT SIGN MEDIAL YA..GURUNG KHEMA CONSONANT SIGN MEDIAL HA +1612D..1612E ; Other_Alphabetic # Mn [2] GURUNG KHEMA SIGN ANUSVARA..GURUNG KHEMA CONSONANT SIGN MEDIAL RA 16F4F ; Other_Alphabetic # Mn MIAO SIGN CONSONANT MODIFIER BAR 16F51..16F87 ; Other_Alphabetic # Mc [55] MIAO SIGN ASPIRATION..MIAO VOWEL SIGN UI 16F8F..16F92 ; Other_Alphabetic # Mn [4] MIAO TONE RIGHT..MIAO TONE BELOW @@ -834,7 +858,7 @@ FB1E ; Other_Alphabetic # Mn HEBREW POINT JUDEO-SPANISH VARIKA 1F150..1F169 ; Other_Alphabetic # So [26] NEGATIVE CIRCLED LATIN CAPITAL LETTER A..NEGATIVE CIRCLED LATIN CAPITAL LETTER Z 1F170..1F189 ; Other_Alphabetic # So [26] NEGATIVE SQUARED LATIN CAPITAL LETTER A..NEGATIVE SQUARED LATIN CAPITAL LETTER Z -# Total code points: 1425 +# Total code points: 1495 # ================================================ @@ -849,7 +873,7 @@ FA70..FAD9 ; Ideographic # Lo [106] CJK COMPATIBILITY IDEOGRAPH-FA70..CJK COM 16FE4 ; Ideographic # Mn KHITAN SMALL SCRIPT FILLER 17000..187F7 ; Ideographic # Lo [6136] TANGUT IDEOGRAPH-17000..TANGUT IDEOGRAPH-187F7 18800..18CD5 ; Ideographic # Lo [1238] TANGUT COMPONENT-001..KHITAN SMALL SCRIPT CHARACTER-18CD5 -18D00..18D08 ; Ideographic # Lo [9] TANGUT IDEOGRAPH-18D00..TANGUT IDEOGRAPH-18D08 +18CFF..18D08 ; Ideographic # Lo [10] KHITAN SMALL SCRIPT CHARACTER-18CFF..TANGUT IDEOGRAPH-18D08 1B170..1B2FB ; Ideographic # Lo [396] NUSHU CHARACTER-1B170..NUSHU CHARACTER-1B2FB 20000..2A6DF ; Ideographic # Lo [42720] CJK UNIFIED IDEOGRAPH-20000..CJK UNIFIED IDEOGRAPH-2A6DF 2A700..2B739 ; Ideographic # Lo [4154] CJK UNIFIED IDEOGRAPH-2A700..CJK UNIFIED IDEOGRAPH-2B739 @@ -861,7 +885,7 @@ FA70..FAD9 ; Ideographic # Lo [106] CJK COMPATIBILITY IDEOGRAPH-FA70..CJK COM 30000..3134A ; Ideographic # Lo [4939] CJK UNIFIED IDEOGRAPH-30000..CJK UNIFIED IDEOGRAPH-3134A 31350..323AF ; Ideographic # Lo [4192] CJK UNIFIED IDEOGRAPH-31350..CJK UNIFIED IDEOGRAPH-323AF -# Total code points: 106476 +# Total code points: 106477 # ================================================ @@ -932,6 +956,7 @@ FA70..FAD9 ; Ideographic # Lo [106] CJK COMPATIBILITY IDEOGRAPH-FA70..CJK COM 0D3B..0D3C ; Diacritic # Mn [2] MALAYALAM SIGN VERTICAL BAR VIRAMA..MALAYALAM SIGN CIRCULAR VIRAMA 0D4D ; Diacritic # Mn MALAYALAM SIGN VIRAMA 0DCA ; Diacritic # Mn SINHALA SIGN AL-LAKUNA +0E3A ; Diacritic # Mn THAI CHARACTER PHINTHU 0E47..0E4C ; Diacritic # Mn [6] THAI CHARACTER MAITAIKHU..THAI CHARACTER THANTHAKHAT 0E4E ; Diacritic # Mn THAI CHARACTER YAMAKKAN 0EBA ; Diacritic # Mn LAO SIGN PALI VIRAMA @@ -955,9 +980,11 @@ FA70..FAD9 ; Ideographic # Lo [106] CJK COMPATIBILITY IDEOGRAPH-FA70..CJK COM 135D..135F ; Diacritic # Mn [3] ETHIOPIC COMBINING GEMINATION AND VOWEL LENGTH MARK..ETHIOPIC COMBINING GEMINATION MARK 1714 ; Diacritic # Mn TAGALOG SIGN VIRAMA 1715 ; Diacritic # Mc TAGALOG SIGN PAMUDPOD +1734 ; Diacritic # Mc HANUNOO SIGN PAMUDPOD 17C9..17D3 ; Diacritic # Mn [11] KHMER SIGN MUUSIKATOAN..KHMER SIGN BATHAMASAT 17DD ; Diacritic # Mn KHMER SIGN ATTHACAN 1939..193B ; Diacritic # Mn [3] LIMBU SIGN MUKPHRENG..LIMBU SIGN SA-I +1A60 ; Diacritic # Mn TAI THAM SIGN SAKOT 1A75..1A7C ; Diacritic # Mn [8] TAI THAM SIGN TONE-1..TAI THAM SIGN KHUEN-LUE KARAN 1A7F ; Diacritic # Mn TAI THAM COMBINING CRYPTOGRAMMIC DOT 1AB0..1ABD ; Diacritic # Mn [14] COMBINING DOUBLED CIRCUMFLEX ACCENT..COMBINING PARENTHESES BELOW @@ -968,6 +995,8 @@ FA70..FAD9 ; Ideographic # Lo [106] CJK COMPATIBILITY IDEOGRAPH-FA70..CJK COM 1B6B..1B73 ; Diacritic # Mn [9] BALINESE MUSICAL SYMBOL COMBINING TEGEH..BALINESE MUSICAL SYMBOL COMBINING GONG 1BAA ; Diacritic # Mc SUNDANESE SIGN PAMAAEH 1BAB ; Diacritic # Mn SUNDANESE SIGN VIRAMA +1BE6 ; Diacritic # Mn BATAK SIGN TOMPI +1BF2..1BF3 ; Diacritic # Mc [2] BATAK PANGOLAT..BATAK PANONGONAN 1C36..1C37 ; Diacritic # Mn [2] LEPCHA SIGN RAN..LEPCHA SIGN NUKTA 1C78..1C7D ; Diacritic # Lm [6] OL CHIKI MU TTUDDAG..OL CHIKI AHAD 1CD0..1CD2 ; Diacritic # Mn [3] VEDIC TONE KARSHANA..VEDIC TONE PRENKHA @@ -1006,6 +1035,8 @@ A720..A721 ; Diacritic # Sk [2] MODIFIER LETTER STRESS AND HIGH TONE..MODIF A788 ; Diacritic # Lm MODIFIER LETTER LOW CIRCUMFLEX ACCENT A789..A78A ; Diacritic # Sk [2] MODIFIER LETTER COLON..MODIFIER LETTER SHORT EQUALS SIGN A7F8..A7F9 ; Diacritic # Lm [2] MODIFIER LETTER CAPITAL H WITH STROKE..MODIFIER LETTER SMALL LIGATURE OE +A806 ; Diacritic # Mn SYLOTI NAGRI SIGN HASANTA +A82C ; Diacritic # Mn SYLOTI NAGRI SIGN ALTERNATE HASANTA A8C4 ; Diacritic # Mn SAURASHTRA SIGN VIRAMA A8E0..A8F1 ; Diacritic # Mn [18] COMBINING DEVANAGARI DIGIT ZERO..COMBINING DEVANAGARI SIGN AVAGRAHA A92B..A92D ; Diacritic # Mn [3] KAYAH LI TONE PLOPHU..KAYAH LI TONE CALYA PLOPHU @@ -1039,9 +1070,13 @@ FFE3 ; Diacritic # Sk FULLWIDTH MACRON 10780..10785 ; Diacritic # Lm [6] MODIFIER LETTER SMALL CAPITAL AA..MODIFIER LETTER SMALL B WITH HOOK 10787..107B0 ; Diacritic # Lm [42] MODIFIER LETTER SMALL DZ DIGRAPH..MODIFIER LETTER SMALL V WITH RIGHT HOOK 107B2..107BA ; Diacritic # Lm [9] MODIFIER LETTER SMALL CAPITAL Y..MODIFIER LETTER SMALL S WITH CURL +10A38..10A3A ; Diacritic # Mn [3] KHAROSHTHI SIGN BAR ABOVE..KHAROSHTHI SIGN DOT BELOW +10A3F ; Diacritic # Mn KHAROSHTHI VIRAMA 10AE5..10AE6 ; Diacritic # Mn [2] MANICHAEAN ABBREVIATION MARK ABOVE..MANICHAEAN ABBREVIATION MARK BELOW 10D22..10D23 ; Diacritic # Lo [2] HANIFI ROHINGYA MARK SAKIN..HANIFI ROHINGYA MARK NA KHONNA 10D24..10D27 ; Diacritic # Mn [4] HANIFI ROHINGYA SIGN HARBAHAY..HANIFI ROHINGYA SIGN TASSI +10D4E ; Diacritic # Lm GARAY VOWEL LENGTH MARK +10D69..10D6D ; Diacritic # Mn [5] GARAY VOWEL SIGN E..GARAY CONSONANT NASALIZATION MARK 10EFD..10EFF ; Diacritic # Mn [3] ARABIC SMALL LOW WORD SAKTA..ARABIC SMALL LOW WORD MADDA 10F46..10F50 ; Diacritic # Mn [11] SOGDIAN COMBINING DOT BELOW..SOGDIAN COMBINING STROKE BELOW 10F82..10F85 ; Diacritic # Mn [4] OLD UYGHUR COMBINING DOT ABOVE..OLD UYGHUR COMBINING TWO DOTS BELOW @@ -1055,10 +1090,16 @@ FFE3 ; Diacritic # Sk FULLWIDTH MACRON 11235 ; Diacritic # Mc KHOJKI SIGN VIRAMA 11236 ; Diacritic # Mn KHOJKI SIGN NUKTA 112E9..112EA ; Diacritic # Mn [2] KHUDAWADI SIGN NUKTA..KHUDAWADI SIGN VIRAMA -1133C ; Diacritic # Mn GRANTHA SIGN NUKTA +1133B..1133C ; Diacritic # Mn [2] COMBINING BINDU BELOW..GRANTHA SIGN NUKTA 1134D ; Diacritic # Mc GRANTHA SIGN VIRAMA 11366..1136C ; Diacritic # Mn [7] COMBINING GRANTHA DIGIT ZERO..COMBINING GRANTHA DIGIT SIX 11370..11374 ; Diacritic # Mn [5] COMBINING GRANTHA LETTER A..COMBINING GRANTHA LETTER PA +113CE ; Diacritic # Mn TULU-TIGALARI SIGN VIRAMA +113CF ; Diacritic # Mc TULU-TIGALARI SIGN LOOPED VIRAMA +113D0 ; Diacritic # Mn TULU-TIGALARI CONJOINER +113D2 ; Diacritic # Mn TULU-TIGALARI GEMINATION MARK +113D3 ; Diacritic # Lo TULU-TIGALARI SIGN PLUTA +113E1..113E2 ; Diacritic # Mn [2] TULU-TIGALARI VEDIC TONE SVARITA..TULU-TIGALARI VEDIC TONE ANUDATTA 11442 ; Diacritic # Mn NEWA SIGN VIRAMA 11446 ; Diacritic # Mn NEWA SIGN NUKTA 114C2..114C3 ; Diacritic # Mn [2] TIRHUTA SIGN VIRAMA..TIRHUTA SIGN NUKTA @@ -1079,9 +1120,14 @@ FFE3 ; Diacritic # Sk FULLWIDTH MACRON 11D42 ; Diacritic # Mn MASARAM GONDI SIGN NUKTA 11D44..11D45 ; Diacritic # Mn [2] MASARAM GONDI SIGN HALANTA..MASARAM GONDI VIRAMA 11D97 ; Diacritic # Mn GUNJALA GONDI VIRAMA +11F41 ; Diacritic # Mc KAWI SIGN KILLER +11F42 ; Diacritic # Mn KAWI CONJOINER +11F5A ; Diacritic # Mn KAWI SIGN NUKTA 13447..13455 ; Diacritic # Mn [15] EGYPTIAN HIEROGLYPH MODIFIER DAMAGED AT TOP START..EGYPTIAN HIEROGLYPH MODIFIER DAMAGED +1612F ; Diacritic # Mn GURUNG KHEMA SIGN THOLHOMA 16AF0..16AF4 ; Diacritic # Mn [5] BASSA VAH COMBINING HIGH TONE..BASSA VAH COMBINING HIGH-LOW TONE 16B30..16B36 ; Diacritic # Mn [7] PAHAWH HMONG MARK CIM TUB..PAHAWH HMONG MARK CIM TAUM +16D6B..16D6C ; Diacritic # Lm [2] KIRAT RAI SIGN VIRAMA..KIRAT RAI SIGN SAAT 16F8F..16F92 ; Diacritic # Mn [4] MIAO TONE RIGHT..MIAO TONE BELOW 16F93..16F9F ; Diacritic # Lm [13] MIAO LETTER TONE-2..MIAO LETTER REFORMED TONE-8 16FF0..16FF1 ; Diacritic # Mc [2] VIETNAMESE ALTERNATE READING MARK CA..VIETNAMESE ALTERNATE READING MARK NHAY @@ -1099,11 +1145,12 @@ FFE3 ; Diacritic # Sk FULLWIDTH MACRON 1E130..1E136 ; Diacritic # Mn [7] NYIAKENG PUACHUE HMONG TONE-B..NYIAKENG PUACHUE HMONG TONE-D 1E2AE ; Diacritic # Mn TOTO SIGN RISING TONE 1E2EC..1E2EF ; Diacritic # Mn [4] WANCHO TONE TUP..WANCHO TONE KOINI +1E5EE..1E5EF ; Diacritic # Mn [2] OL ONAL SIGN MU..OL ONAL SIGN IKIR 1E8D0..1E8D6 ; Diacritic # Mn [7] MENDE KIKAKUI COMBINING NUMBER TEENS..MENDE KIKAKUI COMBINING NUMBER MILLIONS 1E944..1E946 ; Diacritic # Mn [3] ADLAM ALIF LENGTHENER..ADLAM GEMINATION MARK 1E948..1E94A ; Diacritic # Mn [3] ADLAM CONSONANT MODIFIER..ADLAM NUKTA -# Total code points: 1144 +# Total code points: 1178 # ================================================ @@ -1111,6 +1158,8 @@ FFE3 ; Diacritic # Sk FULLWIDTH MACRON 02D0..02D1 ; Extender # Lm [2] MODIFIER LETTER TRIANGULAR COLON..MODIFIER LETTER HALF TRIANGULAR COLON 0640 ; Extender # Lm ARABIC TATWEEL 07FA ; Extender # Lm NKO LAJANYALAN +0A71 ; Extender # Mn GURMUKHI ADDAK +0AFB ; Extender # Mn GUJARATI SIGN SHADDA 0B55 ; Extender # Mn ORIYA SIGN OVERLINE 0E46 ; Extender # Lm THAI CHARACTER MAIYAMOK 0EC6 ; Extender # Lm LAO KO LA @@ -1132,16 +1181,23 @@ AADD ; Extender # Lm TAI VIET SYMBOL SAM AAF3..AAF4 ; Extender # Lm [2] MEETEI MAYEK SYLLABLE REPETITION MARK..MEETEI MAYEK WORD REPETITION MARK FF70 ; Extender # Lm HALFWIDTH KATAKANA-HIRAGANA PROLONGED SOUND MARK 10781..10782 ; Extender # Lm [2] MODIFIER LETTER SUPERSCRIPT TRIANGULAR COLON..MODIFIER LETTER SUPERSCRIPT HALF TRIANGULAR COLON +10D4E ; Extender # Lm GARAY VOWEL LENGTH MARK +10D6A ; Extender # Mn GARAY CONSONANT GEMINATION MARK +10D6F ; Extender # Lm GARAY REDUPLICATION MARK +11237 ; Extender # Mn KHOJKI SIGN SHADDA 1135D ; Extender # Lo GRANTHA SIGN PLUTA +113D2 ; Extender # Mn TULU-TIGALARI GEMINATION MARK +113D3 ; Extender # Lo TULU-TIGALARI SIGN PLUTA 115C6..115C8 ; Extender # Po [3] SIDDHAM REPETITION MARK-1..SIDDHAM REPETITION MARK-3 11A98 ; Extender # Mn SOYOMBO GEMINATION MARK 16B42..16B43 ; Extender # Lm [2] PAHAWH HMONG SIGN VOS NRUA..PAHAWH HMONG SIGN IB YAM 16FE0..16FE1 ; Extender # Lm [2] TANGUT ITERATION MARK..NUSHU ITERATION MARK 16FE3 ; Extender # Lm OLD CHINESE ITERATION MARK 1E13C..1E13D ; Extender # Lm [2] NYIAKENG PUACHUE HMONG SIGN XW XW..NYIAKENG PUACHUE HMONG SYLLABLE LENGTHENER +1E5EF ; Extender # Mn OL ONAL SIGN IKIR 1E944..1E946 ; Extender # Mn [3] ADLAM ALIF LENGTHENER..ADLAM GEMINATION MARK -# Total code points: 50 +# Total code points: 59 # ================================================ @@ -1217,27 +1273,51 @@ FFFFE..FFFFF ; Noncharacter_Code_Point # Cn [2] <noncharacter-FFFFE>..<noncha 0B57 ; Other_Grapheme_Extend # Mc ORIYA AU LENGTH MARK 0BBE ; Other_Grapheme_Extend # Mc TAMIL VOWEL SIGN AA 0BD7 ; Other_Grapheme_Extend # Mc TAMIL AU LENGTH MARK +0CC0 ; Other_Grapheme_Extend # Mc KANNADA VOWEL SIGN II 0CC2 ; Other_Grapheme_Extend # Mc KANNADA VOWEL SIGN UU +0CC7..0CC8 ; Other_Grapheme_Extend # Mc [2] KANNADA VOWEL SIGN EE..KANNADA VOWEL SIGN AI +0CCA..0CCB ; Other_Grapheme_Extend # Mc [2] KANNADA VOWEL SIGN O..KANNADA VOWEL SIGN OO 0CD5..0CD6 ; Other_Grapheme_Extend # Mc [2] KANNADA LENGTH MARK..KANNADA AI LENGTH MARK 0D3E ; Other_Grapheme_Extend # Mc MALAYALAM VOWEL SIGN AA 0D57 ; Other_Grapheme_Extend # Mc MALAYALAM AU LENGTH MARK 0DCF ; Other_Grapheme_Extend # Mc SINHALA VOWEL SIGN AELA-PILLA 0DDF ; Other_Grapheme_Extend # Mc SINHALA VOWEL SIGN GAYANUKITTA +1715 ; Other_Grapheme_Extend # Mc TAGALOG SIGN PAMUDPOD +1734 ; Other_Grapheme_Extend # Mc HANUNOO SIGN PAMUDPOD 1B35 ; Other_Grapheme_Extend # Mc BALINESE VOWEL SIGN TEDUNG +1B3B ; Other_Grapheme_Extend # Mc BALINESE VOWEL SIGN RA REPA TEDUNG +1B3D ; Other_Grapheme_Extend # Mc BALINESE VOWEL SIGN LA LENGA TEDUNG +1B43..1B44 ; Other_Grapheme_Extend # Mc [2] BALINESE VOWEL SIGN PEPET TEDUNG..BALINESE ADEG ADEG +1BAA ; Other_Grapheme_Extend # Mc SUNDANESE SIGN PAMAAEH +1BF2..1BF3 ; Other_Grapheme_Extend # Mc [2] BATAK PANGOLAT..BATAK PANONGONAN 200C ; Other_Grapheme_Extend # Cf ZERO WIDTH NON-JOINER 302E..302F ; Other_Grapheme_Extend # Mc [2] HANGUL SINGLE DOT TONE MARK..HANGUL DOUBLE DOT TONE MARK +A953 ; Other_Grapheme_Extend # Mc REJANG VIRAMA +A9C0 ; Other_Grapheme_Extend # Mc JAVANESE PANGKON FF9E..FF9F ; Other_Grapheme_Extend # Lm [2] HALFWIDTH KATAKANA VOICED SOUND MARK..HALFWIDTH KATAKANA SEMI-VOICED SOUND MARK +111C0 ; Other_Grapheme_Extend # Mc SHARADA SIGN VIRAMA +11235 ; Other_Grapheme_Extend # Mc KHOJKI SIGN VIRAMA 1133E ; Other_Grapheme_Extend # Mc GRANTHA VOWEL SIGN AA +1134D ; Other_Grapheme_Extend # Mc GRANTHA SIGN VIRAMA 11357 ; Other_Grapheme_Extend # Mc GRANTHA AU LENGTH MARK +113B8 ; Other_Grapheme_Extend # Mc TULU-TIGALARI VOWEL SIGN AA +113C2 ; Other_Grapheme_Extend # Mc TULU-TIGALARI VOWEL SIGN EE +113C5 ; Other_Grapheme_Extend # Mc TULU-TIGALARI VOWEL SIGN AI +113C7..113C9 ; Other_Grapheme_Extend # Mc [3] TULU-TIGALARI VOWEL SIGN OO..TULU-TIGALARI AU LENGTH MARK +113CF ; Other_Grapheme_Extend # Mc TULU-TIGALARI SIGN LOOPED VIRAMA 114B0 ; Other_Grapheme_Extend # Mc TIRHUTA VOWEL SIGN AA 114BD ; Other_Grapheme_Extend # Mc TIRHUTA VOWEL SIGN SHORT O 115AF ; Other_Grapheme_Extend # Mc SIDDHAM VOWEL SIGN AA +116B6 ; Other_Grapheme_Extend # Mc TAKRI SIGN VIRAMA 11930 ; Other_Grapheme_Extend # Mc DIVES AKURU VOWEL SIGN AA -1D165 ; Other_Grapheme_Extend # Mc MUSICAL SYMBOL COMBINING STEM -1D16E..1D172 ; Other_Grapheme_Extend # Mc [5] MUSICAL SYMBOL COMBINING FLAG-1..MUSICAL SYMBOL COMBINING FLAG-5 +1193D ; Other_Grapheme_Extend # Mc DIVES AKURU SIGN HALANTA +11F41 ; Other_Grapheme_Extend # Mc KAWI SIGN KILLER +16FF0..16FF1 ; Other_Grapheme_Extend # Mc [2] VIETNAMESE ALTERNATE READING MARK CA..VIETNAMESE ALTERNATE READING MARK NHAY +1D165..1D166 ; Other_Grapheme_Extend # Mc [2] MUSICAL SYMBOL COMBINING STEM..MUSICAL SYMBOL COMBINING SPRECHGESANG STEM +1D16D..1D172 ; Other_Grapheme_Extend # Mc [6] MUSICAL SYMBOL COMBINING AUGMENTATION DOT..MUSICAL SYMBOL COMBINING FLAG-5 E0020..E007F ; Other_Grapheme_Extend # Cf [96] TAG SPACE..CANCEL TAG -# Total code points: 127 +# Total code points: 160 # ================================================ @@ -1462,13 +1542,16 @@ FF65 ; Other_ID_Continue # Po HALFWIDTH KATAKANA MIDDLE DOT 1809 ; Sentence_Terminal # Po MONGOLIAN MANCHU FULL STOP 1944..1945 ; Sentence_Terminal # Po [2] LIMBU EXCLAMATION MARK..LIMBU QUESTION MARK 1AA8..1AAB ; Sentence_Terminal # Po [4] TAI THAM SIGN KAAN..TAI THAM SIGN SATKAANKUU +1B4E..1B4F ; Sentence_Terminal # Po [2] BALINESE INVERTED CARIK SIKI..BALINESE INVERTED CARIK PAREREN 1B5A..1B5B ; Sentence_Terminal # Po [2] BALINESE PANTI..BALINESE PAMADA 1B5E..1B5F ; Sentence_Terminal # Po [2] BALINESE CARIK SIKI..BALINESE CARIK PAREREN -1B7D..1B7E ; Sentence_Terminal # Po [2] BALINESE PANTI LANTANG..BALINESE PAMADA LANTANG +1B7D..1B7F ; Sentence_Terminal # Po [3] BALINESE PANTI LANTANG..BALINESE PANTI BAWAK 1C3B..1C3C ; Sentence_Terminal # Po [2] LEPCHA PUNCTUATION TA-ROL..LEPCHA PUNCTUATION NYET THYOOM TA-ROL 1C7E..1C7F ; Sentence_Terminal # Po [2] OL CHIKI PUNCTUATION MUCAAD..OL CHIKI PUNCTUATION DOUBLE MUCAAD +2024 ; Sentence_Terminal # Po ONE DOT LEADER 203C..203D ; Sentence_Terminal # Po [2] DOUBLE EXCLAMATION MARK..INTERROBANG 2047..2049 ; Sentence_Terminal # Po [3] DOUBLE QUESTION MARK..EXCLAMATION QUESTION MARK +2CF9..2CFB ; Sentence_Terminal # Po [3] COPTIC OLD NUBIAN FULL STOP..COPTIC OLD NUBIAN INDIRECT QUESTION MARK 2E2E ; Sentence_Terminal # Po REVERSED QUESTION MARK 2E3C ; Sentence_Terminal # Po STENOGRAPHIC FULL STOP 2E53..2E54 ; Sentence_Terminal # Po [2] MEDIEVAL EXCLAMATION MARK..MEDIEVAL QUESTION MARK @@ -1484,6 +1567,8 @@ A9C8..A9C9 ; Sentence_Terminal # Po [2] JAVANESE PADA LINGSA..JAVANESE PADA AA5D..AA5F ; Sentence_Terminal # Po [3] CHAM PUNCTUATION DANDA..CHAM PUNCTUATION TRIPLE DANDA AAF0..AAF1 ; Sentence_Terminal # Po [2] MEETEI MAYEK CHEIKHAN..MEETEI MAYEK AHANG KHUDAM ABEB ; Sentence_Terminal # Po MEETEI MAYEK CHEIKHEI +FE12 ; Sentence_Terminal # Po PRESENTATION FORM FOR VERTICAL IDEOGRAPHIC FULL STOP +FE15..FE16 ; Sentence_Terminal # Po [2] PRESENTATION FORM FOR VERTICAL EXCLAMATION MARK..PRESENTATION FORM FOR VERTICAL QUESTION MARK FE52 ; Sentence_Terminal # Po SMALL FULL STOP FE56..FE57 ; Sentence_Terminal # Po [2] SMALL QUESTION MARK..SMALL EXCLAMATION MARK FF01 ; Sentence_Terminal # Po FULLWIDTH EXCLAMATION MARK @@ -1502,6 +1587,7 @@ FF61 ; Sentence_Terminal # Po HALFWIDTH IDEOGRAPHIC FULL STOP 11238..11239 ; Sentence_Terminal # Po [2] KHOJKI DANDA..KHOJKI DOUBLE DANDA 1123B..1123C ; Sentence_Terminal # Po [2] KHOJKI SECTION MARK..KHOJKI DOUBLE SECTION MARK 112A9 ; Sentence_Terminal # Po MULTANI SECTION MARK +113D4..113D5 ; Sentence_Terminal # Po [2] TULU-TIGALARI DANDA..TULU-TIGALARI DOUBLE DANDA 1144B..1144C ; Sentence_Terminal # Po [2] NEWA DANDA..NEWA DOUBLE DANDA 115C2..115C3 ; Sentence_Terminal # Po [2] SIDDHAM DANDA..SIDDHAM DOUBLE DANDA 115C9..115D7 ; Sentence_Terminal # Po [15] SIDDHAM END OF TEXT MARK..SIDDHAM SECTION MARK WITH CIRCLES AND FOUR ENCLOSURES @@ -1518,11 +1604,12 @@ FF61 ; Sentence_Terminal # Po HALFWIDTH IDEOGRAPHIC FULL STOP 16AF5 ; Sentence_Terminal # Po BASSA VAH FULL STOP 16B37..16B38 ; Sentence_Terminal # Po [2] PAHAWH HMONG SIGN VOS THOM..PAHAWH HMONG SIGN VOS TSHAB CEEB 16B44 ; Sentence_Terminal # Po PAHAWH HMONG SIGN XAUS +16D6E..16D6F ; Sentence_Terminal # Po [2] KIRAT RAI DANDA..KIRAT RAI DOUBLE DANDA 16E98 ; Sentence_Terminal # Po MEDEFAIDRIN FULL STOP 1BC9F ; Sentence_Terminal # Po DUPLOYAN PUNCTUATION CHINOOK FULL STOP 1DA88 ; Sentence_Terminal # Po SIGNWRITING FULL STOP -# Total code points: 156 +# Total code points: 170 # ================================================ @@ -1640,8 +1727,8 @@ E0100..E01EF ; Variation_Selector # Mn [240] VARIATION SELECTOR-17..VARIATION S 239B..23B3 ; Pattern_Syntax # Sm [25] LEFT PARENTHESIS UPPER HOOK..SUMMATION BOTTOM 23B4..23DB ; Pattern_Syntax # So [40] TOP SQUARE BRACKET..FUSE 23DC..23E1 ; Pattern_Syntax # Sm [6] TOP PARENTHESIS..BOTTOM TORTOISE SHELL BRACKET -23E2..2426 ; Pattern_Syntax # So [69] WHITE TRAPEZIUM..SYMBOL FOR SUBSTITUTE FORM TWO -2427..243F ; Pattern_Syntax # Cn [25] <reserved-2427>..<reserved-243F> +23E2..2429 ; Pattern_Syntax # So [72] WHITE TRAPEZIUM..SYMBOL FOR DELETE MEDIUM SHADE FORM +242A..243F ; Pattern_Syntax # Cn [22] <reserved-242A>..<reserved-243F> 2440..244A ; Pattern_Syntax # So [11] OCR HOOK..OCR DOUBLE BACKSLASH 244B..245F ; Pattern_Syntax # Cn [21] <reserved-244B>..<reserved-245F> 2500..25B6 ; Pattern_Syntax # So [183] BOX DRAWINGS LIGHT HORIZONTAL..BLACK RIGHT-POINTING TRIANGLE @@ -1824,4 +1911,18 @@ FE45..FE46 ; Pattern_Syntax # Po [2] SESAME DOT..WHITE SESAME DOT # Total code points: 26 +# ================================================ + +0654..0655 ; Modifier_Combining_Mark # Mn [2] ARABIC HAMZA ABOVE..ARABIC HAMZA BELOW +0658 ; Modifier_Combining_Mark # Mn ARABIC MARK NOON GHUNNA +06DC ; Modifier_Combining_Mark # Mn ARABIC SMALL HIGH SEEN +06E3 ; Modifier_Combining_Mark # Mn ARABIC SMALL LOW SEEN +06E7..06E8 ; Modifier_Combining_Mark # Mn [2] ARABIC SMALL HIGH YEH..ARABIC SMALL HIGH NOON +08CA..08CB ; Modifier_Combining_Mark # Mn [2] ARABIC SMALL HIGH FARSI YEH..ARABIC SMALL HIGH YEH BARREE WITH TWO DOTS BELOW +08CD..08CF ; Modifier_Combining_Mark # Mn [3] ARABIC SMALL HIGH ZAH..ARABIC LARGE ROUND DOT BELOW +08D3 ; Modifier_Combining_Mark # Mn ARABIC SMALL LOW WAW +08F3 ; Modifier_Combining_Mark # Mn ARABIC SMALL HIGH WAW + +# Total code points: 14 + # EOF diff --git a/src/java.base/share/data/unicodedata/PropertyValueAliases.txt b/src/java.base/share/data/unicodedata/PropertyValueAliases.txt index 2aa856104ca..97980e2d902 100644 --- a/src/java.base/share/data/unicodedata/PropertyValueAliases.txt +++ b/src/java.base/share/data/unicodedata/PropertyValueAliases.txt @@ -1,8 +1,8 @@ -# PropertyValueAliases-15.1.0.txt -# Date: 2023-08-07, 15:21:34 GMT -# Copyright (c) 2023 Unicode, Inc. +# PropertyValueAliases-16.0.0.txt +# Date: 2024-07-30, 19:59:00 GMT +# Copyright (c) 2024 Unicode, Inc. # Unicode and the Unicode Logo are registered trademarks of Unicode, Inc. in the U.S. and other countries. -# For terms of use, see https://www.unicode.org/terms_of_use.html +# For terms of use and license, see https://www.unicode.org/terms_of_use.html # # Unicode Character Database # For documentation, see https://www.unicode.org/reports/tr44/ @@ -92,6 +92,7 @@ age; 13.0 ; V13_0 age; 14.0 ; V14_0 age; 15.0 ; V15_0 age; 15.1 ; V15_1 +age; 16.0 ; V16_0 age; NA ; Unassigned # Alphabetic (Alpha) @@ -245,6 +246,7 @@ blk; Duployan ; Duployan blk; Early_Dynastic_Cuneiform ; Early_Dynastic_Cuneiform blk; Egyptian_Hieroglyph_Format_Controls; Egyptian_Hieroglyph_Format_Controls blk; Egyptian_Hieroglyphs ; Egyptian_Hieroglyphs +blk; Egyptian_Hieroglyphs_Ext_A ; Egyptian_Hieroglyphs_Extended_A blk; Elbasan ; Elbasan blk; Elymaic ; Elymaic blk; Emoticons ; Emoticons @@ -257,6 +259,7 @@ blk; Ethiopic_Ext ; Ethiopic_Extended blk; Ethiopic_Ext_A ; Ethiopic_Extended_A blk; Ethiopic_Ext_B ; Ethiopic_Extended_B blk; Ethiopic_Sup ; Ethiopic_Supplement +blk; Garay ; Garay blk; Geometric_Shapes ; Geometric_Shapes blk; Geometric_Shapes_Ext ; Geometric_Shapes_Extended blk; Georgian ; Georgian @@ -271,6 +274,7 @@ blk; Greek_Ext ; Greek_Extended blk; Gujarati ; Gujarati blk; Gunjala_Gondi ; Gunjala_Gondi blk; Gurmukhi ; Gurmukhi +blk; Gurung_Khema ; Gurung_Khema blk; Half_And_Full_Forms ; Halfwidth_And_Fullwidth_Forms blk; Half_Marks ; Combining_Half_Marks blk; Hangul ; Hangul_Syllables @@ -311,6 +315,7 @@ blk; Khmer ; Khmer blk; Khmer_Symbols ; Khmer_Symbols blk; Khojki ; Khojki blk; Khudawadi ; Khudawadi +blk; Kirat_Rai ; Kirat_Rai blk; Lao ; Lao blk; Latin_1_Sup ; Latin_1_Supplement ; Latin_1 blk; Latin_Ext_A ; Latin_Extended_A @@ -367,6 +372,7 @@ blk; Music ; Musical_Symbols blk; Myanmar ; Myanmar blk; Myanmar_Ext_A ; Myanmar_Extended_A blk; Myanmar_Ext_B ; Myanmar_Extended_B +blk; Myanmar_Ext_C ; Myanmar_Extended_C blk; Nabataean ; Nabataean blk; Nag_Mundari ; Nag_Mundari blk; Nandinagari ; Nandinagari @@ -380,6 +386,7 @@ blk; Nyiakeng_Puachue_Hmong ; Nyiakeng_Puachue_Hmong blk; OCR ; Optical_Character_Recognition blk; Ogham ; Ogham blk; Ol_Chiki ; Ol_Chiki +blk; Ol_Onal ; Ol_Onal blk; Old_Hungarian ; Old_Hungarian blk; Old_Italic ; Old_Italic blk; Old_North_Arabian ; Old_North_Arabian @@ -425,6 +432,7 @@ blk; Soyombo ; Soyombo blk; Specials ; Specials blk; Sundanese ; Sundanese blk; Sundanese_Sup ; Sundanese_Supplement +blk; Sunuwar ; Sunuwar blk; Sup_Arrows_A ; Supplemental_Arrows_A blk; Sup_Arrows_B ; Supplemental_Arrows_B blk; Sup_Arrows_C ; Supplemental_Arrows_C @@ -438,6 +446,7 @@ blk; Sutton_SignWriting ; Sutton_SignWriting blk; Syloti_Nagri ; Syloti_Nagri blk; Symbols_And_Pictographs_Ext_A ; Symbols_And_Pictographs_Extended_A blk; Symbols_For_Legacy_Computing ; Symbols_For_Legacy_Computing +blk; Symbols_For_Legacy_Computing_Sup ; Symbols_For_Legacy_Computing_Supplement blk; Syriac ; Syriac blk; Syriac_Sup ; Syriac_Supplement blk; Tagalog ; Tagalog @@ -460,8 +469,10 @@ blk; Thai ; Thai blk; Tibetan ; Tibetan blk; Tifinagh ; Tifinagh blk; Tirhuta ; Tirhuta +blk; Todhri ; Todhri blk; Toto ; Toto blk; Transport_And_Map ; Transport_And_Map_Symbols +blk; Tulu_Tigalari ; Tulu_Tigalari blk; UCAS ; Unified_Canadian_Aboriginal_Syllabics; Canadian_Syllabics blk; UCAS_Ext ; Unified_Canadian_Aboriginal_Syllabics_Extended blk; UCAS_Ext_A ; Unified_Canadian_Aboriginal_Syllabics_Extended_A @@ -909,6 +920,7 @@ InSC; Number_Joiner ; Number_Joiner InSC; Other ; Other InSC; Pure_Killer ; Pure_Killer InSC; Register_Shifter ; Register_Shifter +InSC; Reordering_Killer ; Reordering_Killer InSC; Syllable_Modifier ; Syllable_Modifier InSC; Tone_Letter ; Tone_Letter InSC; Tone_Mark ; Tone_Mark @@ -1008,6 +1020,7 @@ jg ; Heh_Goal ; Heh_Goal jg ; Heth ; Heth jg ; Kaf ; Kaf jg ; Kaph ; Kaph +jg ; Kashmiri_Yeh ; Kashmiri_Yeh jg ; Khaph ; Khaph jg ; Knotted_Heh ; Knotted_Heh jg ; Lam ; Lam @@ -1073,7 +1086,7 @@ jg ; Syriac_Waw ; Syriac_Waw jg ; Tah ; Tah jg ; Taw ; Taw jg ; Teh_Marbuta ; Teh_Marbuta -jg ; Teh_Marbuta_Goal ; Hamza_On_Heh_Goal +jg ; Teh_Marbuta_Goal ; Teh_Marbuta_Goal ; Hamza_On_Heh_Goal jg ; Teth ; Teth jg ; Thin_Yeh ; Thin_Yeh jg ; Vertical_Tail ; Vertical_Tail @@ -1165,6 +1178,11 @@ Lower; Y ; Yes ; T Math; N ; No ; F ; False Math; Y ; Yes ; T ; True +# Modifier_Combining_Mark (MCM) + +MCM; N ; No ; F ; False +MCM; Y ; Yes ; T ; True + # NFC_Quick_Check (NFC_QC) NFC_QC; M ; Maybe @@ -1326,6 +1344,7 @@ sc ; Egyp ; Egyptian_Hieroglyphs sc ; Elba ; Elbasan sc ; Elym ; Elymaic sc ; Ethi ; Ethiopic +sc ; Gara ; Garay sc ; Geor ; Georgian sc ; Glag ; Glagolitic sc ; Gong ; Gunjala_Gondi @@ -1334,6 +1353,7 @@ sc ; Goth ; Gothic sc ; Gran ; Grantha sc ; Grek ; Greek sc ; Gujr ; Gujarati +sc ; Gukh ; Gurung_Khema sc ; Guru ; Gurmukhi sc ; Hang ; Hangul sc ; Hani ; Han @@ -1356,6 +1376,7 @@ sc ; Khmr ; Khmer sc ; Khoj ; Khojki sc ; Kits ; Khitan_Small_Script sc ; Knda ; Kannada +sc ; Krai ; Kirat_Rai sc ; Kthi ; Kaithi sc ; Lana ; Tai_Tham sc ; Laoo ; Lao @@ -1392,6 +1413,7 @@ sc ; Nkoo ; Nko sc ; Nshu ; Nushu sc ; Ogam ; Ogham sc ; Olck ; Ol_Chiki +sc ; Onao ; Ol_Onal sc ; Orkh ; Old_Turkic sc ; Orya ; Oriya sc ; Osge ; Osage @@ -1423,6 +1445,7 @@ sc ; Sogo ; Old_Sogdian sc ; Sora ; Sora_Sompeng sc ; Soyo ; Soyombo sc ; Sund ; Sundanese +sc ; Sunu ; Sunuwar sc ; Sylo ; Syloti_Nagri sc ; Syrc ; Syriac sc ; Tagb ; Tagbanwa @@ -1440,7 +1463,9 @@ sc ; Thai ; Thai sc ; Tibt ; Tibetan sc ; Tirh ; Tirhuta sc ; Tnsa ; Tangsa +sc ; Todr ; Todhri sc ; Toto ; Toto +sc ; Tutg ; Tulu_Tigalari sc ; Ugar ; Ugaritic sc ; Vaii ; Vai sc ; Vith ; Vithkuqi @@ -1650,4 +1675,34 @@ XIDS; Y ; Yes ; T # @missing: 0000..10FFFF; cjkRSUnicode; <none> +# kEH_Cat (kEH_Cat) + +# @missing: 0000..10FFFF; kEH_Cat; <none> + +# kEH_Desc (kEH_Desc) + +# @missing: 0000..10FFFF; kEH_Desc; <none> + +# kEH_HG (kEH_HG) + +# @missing: 0000..10FFFF; kEH_HG; <none> + +# kEH_IFAO (kEH_IFAO) + +# @missing: 0000..10FFFF; kEH_IFAO; <none> + +# kEH_JSesh (kEH_JSesh) + +# @missing: 0000..10FFFF; kEH_JSesh; <none> + +# kEH_NoMirror (kEH_NoMirror) + +kEH_NoMirror; N ; No ; F ; False +kEH_NoMirror; Y ; Yes ; T ; True + +# kEH_NoRotate (kEH_NoRotate) + +kEH_NoRotate; N ; No ; F ; False +kEH_NoRotate; Y ; Yes ; T ; True + # EOF diff --git a/src/java.base/share/data/unicodedata/ReadMe.txt b/src/java.base/share/data/unicodedata/ReadMe.txt index 7f7ef848b30..81d489a0575 100644 --- a/src/java.base/share/data/unicodedata/ReadMe.txt +++ b/src/java.base/share/data/unicodedata/ReadMe.txt @@ -1,16 +1,17 @@ # Unicode Character Database -# Date: 2023-08-28 -# Copyright (c) 2023 Unicode, Inc. +# Date: 2024-08-25 +# Copyright (c) 2024 Unicode, Inc. # Unicode and the Unicode Logo are registered trademarks of Unicode, Inc. in the U.S. and other countries. -# For terms of use, see https://www.unicode.org/terms_of_use.html +# For terms of use and license, see https://www.unicode.org/terms_of_use.html # # For documentation, see the following: # NamesList.html # UAX #38, "Unicode Han Database (Unihan)" # UAX #44, "Unicode Character Database" # UTS #51, "Unicode Emoji" +# UAX #57, "Unicode Egyptian Hieroglyph Database" # -# The UAXes and UTS #51 can be accessed at https://www.unicode.org/versions/Unicode15.1.0/ +# The UAXes and UTS #51 can be accessed at https://www.unicode.org/versions/Unicode16.0.0/ This directory contains final data files -for the Unicode Character Database, for Version 15.1.0 of the Unicode Standard. +for the Unicode Character Database, for Version 16.0.0 of the Unicode Standard. diff --git a/src/java.base/share/data/unicodedata/Scripts.txt b/src/java.base/share/data/unicodedata/Scripts.txt index 0722c27ccef..14d48d94162 100644 --- a/src/java.base/share/data/unicodedata/Scripts.txt +++ b/src/java.base/share/data/unicodedata/Scripts.txt @@ -1,8 +1,8 @@ -# Scripts-15.1.0.txt -# Date: 2023-07-28, 16:01:07 GMT -# Copyright (c) 2023 Unicode, Inc. +# Scripts-16.0.0.txt +# Date: 2024-04-30, 21:48:40 GMT +# Copyright (c) 2024 Unicode, Inc. # Unicode and the Unicode Logo are registered trademarks of Unicode, Inc. in the U.S. and other countries. -# For terms of use, see https://www.unicode.org/terms_of_use.html +# For terms of use and license, see https://www.unicode.org/terms_of_use.html # # Unicode Character Database # For documentation, see https://www.unicode.org/reports/tr44/ @@ -224,7 +224,7 @@ 239B..23B3 ; Common # Sm [25] LEFT PARENTHESIS UPPER HOOK..SUMMATION BOTTOM 23B4..23DB ; Common # So [40] TOP SQUARE BRACKET..FUSE 23DC..23E1 ; Common # Sm [6] TOP PARENTHESIS..BOTTOM TORTOISE SHELL BRACKET -23E2..2426 ; Common # So [69] WHITE TRAPEZIUM..SYMBOL FOR SUBSTITUTE FORM TWO +23E2..2429 ; Common # So [72] WHITE TRAPEZIUM..SYMBOL FOR DELETE MEDIUM SHADE FORM 2440..244A ; Common # So [11] OCR HOOK..OCR DOUBLE BACKSLASH 2460..249B ; Common # No [60] CIRCLED DIGIT ONE..NUMBER TWENTY FULL STOP 249C..24E9 ; Common # So [78] PARENTHESIZED LATIN SMALL LETTER A..CIRCLED LATIN SMALL LETTER Z @@ -398,7 +398,7 @@ 3190..3191 ; Common # So [2] IDEOGRAPHIC ANNOTATION LINKING MARK..IDEOGRAPHIC ANNOTATION REVERSE MARK 3192..3195 ; Common # No [4] IDEOGRAPHIC ANNOTATION ONE MARK..IDEOGRAPHIC ANNOTATION FOUR MARK 3196..319F ; Common # So [10] IDEOGRAPHIC ANNOTATION TOP MARK..IDEOGRAPHIC ANNOTATION MAN MARK -31C0..31E3 ; Common # So [36] CJK STROKE T..CJK STROKE Q +31C0..31E5 ; Common # So [38] CJK STROKE T..CJK STROKE SZP 31EF ; Common # So IDEOGRAPHIC DESCRIPTION CHARACTER SUBTRACTION 3220..3229 ; Common # No [10] PARENTHESIZED IDEOGRAPH ONE..PARENTHESIZED IDEOGRAPH TEN 322A..3247 ; Common # So [30] PARENTHESIZED IDEOGRAPH MOON..CIRCLED IDEOGRAPH KOTO @@ -522,6 +522,9 @@ FFFC..FFFD ; Common # So [2] OBJECT REPLACEMENT CHARACTER..REPLACEMENT CHAR 101D0..101FC ; Common # So [45] PHAISTOS DISC SIGN PEDESTRIAN..PHAISTOS DISC SIGN WAVY BAND 102E1..102FB ; Common # No [27] COPTIC EPACT DIGIT ONE..COPTIC EPACT NUMBER NINE HUNDRED 1BCA0..1BCA3 ; Common # Cf [4] SHORTHAND FORMAT LETTER OVERLAP..SHORTHAND FORMAT UP STEP +1CC00..1CCEF ; Common # So [240] UP-POINTING GO-KART..OUTLINED LATIN CAPITAL LETTER Z +1CCF0..1CCF9 ; Common # Nd [10] OUTLINED DIGIT ZERO..OUTLINED DIGIT NINE +1CD00..1CEB3 ; Common # So [436] BLOCK OCTANT-3..BLACK RIGHT TRIANGLE CARET 1CF50..1CFC3 ; Common # So [116] ZNAMENNY NEUME KRYUK..ZNAMENNY NEUME PAUK 1D000..1D0F5 ; Common # So [246] BYZANTINE MUSICAL SYMBOL PSILI..BYZANTINE MUSICAL SYMBOL GORGON NEO KATO 1D100..1D126 ; Common # So [39] MUSICAL SYMBOL SINGLE BARLINE..MUSICAL SYMBOL DRUM CLEF-2 @@ -614,23 +617,23 @@ FFFC..FFFD ; Common # So [2] OBJECT REPLACEMENT CHARACTER..REPLACEMENT CHAR 1F850..1F859 ; Common # So [10] LEFTWARDS SANS-SERIF ARROW..UP DOWN SANS-SERIF ARROW 1F860..1F887 ; Common # So [40] WIDE-HEADED LEFTWARDS LIGHT BARB ARROW..WIDE-HEADED SOUTH WEST VERY HEAVY BARB ARROW 1F890..1F8AD ; Common # So [30] LEFTWARDS TRIANGLE ARROWHEAD..WHITE ARROW SHAFT WIDTH TWO THIRDS -1F8B0..1F8B1 ; Common # So [2] ARROW POINTING UPWARDS THEN NORTH WEST..ARROW POINTING RIGHTWARDS THEN CURVING SOUTH WEST +1F8B0..1F8BB ; Common # So [12] ARROW POINTING UPWARDS THEN NORTH WEST..SOUTH WEST ARROW FROM BAR +1F8C0..1F8C1 ; Common # So [2] LEFTWARDS ARROW FROM DOWNWARDS ARROW..RIGHTWARDS ARROW FROM DOWNWARDS ARROW 1F900..1FA53 ; Common # So [340] CIRCLED CROSS FORMEE WITH FOUR DOTS..BLACK CHESS KNIGHT-BISHOP 1FA60..1FA6D ; Common # So [14] XIANGQI RED GENERAL..XIANGQI BLACK SOLDIER 1FA70..1FA7C ; Common # So [13] BALLET SHOES..CRUTCH -1FA80..1FA88 ; Common # So [9] YO-YO..FLUTE -1FA90..1FABD ; Common # So [46] RINGED PLANET..WING -1FABF..1FAC5 ; Common # So [7] GOOSE..PERSON WITH CROWN -1FACE..1FADB ; Common # So [14] MOOSE..PEA POD -1FAE0..1FAE8 ; Common # So [9] MELTING FACE..SHAKING FACE +1FA80..1FA89 ; Common # So [10] YO-YO..HARP +1FA8F..1FAC6 ; Common # So [56] SHOVEL..FINGERPRINT +1FACE..1FADC ; Common # So [15] MOOSE..ROOT VEGETABLE +1FADF..1FAE9 ; Common # So [11] SPLATTER..FACE WITH BAGS UNDER EYES 1FAF0..1FAF8 ; Common # So [9] HAND WITH INDEX FINGER AND THUMB CROSSED..RIGHTWARDS PUSHING HAND 1FB00..1FB92 ; Common # So [147] BLOCK SEXTANT-1..UPPER HALF INVERSE MEDIUM SHADE AND LOWER HALF BLOCK -1FB94..1FBCA ; Common # So [55] LEFT HALF INVERSE MEDIUM SHADE AND RIGHT HALF BLOCK..WHITE UP-POINTING CHEVRON +1FB94..1FBEF ; Common # So [92] LEFT HALF INVERSE MEDIUM SHADE AND RIGHT HALF BLOCK..TOP LEFT JUSTIFIED LOWER RIGHT QUARTER BLACK CIRCLE 1FBF0..1FBF9 ; Common # Nd [10] SEGMENTED DIGIT ZERO..SEGMENTED DIGIT NINE E0001 ; Common # Cf LANGUAGE TAG E0020..E007F ; Common # Cf [96] TAG SPACE..CANCEL TAG -# Total code points: 8306 +# Total code points: 9053 # ================================================ @@ -673,10 +676,10 @@ A770 ; Latin # Lm MODIFIER LETTER US A771..A787 ; Latin # L& [23] LATIN SMALL LETTER DUM..LATIN SMALL LETTER INSULAR T A78B..A78E ; Latin # L& [4] LATIN CAPITAL LETTER SALTILLO..LATIN SMALL LETTER L WITH RETROFLEX HOOK AND BELT A78F ; Latin # Lo LATIN LETTER SINOLOGICAL DOT -A790..A7CA ; Latin # L& [59] LATIN CAPITAL LETTER N WITH DESCENDER..LATIN SMALL LETTER S WITH SHORT STROKE OVERLAY +A790..A7CD ; Latin # L& [62] LATIN CAPITAL LETTER N WITH DESCENDER..LATIN SMALL LETTER S WITH DIAGONAL STROKE A7D0..A7D1 ; Latin # L& [2] LATIN CAPITAL LETTER CLOSED INSULAR G..LATIN SMALL LETTER CLOSED INSULAR G A7D3 ; Latin # L& LATIN SMALL LETTER DOUBLE THORN -A7D5..A7D9 ; Latin # L& [5] LATIN SMALL LETTER DOUBLE WYNN..LATIN SMALL LETTER SIGMOID S +A7D5..A7DC ; Latin # L& [8] LATIN SMALL LETTER DOUBLE WYNN..LATIN CAPITAL LETTER LAMBDA WITH STROKE A7F2..A7F4 ; Latin # Lm [3] MODIFIER LETTER CAPITAL C..MODIFIER LETTER CAPITAL Q A7F5..A7F6 ; Latin # L& [2] LATIN CAPITAL LETTER REVERSED HALF H..LATIN SMALL LETTER REVERSED HALF H A7F7 ; Latin # Lo LATIN EPIGRAPHIC LETTER SIDEWAYS I @@ -699,7 +702,7 @@ FF41..FF5A ; Latin # L& [26] FULLWIDTH LATIN SMALL LETTER A..FULLWIDTH LATIN 1DF0B..1DF1E ; Latin # L& [20] LATIN SMALL LETTER ESH WITH DOUBLE BAR..LATIN SMALL LETTER S WITH CURL 1DF25..1DF2A ; Latin # L& [6] LATIN SMALL LETTER D WITH MID-HEIGHT LEFT HOOK..LATIN SMALL LETTER T WITH MID-HEIGHT LEFT HOOK -# Total code points: 1481 +# Total code points: 1487 # ================================================ @@ -769,7 +772,7 @@ AB65 ; Greek # L& GREEK LETTER SMALL CAPITAL OMEGA 0487 ; Cyrillic # Mn COMBINING CYRILLIC POKRYTIE 0488..0489 ; Cyrillic # Me [2] COMBINING CYRILLIC HUNDRED THOUSANDS SIGN..COMBINING CYRILLIC MILLIONS SIGN 048A..052F ; Cyrillic # L& [166] CYRILLIC CAPITAL LETTER SHORT I WITH TAIL..CYRILLIC SMALL LETTER EL WITH DESCENDER -1C80..1C88 ; Cyrillic # L& [9] CYRILLIC SMALL LETTER ROUNDED VE..CYRILLIC SMALL LETTER UNBLENDED UK +1C80..1C8A ; Cyrillic # L& [11] CYRILLIC SMALL LETTER ROUNDED VE..CYRILLIC SMALL LETTER TJE 1D2B ; Cyrillic # L& CYRILLIC LETTER SMALL CAPITAL EL 1D78 ; Cyrillic # Lm MODIFIER LETTER CYRILLIC EN 2DE0..2DFF ; Cyrillic # Mn [32] COMBINING CYRILLIC LETTER BE..COMBINING CYRILLIC LETTER IOTIFIED BIG YUS @@ -788,7 +791,7 @@ FE2E..FE2F ; Cyrillic # Mn [2] COMBINING CYRILLIC TITLO LEFT HALF..COMBININ 1E030..1E06D ; Cyrillic # Lm [62] MODIFIER LETTER CYRILLIC SMALL A..MODIFIER LETTER CYRILLIC SMALL STRAIGHT U WITH STROKE 1E08F ; Cyrillic # Mn COMBINING CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I -# Total code points: 506 +# Total code points: 508 # ================================================ @@ -868,7 +871,7 @@ FB46..FB4F ; Hebrew # Lo [10] HEBREW LETTER TSADI WITH DAGESH..HEBREW LIGATU 0888 ; Arabic # Sk ARABIC RAISED ROUND DOT 0889..088E ; Arabic # Lo [6] ARABIC LETTER NOON WITH INVERTED SMALL V..ARABIC VERTICAL TAIL 0890..0891 ; Arabic # Cf [2] ARABIC POUND MARK ABOVE..ARABIC PIASTRE MARK ABOVE -0898..089F ; Arabic # Mn [8] ARABIC SMALL HIGH WORD AL-JUZ..ARABIC HALF MADDA OVER MADDA +0897..089F ; Arabic # Mn [9] ARABIC PEPET..ARABIC HALF MADDA OVER MADDA 08A0..08C8 ; Arabic # Lo [41] ARABIC LETTER BEH WITH SMALL V BELOW..ARABIC LETTER GRAF 08C9 ; Arabic # Lm ARABIC SMALL FARSI YEH 08CA..08E1 ; Arabic # Mn [24] ARABIC SMALL HIGH FARSI YEH..ARABIC SMALL HIGH SIGN SAFHA @@ -886,7 +889,8 @@ FDFD..FDFF ; Arabic # So [3] ARABIC LIGATURE BISMILLAH AR-RAHMAN AR-RAHEEM. FE70..FE74 ; Arabic # Lo [5] ARABIC FATHATAN ISOLATED FORM..ARABIC KASRATAN ISOLATED FORM FE76..FEFC ; Arabic # Lo [135] ARABIC FATHA ISOLATED FORM..ARABIC LIGATURE LAM WITH ALEF FINAL FORM 10E60..10E7E ; Arabic # No [31] RUMI DIGIT ONE..RUMI FRACTION TWO THIRDS -10EFD..10EFF ; Arabic # Mn [3] ARABIC SMALL LOW WORD SAKTA..ARABIC SMALL LOW WORD MADDA +10EC2..10EC4 ; Arabic # Lo [3] ARABIC LETTER DAL WITH TWO DOTS VERTICALLY BELOW..ARABIC LETTER KAF WITH TWO DOTS VERTICALLY BELOW +10EFC..10EFF ; Arabic # Mn [4] ARABIC COMBINING ALEF OVERLAY..ARABIC SMALL LOW WORD MADDA 1EE00..1EE03 ; Arabic # Lo [4] ARABIC MATHEMATICAL ALEF..ARABIC MATHEMATICAL DAL 1EE05..1EE1F ; Arabic # Lo [27] ARABIC MATHEMATICAL WAW..ARABIC MATHEMATICAL DOTLESS QAF 1EE21..1EE22 ; Arabic # Lo [2] ARABIC MATHEMATICAL INITIAL BEH..ARABIC MATHEMATICAL INITIAL JEEM @@ -922,7 +926,7 @@ FE76..FEFC ; Arabic # Lo [135] ARABIC FATHA ISOLATED FORM..ARABIC LIGATURE LA 1EEAB..1EEBB ; Arabic # Lo [17] ARABIC MATHEMATICAL DOUBLE-STRUCK LAM..ARABIC MATHEMATICAL DOUBLE-STRUCK GHAIN 1EEF0..1EEF1 ; Arabic # Sm [2] ARABIC MATHEMATICAL OPERATOR MEEM WITH HAH WITH TATWEEL..ARABIC MATHEMATICAL OPERATOR HAH WITH DAL -# Total code points: 1368 +# Total code points: 1373 # ================================================ @@ -1369,8 +1373,9 @@ AA7B ; Myanmar # Mc MYANMAR SIGN PAO KAREN TONE AA7C ; Myanmar # Mn MYANMAR SIGN TAI LAING TONE-2 AA7D ; Myanmar # Mc MYANMAR SIGN TAI LAING TONE-5 AA7E..AA7F ; Myanmar # Lo [2] MYANMAR LETTER SHWE PALAUNG CHA..MYANMAR LETTER SHWE PALAUNG SHA +116D0..116E3 ; Myanmar # Nd [20] MYANMAR PAO DIGIT ZERO..MYANMAR EASTERN PWO KAREN DIGIT NINE -# Total code points: 223 +# Total code points: 243 # ================================================ @@ -1888,14 +1893,15 @@ A82C ; Syloti_Nagri # Mn SYLOTI NAGRI SIGN ALTERNATE HASANTA 1B42 ; Balinese # Mn BALINESE VOWEL SIGN PEPET 1B43..1B44 ; Balinese # Mc [2] BALINESE VOWEL SIGN PEPET TEDUNG..BALINESE ADEG ADEG 1B45..1B4C ; Balinese # Lo [8] BALINESE LETTER KAF SASAK..BALINESE LETTER ARCHAIC JNYA +1B4E..1B4F ; Balinese # Po [2] BALINESE INVERTED CARIK SIKI..BALINESE INVERTED CARIK PAREREN 1B50..1B59 ; Balinese # Nd [10] BALINESE DIGIT ZERO..BALINESE DIGIT NINE 1B5A..1B60 ; Balinese # Po [7] BALINESE PANTI..BALINESE PAMENENG 1B61..1B6A ; Balinese # So [10] BALINESE MUSICAL SYMBOL DONG..BALINESE MUSICAL SYMBOL DANG GEDE 1B6B..1B73 ; Balinese # Mn [9] BALINESE MUSICAL SYMBOL COMBINING TEGEH..BALINESE MUSICAL SYMBOL COMBINING GONG 1B74..1B7C ; Balinese # So [9] BALINESE MUSICAL SYMBOL RIGHT-HAND OPEN DUG..BALINESE MUSICAL SYMBOL LEFT-HAND OPEN PING -1B7D..1B7E ; Balinese # Po [2] BALINESE PANTI LANTANG..BALINESE PAMADA LANTANG +1B7D..1B7F ; Balinese # Po [3] BALINESE PANTI LANTANG..BALINESE PANTI BAWAK -# Total code points: 124 +# Total code points: 127 # ================================================ @@ -2108,8 +2114,9 @@ AADE..AADF ; Tai_Viet # Po [2] TAI VIET SYMBOL HO HOI..TAI VIET SYMBOL KOI 13440 ; Egyptian_Hieroglyphs # Mn EGYPTIAN HIEROGLYPH MIRROR HORIZONTALLY 13441..13446 ; Egyptian_Hieroglyphs # Lo [6] EGYPTIAN HIEROGLYPH FULL BLANK..EGYPTIAN HIEROGLYPH WIDE LOST SIGN 13447..13455 ; Egyptian_Hieroglyphs # Mn [15] EGYPTIAN HIEROGLYPH MODIFIER DAMAGED AT TOP START..EGYPTIAN HIEROGLYPH MODIFIER DAMAGED +13460..143FA ; Egyptian_Hieroglyphs # Lo [3995] EGYPTIAN HIEROGLYPH-13460..EGYPTIAN HIEROGLYPH-143FA -# Total code points: 1110 +# Total code points: 5105 # ================================================ @@ -2615,7 +2622,9 @@ ABF0..ABF9 ; Meetei_Mayek # Nd [10] MEETEI MAYEK DIGIT ZERO..MEETEI MAYEK DI # ================================================ 11700..1171A ; Ahom # Lo [27] AHOM LETTER KA..AHOM LETTER ALTERNATE BA -1171D..1171F ; Ahom # Mn [3] AHOM CONSONANT SIGN MEDIAL LA..AHOM CONSONANT SIGN MEDIAL LIGATING RA +1171D ; Ahom # Mn AHOM CONSONANT SIGN MEDIAL LA +1171E ; Ahom # Mc AHOM CONSONANT SIGN MEDIAL RA +1171F ; Ahom # Mn AHOM CONSONANT SIGN MEDIAL LIGATING RA 11720..11721 ; Ahom # Mc [2] AHOM VOWEL SIGN A..AHOM VOWEL SIGN AA 11722..11725 ; Ahom # Mn [4] AHOM VOWEL SIGN I..AHOM VOWEL SIGN UU 11726 ; Ahom # Mc AHOM VOWEL SIGN E @@ -2949,8 +2958,9 @@ ABF0..ABF9 ; Meetei_Mayek # Nd [10] MEETEI MAYEK DIGIT ZERO..MEETEI MAYEK DI 16FE4 ; Khitan_Small_Script # Mn KHITAN SMALL SCRIPT FILLER 18B00..18CD5 ; Khitan_Small_Script # Lo [470] KHITAN SMALL SCRIPT CHARACTER-18B00..KHITAN SMALL SCRIPT CHARACTER-18CD5 +18CFF ; Khitan_Small_Script # Lo KHITAN SMALL SCRIPT CHARACTER-18CFF -# Total code points: 471 +# Total code points: 472 # ================================================ @@ -3018,8 +3028,9 @@ ABF0..ABF9 ; Meetei_Mayek # Nd [10] MEETEI MAYEK DIGIT ZERO..MEETEI MAYEK DI 11F42 ; Kawi # Mn KAWI CONJOINER 11F43..11F4F ; Kawi # Po [13] KAWI DANDA..KAWI PUNCTUATION CLOSING SPIRAL 11F50..11F59 ; Kawi # Nd [10] KAWI DIGIT ZERO..KAWI DIGIT NINE +11F5A ; Kawi # Mn KAWI SIGN NUKTA -# Total code points: 86 +# Total code points: 87 # ================================================ @@ -3030,4 +3041,88 @@ ABF0..ABF9 ; Meetei_Mayek # Nd [10] MEETEI MAYEK DIGIT ZERO..MEETEI MAYEK DI # Total code points: 42 +# ================================================ + +10D40..10D49 ; Garay # Nd [10] GARAY DIGIT ZERO..GARAY DIGIT NINE +10D4A..10D4D ; Garay # Lo [4] GARAY VOWEL SIGN A..GARAY VOWEL SIGN EE +10D4E ; Garay # Lm GARAY VOWEL LENGTH MARK +10D4F ; Garay # Lo GARAY SUKUN +10D50..10D65 ; Garay # L& [22] GARAY CAPITAL LETTER A..GARAY CAPITAL LETTER OLD NA +10D69..10D6D ; Garay # Mn [5] GARAY VOWEL SIGN E..GARAY CONSONANT NASALIZATION MARK +10D6E ; Garay # Pd GARAY HYPHEN +10D6F ; Garay # Lm GARAY REDUPLICATION MARK +10D70..10D85 ; Garay # L& [22] GARAY SMALL LETTER A..GARAY SMALL LETTER OLD NA +10D8E..10D8F ; Garay # Sm [2] GARAY PLUS SIGN..GARAY MINUS SIGN + +# Total code points: 69 + +# ================================================ + +16100..1611D ; Gurung_Khema # Lo [30] GURUNG KHEMA LETTER A..GURUNG KHEMA LETTER SA +1611E..16129 ; Gurung_Khema # Mn [12] GURUNG KHEMA VOWEL SIGN AA..GURUNG KHEMA VOWEL LENGTH MARK +1612A..1612C ; Gurung_Khema # Mc [3] GURUNG KHEMA CONSONANT SIGN MEDIAL YA..GURUNG KHEMA CONSONANT SIGN MEDIAL HA +1612D..1612F ; Gurung_Khema # Mn [3] GURUNG KHEMA SIGN ANUSVARA..GURUNG KHEMA SIGN THOLHOMA +16130..16139 ; Gurung_Khema # Nd [10] GURUNG KHEMA DIGIT ZERO..GURUNG KHEMA DIGIT NINE + +# Total code points: 58 + +# ================================================ + +16D40..16D42 ; Kirat_Rai # Lm [3] KIRAT RAI SIGN ANUSVARA..KIRAT RAI SIGN VISARGA +16D43..16D6A ; Kirat_Rai # Lo [40] KIRAT RAI LETTER A..KIRAT RAI VOWEL SIGN AU +16D6B..16D6C ; Kirat_Rai # Lm [2] KIRAT RAI SIGN VIRAMA..KIRAT RAI SIGN SAAT +16D6D..16D6F ; Kirat_Rai # Po [3] KIRAT RAI SIGN YUPI..KIRAT RAI DOUBLE DANDA +16D70..16D79 ; Kirat_Rai # Nd [10] KIRAT RAI DIGIT ZERO..KIRAT RAI DIGIT NINE + +# Total code points: 58 + +# ================================================ + +1E5D0..1E5ED ; Ol_Onal # Lo [30] OL ONAL LETTER O..OL ONAL LETTER EG +1E5EE..1E5EF ; Ol_Onal # Mn [2] OL ONAL SIGN MU..OL ONAL SIGN IKIR +1E5F0 ; Ol_Onal # Lo OL ONAL SIGN HODDOND +1E5F1..1E5FA ; Ol_Onal # Nd [10] OL ONAL DIGIT ZERO..OL ONAL DIGIT NINE +1E5FF ; Ol_Onal # Po OL ONAL ABBREVIATION SIGN + +# Total code points: 44 + +# ================================================ + +11BC0..11BE0 ; Sunuwar # Lo [33] SUNUWAR LETTER DEVI..SUNUWAR LETTER KLOKO +11BE1 ; Sunuwar # Po SUNUWAR SIGN PVO +11BF0..11BF9 ; Sunuwar # Nd [10] SUNUWAR DIGIT ZERO..SUNUWAR DIGIT NINE + +# Total code points: 44 + +# ================================================ + +105C0..105F3 ; Todhri # Lo [52] TODHRI LETTER A..TODHRI LETTER OO + +# Total code points: 52 + +# ================================================ + +11380..11389 ; Tulu_Tigalari # Lo [10] TULU-TIGALARI LETTER A..TULU-TIGALARI LETTER VOCALIC LL +1138B ; Tulu_Tigalari # Lo TULU-TIGALARI LETTER EE +1138E ; Tulu_Tigalari # Lo TULU-TIGALARI LETTER AI +11390..113B5 ; Tulu_Tigalari # Lo [38] TULU-TIGALARI LETTER OO..TULU-TIGALARI LETTER LLLA +113B7 ; Tulu_Tigalari # Lo TULU-TIGALARI SIGN AVAGRAHA +113B8..113BA ; Tulu_Tigalari # Mc [3] TULU-TIGALARI VOWEL SIGN AA..TULU-TIGALARI VOWEL SIGN II +113BB..113C0 ; Tulu_Tigalari # Mn [6] TULU-TIGALARI VOWEL SIGN U..TULU-TIGALARI VOWEL SIGN VOCALIC LL +113C2 ; Tulu_Tigalari # Mc TULU-TIGALARI VOWEL SIGN EE +113C5 ; Tulu_Tigalari # Mc TULU-TIGALARI VOWEL SIGN AI +113C7..113CA ; Tulu_Tigalari # Mc [4] TULU-TIGALARI VOWEL SIGN OO..TULU-TIGALARI SIGN CANDRA ANUNASIKA +113CC..113CD ; Tulu_Tigalari # Mc [2] TULU-TIGALARI SIGN ANUSVARA..TULU-TIGALARI SIGN VISARGA +113CE ; Tulu_Tigalari # Mn TULU-TIGALARI SIGN VIRAMA +113CF ; Tulu_Tigalari # Mc TULU-TIGALARI SIGN LOOPED VIRAMA +113D0 ; Tulu_Tigalari # Mn TULU-TIGALARI CONJOINER +113D1 ; Tulu_Tigalari # Lo TULU-TIGALARI REPHA +113D2 ; Tulu_Tigalari # Mn TULU-TIGALARI GEMINATION MARK +113D3 ; Tulu_Tigalari # Lo TULU-TIGALARI SIGN PLUTA +113D4..113D5 ; Tulu_Tigalari # Po [2] TULU-TIGALARI DANDA..TULU-TIGALARI DOUBLE DANDA +113D7..113D8 ; Tulu_Tigalari # Po [2] TULU-TIGALARI SIGN OM PUSHPIKA..TULU-TIGALARI SIGN SHRII PUSHPIKA +113E1..113E2 ; Tulu_Tigalari # Mn [2] TULU-TIGALARI VEDIC TONE SVARITA..TULU-TIGALARI VEDIC TONE ANUDATTA + +# Total code points: 80 + # EOF diff --git a/src/java.base/share/data/unicodedata/SpecialCasing.txt b/src/java.base/share/data/unicodedata/SpecialCasing.txt index 3d6280f8488..74700b5d321 100644 --- a/src/java.base/share/data/unicodedata/SpecialCasing.txt +++ b/src/java.base/share/data/unicodedata/SpecialCasing.txt @@ -1,28 +1,28 @@ -# SpecialCasing-15.1.0.txt -# Date: 2023-01-05, 20:35:03 GMT -# Copyright (c) 2023 Unicode, Inc. +# SpecialCasing-16.0.0.txt +# Date: 2024-05-10, 22:49:00 GMT +# Copyright (c) 2024 Unicode, Inc. # Unicode and the Unicode Logo are registered trademarks of Unicode, Inc. in the U.S. and other countries. -# For terms of use, see https://www.unicode.org/terms_of_use.html +# For terms of use and license, see https://www.unicode.org/terms_of_use.html # # Unicode Character Database # For documentation, see https://www.unicode.org/reports/tr44/ # # Special Casing # -# This file is a supplement to the UnicodeData.txt file. It does not define any -# properties, but rather provides additional information about the casing of -# Unicode characters, for situations when casing incurs a change in string length -# or is dependent on context or locale. For compatibility, the UnicodeData.txt -# file only contains simple case mappings for characters where they are one-to-one -# and independent of context and language. The data in this file, combined with +# This file is a supplement to the UnicodeData.txt file. The data in this file, combined with # the simple case mappings in UnicodeData.txt, defines the full case mappings # Lowercase_Mapping (lc), Titlecase_Mapping (tc), and Uppercase_Mapping (uc). +# For compatibility, the UnicodeData.txt file only contains simple case mappings +# for characters where they are one-to-one (and independent of context and language). +# +# For historical reasons, this file also provides additional information about the casing +# of Unicode characters for selected situations when casing is dependent on context or locale. # # Note that the preferred mechanism for defining tailored casing operations is # the Unicode Common Locale Data Repository (CLDR). For more information, see the # discussion of case mappings and case algorithms in the Unicode Standard. # -# All code points not listed in this file that do not have a simple case mappings +# All code points not listed in this file that do not have simple case mappings # in UnicodeData.txt map to themselves. # ================================================================================ # Format diff --git a/src/java.base/share/data/unicodedata/UnicodeData.txt b/src/java.base/share/data/unicodedata/UnicodeData.txt index bdcc41850d7..64258a37395 100644 --- a/src/java.base/share/data/unicodedata/UnicodeData.txt +++ b/src/java.base/share/data/unicodedata/UnicodeData.txt @@ -409,7 +409,7 @@ 0198;LATIN CAPITAL LETTER K WITH HOOK;Lu;0;L;;;;;N;LATIN CAPITAL LETTER K HOOK;;;0199; 0199;LATIN SMALL LETTER K WITH HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER K HOOK;;0198;;0198 019A;LATIN SMALL LETTER L WITH BAR;Ll;0;L;;;;;N;LATIN SMALL LETTER BARRED L;;023D;;023D -019B;LATIN SMALL LETTER LAMBDA WITH STROKE;Ll;0;L;;;;;N;LATIN SMALL LETTER BARRED LAMBDA;;;; +019B;LATIN SMALL LETTER LAMBDA WITH STROKE;Ll;0;L;;;;;N;LATIN SMALL LETTER BARRED LAMBDA;;A7DC;;A7DC 019C;LATIN CAPITAL LETTER TURNED M;Lu;0;L;;;;;N;;;;026F; 019D;LATIN CAPITAL LETTER N WITH LEFT HOOK;Lu;0;L;;;;;N;LATIN CAPITAL LETTER N HOOK;;;0272; 019E;LATIN SMALL LETTER N WITH LONG RIGHT LEG;Ll;0;L;;;;;N;;;0220;;0220 @@ -610,7 +610,7 @@ 0261;LATIN SMALL LETTER SCRIPT G;Ll;0;L;;;;;N;;;A7AC;;A7AC 0262;LATIN LETTER SMALL CAPITAL G;Ll;0;L;;;;;N;;;;; 0263;LATIN SMALL LETTER GAMMA;Ll;0;L;;;;;N;;;0194;;0194 -0264;LATIN SMALL LETTER RAMS HORN;Ll;0;L;;;;;N;LATIN SMALL LETTER BABY GAMMA;;;; +0264;LATIN SMALL LETTER RAMS HORN;Ll;0;L;;;;;N;LATIN SMALL LETTER BABY GAMMA;;A7CB;;A7CB 0265;LATIN SMALL LETTER TURNED H;Ll;0;L;;;;;N;;;A78D;;A78D 0266;LATIN SMALL LETTER H WITH HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER H HOOK;;A7AA;;A7AA 0267;LATIN SMALL LETTER HENG WITH HOOK;Ll;0;L;;;;;N;LATIN SMALL LETTER HENG HOOK;;;; @@ -2123,6 +2123,7 @@ 088E;ARABIC VERTICAL TAIL;Lo;0;AL;;;;;N;;;;; 0890;ARABIC POUND MARK ABOVE;Cf;0;AN;;;;;N;;;;; 0891;ARABIC PIASTRE MARK ABOVE;Cf;0;AN;;;;;N;;;;; +0897;ARABIC PEPET;Mn;230;NSM;;;;;N;;;;; 0898;ARABIC SMALL HIGH WORD AL-JUZ;Mn;230;NSM;;;;;N;;;;; 0899;ARABIC SMALL LOW WORD ISHMAAM;Mn;220;NSM;;;;;N;;;;; 089A;ARABIC SMALL LOW WORD IMAALA;Mn;220;NSM;;;;;N;;;;; @@ -6213,6 +6214,8 @@ 1B4A;BALINESE LETTER ZAL SASAK;Lo;0;L;;;;;N;;;;; 1B4B;BALINESE LETTER ASYURA SASAK;Lo;0;L;;;;;N;;;;; 1B4C;BALINESE LETTER ARCHAIC JNYA;Lo;0;L;;;;;N;;;;; +1B4E;BALINESE INVERTED CARIK SIKI;Po;0;L;;;;;N;;;;; +1B4F;BALINESE INVERTED CARIK PAREREN;Po;0;L;;;;;N;;;;; 1B50;BALINESE DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;; 1B51;BALINESE DIGIT ONE;Nd;0;L;;1;1;1;N;;;;; 1B52;BALINESE DIGIT TWO;Nd;0;L;;2;2;2;N;;;;; @@ -6260,6 +6263,7 @@ 1B7C;BALINESE MUSICAL SYMBOL LEFT-HAND OPEN PING;So;0;L;;;;;N;;;;; 1B7D;BALINESE PANTI LANTANG;Po;0;L;;;;;N;;;;; 1B7E;BALINESE PAMADA LANTANG;Po;0;L;;;;;N;;;;; +1B7F;BALINESE PANTI BAWAK;Po;0;L;;;;;N;;;;; 1B80;SUNDANESE SIGN PANYECEK;Mn;0;NSM;;;;;N;;;;; 1B81;SUNDANESE SIGN PANGLAYAR;Mn;0;NSM;;;;;N;;;;; 1B82;SUNDANESE SIGN PANGWISAD;Mc;0;L;;;;;N;;;;; @@ -6511,6 +6515,8 @@ 1C86;CYRILLIC SMALL LETTER TALL HARD SIGN;Ll;0;L;;;;;N;;;042A;;042A 1C87;CYRILLIC SMALL LETTER TALL YAT;Ll;0;L;;;;;N;;;0462;;0462 1C88;CYRILLIC SMALL LETTER UNBLENDED UK;Ll;0;L;;;;;N;;;A64A;;A64A +1C89;CYRILLIC CAPITAL LETTER TJE;Lu;0;L;;;;;N;;;;1C8A; +1C8A;CYRILLIC SMALL LETTER TJE;Ll;0;L;;;;;N;;;1C89;;1C89 1C90;GEORGIAN MTAVRULI CAPITAL LETTER AN;Lu;0;L;;;;;N;;;;10D0; 1C91;GEORGIAN MTAVRULI CAPITAL LETTER BAN;Lu;0;L;;;;;N;;;;10D1; 1C92;GEORGIAN MTAVRULI CAPITAL LETTER GAN;Lu;0;L;;;;;N;;;;10D2; @@ -7933,7 +7939,7 @@ 226A;MUCH LESS-THAN;Sm;0;ON;;;;;Y;MUCH LESS THAN;;;; 226B;MUCH GREATER-THAN;Sm;0;ON;;;;;Y;MUCH GREATER THAN;;;; 226C;BETWEEN;Sm;0;ON;;;;;N;;;;; -226D;NOT EQUIVALENT TO;Sm;0;ON;224D 0338;;;;N;;;;; +226D;NOT EQUIVALENT TO;Sm;0;ON;224D 0338;;;;Y;;;;; 226E;NOT LESS-THAN;Sm;0;ON;003C 0338;;;;Y;NOT LESS THAN;;;; 226F;NOT GREATER-THAN;Sm;0;ON;003E 0338;;;;Y;NOT GREATER THAN;;;; 2270;NEITHER LESS-THAN NOR EQUAL TO;Sm;0;ON;2264 0338;;;;Y;NEITHER LESS THAN NOR EQUAL TO;;;; @@ -8375,6 +8381,9 @@ 2424;SYMBOL FOR NEWLINE;So;0;ON;;;;;N;GRAPHIC FOR NEWLINE;;;; 2425;SYMBOL FOR DELETE FORM TWO;So;0;ON;;;;;N;;;;; 2426;SYMBOL FOR SUBSTITUTE FORM TWO;So;0;ON;;;;;N;;;;; +2427;SYMBOL FOR DELETE SQUARE CHECKER BOARD FORM;So;0;ON;;;;;N;;;;; +2428;SYMBOL FOR DELETE RECTANGULAR CHECKER BOARD FORM;So;0;ON;;;;;N;;;;; +2429;SYMBOL FOR DELETE MEDIUM SHADE FORM;So;0;ON;;;;;N;;;;; 2440;OCR HOOK;So;0;ON;;;;;N;;;;; 2441;OCR CHAIR;So;0;ON;;;;;N;;;;; 2442;OCR FORK;So;0;ON;;;;;N;;;;; @@ -11709,6 +11718,8 @@ 31E1;CJK STROKE HZZZG;So;0;ON;;;;;N;;;;; 31E2;CJK STROKE PG;So;0;ON;;;;;N;;;;; 31E3;CJK STROKE Q;So;0;ON;;;;;N;;;;; +31E4;CJK STROKE HXG;So;0;ON;;;;;N;;;;; +31E5;CJK STROKE SZP;So;0;ON;;;;;N;;;;; 31EF;IDEOGRAPHIC DESCRIPTION CHARACTER SUBTRACTION;So;0;ON;;;;;N;;;;; 31F0;KATAKANA LETTER SMALL KU;Lo;0;L;;;;;N;;;;; 31F1;KATAKANA LETTER SMALL SI;Lo;0;L;;;;;N;;;;; @@ -14260,6 +14271,9 @@ A7C7;LATIN CAPITAL LETTER D WITH SHORT STROKE OVERLAY;Lu;0;L;;;;;N;;;;A7C8; A7C8;LATIN SMALL LETTER D WITH SHORT STROKE OVERLAY;Ll;0;L;;;;;N;;;A7C7;;A7C7 A7C9;LATIN CAPITAL LETTER S WITH SHORT STROKE OVERLAY;Lu;0;L;;;;;N;;;;A7CA; A7CA;LATIN SMALL LETTER S WITH SHORT STROKE OVERLAY;Ll;0;L;;;;;N;;;A7C9;;A7C9 +A7CB;LATIN CAPITAL LETTER RAMS HORN;Lu;0;L;;;;;N;;;;0264; +A7CC;LATIN CAPITAL LETTER S WITH DIAGONAL STROKE;Lu;0;L;;;;;N;;;;A7CD; +A7CD;LATIN SMALL LETTER S WITH DIAGONAL STROKE;Ll;0;L;;;;;N;;;A7CC;;A7CC A7D0;LATIN CAPITAL LETTER CLOSED INSULAR G;Lu;0;L;;;;;N;;;;A7D1; A7D1;LATIN SMALL LETTER CLOSED INSULAR G;Ll;0;L;;;;;N;;;A7D0;;A7D0 A7D3;LATIN SMALL LETTER DOUBLE THORN;Ll;0;L;;;;;N;;;;; @@ -14268,6 +14282,9 @@ A7D6;LATIN CAPITAL LETTER MIDDLE SCOTS S;Lu;0;L;;;;;N;;;;A7D7; A7D7;LATIN SMALL LETTER MIDDLE SCOTS S;Ll;0;L;;;;;N;;;A7D6;;A7D6 A7D8;LATIN CAPITAL LETTER SIGMOID S;Lu;0;L;;;;;N;;;;A7D9; A7D9;LATIN SMALL LETTER SIGMOID S;Ll;0;L;;;;;N;;;A7D8;;A7D8 +A7DA;LATIN CAPITAL LETTER LAMBDA;Lu;0;L;;;;;N;;;;A7DB; +A7DB;LATIN SMALL LETTER LAMBDA;Ll;0;L;;;;;N;;;A7DA;;A7DA +A7DC;LATIN CAPITAL LETTER LAMBDA WITH STROKE;Lu;0;L;;;;;N;;;;019B; A7F2;MODIFIER LETTER CAPITAL C;Lm;0;L;<super> 0043;;;;N;;;;; A7F3;MODIFIER LETTER CAPITAL F;Lm;0;L;<super> 0046;;;;N;;;;; A7F4;MODIFIER LETTER CAPITAL Q;Lm;0;L;<super> 0051;;;;N;;;;; @@ -18001,6 +18018,58 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;; 105B9;VITHKUQI SMALL LETTER XE;Ll;0;L;;;;;N;;;10592;;10592 105BB;VITHKUQI SMALL LETTER Y;Ll;0;L;;;;;N;;;10594;;10594 105BC;VITHKUQI SMALL LETTER ZE;Ll;0;L;;;;;N;;;10595;;10595 +105C0;TODHRI LETTER A;Lo;0;L;;;;;N;;;;; +105C1;TODHRI LETTER AS;Lo;0;L;;;;;N;;;;; +105C2;TODHRI LETTER BA;Lo;0;L;;;;;N;;;;; +105C3;TODHRI LETTER MBA;Lo;0;L;;;;;N;;;;; +105C4;TODHRI LETTER CA;Lo;0;L;;;;;N;;;;; +105C5;TODHRI LETTER CHA;Lo;0;L;;;;;N;;;;; +105C6;TODHRI LETTER DA;Lo;0;L;;;;;N;;;;; +105C7;TODHRI LETTER NDA;Lo;0;L;;;;;N;;;;; +105C8;TODHRI LETTER DHA;Lo;0;L;;;;;N;;;;; +105C9;TODHRI LETTER EI;Lo;0;L;105D2 0307;;;;N;;;;; +105CA;TODHRI LETTER E;Lo;0;L;;;;;N;;;;; +105CB;TODHRI LETTER FA;Lo;0;L;;;;;N;;;;; +105CC;TODHRI LETTER GA;Lo;0;L;;;;;N;;;;; +105CD;TODHRI LETTER NGA;Lo;0;L;;;;;N;;;;; +105CE;TODHRI LETTER GJA;Lo;0;L;;;;;N;;;;; +105CF;TODHRI LETTER NGJA;Lo;0;L;;;;;N;;;;; +105D0;TODHRI LETTER HA;Lo;0;L;;;;;N;;;;; +105D1;TODHRI LETTER HJA;Lo;0;L;;;;;N;;;;; +105D2;TODHRI LETTER I;Lo;0;L;;;;;N;;;;; +105D3;TODHRI LETTER JA;Lo;0;L;;;;;N;;;;; +105D4;TODHRI LETTER KA;Lo;0;L;;;;;N;;;;; +105D5;TODHRI LETTER LA;Lo;0;L;;;;;N;;;;; +105D6;TODHRI LETTER LLA;Lo;0;L;;;;;N;;;;; +105D7;TODHRI LETTER MA;Lo;0;L;;;;;N;;;;; +105D8;TODHRI LETTER NA;Lo;0;L;;;;;N;;;;; +105D9;TODHRI LETTER NJAN;Lo;0;L;;;;;N;;;;; +105DA;TODHRI LETTER O;Lo;0;L;;;;;N;;;;; +105DB;TODHRI LETTER PA;Lo;0;L;;;;;N;;;;; +105DC;TODHRI LETTER QA;Lo;0;L;;;;;N;;;;; +105DD;TODHRI LETTER RA;Lo;0;L;;;;;N;;;;; +105DE;TODHRI LETTER RRA;Lo;0;L;;;;;N;;;;; +105DF;TODHRI LETTER SA;Lo;0;L;;;;;N;;;;; +105E0;TODHRI LETTER SHA;Lo;0;L;;;;;N;;;;; +105E1;TODHRI LETTER SHTA;Lo;0;L;;;;;N;;;;; +105E2;TODHRI LETTER TA;Lo;0;L;;;;;N;;;;; +105E3;TODHRI LETTER THA;Lo;0;L;;;;;N;;;;; +105E4;TODHRI LETTER U;Lo;0;L;105DA 0307;;;;N;;;;; +105E5;TODHRI LETTER VA;Lo;0;L;;;;;N;;;;; +105E6;TODHRI LETTER XA;Lo;0;L;;;;;N;;;;; +105E7;TODHRI LETTER NXA;Lo;0;L;;;;;N;;;;; +105E8;TODHRI LETTER XHA;Lo;0;L;;;;;N;;;;; +105E9;TODHRI LETTER NXHA;Lo;0;L;;;;;N;;;;; +105EA;TODHRI LETTER Y;Lo;0;L;;;;;N;;;;; +105EB;TODHRI LETTER JY;Lo;0;L;;;;;N;;;;; +105EC;TODHRI LETTER ZA;Lo;0;L;;;;;N;;;;; +105ED;TODHRI LETTER ZHA;Lo;0;L;;;;;N;;;;; +105EE;TODHRI LETTER GHA;Lo;0;L;;;;;N;;;;; +105EF;TODHRI LETTER STA;Lo;0;L;;;;;N;;;;; +105F0;TODHRI LETTER SKAN;Lo;0;L;;;;;N;;;;; +105F1;TODHRI LETTER KHA;Lo;0;L;;;;;N;;;;; +105F2;TODHRI LETTER PSA;Lo;0;L;;;;;N;;;;; +105F3;TODHRI LETTER OO;Lo;0;L;;;;;N;;;;; 10600;LINEAR A SIGN AB001;Lo;0;L;;;;;N;;;;; 10601;LINEAR A SIGN AB002;Lo;0;L;;;;;N;;;;; 10602;LINEAR A SIGN AB003;Lo;0;L;;;;;N;;;;; @@ -19322,6 +19391,75 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;; 10D37;HANIFI ROHINGYA DIGIT SEVEN;Nd;0;AN;;7;7;7;N;;;;; 10D38;HANIFI ROHINGYA DIGIT EIGHT;Nd;0;AN;;8;8;8;N;;;;; 10D39;HANIFI ROHINGYA DIGIT NINE;Nd;0;AN;;9;9;9;N;;;;; +10D40;GARAY DIGIT ZERO;Nd;0;AN;;0;0;0;N;;;;; +10D41;GARAY DIGIT ONE;Nd;0;AN;;1;1;1;N;;;;; +10D42;GARAY DIGIT TWO;Nd;0;AN;;2;2;2;N;;;;; +10D43;GARAY DIGIT THREE;Nd;0;AN;;3;3;3;N;;;;; +10D44;GARAY DIGIT FOUR;Nd;0;AN;;4;4;4;N;;;;; +10D45;GARAY DIGIT FIVE;Nd;0;AN;;5;5;5;N;;;;; +10D46;GARAY DIGIT SIX;Nd;0;AN;;6;6;6;N;;;;; +10D47;GARAY DIGIT SEVEN;Nd;0;AN;;7;7;7;N;;;;; +10D48;GARAY DIGIT EIGHT;Nd;0;AN;;8;8;8;N;;;;; +10D49;GARAY DIGIT NINE;Nd;0;AN;;9;9;9;N;;;;; +10D4A;GARAY VOWEL SIGN A;Lo;0;R;;;;;N;;;;; +10D4B;GARAY VOWEL SIGN I;Lo;0;R;;;;;N;;;;; +10D4C;GARAY VOWEL SIGN O;Lo;0;R;;;;;N;;;;; +10D4D;GARAY VOWEL SIGN EE;Lo;0;R;;;;;N;;;;; +10D4E;GARAY VOWEL LENGTH MARK;Lm;0;R;;;;;N;;;;; +10D4F;GARAY SUKUN;Lo;0;R;;;;;N;;;;; +10D50;GARAY CAPITAL LETTER A;Lu;0;R;;;;;N;;;;10D70; +10D51;GARAY CAPITAL LETTER CA;Lu;0;R;;;;;N;;;;10D71; +10D52;GARAY CAPITAL LETTER MA;Lu;0;R;;;;;N;;;;10D72; +10D53;GARAY CAPITAL LETTER KA;Lu;0;R;;;;;N;;;;10D73; +10D54;GARAY CAPITAL LETTER BA;Lu;0;R;;;;;N;;;;10D74; +10D55;GARAY CAPITAL LETTER JA;Lu;0;R;;;;;N;;;;10D75; +10D56;GARAY CAPITAL LETTER SA;Lu;0;R;;;;;N;;;;10D76; +10D57;GARAY CAPITAL LETTER WA;Lu;0;R;;;;;N;;;;10D77; +10D58;GARAY CAPITAL LETTER LA;Lu;0;R;;;;;N;;;;10D78; +10D59;GARAY CAPITAL LETTER GA;Lu;0;R;;;;;N;;;;10D79; +10D5A;GARAY CAPITAL LETTER DA;Lu;0;R;;;;;N;;;;10D7A; +10D5B;GARAY CAPITAL LETTER XA;Lu;0;R;;;;;N;;;;10D7B; +10D5C;GARAY CAPITAL LETTER YA;Lu;0;R;;;;;N;;;;10D7C; +10D5D;GARAY CAPITAL LETTER TA;Lu;0;R;;;;;N;;;;10D7D; +10D5E;GARAY CAPITAL LETTER RA;Lu;0;R;;;;;N;;;;10D7E; +10D5F;GARAY CAPITAL LETTER NYA;Lu;0;R;;;;;N;;;;10D7F; +10D60;GARAY CAPITAL LETTER FA;Lu;0;R;;;;;N;;;;10D80; +10D61;GARAY CAPITAL LETTER NA;Lu;0;R;;;;;N;;;;10D81; +10D62;GARAY CAPITAL LETTER PA;Lu;0;R;;;;;N;;;;10D82; +10D63;GARAY CAPITAL LETTER HA;Lu;0;R;;;;;N;;;;10D83; +10D64;GARAY CAPITAL LETTER OLD KA;Lu;0;R;;;;;N;;;;10D84; +10D65;GARAY CAPITAL LETTER OLD NA;Lu;0;R;;;;;N;;;;10D85; +10D69;GARAY VOWEL SIGN E;Mn;230;NSM;;;;;N;;;;; +10D6A;GARAY CONSONANT GEMINATION MARK;Mn;230;NSM;;;;;N;;;;; +10D6B;GARAY COMBINING DOT ABOVE;Mn;230;NSM;;;;;N;;;;; +10D6C;GARAY COMBINING DOUBLE DOT ABOVE;Mn;230;NSM;;;;;N;;;;; +10D6D;GARAY CONSONANT NASALIZATION MARK;Mn;230;NSM;;;;;N;;;;; +10D6E;GARAY HYPHEN;Pd;0;ON;;;;;N;;;;; +10D6F;GARAY REDUPLICATION MARK;Lm;0;R;;;;;N;;;;; +10D70;GARAY SMALL LETTER A;Ll;0;R;;;;;N;;;10D50;;10D50 +10D71;GARAY SMALL LETTER CA;Ll;0;R;;;;;N;;;10D51;;10D51 +10D72;GARAY SMALL LETTER MA;Ll;0;R;;;;;N;;;10D52;;10D52 +10D73;GARAY SMALL LETTER KA;Ll;0;R;;;;;N;;;10D53;;10D53 +10D74;GARAY SMALL LETTER BA;Ll;0;R;;;;;N;;;10D54;;10D54 +10D75;GARAY SMALL LETTER JA;Ll;0;R;;;;;N;;;10D55;;10D55 +10D76;GARAY SMALL LETTER SA;Ll;0;R;;;;;N;;;10D56;;10D56 +10D77;GARAY SMALL LETTER WA;Ll;0;R;;;;;N;;;10D57;;10D57 +10D78;GARAY SMALL LETTER LA;Ll;0;R;;;;;N;;;10D58;;10D58 +10D79;GARAY SMALL LETTER GA;Ll;0;R;;;;;N;;;10D59;;10D59 +10D7A;GARAY SMALL LETTER DA;Ll;0;R;;;;;N;;;10D5A;;10D5A +10D7B;GARAY SMALL LETTER XA;Ll;0;R;;;;;N;;;10D5B;;10D5B +10D7C;GARAY SMALL LETTER YA;Ll;0;R;;;;;N;;;10D5C;;10D5C +10D7D;GARAY SMALL LETTER TA;Ll;0;R;;;;;N;;;10D5D;;10D5D +10D7E;GARAY SMALL LETTER RA;Ll;0;R;;;;;N;;;10D5E;;10D5E +10D7F;GARAY SMALL LETTER NYA;Ll;0;R;;;;;N;;;10D5F;;10D5F +10D80;GARAY SMALL LETTER FA;Ll;0;R;;;;;N;;;10D60;;10D60 +10D81;GARAY SMALL LETTER NA;Ll;0;R;;;;;N;;;10D61;;10D61 +10D82;GARAY SMALL LETTER PA;Ll;0;R;;;;;N;;;10D62;;10D62 +10D83;GARAY SMALL LETTER HA;Ll;0;R;;;;;N;;;10D63;;10D63 +10D84;GARAY SMALL LETTER OLD KA;Ll;0;R;;;;;N;;;10D64;;10D64 +10D85;GARAY SMALL LETTER OLD NA;Ll;0;R;;;;;N;;;10D65;;10D65 +10D8E;GARAY PLUS SIGN;Sm;0;R;;;;;N;;;;; +10D8F;GARAY MINUS SIGN;Sm;0;R;;;;;N;;;;; 10E60;RUMI DIGIT ONE;No;0;AN;;;1;1;N;;;;; 10E61;RUMI DIGIT TWO;No;0;AN;;;2;2;N;;;;; 10E62;RUMI DIGIT THREE;No;0;AN;;;3;3;N;;;;; @@ -19400,6 +19538,10 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;; 10EAD;YEZIDI HYPHENATION MARK;Pd;0;R;;;;;N;;;;; 10EB0;YEZIDI LETTER LAM WITH DOT ABOVE;Lo;0;R;;;;;N;;;;; 10EB1;YEZIDI LETTER YOT WITH CIRCUMFLEX ABOVE;Lo;0;R;;;;;N;;;;; +10EC2;ARABIC LETTER DAL WITH TWO DOTS VERTICALLY BELOW;Lo;0;AL;;;;;N;;;;; +10EC3;ARABIC LETTER TAH WITH TWO DOTS VERTICALLY BELOW;Lo;0;AL;;;;;N;;;;; +10EC4;ARABIC LETTER KAF WITH TWO DOTS VERTICALLY BELOW;Lo;0;AL;;;;;N;;;;; +10EFC;ARABIC COMBINING ALEF OVERLAY;Mn;0;NSM;;;;;N;;;;; 10EFD;ARABIC SMALL LOW WORD SAKTA;Mn;220;NSM;;;;;N;;;;; 10EFE;ARABIC SMALL LOW WORD QASR;Mn;220;NSM;;;;;N;;;;; 10EFF;ARABIC SMALL LOW WORD MADDA;Mn;220;NSM;;;;;N;;;;; @@ -20264,6 +20406,86 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;; 11372;COMBINING GRANTHA LETTER NA;Mn;230;NSM;;;;;N;;;;; 11373;COMBINING GRANTHA LETTER VI;Mn;230;NSM;;;;;N;;;;; 11374;COMBINING GRANTHA LETTER PA;Mn;230;NSM;;;;;N;;;;; +11380;TULU-TIGALARI LETTER A;Lo;0;L;;;;;N;;;;; +11381;TULU-TIGALARI LETTER AA;Lo;0;L;;;;;N;;;;; +11382;TULU-TIGALARI LETTER I;Lo;0;L;;;;;N;;;;; +11383;TULU-TIGALARI LETTER II;Lo;0;L;11382 113C9;;;;N;;;;; +11384;TULU-TIGALARI LETTER U;Lo;0;L;;;;;N;;;;; +11385;TULU-TIGALARI LETTER UU;Lo;0;L;11384 113BB;;;;N;;;;; +11386;TULU-TIGALARI LETTER VOCALIC R;Lo;0;L;;;;;N;;;;; +11387;TULU-TIGALARI LETTER VOCALIC RR;Lo;0;L;;;;;N;;;;; +11388;TULU-TIGALARI LETTER VOCALIC L;Lo;0;L;;;;;N;;;;; +11389;TULU-TIGALARI LETTER VOCALIC LL;Lo;0;L;;;;;N;;;;; +1138B;TULU-TIGALARI LETTER EE;Lo;0;L;;;;;N;;;;; +1138E;TULU-TIGALARI LETTER AI;Lo;0;L;1138B 113C2;;;;N;;;;; +11390;TULU-TIGALARI LETTER OO;Lo;0;L;;;;;N;;;;; +11391;TULU-TIGALARI LETTER AU;Lo;0;L;11390 113C9;;;;N;;;;; +11392;TULU-TIGALARI LETTER KA;Lo;0;L;;;;;N;;;;; +11393;TULU-TIGALARI LETTER KHA;Lo;0;L;;;;;N;;;;; +11394;TULU-TIGALARI LETTER GA;Lo;0;L;;;;;N;;;;; +11395;TULU-TIGALARI LETTER GHA;Lo;0;L;;;;;N;;;;; +11396;TULU-TIGALARI LETTER NGA;Lo;0;L;;;;;N;;;;; +11397;TULU-TIGALARI LETTER CA;Lo;0;L;;;;;N;;;;; +11398;TULU-TIGALARI LETTER CHA;Lo;0;L;;;;;N;;;;; +11399;TULU-TIGALARI LETTER JA;Lo;0;L;;;;;N;;;;; +1139A;TULU-TIGALARI LETTER JHA;Lo;0;L;;;;;N;;;;; +1139B;TULU-TIGALARI LETTER NYA;Lo;0;L;;;;;N;;;;; +1139C;TULU-TIGALARI LETTER TTA;Lo;0;L;;;;;N;;;;; +1139D;TULU-TIGALARI LETTER TTHA;Lo;0;L;;;;;N;;;;; +1139E;TULU-TIGALARI LETTER DDA;Lo;0;L;;;;;N;;;;; +1139F;TULU-TIGALARI LETTER DDHA;Lo;0;L;;;;;N;;;;; +113A0;TULU-TIGALARI LETTER NNA;Lo;0;L;;;;;N;;;;; +113A1;TULU-TIGALARI LETTER TA;Lo;0;L;;;;;N;;;;; +113A2;TULU-TIGALARI LETTER THA;Lo;0;L;;;;;N;;;;; +113A3;TULU-TIGALARI LETTER DA;Lo;0;L;;;;;N;;;;; +113A4;TULU-TIGALARI LETTER DHA;Lo;0;L;;;;;N;;;;; +113A5;TULU-TIGALARI LETTER NA;Lo;0;L;;;;;N;;;;; +113A6;TULU-TIGALARI LETTER PA;Lo;0;L;;;;;N;;;;; +113A7;TULU-TIGALARI LETTER PHA;Lo;0;L;;;;;N;;;;; +113A8;TULU-TIGALARI LETTER BA;Lo;0;L;;;;;N;;;;; +113A9;TULU-TIGALARI LETTER BHA;Lo;0;L;;;;;N;;;;; +113AA;TULU-TIGALARI LETTER MA;Lo;0;L;;;;;N;;;;; +113AB;TULU-TIGALARI LETTER YA;Lo;0;L;;;;;N;;;;; +113AC;TULU-TIGALARI LETTER RA;Lo;0;L;;;;;N;;;;; +113AD;TULU-TIGALARI LETTER LA;Lo;0;L;;;;;N;;;;; +113AE;TULU-TIGALARI LETTER VA;Lo;0;L;;;;;N;;;;; +113AF;TULU-TIGALARI LETTER SHA;Lo;0;L;;;;;N;;;;; +113B0;TULU-TIGALARI LETTER SSA;Lo;0;L;;;;;N;;;;; +113B1;TULU-TIGALARI LETTER SA;Lo;0;L;;;;;N;;;;; +113B2;TULU-TIGALARI LETTER HA;Lo;0;L;;;;;N;;;;; +113B3;TULU-TIGALARI LETTER LLA;Lo;0;L;;;;;N;;;;; +113B4;TULU-TIGALARI LETTER RRA;Lo;0;L;;;;;N;;;;; +113B5;TULU-TIGALARI LETTER LLLA;Lo;0;L;;;;;N;;;;; +113B7;TULU-TIGALARI SIGN AVAGRAHA;Lo;0;L;;;;;N;;;;; +113B8;TULU-TIGALARI VOWEL SIGN AA;Mc;0;L;;;;;N;;;;; +113B9;TULU-TIGALARI VOWEL SIGN I;Mc;0;L;;;;;N;;;;; +113BA;TULU-TIGALARI VOWEL SIGN II;Mc;0;L;;;;;N;;;;; +113BB;TULU-TIGALARI VOWEL SIGN U;Mn;0;NSM;;;;;N;;;;; +113BC;TULU-TIGALARI VOWEL SIGN UU;Mn;0;NSM;;;;;N;;;;; +113BD;TULU-TIGALARI VOWEL SIGN VOCALIC R;Mn;0;NSM;;;;;N;;;;; +113BE;TULU-TIGALARI VOWEL SIGN VOCALIC RR;Mn;0;NSM;;;;;N;;;;; +113BF;TULU-TIGALARI VOWEL SIGN VOCALIC L;Mn;0;NSM;;;;;N;;;;; +113C0;TULU-TIGALARI VOWEL SIGN VOCALIC LL;Mn;0;NSM;;;;;N;;;;; +113C2;TULU-TIGALARI VOWEL SIGN EE;Mc;0;L;;;;;N;;;;; +113C5;TULU-TIGALARI VOWEL SIGN AI;Mc;0;L;113C2 113C2;;;;N;;;;; +113C7;TULU-TIGALARI VOWEL SIGN OO;Mc;0;L;113C2 113B8;;;;N;;;;; +113C8;TULU-TIGALARI VOWEL SIGN AU;Mc;0;L;113C2 113C9;;;;N;;;;; +113C9;TULU-TIGALARI AU LENGTH MARK;Mc;0;L;;;;;N;;;;; +113CA;TULU-TIGALARI SIGN CANDRA ANUNASIKA;Mc;0;L;;;;;N;;;;; +113CC;TULU-TIGALARI SIGN ANUSVARA;Mc;0;L;;;;;N;;;;; +113CD;TULU-TIGALARI SIGN VISARGA;Mc;0;L;;;;;N;;;;; +113CE;TULU-TIGALARI SIGN VIRAMA;Mn;9;NSM;;;;;N;;;;; +113CF;TULU-TIGALARI SIGN LOOPED VIRAMA;Mc;9;L;;;;;N;;;;; +113D0;TULU-TIGALARI CONJOINER;Mn;9;NSM;;;;;N;;;;; +113D1;TULU-TIGALARI REPHA;Lo;0;L;;;;;N;;;;; +113D2;TULU-TIGALARI GEMINATION MARK;Mn;0;NSM;;;;;N;;;;; +113D3;TULU-TIGALARI SIGN PLUTA;Lo;0;L;;;;;N;;;;; +113D4;TULU-TIGALARI DANDA;Po;0;L;;;;;N;;;;; +113D5;TULU-TIGALARI DOUBLE DANDA;Po;0;L;;;;;N;;;;; +113D7;TULU-TIGALARI SIGN OM PUSHPIKA;Po;0;L;;;;;N;;;;; +113D8;TULU-TIGALARI SIGN SHRII PUSHPIKA;Po;0;L;;;;;N;;;;; +113E1;TULU-TIGALARI VEDIC TONE SVARITA;Mn;0;NSM;;;;;N;;;;; +113E2;TULU-TIGALARI VEDIC TONE ANUDATTA;Mn;0;NSM;;;;;N;;;;; 11400;NEWA LETTER A;Lo;0;L;;;;;N;;;;; 11401;NEWA LETTER AA;Lo;0;L;;;;;N;;;;; 11402;NEWA LETTER I;Lo;0;L;;;;;N;;;;; @@ -20695,6 +20917,26 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;; 116C7;TAKRI DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;; 116C8;TAKRI DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;; 116C9;TAKRI DIGIT NINE;Nd;0;L;;9;9;9;N;;;;; +116D0;MYANMAR PAO DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;; +116D1;MYANMAR PAO DIGIT ONE;Nd;0;L;;1;1;1;N;;;;; +116D2;MYANMAR PAO DIGIT TWO;Nd;0;L;;2;2;2;N;;;;; +116D3;MYANMAR PAO DIGIT THREE;Nd;0;L;;3;3;3;N;;;;; +116D4;MYANMAR PAO DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;; +116D5;MYANMAR PAO DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;; +116D6;MYANMAR PAO DIGIT SIX;Nd;0;L;;6;6;6;N;;;;; +116D7;MYANMAR PAO DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;; +116D8;MYANMAR PAO DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;; +116D9;MYANMAR PAO DIGIT NINE;Nd;0;L;;9;9;9;N;;;;; +116DA;MYANMAR EASTERN PWO KAREN DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;; +116DB;MYANMAR EASTERN PWO KAREN DIGIT ONE;Nd;0;L;;1;1;1;N;;;;; +116DC;MYANMAR EASTERN PWO KAREN DIGIT TWO;Nd;0;L;;2;2;2;N;;;;; +116DD;MYANMAR EASTERN PWO KAREN DIGIT THREE;Nd;0;L;;3;3;3;N;;;;; +116DE;MYANMAR EASTERN PWO KAREN DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;; +116DF;MYANMAR EASTERN PWO KAREN DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;; +116E0;MYANMAR EASTERN PWO KAREN DIGIT SIX;Nd;0;L;;6;6;6;N;;;;; +116E1;MYANMAR EASTERN PWO KAREN DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;; +116E2;MYANMAR EASTERN PWO KAREN DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;; +116E3;MYANMAR EASTERN PWO KAREN DIGIT NINE;Nd;0;L;;9;9;9;N;;;;; 11700;AHOM LETTER KA;Lo;0;L;;;;;N;;;;; 11701;AHOM LETTER KHA;Lo;0;L;;;;;N;;;;; 11702;AHOM LETTER NGA;Lo;0;L;;;;;N;;;;; @@ -20723,7 +20965,7 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;; 11719;AHOM LETTER JHA;Lo;0;L;;;;;N;;;;; 1171A;AHOM LETTER ALTERNATE BA;Lo;0;L;;;;;N;;;;; 1171D;AHOM CONSONANT SIGN MEDIAL LA;Mn;0;NSM;;;;;N;;;;; -1171E;AHOM CONSONANT SIGN MEDIAL RA;Mn;0;NSM;;;;;N;;;;; +1171E;AHOM CONSONANT SIGN MEDIAL RA;Mc;0;L;;;;;N;;;;; 1171F;AHOM CONSONANT SIGN MEDIAL LIGATING RA;Mn;0;NSM;;;;;N;;;;; 11720;AHOM VOWEL SIGN A;Mc;0;L;;;;;N;;;;; 11721;AHOM VOWEL SIGN AA;Mc;0;L;;;;;N;;;;; @@ -21279,6 +21521,50 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;; 11B07;DEVANAGARI SIGN WESTERN NINE-LIKE BHALE;Po;0;L;;;;;N;;;;; 11B08;DEVANAGARI SIGN REVERSED NINE-LIKE BHALE;Po;0;L;;;;;N;;;;; 11B09;DEVANAGARI SIGN MINDU;Po;0;L;;;;;N;;;;; +11BC0;SUNUWAR LETTER DEVI;Lo;0;L;;;;;N;;;;; +11BC1;SUNUWAR LETTER TASLA;Lo;0;L;;;;;N;;;;; +11BC2;SUNUWAR LETTER EKO;Lo;0;L;;;;;N;;;;; +11BC3;SUNUWAR LETTER IMAR;Lo;0;L;;;;;N;;;;; +11BC4;SUNUWAR LETTER REU;Lo;0;L;;;;;N;;;;; +11BC5;SUNUWAR LETTER UTTHI;Lo;0;L;;;;;N;;;;; +11BC6;SUNUWAR LETTER KIK;Lo;0;L;;;;;N;;;;; +11BC7;SUNUWAR LETTER MA;Lo;0;L;;;;;N;;;;; +11BC8;SUNUWAR LETTER APPHO;Lo;0;L;;;;;N;;;;; +11BC9;SUNUWAR LETTER PIP;Lo;0;L;;;;;N;;;;; +11BCA;SUNUWAR LETTER GIL;Lo;0;L;;;;;N;;;;; +11BCB;SUNUWAR LETTER HAMSO;Lo;0;L;;;;;N;;;;; +11BCC;SUNUWAR LETTER CARMI;Lo;0;L;;;;;N;;;;; +11BCD;SUNUWAR LETTER NAH;Lo;0;L;;;;;N;;;;; +11BCE;SUNUWAR LETTER BUR;Lo;0;L;;;;;N;;;;; +11BCF;SUNUWAR LETTER JYAH;Lo;0;L;;;;;N;;;;; +11BD0;SUNUWAR LETTER LOACHA;Lo;0;L;;;;;N;;;;; +11BD1;SUNUWAR LETTER OTTHI;Lo;0;L;;;;;N;;;;; +11BD2;SUNUWAR LETTER SHYELE;Lo;0;L;;;;;N;;;;; +11BD3;SUNUWAR LETTER VARCA;Lo;0;L;;;;;N;;;;; +11BD4;SUNUWAR LETTER YAT;Lo;0;L;;;;;N;;;;; +11BD5;SUNUWAR LETTER AVA;Lo;0;L;;;;;N;;;;; +11BD6;SUNUWAR LETTER AAL;Lo;0;L;;;;;N;;;;; +11BD7;SUNUWAR LETTER DONGA;Lo;0;L;;;;;N;;;;; +11BD8;SUNUWAR LETTER THARI;Lo;0;L;;;;;N;;;;; +11BD9;SUNUWAR LETTER PHAR;Lo;0;L;;;;;N;;;;; +11BDA;SUNUWAR LETTER NGAR;Lo;0;L;;;;;N;;;;; +11BDB;SUNUWAR LETTER KHA;Lo;0;L;;;;;N;;;;; +11BDC;SUNUWAR LETTER SHYER;Lo;0;L;;;;;N;;;;; +11BDD;SUNUWAR LETTER CHELAP;Lo;0;L;;;;;N;;;;; +11BDE;SUNUWAR LETTER TENTU;Lo;0;L;;;;;N;;;;; +11BDF;SUNUWAR LETTER THELE;Lo;0;L;;;;;N;;;;; +11BE0;SUNUWAR LETTER KLOKO;Lo;0;L;;;;;N;;;;; +11BE1;SUNUWAR SIGN PVO;Po;0;L;;;;;N;;;;; +11BF0;SUNUWAR DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;; +11BF1;SUNUWAR DIGIT ONE;Nd;0;L;;1;1;1;N;;;;; +11BF2;SUNUWAR DIGIT TWO;Nd;0;L;;2;2;2;N;;;;; +11BF3;SUNUWAR DIGIT THREE;Nd;0;L;;3;3;3;N;;;;; +11BF4;SUNUWAR DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;; +11BF5;SUNUWAR DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;; +11BF6;SUNUWAR DIGIT SIX;Nd;0;L;;6;6;6;N;;;;; +11BF7;SUNUWAR DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;; +11BF8;SUNUWAR DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;; +11BF9;SUNUWAR DIGIT NINE;Nd;0;L;;9;9;9;N;;;;; 11C00;BHAIKSUKI LETTER A;Lo;0;L;;;;;N;;;;; 11C01;BHAIKSUKI LETTER AA;Lo;0;L;;;;;N;;;;; 11C02;BHAIKSUKI LETTER I;Lo;0;L;;;;;N;;;;; @@ -21693,6 +21979,7 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;; 11F57;KAWI DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;; 11F58;KAWI DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;; 11F59;KAWI DIGIT NINE;Nd;0;L;;9;9;9;N;;;;; +11F5A;KAWI SIGN NUKTA;Mn;0;NSM;;;;;N;;;;; 11FB0;LISU LETTER YHA;Lo;0;L;;;;;N;;;;; 11FC0;TAMIL FRACTION ONE THREE-HUNDRED-AND-TWENTIETH;No;0;L;;;;1/320;N;;;;; 11FC1;TAMIL FRACTION ONE ONE-HUNDRED-AND-SIXTIETH;No;0;L;;;;1/160;N;;;;; @@ -24188,6 +24475,4001 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;; 13453;EGYPTIAN HIEROGLYPH MODIFIER DAMAGED AT TOP AND END;Mn;0;NSM;;;;;N;;;;; 13454;EGYPTIAN HIEROGLYPH MODIFIER DAMAGED AT BOTTOM AND END;Mn;0;NSM;;;;;N;;;;; 13455;EGYPTIAN HIEROGLYPH MODIFIER DAMAGED;Mn;0;NSM;;;;;N;;;;; +13460;EGYPTIAN HIEROGLYPH-13460;Lo;0;L;;;;;N;;;;; +13461;EGYPTIAN HIEROGLYPH-13461;Lo;0;L;;;;;N;;;;; +13462;EGYPTIAN HIEROGLYPH-13462;Lo;0;L;;;;;N;;;;; +13463;EGYPTIAN HIEROGLYPH-13463;Lo;0;L;;;;;N;;;;; +13464;EGYPTIAN HIEROGLYPH-13464;Lo;0;L;;;;;N;;;;; +13465;EGYPTIAN HIEROGLYPH-13465;Lo;0;L;;;;;N;;;;; +13466;EGYPTIAN HIEROGLYPH-13466;Lo;0;L;;;;;N;;;;; +13467;EGYPTIAN HIEROGLYPH-13467;Lo;0;L;;;;;N;;;;; +13468;EGYPTIAN HIEROGLYPH-13468;Lo;0;L;;;;;N;;;;; +13469;EGYPTIAN HIEROGLYPH-13469;Lo;0;L;;;;;N;;;;; +1346A;EGYPTIAN HIEROGLYPH-1346A;Lo;0;L;;;;;N;;;;; +1346B;EGYPTIAN HIEROGLYPH-1346B;Lo;0;L;;;;;N;;;;; +1346C;EGYPTIAN HIEROGLYPH-1346C;Lo;0;L;;;;;N;;;;; +1346D;EGYPTIAN HIEROGLYPH-1346D;Lo;0;L;;;;;N;;;;; +1346E;EGYPTIAN HIEROGLYPH-1346E;Lo;0;L;;;;;N;;;;; +1346F;EGYPTIAN HIEROGLYPH-1346F;Lo;0;L;;;;;N;;;;; +13470;EGYPTIAN HIEROGLYPH-13470;Lo;0;L;;;;;N;;;;; +13471;EGYPTIAN HIEROGLYPH-13471;Lo;0;L;;;;;N;;;;; +13472;EGYPTIAN HIEROGLYPH-13472;Lo;0;L;;;;;N;;;;; +13473;EGYPTIAN HIEROGLYPH-13473;Lo;0;L;;;;;N;;;;; +13474;EGYPTIAN HIEROGLYPH-13474;Lo;0;L;;;;;N;;;;; +13475;EGYPTIAN HIEROGLYPH-13475;Lo;0;L;;;;;N;;;;; +13476;EGYPTIAN HIEROGLYPH-13476;Lo;0;L;;;;;N;;;;; +13477;EGYPTIAN HIEROGLYPH-13477;Lo;0;L;;;;;N;;;;; +13478;EGYPTIAN HIEROGLYPH-13478;Lo;0;L;;;;;N;;;;; +13479;EGYPTIAN HIEROGLYPH-13479;Lo;0;L;;;;;N;;;;; +1347A;EGYPTIAN HIEROGLYPH-1347A;Lo;0;L;;;;;N;;;;; +1347B;EGYPTIAN HIEROGLYPH-1347B;Lo;0;L;;;;;N;;;;; +1347C;EGYPTIAN HIEROGLYPH-1347C;Lo;0;L;;;;;N;;;;; +1347D;EGYPTIAN HIEROGLYPH-1347D;Lo;0;L;;;;;N;;;;; +1347E;EGYPTIAN HIEROGLYPH-1347E;Lo;0;L;;;;;N;;;;; +1347F;EGYPTIAN HIEROGLYPH-1347F;Lo;0;L;;;;;N;;;;; +13480;EGYPTIAN HIEROGLYPH-13480;Lo;0;L;;;;;N;;;;; +13481;EGYPTIAN HIEROGLYPH-13481;Lo;0;L;;;;;N;;;;; +13482;EGYPTIAN HIEROGLYPH-13482;Lo;0;L;;;;;N;;;;; +13483;EGYPTIAN HIEROGLYPH-13483;Lo;0;L;;;;;N;;;;; +13484;EGYPTIAN HIEROGLYPH-13484;Lo;0;L;;;;;N;;;;; +13485;EGYPTIAN HIEROGLYPH-13485;Lo;0;L;;;;;N;;;;; +13486;EGYPTIAN HIEROGLYPH-13486;Lo;0;L;;;;;N;;;;; +13487;EGYPTIAN HIEROGLYPH-13487;Lo;0;L;;;;;N;;;;; +13488;EGYPTIAN HIEROGLYPH-13488;Lo;0;L;;;;;N;;;;; +13489;EGYPTIAN HIEROGLYPH-13489;Lo;0;L;;;;;N;;;;; +1348A;EGYPTIAN HIEROGLYPH-1348A;Lo;0;L;;;;;N;;;;; +1348B;EGYPTIAN HIEROGLYPH-1348B;Lo;0;L;;;;;N;;;;; +1348C;EGYPTIAN HIEROGLYPH-1348C;Lo;0;L;;;;;N;;;;; +1348D;EGYPTIAN HIEROGLYPH-1348D;Lo;0;L;;;;;N;;;;; +1348E;EGYPTIAN HIEROGLYPH-1348E;Lo;0;L;;;;;N;;;;; +1348F;EGYPTIAN HIEROGLYPH-1348F;Lo;0;L;;;;;N;;;;; +13490;EGYPTIAN HIEROGLYPH-13490;Lo;0;L;;;;;N;;;;; +13491;EGYPTIAN HIEROGLYPH-13491;Lo;0;L;;;;;N;;;;; +13492;EGYPTIAN HIEROGLYPH-13492;Lo;0;L;;;;;N;;;;; +13493;EGYPTIAN HIEROGLYPH-13493;Lo;0;L;;;;;N;;;;; +13494;EGYPTIAN HIEROGLYPH-13494;Lo;0;L;;;;;N;;;;; +13495;EGYPTIAN HIEROGLYPH-13495;Lo;0;L;;;;;N;;;;; +13496;EGYPTIAN HIEROGLYPH-13496;Lo;0;L;;;;;N;;;;; +13497;EGYPTIAN HIEROGLYPH-13497;Lo;0;L;;;;;N;;;;; +13498;EGYPTIAN HIEROGLYPH-13498;Lo;0;L;;;;;N;;;;; +13499;EGYPTIAN HIEROGLYPH-13499;Lo;0;L;;;;;N;;;;; +1349A;EGYPTIAN HIEROGLYPH-1349A;Lo;0;L;;;;;N;;;;; +1349B;EGYPTIAN HIEROGLYPH-1349B;Lo;0;L;;;;;N;;;;; +1349C;EGYPTIAN HIEROGLYPH-1349C;Lo;0;L;;;;;N;;;;; +1349D;EGYPTIAN HIEROGLYPH-1349D;Lo;0;L;;;;;N;;;;; +1349E;EGYPTIAN HIEROGLYPH-1349E;Lo;0;L;;;;;N;;;;; +1349F;EGYPTIAN HIEROGLYPH-1349F;Lo;0;L;;;;;N;;;;; +134A0;EGYPTIAN HIEROGLYPH-134A0;Lo;0;L;;;;;N;;;;; +134A1;EGYPTIAN HIEROGLYPH-134A1;Lo;0;L;;;;;N;;;;; +134A2;EGYPTIAN HIEROGLYPH-134A2;Lo;0;L;;;;;N;;;;; +134A3;EGYPTIAN HIEROGLYPH-134A3;Lo;0;L;;;;;N;;;;; +134A4;EGYPTIAN HIEROGLYPH-134A4;Lo;0;L;;;;;N;;;;; +134A5;EGYPTIAN HIEROGLYPH-134A5;Lo;0;L;;;;;N;;;;; +134A6;EGYPTIAN HIEROGLYPH-134A6;Lo;0;L;;;;;N;;;;; +134A7;EGYPTIAN HIEROGLYPH-134A7;Lo;0;L;;;;;N;;;;; +134A8;EGYPTIAN HIEROGLYPH-134A8;Lo;0;L;;;;;N;;;;; +134A9;EGYPTIAN HIEROGLYPH-134A9;Lo;0;L;;;;;N;;;;; +134AA;EGYPTIAN HIEROGLYPH-134AA;Lo;0;L;;;;;N;;;;; +134AB;EGYPTIAN HIEROGLYPH-134AB;Lo;0;L;;;;;N;;;;; +134AC;EGYPTIAN HIEROGLYPH-134AC;Lo;0;L;;;;;N;;;;; +134AD;EGYPTIAN HIEROGLYPH-134AD;Lo;0;L;;;;;N;;;;; +134AE;EGYPTIAN HIEROGLYPH-134AE;Lo;0;L;;;;;N;;;;; +134AF;EGYPTIAN HIEROGLYPH-134AF;Lo;0;L;;;;;N;;;;; +134B0;EGYPTIAN HIEROGLYPH-134B0;Lo;0;L;;;;;N;;;;; +134B1;EGYPTIAN HIEROGLYPH-134B1;Lo;0;L;;;;;N;;;;; +134B2;EGYPTIAN HIEROGLYPH-134B2;Lo;0;L;;;;;N;;;;; +134B3;EGYPTIAN HIEROGLYPH-134B3;Lo;0;L;;;;;N;;;;; +134B4;EGYPTIAN HIEROGLYPH-134B4;Lo;0;L;;;;;N;;;;; +134B5;EGYPTIAN HIEROGLYPH-134B5;Lo;0;L;;;;;N;;;;; +134B6;EGYPTIAN HIEROGLYPH-134B6;Lo;0;L;;;;;N;;;;; +134B7;EGYPTIAN HIEROGLYPH-134B7;Lo;0;L;;;;;N;;;;; +134B8;EGYPTIAN HIEROGLYPH-134B8;Lo;0;L;;;;;N;;;;; +134B9;EGYPTIAN HIEROGLYPH-134B9;Lo;0;L;;;;;N;;;;; +134BA;EGYPTIAN HIEROGLYPH-134BA;Lo;0;L;;;;;N;;;;; +134BB;EGYPTIAN HIEROGLYPH-134BB;Lo;0;L;;;;;N;;;;; +134BC;EGYPTIAN HIEROGLYPH-134BC;Lo;0;L;;;;;N;;;;; +134BD;EGYPTIAN HIEROGLYPH-134BD;Lo;0;L;;;;;N;;;;; +134BE;EGYPTIAN HIEROGLYPH-134BE;Lo;0;L;;;;;N;;;;; +134BF;EGYPTIAN HIEROGLYPH-134BF;Lo;0;L;;;;;N;;;;; +134C0;EGYPTIAN HIEROGLYPH-134C0;Lo;0;L;;;;;N;;;;; +134C1;EGYPTIAN HIEROGLYPH-134C1;Lo;0;L;;;;;N;;;;; +134C2;EGYPTIAN HIEROGLYPH-134C2;Lo;0;L;;;;;N;;;;; +134C3;EGYPTIAN HIEROGLYPH-134C3;Lo;0;L;;;;;N;;;;; +134C4;EGYPTIAN HIEROGLYPH-134C4;Lo;0;L;;;;;N;;;;; +134C5;EGYPTIAN HIEROGLYPH-134C5;Lo;0;L;;;;;N;;;;; +134C6;EGYPTIAN HIEROGLYPH-134C6;Lo;0;L;;;;;N;;;;; +134C7;EGYPTIAN HIEROGLYPH-134C7;Lo;0;L;;;;;N;;;;; +134C8;EGYPTIAN HIEROGLYPH-134C8;Lo;0;L;;;;;N;;;;; +134C9;EGYPTIAN HIEROGLYPH-134C9;Lo;0;L;;;;;N;;;;; +134CA;EGYPTIAN HIEROGLYPH-134CA;Lo;0;L;;;;;N;;;;; +134CB;EGYPTIAN HIEROGLYPH-134CB;Lo;0;L;;;;;N;;;;; +134CC;EGYPTIAN HIEROGLYPH-134CC;Lo;0;L;;;;;N;;;;; +134CD;EGYPTIAN HIEROGLYPH-134CD;Lo;0;L;;;;;N;;;;; +134CE;EGYPTIAN HIEROGLYPH-134CE;Lo;0;L;;;;;N;;;;; +134CF;EGYPTIAN HIEROGLYPH-134CF;Lo;0;L;;;;;N;;;;; +134D0;EGYPTIAN HIEROGLYPH-134D0;Lo;0;L;;;;;N;;;;; +134D1;EGYPTIAN HIEROGLYPH-134D1;Lo;0;L;;;;;N;;;;; +134D2;EGYPTIAN HIEROGLYPH-134D2;Lo;0;L;;;;;N;;;;; +134D3;EGYPTIAN HIEROGLYPH-134D3;Lo;0;L;;;;;N;;;;; +134D4;EGYPTIAN HIEROGLYPH-134D4;Lo;0;L;;;;;N;;;;; +134D5;EGYPTIAN HIEROGLYPH-134D5;Lo;0;L;;;;;N;;;;; +134D6;EGYPTIAN HIEROGLYPH-134D6;Lo;0;L;;;;;N;;;;; +134D7;EGYPTIAN HIEROGLYPH-134D7;Lo;0;L;;;;;N;;;;; +134D8;EGYPTIAN HIEROGLYPH-134D8;Lo;0;L;;;;;N;;;;; +134D9;EGYPTIAN HIEROGLYPH-134D9;Lo;0;L;;;;;N;;;;; +134DA;EGYPTIAN HIEROGLYPH-134DA;Lo;0;L;;;;;N;;;;; +134DB;EGYPTIAN HIEROGLYPH-134DB;Lo;0;L;;;;;N;;;;; +134DC;EGYPTIAN HIEROGLYPH-134DC;Lo;0;L;;;;;N;;;;; +134DD;EGYPTIAN HIEROGLYPH-134DD;Lo;0;L;;;;;N;;;;; +134DE;EGYPTIAN HIEROGLYPH-134DE;Lo;0;L;;;;;N;;;;; +134DF;EGYPTIAN HIEROGLYPH-134DF;Lo;0;L;;;;;N;;;;; +134E0;EGYPTIAN HIEROGLYPH-134E0;Lo;0;L;;;;;N;;;;; +134E1;EGYPTIAN HIEROGLYPH-134E1;Lo;0;L;;;;;N;;;;; +134E2;EGYPTIAN HIEROGLYPH-134E2;Lo;0;L;;;;;N;;;;; +134E3;EGYPTIAN HIEROGLYPH-134E3;Lo;0;L;;;;;N;;;;; +134E4;EGYPTIAN HIEROGLYPH-134E4;Lo;0;L;;;;;N;;;;; +134E5;EGYPTIAN HIEROGLYPH-134E5;Lo;0;L;;;;;N;;;;; +134E6;EGYPTIAN HIEROGLYPH-134E6;Lo;0;L;;;;;N;;;;; +134E7;EGYPTIAN HIEROGLYPH-134E7;Lo;0;L;;;;;N;;;;; +134E8;EGYPTIAN HIEROGLYPH-134E8;Lo;0;L;;;;;N;;;;; +134E9;EGYPTIAN HIEROGLYPH-134E9;Lo;0;L;;;;;N;;;;; +134EA;EGYPTIAN HIEROGLYPH-134EA;Lo;0;L;;;;;N;;;;; +134EB;EGYPTIAN HIEROGLYPH-134EB;Lo;0;L;;;;;N;;;;; +134EC;EGYPTIAN HIEROGLYPH-134EC;Lo;0;L;;;;;N;;;;; +134ED;EGYPTIAN HIEROGLYPH-134ED;Lo;0;L;;;;;N;;;;; +134EE;EGYPTIAN HIEROGLYPH-134EE;Lo;0;L;;;;;N;;;;; +134EF;EGYPTIAN HIEROGLYPH-134EF;Lo;0;L;;;;;N;;;;; +134F0;EGYPTIAN HIEROGLYPH-134F0;Lo;0;L;;;;;N;;;;; +134F1;EGYPTIAN HIEROGLYPH-134F1;Lo;0;L;;;;;N;;;;; +134F2;EGYPTIAN HIEROGLYPH-134F2;Lo;0;L;;;;;N;;;;; +134F3;EGYPTIAN HIEROGLYPH-134F3;Lo;0;L;;;;;N;;;;; +134F4;EGYPTIAN HIEROGLYPH-134F4;Lo;0;L;;;;;N;;;;; +134F5;EGYPTIAN HIEROGLYPH-134F5;Lo;0;L;;;;;N;;;;; +134F6;EGYPTIAN HIEROGLYPH-134F6;Lo;0;L;;;;;N;;;;; +134F7;EGYPTIAN HIEROGLYPH-134F7;Lo;0;L;;;;;N;;;;; +134F8;EGYPTIAN HIEROGLYPH-134F8;Lo;0;L;;;;;N;;;;; +134F9;EGYPTIAN HIEROGLYPH-134F9;Lo;0;L;;;;;N;;;;; +134FA;EGYPTIAN HIEROGLYPH-134FA;Lo;0;L;;;;;N;;;;; +134FB;EGYPTIAN HIEROGLYPH-134FB;Lo;0;L;;;;;N;;;;; +134FC;EGYPTIAN HIEROGLYPH-134FC;Lo;0;L;;;;;N;;;;; +134FD;EGYPTIAN HIEROGLYPH-134FD;Lo;0;L;;;;;N;;;;; +134FE;EGYPTIAN HIEROGLYPH-134FE;Lo;0;L;;;;;N;;;;; +134FF;EGYPTIAN HIEROGLYPH-134FF;Lo;0;L;;;;;N;;;;; +13500;EGYPTIAN HIEROGLYPH-13500;Lo;0;L;;;;;N;;;;; +13501;EGYPTIAN HIEROGLYPH-13501;Lo;0;L;;;;;N;;;;; +13502;EGYPTIAN HIEROGLYPH-13502;Lo;0;L;;;;;N;;;;; +13503;EGYPTIAN HIEROGLYPH-13503;Lo;0;L;;;;;N;;;;; +13504;EGYPTIAN HIEROGLYPH-13504;Lo;0;L;;;;;N;;;;; +13505;EGYPTIAN HIEROGLYPH-13505;Lo;0;L;;;;;N;;;;; +13506;EGYPTIAN HIEROGLYPH-13506;Lo;0;L;;;;;N;;;;; +13507;EGYPTIAN HIEROGLYPH-13507;Lo;0;L;;;;;N;;;;; +13508;EGYPTIAN HIEROGLYPH-13508;Lo;0;L;;;;;N;;;;; +13509;EGYPTIAN HIEROGLYPH-13509;Lo;0;L;;;;;N;;;;; +1350A;EGYPTIAN HIEROGLYPH-1350A;Lo;0;L;;;;;N;;;;; +1350B;EGYPTIAN HIEROGLYPH-1350B;Lo;0;L;;;;;N;;;;; +1350C;EGYPTIAN HIEROGLYPH-1350C;Lo;0;L;;;;;N;;;;; +1350D;EGYPTIAN HIEROGLYPH-1350D;Lo;0;L;;;;;N;;;;; +1350E;EGYPTIAN HIEROGLYPH-1350E;Lo;0;L;;;;;N;;;;; +1350F;EGYPTIAN HIEROGLYPH-1350F;Lo;0;L;;;;;N;;;;; +13510;EGYPTIAN HIEROGLYPH-13510;Lo;0;L;;;;;N;;;;; +13511;EGYPTIAN HIEROGLYPH-13511;Lo;0;L;;;;;N;;;;; +13512;EGYPTIAN HIEROGLYPH-13512;Lo;0;L;;;;;N;;;;; +13513;EGYPTIAN HIEROGLYPH-13513;Lo;0;L;;;;;N;;;;; +13514;EGYPTIAN HIEROGLYPH-13514;Lo;0;L;;;;;N;;;;; +13515;EGYPTIAN HIEROGLYPH-13515;Lo;0;L;;;;;N;;;;; +13516;EGYPTIAN HIEROGLYPH-13516;Lo;0;L;;;;;N;;;;; +13517;EGYPTIAN HIEROGLYPH-13517;Lo;0;L;;;;;N;;;;; +13518;EGYPTIAN HIEROGLYPH-13518;Lo;0;L;;;;;N;;;;; +13519;EGYPTIAN HIEROGLYPH-13519;Lo;0;L;;;;;N;;;;; +1351A;EGYPTIAN HIEROGLYPH-1351A;Lo;0;L;;;;;N;;;;; +1351B;EGYPTIAN HIEROGLYPH-1351B;Lo;0;L;;;;;N;;;;; +1351C;EGYPTIAN HIEROGLYPH-1351C;Lo;0;L;;;;;N;;;;; +1351D;EGYPTIAN HIEROGLYPH-1351D;Lo;0;L;;;;;N;;;;; +1351E;EGYPTIAN HIEROGLYPH-1351E;Lo;0;L;;;;;N;;;;; +1351F;EGYPTIAN HIEROGLYPH-1351F;Lo;0;L;;;;;N;;;;; +13520;EGYPTIAN HIEROGLYPH-13520;Lo;0;L;;;;;N;;;;; +13521;EGYPTIAN HIEROGLYPH-13521;Lo;0;L;;;;;N;;;;; +13522;EGYPTIAN HIEROGLYPH-13522;Lo;0;L;;;;;N;;;;; +13523;EGYPTIAN HIEROGLYPH-13523;Lo;0;L;;;;;N;;;;; +13524;EGYPTIAN HIEROGLYPH-13524;Lo;0;L;;;;;N;;;;; +13525;EGYPTIAN HIEROGLYPH-13525;Lo;0;L;;;;;N;;;;; +13526;EGYPTIAN HIEROGLYPH-13526;Lo;0;L;;;;;N;;;;; +13527;EGYPTIAN HIEROGLYPH-13527;Lo;0;L;;;;;N;;;;; +13528;EGYPTIAN HIEROGLYPH-13528;Lo;0;L;;;;;N;;;;; +13529;EGYPTIAN HIEROGLYPH-13529;Lo;0;L;;;;;N;;;;; +1352A;EGYPTIAN HIEROGLYPH-1352A;Lo;0;L;;;;;N;;;;; +1352B;EGYPTIAN HIEROGLYPH-1352B;Lo;0;L;;;;;N;;;;; +1352C;EGYPTIAN HIEROGLYPH-1352C;Lo;0;L;;;;;N;;;;; +1352D;EGYPTIAN HIEROGLYPH-1352D;Lo;0;L;;;;;N;;;;; +1352E;EGYPTIAN HIEROGLYPH-1352E;Lo;0;L;;;;;N;;;;; +1352F;EGYPTIAN HIEROGLYPH-1352F;Lo;0;L;;;;;N;;;;; +13530;EGYPTIAN HIEROGLYPH-13530;Lo;0;L;;;;;N;;;;; +13531;EGYPTIAN HIEROGLYPH-13531;Lo;0;L;;;;;N;;;;; +13532;EGYPTIAN HIEROGLYPH-13532;Lo;0;L;;;;;N;;;;; +13533;EGYPTIAN HIEROGLYPH-13533;Lo;0;L;;;;;N;;;;; +13534;EGYPTIAN HIEROGLYPH-13534;Lo;0;L;;;;;N;;;;; +13535;EGYPTIAN HIEROGLYPH-13535;Lo;0;L;;;;;N;;;;; +13536;EGYPTIAN HIEROGLYPH-13536;Lo;0;L;;;;;N;;;;; +13537;EGYPTIAN HIEROGLYPH-13537;Lo;0;L;;;;;N;;;;; +13538;EGYPTIAN HIEROGLYPH-13538;Lo;0;L;;;;;N;;;;; +13539;EGYPTIAN HIEROGLYPH-13539;Lo;0;L;;;;;N;;;;; +1353A;EGYPTIAN HIEROGLYPH-1353A;Lo;0;L;;;;;N;;;;; +1353B;EGYPTIAN HIEROGLYPH-1353B;Lo;0;L;;;;;N;;;;; +1353C;EGYPTIAN HIEROGLYPH-1353C;Lo;0;L;;;;;N;;;;; +1353D;EGYPTIAN HIEROGLYPH-1353D;Lo;0;L;;;;;N;;;;; +1353E;EGYPTIAN HIEROGLYPH-1353E;Lo;0;L;;;;;N;;;;; +1353F;EGYPTIAN HIEROGLYPH-1353F;Lo;0;L;;;;;N;;;;; +13540;EGYPTIAN HIEROGLYPH-13540;Lo;0;L;;;;;N;;;;; +13541;EGYPTIAN HIEROGLYPH-13541;Lo;0;L;;;;;N;;;;; +13542;EGYPTIAN HIEROGLYPH-13542;Lo;0;L;;;;;N;;;;; +13543;EGYPTIAN HIEROGLYPH-13543;Lo;0;L;;;;;N;;;;; +13544;EGYPTIAN HIEROGLYPH-13544;Lo;0;L;;;;;N;;;;; +13545;EGYPTIAN HIEROGLYPH-13545;Lo;0;L;;;;;N;;;;; +13546;EGYPTIAN HIEROGLYPH-13546;Lo;0;L;;;;;N;;;;; +13547;EGYPTIAN HIEROGLYPH-13547;Lo;0;L;;;;;N;;;;; +13548;EGYPTIAN HIEROGLYPH-13548;Lo;0;L;;;;;N;;;;; +13549;EGYPTIAN HIEROGLYPH-13549;Lo;0;L;;;;;N;;;;; +1354A;EGYPTIAN HIEROGLYPH-1354A;Lo;0;L;;;;;N;;;;; +1354B;EGYPTIAN HIEROGLYPH-1354B;Lo;0;L;;;;;N;;;;; +1354C;EGYPTIAN HIEROGLYPH-1354C;Lo;0;L;;;;;N;;;;; +1354D;EGYPTIAN HIEROGLYPH-1354D;Lo;0;L;;;;;N;;;;; +1354E;EGYPTIAN HIEROGLYPH-1354E;Lo;0;L;;;;;N;;;;; +1354F;EGYPTIAN HIEROGLYPH-1354F;Lo;0;L;;;;;N;;;;; +13550;EGYPTIAN HIEROGLYPH-13550;Lo;0;L;;;;;N;;;;; +13551;EGYPTIAN HIEROGLYPH-13551;Lo;0;L;;;;;N;;;;; +13552;EGYPTIAN HIEROGLYPH-13552;Lo;0;L;;;;;N;;;;; +13553;EGYPTIAN HIEROGLYPH-13553;Lo;0;L;;;;;N;;;;; +13554;EGYPTIAN HIEROGLYPH-13554;Lo;0;L;;;;;N;;;;; +13555;EGYPTIAN HIEROGLYPH-13555;Lo;0;L;;;;;N;;;;; +13556;EGYPTIAN HIEROGLYPH-13556;Lo;0;L;;;;;N;;;;; +13557;EGYPTIAN HIEROGLYPH-13557;Lo;0;L;;;;;N;;;;; +13558;EGYPTIAN HIEROGLYPH-13558;Lo;0;L;;;;;N;;;;; +13559;EGYPTIAN HIEROGLYPH-13559;Lo;0;L;;;;;N;;;;; +1355A;EGYPTIAN HIEROGLYPH-1355A;Lo;0;L;;;;;N;;;;; +1355B;EGYPTIAN HIEROGLYPH-1355B;Lo;0;L;;;;;N;;;;; +1355C;EGYPTIAN HIEROGLYPH-1355C;Lo;0;L;;;;;N;;;;; +1355D;EGYPTIAN HIEROGLYPH-1355D;Lo;0;L;;;;;N;;;;; +1355E;EGYPTIAN HIEROGLYPH-1355E;Lo;0;L;;;;;N;;;;; +1355F;EGYPTIAN HIEROGLYPH-1355F;Lo;0;L;;;;;N;;;;; +13560;EGYPTIAN HIEROGLYPH-13560;Lo;0;L;;;;;N;;;;; +13561;EGYPTIAN HIEROGLYPH-13561;Lo;0;L;;;;;N;;;;; +13562;EGYPTIAN HIEROGLYPH-13562;Lo;0;L;;;;;N;;;;; +13563;EGYPTIAN HIEROGLYPH-13563;Lo;0;L;;;;;N;;;;; +13564;EGYPTIAN HIEROGLYPH-13564;Lo;0;L;;;;;N;;;;; +13565;EGYPTIAN HIEROGLYPH-13565;Lo;0;L;;;;;N;;;;; +13566;EGYPTIAN HIEROGLYPH-13566;Lo;0;L;;;;;N;;;;; +13567;EGYPTIAN HIEROGLYPH-13567;Lo;0;L;;;;;N;;;;; +13568;EGYPTIAN HIEROGLYPH-13568;Lo;0;L;;;;;N;;;;; +13569;EGYPTIAN HIEROGLYPH-13569;Lo;0;L;;;;;N;;;;; +1356A;EGYPTIAN HIEROGLYPH-1356A;Lo;0;L;;;;;N;;;;; +1356B;EGYPTIAN HIEROGLYPH-1356B;Lo;0;L;;;;;N;;;;; +1356C;EGYPTIAN HIEROGLYPH-1356C;Lo;0;L;;;;;N;;;;; +1356D;EGYPTIAN HIEROGLYPH-1356D;Lo;0;L;;;;;N;;;;; +1356E;EGYPTIAN HIEROGLYPH-1356E;Lo;0;L;;;;;N;;;;; +1356F;EGYPTIAN HIEROGLYPH-1356F;Lo;0;L;;;;;N;;;;; +13570;EGYPTIAN HIEROGLYPH-13570;Lo;0;L;;;;;N;;;;; +13571;EGYPTIAN HIEROGLYPH-13571;Lo;0;L;;;;;N;;;;; +13572;EGYPTIAN HIEROGLYPH-13572;Lo;0;L;;;;;N;;;;; +13573;EGYPTIAN HIEROGLYPH-13573;Lo;0;L;;;;;N;;;;; +13574;EGYPTIAN HIEROGLYPH-13574;Lo;0;L;;;;;N;;;;; +13575;EGYPTIAN HIEROGLYPH-13575;Lo;0;L;;;;;N;;;;; +13576;EGYPTIAN HIEROGLYPH-13576;Lo;0;L;;;;;N;;;;; +13577;EGYPTIAN HIEROGLYPH-13577;Lo;0;L;;;;;N;;;;; +13578;EGYPTIAN HIEROGLYPH-13578;Lo;0;L;;;;;N;;;;; +13579;EGYPTIAN HIEROGLYPH-13579;Lo;0;L;;;;;N;;;;; +1357A;EGYPTIAN HIEROGLYPH-1357A;Lo;0;L;;;;;N;;;;; +1357B;EGYPTIAN HIEROGLYPH-1357B;Lo;0;L;;;;;N;;;;; +1357C;EGYPTIAN HIEROGLYPH-1357C;Lo;0;L;;;;;N;;;;; +1357D;EGYPTIAN HIEROGLYPH-1357D;Lo;0;L;;;;;N;;;;; +1357E;EGYPTIAN HIEROGLYPH-1357E;Lo;0;L;;;;;N;;;;; +1357F;EGYPTIAN HIEROGLYPH-1357F;Lo;0;L;;;;;N;;;;; +13580;EGYPTIAN HIEROGLYPH-13580;Lo;0;L;;;;;N;;;;; +13581;EGYPTIAN HIEROGLYPH-13581;Lo;0;L;;;;;N;;;;; +13582;EGYPTIAN HIEROGLYPH-13582;Lo;0;L;;;;;N;;;;; +13583;EGYPTIAN HIEROGLYPH-13583;Lo;0;L;;;;;N;;;;; +13584;EGYPTIAN HIEROGLYPH-13584;Lo;0;L;;;;;N;;;;; +13585;EGYPTIAN HIEROGLYPH-13585;Lo;0;L;;;;;N;;;;; +13586;EGYPTIAN HIEROGLYPH-13586;Lo;0;L;;;;;N;;;;; +13587;EGYPTIAN HIEROGLYPH-13587;Lo;0;L;;;;;N;;;;; +13588;EGYPTIAN HIEROGLYPH-13588;Lo;0;L;;;;;N;;;;; +13589;EGYPTIAN HIEROGLYPH-13589;Lo;0;L;;;;;N;;;;; +1358A;EGYPTIAN HIEROGLYPH-1358A;Lo;0;L;;;;;N;;;;; +1358B;EGYPTIAN HIEROGLYPH-1358B;Lo;0;L;;;;;N;;;;; +1358C;EGYPTIAN HIEROGLYPH-1358C;Lo;0;L;;;;;N;;;;; +1358D;EGYPTIAN HIEROGLYPH-1358D;Lo;0;L;;;;;N;;;;; +1358E;EGYPTIAN HIEROGLYPH-1358E;Lo;0;L;;;;;N;;;;; +1358F;EGYPTIAN HIEROGLYPH-1358F;Lo;0;L;;;;;N;;;;; +13590;EGYPTIAN HIEROGLYPH-13590;Lo;0;L;;;;;N;;;;; +13591;EGYPTIAN HIEROGLYPH-13591;Lo;0;L;;;;;N;;;;; +13592;EGYPTIAN HIEROGLYPH-13592;Lo;0;L;;;;;N;;;;; +13593;EGYPTIAN HIEROGLYPH-13593;Lo;0;L;;;;;N;;;;; +13594;EGYPTIAN HIEROGLYPH-13594;Lo;0;L;;;;;N;;;;; +13595;EGYPTIAN HIEROGLYPH-13595;Lo;0;L;;;;;N;;;;; +13596;EGYPTIAN HIEROGLYPH-13596;Lo;0;L;;;;;N;;;;; +13597;EGYPTIAN HIEROGLYPH-13597;Lo;0;L;;;;;N;;;;; +13598;EGYPTIAN HIEROGLYPH-13598;Lo;0;L;;;;;N;;;;; +13599;EGYPTIAN HIEROGLYPH-13599;Lo;0;L;;;;;N;;;;; +1359A;EGYPTIAN HIEROGLYPH-1359A;Lo;0;L;;;;;N;;;;; +1359B;EGYPTIAN HIEROGLYPH-1359B;Lo;0;L;;;;;N;;;;; +1359C;EGYPTIAN HIEROGLYPH-1359C;Lo;0;L;;;;;N;;;;; +1359D;EGYPTIAN HIEROGLYPH-1359D;Lo;0;L;;;;;N;;;;; +1359E;EGYPTIAN HIEROGLYPH-1359E;Lo;0;L;;;;;N;;;;; +1359F;EGYPTIAN HIEROGLYPH-1359F;Lo;0;L;;;;;N;;;;; +135A0;EGYPTIAN HIEROGLYPH-135A0;Lo;0;L;;;;;N;;;;; +135A1;EGYPTIAN HIEROGLYPH-135A1;Lo;0;L;;;;;N;;;;; +135A2;EGYPTIAN HIEROGLYPH-135A2;Lo;0;L;;;;;N;;;;; +135A3;EGYPTIAN HIEROGLYPH-135A3;Lo;0;L;;;;;N;;;;; +135A4;EGYPTIAN HIEROGLYPH-135A4;Lo;0;L;;;;;N;;;;; +135A5;EGYPTIAN HIEROGLYPH-135A5;Lo;0;L;;;;;N;;;;; +135A6;EGYPTIAN HIEROGLYPH-135A6;Lo;0;L;;;;;N;;;;; +135A7;EGYPTIAN HIEROGLYPH-135A7;Lo;0;L;;;;;N;;;;; +135A8;EGYPTIAN HIEROGLYPH-135A8;Lo;0;L;;;;;N;;;;; +135A9;EGYPTIAN HIEROGLYPH-135A9;Lo;0;L;;;;;N;;;;; +135AA;EGYPTIAN HIEROGLYPH-135AA;Lo;0;L;;;;;N;;;;; +135AB;EGYPTIAN HIEROGLYPH-135AB;Lo;0;L;;;;;N;;;;; +135AC;EGYPTIAN HIEROGLYPH-135AC;Lo;0;L;;;;;N;;;;; +135AD;EGYPTIAN HIEROGLYPH-135AD;Lo;0;L;;;;;N;;;;; +135AE;EGYPTIAN HIEROGLYPH-135AE;Lo;0;L;;;;;N;;;;; +135AF;EGYPTIAN HIEROGLYPH-135AF;Lo;0;L;;;;;N;;;;; +135B0;EGYPTIAN HIEROGLYPH-135B0;Lo;0;L;;;;;N;;;;; +135B1;EGYPTIAN HIEROGLYPH-135B1;Lo;0;L;;;;;N;;;;; +135B2;EGYPTIAN HIEROGLYPH-135B2;Lo;0;L;;;;;N;;;;; +135B3;EGYPTIAN HIEROGLYPH-135B3;Lo;0;L;;;;;N;;;;; +135B4;EGYPTIAN HIEROGLYPH-135B4;Lo;0;L;;;;;N;;;;; +135B5;EGYPTIAN HIEROGLYPH-135B5;Lo;0;L;;;;;N;;;;; +135B6;EGYPTIAN HIEROGLYPH-135B6;Lo;0;L;;;;;N;;;;; +135B7;EGYPTIAN HIEROGLYPH-135B7;Lo;0;L;;;;;N;;;;; +135B8;EGYPTIAN HIEROGLYPH-135B8;Lo;0;L;;;;;N;;;;; +135B9;EGYPTIAN HIEROGLYPH-135B9;Lo;0;L;;;;;N;;;;; +135BA;EGYPTIAN HIEROGLYPH-135BA;Lo;0;L;;;;;N;;;;; +135BB;EGYPTIAN HIEROGLYPH-135BB;Lo;0;L;;;;;N;;;;; +135BC;EGYPTIAN HIEROGLYPH-135BC;Lo;0;L;;;;;N;;;;; +135BD;EGYPTIAN HIEROGLYPH-135BD;Lo;0;L;;;;;N;;;;; +135BE;EGYPTIAN HIEROGLYPH-135BE;Lo;0;L;;;;;N;;;;; +135BF;EGYPTIAN HIEROGLYPH-135BF;Lo;0;L;;;;;N;;;;; +135C0;EGYPTIAN HIEROGLYPH-135C0;Lo;0;L;;;;;N;;;;; +135C1;EGYPTIAN HIEROGLYPH-135C1;Lo;0;L;;;;;N;;;;; +135C2;EGYPTIAN HIEROGLYPH-135C2;Lo;0;L;;;;;N;;;;; +135C3;EGYPTIAN HIEROGLYPH-135C3;Lo;0;L;;;;;N;;;;; +135C4;EGYPTIAN HIEROGLYPH-135C4;Lo;0;L;;;;;N;;;;; +135C5;EGYPTIAN HIEROGLYPH-135C5;Lo;0;L;;;;;N;;;;; +135C6;EGYPTIAN HIEROGLYPH-135C6;Lo;0;L;;;;;N;;;;; +135C7;EGYPTIAN HIEROGLYPH-135C7;Lo;0;L;;;;;N;;;;; +135C8;EGYPTIAN HIEROGLYPH-135C8;Lo;0;L;;;;;N;;;;; +135C9;EGYPTIAN HIEROGLYPH-135C9;Lo;0;L;;;;;N;;;;; +135CA;EGYPTIAN HIEROGLYPH-135CA;Lo;0;L;;;;;N;;;;; +135CB;EGYPTIAN HIEROGLYPH-135CB;Lo;0;L;;;;;N;;;;; +135CC;EGYPTIAN HIEROGLYPH-135CC;Lo;0;L;;;;;N;;;;; +135CD;EGYPTIAN HIEROGLYPH-135CD;Lo;0;L;;;;;N;;;;; +135CE;EGYPTIAN HIEROGLYPH-135CE;Lo;0;L;;;;;N;;;;; +135CF;EGYPTIAN HIEROGLYPH-135CF;Lo;0;L;;;;;N;;;;; +135D0;EGYPTIAN HIEROGLYPH-135D0;Lo;0;L;;;;;N;;;;; +135D1;EGYPTIAN HIEROGLYPH-135D1;Lo;0;L;;;;;N;;;;; +135D2;EGYPTIAN HIEROGLYPH-135D2;Lo;0;L;;;;;N;;;;; +135D3;EGYPTIAN HIEROGLYPH-135D3;Lo;0;L;;;;;N;;;;; +135D4;EGYPTIAN HIEROGLYPH-135D4;Lo;0;L;;;;;N;;;;; +135D5;EGYPTIAN HIEROGLYPH-135D5;Lo;0;L;;;;;N;;;;; +135D6;EGYPTIAN HIEROGLYPH-135D6;Lo;0;L;;;;;N;;;;; +135D7;EGYPTIAN HIEROGLYPH-135D7;Lo;0;L;;;;;N;;;;; +135D8;EGYPTIAN HIEROGLYPH-135D8;Lo;0;L;;;;;N;;;;; +135D9;EGYPTIAN HIEROGLYPH-135D9;Lo;0;L;;;;;N;;;;; +135DA;EGYPTIAN HIEROGLYPH-135DA;Lo;0;L;;;;;N;;;;; +135DB;EGYPTIAN HIEROGLYPH-135DB;Lo;0;L;;;;;N;;;;; +135DC;EGYPTIAN HIEROGLYPH-135DC;Lo;0;L;;;;;N;;;;; +135DD;EGYPTIAN HIEROGLYPH-135DD;Lo;0;L;;;;;N;;;;; +135DE;EGYPTIAN HIEROGLYPH-135DE;Lo;0;L;;;;;N;;;;; +135DF;EGYPTIAN HIEROGLYPH-135DF;Lo;0;L;;;;;N;;;;; +135E0;EGYPTIAN HIEROGLYPH-135E0;Lo;0;L;;;;;N;;;;; +135E1;EGYPTIAN HIEROGLYPH-135E1;Lo;0;L;;;;;N;;;;; +135E2;EGYPTIAN HIEROGLYPH-135E2;Lo;0;L;;;;;N;;;;; +135E3;EGYPTIAN HIEROGLYPH-135E3;Lo;0;L;;;;;N;;;;; +135E4;EGYPTIAN HIEROGLYPH-135E4;Lo;0;L;;;;;N;;;;; +135E5;EGYPTIAN HIEROGLYPH-135E5;Lo;0;L;;;;;N;;;;; +135E6;EGYPTIAN HIEROGLYPH-135E6;Lo;0;L;;;;;N;;;;; +135E7;EGYPTIAN HIEROGLYPH-135E7;Lo;0;L;;;;;N;;;;; +135E8;EGYPTIAN HIEROGLYPH-135E8;Lo;0;L;;;;;N;;;;; +135E9;EGYPTIAN HIEROGLYPH-135E9;Lo;0;L;;;;;N;;;;; +135EA;EGYPTIAN HIEROGLYPH-135EA;Lo;0;L;;;;;N;;;;; +135EB;EGYPTIAN HIEROGLYPH-135EB;Lo;0;L;;;;;N;;;;; +135EC;EGYPTIAN HIEROGLYPH-135EC;Lo;0;L;;;;;N;;;;; +135ED;EGYPTIAN HIEROGLYPH-135ED;Lo;0;L;;;;;N;;;;; +135EE;EGYPTIAN HIEROGLYPH-135EE;Lo;0;L;;;;;N;;;;; +135EF;EGYPTIAN HIEROGLYPH-135EF;Lo;0;L;;;;;N;;;;; +135F0;EGYPTIAN HIEROGLYPH-135F0;Lo;0;L;;;;;N;;;;; +135F1;EGYPTIAN HIEROGLYPH-135F1;Lo;0;L;;;;;N;;;;; +135F2;EGYPTIAN HIEROGLYPH-135F2;Lo;0;L;;;;;N;;;;; +135F3;EGYPTIAN HIEROGLYPH-135F3;Lo;0;L;;;;;N;;;;; +135F4;EGYPTIAN HIEROGLYPH-135F4;Lo;0;L;;;;;N;;;;; +135F5;EGYPTIAN HIEROGLYPH-135F5;Lo;0;L;;;;;N;;;;; +135F6;EGYPTIAN HIEROGLYPH-135F6;Lo;0;L;;;;;N;;;;; +135F7;EGYPTIAN HIEROGLYPH-135F7;Lo;0;L;;;;;N;;;;; +135F8;EGYPTIAN HIEROGLYPH-135F8;Lo;0;L;;;;;N;;;;; +135F9;EGYPTIAN HIEROGLYPH-135F9;Lo;0;L;;;;;N;;;;; +135FA;EGYPTIAN HIEROGLYPH-135FA;Lo;0;L;;;;;N;;;;; +135FB;EGYPTIAN HIEROGLYPH-135FB;Lo;0;L;;;;;N;;;;; +135FC;EGYPTIAN HIEROGLYPH-135FC;Lo;0;L;;;;;N;;;;; +135FD;EGYPTIAN HIEROGLYPH-135FD;Lo;0;L;;;;;N;;;;; +135FE;EGYPTIAN HIEROGLYPH-135FE;Lo;0;L;;;;;N;;;;; +135FF;EGYPTIAN HIEROGLYPH-135FF;Lo;0;L;;;;;N;;;;; +13600;EGYPTIAN HIEROGLYPH-13600;Lo;0;L;;;;;N;;;;; +13601;EGYPTIAN HIEROGLYPH-13601;Lo;0;L;;;;;N;;;;; +13602;EGYPTIAN HIEROGLYPH-13602;Lo;0;L;;;;;N;;;;; +13603;EGYPTIAN HIEROGLYPH-13603;Lo;0;L;;;;;N;;;;; +13604;EGYPTIAN HIEROGLYPH-13604;Lo;0;L;;;;;N;;;;; +13605;EGYPTIAN HIEROGLYPH-13605;Lo;0;L;;;;;N;;;;; +13606;EGYPTIAN HIEROGLYPH-13606;Lo;0;L;;;;;N;;;;; +13607;EGYPTIAN HIEROGLYPH-13607;Lo;0;L;;;;;N;;;;; +13608;EGYPTIAN HIEROGLYPH-13608;Lo;0;L;;;;;N;;;;; +13609;EGYPTIAN HIEROGLYPH-13609;Lo;0;L;;;;;N;;;;; +1360A;EGYPTIAN HIEROGLYPH-1360A;Lo;0;L;;;;;N;;;;; +1360B;EGYPTIAN HIEROGLYPH-1360B;Lo;0;L;;;;;N;;;;; +1360C;EGYPTIAN HIEROGLYPH-1360C;Lo;0;L;;;;;N;;;;; +1360D;EGYPTIAN HIEROGLYPH-1360D;Lo;0;L;;;;;N;;;;; +1360E;EGYPTIAN HIEROGLYPH-1360E;Lo;0;L;;;;;N;;;;; +1360F;EGYPTIAN HIEROGLYPH-1360F;Lo;0;L;;;;;N;;;;; +13610;EGYPTIAN HIEROGLYPH-13610;Lo;0;L;;;;;N;;;;; +13611;EGYPTIAN HIEROGLYPH-13611;Lo;0;L;;;;;N;;;;; +13612;EGYPTIAN HIEROGLYPH-13612;Lo;0;L;;;;;N;;;;; +13613;EGYPTIAN HIEROGLYPH-13613;Lo;0;L;;;;;N;;;;; +13614;EGYPTIAN HIEROGLYPH-13614;Lo;0;L;;;;;N;;;;; +13615;EGYPTIAN HIEROGLYPH-13615;Lo;0;L;;;;;N;;;;; +13616;EGYPTIAN HIEROGLYPH-13616;Lo;0;L;;;;;N;;;;; +13617;EGYPTIAN HIEROGLYPH-13617;Lo;0;L;;;;;N;;;;; +13618;EGYPTIAN HIEROGLYPH-13618;Lo;0;L;;;;;N;;;;; +13619;EGYPTIAN HIEROGLYPH-13619;Lo;0;L;;;;;N;;;;; +1361A;EGYPTIAN HIEROGLYPH-1361A;Lo;0;L;;;;;N;;;;; +1361B;EGYPTIAN HIEROGLYPH-1361B;Lo;0;L;;;;;N;;;;; +1361C;EGYPTIAN HIEROGLYPH-1361C;Lo;0;L;;;;;N;;;;; +1361D;EGYPTIAN HIEROGLYPH-1361D;Lo;0;L;;;;;N;;;;; +1361E;EGYPTIAN HIEROGLYPH-1361E;Lo;0;L;;;;;N;;;;; +1361F;EGYPTIAN HIEROGLYPH-1361F;Lo;0;L;;;;;N;;;;; +13620;EGYPTIAN HIEROGLYPH-13620;Lo;0;L;;;;;N;;;;; +13621;EGYPTIAN HIEROGLYPH-13621;Lo;0;L;;;;;N;;;;; +13622;EGYPTIAN HIEROGLYPH-13622;Lo;0;L;;;;;N;;;;; +13623;EGYPTIAN HIEROGLYPH-13623;Lo;0;L;;;;;N;;;;; +13624;EGYPTIAN HIEROGLYPH-13624;Lo;0;L;;;;;N;;;;; +13625;EGYPTIAN HIEROGLYPH-13625;Lo;0;L;;;;;N;;;;; +13626;EGYPTIAN HIEROGLYPH-13626;Lo;0;L;;;;;N;;;;; +13627;EGYPTIAN HIEROGLYPH-13627;Lo;0;L;;;;;N;;;;; +13628;EGYPTIAN HIEROGLYPH-13628;Lo;0;L;;;;;N;;;;; +13629;EGYPTIAN HIEROGLYPH-13629;Lo;0;L;;;;;N;;;;; +1362A;EGYPTIAN HIEROGLYPH-1362A;Lo;0;L;;;;;N;;;;; +1362B;EGYPTIAN HIEROGLYPH-1362B;Lo;0;L;;;;;N;;;;; +1362C;EGYPTIAN HIEROGLYPH-1362C;Lo;0;L;;;;;N;;;;; +1362D;EGYPTIAN HIEROGLYPH-1362D;Lo;0;L;;;;;N;;;;; +1362E;EGYPTIAN HIEROGLYPH-1362E;Lo;0;L;;;;;N;;;;; +1362F;EGYPTIAN HIEROGLYPH-1362F;Lo;0;L;;;;;N;;;;; +13630;EGYPTIAN HIEROGLYPH-13630;Lo;0;L;;;;;N;;;;; +13631;EGYPTIAN HIEROGLYPH-13631;Lo;0;L;;;;;N;;;;; +13632;EGYPTIAN HIEROGLYPH-13632;Lo;0;L;;;;;N;;;;; +13633;EGYPTIAN HIEROGLYPH-13633;Lo;0;L;;;;;N;;;;; +13634;EGYPTIAN HIEROGLYPH-13634;Lo;0;L;;;;;N;;;;; +13635;EGYPTIAN HIEROGLYPH-13635;Lo;0;L;;;;;N;;;;; +13636;EGYPTIAN HIEROGLYPH-13636;Lo;0;L;;;;;N;;;;; +13637;EGYPTIAN HIEROGLYPH-13637;Lo;0;L;;;;;N;;;;; +13638;EGYPTIAN HIEROGLYPH-13638;Lo;0;L;;;;;N;;;;; +13639;EGYPTIAN HIEROGLYPH-13639;Lo;0;L;;;;;N;;;;; +1363A;EGYPTIAN HIEROGLYPH-1363A;Lo;0;L;;;;;N;;;;; +1363B;EGYPTIAN HIEROGLYPH-1363B;Lo;0;L;;;;;N;;;;; +1363C;EGYPTIAN HIEROGLYPH-1363C;Lo;0;L;;;;;N;;;;; +1363D;EGYPTIAN HIEROGLYPH-1363D;Lo;0;L;;;;;N;;;;; +1363E;EGYPTIAN HIEROGLYPH-1363E;Lo;0;L;;;;;N;;;;; +1363F;EGYPTIAN HIEROGLYPH-1363F;Lo;0;L;;;;;N;;;;; +13640;EGYPTIAN HIEROGLYPH-13640;Lo;0;L;;;;;N;;;;; +13641;EGYPTIAN HIEROGLYPH-13641;Lo;0;L;;;;;N;;;;; +13642;EGYPTIAN HIEROGLYPH-13642;Lo;0;L;;;;;N;;;;; +13643;EGYPTIAN HIEROGLYPH-13643;Lo;0;L;;;;;N;;;;; +13644;EGYPTIAN HIEROGLYPH-13644;Lo;0;L;;;;;N;;;;; +13645;EGYPTIAN HIEROGLYPH-13645;Lo;0;L;;;;;N;;;;; +13646;EGYPTIAN HIEROGLYPH-13646;Lo;0;L;;;;;N;;;;; +13647;EGYPTIAN HIEROGLYPH-13647;Lo;0;L;;;;;N;;;;; +13648;EGYPTIAN HIEROGLYPH-13648;Lo;0;L;;;;;N;;;;; +13649;EGYPTIAN HIEROGLYPH-13649;Lo;0;L;;;;;N;;;;; +1364A;EGYPTIAN HIEROGLYPH-1364A;Lo;0;L;;;;;N;;;;; +1364B;EGYPTIAN HIEROGLYPH-1364B;Lo;0;L;;;;;N;;;;; +1364C;EGYPTIAN HIEROGLYPH-1364C;Lo;0;L;;;;;N;;;;; +1364D;EGYPTIAN HIEROGLYPH-1364D;Lo;0;L;;;;;N;;;;; +1364E;EGYPTIAN HIEROGLYPH-1364E;Lo;0;L;;;;;N;;;;; +1364F;EGYPTIAN HIEROGLYPH-1364F;Lo;0;L;;;;;N;;;;; +13650;EGYPTIAN HIEROGLYPH-13650;Lo;0;L;;;;;N;;;;; +13651;EGYPTIAN HIEROGLYPH-13651;Lo;0;L;;;;;N;;;;; +13652;EGYPTIAN HIEROGLYPH-13652;Lo;0;L;;;;;N;;;;; +13653;EGYPTIAN HIEROGLYPH-13653;Lo;0;L;;;;;N;;;;; +13654;EGYPTIAN HIEROGLYPH-13654;Lo;0;L;;;;;N;;;;; +13655;EGYPTIAN HIEROGLYPH-13655;Lo;0;L;;;;;N;;;;; +13656;EGYPTIAN HIEROGLYPH-13656;Lo;0;L;;;;;N;;;;; +13657;EGYPTIAN HIEROGLYPH-13657;Lo;0;L;;;;;N;;;;; +13658;EGYPTIAN HIEROGLYPH-13658;Lo;0;L;;;;;N;;;;; +13659;EGYPTIAN HIEROGLYPH-13659;Lo;0;L;;;;;N;;;;; +1365A;EGYPTIAN HIEROGLYPH-1365A;Lo;0;L;;;;;N;;;;; +1365B;EGYPTIAN HIEROGLYPH-1365B;Lo;0;L;;;;;N;;;;; +1365C;EGYPTIAN HIEROGLYPH-1365C;Lo;0;L;;;;;N;;;;; +1365D;EGYPTIAN HIEROGLYPH-1365D;Lo;0;L;;;;;N;;;;; +1365E;EGYPTIAN HIEROGLYPH-1365E;Lo;0;L;;;;;N;;;;; +1365F;EGYPTIAN HIEROGLYPH-1365F;Lo;0;L;;;;;N;;;;; +13660;EGYPTIAN HIEROGLYPH-13660;Lo;0;L;;;;;N;;;;; +13661;EGYPTIAN HIEROGLYPH-13661;Lo;0;L;;;;;N;;;;; +13662;EGYPTIAN HIEROGLYPH-13662;Lo;0;L;;;;;N;;;;; +13663;EGYPTIAN HIEROGLYPH-13663;Lo;0;L;;;;;N;;;;; +13664;EGYPTIAN HIEROGLYPH-13664;Lo;0;L;;;;;N;;;;; +13665;EGYPTIAN HIEROGLYPH-13665;Lo;0;L;;;;;N;;;;; +13666;EGYPTIAN HIEROGLYPH-13666;Lo;0;L;;;;;N;;;;; +13667;EGYPTIAN HIEROGLYPH-13667;Lo;0;L;;;;;N;;;;; +13668;EGYPTIAN HIEROGLYPH-13668;Lo;0;L;;;;;N;;;;; +13669;EGYPTIAN HIEROGLYPH-13669;Lo;0;L;;;;;N;;;;; +1366A;EGYPTIAN HIEROGLYPH-1366A;Lo;0;L;;;;;N;;;;; +1366B;EGYPTIAN HIEROGLYPH-1366B;Lo;0;L;;;;;N;;;;; +1366C;EGYPTIAN HIEROGLYPH-1366C;Lo;0;L;;;;;N;;;;; +1366D;EGYPTIAN HIEROGLYPH-1366D;Lo;0;L;;;;;N;;;;; +1366E;EGYPTIAN HIEROGLYPH-1366E;Lo;0;L;;;;;N;;;;; +1366F;EGYPTIAN HIEROGLYPH-1366F;Lo;0;L;;;;;N;;;;; +13670;EGYPTIAN HIEROGLYPH-13670;Lo;0;L;;;;;N;;;;; +13671;EGYPTIAN HIEROGLYPH-13671;Lo;0;L;;;;;N;;;;; +13672;EGYPTIAN HIEROGLYPH-13672;Lo;0;L;;;;;N;;;;; +13673;EGYPTIAN HIEROGLYPH-13673;Lo;0;L;;;;;N;;;;; +13674;EGYPTIAN HIEROGLYPH-13674;Lo;0;L;;;;;N;;;;; +13675;EGYPTIAN HIEROGLYPH-13675;Lo;0;L;;;;;N;;;;; +13676;EGYPTIAN HIEROGLYPH-13676;Lo;0;L;;;;;N;;;;; +13677;EGYPTIAN HIEROGLYPH-13677;Lo;0;L;;;;;N;;;;; +13678;EGYPTIAN HIEROGLYPH-13678;Lo;0;L;;;;;N;;;;; +13679;EGYPTIAN HIEROGLYPH-13679;Lo;0;L;;;;;N;;;;; +1367A;EGYPTIAN HIEROGLYPH-1367A;Lo;0;L;;;;;N;;;;; +1367B;EGYPTIAN HIEROGLYPH-1367B;Lo;0;L;;;;;N;;;;; +1367C;EGYPTIAN HIEROGLYPH-1367C;Lo;0;L;;;;;N;;;;; +1367D;EGYPTIAN HIEROGLYPH-1367D;Lo;0;L;;;;;N;;;;; +1367E;EGYPTIAN HIEROGLYPH-1367E;Lo;0;L;;;;;N;;;;; +1367F;EGYPTIAN HIEROGLYPH-1367F;Lo;0;L;;;;;N;;;;; +13680;EGYPTIAN HIEROGLYPH-13680;Lo;0;L;;;;;N;;;;; +13681;EGYPTIAN HIEROGLYPH-13681;Lo;0;L;;;;;N;;;;; +13682;EGYPTIAN HIEROGLYPH-13682;Lo;0;L;;;;;N;;;;; +13683;EGYPTIAN HIEROGLYPH-13683;Lo;0;L;;;;;N;;;;; +13684;EGYPTIAN HIEROGLYPH-13684;Lo;0;L;;;;;N;;;;; +13685;EGYPTIAN HIEROGLYPH-13685;Lo;0;L;;;;;N;;;;; +13686;EGYPTIAN HIEROGLYPH-13686;Lo;0;L;;;;;N;;;;; +13687;EGYPTIAN HIEROGLYPH-13687;Lo;0;L;;;;;N;;;;; +13688;EGYPTIAN HIEROGLYPH-13688;Lo;0;L;;;;;N;;;;; +13689;EGYPTIAN HIEROGLYPH-13689;Lo;0;L;;;;;N;;;;; +1368A;EGYPTIAN HIEROGLYPH-1368A;Lo;0;L;;;;;N;;;;; +1368B;EGYPTIAN HIEROGLYPH-1368B;Lo;0;L;;;;;N;;;;; +1368C;EGYPTIAN HIEROGLYPH-1368C;Lo;0;L;;;;;N;;;;; +1368D;EGYPTIAN HIEROGLYPH-1368D;Lo;0;L;;;;;N;;;;; +1368E;EGYPTIAN HIEROGLYPH-1368E;Lo;0;L;;;;;N;;;;; +1368F;EGYPTIAN HIEROGLYPH-1368F;Lo;0;L;;;;;N;;;;; +13690;EGYPTIAN HIEROGLYPH-13690;Lo;0;L;;;;;N;;;;; +13691;EGYPTIAN HIEROGLYPH-13691;Lo;0;L;;;;;N;;;;; +13692;EGYPTIAN HIEROGLYPH-13692;Lo;0;L;;;;;N;;;;; +13693;EGYPTIAN HIEROGLYPH-13693;Lo;0;L;;;;;N;;;;; +13694;EGYPTIAN HIEROGLYPH-13694;Lo;0;L;;;;;N;;;;; +13695;EGYPTIAN HIEROGLYPH-13695;Lo;0;L;;;;;N;;;;; +13696;EGYPTIAN HIEROGLYPH-13696;Lo;0;L;;;;;N;;;;; +13697;EGYPTIAN HIEROGLYPH-13697;Lo;0;L;;;;;N;;;;; +13698;EGYPTIAN HIEROGLYPH-13698;Lo;0;L;;;;;N;;;;; +13699;EGYPTIAN HIEROGLYPH-13699;Lo;0;L;;;;;N;;;;; +1369A;EGYPTIAN HIEROGLYPH-1369A;Lo;0;L;;;;;N;;;;; +1369B;EGYPTIAN HIEROGLYPH-1369B;Lo;0;L;;;;;N;;;;; +1369C;EGYPTIAN HIEROGLYPH-1369C;Lo;0;L;;;;;N;;;;; +1369D;EGYPTIAN HIEROGLYPH-1369D;Lo;0;L;;;;;N;;;;; +1369E;EGYPTIAN HIEROGLYPH-1369E;Lo;0;L;;;;;N;;;;; +1369F;EGYPTIAN HIEROGLYPH-1369F;Lo;0;L;;;;;N;;;;; +136A0;EGYPTIAN HIEROGLYPH-136A0;Lo;0;L;;;;;N;;;;; +136A1;EGYPTIAN HIEROGLYPH-136A1;Lo;0;L;;;;;N;;;;; +136A2;EGYPTIAN HIEROGLYPH-136A2;Lo;0;L;;;;;N;;;;; +136A3;EGYPTIAN HIEROGLYPH-136A3;Lo;0;L;;;;;N;;;;; +136A4;EGYPTIAN HIEROGLYPH-136A4;Lo;0;L;;;;;N;;;;; +136A5;EGYPTIAN HIEROGLYPH-136A5;Lo;0;L;;;;;N;;;;; +136A6;EGYPTIAN HIEROGLYPH-136A6;Lo;0;L;;;;;N;;;;; +136A7;EGYPTIAN HIEROGLYPH-136A7;Lo;0;L;;;;;N;;;;; +136A8;EGYPTIAN HIEROGLYPH-136A8;Lo;0;L;;;;;N;;;;; +136A9;EGYPTIAN HIEROGLYPH-136A9;Lo;0;L;;;;;N;;;;; +136AA;EGYPTIAN HIEROGLYPH-136AA;Lo;0;L;;;;;N;;;;; +136AB;EGYPTIAN HIEROGLYPH-136AB;Lo;0;L;;;;;N;;;;; +136AC;EGYPTIAN HIEROGLYPH-136AC;Lo;0;L;;;;;N;;;;; +136AD;EGYPTIAN HIEROGLYPH-136AD;Lo;0;L;;;;;N;;;;; +136AE;EGYPTIAN HIEROGLYPH-136AE;Lo;0;L;;;;;N;;;;; +136AF;EGYPTIAN HIEROGLYPH-136AF;Lo;0;L;;;;;N;;;;; +136B0;EGYPTIAN HIEROGLYPH-136B0;Lo;0;L;;;;;N;;;;; +136B1;EGYPTIAN HIEROGLYPH-136B1;Lo;0;L;;;;;N;;;;; +136B2;EGYPTIAN HIEROGLYPH-136B2;Lo;0;L;;;;;N;;;;; +136B3;EGYPTIAN HIEROGLYPH-136B3;Lo;0;L;;;;;N;;;;; +136B4;EGYPTIAN HIEROGLYPH-136B4;Lo;0;L;;;;;N;;;;; +136B5;EGYPTIAN HIEROGLYPH-136B5;Lo;0;L;;;;;N;;;;; +136B6;EGYPTIAN HIEROGLYPH-136B6;Lo;0;L;;;;;N;;;;; +136B7;EGYPTIAN HIEROGLYPH-136B7;Lo;0;L;;;;;N;;;;; +136B8;EGYPTIAN HIEROGLYPH-136B8;Lo;0;L;;;;;N;;;;; +136B9;EGYPTIAN HIEROGLYPH-136B9;Lo;0;L;;;;;N;;;;; +136BA;EGYPTIAN HIEROGLYPH-136BA;Lo;0;L;;;;;N;;;;; +136BB;EGYPTIAN HIEROGLYPH-136BB;Lo;0;L;;;;;N;;;;; +136BC;EGYPTIAN HIEROGLYPH-136BC;Lo;0;L;;;;;N;;;;; +136BD;EGYPTIAN HIEROGLYPH-136BD;Lo;0;L;;;;;N;;;;; +136BE;EGYPTIAN HIEROGLYPH-136BE;Lo;0;L;;;;;N;;;;; +136BF;EGYPTIAN HIEROGLYPH-136BF;Lo;0;L;;;;;N;;;;; +136C0;EGYPTIAN HIEROGLYPH-136C0;Lo;0;L;;;;;N;;;;; +136C1;EGYPTIAN HIEROGLYPH-136C1;Lo;0;L;;;;;N;;;;; +136C2;EGYPTIAN HIEROGLYPH-136C2;Lo;0;L;;;;;N;;;;; +136C3;EGYPTIAN HIEROGLYPH-136C3;Lo;0;L;;;;;N;;;;; +136C4;EGYPTIAN HIEROGLYPH-136C4;Lo;0;L;;;;;N;;;;; +136C5;EGYPTIAN HIEROGLYPH-136C5;Lo;0;L;;;;;N;;;;; +136C6;EGYPTIAN HIEROGLYPH-136C6;Lo;0;L;;;;;N;;;;; +136C7;EGYPTIAN HIEROGLYPH-136C7;Lo;0;L;;;;;N;;;;; +136C8;EGYPTIAN HIEROGLYPH-136C8;Lo;0;L;;;;;N;;;;; +136C9;EGYPTIAN HIEROGLYPH-136C9;Lo;0;L;;;;;N;;;;; +136CA;EGYPTIAN HIEROGLYPH-136CA;Lo;0;L;;;;;N;;;;; +136CB;EGYPTIAN HIEROGLYPH-136CB;Lo;0;L;;;;;N;;;;; +136CC;EGYPTIAN HIEROGLYPH-136CC;Lo;0;L;;;;;N;;;;; +136CD;EGYPTIAN HIEROGLYPH-136CD;Lo;0;L;;;;;N;;;;; +136CE;EGYPTIAN HIEROGLYPH-136CE;Lo;0;L;;;;;N;;;;; +136CF;EGYPTIAN HIEROGLYPH-136CF;Lo;0;L;;;;;N;;;;; +136D0;EGYPTIAN HIEROGLYPH-136D0;Lo;0;L;;;;;N;;;;; +136D1;EGYPTIAN HIEROGLYPH-136D1;Lo;0;L;;;;;N;;;;; +136D2;EGYPTIAN HIEROGLYPH-136D2;Lo;0;L;;;;;N;;;;; +136D3;EGYPTIAN HIEROGLYPH-136D3;Lo;0;L;;;;;N;;;;; +136D4;EGYPTIAN HIEROGLYPH-136D4;Lo;0;L;;;;;N;;;;; +136D5;EGYPTIAN HIEROGLYPH-136D5;Lo;0;L;;;;;N;;;;; +136D6;EGYPTIAN HIEROGLYPH-136D6;Lo;0;L;;;;;N;;;;; +136D7;EGYPTIAN HIEROGLYPH-136D7;Lo;0;L;;;;;N;;;;; +136D8;EGYPTIAN HIEROGLYPH-136D8;Lo;0;L;;;;;N;;;;; +136D9;EGYPTIAN HIEROGLYPH-136D9;Lo;0;L;;;;;N;;;;; +136DA;EGYPTIAN HIEROGLYPH-136DA;Lo;0;L;;;;;N;;;;; +136DB;EGYPTIAN HIEROGLYPH-136DB;Lo;0;L;;;;;N;;;;; +136DC;EGYPTIAN HIEROGLYPH-136DC;Lo;0;L;;;;;N;;;;; +136DD;EGYPTIAN HIEROGLYPH-136DD;Lo;0;L;;;;;N;;;;; +136DE;EGYPTIAN HIEROGLYPH-136DE;Lo;0;L;;;;;N;;;;; +136DF;EGYPTIAN HIEROGLYPH-136DF;Lo;0;L;;;;;N;;;;; +136E0;EGYPTIAN HIEROGLYPH-136E0;Lo;0;L;;;;;N;;;;; +136E1;EGYPTIAN HIEROGLYPH-136E1;Lo;0;L;;;;;N;;;;; +136E2;EGYPTIAN HIEROGLYPH-136E2;Lo;0;L;;;;;N;;;;; +136E3;EGYPTIAN HIEROGLYPH-136E3;Lo;0;L;;;;;N;;;;; +136E4;EGYPTIAN HIEROGLYPH-136E4;Lo;0;L;;;;;N;;;;; +136E5;EGYPTIAN HIEROGLYPH-136E5;Lo;0;L;;;;;N;;;;; +136E6;EGYPTIAN HIEROGLYPH-136E6;Lo;0;L;;;;;N;;;;; +136E7;EGYPTIAN HIEROGLYPH-136E7;Lo;0;L;;;;;N;;;;; +136E8;EGYPTIAN HIEROGLYPH-136E8;Lo;0;L;;;;;N;;;;; +136E9;EGYPTIAN HIEROGLYPH-136E9;Lo;0;L;;;;;N;;;;; +136EA;EGYPTIAN HIEROGLYPH-136EA;Lo;0;L;;;;;N;;;;; +136EB;EGYPTIAN HIEROGLYPH-136EB;Lo;0;L;;;;;N;;;;; +136EC;EGYPTIAN HIEROGLYPH-136EC;Lo;0;L;;;;;N;;;;; +136ED;EGYPTIAN HIEROGLYPH-136ED;Lo;0;L;;;;;N;;;;; +136EE;EGYPTIAN HIEROGLYPH-136EE;Lo;0;L;;;;;N;;;;; +136EF;EGYPTIAN HIEROGLYPH-136EF;Lo;0;L;;;;;N;;;;; +136F0;EGYPTIAN HIEROGLYPH-136F0;Lo;0;L;;;;;N;;;;; +136F1;EGYPTIAN HIEROGLYPH-136F1;Lo;0;L;;;;;N;;;;; +136F2;EGYPTIAN HIEROGLYPH-136F2;Lo;0;L;;;;;N;;;;; +136F3;EGYPTIAN HIEROGLYPH-136F3;Lo;0;L;;;;;N;;;;; +136F4;EGYPTIAN HIEROGLYPH-136F4;Lo;0;L;;;;;N;;;;; +136F5;EGYPTIAN HIEROGLYPH-136F5;Lo;0;L;;;;;N;;;;; +136F6;EGYPTIAN HIEROGLYPH-136F6;Lo;0;L;;;;;N;;;;; +136F7;EGYPTIAN HIEROGLYPH-136F7;Lo;0;L;;;;;N;;;;; +136F8;EGYPTIAN HIEROGLYPH-136F8;Lo;0;L;;;;;N;;;;; +136F9;EGYPTIAN HIEROGLYPH-136F9;Lo;0;L;;;;;N;;;;; +136FA;EGYPTIAN HIEROGLYPH-136FA;Lo;0;L;;;;;N;;;;; +136FB;EGYPTIAN HIEROGLYPH-136FB;Lo;0;L;;;;;N;;;;; +136FC;EGYPTIAN HIEROGLYPH-136FC;Lo;0;L;;;;;N;;;;; +136FD;EGYPTIAN HIEROGLYPH-136FD;Lo;0;L;;;;;N;;;;; +136FE;EGYPTIAN HIEROGLYPH-136FE;Lo;0;L;;;;;N;;;;; +136FF;EGYPTIAN HIEROGLYPH-136FF;Lo;0;L;;;;;N;;;;; +13700;EGYPTIAN HIEROGLYPH-13700;Lo;0;L;;;;;N;;;;; +13701;EGYPTIAN HIEROGLYPH-13701;Lo;0;L;;;;;N;;;;; +13702;EGYPTIAN HIEROGLYPH-13702;Lo;0;L;;;;;N;;;;; +13703;EGYPTIAN HIEROGLYPH-13703;Lo;0;L;;;;;N;;;;; +13704;EGYPTIAN HIEROGLYPH-13704;Lo;0;L;;;;;N;;;;; +13705;EGYPTIAN HIEROGLYPH-13705;Lo;0;L;;;;;N;;;;; +13706;EGYPTIAN HIEROGLYPH-13706;Lo;0;L;;;;;N;;;;; +13707;EGYPTIAN HIEROGLYPH-13707;Lo;0;L;;;;;N;;;;; +13708;EGYPTIAN HIEROGLYPH-13708;Lo;0;L;;;;;N;;;;; +13709;EGYPTIAN HIEROGLYPH-13709;Lo;0;L;;;;;N;;;;; +1370A;EGYPTIAN HIEROGLYPH-1370A;Lo;0;L;;;;;N;;;;; +1370B;EGYPTIAN HIEROGLYPH-1370B;Lo;0;L;;;;;N;;;;; +1370C;EGYPTIAN HIEROGLYPH-1370C;Lo;0;L;;;;;N;;;;; +1370D;EGYPTIAN HIEROGLYPH-1370D;Lo;0;L;;;;;N;;;;; +1370E;EGYPTIAN HIEROGLYPH-1370E;Lo;0;L;;;;;N;;;;; +1370F;EGYPTIAN HIEROGLYPH-1370F;Lo;0;L;;;;;N;;;;; +13710;EGYPTIAN HIEROGLYPH-13710;Lo;0;L;;;;;N;;;;; +13711;EGYPTIAN HIEROGLYPH-13711;Lo;0;L;;;;;N;;;;; +13712;EGYPTIAN HIEROGLYPH-13712;Lo;0;L;;;;;N;;;;; +13713;EGYPTIAN HIEROGLYPH-13713;Lo;0;L;;;;;N;;;;; +13714;EGYPTIAN HIEROGLYPH-13714;Lo;0;L;;;;;N;;;;; +13715;EGYPTIAN HIEROGLYPH-13715;Lo;0;L;;;;;N;;;;; +13716;EGYPTIAN HIEROGLYPH-13716;Lo;0;L;;;;;N;;;;; +13717;EGYPTIAN HIEROGLYPH-13717;Lo;0;L;;;;;N;;;;; +13718;EGYPTIAN HIEROGLYPH-13718;Lo;0;L;;;;;N;;;;; +13719;EGYPTIAN HIEROGLYPH-13719;Lo;0;L;;;;;N;;;;; +1371A;EGYPTIAN HIEROGLYPH-1371A;Lo;0;L;;;;;N;;;;; +1371B;EGYPTIAN HIEROGLYPH-1371B;Lo;0;L;;;;;N;;;;; +1371C;EGYPTIAN HIEROGLYPH-1371C;Lo;0;L;;;;;N;;;;; +1371D;EGYPTIAN HIEROGLYPH-1371D;Lo;0;L;;;;;N;;;;; +1371E;EGYPTIAN HIEROGLYPH-1371E;Lo;0;L;;;;;N;;;;; +1371F;EGYPTIAN HIEROGLYPH-1371F;Lo;0;L;;;;;N;;;;; +13720;EGYPTIAN HIEROGLYPH-13720;Lo;0;L;;;;;N;;;;; +13721;EGYPTIAN HIEROGLYPH-13721;Lo;0;L;;;;;N;;;;; +13722;EGYPTIAN HIEROGLYPH-13722;Lo;0;L;;;;;N;;;;; +13723;EGYPTIAN HIEROGLYPH-13723;Lo;0;L;;;;;N;;;;; +13724;EGYPTIAN HIEROGLYPH-13724;Lo;0;L;;;;;N;;;;; +13725;EGYPTIAN HIEROGLYPH-13725;Lo;0;L;;;;;N;;;;; +13726;EGYPTIAN HIEROGLYPH-13726;Lo;0;L;;;;;N;;;;; +13727;EGYPTIAN HIEROGLYPH-13727;Lo;0;L;;;;;N;;;;; +13728;EGYPTIAN HIEROGLYPH-13728;Lo;0;L;;;;;N;;;;; +13729;EGYPTIAN HIEROGLYPH-13729;Lo;0;L;;;;;N;;;;; +1372A;EGYPTIAN HIEROGLYPH-1372A;Lo;0;L;;;;;N;;;;; +1372B;EGYPTIAN HIEROGLYPH-1372B;Lo;0;L;;;;;N;;;;; +1372C;EGYPTIAN HIEROGLYPH-1372C;Lo;0;L;;;;;N;;;;; +1372D;EGYPTIAN HIEROGLYPH-1372D;Lo;0;L;;;;;N;;;;; +1372E;EGYPTIAN HIEROGLYPH-1372E;Lo;0;L;;;;;N;;;;; +1372F;EGYPTIAN HIEROGLYPH-1372F;Lo;0;L;;;;;N;;;;; +13730;EGYPTIAN HIEROGLYPH-13730;Lo;0;L;;;;;N;;;;; +13731;EGYPTIAN HIEROGLYPH-13731;Lo;0;L;;;;;N;;;;; +13732;EGYPTIAN HIEROGLYPH-13732;Lo;0;L;;;;;N;;;;; +13733;EGYPTIAN HIEROGLYPH-13733;Lo;0;L;;;;;N;;;;; +13734;EGYPTIAN HIEROGLYPH-13734;Lo;0;L;;;;;N;;;;; +13735;EGYPTIAN HIEROGLYPH-13735;Lo;0;L;;;;;N;;;;; +13736;EGYPTIAN HIEROGLYPH-13736;Lo;0;L;;;;;N;;;;; +13737;EGYPTIAN HIEROGLYPH-13737;Lo;0;L;;;;;N;;;;; +13738;EGYPTIAN HIEROGLYPH-13738;Lo;0;L;;;;;N;;;;; +13739;EGYPTIAN HIEROGLYPH-13739;Lo;0;L;;;;;N;;;;; +1373A;EGYPTIAN HIEROGLYPH-1373A;Lo;0;L;;;;;N;;;;; +1373B;EGYPTIAN HIEROGLYPH-1373B;Lo;0;L;;;;;N;;;;; +1373C;EGYPTIAN HIEROGLYPH-1373C;Lo;0;L;;;;;N;;;;; +1373D;EGYPTIAN HIEROGLYPH-1373D;Lo;0;L;;;;;N;;;;; +1373E;EGYPTIAN HIEROGLYPH-1373E;Lo;0;L;;;;;N;;;;; +1373F;EGYPTIAN HIEROGLYPH-1373F;Lo;0;L;;;;;N;;;;; +13740;EGYPTIAN HIEROGLYPH-13740;Lo;0;L;;;;;N;;;;; +13741;EGYPTIAN HIEROGLYPH-13741;Lo;0;L;;;;;N;;;;; +13742;EGYPTIAN HIEROGLYPH-13742;Lo;0;L;;;;;N;;;;; +13743;EGYPTIAN HIEROGLYPH-13743;Lo;0;L;;;;;N;;;;; +13744;EGYPTIAN HIEROGLYPH-13744;Lo;0;L;;;;;N;;;;; +13745;EGYPTIAN HIEROGLYPH-13745;Lo;0;L;;;;;N;;;;; +13746;EGYPTIAN HIEROGLYPH-13746;Lo;0;L;;;;;N;;;;; +13747;EGYPTIAN HIEROGLYPH-13747;Lo;0;L;;;;;N;;;;; +13748;EGYPTIAN HIEROGLYPH-13748;Lo;0;L;;;;;N;;;;; +13749;EGYPTIAN HIEROGLYPH-13749;Lo;0;L;;;;;N;;;;; +1374A;EGYPTIAN HIEROGLYPH-1374A;Lo;0;L;;;;;N;;;;; +1374B;EGYPTIAN HIEROGLYPH-1374B;Lo;0;L;;;;;N;;;;; +1374C;EGYPTIAN HIEROGLYPH-1374C;Lo;0;L;;;;;N;;;;; +1374D;EGYPTIAN HIEROGLYPH-1374D;Lo;0;L;;;;;N;;;;; +1374E;EGYPTIAN HIEROGLYPH-1374E;Lo;0;L;;;;;N;;;;; +1374F;EGYPTIAN HIEROGLYPH-1374F;Lo;0;L;;;;;N;;;;; +13750;EGYPTIAN HIEROGLYPH-13750;Lo;0;L;;;;;N;;;;; +13751;EGYPTIAN HIEROGLYPH-13751;Lo;0;L;;;;;N;;;;; +13752;EGYPTIAN HIEROGLYPH-13752;Lo;0;L;;;;;N;;;;; +13753;EGYPTIAN HIEROGLYPH-13753;Lo;0;L;;;;;N;;;;; +13754;EGYPTIAN HIEROGLYPH-13754;Lo;0;L;;;;;N;;;;; +13755;EGYPTIAN HIEROGLYPH-13755;Lo;0;L;;;;;N;;;;; +13756;EGYPTIAN HIEROGLYPH-13756;Lo;0;L;;;;;N;;;;; +13757;EGYPTIAN HIEROGLYPH-13757;Lo;0;L;;;;;N;;;;; +13758;EGYPTIAN HIEROGLYPH-13758;Lo;0;L;;;;;N;;;;; +13759;EGYPTIAN HIEROGLYPH-13759;Lo;0;L;;;;;N;;;;; +1375A;EGYPTIAN HIEROGLYPH-1375A;Lo;0;L;;;;;N;;;;; +1375B;EGYPTIAN HIEROGLYPH-1375B;Lo;0;L;;;;;N;;;;; +1375C;EGYPTIAN HIEROGLYPH-1375C;Lo;0;L;;;;;N;;;;; +1375D;EGYPTIAN HIEROGLYPH-1375D;Lo;0;L;;;;;N;;;;; +1375E;EGYPTIAN HIEROGLYPH-1375E;Lo;0;L;;;;;N;;;;; +1375F;EGYPTIAN HIEROGLYPH-1375F;Lo;0;L;;;;;N;;;;; +13760;EGYPTIAN HIEROGLYPH-13760;Lo;0;L;;;;;N;;;;; +13761;EGYPTIAN HIEROGLYPH-13761;Lo;0;L;;;;;N;;;;; +13762;EGYPTIAN HIEROGLYPH-13762;Lo;0;L;;;;;N;;;;; +13763;EGYPTIAN HIEROGLYPH-13763;Lo;0;L;;;;;N;;;;; +13764;EGYPTIAN HIEROGLYPH-13764;Lo;0;L;;;;;N;;;;; +13765;EGYPTIAN HIEROGLYPH-13765;Lo;0;L;;;;;N;;;;; +13766;EGYPTIAN HIEROGLYPH-13766;Lo;0;L;;;;;N;;;;; +13767;EGYPTIAN HIEROGLYPH-13767;Lo;0;L;;;;;N;;;;; +13768;EGYPTIAN HIEROGLYPH-13768;Lo;0;L;;;;;N;;;;; +13769;EGYPTIAN HIEROGLYPH-13769;Lo;0;L;;;;;N;;;;; +1376A;EGYPTIAN HIEROGLYPH-1376A;Lo;0;L;;;;;N;;;;; +1376B;EGYPTIAN HIEROGLYPH-1376B;Lo;0;L;;;;;N;;;;; +1376C;EGYPTIAN HIEROGLYPH-1376C;Lo;0;L;;;;;N;;;;; +1376D;EGYPTIAN HIEROGLYPH-1376D;Lo;0;L;;;;;N;;;;; +1376E;EGYPTIAN HIEROGLYPH-1376E;Lo;0;L;;;;;N;;;;; +1376F;EGYPTIAN HIEROGLYPH-1376F;Lo;0;L;;;;;N;;;;; +13770;EGYPTIAN HIEROGLYPH-13770;Lo;0;L;;;;;N;;;;; +13771;EGYPTIAN HIEROGLYPH-13771;Lo;0;L;;;;;N;;;;; +13772;EGYPTIAN HIEROGLYPH-13772;Lo;0;L;;;;;N;;;;; +13773;EGYPTIAN HIEROGLYPH-13773;Lo;0;L;;;;;N;;;;; +13774;EGYPTIAN HIEROGLYPH-13774;Lo;0;L;;;;;N;;;;; +13775;EGYPTIAN HIEROGLYPH-13775;Lo;0;L;;;;;N;;;;; +13776;EGYPTIAN HIEROGLYPH-13776;Lo;0;L;;;;;N;;;;; +13777;EGYPTIAN HIEROGLYPH-13777;Lo;0;L;;;;;N;;;;; +13778;EGYPTIAN HIEROGLYPH-13778;Lo;0;L;;;;;N;;;;; +13779;EGYPTIAN HIEROGLYPH-13779;Lo;0;L;;;;;N;;;;; +1377A;EGYPTIAN HIEROGLYPH-1377A;Lo;0;L;;;;;N;;;;; +1377B;EGYPTIAN HIEROGLYPH-1377B;Lo;0;L;;;;;N;;;;; +1377C;EGYPTIAN HIEROGLYPH-1377C;Lo;0;L;;;;;N;;;;; +1377D;EGYPTIAN HIEROGLYPH-1377D;Lo;0;L;;;;;N;;;;; +1377E;EGYPTIAN HIEROGLYPH-1377E;Lo;0;L;;;;;N;;;;; +1377F;EGYPTIAN HIEROGLYPH-1377F;Lo;0;L;;;;;N;;;;; +13780;EGYPTIAN HIEROGLYPH-13780;Lo;0;L;;;;;N;;;;; +13781;EGYPTIAN HIEROGLYPH-13781;Lo;0;L;;;;;N;;;;; +13782;EGYPTIAN HIEROGLYPH-13782;Lo;0;L;;;;;N;;;;; +13783;EGYPTIAN HIEROGLYPH-13783;Lo;0;L;;;;;N;;;;; +13784;EGYPTIAN HIEROGLYPH-13784;Lo;0;L;;;;;N;;;;; +13785;EGYPTIAN HIEROGLYPH-13785;Lo;0;L;;;;;N;;;;; +13786;EGYPTIAN HIEROGLYPH-13786;Lo;0;L;;;;;N;;;;; +13787;EGYPTIAN HIEROGLYPH-13787;Lo;0;L;;;;;N;;;;; +13788;EGYPTIAN HIEROGLYPH-13788;Lo;0;L;;;;;N;;;;; +13789;EGYPTIAN HIEROGLYPH-13789;Lo;0;L;;;;;N;;;;; +1378A;EGYPTIAN HIEROGLYPH-1378A;Lo;0;L;;;;;N;;;;; +1378B;EGYPTIAN HIEROGLYPH-1378B;Lo;0;L;;;;;N;;;;; +1378C;EGYPTIAN HIEROGLYPH-1378C;Lo;0;L;;;;;N;;;;; +1378D;EGYPTIAN HIEROGLYPH-1378D;Lo;0;L;;;;;N;;;;; +1378E;EGYPTIAN HIEROGLYPH-1378E;Lo;0;L;;;;;N;;;;; +1378F;EGYPTIAN HIEROGLYPH-1378F;Lo;0;L;;;;;N;;;;; +13790;EGYPTIAN HIEROGLYPH-13790;Lo;0;L;;;;;N;;;;; +13791;EGYPTIAN HIEROGLYPH-13791;Lo;0;L;;;;;N;;;;; +13792;EGYPTIAN HIEROGLYPH-13792;Lo;0;L;;;;;N;;;;; +13793;EGYPTIAN HIEROGLYPH-13793;Lo;0;L;;;;;N;;;;; +13794;EGYPTIAN HIEROGLYPH-13794;Lo;0;L;;;;;N;;;;; +13795;EGYPTIAN HIEROGLYPH-13795;Lo;0;L;;;;;N;;;;; +13796;EGYPTIAN HIEROGLYPH-13796;Lo;0;L;;;;;N;;;;; +13797;EGYPTIAN HIEROGLYPH-13797;Lo;0;L;;;;;N;;;;; +13798;EGYPTIAN HIEROGLYPH-13798;Lo;0;L;;;;;N;;;;; +13799;EGYPTIAN HIEROGLYPH-13799;Lo;0;L;;;;;N;;;;; +1379A;EGYPTIAN HIEROGLYPH-1379A;Lo;0;L;;;;;N;;;;; +1379B;EGYPTIAN HIEROGLYPH-1379B;Lo;0;L;;;;;N;;;;; +1379C;EGYPTIAN HIEROGLYPH-1379C;Lo;0;L;;;;;N;;;;; +1379D;EGYPTIAN HIEROGLYPH-1379D;Lo;0;L;;;;;N;;;;; +1379E;EGYPTIAN HIEROGLYPH-1379E;Lo;0;L;;;;;N;;;;; +1379F;EGYPTIAN HIEROGLYPH-1379F;Lo;0;L;;;;;N;;;;; +137A0;EGYPTIAN HIEROGLYPH-137A0;Lo;0;L;;;;;N;;;;; +137A1;EGYPTIAN HIEROGLYPH-137A1;Lo;0;L;;;;;N;;;;; +137A2;EGYPTIAN HIEROGLYPH-137A2;Lo;0;L;;;;;N;;;;; +137A3;EGYPTIAN HIEROGLYPH-137A3;Lo;0;L;;;;;N;;;;; +137A4;EGYPTIAN HIEROGLYPH-137A4;Lo;0;L;;;;;N;;;;; +137A5;EGYPTIAN HIEROGLYPH-137A5;Lo;0;L;;;;;N;;;;; +137A6;EGYPTIAN HIEROGLYPH-137A6;Lo;0;L;;;;;N;;;;; +137A7;EGYPTIAN HIEROGLYPH-137A7;Lo;0;L;;;;;N;;;;; +137A8;EGYPTIAN HIEROGLYPH-137A8;Lo;0;L;;;;;N;;;;; +137A9;EGYPTIAN HIEROGLYPH-137A9;Lo;0;L;;;;;N;;;;; +137AA;EGYPTIAN HIEROGLYPH-137AA;Lo;0;L;;;;;N;;;;; +137AB;EGYPTIAN HIEROGLYPH-137AB;Lo;0;L;;;;;N;;;;; +137AC;EGYPTIAN HIEROGLYPH-137AC;Lo;0;L;;;;;N;;;;; +137AD;EGYPTIAN HIEROGLYPH-137AD;Lo;0;L;;;;;N;;;;; +137AE;EGYPTIAN HIEROGLYPH-137AE;Lo;0;L;;;;;N;;;;; +137AF;EGYPTIAN HIEROGLYPH-137AF;Lo;0;L;;;;;N;;;;; +137B0;EGYPTIAN HIEROGLYPH-137B0;Lo;0;L;;;;;N;;;;; +137B1;EGYPTIAN HIEROGLYPH-137B1;Lo;0;L;;;;;N;;;;; +137B2;EGYPTIAN HIEROGLYPH-137B2;Lo;0;L;;;;;N;;;;; +137B3;EGYPTIAN HIEROGLYPH-137B3;Lo;0;L;;;;;N;;;;; +137B4;EGYPTIAN HIEROGLYPH-137B4;Lo;0;L;;;;;N;;;;; +137B5;EGYPTIAN HIEROGLYPH-137B5;Lo;0;L;;;;;N;;;;; +137B6;EGYPTIAN HIEROGLYPH-137B6;Lo;0;L;;;;;N;;;;; +137B7;EGYPTIAN HIEROGLYPH-137B7;Lo;0;L;;;;;N;;;;; +137B8;EGYPTIAN HIEROGLYPH-137B8;Lo;0;L;;;;;N;;;;; +137B9;EGYPTIAN HIEROGLYPH-137B9;Lo;0;L;;;;;N;;;;; +137BA;EGYPTIAN HIEROGLYPH-137BA;Lo;0;L;;;;;N;;;;; +137BB;EGYPTIAN HIEROGLYPH-137BB;Lo;0;L;;;;;N;;;;; +137BC;EGYPTIAN HIEROGLYPH-137BC;Lo;0;L;;;;;N;;;;; +137BD;EGYPTIAN HIEROGLYPH-137BD;Lo;0;L;;;;;N;;;;; +137BE;EGYPTIAN HIEROGLYPH-137BE;Lo;0;L;;;;;N;;;;; +137BF;EGYPTIAN HIEROGLYPH-137BF;Lo;0;L;;;;;N;;;;; +137C0;EGYPTIAN HIEROGLYPH-137C0;Lo;0;L;;;;;N;;;;; +137C1;EGYPTIAN HIEROGLYPH-137C1;Lo;0;L;;;;;N;;;;; +137C2;EGYPTIAN HIEROGLYPH-137C2;Lo;0;L;;;;;N;;;;; +137C3;EGYPTIAN HIEROGLYPH-137C3;Lo;0;L;;;;;N;;;;; +137C4;EGYPTIAN HIEROGLYPH-137C4;Lo;0;L;;;;;N;;;;; +137C5;EGYPTIAN HIEROGLYPH-137C5;Lo;0;L;;;;;N;;;;; +137C6;EGYPTIAN HIEROGLYPH-137C6;Lo;0;L;;;;;N;;;;; +137C7;EGYPTIAN HIEROGLYPH-137C7;Lo;0;L;;;;;N;;;;; +137C8;EGYPTIAN HIEROGLYPH-137C8;Lo;0;L;;;;;N;;;;; +137C9;EGYPTIAN HIEROGLYPH-137C9;Lo;0;L;;;;;N;;;;; +137CA;EGYPTIAN HIEROGLYPH-137CA;Lo;0;L;;;;;N;;;;; +137CB;EGYPTIAN HIEROGLYPH-137CB;Lo;0;L;;;;;N;;;;; +137CC;EGYPTIAN HIEROGLYPH-137CC;Lo;0;L;;;;;N;;;;; +137CD;EGYPTIAN HIEROGLYPH-137CD;Lo;0;L;;;;;N;;;;; +137CE;EGYPTIAN HIEROGLYPH-137CE;Lo;0;L;;;;;N;;;;; +137CF;EGYPTIAN HIEROGLYPH-137CF;Lo;0;L;;;;;N;;;;; +137D0;EGYPTIAN HIEROGLYPH-137D0;Lo;0;L;;;;;N;;;;; +137D1;EGYPTIAN HIEROGLYPH-137D1;Lo;0;L;;;;;N;;;;; +137D2;EGYPTIAN HIEROGLYPH-137D2;Lo;0;L;;;;;N;;;;; +137D3;EGYPTIAN HIEROGLYPH-137D3;Lo;0;L;;;;;N;;;;; +137D4;EGYPTIAN HIEROGLYPH-137D4;Lo;0;L;;;;;N;;;;; +137D5;EGYPTIAN HIEROGLYPH-137D5;Lo;0;L;;;;;N;;;;; +137D6;EGYPTIAN HIEROGLYPH-137D6;Lo;0;L;;;;;N;;;;; +137D7;EGYPTIAN HIEROGLYPH-137D7;Lo;0;L;;;;;N;;;;; +137D8;EGYPTIAN HIEROGLYPH-137D8;Lo;0;L;;;;;N;;;;; +137D9;EGYPTIAN HIEROGLYPH-137D9;Lo;0;L;;;;;N;;;;; +137DA;EGYPTIAN HIEROGLYPH-137DA;Lo;0;L;;;;;N;;;;; +137DB;EGYPTIAN HIEROGLYPH-137DB;Lo;0;L;;;;;N;;;;; +137DC;EGYPTIAN HIEROGLYPH-137DC;Lo;0;L;;;;;N;;;;; +137DD;EGYPTIAN HIEROGLYPH-137DD;Lo;0;L;;;;;N;;;;; +137DE;EGYPTIAN HIEROGLYPH-137DE;Lo;0;L;;;;;N;;;;; +137DF;EGYPTIAN HIEROGLYPH-137DF;Lo;0;L;;;;;N;;;;; +137E0;EGYPTIAN HIEROGLYPH-137E0;Lo;0;L;;;;;N;;;;; +137E1;EGYPTIAN HIEROGLYPH-137E1;Lo;0;L;;;;;N;;;;; +137E2;EGYPTIAN HIEROGLYPH-137E2;Lo;0;L;;;;;N;;;;; +137E3;EGYPTIAN HIEROGLYPH-137E3;Lo;0;L;;;;;N;;;;; +137E4;EGYPTIAN HIEROGLYPH-137E4;Lo;0;L;;;;;N;;;;; +137E5;EGYPTIAN HIEROGLYPH-137E5;Lo;0;L;;;;;N;;;;; +137E6;EGYPTIAN HIEROGLYPH-137E6;Lo;0;L;;;;;N;;;;; +137E7;EGYPTIAN HIEROGLYPH-137E7;Lo;0;L;;;;;N;;;;; +137E8;EGYPTIAN HIEROGLYPH-137E8;Lo;0;L;;;;;N;;;;; +137E9;EGYPTIAN HIEROGLYPH-137E9;Lo;0;L;;;;;N;;;;; +137EA;EGYPTIAN HIEROGLYPH-137EA;Lo;0;L;;;;;N;;;;; +137EB;EGYPTIAN HIEROGLYPH-137EB;Lo;0;L;;;;;N;;;;; +137EC;EGYPTIAN HIEROGLYPH-137EC;Lo;0;L;;;;;N;;;;; +137ED;EGYPTIAN HIEROGLYPH-137ED;Lo;0;L;;;;;N;;;;; +137EE;EGYPTIAN HIEROGLYPH-137EE;Lo;0;L;;;;;N;;;;; +137EF;EGYPTIAN HIEROGLYPH-137EF;Lo;0;L;;;;;N;;;;; +137F0;EGYPTIAN HIEROGLYPH-137F0;Lo;0;L;;;;;N;;;;; +137F1;EGYPTIAN HIEROGLYPH-137F1;Lo;0;L;;;;;N;;;;; +137F2;EGYPTIAN HIEROGLYPH-137F2;Lo;0;L;;;;;N;;;;; +137F3;EGYPTIAN HIEROGLYPH-137F3;Lo;0;L;;;;;N;;;;; +137F4;EGYPTIAN HIEROGLYPH-137F4;Lo;0;L;;;;;N;;;;; +137F5;EGYPTIAN HIEROGLYPH-137F5;Lo;0;L;;;;;N;;;;; +137F6;EGYPTIAN HIEROGLYPH-137F6;Lo;0;L;;;;;N;;;;; +137F7;EGYPTIAN HIEROGLYPH-137F7;Lo;0;L;;;;;N;;;;; +137F8;EGYPTIAN HIEROGLYPH-137F8;Lo;0;L;;;;;N;;;;; +137F9;EGYPTIAN HIEROGLYPH-137F9;Lo;0;L;;;;;N;;;;; +137FA;EGYPTIAN HIEROGLYPH-137FA;Lo;0;L;;;;;N;;;;; +137FB;EGYPTIAN HIEROGLYPH-137FB;Lo;0;L;;;;;N;;;;; +137FC;EGYPTIAN HIEROGLYPH-137FC;Lo;0;L;;;;;N;;;;; +137FD;EGYPTIAN HIEROGLYPH-137FD;Lo;0;L;;;;;N;;;;; +137FE;EGYPTIAN HIEROGLYPH-137FE;Lo;0;L;;;;;N;;;;; +137FF;EGYPTIAN HIEROGLYPH-137FF;Lo;0;L;;;;;N;;;;; +13800;EGYPTIAN HIEROGLYPH-13800;Lo;0;L;;;;;N;;;;; +13801;EGYPTIAN HIEROGLYPH-13801;Lo;0;L;;;;;N;;;;; +13802;EGYPTIAN HIEROGLYPH-13802;Lo;0;L;;;;;N;;;;; +13803;EGYPTIAN HIEROGLYPH-13803;Lo;0;L;;;;;N;;;;; +13804;EGYPTIAN HIEROGLYPH-13804;Lo;0;L;;;;;N;;;;; +13805;EGYPTIAN HIEROGLYPH-13805;Lo;0;L;;;;;N;;;;; +13806;EGYPTIAN HIEROGLYPH-13806;Lo;0;L;;;;;N;;;;; +13807;EGYPTIAN HIEROGLYPH-13807;Lo;0;L;;;;;N;;;;; +13808;EGYPTIAN HIEROGLYPH-13808;Lo;0;L;;;;;N;;;;; +13809;EGYPTIAN HIEROGLYPH-13809;Lo;0;L;;;;;N;;;;; +1380A;EGYPTIAN HIEROGLYPH-1380A;Lo;0;L;;;;;N;;;;; +1380B;EGYPTIAN HIEROGLYPH-1380B;Lo;0;L;;;;;N;;;;; +1380C;EGYPTIAN HIEROGLYPH-1380C;Lo;0;L;;;;;N;;;;; +1380D;EGYPTIAN HIEROGLYPH-1380D;Lo;0;L;;;;;N;;;;; +1380E;EGYPTIAN HIEROGLYPH-1380E;Lo;0;L;;;;;N;;;;; +1380F;EGYPTIAN HIEROGLYPH-1380F;Lo;0;L;;;;;N;;;;; +13810;EGYPTIAN HIEROGLYPH-13810;Lo;0;L;;;;;N;;;;; +13811;EGYPTIAN HIEROGLYPH-13811;Lo;0;L;;;;;N;;;;; +13812;EGYPTIAN HIEROGLYPH-13812;Lo;0;L;;;;;N;;;;; +13813;EGYPTIAN HIEROGLYPH-13813;Lo;0;L;;;;;N;;;;; +13814;EGYPTIAN HIEROGLYPH-13814;Lo;0;L;;;;;N;;;;; +13815;EGYPTIAN HIEROGLYPH-13815;Lo;0;L;;;;;N;;;;; +13816;EGYPTIAN HIEROGLYPH-13816;Lo;0;L;;;;;N;;;;; +13817;EGYPTIAN HIEROGLYPH-13817;Lo;0;L;;;;;N;;;;; +13818;EGYPTIAN HIEROGLYPH-13818;Lo;0;L;;;;;N;;;;; +13819;EGYPTIAN HIEROGLYPH-13819;Lo;0;L;;;;;N;;;;; +1381A;EGYPTIAN HIEROGLYPH-1381A;Lo;0;L;;;;;N;;;;; +1381B;EGYPTIAN HIEROGLYPH-1381B;Lo;0;L;;;;;N;;;;; +1381C;EGYPTIAN HIEROGLYPH-1381C;Lo;0;L;;;;;N;;;;; +1381D;EGYPTIAN HIEROGLYPH-1381D;Lo;0;L;;;;;N;;;;; +1381E;EGYPTIAN HIEROGLYPH-1381E;Lo;0;L;;;;;N;;;;; +1381F;EGYPTIAN HIEROGLYPH-1381F;Lo;0;L;;;;;N;;;;; +13820;EGYPTIAN HIEROGLYPH-13820;Lo;0;L;;;;;N;;;;; +13821;EGYPTIAN HIEROGLYPH-13821;Lo;0;L;;;;;N;;;;; +13822;EGYPTIAN HIEROGLYPH-13822;Lo;0;L;;;;;N;;;;; +13823;EGYPTIAN HIEROGLYPH-13823;Lo;0;L;;;;;N;;;;; +13824;EGYPTIAN HIEROGLYPH-13824;Lo;0;L;;;;;N;;;;; +13825;EGYPTIAN HIEROGLYPH-13825;Lo;0;L;;;;;N;;;;; +13826;EGYPTIAN HIEROGLYPH-13826;Lo;0;L;;;;;N;;;;; +13827;EGYPTIAN HIEROGLYPH-13827;Lo;0;L;;;;;N;;;;; +13828;EGYPTIAN HIEROGLYPH-13828;Lo;0;L;;;;;N;;;;; +13829;EGYPTIAN HIEROGLYPH-13829;Lo;0;L;;;;;N;;;;; +1382A;EGYPTIAN HIEROGLYPH-1382A;Lo;0;L;;;;;N;;;;; +1382B;EGYPTIAN HIEROGLYPH-1382B;Lo;0;L;;;;;N;;;;; +1382C;EGYPTIAN HIEROGLYPH-1382C;Lo;0;L;;;;;N;;;;; +1382D;EGYPTIAN HIEROGLYPH-1382D;Lo;0;L;;;;;N;;;;; +1382E;EGYPTIAN HIEROGLYPH-1382E;Lo;0;L;;;;;N;;;;; +1382F;EGYPTIAN HIEROGLYPH-1382F;Lo;0;L;;;;;N;;;;; +13830;EGYPTIAN HIEROGLYPH-13830;Lo;0;L;;;;;N;;;;; +13831;EGYPTIAN HIEROGLYPH-13831;Lo;0;L;;;;;N;;;;; +13832;EGYPTIAN HIEROGLYPH-13832;Lo;0;L;;;;;N;;;;; +13833;EGYPTIAN HIEROGLYPH-13833;Lo;0;L;;;;;N;;;;; +13834;EGYPTIAN HIEROGLYPH-13834;Lo;0;L;;;;;N;;;;; +13835;EGYPTIAN HIEROGLYPH-13835;Lo;0;L;;;;;N;;;;; +13836;EGYPTIAN HIEROGLYPH-13836;Lo;0;L;;;;;N;;;;; +13837;EGYPTIAN HIEROGLYPH-13837;Lo;0;L;;;;;N;;;;; +13838;EGYPTIAN HIEROGLYPH-13838;Lo;0;L;;;;;N;;;;; +13839;EGYPTIAN HIEROGLYPH-13839;Lo;0;L;;;;;N;;;;; +1383A;EGYPTIAN HIEROGLYPH-1383A;Lo;0;L;;;;;N;;;;; +1383B;EGYPTIAN HIEROGLYPH-1383B;Lo;0;L;;;;;N;;;;; +1383C;EGYPTIAN HIEROGLYPH-1383C;Lo;0;L;;;;;N;;;;; +1383D;EGYPTIAN HIEROGLYPH-1383D;Lo;0;L;;;;;N;;;;; +1383E;EGYPTIAN HIEROGLYPH-1383E;Lo;0;L;;;;;N;;;;; +1383F;EGYPTIAN HIEROGLYPH-1383F;Lo;0;L;;;;;N;;;;; +13840;EGYPTIAN HIEROGLYPH-13840;Lo;0;L;;;;;N;;;;; +13841;EGYPTIAN HIEROGLYPH-13841;Lo;0;L;;;;;N;;;;; +13842;EGYPTIAN HIEROGLYPH-13842;Lo;0;L;;;;;N;;;;; +13843;EGYPTIAN HIEROGLYPH-13843;Lo;0;L;;;;;N;;;;; +13844;EGYPTIAN HIEROGLYPH-13844;Lo;0;L;;;;;N;;;;; +13845;EGYPTIAN HIEROGLYPH-13845;Lo;0;L;;;;;N;;;;; +13846;EGYPTIAN HIEROGLYPH-13846;Lo;0;L;;;;;N;;;;; +13847;EGYPTIAN HIEROGLYPH-13847;Lo;0;L;;;;;N;;;;; +13848;EGYPTIAN HIEROGLYPH-13848;Lo;0;L;;;;;N;;;;; +13849;EGYPTIAN HIEROGLYPH-13849;Lo;0;L;;;;;N;;;;; +1384A;EGYPTIAN HIEROGLYPH-1384A;Lo;0;L;;;;;N;;;;; +1384B;EGYPTIAN HIEROGLYPH-1384B;Lo;0;L;;;;;N;;;;; +1384C;EGYPTIAN HIEROGLYPH-1384C;Lo;0;L;;;;;N;;;;; +1384D;EGYPTIAN HIEROGLYPH-1384D;Lo;0;L;;;;;N;;;;; +1384E;EGYPTIAN HIEROGLYPH-1384E;Lo;0;L;;;;;N;;;;; +1384F;EGYPTIAN HIEROGLYPH-1384F;Lo;0;L;;;;;N;;;;; +13850;EGYPTIAN HIEROGLYPH-13850;Lo;0;L;;;;;N;;;;; +13851;EGYPTIAN HIEROGLYPH-13851;Lo;0;L;;;;;N;;;;; +13852;EGYPTIAN HIEROGLYPH-13852;Lo;0;L;;;;;N;;;;; +13853;EGYPTIAN HIEROGLYPH-13853;Lo;0;L;;;;;N;;;;; +13854;EGYPTIAN HIEROGLYPH-13854;Lo;0;L;;;;;N;;;;; +13855;EGYPTIAN HIEROGLYPH-13855;Lo;0;L;;;;;N;;;;; +13856;EGYPTIAN HIEROGLYPH-13856;Lo;0;L;;;;;N;;;;; +13857;EGYPTIAN HIEROGLYPH-13857;Lo;0;L;;;;;N;;;;; +13858;EGYPTIAN HIEROGLYPH-13858;Lo;0;L;;;;;N;;;;; +13859;EGYPTIAN HIEROGLYPH-13859;Lo;0;L;;;;;N;;;;; +1385A;EGYPTIAN HIEROGLYPH-1385A;Lo;0;L;;;;;N;;;;; +1385B;EGYPTIAN HIEROGLYPH-1385B;Lo;0;L;;;;;N;;;;; +1385C;EGYPTIAN HIEROGLYPH-1385C;Lo;0;L;;;;;N;;;;; +1385D;EGYPTIAN HIEROGLYPH-1385D;Lo;0;L;;;;;N;;;;; +1385E;EGYPTIAN HIEROGLYPH-1385E;Lo;0;L;;;;;N;;;;; +1385F;EGYPTIAN HIEROGLYPH-1385F;Lo;0;L;;;;;N;;;;; +13860;EGYPTIAN HIEROGLYPH-13860;Lo;0;L;;;;;N;;;;; +13861;EGYPTIAN HIEROGLYPH-13861;Lo;0;L;;;;;N;;;;; +13862;EGYPTIAN HIEROGLYPH-13862;Lo;0;L;;;;;N;;;;; +13863;EGYPTIAN HIEROGLYPH-13863;Lo;0;L;;;;;N;;;;; +13864;EGYPTIAN HIEROGLYPH-13864;Lo;0;L;;;;;N;;;;; +13865;EGYPTIAN HIEROGLYPH-13865;Lo;0;L;;;;;N;;;;; +13866;EGYPTIAN HIEROGLYPH-13866;Lo;0;L;;;;;N;;;;; +13867;EGYPTIAN HIEROGLYPH-13867;Lo;0;L;;;;;N;;;;; +13868;EGYPTIAN HIEROGLYPH-13868;Lo;0;L;;;;;N;;;;; +13869;EGYPTIAN HIEROGLYPH-13869;Lo;0;L;;;;;N;;;;; +1386A;EGYPTIAN HIEROGLYPH-1386A;Lo;0;L;;;;;N;;;;; +1386B;EGYPTIAN HIEROGLYPH-1386B;Lo;0;L;;;;;N;;;;; +1386C;EGYPTIAN HIEROGLYPH-1386C;Lo;0;L;;;;;N;;;;; +1386D;EGYPTIAN HIEROGLYPH-1386D;Lo;0;L;;;;;N;;;;; +1386E;EGYPTIAN HIEROGLYPH-1386E;Lo;0;L;;;;;N;;;;; +1386F;EGYPTIAN HIEROGLYPH-1386F;Lo;0;L;;;;;N;;;;; +13870;EGYPTIAN HIEROGLYPH-13870;Lo;0;L;;;;;N;;;;; +13871;EGYPTIAN HIEROGLYPH-13871;Lo;0;L;;;;;N;;;;; +13872;EGYPTIAN HIEROGLYPH-13872;Lo;0;L;;;;;N;;;;; +13873;EGYPTIAN HIEROGLYPH-13873;Lo;0;L;;;;;N;;;;; +13874;EGYPTIAN HIEROGLYPH-13874;Lo;0;L;;;;;N;;;;; +13875;EGYPTIAN HIEROGLYPH-13875;Lo;0;L;;;;;N;;;;; +13876;EGYPTIAN HIEROGLYPH-13876;Lo;0;L;;;;;N;;;;; +13877;EGYPTIAN HIEROGLYPH-13877;Lo;0;L;;;;;N;;;;; +13878;EGYPTIAN HIEROGLYPH-13878;Lo;0;L;;;;;N;;;;; +13879;EGYPTIAN HIEROGLYPH-13879;Lo;0;L;;;;;N;;;;; +1387A;EGYPTIAN HIEROGLYPH-1387A;Lo;0;L;;;;;N;;;;; +1387B;EGYPTIAN HIEROGLYPH-1387B;Lo;0;L;;;;;N;;;;; +1387C;EGYPTIAN HIEROGLYPH-1387C;Lo;0;L;;;;;N;;;;; +1387D;EGYPTIAN HIEROGLYPH-1387D;Lo;0;L;;;;;N;;;;; +1387E;EGYPTIAN HIEROGLYPH-1387E;Lo;0;L;;;;;N;;;;; +1387F;EGYPTIAN HIEROGLYPH-1387F;Lo;0;L;;;;;N;;;;; +13880;EGYPTIAN HIEROGLYPH-13880;Lo;0;L;;;;;N;;;;; +13881;EGYPTIAN HIEROGLYPH-13881;Lo;0;L;;;;;N;;;;; +13882;EGYPTIAN HIEROGLYPH-13882;Lo;0;L;;;;;N;;;;; +13883;EGYPTIAN HIEROGLYPH-13883;Lo;0;L;;;;;N;;;;; +13884;EGYPTIAN HIEROGLYPH-13884;Lo;0;L;;;;;N;;;;; +13885;EGYPTIAN HIEROGLYPH-13885;Lo;0;L;;;;;N;;;;; +13886;EGYPTIAN HIEROGLYPH-13886;Lo;0;L;;;;;N;;;;; +13887;EGYPTIAN HIEROGLYPH-13887;Lo;0;L;;;;;N;;;;; +13888;EGYPTIAN HIEROGLYPH-13888;Lo;0;L;;;;;N;;;;; +13889;EGYPTIAN HIEROGLYPH-13889;Lo;0;L;;;;;N;;;;; +1388A;EGYPTIAN HIEROGLYPH-1388A;Lo;0;L;;;;;N;;;;; +1388B;EGYPTIAN HIEROGLYPH-1388B;Lo;0;L;;;;;N;;;;; +1388C;EGYPTIAN HIEROGLYPH-1388C;Lo;0;L;;;;;N;;;;; +1388D;EGYPTIAN HIEROGLYPH-1388D;Lo;0;L;;;;;N;;;;; +1388E;EGYPTIAN HIEROGLYPH-1388E;Lo;0;L;;;;;N;;;;; +1388F;EGYPTIAN HIEROGLYPH-1388F;Lo;0;L;;;;;N;;;;; +13890;EGYPTIAN HIEROGLYPH-13890;Lo;0;L;;;;;N;;;;; +13891;EGYPTIAN HIEROGLYPH-13891;Lo;0;L;;;;;N;;;;; +13892;EGYPTIAN HIEROGLYPH-13892;Lo;0;L;;;;;N;;;;; +13893;EGYPTIAN HIEROGLYPH-13893;Lo;0;L;;;;;N;;;;; +13894;EGYPTIAN HIEROGLYPH-13894;Lo;0;L;;;;;N;;;;; +13895;EGYPTIAN HIEROGLYPH-13895;Lo;0;L;;;;;N;;;;; +13896;EGYPTIAN HIEROGLYPH-13896;Lo;0;L;;;;;N;;;;; +13897;EGYPTIAN HIEROGLYPH-13897;Lo;0;L;;;;;N;;;;; +13898;EGYPTIAN HIEROGLYPH-13898;Lo;0;L;;;;;N;;;;; +13899;EGYPTIAN HIEROGLYPH-13899;Lo;0;L;;;;;N;;;;; +1389A;EGYPTIAN HIEROGLYPH-1389A;Lo;0;L;;;;;N;;;;; +1389B;EGYPTIAN HIEROGLYPH-1389B;Lo;0;L;;;;;N;;;;; +1389C;EGYPTIAN HIEROGLYPH-1389C;Lo;0;L;;;;;N;;;;; +1389D;EGYPTIAN HIEROGLYPH-1389D;Lo;0;L;;;;;N;;;;; +1389E;EGYPTIAN HIEROGLYPH-1389E;Lo;0;L;;;;;N;;;;; +1389F;EGYPTIAN HIEROGLYPH-1389F;Lo;0;L;;;;;N;;;;; +138A0;EGYPTIAN HIEROGLYPH-138A0;Lo;0;L;;;;;N;;;;; +138A1;EGYPTIAN HIEROGLYPH-138A1;Lo;0;L;;;;;N;;;;; +138A2;EGYPTIAN HIEROGLYPH-138A2;Lo;0;L;;;;;N;;;;; +138A3;EGYPTIAN HIEROGLYPH-138A3;Lo;0;L;;;;;N;;;;; +138A4;EGYPTIAN HIEROGLYPH-138A4;Lo;0;L;;;;;N;;;;; +138A5;EGYPTIAN HIEROGLYPH-138A5;Lo;0;L;;;;;N;;;;; +138A6;EGYPTIAN HIEROGLYPH-138A6;Lo;0;L;;;;;N;;;;; +138A7;EGYPTIAN HIEROGLYPH-138A7;Lo;0;L;;;;;N;;;;; +138A8;EGYPTIAN HIEROGLYPH-138A8;Lo;0;L;;;;;N;;;;; +138A9;EGYPTIAN HIEROGLYPH-138A9;Lo;0;L;;;;;N;;;;; +138AA;EGYPTIAN HIEROGLYPH-138AA;Lo;0;L;;;;;N;;;;; +138AB;EGYPTIAN HIEROGLYPH-138AB;Lo;0;L;;;;;N;;;;; +138AC;EGYPTIAN HIEROGLYPH-138AC;Lo;0;L;;;;;N;;;;; +138AD;EGYPTIAN HIEROGLYPH-138AD;Lo;0;L;;;;;N;;;;; +138AE;EGYPTIAN HIEROGLYPH-138AE;Lo;0;L;;;;;N;;;;; +138AF;EGYPTIAN HIEROGLYPH-138AF;Lo;0;L;;;;;N;;;;; +138B0;EGYPTIAN HIEROGLYPH-138B0;Lo;0;L;;;;;N;;;;; +138B1;EGYPTIAN HIEROGLYPH-138B1;Lo;0;L;;;;;N;;;;; +138B2;EGYPTIAN HIEROGLYPH-138B2;Lo;0;L;;;;;N;;;;; +138B3;EGYPTIAN HIEROGLYPH-138B3;Lo;0;L;;;;;N;;;;; +138B4;EGYPTIAN HIEROGLYPH-138B4;Lo;0;L;;;;;N;;;;; +138B5;EGYPTIAN HIEROGLYPH-138B5;Lo;0;L;;;;;N;;;;; +138B6;EGYPTIAN HIEROGLYPH-138B6;Lo;0;L;;;;;N;;;;; +138B7;EGYPTIAN HIEROGLYPH-138B7;Lo;0;L;;;;;N;;;;; +138B8;EGYPTIAN HIEROGLYPH-138B8;Lo;0;L;;;;;N;;;;; +138B9;EGYPTIAN HIEROGLYPH-138B9;Lo;0;L;;;;;N;;;;; +138BA;EGYPTIAN HIEROGLYPH-138BA;Lo;0;L;;;;;N;;;;; +138BB;EGYPTIAN HIEROGLYPH-138BB;Lo;0;L;;;;;N;;;;; +138BC;EGYPTIAN HIEROGLYPH-138BC;Lo;0;L;;;;;N;;;;; +138BD;EGYPTIAN HIEROGLYPH-138BD;Lo;0;L;;;;;N;;;;; +138BE;EGYPTIAN HIEROGLYPH-138BE;Lo;0;L;;;;;N;;;;; +138BF;EGYPTIAN HIEROGLYPH-138BF;Lo;0;L;;;;;N;;;;; +138C0;EGYPTIAN HIEROGLYPH-138C0;Lo;0;L;;;;;N;;;;; +138C1;EGYPTIAN HIEROGLYPH-138C1;Lo;0;L;;;;;N;;;;; +138C2;EGYPTIAN HIEROGLYPH-138C2;Lo;0;L;;;;;N;;;;; +138C3;EGYPTIAN HIEROGLYPH-138C3;Lo;0;L;;;;;N;;;;; +138C4;EGYPTIAN HIEROGLYPH-138C4;Lo;0;L;;;;;N;;;;; +138C5;EGYPTIAN HIEROGLYPH-138C5;Lo;0;L;;;;;N;;;;; +138C6;EGYPTIAN HIEROGLYPH-138C6;Lo;0;L;;;;;N;;;;; +138C7;EGYPTIAN HIEROGLYPH-138C7;Lo;0;L;;;;;N;;;;; +138C8;EGYPTIAN HIEROGLYPH-138C8;Lo;0;L;;;;;N;;;;; +138C9;EGYPTIAN HIEROGLYPH-138C9;Lo;0;L;;;;;N;;;;; +138CA;EGYPTIAN HIEROGLYPH-138CA;Lo;0;L;;;;;N;;;;; +138CB;EGYPTIAN HIEROGLYPH-138CB;Lo;0;L;;;;;N;;;;; +138CC;EGYPTIAN HIEROGLYPH-138CC;Lo;0;L;;;;;N;;;;; +138CD;EGYPTIAN HIEROGLYPH-138CD;Lo;0;L;;;;;N;;;;; +138CE;EGYPTIAN HIEROGLYPH-138CE;Lo;0;L;;;;;N;;;;; +138CF;EGYPTIAN HIEROGLYPH-138CF;Lo;0;L;;;;;N;;;;; +138D0;EGYPTIAN HIEROGLYPH-138D0;Lo;0;L;;;;;N;;;;; +138D1;EGYPTIAN HIEROGLYPH-138D1;Lo;0;L;;;;;N;;;;; +138D2;EGYPTIAN HIEROGLYPH-138D2;Lo;0;L;;;;;N;;;;; +138D3;EGYPTIAN HIEROGLYPH-138D3;Lo;0;L;;;;;N;;;;; +138D4;EGYPTIAN HIEROGLYPH-138D4;Lo;0;L;;;;;N;;;;; +138D5;EGYPTIAN HIEROGLYPH-138D5;Lo;0;L;;;;;N;;;;; +138D6;EGYPTIAN HIEROGLYPH-138D6;Lo;0;L;;;;;N;;;;; +138D7;EGYPTIAN HIEROGLYPH-138D7;Lo;0;L;;;;;N;;;;; +138D8;EGYPTIAN HIEROGLYPH-138D8;Lo;0;L;;;;;N;;;;; +138D9;EGYPTIAN HIEROGLYPH-138D9;Lo;0;L;;;;;N;;;;; +138DA;EGYPTIAN HIEROGLYPH-138DA;Lo;0;L;;;;;N;;;;; +138DB;EGYPTIAN HIEROGLYPH-138DB;Lo;0;L;;;;;N;;;;; +138DC;EGYPTIAN HIEROGLYPH-138DC;Lo;0;L;;;;;N;;;;; +138DD;EGYPTIAN HIEROGLYPH-138DD;Lo;0;L;;;;;N;;;;; +138DE;EGYPTIAN HIEROGLYPH-138DE;Lo;0;L;;;;;N;;;;; +138DF;EGYPTIAN HIEROGLYPH-138DF;Lo;0;L;;;;;N;;;;; +138E0;EGYPTIAN HIEROGLYPH-138E0;Lo;0;L;;;;;N;;;;; +138E1;EGYPTIAN HIEROGLYPH-138E1;Lo;0;L;;;;;N;;;;; +138E2;EGYPTIAN HIEROGLYPH-138E2;Lo;0;L;;;;;N;;;;; +138E3;EGYPTIAN HIEROGLYPH-138E3;Lo;0;L;;;;;N;;;;; +138E4;EGYPTIAN HIEROGLYPH-138E4;Lo;0;L;;;;;N;;;;; +138E5;EGYPTIAN HIEROGLYPH-138E5;Lo;0;L;;;;;N;;;;; +138E6;EGYPTIAN HIEROGLYPH-138E6;Lo;0;L;;;;;N;;;;; +138E7;EGYPTIAN HIEROGLYPH-138E7;Lo;0;L;;;;;N;;;;; +138E8;EGYPTIAN HIEROGLYPH-138E8;Lo;0;L;;;;;N;;;;; +138E9;EGYPTIAN HIEROGLYPH-138E9;Lo;0;L;;;;;N;;;;; +138EA;EGYPTIAN HIEROGLYPH-138EA;Lo;0;L;;;;;N;;;;; +138EB;EGYPTIAN HIEROGLYPH-138EB;Lo;0;L;;;;;N;;;;; +138EC;EGYPTIAN HIEROGLYPH-138EC;Lo;0;L;;;;;N;;;;; +138ED;EGYPTIAN HIEROGLYPH-138ED;Lo;0;L;;;;;N;;;;; +138EE;EGYPTIAN HIEROGLYPH-138EE;Lo;0;L;;;;;N;;;;; +138EF;EGYPTIAN HIEROGLYPH-138EF;Lo;0;L;;;;;N;;;;; +138F0;EGYPTIAN HIEROGLYPH-138F0;Lo;0;L;;;;;N;;;;; +138F1;EGYPTIAN HIEROGLYPH-138F1;Lo;0;L;;;;;N;;;;; +138F2;EGYPTIAN HIEROGLYPH-138F2;Lo;0;L;;;;;N;;;;; +138F3;EGYPTIAN HIEROGLYPH-138F3;Lo;0;L;;;;;N;;;;; +138F4;EGYPTIAN HIEROGLYPH-138F4;Lo;0;L;;;;;N;;;;; +138F5;EGYPTIAN HIEROGLYPH-138F5;Lo;0;L;;;;;N;;;;; +138F6;EGYPTIAN HIEROGLYPH-138F6;Lo;0;L;;;;;N;;;;; +138F7;EGYPTIAN HIEROGLYPH-138F7;Lo;0;L;;;;;N;;;;; +138F8;EGYPTIAN HIEROGLYPH-138F8;Lo;0;L;;;;;N;;;;; +138F9;EGYPTIAN HIEROGLYPH-138F9;Lo;0;L;;;;;N;;;;; +138FA;EGYPTIAN HIEROGLYPH-138FA;Lo;0;L;;;;;N;;;;; +138FB;EGYPTIAN HIEROGLYPH-138FB;Lo;0;L;;;;;N;;;;; +138FC;EGYPTIAN HIEROGLYPH-138FC;Lo;0;L;;;;;N;;;;; +138FD;EGYPTIAN HIEROGLYPH-138FD;Lo;0;L;;;;;N;;;;; +138FE;EGYPTIAN HIEROGLYPH-138FE;Lo;0;L;;;;;N;;;;; +138FF;EGYPTIAN HIEROGLYPH-138FF;Lo;0;L;;;;;N;;;;; +13900;EGYPTIAN HIEROGLYPH-13900;Lo;0;L;;;;;N;;;;; +13901;EGYPTIAN HIEROGLYPH-13901;Lo;0;L;;;;;N;;;;; +13902;EGYPTIAN HIEROGLYPH-13902;Lo;0;L;;;;;N;;;;; +13903;EGYPTIAN HIEROGLYPH-13903;Lo;0;L;;;;;N;;;;; +13904;EGYPTIAN HIEROGLYPH-13904;Lo;0;L;;;;;N;;;;; +13905;EGYPTIAN HIEROGLYPH-13905;Lo;0;L;;;;;N;;;;; +13906;EGYPTIAN HIEROGLYPH-13906;Lo;0;L;;;;;N;;;;; +13907;EGYPTIAN HIEROGLYPH-13907;Lo;0;L;;;;;N;;;;; +13908;EGYPTIAN HIEROGLYPH-13908;Lo;0;L;;;;;N;;;;; +13909;EGYPTIAN HIEROGLYPH-13909;Lo;0;L;;;;;N;;;;; +1390A;EGYPTIAN HIEROGLYPH-1390A;Lo;0;L;;;;;N;;;;; +1390B;EGYPTIAN HIEROGLYPH-1390B;Lo;0;L;;;;;N;;;;; +1390C;EGYPTIAN HIEROGLYPH-1390C;Lo;0;L;;;;;N;;;;; +1390D;EGYPTIAN HIEROGLYPH-1390D;Lo;0;L;;;;;N;;;;; +1390E;EGYPTIAN HIEROGLYPH-1390E;Lo;0;L;;;;;N;;;;; +1390F;EGYPTIAN HIEROGLYPH-1390F;Lo;0;L;;;;;N;;;;; +13910;EGYPTIAN HIEROGLYPH-13910;Lo;0;L;;;;;N;;;;; +13911;EGYPTIAN HIEROGLYPH-13911;Lo;0;L;;;;;N;;;;; +13912;EGYPTIAN HIEROGLYPH-13912;Lo;0;L;;;;;N;;;;; +13913;EGYPTIAN HIEROGLYPH-13913;Lo;0;L;;;;;N;;;;; +13914;EGYPTIAN HIEROGLYPH-13914;Lo;0;L;;;;;N;;;;; +13915;EGYPTIAN HIEROGLYPH-13915;Lo;0;L;;;;;N;;;;; +13916;EGYPTIAN HIEROGLYPH-13916;Lo;0;L;;;;;N;;;;; +13917;EGYPTIAN HIEROGLYPH-13917;Lo;0;L;;;;;N;;;;; +13918;EGYPTIAN HIEROGLYPH-13918;Lo;0;L;;;;;N;;;;; +13919;EGYPTIAN HIEROGLYPH-13919;Lo;0;L;;;;;N;;;;; +1391A;EGYPTIAN HIEROGLYPH-1391A;Lo;0;L;;;;;N;;;;; +1391B;EGYPTIAN HIEROGLYPH-1391B;Lo;0;L;;;;;N;;;;; +1391C;EGYPTIAN HIEROGLYPH-1391C;Lo;0;L;;;;;N;;;;; +1391D;EGYPTIAN HIEROGLYPH-1391D;Lo;0;L;;;;;N;;;;; +1391E;EGYPTIAN HIEROGLYPH-1391E;Lo;0;L;;;;;N;;;;; +1391F;EGYPTIAN HIEROGLYPH-1391F;Lo;0;L;;;;;N;;;;; +13920;EGYPTIAN HIEROGLYPH-13920;Lo;0;L;;;;;N;;;;; +13921;EGYPTIAN HIEROGLYPH-13921;Lo;0;L;;;;;N;;;;; +13922;EGYPTIAN HIEROGLYPH-13922;Lo;0;L;;;;;N;;;;; +13923;EGYPTIAN HIEROGLYPH-13923;Lo;0;L;;;;;N;;;;; +13924;EGYPTIAN HIEROGLYPH-13924;Lo;0;L;;;;;N;;;;; +13925;EGYPTIAN HIEROGLYPH-13925;Lo;0;L;;;;;N;;;;; +13926;EGYPTIAN HIEROGLYPH-13926;Lo;0;L;;;;;N;;;;; +13927;EGYPTIAN HIEROGLYPH-13927;Lo;0;L;;;;;N;;;;; +13928;EGYPTIAN HIEROGLYPH-13928;Lo;0;L;;;;;N;;;;; +13929;EGYPTIAN HIEROGLYPH-13929;Lo;0;L;;;;;N;;;;; +1392A;EGYPTIAN HIEROGLYPH-1392A;Lo;0;L;;;;;N;;;;; +1392B;EGYPTIAN HIEROGLYPH-1392B;Lo;0;L;;;;;N;;;;; +1392C;EGYPTIAN HIEROGLYPH-1392C;Lo;0;L;;;;;N;;;;; +1392D;EGYPTIAN HIEROGLYPH-1392D;Lo;0;L;;;;;N;;;;; +1392E;EGYPTIAN HIEROGLYPH-1392E;Lo;0;L;;;;;N;;;;; +1392F;EGYPTIAN HIEROGLYPH-1392F;Lo;0;L;;;;;N;;;;; +13930;EGYPTIAN HIEROGLYPH-13930;Lo;0;L;;;;;N;;;;; +13931;EGYPTIAN HIEROGLYPH-13931;Lo;0;L;;;;;N;;;;; +13932;EGYPTIAN HIEROGLYPH-13932;Lo;0;L;;;;;N;;;;; +13933;EGYPTIAN HIEROGLYPH-13933;Lo;0;L;;;;;N;;;;; +13934;EGYPTIAN HIEROGLYPH-13934;Lo;0;L;;;;;N;;;;; +13935;EGYPTIAN HIEROGLYPH-13935;Lo;0;L;;;;;N;;;;; +13936;EGYPTIAN HIEROGLYPH-13936;Lo;0;L;;;;;N;;;;; +13937;EGYPTIAN HIEROGLYPH-13937;Lo;0;L;;;;;N;;;;; +13938;EGYPTIAN HIEROGLYPH-13938;Lo;0;L;;;;;N;;;;; +13939;EGYPTIAN HIEROGLYPH-13939;Lo;0;L;;;;;N;;;;; +1393A;EGYPTIAN HIEROGLYPH-1393A;Lo;0;L;;;;;N;;;;; +1393B;EGYPTIAN HIEROGLYPH-1393B;Lo;0;L;;;;;N;;;;; +1393C;EGYPTIAN HIEROGLYPH-1393C;Lo;0;L;;;;;N;;;;; +1393D;EGYPTIAN HIEROGLYPH-1393D;Lo;0;L;;;;;N;;;;; +1393E;EGYPTIAN HIEROGLYPH-1393E;Lo;0;L;;;;;N;;;;; +1393F;EGYPTIAN HIEROGLYPH-1393F;Lo;0;L;;;;;N;;;;; +13940;EGYPTIAN HIEROGLYPH-13940;Lo;0;L;;;;;N;;;;; +13941;EGYPTIAN HIEROGLYPH-13941;Lo;0;L;;;;;N;;;;; +13942;EGYPTIAN HIEROGLYPH-13942;Lo;0;L;;;;;N;;;;; +13943;EGYPTIAN HIEROGLYPH-13943;Lo;0;L;;;;;N;;;;; +13944;EGYPTIAN HIEROGLYPH-13944;Lo;0;L;;;;;N;;;;; +13945;EGYPTIAN HIEROGLYPH-13945;Lo;0;L;;;;;N;;;;; +13946;EGYPTIAN HIEROGLYPH-13946;Lo;0;L;;;;;N;;;;; +13947;EGYPTIAN HIEROGLYPH-13947;Lo;0;L;;;;;N;;;;; +13948;EGYPTIAN HIEROGLYPH-13948;Lo;0;L;;;;;N;;;;; +13949;EGYPTIAN HIEROGLYPH-13949;Lo;0;L;;;;;N;;;;; +1394A;EGYPTIAN HIEROGLYPH-1394A;Lo;0;L;;;;;N;;;;; +1394B;EGYPTIAN HIEROGLYPH-1394B;Lo;0;L;;;;;N;;;;; +1394C;EGYPTIAN HIEROGLYPH-1394C;Lo;0;L;;;;;N;;;;; +1394D;EGYPTIAN HIEROGLYPH-1394D;Lo;0;L;;;;;N;;;;; +1394E;EGYPTIAN HIEROGLYPH-1394E;Lo;0;L;;;;;N;;;;; +1394F;EGYPTIAN HIEROGLYPH-1394F;Lo;0;L;;;;;N;;;;; +13950;EGYPTIAN HIEROGLYPH-13950;Lo;0;L;;;;;N;;;;; +13951;EGYPTIAN HIEROGLYPH-13951;Lo;0;L;;;;;N;;;;; +13952;EGYPTIAN HIEROGLYPH-13952;Lo;0;L;;;;;N;;;;; +13953;EGYPTIAN HIEROGLYPH-13953;Lo;0;L;;;;;N;;;;; +13954;EGYPTIAN HIEROGLYPH-13954;Lo;0;L;;;;;N;;;;; +13955;EGYPTIAN HIEROGLYPH-13955;Lo;0;L;;;;;N;;;;; +13956;EGYPTIAN HIEROGLYPH-13956;Lo;0;L;;;;;N;;;;; +13957;EGYPTIAN HIEROGLYPH-13957;Lo;0;L;;;;;N;;;;; +13958;EGYPTIAN HIEROGLYPH-13958;Lo;0;L;;;;;N;;;;; +13959;EGYPTIAN HIEROGLYPH-13959;Lo;0;L;;;;;N;;;;; +1395A;EGYPTIAN HIEROGLYPH-1395A;Lo;0;L;;;;;N;;;;; +1395B;EGYPTIAN HIEROGLYPH-1395B;Lo;0;L;;;;;N;;;;; +1395C;EGYPTIAN HIEROGLYPH-1395C;Lo;0;L;;;;;N;;;;; +1395D;EGYPTIAN HIEROGLYPH-1395D;Lo;0;L;;;;;N;;;;; +1395E;EGYPTIAN HIEROGLYPH-1395E;Lo;0;L;;;;;N;;;;; +1395F;EGYPTIAN HIEROGLYPH-1395F;Lo;0;L;;;;;N;;;;; +13960;EGYPTIAN HIEROGLYPH-13960;Lo;0;L;;;;;N;;;;; +13961;EGYPTIAN HIEROGLYPH-13961;Lo;0;L;;;;;N;;;;; +13962;EGYPTIAN HIEROGLYPH-13962;Lo;0;L;;;;;N;;;;; +13963;EGYPTIAN HIEROGLYPH-13963;Lo;0;L;;;;;N;;;;; +13964;EGYPTIAN HIEROGLYPH-13964;Lo;0;L;;;;;N;;;;; +13965;EGYPTIAN HIEROGLYPH-13965;Lo;0;L;;;;;N;;;;; +13966;EGYPTIAN HIEROGLYPH-13966;Lo;0;L;;;;;N;;;;; +13967;EGYPTIAN HIEROGLYPH-13967;Lo;0;L;;;;;N;;;;; +13968;EGYPTIAN HIEROGLYPH-13968;Lo;0;L;;;;;N;;;;; +13969;EGYPTIAN HIEROGLYPH-13969;Lo;0;L;;;;;N;;;;; +1396A;EGYPTIAN HIEROGLYPH-1396A;Lo;0;L;;;;;N;;;;; +1396B;EGYPTIAN HIEROGLYPH-1396B;Lo;0;L;;;;;N;;;;; +1396C;EGYPTIAN HIEROGLYPH-1396C;Lo;0;L;;;;;N;;;;; +1396D;EGYPTIAN HIEROGLYPH-1396D;Lo;0;L;;;;;N;;;;; +1396E;EGYPTIAN HIEROGLYPH-1396E;Lo;0;L;;;;;N;;;;; +1396F;EGYPTIAN HIEROGLYPH-1396F;Lo;0;L;;;;;N;;;;; +13970;EGYPTIAN HIEROGLYPH-13970;Lo;0;L;;;;;N;;;;; +13971;EGYPTIAN HIEROGLYPH-13971;Lo;0;L;;;;;N;;;;; +13972;EGYPTIAN HIEROGLYPH-13972;Lo;0;L;;;;;N;;;;; +13973;EGYPTIAN HIEROGLYPH-13973;Lo;0;L;;;;;N;;;;; +13974;EGYPTIAN HIEROGLYPH-13974;Lo;0;L;;;;;N;;;;; +13975;EGYPTIAN HIEROGLYPH-13975;Lo;0;L;;;;;N;;;;; +13976;EGYPTIAN HIEROGLYPH-13976;Lo;0;L;;;;;N;;;;; +13977;EGYPTIAN HIEROGLYPH-13977;Lo;0;L;;;;;N;;;;; +13978;EGYPTIAN HIEROGLYPH-13978;Lo;0;L;;;;;N;;;;; +13979;EGYPTIAN HIEROGLYPH-13979;Lo;0;L;;;;;N;;;;; +1397A;EGYPTIAN HIEROGLYPH-1397A;Lo;0;L;;;;;N;;;;; +1397B;EGYPTIAN HIEROGLYPH-1397B;Lo;0;L;;;;;N;;;;; +1397C;EGYPTIAN HIEROGLYPH-1397C;Lo;0;L;;;;;N;;;;; +1397D;EGYPTIAN HIEROGLYPH-1397D;Lo;0;L;;;;;N;;;;; +1397E;EGYPTIAN HIEROGLYPH-1397E;Lo;0;L;;;;;N;;;;; +1397F;EGYPTIAN HIEROGLYPH-1397F;Lo;0;L;;;;;N;;;;; +13980;EGYPTIAN HIEROGLYPH-13980;Lo;0;L;;;;;N;;;;; +13981;EGYPTIAN HIEROGLYPH-13981;Lo;0;L;;;;;N;;;;; +13982;EGYPTIAN HIEROGLYPH-13982;Lo;0;L;;;;;N;;;;; +13983;EGYPTIAN HIEROGLYPH-13983;Lo;0;L;;;;;N;;;;; +13984;EGYPTIAN HIEROGLYPH-13984;Lo;0;L;;;;;N;;;;; +13985;EGYPTIAN HIEROGLYPH-13985;Lo;0;L;;;;;N;;;;; +13986;EGYPTIAN HIEROGLYPH-13986;Lo;0;L;;;;;N;;;;; +13987;EGYPTIAN HIEROGLYPH-13987;Lo;0;L;;;;;N;;;;; +13988;EGYPTIAN HIEROGLYPH-13988;Lo;0;L;;;;;N;;;;; +13989;EGYPTIAN HIEROGLYPH-13989;Lo;0;L;;;;;N;;;;; +1398A;EGYPTIAN HIEROGLYPH-1398A;Lo;0;L;;;;;N;;;;; +1398B;EGYPTIAN HIEROGLYPH-1398B;Lo;0;L;;;;;N;;;;; +1398C;EGYPTIAN HIEROGLYPH-1398C;Lo;0;L;;;;;N;;;;; +1398D;EGYPTIAN HIEROGLYPH-1398D;Lo;0;L;;;;;N;;;;; +1398E;EGYPTIAN HIEROGLYPH-1398E;Lo;0;L;;;;;N;;;;; +1398F;EGYPTIAN HIEROGLYPH-1398F;Lo;0;L;;;;;N;;;;; +13990;EGYPTIAN HIEROGLYPH-13990;Lo;0;L;;;;;N;;;;; +13991;EGYPTIAN HIEROGLYPH-13991;Lo;0;L;;;;;N;;;;; +13992;EGYPTIAN HIEROGLYPH-13992;Lo;0;L;;;;;N;;;;; +13993;EGYPTIAN HIEROGLYPH-13993;Lo;0;L;;;;;N;;;;; +13994;EGYPTIAN HIEROGLYPH-13994;Lo;0;L;;;;;N;;;;; +13995;EGYPTIAN HIEROGLYPH-13995;Lo;0;L;;;;;N;;;;; +13996;EGYPTIAN HIEROGLYPH-13996;Lo;0;L;;;;;N;;;;; +13997;EGYPTIAN HIEROGLYPH-13997;Lo;0;L;;;;;N;;;;; +13998;EGYPTIAN HIEROGLYPH-13998;Lo;0;L;;;;;N;;;;; +13999;EGYPTIAN HIEROGLYPH-13999;Lo;0;L;;;;;N;;;;; +1399A;EGYPTIAN HIEROGLYPH-1399A;Lo;0;L;;;;;N;;;;; +1399B;EGYPTIAN HIEROGLYPH-1399B;Lo;0;L;;;;;N;;;;; +1399C;EGYPTIAN HIEROGLYPH-1399C;Lo;0;L;;;;;N;;;;; +1399D;EGYPTIAN HIEROGLYPH-1399D;Lo;0;L;;;;;N;;;;; +1399E;EGYPTIAN HIEROGLYPH-1399E;Lo;0;L;;;;;N;;;;; +1399F;EGYPTIAN HIEROGLYPH-1399F;Lo;0;L;;;;;N;;;;; +139A0;EGYPTIAN HIEROGLYPH-139A0;Lo;0;L;;;;;N;;;;; +139A1;EGYPTIAN HIEROGLYPH-139A1;Lo;0;L;;;;;N;;;;; +139A2;EGYPTIAN HIEROGLYPH-139A2;Lo;0;L;;;;;N;;;;; +139A3;EGYPTIAN HIEROGLYPH-139A3;Lo;0;L;;;;;N;;;;; +139A4;EGYPTIAN HIEROGLYPH-139A4;Lo;0;L;;;;;N;;;;; +139A5;EGYPTIAN HIEROGLYPH-139A5;Lo;0;L;;;;;N;;;;; +139A6;EGYPTIAN HIEROGLYPH-139A6;Lo;0;L;;;;;N;;;;; +139A7;EGYPTIAN HIEROGLYPH-139A7;Lo;0;L;;;;;N;;;;; +139A8;EGYPTIAN HIEROGLYPH-139A8;Lo;0;L;;;;;N;;;;; +139A9;EGYPTIAN HIEROGLYPH-139A9;Lo;0;L;;;;;N;;;;; +139AA;EGYPTIAN HIEROGLYPH-139AA;Lo;0;L;;;;;N;;;;; +139AB;EGYPTIAN HIEROGLYPH-139AB;Lo;0;L;;;;;N;;;;; +139AC;EGYPTIAN HIEROGLYPH-139AC;Lo;0;L;;;;;N;;;;; +139AD;EGYPTIAN HIEROGLYPH-139AD;Lo;0;L;;;;;N;;;;; +139AE;EGYPTIAN HIEROGLYPH-139AE;Lo;0;L;;;;;N;;;;; +139AF;EGYPTIAN HIEROGLYPH-139AF;Lo;0;L;;;;;N;;;;; +139B0;EGYPTIAN HIEROGLYPH-139B0;Lo;0;L;;;;;N;;;;; +139B1;EGYPTIAN HIEROGLYPH-139B1;Lo;0;L;;;;;N;;;;; +139B2;EGYPTIAN HIEROGLYPH-139B2;Lo;0;L;;;;;N;;;;; +139B3;EGYPTIAN HIEROGLYPH-139B3;Lo;0;L;;;;;N;;;;; +139B4;EGYPTIAN HIEROGLYPH-139B4;Lo;0;L;;;;;N;;;;; +139B5;EGYPTIAN HIEROGLYPH-139B5;Lo;0;L;;;;;N;;;;; +139B6;EGYPTIAN HIEROGLYPH-139B6;Lo;0;L;;;;;N;;;;; +139B7;EGYPTIAN HIEROGLYPH-139B7;Lo;0;L;;;;;N;;;;; +139B8;EGYPTIAN HIEROGLYPH-139B8;Lo;0;L;;;;;N;;;;; +139B9;EGYPTIAN HIEROGLYPH-139B9;Lo;0;L;;;;;N;;;;; +139BA;EGYPTIAN HIEROGLYPH-139BA;Lo;0;L;;;;;N;;;;; +139BB;EGYPTIAN HIEROGLYPH-139BB;Lo;0;L;;;;;N;;;;; +139BC;EGYPTIAN HIEROGLYPH-139BC;Lo;0;L;;;;;N;;;;; +139BD;EGYPTIAN HIEROGLYPH-139BD;Lo;0;L;;;;;N;;;;; +139BE;EGYPTIAN HIEROGLYPH-139BE;Lo;0;L;;;;;N;;;;; +139BF;EGYPTIAN HIEROGLYPH-139BF;Lo;0;L;;;;;N;;;;; +139C0;EGYPTIAN HIEROGLYPH-139C0;Lo;0;L;;;;;N;;;;; +139C1;EGYPTIAN HIEROGLYPH-139C1;Lo;0;L;;;;;N;;;;; +139C2;EGYPTIAN HIEROGLYPH-139C2;Lo;0;L;;;;;N;;;;; +139C3;EGYPTIAN HIEROGLYPH-139C3;Lo;0;L;;;;;N;;;;; +139C4;EGYPTIAN HIEROGLYPH-139C4;Lo;0;L;;;;;N;;;;; +139C5;EGYPTIAN HIEROGLYPH-139C5;Lo;0;L;;;;;N;;;;; +139C6;EGYPTIAN HIEROGLYPH-139C6;Lo;0;L;;;;;N;;;;; +139C7;EGYPTIAN HIEROGLYPH-139C7;Lo;0;L;;;;;N;;;;; +139C8;EGYPTIAN HIEROGLYPH-139C8;Lo;0;L;;;;;N;;;;; +139C9;EGYPTIAN HIEROGLYPH-139C9;Lo;0;L;;;;;N;;;;; +139CA;EGYPTIAN HIEROGLYPH-139CA;Lo;0;L;;;;;N;;;;; +139CB;EGYPTIAN HIEROGLYPH-139CB;Lo;0;L;;;;;N;;;;; +139CC;EGYPTIAN HIEROGLYPH-139CC;Lo;0;L;;;;;N;;;;; +139CD;EGYPTIAN HIEROGLYPH-139CD;Lo;0;L;;;;;N;;;;; +139CE;EGYPTIAN HIEROGLYPH-139CE;Lo;0;L;;;;;N;;;;; +139CF;EGYPTIAN HIEROGLYPH-139CF;Lo;0;L;;;;;N;;;;; +139D0;EGYPTIAN HIEROGLYPH-139D0;Lo;0;L;;;;;N;;;;; +139D1;EGYPTIAN HIEROGLYPH-139D1;Lo;0;L;;;;;N;;;;; +139D2;EGYPTIAN HIEROGLYPH-139D2;Lo;0;L;;;;;N;;;;; +139D3;EGYPTIAN HIEROGLYPH-139D3;Lo;0;L;;;;;N;;;;; +139D4;EGYPTIAN HIEROGLYPH-139D4;Lo;0;L;;;;;N;;;;; +139D5;EGYPTIAN HIEROGLYPH-139D5;Lo;0;L;;;;;N;;;;; +139D6;EGYPTIAN HIEROGLYPH-139D6;Lo;0;L;;;;;N;;;;; +139D7;EGYPTIAN HIEROGLYPH-139D7;Lo;0;L;;;;;N;;;;; +139D8;EGYPTIAN HIEROGLYPH-139D8;Lo;0;L;;;;;N;;;;; +139D9;EGYPTIAN HIEROGLYPH-139D9;Lo;0;L;;;;;N;;;;; +139DA;EGYPTIAN HIEROGLYPH-139DA;Lo;0;L;;;;;N;;;;; +139DB;EGYPTIAN HIEROGLYPH-139DB;Lo;0;L;;;;;N;;;;; +139DC;EGYPTIAN HIEROGLYPH-139DC;Lo;0;L;;;;;N;;;;; +139DD;EGYPTIAN HIEROGLYPH-139DD;Lo;0;L;;;;;N;;;;; +139DE;EGYPTIAN HIEROGLYPH-139DE;Lo;0;L;;;;;N;;;;; +139DF;EGYPTIAN HIEROGLYPH-139DF;Lo;0;L;;;;;N;;;;; +139E0;EGYPTIAN HIEROGLYPH-139E0;Lo;0;L;;;;;N;;;;; +139E1;EGYPTIAN HIEROGLYPH-139E1;Lo;0;L;;;;;N;;;;; +139E2;EGYPTIAN HIEROGLYPH-139E2;Lo;0;L;;;;;N;;;;; +139E3;EGYPTIAN HIEROGLYPH-139E3;Lo;0;L;;;;;N;;;;; +139E4;EGYPTIAN HIEROGLYPH-139E4;Lo;0;L;;;;;N;;;;; +139E5;EGYPTIAN HIEROGLYPH-139E5;Lo;0;L;;;;;N;;;;; +139E6;EGYPTIAN HIEROGLYPH-139E6;Lo;0;L;;;;;N;;;;; +139E7;EGYPTIAN HIEROGLYPH-139E7;Lo;0;L;;;;;N;;;;; +139E8;EGYPTIAN HIEROGLYPH-139E8;Lo;0;L;;;;;N;;;;; +139E9;EGYPTIAN HIEROGLYPH-139E9;Lo;0;L;;;;;N;;;;; +139EA;EGYPTIAN HIEROGLYPH-139EA;Lo;0;L;;;;;N;;;;; +139EB;EGYPTIAN HIEROGLYPH-139EB;Lo;0;L;;;;;N;;;;; +139EC;EGYPTIAN HIEROGLYPH-139EC;Lo;0;L;;;;;N;;;;; +139ED;EGYPTIAN HIEROGLYPH-139ED;Lo;0;L;;;;;N;;;;; +139EE;EGYPTIAN HIEROGLYPH-139EE;Lo;0;L;;;;;N;;;;; +139EF;EGYPTIAN HIEROGLYPH-139EF;Lo;0;L;;;;;N;;;;; +139F0;EGYPTIAN HIEROGLYPH-139F0;Lo;0;L;;;;;N;;;;; +139F1;EGYPTIAN HIEROGLYPH-139F1;Lo;0;L;;;;;N;;;;; +139F2;EGYPTIAN HIEROGLYPH-139F2;Lo;0;L;;;;;N;;;;; +139F3;EGYPTIAN HIEROGLYPH-139F3;Lo;0;L;;;;;N;;;;; +139F4;EGYPTIAN HIEROGLYPH-139F4;Lo;0;L;;;;;N;;;;; +139F5;EGYPTIAN HIEROGLYPH-139F5;Lo;0;L;;;;;N;;;;; +139F6;EGYPTIAN HIEROGLYPH-139F6;Lo;0;L;;;;;N;;;;; +139F7;EGYPTIAN HIEROGLYPH-139F7;Lo;0;L;;;;;N;;;;; +139F8;EGYPTIAN HIEROGLYPH-139F8;Lo;0;L;;;;;N;;;;; +139F9;EGYPTIAN HIEROGLYPH-139F9;Lo;0;L;;;;;N;;;;; +139FA;EGYPTIAN HIEROGLYPH-139FA;Lo;0;L;;;;;N;;;;; +139FB;EGYPTIAN HIEROGLYPH-139FB;Lo;0;L;;;;;N;;;;; +139FC;EGYPTIAN HIEROGLYPH-139FC;Lo;0;L;;;;;N;;;;; +139FD;EGYPTIAN HIEROGLYPH-139FD;Lo;0;L;;;;;N;;;;; +139FE;EGYPTIAN HIEROGLYPH-139FE;Lo;0;L;;;;;N;;;;; +139FF;EGYPTIAN HIEROGLYPH-139FF;Lo;0;L;;;;;N;;;;; +13A00;EGYPTIAN HIEROGLYPH-13A00;Lo;0;L;;;;;N;;;;; +13A01;EGYPTIAN HIEROGLYPH-13A01;Lo;0;L;;;;;N;;;;; +13A02;EGYPTIAN HIEROGLYPH-13A02;Lo;0;L;;;;;N;;;;; +13A03;EGYPTIAN HIEROGLYPH-13A03;Lo;0;L;;;;;N;;;;; +13A04;EGYPTIAN HIEROGLYPH-13A04;Lo;0;L;;;;;N;;;;; +13A05;EGYPTIAN HIEROGLYPH-13A05;Lo;0;L;;;;;N;;;;; +13A06;EGYPTIAN HIEROGLYPH-13A06;Lo;0;L;;;;;N;;;;; +13A07;EGYPTIAN HIEROGLYPH-13A07;Lo;0;L;;;;;N;;;;; +13A08;EGYPTIAN HIEROGLYPH-13A08;Lo;0;L;;;;;N;;;;; +13A09;EGYPTIAN HIEROGLYPH-13A09;Lo;0;L;;;;;N;;;;; +13A0A;EGYPTIAN HIEROGLYPH-13A0A;Lo;0;L;;;;;N;;;;; +13A0B;EGYPTIAN HIEROGLYPH-13A0B;Lo;0;L;;;;;N;;;;; +13A0C;EGYPTIAN HIEROGLYPH-13A0C;Lo;0;L;;;;;N;;;;; +13A0D;EGYPTIAN HIEROGLYPH-13A0D;Lo;0;L;;;;;N;;;;; +13A0E;EGYPTIAN HIEROGLYPH-13A0E;Lo;0;L;;;;;N;;;;; +13A0F;EGYPTIAN HIEROGLYPH-13A0F;Lo;0;L;;;;;N;;;;; +13A10;EGYPTIAN HIEROGLYPH-13A10;Lo;0;L;;;;;N;;;;; +13A11;EGYPTIAN HIEROGLYPH-13A11;Lo;0;L;;;;;N;;;;; +13A12;EGYPTIAN HIEROGLYPH-13A12;Lo;0;L;;;;;N;;;;; +13A13;EGYPTIAN HIEROGLYPH-13A13;Lo;0;L;;;;;N;;;;; +13A14;EGYPTIAN HIEROGLYPH-13A14;Lo;0;L;;;;;N;;;;; +13A15;EGYPTIAN HIEROGLYPH-13A15;Lo;0;L;;;;;N;;;;; +13A16;EGYPTIAN HIEROGLYPH-13A16;Lo;0;L;;;;;N;;;;; +13A17;EGYPTIAN HIEROGLYPH-13A17;Lo;0;L;;;;;N;;;;; +13A18;EGYPTIAN HIEROGLYPH-13A18;Lo;0;L;;;;;N;;;;; +13A19;EGYPTIAN HIEROGLYPH-13A19;Lo;0;L;;;;;N;;;;; +13A1A;EGYPTIAN HIEROGLYPH-13A1A;Lo;0;L;;;;;N;;;;; +13A1B;EGYPTIAN HIEROGLYPH-13A1B;Lo;0;L;;;;;N;;;;; +13A1C;EGYPTIAN HIEROGLYPH-13A1C;Lo;0;L;;;;;N;;;;; +13A1D;EGYPTIAN HIEROGLYPH-13A1D;Lo;0;L;;;;;N;;;;; +13A1E;EGYPTIAN HIEROGLYPH-13A1E;Lo;0;L;;;;;N;;;;; +13A1F;EGYPTIAN HIEROGLYPH-13A1F;Lo;0;L;;;;;N;;;;; +13A20;EGYPTIAN HIEROGLYPH-13A20;Lo;0;L;;;;;N;;;;; +13A21;EGYPTIAN HIEROGLYPH-13A21;Lo;0;L;;;;;N;;;;; +13A22;EGYPTIAN HIEROGLYPH-13A22;Lo;0;L;;;;;N;;;;; +13A23;EGYPTIAN HIEROGLYPH-13A23;Lo;0;L;;;;;N;;;;; +13A24;EGYPTIAN HIEROGLYPH-13A24;Lo;0;L;;;;;N;;;;; +13A25;EGYPTIAN HIEROGLYPH-13A25;Lo;0;L;;;;;N;;;;; +13A26;EGYPTIAN HIEROGLYPH-13A26;Lo;0;L;;;;;N;;;;; +13A27;EGYPTIAN HIEROGLYPH-13A27;Lo;0;L;;;;;N;;;;; +13A28;EGYPTIAN HIEROGLYPH-13A28;Lo;0;L;;;;;N;;;;; +13A29;EGYPTIAN HIEROGLYPH-13A29;Lo;0;L;;;;;N;;;;; +13A2A;EGYPTIAN HIEROGLYPH-13A2A;Lo;0;L;;;;;N;;;;; +13A2B;EGYPTIAN HIEROGLYPH-13A2B;Lo;0;L;;;;;N;;;;; +13A2C;EGYPTIAN HIEROGLYPH-13A2C;Lo;0;L;;;;;N;;;;; +13A2D;EGYPTIAN HIEROGLYPH-13A2D;Lo;0;L;;;;;N;;;;; +13A2E;EGYPTIAN HIEROGLYPH-13A2E;Lo;0;L;;;;;N;;;;; +13A2F;EGYPTIAN HIEROGLYPH-13A2F;Lo;0;L;;;;;N;;;;; +13A30;EGYPTIAN HIEROGLYPH-13A30;Lo;0;L;;;;;N;;;;; +13A31;EGYPTIAN HIEROGLYPH-13A31;Lo;0;L;;;;;N;;;;; +13A32;EGYPTIAN HIEROGLYPH-13A32;Lo;0;L;;;;;N;;;;; +13A33;EGYPTIAN HIEROGLYPH-13A33;Lo;0;L;;;;;N;;;;; +13A34;EGYPTIAN HIEROGLYPH-13A34;Lo;0;L;;;;;N;;;;; +13A35;EGYPTIAN HIEROGLYPH-13A35;Lo;0;L;;;;;N;;;;; +13A36;EGYPTIAN HIEROGLYPH-13A36;Lo;0;L;;;;;N;;;;; +13A37;EGYPTIAN HIEROGLYPH-13A37;Lo;0;L;;;;;N;;;;; +13A38;EGYPTIAN HIEROGLYPH-13A38;Lo;0;L;;;;;N;;;;; +13A39;EGYPTIAN HIEROGLYPH-13A39;Lo;0;L;;;;;N;;;;; +13A3A;EGYPTIAN HIEROGLYPH-13A3A;Lo;0;L;;;;;N;;;;; +13A3B;EGYPTIAN HIEROGLYPH-13A3B;Lo;0;L;;;;;N;;;;; +13A3C;EGYPTIAN HIEROGLYPH-13A3C;Lo;0;L;;;;;N;;;;; +13A3D;EGYPTIAN HIEROGLYPH-13A3D;Lo;0;L;;;;;N;;;;; +13A3E;EGYPTIAN HIEROGLYPH-13A3E;Lo;0;L;;;;;N;;;;; +13A3F;EGYPTIAN HIEROGLYPH-13A3F;Lo;0;L;;;;;N;;;;; +13A40;EGYPTIAN HIEROGLYPH-13A40;Lo;0;L;;;;;N;;;;; +13A41;EGYPTIAN HIEROGLYPH-13A41;Lo;0;L;;;;;N;;;;; +13A42;EGYPTIAN HIEROGLYPH-13A42;Lo;0;L;;;;;N;;;;; +13A43;EGYPTIAN HIEROGLYPH-13A43;Lo;0;L;;;;;N;;;;; +13A44;EGYPTIAN HIEROGLYPH-13A44;Lo;0;L;;;;;N;;;;; +13A45;EGYPTIAN HIEROGLYPH-13A45;Lo;0;L;;;;;N;;;;; +13A46;EGYPTIAN HIEROGLYPH-13A46;Lo;0;L;;;;;N;;;;; +13A47;EGYPTIAN HIEROGLYPH-13A47;Lo;0;L;;;;;N;;;;; +13A48;EGYPTIAN HIEROGLYPH-13A48;Lo;0;L;;;;;N;;;;; +13A49;EGYPTIAN HIEROGLYPH-13A49;Lo;0;L;;;;;N;;;;; +13A4A;EGYPTIAN HIEROGLYPH-13A4A;Lo;0;L;;;;;N;;;;; +13A4B;EGYPTIAN HIEROGLYPH-13A4B;Lo;0;L;;;;;N;;;;; +13A4C;EGYPTIAN HIEROGLYPH-13A4C;Lo;0;L;;;;;N;;;;; +13A4D;EGYPTIAN HIEROGLYPH-13A4D;Lo;0;L;;;;;N;;;;; +13A4E;EGYPTIAN HIEROGLYPH-13A4E;Lo;0;L;;;;;N;;;;; +13A4F;EGYPTIAN HIEROGLYPH-13A4F;Lo;0;L;;;;;N;;;;; +13A50;EGYPTIAN HIEROGLYPH-13A50;Lo;0;L;;;;;N;;;;; +13A51;EGYPTIAN HIEROGLYPH-13A51;Lo;0;L;;;;;N;;;;; +13A52;EGYPTIAN HIEROGLYPH-13A52;Lo;0;L;;;;;N;;;;; +13A53;EGYPTIAN HIEROGLYPH-13A53;Lo;0;L;;;;;N;;;;; +13A54;EGYPTIAN HIEROGLYPH-13A54;Lo;0;L;;;;;N;;;;; +13A55;EGYPTIAN HIEROGLYPH-13A55;Lo;0;L;;;;;N;;;;; +13A56;EGYPTIAN HIEROGLYPH-13A56;Lo;0;L;;;;;N;;;;; +13A57;EGYPTIAN HIEROGLYPH-13A57;Lo;0;L;;;;;N;;;;; +13A58;EGYPTIAN HIEROGLYPH-13A58;Lo;0;L;;;;;N;;;;; +13A59;EGYPTIAN HIEROGLYPH-13A59;Lo;0;L;;;;;N;;;;; +13A5A;EGYPTIAN HIEROGLYPH-13A5A;Lo;0;L;;;;;N;;;;; +13A5B;EGYPTIAN HIEROGLYPH-13A5B;Lo;0;L;;;;;N;;;;; +13A5C;EGYPTIAN HIEROGLYPH-13A5C;Lo;0;L;;;;;N;;;;; +13A5D;EGYPTIAN HIEROGLYPH-13A5D;Lo;0;L;;;;;N;;;;; +13A5E;EGYPTIAN HIEROGLYPH-13A5E;Lo;0;L;;;;;N;;;;; +13A5F;EGYPTIAN HIEROGLYPH-13A5F;Lo;0;L;;;;;N;;;;; +13A60;EGYPTIAN HIEROGLYPH-13A60;Lo;0;L;;;;;N;;;;; +13A61;EGYPTIAN HIEROGLYPH-13A61;Lo;0;L;;;;;N;;;;; +13A62;EGYPTIAN HIEROGLYPH-13A62;Lo;0;L;;;;;N;;;;; +13A63;EGYPTIAN HIEROGLYPH-13A63;Lo;0;L;;;;;N;;;;; +13A64;EGYPTIAN HIEROGLYPH-13A64;Lo;0;L;;;;;N;;;;; +13A65;EGYPTIAN HIEROGLYPH-13A65;Lo;0;L;;;;;N;;;;; +13A66;EGYPTIAN HIEROGLYPH-13A66;Lo;0;L;;;;;N;;;;; +13A67;EGYPTIAN HIEROGLYPH-13A67;Lo;0;L;;;;;N;;;;; +13A68;EGYPTIAN HIEROGLYPH-13A68;Lo;0;L;;;;;N;;;;; +13A69;EGYPTIAN HIEROGLYPH-13A69;Lo;0;L;;;;;N;;;;; +13A6A;EGYPTIAN HIEROGLYPH-13A6A;Lo;0;L;;;;;N;;;;; +13A6B;EGYPTIAN HIEROGLYPH-13A6B;Lo;0;L;;;;;N;;;;; +13A6C;EGYPTIAN HIEROGLYPH-13A6C;Lo;0;L;;;;;N;;;;; +13A6D;EGYPTIAN HIEROGLYPH-13A6D;Lo;0;L;;;;;N;;;;; +13A6E;EGYPTIAN HIEROGLYPH-13A6E;Lo;0;L;;;;;N;;;;; +13A6F;EGYPTIAN HIEROGLYPH-13A6F;Lo;0;L;;;;;N;;;;; +13A70;EGYPTIAN HIEROGLYPH-13A70;Lo;0;L;;;;;N;;;;; +13A71;EGYPTIAN HIEROGLYPH-13A71;Lo;0;L;;;;;N;;;;; +13A72;EGYPTIAN HIEROGLYPH-13A72;Lo;0;L;;;;;N;;;;; +13A73;EGYPTIAN HIEROGLYPH-13A73;Lo;0;L;;;;;N;;;;; +13A74;EGYPTIAN HIEROGLYPH-13A74;Lo;0;L;;;;;N;;;;; +13A75;EGYPTIAN HIEROGLYPH-13A75;Lo;0;L;;;;;N;;;;; +13A76;EGYPTIAN HIEROGLYPH-13A76;Lo;0;L;;;;;N;;;;; +13A77;EGYPTIAN HIEROGLYPH-13A77;Lo;0;L;;;;;N;;;;; +13A78;EGYPTIAN HIEROGLYPH-13A78;Lo;0;L;;;;;N;;;;; +13A79;EGYPTIAN HIEROGLYPH-13A79;Lo;0;L;;;;;N;;;;; +13A7A;EGYPTIAN HIEROGLYPH-13A7A;Lo;0;L;;;;;N;;;;; +13A7B;EGYPTIAN HIEROGLYPH-13A7B;Lo;0;L;;;;;N;;;;; +13A7C;EGYPTIAN HIEROGLYPH-13A7C;Lo;0;L;;;;;N;;;;; +13A7D;EGYPTIAN HIEROGLYPH-13A7D;Lo;0;L;;;;;N;;;;; +13A7E;EGYPTIAN HIEROGLYPH-13A7E;Lo;0;L;;;;;N;;;;; +13A7F;EGYPTIAN HIEROGLYPH-13A7F;Lo;0;L;;;;;N;;;;; +13A80;EGYPTIAN HIEROGLYPH-13A80;Lo;0;L;;;;;N;;;;; +13A81;EGYPTIAN HIEROGLYPH-13A81;Lo;0;L;;;;;N;;;;; +13A82;EGYPTIAN HIEROGLYPH-13A82;Lo;0;L;;;;;N;;;;; +13A83;EGYPTIAN HIEROGLYPH-13A83;Lo;0;L;;;;;N;;;;; +13A84;EGYPTIAN HIEROGLYPH-13A84;Lo;0;L;;;;;N;;;;; +13A85;EGYPTIAN HIEROGLYPH-13A85;Lo;0;L;;;;;N;;;;; +13A86;EGYPTIAN HIEROGLYPH-13A86;Lo;0;L;;;;;N;;;;; +13A87;EGYPTIAN HIEROGLYPH-13A87;Lo;0;L;;;;;N;;;;; +13A88;EGYPTIAN HIEROGLYPH-13A88;Lo;0;L;;;;;N;;;;; +13A89;EGYPTIAN HIEROGLYPH-13A89;Lo;0;L;;;;;N;;;;; +13A8A;EGYPTIAN HIEROGLYPH-13A8A;Lo;0;L;;;;;N;;;;; +13A8B;EGYPTIAN HIEROGLYPH-13A8B;Lo;0;L;;;;;N;;;;; +13A8C;EGYPTIAN HIEROGLYPH-13A8C;Lo;0;L;;;;;N;;;;; +13A8D;EGYPTIAN HIEROGLYPH-13A8D;Lo;0;L;;;;;N;;;;; +13A8E;EGYPTIAN HIEROGLYPH-13A8E;Lo;0;L;;;;;N;;;;; +13A8F;EGYPTIAN HIEROGLYPH-13A8F;Lo;0;L;;;;;N;;;;; +13A90;EGYPTIAN HIEROGLYPH-13A90;Lo;0;L;;;;;N;;;;; +13A91;EGYPTIAN HIEROGLYPH-13A91;Lo;0;L;;;;;N;;;;; +13A92;EGYPTIAN HIEROGLYPH-13A92;Lo;0;L;;;;;N;;;;; +13A93;EGYPTIAN HIEROGLYPH-13A93;Lo;0;L;;;;;N;;;;; +13A94;EGYPTIAN HIEROGLYPH-13A94;Lo;0;L;;;;;N;;;;; +13A95;EGYPTIAN HIEROGLYPH-13A95;Lo;0;L;;;;;N;;;;; +13A96;EGYPTIAN HIEROGLYPH-13A96;Lo;0;L;;;;;N;;;;; +13A97;EGYPTIAN HIEROGLYPH-13A97;Lo;0;L;;;;;N;;;;; +13A98;EGYPTIAN HIEROGLYPH-13A98;Lo;0;L;;;;;N;;;;; +13A99;EGYPTIAN HIEROGLYPH-13A99;Lo;0;L;;;;;N;;;;; +13A9A;EGYPTIAN HIEROGLYPH-13A9A;Lo;0;L;;;;;N;;;;; +13A9B;EGYPTIAN HIEROGLYPH-13A9B;Lo;0;L;;;;;N;;;;; +13A9C;EGYPTIAN HIEROGLYPH-13A9C;Lo;0;L;;;;;N;;;;; +13A9D;EGYPTIAN HIEROGLYPH-13A9D;Lo;0;L;;;;;N;;;;; +13A9E;EGYPTIAN HIEROGLYPH-13A9E;Lo;0;L;;;;;N;;;;; +13A9F;EGYPTIAN HIEROGLYPH-13A9F;Lo;0;L;;;;;N;;;;; +13AA0;EGYPTIAN HIEROGLYPH-13AA0;Lo;0;L;;;;;N;;;;; +13AA1;EGYPTIAN HIEROGLYPH-13AA1;Lo;0;L;;;;;N;;;;; +13AA2;EGYPTIAN HIEROGLYPH-13AA2;Lo;0;L;;;;;N;;;;; +13AA3;EGYPTIAN HIEROGLYPH-13AA3;Lo;0;L;;;;;N;;;;; +13AA4;EGYPTIAN HIEROGLYPH-13AA4;Lo;0;L;;;;;N;;;;; +13AA5;EGYPTIAN HIEROGLYPH-13AA5;Lo;0;L;;;;;N;;;;; +13AA6;EGYPTIAN HIEROGLYPH-13AA6;Lo;0;L;;;;;N;;;;; +13AA7;EGYPTIAN HIEROGLYPH-13AA7;Lo;0;L;;;;;N;;;;; +13AA8;EGYPTIAN HIEROGLYPH-13AA8;Lo;0;L;;;;;N;;;;; +13AA9;EGYPTIAN HIEROGLYPH-13AA9;Lo;0;L;;;;;N;;;;; +13AAA;EGYPTIAN HIEROGLYPH-13AAA;Lo;0;L;;;;;N;;;;; +13AAB;EGYPTIAN HIEROGLYPH-13AAB;Lo;0;L;;;;;N;;;;; +13AAC;EGYPTIAN HIEROGLYPH-13AAC;Lo;0;L;;;;;N;;;;; +13AAD;EGYPTIAN HIEROGLYPH-13AAD;Lo;0;L;;;;;N;;;;; +13AAE;EGYPTIAN HIEROGLYPH-13AAE;Lo;0;L;;;;;N;;;;; +13AAF;EGYPTIAN HIEROGLYPH-13AAF;Lo;0;L;;;;;N;;;;; +13AB0;EGYPTIAN HIEROGLYPH-13AB0;Lo;0;L;;;;;N;;;;; +13AB1;EGYPTIAN HIEROGLYPH-13AB1;Lo;0;L;;;;;N;;;;; +13AB2;EGYPTIAN HIEROGLYPH-13AB2;Lo;0;L;;;;;N;;;;; +13AB3;EGYPTIAN HIEROGLYPH-13AB3;Lo;0;L;;;;;N;;;;; +13AB4;EGYPTIAN HIEROGLYPH-13AB4;Lo;0;L;;;;;N;;;;; +13AB5;EGYPTIAN HIEROGLYPH-13AB5;Lo;0;L;;;;;N;;;;; +13AB6;EGYPTIAN HIEROGLYPH-13AB6;Lo;0;L;;;;;N;;;;; +13AB7;EGYPTIAN HIEROGLYPH-13AB7;Lo;0;L;;;;;N;;;;; +13AB8;EGYPTIAN HIEROGLYPH-13AB8;Lo;0;L;;;;;N;;;;; +13AB9;EGYPTIAN HIEROGLYPH-13AB9;Lo;0;L;;;;;N;;;;; +13ABA;EGYPTIAN HIEROGLYPH-13ABA;Lo;0;L;;;;;N;;;;; +13ABB;EGYPTIAN HIEROGLYPH-13ABB;Lo;0;L;;;;;N;;;;; +13ABC;EGYPTIAN HIEROGLYPH-13ABC;Lo;0;L;;;;;N;;;;; +13ABD;EGYPTIAN HIEROGLYPH-13ABD;Lo;0;L;;;;;N;;;;; +13ABE;EGYPTIAN HIEROGLYPH-13ABE;Lo;0;L;;;;;N;;;;; +13ABF;EGYPTIAN HIEROGLYPH-13ABF;Lo;0;L;;;;;N;;;;; +13AC0;EGYPTIAN HIEROGLYPH-13AC0;Lo;0;L;;;;;N;;;;; +13AC1;EGYPTIAN HIEROGLYPH-13AC1;Lo;0;L;;;;;N;;;;; +13AC2;EGYPTIAN HIEROGLYPH-13AC2;Lo;0;L;;;;;N;;;;; +13AC3;EGYPTIAN HIEROGLYPH-13AC3;Lo;0;L;;;;;N;;;;; +13AC4;EGYPTIAN HIEROGLYPH-13AC4;Lo;0;L;;;;;N;;;;; +13AC5;EGYPTIAN HIEROGLYPH-13AC5;Lo;0;L;;;;;N;;;;; +13AC6;EGYPTIAN HIEROGLYPH-13AC6;Lo;0;L;;;;;N;;;;; +13AC7;EGYPTIAN HIEROGLYPH-13AC7;Lo;0;L;;;;;N;;;;; +13AC8;EGYPTIAN HIEROGLYPH-13AC8;Lo;0;L;;;;;N;;;;; +13AC9;EGYPTIAN HIEROGLYPH-13AC9;Lo;0;L;;;;;N;;;;; +13ACA;EGYPTIAN HIEROGLYPH-13ACA;Lo;0;L;;;;;N;;;;; +13ACB;EGYPTIAN HIEROGLYPH-13ACB;Lo;0;L;;;;;N;;;;; +13ACC;EGYPTIAN HIEROGLYPH-13ACC;Lo;0;L;;;;;N;;;;; +13ACD;EGYPTIAN HIEROGLYPH-13ACD;Lo;0;L;;;;;N;;;;; +13ACE;EGYPTIAN HIEROGLYPH-13ACE;Lo;0;L;;;;;N;;;;; +13ACF;EGYPTIAN HIEROGLYPH-13ACF;Lo;0;L;;;;;N;;;;; +13AD0;EGYPTIAN HIEROGLYPH-13AD0;Lo;0;L;;;;;N;;;;; +13AD1;EGYPTIAN HIEROGLYPH-13AD1;Lo;0;L;;;;;N;;;;; +13AD2;EGYPTIAN HIEROGLYPH-13AD2;Lo;0;L;;;;;N;;;;; +13AD3;EGYPTIAN HIEROGLYPH-13AD3;Lo;0;L;;;;;N;;;;; +13AD4;EGYPTIAN HIEROGLYPH-13AD4;Lo;0;L;;;;;N;;;;; +13AD5;EGYPTIAN HIEROGLYPH-13AD5;Lo;0;L;;;;;N;;;;; +13AD6;EGYPTIAN HIEROGLYPH-13AD6;Lo;0;L;;;;;N;;;;; +13AD7;EGYPTIAN HIEROGLYPH-13AD7;Lo;0;L;;;;;N;;;;; +13AD8;EGYPTIAN HIEROGLYPH-13AD8;Lo;0;L;;;;;N;;;;; +13AD9;EGYPTIAN HIEROGLYPH-13AD9;Lo;0;L;;;;;N;;;;; +13ADA;EGYPTIAN HIEROGLYPH-13ADA;Lo;0;L;;;;;N;;;;; +13ADB;EGYPTIAN HIEROGLYPH-13ADB;Lo;0;L;;;;;N;;;;; +13ADC;EGYPTIAN HIEROGLYPH-13ADC;Lo;0;L;;;;;N;;;;; +13ADD;EGYPTIAN HIEROGLYPH-13ADD;Lo;0;L;;;;;N;;;;; +13ADE;EGYPTIAN HIEROGLYPH-13ADE;Lo;0;L;;;;;N;;;;; +13ADF;EGYPTIAN HIEROGLYPH-13ADF;Lo;0;L;;;;;N;;;;; +13AE0;EGYPTIAN HIEROGLYPH-13AE0;Lo;0;L;;;;;N;;;;; +13AE1;EGYPTIAN HIEROGLYPH-13AE1;Lo;0;L;;;;;N;;;;; +13AE2;EGYPTIAN HIEROGLYPH-13AE2;Lo;0;L;;;;;N;;;;; +13AE3;EGYPTIAN HIEROGLYPH-13AE3;Lo;0;L;;;;;N;;;;; +13AE4;EGYPTIAN HIEROGLYPH-13AE4;Lo;0;L;;;;;N;;;;; +13AE5;EGYPTIAN HIEROGLYPH-13AE5;Lo;0;L;;;;;N;;;;; +13AE6;EGYPTIAN HIEROGLYPH-13AE6;Lo;0;L;;;;;N;;;;; +13AE7;EGYPTIAN HIEROGLYPH-13AE7;Lo;0;L;;;;;N;;;;; +13AE8;EGYPTIAN HIEROGLYPH-13AE8;Lo;0;L;;;;;N;;;;; +13AE9;EGYPTIAN HIEROGLYPH-13AE9;Lo;0;L;;;;;N;;;;; +13AEA;EGYPTIAN HIEROGLYPH-13AEA;Lo;0;L;;;;;N;;;;; +13AEB;EGYPTIAN HIEROGLYPH-13AEB;Lo;0;L;;;;;N;;;;; +13AEC;EGYPTIAN HIEROGLYPH-13AEC;Lo;0;L;;;;;N;;;;; +13AED;EGYPTIAN HIEROGLYPH-13AED;Lo;0;L;;;;;N;;;;; +13AEE;EGYPTIAN HIEROGLYPH-13AEE;Lo;0;L;;;;;N;;;;; +13AEF;EGYPTIAN HIEROGLYPH-13AEF;Lo;0;L;;;;;N;;;;; +13AF0;EGYPTIAN HIEROGLYPH-13AF0;Lo;0;L;;;;;N;;;;; +13AF1;EGYPTIAN HIEROGLYPH-13AF1;Lo;0;L;;;;;N;;;;; +13AF2;EGYPTIAN HIEROGLYPH-13AF2;Lo;0;L;;;;;N;;;;; +13AF3;EGYPTIAN HIEROGLYPH-13AF3;Lo;0;L;;;;;N;;;;; +13AF4;EGYPTIAN HIEROGLYPH-13AF4;Lo;0;L;;;;;N;;;;; +13AF5;EGYPTIAN HIEROGLYPH-13AF5;Lo;0;L;;;;;N;;;;; +13AF6;EGYPTIAN HIEROGLYPH-13AF6;Lo;0;L;;;;;N;;;;; +13AF7;EGYPTIAN HIEROGLYPH-13AF7;Lo;0;L;;;;;N;;;;; +13AF8;EGYPTIAN HIEROGLYPH-13AF8;Lo;0;L;;;;;N;;;;; +13AF9;EGYPTIAN HIEROGLYPH-13AF9;Lo;0;L;;;;;N;;;;; +13AFA;EGYPTIAN HIEROGLYPH-13AFA;Lo;0;L;;;;;N;;;;; +13AFB;EGYPTIAN HIEROGLYPH-13AFB;Lo;0;L;;;;;N;;;;; +13AFC;EGYPTIAN HIEROGLYPH-13AFC;Lo;0;L;;;;;N;;;;; +13AFD;EGYPTIAN HIEROGLYPH-13AFD;Lo;0;L;;;;;N;;;;; +13AFE;EGYPTIAN HIEROGLYPH-13AFE;Lo;0;L;;;;;N;;;;; +13AFF;EGYPTIAN HIEROGLYPH-13AFF;Lo;0;L;;;;;N;;;;; +13B00;EGYPTIAN HIEROGLYPH-13B00;Lo;0;L;;;;;N;;;;; +13B01;EGYPTIAN HIEROGLYPH-13B01;Lo;0;L;;;;;N;;;;; +13B02;EGYPTIAN HIEROGLYPH-13B02;Lo;0;L;;;;;N;;;;; +13B03;EGYPTIAN HIEROGLYPH-13B03;Lo;0;L;;;;;N;;;;; +13B04;EGYPTIAN HIEROGLYPH-13B04;Lo;0;L;;;;;N;;;;; +13B05;EGYPTIAN HIEROGLYPH-13B05;Lo;0;L;;;;;N;;;;; +13B06;EGYPTIAN HIEROGLYPH-13B06;Lo;0;L;;;;;N;;;;; +13B07;EGYPTIAN HIEROGLYPH-13B07;Lo;0;L;;;;;N;;;;; +13B08;EGYPTIAN HIEROGLYPH-13B08;Lo;0;L;;;;;N;;;;; +13B09;EGYPTIAN HIEROGLYPH-13B09;Lo;0;L;;;;;N;;;;; +13B0A;EGYPTIAN HIEROGLYPH-13B0A;Lo;0;L;;;;;N;;;;; +13B0B;EGYPTIAN HIEROGLYPH-13B0B;Lo;0;L;;;;;N;;;;; +13B0C;EGYPTIAN HIEROGLYPH-13B0C;Lo;0;L;;;;;N;;;;; +13B0D;EGYPTIAN HIEROGLYPH-13B0D;Lo;0;L;;;;;N;;;;; +13B0E;EGYPTIAN HIEROGLYPH-13B0E;Lo;0;L;;;;;N;;;;; +13B0F;EGYPTIAN HIEROGLYPH-13B0F;Lo;0;L;;;;;N;;;;; +13B10;EGYPTIAN HIEROGLYPH-13B10;Lo;0;L;;;;;N;;;;; +13B11;EGYPTIAN HIEROGLYPH-13B11;Lo;0;L;;;;;N;;;;; +13B12;EGYPTIAN HIEROGLYPH-13B12;Lo;0;L;;;;;N;;;;; +13B13;EGYPTIAN HIEROGLYPH-13B13;Lo;0;L;;;;;N;;;;; +13B14;EGYPTIAN HIEROGLYPH-13B14;Lo;0;L;;;;;N;;;;; +13B15;EGYPTIAN HIEROGLYPH-13B15;Lo;0;L;;;;;N;;;;; +13B16;EGYPTIAN HIEROGLYPH-13B16;Lo;0;L;;;;;N;;;;; +13B17;EGYPTIAN HIEROGLYPH-13B17;Lo;0;L;;;;;N;;;;; +13B18;EGYPTIAN HIEROGLYPH-13B18;Lo;0;L;;;;;N;;;;; +13B19;EGYPTIAN HIEROGLYPH-13B19;Lo;0;L;;;;;N;;;;; +13B1A;EGYPTIAN HIEROGLYPH-13B1A;Lo;0;L;;;;;N;;;;; +13B1B;EGYPTIAN HIEROGLYPH-13B1B;Lo;0;L;;;;;N;;;;; +13B1C;EGYPTIAN HIEROGLYPH-13B1C;Lo;0;L;;;;;N;;;;; +13B1D;EGYPTIAN HIEROGLYPH-13B1D;Lo;0;L;;;;;N;;;;; +13B1E;EGYPTIAN HIEROGLYPH-13B1E;Lo;0;L;;;;;N;;;;; +13B1F;EGYPTIAN HIEROGLYPH-13B1F;Lo;0;L;;;;;N;;;;; +13B20;EGYPTIAN HIEROGLYPH-13B20;Lo;0;L;;;;;N;;;;; +13B21;EGYPTIAN HIEROGLYPH-13B21;Lo;0;L;;;;;N;;;;; +13B22;EGYPTIAN HIEROGLYPH-13B22;Lo;0;L;;;;;N;;;;; +13B23;EGYPTIAN HIEROGLYPH-13B23;Lo;0;L;;;;;N;;;;; +13B24;EGYPTIAN HIEROGLYPH-13B24;Lo;0;L;;;;;N;;;;; +13B25;EGYPTIAN HIEROGLYPH-13B25;Lo;0;L;;;;;N;;;;; +13B26;EGYPTIAN HIEROGLYPH-13B26;Lo;0;L;;;;;N;;;;; +13B27;EGYPTIAN HIEROGLYPH-13B27;Lo;0;L;;;;;N;;;;; +13B28;EGYPTIAN HIEROGLYPH-13B28;Lo;0;L;;;;;N;;;;; +13B29;EGYPTIAN HIEROGLYPH-13B29;Lo;0;L;;;;;N;;;;; +13B2A;EGYPTIAN HIEROGLYPH-13B2A;Lo;0;L;;;;;N;;;;; +13B2B;EGYPTIAN HIEROGLYPH-13B2B;Lo;0;L;;;;;N;;;;; +13B2C;EGYPTIAN HIEROGLYPH-13B2C;Lo;0;L;;;;;N;;;;; +13B2D;EGYPTIAN HIEROGLYPH-13B2D;Lo;0;L;;;;;N;;;;; +13B2E;EGYPTIAN HIEROGLYPH-13B2E;Lo;0;L;;;;;N;;;;; +13B2F;EGYPTIAN HIEROGLYPH-13B2F;Lo;0;L;;;;;N;;;;; +13B30;EGYPTIAN HIEROGLYPH-13B30;Lo;0;L;;;;;N;;;;; +13B31;EGYPTIAN HIEROGLYPH-13B31;Lo;0;L;;;;;N;;;;; +13B32;EGYPTIAN HIEROGLYPH-13B32;Lo;0;L;;;;;N;;;;; +13B33;EGYPTIAN HIEROGLYPH-13B33;Lo;0;L;;;;;N;;;;; +13B34;EGYPTIAN HIEROGLYPH-13B34;Lo;0;L;;;;;N;;;;; +13B35;EGYPTIAN HIEROGLYPH-13B35;Lo;0;L;;;;;N;;;;; +13B36;EGYPTIAN HIEROGLYPH-13B36;Lo;0;L;;;;;N;;;;; +13B37;EGYPTIAN HIEROGLYPH-13B37;Lo;0;L;;;;;N;;;;; +13B38;EGYPTIAN HIEROGLYPH-13B38;Lo;0;L;;;;;N;;;;; +13B39;EGYPTIAN HIEROGLYPH-13B39;Lo;0;L;;;;;N;;;;; +13B3A;EGYPTIAN HIEROGLYPH-13B3A;Lo;0;L;;;;;N;;;;; +13B3B;EGYPTIAN HIEROGLYPH-13B3B;Lo;0;L;;;;;N;;;;; +13B3C;EGYPTIAN HIEROGLYPH-13B3C;Lo;0;L;;;;;N;;;;; +13B3D;EGYPTIAN HIEROGLYPH-13B3D;Lo;0;L;;;;;N;;;;; +13B3E;EGYPTIAN HIEROGLYPH-13B3E;Lo;0;L;;;;;N;;;;; +13B3F;EGYPTIAN HIEROGLYPH-13B3F;Lo;0;L;;;;;N;;;;; +13B40;EGYPTIAN HIEROGLYPH-13B40;Lo;0;L;;;;;N;;;;; +13B41;EGYPTIAN HIEROGLYPH-13B41;Lo;0;L;;;;;N;;;;; +13B42;EGYPTIAN HIEROGLYPH-13B42;Lo;0;L;;;;;N;;;;; +13B43;EGYPTIAN HIEROGLYPH-13B43;Lo;0;L;;;;;N;;;;; +13B44;EGYPTIAN HIEROGLYPH-13B44;Lo;0;L;;;;;N;;;;; +13B45;EGYPTIAN HIEROGLYPH-13B45;Lo;0;L;;;;;N;;;;; +13B46;EGYPTIAN HIEROGLYPH-13B46;Lo;0;L;;;;;N;;;;; +13B47;EGYPTIAN HIEROGLYPH-13B47;Lo;0;L;;;;;N;;;;; +13B48;EGYPTIAN HIEROGLYPH-13B48;Lo;0;L;;;;;N;;;;; +13B49;EGYPTIAN HIEROGLYPH-13B49;Lo;0;L;;;;;N;;;;; +13B4A;EGYPTIAN HIEROGLYPH-13B4A;Lo;0;L;;;;;N;;;;; +13B4B;EGYPTIAN HIEROGLYPH-13B4B;Lo;0;L;;;;;N;;;;; +13B4C;EGYPTIAN HIEROGLYPH-13B4C;Lo;0;L;;;;;N;;;;; +13B4D;EGYPTIAN HIEROGLYPH-13B4D;Lo;0;L;;;;;N;;;;; +13B4E;EGYPTIAN HIEROGLYPH-13B4E;Lo;0;L;;;;;N;;;;; +13B4F;EGYPTIAN HIEROGLYPH-13B4F;Lo;0;L;;;;;N;;;;; +13B50;EGYPTIAN HIEROGLYPH-13B50;Lo;0;L;;;;;N;;;;; +13B51;EGYPTIAN HIEROGLYPH-13B51;Lo;0;L;;;;;N;;;;; +13B52;EGYPTIAN HIEROGLYPH-13B52;Lo;0;L;;;;;N;;;;; +13B53;EGYPTIAN HIEROGLYPH-13B53;Lo;0;L;;;;;N;;;;; +13B54;EGYPTIAN HIEROGLYPH-13B54;Lo;0;L;;;;;N;;;;; +13B55;EGYPTIAN HIEROGLYPH-13B55;Lo;0;L;;;;;N;;;;; +13B56;EGYPTIAN HIEROGLYPH-13B56;Lo;0;L;;;;;N;;;;; +13B57;EGYPTIAN HIEROGLYPH-13B57;Lo;0;L;;;;;N;;;;; +13B58;EGYPTIAN HIEROGLYPH-13B58;Lo;0;L;;;;;N;;;;; +13B59;EGYPTIAN HIEROGLYPH-13B59;Lo;0;L;;;;;N;;;;; +13B5A;EGYPTIAN HIEROGLYPH-13B5A;Lo;0;L;;;;;N;;;;; +13B5B;EGYPTIAN HIEROGLYPH-13B5B;Lo;0;L;;;;;N;;;;; +13B5C;EGYPTIAN HIEROGLYPH-13B5C;Lo;0;L;;;;;N;;;;; +13B5D;EGYPTIAN HIEROGLYPH-13B5D;Lo;0;L;;;;;N;;;;; +13B5E;EGYPTIAN HIEROGLYPH-13B5E;Lo;0;L;;;;;N;;;;; +13B5F;EGYPTIAN HIEROGLYPH-13B5F;Lo;0;L;;;;;N;;;;; +13B60;EGYPTIAN HIEROGLYPH-13B60;Lo;0;L;;;;;N;;;;; +13B61;EGYPTIAN HIEROGLYPH-13B61;Lo;0;L;;;;;N;;;;; +13B62;EGYPTIAN HIEROGLYPH-13B62;Lo;0;L;;;;;N;;;;; +13B63;EGYPTIAN HIEROGLYPH-13B63;Lo;0;L;;;;;N;;;;; +13B64;EGYPTIAN HIEROGLYPH-13B64;Lo;0;L;;;;;N;;;;; +13B65;EGYPTIAN HIEROGLYPH-13B65;Lo;0;L;;;;;N;;;;; +13B66;EGYPTIAN HIEROGLYPH-13B66;Lo;0;L;;;;;N;;;;; +13B67;EGYPTIAN HIEROGLYPH-13B67;Lo;0;L;;;;;N;;;;; +13B68;EGYPTIAN HIEROGLYPH-13B68;Lo;0;L;;;;;N;;;;; +13B69;EGYPTIAN HIEROGLYPH-13B69;Lo;0;L;;;;;N;;;;; +13B6A;EGYPTIAN HIEROGLYPH-13B6A;Lo;0;L;;;;;N;;;;; +13B6B;EGYPTIAN HIEROGLYPH-13B6B;Lo;0;L;;;;;N;;;;; +13B6C;EGYPTIAN HIEROGLYPH-13B6C;Lo;0;L;;;;;N;;;;; +13B6D;EGYPTIAN HIEROGLYPH-13B6D;Lo;0;L;;;;;N;;;;; +13B6E;EGYPTIAN HIEROGLYPH-13B6E;Lo;0;L;;;;;N;;;;; +13B6F;EGYPTIAN HIEROGLYPH-13B6F;Lo;0;L;;;;;N;;;;; +13B70;EGYPTIAN HIEROGLYPH-13B70;Lo;0;L;;;;;N;;;;; +13B71;EGYPTIAN HIEROGLYPH-13B71;Lo;0;L;;;;;N;;;;; +13B72;EGYPTIAN HIEROGLYPH-13B72;Lo;0;L;;;;;N;;;;; +13B73;EGYPTIAN HIEROGLYPH-13B73;Lo;0;L;;;;;N;;;;; +13B74;EGYPTIAN HIEROGLYPH-13B74;Lo;0;L;;;;;N;;;;; +13B75;EGYPTIAN HIEROGLYPH-13B75;Lo;0;L;;;;;N;;;;; +13B76;EGYPTIAN HIEROGLYPH-13B76;Lo;0;L;;;;;N;;;;; +13B77;EGYPTIAN HIEROGLYPH-13B77;Lo;0;L;;;;;N;;;;; +13B78;EGYPTIAN HIEROGLYPH-13B78;Lo;0;L;;;;;N;;;;; +13B79;EGYPTIAN HIEROGLYPH-13B79;Lo;0;L;;;;;N;;;;; +13B7A;EGYPTIAN HIEROGLYPH-13B7A;Lo;0;L;;;;;N;;;;; +13B7B;EGYPTIAN HIEROGLYPH-13B7B;Lo;0;L;;;;;N;;;;; +13B7C;EGYPTIAN HIEROGLYPH-13B7C;Lo;0;L;;;;;N;;;;; +13B7D;EGYPTIAN HIEROGLYPH-13B7D;Lo;0;L;;;;;N;;;;; +13B7E;EGYPTIAN HIEROGLYPH-13B7E;Lo;0;L;;;;;N;;;;; +13B7F;EGYPTIAN HIEROGLYPH-13B7F;Lo;0;L;;;;;N;;;;; +13B80;EGYPTIAN HIEROGLYPH-13B80;Lo;0;L;;;;;N;;;;; +13B81;EGYPTIAN HIEROGLYPH-13B81;Lo;0;L;;;;;N;;;;; +13B82;EGYPTIAN HIEROGLYPH-13B82;Lo;0;L;;;;;N;;;;; +13B83;EGYPTIAN HIEROGLYPH-13B83;Lo;0;L;;;;;N;;;;; +13B84;EGYPTIAN HIEROGLYPH-13B84;Lo;0;L;;;;;N;;;;; +13B85;EGYPTIAN HIEROGLYPH-13B85;Lo;0;L;;;;;N;;;;; +13B86;EGYPTIAN HIEROGLYPH-13B86;Lo;0;L;;;;;N;;;;; +13B87;EGYPTIAN HIEROGLYPH-13B87;Lo;0;L;;;;;N;;;;; +13B88;EGYPTIAN HIEROGLYPH-13B88;Lo;0;L;;;;;N;;;;; +13B89;EGYPTIAN HIEROGLYPH-13B89;Lo;0;L;;;;;N;;;;; +13B8A;EGYPTIAN HIEROGLYPH-13B8A;Lo;0;L;;;;;N;;;;; +13B8B;EGYPTIAN HIEROGLYPH-13B8B;Lo;0;L;;;;;N;;;;; +13B8C;EGYPTIAN HIEROGLYPH-13B8C;Lo;0;L;;;;;N;;;;; +13B8D;EGYPTIAN HIEROGLYPH-13B8D;Lo;0;L;;;;;N;;;;; +13B8E;EGYPTIAN HIEROGLYPH-13B8E;Lo;0;L;;;;;N;;;;; +13B8F;EGYPTIAN HIEROGLYPH-13B8F;Lo;0;L;;;;;N;;;;; +13B90;EGYPTIAN HIEROGLYPH-13B90;Lo;0;L;;;;;N;;;;; +13B91;EGYPTIAN HIEROGLYPH-13B91;Lo;0;L;;;;;N;;;;; +13B92;EGYPTIAN HIEROGLYPH-13B92;Lo;0;L;;;;;N;;;;; +13B93;EGYPTIAN HIEROGLYPH-13B93;Lo;0;L;;;;;N;;;;; +13B94;EGYPTIAN HIEROGLYPH-13B94;Lo;0;L;;;;;N;;;;; +13B95;EGYPTIAN HIEROGLYPH-13B95;Lo;0;L;;;;;N;;;;; +13B96;EGYPTIAN HIEROGLYPH-13B96;Lo;0;L;;;;;N;;;;; +13B97;EGYPTIAN HIEROGLYPH-13B97;Lo;0;L;;;;;N;;;;; +13B98;EGYPTIAN HIEROGLYPH-13B98;Lo;0;L;;;;;N;;;;; +13B99;EGYPTIAN HIEROGLYPH-13B99;Lo;0;L;;;;;N;;;;; +13B9A;EGYPTIAN HIEROGLYPH-13B9A;Lo;0;L;;;;;N;;;;; +13B9B;EGYPTIAN HIEROGLYPH-13B9B;Lo;0;L;;;;;N;;;;; +13B9C;EGYPTIAN HIEROGLYPH-13B9C;Lo;0;L;;;;;N;;;;; +13B9D;EGYPTIAN HIEROGLYPH-13B9D;Lo;0;L;;;;;N;;;;; +13B9E;EGYPTIAN HIEROGLYPH-13B9E;Lo;0;L;;;;;N;;;;; +13B9F;EGYPTIAN HIEROGLYPH-13B9F;Lo;0;L;;;;;N;;;;; +13BA0;EGYPTIAN HIEROGLYPH-13BA0;Lo;0;L;;;;;N;;;;; +13BA1;EGYPTIAN HIEROGLYPH-13BA1;Lo;0;L;;;;;N;;;;; +13BA2;EGYPTIAN HIEROGLYPH-13BA2;Lo;0;L;;;;;N;;;;; +13BA3;EGYPTIAN HIEROGLYPH-13BA3;Lo;0;L;;;;;N;;;;; +13BA4;EGYPTIAN HIEROGLYPH-13BA4;Lo;0;L;;;;;N;;;;; +13BA5;EGYPTIAN HIEROGLYPH-13BA5;Lo;0;L;;;;;N;;;;; +13BA6;EGYPTIAN HIEROGLYPH-13BA6;Lo;0;L;;;;;N;;;;; +13BA7;EGYPTIAN HIEROGLYPH-13BA7;Lo;0;L;;;;;N;;;;; +13BA8;EGYPTIAN HIEROGLYPH-13BA8;Lo;0;L;;;;;N;;;;; +13BA9;EGYPTIAN HIEROGLYPH-13BA9;Lo;0;L;;;;;N;;;;; +13BAA;EGYPTIAN HIEROGLYPH-13BAA;Lo;0;L;;;;;N;;;;; +13BAB;EGYPTIAN HIEROGLYPH-13BAB;Lo;0;L;;;;;N;;;;; +13BAC;EGYPTIAN HIEROGLYPH-13BAC;Lo;0;L;;;;;N;;;;; +13BAD;EGYPTIAN HIEROGLYPH-13BAD;Lo;0;L;;;;;N;;;;; +13BAE;EGYPTIAN HIEROGLYPH-13BAE;Lo;0;L;;;;;N;;;;; +13BAF;EGYPTIAN HIEROGLYPH-13BAF;Lo;0;L;;;;;N;;;;; +13BB0;EGYPTIAN HIEROGLYPH-13BB0;Lo;0;L;;;;;N;;;;; +13BB1;EGYPTIAN HIEROGLYPH-13BB1;Lo;0;L;;;;;N;;;;; +13BB2;EGYPTIAN HIEROGLYPH-13BB2;Lo;0;L;;;;;N;;;;; +13BB3;EGYPTIAN HIEROGLYPH-13BB3;Lo;0;L;;;;;N;;;;; +13BB4;EGYPTIAN HIEROGLYPH-13BB4;Lo;0;L;;;;;N;;;;; +13BB5;EGYPTIAN HIEROGLYPH-13BB5;Lo;0;L;;;;;N;;;;; +13BB6;EGYPTIAN HIEROGLYPH-13BB6;Lo;0;L;;;;;N;;;;; +13BB7;EGYPTIAN HIEROGLYPH-13BB7;Lo;0;L;;;;;N;;;;; +13BB8;EGYPTIAN HIEROGLYPH-13BB8;Lo;0;L;;;;;N;;;;; +13BB9;EGYPTIAN HIEROGLYPH-13BB9;Lo;0;L;;;;;N;;;;; +13BBA;EGYPTIAN HIEROGLYPH-13BBA;Lo;0;L;;;;;N;;;;; +13BBB;EGYPTIAN HIEROGLYPH-13BBB;Lo;0;L;;;;;N;;;;; +13BBC;EGYPTIAN HIEROGLYPH-13BBC;Lo;0;L;;;;;N;;;;; +13BBD;EGYPTIAN HIEROGLYPH-13BBD;Lo;0;L;;;;;N;;;;; +13BBE;EGYPTIAN HIEROGLYPH-13BBE;Lo;0;L;;;;;N;;;;; +13BBF;EGYPTIAN HIEROGLYPH-13BBF;Lo;0;L;;;;;N;;;;; +13BC0;EGYPTIAN HIEROGLYPH-13BC0;Lo;0;L;;;;;N;;;;; +13BC1;EGYPTIAN HIEROGLYPH-13BC1;Lo;0;L;;;;;N;;;;; +13BC2;EGYPTIAN HIEROGLYPH-13BC2;Lo;0;L;;;;;N;;;;; +13BC3;EGYPTIAN HIEROGLYPH-13BC3;Lo;0;L;;;;;N;;;;; +13BC4;EGYPTIAN HIEROGLYPH-13BC4;Lo;0;L;;;;;N;;;;; +13BC5;EGYPTIAN HIEROGLYPH-13BC5;Lo;0;L;;;;;N;;;;; +13BC6;EGYPTIAN HIEROGLYPH-13BC6;Lo;0;L;;;;;N;;;;; +13BC7;EGYPTIAN HIEROGLYPH-13BC7;Lo;0;L;;;;;N;;;;; +13BC8;EGYPTIAN HIEROGLYPH-13BC8;Lo;0;L;;;;;N;;;;; +13BC9;EGYPTIAN HIEROGLYPH-13BC9;Lo;0;L;;;;;N;;;;; +13BCA;EGYPTIAN HIEROGLYPH-13BCA;Lo;0;L;;;;;N;;;;; +13BCB;EGYPTIAN HIEROGLYPH-13BCB;Lo;0;L;;;;;N;;;;; +13BCC;EGYPTIAN HIEROGLYPH-13BCC;Lo;0;L;;;;;N;;;;; +13BCD;EGYPTIAN HIEROGLYPH-13BCD;Lo;0;L;;;;;N;;;;; +13BCE;EGYPTIAN HIEROGLYPH-13BCE;Lo;0;L;;;;;N;;;;; +13BCF;EGYPTIAN HIEROGLYPH-13BCF;Lo;0;L;;;;;N;;;;; +13BD0;EGYPTIAN HIEROGLYPH-13BD0;Lo;0;L;;;;;N;;;;; +13BD1;EGYPTIAN HIEROGLYPH-13BD1;Lo;0;L;;;;;N;;;;; +13BD2;EGYPTIAN HIEROGLYPH-13BD2;Lo;0;L;;;;;N;;;;; +13BD3;EGYPTIAN HIEROGLYPH-13BD3;Lo;0;L;;;;;N;;;;; +13BD4;EGYPTIAN HIEROGLYPH-13BD4;Lo;0;L;;;;;N;;;;; +13BD5;EGYPTIAN HIEROGLYPH-13BD5;Lo;0;L;;;;;N;;;;; +13BD6;EGYPTIAN HIEROGLYPH-13BD6;Lo;0;L;;;;;N;;;;; +13BD7;EGYPTIAN HIEROGLYPH-13BD7;Lo;0;L;;;;;N;;;;; +13BD8;EGYPTIAN HIEROGLYPH-13BD8;Lo;0;L;;;;;N;;;;; +13BD9;EGYPTIAN HIEROGLYPH-13BD9;Lo;0;L;;;;;N;;;;; +13BDA;EGYPTIAN HIEROGLYPH-13BDA;Lo;0;L;;;;;N;;;;; +13BDB;EGYPTIAN HIEROGLYPH-13BDB;Lo;0;L;;;;;N;;;;; +13BDC;EGYPTIAN HIEROGLYPH-13BDC;Lo;0;L;;;;;N;;;;; +13BDD;EGYPTIAN HIEROGLYPH-13BDD;Lo;0;L;;;;;N;;;;; +13BDE;EGYPTIAN HIEROGLYPH-13BDE;Lo;0;L;;;;;N;;;;; +13BDF;EGYPTIAN HIEROGLYPH-13BDF;Lo;0;L;;;;;N;;;;; +13BE0;EGYPTIAN HIEROGLYPH-13BE0;Lo;0;L;;;;;N;;;;; +13BE1;EGYPTIAN HIEROGLYPH-13BE1;Lo;0;L;;;;;N;;;;; +13BE2;EGYPTIAN HIEROGLYPH-13BE2;Lo;0;L;;;;;N;;;;; +13BE3;EGYPTIAN HIEROGLYPH-13BE3;Lo;0;L;;;;;N;;;;; +13BE4;EGYPTIAN HIEROGLYPH-13BE4;Lo;0;L;;;;;N;;;;; +13BE5;EGYPTIAN HIEROGLYPH-13BE5;Lo;0;L;;;;;N;;;;; +13BE6;EGYPTIAN HIEROGLYPH-13BE6;Lo;0;L;;;;;N;;;;; +13BE7;EGYPTIAN HIEROGLYPH-13BE7;Lo;0;L;;;;;N;;;;; +13BE8;EGYPTIAN HIEROGLYPH-13BE8;Lo;0;L;;;;;N;;;;; +13BE9;EGYPTIAN HIEROGLYPH-13BE9;Lo;0;L;;;;;N;;;;; +13BEA;EGYPTIAN HIEROGLYPH-13BEA;Lo;0;L;;;;;N;;;;; +13BEB;EGYPTIAN HIEROGLYPH-13BEB;Lo;0;L;;;;;N;;;;; +13BEC;EGYPTIAN HIEROGLYPH-13BEC;Lo;0;L;;;;;N;;;;; +13BED;EGYPTIAN HIEROGLYPH-13BED;Lo;0;L;;;;;N;;;;; +13BEE;EGYPTIAN HIEROGLYPH-13BEE;Lo;0;L;;;;;N;;;;; +13BEF;EGYPTIAN HIEROGLYPH-13BEF;Lo;0;L;;;;;N;;;;; +13BF0;EGYPTIAN HIEROGLYPH-13BF0;Lo;0;L;;;;;N;;;;; +13BF1;EGYPTIAN HIEROGLYPH-13BF1;Lo;0;L;;;;;N;;;;; +13BF2;EGYPTIAN HIEROGLYPH-13BF2;Lo;0;L;;;;;N;;;;; +13BF3;EGYPTIAN HIEROGLYPH-13BF3;Lo;0;L;;;;;N;;;;; +13BF4;EGYPTIAN HIEROGLYPH-13BF4;Lo;0;L;;;;;N;;;;; +13BF5;EGYPTIAN HIEROGLYPH-13BF5;Lo;0;L;;;;;N;;;;; +13BF6;EGYPTIAN HIEROGLYPH-13BF6;Lo;0;L;;;;;N;;;;; +13BF7;EGYPTIAN HIEROGLYPH-13BF7;Lo;0;L;;;;;N;;;;; +13BF8;EGYPTIAN HIEROGLYPH-13BF8;Lo;0;L;;;;;N;;;;; +13BF9;EGYPTIAN HIEROGLYPH-13BF9;Lo;0;L;;;;;N;;;;; +13BFA;EGYPTIAN HIEROGLYPH-13BFA;Lo;0;L;;;;;N;;;;; +13BFB;EGYPTIAN HIEROGLYPH-13BFB;Lo;0;L;;;;;N;;;;; +13BFC;EGYPTIAN HIEROGLYPH-13BFC;Lo;0;L;;;;;N;;;;; +13BFD;EGYPTIAN HIEROGLYPH-13BFD;Lo;0;L;;;;;N;;;;; +13BFE;EGYPTIAN HIEROGLYPH-13BFE;Lo;0;L;;;;;N;;;;; +13BFF;EGYPTIAN HIEROGLYPH-13BFF;Lo;0;L;;;;;N;;;;; +13C00;EGYPTIAN HIEROGLYPH-13C00;Lo;0;L;;;;;N;;;;; +13C01;EGYPTIAN HIEROGLYPH-13C01;Lo;0;L;;;;;N;;;;; +13C02;EGYPTIAN HIEROGLYPH-13C02;Lo;0;L;;;;;N;;;;; +13C03;EGYPTIAN HIEROGLYPH-13C03;Lo;0;L;;;;;N;;;;; +13C04;EGYPTIAN HIEROGLYPH-13C04;Lo;0;L;;;;;N;;;;; +13C05;EGYPTIAN HIEROGLYPH-13C05;Lo;0;L;;;;;N;;;;; +13C06;EGYPTIAN HIEROGLYPH-13C06;Lo;0;L;;;;;N;;;;; +13C07;EGYPTIAN HIEROGLYPH-13C07;Lo;0;L;;;;;N;;;;; +13C08;EGYPTIAN HIEROGLYPH-13C08;Lo;0;L;;;;;N;;;;; +13C09;EGYPTIAN HIEROGLYPH-13C09;Lo;0;L;;;;;N;;;;; +13C0A;EGYPTIAN HIEROGLYPH-13C0A;Lo;0;L;;;;;N;;;;; +13C0B;EGYPTIAN HIEROGLYPH-13C0B;Lo;0;L;;;;;N;;;;; +13C0C;EGYPTIAN HIEROGLYPH-13C0C;Lo;0;L;;;;;N;;;;; +13C0D;EGYPTIAN HIEROGLYPH-13C0D;Lo;0;L;;;;;N;;;;; +13C0E;EGYPTIAN HIEROGLYPH-13C0E;Lo;0;L;;;;;N;;;;; +13C0F;EGYPTIAN HIEROGLYPH-13C0F;Lo;0;L;;;;;N;;;;; +13C10;EGYPTIAN HIEROGLYPH-13C10;Lo;0;L;;;;;N;;;;; +13C11;EGYPTIAN HIEROGLYPH-13C11;Lo;0;L;;;;;N;;;;; +13C12;EGYPTIAN HIEROGLYPH-13C12;Lo;0;L;;;;;N;;;;; +13C13;EGYPTIAN HIEROGLYPH-13C13;Lo;0;L;;;;;N;;;;; +13C14;EGYPTIAN HIEROGLYPH-13C14;Lo;0;L;;;;;N;;;;; +13C15;EGYPTIAN HIEROGLYPH-13C15;Lo;0;L;;;;;N;;;;; +13C16;EGYPTIAN HIEROGLYPH-13C16;Lo;0;L;;;;;N;;;;; +13C17;EGYPTIAN HIEROGLYPH-13C17;Lo;0;L;;;;;N;;;;; +13C18;EGYPTIAN HIEROGLYPH-13C18;Lo;0;L;;;;;N;;;;; +13C19;EGYPTIAN HIEROGLYPH-13C19;Lo;0;L;;;;;N;;;;; +13C1A;EGYPTIAN HIEROGLYPH-13C1A;Lo;0;L;;;;;N;;;;; +13C1B;EGYPTIAN HIEROGLYPH-13C1B;Lo;0;L;;;;;N;;;;; +13C1C;EGYPTIAN HIEROGLYPH-13C1C;Lo;0;L;;;;;N;;;;; +13C1D;EGYPTIAN HIEROGLYPH-13C1D;Lo;0;L;;;;;N;;;;; +13C1E;EGYPTIAN HIEROGLYPH-13C1E;Lo;0;L;;;;;N;;;;; +13C1F;EGYPTIAN HIEROGLYPH-13C1F;Lo;0;L;;;;;N;;;;; +13C20;EGYPTIAN HIEROGLYPH-13C20;Lo;0;L;;;;;N;;;;; +13C21;EGYPTIAN HIEROGLYPH-13C21;Lo;0;L;;;;;N;;;;; +13C22;EGYPTIAN HIEROGLYPH-13C22;Lo;0;L;;;;;N;;;;; +13C23;EGYPTIAN HIEROGLYPH-13C23;Lo;0;L;;;;;N;;;;; +13C24;EGYPTIAN HIEROGLYPH-13C24;Lo;0;L;;;;;N;;;;; +13C25;EGYPTIAN HIEROGLYPH-13C25;Lo;0;L;;;;;N;;;;; +13C26;EGYPTIAN HIEROGLYPH-13C26;Lo;0;L;;;;;N;;;;; +13C27;EGYPTIAN HIEROGLYPH-13C27;Lo;0;L;;;;;N;;;;; +13C28;EGYPTIAN HIEROGLYPH-13C28;Lo;0;L;;;;;N;;;;; +13C29;EGYPTIAN HIEROGLYPH-13C29;Lo;0;L;;;;;N;;;;; +13C2A;EGYPTIAN HIEROGLYPH-13C2A;Lo;0;L;;;;;N;;;;; +13C2B;EGYPTIAN HIEROGLYPH-13C2B;Lo;0;L;;;;;N;;;;; +13C2C;EGYPTIAN HIEROGLYPH-13C2C;Lo;0;L;;;;;N;;;;; +13C2D;EGYPTIAN HIEROGLYPH-13C2D;Lo;0;L;;;;;N;;;;; +13C2E;EGYPTIAN HIEROGLYPH-13C2E;Lo;0;L;;;;;N;;;;; +13C2F;EGYPTIAN HIEROGLYPH-13C2F;Lo;0;L;;;;;N;;;;; +13C30;EGYPTIAN HIEROGLYPH-13C30;Lo;0;L;;;;;N;;;;; +13C31;EGYPTIAN HIEROGLYPH-13C31;Lo;0;L;;;;;N;;;;; +13C32;EGYPTIAN HIEROGLYPH-13C32;Lo;0;L;;;;;N;;;;; +13C33;EGYPTIAN HIEROGLYPH-13C33;Lo;0;L;;;;;N;;;;; +13C34;EGYPTIAN HIEROGLYPH-13C34;Lo;0;L;;;;;N;;;;; +13C35;EGYPTIAN HIEROGLYPH-13C35;Lo;0;L;;;;;N;;;;; +13C36;EGYPTIAN HIEROGLYPH-13C36;Lo;0;L;;;;;N;;;;; +13C37;EGYPTIAN HIEROGLYPH-13C37;Lo;0;L;;;;;N;;;;; +13C38;EGYPTIAN HIEROGLYPH-13C38;Lo;0;L;;;;;N;;;;; +13C39;EGYPTIAN HIEROGLYPH-13C39;Lo;0;L;;;;;N;;;;; +13C3A;EGYPTIAN HIEROGLYPH-13C3A;Lo;0;L;;;;;N;;;;; +13C3B;EGYPTIAN HIEROGLYPH-13C3B;Lo;0;L;;;;;N;;;;; +13C3C;EGYPTIAN HIEROGLYPH-13C3C;Lo;0;L;;;;;N;;;;; +13C3D;EGYPTIAN HIEROGLYPH-13C3D;Lo;0;L;;;;;N;;;;; +13C3E;EGYPTIAN HIEROGLYPH-13C3E;Lo;0;L;;;;;N;;;;; +13C3F;EGYPTIAN HIEROGLYPH-13C3F;Lo;0;L;;;;;N;;;;; +13C40;EGYPTIAN HIEROGLYPH-13C40;Lo;0;L;;;;;N;;;;; +13C41;EGYPTIAN HIEROGLYPH-13C41;Lo;0;L;;;;;N;;;;; +13C42;EGYPTIAN HIEROGLYPH-13C42;Lo;0;L;;;;;N;;;;; +13C43;EGYPTIAN HIEROGLYPH-13C43;Lo;0;L;;;;;N;;;;; +13C44;EGYPTIAN HIEROGLYPH-13C44;Lo;0;L;;;;;N;;;;; +13C45;EGYPTIAN HIEROGLYPH-13C45;Lo;0;L;;;;;N;;;;; +13C46;EGYPTIAN HIEROGLYPH-13C46;Lo;0;L;;;;;N;;;;; +13C47;EGYPTIAN HIEROGLYPH-13C47;Lo;0;L;;;;;N;;;;; +13C48;EGYPTIAN HIEROGLYPH-13C48;Lo;0;L;;;;;N;;;;; +13C49;EGYPTIAN HIEROGLYPH-13C49;Lo;0;L;;;;;N;;;;; +13C4A;EGYPTIAN HIEROGLYPH-13C4A;Lo;0;L;;;;;N;;;;; +13C4B;EGYPTIAN HIEROGLYPH-13C4B;Lo;0;L;;;;;N;;;;; +13C4C;EGYPTIAN HIEROGLYPH-13C4C;Lo;0;L;;;;;N;;;;; +13C4D;EGYPTIAN HIEROGLYPH-13C4D;Lo;0;L;;;;;N;;;;; +13C4E;EGYPTIAN HIEROGLYPH-13C4E;Lo;0;L;;;;;N;;;;; +13C4F;EGYPTIAN HIEROGLYPH-13C4F;Lo;0;L;;;;;N;;;;; +13C50;EGYPTIAN HIEROGLYPH-13C50;Lo;0;L;;;;;N;;;;; +13C51;EGYPTIAN HIEROGLYPH-13C51;Lo;0;L;;;;;N;;;;; +13C52;EGYPTIAN HIEROGLYPH-13C52;Lo;0;L;;;;;N;;;;; +13C53;EGYPTIAN HIEROGLYPH-13C53;Lo;0;L;;;;;N;;;;; +13C54;EGYPTIAN HIEROGLYPH-13C54;Lo;0;L;;;;;N;;;;; +13C55;EGYPTIAN HIEROGLYPH-13C55;Lo;0;L;;;;;N;;;;; +13C56;EGYPTIAN HIEROGLYPH-13C56;Lo;0;L;;;;;N;;;;; +13C57;EGYPTIAN HIEROGLYPH-13C57;Lo;0;L;;;;;N;;;;; +13C58;EGYPTIAN HIEROGLYPH-13C58;Lo;0;L;;;;;N;;;;; +13C59;EGYPTIAN HIEROGLYPH-13C59;Lo;0;L;;;;;N;;;;; +13C5A;EGYPTIAN HIEROGLYPH-13C5A;Lo;0;L;;;;;N;;;;; +13C5B;EGYPTIAN HIEROGLYPH-13C5B;Lo;0;L;;;;;N;;;;; +13C5C;EGYPTIAN HIEROGLYPH-13C5C;Lo;0;L;;;;;N;;;;; +13C5D;EGYPTIAN HIEROGLYPH-13C5D;Lo;0;L;;;;;N;;;;; +13C5E;EGYPTIAN HIEROGLYPH-13C5E;Lo;0;L;;;;;N;;;;; +13C5F;EGYPTIAN HIEROGLYPH-13C5F;Lo;0;L;;;;;N;;;;; +13C60;EGYPTIAN HIEROGLYPH-13C60;Lo;0;L;;;;;N;;;;; +13C61;EGYPTIAN HIEROGLYPH-13C61;Lo;0;L;;;;;N;;;;; +13C62;EGYPTIAN HIEROGLYPH-13C62;Lo;0;L;;;;;N;;;;; +13C63;EGYPTIAN HIEROGLYPH-13C63;Lo;0;L;;;;;N;;;;; +13C64;EGYPTIAN HIEROGLYPH-13C64;Lo;0;L;;;;;N;;;;; +13C65;EGYPTIAN HIEROGLYPH-13C65;Lo;0;L;;;;;N;;;;; +13C66;EGYPTIAN HIEROGLYPH-13C66;Lo;0;L;;;;;N;;;;; +13C67;EGYPTIAN HIEROGLYPH-13C67;Lo;0;L;;;;;N;;;;; +13C68;EGYPTIAN HIEROGLYPH-13C68;Lo;0;L;;;;;N;;;;; +13C69;EGYPTIAN HIEROGLYPH-13C69;Lo;0;L;;;;;N;;;;; +13C6A;EGYPTIAN HIEROGLYPH-13C6A;Lo;0;L;;;;;N;;;;; +13C6B;EGYPTIAN HIEROGLYPH-13C6B;Lo;0;L;;;;;N;;;;; +13C6C;EGYPTIAN HIEROGLYPH-13C6C;Lo;0;L;;;;;N;;;;; +13C6D;EGYPTIAN HIEROGLYPH-13C6D;Lo;0;L;;;;;N;;;;; +13C6E;EGYPTIAN HIEROGLYPH-13C6E;Lo;0;L;;;;;N;;;;; +13C6F;EGYPTIAN HIEROGLYPH-13C6F;Lo;0;L;;;;;N;;;;; +13C70;EGYPTIAN HIEROGLYPH-13C70;Lo;0;L;;;;;N;;;;; +13C71;EGYPTIAN HIEROGLYPH-13C71;Lo;0;L;;;;;N;;;;; +13C72;EGYPTIAN HIEROGLYPH-13C72;Lo;0;L;;;;;N;;;;; +13C73;EGYPTIAN HIEROGLYPH-13C73;Lo;0;L;;;;;N;;;;; +13C74;EGYPTIAN HIEROGLYPH-13C74;Lo;0;L;;;;;N;;;;; +13C75;EGYPTIAN HIEROGLYPH-13C75;Lo;0;L;;;;;N;;;;; +13C76;EGYPTIAN HIEROGLYPH-13C76;Lo;0;L;;;;;N;;;;; +13C77;EGYPTIAN HIEROGLYPH-13C77;Lo;0;L;;;;;N;;;;; +13C78;EGYPTIAN HIEROGLYPH-13C78;Lo;0;L;;;;;N;;;;; +13C79;EGYPTIAN HIEROGLYPH-13C79;Lo;0;L;;;;;N;;;;; +13C7A;EGYPTIAN HIEROGLYPH-13C7A;Lo;0;L;;;;;N;;;;; +13C7B;EGYPTIAN HIEROGLYPH-13C7B;Lo;0;L;;;;;N;;;;; +13C7C;EGYPTIAN HIEROGLYPH-13C7C;Lo;0;L;;;;;N;;;;; +13C7D;EGYPTIAN HIEROGLYPH-13C7D;Lo;0;L;;;;;N;;;;; +13C7E;EGYPTIAN HIEROGLYPH-13C7E;Lo;0;L;;;;;N;;;;; +13C7F;EGYPTIAN HIEROGLYPH-13C7F;Lo;0;L;;;;;N;;;;; +13C80;EGYPTIAN HIEROGLYPH-13C80;Lo;0;L;;;;;N;;;;; +13C81;EGYPTIAN HIEROGLYPH-13C81;Lo;0;L;;;;;N;;;;; +13C82;EGYPTIAN HIEROGLYPH-13C82;Lo;0;L;;;;;N;;;;; +13C83;EGYPTIAN HIEROGLYPH-13C83;Lo;0;L;;;;;N;;;;; +13C84;EGYPTIAN HIEROGLYPH-13C84;Lo;0;L;;;;;N;;;;; +13C85;EGYPTIAN HIEROGLYPH-13C85;Lo;0;L;;;;;N;;;;; +13C86;EGYPTIAN HIEROGLYPH-13C86;Lo;0;L;;;;;N;;;;; +13C87;EGYPTIAN HIEROGLYPH-13C87;Lo;0;L;;;;;N;;;;; +13C88;EGYPTIAN HIEROGLYPH-13C88;Lo;0;L;;;;;N;;;;; +13C89;EGYPTIAN HIEROGLYPH-13C89;Lo;0;L;;;;;N;;;;; +13C8A;EGYPTIAN HIEROGLYPH-13C8A;Lo;0;L;;;;;N;;;;; +13C8B;EGYPTIAN HIEROGLYPH-13C8B;Lo;0;L;;;;;N;;;;; +13C8C;EGYPTIAN HIEROGLYPH-13C8C;Lo;0;L;;;;;N;;;;; +13C8D;EGYPTIAN HIEROGLYPH-13C8D;Lo;0;L;;;;;N;;;;; +13C8E;EGYPTIAN HIEROGLYPH-13C8E;Lo;0;L;;;;;N;;;;; +13C8F;EGYPTIAN HIEROGLYPH-13C8F;Lo;0;L;;;;;N;;;;; +13C90;EGYPTIAN HIEROGLYPH-13C90;Lo;0;L;;;;;N;;;;; +13C91;EGYPTIAN HIEROGLYPH-13C91;Lo;0;L;;;;;N;;;;; +13C92;EGYPTIAN HIEROGLYPH-13C92;Lo;0;L;;;;;N;;;;; +13C93;EGYPTIAN HIEROGLYPH-13C93;Lo;0;L;;;;;N;;;;; +13C94;EGYPTIAN HIEROGLYPH-13C94;Lo;0;L;;;;;N;;;;; +13C95;EGYPTIAN HIEROGLYPH-13C95;Lo;0;L;;;;;N;;;;; +13C96;EGYPTIAN HIEROGLYPH-13C96;Lo;0;L;;;;;N;;;;; +13C97;EGYPTIAN HIEROGLYPH-13C97;Lo;0;L;;;;;N;;;;; +13C98;EGYPTIAN HIEROGLYPH-13C98;Lo;0;L;;;;;N;;;;; +13C99;EGYPTIAN HIEROGLYPH-13C99;Lo;0;L;;;;;N;;;;; +13C9A;EGYPTIAN HIEROGLYPH-13C9A;Lo;0;L;;;;;N;;;;; +13C9B;EGYPTIAN HIEROGLYPH-13C9B;Lo;0;L;;;;;N;;;;; +13C9C;EGYPTIAN HIEROGLYPH-13C9C;Lo;0;L;;;;;N;;;;; +13C9D;EGYPTIAN HIEROGLYPH-13C9D;Lo;0;L;;;;;N;;;;; +13C9E;EGYPTIAN HIEROGLYPH-13C9E;Lo;0;L;;;;;N;;;;; +13C9F;EGYPTIAN HIEROGLYPH-13C9F;Lo;0;L;;;;;N;;;;; +13CA0;EGYPTIAN HIEROGLYPH-13CA0;Lo;0;L;;;;;N;;;;; +13CA1;EGYPTIAN HIEROGLYPH-13CA1;Lo;0;L;;;;;N;;;;; +13CA2;EGYPTIAN HIEROGLYPH-13CA2;Lo;0;L;;;;;N;;;;; +13CA3;EGYPTIAN HIEROGLYPH-13CA3;Lo;0;L;;;;;N;;;;; +13CA4;EGYPTIAN HIEROGLYPH-13CA4;Lo;0;L;;;;;N;;;;; +13CA5;EGYPTIAN HIEROGLYPH-13CA5;Lo;0;L;;;;;N;;;;; +13CA6;EGYPTIAN HIEROGLYPH-13CA6;Lo;0;L;;;;;N;;;;; +13CA7;EGYPTIAN HIEROGLYPH-13CA7;Lo;0;L;;;;;N;;;;; +13CA8;EGYPTIAN HIEROGLYPH-13CA8;Lo;0;L;;;;;N;;;;; +13CA9;EGYPTIAN HIEROGLYPH-13CA9;Lo;0;L;;;;;N;;;;; +13CAA;EGYPTIAN HIEROGLYPH-13CAA;Lo;0;L;;;;;N;;;;; +13CAB;EGYPTIAN HIEROGLYPH-13CAB;Lo;0;L;;;;;N;;;;; +13CAC;EGYPTIAN HIEROGLYPH-13CAC;Lo;0;L;;;;;N;;;;; +13CAD;EGYPTIAN HIEROGLYPH-13CAD;Lo;0;L;;;;;N;;;;; +13CAE;EGYPTIAN HIEROGLYPH-13CAE;Lo;0;L;;;;;N;;;;; +13CAF;EGYPTIAN HIEROGLYPH-13CAF;Lo;0;L;;;;;N;;;;; +13CB0;EGYPTIAN HIEROGLYPH-13CB0;Lo;0;L;;;;;N;;;;; +13CB1;EGYPTIAN HIEROGLYPH-13CB1;Lo;0;L;;;;;N;;;;; +13CB2;EGYPTIAN HIEROGLYPH-13CB2;Lo;0;L;;;;;N;;;;; +13CB3;EGYPTIAN HIEROGLYPH-13CB3;Lo;0;L;;;;;N;;;;; +13CB4;EGYPTIAN HIEROGLYPH-13CB4;Lo;0;L;;;;;N;;;;; +13CB5;EGYPTIAN HIEROGLYPH-13CB5;Lo;0;L;;;;;N;;;;; +13CB6;EGYPTIAN HIEROGLYPH-13CB6;Lo;0;L;;;;;N;;;;; +13CB7;EGYPTIAN HIEROGLYPH-13CB7;Lo;0;L;;;;;N;;;;; +13CB8;EGYPTIAN HIEROGLYPH-13CB8;Lo;0;L;;;;;N;;;;; +13CB9;EGYPTIAN HIEROGLYPH-13CB9;Lo;0;L;;;;;N;;;;; +13CBA;EGYPTIAN HIEROGLYPH-13CBA;Lo;0;L;;;;;N;;;;; +13CBB;EGYPTIAN HIEROGLYPH-13CBB;Lo;0;L;;;;;N;;;;; +13CBC;EGYPTIAN HIEROGLYPH-13CBC;Lo;0;L;;;;;N;;;;; +13CBD;EGYPTIAN HIEROGLYPH-13CBD;Lo;0;L;;;;;N;;;;; +13CBE;EGYPTIAN HIEROGLYPH-13CBE;Lo;0;L;;;;;N;;;;; +13CBF;EGYPTIAN HIEROGLYPH-13CBF;Lo;0;L;;;;;N;;;;; +13CC0;EGYPTIAN HIEROGLYPH-13CC0;Lo;0;L;;;;;N;;;;; +13CC1;EGYPTIAN HIEROGLYPH-13CC1;Lo;0;L;;;;;N;;;;; +13CC2;EGYPTIAN HIEROGLYPH-13CC2;Lo;0;L;;;;;N;;;;; +13CC3;EGYPTIAN HIEROGLYPH-13CC3;Lo;0;L;;;;;N;;;;; +13CC4;EGYPTIAN HIEROGLYPH-13CC4;Lo;0;L;;;;;N;;;;; +13CC5;EGYPTIAN HIEROGLYPH-13CC5;Lo;0;L;;;;;N;;;;; +13CC6;EGYPTIAN HIEROGLYPH-13CC6;Lo;0;L;;;;;N;;;;; +13CC7;EGYPTIAN HIEROGLYPH-13CC7;Lo;0;L;;;;;N;;;;; +13CC8;EGYPTIAN HIEROGLYPH-13CC8;Lo;0;L;;;;;N;;;;; +13CC9;EGYPTIAN HIEROGLYPH-13CC9;Lo;0;L;;;;;N;;;;; +13CCA;EGYPTIAN HIEROGLYPH-13CCA;Lo;0;L;;;;;N;;;;; +13CCB;EGYPTIAN HIEROGLYPH-13CCB;Lo;0;L;;;;;N;;;;; +13CCC;EGYPTIAN HIEROGLYPH-13CCC;Lo;0;L;;;;;N;;;;; +13CCD;EGYPTIAN HIEROGLYPH-13CCD;Lo;0;L;;;;;N;;;;; +13CCE;EGYPTIAN HIEROGLYPH-13CCE;Lo;0;L;;;;;N;;;;; +13CCF;EGYPTIAN HIEROGLYPH-13CCF;Lo;0;L;;;;;N;;;;; +13CD0;EGYPTIAN HIEROGLYPH-13CD0;Lo;0;L;;;;;N;;;;; +13CD1;EGYPTIAN HIEROGLYPH-13CD1;Lo;0;L;;;;;N;;;;; +13CD2;EGYPTIAN HIEROGLYPH-13CD2;Lo;0;L;;;;;N;;;;; +13CD3;EGYPTIAN HIEROGLYPH-13CD3;Lo;0;L;;;;;N;;;;; +13CD4;EGYPTIAN HIEROGLYPH-13CD4;Lo;0;L;;;;;N;;;;; +13CD5;EGYPTIAN HIEROGLYPH-13CD5;Lo;0;L;;;;;N;;;;; +13CD6;EGYPTIAN HIEROGLYPH-13CD6;Lo;0;L;;;;;N;;;;; +13CD7;EGYPTIAN HIEROGLYPH-13CD7;Lo;0;L;;;;;N;;;;; +13CD8;EGYPTIAN HIEROGLYPH-13CD8;Lo;0;L;;;;;N;;;;; +13CD9;EGYPTIAN HIEROGLYPH-13CD9;Lo;0;L;;;;;N;;;;; +13CDA;EGYPTIAN HIEROGLYPH-13CDA;Lo;0;L;;;;;N;;;;; +13CDB;EGYPTIAN HIEROGLYPH-13CDB;Lo;0;L;;;;;N;;;;; +13CDC;EGYPTIAN HIEROGLYPH-13CDC;Lo;0;L;;;;;N;;;;; +13CDD;EGYPTIAN HIEROGLYPH-13CDD;Lo;0;L;;;;;N;;;;; +13CDE;EGYPTIAN HIEROGLYPH-13CDE;Lo;0;L;;;;;N;;;;; +13CDF;EGYPTIAN HIEROGLYPH-13CDF;Lo;0;L;;;;;N;;;;; +13CE0;EGYPTIAN HIEROGLYPH-13CE0;Lo;0;L;;;;;N;;;;; +13CE1;EGYPTIAN HIEROGLYPH-13CE1;Lo;0;L;;;;;N;;;;; +13CE2;EGYPTIAN HIEROGLYPH-13CE2;Lo;0;L;;;;;N;;;;; +13CE3;EGYPTIAN HIEROGLYPH-13CE3;Lo;0;L;;;;;N;;;;; +13CE4;EGYPTIAN HIEROGLYPH-13CE4;Lo;0;L;;;;;N;;;;; +13CE5;EGYPTIAN HIEROGLYPH-13CE5;Lo;0;L;;;;;N;;;;; +13CE6;EGYPTIAN HIEROGLYPH-13CE6;Lo;0;L;;;;;N;;;;; +13CE7;EGYPTIAN HIEROGLYPH-13CE7;Lo;0;L;;;;;N;;;;; +13CE8;EGYPTIAN HIEROGLYPH-13CE8;Lo;0;L;;;;;N;;;;; +13CE9;EGYPTIAN HIEROGLYPH-13CE9;Lo;0;L;;;;;N;;;;; +13CEA;EGYPTIAN HIEROGLYPH-13CEA;Lo;0;L;;;;;N;;;;; +13CEB;EGYPTIAN HIEROGLYPH-13CEB;Lo;0;L;;;;;N;;;;; +13CEC;EGYPTIAN HIEROGLYPH-13CEC;Lo;0;L;;;;;N;;;;; +13CED;EGYPTIAN HIEROGLYPH-13CED;Lo;0;L;;;;;N;;;;; +13CEE;EGYPTIAN HIEROGLYPH-13CEE;Lo;0;L;;;;;N;;;;; +13CEF;EGYPTIAN HIEROGLYPH-13CEF;Lo;0;L;;;;;N;;;;; +13CF0;EGYPTIAN HIEROGLYPH-13CF0;Lo;0;L;;;;;N;;;;; +13CF1;EGYPTIAN HIEROGLYPH-13CF1;Lo;0;L;;;;;N;;;;; +13CF2;EGYPTIAN HIEROGLYPH-13CF2;Lo;0;L;;;;;N;;;;; +13CF3;EGYPTIAN HIEROGLYPH-13CF3;Lo;0;L;;;;;N;;;;; +13CF4;EGYPTIAN HIEROGLYPH-13CF4;Lo;0;L;;;;;N;;;;; +13CF5;EGYPTIAN HIEROGLYPH-13CF5;Lo;0;L;;;;;N;;;;; +13CF6;EGYPTIAN HIEROGLYPH-13CF6;Lo;0;L;;;;;N;;;;; +13CF7;EGYPTIAN HIEROGLYPH-13CF7;Lo;0;L;;;;;N;;;;; +13CF8;EGYPTIAN HIEROGLYPH-13CF8;Lo;0;L;;;;;N;;;;; +13CF9;EGYPTIAN HIEROGLYPH-13CF9;Lo;0;L;;;;;N;;;;; +13CFA;EGYPTIAN HIEROGLYPH-13CFA;Lo;0;L;;;;;N;;;;; +13CFB;EGYPTIAN HIEROGLYPH-13CFB;Lo;0;L;;;;;N;;;;; +13CFC;EGYPTIAN HIEROGLYPH-13CFC;Lo;0;L;;;;;N;;;;; +13CFD;EGYPTIAN HIEROGLYPH-13CFD;Lo;0;L;;;;;N;;;;; +13CFE;EGYPTIAN HIEROGLYPH-13CFE;Lo;0;L;;;;;N;;;;; +13CFF;EGYPTIAN HIEROGLYPH-13CFF;Lo;0;L;;;;;N;;;;; +13D00;EGYPTIAN HIEROGLYPH-13D00;Lo;0;L;;;;;N;;;;; +13D01;EGYPTIAN HIEROGLYPH-13D01;Lo;0;L;;;;;N;;;;; +13D02;EGYPTIAN HIEROGLYPH-13D02;Lo;0;L;;;;;N;;;;; +13D03;EGYPTIAN HIEROGLYPH-13D03;Lo;0;L;;;;;N;;;;; +13D04;EGYPTIAN HIEROGLYPH-13D04;Lo;0;L;;;;;N;;;;; +13D05;EGYPTIAN HIEROGLYPH-13D05;Lo;0;L;;;;;N;;;;; +13D06;EGYPTIAN HIEROGLYPH-13D06;Lo;0;L;;;;;N;;;;; +13D07;EGYPTIAN HIEROGLYPH-13D07;Lo;0;L;;;;;N;;;;; +13D08;EGYPTIAN HIEROGLYPH-13D08;Lo;0;L;;;;;N;;;;; +13D09;EGYPTIAN HIEROGLYPH-13D09;Lo;0;L;;;;;N;;;;; +13D0A;EGYPTIAN HIEROGLYPH-13D0A;Lo;0;L;;;;;N;;;;; +13D0B;EGYPTIAN HIEROGLYPH-13D0B;Lo;0;L;;;;;N;;;;; +13D0C;EGYPTIAN HIEROGLYPH-13D0C;Lo;0;L;;;;;N;;;;; +13D0D;EGYPTIAN HIEROGLYPH-13D0D;Lo;0;L;;;;;N;;;;; +13D0E;EGYPTIAN HIEROGLYPH-13D0E;Lo;0;L;;;;;N;;;;; +13D0F;EGYPTIAN HIEROGLYPH-13D0F;Lo;0;L;;;;;N;;;;; +13D10;EGYPTIAN HIEROGLYPH-13D10;Lo;0;L;;;;;N;;;;; +13D11;EGYPTIAN HIEROGLYPH-13D11;Lo;0;L;;;;;N;;;;; +13D12;EGYPTIAN HIEROGLYPH-13D12;Lo;0;L;;;;;N;;;;; +13D13;EGYPTIAN HIEROGLYPH-13D13;Lo;0;L;;;;;N;;;;; +13D14;EGYPTIAN HIEROGLYPH-13D14;Lo;0;L;;;;;N;;;;; +13D15;EGYPTIAN HIEROGLYPH-13D15;Lo;0;L;;;;;N;;;;; +13D16;EGYPTIAN HIEROGLYPH-13D16;Lo;0;L;;;;;N;;;;; +13D17;EGYPTIAN HIEROGLYPH-13D17;Lo;0;L;;;;;N;;;;; +13D18;EGYPTIAN HIEROGLYPH-13D18;Lo;0;L;;;;;N;;;;; +13D19;EGYPTIAN HIEROGLYPH-13D19;Lo;0;L;;;;;N;;;;; +13D1A;EGYPTIAN HIEROGLYPH-13D1A;Lo;0;L;;;;;N;;;;; +13D1B;EGYPTIAN HIEROGLYPH-13D1B;Lo;0;L;;;;;N;;;;; +13D1C;EGYPTIAN HIEROGLYPH-13D1C;Lo;0;L;;;;;N;;;;; +13D1D;EGYPTIAN HIEROGLYPH-13D1D;Lo;0;L;;;;;N;;;;; +13D1E;EGYPTIAN HIEROGLYPH-13D1E;Lo;0;L;;;;;N;;;;; +13D1F;EGYPTIAN HIEROGLYPH-13D1F;Lo;0;L;;;;;N;;;;; +13D20;EGYPTIAN HIEROGLYPH-13D20;Lo;0;L;;;;;N;;;;; +13D21;EGYPTIAN HIEROGLYPH-13D21;Lo;0;L;;;;;N;;;;; +13D22;EGYPTIAN HIEROGLYPH-13D22;Lo;0;L;;;;;N;;;;; +13D23;EGYPTIAN HIEROGLYPH-13D23;Lo;0;L;;;;;N;;;;; +13D24;EGYPTIAN HIEROGLYPH-13D24;Lo;0;L;;;;;N;;;;; +13D25;EGYPTIAN HIEROGLYPH-13D25;Lo;0;L;;;;;N;;;;; +13D26;EGYPTIAN HIEROGLYPH-13D26;Lo;0;L;;;;;N;;;;; +13D27;EGYPTIAN HIEROGLYPH-13D27;Lo;0;L;;;;;N;;;;; +13D28;EGYPTIAN HIEROGLYPH-13D28;Lo;0;L;;;;;N;;;;; +13D29;EGYPTIAN HIEROGLYPH-13D29;Lo;0;L;;;;;N;;;;; +13D2A;EGYPTIAN HIEROGLYPH-13D2A;Lo;0;L;;;;;N;;;;; +13D2B;EGYPTIAN HIEROGLYPH-13D2B;Lo;0;L;;;;;N;;;;; +13D2C;EGYPTIAN HIEROGLYPH-13D2C;Lo;0;L;;;;;N;;;;; +13D2D;EGYPTIAN HIEROGLYPH-13D2D;Lo;0;L;;;;;N;;;;; +13D2E;EGYPTIAN HIEROGLYPH-13D2E;Lo;0;L;;;;;N;;;;; +13D2F;EGYPTIAN HIEROGLYPH-13D2F;Lo;0;L;;;;;N;;;;; +13D30;EGYPTIAN HIEROGLYPH-13D30;Lo;0;L;;;;;N;;;;; +13D31;EGYPTIAN HIEROGLYPH-13D31;Lo;0;L;;;;;N;;;;; +13D32;EGYPTIAN HIEROGLYPH-13D32;Lo;0;L;;;;;N;;;;; +13D33;EGYPTIAN HIEROGLYPH-13D33;Lo;0;L;;;;;N;;;;; +13D34;EGYPTIAN HIEROGLYPH-13D34;Lo;0;L;;;;;N;;;;; +13D35;EGYPTIAN HIEROGLYPH-13D35;Lo;0;L;;;;;N;;;;; +13D36;EGYPTIAN HIEROGLYPH-13D36;Lo;0;L;;;;;N;;;;; +13D37;EGYPTIAN HIEROGLYPH-13D37;Lo;0;L;;;;;N;;;;; +13D38;EGYPTIAN HIEROGLYPH-13D38;Lo;0;L;;;;;N;;;;; +13D39;EGYPTIAN HIEROGLYPH-13D39;Lo;0;L;;;;;N;;;;; +13D3A;EGYPTIAN HIEROGLYPH-13D3A;Lo;0;L;;;;;N;;;;; +13D3B;EGYPTIAN HIEROGLYPH-13D3B;Lo;0;L;;;;;N;;;;; +13D3C;EGYPTIAN HIEROGLYPH-13D3C;Lo;0;L;;;;;N;;;;; +13D3D;EGYPTIAN HIEROGLYPH-13D3D;Lo;0;L;;;;;N;;;;; +13D3E;EGYPTIAN HIEROGLYPH-13D3E;Lo;0;L;;;;;N;;;;; +13D3F;EGYPTIAN HIEROGLYPH-13D3F;Lo;0;L;;;;;N;;;;; +13D40;EGYPTIAN HIEROGLYPH-13D40;Lo;0;L;;;;;N;;;;; +13D41;EGYPTIAN HIEROGLYPH-13D41;Lo;0;L;;;;;N;;;;; +13D42;EGYPTIAN HIEROGLYPH-13D42;Lo;0;L;;;;;N;;;;; +13D43;EGYPTIAN HIEROGLYPH-13D43;Lo;0;L;;;;;N;;;;; +13D44;EGYPTIAN HIEROGLYPH-13D44;Lo;0;L;;;;;N;;;;; +13D45;EGYPTIAN HIEROGLYPH-13D45;Lo;0;L;;;;;N;;;;; +13D46;EGYPTIAN HIEROGLYPH-13D46;Lo;0;L;;;;;N;;;;; +13D47;EGYPTIAN HIEROGLYPH-13D47;Lo;0;L;;;;;N;;;;; +13D48;EGYPTIAN HIEROGLYPH-13D48;Lo;0;L;;;;;N;;;;; +13D49;EGYPTIAN HIEROGLYPH-13D49;Lo;0;L;;;;;N;;;;; +13D4A;EGYPTIAN HIEROGLYPH-13D4A;Lo;0;L;;;;;N;;;;; +13D4B;EGYPTIAN HIEROGLYPH-13D4B;Lo;0;L;;;;;N;;;;; +13D4C;EGYPTIAN HIEROGLYPH-13D4C;Lo;0;L;;;;;N;;;;; +13D4D;EGYPTIAN HIEROGLYPH-13D4D;Lo;0;L;;;;;N;;;;; +13D4E;EGYPTIAN HIEROGLYPH-13D4E;Lo;0;L;;;;;N;;;;; +13D4F;EGYPTIAN HIEROGLYPH-13D4F;Lo;0;L;;;;;N;;;;; +13D50;EGYPTIAN HIEROGLYPH-13D50;Lo;0;L;;;;;N;;;;; +13D51;EGYPTIAN HIEROGLYPH-13D51;Lo;0;L;;;;;N;;;;; +13D52;EGYPTIAN HIEROGLYPH-13D52;Lo;0;L;;;;;N;;;;; +13D53;EGYPTIAN HIEROGLYPH-13D53;Lo;0;L;;;;;N;;;;; +13D54;EGYPTIAN HIEROGLYPH-13D54;Lo;0;L;;;;;N;;;;; +13D55;EGYPTIAN HIEROGLYPH-13D55;Lo;0;L;;;;;N;;;;; +13D56;EGYPTIAN HIEROGLYPH-13D56;Lo;0;L;;;;;N;;;;; +13D57;EGYPTIAN HIEROGLYPH-13D57;Lo;0;L;;;;;N;;;;; +13D58;EGYPTIAN HIEROGLYPH-13D58;Lo;0;L;;;;;N;;;;; +13D59;EGYPTIAN HIEROGLYPH-13D59;Lo;0;L;;;;;N;;;;; +13D5A;EGYPTIAN HIEROGLYPH-13D5A;Lo;0;L;;;;;N;;;;; +13D5B;EGYPTIAN HIEROGLYPH-13D5B;Lo;0;L;;;;;N;;;;; +13D5C;EGYPTIAN HIEROGLYPH-13D5C;Lo;0;L;;;;;N;;;;; +13D5D;EGYPTIAN HIEROGLYPH-13D5D;Lo;0;L;;;;;N;;;;; +13D5E;EGYPTIAN HIEROGLYPH-13D5E;Lo;0;L;;;;;N;;;;; +13D5F;EGYPTIAN HIEROGLYPH-13D5F;Lo;0;L;;;;;N;;;;; +13D60;EGYPTIAN HIEROGLYPH-13D60;Lo;0;L;;;;;N;;;;; +13D61;EGYPTIAN HIEROGLYPH-13D61;Lo;0;L;;;;;N;;;;; +13D62;EGYPTIAN HIEROGLYPH-13D62;Lo;0;L;;;;;N;;;;; +13D63;EGYPTIAN HIEROGLYPH-13D63;Lo;0;L;;;;;N;;;;; +13D64;EGYPTIAN HIEROGLYPH-13D64;Lo;0;L;;;;;N;;;;; +13D65;EGYPTIAN HIEROGLYPH-13D65;Lo;0;L;;;;;N;;;;; +13D66;EGYPTIAN HIEROGLYPH-13D66;Lo;0;L;;;;;N;;;;; +13D67;EGYPTIAN HIEROGLYPH-13D67;Lo;0;L;;;;;N;;;;; +13D68;EGYPTIAN HIEROGLYPH-13D68;Lo;0;L;;;;;N;;;;; +13D69;EGYPTIAN HIEROGLYPH-13D69;Lo;0;L;;;;;N;;;;; +13D6A;EGYPTIAN HIEROGLYPH-13D6A;Lo;0;L;;;;;N;;;;; +13D6B;EGYPTIAN HIEROGLYPH-13D6B;Lo;0;L;;;;;N;;;;; +13D6C;EGYPTIAN HIEROGLYPH-13D6C;Lo;0;L;;;;;N;;;;; +13D6D;EGYPTIAN HIEROGLYPH-13D6D;Lo;0;L;;;;;N;;;;; +13D6E;EGYPTIAN HIEROGLYPH-13D6E;Lo;0;L;;;;;N;;;;; +13D6F;EGYPTIAN HIEROGLYPH-13D6F;Lo;0;L;;;;;N;;;;; +13D70;EGYPTIAN HIEROGLYPH-13D70;Lo;0;L;;;;;N;;;;; +13D71;EGYPTIAN HIEROGLYPH-13D71;Lo;0;L;;;;;N;;;;; +13D72;EGYPTIAN HIEROGLYPH-13D72;Lo;0;L;;;;;N;;;;; +13D73;EGYPTIAN HIEROGLYPH-13D73;Lo;0;L;;;;;N;;;;; +13D74;EGYPTIAN HIEROGLYPH-13D74;Lo;0;L;;;;;N;;;;; +13D75;EGYPTIAN HIEROGLYPH-13D75;Lo;0;L;;;;;N;;;;; +13D76;EGYPTIAN HIEROGLYPH-13D76;Lo;0;L;;;;;N;;;;; +13D77;EGYPTIAN HIEROGLYPH-13D77;Lo;0;L;;;;;N;;;;; +13D78;EGYPTIAN HIEROGLYPH-13D78;Lo;0;L;;;;;N;;;;; +13D79;EGYPTIAN HIEROGLYPH-13D79;Lo;0;L;;;;;N;;;;; +13D7A;EGYPTIAN HIEROGLYPH-13D7A;Lo;0;L;;;;;N;;;;; +13D7B;EGYPTIAN HIEROGLYPH-13D7B;Lo;0;L;;;;;N;;;;; +13D7C;EGYPTIAN HIEROGLYPH-13D7C;Lo;0;L;;;;;N;;;;; +13D7D;EGYPTIAN HIEROGLYPH-13D7D;Lo;0;L;;;;;N;;;;; +13D7E;EGYPTIAN HIEROGLYPH-13D7E;Lo;0;L;;;;;N;;;;; +13D7F;EGYPTIAN HIEROGLYPH-13D7F;Lo;0;L;;;;;N;;;;; +13D80;EGYPTIAN HIEROGLYPH-13D80;Lo;0;L;;;;;N;;;;; +13D81;EGYPTIAN HIEROGLYPH-13D81;Lo;0;L;;;;;N;;;;; +13D82;EGYPTIAN HIEROGLYPH-13D82;Lo;0;L;;;;;N;;;;; +13D83;EGYPTIAN HIEROGLYPH-13D83;Lo;0;L;;;;;N;;;;; +13D84;EGYPTIAN HIEROGLYPH-13D84;Lo;0;L;;;;;N;;;;; +13D85;EGYPTIAN HIEROGLYPH-13D85;Lo;0;L;;;;;N;;;;; +13D86;EGYPTIAN HIEROGLYPH-13D86;Lo;0;L;;;;;N;;;;; +13D87;EGYPTIAN HIEROGLYPH-13D87;Lo;0;L;;;;;N;;;;; +13D88;EGYPTIAN HIEROGLYPH-13D88;Lo;0;L;;;;;N;;;;; +13D89;EGYPTIAN HIEROGLYPH-13D89;Lo;0;L;;;;;N;;;;; +13D8A;EGYPTIAN HIEROGLYPH-13D8A;Lo;0;L;;;;;N;;;;; +13D8B;EGYPTIAN HIEROGLYPH-13D8B;Lo;0;L;;;;;N;;;;; +13D8C;EGYPTIAN HIEROGLYPH-13D8C;Lo;0;L;;;;;N;;;;; +13D8D;EGYPTIAN HIEROGLYPH-13D8D;Lo;0;L;;;;;N;;;;; +13D8E;EGYPTIAN HIEROGLYPH-13D8E;Lo;0;L;;;;;N;;;;; +13D8F;EGYPTIAN HIEROGLYPH-13D8F;Lo;0;L;;;;;N;;;;; +13D90;EGYPTIAN HIEROGLYPH-13D90;Lo;0;L;;;;;N;;;;; +13D91;EGYPTIAN HIEROGLYPH-13D91;Lo;0;L;;;;;N;;;;; +13D92;EGYPTIAN HIEROGLYPH-13D92;Lo;0;L;;;;;N;;;;; +13D93;EGYPTIAN HIEROGLYPH-13D93;Lo;0;L;;;;;N;;;;; +13D94;EGYPTIAN HIEROGLYPH-13D94;Lo;0;L;;;;;N;;;;; +13D95;EGYPTIAN HIEROGLYPH-13D95;Lo;0;L;;;;;N;;;;; +13D96;EGYPTIAN HIEROGLYPH-13D96;Lo;0;L;;;;;N;;;;; +13D97;EGYPTIAN HIEROGLYPH-13D97;Lo;0;L;;;;;N;;;;; +13D98;EGYPTIAN HIEROGLYPH-13D98;Lo;0;L;;;;;N;;;;; +13D99;EGYPTIAN HIEROGLYPH-13D99;Lo;0;L;;;;;N;;;;; +13D9A;EGYPTIAN HIEROGLYPH-13D9A;Lo;0;L;;;;;N;;;;; +13D9B;EGYPTIAN HIEROGLYPH-13D9B;Lo;0;L;;;;;N;;;;; +13D9C;EGYPTIAN HIEROGLYPH-13D9C;Lo;0;L;;;;;N;;;;; +13D9D;EGYPTIAN HIEROGLYPH-13D9D;Lo;0;L;;;;;N;;;;; +13D9E;EGYPTIAN HIEROGLYPH-13D9E;Lo;0;L;;;;;N;;;;; +13D9F;EGYPTIAN HIEROGLYPH-13D9F;Lo;0;L;;;;;N;;;;; +13DA0;EGYPTIAN HIEROGLYPH-13DA0;Lo;0;L;;;;;N;;;;; +13DA1;EGYPTIAN HIEROGLYPH-13DA1;Lo;0;L;;;;;N;;;;; +13DA2;EGYPTIAN HIEROGLYPH-13DA2;Lo;0;L;;;;;N;;;;; +13DA3;EGYPTIAN HIEROGLYPH-13DA3;Lo;0;L;;;;;N;;;;; +13DA4;EGYPTIAN HIEROGLYPH-13DA4;Lo;0;L;;;;;N;;;;; +13DA5;EGYPTIAN HIEROGLYPH-13DA5;Lo;0;L;;;;;N;;;;; +13DA6;EGYPTIAN HIEROGLYPH-13DA6;Lo;0;L;;;;;N;;;;; +13DA7;EGYPTIAN HIEROGLYPH-13DA7;Lo;0;L;;;;;N;;;;; +13DA8;EGYPTIAN HIEROGLYPH-13DA8;Lo;0;L;;;;;N;;;;; +13DA9;EGYPTIAN HIEROGLYPH-13DA9;Lo;0;L;;;;;N;;;;; +13DAA;EGYPTIAN HIEROGLYPH-13DAA;Lo;0;L;;;;;N;;;;; +13DAB;EGYPTIAN HIEROGLYPH-13DAB;Lo;0;L;;;;;N;;;;; +13DAC;EGYPTIAN HIEROGLYPH-13DAC;Lo;0;L;;;;;N;;;;; +13DAD;EGYPTIAN HIEROGLYPH-13DAD;Lo;0;L;;;;;N;;;;; +13DAE;EGYPTIAN HIEROGLYPH-13DAE;Lo;0;L;;;;;N;;;;; +13DAF;EGYPTIAN HIEROGLYPH-13DAF;Lo;0;L;;;;;N;;;;; +13DB0;EGYPTIAN HIEROGLYPH-13DB0;Lo;0;L;;;;;N;;;;; +13DB1;EGYPTIAN HIEROGLYPH-13DB1;Lo;0;L;;;;;N;;;;; +13DB2;EGYPTIAN HIEROGLYPH-13DB2;Lo;0;L;;;;;N;;;;; +13DB3;EGYPTIAN HIEROGLYPH-13DB3;Lo;0;L;;;;;N;;;;; +13DB4;EGYPTIAN HIEROGLYPH-13DB4;Lo;0;L;;;;;N;;;;; +13DB5;EGYPTIAN HIEROGLYPH-13DB5;Lo;0;L;;;;;N;;;;; +13DB6;EGYPTIAN HIEROGLYPH-13DB6;Lo;0;L;;;;;N;;;;; +13DB7;EGYPTIAN HIEROGLYPH-13DB7;Lo;0;L;;;;;N;;;;; +13DB8;EGYPTIAN HIEROGLYPH-13DB8;Lo;0;L;;;;;N;;;;; +13DB9;EGYPTIAN HIEROGLYPH-13DB9;Lo;0;L;;;;;N;;;;; +13DBA;EGYPTIAN HIEROGLYPH-13DBA;Lo;0;L;;;;;N;;;;; +13DBB;EGYPTIAN HIEROGLYPH-13DBB;Lo;0;L;;;;;N;;;;; +13DBC;EGYPTIAN HIEROGLYPH-13DBC;Lo;0;L;;;;;N;;;;; +13DBD;EGYPTIAN HIEROGLYPH-13DBD;Lo;0;L;;;;;N;;;;; +13DBE;EGYPTIAN HIEROGLYPH-13DBE;Lo;0;L;;;;;N;;;;; +13DBF;EGYPTIAN HIEROGLYPH-13DBF;Lo;0;L;;;;;N;;;;; +13DC0;EGYPTIAN HIEROGLYPH-13DC0;Lo;0;L;;;;;N;;;;; +13DC1;EGYPTIAN HIEROGLYPH-13DC1;Lo;0;L;;;;;N;;;;; +13DC2;EGYPTIAN HIEROGLYPH-13DC2;Lo;0;L;;;;;N;;;;; +13DC3;EGYPTIAN HIEROGLYPH-13DC3;Lo;0;L;;;;;N;;;;; +13DC4;EGYPTIAN HIEROGLYPH-13DC4;Lo;0;L;;;;;N;;;;; +13DC5;EGYPTIAN HIEROGLYPH-13DC5;Lo;0;L;;;;;N;;;;; +13DC6;EGYPTIAN HIEROGLYPH-13DC6;Lo;0;L;;;;;N;;;;; +13DC7;EGYPTIAN HIEROGLYPH-13DC7;Lo;0;L;;;;;N;;;;; +13DC8;EGYPTIAN HIEROGLYPH-13DC8;Lo;0;L;;;;;N;;;;; +13DC9;EGYPTIAN HIEROGLYPH-13DC9;Lo;0;L;;;;;N;;;;; +13DCA;EGYPTIAN HIEROGLYPH-13DCA;Lo;0;L;;;;;N;;;;; +13DCB;EGYPTIAN HIEROGLYPH-13DCB;Lo;0;L;;;;;N;;;;; +13DCC;EGYPTIAN HIEROGLYPH-13DCC;Lo;0;L;;;;;N;;;;; +13DCD;EGYPTIAN HIEROGLYPH-13DCD;Lo;0;L;;;;;N;;;;; +13DCE;EGYPTIAN HIEROGLYPH-13DCE;Lo;0;L;;;;;N;;;;; +13DCF;EGYPTIAN HIEROGLYPH-13DCF;Lo;0;L;;;;;N;;;;; +13DD0;EGYPTIAN HIEROGLYPH-13DD0;Lo;0;L;;;;;N;;;;; +13DD1;EGYPTIAN HIEROGLYPH-13DD1;Lo;0;L;;;;;N;;;;; +13DD2;EGYPTIAN HIEROGLYPH-13DD2;Lo;0;L;;;;;N;;;;; +13DD3;EGYPTIAN HIEROGLYPH-13DD3;Lo;0;L;;;;;N;;;;; +13DD4;EGYPTIAN HIEROGLYPH-13DD4;Lo;0;L;;;;;N;;;;; +13DD5;EGYPTIAN HIEROGLYPH-13DD5;Lo;0;L;;;;;N;;;;; +13DD6;EGYPTIAN HIEROGLYPH-13DD6;Lo;0;L;;;;;N;;;;; +13DD7;EGYPTIAN HIEROGLYPH-13DD7;Lo;0;L;;;;;N;;;;; +13DD8;EGYPTIAN HIEROGLYPH-13DD8;Lo;0;L;;;;;N;;;;; +13DD9;EGYPTIAN HIEROGLYPH-13DD9;Lo;0;L;;;;;N;;;;; +13DDA;EGYPTIAN HIEROGLYPH-13DDA;Lo;0;L;;;;;N;;;;; +13DDB;EGYPTIAN HIEROGLYPH-13DDB;Lo;0;L;;;;;N;;;;; +13DDC;EGYPTIAN HIEROGLYPH-13DDC;Lo;0;L;;;;;N;;;;; +13DDD;EGYPTIAN HIEROGLYPH-13DDD;Lo;0;L;;;;;N;;;;; +13DDE;EGYPTIAN HIEROGLYPH-13DDE;Lo;0;L;;;;;N;;;;; +13DDF;EGYPTIAN HIEROGLYPH-13DDF;Lo;0;L;;;;;N;;;;; +13DE0;EGYPTIAN HIEROGLYPH-13DE0;Lo;0;L;;;;;N;;;;; +13DE1;EGYPTIAN HIEROGLYPH-13DE1;Lo;0;L;;;;;N;;;;; +13DE2;EGYPTIAN HIEROGLYPH-13DE2;Lo;0;L;;;;;N;;;;; +13DE3;EGYPTIAN HIEROGLYPH-13DE3;Lo;0;L;;;;;N;;;;; +13DE4;EGYPTIAN HIEROGLYPH-13DE4;Lo;0;L;;;;;N;;;;; +13DE5;EGYPTIAN HIEROGLYPH-13DE5;Lo;0;L;;;;;N;;;;; +13DE6;EGYPTIAN HIEROGLYPH-13DE6;Lo;0;L;;;;;N;;;;; +13DE7;EGYPTIAN HIEROGLYPH-13DE7;Lo;0;L;;;;;N;;;;; +13DE8;EGYPTIAN HIEROGLYPH-13DE8;Lo;0;L;;;;;N;;;;; +13DE9;EGYPTIAN HIEROGLYPH-13DE9;Lo;0;L;;;;;N;;;;; +13DEA;EGYPTIAN HIEROGLYPH-13DEA;Lo;0;L;;;;;N;;;;; +13DEB;EGYPTIAN HIEROGLYPH-13DEB;Lo;0;L;;;;;N;;;;; +13DEC;EGYPTIAN HIEROGLYPH-13DEC;Lo;0;L;;;;;N;;;;; +13DED;EGYPTIAN HIEROGLYPH-13DED;Lo;0;L;;;;;N;;;;; +13DEE;EGYPTIAN HIEROGLYPH-13DEE;Lo;0;L;;;;;N;;;;; +13DEF;EGYPTIAN HIEROGLYPH-13DEF;Lo;0;L;;;;;N;;;;; +13DF0;EGYPTIAN HIEROGLYPH-13DF0;Lo;0;L;;;;;N;;;;; +13DF1;EGYPTIAN HIEROGLYPH-13DF1;Lo;0;L;;;;;N;;;;; +13DF2;EGYPTIAN HIEROGLYPH-13DF2;Lo;0;L;;;;;N;;;;; +13DF3;EGYPTIAN HIEROGLYPH-13DF3;Lo;0;L;;;;;N;;;;; +13DF4;EGYPTIAN HIEROGLYPH-13DF4;Lo;0;L;;;;;N;;;;; +13DF5;EGYPTIAN HIEROGLYPH-13DF5;Lo;0;L;;;;;N;;;;; +13DF6;EGYPTIAN HIEROGLYPH-13DF6;Lo;0;L;;;;;N;;;;; +13DF7;EGYPTIAN HIEROGLYPH-13DF7;Lo;0;L;;;;;N;;;;; +13DF8;EGYPTIAN HIEROGLYPH-13DF8;Lo;0;L;;;;;N;;;;; +13DF9;EGYPTIAN HIEROGLYPH-13DF9;Lo;0;L;;;;;N;;;;; +13DFA;EGYPTIAN HIEROGLYPH-13DFA;Lo;0;L;;;;;N;;;;; +13DFB;EGYPTIAN HIEROGLYPH-13DFB;Lo;0;L;;;;;N;;;;; +13DFC;EGYPTIAN HIEROGLYPH-13DFC;Lo;0;L;;;;;N;;;;; +13DFD;EGYPTIAN HIEROGLYPH-13DFD;Lo;0;L;;;;;N;;;;; +13DFE;EGYPTIAN HIEROGLYPH-13DFE;Lo;0;L;;;;;N;;;;; +13DFF;EGYPTIAN HIEROGLYPH-13DFF;Lo;0;L;;;;;N;;;;; +13E00;EGYPTIAN HIEROGLYPH-13E00;Lo;0;L;;;;;N;;;;; +13E01;EGYPTIAN HIEROGLYPH-13E01;Lo;0;L;;;;;N;;;;; +13E02;EGYPTIAN HIEROGLYPH-13E02;Lo;0;L;;;;;N;;;;; +13E03;EGYPTIAN HIEROGLYPH-13E03;Lo;0;L;;;;;N;;;;; +13E04;EGYPTIAN HIEROGLYPH-13E04;Lo;0;L;;;;;N;;;;; +13E05;EGYPTIAN HIEROGLYPH-13E05;Lo;0;L;;;;;N;;;;; +13E06;EGYPTIAN HIEROGLYPH-13E06;Lo;0;L;;;;;N;;;;; +13E07;EGYPTIAN HIEROGLYPH-13E07;Lo;0;L;;;;;N;;;;; +13E08;EGYPTIAN HIEROGLYPH-13E08;Lo;0;L;;;;;N;;;;; +13E09;EGYPTIAN HIEROGLYPH-13E09;Lo;0;L;;;;;N;;;;; +13E0A;EGYPTIAN HIEROGLYPH-13E0A;Lo;0;L;;;;;N;;;;; +13E0B;EGYPTIAN HIEROGLYPH-13E0B;Lo;0;L;;;;;N;;;;; +13E0C;EGYPTIAN HIEROGLYPH-13E0C;Lo;0;L;;;;;N;;;;; +13E0D;EGYPTIAN HIEROGLYPH-13E0D;Lo;0;L;;;;;N;;;;; +13E0E;EGYPTIAN HIEROGLYPH-13E0E;Lo;0;L;;;;;N;;;;; +13E0F;EGYPTIAN HIEROGLYPH-13E0F;Lo;0;L;;;;;N;;;;; +13E10;EGYPTIAN HIEROGLYPH-13E10;Lo;0;L;;;;;N;;;;; +13E11;EGYPTIAN HIEROGLYPH-13E11;Lo;0;L;;;;;N;;;;; +13E12;EGYPTIAN HIEROGLYPH-13E12;Lo;0;L;;;;;N;;;;; +13E13;EGYPTIAN HIEROGLYPH-13E13;Lo;0;L;;;;;N;;;;; +13E14;EGYPTIAN HIEROGLYPH-13E14;Lo;0;L;;;;;N;;;;; +13E15;EGYPTIAN HIEROGLYPH-13E15;Lo;0;L;;;;;N;;;;; +13E16;EGYPTIAN HIEROGLYPH-13E16;Lo;0;L;;;;;N;;;;; +13E17;EGYPTIAN HIEROGLYPH-13E17;Lo;0;L;;;;;N;;;;; +13E18;EGYPTIAN HIEROGLYPH-13E18;Lo;0;L;;;;;N;;;;; +13E19;EGYPTIAN HIEROGLYPH-13E19;Lo;0;L;;;;;N;;;;; +13E1A;EGYPTIAN HIEROGLYPH-13E1A;Lo;0;L;;;;;N;;;;; +13E1B;EGYPTIAN HIEROGLYPH-13E1B;Lo;0;L;;;;;N;;;;; +13E1C;EGYPTIAN HIEROGLYPH-13E1C;Lo;0;L;;;;;N;;;;; +13E1D;EGYPTIAN HIEROGLYPH-13E1D;Lo;0;L;;;;;N;;;;; +13E1E;EGYPTIAN HIEROGLYPH-13E1E;Lo;0;L;;;;;N;;;;; +13E1F;EGYPTIAN HIEROGLYPH-13E1F;Lo;0;L;;;;;N;;;;; +13E20;EGYPTIAN HIEROGLYPH-13E20;Lo;0;L;;;;;N;;;;; +13E21;EGYPTIAN HIEROGLYPH-13E21;Lo;0;L;;;;;N;;;;; +13E22;EGYPTIAN HIEROGLYPH-13E22;Lo;0;L;;;;;N;;;;; +13E23;EGYPTIAN HIEROGLYPH-13E23;Lo;0;L;;;;;N;;;;; +13E24;EGYPTIAN HIEROGLYPH-13E24;Lo;0;L;;;;;N;;;;; +13E25;EGYPTIAN HIEROGLYPH-13E25;Lo;0;L;;;;;N;;;;; +13E26;EGYPTIAN HIEROGLYPH-13E26;Lo;0;L;;;;;N;;;;; +13E27;EGYPTIAN HIEROGLYPH-13E27;Lo;0;L;;;;;N;;;;; +13E28;EGYPTIAN HIEROGLYPH-13E28;Lo;0;L;;;;;N;;;;; +13E29;EGYPTIAN HIEROGLYPH-13E29;Lo;0;L;;;;;N;;;;; +13E2A;EGYPTIAN HIEROGLYPH-13E2A;Lo;0;L;;;;;N;;;;; +13E2B;EGYPTIAN HIEROGLYPH-13E2B;Lo;0;L;;;;;N;;;;; +13E2C;EGYPTIAN HIEROGLYPH-13E2C;Lo;0;L;;;;;N;;;;; +13E2D;EGYPTIAN HIEROGLYPH-13E2D;Lo;0;L;;;;;N;;;;; +13E2E;EGYPTIAN HIEROGLYPH-13E2E;Lo;0;L;;;;;N;;;;; +13E2F;EGYPTIAN HIEROGLYPH-13E2F;Lo;0;L;;;;;N;;;;; +13E30;EGYPTIAN HIEROGLYPH-13E30;Lo;0;L;;;;;N;;;;; +13E31;EGYPTIAN HIEROGLYPH-13E31;Lo;0;L;;;;;N;;;;; +13E32;EGYPTIAN HIEROGLYPH-13E32;Lo;0;L;;;;;N;;;;; +13E33;EGYPTIAN HIEROGLYPH-13E33;Lo;0;L;;;;;N;;;;; +13E34;EGYPTIAN HIEROGLYPH-13E34;Lo;0;L;;;;;N;;;;; +13E35;EGYPTIAN HIEROGLYPH-13E35;Lo;0;L;;;;;N;;;;; +13E36;EGYPTIAN HIEROGLYPH-13E36;Lo;0;L;;;;;N;;;;; +13E37;EGYPTIAN HIEROGLYPH-13E37;Lo;0;L;;;;;N;;;;; +13E38;EGYPTIAN HIEROGLYPH-13E38;Lo;0;L;;;;;N;;;;; +13E39;EGYPTIAN HIEROGLYPH-13E39;Lo;0;L;;;;;N;;;;; +13E3A;EGYPTIAN HIEROGLYPH-13E3A;Lo;0;L;;;;;N;;;;; +13E3B;EGYPTIAN HIEROGLYPH-13E3B;Lo;0;L;;;;;N;;;;; +13E3C;EGYPTIAN HIEROGLYPH-13E3C;Lo;0;L;;;;;N;;;;; +13E3D;EGYPTIAN HIEROGLYPH-13E3D;Lo;0;L;;;;;N;;;;; +13E3E;EGYPTIAN HIEROGLYPH-13E3E;Lo;0;L;;;;;N;;;;; +13E3F;EGYPTIAN HIEROGLYPH-13E3F;Lo;0;L;;;;;N;;;;; +13E40;EGYPTIAN HIEROGLYPH-13E40;Lo;0;L;;;;;N;;;;; +13E41;EGYPTIAN HIEROGLYPH-13E41;Lo;0;L;;;;;N;;;;; +13E42;EGYPTIAN HIEROGLYPH-13E42;Lo;0;L;;;;;N;;;;; +13E43;EGYPTIAN HIEROGLYPH-13E43;Lo;0;L;;;;;N;;;;; +13E44;EGYPTIAN HIEROGLYPH-13E44;Lo;0;L;;;;;N;;;;; +13E45;EGYPTIAN HIEROGLYPH-13E45;Lo;0;L;;;;;N;;;;; +13E46;EGYPTIAN HIEROGLYPH-13E46;Lo;0;L;;;;;N;;;;; +13E47;EGYPTIAN HIEROGLYPH-13E47;Lo;0;L;;;;;N;;;;; +13E48;EGYPTIAN HIEROGLYPH-13E48;Lo;0;L;;;;;N;;;;; +13E49;EGYPTIAN HIEROGLYPH-13E49;Lo;0;L;;;;;N;;;;; +13E4A;EGYPTIAN HIEROGLYPH-13E4A;Lo;0;L;;;;;N;;;;; +13E4B;EGYPTIAN HIEROGLYPH-13E4B;Lo;0;L;;;;;N;;;;; +13E4C;EGYPTIAN HIEROGLYPH-13E4C;Lo;0;L;;;;;N;;;;; +13E4D;EGYPTIAN HIEROGLYPH-13E4D;Lo;0;L;;;;;N;;;;; +13E4E;EGYPTIAN HIEROGLYPH-13E4E;Lo;0;L;;;;;N;;;;; +13E4F;EGYPTIAN HIEROGLYPH-13E4F;Lo;0;L;;;;;N;;;;; +13E50;EGYPTIAN HIEROGLYPH-13E50;Lo;0;L;;;;;N;;;;; +13E51;EGYPTIAN HIEROGLYPH-13E51;Lo;0;L;;;;;N;;;;; +13E52;EGYPTIAN HIEROGLYPH-13E52;Lo;0;L;;;;;N;;;;; +13E53;EGYPTIAN HIEROGLYPH-13E53;Lo;0;L;;;;;N;;;;; +13E54;EGYPTIAN HIEROGLYPH-13E54;Lo;0;L;;;;;N;;;;; +13E55;EGYPTIAN HIEROGLYPH-13E55;Lo;0;L;;;;;N;;;;; +13E56;EGYPTIAN HIEROGLYPH-13E56;Lo;0;L;;;;;N;;;;; +13E57;EGYPTIAN HIEROGLYPH-13E57;Lo;0;L;;;;;N;;;;; +13E58;EGYPTIAN HIEROGLYPH-13E58;Lo;0;L;;;;;N;;;;; +13E59;EGYPTIAN HIEROGLYPH-13E59;Lo;0;L;;;;;N;;;;; +13E5A;EGYPTIAN HIEROGLYPH-13E5A;Lo;0;L;;;;;N;;;;; +13E5B;EGYPTIAN HIEROGLYPH-13E5B;Lo;0;L;;;;;N;;;;; +13E5C;EGYPTIAN HIEROGLYPH-13E5C;Lo;0;L;;;;;N;;;;; +13E5D;EGYPTIAN HIEROGLYPH-13E5D;Lo;0;L;;;;;N;;;;; +13E5E;EGYPTIAN HIEROGLYPH-13E5E;Lo;0;L;;;;;N;;;;; +13E5F;EGYPTIAN HIEROGLYPH-13E5F;Lo;0;L;;;;;N;;;;; +13E60;EGYPTIAN HIEROGLYPH-13E60;Lo;0;L;;;;;N;;;;; +13E61;EGYPTIAN HIEROGLYPH-13E61;Lo;0;L;;;;;N;;;;; +13E62;EGYPTIAN HIEROGLYPH-13E62;Lo;0;L;;;;;N;;;;; +13E63;EGYPTIAN HIEROGLYPH-13E63;Lo;0;L;;;;;N;;;;; +13E64;EGYPTIAN HIEROGLYPH-13E64;Lo;0;L;;;;;N;;;;; +13E65;EGYPTIAN HIEROGLYPH-13E65;Lo;0;L;;;;;N;;;;; +13E66;EGYPTIAN HIEROGLYPH-13E66;Lo;0;L;;;;;N;;;;; +13E67;EGYPTIAN HIEROGLYPH-13E67;Lo;0;L;;;;;N;;;;; +13E68;EGYPTIAN HIEROGLYPH-13E68;Lo;0;L;;;;;N;;;;; +13E69;EGYPTIAN HIEROGLYPH-13E69;Lo;0;L;;;;;N;;;;; +13E6A;EGYPTIAN HIEROGLYPH-13E6A;Lo;0;L;;;;;N;;;;; +13E6B;EGYPTIAN HIEROGLYPH-13E6B;Lo;0;L;;;;;N;;;;; +13E6C;EGYPTIAN HIEROGLYPH-13E6C;Lo;0;L;;;;;N;;;;; +13E6D;EGYPTIAN HIEROGLYPH-13E6D;Lo;0;L;;;;;N;;;;; +13E6E;EGYPTIAN HIEROGLYPH-13E6E;Lo;0;L;;;;;N;;;;; +13E6F;EGYPTIAN HIEROGLYPH-13E6F;Lo;0;L;;;;;N;;;;; +13E70;EGYPTIAN HIEROGLYPH-13E70;Lo;0;L;;;;;N;;;;; +13E71;EGYPTIAN HIEROGLYPH-13E71;Lo;0;L;;;;;N;;;;; +13E72;EGYPTIAN HIEROGLYPH-13E72;Lo;0;L;;;;;N;;;;; +13E73;EGYPTIAN HIEROGLYPH-13E73;Lo;0;L;;;;;N;;;;; +13E74;EGYPTIAN HIEROGLYPH-13E74;Lo;0;L;;;;;N;;;;; +13E75;EGYPTIAN HIEROGLYPH-13E75;Lo;0;L;;;;;N;;;;; +13E76;EGYPTIAN HIEROGLYPH-13E76;Lo;0;L;;;;;N;;;;; +13E77;EGYPTIAN HIEROGLYPH-13E77;Lo;0;L;;;;;N;;;;; +13E78;EGYPTIAN HIEROGLYPH-13E78;Lo;0;L;;;;;N;;;;; +13E79;EGYPTIAN HIEROGLYPH-13E79;Lo;0;L;;;;;N;;;;; +13E7A;EGYPTIAN HIEROGLYPH-13E7A;Lo;0;L;;;;;N;;;;; +13E7B;EGYPTIAN HIEROGLYPH-13E7B;Lo;0;L;;;;;N;;;;; +13E7C;EGYPTIAN HIEROGLYPH-13E7C;Lo;0;L;;;;;N;;;;; +13E7D;EGYPTIAN HIEROGLYPH-13E7D;Lo;0;L;;;;;N;;;;; +13E7E;EGYPTIAN HIEROGLYPH-13E7E;Lo;0;L;;;;;N;;;;; +13E7F;EGYPTIAN HIEROGLYPH-13E7F;Lo;0;L;;;;;N;;;;; +13E80;EGYPTIAN HIEROGLYPH-13E80;Lo;0;L;;;;;N;;;;; +13E81;EGYPTIAN HIEROGLYPH-13E81;Lo;0;L;;;;;N;;;;; +13E82;EGYPTIAN HIEROGLYPH-13E82;Lo;0;L;;;;;N;;;;; +13E83;EGYPTIAN HIEROGLYPH-13E83;Lo;0;L;;;;;N;;;;; +13E84;EGYPTIAN HIEROGLYPH-13E84;Lo;0;L;;;;;N;;;;; +13E85;EGYPTIAN HIEROGLYPH-13E85;Lo;0;L;;;;;N;;;;; +13E86;EGYPTIAN HIEROGLYPH-13E86;Lo;0;L;;;;;N;;;;; +13E87;EGYPTIAN HIEROGLYPH-13E87;Lo;0;L;;;;;N;;;;; +13E88;EGYPTIAN HIEROGLYPH-13E88;Lo;0;L;;;;;N;;;;; +13E89;EGYPTIAN HIEROGLYPH-13E89;Lo;0;L;;;;;N;;;;; +13E8A;EGYPTIAN HIEROGLYPH-13E8A;Lo;0;L;;;;;N;;;;; +13E8B;EGYPTIAN HIEROGLYPH-13E8B;Lo;0;L;;;;;N;;;;; +13E8C;EGYPTIAN HIEROGLYPH-13E8C;Lo;0;L;;;;;N;;;;; +13E8D;EGYPTIAN HIEROGLYPH-13E8D;Lo;0;L;;;;;N;;;;; +13E8E;EGYPTIAN HIEROGLYPH-13E8E;Lo;0;L;;;;;N;;;;; +13E8F;EGYPTIAN HIEROGLYPH-13E8F;Lo;0;L;;;;;N;;;;; +13E90;EGYPTIAN HIEROGLYPH-13E90;Lo;0;L;;;;;N;;;;; +13E91;EGYPTIAN HIEROGLYPH-13E91;Lo;0;L;;;;;N;;;;; +13E92;EGYPTIAN HIEROGLYPH-13E92;Lo;0;L;;;;;N;;;;; +13E93;EGYPTIAN HIEROGLYPH-13E93;Lo;0;L;;;;;N;;;;; +13E94;EGYPTIAN HIEROGLYPH-13E94;Lo;0;L;;;;;N;;;;; +13E95;EGYPTIAN HIEROGLYPH-13E95;Lo;0;L;;;;;N;;;;; +13E96;EGYPTIAN HIEROGLYPH-13E96;Lo;0;L;;;;;N;;;;; +13E97;EGYPTIAN HIEROGLYPH-13E97;Lo;0;L;;;;;N;;;;; +13E98;EGYPTIAN HIEROGLYPH-13E98;Lo;0;L;;;;;N;;;;; +13E99;EGYPTIAN HIEROGLYPH-13E99;Lo;0;L;;;;;N;;;;; +13E9A;EGYPTIAN HIEROGLYPH-13E9A;Lo;0;L;;;;;N;;;;; +13E9B;EGYPTIAN HIEROGLYPH-13E9B;Lo;0;L;;;;;N;;;;; +13E9C;EGYPTIAN HIEROGLYPH-13E9C;Lo;0;L;;;;;N;;;;; +13E9D;EGYPTIAN HIEROGLYPH-13E9D;Lo;0;L;;;;;N;;;;; +13E9E;EGYPTIAN HIEROGLYPH-13E9E;Lo;0;L;;;;;N;;;;; +13E9F;EGYPTIAN HIEROGLYPH-13E9F;Lo;0;L;;;;;N;;;;; +13EA0;EGYPTIAN HIEROGLYPH-13EA0;Lo;0;L;;;;;N;;;;; +13EA1;EGYPTIAN HIEROGLYPH-13EA1;Lo;0;L;;;;;N;;;;; +13EA2;EGYPTIAN HIEROGLYPH-13EA2;Lo;0;L;;;;;N;;;;; +13EA3;EGYPTIAN HIEROGLYPH-13EA3;Lo;0;L;;;;;N;;;;; +13EA4;EGYPTIAN HIEROGLYPH-13EA4;Lo;0;L;;;;;N;;;;; +13EA5;EGYPTIAN HIEROGLYPH-13EA5;Lo;0;L;;;;;N;;;;; +13EA6;EGYPTIAN HIEROGLYPH-13EA6;Lo;0;L;;;;;N;;;;; +13EA7;EGYPTIAN HIEROGLYPH-13EA7;Lo;0;L;;;;;N;;;;; +13EA8;EGYPTIAN HIEROGLYPH-13EA8;Lo;0;L;;;;;N;;;;; +13EA9;EGYPTIAN HIEROGLYPH-13EA9;Lo;0;L;;;;;N;;;;; +13EAA;EGYPTIAN HIEROGLYPH-13EAA;Lo;0;L;;;;;N;;;;; +13EAB;EGYPTIAN HIEROGLYPH-13EAB;Lo;0;L;;;;;N;;;;; +13EAC;EGYPTIAN HIEROGLYPH-13EAC;Lo;0;L;;;;;N;;;;; +13EAD;EGYPTIAN HIEROGLYPH-13EAD;Lo;0;L;;;;;N;;;;; +13EAE;EGYPTIAN HIEROGLYPH-13EAE;Lo;0;L;;;;;N;;;;; +13EAF;EGYPTIAN HIEROGLYPH-13EAF;Lo;0;L;;;;;N;;;;; +13EB0;EGYPTIAN HIEROGLYPH-13EB0;Lo;0;L;;;;;N;;;;; +13EB1;EGYPTIAN HIEROGLYPH-13EB1;Lo;0;L;;;;;N;;;;; +13EB2;EGYPTIAN HIEROGLYPH-13EB2;Lo;0;L;;;;;N;;;;; +13EB3;EGYPTIAN HIEROGLYPH-13EB3;Lo;0;L;;;;;N;;;;; +13EB4;EGYPTIAN HIEROGLYPH-13EB4;Lo;0;L;;;;;N;;;;; +13EB5;EGYPTIAN HIEROGLYPH-13EB5;Lo;0;L;;;;;N;;;;; +13EB6;EGYPTIAN HIEROGLYPH-13EB6;Lo;0;L;;;;;N;;;;; +13EB7;EGYPTIAN HIEROGLYPH-13EB7;Lo;0;L;;;;;N;;;;; +13EB8;EGYPTIAN HIEROGLYPH-13EB8;Lo;0;L;;;;;N;;;;; +13EB9;EGYPTIAN HIEROGLYPH-13EB9;Lo;0;L;;;;;N;;;;; +13EBA;EGYPTIAN HIEROGLYPH-13EBA;Lo;0;L;;;;;N;;;;; +13EBB;EGYPTIAN HIEROGLYPH-13EBB;Lo;0;L;;;;;N;;;;; +13EBC;EGYPTIAN HIEROGLYPH-13EBC;Lo;0;L;;;;;N;;;;; +13EBD;EGYPTIAN HIEROGLYPH-13EBD;Lo;0;L;;;;;N;;;;; +13EBE;EGYPTIAN HIEROGLYPH-13EBE;Lo;0;L;;;;;N;;;;; +13EBF;EGYPTIAN HIEROGLYPH-13EBF;Lo;0;L;;;;;N;;;;; +13EC0;EGYPTIAN HIEROGLYPH-13EC0;Lo;0;L;;;;;N;;;;; +13EC1;EGYPTIAN HIEROGLYPH-13EC1;Lo;0;L;;;;;N;;;;; +13EC2;EGYPTIAN HIEROGLYPH-13EC2;Lo;0;L;;;;;N;;;;; +13EC3;EGYPTIAN HIEROGLYPH-13EC3;Lo;0;L;;;;;N;;;;; +13EC4;EGYPTIAN HIEROGLYPH-13EC4;Lo;0;L;;;;;N;;;;; +13EC5;EGYPTIAN HIEROGLYPH-13EC5;Lo;0;L;;;;;N;;;;; +13EC6;EGYPTIAN HIEROGLYPH-13EC6;Lo;0;L;;;;;N;;;;; +13EC7;EGYPTIAN HIEROGLYPH-13EC7;Lo;0;L;;;;;N;;;;; +13EC8;EGYPTIAN HIEROGLYPH-13EC8;Lo;0;L;;;;;N;;;;; +13EC9;EGYPTIAN HIEROGLYPH-13EC9;Lo;0;L;;;;;N;;;;; +13ECA;EGYPTIAN HIEROGLYPH-13ECA;Lo;0;L;;;;;N;;;;; +13ECB;EGYPTIAN HIEROGLYPH-13ECB;Lo;0;L;;;;;N;;;;; +13ECC;EGYPTIAN HIEROGLYPH-13ECC;Lo;0;L;;;;;N;;;;; +13ECD;EGYPTIAN HIEROGLYPH-13ECD;Lo;0;L;;;;;N;;;;; +13ECE;EGYPTIAN HIEROGLYPH-13ECE;Lo;0;L;;;;;N;;;;; +13ECF;EGYPTIAN HIEROGLYPH-13ECF;Lo;0;L;;;;;N;;;;; +13ED0;EGYPTIAN HIEROGLYPH-13ED0;Lo;0;L;;;;;N;;;;; +13ED1;EGYPTIAN HIEROGLYPH-13ED1;Lo;0;L;;;;;N;;;;; +13ED2;EGYPTIAN HIEROGLYPH-13ED2;Lo;0;L;;;;;N;;;;; +13ED3;EGYPTIAN HIEROGLYPH-13ED3;Lo;0;L;;;;;N;;;;; +13ED4;EGYPTIAN HIEROGLYPH-13ED4;Lo;0;L;;;;;N;;;;; +13ED5;EGYPTIAN HIEROGLYPH-13ED5;Lo;0;L;;;;;N;;;;; +13ED6;EGYPTIAN HIEROGLYPH-13ED6;Lo;0;L;;;;;N;;;;; +13ED7;EGYPTIAN HIEROGLYPH-13ED7;Lo;0;L;;;;;N;;;;; +13ED8;EGYPTIAN HIEROGLYPH-13ED8;Lo;0;L;;;;;N;;;;; +13ED9;EGYPTIAN HIEROGLYPH-13ED9;Lo;0;L;;;;;N;;;;; +13EDA;EGYPTIAN HIEROGLYPH-13EDA;Lo;0;L;;;;;N;;;;; +13EDB;EGYPTIAN HIEROGLYPH-13EDB;Lo;0;L;;;;;N;;;;; +13EDC;EGYPTIAN HIEROGLYPH-13EDC;Lo;0;L;;;;;N;;;;; +13EDD;EGYPTIAN HIEROGLYPH-13EDD;Lo;0;L;;;;;N;;;;; +13EDE;EGYPTIAN HIEROGLYPH-13EDE;Lo;0;L;;;;;N;;;;; +13EDF;EGYPTIAN HIEROGLYPH-13EDF;Lo;0;L;;;;;N;;;;; +13EE0;EGYPTIAN HIEROGLYPH-13EE0;Lo;0;L;;;;;N;;;;; +13EE1;EGYPTIAN HIEROGLYPH-13EE1;Lo;0;L;;;;;N;;;;; +13EE2;EGYPTIAN HIEROGLYPH-13EE2;Lo;0;L;;;;;N;;;;; +13EE3;EGYPTIAN HIEROGLYPH-13EE3;Lo;0;L;;;;;N;;;;; +13EE4;EGYPTIAN HIEROGLYPH-13EE4;Lo;0;L;;;;;N;;;;; +13EE5;EGYPTIAN HIEROGLYPH-13EE5;Lo;0;L;;;;;N;;;;; +13EE6;EGYPTIAN HIEROGLYPH-13EE6;Lo;0;L;;;;;N;;;;; +13EE7;EGYPTIAN HIEROGLYPH-13EE7;Lo;0;L;;;;;N;;;;; +13EE8;EGYPTIAN HIEROGLYPH-13EE8;Lo;0;L;;;;;N;;;;; +13EE9;EGYPTIAN HIEROGLYPH-13EE9;Lo;0;L;;;;;N;;;;; +13EEA;EGYPTIAN HIEROGLYPH-13EEA;Lo;0;L;;;;;N;;;;; +13EEB;EGYPTIAN HIEROGLYPH-13EEB;Lo;0;L;;;;;N;;;;; +13EEC;EGYPTIAN HIEROGLYPH-13EEC;Lo;0;L;;;;;N;;;;; +13EED;EGYPTIAN HIEROGLYPH-13EED;Lo;0;L;;;;;N;;;;; +13EEE;EGYPTIAN HIEROGLYPH-13EEE;Lo;0;L;;;;;N;;;;; +13EEF;EGYPTIAN HIEROGLYPH-13EEF;Lo;0;L;;;;;N;;;;; +13EF0;EGYPTIAN HIEROGLYPH-13EF0;Lo;0;L;;;;;N;;;;; +13EF1;EGYPTIAN HIEROGLYPH-13EF1;Lo;0;L;;;;;N;;;;; +13EF2;EGYPTIAN HIEROGLYPH-13EF2;Lo;0;L;;;;;N;;;;; +13EF3;EGYPTIAN HIEROGLYPH-13EF3;Lo;0;L;;;;;N;;;;; +13EF4;EGYPTIAN HIEROGLYPH-13EF4;Lo;0;L;;;;;N;;;;; +13EF5;EGYPTIAN HIEROGLYPH-13EF5;Lo;0;L;;;;;N;;;;; +13EF6;EGYPTIAN HIEROGLYPH-13EF6;Lo;0;L;;;;;N;;;;; +13EF7;EGYPTIAN HIEROGLYPH-13EF7;Lo;0;L;;;;;N;;;;; +13EF8;EGYPTIAN HIEROGLYPH-13EF8;Lo;0;L;;;;;N;;;;; +13EF9;EGYPTIAN HIEROGLYPH-13EF9;Lo;0;L;;;;;N;;;;; +13EFA;EGYPTIAN HIEROGLYPH-13EFA;Lo;0;L;;;;;N;;;;; +13EFB;EGYPTIAN HIEROGLYPH-13EFB;Lo;0;L;;;;;N;;;;; +13EFC;EGYPTIAN HIEROGLYPH-13EFC;Lo;0;L;;;;;N;;;;; +13EFD;EGYPTIAN HIEROGLYPH-13EFD;Lo;0;L;;;;;N;;;;; +13EFE;EGYPTIAN HIEROGLYPH-13EFE;Lo;0;L;;;;;N;;;;; +13EFF;EGYPTIAN HIEROGLYPH-13EFF;Lo;0;L;;;;;N;;;;; +13F00;EGYPTIAN HIEROGLYPH-13F00;Lo;0;L;;;;;N;;;;; +13F01;EGYPTIAN HIEROGLYPH-13F01;Lo;0;L;;;;;N;;;;; +13F02;EGYPTIAN HIEROGLYPH-13F02;Lo;0;L;;;;;N;;;;; +13F03;EGYPTIAN HIEROGLYPH-13F03;Lo;0;L;;;;;N;;;;; +13F04;EGYPTIAN HIEROGLYPH-13F04;Lo;0;L;;;;;N;;;;; +13F05;EGYPTIAN HIEROGLYPH-13F05;Lo;0;L;;;;;N;;;;; +13F06;EGYPTIAN HIEROGLYPH-13F06;Lo;0;L;;;;;N;;;;; +13F07;EGYPTIAN HIEROGLYPH-13F07;Lo;0;L;;;;;N;;;;; +13F08;EGYPTIAN HIEROGLYPH-13F08;Lo;0;L;;;;;N;;;;; +13F09;EGYPTIAN HIEROGLYPH-13F09;Lo;0;L;;;;;N;;;;; +13F0A;EGYPTIAN HIEROGLYPH-13F0A;Lo;0;L;;;;;N;;;;; +13F0B;EGYPTIAN HIEROGLYPH-13F0B;Lo;0;L;;;;;N;;;;; +13F0C;EGYPTIAN HIEROGLYPH-13F0C;Lo;0;L;;;;;N;;;;; +13F0D;EGYPTIAN HIEROGLYPH-13F0D;Lo;0;L;;;;;N;;;;; +13F0E;EGYPTIAN HIEROGLYPH-13F0E;Lo;0;L;;;;;N;;;;; +13F0F;EGYPTIAN HIEROGLYPH-13F0F;Lo;0;L;;;;;N;;;;; +13F10;EGYPTIAN HIEROGLYPH-13F10;Lo;0;L;;;;;N;;;;; +13F11;EGYPTIAN HIEROGLYPH-13F11;Lo;0;L;;;;;N;;;;; +13F12;EGYPTIAN HIEROGLYPH-13F12;Lo;0;L;;;;;N;;;;; +13F13;EGYPTIAN HIEROGLYPH-13F13;Lo;0;L;;;;;N;;;;; +13F14;EGYPTIAN HIEROGLYPH-13F14;Lo;0;L;;;;;N;;;;; +13F15;EGYPTIAN HIEROGLYPH-13F15;Lo;0;L;;;;;N;;;;; +13F16;EGYPTIAN HIEROGLYPH-13F16;Lo;0;L;;;;;N;;;;; +13F17;EGYPTIAN HIEROGLYPH-13F17;Lo;0;L;;;;;N;;;;; +13F18;EGYPTIAN HIEROGLYPH-13F18;Lo;0;L;;;;;N;;;;; +13F19;EGYPTIAN HIEROGLYPH-13F19;Lo;0;L;;;;;N;;;;; +13F1A;EGYPTIAN HIEROGLYPH-13F1A;Lo;0;L;;;;;N;;;;; +13F1B;EGYPTIAN HIEROGLYPH-13F1B;Lo;0;L;;;;;N;;;;; +13F1C;EGYPTIAN HIEROGLYPH-13F1C;Lo;0;L;;;;;N;;;;; +13F1D;EGYPTIAN HIEROGLYPH-13F1D;Lo;0;L;;;;;N;;;;; +13F1E;EGYPTIAN HIEROGLYPH-13F1E;Lo;0;L;;;;;N;;;;; +13F1F;EGYPTIAN HIEROGLYPH-13F1F;Lo;0;L;;;;;N;;;;; +13F20;EGYPTIAN HIEROGLYPH-13F20;Lo;0;L;;;;;N;;;;; +13F21;EGYPTIAN HIEROGLYPH-13F21;Lo;0;L;;;;;N;;;;; +13F22;EGYPTIAN HIEROGLYPH-13F22;Lo;0;L;;;;;N;;;;; +13F23;EGYPTIAN HIEROGLYPH-13F23;Lo;0;L;;;;;N;;;;; +13F24;EGYPTIAN HIEROGLYPH-13F24;Lo;0;L;;;;;N;;;;; +13F25;EGYPTIAN HIEROGLYPH-13F25;Lo;0;L;;;;;N;;;;; +13F26;EGYPTIAN HIEROGLYPH-13F26;Lo;0;L;;;;;N;;;;; +13F27;EGYPTIAN HIEROGLYPH-13F27;Lo;0;L;;;;;N;;;;; +13F28;EGYPTIAN HIEROGLYPH-13F28;Lo;0;L;;;;;N;;;;; +13F29;EGYPTIAN HIEROGLYPH-13F29;Lo;0;L;;;;;N;;;;; +13F2A;EGYPTIAN HIEROGLYPH-13F2A;Lo;0;L;;;;;N;;;;; +13F2B;EGYPTIAN HIEROGLYPH-13F2B;Lo;0;L;;;;;N;;;;; +13F2C;EGYPTIAN HIEROGLYPH-13F2C;Lo;0;L;;;;;N;;;;; +13F2D;EGYPTIAN HIEROGLYPH-13F2D;Lo;0;L;;;;;N;;;;; +13F2E;EGYPTIAN HIEROGLYPH-13F2E;Lo;0;L;;;;;N;;;;; +13F2F;EGYPTIAN HIEROGLYPH-13F2F;Lo;0;L;;;;;N;;;;; +13F30;EGYPTIAN HIEROGLYPH-13F30;Lo;0;L;;;;;N;;;;; +13F31;EGYPTIAN HIEROGLYPH-13F31;Lo;0;L;;;;;N;;;;; +13F32;EGYPTIAN HIEROGLYPH-13F32;Lo;0;L;;;;;N;;;;; +13F33;EGYPTIAN HIEROGLYPH-13F33;Lo;0;L;;;;;N;;;;; +13F34;EGYPTIAN HIEROGLYPH-13F34;Lo;0;L;;;;;N;;;;; +13F35;EGYPTIAN HIEROGLYPH-13F35;Lo;0;L;;;;;N;;;;; +13F36;EGYPTIAN HIEROGLYPH-13F36;Lo;0;L;;;;;N;;;;; +13F37;EGYPTIAN HIEROGLYPH-13F37;Lo;0;L;;;;;N;;;;; +13F38;EGYPTIAN HIEROGLYPH-13F38;Lo;0;L;;;;;N;;;;; +13F39;EGYPTIAN HIEROGLYPH-13F39;Lo;0;L;;;;;N;;;;; +13F3A;EGYPTIAN HIEROGLYPH-13F3A;Lo;0;L;;;;;N;;;;; +13F3B;EGYPTIAN HIEROGLYPH-13F3B;Lo;0;L;;;;;N;;;;; +13F3C;EGYPTIAN HIEROGLYPH-13F3C;Lo;0;L;;;;;N;;;;; +13F3D;EGYPTIAN HIEROGLYPH-13F3D;Lo;0;L;;;;;N;;;;; +13F3E;EGYPTIAN HIEROGLYPH-13F3E;Lo;0;L;;;;;N;;;;; +13F3F;EGYPTIAN HIEROGLYPH-13F3F;Lo;0;L;;;;;N;;;;; +13F40;EGYPTIAN HIEROGLYPH-13F40;Lo;0;L;;;;;N;;;;; +13F41;EGYPTIAN HIEROGLYPH-13F41;Lo;0;L;;;;;N;;;;; +13F42;EGYPTIAN HIEROGLYPH-13F42;Lo;0;L;;;;;N;;;;; +13F43;EGYPTIAN HIEROGLYPH-13F43;Lo;0;L;;;;;N;;;;; +13F44;EGYPTIAN HIEROGLYPH-13F44;Lo;0;L;;;;;N;;;;; +13F45;EGYPTIAN HIEROGLYPH-13F45;Lo;0;L;;;;;N;;;;; +13F46;EGYPTIAN HIEROGLYPH-13F46;Lo;0;L;;;;;N;;;;; +13F47;EGYPTIAN HIEROGLYPH-13F47;Lo;0;L;;;;;N;;;;; +13F48;EGYPTIAN HIEROGLYPH-13F48;Lo;0;L;;;;;N;;;;; +13F49;EGYPTIAN HIEROGLYPH-13F49;Lo;0;L;;;;;N;;;;; +13F4A;EGYPTIAN HIEROGLYPH-13F4A;Lo;0;L;;;;;N;;;;; +13F4B;EGYPTIAN HIEROGLYPH-13F4B;Lo;0;L;;;;;N;;;;; +13F4C;EGYPTIAN HIEROGLYPH-13F4C;Lo;0;L;;;;;N;;;;; +13F4D;EGYPTIAN HIEROGLYPH-13F4D;Lo;0;L;;;;;N;;;;; +13F4E;EGYPTIAN HIEROGLYPH-13F4E;Lo;0;L;;;;;N;;;;; +13F4F;EGYPTIAN HIEROGLYPH-13F4F;Lo;0;L;;;;;N;;;;; +13F50;EGYPTIAN HIEROGLYPH-13F50;Lo;0;L;;;;;N;;;;; +13F51;EGYPTIAN HIEROGLYPH-13F51;Lo;0;L;;;;;N;;;;; +13F52;EGYPTIAN HIEROGLYPH-13F52;Lo;0;L;;;;;N;;;;; +13F53;EGYPTIAN HIEROGLYPH-13F53;Lo;0;L;;;;;N;;;;; +13F54;EGYPTIAN HIEROGLYPH-13F54;Lo;0;L;;;;;N;;;;; +13F55;EGYPTIAN HIEROGLYPH-13F55;Lo;0;L;;;;;N;;;;; +13F56;EGYPTIAN HIEROGLYPH-13F56;Lo;0;L;;;;;N;;;;; +13F57;EGYPTIAN HIEROGLYPH-13F57;Lo;0;L;;;;;N;;;;; +13F58;EGYPTIAN HIEROGLYPH-13F58;Lo;0;L;;;;;N;;;;; +13F59;EGYPTIAN HIEROGLYPH-13F59;Lo;0;L;;;;;N;;;;; +13F5A;EGYPTIAN HIEROGLYPH-13F5A;Lo;0;L;;;;;N;;;;; +13F5B;EGYPTIAN HIEROGLYPH-13F5B;Lo;0;L;;;;;N;;;;; +13F5C;EGYPTIAN HIEROGLYPH-13F5C;Lo;0;L;;;;;N;;;;; +13F5D;EGYPTIAN HIEROGLYPH-13F5D;Lo;0;L;;;;;N;;;;; +13F5E;EGYPTIAN HIEROGLYPH-13F5E;Lo;0;L;;;;;N;;;;; +13F5F;EGYPTIAN HIEROGLYPH-13F5F;Lo;0;L;;;;;N;;;;; +13F60;EGYPTIAN HIEROGLYPH-13F60;Lo;0;L;;;;;N;;;;; +13F61;EGYPTIAN HIEROGLYPH-13F61;Lo;0;L;;;;;N;;;;; +13F62;EGYPTIAN HIEROGLYPH-13F62;Lo;0;L;;;;;N;;;;; +13F63;EGYPTIAN HIEROGLYPH-13F63;Lo;0;L;;;;;N;;;;; +13F64;EGYPTIAN HIEROGLYPH-13F64;Lo;0;L;;;;;N;;;;; +13F65;EGYPTIAN HIEROGLYPH-13F65;Lo;0;L;;;;;N;;;;; +13F66;EGYPTIAN HIEROGLYPH-13F66;Lo;0;L;;;;;N;;;;; +13F67;EGYPTIAN HIEROGLYPH-13F67;Lo;0;L;;;;;N;;;;; +13F68;EGYPTIAN HIEROGLYPH-13F68;Lo;0;L;;;;;N;;;;; +13F69;EGYPTIAN HIEROGLYPH-13F69;Lo;0;L;;;;;N;;;;; +13F6A;EGYPTIAN HIEROGLYPH-13F6A;Lo;0;L;;;;;N;;;;; +13F6B;EGYPTIAN HIEROGLYPH-13F6B;Lo;0;L;;;;;N;;;;; +13F6C;EGYPTIAN HIEROGLYPH-13F6C;Lo;0;L;;;;;N;;;;; +13F6D;EGYPTIAN HIEROGLYPH-13F6D;Lo;0;L;;;;;N;;;;; +13F6E;EGYPTIAN HIEROGLYPH-13F6E;Lo;0;L;;;;;N;;;;; +13F6F;EGYPTIAN HIEROGLYPH-13F6F;Lo;0;L;;;;;N;;;;; +13F70;EGYPTIAN HIEROGLYPH-13F70;Lo;0;L;;;;;N;;;;; +13F71;EGYPTIAN HIEROGLYPH-13F71;Lo;0;L;;;;;N;;;;; +13F72;EGYPTIAN HIEROGLYPH-13F72;Lo;0;L;;;;;N;;;;; +13F73;EGYPTIAN HIEROGLYPH-13F73;Lo;0;L;;;;;N;;;;; +13F74;EGYPTIAN HIEROGLYPH-13F74;Lo;0;L;;;;;N;;;;; +13F75;EGYPTIAN HIEROGLYPH-13F75;Lo;0;L;;;;;N;;;;; +13F76;EGYPTIAN HIEROGLYPH-13F76;Lo;0;L;;;;;N;;;;; +13F77;EGYPTIAN HIEROGLYPH-13F77;Lo;0;L;;;;;N;;;;; +13F78;EGYPTIAN HIEROGLYPH-13F78;Lo;0;L;;;;;N;;;;; +13F79;EGYPTIAN HIEROGLYPH-13F79;Lo;0;L;;;;;N;;;;; +13F7A;EGYPTIAN HIEROGLYPH-13F7A;Lo;0;L;;;;;N;;;;; +13F7B;EGYPTIAN HIEROGLYPH-13F7B;Lo;0;L;;;;;N;;;;; +13F7C;EGYPTIAN HIEROGLYPH-13F7C;Lo;0;L;;;;;N;;;;; +13F7D;EGYPTIAN HIEROGLYPH-13F7D;Lo;0;L;;;;;N;;;;; +13F7E;EGYPTIAN HIEROGLYPH-13F7E;Lo;0;L;;;;;N;;;;; +13F7F;EGYPTIAN HIEROGLYPH-13F7F;Lo;0;L;;;;;N;;;;; +13F80;EGYPTIAN HIEROGLYPH-13F80;Lo;0;L;;;;;N;;;;; +13F81;EGYPTIAN HIEROGLYPH-13F81;Lo;0;L;;;;;N;;;;; +13F82;EGYPTIAN HIEROGLYPH-13F82;Lo;0;L;;;;;N;;;;; +13F83;EGYPTIAN HIEROGLYPH-13F83;Lo;0;L;;;;;N;;;;; +13F84;EGYPTIAN HIEROGLYPH-13F84;Lo;0;L;;;;;N;;;;; +13F85;EGYPTIAN HIEROGLYPH-13F85;Lo;0;L;;;;;N;;;;; +13F86;EGYPTIAN HIEROGLYPH-13F86;Lo;0;L;;;;;N;;;;; +13F87;EGYPTIAN HIEROGLYPH-13F87;Lo;0;L;;;;;N;;;;; +13F88;EGYPTIAN HIEROGLYPH-13F88;Lo;0;L;;;;;N;;;;; +13F89;EGYPTIAN HIEROGLYPH-13F89;Lo;0;L;;;;;N;;;;; +13F8A;EGYPTIAN HIEROGLYPH-13F8A;Lo;0;L;;;;;N;;;;; +13F8B;EGYPTIAN HIEROGLYPH-13F8B;Lo;0;L;;;;;N;;;;; +13F8C;EGYPTIAN HIEROGLYPH-13F8C;Lo;0;L;;;;;N;;;;; +13F8D;EGYPTIAN HIEROGLYPH-13F8D;Lo;0;L;;;;;N;;;;; +13F8E;EGYPTIAN HIEROGLYPH-13F8E;Lo;0;L;;;;;N;;;;; +13F8F;EGYPTIAN HIEROGLYPH-13F8F;Lo;0;L;;;;;N;;;;; +13F90;EGYPTIAN HIEROGLYPH-13F90;Lo;0;L;;;;;N;;;;; +13F91;EGYPTIAN HIEROGLYPH-13F91;Lo;0;L;;;;;N;;;;; +13F92;EGYPTIAN HIEROGLYPH-13F92;Lo;0;L;;;;;N;;;;; +13F93;EGYPTIAN HIEROGLYPH-13F93;Lo;0;L;;;;;N;;;;; +13F94;EGYPTIAN HIEROGLYPH-13F94;Lo;0;L;;;;;N;;;;; +13F95;EGYPTIAN HIEROGLYPH-13F95;Lo;0;L;;;;;N;;;;; +13F96;EGYPTIAN HIEROGLYPH-13F96;Lo;0;L;;;;;N;;;;; +13F97;EGYPTIAN HIEROGLYPH-13F97;Lo;0;L;;;;;N;;;;; +13F98;EGYPTIAN HIEROGLYPH-13F98;Lo;0;L;;;;;N;;;;; +13F99;EGYPTIAN HIEROGLYPH-13F99;Lo;0;L;;;;;N;;;;; +13F9A;EGYPTIAN HIEROGLYPH-13F9A;Lo;0;L;;;;;N;;;;; +13F9B;EGYPTIAN HIEROGLYPH-13F9B;Lo;0;L;;;;;N;;;;; +13F9C;EGYPTIAN HIEROGLYPH-13F9C;Lo;0;L;;;;;N;;;;; +13F9D;EGYPTIAN HIEROGLYPH-13F9D;Lo;0;L;;;;;N;;;;; +13F9E;EGYPTIAN HIEROGLYPH-13F9E;Lo;0;L;;;;;N;;;;; +13F9F;EGYPTIAN HIEROGLYPH-13F9F;Lo;0;L;;;;;N;;;;; +13FA0;EGYPTIAN HIEROGLYPH-13FA0;Lo;0;L;;;;;N;;;;; +13FA1;EGYPTIAN HIEROGLYPH-13FA1;Lo;0;L;;;;;N;;;;; +13FA2;EGYPTIAN HIEROGLYPH-13FA2;Lo;0;L;;;;;N;;;;; +13FA3;EGYPTIAN HIEROGLYPH-13FA3;Lo;0;L;;;;;N;;;;; +13FA4;EGYPTIAN HIEROGLYPH-13FA4;Lo;0;L;;;;;N;;;;; +13FA5;EGYPTIAN HIEROGLYPH-13FA5;Lo;0;L;;;;;N;;;;; +13FA6;EGYPTIAN HIEROGLYPH-13FA6;Lo;0;L;;;;;N;;;;; +13FA7;EGYPTIAN HIEROGLYPH-13FA7;Lo;0;L;;;;;N;;;;; +13FA8;EGYPTIAN HIEROGLYPH-13FA8;Lo;0;L;;;;;N;;;;; +13FA9;EGYPTIAN HIEROGLYPH-13FA9;Lo;0;L;;;;;N;;;;; +13FAA;EGYPTIAN HIEROGLYPH-13FAA;Lo;0;L;;;;;N;;;;; +13FAB;EGYPTIAN HIEROGLYPH-13FAB;Lo;0;L;;;;;N;;;;; +13FAC;EGYPTIAN HIEROGLYPH-13FAC;Lo;0;L;;;;;N;;;;; +13FAD;EGYPTIAN HIEROGLYPH-13FAD;Lo;0;L;;;;;N;;;;; +13FAE;EGYPTIAN HIEROGLYPH-13FAE;Lo;0;L;;;;;N;;;;; +13FAF;EGYPTIAN HIEROGLYPH-13FAF;Lo;0;L;;;;;N;;;;; +13FB0;EGYPTIAN HIEROGLYPH-13FB0;Lo;0;L;;;;;N;;;;; +13FB1;EGYPTIAN HIEROGLYPH-13FB1;Lo;0;L;;;;;N;;;;; +13FB2;EGYPTIAN HIEROGLYPH-13FB2;Lo;0;L;;;;;N;;;;; +13FB3;EGYPTIAN HIEROGLYPH-13FB3;Lo;0;L;;;;;N;;;;; +13FB4;EGYPTIAN HIEROGLYPH-13FB4;Lo;0;L;;;;;N;;;;; +13FB5;EGYPTIAN HIEROGLYPH-13FB5;Lo;0;L;;;;;N;;;;; +13FB6;EGYPTIAN HIEROGLYPH-13FB6;Lo;0;L;;;;;N;;;;; +13FB7;EGYPTIAN HIEROGLYPH-13FB7;Lo;0;L;;;;;N;;;;; +13FB8;EGYPTIAN HIEROGLYPH-13FB8;Lo;0;L;;;;;N;;;;; +13FB9;EGYPTIAN HIEROGLYPH-13FB9;Lo;0;L;;;;;N;;;;; +13FBA;EGYPTIAN HIEROGLYPH-13FBA;Lo;0;L;;;;;N;;;;; +13FBB;EGYPTIAN HIEROGLYPH-13FBB;Lo;0;L;;;;;N;;;;; +13FBC;EGYPTIAN HIEROGLYPH-13FBC;Lo;0;L;;;;;N;;;;; +13FBD;EGYPTIAN HIEROGLYPH-13FBD;Lo;0;L;;;;;N;;;;; +13FBE;EGYPTIAN HIEROGLYPH-13FBE;Lo;0;L;;;;;N;;;;; +13FBF;EGYPTIAN HIEROGLYPH-13FBF;Lo;0;L;;;;;N;;;;; +13FC0;EGYPTIAN HIEROGLYPH-13FC0;Lo;0;L;;;;;N;;;;; +13FC1;EGYPTIAN HIEROGLYPH-13FC1;Lo;0;L;;;;;N;;;;; +13FC2;EGYPTIAN HIEROGLYPH-13FC2;Lo;0;L;;;;;N;;;;; +13FC3;EGYPTIAN HIEROGLYPH-13FC3;Lo;0;L;;;;;N;;;;; +13FC4;EGYPTIAN HIEROGLYPH-13FC4;Lo;0;L;;;;;N;;;;; +13FC5;EGYPTIAN HIEROGLYPH-13FC5;Lo;0;L;;;;;N;;;;; +13FC6;EGYPTIAN HIEROGLYPH-13FC6;Lo;0;L;;;;;N;;;;; +13FC7;EGYPTIAN HIEROGLYPH-13FC7;Lo;0;L;;;;;N;;;;; +13FC8;EGYPTIAN HIEROGLYPH-13FC8;Lo;0;L;;;;;N;;;;; +13FC9;EGYPTIAN HIEROGLYPH-13FC9;Lo;0;L;;;;;N;;;;; +13FCA;EGYPTIAN HIEROGLYPH-13FCA;Lo;0;L;;;;;N;;;;; +13FCB;EGYPTIAN HIEROGLYPH-13FCB;Lo;0;L;;;;;N;;;;; +13FCC;EGYPTIAN HIEROGLYPH-13FCC;Lo;0;L;;;;;N;;;;; +13FCD;EGYPTIAN HIEROGLYPH-13FCD;Lo;0;L;;;;;N;;;;; +13FCE;EGYPTIAN HIEROGLYPH-13FCE;Lo;0;L;;;;;N;;;;; +13FCF;EGYPTIAN HIEROGLYPH-13FCF;Lo;0;L;;;;;N;;;;; +13FD0;EGYPTIAN HIEROGLYPH-13FD0;Lo;0;L;;;;;N;;;;; +13FD1;EGYPTIAN HIEROGLYPH-13FD1;Lo;0;L;;;;;N;;;;; +13FD2;EGYPTIAN HIEROGLYPH-13FD2;Lo;0;L;;;;;N;;;;; +13FD3;EGYPTIAN HIEROGLYPH-13FD3;Lo;0;L;;;;;N;;;;; +13FD4;EGYPTIAN HIEROGLYPH-13FD4;Lo;0;L;;;;;N;;;;; +13FD5;EGYPTIAN HIEROGLYPH-13FD5;Lo;0;L;;;;;N;;;;; +13FD6;EGYPTIAN HIEROGLYPH-13FD6;Lo;0;L;;;;;N;;;;; +13FD7;EGYPTIAN HIEROGLYPH-13FD7;Lo;0;L;;;;;N;;;;; +13FD8;EGYPTIAN HIEROGLYPH-13FD8;Lo;0;L;;;;;N;;;;; +13FD9;EGYPTIAN HIEROGLYPH-13FD9;Lo;0;L;;;;;N;;;;; +13FDA;EGYPTIAN HIEROGLYPH-13FDA;Lo;0;L;;;;;N;;;;; +13FDB;EGYPTIAN HIEROGLYPH-13FDB;Lo;0;L;;;;;N;;;;; +13FDC;EGYPTIAN HIEROGLYPH-13FDC;Lo;0;L;;;;;N;;;;; +13FDD;EGYPTIAN HIEROGLYPH-13FDD;Lo;0;L;;;;;N;;;;; +13FDE;EGYPTIAN HIEROGLYPH-13FDE;Lo;0;L;;;;;N;;;;; +13FDF;EGYPTIAN HIEROGLYPH-13FDF;Lo;0;L;;;;;N;;;;; +13FE0;EGYPTIAN HIEROGLYPH-13FE0;Lo;0;L;;;;;N;;;;; +13FE1;EGYPTIAN HIEROGLYPH-13FE1;Lo;0;L;;;;;N;;;;; +13FE2;EGYPTIAN HIEROGLYPH-13FE2;Lo;0;L;;;;;N;;;;; +13FE3;EGYPTIAN HIEROGLYPH-13FE3;Lo;0;L;;;;;N;;;;; +13FE4;EGYPTIAN HIEROGLYPH-13FE4;Lo;0;L;;;;;N;;;;; +13FE5;EGYPTIAN HIEROGLYPH-13FE5;Lo;0;L;;;;;N;;;;; +13FE6;EGYPTIAN HIEROGLYPH-13FE6;Lo;0;L;;;;;N;;;;; +13FE7;EGYPTIAN HIEROGLYPH-13FE7;Lo;0;L;;;;;N;;;;; +13FE8;EGYPTIAN HIEROGLYPH-13FE8;Lo;0;L;;;;;N;;;;; +13FE9;EGYPTIAN HIEROGLYPH-13FE9;Lo;0;L;;;;;N;;;;; +13FEA;EGYPTIAN HIEROGLYPH-13FEA;Lo;0;L;;;;;N;;;;; +13FEB;EGYPTIAN HIEROGLYPH-13FEB;Lo;0;L;;;;;N;;;;; +13FEC;EGYPTIAN HIEROGLYPH-13FEC;Lo;0;L;;;;;N;;;;; +13FED;EGYPTIAN HIEROGLYPH-13FED;Lo;0;L;;;;;N;;;;; +13FEE;EGYPTIAN HIEROGLYPH-13FEE;Lo;0;L;;;;;N;;;;; +13FEF;EGYPTIAN HIEROGLYPH-13FEF;Lo;0;L;;;;;N;;;;; +13FF0;EGYPTIAN HIEROGLYPH-13FF0;Lo;0;L;;;;;N;;;;; +13FF1;EGYPTIAN HIEROGLYPH-13FF1;Lo;0;L;;;;;N;;;;; +13FF2;EGYPTIAN HIEROGLYPH-13FF2;Lo;0;L;;;;;N;;;;; +13FF3;EGYPTIAN HIEROGLYPH-13FF3;Lo;0;L;;;;;N;;;;; +13FF4;EGYPTIAN HIEROGLYPH-13FF4;Lo;0;L;;;;;N;;;;; +13FF5;EGYPTIAN HIEROGLYPH-13FF5;Lo;0;L;;;;;N;;;;; +13FF6;EGYPTIAN HIEROGLYPH-13FF6;Lo;0;L;;;;;N;;;;; +13FF7;EGYPTIAN HIEROGLYPH-13FF7;Lo;0;L;;;;;N;;;;; +13FF8;EGYPTIAN HIEROGLYPH-13FF8;Lo;0;L;;;;;N;;;;; +13FF9;EGYPTIAN HIEROGLYPH-13FF9;Lo;0;L;;;;;N;;;;; +13FFA;EGYPTIAN HIEROGLYPH-13FFA;Lo;0;L;;;;;N;;;;; +13FFB;EGYPTIAN HIEROGLYPH-13FFB;Lo;0;L;;;;;N;;;;; +13FFC;EGYPTIAN HIEROGLYPH-13FFC;Lo;0;L;;;;;N;;;;; +13FFD;EGYPTIAN HIEROGLYPH-13FFD;Lo;0;L;;;;;N;;;;; +13FFE;EGYPTIAN HIEROGLYPH-13FFE;Lo;0;L;;;;;N;;;;; +13FFF;EGYPTIAN HIEROGLYPH-13FFF;Lo;0;L;;;;;N;;;;; +14000;EGYPTIAN HIEROGLYPH-14000;Lo;0;L;;;;;N;;;;; +14001;EGYPTIAN HIEROGLYPH-14001;Lo;0;L;;;;;N;;;;; +14002;EGYPTIAN HIEROGLYPH-14002;Lo;0;L;;;;;N;;;;; +14003;EGYPTIAN HIEROGLYPH-14003;Lo;0;L;;;;;N;;;;; +14004;EGYPTIAN HIEROGLYPH-14004;Lo;0;L;;;;;N;;;;; +14005;EGYPTIAN HIEROGLYPH-14005;Lo;0;L;;;;;N;;;;; +14006;EGYPTIAN HIEROGLYPH-14006;Lo;0;L;;;;;N;;;;; +14007;EGYPTIAN HIEROGLYPH-14007;Lo;0;L;;;;;N;;;;; +14008;EGYPTIAN HIEROGLYPH-14008;Lo;0;L;;;;;N;;;;; +14009;EGYPTIAN HIEROGLYPH-14009;Lo;0;L;;;;;N;;;;; +1400A;EGYPTIAN HIEROGLYPH-1400A;Lo;0;L;;;;;N;;;;; +1400B;EGYPTIAN HIEROGLYPH-1400B;Lo;0;L;;;;;N;;;;; +1400C;EGYPTIAN HIEROGLYPH-1400C;Lo;0;L;;;;;N;;;;; +1400D;EGYPTIAN HIEROGLYPH-1400D;Lo;0;L;;;;;N;;;;; +1400E;EGYPTIAN HIEROGLYPH-1400E;Lo;0;L;;;;;N;;;;; +1400F;EGYPTIAN HIEROGLYPH-1400F;Lo;0;L;;;;;N;;;;; +14010;EGYPTIAN HIEROGLYPH-14010;Lo;0;L;;;;;N;;;;; +14011;EGYPTIAN HIEROGLYPH-14011;Lo;0;L;;;;;N;;;;; +14012;EGYPTIAN HIEROGLYPH-14012;Lo;0;L;;;;;N;;;;; +14013;EGYPTIAN HIEROGLYPH-14013;Lo;0;L;;;;;N;;;;; +14014;EGYPTIAN HIEROGLYPH-14014;Lo;0;L;;;;;N;;;;; +14015;EGYPTIAN HIEROGLYPH-14015;Lo;0;L;;;;;N;;;;; +14016;EGYPTIAN HIEROGLYPH-14016;Lo;0;L;;;;;N;;;;; +14017;EGYPTIAN HIEROGLYPH-14017;Lo;0;L;;;;;N;;;;; +14018;EGYPTIAN HIEROGLYPH-14018;Lo;0;L;;;;;N;;;;; +14019;EGYPTIAN HIEROGLYPH-14019;Lo;0;L;;;;;N;;;;; +1401A;EGYPTIAN HIEROGLYPH-1401A;Lo;0;L;;;;;N;;;;; +1401B;EGYPTIAN HIEROGLYPH-1401B;Lo;0;L;;;;;N;;;;; +1401C;EGYPTIAN HIEROGLYPH-1401C;Lo;0;L;;;;;N;;;;; +1401D;EGYPTIAN HIEROGLYPH-1401D;Lo;0;L;;;;;N;;;;; +1401E;EGYPTIAN HIEROGLYPH-1401E;Lo;0;L;;;;;N;;;;; +1401F;EGYPTIAN HIEROGLYPH-1401F;Lo;0;L;;;;;N;;;;; +14020;EGYPTIAN HIEROGLYPH-14020;Lo;0;L;;;;;N;;;;; +14021;EGYPTIAN HIEROGLYPH-14021;Lo;0;L;;;;;N;;;;; +14022;EGYPTIAN HIEROGLYPH-14022;Lo;0;L;;;;;N;;;;; +14023;EGYPTIAN HIEROGLYPH-14023;Lo;0;L;;;;;N;;;;; +14024;EGYPTIAN HIEROGLYPH-14024;Lo;0;L;;;;;N;;;;; +14025;EGYPTIAN HIEROGLYPH-14025;Lo;0;L;;;;;N;;;;; +14026;EGYPTIAN HIEROGLYPH-14026;Lo;0;L;;;;;N;;;;; +14027;EGYPTIAN HIEROGLYPH-14027;Lo;0;L;;;;;N;;;;; +14028;EGYPTIAN HIEROGLYPH-14028;Lo;0;L;;;;;N;;;;; +14029;EGYPTIAN HIEROGLYPH-14029;Lo;0;L;;;;;N;;;;; +1402A;EGYPTIAN HIEROGLYPH-1402A;Lo;0;L;;;;;N;;;;; +1402B;EGYPTIAN HIEROGLYPH-1402B;Lo;0;L;;;;;N;;;;; +1402C;EGYPTIAN HIEROGLYPH-1402C;Lo;0;L;;;;;N;;;;; +1402D;EGYPTIAN HIEROGLYPH-1402D;Lo;0;L;;;;;N;;;;; +1402E;EGYPTIAN HIEROGLYPH-1402E;Lo;0;L;;;;;N;;;;; +1402F;EGYPTIAN HIEROGLYPH-1402F;Lo;0;L;;;;;N;;;;; +14030;EGYPTIAN HIEROGLYPH-14030;Lo;0;L;;;;;N;;;;; +14031;EGYPTIAN HIEROGLYPH-14031;Lo;0;L;;;;;N;;;;; +14032;EGYPTIAN HIEROGLYPH-14032;Lo;0;L;;;;;N;;;;; +14033;EGYPTIAN HIEROGLYPH-14033;Lo;0;L;;;;;N;;;;; +14034;EGYPTIAN HIEROGLYPH-14034;Lo;0;L;;;;;N;;;;; +14035;EGYPTIAN HIEROGLYPH-14035;Lo;0;L;;;;;N;;;;; +14036;EGYPTIAN HIEROGLYPH-14036;Lo;0;L;;;;;N;;;;; +14037;EGYPTIAN HIEROGLYPH-14037;Lo;0;L;;;;;N;;;;; +14038;EGYPTIAN HIEROGLYPH-14038;Lo;0;L;;;;;N;;;;; +14039;EGYPTIAN HIEROGLYPH-14039;Lo;0;L;;;;;N;;;;; +1403A;EGYPTIAN HIEROGLYPH-1403A;Lo;0;L;;;;;N;;;;; +1403B;EGYPTIAN HIEROGLYPH-1403B;Lo;0;L;;;;;N;;;;; +1403C;EGYPTIAN HIEROGLYPH-1403C;Lo;0;L;;;;;N;;;;; +1403D;EGYPTIAN HIEROGLYPH-1403D;Lo;0;L;;;;;N;;;;; +1403E;EGYPTIAN HIEROGLYPH-1403E;Lo;0;L;;;;;N;;;;; +1403F;EGYPTIAN HIEROGLYPH-1403F;Lo;0;L;;;;;N;;;;; +14040;EGYPTIAN HIEROGLYPH-14040;Lo;0;L;;;;;N;;;;; +14041;EGYPTIAN HIEROGLYPH-14041;Lo;0;L;;;;;N;;;;; +14042;EGYPTIAN HIEROGLYPH-14042;Lo;0;L;;;;;N;;;;; +14043;EGYPTIAN HIEROGLYPH-14043;Lo;0;L;;;;;N;;;;; +14044;EGYPTIAN HIEROGLYPH-14044;Lo;0;L;;;;;N;;;;; +14045;EGYPTIAN HIEROGLYPH-14045;Lo;0;L;;;;;N;;;;; +14046;EGYPTIAN HIEROGLYPH-14046;Lo;0;L;;;;;N;;;;; +14047;EGYPTIAN HIEROGLYPH-14047;Lo;0;L;;;;;N;;;;; +14048;EGYPTIAN HIEROGLYPH-14048;Lo;0;L;;;;;N;;;;; +14049;EGYPTIAN HIEROGLYPH-14049;Lo;0;L;;;;;N;;;;; +1404A;EGYPTIAN HIEROGLYPH-1404A;Lo;0;L;;;;;N;;;;; +1404B;EGYPTIAN HIEROGLYPH-1404B;Lo;0;L;;;;;N;;;;; +1404C;EGYPTIAN HIEROGLYPH-1404C;Lo;0;L;;;;;N;;;;; +1404D;EGYPTIAN HIEROGLYPH-1404D;Lo;0;L;;;;;N;;;;; +1404E;EGYPTIAN HIEROGLYPH-1404E;Lo;0;L;;;;;N;;;;; +1404F;EGYPTIAN HIEROGLYPH-1404F;Lo;0;L;;;;;N;;;;; +14050;EGYPTIAN HIEROGLYPH-14050;Lo;0;L;;;;;N;;;;; +14051;EGYPTIAN HIEROGLYPH-14051;Lo;0;L;;;;;N;;;;; +14052;EGYPTIAN HIEROGLYPH-14052;Lo;0;L;;;;;N;;;;; +14053;EGYPTIAN HIEROGLYPH-14053;Lo;0;L;;;;;N;;;;; +14054;EGYPTIAN HIEROGLYPH-14054;Lo;0;L;;;;;N;;;;; +14055;EGYPTIAN HIEROGLYPH-14055;Lo;0;L;;;;;N;;;;; +14056;EGYPTIAN HIEROGLYPH-14056;Lo;0;L;;;;;N;;;;; +14057;EGYPTIAN HIEROGLYPH-14057;Lo;0;L;;;;;N;;;;; +14058;EGYPTIAN HIEROGLYPH-14058;Lo;0;L;;;;;N;;;;; +14059;EGYPTIAN HIEROGLYPH-14059;Lo;0;L;;;;;N;;;;; +1405A;EGYPTIAN HIEROGLYPH-1405A;Lo;0;L;;;;;N;;;;; +1405B;EGYPTIAN HIEROGLYPH-1405B;Lo;0;L;;;;;N;;;;; +1405C;EGYPTIAN HIEROGLYPH-1405C;Lo;0;L;;;;;N;;;;; +1405D;EGYPTIAN HIEROGLYPH-1405D;Lo;0;L;;;;;N;;;;; +1405E;EGYPTIAN HIEROGLYPH-1405E;Lo;0;L;;;;;N;;;;; +1405F;EGYPTIAN HIEROGLYPH-1405F;Lo;0;L;;;;;N;;;;; +14060;EGYPTIAN HIEROGLYPH-14060;Lo;0;L;;;;;N;;;;; +14061;EGYPTIAN HIEROGLYPH-14061;Lo;0;L;;;;;N;;;;; +14062;EGYPTIAN HIEROGLYPH-14062;Lo;0;L;;;;;N;;;;; +14063;EGYPTIAN HIEROGLYPH-14063;Lo;0;L;;;;;N;;;;; +14064;EGYPTIAN HIEROGLYPH-14064;Lo;0;L;;;;;N;;;;; +14065;EGYPTIAN HIEROGLYPH-14065;Lo;0;L;;;;;N;;;;; +14066;EGYPTIAN HIEROGLYPH-14066;Lo;0;L;;;;;N;;;;; +14067;EGYPTIAN HIEROGLYPH-14067;Lo;0;L;;;;;N;;;;; +14068;EGYPTIAN HIEROGLYPH-14068;Lo;0;L;;;;;N;;;;; +14069;EGYPTIAN HIEROGLYPH-14069;Lo;0;L;;;;;N;;;;; +1406A;EGYPTIAN HIEROGLYPH-1406A;Lo;0;L;;;;;N;;;;; +1406B;EGYPTIAN HIEROGLYPH-1406B;Lo;0;L;;;;;N;;;;; +1406C;EGYPTIAN HIEROGLYPH-1406C;Lo;0;L;;;;;N;;;;; +1406D;EGYPTIAN HIEROGLYPH-1406D;Lo;0;L;;;;;N;;;;; +1406E;EGYPTIAN HIEROGLYPH-1406E;Lo;0;L;;;;;N;;;;; +1406F;EGYPTIAN HIEROGLYPH-1406F;Lo;0;L;;;;;N;;;;; +14070;EGYPTIAN HIEROGLYPH-14070;Lo;0;L;;;;;N;;;;; +14071;EGYPTIAN HIEROGLYPH-14071;Lo;0;L;;;;;N;;;;; +14072;EGYPTIAN HIEROGLYPH-14072;Lo;0;L;;;;;N;;;;; +14073;EGYPTIAN HIEROGLYPH-14073;Lo;0;L;;;;;N;;;;; +14074;EGYPTIAN HIEROGLYPH-14074;Lo;0;L;;;;;N;;;;; +14075;EGYPTIAN HIEROGLYPH-14075;Lo;0;L;;;;;N;;;;; +14076;EGYPTIAN HIEROGLYPH-14076;Lo;0;L;;;;;N;;;;; +14077;EGYPTIAN HIEROGLYPH-14077;Lo;0;L;;;;;N;;;;; +14078;EGYPTIAN HIEROGLYPH-14078;Lo;0;L;;;;;N;;;;; +14079;EGYPTIAN HIEROGLYPH-14079;Lo;0;L;;;;;N;;;;; +1407A;EGYPTIAN HIEROGLYPH-1407A;Lo;0;L;;;;;N;;;;; +1407B;EGYPTIAN HIEROGLYPH-1407B;Lo;0;L;;;;;N;;;;; +1407C;EGYPTIAN HIEROGLYPH-1407C;Lo;0;L;;;;;N;;;;; +1407D;EGYPTIAN HIEROGLYPH-1407D;Lo;0;L;;;;;N;;;;; +1407E;EGYPTIAN HIEROGLYPH-1407E;Lo;0;L;;;;;N;;;;; +1407F;EGYPTIAN HIEROGLYPH-1407F;Lo;0;L;;;;;N;;;;; +14080;EGYPTIAN HIEROGLYPH-14080;Lo;0;L;;;;;N;;;;; +14081;EGYPTIAN HIEROGLYPH-14081;Lo;0;L;;;;;N;;;;; +14082;EGYPTIAN HIEROGLYPH-14082;Lo;0;L;;;;;N;;;;; +14083;EGYPTIAN HIEROGLYPH-14083;Lo;0;L;;;;;N;;;;; +14084;EGYPTIAN HIEROGLYPH-14084;Lo;0;L;;;;;N;;;;; +14085;EGYPTIAN HIEROGLYPH-14085;Lo;0;L;;;;;N;;;;; +14086;EGYPTIAN HIEROGLYPH-14086;Lo;0;L;;;;;N;;;;; +14087;EGYPTIAN HIEROGLYPH-14087;Lo;0;L;;;;;N;;;;; +14088;EGYPTIAN HIEROGLYPH-14088;Lo;0;L;;;;;N;;;;; +14089;EGYPTIAN HIEROGLYPH-14089;Lo;0;L;;;;;N;;;;; +1408A;EGYPTIAN HIEROGLYPH-1408A;Lo;0;L;;;;;N;;;;; +1408B;EGYPTIAN HIEROGLYPH-1408B;Lo;0;L;;;;;N;;;;; +1408C;EGYPTIAN HIEROGLYPH-1408C;Lo;0;L;;;;;N;;;;; +1408D;EGYPTIAN HIEROGLYPH-1408D;Lo;0;L;;;;;N;;;;; +1408E;EGYPTIAN HIEROGLYPH-1408E;Lo;0;L;;;;;N;;;;; +1408F;EGYPTIAN HIEROGLYPH-1408F;Lo;0;L;;;;;N;;;;; +14090;EGYPTIAN HIEROGLYPH-14090;Lo;0;L;;;;;N;;;;; +14091;EGYPTIAN HIEROGLYPH-14091;Lo;0;L;;;;;N;;;;; +14092;EGYPTIAN HIEROGLYPH-14092;Lo;0;L;;;;;N;;;;; +14093;EGYPTIAN HIEROGLYPH-14093;Lo;0;L;;;;;N;;;;; +14094;EGYPTIAN HIEROGLYPH-14094;Lo;0;L;;;;;N;;;;; +14095;EGYPTIAN HIEROGLYPH-14095;Lo;0;L;;;;;N;;;;; +14096;EGYPTIAN HIEROGLYPH-14096;Lo;0;L;;;;;N;;;;; +14097;EGYPTIAN HIEROGLYPH-14097;Lo;0;L;;;;;N;;;;; +14098;EGYPTIAN HIEROGLYPH-14098;Lo;0;L;;;;;N;;;;; +14099;EGYPTIAN HIEROGLYPH-14099;Lo;0;L;;;;;N;;;;; +1409A;EGYPTIAN HIEROGLYPH-1409A;Lo;0;L;;;;;N;;;;; +1409B;EGYPTIAN HIEROGLYPH-1409B;Lo;0;L;;;;;N;;;;; +1409C;EGYPTIAN HIEROGLYPH-1409C;Lo;0;L;;;;;N;;;;; +1409D;EGYPTIAN HIEROGLYPH-1409D;Lo;0;L;;;;;N;;;;; +1409E;EGYPTIAN HIEROGLYPH-1409E;Lo;0;L;;;;;N;;;;; +1409F;EGYPTIAN HIEROGLYPH-1409F;Lo;0;L;;;;;N;;;;; +140A0;EGYPTIAN HIEROGLYPH-140A0;Lo;0;L;;;;;N;;;;; +140A1;EGYPTIAN HIEROGLYPH-140A1;Lo;0;L;;;;;N;;;;; +140A2;EGYPTIAN HIEROGLYPH-140A2;Lo;0;L;;;;;N;;;;; +140A3;EGYPTIAN HIEROGLYPH-140A3;Lo;0;L;;;;;N;;;;; +140A4;EGYPTIAN HIEROGLYPH-140A4;Lo;0;L;;;;;N;;;;; +140A5;EGYPTIAN HIEROGLYPH-140A5;Lo;0;L;;;;;N;;;;; +140A6;EGYPTIAN HIEROGLYPH-140A6;Lo;0;L;;;;;N;;;;; +140A7;EGYPTIAN HIEROGLYPH-140A7;Lo;0;L;;;;;N;;;;; +140A8;EGYPTIAN HIEROGLYPH-140A8;Lo;0;L;;;;;N;;;;; +140A9;EGYPTIAN HIEROGLYPH-140A9;Lo;0;L;;;;;N;;;;; +140AA;EGYPTIAN HIEROGLYPH-140AA;Lo;0;L;;;;;N;;;;; +140AB;EGYPTIAN HIEROGLYPH-140AB;Lo;0;L;;;;;N;;;;; +140AC;EGYPTIAN HIEROGLYPH-140AC;Lo;0;L;;;;;N;;;;; +140AD;EGYPTIAN HIEROGLYPH-140AD;Lo;0;L;;;;;N;;;;; +140AE;EGYPTIAN HIEROGLYPH-140AE;Lo;0;L;;;;;N;;;;; +140AF;EGYPTIAN HIEROGLYPH-140AF;Lo;0;L;;;;;N;;;;; +140B0;EGYPTIAN HIEROGLYPH-140B0;Lo;0;L;;;;;N;;;;; +140B1;EGYPTIAN HIEROGLYPH-140B1;Lo;0;L;;;;;N;;;;; +140B2;EGYPTIAN HIEROGLYPH-140B2;Lo;0;L;;;;;N;;;;; +140B3;EGYPTIAN HIEROGLYPH-140B3;Lo;0;L;;;;;N;;;;; +140B4;EGYPTIAN HIEROGLYPH-140B4;Lo;0;L;;;;;N;;;;; +140B5;EGYPTIAN HIEROGLYPH-140B5;Lo;0;L;;;;;N;;;;; +140B6;EGYPTIAN HIEROGLYPH-140B6;Lo;0;L;;;;;N;;;;; +140B7;EGYPTIAN HIEROGLYPH-140B7;Lo;0;L;;;;;N;;;;; +140B8;EGYPTIAN HIEROGLYPH-140B8;Lo;0;L;;;;;N;;;;; +140B9;EGYPTIAN HIEROGLYPH-140B9;Lo;0;L;;;;;N;;;;; +140BA;EGYPTIAN HIEROGLYPH-140BA;Lo;0;L;;;;;N;;;;; +140BB;EGYPTIAN HIEROGLYPH-140BB;Lo;0;L;;;;;N;;;;; +140BC;EGYPTIAN HIEROGLYPH-140BC;Lo;0;L;;;;;N;;;;; +140BD;EGYPTIAN HIEROGLYPH-140BD;Lo;0;L;;;;;N;;;;; +140BE;EGYPTIAN HIEROGLYPH-140BE;Lo;0;L;;;;;N;;;;; +140BF;EGYPTIAN HIEROGLYPH-140BF;Lo;0;L;;;;;N;;;;; +140C0;EGYPTIAN HIEROGLYPH-140C0;Lo;0;L;;;;;N;;;;; +140C1;EGYPTIAN HIEROGLYPH-140C1;Lo;0;L;;;;;N;;;;; +140C2;EGYPTIAN HIEROGLYPH-140C2;Lo;0;L;;;;;N;;;;; +140C3;EGYPTIAN HIEROGLYPH-140C3;Lo;0;L;;;;;N;;;;; +140C4;EGYPTIAN HIEROGLYPH-140C4;Lo;0;L;;;;;N;;;;; +140C5;EGYPTIAN HIEROGLYPH-140C5;Lo;0;L;;;;;N;;;;; +140C6;EGYPTIAN HIEROGLYPH-140C6;Lo;0;L;;;;;N;;;;; +140C7;EGYPTIAN HIEROGLYPH-140C7;Lo;0;L;;;;;N;;;;; +140C8;EGYPTIAN HIEROGLYPH-140C8;Lo;0;L;;;;;N;;;;; +140C9;EGYPTIAN HIEROGLYPH-140C9;Lo;0;L;;;;;N;;;;; +140CA;EGYPTIAN HIEROGLYPH-140CA;Lo;0;L;;;;;N;;;;; +140CB;EGYPTIAN HIEROGLYPH-140CB;Lo;0;L;;;;;N;;;;; +140CC;EGYPTIAN HIEROGLYPH-140CC;Lo;0;L;;;;;N;;;;; +140CD;EGYPTIAN HIEROGLYPH-140CD;Lo;0;L;;;;;N;;;;; +140CE;EGYPTIAN HIEROGLYPH-140CE;Lo;0;L;;;;;N;;;;; +140CF;EGYPTIAN HIEROGLYPH-140CF;Lo;0;L;;;;;N;;;;; +140D0;EGYPTIAN HIEROGLYPH-140D0;Lo;0;L;;;;;N;;;;; +140D1;EGYPTIAN HIEROGLYPH-140D1;Lo;0;L;;;;;N;;;;; +140D2;EGYPTIAN HIEROGLYPH-140D2;Lo;0;L;;;;;N;;;;; +140D3;EGYPTIAN HIEROGLYPH-140D3;Lo;0;L;;;;;N;;;;; +140D4;EGYPTIAN HIEROGLYPH-140D4;Lo;0;L;;;;;N;;;;; +140D5;EGYPTIAN HIEROGLYPH-140D5;Lo;0;L;;;;;N;;;;; +140D6;EGYPTIAN HIEROGLYPH-140D6;Lo;0;L;;;;;N;;;;; +140D7;EGYPTIAN HIEROGLYPH-140D7;Lo;0;L;;;;;N;;;;; +140D8;EGYPTIAN HIEROGLYPH-140D8;Lo;0;L;;;;;N;;;;; +140D9;EGYPTIAN HIEROGLYPH-140D9;Lo;0;L;;;;;N;;;;; +140DA;EGYPTIAN HIEROGLYPH-140DA;Lo;0;L;;;;;N;;;;; +140DB;EGYPTIAN HIEROGLYPH-140DB;Lo;0;L;;;;;N;;;;; +140DC;EGYPTIAN HIEROGLYPH-140DC;Lo;0;L;;;;;N;;;;; +140DD;EGYPTIAN HIEROGLYPH-140DD;Lo;0;L;;;;;N;;;;; +140DE;EGYPTIAN HIEROGLYPH-140DE;Lo;0;L;;;;;N;;;;; +140DF;EGYPTIAN HIEROGLYPH-140DF;Lo;0;L;;;;;N;;;;; +140E0;EGYPTIAN HIEROGLYPH-140E0;Lo;0;L;;;;;N;;;;; +140E1;EGYPTIAN HIEROGLYPH-140E1;Lo;0;L;;;;;N;;;;; +140E2;EGYPTIAN HIEROGLYPH-140E2;Lo;0;L;;;;;N;;;;; +140E3;EGYPTIAN HIEROGLYPH-140E3;Lo;0;L;;;;;N;;;;; +140E4;EGYPTIAN HIEROGLYPH-140E4;Lo;0;L;;;;;N;;;;; +140E5;EGYPTIAN HIEROGLYPH-140E5;Lo;0;L;;;;;N;;;;; +140E6;EGYPTIAN HIEROGLYPH-140E6;Lo;0;L;;;;;N;;;;; +140E7;EGYPTIAN HIEROGLYPH-140E7;Lo;0;L;;;;;N;;;;; +140E8;EGYPTIAN HIEROGLYPH-140E8;Lo;0;L;;;;;N;;;;; +140E9;EGYPTIAN HIEROGLYPH-140E9;Lo;0;L;;;;;N;;;;; +140EA;EGYPTIAN HIEROGLYPH-140EA;Lo;0;L;;;;;N;;;;; +140EB;EGYPTIAN HIEROGLYPH-140EB;Lo;0;L;;;;;N;;;;; +140EC;EGYPTIAN HIEROGLYPH-140EC;Lo;0;L;;;;;N;;;;; +140ED;EGYPTIAN HIEROGLYPH-140ED;Lo;0;L;;;;;N;;;;; +140EE;EGYPTIAN HIEROGLYPH-140EE;Lo;0;L;;;;;N;;;;; +140EF;EGYPTIAN HIEROGLYPH-140EF;Lo;0;L;;;;;N;;;;; +140F0;EGYPTIAN HIEROGLYPH-140F0;Lo;0;L;;;;;N;;;;; +140F1;EGYPTIAN HIEROGLYPH-140F1;Lo;0;L;;;;;N;;;;; +140F2;EGYPTIAN HIEROGLYPH-140F2;Lo;0;L;;;;;N;;;;; +140F3;EGYPTIAN HIEROGLYPH-140F3;Lo;0;L;;;;;N;;;;; +140F4;EGYPTIAN HIEROGLYPH-140F4;Lo;0;L;;;;;N;;;;; +140F5;EGYPTIAN HIEROGLYPH-140F5;Lo;0;L;;;;;N;;;;; +140F6;EGYPTIAN HIEROGLYPH-140F6;Lo;0;L;;;;;N;;;;; +140F7;EGYPTIAN HIEROGLYPH-140F7;Lo;0;L;;;;;N;;;;; +140F8;EGYPTIAN HIEROGLYPH-140F8;Lo;0;L;;;;;N;;;;; +140F9;EGYPTIAN HIEROGLYPH-140F9;Lo;0;L;;;;;N;;;;; +140FA;EGYPTIAN HIEROGLYPH-140FA;Lo;0;L;;;;;N;;;;; +140FB;EGYPTIAN HIEROGLYPH-140FB;Lo;0;L;;;;;N;;;;; +140FC;EGYPTIAN HIEROGLYPH-140FC;Lo;0;L;;;;;N;;;;; +140FD;EGYPTIAN HIEROGLYPH-140FD;Lo;0;L;;;;;N;;;;; +140FE;EGYPTIAN HIEROGLYPH-140FE;Lo;0;L;;;;;N;;;;; +140FF;EGYPTIAN HIEROGLYPH-140FF;Lo;0;L;;;;;N;;;;; +14100;EGYPTIAN HIEROGLYPH-14100;Lo;0;L;;;;;N;;;;; +14101;EGYPTIAN HIEROGLYPH-14101;Lo;0;L;;;;;N;;;;; +14102;EGYPTIAN HIEROGLYPH-14102;Lo;0;L;;;;;N;;;;; +14103;EGYPTIAN HIEROGLYPH-14103;Lo;0;L;;;;;N;;;;; +14104;EGYPTIAN HIEROGLYPH-14104;Lo;0;L;;;;;N;;;;; +14105;EGYPTIAN HIEROGLYPH-14105;Lo;0;L;;;;;N;;;;; +14106;EGYPTIAN HIEROGLYPH-14106;Lo;0;L;;;;;N;;;;; +14107;EGYPTIAN HIEROGLYPH-14107;Lo;0;L;;;;;N;;;;; +14108;EGYPTIAN HIEROGLYPH-14108;Lo;0;L;;;;;N;;;;; +14109;EGYPTIAN HIEROGLYPH-14109;Lo;0;L;;;;;N;;;;; +1410A;EGYPTIAN HIEROGLYPH-1410A;Lo;0;L;;;;;N;;;;; +1410B;EGYPTIAN HIEROGLYPH-1410B;Lo;0;L;;;;;N;;;;; +1410C;EGYPTIAN HIEROGLYPH-1410C;Lo;0;L;;;;;N;;;;; +1410D;EGYPTIAN HIEROGLYPH-1410D;Lo;0;L;;;;;N;;;;; +1410E;EGYPTIAN HIEROGLYPH-1410E;Lo;0;L;;;;;N;;;;; +1410F;EGYPTIAN HIEROGLYPH-1410F;Lo;0;L;;;;;N;;;;; +14110;EGYPTIAN HIEROGLYPH-14110;Lo;0;L;;;;;N;;;;; +14111;EGYPTIAN HIEROGLYPH-14111;Lo;0;L;;;;;N;;;;; +14112;EGYPTIAN HIEROGLYPH-14112;Lo;0;L;;;;;N;;;;; +14113;EGYPTIAN HIEROGLYPH-14113;Lo;0;L;;;;;N;;;;; +14114;EGYPTIAN HIEROGLYPH-14114;Lo;0;L;;;;;N;;;;; +14115;EGYPTIAN HIEROGLYPH-14115;Lo;0;L;;;;;N;;;;; +14116;EGYPTIAN HIEROGLYPH-14116;Lo;0;L;;;;;N;;;;; +14117;EGYPTIAN HIEROGLYPH-14117;Lo;0;L;;;;;N;;;;; +14118;EGYPTIAN HIEROGLYPH-14118;Lo;0;L;;;;;N;;;;; +14119;EGYPTIAN HIEROGLYPH-14119;Lo;0;L;;;;;N;;;;; +1411A;EGYPTIAN HIEROGLYPH-1411A;Lo;0;L;;;;;N;;;;; +1411B;EGYPTIAN HIEROGLYPH-1411B;Lo;0;L;;;;;N;;;;; +1411C;EGYPTIAN HIEROGLYPH-1411C;Lo;0;L;;;;;N;;;;; +1411D;EGYPTIAN HIEROGLYPH-1411D;Lo;0;L;;;;;N;;;;; +1411E;EGYPTIAN HIEROGLYPH-1411E;Lo;0;L;;;;;N;;;;; +1411F;EGYPTIAN HIEROGLYPH-1411F;Lo;0;L;;;;;N;;;;; +14120;EGYPTIAN HIEROGLYPH-14120;Lo;0;L;;;;;N;;;;; +14121;EGYPTIAN HIEROGLYPH-14121;Lo;0;L;;;;;N;;;;; +14122;EGYPTIAN HIEROGLYPH-14122;Lo;0;L;;;;;N;;;;; +14123;EGYPTIAN HIEROGLYPH-14123;Lo;0;L;;;;;N;;;;; +14124;EGYPTIAN HIEROGLYPH-14124;Lo;0;L;;;;;N;;;;; +14125;EGYPTIAN HIEROGLYPH-14125;Lo;0;L;;;;;N;;;;; +14126;EGYPTIAN HIEROGLYPH-14126;Lo;0;L;;;;;N;;;;; +14127;EGYPTIAN HIEROGLYPH-14127;Lo;0;L;;;;;N;;;;; +14128;EGYPTIAN HIEROGLYPH-14128;Lo;0;L;;;;;N;;;;; +14129;EGYPTIAN HIEROGLYPH-14129;Lo;0;L;;;;;N;;;;; +1412A;EGYPTIAN HIEROGLYPH-1412A;Lo;0;L;;;;;N;;;;; +1412B;EGYPTIAN HIEROGLYPH-1412B;Lo;0;L;;;;;N;;;;; +1412C;EGYPTIAN HIEROGLYPH-1412C;Lo;0;L;;;;;N;;;;; +1412D;EGYPTIAN HIEROGLYPH-1412D;Lo;0;L;;;;;N;;;;; +1412E;EGYPTIAN HIEROGLYPH-1412E;Lo;0;L;;;;;N;;;;; +1412F;EGYPTIAN HIEROGLYPH-1412F;Lo;0;L;;;;;N;;;;; +14130;EGYPTIAN HIEROGLYPH-14130;Lo;0;L;;;;;N;;;;; +14131;EGYPTIAN HIEROGLYPH-14131;Lo;0;L;;;;;N;;;;; +14132;EGYPTIAN HIEROGLYPH-14132;Lo;0;L;;;;;N;;;;; +14133;EGYPTIAN HIEROGLYPH-14133;Lo;0;L;;;;;N;;;;; +14134;EGYPTIAN HIEROGLYPH-14134;Lo;0;L;;;;;N;;;;; +14135;EGYPTIAN HIEROGLYPH-14135;Lo;0;L;;;;;N;;;;; +14136;EGYPTIAN HIEROGLYPH-14136;Lo;0;L;;;;;N;;;;; +14137;EGYPTIAN HIEROGLYPH-14137;Lo;0;L;;;;;N;;;;; +14138;EGYPTIAN HIEROGLYPH-14138;Lo;0;L;;;;;N;;;;; +14139;EGYPTIAN HIEROGLYPH-14139;Lo;0;L;;;;;N;;;;; +1413A;EGYPTIAN HIEROGLYPH-1413A;Lo;0;L;;;;;N;;;;; +1413B;EGYPTIAN HIEROGLYPH-1413B;Lo;0;L;;;;;N;;;;; +1413C;EGYPTIAN HIEROGLYPH-1413C;Lo;0;L;;;;;N;;;;; +1413D;EGYPTIAN HIEROGLYPH-1413D;Lo;0;L;;;;;N;;;;; +1413E;EGYPTIAN HIEROGLYPH-1413E;Lo;0;L;;;;;N;;;;; +1413F;EGYPTIAN HIEROGLYPH-1413F;Lo;0;L;;;;;N;;;;; +14140;EGYPTIAN HIEROGLYPH-14140;Lo;0;L;;;;;N;;;;; +14141;EGYPTIAN HIEROGLYPH-14141;Lo;0;L;;;;;N;;;;; +14142;EGYPTIAN HIEROGLYPH-14142;Lo;0;L;;;;;N;;;;; +14143;EGYPTIAN HIEROGLYPH-14143;Lo;0;L;;;;;N;;;;; +14144;EGYPTIAN HIEROGLYPH-14144;Lo;0;L;;;;;N;;;;; +14145;EGYPTIAN HIEROGLYPH-14145;Lo;0;L;;;;;N;;;;; +14146;EGYPTIAN HIEROGLYPH-14146;Lo;0;L;;;;;N;;;;; +14147;EGYPTIAN HIEROGLYPH-14147;Lo;0;L;;;;;N;;;;; +14148;EGYPTIAN HIEROGLYPH-14148;Lo;0;L;;;;;N;;;;; +14149;EGYPTIAN HIEROGLYPH-14149;Lo;0;L;;;;;N;;;;; +1414A;EGYPTIAN HIEROGLYPH-1414A;Lo;0;L;;;;;N;;;;; +1414B;EGYPTIAN HIEROGLYPH-1414B;Lo;0;L;;;;;N;;;;; +1414C;EGYPTIAN HIEROGLYPH-1414C;Lo;0;L;;;;;N;;;;; +1414D;EGYPTIAN HIEROGLYPH-1414D;Lo;0;L;;;;;N;;;;; +1414E;EGYPTIAN HIEROGLYPH-1414E;Lo;0;L;;;;;N;;;;; +1414F;EGYPTIAN HIEROGLYPH-1414F;Lo;0;L;;;;;N;;;;; +14150;EGYPTIAN HIEROGLYPH-14150;Lo;0;L;;;;;N;;;;; +14151;EGYPTIAN HIEROGLYPH-14151;Lo;0;L;;;;;N;;;;; +14152;EGYPTIAN HIEROGLYPH-14152;Lo;0;L;;;;;N;;;;; +14153;EGYPTIAN HIEROGLYPH-14153;Lo;0;L;;;;;N;;;;; +14154;EGYPTIAN HIEROGLYPH-14154;Lo;0;L;;;;;N;;;;; +14155;EGYPTIAN HIEROGLYPH-14155;Lo;0;L;;;;;N;;;;; +14156;EGYPTIAN HIEROGLYPH-14156;Lo;0;L;;;;;N;;;;; +14157;EGYPTIAN HIEROGLYPH-14157;Lo;0;L;;;;;N;;;;; +14158;EGYPTIAN HIEROGLYPH-14158;Lo;0;L;;;;;N;;;;; +14159;EGYPTIAN HIEROGLYPH-14159;Lo;0;L;;;;;N;;;;; +1415A;EGYPTIAN HIEROGLYPH-1415A;Lo;0;L;;;;;N;;;;; +1415B;EGYPTIAN HIEROGLYPH-1415B;Lo;0;L;;;;;N;;;;; +1415C;EGYPTIAN HIEROGLYPH-1415C;Lo;0;L;;;;;N;;;;; +1415D;EGYPTIAN HIEROGLYPH-1415D;Lo;0;L;;;;;N;;;;; +1415E;EGYPTIAN HIEROGLYPH-1415E;Lo;0;L;;;;;N;;;;; +1415F;EGYPTIAN HIEROGLYPH-1415F;Lo;0;L;;;;;N;;;;; +14160;EGYPTIAN HIEROGLYPH-14160;Lo;0;L;;;;;N;;;;; +14161;EGYPTIAN HIEROGLYPH-14161;Lo;0;L;;;;;N;;;;; +14162;EGYPTIAN HIEROGLYPH-14162;Lo;0;L;;;;;N;;;;; +14163;EGYPTIAN HIEROGLYPH-14163;Lo;0;L;;;;;N;;;;; +14164;EGYPTIAN HIEROGLYPH-14164;Lo;0;L;;;;;N;;;;; +14165;EGYPTIAN HIEROGLYPH-14165;Lo;0;L;;;;;N;;;;; +14166;EGYPTIAN HIEROGLYPH-14166;Lo;0;L;;;;;N;;;;; +14167;EGYPTIAN HIEROGLYPH-14167;Lo;0;L;;;;;N;;;;; +14168;EGYPTIAN HIEROGLYPH-14168;Lo;0;L;;;;;N;;;;; +14169;EGYPTIAN HIEROGLYPH-14169;Lo;0;L;;;;;N;;;;; +1416A;EGYPTIAN HIEROGLYPH-1416A;Lo;0;L;;;;;N;;;;; +1416B;EGYPTIAN HIEROGLYPH-1416B;Lo;0;L;;;;;N;;;;; +1416C;EGYPTIAN HIEROGLYPH-1416C;Lo;0;L;;;;;N;;;;; +1416D;EGYPTIAN HIEROGLYPH-1416D;Lo;0;L;;;;;N;;;;; +1416E;EGYPTIAN HIEROGLYPH-1416E;Lo;0;L;;;;;N;;;;; +1416F;EGYPTIAN HIEROGLYPH-1416F;Lo;0;L;;;;;N;;;;; +14170;EGYPTIAN HIEROGLYPH-14170;Lo;0;L;;;;;N;;;;; +14171;EGYPTIAN HIEROGLYPH-14171;Lo;0;L;;;;;N;;;;; +14172;EGYPTIAN HIEROGLYPH-14172;Lo;0;L;;;;;N;;;;; +14173;EGYPTIAN HIEROGLYPH-14173;Lo;0;L;;;;;N;;;;; +14174;EGYPTIAN HIEROGLYPH-14174;Lo;0;L;;;;;N;;;;; +14175;EGYPTIAN HIEROGLYPH-14175;Lo;0;L;;;;;N;;;;; +14176;EGYPTIAN HIEROGLYPH-14176;Lo;0;L;;;;;N;;;;; +14177;EGYPTIAN HIEROGLYPH-14177;Lo;0;L;;;;;N;;;;; +14178;EGYPTIAN HIEROGLYPH-14178;Lo;0;L;;;;;N;;;;; +14179;EGYPTIAN HIEROGLYPH-14179;Lo;0;L;;;;;N;;;;; +1417A;EGYPTIAN HIEROGLYPH-1417A;Lo;0;L;;;;;N;;;;; +1417B;EGYPTIAN HIEROGLYPH-1417B;Lo;0;L;;;;;N;;;;; +1417C;EGYPTIAN HIEROGLYPH-1417C;Lo;0;L;;;;;N;;;;; +1417D;EGYPTIAN HIEROGLYPH-1417D;Lo;0;L;;;;;N;;;;; +1417E;EGYPTIAN HIEROGLYPH-1417E;Lo;0;L;;;;;N;;;;; +1417F;EGYPTIAN HIEROGLYPH-1417F;Lo;0;L;;;;;N;;;;; +14180;EGYPTIAN HIEROGLYPH-14180;Lo;0;L;;;;;N;;;;; +14181;EGYPTIAN HIEROGLYPH-14181;Lo;0;L;;;;;N;;;;; +14182;EGYPTIAN HIEROGLYPH-14182;Lo;0;L;;;;;N;;;;; +14183;EGYPTIAN HIEROGLYPH-14183;Lo;0;L;;;;;N;;;;; +14184;EGYPTIAN HIEROGLYPH-14184;Lo;0;L;;;;;N;;;;; +14185;EGYPTIAN HIEROGLYPH-14185;Lo;0;L;;;;;N;;;;; +14186;EGYPTIAN HIEROGLYPH-14186;Lo;0;L;;;;;N;;;;; +14187;EGYPTIAN HIEROGLYPH-14187;Lo;0;L;;;;;N;;;;; +14188;EGYPTIAN HIEROGLYPH-14188;Lo;0;L;;;;;N;;;;; +14189;EGYPTIAN HIEROGLYPH-14189;Lo;0;L;;;;;N;;;;; +1418A;EGYPTIAN HIEROGLYPH-1418A;Lo;0;L;;;;;N;;;;; +1418B;EGYPTIAN HIEROGLYPH-1418B;Lo;0;L;;;;;N;;;;; +1418C;EGYPTIAN HIEROGLYPH-1418C;Lo;0;L;;;;;N;;;;; +1418D;EGYPTIAN HIEROGLYPH-1418D;Lo;0;L;;;;;N;;;;; +1418E;EGYPTIAN HIEROGLYPH-1418E;Lo;0;L;;;;;N;;;;; +1418F;EGYPTIAN HIEROGLYPH-1418F;Lo;0;L;;;;;N;;;;; +14190;EGYPTIAN HIEROGLYPH-14190;Lo;0;L;;;;;N;;;;; +14191;EGYPTIAN HIEROGLYPH-14191;Lo;0;L;;;;;N;;;;; +14192;EGYPTIAN HIEROGLYPH-14192;Lo;0;L;;;;;N;;;;; +14193;EGYPTIAN HIEROGLYPH-14193;Lo;0;L;;;;;N;;;;; +14194;EGYPTIAN HIEROGLYPH-14194;Lo;0;L;;;;;N;;;;; +14195;EGYPTIAN HIEROGLYPH-14195;Lo;0;L;;;;;N;;;;; +14196;EGYPTIAN HIEROGLYPH-14196;Lo;0;L;;;;;N;;;;; +14197;EGYPTIAN HIEROGLYPH-14197;Lo;0;L;;;;;N;;;;; +14198;EGYPTIAN HIEROGLYPH-14198;Lo;0;L;;;;;N;;;;; +14199;EGYPTIAN HIEROGLYPH-14199;Lo;0;L;;;;;N;;;;; +1419A;EGYPTIAN HIEROGLYPH-1419A;Lo;0;L;;;;;N;;;;; +1419B;EGYPTIAN HIEROGLYPH-1419B;Lo;0;L;;;;;N;;;;; +1419C;EGYPTIAN HIEROGLYPH-1419C;Lo;0;L;;;;;N;;;;; +1419D;EGYPTIAN HIEROGLYPH-1419D;Lo;0;L;;;;;N;;;;; +1419E;EGYPTIAN HIEROGLYPH-1419E;Lo;0;L;;;;;N;;;;; +1419F;EGYPTIAN HIEROGLYPH-1419F;Lo;0;L;;;;;N;;;;; +141A0;EGYPTIAN HIEROGLYPH-141A0;Lo;0;L;;;;;N;;;;; +141A1;EGYPTIAN HIEROGLYPH-141A1;Lo;0;L;;;;;N;;;;; +141A2;EGYPTIAN HIEROGLYPH-141A2;Lo;0;L;;;;;N;;;;; +141A3;EGYPTIAN HIEROGLYPH-141A3;Lo;0;L;;;;;N;;;;; +141A4;EGYPTIAN HIEROGLYPH-141A4;Lo;0;L;;;;;N;;;;; +141A5;EGYPTIAN HIEROGLYPH-141A5;Lo;0;L;;;;;N;;;;; +141A6;EGYPTIAN HIEROGLYPH-141A6;Lo;0;L;;;;;N;;;;; +141A7;EGYPTIAN HIEROGLYPH-141A7;Lo;0;L;;;;;N;;;;; +141A8;EGYPTIAN HIEROGLYPH-141A8;Lo;0;L;;;;;N;;;;; +141A9;EGYPTIAN HIEROGLYPH-141A9;Lo;0;L;;;;;N;;;;; +141AA;EGYPTIAN HIEROGLYPH-141AA;Lo;0;L;;;;;N;;;;; +141AB;EGYPTIAN HIEROGLYPH-141AB;Lo;0;L;;;;;N;;;;; +141AC;EGYPTIAN HIEROGLYPH-141AC;Lo;0;L;;;;;N;;;;; +141AD;EGYPTIAN HIEROGLYPH-141AD;Lo;0;L;;;;;N;;;;; +141AE;EGYPTIAN HIEROGLYPH-141AE;Lo;0;L;;;;;N;;;;; +141AF;EGYPTIAN HIEROGLYPH-141AF;Lo;0;L;;;;;N;;;;; +141B0;EGYPTIAN HIEROGLYPH-141B0;Lo;0;L;;;;;N;;;;; +141B1;EGYPTIAN HIEROGLYPH-141B1;Lo;0;L;;;;;N;;;;; +141B2;EGYPTIAN HIEROGLYPH-141B2;Lo;0;L;;;;;N;;;;; +141B3;EGYPTIAN HIEROGLYPH-141B3;Lo;0;L;;;;;N;;;;; +141B4;EGYPTIAN HIEROGLYPH-141B4;Lo;0;L;;;;;N;;;;; +141B5;EGYPTIAN HIEROGLYPH-141B5;Lo;0;L;;;;;N;;;;; +141B6;EGYPTIAN HIEROGLYPH-141B6;Lo;0;L;;;;;N;;;;; +141B7;EGYPTIAN HIEROGLYPH-141B7;Lo;0;L;;;;;N;;;;; +141B8;EGYPTIAN HIEROGLYPH-141B8;Lo;0;L;;;;;N;;;;; +141B9;EGYPTIAN HIEROGLYPH-141B9;Lo;0;L;;;;;N;;;;; +141BA;EGYPTIAN HIEROGLYPH-141BA;Lo;0;L;;;;;N;;;;; +141BB;EGYPTIAN HIEROGLYPH-141BB;Lo;0;L;;;;;N;;;;; +141BC;EGYPTIAN HIEROGLYPH-141BC;Lo;0;L;;;;;N;;;;; +141BD;EGYPTIAN HIEROGLYPH-141BD;Lo;0;L;;;;;N;;;;; +141BE;EGYPTIAN HIEROGLYPH-141BE;Lo;0;L;;;;;N;;;;; +141BF;EGYPTIAN HIEROGLYPH-141BF;Lo;0;L;;;;;N;;;;; +141C0;EGYPTIAN HIEROGLYPH-141C0;Lo;0;L;;;;;N;;;;; +141C1;EGYPTIAN HIEROGLYPH-141C1;Lo;0;L;;;;;N;;;;; +141C2;EGYPTIAN HIEROGLYPH-141C2;Lo;0;L;;;;;N;;;;; +141C3;EGYPTIAN HIEROGLYPH-141C3;Lo;0;L;;;;;N;;;;; +141C4;EGYPTIAN HIEROGLYPH-141C4;Lo;0;L;;;;;N;;;;; +141C5;EGYPTIAN HIEROGLYPH-141C5;Lo;0;L;;;;;N;;;;; +141C6;EGYPTIAN HIEROGLYPH-141C6;Lo;0;L;;;;;N;;;;; +141C7;EGYPTIAN HIEROGLYPH-141C7;Lo;0;L;;;;;N;;;;; +141C8;EGYPTIAN HIEROGLYPH-141C8;Lo;0;L;;;;;N;;;;; +141C9;EGYPTIAN HIEROGLYPH-141C9;Lo;0;L;;;;;N;;;;; +141CA;EGYPTIAN HIEROGLYPH-141CA;Lo;0;L;;;;;N;;;;; +141CB;EGYPTIAN HIEROGLYPH-141CB;Lo;0;L;;;;;N;;;;; +141CC;EGYPTIAN HIEROGLYPH-141CC;Lo;0;L;;;;;N;;;;; +141CD;EGYPTIAN HIEROGLYPH-141CD;Lo;0;L;;;;;N;;;;; +141CE;EGYPTIAN HIEROGLYPH-141CE;Lo;0;L;;;;;N;;;;; +141CF;EGYPTIAN HIEROGLYPH-141CF;Lo;0;L;;;;;N;;;;; +141D0;EGYPTIAN HIEROGLYPH-141D0;Lo;0;L;;;;;N;;;;; +141D1;EGYPTIAN HIEROGLYPH-141D1;Lo;0;L;;;;;N;;;;; +141D2;EGYPTIAN HIEROGLYPH-141D2;Lo;0;L;;;;;N;;;;; +141D3;EGYPTIAN HIEROGLYPH-141D3;Lo;0;L;;;;;N;;;;; +141D4;EGYPTIAN HIEROGLYPH-141D4;Lo;0;L;;;;;N;;;;; +141D5;EGYPTIAN HIEROGLYPH-141D5;Lo;0;L;;;;;N;;;;; +141D6;EGYPTIAN HIEROGLYPH-141D6;Lo;0;L;;;;;N;;;;; +141D7;EGYPTIAN HIEROGLYPH-141D7;Lo;0;L;;;;;N;;;;; +141D8;EGYPTIAN HIEROGLYPH-141D8;Lo;0;L;;;;;N;;;;; +141D9;EGYPTIAN HIEROGLYPH-141D9;Lo;0;L;;;;;N;;;;; +141DA;EGYPTIAN HIEROGLYPH-141DA;Lo;0;L;;;;;N;;;;; +141DB;EGYPTIAN HIEROGLYPH-141DB;Lo;0;L;;;;;N;;;;; +141DC;EGYPTIAN HIEROGLYPH-141DC;Lo;0;L;;;;;N;;;;; +141DD;EGYPTIAN HIEROGLYPH-141DD;Lo;0;L;;;;;N;;;;; +141DE;EGYPTIAN HIEROGLYPH-141DE;Lo;0;L;;;;;N;;;;; +141DF;EGYPTIAN HIEROGLYPH-141DF;Lo;0;L;;;;;N;;;;; +141E0;EGYPTIAN HIEROGLYPH-141E0;Lo;0;L;;;;;N;;;;; +141E1;EGYPTIAN HIEROGLYPH-141E1;Lo;0;L;;;;;N;;;;; +141E2;EGYPTIAN HIEROGLYPH-141E2;Lo;0;L;;;;;N;;;;; +141E3;EGYPTIAN HIEROGLYPH-141E3;Lo;0;L;;;;;N;;;;; +141E4;EGYPTIAN HIEROGLYPH-141E4;Lo;0;L;;;;;N;;;;; +141E5;EGYPTIAN HIEROGLYPH-141E5;Lo;0;L;;;;;N;;;;; +141E6;EGYPTIAN HIEROGLYPH-141E6;Lo;0;L;;;;;N;;;;; +141E7;EGYPTIAN HIEROGLYPH-141E7;Lo;0;L;;;;;N;;;;; +141E8;EGYPTIAN HIEROGLYPH-141E8;Lo;0;L;;;;;N;;;;; +141E9;EGYPTIAN HIEROGLYPH-141E9;Lo;0;L;;;;;N;;;;; +141EA;EGYPTIAN HIEROGLYPH-141EA;Lo;0;L;;;;;N;;;;; +141EB;EGYPTIAN HIEROGLYPH-141EB;Lo;0;L;;;;;N;;;;; +141EC;EGYPTIAN HIEROGLYPH-141EC;Lo;0;L;;;;;N;;;;; +141ED;EGYPTIAN HIEROGLYPH-141ED;Lo;0;L;;;;;N;;;;; +141EE;EGYPTIAN HIEROGLYPH-141EE;Lo;0;L;;;;;N;;;;; +141EF;EGYPTIAN HIEROGLYPH-141EF;Lo;0;L;;;;;N;;;;; +141F0;EGYPTIAN HIEROGLYPH-141F0;Lo;0;L;;;;;N;;;;; +141F1;EGYPTIAN HIEROGLYPH-141F1;Lo;0;L;;;;;N;;;;; +141F2;EGYPTIAN HIEROGLYPH-141F2;Lo;0;L;;;;;N;;;;; +141F3;EGYPTIAN HIEROGLYPH-141F3;Lo;0;L;;;;;N;;;;; +141F4;EGYPTIAN HIEROGLYPH-141F4;Lo;0;L;;;;;N;;;;; +141F5;EGYPTIAN HIEROGLYPH-141F5;Lo;0;L;;;;;N;;;;; +141F6;EGYPTIAN HIEROGLYPH-141F6;Lo;0;L;;;;;N;;;;; +141F7;EGYPTIAN HIEROGLYPH-141F7;Lo;0;L;;;;;N;;;;; +141F8;EGYPTIAN HIEROGLYPH-141F8;Lo;0;L;;;;;N;;;;; +141F9;EGYPTIAN HIEROGLYPH-141F9;Lo;0;L;;;;;N;;;;; +141FA;EGYPTIAN HIEROGLYPH-141FA;Lo;0;L;;;;;N;;;;; +141FB;EGYPTIAN HIEROGLYPH-141FB;Lo;0;L;;;;;N;;;;; +141FC;EGYPTIAN HIEROGLYPH-141FC;Lo;0;L;;;;;N;;;;; +141FD;EGYPTIAN HIEROGLYPH-141FD;Lo;0;L;;;;;N;;;;; +141FE;EGYPTIAN HIEROGLYPH-141FE;Lo;0;L;;;;;N;;;;; +141FF;EGYPTIAN HIEROGLYPH-141FF;Lo;0;L;;;;;N;;;;; +14200;EGYPTIAN HIEROGLYPH-14200;Lo;0;L;;;;;N;;;;; +14201;EGYPTIAN HIEROGLYPH-14201;Lo;0;L;;;;;N;;;;; +14202;EGYPTIAN HIEROGLYPH-14202;Lo;0;L;;;;;N;;;;; +14203;EGYPTIAN HIEROGLYPH-14203;Lo;0;L;;;;;N;;;;; +14204;EGYPTIAN HIEROGLYPH-14204;Lo;0;L;;;;;N;;;;; +14205;EGYPTIAN HIEROGLYPH-14205;Lo;0;L;;;;;N;;;;; +14206;EGYPTIAN HIEROGLYPH-14206;Lo;0;L;;;;;N;;;;; +14207;EGYPTIAN HIEROGLYPH-14207;Lo;0;L;;;;;N;;;;; +14208;EGYPTIAN HIEROGLYPH-14208;Lo;0;L;;;;;N;;;;; +14209;EGYPTIAN HIEROGLYPH-14209;Lo;0;L;;;;;N;;;;; +1420A;EGYPTIAN HIEROGLYPH-1420A;Lo;0;L;;;;;N;;;;; +1420B;EGYPTIAN HIEROGLYPH-1420B;Lo;0;L;;;;;N;;;;; +1420C;EGYPTIAN HIEROGLYPH-1420C;Lo;0;L;;;;;N;;;;; +1420D;EGYPTIAN HIEROGLYPH-1420D;Lo;0;L;;;;;N;;;;; +1420E;EGYPTIAN HIEROGLYPH-1420E;Lo;0;L;;;;;N;;;;; +1420F;EGYPTIAN HIEROGLYPH-1420F;Lo;0;L;;;;;N;;;;; +14210;EGYPTIAN HIEROGLYPH-14210;Lo;0;L;;;;;N;;;;; +14211;EGYPTIAN HIEROGLYPH-14211;Lo;0;L;;;;;N;;;;; +14212;EGYPTIAN HIEROGLYPH-14212;Lo;0;L;;;;;N;;;;; +14213;EGYPTIAN HIEROGLYPH-14213;Lo;0;L;;;;;N;;;;; +14214;EGYPTIAN HIEROGLYPH-14214;Lo;0;L;;;;;N;;;;; +14215;EGYPTIAN HIEROGLYPH-14215;Lo;0;L;;;;;N;;;;; +14216;EGYPTIAN HIEROGLYPH-14216;Lo;0;L;;;;;N;;;;; +14217;EGYPTIAN HIEROGLYPH-14217;Lo;0;L;;;;;N;;;;; +14218;EGYPTIAN HIEROGLYPH-14218;Lo;0;L;;;;;N;;;;; +14219;EGYPTIAN HIEROGLYPH-14219;Lo;0;L;;;;;N;;;;; +1421A;EGYPTIAN HIEROGLYPH-1421A;Lo;0;L;;;;;N;;;;; +1421B;EGYPTIAN HIEROGLYPH-1421B;Lo;0;L;;;;;N;;;;; +1421C;EGYPTIAN HIEROGLYPH-1421C;Lo;0;L;;;;;N;;;;; +1421D;EGYPTIAN HIEROGLYPH-1421D;Lo;0;L;;;;;N;;;;; +1421E;EGYPTIAN HIEROGLYPH-1421E;Lo;0;L;;;;;N;;;;; +1421F;EGYPTIAN HIEROGLYPH-1421F;Lo;0;L;;;;;N;;;;; +14220;EGYPTIAN HIEROGLYPH-14220;Lo;0;L;;;;;N;;;;; +14221;EGYPTIAN HIEROGLYPH-14221;Lo;0;L;;;;;N;;;;; +14222;EGYPTIAN HIEROGLYPH-14222;Lo;0;L;;;;;N;;;;; +14223;EGYPTIAN HIEROGLYPH-14223;Lo;0;L;;;;;N;;;;; +14224;EGYPTIAN HIEROGLYPH-14224;Lo;0;L;;;;;N;;;;; +14225;EGYPTIAN HIEROGLYPH-14225;Lo;0;L;;;;;N;;;;; +14226;EGYPTIAN HIEROGLYPH-14226;Lo;0;L;;;;;N;;;;; +14227;EGYPTIAN HIEROGLYPH-14227;Lo;0;L;;;;;N;;;;; +14228;EGYPTIAN HIEROGLYPH-14228;Lo;0;L;;;;;N;;;;; +14229;EGYPTIAN HIEROGLYPH-14229;Lo;0;L;;;;;N;;;;; +1422A;EGYPTIAN HIEROGLYPH-1422A;Lo;0;L;;;;;N;;;;; +1422B;EGYPTIAN HIEROGLYPH-1422B;Lo;0;L;;;;;N;;;;; +1422C;EGYPTIAN HIEROGLYPH-1422C;Lo;0;L;;;;;N;;;;; +1422D;EGYPTIAN HIEROGLYPH-1422D;Lo;0;L;;;;;N;;;;; +1422E;EGYPTIAN HIEROGLYPH-1422E;Lo;0;L;;;;;N;;;;; +1422F;EGYPTIAN HIEROGLYPH-1422F;Lo;0;L;;;;;N;;;;; +14230;EGYPTIAN HIEROGLYPH-14230;Lo;0;L;;;;;N;;;;; +14231;EGYPTIAN HIEROGLYPH-14231;Lo;0;L;;;;;N;;;;; +14232;EGYPTIAN HIEROGLYPH-14232;Lo;0;L;;;;;N;;;;; +14233;EGYPTIAN HIEROGLYPH-14233;Lo;0;L;;;;;N;;;;; +14234;EGYPTIAN HIEROGLYPH-14234;Lo;0;L;;;;;N;;;;; +14235;EGYPTIAN HIEROGLYPH-14235;Lo;0;L;;;;;N;;;;; +14236;EGYPTIAN HIEROGLYPH-14236;Lo;0;L;;;;;N;;;;; +14237;EGYPTIAN HIEROGLYPH-14237;Lo;0;L;;;;;N;;;;; +14238;EGYPTIAN HIEROGLYPH-14238;Lo;0;L;;;;;N;;;;; +14239;EGYPTIAN HIEROGLYPH-14239;Lo;0;L;;;;;N;;;;; +1423A;EGYPTIAN HIEROGLYPH-1423A;Lo;0;L;;;;;N;;;;; +1423B;EGYPTIAN HIEROGLYPH-1423B;Lo;0;L;;;;;N;;;;; +1423C;EGYPTIAN HIEROGLYPH-1423C;Lo;0;L;;;;;N;;;;; +1423D;EGYPTIAN HIEROGLYPH-1423D;Lo;0;L;;;;;N;;;;; +1423E;EGYPTIAN HIEROGLYPH-1423E;Lo;0;L;;;;;N;;;;; +1423F;EGYPTIAN HIEROGLYPH-1423F;Lo;0;L;;;;;N;;;;; +14240;EGYPTIAN HIEROGLYPH-14240;Lo;0;L;;;;;N;;;;; +14241;EGYPTIAN HIEROGLYPH-14241;Lo;0;L;;;;;N;;;;; +14242;EGYPTIAN HIEROGLYPH-14242;Lo;0;L;;;;;N;;;;; +14243;EGYPTIAN HIEROGLYPH-14243;Lo;0;L;;;;;N;;;;; +14244;EGYPTIAN HIEROGLYPH-14244;Lo;0;L;;;;;N;;;;; +14245;EGYPTIAN HIEROGLYPH-14245;Lo;0;L;;;;;N;;;;; +14246;EGYPTIAN HIEROGLYPH-14246;Lo;0;L;;;;;N;;;;; +14247;EGYPTIAN HIEROGLYPH-14247;Lo;0;L;;;;;N;;;;; +14248;EGYPTIAN HIEROGLYPH-14248;Lo;0;L;;;;;N;;;;; +14249;EGYPTIAN HIEROGLYPH-14249;Lo;0;L;;;;;N;;;;; +1424A;EGYPTIAN HIEROGLYPH-1424A;Lo;0;L;;;;;N;;;;; +1424B;EGYPTIAN HIEROGLYPH-1424B;Lo;0;L;;;;;N;;;;; +1424C;EGYPTIAN HIEROGLYPH-1424C;Lo;0;L;;;;;N;;;;; +1424D;EGYPTIAN HIEROGLYPH-1424D;Lo;0;L;;;;;N;;;;; +1424E;EGYPTIAN HIEROGLYPH-1424E;Lo;0;L;;;;;N;;;;; +1424F;EGYPTIAN HIEROGLYPH-1424F;Lo;0;L;;;;;N;;;;; +14250;EGYPTIAN HIEROGLYPH-14250;Lo;0;L;;;;;N;;;;; +14251;EGYPTIAN HIEROGLYPH-14251;Lo;0;L;;;;;N;;;;; +14252;EGYPTIAN HIEROGLYPH-14252;Lo;0;L;;;;;N;;;;; +14253;EGYPTIAN HIEROGLYPH-14253;Lo;0;L;;;;;N;;;;; +14254;EGYPTIAN HIEROGLYPH-14254;Lo;0;L;;;;;N;;;;; +14255;EGYPTIAN HIEROGLYPH-14255;Lo;0;L;;;;;N;;;;; +14256;EGYPTIAN HIEROGLYPH-14256;Lo;0;L;;;;;N;;;;; +14257;EGYPTIAN HIEROGLYPH-14257;Lo;0;L;;;;;N;;;;; +14258;EGYPTIAN HIEROGLYPH-14258;Lo;0;L;;;;;N;;;;; +14259;EGYPTIAN HIEROGLYPH-14259;Lo;0;L;;;;;N;;;;; +1425A;EGYPTIAN HIEROGLYPH-1425A;Lo;0;L;;;;;N;;;;; +1425B;EGYPTIAN HIEROGLYPH-1425B;Lo;0;L;;;;;N;;;;; +1425C;EGYPTIAN HIEROGLYPH-1425C;Lo;0;L;;;;;N;;;;; +1425D;EGYPTIAN HIEROGLYPH-1425D;Lo;0;L;;;;;N;;;;; +1425E;EGYPTIAN HIEROGLYPH-1425E;Lo;0;L;;;;;N;;;;; +1425F;EGYPTIAN HIEROGLYPH-1425F;Lo;0;L;;;;;N;;;;; +14260;EGYPTIAN HIEROGLYPH-14260;Lo;0;L;;;;;N;;;;; +14261;EGYPTIAN HIEROGLYPH-14261;Lo;0;L;;;;;N;;;;; +14262;EGYPTIAN HIEROGLYPH-14262;Lo;0;L;;;;;N;;;;; +14263;EGYPTIAN HIEROGLYPH-14263;Lo;0;L;;;;;N;;;;; +14264;EGYPTIAN HIEROGLYPH-14264;Lo;0;L;;;;;N;;;;; +14265;EGYPTIAN HIEROGLYPH-14265;Lo;0;L;;;;;N;;;;; +14266;EGYPTIAN HIEROGLYPH-14266;Lo;0;L;;;;;N;;;;; +14267;EGYPTIAN HIEROGLYPH-14267;Lo;0;L;;;;;N;;;;; +14268;EGYPTIAN HIEROGLYPH-14268;Lo;0;L;;;;;N;;;;; +14269;EGYPTIAN HIEROGLYPH-14269;Lo;0;L;;;;;N;;;;; +1426A;EGYPTIAN HIEROGLYPH-1426A;Lo;0;L;;;;;N;;;;; +1426B;EGYPTIAN HIEROGLYPH-1426B;Lo;0;L;;;;;N;;;;; +1426C;EGYPTIAN HIEROGLYPH-1426C;Lo;0;L;;;;;N;;;;; +1426D;EGYPTIAN HIEROGLYPH-1426D;Lo;0;L;;;;;N;;;;; +1426E;EGYPTIAN HIEROGLYPH-1426E;Lo;0;L;;;;;N;;;;; +1426F;EGYPTIAN HIEROGLYPH-1426F;Lo;0;L;;;;;N;;;;; +14270;EGYPTIAN HIEROGLYPH-14270;Lo;0;L;;;;;N;;;;; +14271;EGYPTIAN HIEROGLYPH-14271;Lo;0;L;;;;;N;;;;; +14272;EGYPTIAN HIEROGLYPH-14272;Lo;0;L;;;;;N;;;;; +14273;EGYPTIAN HIEROGLYPH-14273;Lo;0;L;;;;;N;;;;; +14274;EGYPTIAN HIEROGLYPH-14274;Lo;0;L;;;;;N;;;;; +14275;EGYPTIAN HIEROGLYPH-14275;Lo;0;L;;;;;N;;;;; +14276;EGYPTIAN HIEROGLYPH-14276;Lo;0;L;;;;;N;;;;; +14277;EGYPTIAN HIEROGLYPH-14277;Lo;0;L;;;;;N;;;;; +14278;EGYPTIAN HIEROGLYPH-14278;Lo;0;L;;;;;N;;;;; +14279;EGYPTIAN HIEROGLYPH-14279;Lo;0;L;;;;;N;;;;; +1427A;EGYPTIAN HIEROGLYPH-1427A;Lo;0;L;;;;;N;;;;; +1427B;EGYPTIAN HIEROGLYPH-1427B;Lo;0;L;;;;;N;;;;; +1427C;EGYPTIAN HIEROGLYPH-1427C;Lo;0;L;;;;;N;;;;; +1427D;EGYPTIAN HIEROGLYPH-1427D;Lo;0;L;;;;;N;;;;; +1427E;EGYPTIAN HIEROGLYPH-1427E;Lo;0;L;;;;;N;;;;; +1427F;EGYPTIAN HIEROGLYPH-1427F;Lo;0;L;;;;;N;;;;; +14280;EGYPTIAN HIEROGLYPH-14280;Lo;0;L;;;;;N;;;;; +14281;EGYPTIAN HIEROGLYPH-14281;Lo;0;L;;;;;N;;;;; +14282;EGYPTIAN HIEROGLYPH-14282;Lo;0;L;;;;;N;;;;; +14283;EGYPTIAN HIEROGLYPH-14283;Lo;0;L;;;;;N;;;;; +14284;EGYPTIAN HIEROGLYPH-14284;Lo;0;L;;;;;N;;;;; +14285;EGYPTIAN HIEROGLYPH-14285;Lo;0;L;;;;;N;;;;; +14286;EGYPTIAN HIEROGLYPH-14286;Lo;0;L;;;;;N;;;;; +14287;EGYPTIAN HIEROGLYPH-14287;Lo;0;L;;;;;N;;;;; +14288;EGYPTIAN HIEROGLYPH-14288;Lo;0;L;;;;;N;;;;; +14289;EGYPTIAN HIEROGLYPH-14289;Lo;0;L;;;;;N;;;;; +1428A;EGYPTIAN HIEROGLYPH-1428A;Lo;0;L;;;;;N;;;;; +1428B;EGYPTIAN HIEROGLYPH-1428B;Lo;0;L;;;;;N;;;;; +1428C;EGYPTIAN HIEROGLYPH-1428C;Lo;0;L;;;;;N;;;;; +1428D;EGYPTIAN HIEROGLYPH-1428D;Lo;0;L;;;;;N;;;;; +1428E;EGYPTIAN HIEROGLYPH-1428E;Lo;0;L;;;;;N;;;;; +1428F;EGYPTIAN HIEROGLYPH-1428F;Lo;0;L;;;;;N;;;;; +14290;EGYPTIAN HIEROGLYPH-14290;Lo;0;L;;;;;N;;;;; +14291;EGYPTIAN HIEROGLYPH-14291;Lo;0;L;;;;;N;;;;; +14292;EGYPTIAN HIEROGLYPH-14292;Lo;0;L;;;;;N;;;;; +14293;EGYPTIAN HIEROGLYPH-14293;Lo;0;L;;;;;N;;;;; +14294;EGYPTIAN HIEROGLYPH-14294;Lo;0;L;;;;;N;;;;; +14295;EGYPTIAN HIEROGLYPH-14295;Lo;0;L;;;;;N;;;;; +14296;EGYPTIAN HIEROGLYPH-14296;Lo;0;L;;;;;N;;;;; +14297;EGYPTIAN HIEROGLYPH-14297;Lo;0;L;;;;;N;;;;; +14298;EGYPTIAN HIEROGLYPH-14298;Lo;0;L;;;;;N;;;;; +14299;EGYPTIAN HIEROGLYPH-14299;Lo;0;L;;;;;N;;;;; +1429A;EGYPTIAN HIEROGLYPH-1429A;Lo;0;L;;;;;N;;;;; +1429B;EGYPTIAN HIEROGLYPH-1429B;Lo;0;L;;;;;N;;;;; +1429C;EGYPTIAN HIEROGLYPH-1429C;Lo;0;L;;;;;N;;;;; +1429D;EGYPTIAN HIEROGLYPH-1429D;Lo;0;L;;;;;N;;;;; +1429E;EGYPTIAN HIEROGLYPH-1429E;Lo;0;L;;;;;N;;;;; +1429F;EGYPTIAN HIEROGLYPH-1429F;Lo;0;L;;;;;N;;;;; +142A0;EGYPTIAN HIEROGLYPH-142A0;Lo;0;L;;;;;N;;;;; +142A1;EGYPTIAN HIEROGLYPH-142A1;Lo;0;L;;;;;N;;;;; +142A2;EGYPTIAN HIEROGLYPH-142A2;Lo;0;L;;;;;N;;;;; +142A3;EGYPTIAN HIEROGLYPH-142A3;Lo;0;L;;;;;N;;;;; +142A4;EGYPTIAN HIEROGLYPH-142A4;Lo;0;L;;;;;N;;;;; +142A5;EGYPTIAN HIEROGLYPH-142A5;Lo;0;L;;;;;N;;;;; +142A6;EGYPTIAN HIEROGLYPH-142A6;Lo;0;L;;;;;N;;;;; +142A7;EGYPTIAN HIEROGLYPH-142A7;Lo;0;L;;;;;N;;;;; +142A8;EGYPTIAN HIEROGLYPH-142A8;Lo;0;L;;;;;N;;;;; +142A9;EGYPTIAN HIEROGLYPH-142A9;Lo;0;L;;;;;N;;;;; +142AA;EGYPTIAN HIEROGLYPH-142AA;Lo;0;L;;;;;N;;;;; +142AB;EGYPTIAN HIEROGLYPH-142AB;Lo;0;L;;;;;N;;;;; +142AC;EGYPTIAN HIEROGLYPH-142AC;Lo;0;L;;;;;N;;;;; +142AD;EGYPTIAN HIEROGLYPH-142AD;Lo;0;L;;;;;N;;;;; +142AE;EGYPTIAN HIEROGLYPH-142AE;Lo;0;L;;;;;N;;;;; +142AF;EGYPTIAN HIEROGLYPH-142AF;Lo;0;L;;;;;N;;;;; +142B0;EGYPTIAN HIEROGLYPH-142B0;Lo;0;L;;;;;N;;;;; +142B1;EGYPTIAN HIEROGLYPH-142B1;Lo;0;L;;;;;N;;;;; +142B2;EGYPTIAN HIEROGLYPH-142B2;Lo;0;L;;;;;N;;;;; +142B3;EGYPTIAN HIEROGLYPH-142B3;Lo;0;L;;;;;N;;;;; +142B4;EGYPTIAN HIEROGLYPH-142B4;Lo;0;L;;;;;N;;;;; +142B5;EGYPTIAN HIEROGLYPH-142B5;Lo;0;L;;;;;N;;;;; +142B6;EGYPTIAN HIEROGLYPH-142B6;Lo;0;L;;;;;N;;;;; +142B7;EGYPTIAN HIEROGLYPH-142B7;Lo;0;L;;;;;N;;;;; +142B8;EGYPTIAN HIEROGLYPH-142B8;Lo;0;L;;;;;N;;;;; +142B9;EGYPTIAN HIEROGLYPH-142B9;Lo;0;L;;;;;N;;;;; +142BA;EGYPTIAN HIEROGLYPH-142BA;Lo;0;L;;;;;N;;;;; +142BB;EGYPTIAN HIEROGLYPH-142BB;Lo;0;L;;;;;N;;;;; +142BC;EGYPTIAN HIEROGLYPH-142BC;Lo;0;L;;;;;N;;;;; +142BD;EGYPTIAN HIEROGLYPH-142BD;Lo;0;L;;;;;N;;;;; +142BE;EGYPTIAN HIEROGLYPH-142BE;Lo;0;L;;;;;N;;;;; +142BF;EGYPTIAN HIEROGLYPH-142BF;Lo;0;L;;;;;N;;;;; +142C0;EGYPTIAN HIEROGLYPH-142C0;Lo;0;L;;;;;N;;;;; +142C1;EGYPTIAN HIEROGLYPH-142C1;Lo;0;L;;;;;N;;;;; +142C2;EGYPTIAN HIEROGLYPH-142C2;Lo;0;L;;;;;N;;;;; +142C3;EGYPTIAN HIEROGLYPH-142C3;Lo;0;L;;;;;N;;;;; +142C4;EGYPTIAN HIEROGLYPH-142C4;Lo;0;L;;;;;N;;;;; +142C5;EGYPTIAN HIEROGLYPH-142C5;Lo;0;L;;;;;N;;;;; +142C6;EGYPTIAN HIEROGLYPH-142C6;Lo;0;L;;;;;N;;;;; +142C7;EGYPTIAN HIEROGLYPH-142C7;Lo;0;L;;;;;N;;;;; +142C8;EGYPTIAN HIEROGLYPH-142C8;Lo;0;L;;;;;N;;;;; +142C9;EGYPTIAN HIEROGLYPH-142C9;Lo;0;L;;;;;N;;;;; +142CA;EGYPTIAN HIEROGLYPH-142CA;Lo;0;L;;;;;N;;;;; +142CB;EGYPTIAN HIEROGLYPH-142CB;Lo;0;L;;;;;N;;;;; +142CC;EGYPTIAN HIEROGLYPH-142CC;Lo;0;L;;;;;N;;;;; +142CD;EGYPTIAN HIEROGLYPH-142CD;Lo;0;L;;;;;N;;;;; +142CE;EGYPTIAN HIEROGLYPH-142CE;Lo;0;L;;;;;N;;;;; +142CF;EGYPTIAN HIEROGLYPH-142CF;Lo;0;L;;;;;N;;;;; +142D0;EGYPTIAN HIEROGLYPH-142D0;Lo;0;L;;;;;N;;;;; +142D1;EGYPTIAN HIEROGLYPH-142D1;Lo;0;L;;;;;N;;;;; +142D2;EGYPTIAN HIEROGLYPH-142D2;Lo;0;L;;;;;N;;;;; +142D3;EGYPTIAN HIEROGLYPH-142D3;Lo;0;L;;;;;N;;;;; +142D4;EGYPTIAN HIEROGLYPH-142D4;Lo;0;L;;;;;N;;;;; +142D5;EGYPTIAN HIEROGLYPH-142D5;Lo;0;L;;;;;N;;;;; +142D6;EGYPTIAN HIEROGLYPH-142D6;Lo;0;L;;;;;N;;;;; +142D7;EGYPTIAN HIEROGLYPH-142D7;Lo;0;L;;;;;N;;;;; +142D8;EGYPTIAN HIEROGLYPH-142D8;Lo;0;L;;;;;N;;;;; +142D9;EGYPTIAN HIEROGLYPH-142D9;Lo;0;L;;;;;N;;;;; +142DA;EGYPTIAN HIEROGLYPH-142DA;Lo;0;L;;;;;N;;;;; +142DB;EGYPTIAN HIEROGLYPH-142DB;Lo;0;L;;;;;N;;;;; +142DC;EGYPTIAN HIEROGLYPH-142DC;Lo;0;L;;;;;N;;;;; +142DD;EGYPTIAN HIEROGLYPH-142DD;Lo;0;L;;;;;N;;;;; +142DE;EGYPTIAN HIEROGLYPH-142DE;Lo;0;L;;;;;N;;;;; +142DF;EGYPTIAN HIEROGLYPH-142DF;Lo;0;L;;;;;N;;;;; +142E0;EGYPTIAN HIEROGLYPH-142E0;Lo;0;L;;;;;N;;;;; +142E1;EGYPTIAN HIEROGLYPH-142E1;Lo;0;L;;;;;N;;;;; +142E2;EGYPTIAN HIEROGLYPH-142E2;Lo;0;L;;;;;N;;;;; +142E3;EGYPTIAN HIEROGLYPH-142E3;Lo;0;L;;;;;N;;;;; +142E4;EGYPTIAN HIEROGLYPH-142E4;Lo;0;L;;;;;N;;;;; +142E5;EGYPTIAN HIEROGLYPH-142E5;Lo;0;L;;;;;N;;;;; +142E6;EGYPTIAN HIEROGLYPH-142E6;Lo;0;L;;;;;N;;;;; +142E7;EGYPTIAN HIEROGLYPH-142E7;Lo;0;L;;;;;N;;;;; +142E8;EGYPTIAN HIEROGLYPH-142E8;Lo;0;L;;;;;N;;;;; +142E9;EGYPTIAN HIEROGLYPH-142E9;Lo;0;L;;;;;N;;;;; +142EA;EGYPTIAN HIEROGLYPH-142EA;Lo;0;L;;;;;N;;;;; +142EB;EGYPTIAN HIEROGLYPH-142EB;Lo;0;L;;;;;N;;;;; +142EC;EGYPTIAN HIEROGLYPH-142EC;Lo;0;L;;;;;N;;;;; +142ED;EGYPTIAN HIEROGLYPH-142ED;Lo;0;L;;;;;N;;;;; +142EE;EGYPTIAN HIEROGLYPH-142EE;Lo;0;L;;;;;N;;;;; +142EF;EGYPTIAN HIEROGLYPH-142EF;Lo;0;L;;;;;N;;;;; +142F0;EGYPTIAN HIEROGLYPH-142F0;Lo;0;L;;;;;N;;;;; +142F1;EGYPTIAN HIEROGLYPH-142F1;Lo;0;L;;;;;N;;;;; +142F2;EGYPTIAN HIEROGLYPH-142F2;Lo;0;L;;;;;N;;;;; +142F3;EGYPTIAN HIEROGLYPH-142F3;Lo;0;L;;;;;N;;;;; +142F4;EGYPTIAN HIEROGLYPH-142F4;Lo;0;L;;;;;N;;;;; +142F5;EGYPTIAN HIEROGLYPH-142F5;Lo;0;L;;;;;N;;;;; +142F6;EGYPTIAN HIEROGLYPH-142F6;Lo;0;L;;;;;N;;;;; +142F7;EGYPTIAN HIEROGLYPH-142F7;Lo;0;L;;;;;N;;;;; +142F8;EGYPTIAN HIEROGLYPH-142F8;Lo;0;L;;;;;N;;;;; +142F9;EGYPTIAN HIEROGLYPH-142F9;Lo;0;L;;;;;N;;;;; +142FA;EGYPTIAN HIEROGLYPH-142FA;Lo;0;L;;;;;N;;;;; +142FB;EGYPTIAN HIEROGLYPH-142FB;Lo;0;L;;;;;N;;;;; +142FC;EGYPTIAN HIEROGLYPH-142FC;Lo;0;L;;;;;N;;;;; +142FD;EGYPTIAN HIEROGLYPH-142FD;Lo;0;L;;;;;N;;;;; +142FE;EGYPTIAN HIEROGLYPH-142FE;Lo;0;L;;;;;N;;;;; +142FF;EGYPTIAN HIEROGLYPH-142FF;Lo;0;L;;;;;N;;;;; +14300;EGYPTIAN HIEROGLYPH-14300;Lo;0;L;;;;;N;;;;; +14301;EGYPTIAN HIEROGLYPH-14301;Lo;0;L;;;;;N;;;;; +14302;EGYPTIAN HIEROGLYPH-14302;Lo;0;L;;;;;N;;;;; +14303;EGYPTIAN HIEROGLYPH-14303;Lo;0;L;;;;;N;;;;; +14304;EGYPTIAN HIEROGLYPH-14304;Lo;0;L;;;;;N;;;;; +14305;EGYPTIAN HIEROGLYPH-14305;Lo;0;L;;;;;N;;;;; +14306;EGYPTIAN HIEROGLYPH-14306;Lo;0;L;;;;;N;;;;; +14307;EGYPTIAN HIEROGLYPH-14307;Lo;0;L;;;;;N;;;;; +14308;EGYPTIAN HIEROGLYPH-14308;Lo;0;L;;;;;N;;;;; +14309;EGYPTIAN HIEROGLYPH-14309;Lo;0;L;;;;;N;;;;; +1430A;EGYPTIAN HIEROGLYPH-1430A;Lo;0;L;;;;;N;;;;; +1430B;EGYPTIAN HIEROGLYPH-1430B;Lo;0;L;;;;;N;;;;; +1430C;EGYPTIAN HIEROGLYPH-1430C;Lo;0;L;;;;;N;;;;; +1430D;EGYPTIAN HIEROGLYPH-1430D;Lo;0;L;;;;;N;;;;; +1430E;EGYPTIAN HIEROGLYPH-1430E;Lo;0;L;;;;;N;;;;; +1430F;EGYPTIAN HIEROGLYPH-1430F;Lo;0;L;;;;;N;;;;; +14310;EGYPTIAN HIEROGLYPH-14310;Lo;0;L;;;;;N;;;;; +14311;EGYPTIAN HIEROGLYPH-14311;Lo;0;L;;;;;N;;;;; +14312;EGYPTIAN HIEROGLYPH-14312;Lo;0;L;;;;;N;;;;; +14313;EGYPTIAN HIEROGLYPH-14313;Lo;0;L;;;;;N;;;;; +14314;EGYPTIAN HIEROGLYPH-14314;Lo;0;L;;;;;N;;;;; +14315;EGYPTIAN HIEROGLYPH-14315;Lo;0;L;;;;;N;;;;; +14316;EGYPTIAN HIEROGLYPH-14316;Lo;0;L;;;;;N;;;;; +14317;EGYPTIAN HIEROGLYPH-14317;Lo;0;L;;;;;N;;;;; +14318;EGYPTIAN HIEROGLYPH-14318;Lo;0;L;;;;;N;;;;; +14319;EGYPTIAN HIEROGLYPH-14319;Lo;0;L;;;;;N;;;;; +1431A;EGYPTIAN HIEROGLYPH-1431A;Lo;0;L;;;;;N;;;;; +1431B;EGYPTIAN HIEROGLYPH-1431B;Lo;0;L;;;;;N;;;;; +1431C;EGYPTIAN HIEROGLYPH-1431C;Lo;0;L;;;;;N;;;;; +1431D;EGYPTIAN HIEROGLYPH-1431D;Lo;0;L;;;;;N;;;;; +1431E;EGYPTIAN HIEROGLYPH-1431E;Lo;0;L;;;;;N;;;;; +1431F;EGYPTIAN HIEROGLYPH-1431F;Lo;0;L;;;;;N;;;;; +14320;EGYPTIAN HIEROGLYPH-14320;Lo;0;L;;;;;N;;;;; +14321;EGYPTIAN HIEROGLYPH-14321;Lo;0;L;;;;;N;;;;; +14322;EGYPTIAN HIEROGLYPH-14322;Lo;0;L;;;;;N;;;;; +14323;EGYPTIAN HIEROGLYPH-14323;Lo;0;L;;;;;N;;;;; +14324;EGYPTIAN HIEROGLYPH-14324;Lo;0;L;;;;;N;;;;; +14325;EGYPTIAN HIEROGLYPH-14325;Lo;0;L;;;;;N;;;;; +14326;EGYPTIAN HIEROGLYPH-14326;Lo;0;L;;;;;N;;;;; +14327;EGYPTIAN HIEROGLYPH-14327;Lo;0;L;;;;;N;;;;; +14328;EGYPTIAN HIEROGLYPH-14328;Lo;0;L;;;;;N;;;;; +14329;EGYPTIAN HIEROGLYPH-14329;Lo;0;L;;;;;N;;;;; +1432A;EGYPTIAN HIEROGLYPH-1432A;Lo;0;L;;;;;N;;;;; +1432B;EGYPTIAN HIEROGLYPH-1432B;Lo;0;L;;;;;N;;;;; +1432C;EGYPTIAN HIEROGLYPH-1432C;Lo;0;L;;;;;N;;;;; +1432D;EGYPTIAN HIEROGLYPH-1432D;Lo;0;L;;;;;N;;;;; +1432E;EGYPTIAN HIEROGLYPH-1432E;Lo;0;L;;;;;N;;;;; +1432F;EGYPTIAN HIEROGLYPH-1432F;Lo;0;L;;;;;N;;;;; +14330;EGYPTIAN HIEROGLYPH-14330;Lo;0;L;;;;;N;;;;; +14331;EGYPTIAN HIEROGLYPH-14331;Lo;0;L;;;;;N;;;;; +14332;EGYPTIAN HIEROGLYPH-14332;Lo;0;L;;;;;N;;;;; +14333;EGYPTIAN HIEROGLYPH-14333;Lo;0;L;;;;;N;;;;; +14334;EGYPTIAN HIEROGLYPH-14334;Lo;0;L;;;;;N;;;;; +14335;EGYPTIAN HIEROGLYPH-14335;Lo;0;L;;;;;N;;;;; +14336;EGYPTIAN HIEROGLYPH-14336;Lo;0;L;;;;;N;;;;; +14337;EGYPTIAN HIEROGLYPH-14337;Lo;0;L;;;;;N;;;;; +14338;EGYPTIAN HIEROGLYPH-14338;Lo;0;L;;;;;N;;;;; +14339;EGYPTIAN HIEROGLYPH-14339;Lo;0;L;;;;;N;;;;; +1433A;EGYPTIAN HIEROGLYPH-1433A;Lo;0;L;;;;;N;;;;; +1433B;EGYPTIAN HIEROGLYPH-1433B;Lo;0;L;;;;;N;;;;; +1433C;EGYPTIAN HIEROGLYPH-1433C;Lo;0;L;;;;;N;;;;; +1433D;EGYPTIAN HIEROGLYPH-1433D;Lo;0;L;;;;;N;;;;; +1433E;EGYPTIAN HIEROGLYPH-1433E;Lo;0;L;;;;;N;;;;; +1433F;EGYPTIAN HIEROGLYPH-1433F;Lo;0;L;;;;;N;;;;; +14340;EGYPTIAN HIEROGLYPH-14340;Lo;0;L;;;;;N;;;;; +14341;EGYPTIAN HIEROGLYPH-14341;Lo;0;L;;;;;N;;;;; +14342;EGYPTIAN HIEROGLYPH-14342;Lo;0;L;;;;;N;;;;; +14343;EGYPTIAN HIEROGLYPH-14343;Lo;0;L;;;;;N;;;;; +14344;EGYPTIAN HIEROGLYPH-14344;Lo;0;L;;;;;N;;;;; +14345;EGYPTIAN HIEROGLYPH-14345;Lo;0;L;;;;;N;;;;; +14346;EGYPTIAN HIEROGLYPH-14346;Lo;0;L;;;;;N;;;;; +14347;EGYPTIAN HIEROGLYPH-14347;Lo;0;L;;;;;N;;;;; +14348;EGYPTIAN HIEROGLYPH-14348;Lo;0;L;;;;;N;;;;; +14349;EGYPTIAN HIEROGLYPH-14349;Lo;0;L;;;;;N;;;;; +1434A;EGYPTIAN HIEROGLYPH-1434A;Lo;0;L;;;;;N;;;;; +1434B;EGYPTIAN HIEROGLYPH-1434B;Lo;0;L;;;;;N;;;;; +1434C;EGYPTIAN HIEROGLYPH-1434C;Lo;0;L;;;;;N;;;;; +1434D;EGYPTIAN HIEROGLYPH-1434D;Lo;0;L;;;;;N;;;;; +1434E;EGYPTIAN HIEROGLYPH-1434E;Lo;0;L;;;;;N;;;;; +1434F;EGYPTIAN HIEROGLYPH-1434F;Lo;0;L;;;;;N;;;;; +14350;EGYPTIAN HIEROGLYPH-14350;Lo;0;L;;;;;N;;;;; +14351;EGYPTIAN HIEROGLYPH-14351;Lo;0;L;;;;;N;;;;; +14352;EGYPTIAN HIEROGLYPH-14352;Lo;0;L;;;;;N;;;;; +14353;EGYPTIAN HIEROGLYPH-14353;Lo;0;L;;;;;N;;;;; +14354;EGYPTIAN HIEROGLYPH-14354;Lo;0;L;;;;;N;;;;; +14355;EGYPTIAN HIEROGLYPH-14355;Lo;0;L;;;;;N;;;;; +14356;EGYPTIAN HIEROGLYPH-14356;Lo;0;L;;;;;N;;;;; +14357;EGYPTIAN HIEROGLYPH-14357;Lo;0;L;;;;;N;;;;; +14358;EGYPTIAN HIEROGLYPH-14358;Lo;0;L;;;;;N;;;;; +14359;EGYPTIAN HIEROGLYPH-14359;Lo;0;L;;;;;N;;;;; +1435A;EGYPTIAN HIEROGLYPH-1435A;Lo;0;L;;;;;N;;;;; +1435B;EGYPTIAN HIEROGLYPH-1435B;Lo;0;L;;;;;N;;;;; +1435C;EGYPTIAN HIEROGLYPH-1435C;Lo;0;L;;;;;N;;;;; +1435D;EGYPTIAN HIEROGLYPH-1435D;Lo;0;L;;;;;N;;;;; +1435E;EGYPTIAN HIEROGLYPH-1435E;Lo;0;L;;;;;N;;;;; +1435F;EGYPTIAN HIEROGLYPH-1435F;Lo;0;L;;;;;N;;;;; +14360;EGYPTIAN HIEROGLYPH-14360;Lo;0;L;;;;;N;;;;; +14361;EGYPTIAN HIEROGLYPH-14361;Lo;0;L;;;;;N;;;;; +14362;EGYPTIAN HIEROGLYPH-14362;Lo;0;L;;;;;N;;;;; +14363;EGYPTIAN HIEROGLYPH-14363;Lo;0;L;;;;;N;;;;; +14364;EGYPTIAN HIEROGLYPH-14364;Lo;0;L;;;;;N;;;;; +14365;EGYPTIAN HIEROGLYPH-14365;Lo;0;L;;;;;N;;;;; +14366;EGYPTIAN HIEROGLYPH-14366;Lo;0;L;;;;;N;;;;; +14367;EGYPTIAN HIEROGLYPH-14367;Lo;0;L;;;;;N;;;;; +14368;EGYPTIAN HIEROGLYPH-14368;Lo;0;L;;;;;N;;;;; +14369;EGYPTIAN HIEROGLYPH-14369;Lo;0;L;;;;;N;;;;; +1436A;EGYPTIAN HIEROGLYPH-1436A;Lo;0;L;;;;;N;;;;; +1436B;EGYPTIAN HIEROGLYPH-1436B;Lo;0;L;;;;;N;;;;; +1436C;EGYPTIAN HIEROGLYPH-1436C;Lo;0;L;;;;;N;;;;; +1436D;EGYPTIAN HIEROGLYPH-1436D;Lo;0;L;;;;;N;;;;; +1436E;EGYPTIAN HIEROGLYPH-1436E;Lo;0;L;;;;;N;;;;; +1436F;EGYPTIAN HIEROGLYPH-1436F;Lo;0;L;;;;;N;;;;; +14370;EGYPTIAN HIEROGLYPH-14370;Lo;0;L;;;;;N;;;;; +14371;EGYPTIAN HIEROGLYPH-14371;Lo;0;L;;;;;N;;;;; +14372;EGYPTIAN HIEROGLYPH-14372;Lo;0;L;;;;;N;;;;; +14373;EGYPTIAN HIEROGLYPH-14373;Lo;0;L;;;;;N;;;;; +14374;EGYPTIAN HIEROGLYPH-14374;Lo;0;L;;;;;N;;;;; +14375;EGYPTIAN HIEROGLYPH-14375;Lo;0;L;;;;;N;;;;; +14376;EGYPTIAN HIEROGLYPH-14376;Lo;0;L;;;;;N;;;;; +14377;EGYPTIAN HIEROGLYPH-14377;Lo;0;L;;;;;N;;;;; +14378;EGYPTIAN HIEROGLYPH-14378;Lo;0;L;;;;;N;;;;; +14379;EGYPTIAN HIEROGLYPH-14379;Lo;0;L;;;;;N;;;;; +1437A;EGYPTIAN HIEROGLYPH-1437A;Lo;0;L;;;;;N;;;;; +1437B;EGYPTIAN HIEROGLYPH-1437B;Lo;0;L;;;;;N;;;;; +1437C;EGYPTIAN HIEROGLYPH-1437C;Lo;0;L;;;;;N;;;;; +1437D;EGYPTIAN HIEROGLYPH-1437D;Lo;0;L;;;;;N;;;;; +1437E;EGYPTIAN HIEROGLYPH-1437E;Lo;0;L;;;;;N;;;;; +1437F;EGYPTIAN HIEROGLYPH-1437F;Lo;0;L;;;;;N;;;;; +14380;EGYPTIAN HIEROGLYPH-14380;Lo;0;L;;;;;N;;;;; +14381;EGYPTIAN HIEROGLYPH-14381;Lo;0;L;;;;;N;;;;; +14382;EGYPTIAN HIEROGLYPH-14382;Lo;0;L;;;;;N;;;;; +14383;EGYPTIAN HIEROGLYPH-14383;Lo;0;L;;;;;N;;;;; +14384;EGYPTIAN HIEROGLYPH-14384;Lo;0;L;;;;;N;;;;; +14385;EGYPTIAN HIEROGLYPH-14385;Lo;0;L;;;;;N;;;;; +14386;EGYPTIAN HIEROGLYPH-14386;Lo;0;L;;;;;N;;;;; +14387;EGYPTIAN HIEROGLYPH-14387;Lo;0;L;;;;;N;;;;; +14388;EGYPTIAN HIEROGLYPH-14388;Lo;0;L;;;;;N;;;;; +14389;EGYPTIAN HIEROGLYPH-14389;Lo;0;L;;;;;N;;;;; +1438A;EGYPTIAN HIEROGLYPH-1438A;Lo;0;L;;;;;N;;;;; +1438B;EGYPTIAN HIEROGLYPH-1438B;Lo;0;L;;;;;N;;;;; +1438C;EGYPTIAN HIEROGLYPH-1438C;Lo;0;L;;;;;N;;;;; +1438D;EGYPTIAN HIEROGLYPH-1438D;Lo;0;L;;;;;N;;;;; +1438E;EGYPTIAN HIEROGLYPH-1438E;Lo;0;L;;;;;N;;;;; +1438F;EGYPTIAN HIEROGLYPH-1438F;Lo;0;L;;;;;N;;;;; +14390;EGYPTIAN HIEROGLYPH-14390;Lo;0;L;;;;;N;;;;; +14391;EGYPTIAN HIEROGLYPH-14391;Lo;0;L;;;;;N;;;;; +14392;EGYPTIAN HIEROGLYPH-14392;Lo;0;L;;;;;N;;;;; +14393;EGYPTIAN HIEROGLYPH-14393;Lo;0;L;;;;;N;;;;; +14394;EGYPTIAN HIEROGLYPH-14394;Lo;0;L;;;;;N;;;;; +14395;EGYPTIAN HIEROGLYPH-14395;Lo;0;L;;;;;N;;;;; +14396;EGYPTIAN HIEROGLYPH-14396;Lo;0;L;;;;;N;;;;; +14397;EGYPTIAN HIEROGLYPH-14397;Lo;0;L;;;;;N;;;;; +14398;EGYPTIAN HIEROGLYPH-14398;Lo;0;L;;;;;N;;;;; +14399;EGYPTIAN HIEROGLYPH-14399;Lo;0;L;;;;;N;;;;; +1439A;EGYPTIAN HIEROGLYPH-1439A;Lo;0;L;;;;;N;;;;; +1439B;EGYPTIAN HIEROGLYPH-1439B;Lo;0;L;;;;;N;;;;; +1439C;EGYPTIAN HIEROGLYPH-1439C;Lo;0;L;;;;;N;;;;; +1439D;EGYPTIAN HIEROGLYPH-1439D;Lo;0;L;;;;;N;;;;; +1439E;EGYPTIAN HIEROGLYPH-1439E;Lo;0;L;;;;;N;;;;; +1439F;EGYPTIAN HIEROGLYPH-1439F;Lo;0;L;;;;;N;;;;; +143A0;EGYPTIAN HIEROGLYPH-143A0;Lo;0;L;;;;;N;;;;; +143A1;EGYPTIAN HIEROGLYPH-143A1;Lo;0;L;;;;;N;;;;; +143A2;EGYPTIAN HIEROGLYPH-143A2;Lo;0;L;;;;;N;;;;; +143A3;EGYPTIAN HIEROGLYPH-143A3;Lo;0;L;;;;;N;;;;; +143A4;EGYPTIAN HIEROGLYPH-143A4;Lo;0;L;;;;;N;;;;; +143A5;EGYPTIAN HIEROGLYPH-143A5;Lo;0;L;;;;;N;;;;; +143A6;EGYPTIAN HIEROGLYPH-143A6;Lo;0;L;;;;;N;;;;; +143A7;EGYPTIAN HIEROGLYPH-143A7;Lo;0;L;;;;;N;;;;; +143A8;EGYPTIAN HIEROGLYPH-143A8;Lo;0;L;;;;;N;;;;; +143A9;EGYPTIAN HIEROGLYPH-143A9;Lo;0;L;;;;;N;;;;; +143AA;EGYPTIAN HIEROGLYPH-143AA;Lo;0;L;;;;;N;;;;; +143AB;EGYPTIAN HIEROGLYPH-143AB;Lo;0;L;;;;;N;;;;; +143AC;EGYPTIAN HIEROGLYPH-143AC;Lo;0;L;;;;;N;;;;; +143AD;EGYPTIAN HIEROGLYPH-143AD;Lo;0;L;;;;;N;;;;; +143AE;EGYPTIAN HIEROGLYPH-143AE;Lo;0;L;;;;;N;;;;; +143AF;EGYPTIAN HIEROGLYPH-143AF;Lo;0;L;;;;;N;;;;; +143B0;EGYPTIAN HIEROGLYPH-143B0;Lo;0;L;;;;;N;;;;; +143B1;EGYPTIAN HIEROGLYPH-143B1;Lo;0;L;;;;;N;;;;; +143B2;EGYPTIAN HIEROGLYPH-143B2;Lo;0;L;;;;;N;;;;; +143B3;EGYPTIAN HIEROGLYPH-143B3;Lo;0;L;;;;;N;;;;; +143B4;EGYPTIAN HIEROGLYPH-143B4;Lo;0;L;;;;;N;;;;; +143B5;EGYPTIAN HIEROGLYPH-143B5;Lo;0;L;;;;;N;;;;; +143B6;EGYPTIAN HIEROGLYPH-143B6;Lo;0;L;;;;;N;;;;; +143B7;EGYPTIAN HIEROGLYPH-143B7;Lo;0;L;;;;;N;;;;; +143B8;EGYPTIAN HIEROGLYPH-143B8;Lo;0;L;;;;;N;;;;; +143B9;EGYPTIAN HIEROGLYPH-143B9;Lo;0;L;;;;;N;;;;; +143BA;EGYPTIAN HIEROGLYPH-143BA;Lo;0;L;;;;;N;;;;; +143BB;EGYPTIAN HIEROGLYPH-143BB;Lo;0;L;;;;;N;;;;; +143BC;EGYPTIAN HIEROGLYPH-143BC;Lo;0;L;;;;;N;;;;; +143BD;EGYPTIAN HIEROGLYPH-143BD;Lo;0;L;;;;;N;;;;; +143BE;EGYPTIAN HIEROGLYPH-143BE;Lo;0;L;;;;;N;;;;; +143BF;EGYPTIAN HIEROGLYPH-143BF;Lo;0;L;;;;;N;;;;; +143C0;EGYPTIAN HIEROGLYPH-143C0;Lo;0;L;;;;;N;;;;; +143C1;EGYPTIAN HIEROGLYPH-143C1;Lo;0;L;;;;;N;;;;; +143C2;EGYPTIAN HIEROGLYPH-143C2;Lo;0;L;;;;;N;;;;; +143C3;EGYPTIAN HIEROGLYPH-143C3;Lo;0;L;;;;;N;;;;; +143C4;EGYPTIAN HIEROGLYPH-143C4;Lo;0;L;;;;;N;;;;; +143C5;EGYPTIAN HIEROGLYPH-143C5;Lo;0;L;;;;;N;;;;; +143C6;EGYPTIAN HIEROGLYPH-143C6;Lo;0;L;;;;;N;;;;; +143C7;EGYPTIAN HIEROGLYPH-143C7;Lo;0;L;;;;;N;;;;; +143C8;EGYPTIAN HIEROGLYPH-143C8;Lo;0;L;;;;;N;;;;; +143C9;EGYPTIAN HIEROGLYPH-143C9;Lo;0;L;;;;;N;;;;; +143CA;EGYPTIAN HIEROGLYPH-143CA;Lo;0;L;;;;;N;;;;; +143CB;EGYPTIAN HIEROGLYPH-143CB;Lo;0;L;;;;;N;;;;; +143CC;EGYPTIAN HIEROGLYPH-143CC;Lo;0;L;;;;;N;;;;; +143CD;EGYPTIAN HIEROGLYPH-143CD;Lo;0;L;;;;;N;;;;; +143CE;EGYPTIAN HIEROGLYPH-143CE;Lo;0;L;;;;;N;;;;; +143CF;EGYPTIAN HIEROGLYPH-143CF;Lo;0;L;;;;;N;;;;; +143D0;EGYPTIAN HIEROGLYPH-143D0;Lo;0;L;;;;;N;;;;; +143D1;EGYPTIAN HIEROGLYPH-143D1;Lo;0;L;;;;;N;;;;; +143D2;EGYPTIAN HIEROGLYPH-143D2;Lo;0;L;;;;;N;;;;; +143D3;EGYPTIAN HIEROGLYPH-143D3;Lo;0;L;;;;;N;;;;; +143D4;EGYPTIAN HIEROGLYPH-143D4;Lo;0;L;;;;;N;;;;; +143D5;EGYPTIAN HIEROGLYPH-143D5;Lo;0;L;;;;;N;;;;; +143D6;EGYPTIAN HIEROGLYPH-143D6;Lo;0;L;;;;;N;;;;; +143D7;EGYPTIAN HIEROGLYPH-143D7;Lo;0;L;;;;;N;;;;; +143D8;EGYPTIAN HIEROGLYPH-143D8;Lo;0;L;;;;;N;;;;; +143D9;EGYPTIAN HIEROGLYPH-143D9;Lo;0;L;;;;;N;;;;; +143DA;EGYPTIAN HIEROGLYPH-143DA;Lo;0;L;;;;;N;;;;; +143DB;EGYPTIAN HIEROGLYPH-143DB;Lo;0;L;;;;;N;;;;; +143DC;EGYPTIAN HIEROGLYPH-143DC;Lo;0;L;;;;;N;;;;; +143DD;EGYPTIAN HIEROGLYPH-143DD;Lo;0;L;;;;;N;;;;; +143DE;EGYPTIAN HIEROGLYPH-143DE;Lo;0;L;;;;;N;;;;; +143DF;EGYPTIAN HIEROGLYPH-143DF;Lo;0;L;;;;;N;;;;; +143E0;EGYPTIAN HIEROGLYPH-143E0;Lo;0;L;;;;;N;;;;; +143E1;EGYPTIAN HIEROGLYPH-143E1;Lo;0;L;;;;;N;;;;; +143E2;EGYPTIAN HIEROGLYPH-143E2;Lo;0;L;;;;;N;;;;; +143E3;EGYPTIAN HIEROGLYPH-143E3;Lo;0;L;;;;;N;;;;; +143E4;EGYPTIAN HIEROGLYPH-143E4;Lo;0;L;;;;;N;;;;; +143E5;EGYPTIAN HIEROGLYPH-143E5;Lo;0;L;;;;;N;;;;; +143E6;EGYPTIAN HIEROGLYPH-143E6;Lo;0;L;;;;;N;;;;; +143E7;EGYPTIAN HIEROGLYPH-143E7;Lo;0;L;;;;;N;;;;; +143E8;EGYPTIAN HIEROGLYPH-143E8;Lo;0;L;;;;;N;;;;; +143E9;EGYPTIAN HIEROGLYPH-143E9;Lo;0;L;;;;;N;;;;; +143EA;EGYPTIAN HIEROGLYPH-143EA;Lo;0;L;;;;;N;;;;; +143EB;EGYPTIAN HIEROGLYPH-143EB;Lo;0;L;;;;;N;;;;; +143EC;EGYPTIAN HIEROGLYPH-143EC;Lo;0;L;;;;;N;;;;; +143ED;EGYPTIAN HIEROGLYPH-143ED;Lo;0;L;;;;;N;;;;; +143EE;EGYPTIAN HIEROGLYPH-143EE;Lo;0;L;;;;;N;;;;; +143EF;EGYPTIAN HIEROGLYPH-143EF;Lo;0;L;;;;;N;;;;; +143F0;EGYPTIAN HIEROGLYPH-143F0;Lo;0;L;;;;;N;;;;; +143F1;EGYPTIAN HIEROGLYPH-143F1;Lo;0;L;;;;;N;;;;; +143F2;EGYPTIAN HIEROGLYPH-143F2;Lo;0;L;;;;;N;;;;; +143F3;EGYPTIAN HIEROGLYPH-143F3;Lo;0;L;;;;;N;;;;; +143F4;EGYPTIAN HIEROGLYPH-143F4;Lo;0;L;;;;;N;;;;; +143F5;EGYPTIAN HIEROGLYPH-143F5;Lo;0;L;;;;;N;;;;; +143F6;EGYPTIAN HIEROGLYPH-143F6;Lo;0;L;;;;;N;;;;; +143F7;EGYPTIAN HIEROGLYPH-143F7;Lo;0;L;;;;;N;;;;; +143F8;EGYPTIAN HIEROGLYPH-143F8;Lo;0;L;;;;;N;;;;; +143F9;EGYPTIAN HIEROGLYPH-143F9;Lo;0;L;;;;;N;;;;; +143FA;EGYPTIAN HIEROGLYPH-143FA;Lo;0;L;;;;;N;;;;; 14400;ANATOLIAN HIEROGLYPH A001;Lo;0;L;;;;;N;;;;; 14401;ANATOLIAN HIEROGLYPH A002;Lo;0;L;;;;;N;;;;; 14402;ANATOLIAN HIEROGLYPH A003;Lo;0;L;;;;;N;;;;; @@ -24771,6 +29053,64 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;; 14644;ANATOLIAN HIEROGLYPH A528;Lo;0;L;;;;;N;;;;; 14645;ANATOLIAN HIEROGLYPH A529;Lo;0;L;;;;;N;;;;; 14646;ANATOLIAN HIEROGLYPH A530;Lo;0;L;;;;;N;;;;; +16100;GURUNG KHEMA LETTER A;Lo;0;L;;;;;N;;;;; +16101;GURUNG KHEMA LETTER KA;Lo;0;L;;;;;N;;;;; +16102;GURUNG KHEMA LETTER KHA;Lo;0;L;;;;;N;;;;; +16103;GURUNG KHEMA LETTER GA;Lo;0;L;;;;;N;;;;; +16104;GURUNG KHEMA LETTER GHA;Lo;0;L;;;;;N;;;;; +16105;GURUNG KHEMA LETTER NGA;Lo;0;L;;;;;N;;;;; +16106;GURUNG KHEMA LETTER CA;Lo;0;L;;;;;N;;;;; +16107;GURUNG KHEMA LETTER CHA;Lo;0;L;;;;;N;;;;; +16108;GURUNG KHEMA LETTER JA;Lo;0;L;;;;;N;;;;; +16109;GURUNG KHEMA LETTER JHA;Lo;0;L;;;;;N;;;;; +1610A;GURUNG KHEMA LETTER HA;Lo;0;L;;;;;N;;;;; +1610B;GURUNG KHEMA LETTER TTA;Lo;0;L;;;;;N;;;;; +1610C;GURUNG KHEMA LETTER TTHA;Lo;0;L;;;;;N;;;;; +1610D;GURUNG KHEMA LETTER DDA;Lo;0;L;;;;;N;;;;; +1610E;GURUNG KHEMA LETTER DDHA;Lo;0;L;;;;;N;;;;; +1610F;GURUNG KHEMA LETTER VA;Lo;0;L;;;;;N;;;;; +16110;GURUNG KHEMA LETTER TA;Lo;0;L;;;;;N;;;;; +16111;GURUNG KHEMA LETTER THA;Lo;0;L;;;;;N;;;;; +16112;GURUNG KHEMA LETTER DA;Lo;0;L;;;;;N;;;;; +16113;GURUNG KHEMA LETTER DHA;Lo;0;L;;;;;N;;;;; +16114;GURUNG KHEMA LETTER NA;Lo;0;L;;;;;N;;;;; +16115;GURUNG KHEMA LETTER PA;Lo;0;L;;;;;N;;;;; +16116;GURUNG KHEMA LETTER PHA;Lo;0;L;;;;;N;;;;; +16117;GURUNG KHEMA LETTER BA;Lo;0;L;;;;;N;;;;; +16118;GURUNG KHEMA LETTER BHA;Lo;0;L;;;;;N;;;;; +16119;GURUNG KHEMA LETTER MA;Lo;0;L;;;;;N;;;;; +1611A;GURUNG KHEMA LETTER YA;Lo;0;L;;;;;N;;;;; +1611B;GURUNG KHEMA LETTER RA;Lo;0;L;;;;;N;;;;; +1611C;GURUNG KHEMA LETTER LA;Lo;0;L;;;;;N;;;;; +1611D;GURUNG KHEMA LETTER SA;Lo;0;L;;;;;N;;;;; +1611E;GURUNG KHEMA VOWEL SIGN AA;Mn;0;NSM;;;;;N;;;;; +1611F;GURUNG KHEMA VOWEL SIGN I;Mn;0;NSM;;;;;N;;;;; +16120;GURUNG KHEMA VOWEL SIGN II;Mn;0;NSM;;;;;N;;;;; +16121;GURUNG KHEMA VOWEL SIGN U;Mn;0;NSM;1611E 1611E;;;;N;;;;; +16122;GURUNG KHEMA VOWEL SIGN UU;Mn;0;NSM;1611E 16129;;;;N;;;;; +16123;GURUNG KHEMA VOWEL SIGN E;Mn;0;NSM;1611E 1611F;;;;N;;;;; +16124;GURUNG KHEMA VOWEL SIGN EE;Mn;0;NSM;16129 1611F;;;;N;;;;; +16125;GURUNG KHEMA VOWEL SIGN AI;Mn;0;NSM;1611E 16120;;;;N;;;;; +16126;GURUNG KHEMA VOWEL SIGN O;Mn;0;NSM;16121 1611F;;;;N;;;;; +16127;GURUNG KHEMA VOWEL SIGN OO;Mn;0;NSM;16122 1611F;;;;N;;;;; +16128;GURUNG KHEMA VOWEL SIGN AU;Mn;0;NSM;16121 16120;;;;N;;;;; +16129;GURUNG KHEMA VOWEL LENGTH MARK;Mn;0;NSM;;;;;N;;;;; +1612A;GURUNG KHEMA CONSONANT SIGN MEDIAL YA;Mc;0;L;;;;;N;;;;; +1612B;GURUNG KHEMA CONSONANT SIGN MEDIAL VA;Mc;0;L;;;;;N;;;;; +1612C;GURUNG KHEMA CONSONANT SIGN MEDIAL HA;Mc;0;L;;;;;N;;;;; +1612D;GURUNG KHEMA SIGN ANUSVARA;Mn;0;NSM;;;;;N;;;;; +1612E;GURUNG KHEMA CONSONANT SIGN MEDIAL RA;Mn;0;NSM;;;;;N;;;;; +1612F;GURUNG KHEMA SIGN THOLHOMA;Mn;9;NSM;;;;;N;;;;; +16130;GURUNG KHEMA DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;; +16131;GURUNG KHEMA DIGIT ONE;Nd;0;L;;1;1;1;N;;;;; +16132;GURUNG KHEMA DIGIT TWO;Nd;0;L;;2;2;2;N;;;;; +16133;GURUNG KHEMA DIGIT THREE;Nd;0;L;;3;3;3;N;;;;; +16134;GURUNG KHEMA DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;; +16135;GURUNG KHEMA DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;; +16136;GURUNG KHEMA DIGIT SIX;Nd;0;L;;6;6;6;N;;;;; +16137;GURUNG KHEMA DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;; +16138;GURUNG KHEMA DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;; +16139;GURUNG KHEMA DIGIT NINE;Nd;0;L;;9;9;9;N;;;;; 16800;BAMUM LETTER PHASE-A NGKUE MFON;Lo;0;L;;;;;N;;;;; 16801;BAMUM LETTER PHASE-A GBIEE FON;Lo;0;L;;;;;N;;;;; 16802;BAMUM LETTER PHASE-A PON MFON PIPAEMGBIEE;Lo;0;L;;;;;N;;;;; @@ -25635,6 +29975,64 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;; 16B8D;PAHAWH HMONG CLAN SIGN TSWB;Lo;0;L;;;;;N;;;;; 16B8E;PAHAWH HMONG CLAN SIGN KWM;Lo;0;L;;;;;N;;;;; 16B8F;PAHAWH HMONG CLAN SIGN VWJ;Lo;0;L;;;;;N;;;;; +16D40;KIRAT RAI SIGN ANUSVARA;Lm;0;L;;;;;N;;;;; +16D41;KIRAT RAI SIGN TONPI;Lm;0;L;;;;;N;;;;; +16D42;KIRAT RAI SIGN VISARGA;Lm;0;L;;;;;N;;;;; +16D43;KIRAT RAI LETTER A;Lo;0;L;;;;;N;;;;; +16D44;KIRAT RAI LETTER KA;Lo;0;L;;;;;N;;;;; +16D45;KIRAT RAI LETTER KHA;Lo;0;L;;;;;N;;;;; +16D46;KIRAT RAI LETTER GA;Lo;0;L;;;;;N;;;;; +16D47;KIRAT RAI LETTER GHA;Lo;0;L;;;;;N;;;;; +16D48;KIRAT RAI LETTER NGA;Lo;0;L;;;;;N;;;;; +16D49;KIRAT RAI LETTER CA;Lo;0;L;;;;;N;;;;; +16D4A;KIRAT RAI LETTER CHA;Lo;0;L;;;;;N;;;;; +16D4B;KIRAT RAI LETTER JA;Lo;0;L;;;;;N;;;;; +16D4C;KIRAT RAI LETTER JHA;Lo;0;L;;;;;N;;;;; +16D4D;KIRAT RAI LETTER NYA;Lo;0;L;;;;;N;;;;; +16D4E;KIRAT RAI LETTER TTA;Lo;0;L;;;;;N;;;;; +16D4F;KIRAT RAI LETTER TTHA;Lo;0;L;;;;;N;;;;; +16D50;KIRAT RAI LETTER DDA;Lo;0;L;;;;;N;;;;; +16D51;KIRAT RAI LETTER DDHA;Lo;0;L;;;;;N;;;;; +16D52;KIRAT RAI LETTER TA;Lo;0;L;;;;;N;;;;; +16D53;KIRAT RAI LETTER THA;Lo;0;L;;;;;N;;;;; +16D54;KIRAT RAI LETTER DA;Lo;0;L;;;;;N;;;;; +16D55;KIRAT RAI LETTER DHA;Lo;0;L;;;;;N;;;;; +16D56;KIRAT RAI LETTER NA;Lo;0;L;;;;;N;;;;; +16D57;KIRAT RAI LETTER PA;Lo;0;L;;;;;N;;;;; +16D58;KIRAT RAI LETTER PHA;Lo;0;L;;;;;N;;;;; +16D59;KIRAT RAI LETTER BA;Lo;0;L;;;;;N;;;;; +16D5A;KIRAT RAI LETTER BHA;Lo;0;L;;;;;N;;;;; +16D5B;KIRAT RAI LETTER MA;Lo;0;L;;;;;N;;;;; +16D5C;KIRAT RAI LETTER YA;Lo;0;L;;;;;N;;;;; +16D5D;KIRAT RAI LETTER RA;Lo;0;L;;;;;N;;;;; +16D5E;KIRAT RAI LETTER LA;Lo;0;L;;;;;N;;;;; +16D5F;KIRAT RAI LETTER VA;Lo;0;L;;;;;N;;;;; +16D60;KIRAT RAI LETTER SA;Lo;0;L;;;;;N;;;;; +16D61;KIRAT RAI LETTER SHA;Lo;0;L;;;;;N;;;;; +16D62;KIRAT RAI LETTER HA;Lo;0;L;;;;;N;;;;; +16D63;KIRAT RAI VOWEL SIGN AA;Lo;0;L;;;;;N;;;;; +16D64;KIRAT RAI VOWEL SIGN I;Lo;0;L;;;;;N;;;;; +16D65;KIRAT RAI VOWEL SIGN U;Lo;0;L;;;;;N;;;;; +16D66;KIRAT RAI VOWEL SIGN UE;Lo;0;L;;;;;N;;;;; +16D67;KIRAT RAI VOWEL SIGN E;Lo;0;L;;;;;N;;;;; +16D68;KIRAT RAI VOWEL SIGN AI;Lo;0;L;16D67 16D67;;;;N;;;;; +16D69;KIRAT RAI VOWEL SIGN O;Lo;0;L;16D63 16D67;;;;N;;;;; +16D6A;KIRAT RAI VOWEL SIGN AU;Lo;0;L;16D69 16D67;;;;N;;;;; +16D6B;KIRAT RAI SIGN VIRAMA;Lm;0;L;;;;;N;;;;; +16D6C;KIRAT RAI SIGN SAAT;Lm;0;L;;;;;N;;;;; +16D6D;KIRAT RAI SIGN YUPI;Po;0;L;;;;;N;;;;; +16D6E;KIRAT RAI DANDA;Po;0;L;;;;;N;;;;; +16D6F;KIRAT RAI DOUBLE DANDA;Po;0;L;;;;;N;;;;; +16D70;KIRAT RAI DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;; +16D71;KIRAT RAI DIGIT ONE;Nd;0;L;;1;1;1;N;;;;; +16D72;KIRAT RAI DIGIT TWO;Nd;0;L;;2;2;2;N;;;;; +16D73;KIRAT RAI DIGIT THREE;Nd;0;L;;3;3;3;N;;;;; +16D74;KIRAT RAI DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;; +16D75;KIRAT RAI DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;; +16D76;KIRAT RAI DIGIT SIX;Nd;0;L;;6;6;6;N;;;;; +16D77;KIRAT RAI DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;; +16D78;KIRAT RAI DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;; +16D79;KIRAT RAI DIGIT NINE;Nd;0;L;;9;9;9;N;;;;; 16E40;MEDEFAIDRIN CAPITAL LETTER M;Lu;0;L;;;;;N;;;;16E60; 16E41;MEDEFAIDRIN CAPITAL LETTER S;Lu;0;L;;;;;N;;;;16E61; 16E42;MEDEFAIDRIN CAPITAL LETTER V;Lu;0;L;;;;;N;;;;16E62; @@ -27122,6 +31520,7 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;; 18CD3;KHITAN SMALL SCRIPT CHARACTER-18CD3;Lo;0;L;;;;;N;;;;; 18CD4;KHITAN SMALL SCRIPT CHARACTER-18CD4;Lo;0;L;;;;;N;;;;; 18CD5;KHITAN SMALL SCRIPT CHARACTER-18CD5;Lo;0;L;;;;;N;;;;; +18CFF;KHITAN SMALL SCRIPT CHARACTER-18CFF;Lo;0;L;;;;;N;;;;; 18D00;<Tangut Ideograph Supplement, First>;Lo;0;L;;;;;N;;;;; 18D08;<Tangut Ideograph Supplement, Last>;Lo;0;L;;;;;N;;;;; 1AFF0;KATAKANA LETTER MINNAN TONE-2;Lm;0;L;;;;;N;;;;; @@ -27980,6 +32379,692 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;; 1BCA1;SHORTHAND FORMAT CONTINUING OVERLAP;Cf;0;BN;;;;;N;;;;; 1BCA2;SHORTHAND FORMAT DOWN STEP;Cf;0;BN;;;;;N;;;;; 1BCA3;SHORTHAND FORMAT UP STEP;Cf;0;BN;;;;;N;;;;; +1CC00;UP-POINTING GO-KART;So;0;ON;;;;;N;;;;; +1CC01;RIGHT-POINTING GO-KART;So;0;ON;;;;;N;;;;; +1CC02;LEFT-POINTING STICK FIGURE;So;0;ON;;;;;N;;;;; +1CC03;RIGHT-POINTING STICK FIGURE;So;0;ON;;;;;N;;;;; +1CC04;DOWN-POINTING STICK FIGURE;So;0;ON;;;;;N;;;;; +1CC05;LOWER HORIZONTAL RULER SEGMENT;So;0;ON;;;;;N;;;;; +1CC06;RIGHT VERTICAL RULER SEGMENT;So;0;ON;;;;;N;;;;; +1CC07;LOWER RIGHT RULER SEGMENT;So;0;ON;;;;;N;;;;; +1CC08;ANTENNA;So;0;ON;;;;;N;;;;; +1CC09;HORIZONTAL RESISTOR SEGMENT;So;0;ON;;;;;N;;;;; +1CC0A;VERTICAL RESISTOR SEGMENT;So;0;ON;;;;;N;;;;; +1CC0B;LEFT THIRD INDUCTOR;So;0;ON;;;;;N;;;;; +1CC0C;MIDDLE THIRD INDUCTOR;So;0;ON;;;;;N;;;;; +1CC0D;RIGHT THIRD INDUCTOR;So;0;ON;;;;;N;;;;; +1CC0E;LEFT-POINTING DIODE;So;0;ON;;;;;N;;;;; +1CC0F;RIGHT-POINTING DIODE;So;0;ON;;;;;N;;;;; +1CC10;NPN TRANSISTOR;So;0;ON;;;;;N;;;;; +1CC11;PNP TRANSISTOR;So;0;ON;;;;;N;;;;; +1CC12;RECEPTACLE;So;0;ON;;;;;N;;;;; +1CC13;HORIZONTAL CAPACITOR;So;0;ON;;;;;N;;;;; +1CC14;VERTICAL CAPACITOR;So;0;ON;;;;;N;;;;; +1CC15;LOGIC GATE OR;So;0;ON;;;;;N;;;;; +1CC16;LOGIC GATE AND;So;0;ON;;;;;N;;;;; +1CC17;LOGIC GATE INVERTED INPUTS;So;0;ON;;;;;N;;;;; +1CC18;LOGIC GATE INVERTED OUTPUT;So;0;ON;;;;;N;;;;; +1CC19;LOGIC GATE BUFFER;So;0;ON;;;;;N;;;;; +1CC1A;LOGIC GATE BUFFER WITH INVERTED INPUT;So;0;ON;;;;;N;;;;; +1CC1B;BOX DRAWINGS LIGHT HORIZONTAL AND UPPER RIGHT;So;0;ON;;;;;N;;;;; +1CC1C;BOX DRAWINGS LIGHT HORIZONTAL AND LOWER RIGHT;So;0;ON;;;;;N;;;;; +1CC1D;BOX DRAWINGS LIGHT TOP AND UPPER LEFT;So;0;ON;;;;;N;;;;; +1CC1E;BOX DRAWINGS LIGHT BOTTOM AND LOWER LEFT;So;0;ON;;;;;N;;;;; +1CC1F;BOX DRAWINGS DOUBLE DIAGONAL UPPER RIGHT TO LOWER LEFT;So;0;ON;;;;;N;;;;; +1CC20;BOX DRAWINGS DOUBLE DIAGONAL UPPER LEFT TO LOWER RIGHT;So;0;ON;;;;;N;;;;; +1CC21;SEPARATED BLOCK QUADRANT-1;So;0;ON;;;;;N;;;;; +1CC22;SEPARATED BLOCK QUADRANT-2;So;0;ON;;;;;N;;;;; +1CC23;SEPARATED BLOCK QUADRANT-12;So;0;ON;;;;;N;;;;; +1CC24;SEPARATED BLOCK QUADRANT-3;So;0;ON;;;;;N;;;;; +1CC25;SEPARATED BLOCK QUADRANT-13;So;0;ON;;;;;N;;;;; +1CC26;SEPARATED BLOCK QUADRANT-23;So;0;ON;;;;;N;;;;; +1CC27;SEPARATED BLOCK QUADRANT-123;So;0;ON;;;;;N;;;;; +1CC28;SEPARATED BLOCK QUADRANT-4;So;0;ON;;;;;N;;;;; +1CC29;SEPARATED BLOCK QUADRANT-14;So;0;ON;;;;;N;;;;; +1CC2A;SEPARATED BLOCK QUADRANT-24;So;0;ON;;;;;N;;;;; +1CC2B;SEPARATED BLOCK QUADRANT-124;So;0;ON;;;;;N;;;;; +1CC2C;SEPARATED BLOCK QUADRANT-34;So;0;ON;;;;;N;;;;; +1CC2D;SEPARATED BLOCK QUADRANT-134;So;0;ON;;;;;N;;;;; +1CC2E;SEPARATED BLOCK QUADRANT-234;So;0;ON;;;;;N;;;;; +1CC2F;SEPARATED BLOCK QUADRANT-1234;So;0;ON;;;;;N;;;;; +1CC30;UPPER LEFT TWELFTH CIRCLE;So;0;ON;;;;;N;;;;; +1CC31;UPPER CENTRE LEFT TWELFTH CIRCLE;So;0;ON;;;;;N;;;;; +1CC32;UPPER CENTRE RIGHT TWELFTH CIRCLE;So;0;ON;;;;;N;;;;; +1CC33;UPPER RIGHT TWELFTH CIRCLE;So;0;ON;;;;;N;;;;; +1CC34;UPPER MIDDLE LEFT TWELFTH CIRCLE;So;0;ON;;;;;N;;;;; +1CC35;UPPER LEFT QUARTER CIRCLE;So;0;ON;;;;;N;;;;; +1CC36;UPPER RIGHT QUARTER CIRCLE;So;0;ON;;;;;N;;;;; +1CC37;UPPER MIDDLE RIGHT TWELFTH CIRCLE;So;0;ON;;;;;N;;;;; +1CC38;LOWER MIDDLE LEFT TWELFTH CIRCLE;So;0;ON;;;;;N;;;;; +1CC39;LOWER LEFT QUARTER CIRCLE;So;0;ON;;;;;N;;;;; +1CC3A;LOWER RIGHT QUARTER CIRCLE;So;0;ON;;;;;N;;;;; +1CC3B;LOWER MIDDLE RIGHT TWELFTH CIRCLE;So;0;ON;;;;;N;;;;; +1CC3C;LOWER LEFT TWELFTH CIRCLE;So;0;ON;;;;;N;;;;; +1CC3D;LOWER CENTRE LEFT TWELFTH CIRCLE;So;0;ON;;;;;N;;;;; +1CC3E;LOWER CENTRE RIGHT TWELFTH CIRCLE;So;0;ON;;;;;N;;;;; +1CC3F;LOWER RIGHT TWELFTH CIRCLE;So;0;ON;;;;;N;;;;; +1CC40;SPARSE HORIZONTAL FILL;So;0;ON;;;;;N;;;;; +1CC41;SPARSE VERTICAL FILL;So;0;ON;;;;;N;;;;; +1CC42;ORTHOGONAL CROSSHATCH FILL;So;0;ON;;;;;N;;;;; +1CC43;DIAGONAL CROSSHATCH FILL;So;0;ON;;;;;N;;;;; +1CC44;DENSE VERTICAL FILL;So;0;ON;;;;;N;;;;; +1CC45;DENSE HORIZONTAL FILL;So;0;ON;;;;;N;;;;; +1CC46;SPECKLE FILL FRAME-1;So;0;ON;;;;;N;;;;; +1CC47;SPECKLE FILL FRAME-2;So;0;ON;;;;;N;;;;; +1CC48;LEFT-FACING BASSINET;So;0;ON;;;;;N;;;;; +1CC49;RIGHT-FACING BASSINET;So;0;ON;;;;;N;;;;; +1CC4A;FLYING SAUCER WITH BEAMS;So;0;ON;;;;;N;;;;; +1CC4B;FLYING SAUCER WITHOUT BEAMS;So;0;ON;;;;;N;;;;; +1CC4C;ALIEN MONSTER OPEN JAWS;So;0;ON;;;;;N;;;;; +1CC4D;ALIEN MONSTER CLOSED JAWS;So;0;ON;;;;;N;;;;; +1CC4E;ALIEN SQUID OPEN TENTACLES;So;0;ON;;;;;N;;;;; +1CC4F;ALIEN SQUID CLOSED TENTACLES;So;0;ON;;;;;N;;;;; +1CC50;ALIEN CRAB STEPPING RIGHT;So;0;ON;;;;;N;;;;; +1CC51;ALIEN CRAB STEPPING LEFT;So;0;ON;;;;;N;;;;; +1CC52;ALIEN SPIDER CROUCHING;So;0;ON;;;;;N;;;;; +1CC53;ALIEN SPIDER SPREAD;So;0;ON;;;;;N;;;;; +1CC54;ALIEN MONSTER STEP-1;So;0;ON;;;;;N;;;;; +1CC55;ALIEN MONSTER STEP-2;So;0;ON;;;;;N;;;;; +1CC56;LEFT-POINTING ROCKET SHIP;So;0;ON;;;;;N;;;;; +1CC57;UP-POINTING ROCKET SHIP;So;0;ON;;;;;N;;;;; +1CC58;RIGHT-POINTING ROCKET SHIP;So;0;ON;;;;;N;;;;; +1CC59;DOWN-POINTING ROCKET SHIP;So;0;ON;;;;;N;;;;; +1CC5A;TOP HALF LEFT-FACING ROBOT;So;0;ON;;;;;N;;;;; +1CC5B;TOP HALF FORWARD-FACING ROBOT;So;0;ON;;;;;N;;;;; +1CC5C;TOP HALF RIGHT-FACING ROBOT;So;0;ON;;;;;N;;;;; +1CC5D;BOTTOM HALF LEFT-FACING ROBOT;So;0;ON;;;;;N;;;;; +1CC5E;BOTTOM HALF FORWARD-FACING ROBOT;So;0;ON;;;;;N;;;;; +1CC5F;BOTTOM HALF RIGHT-FACING ROBOT;So;0;ON;;;;;N;;;;; +1CC60;LEFT-POINTING ATOMIC BOMB;So;0;ON;;;;;N;;;;; +1CC61;UP-POINTING ATOMIC BOMB;So;0;ON;;;;;N;;;;; +1CC62;RIGHT-POINTING ATOMIC BOMB;So;0;ON;;;;;N;;;;; +1CC63;DOWN-POINTING ATOMIC BOMB;So;0;ON;;;;;N;;;;; +1CC64;MUSHROOM CLOUD;So;0;ON;;;;;N;;;;; +1CC65;LEFT-POINTING RIFLE;So;0;ON;;;;;N;;;;; +1CC66;UP-POINTING RIFLE;So;0;ON;;;;;N;;;;; +1CC67;RIGHT-POINTING RIFLE;So;0;ON;;;;;N;;;;; +1CC68;DOWN-POINTING RIFLE;So;0;ON;;;;;N;;;;; +1CC69;EIGHT RAYS INWARD;So;0;ON;;;;;N;;;;; +1CC6A;EIGHT RAYS OUTWARD;So;0;ON;;;;;N;;;;; +1CC6B;BLACK LARGE CIRCLE MINUS LEFT QUARTER SECTION;So;0;ON;;;;;N;;;;; +1CC6C;BLACK LARGE CIRCLE MINUS UPPER QUARTER SECTION;So;0;ON;;;;;N;;;;; +1CC6D;BLACK LARGE CIRCLE MINUS RIGHT QUARTER SECTION;So;0;ON;;;;;N;;;;; +1CC6E;BLACK LARGE CIRCLE MINUS LOWER QUARTER SECTION;So;0;ON;;;;;N;;;;; +1CC6F;BLACK NEUTRAL FACE;So;0;ON;;;;;N;;;;; +1CC70;LEFT-FACING SNAKE HEAD WITH OPEN MOUTH;So;0;ON;;;;;N;;;;; +1CC71;UP-FACING SNAKE HEAD WITH OPEN MOUTH;So;0;ON;;;;;N;;;;; +1CC72;RIGHT-FACING SNAKE HEAD WITH OPEN MOUTH;So;0;ON;;;;;N;;;;; +1CC73;DOWN-FACING SNAKE HEAD WITH OPEN MOUTH;So;0;ON;;;;;N;;;;; +1CC74;LEFT-FACING SNAKE HEAD WITH CLOSED MOUTH;So;0;ON;;;;;N;;;;; +1CC75;UP-FACING SNAKE HEAD WITH CLOSED MOUTH;So;0;ON;;;;;N;;;;; +1CC76;RIGHT-FACING SNAKE HEAD WITH CLOSED MOUTH;So;0;ON;;;;;N;;;;; +1CC77;DOWN-FACING SNAKE HEAD WITH CLOSED MOUTH;So;0;ON;;;;;N;;;;; +1CC78;LEFT-POINTING ENERGY WAVE;So;0;ON;;;;;N;;;;; +1CC79;UP-POINTING ENERGY WAVE;So;0;ON;;;;;N;;;;; +1CC7A;RIGHT-POINTING ENERGY WAVE;So;0;ON;;;;;N;;;;; +1CC7B;DOWN-POINTING ENERGY WAVE;So;0;ON;;;;;N;;;;; +1CC7C;SQUARE SPIRAL FROM TOP LEFT;So;0;ON;;;;;N;;;;; +1CC7D;SQUARE SPIRAL FROM TOP RIGHT;So;0;ON;;;;;N;;;;; +1CC7E;SQUARE SPIRAL FROM BOTTOM RIGHT;So;0;ON;;;;;N;;;;; +1CC7F;SQUARE SPIRAL FROM BOTTOM LEFT;So;0;ON;;;;;N;;;;; +1CC80;STRIPED LEFT-POINTING TRIANGLE;So;0;ON;;;;;N;;;;; +1CC81;STRIPED UP-POINTING TRIANGLE;So;0;ON;;;;;N;;;;; +1CC82;STRIPED RIGHT-POINTING TRIANGLE;So;0;ON;;;;;N;;;;; +1CC83;STRIPED DOWN-POINTING TRIANGLE;So;0;ON;;;;;N;;;;; +1CC84;VERTICAL LADDER;So;0;ON;;;;;N;;;;; +1CC85;HORIZONTAL LADDER;So;0;ON;;;;;N;;;;; +1CC86;WHITE LOWER LEFT POINTER;So;0;ON;;;;;N;;;;; +1CC87;WHITE LOWER RIGHT POINTER;So;0;ON;;;;;N;;;;; +1CC88;TWO RINGS ALIGNED HORIZONTALLY;So;0;ON;;;;;N;;;;; +1CC89;SQUARE FOUR CORNER SALTIRES;So;0;ON;;;;;N;;;;; +1CC8A;SQUARE FOUR CORNER DIAGONALS;So;0;ON;;;;;N;;;;; +1CC8B;SQUARE FOUR CORNER BLACK TRIANGLES;So;0;ON;;;;;N;;;;; +1CC8C;SQUARE APERTURE;So;0;ON;;;;;N;;;;; +1CC8D;INVERSE BLACK DIAMOND;So;0;ON;;;;;N;;;;; +1CC8E;LEFT AND UPPER ONE EIGHTH BLOCK CONTAINING BLACK SMALL SQUARE;So;0;ON;;;;;N;;;;; +1CC8F;INVERSE BLACK SMALL SQUARE;So;0;ON;;;;;N;;;;; +1CC90;VERTICAL LINE WITH FOUR TICK MARKS;So;0;ON;;;;;N;;;;; +1CC91;HORIZONTAL LINE WITH FOUR TICK MARKS;So;0;ON;;;;;N;;;;; +1CC92;LEFT-FACING FISH;So;0;ON;;;;;N;;;;; +1CC93;RIGHT-FACING FISH;So;0;ON;;;;;N;;;;; +1CC94;LEFT-FACING FISH WITH OPEN MOUTH;So;0;ON;;;;;N;;;;; +1CC95;RIGHT-FACING FISH WITH OPEN MOUTH;So;0;ON;;;;;N;;;;; +1CC96;FLAPPING BIRD;So;0;ON;;;;;N;;;;; +1CC97;LEFT-POINTING RACING CAR;So;0;ON;;;;;N;;;;; +1CC98;UP-POINTING RACING CAR;So;0;ON;;;;;N;;;;; +1CC99;RIGHT-POINTING RACING CAR;So;0;ON;;;;;N;;;;; +1CC9A;DOWN-POINTING RACING CAR;So;0;ON;;;;;N;;;;; +1CC9B;HORIZONTAL RACING CAR;So;0;ON;;;;;N;;;;; +1CC9C;VERTICAL RACING CAR;So;0;ON;;;;;N;;;;; +1CC9D;VERTICAL GO-KART;So;0;ON;;;;;N;;;;; +1CC9E;LEFT-POINTING TANK;So;0;ON;;;;;N;;;;; +1CC9F;RIGHT-POINTING TANK;So;0;ON;;;;;N;;;;; +1CCA0;LEFT-POINTING ROCKET BOOSTER;So;0;ON;;;;;N;;;;; +1CCA1;RIGHT-POINTING ROCKET BOOSTER;So;0;ON;;;;;N;;;;; +1CCA2;LEFT-POINTING ROLLER COASTER CAR;So;0;ON;;;;;N;;;;; +1CCA3;RIGHT-POINTING ROLLER COASTER CAR;So;0;ON;;;;;N;;;;; +1CCA4;LEFT HALF FLYING SAUCER;So;0;ON;;;;;N;;;;; +1CCA5;RIGHT HALF FLYING SAUCER;So;0;ON;;;;;N;;;;; +1CCA6;UPPER LEFT QUADRANT FACE WITH OPEN EYES;So;0;ON;;;;;N;;;;; +1CCA7;UPPER RIGHT QUADRANT FACE WITH OPEN EYES;So;0;ON;;;;;N;;;;; +1CCA8;UPPER LEFT QUADRANT FACE WITH CLOSED EYES;So;0;ON;;;;;N;;;;; +1CCA9;UPPER RIGHT QUADRANT FACE WITH CLOSED EYES;So;0;ON;;;;;N;;;;; +1CCAA;LOWER LEFT QUADRANT SMILING FACE;So;0;ON;;;;;N;;;;; +1CCAB;LOWER RIGHT QUADRANT SMILING FACE;So;0;ON;;;;;N;;;;; +1CCAC;LOWER LEFT QUADRANT NEUTRAL FACE;So;0;ON;;;;;N;;;;; +1CCAD;LOWER RIGHT QUADRANT NEUTRAL FACE;So;0;ON;;;;;N;;;;; +1CCAE;LOWER LEFT QUADRANT FACE WITH OPEN MOUTH;So;0;ON;;;;;N;;;;; +1CCAF;LOWER RIGHT QUADRANT FACE WITH OPEN MOUTH;So;0;ON;;;;;N;;;;; +1CCB0;LOWER LEFT QUADRANT FROWNING FACE;So;0;ON;;;;;N;;;;; +1CCB1;LOWER RIGHT QUADRANT FROWNING FACE;So;0;ON;;;;;N;;;;; +1CCB2;UPPER LEFT QUADRANT TELEVISION;So;0;ON;;;;;N;;;;; +1CCB3;UPPER RIGHT QUADRANT TELEVISION;So;0;ON;;;;;N;;;;; +1CCB4;LOWER LEFT QUADRANT TELEVISION;So;0;ON;;;;;N;;;;; +1CCB5;LOWER RIGHT QUADRANT TELEVISION;So;0;ON;;;;;N;;;;; +1CCB6;UPPER LEFT QUADRANT MICROCOMPUTER;So;0;ON;;;;;N;;;;; +1CCB7;UPPER RIGHT QUADRANT MICROCOMPUTER;So;0;ON;;;;;N;;;;; +1CCB8;LOWER LEFT QUADRANT MICROCOMPUTER;So;0;ON;;;;;N;;;;; +1CCB9;LOWER RIGHT QUADRANT MICROCOMPUTER;So;0;ON;;;;;N;;;;; +1CCBA;UPPER LEFT QUADRANT CHESS KING;So;0;ON;;;;;N;;;;; +1CCBB;UPPER RIGHT QUADRANT CHESS KING;So;0;ON;;;;;N;;;;; +1CCBC;LOWER LEFT QUADRANT CHESS KING;So;0;ON;;;;;N;;;;; +1CCBD;LOWER RIGHT QUADRANT CHESS KING;So;0;ON;;;;;N;;;;; +1CCBE;UPPER LEFT QUADRANT CHESS QUEEN;So;0;ON;;;;;N;;;;; +1CCBF;UPPER RIGHT QUADRANT CHESS QUEEN;So;0;ON;;;;;N;;;;; +1CCC0;LOWER LEFT QUADRANT CHESS QUEEN;So;0;ON;;;;;N;;;;; +1CCC1;LOWER RIGHT QUADRANT CHESS QUEEN;So;0;ON;;;;;N;;;;; +1CCC2;UPPER LEFT QUADRANT CHESS ROOK;So;0;ON;;;;;N;;;;; +1CCC3;UPPER RIGHT QUADRANT CHESS ROOK;So;0;ON;;;;;N;;;;; +1CCC4;LOWER LEFT QUADRANT CHESS ROOK;So;0;ON;;;;;N;;;;; +1CCC5;LOWER RIGHT QUADRANT CHESS ROOK;So;0;ON;;;;;N;;;;; +1CCC6;UPPER LEFT QUADRANT CHESS BISHOP;So;0;ON;;;;;N;;;;; +1CCC7;UPPER RIGHT QUADRANT CHESS BISHOP;So;0;ON;;;;;N;;;;; +1CCC8;LOWER LEFT QUADRANT CHESS BISHOP;So;0;ON;;;;;N;;;;; +1CCC9;LOWER RIGHT QUADRANT CHESS BISHOP;So;0;ON;;;;;N;;;;; +1CCCA;UPPER LEFT QUADRANT CHESS KNIGHT;So;0;ON;;;;;N;;;;; +1CCCB;UPPER RIGHT QUADRANT CHESS KNIGHT;So;0;ON;;;;;N;;;;; +1CCCC;LOWER LEFT QUADRANT CHESS KNIGHT;So;0;ON;;;;;N;;;;; +1CCCD;LOWER RIGHT QUADRANT CHESS KNIGHT;So;0;ON;;;;;N;;;;; +1CCCE;UPPER LEFT QUADRANT CHESS PAWN;So;0;ON;;;;;N;;;;; +1CCCF;UPPER RIGHT QUADRANT CHESS PAWN;So;0;ON;;;;;N;;;;; +1CCD0;LOWER LEFT QUADRANT CHESS PAWN;So;0;ON;;;;;N;;;;; +1CCD1;LOWER RIGHT QUADRANT CHESS PAWN;So;0;ON;;;;;N;;;;; +1CCD2;UPPER LEFT QUADRANT STANDING KNIGHT;So;0;ON;;;;;N;;;;; +1CCD3;UPPER RIGHT QUADRANT STANDING KNIGHT;So;0;ON;;;;;N;;;;; +1CCD4;LOWER LEFT QUADRANT STANDING KNIGHT;So;0;ON;;;;;N;;;;; +1CCD5;LOWER RIGHT QUADRANT STANDING KNIGHT;So;0;ON;;;;;N;;;;; +1CCD6;OUTLINED LATIN CAPITAL LETTER A;So;0;L;<font> 0041;;;;N;;;;; +1CCD7;OUTLINED LATIN CAPITAL LETTER B;So;0;L;<font> 0042;;;;N;;;;; +1CCD8;OUTLINED LATIN CAPITAL LETTER C;So;0;L;<font> 0043;;;;N;;;;; +1CCD9;OUTLINED LATIN CAPITAL LETTER D;So;0;L;<font> 0044;;;;N;;;;; +1CCDA;OUTLINED LATIN CAPITAL LETTER E;So;0;L;<font> 0045;;;;N;;;;; +1CCDB;OUTLINED LATIN CAPITAL LETTER F;So;0;L;<font> 0046;;;;N;;;;; +1CCDC;OUTLINED LATIN CAPITAL LETTER G;So;0;L;<font> 0047;;;;N;;;;; +1CCDD;OUTLINED LATIN CAPITAL LETTER H;So;0;L;<font> 0048;;;;N;;;;; +1CCDE;OUTLINED LATIN CAPITAL LETTER I;So;0;L;<font> 0049;;;;N;;;;; +1CCDF;OUTLINED LATIN CAPITAL LETTER J;So;0;L;<font> 004A;;;;N;;;;; +1CCE0;OUTLINED LATIN CAPITAL LETTER K;So;0;L;<font> 004B;;;;N;;;;; +1CCE1;OUTLINED LATIN CAPITAL LETTER L;So;0;L;<font> 004C;;;;N;;;;; +1CCE2;OUTLINED LATIN CAPITAL LETTER M;So;0;L;<font> 004D;;;;N;;;;; +1CCE3;OUTLINED LATIN CAPITAL LETTER N;So;0;L;<font> 004E;;;;N;;;;; +1CCE4;OUTLINED LATIN CAPITAL LETTER O;So;0;L;<font> 004F;;;;N;;;;; +1CCE5;OUTLINED LATIN CAPITAL LETTER P;So;0;L;<font> 0050;;;;N;;;;; +1CCE6;OUTLINED LATIN CAPITAL LETTER Q;So;0;L;<font> 0051;;;;N;;;;; +1CCE7;OUTLINED LATIN CAPITAL LETTER R;So;0;L;<font> 0052;;;;N;;;;; +1CCE8;OUTLINED LATIN CAPITAL LETTER S;So;0;L;<font> 0053;;;;N;;;;; +1CCE9;OUTLINED LATIN CAPITAL LETTER T;So;0;L;<font> 0054;;;;N;;;;; +1CCEA;OUTLINED LATIN CAPITAL LETTER U;So;0;L;<font> 0055;;;;N;;;;; +1CCEB;OUTLINED LATIN CAPITAL LETTER V;So;0;L;<font> 0056;;;;N;;;;; +1CCEC;OUTLINED LATIN CAPITAL LETTER W;So;0;L;<font> 0057;;;;N;;;;; +1CCED;OUTLINED LATIN CAPITAL LETTER X;So;0;L;<font> 0058;;;;N;;;;; +1CCEE;OUTLINED LATIN CAPITAL LETTER Y;So;0;L;<font> 0059;;;;N;;;;; +1CCEF;OUTLINED LATIN CAPITAL LETTER Z;So;0;L;<font> 005A;;;;N;;;;; +1CCF0;OUTLINED DIGIT ZERO;Nd;0;EN;<font> 0030;0;0;0;N;;;;; +1CCF1;OUTLINED DIGIT ONE;Nd;0;EN;<font> 0031;1;1;1;N;;;;; +1CCF2;OUTLINED DIGIT TWO;Nd;0;EN;<font> 0032;2;2;2;N;;;;; +1CCF3;OUTLINED DIGIT THREE;Nd;0;EN;<font> 0033;3;3;3;N;;;;; +1CCF4;OUTLINED DIGIT FOUR;Nd;0;EN;<font> 0034;4;4;4;N;;;;; +1CCF5;OUTLINED DIGIT FIVE;Nd;0;EN;<font> 0035;5;5;5;N;;;;; +1CCF6;OUTLINED DIGIT SIX;Nd;0;EN;<font> 0036;6;6;6;N;;;;; +1CCF7;OUTLINED DIGIT SEVEN;Nd;0;EN;<font> 0037;7;7;7;N;;;;; +1CCF8;OUTLINED DIGIT EIGHT;Nd;0;EN;<font> 0038;8;8;8;N;;;;; +1CCF9;OUTLINED DIGIT NINE;Nd;0;EN;<font> 0039;9;9;9;N;;;;; +1CD00;BLOCK OCTANT-3;So;0;ON;;;;;N;;;;; +1CD01;BLOCK OCTANT-23;So;0;ON;;;;;N;;;;; +1CD02;BLOCK OCTANT-123;So;0;ON;;;;;N;;;;; +1CD03;BLOCK OCTANT-4;So;0;ON;;;;;N;;;;; +1CD04;BLOCK OCTANT-14;So;0;ON;;;;;N;;;;; +1CD05;BLOCK OCTANT-124;So;0;ON;;;;;N;;;;; +1CD06;BLOCK OCTANT-34;So;0;ON;;;;;N;;;;; +1CD07;BLOCK OCTANT-134;So;0;ON;;;;;N;;;;; +1CD08;BLOCK OCTANT-234;So;0;ON;;;;;N;;;;; +1CD09;BLOCK OCTANT-5;So;0;ON;;;;;N;;;;; +1CD0A;BLOCK OCTANT-15;So;0;ON;;;;;N;;;;; +1CD0B;BLOCK OCTANT-25;So;0;ON;;;;;N;;;;; +1CD0C;BLOCK OCTANT-125;So;0;ON;;;;;N;;;;; +1CD0D;BLOCK OCTANT-135;So;0;ON;;;;;N;;;;; +1CD0E;BLOCK OCTANT-235;So;0;ON;;;;;N;;;;; +1CD0F;BLOCK OCTANT-1235;So;0;ON;;;;;N;;;;; +1CD10;BLOCK OCTANT-45;So;0;ON;;;;;N;;;;; +1CD11;BLOCK OCTANT-145;So;0;ON;;;;;N;;;;; +1CD12;BLOCK OCTANT-245;So;0;ON;;;;;N;;;;; +1CD13;BLOCK OCTANT-1245;So;0;ON;;;;;N;;;;; +1CD14;BLOCK OCTANT-345;So;0;ON;;;;;N;;;;; +1CD15;BLOCK OCTANT-1345;So;0;ON;;;;;N;;;;; +1CD16;BLOCK OCTANT-2345;So;0;ON;;;;;N;;;;; +1CD17;BLOCK OCTANT-12345;So;0;ON;;;;;N;;;;; +1CD18;BLOCK OCTANT-6;So;0;ON;;;;;N;;;;; +1CD19;BLOCK OCTANT-16;So;0;ON;;;;;N;;;;; +1CD1A;BLOCK OCTANT-26;So;0;ON;;;;;N;;;;; +1CD1B;BLOCK OCTANT-126;So;0;ON;;;;;N;;;;; +1CD1C;BLOCK OCTANT-36;So;0;ON;;;;;N;;;;; +1CD1D;BLOCK OCTANT-136;So;0;ON;;;;;N;;;;; +1CD1E;BLOCK OCTANT-236;So;0;ON;;;;;N;;;;; +1CD1F;BLOCK OCTANT-1236;So;0;ON;;;;;N;;;;; +1CD20;BLOCK OCTANT-146;So;0;ON;;;;;N;;;;; +1CD21;BLOCK OCTANT-246;So;0;ON;;;;;N;;;;; +1CD22;BLOCK OCTANT-1246;So;0;ON;;;;;N;;;;; +1CD23;BLOCK OCTANT-346;So;0;ON;;;;;N;;;;; +1CD24;BLOCK OCTANT-1346;So;0;ON;;;;;N;;;;; +1CD25;BLOCK OCTANT-2346;So;0;ON;;;;;N;;;;; +1CD26;BLOCK OCTANT-12346;So;0;ON;;;;;N;;;;; +1CD27;BLOCK OCTANT-56;So;0;ON;;;;;N;;;;; +1CD28;BLOCK OCTANT-156;So;0;ON;;;;;N;;;;; +1CD29;BLOCK OCTANT-256;So;0;ON;;;;;N;;;;; +1CD2A;BLOCK OCTANT-1256;So;0;ON;;;;;N;;;;; +1CD2B;BLOCK OCTANT-356;So;0;ON;;;;;N;;;;; +1CD2C;BLOCK OCTANT-1356;So;0;ON;;;;;N;;;;; +1CD2D;BLOCK OCTANT-2356;So;0;ON;;;;;N;;;;; +1CD2E;BLOCK OCTANT-12356;So;0;ON;;;;;N;;;;; +1CD2F;BLOCK OCTANT-456;So;0;ON;;;;;N;;;;; +1CD30;BLOCK OCTANT-1456;So;0;ON;;;;;N;;;;; +1CD31;BLOCK OCTANT-2456;So;0;ON;;;;;N;;;;; +1CD32;BLOCK OCTANT-12456;So;0;ON;;;;;N;;;;; +1CD33;BLOCK OCTANT-3456;So;0;ON;;;;;N;;;;; +1CD34;BLOCK OCTANT-13456;So;0;ON;;;;;N;;;;; +1CD35;BLOCK OCTANT-23456;So;0;ON;;;;;N;;;;; +1CD36;BLOCK OCTANT-17;So;0;ON;;;;;N;;;;; +1CD37;BLOCK OCTANT-27;So;0;ON;;;;;N;;;;; +1CD38;BLOCK OCTANT-127;So;0;ON;;;;;N;;;;; +1CD39;BLOCK OCTANT-37;So;0;ON;;;;;N;;;;; +1CD3A;BLOCK OCTANT-137;So;0;ON;;;;;N;;;;; +1CD3B;BLOCK OCTANT-237;So;0;ON;;;;;N;;;;; +1CD3C;BLOCK OCTANT-1237;So;0;ON;;;;;N;;;;; +1CD3D;BLOCK OCTANT-47;So;0;ON;;;;;N;;;;; +1CD3E;BLOCK OCTANT-147;So;0;ON;;;;;N;;;;; +1CD3F;BLOCK OCTANT-247;So;0;ON;;;;;N;;;;; +1CD40;BLOCK OCTANT-1247;So;0;ON;;;;;N;;;;; +1CD41;BLOCK OCTANT-347;So;0;ON;;;;;N;;;;; +1CD42;BLOCK OCTANT-1347;So;0;ON;;;;;N;;;;; +1CD43;BLOCK OCTANT-2347;So;0;ON;;;;;N;;;;; +1CD44;BLOCK OCTANT-12347;So;0;ON;;;;;N;;;;; +1CD45;BLOCK OCTANT-157;So;0;ON;;;;;N;;;;; +1CD46;BLOCK OCTANT-257;So;0;ON;;;;;N;;;;; +1CD47;BLOCK OCTANT-1257;So;0;ON;;;;;N;;;;; +1CD48;BLOCK OCTANT-357;So;0;ON;;;;;N;;;;; +1CD49;BLOCK OCTANT-2357;So;0;ON;;;;;N;;;;; +1CD4A;BLOCK OCTANT-12357;So;0;ON;;;;;N;;;;; +1CD4B;BLOCK OCTANT-457;So;0;ON;;;;;N;;;;; +1CD4C;BLOCK OCTANT-1457;So;0;ON;;;;;N;;;;; +1CD4D;BLOCK OCTANT-12457;So;0;ON;;;;;N;;;;; +1CD4E;BLOCK OCTANT-3457;So;0;ON;;;;;N;;;;; +1CD4F;BLOCK OCTANT-13457;So;0;ON;;;;;N;;;;; +1CD50;BLOCK OCTANT-23457;So;0;ON;;;;;N;;;;; +1CD51;BLOCK OCTANT-67;So;0;ON;;;;;N;;;;; +1CD52;BLOCK OCTANT-167;So;0;ON;;;;;N;;;;; +1CD53;BLOCK OCTANT-267;So;0;ON;;;;;N;;;;; +1CD54;BLOCK OCTANT-1267;So;0;ON;;;;;N;;;;; +1CD55;BLOCK OCTANT-367;So;0;ON;;;;;N;;;;; +1CD56;BLOCK OCTANT-1367;So;0;ON;;;;;N;;;;; +1CD57;BLOCK OCTANT-2367;So;0;ON;;;;;N;;;;; +1CD58;BLOCK OCTANT-12367;So;0;ON;;;;;N;;;;; +1CD59;BLOCK OCTANT-467;So;0;ON;;;;;N;;;;; +1CD5A;BLOCK OCTANT-1467;So;0;ON;;;;;N;;;;; +1CD5B;BLOCK OCTANT-2467;So;0;ON;;;;;N;;;;; +1CD5C;BLOCK OCTANT-12467;So;0;ON;;;;;N;;;;; +1CD5D;BLOCK OCTANT-3467;So;0;ON;;;;;N;;;;; +1CD5E;BLOCK OCTANT-13467;So;0;ON;;;;;N;;;;; +1CD5F;BLOCK OCTANT-23467;So;0;ON;;;;;N;;;;; +1CD60;BLOCK OCTANT-123467;So;0;ON;;;;;N;;;;; +1CD61;BLOCK OCTANT-567;So;0;ON;;;;;N;;;;; +1CD62;BLOCK OCTANT-1567;So;0;ON;;;;;N;;;;; +1CD63;BLOCK OCTANT-2567;So;0;ON;;;;;N;;;;; +1CD64;BLOCK OCTANT-12567;So;0;ON;;;;;N;;;;; +1CD65;BLOCK OCTANT-3567;So;0;ON;;;;;N;;;;; +1CD66;BLOCK OCTANT-13567;So;0;ON;;;;;N;;;;; +1CD67;BLOCK OCTANT-23567;So;0;ON;;;;;N;;;;; +1CD68;BLOCK OCTANT-123567;So;0;ON;;;;;N;;;;; +1CD69;BLOCK OCTANT-4567;So;0;ON;;;;;N;;;;; +1CD6A;BLOCK OCTANT-14567;So;0;ON;;;;;N;;;;; +1CD6B;BLOCK OCTANT-24567;So;0;ON;;;;;N;;;;; +1CD6C;BLOCK OCTANT-124567;So;0;ON;;;;;N;;;;; +1CD6D;BLOCK OCTANT-34567;So;0;ON;;;;;N;;;;; +1CD6E;BLOCK OCTANT-134567;So;0;ON;;;;;N;;;;; +1CD6F;BLOCK OCTANT-234567;So;0;ON;;;;;N;;;;; +1CD70;BLOCK OCTANT-1234567;So;0;ON;;;;;N;;;;; +1CD71;BLOCK OCTANT-18;So;0;ON;;;;;N;;;;; +1CD72;BLOCK OCTANT-28;So;0;ON;;;;;N;;;;; +1CD73;BLOCK OCTANT-128;So;0;ON;;;;;N;;;;; +1CD74;BLOCK OCTANT-38;So;0;ON;;;;;N;;;;; +1CD75;BLOCK OCTANT-138;So;0;ON;;;;;N;;;;; +1CD76;BLOCK OCTANT-238;So;0;ON;;;;;N;;;;; +1CD77;BLOCK OCTANT-1238;So;0;ON;;;;;N;;;;; +1CD78;BLOCK OCTANT-48;So;0;ON;;;;;N;;;;; +1CD79;BLOCK OCTANT-148;So;0;ON;;;;;N;;;;; +1CD7A;BLOCK OCTANT-248;So;0;ON;;;;;N;;;;; +1CD7B;BLOCK OCTANT-1248;So;0;ON;;;;;N;;;;; +1CD7C;BLOCK OCTANT-348;So;0;ON;;;;;N;;;;; +1CD7D;BLOCK OCTANT-1348;So;0;ON;;;;;N;;;;; +1CD7E;BLOCK OCTANT-2348;So;0;ON;;;;;N;;;;; +1CD7F;BLOCK OCTANT-12348;So;0;ON;;;;;N;;;;; +1CD80;BLOCK OCTANT-58;So;0;ON;;;;;N;;;;; +1CD81;BLOCK OCTANT-158;So;0;ON;;;;;N;;;;; +1CD82;BLOCK OCTANT-258;So;0;ON;;;;;N;;;;; +1CD83;BLOCK OCTANT-1258;So;0;ON;;;;;N;;;;; +1CD84;BLOCK OCTANT-358;So;0;ON;;;;;N;;;;; +1CD85;BLOCK OCTANT-1358;So;0;ON;;;;;N;;;;; +1CD86;BLOCK OCTANT-2358;So;0;ON;;;;;N;;;;; +1CD87;BLOCK OCTANT-12358;So;0;ON;;;;;N;;;;; +1CD88;BLOCK OCTANT-458;So;0;ON;;;;;N;;;;; +1CD89;BLOCK OCTANT-1458;So;0;ON;;;;;N;;;;; +1CD8A;BLOCK OCTANT-2458;So;0;ON;;;;;N;;;;; +1CD8B;BLOCK OCTANT-12458;So;0;ON;;;;;N;;;;; +1CD8C;BLOCK OCTANT-3458;So;0;ON;;;;;N;;;;; +1CD8D;BLOCK OCTANT-13458;So;0;ON;;;;;N;;;;; +1CD8E;BLOCK OCTANT-23458;So;0;ON;;;;;N;;;;; +1CD8F;BLOCK OCTANT-123458;So;0;ON;;;;;N;;;;; +1CD90;BLOCK OCTANT-168;So;0;ON;;;;;N;;;;; +1CD91;BLOCK OCTANT-268;So;0;ON;;;;;N;;;;; +1CD92;BLOCK OCTANT-1268;So;0;ON;;;;;N;;;;; +1CD93;BLOCK OCTANT-368;So;0;ON;;;;;N;;;;; +1CD94;BLOCK OCTANT-2368;So;0;ON;;;;;N;;;;; +1CD95;BLOCK OCTANT-12368;So;0;ON;;;;;N;;;;; +1CD96;BLOCK OCTANT-468;So;0;ON;;;;;N;;;;; +1CD97;BLOCK OCTANT-1468;So;0;ON;;;;;N;;;;; +1CD98;BLOCK OCTANT-12468;So;0;ON;;;;;N;;;;; +1CD99;BLOCK OCTANT-3468;So;0;ON;;;;;N;;;;; +1CD9A;BLOCK OCTANT-13468;So;0;ON;;;;;N;;;;; +1CD9B;BLOCK OCTANT-23468;So;0;ON;;;;;N;;;;; +1CD9C;BLOCK OCTANT-568;So;0;ON;;;;;N;;;;; +1CD9D;BLOCK OCTANT-1568;So;0;ON;;;;;N;;;;; +1CD9E;BLOCK OCTANT-2568;So;0;ON;;;;;N;;;;; +1CD9F;BLOCK OCTANT-12568;So;0;ON;;;;;N;;;;; +1CDA0;BLOCK OCTANT-3568;So;0;ON;;;;;N;;;;; +1CDA1;BLOCK OCTANT-13568;So;0;ON;;;;;N;;;;; +1CDA2;BLOCK OCTANT-23568;So;0;ON;;;;;N;;;;; +1CDA3;BLOCK OCTANT-123568;So;0;ON;;;;;N;;;;; +1CDA4;BLOCK OCTANT-4568;So;0;ON;;;;;N;;;;; +1CDA5;BLOCK OCTANT-14568;So;0;ON;;;;;N;;;;; +1CDA6;BLOCK OCTANT-24568;So;0;ON;;;;;N;;;;; +1CDA7;BLOCK OCTANT-124568;So;0;ON;;;;;N;;;;; +1CDA8;BLOCK OCTANT-34568;So;0;ON;;;;;N;;;;; +1CDA9;BLOCK OCTANT-134568;So;0;ON;;;;;N;;;;; +1CDAA;BLOCK OCTANT-234568;So;0;ON;;;;;N;;;;; +1CDAB;BLOCK OCTANT-1234568;So;0;ON;;;;;N;;;;; +1CDAC;BLOCK OCTANT-178;So;0;ON;;;;;N;;;;; +1CDAD;BLOCK OCTANT-278;So;0;ON;;;;;N;;;;; +1CDAE;BLOCK OCTANT-1278;So;0;ON;;;;;N;;;;; +1CDAF;BLOCK OCTANT-378;So;0;ON;;;;;N;;;;; +1CDB0;BLOCK OCTANT-1378;So;0;ON;;;;;N;;;;; +1CDB1;BLOCK OCTANT-2378;So;0;ON;;;;;N;;;;; +1CDB2;BLOCK OCTANT-12378;So;0;ON;;;;;N;;;;; +1CDB3;BLOCK OCTANT-478;So;0;ON;;;;;N;;;;; +1CDB4;BLOCK OCTANT-1478;So;0;ON;;;;;N;;;;; +1CDB5;BLOCK OCTANT-2478;So;0;ON;;;;;N;;;;; +1CDB6;BLOCK OCTANT-12478;So;0;ON;;;;;N;;;;; +1CDB7;BLOCK OCTANT-3478;So;0;ON;;;;;N;;;;; +1CDB8;BLOCK OCTANT-13478;So;0;ON;;;;;N;;;;; +1CDB9;BLOCK OCTANT-23478;So;0;ON;;;;;N;;;;; +1CDBA;BLOCK OCTANT-123478;So;0;ON;;;;;N;;;;; +1CDBB;BLOCK OCTANT-578;So;0;ON;;;;;N;;;;; +1CDBC;BLOCK OCTANT-1578;So;0;ON;;;;;N;;;;; +1CDBD;BLOCK OCTANT-2578;So;0;ON;;;;;N;;;;; +1CDBE;BLOCK OCTANT-12578;So;0;ON;;;;;N;;;;; +1CDBF;BLOCK OCTANT-3578;So;0;ON;;;;;N;;;;; +1CDC0;BLOCK OCTANT-13578;So;0;ON;;;;;N;;;;; +1CDC1;BLOCK OCTANT-23578;So;0;ON;;;;;N;;;;; +1CDC2;BLOCK OCTANT-123578;So;0;ON;;;;;N;;;;; +1CDC3;BLOCK OCTANT-4578;So;0;ON;;;;;N;;;;; +1CDC4;BLOCK OCTANT-14578;So;0;ON;;;;;N;;;;; +1CDC5;BLOCK OCTANT-24578;So;0;ON;;;;;N;;;;; +1CDC6;BLOCK OCTANT-124578;So;0;ON;;;;;N;;;;; +1CDC7;BLOCK OCTANT-34578;So;0;ON;;;;;N;;;;; +1CDC8;BLOCK OCTANT-134578;So;0;ON;;;;;N;;;;; +1CDC9;BLOCK OCTANT-234578;So;0;ON;;;;;N;;;;; +1CDCA;BLOCK OCTANT-1234578;So;0;ON;;;;;N;;;;; +1CDCB;BLOCK OCTANT-678;So;0;ON;;;;;N;;;;; +1CDCC;BLOCK OCTANT-1678;So;0;ON;;;;;N;;;;; +1CDCD;BLOCK OCTANT-2678;So;0;ON;;;;;N;;;;; +1CDCE;BLOCK OCTANT-12678;So;0;ON;;;;;N;;;;; +1CDCF;BLOCK OCTANT-3678;So;0;ON;;;;;N;;;;; +1CDD0;BLOCK OCTANT-13678;So;0;ON;;;;;N;;;;; +1CDD1;BLOCK OCTANT-23678;So;0;ON;;;;;N;;;;; +1CDD2;BLOCK OCTANT-123678;So;0;ON;;;;;N;;;;; +1CDD3;BLOCK OCTANT-4678;So;0;ON;;;;;N;;;;; +1CDD4;BLOCK OCTANT-14678;So;0;ON;;;;;N;;;;; +1CDD5;BLOCK OCTANT-24678;So;0;ON;;;;;N;;;;; +1CDD6;BLOCK OCTANT-124678;So;0;ON;;;;;N;;;;; +1CDD7;BLOCK OCTANT-34678;So;0;ON;;;;;N;;;;; +1CDD8;BLOCK OCTANT-134678;So;0;ON;;;;;N;;;;; +1CDD9;BLOCK OCTANT-234678;So;0;ON;;;;;N;;;;; +1CDDA;BLOCK OCTANT-1234678;So;0;ON;;;;;N;;;;; +1CDDB;BLOCK OCTANT-15678;So;0;ON;;;;;N;;;;; +1CDDC;BLOCK OCTANT-25678;So;0;ON;;;;;N;;;;; +1CDDD;BLOCK OCTANT-125678;So;0;ON;;;;;N;;;;; +1CDDE;BLOCK OCTANT-35678;So;0;ON;;;;;N;;;;; +1CDDF;BLOCK OCTANT-235678;So;0;ON;;;;;N;;;;; +1CDE0;BLOCK OCTANT-1235678;So;0;ON;;;;;N;;;;; +1CDE1;BLOCK OCTANT-45678;So;0;ON;;;;;N;;;;; +1CDE2;BLOCK OCTANT-145678;So;0;ON;;;;;N;;;;; +1CDE3;BLOCK OCTANT-1245678;So;0;ON;;;;;N;;;;; +1CDE4;BLOCK OCTANT-1345678;So;0;ON;;;;;N;;;;; +1CDE5;BLOCK OCTANT-2345678;So;0;ON;;;;;N;;;;; +1CDE6;TOP HALF STANDING PERSON;So;0;ON;;;;;N;;;;; +1CDE7;BOTTOM HALF STANDING PERSON;So;0;ON;;;;;N;;;;; +1CDE8;TOP HALF RIGHT-FACING RUNNER FRAME-1;So;0;ON;;;;;N;;;;; +1CDE9;BOTTOM HALF RIGHT-FACING RUNNER FRAME-1;So;0;ON;;;;;N;;;;; +1CDEA;TOP HALF RIGHT-FACING RUNNER FRAME-2;So;0;ON;;;;;N;;;;; +1CDEB;BOTTOM HALF RIGHT-FACING RUNNER FRAME-2;So;0;ON;;;;;N;;;;; +1CDEC;TOP HALF LEFT-FACING RUNNER FRAME-1;So;0;ON;;;;;N;;;;; +1CDED;BOTTOM HALF LEFT-FACING RUNNER FRAME-1;So;0;ON;;;;;N;;;;; +1CDEE;TOP HALF LEFT-FACING RUNNER FRAME-2;So;0;ON;;;;;N;;;;; +1CDEF;BOTTOM HALF LEFT-FACING RUNNER FRAME-2;So;0;ON;;;;;N;;;;; +1CDF0;TOP HALF FORWARD-FACING RUNNER;So;0;ON;;;;;N;;;;; +1CDF1;BOTTOM HALF FORWARD-FACING RUNNER FRAME-1;So;0;ON;;;;;N;;;;; +1CDF2;BOTTOM HALF FORWARD-FACING RUNNER FRAME-2;So;0;ON;;;;;N;;;;; +1CDF3;BOTTOM HALF FORWARD-FACING RUNNER FRAME-3;So;0;ON;;;;;N;;;;; +1CDF4;BOTTOM HALF FORWARD-FACING RUNNER FRAME-4;So;0;ON;;;;;N;;;;; +1CDF5;MOON LANDER;So;0;ON;;;;;N;;;;; +1CDF6;TOP HALF FLAILING ROBOT FRAME-1;So;0;ON;;;;;N;;;;; +1CDF7;TOP HALF FLAILING ROBOT FRAME-2;So;0;ON;;;;;N;;;;; +1CDF8;DOWN-POINTING AIRPLANE;So;0;ON;;;;;N;;;;; +1CDF9;LEFT-POINTING AIRPLANE;So;0;ON;;;;;N;;;;; +1CDFA;SMALL UP-POINTING AIRPLANE;So;0;ON;;;;;N;;;;; +1CDFB;UP-POINTING FROG;So;0;ON;;;;;N;;;;; +1CDFC;DOWN-POINTING FROG;So;0;ON;;;;;N;;;;; +1CDFD;EXPLOSION FRAME-1;So;0;ON;;;;;N;;;;; +1CDFE;EXPLOSION FRAME-2;So;0;ON;;;;;N;;;;; +1CDFF;EXPLOSION FRAME-3;So;0;ON;;;;;N;;;;; +1CE00;RIGHT HALF AND LEFT HALF WHITE CIRCLE;So;0;ON;;;;;N;;;;; +1CE01;LOWER HALF AND UPPER HALF WHITE CIRCLE;So;0;ON;;;;;N;;;;; +1CE02;EXPLOSION AT HORIZON;So;0;ON;;;;;N;;;;; +1CE03;UPPER HALF HEAVY WHITE SQUARE;So;0;ON;;;;;N;;;;; +1CE04;LOWER HALF HEAVY WHITE SQUARE;So;0;ON;;;;;N;;;;; +1CE05;HEAVY WHITE SQUARE CONTAINING BLACK VERY SMALL SQUARE;So;0;ON;;;;;N;;;;; +1CE06;WHITE VERTICAL RECTANGLE WITH HORIZONTAL BAR;So;0;ON;;;;;N;;;;; +1CE07;TOP LEFT BLACK LEFT-POINTING SMALL TRIANGLE;So;0;ON;;;;;N;;;;; +1CE08;FUNNEL;So;0;ON;;;;;N;;;;; +1CE09;BOX DRAWINGS DOUBLE DIAGONAL LOWER LEFT TO MIDDLE CENTRE TO LOWER RIGHT;So;0;ON;;;;;N;;;;; +1CE0A;BOX DRAWINGS DOUBLE DIAGONAL UPPER LEFT TO MIDDLE CENTRE TO UPPER RIGHT;So;0;ON;;;;;N;;;;; +1CE0B;LEFT HALF WHITE ELLIPSE;So;0;ON;;;;;N;;;;; +1CE0C;RIGHT HALF WHITE ELLIPSE;So;0;ON;;;;;N;;;;; +1CE0D;LEFT HALF TRIPLE DASH HORIZONTAL;So;0;ON;;;;;N;;;;; +1CE0E;RIGHT HALF TRIPLE DASH HORIZONTAL;So;0;ON;;;;;N;;;;; +1CE0F;HORIZONTAL LINE WITH TICK MARK;So;0;ON;;;;;N;;;;; +1CE10;LEFT HALF HORIZONTAL LINE WITH THREE TICK MARKS;So;0;ON;;;;;N;;;;; +1CE11;RIGHT HALF HORIZONTAL LINE WITH THREE TICK MARKS;So;0;ON;;;;;N;;;;; +1CE12;HORIZONTAL LINE WITH THREE TICK MARKS;So;0;ON;;;;;N;;;;; +1CE13;LOWER HALF VERTICAL LINE WITH THREE TICK MARKS;So;0;ON;;;;;N;;;;; +1CE14;UPPER HALF VERTICAL LINE WITH THREE TICK MARKS;So;0;ON;;;;;N;;;;; +1CE15;VERTICAL LINE WITH THREE TICK MARKS;So;0;ON;;;;;N;;;;; +1CE16;BOX DRAWINGS LIGHT VERTICAL AND TOP RIGHT;So;0;ON;;;;;N;;;;; +1CE17;BOX DRAWINGS LIGHT VERTICAL AND BOTTOM RIGHT;So;0;ON;;;;;N;;;;; +1CE18;BOX DRAWINGS LIGHT VERTICAL AND TOP LEFT;So;0;ON;;;;;N;;;;; +1CE19;BOX DRAWINGS LIGHT VERTICAL AND BOTTOM LEFT;So;0;ON;;;;;N;;;;; +1CE1A;LARGE TYPE PIECE UPPER LEFT ARC;So;0;ON;;;;;N;;;;; +1CE1B;LARGE TYPE PIECE UPPER LEFT CORNER;So;0;ON;;;;;N;;;;; +1CE1C;LARGE TYPE PIECE UPPER TERMINAL;So;0;ON;;;;;N;;;;; +1CE1D;LARGE TYPE PIECE UPPER LEFT CROTCH;So;0;ON;;;;;N;;;;; +1CE1E;LARGE TYPE PIECE LEFT ARM;So;0;ON;;;;;N;;;;; +1CE1F;LARGE TYPE PIECE CROSSBAR;So;0;ON;;;;;N;;;;; +1CE20;LARGE TYPE PIECE CROSSBAR WITH LOWER STEM;So;0;ON;;;;;N;;;;; +1CE21;LARGE TYPE PIECE UPPER HALF VERTEX OF M;So;0;ON;;;;;N;;;;; +1CE22;LARGE TYPE PIECE DIAGONAL LOWER LEFT;So;0;ON;;;;;N;;;;; +1CE23;LARGE TYPE PIECE SHORT UPPER TERMINAL;So;0;ON;;;;;N;;;;; +1CE24;LARGE TYPE PIECE UPPER RIGHT ARC;So;0;ON;;;;;N;;;;; +1CE25;LARGE TYPE PIECE RIGHT ARM;So;0;ON;;;;;N;;;;; +1CE26;LARGE TYPE PIECE UPPER RIGHT CROTCH;So;0;ON;;;;;N;;;;; +1CE27;LARGE TYPE PIECE UPPER RIGHT CORNER;So;0;ON;;;;;N;;;;; +1CE28;LARGE TYPE PIECE STEM WITH RIGHT CROSSBAR;So;0;ON;;;;;N;;;;; +1CE29;LARGE TYPE PIECE STEM;So;0;ON;;;;;N;;;;; +1CE2A;LARGE TYPE PIECE DIAGONAL UPPER RIGHT AND LOWER RIGHT;So;0;ON;;;;;N;;;;; +1CE2B;LARGE TYPE PIECE DIAGONAL UPPER RIGHT;So;0;ON;;;;;N;;;;; +1CE2C;LARGE TYPE PIECE DIAGONAL LOWER RIGHT;So;0;ON;;;;;N;;;;; +1CE2D;LARGE TYPE PIECE SHORT LOWER TERMINAL;So;0;ON;;;;;N;;;;; +1CE2E;LARGE TYPE PIECE LOWER LEFT AND UPPER LEFT ARC;So;0;ON;;;;;N;;;;; +1CE2F;LARGE TYPE PIECE CENTRE OF K;So;0;ON;;;;;N;;;;; +1CE30;LARGE TYPE PIECE LOWER HALF VERTEX OF M;So;0;ON;;;;;N;;;;; +1CE31;LARGE TYPE PIECE UPPER HALF VERTEX OF W;So;0;ON;;;;;N;;;;; +1CE32;LARGE TYPE PIECE CENTRE OF X;So;0;ON;;;;;N;;;;; +1CE33;LARGE TYPE PIECE CENTRE OF Y;So;0;ON;;;;;N;;;;; +1CE34;LARGE TYPE PIECE CENTRE OF Z WITH CROSSBAR;So;0;ON;;;;;N;;;;; +1CE35;LARGE TYPE PIECE RAISED UPPER LEFT ARC;So;0;ON;;;;;N;;;;; +1CE36;LARGE TYPE PIECE STEM WITH LEFT CROSSBAR;So;0;ON;;;;;N;;;;; +1CE37;LARGE TYPE PIECE LOWER RIGHT AND UPPER RIGHT ARC;So;0;ON;;;;;N;;;;; +1CE38;LARGE TYPE PIECE DIAGONAL UPPER LEFT AND LOWER LEFT;So;0;ON;;;;;N;;;;; +1CE39;LARGE TYPE PIECE STEM WITH LEFT JOINT;So;0;ON;;;;;N;;;;; +1CE3A;LARGE TYPE PIECE STEM WITH CROSSBAR;So;0;ON;;;;;N;;;;; +1CE3B;LARGE TYPE PIECE DIAGONAL UPPER LEFT;So;0;ON;;;;;N;;;;; +1CE3C;LARGE TYPE PIECE LOWER TERMINAL;So;0;ON;;;;;N;;;;; +1CE3D;LARGE TYPE PIECE LOWER LEFT CORNER;So;0;ON;;;;;N;;;;; +1CE3E;LARGE TYPE PIECE LOWER LEFT ARC;So;0;ON;;;;;N;;;;; +1CE3F;LARGE TYPE PIECE LOWER LEFT CROTCH;So;0;ON;;;;;N;;;;; +1CE40;LARGE TYPE PIECE CROSSBAR WITH UPPER STEM;So;0;ON;;;;;N;;;;; +1CE41;LARGE TYPE PIECE VERTEX OF V;So;0;ON;;;;;N;;;;; +1CE42;LARGE TYPE PIECE LOWER HALF VERTEX OF W;So;0;ON;;;;;N;;;;; +1CE43;LARGE TYPE PIECE LOWER RIGHT ARC;So;0;ON;;;;;N;;;;; +1CE44;LARGE TYPE PIECE LOWER RIGHT CORNER;So;0;ON;;;;;N;;;;; +1CE45;LARGE TYPE PIECE LOWER RIGHT ARC WITH TAIL;So;0;ON;;;;;N;;;;; +1CE46;LARGE TYPE PIECE LOWER RIGHT CROTCH;So;0;ON;;;;;N;;;;; +1CE47;LARGE TYPE PIECE STEM-45;So;0;ON;;;;;N;;;;; +1CE48;LARGE TYPE PIECE STEM-2345;So;0;ON;;;;;N;;;;; +1CE49;LARGE TYPE PIECE STEM-4;So;0;ON;;;;;N;;;;; +1CE4A;LARGE TYPE PIECE STEM-34;So;0;ON;;;;;N;;;;; +1CE4B;LARGE TYPE PIECE STEM-234;So;0;ON;;;;;N;;;;; +1CE4C;LARGE TYPE PIECE STEM-1234;So;0;ON;;;;;N;;;;; +1CE4D;LARGE TYPE PIECE STEM-3;So;0;ON;;;;;N;;;;; +1CE4E;LARGE TYPE PIECE STEM-23;So;0;ON;;;;;N;;;;; +1CE4F;LARGE TYPE PIECE STEM-2;So;0;ON;;;;;N;;;;; +1CE50;LARGE TYPE PIECE STEM-12;So;0;ON;;;;;N;;;;; +1CE51;SEPARATED BLOCK SEXTANT-1;So;0;ON;;;;;N;;;;; +1CE52;SEPARATED BLOCK SEXTANT-2;So;0;ON;;;;;N;;;;; +1CE53;SEPARATED BLOCK SEXTANT-12;So;0;ON;;;;;N;;;;; +1CE54;SEPARATED BLOCK SEXTANT-3;So;0;ON;;;;;N;;;;; +1CE55;SEPARATED BLOCK SEXTANT-13;So;0;ON;;;;;N;;;;; +1CE56;SEPARATED BLOCK SEXTANT-23;So;0;ON;;;;;N;;;;; +1CE57;SEPARATED BLOCK SEXTANT-123;So;0;ON;;;;;N;;;;; +1CE58;SEPARATED BLOCK SEXTANT-4;So;0;ON;;;;;N;;;;; +1CE59;SEPARATED BLOCK SEXTANT-14;So;0;ON;;;;;N;;;;; +1CE5A;SEPARATED BLOCK SEXTANT-24;So;0;ON;;;;;N;;;;; +1CE5B;SEPARATED BLOCK SEXTANT-124;So;0;ON;;;;;N;;;;; +1CE5C;SEPARATED BLOCK SEXTANT-34;So;0;ON;;;;;N;;;;; +1CE5D;SEPARATED BLOCK SEXTANT-134;So;0;ON;;;;;N;;;;; +1CE5E;SEPARATED BLOCK SEXTANT-234;So;0;ON;;;;;N;;;;; +1CE5F;SEPARATED BLOCK SEXTANT-1234;So;0;ON;;;;;N;;;;; +1CE60;SEPARATED BLOCK SEXTANT-5;So;0;ON;;;;;N;;;;; +1CE61;SEPARATED BLOCK SEXTANT-15;So;0;ON;;;;;N;;;;; +1CE62;SEPARATED BLOCK SEXTANT-25;So;0;ON;;;;;N;;;;; +1CE63;SEPARATED BLOCK SEXTANT-125;So;0;ON;;;;;N;;;;; +1CE64;SEPARATED BLOCK SEXTANT-35;So;0;ON;;;;;N;;;;; +1CE65;SEPARATED BLOCK SEXTANT-135;So;0;ON;;;;;N;;;;; +1CE66;SEPARATED BLOCK SEXTANT-235;So;0;ON;;;;;N;;;;; +1CE67;SEPARATED BLOCK SEXTANT-1235;So;0;ON;;;;;N;;;;; +1CE68;SEPARATED BLOCK SEXTANT-45;So;0;ON;;;;;N;;;;; +1CE69;SEPARATED BLOCK SEXTANT-145;So;0;ON;;;;;N;;;;; +1CE6A;SEPARATED BLOCK SEXTANT-245;So;0;ON;;;;;N;;;;; +1CE6B;SEPARATED BLOCK SEXTANT-1245;So;0;ON;;;;;N;;;;; +1CE6C;SEPARATED BLOCK SEXTANT-345;So;0;ON;;;;;N;;;;; +1CE6D;SEPARATED BLOCK SEXTANT-1345;So;0;ON;;;;;N;;;;; +1CE6E;SEPARATED BLOCK SEXTANT-2345;So;0;ON;;;;;N;;;;; +1CE6F;SEPARATED BLOCK SEXTANT-12345;So;0;ON;;;;;N;;;;; +1CE70;SEPARATED BLOCK SEXTANT-6;So;0;ON;;;;;N;;;;; +1CE71;SEPARATED BLOCK SEXTANT-16;So;0;ON;;;;;N;;;;; +1CE72;SEPARATED BLOCK SEXTANT-26;So;0;ON;;;;;N;;;;; +1CE73;SEPARATED BLOCK SEXTANT-126;So;0;ON;;;;;N;;;;; +1CE74;SEPARATED BLOCK SEXTANT-36;So;0;ON;;;;;N;;;;; +1CE75;SEPARATED BLOCK SEXTANT-136;So;0;ON;;;;;N;;;;; +1CE76;SEPARATED BLOCK SEXTANT-236;So;0;ON;;;;;N;;;;; +1CE77;SEPARATED BLOCK SEXTANT-1236;So;0;ON;;;;;N;;;;; +1CE78;SEPARATED BLOCK SEXTANT-46;So;0;ON;;;;;N;;;;; +1CE79;SEPARATED BLOCK SEXTANT-146;So;0;ON;;;;;N;;;;; +1CE7A;SEPARATED BLOCK SEXTANT-246;So;0;ON;;;;;N;;;;; +1CE7B;SEPARATED BLOCK SEXTANT-1246;So;0;ON;;;;;N;;;;; +1CE7C;SEPARATED BLOCK SEXTANT-346;So;0;ON;;;;;N;;;;; +1CE7D;SEPARATED BLOCK SEXTANT-1346;So;0;ON;;;;;N;;;;; +1CE7E;SEPARATED BLOCK SEXTANT-2346;So;0;ON;;;;;N;;;;; +1CE7F;SEPARATED BLOCK SEXTANT-12346;So;0;ON;;;;;N;;;;; +1CE80;SEPARATED BLOCK SEXTANT-56;So;0;ON;;;;;N;;;;; +1CE81;SEPARATED BLOCK SEXTANT-156;So;0;ON;;;;;N;;;;; +1CE82;SEPARATED BLOCK SEXTANT-256;So;0;ON;;;;;N;;;;; +1CE83;SEPARATED BLOCK SEXTANT-1256;So;0;ON;;;;;N;;;;; +1CE84;SEPARATED BLOCK SEXTANT-356;So;0;ON;;;;;N;;;;; +1CE85;SEPARATED BLOCK SEXTANT-1356;So;0;ON;;;;;N;;;;; +1CE86;SEPARATED BLOCK SEXTANT-2356;So;0;ON;;;;;N;;;;; +1CE87;SEPARATED BLOCK SEXTANT-12356;So;0;ON;;;;;N;;;;; +1CE88;SEPARATED BLOCK SEXTANT-456;So;0;ON;;;;;N;;;;; +1CE89;SEPARATED BLOCK SEXTANT-1456;So;0;ON;;;;;N;;;;; +1CE8A;SEPARATED BLOCK SEXTANT-2456;So;0;ON;;;;;N;;;;; +1CE8B;SEPARATED BLOCK SEXTANT-12456;So;0;ON;;;;;N;;;;; +1CE8C;SEPARATED BLOCK SEXTANT-3456;So;0;ON;;;;;N;;;;; +1CE8D;SEPARATED BLOCK SEXTANT-13456;So;0;ON;;;;;N;;;;; +1CE8E;SEPARATED BLOCK SEXTANT-23456;So;0;ON;;;;;N;;;;; +1CE8F;SEPARATED BLOCK SEXTANT-123456;So;0;ON;;;;;N;;;;; +1CE90;UPPER LEFT ONE SIXTEENTH BLOCK;So;0;ON;;;;;N;;;;; +1CE91;UPPER CENTRE LEFT ONE SIXTEENTH BLOCK;So;0;ON;;;;;N;;;;; +1CE92;UPPER CENTRE RIGHT ONE SIXTEENTH BLOCK;So;0;ON;;;;;N;;;;; +1CE93;UPPER RIGHT ONE SIXTEENTH BLOCK;So;0;ON;;;;;N;;;;; +1CE94;UPPER MIDDLE LEFT ONE SIXTEENTH BLOCK;So;0;ON;;;;;N;;;;; +1CE95;UPPER MIDDLE CENTRE LEFT ONE SIXTEENTH BLOCK;So;0;ON;;;;;N;;;;; +1CE96;UPPER MIDDLE CENTRE RIGHT ONE SIXTEENTH BLOCK;So;0;ON;;;;;N;;;;; +1CE97;UPPER MIDDLE RIGHT ONE SIXTEENTH BLOCK;So;0;ON;;;;;N;;;;; +1CE98;LOWER MIDDLE LEFT ONE SIXTEENTH BLOCK;So;0;ON;;;;;N;;;;; +1CE99;LOWER MIDDLE CENTRE LEFT ONE SIXTEENTH BLOCK;So;0;ON;;;;;N;;;;; +1CE9A;LOWER MIDDLE CENTRE RIGHT ONE SIXTEENTH BLOCK;So;0;ON;;;;;N;;;;; +1CE9B;LOWER MIDDLE RIGHT ONE SIXTEENTH BLOCK;So;0;ON;;;;;N;;;;; +1CE9C;LOWER LEFT ONE SIXTEENTH BLOCK;So;0;ON;;;;;N;;;;; +1CE9D;LOWER CENTRE LEFT ONE SIXTEENTH BLOCK;So;0;ON;;;;;N;;;;; +1CE9E;LOWER CENTRE RIGHT ONE SIXTEENTH BLOCK;So;0;ON;;;;;N;;;;; +1CE9F;LOWER RIGHT ONE SIXTEENTH BLOCK;So;0;ON;;;;;N;;;;; +1CEA0;RIGHT HALF LOWER ONE QUARTER BLOCK;So;0;ON;;;;;N;;;;; +1CEA1;RIGHT THREE QUARTERS LOWER ONE QUARTER BLOCK;So;0;ON;;;;;N;;;;; +1CEA2;LEFT THREE QUARTERS LOWER ONE QUARTER BLOCK;So;0;ON;;;;;N;;;;; +1CEA3;LEFT HALF LOWER ONE QUARTER BLOCK;So;0;ON;;;;;N;;;;; +1CEA4;LOWER HALF LEFT ONE QUARTER BLOCK;So;0;ON;;;;;N;;;;; +1CEA5;LOWER THREE QUARTERS LEFT ONE QUARTER BLOCK;So;0;ON;;;;;N;;;;; +1CEA6;UPPER THREE QUARTERS LEFT ONE QUARTER BLOCK;So;0;ON;;;;;N;;;;; +1CEA7;UPPER HALF LEFT ONE QUARTER BLOCK;So;0;ON;;;;;N;;;;; +1CEA8;LEFT HALF UPPER ONE QUARTER BLOCK;So;0;ON;;;;;N;;;;; +1CEA9;LEFT THREE QUARTERS UPPER ONE QUARTER BLOCK;So;0;ON;;;;;N;;;;; +1CEAA;RIGHT THREE QUARTERS UPPER ONE QUARTER BLOCK;So;0;ON;;;;;N;;;;; +1CEAB;RIGHT HALF UPPER ONE QUARTER BLOCK;So;0;ON;;;;;N;;;;; +1CEAC;UPPER HALF RIGHT ONE QUARTER BLOCK;So;0;ON;;;;;N;;;;; +1CEAD;UPPER THREE QUARTERS RIGHT ONE QUARTER BLOCK;So;0;ON;;;;;N;;;;; +1CEAE;LOWER THREE QUARTERS RIGHT ONE QUARTER BLOCK;So;0;ON;;;;;N;;;;; +1CEAF;LOWER HALF RIGHT ONE QUARTER BLOCK;So;0;ON;;;;;N;;;;; +1CEB0;HORIZONTAL ZIGZAG LINE;So;0;ON;;;;;N;;;;; +1CEB1;KEYHOLE;So;0;ON;;;;;N;;;;; +1CEB2;OLD PERSONAL COMPUTER WITH MONITOR IN PORTRAIT ORIENTATION;So;0;ON;;;;;N;;;;; +1CEB3;BLACK RIGHT TRIANGLE CARET;So;0;ON;;;;;N;;;;; 1CF00;ZNAMENNY COMBINING MARK GORAZDO NIZKO S KRYZHEM ON LEFT;Mn;0;NSM;;;;;N;;;;; 1CF01;ZNAMENNY COMBINING MARK NIZKO S KRYZHEM ON LEFT;Mn;0;NSM;;;;;N;;;;; 1CF02;ZNAMENNY COMBINING MARK TSATA ON LEFT;Mn;0;NSM;;;;;N;;;;; @@ -29545,7 +34630,7 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;; 1D6BE;MATHEMATICAL BOLD CAPITAL CHI;Lu;0;L;<font> 03A7;;;;N;;;;; 1D6BF;MATHEMATICAL BOLD CAPITAL PSI;Lu;0;L;<font> 03A8;;;;N;;;;; 1D6C0;MATHEMATICAL BOLD CAPITAL OMEGA;Lu;0;L;<font> 03A9;;;;N;;;;; -1D6C1;MATHEMATICAL BOLD NABLA;Sm;0;L;<font> 2207;;;;N;;;;; +1D6C1;MATHEMATICAL BOLD NABLA;Sm;0;ON;<font> 2207;;;;N;;;;; 1D6C2;MATHEMATICAL BOLD SMALL ALPHA;Ll;0;L;<font> 03B1;;;;N;;;;; 1D6C3;MATHEMATICAL BOLD SMALL BETA;Ll;0;L;<font> 03B2;;;;N;;;;; 1D6C4;MATHEMATICAL BOLD SMALL GAMMA;Ll;0;L;<font> 03B3;;;;N;;;;; @@ -29603,7 +34688,7 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;; 1D6F8;MATHEMATICAL ITALIC CAPITAL CHI;Lu;0;L;<font> 03A7;;;;N;;;;; 1D6F9;MATHEMATICAL ITALIC CAPITAL PSI;Lu;0;L;<font> 03A8;;;;N;;;;; 1D6FA;MATHEMATICAL ITALIC CAPITAL OMEGA;Lu;0;L;<font> 03A9;;;;N;;;;; -1D6FB;MATHEMATICAL ITALIC NABLA;Sm;0;L;<font> 2207;;;;N;;;;; +1D6FB;MATHEMATICAL ITALIC NABLA;Sm;0;ON;<font> 2207;;;;N;;;;; 1D6FC;MATHEMATICAL ITALIC SMALL ALPHA;Ll;0;L;<font> 03B1;;;;N;;;;; 1D6FD;MATHEMATICAL ITALIC SMALL BETA;Ll;0;L;<font> 03B2;;;;N;;;;; 1D6FE;MATHEMATICAL ITALIC SMALL GAMMA;Ll;0;L;<font> 03B3;;;;N;;;;; @@ -29661,7 +34746,7 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;; 1D732;MATHEMATICAL BOLD ITALIC CAPITAL CHI;Lu;0;L;<font> 03A7;;;;N;;;;; 1D733;MATHEMATICAL BOLD ITALIC CAPITAL PSI;Lu;0;L;<font> 03A8;;;;N;;;;; 1D734;MATHEMATICAL BOLD ITALIC CAPITAL OMEGA;Lu;0;L;<font> 03A9;;;;N;;;;; -1D735;MATHEMATICAL BOLD ITALIC NABLA;Sm;0;L;<font> 2207;;;;N;;;;; +1D735;MATHEMATICAL BOLD ITALIC NABLA;Sm;0;ON;<font> 2207;;;;N;;;;; 1D736;MATHEMATICAL BOLD ITALIC SMALL ALPHA;Ll;0;L;<font> 03B1;;;;N;;;;; 1D737;MATHEMATICAL BOLD ITALIC SMALL BETA;Ll;0;L;<font> 03B2;;;;N;;;;; 1D738;MATHEMATICAL BOLD ITALIC SMALL GAMMA;Ll;0;L;<font> 03B3;;;;N;;;;; @@ -29719,7 +34804,7 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;; 1D76C;MATHEMATICAL SANS-SERIF BOLD CAPITAL CHI;Lu;0;L;<font> 03A7;;;;N;;;;; 1D76D;MATHEMATICAL SANS-SERIF BOLD CAPITAL PSI;Lu;0;L;<font> 03A8;;;;N;;;;; 1D76E;MATHEMATICAL SANS-SERIF BOLD CAPITAL OMEGA;Lu;0;L;<font> 03A9;;;;N;;;;; -1D76F;MATHEMATICAL SANS-SERIF BOLD NABLA;Sm;0;L;<font> 2207;;;;N;;;;; +1D76F;MATHEMATICAL SANS-SERIF BOLD NABLA;Sm;0;ON;<font> 2207;;;;N;;;;; 1D770;MATHEMATICAL SANS-SERIF BOLD SMALL ALPHA;Ll;0;L;<font> 03B1;;;;N;;;;; 1D771;MATHEMATICAL SANS-SERIF BOLD SMALL BETA;Ll;0;L;<font> 03B2;;;;N;;;;; 1D772;MATHEMATICAL SANS-SERIF BOLD SMALL GAMMA;Ll;0;L;<font> 03B3;;;;N;;;;; @@ -29777,7 +34862,7 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;; 1D7A6;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL CHI;Lu;0;L;<font> 03A7;;;;N;;;;; 1D7A7;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL PSI;Lu;0;L;<font> 03A8;;;;N;;;;; 1D7A8;MATHEMATICAL SANS-SERIF BOLD ITALIC CAPITAL OMEGA;Lu;0;L;<font> 03A9;;;;N;;;;; -1D7A9;MATHEMATICAL SANS-SERIF BOLD ITALIC NABLA;Sm;0;L;<font> 2207;;;;N;;;;; +1D7A9;MATHEMATICAL SANS-SERIF BOLD ITALIC NABLA;Sm;0;ON;<font> 2207;;;;N;;;;; 1D7AA;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL ALPHA;Ll;0;L;<font> 03B1;;;;N;;;;; 1D7AB;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL BETA;Ll;0;L;<font> 03B2;;;;N;;;;; 1D7AC;MATHEMATICAL SANS-SERIF BOLD ITALIC SMALL GAMMA;Ll;0;L;<font> 03B3;;;;N;;;;; @@ -30875,6 +35960,50 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;; 1E4F7;NAG MUNDARI DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;; 1E4F8;NAG MUNDARI DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;; 1E4F9;NAG MUNDARI DIGIT NINE;Nd;0;L;;9;9;9;N;;;;; +1E5D0;OL ONAL LETTER O;Lo;0;L;;;;;N;;;;; +1E5D1;OL ONAL LETTER OM;Lo;0;L;;;;;N;;;;; +1E5D2;OL ONAL LETTER ONG;Lo;0;L;;;;;N;;;;; +1E5D3;OL ONAL LETTER ORR;Lo;0;L;;;;;N;;;;; +1E5D4;OL ONAL LETTER OO;Lo;0;L;;;;;N;;;;; +1E5D5;OL ONAL LETTER OY;Lo;0;L;;;;;N;;;;; +1E5D6;OL ONAL LETTER A;Lo;0;L;;;;;N;;;;; +1E5D7;OL ONAL LETTER AD;Lo;0;L;;;;;N;;;;; +1E5D8;OL ONAL LETTER AB;Lo;0;L;;;;;N;;;;; +1E5D9;OL ONAL LETTER AH;Lo;0;L;;;;;N;;;;; +1E5DA;OL ONAL LETTER AL;Lo;0;L;;;;;N;;;;; +1E5DB;OL ONAL LETTER AW;Lo;0;L;;;;;N;;;;; +1E5DC;OL ONAL LETTER I;Lo;0;L;;;;;N;;;;; +1E5DD;OL ONAL LETTER IT;Lo;0;L;;;;;N;;;;; +1E5DE;OL ONAL LETTER IP;Lo;0;L;;;;;N;;;;; +1E5DF;OL ONAL LETTER ITT;Lo;0;L;;;;;N;;;;; +1E5E0;OL ONAL LETTER ID;Lo;0;L;;;;;N;;;;; +1E5E1;OL ONAL LETTER IN;Lo;0;L;;;;;N;;;;; +1E5E2;OL ONAL LETTER U;Lo;0;L;;;;;N;;;;; +1E5E3;OL ONAL LETTER UK;Lo;0;L;;;;;N;;;;; +1E5E4;OL ONAL LETTER UDD;Lo;0;L;;;;;N;;;;; +1E5E5;OL ONAL LETTER UJ;Lo;0;L;;;;;N;;;;; +1E5E6;OL ONAL LETTER UNY;Lo;0;L;;;;;N;;;;; +1E5E7;OL ONAL LETTER UR;Lo;0;L;;;;;N;;;;; +1E5E8;OL ONAL LETTER E;Lo;0;L;;;;;N;;;;; +1E5E9;OL ONAL LETTER ES;Lo;0;L;;;;;N;;;;; +1E5EA;OL ONAL LETTER EH;Lo;0;L;;;;;N;;;;; +1E5EB;OL ONAL LETTER EC;Lo;0;L;;;;;N;;;;; +1E5EC;OL ONAL LETTER ENN;Lo;0;L;;;;;N;;;;; +1E5ED;OL ONAL LETTER EG;Lo;0;L;;;;;N;;;;; +1E5EE;OL ONAL SIGN MU;Mn;230;NSM;;;;;N;;;;; +1E5EF;OL ONAL SIGN IKIR;Mn;220;NSM;;;;;N;;;;; +1E5F0;OL ONAL SIGN HODDOND;Lo;0;L;;;;;N;;;;; +1E5F1;OL ONAL DIGIT ZERO;Nd;0;L;;0;0;0;N;;;;; +1E5F2;OL ONAL DIGIT ONE;Nd;0;L;;1;1;1;N;;;;; +1E5F3;OL ONAL DIGIT TWO;Nd;0;L;;2;2;2;N;;;;; +1E5F4;OL ONAL DIGIT THREE;Nd;0;L;;3;3;3;N;;;;; +1E5F5;OL ONAL DIGIT FOUR;Nd;0;L;;4;4;4;N;;;;; +1E5F6;OL ONAL DIGIT FIVE;Nd;0;L;;5;5;5;N;;;;; +1E5F7;OL ONAL DIGIT SIX;Nd;0;L;;6;6;6;N;;;;; +1E5F8;OL ONAL DIGIT SEVEN;Nd;0;L;;7;7;7;N;;;;; +1E5F9;OL ONAL DIGIT EIGHT;Nd;0;L;;8;8;8;N;;;;; +1E5FA;OL ONAL DIGIT NINE;Nd;0;L;;9;9;9;N;;;;; +1E5FF;OL ONAL ABBREVIATION SIGN;Po;0;L;;;;;N;;;;; 1E7E0;ETHIOPIC SYLLABLE HHYA;Lo;0;L;;;;;N;;;;; 1E7E1;ETHIOPIC SYLLABLE HHYU;Lo;0;L;;;;;N;;;;; 1E7E2;ETHIOPIC SYLLABLE HHYI;Lo;0;L;;;;;N;;;;; @@ -33357,6 +38486,18 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;; 1F8AD;WHITE ARROW SHAFT WIDTH TWO THIRDS;So;0;ON;;;;;N;;;;; 1F8B0;ARROW POINTING UPWARDS THEN NORTH WEST;So;0;ON;;;;;N;;;;; 1F8B1;ARROW POINTING RIGHTWARDS THEN CURVING SOUTH WEST;So;0;ON;;;;;N;;;;; +1F8B2;RIGHTWARDS ARROW WITH LOWER HOOK;So;0;ON;;;;;N;;;;; +1F8B3;DOWNWARDS BLACK ARROW TO BAR;So;0;ON;;;;;N;;;;; +1F8B4;NEGATIVE SQUARED LEFTWARDS ARROW;So;0;ON;;;;;N;;;;; +1F8B5;NEGATIVE SQUARED UPWARDS ARROW;So;0;ON;;;;;N;;;;; +1F8B6;NEGATIVE SQUARED RIGHTWARDS ARROW;So;0;ON;;;;;N;;;;; +1F8B7;NEGATIVE SQUARED DOWNWARDS ARROW;So;0;ON;;;;;N;;;;; +1F8B8;NORTH WEST ARROW FROM BAR;So;0;ON;;;;;N;;;;; +1F8B9;NORTH EAST ARROW FROM BAR;So;0;ON;;;;;N;;;;; +1F8BA;SOUTH EAST ARROW FROM BAR;So;0;ON;;;;;N;;;;; +1F8BB;SOUTH WEST ARROW FROM BAR;So;0;ON;;;;;N;;;;; +1F8C0;LEFTWARDS ARROW FROM DOWNWARDS ARROW;So;0;ON;;;;;N;;;;; +1F8C1;RIGHTWARDS ARROW FROM DOWNWARDS ARROW;So;0;ON;;;;;N;;;;; 1F900;CIRCLED CROSS FORMEE WITH FOUR DOTS;So;0;ON;;;;;N;;;;; 1F901;CIRCLED CROSS FORMEE WITH TWO DOTS;So;0;ON;;;;;N;;;;; 1F902;CIRCLED CROSS FORMEE;So;0;ON;;;;;N;;;;; @@ -33733,6 +38874,8 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;; 1FA86;NESTING DOLLS;So;0;ON;;;;;N;;;;; 1FA87;MARACAS;So;0;ON;;;;;N;;;;; 1FA88;FLUTE;So;0;ON;;;;;N;;;;; +1FA89;HARP;So;0;ON;;;;;N;;;;; +1FA8F;SHOVEL;So;0;ON;;;;;N;;;;; 1FA90;RINGED PLANET;So;0;ON;;;;;N;;;;; 1FA91;CHAIR;So;0;ON;;;;;N;;;;; 1FA92;RAZOR;So;0;ON;;;;;N;;;;; @@ -33779,6 +38922,7 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;; 1FABB;HYACINTH;So;0;ON;;;;;N;;;;; 1FABC;JELLYFISH;So;0;ON;;;;;N;;;;; 1FABD;WING;So;0;ON;;;;;N;;;;; +1FABE;LEAFLESS TREE;So;0;ON;;;;;N;;;;; 1FABF;GOOSE;So;0;ON;;;;;N;;;;; 1FAC0;ANATOMICAL HEART;So;0;ON;;;;;N;;;;; 1FAC1;LUNGS;So;0;ON;;;;;N;;;;; @@ -33786,6 +38930,7 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;; 1FAC3;PREGNANT MAN;So;0;ON;;;;;N;;;;; 1FAC4;PREGNANT PERSON;So;0;ON;;;;;N;;;;; 1FAC5;PERSON WITH CROWN;So;0;ON;;;;;N;;;;; +1FAC6;FINGERPRINT;So;0;ON;;;;;N;;;;; 1FACE;MOOSE;So;0;ON;;;;;N;;;;; 1FACF;DONKEY;So;0;ON;;;;;N;;;;; 1FAD0;BLUEBERRIES;So;0;ON;;;;;N;;;;; @@ -33800,6 +38945,8 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;; 1FAD9;JAR;So;0;ON;;;;;N;;;;; 1FADA;GINGER ROOT;So;0;ON;;;;;N;;;;; 1FADB;PEA POD;So;0;ON;;;;;N;;;;; +1FADC;ROOT VEGETABLE;So;0;ON;;;;;N;;;;; +1FADF;SPLATTER;So;0;ON;;;;;N;;;;; 1FAE0;MELTING FACE;So;0;ON;;;;;N;;;;; 1FAE1;SALUTING FACE;So;0;ON;;;;;N;;;;; 1FAE2;FACE WITH OPEN EYES AND HAND OVER MOUTH;So;0;ON;;;;;N;;;;; @@ -33809,6 +38956,7 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;; 1FAE6;BITING LIP;So;0;ON;;;;;N;;;;; 1FAE7;BUBBLES;So;0;ON;;;;;N;;;;; 1FAE8;SHAKING FACE;So;0;ON;;;;;N;;;;; +1FAE9;FACE WITH BAGS UNDER EYES;So;0;ON;;;;;N;;;;; 1FAF0;HAND WITH INDEX FINGER AND THUMB CROSSED;So;0;ON;;;;;N;;;;; 1FAF1;RIGHTWARDS HAND;So;0;ON;;;;;N;;;;; 1FAF2;LEFTWARDS HAND;So;0;ON;;;;;N;;;;; @@ -34020,6 +39168,43 @@ FFFD;REPLACEMENT CHARACTER;So;0;ON;;;;;N;;;;; 1FBC8;STICK FIGURE LEANING RIGHT;So;0;ON;;;;;N;;;;; 1FBC9;STICK FIGURE WITH DRESS;So;0;ON;;;;;N;;;;; 1FBCA;WHITE UP-POINTING CHEVRON;So;0;ON;;;;;N;;;;; +1FBCB;WHITE CROSS MARK;So;0;ON;;;;;N;;;;; +1FBCC;RAISED SMALL LEFT SQUARE BRACKET;So;0;ON;;;;;N;;;;; +1FBCD;BLACK SMALL UP-POINTING CHEVRON;So;0;ON;;;;;N;;;;; +1FBCE;LEFT TWO THIRDS BLOCK;So;0;ON;;;;;N;;;;; +1FBCF;LEFT ONE THIRD BLOCK;So;0;ON;;;;;N;;;;; +1FBD0;BOX DRAWINGS LIGHT DIAGONAL MIDDLE RIGHT TO LOWER LEFT;So;0;ON;;;;;N;;;;; +1FBD1;BOX DRAWINGS LIGHT DIAGONAL UPPER RIGHT TO MIDDLE LEFT;So;0;ON;;;;;N;;;;; +1FBD2;BOX DRAWINGS LIGHT DIAGONAL UPPER LEFT TO MIDDLE RIGHT;So;0;ON;;;;;N;;;;; +1FBD3;BOX DRAWINGS LIGHT DIAGONAL MIDDLE LEFT TO LOWER RIGHT;So;0;ON;;;;;N;;;;; +1FBD4;BOX DRAWINGS LIGHT DIAGONAL UPPER LEFT TO LOWER CENTRE;So;0;ON;;;;;N;;;;; +1FBD5;BOX DRAWINGS LIGHT DIAGONAL UPPER CENTRE TO LOWER RIGHT;So;0;ON;;;;;N;;;;; +1FBD6;BOX DRAWINGS LIGHT DIAGONAL UPPER RIGHT TO LOWER CENTRE;So;0;ON;;;;;N;;;;; +1FBD7;BOX DRAWINGS LIGHT DIAGONAL UPPER CENTRE TO LOWER LEFT;So;0;ON;;;;;N;;;;; +1FBD8;BOX DRAWINGS LIGHT DIAGONAL UPPER LEFT TO MIDDLE CENTRE TO UPPER RIGHT;So;0;ON;;;;;N;;;;; +1FBD9;BOX DRAWINGS LIGHT DIAGONAL UPPER RIGHT TO MIDDLE CENTRE TO LOWER RIGHT;So;0;ON;;;;;N;;;;; +1FBDA;BOX DRAWINGS LIGHT DIAGONAL LOWER LEFT TO MIDDLE CENTRE TO LOWER RIGHT;So;0;ON;;;;;N;;;;; +1FBDB;BOX DRAWINGS LIGHT DIAGONAL UPPER LEFT TO MIDDLE CENTRE TO LOWER LEFT;So;0;ON;;;;;N;;;;; +1FBDC;BOX DRAWINGS LIGHT DIAGONAL UPPER LEFT TO LOWER CENTRE TO UPPER RIGHT;So;0;ON;;;;;N;;;;; +1FBDD;BOX DRAWINGS LIGHT DIAGONAL UPPER RIGHT TO MIDDLE LEFT TO LOWER RIGHT;So;0;ON;;;;;N;;;;; +1FBDE;BOX DRAWINGS LIGHT DIAGONAL LOWER LEFT TO UPPER CENTRE TO LOWER RIGHT;So;0;ON;;;;;N;;;;; +1FBDF;BOX DRAWINGS LIGHT DIAGONAL UPPER LEFT TO MIDDLE RIGHT TO LOWER LEFT;So;0;ON;;;;;N;;;;; +1FBE0;TOP JUSTIFIED LOWER HALF WHITE CIRCLE;So;0;ON;;;;;N;;;;; +1FBE1;RIGHT JUSTIFIED LEFT HALF WHITE CIRCLE;So;0;ON;;;;;N;;;;; +1FBE2;BOTTOM JUSTIFIED UPPER HALF WHITE CIRCLE;So;0;ON;;;;;N;;;;; +1FBE3;LEFT JUSTIFIED RIGHT HALF WHITE CIRCLE;So;0;ON;;;;;N;;;;; +1FBE4;UPPER CENTRE ONE QUARTER BLOCK;So;0;ON;;;;;N;;;;; +1FBE5;LOWER CENTRE ONE QUARTER BLOCK;So;0;ON;;;;;N;;;;; +1FBE6;MIDDLE LEFT ONE QUARTER BLOCK;So;0;ON;;;;;N;;;;; +1FBE7;MIDDLE RIGHT ONE QUARTER BLOCK;So;0;ON;;;;;N;;;;; +1FBE8;TOP JUSTIFIED LOWER HALF BLACK CIRCLE;So;0;ON;;;;;N;;;;; +1FBE9;RIGHT JUSTIFIED LEFT HALF BLACK CIRCLE;So;0;ON;;;;;N;;;;; +1FBEA;BOTTOM JUSTIFIED UPPER HALF BLACK CIRCLE;So;0;ON;;;;;N;;;;; +1FBEB;LEFT JUSTIFIED RIGHT HALF BLACK CIRCLE;So;0;ON;;;;;N;;;;; +1FBEC;TOP RIGHT JUSTIFIED LOWER LEFT QUARTER BLACK CIRCLE;So;0;ON;;;;;N;;;;; +1FBED;BOTTOM LEFT JUSTIFIED UPPER RIGHT QUARTER BLACK CIRCLE;So;0;ON;;;;;N;;;;; +1FBEE;BOTTOM RIGHT JUSTIFIED UPPER LEFT QUARTER BLACK CIRCLE;So;0;ON;;;;;N;;;;; +1FBEF;TOP LEFT JUSTIFIED LOWER RIGHT QUARTER BLACK CIRCLE;So;0;ON;;;;;N;;;;; 1FBF0;SEGMENTED DIGIT ZERO;Nd;0;EN;<font> 0030;0;0;0;N;;;;; 1FBF1;SEGMENTED DIGIT ONE;Nd;0;EN;<font> 0031;1;1;1;N;;;;; 1FBF2;SEGMENTED DIGIT TWO;Nd;0;EN;<font> 0032;2;2;2;N;;;;; diff --git a/src/java.base/share/data/unicodedata/auxiliary/GraphemeBreakProperty.txt b/src/java.base/share/data/unicodedata/auxiliary/GraphemeBreakProperty.txt index 01a4ef02441..a4b7b6fbc3c 100644 --- a/src/java.base/share/data/unicodedata/auxiliary/GraphemeBreakProperty.txt +++ b/src/java.base/share/data/unicodedata/auxiliary/GraphemeBreakProperty.txt @@ -1,8 +1,8 @@ -# GraphemeBreakProperty-15.1.0.txt -# Date: 2023-01-05, 20:34:41 GMT -# Copyright (c) 2023 Unicode, Inc. +# GraphemeBreakProperty-16.0.0.txt +# Date: 2024-05-31, 18:09:38 GMT +# Copyright (c) 2024 Unicode, Inc. # Unicode and the Unicode Logo are registered trademarks of Unicode, Inc. in the U.S. and other countries. -# For terms of use, see https://www.unicode.org/terms_of_use.html +# For terms of use and license, see https://www.unicode.org/terms_of_use.html # # Unicode Character Database # For documentation, see https://www.unicode.org/reports/tr44/ @@ -27,6 +27,7 @@ 110BD ; Prepend # Cf KAITHI NUMBER SIGN 110CD ; Prepend # Cf KAITHI NUMBER SIGN ABOVE 111C2..111C3 ; Prepend # Lo [2] SHARADA SIGN JIHVAMULIYA..SHARADA SIGN UPADHMANIYA +113D1 ; Prepend # Lo TULU-TIGALARI REPHA 1193F ; Prepend # Lo DIVES AKURU PREFIXED NASAL SIGN 11941 ; Prepend # Lo DIVES AKURU INITIAL RA 11A3A ; Prepend # Lo ZANABAZAR SQUARE CLUSTER-INITIAL LETTER RA @@ -34,7 +35,7 @@ 11D46 ; Prepend # Lo MASARAM GONDI REPHA 11F02 ; Prepend # Lo KAWI SIGN REPHA -# Total code points: 27 +# Total code points: 28 # ================================================ @@ -106,7 +107,7 @@ E01F0..E0FFF ; Control # Cn [3600] <reserved-E01F0>..<reserved-E0FFF> 0825..0827 ; Extend # Mn [3] SAMARITAN VOWEL SIGN SHORT A..SAMARITAN VOWEL SIGN U 0829..082D ; Extend # Mn [5] SAMARITAN VOWEL SIGN LONG I..SAMARITAN MARK NEQUDAA 0859..085B ; Extend # Mn [3] MANDAIC AFFRICATION MARK..MANDAIC GEMINATION MARK -0898..089F ; Extend # Mn [8] ARABIC SMALL HIGH WORD AL-JUZ..ARABIC HALF MADDA OVER MADDA +0897..089F ; Extend # Mn [9] ARABIC PEPET..ARABIC HALF MADDA OVER MADDA 08CA..08E1 ; Extend # Mn [24] ARABIC SMALL HIGH FARSI YEH..ARABIC SMALL HIGH SIGN SAFHA 08E3..0902 ; Extend # Mn [32] ARABIC TURNED DAMMA BELOW..DEVANAGARI SIGN ANUSVARA 093A ; Extend # Mn DEVANAGARI VOWEL SIGN OE @@ -163,8 +164,11 @@ E01F0..E0FFF ; Control # Cn [3600] <reserved-E01F0>..<reserved-E0FFF> 0C81 ; Extend # Mn KANNADA SIGN CANDRABINDU 0CBC ; Extend # Mn KANNADA SIGN NUKTA 0CBF ; Extend # Mn KANNADA VOWEL SIGN I +0CC0 ; Extend # Mc KANNADA VOWEL SIGN II 0CC2 ; Extend # Mc KANNADA VOWEL SIGN UU 0CC6 ; Extend # Mn KANNADA VOWEL SIGN E +0CC7..0CC8 ; Extend # Mc [2] KANNADA VOWEL SIGN EE..KANNADA VOWEL SIGN AI +0CCA..0CCB ; Extend # Mc [2] KANNADA VOWEL SIGN O..KANNADA VOWEL SIGN OO 0CCC..0CCD ; Extend # Mn [2] KANNADA VOWEL SIGN AU..KANNADA SIGN VIRAMA 0CD5..0CD6 ; Extend # Mc [2] KANNADA LENGTH MARK..KANNADA AI LENGTH MARK 0CE2..0CE3 ; Extend # Mn [2] KANNADA VOWEL SIGN VOCALIC L..KANNADA VOWEL SIGN VOCALIC LL @@ -210,7 +214,9 @@ E01F0..E0FFF ; Control # Cn [3600] <reserved-E01F0>..<reserved-E0FFF> 109D ; Extend # Mn MYANMAR VOWEL SIGN AITON AI 135D..135F ; Extend # Mn [3] ETHIOPIC COMBINING GEMINATION AND VOWEL LENGTH MARK..ETHIOPIC COMBINING GEMINATION MARK 1712..1714 ; Extend # Mn [3] TAGALOG VOWEL SIGN I..TAGALOG SIGN VIRAMA +1715 ; Extend # Mc TAGALOG SIGN PAMUDPOD 1732..1733 ; Extend # Mn [2] HANUNOO VOWEL SIGN I..HANUNOO VOWEL SIGN U +1734 ; Extend # Mc HANUNOO SIGN PAMUDPOD 1752..1753 ; Extend # Mn [2] BUHID VOWEL SIGN I..BUHID VOWEL SIGN U 1772..1773 ; Extend # Mn [2] TAGBANWA VOWEL SIGN I..TAGBANWA VOWEL SIGN U 17B4..17B5 ; Extend # Mn [2] KHMER VOWEL INHERENT AQ..KHMER VOWEL INHERENT AA @@ -242,17 +248,22 @@ E01F0..E0FFF ; Control # Cn [3600] <reserved-E01F0>..<reserved-E0FFF> 1B34 ; Extend # Mn BALINESE SIGN REREKAN 1B35 ; Extend # Mc BALINESE VOWEL SIGN TEDUNG 1B36..1B3A ; Extend # Mn [5] BALINESE VOWEL SIGN ULU..BALINESE VOWEL SIGN RA REPA +1B3B ; Extend # Mc BALINESE VOWEL SIGN RA REPA TEDUNG 1B3C ; Extend # Mn BALINESE VOWEL SIGN LA LENGA +1B3D ; Extend # Mc BALINESE VOWEL SIGN LA LENGA TEDUNG 1B42 ; Extend # Mn BALINESE VOWEL SIGN PEPET +1B43..1B44 ; Extend # Mc [2] BALINESE VOWEL SIGN PEPET TEDUNG..BALINESE ADEG ADEG 1B6B..1B73 ; Extend # Mn [9] BALINESE MUSICAL SYMBOL COMBINING TEGEH..BALINESE MUSICAL SYMBOL COMBINING GONG 1B80..1B81 ; Extend # Mn [2] SUNDANESE SIGN PANYECEK..SUNDANESE SIGN PANGLAYAR 1BA2..1BA5 ; Extend # Mn [4] SUNDANESE CONSONANT SIGN PANYAKRA..SUNDANESE VOWEL SIGN PANYUKU 1BA8..1BA9 ; Extend # Mn [2] SUNDANESE VOWEL SIGN PAMEPET..SUNDANESE VOWEL SIGN PANEULEUNG +1BAA ; Extend # Mc SUNDANESE SIGN PAMAAEH 1BAB..1BAD ; Extend # Mn [3] SUNDANESE SIGN VIRAMA..SUNDANESE CONSONANT SIGN PASANGAN WA 1BE6 ; Extend # Mn BATAK SIGN TOMPI 1BE8..1BE9 ; Extend # Mn [2] BATAK VOWEL SIGN PAKPAK E..BATAK VOWEL SIGN EE 1BED ; Extend # Mn BATAK VOWEL SIGN KARO O 1BEF..1BF1 ; Extend # Mn [3] BATAK VOWEL SIGN U FOR SIMALUNGUN SA..BATAK CONSONANT SIGN H +1BF2..1BF3 ; Extend # Mc [2] BATAK PANGOLAT..BATAK PANONGONAN 1C2C..1C33 ; Extend # Mn [8] LEPCHA VOWEL SIGN E..LEPCHA CONSONANT SIGN T 1C36..1C37 ; Extend # Mn [2] LEPCHA SIGN RAN..LEPCHA SIGN NUKTA 1CD0..1CD2 ; Extend # Mn [3] VEDIC TONE KARSHANA..VEDIC TONE PRENKHA @@ -289,10 +300,12 @@ A8E0..A8F1 ; Extend # Mn [18] COMBINING DEVANAGARI DIGIT ZERO..COMBINING DEV A8FF ; Extend # Mn DEVANAGARI VOWEL SIGN AY A926..A92D ; Extend # Mn [8] KAYAH LI VOWEL UE..KAYAH LI TONE CALYA PLOPHU A947..A951 ; Extend # Mn [11] REJANG VOWEL SIGN I..REJANG CONSONANT SIGN R +A953 ; Extend # Mc REJANG VIRAMA A980..A982 ; Extend # Mn [3] JAVANESE SIGN PANYANGGA..JAVANESE SIGN LAYAR A9B3 ; Extend # Mn JAVANESE SIGN CECAK TELU A9B6..A9B9 ; Extend # Mn [4] JAVANESE VOWEL SIGN WULU..JAVANESE VOWEL SIGN SUKU MENDUT A9BC..A9BD ; Extend # Mn [2] JAVANESE VOWEL SIGN PEPET..JAVANESE CONSONANT SIGN KERET +A9C0 ; Extend # Mc JAVANESE PANGKON A9E5 ; Extend # Mn MYANMAR SIGN SHAN SAW AA29..AA2E ; Extend # Mn [6] CHAM VOWEL SIGN AA..CHAM VOWEL SIGN OE AA31..AA32 ; Extend # Mn [2] CHAM VOWEL SIGN AU..CHAM VOWEL SIGN UE @@ -324,8 +337,9 @@ FF9E..FF9F ; Extend # Lm [2] HALFWIDTH KATAKANA VOICED SOUND MARK..HALFWIDT 10A3F ; Extend # Mn KHAROSHTHI VIRAMA 10AE5..10AE6 ; Extend # Mn [2] MANICHAEAN ABBREVIATION MARK ABOVE..MANICHAEAN ABBREVIATION MARK BELOW 10D24..10D27 ; Extend # Mn [4] HANIFI ROHINGYA SIGN HARBAHAY..HANIFI ROHINGYA SIGN TASSI +10D69..10D6D ; Extend # Mn [5] GARAY VOWEL SIGN E..GARAY CONSONANT NASALIZATION MARK 10EAB..10EAC ; Extend # Mn [2] YEZIDI COMBINING HAMZA MARK..YEZIDI COMBINING MADDA MARK -10EFD..10EFF ; Extend # Mn [3] ARABIC SMALL LOW WORD SAKTA..ARABIC SMALL LOW WORD MADDA +10EFC..10EFF ; Extend # Mn [4] ARABIC COMBINING ALEF OVERLAY..ARABIC SMALL LOW WORD MADDA 10F46..10F50 ; Extend # Mn [11] SOGDIAN COMBINING DOT BELOW..SOGDIAN COMBINING STROKE BELOW 10F82..10F85 ; Extend # Mn [4] OLD UYGHUR COMBINING DOT ABOVE..OLD UYGHUR COMBINING TWO DOTS BELOW 11001 ; Extend # Mn BRAHMI SIGN ANUSVARA @@ -342,10 +356,12 @@ FF9E..FF9F ; Extend # Lm [2] HALFWIDTH KATAKANA VOICED SOUND MARK..HALFWIDT 11173 ; Extend # Mn MAHAJANI SIGN NUKTA 11180..11181 ; Extend # Mn [2] SHARADA SIGN CANDRABINDU..SHARADA SIGN ANUSVARA 111B6..111BE ; Extend # Mn [9] SHARADA VOWEL SIGN U..SHARADA VOWEL SIGN O +111C0 ; Extend # Mc SHARADA SIGN VIRAMA 111C9..111CC ; Extend # Mn [4] SHARADA SANDHI MARK..SHARADA EXTRA SHORT VOWEL MARK 111CF ; Extend # Mn SHARADA SIGN INVERTED CANDRABINDU 1122F..11231 ; Extend # Mn [3] KHOJKI VOWEL SIGN U..KHOJKI VOWEL SIGN AI 11234 ; Extend # Mn KHOJKI SIGN ANUSVARA +11235 ; Extend # Mc KHOJKI SIGN VIRAMA 11236..11237 ; Extend # Mn [2] KHOJKI SIGN NUKTA..KHOJKI SIGN SHADDA 1123E ; Extend # Mn KHOJKI SIGN SUKUN 11241 ; Extend # Mn KHOJKI VOWEL SIGN VOCALIC R @@ -355,9 +371,20 @@ FF9E..FF9F ; Extend # Lm [2] HALFWIDTH KATAKANA VOICED SOUND MARK..HALFWIDT 1133B..1133C ; Extend # Mn [2] COMBINING BINDU BELOW..GRANTHA SIGN NUKTA 1133E ; Extend # Mc GRANTHA VOWEL SIGN AA 11340 ; Extend # Mn GRANTHA VOWEL SIGN II +1134D ; Extend # Mc GRANTHA SIGN VIRAMA 11357 ; Extend # Mc GRANTHA AU LENGTH MARK 11366..1136C ; Extend # Mn [7] COMBINING GRANTHA DIGIT ZERO..COMBINING GRANTHA DIGIT SIX 11370..11374 ; Extend # Mn [5] COMBINING GRANTHA LETTER A..COMBINING GRANTHA LETTER PA +113B8 ; Extend # Mc TULU-TIGALARI VOWEL SIGN AA +113BB..113C0 ; Extend # Mn [6] TULU-TIGALARI VOWEL SIGN U..TULU-TIGALARI VOWEL SIGN VOCALIC LL +113C2 ; Extend # Mc TULU-TIGALARI VOWEL SIGN EE +113C5 ; Extend # Mc TULU-TIGALARI VOWEL SIGN AI +113C7..113C9 ; Extend # Mc [3] TULU-TIGALARI VOWEL SIGN OO..TULU-TIGALARI AU LENGTH MARK +113CE ; Extend # Mn TULU-TIGALARI SIGN VIRAMA +113CF ; Extend # Mc TULU-TIGALARI SIGN LOOPED VIRAMA +113D0 ; Extend # Mn TULU-TIGALARI CONJOINER +113D2 ; Extend # Mn TULU-TIGALARI GEMINATION MARK +113E1..113E2 ; Extend # Mn [2] TULU-TIGALARI VEDIC TONE SVARITA..TULU-TIGALARI VEDIC TONE ANUDATTA 11438..1143F ; Extend # Mn [8] NEWA VOWEL SIGN U..NEWA VOWEL SIGN AI 11442..11444 ; Extend # Mn [3] NEWA SIGN VIRAMA..NEWA SIGN ANUSVARA 11446 ; Extend # Mn NEWA SIGN NUKTA @@ -379,14 +406,17 @@ FF9E..FF9F ; Extend # Lm [2] HALFWIDTH KATAKANA VOICED SOUND MARK..HALFWIDT 116AB ; Extend # Mn TAKRI SIGN ANUSVARA 116AD ; Extend # Mn TAKRI VOWEL SIGN AA 116B0..116B5 ; Extend # Mn [6] TAKRI VOWEL SIGN U..TAKRI VOWEL SIGN AU +116B6 ; Extend # Mc TAKRI SIGN VIRAMA 116B7 ; Extend # Mn TAKRI SIGN NUKTA -1171D..1171F ; Extend # Mn [3] AHOM CONSONANT SIGN MEDIAL LA..AHOM CONSONANT SIGN MEDIAL LIGATING RA +1171D ; Extend # Mn AHOM CONSONANT SIGN MEDIAL LA +1171F ; Extend # Mn AHOM CONSONANT SIGN MEDIAL LIGATING RA 11722..11725 ; Extend # Mn [4] AHOM VOWEL SIGN I..AHOM VOWEL SIGN UU 11727..1172B ; Extend # Mn [5] AHOM VOWEL SIGN AW..AHOM SIGN KILLER 1182F..11837 ; Extend # Mn [9] DOGRA VOWEL SIGN U..DOGRA SIGN ANUSVARA 11839..1183A ; Extend # Mn [2] DOGRA SIGN VIRAMA..DOGRA SIGN NUKTA 11930 ; Extend # Mc DIVES AKURU VOWEL SIGN AA 1193B..1193C ; Extend # Mn [2] DIVES AKURU SIGN ANUSVARA..DIVES AKURU SIGN CANDRABINDU +1193D ; Extend # Mc DIVES AKURU SIGN HALANTA 1193E ; Extend # Mn DIVES AKURU VIRAMA 11943 ; Extend # Mn DIVES AKURU SIGN NUKTA 119D4..119D7 ; Extend # Mn [4] NANDINAGARI VOWEL SIGN U..NANDINAGARI VOWEL SIGN VOCALIC RR @@ -419,20 +449,25 @@ FF9E..FF9F ; Extend # Lm [2] HALFWIDTH KATAKANA VOICED SOUND MARK..HALFWIDT 11F00..11F01 ; Extend # Mn [2] KAWI SIGN CANDRABINDU..KAWI SIGN ANUSVARA 11F36..11F3A ; Extend # Mn [5] KAWI VOWEL SIGN I..KAWI VOWEL SIGN VOCALIC R 11F40 ; Extend # Mn KAWI VOWEL SIGN EU +11F41 ; Extend # Mc KAWI SIGN KILLER 11F42 ; Extend # Mn KAWI CONJOINER +11F5A ; Extend # Mn KAWI SIGN NUKTA 13440 ; Extend # Mn EGYPTIAN HIEROGLYPH MIRROR HORIZONTALLY 13447..13455 ; Extend # Mn [15] EGYPTIAN HIEROGLYPH MODIFIER DAMAGED AT TOP START..EGYPTIAN HIEROGLYPH MODIFIER DAMAGED +1611E..16129 ; Extend # Mn [12] GURUNG KHEMA VOWEL SIGN AA..GURUNG KHEMA VOWEL LENGTH MARK +1612D..1612F ; Extend # Mn [3] GURUNG KHEMA SIGN ANUSVARA..GURUNG KHEMA SIGN THOLHOMA 16AF0..16AF4 ; Extend # Mn [5] BASSA VAH COMBINING HIGH TONE..BASSA VAH COMBINING HIGH-LOW TONE 16B30..16B36 ; Extend # Mn [7] PAHAWH HMONG MARK CIM TUB..PAHAWH HMONG MARK CIM TAUM 16F4F ; Extend # Mn MIAO SIGN CONSONANT MODIFIER BAR 16F8F..16F92 ; Extend # Mn [4] MIAO TONE RIGHT..MIAO TONE BELOW 16FE4 ; Extend # Mn KHITAN SMALL SCRIPT FILLER +16FF0..16FF1 ; Extend # Mc [2] VIETNAMESE ALTERNATE READING MARK CA..VIETNAMESE ALTERNATE READING MARK NHAY 1BC9D..1BC9E ; Extend # Mn [2] DUPLOYAN THICK LETTER SELECTOR..DUPLOYAN DOUBLE MARK 1CF00..1CF2D ; Extend # Mn [46] ZNAMENNY COMBINING MARK GORAZDO NIZKO S KRYZHEM ON LEFT..ZNAMENNY COMBINING MARK KRYZH ON LEFT 1CF30..1CF46 ; Extend # Mn [23] ZNAMENNY COMBINING TONAL RANGE MARK MRACHNO..ZNAMENNY PRIZNAK MODIFIER ROG -1D165 ; Extend # Mc MUSICAL SYMBOL COMBINING STEM +1D165..1D166 ; Extend # Mc [2] MUSICAL SYMBOL COMBINING STEM..MUSICAL SYMBOL COMBINING SPRECHGESANG STEM 1D167..1D169 ; Extend # Mn [3] MUSICAL SYMBOL COMBINING TREMOLO-1..MUSICAL SYMBOL COMBINING TREMOLO-3 -1D16E..1D172 ; Extend # Mc [5] MUSICAL SYMBOL COMBINING FLAG-1..MUSICAL SYMBOL COMBINING FLAG-5 +1D16D..1D172 ; Extend # Mc [6] MUSICAL SYMBOL COMBINING AUGMENTATION DOT..MUSICAL SYMBOL COMBINING FLAG-5 1D17B..1D182 ; Extend # Mn [8] MUSICAL SYMBOL COMBINING ACCENT..MUSICAL SYMBOL COMBINING LOURE 1D185..1D18B ; Extend # Mn [7] MUSICAL SYMBOL COMBINING DOIT..MUSICAL SYMBOL COMBINING TRIPLE TONGUE 1D1AA..1D1AD ; Extend # Mn [4] MUSICAL SYMBOL COMBINING DOWN BOW..MUSICAL SYMBOL COMBINING SNAP PIZZICATO @@ -453,13 +488,14 @@ FF9E..FF9F ; Extend # Lm [2] HALFWIDTH KATAKANA VOICED SOUND MARK..HALFWIDT 1E2AE ; Extend # Mn TOTO SIGN RISING TONE 1E2EC..1E2EF ; Extend # Mn [4] WANCHO TONE TUP..WANCHO TONE KOINI 1E4EC..1E4EF ; Extend # Mn [4] NAG MUNDARI SIGN MUHOR..NAG MUNDARI SIGN SUTUH +1E5EE..1E5EF ; Extend # Mn [2] OL ONAL SIGN MU..OL ONAL SIGN IKIR 1E8D0..1E8D6 ; Extend # Mn [7] MENDE KIKAKUI COMBINING NUMBER TEENS..MENDE KIKAKUI COMBINING NUMBER MILLIONS 1E944..1E94A ; Extend # Mn [7] ADLAM ALIF LENGTHENER..ADLAM NUKTA 1F3FB..1F3FF ; Extend # Sk [5] EMOJI MODIFIER FITZPATRICK TYPE-1-2..EMOJI MODIFIER FITZPATRICK TYPE-6 E0020..E007F ; Extend # Cf [96] TAG SPACE..CANCEL TAG E0100..E01EF ; Extend # Mn [240] VARIATION SELECTOR-17..VARIATION SELECTOR-256 -# Total code points: 2130 +# Total code points: 2198 # ================================================ @@ -496,10 +532,8 @@ E0100..E01EF ; Extend # Mn [240] VARIATION SELECTOR-17..VARIATION SELECTOR-256 0C41..0C44 ; SpacingMark # Mc [4] TELUGU VOWEL SIGN U..TELUGU VOWEL SIGN VOCALIC RR 0C82..0C83 ; SpacingMark # Mc [2] KANNADA SIGN ANUSVARA..KANNADA SIGN VISARGA 0CBE ; SpacingMark # Mc KANNADA VOWEL SIGN AA -0CC0..0CC1 ; SpacingMark # Mc [2] KANNADA VOWEL SIGN II..KANNADA VOWEL SIGN U +0CC1 ; SpacingMark # Mc KANNADA VOWEL SIGN U 0CC3..0CC4 ; SpacingMark # Mc [2] KANNADA VOWEL SIGN VOCALIC R..KANNADA VOWEL SIGN VOCALIC RR -0CC7..0CC8 ; SpacingMark # Mc [2] KANNADA VOWEL SIGN EE..KANNADA VOWEL SIGN AI -0CCA..0CCB ; SpacingMark # Mc [2] KANNADA VOWEL SIGN O..KANNADA VOWEL SIGN OO 0CF3 ; SpacingMark # Mc KANNADA SIGN COMBINING ANUSVARA ABOVE RIGHT 0D02..0D03 ; SpacingMark # Mc [2] MALAYALAM SIGN ANUSVARA..MALAYALAM SIGN VISARGA 0D3F..0D40 ; SpacingMark # Mc [2] MALAYALAM VOWEL SIGN I..MALAYALAM VOWEL SIGN II @@ -517,8 +551,6 @@ E0100..E01EF ; Extend # Mn [240] VARIATION SELECTOR-17..VARIATION SELECTOR-256 103B..103C ; SpacingMark # Mc [2] MYANMAR CONSONANT SIGN MEDIAL YA..MYANMAR CONSONANT SIGN MEDIAL RA 1056..1057 ; SpacingMark # Mc [2] MYANMAR VOWEL SIGN VOCALIC R..MYANMAR VOWEL SIGN VOCALIC RR 1084 ; SpacingMark # Mc MYANMAR VOWEL SIGN SHAN E -1715 ; SpacingMark # Mc TAGALOG SIGN PAMUDPOD -1734 ; SpacingMark # Mc HANUNOO SIGN PAMUDPOD 17B6 ; SpacingMark # Mc KHMER VOWEL SIGN AA 17BE..17C5 ; SpacingMark # Mc [8] KHMER VOWEL SIGN OE..KHMER VOWEL SIGN AU 17C7..17C8 ; SpacingMark # Mc [2] KHMER SIGN REAHMUK..KHMER SIGN YUUKALEAPINTU @@ -531,17 +563,13 @@ E0100..E01EF ; Extend # Mn [240] VARIATION SELECTOR-17..VARIATION SELECTOR-256 1A57 ; SpacingMark # Mc TAI THAM CONSONANT SIGN LA TANG LAI 1A6D..1A72 ; SpacingMark # Mc [6] TAI THAM VOWEL SIGN OY..TAI THAM VOWEL SIGN THAM AI 1B04 ; SpacingMark # Mc BALINESE SIGN BISAH -1B3B ; SpacingMark # Mc BALINESE VOWEL SIGN RA REPA TEDUNG -1B3D..1B41 ; SpacingMark # Mc [5] BALINESE VOWEL SIGN LA LENGA TEDUNG..BALINESE VOWEL SIGN TALING REPA TEDUNG -1B43..1B44 ; SpacingMark # Mc [2] BALINESE VOWEL SIGN PEPET TEDUNG..BALINESE ADEG ADEG +1B3E..1B41 ; SpacingMark # Mc [4] BALINESE VOWEL SIGN TALING..BALINESE VOWEL SIGN TALING REPA TEDUNG 1B82 ; SpacingMark # Mc SUNDANESE SIGN PANGWISAD 1BA1 ; SpacingMark # Mc SUNDANESE CONSONANT SIGN PAMINGKAL 1BA6..1BA7 ; SpacingMark # Mc [2] SUNDANESE VOWEL SIGN PANAELAENG..SUNDANESE VOWEL SIGN PANOLONG -1BAA ; SpacingMark # Mc SUNDANESE SIGN PAMAAEH 1BE7 ; SpacingMark # Mc BATAK VOWEL SIGN E 1BEA..1BEC ; SpacingMark # Mc [3] BATAK VOWEL SIGN I..BATAK VOWEL SIGN O 1BEE ; SpacingMark # Mc BATAK VOWEL SIGN U -1BF2..1BF3 ; SpacingMark # Mc [2] BATAK PANGOLAT..BATAK PANONGONAN 1C24..1C2B ; SpacingMark # Mc [8] LEPCHA SUBJOINED LETTER YA..LEPCHA VOWEL SIGN UU 1C34..1C35 ; SpacingMark # Mc [2] LEPCHA CONSONANT SIGN NYIN-DO..LEPCHA CONSONANT SIGN KANG 1CE1 ; SpacingMark # Mc VEDIC TONE ATHARVAVEDIC INDEPENDENT SVARITA @@ -550,11 +578,11 @@ A823..A824 ; SpacingMark # Mc [2] SYLOTI NAGRI VOWEL SIGN A..SYLOTI NAGRI V A827 ; SpacingMark # Mc SYLOTI NAGRI VOWEL SIGN OO A880..A881 ; SpacingMark # Mc [2] SAURASHTRA SIGN ANUSVARA..SAURASHTRA SIGN VISARGA A8B4..A8C3 ; SpacingMark # Mc [16] SAURASHTRA CONSONANT SIGN HAARU..SAURASHTRA VOWEL SIGN AU -A952..A953 ; SpacingMark # Mc [2] REJANG CONSONANT SIGN H..REJANG VIRAMA +A952 ; SpacingMark # Mc REJANG CONSONANT SIGN H A983 ; SpacingMark # Mc JAVANESE SIGN WIGNYAN A9B4..A9B5 ; SpacingMark # Mc [2] JAVANESE VOWEL SIGN TARUNG..JAVANESE VOWEL SIGN TOLONG A9BA..A9BB ; SpacingMark # Mc [2] JAVANESE VOWEL SIGN TALING..JAVANESE VOWEL SIGN DIRGA MURE -A9BE..A9C0 ; SpacingMark # Mc [3] JAVANESE CONSONANT SIGN PENGKAL..JAVANESE PANGKON +A9BE..A9BF ; SpacingMark # Mc [2] JAVANESE CONSONANT SIGN PENGKAL..JAVANESE CONSONANT SIGN CAKRA AA2F..AA30 ; SpacingMark # Mc [2] CHAM VOWEL SIGN O..CHAM VOWEL SIGN AI AA33..AA34 ; SpacingMark # Mc [2] CHAM CONSONANT SIGN YA..CHAM CONSONANT SIGN RA AA4D ; SpacingMark # Mc CHAM CONSONANT SIGN FINAL H @@ -574,18 +602,20 @@ ABEC ; SpacingMark # Mc MEETEI MAYEK LUM IYEK 11145..11146 ; SpacingMark # Mc [2] CHAKMA VOWEL SIGN AA..CHAKMA VOWEL SIGN EI 11182 ; SpacingMark # Mc SHARADA SIGN VISARGA 111B3..111B5 ; SpacingMark # Mc [3] SHARADA VOWEL SIGN AA..SHARADA VOWEL SIGN II -111BF..111C0 ; SpacingMark # Mc [2] SHARADA VOWEL SIGN AU..SHARADA SIGN VIRAMA +111BF ; SpacingMark # Mc SHARADA VOWEL SIGN AU 111CE ; SpacingMark # Mc SHARADA VOWEL SIGN PRISHTHAMATRA E 1122C..1122E ; SpacingMark # Mc [3] KHOJKI VOWEL SIGN AA..KHOJKI VOWEL SIGN II 11232..11233 ; SpacingMark # Mc [2] KHOJKI VOWEL SIGN O..KHOJKI VOWEL SIGN AU -11235 ; SpacingMark # Mc KHOJKI SIGN VIRAMA 112E0..112E2 ; SpacingMark # Mc [3] KHUDAWADI VOWEL SIGN AA..KHUDAWADI VOWEL SIGN II 11302..11303 ; SpacingMark # Mc [2] GRANTHA SIGN ANUSVARA..GRANTHA SIGN VISARGA 1133F ; SpacingMark # Mc GRANTHA VOWEL SIGN I 11341..11344 ; SpacingMark # Mc [4] GRANTHA VOWEL SIGN U..GRANTHA VOWEL SIGN VOCALIC RR 11347..11348 ; SpacingMark # Mc [2] GRANTHA VOWEL SIGN EE..GRANTHA VOWEL SIGN AI -1134B..1134D ; SpacingMark # Mc [3] GRANTHA VOWEL SIGN OO..GRANTHA SIGN VIRAMA +1134B..1134C ; SpacingMark # Mc [2] GRANTHA VOWEL SIGN OO..GRANTHA VOWEL SIGN AU 11362..11363 ; SpacingMark # Mc [2] GRANTHA VOWEL SIGN VOCALIC L..GRANTHA VOWEL SIGN VOCALIC LL +113B9..113BA ; SpacingMark # Mc [2] TULU-TIGALARI VOWEL SIGN I..TULU-TIGALARI VOWEL SIGN II +113CA ; SpacingMark # Mc TULU-TIGALARI SIGN CANDRA ANUNASIKA +113CC..113CD ; SpacingMark # Mc [2] TULU-TIGALARI SIGN ANUSVARA..TULU-TIGALARI SIGN VISARGA 11435..11437 ; SpacingMark # Mc [3] NEWA VOWEL SIGN AA..NEWA VOWEL SIGN II 11440..11441 ; SpacingMark # Mc [2] NEWA VOWEL SIGN O..NEWA VOWEL SIGN AU 11445 ; SpacingMark # Mc NEWA SIGN VISARGA @@ -602,13 +632,12 @@ ABEC ; SpacingMark # Mc MEETEI MAYEK LUM IYEK 1163E ; SpacingMark # Mc MODI SIGN VISARGA 116AC ; SpacingMark # Mc TAKRI SIGN VISARGA 116AE..116AF ; SpacingMark # Mc [2] TAKRI VOWEL SIGN I..TAKRI VOWEL SIGN II -116B6 ; SpacingMark # Mc TAKRI SIGN VIRAMA +1171E ; SpacingMark # Mc AHOM CONSONANT SIGN MEDIAL RA 11726 ; SpacingMark # Mc AHOM VOWEL SIGN E 1182C..1182E ; SpacingMark # Mc [3] DOGRA VOWEL SIGN AA..DOGRA VOWEL SIGN II 11838 ; SpacingMark # Mc DOGRA SIGN VISARGA 11931..11935 ; SpacingMark # Mc [5] DIVES AKURU VOWEL SIGN I..DIVES AKURU VOWEL SIGN E 11937..11938 ; SpacingMark # Mc [2] DIVES AKURU VOWEL SIGN AI..DIVES AKURU VOWEL SIGN O -1193D ; SpacingMark # Mc DIVES AKURU SIGN HALANTA 11940 ; SpacingMark # Mc DIVES AKURU MEDIAL YA 11942 ; SpacingMark # Mc DIVES AKURU MEDIAL RA 119D1..119D3 ; SpacingMark # Mc [3] NANDINAGARI VOWEL SIGN AA..NANDINAGARI VOWEL SIGN II @@ -629,13 +658,10 @@ ABEC ; SpacingMark # Mc MEETEI MAYEK LUM IYEK 11F03 ; SpacingMark # Mc KAWI SIGN VISARGA 11F34..11F35 ; SpacingMark # Mc [2] KAWI VOWEL SIGN AA..KAWI VOWEL SIGN ALTERNATE AA 11F3E..11F3F ; SpacingMark # Mc [2] KAWI VOWEL SIGN E..KAWI VOWEL SIGN AI -11F41 ; SpacingMark # Mc KAWI SIGN KILLER +1612A..1612C ; SpacingMark # Mc [3] GURUNG KHEMA CONSONANT SIGN MEDIAL YA..GURUNG KHEMA CONSONANT SIGN MEDIAL HA 16F51..16F87 ; SpacingMark # Mc [55] MIAO SIGN ASPIRATION..MIAO VOWEL SIGN UI -16FF0..16FF1 ; SpacingMark # Mc [2] VIETNAMESE ALTERNATE READING MARK CA..VIETNAMESE ALTERNATE READING MARK NHAY -1D166 ; SpacingMark # Mc MUSICAL SYMBOL COMBINING SPRECHGESANG STEM -1D16D ; SpacingMark # Mc MUSICAL SYMBOL COMBINING AUGMENTATION DOT -# Total code points: 395 +# Total code points: 378 # ================================================ @@ -648,8 +674,10 @@ A960..A97C ; L # Lo [29] HANGUL CHOSEONG TIKEUT-MIEUM..HANGUL CHOSEONG SSANG 1160..11A7 ; V # Lo [72] HANGUL JUNGSEONG FILLER..HANGUL JUNGSEONG O-YAE D7B0..D7C6 ; V # Lo [23] HANGUL JUNGSEONG O-YEO..HANGUL JUNGSEONG ARAEA-E +16D63 ; V # Lo KIRAT RAI VOWEL SIGN AA +16D67..16D6A ; V # Lo [4] KIRAT RAI VOWEL SIGN E..KIRAT RAI VOWEL SIGN AU -# Total code points: 95 +# Total code points: 100 # ================================================ diff --git a/src/java.base/share/data/unicodedata/auxiliary/GraphemeBreakTest.txt b/src/java.base/share/data/unicodedata/auxiliary/GraphemeBreakTest.txt index 29a3ecb360b..3eb4b307e8e 100644 --- a/src/java.base/share/data/unicodedata/auxiliary/GraphemeBreakTest.txt +++ b/src/java.base/share/data/unicodedata/auxiliary/GraphemeBreakTest.txt @@ -1,8 +1,8 @@ -# GraphemeBreakTest-15.1.0.txt -# Date: 2023-08-07, 15:52:55 GMT -# Copyright (c) 2023 Unicode, Inc. +# GraphemeBreakTest-16.0.0.txt +# Date: 2024-05-02, 15:02:48 GMT +# Copyright (c) 2024 Unicode, Inc. # Unicode and the Unicode Logo are registered trademarks of Unicode, Inc. in the U.S. and other countries. -# For terms of use, see https://www.unicode.org/terms_of_use.html +# For terms of use and license, see https://www.unicode.org/terms_of_use.html # # Unicode Character Database # For documentation, see https://www.unicode.org/reports/tr44/ @@ -30,8 +30,8 @@ ÷ 0020 × 0308 ÷ 000A ÷ # ÷ [0.2] SPACE (Other) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] <LINE FEED (LF)> (LF) ÷ [0.3] ÷ 0020 ÷ 0001 ÷ # ÷ [0.2] SPACE (Other) ÷ [5.0] <START OF HEADING> (Control) ÷ [0.3] ÷ 0020 × 0308 ÷ 0001 ÷ # ÷ [0.2] SPACE (Other) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] <START OF HEADING> (Control) ÷ [0.3] -÷ 0020 × 034F ÷ # ÷ [0.2] SPACE (Other) × [9.0] COMBINING GRAPHEME JOINER (Extend) ÷ [0.3] -÷ 0020 × 0308 × 034F ÷ # ÷ [0.2] SPACE (Other) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] COMBINING GRAPHEME JOINER (Extend) ÷ [0.3] +÷ 0020 × 200C ÷ # ÷ [0.2] SPACE (Other) × [9.0] ZERO WIDTH NON-JOINER (Extend) ÷ [0.3] +÷ 0020 × 0308 × 200C ÷ # ÷ [0.2] SPACE (Other) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] ZERO WIDTH NON-JOINER (Extend) ÷ [0.3] ÷ 0020 ÷ 1F1E6 ÷ # ÷ [0.2] SPACE (Other) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3] ÷ 0020 × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] SPACE (Other) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3] ÷ 0020 ÷ 0600 ÷ # ÷ [0.2] SPACE (Other) ÷ [999.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3] @@ -48,8 +48,6 @@ ÷ 0020 × 0308 ÷ AC00 ÷ # ÷ [0.2] SPACE (Other) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL SYLLABLE GA (LV) ÷ [0.3] ÷ 0020 ÷ AC01 ÷ # ÷ [0.2] SPACE (Other) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3] ÷ 0020 × 0308 ÷ AC01 ÷ # ÷ [0.2] SPACE (Other) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3] -÷ 0020 × 0900 ÷ # ÷ [0.2] SPACE (Other) × [9.0] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts) ÷ [0.3] -÷ 0020 × 0308 × 0900 ÷ # ÷ [0.2] SPACE (Other) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts) ÷ [0.3] ÷ 0020 × 0903 ÷ # ÷ [0.2] SPACE (Other) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark_ConjunctLinkingScripts) ÷ [0.3] ÷ 0020 × 0308 × 0903 ÷ # ÷ [0.2] SPACE (Other) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark_ConjunctLinkingScripts) ÷ [0.3] ÷ 0020 ÷ 0904 ÷ # ÷ [0.2] SPACE (Other) ÷ [999.0] DEVANAGARI LETTER SHORT A (ConjunctLinkingScripts) ÷ [0.3] @@ -62,8 +60,8 @@ ÷ 0020 × 0308 ÷ 231A ÷ # ÷ [0.2] SPACE (Other) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] WATCH (ExtPict) ÷ [0.3] ÷ 0020 × 0300 ÷ # ÷ [0.2] SPACE (Other) × [9.0] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [0.3] ÷ 0020 × 0308 × 0300 ÷ # ÷ [0.2] SPACE (Other) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [0.3] -÷ 0020 × 093C ÷ # ÷ [0.2] SPACE (Other) × [9.0] DEVANAGARI SIGN NUKTA (Extend_ConjunctLinkingScripts_ExtCccZwj) ÷ [0.3] -÷ 0020 × 0308 × 093C ÷ # ÷ [0.2] SPACE (Other) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] DEVANAGARI SIGN NUKTA (Extend_ConjunctLinkingScripts_ExtCccZwj) ÷ [0.3] +÷ 0020 × 0900 ÷ # ÷ [0.2] SPACE (Other) × [9.0] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts_ExtCccZwj) ÷ [0.3] +÷ 0020 × 0308 × 0900 ÷ # ÷ [0.2] SPACE (Other) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts_ExtCccZwj) ÷ [0.3] ÷ 0020 × 094D ÷ # ÷ [0.2] SPACE (Other) × [9.0] DEVANAGARI SIGN VIRAMA (Extend_ConjunctLinkingScripts_ConjunctLinker_ExtCccZwj) ÷ [0.3] ÷ 0020 × 0308 × 094D ÷ # ÷ [0.2] SPACE (Other) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] DEVANAGARI SIGN VIRAMA (Extend_ConjunctLinkingScripts_ConjunctLinker_ExtCccZwj) ÷ [0.3] ÷ 0020 × 200D ÷ # ÷ [0.2] SPACE (Other) × [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [0.3] @@ -78,8 +76,8 @@ ÷ 000D ÷ 0308 ÷ 000A ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] <LINE FEED (LF)> (LF) ÷ [0.3] ÷ 000D ÷ 0001 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] <START OF HEADING> (Control) ÷ [0.3] ÷ 000D ÷ 0308 ÷ 0001 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] <START OF HEADING> (Control) ÷ [0.3] -÷ 000D ÷ 034F ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] COMBINING GRAPHEME JOINER (Extend) ÷ [0.3] -÷ 000D ÷ 0308 × 034F ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] COMBINING GRAPHEME JOINER (Extend) ÷ [0.3] +÷ 000D ÷ 200C ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] ZERO WIDTH NON-JOINER (Extend) ÷ [0.3] +÷ 000D ÷ 0308 × 200C ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] ZERO WIDTH NON-JOINER (Extend) ÷ [0.3] ÷ 000D ÷ 1F1E6 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3] ÷ 000D ÷ 0308 ÷ 1F1E6 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3] ÷ 000D ÷ 0600 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3] @@ -96,8 +94,6 @@ ÷ 000D ÷ 0308 ÷ AC00 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL SYLLABLE GA (LV) ÷ [0.3] ÷ 000D ÷ AC01 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3] ÷ 000D ÷ 0308 ÷ AC01 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3] -÷ 000D ÷ 0900 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts) ÷ [0.3] -÷ 000D ÷ 0308 × 0900 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts) ÷ [0.3] ÷ 000D ÷ 0903 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] DEVANAGARI SIGN VISARGA (SpacingMark_ConjunctLinkingScripts) ÷ [0.3] ÷ 000D ÷ 0308 × 0903 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark_ConjunctLinkingScripts) ÷ [0.3] ÷ 000D ÷ 0904 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] DEVANAGARI LETTER SHORT A (ConjunctLinkingScripts) ÷ [0.3] @@ -110,8 +106,8 @@ ÷ 000D ÷ 0308 ÷ 231A ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] WATCH (ExtPict) ÷ [0.3] ÷ 000D ÷ 0300 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [0.3] ÷ 000D ÷ 0308 × 0300 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [0.3] -÷ 000D ÷ 093C ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] DEVANAGARI SIGN NUKTA (Extend_ConjunctLinkingScripts_ExtCccZwj) ÷ [0.3] -÷ 000D ÷ 0308 × 093C ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] DEVANAGARI SIGN NUKTA (Extend_ConjunctLinkingScripts_ExtCccZwj) ÷ [0.3] +÷ 000D ÷ 0900 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts_ExtCccZwj) ÷ [0.3] +÷ 000D ÷ 0308 × 0900 ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts_ExtCccZwj) ÷ [0.3] ÷ 000D ÷ 094D ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] DEVANAGARI SIGN VIRAMA (Extend_ConjunctLinkingScripts_ConjunctLinker_ExtCccZwj) ÷ [0.3] ÷ 000D ÷ 0308 × 094D ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] DEVANAGARI SIGN VIRAMA (Extend_ConjunctLinkingScripts_ConjunctLinker_ExtCccZwj) ÷ [0.3] ÷ 000D ÷ 200D ÷ # ÷ [0.2] <CARRIAGE RETURN (CR)> (CR) ÷ [4.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [0.3] @@ -126,8 +122,8 @@ ÷ 000A ÷ 0308 ÷ 000A ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] <LINE FEED (LF)> (LF) ÷ [0.3] ÷ 000A ÷ 0001 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] <START OF HEADING> (Control) ÷ [0.3] ÷ 000A ÷ 0308 ÷ 0001 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] <START OF HEADING> (Control) ÷ [0.3] -÷ 000A ÷ 034F ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] COMBINING GRAPHEME JOINER (Extend) ÷ [0.3] -÷ 000A ÷ 0308 × 034F ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] COMBINING GRAPHEME JOINER (Extend) ÷ [0.3] +÷ 000A ÷ 200C ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] ZERO WIDTH NON-JOINER (Extend) ÷ [0.3] +÷ 000A ÷ 0308 × 200C ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] ZERO WIDTH NON-JOINER (Extend) ÷ [0.3] ÷ 000A ÷ 1F1E6 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3] ÷ 000A ÷ 0308 ÷ 1F1E6 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3] ÷ 000A ÷ 0600 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3] @@ -144,8 +140,6 @@ ÷ 000A ÷ 0308 ÷ AC00 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL SYLLABLE GA (LV) ÷ [0.3] ÷ 000A ÷ AC01 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3] ÷ 000A ÷ 0308 ÷ AC01 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3] -÷ 000A ÷ 0900 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts) ÷ [0.3] -÷ 000A ÷ 0308 × 0900 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts) ÷ [0.3] ÷ 000A ÷ 0903 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] DEVANAGARI SIGN VISARGA (SpacingMark_ConjunctLinkingScripts) ÷ [0.3] ÷ 000A ÷ 0308 × 0903 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark_ConjunctLinkingScripts) ÷ [0.3] ÷ 000A ÷ 0904 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] DEVANAGARI LETTER SHORT A (ConjunctLinkingScripts) ÷ [0.3] @@ -158,8 +152,8 @@ ÷ 000A ÷ 0308 ÷ 231A ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] WATCH (ExtPict) ÷ [0.3] ÷ 000A ÷ 0300 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [0.3] ÷ 000A ÷ 0308 × 0300 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [0.3] -÷ 000A ÷ 093C ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] DEVANAGARI SIGN NUKTA (Extend_ConjunctLinkingScripts_ExtCccZwj) ÷ [0.3] -÷ 000A ÷ 0308 × 093C ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] DEVANAGARI SIGN NUKTA (Extend_ConjunctLinkingScripts_ExtCccZwj) ÷ [0.3] +÷ 000A ÷ 0900 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts_ExtCccZwj) ÷ [0.3] +÷ 000A ÷ 0308 × 0900 ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts_ExtCccZwj) ÷ [0.3] ÷ 000A ÷ 094D ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] DEVANAGARI SIGN VIRAMA (Extend_ConjunctLinkingScripts_ConjunctLinker_ExtCccZwj) ÷ [0.3] ÷ 000A ÷ 0308 × 094D ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] DEVANAGARI SIGN VIRAMA (Extend_ConjunctLinkingScripts_ConjunctLinker_ExtCccZwj) ÷ [0.3] ÷ 000A ÷ 200D ÷ # ÷ [0.2] <LINE FEED (LF)> (LF) ÷ [4.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [0.3] @@ -174,8 +168,8 @@ ÷ 0001 ÷ 0308 ÷ 000A ÷ # ÷ [0.2] <START OF HEADING> (Control) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] <LINE FEED (LF)> (LF) ÷ [0.3] ÷ 0001 ÷ 0001 ÷ # ÷ [0.2] <START OF HEADING> (Control) ÷ [4.0] <START OF HEADING> (Control) ÷ [0.3] ÷ 0001 ÷ 0308 ÷ 0001 ÷ # ÷ [0.2] <START OF HEADING> (Control) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] <START OF HEADING> (Control) ÷ [0.3] -÷ 0001 ÷ 034F ÷ # ÷ [0.2] <START OF HEADING> (Control) ÷ [4.0] COMBINING GRAPHEME JOINER (Extend) ÷ [0.3] -÷ 0001 ÷ 0308 × 034F ÷ # ÷ [0.2] <START OF HEADING> (Control) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] COMBINING GRAPHEME JOINER (Extend) ÷ [0.3] +÷ 0001 ÷ 200C ÷ # ÷ [0.2] <START OF HEADING> (Control) ÷ [4.0] ZERO WIDTH NON-JOINER (Extend) ÷ [0.3] +÷ 0001 ÷ 0308 × 200C ÷ # ÷ [0.2] <START OF HEADING> (Control) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] ZERO WIDTH NON-JOINER (Extend) ÷ [0.3] ÷ 0001 ÷ 1F1E6 ÷ # ÷ [0.2] <START OF HEADING> (Control) ÷ [4.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3] ÷ 0001 ÷ 0308 ÷ 1F1E6 ÷ # ÷ [0.2] <START OF HEADING> (Control) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3] ÷ 0001 ÷ 0600 ÷ # ÷ [0.2] <START OF HEADING> (Control) ÷ [4.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3] @@ -192,8 +186,6 @@ ÷ 0001 ÷ 0308 ÷ AC00 ÷ # ÷ [0.2] <START OF HEADING> (Control) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL SYLLABLE GA (LV) ÷ [0.3] ÷ 0001 ÷ AC01 ÷ # ÷ [0.2] <START OF HEADING> (Control) ÷ [4.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3] ÷ 0001 ÷ 0308 ÷ AC01 ÷ # ÷ [0.2] <START OF HEADING> (Control) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3] -÷ 0001 ÷ 0900 ÷ # ÷ [0.2] <START OF HEADING> (Control) ÷ [4.0] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts) ÷ [0.3] -÷ 0001 ÷ 0308 × 0900 ÷ # ÷ [0.2] <START OF HEADING> (Control) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts) ÷ [0.3] ÷ 0001 ÷ 0903 ÷ # ÷ [0.2] <START OF HEADING> (Control) ÷ [4.0] DEVANAGARI SIGN VISARGA (SpacingMark_ConjunctLinkingScripts) ÷ [0.3] ÷ 0001 ÷ 0308 × 0903 ÷ # ÷ [0.2] <START OF HEADING> (Control) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark_ConjunctLinkingScripts) ÷ [0.3] ÷ 0001 ÷ 0904 ÷ # ÷ [0.2] <START OF HEADING> (Control) ÷ [4.0] DEVANAGARI LETTER SHORT A (ConjunctLinkingScripts) ÷ [0.3] @@ -206,62 +198,60 @@ ÷ 0001 ÷ 0308 ÷ 231A ÷ # ÷ [0.2] <START OF HEADING> (Control) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] WATCH (ExtPict) ÷ [0.3] ÷ 0001 ÷ 0300 ÷ # ÷ [0.2] <START OF HEADING> (Control) ÷ [4.0] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [0.3] ÷ 0001 ÷ 0308 × 0300 ÷ # ÷ [0.2] <START OF HEADING> (Control) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [0.3] -÷ 0001 ÷ 093C ÷ # ÷ [0.2] <START OF HEADING> (Control) ÷ [4.0] DEVANAGARI SIGN NUKTA (Extend_ConjunctLinkingScripts_ExtCccZwj) ÷ [0.3] -÷ 0001 ÷ 0308 × 093C ÷ # ÷ [0.2] <START OF HEADING> (Control) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] DEVANAGARI SIGN NUKTA (Extend_ConjunctLinkingScripts_ExtCccZwj) ÷ [0.3] +÷ 0001 ÷ 0900 ÷ # ÷ [0.2] <START OF HEADING> (Control) ÷ [4.0] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts_ExtCccZwj) ÷ [0.3] +÷ 0001 ÷ 0308 × 0900 ÷ # ÷ [0.2] <START OF HEADING> (Control) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts_ExtCccZwj) ÷ [0.3] ÷ 0001 ÷ 094D ÷ # ÷ [0.2] <START OF HEADING> (Control) ÷ [4.0] DEVANAGARI SIGN VIRAMA (Extend_ConjunctLinkingScripts_ConjunctLinker_ExtCccZwj) ÷ [0.3] ÷ 0001 ÷ 0308 × 094D ÷ # ÷ [0.2] <START OF HEADING> (Control) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] DEVANAGARI SIGN VIRAMA (Extend_ConjunctLinkingScripts_ConjunctLinker_ExtCccZwj) ÷ [0.3] ÷ 0001 ÷ 200D ÷ # ÷ [0.2] <START OF HEADING> (Control) ÷ [4.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [0.3] ÷ 0001 ÷ 0308 × 200D ÷ # ÷ [0.2] <START OF HEADING> (Control) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [0.3] ÷ 0001 ÷ 0378 ÷ # ÷ [0.2] <START OF HEADING> (Control) ÷ [4.0] <reserved-0378> (Other) ÷ [0.3] ÷ 0001 ÷ 0308 ÷ 0378 ÷ # ÷ [0.2] <START OF HEADING> (Control) ÷ [4.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] <reserved-0378> (Other) ÷ [0.3] -÷ 034F ÷ 0020 ÷ # ÷ [0.2] COMBINING GRAPHEME JOINER (Extend) ÷ [999.0] SPACE (Other) ÷ [0.3] -÷ 034F × 0308 ÷ 0020 ÷ # ÷ [0.2] COMBINING GRAPHEME JOINER (Extend) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] SPACE (Other) ÷ [0.3] -÷ 034F ÷ 000D ÷ # ÷ [0.2] COMBINING GRAPHEME JOINER (Extend) ÷ [5.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3] -÷ 034F × 0308 ÷ 000D ÷ # ÷ [0.2] COMBINING GRAPHEME JOINER (Extend) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3] -÷ 034F ÷ 000A ÷ # ÷ [0.2] COMBINING GRAPHEME JOINER (Extend) ÷ [5.0] <LINE FEED (LF)> (LF) ÷ [0.3] -÷ 034F × 0308 ÷ 000A ÷ # ÷ [0.2] COMBINING GRAPHEME JOINER (Extend) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] <LINE FEED (LF)> (LF) ÷ [0.3] -÷ 034F ÷ 0001 ÷ # ÷ [0.2] COMBINING GRAPHEME JOINER (Extend) ÷ [5.0] <START OF HEADING> (Control) ÷ [0.3] -÷ 034F × 0308 ÷ 0001 ÷ # ÷ [0.2] COMBINING GRAPHEME JOINER (Extend) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] <START OF HEADING> (Control) ÷ [0.3] -÷ 034F × 034F ÷ # ÷ [0.2] COMBINING GRAPHEME JOINER (Extend) × [9.0] COMBINING GRAPHEME JOINER (Extend) ÷ [0.3] -÷ 034F × 0308 × 034F ÷ # ÷ [0.2] COMBINING GRAPHEME JOINER (Extend) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] COMBINING GRAPHEME JOINER (Extend) ÷ [0.3] -÷ 034F ÷ 1F1E6 ÷ # ÷ [0.2] COMBINING GRAPHEME JOINER (Extend) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3] -÷ 034F × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] COMBINING GRAPHEME JOINER (Extend) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3] -÷ 034F ÷ 0600 ÷ # ÷ [0.2] COMBINING GRAPHEME JOINER (Extend) ÷ [999.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3] -÷ 034F × 0308 ÷ 0600 ÷ # ÷ [0.2] COMBINING GRAPHEME JOINER (Extend) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3] -÷ 034F × 0A03 ÷ # ÷ [0.2] COMBINING GRAPHEME JOINER (Extend) × [9.1] GURMUKHI SIGN VISARGA (SpacingMark) ÷ [0.3] -÷ 034F × 0308 × 0A03 ÷ # ÷ [0.2] COMBINING GRAPHEME JOINER (Extend) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.1] GURMUKHI SIGN VISARGA (SpacingMark) ÷ [0.3] -÷ 034F ÷ 1100 ÷ # ÷ [0.2] COMBINING GRAPHEME JOINER (Extend) ÷ [999.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3] -÷ 034F × 0308 ÷ 1100 ÷ # ÷ [0.2] COMBINING GRAPHEME JOINER (Extend) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3] -÷ 034F ÷ 1160 ÷ # ÷ [0.2] COMBINING GRAPHEME JOINER (Extend) ÷ [999.0] HANGUL JUNGSEONG FILLER (V) ÷ [0.3] -÷ 034F × 0308 ÷ 1160 ÷ # ÷ [0.2] COMBINING GRAPHEME JOINER (Extend) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL JUNGSEONG FILLER (V) ÷ [0.3] -÷ 034F ÷ 11A8 ÷ # ÷ [0.2] COMBINING GRAPHEME JOINER (Extend) ÷ [999.0] HANGUL JONGSEONG KIYEOK (T) ÷ [0.3] -÷ 034F × 0308 ÷ 11A8 ÷ # ÷ [0.2] COMBINING GRAPHEME JOINER (Extend) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL JONGSEONG KIYEOK (T) ÷ [0.3] -÷ 034F ÷ AC00 ÷ # ÷ [0.2] COMBINING GRAPHEME JOINER (Extend) ÷ [999.0] HANGUL SYLLABLE GA (LV) ÷ [0.3] -÷ 034F × 0308 ÷ AC00 ÷ # ÷ [0.2] COMBINING GRAPHEME JOINER (Extend) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL SYLLABLE GA (LV) ÷ [0.3] -÷ 034F ÷ AC01 ÷ # ÷ [0.2] COMBINING GRAPHEME JOINER (Extend) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3] -÷ 034F × 0308 ÷ AC01 ÷ # ÷ [0.2] COMBINING GRAPHEME JOINER (Extend) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3] -÷ 034F × 0900 ÷ # ÷ [0.2] COMBINING GRAPHEME JOINER (Extend) × [9.0] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts) ÷ [0.3] -÷ 034F × 0308 × 0900 ÷ # ÷ [0.2] COMBINING GRAPHEME JOINER (Extend) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts) ÷ [0.3] -÷ 034F × 0903 ÷ # ÷ [0.2] COMBINING GRAPHEME JOINER (Extend) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark_ConjunctLinkingScripts) ÷ [0.3] -÷ 034F × 0308 × 0903 ÷ # ÷ [0.2] COMBINING GRAPHEME JOINER (Extend) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark_ConjunctLinkingScripts) ÷ [0.3] -÷ 034F ÷ 0904 ÷ # ÷ [0.2] COMBINING GRAPHEME JOINER (Extend) ÷ [999.0] DEVANAGARI LETTER SHORT A (ConjunctLinkingScripts) ÷ [0.3] -÷ 034F × 0308 ÷ 0904 ÷ # ÷ [0.2] COMBINING GRAPHEME JOINER (Extend) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] DEVANAGARI LETTER SHORT A (ConjunctLinkingScripts) ÷ [0.3] -÷ 034F ÷ 0D4E ÷ # ÷ [0.2] COMBINING GRAPHEME JOINER (Extend) ÷ [999.0] MALAYALAM LETTER DOT REPH (Prepend_ConjunctLinkingScripts) ÷ [0.3] -÷ 034F × 0308 ÷ 0D4E ÷ # ÷ [0.2] COMBINING GRAPHEME JOINER (Extend) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] MALAYALAM LETTER DOT REPH (Prepend_ConjunctLinkingScripts) ÷ [0.3] -÷ 034F ÷ 0915 ÷ # ÷ [0.2] COMBINING GRAPHEME JOINER (Extend) ÷ [999.0] DEVANAGARI LETTER KA (ConjunctLinkingScripts_LinkingConsonant) ÷ [0.3] -÷ 034F × 0308 ÷ 0915 ÷ # ÷ [0.2] COMBINING GRAPHEME JOINER (Extend) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] DEVANAGARI LETTER KA (ConjunctLinkingScripts_LinkingConsonant) ÷ [0.3] -÷ 034F ÷ 231A ÷ # ÷ [0.2] COMBINING GRAPHEME JOINER (Extend) ÷ [999.0] WATCH (ExtPict) ÷ [0.3] -÷ 034F × 0308 ÷ 231A ÷ # ÷ [0.2] COMBINING GRAPHEME JOINER (Extend) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] WATCH (ExtPict) ÷ [0.3] -÷ 034F × 0300 ÷ # ÷ [0.2] COMBINING GRAPHEME JOINER (Extend) × [9.0] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [0.3] -÷ 034F × 0308 × 0300 ÷ # ÷ [0.2] COMBINING GRAPHEME JOINER (Extend) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [0.3] -÷ 034F × 093C ÷ # ÷ [0.2] COMBINING GRAPHEME JOINER (Extend) × [9.0] DEVANAGARI SIGN NUKTA (Extend_ConjunctLinkingScripts_ExtCccZwj) ÷ [0.3] -÷ 034F × 0308 × 093C ÷ # ÷ [0.2] COMBINING GRAPHEME JOINER (Extend) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] DEVANAGARI SIGN NUKTA (Extend_ConjunctLinkingScripts_ExtCccZwj) ÷ [0.3] -÷ 034F × 094D ÷ # ÷ [0.2] COMBINING GRAPHEME JOINER (Extend) × [9.0] DEVANAGARI SIGN VIRAMA (Extend_ConjunctLinkingScripts_ConjunctLinker_ExtCccZwj) ÷ [0.3] -÷ 034F × 0308 × 094D ÷ # ÷ [0.2] COMBINING GRAPHEME JOINER (Extend) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] DEVANAGARI SIGN VIRAMA (Extend_ConjunctLinkingScripts_ConjunctLinker_ExtCccZwj) ÷ [0.3] -÷ 034F × 200D ÷ # ÷ [0.2] COMBINING GRAPHEME JOINER (Extend) × [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [0.3] -÷ 034F × 0308 × 200D ÷ # ÷ [0.2] COMBINING GRAPHEME JOINER (Extend) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [0.3] -÷ 034F ÷ 0378 ÷ # ÷ [0.2] COMBINING GRAPHEME JOINER (Extend) ÷ [999.0] <reserved-0378> (Other) ÷ [0.3] -÷ 034F × 0308 ÷ 0378 ÷ # ÷ [0.2] COMBINING GRAPHEME JOINER (Extend) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] <reserved-0378> (Other) ÷ [0.3] +÷ 200C ÷ 0020 ÷ # ÷ [0.2] ZERO WIDTH NON-JOINER (Extend) ÷ [999.0] SPACE (Other) ÷ [0.3] +÷ 200C × 0308 ÷ 0020 ÷ # ÷ [0.2] ZERO WIDTH NON-JOINER (Extend) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] SPACE (Other) ÷ [0.3] +÷ 200C ÷ 000D ÷ # ÷ [0.2] ZERO WIDTH NON-JOINER (Extend) ÷ [5.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3] +÷ 200C × 0308 ÷ 000D ÷ # ÷ [0.2] ZERO WIDTH NON-JOINER (Extend) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3] +÷ 200C ÷ 000A ÷ # ÷ [0.2] ZERO WIDTH NON-JOINER (Extend) ÷ [5.0] <LINE FEED (LF)> (LF) ÷ [0.3] +÷ 200C × 0308 ÷ 000A ÷ # ÷ [0.2] ZERO WIDTH NON-JOINER (Extend) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] <LINE FEED (LF)> (LF) ÷ [0.3] +÷ 200C ÷ 0001 ÷ # ÷ [0.2] ZERO WIDTH NON-JOINER (Extend) ÷ [5.0] <START OF HEADING> (Control) ÷ [0.3] +÷ 200C × 0308 ÷ 0001 ÷ # ÷ [0.2] ZERO WIDTH NON-JOINER (Extend) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] <START OF HEADING> (Control) ÷ [0.3] +÷ 200C × 200C ÷ # ÷ [0.2] ZERO WIDTH NON-JOINER (Extend) × [9.0] ZERO WIDTH NON-JOINER (Extend) ÷ [0.3] +÷ 200C × 0308 × 200C ÷ # ÷ [0.2] ZERO WIDTH NON-JOINER (Extend) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] ZERO WIDTH NON-JOINER (Extend) ÷ [0.3] +÷ 200C ÷ 1F1E6 ÷ # ÷ [0.2] ZERO WIDTH NON-JOINER (Extend) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3] +÷ 200C × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] ZERO WIDTH NON-JOINER (Extend) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3] +÷ 200C ÷ 0600 ÷ # ÷ [0.2] ZERO WIDTH NON-JOINER (Extend) ÷ [999.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3] +÷ 200C × 0308 ÷ 0600 ÷ # ÷ [0.2] ZERO WIDTH NON-JOINER (Extend) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3] +÷ 200C × 0A03 ÷ # ÷ [0.2] ZERO WIDTH NON-JOINER (Extend) × [9.1] GURMUKHI SIGN VISARGA (SpacingMark) ÷ [0.3] +÷ 200C × 0308 × 0A03 ÷ # ÷ [0.2] ZERO WIDTH NON-JOINER (Extend) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.1] GURMUKHI SIGN VISARGA (SpacingMark) ÷ [0.3] +÷ 200C ÷ 1100 ÷ # ÷ [0.2] ZERO WIDTH NON-JOINER (Extend) ÷ [999.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3] +÷ 200C × 0308 ÷ 1100 ÷ # ÷ [0.2] ZERO WIDTH NON-JOINER (Extend) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3] +÷ 200C ÷ 1160 ÷ # ÷ [0.2] ZERO WIDTH NON-JOINER (Extend) ÷ [999.0] HANGUL JUNGSEONG FILLER (V) ÷ [0.3] +÷ 200C × 0308 ÷ 1160 ÷ # ÷ [0.2] ZERO WIDTH NON-JOINER (Extend) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL JUNGSEONG FILLER (V) ÷ [0.3] +÷ 200C ÷ 11A8 ÷ # ÷ [0.2] ZERO WIDTH NON-JOINER (Extend) ÷ [999.0] HANGUL JONGSEONG KIYEOK (T) ÷ [0.3] +÷ 200C × 0308 ÷ 11A8 ÷ # ÷ [0.2] ZERO WIDTH NON-JOINER (Extend) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL JONGSEONG KIYEOK (T) ÷ [0.3] +÷ 200C ÷ AC00 ÷ # ÷ [0.2] ZERO WIDTH NON-JOINER (Extend) ÷ [999.0] HANGUL SYLLABLE GA (LV) ÷ [0.3] +÷ 200C × 0308 ÷ AC00 ÷ # ÷ [0.2] ZERO WIDTH NON-JOINER (Extend) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL SYLLABLE GA (LV) ÷ [0.3] +÷ 200C ÷ AC01 ÷ # ÷ [0.2] ZERO WIDTH NON-JOINER (Extend) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3] +÷ 200C × 0308 ÷ AC01 ÷ # ÷ [0.2] ZERO WIDTH NON-JOINER (Extend) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3] +÷ 200C × 0903 ÷ # ÷ [0.2] ZERO WIDTH NON-JOINER (Extend) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark_ConjunctLinkingScripts) ÷ [0.3] +÷ 200C × 0308 × 0903 ÷ # ÷ [0.2] ZERO WIDTH NON-JOINER (Extend) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark_ConjunctLinkingScripts) ÷ [0.3] +÷ 200C ÷ 0904 ÷ # ÷ [0.2] ZERO WIDTH NON-JOINER (Extend) ÷ [999.0] DEVANAGARI LETTER SHORT A (ConjunctLinkingScripts) ÷ [0.3] +÷ 200C × 0308 ÷ 0904 ÷ # ÷ [0.2] ZERO WIDTH NON-JOINER (Extend) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] DEVANAGARI LETTER SHORT A (ConjunctLinkingScripts) ÷ [0.3] +÷ 200C ÷ 0D4E ÷ # ÷ [0.2] ZERO WIDTH NON-JOINER (Extend) ÷ [999.0] MALAYALAM LETTER DOT REPH (Prepend_ConjunctLinkingScripts) ÷ [0.3] +÷ 200C × 0308 ÷ 0D4E ÷ # ÷ [0.2] ZERO WIDTH NON-JOINER (Extend) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] MALAYALAM LETTER DOT REPH (Prepend_ConjunctLinkingScripts) ÷ [0.3] +÷ 200C ÷ 0915 ÷ # ÷ [0.2] ZERO WIDTH NON-JOINER (Extend) ÷ [999.0] DEVANAGARI LETTER KA (ConjunctLinkingScripts_LinkingConsonant) ÷ [0.3] +÷ 200C × 0308 ÷ 0915 ÷ # ÷ [0.2] ZERO WIDTH NON-JOINER (Extend) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] DEVANAGARI LETTER KA (ConjunctLinkingScripts_LinkingConsonant) ÷ [0.3] +÷ 200C ÷ 231A ÷ # ÷ [0.2] ZERO WIDTH NON-JOINER (Extend) ÷ [999.0] WATCH (ExtPict) ÷ [0.3] +÷ 200C × 0308 ÷ 231A ÷ # ÷ [0.2] ZERO WIDTH NON-JOINER (Extend) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] WATCH (ExtPict) ÷ [0.3] +÷ 200C × 0300 ÷ # ÷ [0.2] ZERO WIDTH NON-JOINER (Extend) × [9.0] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [0.3] +÷ 200C × 0308 × 0300 ÷ # ÷ [0.2] ZERO WIDTH NON-JOINER (Extend) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [0.3] +÷ 200C × 0900 ÷ # ÷ [0.2] ZERO WIDTH NON-JOINER (Extend) × [9.0] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts_ExtCccZwj) ÷ [0.3] +÷ 200C × 0308 × 0900 ÷ # ÷ [0.2] ZERO WIDTH NON-JOINER (Extend) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts_ExtCccZwj) ÷ [0.3] +÷ 200C × 094D ÷ # ÷ [0.2] ZERO WIDTH NON-JOINER (Extend) × [9.0] DEVANAGARI SIGN VIRAMA (Extend_ConjunctLinkingScripts_ConjunctLinker_ExtCccZwj) ÷ [0.3] +÷ 200C × 0308 × 094D ÷ # ÷ [0.2] ZERO WIDTH NON-JOINER (Extend) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] DEVANAGARI SIGN VIRAMA (Extend_ConjunctLinkingScripts_ConjunctLinker_ExtCccZwj) ÷ [0.3] +÷ 200C × 200D ÷ # ÷ [0.2] ZERO WIDTH NON-JOINER (Extend) × [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [0.3] +÷ 200C × 0308 × 200D ÷ # ÷ [0.2] ZERO WIDTH NON-JOINER (Extend) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [0.3] +÷ 200C ÷ 0378 ÷ # ÷ [0.2] ZERO WIDTH NON-JOINER (Extend) ÷ [999.0] <reserved-0378> (Other) ÷ [0.3] +÷ 200C × 0308 ÷ 0378 ÷ # ÷ [0.2] ZERO WIDTH NON-JOINER (Extend) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] <reserved-0378> (Other) ÷ [0.3] ÷ 1F1E6 ÷ 0020 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [999.0] SPACE (Other) ÷ [0.3] ÷ 1F1E6 × 0308 ÷ 0020 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] SPACE (Other) ÷ [0.3] ÷ 1F1E6 ÷ 000D ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [5.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3] @@ -270,8 +260,8 @@ ÷ 1F1E6 × 0308 ÷ 000A ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] <LINE FEED (LF)> (LF) ÷ [0.3] ÷ 1F1E6 ÷ 0001 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [5.0] <START OF HEADING> (Control) ÷ [0.3] ÷ 1F1E6 × 0308 ÷ 0001 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] <START OF HEADING> (Control) ÷ [0.3] -÷ 1F1E6 × 034F ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING GRAPHEME JOINER (Extend) ÷ [0.3] -÷ 1F1E6 × 0308 × 034F ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] COMBINING GRAPHEME JOINER (Extend) ÷ [0.3] +÷ 1F1E6 × 200C ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] ZERO WIDTH NON-JOINER (Extend) ÷ [0.3] +÷ 1F1E6 × 0308 × 200C ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] ZERO WIDTH NON-JOINER (Extend) ÷ [0.3] ÷ 1F1E6 × 1F1E6 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [12.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3] ÷ 1F1E6 × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3] ÷ 1F1E6 ÷ 0600 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [999.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3] @@ -288,8 +278,6 @@ ÷ 1F1E6 × 0308 ÷ AC00 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL SYLLABLE GA (LV) ÷ [0.3] ÷ 1F1E6 ÷ AC01 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3] ÷ 1F1E6 × 0308 ÷ AC01 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3] -÷ 1F1E6 × 0900 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts) ÷ [0.3] -÷ 1F1E6 × 0308 × 0900 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts) ÷ [0.3] ÷ 1F1E6 × 0903 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark_ConjunctLinkingScripts) ÷ [0.3] ÷ 1F1E6 × 0308 × 0903 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark_ConjunctLinkingScripts) ÷ [0.3] ÷ 1F1E6 ÷ 0904 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [999.0] DEVANAGARI LETTER SHORT A (ConjunctLinkingScripts) ÷ [0.3] @@ -302,8 +290,8 @@ ÷ 1F1E6 × 0308 ÷ 231A ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] WATCH (ExtPict) ÷ [0.3] ÷ 1F1E6 × 0300 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [0.3] ÷ 1F1E6 × 0308 × 0300 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [0.3] -÷ 1F1E6 × 093C ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] DEVANAGARI SIGN NUKTA (Extend_ConjunctLinkingScripts_ExtCccZwj) ÷ [0.3] -÷ 1F1E6 × 0308 × 093C ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] DEVANAGARI SIGN NUKTA (Extend_ConjunctLinkingScripts_ExtCccZwj) ÷ [0.3] +÷ 1F1E6 × 0900 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts_ExtCccZwj) ÷ [0.3] +÷ 1F1E6 × 0308 × 0900 ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts_ExtCccZwj) ÷ [0.3] ÷ 1F1E6 × 094D ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] DEVANAGARI SIGN VIRAMA (Extend_ConjunctLinkingScripts_ConjunctLinker_ExtCccZwj) ÷ [0.3] ÷ 1F1E6 × 0308 × 094D ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] DEVANAGARI SIGN VIRAMA (Extend_ConjunctLinkingScripts_ConjunctLinker_ExtCccZwj) ÷ [0.3] ÷ 1F1E6 × 200D ÷ # ÷ [0.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) × [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [0.3] @@ -318,8 +306,8 @@ ÷ 0600 × 0308 ÷ 000A ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] <LINE FEED (LF)> (LF) ÷ [0.3] ÷ 0600 ÷ 0001 ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) ÷ [5.0] <START OF HEADING> (Control) ÷ [0.3] ÷ 0600 × 0308 ÷ 0001 ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] <START OF HEADING> (Control) ÷ [0.3] -÷ 0600 × 034F ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) × [9.0] COMBINING GRAPHEME JOINER (Extend) ÷ [0.3] -÷ 0600 × 0308 × 034F ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] COMBINING GRAPHEME JOINER (Extend) ÷ [0.3] +÷ 0600 × 200C ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) × [9.0] ZERO WIDTH NON-JOINER (Extend) ÷ [0.3] +÷ 0600 × 0308 × 200C ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] ZERO WIDTH NON-JOINER (Extend) ÷ [0.3] ÷ 0600 × 1F1E6 ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) × [9.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3] ÷ 0600 × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3] ÷ 0600 × 0600 ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) × [9.2] ARABIC NUMBER SIGN (Prepend) ÷ [0.3] @@ -336,8 +324,6 @@ ÷ 0600 × 0308 ÷ AC00 ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL SYLLABLE GA (LV) ÷ [0.3] ÷ 0600 × AC01 ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) × [9.2] HANGUL SYLLABLE GAG (LVT) ÷ [0.3] ÷ 0600 × 0308 ÷ AC01 ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3] -÷ 0600 × 0900 ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) × [9.0] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts) ÷ [0.3] -÷ 0600 × 0308 × 0900 ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts) ÷ [0.3] ÷ 0600 × 0903 ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark_ConjunctLinkingScripts) ÷ [0.3] ÷ 0600 × 0308 × 0903 ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark_ConjunctLinkingScripts) ÷ [0.3] ÷ 0600 × 0904 ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) × [9.2] DEVANAGARI LETTER SHORT A (ConjunctLinkingScripts) ÷ [0.3] @@ -350,8 +336,8 @@ ÷ 0600 × 0308 ÷ 231A ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] WATCH (ExtPict) ÷ [0.3] ÷ 0600 × 0300 ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) × [9.0] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [0.3] ÷ 0600 × 0308 × 0300 ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [0.3] -÷ 0600 × 093C ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) × [9.0] DEVANAGARI SIGN NUKTA (Extend_ConjunctLinkingScripts_ExtCccZwj) ÷ [0.3] -÷ 0600 × 0308 × 093C ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] DEVANAGARI SIGN NUKTA (Extend_ConjunctLinkingScripts_ExtCccZwj) ÷ [0.3] +÷ 0600 × 0900 ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) × [9.0] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts_ExtCccZwj) ÷ [0.3] +÷ 0600 × 0308 × 0900 ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts_ExtCccZwj) ÷ [0.3] ÷ 0600 × 094D ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) × [9.0] DEVANAGARI SIGN VIRAMA (Extend_ConjunctLinkingScripts_ConjunctLinker_ExtCccZwj) ÷ [0.3] ÷ 0600 × 0308 × 094D ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] DEVANAGARI SIGN VIRAMA (Extend_ConjunctLinkingScripts_ConjunctLinker_ExtCccZwj) ÷ [0.3] ÷ 0600 × 200D ÷ # ÷ [0.2] ARABIC NUMBER SIGN (Prepend) × [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [0.3] @@ -366,8 +352,8 @@ ÷ 0A03 × 0308 ÷ 000A ÷ # ÷ [0.2] GURMUKHI SIGN VISARGA (SpacingMark) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] <LINE FEED (LF)> (LF) ÷ [0.3] ÷ 0A03 ÷ 0001 ÷ # ÷ [0.2] GURMUKHI SIGN VISARGA (SpacingMark) ÷ [5.0] <START OF HEADING> (Control) ÷ [0.3] ÷ 0A03 × 0308 ÷ 0001 ÷ # ÷ [0.2] GURMUKHI SIGN VISARGA (SpacingMark) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] <START OF HEADING> (Control) ÷ [0.3] -÷ 0A03 × 034F ÷ # ÷ [0.2] GURMUKHI SIGN VISARGA (SpacingMark) × [9.0] COMBINING GRAPHEME JOINER (Extend) ÷ [0.3] -÷ 0A03 × 0308 × 034F ÷ # ÷ [0.2] GURMUKHI SIGN VISARGA (SpacingMark) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] COMBINING GRAPHEME JOINER (Extend) ÷ [0.3] +÷ 0A03 × 200C ÷ # ÷ [0.2] GURMUKHI SIGN VISARGA (SpacingMark) × [9.0] ZERO WIDTH NON-JOINER (Extend) ÷ [0.3] +÷ 0A03 × 0308 × 200C ÷ # ÷ [0.2] GURMUKHI SIGN VISARGA (SpacingMark) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] ZERO WIDTH NON-JOINER (Extend) ÷ [0.3] ÷ 0A03 ÷ 1F1E6 ÷ # ÷ [0.2] GURMUKHI SIGN VISARGA (SpacingMark) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3] ÷ 0A03 × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] GURMUKHI SIGN VISARGA (SpacingMark) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3] ÷ 0A03 ÷ 0600 ÷ # ÷ [0.2] GURMUKHI SIGN VISARGA (SpacingMark) ÷ [999.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3] @@ -384,8 +370,6 @@ ÷ 0A03 × 0308 ÷ AC00 ÷ # ÷ [0.2] GURMUKHI SIGN VISARGA (SpacingMark) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL SYLLABLE GA (LV) ÷ [0.3] ÷ 0A03 ÷ AC01 ÷ # ÷ [0.2] GURMUKHI SIGN VISARGA (SpacingMark) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3] ÷ 0A03 × 0308 ÷ AC01 ÷ # ÷ [0.2] GURMUKHI SIGN VISARGA (SpacingMark) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3] -÷ 0A03 × 0900 ÷ # ÷ [0.2] GURMUKHI SIGN VISARGA (SpacingMark) × [9.0] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts) ÷ [0.3] -÷ 0A03 × 0308 × 0900 ÷ # ÷ [0.2] GURMUKHI SIGN VISARGA (SpacingMark) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts) ÷ [0.3] ÷ 0A03 × 0903 ÷ # ÷ [0.2] GURMUKHI SIGN VISARGA (SpacingMark) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark_ConjunctLinkingScripts) ÷ [0.3] ÷ 0A03 × 0308 × 0903 ÷ # ÷ [0.2] GURMUKHI SIGN VISARGA (SpacingMark) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark_ConjunctLinkingScripts) ÷ [0.3] ÷ 0A03 ÷ 0904 ÷ # ÷ [0.2] GURMUKHI SIGN VISARGA (SpacingMark) ÷ [999.0] DEVANAGARI LETTER SHORT A (ConjunctLinkingScripts) ÷ [0.3] @@ -398,8 +382,8 @@ ÷ 0A03 × 0308 ÷ 231A ÷ # ÷ [0.2] GURMUKHI SIGN VISARGA (SpacingMark) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] WATCH (ExtPict) ÷ [0.3] ÷ 0A03 × 0300 ÷ # ÷ [0.2] GURMUKHI SIGN VISARGA (SpacingMark) × [9.0] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [0.3] ÷ 0A03 × 0308 × 0300 ÷ # ÷ [0.2] GURMUKHI SIGN VISARGA (SpacingMark) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [0.3] -÷ 0A03 × 093C ÷ # ÷ [0.2] GURMUKHI SIGN VISARGA (SpacingMark) × [9.0] DEVANAGARI SIGN NUKTA (Extend_ConjunctLinkingScripts_ExtCccZwj) ÷ [0.3] -÷ 0A03 × 0308 × 093C ÷ # ÷ [0.2] GURMUKHI SIGN VISARGA (SpacingMark) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] DEVANAGARI SIGN NUKTA (Extend_ConjunctLinkingScripts_ExtCccZwj) ÷ [0.3] +÷ 0A03 × 0900 ÷ # ÷ [0.2] GURMUKHI SIGN VISARGA (SpacingMark) × [9.0] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts_ExtCccZwj) ÷ [0.3] +÷ 0A03 × 0308 × 0900 ÷ # ÷ [0.2] GURMUKHI SIGN VISARGA (SpacingMark) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts_ExtCccZwj) ÷ [0.3] ÷ 0A03 × 094D ÷ # ÷ [0.2] GURMUKHI SIGN VISARGA (SpacingMark) × [9.0] DEVANAGARI SIGN VIRAMA (Extend_ConjunctLinkingScripts_ConjunctLinker_ExtCccZwj) ÷ [0.3] ÷ 0A03 × 0308 × 094D ÷ # ÷ [0.2] GURMUKHI SIGN VISARGA (SpacingMark) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] DEVANAGARI SIGN VIRAMA (Extend_ConjunctLinkingScripts_ConjunctLinker_ExtCccZwj) ÷ [0.3] ÷ 0A03 × 200D ÷ # ÷ [0.2] GURMUKHI SIGN VISARGA (SpacingMark) × [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [0.3] @@ -414,8 +398,8 @@ ÷ 1100 × 0308 ÷ 000A ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] <LINE FEED (LF)> (LF) ÷ [0.3] ÷ 1100 ÷ 0001 ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) ÷ [5.0] <START OF HEADING> (Control) ÷ [0.3] ÷ 1100 × 0308 ÷ 0001 ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] <START OF HEADING> (Control) ÷ [0.3] -÷ 1100 × 034F ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) × [9.0] COMBINING GRAPHEME JOINER (Extend) ÷ [0.3] -÷ 1100 × 0308 × 034F ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] COMBINING GRAPHEME JOINER (Extend) ÷ [0.3] +÷ 1100 × 200C ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) × [9.0] ZERO WIDTH NON-JOINER (Extend) ÷ [0.3] +÷ 1100 × 0308 × 200C ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] ZERO WIDTH NON-JOINER (Extend) ÷ [0.3] ÷ 1100 ÷ 1F1E6 ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3] ÷ 1100 × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3] ÷ 1100 ÷ 0600 ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) ÷ [999.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3] @@ -432,8 +416,6 @@ ÷ 1100 × 0308 ÷ AC00 ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL SYLLABLE GA (LV) ÷ [0.3] ÷ 1100 × AC01 ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) × [6.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3] ÷ 1100 × 0308 ÷ AC01 ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3] -÷ 1100 × 0900 ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) × [9.0] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts) ÷ [0.3] -÷ 1100 × 0308 × 0900 ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts) ÷ [0.3] ÷ 1100 × 0903 ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark_ConjunctLinkingScripts) ÷ [0.3] ÷ 1100 × 0308 × 0903 ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark_ConjunctLinkingScripts) ÷ [0.3] ÷ 1100 ÷ 0904 ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) ÷ [999.0] DEVANAGARI LETTER SHORT A (ConjunctLinkingScripts) ÷ [0.3] @@ -446,8 +428,8 @@ ÷ 1100 × 0308 ÷ 231A ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] WATCH (ExtPict) ÷ [0.3] ÷ 1100 × 0300 ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) × [9.0] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [0.3] ÷ 1100 × 0308 × 0300 ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [0.3] -÷ 1100 × 093C ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) × [9.0] DEVANAGARI SIGN NUKTA (Extend_ConjunctLinkingScripts_ExtCccZwj) ÷ [0.3] -÷ 1100 × 0308 × 093C ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] DEVANAGARI SIGN NUKTA (Extend_ConjunctLinkingScripts_ExtCccZwj) ÷ [0.3] +÷ 1100 × 0900 ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) × [9.0] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts_ExtCccZwj) ÷ [0.3] +÷ 1100 × 0308 × 0900 ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts_ExtCccZwj) ÷ [0.3] ÷ 1100 × 094D ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) × [9.0] DEVANAGARI SIGN VIRAMA (Extend_ConjunctLinkingScripts_ConjunctLinker_ExtCccZwj) ÷ [0.3] ÷ 1100 × 0308 × 094D ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] DEVANAGARI SIGN VIRAMA (Extend_ConjunctLinkingScripts_ConjunctLinker_ExtCccZwj) ÷ [0.3] ÷ 1100 × 200D ÷ # ÷ [0.2] HANGUL CHOSEONG KIYEOK (L) × [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [0.3] @@ -462,8 +444,8 @@ ÷ 1160 × 0308 ÷ 000A ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] <LINE FEED (LF)> (LF) ÷ [0.3] ÷ 1160 ÷ 0001 ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) ÷ [5.0] <START OF HEADING> (Control) ÷ [0.3] ÷ 1160 × 0308 ÷ 0001 ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] <START OF HEADING> (Control) ÷ [0.3] -÷ 1160 × 034F ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) × [9.0] COMBINING GRAPHEME JOINER (Extend) ÷ [0.3] -÷ 1160 × 0308 × 034F ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] COMBINING GRAPHEME JOINER (Extend) ÷ [0.3] +÷ 1160 × 200C ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) × [9.0] ZERO WIDTH NON-JOINER (Extend) ÷ [0.3] +÷ 1160 × 0308 × 200C ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] ZERO WIDTH NON-JOINER (Extend) ÷ [0.3] ÷ 1160 ÷ 1F1E6 ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3] ÷ 1160 × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3] ÷ 1160 ÷ 0600 ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) ÷ [999.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3] @@ -480,8 +462,6 @@ ÷ 1160 × 0308 ÷ AC00 ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL SYLLABLE GA (LV) ÷ [0.3] ÷ 1160 ÷ AC01 ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3] ÷ 1160 × 0308 ÷ AC01 ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3] -÷ 1160 × 0900 ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) × [9.0] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts) ÷ [0.3] -÷ 1160 × 0308 × 0900 ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts) ÷ [0.3] ÷ 1160 × 0903 ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark_ConjunctLinkingScripts) ÷ [0.3] ÷ 1160 × 0308 × 0903 ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark_ConjunctLinkingScripts) ÷ [0.3] ÷ 1160 ÷ 0904 ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) ÷ [999.0] DEVANAGARI LETTER SHORT A (ConjunctLinkingScripts) ÷ [0.3] @@ -494,8 +474,8 @@ ÷ 1160 × 0308 ÷ 231A ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] WATCH (ExtPict) ÷ [0.3] ÷ 1160 × 0300 ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) × [9.0] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [0.3] ÷ 1160 × 0308 × 0300 ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [0.3] -÷ 1160 × 093C ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) × [9.0] DEVANAGARI SIGN NUKTA (Extend_ConjunctLinkingScripts_ExtCccZwj) ÷ [0.3] -÷ 1160 × 0308 × 093C ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] DEVANAGARI SIGN NUKTA (Extend_ConjunctLinkingScripts_ExtCccZwj) ÷ [0.3] +÷ 1160 × 0900 ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) × [9.0] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts_ExtCccZwj) ÷ [0.3] +÷ 1160 × 0308 × 0900 ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts_ExtCccZwj) ÷ [0.3] ÷ 1160 × 094D ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) × [9.0] DEVANAGARI SIGN VIRAMA (Extend_ConjunctLinkingScripts_ConjunctLinker_ExtCccZwj) ÷ [0.3] ÷ 1160 × 0308 × 094D ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] DEVANAGARI SIGN VIRAMA (Extend_ConjunctLinkingScripts_ConjunctLinker_ExtCccZwj) ÷ [0.3] ÷ 1160 × 200D ÷ # ÷ [0.2] HANGUL JUNGSEONG FILLER (V) × [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [0.3] @@ -510,8 +490,8 @@ ÷ 11A8 × 0308 ÷ 000A ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] <LINE FEED (LF)> (LF) ÷ [0.3] ÷ 11A8 ÷ 0001 ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) ÷ [5.0] <START OF HEADING> (Control) ÷ [0.3] ÷ 11A8 × 0308 ÷ 0001 ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] <START OF HEADING> (Control) ÷ [0.3] -÷ 11A8 × 034F ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) × [9.0] COMBINING GRAPHEME JOINER (Extend) ÷ [0.3] -÷ 11A8 × 0308 × 034F ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] COMBINING GRAPHEME JOINER (Extend) ÷ [0.3] +÷ 11A8 × 200C ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) × [9.0] ZERO WIDTH NON-JOINER (Extend) ÷ [0.3] +÷ 11A8 × 0308 × 200C ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] ZERO WIDTH NON-JOINER (Extend) ÷ [0.3] ÷ 11A8 ÷ 1F1E6 ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3] ÷ 11A8 × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3] ÷ 11A8 ÷ 0600 ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) ÷ [999.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3] @@ -528,8 +508,6 @@ ÷ 11A8 × 0308 ÷ AC00 ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL SYLLABLE GA (LV) ÷ [0.3] ÷ 11A8 ÷ AC01 ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3] ÷ 11A8 × 0308 ÷ AC01 ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3] -÷ 11A8 × 0900 ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) × [9.0] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts) ÷ [0.3] -÷ 11A8 × 0308 × 0900 ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts) ÷ [0.3] ÷ 11A8 × 0903 ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark_ConjunctLinkingScripts) ÷ [0.3] ÷ 11A8 × 0308 × 0903 ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark_ConjunctLinkingScripts) ÷ [0.3] ÷ 11A8 ÷ 0904 ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) ÷ [999.0] DEVANAGARI LETTER SHORT A (ConjunctLinkingScripts) ÷ [0.3] @@ -542,8 +520,8 @@ ÷ 11A8 × 0308 ÷ 231A ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] WATCH (ExtPict) ÷ [0.3] ÷ 11A8 × 0300 ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) × [9.0] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [0.3] ÷ 11A8 × 0308 × 0300 ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [0.3] -÷ 11A8 × 093C ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) × [9.0] DEVANAGARI SIGN NUKTA (Extend_ConjunctLinkingScripts_ExtCccZwj) ÷ [0.3] -÷ 11A8 × 0308 × 093C ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] DEVANAGARI SIGN NUKTA (Extend_ConjunctLinkingScripts_ExtCccZwj) ÷ [0.3] +÷ 11A8 × 0900 ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) × [9.0] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts_ExtCccZwj) ÷ [0.3] +÷ 11A8 × 0308 × 0900 ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts_ExtCccZwj) ÷ [0.3] ÷ 11A8 × 094D ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) × [9.0] DEVANAGARI SIGN VIRAMA (Extend_ConjunctLinkingScripts_ConjunctLinker_ExtCccZwj) ÷ [0.3] ÷ 11A8 × 0308 × 094D ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] DEVANAGARI SIGN VIRAMA (Extend_ConjunctLinkingScripts_ConjunctLinker_ExtCccZwj) ÷ [0.3] ÷ 11A8 × 200D ÷ # ÷ [0.2] HANGUL JONGSEONG KIYEOK (T) × [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [0.3] @@ -558,8 +536,8 @@ ÷ AC00 × 0308 ÷ 000A ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] <LINE FEED (LF)> (LF) ÷ [0.3] ÷ AC00 ÷ 0001 ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) ÷ [5.0] <START OF HEADING> (Control) ÷ [0.3] ÷ AC00 × 0308 ÷ 0001 ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] <START OF HEADING> (Control) ÷ [0.3] -÷ AC00 × 034F ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) × [9.0] COMBINING GRAPHEME JOINER (Extend) ÷ [0.3] -÷ AC00 × 0308 × 034F ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] COMBINING GRAPHEME JOINER (Extend) ÷ [0.3] +÷ AC00 × 200C ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) × [9.0] ZERO WIDTH NON-JOINER (Extend) ÷ [0.3] +÷ AC00 × 0308 × 200C ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] ZERO WIDTH NON-JOINER (Extend) ÷ [0.3] ÷ AC00 ÷ 1F1E6 ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3] ÷ AC00 × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3] ÷ AC00 ÷ 0600 ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) ÷ [999.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3] @@ -576,8 +554,6 @@ ÷ AC00 × 0308 ÷ AC00 ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL SYLLABLE GA (LV) ÷ [0.3] ÷ AC00 ÷ AC01 ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3] ÷ AC00 × 0308 ÷ AC01 ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3] -÷ AC00 × 0900 ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) × [9.0] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts) ÷ [0.3] -÷ AC00 × 0308 × 0900 ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts) ÷ [0.3] ÷ AC00 × 0903 ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark_ConjunctLinkingScripts) ÷ [0.3] ÷ AC00 × 0308 × 0903 ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark_ConjunctLinkingScripts) ÷ [0.3] ÷ AC00 ÷ 0904 ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) ÷ [999.0] DEVANAGARI LETTER SHORT A (ConjunctLinkingScripts) ÷ [0.3] @@ -590,8 +566,8 @@ ÷ AC00 × 0308 ÷ 231A ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] WATCH (ExtPict) ÷ [0.3] ÷ AC00 × 0300 ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) × [9.0] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [0.3] ÷ AC00 × 0308 × 0300 ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [0.3] -÷ AC00 × 093C ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) × [9.0] DEVANAGARI SIGN NUKTA (Extend_ConjunctLinkingScripts_ExtCccZwj) ÷ [0.3] -÷ AC00 × 0308 × 093C ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] DEVANAGARI SIGN NUKTA (Extend_ConjunctLinkingScripts_ExtCccZwj) ÷ [0.3] +÷ AC00 × 0900 ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) × [9.0] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts_ExtCccZwj) ÷ [0.3] +÷ AC00 × 0308 × 0900 ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts_ExtCccZwj) ÷ [0.3] ÷ AC00 × 094D ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) × [9.0] DEVANAGARI SIGN VIRAMA (Extend_ConjunctLinkingScripts_ConjunctLinker_ExtCccZwj) ÷ [0.3] ÷ AC00 × 0308 × 094D ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] DEVANAGARI SIGN VIRAMA (Extend_ConjunctLinkingScripts_ConjunctLinker_ExtCccZwj) ÷ [0.3] ÷ AC00 × 200D ÷ # ÷ [0.2] HANGUL SYLLABLE GA (LV) × [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [0.3] @@ -606,8 +582,8 @@ ÷ AC01 × 0308 ÷ 000A ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] <LINE FEED (LF)> (LF) ÷ [0.3] ÷ AC01 ÷ 0001 ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) ÷ [5.0] <START OF HEADING> (Control) ÷ [0.3] ÷ AC01 × 0308 ÷ 0001 ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] <START OF HEADING> (Control) ÷ [0.3] -÷ AC01 × 034F ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) × [9.0] COMBINING GRAPHEME JOINER (Extend) ÷ [0.3] -÷ AC01 × 0308 × 034F ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] COMBINING GRAPHEME JOINER (Extend) ÷ [0.3] +÷ AC01 × 200C ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) × [9.0] ZERO WIDTH NON-JOINER (Extend) ÷ [0.3] +÷ AC01 × 0308 × 200C ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] ZERO WIDTH NON-JOINER (Extend) ÷ [0.3] ÷ AC01 ÷ 1F1E6 ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3] ÷ AC01 × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3] ÷ AC01 ÷ 0600 ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) ÷ [999.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3] @@ -624,8 +600,6 @@ ÷ AC01 × 0308 ÷ AC00 ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL SYLLABLE GA (LV) ÷ [0.3] ÷ AC01 ÷ AC01 ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3] ÷ AC01 × 0308 ÷ AC01 ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3] -÷ AC01 × 0900 ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) × [9.0] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts) ÷ [0.3] -÷ AC01 × 0308 × 0900 ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts) ÷ [0.3] ÷ AC01 × 0903 ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark_ConjunctLinkingScripts) ÷ [0.3] ÷ AC01 × 0308 × 0903 ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark_ConjunctLinkingScripts) ÷ [0.3] ÷ AC01 ÷ 0904 ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) ÷ [999.0] DEVANAGARI LETTER SHORT A (ConjunctLinkingScripts) ÷ [0.3] @@ -638,62 +612,14 @@ ÷ AC01 × 0308 ÷ 231A ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] WATCH (ExtPict) ÷ [0.3] ÷ AC01 × 0300 ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) × [9.0] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [0.3] ÷ AC01 × 0308 × 0300 ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [0.3] -÷ AC01 × 093C ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) × [9.0] DEVANAGARI SIGN NUKTA (Extend_ConjunctLinkingScripts_ExtCccZwj) ÷ [0.3] -÷ AC01 × 0308 × 093C ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] DEVANAGARI SIGN NUKTA (Extend_ConjunctLinkingScripts_ExtCccZwj) ÷ [0.3] +÷ AC01 × 0900 ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) × [9.0] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts_ExtCccZwj) ÷ [0.3] +÷ AC01 × 0308 × 0900 ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts_ExtCccZwj) ÷ [0.3] ÷ AC01 × 094D ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) × [9.0] DEVANAGARI SIGN VIRAMA (Extend_ConjunctLinkingScripts_ConjunctLinker_ExtCccZwj) ÷ [0.3] ÷ AC01 × 0308 × 094D ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] DEVANAGARI SIGN VIRAMA (Extend_ConjunctLinkingScripts_ConjunctLinker_ExtCccZwj) ÷ [0.3] ÷ AC01 × 200D ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) × [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [0.3] ÷ AC01 × 0308 × 200D ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [0.3] ÷ AC01 ÷ 0378 ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) ÷ [999.0] <reserved-0378> (Other) ÷ [0.3] ÷ AC01 × 0308 ÷ 0378 ÷ # ÷ [0.2] HANGUL SYLLABLE GAG (LVT) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] <reserved-0378> (Other) ÷ [0.3] -÷ 0900 ÷ 0020 ÷ # ÷ [0.2] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts) ÷ [999.0] SPACE (Other) ÷ [0.3] -÷ 0900 × 0308 ÷ 0020 ÷ # ÷ [0.2] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] SPACE (Other) ÷ [0.3] -÷ 0900 ÷ 000D ÷ # ÷ [0.2] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts) ÷ [5.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3] -÷ 0900 × 0308 ÷ 000D ÷ # ÷ [0.2] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3] -÷ 0900 ÷ 000A ÷ # ÷ [0.2] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts) ÷ [5.0] <LINE FEED (LF)> (LF) ÷ [0.3] -÷ 0900 × 0308 ÷ 000A ÷ # ÷ [0.2] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] <LINE FEED (LF)> (LF) ÷ [0.3] -÷ 0900 ÷ 0001 ÷ # ÷ [0.2] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts) ÷ [5.0] <START OF HEADING> (Control) ÷ [0.3] -÷ 0900 × 0308 ÷ 0001 ÷ # ÷ [0.2] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] <START OF HEADING> (Control) ÷ [0.3] -÷ 0900 × 034F ÷ # ÷ [0.2] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts) × [9.0] COMBINING GRAPHEME JOINER (Extend) ÷ [0.3] -÷ 0900 × 0308 × 034F ÷ # ÷ [0.2] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] COMBINING GRAPHEME JOINER (Extend) ÷ [0.3] -÷ 0900 ÷ 1F1E6 ÷ # ÷ [0.2] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3] -÷ 0900 × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3] -÷ 0900 ÷ 0600 ÷ # ÷ [0.2] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts) ÷ [999.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3] -÷ 0900 × 0308 ÷ 0600 ÷ # ÷ [0.2] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3] -÷ 0900 × 0A03 ÷ # ÷ [0.2] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts) × [9.1] GURMUKHI SIGN VISARGA (SpacingMark) ÷ [0.3] -÷ 0900 × 0308 × 0A03 ÷ # ÷ [0.2] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.1] GURMUKHI SIGN VISARGA (SpacingMark) ÷ [0.3] -÷ 0900 ÷ 1100 ÷ # ÷ [0.2] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts) ÷ [999.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3] -÷ 0900 × 0308 ÷ 1100 ÷ # ÷ [0.2] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3] -÷ 0900 ÷ 1160 ÷ # ÷ [0.2] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts) ÷ [999.0] HANGUL JUNGSEONG FILLER (V) ÷ [0.3] -÷ 0900 × 0308 ÷ 1160 ÷ # ÷ [0.2] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL JUNGSEONG FILLER (V) ÷ [0.3] -÷ 0900 ÷ 11A8 ÷ # ÷ [0.2] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts) ÷ [999.0] HANGUL JONGSEONG KIYEOK (T) ÷ [0.3] -÷ 0900 × 0308 ÷ 11A8 ÷ # ÷ [0.2] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL JONGSEONG KIYEOK (T) ÷ [0.3] -÷ 0900 ÷ AC00 ÷ # ÷ [0.2] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts) ÷ [999.0] HANGUL SYLLABLE GA (LV) ÷ [0.3] -÷ 0900 × 0308 ÷ AC00 ÷ # ÷ [0.2] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL SYLLABLE GA (LV) ÷ [0.3] -÷ 0900 ÷ AC01 ÷ # ÷ [0.2] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3] -÷ 0900 × 0308 ÷ AC01 ÷ # ÷ [0.2] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3] -÷ 0900 × 0900 ÷ # ÷ [0.2] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts) × [9.0] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts) ÷ [0.3] -÷ 0900 × 0308 × 0900 ÷ # ÷ [0.2] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts) ÷ [0.3] -÷ 0900 × 0903 ÷ # ÷ [0.2] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark_ConjunctLinkingScripts) ÷ [0.3] -÷ 0900 × 0308 × 0903 ÷ # ÷ [0.2] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark_ConjunctLinkingScripts) ÷ [0.3] -÷ 0900 ÷ 0904 ÷ # ÷ [0.2] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts) ÷ [999.0] DEVANAGARI LETTER SHORT A (ConjunctLinkingScripts) ÷ [0.3] -÷ 0900 × 0308 ÷ 0904 ÷ # ÷ [0.2] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] DEVANAGARI LETTER SHORT A (ConjunctLinkingScripts) ÷ [0.3] -÷ 0900 ÷ 0D4E ÷ # ÷ [0.2] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts) ÷ [999.0] MALAYALAM LETTER DOT REPH (Prepend_ConjunctLinkingScripts) ÷ [0.3] -÷ 0900 × 0308 ÷ 0D4E ÷ # ÷ [0.2] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] MALAYALAM LETTER DOT REPH (Prepend_ConjunctLinkingScripts) ÷ [0.3] -÷ 0900 ÷ 0915 ÷ # ÷ [0.2] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts) ÷ [999.0] DEVANAGARI LETTER KA (ConjunctLinkingScripts_LinkingConsonant) ÷ [0.3] -÷ 0900 × 0308 ÷ 0915 ÷ # ÷ [0.2] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] DEVANAGARI LETTER KA (ConjunctLinkingScripts_LinkingConsonant) ÷ [0.3] -÷ 0900 ÷ 231A ÷ # ÷ [0.2] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts) ÷ [999.0] WATCH (ExtPict) ÷ [0.3] -÷ 0900 × 0308 ÷ 231A ÷ # ÷ [0.2] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] WATCH (ExtPict) ÷ [0.3] -÷ 0900 × 0300 ÷ # ÷ [0.2] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts) × [9.0] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [0.3] -÷ 0900 × 0308 × 0300 ÷ # ÷ [0.2] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [0.3] -÷ 0900 × 093C ÷ # ÷ [0.2] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts) × [9.0] DEVANAGARI SIGN NUKTA (Extend_ConjunctLinkingScripts_ExtCccZwj) ÷ [0.3] -÷ 0900 × 0308 × 093C ÷ # ÷ [0.2] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] DEVANAGARI SIGN NUKTA (Extend_ConjunctLinkingScripts_ExtCccZwj) ÷ [0.3] -÷ 0900 × 094D ÷ # ÷ [0.2] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts) × [9.0] DEVANAGARI SIGN VIRAMA (Extend_ConjunctLinkingScripts_ConjunctLinker_ExtCccZwj) ÷ [0.3] -÷ 0900 × 0308 × 094D ÷ # ÷ [0.2] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] DEVANAGARI SIGN VIRAMA (Extend_ConjunctLinkingScripts_ConjunctLinker_ExtCccZwj) ÷ [0.3] -÷ 0900 × 200D ÷ # ÷ [0.2] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts) × [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [0.3] -÷ 0900 × 0308 × 200D ÷ # ÷ [0.2] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [0.3] -÷ 0900 ÷ 0378 ÷ # ÷ [0.2] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts) ÷ [999.0] <reserved-0378> (Other) ÷ [0.3] -÷ 0900 × 0308 ÷ 0378 ÷ # ÷ [0.2] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] <reserved-0378> (Other) ÷ [0.3] ÷ 0903 ÷ 0020 ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark_ConjunctLinkingScripts) ÷ [999.0] SPACE (Other) ÷ [0.3] ÷ 0903 × 0308 ÷ 0020 ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark_ConjunctLinkingScripts) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] SPACE (Other) ÷ [0.3] ÷ 0903 ÷ 000D ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark_ConjunctLinkingScripts) ÷ [5.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3] @@ -702,8 +628,8 @@ ÷ 0903 × 0308 ÷ 000A ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark_ConjunctLinkingScripts) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] <LINE FEED (LF)> (LF) ÷ [0.3] ÷ 0903 ÷ 0001 ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark_ConjunctLinkingScripts) ÷ [5.0] <START OF HEADING> (Control) ÷ [0.3] ÷ 0903 × 0308 ÷ 0001 ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark_ConjunctLinkingScripts) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] <START OF HEADING> (Control) ÷ [0.3] -÷ 0903 × 034F ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark_ConjunctLinkingScripts) × [9.0] COMBINING GRAPHEME JOINER (Extend) ÷ [0.3] -÷ 0903 × 0308 × 034F ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark_ConjunctLinkingScripts) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] COMBINING GRAPHEME JOINER (Extend) ÷ [0.3] +÷ 0903 × 200C ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark_ConjunctLinkingScripts) × [9.0] ZERO WIDTH NON-JOINER (Extend) ÷ [0.3] +÷ 0903 × 0308 × 200C ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark_ConjunctLinkingScripts) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] ZERO WIDTH NON-JOINER (Extend) ÷ [0.3] ÷ 0903 ÷ 1F1E6 ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark_ConjunctLinkingScripts) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3] ÷ 0903 × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark_ConjunctLinkingScripts) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3] ÷ 0903 ÷ 0600 ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark_ConjunctLinkingScripts) ÷ [999.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3] @@ -720,8 +646,6 @@ ÷ 0903 × 0308 ÷ AC00 ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark_ConjunctLinkingScripts) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL SYLLABLE GA (LV) ÷ [0.3] ÷ 0903 ÷ AC01 ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark_ConjunctLinkingScripts) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3] ÷ 0903 × 0308 ÷ AC01 ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark_ConjunctLinkingScripts) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3] -÷ 0903 × 0900 ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark_ConjunctLinkingScripts) × [9.0] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts) ÷ [0.3] -÷ 0903 × 0308 × 0900 ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark_ConjunctLinkingScripts) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts) ÷ [0.3] ÷ 0903 × 0903 ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark_ConjunctLinkingScripts) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark_ConjunctLinkingScripts) ÷ [0.3] ÷ 0903 × 0308 × 0903 ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark_ConjunctLinkingScripts) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark_ConjunctLinkingScripts) ÷ [0.3] ÷ 0903 ÷ 0904 ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark_ConjunctLinkingScripts) ÷ [999.0] DEVANAGARI LETTER SHORT A (ConjunctLinkingScripts) ÷ [0.3] @@ -734,8 +658,8 @@ ÷ 0903 × 0308 ÷ 231A ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark_ConjunctLinkingScripts) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] WATCH (ExtPict) ÷ [0.3] ÷ 0903 × 0300 ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark_ConjunctLinkingScripts) × [9.0] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [0.3] ÷ 0903 × 0308 × 0300 ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark_ConjunctLinkingScripts) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [0.3] -÷ 0903 × 093C ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark_ConjunctLinkingScripts) × [9.0] DEVANAGARI SIGN NUKTA (Extend_ConjunctLinkingScripts_ExtCccZwj) ÷ [0.3] -÷ 0903 × 0308 × 093C ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark_ConjunctLinkingScripts) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] DEVANAGARI SIGN NUKTA (Extend_ConjunctLinkingScripts_ExtCccZwj) ÷ [0.3] +÷ 0903 × 0900 ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark_ConjunctLinkingScripts) × [9.0] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts_ExtCccZwj) ÷ [0.3] +÷ 0903 × 0308 × 0900 ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark_ConjunctLinkingScripts) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts_ExtCccZwj) ÷ [0.3] ÷ 0903 × 094D ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark_ConjunctLinkingScripts) × [9.0] DEVANAGARI SIGN VIRAMA (Extend_ConjunctLinkingScripts_ConjunctLinker_ExtCccZwj) ÷ [0.3] ÷ 0903 × 0308 × 094D ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark_ConjunctLinkingScripts) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] DEVANAGARI SIGN VIRAMA (Extend_ConjunctLinkingScripts_ConjunctLinker_ExtCccZwj) ÷ [0.3] ÷ 0903 × 200D ÷ # ÷ [0.2] DEVANAGARI SIGN VISARGA (SpacingMark_ConjunctLinkingScripts) × [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [0.3] @@ -750,8 +674,8 @@ ÷ 0904 × 0308 ÷ 000A ÷ # ÷ [0.2] DEVANAGARI LETTER SHORT A (ConjunctLinkingScripts) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] <LINE FEED (LF)> (LF) ÷ [0.3] ÷ 0904 ÷ 0001 ÷ # ÷ [0.2] DEVANAGARI LETTER SHORT A (ConjunctLinkingScripts) ÷ [5.0] <START OF HEADING> (Control) ÷ [0.3] ÷ 0904 × 0308 ÷ 0001 ÷ # ÷ [0.2] DEVANAGARI LETTER SHORT A (ConjunctLinkingScripts) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] <START OF HEADING> (Control) ÷ [0.3] -÷ 0904 × 034F ÷ # ÷ [0.2] DEVANAGARI LETTER SHORT A (ConjunctLinkingScripts) × [9.0] COMBINING GRAPHEME JOINER (Extend) ÷ [0.3] -÷ 0904 × 0308 × 034F ÷ # ÷ [0.2] DEVANAGARI LETTER SHORT A (ConjunctLinkingScripts) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] COMBINING GRAPHEME JOINER (Extend) ÷ [0.3] +÷ 0904 × 200C ÷ # ÷ [0.2] DEVANAGARI LETTER SHORT A (ConjunctLinkingScripts) × [9.0] ZERO WIDTH NON-JOINER (Extend) ÷ [0.3] +÷ 0904 × 0308 × 200C ÷ # ÷ [0.2] DEVANAGARI LETTER SHORT A (ConjunctLinkingScripts) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] ZERO WIDTH NON-JOINER (Extend) ÷ [0.3] ÷ 0904 ÷ 1F1E6 ÷ # ÷ [0.2] DEVANAGARI LETTER SHORT A (ConjunctLinkingScripts) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3] ÷ 0904 × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] DEVANAGARI LETTER SHORT A (ConjunctLinkingScripts) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3] ÷ 0904 ÷ 0600 ÷ # ÷ [0.2] DEVANAGARI LETTER SHORT A (ConjunctLinkingScripts) ÷ [999.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3] @@ -768,8 +692,6 @@ ÷ 0904 × 0308 ÷ AC00 ÷ # ÷ [0.2] DEVANAGARI LETTER SHORT A (ConjunctLinkingScripts) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL SYLLABLE GA (LV) ÷ [0.3] ÷ 0904 ÷ AC01 ÷ # ÷ [0.2] DEVANAGARI LETTER SHORT A (ConjunctLinkingScripts) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3] ÷ 0904 × 0308 ÷ AC01 ÷ # ÷ [0.2] DEVANAGARI LETTER SHORT A (ConjunctLinkingScripts) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3] -÷ 0904 × 0900 ÷ # ÷ [0.2] DEVANAGARI LETTER SHORT A (ConjunctLinkingScripts) × [9.0] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts) ÷ [0.3] -÷ 0904 × 0308 × 0900 ÷ # ÷ [0.2] DEVANAGARI LETTER SHORT A (ConjunctLinkingScripts) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts) ÷ [0.3] ÷ 0904 × 0903 ÷ # ÷ [0.2] DEVANAGARI LETTER SHORT A (ConjunctLinkingScripts) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark_ConjunctLinkingScripts) ÷ [0.3] ÷ 0904 × 0308 × 0903 ÷ # ÷ [0.2] DEVANAGARI LETTER SHORT A (ConjunctLinkingScripts) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark_ConjunctLinkingScripts) ÷ [0.3] ÷ 0904 ÷ 0904 ÷ # ÷ [0.2] DEVANAGARI LETTER SHORT A (ConjunctLinkingScripts) ÷ [999.0] DEVANAGARI LETTER SHORT A (ConjunctLinkingScripts) ÷ [0.3] @@ -782,8 +704,8 @@ ÷ 0904 × 0308 ÷ 231A ÷ # ÷ [0.2] DEVANAGARI LETTER SHORT A (ConjunctLinkingScripts) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] WATCH (ExtPict) ÷ [0.3] ÷ 0904 × 0300 ÷ # ÷ [0.2] DEVANAGARI LETTER SHORT A (ConjunctLinkingScripts) × [9.0] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [0.3] ÷ 0904 × 0308 × 0300 ÷ # ÷ [0.2] DEVANAGARI LETTER SHORT A (ConjunctLinkingScripts) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [0.3] -÷ 0904 × 093C ÷ # ÷ [0.2] DEVANAGARI LETTER SHORT A (ConjunctLinkingScripts) × [9.0] DEVANAGARI SIGN NUKTA (Extend_ConjunctLinkingScripts_ExtCccZwj) ÷ [0.3] -÷ 0904 × 0308 × 093C ÷ # ÷ [0.2] DEVANAGARI LETTER SHORT A (ConjunctLinkingScripts) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] DEVANAGARI SIGN NUKTA (Extend_ConjunctLinkingScripts_ExtCccZwj) ÷ [0.3] +÷ 0904 × 0900 ÷ # ÷ [0.2] DEVANAGARI LETTER SHORT A (ConjunctLinkingScripts) × [9.0] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts_ExtCccZwj) ÷ [0.3] +÷ 0904 × 0308 × 0900 ÷ # ÷ [0.2] DEVANAGARI LETTER SHORT A (ConjunctLinkingScripts) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts_ExtCccZwj) ÷ [0.3] ÷ 0904 × 094D ÷ # ÷ [0.2] DEVANAGARI LETTER SHORT A (ConjunctLinkingScripts) × [9.0] DEVANAGARI SIGN VIRAMA (Extend_ConjunctLinkingScripts_ConjunctLinker_ExtCccZwj) ÷ [0.3] ÷ 0904 × 0308 × 094D ÷ # ÷ [0.2] DEVANAGARI LETTER SHORT A (ConjunctLinkingScripts) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] DEVANAGARI SIGN VIRAMA (Extend_ConjunctLinkingScripts_ConjunctLinker_ExtCccZwj) ÷ [0.3] ÷ 0904 × 200D ÷ # ÷ [0.2] DEVANAGARI LETTER SHORT A (ConjunctLinkingScripts) × [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [0.3] @@ -798,8 +720,8 @@ ÷ 0D4E × 0308 ÷ 000A ÷ # ÷ [0.2] MALAYALAM LETTER DOT REPH (Prepend_ConjunctLinkingScripts) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] <LINE FEED (LF)> (LF) ÷ [0.3] ÷ 0D4E ÷ 0001 ÷ # ÷ [0.2] MALAYALAM LETTER DOT REPH (Prepend_ConjunctLinkingScripts) ÷ [5.0] <START OF HEADING> (Control) ÷ [0.3] ÷ 0D4E × 0308 ÷ 0001 ÷ # ÷ [0.2] MALAYALAM LETTER DOT REPH (Prepend_ConjunctLinkingScripts) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] <START OF HEADING> (Control) ÷ [0.3] -÷ 0D4E × 034F ÷ # ÷ [0.2] MALAYALAM LETTER DOT REPH (Prepend_ConjunctLinkingScripts) × [9.0] COMBINING GRAPHEME JOINER (Extend) ÷ [0.3] -÷ 0D4E × 0308 × 034F ÷ # ÷ [0.2] MALAYALAM LETTER DOT REPH (Prepend_ConjunctLinkingScripts) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] COMBINING GRAPHEME JOINER (Extend) ÷ [0.3] +÷ 0D4E × 200C ÷ # ÷ [0.2] MALAYALAM LETTER DOT REPH (Prepend_ConjunctLinkingScripts) × [9.0] ZERO WIDTH NON-JOINER (Extend) ÷ [0.3] +÷ 0D4E × 0308 × 200C ÷ # ÷ [0.2] MALAYALAM LETTER DOT REPH (Prepend_ConjunctLinkingScripts) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] ZERO WIDTH NON-JOINER (Extend) ÷ [0.3] ÷ 0D4E × 1F1E6 ÷ # ÷ [0.2] MALAYALAM LETTER DOT REPH (Prepend_ConjunctLinkingScripts) × [9.2] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3] ÷ 0D4E × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] MALAYALAM LETTER DOT REPH (Prepend_ConjunctLinkingScripts) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3] ÷ 0D4E × 0600 ÷ # ÷ [0.2] MALAYALAM LETTER DOT REPH (Prepend_ConjunctLinkingScripts) × [9.2] ARABIC NUMBER SIGN (Prepend) ÷ [0.3] @@ -816,8 +738,6 @@ ÷ 0D4E × 0308 ÷ AC00 ÷ # ÷ [0.2] MALAYALAM LETTER DOT REPH (Prepend_ConjunctLinkingScripts) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL SYLLABLE GA (LV) ÷ [0.3] ÷ 0D4E × AC01 ÷ # ÷ [0.2] MALAYALAM LETTER DOT REPH (Prepend_ConjunctLinkingScripts) × [9.2] HANGUL SYLLABLE GAG (LVT) ÷ [0.3] ÷ 0D4E × 0308 ÷ AC01 ÷ # ÷ [0.2] MALAYALAM LETTER DOT REPH (Prepend_ConjunctLinkingScripts) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3] -÷ 0D4E × 0900 ÷ # ÷ [0.2] MALAYALAM LETTER DOT REPH (Prepend_ConjunctLinkingScripts) × [9.0] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts) ÷ [0.3] -÷ 0D4E × 0308 × 0900 ÷ # ÷ [0.2] MALAYALAM LETTER DOT REPH (Prepend_ConjunctLinkingScripts) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts) ÷ [0.3] ÷ 0D4E × 0903 ÷ # ÷ [0.2] MALAYALAM LETTER DOT REPH (Prepend_ConjunctLinkingScripts) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark_ConjunctLinkingScripts) ÷ [0.3] ÷ 0D4E × 0308 × 0903 ÷ # ÷ [0.2] MALAYALAM LETTER DOT REPH (Prepend_ConjunctLinkingScripts) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark_ConjunctLinkingScripts) ÷ [0.3] ÷ 0D4E × 0904 ÷ # ÷ [0.2] MALAYALAM LETTER DOT REPH (Prepend_ConjunctLinkingScripts) × [9.2] DEVANAGARI LETTER SHORT A (ConjunctLinkingScripts) ÷ [0.3] @@ -830,8 +750,8 @@ ÷ 0D4E × 0308 ÷ 231A ÷ # ÷ [0.2] MALAYALAM LETTER DOT REPH (Prepend_ConjunctLinkingScripts) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] WATCH (ExtPict) ÷ [0.3] ÷ 0D4E × 0300 ÷ # ÷ [0.2] MALAYALAM LETTER DOT REPH (Prepend_ConjunctLinkingScripts) × [9.0] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [0.3] ÷ 0D4E × 0308 × 0300 ÷ # ÷ [0.2] MALAYALAM LETTER DOT REPH (Prepend_ConjunctLinkingScripts) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [0.3] -÷ 0D4E × 093C ÷ # ÷ [0.2] MALAYALAM LETTER DOT REPH (Prepend_ConjunctLinkingScripts) × [9.0] DEVANAGARI SIGN NUKTA (Extend_ConjunctLinkingScripts_ExtCccZwj) ÷ [0.3] -÷ 0D4E × 0308 × 093C ÷ # ÷ [0.2] MALAYALAM LETTER DOT REPH (Prepend_ConjunctLinkingScripts) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] DEVANAGARI SIGN NUKTA (Extend_ConjunctLinkingScripts_ExtCccZwj) ÷ [0.3] +÷ 0D4E × 0900 ÷ # ÷ [0.2] MALAYALAM LETTER DOT REPH (Prepend_ConjunctLinkingScripts) × [9.0] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts_ExtCccZwj) ÷ [0.3] +÷ 0D4E × 0308 × 0900 ÷ # ÷ [0.2] MALAYALAM LETTER DOT REPH (Prepend_ConjunctLinkingScripts) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts_ExtCccZwj) ÷ [0.3] ÷ 0D4E × 094D ÷ # ÷ [0.2] MALAYALAM LETTER DOT REPH (Prepend_ConjunctLinkingScripts) × [9.0] DEVANAGARI SIGN VIRAMA (Extend_ConjunctLinkingScripts_ConjunctLinker_ExtCccZwj) ÷ [0.3] ÷ 0D4E × 0308 × 094D ÷ # ÷ [0.2] MALAYALAM LETTER DOT REPH (Prepend_ConjunctLinkingScripts) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] DEVANAGARI SIGN VIRAMA (Extend_ConjunctLinkingScripts_ConjunctLinker_ExtCccZwj) ÷ [0.3] ÷ 0D4E × 200D ÷ # ÷ [0.2] MALAYALAM LETTER DOT REPH (Prepend_ConjunctLinkingScripts) × [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [0.3] @@ -846,8 +766,8 @@ ÷ 0915 × 0308 ÷ 000A ÷ # ÷ [0.2] DEVANAGARI LETTER KA (ConjunctLinkingScripts_LinkingConsonant) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] <LINE FEED (LF)> (LF) ÷ [0.3] ÷ 0915 ÷ 0001 ÷ # ÷ [0.2] DEVANAGARI LETTER KA (ConjunctLinkingScripts_LinkingConsonant) ÷ [5.0] <START OF HEADING> (Control) ÷ [0.3] ÷ 0915 × 0308 ÷ 0001 ÷ # ÷ [0.2] DEVANAGARI LETTER KA (ConjunctLinkingScripts_LinkingConsonant) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] <START OF HEADING> (Control) ÷ [0.3] -÷ 0915 × 034F ÷ # ÷ [0.2] DEVANAGARI LETTER KA (ConjunctLinkingScripts_LinkingConsonant) × [9.0] COMBINING GRAPHEME JOINER (Extend) ÷ [0.3] -÷ 0915 × 0308 × 034F ÷ # ÷ [0.2] DEVANAGARI LETTER KA (ConjunctLinkingScripts_LinkingConsonant) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] COMBINING GRAPHEME JOINER (Extend) ÷ [0.3] +÷ 0915 × 200C ÷ # ÷ [0.2] DEVANAGARI LETTER KA (ConjunctLinkingScripts_LinkingConsonant) × [9.0] ZERO WIDTH NON-JOINER (Extend) ÷ [0.3] +÷ 0915 × 0308 × 200C ÷ # ÷ [0.2] DEVANAGARI LETTER KA (ConjunctLinkingScripts_LinkingConsonant) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] ZERO WIDTH NON-JOINER (Extend) ÷ [0.3] ÷ 0915 ÷ 1F1E6 ÷ # ÷ [0.2] DEVANAGARI LETTER KA (ConjunctLinkingScripts_LinkingConsonant) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3] ÷ 0915 × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] DEVANAGARI LETTER KA (ConjunctLinkingScripts_LinkingConsonant) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3] ÷ 0915 ÷ 0600 ÷ # ÷ [0.2] DEVANAGARI LETTER KA (ConjunctLinkingScripts_LinkingConsonant) ÷ [999.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3] @@ -864,8 +784,6 @@ ÷ 0915 × 0308 ÷ AC00 ÷ # ÷ [0.2] DEVANAGARI LETTER KA (ConjunctLinkingScripts_LinkingConsonant) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL SYLLABLE GA (LV) ÷ [0.3] ÷ 0915 ÷ AC01 ÷ # ÷ [0.2] DEVANAGARI LETTER KA (ConjunctLinkingScripts_LinkingConsonant) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3] ÷ 0915 × 0308 ÷ AC01 ÷ # ÷ [0.2] DEVANAGARI LETTER KA (ConjunctLinkingScripts_LinkingConsonant) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3] -÷ 0915 × 0900 ÷ # ÷ [0.2] DEVANAGARI LETTER KA (ConjunctLinkingScripts_LinkingConsonant) × [9.0] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts) ÷ [0.3] -÷ 0915 × 0308 × 0900 ÷ # ÷ [0.2] DEVANAGARI LETTER KA (ConjunctLinkingScripts_LinkingConsonant) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts) ÷ [0.3] ÷ 0915 × 0903 ÷ # ÷ [0.2] DEVANAGARI LETTER KA (ConjunctLinkingScripts_LinkingConsonant) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark_ConjunctLinkingScripts) ÷ [0.3] ÷ 0915 × 0308 × 0903 ÷ # ÷ [0.2] DEVANAGARI LETTER KA (ConjunctLinkingScripts_LinkingConsonant) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark_ConjunctLinkingScripts) ÷ [0.3] ÷ 0915 ÷ 0904 ÷ # ÷ [0.2] DEVANAGARI LETTER KA (ConjunctLinkingScripts_LinkingConsonant) ÷ [999.0] DEVANAGARI LETTER SHORT A (ConjunctLinkingScripts) ÷ [0.3] @@ -878,8 +796,8 @@ ÷ 0915 × 0308 ÷ 231A ÷ # ÷ [0.2] DEVANAGARI LETTER KA (ConjunctLinkingScripts_LinkingConsonant) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] WATCH (ExtPict) ÷ [0.3] ÷ 0915 × 0300 ÷ # ÷ [0.2] DEVANAGARI LETTER KA (ConjunctLinkingScripts_LinkingConsonant) × [9.0] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [0.3] ÷ 0915 × 0308 × 0300 ÷ # ÷ [0.2] DEVANAGARI LETTER KA (ConjunctLinkingScripts_LinkingConsonant) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [0.3] -÷ 0915 × 093C ÷ # ÷ [0.2] DEVANAGARI LETTER KA (ConjunctLinkingScripts_LinkingConsonant) × [9.0] DEVANAGARI SIGN NUKTA (Extend_ConjunctLinkingScripts_ExtCccZwj) ÷ [0.3] -÷ 0915 × 0308 × 093C ÷ # ÷ [0.2] DEVANAGARI LETTER KA (ConjunctLinkingScripts_LinkingConsonant) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] DEVANAGARI SIGN NUKTA (Extend_ConjunctLinkingScripts_ExtCccZwj) ÷ [0.3] +÷ 0915 × 0900 ÷ # ÷ [0.2] DEVANAGARI LETTER KA (ConjunctLinkingScripts_LinkingConsonant) × [9.0] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts_ExtCccZwj) ÷ [0.3] +÷ 0915 × 0308 × 0900 ÷ # ÷ [0.2] DEVANAGARI LETTER KA (ConjunctLinkingScripts_LinkingConsonant) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts_ExtCccZwj) ÷ [0.3] ÷ 0915 × 094D ÷ # ÷ [0.2] DEVANAGARI LETTER KA (ConjunctLinkingScripts_LinkingConsonant) × [9.0] DEVANAGARI SIGN VIRAMA (Extend_ConjunctLinkingScripts_ConjunctLinker_ExtCccZwj) ÷ [0.3] ÷ 0915 × 0308 × 094D ÷ # ÷ [0.2] DEVANAGARI LETTER KA (ConjunctLinkingScripts_LinkingConsonant) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] DEVANAGARI SIGN VIRAMA (Extend_ConjunctLinkingScripts_ConjunctLinker_ExtCccZwj) ÷ [0.3] ÷ 0915 × 200D ÷ # ÷ [0.2] DEVANAGARI LETTER KA (ConjunctLinkingScripts_LinkingConsonant) × [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [0.3] @@ -894,8 +812,8 @@ ÷ 231A × 0308 ÷ 000A ÷ # ÷ [0.2] WATCH (ExtPict) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] <LINE FEED (LF)> (LF) ÷ [0.3] ÷ 231A ÷ 0001 ÷ # ÷ [0.2] WATCH (ExtPict) ÷ [5.0] <START OF HEADING> (Control) ÷ [0.3] ÷ 231A × 0308 ÷ 0001 ÷ # ÷ [0.2] WATCH (ExtPict) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] <START OF HEADING> (Control) ÷ [0.3] -÷ 231A × 034F ÷ # ÷ [0.2] WATCH (ExtPict) × [9.0] COMBINING GRAPHEME JOINER (Extend) ÷ [0.3] -÷ 231A × 0308 × 034F ÷ # ÷ [0.2] WATCH (ExtPict) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] COMBINING GRAPHEME JOINER (Extend) ÷ [0.3] +÷ 231A × 200C ÷ # ÷ [0.2] WATCH (ExtPict) × [9.0] ZERO WIDTH NON-JOINER (Extend) ÷ [0.3] +÷ 231A × 0308 × 200C ÷ # ÷ [0.2] WATCH (ExtPict) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] ZERO WIDTH NON-JOINER (Extend) ÷ [0.3] ÷ 231A ÷ 1F1E6 ÷ # ÷ [0.2] WATCH (ExtPict) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3] ÷ 231A × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] WATCH (ExtPict) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3] ÷ 231A ÷ 0600 ÷ # ÷ [0.2] WATCH (ExtPict) ÷ [999.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3] @@ -912,8 +830,6 @@ ÷ 231A × 0308 ÷ AC00 ÷ # ÷ [0.2] WATCH (ExtPict) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL SYLLABLE GA (LV) ÷ [0.3] ÷ 231A ÷ AC01 ÷ # ÷ [0.2] WATCH (ExtPict) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3] ÷ 231A × 0308 ÷ AC01 ÷ # ÷ [0.2] WATCH (ExtPict) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3] -÷ 231A × 0900 ÷ # ÷ [0.2] WATCH (ExtPict) × [9.0] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts) ÷ [0.3] -÷ 231A × 0308 × 0900 ÷ # ÷ [0.2] WATCH (ExtPict) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts) ÷ [0.3] ÷ 231A × 0903 ÷ # ÷ [0.2] WATCH (ExtPict) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark_ConjunctLinkingScripts) ÷ [0.3] ÷ 231A × 0308 × 0903 ÷ # ÷ [0.2] WATCH (ExtPict) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark_ConjunctLinkingScripts) ÷ [0.3] ÷ 231A ÷ 0904 ÷ # ÷ [0.2] WATCH (ExtPict) ÷ [999.0] DEVANAGARI LETTER SHORT A (ConjunctLinkingScripts) ÷ [0.3] @@ -926,8 +842,8 @@ ÷ 231A × 0308 ÷ 231A ÷ # ÷ [0.2] WATCH (ExtPict) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] WATCH (ExtPict) ÷ [0.3] ÷ 231A × 0300 ÷ # ÷ [0.2] WATCH (ExtPict) × [9.0] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [0.3] ÷ 231A × 0308 × 0300 ÷ # ÷ [0.2] WATCH (ExtPict) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [0.3] -÷ 231A × 093C ÷ # ÷ [0.2] WATCH (ExtPict) × [9.0] DEVANAGARI SIGN NUKTA (Extend_ConjunctLinkingScripts_ExtCccZwj) ÷ [0.3] -÷ 231A × 0308 × 093C ÷ # ÷ [0.2] WATCH (ExtPict) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] DEVANAGARI SIGN NUKTA (Extend_ConjunctLinkingScripts_ExtCccZwj) ÷ [0.3] +÷ 231A × 0900 ÷ # ÷ [0.2] WATCH (ExtPict) × [9.0] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts_ExtCccZwj) ÷ [0.3] +÷ 231A × 0308 × 0900 ÷ # ÷ [0.2] WATCH (ExtPict) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts_ExtCccZwj) ÷ [0.3] ÷ 231A × 094D ÷ # ÷ [0.2] WATCH (ExtPict) × [9.0] DEVANAGARI SIGN VIRAMA (Extend_ConjunctLinkingScripts_ConjunctLinker_ExtCccZwj) ÷ [0.3] ÷ 231A × 0308 × 094D ÷ # ÷ [0.2] WATCH (ExtPict) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] DEVANAGARI SIGN VIRAMA (Extend_ConjunctLinkingScripts_ConjunctLinker_ExtCccZwj) ÷ [0.3] ÷ 231A × 200D ÷ # ÷ [0.2] WATCH (ExtPict) × [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [0.3] @@ -942,8 +858,8 @@ ÷ 0300 × 0308 ÷ 000A ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] <LINE FEED (LF)> (LF) ÷ [0.3] ÷ 0300 ÷ 0001 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [5.0] <START OF HEADING> (Control) ÷ [0.3] ÷ 0300 × 0308 ÷ 0001 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] <START OF HEADING> (Control) ÷ [0.3] -÷ 0300 × 034F ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) × [9.0] COMBINING GRAPHEME JOINER (Extend) ÷ [0.3] -÷ 0300 × 0308 × 034F ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] COMBINING GRAPHEME JOINER (Extend) ÷ [0.3] +÷ 0300 × 200C ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) × [9.0] ZERO WIDTH NON-JOINER (Extend) ÷ [0.3] +÷ 0300 × 0308 × 200C ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] ZERO WIDTH NON-JOINER (Extend) ÷ [0.3] ÷ 0300 ÷ 1F1E6 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3] ÷ 0300 × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3] ÷ 0300 ÷ 0600 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [999.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3] @@ -960,8 +876,6 @@ ÷ 0300 × 0308 ÷ AC00 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL SYLLABLE GA (LV) ÷ [0.3] ÷ 0300 ÷ AC01 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3] ÷ 0300 × 0308 ÷ AC01 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3] -÷ 0300 × 0900 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) × [9.0] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts) ÷ [0.3] -÷ 0300 × 0308 × 0900 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts) ÷ [0.3] ÷ 0300 × 0903 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark_ConjunctLinkingScripts) ÷ [0.3] ÷ 0300 × 0308 × 0903 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark_ConjunctLinkingScripts) ÷ [0.3] ÷ 0300 ÷ 0904 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [999.0] DEVANAGARI LETTER SHORT A (ConjunctLinkingScripts) ÷ [0.3] @@ -974,62 +888,60 @@ ÷ 0300 × 0308 ÷ 231A ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] WATCH (ExtPict) ÷ [0.3] ÷ 0300 × 0300 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) × [9.0] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [0.3] ÷ 0300 × 0308 × 0300 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [0.3] -÷ 0300 × 093C ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) × [9.0] DEVANAGARI SIGN NUKTA (Extend_ConjunctLinkingScripts_ExtCccZwj) ÷ [0.3] -÷ 0300 × 0308 × 093C ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] DEVANAGARI SIGN NUKTA (Extend_ConjunctLinkingScripts_ExtCccZwj) ÷ [0.3] +÷ 0300 × 0900 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) × [9.0] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts_ExtCccZwj) ÷ [0.3] +÷ 0300 × 0308 × 0900 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts_ExtCccZwj) ÷ [0.3] ÷ 0300 × 094D ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) × [9.0] DEVANAGARI SIGN VIRAMA (Extend_ConjunctLinkingScripts_ConjunctLinker_ExtCccZwj) ÷ [0.3] ÷ 0300 × 0308 × 094D ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] DEVANAGARI SIGN VIRAMA (Extend_ConjunctLinkingScripts_ConjunctLinker_ExtCccZwj) ÷ [0.3] ÷ 0300 × 200D ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) × [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [0.3] ÷ 0300 × 0308 × 200D ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [0.3] ÷ 0300 ÷ 0378 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [999.0] <reserved-0378> (Other) ÷ [0.3] ÷ 0300 × 0308 ÷ 0378 ÷ # ÷ [0.2] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] <reserved-0378> (Other) ÷ [0.3] -÷ 093C ÷ 0020 ÷ # ÷ [0.2] DEVANAGARI SIGN NUKTA (Extend_ConjunctLinkingScripts_ExtCccZwj) ÷ [999.0] SPACE (Other) ÷ [0.3] -÷ 093C × 0308 ÷ 0020 ÷ # ÷ [0.2] DEVANAGARI SIGN NUKTA (Extend_ConjunctLinkingScripts_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] SPACE (Other) ÷ [0.3] -÷ 093C ÷ 000D ÷ # ÷ [0.2] DEVANAGARI SIGN NUKTA (Extend_ConjunctLinkingScripts_ExtCccZwj) ÷ [5.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3] -÷ 093C × 0308 ÷ 000D ÷ # ÷ [0.2] DEVANAGARI SIGN NUKTA (Extend_ConjunctLinkingScripts_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3] -÷ 093C ÷ 000A ÷ # ÷ [0.2] DEVANAGARI SIGN NUKTA (Extend_ConjunctLinkingScripts_ExtCccZwj) ÷ [5.0] <LINE FEED (LF)> (LF) ÷ [0.3] -÷ 093C × 0308 ÷ 000A ÷ # ÷ [0.2] DEVANAGARI SIGN NUKTA (Extend_ConjunctLinkingScripts_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] <LINE FEED (LF)> (LF) ÷ [0.3] -÷ 093C ÷ 0001 ÷ # ÷ [0.2] DEVANAGARI SIGN NUKTA (Extend_ConjunctLinkingScripts_ExtCccZwj) ÷ [5.0] <START OF HEADING> (Control) ÷ [0.3] -÷ 093C × 0308 ÷ 0001 ÷ # ÷ [0.2] DEVANAGARI SIGN NUKTA (Extend_ConjunctLinkingScripts_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] <START OF HEADING> (Control) ÷ [0.3] -÷ 093C × 034F ÷ # ÷ [0.2] DEVANAGARI SIGN NUKTA (Extend_ConjunctLinkingScripts_ExtCccZwj) × [9.0] COMBINING GRAPHEME JOINER (Extend) ÷ [0.3] -÷ 093C × 0308 × 034F ÷ # ÷ [0.2] DEVANAGARI SIGN NUKTA (Extend_ConjunctLinkingScripts_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] COMBINING GRAPHEME JOINER (Extend) ÷ [0.3] -÷ 093C ÷ 1F1E6 ÷ # ÷ [0.2] DEVANAGARI SIGN NUKTA (Extend_ConjunctLinkingScripts_ExtCccZwj) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3] -÷ 093C × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] DEVANAGARI SIGN NUKTA (Extend_ConjunctLinkingScripts_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3] -÷ 093C ÷ 0600 ÷ # ÷ [0.2] DEVANAGARI SIGN NUKTA (Extend_ConjunctLinkingScripts_ExtCccZwj) ÷ [999.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3] -÷ 093C × 0308 ÷ 0600 ÷ # ÷ [0.2] DEVANAGARI SIGN NUKTA (Extend_ConjunctLinkingScripts_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3] -÷ 093C × 0A03 ÷ # ÷ [0.2] DEVANAGARI SIGN NUKTA (Extend_ConjunctLinkingScripts_ExtCccZwj) × [9.1] GURMUKHI SIGN VISARGA (SpacingMark) ÷ [0.3] -÷ 093C × 0308 × 0A03 ÷ # ÷ [0.2] DEVANAGARI SIGN NUKTA (Extend_ConjunctLinkingScripts_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.1] GURMUKHI SIGN VISARGA (SpacingMark) ÷ [0.3] -÷ 093C ÷ 1100 ÷ # ÷ [0.2] DEVANAGARI SIGN NUKTA (Extend_ConjunctLinkingScripts_ExtCccZwj) ÷ [999.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3] -÷ 093C × 0308 ÷ 1100 ÷ # ÷ [0.2] DEVANAGARI SIGN NUKTA (Extend_ConjunctLinkingScripts_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3] -÷ 093C ÷ 1160 ÷ # ÷ [0.2] DEVANAGARI SIGN NUKTA (Extend_ConjunctLinkingScripts_ExtCccZwj) ÷ [999.0] HANGUL JUNGSEONG FILLER (V) ÷ [0.3] -÷ 093C × 0308 ÷ 1160 ÷ # ÷ [0.2] DEVANAGARI SIGN NUKTA (Extend_ConjunctLinkingScripts_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL JUNGSEONG FILLER (V) ÷ [0.3] -÷ 093C ÷ 11A8 ÷ # ÷ [0.2] DEVANAGARI SIGN NUKTA (Extend_ConjunctLinkingScripts_ExtCccZwj) ÷ [999.0] HANGUL JONGSEONG KIYEOK (T) ÷ [0.3] -÷ 093C × 0308 ÷ 11A8 ÷ # ÷ [0.2] DEVANAGARI SIGN NUKTA (Extend_ConjunctLinkingScripts_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL JONGSEONG KIYEOK (T) ÷ [0.3] -÷ 093C ÷ AC00 ÷ # ÷ [0.2] DEVANAGARI SIGN NUKTA (Extend_ConjunctLinkingScripts_ExtCccZwj) ÷ [999.0] HANGUL SYLLABLE GA (LV) ÷ [0.3] -÷ 093C × 0308 ÷ AC00 ÷ # ÷ [0.2] DEVANAGARI SIGN NUKTA (Extend_ConjunctLinkingScripts_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL SYLLABLE GA (LV) ÷ [0.3] -÷ 093C ÷ AC01 ÷ # ÷ [0.2] DEVANAGARI SIGN NUKTA (Extend_ConjunctLinkingScripts_ExtCccZwj) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3] -÷ 093C × 0308 ÷ AC01 ÷ # ÷ [0.2] DEVANAGARI SIGN NUKTA (Extend_ConjunctLinkingScripts_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3] -÷ 093C × 0900 ÷ # ÷ [0.2] DEVANAGARI SIGN NUKTA (Extend_ConjunctLinkingScripts_ExtCccZwj) × [9.0] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts) ÷ [0.3] -÷ 093C × 0308 × 0900 ÷ # ÷ [0.2] DEVANAGARI SIGN NUKTA (Extend_ConjunctLinkingScripts_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts) ÷ [0.3] -÷ 093C × 0903 ÷ # ÷ [0.2] DEVANAGARI SIGN NUKTA (Extend_ConjunctLinkingScripts_ExtCccZwj) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark_ConjunctLinkingScripts) ÷ [0.3] -÷ 093C × 0308 × 0903 ÷ # ÷ [0.2] DEVANAGARI SIGN NUKTA (Extend_ConjunctLinkingScripts_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark_ConjunctLinkingScripts) ÷ [0.3] -÷ 093C ÷ 0904 ÷ # ÷ [0.2] DEVANAGARI SIGN NUKTA (Extend_ConjunctLinkingScripts_ExtCccZwj) ÷ [999.0] DEVANAGARI LETTER SHORT A (ConjunctLinkingScripts) ÷ [0.3] -÷ 093C × 0308 ÷ 0904 ÷ # ÷ [0.2] DEVANAGARI SIGN NUKTA (Extend_ConjunctLinkingScripts_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] DEVANAGARI LETTER SHORT A (ConjunctLinkingScripts) ÷ [0.3] -÷ 093C ÷ 0D4E ÷ # ÷ [0.2] DEVANAGARI SIGN NUKTA (Extend_ConjunctLinkingScripts_ExtCccZwj) ÷ [999.0] MALAYALAM LETTER DOT REPH (Prepend_ConjunctLinkingScripts) ÷ [0.3] -÷ 093C × 0308 ÷ 0D4E ÷ # ÷ [0.2] DEVANAGARI SIGN NUKTA (Extend_ConjunctLinkingScripts_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] MALAYALAM LETTER DOT REPH (Prepend_ConjunctLinkingScripts) ÷ [0.3] -÷ 093C ÷ 0915 ÷ # ÷ [0.2] DEVANAGARI SIGN NUKTA (Extend_ConjunctLinkingScripts_ExtCccZwj) ÷ [999.0] DEVANAGARI LETTER KA (ConjunctLinkingScripts_LinkingConsonant) ÷ [0.3] -÷ 093C × 0308 ÷ 0915 ÷ # ÷ [0.2] DEVANAGARI SIGN NUKTA (Extend_ConjunctLinkingScripts_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] DEVANAGARI LETTER KA (ConjunctLinkingScripts_LinkingConsonant) ÷ [0.3] -÷ 093C ÷ 231A ÷ # ÷ [0.2] DEVANAGARI SIGN NUKTA (Extend_ConjunctLinkingScripts_ExtCccZwj) ÷ [999.0] WATCH (ExtPict) ÷ [0.3] -÷ 093C × 0308 ÷ 231A ÷ # ÷ [0.2] DEVANAGARI SIGN NUKTA (Extend_ConjunctLinkingScripts_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] WATCH (ExtPict) ÷ [0.3] -÷ 093C × 0300 ÷ # ÷ [0.2] DEVANAGARI SIGN NUKTA (Extend_ConjunctLinkingScripts_ExtCccZwj) × [9.0] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [0.3] -÷ 093C × 0308 × 0300 ÷ # ÷ [0.2] DEVANAGARI SIGN NUKTA (Extend_ConjunctLinkingScripts_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [0.3] -÷ 093C × 093C ÷ # ÷ [0.2] DEVANAGARI SIGN NUKTA (Extend_ConjunctLinkingScripts_ExtCccZwj) × [9.0] DEVANAGARI SIGN NUKTA (Extend_ConjunctLinkingScripts_ExtCccZwj) ÷ [0.3] -÷ 093C × 0308 × 093C ÷ # ÷ [0.2] DEVANAGARI SIGN NUKTA (Extend_ConjunctLinkingScripts_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] DEVANAGARI SIGN NUKTA (Extend_ConjunctLinkingScripts_ExtCccZwj) ÷ [0.3] -÷ 093C × 094D ÷ # ÷ [0.2] DEVANAGARI SIGN NUKTA (Extend_ConjunctLinkingScripts_ExtCccZwj) × [9.0] DEVANAGARI SIGN VIRAMA (Extend_ConjunctLinkingScripts_ConjunctLinker_ExtCccZwj) ÷ [0.3] -÷ 093C × 0308 × 094D ÷ # ÷ [0.2] DEVANAGARI SIGN NUKTA (Extend_ConjunctLinkingScripts_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] DEVANAGARI SIGN VIRAMA (Extend_ConjunctLinkingScripts_ConjunctLinker_ExtCccZwj) ÷ [0.3] -÷ 093C × 200D ÷ # ÷ [0.2] DEVANAGARI SIGN NUKTA (Extend_ConjunctLinkingScripts_ExtCccZwj) × [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [0.3] -÷ 093C × 0308 × 200D ÷ # ÷ [0.2] DEVANAGARI SIGN NUKTA (Extend_ConjunctLinkingScripts_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [0.3] -÷ 093C ÷ 0378 ÷ # ÷ [0.2] DEVANAGARI SIGN NUKTA (Extend_ConjunctLinkingScripts_ExtCccZwj) ÷ [999.0] <reserved-0378> (Other) ÷ [0.3] -÷ 093C × 0308 ÷ 0378 ÷ # ÷ [0.2] DEVANAGARI SIGN NUKTA (Extend_ConjunctLinkingScripts_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] <reserved-0378> (Other) ÷ [0.3] +÷ 0900 ÷ 0020 ÷ # ÷ [0.2] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts_ExtCccZwj) ÷ [999.0] SPACE (Other) ÷ [0.3] +÷ 0900 × 0308 ÷ 0020 ÷ # ÷ [0.2] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] SPACE (Other) ÷ [0.3] +÷ 0900 ÷ 000D ÷ # ÷ [0.2] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts_ExtCccZwj) ÷ [5.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3] +÷ 0900 × 0308 ÷ 000D ÷ # ÷ [0.2] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3] +÷ 0900 ÷ 000A ÷ # ÷ [0.2] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts_ExtCccZwj) ÷ [5.0] <LINE FEED (LF)> (LF) ÷ [0.3] +÷ 0900 × 0308 ÷ 000A ÷ # ÷ [0.2] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] <LINE FEED (LF)> (LF) ÷ [0.3] +÷ 0900 ÷ 0001 ÷ # ÷ [0.2] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts_ExtCccZwj) ÷ [5.0] <START OF HEADING> (Control) ÷ [0.3] +÷ 0900 × 0308 ÷ 0001 ÷ # ÷ [0.2] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] <START OF HEADING> (Control) ÷ [0.3] +÷ 0900 × 200C ÷ # ÷ [0.2] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts_ExtCccZwj) × [9.0] ZERO WIDTH NON-JOINER (Extend) ÷ [0.3] +÷ 0900 × 0308 × 200C ÷ # ÷ [0.2] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] ZERO WIDTH NON-JOINER (Extend) ÷ [0.3] +÷ 0900 ÷ 1F1E6 ÷ # ÷ [0.2] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts_ExtCccZwj) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3] +÷ 0900 × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3] +÷ 0900 ÷ 0600 ÷ # ÷ [0.2] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts_ExtCccZwj) ÷ [999.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3] +÷ 0900 × 0308 ÷ 0600 ÷ # ÷ [0.2] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3] +÷ 0900 × 0A03 ÷ # ÷ [0.2] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts_ExtCccZwj) × [9.1] GURMUKHI SIGN VISARGA (SpacingMark) ÷ [0.3] +÷ 0900 × 0308 × 0A03 ÷ # ÷ [0.2] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.1] GURMUKHI SIGN VISARGA (SpacingMark) ÷ [0.3] +÷ 0900 ÷ 1100 ÷ # ÷ [0.2] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts_ExtCccZwj) ÷ [999.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3] +÷ 0900 × 0308 ÷ 1100 ÷ # ÷ [0.2] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL CHOSEONG KIYEOK (L) ÷ [0.3] +÷ 0900 ÷ 1160 ÷ # ÷ [0.2] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts_ExtCccZwj) ÷ [999.0] HANGUL JUNGSEONG FILLER (V) ÷ [0.3] +÷ 0900 × 0308 ÷ 1160 ÷ # ÷ [0.2] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL JUNGSEONG FILLER (V) ÷ [0.3] +÷ 0900 ÷ 11A8 ÷ # ÷ [0.2] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts_ExtCccZwj) ÷ [999.0] HANGUL JONGSEONG KIYEOK (T) ÷ [0.3] +÷ 0900 × 0308 ÷ 11A8 ÷ # ÷ [0.2] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL JONGSEONG KIYEOK (T) ÷ [0.3] +÷ 0900 ÷ AC00 ÷ # ÷ [0.2] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts_ExtCccZwj) ÷ [999.0] HANGUL SYLLABLE GA (LV) ÷ [0.3] +÷ 0900 × 0308 ÷ AC00 ÷ # ÷ [0.2] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL SYLLABLE GA (LV) ÷ [0.3] +÷ 0900 ÷ AC01 ÷ # ÷ [0.2] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts_ExtCccZwj) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3] +÷ 0900 × 0308 ÷ AC01 ÷ # ÷ [0.2] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3] +÷ 0900 × 0903 ÷ # ÷ [0.2] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts_ExtCccZwj) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark_ConjunctLinkingScripts) ÷ [0.3] +÷ 0900 × 0308 × 0903 ÷ # ÷ [0.2] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark_ConjunctLinkingScripts) ÷ [0.3] +÷ 0900 ÷ 0904 ÷ # ÷ [0.2] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts_ExtCccZwj) ÷ [999.0] DEVANAGARI LETTER SHORT A (ConjunctLinkingScripts) ÷ [0.3] +÷ 0900 × 0308 ÷ 0904 ÷ # ÷ [0.2] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] DEVANAGARI LETTER SHORT A (ConjunctLinkingScripts) ÷ [0.3] +÷ 0900 ÷ 0D4E ÷ # ÷ [0.2] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts_ExtCccZwj) ÷ [999.0] MALAYALAM LETTER DOT REPH (Prepend_ConjunctLinkingScripts) ÷ [0.3] +÷ 0900 × 0308 ÷ 0D4E ÷ # ÷ [0.2] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] MALAYALAM LETTER DOT REPH (Prepend_ConjunctLinkingScripts) ÷ [0.3] +÷ 0900 ÷ 0915 ÷ # ÷ [0.2] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts_ExtCccZwj) ÷ [999.0] DEVANAGARI LETTER KA (ConjunctLinkingScripts_LinkingConsonant) ÷ [0.3] +÷ 0900 × 0308 ÷ 0915 ÷ # ÷ [0.2] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] DEVANAGARI LETTER KA (ConjunctLinkingScripts_LinkingConsonant) ÷ [0.3] +÷ 0900 ÷ 231A ÷ # ÷ [0.2] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts_ExtCccZwj) ÷ [999.0] WATCH (ExtPict) ÷ [0.3] +÷ 0900 × 0308 ÷ 231A ÷ # ÷ [0.2] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] WATCH (ExtPict) ÷ [0.3] +÷ 0900 × 0300 ÷ # ÷ [0.2] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts_ExtCccZwj) × [9.0] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [0.3] +÷ 0900 × 0308 × 0300 ÷ # ÷ [0.2] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [0.3] +÷ 0900 × 0900 ÷ # ÷ [0.2] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts_ExtCccZwj) × [9.0] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts_ExtCccZwj) ÷ [0.3] +÷ 0900 × 0308 × 0900 ÷ # ÷ [0.2] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts_ExtCccZwj) ÷ [0.3] +÷ 0900 × 094D ÷ # ÷ [0.2] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts_ExtCccZwj) × [9.0] DEVANAGARI SIGN VIRAMA (Extend_ConjunctLinkingScripts_ConjunctLinker_ExtCccZwj) ÷ [0.3] +÷ 0900 × 0308 × 094D ÷ # ÷ [0.2] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] DEVANAGARI SIGN VIRAMA (Extend_ConjunctLinkingScripts_ConjunctLinker_ExtCccZwj) ÷ [0.3] +÷ 0900 × 200D ÷ # ÷ [0.2] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts_ExtCccZwj) × [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [0.3] +÷ 0900 × 0308 × 200D ÷ # ÷ [0.2] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [0.3] +÷ 0900 ÷ 0378 ÷ # ÷ [0.2] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts_ExtCccZwj) ÷ [999.0] <reserved-0378> (Other) ÷ [0.3] +÷ 0900 × 0308 ÷ 0378 ÷ # ÷ [0.2] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] <reserved-0378> (Other) ÷ [0.3] ÷ 094D ÷ 0020 ÷ # ÷ [0.2] DEVANAGARI SIGN VIRAMA (Extend_ConjunctLinkingScripts_ConjunctLinker_ExtCccZwj) ÷ [999.0] SPACE (Other) ÷ [0.3] ÷ 094D × 0308 ÷ 0020 ÷ # ÷ [0.2] DEVANAGARI SIGN VIRAMA (Extend_ConjunctLinkingScripts_ConjunctLinker_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] SPACE (Other) ÷ [0.3] ÷ 094D ÷ 000D ÷ # ÷ [0.2] DEVANAGARI SIGN VIRAMA (Extend_ConjunctLinkingScripts_ConjunctLinker_ExtCccZwj) ÷ [5.0] <CARRIAGE RETURN (CR)> (CR) ÷ [0.3] @@ -1038,8 +950,8 @@ ÷ 094D × 0308 ÷ 000A ÷ # ÷ [0.2] DEVANAGARI SIGN VIRAMA (Extend_ConjunctLinkingScripts_ConjunctLinker_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] <LINE FEED (LF)> (LF) ÷ [0.3] ÷ 094D ÷ 0001 ÷ # ÷ [0.2] DEVANAGARI SIGN VIRAMA (Extend_ConjunctLinkingScripts_ConjunctLinker_ExtCccZwj) ÷ [5.0] <START OF HEADING> (Control) ÷ [0.3] ÷ 094D × 0308 ÷ 0001 ÷ # ÷ [0.2] DEVANAGARI SIGN VIRAMA (Extend_ConjunctLinkingScripts_ConjunctLinker_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] <START OF HEADING> (Control) ÷ [0.3] -÷ 094D × 034F ÷ # ÷ [0.2] DEVANAGARI SIGN VIRAMA (Extend_ConjunctLinkingScripts_ConjunctLinker_ExtCccZwj) × [9.0] COMBINING GRAPHEME JOINER (Extend) ÷ [0.3] -÷ 094D × 0308 × 034F ÷ # ÷ [0.2] DEVANAGARI SIGN VIRAMA (Extend_ConjunctLinkingScripts_ConjunctLinker_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] COMBINING GRAPHEME JOINER (Extend) ÷ [0.3] +÷ 094D × 200C ÷ # ÷ [0.2] DEVANAGARI SIGN VIRAMA (Extend_ConjunctLinkingScripts_ConjunctLinker_ExtCccZwj) × [9.0] ZERO WIDTH NON-JOINER (Extend) ÷ [0.3] +÷ 094D × 0308 × 200C ÷ # ÷ [0.2] DEVANAGARI SIGN VIRAMA (Extend_ConjunctLinkingScripts_ConjunctLinker_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] ZERO WIDTH NON-JOINER (Extend) ÷ [0.3] ÷ 094D ÷ 1F1E6 ÷ # ÷ [0.2] DEVANAGARI SIGN VIRAMA (Extend_ConjunctLinkingScripts_ConjunctLinker_ExtCccZwj) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3] ÷ 094D × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] DEVANAGARI SIGN VIRAMA (Extend_ConjunctLinkingScripts_ConjunctLinker_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3] ÷ 094D ÷ 0600 ÷ # ÷ [0.2] DEVANAGARI SIGN VIRAMA (Extend_ConjunctLinkingScripts_ConjunctLinker_ExtCccZwj) ÷ [999.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3] @@ -1056,8 +968,6 @@ ÷ 094D × 0308 ÷ AC00 ÷ # ÷ [0.2] DEVANAGARI SIGN VIRAMA (Extend_ConjunctLinkingScripts_ConjunctLinker_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL SYLLABLE GA (LV) ÷ [0.3] ÷ 094D ÷ AC01 ÷ # ÷ [0.2] DEVANAGARI SIGN VIRAMA (Extend_ConjunctLinkingScripts_ConjunctLinker_ExtCccZwj) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3] ÷ 094D × 0308 ÷ AC01 ÷ # ÷ [0.2] DEVANAGARI SIGN VIRAMA (Extend_ConjunctLinkingScripts_ConjunctLinker_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3] -÷ 094D × 0900 ÷ # ÷ [0.2] DEVANAGARI SIGN VIRAMA (Extend_ConjunctLinkingScripts_ConjunctLinker_ExtCccZwj) × [9.0] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts) ÷ [0.3] -÷ 094D × 0308 × 0900 ÷ # ÷ [0.2] DEVANAGARI SIGN VIRAMA (Extend_ConjunctLinkingScripts_ConjunctLinker_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts) ÷ [0.3] ÷ 094D × 0903 ÷ # ÷ [0.2] DEVANAGARI SIGN VIRAMA (Extend_ConjunctLinkingScripts_ConjunctLinker_ExtCccZwj) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark_ConjunctLinkingScripts) ÷ [0.3] ÷ 094D × 0308 × 0903 ÷ # ÷ [0.2] DEVANAGARI SIGN VIRAMA (Extend_ConjunctLinkingScripts_ConjunctLinker_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark_ConjunctLinkingScripts) ÷ [0.3] ÷ 094D ÷ 0904 ÷ # ÷ [0.2] DEVANAGARI SIGN VIRAMA (Extend_ConjunctLinkingScripts_ConjunctLinker_ExtCccZwj) ÷ [999.0] DEVANAGARI LETTER SHORT A (ConjunctLinkingScripts) ÷ [0.3] @@ -1070,8 +980,8 @@ ÷ 094D × 0308 ÷ 231A ÷ # ÷ [0.2] DEVANAGARI SIGN VIRAMA (Extend_ConjunctLinkingScripts_ConjunctLinker_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] WATCH (ExtPict) ÷ [0.3] ÷ 094D × 0300 ÷ # ÷ [0.2] DEVANAGARI SIGN VIRAMA (Extend_ConjunctLinkingScripts_ConjunctLinker_ExtCccZwj) × [9.0] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [0.3] ÷ 094D × 0308 × 0300 ÷ # ÷ [0.2] DEVANAGARI SIGN VIRAMA (Extend_ConjunctLinkingScripts_ConjunctLinker_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [0.3] -÷ 094D × 093C ÷ # ÷ [0.2] DEVANAGARI SIGN VIRAMA (Extend_ConjunctLinkingScripts_ConjunctLinker_ExtCccZwj) × [9.0] DEVANAGARI SIGN NUKTA (Extend_ConjunctLinkingScripts_ExtCccZwj) ÷ [0.3] -÷ 094D × 0308 × 093C ÷ # ÷ [0.2] DEVANAGARI SIGN VIRAMA (Extend_ConjunctLinkingScripts_ConjunctLinker_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] DEVANAGARI SIGN NUKTA (Extend_ConjunctLinkingScripts_ExtCccZwj) ÷ [0.3] +÷ 094D × 0900 ÷ # ÷ [0.2] DEVANAGARI SIGN VIRAMA (Extend_ConjunctLinkingScripts_ConjunctLinker_ExtCccZwj) × [9.0] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts_ExtCccZwj) ÷ [0.3] +÷ 094D × 0308 × 0900 ÷ # ÷ [0.2] DEVANAGARI SIGN VIRAMA (Extend_ConjunctLinkingScripts_ConjunctLinker_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts_ExtCccZwj) ÷ [0.3] ÷ 094D × 094D ÷ # ÷ [0.2] DEVANAGARI SIGN VIRAMA (Extend_ConjunctLinkingScripts_ConjunctLinker_ExtCccZwj) × [9.0] DEVANAGARI SIGN VIRAMA (Extend_ConjunctLinkingScripts_ConjunctLinker_ExtCccZwj) ÷ [0.3] ÷ 094D × 0308 × 094D ÷ # ÷ [0.2] DEVANAGARI SIGN VIRAMA (Extend_ConjunctLinkingScripts_ConjunctLinker_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] DEVANAGARI SIGN VIRAMA (Extend_ConjunctLinkingScripts_ConjunctLinker_ExtCccZwj) ÷ [0.3] ÷ 094D × 200D ÷ # ÷ [0.2] DEVANAGARI SIGN VIRAMA (Extend_ConjunctLinkingScripts_ConjunctLinker_ExtCccZwj) × [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [0.3] @@ -1086,8 +996,8 @@ ÷ 200D × 0308 ÷ 000A ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] <LINE FEED (LF)> (LF) ÷ [0.3] ÷ 200D ÷ 0001 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [5.0] <START OF HEADING> (Control) ÷ [0.3] ÷ 200D × 0308 ÷ 0001 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] <START OF HEADING> (Control) ÷ [0.3] -÷ 200D × 034F ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) × [9.0] COMBINING GRAPHEME JOINER (Extend) ÷ [0.3] -÷ 200D × 0308 × 034F ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] COMBINING GRAPHEME JOINER (Extend) ÷ [0.3] +÷ 200D × 200C ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) × [9.0] ZERO WIDTH NON-JOINER (Extend) ÷ [0.3] +÷ 200D × 0308 × 200C ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] ZERO WIDTH NON-JOINER (Extend) ÷ [0.3] ÷ 200D ÷ 1F1E6 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3] ÷ 200D × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3] ÷ 200D ÷ 0600 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [999.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3] @@ -1104,8 +1014,6 @@ ÷ 200D × 0308 ÷ AC00 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL SYLLABLE GA (LV) ÷ [0.3] ÷ 200D ÷ AC01 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3] ÷ 200D × 0308 ÷ AC01 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3] -÷ 200D × 0900 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) × [9.0] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts) ÷ [0.3] -÷ 200D × 0308 × 0900 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts) ÷ [0.3] ÷ 200D × 0903 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark_ConjunctLinkingScripts) ÷ [0.3] ÷ 200D × 0308 × 0903 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark_ConjunctLinkingScripts) ÷ [0.3] ÷ 200D ÷ 0904 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [999.0] DEVANAGARI LETTER SHORT A (ConjunctLinkingScripts) ÷ [0.3] @@ -1118,8 +1026,8 @@ ÷ 200D × 0308 ÷ 231A ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] WATCH (ExtPict) ÷ [0.3] ÷ 200D × 0300 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) × [9.0] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [0.3] ÷ 200D × 0308 × 0300 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [0.3] -÷ 200D × 093C ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) × [9.0] DEVANAGARI SIGN NUKTA (Extend_ConjunctLinkingScripts_ExtCccZwj) ÷ [0.3] -÷ 200D × 0308 × 093C ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] DEVANAGARI SIGN NUKTA (Extend_ConjunctLinkingScripts_ExtCccZwj) ÷ [0.3] +÷ 200D × 0900 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) × [9.0] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts_ExtCccZwj) ÷ [0.3] +÷ 200D × 0308 × 0900 ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts_ExtCccZwj) ÷ [0.3] ÷ 200D × 094D ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) × [9.0] DEVANAGARI SIGN VIRAMA (Extend_ConjunctLinkingScripts_ConjunctLinker_ExtCccZwj) ÷ [0.3] ÷ 200D × 0308 × 094D ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] DEVANAGARI SIGN VIRAMA (Extend_ConjunctLinkingScripts_ConjunctLinker_ExtCccZwj) ÷ [0.3] ÷ 200D × 200D ÷ # ÷ [0.2] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) × [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [0.3] @@ -1134,8 +1042,8 @@ ÷ 0378 × 0308 ÷ 000A ÷ # ÷ [0.2] <reserved-0378> (Other) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] <LINE FEED (LF)> (LF) ÷ [0.3] ÷ 0378 ÷ 0001 ÷ # ÷ [0.2] <reserved-0378> (Other) ÷ [5.0] <START OF HEADING> (Control) ÷ [0.3] ÷ 0378 × 0308 ÷ 0001 ÷ # ÷ [0.2] <reserved-0378> (Other) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [5.0] <START OF HEADING> (Control) ÷ [0.3] -÷ 0378 × 034F ÷ # ÷ [0.2] <reserved-0378> (Other) × [9.0] COMBINING GRAPHEME JOINER (Extend) ÷ [0.3] -÷ 0378 × 0308 × 034F ÷ # ÷ [0.2] <reserved-0378> (Other) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] COMBINING GRAPHEME JOINER (Extend) ÷ [0.3] +÷ 0378 × 200C ÷ # ÷ [0.2] <reserved-0378> (Other) × [9.0] ZERO WIDTH NON-JOINER (Extend) ÷ [0.3] +÷ 0378 × 0308 × 200C ÷ # ÷ [0.2] <reserved-0378> (Other) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] ZERO WIDTH NON-JOINER (Extend) ÷ [0.3] ÷ 0378 ÷ 1F1E6 ÷ # ÷ [0.2] <reserved-0378> (Other) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3] ÷ 0378 × 0308 ÷ 1F1E6 ÷ # ÷ [0.2] <reserved-0378> (Other) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] REGIONAL INDICATOR SYMBOL LETTER A (RI) ÷ [0.3] ÷ 0378 ÷ 0600 ÷ # ÷ [0.2] <reserved-0378> (Other) ÷ [999.0] ARABIC NUMBER SIGN (Prepend) ÷ [0.3] @@ -1152,8 +1060,6 @@ ÷ 0378 × 0308 ÷ AC00 ÷ # ÷ [0.2] <reserved-0378> (Other) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL SYLLABLE GA (LV) ÷ [0.3] ÷ 0378 ÷ AC01 ÷ # ÷ [0.2] <reserved-0378> (Other) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3] ÷ 0378 × 0308 ÷ AC01 ÷ # ÷ [0.2] <reserved-0378> (Other) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] HANGUL SYLLABLE GAG (LVT) ÷ [0.3] -÷ 0378 × 0900 ÷ # ÷ [0.2] <reserved-0378> (Other) × [9.0] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts) ÷ [0.3] -÷ 0378 × 0308 × 0900 ÷ # ÷ [0.2] <reserved-0378> (Other) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts) ÷ [0.3] ÷ 0378 × 0903 ÷ # ÷ [0.2] <reserved-0378> (Other) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark_ConjunctLinkingScripts) ÷ [0.3] ÷ 0378 × 0308 × 0903 ÷ # ÷ [0.2] <reserved-0378> (Other) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark_ConjunctLinkingScripts) ÷ [0.3] ÷ 0378 ÷ 0904 ÷ # ÷ [0.2] <reserved-0378> (Other) ÷ [999.0] DEVANAGARI LETTER SHORT A (ConjunctLinkingScripts) ÷ [0.3] @@ -1166,8 +1072,8 @@ ÷ 0378 × 0308 ÷ 231A ÷ # ÷ [0.2] <reserved-0378> (Other) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] WATCH (ExtPict) ÷ [0.3] ÷ 0378 × 0300 ÷ # ÷ [0.2] <reserved-0378> (Other) × [9.0] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [0.3] ÷ 0378 × 0308 × 0300 ÷ # ÷ [0.2] <reserved-0378> (Other) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] COMBINING GRAVE ACCENT (Extend_ExtCccZwj) ÷ [0.3] -÷ 0378 × 093C ÷ # ÷ [0.2] <reserved-0378> (Other) × [9.0] DEVANAGARI SIGN NUKTA (Extend_ConjunctLinkingScripts_ExtCccZwj) ÷ [0.3] -÷ 0378 × 0308 × 093C ÷ # ÷ [0.2] <reserved-0378> (Other) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] DEVANAGARI SIGN NUKTA (Extend_ConjunctLinkingScripts_ExtCccZwj) ÷ [0.3] +÷ 0378 × 0900 ÷ # ÷ [0.2] <reserved-0378> (Other) × [9.0] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts_ExtCccZwj) ÷ [0.3] +÷ 0378 × 0308 × 0900 ÷ # ÷ [0.2] <reserved-0378> (Other) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] DEVANAGARI SIGN INVERTED CANDRABINDU (Extend_ConjunctLinkingScripts_ExtCccZwj) ÷ [0.3] ÷ 0378 × 094D ÷ # ÷ [0.2] <reserved-0378> (Other) × [9.0] DEVANAGARI SIGN VIRAMA (Extend_ConjunctLinkingScripts_ConjunctLinker_ExtCccZwj) ÷ [0.3] ÷ 0378 × 0308 × 094D ÷ # ÷ [0.2] <reserved-0378> (Other) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] DEVANAGARI SIGN VIRAMA (Extend_ConjunctLinkingScripts_ConjunctLinker_ExtCccZwj) ÷ [0.3] ÷ 0378 × 200D ÷ # ÷ [0.2] <reserved-0378> (Other) × [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [0.3] @@ -1190,10 +1096,10 @@ ÷ 0061 × 0308 ÷ 0062 ÷ # ÷ [0.2] LATIN SMALL LETTER A (Other) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) ÷ [999.0] LATIN SMALL LETTER B (Other) ÷ [0.3] ÷ 0061 × 0903 ÷ 0062 ÷ # ÷ [0.2] LATIN SMALL LETTER A (Other) × [9.1] DEVANAGARI SIGN VISARGA (SpacingMark_ConjunctLinkingScripts) ÷ [999.0] LATIN SMALL LETTER B (Other) ÷ [0.3] ÷ 0061 ÷ 0600 × 0062 ÷ # ÷ [0.2] LATIN SMALL LETTER A (Other) ÷ [999.0] ARABIC NUMBER SIGN (Prepend) × [9.2] LATIN SMALL LETTER B (Other) ÷ [0.3] -÷ 1F476 × 1F3FF ÷ 1F476 ÷ # ÷ [0.2] BABY (ExtPict) × [9.0] EMOJI MODIFIER FITZPATRICK TYPE-6 (Extend) ÷ [999.0] BABY (ExtPict) ÷ [0.3] -÷ 0061 × 1F3FF ÷ 1F476 ÷ # ÷ [0.2] LATIN SMALL LETTER A (Other) × [9.0] EMOJI MODIFIER FITZPATRICK TYPE-6 (Extend) ÷ [999.0] BABY (ExtPict) ÷ [0.3] -÷ 0061 × 1F3FF ÷ 1F476 × 200D × 1F6D1 ÷ # ÷ [0.2] LATIN SMALL LETTER A (Other) × [9.0] EMOJI MODIFIER FITZPATRICK TYPE-6 (Extend) ÷ [999.0] BABY (ExtPict) × [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) × [11.0] OCTAGONAL SIGN (ExtPict) ÷ [0.3] -÷ 1F476 × 1F3FF × 0308 × 200D × 1F476 × 1F3FF ÷ # ÷ [0.2] BABY (ExtPict) × [9.0] EMOJI MODIFIER FITZPATRICK TYPE-6 (Extend) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) × [11.0] BABY (ExtPict) × [9.0] EMOJI MODIFIER FITZPATRICK TYPE-6 (Extend) ÷ [0.3] +÷ 1F476 × 1F3FF ÷ 1F476 ÷ # ÷ [0.2] BABY (ExtPict) × [9.0] EMOJI MODIFIER FITZPATRICK TYPE-6 (Extend_ExtCccZwj) ÷ [999.0] BABY (ExtPict) ÷ [0.3] +÷ 0061 × 1F3FF ÷ 1F476 ÷ # ÷ [0.2] LATIN SMALL LETTER A (Other) × [9.0] EMOJI MODIFIER FITZPATRICK TYPE-6 (Extend_ExtCccZwj) ÷ [999.0] BABY (ExtPict) ÷ [0.3] +÷ 0061 × 1F3FF ÷ 1F476 × 200D × 1F6D1 ÷ # ÷ [0.2] LATIN SMALL LETTER A (Other) × [9.0] EMOJI MODIFIER FITZPATRICK TYPE-6 (Extend_ExtCccZwj) ÷ [999.0] BABY (ExtPict) × [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) × [11.0] OCTAGONAL SIGN (ExtPict) ÷ [0.3] +÷ 1F476 × 1F3FF × 0308 × 200D × 1F476 × 1F3FF ÷ # ÷ [0.2] BABY (ExtPict) × [9.0] EMOJI MODIFIER FITZPATRICK TYPE-6 (Extend_ExtCccZwj) × [9.0] COMBINING DIAERESIS (Extend_ExtCccZwj) × [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) × [11.0] BABY (ExtPict) × [9.0] EMOJI MODIFIER FITZPATRICK TYPE-6 (Extend_ExtCccZwj) ÷ [0.3] ÷ 1F6D1 × 200D × 1F6D1 ÷ # ÷ [0.2] OCTAGONAL SIGN (ExtPict) × [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) × [11.0] OCTAGONAL SIGN (ExtPict) ÷ [0.3] ÷ 0061 × 200D ÷ 1F6D1 ÷ # ÷ [0.2] LATIN SMALL LETTER A (Other) × [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) ÷ [999.0] OCTAGONAL SIGN (ExtPict) ÷ [0.3] ÷ 2701 × 200D × 2701 ÷ # ÷ [0.2] UPPER BLADE SCISSORS (Other) × [9.0] ZERO WIDTH JOINER (ZWJ_ExtCccZwj) × [11.0] UPPER BLADE SCISSORS (Other) ÷ [0.3] @@ -1210,6 +1116,6 @@ ÷ 003F × 094D ÷ 0924 ÷ # ÷ [0.2] QUESTION MARK (Other) × [9.0] DEVANAGARI SIGN VIRAMA (Extend_ConjunctLinkingScripts_ConjunctLinker_ExtCccZwj) ÷ [999.0] DEVANAGARI LETTER TA (ConjunctLinkingScripts_LinkingConsonant) ÷ [0.3] ÷ 0915 × 094D × 094D × 0924 ÷ # ÷ [0.2] DEVANAGARI LETTER KA (ConjunctLinkingScripts_LinkingConsonant) × [9.0] DEVANAGARI SIGN VIRAMA (Extend_ConjunctLinkingScripts_ConjunctLinker_ExtCccZwj) × [9.0] DEVANAGARI SIGN VIRAMA (Extend_ConjunctLinkingScripts_ConjunctLinker_ExtCccZwj) × [9.3] DEVANAGARI LETTER TA (ConjunctLinkingScripts_LinkingConsonant) ÷ [0.3] # -# Lines: 1187 +# Lines: 1093 # # EOF diff --git a/src/java.base/share/data/unicodedata/emoji/emoji-data.txt b/src/java.base/share/data/unicodedata/emoji/emoji-data.txt index b7083f84a29..12f83273cf5 100644 --- a/src/java.base/share/data/unicodedata/emoji/emoji-data.txt +++ b/src/java.base/share/data/unicodedata/emoji/emoji-data.txt @@ -1,11 +1,11 @@ # emoji-data.txt -# Date: 2023-02-01, 02:22:54 GMT -# Copyright (c) 2023 Unicode, Inc. +# Date: 2024-05-01, 21:25:24 GMT +# Copyright (c) 2024 Unicode, Inc. # Unicode and the Unicode Logo are registered trademarks of Unicode, Inc. in the U.S. and other countries. -# For terms of use, see https://www.unicode.org/terms_of_use.html +# For terms of use and license, see https://www.unicode.org/terms_of_use.html # # Emoji Data for UTS #51 -# Used with Emoji Version 15.1 and subsequent minor revisions (if any) +# Used with Emoji Version 16.0 and subsequent minor revisions (if any) # # For documentation and usage, see https://www.unicode.org/reports/tr51 # @@ -407,6 +407,8 @@ 1FA80..1FA82 ; Emoji # E12.0 [3] (🪀..🪂) yo-yo..parachute 1FA83..1FA86 ; Emoji # E13.0 [4] (🪃..🪆) boomerang..nesting dolls 1FA87..1FA88 ; Emoji # E15.0 [2] (🪇..🪈) maracas..flute +1FA89 ; Emoji # E16.0 [1] (🪉) harp +1FA8F ; Emoji # E16.0 [1] (🪏) shovel 1FA90..1FA95 ; Emoji # E12.0 [6] (🪐..🪕) ringed planet..banjo 1FA96..1FAA8 ; Emoji # E13.0 [19] (🪖..🪨) military helmet..rock 1FAA9..1FAAC ; Emoji # E14.0 [4] (🪩..🪬) mirror ball..hamsa @@ -414,19 +416,24 @@ 1FAB0..1FAB6 ; Emoji # E13.0 [7] (🪰..🪶) fly..feather 1FAB7..1FABA ; Emoji # E14.0 [4] (🪷..🪺) lotus..nest with eggs 1FABB..1FABD ; Emoji # E15.0 [3] (🪻..🪽) hyacinth..wing +1FABE ; Emoji # E16.0 [1] (🪾) leafless tree 1FABF ; Emoji # E15.0 [1] (🪿) goose 1FAC0..1FAC2 ; Emoji # E13.0 [3] (🫀..🫂) anatomical heart..people hugging 1FAC3..1FAC5 ; Emoji # E14.0 [3] (🫃..🫅) pregnant man..person with crown +1FAC6 ; Emoji # E16.0 [1] (🫆) fingerprint 1FACE..1FACF ; Emoji # E15.0 [2] (🫎..🫏) moose..donkey 1FAD0..1FAD6 ; Emoji # E13.0 [7] (🫐..🫖) blueberries..teapot 1FAD7..1FAD9 ; Emoji # E14.0 [3] (🫗..🫙) pouring liquid..jar 1FADA..1FADB ; Emoji # E15.0 [2] (🫚..🫛) ginger root..pea pod +1FADC ; Emoji # E16.0 [1] (🫜) root vegetable +1FADF ; Emoji # E16.0 [1] (🫟) splatter 1FAE0..1FAE7 ; Emoji # E14.0 [8] (🫠..🫧) melting face..bubbles 1FAE8 ; Emoji # E15.0 [1] (🫨) shaking face +1FAE9 ; Emoji # E16.0 [1] (🫩) face with bags under eyes 1FAF0..1FAF6 ; Emoji # E14.0 [7] (🫰..🫶) hand with index finger and thumb crossed..heart hands 1FAF7..1FAF8 ; Emoji # E15.0 [2] (🫷..🫸) leftwards pushing hand..rightwards pushing hand -# Total elements: 1424 +# Total elements: 1431 # ================================================ @@ -696,6 +703,8 @@ 1FA80..1FA82 ; Emoji_Presentation # E12.0 [3] (🪀..🪂) yo-yo..parachute 1FA83..1FA86 ; Emoji_Presentation # E13.0 [4] (🪃..🪆) boomerang..nesting dolls 1FA87..1FA88 ; Emoji_Presentation # E15.0 [2] (🪇..🪈) maracas..flute +1FA89 ; Emoji_Presentation # E16.0 [1] (🪉) harp +1FA8F ; Emoji_Presentation # E16.0 [1] (🪏) shovel 1FA90..1FA95 ; Emoji_Presentation # E12.0 [6] (🪐..🪕) ringed planet..banjo 1FA96..1FAA8 ; Emoji_Presentation # E13.0 [19] (🪖..🪨) military helmet..rock 1FAA9..1FAAC ; Emoji_Presentation # E14.0 [4] (🪩..🪬) mirror ball..hamsa @@ -703,19 +712,24 @@ 1FAB0..1FAB6 ; Emoji_Presentation # E13.0 [7] (🪰..🪶) fly..feather 1FAB7..1FABA ; Emoji_Presentation # E14.0 [4] (🪷..🪺) lotus..nest with eggs 1FABB..1FABD ; Emoji_Presentation # E15.0 [3] (🪻..🪽) hyacinth..wing +1FABE ; Emoji_Presentation # E16.0 [1] (🪾) leafless tree 1FABF ; Emoji_Presentation # E15.0 [1] (🪿) goose 1FAC0..1FAC2 ; Emoji_Presentation # E13.0 [3] (🫀..🫂) anatomical heart..people hugging 1FAC3..1FAC5 ; Emoji_Presentation # E14.0 [3] (🫃..🫅) pregnant man..person with crown +1FAC6 ; Emoji_Presentation # E16.0 [1] (🫆) fingerprint 1FACE..1FACF ; Emoji_Presentation # E15.0 [2] (🫎..🫏) moose..donkey 1FAD0..1FAD6 ; Emoji_Presentation # E13.0 [7] (🫐..🫖) blueberries..teapot 1FAD7..1FAD9 ; Emoji_Presentation # E14.0 [3] (🫗..🫙) pouring liquid..jar 1FADA..1FADB ; Emoji_Presentation # E15.0 [2] (🫚..🫛) ginger root..pea pod +1FADC ; Emoji_Presentation # E16.0 [1] (🫜) root vegetable +1FADF ; Emoji_Presentation # E16.0 [1] (🫟) splatter 1FAE0..1FAE7 ; Emoji_Presentation # E14.0 [8] (🫠..🫧) melting face..bubbles 1FAE8 ; Emoji_Presentation # E15.0 [1] (🫨) shaking face +1FAE9 ; Emoji_Presentation # E16.0 [1] (🫩) face with bags under eyes 1FAF0..1FAF6 ; Emoji_Presentation # E14.0 [7] (🫰..🫶) hand with index finger and thumb crossed..heart hands 1FAF7..1FAF8 ; Emoji_Presentation # E15.0 [2] (🫷..🫸) leftwards pushing hand..rightwards pushing hand -# Total elements: 1205 +# Total elements: 1212 # ================================================ @@ -1289,7 +1303,9 @@ E0020..E007F ; Emoji_Component # E0.0 [96] (󠀠..󠁿) tag space..c 1FA80..1FA82 ; Extended_Pictographic# E12.0 [3] (🪀..🪂) yo-yo..parachute 1FA83..1FA86 ; Extended_Pictographic# E13.0 [4] (🪃..🪆) boomerang..nesting dolls 1FA87..1FA88 ; Extended_Pictographic# E15.0 [2] (🪇..🪈) maracas..flute -1FA89..1FA8F ; Extended_Pictographic# E0.0 [7] (🪉..🪏) <reserved-1FA89>..<reserved-1FA8F> +1FA89 ; Extended_Pictographic# E16.0 [1] (🪉) harp +1FA8A..1FA8E ; Extended_Pictographic# E0.0 [5] (🪊..🪎) <reserved-1FA8A>..<reserved-1FA8E> +1FA8F ; Extended_Pictographic# E16.0 [1] (🪏) shovel 1FA90..1FA95 ; Extended_Pictographic# E12.0 [6] (🪐..🪕) ringed planet..banjo 1FA96..1FAA8 ; Extended_Pictographic# E13.0 [19] (🪖..🪨) military helmet..rock 1FAA9..1FAAC ; Extended_Pictographic# E14.0 [4] (🪩..🪬) mirror ball..hamsa @@ -1297,19 +1313,23 @@ E0020..E007F ; Emoji_Component # E0.0 [96] (󠀠..󠁿) tag space..c 1FAB0..1FAB6 ; Extended_Pictographic# E13.0 [7] (🪰..🪶) fly..feather 1FAB7..1FABA ; Extended_Pictographic# E14.0 [4] (🪷..🪺) lotus..nest with eggs 1FABB..1FABD ; Extended_Pictographic# E15.0 [3] (🪻..🪽) hyacinth..wing -1FABE ; Extended_Pictographic# E0.0 [1] (🪾) <reserved-1FABE> +1FABE ; Extended_Pictographic# E16.0 [1] (🪾) leafless tree 1FABF ; Extended_Pictographic# E15.0 [1] (🪿) goose 1FAC0..1FAC2 ; Extended_Pictographic# E13.0 [3] (🫀..🫂) anatomical heart..people hugging 1FAC3..1FAC5 ; Extended_Pictographic# E14.0 [3] (🫃..🫅) pregnant man..person with crown -1FAC6..1FACD ; Extended_Pictographic# E0.0 [8] (🫆..🫍) <reserved-1FAC6>..<reserved-1FACD> +1FAC6 ; Extended_Pictographic# E16.0 [1] (🫆) fingerprint +1FAC7..1FACD ; Extended_Pictographic# E0.0 [7] (🫇..🫍) <reserved-1FAC7>..<reserved-1FACD> 1FACE..1FACF ; Extended_Pictographic# E15.0 [2] (🫎..🫏) moose..donkey 1FAD0..1FAD6 ; Extended_Pictographic# E13.0 [7] (🫐..🫖) blueberries..teapot 1FAD7..1FAD9 ; Extended_Pictographic# E14.0 [3] (🫗..🫙) pouring liquid..jar 1FADA..1FADB ; Extended_Pictographic# E15.0 [2] (🫚..🫛) ginger root..pea pod -1FADC..1FADF ; Extended_Pictographic# E0.0 [4] (🫜..🫟) <reserved-1FADC>..<reserved-1FADF> +1FADC ; Extended_Pictographic# E16.0 [1] (🫜) root vegetable +1FADD..1FADE ; Extended_Pictographic# E0.0 [2] (🫝..🫞) <reserved-1FADD>..<reserved-1FADE> +1FADF ; Extended_Pictographic# E16.0 [1] (🫟) splatter 1FAE0..1FAE7 ; Extended_Pictographic# E14.0 [8] (🫠..🫧) melting face..bubbles 1FAE8 ; Extended_Pictographic# E15.0 [1] (🫨) shaking face -1FAE9..1FAEF ; Extended_Pictographic# E0.0 [7] (🫩..🫯) <reserved-1FAE9>..<reserved-1FAEF> +1FAE9 ; Extended_Pictographic# E16.0 [1] (🫩) face with bags under eyes +1FAEA..1FAEF ; Extended_Pictographic# E0.0 [6] (🫪..🫯) <reserved-1FAEA>..<reserved-1FAEF> 1FAF0..1FAF6 ; Extended_Pictographic# E14.0 [7] (🫰..🫶) hand with index finger and thumb crossed..heart hands 1FAF7..1FAF8 ; Extended_Pictographic# E15.0 [2] (🫷..🫸) leftwards pushing hand..rightwards pushing hand 1FAF9..1FAFF ; Extended_Pictographic# E0.0 [7] (🫹..🫿) <reserved-1FAF9>..<reserved-1FAFF> diff --git a/src/java.base/share/legal/icu.md b/src/java.base/share/legal/icu.md index 588e88e35fb..e27193e10be 100644 --- a/src/java.base/share/legal/icu.md +++ b/src/java.base/share/legal/icu.md @@ -1,4 +1,4 @@ -## International Components for Unicode (ICU4J) v74.1 +## International Components for Unicode (ICU4J) v76.1 ### ICU4J License ``` @@ -6,7 +6,7 @@ UNICODE LICENSE V3 COPYRIGHT AND PERMISSION NOTICE -Copyright © 2016-2023 Unicode, Inc. +Copyright © 2016-2024 Unicode, Inc. NOTICE TO USER: Carefully read the following legal agreement. BY DOWNLOADING, INSTALLING, COPYING OR OTHERWISE USING DATA FILES, AND/OR @@ -42,6 +42,8 @@ not be used in advertising or otherwise to promote the sale, use or other dealings in these Data Files or Software without prior written authorization of the copyright holder. +SPDX-License-Identifier: Unicode-3.0 + ---------------------------------------------------------------------- Third-Party Software Licenses @@ -87,86 +89,5 @@ of the copyright holder. All trademarks and registered trademarks mentioned herein are the property of their respective owners. ----------------------------------------------------------------------- - - -Time Zone Database - - ICU uses the public domain data and code derived from Time Zone -Database for its time zone support. The ownership of the TZ database -is explained in BCP 175: Procedure for Maintaining the Time Zone -Database section 7. - - # 7. Database Ownership - # - # The TZ database itself is not an IETF Contribution or an IETF - # document. Rather it is a pre-existing and regularly updated work - # that is in the public domain, and is intended to remain in the - # public domain. Therefore, BCPs 78 [RFC5378] and 79 [RFC3979] do - # not apply to the TZ Database or contributions that individuals make - # to it. Should any claims be made and substantiated against the TZ - # Database, the organization that is providing the IANA - # Considerations defined in this RFC, under the memorandum of - # understanding with the IETF, currently ICANN, may act in accordance - # with all competent court orders. No ownership claims will be made - # by ICANN or the IETF Trust on the database or the code. Any person - # making a contribution to the database or code waives all rights to - # future claims in that contribution or in the TZ Database. - ----------------------------------------------------------------------- - -====================================================================== - - -From: https://www.unicode.org/copyright.html - -For the general privacy policy governing access to this site, see the Unicode Privacy Policy. - - Unicode Copyright - Copyright © 1991-2023 Unicode, Inc. All rights reserved. - Definitions - - Unicode Data Files ("DATA FILES") include all data files under the directories: - https://www.unicode.org/Public/ - https://www.unicode.org/reports/ - https://www.unicode.org/ivd/data/ - - Unicode Data Files do not include PDF online code charts under the directory: - https://www.unicode.org/Public/ - - Unicode Software ("SOFTWARE") includes any source code published in the Unicode Standard - or any source code or compiled code under the directories: - https://www.unicode.org/Public/PROGRAMS/ - https://www.unicode.org/Public/cldr/ - http://site.icu-project.org/download/ - - Terms of Use - Certain documents and files on this website contain a legend indicating that "Modification is permitted." Any person is hereby authorized, without fee, to modify such documents and files to create derivative works conforming to the Unicode® Standard, subject to Terms and Conditions herein. - Any person is hereby authorized, without fee, to view, use, reproduce, and distribute all documents and files, subject to the Terms and Conditions herein. - Further specifications of rights and restrictions pertaining to the use of the Unicode DATA FILES and SOFTWARE can be found in the Unicode Data Files and Software License. - Each version of the Unicode Standard has further specifications of rights and restrictions of use. For the book editions (Unicode 5.0 and earlier), these are found on the back of the title page. - The Unicode PDF online code charts carry specific restrictions. Those restrictions are incorporated as the first page of each PDF code chart. - All other files, including online documentation of the core specification for Unicode 6.0 and later, are covered under these general Terms of Use. - No license is granted to "mirror" the Unicode website where a fee is charged for access to the "mirror" site. - Modification is not permitted with respect to this document. All copies of this document must be verbatim. - Restricted Rights Legend - Any technical data or software which is licensed to the United States of America, its agencies and/or instrumentalities under this Agreement is commercial technical data or commercial computer software developed exclusively at private expense as defined in FAR 2.101, or DFARS 252.227-7014 (June 1995), as applicable. For technical data, use, duplication, or disclosure by the Government is subject to restrictions as set forth in DFARS 202.227-7015 Technical Data, Commercial and Items (Nov 1995) and this Agreement. For Software, in accordance with FAR 12-212 or DFARS 227-7202, as applicable, use, duplication or disclosure by the Government is subject to the restrictions set forth in this Agreement. - Warranties and Disclaimers - This publication and/or website may include technical or typographical errors or other inaccuracies. Changes are periodically added to the information herein; these changes will be incorporated in new editions of the publication and/or website. Unicode, Inc. may make improvements and/or changes in the product(s) and/or program(s) described in this publication and/or website at any time. - If this file has been purchased on magnetic or optical media from Unicode, Inc. the sole and exclusive remedy for any claim will be exchange of the defective media within ninety (90) days of original purchase. - EXCEPT AS PROVIDED IN SECTION E.2, THIS PUBLICATION AND/OR SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND EITHER EXPRESS, IMPLIED, OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. UNICODE, INC. AND ITS LICENSORS ASSUME NO RESPONSIBILITY FOR ERRORS OR OMISSIONS IN THIS PUBLICATION AND/OR SOFTWARE OR OTHER DOCUMENTS WHICH ARE REFERENCED BY OR LINKED TO THIS PUBLICATION OR THE UNICODE WEBSITE. - Waiver of Damages - In no event shall Unicode, Inc. or its licensors be liable for any special, incidental, indirect or consequential damages of any kind, or any damages whatsoever, whether or not Unicode, Inc. was advised of the possibility of the damage, including, without limitation, those resulting from the following: loss of use, data or profits, in connection with the use, modification or distribution of this information or its derivatives. - Trademarks & Logos - The Unicode Word Mark and the Unicode Logo are trademarks of Unicode, Inc. “The Unicode Consortium” and “Unicode, Inc.” are trade names of Unicode, Inc. Use of the information and materials found on this website indicates your acknowledgement of Unicode, Inc.’s exclusive worldwide rights in the Unicode Word Mark, the Unicode Logo, and the Unicode trade names. - The Unicode Consortium Name and Trademark Usage Policy (“Trademark Policy”) are incorporated herein by reference and you agree to abide by the provisions of the Trademark Policy, which may be changed from time to time in the sole discretion of Unicode, Inc. - All third party trademarks referenced herein are the property of their respective owners. - Miscellaneous - Jurisdiction and Venue. This website is operated from a location in the State of California, United States of America. Unicode, Inc. makes no representation that the materials are appropriate for use in other locations. If you access this website from other locations, you are responsible for compliance with local laws. This Agreement, all use of this website and any claims and damages resulting from use of this website are governed solely by the laws of the State of California without regard to any principles which would apply the laws of a different jurisdiction. The user agrees that any disputes regarding this website shall be resolved solely in the courts located in Santa Clara County, California. The user agrees said courts have personal jurisdiction and agree to waive any right to transfer the dispute to any other forum. - Modification by Unicode, Inc. Unicode, Inc. shall have the right to modify this Agreement at any time by posting it to this website. The user may not assign any part of this Agreement without Unicode, Inc.’s prior written consent. - Taxes. The user agrees to pay any taxes arising from access to this website or use of the information herein, except for those based on Unicode’s net income. - Severability. If any provision of this Agreement is declared invalid or unenforceable, the remaining provisions of this Agreement shall remain in effect. - Entire Agreement. This Agreement constitutes the entire agreement between the parties. - ``` diff --git a/src/java.base/share/legal/unicode.md b/src/java.base/share/legal/unicode.md index a128f8a7b0e..8bd2ed8bd13 100644 --- a/src/java.base/share/legal/unicode.md +++ b/src/java.base/share/legal/unicode.md @@ -1,4 +1,4 @@ -## The Unicode Standard, Unicode Character Database, Version 15.1.0 +## The Unicode Standard, Unicode Character Database, Version 16.0.0 ### Unicode Character Database ``` @@ -7,7 +7,7 @@ UNICODE LICENSE V3 COPYRIGHT AND PERMISSION NOTICE -Copyright © 1991-2023 Unicode, Inc. +Copyright © 1991-2024 Unicode, Inc. NOTICE TO USER: Carefully read the following legal agreement. BY DOWNLOADING, INSTALLING, COPYING OR OTHERWISE USING DATA FILES, AND/OR @@ -46,59 +46,224 @@ authorization of the copyright holder. ------------------ -Unicode® Copyright and Terms of Use -For the general privacy policy governing access to this site, see the Unicode Privacy Policy. - - A. Unicode Copyright - Copyright © 1991-2023 Unicode, Inc. All rights reserved. - - B. Definitions - Unicode Data Files ("DATA FILES") include all data files under the directories: - https://www.unicode.org/Public/ - https://www.unicode.org/reports/ - https://www.unicode.org/ivd/data/ - - Unicode Data Files do not include PDF online code charts under the directory: - https://www.unicode.org/Public/ - - Unicode Software ("SOFTWARE") includes any source code published in the Unicode Standard - or any source code or compiled code under the directories: - https://www.unicode.org/Public/PROGRAMS/ - https://www.unicode.org/Public/cldr/ - http://site.icu-project.org/download/ - - C. Terms of Use - 1. Certain documents and files on this website contain a legend indicating that "Modification is permitted." Any person is hereby authorized, without fee, to modify such documents and files to create derivative works conforming to the Unicode® Standard, subject to Terms and Conditions herein. - 2. Any person is hereby authorized, without fee, to view, use, reproduce, and distribute all documents and files, subject to the Terms and Conditions herein. - 3. Further specifications of rights and restrictions pertaining to the use of the Unicode DATA FILES and SOFTWARE can be found in the Unicode Data Files and Software License. - 4. Each version of the Unicode Standard has further specifications of rights and restrictions of use. For the book editions (Unicode 5.0 and earlier), these are found on the back of the title page. - 5. The Unicode PDF online code charts carry specific restrictions. Those restrictions are incorporated as the first page of each PDF code chart. - 6. All other files, including online documentation of the core specification for Unicode 6.0 and later, are covered under these general Terms of Use. - 7. No license is granted to "mirror" the Unicode website where a fee is charged for access to the "mirror" site. - 8. Modification is not permitted with respect to this document. All copies of this document must be verbatim. - - D. Restricted Rights Legend - 1. Any technical data or software which is licensed to the United States of America, its agencies and/or instrumentalities under this Agreement is commercial technical data or commercial computer software developed exclusively at private expense as defined in FAR 2.101, or DFARS 252.227-7014 (June 1995), as applicable. For technical data, use, duplication, or disclosure by the Government is subject to restrictions as set forth in DFARS 202.227-7015 Technical Data, Commercial and Items (Nov 1995) and this Agreement. For Software, in accordance with FAR 12-212 or DFARS 227-7202, as applicable, use, duplication or disclosure by the Government is subject to the restrictions set forth in this Agreement. - - E. Warranties and Disclaimers - 1. This publication and/or website may include technical or typographical errors or other inaccuracies. Changes are periodically added to the information herein; these changes will be incorporated in new editions of the publication and/or website. Unicode, Inc. may make improvements and/or changes in the product(s) and/or program(s) described in this publication and/or website at any time. - 2. If this file has been purchased on magnetic or optical media from Unicode, Inc. the sole and exclusive remedy for any claim will be exchange of the defective media within ninety (90) days of original purchase. - 3. EXCEPT AS PROVIDED IN SECTION E.2, THIS PUBLICATION AND/OR SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND EITHER EXPRESS, IMPLIED, OR STATUTORY, INCLUDING, BUT NOT LIMITED TO, ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. UNICODE, INC. AND ITS LICENSORS ASSUME NO RESPONSIBILITY FOR ERRORS OR OMISSIONS IN THIS PUBLICATION AND/OR SOFTWARE OR OTHER DOCUMENTS WHICH ARE REFERENCED BY OR LINKED TO THIS PUBLICATION OR THE UNICODE WEBSITE. - - F. Waiver of Damages - 1. In no event shall Unicode, Inc. or its licensors be liable for any special, incidental, indirect or consequential damages of any kind, or any damages whatsoever, whether or not Unicode, Inc. was advised of the possibility of the damage, including, without limitation, those resulting from the following: loss of use, data or profits, in connection with the use, modification or distribution of this information or its derivatives. - - G. Trademarks & Logos - 1. The Unicode Word Mark and the Unicode Logo are trademarks of Unicode, Inc. "The Unicode Consortium" and "Unicode, Inc." are trade names of Unicode, Inc. Use of the information and materials found on this website indicates your acknowledgement of Unicode, Inc.'s exclusive worldwide rights in the Unicode Word Mark, the Unicode Logo, and the Unicode trade names. - 2. The Unicode Consortium Name and Trademark Usage Policy ("Trademark Policy") are incorporated herein by reference and you agree to abide by the provisions of the Trademark Policy, which may be changed from time to time in the sole discretion of Unicode, Inc. - All third party trademarks referenced herein are the property of their respective owners. - - H. Miscellaneous - 1. Jurisdiction and Venue. This website is operated from a location in the State of California, United States of America. Unicode, Inc. makes no representation that the materials are appropriate for use in other locations. If you access this website from other locations, you are responsible for compliance with local laws. This Agreement, all use of this website and any claims and damages resulting from use of this website are governed solely by the laws of the State of California without regard to any principles which would apply the laws of a different jurisdiction. The user agrees that any disputes regarding this website shall be resolved solely in the courts located in Santa Clara County, California. The user agrees said courts have personal jurisdiction and agree to waive any right to transfer the dispute to any other forum. - 2. Modification by Unicode, Inc. Unicode, Inc. shall have the right to modify this Agreement at any time by posting it to this website. The user may not assign any part of this Agreement without Unicode, Inc.'s prior written consent. - 3. Taxes. The user agrees to pay any taxes arising from access to this website or use of the information herein, except for those based on Unicode's net income. - 4. Severability. If any provision of this Agreement is declared invalid or unenforceable, the remaining provisions of this Agreement shall remain in effect. - 5. Entire Agreement. This Agreement constitutes the entire agreement between the parties. +Unicode® Consortium Copyright, Terms of Use, and Licenses -``` +Welcome to the website of Unicode, Inc. (dba The Unicode Consortium) +(“Unicode”). Except as otherwise noted herein, these terms and conditions +(“Terms of Use”) govern your use of the Unicode website and Unicode Products. +Your use of this website and/or Unicode Products constitutes your agreement +to follow and be bound by these Terms of Use. Unicode provides you with +access to and use of this website and Unicode Products subject to your +compliance with these Terms of Use. If you do not agree to these Terms +of Use, you should not access or use this website or Unicode Products. +Unicode reserves the right to make changes to the website, to Unicode +Products, and to these Terms of Use at any time in its sole d iscretion. + + 1. Unicode Copyright: Copyright © 1991-Present Unicode, Inc. + + 2. Definitions + + a. “Unicode Products” includes the Unicode website and its content, + Data Files, Software, the Unicode Standard, all other Unicode + standards, specifications, technical reports, technical notes, + annexes, code charts, data files, software, publications, + webinars, videos, course materials, online and in-person events, + and all other Unicode products and services made available via + this website or any other channel of distribution, including but + not limited to Github, Maven, YouTube, and other third-party + sites where Unicode maintains and provides products, materials, + and services. + + b. “Unicode Data Files” or "Data Files" include all computer data + files under the following directories: + + i. https://www.unicode.org/Public/ + ii. https://www.unicode.org/reports/ + iii. https://www.unicode.org/ivd/data/ + iv. https://github.com/unicode-org/ + + but exclude any materials present in the above directories that + are not computer data files, such as PDF code charts and + Technical Reports. + + c. “Unicode Software” or "Software" includes any source code or + compiled code in any Unicode Product including but not limited to + the code included in the following directories: + + i. https://www.unicode.org/Public/PROGRAMS/ + ii. https://www.unicode.org/Public/cldr/ + iii. https://github.com/unicode-org/ + + 3. Permissions, Licenses, and Restrictions on Use + + a. You are authorized to freely access and use this website and its + content and all Unicode Products subject to these Terms of Use and + subject to any restriction, permission, or license specifically + associated with any specific material or content. No license is + granted to copy or "mirror" this website. Linking to this website + is permitted. + + b. Except where otherwise more broadly permitted or licensed: + + 1. you may not make copies of or modifications to Unicode + Products for public distribution, or incorporate Unicode + Products in whole or in part into any product or publication, + or otherwise publicly distribute them, without the express + written permission of Unicode, and + + 2. you may not copy or extract fonts or font data from any + Unicode Products, including but not limited to Unicode Code + Charts. + + c. All Unicode Data Files and Unicode Software are subject to the + terms and conditions of the free and open-source Unicode License + v3, unless otherwise indicated by specific restriction, + permission, or license identified at the point of release or in + such software, data file, or other documentation. + + d. You may freely download and make copies of the Unicode® Standard + Core Specification, Unicode Technical Reports, Unicode Technical + Notes, Unicode Code Charts, and other portions of this website + and may annotate and translate such permitted downloads and + copies, provided that such downloads, copies, annotations, and + translations are solely for personal or internal business + purposes and not for public distribution, and further provided + that any permitted copies and modifications fully reproduce all + copyright and other legal notices contained in the original. + Notwithstanding the foregoing, specific versions of the Unicode® + Standard Core Specification, Unicode Technical Reports, Unicode + Technical Notes, and Unicode Code Charts, as well as other Unicode + publications, materials, and portions of this website may be + subject to broader permissions and/or further reservations of + rights and restrictions on use found in the title pages, cover + sheets, front matter, and/or footnotes for each such version, + report, chart, or other publication or material. Consult each + version, report, chart, or other publication or material for any + such permissions and further reservations of rights and + restrictions on use. + + 4. Restricted Rights Legend. Any Unicode Data Files or Software that are + licensed to the United States of America, its agencies and/or + instrumentalities under these Terms of Use is commercial technical + data or commercial computer software developed exclusively at private + expense as defined in FAR 2.101, or DFARS 252.227-7014, as applicable. + For Unicode Data Files, use, duplication, or disclosure by the + Government is subject to restrictions as set forth in DFARS + 202.227-7015 Technical Data, Commercial and Items and these Terms of + Use. For Unicode Software, in accordance with FAR 12-212 or DFARS + 227-7202, as applicable, use, duplication or disclosure by the + Government is subject to the restrictions set forth in these Terms + of Use. + + 5. Disclaimer of Warranties & Limitation of Liability + + a. This website and the Unicode Products are provided “AS-IS” without + charge as a convenience to visitors and users. While Unicode + attempts to provide accurate, error-free, and timely information, + there may be technical or factual inaccuracies and typographical + or other errors in this website and in the Unicode Products. + Unicode reserves the right to make corrections and changes to the + website and the Unicode Products at any time without notice. + + b. YOU ASSUME ALL RESPONSIBILITY AND RISK WITH RESPECT TO YOUR USE + OF THIS WEBSITE AND THE UNICODE PRODUCTS, WHICH ARE PROVIDED "AS + IS" WITHOUT WARRANTY OF ANY KIND EITHER EXPRESS, IMPLIED, OR + STATUTORY, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF + ACCURACY, COMPLETENESS, TITLE, MERCHANTABILITY, FITNESS FOR A + PARTICULAR PURPOSE, OR NON-INFRINGEMENT OF THIRD PARTY RIGHTS. + UNICODE AND ITS LICENSORS AND CONTRIBUTORS ASSUME NO + RESPONSIBILITY FOR ERRORS OR OMISSIONS IN THIS WEBSITE AND/OR THE + UNICODE PRODUCTS. IF YOU ARE DISSATISFIED WITH THIS WEBSITE OR THE + UNICODE PRODUCTS, YOUR SOLE REMEDY IS TO DISCONTINUE USE OF THE + WEBSITE AND THE UNICODE PRODUCTS. + + c. IN NO EVENT SHALL UNICODE, ITS MEMBERS, OR ITS LICENSORS OR + CONTRIBUTORS BE LIABLE FOR ANY CLAIM OR DAMAGES WHATSOEVER OF ANY + KIND, WHETHER DIRECT, INDIRECT, SPECIAL, INCIDENTAL, + CONSEQUENTIAL, EXEMPLARY, OR PUNITIVE DAMAGES, WHETHER OR NOT + UNICODE WAS ADVISED OF THE POSSIBILITY OF SUCH DAMAGE, INCLUDING + BUT NOT LIMITED TO DAMAGE RESULTING FROM LOSS OF USE, DATA, OR + PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE, OR OTHER + TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE, + INABILITY TO USE, PERFORMANCE, FUNCTIONALITY, MODIFICATION, OR + DISTRIBUTION OF THIS WEBSITE, THE UNICODE PRODUCTS, OR ANY + DERIVATIVES THEREOF. + + d. Unicode makes no warranties or representations of any kind + regarding any non-Unicode sites to which you may be directed or + hyperlinked from this website. Hyperlinks are included solely for + your convenience and Unicode makes no warranties or + representations with regard to the accuracy, availability, + suitability, or safety of information, products, or services + provided on such non-Unicode sites. + + 6. Intellectual Property Contributions to Unicode. All contributions or + submissions to Unicode are governed by The Unicode Consortium + Intellectual Property, Licensing & Technical Contribution Policies. + If you wish to make any contribution or submission to Unicode, refer + to the foregoing Policies for further information on how to do so. + In the absence of a signed contributor license or other agreement with + Unicode that expressly governs a particular contribution or + submission, the act of making a contribution or submission of any kind + to Unicode by any communication channel constitutes a binding legal + agreement by the contributor or submitter that they: + + a. represent and agree that the contributed matter is not + proprietary or confidential to the contributor or any third + party, and + + b. grant to Unicode and to recipients of products distributed by + Unicode a perpetual, irrevocable, unrestricted, worldwide, + nonexclusive, no-charge, royalty-free license, without + obligation for accounting, to reproduce, prepare derivative + works of, publicly display, publicly perform, distribute, + make, use, sell, offer to sell, or import that matter for any + purpose, with the unrestricted right to sublicense those + rights. + + 7. Compliance with Unicode Policies. These Terms of Use hereby + incorporate by reference the following Unicode Policies. Your use of + this website and/or Unicode Products and/or your participation in + Unicode activities constitutes your agreement to these Policies + which may be modified at any time in Unicode’s sole discretion: + + a. The Unicode Consortium Code of Conduct + b. The Unicode Consortium Antitrust Policy & Guidelines + c. The Unicode Consortium Intellectual Property, Licensing & + Technical Contribution Policies + d. The Unicode Consortium Name and Trademark Usage Policy + e. The Unicode Consortium Policy on Handling of Confidential + Business Data + f. The Unicode Consortium General Privacy Policy + g. The Unicode Technical Group Procedures + + 8. Trademarks & Logos. The Unicode Word Mark and the Unicode Logo are + trademarks of Unicode, Inc. “The Unicode Consortium'' and “Unicode, + Inc.” are trade names of Unicode, Inc. You hereby acknowledge and + agree to respect Unicode’s exclusive worldwide rights in the Unicode + Word Mark, the Unicode Logo, and the Unicode trade names. The Unicode + Consortium Name and Trademark Usage Policy is incorporated herein by + reference and you agree to abide by its provisions, which may be + changed from time to time in Unicode’s sole discretion. + + 9. Jurisdiction and Venue. This website is operated from, and the + Unicode Products are made available from, locations in the United + States of America. Unicode makes no representation that this website + or Unicode Products are appropriate for use in other locations. If + you access this website or the Unicode Products from other locations, + you are responsible for compliance with local laws. These Terms of + Use, all use of this website and Unicode Products, and any claims and + damages resulting from use of this website or Unicode Products, are + governed by the applicable laws of the United States of America and + the State of California without regard to any principles which would + apply the laws of different jurisdictions. You agree that any disputes + regarding this website and the Unicode Products shall be resolved + solely in the appropriate state and federal courts located in the + counties of San Francisco, San Mateo, or Santa Clara, California. + You agree that these courts have personal jurisdiction over you and + agree to waive any right to transfer the dispute to any other forum. + + 10. Severability. If any provision of these Terms of Use is declared + invalid or unenforceable, the remaining provisions of these Terms of + Use shall remain in effect. diff --git a/test/jdk/java/lang/String/UnicodeCasingTest.java b/test/jdk/java/lang/String/UnicodeCasingTest.java index 8924c4ad20e..84f8dd12975 100644 --- a/test/jdk/java/lang/String/UnicodeCasingTest.java +++ b/test/jdk/java/lang/String/UnicodeCasingTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -66,7 +66,7 @@ private void test() { Locale defaultLocale = Locale.getDefault(); BufferedReader in = null; try { - // First, we create exlude lists of characters whose mappings exist + // First, we create exclude lists of characters whose mappings exist // in SpecialCasing.txt and mapping rules in UnicodeData.txt aren't // applicable. in = Files.newBufferedReader(UCDFiles.SPECIAL_CASING.toRealPath()); @@ -84,7 +84,6 @@ private void test() { Locale locale = locales.get(l); Locale.setDefault(locale); defaultLang = locale.getLanguage(); -// System.out.println("Testing on " + locale + " locale...."); System.err.println("Testing on " + locale + " locale...."); in = Files.newBufferedReader(UCDFiles.UNICODE_DATA.toRealPath()); while ((line = in.readLine()) != null) { From 593a5898f93fd009197e89aba311268bc1a2e74e Mon Sep 17 00:00:00 2001 From: Roger Riggs <rriggs@openjdk.org> Date: Mon, 25 Nov 2024 16:46:19 +0000 Subject: [PATCH 224/311] 8344319: SM cleanup in jdk.dynalink module Reviewed-by: attila --- .../classes/jdk/dynalink/BiClassValue.java | 27 ++----- .../jdk/dynalink/DynamicLinkerFactory.java | 28 ++----- .../jdk/dynalink/SecureLookupSupplier.java | 7 -- .../jdk/dynalink/beans/BeanIntrospector.java | 24 ++---- .../beans/CallerSensitiveDynamicMethod.java | 15 +--- .../beans/CheckRestrictedPackage.java | 25 +----- .../jdk/dynalink/beans/ClassString.java | 22 ++--- .../beans/OverloadedDynamicMethod.java | 15 +--- .../internal/AccessControlContextFactory.java | 80 ------------------- .../internal/InternalTypeUtilities.java | 3 - .../linker/GuardingDynamicLinkerExporter.java | 7 -- .../linker/GuardingTypeConverterFactory.java | 6 +- .../jdk/dynalink/linker/LinkerServices.java | 5 +- 13 files changed, 32 insertions(+), 232 deletions(-) delete mode 100644 src/jdk.dynalink/share/classes/jdk/dynalink/internal/AccessControlContextFactory.java diff --git a/src/jdk.dynalink/share/classes/jdk/dynalink/BiClassValue.java b/src/jdk.dynalink/share/classes/jdk/dynalink/BiClassValue.java index 4a540be5377..661ca87c358 100644 --- a/src/jdk.dynalink/share/classes/jdk/dynalink/BiClassValue.java +++ b/src/jdk.dynalink/share/classes/jdk/dynalink/BiClassValue.java @@ -27,14 +27,10 @@ import java.lang.invoke.MethodHandles; import java.lang.invoke.VarHandle; -import java.security.AccessControlContext; -import java.security.AccessController; -import java.security.PrivilegedAction; import java.util.Map; import java.util.Objects; import java.util.function.BiFunction; import java.util.function.Function; -import jdk.dynalink.internal.AccessControlContextFactory; import static jdk.dynalink.internal.InternalTypeUtilities.canReferenceDirectly; @@ -201,21 +197,14 @@ final T get(final Class<?> c1, final Class<?> c2) { } } - @SuppressWarnings("removal") - private static final AccessControlContext GET_CLASS_LOADER_CONTEXT = - AccessControlContextFactory.createAccessControlContext("getClassLoader"); - - @SuppressWarnings("removal") private static RetentionDirection getRetentionDirection(Class<?> from, Class<?> to) { - return AccessController.doPrivileged((PrivilegedAction<RetentionDirection>) () -> { - final ClassLoader cl1 = from.getClassLoader(); - final ClassLoader cl2 = to.getClassLoader(); - if (canReferenceDirectly(cl1, cl2)) { - return RetentionDirection.FORWARD; - } else if (canReferenceDirectly(cl2, cl1)) { - return RetentionDirection.REVERSE; - } - return RetentionDirection.NEITHER; - }, GET_CLASS_LOADER_CONTEXT); + final ClassLoader cl1 = from.getClassLoader(); + final ClassLoader cl2 = to.getClassLoader(); + if (canReferenceDirectly(cl1, cl2)) { + return RetentionDirection.FORWARD; + } else if (canReferenceDirectly(cl2, cl1)) { + return RetentionDirection.REVERSE; + } + return RetentionDirection.NEITHER; } } diff --git a/src/jdk.dynalink/share/classes/jdk/dynalink/DynamicLinkerFactory.java b/src/jdk.dynalink/share/classes/jdk/dynalink/DynamicLinkerFactory.java index 8714ae314f2..dfa077fc1af 100644 --- a/src/jdk.dynalink/share/classes/jdk/dynalink/DynamicLinkerFactory.java +++ b/src/jdk.dynalink/share/classes/jdk/dynalink/DynamicLinkerFactory.java @@ -63,9 +63,6 @@ WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodType; import java.lang.invoke.MutableCallSite; -import java.security.AccessControlContext; -import java.security.AccessController; -import java.security.PrivilegedAction; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; @@ -79,7 +76,6 @@ WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR import java.util.Set; import java.util.function.Supplier; import jdk.dynalink.beans.BeansLinker; -import jdk.dynalink.internal.AccessControlContextFactory; import jdk.dynalink.linker.GuardedInvocation; import jdk.dynalink.linker.GuardedInvocationTransformer; import jdk.dynalink.linker.GuardingDynamicLinker; @@ -108,10 +104,6 @@ WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR * @since 9 */ public final class DynamicLinkerFactory { - @SuppressWarnings("removal") - private static final AccessControlContext GET_CLASS_LOADER_CONTEXT = - AccessControlContextFactory.createAccessControlContext("getClassLoader"); - /** * Default value for {@link #setUnstableRelinkThreshold(int) unstable relink * threshold}. @@ -430,17 +422,14 @@ public List<ServiceConfigurationError> getAutoLoadingErrors() { private List<GuardingDynamicLinker> discoverAutoLoadLinkers() { autoLoadingErrors = new LinkedList<>(); - final ClassLoader effectiveClassLoader = classLoaderExplicitlySet ? classLoader : getThreadContextClassLoader(); + final ClassLoader effectiveClassLoader = + classLoaderExplicitlySet ? classLoader : Thread.currentThread().getContextClassLoader(); final List<GuardingDynamicLinker> discovered = new LinkedList<>(); try { - @SuppressWarnings("removal") final ServiceLoader<GuardingDynamicLinkerExporter> linkerLoader = - AccessController.doPrivileged((PrivilegedAction<ServiceLoader<GuardingDynamicLinkerExporter>>)()-> { - if (effectiveClassLoader == null) { - return ServiceLoader.loadInstalled(GuardingDynamicLinkerExporter.class); - } - return ServiceLoader.load(GuardingDynamicLinkerExporter.class, effectiveClassLoader); - }); + (effectiveClassLoader == null) + ? ServiceLoader.loadInstalled(GuardingDynamicLinkerExporter.class) + : ServiceLoader.load(GuardingDynamicLinkerExporter.class, effectiveClassLoader); for(final Iterator<GuardingDynamicLinkerExporter> it = linkerLoader.iterator(); it.hasNext();) { try { @@ -470,13 +459,6 @@ private List<GuardingDynamicLinker> discoverAutoLoadLinkers() { return discovered; } - @SuppressWarnings("removal") - private static ClassLoader getThreadContextClassLoader() { - return AccessController.doPrivileged( - (PrivilegedAction<ClassLoader>) () -> Thread.currentThread().getContextClassLoader(), - GET_CLASS_LOADER_CONTEXT); - } - private static void addClasses(final Set<Class<? extends GuardingDynamicLinker>> knownLinkerClasses, final List<? extends GuardingDynamicLinker> linkers) { for(final GuardingDynamicLinker linker: linkers) { diff --git a/src/jdk.dynalink/share/classes/jdk/dynalink/SecureLookupSupplier.java b/src/jdk.dynalink/share/classes/jdk/dynalink/SecureLookupSupplier.java index 8b76f0abdc3..72a66973eb3 100644 --- a/src/jdk.dynalink/share/classes/jdk/dynalink/SecureLookupSupplier.java +++ b/src/jdk.dynalink/share/classes/jdk/dynalink/SecureLookupSupplier.java @@ -45,8 +45,6 @@ public class SecureLookupSupplier { */ public static final String GET_LOOKUP_PERMISSION_NAME = "dynalink.getLookup"; - private static final RuntimePermission GET_LOOKUP_PERMISSION = new RuntimePermission(SecureLookupSupplier.GET_LOOKUP_PERMISSION_NAME); - private final MethodHandles.Lookup lookup; /** @@ -63,11 +61,6 @@ public SecureLookupSupplier(final MethodHandles.Lookup lookup) { * @return the lookup secured by this {@code SecureLookupSupplier}. */ public final Lookup getLookup() { - @SuppressWarnings("removal") - final SecurityManager sm = System.getSecurityManager(); - if (sm != null && lookup != MethodHandles.publicLookup()) { - sm.checkPermission(GET_LOOKUP_PERMISSION); - } return lookup; } diff --git a/src/jdk.dynalink/share/classes/jdk/dynalink/beans/BeanIntrospector.java b/src/jdk.dynalink/share/classes/jdk/dynalink/beans/BeanIntrospector.java index 1df330aad3f..76b5de969f9 100644 --- a/src/jdk.dynalink/share/classes/jdk/dynalink/beans/BeanIntrospector.java +++ b/src/jdk.dynalink/share/classes/jdk/dynalink/beans/BeanIntrospector.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -63,8 +63,6 @@ WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR import java.lang.invoke.MethodHandle; import java.lang.reflect.Method; import java.lang.reflect.RecordComponent; -import java.security.AccessController; -import java.security.PrivilegedAction; import java.util.Arrays; import java.util.Collection; import java.util.List; @@ -86,20 +84,12 @@ Map<String, MethodHandle> getInnerClassGetters() { @Override Collection<Method> getRecordComponentGetters() { if (clazz.isRecord()) { - try { - // Need to use doPrivileged as getRecordComponents is rather strict. - @SuppressWarnings("removal") - final RecordComponent[] rcs = AccessController.doPrivileged( - (PrivilegedAction<RecordComponent[]>) clazz::getRecordComponents); - return Arrays.stream(rcs) - .map(RecordComponent::getAccessor) - .map(membersLookup::getAccessibleMethod) - .filter(Objects::nonNull) // no accessible counterpart - .toList(); - } catch (SecurityException e) { - // We couldn't execute getRecordComponents. - return List.of(); - } + final RecordComponent[] rcs = clazz.getRecordComponents(); + return Arrays.stream(rcs) + .map(RecordComponent::getAccessor) + .map(membersLookup::getAccessibleMethod) + .filter(Objects::nonNull) // no accessible counterpart + .toList(); } else { return List.of(); } diff --git a/src/jdk.dynalink/share/classes/jdk/dynalink/beans/CallerSensitiveDynamicMethod.java b/src/jdk.dynalink/share/classes/jdk/dynalink/beans/CallerSensitiveDynamicMethod.java index f8218c876ee..c860289925e 100644 --- a/src/jdk.dynalink/share/classes/jdk/dynalink/beans/CallerSensitiveDynamicMethod.java +++ b/src/jdk.dynalink/share/classes/jdk/dynalink/beans/CallerSensitiveDynamicMethod.java @@ -67,12 +67,8 @@ WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR import java.lang.reflect.Executable; import java.lang.reflect.Method; import java.lang.reflect.Modifier; -import java.security.AccessControlContext; -import java.security.AccessController; -import java.security.PrivilegedAction; + import jdk.dynalink.CallSiteDescriptor; -import jdk.dynalink.SecureLookupSupplier; -import jdk.dynalink.internal.AccessControlContextFactory; import jdk.dynalink.linker.support.Lookup; /** @@ -82,10 +78,6 @@ WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR * every request. */ class CallerSensitiveDynamicMethod extends SingleDynamicMethod { - @SuppressWarnings("removal") - private static final AccessControlContext GET_LOOKUP_CONTEXT = - AccessControlContextFactory.createAccessControlContext( - SecureLookupSupplier.GET_LOOKUP_PERMISSION_NAME); private final Executable target; private final MethodType type; @@ -127,10 +119,7 @@ boolean isVarArgs() { @Override MethodHandle getTarget(final CallSiteDescriptor desc) { - @SuppressWarnings("removal") - final MethodHandles.Lookup lookup = AccessController.doPrivileged( - (PrivilegedAction<MethodHandles.Lookup>)desc::getLookup, - GET_LOOKUP_CONTEXT); + final MethodHandles.Lookup lookup = desc.getLookup(); if(target instanceof Method) { final MethodHandle mh = unreflect(lookup, (Method)target); diff --git a/src/jdk.dynalink/share/classes/jdk/dynalink/beans/CheckRestrictedPackage.java b/src/jdk.dynalink/share/classes/jdk/dynalink/beans/CheckRestrictedPackage.java index f7d5e5c43c2..7412a962940 100644 --- a/src/jdk.dynalink/share/classes/jdk/dynalink/beans/CheckRestrictedPackage.java +++ b/src/jdk.dynalink/share/classes/jdk/dynalink/beans/CheckRestrictedPackage.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -61,25 +61,17 @@ WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR package jdk.dynalink.beans; import java.lang.reflect.Modifier; -import java.security.AccessControlContext; -import java.security.AccessController; -import java.security.PrivilegedAction; -import jdk.dynalink.internal.AccessControlContextFactory; /** * A utility class to check whether a given class is in a package with restricted access e.g. "sun.*" etc. */ class CheckRestrictedPackage { - @SuppressWarnings("removal") - private static final AccessControlContext NO_PERMISSIONS_CONTEXT = - AccessControlContextFactory.createAccessControlContext(); /** * Returns true if the class is either not public, or it resides in a package with restricted access. * @param clazz the class to test * @return true if the class is either not public, or it resides in a package with restricted access. */ - @SuppressWarnings("removal") static boolean isRestrictedClass(final Class<?> clazz) { if(!Modifier.isPublic(clazz.getModifiers())) { // Non-public classes are always restricted @@ -97,21 +89,6 @@ static boolean isRestrictedClass(final Class<?> clazz) { // Classes in unexported packages of modules are always restricted return true; } - - final SecurityManager sm = System.getSecurityManager(); - if(sm == null) { - // No further restrictions if we don't have a security manager - return false; - } - // Do a package access check from within an access control context with no permissions - try { - AccessController.doPrivileged((PrivilegedAction<Void>) () -> { - sm.checkPackageAccess(pkgName); - return null; - }, NO_PERMISSIONS_CONTEXT); - } catch(final SecurityException e) { - return true; - } return false; } } diff --git a/src/jdk.dynalink/share/classes/jdk/dynalink/beans/ClassString.java b/src/jdk.dynalink/share/classes/jdk/dynalink/beans/ClassString.java index af0ee1beeca..a892f06e55d 100644 --- a/src/jdk.dynalink/share/classes/jdk/dynalink/beans/ClassString.java +++ b/src/jdk.dynalink/share/classes/jdk/dynalink/beans/ClassString.java @@ -61,13 +61,10 @@ WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR package jdk.dynalink.beans; import java.lang.invoke.MethodHandle; -import java.security.AccessControlContext; -import java.security.AccessController; -import java.security.PrivilegedAction; import java.util.Arrays; import java.util.LinkedList; import java.util.List; -import jdk.dynalink.internal.AccessControlContextFactory; + import jdk.dynalink.internal.InternalTypeUtilities; import jdk.dynalink.linker.LinkerServices; import jdk.dynalink.linker.support.TypeUtilities; @@ -78,10 +75,6 @@ WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR * JLS. */ final class ClassString { - @SuppressWarnings("removal") - private static final AccessControlContext GET_CLASS_LOADER_CONTEXT = - AccessControlContextFactory.createAccessControlContext("getClassLoader"); - /** * An anonymous inner class used solely to represent the "type" of null values for method applicability checking. */ @@ -128,16 +121,13 @@ public String toString() { return "ClassString[" + Arrays.toString(classes) + "]"; } - @SuppressWarnings("removal") boolean isVisibleFrom(final ClassLoader classLoader) { - return AccessController.doPrivileged((PrivilegedAction<Boolean>) () -> { - for(final Class<?> clazz: classes) { - if(!InternalTypeUtilities.canReferenceDirectly(classLoader, clazz.getClassLoader())) { - return false; - } + for(final Class<?> clazz: classes) { + if(!InternalTypeUtilities.canReferenceDirectly(classLoader, clazz.getClassLoader())) { + return false; } - return true; - }, GET_CLASS_LOADER_CONTEXT); + } + return true; } List<MethodHandle> getMaximallySpecifics(final List<MethodHandle> methods, final LinkerServices linkerServices, final boolean varArg) { diff --git a/src/jdk.dynalink/share/classes/jdk/dynalink/beans/OverloadedDynamicMethod.java b/src/jdk.dynalink/share/classes/jdk/dynalink/beans/OverloadedDynamicMethod.java index 2f3c3315fbf..14e0aa2ca96 100644 --- a/src/jdk.dynalink/share/classes/jdk/dynalink/beans/OverloadedDynamicMethod.java +++ b/src/jdk.dynalink/share/classes/jdk/dynalink/beans/OverloadedDynamicMethod.java @@ -62,9 +62,6 @@ WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodType; -import java.security.AccessControlContext; -import java.security.AccessController; -import java.security.PrivilegedAction; import java.text.Collator; import java.util.ArrayList; import java.util.IdentityHashMap; @@ -73,9 +70,7 @@ WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR import java.util.Map; import java.util.Set; import jdk.dynalink.CallSiteDescriptor; -import jdk.dynalink.SecureLookupSupplier; import jdk.dynalink.beans.ApplicableOverloadedMethods.ApplicabilityTest; -import jdk.dynalink.internal.AccessControlContextFactory; import jdk.dynalink.internal.InternalTypeUtilities; import jdk.dynalink.linker.LinkerServices; @@ -194,16 +189,8 @@ MethodHandle getInvocation(final CallSiteDescriptor callSiteDescriptor, final Li } } - @SuppressWarnings("removal") - private static final AccessControlContext GET_CALL_SITE_CLASS_LOADER_CONTEXT = - AccessControlContextFactory.createAccessControlContext( - "getClassLoader", SecureLookupSupplier.GET_LOOKUP_PERMISSION_NAME); - - @SuppressWarnings("removal") private static ClassLoader getCallSiteClassLoader(final CallSiteDescriptor callSiteDescriptor) { - return AccessController.doPrivileged( - (PrivilegedAction<ClassLoader>) () -> callSiteDescriptor.getLookup().lookupClass().getClassLoader(), - GET_CALL_SITE_CLASS_LOADER_CONTEXT); + return callSiteDescriptor.getLookup().lookupClass().getClassLoader(); } @Override diff --git a/src/jdk.dynalink/share/classes/jdk/dynalink/internal/AccessControlContextFactory.java b/src/jdk.dynalink/share/classes/jdk/dynalink/internal/AccessControlContextFactory.java deleted file mode 100644 index b5c3ea82de0..00000000000 --- a/src/jdk.dynalink/share/classes/jdk/dynalink/internal/AccessControlContextFactory.java +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Copyright (c) 2015, 2021, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package jdk.dynalink.internal; - -import java.security.AccessControlContext; -import java.security.Permission; -import java.security.Permissions; -import java.security.ProtectionDomain; -import java.util.stream.Stream; - -/** - * Utility class for creating permission-restricting {@link AccessControlContext}s. - */ -public final class AccessControlContextFactory { - private AccessControlContextFactory () { - } - - /** - * Creates an access control context with no permissions. - * @return an access control context with no permissions. - */ - @SuppressWarnings("removal") - public static AccessControlContext createAccessControlContext() { - return createAccessControlContext(new Permission[0]); - } - - /** - * Creates an access control context limited to only the specified permissions. - * @param permissions the permissions for the newly created access control context. - * @return a new access control context limited to only the specified permissions. - */ - @SuppressWarnings("removal") - public static AccessControlContext createAccessControlContext(final Permission... permissions) { - final Permissions perms = new Permissions(); - for(final Permission permission: permissions) { - perms.add(permission); - } - return new AccessControlContext(new ProtectionDomain[] { new ProtectionDomain(null, perms) }); - } - - /** - * Creates an access control context limited to only the {@link RuntimePermission}s - * of the given names. - * @param runtimePermissionNames the names of runtime permissions for the - * newly created access control context. - * @return a new access control context limited to only the runtime - * permissions with the specified names. - */ - @SuppressWarnings("removal") - public static AccessControlContext createAccessControlContext(final String... runtimePermissionNames) { - return createAccessControlContext(makeRuntimePermissions(runtimePermissionNames)); - } - - private static Permission[] makeRuntimePermissions(final String... runtimePermissionNames) { - return Stream.of(runtimePermissionNames).map(RuntimePermission::new).toArray(Permission[]::new); - } -} diff --git a/src/jdk.dynalink/share/classes/jdk/dynalink/internal/InternalTypeUtilities.java b/src/jdk.dynalink/share/classes/jdk/dynalink/internal/InternalTypeUtilities.java index 147e7cb6f4e..8cda7a1e804 100644 --- a/src/jdk.dynalink/share/classes/jdk/dynalink/internal/InternalTypeUtilities.java +++ b/src/jdk.dynalink/share/classes/jdk/dynalink/internal/InternalTypeUtilities.java @@ -63,9 +63,6 @@ public static boolean areAssignable(final Class<?> c1, final Class<?> c2) { * @param referredLoader the referred class loader * @return true if it is safe to strongly reference the class from referred * in referred. - * @throws SecurityException if the caller does not have the - * {@code RuntimePermission("getClassLoader")} permission and the method - * needs to traverse the parent class loader chain. */ public static boolean canReferenceDirectly(final ClassLoader referrerLoader, final ClassLoader referredLoader) { if(referredLoader == null) { diff --git a/src/jdk.dynalink/share/classes/jdk/dynalink/linker/GuardingDynamicLinkerExporter.java b/src/jdk.dynalink/share/classes/jdk/dynalink/linker/GuardingDynamicLinkerExporter.java index f00bb81c587..ceed8903ade 100644 --- a/src/jdk.dynalink/share/classes/jdk/dynalink/linker/GuardingDynamicLinkerExporter.java +++ b/src/jdk.dynalink/share/classes/jdk/dynalink/linker/GuardingDynamicLinkerExporter.java @@ -52,16 +52,9 @@ public abstract class GuardingDynamicLinkerExporter implements Supplier<List<Gua */ public static final String AUTOLOAD_PERMISSION_NAME = "dynalink.exportLinkersAutomatically"; - private static final Permission AUTOLOAD_PERMISSION = new RuntimePermission(AUTOLOAD_PERMISSION_NAME); - /** * Creates a new linker exporter. */ protected GuardingDynamicLinkerExporter() { - @SuppressWarnings("removal") - final SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - sm.checkPermission(AUTOLOAD_PERMISSION); - } } } diff --git a/src/jdk.dynalink/share/classes/jdk/dynalink/linker/GuardingTypeConverterFactory.java b/src/jdk.dynalink/share/classes/jdk/dynalink/linker/GuardingTypeConverterFactory.java index bbd327d5bbe..56b3c0c8eae 100644 --- a/src/jdk.dynalink/share/classes/jdk/dynalink/linker/GuardingTypeConverterFactory.java +++ b/src/jdk.dynalink/share/classes/jdk/dynalink/linker/GuardingTypeConverterFactory.java @@ -115,11 +115,7 @@ public interface GuardingTypeConverterFactory { * it will return the public lookup. A typical case where the lookup might * be needed is when the converter creates a Java adapter class on the fly * (e.g. to convert some object from the dynamic language into a Java - * interface for interoperability). Invoking the {@link Supplier#get()} - * method on the passed supplier will be subject to the same security checks - * as {@link SecureLookupSupplier#getLookup()}. An implementation should avoid - * retrieving the lookup if it is not needed so as to avoid the expense of - * {@code AccessController.doPrivileged} call. + * interface for interoperability). * @return a guarded invocation that can take an object (if it passes guard) * and return another object that is its representation coerced into the * target type. In case the factory is certain it is unable to handle a diff --git a/src/jdk.dynalink/share/classes/jdk/dynalink/linker/LinkerServices.java b/src/jdk.dynalink/share/classes/jdk/dynalink/linker/LinkerServices.java index 5a028205676..409af52f592 100644 --- a/src/jdk.dynalink/share/classes/jdk/dynalink/linker/LinkerServices.java +++ b/src/jdk.dynalink/share/classes/jdk/dynalink/linker/LinkerServices.java @@ -215,10 +215,7 @@ public default MethodHandle asTypeLosslessReturn(final MethodHandle handle, fina * operation to the context of some caller class, consider performing it * within an invocation of this method and passing a full-strength lookup * for that class, as it will associate that lookup with the current thread - * for the duration of the operation. Note that since you are passing a - * {@link SecureLookupSupplier}, any invoked type converter factories will - * still need to hold the necessary runtime permission to be able to get the - * lookup should they need it. + * for the duration of the operation. * @param <T> the type of the return value provided by the passed-in supplier. * @param operation the operation to execute in context of the specified lookup. * @param lookupSupplier secure supplier of the lookup From 08dfc4a42e58a13a51fb7be2ebfa1c15daea28a9 Mon Sep 17 00:00:00 2001 From: Christian Hagedorn <chagedorn@openjdk.org> Date: Mon, 25 Nov 2024 16:46:44 +0000 Subject: [PATCH 225/311] 8344213: Cleanup OpaqueLoop*Node verification code for Assertion Predicates Reviewed-by: thartmann, epeter --- src/hotspot/share/opto/loopPredicate.cpp | 2 - src/hotspot/share/opto/loopTransform.cpp | 77 ----------- src/hotspot/share/opto/loopnode.hpp | 5 - src/hotspot/share/opto/loopopts.cpp | 1 - src/hotspot/share/opto/node.hpp | 47 +++++++ src/hotspot/share/opto/predicates.cpp | 155 +++++++++++++++++------ src/hotspot/share/opto/predicates.hpp | 22 ++++ 7 files changed, 184 insertions(+), 125 deletions(-) diff --git a/src/hotspot/share/opto/loopPredicate.cpp b/src/hotspot/share/opto/loopPredicate.cpp index ed2cee63122..9340f7e0978 100644 --- a/src/hotspot/share/opto/loopPredicate.cpp +++ b/src/hotspot/share/opto/loopPredicate.cpp @@ -348,8 +348,6 @@ PhaseIdealLoop::clone_assertion_predicate_for_unswitched_loops(IfTrueNode* templ ParsePredicateNode* unswitched_loop_parse_predicate) { TemplateAssertionPredicate template_assertion_predicate(template_assertion_predicate_success_proj); IfTrueNode* template_success_proj = template_assertion_predicate.clone(unswitched_loop_parse_predicate->in(0), this); - assert(assertion_predicate_has_loop_opaque_node(template_success_proj->in(0)->as_If()), - "must find Assertion Predicate for fast loop"); _igvn.replace_input_of(unswitched_loop_parse_predicate, 0, template_success_proj); set_idom(unswitched_loop_parse_predicate, template_success_proj, dom_depth(template_success_proj)); return template_success_proj; diff --git a/src/hotspot/share/opto/loopTransform.cpp b/src/hotspot/share/opto/loopTransform.cpp index e6a56410bd7..f644e26bbe7 100644 --- a/src/hotspot/share/opto/loopTransform.cpp +++ b/src/hotspot/share/opto/loopTransform.cpp @@ -1312,80 +1312,6 @@ void PhaseIdealLoop::ensure_zero_trip_guard_proj(Node* node, bool is_main_loop) } #endif -#ifdef ASSERT -bool PhaseIdealLoop::assertion_predicate_has_loop_opaque_node(IfNode* iff) { - uint init; - uint stride; - count_opaque_loop_nodes(iff->in(1)->in(1), init, stride); - ResourceMark rm; - Unique_Node_List wq; - wq.clear(); - wq.push(iff->in(1)->in(1)); - uint verif_init = 0; - uint verif_stride = 0; - for (uint i = 0; i < wq.size(); i++) { - Node* n = wq.at(i); - int op = n->Opcode(); - if (!n->is_CFG()) { - if (n->Opcode() == Op_OpaqueLoopInit) { - verif_init++; - } else if (n->Opcode() == Op_OpaqueLoopStride) { - verif_stride++; - } else { - for (uint j = 1; j < n->req(); j++) { - Node* m = n->in(j); - if (m != nullptr) { - wq.push(m); - } - } - } - } - } - assert(init == verif_init && stride == verif_stride, "missed opaque node"); - assert(stride == 0 || init != 0, "init should be there every time stride is"); - return init != 0; -} - -void PhaseIdealLoop::count_opaque_loop_nodes(Node* n, uint& init, uint& stride) { - init = 0; - stride = 0; - ResourceMark rm; - Unique_Node_List wq; - wq.push(n); - for (uint i = 0; i < wq.size(); i++) { - Node* n = wq.at(i); - if (TemplateAssertionExpressionNode::is_maybe_in_expression(n)) { - if (n->is_OpaqueLoopInit()) { - init++; - } else if (n->is_OpaqueLoopStride()) { - stride++; - } else { - for (uint j = 1; j < n->req(); j++) { - Node* m = n->in(j); - if (m != nullptr) { - wq.push(m); - } - } - } - } - } -} -#endif // ASSERT - -// Create an Initialized Assertion Predicate from the template_assertion_predicate -IfTrueNode* PhaseIdealLoop::create_initialized_assertion_predicate(IfNode* template_assertion_predicate, Node* new_init, - Node* new_stride, Node* new_control) { - assert(assertion_predicate_has_loop_opaque_node(template_assertion_predicate), - "must find OpaqueLoop* nodes for Template Assertion Predicate"); - InitializedAssertionPredicateCreator initialized_assertion_predicate(this); - IfTrueNode* success_proj = initialized_assertion_predicate.create_from_template(template_assertion_predicate, - new_control, new_init, new_stride); - - assert(!assertion_predicate_has_loop_opaque_node(success_proj->in(0)->as_If()), - "Initialized Assertion Predicates do not have OpaqueLoop* nodes in the bool expression anymore"); - return success_proj; -} - //------------------------------insert_pre_post_loops-------------------------- // Insert pre and post loops. If peel_only is set, the pre-loop can not have // more iterations added. It acts as a 'peel' only, no lower-bound RCE, no @@ -2761,7 +2687,6 @@ void PhaseIdealLoop::do_range_check(IdealLoopTree *loop, Node_List &old_new) { loop_entry = initialized_assertion_predicate_creator.create(final_iv_placeholder, loop_entry, stride_con, scale_con, int_offset, int_limit, AssertionPredicateType::FinalIv); - assert(!assertion_predicate_has_loop_opaque_node(loop_entry->in(0)->as_If()), "unexpected"); } // Add two Template Assertion Predicates to create new Initialized Assertion Predicates from when either @@ -2769,13 +2694,11 @@ void PhaseIdealLoop::do_range_check(IdealLoopTree *loop, Node_List &old_new) { TemplateAssertionPredicateCreator template_assertion_predicate_creator(cl, scale_con , int_offset, int_limit, this); loop_entry = template_assertion_predicate_creator.create(loop_entry); - assert(assertion_predicate_has_loop_opaque_node(loop_entry->in(0)->as_If()), "unexpected"); // Initialized Assertion Predicate for the value of the initial main-loop. loop_entry = initialized_assertion_predicate_creator.create(init, loop_entry, stride_con, scale_con, int_offset, int_limit, AssertionPredicateType::InitValue); - assert(!assertion_predicate_has_loop_opaque_node(loop_entry->in(0)->as_If()), "unexpected"); } else { if (PrintOpto) { diff --git a/src/hotspot/share/opto/loopnode.hpp b/src/hotspot/share/opto/loopnode.hpp index 07ae390bd2e..698e48aadb4 100644 --- a/src/hotspot/share/opto/loopnode.hpp +++ b/src/hotspot/share/opto/loopnode.hpp @@ -941,12 +941,7 @@ class PhaseIdealLoop : public PhaseTransform { #ifdef ASSERT static void ensure_zero_trip_guard_proj(Node* node, bool is_main_loop); #endif - public: - IfTrueNode* create_initialized_assertion_predicate(IfNode* template_assertion_predicate, Node* new_init, - Node* new_stride, Node* control); - DEBUG_ONLY(static bool assertion_predicate_has_loop_opaque_node(IfNode* iff);) private: - DEBUG_ONLY(static void count_opaque_loop_nodes(Node* n, uint& init, uint& stride);) static void get_template_assertion_predicates(ParsePredicateSuccessProj* parse_predicate_proj, Unique_Node_List& list, bool get_opaque = false); void update_main_loop_assertion_predicates(CountedLoopNode* main_loop_head); void initialize_assertion_predicates_for_peeled_loop(CountedLoopNode* peeled_loop_head, diff --git a/src/hotspot/share/opto/loopopts.cpp b/src/hotspot/share/opto/loopopts.cpp index 9c4385000fb..2626b0af6ee 100644 --- a/src/hotspot/share/opto/loopopts.cpp +++ b/src/hotspot/share/opto/loopopts.cpp @@ -789,7 +789,6 @@ Node *PhaseIdealLoop::conditional_move( Node *region ) { assert(!bol->is_OpaqueInitializedAssertionPredicate(), "Initialized Assertion Predicates cannot form a diamond with Halt"); if (bol->is_OpaqueTemplateAssertionPredicate()) { // Ignore Template Assertion Predicates with OpaqueTemplateAssertionPredicate nodes. - assert(assertion_predicate_has_loop_opaque_node(iff), "must find OpaqueLoop* nodes"); return nullptr; } assert(bol->Opcode() == Op_Bool, "Unexpected node"); diff --git a/src/hotspot/share/opto/node.hpp b/src/hotspot/share/opto/node.hpp index 678b12b04ac..b3515236ff0 100644 --- a/src/hotspot/share/opto/node.hpp +++ b/src/hotspot/share/opto/node.hpp @@ -2114,4 +2114,51 @@ inline int Op_DivModIL(BasicType bt, bool is_unsigned) { } } +// Interface to define actions that should be taken when running DataNodeBFS. Each use can extend this class to specify +// a customized BFS. +class BFSActions : public StackObj { + public: + // Should a node's inputs further be visited in the BFS traversal? By default, we visit all data inputs. Override this + // method to provide a custom filter. + virtual bool should_visit(Node* node) const { + // By default, visit all inputs. + return true; + }; + + // Is the visited node a target node that we are looking for in the BFS traversal? We do not visit its inputs further + // but the BFS will continue to visit all unvisited nodes in the queue. + virtual bool is_target_node(Node* node) const = 0; + + // Defines an action that should be taken when we visit a target node in the BFS traversal. + virtual void target_node_action(Node* target_node) = 0; +}; + +// Class to perform a BFS traversal on the data nodes from a given start node. The provided BFSActions guide which +// data node's inputs should be further visited, which data nodes are target nodes and what to do with the target nodes. +class DataNodeBFS : public StackObj { + BFSActions& _bfs_actions; + + public: + explicit DataNodeBFS(BFSActions& bfs_action) : _bfs_actions(bfs_action) {} + + // Run the BFS starting from 'start_node' and apply the actions provided to this class. + void run(Node* start_node) { + ResourceMark rm; + Unique_Node_List _nodes_to_visit; + _nodes_to_visit.push(start_node); + for (uint i = 0; i < _nodes_to_visit.size(); i++) { + Node* next = _nodes_to_visit[i]; + for (uint j = 1; j < next->req(); j++) { + Node* input = next->in(j); + if (_bfs_actions.is_target_node(input)) { + assert(_bfs_actions.should_visit(input), "must also pass node filter"); + _bfs_actions.target_node_action(input); + } else if (_bfs_actions.should_visit(input)) { + _nodes_to_visit.push(input); + } + } + } + } +}; + #endif // SHARE_OPTO_NODE_HPP diff --git a/src/hotspot/share/opto/predicates.cpp b/src/hotspot/share/opto/predicates.cpp index b57a4d6fdf1..3df899f5e9a 100644 --- a/src/hotspot/share/opto/predicates.cpp +++ b/src/hotspot/share/opto/predicates.cpp @@ -153,24 +153,21 @@ bool TemplateAssertionPredicate::is_predicate(Node* node) { // Clone this Template Assertion Predicate and replace the OpaqueLoopInitNode with the provided 'new_opaque_init' node. IfTrueNode* TemplateAssertionPredicate::clone(Node* new_control, PhaseIdealLoop* phase) const { - assert(PhaseIdealLoop::assertion_predicate_has_loop_opaque_node(_if_node), - "must find OpaqueLoop* nodes for Template Assertion Predicate"); + DEBUG_ONLY(verify();) TemplateAssertionExpression template_assertion_expression(opaque_node()); OpaqueTemplateAssertionPredicateNode* new_opaque_node = template_assertion_expression.clone(new_control, phase); AssertionPredicateIfCreator assertion_predicate_if_creator(phase); IfTrueNode* success_proj = assertion_predicate_if_creator.create_for_template(new_control, _if_node->Opcode(), new_opaque_node, _if_node->assertion_predicate_type()); - assert(PhaseIdealLoop::assertion_predicate_has_loop_opaque_node(success_proj->in(0)->as_If()), - "Template Assertion Predicates must have OpaqueLoop* nodes in the bool expression"); + DEBUG_ONLY(TemplateAssertionPredicate::verify(success_proj);) return success_proj; } // Clone this Template Assertion Predicate and replace the OpaqueLoopInitNode with the provided 'new_opaque_init' node. IfTrueNode* TemplateAssertionPredicate::clone_and_replace_init(Node* new_control, OpaqueLoopInitNode* new_opaque_init, PhaseIdealLoop* phase) const { - assert(PhaseIdealLoop::assertion_predicate_has_loop_opaque_node(_if_node), - "must find OpaqueLoop* nodes for Template Assertion Predicate"); + DEBUG_ONLY(verify();) TemplateAssertionExpression template_assertion_expression(opaque_node()); OpaqueTemplateAssertionPredicateNode* new_opaque_node = template_assertion_expression.clone_and_replace_init(new_control, new_opaque_init, phase); @@ -178,13 +175,13 @@ IfTrueNode* TemplateAssertionPredicate::clone_and_replace_init(Node* new_control IfTrueNode* success_proj = assertion_predicate_if_creator.create_for_template(new_control, _if_node->Opcode(), new_opaque_node, _if_node->assertion_predicate_type()); - assert(PhaseIdealLoop::assertion_predicate_has_loop_opaque_node(success_proj->in(0)->as_If()), - "Template Assertion Predicates must have OpaqueLoop* nodes in the bool expression"); + DEBUG_ONLY(TemplateAssertionPredicate::verify(success_proj);) return success_proj; } // Replace the input to OpaqueLoopStrideNode with 'new_stride' and leave the other nodes unchanged. void TemplateAssertionPredicate::replace_opaque_stride_input(Node* new_stride, PhaseIterGVN& igvn) const { + DEBUG_ONLY(verify();) TemplateAssertionExpression expression(opaque_node()); expression.replace_opaque_stride_input(new_stride, igvn); } @@ -192,15 +189,80 @@ void TemplateAssertionPredicate::replace_opaque_stride_input(Node* new_stride, P // Create a new Initialized Assertion Predicate from this template at 'new_control' and return the success projection // of the newly created Initialized Assertion Predicate. IfTrueNode* TemplateAssertionPredicate::initialize(PhaseIdealLoop* phase, Node* new_control) const { - assert(phase->assertion_predicate_has_loop_opaque_node(head()), - "must find OpaqueLoop* nodes for Template Assertion Predicate"); - InitializedAssertionPredicateCreator initialized_assertion_predicate(phase); - IfTrueNode* success_proj = initialized_assertion_predicate.create_from_template(head(), new_control); - assert(!phase->assertion_predicate_has_loop_opaque_node(success_proj->in(0)->as_If()), - "Initialized Assertion Predicates do not have OpaqueLoop* nodes in the bool expression anymore"); + DEBUG_ONLY(verify();) + InitializedAssertionPredicateCreator initialized_assertion_predicate_creator(phase); + IfTrueNode* success_proj = initialized_assertion_predicate_creator.create_from_template(head(), new_control); + DEBUG_ONLY(InitializedAssertionPredicate::verify(success_proj);) return success_proj; } +#ifdef ASSERT +// Class to verify Initialized and Template Assertion Predicates by trying to find OpaqueLoop*Nodes. +class OpaqueLoopNodesVerifier : public BFSActions { + bool _found_init; + bool _found_stride; + + public: + OpaqueLoopNodesVerifier() + : _found_init(false), + _found_stride(false) {} + + // A Template Assertion Predicate has: + // - Always an OpaqueLoopInitNode + // - Only an OpaqueLoopStrideNode for the last value. + void verify(const TemplateAssertionPredicate& template_assertion_predicate) { + DataNodeBFS bfs(*this); + bfs.run(template_assertion_predicate.opaque_node()); + if (template_assertion_predicate.is_last_value()) { + assert(_found_init && _found_stride, + "must find OpaqueLoopInit and OpaqueLoopStride for last value Template Assertion Predicate"); + } else { + assert(_found_init && !_found_stride, + "must find OpaqueLoopInit but not OpaqueLoopStride for init value Template Assertion Predicate"); + } + } + + // An Initialized Assertion Predicate never has any OpaqueLoop*Nodes. + void verify(const InitializedAssertionPredicate& initialized_assertion_predicate) { + DataNodeBFS bfs(*this); + bfs.run(initialized_assertion_predicate.opaque_node()); + assert(!_found_init && !_found_stride, + "must neither find OpaqueLoopInit nor OpaqueLoopStride for Initialized Assertion Predicate"); + } + + bool should_visit(Node* node) const override { + return TemplateAssertionExpressionNode::is_maybe_in_expression(node); + } + + bool is_target_node(Node* node) const override { + return node->is_Opaque1(); + } + + void target_node_action(Node* target_node) override { + if (target_node->is_OpaqueLoopInit()) { + assert(!_found_init, "should only find one OpaqueLoopInitNode"); + _found_init = true; + } else { + assert(target_node->is_OpaqueLoopStride(), "unexpected Opaque1 node"); + assert(!_found_stride, "should only find one OpaqueLoopStrideNode"); + _found_stride = true; + } + } +}; + +// Verify that the Template Assertion Predicate has the correct OpaqueLoop*Nodes. +void TemplateAssertionPredicate::verify() const { + OpaqueLoopNodesVerifier opaque_loop_nodes_verifier; + opaque_loop_nodes_verifier.verify(*this); +} + +// Verify that the Initialized Assertion Predicate has no OpaqueLoop*Node. +void InitializedAssertionPredicate::verify() const { + OpaqueLoopNodesVerifier opaque_loop_nodes_verifier; + opaque_loop_nodes_verifier.verify(*this); +} +#endif // ASSERT + // Initialized Assertion Predicates always have the dedicated OpaqueInitiailizedAssertionPredicate node to identify // them. bool InitializedAssertionPredicate::is_predicate(Node* node) { @@ -418,36 +480,38 @@ TemplateAssertionExpression::clone(const TransformStrategyForOpaqueLoopNodes& tr // This class is used to replace the input to OpaqueLoopStrideNode with a new node while leaving the other nodes // unchanged. -class ReplaceOpaqueStrideInput : public StackObj { +class ReplaceOpaqueStrideInput : public BFSActions { + Node* _new_opaque_stride_input; PhaseIterGVN& _igvn; - Unique_Node_List _nodes_to_visit; public: - ReplaceOpaqueStrideInput(OpaqueTemplateAssertionPredicateNode* start_node, PhaseIterGVN& igvn) : _igvn(igvn) { - _nodes_to_visit.push(start_node); - } + ReplaceOpaqueStrideInput(Node* new_opaque_stride_input, PhaseIterGVN& igvn) + : _new_opaque_stride_input(new_opaque_stride_input), + _igvn(igvn) {} NONCOPYABLE(ReplaceOpaqueStrideInput); - void replace(Node* new_opaque_stride_input) { - for (uint i = 0; i < _nodes_to_visit.size(); i++) { - Node* next = _nodes_to_visit[i]; - for (uint j = 1; j < next->req(); j++) { - Node* input = next->in(j); - if (input->is_OpaqueLoopStride()) { - assert(TemplateAssertionExpressionNode::is_maybe_in_expression(input), "must also pass node filter"); - _igvn.replace_input_of(input, 1, new_opaque_stride_input); - } else if (TemplateAssertionExpressionNode::is_maybe_in_expression(input)) { - _nodes_to_visit.push(input); - } - } - } + void replace_for(OpaqueTemplateAssertionPredicateNode* opaque_node) { + DataNodeBFS bfs(*this); + bfs.run(opaque_node); + } + + bool should_visit(Node* node) const override { + return TemplateAssertionExpressionNode::is_maybe_in_expression(node); + } + + bool is_target_node(Node* node) const override { + return node->is_OpaqueLoopStride(); + } + + void target_node_action(Node* target_node) override { + _igvn.replace_input_of(target_node, 1, _new_opaque_stride_input); } }; // Replace the input to OpaqueLoopStrideNode with 'new_stride' and leave the other nodes unchanged. void TemplateAssertionExpression::replace_opaque_stride_input(Node* new_stride, PhaseIterGVN& igvn) { - ReplaceOpaqueStrideInput replace_opaque_stride_input(_opaque_node, igvn); - replace_opaque_stride_input.replace(new_stride); + ReplaceOpaqueStrideInput replace_opaque_stride_input(new_stride, igvn); + replace_opaque_stride_input.replace_for(_opaque_node); } // The transformations of this class fold the OpaqueLoop* nodes by returning their inputs. @@ -676,10 +740,15 @@ IfTrueNode* TemplateAssertionPredicateCreator::create(Node* new_control) { IfTrueNode* template_predicate_success_proj = create_if_node(new_control, template_assertion_predicate_expression, does_overflow, AssertionPredicateType::InitValue); + DEBUG_ONLY(TemplateAssertionPredicate::verify(template_predicate_success_proj);) + template_assertion_predicate_expression = create_for_last_value(template_predicate_success_proj, opaque_init, does_overflow); - return create_if_node(template_predicate_success_proj, template_assertion_predicate_expression, - does_overflow, AssertionPredicateType::LastValue); + template_predicate_success_proj = create_if_node(template_predicate_success_proj, + template_assertion_predicate_expression, does_overflow, + AssertionPredicateType::LastValue); + DEBUG_ONLY(TemplateAssertionPredicate::verify(template_predicate_success_proj);) + return template_predicate_success_proj; } InitializedAssertionPredicateCreator::InitializedAssertionPredicateCreator(PhaseIdealLoop* phase) @@ -735,8 +804,10 @@ IfTrueNode* InitializedAssertionPredicateCreator::create(Node* operand, Node* ne bool does_overflow; OpaqueInitializedAssertionPredicateNode* assertion_expression = expression_creator.create_for_initialized(new_control, operand, does_overflow); - return create_control_nodes(new_control, does_overflow ? Op_If : Op_RangeCheck, assertion_expression, - assertion_predicate_type); + IfTrueNode* success_proj = create_control_nodes(new_control, does_overflow ? Op_If : Op_RangeCheck, + assertion_expression, assertion_predicate_type); + DEBUG_ONLY(InitializedAssertionPredicate::verify(success_proj);) + return success_proj; } // Creates the CFG nodes for the Initialized Assertion Predicate. @@ -832,9 +903,13 @@ void CreateAssertionPredicatesVisitor::visit(const TemplateAssertionPredicate& t // Create an Initialized Assertion Predicate from the provided Template Assertion Predicate. IfTrueNode* CreateAssertionPredicatesVisitor::initialize_from_template( const TemplateAssertionPredicate& template_assertion_predicate) const { + DEBUG_ONLY(template_assertion_predicate.verify();) IfNode* template_head = template_assertion_predicate.head(); - IfTrueNode* initialized_predicate = _phase->create_initialized_assertion_predicate(template_head, _init, _stride, - _new_control); + InitializedAssertionPredicateCreator initialized_assertion_predicate_creator(_phase); + IfTrueNode* initialized_predicate = initialized_assertion_predicate_creator.create_from_template(template_head, + _new_control, + _init, _stride); + DEBUG_ONLY(InitializedAssertionPredicate::verify(initialized_predicate);) template_assertion_predicate.rewire_loop_data_dependencies(initialized_predicate, _node_in_loop_body, _phase); return initialized_predicate; } diff --git a/src/hotspot/share/opto/predicates.hpp b/src/hotspot/share/opto/predicates.hpp index 4b8440f5aae..407a931a91c 100644 --- a/src/hotspot/share/opto/predicates.hpp +++ b/src/hotspot/share/opto/predicates.hpp @@ -400,6 +400,15 @@ class TemplateAssertionPredicate : public Predicate { void rewire_loop_data_dependencies(IfTrueNode* target_predicate, const NodeInLoopBody& data_in_loop_body, PhaseIdealLoop* phase) const; static bool is_predicate(Node* node); + +#ifdef ASSERT + static void verify(IfTrueNode* template_assertion_predicate_success_proj) { + TemplateAssertionPredicate template_assertion_predicate(template_assertion_predicate_success_proj); + template_assertion_predicate.verify(); + } + + void verify() const; +#endif // ASSERT }; // Class to represent an Initialized Assertion Predicate which always has a halt node on the failing path. @@ -419,6 +428,10 @@ class InitializedAssertionPredicate : public Predicate { return _if_node->in(0); } + OpaqueInitializedAssertionPredicateNode* opaque_node() const { + return _if_node->in(1)->as_OpaqueInitializedAssertionPredicate(); + } + IfNode* head() const override { return _if_node; } @@ -433,6 +446,15 @@ class InitializedAssertionPredicate : public Predicate { void kill(PhaseIdealLoop* phase) const; static bool is_predicate(Node* node); + +#ifdef ASSERT + static void verify(IfTrueNode* initialized_assertion_predicate_success_proj) { + InitializedAssertionPredicate initialized_assertion_predicate(initialized_assertion_predicate_success_proj); + initialized_assertion_predicate.verify(); + } + + void verify() const; +#endif // ASSERT }; // Interface to transform OpaqueLoopInit and OpaqueLoopStride nodes of a Template Assertion Expression. From 4d898aa451db5b57601c088cdc3c947827f0bc08 Mon Sep 17 00:00:00 2001 From: Phil Race <prr@openjdk.org> Date: Mon, 25 Nov 2024 19:31:22 +0000 Subject: [PATCH 226/311] 8344896: Remove obsolete checks for AWTPermission accessClipboard Reviewed-by: azvegint --- .../macosx/classes/sun/lwawt/LWToolkit.java | 6 - .../share/classes/java/awt/TextComponent.java | 15 -- .../classes/java/awt/event/InputEvent.java | 23 +-- .../javax/swing/text/DefaultCaret.java | 15 +- .../sun/awt/dnd/SunDropTargetContextPeer.java | 12 -- .../classes/sun/swing/SwingUtilities2.java | 144 +----------------- .../unix/classes/sun/awt/X11/XToolkit.java | 12 -- .../sun/awt/windows/WTextComponentPeer.java | 9 -- .../classes/sun/awt/windows/WToolkit.java | 6 - .../libawt/windows/awt_TextComponent.cpp | 47 +----- .../native/libawt/windows/awt_TextComponent.h | 1 - 11 files changed, 10 insertions(+), 280 deletions(-) diff --git a/src/java.desktop/macosx/classes/sun/lwawt/LWToolkit.java b/src/java.desktop/macosx/classes/sun/lwawt/LWToolkit.java index 0de6b213299..5c8148a668f 100644 --- a/src/java.desktop/macosx/classes/sun/lwawt/LWToolkit.java +++ b/src/java.desktop/macosx/classes/sun/lwawt/LWToolkit.java @@ -407,12 +407,6 @@ public final PrintJob getPrintJob(Frame frame, String doctitle, @Override public final Clipboard getSystemClipboard() { - @SuppressWarnings("removal") - SecurityManager security = System.getSecurityManager(); - if (security != null) { - security.checkPermission(AWTPermissions.ACCESS_CLIPBOARD_PERMISSION); - } - synchronized (this) { if (clipboard == null) { clipboard = createPlatformClipboard(); diff --git a/src/java.desktop/share/classes/java/awt/TextComponent.java b/src/java.desktop/share/classes/java/awt/TextComponent.java index 9c33172d9f5..20c129795a2 100644 --- a/src/java.desktop/share/classes/java/awt/TextComponent.java +++ b/src/java.desktop/share/classes/java/awt/TextComponent.java @@ -44,7 +44,6 @@ import javax.accessibility.AccessibleText; import javax.swing.text.AttributeSet; -import sun.awt.AWTPermissions; import sun.awt.InputMethodSupport; /** @@ -744,20 +743,6 @@ protected String paramString() { return str + ",selection=" + getSelectionStart() + "-" + getSelectionEnd(); } - /** - * Assigns a valid value to the canAccessClipboard instance variable. - */ - private boolean canAccessClipboard() { - @SuppressWarnings("removal") - SecurityManager sm = System.getSecurityManager(); - if (sm == null) return true; - try { - sm.checkPermission(AWTPermissions.ACCESS_CLIPBOARD_PERMISSION); - return true; - } catch (SecurityException e) {} - return false; - } - /* * Serialization support. */ diff --git a/src/java.desktop/share/classes/java/awt/event/InputEvent.java b/src/java.desktop/share/classes/java/awt/event/InputEvent.java index 58adec9f635..3da01fd639c 100644 --- a/src/java.desktop/share/classes/java/awt/event/InputEvent.java +++ b/src/java.desktop/share/classes/java/awt/event/InputEvent.java @@ -33,7 +33,6 @@ import java.util.Arrays; import sun.awt.AWTAccessor; -import sun.awt.AWTPermissions; import sun.util.logging.PlatformLogger; /** @@ -313,6 +312,7 @@ public static int getMaskForButton(int button) { /* * A flag that indicates that this instance can be used to access * the system clipboard. + * This should be false in a headless environment, true in a headful one. */ private transient boolean canAccessSystemClipboard; @@ -385,26 +385,7 @@ public void setCanAccessSystemClipboard(InputEvent event, } private boolean canAccessSystemClipboard() { - boolean b = false; - - if (!GraphicsEnvironment.isHeadless()) { - @SuppressWarnings("removal") - SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - try { - sm.checkPermission(AWTPermissions.ACCESS_CLIPBOARD_PERMISSION); - b = true; - } catch (SecurityException se) { - if (logger.isLoggable(PlatformLogger.Level.FINE)) { - logger.fine("InputEvent.canAccessSystemClipboard() got SecurityException ", se); - } - } - } else { - b = true; - } - } - - return b; + return !GraphicsEnvironment.isHeadless(); } /** diff --git a/src/java.desktop/share/classes/javax/swing/text/DefaultCaret.java b/src/java.desktop/share/classes/javax/swing/text/DefaultCaret.java index cf8220efb75..bed18fc3fc3 100644 --- a/src/java.desktop/share/classes/javax/swing/text/DefaultCaret.java +++ b/src/java.desktop/share/classes/javax/swing/text/DefaultCaret.java @@ -467,12 +467,10 @@ public void mouseClicked(MouseEvent e) { // mouse 1 behavior if(nclicks == 1) { selectedWordEvent = null; - } else if(nclicks == 2 - && SwingUtilities2.canEventAccessSystemClipboard(e)) { + } else if (nclicks == 2) { selectWord(e); selectedWordEvent = null; - } else if(nclicks == 3 - && SwingUtilities2.canEventAccessSystemClipboard(e)) { + } else if (nclicks == 3) { Action a = null; ActionMap map = getComponent().getActionMap(); if (map != null) { @@ -489,8 +487,7 @@ public void mouseClicked(MouseEvent e) { } } else if (SwingUtilities.isMiddleMouseButton(e)) { // mouse 2 behavior - if (nclicks == 1 && component.isEditable() && component.isEnabled() - && SwingUtilities2.canEventAccessSystemClipboard(e)) { + if (nclicks == 1 && component.isEditable() && component.isEnabled()) { // paste system selection, if it exists JTextComponent c = (JTextComponent) e.getSource(); if (c != null) { @@ -547,8 +544,7 @@ public void mousePressed(MouseEvent e) { } else { shouldHandleRelease = false; adjustCaretAndFocus(e); - if (nclicks == 2 - && SwingUtilities2.canEventAccessSystemClipboard(e)) { + if (nclicks == 2) { selectWord(e); } } @@ -1394,9 +1390,6 @@ void repaintNewCaret() { } private void updateSystemSelection() { - if ( ! SwingUtilities2.canCurrentEventAccessSystemClipboard() ) { - return; - } if (this.dot != this.mark && component != null && component.hasFocus()) { Clipboard clip = getSystemSelection(); if (clip != null) { diff --git a/src/java.desktop/share/classes/sun/awt/dnd/SunDropTargetContextPeer.java b/src/java.desktop/share/classes/sun/awt/dnd/SunDropTargetContextPeer.java index b0c362acc9e..c6346fddebd 100644 --- a/src/java.desktop/share/classes/sun/awt/dnd/SunDropTargetContextPeer.java +++ b/src/java.desktop/share/classes/sun/awt/dnd/SunDropTargetContextPeer.java @@ -224,18 +224,6 @@ public Object getTransferData(DataFlavor df) InvalidDnDOperationException { - @SuppressWarnings("removal") - SecurityManager sm = System.getSecurityManager(); - try { - if (!dropInProcess && sm != null) { - sm.checkPermission(AWTPermissions.ACCESS_CLIPBOARD_PERMISSION); - } - } catch (Exception e) { - Thread currentThread = Thread.currentThread(); - currentThread.getUncaughtExceptionHandler().uncaughtException(currentThread, e); - return null; - } - Long lFormat = null; Transferable localTransferable = local; diff --git a/src/java.desktop/share/classes/sun/swing/SwingUtilities2.java b/src/java.desktop/share/classes/sun/swing/SwingUtilities2.java index eb35920aad0..7c2b5517e15 100644 --- a/src/java.desktop/share/classes/sun/swing/SwingUtilities2.java +++ b/src/java.desktop/share/classes/sun/swing/SwingUtilities2.java @@ -189,10 +189,6 @@ public static void putAATextInfo(boolean lafCondition, public static final StringUIClientPropertyKey BASICMENUITEMUI_MAX_TEXT_OFFSET = new StringUIClientPropertyKey ("maxTextOffset"); - // security stuff - private static final String UntrustedClipboardAccess = - "UNTRUSTED_CLIPBOARD_ACCESS_KEY"; - //all access to charsBuffer is to be synchronized on charsBufferLock private static final int CHAR_BUFFER_SIZE = 100; private static final Object charsBufferLock = new Object(); @@ -1458,123 +1454,14 @@ public int hashCode() { } } - /* - * here goes the fix for 4856343 [Problem with applet interaction - * with system selection clipboard] - * - * NOTE. In case isTrustedContext() no checking - * are to be performed - */ - /** - * checks the security permissions for accessing system clipboard - * - * for untrusted context (see isTrustedContext) checks the - * permissions for the current event being handled + * checks if the system clipboard can be accessed. + * This is true in a headful environment, false in a headless one * */ public static boolean canAccessSystemClipboard() { - boolean canAccess = false; - if (!GraphicsEnvironment.isHeadless()) { - @SuppressWarnings("removal") - SecurityManager sm = System.getSecurityManager(); - if (sm == null) { - canAccess = true; - } else { - try { - sm.checkPermission(AWTPermissions.ACCESS_CLIPBOARD_PERMISSION); - canAccess = true; - } catch (SecurityException e) { - } - if (canAccess && ! isTrustedContext()) { - canAccess = canCurrentEventAccessSystemClipboard(true); - } - } - } - return canAccess; + return !GraphicsEnvironment.isHeadless(); } - /** - * Returns true if EventQueue.getCurrentEvent() has the permissions to - * access the system clipboard - */ - public static boolean canCurrentEventAccessSystemClipboard() { - return isTrustedContext() - || canCurrentEventAccessSystemClipboard(false); - } - - /** - * Returns true if the given event has permissions to access the - * system clipboard - * - * @param e AWTEvent to check - */ - public static boolean canEventAccessSystemClipboard(AWTEvent e) { - return isTrustedContext() - || canEventAccessSystemClipboard(e, false); - } - - /** - * Returns true if the given event is current gesture for - * accessing clipboard - * - * @param ie InputEvent to check - */ - @SuppressWarnings("deprecation") - private static boolean isAccessClipboardGesture(InputEvent ie) { - boolean allowedGesture = false; - if (ie instanceof KeyEvent) { //we can validate only keyboard gestures - KeyEvent ke = (KeyEvent)ie; - int keyCode = ke.getKeyCode(); - int keyModifiers = ke.getModifiers(); - switch(keyCode) { - case KeyEvent.VK_C: - case KeyEvent.VK_V: - case KeyEvent.VK_X: - allowedGesture = (keyModifiers == InputEvent.CTRL_MASK); - break; - case KeyEvent.VK_INSERT: - allowedGesture = (keyModifiers == InputEvent.CTRL_MASK || - keyModifiers == InputEvent.SHIFT_MASK); - break; - case KeyEvent.VK_COPY: - case KeyEvent.VK_PASTE: - case KeyEvent.VK_CUT: - allowedGesture = true; - break; - case KeyEvent.VK_DELETE: - allowedGesture = ( keyModifiers == InputEvent.SHIFT_MASK); - break; - } - } - return allowedGesture; - } - - /** - * Returns true if e has the permissions to - * access the system clipboard and if it is allowed gesture (if - * checkGesture is true) - * - * @param e AWTEvent to check - * @param checkGesture boolean - */ - private static boolean canEventAccessSystemClipboard(AWTEvent e, - boolean checkGesture) { - if (EventQueue.isDispatchThread()) { - /* - * Checking event permissions makes sense only for event - * dispatching thread - */ - if (e instanceof InputEvent - && (! checkGesture || isAccessClipboardGesture((InputEvent)e))) { - return AWTAccessor.getInputEventAccessor(). - canAccessSystemClipboard((InputEvent) e); - } else { - return false; - } - } else { - return true; - } - } /** * Utility method that throws SecurityException if SecurityManager is set @@ -1590,31 +1477,6 @@ public static void checkAccess(int modifiers) { } } - /** - * Returns true if EventQueue.getCurrentEvent() has the permissions to - * access the system clipboard and if it is allowed gesture (if - * checkGesture true) - * - * @param checkGesture boolean - */ - private static boolean canCurrentEventAccessSystemClipboard(boolean - checkGesture) { - AWTEvent event = EventQueue.getCurrentEvent(); - return canEventAccessSystemClipboard(event, checkGesture); - } - - /** - * see RFE 5012841 [Per AppContect security permissions] for the - * details - * - */ - @SuppressWarnings("removal") - private static boolean isTrustedContext() { - return (System.getSecurityManager() == null) - || (AppContext.getAppContext(). - get(UntrustedClipboardAccess) == null); - } - public static String displayPropertiesToCSS(Font font, Color fg) { StringBuilder rule = new StringBuilder("body {"); if (font != null) { diff --git a/src/java.desktop/unix/classes/sun/awt/X11/XToolkit.java b/src/java.desktop/unix/classes/sun/awt/X11/XToolkit.java index 5a2a849b757..bc6275aaacc 100644 --- a/src/java.desktop/unix/classes/sun/awt/X11/XToolkit.java +++ b/src/java.desktop/unix/classes/sun/awt/X11/XToolkit.java @@ -114,7 +114,6 @@ import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; -import java.util.Hashtable; import java.util.Iterator; import java.util.LinkedList; import java.util.Map; @@ -129,7 +128,6 @@ import javax.swing.UIDefaults; import sun.awt.AWTAccessor; -import sun.awt.AWTPermissions; import sun.awt.AppContext; import sun.awt.DisplayChangedListener; import sun.awt.LightweightFrame; @@ -1233,11 +1231,6 @@ public boolean getLockingKeyState(int key) { @Override public Clipboard getSystemClipboard() { - @SuppressWarnings("removal") - SecurityManager security = System.getSecurityManager(); - if (security != null) { - security.checkPermission(AWTPermissions.ACCESS_CLIPBOARD_PERMISSION); - } synchronized (this) { if (clipboard == null) { clipboard = new XClipboard("System", "CLIPBOARD"); @@ -1248,11 +1241,6 @@ public Clipboard getSystemClipboard() { @Override public Clipboard getSystemSelection() { - @SuppressWarnings("removal") - SecurityManager security = System.getSecurityManager(); - if (security != null) { - security.checkPermission(AWTPermissions.ACCESS_CLIPBOARD_PERMISSION); - } synchronized (this) { if (selection == null) { selection = new XClipboard("Selection", "PRIMARY"); diff --git a/src/java.desktop/windows/classes/sun/awt/windows/WTextComponentPeer.java b/src/java.desktop/windows/classes/sun/awt/windows/WTextComponentPeer.java index 762672ad48b..e725e7f3754 100644 --- a/src/java.desktop/windows/classes/sun/awt/windows/WTextComponentPeer.java +++ b/src/java.desktop/windows/classes/sun/awt/windows/WTextComponentPeer.java @@ -32,10 +32,6 @@ abstract class WTextComponentPeer extends WComponentPeer implements TextComponentPeer { - static { - initIDs(); - } - // TextComponentPeer implementation @Override @@ -107,11 +103,6 @@ public void valueChanged() { postEvent(new TextEvent(target, TextEvent.TEXT_VALUE_CHANGED)); } - /** - * Initialize JNI field and method IDs - */ - private static native void initIDs(); - @Override public boolean shouldClearRectBeforePaint() { return false; diff --git a/src/java.desktop/windows/classes/sun/awt/windows/WToolkit.java b/src/java.desktop/windows/classes/sun/awt/windows/WToolkit.java index f2fbfa9b77d..1ede804d449 100644 --- a/src/java.desktop/windows/classes/sun/awt/windows/WToolkit.java +++ b/src/java.desktop/windows/classes/sun/awt/windows/WToolkit.java @@ -123,7 +123,6 @@ import sun.awt.AWTAccessor; import sun.awt.AWTAutoShutdown; -import sun.awt.AWTPermissions; import sun.awt.AppContext; import sun.awt.DisplayChangedListener; import sun.awt.LightweightFrame; @@ -678,11 +677,6 @@ public void setLockingKeyState(int key, boolean on) { @Override public Clipboard getSystemClipboard() { - @SuppressWarnings("removal") - SecurityManager security = System.getSecurityManager(); - if (security != null) { - security.checkPermission(AWTPermissions.ACCESS_CLIPBOARD_PERMISSION); - } synchronized (this) { if (clipboard == null) { clipboard = new WClipboard(); diff --git a/src/java.desktop/windows/native/libawt/windows/awt_TextComponent.cpp b/src/java.desktop/windows/native/libawt/windows/awt_TextComponent.cpp index fff4237911c..81d44b9d760 100644 --- a/src/java.desktop/windows/native/libawt/windows/awt_TextComponent.cpp +++ b/src/java.desktop/windows/native/libawt/windows/awt_TextComponent.cpp @@ -53,7 +53,6 @@ struct EnableEditingStruct { * AwtTextComponent fields */ -jmethodID AwtTextComponent::canAccessClipboardMID; AwtTextComponent::OleCallback AwtTextComponent::sm_oleCallback; WNDPROC AwtTextComponent::sm_pDefWindowProc = NULL; @@ -392,31 +391,10 @@ AwtTextComponent::HandleEvent(MSG *msg, BOOL synthetic) return returnVal; } -/* - * If this Paste is occurring because of a synthetic Java event (e.g., - * a synthesized <CTRL>-V KeyEvent), then verify that the TextComponent - * has permission to access the Clipboard before pasting. If permission - * is denied, we should throw a SecurityException, but currently do not - * because when we detect the security violation, we are in the Toolkit - * thread, not the thread which dispatched the illegal event. - */ MsgRouting AwtTextComponent::WmPaste() { - if (m_synthetic) { - JNIEnv *env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); - if (env->EnsureLocalCapacity(1) < 0) { - return mrConsume; - } - jobject target = GetTarget(env); - jboolean canAccessClipboard = - env->CallBooleanMethod (target, AwtTextComponent::canAccessClipboardMID); - env->DeleteLocalRef(target); - return (canAccessClipboard) ? mrDoDefault : mrConsume; - } - else { - return mrDoDefault; - } + return mrDoDefault; } //im --- override to over the spot composition @@ -890,29 +868,6 @@ Java_sun_awt_windows_WTextComponentPeer_enableEditing(JNIEnv *env, CATCH_BAD_ALLOC; } -/* - * Class: sun_awt_windows_WTextComponentPeer - * Method: initIDs - * Signature: ()V - */ -JNIEXPORT void JNICALL -Java_sun_awt_windows_WTextComponentPeer_initIDs(JNIEnv *env, jclass cls) -{ - TRY; - - jclass textComponentClassID = env->FindClass("java/awt/TextComponent"); - CHECK_NULL(textComponentClassID); - - AwtTextComponent::canAccessClipboardMID = - env->GetMethodID(textComponentClassID, "canAccessClipboard", "()Z"); - env->DeleteLocalRef(textComponentClassID); - - DASSERT(AwtTextComponent::canAccessClipboardMID != NULL); - - CATCH_BAD_ALLOC; -} - - /************************************************************************ * Inner class OleCallback definition. */ diff --git a/src/java.desktop/windows/native/libawt/windows/awt_TextComponent.h b/src/java.desktop/windows/native/libawt/windows/awt_TextComponent.h index 2a9eecc4e64..6bc81e3ef45 100644 --- a/src/java.desktop/windows/native/libawt/windows/awt_TextComponent.h +++ b/src/java.desktop/windows/native/libawt/windows/awt_TextComponent.h @@ -41,7 +41,6 @@ class AwtTextComponent : public AwtComponent { public: - static jmethodID canAccessClipboardMID; AwtTextComponent(); From df2d4c157573ae0faca039bfd3c4191475b5f0de Mon Sep 17 00:00:00 2001 From: Roger Riggs <rriggs@openjdk.org> Date: Mon, 25 Nov 2024 19:44:40 +0000 Subject: [PATCH 227/311] 8344898: SM cleanup of java.base sun/util calendar, locale, cldr, and resources Reviewed-by: naoto --- .../sun/util/calendar/ZoneInfoFile.java | 26 ++-- .../util/cldr/CLDRLocaleProviderAdapter.java | 47 ++---- .../provider/AuxLocaleProviderAdapter.java | 8 +- .../FallbackLocaleProviderAdapter.java | 9 +- .../provider/JRELocaleProviderAdapter.java | 140 ++++++------------ .../provider/SPILocaleProviderAdapter.java | 59 +++----- .../BreakIteratorResourceBundle.java | 20 +-- .../classes/sun/util/resources/Bundles.java | 39 ++--- .../sun/util/resources/LocaleData.java | 34 ++--- 9 files changed, 119 insertions(+), 263 deletions(-) diff --git a/src/java.base/share/classes/sun/util/calendar/ZoneInfoFile.java b/src/java.base/share/classes/sun/util/calendar/ZoneInfoFile.java index 8bfb8088108..267b57cc56d 100644 --- a/src/java.base/share/classes/sun/util/calendar/ZoneInfoFile.java +++ b/src/java.base/share/classes/sun/util/calendar/ZoneInfoFile.java @@ -33,8 +33,6 @@ import java.io.FileInputStream; import java.io.IOException; import java.io.StreamCorruptedException; -import java.security.AccessController; -import java.security.PrivilegedAction; import java.time.LocalDateTime; import java.time.ZoneId; import java.time.ZoneOffset; @@ -212,23 +210,17 @@ private ZoneInfoFile() { loadTZDB(); } - @SuppressWarnings("removal") private static void loadTZDB() { - AccessController.doPrivileged(new PrivilegedAction<Void>() { - public Void run() { - try { - String libDir = StaticProperty.javaHome() + File.separator + "lib"; - try (DataInputStream dis = new DataInputStream( - new BufferedInputStream(new FileInputStream( - new File(libDir, "tzdb.dat"))))) { - load(dis); - } - } catch (Exception x) { - throw new Error(x); - } - return null; + try { + String libDir = StaticProperty.javaHome() + File.separator + "lib"; + try (DataInputStream dis = new DataInputStream( + new BufferedInputStream(new FileInputStream( + new File(libDir, "tzdb.dat"))))) { + load(dis); } - }); + } catch (Exception x) { + throw new Error(x); + } } /** diff --git a/src/java.base/share/classes/sun/util/cldr/CLDRLocaleProviderAdapter.java b/src/java.base/share/classes/sun/util/cldr/CLDRLocaleProviderAdapter.java index 0ce080c2054..573187ba3d0 100644 --- a/src/java.base/share/classes/sun/util/cldr/CLDRLocaleProviderAdapter.java +++ b/src/java.base/share/classes/sun/util/cldr/CLDRLocaleProviderAdapter.java @@ -25,10 +25,6 @@ package sun.util.cldr; -import java.security.AccessController; -import java.security.PrivilegedAction; -import java.security.PrivilegedActionException; -import java.security.PrivilegedExceptionAction; import java.text.spi.BreakIteratorProvider; import java.text.spi.CollatorProvider; import java.util.Arrays; @@ -75,24 +71,14 @@ public class CLDRLocaleProviderAdapter extends JRELocaleProviderAdapter { parentLocalesMap.put(Locale.US, Locale.US); } - @SuppressWarnings("removal") public CLDRLocaleProviderAdapter() { - LocaleDataMetaInfo nbmi; - - try { - nbmi = AccessController.doPrivileged((PrivilegedExceptionAction<LocaleDataMetaInfo>) () -> { - for (LocaleDataMetaInfo ldmi : ServiceLoader.loadInstalled(LocaleDataMetaInfo.class)) { - if (ldmi.getType() == Type.CLDR) { - return ldmi; - } - } - return null; - }); - } catch (PrivilegedActionException pae) { - throw new InternalError(pae.getCause()); + for (LocaleDataMetaInfo ldmi : ServiceLoader.loadInstalled(LocaleDataMetaInfo.class)) { + if (ldmi.getType() == Type.CLDR) { + nonBaseMetaInfo = ldmi; + return; + } } - - nonBaseMetaInfo = nbmi; + nonBaseMetaInfo = null; } /** @@ -112,12 +98,9 @@ public BreakIteratorProvider getBreakIteratorProvider() { @Override public CalendarDataProvider getCalendarDataProvider() { if (calendarDataProvider == null) { - @SuppressWarnings("removal") - CalendarDataProvider provider = AccessController.doPrivileged( - (PrivilegedAction<CalendarDataProvider>) () -> - new CLDRCalendarDataProviderImpl( + CalendarDataProvider provider = new CLDRCalendarDataProviderImpl( getAdapterType(), - getLanguageTagSet("CalendarData"))); + getLanguageTagSet("CalendarData")); synchronized (this) { if (calendarDataProvider == null) { @@ -131,12 +114,9 @@ public CalendarDataProvider getCalendarDataProvider() { @Override public CalendarNameProvider getCalendarNameProvider() { if (calendarNameProvider == null) { - @SuppressWarnings("removal") - CalendarNameProvider provider = AccessController.doPrivileged( - (PrivilegedAction<CalendarNameProvider>) () - -> new CLDRCalendarNameProviderImpl( + CalendarNameProvider provider = new CLDRCalendarNameProviderImpl( getAdapterType(), - getLanguageTagSet("FormatData"))); + getLanguageTagSet("FormatData")); synchronized (this) { if (calendarNameProvider == null) { @@ -155,12 +135,9 @@ public CollatorProvider getCollatorProvider() { @Override public TimeZoneNameProvider getTimeZoneNameProvider() { if (timeZoneNameProvider == null) { - @SuppressWarnings("removal") - TimeZoneNameProvider provider = AccessController.doPrivileged( - (PrivilegedAction<TimeZoneNameProvider>) () -> - new CLDRTimeZoneNameProviderImpl( + TimeZoneNameProvider provider = new CLDRTimeZoneNameProviderImpl( getAdapterType(), - getLanguageTagSet("TimeZoneNames"))); + getLanguageTagSet("TimeZoneNames")); synchronized (this) { if (timeZoneNameProvider == null) { diff --git a/src/java.base/share/classes/sun/util/locale/provider/AuxLocaleProviderAdapter.java b/src/java.base/share/classes/sun/util/locale/provider/AuxLocaleProviderAdapter.java index f26cd8d73f4..f739cb613af 100644 --- a/src/java.base/share/classes/sun/util/locale/provider/AuxLocaleProviderAdapter.java +++ b/src/java.base/share/classes/sun/util/locale/provider/AuxLocaleProviderAdapter.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,8 +25,6 @@ package sun.util.locale.provider; -import java.security.AccessController; -import java.security.PrivilegedAction; import java.text.spi.BreakIteratorProvider; import java.text.spi.CollatorProvider; import java.text.spi.DateFormatProvider; @@ -186,9 +184,7 @@ public Locale[] getAvailableLocales() { * A dummy locale service provider that indicates there is no * provider available */ - @SuppressWarnings("removal") - private static final NullProvider NULL_PROVIDER = AccessController.doPrivileged( - (PrivilegedAction<NullProvider>) () -> new NullProvider()); + private static final NullProvider NULL_PROVIDER = new NullProvider(); private static class NullProvider extends LocaleServiceProvider { @Override diff --git a/src/java.base/share/classes/sun/util/locale/provider/FallbackLocaleProviderAdapter.java b/src/java.base/share/classes/sun/util/locale/provider/FallbackLocaleProviderAdapter.java index 8ee95c567aa..0637be76781 100644 --- a/src/java.base/share/classes/sun/util/locale/provider/FallbackLocaleProviderAdapter.java +++ b/src/java.base/share/classes/sun/util/locale/provider/FallbackLocaleProviderAdapter.java @@ -25,8 +25,6 @@ package sun.util.locale.provider; -import java.security.AccessController; -import java.security.PrivilegedAction; import java.text.spi.BreakIteratorProvider; import java.util.Arrays; import java.util.HashSet; @@ -85,12 +83,9 @@ public boolean isSupportedProviderLocale(Locale locale, Set<String> langtags) { // In order to correctly report supported locales public BreakIteratorProvider getBreakIteratorProvider() { if (breakIteratorProvider == null) { - @SuppressWarnings("removal") - BreakIteratorProvider provider = AccessController.doPrivileged( - (PrivilegedAction<BreakIteratorProvider>) () -> - new BreakIteratorProviderImpl( + BreakIteratorProvider provider = new BreakIteratorProviderImpl( getAdapterType(), - getLanguageTagSet("BreakIteratorRules"))); + getLanguageTagSet("BreakIteratorRules")); synchronized (this) { if (breakIteratorProvider == null) { diff --git a/src/java.base/share/classes/sun/util/locale/provider/JRELocaleProviderAdapter.java b/src/java.base/share/classes/sun/util/locale/provider/JRELocaleProviderAdapter.java index 1dd927b8729..14d36f0e266 100644 --- a/src/java.base/share/classes/sun/util/locale/provider/JRELocaleProviderAdapter.java +++ b/src/java.base/share/classes/sun/util/locale/provider/JRELocaleProviderAdapter.java @@ -25,10 +25,6 @@ package sun.util.locale.provider; -import java.security.AccessController; -import java.security.PrivilegedAction; -import java.security.PrivilegedActionException; -import java.security.PrivilegedExceptionAction; import java.text.spi.BreakIteratorProvider; import java.text.spi.CollatorProvider; import java.text.spi.DateFormatProvider; @@ -139,12 +135,9 @@ public <P extends LocaleServiceProvider> P getLocaleServiceProvider(Class<P> c) @Override public BreakIteratorProvider getBreakIteratorProvider() { if (breakIteratorProvider == null) { - @SuppressWarnings("removal") - BreakIteratorProvider provider = AccessController.doPrivileged( - (PrivilegedAction<BreakIteratorProvider>) () -> - new BreakIteratorProviderImpl( - getAdapterType(), - getLanguageTagSet("FormatData"))); + BreakIteratorProvider provider = new BreakIteratorProviderImpl( + getAdapterType(), + getLanguageTagSet("FormatData")); synchronized (this) { if (breakIteratorProvider == null) { @@ -158,12 +151,9 @@ public BreakIteratorProvider getBreakIteratorProvider() { @Override public CollatorProvider getCollatorProvider() { if (collatorProvider == null) { - @SuppressWarnings("removal") - CollatorProvider provider = AccessController.doPrivileged( - (PrivilegedAction<CollatorProvider>) () -> - new CollatorProviderImpl( - getAdapterType(), - getLanguageTagSet("CollationData"))); + CollatorProvider provider = new CollatorProviderImpl( + getAdapterType(), + getLanguageTagSet("CollationData")); synchronized (this) { if (collatorProvider == null) { @@ -177,12 +167,9 @@ public CollatorProvider getCollatorProvider() { @Override public DateFormatProvider getDateFormatProvider() { if (dateFormatProvider == null) { - @SuppressWarnings("removal") - DateFormatProvider provider = AccessController.doPrivileged( - (PrivilegedAction<DateFormatProvider>) () -> - new DateFormatProviderImpl( - getAdapterType(), - getLanguageTagSet("FormatData"))); + DateFormatProvider provider = new DateFormatProviderImpl( + getAdapterType(), + getLanguageTagSet("FormatData")); synchronized (this) { if (dateFormatProvider == null) { @@ -196,12 +183,9 @@ public DateFormatProvider getDateFormatProvider() { @Override public DateFormatSymbolsProvider getDateFormatSymbolsProvider() { if (dateFormatSymbolsProvider == null) { - @SuppressWarnings("removal") - DateFormatSymbolsProvider provider = AccessController.doPrivileged( - (PrivilegedAction<DateFormatSymbolsProvider>) () -> - new DateFormatSymbolsProviderImpl( - getAdapterType(), - getLanguageTagSet("FormatData"))); + DateFormatSymbolsProvider provider = new DateFormatSymbolsProviderImpl( + getAdapterType(), + getLanguageTagSet("FormatData")); synchronized (this) { if (dateFormatSymbolsProvider == null) { @@ -215,12 +199,9 @@ public DateFormatSymbolsProvider getDateFormatSymbolsProvider() { @Override public DecimalFormatSymbolsProvider getDecimalFormatSymbolsProvider() { if (decimalFormatSymbolsProvider == null) { - @SuppressWarnings("removal") - DecimalFormatSymbolsProvider provider = AccessController.doPrivileged( - (PrivilegedAction<DecimalFormatSymbolsProvider>) () -> - new DecimalFormatSymbolsProviderImpl( - getAdapterType(), - getLanguageTagSet("FormatData"))); + DecimalFormatSymbolsProvider provider = new DecimalFormatSymbolsProviderImpl( + getAdapterType(), + getLanguageTagSet("FormatData")); synchronized (this) { if (decimalFormatSymbolsProvider == null) { @@ -234,12 +215,9 @@ public DecimalFormatSymbolsProvider getDecimalFormatSymbolsProvider() { @Override public NumberFormatProvider getNumberFormatProvider() { if (numberFormatProvider == null) { - @SuppressWarnings("removal") - NumberFormatProvider provider = AccessController.doPrivileged( - (PrivilegedAction<NumberFormatProvider>) () -> - new NumberFormatProviderImpl( + NumberFormatProvider provider = new NumberFormatProviderImpl( getAdapterType(), - getLanguageTagSet("FormatData"))); + getLanguageTagSet("FormatData")); synchronized (this) { if (numberFormatProvider == null) { @@ -256,12 +234,9 @@ public NumberFormatProvider getNumberFormatProvider() { @Override public CurrencyNameProvider getCurrencyNameProvider() { if (currencyNameProvider == null) { - @SuppressWarnings("removal") - CurrencyNameProvider provider = AccessController.doPrivileged( - (PrivilegedAction<CurrencyNameProvider>) () -> - new CurrencyNameProviderImpl( + CurrencyNameProvider provider = new CurrencyNameProviderImpl( getAdapterType(), - getLanguageTagSet("CurrencyNames"))); + getLanguageTagSet("CurrencyNames")); synchronized (this) { if (currencyNameProvider == null) { @@ -275,12 +250,9 @@ public CurrencyNameProvider getCurrencyNameProvider() { @Override public LocaleNameProvider getLocaleNameProvider() { if (localeNameProvider == null) { - @SuppressWarnings("removal") - LocaleNameProvider provider = AccessController.doPrivileged( - (PrivilegedAction<LocaleNameProvider>) () -> - new LocaleNameProviderImpl( + LocaleNameProvider provider = new LocaleNameProviderImpl( getAdapterType(), - getLanguageTagSet("LocaleNames"))); + getLanguageTagSet("LocaleNames")); synchronized (this) { if (localeNameProvider == null) { @@ -294,12 +266,9 @@ public LocaleNameProvider getLocaleNameProvider() { @Override public TimeZoneNameProvider getTimeZoneNameProvider() { if (timeZoneNameProvider == null) { - @SuppressWarnings("removal") - TimeZoneNameProvider provider = AccessController.doPrivileged( - (PrivilegedAction<TimeZoneNameProvider>) () -> - new TimeZoneNameProviderImpl( + TimeZoneNameProvider provider = new TimeZoneNameProviderImpl( getAdapterType(), - getLanguageTagSet("TimeZoneNames"))); + getLanguageTagSet("TimeZoneNames")); synchronized (this) { if (timeZoneNameProvider == null) { @@ -313,12 +282,9 @@ public TimeZoneNameProvider getTimeZoneNameProvider() { @Override public CalendarDataProvider getCalendarDataProvider() { if (calendarDataProvider == null) { - @SuppressWarnings("removal") - CalendarDataProvider provider = AccessController.doPrivileged( - (PrivilegedAction<CalendarDataProvider>) () -> - new CalendarDataProviderImpl( + CalendarDataProvider provider = new CalendarDataProviderImpl( getAdapterType(), - getLanguageTagSet("CalendarData"))); + getLanguageTagSet("CalendarData")); synchronized (this) { if (calendarDataProvider == null) { @@ -332,12 +298,9 @@ public CalendarDataProvider getCalendarDataProvider() { @Override public CalendarNameProvider getCalendarNameProvider() { if (calendarNameProvider == null) { - @SuppressWarnings("removal") - CalendarNameProvider provider = AccessController.doPrivileged( - (PrivilegedAction<CalendarNameProvider>) () -> - new CalendarNameProviderImpl( + CalendarNameProvider provider = new CalendarNameProviderImpl( getAdapterType(), - getLanguageTagSet("FormatData"))); + getLanguageTagSet("FormatData")); synchronized (this) { if (calendarNameProvider == null) { @@ -354,12 +317,9 @@ public CalendarNameProvider getCalendarNameProvider() { @Override public CalendarProvider getCalendarProvider() { if (calendarProvider == null) { - @SuppressWarnings("removal") - CalendarProvider provider = AccessController.doPrivileged( - (PrivilegedAction<CalendarProvider>) () -> - new CalendarProviderImpl( + CalendarProvider provider = new CalendarProviderImpl( getAdapterType(), - getLanguageTagSet("CalendarData"))); + getLanguageTagSet("CalendarData")); synchronized (this) { if (calendarProvider == null) { @@ -376,12 +336,9 @@ public CalendarProvider getCalendarProvider() { @Override public JavaTimeDateTimePatternProvider getJavaTimeDateTimePatternProvider() { if (javaTimeDateTimePatternProvider == null) { - @SuppressWarnings("removal") - JavaTimeDateTimePatternProvider provider = AccessController.doPrivileged( - (PrivilegedAction<JavaTimeDateTimePatternProvider>) () - -> new JavaTimeDateTimePatternImpl( + JavaTimeDateTimePatternProvider provider = new JavaTimeDateTimePatternImpl( getAdapterType(), - getLanguageTagSet("FormatData"))); + getLanguageTagSet("FormatData")); synchronized (this) { if (javaTimeDateTimePatternProvider == null) { @@ -461,30 +418,23 @@ private static String createSupportedLocaleString(String category) { String supportedLocaleString = BaseLocaleDataMetaInfo.getSupportedLocaleString(category); // Use ServiceLoader to dynamically acquire installed locales' tags. - try { - @SuppressWarnings("removal") - String nonBaseTags = AccessController.doPrivileged((PrivilegedExceptionAction<String>) () -> { - StringBuilder tags = new StringBuilder(); - for (LocaleDataMetaInfo ldmi : - ServiceLoader.loadInstalled(LocaleDataMetaInfo.class)) { - if (ldmi.getType() == LocaleProviderAdapter.Type.JRE) { - String t = ldmi.availableLanguageTags(category); - if (t != null) { - if (!tags.isEmpty()) { - tags.append(' '); - } - tags.append(t); - } + StringBuilder tags = new StringBuilder(); + for (LocaleDataMetaInfo ldmi : + ServiceLoader.loadInstalled(LocaleDataMetaInfo.class)) { + if (ldmi.getType() == LocaleProviderAdapter.Type.JRE) { + String t = ldmi.availableLanguageTags(category); + if (t != null) { + if (!tags.isEmpty()) { + tags.append(' '); } + tags.append(t); } - return tags.toString(); - }); - - if (nonBaseTags != null) { - supportedLocaleString += " " + nonBaseTags; } - } catch (PrivilegedActionException pae) { - throw new InternalError(pae.getCause()); + } + String nonBaseTags = tags.toString(); + + if (nonBaseTags != null) { + supportedLocaleString += " " + nonBaseTags; } return supportedLocaleString; diff --git a/src/java.base/share/classes/sun/util/locale/provider/SPILocaleProviderAdapter.java b/src/java.base/share/classes/sun/util/locale/provider/SPILocaleProviderAdapter.java index 65b1b75a87c..019e72b4d1c 100644 --- a/src/java.base/share/classes/sun/util/locale/provider/SPILocaleProviderAdapter.java +++ b/src/java.base/share/classes/sun/util/locale/provider/SPILocaleProviderAdapter.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,9 +25,6 @@ package sun.util.locale.provider; -import java.security.AccessController; -import java.security.PrivilegedActionException; -import java.security.PrivilegedExceptionAction; import java.text.BreakIterator; import java.text.Collator; import java.text.DateFormat; @@ -69,43 +66,31 @@ public LocaleProviderAdapter.Type getAdapterType() { return LocaleProviderAdapter.Type.SPI; } - @SuppressWarnings("removal") @Override + @SuppressWarnings(value={"unchecked", "deprecation"}) protected <P extends LocaleServiceProvider> P findInstalledProvider(final Class<P> c) { - try { - return AccessController.doPrivileged(new PrivilegedExceptionAction<>() { - @Override - @SuppressWarnings(value={"unchecked", "deprecation"}) - public P run() { - P delegate = null; - - for (LocaleServiceProvider provider : - ServiceLoader.load(c, ClassLoader.getSystemClassLoader())) { - if (delegate == null) { - try { - delegate = - (P) Class.forName(SPILocaleProviderAdapter.class.getCanonicalName() + - "$" + - c.getSimpleName() + - "Delegate") - .newInstance(); - } catch (ClassNotFoundException | - InstantiationException | - IllegalAccessException e) { - throw new ServiceConfigurationError( - "SPI locale provider cannot be instantiated.", e); - } - } - - ((Delegate)delegate).addImpl(provider); - } - return delegate; + P delegate = null; + for (LocaleServiceProvider provider : + ServiceLoader.load(c, ClassLoader.getSystemClassLoader())) { + if (delegate == null) { + try { + delegate = + (P) Class.forName(SPILocaleProviderAdapter.class.getCanonicalName() + + "$" + + c.getSimpleName() + + "Delegate") + .newInstance(); + } catch (ClassNotFoundException | + InstantiationException | + IllegalAccessException e) { + throw new ServiceConfigurationError( + "SPI locale provider cannot be instantiated.", e); } - }); - } catch (PrivilegedActionException e) { - throw new ServiceConfigurationError( - "SPI locale provider cannot be instantiated.", e); + } + + ((Delegate)delegate).addImpl(provider); } + return delegate; } /* diff --git a/src/java.base/share/classes/sun/util/resources/BreakIteratorResourceBundle.java b/src/java.base/share/classes/sun/util/resources/BreakIteratorResourceBundle.java index f8cf0263fa5..3a55e7ccb8c 100644 --- a/src/java.base/share/classes/sun/util/resources/BreakIteratorResourceBundle.java +++ b/src/java.base/share/classes/sun/util/resources/BreakIteratorResourceBundle.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,9 +26,6 @@ package sun.util.resources; import java.io.InputStream; -import java.security.AccessController; -import java.security.PrivilegedActionException; -import java.security.PrivilegedExceptionAction; import java.util.Collections; import java.util.Enumeration; import java.util.ResourceBundle; @@ -72,7 +69,7 @@ protected Object handleGetObject(String key) { String path = getClass().getPackageName().replace('.', '/') + '/' + info.getString(key); byte[] data; - try (InputStream is = getResourceAsStream(path)) { + try (InputStream is = getClass().getModule().getResourceAsStream(path)) { data = is.readAllBytes(); } catch (Exception e) { throw new InternalError("Can't load " + path, e); @@ -80,19 +77,6 @@ protected Object handleGetObject(String key) { return data; } - @SuppressWarnings("removal") - private InputStream getResourceAsStream(String path) throws Exception { - PrivilegedExceptionAction<InputStream> pa; - pa = () -> getClass().getModule().getResourceAsStream(path); - InputStream is; - try { - is = AccessController.doPrivileged(pa); - } catch (PrivilegedActionException e) { - throw e.getException(); - } - return is; - } - @Override public Enumeration<String> getKeys() { return Collections.enumeration(keySet()); diff --git a/src/java.base/share/classes/sun/util/resources/Bundles.java b/src/java.base/share/classes/sun/util/resources/Bundles.java index 14247f0d347..b36259cf025 100644 --- a/src/java.base/share/classes/sun/util/resources/Bundles.java +++ b/src/java.base/share/classes/sun/util/resources/Bundles.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -42,8 +42,6 @@ import java.lang.ref.ReferenceQueue; import java.lang.ref.SoftReference; -import java.security.AccessController; -import java.security.PrivilegedAction; import java.util.Enumeration; import java.util.Iterator; import java.util.List; @@ -255,32 +253,25 @@ private static void cleanupCache() { /** * Loads ResourceBundle from service providers. */ - @SuppressWarnings("removal") private static ResourceBundle loadBundleFromProviders(String baseName, Locale locale, ServiceLoader<ResourceBundleProvider> providers, CacheKey cacheKey) { - return AccessController.doPrivileged( - new PrivilegedAction<>() { - public ResourceBundle run() { - for (Iterator<ResourceBundleProvider> itr = providers.iterator(); itr.hasNext(); ) { - try { - ResourceBundleProvider provider = itr.next(); - ResourceBundle bundle = provider.getBundle(baseName, locale); - if (bundle != null) { - return bundle; - } - } catch (ServiceConfigurationError | SecurityException e) { - if (cacheKey != null) { - cacheKey.setCause(e); - } - } - } - return null; - } - }); - + for (Iterator<ResourceBundleProvider> itr = providers.iterator(); itr.hasNext(); ) { + try { + ResourceBundleProvider provider = itr.next(); + ResourceBundle bundle = provider.getBundle(baseName, locale); + if (bundle != null) { + return bundle; + } + } catch (ServiceConfigurationError e) { + if (cacheKey != null) { + cacheKey.setCause(e); + } + } + } + return null; } private static boolean isValidBundle(ResourceBundle bundle) { diff --git a/src/java.base/share/classes/sun/util/resources/LocaleData.java b/src/java.base/share/classes/sun/util/resources/LocaleData.java index 7d9af41811c..7bf14343531 100644 --- a/src/java.base/share/classes/sun/util/resources/LocaleData.java +++ b/src/java.base/share/classes/sun/util/resources/LocaleData.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -40,8 +40,6 @@ package sun.util.resources; -import java.security.AccessController; -import java.security.PrivilegedAction; import java.util.Iterator; import java.util.List; import java.util.Locale; @@ -177,31 +175,19 @@ public ResourceBundle getNumberFormatData(Locale locale) { return getBundle(type.getTextResourcesPackage() + ".FormatData", locale); } - @SuppressWarnings("removal") public static ResourceBundle getBundle(final String baseName, final Locale locale) { - return AccessController.doPrivileged(new PrivilegedAction<>() { - @Override - public ResourceBundle run() { - return Bundles.of(baseName, locale, LocaleDataStrategy.INSTANCE); - } - }); + return Bundles.of(baseName, locale, LocaleDataStrategy.INSTANCE); } - @SuppressWarnings("removal") private static OpenListResourceBundle getSupplementary(final String baseName, final Locale locale) { - return AccessController.doPrivileged(new PrivilegedAction<>() { - @Override - public OpenListResourceBundle run() { - OpenListResourceBundle rb = null; - try { - rb = (OpenListResourceBundle) Bundles.of(baseName, locale, - SupplementaryStrategy.INSTANCE); - } catch (MissingResourceException e) { - // return null if no supplementary is available - } - return rb; - } - }); + OpenListResourceBundle rb = null; + try { + rb = (OpenListResourceBundle) Bundles.of(baseName, locale, + SupplementaryStrategy.INSTANCE); + } catch (MissingResourceException e) { + // return null if no supplementary is available + } + return rb; } private abstract static class LocaleDataResourceBundleProvider From 8de158aefe64d493e107ef310f510bab57beb251 Mon Sep 17 00:00:00 2001 From: David Holmes <dholmes@openjdk.org> Date: Mon, 25 Nov 2024 19:55:26 +0000 Subject: [PATCH 228/311] 8339134: Callers of Exceptions::fthrow should ensure exception message lengths avoid the INT_MAX limits of os::vsnprintf Reviewed-by: coleenp, jsjolen --- src/hotspot/share/classfile/classFileError.cpp | 4 ++++ src/hotspot/share/classfile/classFileParser.cpp | 17 +++++++++++++++++ src/hotspot/share/interpreter/linkResolver.cpp | 6 ++++++ src/hotspot/share/oops/constantPool.cpp | 1 + src/hotspot/share/oops/instanceKlass.cpp | 3 +++ src/hotspot/share/runtime/reflection.cpp | 1 + .../share/services/diagnosticArgument.cpp | 17 +++++++++++------ .../share/services/diagnosticArgument.hpp | 1 + src/hotspot/share/utilities/exceptions.cpp | 5 +++++ 9 files changed, 49 insertions(+), 6 deletions(-) diff --git a/src/hotspot/share/classfile/classFileError.cpp b/src/hotspot/share/classfile/classFileError.cpp index 4de5c288955..f6bac278e60 100644 --- a/src/hotspot/share/classfile/classFileError.cpp +++ b/src/hotspot/share/classfile/classFileError.cpp @@ -34,6 +34,10 @@ PRAGMA_DIAG_PUSH PRAGMA_FORMAT_NONLITERAL_IGNORED +// None of the error routines below take in a free-form, potentially unbounded +// string, and names are all limited to < 64K, so we know that all formatted +// strings passed to fthrow will not be excessively large. + void ClassFileParser::classfile_parse_error(const char* msg, TRAPS) const { assert(_class_name != nullptr, "invariant"); ResourceMark rm(THREAD); diff --git a/src/hotspot/share/classfile/classFileParser.cpp b/src/hotspot/share/classfile/classFileParser.cpp index 12e7cf1ae9d..f0586cd7bcc 100644 --- a/src/hotspot/share/classfile/classFileParser.cpp +++ b/src/hotspot/share/classfile/classFileParser.cpp @@ -1794,6 +1794,7 @@ void ClassFileParser::throwIllegalSignature(const char* type, assert(sig != nullptr, "invariant"); ResourceMark rm(THREAD); + // Names are all known to be < 64k so we know this formatted message is not excessively large. Exceptions::fthrow(THREAD_AND_LOCATION, vmSymbols::java_lang_ClassFormatError(), "%s \"%s\" in class %s has illegal signature \"%s\"", type, @@ -4073,6 +4074,8 @@ void ClassFileParser::check_super_class_access(const InstanceKlass* this_klass, char* msg = Reflection::verify_class_access_msg(this_klass, InstanceKlass::cast(super), vca_result); + + // Names are all known to be < 64k so we know this formatted message is not excessively large. if (msg == nullptr) { bool same_module = (this_klass->module() == super->module()); Exceptions::fthrow( @@ -4121,6 +4124,8 @@ void ClassFileParser::check_super_interface_access(const InstanceKlass* this_kla char* msg = Reflection::verify_class_access_msg(this_klass, k, vca_result); + + // Names are all known to be < 64k so we know this formatted message is not excessively large. if (msg == nullptr) { bool same_module = (this_klass->module() == k->module()); Exceptions::fthrow( @@ -4217,6 +4222,8 @@ static void check_illegal_static_method(const InstanceKlass* this_klass, TRAPS) // if m is static and not the init method, throw a verify error if ((m->is_static()) && (m->name() != vmSymbols::class_initializer_name())) { ResourceMark rm(THREAD); + + // Names are all known to be < 64k so we know this formatted message is not excessively large. Exceptions::fthrow( THREAD_AND_LOCATION, vmSymbols::java_lang_VerifyError(), @@ -4236,6 +4243,7 @@ void ClassFileParser::verify_legal_class_modifiers(jint flags, TRAPS) const { assert(_major_version >= JAVA_9_VERSION || !is_module, "JVM_ACC_MODULE should not be set"); if (is_module) { ResourceMark rm(THREAD); + // Names are all known to be < 64k so we know this formatted message is not excessively large. Exceptions::fthrow( THREAD_AND_LOCATION, vmSymbols::java_lang_NoClassDefFoundError(), @@ -4259,6 +4267,7 @@ void ClassFileParser::verify_legal_class_modifiers(jint flags, TRAPS) const { (is_interface && major_gte_1_5 && (is_super || is_enum)) || (!is_interface && major_gte_1_5 && is_annotation)) { ResourceMark rm(THREAD); + // Names are all known to be < 64k so we know this formatted message is not excessively large. Exceptions::fthrow( THREAD_AND_LOCATION, vmSymbols::java_lang_ClassFormatError(), @@ -4295,6 +4304,7 @@ void ClassFileParser::verify_class_version(u2 major, u2 minor, Symbol* class_nam } if (major > max_version) { + // Names are all known to be < 64k so we know this formatted message is not excessively large. Exceptions::fthrow( THREAD_AND_LOCATION, vmSymbols::java_lang_UnsupportedClassVersionError(), @@ -4310,6 +4320,7 @@ void ClassFileParser::verify_class_version(u2 major, u2 minor, Symbol* class_nam if (minor == JAVA_PREVIEW_MINOR_VERSION) { if (major != max_version) { + // Names are all known to be < 64k so we know this formatted message is not excessively large. Exceptions::fthrow( THREAD_AND_LOCATION, vmSymbols::java_lang_UnsupportedClassVersionError(), @@ -4362,6 +4373,7 @@ void ClassFileParser::verify_legal_field_modifiers(jint flags, if (is_illegal) { ResourceMark rm(THREAD); + // Names are all known to be < 64k so we know this formatted message is not excessively large. Exceptions::fthrow( THREAD_AND_LOCATION, vmSymbols::java_lang_ClassFormatError(), @@ -4445,6 +4457,7 @@ void ClassFileParser::verify_legal_method_modifiers(jint flags, if (is_illegal) { ResourceMark rm(THREAD); + // Names are all known to be < 64k so we know this formatted message is not excessively large. Exceptions::fthrow( THREAD_AND_LOCATION, vmSymbols::java_lang_ClassFormatError(), @@ -4686,6 +4699,7 @@ void ClassFileParser::verify_legal_class_name(const Symbol* name, TRAPS) const { if (!legal) { ResourceMark rm(THREAD); assert(_class_name != nullptr, "invariant"); + // Names are all known to be < 64k so we know this formatted message is not excessively large. Exceptions::fthrow( THREAD_AND_LOCATION, vmSymbols::java_lang_ClassFormatError(), @@ -4719,6 +4733,7 @@ void ClassFileParser::verify_legal_field_name(const Symbol* name, TRAPS) const { if (!legal) { ResourceMark rm(THREAD); assert(_class_name != nullptr, "invariant"); + // Names are all known to be < 64k so we know this formatted message is not excessively large. Exceptions::fthrow( THREAD_AND_LOCATION, vmSymbols::java_lang_ClassFormatError(), @@ -4756,6 +4771,7 @@ void ClassFileParser::verify_legal_method_name(const Symbol* name, TRAPS) const if (!legal) { ResourceMark rm(THREAD); assert(_class_name != nullptr, "invariant"); + // Names are all known to be < 64k so we know this formatted message is not excessively large. Exceptions::fthrow( THREAD_AND_LOCATION, vmSymbols::java_lang_ClassFormatError(), @@ -5527,6 +5543,7 @@ void ClassFileParser::parse_stream(const ClassFileStream* const stream, if (_class_name != class_name_in_cp) { if (_class_name != vmSymbols::unknown_class_name()) { ResourceMark rm(THREAD); + // Names are all known to be < 64k so we know this formatted message is not excessively large. Exceptions::fthrow(THREAD_AND_LOCATION, vmSymbols::java_lang_NoClassDefFoundError(), "%s (wrong name: %s)", diff --git a/src/hotspot/share/interpreter/linkResolver.cpp b/src/hotspot/share/interpreter/linkResolver.cpp index 6300b660092..ca8a85c8bba 100644 --- a/src/hotspot/share/interpreter/linkResolver.cpp +++ b/src/hotspot/share/interpreter/linkResolver.cpp @@ -323,6 +323,9 @@ void LinkResolver::check_klass_accessibility(Klass* ref_klass, Klass* sel_klass, char* msg = Reflection::verify_class_access_msg(ref_klass, InstanceKlass::cast(base_klass), vca_result); + + // Names are all known to be < 64k so we know this formatted message is not excessively large. + bool same_module = (base_klass->module() == ref_klass->module()); if (msg == nullptr) { Exceptions::fthrow( @@ -615,6 +618,7 @@ void LinkResolver::check_method_accessability(Klass* ref_klass, print_nest_host_error_on(&ss, ref_klass, sel_klass); } + // Names are all known to be < 64k so we know this formatted message is not excessively large. Exceptions::fthrow(THREAD_AND_LOCATION, vmSymbols::java_lang_IllegalAccessError(), "%s", @@ -968,6 +972,7 @@ void LinkResolver::check_field_accessability(Klass* ref_klass, if (fd.is_private()) { print_nest_host_error_on(&ss, ref_klass, sel_klass); } + // Names are all known to be < 64k so we know this formatted message is not excessively large. Exceptions::fthrow(THREAD_AND_LOCATION, vmSymbols::java_lang_IllegalAccessError(), "%s", @@ -1187,6 +1192,7 @@ Method* LinkResolver::linktime_resolve_special_method(const LinkInfo& link_info, ss.print(" %s(", resolved_method->name()->as_C_string()); resolved_method->signature()->print_as_signature_external_parameters(&ss); ss.print(")' not found"); + // Names are all known to be < 64k so we know this formatted message is not excessively large. Exceptions::fthrow( THREAD_AND_LOCATION, vmSymbols::java_lang_NoSuchMethodError(), diff --git a/src/hotspot/share/oops/constantPool.cpp b/src/hotspot/share/oops/constantPool.cpp index 015ec32700a..31644f33797 100644 --- a/src/hotspot/share/oops/constantPool.cpp +++ b/src/hotspot/share/oops/constantPool.cpp @@ -1266,6 +1266,7 @@ oop ConstantPool::resolve_constant_at_impl(const constantPoolHandle& this_cp, cp_index, callee->is_interface() ? "CONSTANT_MethodRef" : "CONSTANT_InterfaceMethodRef", callee->is_interface() ? "CONSTANT_InterfaceMethodRef" : "CONSTANT_MethodRef"); + // Names are all known to be < 64k so we know this formatted message is not excessively large. Exceptions::fthrow(THREAD_AND_LOCATION, vmSymbols::java_lang_IncompatibleClassChangeError(), "%s", ss.as_string()); save_and_throw_exception(this_cp, cp_index, tag, CHECK_NULL); } diff --git a/src/hotspot/share/oops/instanceKlass.cpp b/src/hotspot/share/oops/instanceKlass.cpp index d2761667f64..9cf48da91b6 100644 --- a/src/hotspot/share/oops/instanceKlass.cpp +++ b/src/hotspot/share/oops/instanceKlass.cpp @@ -899,6 +899,7 @@ bool InstanceKlass::link_class_impl(TRAPS) { // if we are executing Java code. This is not a problem for CDS dumping phase since // it doesn't execute any Java code. ResourceMark rm(THREAD); + // Names are all known to be < 64k so we know this formatted message is not excessively large. Exceptions::fthrow(THREAD_AND_LOCATION, vmSymbols::java_lang_NoClassDefFoundError(), "Class %s, or one of its supertypes, failed class initialization", @@ -919,6 +920,7 @@ bool InstanceKlass::link_class_impl(TRAPS) { if (super_klass != nullptr) { if (super_klass->is_interface()) { // check if super class is an interface ResourceMark rm(THREAD); + // Names are all known to be < 64k so we know this formatted message is not excessively large. Exceptions::fthrow( THREAD_AND_LOCATION, vmSymbols::java_lang_IncompatibleClassChangeError(), @@ -3286,6 +3288,7 @@ InstanceKlass* InstanceKlass::compute_enclosing_class(bool* inner_is_member, TRA // If the outer class is not an instance klass then it cannot have // declared any inner classes. ResourceMark rm(THREAD); + // Names are all known to be < 64k so we know this formatted message is not excessively large. Exceptions::fthrow( THREAD_AND_LOCATION, vmSymbols::java_lang_IncompatibleClassChangeError(), diff --git a/src/hotspot/share/runtime/reflection.cpp b/src/hotspot/share/runtime/reflection.cpp index 97fc26a599f..7739cff03bf 100644 --- a/src/hotspot/share/runtime/reflection.cpp +++ b/src/hotspot/share/runtime/reflection.cpp @@ -697,6 +697,7 @@ void Reflection::check_for_inner_class(const InstanceKlass* outer, const Instanc // 'inner' not declared as an inner klass in outer ResourceMark rm(THREAD); + // Names are all known to be < 64k so we know this formatted message is not excessively large. Exceptions::fthrow( THREAD_AND_LOCATION, vmSymbols::java_lang_IncompatibleClassChangeError(), diff --git a/src/hotspot/share/services/diagnosticArgument.cpp b/src/hotspot/share/services/diagnosticArgument.cpp index 5fd565a605a..a36b8e853b8 100644 --- a/src/hotspot/share/services/diagnosticArgument.cpp +++ b/src/hotspot/share/services/diagnosticArgument.cpp @@ -115,12 +115,13 @@ template <> void DCmdArgument<jlong>::parse_value(const char* str, || sscanf(str, JLONG_FORMAT "%n", &_value, &scanned) != 1 || (size_t)scanned != len) { - const int maxprint = 64; Exceptions::fthrow(THREAD_AND_LOCATION, vmSymbols::java_lang_IllegalArgumentException(), - "Integer parsing error in command argument '%s'. Could not parse: %.*s%s.\n", _name, - MIN2((int)len, maxprint), - (str == nullptr ? "<null>" : str), - (len > maxprint ? "..." : "")); + "Integer parsing error in command argument '%.*s'. Could not parse: %.*s%s.\n", + maxprint, + _name, + maxprint > len ? (int)len : maxprint, + (str == nullptr ? "<null>" : str), + (len > maxprint ? "..." : "")); } } @@ -160,7 +161,11 @@ PRAGMA_DIAG_POP buf[len] = '\0'; Exceptions::fthrow(THREAD_AND_LOCATION, vmSymbols::java_lang_IllegalArgumentException(), - "Boolean parsing error in command argument '%s'. Could not parse: %s.\n", _name, buf); + "Boolean parsing error in command argument '%.*s'. Could not parse: %.*s.\n", + maxprint, + _name, + maxprint, + buf); } } } diff --git a/src/hotspot/share/services/diagnosticArgument.hpp b/src/hotspot/share/services/diagnosticArgument.hpp index 1451ea34f86..639330d6a0e 100644 --- a/src/hotspot/share/services/diagnosticArgument.hpp +++ b/src/hotspot/share/services/diagnosticArgument.hpp @@ -62,6 +62,7 @@ class MemorySizeArgument { class GenDCmdArgument : public ResourceObj { protected: + static const int maxprint = 64; GenDCmdArgument* _next; const char* const _name; const char* const _description; diff --git a/src/hotspot/share/utilities/exceptions.cpp b/src/hotspot/share/utilities/exceptions.cpp index 0f87f76a2e8..86961039c7c 100644 --- a/src/hotspot/share/utilities/exceptions.cpp +++ b/src/hotspot/share/utilities/exceptions.cpp @@ -258,6 +258,10 @@ void Exceptions::throw_stack_overflow_exception(JavaThread* THREAD, const char* _throw(THREAD, file, line, exception); } +// All callers are expected to have ensured that the incoming expanded format string +// will be within reasonable limits - specifically we will never hit the INT_MAX limit +// of os::vsnprintf when it tries to report how big a buffer is needed. Even so we +// further limit the formatted output to 1024 characters. void Exceptions::fthrow(JavaThread* thread, const char* file, int line, Symbol* h_name, const char* format, ...) { const int max_msg_size = 1024; va_list ap; @@ -273,6 +277,7 @@ void Exceptions::fthrow(JavaThread* thread, const char* file, int line, Symbol* // have a truncated UTF-8 sequence. Similarly, if the buffer was too small and ret >= max_msg_size // we may also have a truncated UTF-8 sequence. In such cases we need to fix the buffer so the UTF-8 // sequence is valid. + assert(ret != -1, "Caller should have ensured the incoming format string is size limited!"); if (ret == -1 || ret >= max_msg_size) { int len = (int) strlen(msg); if (len > 0) { From 027607968b3d55b498e9f2d7a4023b8ae2d47b5b Mon Sep 17 00:00:00 2001 From: Phil Race <prr@openjdk.org> Date: Mon, 25 Nov 2024 22:16:07 +0000 Subject: [PATCH 229/311] 8344667: Remove most uses of AWT Permissions from the desktop module Reviewed-by: azvegint, kizune --- .../classes/sun/awt/CGraphicsDevice.java | 20 ------- .../share/classes/java/applet/Applet.java | 7 --- .../share/classes/java/awt/Dialog.java | 20 ------- .../java/awt/KeyboardFocusManager.java | 54 ------------------- .../share/classes/java/awt/MouseInfo.java | 7 --- .../share/classes/java/awt/Robot.java | 22 -------- .../share/classes/java/awt/SystemTray.java | 10 ---- .../share/classes/java/awt/Toolkit.java | 26 --------- .../share/classes/java/awt/TrayIcon.java | 3 +- .../share/classes/java/awt/Window.java | 14 ----- .../classes/javax/swing/JInternalFrame.java | 6 +-- .../classes/javax/swing/SwingUtilities.java | 8 --- .../basic/BasicInternalFrameTitlePane.java | 7 +-- .../share/classes/sun/awt/AWTPermissions.java | 24 --------- .../share/classes/sun/awt/SunToolkit.java | 15 +----- .../sun/awt/image/BufImgSurfaceData.java | 5 -- .../classes/sun/java2d/NullSurfaceData.java | 9 ---- .../classes/sun/java2d/SunGraphics2D.java | 1 - .../share/classes/sun/java2d/SurfaceData.java | 19 ------- .../classes/sun/awt/X11GraphicsDevice.java | 20 +------ .../classes/sun/awt/Win32GraphicsDevice.java | 21 +------- test/jdk/lib/client/ExtendedRobot.java | 6 --- 22 files changed, 6 insertions(+), 318 deletions(-) diff --git a/src/java.desktop/macosx/classes/sun/awt/CGraphicsDevice.java b/src/java.desktop/macosx/classes/sun/awt/CGraphicsDevice.java index 5a865f92cb6..bdb36a90899 100644 --- a/src/java.desktop/macosx/classes/sun/awt/CGraphicsDevice.java +++ b/src/java.desktop/macosx/classes/sun/awt/CGraphicsDevice.java @@ -25,7 +25,6 @@ package sun.awt; -import java.awt.AWTPermission; import java.awt.DisplayMode; import java.awt.GraphicsConfiguration; import java.awt.GraphicsDevice; @@ -62,8 +61,6 @@ public final class CGraphicsDevice extends GraphicsDevice private static boolean oglPipelineEnabled = false; - private static AWTPermission fullScreenExclusivePermission; - // Save/restore DisplayMode for the Full Screen mode private DisplayMode originalMode; private DisplayMode initialMode; @@ -260,23 +257,6 @@ public synchronized void setFullScreenWindow(Window w) { */ @Override public boolean isFullScreenSupported() { - return isFSExclusiveModeAllowed(); - } - - private static boolean isFSExclusiveModeAllowed() { - @SuppressWarnings("removal") - SecurityManager security = System.getSecurityManager(); - if (security != null) { - if (fullScreenExclusivePermission == null) { - fullScreenExclusivePermission = - new AWTPermission("fullScreenExclusive"); - } - try { - security.checkPermission(fullScreenExclusivePermission); - } catch (SecurityException e) { - return false; - } - } return true; } diff --git a/src/java.desktop/share/classes/java/applet/Applet.java b/src/java.desktop/share/classes/java/applet/Applet.java index c68605a9b64..2228ea419d4 100644 --- a/src/java.desktop/share/classes/java/applet/Applet.java +++ b/src/java.desktop/share/classes/java/applet/Applet.java @@ -25,7 +25,6 @@ package java.applet; -import java.awt.AWTPermission; import java.awt.Dimension; import java.awt.GraphicsEnvironment; import java.awt.HeadlessException; @@ -127,12 +126,6 @@ private void readObject(ObjectInputStream s) * @param stub the new stub */ public final void setStub(AppletStub stub) { - if (this.stub != null) { - SecurityManager s = System.getSecurityManager(); - if (s != null) { - s.checkPermission(new AWTPermission("setAppletStub")); - } - } this.stub = stub; } diff --git a/src/java.desktop/share/classes/java/awt/Dialog.java b/src/java.desktop/share/classes/java/awt/Dialog.java index 03449200478..95d32161b36 100644 --- a/src/java.desktop/share/classes/java/awt/Dialog.java +++ b/src/java.desktop/share/classes/java/awt/Dialog.java @@ -33,7 +33,6 @@ import java.io.IOException; import java.io.ObjectInputStream; import java.io.Serial; -import java.security.AccessControlException; import java.util.Iterator; import java.util.concurrent.atomic.AtomicLong; @@ -42,7 +41,6 @@ import javax.accessibility.AccessibleState; import javax.accessibility.AccessibleStateSet; -import sun.awt.AWTPermissions; import sun.awt.AppContext; import sun.awt.SunToolkit; import sun.awt.util.IdentityArrayList; @@ -844,8 +842,6 @@ public void setModalityType(ModalityType type) { return; } - checkModalityPermission(type); - modalityType = type; modal = (modalityType != ModalityType.MODELESS); } @@ -1561,16 +1557,6 @@ static void checkShouldBeBlocked(Window w) { } } - private void checkModalityPermission(ModalityType mt) { - if (mt == ModalityType.TOOLKIT_MODAL) { - @SuppressWarnings("removal") - SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - sm.checkPermission(AWTPermissions.TOOLKIT_MODALITY_PERMISSION); - } - } - } - /** * Reads serializable fields from stream. * @@ -1592,12 +1578,6 @@ private void readObject(ObjectInputStream s) ModalityType localModalityType = (ModalityType)fields.get("modalityType", null); - try { - checkModalityPermission(localModalityType); - } catch (@SuppressWarnings("removal") AccessControlException ace) { - localModalityType = DEFAULT_MODALITY_TYPE; - } - // in 1.5 or earlier modalityType was absent, so use "modal" instead if (localModalityType == null) { this.modal = fields.get("modal", false); diff --git a/src/java.desktop/share/classes/java/awt/KeyboardFocusManager.java b/src/java.desktop/share/classes/java/awt/KeyboardFocusManager.java index eb623213a77..ede4d385a80 100644 --- a/src/java.desktop/share/classes/java/awt/KeyboardFocusManager.java +++ b/src/java.desktop/share/classes/java/awt/KeyboardFocusManager.java @@ -226,7 +226,6 @@ public static KeyboardFocusManager getCurrentKeyboardFocusManager() { * @see DefaultKeyboardFocusManager */ public static void setCurrentKeyboardFocusManager(KeyboardFocusManager newManager) { - checkReplaceKFMPermission(); KeyboardFocusManager oldManager = null; @@ -354,12 +353,6 @@ public static void setCurrentKeyboardFocusManager(KeyboardFocusManager newManage */ private static java.util.Map<Window, WeakReference<Component>> mostRecentFocusOwners = new WeakHashMap<>(); - /** - * We cache the permission used to verify that the calling thread is - * permitted to access the global focus state. - */ - private static AWTPermission replaceKeyboardFocusManagerPermission; - /* * SequencedEvent which is currently dispatched in AppContext. */ @@ -473,7 +466,6 @@ public Component getFocusOwner() { */ protected Component getGlobalFocusOwner() { synchronized (KeyboardFocusManager.class) { - checkKFMSecurity(); return focusOwner; } } @@ -506,7 +498,6 @@ protected void setGlobalFocusOwner(Component focusOwner) { if (focusOwner == null || focusOwner.isFocusable()) { synchronized (KeyboardFocusManager.class) { - checkKFMSecurity(); oldFocusOwner = getFocusOwner(); @@ -584,7 +575,6 @@ public void clearFocusOwner() { * @see java.awt.event.FocusEvent#FOCUS_LOST */ public void clearGlobalFocusOwner() { - checkReplaceKFMPermission(); if (!GraphicsEnvironment.isHeadless()) { // Toolkit must be fully initialized, otherwise // _clearGlobalFocusOwner will crash or throw an exception @@ -660,7 +650,6 @@ public Component getPermanentFocusOwner() { */ protected Component getGlobalPermanentFocusOwner() { synchronized (KeyboardFocusManager.class) { - checkKFMSecurity(); return permanentFocusOwner; } } @@ -694,7 +683,6 @@ protected void setGlobalPermanentFocusOwner(Component permanentFocusOwner) { if (permanentFocusOwner == null || permanentFocusOwner.isFocusable()) { synchronized (KeyboardFocusManager.class) { - checkKFMSecurity(); oldPermanentFocusOwner = getPermanentFocusOwner(); @@ -755,7 +743,6 @@ public Window getFocusedWindow() { */ protected Window getGlobalFocusedWindow() { synchronized (KeyboardFocusManager.class) { - checkKFMSecurity(); return focusedWindow; } } @@ -785,7 +772,6 @@ protected void setGlobalFocusedWindow(Window focusedWindow) { if (focusedWindow == null || focusedWindow.isFocusableWindow()) { synchronized (KeyboardFocusManager.class) { - checkKFMSecurity(); oldFocusedWindow = getFocusedWindow(); @@ -847,7 +833,6 @@ public Window getActiveWindow() { */ protected Window getGlobalActiveWindow() { synchronized (KeyboardFocusManager.class) { - checkKFMSecurity(); return activeWindow; } } @@ -875,7 +860,6 @@ protected Window getGlobalActiveWindow() { protected void setGlobalActiveWindow(Window activeWindow) { Window oldActiveWindow; synchronized (KeyboardFocusManager.class) { - checkKFMSecurity(); oldActiveWindow = getActiveWindow(); if (focusLog.isLoggable(PlatformLogger.Level.FINER)) { @@ -1152,7 +1136,6 @@ public Container getCurrentFocusCycleRoot() { */ protected Container getGlobalCurrentFocusCycleRoot() { synchronized (KeyboardFocusManager.class) { - checkKFMSecurity(); return currentFocusCycleRoot; } } @@ -1172,7 +1155,6 @@ protected Container getGlobalCurrentFocusCycleRoot() { * @see #getGlobalCurrentFocusCycleRoot */ public void setGlobalCurrentFocusCycleRoot(Container newFocusCycleRoot) { - checkReplaceKFMPermission(); Container oldFocusCycleRoot; @@ -2976,40 +2958,4 @@ private static HeavyweightFocusRequest getFirstHWRequest() { : null; } } - - private static void checkReplaceKFMPermission() - throws SecurityException - { - @SuppressWarnings("removal") - SecurityManager security = System.getSecurityManager(); - if (security != null) { - if (replaceKeyboardFocusManagerPermission == null) { - replaceKeyboardFocusManagerPermission = - new AWTPermission("replaceKeyboardFocusManager"); - } - security. - checkPermission(replaceKeyboardFocusManagerPermission); - } - } - - // Checks if this KeyboardFocusManager instance is the current KFM, - // or otherwise checks if the calling thread has "replaceKeyboardFocusManager" - // permission. Here's the reasoning to do so: - // - // A system KFM instance (which is the current KFM by default) may have no - // "replaceKFM" permission when a client code is on the call stack beneath, - // but still it should be able to execute the methods protected by this check - // due to the system KFM is trusted (and so it does like "privileged"). - // - // If this KFM instance is not the current KFM but the client code has all - // permissions we can't throw SecurityException because it would contradict - // the security concepts. In this case the trusted client code is responsible - // for calling the secured methods from KFM instance which is not current. - private void checkKFMSecurity() - throws SecurityException - { - if (this != getCurrentKeyboardFocusManager()) { - checkReplaceKFMPermission(); - } - } } diff --git a/src/java.desktop/share/classes/java/awt/MouseInfo.java b/src/java.desktop/share/classes/java/awt/MouseInfo.java index 3081e376cdc..6b913adf06e 100644 --- a/src/java.desktop/share/classes/java/awt/MouseInfo.java +++ b/src/java.desktop/share/classes/java/awt/MouseInfo.java @@ -25,7 +25,6 @@ package java.awt; -import sun.awt.AWTPermissions; import sun.awt.ComponentFactory; /** @@ -66,12 +65,6 @@ public static PointerInfo getPointerInfo() throws HeadlessException { throw new HeadlessException(); } - @SuppressWarnings("removal") - SecurityManager security = System.getSecurityManager(); - if (security != null) { - security.checkPermission(AWTPermissions.WATCH_MOUSE_PERMISSION); - } - Toolkit toolkit = Toolkit.getDefaultToolkit(); Point point = new Point(0, 0); int deviceNum = 0; diff --git a/src/java.desktop/share/classes/java/awt/Robot.java b/src/java.desktop/share/classes/java/awt/Robot.java index 95ea477beb3..8b7506f5f2d 100644 --- a/src/java.desktop/share/classes/java/awt/Robot.java +++ b/src/java.desktop/share/classes/java/awt/Robot.java @@ -37,7 +37,6 @@ import java.awt.image.WritableRaster; import java.awt.peer.RobotPeer; -import sun.awt.AWTPermissions; import sun.awt.ComponentFactory; import sun.awt.SunToolkit; import sun.awt.image.SunWritableRaster; @@ -163,7 +162,6 @@ public Robot(GraphicsDevice screen) throws AWTException { } private void init(GraphicsDevice screen) throws AWTException { - checkRobotAllowed(); Toolkit toolkit = Toolkit.getDefaultToolkit(); if (toolkit instanceof ComponentFactory) { peer = ((ComponentFactory)toolkit).createRobot(screen); @@ -193,15 +191,6 @@ private static synchronized void initLegalButtonMask() { LEGAL_BUTTON_MASK = tmpMask; } - /* determine if the security policy allows Robot's to be created */ - private static void checkRobotAllowed() { - @SuppressWarnings("removal") - SecurityManager security = System.getSecurityManager(); - if (security != null) { - security.checkPermission(AWTPermissions.CREATE_ROBOT_PERMISSION); - } - } - /** * Check for headless state and throw {@code AWTException} if headless. */ @@ -437,7 +426,6 @@ private static void checkKeycodeArgument(int keycode) { * @return Color of the pixel */ public synchronized Color getPixelColor(int x, int y) { - checkScreenCaptureAllowed(); Point point = peer.useAbsoluteCoordinates() ? toDeviceSpaceAbs(x, y) : toDeviceSpace(x, y); return new Color(peer.getRGBPixel(point.x, point.y)); @@ -518,8 +506,6 @@ public synchronized BufferedImage createScreenCapture(Rectangle screenRect) { private synchronized BufferedImage[] createCompatibleImage(Rectangle screenRect, boolean isHiDPI) { - checkScreenCaptureAllowed(); - checkValidRect(screenRect); BufferedImage lowResolutionImage; @@ -635,14 +621,6 @@ private static void checkValidRect(Rectangle rect) { } } - private static void checkScreenCaptureAllowed() { - @SuppressWarnings("removal") - SecurityManager security = System.getSecurityManager(); - if (security != null) { - security.checkPermission(AWTPermissions.READ_DISPLAY_PIXELS_PERMISSION); - } - } - /* * Called after an event is generated */ diff --git a/src/java.desktop/share/classes/java/awt/SystemTray.java b/src/java.desktop/share/classes/java/awt/SystemTray.java index 990985e7b44..abf8c97abda 100644 --- a/src/java.desktop/share/classes/java/awt/SystemTray.java +++ b/src/java.desktop/share/classes/java/awt/SystemTray.java @@ -32,7 +32,6 @@ import java.util.Vector; import sun.awt.AWTAccessor; -import sun.awt.AWTPermissions; import sun.awt.AppContext; import sun.awt.HeadlessToolkit; import sun.awt.SunToolkit; @@ -160,7 +159,6 @@ private SystemTray() { * @see #isSupported */ public static SystemTray getSystemTray() { - checkSystemTrayAllowed(); if (GraphicsEnvironment.isHeadless()) { throw new HeadlessException(); } @@ -494,14 +492,6 @@ synchronized void addNotify() { } } - static void checkSystemTrayAllowed() { - @SuppressWarnings("removal") - SecurityManager security = System.getSecurityManager(); - if (security != null) { - security.checkPermission(AWTPermissions.ACCESS_SYSTEM_TRAY_PERMISSION); - } - } - private static void initializeSystemTrayIfNeeded() { synchronized (SystemTray.class) { if (systemTray == null) { diff --git a/src/java.desktop/share/classes/java/awt/Toolkit.java b/src/java.desktop/share/classes/java/awt/Toolkit.java index d181fb6f536..3d9d781de33 100644 --- a/src/java.desktop/share/classes/java/awt/Toolkit.java +++ b/src/java.desktop/share/classes/java/awt/Toolkit.java @@ -72,7 +72,6 @@ import javax.accessibility.AccessibilityProvider; import sun.awt.AWTAccessor; -import sun.awt.AWTPermissions; import sun.awt.AppContext; import sun.awt.HeadlessToolkit; import sun.awt.PeerEvent; @@ -1360,11 +1359,6 @@ public static String getProperty(String key, String defaultValue) { * @return the {@code EventQueue} object */ public final EventQueue getSystemEventQueue() { - @SuppressWarnings("removal") - SecurityManager security = System.getSecurityManager(); - if (security != null) { - security.checkPermission(AWTPermissions.CHECK_AWT_EVENTQUEUE_PERMISSION); - } return getSystemEventQueueImpl(); } @@ -1690,11 +1684,6 @@ public void addAWTEventListener(AWTEventListener listener, long eventMask) { if (localL == null) { return; } - @SuppressWarnings("removal") - SecurityManager security = System.getSecurityManager(); - if (security != null) { - security.checkPermission(AWTPermissions.ALL_AWT_EVENTS_PERMISSION); - } synchronized (this) { SelectiveAWTEventListener selectiveListener = listener2SelectiveListener.get(localL); @@ -1750,11 +1739,6 @@ public void removeAWTEventListener(AWTEventListener listener) { if (listener == null) { return; } - @SuppressWarnings("removal") - SecurityManager security = System.getSecurityManager(); - if (security != null) { - security.checkPermission(AWTPermissions.ALL_AWT_EVENTS_PERMISSION); - } synchronized (this) { SelectiveAWTEventListener selectiveListener = @@ -1807,11 +1791,6 @@ synchronized int countAWTEventListeners(long eventMask) { * @since 1.4 */ public AWTEventListener[] getAWTEventListeners() { - @SuppressWarnings("removal") - SecurityManager security = System.getSecurityManager(); - if (security != null) { - security.checkPermission(AWTPermissions.ALL_AWT_EVENTS_PERMISSION); - } synchronized (this) { EventListener[] la = ToolkitEventMulticaster.getListeners(eventListener,AWTEventListener.class); @@ -1851,11 +1830,6 @@ public AWTEventListener[] getAWTEventListeners() { * @since 1.4 */ public AWTEventListener[] getAWTEventListeners(long eventMask) { - @SuppressWarnings("removal") - SecurityManager security = System.getSecurityManager(); - if (security != null) { - security.checkPermission(AWTPermissions.ALL_AWT_EVENTS_PERMISSION); - } synchronized (this) { EventListener[] la = ToolkitEventMulticaster.getListeners(eventListener,AWTEventListener.class); diff --git a/src/java.desktop/share/classes/java/awt/TrayIcon.java b/src/java.desktop/share/classes/java/awt/TrayIcon.java index 3323818eeb1..b53174ef05e 100644 --- a/src/java.desktop/share/classes/java/awt/TrayIcon.java +++ b/src/java.desktop/share/classes/java/awt/TrayIcon.java @@ -118,9 +118,8 @@ public void removeNotify(TrayIcon trayIcon) { } private TrayIcon() - throws UnsupportedOperationException, HeadlessException, SecurityException + throws UnsupportedOperationException, HeadlessException { - SystemTray.checkSystemTrayAllowed(); if (GraphicsEnvironment.isHeadless()) { throw new HeadlessException(); } diff --git a/src/java.desktop/share/classes/java/awt/Window.java b/src/java.desktop/share/classes/java/awt/Window.java index ac1a2e41dc1..9d12b0cd3c0 100644 --- a/src/java.desktop/share/classes/java/awt/Window.java +++ b/src/java.desktop/share/classes/java/awt/Window.java @@ -64,7 +64,6 @@ import javax.accessibility.AccessibleStateSet; import sun.awt.AWTAccessor; -import sun.awt.AWTPermissions; import sun.awt.AppContext; import sun.awt.DebugSettings; import sun.awt.SunToolkit; @@ -1627,13 +1626,6 @@ public void setModalExclusionType(Dialog.ModalExclusionType exclusionType) { if (modalExclusionType == exclusionType) { return; } - if (exclusionType == Dialog.ModalExclusionType.TOOLKIT_EXCLUDE) { - @SuppressWarnings("removal") - SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - sm.checkPermission(AWTPermissions.TOOLKIT_MODALITY_PERMISSION); - } - } modalExclusionType = exclusionType; // if we want on-fly changes, we need to uncomment the lines below @@ -2169,12 +2161,6 @@ void postProcessKeyEvent(KeyEvent e) { * @since 1.5 */ public final void setAlwaysOnTop(boolean alwaysOnTop) { - @SuppressWarnings("removal") - SecurityManager security = System.getSecurityManager(); - if (security != null) { - security.checkPermission(AWTPermissions.SET_WINDOW_ALWAYS_ON_TOP_PERMISSION); - } - boolean oldAlwaysOnTop; synchronized(this) { oldAlwaysOnTop = this.alwaysOnTop; diff --git a/src/java.desktop/share/classes/javax/swing/JInternalFrame.java b/src/java.desktop/share/classes/javax/swing/JInternalFrame.java index d6b6958e084..e7d0eec76fb 100644 --- a/src/java.desktop/share/classes/javax/swing/JInternalFrame.java +++ b/src/java.desktop/share/classes/javax/swing/JInternalFrame.java @@ -1096,12 +1096,8 @@ public void setSelected(boolean selected) throws PropertyVetoException { fireInternalFrameEvent(InternalFrameEvent.INTERNAL_FRAME_ACTIVATED); else { fireInternalFrameEvent(InternalFrameEvent.INTERNAL_FRAME_DEACTIVATED); - try { - java.awt.Toolkit.getDefaultToolkit().getSystemEventQueue().postEvent( + java.awt.Toolkit.getDefaultToolkit().getSystemEventQueue().postEvent( new sun.awt.UngrabEvent(this)); - } catch (SecurityException e) { - this.dispatchEvent(new sun.awt.UngrabEvent(this)); - } } repaint(); } diff --git a/src/java.desktop/share/classes/javax/swing/SwingUtilities.java b/src/java.desktop/share/classes/javax/swing/SwingUtilities.java index 8d944187418..f2cecb3d761 100644 --- a/src/java.desktop/share/classes/javax/swing/SwingUtilities.java +++ b/src/java.desktop/share/classes/javax/swing/SwingUtilities.java @@ -1970,14 +1970,6 @@ public void windowDeactivated(WindowEvent e) { public void show() { // This frame can never be shown } - public void dispose() { - try { - getToolkit().getSystemEventQueue(); - super.dispose(); - } catch (Exception e) { - // untrusted code not allowed to dispose - } - } } /** diff --git a/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicInternalFrameTitlePane.java b/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicInternalFrameTitlePane.java index cea618a20e3..c11172d7f4e 100644 --- a/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicInternalFrameTitlePane.java +++ b/src/java.desktop/share/classes/javax/swing/plaf/basic/BasicInternalFrameTitlePane.java @@ -528,12 +528,7 @@ protected String getTitle(String text, FontMetrics fm, int availTextWidth) { protected void postClosingEvent(JInternalFrame frame) { InternalFrameEvent e = new InternalFrameEvent( frame, InternalFrameEvent.INTERNAL_FRAME_CLOSING); - // Try posting event, unless there's a SecurityManager. - try { - Toolkit.getDefaultToolkit().getSystemEventQueue().postEvent(e); - } catch (SecurityException se) { - frame.dispatchEvent(e); - } + Toolkit.getDefaultToolkit().getSystemEventQueue().postEvent(e); } /** diff --git a/src/java.desktop/share/classes/sun/awt/AWTPermissions.java b/src/java.desktop/share/classes/sun/awt/AWTPermissions.java index da0dcd1c3af..9fc8ab85aab 100644 --- a/src/java.desktop/share/classes/sun/awt/AWTPermissions.java +++ b/src/java.desktop/share/classes/sun/awt/AWTPermissions.java @@ -35,28 +35,4 @@ private AWTPermissions() { } public static final AWTPermission ACCESS_CLIPBOARD_PERMISSION = new AWTPermission("accessClipboard"); - - public static final AWTPermission CHECK_AWT_EVENTQUEUE_PERMISSION = - new AWTPermission("accessEventQueue"); - - public static final AWTPermission TOOLKIT_MODALITY_PERMISSION = - new AWTPermission("toolkitModality"); - - public static final AWTPermission READ_DISPLAY_PIXELS_PERMISSION = - new AWTPermission("readDisplayPixels"); - - public static final AWTPermission CREATE_ROBOT_PERMISSION = - new AWTPermission("createRobot"); - - public static final AWTPermission WATCH_MOUSE_PERMISSION = - new AWTPermission("watchMousePointer"); - - public static final AWTPermission SET_WINDOW_ALWAYS_ON_TOP_PERMISSION = - new AWTPermission("setWindowAlwaysOnTop"); - - public static final AWTPermission ALL_AWT_EVENTS_PERMISSION = - new AWTPermission("listenToAllAWTEvents"); - - public static final AWTPermission ACCESS_SYSTEM_TRAY_PERMISSION = - new AWTPermission("accessSystemTray"); } diff --git a/src/java.desktop/share/classes/sun/awt/SunToolkit.java b/src/java.desktop/share/classes/sun/awt/SunToolkit.java index 439167d6642..b630148f809 100644 --- a/src/java.desktop/share/classes/sun/awt/SunToolkit.java +++ b/src/java.desktop/share/classes/sun/awt/SunToolkit.java @@ -1082,22 +1082,9 @@ public boolean isPrintableCharacterModifiersMask(int mods) { /** * Returns whether popup is allowed to be shown above the task bar. - * This is a default implementation of this method, which checks - * corresponding security permission. */ public boolean canPopupOverlapTaskBar() { - boolean result = true; - try { - @SuppressWarnings("removal") - SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - sm.checkPermission(AWTPermissions.SET_WINDOW_ALWAYS_ON_TOP_PERMISSION); - } - } catch (SecurityException se) { - // There is no permission to show popups over the task bar - result = false; - } - return result; + return true; } /** diff --git a/src/java.desktop/share/classes/sun/awt/image/BufImgSurfaceData.java b/src/java.desktop/share/classes/sun/awt/image/BufImgSurfaceData.java index 09d5adcb776..1a76c47692e 100644 --- a/src/java.desktop/share/classes/sun/awt/image/BufImgSurfaceData.java +++ b/src/java.desktop/share/classes/sun/awt/image/BufImgSurfaceData.java @@ -437,11 +437,6 @@ public java.awt.Rectangle getBounds() { return new Rectangle(bufImg.getWidth(), bufImg.getHeight()); } - protected void checkCustomComposite() { - // BufferedImages always allow Custom Composite objects since - // their pixels are immediately retrievable anyway. - } - /** * Returns destination Image associated with this SurfaceData. */ diff --git a/src/java.desktop/share/classes/sun/java2d/NullSurfaceData.java b/src/java.desktop/share/classes/sun/java2d/NullSurfaceData.java index 6b93d81afb6..827170e488d 100644 --- a/src/java.desktop/share/classes/sun/java2d/NullSurfaceData.java +++ b/src/java.desktop/share/classes/sun/java2d/NullSurfaceData.java @@ -130,15 +130,6 @@ public Rectangle getBounds() { return new Rectangle(); } - /** - * Performs Security Permissions checks to see if a Custom - * Composite object should be allowed access to the pixels - * of this surface. - */ - protected void checkCustomComposite() { - return; - } - /** * Performs a copyarea within this surface. Returns * false if there is no algorithm to perform the copyarea diff --git a/src/java.desktop/share/classes/sun/java2d/SunGraphics2D.java b/src/java.desktop/share/classes/sun/java2d/SunGraphics2D.java index c27e4c6ebe0..1bebf379997 100644 --- a/src/java.desktop/share/classes/sun/java2d/SunGraphics2D.java +++ b/src/java.desktop/share/classes/sun/java2d/SunGraphics2D.java @@ -974,7 +974,6 @@ public void setComposite(Composite comp) { } else if (comp == null) { throw new IllegalArgumentException("null Composite"); } else { - surfaceData.checkCustomComposite(); newCompState = COMP_CUSTOM; newCompType = CompositeType.General; } diff --git a/src/java.desktop/share/classes/sun/java2d/SurfaceData.java b/src/java.desktop/share/classes/sun/java2d/SurfaceData.java index 3e20631f682..cd39e48d90e 100644 --- a/src/java.desktop/share/classes/sun/java2d/SurfaceData.java +++ b/src/java.desktop/share/classes/sun/java2d/SurfaceData.java @@ -1002,25 +1002,6 @@ public int rgbFor(int pixel) { */ public abstract Rectangle getBounds(); - static java.security.Permission compPermission; - - /** - * Performs Security Permissions checks to see if a Custom - * Composite object should be allowed access to the pixels - * of this surface. - */ - protected void checkCustomComposite() { - @SuppressWarnings("removal") - SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - if (compPermission == null) { - compPermission = - new java.awt.AWTPermission("readDisplayPixels"); - } - sm.checkPermission(compPermission); - } - } - /** * Fetches private field IndexColorModel.allgrayopaque * which is true when all palette entries in the color diff --git a/src/java.desktop/unix/classes/sun/awt/X11GraphicsDevice.java b/src/java.desktop/unix/classes/sun/awt/X11GraphicsDevice.java index ca43142a098..eed50962f0d 100644 --- a/src/java.desktop/unix/classes/sun/awt/X11GraphicsDevice.java +++ b/src/java.desktop/unix/classes/sun/awt/X11GraphicsDevice.java @@ -25,7 +25,6 @@ package sun.awt; -import java.awt.AWTPermission; import java.awt.DisplayMode; import java.awt.GraphicsConfiguration; import java.awt.GraphicsDevice; @@ -65,7 +64,6 @@ public final class X11GraphicsDevice extends GraphicsDevice private volatile int screen; Map<SurfaceType, SurfaceManager.ProxyCache> x11ProxyCacheMap = Collections.synchronizedMap(new HashMap<>()); - private static AWTPermission fullScreenExclusivePermission; private static Boolean xrandrExtSupported; private SunDisplayChanger topLevels = new SunDisplayChanger(); private DisplayMode origDisplayMode; @@ -335,23 +333,7 @@ private static synchronized boolean isXrandrExtensionSupported() { @Override public boolean isFullScreenSupported() { - boolean fsAvailable = isXrandrExtensionSupported(); - if (fsAvailable) { - @SuppressWarnings("removal") - SecurityManager security = System.getSecurityManager(); - if (security != null) { - if (fullScreenExclusivePermission == null) { - fullScreenExclusivePermission = - new AWTPermission("fullScreenExclusive"); - } - try { - security.checkPermission(fullScreenExclusivePermission); - } catch (SecurityException e) { - return false; - } - } - } - return fsAvailable; + return isXrandrExtensionSupported(); } @Override diff --git a/src/java.desktop/windows/classes/sun/awt/Win32GraphicsDevice.java b/src/java.desktop/windows/classes/sun/awt/Win32GraphicsDevice.java index f32b25626bb..95aa5b302f0 100644 --- a/src/java.desktop/windows/classes/sun/awt/Win32GraphicsDevice.java +++ b/src/java.desktop/windows/classes/sun/awt/Win32GraphicsDevice.java @@ -25,7 +25,6 @@ package sun.awt; -import java.awt.AWTPermission; import java.awt.DisplayMode; import java.awt.EventQueue; import java.awt.Frame; @@ -81,7 +80,6 @@ public class Win32GraphicsDevice extends GraphicsDevice implements // pipelines which are mutually exclusive with opengl, for which // pixel formats were added in the first place protected static boolean pfDisabled; - private static AWTPermission fullScreenExclusivePermission; // the original display mode we had before entering the fullscreen // mode private DisplayMode defaultDisplayMode; @@ -349,29 +347,12 @@ private boolean isDefaultDevice() { getLocalGraphicsEnvironment().getDefaultScreenDevice()); } - private static boolean isFSExclusiveModeAllowed() { - @SuppressWarnings("removal") - SecurityManager security = System.getSecurityManager(); - if (security != null) { - if (fullScreenExclusivePermission == null) { - fullScreenExclusivePermission = - new AWTPermission("fullScreenExclusive"); - } - try { - security.checkPermission(fullScreenExclusivePermission); - } catch (SecurityException e) { - return false; - } - } - return true; - } - /** * returns true unless we're not allowed to use fullscreen mode. */ @Override public boolean isFullScreenSupported() { - return isFSExclusiveModeAllowed(); + return true; } @Override diff --git a/test/jdk/lib/client/ExtendedRobot.java b/test/jdk/lib/client/ExtendedRobot.java index 2a39017231c..3f77da88750 100644 --- a/test/jdk/lib/client/ExtendedRobot.java +++ b/test/jdk/lib/client/ExtendedRobot.java @@ -68,11 +68,8 @@ public class ExtendedRobot extends Robot { * @throws AWTException if the platform configuration does not allow low-level input * control. This exception is always thrown when * GraphicsEnvironment.isHeadless() returns true - * @throws SecurityException if {@code createRobot} permission is not granted * * @see java.awt.GraphicsEnvironment#isHeadless - * @see SecurityManager#checkPermission - * @see java.awt.AWTPermission */ public ExtendedRobot() throws AWTException { super(); @@ -99,12 +96,9 @@ public ExtendedRobot() throws AWTException { * GraphicsEnvironment.isHeadless() returns true. * @throws IllegalArgumentException if {@code screen} is not a screen * GraphicsDevice. - * @throws SecurityException if {@code createRobot} permission is not granted * * @see java.awt.GraphicsEnvironment#isHeadless * @see GraphicsDevice - * @see SecurityManager#checkPermission - * @see java.awt.AWTPermission */ public ExtendedRobot(GraphicsDevice screen) throws AWTException { super(screen); From 16232578d9acf9d0b5a9ad0e7530291471b5cc9c Mon Sep 17 00:00:00 2001 From: Alisen Chung <achung@openjdk.org> Date: Mon, 25 Nov 2024 22:32:59 +0000 Subject: [PATCH 230/311] 8339524: Clean up a few ExtendedRobot tests Reviewed-by: honkar, aivanov, prr --- .../JInternalFrame/6725409/bug6725409.java | 77 ++++++++----------- 1 file changed, 30 insertions(+), 47 deletions(-) diff --git a/test/jdk/javax/swing/JInternalFrame/6725409/bug6725409.java b/test/jdk/javax/swing/JInternalFrame/6725409/bug6725409.java index a1dc1532dce..b5f26aaf6e6 100644 --- a/test/jdk/javax/swing/JInternalFrame/6725409/bug6725409.java +++ b/test/jdk/javax/swing/JInternalFrame/6725409/bug6725409.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2008, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,68 +21,61 @@ * questions. */ -/* @test +/* + * @test * @key headful * @bug 6725409 * @requires (os.family == "windows") * @summary Checks that JInternalFrame's system menu * can be localized during run-time - * @author Mikhail Lapshin - * @library /lib/client/ * @modules java.desktop/com.sun.java.swing.plaf.windows - * @build ExtendedRobot * @run main bug6725409 */ -import javax.swing.*; -import java.awt.*; +import java.awt.Robot; +import javax.swing.JDesktopPane; +import javax.swing.JFrame; +import javax.swing.JInternalFrame; +import javax.swing.JMenuItem; +import javax.swing.JPopupMenu; +import javax.swing.SwingUtilities; +import javax.swing.UIManager; + +import com.sun.java.swing.plaf.windows.WindowsClassicLookAndFeel; +import com.sun.java.swing.plaf.windows.WindowsInternalFrameTitlePane; public class bug6725409 { private JFrame frame; private JInternalFrame iFrame; - private TestTitlePane testTitlePane; - private boolean passed; - private static ExtendedRobot robot = createRobot(); + private static TestTitlePane testTitlePane; + private static volatile boolean passed; + private static Robot robot; public static void main(String[] args) throws Exception { - try { - UIManager.setLookAndFeel( - new com.sun.java.swing.plaf.windows.WindowsClassicLookAndFeel()); - } catch(UnsupportedLookAndFeelException e) { - System.out.println("The test is for Windows LaF only"); - return; - } + UIManager.setLookAndFeel( + new WindowsClassicLookAndFeel()); + robot = new Robot(); final bug6725409 bug6725409 = new bug6725409(); try { - SwingUtilities.invokeAndWait(new Runnable() { - public void run() { - bug6725409.setupUIStep1(); - } - }); + SwingUtilities.invokeAndWait(bug6725409::setupUIStep1); sync(); - SwingUtilities.invokeAndWait(new Runnable() { - public void run() { - bug6725409.setupUIStep2(); - } - }); + SwingUtilities.invokeAndWait(bug6725409::setupUIStep2); sync(); - SwingUtilities.invokeAndWait(new Runnable() { - public void run() { - bug6725409.test(); - } - }); + SwingUtilities.invokeAndWait(bug6725409::test); sync(); bug6725409.checkResult(); } finally { - if (bug6725409.frame != null) { - bug6725409.frame.dispose(); - } + SwingUtilities.invokeAndWait(() -> { + if (bug6725409.frame != null) { + bug6725409.frame.dispose(); + } + }); } } private void setupUIStep1() { - frame = new JFrame(); + frame = new JFrame("bug6725409"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); JDesktopPane desktop = new JDesktopPane(); @@ -147,19 +140,9 @@ private void checkResult() { private static void sync() { robot.waitForIdle(); } - private static ExtendedRobot createRobot() { - try { - ExtendedRobot robot = new ExtendedRobot(); - return robot; - }catch(Exception ex) { - ex.printStackTrace(); - throw new Error("Unexpected Failure"); - } - } // Extend WindowsInternalFrameTitlePane to get access to systemPopupMenu - private class TestTitlePane extends - com.sun.java.swing.plaf.windows.WindowsInternalFrameTitlePane { + private class TestTitlePane extends WindowsInternalFrameTitlePane { private JPopupMenu systemPopupMenu; public TestTitlePane(JInternalFrame f) { From 48e3b6511adf3d4e97035014612674d84ae83aa0 Mon Sep 17 00:00:00 2001 From: Taizo Kurashige <taizousum11@gmail.com> Date: Mon, 25 Nov 2024 23:23:03 +0000 Subject: [PATCH 231/311] 8344275: tools/jpackage/windows/Win8301247Test.java fails on localized Windows platform Reviewed-by: asemenyuk, almatvee --- .../helpers/jdk/jpackage/test/Executor.java | 37 ++++++++++++++++--- .../jdk/jpackage/test/WindowsHelper.java | 7 ++-- 2 files changed, 35 insertions(+), 9 deletions(-) diff --git a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/Executor.java b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/Executor.java index 00f6ab5263c..7a0878d826b 100644 --- a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/Executor.java +++ b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/Executor.java @@ -54,6 +54,7 @@ public static Executor of(String... cmdline) { public Executor() { saveOutputType = new HashSet<>(Set.of(SaveOutputType.NONE)); removePathEnvVar = false; + winEnglishOutput = false; } public Executor setExecutable(String v) { @@ -90,6 +91,15 @@ public Executor setRemovePathEnvVar(boolean value) { return this; } + public Executor setWinRunWithEnglishOutput(boolean value) { + if (!TKit.isWindows()) { + throw new UnsupportedOperationException( + "setWinRunWithEnglishOutput is only valid on Windows platform"); + } + winEnglishOutput = value; + return this; + } + public Executor setWindowsTmpDir(String tmp) { if (!TKit.isWindows()) { throw new UnsupportedOperationException( @@ -207,6 +217,11 @@ public Result executeWithoutExitCodeCheck() { "Can't change directory when using tool provider"); } + if (toolProvider != null && winEnglishOutput) { + throw new IllegalArgumentException( + "Can't change locale when using tool provider"); + } + return ThrowingSupplier.toSupplier(() -> { if (toolProvider != null) { return runToolProvider(); @@ -324,8 +339,17 @@ private Path executablePath() { return executable.toAbsolutePath(); } + private List<String> prefixCommandLineArgs() { + if (winEnglishOutput) { + return List.of("cmd.exe", "/c", "chcp", "437", ">nul", "2>&1", "&&"); + } else { + return List.of(); + } + } + private Result runExecutable() throws IOException, InterruptedException { List<String> command = new ArrayList<>(); + command.addAll(prefixCommandLineArgs()); command.add(executablePath().toString()); command.addAll(args); ProcessBuilder builder = new ProcessBuilder(command); @@ -457,15 +481,17 @@ public String getPrintableCommandLine() { exec = executablePath().toString(); } - return String.format(format, printCommandLine(exec, args), - args.size() + 1); + var cmdline = Stream.of(prefixCommandLineArgs(), List.of(exec), args).flatMap( + List::stream).toList(); + + return String.format(format, printCommandLine(cmdline), cmdline.size()); } - private static String printCommandLine(String executable, List<String> args) { + private static String printCommandLine(List<String> cmdline) { // Want command line printed in a way it can be easily copy/pasted - // to be executed manally + // to be executed manually Pattern regex = Pattern.compile("\\s"); - return Stream.concat(Stream.of(executable), args.stream()).map( + return cmdline.stream().map( v -> (v.isEmpty() || regex.matcher(v).find()) ? "\"" + v + "\"" : v).collect( Collectors.joining(" ")); } @@ -479,6 +505,7 @@ private static void trace(String msg) { private Set<SaveOutputType> saveOutputType; private Path directory; private boolean removePathEnvVar; + private boolean winEnglishOutput; private String winTmpDir = null; private static enum SaveOutputType { diff --git a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/WindowsHelper.java b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/WindowsHelper.java index 4fb937864aa..9d289c56540 100644 --- a/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/WindowsHelper.java +++ b/test/jdk/tools/jpackage/helpers/jdk/jpackage/test/WindowsHelper.java @@ -284,14 +284,13 @@ public static void killAppLauncherProcess(JPackageCommand cmd, } private static long[] findAppLauncherPIDs(JPackageCommand cmd, String launcherName) { - // Get the list of PIDs and PPIDs of app launcher processes. + // Get the list of PIDs and PPIDs of app launcher processes. Run setWinRunWithEnglishOutput(true) for JDK-8344275. // wmic process where (name = "foo.exe") get ProcessID,ParentProcessID List<String> output = Executor.of("wmic", "process", "where", "(name", "=", "\"" + cmd.appLauncherPath(launcherName).getFileName().toString() + "\"", - ")", "get", "ProcessID,ParentProcessID").dumpOutput(true). - saveOutput().executeAndGetOutput(); - + ")", "get", "ProcessID,ParentProcessID").dumpOutput(true).saveOutput(). + setWinRunWithEnglishOutput(true).executeAndGetOutput(); if ("No Instance(s) Available.".equals(output.getFirst().trim())) { return new long[0]; } From 3326874f5f067119b3632a3ea96f0c2f3897598e Mon Sep 17 00:00:00 2001 From: Jaikiran Pai <jpai@openjdk.org> Date: Tue, 26 Nov 2024 00:52:50 +0000 Subject: [PATCH 232/311] 8344857: Remove calls to SecurityManager and doPrivileged in SocketExceptions and URLJarFile in the sun.net package after JEP 486 integration Reviewed-by: dfuchs, michaelm --- .../sun/net/util/SocketExceptions.java | 32 +++++--------- .../sun/net/www/protocol/jar/URLJarFile.java | 44 ++++++------------- 2 files changed, 26 insertions(+), 50 deletions(-) diff --git a/src/java.base/share/classes/sun/net/util/SocketExceptions.java b/src/java.base/share/classes/sun/net/util/SocketExceptions.java index ee70c58b9ba..1198898edcb 100644 --- a/src/java.base/share/classes/sun/net/util/SocketExceptions.java +++ b/src/java.base/share/classes/sun/net/util/SocketExceptions.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -30,8 +30,6 @@ import java.net.InetSocketAddress; import java.net.UnixDomainSocketAddress; import java.net.SocketAddress; -import java.security.AccessController; -import java.security.PrivilegedAction; import sun.security.util.SecurityProperties; @@ -83,22 +81,16 @@ private static IOException ofUnixDomain(IOException e, UnixDomainSocketAddress a // return a new instance of the same type with the given detail // msg, or if the type doesn't support detail msgs, return given // instance. - - @SuppressWarnings("removal") - private static IOException create(IOException e, String msg) { - return AccessController.doPrivileged(new PrivilegedAction<IOException>() { - public IOException run() { - try { - Class<?> clazz = e.getClass(); - Constructor<?> ctor = clazz.getConstructor(String.class); - IOException e1 = (IOException)(ctor.newInstance(msg)); - e1.setStackTrace(e.getStackTrace()); - return e1; - } catch (Exception e0) { - // Some eg AsynchronousCloseException have no detail msg - return e; - } - } - }); + private static IOException create(final IOException e, final String msg) { + try { + Class<?> clazz = e.getClass(); + Constructor<?> ctor = clazz.getConstructor(String.class); + IOException e1 = (IOException)(ctor.newInstance(msg)); + e1.setStackTrace(e.getStackTrace()); + return e1; + } catch (Exception e0) { + // Some eg AsynchronousCloseException have no detail msg + return e; + } } } diff --git a/src/java.base/share/classes/sun/net/www/protocol/jar/URLJarFile.java b/src/java.base/share/classes/sun/net/www/protocol/jar/URLJarFile.java index 8690ed34e12..b3d4a223196 100644 --- a/src/java.base/share/classes/sun/net/www/protocol/jar/URLJarFile.java +++ b/src/java.base/share/classes/sun/net/www/protocol/jar/URLJarFile.java @@ -36,9 +36,6 @@ import java.util.zip.ZipEntry; import java.security.CodeSigner; import java.security.cert.Certificate; -import java.security.AccessController; -import java.security.PrivilegedExceptionAction; -import java.security.PrivilegedActionException; import sun.net.www.ParseUtil; /* URL jar file is a common JarFile subtype used for JarURLConnection */ @@ -159,39 +156,26 @@ private synchronized boolean isSuperMan() throws IOException { * Given a URL, retrieves a JAR file, caches it to disk, and creates a * cached JAR file object. */ - @SuppressWarnings("removal") private static JarFile retrieve(final URL url, final URLJarFileCloseController closeController) throws IOException { - JarFile result = null; Runtime.Version version = "runtime".equals(url.getRef()) ? JarFile.runtimeVersion() : JarFile.baseVersion(); - - /* get the stream before asserting privileges */ try (final InputStream in = url.openConnection().getInputStream()) { - result = AccessController.doPrivileged( - new PrivilegedExceptionAction<>() { - public JarFile run() throws IOException { - Path tmpFile = Files.createTempFile("jar_cache", null); - try { - Files.copy(in, tmpFile, StandardCopyOption.REPLACE_EXISTING); - JarFile jarFile = new URLJarFile(tmpFile.toFile(), closeController, version); - tmpFile.toFile().deleteOnExit(); - return jarFile; - } catch (Throwable thr) { - try { - Files.delete(tmpFile); - } catch (IOException ioe) { - thr.addSuppressed(ioe); - } - throw thr; - } - } - }); - } catch (PrivilegedActionException pae) { - throw (IOException) pae.getException(); + Path tmpFile = Files.createTempFile("jar_cache", null); + try { + Files.copy(in, tmpFile, StandardCopyOption.REPLACE_EXISTING); + JarFile jarFile = new URLJarFile(tmpFile.toFile(), closeController, version); + tmpFile.toFile().deleteOnExit(); + return jarFile; + } catch (Throwable thr) { + try { + Files.delete(tmpFile); + } catch (IOException ioe) { + thr.addSuppressed(ioe); + } + throw thr; + } } - - return result; } private class URLJarFileEntry extends JarEntry { From 5e0d42b6a633d58d7303257569a7b45483f2db53 Mon Sep 17 00:00:00 2001 From: Fei Yang <fyang@openjdk.org> Date: Tue, 26 Nov 2024 01:01:17 +0000 Subject: [PATCH 233/311] 8344916: RISC-V: Misaligned access in array fill stub Reviewed-by: rehn, mli --- src/hotspot/cpu/riscv/stubGenerator_riscv.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hotspot/cpu/riscv/stubGenerator_riscv.cpp b/src/hotspot/cpu/riscv/stubGenerator_riscv.cpp index 795e6882c6a..7e6fe50e8f8 100644 --- a/src/hotspot/cpu/riscv/stubGenerator_riscv.cpp +++ b/src/hotspot/cpu/riscv/stubGenerator_riscv.cpp @@ -2112,7 +2112,7 @@ class StubGenerator: public StubCodeGenerator { // Remaining count is less than 8 bytes. Fill it by a single store. // Note that the total length is no less than 8 bytes. - if (t == T_BYTE || t == T_SHORT) { + if (!AvoidUnalignedAccesses && (t == T_BYTE || t == T_SHORT)) { __ beqz(count, L_exit1); __ shadd(to, count, to, tmp_reg, shift); // points to the end __ sd(value, Address(to, -8)); // overwrite some elements From 1c7f34d3dd24551c0d325f1f3c56ffb7be9042e1 Mon Sep 17 00:00:00 2001 From: Phil Race <prr@openjdk.org> Date: Tue, 26 Nov 2024 01:10:24 +0000 Subject: [PATCH 234/311] 8345000: Remove last mentions of sun.awt.AWTPermissions Reviewed-by: honkar, azvegint --- .../share/classes/sun/awt/AWTPermissions.java | 38 ------------------- .../sun/awt/dnd/SunDropTargetContextPeer.java | 1 - .../classes/sun/swing/SwingUtilities2.java | 1 - 3 files changed, 40 deletions(-) delete mode 100644 src/java.desktop/share/classes/sun/awt/AWTPermissions.java diff --git a/src/java.desktop/share/classes/sun/awt/AWTPermissions.java b/src/java.desktop/share/classes/sun/awt/AWTPermissions.java deleted file mode 100644 index 9fc8ab85aab..00000000000 --- a/src/java.desktop/share/classes/sun/awt/AWTPermissions.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package sun.awt; - -import java.awt.AWTPermission; - -/** - * Defines the {@code AWTPermission} objects used for permission checks. - */ - -public final class AWTPermissions { - private AWTPermissions() { } - - public static final AWTPermission ACCESS_CLIPBOARD_PERMISSION = - new AWTPermission("accessClipboard"); -} diff --git a/src/java.desktop/share/classes/sun/awt/dnd/SunDropTargetContextPeer.java b/src/java.desktop/share/classes/sun/awt/dnd/SunDropTargetContextPeer.java index c6346fddebd..686c3166441 100644 --- a/src/java.desktop/share/classes/sun/awt/dnd/SunDropTargetContextPeer.java +++ b/src/java.desktop/share/classes/sun/awt/dnd/SunDropTargetContextPeer.java @@ -56,7 +56,6 @@ import java.io.InputStream; import sun.awt.AppContext; -import sun.awt.AWTPermissions; import sun.awt.SunToolkit; import sun.awt.datatransfer.DataTransferer; import sun.awt.datatransfer.ToolkitThreadBlockedHandler; diff --git a/src/java.desktop/share/classes/sun/swing/SwingUtilities2.java b/src/java.desktop/share/classes/sun/swing/SwingUtilities2.java index 7c2b5517e15..181d2d5d33b 100644 --- a/src/java.desktop/share/classes/sun/swing/SwingUtilities2.java +++ b/src/java.desktop/share/classes/sun/swing/SwingUtilities2.java @@ -92,7 +92,6 @@ import javax.swing.tree.TreePath; import sun.awt.AWTAccessor; -import sun.awt.AWTPermissions; import sun.awt.AppContext; import sun.awt.SunToolkit; import sun.font.FontDesignMetrics; From 4d4cef800a4b763ab00e93e7a76a5ca5040ab826 Mon Sep 17 00:00:00 2001 From: Brent Christian <bchristi@openjdk.org> Date: Tue, 26 Nov 2024 01:17:37 +0000 Subject: [PATCH 235/311] 8344337: SecurityManager cleanup in java.prefs module Reviewed-by: lancea, bpb, rriggs, iris --- .../java/util/prefs/MacOSXPreferences.java | 4 +- .../util/prefs/MacOSXPreferencesFile.java | 12 +- .../java/util/prefs/AbstractPreferences.java | 12 +- .../classes/java/util/prefs/Preferences.java | 50 +- .../util/prefs/FileSystemPreferences.java | 433 +++++++----------- .../java/util/prefs/WindowsPreferences.java | 12 +- 6 files changed, 180 insertions(+), 343 deletions(-) diff --git a/src/java.prefs/macosx/classes/java/util/prefs/MacOSXPreferences.java b/src/java.prefs/macosx/classes/java/util/prefs/MacOSXPreferences.java index 6f395514352..f60fddd3fcb 100644 --- a/src/java.prefs/macosx/classes/java/util/prefs/MacOSXPreferences.java +++ b/src/java.prefs/macosx/classes/java/util/prefs/MacOSXPreferences.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -28,8 +28,6 @@ import java.util.Objects; class MacOSXPreferences extends AbstractPreferences { - // fixme need security checks? - // CF preferences file name for Java nodes with short names // This value is also in MacOSXPreferencesFile.c private static final String defaultAppName = "com.apple.java.util.prefs"; diff --git a/src/java.prefs/macosx/classes/java/util/prefs/MacOSXPreferencesFile.java b/src/java.prefs/macosx/classes/java/util/prefs/MacOSXPreferencesFile.java index c222bc3d81f..9c599b66d8c 100644 --- a/src/java.prefs/macosx/classes/java/util/prefs/MacOSXPreferencesFile.java +++ b/src/java.prefs/macosx/classes/java/util/prefs/MacOSXPreferencesFile.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -82,15 +82,9 @@ class MacOSXPreferencesFile { loadPrefsLib(); } - @SuppressWarnings({"removal", "restricted"}) + @SuppressWarnings("restricted") private static void loadPrefsLib() { - java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction<Void>() { - public Void run() { - System.loadLibrary("prefs"); - return null; - } - }); + System.loadLibrary("prefs"); } private static class FlushTask extends TimerTask { diff --git a/src/java.prefs/share/classes/java/util/prefs/AbstractPreferences.java b/src/java.prefs/share/classes/java/util/prefs/AbstractPreferences.java index 94963658f1d..0d64690f894 100644 --- a/src/java.prefs/share/classes/java/util/prefs/AbstractPreferences.java +++ b/src/java.prefs/share/classes/java/util/prefs/AbstractPreferences.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -27,8 +27,6 @@ import java.util.*; import java.io.*; -import java.security.AccessController; -import java.security.PrivilegedAction; /** * This class provides a skeletal implementation of the {@link Preferences} @@ -1058,14 +1056,8 @@ public String absolutePath() { * preference tree, {@code false} if it's in the system * preference tree. */ - @SuppressWarnings("removal") public boolean isUserNode() { - return AccessController.doPrivileged( - new PrivilegedAction<Boolean>() { - public Boolean run() { - return root == Preferences.userRoot(); - } - }).booleanValue(); + return root == Preferences.userRoot(); } public void addPreferenceChangeListener(PreferenceChangeListener pcl) { diff --git a/src/java.prefs/share/classes/java/util/prefs/Preferences.java b/src/java.prefs/share/classes/java/util/prefs/Preferences.java index d428261aac9..0d9deb024ff 100644 --- a/src/java.prefs/share/classes/java/util/prefs/Preferences.java +++ b/src/java.prefs/share/classes/java/util/prefs/Preferences.java @@ -30,20 +30,10 @@ import java.io.InputStream; import java.io.IOException; import java.io.OutputStream; -import java.security.AccessController; -import java.security.Permission; -import java.security.PrivilegedAction; import java.util.Iterator; import java.util.ServiceLoader; import java.util.ServiceConfigurationError; -// These imports needed only as a workaround for a JavaDoc bug -import java.lang.RuntimePermission; -import java.lang.Integer; -import java.lang.Long; -import java.lang.Float; -import java.lang.Double; - /** * A node in a hierarchical collection of preference data. This class * allows applications to store and retrieve user and system @@ -227,19 +217,10 @@ public abstract class Preferences { private static final PreferencesFactory factory = factory(); - @SuppressWarnings("removal") private static PreferencesFactory factory() { // 1. Try user-specified system property - String factoryName = AccessController.doPrivileged( - new PrivilegedAction<String>() { - public String run() { - return System.getProperty( - "java.util.prefs.PreferencesFactory");}}); + String factoryName = System.getProperty("java.util.prefs.PreferencesFactory"); if (factoryName != null) { - // FIXME: This code should be run in a doPrivileged and - // not use the context classloader, to avoid being - // dependent on the invoking thread. - // Checking AllPermission also seems wrong. try { @SuppressWarnings("deprecation") Object result =Class.forName(factoryName, false, @@ -250,10 +231,6 @@ public String run() { try { // workaround for javaws, plugin, // load factory class using non-system classloader - SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - sm.checkPermission(new java.security.AllPermission()); - } @SuppressWarnings("deprecation") Object result = Class.forName(factoryName, false, Thread.currentThread() @@ -267,14 +244,6 @@ public String run() { } } } - - return AccessController.doPrivileged( - new PrivilegedAction<PreferencesFactory>() { - public PreferencesFactory run() { - return factory1();}}); - } - - private static PreferencesFactory factory1() { // 2. Try service provider interface Iterator<PreferencesFactory> itr = ServiceLoader .load(PreferencesFactory.class, ClassLoader.getSystemClassLoader()) @@ -427,24 +396,12 @@ private static String nodeName(Class<?> c) { return "/" + packageName.replace('.', '/'); } - /** - * This permission object represents the permission required to get - * access to the user or system root (which in turn allows for all - * other operations). - */ - private static Permission prefsPerm = new RuntimePermission("preferences"); - /** * Returns the root preference node for the calling user. * * @return the root preference node for the calling user. */ public static Preferences userRoot() { - @SuppressWarnings("removal") - SecurityManager security = System.getSecurityManager(); - if (security != null) - security.checkPermission(prefsPerm); - return factory.userRoot(); } @@ -454,11 +411,6 @@ public static Preferences userRoot() { * @return the root preference node for the system. */ public static Preferences systemRoot() { - @SuppressWarnings("removal") - SecurityManager security = System.getSecurityManager(); - if (security != null) - security.checkPermission(prefsPerm); - return factory.systemRoot(); } diff --git a/src/java.prefs/unix/classes/java/util/prefs/FileSystemPreferences.java b/src/java.prefs/unix/classes/java/util/prefs/FileSystemPreferences.java index 756eedade72..4f75f434745 100644 --- a/src/java.prefs/unix/classes/java/util/prefs/FileSystemPreferences.java +++ b/src/java.prefs/unix/classes/java/util/prefs/FileSystemPreferences.java @@ -27,9 +27,6 @@ import java.util.*; import java.io.*; -import java.security.AccessController; -import java.security.PrivilegedAction; -import java.security.PrivilegedExceptionAction; import java.security.PrivilegedActionException; import sun.util.logging.PlatformLogger; @@ -53,13 +50,9 @@ class FileSystemPreferences extends AbstractPreferences { loadPrefsLib(); } - @SuppressWarnings({"removal", "restricted"}) + @SuppressWarnings("restricted") private static void loadPrefsLib() { - PrivilegedAction<Void> load = () -> { - System.loadLibrary("prefs"); - return null; - }; - AccessController.doPrivileged(load); + System.loadLibrary("prefs"); } /** @@ -67,8 +60,7 @@ private static void loadPrefsLib() { */ @SuppressWarnings("removal") private static final int SYNC_INTERVAL = Math.max(1, - AccessController.doPrivileged((PrivilegedAction<Integer>) () -> - Integer.getInteger("java.util.prefs.syncInterval", 30))); + Integer.getInteger("java.util.prefs.syncInterval", 30)); /** * Returns logger for error messages. Backing store exceptions are logged at @@ -117,52 +109,47 @@ static Preferences getUserRoot() { return root; } - @SuppressWarnings("removal") private static void setupUserRoot() { - AccessController.doPrivileged(new PrivilegedAction<Void>() { - public Void run() { - userRootDir = - new File(System.getProperty("java.util.prefs.userRoot", + userRootDir = + new File(System.getProperty("java.util.prefs.userRoot", System.getProperty("user.home")), ".java/.userPrefs"); - // Attempt to create root dir if it does not yet exist. - if (!userRootDir.exists()) { - if (userRootDir.mkdirs()) { - try { - chmod(userRootDir.getCanonicalPath(), USER_RWX); - } catch (IOException e) { - getLogger().warning("Could not change permissions" + - " on userRoot directory. "); - } - getLogger().info("Created user preferences directory."); - } - else - getLogger().warning("Couldn't create user preferences" + - " directory. User preferences are unusable."); - } - isUserRootWritable = userRootDir.canWrite(); - String USER_NAME = System.getProperty("user.name"); - userLockFile = new File (userRootDir,".user.lock." + USER_NAME); - userRootModFile = new File (userRootDir, - ".userRootModFile." + USER_NAME); - if (!userRootModFile.exists()) + // Attempt to create root dir if it does not yet exist. + if (!userRootDir.exists()) { + if (userRootDir.mkdirs()) { try { - // create if does not exist. - userRootModFile.createNewFile(); - // Only user can read/write userRootModFile. - int result = chmod(userRootModFile.getCanonicalPath(), - USER_READ_WRITE); - if (result !=0) - getLogger().warning("Problem creating userRoot " + - "mod file. Chmod failed on " + - userRootModFile.getCanonicalPath() + - " Unix error code " + result); + chmod(userRootDir.getCanonicalPath(), USER_RWX); } catch (IOException e) { - getLogger().warning(e.toString()); + getLogger().warning("Could not change permissions" + + " on userRoot directory. "); } - userRootModTime = userRootModFile.lastModified(); - return null; + getLogger().info("Created user preferences directory."); + } else { + getLogger().warning("Couldn't create user preferences" + + " directory. User preferences are unusable."); } - }); + } + isUserRootWritable = userRootDir.canWrite(); + String USER_NAME = System.getProperty("user.name"); + userLockFile = new File(userRootDir,".user.lock." + USER_NAME); + userRootModFile = new File (userRootDir, + ".userRootModFile." + USER_NAME); + if (!userRootModFile.exists()) { + try { + // create if does not exist. + userRootModFile.createNewFile(); + // Only user can read/write userRootModFile. + int result = chmod(userRootModFile.getCanonicalPath(), + USER_READ_WRITE); + if (result != 0) + getLogger().warning("Problem creating userRoot " + + "mod file. Chmod failed on " + + userRootModFile.getCanonicalPath() + + " Unix error code " + result); + } catch (IOException e) { + getLogger().warning(e.toString()); + } + } + userRootModTime = userRootModFile.lastModified(); } @@ -185,58 +172,54 @@ static Preferences getSystemRoot() { return root; } - @SuppressWarnings("removal") private static void setupSystemRoot() { - AccessController.doPrivileged(new PrivilegedAction<Void>() { - public Void run() { - String systemPrefsDirName = - System.getProperty("java.util.prefs.systemRoot","/etc/.java"); - systemRootDir = - new File(systemPrefsDirName, ".systemPrefs"); - // Attempt to create root dir if it does not yet exist. - if (!systemRootDir.exists()) { - // system root does not exist in /etc/.java - // Switching to java.home - systemRootDir = - new File(System.getProperty("java.home"), - ".systemPrefs"); - if (!systemRootDir.exists()) { - if (systemRootDir.mkdirs()) { - getLogger().info( - "Created system preferences directory " - + "in java.home."); - try { - chmod(systemRootDir.getCanonicalPath(), - USER_RWX_ALL_RX); - } catch (IOException e) { - } - } else { - getLogger().warning("Could not create " - + "system preferences directory. System " - + "preferences are unusable."); - } + String systemPrefsDirName = + System.getProperty("java.util.prefs.systemRoot", "/etc/.java"); + systemRootDir = + new File(systemPrefsDirName, ".systemPrefs"); + // Attempt to create root dir if it does not yet exist. + if (!systemRootDir.exists()) { + // system root does not exist in /etc/.java + // Switching to java.home + systemRootDir = + new File(System.getProperty("java.home"), + ".systemPrefs"); + if (!systemRootDir.exists()) { + if (systemRootDir.mkdirs()) { + getLogger().info( + "Created system preferences directory " + + "in java.home."); + try { + chmod(systemRootDir.getCanonicalPath(), + USER_RWX_ALL_RX); + } catch (IOException e) { } + } else { + getLogger().warning("Could not create " + + "system preferences directory. System " + + "preferences are unusable."); } - isSystemRootWritable = systemRootDir.canWrite(); - systemLockFile = new File(systemRootDir, ".system.lock"); - systemRootModFile = - new File (systemRootDir,".systemRootModFile"); - if (!systemRootModFile.exists() && isSystemRootWritable) - try { - // create if does not exist. - systemRootModFile.createNewFile(); - int result = chmod(systemRootModFile.getCanonicalPath(), - USER_RW_ALL_READ); - if (result !=0) - getLogger().warning("Chmod failed on " + - systemRootModFile.getCanonicalPath() + - " Unix error code " + result); - } catch (IOException e) { getLogger().warning(e.toString()); + } + } + isSystemRootWritable = systemRootDir.canWrite(); + systemLockFile = new File(systemRootDir, ".system.lock"); + systemRootModFile = new File (systemRootDir, ".systemRootModFile"); + if (!systemRootModFile.exists() && isSystemRootWritable) { + try { + // create if does not exist. + systemRootModFile.createNewFile(); + int result = chmod(systemRootModFile.getCanonicalPath(), + USER_RW_ALL_READ); + if (result != 0) { + getLogger().warning("Chmod failed on " + + systemRootModFile.getCanonicalPath() + + " Unix error code " + result); } - systemRootModTime = systemRootModFile.lastModified(); - return null; + } catch (IOException e) { + getLogger().warning(e.toString()); } - }); + } + systemRootModTime = systemRootModFile.lastModified(); } @@ -456,7 +439,6 @@ private void replayChanges() { addShutdownHook(); } - @SuppressWarnings("removal") private static void addShutdownHook() { // Add periodic timer task to periodically sync cached prefs syncTimer.schedule(new TimerTask() { @@ -466,16 +448,11 @@ public void run() { }, SYNC_INTERVAL*1000, SYNC_INTERVAL*1000); // Add shutdown hook to flush cached prefs on normal termination - AccessController.doPrivileged(new PrivilegedAction<Void>() { - public Void run() { - Runtime.getRuntime().addShutdownHook( - new Thread(null, null, "Sync Timer Thread", 0, false) { - public void run() { - syncTimer.cancel(); - syncWorld(); - } - }); - return null; + Runtime.getRuntime().addShutdownHook( + new Thread(null, null, "Sync Timer Thread", 0, false) { + public void run() { + syncTimer.cancel(); + syncWorld(); } }); } @@ -526,19 +503,13 @@ private FileSystemPreferences(boolean user) { * parent node and name. This constructor, called from childSpi, * is used to make every node except for the two //roots. */ - @SuppressWarnings("removal") private FileSystemPreferences(FileSystemPreferences parent, String name) { super(parent, name); isUserNode = parent.isUserNode; dir = new File(parent.dir, dirName(name)); prefsFile = new File(dir, "prefs.xml"); tmpFile = new File(dir, "prefs.tmp"); - AccessController.doPrivileged(new PrivilegedAction<Void>() { - public Void run() { - newNode = !dir.exists(); - return null; - } - }); + newNode = !dir.exists(); if (newNode) { // These 2 things guarantee node will get written at next flush/sync prefsCache = new TreeMap<>(); @@ -596,43 +567,32 @@ private void initCacheIfNecessary() { * fails, a BackingStoreException is thrown and both prefsCache and * lastSyncTime are unaffected by the call. */ - @SuppressWarnings("removal") private void loadCache() throws BackingStoreException { + Map<String, String> m = new TreeMap<>(); + long newLastSyncTime = 0; try { - AccessController.doPrivileged( - new PrivilegedExceptionAction<Void>() { - public Void run() throws BackingStoreException { - Map<String, String> m = new TreeMap<>(); - long newLastSyncTime = 0; - try { - newLastSyncTime = prefsFile.lastModified(); - try (FileInputStream fis = new FileInputStream(prefsFile)) { - XmlSupport.importMap(fis, m); - } - } catch(Exception e) { - if (e instanceof InvalidPreferencesFormatException) { - getLogger().warning("Invalid preferences format in " - + prefsFile.getPath()); - prefsFile.renameTo( new File( - prefsFile.getParentFile(), - "IncorrectFormatPrefs.xml")); - m = new TreeMap<>(); - } else if (e instanceof FileNotFoundException) { - getLogger().warning("Prefs file removed in background " - + prefsFile.getPath()); - } else { - throw new BackingStoreException(e); - } - } - // Attempt succeeded; update state - prefsCache = m; - lastSyncTime = newLastSyncTime; - return null; - } - }); - } catch (PrivilegedActionException e) { - throw (BackingStoreException) e.getException(); + newLastSyncTime = prefsFile.lastModified(); + try (FileInputStream fis = new FileInputStream(prefsFile)) { + XmlSupport.importMap(fis, m); + } + } catch(Exception e) { + if (e instanceof InvalidPreferencesFormatException) { + getLogger().warning("Invalid preferences format in " + + prefsFile.getPath()); + prefsFile.renameTo( new File( + prefsFile.getParentFile(), + "IncorrectFormatPrefs.xml")); + m = new TreeMap<>(); + } else if (e instanceof FileNotFoundException) { + getLogger().warning("Prefs file removed in background " + + prefsFile.getPath()); + } else { + throw new BackingStoreException(e); + } } + // Attempt succeeded; update state + prefsCache = m; + lastSyncTime = newLastSyncTime; } /** @@ -644,32 +604,21 @@ public Void run() throws BackingStoreException { * and lastSyncTime will be unaffected by this call. This call will * NEVER leave prefsFile in a corrupt state. */ - @SuppressWarnings("removal") private void writeBackCache() throws BackingStoreException { try { - AccessController.doPrivileged( - new PrivilegedExceptionAction<Void>() { - public Void run() throws BackingStoreException { - try { - if (!dir.exists() && !dir.mkdirs()) - throw new BackingStoreException(dir + - " create failed."); - try (FileOutputStream fos = new FileOutputStream(tmpFile)) { - XmlSupport.exportMap(fos, prefsCache); - } - if (!tmpFile.renameTo(prefsFile)) - throw new BackingStoreException("Can't rename " + - tmpFile + " to " + prefsFile); - } catch(Exception e) { - if (e instanceof BackingStoreException) - throw (BackingStoreException)e; - throw new BackingStoreException(e); - } - return null; - } - }); - } catch (PrivilegedActionException e) { - throw (BackingStoreException) e.getException(); + if (!dir.exists() && !dir.mkdirs()) + throw new BackingStoreException(dir + + " create failed."); + try (FileOutputStream fos = new FileOutputStream(tmpFile)) { + XmlSupport.exportMap(fos, prefsCache); + } + if (!tmpFile.renameTo(prefsFile)) + throw new BackingStoreException("Can't rename " + + tmpFile + " to " + prefsFile); + } catch(BackingStoreException e) { + throw e; + } catch(Exception e) { + throw new BackingStoreException(e); } } @@ -678,21 +627,15 @@ protected String[] keysSpi() { return prefsCache.keySet().toArray(new String[prefsCache.size()]); } - @SuppressWarnings("removal") protected String[] childrenNamesSpi() { - return AccessController.doPrivileged( - new PrivilegedAction<String[]>() { - public String[] run() { - List<String> result = new ArrayList<>(); - File[] dirContents = dir.listFiles(); - if (dirContents != null) { - for (int i = 0; i < dirContents.length; i++) - if (dirContents[i].isDirectory()) - result.add(nodeName(dirContents[i].getName())); - } - return result.toArray(EMPTY_STRING_ARRAY); - } - }); + List<String> result = new ArrayList<>(); + File[] dirContents = dir.listFiles(); + if (dirContents != null) { + for (int i = 0; i < dirContents.length; i++) + if (dirContents[i].isDirectory()) + result.add(nodeName(dirContents[i].getName())); + } + return result.toArray(EMPTY_STRING_ARRAY); } private static final String[] EMPTY_STRING_ARRAY = new String[0]; @@ -717,42 +660,30 @@ public void removeNode() throws BackingStoreException { /** * Called with file lock held (in addition to node locks). */ - @SuppressWarnings("removal") protected void removeNodeSpi() throws BackingStoreException { - try { - AccessController.doPrivileged( - new PrivilegedExceptionAction<Void>() { - public Void run() throws BackingStoreException { - if (changeLog.contains(nodeCreate)) { - changeLog.remove(nodeCreate); - nodeCreate = null; - return null; - } - if (!dir.exists()) - return null; - prefsFile.delete(); - tmpFile.delete(); - // dir should be empty now. If it's not, empty it - File[] junk = dir.listFiles(); - if (junk.length != 0) { - getLogger().warning( - "Found extraneous files when removing node: " - + Arrays.asList(junk)); - for (int i=0; i<junk.length; i++) - junk[i].delete(); - } - if (!dir.delete()) - throw new BackingStoreException("Couldn't delete dir: " - + dir); - return null; - } - }); - } catch (PrivilegedActionException e) { - throw (BackingStoreException) e.getException(); + if (changeLog.contains(nodeCreate)) { + changeLog.remove(nodeCreate); + nodeCreate = null; + return; + } + if (!dir.exists()) + return; + prefsFile.delete(); + tmpFile.delete(); + // dir should be empty now. If it's not, empty it + File[] junk = dir.listFiles(); + if (junk.length != 0) { + getLogger().warning( + "Found extraneous files when removing node: " + + Arrays.asList(junk)); + for (int i=0; i<junk.length; i++) + junk[i].delete(); } + if (!dir.delete()) + throw new BackingStoreException("Couldn't delete dir: " + + dir); } - @SuppressWarnings("removal") public synchronized void sync() throws BackingStoreException { boolean userNode = isUserNode(); boolean shared; @@ -765,58 +696,34 @@ public synchronized void sync() throws BackingStoreException { shared = !isSystemRootWritable; } synchronized (isUserNode()? userLockFile:systemLockFile) { - if (!lockFile(shared)) - throw(new BackingStoreException("Couldn't get file lock.")); - final Long newModTime = - AccessController.doPrivileged( - new PrivilegedAction<Long>() { - public Long run() { - long nmt; - if (isUserNode()) { - nmt = userRootModFile.lastModified(); - isUserRootModified = userRootModTime == nmt; - } else { - nmt = systemRootModFile.lastModified(); - isSystemRootModified = systemRootModTime == nmt; - } - return nmt; - } - }); + if (!lockFile(shared)) { + throw (new BackingStoreException("Couldn't get file lock.")); + } + long nmt; + if (isUserNode()) { + nmt = userRootModFile.lastModified(); + isUserRootModified = userRootModTime == nmt; + } else { + nmt = systemRootModFile.lastModified(); + isSystemRootModified = systemRootModTime == nmt; + } + final long newModTime = nmt; try { super.sync(); - AccessController.doPrivileged(new PrivilegedAction<Void>() { - public Void run() { - if (isUserNode()) { - userRootModTime = newModTime.longValue() + 1000; - userRootModFile.setLastModified(userRootModTime); - } else { - systemRootModTime = newModTime.longValue() + 1000; - systemRootModFile.setLastModified(systemRootModTime); - } - return null; - } - }); + if (isUserNode()) { + userRootModTime = newModTime + 1000; + userRootModFile.setLastModified(userRootModTime); + } else { + systemRootModTime = newModTime + 1000; + systemRootModFile.setLastModified(systemRootModTime); + } } finally { unlockFile(); } } } - @SuppressWarnings("removal") protected void syncSpi() throws BackingStoreException { - try { - AccessController.doPrivileged( - new PrivilegedExceptionAction<Void>() { - public Void run() throws BackingStoreException { - syncSpiPrivileged(); - return null; - } - }); - } catch (PrivilegedActionException e) { - throw (BackingStoreException) e.getException(); - } - } - private void syncSpiPrivileged() throws BackingStoreException { if (isRemoved()) throw new IllegalStateException("Node has been removed"); if (prefsCache == null) diff --git a/src/java.prefs/windows/classes/java/util/prefs/WindowsPreferences.java b/src/java.prefs/windows/classes/java/util/prefs/WindowsPreferences.java index 885535755a2..7b69e1ee29a 100644 --- a/src/java.prefs/windows/classes/java/util/prefs/WindowsPreferences.java +++ b/src/java.prefs/windows/classes/java/util/prefs/WindowsPreferences.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -27,8 +27,6 @@ import java.util.StringTokenizer; import java.io.ByteArrayOutputStream; -import java.security.AccessController; -import java.security.PrivilegedAction; import sun.util.logging.PlatformLogger; @@ -50,13 +48,9 @@ class WindowsPreferences extends AbstractPreferences { loadPrefsLib(); } - @SuppressWarnings({"removal", "restricted"}) + @SuppressWarnings("restricted") private static void loadPrefsLib() { - PrivilegedAction<Void> load = () -> { - System.loadLibrary("prefs"); - return null; - }; - AccessController.doPrivileged(load); + System.loadLibrary("prefs"); } /** From 43603ac2f9cb0b74b7baa61c14a29959970c7769 Mon Sep 17 00:00:00 2001 From: Phil Race <prr@openjdk.org> Date: Tue, 26 Nov 2024 06:57:06 +0000 Subject: [PATCH 236/311] 8344894: Obsolete reference to checking permissions in java.awt.Composite Reviewed-by: kizune, kcr, azvegint --- src/java.desktop/share/classes/java/awt/Composite.java | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/java.desktop/share/classes/java/awt/Composite.java b/src/java.desktop/share/classes/java/awt/Composite.java index d86b73abac3..5b024446714 100644 --- a/src/java.desktop/share/classes/java/awt/Composite.java +++ b/src/java.desktop/share/classes/java/awt/Composite.java @@ -53,14 +53,6 @@ * {@code Graphics2D}, resulting from the modification of * the {@code Composite} object after it has been set in the * {@code Graphics2D} context. - * <p> - * Since this interface must expose the contents of pixels on the - * target device or image to potentially arbitrary code, the use of - * custom objects which implement this interface when rendering directly - * to a screen device is governed by the {@code readDisplayPixels} - * {@link AWTPermission}. The permission check will occur when such - * a custom object is passed to the {@code setComposite} method - * of a {@code Graphics2D} retrieved from a {@link Component}. * @see AlphaComposite * @see CompositeContext * @see Graphics2D#setComposite From ca81ab5ebc10722171ac861aa460bfaf520f3c7d Mon Sep 17 00:00:00 2001 From: Phil Race <prr@openjdk.org> Date: Tue, 26 Nov 2024 07:03:15 +0000 Subject: [PATCH 237/311] 8344994: Remove most uses of RuntimePermission checks in java.desktop Reviewed-by: azvegint --- .../classes/com/apple/eawt/Application.java | 10 ----- .../classes/com/apple/eio/FileManager.java | 17 -------- .../classes/sun/lwawt/macosx/CPrinterJob.java | 6 +-- .../sun/lwawt/macosx/CPrinterJobDialog.java | 4 +- .../share/classes/java/awt/Font.java | 8 ---- .../share/classes/java/awt/Taskbar.java | 24 ----------- .../classes/java/awt/color/ICC_Profile.java | 1 - .../accessibility/AccessibilityProvider.java | 31 -------------- .../share/classes/javax/imageio/ImageIO.java | 40 +------------------ .../share/classes/sun/print/PrintJob2D.java | 15 ------- .../classes/sun/print/RasterPrinterJob.java | 38 ------------------ .../classes/sun/print/ServiceDialog.java | 36 ++--------------- .../classes/sun/awt/windows/WPrinterJob.java | 18 --------- .../libawt/windows/awt_PrintControl.cpp | 11 ----- .../native/libawt/windows/awt_PrintControl.h | 1 - 15 files changed, 8 insertions(+), 252 deletions(-) diff --git a/src/java.desktop/macosx/classes/com/apple/eawt/Application.java b/src/java.desktop/macosx/classes/com/apple/eawt/Application.java index 6ed4a7c1daf..d9f01f75dd9 100644 --- a/src/java.desktop/macosx/classes/com/apple/eawt/Application.java +++ b/src/java.desktop/macosx/classes/com/apple/eawt/Application.java @@ -79,7 +79,6 @@ public class Application { static Application sApplication = null; static { - checkSecurity(); Toolkit.getDefaultToolkit(); // Start AppKit if (!Beans.isDesignTime()) { nativeInitializeApplicationDelegate(); @@ -88,20 +87,12 @@ public class Application { sApplication = new Application(); } - private static void checkSecurity() { - @SuppressWarnings("removal") - final SecurityManager security = System.getSecurityManager(); - if (security == null) return; - security.checkPermission(new RuntimePermission("canProcessApplicationEvents")); - } - /** * @return the singleton representing this Mac OS X Application * * @since 1.4 */ public static Application getApplication() { - checkSecurity(); return sApplication; } @@ -118,7 +109,6 @@ public static Application getApplication() { */ @Deprecated public Application() { - checkSecurity(); } /** diff --git a/src/java.desktop/macosx/classes/com/apple/eio/FileManager.java b/src/java.desktop/macosx/classes/com/apple/eio/FileManager.java index 5449e3ff9e2..2f847416d21 100644 --- a/src/java.desktop/macosx/classes/com/apple/eio/FileManager.java +++ b/src/java.desktop/macosx/classes/com/apple/eio/FileManager.java @@ -254,11 +254,6 @@ public static String findFolder(short domain, int folderType) throws FileNotFoun * @since 1.4 */ public static String findFolder(short domain, int folderType, boolean createIfNeeded) throws FileNotFoundException { - @SuppressWarnings("removal") - final SecurityManager security = System.getSecurityManager(); - if (security != null) { - security.checkPermission(new RuntimePermission("canExamineFileSystem")); - } final String foundFolder = _findFolder(domain, folderType, createIfNeeded); if (foundFolder == null) throw new FileNotFoundException("Can't find folder: " + Integer.toHexString(folderType)); @@ -282,11 +277,6 @@ public static String findFolder(short domain, int folderType, boolean createIfNe */ @Deprecated public static void openURL(String url) throws IOException { - @SuppressWarnings("removal") - SecurityManager security = System.getSecurityManager(); - if (security != null) { - security.checkPermission(new RuntimePermission("canOpenURLs")); - } _openURL(url); } private static native void _openURL(String url) throws IOException; @@ -334,10 +324,6 @@ public static String getResource(String resourceName, String subDirName, String private static native String getNativeResourceFromBundle(String resourceName, String subDirName, String type) throws FileNotFoundException; private static String getResourceFromBundle(String resourceName, String subDirName, String type) throws FileNotFoundException { - @SuppressWarnings("removal") - final SecurityManager security = System.getSecurityManager(); - if (security != null) security.checkPermission(new RuntimePermission("canReadBundle")); - final String resourceFromBundle = getNativeResourceFromBundle(resourceName, subDirName, type); if (resourceFromBundle == null) throw new FileNotFoundException(resourceName); return resourceFromBundle; @@ -353,9 +339,6 @@ private static String getResourceFromBundle(String resourceName, String subDirNa * @since Java for Mac OS X 10.5 Update 2 - 1.5 */ public static String getPathToApplicationBundle() { - @SuppressWarnings("removal") - SecurityManager security = System.getSecurityManager(); - if (security != null) security.checkPermission(new RuntimePermission("canReadBundle")); return getNativePathToApplicationBundle(); } diff --git a/src/java.desktop/macosx/classes/sun/lwawt/macosx/CPrinterJob.java b/src/java.desktop/macosx/classes/sun/lwawt/macosx/CPrinterJob.java index 95cca2d3ea8..a336f427812 100644 --- a/src/java.desktop/macosx/classes/sun/lwawt/macosx/CPrinterJob.java +++ b/src/java.desktop/macosx/classes/sun/lwawt/macosx/CPrinterJob.java @@ -123,7 +123,7 @@ public boolean printDialog() throws HeadlessException { return super.printDialog(attributes); } - return jobSetup(getPageable(), checkAllowedToPrintToFile()); + return jobSetup(getPageable()); } /** @@ -580,8 +580,8 @@ public boolean pageSetup(PageFormat page, Printable painter) { * dialog. * If the dialog is to use a set of attributes, useAttributes is true. */ - private boolean jobSetup(Pageable doc, boolean allowPrintToFile) { - CPrinterDialog printerDialog = new CPrinterJobDialog(null, this, doc, allowPrintToFile); + private boolean jobSetup(Pageable doc) { + CPrinterDialog printerDialog = new CPrinterJobDialog(null, this, doc); printerDialog.setVisible(true); boolean result = printerDialog.getRetVal(); printerDialog.dispose(); diff --git a/src/java.desktop/macosx/classes/sun/lwawt/macosx/CPrinterJobDialog.java b/src/java.desktop/macosx/classes/sun/lwawt/macosx/CPrinterJobDialog.java index 562f0524f91..129cc17b515 100644 --- a/src/java.desktop/macosx/classes/sun/lwawt/macosx/CPrinterJobDialog.java +++ b/src/java.desktop/macosx/classes/sun/lwawt/macosx/CPrinterJobDialog.java @@ -32,12 +32,10 @@ @SuppressWarnings("serial") // JDK implementation class final class CPrinterJobDialog extends CPrinterDialog { private Pageable fPageable; - private boolean fAllowPrintToFile; - CPrinterJobDialog(Frame parent, CPrinterJob printerJob, Pageable doc, boolean allowPrintToFile) { + CPrinterJobDialog(Frame parent, CPrinterJob printerJob, Pageable doc) { super(parent, printerJob); fPageable = doc; - fAllowPrintToFile = allowPrintToFile; } @Override diff --git a/src/java.desktop/share/classes/java/awt/Font.java b/src/java.desktop/share/classes/java/awt/Font.java index 3df4632f9d3..4de61473707 100644 --- a/src/java.desktop/share/classes/java/awt/Font.java +++ b/src/java.desktop/share/classes/java/awt/Font.java @@ -36,7 +36,6 @@ import java.awt.peer.FontPeer; import java.io.File; import java.io.FileOutputStream; -import java.io.FilePermission; import java.io.IOException; import java.io.InputStream; import java.io.ObjectOutputStream; @@ -1231,13 +1230,6 @@ private static File checkFontFile(int fontFormat, File fontFile) fontFormat != Font.TYPE1_FONT) { throw new IllegalArgumentException ("font format not recognized"); } - @SuppressWarnings("removal") - SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - FilePermission filePermission = - new FilePermission(fontFile.getPath(), "read"); - sm.checkPermission(filePermission); - } if (!fontFile.canRead()) { throw new IOException("Can't read " + fontFile); } diff --git a/src/java.desktop/share/classes/java/awt/Taskbar.java b/src/java.desktop/share/classes/java/awt/Taskbar.java index 8922c7380b0..2a46aca7116 100644 --- a/src/java.desktop/share/classes/java/awt/Taskbar.java +++ b/src/java.desktop/share/classes/java/awt/Taskbar.java @@ -177,19 +177,6 @@ private void checkFeatureSupport(Feature featureType){ } } - /** - * Calls to the security manager's {@code checkPermission} method with - * an {@code RuntimePermission("canProcessApplicationEvents")} permissions. - */ - private void checkEventsProcessingPermission(){ - @SuppressWarnings("removal") - SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - sm.checkPermission(new RuntimePermission( - "canProcessApplicationEvents")); - } - } - private Taskbar() { Toolkit defaultToolkit = Toolkit.getDefaultToolkit(); if (defaultToolkit instanceof SunToolkit) { @@ -265,7 +252,6 @@ public static boolean isTaskbarSupported(){ * does not support the {@link Taskbar.Feature#USER_ATTENTION} feature */ public void requestUserAttention(final boolean enabled, final boolean critical) { - checkEventsProcessingPermission(); checkFeatureSupport(Feature.USER_ATTENTION); peer.requestUserAttention(enabled, critical); } @@ -282,7 +268,6 @@ public void requestUserAttention(final boolean enabled, final boolean critical) * does not support the {@link Taskbar.Feature#USER_ATTENTION_WINDOW} feature */ public void requestWindowUserAttention(Window w) { - checkEventsProcessingPermission(); checkFeatureSupport(Feature.USER_ATTENTION_WINDOW); peer.requestWindowUserAttention(w); } @@ -296,7 +281,6 @@ public void requestWindowUserAttention(Window w) { * does not support the {@link Taskbar.Feature#MENU} feature */ public void setMenu(final PopupMenu menu) { - checkEventsProcessingPermission(); checkFeatureSupport(Feature.MENU); peer.setMenu(menu); } @@ -309,7 +293,6 @@ public void setMenu(final PopupMenu menu) { * does not support the {@link Taskbar.Feature#MENU} feature */ public PopupMenu getMenu() { - checkEventsProcessingPermission(); checkFeatureSupport(Feature.MENU); return peer.getMenu(); } @@ -322,7 +305,6 @@ public PopupMenu getMenu() { * does not support the {@link Taskbar.Feature#ICON_IMAGE} feature */ public void setIconImage(final Image image) { - checkEventsProcessingPermission(); checkFeatureSupport(Feature.ICON_IMAGE); peer.setIconImage(image); } @@ -339,7 +321,6 @@ public void setIconImage(final Image image) { * does not support the {@link Taskbar.Feature#ICON_IMAGE} feature */ public Image getIconImage() { - checkEventsProcessingPermission(); checkFeatureSupport(Feature.ICON_IMAGE); return peer.getIconImage(); } @@ -360,7 +341,6 @@ public Image getIconImage() { * or {@link Taskbar.Feature#ICON_BADGE_TEXT} feature */ public void setIconBadge(final String badge) { - checkEventsProcessingPermission(); checkFeatureSupport(Feature.ICON_BADGE_NUMBER); peer.setIconBadge(badge); } @@ -380,7 +360,6 @@ public void setIconBadge(final String badge) { * does not support the {@link Taskbar.Feature#ICON_BADGE_IMAGE_WINDOW} feature */ public void setWindowIconBadge(Window w, final Image badge) { - checkEventsProcessingPermission(); checkFeatureSupport(Feature.ICON_BADGE_IMAGE_WINDOW); if (w != null) { peer.setWindowIconBadge(w, badge); @@ -396,7 +375,6 @@ public void setWindowIconBadge(Window w, final Image badge) { * does not support the {@link Taskbar.Feature#PROGRESS_VALUE} feature */ public void setProgressValue(int value) { - checkEventsProcessingPermission(); checkFeatureSupport(Feature.PROGRESS_VALUE); peer.setProgressValue(value); } @@ -426,7 +404,6 @@ public void setProgressValue(int value) { * does not support the {@link Taskbar.Feature#PROGRESS_VALUE_WINDOW} feature */ public void setWindowProgressValue(Window w, int value) { - checkEventsProcessingPermission(); checkFeatureSupport(Feature.PROGRESS_VALUE_WINDOW); if (w != null) { peer.setWindowProgressValue(w, value); @@ -458,7 +435,6 @@ public void setWindowProgressValue(Window w, int value) { * does not support the {@link Taskbar.Feature#PROGRESS_STATE_WINDOW} feature */ public void setWindowProgressState(Window w, State state) { - checkEventsProcessingPermission(); checkFeatureSupport(Feature.PROGRESS_STATE_WINDOW); if (w != null) { peer.setWindowProgressState(w, state); diff --git a/src/java.desktop/share/classes/java/awt/color/ICC_Profile.java b/src/java.desktop/share/classes/java/awt/color/ICC_Profile.java index 729d8123a24..d4bae0d08ce 100644 --- a/src/java.desktop/share/classes/java/awt/color/ICC_Profile.java +++ b/src/java.desktop/share/classes/java/awt/color/ICC_Profile.java @@ -39,7 +39,6 @@ import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; -import java.io.FilePermission; import java.io.IOException; import java.io.InputStream; import java.io.ObjectInputStream; diff --git a/src/java.desktop/share/classes/javax/accessibility/AccessibilityProvider.java b/src/java.desktop/share/classes/javax/accessibility/AccessibilityProvider.java index abf6f471916..8ca6f8332f6 100644 --- a/src/java.desktop/share/classes/javax/accessibility/AccessibilityProvider.java +++ b/src/java.desktop/share/classes/javax/accessibility/AccessibilityProvider.java @@ -52,37 +52,6 @@ public abstract class AccessibilityProvider { * Initializes a new accessibility provider. */ protected AccessibilityProvider() { - // Use a permission check when calling a private constructor to check - // that the proper security permission has been granted before the - // {@code Object} superclass is called. If an exception is thrown before - // the {@code Object} superclass is constructed a finalizer in a - // subclass of this class will not be run. This protects against a - // finalizer vulnerability. - this(checkPermission()); - } - - /** - * Allows to check a permission before the {@code Object} is called. - * - * @param ignore unused stub to call a {@link #checkPermission()}} - */ - private AccessibilityProvider(Void ignore) { } - - /** - * If this code is running with a security manager and if the permission - * {@code "accessibilityProvider"} has not been granted - * {@code SecurityException} will be thrown. - * - * @return {@code null} if {@code SecurityException} was not thrown - * @throws SecurityException If a security manager has been installed and it - * denies {@link RuntimePermission} {@code "accessibilityProvider"} - */ - private static Void checkPermission() { - @SuppressWarnings("removal") - SecurityManager sm = System.getSecurityManager(); - if (sm != null) - sm.checkPermission(new RuntimePermission("accessibilityProvider")); - return null; } /** diff --git a/src/java.desktop/share/classes/javax/imageio/ImageIO.java b/src/java.desktop/share/classes/javax/imageio/ImageIO.java index f085383284e..8180145a8ea 100644 --- a/src/java.desktop/share/classes/javax/imageio/ImageIO.java +++ b/src/java.desktop/share/classes/javax/imageio/ImageIO.java @@ -28,7 +28,6 @@ import java.awt.image.BufferedImage; import java.awt.image.RenderedImage; import java.io.File; -import java.io.FilePermission; import java.io.InputStream; import java.io.IOException; import java.io.OutputStream; @@ -170,50 +169,13 @@ private static String getTempDir() { /** * Determines whether the caller has write access to the cache * directory, stores the result in the {@code CacheInfo} object, - * and returns the decision. This method helps to prevent mysterious - * SecurityExceptions to be thrown when this convenience class is used - * in an applet, for example. + * and returns the decision. */ private static boolean hasCachePermission() { Boolean hasPermission = getCacheInfo().getHasPermission(); - if (hasPermission != null) { return hasPermission.booleanValue(); } else { - try { - @SuppressWarnings("removal") - SecurityManager security = System.getSecurityManager(); - if (security != null) { - File cachedir = getCacheDirectory(); - String cachepath; - - if (cachedir != null) { - cachepath = cachedir.getPath(); - } else { - cachepath = getTempDir(); - - if (cachepath == null || cachepath.isEmpty()) { - getCacheInfo().setHasPermission(Boolean.FALSE); - return false; - } - } - - // we have to check whether we can read, write, - // and delete cache files. - // So, compose cache file path and check it. - String filepath = cachepath; - if (!filepath.endsWith(File.separator)) { - filepath += File.separator; - } - filepath += "*"; - - security.checkPermission(new FilePermission(filepath, "read, write, delete")); - } - } catch (SecurityException e) { - getCacheInfo().setHasPermission(Boolean.FALSE); - return false; - } - getCacheInfo().setHasPermission(Boolean.TRUE); return true; } diff --git a/src/java.desktop/share/classes/sun/print/PrintJob2D.java b/src/java.desktop/share/classes/sun/print/PrintJob2D.java index 975c9c47d54..fbec484435f 100644 --- a/src/java.desktop/share/classes/sun/print/PrintJob2D.java +++ b/src/java.desktop/share/classes/sun/print/PrintJob2D.java @@ -42,7 +42,6 @@ import java.awt.print.PrinterJob; import java.io.File; -import java.io.FilePermission; import java.io.IOException; import java.net.URI; @@ -351,7 +350,6 @@ private void initPrintJob2D(Frame frame, String doctitle, // Verify that the app has access to the file system DestinationType dest= this.jobAttributes.getDestination(); if (dest == DestinationType.FILE) { - throwPrintToFile(); // check if given filename is valid String destStr = jobAttributes.getFileName(); @@ -1264,17 +1262,4 @@ private void translateOutputProps() { props.setProperty(PAPERSIZE_PROP, str); } - private void throwPrintToFile() { - @SuppressWarnings("removal") - SecurityManager security = System.getSecurityManager(); - FilePermission printToFilePermission = null; - if (security != null) { - if (printToFilePermission == null) { - printToFilePermission = - new FilePermission("<<ALL FILES>>", "read,write"); - } - security.checkPermission(printToFilePermission); - } - } - } diff --git a/src/java.desktop/share/classes/sun/print/RasterPrinterJob.java b/src/java.desktop/share/classes/sun/print/RasterPrinterJob.java index bf380873d2b..4e096f506e5 100644 --- a/src/java.desktop/share/classes/sun/print/RasterPrinterJob.java +++ b/src/java.desktop/share/classes/sun/print/RasterPrinterJob.java @@ -25,8 +25,6 @@ package sun.print; -import java.io.FilePermission; - import java.awt.Color; import java.awt.Graphics2D; import java.awt.GraphicsConfiguration; @@ -256,11 +254,6 @@ public abstract class RasterPrinterJob extends PrinterJob { // MacOSX - made protected so subclasses can reference it. protected boolean userCancelled = false; - /** - * Print to file permission variables. - */ - private FilePermission printToFilePermission; - /** * List of areas & the graphics state for redrawing */ @@ -2501,37 +2494,6 @@ protected void initPrinterGraphics(Graphics2D g, Rectangle2D clip) { g.setPaint(Color.black); } - - /** - * User dialogs should disable "File" buttons if this returns false. - * - */ - public boolean checkAllowedToPrintToFile() { - try { - throwPrintToFile(); - return true; - } catch (SecurityException e) { - return false; - } - } - - /** - * Break this out as it may be useful when we allow API to - * specify printing to a file. In that case its probably right - * to throw a SecurityException if the permission is not granted - */ - private void throwPrintToFile() { - @SuppressWarnings("removal") - SecurityManager security = System.getSecurityManager(); - if (security != null) { - if (printToFilePermission == null) { - printToFilePermission = - new FilePermission("<<ALL FILES>>", "read,write"); - } - security.checkPermission(printToFilePermission); - } - } - /* On-screen drawString renders most control chars as the missing glyph * and have the non-zero advance of that glyph. * Exceptions are \t, \n and \r which are considered zero-width. diff --git a/src/java.desktop/share/classes/sun/print/ServiceDialog.java b/src/java.desktop/share/classes/sun/print/ServiceDialog.java index ae2c787ce36..ba530bbf58f 100644 --- a/src/java.desktop/share/classes/sun/print/ServiceDialog.java +++ b/src/java.desktop/share/classes/sun/print/ServiceDialog.java @@ -46,7 +46,6 @@ import java.awt.event.WindowAdapter; import java.awt.print.PrinterJob; import java.io.File; -import java.io.FilePermission; import java.io.IOException; import java.net.URI; import java.net.URL; @@ -680,14 +679,12 @@ private class PrintServicePanel extends JPanel implements ActionListener, ItemListener, PopupMenuListener { private final String strTitle = getMsg("border.printservice"); - private FilePermission printToFilePermission; private JButton btnProperties; private JCheckBox cbPrintToFile; private JComboBox<String> cbName; private JLabel lblType, lblStatus, lblInfo; private ServiceUIFactory uiFactory; private boolean changedService = false; - private boolean filePermission; public PrintServicePanel() { super(); @@ -744,8 +741,6 @@ public PrintServicePanel() { c.gridwidth = GridBagConstraints.REMAINDER; cbPrintToFile = createCheckBox("checkbox.printtofile", this); addToGB(cbPrintToFile, this, gridbag, c); - - filePermission = allowedToPrintToFile(); } public boolean isPrintToFileSelected() { @@ -873,37 +868,13 @@ public void popupMenuCanceled(PopupMenuEvent e) { * We disable the "Print To File" checkbox if this returns false */ private boolean allowedToPrintToFile() { - try { - throwPrintToFile(); - return true; - } catch (SecurityException e) { - return false; - } - } - - /** - * Break this out as it may be useful when we allow API to - * specify printing to a file. In that case its probably right - * to throw a SecurityException if the permission is not granted. - */ - private void throwPrintToFile() { - @SuppressWarnings("removal") - SecurityManager security = System.getSecurityManager(); - if (security != null) { - if (printToFilePermission == null) { - printToFilePermission = - new FilePermission("<<ALL FILES>>", "read,write"); - } - security.checkPermission(printToFilePermission); - } + return true; } public void updateInfo() { Class<Destination> dstCategory = Destination.class; boolean dstSupported = false; boolean dstSelected = false; - boolean dstAllowed = filePermission ? - allowedToPrintToFile() : false; // setup Destination (print-to-file) widgets Destination dst = (Destination)asCurrent.get(dstCategory); @@ -923,9 +894,8 @@ public void updateInfo() { dstSupported = true; } } - cbPrintToFile.setEnabled(dstSupported && dstAllowed); - cbPrintToFile.setSelected(dstSelected && dstAllowed - && dstSupported); + cbPrintToFile.setEnabled(dstSupported); + cbPrintToFile.setSelected(dstSelected && dstSupported); // setup PrintService information widgets Attribute type = psCurrent.getAttribute(PrinterMakeAndModel.class); diff --git a/src/java.desktop/windows/classes/sun/awt/windows/WPrinterJob.java b/src/java.desktop/windows/classes/sun/awt/windows/WPrinterJob.java index 85b4866e232..0d41aacde2f 100644 --- a/src/java.desktop/windows/classes/sun/awt/windows/WPrinterJob.java +++ b/src/java.desktop/windows/classes/sun/awt/windows/WPrinterJob.java @@ -98,7 +98,6 @@ import sun.print.ServiceDialog; import java.awt.Frame; -import java.io.FilePermission; import sun.java2d.Disposer; import sun.java2d.DisposerRecord; @@ -1906,23 +1905,6 @@ private int getMediaTrayAttrib() { return mAttMediaTray; } - - - private boolean getPrintToFileEnabled() { - @SuppressWarnings("removal") - SecurityManager security = System.getSecurityManager(); - if (security != null) { - FilePermission printToFilePermission = - new FilePermission("<<ALL FILES>>", "read,write"); - try { - security.checkPermission(printToFilePermission); - } catch (SecurityException e) { - return false; - } - } - return true; - } - private void setNativeAttributes(int flags, int fields, int values) { if (attributes == null) { return; diff --git a/src/java.desktop/windows/native/libawt/windows/awt_PrintControl.cpp b/src/java.desktop/windows/native/libawt/windows/awt_PrintControl.cpp index 8f2dcf21caa..a8a20789eec 100644 --- a/src/java.desktop/windows/native/libawt/windows/awt_PrintControl.cpp +++ b/src/java.desktop/windows/native/libawt/windows/awt_PrintControl.cpp @@ -72,7 +72,6 @@ jmethodID AwtPrintControl::getMinPageID; jmethodID AwtPrintControl::getCollateID; jmethodID AwtPrintControl::getOrientID; jmethodID AwtPrintControl::getQualityID; -jmethodID AwtPrintControl::getPrintToFileEnabledID; jmethodID AwtPrintControl::getPrinterID; jmethodID AwtPrintControl::setPrinterID; jmethodID AwtPrintControl::getResID; @@ -369,11 +368,6 @@ void AwtPrintControl::initIDs(JNIEnv *env, jclass cls) DASSERT(AwtPrintControl::getSelectID != NULL); CHECK_NULL(AwtPrintControl::getSelectID); - AwtPrintControl::getPrintToFileEnabledID = - env->GetMethodID(cls, "getPrintToFileEnabled", "()Z"); - DASSERT(AwtPrintControl::getPrintToFileEnabledID != NULL); - CHECK_NULL(AwtPrintControl::getPrintToFileEnabledID); - AwtPrintControl::setNativeAttID = env->GetMethodID(cls, "setNativeAttributes", "(III)V"); DASSERT(AwtPrintControl::setNativeAttID != NULL); @@ -809,11 +803,6 @@ BOOL AwtPrintControl::InitPrintDialog(JNIEnv *env, pd.Flags |= selectType; } - if (!env->CallBooleanMethod(printCtrl, - AwtPrintControl::getPrintToFileEnabledID)) { - pd.Flags |= PD_DISABLEPRINTTOFILE; - } - if (pd.hDevMode != NULL) { DEVMODE *devmode = (DEVMODE *)::GlobalLock(pd.hDevMode); DASSERT(!IsBadWritePtr(devmode, sizeof(DEVMODE))); diff --git a/src/java.desktop/windows/native/libawt/windows/awt_PrintControl.h b/src/java.desktop/windows/native/libawt/windows/awt_PrintControl.h index bc782c41469..d3a77babb2e 100644 --- a/src/java.desktop/windows/native/libawt/windows/awt_PrintControl.h +++ b/src/java.desktop/windows/native/libawt/windows/awt_PrintControl.h @@ -63,7 +63,6 @@ class AwtPrintControl { static jmethodID getCollateID; static jmethodID getOrientID; static jmethodID getQualityID; - static jmethodID getPrintToFileEnabledID; static jmethodID getPrinterID; static jmethodID setPrinterID; static jmethodID getResID; From 4e68d665bef8d13adb499a803c2f68b704ea54fe Mon Sep 17 00:00:00 2001 From: Per Minborg <pminborg@openjdk.org> Date: Tue, 26 Nov 2024 08:24:21 +0000 Subject: [PATCH 238/311] 8344954: Linker tests fails on BE platforms after JDK-8340205 Reviewed-by: mdoerr, amitkumar --- test/jdk/java/foreign/TestLinker.java | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/test/jdk/java/foreign/TestLinker.java b/test/jdk/java/foreign/TestLinker.java index 4bc19965f19..798e5dd04db 100644 --- a/test/jdk/java/foreign/TestLinker.java +++ b/test/jdk/java/foreign/TestLinker.java @@ -181,7 +181,7 @@ public void interwovenPadding() { var fd = FunctionDescriptor.of(struct, struct, struct); var e = expectThrows(IllegalArgumentException.class, () -> linker.downcallHandle(fd)); assertEquals(e.getMessage(), - "The padding layout x2 was preceded by another padding layout x1 in [b1x1x2i4]"); + "The padding layout x2 was preceded by another padding layout x1 in " + struct); } @Test @@ -199,7 +199,7 @@ public void stackedPadding() { var fd = FunctionDescriptor.of(struct, struct, struct); var e = expectThrows(IllegalArgumentException.class, () -> linker.downcallHandle(fd)); assertEquals(e.getMessage(), - "The padding layout x2 was preceded by another padding layout x1 in [b1x1x2x4x8x16[[[4:j8]]|x32]]"); + "The padding layout x2 was preceded by another padding layout x1 in " + struct); } @Test @@ -208,7 +208,7 @@ public void paddingUnionByteSize3() { var union = MemoryLayout.unionLayout(MemoryLayout.paddingLayout(3), ValueLayout.JAVA_INT); var fd = FunctionDescriptor.of(union, union, union); var e = expectThrows(IllegalArgumentException.class, () -> linker.downcallHandle(fd)); - assertEquals(e.getMessage(), "Superfluous padding x3 in [x3|i4]"); + assertEquals(e.getMessage(), "Superfluous padding x3 in " + union); } @Test @@ -217,7 +217,7 @@ public void paddingUnionByteSize4() { var union = MemoryLayout.unionLayout(MemoryLayout.paddingLayout(4), ValueLayout.JAVA_INT); var fd = FunctionDescriptor.of(union, union, union); var e = expectThrows(IllegalArgumentException.class, () -> linker.downcallHandle(fd)); - assertEquals(e.getMessage(), "Superfluous padding x4 in [x4|i4]"); + assertEquals(e.getMessage(), "Superfluous padding x4 in " + union); } @Test @@ -226,7 +226,7 @@ public void paddingUnionByteSize5() { var union = MemoryLayout.unionLayout(MemoryLayout.paddingLayout(5), ValueLayout.JAVA_INT); var fd = FunctionDescriptor.of(union, union, union); var e = expectThrows(IllegalArgumentException.class, () -> linker.downcallHandle(fd)); - assertEquals(e.getMessage(), "Layout '[x5|i4]' has unexpected size: 5 != 4"); + assertEquals(e.getMessage(), "Layout '" + union + "' has unexpected size: 5 != 4"); } @Test @@ -239,7 +239,7 @@ public void paddingUnionSeveral() { MemoryLayout.paddingLayout(16)); var fd = FunctionDescriptor.of(union, union, union); var e = expectThrows(IllegalArgumentException.class, () -> linker.downcallHandle(fd)); - assertEquals(e.getMessage(), "More than one padding in [[3:i4]|j8|x16|x16]"); + assertEquals(e.getMessage(), "More than one padding in " + union); } @Test From 0105203575182e24a56a38a12da7c1af58ea0a78 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roberto=20Casta=C3=B1eda=20Lozano?= <rcastanedalo@openjdk.org> Date: Tue, 26 Nov 2024 08:51:34 +0000 Subject: [PATCH 239/311] 8337660: C2: basic blocks with only BoxLock nodes are wrongly treated as empty Co-authored-by: Emanuel Peter <epeter@openjdk.org> Reviewed-by: qamai, thartmann, kvn --- src/hotspot/share/opto/block.cpp | 11 +-- .../locks/TestSynchronizeWithEmptyBlock.java | 87 +++++++++++++++++++ 2 files changed, 93 insertions(+), 5 deletions(-) create mode 100644 test/hotspot/jtreg/compiler/locks/TestSynchronizeWithEmptyBlock.java diff --git a/src/hotspot/share/opto/block.cpp b/src/hotspot/share/opto/block.cpp index b39db528691..857bdeb7032 100644 --- a/src/hotspot/share/opto/block.cpp +++ b/src/hotspot/share/opto/block.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -181,10 +181,11 @@ int Block::is_Empty() const { return success_result; } - // Ideal nodes are allowable in empty blocks: skip them Only MachNodes - // turn directly into code, because only MachNodes have non-trivial - // emit() functions. - while ((end_idx > 0) && !get_node(end_idx)->is_Mach()) { + // Ideal nodes (except BoxLock) are allowable in empty blocks: skip them. Only + // Mach and BoxLock nodes turn directly into code via emit(). + while ((end_idx > 0) && + !get_node(end_idx)->is_Mach() && + !get_node(end_idx)->is_BoxLock()) { end_idx--; } diff --git a/test/hotspot/jtreg/compiler/locks/TestSynchronizeWithEmptyBlock.java b/test/hotspot/jtreg/compiler/locks/TestSynchronizeWithEmptyBlock.java new file mode 100644 index 00000000000..4165e6285b6 --- /dev/null +++ b/test/hotspot/jtreg/compiler/locks/TestSynchronizeWithEmptyBlock.java @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/** + * @test + * @bug 8337660 + * @summary Test that C2 does not remove blocks with BoxLock nodes that are + * otherwise empty. + * @run main/othervm -Xbatch -XX:LockingMode=1 + * -XX:CompileOnly=compiler.locks.TestSynchronizeWithEmptyBlock::* + * compiler.locks.TestSynchronizeWithEmptyBlock + * @run main/othervm -Xbatch + * -XX:CompileOnly=compiler.locks.TestSynchronizeWithEmptyBlock::* + * compiler.locks.TestSynchronizeWithEmptyBlock + */ + +package compiler.locks; + +public class TestSynchronizeWithEmptyBlock { + + static int c; + static final Object obj = new Object(); + + static void test1() { + synchronized (TestSynchronizeWithEmptyBlock.class) { + int i = 0; + while (i < 1000) { + i++; + if (i < 5); + } + } + synchronized (TestSynchronizeWithEmptyBlock.class) { + int i = 0; + do { + i++; + if (i < 4) { + boolean p = true; + int j = 0; + do { + j++; + if (p) { + c++; + } + } while (j < 100); + } + } while (i < 1000); + } + } + + static void test2() { + synchronized (obj) { + for (long i = 0; i < 1_000_000_000_000L; i+=6_500_000_000L) {} + } + synchronized (obj) { + for (long i = 0; i < 1_000_000_000_000L; i+=6_500_000_000L) {} + } + } + + public static void main(String[] args) { + for (int i = 0; i < 10_000; i++) { + test1(); + } + for (int i = 0; i < 10_000; i++) { + test2(); + } + } +} From 57d35f98f6966485c034cf096ddefcf0c7569627 Mon Sep 17 00:00:00 2001 From: Robbin Ehn <rehn@openjdk.org> Date: Tue, 26 Nov 2024 08:51:55 +0000 Subject: [PATCH 240/311] 8344382: RISC-V: CASandCAEwithNegExpected fails with Zacas Reviewed-by: fyang, mli --- .../cpu/riscv/macroAssembler_riscv.cpp | 115 ++++++++++-------- .../cpu/riscv/macroAssembler_riscv.hpp | 5 +- 2 files changed, 68 insertions(+), 52 deletions(-) diff --git a/src/hotspot/cpu/riscv/macroAssembler_riscv.cpp b/src/hotspot/cpu/riscv/macroAssembler_riscv.cpp index 81d3338638d..cf3c851a7ec 100644 --- a/src/hotspot/cpu/riscv/macroAssembler_riscv.cpp +++ b/src/hotspot/cpu/riscv/macroAssembler_riscv.cpp @@ -3313,14 +3313,11 @@ void MacroAssembler::store_conditional(Register dst, } -void MacroAssembler::cmpxchg_narrow_value_helper(Register addr, Register expected, - Register new_val, +void MacroAssembler::cmpxchg_narrow_value_helper(Register addr, Register expected, Register new_val, enum operand_size size, - Register tmp1, Register tmp2, Register tmp3) { + Register shift, Register mask, Register aligned_addr) { assert(size == int8 || size == int16, "unsupported operand size"); - Register aligned_addr = t1, shift = tmp1, mask = tmp2, not_mask = tmp3; - andi(shift, addr, 3); slli(shift, shift, 3); @@ -3335,8 +3332,6 @@ void MacroAssembler::cmpxchg_narrow_value_helper(Register addr, Register expecte } sll(mask, mask, shift); - notr(not_mask, mask); - sll(expected, expected, shift); andr(expected, expected, mask); @@ -3353,35 +3348,46 @@ void MacroAssembler::cmpxchg_narrow_value(Register addr, Register expected, Assembler::Aqrl acquire, Assembler::Aqrl release, Register result, bool result_as_bool, Register tmp1, Register tmp2, Register tmp3) { - Register aligned_addr = t1, shift = tmp1, mask = tmp2, not_mask = tmp3, old = result, tmp = t0; - assert_different_registers(addr, old, mask, not_mask, new_val, expected, shift, tmp); - cmpxchg_narrow_value_helper(addr, expected, new_val, size, tmp1, tmp2, tmp3); + assert_different_registers(addr, expected, new_val, result, tmp1, tmp2, tmp3, t0, t1); - Label retry, fail, done; + Register scratch0 = t0, aligned_addr = t1; + Register shift = tmp1, mask = tmp2, scratch1 = tmp3; + + cmpxchg_narrow_value_helper(addr, expected, new_val, size, shift, mask, aligned_addr); - bind(retry); + Label retry, fail, done; if (UseZacas) { - lw(old, aligned_addr); + lw(result, aligned_addr); + + bind(retry); // amocas loads the current value into result + notr(scratch1, mask); - // if old & mask != expected - andr(tmp, old, mask); - bne(tmp, expected, fail); + andr(scratch0, result, scratch1); // scratch0 = word - cas bits + orr(scratch1, expected, scratch0); // scratch1 = non-cas bits + cas bits + bne(result, scratch1, fail); // cas bits differ, cas failed - andr(tmp, old, not_mask); - orr(tmp, tmp, new_val); + // result is the same as expected, use as expected value. - atomic_cas(old, tmp, aligned_addr, operand_size::int32, acquire, release); - bne(tmp, old, retry); + // scratch0 is still = word - cas bits + // Or in the new value to create complete new value. + orr(scratch0, scratch0, new_val); + + mv(scratch1, result); // save our expected value + atomic_cas(result, scratch0, aligned_addr, operand_size::int32, acquire, release); + bne(scratch1, result, retry); } else { - lr_w(old, aligned_addr, acquire); - andr(tmp, old, mask); - bne(tmp, expected, fail); + notr(scratch1, mask); + bind(retry); + + lr_w(result, aligned_addr, acquire); + andr(scratch0, result, mask); + bne(scratch0, expected, fail); - andr(tmp, old, not_mask); - orr(tmp, tmp, new_val); - sc_w(tmp, tmp, aligned_addr, release); - bnez(tmp, retry); + andr(scratch0, result, scratch1); // scratch1 is ~mask + orr(scratch0, scratch0, new_val); + sc_w(scratch0, scratch0, aligned_addr, release); + bnez(scratch0, retry); } if (result_as_bool) { @@ -3393,10 +3399,10 @@ void MacroAssembler::cmpxchg_narrow_value(Register addr, Register expected, bind(done); } else { - andr(tmp, old, mask); - bind(fail); - srl(result, tmp, shift); + + andr(scratch0, result, mask); + srl(result, scratch0, shift); if (size == int8) { sign_extend(result, result, 8); @@ -3416,33 +3422,44 @@ void MacroAssembler::weak_cmpxchg_narrow_value(Register addr, Register expected, Assembler::Aqrl acquire, Assembler::Aqrl release, Register result, Register tmp1, Register tmp2, Register tmp3) { - Register aligned_addr = t1, shift = tmp1, mask = tmp2, not_mask = tmp3, old = result, tmp = t0; - assert_different_registers(addr, old, mask, not_mask, new_val, expected, shift, tmp); - cmpxchg_narrow_value_helper(addr, expected, new_val, size, tmp1, tmp2, tmp3); + assert_different_registers(addr, expected, new_val, result, tmp1, tmp2, tmp3, t0, t1); + + Register scratch0 = t0, aligned_addr = t1; + Register shift = tmp1, mask = tmp2, scratch1 = tmp3; + + cmpxchg_narrow_value_helper(addr, expected, new_val, size, shift, mask, aligned_addr); Label fail, done; if (UseZacas) { - lw(old, aligned_addr); + lw(result, aligned_addr); - // if old & mask != expected - andr(tmp, old, mask); - bne(tmp, expected, fail); + notr(scratch1, mask); - andr(tmp, old, not_mask); - orr(tmp, tmp, new_val); + andr(scratch0, result, scratch1); // scratch0 = word - cas bits + orr(scratch1, expected, scratch0); // scratch1 = non-cas bits + cas bits + bne(result, scratch1, fail); // cas bits differ, cas failed - atomic_cas(tmp, new_val, addr, operand_size::int32, acquire, release); - bne(tmp, old, fail); + // result is the same as expected, use as expected value. + + // scratch0 is still = word - cas bits + // Or in the new value to create complete new value. + orr(scratch0, scratch0, new_val); + + mv(scratch1, result); // save our expected value + atomic_cas(result, scratch0, aligned_addr, operand_size::int32, acquire, release); + bne(scratch1, result, fail); // This weak, so just bail-out. } else { - lr_w(old, aligned_addr, acquire); - andr(tmp, old, mask); - bne(tmp, expected, fail); - - andr(tmp, old, not_mask); - orr(tmp, tmp, new_val); - sc_w(tmp, tmp, aligned_addr, release); - bnez(tmp, fail); + notr(scratch1, mask); + + lr_w(result, aligned_addr, acquire); + andr(scratch0, result, mask); + bne(scratch0, expected, fail); + + andr(scratch0, result, scratch1); // scratch1 is ~mask + orr(scratch0, scratch0, new_val); + sc_w(scratch0, scratch0, aligned_addr, release); + bnez(scratch0, fail); } // Success diff --git a/src/hotspot/cpu/riscv/macroAssembler_riscv.hpp b/src/hotspot/cpu/riscv/macroAssembler_riscv.hpp index 568df056222..54f7127106b 100644 --- a/src/hotspot/cpu/riscv/macroAssembler_riscv.hpp +++ b/src/hotspot/cpu/riscv/macroAssembler_riscv.hpp @@ -1146,10 +1146,9 @@ class MacroAssembler: public Assembler { enum operand_size size, Assembler::Aqrl acquire, Assembler::Aqrl release, Register result); - void cmpxchg_narrow_value_helper(Register addr, Register expected, - Register new_val, + void cmpxchg_narrow_value_helper(Register addr, Register expected, Register new_val, enum operand_size size, - Register tmp1, Register tmp2, Register tmp3); + Register shift, Register mask, Register aligned_addr); void cmpxchg_narrow_value(Register addr, Register expected, Register new_val, enum operand_size size, From 9793e73bc1b25ed92d6f0599fd2e721249389df7 Mon Sep 17 00:00:00 2001 From: Albert Mingkun Yang <ayang@openjdk.org> Date: Tue, 26 Nov 2024 08:55:01 +0000 Subject: [PATCH 241/311] 8344853: Parallel: Improve comments in psParallelCompact Reviewed-by: sjohanss, zgu --- .../share/gc/parallel/psParallelCompact.cpp | 32 +++++++++---------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/src/hotspot/share/gc/parallel/psParallelCompact.cpp b/src/hotspot/share/gc/parallel/psParallelCompact.cpp index e90404b6502..f4e3af4407d 100644 --- a/src/hotspot/share/gc/parallel/psParallelCompact.cpp +++ b/src/hotspot/share/gc/parallel/psParallelCompact.cpp @@ -362,8 +362,9 @@ HeapWord* ParallelCompactData::summarize_split_space(size_t src_region, split_info.record(split_region, overflowing_obj, preceding_live_words); - HeapWord* src_region_start = region_to_addr(src_region); - HeapWord* new_top = destination - pointer_delta(src_region_start, overflowing_obj); + // The [overflowing_obj, src_region_start) part has been accounted for, so + // must move back the new_top, now that this overflowing obj is deferred. + HeapWord* new_top = destination - pointer_delta(region_to_addr(src_region), overflowing_obj); // If the overflowing obj was relocated to its original destination, // those destination regions would have their source_region set. Now that @@ -890,7 +891,7 @@ void PSParallelCompact::summary_phase() _summary_data.summarize_dense_prefix(old_space->bottom(), dense_prefix_end); } - // Compacting objs inn [dense_prefix_end, old_space->top()) + // Compacting objs in [dense_prefix_end, old_space->top()) _summary_data.summarize(_space_info[id].split_info(), dense_prefix_end, old_space->top(), nullptr, dense_prefix_end, old_space->end(), @@ -1596,9 +1597,9 @@ void PSParallelCompact::forward_to_new_addr() { &start_region, &end_region); for (size_t cur_region = start_region; cur_region < end_region; ++cur_region) { RegionData* region_ptr = _summary_data.region(cur_region); - size_t live_words = region_ptr->partial_obj_size(); + size_t partial_obj_size = region_ptr->partial_obj_size(); - if (live_words == ParallelCompactData::RegionSize) { + if (partial_obj_size == ParallelCompactData::RegionSize) { // No obj-start continue; } @@ -1606,19 +1607,18 @@ void PSParallelCompact::forward_to_new_addr() { HeapWord* region_start = _summary_data.region_to_addr(cur_region); HeapWord* region_end = region_start + ParallelCompactData::RegionSize; - if (split_info.is_split(cur_region)) { // Part 1: will be relocated to space-1 HeapWord* preceding_destination = split_info.preceding_destination(); HeapWord* split_point = split_info.split_point(); - forward_objs_in_range(cm, region_start + live_words, split_point, preceding_destination + live_words); + forward_objs_in_range(cm, region_start + partial_obj_size, split_point, preceding_destination + partial_obj_size); // Part 2: will be relocated to space-2 HeapWord* destination = region_ptr->destination(); forward_objs_in_range(cm, split_point, region_end, destination); } else { HeapWord* destination = region_ptr->destination(); - forward_objs_in_range(cm, region_start + live_words, region_end, destination + live_words); + forward_objs_in_range(cm, region_start + partial_obj_size, region_end, destination + partial_obj_size); } } } @@ -1984,11 +1984,11 @@ HeapWord* PSParallelCompact::skip_live_words(HeapWord* beg, HeapWord* end, size_ } } -// On filling a destination region (dest-region), we need to know the location -// of the word that will be at the start of the dest-region after compaction. -// A dest-region can have one or more source regions, but only the first -// source-region contains this location. This location is retrieved by calling -// `first_src_addr` on a dest-region. +// On starting to fill a destination region (dest-region), we need to know the +// location of the word that will be at the start of the dest-region after +// compaction. A dest-region can have one or more source regions, but only the +// first source-region contains this location. This location is retrieved by +// calling `first_src_addr` on a dest-region. // Conversely, a source-region has a dest-region which holds the destination of // the first live word on this source-region, based on which the destination // for the rest of live words can be derived. @@ -2017,9 +2017,9 @@ HeapWord* PSParallelCompact::skip_live_words(HeapWord* beg, HeapWord* end, size_ // ^ ^ // | old-space-end | eden-space-start // -// Therefore, in this example, region-n will have two dest-regions, one for -// the final region in old-space and the other for the first region in -// eden-space. +// Therefore, in this example, region-n will have two dest-regions: +// 1. the final region in old-space +// 2. the first region in eden-space. // To handle this special case, we introduce the concept of split-region, whose // contents are relocated to two spaces. `SplitInfo` captures all necessary // info about the split, the first part, spliting-point, and the second part. From 25dd51e4fc424deb0cb71ec8c706c551e9abad55 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Volkan=20Yaz=C4=B1c=C4=B1?= <volkan.yazici@oracle.com> Date: Tue, 26 Nov 2024 09:35:31 +0000 Subject: [PATCH 242/311] 8344222: Remove calls to SecurityManager and doPrivileged in java.net.HttpURLConnection, java.net.HttpConnectSocketImpl, and javax.net.HttpsURLConnection after JEP 486 integration Reviewed-by: dfuchs, jpai --- .../java/net/HttpConnectSocketImpl.java | 37 +++---------------- .../classes/java/net/HttpURLConnection.java | 13 ------- .../javax/net/ssl/HttpsURLConnection.java | 3 -- .../HttpURLConWithProxy.java | 4 +- 4 files changed, 7 insertions(+), 50 deletions(-) diff --git a/src/java.base/share/classes/java/net/HttpConnectSocketImpl.java b/src/java.base/share/classes/java/net/HttpConnectSocketImpl.java index 742187e3454..f8f1f7125c3 100644 --- a/src/java.base/share/classes/java/net/HttpConnectSocketImpl.java +++ b/src/java.base/share/classes/java/net/HttpConnectSocketImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -40,7 +40,7 @@ * @since 1.8 */ -/*package*/ @SuppressWarnings("removal") class HttpConnectSocketImpl extends DelegatingSocketImpl { +/*package*/ class HttpConnectSocketImpl extends DelegatingSocketImpl { private static final String httpURLClazzStr = "sun.net.www.protocol.http.HttpURLConnection"; @@ -59,18 +59,11 @@ try { Class<?> httpClazz = Class.forName(httpURLClazzStr, true, null); httpField = httpClazz.getDeclaredField("http"); + httpField.setAccessible(true); doTunneling = httpClazz.getDeclaredMethod(doTunnelingStr); Class<?> netClientClazz = Class.forName(netClientClazzStr, true, null); serverSocketField = netClientClazz.getDeclaredField("serverSocket"); - - java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction<>() { - public Void run() { - httpField.setAccessible(true); - serverSocketField.setAccessible(true); - return null; - } - }); + serverSocketField.setAccessible(true); } catch (ReflectiveOperationException x) { throw new InternalError("Should not reach here", x); } @@ -107,16 +100,12 @@ protected void connect(SocketAddress endpoint, int timeout) : epoint.getAddress().getHostAddress(); final int destPort = epoint.getPort(); - SecurityManager security = System.getSecurityManager(); - if (security != null) - security.checkConnect(destHost, destPort); - if (destHost.contains(":")) destHost = "[" + destHost + "]"; // Connect to the HTTP proxy server String urlString = "http://" + destHost + ":" + destPort; - Socket httpSocket = privilegedDoTunnel(urlString, timeout); + Socket httpSocket = doTunnel(urlString, timeout); // Success! external_address = epoint; @@ -164,22 +153,6 @@ public void setOption(int opt, Object val) throws SocketException { optionsMap.put(opt, val); } - private Socket privilegedDoTunnel(final String urlString, - final int timeout) - throws IOException - { - try { - return java.security.AccessController.doPrivileged( - new java.security.PrivilegedExceptionAction<>() { - public Socket run() throws IOException { - return doTunnel(urlString, timeout); - } - }); - } catch (java.security.PrivilegedActionException pae) { - throw (IOException) pae.getException(); - } - } - private Socket doTunnel(String urlString, int connectTimeout) throws IOException { diff --git a/src/java.base/share/classes/java/net/HttpURLConnection.java b/src/java.base/share/classes/java/net/HttpURLConnection.java index 65c6f8445b2..20b9068e7f3 100644 --- a/src/java.base/share/classes/java/net/HttpURLConnection.java +++ b/src/java.base/share/classes/java/net/HttpURLConnection.java @@ -368,12 +368,6 @@ protected HttpURLConnection (URL u) { * @see #getFollowRedirects() */ public static void setFollowRedirects(boolean set) { - @SuppressWarnings("removal") - SecurityManager sec = System.getSecurityManager(); - if (sec != null) { - // seems to be the best check here... - sec.checkSetFactory(); - } followRedirects = set; } @@ -452,13 +446,6 @@ public void setRequestMethod(String method) throws ProtocolException { for (int i = 0; i < methods.length; i++) { if (methods[i].equals(method)) { - if (method.equals("TRACE")) { - @SuppressWarnings("removal") - SecurityManager s = System.getSecurityManager(); - if (s != null) { - s.checkPermission(new NetPermission("allowHttpTrace")); - } - } this.method = method; return; } diff --git a/src/java.base/share/classes/javax/net/ssl/HttpsURLConnection.java b/src/java.base/share/classes/javax/net/ssl/HttpsURLConnection.java index 61bd8d140d2..4915c1221bb 100644 --- a/src/java.base/share/classes/javax/net/ssl/HttpsURLConnection.java +++ b/src/java.base/share/classes/javax/net/ssl/HttpsURLConnection.java @@ -226,7 +226,6 @@ public static void setDefaultHostnameVerifier(HostnameVerifier v) { throw new IllegalArgumentException( "no default HostnameVerifier specified"); } - defaultHostnameVerifier = v; } @@ -300,7 +299,6 @@ public static void setDefaultSSLSocketFactory(SSLSocketFactory sf) { throw new IllegalArgumentException( "no default SSLSocketFactory specified"); } - defaultSSLSocketFactory = sf; } @@ -342,7 +340,6 @@ public void setSSLSocketFactory(SSLSocketFactory sf) { throw new IllegalArgumentException( "no SSLSocketFactory specified"); } - sslSocketFactory = sf; } diff --git a/test/jdk/java/net/HttpURLConnection/HttpURLConWithProxy.java b/test/jdk/java/net/HttpURLConnection/HttpURLConWithProxy.java index 9de4bff1d7b..04923a99501 100644 --- a/test/jdk/java/net/HttpURLConnection/HttpURLConWithProxy.java +++ b/test/jdk/java/net/HttpURLConnection/HttpURLConWithProxy.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -165,6 +165,6 @@ public void flush() { } @Override - public void close() throws SecurityException { + public void close() { } } From 3a625f38aa4ab611fe5c7dffe420abce826d0d7e Mon Sep 17 00:00:00 2001 From: Doug Simon <dnsimon@openjdk.org> Date: Tue, 26 Nov 2024 09:50:57 +0000 Subject: [PATCH 243/311] 8344628: Test TestEnableJVMCIProduct.java run with virtual thread intermittent fails Reviewed-by: syan, dlong, mli --- .../jvmci/TestEnableJVMCIProduct.java | 25 ++++++++++++++----- 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/test/hotspot/jtreg/compiler/jvmci/TestEnableJVMCIProduct.java b/test/hotspot/jtreg/compiler/jvmci/TestEnableJVMCIProduct.java index 1c36ab78ac6..16f9345c2ee 100644 --- a/test/hotspot/jtreg/compiler/jvmci/TestEnableJVMCIProduct.java +++ b/test/hotspot/jtreg/compiler/jvmci/TestEnableJVMCIProduct.java @@ -34,6 +34,11 @@ import jdk.test.lib.process.ProcessTools; import jdk.test.lib.process.OutputAnalyzer; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.List; +import java.util.stream.Collectors; + public class TestEnableJVMCIProduct { static class Expectation { @@ -52,10 +57,11 @@ static class Expectation { public static void main(String[] args) throws Exception { if (args.length != 0) { // Called as subprocess. Print system properties named by - // `args` and then exit. - for (String arg : args) { - System.out.printf("%s=%s%n", arg, System.getProperty(arg)); - } + // `args[1..]` to the file `args[0]` and then exit. + Files.writeString(Path.of(args[0]), + List.of(args).subList(1, args.length).stream() + .map(a -> "%s=%s".formatted(a, System.getProperty(a))) + .collect(Collectors.joining(","))); return; } // Test EnableJVMCIProduct without any other explicit JVMCI option @@ -80,16 +86,19 @@ public static void main(String[] args) throws Exception { new Expectation("UseJVMCICompiler", "true", "default")); } + static int id; + static void test(String explicitFlag, Expectation... expectations) throws Exception { String[] flags = {"-XX:+EnableJVMCIProduct", "-XX:+UseGraalJIT"}; String cwd = System.getProperty("user.dir"); for (String flag : flags) { + Path propsPath = Path.of("props." + id++); ProcessBuilder pb = ProcessTools.createLimitedTestJavaProcessBuilder( "-XX:+UnlockExperimentalVMOptions", flag, "-XX:-UnlockExperimentalVMOptions", explicitFlag, "-XX:+PrintFlagsFinal", "--class-path=" + System.getProperty("java.class.path"), - "TestEnableJVMCIProduct", "jvmci.Compiler"); + "TestEnableJVMCIProduct", propsPath.toString(), "jvmci.Compiler"); OutputAnalyzer output = new OutputAnalyzer(pb.start()); for (Expectation expectation : expectations) { output.stdoutShouldMatch(expectation.pattern); @@ -103,7 +112,11 @@ static void test(String explicitFlag, Expectation... expectations) throws Except output.stdoutShouldMatch("No JVMCI compiler found"); } } else if (flag.equals("-XX:+UseGraalJIT")) { - output.shouldContain("jvmci.Compiler=graal"); + String props = Files.readString(propsPath); + String expect = "jvmci.Compiler=graal"; + if (!props.contains(expect)) { + throw new RuntimeException("\"%s\" does not contain \"%s\"".formatted(props, expect)); + } } } } From 0054bbed7fce5b8566655d6910b09b10c952e609 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20Gr=C3=B6nlund?= <mgronlun@openjdk.org> Date: Tue, 26 Nov 2024 10:50:20 +0000 Subject: [PATCH 244/311] 8343756: CAN_SHOW_REGISTERS_ON_ASSERT for Windows Reviewed-by: stuefe, jsjolen --- src/hotspot/os/posix/os_posix.cpp | 42 +++++++- src/hotspot/os/posix/signals_posix.cpp | 15 ++- src/hotspot/os/posix/vmError_posix.cpp | 15 ++- src/hotspot/os/windows/os_windows.cpp | 44 ++++++++- src/hotspot/os/windows/vmError_windows.cpp | 22 ++++- src/hotspot/share/runtime/os.hpp | 6 +- src/hotspot/share/utilities/debug.cpp | 98 ++++++++----------- src/hotspot/share/utilities/debug.hpp | 7 +- src/hotspot/share/utilities/vmError.cpp | 18 ++-- src/hotspot/share/utilities/vmError.hpp | 25 ++--- .../ShowRegistersOnAssertTest.java | 18 +++- 11 files changed, 216 insertions(+), 94 deletions(-) diff --git a/src/hotspot/os/posix/os_posix.cpp b/src/hotspot/os/posix/os_posix.cpp index 9aae3b5c143..7d418d4ad43 100644 --- a/src/hotspot/os/posix/os_posix.cpp +++ b/src/hotspot/os/posix/os_posix.cpp @@ -2111,7 +2111,7 @@ void os::shutdown() { // easily trigger secondary faults in those threads. To reduce the likelihood // of that we use _exit rather than exit, so that no atexit hooks get run. // But note that os::shutdown() could also trigger secondary faults. -void os::abort(bool dump_core, void* siginfo, const void* context) { +void os::abort(bool dump_core, const void* siginfo, const void* context) { os::shutdown(); if (dump_core) { LINUX_ONLY(if (DumpPrivateMappingsInCore) ClassLoader::close_jrt_image();) @@ -2186,3 +2186,43 @@ char* os::pd_map_memory(int fd, const char* unused, bool os::pd_unmap_memory(char* addr, size_t bytes) { return munmap(addr, bytes) == 0; } + +#ifdef CAN_SHOW_REGISTERS_ON_ASSERT +static ucontext_t _saved_assert_context; +static bool _has_saved_context = false; +#endif // CAN_SHOW_REGISTERS_ON_ASSERT + +void os::save_assert_context(const void* ucVoid) { +#ifdef CAN_SHOW_REGISTERS_ON_ASSERT + assert(ucVoid != nullptr, "invariant"); + assert(!_has_saved_context, "invariant"); + memcpy(&_saved_assert_context, ucVoid, sizeof(ucontext_t)); + // on Linux ppc64, ucontext_t contains pointers into itself which have to be patched up + // after copying the context (see comment in sys/ucontext.h): +#if defined(PPC64) + *((void**)&_saved_assert_context.uc_mcontext.regs) = &(_saved_assert_context.uc_mcontext.gp_regs); +#elif defined(AMD64) + // In the copied version, fpregs should point to the copied contents. + // Sanity check: fpregs should point into the context. + if ((address)((const ucontext_t*)ucVoid)->uc_mcontext.fpregs > (address)ucVoid) { + size_t fpregs_offset = pointer_delta(((const ucontext_t*)ucVoid)->uc_mcontext.fpregs, ucVoid, 1); + if (fpregs_offset < sizeof(ucontext_t)) { + // Preserve the offset. + *((void**)&_saved_assert_context.uc_mcontext.fpregs) = (void*)((address)(void*)&_saved_assert_context + fpregs_offset); + } + } +#endif + _has_saved_context = true; +#endif // CAN_SHOW_REGISTERS_ON_ASSERT +} + +const void* os::get_saved_assert_context(const void** sigInfo) { +#ifdef CAN_SHOW_REGISTERS_ON_ASSERT + assert(sigInfo != nullptr, "invariant"); + *sigInfo = nullptr; + return _has_saved_context ? &_saved_assert_context : nullptr; +#endif + *sigInfo = nullptr; + return nullptr; +} + diff --git a/src/hotspot/os/posix/signals_posix.cpp b/src/hotspot/os/posix/signals_posix.cpp index 6a14d0a4856..bbf122fabfb 100644 --- a/src/hotspot/os/posix/signals_posix.cpp +++ b/src/hotspot/os/posix/signals_posix.cpp @@ -578,9 +578,8 @@ int JVM_HANDLE_XXX_SIGNAL(int sig, siginfo_t* info, // Handle assertion poison page accesses. #ifdef CAN_SHOW_REGISTERS_ON_ASSERT - if (!signal_was_handled && - ((sig == SIGSEGV || sig == SIGBUS) && info != nullptr && info->si_addr == g_assert_poison)) { - signal_was_handled = handle_assert_poison_fault(ucVoid, info->si_addr); + if (VMError::was_assert_poison_crash(info)) { + signal_was_handled = handle_assert_poison_fault(ucVoid); } #endif @@ -1136,8 +1135,16 @@ static const char* get_signal_name(int sig, char* out, size_t outlen) { } void os::print_siginfo(outputStream* os, const void* si0) { +#ifdef CAN_SHOW_REGISTERS_ON_ASSERT + // If we are here because of an assert/guarantee, we suppress + // printing the siginfo, because it is only an implementation + // detail capturing the context for said assert/guarantee. + if (VMError::was_assert_poison_crash(si0)) { + return; + } +#endif - const siginfo_t* const si = (const siginfo_t*) si0; + const siginfo_t* const si = (const siginfo_t*)si0; char buf[20]; os->print("siginfo:"); diff --git a/src/hotspot/os/posix/vmError_posix.cpp b/src/hotspot/os/posix/vmError_posix.cpp index 30ebf8092f8..c1d89efa855 100644 --- a/src/hotspot/os/posix/vmError_posix.cpp +++ b/src/hotspot/os/posix/vmError_posix.cpp @@ -84,8 +84,8 @@ static void crash_handler(int sig, siginfo_t* info, void* context) { // Needed because asserts may happen in error handling too. #ifdef CAN_SHOW_REGISTERS_ON_ASSERT - if ((sig == SIGSEGV || sig == SIGBUS) && info != nullptr && info->si_addr == g_assert_poison) { - if (handle_assert_poison_fault(context, info->si_addr)) { + if (VMError::was_assert_poison_crash(info)) { + if (handle_assert_poison_fault(context)) { return; } } @@ -127,3 +127,14 @@ void VMError::check_failing_cds_access(outputStream* st, const void* siginfo) { } #endif } + +bool VMError::was_assert_poison_crash(const void* siginfo) { +#ifdef CAN_SHOW_REGISTERS_ON_ASSERT + if (siginfo == nullptr) { + return false; + } + const siginfo_t* const si = (siginfo_t*)siginfo; + return (si->si_signo == SIGSEGV || si->si_signo == SIGBUS) && si->si_addr == g_assert_poison_read_only; +#endif + return false; +} diff --git a/src/hotspot/os/windows/os_windows.cpp b/src/hotspot/os/windows/os_windows.cpp index fd857c2cd95..8bb3789bbad 100644 --- a/src/hotspot/os/windows/os_windows.cpp +++ b/src/hotspot/os/windows/os_windows.cpp @@ -72,6 +72,7 @@ #include "services/runtimeService.hpp" #include "symbolengine.hpp" #include "utilities/align.hpp" +#include "utilities/debug.hpp" #include "utilities/decoder.hpp" #include "utilities/defaultStream.hpp" #include "utilities/events.hpp" @@ -1317,7 +1318,7 @@ void os::check_core_dump_prerequisites(char* buffer, size_t bufferSize, bool che } } -void os::abort(bool dump_core, void* siginfo, const void* context) { +void os::abort(bool dump_core, const void* siginfo, const void* context) { EXCEPTION_POINTERS ep; MINIDUMP_EXCEPTION_INFORMATION mei; MINIDUMP_EXCEPTION_INFORMATION* pmei; @@ -2112,7 +2113,17 @@ bool os::signal_sent_by_kill(const void* siginfo) { } void os::print_siginfo(outputStream *st, const void* siginfo) { +#ifdef CAN_SHOW_REGISTERS_ON_ASSERT + // If we are here because of an assert/guarantee, we suppress + // printing the siginfo, because it is only an implementation + // detail capturing the context for said assert/guarantee. + if (VMError::was_assert_poison_crash(siginfo)) { + return; + } +#endif + const EXCEPTION_RECORD* const er = (EXCEPTION_RECORD*)siginfo; + st->print("siginfo:"); char tmp[64]; @@ -2625,6 +2636,14 @@ LONG WINAPI topLevelExceptionFilter(struct _EXCEPTION_POINTERS* exceptionInfo) { #endif #endif +#ifdef CAN_SHOW_REGISTERS_ON_ASSERT + if (VMError::was_assert_poison_crash(exception_record)) { + if (handle_assert_poison_fault(exceptionInfo)) { + return EXCEPTION_CONTINUE_EXECUTION; + } + } +#endif + if (t != nullptr && t->is_Java_thread()) { JavaThread* thread = JavaThread::cast(t); bool in_java = thread->thread_state() == _thread_in_Java; @@ -6165,3 +6184,26 @@ void os::print_user_info(outputStream* st) { void os::print_active_locale(outputStream* st) { // not implemented yet } + +static CONTEXT _saved_assert_context; +static EXCEPTION_RECORD _saved_exception_record; +static bool _has_saved_context = false; + +void os::save_assert_context(const void* ucVoid) { + assert(ucVoid != nullptr, "invariant"); + assert(!_has_saved_context, "invariant"); + const EXCEPTION_POINTERS* ep = static_cast<const EXCEPTION_POINTERS*>(ucVoid); + memcpy(&_saved_assert_context, ep->ContextRecord, sizeof(CONTEXT)); + memcpy(&_saved_exception_record, ep->ExceptionRecord, sizeof(EXCEPTION_RECORD)); + _has_saved_context = true; +} + +const void* os::get_saved_assert_context(const void** sigInfo) { + assert(sigInfo != nullptr, "invariant"); + if (_has_saved_context) { + *sigInfo = &_saved_exception_record; + return &_saved_assert_context; + } + *sigInfo = nullptr; + return nullptr; +} diff --git a/src/hotspot/os/windows/vmError_windows.cpp b/src/hotspot/os/windows/vmError_windows.cpp index 363ec3192ce..705e04e77db 100644 --- a/src/hotspot/os/windows/vmError_windows.cpp +++ b/src/hotspot/os/windows/vmError_windows.cpp @@ -28,6 +28,7 @@ #include "runtime/arguments.hpp" #include "runtime/javaThread.hpp" #include "runtime/os.hpp" +#include "utilities/debug.hpp" #include "utilities/vmError.hpp" LONG WINAPI crash_handler(struct _EXCEPTION_POINTERS* exceptionInfo) { @@ -67,10 +68,23 @@ void VMError::check_failing_cds_access(outputStream* st, const void* siginfo) { void VMError::reporting_started() {} void VMError::interrupt_reporting_thread() {} -void VMError::raise_fail_fast(void* exrecord, void* context) { +void VMError::raise_fail_fast(const void* exrecord, const void* context) { DWORD flags = (exrecord == nullptr) ? FAIL_FAST_GENERATE_EXCEPTION_ADDRESS : 0; - RaiseFailFastException(static_cast<PEXCEPTION_RECORD>(exrecord), - static_cast<PCONTEXT>(context), - flags); + PEXCEPTION_RECORD exception_record = static_cast<PEXCEPTION_RECORD>(const_cast<void*>(exrecord)); + PCONTEXT ctx = static_cast<PCONTEXT>(const_cast<void*>(context)); + RaiseFailFastException(exception_record, ctx, flags); ::abort(); } + +bool VMError::was_assert_poison_crash(const void* siginfo) { +#ifdef CAN_SHOW_REGISTERS_ON_ASSERT + if (siginfo == nullptr) { + return false; + } + const EXCEPTION_RECORD* const er = (EXCEPTION_RECORD*)siginfo; + if (er->ExceptionCode == EXCEPTION_ACCESS_VIOLATION && er->NumberParameters >= 2) { + return (void*)er->ExceptionInformation[1] == g_assert_poison_read_only; + } +#endif + return false; +} diff --git a/src/hotspot/share/runtime/os.hpp b/src/hotspot/share/runtime/os.hpp index 54771f622e9..8e4a214b691 100644 --- a/src/hotspot/share/runtime/os.hpp +++ b/src/hotspot/share/runtime/os.hpp @@ -617,6 +617,10 @@ class os: AllStatic { static frame fetch_frame_from_context(const void* ucVoid); static frame fetch_compiled_frame_from_context(const void* ucVoid); + // For saving an os specific context generated by an assert or guarantee. + static void save_assert_context(const void* ucVoid); + static const void* get_saved_assert_context(const void** sigInfo); + static void breakpoint(); static bool start_debugging(char *buf, int buflen); @@ -643,7 +647,7 @@ class os: AllStatic { // Terminate with an error. Default is to generate a core file on platforms // that support such things. This calls shutdown() and then aborts. - [[noreturn]] static void abort(bool dump_core, void *siginfo, const void *context); + [[noreturn]] static void abort(bool dump_core, const void *siginfo, const void *context); [[noreturn]] static void abort(bool dump_core = true); // Die immediately, no exit hook, no abort hook, no cleanup. diff --git a/src/hotspot/share/utilities/debug.cpp b/src/hotspot/share/utilities/debug.cpp index 88730c1e6ec..7286f70412a 100644 --- a/src/hotspot/share/utilities/debug.cpp +++ b/src/hotspot/share/utilities/debug.cpp @@ -74,8 +74,8 @@ #ifdef CAN_SHOW_REGISTERS_ON_ASSERT static char g_dummy; char* g_assert_poison = &g_dummy; +const char* g_assert_poison_read_only = &g_dummy; static intx g_asserting_thread = 0; -static void* g_assertion_context = nullptr; #endif // CAN_SHOW_REGISTERS_ON_ASSERT int DebuggingContext::_enabled = 0; // Initially disabled. @@ -181,16 +181,21 @@ void report_vm_error(const char* file, int line, const char* error_msg, const ch { va_list detail_args; va_start(detail_args, detail_fmt); - void* context = nullptr; + + print_error_for_unit_test(error_msg, detail_fmt, detail_args); + + const void* context = nullptr; + const void* siginfo = nullptr; + #ifdef CAN_SHOW_REGISTERS_ON_ASSERT - if (g_assertion_context != nullptr && os::current_thread_id() == g_asserting_thread) { - context = g_assertion_context; + if (os::current_thread_id() == g_asserting_thread) { + context = os::get_saved_assert_context(&siginfo); } #endif // CAN_SHOW_REGISTERS_ON_ASSERT - print_error_for_unit_test(error_msg, detail_fmt, detail_args); - - VMError::report_and_die(Thread::current_or_null(), context, file, line, error_msg, detail_fmt, detail_args); + VMError::report_and_die(INTERNAL_ERROR, error_msg, detail_fmt, detail_args, + Thread::current_or_null(), nullptr, siginfo, context, + file, line, 0); va_end(detail_args); } @@ -202,17 +207,21 @@ void report_vm_status_error(const char* file, int line, const char* error_msg, void report_fatal(VMErrorType error_type, const char* file, int line, const char* detail_fmt, ...) { va_list detail_args; va_start(detail_args, detail_fmt); - void* context = nullptr; + + + print_error_for_unit_test("fatal error", detail_fmt, detail_args); + + const void* context = nullptr; + const void* siginfo = nullptr; + #ifdef CAN_SHOW_REGISTERS_ON_ASSERT - if (g_assertion_context != nullptr && os::current_thread_id() == g_asserting_thread) { - context = g_assertion_context; + if (os::current_thread_id() == g_asserting_thread) { + context = os::get_saved_assert_context(&siginfo); } #endif // CAN_SHOW_REGISTERS_ON_ASSERT - print_error_for_unit_test("fatal error", detail_fmt, detail_args); - VMError::report_and_die(error_type, "fatal error", detail_fmt, detail_args, - Thread::current_or_null(), nullptr, nullptr, context, + Thread::current_or_null(), nullptr, siginfo, context, file, line, 0); va_end(detail_args); } @@ -705,9 +714,6 @@ struct TestMultipleStaticAssertFormsInClassScope { // Support for showing register content on asserts/guarantees. #ifdef CAN_SHOW_REGISTERS_ON_ASSERT - -static ucontext_t g_stored_assertion_context; - void initialize_assert_poison() { char* page = os::reserve_memory(os::vm_page_size()); if (page) { @@ -715,6 +721,7 @@ void initialize_assert_poison() { if (os::commit_memory(page, os::vm_page_size(), false) && os::protect_memory(page, os::vm_page_size(), os::MEM_PROT_NONE)) { g_assert_poison = page; + g_assert_poison_read_only = page; } } } @@ -723,48 +730,29 @@ void disarm_assert_poison() { g_assert_poison = &g_dummy; } -static void store_context(const void* context) { - memcpy(&g_stored_assertion_context, context, sizeof(ucontext_t)); -#if defined(LINUX) - // on Linux ppc64, ucontext_t contains pointers into itself which have to be patched up - // after copying the context (see comment in sys/ucontext.h): -#if defined(PPC64) - *((void**) &g_stored_assertion_context.uc_mcontext.regs) = &(g_stored_assertion_context.uc_mcontext.gp_regs); -#elif defined(AMD64) - // In the copied version, fpregs should point to the copied contents. - // Sanity check: fpregs should point into the context. - if ((address)((const ucontext_t*)context)->uc_mcontext.fpregs > (address)context) { - size_t fpregs_offset = pointer_delta(((const ucontext_t*)context)->uc_mcontext.fpregs, context, 1); - if (fpregs_offset < sizeof(ucontext_t)) { - // Preserve the offset. - *((void**) &g_stored_assertion_context.uc_mcontext.fpregs) = (void*)((address)(void*)&g_stored_assertion_context + fpregs_offset); - } - } -#endif -#endif -} - -bool handle_assert_poison_fault(const void* ucVoid, const void* faulting_address) { - if (faulting_address == g_assert_poison) { - // Disarm poison page. - if (os::protect_memory((char*)g_assert_poison, os::vm_page_size(), os::MEM_PROT_RWX) == false) { #ifdef ASSERT - fprintf(stderr, "Assertion poison page cannot be unprotected - mprotect failed with %d (%s)", - errno, os::strerror(errno)); - fflush(stderr); +static void print_unprotect_error() { + fprintf(stderr, "Assertion poison page cannot be unprotected - mprotect failed with %d (%s)", + errno, os::strerror(errno)); + fflush(stderr); +} #endif - return false; // unprotecting memory may fail in OOM situations, as surprising as this sounds. - } - // Store Context away. - if (ucVoid) { - const intx my_tid = os::current_thread_id(); - if (Atomic::cmpxchg(&g_asserting_thread, (intx)0, my_tid) == 0) { - store_context(ucVoid); - g_assertion_context = &g_stored_assertion_context; - } + +// TOUCH_ASSERT_POISON writes to the protected g_assert_poison page, which faults +// and enters platform signal handlers which in turn invokes this routine. +bool handle_assert_poison_fault(const void* ucVoid) { + // Disarm poison page. + if (!os::protect_memory((char*)g_assert_poison, os::vm_page_size(), os::MEM_PROT_RWX)) { + DEBUG_ONLY(print_unprotect_error();) + return false; // unprotecting memory may fail in OOM situations, as surprising as this sounds. + } + if (ucVoid != nullptr) { + // Save context. + const intx my_tid = os::current_thread_id(); + if (Atomic::cmpxchg(&g_asserting_thread, (intx)0, my_tid) == 0) { + os::save_assert_context(ucVoid); } - return true; } - return false; + return true; } #endif // CAN_SHOW_REGISTERS_ON_ASSERT diff --git a/src/hotspot/share/utilities/debug.hpp b/src/hotspot/share/utilities/debug.hpp index 567e72cda57..12724153659 100644 --- a/src/hotspot/share/utilities/debug.hpp +++ b/src/hotspot/share/utilities/debug.hpp @@ -34,14 +34,15 @@ class oopDesc; -// ShowRegistersOnAssert support (for now Linux only) -#if defined(LINUX) && !defined(ZERO) +// ShowRegistersOnAssert support (for now Linux and Windows only) +#if (defined(LINUX) || defined(_WINDOWS)) && !defined(ZERO) #define CAN_SHOW_REGISTERS_ON_ASSERT extern char* g_assert_poison; +extern const char* g_assert_poison_read_only; #define TOUCH_ASSERT_POISON (*g_assert_poison) = 'X'; void initialize_assert_poison(); void disarm_assert_poison(); -bool handle_assert_poison_fault(const void* ucVoid, const void* faulting_address); +bool handle_assert_poison_fault(const void* ucVoid); #else #define TOUCH_ASSERT_POISON #endif // CAN_SHOW_REGISTERS_ON_ASSERT diff --git a/src/hotspot/share/utilities/vmError.cpp b/src/hotspot/share/utilities/vmError.cpp index cdece538cba..bb57c19c528 100644 --- a/src/hotspot/share/utilities/vmError.cpp +++ b/src/hotspot/share/utilities/vmError.cpp @@ -95,8 +95,8 @@ const char* VMError::_message; char VMError::_detail_msg[1024]; Thread* VMError::_thread; address VMError::_pc; -void* VMError::_siginfo; -void* VMError::_context; +const void* VMError::_siginfo; +const void* VMError::_context; bool VMError::_print_native_stack_used = false; const char* VMError::_filename; int VMError::_lineno; @@ -532,7 +532,7 @@ static void print_oom_reasons(outputStream* st) { st->print_cr("# This output file may be truncated or incomplete."); } -static void print_stack_location(outputStream* st, void* context, int& continuation) { +static void print_stack_location(outputStream* st, const void* context, int& continuation) { const int number_of_stack_slots = 8; int i = continuation; @@ -1583,8 +1583,8 @@ int VMError::prepare_log_file(const char* pattern, const char* default_pattern, return fd; } -void VMError::report_and_die(Thread* thread, unsigned int sig, address pc, void* siginfo, - void* context, const char* detail_fmt, ...) +void VMError::report_and_die(Thread* thread, unsigned int sig, address pc, const void* siginfo, + const void* context, const char* detail_fmt, ...) { va_list detail_args; va_start(detail_args, detail_fmt); @@ -1592,7 +1592,7 @@ void VMError::report_and_die(Thread* thread, unsigned int sig, address pc, void* va_end(detail_args); } -void VMError::report_and_die(Thread* thread, void* context, const char* filename, int lineno, const char* message, +void VMError::report_and_die(Thread* thread, const void* context, const char* filename, int lineno, const char* message, const char* detail_fmt, ...) { va_list detail_args; va_start(detail_args, detail_fmt); @@ -1600,12 +1600,12 @@ void VMError::report_and_die(Thread* thread, void* context, const char* filename va_end(detail_args); } -void VMError::report_and_die(Thread* thread, unsigned int sig, address pc, void* siginfo, void* context) +void VMError::report_and_die(Thread* thread, unsigned int sig, address pc, const void* siginfo, const void* context) { report_and_die(thread, sig, pc, siginfo, context, "%s", ""); } -void VMError::report_and_die(Thread* thread, void* context, const char* filename, int lineno, const char* message, +void VMError::report_and_die(Thread* thread, const void* context, const char* filename, int lineno, const char* message, const char* detail_fmt, va_list detail_args) { report_and_die(INTERNAL_ERROR, message, detail_fmt, detail_args, thread, nullptr, nullptr, context, filename, lineno, 0); @@ -1617,7 +1617,7 @@ void VMError::report_and_die(Thread* thread, const char* filename, int lineno, s } void VMError::report_and_die(int id, const char* message, const char* detail_fmt, va_list detail_args, - Thread* thread, address pc, void* siginfo, void* context, const char* filename, + Thread* thread, address pc, const void* siginfo, const void* context, const char* filename, int lineno, size_t size) { // A single scratch buffer to be used from here on. diff --git a/src/hotspot/share/utilities/vmError.hpp b/src/hotspot/share/utilities/vmError.hpp index dee8335afd5..405cb515896 100644 --- a/src/hotspot/share/utilities/vmError.hpp +++ b/src/hotspot/share/utilities/vmError.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2017, 2022 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -46,9 +46,9 @@ class VMError : public AllStatic { // additional info for crashes static address _pc; // faulting PC - static void* _siginfo; // ExceptionRecord on Windows, + static const void* _siginfo; // ExceptionRecord on Windows, // siginfo_t on Solaris/Linux - static void* _context; // ContextRecord on Windows, + static const void* _context; // ContextRecord on Windows, // ucontext_t on Solaris/Linux // records if VMError::print_native_stack was used to @@ -144,7 +144,7 @@ class VMError : public AllStatic { static jlong get_step_start_time(); static void clear_step_start_time(); - WINDOWS_ONLY([[noreturn]] static void raise_fail_fast(void* exrecord, void* context);) + WINDOWS_ONLY([[noreturn]] static void raise_fail_fast(const void* exrecord, const void* context);) public: @@ -166,28 +166,28 @@ class VMError : public AllStatic { // main error reporting function [[noreturn]] ATTRIBUTE_PRINTF(6, 7) - static void report_and_die(Thread* thread, unsigned int sig, address pc, void* siginfo, - void* context, const char* detail_fmt, ...); + static void report_and_die(Thread* thread, unsigned int sig, address pc, const void* siginfo, + const void* context, const char* detail_fmt, ...); [[noreturn]] ATTRIBUTE_PRINTF(6, 7) - static void report_and_die(Thread* thread, void* context, const char* filename, int lineno, const char* message, - const char* detail_fmt, ...); + static void report_and_die(Thread* thread, const void* context, const char* filename, + int lineno, const char* message, const char* detail_fmt, ...); [[noreturn]] ATTRIBUTE_PRINTF(3, 0) static void report_and_die(int id, const char* message, const char* detail_fmt, va_list detail_args, - Thread* thread, address pc, void* siginfo, void* context, + Thread* thread, address pc, const void* siginfo, const void* context, const char* filename, int lineno, size_t size); [[noreturn]] static void report_and_die(Thread* thread, unsigned int sig, address pc, - void* siginfo, void* context); + const void* siginfo, const void* context); [[noreturn]] ATTRIBUTE_PRINTF(6, 0) - static void report_and_die(Thread* thread, void* context, const char* filename, int lineno, const char* message, - const char* detail_fmt, va_list detail_args); + static void report_and_die(Thread* thread, const void* context, const char* filename, + int lineno, const char* message, const char* detail_fmt, va_list detail_args); [[noreturn]] ATTRIBUTE_PRINTF(6, 0) @@ -225,6 +225,7 @@ class VMError : public AllStatic { // permissions. static int prepare_log_file(const char* pattern, const char* default_pattern, bool overwrite_existing, char* buf, size_t buflen); + static bool was_assert_poison_crash(const void* sigInfo); }; class VMErrorCallback { diff --git a/test/hotspot/jtreg/runtime/ErrorHandling/ShowRegistersOnAssertTest.java b/test/hotspot/jtreg/runtime/ErrorHandling/ShowRegistersOnAssertTest.java index b861e44532d..d9ccac0a3df 100644 --- a/test/hotspot/jtreg/runtime/ErrorHandling/ShowRegistersOnAssertTest.java +++ b/test/hotspot/jtreg/runtime/ErrorHandling/ShowRegistersOnAssertTest.java @@ -1,6 +1,6 @@ /* * Copyright (c) 2018, 2022 SAP SE. All rights reserved. - * Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -29,7 +29,7 @@ * @summary Show Registers on assert/guarantee * @library /test/lib * @requires vm.flagless - * @requires (vm.debug == true) & (os.family == "linux") + * @requires vm.debug == true & (os.family == "linux" | os.family == "windows") * @author Thomas Stuefe (SAP) * @modules java.base/jdk.internal.misc * java.management @@ -67,6 +67,20 @@ private static void do_test(boolean do_assert, // true - assert, false - guarant // (which would be a sign that the assert poison page mechanism does not work). output_detail.shouldMatch("# A fatal error has been detected by the Java Runtime Environment:.*"); output_detail.shouldMatch("# +Internal Error.*"); + if (show_registers_on_assert) { + // Extract the hs_err_pid file. + File hs_err_file = HsErrFileUtils.openHsErrFileFromOutput(output_detail); + Pattern[] pattern = new Pattern[] { Pattern.compile("Registers:"), null }; + if (Platform.isX64()) { + pattern[1] = Pattern.compile("RAX=.*"); + } else if (Platform.isX86()) { + pattern[1] = Pattern.compile("EAX=.*"); + } else if (Platform.isAArch64()) { + pattern[1] = Pattern.compile("R0=.*"); + } + // Pattern match the hs_err_pid file. + HsErrFileUtils.checkHsErrFileContent(hs_err_file, pattern, false); + } } public static void main(String[] args) throws Exception { From 9291abc6337f8cf480806f4b2996ec905b021704 Mon Sep 17 00:00:00 2001 From: Afshin Zafari <azafari@openjdk.org> Date: Tue, 26 Nov 2024 11:08:34 +0000 Subject: [PATCH 245/311] 8342074: Fix runtime/Thread/TestAlwaysPreTouchStacks.java to be flagless or accept VM flags Reviewed-by: gziemski, lmesnik --- test/hotspot/jtreg/runtime/Thread/TestAlwaysPreTouchStacks.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/hotspot/jtreg/runtime/Thread/TestAlwaysPreTouchStacks.java b/test/hotspot/jtreg/runtime/Thread/TestAlwaysPreTouchStacks.java index d47a07d2dec..06ddaadf91c 100644 --- a/test/hotspot/jtreg/runtime/Thread/TestAlwaysPreTouchStacks.java +++ b/test/hotspot/jtreg/runtime/Thread/TestAlwaysPreTouchStacks.java @@ -93,7 +93,7 @@ private static long runPreTouchTest(boolean preTouch) throws Exception { vmArgs.add("-XX:-UseMadvPopulateWrite"); } Collections.addAll(vmArgs, "TestAlwaysPreTouchStacks", "test"); - ProcessBuilder pb = ProcessTools.createLimitedTestJavaProcessBuilder(vmArgs); + ProcessBuilder pb = ProcessTools.createTestJavaProcessBuilder(vmArgs); OutputAnalyzer output = new OutputAnalyzer(pb.start()); output.shouldHaveExitValue(0); From 6da3ecd65ddeb94587933c69ca8b9c279c70ac24 Mon Sep 17 00:00:00 2001 From: Hamlin Li <mli@openjdk.org> Date: Tue, 26 Nov 2024 11:10:36 +0000 Subject: [PATCH 246/311] 8344960: RISC-V: fix TestFloatConversionsVectorNaN for COH and AlignVector Reviewed-by: fyang, luhenry --- .../TestFloatConversionsVectorNaN.java | 33 ++++++++++++++++--- 1 file changed, 28 insertions(+), 5 deletions(-) diff --git a/test/hotspot/jtreg/compiler/vectorization/TestFloatConversionsVectorNaN.java b/test/hotspot/jtreg/compiler/vectorization/TestFloatConversionsVectorNaN.java index 26e42b92bad..a4acd9b5ebd 100644 --- a/test/hotspot/jtreg/compiler/vectorization/TestFloatConversionsVectorNaN.java +++ b/test/hotspot/jtreg/compiler/vectorization/TestFloatConversionsVectorNaN.java @@ -28,7 +28,10 @@ * @requires vm.compiler2.enabled * @requires (os.arch == "riscv64" & vm.cpu.features ~= ".*zvfh.*") * @library /test/lib / - * @run driver compiler.vectorization.TestFloatConversionsVectorNaN + * @run driver compiler.vectorization.TestFloatConversionsVectorNaN nCOH_nAV + * @run driver compiler.vectorization.TestFloatConversionsVectorNaN nCOH_yAV + * @run driver compiler.vectorization.TestFloatConversionsVectorNaN yCOH_nAV + * @run driver compiler.vectorization.TestFloatConversionsVectorNaN yCOH_yAV */ package compiler.vectorization; @@ -47,16 +50,30 @@ public class TestFloatConversionsVectorNaN { private static float [] fout; public static void main(String args[]) { - TestFramework.runWithFlags("-XX:-TieredCompilation", - "-XX:CompileThresholdScaling=0.3"); + TestFramework framework = new TestFramework(TestFloatConversionsVectorNaN.class); + framework.addFlags("-XX:-TieredCompilation", "-XX:CompileThresholdScaling=0.3"); + switch (args[0]) { + case "nCOH_nAV" -> { framework.addFlags("-XX:+UnlockExperimentalVMOptions", "-XX:-UseCompactObjectHeaders", "-XX:-AlignVector"); } + case "nCOH_yAV" -> { framework.addFlags("-XX:+UnlockExperimentalVMOptions", "-XX:-UseCompactObjectHeaders", "-XX:+AlignVector"); } + case "yCOH_nAV" -> { framework.addFlags("-XX:+UnlockExperimentalVMOptions", "-XX:+UseCompactObjectHeaders", "-XX:-AlignVector"); } + case "yCOH_yAV" -> { framework.addFlags("-XX:+UnlockExperimentalVMOptions", "-XX:+UseCompactObjectHeaders", "-XX:+AlignVector"); } + default -> { throw new RuntimeException("Test argument not recognized: " + args[0]); } + }; + framework.start(); System.out.println("PASSED"); } @Test - @IR(counts = {IRNode.VECTOR_CAST_F2HF, IRNode.VECTOR_SIZE + "min(max_float, max_short)", "> 0"}) + @IR(counts = {IRNode.VECTOR_CAST_F2HF, IRNode.VECTOR_SIZE + "min(max_float, max_short)", "> 0"}, + applyIfOr = {"UseCompactObjectHeaders", "false", "AlignVector", "false"}) public void test_float_float16(short[] sout, float[] finp) { for (int i = 0; i < finp.length; i++) { sout[i] = Float.floatToFloat16(finp[i]); + // With AlignVector, we need 8-byte alignment of vector loads/stores. + // UseCompactObjectHeaders=false UseCompactObjectHeaders=true + // F_adr = base + 16 + 4*i -> i % 2 = 0 F_adr = base + 12 + 4*i -> i % 2 = 1 + // S_adr = base + 16 + 2*i -> i % 4 = 0 S_adr = base + 12 + 2*i -> i % 4 = 2 + // -> vectorize -> no vectorization } } @@ -129,10 +146,16 @@ static int assertEquals(int idx, float f, short expected, short actual) { } @Test - @IR(counts = {IRNode.VECTOR_CAST_HF2F, IRNode.VECTOR_SIZE + "min(max_float, max_short)", "> 0"}) + @IR(counts = {IRNode.VECTOR_CAST_HF2F, IRNode.VECTOR_SIZE + "min(max_float, max_short)", "> 0"}, + applyIfOr = {"UseCompactObjectHeaders", "false", "AlignVector", "false"}) public void test_float16_float(float[] fout, short[] sinp) { for (int i = 0; i < sinp.length; i++) { fout[i] = Float.float16ToFloat(sinp[i]); + // With AlignVector, we need 8-byte alignment of vector loads/stores. + // UseCompactObjectHeaders=false UseCompactObjectHeaders=true + // F_adr = base + 16 + 4*i -> i % 2 = 0 F_adr = base + 12 + 4*i -> i % 2 = 1 + // S_adr = base + 16 + 2*i -> i % 4 = 0 S_adr = base + 12 + 2*i -> i % 4 = 2 + // -> vectorize -> no vectorization } } From 3e509c8bd150121e4e99ace9231fc9419630751e Mon Sep 17 00:00:00 2001 From: Doug Lea <dl@openjdk.org> Date: Tue, 26 Nov 2024 11:44:29 +0000 Subject: [PATCH 247/311] 8344773: SM cleanup in ForkJoinPool Reviewed-by: alanb --- .../java/util/concurrent/ForkJoinPool.java | 130 ++++-------------- .../util/concurrent/ForkJoinWorkerThread.java | 50 +++---- 2 files changed, 49 insertions(+), 131 deletions(-) diff --git a/src/java.base/share/classes/java/util/concurrent/ForkJoinPool.java b/src/java.base/share/classes/java/util/concurrent/ForkJoinPool.java index 0f9ccbf6284..d51b4ba0770 100644 --- a/src/java.base/share/classes/java/util/concurrent/ForkJoinPool.java +++ b/src/java.base/share/classes/java/util/concurrent/ForkJoinPool.java @@ -37,12 +37,6 @@ import java.lang.Thread.UncaughtExceptionHandler; import java.lang.reflect.Field; -import java.security.AccessController; -import java.security.AccessControlContext; -import java.security.Permission; -import java.security.Permissions; -import java.security.PrivilegedAction; -import java.security.ProtectionDomain; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; @@ -811,9 +805,7 @@ public class ForkJoinPool extends AbstractExecutorService { * initialization. Since it (or any other created pool) need * never be used, we minimize initial construction overhead and * footprint to the setup of about a dozen fields, although with - * some System property parsing and security processing that takes - * far longer than the actual construction when SecurityManagers - * are used or properties are set. The common pool is + * some System property parsing properties are set. The common pool is * distinguished by having a null workerNamePrefix (which is an * odd convention, but avoids the need to decode status in factory * classes). It also has PRESET_SIZE config set if parallelism @@ -839,13 +831,12 @@ public class ForkJoinPool extends AbstractExecutorService { * * As a more appropriate default in managed environments, unless * overridden by system properties, we use workers of subclass - * InnocuousForkJoinWorkerThread when there is a SecurityManager - * present. These workers have no permissions set, do not belong - * to any user-defined ThreadGroup, and clear all ThreadLocals and - * reset the ContextClassLoader before (re)activating to execute - * top-level task. The associated mechanics may be JVM-dependent - * and must access particular Thread class fields to achieve this - * effect. + * InnocuousForkJoinWorkerThread for the commonPool. These + * workers do not belong to any user-defined ThreadGroup, and + * clear all ThreadLocals and reset the ContextClassLoader before + * (re)activating to execute top-level tasks. The associated + * mechanics may be JVM-dependent and must access particular + * Thread class fields to achieve this effect. * * InterruptibleTasks * ==================== @@ -917,9 +908,6 @@ public class ForkJoinPool extends AbstractExecutorService { * shorts would suffice. For class WorkQueue, an * embedded @Contended region segregates fields most heavily * updated by owners from those most commonly read by stealers or - * other management. For class WorkQueue, an embedded padded - * region segregates fields (all declared as "int") most heavily - * updated by owners from those most commonly read by stealers or * other management. * * Initial sizing and resizing of WorkQueue arrays is an even more @@ -929,8 +917,10 @@ public class ForkJoinPool extends AbstractExecutorService { * direct false-sharing and indirect cases due to GC bookkeeping * (cardmarks etc), and reduce the number of resizes, which are * not especially fast because they require atomic transfers. - * Currently, arrays are initialized to be just large enough to - * avoid resizing in most tree-structured tasks. (Maintenance note: + * Currently, arrays for workers are initialized to be just large + * enough to avoid resizing in most tree-structured tasks, but + * larger for external queues where both false-sharing problems + * and the need for resizing are more common. (Maintenance note: * any changes in fields, queues, or their uses, or JVM layout * policies, must be accompanied by re-evaluation of these * placement and sizing decisions.) @@ -1019,6 +1009,12 @@ public class ForkJoinPool extends AbstractExecutorService { */ static final int INITIAL_QUEUE_CAPACITY = 1 << 6; + /** + * Initial capacity of work-stealing queue array for external queues. + * Must be a power of two, at least 2. See above. + */ + static final int INITIAL_EXTERNAL_QUEUE_CAPACITY = 1 << 9; + // conversions among short, int, long static final int SMASK = 0xffff; // (unsigned) short bits static final long LMASK = 0xffffffffL; // lower 32 bits of long @@ -1097,21 +1093,6 @@ static long slotOffset(int index) { return ((long)index << ASHIFT) + ABASE; } - /** - * If there is a security manager, makes sure caller has - * permission to modify threads. - */ - @SuppressWarnings("removal") - private static void checkPermission() { - SecurityManager security; RuntimePermission perm; - if ((security = System.getSecurityManager()) != null) { - if ((perm = modifyThreadPermission) == null) - modifyThreadPermission = perm = // races OK - new RuntimePermission("modifyThread"); - security.checkPermission(perm); - } - } - // Nested classes /** @@ -1147,64 +1128,9 @@ public static interface ForkJoinWorkerThreadFactory { static final class DefaultForkJoinWorkerThreadFactory implements ForkJoinWorkerThreadFactory { public final ForkJoinWorkerThread newThread(ForkJoinPool pool) { - boolean isCommon = (pool.workerNamePrefix == null); - @SuppressWarnings("removal") - SecurityManager sm = System.getSecurityManager(); - if (sm != null && isCommon) - return newCommonWithACC(pool); - else - return newRegularWithACC(pool); - } - - /* - * Create and use static AccessControlContexts only if there - * is a SecurityManager. (These can be removed if/when - * SecurityManagers are removed from platform.) The ACCs are - * immutable and equivalent even when racily initialized, so - * they don't require locking, although with the chance of - * needlessly duplicate construction. - */ - @SuppressWarnings("removal") - static volatile AccessControlContext regularACC, commonACC; - - @SuppressWarnings("removal") - static ForkJoinWorkerThread newRegularWithACC(ForkJoinPool pool) { - AccessControlContext acc = regularACC; - if (acc == null) { - Permissions ps = new Permissions(); - ps.add(new RuntimePermission("getClassLoader")); - ps.add(new RuntimePermission("setContextClassLoader")); - regularACC = acc = - new AccessControlContext(new ProtectionDomain[] { - new ProtectionDomain(null, ps) }); - } - return AccessController.doPrivileged( - new PrivilegedAction<>() { - public ForkJoinWorkerThread run() { - return new ForkJoinWorkerThread(null, pool, true, false); - }}, acc); - } - - @SuppressWarnings("removal") - static ForkJoinWorkerThread newCommonWithACC(ForkJoinPool pool) { - AccessControlContext acc = commonACC; - if (acc == null) { - Permissions ps = new Permissions(); - ps.add(new RuntimePermission("getClassLoader")); - ps.add(new RuntimePermission("setContextClassLoader")); - ps.add(new RuntimePermission("modifyThread")); - ps.add(new RuntimePermission("enableContextClassLoaderOverride")); - ps.add(new RuntimePermission("modifyThreadGroup")); - commonACC = acc = - new AccessControlContext(new ProtectionDomain[] { - new ProtectionDomain(null, ps) }); - } - return AccessController.doPrivileged( - new PrivilegedAction<>() { - public ForkJoinWorkerThread run() { - return new ForkJoinWorkerThread. - InnocuousForkJoinWorkerThread(pool); - }}, acc); + return ((pool.workerNamePrefix == null) ? // is commonPool + new ForkJoinWorkerThread.InnocuousForkJoinWorkerThread(pool) : + new ForkJoinWorkerThread(null, pool, true, false)); } } @@ -1264,7 +1190,9 @@ final boolean tryLockPhase() { // seqlock acquire */ WorkQueue(ForkJoinWorkerThread owner, int id, int cfg, boolean clearThreadLocals) { - array = new ForkJoinTask<?>[INITIAL_QUEUE_CAPACITY]; + array = new ForkJoinTask<?>[owner == null ? + INITIAL_EXTERNAL_QUEUE_CAPACITY : + INITIAL_QUEUE_CAPACITY]; this.owner = owner; this.config = (clearThreadLocals) ? cfg | CLEAR_TLS : cfg; } @@ -3024,7 +2952,6 @@ public ForkJoinPool(int parallelism, Predicate<? super ForkJoinPool> saturate, long keepAliveTime, TimeUnit unit) { - checkPermission(); int p = parallelism; if (p <= 0 || p > MAX_CAP || p > maximumPoolSize || keepAliveTime <= 0L) throw new IllegalArgumentException(); @@ -3312,7 +3239,6 @@ public int setParallelism(int size) { throw new IllegalArgumentException(); if ((config & PRESET_SIZE) != 0) throw new UnsupportedOperationException("Cannot override System property"); - checkPermission(); return getAndSetParallelism(size); } @@ -3710,7 +3636,6 @@ public String toString() { * may not be rejected. */ public void shutdown() { - checkPermission(); if (workerNamePrefix != null) // not common pool tryTerminate(false, true); } @@ -3730,7 +3655,6 @@ public void shutdown() { * @return an empty list */ public List<Runnable> shutdownNow() { - checkPermission(); if (workerNamePrefix != null) // not common pool tryTerminate(true, true); return Collections.emptyList(); @@ -3837,7 +3761,6 @@ public boolean awaitQuiescence(long timeout, TimeUnit unit) { @Override public void close() { if (workerNamePrefix != null) { - checkPermission(); CountDownLatch done = null; boolean interrupted = false; while ((tryTerminate(interrupted, true) & TERMINATED) == 0) { @@ -4075,11 +3998,6 @@ public void endCompensatedBlock(ForkJoinPool pool, long post) { }); defaultForkJoinWorkerThreadFactory = new DefaultForkJoinWorkerThreadFactory(); - @SuppressWarnings("removal") - ForkJoinPool p = common = (System.getSecurityManager() == null) ? - new ForkJoinPool((byte)0) : - AccessController.doPrivileged(new PrivilegedAction<>() { - public ForkJoinPool run() { - return new ForkJoinPool((byte)0); }}); + common = new ForkJoinPool((byte)0); } } diff --git a/src/java.base/share/classes/java/util/concurrent/ForkJoinWorkerThread.java b/src/java.base/share/classes/java/util/concurrent/ForkJoinWorkerThread.java index 7a468666ad3..b942d3ecd09 100644 --- a/src/java.base/share/classes/java/util/concurrent/ForkJoinWorkerThread.java +++ b/src/java.base/share/classes/java/util/concurrent/ForkJoinWorkerThread.java @@ -35,10 +35,6 @@ package java.util.concurrent; -import java.security.AccessController; -import java.security.AccessControlContext; -import java.security.PrivilegedAction; -import java.security.ProtectionDomain; import jdk.internal.access.JavaLangAccess; import jdk.internal.access.SharedSecrets; import jdk.internal.misc.Unsafe; @@ -84,7 +80,7 @@ public class ForkJoinWorkerThread extends Thread { super.setDaemon(true); if (handler != null) super.setUncaughtExceptionHandler(handler); - if (useSystemClassLoader) + if (useSystemClassLoader && !clearThreadLocals) // else done by Thread ctor super.setContextClassLoader(ClassLoader.getSystemClassLoader()); } @@ -228,18 +224,23 @@ static boolean hasKnownQueuedWork() { } /** - * Clears ThreadLocals, and if necessary resets ContextClassLoader + * Clears ThreadLocals */ - final void resetThreadLocals() { + final void resetThreadLocals() { if (U.getReference(this, THREADLOCALS) != null) U.putReference(this, THREADLOCALS, null); if (U.getReference(this, INHERITABLETHREADLOCALS) != null) U.putReference(this, INHERITABLETHREADLOCALS, null); - if ((this instanceof InnocuousForkJoinWorkerThread) && - ((InnocuousForkJoinWorkerThread)this).needCCLReset()) - super.setContextClassLoader(ClassLoader.getSystemClassLoader()); + onThreadLocalReset(); } + /** + * Performs any further cleanup after ThreadLocals are cleared in + * method resetThreadLocals + */ + void onThreadLocalReset() { + } + private static final Unsafe U = Unsafe.getUnsafe(); private static final long THREADLOCALS = U.objectFieldOffset(Thread.class, "threadLocals"); @@ -248,10 +249,10 @@ final void resetThreadLocals() { private static final JavaLangAccess JLA = SharedSecrets.getJavaLangAccess(); /** - * A worker thread that has no permissions, is not a member of any - * user-defined ThreadGroup, uses the system class loader as - * thread context class loader, and clears all ThreadLocals after - * running each top-level task. + * A worker thread that is not a member of any user-defined + * ThreadGroup, uses the system class loader as thread context + * class loader, and clears all ThreadLocals after running each + * top-level task. */ static final class InnocuousForkJoinWorkerThread extends ForkJoinWorkerThread { /** The ThreadGroup for all InnocuousForkJoinWorkerThreads */ @@ -264,21 +265,20 @@ static final class InnocuousForkJoinWorkerThread extends ForkJoinWorkerThread { @Override // to silently fail public void setUncaughtExceptionHandler(UncaughtExceptionHandler x) { } - @Override // paranoically - @SuppressWarnings("removal") + @Override // to record changes public void setContextClassLoader(ClassLoader cl) { - if (System.getSecurityManager() != null && - cl != null && ClassLoader.getSystemClassLoader() != cl) - throw new SecurityException("setContextClassLoader"); - resetCCL = true; - super.setContextClassLoader(cl); + if (ClassLoader.getSystemClassLoader() != cl) { + resetCCL = true; + super.setContextClassLoader(cl); + } } - final boolean needCCLReset() { // get and clear - boolean needReset; - if (needReset = resetCCL) + @Override // to re-establish CCL if necessary + final void onThreadLocalReset() { + if (resetCCL) { resetCCL = false; - return needReset; + super.setContextClassLoader(ClassLoader.getSystemClassLoader()); + } } static ThreadGroup createGroup() { From fc2da15bcee9560186058b3e2fd12ddcb0eb0f39 Mon Sep 17 00:00:00 2001 From: Per Minborg <pminborg@openjdk.org> Date: Tue, 26 Nov 2024 12:07:26 +0000 Subject: [PATCH 248/311] 8344419: Use StaticProperty in some JDK classes Reviewed-by: alanb, rriggs --- src/java.base/share/classes/jdk/internal/misc/CDS.java | 3 ++- .../share/classes/sun/security/util/DomainName.java | 5 +++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/java.base/share/classes/jdk/internal/misc/CDS.java b/src/java.base/share/classes/jdk/internal/misc/CDS.java index ddb25cb7904..8661a2b3ff2 100644 --- a/src/java.base/share/classes/jdk/internal/misc/CDS.java +++ b/src/java.base/share/classes/jdk/internal/misc/CDS.java @@ -39,6 +39,7 @@ import java.util.stream.Stream; import jdk.internal.access.SharedSecrets; +import jdk.internal.util.StaticProperty; public class CDS { // Must be in sync with cdsConfig.hpp @@ -275,7 +276,7 @@ private static String dumpSharedArchive(boolean isStatic, String fileName) throw listFile.delete(); } dumpClassList(listFileName); - String jdkHome = System.getProperty("java.home"); + String jdkHome = StaticProperty.javaHome(); String classPath = System.getProperty("java.class.path"); List<String> cmds = new ArrayList<String>(); cmds.add(jdkHome + File.separator + "bin" + File.separator + "java"); // java diff --git a/src/java.base/share/classes/sun/security/util/DomainName.java b/src/java.base/share/classes/sun/security/util/DomainName.java index 8be55036b58..5182ad1b5ca 100644 --- a/src/java.base/share/classes/sun/security/util/DomainName.java +++ b/src/java.base/share/classes/sun/security/util/DomainName.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -47,6 +47,7 @@ import static java.nio.charset.StandardCharsets.UTF_8; +import jdk.internal.util.StaticProperty; import sun.security.ssl.SSLLogger; /** @@ -209,7 +210,7 @@ private static InputStream getPubSuffixStream() { new PrivilegedAction<>() { @Override public InputStream run() { - File f = new File(System.getProperty("java.home"), + File f = new File(StaticProperty.javaHome(), "lib/security/public_suffix_list.dat"); try { return new FileInputStream(f); From f0b72f728d357a257074177fbea2f1ff70cf70f2 Mon Sep 17 00:00:00 2001 From: Alan Bateman <alanb@openjdk.org> Date: Tue, 26 Nov 2024 12:28:55 +0000 Subject: [PATCH 249/311] 8342380: Implement JEP 498: Warn upon Use of Memory-Access Methods in sun.misc.Unsafe Reviewed-by: vklang, jpai --- .../launcher/resources/launcher.properties | 2 +- src/java.base/share/man/java.md | 2 +- .../share/classes/sun/misc/Unsafe.java | 2 +- .../sun/misc/UnsafeMemoryAccessWarnings.java | 37 +++++++++++-------- 4 files changed, 24 insertions(+), 19 deletions(-) diff --git a/src/java.base/share/classes/sun/launcher/resources/launcher.properties b/src/java.base/share/classes/sun/launcher/resources/launcher.properties index f493dfd36b6..61ff563cb24 100644 --- a/src/java.base/share/classes/sun/launcher/resources/launcher.properties +++ b/src/java.base/share/classes/sun/launcher/resources/launcher.properties @@ -218,7 +218,7 @@ java.launcher.X.usage=\n\ \ --sun-misc-unsafe-memory-access=<value>\n\ \ allow or deny usage of unsupported API sun.misc.Unsafe\n\ \ <value> is one of "allow", "warn", "debug", or "deny".\n\ -\ The default value is "allow".\n\n\ +\ The default value is "warn".\n\n\ These extra options are subject to change without notice.\n # Translators please note do not translate the options themselves diff --git a/src/java.base/share/man/java.md b/src/java.base/share/man/java.md index 5f1f9d8ef45..f1f1cc27e4c 100644 --- a/src/java.base/share/man/java.md +++ b/src/java.base/share/man/java.md @@ -979,7 +979,7 @@ the Java HotSpot Virtual Machine. : Disallow use of the memory-access methods by throwing an `UnsupportedOperationException` on every usage. - The default value when the option is not specified is `allow`. + The default value when the option is not specified is `warn`. ## Extra Options for macOS diff --git a/src/jdk.unsupported/share/classes/sun/misc/Unsafe.java b/src/jdk.unsupported/share/classes/sun/misc/Unsafe.java index 563f2039de9..043af1fc9b7 100644 --- a/src/jdk.unsupported/share/classes/sun/misc/Unsafe.java +++ b/src/jdk.unsupported/share/classes/sun/misc/Unsafe.java @@ -1846,7 +1846,7 @@ private enum MemoryAccessOption { DENY; private static MemoryAccessOption defaultValue() { - return ALLOW; + return WARN; } /** diff --git a/test/jdk/sun/misc/UnsafeMemoryAccessWarnings.java b/test/jdk/sun/misc/UnsafeMemoryAccessWarnings.java index 3d4b6965828..0e71dfdc194 100644 --- a/test/jdk/sun/misc/UnsafeMemoryAccessWarnings.java +++ b/test/jdk/sun/misc/UnsafeMemoryAccessWarnings.java @@ -23,7 +23,7 @@ /* * @test - * @bug 8331670 + * @bug 8331670 8338383 * @summary Basic test for --sun-misc-unsafe-memory-access=<value> * @library /test/lib * @compile TryUnsafeMemoryAccess.java @@ -43,19 +43,15 @@ class UnsafeMemoryAccessWarnings { /** - * Test default is "allow" + * Test default is "warn" */ - @Test - void testDefault() throws Exception { - test("allocateMemory+freeMemory+objectFieldOffset+putLong+getLong+invokeCleaner") - .shouldHaveExitValue(0) - .shouldNotContain("WARNING: A terminally deprecated method in sun.misc.Unsafe has been called") - .shouldNotContain("WARNING: sun.misc.Unsafe::allocateMemory") - .shouldNotContain("WARNING: sun.misc.Unsafe::freeMemory") - .shouldNotContain("WARNING: sun.misc.Unsafe::objectFieldOffset") - .shouldNotContain("WARNING: sun.misc.Unsafe::putLong") - .shouldNotContain("WARNING: sun.misc.Unsafe::getLong") - .shouldNotContain("WARNING: sun.misc.Unsafe::invokeCleaner"); + @ParameterizedTest + @ValueSource(strings = { + "allocateMemory+freeMemory", + "objectFieldOffset+putLong+getLong" + }) + void testDefault(String input) throws Exception { + testOneWarning(input); } /** @@ -81,11 +77,19 @@ void testAllow() throws Exception { @ParameterizedTest @ValueSource(strings = { "allocateMemory+freeMemory", - "objectFieldOffset+putLong+getLong", - "invokeCleaner" + "objectFieldOffset+putLong+getLong" }) void testWarn(String input) throws Exception { - var output = test(input, "--sun-misc-unsafe-memory-access=warn").shouldHaveExitValue(0); + testOneWarning(input, "--sun-misc-unsafe-memory-access=warn"); + } + + /** + * Test that a warning is printed by the first memory access method only. + * @param input comma separated list of Unsafe memory access methods to execute + * @param vmopts VM options + */ + private void testOneWarning(String input, String... vmopts) throws Exception { + var output = test(input, vmopts).shouldHaveExitValue(0); // should be warning printed for the first memory access method String[] methodNames = input.split("\\+"); @@ -99,6 +103,7 @@ void testWarn(String input) throws Exception { int index = 1; while (index < methodNames.length) { String methodName = methodNames[index++]; + assertNotEquals(firstMethodName, methodName); output.shouldNotContain("WARNING: sun.misc.Unsafe::" + methodName); } } From 86d527f987a27c22fae784812aad9d8f370d2e9c Mon Sep 17 00:00:00 2001 From: Sean Mullan <mullan@openjdk.org> Date: Tue, 26 Nov 2024 14:21:01 +0000 Subject: [PATCH 250/311] 8344949: javax.security.auth.Subject.SecureSet.writeObject does not do a security check anymore Reviewed-by: alanb --- .../share/classes/javax/security/auth/Subject.java | 6 ------ 1 file changed, 6 deletions(-) diff --git a/src/java.base/share/classes/javax/security/auth/Subject.java b/src/java.base/share/classes/javax/security/auth/Subject.java index 5c5726ca38f..303abe49538 100644 --- a/src/java.base/share/classes/javax/security/auth/Subject.java +++ b/src/java.base/share/classes/javax/security/auth/Subject.java @@ -1418,12 +1418,6 @@ public int hashCode() { /** * Writes this object out to a stream (i.e., serializes it). * - * @serialData If this is a private credential set, - * a security check is performed to ensure that - * the caller has permission to access each credential - * in the set. If the security check passes, - * the set is serialized. - * * @param oos the {@code ObjectOutputStream} to which data is written * @throws IOException if an I/O error occurs */ From c329f97f3211bc14aa4211461bb9a7abb073296e Mon Sep 17 00:00:00 2001 From: "Marc R. Hoffmann" <marchof@openjdk.org> Date: Tue, 26 Nov 2024 15:09:49 +0000 Subject: [PATCH 251/311] 8345015: Remove unused method lookup_time_t_function Reviewed-by: alanb --- .../native/libnio/fs/UnixNativeDispatcher.c | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/src/java.base/unix/native/libnio/fs/UnixNativeDispatcher.c b/src/java.base/unix/native/libnio/fs/UnixNativeDispatcher.c index 1a616446b4a..87cdd228b22 100644 --- a/src/java.base/unix/native/libnio/fs/UnixNativeDispatcher.c +++ b/src/java.base/unix/native/libnio/fs/UnixNativeDispatcher.c @@ -250,23 +250,6 @@ static int statx_wrapper(int dirfd, const char *restrict pathname, int flags, } #endif -#if defined(__linux__) && defined(__arm__) -/** - * Lookup functions with time_t parameter. Try to use 64 bit symbol - * if sizeof(time_t) exceeds 32 bit. - */ -static void* lookup_time_t_function(const char* symbol, const char* symbol64) { - void *func_ptr = NULL; - if (sizeof(time_t) > 4) { - func_ptr = dlsym(RTLD_DEFAULT, symbol64); - } - if (func_ptr == NULL) { - return dlsym(RTLD_DEFAULT, symbol); - } - return func_ptr; -} -#endif - /** * Call this to throw an internal UnixException when a system/library * call fails From d8a23373c6fb349314c8cceda9608eaac75198fd Mon Sep 17 00:00:00 2001 From: Roger Riggs <rriggs@openjdk.org> Date: Tue, 26 Nov 2024 17:08:45 +0000 Subject: [PATCH 252/311] 8344895: SM cleanup of module java.xml Reviewed-by: joehw --- .../internal/utils/FeaturePropertyBase.java | 6 +- .../xalan/internal/utils/ObjectFactory.java | 31 +-- .../xsltc/compiler/util/ErrorMessages.java | 9 +- .../xsltc/compiler/util/ErrorMessages_de.java | 6 +- .../xsltc/compiler/util/ErrorMessages_es.java | 5 +- .../xsltc/compiler/util/ErrorMessages_fr.java | 4 +- .../xsltc/compiler/util/ErrorMessages_it.java | 4 +- .../xsltc/compiler/util/ErrorMessages_ja.java | 6 +- .../xsltc/compiler/util/ErrorMessages_ko.java | 4 +- .../compiler/util/ErrorMessages_pt_BR.java | 4 +- .../xsltc/compiler/util/ErrorMessages_sv.java | 4 +- .../compiler/util/ErrorMessages_zh_CN.java | 6 +- .../compiler/util/ErrorMessages_zh_TW.java | 4 +- .../xsltc/compiler/util/ErrorMsg.java | 6 +- .../internal/xsltc/compiler/util/Type.java | 8 +- .../internal/xsltc/compiler/util/Util.java | 6 +- .../xsltc/dom/NodeSortRecordFactory.java | 5 +- .../internal/xsltc/trax/TemplatesImpl.java | 29 +-- .../xsltc/trax/TransformerFactoryImpl.java | 13 +- .../xalan/internal/xsltc/trax/Util.java | 8 +- .../xerces/internal/dom/CoreDocumentImpl.java | 6 +- .../internal/impl/XMLEntityManager.java | 9 +- .../internal/impl/dv/xs/TypeValidator.java | 6 +- .../jaxp/DocumentBuilderFactoryImpl.java | 10 +- .../internal/jaxp/SAXParserFactoryImpl.java | 10 +- .../datatype/XMLGregorianCalendarImpl.java | 10 +- .../jaxp/validation/XMLSchemaFactory.java | 15 +- .../XMLSchemaValidatorComponentManager.java | 10 +- .../xerces/internal/utils/ObjectFactory.java | 42 +--- .../utils/XMLSecurityPropertyManager.java | 4 +- .../internal/serialize/SerializerFactory.java | 6 +- .../xml/internal/serializer/Encodings.java | 66 +++--- .../serializer/OutputPropertiesFactory.java | 6 +- .../serializer/utils/SystemIDResolver.java | 24 +- .../apache/xml/internal/utils/ObjectPool.java | 6 +- .../xml/internal/utils/SystemIDResolver.java | 26 +-- .../xml/internal/utils/XMLReaderManager.java | 6 +- .../internal/utils/res/XResourceBundle.java | 5 - .../internal/compiler/FunctionTable.java | 6 +- .../functions/FuncSystemProperty.java | 40 +--- .../xpath/internal/jaxp/XPathFactoryImpl.java | 9 +- .../internal/res/XPATHErrorResources.java | 8 +- .../internal/res/XPATHErrorResources_de.java | 8 +- .../internal/res/XPATHErrorResources_es.java | 8 +- .../internal/res/XPATHErrorResources_fr.java | 8 +- .../internal/res/XPATHErrorResources_it.java | 8 +- .../internal/res/XPATHErrorResources_ja.java | 8 +- .../internal/res/XPATHErrorResources_ko.java | 8 +- .../res/XPATHErrorResources_pt_BR.java | 8 +- .../internal/res/XPATHErrorResources_sv.java | 8 +- .../res/XPATHErrorResources_zh_CN.java | 8 +- .../res/XPATHErrorResources_zh_TW.java | 8 +- .../xml/internal/stream/XMLEntityStorage.java | 9 +- .../stream/writers/WriterUtility.java | 4 +- .../stream/writers/XMLStreamWriterImpl.java | 4 +- .../javax/xml/catalog/CatalogFeatures.java | 2 +- .../javax/xml/datatype/FactoryFinder.java | 58 ++--- .../javax/xml/parsers/FactoryFinder.java | 57 ++--- .../javax/xml/stream/FactoryFinder.java | 81 ++----- .../javax/xml/transform/FactoryFinder.java | 59 ++--- .../xml/transform/TransformerException.java | 15 +- .../xml/validation/SchemaFactoryFinder.java | 64 ++---- .../javax/xml/xpath/XPathFactoryFinder.java | 63 ++--- .../jdk/xml/internal/JdkXmlFeatures.java | 4 +- .../classes/jdk/xml/internal/JdkXmlUtils.java | 14 +- .../jdk/xml/internal/SecuritySupport.java | 217 ++++-------------- .../share/classes/jdk/xml/internal/Utils.java | 13 +- .../jdk/xml/internal/XMLSecurityManager.java | 4 +- .../bootstrap/DOMImplementationRegistry.java | 63 +---- .../org/xml/sax/helpers/NewInstance.java | 14 +- .../org/xml/sax/helpers/ParserAdapter.java | 4 +- .../org/xml/sax/helpers/ParserFactory.java | 4 +- .../org/xml/sax/helpers/XMLReaderFactory.java | 18 +- 73 files changed, 345 insertions(+), 1004 deletions(-) diff --git a/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/utils/FeaturePropertyBase.java b/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/utils/FeaturePropertyBase.java index 1ba2190b65f..a5000b026e1 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/utils/FeaturePropertyBase.java +++ b/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/utils/FeaturePropertyBase.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -31,7 +31,7 @@ /** * This is the base class for features and properties * - * @LastModified: Mar 2023 + * @LastModified: Nov 2024 */ public abstract class FeaturePropertyBase { @@ -198,7 +198,7 @@ public <E extends Enum<E>> int getIndex(Class<E> property, String propertyName) */ void getSystemProperty(Enum<?> property, String systemProperty) { try { - String value = SecuritySupport.getSystemProperty(systemProperty); + String value = System.getProperty(systemProperty); if (value != null) { values[property.ordinal()] = value; states[property.ordinal()] = State.SYSTEMPROPERTY; diff --git a/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/utils/ObjectFactory.java b/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/utils/ObjectFactory.java index c1d910b0616..58971b4d6e2 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/utils/ObjectFactory.java +++ b/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/utils/ObjectFactory.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -32,7 +32,7 @@ * class and modified to be used as a general utility for creating objects * dynamically. * - * @LastModified: Oct 2017 + * @LastModified: Nov 2024 */ public class ObjectFactory { @@ -57,14 +57,8 @@ private static void debugPrintln(Supplier<String> msgGen) { * Figure out which ClassLoader to use. For JDK 1.2 and later use * the context ClassLoader. */ - @SuppressWarnings("removal") public static ClassLoader findClassLoader() { - if (System.getSecurityManager()!=null) { - //this will ensure bootclassloader is used - return null; - } - // Figure out which ClassLoader to use for loading the provider // class. If there is a Context ClassLoader then use it. ClassLoader context = SecuritySupport.getContextClassLoader(); @@ -123,8 +117,7 @@ public static ClassLoader findClassLoader() public static Object newInstance(String className, boolean doFallback) throws ConfigurationError { - @SuppressWarnings("removal") - ClassLoader cl = System.getSecurityManager()!=null ? null : findClassLoader(); + ClassLoader cl = findClassLoader(); try{ Class<?> providerClass = findProviderClass(className, cl, doFallback); Object instance = providerClass.getConstructor().newInstance(); @@ -161,24 +154,6 @@ private static Class<?> findProviderClass(String className, ClassLoader cl, { //throw security exception if the calling thread is not allowed to access the //class. Restrict the access to the package classes as specified in java.security policy. - @SuppressWarnings("removal") - SecurityManager security = System.getSecurityManager(); - try{ - if (security != null){ - if (className.startsWith(JAXP_INTERNAL) || - className.startsWith(STAX_INTERNAL)) { - cl = null; - } else { - final int lastDot = className.lastIndexOf("."); - String packageName = className; - if (lastDot != -1) packageName = className.substring(0, lastDot); - security.checkPackageAccess(packageName); - } - } - }catch(SecurityException e){ - throw e; - } - Class<?> providerClass; if (cl == null) { providerClass = Class.forName(className, false, ObjectFactory.class.getClassLoader()); diff --git a/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages.java b/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages.java index 0c20a0ac919..c34f4fa59eb 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages.java +++ b/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2024, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -24,7 +24,7 @@ /** * @author Morten Jorgensen - * @LastModified: Jan 2022 + * @LastModified: Nov 2024 */ public class ErrorMessages extends ListResourceBundle { @@ -1028,11 +1028,6 @@ public Object[][] getContents() "smaller templates." }, - {ErrorMsg.DESERIALIZE_TRANSLET_ERR, "When Java security is enabled, " - + "support for deserializing TemplatesImpl is disabled. This can be " - + "overridden by setting the jdk.xml.enableTemplatesImplDeserialization" - + " system property to true."}, - {ErrorMsg.XPATH_GROUP_LIMIT, "JAXP0801001: the compiler encountered an XPath expression containing " + "''{0}'' groups that exceeds the ''{1}'' limit set by ''{2}''."}, diff --git a/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_de.java b/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_de.java index a73fe47191f..12ec243bbc9 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_de.java +++ b/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_de.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2024, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -24,7 +24,7 @@ /** * @author Morten Jorgensen - * @LastModified: Jan 2022 + * @LastModified: Nov 2024 */ public class ErrorMessages_de extends ListResourceBundle { @@ -981,8 +981,6 @@ public Object[][] getContents() "Interner XSLTC-Fehler: Eine Methode im Translet \u00FCberschreitet die Java Virtual Machine-L\u00E4ngeneinschr\u00E4nkung einer Methode von 64 KB. Ursache hierf\u00FCr sind in der Regel sehr gro\u00DFe Vorlagen in einem Stylesheet. Versuchen Sie, das Stylesheet mit kleineren Vorlagen umzustrukturieren." }, - {ErrorMsg.DESERIALIZE_TRANSLET_ERR, "Wenn die Java-Sicherheit aktiviert ist, wird die Unterst\u00FCtzung f\u00FCr das Deserialisieren von TemplatesImpl deaktiviert. Dieses Verhalten kann durch Setzen der Systemeigenschaft jdk.xml.enableTemplatesImplDeserialization auf \"true\" au\u00DFer Kraft gesetzt werden."}, - {ErrorMsg.XPATH_GROUP_LIMIT, "JAXP0801001: Im Compiler ist ein XPath-Ausdruck mit {0} Gruppen aufgetreten, der den von \"{2}\" festgelegten Grenzwert \"{1}\" \u00FCberschreitet."}, diff --git a/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_es.java b/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_es.java index 111b251d48d..099644221a6 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_es.java +++ b/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_es.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2024, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -979,9 +979,6 @@ public Object[][] getContents() {ErrorMsg.OUTLINE_ERR_METHOD_TOO_BIG, "Error interno de XSLTC: un m\u00E9todo en el translet excede la limitaci\u00F3n de Java Virtual Machine de longitud de un m\u00E9todo de 64 kilobytes. Normalmente, esto lo causan plantillas en una hoja de estilos demasiado grandes. Pruebe a reestructurar la hoja de estilos para utilizar plantillas m\u00E1s peque\u00F1as." }, - - {ErrorMsg.DESERIALIZE_TRANSLET_ERR, "Cuando la seguridad de Java est\u00E1 activada, el soporte para anular la serializaci\u00F3n de TemplatesImpl est\u00E1 desactivado. Esto se puede sustituir definiendo la propiedad del sistema jdk.xml.enableTemplatesImplDeserialization en true."} - }; } diff --git a/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_fr.java b/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_fr.java index 1123464069e..5690aff3192 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_fr.java +++ b/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_fr.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2024, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -980,8 +980,6 @@ public Object[][] getContents() "Erreur XSLTC interne : une m\u00E9thode dans le translet d\u00E9passe la limite de la JVM concernant la longueur d'une m\u00E9thode de 64 kilo-octets. En g\u00E9n\u00E9ral, ceci est d\u00FB \u00E0 de tr\u00E8s grands mod\u00E8les dans une feuille de style. Essayez de restructurer la feuille de style pour utiliser des mod\u00E8les plus petits." }, - {ErrorMsg.DESERIALIZE_TRANSLET_ERR, "Lorsque la s\u00E9curit\u00E9 Java est activ\u00E9e, la prise en charge de la d\u00E9s\u00E9rialisation de TemplatesImpl est d\u00E9sactiv\u00E9e. La d\u00E9finition de la propri\u00E9t\u00E9 syst\u00E8me jdk.xml.enableTemplatesImplDeserialization sur True permet de remplacer ce param\u00E8tre."} - }; } diff --git a/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_it.java b/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_it.java index ab05118b8a1..a5c9e0dc348 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_it.java +++ b/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_it.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2024, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -980,8 +980,6 @@ public Object[][] getContents() "Errore XSLTC interno: un metodo nel translet supera la limitazione Java Virtual Machine relativa alla lunghezza per un metodo di 64 kilobyte. Ci\u00F2 \u00E8 generalmente causato dalle grandi dimensioni dei modelli in un foglio di stile. Provare a ristrutturare il foglio di stile per utilizzare modelli di dimensioni inferiori." }, - {ErrorMsg.DESERIALIZE_TRANSLET_ERR, "Quando la sicurezza Java \u00E8 abilitata, il supporto per la deserializzazione TemplatesImpl \u00E8 disabilitato. \u00C8 possibile ignorare questa condizione impostando su true la propriet\u00E0 di sistema jdk.xml.enableTemplatesImplDeserialization."} - }; } diff --git a/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_ja.java b/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_ja.java index ba170bdfffa..5e03673aef5 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_ja.java +++ b/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_ja.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2024, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -24,7 +24,7 @@ /** * @author Morten Jorgensen - * @LastModified: Jan 2022 + * @LastModified: Nov 2024 */ public class ErrorMessages_ja extends ListResourceBundle { @@ -981,8 +981,6 @@ public Object[][] getContents() "\u5185\u90E8XSLTC\u30A8\u30E9\u30FC: \u30C8\u30E9\u30F3\u30B9\u30EC\u30C3\u30C8\u5185\u306E\u30E1\u30BD\u30C3\u30C9\u304C\u3001Java\u4EEE\u60F3\u30DE\u30B7\u30F3\u306E\u5236\u9650(1\u30E1\u30BD\u30C3\u30C9\u306E\u9577\u3055\u306F\u6700\u592764\u30AD\u30ED\u30D0\u30A4\u30C8)\u3092\u8D85\u3048\u3066\u3044\u307E\u3059\u3002\u4E00\u822C\u7684\u306B\u3001\u30B9\u30BF\u30A4\u30EB\u30B7\u30FC\u30C8\u5185\u306E\u30C6\u30F3\u30D7\u30EC\u30FC\u30C8\u306E\u30B5\u30A4\u30BA\u304C\u5927\u304D\u904E\u304E\u308B\u3053\u3068\u304C\u539F\u56E0\u3068\u3057\u3066\u8003\u3048\u3089\u308C\u307E\u3059\u3002\u5C0F\u3055\u3044\u30B5\u30A4\u30BA\u306E\u30C6\u30F3\u30D7\u30EC\u30FC\u30C8\u3092\u4F7F\u7528\u3057\u3066\u3001\u30B9\u30BF\u30A4\u30EB\u30B7\u30FC\u30C8\u3092\u518D\u69CB\u6210\u3057\u3066\u304F\u3060\u3055\u3044\u3002" }, - {ErrorMsg.DESERIALIZE_TRANSLET_ERR, "Java\u30BB\u30AD\u30E5\u30EA\u30C6\u30A3\u304C\u6709\u52B9\u5316\u3055\u308C\u3066\u3044\u308B\u5834\u5408\u3001TemplatesImpl\u306E\u30C7\u30B7\u30EA\u30A2\u30E9\u30A4\u30BA\u306E\u30B5\u30DD\u30FC\u30C8\u306F\u7121\u52B9\u5316\u3055\u308C\u307E\u3059\u3002\u3053\u308C\u306F\u3001jdk.xml.enableTemplatesImplDeserialization\u30B7\u30B9\u30C6\u30E0\u30FB\u30D7\u30ED\u30D1\u30C6\u30A3\u3092true\u306B\u8A2D\u5B9A\u3057\u3066\u30AA\u30FC\u30D0\u30FC\u30E9\u30A4\u30C9\u3067\u304D\u307E\u3059\u3002"}, - {ErrorMsg.XPATH_GROUP_LIMIT, "JAXP0801001: \u30B3\u30F3\u30D1\u30A4\u30E9\u306F\u3001''{2}''\u3067\u8A2D\u5B9A\u3055\u308C\u305F''{1}''\u5236\u9650\u3092\u8D85\u3048\u308B''{0}''\u30B0\u30EB\u30FC\u30D7\u3092\u542B\u3080XPath\u5F0F\u3092\u691C\u51FA\u3057\u307E\u3057\u305F\u3002"}, diff --git a/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_ko.java b/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_ko.java index 79785fb75f0..5128d65cadf 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_ko.java +++ b/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_ko.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2024, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -980,8 +980,6 @@ public Object[][] getContents() "\uB0B4\uBD80 XSLTC \uC624\uB958: translet\uC758 \uBA54\uC18C\uB4DC\uAC00 Java Virtual Machine\uC758 \uBA54\uC18C\uB4DC \uAE38\uC774 \uC81C\uD55C\uC778 64KB\uB97C \uCD08\uACFC\uD569\uB2C8\uB2E4. \uB300\uAC1C \uC2A4\uD0C0\uC77C\uC2DC\uD2B8\uC758 \uD15C\uD50C\uB9AC\uD2B8\uAC00 \uB9E4\uC6B0 \uD06C\uAE30 \uB54C\uBB38\uC5D0 \uBC1C\uC0DD\uD569\uB2C8\uB2E4. \uB354 \uC791\uC740 \uD15C\uD50C\uB9AC\uD2B8\uB97C \uC0AC\uC6A9\uD558\uB3C4\uB85D \uC2A4\uD0C0\uC77C\uC2DC\uD2B8\uB97C \uC7AC\uAD6C\uC131\uD574 \uBCF4\uC2ED\uC2DC\uC624." }, - {ErrorMsg.DESERIALIZE_TRANSLET_ERR, "Java \uBCF4\uC548\uC774 \uC0AC\uC6A9\uC73C\uB85C \uC124\uC815\uB41C \uACBD\uC6B0 TemplatesImpl \uC9C1\uB82C\uD654 \uD574\uC81C\uC5D0 \uB300\uD55C \uC9C0\uC6D0\uC774 \uC0AC\uC6A9 \uC548\uD568\uC73C\uB85C \uC124\uC815\uB429\uB2C8\uB2E4. jdk.xml.enableTemplatesImplDeserialization \uC2DC\uC2A4\uD15C \uC18D\uC131\uC744 true\uB85C \uC124\uC815\uD558\uBA74 \uC774\uB97C \uBB34\uD6A8\uD654\uD560 \uC218 \uC788\uC2B5\uB2C8\uB2E4."} - }; } diff --git a/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_pt_BR.java b/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_pt_BR.java index 25e16e53925..061348dc2e5 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_pt_BR.java +++ b/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_pt_BR.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2024, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -980,8 +980,6 @@ public Object[][] getContents() "Erro interno de XSLTC: um m\u00E9todo no translet excede a limita\u00E7\u00E3o da M\u00E1quina Virtual Java quanto ao tamanho de um m\u00E9todo de de 64 kilobytes. Em geral, essa situa\u00E7\u00E3o \u00E9 causada por modelos de uma folha de estilos que s\u00E3o muito grandes. Tente reestruturar sua folha de estilos de forma a usar modelos menores." }, - {ErrorMsg.DESERIALIZE_TRANSLET_ERR, "Quando a seguran\u00E7a do Java est\u00E1 ativada, o suporte para desserializar TemplatesImpl fica desativado. Essa situa\u00E7\u00E3o pode ser corrigida definindo a propriedade do sistema jdk.xml.enableTemplatesImplDeserialization como true."} - }; } diff --git a/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_sv.java b/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_sv.java index 153e8fa3d15..78a7a6b92e3 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_sv.java +++ b/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_sv.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2024, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -980,8 +980,6 @@ public Object[][] getContents() "Internt XSLTC-fel: en metod i transleten \u00F6verstiger Java Virtual Machines l\u00E4ngdbegr\u00E4nsning f\u00F6r en metod p\u00E5 64 kilobytes. Det h\u00E4r orsakas vanligen av mycket stora mallar i en formatmall. F\u00F6rs\u00F6k att omstrukturera formatmallen att anv\u00E4nda mindre mallar." }, - {ErrorMsg.DESERIALIZE_TRANSLET_ERR, "N\u00E4r Java-s\u00E4kerheten \u00E4r aktiverad \u00E4r st\u00F6det f\u00F6r avserialisering av TemplatesImpl avaktiverat. Du kan \u00E5sidos\u00E4tta det h\u00E4r genom att st\u00E4lla in systemegenskapen jdk.xml.enableTemplatesImplDeserialization till sant."} - }; } diff --git a/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_zh_CN.java b/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_zh_CN.java index 7a96e488a9a..728abc0df37 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_zh_CN.java +++ b/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_zh_CN.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2024, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -24,7 +24,7 @@ /** * @author Morten Jorgensen - * @LastModified: Jan 2022 + * @LastModified: Nov 2024 */ public class ErrorMessages_zh_CN extends ListResourceBundle { @@ -981,8 +981,6 @@ public Object[][] getContents() "\u5185\u90E8 XSLTC \u9519\u8BEF: translet \u4E2D\u7684\u65B9\u6CD5\u8D85\u8FC7\u4E86 Java \u865A\u62DF\u673A\u7684\u65B9\u6CD5\u957F\u5EA6\u9650\u5236 64 KB\u3002\u8FD9\u901A\u5E38\u662F\u7531\u4E8E\u6837\u5F0F\u8868\u4E2D\u7684\u6A21\u677F\u975E\u5E38\u5927\u9020\u6210\u7684\u3002\u8BF7\u5C1D\u8BD5\u4F7F\u7528\u8F83\u5C0F\u7684\u6A21\u677F\u91CD\u65B0\u6784\u5EFA\u6837\u5F0F\u8868\u3002" }, - {ErrorMsg.DESERIALIZE_TRANSLET_ERR, "\u542F\u7528\u4E86 Java \u5B89\u5168\u65F6\uFF0C\u5C06\u7981\u7528\u5BF9\u53CD\u5E8F\u5217\u5316 TemplatesImpl \u7684\u652F\u6301\u3002\u53EF\u4EE5\u901A\u8FC7\u5C06 jdk.xml.enableTemplatesImplDeserialization \u7CFB\u7EDF\u5C5E\u6027\u8BBE\u7F6E\u4E3A true \u6765\u8986\u76D6\u6B64\u8BBE\u7F6E\u3002"}, - {ErrorMsg.XPATH_GROUP_LIMIT, "JAXP0801001\uFF1A\u7F16\u8BD1\u5668\u9047\u5230\u5305\u542B ''{0}'' \u7EC4\u7684 XPath \u8868\u8FBE\u5F0F\uFF0C\u8BE5\u8868\u8FBE\u5F0F\u8D85\u8FC7\u4E86 ''{2}'' \u8BBE\u7F6E\u7684 ''{1}'' \u9650\u5236\u3002"}, diff --git a/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_zh_TW.java b/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_zh_TW.java index 5ab9c32979f..07f1ff4f63d 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_zh_TW.java +++ b/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMessages_zh_TW.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2024, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -980,8 +980,6 @@ public Object[][] getContents() "\u5167\u90E8 XSLTC \u932F\u8AA4: translet \u4E2D\u7684\u65B9\u6CD5\u8D85\u904E Java \u865B\u64EC\u6A5F\u5668\u5C0D\u65BC\u65B9\u6CD5\u9577\u5EA6 64 KB \u7684\u9650\u5236\u3002\u9019\u901A\u5E38\u662F\u56E0\u70BA\u6A23\u5F0F\u8868\u4E2D\u6709\u975E\u5E38\u5927\u7684\u6A23\u677F\u3002\u8ACB\u5617\u8A66\u91CD\u65B0\u7D44\u7E54\u60A8\u7684\u6A23\u5F0F\u8868\u4EE5\u4F7F\u7528\u8F03\u5C0F\u7684\u6A23\u677F\u3002" }, - {ErrorMsg.DESERIALIZE_TRANSLET_ERR, "\u555F\u7528 Java \u5B89\u5168\u6642\uFF0C\u6703\u505C\u7528\u9084\u539F\u5E8F\u5217\u5316 TemplatesImpl \u7684\u652F\u63F4\u3002\u5C07 jdk.xml.enableTemplatesImplDeserialization \u7CFB\u7D71\u5C6C\u6027\u8A2D\u70BA\u771F\u5373\u53EF\u8986\u5BEB\u6B64\u8A2D\u5B9A\u3002"} - }; } diff --git a/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMsg.java b/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMsg.java index 937e7bc69ea..c586ad2674c 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMsg.java +++ b/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/util/ErrorMsg.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2024, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -33,7 +33,7 @@ * @author G. Todd Miller * @author Erwin Bolwidt <ejb@klomp.org> * @author Morten Jorgensen - * @LastModified: Jul 2022 + * @LastModified: Nov 2024 */ public final class ErrorMsg { @@ -169,8 +169,6 @@ public final class ErrorMsg { public static final String OUTLINE_ERR_METHOD_TOO_BIG = "OUTLINE_ERR_METHOD_TOO_BIG"; - public static final String DESERIALIZE_TRANSLET_ERR = "DESERIALIZE_TRANSLET_ERR"; - public static final String XPATH_LIMIT = "XPATH_LIMIT"; public static final String XPATH_GROUP_LIMIT = "XPATH_GROUP_LIMIT"; public static final String XPATH_OPERATOR_LIMIT = "XPATH_OPERATOR_LIMIT"; diff --git a/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/util/Type.java b/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/util/Type.java index 469d255ebf3..1d7796f7b69 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/util/Type.java +++ b/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/util/Type.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -30,7 +30,7 @@ * @author Jacek Ambroziak * @author Santiago Pericas-Geertsen * @author Morten Jorgensen - * @LastModified: Oct 2017 + * @LastModified: Nov 2024 */ public abstract class Type implements Constants { public static final Type Int = new IntType(); @@ -65,10 +65,6 @@ else if (javaClassName == "java.lang.String") { return Type.ObjectString; } else { - // - @SuppressWarnings("removal") - java.security.AccessControlContext acc = java.security.AccessController.getContext(); - acc.checkPermission(new RuntimePermission("getContextClassLoader")); return new ObjectType(javaClassName); } } diff --git a/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/util/Util.java b/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/util/Util.java index b02aad4f2fd..491000e60ff 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/util/Util.java +++ b/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/compiler/util/Util.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -29,13 +29,13 @@ /** * @author Jacek Ambroziak * @author Santiago Pericas-Geertsen - * @LastModified: Sep 2017 + * @LastModified: Nov 2024 */ public final class Util { private static char filesep; static { - String temp = SecuritySupport.getSystemProperty("file.separator", "/"); + String temp = System.getProperty("file.separator", "/"); filesep = temp.charAt(0); } diff --git a/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/dom/NodeSortRecordFactory.java b/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/dom/NodeSortRecordFactory.java index e7cbb69ecac..ddfd461ea45 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/dom/NodeSortRecordFactory.java +++ b/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/dom/NodeSortRecordFactory.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -31,7 +31,7 @@ import java.util.Locale; /** - * @LastModified: Oct 2017 + * @LastModified: Nov 2024 */ public class NodeSortRecordFactory { @@ -149,7 +149,6 @@ public NodeSortRecord makeNodeSortRecord(int node, int last) LinkageError, IllegalAccessException, InstantiationException, - SecurityException, TransletException { try { diff --git a/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/trax/TemplatesImpl.java b/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/trax/TemplatesImpl.java index bb1e89911eb..f167cf78d5a 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/trax/TemplatesImpl.java +++ b/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/trax/TemplatesImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2024, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -42,11 +42,9 @@ import java.lang.module.ModuleReader; import java.lang.module.ModuleReference; import java.lang.reflect.InvocationTargetException; -import java.security.AccessController; import java.security.CodeSigner; import java.security.CodeSource; import java.security.PermissionCollection; -import java.security.PrivilegedAction; import java.security.ProtectionDomain; import java.util.Arrays; import java.util.HashMap; @@ -60,7 +58,6 @@ import javax.xml.transform.TransformerConfigurationException; import javax.xml.transform.URIResolver; import jdk.xml.internal.JdkConstants; -import jdk.xml.internal.SecuritySupport; /** @@ -68,7 +65,7 @@ * @author G. Todd Millerj * @author Jochen Cordes <Jochen.Cordes@t-online.de> * @author Santiago Pericas-Geertsen - * @LastModified: May 2021 + * @LastModified: Nov 2024 */ public final class TemplatesImpl implements Templates, Serializable { static final long serialVersionUID = 673094361519270707L; @@ -262,16 +259,6 @@ public TemplatesImpl() { } private void readObject(ObjectInputStream is) throws IOException, ClassNotFoundException { - @SuppressWarnings("removal") - SecurityManager security = System.getSecurityManager(); - if (security != null){ - String temp = SecuritySupport.getSystemProperty(DESERIALIZE_TRANSLET); - if (temp == null || !(temp.length()==0 || temp.equalsIgnoreCase("true"))) { - ErrorMsg err = new ErrorMsg(ErrorMsg.DESERIALIZE_TRANSLET_ERR); - throw new UnsupportedOperationException(err.toString()); - } - } - // We have to read serialized fields first. ObjectInputStream.GetField gf = is.readFields(); _name = (String)gf.get("_name", null); @@ -441,10 +428,7 @@ public Set<ModuleReference> findAll() { Configuration cf = bootLayer.configuration() .resolve(finder, ModuleFinder.of(), Set.of(mn)); - PrivilegedAction<ModuleLayer> pa = () -> bootLayer.defineModules(cf, name -> loader); - @SuppressWarnings("removal") - ModuleLayer layer = AccessController.doPrivileged(pa); - + ModuleLayer layer = bootLayer.defineModules(cf, _ -> loader); Module m = layer.findModule(mn).get(); assert m.getLayer() == layer; @@ -463,14 +447,9 @@ private void defineTransletClasses() throw new TransformerConfigurationException(err.toString()); } - @SuppressWarnings("removal") TransletClassLoader loader = - AccessController.doPrivileged(new PrivilegedAction<TransletClassLoader>() { - public TransletClassLoader run() { - return new TransletClassLoader(ObjectFactory.findClassLoader(), + new TransletClassLoader(ObjectFactory.findClassLoader(), _tfactory.getExternalExtensionsMap()); - } - }); try { final int classCount = _bytecodes.length; diff --git a/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/trax/TransformerFactoryImpl.java b/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/trax/TransformerFactoryImpl.java index ca52f46daf7..440df5593ea 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/trax/TransformerFactoryImpl.java +++ b/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/trax/TransformerFactoryImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2024, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -88,7 +88,7 @@ * @author G. Todd Miller * @author Morten Jorgensen * @author Santiago Pericas-Geertsen - * @LastModified: July 2023 + * @LastModified: Nov 2024 */ public class TransformerFactoryImpl extends SAXTransformerFactory implements SourceLoader @@ -265,14 +265,7 @@ public PIParamWrapper(String media, String title, String charset) { /** * javax.xml.transform.sax.TransformerFactory implementation. */ - @SuppressWarnings("removal") public TransformerFactoryImpl() { - - if (System.getSecurityManager() != null) { - _isSecureMode = true; - _isNotSecureProcessing = false; - } - _xmlFeatures = new JdkXmlFeatures(!_isNotSecureProcessing); _overrideDefaultParser = _xmlFeatures.getFeature( JdkXmlFeatures.XmlFeature.JDK_OVERRIDE_PARSER); @@ -1392,7 +1385,7 @@ private byte[][] getBytecodesFromClasses(Source source, String fullClassName) // Find the parent directory of the translet. String transletParentDir = transletFile.getParent(); if (transletParentDir == null) - transletParentDir = SecuritySupport.getSystemProperty("user.dir"); + transletParentDir = System.getProperty("user.dir"); File transletParentFile = new File(transletParentDir); diff --git a/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/trax/Util.java b/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/trax/Util.java index a0e0e948f8c..b4dd0ef6b97 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/trax/Util.java +++ b/src/java.xml/share/classes/com/sun/org/apache/xalan/internal/xsltc/trax/Util.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2024, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -50,7 +50,7 @@ * * Added Catalog Support for URI resolution * - * @LastModified: July 2023 + * @LastModified: Nov 2024 */ @SuppressWarnings("deprecation") //org.xml.sax.helpers.XMLReaderFactory public final class Util { @@ -207,10 +207,6 @@ else if (reader != null) { "TransformerFactory.newTemplates()"); throw new TransformerConfigurationException(err.toString()); } - catch (SecurityException e) { - ErrorMsg err = new ErrorMsg(ErrorMsg.FILE_ACCESS_ERR, systemId); - throw new TransformerConfigurationException(err.toString()); - } return input; } diff --git a/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/dom/CoreDocumentImpl.java b/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/dom/CoreDocumentImpl.java index 1fd84e9f639..ac60d679c86 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/dom/CoreDocumentImpl.java +++ b/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/dom/CoreDocumentImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 2024, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -83,7 +83,7 @@ * @author Andy Clark, IBM * @author Ralf Pfeiffer, IBM * @since PR-DOM-Level-1-19980818. - * @LastModified: Apr 2022 + * @LastModified: Nov 2024 */ public class CoreDocumentImpl extends ParentNode implements Document { @@ -306,7 +306,7 @@ public CoreDocumentImpl(boolean grammarAccess) { super(null); ownerDocument = this; allowGrammarAccess = grammarAccess; - String systemProp = SecuritySupport.getSystemProperty(Constants.SUN_DOM_PROPERTY_PREFIX+Constants.SUN_DOM_ANCESTOR_CHECCK); + String systemProp = System.getProperty(Constants.SUN_DOM_PROPERTY_PREFIX+Constants.SUN_DOM_ANCESTOR_CHECCK); if (systemProp != null) { if (systemProp.equalsIgnoreCase("false")) { ancestorChecking = false; diff --git a/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/XMLEntityManager.java b/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/XMLEntityManager.java index 455e2b5446f..e6ad6229224 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/XMLEntityManager.java +++ b/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/XMLEntityManager.java @@ -94,7 +94,7 @@ * @author K.Venugopal SUN Microsystems * @author Neeraj Bajaj SUN Microsystems * @author Sunitha Reddy SUN Microsystems - * @LastModified: Feb 2024 + * @LastModified: Nov 2024 */ public class XMLEntityManager implements XMLComponent, XMLEntityResolver { @@ -2010,12 +2010,7 @@ public static String expandSystemId(String systemId) { // which encoding to use. Leave them for now. private static synchronized URI getUserDir() throws URI.MalformedURIException { // get the user.dir property - String userDir = ""; - try { - userDir = SecuritySupport.getSystemProperty("user.dir"); - } - catch (SecurityException se) { - } + String userDir = System.getProperty("user.dir"); // return empty string if property value is empty string. if (userDir.length() == 0) diff --git a/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/dv/xs/TypeValidator.java b/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/dv/xs/TypeValidator.java index 59504ec0bd4..c3a14f6d82b 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/dv/xs/TypeValidator.java +++ b/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/dv/xs/TypeValidator.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2024, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -36,12 +36,12 @@ * @author Neeraj Bajaj, Sun Microsystems, inc. * @author Sandy Gao, IBM * - * @LastModified: Apr 2019 + * @LastModified: Nov 2024 */ public abstract class TypeValidator { private static final boolean USE_CODE_POINT_COUNT_FOR_STRING_LENGTH = - Boolean.parseBoolean(SecuritySupport.getSystemProperty( + Boolean.parseBoolean(System.getProperty( "com.sun.org.apache.xerces.internal.impl.dv.xs.useCodePointCountForStringLength", "false")); // which facets are allowed for this type diff --git a/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/jaxp/DocumentBuilderFactoryImpl.java b/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/jaxp/DocumentBuilderFactoryImpl.java index 1ee1e5225f2..5d469a0c56c 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/jaxp/DocumentBuilderFactoryImpl.java +++ b/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/jaxp/DocumentBuilderFactoryImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2024, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -39,7 +39,7 @@ /** * @author Rajiv Mordani * @author Edwin Goei - * @LastModified: July 2023 + * @LastModified: Nov 2024 */ public class DocumentBuilderFactoryImpl extends DocumentBuilderFactory { /** These are DocumentBuilderFactory attributes not DOM attributes */ @@ -220,7 +220,6 @@ public boolean getFeature(String name) } } - @SuppressWarnings("removal") public void setFeature(String name, boolean value) throws ParserConfigurationException { if (features == null) { @@ -228,11 +227,6 @@ public void setFeature(String name, boolean value) } // If this is the secure processing feature, save it then return. if (name.equals(XMLConstants.FEATURE_SECURE_PROCESSING)) { - if (System.getSecurityManager() != null && (!value)) { - throw new ParserConfigurationException( - SAXMessageFormatter.formatMessage(null, - "jaxp-secureprocessing-feature", null)); - } fSecureProcess = value; fSecurityManager.setSecureProcessing(fSecureProcess); features.put(name, value ? Boolean.TRUE : Boolean.FALSE); diff --git a/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/jaxp/SAXParserFactoryImpl.java b/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/jaxp/SAXParserFactoryImpl.java index 5086dab2669..c8b5a7c99b0 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/jaxp/SAXParserFactoryImpl.java +++ b/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/jaxp/SAXParserFactoryImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2024, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -43,7 +43,7 @@ * @author Rajiv Mordani * @author Edwin Goei * - * @LastModified: July 2023 + * @LastModified: Nov 2024 */ public class SAXParserFactoryImpl extends SAXParserFactory { @@ -116,7 +116,6 @@ private SAXParserImpl newSAXParserImpl() * Sets the particular feature in the underlying implementation of * org.xml.sax.XMLReader. */ - @SuppressWarnings("removal") public void setFeature(String name, boolean value) throws ParserConfigurationException, SAXNotRecognizedException, SAXNotSupportedException { @@ -125,11 +124,6 @@ public void setFeature(String name, boolean value) } // If this is the secure processing feature, save it then return. if (name.equals(XMLConstants.FEATURE_SECURE_PROCESSING)) { - if (System.getSecurityManager() != null && (!value)) { - throw new ParserConfigurationException( - SAXMessageFormatter.formatMessage(null, - "jaxp-secureprocessing-feature", null)); - } fSecureProcess = value; fSecurityManager.setSecureProcessing(fSecureProcess); putInFeatures(name, value); diff --git a/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/jaxp/datatype/XMLGregorianCalendarImpl.java b/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/jaxp/datatype/XMLGregorianCalendarImpl.java index fbb758def47..0569961013f 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/jaxp/datatype/XMLGregorianCalendarImpl.java +++ b/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/jaxp/datatype/XMLGregorianCalendarImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -190,7 +190,7 @@ * @author Sunitha Reddy * @see javax.xml.datatype.Duration * @since 1.5 - * @LastModified: Aug 2020 + * @LastModified: Nov 2024 */ public class XMLGregorianCalendarImpl @@ -2418,9 +2418,9 @@ public java.util.GregorianCalendar toGregorianCalendar() { */ private Locale getDefaultLocale() { - String lang = SecuritySupport.getSystemProperty("user.language.format"); - String country = SecuritySupport.getSystemProperty("user.country.format"); - String variant = SecuritySupport.getSystemProperty("user.variant.format"); + String lang = System.getProperty("user.language.format"); + String country = System.getProperty("user.country.format"); + String variant = System.getProperty("user.variant.format"); Locale locale = null; if (lang != null) { if (country != null) { diff --git a/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/jaxp/validation/XMLSchemaFactory.java b/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/jaxp/validation/XMLSchemaFactory.java index f36d2bd14bb..16c07fabbcd 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/jaxp/validation/XMLSchemaFactory.java +++ b/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/jaxp/validation/XMLSchemaFactory.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2024, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -70,7 +70,7 @@ * * @author Kohsuke Kawaguchi * - * @LastModified: July 2023 + * @LastModified: Nov 2024 */ public final class XMLSchemaFactory extends SchemaFactory { @@ -423,7 +423,7 @@ else if (name.equals(XMLGRAMMAR_POOL)) { } } - @SuppressWarnings({"removal","deprecation"}) + @SuppressWarnings("deprecation") public void setFeature(String name, boolean value) throws SAXNotRecognizedException, SAXNotSupportedException { if (name == null) { @@ -441,12 +441,6 @@ public void setFeature(String name, boolean value) } } if (name.equals(XMLConstants.FEATURE_SECURE_PROCESSING)) { - if (System.getSecurityManager() != null && (!value)) { - throw new SAXNotSupportedException( - SAXMessageFormatter.formatMessage(null, - "jaxp-secureprocessing-feature", null)); - } - fSecurityManager.setSecureProcessing(value); if (value) { fSecurityPropertyMgr.setValue(XMLSecurityPropertyManager.Property.ACCESS_EXTERNAL_DTD, @@ -464,8 +458,7 @@ else if (name.equals(USE_GRAMMAR_POOL_ONLY)) { } else if (name.equals(JdkConstants.ORACLE_FEATURE_SERVICE_MECHANISM)) { //in secure mode, let useServicesMechanism be determined by the constructor - if (System.getSecurityManager() != null) - return; + return; } if ((fXmlFeatures != null) && diff --git a/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/jaxp/validation/XMLSchemaValidatorComponentManager.java b/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/jaxp/validation/XMLSchemaValidatorComponentManager.java index 179afcaeb31..7644127a60d 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/jaxp/validation/XMLSchemaValidatorComponentManager.java +++ b/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/jaxp/validation/XMLSchemaValidatorComponentManager.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2024, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -57,7 +57,7 @@ * <p>An implementation of XMLComponentManager for a schema validator.</p> * * @author Michael Glavassevich, IBM - * @LastModified: July 2023 + * @LastModified: Nov 2024 */ final class XMLSchemaValidatorComponentManager extends ParserConfigurationSettings implements XMLComponentManager { @@ -230,7 +230,6 @@ final class XMLSchemaValidatorComponentManager extends ParserConfigurationSettin private Locale fLocale = null; /** Constructs a component manager suitable for Xerces' schema validator. */ - @SuppressWarnings("removal") public XMLSchemaValidatorComponentManager(XSGrammarPoolContainer grammarContainer) { // setup components fEntityManager = new XMLEntityManager(); @@ -293,11 +292,6 @@ public XMLSchemaValidatorComponentManager(XSGrammarPoolContainer grammarContaine fFeatures.put(UNPARSED_ENTITY_CHECKING, Boolean.TRUE); boolean secureProcessing = grammarContainer.getFeature(XMLConstants.FEATURE_SECURE_PROCESSING); - if (System.getSecurityManager() != null) { - _isSecureMode = true; - secureProcessing = true; - } - fInitSecurityManager = (XMLSecurityManager) grammarContainer.getProperty(SECURITY_MANAGER); if (fInitSecurityManager != null ) { diff --git a/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/utils/ObjectFactory.java b/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/utils/ObjectFactory.java index aaddf407288..2d06f6e7e8e 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/utils/ObjectFactory.java +++ b/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/utils/ObjectFactory.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -35,7 +35,7 @@ * when bundled as part of the JDK. * <p> * - * @LastModified: Oct 2017 + * @LastModified: Nov 2024 */ public final class ObjectFactory { @@ -55,13 +55,9 @@ public final class ObjectFactory { /** Returns true if debug has been enabled. */ private static boolean isDebugEnabled() { - try { - String val = SecuritySupport.getSystemProperty("xerces.debug"); - // Allow simply setting the prop to turn on debug - return (val != null && (!"false".equals(val))); - } - catch (SecurityException se) {} - return false; + String val = System.getProperty("xerces.debug"); + // Allow simply setting the prop to turn on debug + return (val != null && (!"false".equals(val))); } // isDebugEnabled() /** Prints a message to standard error if debugging is enabled. */ @@ -75,14 +71,9 @@ private static void debugPrintln(Supplier<String> msgGen) { * Figure out which ClassLoader to use. For JDK 1.2 and later use * the context ClassLoader. */ - @SuppressWarnings("removal") public static ClassLoader findClassLoader() throws ConfigurationError { - if (System.getSecurityManager()!=null) { - //this will ensure bootclassloader is used - return null; - } // Figure out which ClassLoader to use for loading the provider // class. If there is a Context ClassLoader then use it. ClassLoader context = SecuritySupport.getContextClassLoader(); @@ -138,16 +129,10 @@ public static ClassLoader findClassLoader() * Create an instance of a class using the same classloader for the ObjectFactory by default * or bootclassloader when Security Manager is in place */ - @SuppressWarnings("removal") public static Object newInstance(String className, boolean doFallback) throws ConfigurationError { - if (System.getSecurityManager()!=null) { - return newInstance(className, null, doFallback); - } else { - return newInstance(className, - findClassLoader (), doFallback); - } + return newInstance(className, findClassLoader (), doFallback); } /** @@ -191,21 +176,6 @@ public static Class<?> findProviderClass(String className, ClassLoader cl, boolean doFallback) throws ClassNotFoundException, ConfigurationError { - //throw security exception if the calling thread is not allowed to access the package - //restrict the access to package as speicified in java.security policy - @SuppressWarnings("removal") - SecurityManager security = System.getSecurityManager(); - if (security != null) { - if (className.startsWith(JAXP_INTERNAL) || - className.startsWith(STAX_INTERNAL)) { - cl = null; - } else { - final int lastDot = className.lastIndexOf("."); - String packageName = className; - if (lastDot != -1) packageName = className.substring(0, lastDot); - security.checkPackageAccess(packageName); - } - } Class<?> providerClass; if (cl == null) { //use the bootstrap ClassLoader. diff --git a/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/utils/XMLSecurityPropertyManager.java b/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/utils/XMLSecurityPropertyManager.java index d89072fe277..2b1e1411f5f 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/utils/XMLSecurityPropertyManager.java +++ b/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/utils/XMLSecurityPropertyManager.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -224,7 +224,7 @@ private void readSystemProperties() { */ private void getSystemProperty(Property property, String systemProperty) { try { - String value = SecuritySupport.getSystemProperty(systemProperty); + String value = System.getProperty(systemProperty); if (value != null) { values[property.ordinal()] = value; states[property.ordinal()] = State.SYSTEMPROPERTY; diff --git a/src/java.xml/share/classes/com/sun/org/apache/xml/internal/serialize/SerializerFactory.java b/src/java.xml/share/classes/com/sun/org/apache/xml/internal/serialize/SerializerFactory.java index f619b32fac5..17dcac31250 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/xml/internal/serialize/SerializerFactory.java +++ b/src/java.xml/share/classes/com/sun/org/apache/xml/internal/serialize/SerializerFactory.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -42,7 +42,7 @@ * {@link com.sun.org.apache.xml.internal.serialize.DOMSerializerImpl} is replaced * by {@link com.sun.org.apache.xml.internal.serializer.dom3.LSSerializerImpl}. * - * @LastModified: Oct 2017 + * @LastModified: Nov 2024 */ @Deprecated public abstract class SerializerFactory @@ -74,7 +74,7 @@ public abstract class SerializerFactory factory = new SerializerFactoryImpl( Method.TEXT ); registerSerializerFactory( factory ); - list = SecuritySupport.getSystemProperty( FactoriesProperty ); + list = System.getProperty( FactoriesProperty ); if ( list != null ) { token = new StringTokenizer( list, " ;,:" ); while ( token.hasMoreTokens() ) { diff --git a/src/java.xml/share/classes/com/sun/org/apache/xml/internal/serializer/Encodings.java b/src/java.xml/share/classes/com/sun/org/apache/xml/internal/serializer/Encodings.java index a88606d5085..a4792795a58 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/xml/internal/serializer/Encodings.java +++ b/src/java.xml/share/classes/com/sun/org/apache/xml/internal/serializer/Encodings.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -48,7 +48,7 @@ * for each encoding. * * @author <a href="mailto:arkin@intalio.com">Assaf Arkin</a> - * @LastModified: Oct 2017 + * @LastModified: Nov 2024 */ public final class Encodings extends Object @@ -229,41 +229,33 @@ static String getMimeEncoding(String encoding) if (null == encoding) { - try + // Get the default system character encoding. This may be + // incorrect if they passed in a writer, but right now there + // seems to be no way to get the encoding from a writer. + encoding = System.getProperty("file.encoding", "UTF8"); + + if (null != encoding) { - // Get the default system character encoding. This may be - // incorrect if they passed in a writer, but right now there - // seems to be no way to get the encoding from a writer. - encoding = SecuritySupport.getSystemProperty("file.encoding", "UTF8"); - - if (null != encoding) - { - - /* - * See if the mime type is equal to UTF8. If you don't - * do that, then convertJava2MimeEncoding will convert - * 8859_1 to "ISO-8859-1", which is not what we want, - * I think, and I don't think I want to alter the tables - * to convert everything to UTF-8. - */ - String jencoding = - (encoding.equalsIgnoreCase("Cp1252") - || encoding.equalsIgnoreCase("ISO8859_1") - || encoding.equalsIgnoreCase("8859_1") - || encoding.equalsIgnoreCase("UTF8")) - ? DEFAULT_MIME_ENCODING - : convertJava2MimeEncoding(encoding); - - encoding = - (null != jencoding) ? jencoding : DEFAULT_MIME_ENCODING; - } - else - { - encoding = DEFAULT_MIME_ENCODING; - } + /* + * See if the mime type is equal to UTF8. If you don't + * do that, then convertJava2MimeEncoding will convert + * 8859_1 to "ISO-8859-1", which is not what we want, + * I think, and I don't think I want to alter the tables + * to convert everything to UTF-8. + */ + String jencoding = + (encoding.equalsIgnoreCase("Cp1252") + || encoding.equalsIgnoreCase("ISO8859_1") + || encoding.equalsIgnoreCase("8859_1") + || encoding.equalsIgnoreCase("UTF8")) + ? DEFAULT_MIME_ENCODING + : convertJava2MimeEncoding(encoding); + + encoding = + (null != jencoding) ? jencoding : DEFAULT_MIME_ENCODING; } - catch (SecurityException se) + else { encoding = DEFAULT_MIME_ENCODING; } @@ -329,11 +321,7 @@ private InputStream openEncodingsFileStream() throws MalformedURLException, IOEx String urlString = null; InputStream is = null; - try { - urlString = SecuritySupport.getSystemProperty(ENCODINGS_PROP, ""); - } catch (SecurityException e) { - } - + urlString = System.getProperty(ENCODINGS_PROP, ""); if (urlString != null && urlString.length() > 0) { @SuppressWarnings("deprecation") URL url = new URL(urlString); diff --git a/src/java.xml/share/classes/com/sun/org/apache/xml/internal/serializer/OutputPropertiesFactory.java b/src/java.xml/share/classes/com/sun/org/apache/xml/internal/serializer/OutputPropertiesFactory.java index 9bd16cb86d7..5be3d6a6d76 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/xml/internal/serializer/OutputPropertiesFactory.java +++ b/src/java.xml/share/classes/com/sun/org/apache/xml/internal/serializer/OutputPropertiesFactory.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -70,7 +70,7 @@ * @see SerializerFactory * @see Method * @see Serializer - * @LastModified: May 2021 + * @LastModified: Nov 2024 */ public final class OutputPropertiesFactory { @@ -354,7 +354,7 @@ static private Properties initProperties(String[] keys, String[] values, Propert for (int i = 0; i < keys.length; i++) { // check System Property. This is kept as is for binary compatibility - String sys = SecuritySupport.getSystemProperty(keys[i]); + String sys = System.getProperty(keys[i]); props.put(keys[i], (sys == null) ? values[i] : sys); } diff --git a/src/java.xml/share/classes/com/sun/org/apache/xml/internal/serializer/utils/SystemIDResolver.java b/src/java.xml/share/classes/com/sun/org/apache/xml/internal/serializer/utils/SystemIDResolver.java index fa4e0c90126..ba8c75439e3 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/xml/internal/serializer/utils/SystemIDResolver.java +++ b/src/java.xml/share/classes/com/sun/org/apache/xml/internal/serializer/utils/SystemIDResolver.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -42,7 +42,7 @@ * * @xsl.usage internal * - * @LastModified: Jan 2022 + * @LastModified: Nov 2024 */ public final class SystemIDResolver { @@ -52,8 +52,7 @@ public final class SystemIDResolver * * <p>The relative URI is a local filesystem path. The path can be * absolute or relative. If it is a relative path, it is resolved relative - * to the system property "user.dir" if it is available; if not (i.e. in an - * Applet perhaps which throws SecurityException) then we just return the + * to the system property "user.dir" if it is available; if not then we just return the * relative path. The space and backslash characters are also replaced to * generate a good absolute URI.</p> * @@ -71,15 +70,7 @@ public static String getAbsoluteURIFromRelative(String localPath) String absolutePath = localPath; if (!isAbsolutePath(localPath)) { - try - { absolutePath = getAbsolutePathFromRelativePath(localPath); - } - // user.dir not accessible from applet - catch (SecurityException se) - { - return "file:" + localPath; - } } String urlString; @@ -244,14 +235,9 @@ public static String getAbsoluteURI(String systemId) if (secondColonIndex > 0) { String localPath = systemId.substring(secondColonIndex-1); - try { - if (!isAbsolutePath(localPath)) - absoluteURI = systemId.substring(0, secondColonIndex-1) + + if (!isAbsolutePath(localPath)) + absoluteURI = systemId.substring(0, secondColonIndex-1) + getAbsolutePathFromRelativePath(localPath); - } - catch (SecurityException se) { - return systemId; - } } } } diff --git a/src/java.xml/share/classes/com/sun/org/apache/xml/internal/utils/ObjectPool.java b/src/java.xml/share/classes/com/sun/org/apache/xml/internal/utils/ObjectPool.java index c6897b0fc0d..9b1fa9c25d5 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/xml/internal/utils/ObjectPool.java +++ b/src/java.xml/share/classes/com/sun/org/apache/xml/internal/utils/ObjectPool.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -31,7 +31,7 @@ /** * Pool of object of a given type to pick from to help memory usage * @xsl.usage internal - * @LastModified: Oct 2017 + * @LastModified: Nov 2024 */ public class ObjectPool implements java.io.Serializable { @@ -138,7 +138,7 @@ public synchronized Object getInstance() { return objectType.getConstructor().newInstance(); } - catch (InstantiationException | IllegalAccessException | SecurityException | + catch (InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException | NoSuchMethodException ex){} // Throw unchecked exception for error in pool configuration. diff --git a/src/java.xml/share/classes/com/sun/org/apache/xml/internal/utils/SystemIDResolver.java b/src/java.xml/share/classes/com/sun/org/apache/xml/internal/utils/SystemIDResolver.java index caf2a4b1ba7..8b1cbfe8279 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/xml/internal/utils/SystemIDResolver.java +++ b/src/java.xml/share/classes/com/sun/org/apache/xml/internal/utils/SystemIDResolver.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2024, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -35,7 +35,7 @@ * see code comments for details on how resolution is performed.</p> * @xsl.usage internal * - * @LastModified: Sept 2021 + * @LastModified: Nov 2024 */ public class SystemIDResolver { @@ -45,8 +45,7 @@ public class SystemIDResolver * * <p>The relative URI is a local filesystem path. The path can be * absolute or relative. If it is a relative path, it is resolved relative - * to the system property "user.dir" if it is available; if not (i.e. in an - * Applet perhaps which throws SecurityException) then we just return the + * to the system property "user.dir" if it is available; if not then we just return the * relative path. The space and backslash characters are also replaced to * generate a good absolute URI.</p> * @@ -64,15 +63,7 @@ public static String getAbsoluteURIFromRelative(String localPath) String absolutePath = localPath; if (!isAbsolutePath(localPath)) { - try - { absolutePath = getAbsolutePathFromRelativePath(localPath); - } - // user.dir not accessible from applet - catch (SecurityException se) - { - return "file:" + localPath; - } } String urlString; @@ -237,14 +228,9 @@ public static String getAbsoluteURI(String systemId) if (secondColonIndex > 0) { String localPath = systemId.substring(secondColonIndex-1); - try { - if (!isAbsolutePath(localPath)) - absoluteURI = systemId.substring(0, secondColonIndex-1) + - getAbsolutePathFromRelativePath(localPath); - } - catch (SecurityException se) { - return systemId; - } + if (!isAbsolutePath(localPath)) + absoluteURI = systemId.substring(0, secondColonIndex-1) + + getAbsolutePathFromRelativePath(localPath); } } } diff --git a/src/java.xml/share/classes/com/sun/org/apache/xml/internal/utils/XMLReaderManager.java b/src/java.xml/share/classes/com/sun/org/apache/xml/internal/utils/XMLReaderManager.java index d1ab24859fa..91a6597a603 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/xml/internal/utils/XMLReaderManager.java +++ b/src/java.xml/share/classes/com/sun/org/apache/xml/internal/utils/XMLReaderManager.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2007, 2024, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -37,7 +37,7 @@ * Creates XMLReader objects and caches them for re-use. * This class follows the singleton pattern. * - * @LastModified: July 2023 + * @LastModified: Nov 2024 */ public class XMLReaderManager { @@ -118,7 +118,7 @@ public synchronized XMLReader getXMLReader() throws SAXException { ReaderWrapper rw = m_readers.get(); boolean threadHasReader = (rw != null); reader = threadHasReader ? rw.reader : null; - String factory = SecuritySupport.getSystemProperty(property); + String factory = System.getProperty(property); if (threadHasReader && m_inUse.get(reader) != Boolean.TRUE && (rw.overrideDefaultParser == m_overrideDefaultParser) && ( factory == null || reader.getClass().getName().equals(factory))) { diff --git a/src/java.xml/share/classes/com/sun/org/apache/xml/internal/utils/res/XResourceBundle.java b/src/java.xml/share/classes/com/sun/org/apache/xml/internal/utils/res/XResourceBundle.java index def8cec86ce..90fabdc0f58 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/xml/internal/utils/res/XResourceBundle.java +++ b/src/java.xml/share/classes/com/sun/org/apache/xml/internal/utils/res/XResourceBundle.java @@ -21,12 +21,7 @@ package com.sun.org.apache.xml.internal.utils.res; -import java.security.AccessController; -import java.security.PrivilegedAction; import java.util.ListResourceBundle; -import java.util.Locale; -import java.util.MissingResourceException; -import java.util.ResourceBundle; /** * The default (english) resource bundle. diff --git a/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/compiler/FunctionTable.java b/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/compiler/FunctionTable.java index 532d1cf6299..326c40f4355 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/compiler/FunctionTable.java +++ b/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/compiler/FunctionTable.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved. */ /** * Licensed to the Apache Software Foundation (ASF) under one @@ -31,7 +31,7 @@ /** * The function table for XPath. * - * @LastModified: Oct 2017 + * @LastModified: Nov 2024 */ public class FunctionTable { @@ -348,7 +348,7 @@ Function getFunction(int which) Class<?> c = m_functions_customer[which-NUM_BUILT_IN_FUNCS]; return (Function) c.getConstructor().newInstance(); } - }catch (InstantiationException | IllegalAccessException | SecurityException | + }catch (InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException | NoSuchMethodException ex){ throw new TransformerException(ex.getMessage()); } diff --git a/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/functions/FuncSystemProperty.java b/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/functions/FuncSystemProperty.java index 819faa61b9c..0beccb5132b 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/functions/FuncSystemProperty.java +++ b/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/functions/FuncSystemProperty.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -32,7 +32,7 @@ /** * Execute the SystemProperty() function. * @xsl.usage advanced - * @LastModified: Sep 2017 + * @LastModified: Nov 2024 */ public class FuncSystemProperty extends FunctionOneArg { @@ -96,44 +96,21 @@ public XObject execute(XPathContext xctxt) throws javax.xml.transform.Transforme new Object[]{ namespace, fullName }); //"Don't currently do anything with namespace "+namespace+" in property: "+fullName); - try - { - result = SecuritySupport.getSystemProperty(propName); - - if (null == result) - { - - // result = System.getenv(propName); - return XString.EMPTYSTRING; - } - } - catch (SecurityException se) + result = System.getProperty(propName); + if (null == result) { - warn(xctxt, XPATHErrorResources.WG_SECURITY_EXCEPTION, - new Object[]{ fullName }); //"SecurityException when trying to access XSL system property: "+fullName); - + // result = System.getenv(propName); return XString.EMPTYSTRING; } } } else { - try - { - result = SecuritySupport.getSystemProperty(fullName); + result = System.getProperty(fullName); - if (null == result) - { - - // result = System.getenv(fullName); - return XString.EMPTYSTRING; - } - } - catch (SecurityException se) + if (null == result) { - warn(xctxt, XPATHErrorResources.WG_SECURITY_EXCEPTION, - new Object[]{ fullName }); //"SecurityException when trying to access XSL system property: "+fullName); - + // result = System.getenv(fullName); return XString.EMPTYSTRING; } } @@ -163,7 +140,6 @@ private void loadPropertyFile(Properties target) { try { - // Use SecuritySupport class to provide privileged access to property file try (InputStream is = SecuritySupport.getResourceAsStream(XSLT_PROPERTIES)) { target.load(is); // and load up the property bag from this } diff --git a/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/jaxp/XPathFactoryImpl.java b/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/jaxp/XPathFactoryImpl.java index aa1e37ea6b3..7c5269f9d12 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/jaxp/XPathFactoryImpl.java +++ b/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/jaxp/XPathFactoryImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2024, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -37,7 +37,7 @@ * * @author Ramesh Mandava * - * @LastModified: Jan 2022 + * @LastModified: Nov 2024 */ public class XPathFactoryImpl extends XPathFactory { @@ -78,12 +78,7 @@ public class XPathFactoryImpl extends XPathFactory { /** * javax.xml.xpath.XPathFactory implementation. */ - @SuppressWarnings("removal") public XPathFactoryImpl() { - if (System.getSecurityManager() != null) { - _isSecureMode = true; - _isNotSecureProcessing = false; - } _featureManager = new JdkXmlFeatures(!_isNotSecureProcessing); _xmlSecMgr = new XMLSecurityManager(true); } diff --git a/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/res/XPATHErrorResources.java b/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/res/XPATHErrorResources.java index eaa02c98798..433a0f85389 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/res/XPATHErrorResources.java +++ b/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/res/XPATHErrorResources.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -31,7 +31,7 @@ * Also you need to update the count of messages(MAX_CODE)or * the count of warnings(MAX_WARNING) [ Information purpose only] * @xsl.usage advanced - * @LastModified: Jul 2022 + * @LastModified: Nov 2024 */ public class XPATHErrorResources extends ListResourceBundle { @@ -337,7 +337,6 @@ public class XPATHErrorResources extends ListResourceBundle "WG_PROPERTY_NOT_SUPPORTED"; public static final String WG_DONT_DO_ANYTHING_WITH_NS = "WG_DONT_DO_ANYTHING_WITH_NS"; - public static final String WG_SECURITY_EXCEPTION = "WG_SECURITY_EXCEPTION"; public static final String WG_QUO_NO_LONGER_DEFINED = "WG_QUO_NO_LONGER_DEFINED"; public static final String WG_NEED_DERIVED_OBJECT_TO_IMPLEMENT_NODETEST = @@ -882,9 +881,6 @@ public class XPATHErrorResources extends ListResourceBundle { WG_DONT_DO_ANYTHING_WITH_NS, "Do not currently do anything with namespace {0} in property: {1}"}, - { WG_SECURITY_EXCEPTION, - "SecurityException when trying to access XSL system property: {0}"}, - { WG_QUO_NO_LONGER_DEFINED, "Old syntax: quo(...) is no longer defined in XPath."}, diff --git a/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/res/XPATHErrorResources_de.java b/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/res/XPATHErrorResources_de.java index eed36ae9d7a..272dca058d3 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/res/XPATHErrorResources_de.java +++ b/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/res/XPATHErrorResources_de.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -31,7 +31,7 @@ * Also you need to update the count of messages(MAX_CODE)or * the count of warnings(MAX_WARNING) [ Information purpose only] * @xsl.usage advanced - * @LastModified: Jul 2022 + * @LastModified: Nov 2024 */ public class XPATHErrorResources_de extends ListResourceBundle { @@ -337,7 +337,6 @@ public class XPATHErrorResources_de extends ListResourceBundle "WG_PROPERTY_NOT_SUPPORTED"; public static final String WG_DONT_DO_ANYTHING_WITH_NS = "WG_DONT_DO_ANYTHING_WITH_NS"; - public static final String WG_SECURITY_EXCEPTION = "WG_SECURITY_EXCEPTION"; public static final String WG_QUO_NO_LONGER_DEFINED = "WG_QUO_NO_LONGER_DEFINED"; public static final String WG_NEED_DERIVED_OBJECT_TO_IMPLEMENT_NODETEST = @@ -880,9 +879,6 @@ public class XPATHErrorResources_de extends ListResourceBundle { WG_DONT_DO_ANYTHING_WITH_NS, "Derzeit keine Aktion mit Namespace {0} in Eigenschaft {1} ausf\u00FChren"}, - { WG_SECURITY_EXCEPTION, - "SecurityException beim Versuch, auf XSL-Systemeigenschaft {0} zuzugreifen"}, - { WG_QUO_NO_LONGER_DEFINED, "Alte Syntax: quo(...) nicht mehr definiert in XPath."}, diff --git a/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/res/XPATHErrorResources_es.java b/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/res/XPATHErrorResources_es.java index faa87ab77c7..859983ca6dd 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/res/XPATHErrorResources_es.java +++ b/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/res/XPATHErrorResources_es.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -31,7 +31,7 @@ * Also you need to update the count of messages(MAX_CODE)or * the count of warnings(MAX_WARNING) [ Information purpose only] * @xsl.usage advanced - * @LastModified: May 2022 + * @LastModified: Nov 2024 */ public class XPATHErrorResources_es extends ListResourceBundle { @@ -326,7 +326,6 @@ public class XPATHErrorResources_es extends ListResourceBundle "WG_PROPERTY_NOT_SUPPORTED"; public static final String WG_DONT_DO_ANYTHING_WITH_NS = "WG_DONT_DO_ANYTHING_WITH_NS"; - public static final String WG_SECURITY_EXCEPTION = "WG_SECURITY_EXCEPTION"; public static final String WG_QUO_NO_LONGER_DEFINED = "WG_QUO_NO_LONGER_DEFINED"; public static final String WG_NEED_DERIVED_OBJECT_TO_IMPLEMENT_NODETEST = @@ -839,9 +838,6 @@ public class XPATHErrorResources_es extends ListResourceBundle { WG_DONT_DO_ANYTHING_WITH_NS, "No realice ninguna acci\u00F3n con el espacio de nombres {0} en la propiedad: {1}"}, - { WG_SECURITY_EXCEPTION, - "Excepci\u00F3n de seguridad al intentar acceder a la propiedad del sistema XSL: {0}"}, - { WG_QUO_NO_LONGER_DEFINED, "Sintaxis anterior: quo(...) ya no se define en XPath."}, diff --git a/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/res/XPATHErrorResources_fr.java b/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/res/XPATHErrorResources_fr.java index 4f17799a935..d9ddcf8212a 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/res/XPATHErrorResources_fr.java +++ b/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/res/XPATHErrorResources_fr.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -31,7 +31,7 @@ * Also you need to update the count of messages(MAX_CODE)or * the count of warnings(MAX_WARNING) [ Information purpose only] * @xsl.usage advanced - * @LastModified: May 2022 + * @LastModified: Nov 2024 */ public class XPATHErrorResources_fr extends ListResourceBundle { @@ -326,7 +326,6 @@ public class XPATHErrorResources_fr extends ListResourceBundle "WG_PROPERTY_NOT_SUPPORTED"; public static final String WG_DONT_DO_ANYTHING_WITH_NS = "WG_DONT_DO_ANYTHING_WITH_NS"; - public static final String WG_SECURITY_EXCEPTION = "WG_SECURITY_EXCEPTION"; public static final String WG_QUO_NO_LONGER_DEFINED = "WG_QUO_NO_LONGER_DEFINED"; public static final String WG_NEED_DERIVED_OBJECT_TO_IMPLEMENT_NODETEST = @@ -839,9 +838,6 @@ public class XPATHErrorResources_fr extends ListResourceBundle { WG_DONT_DO_ANYTHING_WITH_NS, "Espace de noms {0} inexploitable dans la propri\u00E9t\u00E9 : {1}"}, - { WG_SECURITY_EXCEPTION, - "Exception SecurityException g\u00E9n\u00E9r\u00E9e lors de la tentative d''acc\u00E8s \u00E0 la propri\u00E9t\u00E9 syst\u00E8me XSL : {0}"}, - { WG_QUO_NO_LONGER_DEFINED, "L'ancienne syntaxe quo(...) n'est plus d\u00E9finie dans XPath."}, diff --git a/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/res/XPATHErrorResources_it.java b/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/res/XPATHErrorResources_it.java index a1bb1f43fbb..ad730f9894f 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/res/XPATHErrorResources_it.java +++ b/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/res/XPATHErrorResources_it.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -31,7 +31,7 @@ * Also you need to update the count of messages(MAX_CODE)or * the count of warnings(MAX_WARNING) [ Information purpose only] * @xsl.usage advanced - * @LastModified: May 2022 + * @LastModified: Nov 2024 */ public class XPATHErrorResources_it extends ListResourceBundle { @@ -326,7 +326,6 @@ public class XPATHErrorResources_it extends ListResourceBundle "WG_PROPERTY_NOT_SUPPORTED"; public static final String WG_DONT_DO_ANYTHING_WITH_NS = "WG_DONT_DO_ANYTHING_WITH_NS"; - public static final String WG_SECURITY_EXCEPTION = "WG_SECURITY_EXCEPTION"; public static final String WG_QUO_NO_LONGER_DEFINED = "WG_QUO_NO_LONGER_DEFINED"; public static final String WG_NEED_DERIVED_OBJECT_TO_IMPLEMENT_NODETEST = @@ -839,9 +838,6 @@ public class XPATHErrorResources_it extends ListResourceBundle { WG_DONT_DO_ANYTHING_WITH_NS, "Non effettuare alcuna operazione sullo spazio di nomi {0} nella propriet\u00E0: {1}"}, - { WG_SECURITY_EXCEPTION, - "SecurityException nel tentativo di accedere alla propriet\u00E0 di sistema XSL {0}"}, - { WG_QUO_NO_LONGER_DEFINED, "Sintassi obsoleta: quo(...) non \u00E8 pi\u00F9 definito nell'XPath."}, diff --git a/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/res/XPATHErrorResources_ja.java b/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/res/XPATHErrorResources_ja.java index 7347a22f8e9..1b707cd7820 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/res/XPATHErrorResources_ja.java +++ b/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/res/XPATHErrorResources_ja.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -31,7 +31,7 @@ * Also you need to update the count of messages(MAX_CODE)or * the count of warnings(MAX_WARNING) [ Information purpose only] * @xsl.usage advanced - * @LastModified: Jul 2022 + * @LastModified: Nov 2024 */ public class XPATHErrorResources_ja extends ListResourceBundle { @@ -337,7 +337,6 @@ public class XPATHErrorResources_ja extends ListResourceBundle "WG_PROPERTY_NOT_SUPPORTED"; public static final String WG_DONT_DO_ANYTHING_WITH_NS = "WG_DONT_DO_ANYTHING_WITH_NS"; - public static final String WG_SECURITY_EXCEPTION = "WG_SECURITY_EXCEPTION"; public static final String WG_QUO_NO_LONGER_DEFINED = "WG_QUO_NO_LONGER_DEFINED"; public static final String WG_NEED_DERIVED_OBJECT_TO_IMPLEMENT_NODETEST = @@ -880,9 +879,6 @@ public class XPATHErrorResources_ja extends ListResourceBundle { WG_DONT_DO_ANYTHING_WITH_NS, "\u30D7\u30ED\u30D1\u30C6\u30A3{1}\u5185\u306E\u30CD\u30FC\u30E0\u30B9\u30DA\u30FC\u30B9{0}\u3067\u306F\u73FE\u5728\u4F55\u3082\u5B9F\u884C\u3057\u306A\u3044\u3067\u304F\u3060\u3055\u3044"}, - { WG_SECURITY_EXCEPTION, - "XSL\u30B7\u30B9\u30C6\u30E0\u30FB\u30D7\u30ED\u30D1\u30C6\u30A3{0}\u306B\u30A2\u30AF\u30BB\u30B9\u3057\u3088\u3046\u3068\u3057\u305F\u3068\u304D\u306BSecurityException\u304C\u767A\u751F\u3057\u307E\u3057\u305F"}, - { WG_QUO_NO_LONGER_DEFINED, "\u53E4\u3044\u69CB\u6587: quo(...)\u306FXPath\u3067\u306F\u73FE\u5728\u5B9A\u7FA9\u3055\u308C\u3066\u3044\u307E\u305B\u3093\u3002"}, diff --git a/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/res/XPATHErrorResources_ko.java b/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/res/XPATHErrorResources_ko.java index 2b2f4f811ff..01e0f4062ed 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/res/XPATHErrorResources_ko.java +++ b/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/res/XPATHErrorResources_ko.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -31,7 +31,7 @@ * Also you need to update the count of messages(MAX_CODE)or * the count of warnings(MAX_WARNING) [ Information purpose only] * @xsl.usage advanced - * @LastModified: May 2022 + * @LastModified: Nov 2024 */ public class XPATHErrorResources_ko extends ListResourceBundle { @@ -326,7 +326,6 @@ public class XPATHErrorResources_ko extends ListResourceBundle "WG_PROPERTY_NOT_SUPPORTED"; public static final String WG_DONT_DO_ANYTHING_WITH_NS = "WG_DONT_DO_ANYTHING_WITH_NS"; - public static final String WG_SECURITY_EXCEPTION = "WG_SECURITY_EXCEPTION"; public static final String WG_QUO_NO_LONGER_DEFINED = "WG_QUO_NO_LONGER_DEFINED"; public static final String WG_NEED_DERIVED_OBJECT_TO_IMPLEMENT_NODETEST = @@ -839,9 +838,6 @@ public class XPATHErrorResources_ko extends ListResourceBundle { WG_DONT_DO_ANYTHING_WITH_NS, "\uC18D\uC131\uC758 {0} \uB124\uC784\uC2A4\uD398\uC774\uC2A4\uC5D0 \uB300\uD574 \uD604\uC7AC \uC5B4\uB5A4 \uC791\uC5C5\uB3C4 \uC218\uD589\uD558\uC9C0 \uC54A\uC544\uC57C \uD568: {1}"}, - { WG_SECURITY_EXCEPTION, - "XSL \uC2DC\uC2A4\uD15C \uC18D\uC131\uC5D0 \uC561\uC138\uC2A4\uD558\uB824\uACE0 \uC2DC\uB3C4\uD558\uB294 \uC911 SecurityException \uBC1C\uC0DD: {0}"}, - { WG_QUO_NO_LONGER_DEFINED, "\uC774\uC804 \uAD6C\uBB38: quo(...)\uAC00 XPath\uC5D0 \uB354 \uC774\uC0C1 \uC815\uC758\uB418\uC5B4 \uC788\uC9C0 \uC54A\uC2B5\uB2C8\uB2E4."}, diff --git a/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/res/XPATHErrorResources_pt_BR.java b/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/res/XPATHErrorResources_pt_BR.java index 4a8226142fa..ee9e50cf644 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/res/XPATHErrorResources_pt_BR.java +++ b/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/res/XPATHErrorResources_pt_BR.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -31,7 +31,7 @@ * Also you need to update the count of messages(MAX_CODE)or * the count of warnings(MAX_WARNING) [ Information purpose only] * @xsl.usage advanced - * @LastModified: May 2022 + * @LastModified: Nov 2024 */ public class XPATHErrorResources_pt_BR extends ListResourceBundle { @@ -326,7 +326,6 @@ public class XPATHErrorResources_pt_BR extends ListResourceBundle "WG_PROPERTY_NOT_SUPPORTED"; public static final String WG_DONT_DO_ANYTHING_WITH_NS = "WG_DONT_DO_ANYTHING_WITH_NS"; - public static final String WG_SECURITY_EXCEPTION = "WG_SECURITY_EXCEPTION"; public static final String WG_QUO_NO_LONGER_DEFINED = "WG_QUO_NO_LONGER_DEFINED"; public static final String WG_NEED_DERIVED_OBJECT_TO_IMPLEMENT_NODETEST = @@ -839,9 +838,6 @@ public class XPATHErrorResources_pt_BR extends ListResourceBundle { WG_DONT_DO_ANYTHING_WITH_NS, "Nenhuma a\u00E7\u00E3o a ser tomada com o namespace {0} na propriedade: {1}"}, - { WG_SECURITY_EXCEPTION, - "SecurityException ao tentar acessar a propriedade de sistema XSL: {0}"}, - { WG_QUO_NO_LONGER_DEFINED, "Sintaxe antiga: quo(...) n\u00E3o est\u00E1 mais definido no XPath."}, diff --git a/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/res/XPATHErrorResources_sv.java b/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/res/XPATHErrorResources_sv.java index 61585bda1c3..c0acf167b9d 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/res/XPATHErrorResources_sv.java +++ b/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/res/XPATHErrorResources_sv.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -31,7 +31,7 @@ * Also you need to update the count of messages(MAX_CODE)or * the count of warnings(MAX_WARNING) [ Information purpose only] * @xsl.usage advanced - * @LastModified: May 2022 + * @LastModified: Nov 2024 */ public class XPATHErrorResources_sv extends ListResourceBundle { @@ -326,7 +326,6 @@ public class XPATHErrorResources_sv extends ListResourceBundle "WG_PROPERTY_NOT_SUPPORTED"; public static final String WG_DONT_DO_ANYTHING_WITH_NS = "WG_DONT_DO_ANYTHING_WITH_NS"; - public static final String WG_SECURITY_EXCEPTION = "WG_SECURITY_EXCEPTION"; public static final String WG_QUO_NO_LONGER_DEFINED = "WG_QUO_NO_LONGER_DEFINED"; public static final String WG_NEED_DERIVED_OBJECT_TO_IMPLEMENT_NODETEST = @@ -839,9 +838,6 @@ public class XPATHErrorResources_sv extends ListResourceBundle { WG_DONT_DO_ANYTHING_WITH_NS, "G\u00F6r f\u00F6r n\u00E4rvarande inte n\u00E5gonting med namnrymden {0} i egenskap: {1}"}, - { WG_SECURITY_EXCEPTION, - "SecurityException vid f\u00F6rs\u00F6k att f\u00E5 \u00E5tkomst till XSL-systemegenskap: {0}"}, - { WG_QUO_NO_LONGER_DEFINED, "Gammal syntax: quo(...) definieras inte l\u00E4ngre i XPath."}, diff --git a/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/res/XPATHErrorResources_zh_CN.java b/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/res/XPATHErrorResources_zh_CN.java index 511fb6ad768..dd9e507a8f0 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/res/XPATHErrorResources_zh_CN.java +++ b/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/res/XPATHErrorResources_zh_CN.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -31,7 +31,7 @@ * Also you need to update the count of messages(MAX_CODE)or * the count of warnings(MAX_WARNING) [ Information purpose only] * @xsl.usage advanced - * @LastModified: Jul 2022 + * @LastModified: Nov 2024 */ public class XPATHErrorResources_zh_CN extends ListResourceBundle { @@ -337,7 +337,6 @@ public class XPATHErrorResources_zh_CN extends ListResourceBundle "WG_PROPERTY_NOT_SUPPORTED"; public static final String WG_DONT_DO_ANYTHING_WITH_NS = "WG_DONT_DO_ANYTHING_WITH_NS"; - public static final String WG_SECURITY_EXCEPTION = "WG_SECURITY_EXCEPTION"; public static final String WG_QUO_NO_LONGER_DEFINED = "WG_QUO_NO_LONGER_DEFINED"; public static final String WG_NEED_DERIVED_OBJECT_TO_IMPLEMENT_NODETEST = @@ -880,9 +879,6 @@ public class XPATHErrorResources_zh_CN extends ListResourceBundle { WG_DONT_DO_ANYTHING_WITH_NS, "\u76EE\u524D\u4E0D\u8981\u4F7F\u7528\u5C5E\u6027{1}\u4E2D\u7684\u540D\u79F0\u7A7A\u95F4{0}\u6267\u884C\u4EFB\u4F55\u64CD\u4F5C"}, - { WG_SECURITY_EXCEPTION, - "\u5C1D\u8BD5\u8BBF\u95EE XSL \u7CFB\u7EDF\u5C5E\u6027\u65F6\u51FA\u73B0 SecurityException: {0}"}, - { WG_QUO_NO_LONGER_DEFINED, "\u65E7\u8BED\u6CD5: XPath \u4E2D\u4E0D\u518D\u5B9A\u4E49 quo(...)\u3002"}, diff --git a/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/res/XPATHErrorResources_zh_TW.java b/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/res/XPATHErrorResources_zh_TW.java index d962d6b0c8c..edfb20a0920 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/res/XPATHErrorResources_zh_TW.java +++ b/src/java.xml/share/classes/com/sun/org/apache/xpath/internal/res/XPATHErrorResources_zh_TW.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -31,7 +31,7 @@ * Also you need to update the count of messages(MAX_CODE)or * the count of warnings(MAX_WARNING) [ Information purpose only] * @xsl.usage advanced - * @LastModified: May 2022 + * @LastModified: Nov 2024 */ public class XPATHErrorResources_zh_TW extends ListResourceBundle { @@ -326,7 +326,6 @@ public class XPATHErrorResources_zh_TW extends ListResourceBundle "WG_PROPERTY_NOT_SUPPORTED"; public static final String WG_DONT_DO_ANYTHING_WITH_NS = "WG_DONT_DO_ANYTHING_WITH_NS"; - public static final String WG_SECURITY_EXCEPTION = "WG_SECURITY_EXCEPTION"; public static final String WG_QUO_NO_LONGER_DEFINED = "WG_QUO_NO_LONGER_DEFINED"; public static final String WG_NEED_DERIVED_OBJECT_TO_IMPLEMENT_NODETEST = @@ -839,9 +838,6 @@ public class XPATHErrorResources_zh_TW extends ListResourceBundle { WG_DONT_DO_ANYTHING_WITH_NS, "\u76EE\u524D\u4E0D\u6703\u8655\u7406\u5C6C\u6027\u4E2D\u7684\u547D\u540D\u7A7A\u9593 {0}: {1}"}, - { WG_SECURITY_EXCEPTION, - "\u5617\u8A66\u5B58\u53D6 XSL \u7CFB\u7D71\u5C6C\u6027\u6642\u767C\u751F SecurityException: {0}"}, - { WG_QUO_NO_LONGER_DEFINED, "\u820A\u8A9E\u6CD5: XPath \u4E2D\u4E0D\u518D\u5B9A\u7FA9 quo(...)\u3002"}, diff --git a/src/java.xml/share/classes/com/sun/xml/internal/stream/XMLEntityStorage.java b/src/java.xml/share/classes/com/sun/xml/internal/stream/XMLEntityStorage.java index 3f1fb40f73f..2befe055739 100644 --- a/src/java.xml/share/classes/com/sun/xml/internal/stream/XMLEntityStorage.java +++ b/src/java.xml/share/classes/com/sun/xml/internal/stream/XMLEntityStorage.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -404,12 +404,7 @@ public static String expandSystemId(String systemId) { // which encoding to use. Leave them for now. private static synchronized String getUserDir() { // get the user.dir property - String userDir = ""; - try { - userDir = SecuritySupport.getSystemProperty("user.dir"); - } - catch (SecurityException se) { - } + String userDir = System.getProperty("user.dir"); // return empty string if property value is empty string. if (userDir.length() == 0) diff --git a/src/java.xml/share/classes/com/sun/xml/internal/stream/writers/WriterUtility.java b/src/java.xml/share/classes/com/sun/xml/internal/stream/writers/WriterUtility.java index 47f85159c1c..75b930d0537 100644 --- a/src/java.xml/share/classes/com/sun/xml/internal/stream/writers/WriterUtility.java +++ b/src/java.xml/share/classes/com/sun/xml/internal/stream/writers/WriterUtility.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -240,7 +240,7 @@ public void writeXMLAttributeValue(String value)throws IOException{ private CharsetEncoder getDefaultEncoder(){ try{ - String encoding = SecuritySupport.getSystemProperty("file.encoding"); + String encoding = System.getProperty("file.encoding"); if(encoding != null){ return Charset.forName(encoding).newEncoder(); } diff --git a/src/java.xml/share/classes/com/sun/xml/internal/stream/writers/XMLStreamWriterImpl.java b/src/java.xml/share/classes/com/sun/xml/internal/stream/writers/XMLStreamWriterImpl.java index 3dbe4b24536..05c974b54bf 100644 --- a/src/java.xml/share/classes/com/sun/xml/internal/stream/writers/XMLStreamWriterImpl.java +++ b/src/java.xml/share/classes/com/sun/xml/internal/stream/writers/XMLStreamWriterImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -339,7 +339,7 @@ private void setOutputUsingStream(OutputStream os, String encoding) fEncoder = Charset.forName(encoding).newEncoder(); } } else { - encoding = SecuritySupport.getSystemProperty("file.encoding"); + encoding = System.getProperty("file.encoding"); if (encoding != null && encoding.equalsIgnoreCase("utf-8")) { fWriter = new UTF8OutputStreamWriter(os); } else { diff --git a/src/java.xml/share/classes/javax/xml/catalog/CatalogFeatures.java b/src/java.xml/share/classes/javax/xml/catalog/CatalogFeatures.java index 1c498148933..4376bbe9fdf 100644 --- a/src/java.xml/share/classes/javax/xml/catalog/CatalogFeatures.java +++ b/src/java.xml/share/classes/javax/xml/catalog/CatalogFeatures.java @@ -597,7 +597,7 @@ private void readSystemProperties() { */ private boolean getSystemProperty(Feature cf, String sysPropertyName) { if (cf.hasSystemProperty()) { - String value = SecuritySupport.getSystemProperty(sysPropertyName); + String value = System.getProperty(sysPropertyName); if (value != null && !value.isEmpty()) { setProperty(cf, State.SYSTEMPROPERTY, value); return true; diff --git a/src/java.xml/share/classes/javax/xml/datatype/FactoryFinder.java b/src/java.xml/share/classes/javax/xml/datatype/FactoryFinder.java index 9074ea2e44f..27ad30dec02 100644 --- a/src/java.xml/share/classes/javax/xml/datatype/FactoryFinder.java +++ b/src/java.xml/share/classes/javax/xml/datatype/FactoryFinder.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,8 +25,6 @@ package javax.xml.datatype; -import java.security.AccessController; -import java.security.PrivilegedAction; import java.util.Iterator; import java.util.ServiceConfigurationError; import java.util.ServiceLoader; @@ -51,16 +49,9 @@ class FactoryFinder { // Define system property "jaxp.debug" to get output static { - // Use try/catch block to support applets, which throws - // SecurityException out of this code. - try { - String val = SecuritySupport.getSystemProperty("jaxp.debug"); - // Allow simply setting the prop to turn on debug - debug = val != null && !"false".equals(val); - } - catch (SecurityException se) { - debug = false; - } + String val = System.getProperty("jaxp.debug"); + // Allow simply setting the prop to turn on debug + debug = val != null && !"false".equals(val); } private static void dPrint(Supplier<String> msgGen) { @@ -153,21 +144,12 @@ static <T> T newInstance(Class<T> type, String className, ClassLoader cl, boolea * @param useBSClsLoader True if cl=null actually meant bootstrap classLoader. This parameter * is needed since DocumentBuilderFactory/SAXParserFactory defined null as context classLoader. */ - @SuppressWarnings("removal") static <T> T newInstance(Class<T> type, String className, ClassLoader cl, boolean doFallback, boolean useBSClsLoader) throws DatatypeConfigurationException { assert type != null; - // make sure we have access to restricted packages - if (System.getSecurityManager() != null) { - if (className != null && className.startsWith(DEFAULT_PACKAGE)) { - cl = null; - useBSClsLoader = true; - } - } - try { Class<?> providerClass = getProviderClass(className, cl, doFallback, useBSClsLoader); if (!type.isAssignableFrom(providerClass)) { @@ -209,15 +191,10 @@ static <T> T find(Class<T> type, String fallbackClassName) dPrint(()->"find factoryId =" + factoryId); // Use the system property first - try { - String systemProp = SecuritySupport.getSystemProperty(factoryId); - if (systemProp != null) { - dPrint(()->"found system property, value=" + systemProp); - return newInstance(type, systemProp, null, true); - } - } - catch (SecurityException se) { - if (debug) se.printStackTrace(); + String systemProp = System.getProperty(factoryId); + if (systemProp != null) { + dPrint(()->"found system property, value=" + systemProp); + return newInstance(type, systemProp, null, true); } // try to read from the configuration file @@ -247,22 +224,17 @@ static <T> T find(Class<T> type, String fallbackClassName) * * @return instance of provider class if found or null */ - @SuppressWarnings("removal") private static <T> T findServiceProvider(final Class<T> type) throws DatatypeConfigurationException { try { - return AccessController.doPrivileged(new PrivilegedAction<T>() { - public T run() { - final ServiceLoader<T> serviceLoader = ServiceLoader.load(type); - final Iterator<T> iterator = serviceLoader.iterator(); - if (iterator.hasNext()) { - return iterator.next(); - } else { - return null; - } - } - }); + final ServiceLoader<T> serviceLoader = ServiceLoader.load(type); + final Iterator<T> iterator = serviceLoader.iterator(); + if (iterator.hasNext()) { + return iterator.next(); + } else { + return null; + } } catch(ServiceConfigurationError e) { final DatatypeConfigurationException error = new DatatypeConfigurationException( diff --git a/src/java.xml/share/classes/javax/xml/parsers/FactoryFinder.java b/src/java.xml/share/classes/javax/xml/parsers/FactoryFinder.java index b11f030d4f6..3fa1c220f6c 100644 --- a/src/java.xml/share/classes/javax/xml/parsers/FactoryFinder.java +++ b/src/java.xml/share/classes/javax/xml/parsers/FactoryFinder.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,8 +25,6 @@ package javax.xml.parsers; -import java.security.AccessController; -import java.security.PrivilegedAction; import java.util.Iterator; import java.util.ServiceConfigurationError; import java.util.ServiceLoader; @@ -50,16 +48,9 @@ class FactoryFinder { // Define system property "jaxp.debug" to get output static { - // Use try/catch block to support applets, which throws - // SecurityException out of this code. - try { - String val = SecuritySupport.getSystemProperty("jaxp.debug"); - // Allow simply setting the prop to turn on debug - debug = val != null && !"false".equals(val); - } - catch (SecurityException se) { - debug = false; - } + String val = System.getProperty("jaxp.debug"); + // Allow simply setting the prop to turn on debug + debug = val != null && !"false".equals(val); } private static void dPrint(Supplier<String> msgGen) { @@ -153,19 +144,11 @@ static <T> T newInstance(Class<T> type, String className, ClassLoader cl, * @param useBSClsLoader True if cl=null actually meant bootstrap classLoader. This parameter * is needed since DocumentBuilderFactory/SAXParserFactory defined null as context classLoader. */ - @SuppressWarnings("removal") static <T> T newInstance(Class<T> type, String className, ClassLoader cl, boolean doFallback, boolean useBSClsLoader) throws FactoryConfigurationError { assert type != null; - // make sure we have access to restricted packages - if (System.getSecurityManager() != null) { - if (className != null && className.startsWith(DEFAULT_PACKAGE)) { - cl = null; - useBSClsLoader = true; - } - } try { Class<?> providerClass = getProviderClass(className, cl, doFallback, useBSClsLoader); @@ -207,15 +190,10 @@ static <T> T find(Class<T> type, String fallbackClassName) dPrint(()->"find factoryId =" + factoryId); // Use the system property first - try { - String systemProp = SecuritySupport.getSystemProperty(factoryId); - if (systemProp != null) { - dPrint(()->"found system property, value=" + systemProp); - return newInstance(type, systemProp, null, true); - } - } - catch (SecurityException se) { - if (debug) se.printStackTrace(); + String systemProp = System.getProperty(factoryId); + if (systemProp != null) { + dPrint(()->"found system property, value=" + systemProp); + return newInstance(type, systemProp, null, true); } // try to read from the configuration file @@ -245,20 +223,15 @@ static <T> T find(Class<T> type, String fallbackClassName) * * @return instance of provider class if found or null */ - @SuppressWarnings("removal") private static <T> T findServiceProvider(final Class<T> type) { try { - return AccessController.doPrivileged(new PrivilegedAction<T>() { - public T run() { - final ServiceLoader<T> serviceLoader = ServiceLoader.load(type); - final Iterator<T> iterator = serviceLoader.iterator(); - if (iterator.hasNext()) { - return iterator.next(); - } else { - return null; - } - } - }); + final ServiceLoader<T> serviceLoader = ServiceLoader.load(type); + final Iterator<T> iterator = serviceLoader.iterator(); + if (iterator.hasNext()) { + return iterator.next(); + } else { + return null; + } } catch(ServiceConfigurationError e) { // It is not possible to wrap an error directly in // FactoryConfigurationError - so we need to wrap the diff --git a/src/java.xml/share/classes/javax/xml/stream/FactoryFinder.java b/src/java.xml/share/classes/javax/xml/stream/FactoryFinder.java index d3375a3db62..c389e9edd94 100644 --- a/src/java.xml/share/classes/javax/xml/stream/FactoryFinder.java +++ b/src/java.xml/share/classes/javax/xml/stream/FactoryFinder.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,8 +25,6 @@ package javax.xml.stream; -import java.security.AccessController; -import java.security.PrivilegedAction; import java.util.Iterator; import java.util.ServiceConfigurationError; import java.util.ServiceLoader; @@ -52,16 +50,9 @@ class FactoryFinder { // Define system property "jaxp.debug" to get output static { - // Use try/catch block to support applets, which throws - // SecurityException out of this code. - try { - String val = SecuritySupport.getSystemProperty("jaxp.debug"); - // Allow simply setting the prop to turn on debug - debug = val != null && !"false".equals(val); - } - catch (SecurityException se) { - debug = false; - } + String val = System.getProperty("jaxp.debug"); + // Allow simply setting the prop to turn on debug + debug = val != null && !"false".equals(val); } private static void dPrint(Supplier<String> msgGen) { @@ -154,21 +145,12 @@ static <T> T newInstance(Class<T> type, String className, ClassLoader cl, boolea * @param useBSClsLoader True if cl=null actually meant bootstrap classLoader. This parameter * is needed since DocumentBuilderFactory/SAXParserFactory defined null as context classLoader. */ - @SuppressWarnings("removal") static <T> T newInstance(Class<T> type, String className, ClassLoader cl, boolean doFallback, boolean useBSClsLoader) throws FactoryConfigurationError { assert type != null; - // make sure we have access to restricted packages - if (System.getSecurityManager() != null) { - if (className != null && className.startsWith(DEFAULT_PACKAGE)) { - cl = null; - useBSClsLoader = true; - } - } - try { Class<?> providerClass = getProviderClass(className, cl, doFallback, useBSClsLoader); if (!type.isAssignableFrom(providerClass)) { @@ -235,22 +217,15 @@ static <T> T find(Class<T> type, String factoryId, ClassLoader cl, String fallba dPrint(()->"find factoryId =" + factoryId); // Use the system property first - try { - - final String systemProp; - if (type.getName().equals(factoryId)) { - systemProp = SecuritySupport.getSystemProperty(factoryId); - } else { - systemProp = System.getProperty(factoryId); - } - if (systemProp != null) { - dPrint(()->"found system property, value=" + systemProp); - return newInstance(type, systemProp, cl, true); - } + final String systemProp; + if (type.getName().equals(factoryId)) { + systemProp = System.getProperty(factoryId); + } else { + systemProp = System.getProperty(factoryId); } - catch (SecurityException se) { - throw new FactoryConfigurationError( - "Failed to read factoryId '" + factoryId + "'", se); + if (systemProp != null) { + dPrint(()->"found system property, value=" + systemProp); + return newInstance(type, systemProp, cl, true); } // try to read from the configuration file @@ -287,27 +262,21 @@ static <T> T find(Class<T> type, String factoryId, ClassLoader cl, String fallba * * @return instance of provider class if found or null */ - @SuppressWarnings("removal") private static <T> T findServiceProvider(final Class<T> type, final ClassLoader cl) { try { - return AccessController.doPrivileged(new PrivilegedAction<T>() { - @Override - public T run() { - final ServiceLoader<T> serviceLoader; - if (cl == null) { - //the current thread's context class loader - serviceLoader = ServiceLoader.load(type); - } else { - serviceLoader = ServiceLoader.load(type, cl); - } - final Iterator<T> iterator = serviceLoader.iterator(); - if (iterator.hasNext()) { - return iterator.next(); - } else { - return null; - } - } - }); + final ServiceLoader<T> serviceLoader; + if (cl == null) { + //the current thread's context class loader + serviceLoader = ServiceLoader.load(type); + } else { + serviceLoader = ServiceLoader.load(type, cl); + } + final Iterator<T> iterator = serviceLoader.iterator(); + if (iterator.hasNext()) { + return iterator.next(); + } else { + return null; + } } catch(ServiceConfigurationError e) { // It is not possible to wrap an error directly in // FactoryConfigurationError - so we need to wrap the diff --git a/src/java.xml/share/classes/javax/xml/transform/FactoryFinder.java b/src/java.xml/share/classes/javax/xml/transform/FactoryFinder.java index 3b1944fa8de..ca0731d1878 100644 --- a/src/java.xml/share/classes/javax/xml/transform/FactoryFinder.java +++ b/src/java.xml/share/classes/javax/xml/transform/FactoryFinder.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,8 +25,6 @@ package javax.xml.transform; -import java.security.AccessController; -import java.security.PrivilegedAction; import java.util.Iterator; import java.util.ServiceConfigurationError; import java.util.ServiceLoader; @@ -51,16 +49,9 @@ class FactoryFinder { // Define system property "jaxp.debug" to get output static { - // Use try/catch block to support applets, which throws - // SecurityException out of this code. - try { - String val = SecuritySupport.getSystemProperty("jaxp.debug"); - // Allow simply setting the prop to turn on debug - debug = val != null && !"false".equals(val); - } - catch (SecurityException se) { - debug = false; - } + String val = System.getProperty("jaxp.debug"); + // Allow simply setting the prop to turn on debug + debug = val != null && !"false".equals(val); } private static void dPrint(Supplier<String> msgGen) { @@ -128,10 +119,9 @@ static private Class<?> getProviderClass(String className, ClassLoader cl, * @param doFallback True if the current ClassLoader should be tried as * a fallback if the class is not found using cl * - * @param overrideDefaultParser True to allow overriding the system-default + * @param doFallback True to allow overriding the system-default * parser. */ - @SuppressWarnings("removal") static <T> T newInstance(Class<T> type, String className, ClassLoader cl, boolean doFallback) throws TransformerFactoryConfigurationError @@ -139,13 +129,6 @@ static <T> T newInstance(Class<T> type, String className, ClassLoader cl, assert type != null; boolean useBSClsLoader = false; - // make sure we have access to restricted packages - if (System.getSecurityManager() != null) { - if (className != null && className.startsWith(DEFAULT_PACKAGE)) { - cl = null; - useBSClsLoader = true; - } - } try { Class<?> providerClass = getProviderClass(className, cl, doFallback, useBSClsLoader); @@ -191,15 +174,10 @@ static <T> T find(Class<T> type, String fallbackClassName) dPrint(()->"find factoryId =" + factoryId); // Use the system property first - try { - String systemProp = SecuritySupport.getSystemProperty(factoryId); - if (systemProp != null) { - dPrint(()->"found system property, value=" + systemProp); - return newInstance(type, systemProp, null, true); - } - } - catch (SecurityException se) { - if (debug) se.printStackTrace(); + String systemProp = System.getProperty(factoryId); + if (systemProp != null) { + dPrint(()->"found system property, value=" + systemProp); + return newInstance(type, systemProp, null, true); } // try to read from the configuration file @@ -229,22 +207,17 @@ static <T> T find(Class<T> type, String fallbackClassName) * * @return instance of provider class if found or null */ - @SuppressWarnings("removal") private static <T> T findServiceProvider(final Class<T> type) throws TransformerFactoryConfigurationError { try { - return AccessController.doPrivileged(new PrivilegedAction<T>() { - public T run() { - final ServiceLoader<T> serviceLoader = ServiceLoader.load(type); - final Iterator<T> iterator = serviceLoader.iterator(); - if (iterator.hasNext()) { - return iterator.next(); - } else { - return null; - } - } - }); + final ServiceLoader<T> serviceLoader = ServiceLoader.load(type); + final Iterator<T> iterator = serviceLoader.iterator(); + if (iterator.hasNext()) { + return iterator.next(); + } else { + return null; + } } catch(ServiceConfigurationError e) { // It is not possible to wrap an error directly in // FactoryConfigurationError - so we need to wrap the diff --git a/src/java.xml/share/classes/javax/xml/transform/TransformerException.java b/src/java.xml/share/classes/javax/xml/transform/TransformerException.java index 241c1ae77b5..2e01dc00361 100644 --- a/src/java.xml/share/classes/javax/xml/transform/TransformerException.java +++ b/src/java.xml/share/classes/javax/xml/transform/TransformerException.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -27,13 +27,10 @@ import java.lang.reflect.Method; import java.lang.reflect.InvocationTargetException; -import java.security.AccessControlContext; -import java.security.AccessController; import java.security.CodeSigner; import java.security.CodeSource; import java.security.PermissionCollection; import java.security.Permissions; -import java.security.PrivilegedAction; import java.security.ProtectionDomain; import java.util.Objects; @@ -230,19 +227,11 @@ public String getMessageAndLocation() { * @return A string with location info, or null * if there is no location information. */ - @SuppressWarnings("removal") public String getLocationAsString() { if (locator == null) { return null; } - - if (System.getSecurityManager() == null) { - return getLocationString(); - } else { - return AccessController.doPrivileged((PrivilegedAction<String>) () -> - getLocationString(), - new AccessControlContext(new ProtectionDomain[] {getNonPrivDomain()})); - } + return getLocationString(); } /** diff --git a/src/java.xml/share/classes/javax/xml/validation/SchemaFactoryFinder.java b/src/java.xml/share/classes/javax/xml/validation/SchemaFactoryFinder.java index 7140483ae5a..6b8cf9441e1 100644 --- a/src/java.xml/share/classes/javax/xml/validation/SchemaFactoryFinder.java +++ b/src/java.xml/share/classes/javax/xml/validation/SchemaFactoryFinder.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -27,9 +27,6 @@ import com.sun.org.apache.xerces.internal.jaxp.validation.XMLSchemaFactory; import java.lang.reflect.InvocationTargetException; -import java.security.AccessControlContext; -import java.security.AccessController; -import java.security.PrivilegedAction; import java.util.ServiceConfigurationError; import java.util.ServiceLoader; import java.util.function.Supplier; @@ -49,12 +46,7 @@ class SchemaFactoryFinder { private static final String DEFAULT_PACKAGE = "com.sun.org.apache.xerces.internal"; static { - // Use try/catch block to support applets - try { - debug = SecuritySupport.getSystemProperty("jaxp.debug") != null; - } catch (Exception unused) { - debug = false; - } + debug = System.getProperty("jaxp.debug") != null; } /** @@ -152,7 +144,7 @@ private SchemaFactory _newFactory(String schemaLanguage) { // system property look up try { debugPrintln(()->"Looking up system property '"+propertyName+"'" ); - String r = SecuritySupport.getSystemProperty(propertyName); + String r = System.getProperty(propertyName); if(r!=null) { debugPrintln(()->"The value is '"+r+"'"); sf = createInstance(r); @@ -201,19 +193,10 @@ private SchemaFactory _newFactory(String schemaLanguage) { * @param className Name of class to create. * @return Created class or <code>null</code>. */ - @SuppressWarnings("removal") private Class<?> createClass(String className) { Class<?> clazz; - // make sure we have access to restricted packages - boolean internal = false; - if (System.getSecurityManager() != null) { - if (className != null && className.startsWith(DEFAULT_PACKAGE)) { - internal = true; - } - } - try { - if (classLoader != null && !internal) { + if (classLoader != null) { clazz = Class.forName(className, false, classLoader); } else { clazz = Class.forName(className); @@ -258,8 +241,7 @@ SchemaFactory createInstance(String className) { } schemaFactory = (SchemaFactory) clazz.getConstructor().newInstance(); } catch (ClassCastException | IllegalAccessException | IllegalArgumentException | - InstantiationException | InvocationTargetException | NoSuchMethodException | - SecurityException ex) { + InstantiationException | InvocationTargetException | NoSuchMethodException ex) { debugPrintln(()->"could not instantiate " + clazz.getName()); if (debug) { ex.printStackTrace(); @@ -270,18 +252,6 @@ SchemaFactory createInstance(String className) { return schemaFactory; } - // Call isSchemaLanguageSupported with initial context. - @SuppressWarnings("removal") - private boolean isSchemaLanguageSupportedBy(final SchemaFactory factory, - final String schemaLanguage, - AccessControlContext acc) { - return AccessController.doPrivileged(new PrivilegedAction<Boolean>() { - public Boolean run() { - return factory.isSchemaLanguageSupported(schemaLanguage); - } - }, acc); - } - /** * Finds a service provider subclass of SchemaFactory that supports the * given schema language using the ServiceLoader. @@ -291,26 +261,18 @@ public Boolean run() { * if none is found. * @throws SchemaFactoryConfigurationError if a configuration error is found. */ - @SuppressWarnings("removal") private SchemaFactory findServiceProvider(final String schemaLanguage) { assert schemaLanguage != null; - // store current context. - final AccessControlContext acc = AccessController.getContext(); try { - return AccessController.doPrivileged(new PrivilegedAction<SchemaFactory>() { - public SchemaFactory run() { - final ServiceLoader<SchemaFactory> loader = - ServiceLoader.load(SERVICE_CLASS); - for (SchemaFactory factory : loader) { - // restore initial context to call - // factory.isSchemaLanguageSupported - if (isSchemaLanguageSupportedBy(factory, schemaLanguage, acc)) { - return factory; - } - } - return null; // no factory found. + final ServiceLoader<SchemaFactory> loader = + ServiceLoader.load(SERVICE_CLASS); + for (SchemaFactory factory : loader) { + // factory.isSchemaLanguageSupported + if (factory.isSchemaLanguageSupported(schemaLanguage)) { + return factory; } - }); + } + return null; // no factory found. } catch (ServiceConfigurationError error) { throw new SchemaFactoryConfigurationError( "Provider for " + SERVICE_CLASS + " cannot be created", error); diff --git a/src/java.xml/share/classes/javax/xml/xpath/XPathFactoryFinder.java b/src/java.xml/share/classes/javax/xml/xpath/XPathFactoryFinder.java index c6cdb6d4098..7726adac3fb 100644 --- a/src/java.xml/share/classes/javax/xml/xpath/XPathFactoryFinder.java +++ b/src/java.xml/share/classes/javax/xml/xpath/XPathFactoryFinder.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2004, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -27,9 +27,6 @@ import com.sun.org.apache.xpath.internal.jaxp.XPathFactoryImpl; import java.lang.reflect.InvocationTargetException; -import java.security.AccessControlContext; -import java.security.AccessController; -import java.security.PrivilegedAction; import java.util.Properties; import java.util.ServiceConfigurationError; import java.util.ServiceLoader; @@ -48,12 +45,7 @@ class XPathFactoryFinder { /** debug support code. */ private static boolean debug = false; static { - // Use try/catch block to support applets - try { - debug = SecuritySupport.getSystemProperty("jaxp.debug") != null; - } catch (Exception unused) { - debug = false; - } + debug = System.getProperty("jaxp.debug") != null; } /** @@ -157,7 +149,7 @@ private XPathFactory _newFactory(String uri) throws XPathFactoryConfigurationExc // system property look up try { debugPrintln(()->"Looking up system property '"+propertyName+"'" ); - String r = SecuritySupport.getSystemProperty(propertyName); + String r = System.getProperty(propertyName); if(r!=null) { debugPrintln(()->"The value is '"+r+"'"); xpathFactory = createInstance(r); @@ -208,20 +200,12 @@ private XPathFactory _newFactory(String uri) throws XPathFactoryConfigurationExc * @param className Name of class to create. * @return Created class or <code>null</code>. */ - @SuppressWarnings("removal") private Class<?> createClass(String className) { Class<?> clazz; - // make sure we have access to restricted packages - boolean internal = false; - if (System.getSecurityManager() != null) { - if (className != null && className.startsWith(DEFAULT_PACKAGE)) { - internal = true; - } - } // use appropriate ClassLoader try { - if (classLoader != null && !internal) { + if (classLoader != null) { clazz = Class.forName(className, false, classLoader); } else { clazz = Class.forName(className); @@ -264,8 +248,7 @@ XPathFactory createInstance(String className) try { xPathFactory = (XPathFactory) clazz.getConstructor().newInstance(); } catch (ClassCastException | IllegalAccessException | IllegalArgumentException | - InstantiationException | InvocationTargetException | NoSuchMethodException | - SecurityException ex) { + InstantiationException | InvocationTargetException | NoSuchMethodException ex) { debugPrintln(()->"could not instantiate " + clazz.getName()); if (debug) { ex.printStackTrace(); @@ -276,18 +259,6 @@ XPathFactory createInstance(String className) return xPathFactory; } - // Call isObjectModelSupportedBy with initial context. - @SuppressWarnings("removal") - private boolean isObjectModelSupportedBy(final XPathFactory factory, - final String objectModel, - AccessControlContext acc) { - return AccessController.doPrivileged(new PrivilegedAction<Boolean>() { - public Boolean run() { - return factory.isObjectModelSupported(objectModel); - } - }, acc); - } - /** * Finds a service provider subclass of XPathFactory that supports the * given object model using the ServiceLoader. @@ -297,28 +268,20 @@ public Boolean run() { * if none is found. * @throws XPathFactoryConfigurationException if a configuration error is found. */ - @SuppressWarnings("removal") private XPathFactory findServiceProvider(final String objectModel) throws XPathFactoryConfigurationException { assert objectModel != null; - // store current context. - final AccessControlContext acc = AccessController.getContext(); try { - return AccessController.doPrivileged(new PrivilegedAction<XPathFactory>() { - public XPathFactory run() { - final ServiceLoader<XPathFactory> loader = - ServiceLoader.load(SERVICE_CLASS); - for (XPathFactory factory : loader) { - // restore initial context to call - // factory.isObjectModelSupportedBy - if (isObjectModelSupportedBy(factory, objectModel, acc)) { - return factory; - } - } - return null; // no factory found. + final ServiceLoader<XPathFactory> loader = + ServiceLoader.load(SERVICE_CLASS); + for (XPathFactory factory : loader) { + // factory.isObjectModelSupportedBy + if (factory.isObjectModelSupported(objectModel)) { + return factory; } - }); + } + return null; // no factory found. } catch (ServiceConfigurationError error) { throw new XPathFactoryConfigurationException(error); } diff --git a/src/java.xml/share/classes/jdk/xml/internal/JdkXmlFeatures.java b/src/java.xml/share/classes/jdk/xml/internal/JdkXmlFeatures.java index bfb43f47d0e..b3b42588911 100644 --- a/src/java.xml/share/classes/jdk/xml/internal/JdkXmlFeatures.java +++ b/src/java.xml/share/classes/jdk/xml/internal/JdkXmlFeatures.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -401,7 +401,7 @@ private void readSystemProperties() { */ private boolean getSystemProperty(XmlFeature feature, String sysPropertyName) { try { - String value = SecuritySupport.getSystemProperty(sysPropertyName); + String value = System.getProperty(sysPropertyName); if (value != null && !value.isEmpty()) { setFeature(feature, State.SYSTEMPROPERTY, Boolean.parseBoolean(value)); return true; diff --git a/src/java.xml/share/classes/jdk/xml/internal/JdkXmlUtils.java b/src/java.xml/share/classes/jdk/xml/internal/JdkXmlUtils.java index 7ee98622317..47c68173d84 100644 --- a/src/java.xml/share/classes/jdk/xml/internal/JdkXmlUtils.java +++ b/src/java.xml/share/classes/jdk/xml/internal/JdkXmlUtils.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -51,8 +51,8 @@ * Constants for use across JAXP processors. */ public class JdkXmlUtils { - public static final boolean IS_WINDOWS = SecuritySupport.getSystemProperty("os.name").contains("Windows"); - public static final String JAVA_HOME = SecuritySupport.getSystemProperty("java.home"); + public static final boolean IS_WINDOWS = System.getProperty("os.name").contains("Windows"); + public static final String JAVA_HOME = System.getProperty("java.home"); private static final String DOM_FACTORY_ID = "javax.xml.parsers.DocumentBuilderFactory"; private static final String SAX_FACTORY_ID = "javax.xml.parsers.SAXParserFactory"; @@ -298,7 +298,7 @@ public static XMLReader getXMLReader(XMLSecurityManager sm, boolean useCatalog, CatalogFeatures catalogFeatures) { SAXParserFactory saxFactory; XMLReader reader = null; - String spSAXDriver = SecuritySupport.getSystemProperty(SAX_DRIVER); + String spSAXDriver = System.getProperty(SAX_DRIVER); if (spSAXDriver != null) { reader = getXMLReaderWXMLReaderFactory(); } else if (overrideDefaultParser) { @@ -401,12 +401,11 @@ public static Document getDOMDocument() { * * @return a DocumentBuilderFactory instance. */ - @SuppressWarnings("removal") public static DocumentBuilderFactory getDOMFactory(boolean overrideDefaultParser) { boolean override = overrideDefaultParser; String spDOMFactory = SecuritySupport.getJAXPSystemProperty(DOM_FACTORY_ID); - if (spDOMFactory != null && System.getSecurityManager() == null) { + if (spDOMFactory != null) { override = true; } DocumentBuilderFactory dbf @@ -428,11 +427,10 @@ public static DocumentBuilderFactory getDOMFactory(boolean overrideDefaultParser * * @return a SAXParserFactory instance. */ - @SuppressWarnings("removal") public static SAXParserFactory getSAXFactory(boolean overrideDefaultParser) { boolean override = overrideDefaultParser; String spSAXFactory = SecuritySupport.getJAXPSystemProperty(SAX_FACTORY_ID); - if (spSAXFactory != null && System.getSecurityManager() == null) { + if (spSAXFactory != null) { override = true; } diff --git a/src/java.xml/share/classes/jdk/xml/internal/SecuritySupport.java b/src/java.xml/share/classes/jdk/xml/internal/SecuritySupport.java index 071676703e1..dee62f58950 100644 --- a/src/java.xml/share/classes/jdk/xml/internal/SecuritySupport.java +++ b/src/java.xml/share/classes/jdk/xml/internal/SecuritySupport.java @@ -32,11 +32,7 @@ import java.net.URL; import java.net.URLConnection; import java.nio.file.Paths; -import java.security.AccessController; import java.security.CodeSource; -import java.security.PrivilegedAction; -import java.security.PrivilegedActionException; -import java.security.PrivilegedExceptionAction; import java.text.MessageFormat; import java.util.Locale; import java.util.MissingResourceException; @@ -77,56 +73,6 @@ public static String getErrorMessage(Locale locale, String bundle, String key, return msg; } - /** - * Reads a system property with privilege - * - * @param propName the name of the property - * @return the value of the property - */ - @SuppressWarnings("removal") - public static String getSystemProperty(final String propName) { - return - AccessController.doPrivileged( - (PrivilegedAction<String>) () -> System.getProperty(propName)); - } - - /** - * Reads a system property with privilege - * - * @param propName the name of the property - * @return the value of the property - */ - public static String getSystemProperty(final String propName, String defValue) { - String value = getSystemProperty(propName); - if (value == null) { - return defValue; - } - return value; - } - - /** - * Reads a system property with specified type. - * - * @param <T> the type of the property value - * @param type the type of the property value - * @param propName the name of the property - * @param defValue the default value - * @return the value of the property, or the default value if no system - * property is found - */ - public static <T> T getSystemProperty(Class<T> type, String propName, String defValue) { - String value = getSystemProperty(propName); - if (value == null) { - value = defValue; - } - if (Integer.class == type) { - return type.cast(Integer.parseInt(value)); - } else if (Boolean.class == type) { - return type.cast(Boolean.parseBoolean(value)); - } - return type.cast(value); - } - /** * Reads JAXP system property in this order: system property, * $java.home/conf/jaxp.properties if the system property is not specified @@ -159,7 +105,7 @@ public static <T> T getJAXPSystemProperty(Class<T> type, String propName, String * @return the value of the property */ public static String getJAXPSystemProperty(String propName) { - String value = getSystemProperty(propName); + String value = System.getProperty(propName); if (value == null) { value = readConfig(propName); } @@ -199,21 +145,21 @@ public static String readConfig(String propName, boolean stax) { synchronized (cacheProps) { if (firstTime) { boolean found = loadProperties( - Paths.get(SecuritySupport.getSystemProperty("java.home"), + Paths.get(System.getProperty("java.home"), "conf", "jaxp.properties") .toAbsolutePath().normalize().toString()); // attempts to find stax.properties only if jaxp.properties is not available if (stax && !found) { found = loadProperties( - Paths.get(SecuritySupport.getSystemProperty("java.home"), + Paths.get(System.getProperty("java.home"), "conf", "stax.properties") .toAbsolutePath().normalize().toString() ); } // load the custom configure on top of the default if any - String configFile = SecuritySupport.getSystemProperty(JdkConstants.CONFIG_FILE_PROPNAME); + String configFile = System.getProperty(JdkConstants.CONFIG_FILE_PROPNAME); if (configFile != null) { loadProperties(configFile); } @@ -249,10 +195,8 @@ private static boolean loadProperties(String file) { * @param f the file to be tested * @return true if it is a directory, false otherwise */ - @SuppressWarnings("removal") public static boolean isDirectory(final File f) { - return (AccessController.doPrivileged((PrivilegedAction<Boolean>) () - -> f.isDirectory())); + return f.isDirectory(); } /** @@ -261,10 +205,8 @@ public static boolean isDirectory(final File f) { * @param f the file to be tested * @return true if the file exists, false otherwise */ - @SuppressWarnings("removal") public static boolean isFileExists(final File f) { - return (AccessController.doPrivileged((PrivilegedAction<Boolean>) () - -> f.exists())); + return f.exists(); } /** @@ -273,10 +215,8 @@ public static boolean isFileExists(final File f) { * @param f the file to be tested * @return true if the input is file, false otherwise */ - @SuppressWarnings("removal") public static boolean isFile(final File f) { - return (AccessController.doPrivileged((PrivilegedAction<Boolean>) () - -> f.isFile())); + return f.isFile(); } /** @@ -285,15 +225,9 @@ public static boolean isFile(final File f) { * @return the FileInputStream * @throws FileNotFoundException if the file is not found */ - @SuppressWarnings("removal") public static FileInputStream getFileInputStream(final File file) throws FileNotFoundException { - try { - return AccessController.doPrivileged((PrivilegedExceptionAction<FileInputStream>) () - -> new FileInputStream(file)); - } catch (PrivilegedActionException e) { - throw (FileNotFoundException) e.getException(); - } + return new FileInputStream(file); } /** @@ -302,15 +236,9 @@ public static FileInputStream getFileInputStream(final File file) * @return the InputStream * @throws IOException if an I/O error occurs while creating the input stream */ - @SuppressWarnings("removal") public static InputStream getInputStream(final URLConnection uc) throws IOException { - try { - return AccessController.doPrivileged((PrivilegedExceptionAction<InputStream>) () - -> uc.getInputStream()); - } catch (PrivilegedActionException e) { - throw (IOException) e.getException(); - } + return uc.getInputStream(); } /** @@ -318,10 +246,8 @@ public static InputStream getInputStream(final URLConnection uc) * @param name the resource name * @return the resource stream */ - @SuppressWarnings("removal") public static InputStream getResourceAsStream(final String name) { - return AccessController.doPrivileged((PrivilegedAction<InputStream>) () -> - SecuritySupport.class.getResourceAsStream("/"+name)); + return SecuritySupport.class.getResourceAsStream("/"+name); } /** @@ -329,10 +255,8 @@ public static InputStream getResourceAsStream(final String name) { * @param name the resource name * @return the resource */ - @SuppressWarnings("removal") public static URL getResource(final String name) { - return AccessController.doPrivileged((PrivilegedAction<URL>) () -> - SecuritySupport.class.getResource(name)); + return SecuritySupport.class.getResource(name); } /** @@ -350,20 +274,17 @@ public static ResourceBundle getResourceBundle(String bundle) { * @param locale the locale for which a resource bundle is desired * @return a resource bundle for the given base name and locale */ - @SuppressWarnings("removal") public static ResourceBundle getResourceBundle(final String bundle, final Locale locale) { - return AccessController.doPrivileged((PrivilegedAction<ResourceBundle>) () -> { + try { + return ResourceBundle.getBundle(bundle, locale); + } catch (MissingResourceException e) { try { - return ResourceBundle.getBundle(bundle, locale); - } catch (MissingResourceException e) { - try { - return ResourceBundle.getBundle(bundle, Locale.US); - } catch (MissingResourceException e2) { - throw new MissingResourceException( - "Could not load any resource bundle by " + bundle, bundle, ""); - } + return ResourceBundle.getBundle(bundle, Locale.US); + } catch (MissingResourceException e2) { + throw new MissingResourceException( + "Could not load any resource bundle by " + bundle, bundle, ""); } - }); + } } /** @@ -371,19 +292,8 @@ public static ResourceBundle getResourceBundle(final String bundle, final Locale * @param f the specified file * @return true if the file exists, false otherwise */ - @SuppressWarnings("removal") public static boolean doesFileExist(final File f) { - return (AccessController.doPrivileged((PrivilegedAction<Boolean>) () -> f.exists())); - } - - /** - * Checks the LastModified attribute of a file. - * @param f the specified file - * @return the LastModified attribute - */ - @SuppressWarnings("removal") - static long getLastModified(final File f) { - return (AccessController.doPrivileged((PrivilegedAction<Long>) () -> f.lastModified())); + return f.exists(); } /** @@ -465,57 +375,35 @@ private static boolean isProtocolAllowed(String protocol, String allowedProtocol return false; } - @SuppressWarnings("removal") public static ClassLoader getContextClassLoader() { - return AccessController.doPrivileged((PrivilegedAction<ClassLoader>) () -> { - ClassLoader cl = Thread.currentThread().getContextClassLoader(); - if (cl == null) - cl = ClassLoader.getSystemClassLoader(); - return cl; - }); + ClassLoader cl = Thread.currentThread().getContextClassLoader(); + if (cl == null) + cl = ClassLoader.getSystemClassLoader(); + return cl; } - - @SuppressWarnings("removal") public static ClassLoader getSystemClassLoader() { - return AccessController.doPrivileged((PrivilegedAction<ClassLoader>) () -> { - ClassLoader cl = null; - try { - cl = ClassLoader.getSystemClassLoader(); - } catch (SecurityException ex) { - } - return cl; - }); + return ClassLoader.getSystemClassLoader(); } - @SuppressWarnings("removal") public static ClassLoader getParentClassLoader(final ClassLoader cl) { - return AccessController.doPrivileged((PrivilegedAction<ClassLoader>) () -> { - ClassLoader parent = null; - try { - parent = cl.getParent(); - } catch (SecurityException ex) { - } + ClassLoader parent = cl.getParent(); - // eliminate loops in case of the boot - // ClassLoader returning itself as a parent - return (parent == cl) ? null : parent; - }); + // eliminate loops in case of the boot + // ClassLoader returning itself as a parent + return (parent == cl) ? null : parent; } // Used for debugging purposes - @SuppressWarnings("removal") public static String getClassSource(Class<?> cls) { - return AccessController.doPrivileged((PrivilegedAction<String>) () -> { - CodeSource cs = cls.getProtectionDomain().getCodeSource(); - if (cs != null) { - URL loc = cs.getLocation(); - return loc != null ? loc.toString() : "(no location)"; - } else { - return "(no code source)"; - } - }); + CodeSource cs = cls.getProtectionDomain().getCodeSource(); + if (cs != null) { + URL loc = cs.getLocation(); + return loc != null ? loc.toString() : "(no location)"; + } else { + return "(no code source)"; + } } // ---------------- For SAX ---------------------- @@ -523,31 +411,24 @@ public static String getClassSource(Class<?> cls) { * Returns the current thread's context class loader, or the system class loader * if the context class loader is null. * @return the current thread's context class loader, or the system class loader - * @throws SecurityException */ - @SuppressWarnings("removal") - public static ClassLoader getClassLoader() throws SecurityException{ - return AccessController.doPrivileged((PrivilegedAction<ClassLoader>)() -> { - ClassLoader cl = Thread.currentThread().getContextClassLoader(); - if (cl == null) { - cl = ClassLoader.getSystemClassLoader(); - } + public static ClassLoader getClassLoader() { + ClassLoader cl = Thread.currentThread().getContextClassLoader(); + if (cl == null) { + cl = ClassLoader.getSystemClassLoader(); + } - return cl; - }); + return cl; } - @SuppressWarnings("removal") public static InputStream getResourceAsStream(final ClassLoader cl, final String name) { - return AccessController.doPrivileged((PrivilegedAction<InputStream>) () -> { - InputStream ris; - if (cl == null) { - ris = SecuritySupport.class.getResourceAsStream(name); - } else { - ris = cl.getResourceAsStream(name); - } - return ris; - }); + InputStream ris; + if (cl == null) { + ris = SecuritySupport.class.getResourceAsStream(name); + } else { + ris = cl.getResourceAsStream(name); + } + return ris; } } diff --git a/src/java.xml/share/classes/jdk/xml/internal/Utils.java b/src/java.xml/share/classes/jdk/xml/internal/Utils.java index e60bc8f060d..f55ab95a58f 100644 --- a/src/java.xml/share/classes/jdk/xml/internal/Utils.java +++ b/src/java.xml/share/classes/jdk/xml/internal/Utils.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -41,14 +41,9 @@ public class Utils { * and processors */ static { - try { - String val = SecuritySupport.getSystemProperty("jaxp.debug"); - // Allow simply setting the prop to turn on debug - debug = val != null && !"false".equals(val); - } - catch (SecurityException se) { - debug = false; - } + String val = System.getProperty("jaxp.debug"); + // Allow simply setting the prop to turn on debug + debug = val != null && !"false".equals(val); } // print out debug information if jaxp.debug is enabled diff --git a/src/java.xml/share/classes/jdk/xml/internal/XMLSecurityManager.java b/src/java.xml/share/classes/jdk/xml/internal/XMLSecurityManager.java index d343b99cf14..cace5492d69 100644 --- a/src/java.xml/share/classes/jdk/xml/internal/XMLSecurityManager.java +++ b/src/java.xml/share/classes/jdk/xml/internal/XMLSecurityManager.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -716,7 +716,7 @@ private boolean getSystemProperty(Limit limit, String sysPropertyName) { if (sysPropertyName == null) return false; try { - String value = SecuritySupport.getSystemProperty(sysPropertyName); + String value = System.getProperty(sysPropertyName); if (value != null && !value.equals("")) { setLimit(limit, State.SYSTEMPROPERTY, value); return true; diff --git a/src/java.xml/share/classes/org/w3c/dom/bootstrap/DOMImplementationRegistry.java b/src/java.xml/share/classes/org/w3c/dom/bootstrap/DOMImplementationRegistry.java index 0be2e912246..683d4b383d5 100644 --- a/src/java.xml/share/classes/org/w3c/dom/bootstrap/DOMImplementationRegistry.java +++ b/src/java.xml/share/classes/org/w3c/dom/bootstrap/DOMImplementationRegistry.java @@ -46,8 +46,6 @@ import java.io.InputStream; import java.io.InputStreamReader; import java.lang.reflect.InvocationTargetException; -import java.security.AccessController; -import java.security.PrivilegedAction; import java.util.ArrayList; import java.util.List; import java.util.StringTokenizer; @@ -143,7 +141,6 @@ private DOMImplementationRegistry(final List<DOMImplementationSource> srcs) { * If any specified class does not implement * <code>DOMImplementationSource</code> */ - @SuppressWarnings("removal") public static DOMImplementationRegistry newInstance() throws ClassNotFoundException, @@ -173,15 +170,8 @@ public static DOMImplementationRegistry newInstance() StringTokenizer st = new StringTokenizer(p); while (st.hasMoreTokens()) { String sourceName = st.nextToken(); - // make sure we have access to restricted packages - boolean internal = false; - if (System.getSecurityManager() != null) { - if (sourceName != null && sourceName.startsWith(DEFAULT_PACKAGE)) { - internal = true; - } - } - Class<?> sourceClass = null; - if (classLoader != null && !internal) { + Class<?> sourceClass; + if (classLoader != null) { sourceClass = classLoader.loadClass(sourceName); } else { sourceClass = Class.forName(sourceName); @@ -341,63 +331,32 @@ private static String getServiceValue(final ClassLoader classLoader) { * * @return The Context Classloader */ - @SuppressWarnings("removal") private static ClassLoader getContextClassLoader() { - return AccessController.doPrivileged(new PrivilegedAction<ClassLoader>() { - @Override - public ClassLoader run() { - ClassLoader classLoader = null; - try { - classLoader = - Thread.currentThread().getContextClassLoader(); - } catch (SecurityException ex) { - } - return classLoader; - } - }); + return Thread.currentThread().getContextClassLoader(); } /** - * This method returns the system property indicated by the specified name - * after checking access control privileges. + * This method returns the system property indicated by the specified name. * * @param name the name of the system property * @return the system property */ - @SuppressWarnings("removal") private static String getSystemProperty(final String name) { - return AccessController.doPrivileged(new PrivilegedAction<String>() { - @Override - public String run() { - return System.getProperty(name); - } - }); + return System.getProperty(name); } /** - * This method returns an Inputstream for the reading resource - * META_INF/services/org.w3c.dom.DOMImplementationSourceList after checking - * access control privileges. + * This method returns an InputStream for the reading resource + * META_INF/services/org.w3c.dom.DOMImplementationSourceList. * * @param classLoader classLoader * @param name the resource - * @return an Inputstream for the resource specified + * @return an InputStream for the resource specified */ - @SuppressWarnings("removal") private static InputStream getResourceAsStream(final ClassLoader classLoader, final String name) { - return AccessController.doPrivileged(new PrivilegedAction<InputStream>() { - @Override - public InputStream run() { - InputStream ris; - if (classLoader == null) { - ris = - ClassLoader.getSystemResourceAsStream(name); - } else { - ris = classLoader.getResourceAsStream(name); - } - return ris; - } - }); + return (classLoader == null) + ? ClassLoader.getSystemResourceAsStream(name) + : classLoader.getResourceAsStream(name); } } diff --git a/src/java.xml/share/classes/org/xml/sax/helpers/NewInstance.java b/src/java.xml/share/classes/org/xml/sax/helpers/NewInstance.java index 03e7f7e8e9f..9abece46e68 100644 --- a/src/java.xml/share/classes/org/xml/sax/helpers/NewInstance.java +++ b/src/java.xml/share/classes/org/xml/sax/helpers/NewInstance.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -51,7 +51,6 @@ class NewInstance { * * Package private so this code is not exposed at the API level. */ - @SuppressWarnings("removal") static <T> T newInstance (Class<T> type, ClassLoader loader, String clsName) throws ClassNotFoundException, IllegalAccessException, InstantiationException @@ -65,15 +64,8 @@ static <T> T newInstance (Class<T> type, ClassLoader loader, String clsName) } // make sure we have access to restricted packages - boolean internal = false; - if (System.getSecurityManager() != null) { - if (className != null && className.startsWith(DEFAULT_PACKAGE)) { - internal = true; - } - } - Class<?> driverClass; - if (classLoader == null || internal) { + if (classLoader == null) { driverClass = Class.forName(className); } else { driverClass = classLoader.loadClass(className); @@ -81,7 +73,7 @@ static <T> T newInstance (Class<T> type, ClassLoader loader, String clsName) try { return type.cast(driverClass.getConstructor().newInstance()); - } catch (NoSuchMethodException | SecurityException | InvocationTargetException ex) { + } catch (NoSuchMethodException | InvocationTargetException ex) { throw new InstantiationException(ex.getMessage()); } } diff --git a/src/java.xml/share/classes/org/xml/sax/helpers/ParserAdapter.java b/src/java.xml/share/classes/org/xml/sax/helpers/ParserAdapter.java index 072b81f1671..b67200bcabe 100644 --- a/src/java.xml/share/classes/org/xml/sax/helpers/ParserAdapter.java +++ b/src/java.xml/share/classes/org/xml/sax/helpers/ParserAdapter.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -90,7 +90,7 @@ public ParserAdapter () { super(); - String driver = SecuritySupport.getSystemProperty("org.xml.sax.parser"); + String driver = System.getProperty("org.xml.sax.parser"); try { setup(ParserFactory.makeParser()); diff --git a/src/java.xml/share/classes/org/xml/sax/helpers/ParserFactory.java b/src/java.xml/share/classes/org/xml/sax/helpers/ParserFactory.java index d4dfb6ca6ce..789237b6acf 100644 --- a/src/java.xml/share/classes/org/xml/sax/helpers/ParserFactory.java +++ b/src/java.xml/share/classes/org/xml/sax/helpers/ParserFactory.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -93,7 +93,7 @@ public static org.xml.sax.Parser makeParser () NullPointerException, ClassCastException { - String className = SecuritySupport.getSystemProperty("org.xml.sax.parser"); + String className = System.getProperty("org.xml.sax.parser"); if (className == null) { throw new NullPointerException("No value for sax.parser property"); } else { diff --git a/src/java.xml/share/classes/org/xml/sax/helpers/XMLReaderFactory.java b/src/java.xml/share/classes/org/xml/sax/helpers/XMLReaderFactory.java index a3f3faea8f1..00fd01ab4e7 100644 --- a/src/java.xml/share/classes/org/xml/sax/helpers/XMLReaderFactory.java +++ b/src/java.xml/share/classes/org/xml/sax/helpers/XMLReaderFactory.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -29,8 +29,6 @@ import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; -import java.security.AccessController; -import java.security.PrivilegedAction; import java.util.Iterator; import java.util.Objects; import java.util.ServiceConfigurationError; @@ -129,7 +127,7 @@ public static XMLReader createXMLReader () // 1. try the JVM-instance-wide system property try { - className = SecuritySupport.getSystemProperty(property); + className = System.getProperty(property); } catch (RuntimeException e) { /* continue searching */ } @@ -236,21 +234,11 @@ private static String jarLookup(final ClassLoader loader) { * * @return instance of provider class if found or null */ - @SuppressWarnings("removal") private static <T> T findServiceProvider(final Class<T> type, final ClassLoader loader) throws SAXException { ClassLoader cl = Objects.requireNonNull(loader); try { - return AccessController.doPrivileged((PrivilegedAction<T>) () -> { - final ServiceLoader<T> serviceLoader; - serviceLoader = ServiceLoader.load(type, cl); - final Iterator<T> iterator = serviceLoader.iterator(); - if (iterator.hasNext()) { - return iterator.next(); - } else { - return null; - } - }); + return ServiceLoader.load(type, cl).findFirst().orElse(null); } catch(ServiceConfigurationError e) { final RuntimeException x = new RuntimeException( "Provider for " + type + " cannot be created", e); From f1b5a6e66e483ee58944fb9064e310f49975e502 Mon Sep 17 00:00:00 2001 From: Roger Riggs <rriggs@openjdk.org> Date: Tue, 26 Nov 2024 17:12:17 +0000 Subject: [PATCH 253/311] 8344565: SM cleanup in jdk/internal and java/lang package private classes Reviewed-by: alanb, mchung --- .../classes/java/lang/CharacterName.java | 12 ++------ .../classes/java/lang/ref/Finalizer.java | 30 +++++++------------ .../jdk/internal/icu/impl/ICUBinary.java | 10 ++----- .../jdk/internal/misc/ExtendedMapMode.java | 9 ++---- 4 files changed, 18 insertions(+), 43 deletions(-) diff --git a/src/java.base/share/classes/java/lang/CharacterName.java b/src/java.base/share/classes/java/lang/CharacterName.java index 1a586d4e580..0b67f6df83a 100644 --- a/src/java.base/share/classes/java/lang/CharacterName.java +++ b/src/java.base/share/classes/java/lang/CharacterName.java @@ -28,12 +28,9 @@ import jdk.internal.util.ArraysSupport; import java.io.DataInputStream; -import java.io.InputStream; import java.lang.ref.SoftReference; import java.util.Arrays; import java.util.zip.InflaterInputStream; -import java.security.AccessController; -import java.security.PrivilegedAction; class CharacterName { @@ -49,12 +46,9 @@ class CharacterName { private final int[] hsIndices; // chain heads, hash indices into "cps" private CharacterName() { - try (@SuppressWarnings("removal") DataInputStream dis = new DataInputStream(new InflaterInputStream( - AccessController.doPrivileged(new PrivilegedAction<>() { - public InputStream run() { - return getClass().getResourceAsStream("uniName.dat"); - } - })))) { + try (DataInputStream dis = new DataInputStream( + new InflaterInputStream(CharacterName.class + .getResourceAsStream("uniName.dat")))) { int total = dis.readInt(); int bkNum = dis.readInt(); diff --git a/src/java.base/share/classes/java/lang/ref/Finalizer.java b/src/java.base/share/classes/java/lang/ref/Finalizer.java index d0c04d7345d..a36a1f73c89 100644 --- a/src/java.base/share/classes/java/lang/ref/Finalizer.java +++ b/src/java.base/share/classes/java/lang/ref/Finalizer.java @@ -25,8 +25,6 @@ package java.lang.ref; -import java.security.PrivilegedAction; -import java.security.AccessController; import jdk.internal.access.JavaLangAccess; import jdk.internal.access.SharedSecrets; import jdk.internal.misc.VM; @@ -116,24 +114,18 @@ private void runFinalizer(JavaLangAccess jla) { * The advantage of creating a fresh thread, however, is that it insulates * invokers of that method from a stalled or deadlocked finalizer thread. */ - @SuppressWarnings("removal") private static void forkSecondaryFinalizer(final Runnable proc) { - AccessController.doPrivileged( - new PrivilegedAction<>() { - public Void run() { - ThreadGroup tg = Thread.currentThread().getThreadGroup(); - for (ThreadGroup tgn = tg; - tgn != null; - tg = tgn, tgn = tg.getParent()); - Thread sft = new Thread(tg, proc, "Secondary finalizer", 0, false); - sft.start(); - try { - sft.join(); - } catch (InterruptedException x) { - Thread.currentThread().interrupt(); - } - return null; - }}); + ThreadGroup tg = Thread.currentThread().getThreadGroup(); + for (ThreadGroup tgn = tg; + tgn != null; + tg = tgn, tgn = tg.getParent()); + Thread sft = new Thread(tg, proc, "Secondary finalizer", 0, false); + sft.start(); + try { + sft.join(); + } catch (InterruptedException x) { + Thread.currentThread().interrupt(); + } } /* Called by Runtime.runFinalization() */ diff --git a/src/java.base/share/classes/jdk/internal/icu/impl/ICUBinary.java b/src/java.base/share/classes/jdk/internal/icu/impl/ICUBinary.java index d8b48e7fa0d..5bb08ce918f 100644 --- a/src/java.base/share/classes/jdk/internal/icu/impl/ICUBinary.java +++ b/src/java.base/share/classes/jdk/internal/icu/impl/ICUBinary.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -39,8 +39,6 @@ import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.util.Arrays; -import java.security.AccessController; -import java.security.PrivilegedAction; import jdk.internal.icu.util.VersionInfo; @@ -81,11 +79,7 @@ public static interface Authenticate public static ByteBuffer getRequiredData(String itemPath) { final Class<ICUBinary> root = ICUBinary.class; - try (@SuppressWarnings("removal") InputStream is = AccessController.doPrivileged(new PrivilegedAction<InputStream>() { - public InputStream run() { - return root.getResourceAsStream(itemPath); - } - })) { + try (InputStream is = root.getResourceAsStream(itemPath)) { // is.available() may return 0, or 1, or the total number of bytes in the stream, // or some other number. diff --git a/src/java.base/share/classes/jdk/internal/misc/ExtendedMapMode.java b/src/java.base/share/classes/jdk/internal/misc/ExtendedMapMode.java index f2852f569bd..3680279b7fa 100644 --- a/src/java.base/share/classes/jdk/internal/misc/ExtendedMapMode.java +++ b/src/java.base/share/classes/jdk/internal/misc/ExtendedMapMode.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -30,8 +30,6 @@ import java.lang.invoke.MethodHandles.Lookup; import java.lang.invoke.MethodType; import java.nio.channels.FileChannel.MapMode; -import java.security.AccessController; -import java.security.PrivilegedExceptionAction; /** * JDK-specific map modes implemented in java.base. @@ -41,10 +39,7 @@ public class ExtendedMapMode { static final MethodHandle MAP_MODE_CONSTRUCTOR; static { try { - PrivilegedExceptionAction<Lookup> pae = () -> - MethodHandles.privateLookupIn(MapMode.class, MethodHandles.lookup()); - @SuppressWarnings("removal") - Lookup lookup = AccessController.doPrivileged(pae); + Lookup lookup = MethodHandles.privateLookupIn(MapMode.class, MethodHandles.lookup()); var methodType = MethodType.methodType(void.class, String.class); MAP_MODE_CONSTRUCTOR = lookup.findConstructor(MapMode.class, methodType); } catch (Exception e) { From d752f19611f7d2a83b4d5356c37e6c8ff02543fd Mon Sep 17 00:00:00 2001 From: Calvin Cheung <ccheung@openjdk.org> Date: Tue, 26 Nov 2024 17:14:00 +0000 Subject: [PATCH 254/311] 8343427: Class file load hook crashes on archived classes from multi-release JARs Reviewed-by: dholmes, iklam --- src/hotspot/share/cds/filemap.cpp | 38 +++- src/hotspot/share/cds/filemap.hpp | 4 + src/hotspot/share/classfile/vmSymbols.hpp | 2 + .../share/classes/java/lang/ClassLoader.java | 9 + .../jvmti/{ => CFLH}/ClassFileLoadHook.java | 0 .../{ => CFLH}/ClassFileLoadHookTest.java | 0 .../appcds/jvmti/CFLH/MultiReleaseJars.java | 187 ++++++++++++++++++ 7 files changed, 239 insertions(+), 1 deletion(-) rename test/hotspot/jtreg/runtime/cds/appcds/jvmti/{ => CFLH}/ClassFileLoadHook.java (100%) rename test/hotspot/jtreg/runtime/cds/appcds/jvmti/{ => CFLH}/ClassFileLoadHookTest.java (100%) create mode 100644 test/hotspot/jtreg/runtime/cds/appcds/jvmti/CFLH/MultiReleaseJars.java diff --git a/src/hotspot/share/cds/filemap.cpp b/src/hotspot/share/cds/filemap.cpp index 00d8fba4411..91a2a57dee5 100644 --- a/src/hotspot/share/cds/filemap.cpp +++ b/src/hotspot/share/cds/filemap.cpp @@ -53,15 +53,18 @@ #include "memory/oopFactory.hpp" #include "memory/universe.hpp" #include "nmt/memTracker.hpp" +#include "oops/access.hpp" #include "oops/compressedOops.hpp" #include "oops/compressedOops.inline.hpp" #include "oops/compressedKlass.hpp" #include "oops/objArrayOop.hpp" #include "oops/oop.inline.hpp" +#include "oops/typeArrayKlass.hpp" #include "prims/jvmtiExport.hpp" #include "runtime/arguments.hpp" #include "runtime/globals_extension.hpp" #include "runtime/java.hpp" +#include "runtime/javaCalls.hpp" #include "runtime/mutexLocker.hpp" #include "runtime/os.hpp" #include "runtime/vm_version.hpp" @@ -2678,11 +2681,44 @@ ClassFileStream* FileMapInfo::open_stream_for_jvmti(InstanceKlass* ik, Handle cl const char* const file_name = ClassLoader::file_name_for_class_name(class_name, name->utf8_length()); ClassLoaderData* loader_data = ClassLoaderData::class_loader_data(class_loader()); - ClassFileStream* cfs = cpe->open_stream_for_loader(THREAD, file_name, loader_data); + ClassFileStream* cfs; + if (class_loader() != nullptr && !cpe->is_modules_image()) { + cfs = get_stream_from_class_loader(class_loader, cpe, file_name, CHECK_NULL); + } else { + cfs = cpe->open_stream_for_loader(THREAD, file_name, loader_data); + } assert(cfs != nullptr, "must be able to read the classfile data of shared classes for built-in loaders."); log_debug(cds, jvmti)("classfile data for %s [%d: %s] = %d bytes", class_name, path_index, cfs->source(), cfs->length()); return cfs; } +ClassFileStream* FileMapInfo::get_stream_from_class_loader(Handle class_loader, + ClassPathEntry* cpe, + const char* file_name, + TRAPS) { + JavaValue result(T_OBJECT); + TempNewSymbol class_name_sym = SymbolTable::new_symbol(file_name); + Handle ext_class_name = java_lang_String::externalize_classname(class_name_sym, CHECK_NULL); + + // byte[] ClassLoader.getResourceAsByteArray(String name) + JavaCalls::call_virtual(&result, + class_loader, + vmClasses::ClassLoader_klass(), + vmSymbols::getResourceAsByteArray_name(), + vmSymbols::getResourceAsByteArray_signature(), + ext_class_name, + CHECK_NULL); + assert(result.get_type() == T_OBJECT, "just checking"); + oop obj = result.get_oop(); + assert(obj != nullptr, "ClassLoader.getResourceAsByteArray should not return null"); + + // copy from byte[] to a buffer + typeArrayOop ba = typeArrayOop(obj); + jint len = ba->length(); + u1* buffer = NEW_RESOURCE_ARRAY(u1, len); + ArrayAccess<>::arraycopy_to_native<>(ba, typeArrayOopDesc::element_offset<jbyte>(0), buffer, len); + + return new ClassFileStream(buffer, len, cpe->name()); +} #endif diff --git a/src/hotspot/share/cds/filemap.hpp b/src/hotspot/share/cds/filemap.hpp index 6319c51f1ce..cabb54769fe 100644 --- a/src/hotspot/share/cds/filemap.hpp +++ b/src/hotspot/share/cds/filemap.hpp @@ -507,6 +507,10 @@ class FileMapInfo : public CHeapObj<mtInternal> { #if INCLUDE_JVMTI // Caller needs a ResourceMark because parts of the returned cfs are resource-allocated. static ClassFileStream* open_stream_for_jvmti(InstanceKlass* ik, Handle class_loader, TRAPS); + static ClassFileStream* get_stream_from_class_loader(Handle class_loader, + ClassPathEntry* cpe, + const char* file_name, + TRAPS); #endif static SharedClassPathEntry* shared_path(int index) { diff --git a/src/hotspot/share/classfile/vmSymbols.hpp b/src/hotspot/share/classfile/vmSymbols.hpp index ca451572de7..6a6f7754c50 100644 --- a/src/hotspot/share/classfile/vmSymbols.hpp +++ b/src/hotspot/share/classfile/vmSymbols.hpp @@ -723,6 +723,8 @@ class SerializeClosure; template(dumpSharedArchive_signature, "(ZLjava/lang/String;)Ljava/lang/String;") \ template(generateLambdaFormHolderClasses, "generateLambdaFormHolderClasses") \ template(generateLambdaFormHolderClasses_signature, "([Ljava/lang/String;)[Ljava/lang/Object;") \ + template(getResourceAsByteArray_name, "getResourceAsByteArray") \ + template(getResourceAsByteArray_signature, "(Ljava/lang/String;)[B") \ template(java_lang_Enum, "java/lang/Enum") \ template(java_lang_invoke_Invokers_Holder, "java/lang/invoke/Invokers$Holder") \ template(java_lang_invoke_DirectMethodHandle_Holder, "java/lang/invoke/DirectMethodHandle$Holder") \ diff --git a/src/java.base/share/classes/java/lang/ClassLoader.java b/src/java.base/share/classes/java/lang/ClassLoader.java index 55341635d8a..b890ba51651 100644 --- a/src/java.base/share/classes/java/lang/ClassLoader.java +++ b/src/java.base/share/classes/java/lang/ClassLoader.java @@ -1685,6 +1685,15 @@ public InputStream getResourceAsStream(String name) { } } + /** + * Called by VM for reading class bytes. + */ + private byte[] getResourceAsByteArray(String name) throws IOException { + Objects.requireNonNull(name); + InputStream is = getResourceAsStream(name); + return is != null ? is.readAllBytes() : null; + } + /** * Open for reading, a resource of the specified name from the search path * used to load classes. This method locates the resource through the diff --git a/test/hotspot/jtreg/runtime/cds/appcds/jvmti/ClassFileLoadHook.java b/test/hotspot/jtreg/runtime/cds/appcds/jvmti/CFLH/ClassFileLoadHook.java similarity index 100% rename from test/hotspot/jtreg/runtime/cds/appcds/jvmti/ClassFileLoadHook.java rename to test/hotspot/jtreg/runtime/cds/appcds/jvmti/CFLH/ClassFileLoadHook.java diff --git a/test/hotspot/jtreg/runtime/cds/appcds/jvmti/ClassFileLoadHookTest.java b/test/hotspot/jtreg/runtime/cds/appcds/jvmti/CFLH/ClassFileLoadHookTest.java similarity index 100% rename from test/hotspot/jtreg/runtime/cds/appcds/jvmti/ClassFileLoadHookTest.java rename to test/hotspot/jtreg/runtime/cds/appcds/jvmti/CFLH/ClassFileLoadHookTest.java diff --git a/test/hotspot/jtreg/runtime/cds/appcds/jvmti/CFLH/MultiReleaseJars.java b/test/hotspot/jtreg/runtime/cds/appcds/jvmti/CFLH/MultiReleaseJars.java new file mode 100644 index 00000000000..92c5e3d5f02 --- /dev/null +++ b/test/hotspot/jtreg/runtime/cds/appcds/jvmti/CFLH/MultiReleaseJars.java @@ -0,0 +1,187 @@ +/* + * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +/* + * @test + * @summary Test multi-release jar with CFLH + * @requires vm.cds + * @requires vm.jvmti + * @library /test/lib /test/hotspot/jtreg/runtime/cds/appcds + * @run main/othervm/native MultiReleaseJars + */ + +import java.io.File; +import java.io.FileOutputStream; +import java.io.PrintStream; +import java.io.IOException; +import jdk.test.lib.cds.CDSTestUtils; +import jdk.test.lib.process.OutputAnalyzer; + +public class MultiReleaseJars { + + static final int BASE_VERSION = 9; + static final String BASE_VERSION_STRING = Integer.toString(BASE_VERSION); + static final int MAJOR_VERSION = Runtime.version().major(); + static final String MAJOR_VERSION_STRING = String.valueOf(MAJOR_VERSION); + + static String getMain() { + String sts = """ + public class Main { + public static void main(String[] args) throws Exception { + System.out.println(Class.forName(\"Foo\")); + System.out.println(Class.forName(\"Bar\")); + } + } + """; + return sts; + } + + static String getFoo() { + String sts = """ + class Foo { + static { + System.out.println("Hello from Foo old version"); + } + } + """; + return sts; + } + + static String getFooNewVersion() { + String sts = """ + class Foo { + static { + System.out.println("Hello from Foo new version"); + } + } + """; + return sts; + } + + static String getBar() { + String sts = """ + class Bar { + static { + System.out.println("Hello from Bar"); + } + } + """; + return sts; + } + + static void writeFile(File file, String... contents) throws Exception { + if (contents == null) { + throw new java.lang.RuntimeException("No input for writing to file" + file); + } + try ( + FileOutputStream fos = new FileOutputStream(file); + PrintStream ps = new PrintStream(fos) + ) { + for (String str : contents) { + ps.println(str); + } + } + } + + /* version.jar entries and files: + * META-INF/ + * META-INF/MANIFEST.MF + * Bar.class + * Main.class + * META-INF/versions/9/ + * META-INF/versions/9/Bar.class + * META-INF/versions/9/Foo.class + * META-INF/versions/24/ + * META-INF/versions/24/Foo.class + */ + static void createClassFilesAndJar() throws Exception { + String tempDir = CDSTestUtils.getOutputDir(); + File baseDir = new File(tempDir + File.separator + "base"); + File vDir = new File(tempDir + File.separator + BASE_VERSION_STRING); + File vDir2 = new File(tempDir + File.separator + MAJOR_VERSION_STRING); + + baseDir.mkdirs(); + vDir.mkdirs(); + + File fileFoo = TestCommon.getOutputSourceFile("Foo.java"); + writeFile(fileFoo, getFoo()); + JarBuilder.compile(vDir.getAbsolutePath(), fileFoo.getAbsolutePath(), "--release", BASE_VERSION_STRING); + + writeFile(fileFoo, getFooNewVersion()); + JarBuilder.compile(vDir2.getAbsolutePath(), fileFoo.getAbsolutePath(), "--release", MAJOR_VERSION_STRING); + + File fileMain = TestCommon.getOutputSourceFile("Main.java"); + writeFile(fileMain, getMain()); + JarBuilder.compile(baseDir.getAbsolutePath(), fileMain.getAbsolutePath()); + File fileBar = TestCommon.getOutputSourceFile("Bar.java"); + writeFile(fileBar, getBar()); + JarBuilder.compile(baseDir.getAbsolutePath(), fileBar.getAbsolutePath()); + JarBuilder.compile(vDir.getAbsolutePath(), fileBar.getAbsolutePath(), "--release", BASE_VERSION_STRING); + + String[] meta = { + "Multi-Release: true", + "Main-Class: Main" + }; + File metainf = new File(tempDir, "mf.txt"); + writeFile(metainf, meta); + + JarBuilder.build("multi-version", baseDir, metainf.getAbsolutePath(), + "--release", BASE_VERSION_STRING, "-C", vDir.getAbsolutePath(), ".", + "--release", MAJOR_VERSION_STRING, "-C", vDir2.getAbsolutePath(), "."); + + } + + public static void main(String... args) throws Exception { + // create multi-version.jar which contains Main.class, Foo.class and Bar.class. + // Foo.class has two version: base version 9 and current major JDK version. + // Bar.class has two versions: base version 9 and default version. + // Since there is no default version for Foo, the class loader will get the + // highest version (current major JDK version in this case) which is the + // same or below the current JDK version. + createClassFilesAndJar(); + + String mainClass = "Main"; + String appJar = TestCommon.getTestJar("multi-version.jar"); + String appClasses[] = {"Foo", "Bar"}; + + OutputAnalyzer output = TestCommon.dump(appJar, appClasses); + output.shouldContain("Loading classes to share: done.") + .shouldHaveExitValue(0); + + String agentCmdArg = "-agentlib:SimpleClassFileLoadHook=Foo,Hello,HELLO"; + output = TestCommon.execAuto("-cp", appJar, + "-Xlog:cds=info,class+load", + agentCmdArg, + mainClass); + + output.shouldMatch(".*Foo.source:.*multi-version.jar") + // New version of Foo is loaded from jar since it was modified by CFLH + .shouldContain("HELLO from Foo new version") // CFLH changed "Hello" to "HELLO" + .shouldContain("class Foo") // output from Main + // Bar is loaded from archive + .shouldContain("Bar source: shared objects file") + .shouldContain("Hello from Bar") + .shouldContain("class Bar"); // output from Main + } +} From 246552674c5508ba350836389a0fa35716e776fb Mon Sep 17 00:00:00 2001 From: Calvin Cheung <ccheung@openjdk.org> Date: Tue, 26 Nov 2024 17:17:45 +0000 Subject: [PATCH 255/311] 8344821: Test CheckDefaultArchiveFile.java fails if classes_coh.jsa is not present Reviewed-by: iklam, dholmes --- .../runtime/cds/CheckDefaultArchiveFile.java | 69 ------------------- 1 file changed, 69 deletions(-) delete mode 100644 test/hotspot/jtreg/runtime/cds/CheckDefaultArchiveFile.java diff --git a/test/hotspot/jtreg/runtime/cds/CheckDefaultArchiveFile.java b/test/hotspot/jtreg/runtime/cds/CheckDefaultArchiveFile.java deleted file mode 100644 index 13f5c84d1c5..00000000000 --- a/test/hotspot/jtreg/runtime/cds/CheckDefaultArchiveFile.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright (c) 2018, 2022, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -/** - * @test Default CDS archive file - * @summary JDK platforms/binaries do not support default CDS archive should - * not contain classes.jsa in the default location. - * @requires vm.cds - * @library /test/lib - * @build jdk.test.whitebox.WhiteBox - * @run driver jdk.test.lib.helpers.ClassFileInstaller jdk.test.whitebox.WhiteBox - * @run main/othervm -Xbootclasspath/a:. -XX:+UnlockDiagnosticVMOptions - * -XX:+WhiteBoxAPI CheckDefaultArchiveFile - */ -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import jdk.test.lib.Platform; -import jdk.test.lib.cds.CDSTestUtils; -import jtreg.SkippedException; -import jdk.test.whitebox.WhiteBox; - -public class CheckDefaultArchiveFile { - public static void main(String[] args) throws Exception { - WhiteBox wb = WhiteBox.getWhiteBox(); - String osArch = Platform.getOsArch(); - String vmName = System.getProperty("java.vm.name"); - String vmString = vmName + "(" + osArch + ")"; - String jsaString = wb.getDefaultArchivePath(); - System.out.println("classes.jsa location:" + jsaString); - if (jsaString == null) { - if (Platform.isDefaultCDSArchiveSupported()) { - throw new RuntimeException("default CDS archive supported, but classes.jsa path null"); - } - } else { - Path jsa = Paths.get(jsaString); - if (Platform.isDefaultCDSArchiveSupported()) { - if (Files.exists(jsa)) { - System.out.println("Passed. " + vmString + - ": has default classes.jsa file"); - } else { - throw new RuntimeException(vmString + "has no " + jsaString); - } - } else { - throw new SkippedException("Default CDS archive is not supported"); - } - } - } -} From 65c98e577f72bfe544d7e6b5e9d1568667d208fa Mon Sep 17 00:00:00 2001 From: Sean Mullan <mullan@openjdk.org> Date: Tue, 26 Nov 2024 17:24:22 +0000 Subject: [PATCH 256/311] 8344420: Remove Security Manager dependencies from javax.security package Reviewed-by: alanb, rriggs, wetmore --- .../classes/com/sun/security/ntlm/NTLM.java | 7 +- .../classes/javax/security/auth/Subject.java | 308 ++---------------- .../security/auth/SubjectDomainCombiner.java | 22 +- .../security/auth/login/Configuration.java | 89 +---- .../security/auth/login/LoginContext.java | 181 ++-------- .../javax/security/cert/X509Certificate.java | 16 +- .../Configuration/GetInstanceConfigSpi.java | 19 +- .../Configuration/GetInstanceProvider.java | 12 +- .../login/LoginContext/ConfigConstructor.java | 9 +- .../auth/login/LoginContext/LCTest.java | 22 +- 10 files changed, 86 insertions(+), 599 deletions(-) diff --git a/src/java.base/share/classes/com/sun/security/ntlm/NTLM.java b/src/java.base/share/classes/com/sun/security/ntlm/NTLM.java index 241756b69e2..7413abf5da4 100644 --- a/src/java.base/share/classes/com/sun/security/ntlm/NTLM.java +++ b/src/java.base/share/classes/com/sun/security/ntlm/NTLM.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2010, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,8 +25,6 @@ package com.sun.security.ntlm; -import sun.security.action.GetBooleanAction; - import static com.sun.security.ntlm.Version.*; import java.io.IOException; import java.nio.charset.StandardCharsets; @@ -57,8 +55,7 @@ class NTLM { private final MessageDigest md4; private final Mac hmac; private final MessageDigest md5; - private static final boolean DEBUG - = GetBooleanAction.privilegedGetProperty("ntlm.debug"); + private static final boolean DEBUG = Boolean.getBoolean("ntlm.debug"); final Version v; diff --git a/src/java.base/share/classes/javax/security/auth/Subject.java b/src/java.base/share/classes/javax/security/auth/Subject.java index 303abe49538..97ab672e1cc 100644 --- a/src/java.base/share/classes/javax/security/auth/Subject.java +++ b/src/java.base/share/classes/javax/security/auth/Subject.java @@ -237,12 +237,6 @@ public Subject(boolean readOnly, Set<? extends Principal> principals, * it can not be reset to being writable again. */ public void setReadOnly() { - @SuppressWarnings("removal") - java.lang.SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - sm.checkPermission(AuthPermissionHolder.SET_READ_ONLY_PERMISSION); - } - this.readOnly = true; } @@ -305,7 +299,6 @@ public static Subject getSubject(final AccessControlContext acc) { * @see #callAs(Subject, Callable) * @since 18 */ - @SuppressWarnings("removal") public static Subject current() { return SCOPED_SUBJECT.orElse(null); } @@ -375,16 +368,10 @@ public static <T> T callAs(final Subject subject, * * @see #callAs(Subject, Callable) */ - @SuppressWarnings("removal") @Deprecated(since="18", forRemoval=true) public static <T> T doAs(final Subject subject, final java.security.PrivilegedAction<T> action) { - java.lang.SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - sm.checkPermission(AuthPermissionHolder.DO_AS_PERMISSION); - } - Objects.requireNonNull(action, ResourcesMgr.getString("invalid.null.action.provided")); @@ -441,17 +428,11 @@ public static <T> T doAs(final Subject subject, * * @see #callAs(Subject, Callable) */ - @SuppressWarnings("removal") @Deprecated(since="18", forRemoval=true) public static <T> T doAs(final Subject subject, final java.security.PrivilegedExceptionAction<T> action) throws java.security.PrivilegedActionException { - java.lang.SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - sm.checkPermission(AuthPermissionHolder.DO_AS_PERMISSION); - } - Objects.requireNonNull(action, ResourcesMgr.getString("invalid.null.action.provided")); @@ -514,11 +495,6 @@ public static <T> T doAsPrivileged(final Subject subject, final java.security.PrivilegedAction<T> action, final java.security.AccessControlContext acc) { - java.lang.SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - sm.checkPermission(AuthPermissionHolder.DO_AS_PRIVILEGED_PERMISSION); - } - Objects.requireNonNull(action, ResourcesMgr.getString("invalid.null.action.provided")); @@ -585,11 +561,6 @@ public static <T> T doAsPrivileged(final Subject subject, final java.security.AccessControlContext acc) throws java.security.PrivilegedActionException { - java.lang.SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - sm.checkPermission(AuthPermissionHolder.DO_AS_PRIVILEGED_PERMISSION); - } - Objects.requireNonNull(action, ResourcesMgr.getString("invalid.null.action.provided")); @@ -609,25 +580,6 @@ public static <T> T doAsPrivileged(final Subject subject, } } - @SuppressWarnings("removal") - private static AccessControlContext createContext(final Subject subject, - final AccessControlContext acc) { - - - return java.security.AccessController.doPrivileged - (new java.security.PrivilegedAction<>() { - public AccessControlContext run() { - if (subject == null) { - return new AccessControlContext(acc, null); - } else { - return new AccessControlContext - (acc, - new SubjectDomainCombiner(subject)); - } - } - }); - } - /** * Return the {@code Set} of Principals associated with this * {@code Subject}. Each {@code Principal} represents @@ -713,14 +665,6 @@ public Set<Object> getPublicCredentials() { */ public Set<Object> getPrivateCredentials() { - // XXX - // we do not need a security check for - // AuthPermission(getPrivateCredentials) - // because we already restrict access to private credentials - // via the PrivateCredentialPermission. all the extra AuthPermission - // would do is protect the set operations themselves - // (like size()), which don't seem security-sensitive. - // always return an empty Set instead of null // so LoginModules can add to the Set if necessary return privCredentials; @@ -782,14 +726,6 @@ public <T> Set<T> getPublicCredentials(Class<T> c) { */ public <T> Set<T> getPrivateCredentials(Class<T> c) { - // XXX - // we do not need a security check for - // AuthPermission(getPrivateCredentials) - // because we already restrict access to private credentials - // via the PrivateCredentialPermission. all the extra AuthPermission - // would do is protect the set operations themselves - // (like size()), which don't seem security-sensitive. - Objects.requireNonNull(c, ResourcesMgr.getString("invalid.null.Class.provided")); @@ -857,15 +793,6 @@ public boolean equals(Object o) { */ @Override public String toString() { - return toString(true); - } - - /** - * package private convenience method to print out the Subject - * without firing off a security check when trying to access - * the Private Credentials - */ - String toString(boolean includePrivateCredentials) { String s = ResourcesMgr.getString("Subject."); String suffix = ""; @@ -885,21 +812,19 @@ String toString(boolean includePrivateCredentials) { } } - if (includePrivateCredentials) { - synchronized(privCredentials) { - Iterator<Object> pI = privCredentials.iterator(); - while (pI.hasNext()) { - try { - Object o = pI.next(); - suffix += ResourcesMgr.getString - (".Private.Credential.") + - o.toString() + - ResourcesMgr.getString("NEWLINE"); - } catch (SecurityException se) { - suffix += ResourcesMgr.getString - (".Private.Credential.inaccessible."); - break; - } + synchronized(privCredentials) { + Iterator<Object> pI = privCredentials.iterator(); + while (pI.hasNext()) { + try { + Object o = pI.next(); + suffix += ResourcesMgr.getString + (".Private.Credential.") + + o.toString() + + ResourcesMgr.getString("NEWLINE"); + } catch (SecurityException se) { + suffix += ResourcesMgr.getString + (".Private.Credential.inaccessible."); + break; } } } @@ -1091,22 +1016,6 @@ public boolean hasNext() { } public E next() { - if (which != Subject.PRIV_CREDENTIAL_SET) { - return i.next(); - } - - @SuppressWarnings("removal") - SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - try { - sm.checkPermission(new PrivateCredentialPermission - (list.get(i.nextIndex()).getClass().getName(), - subject.getPrincipals())); - } catch (SecurityException se) { - i.next(); - throw (se); - } - } return i.next(); } @@ -1117,21 +1026,6 @@ public void remove() { ("Subject.is.read.only")); } - @SuppressWarnings("removal") - java.lang.SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - switch (which) { - case Subject.PRINCIPAL_SET: - sm.checkPermission(AuthPermissionHolder.MODIFY_PRINCIPALS_PERMISSION); - break; - case Subject.PUB_CREDENTIAL_SET: - sm.checkPermission(AuthPermissionHolder.MODIFY_PUBLIC_CREDENTIALS_PERMISSION); - break; - default: - sm.checkPermission(AuthPermissionHolder.MODIFY_PRIVATE_CREDENTIALS_PERMISSION); - break; - } - } i.remove(); } }; @@ -1147,22 +1041,6 @@ public boolean add(E o) { (ResourcesMgr.getString("Subject.is.read.only")); } - @SuppressWarnings("removal") - java.lang.SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - switch (which) { - case Subject.PRINCIPAL_SET: - sm.checkPermission(AuthPermissionHolder.MODIFY_PRINCIPALS_PERMISSION); - break; - case Subject.PUB_CREDENTIAL_SET: - sm.checkPermission(AuthPermissionHolder.MODIFY_PUBLIC_CREDENTIALS_PERMISSION); - break; - default: - sm.checkPermission(AuthPermissionHolder.MODIFY_PRIVATE_CREDENTIALS_PERMISSION); - break; - } - } - switch (which) { case Subject.PRINCIPAL_SET: if (!(o instanceof Principal)) { @@ -1180,10 +1058,9 @@ public boolean add(E o) { return elements.add(o); else { return false; - } + } } - @SuppressWarnings("removal") public boolean remove(Object o) { Objects.requireNonNull(o, @@ -1191,17 +1068,7 @@ public boolean remove(Object o) { final Iterator<E> e = iterator(); while (e.hasNext()) { - E next; - if (which != Subject.PRIV_CREDENTIAL_SET) { - next = e.next(); - } else { - next = java.security.AccessController.doPrivileged - (new java.security.PrivilegedAction<E>() { - public E run() { - return e.next(); - } - }); - } + E next = e.next(); if (next.equals(o)) { e.remove(); @@ -1211,7 +1078,6 @@ public E run() { return false; } - @SuppressWarnings("removal") public boolean contains(Object o) { Objects.requireNonNull(o, @@ -1219,30 +1085,7 @@ public boolean contains(Object o) { final Iterator<E> e = iterator(); while (e.hasNext()) { - E next; - if (which != Subject.PRIV_CREDENTIAL_SET) { - next = e.next(); - } else { - - // For private credentials: - // If the caller does not have read permission - // for o.getClass(), we throw a SecurityException. - // Otherwise, we check the private cred set to see whether - // it contains the Object - - SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - sm.checkPermission(new PrivateCredentialPermission - (o.getClass().getName(), - subject.getPrincipals())); - } - next = java.security.AccessController.doPrivileged - (new java.security.PrivilegedAction<E>() { - public E run() { - return e.next(); - } - }); - } + E next = e.next(); if (next.equals(o)) { return true; @@ -1263,24 +1106,13 @@ public boolean addAll(Collection<? extends E> c) { return result; } - @SuppressWarnings("removal") public boolean removeAll(Collection<?> c) { c = collectionNullClean(c); boolean modified = false; final Iterator<E> e = iterator(); while (e.hasNext()) { - E next; - if (which != Subject.PRIV_CREDENTIAL_SET) { - next = e.next(); - } else { - next = java.security.AccessController.doPrivileged - (new java.security.PrivilegedAction<E>() { - public E run() { - return e.next(); - } - }); - } + E next = e.next(); for (Object o : c) { if (next.equals(o)) { @@ -1305,24 +1137,13 @@ public boolean containsAll(Collection<?> c) { return true; } - @SuppressWarnings("removal") public boolean retainAll(Collection<?> c) { c = collectionNullClean(c); boolean modified = false; final Iterator<E> e = iterator(); while (e.hasNext()) { - E next; - if (which != Subject.PRIV_CREDENTIAL_SET) { - next = e.next(); - } else { - next = java.security.AccessController.doPrivileged - (new java.security.PrivilegedAction<E>() { - public E run() { - return e.next(); - } - }); - } + E next = e.next(); if (c.contains(next) == false) { e.remove(); @@ -1333,21 +1154,10 @@ public E run() { return modified; } - @SuppressWarnings("removal") public void clear() { final Iterator<E> e = iterator(); while (e.hasNext()) { - E next; - if (which != Subject.PRIV_CREDENTIAL_SET) { - next = e.next(); - } else { - next = java.security.AccessController.doPrivileged - (new java.security.PrivilegedAction<E>() { - public E run() { - return e.next(); - } - }); - } + E next = e.next(); e.remove(); } } @@ -1357,30 +1167,10 @@ public boolean isEmpty() { } public Object[] toArray() { - final Iterator<E> e = iterator(); - while (e.hasNext()) { - // The next() method performs a security manager check - // on each element in the SecureSet. If we make it all - // the way through we should be able to simply return - // element's toArray results. Otherwise, we'll let - // the SecurityException pass up the call stack. - e.next(); - } - return elements.toArray(); } public <T> T[] toArray(T[] a) { - final Iterator<E> e = iterator(); - while (e.hasNext()) { - // The next() method performs a security manager check - // on each element in the SecureSet. If we make it all - // the way through we should be able to simply return - // element's toArray results. Otherwise, we'll let - // the SecurityException pass up the call stack. - e.next(); - } - return elements.toArray(a); } @@ -1425,13 +1215,6 @@ public int hashCode() { private void writeObject(java.io.ObjectOutputStream oos) throws java.io.IOException { - if (which == Subject.PRIV_CREDENTIAL_SET) { - // check permissions before serializing - Iterator<E> i = iterator(); - while (i.hasNext()) { - i.next(); - } - } ObjectOutputStream.PutField fields = oos.putFields(); fields.put("this$0", subject); fields.put("elements", elements); @@ -1490,7 +1273,7 @@ private class ClassSet<T> extends AbstractSet<T> { } } - @SuppressWarnings({"removal","unchecked"}) /*To suppress warning from line 1374*/ + @SuppressWarnings("unchecked") private void populateSet() { final Iterator<?> iterator; switch(which) { @@ -1505,34 +1288,10 @@ private void populateSet() { break; } - // Check whether the caller has permission to get - // credentials of Class c - while (iterator.hasNext()) { - Object next; - if (which == Subject.PRIV_CREDENTIAL_SET) { - next = java.security.AccessController.doPrivileged - (new java.security.PrivilegedAction<>() { - public Object run() { - return iterator.next(); - } - }); - } else { - next = iterator.next(); - } + Object next = iterator.next(); if (c.isAssignableFrom(next.getClass())) { - if (which != Subject.PRIV_CREDENTIAL_SET) { - set.add((T)next); - } else { - // Check permission for private creds - SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - sm.checkPermission(new PrivateCredentialPermission - (next.getClass().getName(), - Subject.this.getPrincipals())); - } - set.add((T)next); - } + set.add((T)next); } } } @@ -1560,27 +1319,4 @@ public boolean add(T o) { return set.add(o); } } - - static final class AuthPermissionHolder { - static final AuthPermission DO_AS_PERMISSION = - new AuthPermission("doAs"); - - static final AuthPermission DO_AS_PRIVILEGED_PERMISSION = - new AuthPermission("doAsPrivileged"); - - static final AuthPermission SET_READ_ONLY_PERMISSION = - new AuthPermission("setReadOnly"); - - static final AuthPermission GET_SUBJECT_PERMISSION = - new AuthPermission("getSubject"); - - static final AuthPermission MODIFY_PRINCIPALS_PERMISSION = - new AuthPermission("modifyPrincipals"); - - static final AuthPermission MODIFY_PUBLIC_CREDENTIALS_PERMISSION = - new AuthPermission("modifyPublicCredentials"); - - static final AuthPermission MODIFY_PRIVATE_CREDENTIALS_PERMISSION = - new AuthPermission("modifyPrivateCredentials"); - } } diff --git a/src/java.base/share/classes/javax/security/auth/SubjectDomainCombiner.java b/src/java.base/share/classes/javax/security/auth/SubjectDomainCombiner.java index 222976051c8..bab2c5b9da9 100644 --- a/src/java.base/share/classes/javax/security/auth/SubjectDomainCombiner.java +++ b/src/java.base/share/classes/javax/security/auth/SubjectDomainCombiner.java @@ -25,9 +25,7 @@ package javax.security.auth; -import java.security.AccessController; import java.security.Principal; -import java.security.PrivilegedAction; import java.security.ProtectionDomain; import java.util.Set; import java.util.WeakHashMap; @@ -84,11 +82,6 @@ public SubjectDomainCombiner(Subject subject) { * {@code SubjectDomainCombiner}. */ public Subject getSubject() { - java.lang.SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - sm.checkPermission(new AuthPermission - ("getSubjectFromDomainCombiner")); - } return subject; } @@ -144,14 +137,7 @@ public ProtectionDomain[] combine(ProtectionDomain[] currentDomains, if (subject == null) { debug.println("null subject"); } else { - final Subject s = subject; - AccessController.doPrivileged - (new java.security.PrivilegedAction<Void>() { - public Void run() { - debug.println(s.toString()); - return null; - } - }); + debug.println(subject.toString()); } printInputDomains(currentDomains, assignedDomains); } @@ -349,11 +335,7 @@ private static String printDomain(final ProtectionDomain pd) { if (pd == null) { return "null"; } - return AccessController.doPrivileged(new PrivilegedAction<String>() { - public String run() { - return pd.toString(); - } - }); + return pd.toString(); } /** diff --git a/src/java.base/share/classes/javax/security/auth/login/Configuration.java b/src/java.base/share/classes/javax/security/auth/login/Configuration.java index b46a671e6d3..bebf5f6901a 100644 --- a/src/java.base/share/classes/javax/security/auth/login/Configuration.java +++ b/src/java.base/share/classes/javax/security/auth/login/Configuration.java @@ -25,12 +25,6 @@ package javax.security.auth.login; -import javax.security.auth.AuthPermission; - -import java.security.AccessController; -import java.security.PrivilegedAction; -import java.security.PrivilegedExceptionAction; -import java.security.PrivilegedActionException; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.Provider; @@ -190,19 +184,6 @@ public abstract class Configuration { private static Configuration configuration; - @SuppressWarnings("removal") - private final java.security.AccessControlContext acc = - java.security.AccessController.getContext(); - - private static void checkPermission(String type) { - @SuppressWarnings("removal") - SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - sm.checkPermission(new AuthPermission - ("createLoginConfiguration." + type)); - } - } - /** * Sole constructor. (For invocation by subclass constructors, typically * implicit.) @@ -219,64 +200,29 @@ protected Configuration() { } * * @see #setConfiguration */ - @SuppressWarnings("removal") public static Configuration getConfiguration() { - SecurityManager sm = System.getSecurityManager(); - if (sm != null) - sm.checkPermission(new AuthPermission("getLoginConfiguration")); - synchronized (Configuration.class) { if (configuration == null) { - String config_class = null; - config_class = AccessController.doPrivileged - (new PrivilegedAction<>() { - public String run() { - return java.security.Security.getProperty - ("login.configuration.provider"); - } - }); + String config_class = Security.getProperty + ("login.configuration.provider"); if (config_class == null) { config_class = "sun.security.provider.ConfigFile"; } try { - final String finalClass = config_class; - Configuration untrustedImpl = AccessController.doPrivileged( - new PrivilegedExceptionAction<>() { - public Configuration run() throws ClassNotFoundException, - InstantiationException, - IllegalAccessException { - Class<? extends Configuration> implClass = Class.forName( - finalClass, false, - Thread.currentThread().getContextClassLoader() - ).asSubclass(Configuration.class); - @SuppressWarnings("deprecation") - Configuration result = implClass.newInstance(); - return result; - } - }); - AccessController.doPrivileged( - new PrivilegedExceptionAction<>() { - public Void run() { - setConfiguration(untrustedImpl); - return null; - } - }, Objects.requireNonNull(untrustedImpl.acc) - ); - } catch (PrivilegedActionException e) { - Exception ee = e.getException(); - if (ee instanceof InstantiationException) { - throw new SecurityException - ("Configuration error:" + - ee.getCause().getMessage() + - "\n", ee.getCause()); - } else { - throw new SecurityException - ("Configuration error: " + - ee.toString() + - "\n", ee); - } + Class<? extends Configuration> implClass = Class.forName( + config_class, false, + Thread.currentThread().getContextClassLoader() + ).asSubclass(Configuration.class); + @SuppressWarnings("deprecation") + Configuration result = implClass.newInstance(); + setConfiguration(result); + } catch (ReflectiveOperationException e) { + throw new SecurityException + ("Configuration error: " + + e.toString() + + "\n", e); } } return configuration; @@ -291,10 +237,6 @@ public Void run() { * @see #getConfiguration */ public static void setConfiguration(Configuration configuration) { - @SuppressWarnings("removal") - SecurityManager sm = System.getSecurityManager(); - if (sm != null) - sm.checkPermission(new AuthPermission("setLoginConfiguration")); Configuration.configuration = configuration; } @@ -346,7 +288,6 @@ public static Configuration getInstance(String type, throws NoSuchAlgorithmException { Objects.requireNonNull(type, "null type name"); - checkPermission(type); try { GetInstance.Instance instance = GetInstance.getInstance ("Configuration", @@ -412,7 +353,6 @@ public static Configuration getInstance(String type, throw new IllegalArgumentException("missing provider"); } - checkPermission(type); try { GetInstance.Instance instance = GetInstance.getInstance ("Configuration", @@ -473,7 +413,6 @@ public static Configuration getInstance(String type, throw new IllegalArgumentException("missing provider"); } - checkPermission(type); try { GetInstance.Instance instance = GetInstance.getInstance ("Configuration", diff --git a/src/java.base/share/classes/javax/security/auth/login/LoginContext.java b/src/java.base/share/classes/javax/security/auth/login/LoginContext.java index 5878da078f6..988379a3c40 100644 --- a/src/java.base/share/classes/javax/security/auth/login/LoginContext.java +++ b/src/java.base/share/classes/javax/security/auth/login/LoginContext.java @@ -25,16 +25,13 @@ package javax.security.auth.login; -import java.security.AccessController; -import java.security.PrivilegedAction; import java.util.Map; import java.util.HashMap; +import java.security.Security; import java.text.MessageFormat; import javax.security.auth.Subject; -import javax.security.auth.AuthPermission; import javax.security.auth.callback.*; import javax.security.auth.spi.LoginModule; -import java.security.AccessControlContext; import java.util.ServiceLoader; import sun.security.util.PendingException; @@ -182,8 +179,6 @@ public class LoginContext { private final Map<String,?> state = new HashMap<>(); private Configuration config; - @SuppressWarnings("removal") - private AccessControlContext creatorAcc = null; // customized config only private ModuleInfo[] moduleStack; private ClassLoader contextClassLoader = null; @@ -200,38 +195,21 @@ public class LoginContext { private static final WeakHashMap<ClassLoader, Set<Provider<LoginModule>>> providersCache = new WeakHashMap<>(); - @SuppressWarnings("removal") private void init(String name) throws LoginException { - SecurityManager sm = System.getSecurityManager(); - if (sm != null && creatorAcc == null) { - sm.checkPermission(new AuthPermission - ("createLoginContext." + name)); - } - if (name == null) throw new LoginException (ResourcesMgr.getString("Invalid.null.input.name")); // get the Configuration if (config == null) { - config = java.security.AccessController.doPrivileged - (new java.security.PrivilegedAction<Configuration>() { - public Configuration run() { - return Configuration.getConfiguration(); - } - }); + config = Configuration.getConfiguration(); } // get the LoginModules configured for this application AppConfigurationEntry[] entries = config.getAppConfigurationEntry(name); if (entries == null) { - if (sm != null && creatorAcc == null) { - sm.checkPermission(new AuthPermission - ("createLoginContext." + OTHER)); - } - entries = config.getAppConfigurationEntry(OTHER); if (entries == null) { MessageFormat form = new MessageFormat(ResourcesMgr.getString @@ -251,55 +229,30 @@ public Configuration run() { null); } - contextClassLoader = java.security.AccessController.doPrivileged - (new java.security.PrivilegedAction<ClassLoader>() { - public ClassLoader run() { - ClassLoader loader = - Thread.currentThread().getContextClassLoader(); - if (loader == null) { - // Don't use bootstrap class loader directly to ensure - // proper package access control! - loader = ClassLoader.getSystemClassLoader(); - } - - return loader; - } - }); + ClassLoader loader = Thread.currentThread().getContextClassLoader(); + if (loader == null) { + loader = ClassLoader.getSystemClassLoader(); + } + contextClassLoader = loader; } - @SuppressWarnings("removal") + @SuppressWarnings("deprecation") private void loadDefaultCallbackHandler() throws LoginException { // get the default handler class try { - - final ClassLoader finalLoader = contextClassLoader; - - this.callbackHandler = java.security.AccessController.doPrivileged( - new java.security.PrivilegedExceptionAction<CallbackHandler>() { - public CallbackHandler run() throws Exception { - String defaultHandler = java.security.Security.getProperty - (DEFAULT_HANDLER); - if (defaultHandler == null || defaultHandler.isEmpty()) - return null; - Class<? extends CallbackHandler> c = Class.forName( - defaultHandler, true, - finalLoader).asSubclass(CallbackHandler.class); - @SuppressWarnings("deprecation") - CallbackHandler result = c.newInstance(); - return result; - } - }); - } catch (java.security.PrivilegedActionException pae) { - throw new LoginException(pae.getException().toString()); - } - - // secure it with the caller's ACC - if (this.callbackHandler != null && creatorAcc == null) { - this.callbackHandler = new SecureCallbackHandler - (java.security.AccessController.getContext(), - this.callbackHandler); + String defaultHandler = Security.getProperty(DEFAULT_HANDLER); + if (defaultHandler == null || defaultHandler.isEmpty()) { + this.callbackHandler = null; + } else { + Class<? extends CallbackHandler> c = Class.forName( + defaultHandler, true, + contextClassLoader).asSubclass(CallbackHandler.class); + this.callbackHandler = (CallbackHandler) c.newInstance(); + } + } catch (ReflectiveOperationException e) { + throw new LoginException(e.toString()); } } @@ -367,16 +320,13 @@ public LoginContext(String name, Subject subject) * for "{@code other}", or if the caller-specified * {@code callbackHandler} is {@code null}. */ - @SuppressWarnings("removal") public LoginContext(String name, CallbackHandler callbackHandler) throws LoginException { init(name); if (callbackHandler == null) throw new LoginException(ResourcesMgr.getString ("invalid.null.CallbackHandler.provided")); - this.callbackHandler = new SecureCallbackHandler - (java.security.AccessController.getContext(), - callbackHandler); + this.callbackHandler = callbackHandler; } /** @@ -400,16 +350,13 @@ public LoginContext(String name, CallbackHandler callbackHandler) * or if the caller-specified * {@code callbackHandler} is {@code null}. */ - @SuppressWarnings("removal") public LoginContext(String name, Subject subject, CallbackHandler callbackHandler) throws LoginException { this(name, subject); if (callbackHandler == null) throw new LoginException(ResourcesMgr.getString ("invalid.null.CallbackHandler.provided")); - this.callbackHandler = new SecureCallbackHandler - (java.security.AccessController.getContext(), - callbackHandler); + this.callbackHandler = callbackHandler; } /** @@ -437,14 +384,10 @@ public LoginContext(String name, Subject subject, * * @since 1.5 */ - @SuppressWarnings("removal") public LoginContext(String name, Subject subject, CallbackHandler callbackHandler, Configuration config) throws LoginException { this.config = config; - if (config != null) { - creatorAcc = java.security.AccessController.getContext(); - } init(name); if (subject != null) { @@ -453,10 +396,6 @@ public LoginContext(String name, Subject subject, } if (callbackHandler == null) { loadDefaultCallbackHandler(); - } else if (creatorAcc == null) { - this.callbackHandler = new SecureCallbackHandler - (java.security.AccessController.getContext(), - callbackHandler); } else { this.callbackHandler = callbackHandler; } @@ -518,13 +457,12 @@ public void login() throws LoginException { } try { - // module invoked in doPrivileged - invokePriv(LOGIN_METHOD); - invokePriv(COMMIT_METHOD); + invoke(LOGIN_METHOD); + invoke(COMMIT_METHOD); loginSucceeded = true; } catch (LoginException le) { try { - invokePriv(ABORT_METHOD); + invoke(ABORT_METHOD); } catch (LoginException le2) { throw le; } @@ -557,8 +495,7 @@ public void logout() throws LoginException { ("null.subject.logout.called.before.login")); } - // module invoked in doPrivileged - invokePriv(LOGOUT_METHOD); + invoke(LOGOUT_METHOD); } /** @@ -597,28 +534,8 @@ private void throwException(LoginException originalError, LoginException le) } /** - * Invokes the login, commit, and logout methods - * from a LoginModule inside a doPrivileged block restricted - * by creatorAcc (may be null). - * - * This version is called if the caller did not instantiate - * the LoginContext with a Configuration object. + * Invokes the login, commit, and logout methods from a LoginModule. */ - @SuppressWarnings("removal") - private void invokePriv(final String methodName) throws LoginException { - try { - java.security.AccessController.doPrivileged - (new java.security.PrivilegedExceptionAction<Void>() { - public Void run() throws LoginException { - invoke(methodName); - return null; - } - }, creatorAcc); - } catch (java.security.PrivilegedActionException pae) { - throw (LoginException)pae.getException(); - } - } - private void invoke(String methodName) throws LoginException { // start at moduleIndex @@ -639,11 +556,8 @@ private void invoke(String methodName) throws LoginException { if (debug != null){ debug.println("Build ServiceProviders cache for ClassLoader: " + contextClassLoader.getName()); } - @SuppressWarnings("removal") - ServiceLoader<LoginModule> sc = AccessController.doPrivileged( - (PrivilegedAction<ServiceLoader<LoginModule>>) - () -> java.util.ServiceLoader.load( - LoginModule.class, contextClassLoader)); + ServiceLoader<LoginModule> sc = ServiceLoader.load( + LoginModule.class, contextClassLoader); lmProviders = sc.stream().collect(Collectors.toSet()); if (debug != null){ debug.println("Discovered ServiceProviders for ClassLoader: " + contextClassLoader.getName()); @@ -841,45 +755,6 @@ private void invoke(String methodName) throws LoginException { } } - /** - * Wrap the caller-specified CallbackHandler in our own - * and invoke it within a privileged block, constrained by - * the caller's AccessControlContext. - */ - private static class SecureCallbackHandler implements CallbackHandler { - - @SuppressWarnings("removal") - private final java.security.AccessControlContext acc; - private final CallbackHandler ch; - - SecureCallbackHandler(@SuppressWarnings("removal") java.security.AccessControlContext acc, - CallbackHandler ch) { - this.acc = acc; - this.ch = ch; - } - - @SuppressWarnings("removal") - public void handle(final Callback[] callbacks) - throws java.io.IOException, UnsupportedCallbackException { - try { - java.security.AccessController.doPrivileged - (new java.security.PrivilegedExceptionAction<Void>() { - public Void run() throws java.io.IOException, - UnsupportedCallbackException { - ch.handle(callbacks); - return null; - } - }, acc); - } catch (java.security.PrivilegedActionException pae) { - if (pae.getException() instanceof java.io.IOException) { - throw (java.io.IOException)pae.getException(); - } else { - throw (UnsupportedCallbackException)pae.getException(); - } - } - } - } - /** * LoginModule information - * encapsulates Configuration info and actual module instances diff --git a/src/java.base/share/classes/javax/security/cert/X509Certificate.java b/src/java.base/share/classes/javax/security/cert/X509Certificate.java index f93c811cf29..38ab1976987 100644 --- a/src/java.base/share/classes/javax/security/cert/X509Certificate.java +++ b/src/java.base/share/classes/javax/security/cert/X509Certificate.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -30,9 +30,7 @@ import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.math.BigInteger; -import java.security.AccessController; import java.security.Principal; -import java.security.PrivilegedAction; import java.security.Security; import java.util.Date; @@ -140,17 +138,7 @@ public X509Certificate() {} * </pre> */ private static final String X509_PROVIDER = "cert.provider.x509v1"; - private static String X509Provider; - - static { - X509Provider = AccessController.doPrivileged( - new PrivilegedAction<>() { - public String run() { - return Security.getProperty(X509_PROVIDER); - } - } - ); - } + private static String X509Provider = Security.getProperty(X509_PROVIDER); /** * Instantiates an X509Certificate object, and initializes it with diff --git a/test/jdk/javax/security/auth/login/Configuration/GetInstanceConfigSpi.java b/test/jdk/javax/security/auth/login/Configuration/GetInstanceConfigSpi.java index f8b73c6ce36..8127292ee3b 100644 --- a/test/jdk/javax/security/auth/login/Configuration/GetInstanceConfigSpi.java +++ b/test/jdk/javax/security/auth/login/Configuration/GetInstanceConfigSpi.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,7 +21,7 @@ * questions. */ -import java.security.*; +import java.security.URIParameter; import javax.security.auth.login.*; import com.sun.security.auth.login.*; @@ -31,16 +31,11 @@ public class GetInstanceConfigSpi extends ConfigurationSpi { public GetInstanceConfigSpi(final Configuration.Parameters params) { - c = AccessController.doPrivileged - (new PrivilegedAction<Configuration>() { - public Configuration run() { - if (params instanceof URIParameter) { - URIParameter uriParam = (URIParameter)params; - return new ConfigFile(uriParam.getURI()); - } - return new ConfigFile(); - } - }); + if (params instanceof URIParameter uriParam) { + c = new ConfigFile(uriParam.getURI()); + } else { + c = new ConfigFile(); + } } public AppConfigurationEntry[] engineGetAppConfigurationEntry(String name) { diff --git a/test/jdk/javax/security/auth/login/Configuration/GetInstanceProvider.java b/test/jdk/javax/security/auth/login/Configuration/GetInstanceProvider.java index 01f0a1fd572..ac6e4693fc2 100644 --- a/test/jdk/javax/security/auth/login/Configuration/GetInstanceProvider.java +++ b/test/jdk/javax/security/auth/login/Configuration/GetInstanceProvider.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -21,7 +21,7 @@ * questions. */ -import java.security.*; +import java.security.Provider; public class GetInstanceProvider extends Provider { @@ -30,12 +30,6 @@ public GetInstanceProvider() { "1", "GetInstanceProvider: Configuration.GetInstanceConfigSpi"); - AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { - put("Configuration.GetInstanceConfigSpi", - "GetInstanceConfigSpi"); - return null; - } - }); + put("Configuration.GetInstanceConfigSpi", "GetInstanceConfigSpi"); } } diff --git a/test/jdk/javax/security/auth/login/LoginContext/ConfigConstructor.java b/test/jdk/javax/security/auth/login/LoginContext/ConfigConstructor.java index 7907ad12bbe..d6ab1d5d857 100644 --- a/test/jdk/javax/security/auth/login/LoginContext/ConfigConstructor.java +++ b/test/jdk/javax/security/auth/login/LoginContext/ConfigConstructor.java @@ -31,12 +31,6 @@ * */ -/** - * This test shares the login config with ConfigConstructorNoPerm. - * This test has all necessary permissions configured in the policy - * (ConfigConstructorNoPerm has no perms and checks for SecurityExceptions). - */ - import java.util.Map; import javax.security.auth.Subject; import javax.security.auth.login.AppConfigurationEntry; @@ -209,8 +203,7 @@ public MyModule3() { } public void initialize(Subject s, CallbackHandler ch, Map<String,?> state, Map<String,?> options) { if (s != ConfigConstructor.s || - ch == null || - ch == ConfigConstructor.ch) { + ch == null) { throw new SecurityException("Module 3 failed"); } } diff --git a/test/jdk/javax/security/auth/login/LoginContext/LCTest.java b/test/jdk/javax/security/auth/login/LoginContext/LCTest.java index e5eeb6c1d7f..b9c8735499f 100644 --- a/test/jdk/javax/security/auth/login/LoginContext/LCTest.java +++ b/test/jdk/javax/security/auth/login/LoginContext/LCTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -287,15 +287,9 @@ public boolean commit() throws LoginException { return false; } userPrincipal = new UnixPrincipal(username); - final Subject s = subject; - final UnixPrincipal up = userPrincipal; - java.security.AccessController.doPrivileged - ((java.security.PrivilegedAction) () -> { - if (!s.getPrincipals().contains(up)) { - s.getPrincipals().add(up); - } - return null; - }); + if (!subject.getPrincipals().contains(userPrincipal)) { + subject.getPrincipals().add(userPrincipal); + } password = null; commitSucceeded = true; return true; @@ -320,13 +314,7 @@ public boolean logout() throws LoginException { private void clearState() { if (commitSucceeded) { - final Subject s = subject; - final UnixPrincipal up = userPrincipal; - java.security.AccessController.doPrivileged - ((java.security.PrivilegedAction) () -> { - s.getPrincipals().remove(up); - return null; - }); + subject.getPrincipals().remove(userPrincipal); } username = null; password = null; From c5de307284e51404ccc7da6ac491761c10ed08c2 Mon Sep 17 00:00:00 2001 From: Sean Mullan <mullan@openjdk.org> Date: Tue, 26 Nov 2024 18:40:52 +0000 Subject: [PATCH 257/311] 8344992: Remove Security Manager dependencies from java.security.cert API and implementations Reviewed-by: rriggs, hchao --- .../java/security/cert/CertPathBuilder.java | 9 +-- .../java/security/cert/CertPathValidator.java | 9 +-- .../classes/java/security/cert/CertStore.java | 9 +-- .../security/provider/certpath/Builder.java | 5 +- .../provider/certpath/OCSPResponse.java | 7 +- .../provider/certpath/RevocationChecker.java | 45 +++++-------- .../sun/security/util/AnchorCertificates.java | 66 ++++++++----------- .../sun/security/util/SecurityProperties.java | 4 +- .../security/util/UntrustedCertificates.java | 27 +++----- .../security/validator/CADistrustPolicy.java | 13 +--- .../sun/security/validator/PKIXValidator.java | 9 ++- .../share/classes/sun/security/x509/AVA.java | 7 +- 12 files changed, 73 insertions(+), 137 deletions(-) diff --git a/src/java.base/share/classes/java/security/cert/CertPathBuilder.java b/src/java.base/share/classes/java/security/cert/CertPathBuilder.java index a89d4264234..de1a86312c4 100644 --- a/src/java.base/share/classes/java/security/cert/CertPathBuilder.java +++ b/src/java.base/share/classes/java/security/cert/CertPathBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,11 +25,9 @@ package java.security.cert; -import java.security.AccessController; import java.security.InvalidAlgorithmParameterException; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; -import java.security.PrivilegedAction; import java.security.Provider; import java.security.Security; import java.util.Objects; @@ -317,10 +315,7 @@ public final CertPathBuilderResult build(CertPathParameters params) * {@literal "PKIX"} if no such property exists. */ public static final String getDefaultType() { - @SuppressWarnings("removal") - String cpbtype = - AccessController.doPrivileged((PrivilegedAction<String>) () -> - Security.getProperty(CPB_TYPE)); + String cpbtype = Security.getProperty(CPB_TYPE); return (cpbtype == null) ? "PKIX" : cpbtype; } diff --git a/src/java.base/share/classes/java/security/cert/CertPathValidator.java b/src/java.base/share/classes/java/security/cert/CertPathValidator.java index 69918826dfb..c79283b536f 100644 --- a/src/java.base/share/classes/java/security/cert/CertPathValidator.java +++ b/src/java.base/share/classes/java/security/cert/CertPathValidator.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,11 +25,9 @@ package java.security.cert; -import java.security.AccessController; import java.security.InvalidAlgorithmParameterException; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; -import java.security.PrivilegedAction; import java.security.Provider; import java.security.Security; import java.util.Objects; @@ -329,10 +327,7 @@ public final CertPathValidatorResult validate(CertPath certPath, * {@literal "PKIX"} if no such property exists. */ public static final String getDefaultType() { - @SuppressWarnings("removal") - String cpvtype = - AccessController.doPrivileged((PrivilegedAction<String>) () -> - Security.getProperty(CPV_TYPE)); + String cpvtype = Security.getProperty(CPV_TYPE); return (cpvtype == null) ? "PKIX" : cpvtype; } diff --git a/src/java.base/share/classes/java/security/cert/CertStore.java b/src/java.base/share/classes/java/security/cert/CertStore.java index 0b8c5bfefd9..3801a1fbcaf 100644 --- a/src/java.base/share/classes/java/security/cert/CertStore.java +++ b/src/java.base/share/classes/java/security/cert/CertStore.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,11 +25,9 @@ package java.security.cert; -import java.security.AccessController; import java.security.InvalidAlgorithmParameterException; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; -import java.security.PrivilegedAction; import java.security.Provider; import java.security.Security; import java.util.Collection; @@ -426,11 +424,8 @@ public final Provider getProvider() { * {@code certstore.type} security property, or the string * {@literal "LDAP"} if no such property exists. */ - @SuppressWarnings("removal") public static final String getDefaultType() { - String cstype; - cstype = AccessController.doPrivileged((PrivilegedAction<String>) () -> - Security.getProperty(CERTSTORE_TYPE)); + String cstype = Security.getProperty(CERTSTORE_TYPE); if (cstype == null) { cstype = "LDAP"; } diff --git a/src/java.base/share/classes/sun/security/provider/certpath/Builder.java b/src/java.base/share/classes/sun/security/provider/certpath/Builder.java index 71e8b615a36..3331e98412e 100644 --- a/src/java.base/share/classes/sun/security/provider/certpath/Builder.java +++ b/src/java.base/share/classes/sun/security/provider/certpath/Builder.java @@ -30,7 +30,6 @@ import java.security.cert.*; import java.util.*; -import sun.security.action.GetBooleanAction; import sun.security.provider.certpath.PKIX.BuilderParams; import sun.security.util.Debug; @@ -55,8 +54,8 @@ abstract class Builder { * Authority Information Access extension shall be enabled. Currently * disabled by default for compatibility reasons. */ - static final boolean USE_AIA = GetBooleanAction - .privilegedGetProperty("com.sun.security.enableAIAcaIssuers"); + static final boolean USE_AIA = + Boolean.getBoolean("com.sun.security.enableAIAcaIssuers"); /** * Initialize the builder with the input parameters. diff --git a/src/java.base/share/classes/sun/security/provider/certpath/OCSPResponse.java b/src/java.base/share/classes/sun/security/provider/certpath/OCSPResponse.java index ab9cf32d103..8396503e355 100644 --- a/src/java.base/share/classes/sun/security/provider/certpath/OCSPResponse.java +++ b/src/java.base/share/classes/sun/security/provider/certpath/OCSPResponse.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -45,7 +45,6 @@ import javax.security.auth.x500.X500Principal; import sun.security.util.HexDumpEncoder; -import sun.security.action.GetIntegerAction; import sun.security.x509.*; import sun.security.util.*; @@ -161,9 +160,7 @@ public enum ResponseStatus { * value is negative, set the skew to the default. */ private static int initializeClockSkew() { - @SuppressWarnings("removal") - Integer tmp = java.security.AccessController.doPrivileged( - new GetIntegerAction("com.sun.security.ocsp.clockSkew")); + Integer tmp = Integer.getInteger("com.sun.security.ocsp.clockSkew"); if (tmp == null || tmp < 0) { return DEFAULT_MAX_CLOCK_SKEW; } diff --git a/src/java.base/share/classes/sun/security/provider/certpath/RevocationChecker.java b/src/java.base/share/classes/sun/security/provider/certpath/RevocationChecker.java index 82a72d7123b..297727310d4 100644 --- a/src/java.base/share/classes/sun/security/provider/certpath/RevocationChecker.java +++ b/src/java.base/share/classes/sun/security/provider/certpath/RevocationChecker.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -29,10 +29,8 @@ import java.math.BigInteger; import java.net.URI; import java.net.URISyntaxException; -import java.security.AccessController; import java.security.InvalidAlgorithmParameterException; import java.security.NoSuchAlgorithmException; -import java.security.PrivilegedAction; import java.security.PublicKey; import java.security.Security; import java.security.cert.CertPathValidatorException.BasicReason; @@ -181,34 +179,21 @@ private static URI toURI(String uriString) } } - @SuppressWarnings("removal") private static RevocationProperties getRevocationProperties() { - return AccessController.doPrivileged( - new PrivilegedAction<RevocationProperties>() { - public RevocationProperties run() { - RevocationProperties rp = new RevocationProperties(); - String onlyEE = Security.getProperty( - "com.sun.security.onlyCheckRevocationOfEECert"); - rp.onlyEE = onlyEE != null - && onlyEE.equalsIgnoreCase("true"); - String ocspEnabled = Security.getProperty("ocsp.enable"); - rp.ocspEnabled = ocspEnabled != null - && ocspEnabled.equalsIgnoreCase("true"); - rp.ocspUrl = Security.getProperty("ocsp.responderURL"); - rp.ocspSubject - = Security.getProperty("ocsp.responderCertSubjectName"); - rp.ocspIssuer - = Security.getProperty("ocsp.responderCertIssuerName"); - rp.ocspSerial - = Security.getProperty("ocsp.responderCertSerialNumber"); - rp.crlDPEnabled - = Boolean.getBoolean("com.sun.security.enableCRLDP"); - rp.ocspNonce - = Boolean.getBoolean("jdk.security.certpath.ocspNonce"); - return rp; - } - } - ); + RevocationProperties rp = new RevocationProperties(); + String onlyEE = Security.getProperty( + "com.sun.security.onlyCheckRevocationOfEECert"); + rp.onlyEE = onlyEE != null && onlyEE.equalsIgnoreCase("true"); + String ocspEnabled = Security.getProperty("ocsp.enable"); + rp.ocspEnabled = ocspEnabled != null + && ocspEnabled.equalsIgnoreCase("true"); + rp.ocspUrl = Security.getProperty("ocsp.responderURL"); + rp.ocspSubject = Security.getProperty("ocsp.responderCertSubjectName"); + rp.ocspIssuer = Security.getProperty("ocsp.responderCertIssuerName"); + rp.ocspSerial = Security.getProperty("ocsp.responderCertSerialNumber"); + rp.crlDPEnabled = Boolean.getBoolean("com.sun.security.enableCRLDP"); + rp.ocspNonce = Boolean.getBoolean("jdk.security.certpath.ocspNonce"); + return rp; } private static X509Certificate getResponderCert(RevocationProperties rp, diff --git a/src/java.base/share/classes/sun/security/util/AnchorCertificates.java b/src/java.base/share/classes/sun/security/util/AnchorCertificates.java index 5d2c0674475..67900084b63 100644 --- a/src/java.base/share/classes/sun/security/util/AnchorCertificates.java +++ b/src/java.base/share/classes/sun/security/util/AnchorCertificates.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2016, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -27,9 +27,7 @@ import java.io.File; import java.io.FileInputStream; -import java.security.AccessController; import java.security.KeyStore; -import java.security.PrivilegedAction; import java.security.cert.X509Certificate; import java.util.Collections; import java.util.Enumeration; @@ -51,45 +49,37 @@ public class AnchorCertificates { private static Set<X500Principal> certIssuers = Collections.emptySet(); static { - @SuppressWarnings("removal") - var dummy = AccessController.doPrivileged(new PrivilegedAction<>() { - @Override - public Void run() { - File f = new File(FilePaths.cacerts()); - try { - KeyStore cacerts; - cacerts = KeyStore.getInstance("JKS"); - try (FileInputStream fis = new FileInputStream(f)) { - cacerts.load(fis, null); - certs = new HashSet<>(); - certIssuers = new HashSet<>(); - Enumeration<String> list = cacerts.aliases(); - while (list.hasMoreElements()) { - String alias = list.nextElement(); - // Check if this cert is labeled a trust anchor. - if (alias.contains(" [jdk")) { - X509Certificate cert = (X509Certificate) cacerts - .getCertificate(alias); - String fp = - X509CertImpl.getFingerprint(HASH, cert, debug); - // only add trust anchor if fingerprint can - // be calculated - if (fp != null) { - certs.add(fp); - certIssuers.add(cert.getSubjectX500Principal()); - } - } + File f = new File(FilePaths.cacerts()); + try { + KeyStore cacerts = KeyStore.getInstance("JKS"); + try (FileInputStream fis = new FileInputStream(f)) { + cacerts.load(fis, null); + certs = new HashSet<>(); + certIssuers = new HashSet<>(); + Enumeration<String> list = cacerts.aliases(); + while (list.hasMoreElements()) { + String alias = list.nextElement(); + // Check if this cert is labeled a trust anchor. + if (alias.contains(" [jdk")) { + X509Certificate cert = (X509Certificate) cacerts + .getCertificate(alias); + String fp = + X509CertImpl.getFingerprint(HASH, cert, debug); + // only add trust anchor if fingerprint can + // be calculated + if (fp != null) { + certs.add(fp); + certIssuers.add(cert.getSubjectX500Principal()); } } - } catch (Exception e) { - if (debug != null) { - debug.println("Error parsing cacerts"); - e.printStackTrace(); - } } - return null; } - }); + } catch (Exception e) { + if (debug != null) { + debug.println("Error parsing cacerts"); + e.printStackTrace(); + } + } } /** diff --git a/src/java.base/share/classes/sun/security/util/SecurityProperties.java b/src/java.base/share/classes/sun/security/util/SecurityProperties.java index ac9ca12d4b4..a07c9b743fc 100644 --- a/src/java.base/share/classes/sun/security/util/SecurityProperties.java +++ b/src/java.base/share/classes/sun/security/util/SecurityProperties.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2018 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -51,7 +51,7 @@ public static String privilegedGetOverridable(String propName) { } } - private static String getOverridableProperty(String propName) { + public static String getOverridableProperty(String propName) { String val = System.getProperty(propName); if (val == null) { return Security.getProperty(propName); diff --git a/src/java.base/share/classes/sun/security/util/UntrustedCertificates.java b/src/java.base/share/classes/sun/security/util/UntrustedCertificates.java index c232e02e474..f41d9156f8c 100644 --- a/src/java.base/share/classes/sun/security/util/UntrustedCertificates.java +++ b/src/java.base/share/classes/sun/security/util/UntrustedCertificates.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,8 +25,6 @@ package sun.security.util; import java.io.*; -import java.security.AccessController; -import java.security.PrivilegedAction; import java.security.cert.X509Certificate; import java.util.Properties; @@ -50,22 +48,15 @@ public final class UntrustedCertificates { private static final String algorithm; static { - @SuppressWarnings("removal") - var dummy = AccessController.doPrivileged(new PrivilegedAction<Void>() { - @Override - public Void run() { - File f = new File(StaticProperty.javaHome(), - "lib/security/blocked.certs"); - try (FileInputStream fin = new FileInputStream(f)) { - props.load(fin); - } catch (IOException fnfe) { - if (debug != null) { - debug.println("Error parsing blocked.certs"); - } - } - return null; + File f = new File(StaticProperty.javaHome(), + "lib/security/blocked.certs"); + try (FileInputStream fin = new FileInputStream(f)) { + props.load(fin); + } catch (IOException fnfe) { + if (debug != null) { + debug.println("Error parsing blocked.certs"); } - }); + } algorithm = props.getProperty(ALGORITHM_KEY); } diff --git a/src/java.base/share/classes/sun/security/validator/CADistrustPolicy.java b/src/java.base/share/classes/sun/security/validator/CADistrustPolicy.java index 17b9e7248c0..e8f821686fd 100644 --- a/src/java.base/share/classes/sun/security/validator/CADistrustPolicy.java +++ b/src/java.base/share/classes/sun/security/validator/CADistrustPolicy.java @@ -24,8 +24,6 @@ */ package sun.security.validator; -import java.security.AccessController; -import java.security.PrivilegedAction; import java.security.Security; import java.security.cert.X509Certificate; import java.util.EnumSet; @@ -86,15 +84,8 @@ abstract void checkDistrust(String variant, // The policies set in the jdk.security.caDistrustPolicies property. static final EnumSet<CADistrustPolicy> POLICIES = parseProperty(); private static EnumSet<CADistrustPolicy> parseProperty() { - @SuppressWarnings("removal") - String property = AccessController.doPrivileged( - new PrivilegedAction<>() { - @Override - public String run() { - return Security.getProperty( - "jdk.security.caDistrustPolicies"); - } - }); + String property = Security.getProperty( + "jdk.security.caDistrustPolicies"); EnumSet<CADistrustPolicy> set = EnumSet.noneOf(CADistrustPolicy.class); // if property is null or empty, the restrictions are not enforced if (property == null || property.isEmpty()) { diff --git a/src/java.base/share/classes/sun/security/validator/PKIXValidator.java b/src/java.base/share/classes/sun/security/validator/PKIXValidator.java index 8c70907279d..7cbca031cdb 100644 --- a/src/java.base/share/classes/sun/security/validator/PKIXValidator.java +++ b/src/java.base/share/classes/sun/security/validator/PKIXValidator.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -29,7 +29,6 @@ import java.security.cert.*; import java.util.*; import javax.security.auth.x500.X500Principal; -import sun.security.action.GetBooleanAction; import sun.security.provider.certpath.AlgorithmChecker; import sun.security.provider.certpath.PKIXExtendedParameters; import sun.security.util.SecurityProperties; @@ -56,8 +55,8 @@ public final class PKIXValidator extends Validator { * manager. Typically, this will only work if the PKIX implementation * supports CRL distribution points as we do not manually set up CertStores. */ - private static final boolean checkTLSRevocation = GetBooleanAction - .privilegedGetProperty("com.sun.net.ssl.checkRevocation"); + private static final boolean checkTLSRevocation = + Boolean.getBoolean("com.sun.net.ssl.checkRevocation"); /** * System or security property that if set (or set to "true"), allows trust @@ -67,7 +66,7 @@ public final class PKIXValidator extends Validator { private static final boolean ALLOW_NON_CA_ANCHOR = allowNonCaAnchor(); private static boolean allowNonCaAnchor() { String prop = SecurityProperties - .privilegedGetOverridable("jdk.security.allowNonCaAnchor"); + .getOverridableProperty("jdk.security.allowNonCaAnchor"); return prop != null && (prop.isEmpty() || prop.equalsIgnoreCase("true")); } diff --git a/src/java.base/share/classes/sun/security/x509/AVA.java b/src/java.base/share/classes/sun/security/x509/AVA.java index b1143600d6b..f5d8008fbb0 100644 --- a/src/java.base/share/classes/sun/security/x509/AVA.java +++ b/src/java.base/share/classes/sun/security/x509/AVA.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1996, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -33,7 +33,6 @@ import static java.nio.charset.StandardCharsets.UTF_8; -import sun.security.action.GetBooleanAction; import sun.security.util.*; import sun.security.pkcs.PKCS9Attribute; @@ -64,8 +63,8 @@ public class AVA implements DerEncoder { // See CR 6391482: if enabled this flag preserves the old but incorrect // PrintableString encoding for DomainComponent. It may need to be set to // avoid breaking preexisting certificates generated with sun.security APIs. - private static final boolean PRESERVE_OLD_DC_ENCODING = GetBooleanAction - .privilegedGetProperty("com.sun.security.preserveOldDCEncoding"); + private static final boolean PRESERVE_OLD_DC_ENCODING = + Boolean.getBoolean("com.sun.security.preserveOldDCEncoding"); /** * DEFAULT format allows both RFC1779 and RFC2253 syntax and From 9458a4355fc0778311c19e67abdbd2c7fadd15e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hannes=20Walln=C3=B6fer?= <hannesw@openjdk.org> Date: Tue, 26 Nov 2024 18:50:50 +0000 Subject: [PATCH 258/311] 8318416: Superscript marks should use consistent font style Reviewed-by: liach --- .../formats/html/HtmlDocletWriter.java | 30 +++++------- .../doclets/formats/html/HtmlLinkFactory.java | 16 ++++--- .../doclets/formats/html/ModuleWriter.java | 6 +-- .../doclets/formats/html/Signatures.java | 8 ++-- .../formats/html/markup/HtmlStyles.java | 10 ++++ .../formats/html/resources/stylesheet.css | 22 ++++++--- .../jdk/javadoc/internal/html/HtmlTree.java | 45 ++---------------- .../doclet/testErasure/TestErasure.java | 8 ++-- .../doclet/testPreview/TestPreview.java | 47 ++++++++++++------- .../doclet/testRestricted/TestRestricted.java | 22 +++++---- 10 files changed, 104 insertions(+), 110 deletions(-) diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlDocletWriter.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlDocletWriter.java index 9bb1ebaaf62..3f20c7dfd76 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlDocletWriter.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlDocletWriter.java @@ -791,19 +791,16 @@ public Content getPackageLink(PackageElement packageElement, Content label, Stri } if (targetLink != null) { if (flags.contains(ElementFlag.PREVIEW)) { - return new ContentBuilder( - links.createLink(targetLink, label), - HtmlTree.SUP(links.createLink(targetLink.withFragment(htmlIds.forPreviewSection(packageElement).name()), - contents.previewMark)) - ); + return new ContentBuilder(links.createLink(targetLink, label), + HtmlTree.SUP(HtmlStyles.previewMark, + links.createLink(targetLink.withFragment(htmlIds.forPreviewSection(packageElement).name()), + contents.previewMark))); } return links.createLink(targetLink, label); } else { if (flags.contains(ElementFlag.PREVIEW)) { - return new ContentBuilder( - label, - HtmlTree.SUP(contents.previewMark) - ); + return new ContentBuilder(label, + HtmlTree.SUP(HtmlStyles.previewMark, contents.previewMark)); } return label; } @@ -835,19 +832,16 @@ public Content getModuleLink(ModuleElement mdle, Content label, String fragment) targetLink = new DocLink(pathToRoot.resolve(docPaths.moduleSummary(mdle)), fragment); Content link = links.createLink(targetLink, label, ""); if (flags.contains(ElementFlag.PREVIEW) && label != contents.moduleLabel) { - link = new ContentBuilder( - link, - HtmlTree.SUP(links.createLink(targetLink.withFragment(htmlIds.forPreviewSection(mdle).name()), - contents.previewMark)) - ); + link = new ContentBuilder(link, + HtmlTree.SUP(HtmlStyles.previewMark, + links.createLink(targetLink.withFragment(htmlIds.forPreviewSection(mdle).name()), + contents.previewMark))); } return link; } if (flags.contains(ElementFlag.PREVIEW)) { - return new ContentBuilder( - label, - HtmlTree.SUP(contents.previewMark) - ); + return new ContentBuilder(label, + HtmlTree.SUP(HtmlStyles.previewMark, contents.previewMark)); } return label; } diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlLinkFactory.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlLinkFactory.java index bf210b91ea6..cca5c821c67 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlLinkFactory.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlLinkFactory.java @@ -43,6 +43,7 @@ import javax.lang.model.type.WildcardType; import javax.lang.model.util.SimpleTypeVisitor14; +import jdk.javadoc.internal.doclets.formats.html.markup.HtmlStyles; import jdk.javadoc.internal.doclets.toolkit.BaseConfiguration; import jdk.javadoc.internal.doclets.toolkit.Resources; import jdk.javadoc.internal.doclets.toolkit.util.DocPath; @@ -53,7 +54,6 @@ import jdk.javadoc.internal.html.ContentBuilder; import jdk.javadoc.internal.html.Entity; import jdk.javadoc.internal.html.HtmlId; -import jdk.javadoc.internal.html.HtmlTag; import jdk.javadoc.internal.html.HtmlTree; import jdk.javadoc.internal.html.Text; @@ -337,16 +337,18 @@ private void addSuperscript(Content content, Set<ElementFlag> flags, DocPath fil Element previewTarget, ExecutableElement restrictedTarget) { Content spacer = Text.EMPTY; if (flags.contains(ElementFlag.PREVIEW)) { - content.add(HtmlTree.SUP(getSuperscript(fileName, typeElement, - m_writer.htmlIds.forPreviewSection(previewTarget), - m_writer.contents.previewMark))); + content.add(HtmlTree.SUP(HtmlStyles.previewMark, + getSuperscript(fileName, typeElement, + m_writer.htmlIds.forPreviewSection(previewTarget), + m_writer.contents.previewMark))); spacer = Entity.NO_BREAK_SPACE; } if (flags.contains(ElementFlag.RESTRICTED)) { content.add(spacer); - content.add(HtmlTree.SUP(getSuperscript(fileName, typeElement, - m_writer.htmlIds.forRestrictedSection(restrictedTarget), - m_writer.contents.restrictedMark))); + content.add(HtmlTree.SUP(HtmlStyles.restrictedMark, + getSuperscript(fileName, typeElement, + m_writer.htmlIds.forRestrictedSection(restrictedTarget), + m_writer.contents.restrictedMark))); } } diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ModuleWriter.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ModuleWriter.java index 793f619035a..cf4876f7421 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ModuleWriter.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ModuleWriter.java @@ -42,7 +42,6 @@ import com.sun.source.doctree.DeprecatedTree; import com.sun.source.doctree.DocTree; import java.util.function.Predicate; -import java.util.stream.Collectors; import jdk.javadoc.doclet.DocletEnvironment.ModuleMode; import jdk.javadoc.internal.doclets.formats.html.Navigation.PageMode; @@ -614,8 +613,9 @@ protected void addPackagesSummary(Content summariesList) { String aepPreviewText = resources.getText("doclet.Indirect_Exports_Summary"); ContentBuilder tableCaption = new ContentBuilder( Text.of(aepPreviewText), - HtmlTree.SUP(links.createLink(previewRequiresTransitiveId, - contents.previewMark))); + HtmlTree.SUP(HtmlStyles.previewMark, + links.createLink(previewRequiresTransitiveId, + contents.previewMark))); var aepPreviewTable = getTable2(tableCaption, indirectPackagesHeader); addIndirectPackages(aepPreviewTable, indirectPackages, m -> m.equals(javaBase)); diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/Signatures.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/Signatures.java index f1e26879ef4..872fb2dcabe 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/Signatures.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/Signatures.java @@ -48,7 +48,6 @@ import jdk.javadoc.internal.html.Content; import jdk.javadoc.internal.html.ContentBuilder; import jdk.javadoc.internal.html.Entity; -import jdk.javadoc.internal.html.HtmlTag; import jdk.javadoc.internal.html.HtmlTree; import jdk.javadoc.internal.html.Text; @@ -242,9 +241,10 @@ private Content markPreviewModifiers(List<String> modifiers) { } content.add(modifier); if (previewModifiers.contains(modifier)) { - content.add(HtmlTree.SUP(writer.links.createLink( - configuration.htmlIds.forPreviewSection(typeElement), - configuration.contents.previewMark))); + content.add(HtmlTree.SUP(HtmlStyles.previewMark, + writer.links.createLink( + configuration.htmlIds.forPreviewSection(typeElement), + configuration.contents.previewMark))); } sep = " "; } diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/markup/HtmlStyles.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/markup/HtmlStyles.java index e13ed9393a3..6199e6a72a3 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/markup/HtmlStyles.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/markup/HtmlStyles.java @@ -687,6 +687,16 @@ public enum HtmlStyles implements HtmlStyle { */ permits, + /** + * The class used for a {@code sup} element marking an element as preview feature. + */ + previewMark, + + /** + * The class used for a {@code sup} element marking a method as restricted. + */ + restrictedMark, + /** * The class of a {@code span} containing the return type in the signature of a method element. */ diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/stylesheet.css b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/stylesheet.css index 641a6684444..f8c9b38f122 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/stylesheet.css +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/stylesheet.css @@ -30,10 +30,11 @@ /* Text colors for body and block elements */ --body-text-color: #282828; --block-text-color: #282828; - /* Background colors for various structural elements */ + /* Background colors for various elements */ --body-background-color: #ffffff; --section-background-color: #f8f8f8; --detail-background-color: #ffffff; + --mark-background-color: #f7f7f7; /* Colors for navigation bar and table captions */ --navbar-background-color: #4D7A97; --navbar-text-color: #ffffff; @@ -141,8 +142,7 @@ ul { code, tt { font-family:var(--code-font-family); } -:not(h1, h2, h3, h4, h5, h6) > code, -:not(h1, h2, h3, h4, h5, h6) > tt { +:not(h1, h2, h3, h4, h5, h6, sup, sub, small, big) > :is(code, tt) { font-size:var(--code-font-size); line-height:1.4em; } @@ -157,9 +157,6 @@ dt code { vertical-align:top; padding-top:4px; } -sup { - font-size:8px; -} button { font-family: var(--body-font-family); font-size: 1em; @@ -823,6 +820,19 @@ div.block { .package-hierarchy-label, .type-name-label, .type-name-link, .search-tag-link, .preview-label, .restricted-label { font-weight:bold; } +sup.preview-mark, +sup.restricted-mark { + font-family: var(--code-font-family); + font-weight: normal; + font-size: 8px; + background-color: var(--mark-background-color); + padding: 1px; + border-radius: 2px; +} +sup.preview-mark > a:link, +sup.restricted-mark > a:link { + font-weight: normal; +} .deprecation-comment, .help-footnote, .preview-comment, .restricted-comment { font-style:italic; } diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/html/HtmlTree.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/html/HtmlTree.java index f1ca45cc040..4c2477babf5 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/html/HtmlTree.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/html/HtmlTree.java @@ -1048,54 +1048,15 @@ public static HtmlTree SUMMARY(Content body) { } /** - * Creates an HTML {@code SUP} element with the given content. - * - * @param body the content - * @return the element - */ - public static HtmlTree SUP(Content body) { - return new HtmlTree(HtmlTag.SUP) - .add(body); - } - - /** - * Creates an HTML {@code TD} element with the given style and some content. - * - * @param style the style - * @param body the content - * @return the element - */ - public static HtmlTree TD(HtmlStyle style, Content body) { - return new HtmlTree(HtmlTag.TD) - .setStyle(style) - .add(body); - } - - /** - * Creates an HTML {@code TH} element with the given style and scope, and some content. + * Creates an HTML {@code SUP} element with the given style and content. * * @param style the style - * @param scope the value for the {@code scope} attribute * @param body the content * @return the element */ - public static HtmlTree TH(HtmlStyle style, String scope, Content body) { - return new HtmlTree(HtmlTag.TH) + public static HtmlTree SUP(HtmlStyle style, Content body) { + return new HtmlTree(HtmlTag.SUP) .setStyle(style) - .put(HtmlAttr.SCOPE, scope) - .add(body); - } - - /** - * Creates an HTML {@code TH} element with the given scope, and some content. - * - * @param scope the value for the {@code scope} attribute - * @param body the content - * @return the element - */ - public static HtmlTree TH(String scope, Content body) { - return new HtmlTree(HtmlTag.TH) - .put(HtmlAttr.SCOPE, scope) .add(body); } diff --git a/test/langtools/jdk/javadoc/doclet/testErasure/TestErasure.java b/test/langtools/jdk/javadoc/doclet/testErasure/TestErasure.java index ee2ec08b884..416d0cd2ec2 100644 --- a/test/langtools/jdk/javadoc/doclet/testErasure/TestErasure.java +++ b/test/langtools/jdk/javadoc/doclet/testErasure/TestErasure.java @@ -364,23 +364,23 @@ class Y { } checkExit(Exit.OK); checkOutput("preview-list.html", true, """ <div class="col-summary-item-name even-row-color method method-tab1">\ - <a href="java.base/p/Foo.html#m(T)">p.Foo.m<wbr>(T)</a><sup>\ + <a href="java.base/p/Foo.html#m(T)">p.Foo.m<wbr>(T)</a><sup class="preview-mark">\ <a href="java.base/p/Foo.html#preview-m(T)">PREVIEW</a></sup></div> <div class="col-second even-row-color method method-tab1">Test Feature</div> <div class="col-last even-row-color method method-tab1"></div> <div class="col-summary-item-name odd-row-color method method-tab1">\ - <a href="java.base/p/Foo.html#m(p.Y)">p.Foo.m<wbr>(T)</a><sup>\ + <a href="java.base/p/Foo.html#m(p.Y)">p.Foo.m<wbr>(T)</a><sup class="preview-mark">\ <a href="java.base/p/Foo.html#preview-m(p.Y)">PREVIEW</a></sup></div> <div class="col-second odd-row-color method method-tab1">Test Feature</div> <div class="col-last odd-row-color method method-tab1"></div>"""); checkOutput("preview-list.html", true, """ <div class="col-summary-item-name even-row-color constructor constructor-tab1">\ - <a href="java.base/p/Foo.html#%3Cinit%3E(T)">p.Foo<wbr>(T)</a><sup>\ + <a href="java.base/p/Foo.html#%3Cinit%3E(T)">p.Foo<wbr>(T)</a><sup class="preview-mark">\ <a href="java.base/p/Foo.html#preview-%3Cinit%3E(T)">PREVIEW</a></sup></div> <div class="col-second even-row-color constructor constructor-tab1">Test Feature</div> <div class="col-last even-row-color constructor constructor-tab1"></div> <div class="col-summary-item-name odd-row-color constructor constructor-tab1">\ - <a href="java.base/p/Foo.html#%3Cinit%3E(p.Y)">p.Foo<wbr>(T)</a><sup>\ + <a href="java.base/p/Foo.html#%3Cinit%3E(p.Y)">p.Foo<wbr>(T)</a><sup class="preview-mark">\ <a href="java.base/p/Foo.html#preview-%3Cinit%3E(p.Y)">PREVIEW</a></sup></div> <div class="col-second odd-row-color constructor constructor-tab1">Test Feature</div> <div class="col-last odd-row-color constructor constructor-tab1"></div>"""); diff --git a/test/langtools/jdk/javadoc/doclet/testPreview/TestPreview.java b/test/langtools/jdk/javadoc/doclet/testPreview/TestPreview.java index 79658e4c606..7022b02ee88 100644 --- a/test/langtools/jdk/javadoc/doclet/testPreview/TestPreview.java +++ b/test/langtools/jdk/javadoc/doclet/testPreview/TestPreview.java @@ -24,7 +24,7 @@ /* * @test * @bug 8250768 8261976 8277300 8282452 8287597 8325325 8325874 8297879 - * 8331947 8281533 + * 8331947 8281533 8318416 * @summary test generated docs for items declared using preview * @library ../../lib * @modules jdk.javadoc/jdk.javadoc.internal.tool @@ -59,7 +59,10 @@ public void testUserJavadoc() { checkOutput("m/pkg/TestPreviewDeclarationUse.html", true, "<code><a href=\"TestPreviewDeclaration.html\" title=\"interface in pkg\">TestPreviewDeclaration</a></code>"); checkOutput("m/pkg/TestPreviewAPIUse.html", true, - "<a href=\"" + doc + "java.base/preview/Core.html\" title=\"class or interface in preview\" class=\"external-link\">Core</a><sup><a href=\"" + doc + "java.base/preview/Core.html#preview-preview.Core\" title=\"class or interface in preview\" class=\"external-link\">PREVIEW</a>"); + "<a href=\"" + doc + "java.base/preview/Core.html\" title=\"class or interface in preview\" class=" + + "\"external-link\">Core</a><sup class=\"preview-mark\"><a href=\"" + doc + "java.base/pr" + + "eview/Core.html#preview-preview.Core\" title=\"class or interface in preview\" class=\"" + + "external-link\">PREVIEW</a>"); checkOutput("m/pkg/DocAnnotation.html", true, "<span class=\"modifiers\">public @interface </span><span class=\"element-name type-name-label\">DocAnnotation</span>"); checkOutput("m/pkg/DocAnnotationUse1.html", true, @@ -106,7 +109,9 @@ public void testPreviewAPIJavadoc() { <div class="table-header col-first sort-asc" onclick="sortTable(this, 0, 3)">Package</div> <div class="table-header col-second" onclick="sortTable(this, 1, 3)">Preview Feature</div> <div class="table-header col-last">Description</div> - <div class="col-summary-item-name even-row-color package package-tab1"><a href="java.base/preview/package-summary.html">preview</a><sup><a href="java.base/preview/package-summary.html#preview-preview">PREVIEW</a></sup></div> + <div class="col-summary-item-name even-row-color package package-tab1"><a href="java.base/prev\ + iew/package-summary.html">preview</a><sup class="preview-mark"><a href="java.base/preview/pack\ + age-summary.html#preview-preview">PREVIEW</a></sup></div> <div class="col-second even-row-color package package-tab1">Test Feature</div> <div class="col-last even-row-color package package-tab1"> <div class="block">Preview package.</div> @@ -122,7 +127,9 @@ public void testPreviewAPIJavadoc() { <div class="table-header col-first sort-asc" onclick="sortTable(this, 0, 3)">Record Class</div> <div class="table-header col-second" onclick="sortTable(this, 1, 3)">Preview Feature</div> <div class="table-header col-last">Description</div> - <div class="col-summary-item-name even-row-color record-class record-class-tab1"><a href="java.base/preview/CoreRecord.html" title="class in preview">preview.CoreRecord</a><sup><a href="java.base/preview/CoreRecord.html#preview-preview.CoreRecord">PREVIEW</a></sup></div> + <div class="col-summary-item-name even-row-color record-class record-class-tab1"><a href="java\ + .base/preview/CoreRecord.html" title="class in preview">preview.CoreRecord</a><sup class="prev\ + iew-mark"><a href="java.base/preview/CoreRecord.html#preview-preview.CoreRecord">PREVIEW</a></sup></div> <div class="col-second even-row-color record-class record-class-tab1">Test Feature</div> <div class="col-last even-row-color record-class record-class-tab1"></div> </div> @@ -137,7 +144,9 @@ public void testPreviewAPIJavadoc() { <div class="table-header col-first sort-asc" onclick="sortTable(this, 0, 3)">Method</div> <div class="table-header col-second" onclick="sortTable(this, 1, 3)">Preview Feature</div> <div class="table-header col-last">Description</div> - <div class="col-summary-item-name even-row-color method method-tab1"><a href="java.base/preview/CoreRecordComponent.html#i()">preview.CoreRecordComponent.i()</a><sup><a href="java.base/preview/CoreRecordComponent.html#preview-i()">PREVIEW</a></sup></div> + <div class="col-summary-item-name even-row-color method method-tab1"><a href="java.base/previe\ + w/CoreRecordComponent.html#i()">preview.CoreRecordComponent.i()</a><sup class="preview-mark"><\ + a href="java.base/preview/CoreRecordComponent.html#preview-i()">PREVIEW</a></sup></div> <div class="col-second even-row-color method method-tab1">Test Feature</div> <div class="col-last even-row-color method method-tab1"> <div class="block">Returns the value of the <code>i</code> record component.</div> @@ -160,16 +169,16 @@ public void testPreviewAPIJavadoc() { </ol>""", """ <div class="block">Preview feature. Links: <a href="CoreRecord.html" title="cla\ - ss in preview"><code>CoreRecord</code></a><sup><a href="CoreRecord.html#preview\ - -preview.CoreRecord">PREVIEW</a></sup>, <a href="CoreRecord.html" title="class \ - in preview"><code>core record</code></a><sup><a href="CoreRecord.html#preview-p\ - review.CoreRecord">PREVIEW</a></sup>, + ss in preview"><code>CoreRecord</code></a><sup class="preview-mark"><a href="Co\ + reRecord.html#preview-preview.CoreRecord">PREVIEW</a></sup>, <a href="CoreRecor\ + d.html" title="class in preview"><code>core record</code></a><sup class="previe\ + w-mark"><a href="CoreRecord.html#preview-preview.CoreRecord">PREVIEW</a></sup>, <a href="CoreRecord.html" title="class in preview">CoreRecord</a>, <a href="Co\ reRecord.html" title="class in preview">core record</a>.</div>""", """ <li><a href="CoreRecord.html" title="class in preview"><code>CoreRecord</code><\ - /a><sup><a href="CoreRecord.html#preview-preview.CoreRecord">PREVIEW</a></sup><\ - /li> + /a><sup class="preview-mark"><a href="CoreRecord.html#preview-preview.CoreRecor\ + d">PREVIEW</a></sup></li> <li><a href="CoreRecord.html" title="class in preview">core record</a></li>"""); // 8331947: Support preview features without JEP should not be included in Preview API page @@ -188,13 +197,19 @@ public void test8277300() { checkOutput("api2/api/API.html", true, "<p><a href=\"#test()\"><code>test()</code></a></p>", "<p><a href=\"#testNoPreviewInSig()\"><code>testNoPreviewInSig()</code></a></p>", - "title=\"class or interface in java.util\" class=\"external-link\">List</a><<a href=\"API.html\" title=\"class in api\">API</a><sup><a href=\"#preview-api.API\">PREVIEW</a></sup>>"); + "title=\"class or interface in java.util\" class=\"external-link\">List</a><<a href=\"API.h" + + "tml\" title=\"class in api\">API</a><sup class=\"preview-mark\"><a href=\"#preview-" + + "api.API\">PREVIEW</a></sup>>"); checkOutput("api2/api/API2.html", true, - "<a href=\"API.html#test()\"><code>API.test()</code></a><sup><a href=\"API.html#preview-api.API\">PREVIEW</a></sup>", - "<a href=\"API.html#testNoPreviewInSig()\"><code>API.testNoPreviewInSig()</code></a><sup><a href=\"API.html#preview-api.API\">PREVIEW</a></sup>", - "<a href=\"API3.html#test()\"><code>API3.test()</code></a><sup><a href=\"API3.html#preview-test()\">PREVIEW</a></sup>"); + "<a href=\"API.html#test()\"><code>API.test()</code></a><sup class=\"preview-mark\"><a href=\"" + + "API.html#preview-api.API\">PREVIEW</a></sup>", + "<a href=\"API.html#testNoPreviewInSig()\"><code>API.testNoPreviewInSig()</code></a><sup class" + + "=\"preview-mark\"><a href=\"API.html#preview-api.API\">PREVIEW</a></sup>", + "<a href=\"API3.html#test()\"><code>API3.test()</code></a><sup class=\"preview-mark\"><a href=" + + "\"API3.html#preview-test()\">PREVIEW</a></sup>"); checkOutput("api2/api/API3.html", true, - "<div class=\"block\"><a href=\"#test()\"><code>test()</code></a><sup><a href=\"#preview-test()\">PREVIEW</a></sup></div>"); + "<div class=\"block\"><a href=\"#test()\"><code>test()</code></a><sup class=\"preview-mark\"><" + + "a href=\"#preview-test()\">PREVIEW</a></sup></div>"); } @Test diff --git a/test/langtools/jdk/javadoc/doclet/testRestricted/TestRestricted.java b/test/langtools/jdk/javadoc/doclet/testRestricted/TestRestricted.java index 05b833a55a3..3e9dc7fbf90 100644 --- a/test/langtools/jdk/javadoc/doclet/testRestricted/TestRestricted.java +++ b/test/langtools/jdk/javadoc/doclet/testRestricted/TestRestricted.java @@ -23,7 +23,7 @@ /* * @test - * @bug 8316972 8325217 + * @bug 8316972 8325217 8318416 * @summary Add javadoc support for restricted methods * @library /tools/lib ../../lib * @modules jdk.javadoc/jdk.javadoc.internal.tool @@ -92,11 +92,12 @@ public interface I { checkOutput("pkg/I.html", true, """ <ul class="tag-list-long"> - <li><a href="#restrictedMethod()"><code>restrictedMethod()</code></a><sup><a href="\ - #restricted-restrictedMethod()">RESTRICTED</a></sup></li> + <li><a href="#restrictedMethod()"><code>restrictedMethod()</code></a><sup class="re\ + stricted-mark"><a href="#restricted-restrictedMethod()">RESTRICTED</a></sup></li> <li><a href="#restrictedPreviewMethod()"><code>restrictedPreviewMethod()</code></a>\ - <sup><a href="#preview-restrictedPreviewMethod()">PREVIEW</a></sup> <sup><a hr\ - ef="#restricted-restrictedPreviewMethod()">RESTRICTED</a></sup></li>""", + <sup class="preview-mark"><a href="#preview-restrictedPreviewMethod()">PREVIEW</a><\ + /sup> <sup class="restricted-mark"><a href="#restricted-restrictedPreviewMetho\ + d()">RESTRICTED</a></sup></li>""", """ <div class="block"><span class="restricted-label">Restricted.</span></div> <div class="block">Restricted method.</div>""", @@ -157,15 +158,16 @@ public interface I { <div class="table-header col-first">Method</div> <div class="table-header col-last">Description</div> <div class="col-summary-item-name even-row-color"><a href="pkg/I.html#restrictedMet\ - hod()">pkg.I.restrictedMethod()</a><sup><a href="pkg/I.html#restricted-restrictedMe\ - thod()">RESTRICTED</a></sup></div> + hod()">pkg.I.restrictedMethod()</a><sup class="restricted-mark"><a href="pkg/I.html\ + #restricted-restrictedMethod()">RESTRICTED</a></sup></div> <div class="col-last even-row-color"> <div class="block">Restricted method.</div> </div> <div class="col-summary-item-name odd-row-color"><a href="pkg/I.html#restrictedPrev\ - iewMethod()">pkg.I.restrictedPreviewMethod()</a><sup><a href="pkg/I.html#preview-re\ - strictedPreviewMethod()">PREVIEW</a></sup> <sup><a href="pkg/I.html#restricted\ - -restrictedPreviewMethod()">RESTRICTED</a></sup></div> + iewMethod()">pkg.I.restrictedPreviewMethod()</a><sup class="preview-mark"><a href="\ + pkg/I.html#preview-restrictedPreviewMethod()">PREVIEW</a></sup> <sup class="re\ + stricted-mark"><a href="pkg/I.html#restricted-restrictedPreviewMethod()">RESTRICTED\ + </a></sup></div> <div class="col-last odd-row-color"> <div class="block">Restricted preview method.</div> </div>"""); From 3689f3909ee87e79b350a739878cd0a358810c99 Mon Sep 17 00:00:00 2001 From: Sonia Zaldana Calles <szaldana@openjdk.org> Date: Tue, 26 Nov 2024 19:44:09 +0000 Subject: [PATCH 259/311] 8344013: "bad tag in log" assert with +LogCompilation +CITimeVerbose Reviewed-by: chagedorn, dfenacci --- src/hotspot/share/opto/compile.cpp | 3 ++ .../compiler/debug/TestLogStackAssert.java | 39 +++++++++++++++++++ 2 files changed, 42 insertions(+) create mode 100644 test/hotspot/jtreg/compiler/debug/TestLogStackAssert.java diff --git a/src/hotspot/share/opto/compile.cpp b/src/hotspot/share/opto/compile.cpp index 7e4760e2cd6..5eec8b2a8f0 100644 --- a/src/hotspot/share/opto/compile.cpp +++ b/src/hotspot/share/opto/compile.cpp @@ -4335,6 +4335,9 @@ Compile::TracePhase::TracePhase(PhaseTraceId id) Compile::TracePhase::~TracePhase() { if (_compile->failing_internal()) { + if (_log != nullptr) { + _log->done("phase"); + } return; // timing code, not stressing bailouts. } #ifdef ASSERT diff --git a/test/hotspot/jtreg/compiler/debug/TestLogStackAssert.java b/test/hotspot/jtreg/compiler/debug/TestLogStackAssert.java new file mode 100644 index 00000000000..042abc23fcc --- /dev/null +++ b/test/hotspot/jtreg/compiler/debug/TestLogStackAssert.java @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package compiler.debug; + +/* + * @test + * @bug 8344013 + * @requires vm.debug == true & vm.compiler2.enabled + * @summary Verify the xmlStream log stack is not left in a bad state + * @run main/othervm -XX:+LogCompilation -XX:CompileCommand=log,*.* -XX:+CITimeVerbose -Xcomp compiler.debug.TestLogStackAssert + */ +public class TestLogStackAssert { + + public static void main(String[] args) throws Exception { + System.out.println("Test passed!"); + } + +} From 5e15415cb9c051531bbd610820cf3a5343c60228 Mon Sep 17 00:00:00 2001 From: Harshitha Onkar <honkar@openjdk.org> Date: Tue, 26 Nov 2024 20:10:48 +0000 Subject: [PATCH 260/311] 8344654: Some client tests still expect a SecurityManager after JEP486 Reviewed-by: prr, azvegint --- .../java/awt/Desktop/8064934/bug8064934.java | 9 +-- .../awt/TrayIcon/SystemTrayIconHelper.java | 17 +---- .../awt/a11y/AccessibleComponentTest.java | 1 - .../Independence/IndependenceAWTTest.java | 13 +--- .../Independence/IndependenceSwingTest.java | 13 +--- .../SystemSelectionAWTTest.java | 20 +----- .../SystemSelectionSwingTest.java | 20 +----- .../ButtonArraysEquality.java | 30 ++++---- .../CheckGetMaskForButton.java | 27 +++---- .../java/awt/print/PrinterJob/PrintToDir.java | 12 ---- test/jdk/java/awt/regtesthelpers/Util.java | 42 ++++------- .../MetadataFormatThreadTest.java | 16 +---- .../BadPluginConfigurationTest.sh | 7 +- .../swing/UIDefaults/6795356/bug6795356.java | 70 ------------------- 14 files changed, 46 insertions(+), 251 deletions(-) delete mode 100644 test/jdk/javax/swing/UIDefaults/6795356/bug6795356.java diff --git a/test/jdk/java/awt/Desktop/8064934/bug8064934.java b/test/jdk/java/awt/Desktop/8064934/bug8064934.java index f3a6b4658ad..6d4ffc08f34 100644 --- a/test/jdk/java/awt/Desktop/8064934/bug8064934.java +++ b/test/jdk/java/awt/Desktop/8064934/bug8064934.java @@ -32,23 +32,16 @@ * @build jdk.test.lib.Platform * @run main bug8064934 */ -import jdk.test.lib.Platform; + import java.awt.*; import java.io.File; import java.io.IOException; -import java.security.AccessController; -import java.security.PrivilegedAction; public class bug8064934 { private static final String NO_ASSOCIATION_ERROR_MESSAGE = "Error message: No application is associated with" + " the specified file for this operation."; public static void main(String[] args) { - // This test is intended only for Windows - if (!AccessController.doPrivileged((PrivilegedAction<Boolean>) Platform::isWindows)) { - System.out.println("The test is for Windows platform only"); - return; - } // Test whether Desktop is supported of not if (!Desktop.isDesktopSupported()) { diff --git a/test/jdk/java/awt/TrayIcon/SystemTrayIconHelper.java b/test/jdk/java/awt/TrayIcon/SystemTrayIconHelper.java index ac28281a10c..eaf60655441 100644 --- a/test/jdk/java/awt/TrayIcon/SystemTrayIconHelper.java +++ b/test/jdk/java/awt/TrayIcon/SystemTrayIconHelper.java @@ -27,9 +27,6 @@ import java.awt.image.BufferedImage; import java.lang.reflect.Field; import java.lang.reflect.Method; -import java.security.AccessController; -import java.security.PrivilegedActionException; -import java.security.PrivilegedExceptionAction; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -154,17 +151,9 @@ static Point getTrayIconLocation(TrayIcon icon) throws Exception { return null; } - static Field getField(final Class clz, final String fieldName) { - Field res = null; - try { - res = (Field)AccessController.doPrivileged((PrivilegedExceptionAction) () -> { - Field f = clz.getDeclaredField(fieldName); - f.setAccessible(true); - return f; - }); - } catch (PrivilegedActionException ex) { - ex.printStackTrace(); - } + static Field getField(final Class clz, final String fieldName) throws NoSuchFieldException { + Field res = clz.getDeclaredField(fieldName); + res.setAccessible(true); return res; } diff --git a/test/jdk/java/awt/a11y/AccessibleComponentTest.java b/test/jdk/java/awt/a11y/AccessibleComponentTest.java index 86d41574d6e..ae2943d6994 100644 --- a/test/jdk/java/awt/a11y/AccessibleComponentTest.java +++ b/test/jdk/java/awt/a11y/AccessibleComponentTest.java @@ -23,7 +23,6 @@ */ import java.awt.*; -import java.security.PublicKey; import java.util.concurrent.TimeUnit; import java.util.concurrent.CountDownLatch; diff --git a/test/jdk/java/awt/datatransfer/Independence/IndependenceAWTTest.java b/test/jdk/java/awt/datatransfer/Independence/IndependenceAWTTest.java index 8a1f5f4b19c..2ace3510d1f 100644 --- a/test/jdk/java/awt/datatransfer/Independence/IndependenceAWTTest.java +++ b/test/jdk/java/awt/datatransfer/Independence/IndependenceAWTTest.java @@ -78,17 +78,6 @@ public void focusGained(FocusEvent fe) { tf1.requestFocus(); } - public void checkSecurity() { - SecurityManager sm = System.getSecurityManager(); - if (sm == null) { - System.out.println("security manager is not there"); - getPrimaryClipboard(); - } else { - sm.checkPermission(new AWTPermission("accessClipboard")); - getPrimaryClipboard(); - } - } - // Get System Selection i.e. Primary Clipboard private void getPrimaryClipboard() { Properties ps = System.getProperties(); @@ -148,7 +137,7 @@ public void compareText (boolean mustEqual) { } public void doTest() throws Exception { - checkSecurity(); + getPrimaryClipboard(); ExtendedRobot robot = new ExtendedRobot(); robot.waitForIdle(1000); frame.setLocation(100, 100); diff --git a/test/jdk/java/awt/datatransfer/Independence/IndependenceSwingTest.java b/test/jdk/java/awt/datatransfer/Independence/IndependenceSwingTest.java index 550151c0906..4ee7dea6a54 100644 --- a/test/jdk/java/awt/datatransfer/Independence/IndependenceSwingTest.java +++ b/test/jdk/java/awt/datatransfer/Independence/IndependenceSwingTest.java @@ -85,17 +85,6 @@ public void focusGained(FocusEvent fe) { tf1.requestFocus(); } - public void checkSecurity() { - SecurityManager sm = System.getSecurityManager(); - if (sm == null) { - System.out.println("security manager is not there"); - getPrimaryClipboard(); - } else { - sm.checkPermission(new AWTPermission("accessClipboard")); - getPrimaryClipboard(); - } - } - // Get System Selection i.e. Primary Clipboard private void getPrimaryClipboard() { Properties ps = System.getProperties(); @@ -155,7 +144,7 @@ public void compareText (boolean mustEqual) { } public void doTest() throws Exception { - checkSecurity(); + getPrimaryClipboard(); ExtendedRobot robot = new ExtendedRobot(); robot.waitForIdle(1000); frame.setLocation(100, 100); diff --git a/test/jdk/java/awt/datatransfer/SystemSelection/SystemSelectionAWTTest.java b/test/jdk/java/awt/datatransfer/SystemSelection/SystemSelectionAWTTest.java index 281ee41f4c7..9d80f0bb676 100644 --- a/test/jdk/java/awt/datatransfer/SystemSelection/SystemSelectionAWTTest.java +++ b/test/jdk/java/awt/datatransfer/SystemSelection/SystemSelectionAWTTest.java @@ -74,24 +74,6 @@ public void focusGained(FocusEvent fe) { tf1.setText("Selection Testing"); } - // Check whether Security manager is there - public void checkSecurity() { - SecurityManager sm = System.getSecurityManager(); - - if (sm == null) { - System.out.println("security manager is not there"); - getPrimaryClipboard(); - } else { - try { - sm.checkPermission(new AWTPermission("accessClipboard")); - getPrimaryClipboard(); - } catch(SecurityException e) { - clip = null; - System.out.println("Access to System selection is not allowed"); - } - } - } - // Get the contents from the clipboard void getClipboardContent() throws Exception { t = clip.getContents(this); @@ -134,7 +116,7 @@ public void doTest() throws Exception { Point tf1Location = tf1.getLocationOnScreen(); Dimension tf1Size = tf1.getSize(); - checkSecurity(); + getPrimaryClipboard(); if (clip != null) { robot.mouseMove(tf1Location.x + 5, tf1Location.y + tf1Size.height / 2); diff --git a/test/jdk/java/awt/datatransfer/SystemSelection/SystemSelectionSwingTest.java b/test/jdk/java/awt/datatransfer/SystemSelection/SystemSelectionSwingTest.java index 00ecf6fab77..4c409a66408 100644 --- a/test/jdk/java/awt/datatransfer/SystemSelection/SystemSelectionSwingTest.java +++ b/test/jdk/java/awt/datatransfer/SystemSelection/SystemSelectionSwingTest.java @@ -75,24 +75,6 @@ public void focusGained(FocusEvent fe) { jtf1.setText("Selection Testing"); } - // Check whether Security manager is there - public void checkSecurity() { - SecurityManager sm = System.getSecurityManager(); - - if (sm == null) { - System.out.println("security manager is not there"); - getPrimaryClipboard(); - } else { - try { - sm.checkPermission(new AWTPermission("accessClipboard")); - getPrimaryClipboard(); - } catch(SecurityException e) { - clip = null; - System.out.println("Access to System selection is not allowed"); - } - } - } - // Get the contents from the clipboard void getClipboardContent() throws Exception { t = clip.getContents(this); @@ -136,7 +118,7 @@ public void doTest() throws Exception { Point tf1Location = jtf1.getLocationOnScreen(); Dimension tf1Size = jtf1.getSize(); - checkSecurity(); + getPrimaryClipboard(); if (clip != null) { robot.mouseMove(tf1Location.x + 5, tf1Location.y + tf1Size.height / 2); diff --git a/test/jdk/java/awt/event/InputEvent/ButtonArraysEquality/ButtonArraysEquality.java b/test/jdk/java/awt/event/InputEvent/ButtonArraysEquality/ButtonArraysEquality.java index 384a4ea43a6..718891c21fa 100644 --- a/test/jdk/java/awt/event/InputEvent/ButtonArraysEquality/ButtonArraysEquality.java +++ b/test/jdk/java/awt/event/InputEvent/ButtonArraysEquality/ButtonArraysEquality.java @@ -34,8 +34,6 @@ import java.awt.*; import java.awt.event.*; import java.lang.reflect.*; -import java.security.AccessController; -import java.security.PrivilegedAction; // get array InputEvent.BUTTON_MASK via reflection // get array InputEvent.BUTTON_DOWN_MASK via reflection @@ -52,22 +50,18 @@ public static void main(String []s){ } // getButtonDownMasks() - Object obj = AccessController.doPrivileged( - new PrivilegedAction() { - public Object run() { - try { - Class clazz = Class.forName("java.awt.event.InputEvent"); - Method method = clazz.getDeclaredMethod("getButtonDownMasks",new Class [] {}); - if (method != null) { - method.setAccessible(true); - return method.invoke(null, (Object[])null); - } - }catch (Exception e){ - throw new RuntimeException("Test failed. Exception occured:", e); - } - return null; - } - }); + Object obj = null; + + try { + Class clazz = Class.forName("java.awt.event.InputEvent"); + Method method = clazz.getDeclaredMethod("getButtonDownMasks",new Class [] {}); + if (method != null) { + method.setAccessible(true); + obj = method.invoke(null, (Object[])null); + } + } catch (Exception e) { + throw new RuntimeException("Test failed. Exception occurred:", e); + } int [] buttonDownMasks = new int [Array.getLength(obj)]; checkNullAndPutValuesToArray(buttonDownMasks, obj); diff --git a/test/jdk/java/awt/event/MouseEvent/CheckGetMaskForButton/CheckGetMaskForButton.java b/test/jdk/java/awt/event/MouseEvent/CheckGetMaskForButton/CheckGetMaskForButton.java index 8770a72eae5..fa3f7d9b315 100644 --- a/test/jdk/java/awt/event/MouseEvent/CheckGetMaskForButton/CheckGetMaskForButton.java +++ b/test/jdk/java/awt/event/MouseEvent/CheckGetMaskForButton/CheckGetMaskForButton.java @@ -34,8 +34,6 @@ import java.awt.*; import java.awt.event.InputEvent; import java.lang.reflect.*; -import java.security.AccessController; -import java.security.PrivilegedAction; public class CheckGetMaskForButton{ static Robot robot; @@ -50,22 +48,17 @@ public static void main(String []s){ } //get same array via reflection - Object obj = AccessController.doPrivileged( - new PrivilegedAction() { - public Object run() { - try { - Class clazz = Class.forName("java.awt.event.InputEvent"); - Method method = clazz.getDeclaredMethod("getButtonDownMasks",new Class [] {}); - if (method != null) { - method.setAccessible(true); - return method.invoke(null, (Object[])null); - } - }catch (Exception e){ - throw new RuntimeException("Test failed. Exception occured:", e); - } - return null; + Object obj = null; + try { + Class clazz = Class.forName("java.awt.event.InputEvent"); + Method method = clazz.getDeclaredMethod("getButtonDownMasks",new Class [] {}); + if (method != null) { + method.setAccessible(true); + obj = method.invoke(null, (Object[])null); } - }); + } catch (Exception e) { + throw new RuntimeException("Test failed. Exception occured:", e); + } if (obj == null){ throw new RuntimeException("Test failed. The value obtained via reflection is "+obj); diff --git a/test/jdk/java/awt/print/PrinterJob/PrintToDir.java b/test/jdk/java/awt/print/PrinterJob/PrintToDir.java index 4f76647b563..f451f8362e3 100644 --- a/test/jdk/java/awt/print/PrinterJob/PrintToDir.java +++ b/test/jdk/java/awt/print/PrinterJob/PrintToDir.java @@ -37,7 +37,6 @@ import javax.print.PrintService; import javax.print.attribute.*; import javax.print.attribute.standard.*; -import java.util.PropertyPermission; public class PrintToDir extends Frame implements Printable { @@ -122,17 +121,6 @@ public static void doPrinterJob(String fileStr, OrientationRequested o) { public static void main(String arg[]) { - SecurityManager security = System.getSecurityManager(); - if (security != null) { - System.out.println("Security manager detected"); - try { - security.checkPermission(new FilePermission("<<ALL FILES>>", "read,write")); - security.checkPermission(new PropertyPermission("user.dir", "read")); - } catch (SecurityException se) { - System.out.println("Security requirement not obtained. TEST PASSED"); - return; - } - } String[] testStr = {".", ""}; for (int i=0; i<testStr.length; i++) { System.out.println("Testing file name = \""+testStr[i]+"\""); diff --git a/test/jdk/java/awt/regtesthelpers/Util.java b/test/jdk/java/awt/regtesthelpers/Util.java index 265c5517dd7..5de2743d312 100644 --- a/test/jdk/java/awt/regtesthelpers/Util.java +++ b/test/jdk/java/awt/regtesthelpers/Util.java @@ -68,9 +68,6 @@ import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; -import java.security.PrivilegedAction; -import java.security.AccessController; - import java.util.concurrent.atomic.AtomicBoolean; public final class Util { @@ -452,32 +449,19 @@ public static int getWMID() { Method m_addExports = Class.forName("java.awt.Helper").getDeclaredMethod("addExports", String.class, java.lang.Module.class); // We may be called from non-X11 system, and this permission cannot be delegated to a test. m_addExports.invoke(null, "sun.awt.X11", Util.class.getModule()); - @SuppressWarnings("removal") - Method m_getWMID = (Method)AccessController.doPrivileged(new PrivilegedAction() { - public Object run() { - try { - Method method = _clazz.getDeclaredMethod("getWMID", new Class[] {}); - if (method != null) { - method.setAccessible(true); - } - return method; - } catch (NoSuchMethodException e) { - assert false; - } catch (SecurityException e) { - assert false; - } - return null; - } - }); - return ((Integer)m_getWMID.invoke(null, new Object[] {})).intValue(); - } catch (ClassNotFoundException cnfe) { - cnfe.printStackTrace(); - } catch (NoSuchMethodException nsme) { - nsme.printStackTrace(); - } catch (IllegalAccessException iae) { - iae.printStackTrace(); - } catch (InvocationTargetException ite) { - ite.printStackTrace(); + Method m_getWMID = null; + try { + m_getWMID = _clazz.getDeclaredMethod("getWMID", new Class[] {}); + if (m_getWMID != null) { + m_getWMID.setAccessible(true); + } + } catch (NoSuchMethodException e) { + assert false; + } + return (Integer) m_getWMID.invoke(null, new Object[]{}); + } catch (ClassNotFoundException | NoSuchMethodException + | IllegalAccessException | InvocationTargetException e) { + e.printStackTrace(); } return -1; } diff --git a/test/jdk/javax/imageio/metadata/IIOMetadataFormat/MetadataFormatThreadTest.java b/test/jdk/javax/imageio/metadata/IIOMetadataFormat/MetadataFormatThreadTest.java index 2731b83257e..ef39bb74115 100644 --- a/test/jdk/javax/imageio/metadata/IIOMetadataFormat/MetadataFormatThreadTest.java +++ b/test/jdk/javax/imageio/metadata/IIOMetadataFormat/MetadataFormatThreadTest.java @@ -57,13 +57,7 @@ public MetadataFormatThreadTest(String c) { public void run() { try { - ClassLoader loader = (ClassLoader) - java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction() { - public Object run() { - return Thread.currentThread().getContextClassLoader(); - } - }); + ClassLoader loader = (ClassLoader) Thread.currentThread().getContextClassLoader(); Class ct = loader.loadClass(test_class); @@ -84,13 +78,7 @@ protected static Thread createTest(String codebase, final ClassLoader loader = new URLClassLoader(urls); final Thread t = new Thread(new MetadataFormatThreadTest(code)); - java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction() { - public Object run() { - t.setContextClassLoader(loader); - return null; - } - }); + t.setContextClassLoader(loader); return t; } diff --git a/test/jdk/javax/imageio/spi/AppletContextTest/BadPluginConfigurationTest.sh b/test/jdk/javax/imageio/spi/AppletContextTest/BadPluginConfigurationTest.sh index 607e261aefd..66c890a1cd4 100644 --- a/test/jdk/javax/imageio/spi/AppletContextTest/BadPluginConfigurationTest.sh +++ b/test/jdk/javax/imageio/spi/AppletContextTest/BadPluginConfigurationTest.sh @@ -258,12 +258,7 @@ esac echo ------------------------------- echo --- Applet Classpath Test --- echo ------------------------------- -# -# please note that we need to use "==" in setup of the java.security.policy -# property in order to overwrite policies defined in the user policy file -# For more details see: -# http://java.sun.com/j2se/1.5.0/docs/guide/security/PolicyFiles.html) -# + ${TESTJAVA}/bin/java ${TESTVMOPTS} -cp ".${PATHSEP}${TEST_PLUGIN_JAR}" IIOPluginTest diff --git a/test/jdk/javax/swing/UIDefaults/6795356/bug6795356.java b/test/jdk/javax/swing/UIDefaults/6795356/bug6795356.java deleted file mode 100644 index 7ff527cc19d..00000000000 --- a/test/jdk/javax/swing/UIDefaults/6795356/bug6795356.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright (c) 2009, 2024, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -/* - * @test - * @bug 6795356 - * @summary Leak caused by javax.swing.UIDefaults.ProxyLazyValue.acc - * @author Alexander Potochkin - * @library ../../regtesthelpers - * @build Util - * @run main/othervm -Xmx128m bug6795356 - */ - -import java.lang.ref.WeakReference; -import java.security.ProtectionDomain; -import java.security.AccessController; -import java.security.PrivilegedAction; -import java.security.AccessControlContext; -import java.util.LinkedList; -import java.util.List; -import javax.swing.*; - -public class bug6795356 { - volatile static WeakReference<ProtectionDomain> weakRef; - - public static void main(String[] args) throws Exception { - - ProtectionDomain domain = new ProtectionDomain(null, null); - - AccessController.doPrivileged(new PrivilegedAction<Object>() { - public Object run() { - - // this initialize ProxyLazyValues - UIManager.getLookAndFeel(); - - return null; - } - }, new AccessControlContext(new ProtectionDomain[]{domain})); - - weakRef = new WeakReference<ProtectionDomain>(domain); - domain = null; - - Util.generateOOME(); - - if (weakRef.get() != null) { - throw new RuntimeException("Memory leak found!"); - } - System.out.println("Test passed"); - } -} From 1d5587b887cd3885b2b80e2334c2f3ea2de7c5f3 Mon Sep 17 00:00:00 2001 From: Phil Race <prr@openjdk.org> Date: Tue, 26 Nov 2024 20:11:52 +0000 Subject: [PATCH 261/311] 8344256: Clean up obsolete code in java.desktop/share/classes/sun/awt/datatransfer/DataTransferer.java Reviewed-by: azvegint, kizune --- .../sun/awt/datatransfer/DataTransferer.java | 109 +----------------- 1 file changed, 5 insertions(+), 104 deletions(-) diff --git a/src/java.desktop/share/classes/sun/awt/datatransfer/DataTransferer.java b/src/java.desktop/share/classes/sun/awt/datatransfer/DataTransferer.java index 5014bb78ead..568da951a7d 100644 --- a/src/java.desktop/share/classes/sun/awt/datatransfer/DataTransferer.java +++ b/src/java.desktop/share/classes/sun/awt/datatransfer/DataTransferer.java @@ -43,7 +43,6 @@ import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.File; -import java.io.FilePermission; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; @@ -62,7 +61,6 @@ import java.nio.charset.CharsetEncoder; import java.nio.charset.IllegalCharsetNameException; import java.nio.charset.UnsupportedCharsetException; -import java.security.ProtectionDomain; import java.util.AbstractMap; import java.util.ArrayList; import java.util.Arrays; @@ -756,7 +754,7 @@ public byte[] translateTransferable(Transferable contents, (String.class.equals(flavor.getRepresentationClass()) && DataFlavorUtil.isFlavorCharsetTextType(flavor) && isTextFormat(format))) { - String str = removeSuspectedData(flavor, contents, (String)obj); + String str = (String)obj; return translateTransferableString( str, @@ -869,9 +867,7 @@ public byte[] translateTransferable(Transferable contents, final List<?> list = (List<?>)obj; - final ProtectionDomain userProtectionDomain = getUserProtectionDomain(contents); - - final ArrayList<String> fileList = castToFiles(list, userProtectionDomain); + final ArrayList<String> fileList = castToFiles(list); try (ByteArrayOutputStream bos = convertFileListToBytes(fileList)) { theByteArray = bos.toByteArray(); @@ -896,8 +892,7 @@ public byte[] translateTransferable(Transferable contents, targetCharset = "UTF-8"; } final List<?> list = (List<?>)obj; - final ProtectionDomain userProtectionDomain = getUserProtectionDomain(contents); - final ArrayList<String> fileList = castToFiles(list, userProtectionDomain); + final ArrayList<String> fileList = castToFiles(list); final ArrayList<String> uriList = new ArrayList<>(fileList.size()); for (String fileObject : fileList) { final URI uri = new File(fileObject).toURI(); @@ -979,69 +974,12 @@ private static byte[] convertObjectToBytes(Object object) throws IOException { protected abstract ByteArrayOutputStream convertFileListToBytes(ArrayList<String> fileList) throws IOException; - @SuppressWarnings("removal") - private String removeSuspectedData(DataFlavor flavor, final Transferable contents, final String str) - { - if (null == System.getSecurityManager() - || !flavor.isMimeTypeEqual("text/uri-list")) - { - return str; - } - - final ProtectionDomain userProtectionDomain = getUserProtectionDomain(contents); - StringBuilder allowedFiles = new StringBuilder(str.length()); - String [] uriArray = str.split("(\\s)+"); - - for (String fileName : uriArray) - { - File file = new File(fileName); - if (file.exists() && - !(isFileInWebstartedCache(file) || - isForbiddenToRead(file, userProtectionDomain))) - { - if (0 != allowedFiles.length()) - { - allowedFiles.append("\\r\\n"); - } - - allowedFiles.append(fileName); - } - } - return allowedFiles.toString(); - } - - private static ProtectionDomain getUserProtectionDomain(Transferable contents) { - return contents.getClass().getProtectionDomain(); - } - - private boolean isForbiddenToRead (File file, ProtectionDomain protectionDomain) - { - if (null == protectionDomain) { - return false; - } - try { - FilePermission filePermission = - new FilePermission(file.getCanonicalPath(), "read, delete"); - if (protectionDomain.implies(filePermission)) { - return false; - } - } catch (IOException e) {} - - return true; - } - - @SuppressWarnings("removal") - private ArrayList<String> castToFiles(final List<?> files, - final ProtectionDomain userProtectionDomain) throws IOException { + private ArrayList<String> castToFiles(final List<?> files) throws IOException { ArrayList<String> fileList = new ArrayList<>(); for (Object fileObject : files) { File file = castToFile(fileObject); - if (file != null && - (null == System.getSecurityManager() || - !(isFileInWebstartedCache(file) || - isForbiddenToRead(file, userProtectionDomain)))) - { + if (file != null) { fileList.add(file.getCanonicalPath()); } } @@ -1062,43 +1000,6 @@ private File castToFile(Object fileObject) throws IOException { return new File(filePath); } - private static final String[] DEPLOYMENT_CACHE_PROPERTIES = { - "deployment.system.cachedir", - "deployment.user.cachedir", - "deployment.javaws.cachedir", - "deployment.javapi.cachedir" - }; - - private static final ArrayList <File> deploymentCacheDirectoryList = new ArrayList<>(); - - private static boolean isFileInWebstartedCache(File f) { - - if (deploymentCacheDirectoryList.isEmpty()) { - for (String cacheDirectoryProperty : DEPLOYMENT_CACHE_PROPERTIES) { - String cacheDirectoryPath = System.getProperty(cacheDirectoryProperty); - if (cacheDirectoryPath != null) { - try { - File cacheDirectory = (new File(cacheDirectoryPath)).getCanonicalFile(); - if (cacheDirectory != null) { - deploymentCacheDirectoryList.add(cacheDirectory); - } - } catch (IOException ioe) {} - } - } - } - - for (File deploymentCacheDirectory : deploymentCacheDirectoryList) { - for (File dir = f; dir != null; dir = dir.getParentFile()) { - if (dir.equals(deploymentCacheDirectory)) { - return true; - } - } - } - - return false; - } - - public Object translateBytes(byte[] bytes, DataFlavor flavor, long format, Transferable localeTransferable) throws IOException From 7ae6069ee8b9815a35d3b6d976b59d30c96a4837 Mon Sep 17 00:00:00 2001 From: Daniel Fuchs <dfuchs@openjdk.org> Date: Tue, 26 Nov 2024 20:47:56 +0000 Subject: [PATCH 262/311] 8344184: Remove sun.net.ResourceManager after JEP 486 integration Reviewed-by: alanb --- .../classes/sun/net/ResourceManager.java | 84 ------------------- .../sun/nio/ch/DatagramChannelImpl.java | 8 +- .../classes/sun/nio/ch/NioSocketImpl.java | 24 ++---- 3 files changed, 7 insertions(+), 109 deletions(-) delete mode 100644 src/java.base/share/classes/sun/net/ResourceManager.java diff --git a/src/java.base/share/classes/sun/net/ResourceManager.java b/src/java.base/share/classes/sun/net/ResourceManager.java deleted file mode 100644 index 6776f95c9ff..00000000000 --- a/src/java.base/share/classes/sun/net/ResourceManager.java +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright (c) 2011, 2021, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package sun.net; - -import java.net.SocketException; -import java.util.concurrent.atomic.AtomicInteger; -import sun.security.action.GetPropertyAction; - -/** - * Manages count of total number of UDP sockets and ensures - * that exception is thrown if we try to create more than the - * configured limit. - * - * This functionality could be put in NetHooks some time in future. - */ - -public class ResourceManager { - - /* default maximum number of udp sockets per VM - * when a security manager is enabled. - * The default is 25 which is high enough to be useful - * but low enough to be well below the maximum number - * of port numbers actually available on all OSes - * when multiplied by the maximum feasible number of VM processes - * that could practically be spawned. - */ - - private static final int DEFAULT_MAX_SOCKETS = 25; - private static final int maxSockets; - private static final AtomicInteger numSockets; - - static { - String prop = GetPropertyAction - .privilegedGetProperty("sun.net.maxDatagramSockets"); - int defmax = DEFAULT_MAX_SOCKETS; - try { - if (prop != null) { - defmax = Integer.parseInt(prop); - } - } catch (NumberFormatException e) {} - maxSockets = defmax; - numSockets = new AtomicInteger(); - } - - @SuppressWarnings("removal") - public static void beforeUdpCreate() throws SocketException { - if (System.getSecurityManager() != null) { - if (numSockets.incrementAndGet() > maxSockets) { - numSockets.decrementAndGet(); - throw new SocketException("maximum number of DatagramSockets reached"); - } - } - } - - @SuppressWarnings("removal") - public static void afterUdpClose() { - if (System.getSecurityManager() != null) { - numSockets.decrementAndGet(); - } - } -} diff --git a/src/java.base/share/classes/sun/nio/ch/DatagramChannelImpl.java b/src/java.base/share/classes/sun/nio/ch/DatagramChannelImpl.java index 33948afbcb0..ae8fd00a318 100644 --- a/src/java.base/share/classes/sun/nio/ch/DatagramChannelImpl.java +++ b/src/java.base/share/classes/sun/nio/ch/DatagramChannelImpl.java @@ -73,7 +73,6 @@ import jdk.internal.access.SharedSecrets; import jdk.internal.ref.CleanerFactory; import jdk.internal.invoke.MhUtil; -import sun.net.ResourceManager; import sun.net.ext.ExtendedSocketOptions; import sun.net.util.IPAddressUtil; @@ -194,7 +193,6 @@ class DatagramChannelImpl FileDescriptor fd = null; NativeSocketAddress[] sockAddrs = null; - ResourceManager.beforeUdpCreate(); boolean initialized = false; try { this.interruptible = interruptible; @@ -217,7 +215,6 @@ class DatagramChannelImpl if (!initialized) { if (sockAddrs != null) NativeSocketAddress.freeAll(sockAddrs); if (fd != null) nd.close(fd); - ResourceManager.afterUdpClose(); } } @@ -232,7 +229,6 @@ class DatagramChannelImpl NativeSocketAddress[] sockAddrs = null; - ResourceManager.beforeUdpCreate(); boolean initialized = false; try { this.interruptible = true; @@ -257,7 +253,6 @@ class DatagramChannelImpl if (!initialized) { if (sockAddrs != null) NativeSocketAddress.freeAll(sockAddrs); nd.close(fd); - ResourceManager.afterUdpClose(); } } @@ -1909,8 +1904,7 @@ private static Runnable releaserFor(FileDescriptor fd, NativeSocketAddress... so } catch (IOException ioe) { throw new UncheckedIOException(ioe); } finally { - // decrement socket count and release memory - ResourceManager.afterUdpClose(); + // release memory NativeSocketAddress.freeAll(sockAddrs); } }; diff --git a/src/java.base/share/classes/sun/nio/ch/NioSocketImpl.java b/src/java.base/share/classes/sun/nio/ch/NioSocketImpl.java index b9885a36fa8..40bc3156680 100644 --- a/src/java.base/share/classes/sun/nio/ch/NioSocketImpl.java +++ b/src/java.base/share/classes/sun/nio/ch/NioSocketImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -57,7 +57,6 @@ import sun.net.ConnectionResetException; import sun.net.NetHooks; import sun.net.PlatformSocketImpl; -import sun.net.ResourceManager; import sun.net.ext.ExtendedSocketOptions; import sun.net.util.SocketExceptions; @@ -455,20 +454,12 @@ protected void create(boolean stream) throws IOException { synchronized (stateLock) { if (state != ST_NEW) throw new IOException("Already created"); - if (!stream) - ResourceManager.beforeUdpCreate(); FileDescriptor fd; - try { - if (server) { - assert stream; - fd = Net.serverSocket(true); - } else { - fd = Net.socket(stream); - } - } catch (IOException ioe) { - if (!stream) - ResourceManager.afterUdpClose(); - throw ioe; + if (server) { + assert stream; + fd = Net.serverSocket(true); + } else { + fd = Net.socket(stream); } Runnable closer = closerFor(fd, stream); this.fd = fd; @@ -1221,9 +1212,6 @@ private static Runnable closerFor(FileDescriptor fd, boolean stream) { nd.close(fd); } catch (IOException ioe) { throw new UncheckedIOException(ioe); - } finally { - // decrement - ResourceManager.afterUdpClose(); } }; } From 8da6435d4d2b94b72d2f3872f2fd2cc71a66499a Mon Sep 17 00:00:00 2001 From: Yudi Zheng <yzheng@openjdk.org> Date: Tue, 26 Nov 2024 20:50:49 +0000 Subject: [PATCH 263/311] 8343693: [JVMCI] Override ModifiersProvider.isConcrete in ResolvedJavaType to be isArray() || !isAbstract() Reviewed-by: never --- .../classes/jdk/vm/ci/meta/ModifiersProvider.java | 8 +++++--- .../share/classes/jdk/vm/ci/meta/ResolvedJavaType.java | 5 +++++ .../jdk/vm/ci/runtime/test/TestResolvedJavaType.java | 10 ++++++++++ 3 files changed, 20 insertions(+), 3 deletions(-) diff --git a/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/ModifiersProvider.java b/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/ModifiersProvider.java index 637cb65111c..2a193cc79b3 100644 --- a/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/ModifiersProvider.java +++ b/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/ModifiersProvider.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -137,9 +137,11 @@ default boolean isAbstract() { } /** - * Checks that the method is concrete and not abstract. + * Returns true if this element is a method with a concrete implementation, or a type that can + * be instantiated. For example, array types return true for both {@link #isAbstract()} and this + * method. * - * @return whether the method is a concrete method + * @see ResolvedJavaType#isConcrete() */ default boolean isConcrete() { return !isAbstract(); diff --git a/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/ResolvedJavaType.java b/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/ResolvedJavaType.java index fff2a6dc2b2..272f821b7ca 100644 --- a/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/ResolvedJavaType.java +++ b/src/jdk.internal.vm.ci/share/classes/jdk/vm/ci/meta/ResolvedJavaType.java @@ -402,4 +402,9 @@ default ResolvedJavaType lookupType(UnresolvedJavaType unresolvedJavaType, boole default ResolvedJavaField resolveField(UnresolvedJavaField unresolvedJavaField, ResolvedJavaType accessingClass) { return null; } + + @Override + default boolean isConcrete() { + return isArray() || !isAbstract(); + } } diff --git a/test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/TestResolvedJavaType.java b/test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/TestResolvedJavaType.java index 9540b965520..14dbcdd6989 100644 --- a/test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/TestResolvedJavaType.java +++ b/test/hotspot/jtreg/compiler/jvmci/jdk.vm.ci.runtime.test/src/jdk/vm/ci/runtime/test/TestResolvedJavaType.java @@ -196,6 +196,16 @@ public void isArrayTest() { } } + @Test + public void isConcreteTest() { + for (Class<?> c : classes) { + ResolvedJavaType type = metaAccess.lookupJavaType(c); + boolean expected = c.isArray() || !isAbstract(c.getModifiers()); + boolean actual = type.isConcrete(); + assertEquals(expected, actual); + } + } + @Test public void lambdaInternalNameTest() { // Verify that the last dot in lambda types is properly handled when transitioning from From 8389e24d388f3761a6963503955207a574c1bbd3 Mon Sep 17 00:00:00 2001 From: Vicente Romero <vromero@openjdk.org> Date: Tue, 26 Nov 2024 20:53:12 +0000 Subject: [PATCH 264/311] 8345058: Javac issues different error messages for the modifiers of the requires directive Reviewed-by: mcimadamore --- .../sun/tools/javac/parser/JavacParser.java | 3 ++ .../javac/modules/RequiresTransitiveTest.java | 35 +++++++++++++++++++ 2 files changed, 38 insertions(+) diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/JavacParser.java b/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/JavacParser.java index 0bbcd56293f..c55c2db98de 100644 --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/JavacParser.java +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/parser/JavacParser.java @@ -4215,6 +4215,9 @@ List<JCDirective> moduleDirectiveList() { } isTransitive = true; break; + } else if (token.name() == names.transitive && isTransitive) { + log.error(DiagnosticFlag.SYNTAX, token.pos, Errors.RepeatedModifier); + break; } else { break loop; } diff --git a/test/langtools/tools/javac/modules/RequiresTransitiveTest.java b/test/langtools/tools/javac/modules/RequiresTransitiveTest.java index cae6bd7fb03..6ff0dabec1f 100644 --- a/test/langtools/tools/javac/modules/RequiresTransitiveTest.java +++ b/test/langtools/tools/javac/modules/RequiresTransitiveTest.java @@ -221,4 +221,39 @@ public class C7 { }"""); return src; } + + @Test + public void testRepeatedModifiers(Path base) throws Exception { + Path src = base.resolve("src"); + Path src_m1 = src.resolve("m1"); + tb.writeJavaFiles(src_m1, + """ + module m1 { + requires static static java.sql; + requires transitive transitive java.desktop; + } + """ + ); + Path classes = base.resolve("classes"); + Files.createDirectories(classes); + + String log = new JavacTask(tb, Task.Mode.CMDLINE) + .options("-XDrawDiagnostics", + "--module-source-path", src.toString()) + .files(findJavaFiles(src)) + .outdir(classes) + .run(Task.Expect.FAIL) + .writeAll() + .getOutput(Task.OutputKind.DIRECT); + + String[] expect = { + "module-info.java:2:21: compiler.err.repeated.modifier", + "module-info.java:3:25: compiler.err.repeated.modifier" + }; + + for (String e: expect) { + if (!log.contains(e)) + throw new Exception("expected output not found: " + e); + } + } } From 8c2b4f62714f26ab3bc4808c734502af632a1eef Mon Sep 17 00:00:00 2001 From: Valerie Peng <valeriep@openjdk.org> Date: Tue, 26 Nov 2024 21:08:57 +0000 Subject: [PATCH 265/311] 8345057: ML_KEM NamedParameterSpec constants removed by ML-DSA integration Reviewed-by: mullan, hchao --- .../security/spec/NamedParameterSpec.java | 24 +++++++ .../security/spec/TestNamedParameterSpec.java | 69 +++++++++++++++++++ .../sun/security/provider/acvp/Launcher.java | 2 +- .../security/provider/acvp/ML_DSA_Test.java | 12 +++- .../security/provider/acvp/ML_KEM_Test.java | 11 ++- 5 files changed, 115 insertions(+), 3 deletions(-) create mode 100644 test/jdk/java/security/spec/TestNamedParameterSpec.java diff --git a/src/java.base/share/classes/java/security/spec/NamedParameterSpec.java b/src/java.base/share/classes/java/security/spec/NamedParameterSpec.java index 48a177f8c1c..d50426b6ccf 100644 --- a/src/java.base/share/classes/java/security/spec/NamedParameterSpec.java +++ b/src/java.base/share/classes/java/security/spec/NamedParameterSpec.java @@ -92,6 +92,30 @@ public class NamedParameterSpec implements AlgorithmParameterSpec { public static final NamedParameterSpec ML_DSA_87 = new NamedParameterSpec("ML-DSA-87"); + /** + * The ML-KEM-512 parameters + * + * @since 24 + */ + public static final NamedParameterSpec ML_KEM_512 + = new NamedParameterSpec("ML-KEM-512"); + + /** + * The ML-KEM-768 parameters + * + * @since 24 + */ + public static final NamedParameterSpec ML_KEM_768 + = new NamedParameterSpec("ML-KEM-768"); + + /** + * The ML-KEM-1024 parameters + * + * @since 24 + */ + public static final NamedParameterSpec ML_KEM_1024 + = new NamedParameterSpec("ML-KEM-1024"); + private final String name; /** diff --git a/test/jdk/java/security/spec/TestNamedParameterSpec.java b/test/jdk/java/security/spec/TestNamedParameterSpec.java new file mode 100644 index 00000000000..0da8b78bf5d --- /dev/null +++ b/test/jdk/java/security/spec/TestNamedParameterSpec.java @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8345057 + * @summary Test the existence of constants inside the + * java.security.spec.NamedParameterSpec class. + * @run main TestNamedParameterSpec + */ +import java.lang.reflect.Field; +import java.lang.reflect.Modifier; +import java.security.spec.NamedParameterSpec; +import java.util.Arrays; +import java.util.TreeSet; + +public class TestNamedParameterSpec { + + // names of the static fields in NamedParameterSpec class + private static String[] EXPECTED = { + "ED25519", "ED448", "X25519", "X448", + "ML_DSA_44", "ML_DSA_65", "ML_DSA_87", + "ML_KEM_512", "ML_KEM_768", "ML_KEM_1024", + }; + + public static void main(String[] args) throws Exception { + Arrays.sort(EXPECTED); + var actual = getSortedConstNames(NamedParameterSpec.class); + // both arrays should be sorted before comparison + if (Arrays.compare(EXPECTED, actual) != 0) { + System.out.println("expected: " + Arrays.toString(EXPECTED)); + System.out.println("actual: " + Arrays.toString(actual)); + throw new RuntimeException("Name check failed"); + } + System.out.println("Test Passed"); + } + + public static String[] getSortedConstNames(Class<?> clazz) { + TreeSet<String> names = new TreeSet<String>(); + for (Field field : clazz.getDeclaredFields()) { + int mods = field.getModifiers(); + if (Modifier.isPublic(mods) && Modifier.isStatic(mods) + && Modifier.isFinal(mods)){ + names.add(field.getName()); + } + } + return names.toArray(new String[0]); + } +} diff --git a/test/jdk/sun/security/provider/acvp/Launcher.java b/test/jdk/sun/security/provider/acvp/Launcher.java index 5a2ef1233f2..b5c5908a902 100644 --- a/test/jdk/sun/security/provider/acvp/Launcher.java +++ b/test/jdk/sun/security/provider/acvp/Launcher.java @@ -30,7 +30,7 @@ /* * @test - * @bug 8342442 + * @bug 8342442 8345057 * @library /test/lib */ diff --git a/test/jdk/sun/security/provider/acvp/ML_DSA_Test.java b/test/jdk/sun/security/provider/acvp/ML_DSA_Test.java index 6d402516410..87bd304518f 100644 --- a/test/jdk/sun/security/provider/acvp/ML_DSA_Test.java +++ b/test/jdk/sun/security/provider/acvp/ML_DSA_Test.java @@ -43,6 +43,16 @@ public static void run(JSONValue kat, Provider provider) throws Exception { } } + static NamedParameterSpec genParams(String pname) { + return switch (pname) { + case "ML-DSA-44" -> NamedParameterSpec.ML_DSA_44; + case "ML-DSA-65" -> NamedParameterSpec.ML_DSA_65; + case "ML-DSA-87" -> NamedParameterSpec.ML_DSA_87; + default -> throw new RuntimeException("Unknown params: " + pname); + + }; + } + static void keyGenTest(JSONValue kat, Provider p) throws Exception { var g = p == null ? KeyPairGenerator.getInstance("ML-DSA") @@ -52,7 +62,7 @@ static void keyGenTest(JSONValue kat, Provider p) throws Exception { : KeyFactory.getInstance("ML-DSA", p); for (var t : kat.get("testGroups").asArray()) { var pname = t.get("parameterSet").asString(); - var np = new NamedParameterSpec(pname); + var np = genParams(pname); System.out.println(">> " + pname); for (var c : t.get("tests").asArray()) { System.out.print(c.get("tcId").asString() + " "); diff --git a/test/jdk/sun/security/provider/acvp/ML_KEM_Test.java b/test/jdk/sun/security/provider/acvp/ML_KEM_Test.java index 5b707bee6d8..46f394adbdf 100644 --- a/test/jdk/sun/security/provider/acvp/ML_KEM_Test.java +++ b/test/jdk/sun/security/provider/acvp/ML_KEM_Test.java @@ -43,6 +43,15 @@ public static void run(JSONValue kat, Provider provider) throws Exception { } } + static NamedParameterSpec genParams(String pname) { + return switch (pname) { + case "ML-KEM-512" -> NamedParameterSpec.ML_KEM_512; + case "ML-KEM-768" -> NamedParameterSpec.ML_KEM_768; + case "ML-KEM-1024" -> NamedParameterSpec.ML_KEM_1024; + default -> throw new RuntimeException("Unknown params: " + pname); + }; + } + static void keyGenTest(JSONValue kat, Provider p) throws Exception { var g = p == null ? KeyPairGenerator.getInstance("ML-KEM") @@ -52,7 +61,7 @@ static void keyGenTest(JSONValue kat, Provider p) throws Exception { : KeyFactory.getInstance("ML-KEM", p); for (var t : kat.get("testGroups").asArray()) { var pname = t.get("parameterSet").asString(); - var np = new NamedParameterSpec(pname); + var np = genParams(pname); System.out.println(">> " + pname); for (var c : t.get("tests").asArray()) { System.out.print(c.get("tcId").asString() + " "); From 28c8729019292820f17002cc007305418f2d2676 Mon Sep 17 00:00:00 2001 From: Joe Wang <joehw@openjdk.org> Date: Tue, 26 Nov 2024 22:59:49 +0000 Subject: [PATCH 266/311] 8343004: Adjust JAXP limits Reviewed-by: lancea, rriggs --- .../impl/XML11NSDocumentScannerImpl.java | 7 +- .../impl/XMLDocumentFragmentScannerImpl.java | 9 +- .../internal/impl/XMLEntityManager.java | 3 +- .../internal/impl/XMLEntityScanner.java | 6 +- .../impl/XMLNSDocumentScannerImpl.java | 7 +- .../xerces/internal/impl/XMLScanner.java | 8 +- .../internal/impl/msg/XMLMessages.properties | 4 +- .../jdk/xml/internal/XMLSecurityManager.java | 18 +- src/java.xml/share/classes/module-info.java | 30 +- .../conf/jaxp-strict.properties.template | 8 +- src/java.xml/share/conf/jaxp.properties | 30 +- .../common/config/ConfigFileTest.java | 65 +- .../common/config/ConfigurationTest.java | 10 +- .../common/config/ImplProperties.java | 112 + .../parsers/Bug4674384_MAX_OCCURS_Test.java | 69 - .../parsers/Bug4674384_MAX_OCCURS_Test.xml | 8 - .../parsers/Bug4674384_MAX_OCCURS_Test.xsd | 15 - .../xml/jaxp/unittest/parsers/Bug6309988.java | 369 --- .../xml/jaxp/unittest/parsers/DosTest.xml | 2031 ----------------- .../xml/jaxp/unittest/parsers/DosTest3.xml | 42 - .../xml/jaxp/unittest/parsers/entity.xml | 8 - .../xml/jaxp/unittest/parsers/entity64K.xml | 4 - .../EventsTest/EventFilterSupportTest.java | 3 +- 23 files changed, 207 insertions(+), 2659 deletions(-) create mode 100644 test/jaxp/javax/xml/jaxp/unittest/common/config/ImplProperties.java delete mode 100644 test/jaxp/javax/xml/jaxp/unittest/parsers/Bug4674384_MAX_OCCURS_Test.java delete mode 100644 test/jaxp/javax/xml/jaxp/unittest/parsers/Bug4674384_MAX_OCCURS_Test.xml delete mode 100644 test/jaxp/javax/xml/jaxp/unittest/parsers/Bug4674384_MAX_OCCURS_Test.xsd delete mode 100644 test/jaxp/javax/xml/jaxp/unittest/parsers/Bug6309988.java delete mode 100644 test/jaxp/javax/xml/jaxp/unittest/parsers/DosTest.xml delete mode 100644 test/jaxp/javax/xml/jaxp/unittest/parsers/DosTest3.xml delete mode 100644 test/jaxp/javax/xml/jaxp/unittest/parsers/entity.xml delete mode 100644 test/jaxp/javax/xml/jaxp/unittest/parsers/entity64K.xml diff --git a/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/XML11NSDocumentScannerImpl.java b/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/XML11NSDocumentScannerImpl.java index 576dffba177..5e8d16ea3a9 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/XML11NSDocumentScannerImpl.java +++ b/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/XML11NSDocumentScannerImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -70,7 +70,7 @@ * @author Michael Glavassevich, IBM * @author Sunitha Reddy, Sun Microsystems * - * @LastModified: July 2023 + * @LastModified: Nov 2024 */ public class XML11NSDocumentScannerImpl extends XML11DocumentScannerImpl { @@ -203,7 +203,8 @@ protected boolean scanStartElement() throws IOException, XNIException { fAttributes.getLength() > fElementAttributeLimit){ fErrorReporter.reportError(XMLMessageFormatter.XML_DOMAIN, "ElementAttributeLimit", - new Object[]{rawname, fElementAttributeLimit }, + new Object[]{rawname, fElementAttributeLimit, + XMLSecurityManager.Limit.ELEMENT_ATTRIBUTE_LIMIT.systemProperty() }, XMLErrorReporter.SEVERITY_FATAL_ERROR ); } diff --git a/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/XMLDocumentFragmentScannerImpl.java b/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/XMLDocumentFragmentScannerImpl.java index b77108b1e0e..7d6e940f993 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/XMLDocumentFragmentScannerImpl.java +++ b/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/XMLDocumentFragmentScannerImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved. */ /* @@ -74,7 +74,7 @@ * @author Eric Ye, IBM * @author Sunitha Reddy, SUN Microsystems * - * @LastModified: Nov 2023 + * @LastModified: Nov 2024 */ public class XMLDocumentFragmentScannerImpl extends XMLScanner @@ -1374,7 +1374,8 @@ protected boolean scanStartElement() fAttributes.getLength() > fElementAttributeLimit){ fErrorReporter.reportError(XMLMessageFormatter.XML_DOMAIN, "ElementAttributeLimit", - new Object[]{rawname, fElementAttributeLimit }, + new Object[]{rawname, fElementAttributeLimit, + XMLSecurityManager.Limit.ELEMENT_ATTRIBUTE_LIMIT.systemProperty() }, XMLErrorReporter.SEVERITY_FATAL_ERROR ); } @@ -1885,7 +1886,7 @@ void checkDepth(String elementName) { reportFatalError("MaxElementDepthLimit", new Object[]{elementName, fLimitAnalyzer.getTotalValue(Limit.MAX_ELEMENT_DEPTH_LIMIT), fSecurityManager.getLimit(Limit.MAX_ELEMENT_DEPTH_LIMIT), - "maxElementDepth"}); + Limit.MAX_ELEMENT_DEPTH_LIMIT.systemProperty()}); } } diff --git a/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/XMLEntityManager.java b/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/XMLEntityManager.java index e6ad6229224..aa7b62151d1 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/XMLEntityManager.java +++ b/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/XMLEntityManager.java @@ -1462,7 +1462,8 @@ public void startEntity(boolean isGE, String name, if( fSecurityManager != null && fSecurityManager.isOverLimit(entityExpansionIndex, fLimitAnalyzer)){ fSecurityManager.debugPrint(fLimitAnalyzer); fErrorReporter.reportError(XMLMessageFormatter.XML_DOMAIN,"EntityExpansionLimit", - new Object[]{fSecurityManager.getLimitValueByIndex(entityExpansionIndex)}, + new Object[]{fSecurityManager.getLimitValueByIndex(entityExpansionIndex), + Limit.ENTITY_EXPANSION_LIMIT.systemProperty()}, XMLErrorReporter.SEVERITY_FATAL_ERROR ); // is there anything better to do than reset the counter? // at least one can envision debugging applications where this might diff --git a/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/XMLEntityScanner.java b/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/XMLEntityScanner.java index 265f4ec6508..6514fd7d907 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/XMLEntityScanner.java +++ b/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/XMLEntityScanner.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved. */ /* @@ -57,7 +57,7 @@ * @author Arnaud Le Hors, IBM * @author K.Venugopal Sun Microsystems * - * @LastModified: July 2023 + * @LastModified: Nov 2024 */ public class XMLEntityScanner implements XMLLocator { @@ -1009,7 +1009,7 @@ protected void checkLimit(Limit limit, ScannedEntity entity, int offset, int len fErrorReporter.reportError(XMLMessageFormatter.XML_DOMAIN, "TotalEntitySizeLimit", new Object[]{fLimitAnalyzer.getTotalValue(Limit.TOTAL_ENTITY_SIZE_LIMIT), fSecurityManager.getLimit(Limit.TOTAL_ENTITY_SIZE_LIMIT), - fSecurityManager.getStateLiteral(Limit.TOTAL_ENTITY_SIZE_LIMIT)}, + Limit.TOTAL_ENTITY_SIZE_LIMIT.systemProperty()}, XMLErrorReporter.SEVERITY_FATAL_ERROR); } } diff --git a/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/XMLNSDocumentScannerImpl.java b/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/XMLNSDocumentScannerImpl.java index 1942510e9b7..c79ff92b1bc 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/XMLNSDocumentScannerImpl.java +++ b/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/XMLNSDocumentScannerImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -54,7 +54,7 @@ * @author Venugopal Rao K, Sun Microsystems * @author Elena Litani, IBM * - * @LastModified: July 2023 + * @LastModified: Nov 2024 */ public class XMLNSDocumentScannerImpl extends XMLDocumentScannerImpl { @@ -253,7 +253,8 @@ protected boolean scanStartElement() fAttributes.getLength() > fElementAttributeLimit){ fErrorReporter.reportError(XMLMessageFormatter.XML_DOMAIN, "ElementAttributeLimit", - new Object[]{rawname, fElementAttributeLimit }, + new Object[]{rawname, fElementAttributeLimit, + XMLSecurityManager.Limit.ELEMENT_ATTRIBUTE_LIMIT.systemProperty() }, XMLErrorReporter.SEVERITY_FATAL_ERROR ); } diff --git a/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/XMLScanner.java b/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/XMLScanner.java index 70084c08214..7099b68b8d6 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/XMLScanner.java +++ b/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/XMLScanner.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2003, 2024, Oracle and/or its affiliates. All rights reserved. */ /* * Licensed to the Apache Software Foundation (ASF) under one or more @@ -67,7 +67,7 @@ * @author Eric Ye, IBM * @author K.Venugopal SUN Microsystems * @author Sunitha Reddy, SUN Microsystems - * @LastModified: July 2023 + * @LastModified: Nov 2024 */ public abstract class XMLScanner implements XMLComponent { @@ -1527,7 +1527,7 @@ void checkEntityLimit(boolean isPEDecl, String entityName, int len) { reportFatalError("MaxEntitySizeLimit", new Object[]{"%" + entityName, fLimitAnalyzer.getValue(XMLSecurityManager.Limit.PARAMETER_ENTITY_SIZE_LIMIT), fSecurityManager.getLimit(XMLSecurityManager.Limit.PARAMETER_ENTITY_SIZE_LIMIT), - fSecurityManager.getStateLiteral(XMLSecurityManager.Limit.PARAMETER_ENTITY_SIZE_LIMIT)}); + XMLSecurityManager.Limit.PARAMETER_ENTITY_SIZE_LIMIT.systemProperty()}); } } else { fLimitAnalyzer.addValue(XMLSecurityManager.Limit.GENERAL_ENTITY_SIZE_LIMIT, entityName, len); @@ -1536,7 +1536,7 @@ void checkEntityLimit(boolean isPEDecl, String entityName, int len) { reportFatalError("MaxEntitySizeLimit", new Object[]{entityName, fLimitAnalyzer.getValue(XMLSecurityManager.Limit.GENERAL_ENTITY_SIZE_LIMIT), fSecurityManager.getLimit(XMLSecurityManager.Limit.GENERAL_ENTITY_SIZE_LIMIT), - fSecurityManager.getStateLiteral(XMLSecurityManager.Limit.GENERAL_ENTITY_SIZE_LIMIT)}); + XMLSecurityManager.Limit.GENERAL_ENTITY_SIZE_LIMIT.systemProperty()}); } } if (fSecurityManager.isOverLimit(XMLSecurityManager.Limit.TOTAL_ENTITY_SIZE_LIMIT, fLimitAnalyzer)) { diff --git a/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages.properties b/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages.properties index 78a34631d0b..146a4abd170 100644 --- a/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages.properties +++ b/src/java.xml/share/classes/com/sun/org/apache/xerces/internal/impl/msg/XMLMessages.properties @@ -315,8 +315,8 @@ # Implementation limits - EntityExpansionLimit=JAXP00010001: The parser has encountered more than \"{0}\" entity expansions in this document; this is the limit imposed by the JDK. - ElementAttributeLimit=JAXP00010002: Element \"{0}\" has more than \"{1}\" attributes, \"{1}\" is the limit imposed by the JDK. + EntityExpansionLimit=JAXP00010001: The parser has encountered more than \"{0}\" entity expansions in this document; this is the limit imposed by \"{1}\". + ElementAttributeLimit=JAXP00010002: Element \"{0}\" has more than \"{1}\" attributes, \"{1}\" is the limit set by \"{2}\". MaxEntitySizeLimit=JAXP00010003: The length of entity \"{0}\" is \"{1}\" that exceeds the \"{2}\" limit set by \"{3}\". TotalEntitySizeLimit=JAXP00010004: The accumulated size of entities is \"{0}\" that exceeded the \"{1}\" limit set by \"{2}\". MaxXMLNameLimit=JAXP00010005: The length of entity \"{0}\" is \"{1}\" that exceeds the \"{2}\" limit set by \"{3}\". diff --git a/src/java.xml/share/classes/jdk/xml/internal/XMLSecurityManager.java b/src/java.xml/share/classes/jdk/xml/internal/XMLSecurityManager.java index cace5492d69..394bf28e02a 100644 --- a/src/java.xml/share/classes/jdk/xml/internal/XMLSecurityManager.java +++ b/src/java.xml/share/classes/jdk/xml/internal/XMLSecurityManager.java @@ -100,23 +100,23 @@ public final class XMLSecurityManager { @SuppressWarnings("deprecation") public static enum Limit { ENTITY_EXPANSION_LIMIT("EntityExpansionLimit", JdkConstants.JDK_ENTITY_EXPANSION_LIMIT, - JdkConstants.SP_ENTITY_EXPANSION_LIMIT, JdkConstants.ENTITY_EXPANSION_LIMIT, 0, 64000, Processor.PARSER, INTMAPPER), + JdkConstants.SP_ENTITY_EXPANSION_LIMIT, JdkConstants.ENTITY_EXPANSION_LIMIT, 2500, 2500, Processor.PARSER, INTMAPPER), MAX_OCCUR_NODE_LIMIT("MaxOccurLimit", JdkConstants.JDK_MAX_OCCUR_LIMIT, - JdkConstants.SP_MAX_OCCUR_LIMIT, JdkConstants.MAX_OCCUR_LIMIT, 0, 5000, Processor.PARSER, INTMAPPER), + JdkConstants.SP_MAX_OCCUR_LIMIT, JdkConstants.MAX_OCCUR_LIMIT, 5000, 5000, Processor.PARSER, INTMAPPER), ELEMENT_ATTRIBUTE_LIMIT("ElementAttributeLimit", JdkConstants.JDK_ELEMENT_ATTRIBUTE_LIMIT, - JdkConstants.SP_ELEMENT_ATTRIBUTE_LIMIT, JdkConstants.ELEMENT_ATTRIBUTE_LIMIT, 0, 10000, Processor.PARSER, INTMAPPER), + JdkConstants.SP_ELEMENT_ATTRIBUTE_LIMIT, JdkConstants.ELEMENT_ATTRIBUTE_LIMIT, 200, 200, Processor.PARSER, INTMAPPER), TOTAL_ENTITY_SIZE_LIMIT("TotalEntitySizeLimit", JdkConstants.JDK_TOTAL_ENTITY_SIZE_LIMIT, - JdkConstants.SP_TOTAL_ENTITY_SIZE_LIMIT, null, 0, 50000000, Processor.PARSER, INTMAPPER), + JdkConstants.SP_TOTAL_ENTITY_SIZE_LIMIT, null, 100000, 100000, Processor.PARSER, INTMAPPER), GENERAL_ENTITY_SIZE_LIMIT("MaxEntitySizeLimit", JdkConstants.JDK_GENERAL_ENTITY_SIZE_LIMIT, - JdkConstants.SP_GENERAL_ENTITY_SIZE_LIMIT, null, 0, 0, Processor.PARSER, INTMAPPER), - PARAMETER_ENTITY_SIZE_LIMIT("MaxEntitySizeLimit", JdkConstants.JDK_PARAMETER_ENTITY_SIZE_LIMIT, - JdkConstants.SP_PARAMETER_ENTITY_SIZE_LIMIT, null, 0, 1000000, Processor.PARSER, INTMAPPER), + JdkConstants.SP_GENERAL_ENTITY_SIZE_LIMIT, null, 100000, 100000, Processor.PARSER, INTMAPPER), + PARAMETER_ENTITY_SIZE_LIMIT("MaxParameterEntitySizeLimit", JdkConstants.JDK_PARAMETER_ENTITY_SIZE_LIMIT, + JdkConstants.SP_PARAMETER_ENTITY_SIZE_LIMIT, null, 15000, 15000, Processor.PARSER, INTMAPPER), MAX_ELEMENT_DEPTH_LIMIT("MaxElementDepthLimit", JdkConstants.JDK_MAX_ELEMENT_DEPTH, - JdkConstants.SP_MAX_ELEMENT_DEPTH, null, 0, 0, Processor.PARSER, INTMAPPER), + JdkConstants.SP_MAX_ELEMENT_DEPTH, null, 100, 100, Processor.PARSER, INTMAPPER), MAX_NAME_LIMIT("MaxXMLNameLimit", JdkConstants.JDK_XML_NAME_LIMIT, JdkConstants.SP_XML_NAME_LIMIT, null, 1000, 1000, Processor.PARSER, INTMAPPER), ENTITY_REPLACEMENT_LIMIT("EntityReplacementLimit", JdkConstants.JDK_ENTITY_REPLACEMENT_LIMIT, - JdkConstants.SP_ENTITY_REPLACEMENT_LIMIT, null, 0, 3000000, Processor.PARSER, INTMAPPER), + JdkConstants.SP_ENTITY_REPLACEMENT_LIMIT, null, 100000, 100000, Processor.PARSER, INTMAPPER), XPATH_GROUP_LIMIT("XPathGroupLimit", JdkConstants.XPATH_GROUP_LIMIT, JdkConstants.XPATH_GROUP_LIMIT, null, 10, 10, Processor.XPATH, INTMAPPER), XPATH_OP_LIMIT("XPathExprOpLimit", JdkConstants.XPATH_OP_LIMIT, diff --git a/src/java.xml/share/classes/module-info.java b/src/java.xml/share/classes/module-info.java index 78ae9561519..e5c421261b0 100644 --- a/src/java.xml/share/classes/module-info.java +++ b/src/java.xml/share/classes/module-info.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -602,8 +602,8 @@ * A positive integer. A value less than or equal to 0 indicates no limit. * If the value is not an integer, a NumberFormatException is thrown. * </td> - * <td style="text-align:center">64000</td> - * <td style="text-align:center">64000</td> + * <td style="text-align:center">2500</td> + * <td style="text-align:center">2500</td> * <td style="text-align:center" rowspan="9">Yes</td> * <td style="text-align:center" rowspan="9"> * <a href="#DOM">DOM</a><br> @@ -619,8 +619,8 @@ * <td id="EALimit">{@systemProperty jdk.xml.elementAttributeLimit}</td> * <td>Limits the number of attributes an element can have. * </td> - * <td style="text-align:center">10000</td> - * <td style="text-align:center">10000</td> + * <td style="text-align:center">200</td> + * <td style="text-align:center">200</td> * </tr> * <tr> * <td id="OccurLimit">{@systemProperty jdk.xml.maxOccurLimit}</td> @@ -636,37 +636,37 @@ * <td>Limits the total size of all entities that include general and parameter * entities. The size is calculated as an aggregation of all entities. * </td> - * <td style="text-align:center">5x10^7</td> - * <td style="text-align:center">5x10^7</td> + * <td style="text-align:center">100000</td> + * <td style="text-align:center">100000</td> * </tr> * <tr> * <td id="GELimit">{@systemProperty jdk.xml.maxGeneralEntitySizeLimit}</td> * <td>Limits the maximum size of any general entities. * </td> - * <td style="text-align:center">0</td> - * <td style="text-align:center">0</td> + * <td style="text-align:center">100000</td> + * <td style="text-align:center">100000</td> * </tr> * <tr> * <td id="PELimit">{@systemProperty jdk.xml.maxParameterEntitySizeLimit}</td> * <td>Limits the maximum size of any parameter entities, including the result * of nesting multiple parameter entities. * </td> - * <td style="text-align:center">10^6</td> - * <td style="text-align:center">10^6</td> + * <td style="text-align:center">15000</td> + * <td style="text-align:center">15000</td> * </tr> * <tr> * <td id="ERLimit">{@systemProperty jdk.xml.entityReplacementLimit}</td> * <td>Limits the total number of nodes in all entity references. * </td> - * <td style="text-align:center">3x10^6</td> - * <td style="text-align:center">3x10^6</td> + * <td style="text-align:center">100000</td> + * <td style="text-align:center">100000</td> * </tr> * <tr> * <td id="ElementDepth">{@systemProperty jdk.xml.maxElementDepth}</td> * <td>Limits the maximum element depth. * </td> - * <td style="text-align:center">0</td> - * <td style="text-align:center">0</td> + * <td style="text-align:center">100</td> + * <td style="text-align:center">100</td> * </tr> * <tr> * <td id="NameLimit">{@systemProperty jdk.xml.maxXMLNameLimit}</td> diff --git a/src/java.xml/share/conf/jaxp-strict.properties.template b/src/java.xml/share/conf/jaxp-strict.properties.template index 2d6cbc951e2..7bacd042046 100644 --- a/src/java.xml/share/conf/jaxp-strict.properties.template +++ b/src/java.xml/share/conf/jaxp-strict.properties.template @@ -95,16 +95,16 @@ jdk.xml.maxParameterEntitySizeLimit=15000 # Limits the total number of nodes in all entity references. jdk.xml.entityReplacementLimit=100000 # -# Limits the number of attributes an element can have. The default value is 10000. -jdk.xml.elementAttributeLimit=10000 +# Limits the number of attributes an element can have. The default value is 200. +jdk.xml.elementAttributeLimit=200 # # Limits the number of content model nodes that may be created when building a # grammar for a W3C XML Schema that contains maxOccurs attributes with values # other than "unbounded". The default value is 5000. jdk.xml.maxOccurLimit=5000 # -# Limits the maximum element depth. The default value is 0. -jdk.xml.maxElementDepth=0 +# Limits the maximum element depth. The default value is 100. +jdk.xml.maxElementDepth=100 # # Limits the maximum size of XML names, including element name, attribute name # and namespace prefix and URI. The default value is 1000. diff --git a/src/java.xml/share/conf/jaxp.properties b/src/java.xml/share/conf/jaxp.properties index 53835f63743..b011586c13c 100644 --- a/src/java.xml/share/conf/jaxp.properties +++ b/src/java.xml/share/conf/jaxp.properties @@ -156,33 +156,33 @@ jdk.xml.dtd.support=allow # Limits have a value type Integer. The values must be positive integers. Zero # means no limit. # -# Limits the number of entity expansions. The default value is 64000 -# jdk.xml.entityExpansionLimit=64000 +# Limits the number of entity expansions. The default value is 2500 +jdk.xml.entityExpansionLimit=2500 # # Limits the total size of all entities that include general and parameter entities. -# The size is calculated as an aggregation of all entities. The default value is 5x10^7. -# jdk.xml.totalEntitySizeLimit=50000000 +# The size is calculated as an aggregation of all entities. The default value is 100000. +jdk.xml.totalEntitySizeLimit=100000 # -# Limits the maximum size of any general entities. The default value is 0. -# jdk.xml.maxGeneralEntitySizeLimit=0 +# Limits the maximum size of any general entities. The default value is 100000. +jdk.xml.maxGeneralEntitySizeLimit=100000 # # Limits the maximum size of any parameter entities, including the result of -# nesting multiple parameter entities. The default value is 10^6. -# jdk.xml.maxParameterEntitySizeLimit=1000000 +# nesting multiple parameter entities. The default value is 15000. +jdk.xml.maxParameterEntitySizeLimit=15000 # -# Limits the total number of nodes in all entity references. The default value is 3x10^6. -# jdk.xml.entityReplacementLimit=3000000 +# Limits the total number of nodes in all entity references. The default value is 100000. +jdk.xml.entityReplacementLimit=100000 # -# Limits the number of attributes an element can have. The default value is 10000. -# jdk.xml.elementAttributeLimit=10000 +# Limits the number of attributes an element can have. The default value is 200. +jdk.xml.elementAttributeLimit=200 # # Limits the number of content model nodes that may be created when building a # grammar for a W3C XML Schema that contains maxOccurs attributes with values # other than "unbounded". The default value is 5000. -# jdk.xml.maxOccurLimit=5000 +jdk.xml.maxOccurLimit=5000 # -# Limits the maximum element depth. The default value is 0. -# jdk.xml.maxElementDepth=0 +# Limits the maximum element depth. The default value is 100. +jdk.xml.maxElementDepth=100 # # Limits the maximum size of XML names, including element name, attribute name # and namespace prefix and URI. The default value is 1000. diff --git a/test/jaxp/javax/xml/jaxp/unittest/common/config/ConfigFileTest.java b/test/jaxp/javax/xml/jaxp/unittest/common/config/ConfigFileTest.java index fd5b8b36fa3..d1d8dcd8bd5 100644 --- a/test/jaxp/javax/xml/jaxp/unittest/common/config/ConfigFileTest.java +++ b/test/jaxp/javax/xml/jaxp/unittest/common/config/ConfigFileTest.java @@ -38,58 +38,35 @@ * strict template jaxp-strict.properties.template. * @library /javax/xml/jaxp/libs /javax/xml/jaxp/unittest * @modules java.xml/jdk.xml.internal - * @run driver common.config.ConfigFileTest 0 // verifies jaxp.properties - * @run driver common.config.ConfigFileTest 1 // verifies jaxp-strict.properties.template + * + * @run driver common.config.ConfigFileTest 1 // verifies jaxp.properties in JDK 24 and later + * @run driver common.config.ConfigFileTest 2 // verifies jaxp-strict.properties.template */ -public class ConfigFileTest { +public class ConfigFileTest extends ImplProperties { // system property for custom configuration file static final String SP_CONFIG = "java.xml.config.file"; // target directory static String TEST_DIR = System.getProperty("test.classes"); - // properties in the configuration file - String[] keys = { - "jdk.xml.enableExtensionFunctions", - "jdk.xml.overrideDefaultParser", - "jdk.xml.jdkcatalog.resolve", - "jdk.xml.dtd.support", - "jdk.xml.entityExpansionLimit", - "jdk.xml.totalEntitySizeLimit", - "jdk.xml.maxGeneralEntitySizeLimit", - "jdk.xml.maxParameterEntitySizeLimit", - "jdk.xml.entityReplacementLimit", - "jdk.xml.elementAttributeLimit", - "jdk.xml.maxOccurLimit", - "jdk.xml.maxElementDepth", - "jdk.xml.maxXMLNameLimit", - "jdk.xml.xpathExprGrpLimit", - "jdk.xml.xpathExprOpLimit", - "jdk.xml.xpathTotalOpLimit"}; - - // type of properties - boolean[] propertyIsFeature ={true, true, false, false, false, false, - false, false, false, false, false, false, false, false, false, false}; - - // values from jaxp-strict.properties.template - String[] strictValues ={"false", "false", "strict", "allow", "2500", "100000", - "100000", "15000", "100000", "10000", "5000", "0", "1000", "10", "100", "10000"}; - - // values from jaxp.properties, as of JDK 23 - String[] defaultValues ={"true", "false", "continue", "allow", "64000", "50000000", - "0", "1000000", "3000000", "10000", "5000", "0", "1000", "10", "100", "10000"}; - public static void main(String args[]) throws Exception { new ConfigFileTest().run(args[0]); } public void run(String index) throws Exception { String conf = System.getProperty("java.home") + "/conf/"; - if (index.equals("0")) { - verifyConfig(conf + CONFIG_DEFAULT, defaultValues); - } else { - Path config = Paths.get(TEST_DIR, CONFIG_STRICT); - Files.copy(Paths.get(conf, CONFIG_TEMPLATE_STRICT), config); - verifyConfig(config.toString(), strictValues); + int i = Integer.parseInt(index); + switch (i) { + case 0: // JDK 23 and older + // add compat template after the JEP + break; + case 1: // JDK 24 + verifyConfig(conf + CONFIG_DEFAULT, PROPERTY_VALUE[PROPERTY_VALUE_JDK24]); + break; + case 2: // strict template, since JDK 23 + Path configStrict = Paths.get(TEST_DIR, CONFIG_STRICT); + Files.copy(Paths.get(conf, CONFIG_TEMPLATE_STRICT), configStrict); + verifyConfig(configStrict.toString(), PROPERTY_VALUE[PROPERTY_VALUE_JDK23STRICT]); + break; } } @@ -102,11 +79,11 @@ private void verifyConfig(String filename, String[] values) { System.setProperty(SP_CONFIG, filename); TransformerFactory tf = TransformerFactory.newInstance(); - IntStream.range(0, keys.length).forEach(i -> { - if (propertyIsFeature[i]) { - TestBase.Assert.assertEquals(tf.getFeature(keys[i]), Boolean.parseBoolean(values[i])); + IntStream.range(0, PROPERTY_KEYS.length).forEach(i -> { + if (PROPERTY_TYPE[i] == PropertyType.BOOLEAN) { + TestBase.Assert.assertEquals(tf.getFeature(PROPERTY_KEYS[i]), Boolean.parseBoolean(values[i])); } else { - TestBase.Assert.assertEquals(tf.getAttribute(keys[i]), values[i]); + TestBase.Assert.assertEquals(tf.getAttribute(PROPERTY_KEYS[i]), values[i]); } }); System.clearProperty(SP_CONFIG); diff --git a/test/jaxp/javax/xml/jaxp/unittest/common/config/ConfigurationTest.java b/test/jaxp/javax/xml/jaxp/unittest/common/config/ConfigurationTest.java index 70cc92d67a2..4f70dbe7db0 100644 --- a/test/jaxp/javax/xml/jaxp/unittest/common/config/ConfigurationTest.java +++ b/test/jaxp/javax/xml/jaxp/unittest/common/config/ConfigurationTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -30,7 +30,7 @@ * any settings in a custom configuration file override those in the default * configuration. */ -public class ConfigurationTest { +public class ConfigurationTest extends ImplProperties { // system property for custom configuration file static final String SP_CONFIG = "java.xml.config.file"; // Impl-Specific Property: entity expansion @@ -79,14 +79,14 @@ public Object[][] getProperty() { return new Object[][]{ // default value is expected for property (PARAMETER_ENTITY) not // set in the default and custom configuration files - {null, ISP_PARAMETER_ENTITY, "1000000"}, + {null, ISP_PARAMETER_ENTITY, PROPERTY_VALUE[PROPERTY_VALUE_JDK24][INDEX_PE]}, // this property is set in the default (jaxp.properties), // but not the custom configuration file. Expects readings from the // default config - {null, ISP_NAME_LIMIT, "1000"}, + {null, ISP_NAME_LIMIT, PROPERTY_VALUE[PROPERTY_VALUE_JDK24][INDEX_NAME]}, // the property in the default configuration file (jaxp.properties) // will be read and used as the default value of the property - {null, ISP_ENTITY_EXPANSION, "64000"}, + {null, ISP_ENTITY_EXPANSION, PROPERTY_VALUE[PROPERTY_VALUE_JDK24][INDEX_EE]}, }; } diff --git a/test/jaxp/javax/xml/jaxp/unittest/common/config/ImplProperties.java b/test/jaxp/javax/xml/jaxp/unittest/common/config/ImplProperties.java new file mode 100644 index 00000000000..e72252e0f67 --- /dev/null +++ b/test/jaxp/javax/xml/jaxp/unittest/common/config/ImplProperties.java @@ -0,0 +1,112 @@ +/* + * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package common.config; + +/** + * Implementation Specific Properties: + * https://docs.oracle.com/en/java/javase/23/docs/api/java.xml/module-summary.html#IN_ISFP + */ +public class ImplProperties { + // JDK Implementation Specific Properties, refer to module description + public static final String[] PROPERTY_KEYS = { + "jdk.xml.enableExtensionFunctions", + "jdk.xml.overrideDefaultParser", + "jdk.xml.jdkcatalog.resolve", + "jdk.xml.dtd.support", + "jdk.xml.entityExpansionLimit", + "jdk.xml.totalEntitySizeLimit", + "jdk.xml.maxGeneralEntitySizeLimit", + "jdk.xml.maxParameterEntitySizeLimit", + "jdk.xml.entityReplacementLimit", + "jdk.xml.elementAttributeLimit", + "jdk.xml.maxOccurLimit", + "jdk.xml.maxElementDepth", + "jdk.xml.maxXMLNameLimit", + "jdk.xml.xpathExprGrpLimit", + "jdk.xml.xpathExprOpLimit", + "jdk.xml.xpathTotalOpLimit" + }; + + static final int INDEX_EXTFUNC = 0; + static final int INDEX_OVERRIDE = 1; + static final int INDEX_JDKCATALOG = 2; + static final int INDEX_DTD = 3; + static final int INDEX_EE = 4; + static final int INDEX_TE = 5; + static final int INDEX_GE = 6; + static final int INDEX_PE = 7; + static final int INDEX_ER = 8; + static final int INDEX_ATTR = 9; + static final int INDEX_MAXOCCUR = 10; + static final int INDEX_DEPTH = 11; + static final int INDEX_NAME = 12; + static final int INDEX_XPATHGRP = 13; + static final int INDEX_XPATHOP = 14; + static final int INDEX_XPATHTOTAL = 15; + + /** + * Type of properties + */ + public static enum PropertyType { + BOOLEAN, + INTEGER, + STRING; + } + + public static final PropertyType[] PROPERTY_TYPE = new PropertyType[16]; + static { + PROPERTY_TYPE[0] = PropertyType.BOOLEAN; + PROPERTY_TYPE[1] = PropertyType.BOOLEAN; + PROPERTY_TYPE[2] = PropertyType.STRING; + PROPERTY_TYPE[3] = PropertyType.STRING; + for (int i = 4; i < PROPERTY_TYPE.length; i++) { + PROPERTY_TYPE[i] = PropertyType.INTEGER; + } + } + + public static final boolean[] propertyIsFeature ={true, true, false, false, false, false, + false, false, false, false, false, false, false, false, false, false}; + + // default values in JDK 23 and older + public static final int PROPERTY_VALUE_JDK23 = 0; + + // default values in JDK 24 + public static final int PROPERTY_VALUE_JDK24 = 1; + + // default values in jaxp-strict.properties.template, since JDK 23 + public static final int PROPERTY_VALUE_JDK23STRICT = 2; + + public static final String[][] PROPERTY_VALUE = { + // default values in JDK 23 and older + {"true", "false", "continue", "allow", "64000", "50000000", + "0", "1000000", "3000000", "10000", "5000", "0", "1000", "10", "100", "10000"}, + + // default values in JDK 24 + {"true", "false", "continue", "allow", "2500", "100000", + "100000", "15000", "100000", "200", "5000", "100", "1000", "10", "100", "10000"}, + + // default values in jaxp-strict.properties.template, since JDK 23 + {"false", "false", "strict", "allow", "2500", "100000", + "100000", "15000", "100000", "200", "5000", "100", "1000", "10", "100", "10000"} + }; +} diff --git a/test/jaxp/javax/xml/jaxp/unittest/parsers/Bug4674384_MAX_OCCURS_Test.java b/test/jaxp/javax/xml/jaxp/unittest/parsers/Bug4674384_MAX_OCCURS_Test.java deleted file mode 100644 index fdc882181d6..00000000000 --- a/test/jaxp/javax/xml/jaxp/unittest/parsers/Bug4674384_MAX_OCCURS_Test.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright (c) 2014, 2024, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package parsers; - -import java.io.File; - -import javax.xml.parsers.SAXParser; -import javax.xml.parsers.SAXParserFactory; - -import org.testng.Assert; -import org.testng.annotations.Test; -import org.xml.sax.helpers.DefaultHandler; - -/* - * @test - * @bug 4674384 - * @library /javax/xml/jaxp/libs /javax/xml/jaxp/unittest - * @run testng/othervm parsers.Bug4674384_MAX_OCCURS_Test - * @summary Test large maxOccurs. - */ -public class Bug4674384_MAX_OCCURS_Test { - - @Test - public final void testLargeMaxOccurs() { - - String XML_FILE_NAME = "Bug4674384_MAX_OCCURS_Test.xml"; - - try { - // create and initialize the parser - SAXParserFactory spf = SAXParserFactory.newInstance(); - spf.setNamespaceAware(true); - spf.setValidating(true); - - SAXParser parser = spf.newSAXParser(); - parser.setProperty("http://java.sun.com/xml/jaxp/properties/schemaLanguage", "http://www.w3.org/2001/XMLSchema"); - - File xmlFile = new File(getClass().getResource(XML_FILE_NAME).getPath()); - - parser.parse(xmlFile, new DefaultHandler()); - } catch (Exception e) { - System.err.println("Failure: File " + XML_FILE_NAME + " was parsed with a large value of maxOccurs."); - e.printStackTrace(); - Assert.fail("Failure: File " + XML_FILE_NAME + " was parsed with a large value of maxOccurs. " + e.getMessage()); - } - - System.out.println("Success: File " + XML_FILE_NAME + " was parsed with a large value of maxOccurs."); - } -} diff --git a/test/jaxp/javax/xml/jaxp/unittest/parsers/Bug4674384_MAX_OCCURS_Test.xml b/test/jaxp/javax/xml/jaxp/unittest/parsers/Bug4674384_MAX_OCCURS_Test.xml deleted file mode 100644 index 56a2fe5eb69..00000000000 --- a/test/jaxp/javax/xml/jaxp/unittest/parsers/Bug4674384_MAX_OCCURS_Test.xml +++ /dev/null @@ -1,8 +0,0 @@ -<?xml version="1.0"?> -<test:a - xmlns:test="test" - xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" - xsi:schemaLocation="test Bug4674384_MAX_OCCURS_Test.xsd"> -<b>1</b> -<b>2</b> -</test:a> diff --git a/test/jaxp/javax/xml/jaxp/unittest/parsers/Bug4674384_MAX_OCCURS_Test.xsd b/test/jaxp/javax/xml/jaxp/unittest/parsers/Bug4674384_MAX_OCCURS_Test.xsd deleted file mode 100644 index 1a77727eed4..00000000000 --- a/test/jaxp/javax/xml/jaxp/unittest/parsers/Bug4674384_MAX_OCCURS_Test.xsd +++ /dev/null @@ -1,15 +0,0 @@ -<?xml version="1.0"?> - -<xsd:schema - xmlns:xsd="http://www.w3.org/2001/XMLSchema" - xmlns="test" - targetNamespace="test"> - - <xsd:element name="a" type="A"/> - <xsd:complexType name="A"> - <xsd:sequence> - <xsd:element name="b" type="xsd:string" maxOccurs="3000"/> - </xsd:sequence> - </xsd:complexType> - -</xsd:schema> diff --git a/test/jaxp/javax/xml/jaxp/unittest/parsers/Bug6309988.java b/test/jaxp/javax/xml/jaxp/unittest/parsers/Bug6309988.java deleted file mode 100644 index 6ad407f9555..00000000000 --- a/test/jaxp/javax/xml/jaxp/unittest/parsers/Bug6309988.java +++ /dev/null @@ -1,369 +0,0 @@ -/* - * Copyright (c) 2014, 2024, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package parsers; - -import static jaxp.library.JAXPTestUtilities.clearSystemProperty; -import static jaxp.library.JAXPTestUtilities.setSystemProperty; - -import java.io.File; -import java.io.InputStream; - -import javax.xml.XMLConstants; -import javax.xml.parsers.DocumentBuilder; -import javax.xml.parsers.DocumentBuilderFactory; -import javax.xml.parsers.SAXParser; -import javax.xml.parsers.SAXParserFactory; - -import org.testng.Assert; -import org.testng.annotations.Test; -import org.w3c.dom.Document; -import org.xml.sax.SAXParseException; - -/* - * @test - * @bug 6309988 - * @library /javax/xml/jaxp/libs /javax/xml/jaxp/unittest - * @run testng/othervm parsers.Bug6309988 - * @summary Test elementAttributeLimit, maxOccurLimit, entityExpansionLimit. - */ -@Test(singleThreaded = true) -public class Bug6309988 { - - DocumentBuilderFactory dbf = null; - - /* - * Given XML document has more than 10000 attributes. Exception is expected - */ - public void testDOMParserElementAttributeLimit() { - try { - dbf = DocumentBuilderFactory.newInstance(); - DocumentBuilder parser = dbf.newDocumentBuilder(); - Document doc = parser.parse(this.getClass().getResourceAsStream("DosTest.xml")); - Assert.fail("SAXParserException is expected, as given XML document contains more than 10000 attributes"); - } catch (SAXParseException e) { - System.out.println(e.getMessage()); - } catch (Exception e) { - Assert.fail("Exception " + e.getMessage()); - } - } - - /* - * Given XML document has more than 10000 attributes. It should report an - * error. - */ - public void testDOMNSParserElementAttributeLimit() { - try { - dbf = DocumentBuilderFactory.newInstance(); - dbf.setNamespaceAware(true); - DocumentBuilder parser = dbf.newDocumentBuilder(); - Document doc = parser.parse(this.getClass().getResourceAsStream("DosTest.xml")); - Assert.fail("SAXParserException is expected, as given XML document contains more than 10000 attributes"); - } catch (SAXParseException e) { - System.out.println(e.getMessage()); - } catch (Exception e) { - Assert.fail("Exception " + e.getMessage()); - } - } - - /* - * Given XML document has more than 10000 attributes. Parsing this XML - * document in non-secure mode, should not report any error. - */ - public void testDOMNSParserElementAttributeLimitWithoutSecureProcessing() { - if (isSecureMode()) - return; // jaxp secure feature can not be turned off when security - // manager is present - try { - dbf = DocumentBuilderFactory.newInstance(); - dbf.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, false); - dbf.setNamespaceAware(true); - DocumentBuilder parser = dbf.newDocumentBuilder(); - Document doc = parser.parse(this.getClass().getResourceAsStream("DosTest.xml")); - - } catch (SAXParseException e) { - Assert.fail(e.getMessage()); - } catch (Exception e) { - Assert.fail("Exception " + e.getMessage()); - } - } - - /* - * Before 8014530: Given XML document has 3 attributes and System property - * is set to 2. Parsing this XML document in non-secure mode, should not - * report an error. - * After 8014530: System properties will override FSP, the result of this - * test should be the same as - * testSystemElementAttributeLimitWithSecureProcessing - */ - public void testSystemElementAttributeLimitWithoutSecureProcessing() { - if (isSecureMode()) - return; // jaxp secure feature can not be turned off when security - // manager is present - try { - dbf = DocumentBuilderFactory.newInstance(); - dbf.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, false); - dbf.setNamespaceAware(true); - setSystemProperty("elementAttributeLimit", "2"); - DocumentBuilder parser = dbf.newDocumentBuilder(); - Document doc = parser.parse(this.getClass().getResourceAsStream("DosTest3.xml")); - - Assert.fail("SAXParserException is expected, as given XML document contains more than 2 attributes"); - } catch (Exception e) { - String errMsg = e.getMessage(); - Throwable cause = e.getCause(); - if (cause != null) { - errMsg += cause.getMessage(); - } - if (errMsg.contains("JAXP0001")) { - // expected - } else { - Assert.fail("Unexpected error: " + e.getMessage()); - } - } finally { - clearSystemProperty("elementAttributeLimit"); - } - } - - /* - * Given XML document has 3 attributes and System property is set to 2. - * Parsing this XML document in secure mode, should report an error. - */ - public void testSystemElementAttributeLimitWithSecureProcessing() { - try { - dbf = DocumentBuilderFactory.newInstance(); - dbf.setNamespaceAware(true); - setSystemProperty("elementAttributeLimit", "2"); - DocumentBuilder parser = dbf.newDocumentBuilder(); - Document doc = parser.parse(this.getClass().getResourceAsStream("DosTest3.xml")); - Assert.fail("SAXParserException is expected, as given XML document contains more than 2 attributes"); - } catch (SAXParseException e) { - System.out.println(e.getMessage()); - } catch (Exception e) { - Assert.fail("Exception " + e.getMessage()); - } finally { - setSystemProperty("elementAttributeLimit", ""); - } - } - - /* - * Default value for secure processing feature should be true. - */ - public void testDOMSecureProcessingDefaultValue() { - try { - dbf = DocumentBuilderFactory.newInstance(); - Assert.assertTrue(dbf.getFeature(XMLConstants.FEATURE_SECURE_PROCESSING), "Default value for secureProcessing feature should be true"); - - } catch (Exception e) { - Assert.fail("Exception " + e.getMessage()); - } - } - - /* - * Default value for secure processing feature should be true. - */ - public void testSAXSecureProcessingDefaultValue() { - try { - SAXParserFactory spf = SAXParserFactory.newInstance(); - Assert.assertTrue(spf.getFeature(XMLConstants.FEATURE_SECURE_PROCESSING), "Default value for secureProcessing feature should be true"); - - } catch (Exception e) { - Assert.fail("Exception " + e.getMessage()); - } - } - - /* - * This method sets system property for maxOccurLimit=2 and secure process - * feature is off. Given doument contains more than 2 elements and hence an - * error should be reported. - */ - public void testSystemMaxOccurLimitWithoutSecureProcessing() { - if (isSecureMode()) - return; // jaxp secure feature can not be turned off when security - // manager is present - try { - SAXParserFactory spf = SAXParserFactory.newInstance(); - spf.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, false); - spf.setValidating(true); - setSystemProperty("maxOccurLimit", "2"); - // Set the properties for Schema Validation - String SCHEMA_LANG = "http://java.sun.com/xml/jaxp/properties/schemaLanguage"; - String SCHEMA_TYPE = "http://www.w3.org/2001/XMLSchema"; - // Get the Schema location as a File object - File schemaFile = new File(this.getClass().getResource("toys.xsd").toURI()); - // Get the parser - SAXParser parser = spf.newSAXParser(); - parser.setProperty(SCHEMA_LANG, SCHEMA_TYPE); - parser.setProperty("http://java.sun.com/xml/jaxp/properties/schemaSource", schemaFile); - - InputStream is = this.getClass().getResourceAsStream("toys.xml"); - MyErrorHandler eh = new MyErrorHandler(); - parser.parse(is, eh); - Assert.assertFalse(eh.errorOccured, "Not Expected Error"); - setSystemProperty("maxOccurLimit", ""); - } catch (Exception e) { - Assert.fail("Exception occured: " + e.getMessage()); - } - } - - /* - * This test will take longer time to execute( abt 120sec). This method - * tries to validate a document. This document contains an element whose - * maxOccur is '3002'. Since secure processing feature is off, document - * should be parsed without any errors. - */ - public void testValidMaxOccurLimitWithOutSecureProcessing() { - if (isSecureMode()) - return; // jaxp secure feature can not be turned off when security - // manager is present - try { - SAXParserFactory spf = SAXParserFactory.newInstance(); - spf.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, false); - spf.setValidating(true); - // Set the properties for Schema Validation - String SCHEMA_LANG = "http://java.sun.com/xml/jaxp/properties/schemaLanguage"; - String SCHEMA_TYPE = "http://www.w3.org/2001/XMLSchema"; - // Get the Schema location as a File object - File schemaFile = new File(this.getClass().getResource("toys3002.xsd").toURI()); - // Get the parser - SAXParser parser = spf.newSAXParser(); - parser.setProperty(SCHEMA_LANG, SCHEMA_TYPE); - parser.setProperty("http://java.sun.com/xml/jaxp/properties/schemaSource", schemaFile); - - InputStream is = this.getClass().getResourceAsStream("toys.xml"); - MyErrorHandler eh = new MyErrorHandler(); - parser.parse(is, eh); - Assert.assertFalse(eh.errorOccured, "Expected Error as maxOccurLimit is exceeded"); - - } catch (Exception e) { - Assert.fail("Exception occured: " + e.getMessage()); - } - } - - /* - * Before 8014530: System property is set to 2. Given XML document has more - * than 2 entity references. Parsing this document in non-secure mode, - * should *not* report an error. - * After 8014530: System properties will override FSP, the result of this - * test should be the same as - * testSystemElementAttributeLimitWithSecureProcessing - */ - public void testSystemEntityExpansionLimitWithOutSecureProcessing() { - if (isSecureMode()) - return; // jaxp secure feature can not be turned off when security - // manager is present - try { - setSystemProperty("entityExpansionLimit", "2"); - dbf = DocumentBuilderFactory.newInstance(); - dbf.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, false); - dbf.setValidating(true); - DocumentBuilder parser = dbf.newDocumentBuilder(); - Document doc = parser.parse(this.getClass().getResourceAsStream("entity.xml")); - Assert.fail("SAXParserException is expected, as given XML document contains more 2 entity references"); - } catch (Exception e) { - String errMsg = e.getMessage(); - Throwable cause = e.getCause(); - if (cause != null) { - errMsg += cause.getMessage(); - } - if (errMsg.contains("JAXP0001")) { - // expected - } else { - Assert.fail("Unexpected error: " + e.getMessage()); - } - } finally { - clearSystemProperty("entityExpansionLimit"); - } - } - - /* - * System property is set to 2. Given XML document has more than 2 entity - * references. Parsing this document in secure mode, should report an error. - */ - public void testSystemEntityExpansionLimitWithSecureProcessing() { - try { - dbf = DocumentBuilderFactory.newInstance(); - dbf.setValidating(true); - setSystemProperty("entityExpansionLimit", "2"); - DocumentBuilder parser = dbf.newDocumentBuilder(); - Document doc = parser.parse(this.getClass().getResourceAsStream("entity.xml")); - Assert.fail("SAXParserException is expected, as given XML document contains more 2 entity references"); - - } catch (SAXParseException e) { - System.out.println(e.getMessage()); - } catch (Exception e) { - Assert.fail("Exception " + e.getMessage()); - } finally { - setSystemProperty("entityExpansionLimit", ""); - } - } - - /* - * Given XML document has more than 64000 entity references. Parsing this - * document in secure mode, should report an error. - */ - public void testEntityExpansionLimitWithSecureProcessing() { - try { - dbf = DocumentBuilderFactory.newInstance(); - dbf.setValidating(true); - DocumentBuilder parser = dbf.newDocumentBuilder(); - Document doc = parser.parse(this.getClass().getResourceAsStream("entity64K.xml")); - Assert.fail("SAXParserException is expected, as given XML document contains more 2 entity references"); - - } catch (SAXParseException e) { - System.out.println(e.getMessage()); - } catch (Exception e) { - Assert.fail("Exception " + e.getMessage()); - } finally { - setSystemProperty("entityExpansionLimit", ""); - } - } - - /* - * Given XML document has more than 64000 entity references. Parsing this - * document in non-secure mode, should not report any error. - */ - public void testEntityExpansionLimitWithOutSecureProcessing() { - if (isSecureMode()) - return; // jaxp secure feature can not be turned off when security - // manager is present - try { - dbf = DocumentBuilderFactory.newInstance(); - dbf.setFeature(XMLConstants.FEATURE_SECURE_PROCESSING, false); - dbf.setValidating(true); - DocumentBuilder parser = dbf.newDocumentBuilder(); - Document doc = parser.parse(this.getClass().getResourceAsStream("entity64K.xml")); - - } catch (SAXParseException e) { - Assert.fail("Exception " + e.getMessage()); - } catch (Exception e) { - Assert.fail("Exception " + e.getMessage()); - } finally { - setSystemProperty("entityExpansionLimit", ""); - } - } - - private boolean isSecureMode() { - return System.getSecurityManager() != null; - } -} diff --git a/test/jaxp/javax/xml/jaxp/unittest/parsers/DosTest.xml b/test/jaxp/javax/xml/jaxp/unittest/parsers/DosTest.xml deleted file mode 100644 index 757213ee5f4..00000000000 --- a/test/jaxp/javax/xml/jaxp/unittest/parsers/DosTest.xml +++ /dev/null @@ -1,2031 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<personnel> - -<person id="Big.Boss" A100 = "" -A101 = "" A102 = "" A103 = "" A104 = "" A105 = "" A106 = "" A107 = "" A108 = "" A109 = "" A110 = "" -A111 = "" A112 = "" A113 = "" A114 = "" A115 = "" A116 = "" A117 = "" A118 = "" A119 = "" A120 = "" -A121 = "" A122 = "" A123 = "" A124 = "" A125 = "" A126 = "" A127 = "" A128 = "" A129 = "" A130 = "" -A131 = "" A132 = "" A133 = "" A134 = "" A135 = "" A136 = "" A137 = "" A138 = "" A139 = "" A140 = "" -A141 = "" A142 = "" A143 = "" A144 = "" A145 = "" A146 = "" A147 = "" A148 = "" A149 = "" A150 = "" -A151 = "" A152 = "" A153 = "" A154 = "" A155 = "" A156 = "" A157 = "" A158 = "" A159 = "" A160 = "" -A161 = "" A162 = "" A163 = "" A164 = "" A165 = "" A166 = "" A167 = "" A168 = "" A169 = "" A170 = "" -A171 = "" A172 = "" A173 = "" A174 = "" A175 = "" A176 = "" A177 = "" A178 = "" A179 = "" A180 = "" -A181 = "" A182 = "" A183 = "" A184 = "" A185 = "" A186 = "" A187 = "" A188 = "" A189 = "" A190 = "" -A191 = "" A192 = "" A193 = "" A194 = "" A195 = "" A196 = "" A197 = "" A198 = "" A199 = "" A200 = "" -A201 = "" A202 = "" A203 = "" A204 = "" A205 = "" A206 = "" A207 = "" A208 = "" A209 = "" A210 = "" -A211 = "" A212 = "" A213 = "" A214 = "" A215 = "" A216 = "" A217 = "" A218 = "" A219 = "" A220 = "" -A221 = "" A222 = "" A223 = "" A224 = "" A225 = "" A226 = "" A227 = "" A228 = "" A229 = "" A230 = "" -A231 = "" A232 = "" A233 = "" A234 = "" A235 = "" A236 = "" A237 = "" A238 = "" A239 = "" A240 = "" -A241 = "" A242 = "" A243 = "" A244 = "" A245 = "" A246 = "" A247 = "" A248 = "" A249 = "" A250 = "" -A251 = "" A252 = "" A253 = "" A254 = "" A255 = "" A256 = "" A257 = "" A258 = "" A259 = "" A260 = "" -A261 = "" A262 = "" A263 = "" A264 = "" A265 = "" A266 = "" A267 = "" A268 = "" A269 = "" A270 = "" -A271 = "" A272 = "" A273 = "" A274 = "" A275 = "" A276 = "" A277 = "" A278 = "" A279 = "" A280 = "" -A281 = "" A282 = "" A283 = "" A284 = "" A285 = "" A286 = "" A287 = "" A288 = "" A289 = "" A290 = "" -A291 = "" A292 = "" A293 = "" A294 = "" A295 = "" A296 = "" A297 = "" A298 = "" A299 = "" A300 = "" -A301 = "" A302 = "" A303 = "" A304 = "" A305 = "" A306 = "" A307 = "" A308 = "" A309 = "" A310 = "" -A311 = "" A312 = "" A313 = "" A314 = "" A315 = "" A316 = "" A317 = "" A318 = "" A319 = "" A320 = "" -A321 = "" A322 = "" A323 = "" A324 = "" A325 = "" A326 = "" A327 = "" A328 = "" A329 = "" A330 = "" -A331 = "" A332 = "" A333 = "" A334 = "" A335 = "" A336 = "" A337 = "" A338 = "" A339 = "" A340 = "" -A341 = "" A342 = "" A343 = "" A344 = "" A345 = "" A346 = "" A347 = "" A348 = "" A349 = "" A350 = "" -A351 = "" A352 = "" A353 = "" A354 = "" A355 = "" A356 = "" A357 = "" A358 = "" A359 = "" A360 = "" -A361 = "" A362 = "" A363 = "" A364 = "" A365 = "" A366 = "" A367 = "" A368 = "" A369 = "" A370 = "" -A371 = "" A372 = "" A373 = "" A374 = "" A375 = "" A376 = "" A377 = "" A378 = "" A379 = "" A380 = "" -A381 = "" A382 = "" A383 = "" A384 = "" A385 = "" A386 = "" A387 = "" A388 = "" A389 = "" A390 = "" -A391 = "" A392 = "" A393 = "" A394 = "" A395 = "" A396 = "" A397 = "" A398 = "" A399 = "" A400 = "" -A401 = "" A402 = "" A403 = "" A404 = "" A405 = "" A406 = "" A407 = "" A408 = "" A409 = "" A410 = "" -A411 = "" A412 = "" A413 = "" A414 = "" A415 = "" A416 = "" A417 = "" A418 = "" A419 = "" A420 = "" -A421 = "" A422 = "" A423 = "" A424 = "" A425 = "" A426 = "" A427 = "" A428 = "" A429 = "" A430 = "" -A431 = "" A432 = "" A433 = "" A434 = "" A435 = "" A436 = "" A437 = "" A438 = "" A439 = "" A440 = "" -A441 = "" A442 = "" A443 = "" A444 = "" A445 = "" A446 = "" A447 = "" A448 = "" A449 = "" A450 = "" -A451 = "" A452 = "" A453 = "" A454 = "" A455 = "" A456 = "" A457 = "" A458 = "" A459 = "" A460 = "" -A461 = "" A462 = "" A463 = "" A464 = "" A465 = "" A466 = "" A467 = "" A468 = "" A469 = "" A470 = "" -A471 = "" A472 = "" A473 = "" A474 = "" A475 = "" A476 = "" A477 = "" A478 = "" A479 = "" A480 = "" -A481 = "" A482 = "" A483 = "" A484 = "" A485 = "" A486 = "" A487 = "" A488 = "" A489 = "" A490 = "" -A491 = "" A492 = "" A493 = "" A494 = "" A495 = "" A496 = "" A497 = "" A498 = "" A499 = "" A500 = "" -A501 = "" A502 = "" A503 = "" A504 = "" A505 = "" A506 = "" A507 = "" A508 = "" A509 = "" A510 = "" -A511 = "" A512 = "" A513 = "" A514 = "" A515 = "" A516 = "" A517 = "" A518 = "" A519 = "" A520 = "" -A521 = "" A522 = "" A523 = "" A524 = "" A525 = "" A526 = "" A527 = "" A528 = "" A529 = "" A530 = "" -A531 = "" A532 = "" A533 = "" A534 = "" A535 = "" A536 = "" A537 = "" A538 = "" A539 = "" A540 = "" -A541 = "" A542 = "" A543 = "" A544 = "" A545 = "" A546 = "" A547 = "" A548 = "" A549 = "" A550 = "" -A551 = "" A552 = "" A553 = "" A554 = "" A555 = "" A556 = "" A557 = "" A558 = "" A559 = "" A560 = "" -A561 = "" A562 = "" A563 = "" A564 = "" A565 = "" A566 = "" A567 = "" A568 = "" A569 = "" A570 = "" -A571 = "" A572 = "" A573 = "" A574 = "" A575 = "" A576 = "" A577 = "" A578 = "" A579 = "" A580 = "" -A581 = "" A582 = "" A583 = "" A584 = "" A585 = "" A586 = "" A587 = "" A588 = "" A589 = "" A590 = "" -A591 = "" A592 = "" A593 = "" A594 = "" A595 = "" A596 = "" A597 = "" A598 = "" A599 = "" A600 = "" -A601 = "" A602 = "" A603 = "" A604 = "" A605 = "" A606 = "" A607 = "" A608 = "" A609 = "" A610 = "" -A611 = "" A612 = "" A613 = "" A614 = "" A615 = "" A616 = "" A617 = "" A618 = "" A619 = "" A620 = "" -A621 = "" A622 = "" A623 = "" A624 = "" A625 = "" A626 = "" A627 = "" A628 = "" A629 = "" A630 = "" -A631 = "" A632 = "" A633 = "" A634 = "" A635 = "" A636 = "" A637 = "" A638 = "" A639 = "" A640 = "" -A641 = "" A642 = "" A643 = "" A644 = "" A645 = "" A646 = "" A647 = "" A648 = "" A649 = "" A650 = "" -A651 = "" A652 = "" A653 = "" A654 = "" A655 = "" A656 = "" A657 = "" A658 = "" A659 = "" A660 = "" -A661 = "" A662 = "" A663 = "" A664 = "" A665 = "" A666 = "" A667 = "" A668 = "" A669 = "" A670 = "" -A671 = "" A672 = "" A673 = "" A674 = "" A675 = "" A676 = "" A677 = "" A678 = "" A679 = "" A680 = "" -A681 = "" A682 = "" A683 = "" A684 = "" A685 = "" A686 = "" A687 = "" A688 = "" A689 = "" A690 = "" -A691 = "" A692 = "" A693 = "" A694 = "" A695 = "" A696 = "" A697 = "" A698 = "" A699 = "" A700 = "" -A701 = "" A702 = "" A703 = "" A704 = "" A705 = "" A706 = "" A707 = "" A708 = "" A709 = "" A710 = "" -A711 = "" A712 = "" A713 = "" A714 = "" A715 = "" A716 = "" A717 = "" A718 = "" A719 = "" A720 = "" -A721 = "" A722 = "" A723 = "" A724 = "" A725 = "" A726 = "" A727 = "" A728 = "" A729 = "" A730 = "" -A731 = "" A732 = "" A733 = "" A734 = "" A735 = "" A736 = "" A737 = "" A738 = "" A739 = "" A740 = "" -A741 = "" A742 = "" A743 = "" A744 = "" A745 = "" A746 = "" A747 = "" A748 = "" A749 = "" A750 = "" -A751 = "" A752 = "" A753 = "" A754 = "" A755 = "" A756 = "" A757 = "" A758 = "" A759 = "" A760 = "" -A761 = "" A762 = "" A763 = "" A764 = "" A765 = "" A766 = "" A767 = "" A768 = "" A769 = "" A770 = "" -A771 = "" A772 = "" A773 = "" A774 = "" A775 = "" A776 = "" A777 = "" A778 = "" A779 = "" A780 = "" -A781 = "" A782 = "" A783 = "" A784 = "" A785 = "" A786 = "" A787 = "" A788 = "" A789 = "" A790 = "" -A791 = "" A792 = "" A793 = "" A794 = "" A795 = "" A796 = "" A797 = "" A798 = "" A799 = "" A800 = "" -A801 = "" A802 = "" A803 = "" A804 = "" A805 = "" A806 = "" A807 = "" A808 = "" A809 = "" A810 = "" -A811 = "" A812 = "" A813 = "" A814 = "" A815 = "" A816 = "" A817 = "" A818 = "" A819 = "" A820 = "" -A821 = "" A822 = "" A823 = "" A824 = "" A825 = "" A826 = "" A827 = "" A828 = "" A829 = "" A830 = "" -A831 = "" A832 = "" A833 = "" A834 = "" A835 = "" A836 = "" A837 = "" A838 = "" A839 = "" A840 = "" -A841 = "" A842 = "" A843 = "" A844 = "" A845 = "" A846 = "" A847 = "" A848 = "" A849 = "" A850 = "" -A851 = "" A852 = "" A853 = "" A854 = "" A855 = "" A856 = "" A857 = "" A858 = "" A859 = "" A860 = "" -A861 = "" A862 = "" A863 = "" A864 = "" A865 = "" A866 = "" A867 = "" A868 = "" A869 = "" A870 = "" -A871 = "" A872 = "" A873 = "" A874 = "" A875 = "" A876 = "" A877 = "" A878 = "" A879 = "" A880 = "" -A881 = "" A882 = "" A883 = "" A884 = "" A885 = "" A886 = "" A887 = "" A888 = "" A889 = "" A890 = "" -A891 = "" A892 = "" A893 = "" A894 = "" A895 = "" A896 = "" A897 = "" A898 = "" A899 = "" A900 = "" -A901 = "" A902 = "" A903 = "" A904 = "" A905 = "" A906 = "" A907 = "" A908 = "" A909 = "" A910 = "" -A911 = "" A912 = "" A913 = "" A914 = "" A915 = "" A916 = "" A917 = "" A918 = "" A919 = "" A920 = "" -A921 = "" A922 = "" A923 = "" A924 = "" A925 = "" A926 = "" A927 = "" A928 = "" A929 = "" A930 = "" -A931 = "" A932 = "" A933 = "" A934 = "" A935 = "" A936 = "" A937 = "" A938 = "" A939 = "" A940 = "" -A941 = "" A942 = "" A943 = "" A944 = "" A945 = "" A946 = "" A947 = "" A948 = "" A949 = "" A950 = "" -A951 = "" A952 = "" A953 = "" A954 = "" A955 = "" A956 = "" A957 = "" A958 = "" A959 = "" A960 = "" -A961 = "" A962 = "" A963 = "" A964 = "" A965 = "" A966 = "" A967 = "" A968 = "" A969 = "" A970 = "" -A971 = "" A972 = "" A973 = "" A974 = "" A975 = "" A976 = "" A977 = "" A978 = "" A979 = "" A980 = "" -A981 = "" A982 = "" A983 = "" A984 = "" A985 = "" A986 = "" A987 = "" A988 = "" A989 = "" A990 = "" -A991 = "" A992 = "" A993 = "" A994 = "" A995 = "" A996 = "" A997 = "" A998 = "" A999 = "" A1000 = "" -A1001 = "" A1002 = "" A1003 = "" A1004 = "" A1005 = "" A1006 = "" A1007 = "" A1008 = "" A1009 = "" A1010 = "" -A1011 = "" A1012 = "" A1013 = "" A1014 = "" A1015 = "" A1016 = "" A1017 = "" A1018 = "" A1019 = "" A1020 = "" -A1021 = "" A1022 = "" A1023 = "" A1024 = "" A1025 = "" A1026 = "" A1027 = "" A1028 = "" A1029 = "" A1030 = "" -A1031 = "" A1032 = "" A1033 = "" A1034 = "" A1035 = "" A1036 = "" A1037 = "" A1038 = "" A1039 = "" A1040 = "" -A1041 = "" A1042 = "" A1043 = "" A1044 = "" A1045 = "" A1046 = "" A1047 = "" A1048 = "" A1049 = "" A1050 = "" -A1051 = "" A1052 = "" A1053 = "" A1054 = "" A1055 = "" A1056 = "" A1057 = "" A1058 = "" A1059 = "" A1060 = "" -A1061 = "" A1062 = "" A1063 = "" A1064 = "" A1065 = "" A1066 = "" A1067 = "" A1068 = "" A1069 = "" A1070 = "" -A1071 = "" A1072 = "" A1073 = "" A1074 = "" A1075 = "" A1076 = "" A1077 = "" A1078 = "" A1079 = "" A1080 = "" -A1081 = "" A1082 = "" A1083 = "" A1084 = "" A1085 = "" A1086 = "" A1087 = "" A1088 = "" A1089 = "" A1090 = "" -A1091 = "" A1092 = "" A1093 = "" A1094 = "" A1095 = "" A1096 = "" A1097 = "" A1098 = "" A1099 = "" A1100 = "" -A1101 = "" A1102 = "" A1103 = "" A1104 = "" A1105 = "" A1106 = "" A1107 = "" A1108 = "" A1109 = "" A1110 = "" -A1111 = "" A1112 = "" A1113 = "" A1114 = "" A1115 = "" A1116 = "" A1117 = "" A1118 = "" A1119 = "" A1120 = "" -A1121 = "" A1122 = "" A1123 = "" A1124 = "" A1125 = "" A1126 = "" A1127 = "" A1128 = "" A1129 = "" A1130 = "" -A1131 = "" A1132 = "" A1133 = "" A1134 = "" A1135 = "" A1136 = "" A1137 = "" A1138 = "" A1139 = "" A1140 = "" -A1141 = "" A1142 = "" A1143 = "" A1144 = "" A1145 = "" A1146 = "" A1147 = "" A1148 = "" A1149 = "" A1150 = "" -A1151 = "" A1152 = "" A1153 = "" A1154 = "" A1155 = "" A1156 = "" A1157 = "" A1158 = "" A1159 = "" A1160 = "" -A1161 = "" A1162 = "" A1163 = "" A1164 = "" A1165 = "" A1166 = "" A1167 = "" A1168 = "" A1169 = "" A1170 = "" -A1171 = "" A1172 = "" A1173 = "" A1174 = "" A1175 = "" A1176 = "" A1177 = "" A1178 = "" A1179 = "" A1180 = "" -A1181 = "" A1182 = "" A1183 = "" A1184 = "" A1185 = "" A1186 = "" A1187 = "" A1188 = "" A1189 = "" A1190 = "" -A1191 = "" A1192 = "" A1193 = "" A1194 = "" A1195 = "" A1196 = "" A1197 = "" A1198 = "" A1199 = "" A1200 = "" -A1201 = "" A1202 = "" A1203 = "" A1204 = "" A1205 = "" A1206 = "" A1207 = "" A1208 = "" A1209 = "" A1210 = "" -A1211 = "" A1212 = "" A1213 = "" A1214 = "" A1215 = "" A1216 = "" A1217 = "" A1218 = "" A1219 = "" A1220 = "" -A1221 = "" A1222 = "" A1223 = "" A1224 = "" A1225 = "" A1226 = "" A1227 = "" A1228 = "" A1229 = "" A1230 = "" -A1231 = "" A1232 = "" A1233 = "" A1234 = "" A1235 = "" A1236 = "" A1237 = "" A1238 = "" A1239 = "" A1240 = "" -A1241 = "" A1242 = "" A1243 = "" A1244 = "" A1245 = "" A1246 = "" A1247 = "" A1248 = "" A1249 = "" A1250 = "" -A1251 = "" A1252 = "" A1253 = "" A1254 = "" A1255 = "" A1256 = "" A1257 = "" A1258 = "" A1259 = "" A1260 = "" -A1261 = "" A1262 = "" A1263 = "" A1264 = "" A1265 = "" A1266 = "" A1267 = "" A1268 = "" A1269 = "" A1270 = "" -A1271 = "" A1272 = "" A1273 = "" A1274 = "" A1275 = "" A1276 = "" A1277 = "" A1278 = "" A1279 = "" A1280 = "" -A1281 = "" A1282 = "" A1283 = "" A1284 = "" A1285 = "" A1286 = "" A1287 = "" A1288 = "" A1289 = "" A1290 = "" -A1291 = "" A1292 = "" A1293 = "" A1294 = "" A1295 = "" A1296 = "" A1297 = "" A1298 = "" A1299 = "" A1300 = "" -A1301 = "" A1302 = "" A1303 = "" A1304 = "" A1305 = "" A1306 = "" A1307 = "" A1308 = "" A1309 = "" A1310 = "" -A1311 = "" A1312 = "" A1313 = "" A1314 = "" A1315 = "" A1316 = "" A1317 = "" A1318 = "" A1319 = "" A1320 = "" -A1321 = "" A1322 = "" A1323 = "" A1324 = "" A1325 = "" A1326 = "" A1327 = "" A1328 = "" A1329 = "" A1330 = "" -A1331 = "" A1332 = "" A1333 = "" A1334 = "" A1335 = "" A1336 = "" A1337 = "" A1338 = "" A1339 = "" A1340 = "" -A1341 = "" A1342 = "" A1343 = "" A1344 = "" A1345 = "" A1346 = "" A1347 = "" A1348 = "" A1349 = "" A1350 = "" -A1351 = "" A1352 = "" A1353 = "" A1354 = "" A1355 = "" A1356 = "" A1357 = "" A1358 = "" A1359 = "" A1360 = "" -A1361 = "" A1362 = "" A1363 = "" A1364 = "" A1365 = "" A1366 = "" A1367 = "" A1368 = "" A1369 = "" A1370 = "" -A1371 = "" A1372 = "" A1373 = "" A1374 = "" A1375 = "" A1376 = "" A1377 = "" A1378 = "" A1379 = "" A1380 = "" -A1381 = "" A1382 = "" A1383 = "" A1384 = "" A1385 = "" A1386 = "" A1387 = "" A1388 = "" A1389 = "" A1390 = "" -A1391 = "" A1392 = "" A1393 = "" A1394 = "" A1395 = "" A1396 = "" A1397 = "" A1398 = "" A1399 = "" A1400 = "" -A1401 = "" A1402 = "" A1403 = "" A1404 = "" A1405 = "" A1406 = "" A1407 = "" A1408 = "" A1409 = "" A1410 = "" -A1411 = "" A1412 = "" A1413 = "" A1414 = "" A1415 = "" A1416 = "" A1417 = "" A1418 = "" A1419 = "" A1420 = "" -A1421 = "" A1422 = "" A1423 = "" A1424 = "" A1425 = "" A1426 = "" A1427 = "" A1428 = "" A1429 = "" A1430 = "" -A1431 = "" A1432 = "" A1433 = "" A1434 = "" A1435 = "" A1436 = "" A1437 = "" A1438 = "" A1439 = "" A1440 = "" -A1441 = "" A1442 = "" A1443 = "" A1444 = "" A1445 = "" A1446 = "" A1447 = "" A1448 = "" A1449 = "" A1450 = "" -A1451 = "" A1452 = "" A1453 = "" A1454 = "" A1455 = "" A1456 = "" A1457 = "" A1458 = "" A1459 = "" A1460 = "" -A1461 = "" A1462 = "" A1463 = "" A1464 = "" A1465 = "" A1466 = "" A1467 = "" A1468 = "" A1469 = "" A1470 = "" -A1471 = "" A1472 = "" A1473 = "" A1474 = "" A1475 = "" A1476 = "" A1477 = "" A1478 = "" A1479 = "" A1480 = "" -A1481 = "" A1482 = "" A1483 = "" A1484 = "" A1485 = "" A1486 = "" A1487 = "" A1488 = "" A1489 = "" A1490 = "" -A1491 = "" A1492 = "" A1493 = "" A1494 = "" A1495 = "" A1496 = "" A1497 = "" A1498 = "" A1499 = "" A1500 = "" -A1501 = "" A1502 = "" A1503 = "" A1504 = "" A1505 = "" A1506 = "" A1507 = "" A1508 = "" A1509 = "" A1510 = "" -A1511 = "" A1512 = "" A1513 = "" A1514 = "" A1515 = "" A1516 = "" A1517 = "" A1518 = "" A1519 = "" A1520 = "" -A1521 = "" A1522 = "" A1523 = "" A1524 = "" A1525 = "" A1526 = "" A1527 = "" A1528 = "" A1529 = "" A1530 = "" -A1531 = "" A1532 = "" A1533 = "" A1534 = "" A1535 = "" A1536 = "" A1537 = "" A1538 = "" A1539 = "" A1540 = "" -A1541 = "" A1542 = "" A1543 = "" A1544 = "" A1545 = "" A1546 = "" A1547 = "" A1548 = "" A1549 = "" A1550 = "" -A1551 = "" A1552 = "" A1553 = "" A1554 = "" A1555 = "" A1556 = "" A1557 = "" A1558 = "" A1559 = "" A1560 = "" -A1561 = "" A1562 = "" A1563 = "" A1564 = "" A1565 = "" A1566 = "" A1567 = "" A1568 = "" A1569 = "" A1570 = "" -A1571 = "" A1572 = "" A1573 = "" A1574 = "" A1575 = "" A1576 = "" A1577 = "" A1578 = "" A1579 = "" A1580 = "" -A1581 = "" A1582 = "" A1583 = "" A1584 = "" A1585 = "" A1586 = "" A1587 = "" A1588 = "" A1589 = "" A1590 = "" -A1591 = "" A1592 = "" A1593 = "" A1594 = "" A1595 = "" A1596 = "" A1597 = "" A1598 = "" A1599 = "" A1600 = "" -A1601 = "" A1602 = "" A1603 = "" A1604 = "" A1605 = "" A1606 = "" A1607 = "" A1608 = "" A1609 = "" A1610 = "" -A1611 = "" A1612 = "" A1613 = "" A1614 = "" A1615 = "" A1616 = "" A1617 = "" A1618 = "" A1619 = "" A1620 = "" -A1621 = "" A1622 = "" A1623 = "" A1624 = "" A1625 = "" A1626 = "" A1627 = "" A1628 = "" A1629 = "" A1630 = "" -A1631 = "" A1632 = "" A1633 = "" A1634 = "" A1635 = "" A1636 = "" A1637 = "" A1638 = "" A1639 = "" A1640 = "" -A1641 = "" A1642 = "" A1643 = "" A1644 = "" A1645 = "" A1646 = "" A1647 = "" A1648 = "" A1649 = "" A1650 = "" -A1651 = "" A1652 = "" A1653 = "" A1654 = "" A1655 = "" A1656 = "" A1657 = "" A1658 = "" A1659 = "" A1660 = "" -A1661 = "" A1662 = "" A1663 = "" A1664 = "" A1665 = "" A1666 = "" A1667 = "" A1668 = "" A1669 = "" A1670 = "" -A1671 = "" A1672 = "" A1673 = "" A1674 = "" A1675 = "" A1676 = "" A1677 = "" A1678 = "" A1679 = "" A1680 = "" -A1681 = "" A1682 = "" A1683 = "" A1684 = "" A1685 = "" A1686 = "" A1687 = "" A1688 = "" A1689 = "" A1690 = "" -A1691 = "" A1692 = "" A1693 = "" A1694 = "" A1695 = "" A1696 = "" A1697 = "" A1698 = "" A1699 = "" A1700 = "" -A1701 = "" A1702 = "" A1703 = "" A1704 = "" A1705 = "" A1706 = "" A1707 = "" A1708 = "" A1709 = "" A1710 = "" -A1711 = "" A1712 = "" A1713 = "" A1714 = "" A1715 = "" A1716 = "" A1717 = "" A1718 = "" A1719 = "" A1720 = "" -A1721 = "" A1722 = "" A1723 = "" A1724 = "" A1725 = "" A1726 = "" A1727 = "" A1728 = "" A1729 = "" A1730 = "" -A1731 = "" A1732 = "" A1733 = "" A1734 = "" A1735 = "" A1736 = "" A1737 = "" A1738 = "" A1739 = "" A1740 = "" -A1741 = "" A1742 = "" A1743 = "" A1744 = "" A1745 = "" A1746 = "" A1747 = "" A1748 = "" A1749 = "" A1750 = "" -A1751 = "" A1752 = "" A1753 = "" A1754 = "" A1755 = "" A1756 = "" A1757 = "" A1758 = "" A1759 = "" A1760 = "" -A1761 = "" A1762 = "" A1763 = "" A1764 = "" A1765 = "" A1766 = "" A1767 = "" A1768 = "" A1769 = "" A1770 = "" -A1771 = "" A1772 = "" A1773 = "" A1774 = "" A1775 = "" A1776 = "" A1777 = "" A1778 = "" A1779 = "" A1780 = "" -A1781 = "" A1782 = "" A1783 = "" A1784 = "" A1785 = "" A1786 = "" A1787 = "" A1788 = "" A1789 = "" A1790 = "" -A1791 = "" A1792 = "" A1793 = "" A1794 = "" A1795 = "" A1796 = "" A1797 = "" A1798 = "" A1799 = "" A1800 = "" -A1801 = "" A1802 = "" A1803 = "" A1804 = "" A1805 = "" A1806 = "" A1807 = "" A1808 = "" A1809 = "" A1810 = "" -A1811 = "" A1812 = "" A1813 = "" A1814 = "" A1815 = "" A1816 = "" A1817 = "" A1818 = "" A1819 = "" A1820 = "" -A1821 = "" A1822 = "" A1823 = "" A1824 = "" A1825 = "" A1826 = "" A1827 = "" A1828 = "" A1829 = "" A1830 = "" -A1831 = "" A1832 = "" A1833 = "" A1834 = "" A1835 = "" A1836 = "" A1837 = "" A1838 = "" A1839 = "" A1840 = "" -A1841 = "" A1842 = "" A1843 = "" A1844 = "" A1845 = "" A1846 = "" A1847 = "" A1848 = "" A1849 = "" A1850 = "" -A1851 = "" A1852 = "" A1853 = "" A1854 = "" A1855 = "" A1856 = "" A1857 = "" A1858 = "" A1859 = "" A1860 = "" -A1861 = "" A1862 = "" A1863 = "" A1864 = "" A1865 = "" A1866 = "" A1867 = "" A1868 = "" A1869 = "" A1870 = "" -A1871 = "" A1872 = "" A1873 = "" A1874 = "" A1875 = "" A1876 = "" A1877 = "" A1878 = "" A1879 = "" A1880 = "" -A1881 = "" A1882 = "" A1883 = "" A1884 = "" A1885 = "" A1886 = "" A1887 = "" A1888 = "" A1889 = "" A1890 = "" -A1891 = "" A1892 = "" A1893 = "" A1894 = "" A1895 = "" A1896 = "" A1897 = "" A1898 = "" A1899 = "" A1900 = "" -A1901 = "" A1902 = "" A1903 = "" A1904 = "" A1905 = "" A1906 = "" A1907 = "" A1908 = "" A1909 = "" A1910 = "" -A1911 = "" A1912 = "" A1913 = "" A1914 = "" A1915 = "" A1916 = "" A1917 = "" A1918 = "" A1919 = "" A1920 = "" -A1921 = "" A1922 = "" A1923 = "" A1924 = "" A1925 = "" A1926 = "" A1927 = "" A1928 = "" A1929 = "" A1930 = "" -A1931 = "" A1932 = "" A1933 = "" A1934 = "" A1935 = "" A1936 = "" A1937 = "" A1938 = "" A1939 = "" A1940 = "" -A1941 = "" A1942 = "" A1943 = "" A1944 = "" A1945 = "" A1946 = "" A1947 = "" A1948 = "" A1949 = "" A1950 = "" -A1951 = "" A1952 = "" A1953 = "" A1954 = "" A1955 = "" A1956 = "" A1957 = "" A1958 = "" A1959 = "" A1960 = "" -A1961 = "" A1962 = "" A1963 = "" A1964 = "" A1965 = "" A1966 = "" A1967 = "" A1968 = "" A1969 = "" A1970 = "" -A1971 = "" A1972 = "" A1973 = "" A1974 = "" A1975 = "" A1976 = "" A1977 = "" A1978 = "" A1979 = "" A1980 = "" -A1981 = "" A1982 = "" A1983 = "" A1984 = "" A1985 = "" A1986 = "" A1987 = "" A1988 = "" A1989 = "" A1990 = "" -A1991 = "" A1992 = "" A1993 = "" A1994 = "" A1995 = "" A1996 = "" A1997 = "" A1998 = "" A1999 = "" A2000 = "" -A2001 = "" A2002 = "" A2003 = "" A2004 = "" A2005 = "" A2006 = "" A2007 = "" A2008 = "" A2009 = "" A2010 = "" -A2011 = "" A2012 = "" A2013 = "" A2014 = "" A2015 = "" A2016 = "" A2017 = "" A2018 = "" A2019 = "" A2020 = "" -A2021 = "" A2022 = "" A2023 = "" A2024 = "" A2025 = "" A2026 = "" A2027 = "" A2028 = "" A2029 = "" A2030 = "" -A2031 = "" A2032 = "" A2033 = "" A2034 = "" A2035 = "" A2036 = "" A2037 = "" A2038 = "" A2039 = "" A2040 = "" -A2041 = "" A2042 = "" A2043 = "" A2044 = "" A2045 = "" A2046 = "" A2047 = "" A2048 = "" A2049 = "" A2050 = "" -A2051 = "" A2052 = "" A2053 = "" A2054 = "" A2055 = "" A2056 = "" A2057 = "" A2058 = "" A2059 = "" A2060 = "" -A2061 = "" A2062 = "" A2063 = "" A2064 = "" A2065 = "" A2066 = "" A2067 = "" A2068 = "" A2069 = "" A2070 = "" -A2071 = "" A2072 = "" A2073 = "" A2074 = "" A2075 = "" A2076 = "" A2077 = "" A2078 = "" A2079 = "" A2080 = "" -A2081 = "" A2082 = "" A2083 = "" A2084 = "" A2085 = "" A2086 = "" A2087 = "" A2088 = "" A2089 = "" A2090 = "" -A2091 = "" A2092 = "" A2093 = "" A2094 = "" A2095 = "" A2096 = "" A2097 = "" A2098 = "" A2099 = "" A2100 = "" -A2101 = "" A2102 = "" A2103 = "" A2104 = "" A2105 = "" A2106 = "" A2107 = "" A2108 = "" A2109 = "" A2110 = "" -A2111 = "" A2112 = "" A2113 = "" A2114 = "" A2115 = "" A2116 = "" A2117 = "" A2118 = "" A2119 = "" A2120 = "" -A2121 = "" A2122 = "" A2123 = "" A2124 = "" A2125 = "" A2126 = "" A2127 = "" A2128 = "" A2129 = "" A2130 = "" -A2131 = "" A2132 = "" A2133 = "" A2134 = "" A2135 = "" A2136 = "" A2137 = "" A2138 = "" A2139 = "" A2140 = "" -A2141 = "" A2142 = "" A2143 = "" A2144 = "" A2145 = "" A2146 = "" A2147 = "" A2148 = "" A2149 = "" A2150 = "" -A2151 = "" A2152 = "" A2153 = "" A2154 = "" A2155 = "" A2156 = "" A2157 = "" A2158 = "" A2159 = "" A2160 = "" -A2161 = "" A2162 = "" A2163 = "" A2164 = "" A2165 = "" A2166 = "" A2167 = "" A2168 = "" A2169 = "" A2170 = "" -A2171 = "" A2172 = "" A2173 = "" A2174 = "" A2175 = "" A2176 = "" A2177 = "" A2178 = "" A2179 = "" A2180 = "" -A2181 = "" A2182 = "" A2183 = "" A2184 = "" A2185 = "" A2186 = "" A2187 = "" A2188 = "" A2189 = "" A2190 = "" -A2191 = "" A2192 = "" A2193 = "" A2194 = "" A2195 = "" A2196 = "" A2197 = "" A2198 = "" A2199 = "" A2200 = "" -A2201 = "" A2202 = "" A2203 = "" A2204 = "" A2205 = "" A2206 = "" A2207 = "" A2208 = "" A2209 = "" A2210 = "" -A2211 = "" A2212 = "" A2213 = "" A2214 = "" A2215 = "" A2216 = "" A2217 = "" A2218 = "" A2219 = "" A2220 = "" -A2221 = "" A2222 = "" A2223 = "" A2224 = "" A2225 = "" A2226 = "" A2227 = "" A2228 = "" A2229 = "" A2230 = "" -A2231 = "" A2232 = "" A2233 = "" A2234 = "" A2235 = "" A2236 = "" A2237 = "" A2238 = "" A2239 = "" A2240 = "" -A2241 = "" A2242 = "" A2243 = "" A2244 = "" A2245 = "" A2246 = "" A2247 = "" A2248 = "" A2249 = "" A2250 = "" -A2251 = "" A2252 = "" A2253 = "" A2254 = "" A2255 = "" A2256 = "" A2257 = "" A2258 = "" A2259 = "" A2260 = "" -A2261 = "" A2262 = "" A2263 = "" A2264 = "" A2265 = "" A2266 = "" A2267 = "" A2268 = "" A2269 = "" A2270 = "" -A2271 = "" A2272 = "" A2273 = "" A2274 = "" A2275 = "" A2276 = "" A2277 = "" A2278 = "" A2279 = "" A2280 = "" -A2281 = "" A2282 = "" A2283 = "" A2284 = "" A2285 = "" A2286 = "" A2287 = "" A2288 = "" A2289 = "" A2290 = "" -A2291 = "" A2292 = "" A2293 = "" A2294 = "" A2295 = "" A2296 = "" A2297 = "" A2298 = "" A2299 = "" A2300 = "" -A2301 = "" A2302 = "" A2303 = "" A2304 = "" A2305 = "" A2306 = "" A2307 = "" A2308 = "" A2309 = "" A2310 = "" -A2311 = "" A2312 = "" A2313 = "" A2314 = "" A2315 = "" A2316 = "" A2317 = "" A2318 = "" A2319 = "" A2320 = "" -A2321 = "" A2322 = "" A2323 = "" A2324 = "" A2325 = "" A2326 = "" A2327 = "" A2328 = "" A2329 = "" A2330 = "" -A2331 = "" A2332 = "" A2333 = "" A2334 = "" A2335 = "" A2336 = "" A2337 = "" A2338 = "" A2339 = "" A2340 = "" -A2341 = "" A2342 = "" A2343 = "" A2344 = "" A2345 = "" A2346 = "" A2347 = "" A2348 = "" A2349 = "" A2350 = "" -A2351 = "" A2352 = "" A2353 = "" A2354 = "" A2355 = "" A2356 = "" A2357 = "" A2358 = "" A2359 = "" A2360 = "" -A2361 = "" A2362 = "" A2363 = "" A2364 = "" A2365 = "" A2366 = "" A2367 = "" A2368 = "" A2369 = "" A2370 = "" -A2371 = "" A2372 = "" A2373 = "" A2374 = "" A2375 = "" A2376 = "" A2377 = "" A2378 = "" A2379 = "" A2380 = "" -A2381 = "" A2382 = "" A2383 = "" A2384 = "" A2385 = "" A2386 = "" A2387 = "" A2388 = "" A2389 = "" A2390 = "" -A2391 = "" A2392 = "" A2393 = "" A2394 = "" A2395 = "" A2396 = "" A2397 = "" A2398 = "" A2399 = "" A2400 = "" -A2401 = "" A2402 = "" A2403 = "" A2404 = "" A2405 = "" A2406 = "" A2407 = "" A2408 = "" A2409 = "" A2410 = "" -A2411 = "" A2412 = "" A2413 = "" A2414 = "" A2415 = "" A2416 = "" A2417 = "" A2418 = "" A2419 = "" A2420 = "" -A2421 = "" A2422 = "" A2423 = "" A2424 = "" A2425 = "" A2426 = "" A2427 = "" A2428 = "" A2429 = "" A2430 = "" -A2431 = "" A2432 = "" A2433 = "" A2434 = "" A2435 = "" A2436 = "" A2437 = "" A2438 = "" A2439 = "" A2440 = "" -A2441 = "" A2442 = "" A2443 = "" A2444 = "" A2445 = "" A2446 = "" A2447 = "" A2448 = "" A2449 = "" A2450 = "" -A2451 = "" A2452 = "" A2453 = "" A2454 = "" A2455 = "" A2456 = "" A2457 = "" A2458 = "" A2459 = "" A2460 = "" -A2461 = "" A2462 = "" A2463 = "" A2464 = "" A2465 = "" A2466 = "" A2467 = "" A2468 = "" A2469 = "" A2470 = "" -A2471 = "" A2472 = "" A2473 = "" A2474 = "" A2475 = "" A2476 = "" A2477 = "" A2478 = "" A2479 = "" A2480 = "" -A2481 = "" A2482 = "" A2483 = "" A2484 = "" A2485 = "" A2486 = "" A2487 = "" A2488 = "" A2489 = "" A2490 = "" -A2491 = "" A2492 = "" A2493 = "" A2494 = "" A2495 = "" A2496 = "" A2497 = "" A2498 = "" A2499 = "" A2500 = "" -A2501 = "" A2502 = "" A2503 = "" A2504 = "" A2505 = "" A2506 = "" A2507 = "" A2508 = "" A2509 = "" A2510 = "" -A2511 = "" A2512 = "" A2513 = "" A2514 = "" A2515 = "" A2516 = "" A2517 = "" A2518 = "" A2519 = "" A2520 = "" -A2521 = "" A2522 = "" A2523 = "" A2524 = "" A2525 = "" A2526 = "" A2527 = "" A2528 = "" A2529 = "" A2530 = "" -A2531 = "" A2532 = "" A2533 = "" A2534 = "" A2535 = "" A2536 = "" A2537 = "" A2538 = "" A2539 = "" A2540 = "" -A2541 = "" A2542 = "" A2543 = "" A2544 = "" A2545 = "" A2546 = "" A2547 = "" A2548 = "" A2549 = "" A2550 = "" -A2551 = "" A2552 = "" A2553 = "" A2554 = "" A2555 = "" A2556 = "" A2557 = "" A2558 = "" A2559 = "" A2560 = "" -A2561 = "" A2562 = "" A2563 = "" A2564 = "" A2565 = "" A2566 = "" A2567 = "" A2568 = "" A2569 = "" A2570 = "" -A2571 = "" A2572 = "" A2573 = "" A2574 = "" A2575 = "" A2576 = "" A2577 = "" A2578 = "" A2579 = "" A2580 = "" -A2581 = "" A2582 = "" A2583 = "" A2584 = "" A2585 = "" A2586 = "" A2587 = "" A2588 = "" A2589 = "" A2590 = "" -A2591 = "" A2592 = "" A2593 = "" A2594 = "" A2595 = "" A2596 = "" A2597 = "" A2598 = "" A2599 = "" A2600 = "" -A2601 = "" A2602 = "" A2603 = "" A2604 = "" A2605 = "" A2606 = "" A2607 = "" A2608 = "" A2609 = "" A2610 = "" -A2611 = "" A2612 = "" A2613 = "" A2614 = "" A2615 = "" A2616 = "" A2617 = "" A2618 = "" A2619 = "" A2620 = "" -A2621 = "" A2622 = "" A2623 = "" A2624 = "" A2625 = "" A2626 = "" A2627 = "" A2628 = "" A2629 = "" A2630 = "" -A2631 = "" A2632 = "" A2633 = "" A2634 = "" A2635 = "" A2636 = "" A2637 = "" A2638 = "" A2639 = "" A2640 = "" -A2641 = "" A2642 = "" A2643 = "" A2644 = "" A2645 = "" A2646 = "" A2647 = "" A2648 = "" A2649 = "" A2650 = "" -A2651 = "" A2652 = "" A2653 = "" A2654 = "" A2655 = "" A2656 = "" A2657 = "" A2658 = "" A2659 = "" A2660 = "" -A2661 = "" A2662 = "" A2663 = "" A2664 = "" A2665 = "" A2666 = "" A2667 = "" A2668 = "" A2669 = "" A2670 = "" -A2671 = "" A2672 = "" A2673 = "" A2674 = "" A2675 = "" A2676 = "" A2677 = "" A2678 = "" A2679 = "" A2680 = "" -A2681 = "" A2682 = "" A2683 = "" A2684 = "" A2685 = "" A2686 = "" A2687 = "" A2688 = "" A2689 = "" A2690 = "" -A2691 = "" A2692 = "" A2693 = "" A2694 = "" A2695 = "" A2696 = "" A2697 = "" A2698 = "" A2699 = "" A2700 = "" -A2701 = "" A2702 = "" A2703 = "" A2704 = "" A2705 = "" A2706 = "" A2707 = "" A2708 = "" A2709 = "" A2710 = "" -A2711 = "" A2712 = "" A2713 = "" A2714 = "" A2715 = "" A2716 = "" A2717 = "" A2718 = "" A2719 = "" A2720 = "" -A2721 = "" A2722 = "" A2723 = "" A2724 = "" A2725 = "" A2726 = "" A2727 = "" A2728 = "" A2729 = "" A2730 = "" -A2731 = "" A2732 = "" A2733 = "" A2734 = "" A2735 = "" A2736 = "" A2737 = "" A2738 = "" A2739 = "" A2740 = "" -A2741 = "" A2742 = "" A2743 = "" A2744 = "" A2745 = "" A2746 = "" A2747 = "" A2748 = "" A2749 = "" A2750 = "" -A2751 = "" A2752 = "" A2753 = "" A2754 = "" A2755 = "" A2756 = "" A2757 = "" A2758 = "" A2759 = "" A2760 = "" -A2761 = "" A2762 = "" A2763 = "" A2764 = "" A2765 = "" A2766 = "" A2767 = "" A2768 = "" A2769 = "" A2770 = "" -A2771 = "" A2772 = "" A2773 = "" A2774 = "" A2775 = "" A2776 = "" A2777 = "" A2778 = "" A2779 = "" A2780 = "" -A2781 = "" A2782 = "" A2783 = "" A2784 = "" A2785 = "" A2786 = "" A2787 = "" A2788 = "" A2789 = "" A2790 = "" -A2791 = "" A2792 = "" A2793 = "" A2794 = "" A2795 = "" A2796 = "" A2797 = "" A2798 = "" A2799 = "" A2800 = "" -A2801 = "" A2802 = "" A2803 = "" A2804 = "" A2805 = "" A2806 = "" A2807 = "" A2808 = "" A2809 = "" A2810 = "" -A2811 = "" A2812 = "" A2813 = "" A2814 = "" A2815 = "" A2816 = "" A2817 = "" A2818 = "" A2819 = "" A2820 = "" -A2821 = "" A2822 = "" A2823 = "" A2824 = "" A2825 = "" A2826 = "" A2827 = "" A2828 = "" A2829 = "" A2830 = "" -A2831 = "" A2832 = "" A2833 = "" A2834 = "" A2835 = "" A2836 = "" A2837 = "" A2838 = "" A2839 = "" A2840 = "" -A2841 = "" A2842 = "" A2843 = "" A2844 = "" A2845 = "" A2846 = "" A2847 = "" A2848 = "" A2849 = "" A2850 = "" -A2851 = "" A2852 = "" A2853 = "" A2854 = "" A2855 = "" A2856 = "" A2857 = "" A2858 = "" A2859 = "" A2860 = "" -A2861 = "" A2862 = "" A2863 = "" A2864 = "" A2865 = "" A2866 = "" A2867 = "" A2868 = "" A2869 = "" A2870 = "" -A2871 = "" A2872 = "" A2873 = "" A2874 = "" A2875 = "" A2876 = "" A2877 = "" A2878 = "" A2879 = "" A2880 = "" -A2881 = "" A2882 = "" A2883 = "" A2884 = "" A2885 = "" A2886 = "" A2887 = "" A2888 = "" A2889 = "" A2890 = "" -A2891 = "" A2892 = "" A2893 = "" A2894 = "" A2895 = "" A2896 = "" A2897 = "" A2898 = "" A2899 = "" A2900 = "" -A2901 = "" A2902 = "" A2903 = "" A2904 = "" A2905 = "" A2906 = "" A2907 = "" A2908 = "" A2909 = "" A2910 = "" -A2911 = "" A2912 = "" A2913 = "" A2914 = "" A2915 = "" A2916 = "" A2917 = "" A2918 = "" A2919 = "" A2920 = "" -A2921 = "" A2922 = "" A2923 = "" A2924 = "" A2925 = "" A2926 = "" A2927 = "" A2928 = "" A2929 = "" A2930 = "" -A2931 = "" A2932 = "" A2933 = "" A2934 = "" A2935 = "" A2936 = "" A2937 = "" A2938 = "" A2939 = "" A2940 = "" -A2941 = "" A2942 = "" A2943 = "" A2944 = "" A2945 = "" A2946 = "" A2947 = "" A2948 = "" A2949 = "" A2950 = "" -A2951 = "" A2952 = "" A2953 = "" A2954 = "" A2955 = "" A2956 = "" A2957 = "" A2958 = "" A2959 = "" A2960 = "" -A2961 = "" A2962 = "" A2963 = "" A2964 = "" A2965 = "" A2966 = "" A2967 = "" A2968 = "" A2969 = "" A2970 = "" -A2971 = "" A2972 = "" A2973 = "" A2974 = "" A2975 = "" A2976 = "" A2977 = "" A2978 = "" A2979 = "" A2980 = "" -A2981 = "" A2982 = "" A2983 = "" A2984 = "" A2985 = "" A2986 = "" A2987 = "" A2988 = "" A2989 = "" A2990 = "" -A2991 = "" A2992 = "" A2993 = "" A2994 = "" A2995 = "" A2996 = "" A2997 = "" A2998 = "" A2999 = "" A3000 = "" -A3001 = "" A3002 = "" A3003 = "" A3004 = "" A3005 = "" A3006 = "" A3007 = "" A3008 = "" A3009 = "" A3010 = "" -A3011 = "" A3012 = "" A3013 = "" A3014 = "" A3015 = "" A3016 = "" A3017 = "" A3018 = "" A3019 = "" A3020 = "" -A3021 = "" A3022 = "" A3023 = "" A3024 = "" A3025 = "" A3026 = "" A3027 = "" A3028 = "" A3029 = "" A3030 = "" -A3031 = "" A3032 = "" A3033 = "" A3034 = "" A3035 = "" A3036 = "" A3037 = "" A3038 = "" A3039 = "" A3040 = "" -A3041 = "" A3042 = "" A3043 = "" A3044 = "" A3045 = "" A3046 = "" A3047 = "" A3048 = "" A3049 = "" A3050 = "" -A3051 = "" A3052 = "" A3053 = "" A3054 = "" A3055 = "" A3056 = "" A3057 = "" A3058 = "" A3059 = "" A3060 = "" -A3061 = "" A3062 = "" A3063 = "" A3064 = "" A3065 = "" A3066 = "" A3067 = "" A3068 = "" A3069 = "" A3070 = "" -A3071 = "" A3072 = "" A3073 = "" A3074 = "" A3075 = "" A3076 = "" A3077 = "" A3078 = "" A3079 = "" A3080 = "" -A3081 = "" A3082 = "" A3083 = "" A3084 = "" A3085 = "" A3086 = "" A3087 = "" A3088 = "" A3089 = "" A3090 = "" -A3091 = "" A3092 = "" A3093 = "" A3094 = "" A3095 = "" A3096 = "" A3097 = "" A3098 = "" A3099 = "" A3100 = "" -A3101 = "" A3102 = "" A3103 = "" A3104 = "" A3105 = "" A3106 = "" A3107 = "" A3108 = "" A3109 = "" A3110 = "" -A3111 = "" A3112 = "" A3113 = "" A3114 = "" A3115 = "" A3116 = "" A3117 = "" A3118 = "" A3119 = "" A3120 = "" -A3121 = "" A3122 = "" A3123 = "" A3124 = "" A3125 = "" A3126 = "" A3127 = "" A3128 = "" A3129 = "" A3130 = "" -A3131 = "" A3132 = "" A3133 = "" A3134 = "" A3135 = "" A3136 = "" A3137 = "" A3138 = "" A3139 = "" A3140 = "" -A3141 = "" A3142 = "" A3143 = "" A3144 = "" A3145 = "" A3146 = "" A3147 = "" A3148 = "" A3149 = "" A3150 = "" -A3151 = "" A3152 = "" A3153 = "" A3154 = "" A3155 = "" A3156 = "" A3157 = "" A3158 = "" A3159 = "" A3160 = "" -A3161 = "" A3162 = "" A3163 = "" A3164 = "" A3165 = "" A3166 = "" A3167 = "" A3168 = "" A3169 = "" A3170 = "" -A3171 = "" A3172 = "" A3173 = "" A3174 = "" A3175 = "" A3176 = "" A3177 = "" A3178 = "" A3179 = "" A3180 = "" -A3181 = "" A3182 = "" A3183 = "" A3184 = "" A3185 = "" A3186 = "" A3187 = "" A3188 = "" A3189 = "" A3190 = "" -A3191 = "" A3192 = "" A3193 = "" A3194 = "" A3195 = "" A3196 = "" A3197 = "" A3198 = "" A3199 = "" A3200 = "" -A3201 = "" A3202 = "" A3203 = "" A3204 = "" A3205 = "" A3206 = "" A3207 = "" A3208 = "" A3209 = "" A3210 = "" -A3211 = "" A3212 = "" A3213 = "" A3214 = "" A3215 = "" A3216 = "" A3217 = "" A3218 = "" A3219 = "" A3220 = "" -A3221 = "" A3222 = "" A3223 = "" A3224 = "" A3225 = "" A3226 = "" A3227 = "" A3228 = "" A3229 = "" A3230 = "" -A3231 = "" A3232 = "" A3233 = "" A3234 = "" A3235 = "" A3236 = "" A3237 = "" A3238 = "" A3239 = "" A3240 = "" -A3241 = "" A3242 = "" A3243 = "" A3244 = "" A3245 = "" A3246 = "" A3247 = "" A3248 = "" A3249 = "" A3250 = "" -A3251 = "" A3252 = "" A3253 = "" A3254 = "" A3255 = "" A3256 = "" A3257 = "" A3258 = "" A3259 = "" A3260 = "" -A3261 = "" A3262 = "" A3263 = "" A3264 = "" A3265 = "" A3266 = "" A3267 = "" A3268 = "" A3269 = "" A3270 = "" -A3271 = "" A3272 = "" A3273 = "" A3274 = "" A3275 = "" A3276 = "" A3277 = "" A3278 = "" A3279 = "" A3280 = "" -A3281 = "" A3282 = "" A3283 = "" A3284 = "" A3285 = "" A3286 = "" A3287 = "" A3288 = "" A3289 = "" A3290 = "" -A3291 = "" A3292 = "" A3293 = "" A3294 = "" A3295 = "" A3296 = "" A3297 = "" A3298 = "" A3299 = "" A3300 = "" -A3301 = "" A3302 = "" A3303 = "" A3304 = "" A3305 = "" A3306 = "" A3307 = "" A3308 = "" A3309 = "" A3310 = "" -A3311 = "" A3312 = "" A3313 = "" A3314 = "" A3315 = "" A3316 = "" A3317 = "" A3318 = "" A3319 = "" A3320 = "" -A3321 = "" A3322 = "" A3323 = "" A3324 = "" A3325 = "" A3326 = "" A3327 = "" A3328 = "" A3329 = "" A3330 = "" -A3331 = "" A3332 = "" A3333 = "" A3334 = "" A3335 = "" A3336 = "" A3337 = "" A3338 = "" A3339 = "" A3340 = "" -A3341 = "" A3342 = "" A3343 = "" A3344 = "" A3345 = "" A3346 = "" A3347 = "" A3348 = "" A3349 = "" A3350 = "" -A3351 = "" A3352 = "" A3353 = "" A3354 = "" A3355 = "" A3356 = "" A3357 = "" A3358 = "" A3359 = "" A3360 = "" -A3361 = "" A3362 = "" A3363 = "" A3364 = "" A3365 = "" A3366 = "" A3367 = "" A3368 = "" A3369 = "" A3370 = "" -A3371 = "" A3372 = "" A3373 = "" A3374 = "" A3375 = "" A3376 = "" A3377 = "" A3378 = "" A3379 = "" A3380 = "" -A3381 = "" A3382 = "" A3383 = "" A3384 = "" A3385 = "" A3386 = "" A3387 = "" A3388 = "" A3389 = "" A3390 = "" -A3391 = "" A3392 = "" A3393 = "" A3394 = "" A3395 = "" A3396 = "" A3397 = "" A3398 = "" A3399 = "" A3400 = "" -A3401 = "" A3402 = "" A3403 = "" A3404 = "" A3405 = "" A3406 = "" A3407 = "" A3408 = "" A3409 = "" A3410 = "" -A3411 = "" A3412 = "" A3413 = "" A3414 = "" A3415 = "" A3416 = "" A3417 = "" A3418 = "" A3419 = "" A3420 = "" -A3421 = "" A3422 = "" A3423 = "" A3424 = "" A3425 = "" A3426 = "" A3427 = "" A3428 = "" A3429 = "" A3430 = "" -A3431 = "" A3432 = "" A3433 = "" A3434 = "" A3435 = "" A3436 = "" A3437 = "" A3438 = "" A3439 = "" A3440 = "" -A3441 = "" A3442 = "" A3443 = "" A3444 = "" A3445 = "" A3446 = "" A3447 = "" A3448 = "" A3449 = "" A3450 = "" -A3451 = "" A3452 = "" A3453 = "" A3454 = "" A3455 = "" A3456 = "" A3457 = "" A3458 = "" A3459 = "" A3460 = "" -A3461 = "" A3462 = "" A3463 = "" A3464 = "" A3465 = "" A3466 = "" A3467 = "" A3468 = "" A3469 = "" A3470 = "" -A3471 = "" A3472 = "" A3473 = "" A3474 = "" A3475 = "" A3476 = "" A3477 = "" A3478 = "" A3479 = "" A3480 = "" -A3481 = "" A3482 = "" A3483 = "" A3484 = "" A3485 = "" A3486 = "" A3487 = "" A3488 = "" A3489 = "" A3490 = "" -A3491 = "" A3492 = "" A3493 = "" A3494 = "" A3495 = "" A3496 = "" A3497 = "" A3498 = "" A3499 = "" A3500 = "" -A3501 = "" A3502 = "" A3503 = "" A3504 = "" A3505 = "" A3506 = "" A3507 = "" A3508 = "" A3509 = "" A3510 = "" -A3511 = "" A3512 = "" A3513 = "" A3514 = "" A3515 = "" A3516 = "" A3517 = "" A3518 = "" A3519 = "" A3520 = "" -A3521 = "" A3522 = "" A3523 = "" A3524 = "" A3525 = "" A3526 = "" A3527 = "" A3528 = "" A3529 = "" A3530 = "" -A3531 = "" A3532 = "" A3533 = "" A3534 = "" A3535 = "" A3536 = "" A3537 = "" A3538 = "" A3539 = "" A3540 = "" -A3541 = "" A3542 = "" A3543 = "" A3544 = "" A3545 = "" A3546 = "" A3547 = "" A3548 = "" A3549 = "" A3550 = "" -A3551 = "" A3552 = "" A3553 = "" A3554 = "" A3555 = "" A3556 = "" A3557 = "" A3558 = "" A3559 = "" A3560 = "" -A3561 = "" A3562 = "" A3563 = "" A3564 = "" A3565 = "" A3566 = "" A3567 = "" A3568 = "" A3569 = "" A3570 = "" -A3571 = "" A3572 = "" A3573 = "" A3574 = "" A3575 = "" A3576 = "" A3577 = "" A3578 = "" A3579 = "" A3580 = "" -A3581 = "" A3582 = "" A3583 = "" A3584 = "" A3585 = "" A3586 = "" A3587 = "" A3588 = "" A3589 = "" A3590 = "" -A3591 = "" A3592 = "" A3593 = "" A3594 = "" A3595 = "" A3596 = "" A3597 = "" A3598 = "" A3599 = "" A3600 = "" -A3601 = "" A3602 = "" A3603 = "" A3604 = "" A3605 = "" A3606 = "" A3607 = "" A3608 = "" A3609 = "" A3610 = "" -A3611 = "" A3612 = "" A3613 = "" A3614 = "" A3615 = "" A3616 = "" A3617 = "" A3618 = "" A3619 = "" A3620 = "" -A3621 = "" A3622 = "" A3623 = "" A3624 = "" A3625 = "" A3626 = "" A3627 = "" A3628 = "" A3629 = "" A3630 = "" -A3631 = "" A3632 = "" A3633 = "" A3634 = "" A3635 = "" A3636 = "" A3637 = "" A3638 = "" A3639 = "" A3640 = "" -A3641 = "" A3642 = "" A3643 = "" A3644 = "" A3645 = "" A3646 = "" A3647 = "" A3648 = "" A3649 = "" A3650 = "" -A3651 = "" A3652 = "" A3653 = "" A3654 = "" A3655 = "" A3656 = "" A3657 = "" A3658 = "" A3659 = "" A3660 = "" -A3661 = "" A3662 = "" A3663 = "" A3664 = "" A3665 = "" A3666 = "" A3667 = "" A3668 = "" A3669 = "" A3670 = "" -A3671 = "" A3672 = "" A3673 = "" A3674 = "" A3675 = "" A3676 = "" A3677 = "" A3678 = "" A3679 = "" A3680 = "" -A3681 = "" A3682 = "" A3683 = "" A3684 = "" A3685 = "" A3686 = "" A3687 = "" A3688 = "" A3689 = "" A3690 = "" -A3691 = "" A3692 = "" A3693 = "" A3694 = "" A3695 = "" A3696 = "" A3697 = "" A3698 = "" A3699 = "" A3700 = "" -A3701 = "" A3702 = "" A3703 = "" A3704 = "" A3705 = "" A3706 = "" A3707 = "" A3708 = "" A3709 = "" A3710 = "" -A3711 = "" A3712 = "" A3713 = "" A3714 = "" A3715 = "" A3716 = "" A3717 = "" A3718 = "" A3719 = "" A3720 = "" -A3721 = "" A3722 = "" A3723 = "" A3724 = "" A3725 = "" A3726 = "" A3727 = "" A3728 = "" A3729 = "" A3730 = "" -A3731 = "" A3732 = "" A3733 = "" A3734 = "" A3735 = "" A3736 = "" A3737 = "" A3738 = "" A3739 = "" A3740 = "" -A3741 = "" A3742 = "" A3743 = "" A3744 = "" A3745 = "" A3746 = "" A3747 = "" A3748 = "" A3749 = "" A3750 = "" -A3751 = "" A3752 = "" A3753 = "" A3754 = "" A3755 = "" A3756 = "" A3757 = "" A3758 = "" A3759 = "" A3760 = "" -A3761 = "" A3762 = "" A3763 = "" A3764 = "" A3765 = "" A3766 = "" A3767 = "" A3768 = "" A3769 = "" A3770 = "" -A3771 = "" A3772 = "" A3773 = "" A3774 = "" A3775 = "" A3776 = "" A3777 = "" A3778 = "" A3779 = "" A3780 = "" -A3781 = "" A3782 = "" A3783 = "" A3784 = "" A3785 = "" A3786 = "" A3787 = "" A3788 = "" A3789 = "" A3790 = "" -A3791 = "" A3792 = "" A3793 = "" A3794 = "" A3795 = "" A3796 = "" A3797 = "" A3798 = "" A3799 = "" A3800 = "" -A3801 = "" A3802 = "" A3803 = "" A3804 = "" A3805 = "" A3806 = "" A3807 = "" A3808 = "" A3809 = "" A3810 = "" -A3811 = "" A3812 = "" A3813 = "" A3814 = "" A3815 = "" A3816 = "" A3817 = "" A3818 = "" A3819 = "" A3820 = "" -A3821 = "" A3822 = "" A3823 = "" A3824 = "" A3825 = "" A3826 = "" A3827 = "" A3828 = "" A3829 = "" A3830 = "" -A3831 = "" A3832 = "" A3833 = "" A3834 = "" A3835 = "" A3836 = "" A3837 = "" A3838 = "" A3839 = "" A3840 = "" -A3841 = "" A3842 = "" A3843 = "" A3844 = "" A3845 = "" A3846 = "" A3847 = "" A3848 = "" A3849 = "" A3850 = "" -A3851 = "" A3852 = "" A3853 = "" A3854 = "" A3855 = "" A3856 = "" A3857 = "" A3858 = "" A3859 = "" A3860 = "" -A3861 = "" A3862 = "" A3863 = "" A3864 = "" A3865 = "" A3866 = "" A3867 = "" A3868 = "" A3869 = "" A3870 = "" -A3871 = "" A3872 = "" A3873 = "" A3874 = "" A3875 = "" A3876 = "" A3877 = "" A3878 = "" A3879 = "" A3880 = "" -A3881 = "" A3882 = "" A3883 = "" A3884 = "" A3885 = "" A3886 = "" A3887 = "" A3888 = "" A3889 = "" A3890 = "" -A3891 = "" A3892 = "" A3893 = "" A3894 = "" A3895 = "" A3896 = "" A3897 = "" A3898 = "" A3899 = "" A3900 = "" -A3901 = "" A3902 = "" A3903 = "" A3904 = "" A3905 = "" A3906 = "" A3907 = "" A3908 = "" A3909 = "" A3910 = "" -A3911 = "" A3912 = "" A3913 = "" A3914 = "" A3915 = "" A3916 = "" A3917 = "" A3918 = "" A3919 = "" A3920 = "" -A3921 = "" A3922 = "" A3923 = "" A3924 = "" A3925 = "" A3926 = "" A3927 = "" A3928 = "" A3929 = "" A3930 = "" -A3931 = "" A3932 = "" A3933 = "" A3934 = "" A3935 = "" A3936 = "" A3937 = "" A3938 = "" A3939 = "" A3940 = "" -A3941 = "" A3942 = "" A3943 = "" A3944 = "" A3945 = "" A3946 = "" A3947 = "" A3948 = "" A3949 = "" A3950 = "" -A3951 = "" A3952 = "" A3953 = "" A3954 = "" A3955 = "" A3956 = "" A3957 = "" A3958 = "" A3959 = "" A3960 = "" -A3961 = "" A3962 = "" A3963 = "" A3964 = "" A3965 = "" A3966 = "" A3967 = "" A3968 = "" A3969 = "" A3970 = "" -A3971 = "" A3972 = "" A3973 = "" A3974 = "" A3975 = "" A3976 = "" A3977 = "" A3978 = "" A3979 = "" A3980 = "" -A3981 = "" A3982 = "" A3983 = "" A3984 = "" A3985 = "" A3986 = "" A3987 = "" A3988 = "" A3989 = "" A3990 = "" -A3991 = "" A3992 = "" A3993 = "" A3994 = "" A3995 = "" A3996 = "" A3997 = "" A3998 = "" A3999 = "" A4000 = "" -A4001 = "" A4002 = "" A4003 = "" A4004 = "" A4005 = "" A4006 = "" A4007 = "" A4008 = "" A4009 = "" A4010 = "" -A4011 = "" A4012 = "" A4013 = "" A4014 = "" A4015 = "" A4016 = "" A4017 = "" A4018 = "" A4019 = "" A4020 = "" -A4021 = "" A4022 = "" A4023 = "" A4024 = "" A4025 = "" A4026 = "" A4027 = "" A4028 = "" A4029 = "" A4030 = "" -A4031 = "" A4032 = "" A4033 = "" A4034 = "" A4035 = "" A4036 = "" A4037 = "" A4038 = "" A4039 = "" A4040 = "" -A4041 = "" A4042 = "" A4043 = "" A4044 = "" A4045 = "" A4046 = "" A4047 = "" A4048 = "" A4049 = "" A4050 = "" -A4051 = "" A4052 = "" A4053 = "" A4054 = "" A4055 = "" A4056 = "" A4057 = "" A4058 = "" A4059 = "" A4060 = "" -A4061 = "" A4062 = "" A4063 = "" A4064 = "" A4065 = "" A4066 = "" A4067 = "" A4068 = "" A4069 = "" A4070 = "" -A4071 = "" A4072 = "" A4073 = "" A4074 = "" A4075 = "" A4076 = "" A4077 = "" A4078 = "" A4079 = "" A4080 = "" -A4081 = "" A4082 = "" A4083 = "" A4084 = "" A4085 = "" A4086 = "" A4087 = "" A4088 = "" A4089 = "" A4090 = "" -A4091 = "" A4092 = "" A4093 = "" A4094 = "" A4095 = "" A4096 = "" A4097 = "" A4098 = "" A4099 = "" A4100 = "" -A4101 = "" A4102 = "" A4103 = "" A4104 = "" A4105 = "" A4106 = "" A4107 = "" A4108 = "" A4109 = "" A4110 = "" -A4111 = "" A4112 = "" A4113 = "" A4114 = "" A4115 = "" A4116 = "" A4117 = "" A4118 = "" A4119 = "" A4120 = "" -A4121 = "" A4122 = "" A4123 = "" A4124 = "" A4125 = "" A4126 = "" A4127 = "" A4128 = "" A4129 = "" A4130 = "" -A4131 = "" A4132 = "" A4133 = "" A4134 = "" A4135 = "" A4136 = "" A4137 = "" A4138 = "" A4139 = "" A4140 = "" -A4141 = "" A4142 = "" A4143 = "" A4144 = "" A4145 = "" A4146 = "" A4147 = "" A4148 = "" A4149 = "" A4150 = "" -A4151 = "" A4152 = "" A4153 = "" A4154 = "" A4155 = "" A4156 = "" A4157 = "" A4158 = "" A4159 = "" A4160 = "" -A4161 = "" A4162 = "" A4163 = "" A4164 = "" A4165 = "" A4166 = "" A4167 = "" A4168 = "" A4169 = "" A4170 = "" -A4171 = "" A4172 = "" A4173 = "" A4174 = "" A4175 = "" A4176 = "" A4177 = "" A4178 = "" A4179 = "" A4180 = "" -A4181 = "" A4182 = "" A4183 = "" A4184 = "" A4185 = "" A4186 = "" A4187 = "" A4188 = "" A4189 = "" A4190 = "" -A4191 = "" A4192 = "" A4193 = "" A4194 = "" A4195 = "" A4196 = "" A4197 = "" A4198 = "" A4199 = "" A4200 = "" -A4201 = "" A4202 = "" A4203 = "" A4204 = "" A4205 = "" A4206 = "" A4207 = "" A4208 = "" A4209 = "" A4210 = "" -A4211 = "" A4212 = "" A4213 = "" A4214 = "" A4215 = "" A4216 = "" A4217 = "" A4218 = "" A4219 = "" A4220 = "" -A4221 = "" A4222 = "" A4223 = "" A4224 = "" A4225 = "" A4226 = "" A4227 = "" A4228 = "" A4229 = "" A4230 = "" -A4231 = "" A4232 = "" A4233 = "" A4234 = "" A4235 = "" A4236 = "" A4237 = "" A4238 = "" A4239 = "" A4240 = "" -A4241 = "" A4242 = "" A4243 = "" A4244 = "" A4245 = "" A4246 = "" A4247 = "" A4248 = "" A4249 = "" A4250 = "" -A4251 = "" A4252 = "" A4253 = "" A4254 = "" A4255 = "" A4256 = "" A4257 = "" A4258 = "" A4259 = "" A4260 = "" -A4261 = "" A4262 = "" A4263 = "" A4264 = "" A4265 = "" A4266 = "" A4267 = "" A4268 = "" A4269 = "" A4270 = "" -A4271 = "" A4272 = "" A4273 = "" A4274 = "" A4275 = "" A4276 = "" A4277 = "" A4278 = "" A4279 = "" A4280 = "" -A4281 = "" A4282 = "" A4283 = "" A4284 = "" A4285 = "" A4286 = "" A4287 = "" A4288 = "" A4289 = "" A4290 = "" -A4291 = "" A4292 = "" A4293 = "" A4294 = "" A4295 = "" A4296 = "" A4297 = "" A4298 = "" A4299 = "" A4300 = "" -A4301 = "" A4302 = "" A4303 = "" A4304 = "" A4305 = "" A4306 = "" A4307 = "" A4308 = "" A4309 = "" A4310 = "" -A4311 = "" A4312 = "" A4313 = "" A4314 = "" A4315 = "" A4316 = "" A4317 = "" A4318 = "" A4319 = "" A4320 = "" -A4321 = "" A4322 = "" A4323 = "" A4324 = "" A4325 = "" A4326 = "" A4327 = "" A4328 = "" A4329 = "" A4330 = "" -A4331 = "" A4332 = "" A4333 = "" A4334 = "" A4335 = "" A4336 = "" A4337 = "" A4338 = "" A4339 = "" A4340 = "" -A4341 = "" A4342 = "" A4343 = "" A4344 = "" A4345 = "" A4346 = "" A4347 = "" A4348 = "" A4349 = "" A4350 = "" -A4351 = "" A4352 = "" A4353 = "" A4354 = "" A4355 = "" A4356 = "" A4357 = "" A4358 = "" A4359 = "" A4360 = "" -A4361 = "" A4362 = "" A4363 = "" A4364 = "" A4365 = "" A4366 = "" A4367 = "" A4368 = "" A4369 = "" A4370 = "" -A4371 = "" A4372 = "" A4373 = "" A4374 = "" A4375 = "" A4376 = "" A4377 = "" A4378 = "" A4379 = "" A4380 = "" -A4381 = "" A4382 = "" A4383 = "" A4384 = "" A4385 = "" A4386 = "" A4387 = "" A4388 = "" A4389 = "" A4390 = "" -A4391 = "" A4392 = "" A4393 = "" A4394 = "" A4395 = "" A4396 = "" A4397 = "" A4398 = "" A4399 = "" A4400 = "" -A4401 = "" A4402 = "" A4403 = "" A4404 = "" A4405 = "" A4406 = "" A4407 = "" A4408 = "" A4409 = "" A4410 = "" -A4411 = "" A4412 = "" A4413 = "" A4414 = "" A4415 = "" A4416 = "" A4417 = "" A4418 = "" A4419 = "" A4420 = "" -A4421 = "" A4422 = "" A4423 = "" A4424 = "" A4425 = "" A4426 = "" A4427 = "" A4428 = "" A4429 = "" A4430 = "" -A4431 = "" A4432 = "" A4433 = "" A4434 = "" A4435 = "" A4436 = "" A4437 = "" A4438 = "" A4439 = "" A4440 = "" -A4441 = "" A4442 = "" A4443 = "" A4444 = "" A4445 = "" A4446 = "" A4447 = "" A4448 = "" A4449 = "" A4450 = "" -A4451 = "" A4452 = "" A4453 = "" A4454 = "" A4455 = "" A4456 = "" A4457 = "" A4458 = "" A4459 = "" A4460 = "" -A4461 = "" A4462 = "" A4463 = "" A4464 = "" A4465 = "" A4466 = "" A4467 = "" A4468 = "" A4469 = "" A4470 = "" -A4471 = "" A4472 = "" A4473 = "" A4474 = "" A4475 = "" A4476 = "" A4477 = "" A4478 = "" A4479 = "" A4480 = "" -A4481 = "" A4482 = "" A4483 = "" A4484 = "" A4485 = "" A4486 = "" A4487 = "" A4488 = "" A4489 = "" A4490 = "" -A4491 = "" A4492 = "" A4493 = "" A4494 = "" A4495 = "" A4496 = "" A4497 = "" A4498 = "" A4499 = "" A4500 = "" -A4501 = "" A4502 = "" A4503 = "" A4504 = "" A4505 = "" A4506 = "" A4507 = "" A4508 = "" A4509 = "" A4510 = "" -A4511 = "" A4512 = "" A4513 = "" A4514 = "" A4515 = "" A4516 = "" A4517 = "" A4518 = "" A4519 = "" A4520 = "" -A4521 = "" A4522 = "" A4523 = "" A4524 = "" A4525 = "" A4526 = "" A4527 = "" A4528 = "" A4529 = "" A4530 = "" -A4531 = "" A4532 = "" A4533 = "" A4534 = "" A4535 = "" A4536 = "" A4537 = "" A4538 = "" A4539 = "" A4540 = "" -A4541 = "" A4542 = "" A4543 = "" A4544 = "" A4545 = "" A4546 = "" A4547 = "" A4548 = "" A4549 = "" A4550 = "" -A4551 = "" A4552 = "" A4553 = "" A4554 = "" A4555 = "" A4556 = "" A4557 = "" A4558 = "" A4559 = "" A4560 = "" -A4561 = "" A4562 = "" A4563 = "" A4564 = "" A4565 = "" A4566 = "" A4567 = "" A4568 = "" A4569 = "" A4570 = "" -A4571 = "" A4572 = "" A4573 = "" A4574 = "" A4575 = "" A4576 = "" A4577 = "" A4578 = "" A4579 = "" A4580 = "" -A4581 = "" A4582 = "" A4583 = "" A4584 = "" A4585 = "" A4586 = "" A4587 = "" A4588 = "" A4589 = "" A4590 = "" -A4591 = "" A4592 = "" A4593 = "" A4594 = "" A4595 = "" A4596 = "" A4597 = "" A4598 = "" A4599 = "" A4600 = "" -A4601 = "" A4602 = "" A4603 = "" A4604 = "" A4605 = "" A4606 = "" A4607 = "" A4608 = "" A4609 = "" A4610 = "" -A4611 = "" A4612 = "" A4613 = "" A4614 = "" A4615 = "" A4616 = "" A4617 = "" A4618 = "" A4619 = "" A4620 = "" -A4621 = "" A4622 = "" A4623 = "" A4624 = "" A4625 = "" A4626 = "" A4627 = "" A4628 = "" A4629 = "" A4630 = "" -A4631 = "" A4632 = "" A4633 = "" A4634 = "" A4635 = "" A4636 = "" A4637 = "" A4638 = "" A4639 = "" A4640 = "" -A4641 = "" A4642 = "" A4643 = "" A4644 = "" A4645 = "" A4646 = "" A4647 = "" A4648 = "" A4649 = "" A4650 = "" -A4651 = "" A4652 = "" A4653 = "" A4654 = "" A4655 = "" A4656 = "" A4657 = "" A4658 = "" A4659 = "" A4660 = "" -A4661 = "" A4662 = "" A4663 = "" A4664 = "" A4665 = "" A4666 = "" A4667 = "" A4668 = "" A4669 = "" A4670 = "" -A4671 = "" A4672 = "" A4673 = "" A4674 = "" A4675 = "" A4676 = "" A4677 = "" A4678 = "" A4679 = "" A4680 = "" -A4681 = "" A4682 = "" A4683 = "" A4684 = "" A4685 = "" A4686 = "" A4687 = "" A4688 = "" A4689 = "" A4690 = "" -A4691 = "" A4692 = "" A4693 = "" A4694 = "" A4695 = "" A4696 = "" A4697 = "" A4698 = "" A4699 = "" A4700 = "" -A4701 = "" A4702 = "" A4703 = "" A4704 = "" A4705 = "" A4706 = "" A4707 = "" A4708 = "" A4709 = "" A4710 = "" -A4711 = "" A4712 = "" A4713 = "" A4714 = "" A4715 = "" A4716 = "" A4717 = "" A4718 = "" A4719 = "" A4720 = "" -A4721 = "" A4722 = "" A4723 = "" A4724 = "" A4725 = "" A4726 = "" A4727 = "" A4728 = "" A4729 = "" A4730 = "" -A4731 = "" A4732 = "" A4733 = "" A4734 = "" A4735 = "" A4736 = "" A4737 = "" A4738 = "" A4739 = "" A4740 = "" -A4741 = "" A4742 = "" A4743 = "" A4744 = "" A4745 = "" A4746 = "" A4747 = "" A4748 = "" A4749 = "" A4750 = "" -A4751 = "" A4752 = "" A4753 = "" A4754 = "" A4755 = "" A4756 = "" A4757 = "" A4758 = "" A4759 = "" A4760 = "" -A4761 = "" A4762 = "" A4763 = "" A4764 = "" A4765 = "" A4766 = "" A4767 = "" A4768 = "" A4769 = "" A4770 = "" -A4771 = "" A4772 = "" A4773 = "" A4774 = "" A4775 = "" A4776 = "" A4777 = "" A4778 = "" A4779 = "" A4780 = "" -A4781 = "" A4782 = "" A4783 = "" A4784 = "" A4785 = "" A4786 = "" A4787 = "" A4788 = "" A4789 = "" A4790 = "" -A4791 = "" A4792 = "" A4793 = "" A4794 = "" A4795 = "" A4796 = "" A4797 = "" A4798 = "" A4799 = "" A4800 = "" -A4801 = "" A4802 = "" A4803 = "" A4804 = "" A4805 = "" A4806 = "" A4807 = "" A4808 = "" A4809 = "" A4810 = "" -A4811 = "" A4812 = "" A4813 = "" A4814 = "" A4815 = "" A4816 = "" A4817 = "" A4818 = "" A4819 = "" A4820 = "" -A4821 = "" A4822 = "" A4823 = "" A4824 = "" A4825 = "" A4826 = "" A4827 = "" A4828 = "" A4829 = "" A4830 = "" -A4831 = "" A4832 = "" A4833 = "" A4834 = "" A4835 = "" A4836 = "" A4837 = "" A4838 = "" A4839 = "" A4840 = "" -A4841 = "" A4842 = "" A4843 = "" A4844 = "" A4845 = "" A4846 = "" A4847 = "" A4848 = "" A4849 = "" A4850 = "" -A4851 = "" A4852 = "" A4853 = "" A4854 = "" A4855 = "" A4856 = "" A4857 = "" A4858 = "" A4859 = "" A4860 = "" -A4861 = "" A4862 = "" A4863 = "" A4864 = "" A4865 = "" A4866 = "" A4867 = "" A4868 = "" A4869 = "" A4870 = "" -A4871 = "" A4872 = "" A4873 = "" A4874 = "" A4875 = "" A4876 = "" A4877 = "" A4878 = "" A4879 = "" A4880 = "" -A4881 = "" A4882 = "" A4883 = "" A4884 = "" A4885 = "" A4886 = "" A4887 = "" A4888 = "" A4889 = "" A4890 = "" -A4891 = "" A4892 = "" A4893 = "" A4894 = "" A4895 = "" A4896 = "" A4897 = "" A4898 = "" A4899 = "" A4900 = "" -A4901 = "" A4902 = "" A4903 = "" A4904 = "" A4905 = "" A4906 = "" A4907 = "" A4908 = "" A4909 = "" A4910 = "" -A4911 = "" A4912 = "" A4913 = "" A4914 = "" A4915 = "" A4916 = "" A4917 = "" A4918 = "" A4919 = "" A4920 = "" -A4921 = "" A4922 = "" A4923 = "" A4924 = "" A4925 = "" A4926 = "" A4927 = "" A4928 = "" A4929 = "" A4930 = "" -A4931 = "" A4932 = "" A4933 = "" A4934 = "" A4935 = "" A4936 = "" A4937 = "" A4938 = "" A4939 = "" A4940 = "" -A4941 = "" A4942 = "" A4943 = "" A4944 = "" A4945 = "" A4946 = "" A4947 = "" A4948 = "" A4949 = "" A4950 = "" -A4951 = "" A4952 = "" A4953 = "" A4954 = "" A4955 = "" A4956 = "" A4957 = "" A4958 = "" A4959 = "" A4960 = "" -A4961 = "" A4962 = "" A4963 = "" A4964 = "" A4965 = "" A4966 = "" A4967 = "" A4968 = "" A4969 = "" A4970 = "" -A4971 = "" A4972 = "" A4973 = "" A4974 = "" A4975 = "" A4976 = "" A4977 = "" A4978 = "" A4979 = "" A4980 = "" -A4981 = "" A4982 = "" A4983 = "" A4984 = "" A4985 = "" A4986 = "" A4987 = "" A4988 = "" A4989 = "" A4990 = "" -A4991 = "" A4992 = "" A4993 = "" A4994 = "" A4995 = "" A4996 = "" A4997 = "" A4998 = "" A4999 = "" A5000 = "" -A5001 = "" A5002 = "" A5003 = "" A5004 = "" A5005 = "" A5006 = "" A5007 = "" A5008 = "" A5009 = "" A5010 = "" -A5011 = "" A5012 = "" A5013 = "" A5014 = "" A5015 = "" A5016 = "" A5017 = "" A5018 = "" A5019 = "" A5020 = "" -A5021 = "" A5022 = "" A5023 = "" A5024 = "" A5025 = "" A5026 = "" A5027 = "" A5028 = "" A5029 = "" A5030 = "" -A5031 = "" A5032 = "" A5033 = "" A5034 = "" A5035 = "" A5036 = "" A5037 = "" A5038 = "" A5039 = "" A5040 = "" -A5041 = "" A5042 = "" A5043 = "" A5044 = "" A5045 = "" A5046 = "" A5047 = "" A5048 = "" A5049 = "" A5050 = "" -A5051 = "" A5052 = "" A5053 = "" A5054 = "" A5055 = "" A5056 = "" A5057 = "" A5058 = "" A5059 = "" A5060 = "" -A5061 = "" A5062 = "" A5063 = "" A5064 = "" A5065 = "" A5066 = "" A5067 = "" A5068 = "" A5069 = "" A5070 = "" -A5071 = "" A5072 = "" A5073 = "" A5074 = "" A5075 = "" A5076 = "" A5077 = "" A5078 = "" A5079 = "" A5080 = "" -A5081 = "" A5082 = "" A5083 = "" A5084 = "" A5085 = "" A5086 = "" A5087 = "" A5088 = "" A5089 = "" A5090 = "" -A5091 = "" A5092 = "" A5093 = "" A5094 = "" A5095 = "" A5096 = "" A5097 = "" A5098 = "" A5099 = "" A5100 = "" -A5101 = "" A5102 = "" A5103 = "" A5104 = "" A5105 = "" A5106 = "" A5107 = "" A5108 = "" A5109 = "" A5110 = "" -A5111 = "" A5112 = "" A5113 = "" A5114 = "" A5115 = "" A5116 = "" A5117 = "" A5118 = "" A5119 = "" A5120 = "" -A5121 = "" A5122 = "" A5123 = "" A5124 = "" A5125 = "" A5126 = "" A5127 = "" A5128 = "" A5129 = "" A5130 = "" -A5131 = "" A5132 = "" A5133 = "" A5134 = "" A5135 = "" A5136 = "" A5137 = "" A5138 = "" A5139 = "" A5140 = "" -A5141 = "" A5142 = "" A5143 = "" A5144 = "" A5145 = "" A5146 = "" A5147 = "" A5148 = "" A5149 = "" A5150 = "" -A5151 = "" A5152 = "" A5153 = "" A5154 = "" A5155 = "" A5156 = "" A5157 = "" A5158 = "" A5159 = "" A5160 = "" -A5161 = "" A5162 = "" A5163 = "" A5164 = "" A5165 = "" A5166 = "" A5167 = "" A5168 = "" A5169 = "" A5170 = "" -A5171 = "" A5172 = "" A5173 = "" A5174 = "" A5175 = "" A5176 = "" A5177 = "" A5178 = "" A5179 = "" A5180 = "" -A5181 = "" A5182 = "" A5183 = "" A5184 = "" A5185 = "" A5186 = "" A5187 = "" A5188 = "" A5189 = "" A5190 = "" -A5191 = "" A5192 = "" A5193 = "" A5194 = "" A5195 = "" A5196 = "" A5197 = "" A5198 = "" A5199 = "" A5200 = "" -A5201 = "" A5202 = "" A5203 = "" A5204 = "" A5205 = "" A5206 = "" A5207 = "" A5208 = "" A5209 = "" A5210 = "" -A5211 = "" A5212 = "" A5213 = "" A5214 = "" A5215 = "" A5216 = "" A5217 = "" A5218 = "" A5219 = "" A5220 = "" -A5221 = "" A5222 = "" A5223 = "" A5224 = "" A5225 = "" A5226 = "" A5227 = "" A5228 = "" A5229 = "" A5230 = "" -A5231 = "" A5232 = "" A5233 = "" A5234 = "" A5235 = "" A5236 = "" A5237 = "" A5238 = "" A5239 = "" A5240 = "" -A5241 = "" A5242 = "" A5243 = "" A5244 = "" A5245 = "" A5246 = "" A5247 = "" A5248 = "" A5249 = "" A5250 = "" -A5251 = "" A5252 = "" A5253 = "" A5254 = "" A5255 = "" A5256 = "" A5257 = "" A5258 = "" A5259 = "" A5260 = "" -A5261 = "" A5262 = "" A5263 = "" A5264 = "" A5265 = "" A5266 = "" A5267 = "" A5268 = "" A5269 = "" A5270 = "" -A5271 = "" A5272 = "" A5273 = "" A5274 = "" A5275 = "" A5276 = "" A5277 = "" A5278 = "" A5279 = "" A5280 = "" -A5281 = "" A5282 = "" A5283 = "" A5284 = "" A5285 = "" A5286 = "" A5287 = "" A5288 = "" A5289 = "" A5290 = "" -A5291 = "" A5292 = "" A5293 = "" A5294 = "" A5295 = "" A5296 = "" A5297 = "" A5298 = "" A5299 = "" A5300 = "" -A5301 = "" A5302 = "" A5303 = "" A5304 = "" A5305 = "" A5306 = "" A5307 = "" A5308 = "" A5309 = "" A5310 = "" -A5311 = "" A5312 = "" A5313 = "" A5314 = "" A5315 = "" A5316 = "" A5317 = "" A5318 = "" A5319 = "" A5320 = "" -A5321 = "" A5322 = "" A5323 = "" A5324 = "" A5325 = "" A5326 = "" A5327 = "" A5328 = "" A5329 = "" A5330 = "" -A5331 = "" A5332 = "" A5333 = "" A5334 = "" A5335 = "" A5336 = "" A5337 = "" A5338 = "" A5339 = "" A5340 = "" -A5341 = "" A5342 = "" A5343 = "" A5344 = "" A5345 = "" A5346 = "" A5347 = "" A5348 = "" A5349 = "" A5350 = "" -A5351 = "" A5352 = "" A5353 = "" A5354 = "" A5355 = "" A5356 = "" A5357 = "" A5358 = "" A5359 = "" A5360 = "" -A5361 = "" A5362 = "" A5363 = "" A5364 = "" A5365 = "" A5366 = "" A5367 = "" A5368 = "" A5369 = "" A5370 = "" -A5371 = "" A5372 = "" A5373 = "" A5374 = "" A5375 = "" A5376 = "" A5377 = "" A5378 = "" A5379 = "" A5380 = "" -A5381 = "" A5382 = "" A5383 = "" A5384 = "" A5385 = "" A5386 = "" A5387 = "" A5388 = "" A5389 = "" A5390 = "" -A5391 = "" A5392 = "" A5393 = "" A5394 = "" A5395 = "" A5396 = "" A5397 = "" A5398 = "" A5399 = "" A5400 = "" -A5401 = "" A5402 = "" A5403 = "" A5404 = "" A5405 = "" A5406 = "" A5407 = "" A5408 = "" A5409 = "" A5410 = "" -A5411 = "" A5412 = "" A5413 = "" A5414 = "" A5415 = "" A5416 = "" A5417 = "" A5418 = "" A5419 = "" A5420 = "" -A5421 = "" A5422 = "" A5423 = "" A5424 = "" A5425 = "" A5426 = "" A5427 = "" A5428 = "" A5429 = "" A5430 = "" -A5431 = "" A5432 = "" A5433 = "" A5434 = "" A5435 = "" A5436 = "" A5437 = "" A5438 = "" A5439 = "" A5440 = "" -A5441 = "" A5442 = "" A5443 = "" A5444 = "" A5445 = "" A5446 = "" A5447 = "" A5448 = "" A5449 = "" A5450 = "" -A5451 = "" A5452 = "" A5453 = "" A5454 = "" A5455 = "" A5456 = "" A5457 = "" A5458 = "" A5459 = "" A5460 = "" -A5461 = "" A5462 = "" A5463 = "" A5464 = "" A5465 = "" A5466 = "" A5467 = "" A5468 = "" A5469 = "" A5470 = "" -A5471 = "" A5472 = "" A5473 = "" A5474 = "" A5475 = "" A5476 = "" A5477 = "" A5478 = "" A5479 = "" A5480 = "" -A5481 = "" A5482 = "" A5483 = "" A5484 = "" A5485 = "" A5486 = "" A5487 = "" A5488 = "" A5489 = "" A5490 = "" -A5491 = "" A5492 = "" A5493 = "" A5494 = "" A5495 = "" A5496 = "" A5497 = "" A5498 = "" A5499 = "" A5500 = "" -A5501 = "" A5502 = "" A5503 = "" A5504 = "" A5505 = "" A5506 = "" A5507 = "" A5508 = "" A5509 = "" A5510 = "" -A5511 = "" A5512 = "" A5513 = "" A5514 = "" A5515 = "" A5516 = "" A5517 = "" A5518 = "" A5519 = "" A5520 = "" -A5521 = "" A5522 = "" A5523 = "" A5524 = "" A5525 = "" A5526 = "" A5527 = "" A5528 = "" A5529 = "" A5530 = "" -A5531 = "" A5532 = "" A5533 = "" A5534 = "" A5535 = "" A5536 = "" A5537 = "" A5538 = "" A5539 = "" A5540 = "" -A5541 = "" A5542 = "" A5543 = "" A5544 = "" A5545 = "" A5546 = "" A5547 = "" A5548 = "" A5549 = "" A5550 = "" -A5551 = "" A5552 = "" A5553 = "" A5554 = "" A5555 = "" A5556 = "" A5557 = "" A5558 = "" A5559 = "" A5560 = "" -A5561 = "" A5562 = "" A5563 = "" A5564 = "" A5565 = "" A5566 = "" A5567 = "" A5568 = "" A5569 = "" A5570 = "" -A5571 = "" A5572 = "" A5573 = "" A5574 = "" A5575 = "" A5576 = "" A5577 = "" A5578 = "" A5579 = "" A5580 = "" -A5581 = "" A5582 = "" A5583 = "" A5584 = "" A5585 = "" A5586 = "" A5587 = "" A5588 = "" A5589 = "" A5590 = "" -A5591 = "" A5592 = "" A5593 = "" A5594 = "" A5595 = "" A5596 = "" A5597 = "" A5598 = "" A5599 = "" A5600 = "" -A5601 = "" A5602 = "" A5603 = "" A5604 = "" A5605 = "" A5606 = "" A5607 = "" A5608 = "" A5609 = "" A5610 = "" -A5611 = "" A5612 = "" A5613 = "" A5614 = "" A5615 = "" A5616 = "" A5617 = "" A5618 = "" A5619 = "" A5620 = "" -A5621 = "" A5622 = "" A5623 = "" A5624 = "" A5625 = "" A5626 = "" A5627 = "" A5628 = "" A5629 = "" A5630 = "" -A5631 = "" A5632 = "" A5633 = "" A5634 = "" A5635 = "" A5636 = "" A5637 = "" A5638 = "" A5639 = "" A5640 = "" -A5641 = "" A5642 = "" A5643 = "" A5644 = "" A5645 = "" A5646 = "" A5647 = "" A5648 = "" A5649 = "" A5650 = "" -A5651 = "" A5652 = "" A5653 = "" A5654 = "" A5655 = "" A5656 = "" A5657 = "" A5658 = "" A5659 = "" A5660 = "" -A5661 = "" A5662 = "" A5663 = "" A5664 = "" A5665 = "" A5666 = "" A5667 = "" A5668 = "" A5669 = "" A5670 = "" -A5671 = "" A5672 = "" A5673 = "" A5674 = "" A5675 = "" A5676 = "" A5677 = "" A5678 = "" A5679 = "" A5680 = "" -A5681 = "" A5682 = "" A5683 = "" A5684 = "" A5685 = "" A5686 = "" A5687 = "" A5688 = "" A5689 = "" A5690 = "" -A5691 = "" A5692 = "" A5693 = "" A5694 = "" A5695 = "" A5696 = "" A5697 = "" A5698 = "" A5699 = "" A5700 = "" -A5701 = "" A5702 = "" A5703 = "" A5704 = "" A5705 = "" A5706 = "" A5707 = "" A5708 = "" A5709 = "" A5710 = "" -A5711 = "" A5712 = "" A5713 = "" A5714 = "" A5715 = "" A5716 = "" A5717 = "" A5718 = "" A5719 = "" A5720 = "" -A5721 = "" A5722 = "" A5723 = "" A5724 = "" A5725 = "" A5726 = "" A5727 = "" A5728 = "" A5729 = "" A5730 = "" -A5731 = "" A5732 = "" A5733 = "" A5734 = "" A5735 = "" A5736 = "" A5737 = "" A5738 = "" A5739 = "" A5740 = "" -A5741 = "" A5742 = "" A5743 = "" A5744 = "" A5745 = "" A5746 = "" A5747 = "" A5748 = "" A5749 = "" A5750 = "" -A5751 = "" A5752 = "" A5753 = "" A5754 = "" A5755 = "" A5756 = "" A5757 = "" A5758 = "" A5759 = "" A5760 = "" -A5761 = "" A5762 = "" A5763 = "" A5764 = "" A5765 = "" A5766 = "" A5767 = "" A5768 = "" A5769 = "" A5770 = "" -A5771 = "" A5772 = "" A5773 = "" A5774 = "" A5775 = "" A5776 = "" A5777 = "" A5778 = "" A5779 = "" A5780 = "" -A5781 = "" A5782 = "" A5783 = "" A5784 = "" A5785 = "" A5786 = "" A5787 = "" A5788 = "" A5789 = "" A5790 = "" -A5791 = "" A5792 = "" A5793 = "" A5794 = "" A5795 = "" A5796 = "" A5797 = "" A5798 = "" A5799 = "" A5800 = "" -A5801 = "" A5802 = "" A5803 = "" A5804 = "" A5805 = "" A5806 = "" A5807 = "" A5808 = "" A5809 = "" A5810 = "" -A5811 = "" A5812 = "" A5813 = "" A5814 = "" A5815 = "" A5816 = "" A5817 = "" A5818 = "" A5819 = "" A5820 = "" -A5821 = "" A5822 = "" A5823 = "" A5824 = "" A5825 = "" A5826 = "" A5827 = "" A5828 = "" A5829 = "" A5830 = "" -A5831 = "" A5832 = "" A5833 = "" A5834 = "" A5835 = "" A5836 = "" A5837 = "" A5838 = "" A5839 = "" A5840 = "" -A5841 = "" A5842 = "" A5843 = "" A5844 = "" A5845 = "" A5846 = "" A5847 = "" A5848 = "" A5849 = "" A5850 = "" -A5851 = "" A5852 = "" A5853 = "" A5854 = "" A5855 = "" A5856 = "" A5857 = "" A5858 = "" A5859 = "" A5860 = "" -A5861 = "" A5862 = "" A5863 = "" A5864 = "" A5865 = "" A5866 = "" A5867 = "" A5868 = "" A5869 = "" A5870 = "" -A5871 = "" A5872 = "" A5873 = "" A5874 = "" A5875 = "" A5876 = "" A5877 = "" A5878 = "" A5879 = "" A5880 = "" -A5881 = "" A5882 = "" A5883 = "" A5884 = "" A5885 = "" A5886 = "" A5887 = "" A5888 = "" A5889 = "" A5890 = "" -A5891 = "" A5892 = "" A5893 = "" A5894 = "" A5895 = "" A5896 = "" A5897 = "" A5898 = "" A5899 = "" A5900 = "" -A5901 = "" A5902 = "" A5903 = "" A5904 = "" A5905 = "" A5906 = "" A5907 = "" A5908 = "" A5909 = "" A5910 = "" -A5911 = "" A5912 = "" A5913 = "" A5914 = "" A5915 = "" A5916 = "" A5917 = "" A5918 = "" A5919 = "" A5920 = "" -A5921 = "" A5922 = "" A5923 = "" A5924 = "" A5925 = "" A5926 = "" A5927 = "" A5928 = "" A5929 = "" A5930 = "" -A5931 = "" A5932 = "" A5933 = "" A5934 = "" A5935 = "" A5936 = "" A5937 = "" A5938 = "" A5939 = "" A5940 = "" -A5941 = "" A5942 = "" A5943 = "" A5944 = "" A5945 = "" A5946 = "" A5947 = "" A5948 = "" A5949 = "" A5950 = "" -A5951 = "" A5952 = "" A5953 = "" A5954 = "" A5955 = "" A5956 = "" A5957 = "" A5958 = "" A5959 = "" A5960 = "" -A5961 = "" A5962 = "" A5963 = "" A5964 = "" A5965 = "" A5966 = "" A5967 = "" A5968 = "" A5969 = "" A5970 = "" -A5971 = "" A5972 = "" A5973 = "" A5974 = "" A5975 = "" A5976 = "" A5977 = "" A5978 = "" A5979 = "" A5980 = "" -A5981 = "" A5982 = "" A5983 = "" A5984 = "" A5985 = "" A5986 = "" A5987 = "" A5988 = "" A5989 = "" A5990 = "" -A5991 = "" A5992 = "" A5993 = "" A5994 = "" A5995 = "" A5996 = "" A5997 = "" A5998 = "" A5999 = "" A6000 = "" -A6001 = "" A6002 = "" A6003 = "" A6004 = "" A6005 = "" A6006 = "" A6007 = "" A6008 = "" A6009 = "" A6010 = "" -A6011 = "" A6012 = "" A6013 = "" A6014 = "" A6015 = "" A6016 = "" A6017 = "" A6018 = "" A6019 = "" A6020 = "" -A6021 = "" A6022 = "" A6023 = "" A6024 = "" A6025 = "" A6026 = "" A6027 = "" A6028 = "" A6029 = "" A6030 = "" -A6031 = "" A6032 = "" A6033 = "" A6034 = "" A6035 = "" A6036 = "" A6037 = "" A6038 = "" A6039 = "" A6040 = "" -A6041 = "" A6042 = "" A6043 = "" A6044 = "" A6045 = "" A6046 = "" A6047 = "" A6048 = "" A6049 = "" A6050 = "" -A6051 = "" A6052 = "" A6053 = "" A6054 = "" A6055 = "" A6056 = "" A6057 = "" A6058 = "" A6059 = "" A6060 = "" -A6061 = "" A6062 = "" A6063 = "" A6064 = "" A6065 = "" A6066 = "" A6067 = "" A6068 = "" A6069 = "" A6070 = "" -A6071 = "" A6072 = "" A6073 = "" A6074 = "" A6075 = "" A6076 = "" A6077 = "" A6078 = "" A6079 = "" A6080 = "" -A6081 = "" A6082 = "" A6083 = "" A6084 = "" A6085 = "" A6086 = "" A6087 = "" A6088 = "" A6089 = "" A6090 = "" -A6091 = "" A6092 = "" A6093 = "" A6094 = "" A6095 = "" A6096 = "" A6097 = "" A6098 = "" A6099 = "" A6100 = "" -A6101 = "" A6102 = "" A6103 = "" A6104 = "" A6105 = "" A6106 = "" A6107 = "" A6108 = "" A6109 = "" A6110 = "" -A6111 = "" A6112 = "" A6113 = "" A6114 = "" A6115 = "" A6116 = "" A6117 = "" A6118 = "" A6119 = "" A6120 = "" -A6121 = "" A6122 = "" A6123 = "" A6124 = "" A6125 = "" A6126 = "" A6127 = "" A6128 = "" A6129 = "" A6130 = "" -A6131 = "" A6132 = "" A6133 = "" A6134 = "" A6135 = "" A6136 = "" A6137 = "" A6138 = "" A6139 = "" A6140 = "" -A6141 = "" A6142 = "" A6143 = "" A6144 = "" A6145 = "" A6146 = "" A6147 = "" A6148 = "" A6149 = "" A6150 = "" -A6151 = "" A6152 = "" A6153 = "" A6154 = "" A6155 = "" A6156 = "" A6157 = "" A6158 = "" A6159 = "" A6160 = "" -A6161 = "" A6162 = "" A6163 = "" A6164 = "" A6165 = "" A6166 = "" A6167 = "" A6168 = "" A6169 = "" A6170 = "" -A6171 = "" A6172 = "" A6173 = "" A6174 = "" A6175 = "" A6176 = "" A6177 = "" A6178 = "" A6179 = "" A6180 = "" -A6181 = "" A6182 = "" A6183 = "" A6184 = "" A6185 = "" A6186 = "" A6187 = "" A6188 = "" A6189 = "" A6190 = "" -A6191 = "" A6192 = "" A6193 = "" A6194 = "" A6195 = "" A6196 = "" A6197 = "" A6198 = "" A6199 = "" A6200 = "" -A6201 = "" A6202 = "" A6203 = "" A6204 = "" A6205 = "" A6206 = "" A6207 = "" A6208 = "" A6209 = "" A6210 = "" -A6211 = "" A6212 = "" A6213 = "" A6214 = "" A6215 = "" A6216 = "" A6217 = "" A6218 = "" A6219 = "" A6220 = "" -A6221 = "" A6222 = "" A6223 = "" A6224 = "" A6225 = "" A6226 = "" A6227 = "" A6228 = "" A6229 = "" A6230 = "" -A6231 = "" A6232 = "" A6233 = "" A6234 = "" A6235 = "" A6236 = "" A6237 = "" A6238 = "" A6239 = "" A6240 = "" -A6241 = "" A6242 = "" A6243 = "" A6244 = "" A6245 = "" A6246 = "" A6247 = "" A6248 = "" A6249 = "" A6250 = "" -A6251 = "" A6252 = "" A6253 = "" A6254 = "" A6255 = "" A6256 = "" A6257 = "" A6258 = "" A6259 = "" A6260 = "" -A6261 = "" A6262 = "" A6263 = "" A6264 = "" A6265 = "" A6266 = "" A6267 = "" A6268 = "" A6269 = "" A6270 = "" -A6271 = "" A6272 = "" A6273 = "" A6274 = "" A6275 = "" A6276 = "" A6277 = "" A6278 = "" A6279 = "" A6280 = "" -A6281 = "" A6282 = "" A6283 = "" A6284 = "" A6285 = "" A6286 = "" A6287 = "" A6288 = "" A6289 = "" A6290 = "" -A6291 = "" A6292 = "" A6293 = "" A6294 = "" A6295 = "" A6296 = "" A6297 = "" A6298 = "" A6299 = "" A6300 = "" -A6301 = "" A6302 = "" A6303 = "" A6304 = "" A6305 = "" A6306 = "" A6307 = "" A6308 = "" A6309 = "" A6310 = "" -A6311 = "" A6312 = "" A6313 = "" A6314 = "" A6315 = "" A6316 = "" A6317 = "" A6318 = "" A6319 = "" A6320 = "" -A6321 = "" A6322 = "" A6323 = "" A6324 = "" A6325 = "" A6326 = "" A6327 = "" A6328 = "" A6329 = "" A6330 = "" -A6331 = "" A6332 = "" A6333 = "" A6334 = "" A6335 = "" A6336 = "" A6337 = "" A6338 = "" A6339 = "" A6340 = "" -A6341 = "" A6342 = "" A6343 = "" A6344 = "" A6345 = "" A6346 = "" A6347 = "" A6348 = "" A6349 = "" A6350 = "" -A6351 = "" A6352 = "" A6353 = "" A6354 = "" A6355 = "" A6356 = "" A6357 = "" A6358 = "" A6359 = "" A6360 = "" -A6361 = "" A6362 = "" A6363 = "" A6364 = "" A6365 = "" A6366 = "" A6367 = "" A6368 = "" A6369 = "" A6370 = "" -A6371 = "" A6372 = "" A6373 = "" A6374 = "" A6375 = "" A6376 = "" A6377 = "" A6378 = "" A6379 = "" A6380 = "" -A6381 = "" A6382 = "" A6383 = "" A6384 = "" A6385 = "" A6386 = "" A6387 = "" A6388 = "" A6389 = "" A6390 = "" -A6391 = "" A6392 = "" A6393 = "" A6394 = "" A6395 = "" A6396 = "" A6397 = "" A6398 = "" A6399 = "" A6400 = "" -A6401 = "" A6402 = "" A6403 = "" A6404 = "" A6405 = "" A6406 = "" A6407 = "" A6408 = "" A6409 = "" A6410 = "" -A6411 = "" A6412 = "" A6413 = "" A6414 = "" A6415 = "" A6416 = "" A6417 = "" A6418 = "" A6419 = "" A6420 = "" -A6421 = "" A6422 = "" A6423 = "" A6424 = "" A6425 = "" A6426 = "" A6427 = "" A6428 = "" A6429 = "" A6430 = "" -A6431 = "" A6432 = "" A6433 = "" A6434 = "" A6435 = "" A6436 = "" A6437 = "" A6438 = "" A6439 = "" A6440 = "" -A6441 = "" A6442 = "" A6443 = "" A6444 = "" A6445 = "" A6446 = "" A6447 = "" A6448 = "" A6449 = "" A6450 = "" -A6451 = "" A6452 = "" A6453 = "" A6454 = "" A6455 = "" A6456 = "" A6457 = "" A6458 = "" A6459 = "" A6460 = "" -A6461 = "" A6462 = "" A6463 = "" A6464 = "" A6465 = "" A6466 = "" A6467 = "" A6468 = "" A6469 = "" A6470 = "" -A6471 = "" A6472 = "" A6473 = "" A6474 = "" A6475 = "" A6476 = "" A6477 = "" A6478 = "" A6479 = "" A6480 = "" -A6481 = "" A6482 = "" A6483 = "" A6484 = "" A6485 = "" A6486 = "" A6487 = "" A6488 = "" A6489 = "" A6490 = "" -A6491 = "" A6492 = "" A6493 = "" A6494 = "" A6495 = "" A6496 = "" A6497 = "" A6498 = "" A6499 = "" A6500 = "" -A6501 = "" A6502 = "" A6503 = "" A6504 = "" A6505 = "" A6506 = "" A6507 = "" A6508 = "" A6509 = "" A6510 = "" -A6511 = "" A6512 = "" A6513 = "" A6514 = "" A6515 = "" A6516 = "" A6517 = "" A6518 = "" A6519 = "" A6520 = "" -A6521 = "" A6522 = "" A6523 = "" A6524 = "" A6525 = "" A6526 = "" A6527 = "" A6528 = "" A6529 = "" A6530 = "" -A6531 = "" A6532 = "" A6533 = "" A6534 = "" A6535 = "" A6536 = "" A6537 = "" A6538 = "" A6539 = "" A6540 = "" -A6541 = "" A6542 = "" A6543 = "" A6544 = "" A6545 = "" A6546 = "" A6547 = "" A6548 = "" A6549 = "" A6550 = "" -A6551 = "" A6552 = "" A6553 = "" A6554 = "" A6555 = "" A6556 = "" A6557 = "" A6558 = "" A6559 = "" A6560 = "" -A6561 = "" A6562 = "" A6563 = "" A6564 = "" A6565 = "" A6566 = "" A6567 = "" A6568 = "" A6569 = "" A6570 = "" -A6571 = "" A6572 = "" A6573 = "" A6574 = "" A6575 = "" A6576 = "" A6577 = "" A6578 = "" A6579 = "" A6580 = "" -A6581 = "" A6582 = "" A6583 = "" A6584 = "" A6585 = "" A6586 = "" A6587 = "" A6588 = "" A6589 = "" A6590 = "" -A6591 = "" A6592 = "" A6593 = "" A6594 = "" A6595 = "" A6596 = "" A6597 = "" A6598 = "" A6599 = "" A6600 = "" -A6601 = "" A6602 = "" A6603 = "" A6604 = "" A6605 = "" A6606 = "" A6607 = "" A6608 = "" A6609 = "" A6610 = "" -A6611 = "" A6612 = "" A6613 = "" A6614 = "" A6615 = "" A6616 = "" A6617 = "" A6618 = "" A6619 = "" A6620 = "" -A6621 = "" A6622 = "" A6623 = "" A6624 = "" A6625 = "" A6626 = "" A6627 = "" A6628 = "" A6629 = "" A6630 = "" -A6631 = "" A6632 = "" A6633 = "" A6634 = "" A6635 = "" A6636 = "" A6637 = "" A6638 = "" A6639 = "" A6640 = "" -A6641 = "" A6642 = "" A6643 = "" A6644 = "" A6645 = "" A6646 = "" A6647 = "" A6648 = "" A6649 = "" A6650 = "" -A6651 = "" A6652 = "" A6653 = "" A6654 = "" A6655 = "" A6656 = "" A6657 = "" A6658 = "" A6659 = "" A6660 = "" -A6661 = "" A6662 = "" A6663 = "" A6664 = "" A6665 = "" A6666 = "" A6667 = "" A6668 = "" A6669 = "" A6670 = "" -A6671 = "" A6672 = "" A6673 = "" A6674 = "" A6675 = "" A6676 = "" A6677 = "" A6678 = "" A6679 = "" A6680 = "" -A6681 = "" A6682 = "" A6683 = "" A6684 = "" A6685 = "" A6686 = "" A6687 = "" A6688 = "" A6689 = "" A6690 = "" -A6691 = "" A6692 = "" A6693 = "" A6694 = "" A6695 = "" A6696 = "" A6697 = "" A6698 = "" A6699 = "" A6700 = "" -A6701 = "" A6702 = "" A6703 = "" A6704 = "" A6705 = "" A6706 = "" A6707 = "" A6708 = "" A6709 = "" A6710 = "" -A6711 = "" A6712 = "" A6713 = "" A6714 = "" A6715 = "" A6716 = "" A6717 = "" A6718 = "" A6719 = "" A6720 = "" -A6721 = "" A6722 = "" A6723 = "" A6724 = "" A6725 = "" A6726 = "" A6727 = "" A6728 = "" A6729 = "" A6730 = "" -A6731 = "" A6732 = "" A6733 = "" A6734 = "" A6735 = "" A6736 = "" A6737 = "" A6738 = "" A6739 = "" A6740 = "" -A6741 = "" A6742 = "" A6743 = "" A6744 = "" A6745 = "" A6746 = "" A6747 = "" A6748 = "" A6749 = "" A6750 = "" -A6751 = "" A6752 = "" A6753 = "" A6754 = "" A6755 = "" A6756 = "" A6757 = "" A6758 = "" A6759 = "" A6760 = "" -A6761 = "" A6762 = "" A6763 = "" A6764 = "" A6765 = "" A6766 = "" A6767 = "" A6768 = "" A6769 = "" A6770 = "" -A6771 = "" A6772 = "" A6773 = "" A6774 = "" A6775 = "" A6776 = "" A6777 = "" A6778 = "" A6779 = "" A6780 = "" -A6781 = "" A6782 = "" A6783 = "" A6784 = "" A6785 = "" A6786 = "" A6787 = "" A6788 = "" A6789 = "" A6790 = "" -A6791 = "" A6792 = "" A6793 = "" A6794 = "" A6795 = "" A6796 = "" A6797 = "" A6798 = "" A6799 = "" A6800 = "" -A6801 = "" A6802 = "" A6803 = "" A6804 = "" A6805 = "" A6806 = "" A6807 = "" A6808 = "" A6809 = "" A6810 = "" -A6811 = "" A6812 = "" A6813 = "" A6814 = "" A6815 = "" A6816 = "" A6817 = "" A6818 = "" A6819 = "" A6820 = "" -A6821 = "" A6822 = "" A6823 = "" A6824 = "" A6825 = "" A6826 = "" A6827 = "" A6828 = "" A6829 = "" A6830 = "" -A6831 = "" A6832 = "" A6833 = "" A6834 = "" A6835 = "" A6836 = "" A6837 = "" A6838 = "" A6839 = "" A6840 = "" -A6841 = "" A6842 = "" A6843 = "" A6844 = "" A6845 = "" A6846 = "" A6847 = "" A6848 = "" A6849 = "" A6850 = "" -A6851 = "" A6852 = "" A6853 = "" A6854 = "" A6855 = "" A6856 = "" A6857 = "" A6858 = "" A6859 = "" A6860 = "" -A6861 = "" A6862 = "" A6863 = "" A6864 = "" A6865 = "" A6866 = "" A6867 = "" A6868 = "" A6869 = "" A6870 = "" -A6871 = "" A6872 = "" A6873 = "" A6874 = "" A6875 = "" A6876 = "" A6877 = "" A6878 = "" A6879 = "" A6880 = "" -A6881 = "" A6882 = "" A6883 = "" A6884 = "" A6885 = "" A6886 = "" A6887 = "" A6888 = "" A6889 = "" A6890 = "" -A6891 = "" A6892 = "" A6893 = "" A6894 = "" A6895 = "" A6896 = "" A6897 = "" A6898 = "" A6899 = "" A6900 = "" -A6901 = "" A6902 = "" A6903 = "" A6904 = "" A6905 = "" A6906 = "" A6907 = "" A6908 = "" A6909 = "" A6910 = "" -A6911 = "" A6912 = "" A6913 = "" A6914 = "" A6915 = "" A6916 = "" A6917 = "" A6918 = "" A6919 = "" A6920 = "" -A6921 = "" A6922 = "" A6923 = "" A6924 = "" A6925 = "" A6926 = "" A6927 = "" A6928 = "" A6929 = "" A6930 = "" -A6931 = "" A6932 = "" A6933 = "" A6934 = "" A6935 = "" A6936 = "" A6937 = "" A6938 = "" A6939 = "" A6940 = "" -A6941 = "" A6942 = "" A6943 = "" A6944 = "" A6945 = "" A6946 = "" A6947 = "" A6948 = "" A6949 = "" A6950 = "" -A6951 = "" A6952 = "" A6953 = "" A6954 = "" A6955 = "" A6956 = "" A6957 = "" A6958 = "" A6959 = "" A6960 = "" -A6961 = "" A6962 = "" A6963 = "" A6964 = "" A6965 = "" A6966 = "" A6967 = "" A6968 = "" A6969 = "" A6970 = "" -A6971 = "" A6972 = "" A6973 = "" A6974 = "" A6975 = "" A6976 = "" A6977 = "" A6978 = "" A6979 = "" A6980 = "" -A6981 = "" A6982 = "" A6983 = "" A6984 = "" A6985 = "" A6986 = "" A6987 = "" A6988 = "" A6989 = "" A6990 = "" -A6991 = "" A6992 = "" A6993 = "" A6994 = "" A6995 = "" A6996 = "" A6997 = "" A6998 = "" A6999 = "" A7000 = "" -A7001 = "" A7002 = "" A7003 = "" A7004 = "" A7005 = "" A7006 = "" A7007 = "" A7008 = "" A7009 = "" A7010 = "" -A7011 = "" A7012 = "" A7013 = "" A7014 = "" A7015 = "" A7016 = "" A7017 = "" A7018 = "" A7019 = "" A7020 = "" -A7021 = "" A7022 = "" A7023 = "" A7024 = "" A7025 = "" A7026 = "" A7027 = "" A7028 = "" A7029 = "" A7030 = "" -A7031 = "" A7032 = "" A7033 = "" A7034 = "" A7035 = "" A7036 = "" A7037 = "" A7038 = "" A7039 = "" A7040 = "" -A7041 = "" A7042 = "" A7043 = "" A7044 = "" A7045 = "" A7046 = "" A7047 = "" A7048 = "" A7049 = "" A7050 = "" -A7051 = "" A7052 = "" A7053 = "" A7054 = "" A7055 = "" A7056 = "" A7057 = "" A7058 = "" A7059 = "" A7060 = "" -A7061 = "" A7062 = "" A7063 = "" A7064 = "" A7065 = "" A7066 = "" A7067 = "" A7068 = "" A7069 = "" A7070 = "" -A7071 = "" A7072 = "" A7073 = "" A7074 = "" A7075 = "" A7076 = "" A7077 = "" A7078 = "" A7079 = "" A7080 = "" -A7081 = "" A7082 = "" A7083 = "" A7084 = "" A7085 = "" A7086 = "" A7087 = "" A7088 = "" A7089 = "" A7090 = "" -A7091 = "" A7092 = "" A7093 = "" A7094 = "" A7095 = "" A7096 = "" A7097 = "" A7098 = "" A7099 = "" A7100 = "" -A7101 = "" A7102 = "" A7103 = "" A7104 = "" A7105 = "" A7106 = "" A7107 = "" A7108 = "" A7109 = "" A7110 = "" -A7111 = "" A7112 = "" A7113 = "" A7114 = "" A7115 = "" A7116 = "" A7117 = "" A7118 = "" A7119 = "" A7120 = "" -A7121 = "" A7122 = "" A7123 = "" A7124 = "" A7125 = "" A7126 = "" A7127 = "" A7128 = "" A7129 = "" A7130 = "" -A7131 = "" A7132 = "" A7133 = "" A7134 = "" A7135 = "" A7136 = "" A7137 = "" A7138 = "" A7139 = "" A7140 = "" -A7141 = "" A7142 = "" A7143 = "" A7144 = "" A7145 = "" A7146 = "" A7147 = "" A7148 = "" A7149 = "" A7150 = "" -A7151 = "" A7152 = "" A7153 = "" A7154 = "" A7155 = "" A7156 = "" A7157 = "" A7158 = "" A7159 = "" A7160 = "" -A7161 = "" A7162 = "" A7163 = "" A7164 = "" A7165 = "" A7166 = "" A7167 = "" A7168 = "" A7169 = "" A7170 = "" -A7171 = "" A7172 = "" A7173 = "" A7174 = "" A7175 = "" A7176 = "" A7177 = "" A7178 = "" A7179 = "" A7180 = "" -A7181 = "" A7182 = "" A7183 = "" A7184 = "" A7185 = "" A7186 = "" A7187 = "" A7188 = "" A7189 = "" A7190 = "" -A7191 = "" A7192 = "" A7193 = "" A7194 = "" A7195 = "" A7196 = "" A7197 = "" A7198 = "" A7199 = "" A7200 = "" -A7201 = "" A7202 = "" A7203 = "" A7204 = "" A7205 = "" A7206 = "" A7207 = "" A7208 = "" A7209 = "" A7210 = "" -A7211 = "" A7212 = "" A7213 = "" A7214 = "" A7215 = "" A7216 = "" A7217 = "" A7218 = "" A7219 = "" A7220 = "" -A7221 = "" A7222 = "" A7223 = "" A7224 = "" A7225 = "" A7226 = "" A7227 = "" A7228 = "" A7229 = "" A7230 = "" -A7231 = "" A7232 = "" A7233 = "" A7234 = "" A7235 = "" A7236 = "" A7237 = "" A7238 = "" A7239 = "" A7240 = "" -A7241 = "" A7242 = "" A7243 = "" A7244 = "" A7245 = "" A7246 = "" A7247 = "" A7248 = "" A7249 = "" A7250 = "" -A7251 = "" A7252 = "" A7253 = "" A7254 = "" A7255 = "" A7256 = "" A7257 = "" A7258 = "" A7259 = "" A7260 = "" -A7261 = "" A7262 = "" A7263 = "" A7264 = "" A7265 = "" A7266 = "" A7267 = "" A7268 = "" A7269 = "" A7270 = "" -A7271 = "" A7272 = "" A7273 = "" A7274 = "" A7275 = "" A7276 = "" A7277 = "" A7278 = "" A7279 = "" A7280 = "" -A7281 = "" A7282 = "" A7283 = "" A7284 = "" A7285 = "" A7286 = "" A7287 = "" A7288 = "" A7289 = "" A7290 = "" -A7291 = "" A7292 = "" A7293 = "" A7294 = "" A7295 = "" A7296 = "" A7297 = "" A7298 = "" A7299 = "" A7300 = "" -A7301 = "" A7302 = "" A7303 = "" A7304 = "" A7305 = "" A7306 = "" A7307 = "" A7308 = "" A7309 = "" A7310 = "" -A7311 = "" A7312 = "" A7313 = "" A7314 = "" A7315 = "" A7316 = "" A7317 = "" A7318 = "" A7319 = "" A7320 = "" -A7321 = "" A7322 = "" A7323 = "" A7324 = "" A7325 = "" A7326 = "" A7327 = "" A7328 = "" A7329 = "" A7330 = "" -A7331 = "" A7332 = "" A7333 = "" A7334 = "" A7335 = "" A7336 = "" A7337 = "" A7338 = "" A7339 = "" A7340 = "" -A7341 = "" A7342 = "" A7343 = "" A7344 = "" A7345 = "" A7346 = "" A7347 = "" A7348 = "" A7349 = "" A7350 = "" -A7351 = "" A7352 = "" A7353 = "" A7354 = "" A7355 = "" A7356 = "" A7357 = "" A7358 = "" A7359 = "" A7360 = "" -A7361 = "" A7362 = "" A7363 = "" A7364 = "" A7365 = "" A7366 = "" A7367 = "" A7368 = "" A7369 = "" A7370 = "" -A7371 = "" A7372 = "" A7373 = "" A7374 = "" A7375 = "" A7376 = "" A7377 = "" A7378 = "" A7379 = "" A7380 = "" -A7381 = "" A7382 = "" A7383 = "" A7384 = "" A7385 = "" A7386 = "" A7387 = "" A7388 = "" A7389 = "" A7390 = "" -A7391 = "" A7392 = "" A7393 = "" A7394 = "" A7395 = "" A7396 = "" A7397 = "" A7398 = "" A7399 = "" A7400 = "" -A7401 = "" A7402 = "" A7403 = "" A7404 = "" A7405 = "" A7406 = "" A7407 = "" A7408 = "" A7409 = "" A7410 = "" -A7411 = "" A7412 = "" A7413 = "" A7414 = "" A7415 = "" A7416 = "" A7417 = "" A7418 = "" A7419 = "" A7420 = "" -A7421 = "" A7422 = "" A7423 = "" A7424 = "" A7425 = "" A7426 = "" A7427 = "" A7428 = "" A7429 = "" A7430 = "" -A7431 = "" A7432 = "" A7433 = "" A7434 = "" A7435 = "" A7436 = "" A7437 = "" A7438 = "" A7439 = "" A7440 = "" -A7441 = "" A7442 = "" A7443 = "" A7444 = "" A7445 = "" A7446 = "" A7447 = "" A7448 = "" A7449 = "" A7450 = "" -A7451 = "" A7452 = "" A7453 = "" A7454 = "" A7455 = "" A7456 = "" A7457 = "" A7458 = "" A7459 = "" A7460 = "" -A7461 = "" A7462 = "" A7463 = "" A7464 = "" A7465 = "" A7466 = "" A7467 = "" A7468 = "" A7469 = "" A7470 = "" -A7471 = "" A7472 = "" A7473 = "" A7474 = "" A7475 = "" A7476 = "" A7477 = "" A7478 = "" A7479 = "" A7480 = "" -A7481 = "" A7482 = "" A7483 = "" A7484 = "" A7485 = "" A7486 = "" A7487 = "" A7488 = "" A7489 = "" A7490 = "" -A7491 = "" A7492 = "" A7493 = "" A7494 = "" A7495 = "" A7496 = "" A7497 = "" A7498 = "" A7499 = "" A7500 = "" -A7501 = "" A7502 = "" A7503 = "" A7504 = "" A7505 = "" A7506 = "" A7507 = "" A7508 = "" A7509 = "" A7510 = "" -A7511 = "" A7512 = "" A7513 = "" A7514 = "" A7515 = "" A7516 = "" A7517 = "" A7518 = "" A7519 = "" A7520 = "" -A7521 = "" A7522 = "" A7523 = "" A7524 = "" A7525 = "" A7526 = "" A7527 = "" A7528 = "" A7529 = "" A7530 = "" -A7531 = "" A7532 = "" A7533 = "" A7534 = "" A7535 = "" A7536 = "" A7537 = "" A7538 = "" A7539 = "" A7540 = "" -A7541 = "" A7542 = "" A7543 = "" A7544 = "" A7545 = "" A7546 = "" A7547 = "" A7548 = "" A7549 = "" A7550 = "" -A7551 = "" A7552 = "" A7553 = "" A7554 = "" A7555 = "" A7556 = "" A7557 = "" A7558 = "" A7559 = "" A7560 = "" -A7561 = "" A7562 = "" A7563 = "" A7564 = "" A7565 = "" A7566 = "" A7567 = "" A7568 = "" A7569 = "" A7570 = "" -A7571 = "" A7572 = "" A7573 = "" A7574 = "" A7575 = "" A7576 = "" A7577 = "" A7578 = "" A7579 = "" A7580 = "" -A7581 = "" A7582 = "" A7583 = "" A7584 = "" A7585 = "" A7586 = "" A7587 = "" A7588 = "" A7589 = "" A7590 = "" -A7591 = "" A7592 = "" A7593 = "" A7594 = "" A7595 = "" A7596 = "" A7597 = "" A7598 = "" A7599 = "" A7600 = "" -A7601 = "" A7602 = "" A7603 = "" A7604 = "" A7605 = "" A7606 = "" A7607 = "" A7608 = "" A7609 = "" A7610 = "" -A7611 = "" A7612 = "" A7613 = "" A7614 = "" A7615 = "" A7616 = "" A7617 = "" A7618 = "" A7619 = "" A7620 = "" -A7621 = "" A7622 = "" A7623 = "" A7624 = "" A7625 = "" A7626 = "" A7627 = "" A7628 = "" A7629 = "" A7630 = "" -A7631 = "" A7632 = "" A7633 = "" A7634 = "" A7635 = "" A7636 = "" A7637 = "" A7638 = "" A7639 = "" A7640 = "" -A7641 = "" A7642 = "" A7643 = "" A7644 = "" A7645 = "" A7646 = "" A7647 = "" A7648 = "" A7649 = "" A7650 = "" -A7651 = "" A7652 = "" A7653 = "" A7654 = "" A7655 = "" A7656 = "" A7657 = "" A7658 = "" A7659 = "" A7660 = "" -A7661 = "" A7662 = "" A7663 = "" A7664 = "" A7665 = "" A7666 = "" A7667 = "" A7668 = "" A7669 = "" A7670 = "" -A7671 = "" A7672 = "" A7673 = "" A7674 = "" A7675 = "" A7676 = "" A7677 = "" A7678 = "" A7679 = "" A7680 = "" -A7681 = "" A7682 = "" A7683 = "" A7684 = "" A7685 = "" A7686 = "" A7687 = "" A7688 = "" A7689 = "" A7690 = "" -A7691 = "" A7692 = "" A7693 = "" A7694 = "" A7695 = "" A7696 = "" A7697 = "" A7698 = "" A7699 = "" A7700 = "" -A7701 = "" A7702 = "" A7703 = "" A7704 = "" A7705 = "" A7706 = "" A7707 = "" A7708 = "" A7709 = "" A7710 = "" -A7711 = "" A7712 = "" A7713 = "" A7714 = "" A7715 = "" A7716 = "" A7717 = "" A7718 = "" A7719 = "" A7720 = "" -A7721 = "" A7722 = "" A7723 = "" A7724 = "" A7725 = "" A7726 = "" A7727 = "" A7728 = "" A7729 = "" A7730 = "" -A7731 = "" A7732 = "" A7733 = "" A7734 = "" A7735 = "" A7736 = "" A7737 = "" A7738 = "" A7739 = "" A7740 = "" -A7741 = "" A7742 = "" A7743 = "" A7744 = "" A7745 = "" A7746 = "" A7747 = "" A7748 = "" A7749 = "" A7750 = "" -A7751 = "" A7752 = "" A7753 = "" A7754 = "" A7755 = "" A7756 = "" A7757 = "" A7758 = "" A7759 = "" A7760 = "" -A7761 = "" A7762 = "" A7763 = "" A7764 = "" A7765 = "" A7766 = "" A7767 = "" A7768 = "" A7769 = "" A7770 = "" -A7771 = "" A7772 = "" A7773 = "" A7774 = "" A7775 = "" A7776 = "" A7777 = "" A7778 = "" A7779 = "" A7780 = "" -A7781 = "" A7782 = "" A7783 = "" A7784 = "" A7785 = "" A7786 = "" A7787 = "" A7788 = "" A7789 = "" A7790 = "" -A7791 = "" A7792 = "" A7793 = "" A7794 = "" A7795 = "" A7796 = "" A7797 = "" A7798 = "" A7799 = "" A7800 = "" -A7801 = "" A7802 = "" A7803 = "" A7804 = "" A7805 = "" A7806 = "" A7807 = "" A7808 = "" A7809 = "" A7810 = "" -A7811 = "" A7812 = "" A7813 = "" A7814 = "" A7815 = "" A7816 = "" A7817 = "" A7818 = "" A7819 = "" A7820 = "" -A7821 = "" A7822 = "" A7823 = "" A7824 = "" A7825 = "" A7826 = "" A7827 = "" A7828 = "" A7829 = "" A7830 = "" -A7831 = "" A7832 = "" A7833 = "" A7834 = "" A7835 = "" A7836 = "" A7837 = "" A7838 = "" A7839 = "" A7840 = "" -A7841 = "" A7842 = "" A7843 = "" A7844 = "" A7845 = "" A7846 = "" A7847 = "" A7848 = "" A7849 = "" A7850 = "" -A7851 = "" A7852 = "" A7853 = "" A7854 = "" A7855 = "" A7856 = "" A7857 = "" A7858 = "" A7859 = "" A7860 = "" -A7861 = "" A7862 = "" A7863 = "" A7864 = "" A7865 = "" A7866 = "" A7867 = "" A7868 = "" A7869 = "" A7870 = "" -A7871 = "" A7872 = "" A7873 = "" A7874 = "" A7875 = "" A7876 = "" A7877 = "" A7878 = "" A7879 = "" A7880 = "" -A7881 = "" A7882 = "" A7883 = "" A7884 = "" A7885 = "" A7886 = "" A7887 = "" A7888 = "" A7889 = "" A7890 = "" -A7891 = "" A7892 = "" A7893 = "" A7894 = "" A7895 = "" A7896 = "" A7897 = "" A7898 = "" A7899 = "" A7900 = "" -A7901 = "" A7902 = "" A7903 = "" A7904 = "" A7905 = "" A7906 = "" A7907 = "" A7908 = "" A7909 = "" A7910 = "" -A7911 = "" A7912 = "" A7913 = "" A7914 = "" A7915 = "" A7916 = "" A7917 = "" A7918 = "" A7919 = "" A7920 = "" -A7921 = "" A7922 = "" A7923 = "" A7924 = "" A7925 = "" A7926 = "" A7927 = "" A7928 = "" A7929 = "" A7930 = "" -A7931 = "" A7932 = "" A7933 = "" A7934 = "" A7935 = "" A7936 = "" A7937 = "" A7938 = "" A7939 = "" A7940 = "" -A7941 = "" A7942 = "" A7943 = "" A7944 = "" A7945 = "" A7946 = "" A7947 = "" A7948 = "" A7949 = "" A7950 = "" -A7951 = "" A7952 = "" A7953 = "" A7954 = "" A7955 = "" A7956 = "" A7957 = "" A7958 = "" A7959 = "" A7960 = "" -A7961 = "" A7962 = "" A7963 = "" A7964 = "" A7965 = "" A7966 = "" A7967 = "" A7968 = "" A7969 = "" A7970 = "" -A7971 = "" A7972 = "" A7973 = "" A7974 = "" A7975 = "" A7976 = "" A7977 = "" A7978 = "" A7979 = "" A7980 = "" -A7981 = "" A7982 = "" A7983 = "" A7984 = "" A7985 = "" A7986 = "" A7987 = "" A7988 = "" A7989 = "" A7990 = "" -A7991 = "" A7992 = "" A7993 = "" A7994 = "" A7995 = "" A7996 = "" A7997 = "" A7998 = "" A7999 = "" A8000 = "" -A8001 = "" A8002 = "" A8003 = "" A8004 = "" A8005 = "" A8006 = "" A8007 = "" A8008 = "" A8009 = "" A8010 = "" -A8011 = "" A8012 = "" A8013 = "" A8014 = "" A8015 = "" A8016 = "" A8017 = "" A8018 = "" A8019 = "" A8020 = "" -A8021 = "" A8022 = "" A8023 = "" A8024 = "" A8025 = "" A8026 = "" A8027 = "" A8028 = "" A8029 = "" A8030 = "" -A8031 = "" A8032 = "" A8033 = "" A8034 = "" A8035 = "" A8036 = "" A8037 = "" A8038 = "" A8039 = "" A8040 = "" -A8041 = "" A8042 = "" A8043 = "" A8044 = "" A8045 = "" A8046 = "" A8047 = "" A8048 = "" A8049 = "" A8050 = "" -A8051 = "" A8052 = "" A8053 = "" A8054 = "" A8055 = "" A8056 = "" A8057 = "" A8058 = "" A8059 = "" A8060 = "" -A8061 = "" A8062 = "" A8063 = "" A8064 = "" A8065 = "" A8066 = "" A8067 = "" A8068 = "" A8069 = "" A8070 = "" -A8071 = "" A8072 = "" A8073 = "" A8074 = "" A8075 = "" A8076 = "" A8077 = "" A8078 = "" A8079 = "" A8080 = "" -A8081 = "" A8082 = "" A8083 = "" A8084 = "" A8085 = "" A8086 = "" A8087 = "" A8088 = "" A8089 = "" A8090 = "" -A8091 = "" A8092 = "" A8093 = "" A8094 = "" A8095 = "" A8096 = "" A8097 = "" A8098 = "" A8099 = "" A8100 = "" -A8101 = "" A8102 = "" A8103 = "" A8104 = "" A8105 = "" A8106 = "" A8107 = "" A8108 = "" A8109 = "" A8110 = "" -A8111 = "" A8112 = "" A8113 = "" A8114 = "" A8115 = "" A8116 = "" A8117 = "" A8118 = "" A8119 = "" A8120 = "" -A8121 = "" A8122 = "" A8123 = "" A8124 = "" A8125 = "" A8126 = "" A8127 = "" A8128 = "" A8129 = "" A8130 = "" -A8131 = "" A8132 = "" A8133 = "" A8134 = "" A8135 = "" A8136 = "" A8137 = "" A8138 = "" A8139 = "" A8140 = "" -A8141 = "" A8142 = "" A8143 = "" A8144 = "" A8145 = "" A8146 = "" A8147 = "" A8148 = "" A8149 = "" A8150 = "" -A8151 = "" A8152 = "" A8153 = "" A8154 = "" A8155 = "" A8156 = "" A8157 = "" A8158 = "" A8159 = "" A8160 = "" -A8161 = "" A8162 = "" A8163 = "" A8164 = "" A8165 = "" A8166 = "" A8167 = "" A8168 = "" A8169 = "" A8170 = "" -A8171 = "" A8172 = "" A8173 = "" A8174 = "" A8175 = "" A8176 = "" A8177 = "" A8178 = "" A8179 = "" A8180 = "" -A8181 = "" A8182 = "" A8183 = "" A8184 = "" A8185 = "" A8186 = "" A8187 = "" A8188 = "" A8189 = "" A8190 = "" -A8191 = "" A8192 = "" A8193 = "" A8194 = "" A8195 = "" A8196 = "" A8197 = "" A8198 = "" A8199 = "" A8200 = "" -A8201 = "" A8202 = "" A8203 = "" A8204 = "" A8205 = "" A8206 = "" A8207 = "" A8208 = "" A8209 = "" A8210 = "" -A8211 = "" A8212 = "" A8213 = "" A8214 = "" A8215 = "" A8216 = "" A8217 = "" A8218 = "" A8219 = "" A8220 = "" -A8221 = "" A8222 = "" A8223 = "" A8224 = "" A8225 = "" A8226 = "" A8227 = "" A8228 = "" A8229 = "" A8230 = "" -A8231 = "" A8232 = "" A8233 = "" A8234 = "" A8235 = "" A8236 = "" A8237 = "" A8238 = "" A8239 = "" A8240 = "" -A8241 = "" A8242 = "" A8243 = "" A8244 = "" A8245 = "" A8246 = "" A8247 = "" A8248 = "" A8249 = "" A8250 = "" -A8251 = "" A8252 = "" A8253 = "" A8254 = "" A8255 = "" A8256 = "" A8257 = "" A8258 = "" A8259 = "" A8260 = "" -A8261 = "" A8262 = "" A8263 = "" A8264 = "" A8265 = "" A8266 = "" A8267 = "" A8268 = "" A8269 = "" A8270 = "" -A8271 = "" A8272 = "" A8273 = "" A8274 = "" A8275 = "" A8276 = "" A8277 = "" A8278 = "" A8279 = "" A8280 = "" -A8281 = "" A8282 = "" A8283 = "" A8284 = "" A8285 = "" A8286 = "" A8287 = "" A8288 = "" A8289 = "" A8290 = "" -A8291 = "" A8292 = "" A8293 = "" A8294 = "" A8295 = "" A8296 = "" A8297 = "" A8298 = "" A8299 = "" A8300 = "" -A8301 = "" A8302 = "" A8303 = "" A8304 = "" A8305 = "" A8306 = "" A8307 = "" A8308 = "" A8309 = "" A8310 = "" -A8311 = "" A8312 = "" A8313 = "" A8314 = "" A8315 = "" A8316 = "" A8317 = "" A8318 = "" A8319 = "" A8320 = "" -A8321 = "" A8322 = "" A8323 = "" A8324 = "" A8325 = "" A8326 = "" A8327 = "" A8328 = "" A8329 = "" A8330 = "" -A8331 = "" A8332 = "" A8333 = "" A8334 = "" A8335 = "" A8336 = "" A8337 = "" A8338 = "" A8339 = "" A8340 = "" -A8341 = "" A8342 = "" A8343 = "" A8344 = "" A8345 = "" A8346 = "" A8347 = "" A8348 = "" A8349 = "" A8350 = "" -A8351 = "" A8352 = "" A8353 = "" A8354 = "" A8355 = "" A8356 = "" A8357 = "" A8358 = "" A8359 = "" A8360 = "" -A8361 = "" A8362 = "" A8363 = "" A8364 = "" A8365 = "" A8366 = "" A8367 = "" A8368 = "" A8369 = "" A8370 = "" -A8371 = "" A8372 = "" A8373 = "" A8374 = "" A8375 = "" A8376 = "" A8377 = "" A8378 = "" A8379 = "" A8380 = "" -A8381 = "" A8382 = "" A8383 = "" A8384 = "" A8385 = "" A8386 = "" A8387 = "" A8388 = "" A8389 = "" A8390 = "" -A8391 = "" A8392 = "" A8393 = "" A8394 = "" A8395 = "" A8396 = "" A8397 = "" A8398 = "" A8399 = "" A8400 = "" -A8401 = "" A8402 = "" A8403 = "" A8404 = "" A8405 = "" A8406 = "" A8407 = "" A8408 = "" A8409 = "" A8410 = "" -A8411 = "" A8412 = "" A8413 = "" A8414 = "" A8415 = "" A8416 = "" A8417 = "" A8418 = "" A8419 = "" A8420 = "" -A8421 = "" A8422 = "" A8423 = "" A8424 = "" A8425 = "" A8426 = "" A8427 = "" A8428 = "" A8429 = "" A8430 = "" -A8431 = "" A8432 = "" A8433 = "" A8434 = "" A8435 = "" A8436 = "" A8437 = "" A8438 = "" A8439 = "" A8440 = "" -A8441 = "" A8442 = "" A8443 = "" A8444 = "" A8445 = "" A8446 = "" A8447 = "" A8448 = "" A8449 = "" A8450 = "" -A8451 = "" A8452 = "" A8453 = "" A8454 = "" A8455 = "" A8456 = "" A8457 = "" A8458 = "" A8459 = "" A8460 = "" -A8461 = "" A8462 = "" A8463 = "" A8464 = "" A8465 = "" A8466 = "" A8467 = "" A8468 = "" A8469 = "" A8470 = "" -A8471 = "" A8472 = "" A8473 = "" A8474 = "" A8475 = "" A8476 = "" A8477 = "" A8478 = "" A8479 = "" A8480 = "" -A8481 = "" A8482 = "" A8483 = "" A8484 = "" A8485 = "" A8486 = "" A8487 = "" A8488 = "" A8489 = "" A8490 = "" -A8491 = "" A8492 = "" A8493 = "" A8494 = "" A8495 = "" A8496 = "" A8497 = "" A8498 = "" A8499 = "" A8500 = "" -A8501 = "" A8502 = "" A8503 = "" A8504 = "" A8505 = "" A8506 = "" A8507 = "" A8508 = "" A8509 = "" A8510 = "" -A8511 = "" A8512 = "" A8513 = "" A8514 = "" A8515 = "" A8516 = "" A8517 = "" A8518 = "" A8519 = "" A8520 = "" -A8521 = "" A8522 = "" A8523 = "" A8524 = "" A8525 = "" A8526 = "" A8527 = "" A8528 = "" A8529 = "" A8530 = "" -A8531 = "" A8532 = "" A8533 = "" A8534 = "" A8535 = "" A8536 = "" A8537 = "" A8538 = "" A8539 = "" A8540 = "" -A8541 = "" A8542 = "" A8543 = "" A8544 = "" A8545 = "" A8546 = "" A8547 = "" A8548 = "" A8549 = "" A8550 = "" -A8551 = "" A8552 = "" A8553 = "" A8554 = "" A8555 = "" A8556 = "" A8557 = "" A8558 = "" A8559 = "" A8560 = "" -A8561 = "" A8562 = "" A8563 = "" A8564 = "" A8565 = "" A8566 = "" A8567 = "" A8568 = "" A8569 = "" A8570 = "" -A8571 = "" A8572 = "" A8573 = "" A8574 = "" A8575 = "" A8576 = "" A8577 = "" A8578 = "" A8579 = "" A8580 = "" -A8581 = "" A8582 = "" A8583 = "" A8584 = "" A8585 = "" A8586 = "" A8587 = "" A8588 = "" A8589 = "" A8590 = "" -A8591 = "" A8592 = "" A8593 = "" A8594 = "" A8595 = "" A8596 = "" A8597 = "" A8598 = "" A8599 = "" A8600 = "" -A8601 = "" A8602 = "" A8603 = "" A8604 = "" A8605 = "" A8606 = "" A8607 = "" A8608 = "" A8609 = "" A8610 = "" -A8611 = "" A8612 = "" A8613 = "" A8614 = "" A8615 = "" A8616 = "" A8617 = "" A8618 = "" A8619 = "" A8620 = "" -A8621 = "" A8622 = "" A8623 = "" A8624 = "" A8625 = "" A8626 = "" A8627 = "" A8628 = "" A8629 = "" A8630 = "" -A8631 = "" A8632 = "" A8633 = "" A8634 = "" A8635 = "" A8636 = "" A8637 = "" A8638 = "" A8639 = "" A8640 = "" -A8641 = "" A8642 = "" A8643 = "" A8644 = "" A8645 = "" A8646 = "" A8647 = "" A8648 = "" A8649 = "" A8650 = "" -A8651 = "" A8652 = "" A8653 = "" A8654 = "" A8655 = "" A8656 = "" A8657 = "" A8658 = "" A8659 = "" A8660 = "" -A8661 = "" A8662 = "" A8663 = "" A8664 = "" A8665 = "" A8666 = "" A8667 = "" A8668 = "" A8669 = "" A8670 = "" -A8671 = "" A8672 = "" A8673 = "" A8674 = "" A8675 = "" A8676 = "" A8677 = "" A8678 = "" A8679 = "" A8680 = "" -A8681 = "" A8682 = "" A8683 = "" A8684 = "" A8685 = "" A8686 = "" A8687 = "" A8688 = "" A8689 = "" A8690 = "" -A8691 = "" A8692 = "" A8693 = "" A8694 = "" A8695 = "" A8696 = "" A8697 = "" A8698 = "" A8699 = "" A8700 = "" -A8701 = "" A8702 = "" A8703 = "" A8704 = "" A8705 = "" A8706 = "" A8707 = "" A8708 = "" A8709 = "" A8710 = "" -A8711 = "" A8712 = "" A8713 = "" A8714 = "" A8715 = "" A8716 = "" A8717 = "" A8718 = "" A8719 = "" A8720 = "" -A8721 = "" A8722 = "" A8723 = "" A8724 = "" A8725 = "" A8726 = "" A8727 = "" A8728 = "" A8729 = "" A8730 = "" -A8731 = "" A8732 = "" A8733 = "" A8734 = "" A8735 = "" A8736 = "" A8737 = "" A8738 = "" A8739 = "" A8740 = "" -A8741 = "" A8742 = "" A8743 = "" A8744 = "" A8745 = "" A8746 = "" A8747 = "" A8748 = "" A8749 = "" A8750 = "" -A8751 = "" A8752 = "" A8753 = "" A8754 = "" A8755 = "" A8756 = "" A8757 = "" A8758 = "" A8759 = "" A8760 = "" -A8761 = "" A8762 = "" A8763 = "" A8764 = "" A8765 = "" A8766 = "" A8767 = "" A8768 = "" A8769 = "" A8770 = "" -A8771 = "" A8772 = "" A8773 = "" A8774 = "" A8775 = "" A8776 = "" A8777 = "" A8778 = "" A8779 = "" A8780 = "" -A8781 = "" A8782 = "" A8783 = "" A8784 = "" A8785 = "" A8786 = "" A8787 = "" A8788 = "" A8789 = "" A8790 = "" -A8791 = "" A8792 = "" A8793 = "" A8794 = "" A8795 = "" A8796 = "" A8797 = "" A8798 = "" A8799 = "" A8800 = "" -A8801 = "" A8802 = "" A8803 = "" A8804 = "" A8805 = "" A8806 = "" A8807 = "" A8808 = "" A8809 = "" A8810 = "" -A8811 = "" A8812 = "" A8813 = "" A8814 = "" A8815 = "" A8816 = "" A8817 = "" A8818 = "" A8819 = "" A8820 = "" -A8821 = "" A8822 = "" A8823 = "" A8824 = "" A8825 = "" A8826 = "" A8827 = "" A8828 = "" A8829 = "" A8830 = "" -A8831 = "" A8832 = "" A8833 = "" A8834 = "" A8835 = "" A8836 = "" A8837 = "" A8838 = "" A8839 = "" A8840 = "" -A8841 = "" A8842 = "" A8843 = "" A8844 = "" A8845 = "" A8846 = "" A8847 = "" A8848 = "" A8849 = "" A8850 = "" -A8851 = "" A8852 = "" A8853 = "" A8854 = "" A8855 = "" A8856 = "" A8857 = "" A8858 = "" A8859 = "" A8860 = "" -A8861 = "" A8862 = "" A8863 = "" A8864 = "" A8865 = "" A8866 = "" A8867 = "" A8868 = "" A8869 = "" A8870 = "" -A8871 = "" A8872 = "" A8873 = "" A8874 = "" A8875 = "" A8876 = "" A8877 = "" A8878 = "" A8879 = "" A8880 = "" -A8881 = "" A8882 = "" A8883 = "" A8884 = "" A8885 = "" A8886 = "" A8887 = "" A8888 = "" A8889 = "" A8890 = "" -A8891 = "" A8892 = "" A8893 = "" A8894 = "" A8895 = "" A8896 = "" A8897 = "" A8898 = "" A8899 = "" A8900 = "" -A8901 = "" A8902 = "" A8903 = "" A8904 = "" A8905 = "" A8906 = "" A8907 = "" A8908 = "" A8909 = "" A8910 = "" -A8911 = "" A8912 = "" A8913 = "" A8914 = "" A8915 = "" A8916 = "" A8917 = "" A8918 = "" A8919 = "" A8920 = "" -A8921 = "" A8922 = "" A8923 = "" A8924 = "" A8925 = "" A8926 = "" A8927 = "" A8928 = "" A8929 = "" A8930 = "" -A8931 = "" A8932 = "" A8933 = "" A8934 = "" A8935 = "" A8936 = "" A8937 = "" A8938 = "" A8939 = "" A8940 = "" -A8941 = "" A8942 = "" A8943 = "" A8944 = "" A8945 = "" A8946 = "" A8947 = "" A8948 = "" A8949 = "" A8950 = "" -A8951 = "" A8952 = "" A8953 = "" A8954 = "" A8955 = "" A8956 = "" A8957 = "" A8958 = "" A8959 = "" A8960 = "" -A8961 = "" A8962 = "" A8963 = "" A8964 = "" A8965 = "" A8966 = "" A8967 = "" A8968 = "" A8969 = "" A8970 = "" -A8971 = "" A8972 = "" A8973 = "" A8974 = "" A8975 = "" A8976 = "" A8977 = "" A8978 = "" A8979 = "" A8980 = "" -A8981 = "" A8982 = "" A8983 = "" A8984 = "" A8985 = "" A8986 = "" A8987 = "" A8988 = "" A8989 = "" A8990 = "" -A8991 = "" A8992 = "" A8993 = "" A8994 = "" A8995 = "" A8996 = "" A8997 = "" A8998 = "" A8999 = "" A9000 = "" -A9001 = "" A9002 = "" A9003 = "" A9004 = "" A9005 = "" A9006 = "" A9007 = "" A9008 = "" A9009 = "" A9010 = "" -A9011 = "" A9012 = "" A9013 = "" A9014 = "" A9015 = "" A9016 = "" A9017 = "" A9018 = "" A9019 = "" A9020 = "" -A9021 = "" A9022 = "" A9023 = "" A9024 = "" A9025 = "" A9026 = "" A9027 = "" A9028 = "" A9029 = "" A9030 = "" -A9031 = "" A9032 = "" A9033 = "" A9034 = "" A9035 = "" A9036 = "" A9037 = "" A9038 = "" A9039 = "" A9040 = "" -A9041 = "" A9042 = "" A9043 = "" A9044 = "" A9045 = "" A9046 = "" A9047 = "" A9048 = "" A9049 = "" A9050 = "" -A9051 = "" A9052 = "" A9053 = "" A9054 = "" A9055 = "" A9056 = "" A9057 = "" A9058 = "" A9059 = "" A9060 = "" -A9061 = "" A9062 = "" A9063 = "" A9064 = "" A9065 = "" A9066 = "" A9067 = "" A9068 = "" A9069 = "" A9070 = "" -A9071 = "" A9072 = "" A9073 = "" A9074 = "" A9075 = "" A9076 = "" A9077 = "" A9078 = "" A9079 = "" A9080 = "" -A9081 = "" A9082 = "" A9083 = "" A9084 = "" A9085 = "" A9086 = "" A9087 = "" A9088 = "" A9089 = "" A9090 = "" -A9091 = "" A9092 = "" A9093 = "" A9094 = "" A9095 = "" A9096 = "" A9097 = "" A9098 = "" A9099 = "" A9100 = "" -A9101 = "" A9102 = "" A9103 = "" A9104 = "" A9105 = "" A9106 = "" A9107 = "" A9108 = "" A9109 = "" A9110 = "" -A9111 = "" A9112 = "" A9113 = "" A9114 = "" A9115 = "" A9116 = "" A9117 = "" A9118 = "" A9119 = "" A9120 = "" -A9121 = "" A9122 = "" A9123 = "" A9124 = "" A9125 = "" A9126 = "" A9127 = "" A9128 = "" A9129 = "" A9130 = "" -A9131 = "" A9132 = "" A9133 = "" A9134 = "" A9135 = "" A9136 = "" A9137 = "" A9138 = "" A9139 = "" A9140 = "" -A9141 = "" A9142 = "" A9143 = "" A9144 = "" A9145 = "" A9146 = "" A9147 = "" A9148 = "" A9149 = "" A9150 = "" -A9151 = "" A9152 = "" A9153 = "" A9154 = "" A9155 = "" A9156 = "" A9157 = "" A9158 = "" A9159 = "" A9160 = "" -A9161 = "" A9162 = "" A9163 = "" A9164 = "" A9165 = "" A9166 = "" A9167 = "" A9168 = "" A9169 = "" A9170 = "" -A9171 = "" A9172 = "" A9173 = "" A9174 = "" A9175 = "" A9176 = "" A9177 = "" A9178 = "" A9179 = "" A9180 = "" -A9181 = "" A9182 = "" A9183 = "" A9184 = "" A9185 = "" A9186 = "" A9187 = "" A9188 = "" A9189 = "" A9190 = "" -A9191 = "" A9192 = "" A9193 = "" A9194 = "" A9195 = "" A9196 = "" A9197 = "" A9198 = "" A9199 = "" A9200 = "" -A9201 = "" A9202 = "" A9203 = "" A9204 = "" A9205 = "" A9206 = "" A9207 = "" A9208 = "" A9209 = "" A9210 = "" -A9211 = "" A9212 = "" A9213 = "" A9214 = "" A9215 = "" A9216 = "" A9217 = "" A9218 = "" A9219 = "" A9220 = "" -A9221 = "" A9222 = "" A9223 = "" A9224 = "" A9225 = "" A9226 = "" A9227 = "" A9228 = "" A9229 = "" A9230 = "" -A9231 = "" A9232 = "" A9233 = "" A9234 = "" A9235 = "" A9236 = "" A9237 = "" A9238 = "" A9239 = "" A9240 = "" -A9241 = "" A9242 = "" A9243 = "" A9244 = "" A9245 = "" A9246 = "" A9247 = "" A9248 = "" A9249 = "" A9250 = "" -A9251 = "" A9252 = "" A9253 = "" A9254 = "" A9255 = "" A9256 = "" A9257 = "" A9258 = "" A9259 = "" A9260 = "" -A9261 = "" A9262 = "" A9263 = "" A9264 = "" A9265 = "" A9266 = "" A9267 = "" A9268 = "" A9269 = "" A9270 = "" -A9271 = "" A9272 = "" A9273 = "" A9274 = "" A9275 = "" A9276 = "" A9277 = "" A9278 = "" A9279 = "" A9280 = "" -A9281 = "" A9282 = "" A9283 = "" A9284 = "" A9285 = "" A9286 = "" A9287 = "" A9288 = "" A9289 = "" A9290 = "" -A9291 = "" A9292 = "" A9293 = "" A9294 = "" A9295 = "" A9296 = "" A9297 = "" A9298 = "" A9299 = "" A9300 = "" -A9301 = "" A9302 = "" A9303 = "" A9304 = "" A9305 = "" A9306 = "" A9307 = "" A9308 = "" A9309 = "" A9310 = "" -A9311 = "" A9312 = "" A9313 = "" A9314 = "" A9315 = "" A9316 = "" A9317 = "" A9318 = "" A9319 = "" A9320 = "" -A9321 = "" A9322 = "" A9323 = "" A9324 = "" A9325 = "" A9326 = "" A9327 = "" A9328 = "" A9329 = "" A9330 = "" -A9331 = "" A9332 = "" A9333 = "" A9334 = "" A9335 = "" A9336 = "" A9337 = "" A9338 = "" A9339 = "" A9340 = "" -A9341 = "" A9342 = "" A9343 = "" A9344 = "" A9345 = "" A9346 = "" A9347 = "" A9348 = "" A9349 = "" A9350 = "" -A9351 = "" A9352 = "" A9353 = "" A9354 = "" A9355 = "" A9356 = "" A9357 = "" A9358 = "" A9359 = "" A9360 = "" -A9361 = "" A9362 = "" A9363 = "" A9364 = "" A9365 = "" A9366 = "" A9367 = "" A9368 = "" A9369 = "" A9370 = "" -A9371 = "" A9372 = "" A9373 = "" A9374 = "" A9375 = "" A9376 = "" A9377 = "" A9378 = "" A9379 = "" A9380 = "" -A9381 = "" A9382 = "" A9383 = "" A9384 = "" A9385 = "" A9386 = "" A9387 = "" A9388 = "" A9389 = "" A9390 = "" -A9391 = "" A9392 = "" A9393 = "" A9394 = "" A9395 = "" A9396 = "" A9397 = "" A9398 = "" A9399 = "" A9400 = "" -A9401 = "" A9402 = "" A9403 = "" A9404 = "" A9405 = "" A9406 = "" A9407 = "" A9408 = "" A9409 = "" A9410 = "" -A9411 = "" A9412 = "" A9413 = "" A9414 = "" A9415 = "" A9416 = "" A9417 = "" A9418 = "" A9419 = "" A9420 = "" -A9421 = "" A9422 = "" A9423 = "" A9424 = "" A9425 = "" A9426 = "" A9427 = "" A9428 = "" A9429 = "" A9430 = "" -A9431 = "" A9432 = "" A9433 = "" A9434 = "" A9435 = "" A9436 = "" A9437 = "" A9438 = "" A9439 = "" A9440 = "" -A9441 = "" A9442 = "" A9443 = "" A9444 = "" A9445 = "" A9446 = "" A9447 = "" A9448 = "" A9449 = "" A9450 = "" -A9451 = "" A9452 = "" A9453 = "" A9454 = "" A9455 = "" A9456 = "" A9457 = "" A9458 = "" A9459 = "" A9460 = "" -A9461 = "" A9462 = "" A9463 = "" A9464 = "" A9465 = "" A9466 = "" A9467 = "" A9468 = "" A9469 = "" A9470 = "" -A9471 = "" A9472 = "" A9473 = "" A9474 = "" A9475 = "" A9476 = "" A9477 = "" A9478 = "" A9479 = "" A9480 = "" -A9481 = "" A9482 = "" A9483 = "" A9484 = "" A9485 = "" A9486 = "" A9487 = "" A9488 = "" A9489 = "" A9490 = "" -A9491 = "" A9492 = "" A9493 = "" A9494 = "" A9495 = "" A9496 = "" A9497 = "" A9498 = "" A9499 = "" A9500 = "" -A9501 = "" A9502 = "" A9503 = "" A9504 = "" A9505 = "" A9506 = "" A9507 = "" A9508 = "" A9509 = "" A9510 = "" -A9511 = "" A9512 = "" A9513 = "" A9514 = "" A9515 = "" A9516 = "" A9517 = "" A9518 = "" A9519 = "" A9520 = "" -A9521 = "" A9522 = "" A9523 = "" A9524 = "" A9525 = "" A9526 = "" A9527 = "" A9528 = "" A9529 = "" A9530 = "" -A9531 = "" A9532 = "" A9533 = "" A9534 = "" A9535 = "" A9536 = "" A9537 = "" A9538 = "" A9539 = "" A9540 = "" -A9541 = "" A9542 = "" A9543 = "" A9544 = "" A9545 = "" A9546 = "" A9547 = "" A9548 = "" A9549 = "" A9550 = "" -A9551 = "" A9552 = "" A9553 = "" A9554 = "" A9555 = "" A9556 = "" A9557 = "" A9558 = "" A9559 = "" A9560 = "" -A9561 = "" A9562 = "" A9563 = "" A9564 = "" A9565 = "" A9566 = "" A9567 = "" A9568 = "" A9569 = "" A9570 = "" -A9571 = "" A9572 = "" A9573 = "" A9574 = "" A9575 = "" A9576 = "" A9577 = "" A9578 = "" A9579 = "" A9580 = "" -A9581 = "" A9582 = "" A9583 = "" A9584 = "" A9585 = "" A9586 = "" A9587 = "" A9588 = "" A9589 = "" A9590 = "" -A9591 = "" A9592 = "" A9593 = "" A9594 = "" A9595 = "" A9596 = "" A9597 = "" A9598 = "" A9599 = "" A9600 = "" -A9601 = "" A9602 = "" A9603 = "" A9604 = "" A9605 = "" A9606 = "" A9607 = "" A9608 = "" A9609 = "" A9610 = "" -A9611 = "" A9612 = "" A9613 = "" A9614 = "" A9615 = "" A9616 = "" A9617 = "" A9618 = "" A9619 = "" A9620 = "" -A9621 = "" A9622 = "" A9623 = "" A9624 = "" A9625 = "" A9626 = "" A9627 = "" A9628 = "" A9629 = "" A9630 = "" -A9631 = "" A9632 = "" A9633 = "" A9634 = "" A9635 = "" A9636 = "" A9637 = "" A9638 = "" A9639 = "" A9640 = "" -A9641 = "" A9642 = "" A9643 = "" A9644 = "" A9645 = "" A9646 = "" A9647 = "" A9648 = "" A9649 = "" A9650 = "" -A9651 = "" A9652 = "" A9653 = "" A9654 = "" A9655 = "" A9656 = "" A9657 = "" A9658 = "" A9659 = "" A9660 = "" -A9661 = "" A9662 = "" A9663 = "" A9664 = "" A9665 = "" A9666 = "" A9667 = "" A9668 = "" A9669 = "" A9670 = "" -A9671 = "" A9672 = "" A9673 = "" A9674 = "" A9675 = "" A9676 = "" A9677 = "" A9678 = "" A9679 = "" A9680 = "" -A9681 = "" A9682 = "" A9683 = "" A9684 = "" A9685 = "" A9686 = "" A9687 = "" A9688 = "" A9689 = "" A9690 = "" -A9691 = "" A9692 = "" A9693 = "" A9694 = "" A9695 = "" A9696 = "" A9697 = "" A9698 = "" A9699 = "" A9700 = "" -A9701 = "" A9702 = "" A9703 = "" A9704 = "" A9705 = "" A9706 = "" A9707 = "" A9708 = "" A9709 = "" A9710 = "" -A9711 = "" A9712 = "" A9713 = "" A9714 = "" A9715 = "" A9716 = "" A9717 = "" A9718 = "" A9719 = "" A9720 = "" -A9721 = "" A9722 = "" A9723 = "" A9724 = "" A9725 = "" A9726 = "" A9727 = "" A9728 = "" A9729 = "" A9730 = "" -A9731 = "" A9732 = "" A9733 = "" A9734 = "" A9735 = "" A9736 = "" A9737 = "" A9738 = "" A9739 = "" A9740 = "" -A9741 = "" A9742 = "" A9743 = "" A9744 = "" A9745 = "" A9746 = "" A9747 = "" A9748 = "" A9749 = "" A9750 = "" -A9751 = "" A9752 = "" A9753 = "" A9754 = "" A9755 = "" A9756 = "" A9757 = "" A9758 = "" A9759 = "" A9760 = "" -A9761 = "" A9762 = "" A9763 = "" A9764 = "" A9765 = "" A9766 = "" A9767 = "" A9768 = "" A9769 = "" A9770 = "" -A9771 = "" A9772 = "" A9773 = "" A9774 = "" A9775 = "" A9776 = "" A9777 = "" A9778 = "" A9779 = "" A9780 = "" -A9781 = "" A9782 = "" A9783 = "" A9784 = "" A9785 = "" A9786 = "" A9787 = "" A9788 = "" A9789 = "" A9790 = "" -A9791 = "" A9792 = "" A9793 = "" A9794 = "" A9795 = "" A9796 = "" A9797 = "" A9798 = "" A9799 = "" A9800 = "" -A9801 = "" A9802 = "" A9803 = "" A9804 = "" A9805 = "" A9806 = "" A9807 = "" A9808 = "" A9809 = "" A9810 = "" -A9811 = "" A9812 = "" A9813 = "" A9814 = "" A9815 = "" A9816 = "" A9817 = "" A9818 = "" A9819 = "" A9820 = "" -A9821 = "" A9822 = "" A9823 = "" A9824 = "" A9825 = "" A9826 = "" A9827 = "" A9828 = "" A9829 = "" A9830 = "" -A9831 = "" A9832 = "" A9833 = "" A9834 = "" A9835 = "" A9836 = "" A9837 = "" A9838 = "" A9839 = "" A9840 = "" -A9841 = "" A9842 = "" A9843 = "" A9844 = "" A9845 = "" A9846 = "" A9847 = "" A9848 = "" A9849 = "" A9850 = "" -A9851 = "" A9852 = "" A9853 = "" A9854 = "" A9855 = "" A9856 = "" A9857 = "" A9858 = "" A9859 = "" A9860 = "" -A9861 = "" A9862 = "" A9863 = "" A9864 = "" A9865 = "" A9866 = "" A9867 = "" A9868 = "" A9869 = "" A9870 = "" -A9871 = "" A9872 = "" A9873 = "" A9874 = "" A9875 = "" A9876 = "" A9877 = "" A9878 = "" A9879 = "" A9880 = "" -A9881 = "" A9882 = "" A9883 = "" A9884 = "" A9885 = "" A9886 = "" A9887 = "" A9888 = "" A9889 = "" A9890 = "" -A9891 = "" A9892 = "" A9893 = "" A9894 = "" A9895 = "" A9896 = "" A9897 = "" A9898 = "" A9899 = "" A9900 = "" -A9901 = "" A9902 = "" A9903 = "" A9904 = "" A9905 = "" A9906 = "" A9907 = "" A9908 = "" A9909 = "" A9910 = "" -A9911 = "" A9912 = "" A9913 = "" A9914 = "" A9915 = "" A9916 = "" A9917 = "" A9918 = "" A9919 = "" A9920 = "" -A9921 = "" A9922 = "" A9923 = "" A9924 = "" A9925 = "" A9926 = "" A9927 = "" A9928 = "" A9929 = "" A9930 = "" -A9931 = "" A9932 = "" A9933 = "" A9934 = "" A9935 = "" A9936 = "" A9937 = "" A9938 = "" A9939 = "" A9940 = "" -A9941 = "" A9942 = "" A9943 = "" A9944 = "" A9945 = "" A9946 = "" A9947 = "" A9948 = "" A9949 = "" A9950 = "" -A9951 = "" A9952 = "" A9953 = "" A9954 = "" A9955 = "" A9956 = "" A9957 = "" A9958 = "" A9959 = "" A9960 = "" -A9961 = "" A9962 = "" A9963 = "" A9964 = "" A9965 = "" A9966 = "" A9967 = "" A9968 = "" A9969 = "" A9970 = "" -A9971 = "" A9972 = "" A9973 = "" A9974 = "" A9975 = "" A9976 = "" A9977 = "" A9978 = "" A9979 = "" A9980 = "" -A9981 = "" A9982 = "" A9983 = "" A9984 = "" A9985 = "" A9986 = "" A9987 = "" A9988 = "" A9989 = "" A9990 = "" -A9991 = "" A9992 = "" A9993 = "" A9994 = "" A9995 = "" A9996 = "" A9997 = "" A9998 = "" A9999 = "" A10000 = "" -A10001 = "" A10002 = "" A10003 = "" A10004 = "" A10005 = "" A10006 = "" A10007 = "" A10008 = "" A10009 = "" A10010 = "" -A10011 = "" A10012 = "" A10013 = "" A10014 = "" A10015 = "" A10016 = "" A10017 = "" A10018 = "" A10019 = "" A10020 = "" -A10021 = "" A10022 = "" A10023 = "" A10024 = "" A10025 = "" A10026 = "" A10027 = "" A10028 = "" A10029 = "" A10030 = "" -A10031 = "" A10032 = "" A10033 = "" A10034 = "" A10035 = "" A10036 = "" A10037 = "" A10038 = "" A10039 = "" A10040 = "" -A10041 = "" A10042 = "" A10043 = "" A10044 = "" A10045 = "" A10046 = "" A10047 = "" A10048 = "" A10049 = "" A10050 = "" -A10051 = "" A10052 = "" A10053 = "" A10054 = "" A10055 = "" A10056 = "" A10057 = "" A10058 = "" A10059 = "" A10060 = "" -A10061 = "" A10062 = "" A10063 = "" A10064 = "" A10065 = "" A10066 = "" A10067 = "" A10068 = "" A10069 = "" A10070 = "" -A10071 = "" A10072 = "" A10073 = "" A10074 = "" A10075 = "" A10076 = "" A10077 = "" A10078 = "" A10079 = "" A10080 = "" -A10081 = "" A10082 = "" A10083 = "" A10084 = "" A10085 = "" A10086 = "" A10087 = "" A10088 = "" A10089 = "" A10090 = "" -A10091 = "" A10092 = "" A10093 = "" A10094 = "" A10095 = "" A10096 = "" A10097 = "" A10098 = "" A10099 = "" A10100 = "" -A10101 = "" A10102 = "" A10103 = "" A10104 = "" A10105 = "" A10106 = "" A10107 = "" A10108 = "" A10109 = "" A10110 = "" -A10111 = "" A10112 = "" A10113 = "" A10114 = "" A10115 = "" A10116 = "" A10117 = "" A10118 = "" A10119 = "" A10120 = "" -A10121 = "" A10122 = "" A10123 = "" A10124 = "" A10125 = "" A10126 = "" A10127 = "" A10128 = "" A10129 = "" A10130 = "" -A10131 = "" A10132 = "" A10133 = "" A10134 = "" A10135 = "" A10136 = "" A10137 = "" A10138 = "" A10139 = "" A10140 = "" -A10141 = "" A10142 = "" A10143 = "" A10144 = "" A10145 = "" A10146 = "" A10147 = "" A10148 = "" A10149 = "" A10150 = "" -A10151 = "" A10152 = "" A10153 = "" A10154 = "" A10155 = "" A10156 = "" A10157 = "" A10158 = "" A10159 = "" A10160 = "" -A10161 = "" A10162 = "" A10163 = "" A10164 = "" A10165 = "" A10166 = "" A10167 = "" A10168 = "" A10169 = "" A10170 = "" -A10171 = "" A10172 = "" A10173 = "" A10174 = "" A10175 = "" A10176 = "" A10177 = "" A10178 = "" A10179 = "" A10180 = "" -A10181 = "" A10182 = "" A10183 = "" A10184 = "" A10185 = "" A10186 = "" A10187 = "" A10188 = "" A10189 = "" A10190 = "" -A10191 = "" A10192 = "" A10193 = "" A10194 = "" A10195 = "" A10196 = "" A10197 = "" A10198 = "" A10199 = "" A10200 = "" -A10201 = "" A10202 = "" A10203 = "" A10204 = "" A10205 = "" A10206 = "" A10207 = "" A10208 = "" A10209 = "" A10210 = "" -A10211 = "" A10212 = "" A10213 = "" A10214 = "" A10215 = "" A10216 = "" A10217 = "" A10218 = "" A10219 = "" A10220 = "" -A10221 = "" A10222 = "" A10223 = "" A10224 = "" A10225 = "" A10226 = "" A10227 = "" A10228 = "" A10229 = "" A10230 = "" -A10231 = "" A10232 = "" A10233 = "" A10234 = "" A10235 = "" A10236 = "" A10237 = "" A10238 = "" A10239 = "" A10240 = "" -A10241 = "" A10242 = "" A10243 = "" A10244 = "" A10245 = "" A10246 = "" A10247 = "" A10248 = "" A10249 = "" A10250 = "" -A10251 = "" A10252 = "" A10253 = "" A10254 = "" A10255 = "" A10256 = "" A10257 = "" A10258 = "" A10259 = "" A10260 = "" -A10261 = "" A10262 = "" A10263 = "" A10264 = "" A10265 = "" A10266 = "" A10267 = "" A10268 = "" A10269 = "" A10270 = "" -A10271 = "" A10272 = "" A10273 = "" A10274 = "" A10275 = "" A10276 = "" A10277 = "" A10278 = "" A10279 = "" A10280 = "" -A10281 = "" A10282 = "" A10283 = "" A10284 = "" A10285 = "" A10286 = "" A10287 = "" A10288 = "" A10289 = "" A10290 = "" -A10291 = "" A10292 = "" A10293 = "" A10294 = "" A10295 = "" A10296 = "" A10297 = "" A10298 = "" A10299 = "" A10300 = "" -A10301 = "" A10302 = "" A10303 = "" A10304 = "" A10305 = "" A10306 = "" A10307 = "" A10308 = "" A10309 = "" A10310 = "" -A10311 = "" A10312 = "" A10313 = "" A10314 = "" A10315 = "" A10316 = "" A10317 = "" A10318 = "" A10319 = "" A10320 = "" -A10321 = "" A10322 = "" A10323 = "" A10324 = "" A10325 = "" A10326 = "" A10327 = "" A10328 = "" A10329 = "" A10330 = "" -A10331 = "" A10332 = "" A10333 = "" A10334 = "" A10335 = "" A10336 = "" A10337 = "" A10338 = "" A10339 = "" A10340 = "" -A10341 = "" A10342 = "" A10343 = "" A10344 = "" A10345 = "" A10346 = "" A10347 = "" A10348 = "" A10349 = "" A10350 = "" -A10351 = "" A10352 = "" A10353 = "" A10354 = "" A10355 = "" A10356 = "" A10357 = "" A10358 = "" A10359 = "" A10360 = "" -A10361 = "" A10362 = "" A10363 = "" A10364 = "" A10365 = "" A10366 = "" A10367 = "" A10368 = "" A10369 = "" A10370 = "" -A10371 = "" A10372 = "" A10373 = "" A10374 = "" A10375 = "" A10376 = "" A10377 = "" A10378 = "" A10379 = "" A10380 = "" -A10381 = "" A10382 = "" A10383 = "" A10384 = "" A10385 = "" A10386 = "" A10387 = "" A10388 = "" A10389 = "" A10390 = "" -A10391 = "" A10392 = "" A10393 = "" A10394 = "" A10395 = "" A10396 = "" A10397 = "" A10398 = "" A10399 = "" A10400 = "" -A10401 = "" A10402 = "" A10403 = "" A10404 = "" A10405 = "" A10406 = "" A10407 = "" A10408 = "" A10409 = "" A10410 = "" -A10411 = "" A10412 = "" A10413 = "" A10414 = "" A10415 = "" A10416 = "" A10417 = "" A10418 = "" A10419 = "" A10420 = "" -A10421 = "" A10422 = "" A10423 = "" A10424 = "" A10425 = "" A10426 = "" A10427 = "" A10428 = "" A10429 = "" A10430 = "" -A10431 = "" A10432 = "" A10433 = "" A10434 = "" A10435 = "" A10436 = "" A10437 = "" A10438 = "" A10439 = "" A10440 = "" -A10441 = "" A10442 = "" A10443 = "" A10444 = "" A10445 = "" A10446 = "" A10447 = "" A10448 = "" A10449 = "" A10450 = "" -A10451 = "" A10452 = "" A10453 = "" A10454 = "" A10455 = "" A10456 = "" A10457 = "" A10458 = "" A10459 = "" A10460 = "" -A10461 = "" A10462 = "" A10463 = "" A10464 = "" A10465 = "" A10466 = "" A10467 = "" A10468 = "" A10469 = "" A10470 = "" -A10471 = "" A10472 = "" A10473 = "" A10474 = "" A10475 = "" A10476 = "" A10477 = "" A10478 = "" A10479 = "" A10480 = "" -A10481 = "" A10482 = "" A10483 = "" A10484 = "" A10485 = "" A10486 = "" A10487 = "" A10488 = "" A10489 = "" A10490 = "" -A10491 = "" A10492 = "" A10493 = "" A10494 = "" A10495 = "" A10496 = "" A10497 = "" A10498 = "" A10499 = "" A10500 = "" -A10501 = "" A10502 = "" A10503 = "" A10504 = "" A10505 = "" A10506 = "" A10507 = "" A10508 = "" A10509 = "" A10510 = "" -A10511 = "" A10512 = "" A10513 = "" A10514 = "" A10515 = "" A10516 = "" A10517 = "" A10518 = "" A10519 = "" A10520 = "" -A10521 = "" A10522 = "" A10523 = "" A10524 = "" A10525 = "" A10526 = "" A10527 = "" A10528 = "" A10529 = "" A10530 = "" -A10531 = "" A10532 = "" A10533 = "" A10534 = "" A10535 = "" A10536 = "" A10537 = "" A10538 = "" A10539 = "" A10540 = "" -A10541 = "" A10542 = "" A10543 = "" A10544 = "" A10545 = "" A10546 = "" A10547 = "" A10548 = "" A10549 = "" A10550 = "" -A10551 = "" A10552 = "" A10553 = "" A10554 = "" A10555 = "" A10556 = "" A10557 = "" A10558 = "" A10559 = "" A10560 = "" -A10561 = "" A10562 = "" A10563 = "" A10564 = "" A10565 = "" A10566 = "" A10567 = "" A10568 = "" A10569 = "" A10570 = "" -A10571 = "" A10572 = "" A10573 = "" A10574 = "" A10575 = "" A10576 = "" A10577 = "" A10578 = "" A10579 = "" A10580 = "" -A10581 = "" A10582 = "" A10583 = "" A10584 = "" A10585 = "" A10586 = "" A10587 = "" A10588 = "" A10589 = "" A10590 = "" -A10591 = "" A10592 = "" A10593 = "" A10594 = "" A10595 = "" A10596 = "" A10597 = "" A10598 = "" A10599 = "" A10600 = "" -A10601 = "" A10602 = "" A10603 = "" A10604 = "" A10605 = "" A10606 = "" A10607 = "" A10608 = "" A10609 = "" A10610 = "" -A10611 = "" A10612 = "" A10613 = "" A10614 = "" A10615 = "" A10616 = "" A10617 = "" A10618 = "" A10619 = "" A10620 = "" -A10621 = "" A10622 = "" A10623 = "" A10624 = "" A10625 = "" A10626 = "" A10627 = "" A10628 = "" A10629 = "" A10630 = "" -A10631 = "" A10632 = "" A10633 = "" A10634 = "" A10635 = "" A10636 = "" A10637 = "" A10638 = "" A10639 = "" A10640 = "" -A10641 = "" A10642 = "" A10643 = "" A10644 = "" A10645 = "" A10646 = "" A10647 = "" A10648 = "" A10649 = "" A10650 = "" -A10651 = "" A10652 = "" A10653 = "" A10654 = "" A10655 = "" A10656 = "" A10657 = "" A10658 = "" A10659 = "" A10660 = "" -A10661 = "" A10662 = "" A10663 = "" A10664 = "" A10665 = "" A10666 = "" A10667 = "" A10668 = "" A10669 = "" A10670 = "" -A10671 = "" A10672 = "" A10673 = "" A10674 = "" A10675 = "" A10676 = "" A10677 = "" A10678 = "" A10679 = "" A10680 = "" -A10681 = "" A10682 = "" A10683 = "" A10684 = "" A10685 = "" A10686 = "" A10687 = "" A10688 = "" A10689 = "" A10690 = "" -A10691 = "" A10692 = "" A10693 = "" A10694 = "" A10695 = "" A10696 = "" A10697 = "" A10698 = "" A10699 = "" A10700 = "" -A10701 = "" A10702 = "" A10703 = "" A10704 = "" A10705 = "" A10706 = "" A10707 = "" A10708 = "" A10709 = "" A10710 = "" -A10711 = "" A10712 = "" A10713 = "" A10714 = "" A10715 = "" A10716 = "" A10717 = "" A10718 = "" A10719 = "" A10720 = "" -A10721 = "" A10722 = "" A10723 = "" A10724 = "" A10725 = "" A10726 = "" A10727 = "" A10728 = "" A10729 = "" A10730 = "" -A10731 = "" A10732 = "" A10733 = "" A10734 = "" A10735 = "" A10736 = "" A10737 = "" A10738 = "" A10739 = "" A10740 = "" -A10741 = "" A10742 = "" A10743 = "" A10744 = "" A10745 = "" A10746 = "" A10747 = "" A10748 = "" A10749 = "" A10750 = "" -A10751 = "" A10752 = "" A10753 = "" A10754 = "" A10755 = "" A10756 = "" A10757 = "" A10758 = "" A10759 = "" A10760 = "" -A10761 = "" A10762 = "" A10763 = "" A10764 = "" A10765 = "" A10766 = "" A10767 = "" A10768 = "" A10769 = "" A10770 = "" -A10771 = "" A10772 = "" A10773 = "" A10774 = "" A10775 = "" A10776 = "" A10777 = "" A10778 = "" A10779 = "" A10780 = "" -A10781 = "" A10782 = "" A10783 = "" A10784 = "" A10785 = "" A10786 = "" A10787 = "" A10788 = "" A10789 = "" A10790 = "" -A10791 = "" A10792 = "" A10793 = "" A10794 = "" A10795 = "" A10796 = "" A10797 = "" A10798 = "" A10799 = "" A10800 = "" -A10801 = "" A10802 = "" A10803 = "" A10804 = "" A10805 = "" A10806 = "" A10807 = "" A10808 = "" A10809 = "" A10810 = "" -A10811 = "" A10812 = "" A10813 = "" A10814 = "" A10815 = "" A10816 = "" A10817 = "" A10818 = "" A10819 = "" A10820 = "" -A10821 = "" A10822 = "" A10823 = "" A10824 = "" A10825 = "" A10826 = "" A10827 = "" A10828 = "" A10829 = "" A10830 = "" -A10831 = "" A10832 = "" A10833 = "" A10834 = "" A10835 = "" A10836 = "" A10837 = "" A10838 = "" A10839 = "" A10840 = "" -A10841 = "" A10842 = "" A10843 = "" A10844 = "" A10845 = "" A10846 = "" A10847 = "" A10848 = "" A10849 = "" A10850 = "" -A10851 = "" A10852 = "" A10853 = "" A10854 = "" A10855 = "" A10856 = "" A10857 = "" A10858 = "" A10859 = "" A10860 = "" -A10861 = "" A10862 = "" A10863 = "" A10864 = "" A10865 = "" A10866 = "" A10867 = "" A10868 = "" A10869 = "" A10870 = "" -A10871 = "" A10872 = "" A10873 = "" A10874 = "" A10875 = "" A10876 = "" A10877 = "" A10878 = "" A10879 = "" A10880 = "" -A10881 = "" A10882 = "" A10883 = "" A10884 = "" A10885 = "" A10886 = "" A10887 = "" A10888 = "" A10889 = "" A10890 = "" -A10891 = "" A10892 = "" A10893 = "" A10894 = "" A10895 = "" A10896 = "" A10897 = "" A10898 = "" A10899 = "" A10900 = "" -A10901 = "" A10902 = "" A10903 = "" A10904 = "" A10905 = "" A10906 = "" A10907 = "" A10908 = "" A10909 = "" A10910 = "" -A10911 = "" A10912 = "" A10913 = "" A10914 = "" A10915 = "" A10916 = "" A10917 = "" A10918 = "" A10919 = "" A10920 = "" -A10921 = "" A10922 = "" A10923 = "" A10924 = "" A10925 = "" A10926 = "" A10927 = "" A10928 = "" A10929 = "" A10930 = "" -A10931 = "" A10932 = "" A10933 = "" A10934 = "" A10935 = "" A10936 = "" A10937 = "" A10938 = "" A10939 = "" A10940 = "" -A10941 = "" A10942 = "" A10943 = "" A10944 = "" A10945 = "" A10946 = "" A10947 = "" A10948 = "" A10949 = "" A10950 = "" -A10951 = "" A10952 = "" A10953 = "" A10954 = "" A10955 = "" A10956 = "" A10957 = "" A10958 = "" A10959 = "" A10960 = "" -A10961 = "" A10962 = "" A10963 = "" A10964 = "" A10965 = "" A10966 = "" A10967 = "" A10968 = "" A10969 = "" A10970 = "" -A10971 = "" A10972 = "" A10973 = "" A10974 = "" A10975 = "" A10976 = "" A10977 = "" A10978 = "" A10979 = "" A10980 = "" -A10981 = "" A10982 = "" A10983 = "" A10984 = "" A10985 = "" A10986 = "" A10987 = "" A10988 = "" A10989 = "" A10990 = "" -A10991 = "" A10992 = "" A10993 = "" A10994 = "" A10995 = "" A10996 = "" A10997 = "" A10998 = "" A10999 = "" A11000 = "" -A11001 = "" A11002 = "" A11003 = "" A11004 = "" A11005 = "" A11006 = "" A11007 = "" A11008 = "" A11009 = "" A11010 = "" -A11011 = "" A11012 = "" A11013 = "" A11014 = "" A11015 = "" A11016 = "" A11017 = "" A11018 = "" A11019 = "" A11020 = "" -A11021 = "" A11022 = "" A11023 = "" A11024 = "" A11025 = "" A11026 = "" A11027 = "" A11028 = "" A11029 = "" A11030 = "" -A11031 = "" A11032 = "" A11033 = "" A11034 = "" A11035 = "" A11036 = "" A11037 = "" A11038 = "" A11039 = "" A11040 = "" -A11041 = "" A11042 = "" A11043 = "" A11044 = "" A11045 = "" A11046 = "" A11047 = "" A11048 = "" A11049 = "" A11050 = "" -A11051 = "" A11052 = "" A11053 = "" A11054 = "" A11055 = "" A11056 = "" A11057 = "" A11058 = "" A11059 = "" A11060 = "" -A11061 = "" A11062 = "" A11063 = "" A11064 = "" A11065 = "" A11066 = "" A11067 = "" A11068 = "" A11069 = "" A11070 = "" -A11071 = "" A11072 = "" A11073 = "" A11074 = "" A11075 = "" A11076 = "" A11077 = "" A11078 = "" A11079 = "" A11080 = "" -A11081 = "" A11082 = "" A11083 = "" A11084 = "" A11085 = "" A11086 = "" A11087 = "" A11088 = "" A11089 = "" A11090 = "" -A11091 = "" A11092 = "" A11093 = "" A11094 = "" A11095 = "" A11096 = "" A11097 = "" A11098 = "" A11099 = "" A11100 = "" -A11101 = "" A11102 = "" A11103 = "" A11104 = "" A11105 = "" A11106 = "" A11107 = "" A11108 = "" A11109 = "" A11110 = "" -A11111 = "" A11112 = "" A11113 = "" A11114 = "" A11115 = "" A11116 = "" A11117 = "" A11118 = "" A11119 = "" A11120 = "" -A11121 = "" A11122 = "" A11123 = "" A11124 = "" A11125 = "" A11126 = "" A11127 = "" A11128 = "" A11129 = "" A11130 = "" -A11131 = "" A11132 = "" A11133 = "" A11134 = "" A11135 = "" A11136 = "" A11137 = "" A11138 = "" A11139 = "" A11140 = "" -A11141 = "" A11142 = "" A11143 = "" A11144 = "" A11145 = "" A11146 = "" A11147 = "" A11148 = "" A11149 = "" A11150 = "" -A11151 = "" A11152 = "" A11153 = "" A11154 = "" A11155 = "" A11156 = "" A11157 = "" A11158 = "" A11159 = "" A11160 = "" -A11161 = "" A11162 = "" A11163 = "" A11164 = "" A11165 = "" A11166 = "" A11167 = "" A11168 = "" A11169 = "" A11170 = "" -A11171 = "" A11172 = "" A11173 = "" A11174 = "" A11175 = "" A11176 = "" A11177 = "" A11178 = "" A11179 = "" A11180 = "" -A11181 = "" A11182 = "" A11183 = "" A11184 = "" A11185 = "" A11186 = "" A11187 = "" A11188 = "" A11189 = "" A11190 = "" -A11191 = "" A11192 = "" A11193 = "" A11194 = "" A11195 = "" A11196 = "" A11197 = "" A11198 = "" A11199 = "" A11200 = "" -A11201 = "" A11202 = "" A11203 = "" A11204 = "" A11205 = "" A11206 = "" A11207 = "" A11208 = "" A11209 = "" A11210 = "" -A11211 = "" A11212 = "" A11213 = "" A11214 = "" A11215 = "" A11216 = "" A11217 = "" A11218 = "" A11219 = "" A11220 = "" -A11221 = "" A11222 = "" A11223 = "" A11224 = "" A11225 = "" A11226 = "" A11227 = "" A11228 = "" A11229 = "" A11230 = "" -A11231 = "" A11232 = "" A11233 = "" A11234 = "" A11235 = "" A11236 = "" A11237 = "" A11238 = "" A11239 = "" A11240 = "" -A11241 = "" A11242 = "" A11243 = "" A11244 = "" A11245 = "" A11246 = "" A11247 = "" A11248 = "" A11249 = "" A11250 = "" -A11251 = "" A11252 = "" A11253 = "" A11254 = "" A11255 = "" A11256 = "" A11257 = "" A11258 = "" A11259 = "" A11260 = "" -A11261 = "" A11262 = "" A11263 = "" A11264 = "" A11265 = "" A11266 = "" A11267 = "" A11268 = "" A11269 = "" A11270 = "" -A11271 = "" A11272 = "" A11273 = "" A11274 = "" A11275 = "" A11276 = "" A11277 = "" A11278 = "" A11279 = "" A11280 = "" -A11281 = "" A11282 = "" A11283 = "" A11284 = "" A11285 = "" A11286 = "" A11287 = "" A11288 = "" A11289 = "" A11290 = "" -A11291 = "" A11292 = "" A11293 = "" A11294 = "" A11295 = "" A11296 = "" A11297 = "" A11298 = "" A11299 = "" A11300 = "" -A11301 = "" A11302 = "" A11303 = "" A11304 = "" A11305 = "" A11306 = "" A11307 = "" A11308 = "" A11309 = "" A11310 = "" -A11311 = "" A11312 = "" A11313 = "" A11314 = "" A11315 = "" A11316 = "" A11317 = "" A11318 = "" A11319 = "" A11320 = "" -A11321 = "" A11322 = "" A11323 = "" A11324 = "" A11325 = "" A11326 = "" A11327 = "" A11328 = "" A11329 = "" A11330 = "" -A11331 = "" A11332 = "" A11333 = "" A11334 = "" A11335 = "" A11336 = "" A11337 = "" A11338 = "" A11339 = "" A11340 = "" -A11341 = "" A11342 = "" A11343 = "" A11344 = "" A11345 = "" A11346 = "" A11347 = "" A11348 = "" A11349 = "" A11350 = "" -A11351 = "" A11352 = "" A11353 = "" A11354 = "" A11355 = "" A11356 = "" A11357 = "" A11358 = "" A11359 = "" A11360 = "" -A11361 = "" A11362 = "" A11363 = "" A11364 = "" A11365 = "" A11366 = "" A11367 = "" A11368 = "" A11369 = "" A11370 = "" -A11371 = "" A11372 = "" A11373 = "" A11374 = "" A11375 = "" A11376 = "" A11377 = "" A11378 = "" A11379 = "" A11380 = "" -A11381 = "" A11382 = "" A11383 = "" A11384 = "" A11385 = "" A11386 = "" A11387 = "" A11388 = "" A11389 = "" A11390 = "" -A11391 = "" A11392 = "" A11393 = "" A11394 = "" A11395 = "" A11396 = "" A11397 = "" A11398 = "" A11399 = "" A11400 = "" -A11401 = "" A11402 = "" A11403 = "" A11404 = "" A11405 = "" A11406 = "" A11407 = "" A11408 = "" A11409 = "" A11410 = "" -A11411 = "" A11412 = "" A11413 = "" A11414 = "" A11415 = "" A11416 = "" A11417 = "" A11418 = "" A11419 = "" A11420 = "" -A11421 = "" A11422 = "" A11423 = "" A11424 = "" A11425 = "" A11426 = "" A11427 = "" A11428 = "" A11429 = "" A11430 = "" -A11431 = "" A11432 = "" A11433 = "" A11434 = "" A11435 = "" A11436 = "" A11437 = "" A11438 = "" A11439 = "" A11440 = "" -A11441 = "" A11442 = "" A11443 = "" A11444 = "" A11445 = "" A11446 = "" A11447 = "" A11448 = "" A11449 = "" A11450 = "" -A11451 = "" A11452 = "" A11453 = "" A11454 = "" A11455 = "" A11456 = "" A11457 = "" A11458 = "" A11459 = "" A11460 = "" -A11461 = "" A11462 = "" A11463 = "" A11464 = "" A11465 = "" A11466 = "" A11467 = "" A11468 = "" A11469 = "" A11470 = "" -A11471 = "" A11472 = "" A11473 = "" A11474 = "" A11475 = "" A11476 = "" A11477 = "" A11478 = "" A11479 = "" A11480 = "" -A11481 = "" A11482 = "" A11483 = "" A11484 = "" A11485 = "" A11486 = "" A11487 = "" A11488 = "" A11489 = "" A11490 = "" -A11491 = "" A11492 = "" A11493 = "" A11494 = "" A11495 = "" A11496 = "" A11497 = "" A11498 = "" A11499 = "" A11500 = "" -A11501 = "" A11502 = "" A11503 = "" A11504 = "" A11505 = "" A11506 = "" A11507 = "" A11508 = "" A11509 = "" A11510 = "" -A11511 = "" A11512 = "" A11513 = "" A11514 = "" A11515 = "" A11516 = "" A11517 = "" A11518 = "" A11519 = "" A11520 = "" -A11521 = "" A11522 = "" A11523 = "" A11524 = "" A11525 = "" A11526 = "" A11527 = "" A11528 = "" A11529 = "" A11530 = "" -A11531 = "" A11532 = "" A11533 = "" A11534 = "" A11535 = "" A11536 = "" A11537 = "" A11538 = "" A11539 = "" A11540 = "" -A11541 = "" A11542 = "" A11543 = "" A11544 = "" A11545 = "" A11546 = "" A11547 = "" A11548 = "" A11549 = "" A11550 = "" -A11551 = "" A11552 = "" A11553 = "" A11554 = "" A11555 = "" A11556 = "" A11557 = "" A11558 = "" A11559 = "" A11560 = "" -A11561 = "" A11562 = "" A11563 = "" A11564 = "" A11565 = "" A11566 = "" A11567 = "" A11568 = "" A11569 = "" A11570 = "" -A11571 = "" A11572 = "" A11573 = "" A11574 = "" A11575 = "" A11576 = "" A11577 = "" A11578 = "" A11579 = "" A11580 = "" -A11581 = "" A11582 = "" A11583 = "" A11584 = "" A11585 = "" A11586 = "" A11587 = "" A11588 = "" A11589 = "" A11590 = "" -A11591 = "" A11592 = "" A11593 = "" A11594 = "" A11595 = "" A11596 = "" A11597 = "" A11598 = "" A11599 = "" A11600 = "" -A11601 = "" A11602 = "" A11603 = "" A11604 = "" A11605 = "" A11606 = "" A11607 = "" A11608 = "" A11609 = "" A11610 = "" -A11611 = "" A11612 = "" A11613 = "" A11614 = "" A11615 = "" A11616 = "" A11617 = "" A11618 = "" A11619 = "" A11620 = "" -A11621 = "" A11622 = "" A11623 = "" A11624 = "" A11625 = "" A11626 = "" A11627 = "" A11628 = "" A11629 = "" A11630 = "" -A11631 = "" A11632 = "" A11633 = "" A11634 = "" A11635 = "" A11636 = "" A11637 = "" A11638 = "" A11639 = "" A11640 = "" -A11641 = "" A11642 = "" A11643 = "" A11644 = "" A11645 = "" A11646 = "" A11647 = "" A11648 = "" A11649 = "" A11650 = "" -A11651 = "" A11652 = "" A11653 = "" A11654 = "" A11655 = "" A11656 = "" A11657 = "" A11658 = "" A11659 = "" A11660 = "" -A11661 = "" A11662 = "" A11663 = "" A11664 = "" A11665 = "" A11666 = "" A11667 = "" A11668 = "" A11669 = "" A11670 = "" -A11671 = "" A11672 = "" A11673 = "" A11674 = "" A11675 = "" A11676 = "" A11677 = "" A11678 = "" A11679 = "" A11680 = "" -A11681 = "" A11682 = "" A11683 = "" A11684 = "" A11685 = "" A11686 = "" A11687 = "" A11688 = "" A11689 = "" A11690 = "" -A11691 = "" A11692 = "" A11693 = "" A11694 = "" A11695 = "" A11696 = "" A11697 = "" A11698 = "" A11699 = "" A11700 = "" -A11701 = "" A11702 = "" A11703 = "" A11704 = "" A11705 = "" A11706 = "" A11707 = "" A11708 = "" A11709 = "" A11710 = "" -A11711 = "" A11712 = "" A11713 = "" A11714 = "" A11715 = "" A11716 = "" A11717 = "" A11718 = "" A11719 = "" A11720 = "" -A11721 = "" A11722 = "" A11723 = "" A11724 = "" A11725 = "" A11726 = "" A11727 = "" A11728 = "" A11729 = "" A11730 = "" -A11731 = "" A11732 = "" A11733 = "" A11734 = "" A11735 = "" A11736 = "" A11737 = "" A11738 = "" A11739 = "" A11740 = "" -A11741 = "" A11742 = "" A11743 = "" A11744 = "" A11745 = "" A11746 = "" A11747 = "" A11748 = "" A11749 = "" A11750 = "" -A11751 = "" A11752 = "" A11753 = "" A11754 = "" A11755 = "" A11756 = "" A11757 = "" A11758 = "" A11759 = "" A11760 = "" -A11761 = "" A11762 = "" A11763 = "" A11764 = "" A11765 = "" A11766 = "" A11767 = "" A11768 = "" A11769 = "" A11770 = "" -A11771 = "" A11772 = "" A11773 = "" A11774 = "" A11775 = "" A11776 = "" A11777 = "" A11778 = "" A11779 = "" A11780 = "" -A11781 = "" A11782 = "" A11783 = "" A11784 = "" A11785 = "" A11786 = "" A11787 = "" A11788 = "" A11789 = "" A11790 = "" -A11791 = "" A11792 = "" A11793 = "" A11794 = "" A11795 = "" A11796 = "" A11797 = "" A11798 = "" A11799 = "" A11800 = "" -A11801 = "" A11802 = "" A11803 = "" A11804 = "" A11805 = "" A11806 = "" A11807 = "" A11808 = "" A11809 = "" A11810 = "" -A11811 = "" A11812 = "" A11813 = "" A11814 = "" A11815 = "" A11816 = "" A11817 = "" A11818 = "" A11819 = "" A11820 = "" -A11821 = "" A11822 = "" A11823 = "" A11824 = "" A11825 = "" A11826 = "" A11827 = "" A11828 = "" A11829 = "" A11830 = "" -A11831 = "" A11832 = "" A11833 = "" A11834 = "" A11835 = "" A11836 = "" A11837 = "" A11838 = "" A11839 = "" A11840 = "" -A11841 = "" A11842 = "" A11843 = "" A11844 = "" A11845 = "" A11846 = "" A11847 = "" A11848 = "" A11849 = "" A11850 = "" -A11851 = "" A11852 = "" A11853 = "" A11854 = "" A11855 = "" A11856 = "" A11857 = "" A11858 = "" A11859 = "" A11860 = "" -A11861 = "" A11862 = "" A11863 = "" A11864 = "" A11865 = "" A11866 = "" A11867 = "" A11868 = "" A11869 = "" A11870 = "" -A11871 = "" A11872 = "" A11873 = "" A11874 = "" A11875 = "" A11876 = "" A11877 = "" A11878 = "" A11879 = "" A11880 = "" -A11881 = "" A11882 = "" A11883 = "" A11884 = "" A11885 = "" A11886 = "" A11887 = "" A11888 = "" A11889 = "" A11890 = "" -A11891 = "" A11892 = "" A11893 = "" A11894 = "" A11895 = "" A11896 = "" A11897 = "" A11898 = "" A11899 = "" A11900 = "" -A11901 = "" A11902 = "" A11903 = "" A11904 = "" A11905 = "" A11906 = "" A11907 = "" A11908 = "" A11909 = "" A11910 = "" -A11911 = "" A11912 = "" A11913 = "" A11914 = "" A11915 = "" A11916 = "" A11917 = "" A11918 = "" A11919 = "" A11920 = "" -A11921 = "" A11922 = "" A11923 = "" A11924 = "" A11925 = "" A11926 = "" A11927 = "" A11928 = "" A11929 = "" A11930 = "" -A11931 = "" A11932 = "" A11933 = "" A11934 = "" A11935 = "" A11936 = "" A11937 = "" A11938 = "" A11939 = "" A11940 = "" -A11941 = "" A11942 = "" A11943 = "" A11944 = "" A11945 = "" A11946 = "" A11947 = "" A11948 = "" A11949 = "" A11950 = "" -A11951 = "" A11952 = "" A11953 = "" A11954 = "" A11955 = "" A11956 = "" A11957 = "" A11958 = "" A11959 = "" A11960 = "" -A11961 = "" A11962 = "" A11963 = "" A11964 = "" A11965 = "" A11966 = "" A11967 = "" A11968 = "" A11969 = "" A11970 = "" -A11971 = "" A11972 = "" A11973 = "" A11974 = "" A11975 = "" A11976 = "" A11977 = "" A11978 = "" A11979 = "" A11980 = "" -A11981 = "" A11982 = "" A11983 = "" A11984 = "" A11985 = "" A11986 = "" A11987 = "" A11988 = "" A11989 = "" A11990 = "" -A11991 = "" A11992 = "" A11993 = "" A11994 = "" A11995 = "" A11996 = "" A11997 = "" A11998 = "" A11999 = "" A12000 = "" -A12001 = "" A12002 = "" A12003 = "" A12004 = "" A12005 = "" A12006 = "" A12007 = "" A12008 = "" A12009 = "" A12010 = "" -A12011 = "" A12012 = "" A12013 = "" A12014 = "" A12015 = "" A12016 = "" A12017 = "" A12018 = "" A12019 = "" A12020 = "" -A12021 = "" A12022 = "" A12023 = "" A12024 = "" A12025 = "" A12026 = "" A12027 = "" A12028 = "" A12029 = "" A12030 = "" -A12031 = "" A12032 = "" A12033 = "" A12034 = "" A12035 = "" A12036 = "" A12037 = "" A12038 = "" A12039 = "" A12040 = "" -A12041 = "" A12042 = "" A12043 = "" A12044 = "" A12045 = "" A12046 = "" A12047 = "" A12048 = "" A12049 = "" A12050 = "" -A12051 = "" A12052 = "" A12053 = "" A12054 = "" A12055 = "" A12056 = "" A12057 = "" A12058 = "" A12059 = "" A12060 = "" -A12061 = "" A12062 = "" A12063 = "" A12064 = "" A12065 = "" A12066 = "" A12067 = "" A12068 = "" A12069 = "" A12070 = "" -A12071 = "" A12072 = "" A12073 = "" A12074 = "" A12075 = "" A12076 = "" A12077 = "" A12078 = "" A12079 = "" A12080 = "" -A12081 = "" A12082 = "" A12083 = "" A12084 = "" A12085 = "" A12086 = "" A12087 = "" A12088 = "" A12089 = "" A12090 = "" -A12091 = "" A12092 = "" A12093 = "" A12094 = "" A12095 = "" A12096 = "" A12097 = "" A12098 = "" A12099 = "" A12100 = "" -A12101 = "" A12102 = "" A12103 = "" A12104 = "" A12105 = "" A12106 = "" A12107 = "" A12108 = "" A12109 = "" A12110 = "" -A12111 = "" A12112 = "" A12113 = "" A12114 = "" A12115 = "" A12116 = "" A12117 = "" A12118 = "" A12119 = "" A12120 = "" -A12121 = "" A12122 = "" A12123 = "" A12124 = "" A12125 = "" A12126 = "" A12127 = "" A12128 = "" A12129 = "" A12130 = "" -A12131 = "" A12132 = "" A12133 = "" A12134 = "" A12135 = "" A12136 = "" A12137 = "" A12138 = "" A12139 = "" A12140 = "" -A12141 = "" A12142 = "" A12143 = "" A12144 = "" A12145 = "" A12146 = "" A12147 = "" A12148 = "" A12149 = "" A12150 = "" -A12151 = "" A12152 = "" A12153 = "" A12154 = "" A12155 = "" A12156 = "" A12157 = "" A12158 = "" A12159 = "" A12160 = "" -A12161 = "" A12162 = "" A12163 = "" A12164 = "" A12165 = "" A12166 = "" A12167 = "" A12168 = "" A12169 = "" A12170 = "" -A12171 = "" A12172 = "" A12173 = "" A12174 = "" A12175 = "" A12176 = "" A12177 = "" A12178 = "" A12179 = "" A12180 = "" -A12181 = "" A12182 = "" A12183 = "" A12184 = "" A12185 = "" A12186 = "" A12187 = "" A12188 = "" A12189 = "" A12190 = "" -A12191 = "" A12192 = "" A12193 = "" A12194 = "" A12195 = "" A12196 = "" A12197 = "" A12198 = "" A12199 = "" A12200 = "" -A12201 = "" A12202 = "" A12203 = "" A12204 = "" A12205 = "" A12206 = "" A12207 = "" A12208 = "" A12209 = "" A12210 = "" -A12211 = "" A12212 = "" A12213 = "" A12214 = "" A12215 = "" A12216 = "" A12217 = "" A12218 = "" A12219 = "" A12220 = "" -A12221 = "" A12222 = "" A12223 = "" A12224 = "" A12225 = "" A12226 = "" A12227 = "" A12228 = "" A12229 = "" A12230 = "" -A12231 = "" A12232 = "" A12233 = "" A12234 = "" A12235 = "" A12236 = "" A12237 = "" A12238 = "" A12239 = "" A12240 = "" -A12241 = "" A12242 = "" A12243 = "" A12244 = "" A12245 = "" A12246 = "" A12247 = "" A12248 = "" A12249 = "" A12250 = "" -A12251 = "" A12252 = "" A12253 = "" A12254 = "" A12255 = "" A12256 = "" A12257 = "" A12258 = "" A12259 = "" A12260 = "" -A12261 = "" A12262 = "" A12263 = "" A12264 = "" A12265 = "" A12266 = "" A12267 = "" A12268 = "" A12269 = "" A12270 = "" -A12271 = "" A12272 = "" A12273 = "" A12274 = "" A12275 = "" A12276 = "" A12277 = "" A12278 = "" A12279 = "" A12280 = "" -A12281 = "" A12282 = "" A12283 = "" A12284 = "" A12285 = "" A12286 = "" A12287 = "" A12288 = "" A12289 = "" A12290 = "" -A12291 = "" A12292 = "" A12293 = "" A12294 = "" A12295 = "" A12296 = "" A12297 = "" A12298 = "" A12299 = "" A12300 = "" -A12301 = "" A12302 = "" A12303 = "" A12304 = "" A12305 = "" A12306 = "" A12307 = "" A12308 = "" A12309 = "" A12310 = "" -A12311 = "" A12312 = "" A12313 = "" A12314 = "" A12315 = "" A12316 = "" A12317 = "" A12318 = "" A12319 = "" A12320 = "" -A12321 = "" A12322 = "" A12323 = "" A12324 = "" A12325 = "" A12326 = "" A12327 = "" A12328 = "" A12329 = "" A12330 = "" -A12331 = "" A12332 = "" A12333 = "" A12334 = "" A12335 = "" A12336 = "" A12337 = "" A12338 = "" A12339 = "" A12340 = "" -A12341 = "" A12342 = "" A12343 = "" A12344 = "" A12345 = "" A12346 = "" A12347 = "" A12348 = "" A12349 = "" A12350 = "" -A12351 = "" A12352 = "" A12353 = "" A12354 = "" A12355 = "" A12356 = "" A12357 = "" A12358 = "" A12359 = "" A12360 = "" -A12361 = "" A12362 = "" A12363 = "" A12364 = "" A12365 = "" A12366 = "" A12367 = "" A12368 = "" A12369 = "" A12370 = "" -A12371 = "" A12372 = "" A12373 = "" A12374 = "" A12375 = "" A12376 = "" A12377 = "" A12378 = "" A12379 = "" A12380 = "" -A12381 = "" A12382 = "" A12383 = "" A12384 = "" A12385 = "" A12386 = "" A12387 = "" A12388 = "" A12389 = "" A12390 = "" -A12391 = "" A12392 = "" A12393 = "" A12394 = "" A12395 = "" A12396 = "" A12397 = "" A12398 = "" A12399 = "" A12400 = "" -A12401 = "" A12402 = "" A12403 = "" A12404 = "" A12405 = "" A12406 = "" A12407 = "" A12408 = "" A12409 = "" A12410 = "" -A12411 = "" A12412 = "" A12413 = "" A12414 = "" A12415 = "" A12416 = "" A12417 = "" A12418 = "" A12419 = "" A12420 = "" -A12421 = "" A12422 = "" A12423 = "" A12424 = "" A12425 = "" A12426 = "" A12427 = "" A12428 = "" A12429 = "" A12430 = "" -A12431 = "" A12432 = "" A12433 = "" A12434 = "" A12435 = "" A12436 = "" A12437 = "" A12438 = "" A12439 = "" A12440 = "" -A12441 = "" A12442 = "" A12443 = "" A12444 = "" A12445 = "" A12446 = "" A12447 = "" A12448 = "" A12449 = "" A12450 = "" -A12451 = "" A12452 = "" A12453 = "" A12454 = "" A12455 = "" A12456 = "" A12457 = "" A12458 = "" A12459 = "" A12460 = "" -A12461 = "" A12462 = "" A12463 = "" A12464 = "" A12465 = "" A12466 = "" A12467 = "" A12468 = "" A12469 = "" A12470 = "" -A12471 = "" A12472 = "" A12473 = "" A12474 = "" A12475 = "" A12476 = "" A12477 = "" A12478 = "" A12479 = "" A12480 = "" -A12481 = "" A12482 = "" A12483 = "" A12484 = "" A12485 = "" A12486 = "" A12487 = "" A12488 = "" A12489 = "" A12490 = "" -A12491 = "" A12492 = "" A12493 = "" A12494 = "" A12495 = "" A12496 = "" A12497 = "" A12498 = "" A12499 = "" A12500 = "" -A12501 = "" A12502 = "" A12503 = "" A12504 = "" A12505 = "" A12506 = "" A12507 = "" A12508 = "" A12509 = "" A12510 = "" -A12511 = "" A12512 = "" A12513 = "" A12514 = "" A12515 = "" A12516 = "" A12517 = "" A12518 = "" A12519 = "" A12520 = "" -A12521 = "" A12522 = "" A12523 = "" A12524 = "" A12525 = "" A12526 = "" A12527 = "" A12528 = "" A12529 = "" A12530 = "" -A12531 = "" A12532 = "" A12533 = "" A12534 = "" A12535 = "" A12536 = "" A12537 = "" A12538 = "" A12539 = "" A12540 = "" -A12541 = "" A12542 = "" A12543 = "" A12544 = "" A12545 = "" A12546 = "" A12547 = "" A12548 = "" A12549 = "" A12550 = "" -A12551 = "" A12552 = "" A12553 = "" A12554 = "" A12555 = "" A12556 = "" A12557 = "" A12558 = "" A12559 = "" A12560 = "" -A12561 = "" A12562 = "" A12563 = "" A12564 = "" A12565 = "" A12566 = "" A12567 = "" A12568 = "" A12569 = "" A12570 = "" -A12571 = "" A12572 = "" A12573 = "" A12574 = "" A12575 = "" A12576 = "" A12577 = "" A12578 = "" A12579 = "" A12580 = "" -A12581 = "" A12582 = "" A12583 = "" A12584 = "" A12585 = "" A12586 = "" A12587 = "" A12588 = "" A12589 = "" A12590 = "" -A12591 = "" A12592 = "" A12593 = "" A12594 = "" A12595 = "" A12596 = "" A12597 = "" A12598 = "" A12599 = "" A12600 = "" -A12601 = "" A12602 = "" A12603 = "" A12604 = "" A12605 = "" A12606 = "" A12607 = "" A12608 = "" A12609 = "" A12610 = "" -A12611 = "" A12612 = "" A12613 = "" A12614 = "" A12615 = "" A12616 = "" A12617 = "" A12618 = "" A12619 = "" A12620 = "" -A12621 = "" A12622 = "" A12623 = "" A12624 = "" A12625 = "" A12626 = "" A12627 = "" A12628 = "" A12629 = "" A12630 = "" -A12631 = "" A12632 = "" A12633 = "" A12634 = "" A12635 = "" A12636 = "" A12637 = "" A12638 = "" A12639 = "" A12640 = "" -A12641 = "" A12642 = "" A12643 = "" A12644 = "" A12645 = "" A12646 = "" A12647 = "" A12648 = "" A12649 = "" A12650 = "" -A12651 = "" A12652 = "" A12653 = "" A12654 = "" A12655 = "" A12656 = "" A12657 = "" A12658 = "" A12659 = "" A12660 = "" -A12661 = "" A12662 = "" A12663 = "" A12664 = "" A12665 = "" A12666 = "" A12667 = "" A12668 = "" A12669 = "" A12670 = "" -A12671 = "" A12672 = "" A12673 = "" A12674 = "" A12675 = "" A12676 = "" A12677 = "" A12678 = "" A12679 = "" A12680 = "" -A12681 = "" A12682 = "" A12683 = "" A12684 = "" A12685 = "" A12686 = "" A12687 = "" A12688 = "" A12689 = "" A12690 = "" -A12691 = "" A12692 = "" A12693 = "" A12694 = "" A12695 = "" A12696 = "" A12697 = "" A12698 = "" A12699 = "" A12700 = "" -A12701 = "" A12702 = "" A12703 = "" A12704 = "" A12705 = "" A12706 = "" A12707 = "" A12708 = "" A12709 = "" A12710 = "" -A12711 = "" A12712 = "" A12713 = "" A12714 = "" A12715 = "" A12716 = "" A12717 = "" A12718 = "" A12719 = "" A12720 = "" -A12721 = "" A12722 = "" A12723 = "" A12724 = "" A12725 = "" A12726 = "" A12727 = "" A12728 = "" A12729 = "" A12730 = "" -A12731 = "" A12732 = "" A12733 = "" A12734 = "" A12735 = "" A12736 = "" A12737 = "" A12738 = "" A12739 = "" A12740 = "" -A12741 = "" A12742 = "" A12743 = "" A12744 = "" A12745 = "" A12746 = "" A12747 = "" A12748 = "" A12749 = "" A12750 = "" -A12751 = "" A12752 = "" A12753 = "" A12754 = "" A12755 = "" A12756 = "" A12757 = "" A12758 = "" A12759 = "" A12760 = "" -A12761 = "" A12762 = "" A12763 = "" A12764 = "" A12765 = "" A12766 = "" A12767 = "" A12768 = "" A12769 = "" A12770 = "" -A12771 = "" A12772 = "" A12773 = "" A12774 = "" A12775 = "" A12776 = "" A12777 = "" A12778 = "" A12779 = "" A12780 = "" -A12781 = "" A12782 = "" A12783 = "" A12784 = "" A12785 = "" A12786 = "" A12787 = "" A12788 = "" A12789 = "" A12790 = "" -A12791 = "" A12792 = "" A12793 = "" A12794 = "" A12795 = "" A12796 = "" A12797 = "" A12798 = "" A12799 = "" A12800 = "" -A12801 = "" A12802 = "" A12803 = "" A12804 = "" A12805 = "" A12806 = "" A12807 = "" A12808 = "" A12809 = "" A12810 = "" -A12811 = "" A12812 = "" A12813 = "" A12814 = "" A12815 = "" A12816 = "" A12817 = "" A12818 = "" A12819 = "" A12820 = "" -A12821 = "" A12822 = "" A12823 = "" A12824 = "" A12825 = "" A12826 = "" A12827 = "" A12828 = "" A12829 = "" A12830 = "" -A12831 = "" A12832 = "" A12833 = "" A12834 = "" A12835 = "" A12836 = "" A12837 = "" A12838 = "" A12839 = "" A12840 = "" -A12841 = "" A12842 = "" A12843 = "" A12844 = "" A12845 = "" A12846 = "" A12847 = "" A12848 = "" A12849 = "" A12850 = "" -A12851 = "" A12852 = "" A12853 = "" A12854 = "" A12855 = "" A12856 = "" A12857 = "" A12858 = "" A12859 = "" A12860 = "" -A12861 = "" A12862 = "" A12863 = "" A12864 = "" A12865 = "" A12866 = "" A12867 = "" A12868 = "" A12869 = "" A12870 = "" -A12871 = "" A12872 = "" A12873 = "" A12874 = "" A12875 = "" A12876 = "" A12877 = "" A12878 = "" A12879 = "" A12880 = "" -A12881 = "" A12882 = "" A12883 = "" A12884 = "" A12885 = "" A12886 = "" A12887 = "" A12888 = "" A12889 = "" A12890 = "" -A12891 = "" A12892 = "" A12893 = "" A12894 = "" A12895 = "" A12896 = "" A12897 = "" A12898 = "" A12899 = "" A12900 = "" -A12901 = "" A12902 = "" A12903 = "" A12904 = "" A12905 = "" A12906 = "" A12907 = "" A12908 = "" A12909 = "" A12910 = "" -A12911 = "" A12912 = "" A12913 = "" A12914 = "" A12915 = "" A12916 = "" A12917 = "" A12918 = "" A12919 = "" A12920 = "" -A12921 = "" A12922 = "" A12923 = "" A12924 = "" A12925 = "" A12926 = "" A12927 = "" A12928 = "" A12929 = "" A12930 = "" -A12931 = "" A12932 = "" A12933 = "" A12934 = "" A12935 = "" A12936 = "" A12937 = "" A12938 = "" A12939 = "" A12940 = "" -A12941 = "" A12942 = "" A12943 = "" A12944 = "" A12945 = "" A12946 = "" A12947 = "" A12948 = "" A12949 = "" A12950 = "" -A12951 = "" A12952 = "" A12953 = "" A12954 = "" A12955 = "" A12956 = "" A12957 = "" A12958 = "" A12959 = "" A12960 = "" -A12961 = "" A12962 = "" A12963 = "" A12964 = "" A12965 = "" A12966 = "" A12967 = "" A12968 = "" A12969 = "" A12970 = "" -A12971 = "" A12972 = "" A12973 = "" A12974 = "" A12975 = "" A12976 = "" A12977 = "" A12978 = "" A12979 = "" A12980 = "" -A12981 = "" A12982 = "" A12983 = "" A12984 = "" A12985 = "" A12986 = "" A12987 = "" A12988 = "" A12989 = "" A12990 = "" -A12991 = "" A12992 = "" A12993 = "" A12994 = "" A12995 = "" A12996 = "" A12997 = "" A12998 = "" A12999 = "" A13000 = "" -A13001 = "" A13002 = "" A13003 = "" A13004 = "" A13005 = "" A13006 = "" A13007 = "" A13008 = "" A13009 = "" A13010 = "" -A13011 = "" A13012 = "" A13013 = "" A13014 = "" A13015 = "" A13016 = "" A13017 = "" A13018 = "" A13019 = "" A13020 = "" -A13021 = "" A13022 = "" A13023 = "" A13024 = "" A13025 = "" A13026 = "" A13027 = "" A13028 = "" A13029 = "" A13030 = "" -A13031 = "" A13032 = "" A13033 = "" A13034 = "" A13035 = "" A13036 = "" A13037 = "" A13038 = "" A13039 = "" A13040 = "" -A13041 = "" A13042 = "" A13043 = "" A13044 = "" A13045 = "" A13046 = "" A13047 = "" A13048 = "" A13049 = "" A13050 = "" -A13051 = "" A13052 = "" A13053 = "" A13054 = "" A13055 = "" A13056 = "" A13057 = "" A13058 = "" A13059 = "" A13060 = "" -A13061 = "" A13062 = "" A13063 = "" A13064 = "" A13065 = "" A13066 = "" A13067 = "" A13068 = "" A13069 = "" A13070 = "" -A13071 = "" A13072 = "" A13073 = "" A13074 = "" A13075 = "" A13076 = "" A13077 = "" A13078 = "" A13079 = "" A13080 = "" -A13081 = "" A13082 = "" A13083 = "" A13084 = "" A13085 = "" A13086 = "" A13087 = "" A13088 = "" A13089 = "" A13090 = "" -A13091 = "" A13092 = "" A13093 = "" A13094 = "" A13095 = "" A13096 = "" A13097 = "" A13098 = "" A13099 = "" A13100 = "" -A13101 = "" A13102 = "" A13103 = "" A13104 = "" A13105 = "" A13106 = "" A13107 = "" A13108 = "" A13109 = "" A13110 = "" -A13111 = "" A13112 = "" A13113 = "" A13114 = "" A13115 = "" A13116 = "" A13117 = "" A13118 = "" A13119 = "" A13120 = "" -A13121 = "" A13122 = "" A13123 = "" A13124 = "" A13125 = "" A13126 = "" A13127 = "" A13128 = "" A13129 = "" A13130 = "" -A13131 = "" A13132 = "" A13133 = "" A13134 = "" A13135 = "" A13136 = "" A13137 = "" A13138 = "" A13139 = "" A13140 = "" -A13141 = "" A13142 = "" A13143 = "" A13144 = "" A13145 = "" A13146 = "" A13147 = "" A13148 = "" A13149 = "" A13150 = "" -A13151 = "" A13152 = "" A13153 = "" A13154 = "" A13155 = "" A13156 = "" A13157 = "" A13158 = "" A13159 = "" A13160 = "" -A13161 = "" A13162 = "" A13163 = "" A13164 = "" A13165 = "" A13166 = "" A13167 = "" A13168 = "" A13169 = "" A13170 = "" -A13171 = "" A13172 = "" A13173 = "" A13174 = "" A13175 = "" A13176 = "" A13177 = "" A13178 = "" A13179 = "" A13180 = "" -A13181 = "" A13182 = "" A13183 = "" A13184 = "" A13185 = "" A13186 = "" A13187 = "" A13188 = "" A13189 = "" A13190 = "" -A13191 = "" A13192 = "" A13193 = "" A13194 = "" A13195 = "" A13196 = "" A13197 = "" A13198 = "" A13199 = "" A13200 = "" -A13201 = "" A13202 = "" A13203 = "" A13204 = "" A13205 = "" A13206 = "" A13207 = "" A13208 = "" A13209 = "" A13210 = "" -A13211 = "" A13212 = "" A13213 = "" A13214 = "" A13215 = "" A13216 = "" A13217 = "" A13218 = "" A13219 = "" A13220 = "" -A13221 = "" A13222 = "" A13223 = "" A13224 = "" A13225 = "" A13226 = "" A13227 = "" A13228 = "" A13229 = "" A13230 = "" -A13231 = "" A13232 = "" A13233 = "" A13234 = "" A13235 = "" A13236 = "" A13237 = "" A13238 = "" A13239 = "" A13240 = "" -A13241 = "" A13242 = "" A13243 = "" A13244 = "" A13245 = "" A13246 = "" A13247 = "" A13248 = "" A13249 = "" A13250 = "" -A13251 = "" A13252 = "" A13253 = "" A13254 = "" A13255 = "" A13256 = "" A13257 = "" A13258 = "" A13259 = "" A13260 = "" -A13261 = "" A13262 = "" A13263 = "" A13264 = "" A13265 = "" A13266 = "" A13267 = "" A13268 = "" A13269 = "" A13270 = "" -A13271 = "" A13272 = "" A13273 = "" A13274 = "" A13275 = "" A13276 = "" A13277 = "" A13278 = "" A13279 = "" A13280 = "" -A13281 = "" A13282 = "" A13283 = "" A13284 = "" A13285 = "" A13286 = "" A13287 = "" A13288 = "" A13289 = "" A13290 = "" -A13291 = "" A13292 = "" A13293 = "" A13294 = "" A13295 = "" A13296 = "" A13297 = "" A13298 = "" A13299 = "" A13300 = "" -A13301 = "" A13302 = "" A13303 = "" A13304 = "" A13305 = "" A13306 = "" A13307 = "" A13308 = "" A13309 = "" A13310 = "" -A13311 = "" A13312 = "" A13313 = "" A13314 = "" A13315 = "" A13316 = "" A13317 = "" A13318 = "" A13319 = "" A13320 = "" -A13321 = "" A13322 = "" A13323 = "" A13324 = "" A13325 = "" A13326 = "" A13327 = "" A13328 = "" A13329 = "" A13330 = "" -A13331 = "" A13332 = "" A13333 = "" A13334 = "" A13335 = "" A13336 = "" A13337 = "" A13338 = "" A13339 = "" A13340 = "" -A13341 = "" A13342 = "" A13343 = "" A13344 = "" A13345 = "" A13346 = "" A13347 = "" A13348 = "" A13349 = "" A13350 = "" -A13351 = "" A13352 = "" A13353 = "" A13354 = "" A13355 = "" A13356 = "" A13357 = "" A13358 = "" A13359 = "" A13360 = "" -A13361 = "" A13362 = "" A13363 = "" A13364 = "" A13365 = "" A13366 = "" A13367 = "" A13368 = "" A13369 = "" A13370 = "" -A13371 = "" A13372 = "" A13373 = "" A13374 = "" A13375 = "" A13376 = "" A13377 = "" A13378 = "" A13379 = "" A13380 = "" -A13381 = "" A13382 = "" A13383 = "" A13384 = "" A13385 = "" A13386 = "" A13387 = "" A13388 = "" A13389 = "" A13390 = "" -A13391 = "" A13392 = "" A13393 = "" A13394 = "" A13395 = "" A13396 = "" A13397 = "" A13398 = "" A13399 = "" A13400 = "" -A13401 = "" A13402 = "" A13403 = "" A13404 = "" A13405 = "" A13406 = "" A13407 = "" A13408 = "" A13409 = "" A13410 = "" -A13411 = "" A13412 = "" A13413 = "" A13414 = "" A13415 = "" A13416 = "" A13417 = "" A13418 = "" A13419 = "" A13420 = "" -A13421 = "" A13422 = "" A13423 = "" A13424 = "" A13425 = "" A13426 = "" A13427 = "" A13428 = "" A13429 = "" A13430 = "" -A13431 = "" A13432 = "" A13433 = "" A13434 = "" A13435 = "" A13436 = "" A13437 = "" A13438 = "" A13439 = "" A13440 = "" -A13441 = "" A13442 = "" A13443 = "" A13444 = "" A13445 = "" A13446 = "" A13447 = "" A13448 = "" A13449 = "" A13450 = "" -A13451 = "" A13452 = "" A13453 = "" A13454 = "" A13455 = "" A13456 = "" A13457 = "" A13458 = "" A13459 = "" A13460 = "" -A13461 = "" A13462 = "" A13463 = "" A13464 = "" A13465 = "" A13466 = "" A13467 = "" A13468 = "" A13469 = "" A13470 = "" -A13471 = "" A13472 = "" A13473 = "" A13474 = "" A13475 = "" A13476 = "" A13477 = "" A13478 = "" A13479 = "" A13480 = "" -A13481 = "" A13482 = "" A13483 = "" A13484 = "" A13485 = "" A13486 = "" A13487 = "" A13488 = "" A13489 = "" A13490 = "" -A13491 = "" A13492 = "" A13493 = "" A13494 = "" A13495 = "" A13496 = "" A13497 = "" A13498 = "" A13499 = "" A13500 = "" -A13501 = "" A13502 = "" A13503 = "" A13504 = "" A13505 = "" A13506 = "" A13507 = "" A13508 = "" A13509 = "" A13510 = "" -A13511 = "" A13512 = "" A13513 = "" A13514 = "" A13515 = "" A13516 = "" A13517 = "" A13518 = "" A13519 = "" A13520 = "" -A13521 = "" A13522 = "" A13523 = "" A13524 = "" A13525 = "" A13526 = "" A13527 = "" A13528 = "" A13529 = "" A13530 = "" -A13531 = "" A13532 = "" A13533 = "" A13534 = "" A13535 = "" A13536 = "" A13537 = "" A13538 = "" A13539 = "" A13540 = "" -A13541 = "" A13542 = "" A13543 = "" A13544 = "" A13545 = "" A13546 = "" A13547 = "" A13548 = "" A13549 = "" A13550 = "" -A13551 = "" A13552 = "" A13553 = "" A13554 = "" A13555 = "" A13556 = "" A13557 = "" A13558 = "" A13559 = "" A13560 = "" -A13561 = "" A13562 = "" A13563 = "" A13564 = "" A13565 = "" A13566 = "" A13567 = "" A13568 = "" A13569 = "" A13570 = "" -A13571 = "" A13572 = "" A13573 = "" A13574 = "" A13575 = "" A13576 = "" A13577 = "" A13578 = "" A13579 = "" A13580 = "" -A13581 = "" A13582 = "" A13583 = "" A13584 = "" A13585 = "" A13586 = "" A13587 = "" A13588 = "" A13589 = "" A13590 = "" -A13591 = "" A13592 = "" A13593 = "" A13594 = "" A13595 = "" A13596 = "" A13597 = "" A13598 = "" A13599 = "" A13600 = "" -A13601 = "" A13602 = "" A13603 = "" A13604 = "" A13605 = "" A13606 = "" A13607 = "" A13608 = "" A13609 = "" A13610 = "" -A13611 = "" A13612 = "" A13613 = "" A13614 = "" A13615 = "" A13616 = "" A13617 = "" A13618 = "" A13619 = "" A13620 = "" -A13621 = "" A13622 = "" A13623 = "" A13624 = "" A13625 = "" A13626 = "" A13627 = "" A13628 = "" A13629 = "" A13630 = "" -A13631 = "" A13632 = "" A13633 = "" A13634 = "" A13635 = "" A13636 = "" A13637 = "" A13638 = "" A13639 = "" A13640 = "" -A13641 = "" A13642 = "" A13643 = "" A13644 = "" A13645 = "" A13646 = "" A13647 = "" A13648 = "" A13649 = "" A13650 = "" -A13651 = "" A13652 = "" A13653 = "" A13654 = "" A13655 = "" A13656 = "" A13657 = "" A13658 = "" A13659 = "" A13660 = "" -A13661 = "" A13662 = "" A13663 = "" A13664 = "" A13665 = "" A13666 = "" A13667 = "" A13668 = "" A13669 = "" A13670 = "" -A13671 = "" A13672 = "" A13673 = "" A13674 = "" A13675 = "" A13676 = "" A13677 = "" A13678 = "" A13679 = "" A13680 = "" -A13681 = "" A13682 = "" A13683 = "" A13684 = "" A13685 = "" A13686 = "" A13687 = "" A13688 = "" A13689 = "" A13690 = "" -A13691 = "" A13692 = "" A13693 = "" A13694 = "" A13695 = "" A13696 = "" A13697 = "" A13698 = "" A13699 = "" A13700 = "" -A13701 = "" A13702 = "" A13703 = "" A13704 = "" A13705 = "" A13706 = "" A13707 = "" A13708 = "" A13709 = "" A13710 = "" -A13711 = "" A13712 = "" A13713 = "" A13714 = "" A13715 = "" A13716 = "" A13717 = "" A13718 = "" A13719 = "" A13720 = "" -A13721 = "" A13722 = "" A13723 = "" A13724 = "" A13725 = "" A13726 = "" A13727 = "" A13728 = "" A13729 = "" A13730 = "" -A13731 = "" A13732 = "" A13733 = "" A13734 = "" A13735 = "" A13736 = "" A13737 = "" A13738 = "" A13739 = "" A13740 = "" -A13741 = "" A13742 = "" A13743 = "" A13744 = "" A13745 = "" A13746 = "" A13747 = "" A13748 = "" A13749 = "" A13750 = "" -A13751 = "" A13752 = "" A13753 = "" A13754 = "" A13755 = "" A13756 = "" A13757 = "" A13758 = "" A13759 = "" A13760 = "" -A13761 = "" A13762 = "" A13763 = "" A13764 = "" A13765 = "" A13766 = "" A13767 = "" A13768 = "" A13769 = "" A13770 = "" -A13771 = "" A13772 = "" A13773 = "" A13774 = "" A13775 = "" A13776 = "" A13777 = "" A13778 = "" A13779 = "" A13780 = "" -A13781 = "" A13782 = "" A13783 = "" A13784 = "" A13785 = "" A13786 = "" A13787 = "" A13788 = "" A13789 = "" A13790 = "" -A13791 = "" A13792 = "" A13793 = "" A13794 = "" A13795 = "" A13796 = "" A13797 = "" A13798 = "" A13799 = "" A13800 = "" -A13801 = "" A13802 = "" A13803 = "" A13804 = "" A13805 = "" A13806 = "" A13807 = "" A13808 = "" A13809 = "" A13810 = "" -A13811 = "" A13812 = "" A13813 = "" A13814 = "" A13815 = "" A13816 = "" A13817 = "" A13818 = "" A13819 = "" A13820 = "" -A13821 = "" A13822 = "" A13823 = "" A13824 = "" A13825 = "" A13826 = "" A13827 = "" A13828 = "" A13829 = "" A13830 = "" -A13831 = "" A13832 = "" A13833 = "" A13834 = "" A13835 = "" A13836 = "" A13837 = "" A13838 = "" A13839 = "" A13840 = "" -A13841 = "" A13842 = "" A13843 = "" A13844 = "" A13845 = "" A13846 = "" A13847 = "" A13848 = "" A13849 = "" A13850 = "" -A13851 = "" A13852 = "" A13853 = "" A13854 = "" A13855 = "" A13856 = "" A13857 = "" A13858 = "" A13859 = "" A13860 = "" -A13861 = "" A13862 = "" A13863 = "" A13864 = "" A13865 = "" A13866 = "" A13867 = "" A13868 = "" A13869 = "" A13870 = "" -A13871 = "" A13872 = "" A13873 = "" A13874 = "" A13875 = "" A13876 = "" A13877 = "" A13878 = "" A13879 = "" A13880 = "" -A13881 = "" A13882 = "" A13883 = "" A13884 = "" A13885 = "" A13886 = "" A13887 = "" A13888 = "" A13889 = "" A13890 = "" -A13891 = "" A13892 = "" A13893 = "" A13894 = "" A13895 = "" A13896 = "" A13897 = "" A13898 = "" A13899 = "" A13900 = "" -A13901 = "" A13902 = "" A13903 = "" A13904 = "" A13905 = "" A13906 = "" A13907 = "" A13908 = "" A13909 = "" A13910 = "" -A13911 = "" A13912 = "" A13913 = "" A13914 = "" A13915 = "" A13916 = "" A13917 = "" A13918 = "" A13919 = "" A13920 = "" -A13921 = "" A13922 = "" A13923 = "" A13924 = "" A13925 = "" A13926 = "" A13927 = "" A13928 = "" A13929 = "" A13930 = "" -A13931 = "" A13932 = "" A13933 = "" A13934 = "" A13935 = "" A13936 = "" A13937 = "" A13938 = "" A13939 = "" A13940 = "" -A13941 = "" A13942 = "" A13943 = "" A13944 = "" A13945 = "" A13946 = "" A13947 = "" A13948 = "" A13949 = "" A13950 = "" -A13951 = "" A13952 = "" A13953 = "" A13954 = "" A13955 = "" A13956 = "" A13957 = "" A13958 = "" A13959 = "" A13960 = "" -A13961 = "" A13962 = "" A13963 = "" A13964 = "" A13965 = "" A13966 = "" A13967 = "" A13968 = "" A13969 = "" A13970 = "" -A13971 = "" A13972 = "" A13973 = "" A13974 = "" A13975 = "" A13976 = "" A13977 = "" A13978 = "" A13979 = "" A13980 = "" -A13981 = "" A13982 = "" A13983 = "" A13984 = "" A13985 = "" A13986 = "" A13987 = "" A13988 = "" A13989 = "" A13990 = "" -A13991 = "" A13992 = "" A13993 = "" A13994 = "" A13995 = "" A13996 = "" A13997 = "" A13998 = "" A13999 = "" A14000 = "" -A14001 = "" A14002 = "" A14003 = "" A14004 = "" A14005 = "" A14006 = "" A14007 = "" A14008 = "" A14009 = "" A14010 = "" -A14011 = "" A14012 = "" A14013 = "" A14014 = "" A14015 = "" A14016 = "" A14017 = "" A14018 = "" A14019 = "" A14020 = "" -A14021 = "" A14022 = "" A14023 = "" A14024 = "" A14025 = "" A14026 = "" A14027 = "" A14028 = "" A14029 = "" A14030 = "" -A14031 = "" A14032 = "" A14033 = "" A14034 = "" A14035 = "" A14036 = "" A14037 = "" A14038 = "" A14039 = "" A14040 = "" -A14041 = "" A14042 = "" A14043 = "" A14044 = "" A14045 = "" A14046 = "" A14047 = "" A14048 = "" A14049 = "" A14050 = "" -A14051 = "" A14052 = "" A14053 = "" A14054 = "" A14055 = "" A14056 = "" A14057 = "" A14058 = "" A14059 = "" A14060 = "" -A14061 = "" A14062 = "" A14063 = "" A14064 = "" A14065 = "" A14066 = "" A14067 = "" A14068 = "" A14069 = "" A14070 = "" -A14071 = "" A14072 = "" A14073 = "" A14074 = "" A14075 = "" A14076 = "" A14077 = "" A14078 = "" A14079 = "" A14080 = "" -A14081 = "" A14082 = "" A14083 = "" A14084 = "" A14085 = "" A14086 = "" A14087 = "" A14088 = "" A14089 = "" A14090 = "" -A14091 = "" A14092 = "" A14093 = "" A14094 = "" A14095 = "" A14096 = "" A14097 = "" A14098 = "" A14099 = "" A14100 = "" -A14101 = "" A14102 = "" A14103 = "" A14104 = "" A14105 = "" A14106 = "" A14107 = "" A14108 = "" A14109 = "" A14110 = "" -A14111 = "" A14112 = "" A14113 = "" A14114 = "" A14115 = "" A14116 = "" A14117 = "" A14118 = "" A14119 = "" A14120 = "" -A14121 = "" A14122 = "" A14123 = "" A14124 = "" A14125 = "" A14126 = "" A14127 = "" A14128 = "" A14129 = "" A14130 = "" -A14131 = "" A14132 = "" A14133 = "" A14134 = "" A14135 = "" A14136 = "" A14137 = "" A14138 = "" A14139 = "" A14140 = "" -A14141 = "" A14142 = "" A14143 = "" A14144 = "" A14145 = "" A14146 = "" A14147 = "" A14148 = "" A14149 = "" A14150 = "" -A14151 = "" A14152 = "" A14153 = "" A14154 = "" A14155 = "" A14156 = "" A14157 = "" A14158 = "" A14159 = "" A14160 = "" -A14161 = "" A14162 = "" A14163 = "" A14164 = "" A14165 = "" A14166 = "" A14167 = "" A14168 = "" A14169 = "" A14170 = "" -A14171 = "" A14172 = "" A14173 = "" A14174 = "" A14175 = "" A14176 = "" A14177 = "" A14178 = "" A14179 = "" A14180 = "" -A14181 = "" A14182 = "" A14183 = "" A14184 = "" A14185 = "" A14186 = "" A14187 = "" A14188 = "" A14189 = "" A14190 = "" -A14191 = "" A14192 = "" A14193 = "" A14194 = "" A14195 = "" A14196 = "" A14197 = "" A14198 = "" A14199 = "" A14200 = "" -A14201 = "" A14202 = "" A14203 = "" A14204 = "" A14205 = "" A14206 = "" A14207 = "" A14208 = "" A14209 = "" A14210 = "" -A14211 = "" A14212 = "" A14213 = "" A14214 = "" A14215 = "" A14216 = "" A14217 = "" A14218 = "" A14219 = "" A14220 = "" -A14221 = "" A14222 = "" A14223 = "" A14224 = "" A14225 = "" A14226 = "" A14227 = "" A14228 = "" A14229 = "" A14230 = "" -A14231 = "" A14232 = "" A14233 = "" A14234 = "" A14235 = "" A14236 = "" A14237 = "" A14238 = "" A14239 = "" A14240 = "" -A14241 = "" A14242 = "" A14243 = "" A14244 = "" A14245 = "" A14246 = "" A14247 = "" A14248 = "" A14249 = "" A14250 = "" -A14251 = "" A14252 = "" A14253 = "" A14254 = "" A14255 = "" A14256 = "" A14257 = "" A14258 = "" A14259 = "" A14260 = "" -A14261 = "" A14262 = "" A14263 = "" A14264 = "" A14265 = "" A14266 = "" A14267 = "" A14268 = "" A14269 = "" A14270 = "" -A14271 = "" A14272 = "" A14273 = "" A14274 = "" A14275 = "" A14276 = "" A14277 = "" A14278 = "" A14279 = "" A14280 = "" -A14281 = "" A14282 = "" A14283 = "" A14284 = "" A14285 = "" A14286 = "" A14287 = "" A14288 = "" A14289 = "" A14290 = "" -A14291 = "" A14292 = "" A14293 = "" A14294 = "" A14295 = "" A14296 = "" A14297 = "" A14298 = "" A14299 = "" A14300 = "" -A14301 = "" A14302 = "" A14303 = "" A14304 = "" A14305 = "" A14306 = "" A14307 = "" A14308 = "" A14309 = "" A14310 = "" -A14311 = "" A14312 = "" A14313 = "" A14314 = "" A14315 = "" A14316 = "" A14317 = "" A14318 = "" A14319 = "" A14320 = "" -A14321 = "" A14322 = "" A14323 = "" A14324 = "" A14325 = "" A14326 = "" A14327 = "" A14328 = "" A14329 = "" A14330 = "" -A14331 = "" A14332 = "" A14333 = "" A14334 = "" A14335 = "" A14336 = "" A14337 = "" A14338 = "" A14339 = "" A14340 = "" -A14341 = "" A14342 = "" A14343 = "" A14344 = "" A14345 = "" A14346 = "" A14347 = "" A14348 = "" A14349 = "" A14350 = "" -A14351 = "" A14352 = "" A14353 = "" A14354 = "" A14355 = "" A14356 = "" A14357 = "" A14358 = "" A14359 = "" A14360 = "" -A14361 = "" A14362 = "" A14363 = "" A14364 = "" A14365 = "" A14366 = "" A14367 = "" A14368 = "" A14369 = "" A14370 = "" -A14371 = "" A14372 = "" A14373 = "" A14374 = "" A14375 = "" A14376 = "" A14377 = "" A14378 = "" A14379 = "" A14380 = "" -A14381 = "" A14382 = "" A14383 = "" A14384 = "" A14385 = "" A14386 = "" A14387 = "" A14388 = "" A14389 = "" A14390 = "" -A14391 = "" A14392 = "" A14393 = "" A14394 = "" A14395 = "" A14396 = "" A14397 = "" A14398 = "" A14399 = "" A14400 = "" -A14401 = "" A14402 = "" A14403 = "" A14404 = "" A14405 = "" A14406 = "" A14407 = "" A14408 = "" A14409 = "" A14410 = "" -A14411 = "" A14412 = "" A14413 = "" A14414 = "" A14415 = "" A14416 = "" A14417 = "" A14418 = "" A14419 = "" A14420 = "" -A14421 = "" A14422 = "" A14423 = "" A14424 = "" A14425 = "" A14426 = "" A14427 = "" A14428 = "" A14429 = "" A14430 = "" -A14431 = "" A14432 = "" A14433 = "" A14434 = "" A14435 = "" A14436 = "" A14437 = "" A14438 = "" A14439 = "" A14440 = "" -A14441 = "" A14442 = "" A14443 = "" A14444 = "" A14445 = "" A14446 = "" A14447 = "" A14448 = "" A14449 = "" A14450 = "" -A14451 = "" A14452 = "" A14453 = "" A14454 = "" A14455 = "" A14456 = "" A14457 = "" A14458 = "" A14459 = "" A14460 = "" -A14461 = "" A14462 = "" A14463 = "" A14464 = "" A14465 = "" A14466 = "" A14467 = "" A14468 = "" A14469 = "" A14470 = "" -A14471 = "" A14472 = "" A14473 = "" A14474 = "" A14475 = "" A14476 = "" A14477 = "" A14478 = "" A14479 = "" A14480 = "" -A14481 = "" A14482 = "" A14483 = "" A14484 = "" A14485 = "" A14486 = "" A14487 = "" A14488 = "" A14489 = "" A14490 = "" -A14491 = "" A14492 = "" A14493 = "" A14494 = "" A14495 = "" A14496 = "" A14497 = "" A14498 = "" A14499 = "" A14500 = "" -A14501 = "" A14502 = "" A14503 = "" A14504 = "" A14505 = "" A14506 = "" A14507 = "" A14508 = "" A14509 = "" A14510 = "" -A14511 = "" A14512 = "" A14513 = "" A14514 = "" A14515 = "" A14516 = "" A14517 = "" A14518 = "" A14519 = "" A14520 = "" -A14521 = "" A14522 = "" A14523 = "" A14524 = "" A14525 = "" A14526 = "" A14527 = "" A14528 = "" A14529 = "" A14530 = "" -A14531 = "" A14532 = "" A14533 = "" A14534 = "" A14535 = "" A14536 = "" A14537 = "" A14538 = "" A14539 = "" A14540 = "" -A14541 = "" A14542 = "" A14543 = "" A14544 = "" A14545 = "" A14546 = "" A14547 = "" A14548 = "" A14549 = "" A14550 = "" -A14551 = "" A14552 = "" A14553 = "" A14554 = "" A14555 = "" A14556 = "" A14557 = "" A14558 = "" A14559 = "" A14560 = "" -A14561 = "" A14562 = "" A14563 = "" A14564 = "" A14565 = "" A14566 = "" A14567 = "" A14568 = "" A14569 = "" A14570 = "" -A14571 = "" A14572 = "" A14573 = "" A14574 = "" A14575 = "" A14576 = "" A14577 = "" A14578 = "" A14579 = "" A14580 = "" -A14581 = "" A14582 = "" A14583 = "" A14584 = "" A14585 = "" A14586 = "" A14587 = "" A14588 = "" A14589 = "" A14590 = "" -A14591 = "" A14592 = "" A14593 = "" A14594 = "" A14595 = "" A14596 = "" A14597 = "" A14598 = "" A14599 = "" A14600 = "" -A14601 = "" A14602 = "" A14603 = "" A14604 = "" A14605 = "" A14606 = "" A14607 = "" A14608 = "" A14609 = "" A14610 = "" -A14611 = "" A14612 = "" A14613 = "" A14614 = "" A14615 = "" A14616 = "" A14617 = "" A14618 = "" A14619 = "" A14620 = "" -A14621 = "" A14622 = "" A14623 = "" A14624 = "" A14625 = "" A14626 = "" A14627 = "" A14628 = "" A14629 = "" A14630 = "" -A14631 = "" A14632 = "" A14633 = "" A14634 = "" A14635 = "" A14636 = "" A14637 = "" A14638 = "" A14639 = "" A14640 = "" -A14641 = "" A14642 = "" A14643 = "" A14644 = "" A14645 = "" A14646 = "" A14647 = "" A14648 = "" A14649 = "" A14650 = "" -A14651 = "" A14652 = "" A14653 = "" A14654 = "" A14655 = "" A14656 = "" A14657 = "" A14658 = "" A14659 = "" A14660 = "" -A14661 = "" A14662 = "" A14663 = "" A14664 = "" A14665 = "" A14666 = "" A14667 = "" A14668 = "" A14669 = "" A14670 = "" -A14671 = "" A14672 = "" A14673 = "" A14674 = "" A14675 = "" A14676 = "" A14677 = "" A14678 = "" A14679 = "" A14680 = "" -A14681 = "" A14682 = "" A14683 = "" A14684 = "" A14685 = "" A14686 = "" A14687 = "" A14688 = "" A14689 = "" A14690 = "" -A14691 = "" A14692 = "" A14693 = "" A14694 = "" A14695 = "" A14696 = "" A14697 = "" A14698 = "" A14699 = "" A14700 = "" -A14701 = "" A14702 = "" A14703 = "" A14704 = "" A14705 = "" A14706 = "" A14707 = "" A14708 = "" A14709 = "" A14710 = "" -A14711 = "" A14712 = "" A14713 = "" A14714 = "" A14715 = "" A14716 = "" A14717 = "" A14718 = "" A14719 = "" A14720 = "" -A14721 = "" A14722 = "" A14723 = "" A14724 = "" A14725 = "" A14726 = "" A14727 = "" A14728 = "" A14729 = "" A14730 = "" -A14731 = "" A14732 = "" A14733 = "" A14734 = "" A14735 = "" A14736 = "" A14737 = "" A14738 = "" A14739 = "" A14740 = "" -A14741 = "" A14742 = "" A14743 = "" A14744 = "" A14745 = "" A14746 = "" A14747 = "" A14748 = "" A14749 = "" A14750 = "" -A14751 = "" A14752 = "" A14753 = "" A14754 = "" A14755 = "" A14756 = "" A14757 = "" A14758 = "" A14759 = "" A14760 = "" -A14761 = "" A14762 = "" A14763 = "" A14764 = "" A14765 = "" A14766 = "" A14767 = "" A14768 = "" A14769 = "" A14770 = "" -A14771 = "" A14772 = "" A14773 = "" A14774 = "" A14775 = "" A14776 = "" A14777 = "" A14778 = "" A14779 = "" A14780 = "" -A14781 = "" A14782 = "" A14783 = "" A14784 = "" A14785 = "" A14786 = "" A14787 = "" A14788 = "" A14789 = "" A14790 = "" -A14791 = "" A14792 = "" A14793 = "" A14794 = "" A14795 = "" A14796 = "" A14797 = "" A14798 = "" A14799 = "" A14800 = "" -A14801 = "" A14802 = "" A14803 = "" A14804 = "" A14805 = "" A14806 = "" A14807 = "" A14808 = "" A14809 = "" A14810 = "" -A14811 = "" A14812 = "" A14813 = "" A14814 = "" A14815 = "" A14816 = "" A14817 = "" A14818 = "" A14819 = "" A14820 = "" -A14821 = "" A14822 = "" A14823 = "" A14824 = "" A14825 = "" A14826 = "" A14827 = "" A14828 = "" A14829 = "" A14830 = "" -A14831 = "" A14832 = "" A14833 = "" A14834 = "" A14835 = "" A14836 = "" A14837 = "" A14838 = "" A14839 = "" A14840 = "" -A14841 = "" A14842 = "" A14843 = "" A14844 = "" A14845 = "" A14846 = "" A14847 = "" A14848 = "" A14849 = "" A14850 = "" -A14851 = "" A14852 = "" A14853 = "" A14854 = "" A14855 = "" A14856 = "" A14857 = "" A14858 = "" A14859 = "" A14860 = "" -A14861 = "" A14862 = "" A14863 = "" A14864 = "" A14865 = "" A14866 = "" A14867 = "" A14868 = "" A14869 = "" A14870 = "" -A14871 = "" A14872 = "" A14873 = "" A14874 = "" A14875 = "" A14876 = "" A14877 = "" A14878 = "" A14879 = "" A14880 = "" -A14881 = "" A14882 = "" A14883 = "" A14884 = "" A14885 = "" A14886 = "" A14887 = "" A14888 = "" A14889 = "" A14890 = "" -A14891 = "" A14892 = "" A14893 = "" A14894 = "" A14895 = "" A14896 = "" A14897 = "" A14898 = "" A14899 = "" A14900 = "" -A14901 = "" A14902 = "" A14903 = "" A14904 = "" A14905 = "" A14906 = "" A14907 = "" A14908 = "" A14909 = "" A14910 = "" -A14911 = "" A14912 = "" A14913 = "" A14914 = "" A14915 = "" A14916 = "" A14917 = "" A14918 = "" A14919 = "" A14920 = "" -A14921 = "" A14922 = "" A14923 = "" A14924 = "" A14925 = "" A14926 = "" A14927 = "" A14928 = "" A14929 = "" A14930 = "" -A14931 = "" A14932 = "" A14933 = "" A14934 = "" A14935 = "" A14936 = "" A14937 = "" A14938 = "" A14939 = "" A14940 = "" -A14941 = "" A14942 = "" A14943 = "" A14944 = "" A14945 = "" A14946 = "" A14947 = "" A14948 = "" A14949 = "" A14950 = "" -A14951 = "" A14952 = "" A14953 = "" A14954 = "" A14955 = "" A14956 = "" A14957 = "" A14958 = "" A14959 = "" A14960 = "" -A14961 = "" A14962 = "" A14963 = "" A14964 = "" A14965 = "" A14966 = "" A14967 = "" A14968 = "" A14969 = "" A14970 = "" -A14971 = "" A14972 = "" A14973 = "" A14974 = "" A14975 = "" A14976 = "" A14977 = "" A14978 = "" A14979 = "" A14980 = "" -A14981 = "" A14982 = "" A14983 = "" A14984 = "" A14985 = "" A14986 = "" A14987 = "" A14988 = "" A14989 = "" A14990 = "" -A14991 = "" A14992 = "" A14993 = "" A14994 = "" A14995 = "" A14996 = "" A14997 = "" A14998 = "" A14999 = "" A15000 = "" -A15001 = "" A15002 = "" A15003 = "" A15004 = "" A15005 = "" A15006 = "" A15007 = "" A15008 = "" A15009 = "" A15010 = "" -A15011 = "" A15012 = "" A15013 = "" A15014 = "" A15015 = "" A15016 = "" A15017 = "" A15018 = "" A15019 = "" A15020 = "" -A15021 = "" A15022 = "" A15023 = "" A15024 = "" A15025 = "" A15026 = "" A15027 = "" A15028 = "" A15029 = "" A15030 = "" -A15031 = "" A15032 = "" A15033 = "" A15034 = "" A15035 = "" A15036 = "" A15037 = "" A15038 = "" A15039 = "" A15040 = "" -A15041 = "" A15042 = "" A15043 = "" A15044 = "" A15045 = "" A15046 = "" A15047 = "" A15048 = "" A15049 = "" A15050 = "" -A15051 = "" A15052 = "" A15053 = "" A15054 = "" A15055 = "" A15056 = "" A15057 = "" A15058 = "" A15059 = "" A15060 = "" -A15061 = "" A15062 = "" A15063 = "" A15064 = "" A15065 = "" A15066 = "" A15067 = "" A15068 = "" A15069 = "" A15070 = "" -A15071 = "" A15072 = "" A15073 = "" A15074 = "" A15075 = "" A15076 = "" A15077 = "" A15078 = "" A15079 = "" A15080 = "" -A15081 = "" A15082 = "" A15083 = "" A15084 = "" A15085 = "" A15086 = "" A15087 = "" A15088 = "" A15089 = "" A15090 = "" -A15091 = "" A15092 = "" A15093 = "" A15094 = "" A15095 = "" A15096 = "" A15097 = "" A15098 = "" A15099 = "" A15100 = "" -A15101 = "" A15102 = "" A15103 = "" A15104 = "" A15105 = "" A15106 = "" A15107 = "" A15108 = "" A15109 = "" A15110 = "" -A15111 = "" A15112 = "" A15113 = "" A15114 = "" A15115 = "" A15116 = "" A15117 = "" A15118 = "" A15119 = "" A15120 = "" -A15121 = "" A15122 = "" A15123 = "" A15124 = "" A15125 = "" A15126 = "" A15127 = "" A15128 = "" A15129 = "" A15130 = "" -A15131 = "" A15132 = "" A15133 = "" A15134 = "" A15135 = "" A15136 = "" A15137 = "" A15138 = "" A15139 = "" A15140 = "" -A15141 = "" A15142 = "" A15143 = "" A15144 = "" A15145 = "" A15146 = "" A15147 = "" A15148 = "" A15149 = "" A15150 = "" -A15151 = "" A15152 = "" A15153 = "" A15154 = "" A15155 = "" A15156 = "" A15157 = "" A15158 = "" A15159 = "" A15160 = "" -A15161 = "" A15162 = "" A15163 = "" A15164 = "" A15165 = "" A15166 = "" A15167 = "" A15168 = "" A15169 = "" A15170 = "" -A15171 = "" A15172 = "" A15173 = "" A15174 = "" A15175 = "" A15176 = "" A15177 = "" A15178 = "" A15179 = "" A15180 = "" -A15181 = "" A15182 = "" A15183 = "" A15184 = "" A15185 = "" A15186 = "" A15187 = "" A15188 = "" A15189 = "" A15190 = "" -A15191 = "" A15192 = "" A15193 = "" A15194 = "" A15195 = "" A15196 = "" A15197 = "" A15198 = "" A15199 = "" A15200 = "" -A15201 = "" A15202 = "" A15203 = "" A15204 = "" A15205 = "" A15206 = "" A15207 = "" A15208 = "" A15209 = "" A15210 = "" -A15211 = "" A15212 = "" A15213 = "" A15214 = "" A15215 = "" A15216 = "" A15217 = "" A15218 = "" A15219 = "" A15220 = "" -A15221 = "" A15222 = "" A15223 = "" A15224 = "" A15225 = "" A15226 = "" A15227 = "" A15228 = "" A15229 = "" A15230 = "" -A15231 = "" A15232 = "" A15233 = "" A15234 = "" A15235 = "" A15236 = "" A15237 = "" A15238 = "" A15239 = "" A15240 = "" -A15241 = "" A15242 = "" A15243 = "" A15244 = "" A15245 = "" A15246 = "" A15247 = "" A15248 = "" A15249 = "" A15250 = "" -A15251 = "" A15252 = "" A15253 = "" A15254 = "" A15255 = "" A15256 = "" A15257 = "" A15258 = "" A15259 = "" A15260 = "" -A15261 = "" A15262 = "" A15263 = "" A15264 = "" A15265 = "" A15266 = "" A15267 = "" A15268 = "" A15269 = "" A15270 = "" -A15271 = "" A15272 = "" A15273 = "" A15274 = "" A15275 = "" A15276 = "" A15277 = "" A15278 = "" A15279 = "" A15280 = "" -A15281 = "" A15282 = "" A15283 = "" A15284 = "" A15285 = "" A15286 = "" A15287 = "" A15288 = "" A15289 = "" A15290 = "" -A15291 = "" A15292 = "" A15293 = "" A15294 = "" A15295 = "" A15296 = "" A15297 = "" A15298 = "" A15299 = "" A15300 = "" -A15301 = "" A15302 = "" A15303 = "" A15304 = "" A15305 = "" A15306 = "" A15307 = "" A15308 = "" A15309 = "" A15310 = "" -A15311 = "" A15312 = "" A15313 = "" A15314 = "" A15315 = "" A15316 = "" A15317 = "" A15318 = "" A15319 = "" A15320 = "" -A15321 = "" A15322 = "" A15323 = "" A15324 = "" A15325 = "" A15326 = "" A15327 = "" A15328 = "" A15329 = "" A15330 = "" -A15331 = "" A15332 = "" A15333 = "" A15334 = "" A15335 = "" A15336 = "" A15337 = "" A15338 = "" A15339 = "" A15340 = "" -A15341 = "" A15342 = "" A15343 = "" A15344 = "" A15345 = "" A15346 = "" A15347 = "" A15348 = "" A15349 = "" A15350 = "" -A15351 = "" A15352 = "" A15353 = "" A15354 = "" A15355 = "" A15356 = "" A15357 = "" A15358 = "" A15359 = "" A15360 = "" -A15361 = "" A15362 = "" A15363 = "" A15364 = "" A15365 = "" A15366 = "" A15367 = "" A15368 = "" A15369 = "" A15370 = "" -A15371 = "" A15372 = "" A15373 = "" A15374 = "" A15375 = "" A15376 = "" A15377 = "" A15378 = "" A15379 = "" A15380 = "" -A15381 = "" A15382 = "" A15383 = "" A15384 = "" A15385 = "" A15386 = "" A15387 = "" A15388 = "" A15389 = "" A15390 = "" -A15391 = "" A15392 = "" A15393 = "" A15394 = "" A15395 = "" A15396 = "" A15397 = "" A15398 = "" A15399 = "" A15400 = "" -A15401 = "" A15402 = "" A15403 = "" A15404 = "" A15405 = "" A15406 = "" A15407 = "" A15408 = "" A15409 = "" A15410 = "" -A15411 = "" A15412 = "" A15413 = "" A15414 = "" A15415 = "" A15416 = "" A15417 = "" A15418 = "" A15419 = "" A15420 = "" -A15421 = "" A15422 = "" A15423 = "" A15424 = "" A15425 = "" A15426 = "" A15427 = "" A15428 = "" A15429 = "" A15430 = "" -A15431 = "" A15432 = "" A15433 = "" A15434 = "" A15435 = "" A15436 = "" A15437 = "" A15438 = "" A15439 = "" A15440 = "" -A15441 = "" A15442 = "" A15443 = "" A15444 = "" A15445 = "" A15446 = "" A15447 = "" A15448 = "" A15449 = "" A15450 = "" -A15451 = "" A15452 = "" A15453 = "" A15454 = "" A15455 = "" A15456 = "" A15457 = "" A15458 = "" A15459 = "" A15460 = "" -A15461 = "" A15462 = "" A15463 = "" A15464 = "" A15465 = "" A15466 = "" A15467 = "" A15468 = "" A15469 = "" A15470 = "" -A15471 = "" A15472 = "" A15473 = "" A15474 = "" A15475 = "" A15476 = "" A15477 = "" A15478 = "" A15479 = "" A15480 = "" -A15481 = "" A15482 = "" A15483 = "" A15484 = "" A15485 = "" A15486 = "" A15487 = "" A15488 = "" A15489 = "" A15490 = "" -A15491 = "" A15492 = "" A15493 = "" A15494 = "" A15495 = "" A15496 = "" A15497 = "" A15498 = "" A15499 = "" A15500 = "" -A15501 = "" A15502 = "" A15503 = "" A15504 = "" A15505 = "" A15506 = "" A15507 = "" A15508 = "" A15509 = "" A15510 = "" -A15511 = "" A15512 = "" A15513 = "" A15514 = "" A15515 = "" A15516 = "" A15517 = "" A15518 = "" A15519 = "" A15520 = "" -A15521 = "" A15522 = "" A15523 = "" A15524 = "" A15525 = "" A15526 = "" A15527 = "" A15528 = "" A15529 = "" A15530 = "" -A15531 = "" A15532 = "" A15533 = "" A15534 = "" A15535 = "" A15536 = "" A15537 = "" A15538 = "" A15539 = "" A15540 = "" -A15541 = "" A15542 = "" A15543 = "" A15544 = "" A15545 = "" A15546 = "" A15547 = "" A15548 = "" A15549 = "" A15550 = "" -A15551 = "" A15552 = "" A15553 = "" A15554 = "" A15555 = "" A15556 = "" A15557 = "" A15558 = "" A15559 = "" A15560 = "" -A15561 = "" A15562 = "" A15563 = "" A15564 = "" A15565 = "" A15566 = "" A15567 = "" A15568 = "" A15569 = "" A15570 = "" -A15571 = "" A15572 = "" A15573 = "" A15574 = "" A15575 = "" A15576 = "" A15577 = "" A15578 = "" A15579 = "" A15580 = "" -A15581 = "" A15582 = "" A15583 = "" A15584 = "" A15585 = "" A15586 = "" A15587 = "" A15588 = "" A15589 = "" A15590 = "" -A15591 = "" A15592 = "" A15593 = "" A15594 = "" A15595 = "" A15596 = "" A15597 = "" A15598 = "" A15599 = "" A15600 = "" -A15601 = "" A15602 = "" A15603 = "" A15604 = "" A15605 = "" A15606 = "" A15607 = "" A15608 = "" A15609 = "" A15610 = "" -A15611 = "" A15612 = "" A15613 = "" A15614 = "" A15615 = "" A15616 = "" A15617 = "" A15618 = "" A15619 = "" A15620 = "" -A15621 = "" A15622 = "" A15623 = "" A15624 = "" A15625 = "" A15626 = "" A15627 = "" A15628 = "" A15629 = "" A15630 = "" -A15631 = "" A15632 = "" A15633 = "" A15634 = "" A15635 = "" A15636 = "" A15637 = "" A15638 = "" A15639 = "" A15640 = "" -A15641 = "" A15642 = "" A15643 = "" A15644 = "" A15645 = "" A15646 = "" A15647 = "" A15648 = "" A15649 = "" A15650 = "" -A15651 = "" A15652 = "" A15653 = "" A15654 = "" A15655 = "" A15656 = "" A15657 = "" A15658 = "" A15659 = "" A15660 = "" -A15661 = "" A15662 = "" A15663 = "" A15664 = "" A15665 = "" A15666 = "" A15667 = "" A15668 = "" A15669 = "" A15670 = "" -A15671 = "" A15672 = "" A15673 = "" A15674 = "" A15675 = "" A15676 = "" A15677 = "" A15678 = "" A15679 = "" A15680 = "" -A15681 = "" A15682 = "" A15683 = "" A15684 = "" A15685 = "" A15686 = "" A15687 = "" A15688 = "" A15689 = "" A15690 = "" -A15691 = "" A15692 = "" A15693 = "" A15694 = "" A15695 = "" A15696 = "" A15697 = "" A15698 = "" A15699 = "" A15700 = "" -A15701 = "" A15702 = "" A15703 = "" A15704 = "" A15705 = "" A15706 = "" A15707 = "" A15708 = "" A15709 = "" A15710 = "" -A15711 = "" A15712 = "" A15713 = "" A15714 = "" A15715 = "" A15716 = "" A15717 = "" A15718 = "" A15719 = "" A15720 = "" -A15721 = "" A15722 = "" A15723 = "" A15724 = "" A15725 = "" A15726 = "" A15727 = "" A15728 = "" A15729 = "" A15730 = "" -A15731 = "" A15732 = "" A15733 = "" A15734 = "" A15735 = "" A15736 = "" A15737 = "" A15738 = "" A15739 = "" A15740 = "" -A15741 = "" A15742 = "" A15743 = "" A15744 = "" A15745 = "" A15746 = "" A15747 = "" A15748 = "" A15749 = "" A15750 = "" -A15751 = "" A15752 = "" A15753 = "" A15754 = "" A15755 = "" A15756 = "" A15757 = "" A15758 = "" A15759 = "" A15760 = "" -A15761 = "" A15762 = "" A15763 = "" A15764 = "" A15765 = "" A15766 = "" A15767 = "" A15768 = "" A15769 = "" A15770 = "" -A15771 = "" A15772 = "" A15773 = "" A15774 = "" A15775 = "" A15776 = "" A15777 = "" A15778 = "" A15779 = "" A15780 = "" -A15781 = "" A15782 = "" A15783 = "" A15784 = "" A15785 = "" A15786 = "" A15787 = "" A15788 = "" A15789 = "" A15790 = "" -A15791 = "" A15792 = "" A15793 = "" A15794 = "" A15795 = "" A15796 = "" A15797 = "" A15798 = "" A15799 = "" A15800 = "" -A15801 = "" A15802 = "" A15803 = "" A15804 = "" A15805 = "" A15806 = "" A15807 = "" A15808 = "" A15809 = "" A15810 = "" -A15811 = "" A15812 = "" A15813 = "" A15814 = "" A15815 = "" A15816 = "" A15817 = "" A15818 = "" A15819 = "" A15820 = "" -A15821 = "" A15822 = "" A15823 = "" A15824 = "" A15825 = "" A15826 = "" A15827 = "" A15828 = "" A15829 = "" A15830 = "" -A15831 = "" A15832 = "" A15833 = "" A15834 = "" A15835 = "" A15836 = "" A15837 = "" A15838 = "" A15839 = "" A15840 = "" -A15841 = "" A15842 = "" A15843 = "" A15844 = "" A15845 = "" A15846 = "" A15847 = "" A15848 = "" A15849 = "" A15850 = "" -A15851 = "" A15852 = "" A15853 = "" A15854 = "" A15855 = "" A15856 = "" A15857 = "" A15858 = "" A15859 = "" A15860 = "" -A15861 = "" A15862 = "" A15863 = "" A15864 = "" A15865 = "" A15866 = "" A15867 = "" A15868 = "" A15869 = "" A15870 = "" -A15871 = "" A15872 = "" A15873 = "" A15874 = "" A15875 = "" A15876 = "" A15877 = "" A15878 = "" A15879 = "" A15880 = "" -A15881 = "" A15882 = "" A15883 = "" A15884 = "" A15885 = "" A15886 = "" A15887 = "" A15888 = "" A15889 = "" A15890 = "" -A15891 = "" A15892 = "" A15893 = "" A15894 = "" A15895 = "" A15896 = "" A15897 = "" A15898 = "" A15899 = "" A15900 = "" -A15901 = "" A15902 = "" A15903 = "" A15904 = "" A15905 = "" A15906 = "" A15907 = "" A15908 = "" A15909 = "" A15910 = "" -A15911 = "" A15912 = "" A15913 = "" A15914 = "" A15915 = "" A15916 = "" A15917 = "" A15918 = "" A15919 = "" A15920 = "" -A15921 = "" A15922 = "" A15923 = "" A15924 = "" A15925 = "" A15926 = "" A15927 = "" A15928 = "" A15929 = "" A15930 = "" -A15931 = "" A15932 = "" A15933 = "" A15934 = "" A15935 = "" A15936 = "" A15937 = "" A15938 = "" A15939 = "" A15940 = "" -A15941 = "" A15942 = "" A15943 = "" A15944 = "" A15945 = "" A15946 = "" A15947 = "" A15948 = "" A15949 = "" A15950 = "" -A15951 = "" A15952 = "" A15953 = "" A15954 = "" A15955 = "" A15956 = "" A15957 = "" A15958 = "" A15959 = "" A15960 = "" -A15961 = "" A15962 = "" A15963 = "" A15964 = "" A15965 = "" A15966 = "" A15967 = "" A15968 = "" A15969 = "" A15970 = "" -A15971 = "" A15972 = "" A15973 = "" A15974 = "" A15975 = "" A15976 = "" A15977 = "" A15978 = "" A15979 = "" A15980 = "" -A15981 = "" A15982 = "" A15983 = "" A15984 = "" A15985 = "" A15986 = "" A15987 = "" A15988 = "" A15989 = "" A15990 = "" -A15991 = "" A15992 = "" A15993 = "" A15994 = "" A15995 = "" A15996 = "" A15997 = "" A15998 = "" A15999 = "" A16000 = "" -A16001 = "" A16002 = "" A16003 = "" A16004 = "" A16005 = "" A16006 = "" A16007 = "" A16008 = "" A16009 = "" A16010 = "" -A16011 = "" A16012 = "" A16013 = "" A16014 = "" A16015 = "" A16016 = "" A16017 = "" A16018 = "" A16019 = "" A16020 = "" -A16021 = "" A16022 = "" A16023 = "" A16024 = "" A16025 = "" A16026 = "" A16027 = "" A16028 = "" A16029 = "" A16030 = "" -A16031 = "" A16032 = "" A16033 = "" A16034 = "" A16035 = "" A16036 = "" A16037 = "" A16038 = "" A16039 = "" A16040 = "" -A16041 = "" A16042 = "" A16043 = "" A16044 = "" A16045 = "" A16046 = "" A16047 = "" A16048 = "" A16049 = "" A16050 = "" -A16051 = "" A16052 = "" A16053 = "" A16054 = "" A16055 = "" A16056 = "" A16057 = "" A16058 = "" A16059 = "" A16060 = "" -A16061 = "" A16062 = "" A16063 = "" A16064 = "" A16065 = "" A16066 = "" A16067 = "" A16068 = "" A16069 = "" A16070 = "" -A16071 = "" A16072 = "" A16073 = "" A16074 = "" A16075 = "" A16076 = "" A16077 = "" A16078 = "" A16079 = "" A16080 = "" -A16081 = "" A16082 = "" A16083 = "" A16084 = "" A16085 = "" A16086 = "" A16087 = "" A16088 = "" A16089 = "" A16090 = "" -A16091 = "" A16092 = "" A16093 = "" A16094 = "" A16095 = "" A16096 = "" A16097 = "" A16098 = "" A16099 = "" A16100 = "" -A16101 = "" A16102 = "" A16103 = "" A16104 = "" A16105 = "" A16106 = "" A16107 = "" A16108 = "" A16109 = "" A16110 = "" -A16111 = "" A16112 = "" A16113 = "" A16114 = "" A16115 = "" A16116 = "" A16117 = "" A16118 = "" A16119 = "" A16120 = "" -A16121 = "" A16122 = "" A16123 = "" A16124 = "" A16125 = "" A16126 = "" A16127 = "" A16128 = "" A16129 = "" A16130 = "" -A16131 = "" A16132 = "" A16133 = "" A16134 = "" A16135 = "" A16136 = "" A16137 = "" A16138 = "" A16139 = "" A16140 = "" -A16141 = "" A16142 = "" A16143 = "" A16144 = "" A16145 = "" A16146 = "" A16147 = "" A16148 = "" A16149 = "" A16150 = "" -A16151 = "" A16152 = "" A16153 = "" A16154 = "" A16155 = "" A16156 = "" A16157 = "" A16158 = "" A16159 = "" A16160 = "" -A16161 = "" A16162 = "" A16163 = "" A16164 = "" A16165 = "" A16166 = "" A16167 = "" A16168 = "" A16169 = "" A16170 = "" -A16171 = "" A16172 = "" A16173 = "" A16174 = "" A16175 = "" A16176 = "" A16177 = "" A16178 = "" A16179 = "" A16180 = "" -A16181 = "" A16182 = "" A16183 = "" A16184 = "" A16185 = "" A16186 = "" A16187 = "" A16188 = "" A16189 = "" A16190 = "" -A16191 = "" A16192 = "" A16193 = "" A16194 = "" A16195 = "" A16196 = "" A16197 = "" A16198 = "" A16199 = "" A16200 = "" -A16201 = "" A16202 = "" A16203 = "" A16204 = "" A16205 = "" A16206 = "" A16207 = "" A16208 = "" A16209 = "" A16210 = "" -A16211 = "" A16212 = "" A16213 = "" A16214 = "" A16215 = "" A16216 = "" A16217 = "" A16218 = "" A16219 = "" A16220 = "" -A16221 = "" A16222 = "" A16223 = "" A16224 = "" A16225 = "" A16226 = "" A16227 = "" A16228 = "" A16229 = "" A16230 = "" -A16231 = "" A16232 = "" A16233 = "" A16234 = "" A16235 = "" A16236 = "" A16237 = "" A16238 = "" A16239 = "" A16240 = "" -A16241 = "" A16242 = "" A16243 = "" A16244 = "" A16245 = "" A16246 = "" A16247 = "" A16248 = "" A16249 = "" A16250 = "" -A16251 = "" A16252 = "" A16253 = "" A16254 = "" A16255 = "" A16256 = "" A16257 = "" A16258 = "" A16259 = "" A16260 = "" -A16261 = "" A16262 = "" A16263 = "" A16264 = "" A16265 = "" A16266 = "" A16267 = "" A16268 = "" A16269 = "" A16270 = "" -A16271 = "" A16272 = "" A16273 = "" A16274 = "" A16275 = "" A16276 = "" A16277 = "" A16278 = "" A16279 = "" A16280 = "" -A16281 = "" A16282 = "" A16283 = "" A16284 = "" A16285 = "" A16286 = "" A16287 = "" A16288 = "" A16289 = "" A16290 = "" -A16291 = "" A16292 = "" A16293 = "" A16294 = "" A16295 = "" A16296 = "" A16297 = "" A16298 = "" A16299 = "" A16300 = "" -A16301 = "" A16302 = "" A16303 = "" A16304 = "" A16305 = "" A16306 = "" A16307 = "" A16308 = "" A16309 = "" A16310 = "" -A16311 = "" A16312 = "" A16313 = "" A16314 = "" A16315 = "" A16316 = "" A16317 = "" A16318 = "" A16319 = "" A16320 = "" -A16321 = "" A16322 = "" A16323 = "" A16324 = "" A16325 = "" A16326 = "" A16327 = "" A16328 = "" A16329 = "" A16330 = "" -A16331 = "" A16332 = "" A16333 = "" A16334 = "" A16335 = "" A16336 = "" A16337 = "" A16338 = "" A16339 = "" A16340 = "" -A16341 = "" A16342 = "" A16343 = "" A16344 = "" A16345 = "" A16346 = "" A16347 = "" A16348 = "" A16349 = "" A16350 = "" -A16351 = "" A16352 = "" A16353 = "" A16354 = "" A16355 = "" A16356 = "" A16357 = "" A16358 = "" A16359 = "" A16360 = "" -A16361 = "" A16362 = "" A16363 = "" A16364 = "" A16365 = "" A16366 = "" A16367 = "" A16368 = "" A16369 = "" A16370 = "" -A16371 = "" A16372 = "" A16373 = "" A16374 = "" A16375 = "" A16376 = "" A16377 = "" A16378 = "" A16379 = "" A16380 = "" -A16381 = "" A16382 = "" A16383 = "" A16384 = "" A16385 = "" A16386 = "" A16387 = "" A16388 = "" A16389 = "" A16390 = "" -A16391 = "" A16392 = "" A16393 = "" A16394 = "" A16395 = "" A16396 = "" A16397 = "" A16398 = "" A16399 = "" A16400 = "" -A16401 = "" A16402 = "" A16403 = "" A16404 = "" A16405 = "" A16406 = "" A16407 = "" A16408 = "" A16409 = "" A16410 = "" -A16411 = "" A16412 = "" A16413 = "" A16414 = "" A16415 = "" A16416 = "" A16417 = "" A16418 = "" A16419 = "" A16420 = "" -A16421 = "" A16422 = "" A16423 = "" A16424 = "" A16425 = "" A16426 = "" A16427 = "" A16428 = "" A16429 = "" A16430 = "" -A16431 = "" A16432 = "" A16433 = "" A16434 = "" A16435 = "" A16436 = "" A16437 = "" A16438 = "" A16439 = "" A16440 = "" -A16441 = "" A16442 = "" A16443 = "" A16444 = "" A16445 = "" A16446 = "" A16447 = "" A16448 = "" A16449 = "" A16450 = "" -A16451 = "" A16452 = "" A16453 = "" A16454 = "" A16455 = "" A16456 = "" A16457 = "" A16458 = "" A16459 = "" A16460 = "" -A16461 = "" A16462 = "" A16463 = "" A16464 = "" A16465 = "" A16466 = "" A16467 = "" A16468 = "" A16469 = "" A16470 = "" -A16471 = "" A16472 = "" A16473 = "" A16474 = "" A16475 = "" A16476 = "" A16477 = "" A16478 = "" A16479 = "" A16480 = "" -A16481 = "" A16482 = "" A16483 = "" A16484 = "" A16485 = "" A16486 = "" A16487 = "" A16488 = "" A16489 = "" A16490 = "" -A16491 = "" A16492 = "" A16493 = "" A16494 = "" A16495 = "" A16496 = "" A16497 = "" A16498 = "" A16499 = "" A16500 = "" -A16501 = "" A16502 = "" A16503 = "" A16504 = "" A16505 = "" A16506 = "" A16507 = "" A16508 = "" A16509 = "" A16510 = "" -A16511 = "" A16512 = "" A16513 = "" A16514 = "" A16515 = "" A16516 = "" A16517 = "" A16518 = "" A16519 = "" A16520 = "" -A16521 = "" A16522 = "" A16523 = "" A16524 = "" A16525 = "" A16526 = "" A16527 = "" A16528 = "" A16529 = "" A16530 = "" -A16531 = "" A16532 = "" A16533 = "" A16534 = "" A16535 = "" A16536 = "" A16537 = "" A16538 = "" A16539 = "" A16540 = "" -A16541 = "" A16542 = "" A16543 = "" A16544 = "" A16545 = "" A16546 = "" A16547 = "" A16548 = "" A16549 = "" A16550 = "" -A16551 = "" A16552 = "" A16553 = "" A16554 = "" A16555 = "" A16556 = "" A16557 = "" A16558 = "" A16559 = "" A16560 = "" -A16561 = "" A16562 = "" A16563 = "" A16564 = "" A16565 = "" A16566 = "" A16567 = "" A16568 = "" A16569 = "" A16570 = "" -A16571 = "" A16572 = "" A16573 = "" A16574 = "" A16575 = "" A16576 = "" A16577 = "" A16578 = "" A16579 = "" A16580 = "" -A16581 = "" A16582 = "" A16583 = "" A16584 = "" A16585 = "" A16586 = "" A16587 = "" A16588 = "" A16589 = "" A16590 = "" -A16591 = "" A16592 = "" A16593 = "" A16594 = "" A16595 = "" A16596 = "" A16597 = "" A16598 = "" A16599 = "" A16600 = "" -A16601 = "" A16602 = "" A16603 = "" A16604 = "" A16605 = "" A16606 = "" A16607 = "" A16608 = "" A16609 = "" A16610 = "" -A16611 = "" A16612 = "" A16613 = "" A16614 = "" A16615 = "" A16616 = "" A16617 = "" A16618 = "" A16619 = "" A16620 = "" -A16621 = "" A16622 = "" A16623 = "" A16624 = "" A16625 = "" A16626 = "" A16627 = "" A16628 = "" A16629 = "" A16630 = "" -A16631 = "" A16632 = "" A16633 = "" A16634 = "" A16635 = "" A16636 = "" A16637 = "" A16638 = "" A16639 = "" A16640 = "" -A16641 = "" A16642 = "" A16643 = "" A16644 = "" A16645 = "" A16646 = "" A16647 = "" A16648 = "" A16649 = "" A16650 = "" -A16651 = "" A16652 = "" A16653 = "" A16654 = "" A16655 = "" A16656 = "" A16657 = "" A16658 = "" A16659 = "" A16660 = "" -A16661 = "" A16662 = "" A16663 = "" A16664 = "" A16665 = "" A16666 = "" A16667 = "" A16668 = "" A16669 = "" A16670 = "" -A16671 = "" A16672 = "" A16673 = "" A16674 = "" A16675 = "" A16676 = "" A16677 = "" A16678 = "" A16679 = "" A16680 = "" -A16681 = "" A16682 = "" A16683 = "" A16684 = "" A16685 = "" A16686 = "" A16687 = "" A16688 = "" A16689 = "" A16690 = "" -A16691 = "" A16692 = "" A16693 = "" A16694 = "" A16695 = "" A16696 = "" A16697 = "" A16698 = "" A16699 = "" A16700 = "" -A16701 = "" A16702 = "" A16703 = "" A16704 = "" A16705 = "" A16706 = "" A16707 = "" A16708 = "" A16709 = "" A16710 = "" -A16711 = "" A16712 = "" A16713 = "" A16714 = "" A16715 = "" A16716 = "" A16717 = "" A16718 = "" A16719 = "" A16720 = "" -A16721 = "" A16722 = "" A16723 = "" A16724 = "" A16725 = "" A16726 = "" A16727 = "" A16728 = "" A16729 = "" A16730 = "" -A16731 = "" A16732 = "" A16733 = "" A16734 = "" A16735 = "" A16736 = "" A16737 = "" A16738 = "" A16739 = "" A16740 = "" -A16741 = "" A16742 = "" A16743 = "" A16744 = "" A16745 = "" A16746 = "" A16747 = "" A16748 = "" A16749 = "" A16750 = "" -A16751 = "" A16752 = "" A16753 = "" A16754 = "" A16755 = "" A16756 = "" A16757 = "" A16758 = "" A16759 = "" A16760 = "" -A16761 = "" A16762 = "" A16763 = "" A16764 = "" A16765 = "" A16766 = "" A16767 = "" A16768 = "" A16769 = "" A16770 = "" -A16771 = "" A16772 = "" A16773 = "" A16774 = "" A16775 = "" A16776 = "" A16777 = "" A16778 = "" A16779 = "" A16780 = "" -A16781 = "" A16782 = "" A16783 = "" A16784 = "" A16785 = "" A16786 = "" A16787 = "" A16788 = "" A16789 = "" A16790 = "" -A16791 = "" A16792 = "" A16793 = "" A16794 = "" A16795 = "" A16796 = "" A16797 = "" A16798 = "" A16799 = "" A16800 = "" -A16801 = "" A16802 = "" A16803 = "" A16804 = "" A16805 = "" A16806 = "" A16807 = "" A16808 = "" A16809 = "" A16810 = "" -A16811 = "" A16812 = "" A16813 = "" A16814 = "" A16815 = "" A16816 = "" A16817 = "" A16818 = "" A16819 = "" A16820 = "" -A16821 = "" A16822 = "" A16823 = "" A16824 = "" A16825 = "" A16826 = "" A16827 = "" A16828 = "" A16829 = "" A16830 = "" -A16831 = "" A16832 = "" A16833 = "" A16834 = "" A16835 = "" A16836 = "" A16837 = "" A16838 = "" A16839 = "" A16840 = "" -A16841 = "" A16842 = "" A16843 = "" A16844 = "" A16845 = "" A16846 = "" A16847 = "" A16848 = "" A16849 = "" A16850 = "" -A16851 = "" A16852 = "" A16853 = "" A16854 = "" A16855 = "" A16856 = "" A16857 = "" A16858 = "" A16859 = "" A16860 = "" -A16861 = "" A16862 = "" A16863 = "" A16864 = "" A16865 = "" A16866 = "" A16867 = "" A16868 = "" A16869 = "" A16870 = "" -A16871 = "" A16872 = "" A16873 = "" A16874 = "" A16875 = "" A16876 = "" A16877 = "" A16878 = "" A16879 = "" A16880 = "" -A16881 = "" A16882 = "" A16883 = "" A16884 = "" A16885 = "" A16886 = "" A16887 = "" A16888 = "" A16889 = "" A16890 = "" -A16891 = "" A16892 = "" A16893 = "" A16894 = "" A16895 = "" A16896 = "" A16897 = "" A16898 = "" A16899 = "" A16900 = "" -A16901 = "" A16902 = "" A16903 = "" A16904 = "" A16905 = "" A16906 = "" A16907 = "" A16908 = "" A16909 = "" A16910 = "" -A16911 = "" A16912 = "" A16913 = "" A16914 = "" A16915 = "" A16916 = "" A16917 = "" A16918 = "" A16919 = "" A16920 = "" -A16921 = "" A16922 = "" A16923 = "" A16924 = "" A16925 = "" A16926 = "" A16927 = "" A16928 = "" A16929 = "" A16930 = "" -A16931 = "" A16932 = "" A16933 = "" A16934 = "" A16935 = "" A16936 = "" A16937 = "" A16938 = "" A16939 = "" A16940 = "" -A16941 = "" A16942 = "" A16943 = "" A16944 = "" A16945 = "" A16946 = "" A16947 = "" A16948 = "" A16949 = "" A16950 = "" -A16951 = "" A16952 = "" A16953 = "" A16954 = "" A16955 = "" A16956 = "" A16957 = "" A16958 = "" A16959 = "" A16960 = "" -A16961 = "" A16962 = "" A16963 = "" A16964 = "" A16965 = "" A16966 = "" A16967 = "" A16968 = "" A16969 = "" A16970 = "" -A16971 = "" A16972 = "" A16973 = "" A16974 = "" A16975 = "" A16976 = "" A16977 = "" A16978 = "" A16979 = "" A16980 = "" -A16981 = "" A16982 = "" A16983 = "" A16984 = "" A16985 = "" A16986 = "" A16987 = "" A16988 = "" A16989 = "" A16990 = "" -A16991 = "" A16992 = "" A16993 = "" A16994 = "" A16995 = "" A16996 = "" A16997 = "" A16998 = "" A16999 = "" A17000 = "" -A17001 = "" A17002 = "" A17003 = "" A17004 = "" A17005 = "" A17006 = "" A17007 = "" A17008 = "" A17009 = "" A17010 = "" -A17011 = "" A17012 = "" A17013 = "" A17014 = "" A17015 = "" A17016 = "" A17017 = "" A17018 = "" A17019 = "" A17020 = "" -A17021 = "" A17022 = "" A17023 = "" A17024 = "" A17025 = "" A17026 = "" A17027 = "" A17028 = "" A17029 = "" A17030 = "" -A17031 = "" A17032 = "" A17033 = "" A17034 = "" A17035 = "" A17036 = "" A17037 = "" A17038 = "" A17039 = "" A17040 = "" -A17041 = "" A17042 = "" A17043 = "" A17044 = "" A17045 = "" A17046 = "" A17047 = "" A17048 = "" A17049 = "" A17050 = "" -A17051 = "" A17052 = "" A17053 = "" A17054 = "" A17055 = "" A17056 = "" A17057 = "" A17058 = "" A17059 = "" A17060 = "" -A17061 = "" A17062 = "" A17063 = "" A17064 = "" A17065 = "" A17066 = "" A17067 = "" A17068 = "" A17069 = "" A17070 = "" -A17071 = "" A17072 = "" A17073 = "" A17074 = "" A17075 = "" A17076 = "" A17077 = "" A17078 = "" A17079 = "" A17080 = "" -A17081 = "" A17082 = "" A17083 = "" A17084 = "" A17085 = "" A17086 = "" A17087 = "" A17088 = "" A17089 = "" A17090 = "" -A17091 = "" A17092 = "" A17093 = "" A17094 = "" A17095 = "" A17096 = "" A17097 = "" A17098 = "" A17099 = "" A17100 = "" -A17101 = "" A17102 = "" A17103 = "" A17104 = "" A17105 = "" A17106 = "" A17107 = "" A17108 = "" A17109 = "" A17110 = "" -A17111 = "" A17112 = "" A17113 = "" A17114 = "" A17115 = "" A17116 = "" A17117 = "" A17118 = "" A17119 = "" A17120 = "" -A17121 = "" A17122 = "" A17123 = "" A17124 = "" A17125 = "" A17126 = "" A17127 = "" A17128 = "" A17129 = "" A17130 = "" -A17131 = "" A17132 = "" A17133 = "" A17134 = "" A17135 = "" A17136 = "" A17137 = "" A17138 = "" A17139 = "" A17140 = "" -A17141 = "" A17142 = "" A17143 = "" A17144 = "" A17145 = "" A17146 = "" A17147 = "" A17148 = "" A17149 = "" A17150 = "" -A17151 = "" A17152 = "" A17153 = "" A17154 = "" A17155 = "" A17156 = "" A17157 = "" A17158 = "" A17159 = "" A17160 = "" -A17161 = "" A17162 = "" A17163 = "" A17164 = "" A17165 = "" A17166 = "" A17167 = "" A17168 = "" A17169 = "" A17170 = "" -A17171 = "" A17172 = "" A17173 = "" A17174 = "" A17175 = "" A17176 = "" A17177 = "" A17178 = "" A17179 = "" A17180 = "" -A17181 = "" A17182 = "" A17183 = "" A17184 = "" A17185 = "" A17186 = "" A17187 = "" A17188 = "" A17189 = "" A17190 = "" -A17191 = "" A17192 = "" A17193 = "" A17194 = "" A17195 = "" A17196 = "" A17197 = "" A17198 = "" A17199 = "" A17200 = "" -A17201 = "" A17202 = "" A17203 = "" A17204 = "" A17205 = "" A17206 = "" A17207 = "" A17208 = "" A17209 = "" A17210 = "" -A17211 = "" A17212 = "" A17213 = "" A17214 = "" A17215 = "" A17216 = "" A17217 = "" A17218 = "" A17219 = "" A17220 = "" -A17221 = "" A17222 = "" A17223 = "" A17224 = "" A17225 = "" A17226 = "" A17227 = "" A17228 = "" A17229 = "" A17230 = "" -A17231 = "" A17232 = "" A17233 = "" A17234 = "" A17235 = "" A17236 = "" A17237 = "" A17238 = "" A17239 = "" A17240 = "" -A17241 = "" A17242 = "" A17243 = "" A17244 = "" A17245 = "" A17246 = "" A17247 = "" A17248 = "" A17249 = "" A17250 = "" -A17251 = "" A17252 = "" A17253 = "" A17254 = "" A17255 = "" A17256 = "" A17257 = "" A17258 = "" A17259 = "" A17260 = "" -A17261 = "" A17262 = "" A17263 = "" A17264 = "" A17265 = "" A17266 = "" A17267 = "" A17268 = "" A17269 = "" A17270 = "" -A17271 = "" A17272 = "" A17273 = "" A17274 = "" A17275 = "" A17276 = "" A17277 = "" A17278 = "" A17279 = "" A17280 = "" -A17281 = "" A17282 = "" A17283 = "" A17284 = "" A17285 = "" A17286 = "" A17287 = "" A17288 = "" A17289 = "" A17290 = "" -A17291 = "" A17292 = "" A17293 = "" A17294 = "" A17295 = "" A17296 = "" A17297 = "" A17298 = "" A17299 = "" A17300 = "" -A17301 = "" A17302 = "" A17303 = "" A17304 = "" A17305 = "" A17306 = "" A17307 = "" A17308 = "" A17309 = "" A17310 = "" -A17311 = "" A17312 = "" A17313 = "" A17314 = "" A17315 = "" A17316 = "" A17317 = "" A17318 = "" A17319 = "" A17320 = "" -A17321 = "" A17322 = "" A17323 = "" A17324 = "" A17325 = "" A17326 = "" A17327 = "" A17328 = "" A17329 = "" A17330 = "" -A17331 = "" A17332 = "" A17333 = "" A17334 = "" A17335 = "" A17336 = "" A17337 = "" A17338 = "" A17339 = "" A17340 = "" -A17341 = "" A17342 = "" A17343 = "" A17344 = "" A17345 = "" A17346 = "" A17347 = "" A17348 = "" A17349 = "" A17350 = "" -A17351 = "" A17352 = "" A17353 = "" A17354 = "" A17355 = "" A17356 = "" A17357 = "" A17358 = "" A17359 = "" A17360 = "" -A17361 = "" A17362 = "" A17363 = "" A17364 = "" A17365 = "" A17366 = "" A17367 = "" A17368 = "" A17369 = "" A17370 = "" -A17371 = "" A17372 = "" A17373 = "" A17374 = "" A17375 = "" A17376 = "" A17377 = "" A17378 = "" A17379 = "" A17380 = "" -A17381 = "" A17382 = "" A17383 = "" A17384 = "" A17385 = "" A17386 = "" A17387 = "" A17388 = "" A17389 = "" A17390 = "" -A17391 = "" A17392 = "" A17393 = "" A17394 = "" A17395 = "" A17396 = "" A17397 = "" A17398 = "" A17399 = "" A17400 = "" -A17401 = "" A17402 = "" A17403 = "" A17404 = "" A17405 = "" A17406 = "" A17407 = "" A17408 = "" A17409 = "" A17410 = "" -A17411 = "" A17412 = "" A17413 = "" A17414 = "" A17415 = "" A17416 = "" A17417 = "" A17418 = "" A17419 = "" A17420 = "" -A17421 = "" A17422 = "" A17423 = "" A17424 = "" A17425 = "" A17426 = "" A17427 = "" A17428 = "" A17429 = "" A17430 = "" -A17431 = "" A17432 = "" A17433 = "" A17434 = "" A17435 = "" A17436 = "" A17437 = "" A17438 = "" A17439 = "" A17440 = "" -A17441 = "" A17442 = "" A17443 = "" A17444 = "" A17445 = "" A17446 = "" A17447 = "" A17448 = "" A17449 = "" A17450 = "" -A17451 = "" A17452 = "" A17453 = "" A17454 = "" A17455 = "" A17456 = "" A17457 = "" A17458 = "" A17459 = "" A17460 = "" -A17461 = "" A17462 = "" A17463 = "" A17464 = "" A17465 = "" A17466 = "" A17467 = "" A17468 = "" A17469 = "" A17470 = "" -A17471 = "" A17472 = "" A17473 = "" A17474 = "" A17475 = "" A17476 = "" A17477 = "" A17478 = "" A17479 = "" A17480 = "" -A17481 = "" A17482 = "" A17483 = "" A17484 = "" A17485 = "" A17486 = "" A17487 = "" A17488 = "" A17489 = "" A17490 = "" -A17491 = "" A17492 = "" A17493 = "" A17494 = "" A17495 = "" A17496 = "" A17497 = "" A17498 = "" A17499 = "" A17500 = "" -A17501 = "" A17502 = "" A17503 = "" A17504 = "" A17505 = "" A17506 = "" A17507 = "" A17508 = "" A17509 = "" A17510 = "" -A17511 = "" A17512 = "" A17513 = "" A17514 = "" A17515 = "" A17516 = "" A17517 = "" A17518 = "" A17519 = "" A17520 = "" -A17521 = "" A17522 = "" A17523 = "" A17524 = "" A17525 = "" A17526 = "" A17527 = "" A17528 = "" A17529 = "" A17530 = "" -A17531 = "" A17532 = "" A17533 = "" A17534 = "" A17535 = "" A17536 = "" A17537 = "" A17538 = "" A17539 = "" A17540 = "" -A17541 = "" A17542 = "" A17543 = "" A17544 = "" A17545 = "" A17546 = "" A17547 = "" A17548 = "" A17549 = "" A17550 = "" -A17551 = "" A17552 = "" A17553 = "" A17554 = "" A17555 = "" A17556 = "" A17557 = "" A17558 = "" A17559 = "" A17560 = "" -A17561 = "" A17562 = "" A17563 = "" A17564 = "" A17565 = "" A17566 = "" A17567 = "" A17568 = "" A17569 = "" A17570 = "" -A17571 = "" A17572 = "" A17573 = "" A17574 = "" A17575 = "" A17576 = "" A17577 = "" A17578 = "" A17579 = "" A17580 = "" -A17581 = "" A17582 = "" A17583 = "" A17584 = "" A17585 = "" A17586 = "" A17587 = "" A17588 = "" A17589 = "" A17590 = "" -A17591 = "" A17592 = "" A17593 = "" A17594 = "" A17595 = "" A17596 = "" A17597 = "" A17598 = "" A17599 = "" A17600 = "" -A17601 = "" A17602 = "" A17603 = "" A17604 = "" A17605 = "" A17606 = "" A17607 = "" A17608 = "" A17609 = "" A17610 = "" -A17611 = "" A17612 = "" A17613 = "" A17614 = "" A17615 = "" A17616 = "" A17617 = "" A17618 = "" A17619 = "" A17620 = "" -A17621 = "" A17622 = "" A17623 = "" A17624 = "" A17625 = "" A17626 = "" A17627 = "" A17628 = "" A17629 = "" A17630 = "" -A17631 = "" A17632 = "" A17633 = "" A17634 = "" A17635 = "" A17636 = "" A17637 = "" A17638 = "" A17639 = "" A17640 = "" -A17641 = "" A17642 = "" A17643 = "" A17644 = "" A17645 = "" A17646 = "" A17647 = "" A17648 = "" A17649 = "" A17650 = "" -A17651 = "" A17652 = "" A17653 = "" A17654 = "" A17655 = "" A17656 = "" A17657 = "" A17658 = "" A17659 = "" A17660 = "" -A17661 = "" A17662 = "" A17663 = "" A17664 = "" A17665 = "" A17666 = "" A17667 = "" A17668 = "" A17669 = "" A17670 = "" -A17671 = "" A17672 = "" A17673 = "" A17674 = "" A17675 = "" A17676 = "" A17677 = "" A17678 = "" A17679 = "" A17680 = "" -A17681 = "" A17682 = "" A17683 = "" A17684 = "" A17685 = "" A17686 = "" A17687 = "" A17688 = "" A17689 = "" A17690 = "" -A17691 = "" A17692 = "" A17693 = "" A17694 = "" A17695 = "" A17696 = "" A17697 = "" A17698 = "" A17699 = "" A17700 = "" -A17701 = "" A17702 = "" A17703 = "" A17704 = "" A17705 = "" A17706 = "" A17707 = "" A17708 = "" A17709 = "" A17710 = "" -A17711 = "" A17712 = "" A17713 = "" A17714 = "" A17715 = "" A17716 = "" A17717 = "" A17718 = "" A17719 = "" A17720 = "" -A17721 = "" A17722 = "" A17723 = "" A17724 = "" A17725 = "" A17726 = "" A17727 = "" A17728 = "" A17729 = "" A17730 = "" -A17731 = "" A17732 = "" A17733 = "" A17734 = "" A17735 = "" A17736 = "" A17737 = "" A17738 = "" A17739 = "" A17740 = "" -A17741 = "" A17742 = "" A17743 = "" A17744 = "" A17745 = "" A17746 = "" A17747 = "" A17748 = "" A17749 = "" A17750 = "" -A17751 = "" A17752 = "" A17753 = "" A17754 = "" A17755 = "" A17756 = "" A17757 = "" A17758 = "" A17759 = "" A17760 = "" -A17761 = "" A17762 = "" A17763 = "" A17764 = "" A17765 = "" A17766 = "" A17767 = "" A17768 = "" A17769 = "" A17770 = "" -A17771 = "" A17772 = "" A17773 = "" A17774 = "" A17775 = "" A17776 = "" A17777 = "" A17778 = "" A17779 = "" A17780 = "" -A17781 = "" A17782 = "" A17783 = "" A17784 = "" A17785 = "" A17786 = "" A17787 = "" A17788 = "" A17789 = "" A17790 = "" -A17791 = "" A17792 = "" A17793 = "" A17794 = "" A17795 = "" A17796 = "" A17797 = "" A17798 = "" A17799 = "" A17800 = "" -A17801 = "" A17802 = "" A17803 = "" A17804 = "" A17805 = "" A17806 = "" A17807 = "" A17808 = "" A17809 = "" A17810 = "" -A17811 = "" A17812 = "" A17813 = "" A17814 = "" A17815 = "" A17816 = "" A17817 = "" A17818 = "" A17819 = "" A17820 = "" -A17821 = "" A17822 = "" A17823 = "" A17824 = "" A17825 = "" A17826 = "" A17827 = "" A17828 = "" A17829 = "" A17830 = "" -A17831 = "" A17832 = "" A17833 = "" A17834 = "" A17835 = "" A17836 = "" A17837 = "" A17838 = "" A17839 = "" A17840 = "" -A17841 = "" A17842 = "" A17843 = "" A17844 = "" A17845 = "" A17846 = "" A17847 = "" A17848 = "" A17849 = "" A17850 = "" -A17851 = "" A17852 = "" A17853 = "" A17854 = "" A17855 = "" A17856 = "" A17857 = "" A17858 = "" A17859 = "" A17860 = "" -A17861 = "" A17862 = "" A17863 = "" A17864 = "" A17865 = "" A17866 = "" A17867 = "" A17868 = "" A17869 = "" A17870 = "" -A17871 = "" A17872 = "" A17873 = "" A17874 = "" A17875 = "" A17876 = "" A17877 = "" A17878 = "" A17879 = "" A17880 = "" -A17881 = "" A17882 = "" A17883 = "" A17884 = "" A17885 = "" A17886 = "" A17887 = "" A17888 = "" A17889 = "" A17890 = "" -A17891 = "" A17892 = "" A17893 = "" A17894 = "" A17895 = "" A17896 = "" A17897 = "" A17898 = "" A17899 = "" A17900 = "" -A17901 = "" A17902 = "" A17903 = "" A17904 = "" A17905 = "" A17906 = "" A17907 = "" A17908 = "" A17909 = "" A17910 = "" -A17911 = "" A17912 = "" A17913 = "" A17914 = "" A17915 = "" A17916 = "" A17917 = "" A17918 = "" A17919 = "" A17920 = "" -A17921 = "" A17922 = "" A17923 = "" A17924 = "" A17925 = "" A17926 = "" A17927 = "" A17928 = "" A17929 = "" A17930 = "" -A17931 = "" A17932 = "" A17933 = "" A17934 = "" A17935 = "" A17936 = "" A17937 = "" A17938 = "" A17939 = "" A17940 = "" -A17941 = "" A17942 = "" A17943 = "" A17944 = "" A17945 = "" A17946 = "" A17947 = "" A17948 = "" A17949 = "" A17950 = "" -A17951 = "" A17952 = "" A17953 = "" A17954 = "" A17955 = "" A17956 = "" A17957 = "" A17958 = "" A17959 = "" A17960 = "" -A17961 = "" A17962 = "" A17963 = "" A17964 = "" A17965 = "" A17966 = "" A17967 = "" A17968 = "" A17969 = "" A17970 = "" -A17971 = "" A17972 = "" A17973 = "" A17974 = "" A17975 = "" A17976 = "" A17977 = "" A17978 = "" A17979 = "" A17980 = "" -A17981 = "" A17982 = "" A17983 = "" A17984 = "" A17985 = "" A17986 = "" A17987 = "" A17988 = "" A17989 = "" A17990 = "" -A17991 = "" A17992 = "" A17993 = "" A17994 = "" A17995 = "" A17996 = "" A17997 = "" A17998 = "" A17999 = "" A18000 = "" -A18001 = "" A18002 = "" A18003 = "" A18004 = "" A18005 = "" A18006 = "" A18007 = "" A18008 = "" A18009 = "" A18010 = "" -A18011 = "" A18012 = "" A18013 = "" A18014 = "" A18015 = "" A18016 = "" A18017 = "" A18018 = "" A18019 = "" A18020 = "" -A18021 = "" A18022 = "" A18023 = "" A18024 = "" A18025 = "" A18026 = "" A18027 = "" A18028 = "" A18029 = "" A18030 = "" -A18031 = "" A18032 = "" A18033 = "" A18034 = "" A18035 = "" A18036 = "" A18037 = "" A18038 = "" A18039 = "" A18040 = "" -A18041 = "" A18042 = "" A18043 = "" A18044 = "" A18045 = "" A18046 = "" A18047 = "" A18048 = "" A18049 = "" A18050 = "" -A18051 = "" A18052 = "" A18053 = "" A18054 = "" A18055 = "" A18056 = "" A18057 = "" A18058 = "" A18059 = "" A18060 = "" -A18061 = "" A18062 = "" A18063 = "" A18064 = "" A18065 = "" A18066 = "" A18067 = "" A18068 = "" A18069 = "" A18070 = "" -A18071 = "" A18072 = "" A18073 = "" A18074 = "" A18075 = "" A18076 = "" A18077 = "" A18078 = "" A18079 = "" A18080 = "" -A18081 = "" A18082 = "" A18083 = "" A18084 = "" A18085 = "" A18086 = "" A18087 = "" A18088 = "" A18089 = "" A18090 = "" -A18091 = "" A18092 = "" A18093 = "" A18094 = "" A18095 = "" A18096 = "" A18097 = "" A18098 = "" A18099 = "" A18100 = "" -A18101 = "" A18102 = "" A18103 = "" A18104 = "" A18105 = "" A18106 = "" A18107 = "" A18108 = "" A18109 = "" A18110 = "" -A18111 = "" A18112 = "" A18113 = "" A18114 = "" A18115 = "" A18116 = "" A18117 = "" A18118 = "" A18119 = "" A18120 = "" -A18121 = "" A18122 = "" A18123 = "" A18124 = "" A18125 = "" A18126 = "" A18127 = "" A18128 = "" A18129 = "" A18130 = "" -A18131 = "" A18132 = "" A18133 = "" A18134 = "" A18135 = "" A18136 = "" A18137 = "" A18138 = "" A18139 = "" A18140 = "" -A18141 = "" A18142 = "" A18143 = "" A18144 = "" A18145 = "" A18146 = "" A18147 = "" A18148 = "" A18149 = "" A18150 = "" -A18151 = "" A18152 = "" A18153 = "" A18154 = "" A18155 = "" A18156 = "" A18157 = "" A18158 = "" A18159 = "" A18160 = "" -A18161 = "" A18162 = "" A18163 = "" A18164 = "" A18165 = "" A18166 = "" A18167 = "" A18168 = "" A18169 = "" A18170 = "" -A18171 = "" A18172 = "" A18173 = "" A18174 = "" A18175 = "" A18176 = "" A18177 = "" A18178 = "" A18179 = "" A18180 = "" -A18181 = "" A18182 = "" A18183 = "" A18184 = "" A18185 = "" A18186 = "" A18187 = "" A18188 = "" A18189 = "" A18190 = "" -A18191 = "" A18192 = "" A18193 = "" A18194 = "" A18195 = "" A18196 = "" A18197 = "" A18198 = "" A18199 = "" A18200 = "" -A18201 = "" A18202 = "" A18203 = "" A18204 = "" A18205 = "" A18206 = "" A18207 = "" A18208 = "" A18209 = "" A18210 = "" -A18211 = "" A18212 = "" A18213 = "" A18214 = "" A18215 = "" A18216 = "" A18217 = "" A18218 = "" A18219 = "" A18220 = "" -A18221 = "" A18222 = "" A18223 = "" A18224 = "" A18225 = "" A18226 = "" A18227 = "" A18228 = "" A18229 = "" A18230 = "" -A18231 = "" A18232 = "" A18233 = "" A18234 = "" A18235 = "" A18236 = "" A18237 = "" A18238 = "" A18239 = "" A18240 = "" -A18241 = "" A18242 = "" A18243 = "" A18244 = "" A18245 = "" A18246 = "" A18247 = "" A18248 = "" A18249 = "" A18250 = "" -A18251 = "" A18252 = "" A18253 = "" A18254 = "" A18255 = "" A18256 = "" A18257 = "" A18258 = "" A18259 = "" A18260 = "" -A18261 = "" A18262 = "" A18263 = "" A18264 = "" A18265 = "" A18266 = "" A18267 = "" A18268 = "" A18269 = "" A18270 = "" -A18271 = "" A18272 = "" A18273 = "" A18274 = "" A18275 = "" A18276 = "" A18277 = "" A18278 = "" A18279 = "" A18280 = "" -A18281 = "" A18282 = "" A18283 = "" A18284 = "" A18285 = "" A18286 = "" A18287 = "" A18288 = "" A18289 = "" A18290 = "" -A18291 = "" A18292 = "" A18293 = "" A18294 = "" A18295 = "" A18296 = "" A18297 = "" A18298 = "" A18299 = "" A18300 = "" -A18301 = "" A18302 = "" A18303 = "" A18304 = "" A18305 = "" A18306 = "" A18307 = "" A18308 = "" A18309 = "" A18310 = "" -A18311 = "" A18312 = "" A18313 = "" A18314 = "" A18315 = "" A18316 = "" A18317 = "" A18318 = "" A18319 = "" A18320 = "" -A18321 = "" A18322 = "" A18323 = "" A18324 = "" A18325 = "" A18326 = "" A18327 = "" A18328 = "" A18329 = "" A18330 = "" -A18331 = "" A18332 = "" A18333 = "" A18334 = "" A18335 = "" A18336 = "" A18337 = "" A18338 = "" A18339 = "" A18340 = "" -A18341 = "" A18342 = "" A18343 = "" A18344 = "" A18345 = "" A18346 = "" A18347 = "" A18348 = "" A18349 = "" A18350 = "" -A18351 = "" A18352 = "" A18353 = "" A18354 = "" A18355 = "" A18356 = "" A18357 = "" A18358 = "" A18359 = "" A18360 = "" -A18361 = "" A18362 = "" A18363 = "" A18364 = "" A18365 = "" A18366 = "" A18367 = "" A18368 = "" A18369 = "" A18370 = "" -A18371 = "" A18372 = "" A18373 = "" A18374 = "" A18375 = "" A18376 = "" A18377 = "" A18378 = "" A18379 = "" A18380 = "" -A18381 = "" A18382 = "" A18383 = "" A18384 = "" A18385 = "" A18386 = "" A18387 = "" A18388 = "" A18389 = "" A18390 = "" -A18391 = "" A18392 = "" A18393 = "" A18394 = "" A18395 = "" A18396 = "" A18397 = "" A18398 = "" A18399 = "" A18400 = "" -A18401 = "" A18402 = "" A18403 = "" A18404 = "" A18405 = "" A18406 = "" A18407 = "" A18408 = "" A18409 = "" A18410 = "" -A18411 = "" A18412 = "" A18413 = "" A18414 = "" A18415 = "" A18416 = "" A18417 = "" A18418 = "" A18419 = "" A18420 = "" -A18421 = "" A18422 = "" A18423 = "" A18424 = "" A18425 = "" A18426 = "" A18427 = "" A18428 = "" A18429 = "" A18430 = "" -A18431 = "" A18432 = "" A18433 = "" A18434 = "" A18435 = "" A18436 = "" A18437 = "" A18438 = "" A18439 = "" A18440 = "" -A18441 = "" A18442 = "" A18443 = "" A18444 = "" A18445 = "" A18446 = "" A18447 = "" A18448 = "" A18449 = "" A18450 = "" -A18451 = "" A18452 = "" A18453 = "" A18454 = "" A18455 = "" A18456 = "" A18457 = "" A18458 = "" A18459 = "" A18460 = "" -A18461 = "" A18462 = "" A18463 = "" A18464 = "" A18465 = "" A18466 = "" A18467 = "" A18468 = "" A18469 = "" A18470 = "" -A18471 = "" A18472 = "" A18473 = "" A18474 = "" A18475 = "" A18476 = "" A18477 = "" A18478 = "" A18479 = "" A18480 = "" -A18481 = "" A18482 = "" A18483 = "" A18484 = "" A18485 = "" A18486 = "" A18487 = "" A18488 = "" A18489 = "" A18490 = "" -A18491 = "" A18492 = "" A18493 = "" A18494 = "" A18495 = "" A18496 = "" A18497 = "" A18498 = "" A18499 = "" A18500 = "" -A18501 = "" A18502 = "" A18503 = "" A18504 = "" A18505 = "" A18506 = "" A18507 = "" A18508 = "" A18509 = "" A18510 = "" -A18511 = "" A18512 = "" A18513 = "" A18514 = "" A18515 = "" A18516 = "" A18517 = "" A18518 = "" A18519 = "" A18520 = "" -A18521 = "" A18522 = "" A18523 = "" A18524 = "" A18525 = "" A18526 = "" A18527 = "" A18528 = "" A18529 = "" A18530 = "" -A18531 = "" A18532 = "" A18533 = "" A18534 = "" A18535 = "" A18536 = "" A18537 = "" A18538 = "" A18539 = "" A18540 = "" -A18541 = "" A18542 = "" A18543 = "" A18544 = "" A18545 = "" A18546 = "" A18547 = "" A18548 = "" A18549 = "" A18550 = "" -A18551 = "" A18552 = "" A18553 = "" A18554 = "" A18555 = "" A18556 = "" A18557 = "" A18558 = "" A18559 = "" A18560 = "" -A18561 = "" A18562 = "" A18563 = "" A18564 = "" A18565 = "" A18566 = "" A18567 = "" A18568 = "" A18569 = "" A18570 = "" -A18571 = "" A18572 = "" A18573 = "" A18574 = "" A18575 = "" A18576 = "" A18577 = "" A18578 = "" A18579 = "" A18580 = "" -A18581 = "" A18582 = "" A18583 = "" A18584 = "" A18585 = "" A18586 = "" A18587 = "" A18588 = "" A18589 = "" A18590 = "" -A18591 = "" A18592 = "" A18593 = "" A18594 = "" A18595 = "" A18596 = "" A18597 = "" A18598 = "" A18599 = "" A18600 = "" -A18601 = "" A18602 = "" A18603 = "" A18604 = "" A18605 = "" A18606 = "" A18607 = "" A18608 = "" A18609 = "" A18610 = "" -A18611 = "" A18612 = "" A18613 = "" A18614 = "" A18615 = "" A18616 = "" A18617 = "" A18618 = "" A18619 = "" A18620 = "" -A18621 = "" A18622 = "" A18623 = "" A18624 = "" A18625 = "" A18626 = "" A18627 = "" A18628 = "" A18629 = "" A18630 = "" -A18631 = "" A18632 = "" A18633 = "" A18634 = "" A18635 = "" A18636 = "" A18637 = "" A18638 = "" A18639 = "" A18640 = "" -A18641 = "" A18642 = "" A18643 = "" A18644 = "" A18645 = "" A18646 = "" A18647 = "" A18648 = "" A18649 = "" A18650 = "" -A18651 = "" A18652 = "" A18653 = "" A18654 = "" A18655 = "" A18656 = "" A18657 = "" A18658 = "" A18659 = "" A18660 = "" -A18661 = "" A18662 = "" A18663 = "" A18664 = "" A18665 = "" A18666 = "" A18667 = "" A18668 = "" A18669 = "" A18670 = "" -A18671 = "" A18672 = "" A18673 = "" A18674 = "" A18675 = "" A18676 = "" A18677 = "" A18678 = "" A18679 = "" A18680 = "" -A18681 = "" A18682 = "" A18683 = "" A18684 = "" A18685 = "" A18686 = "" A18687 = "" A18688 = "" A18689 = "" A18690 = "" -A18691 = "" A18692 = "" A18693 = "" A18694 = "" A18695 = "" A18696 = "" A18697 = "" A18698 = "" A18699 = "" A18700 = "" -A18701 = "" A18702 = "" A18703 = "" A18704 = "" A18705 = "" A18706 = "" A18707 = "" A18708 = "" A18709 = "" A18710 = "" -A18711 = "" A18712 = "" A18713 = "" A18714 = "" A18715 = "" A18716 = "" A18717 = "" A18718 = "" A18719 = "" A18720 = "" -A18721 = "" A18722 = "" A18723 = "" A18724 = "" A18725 = "" A18726 = "" A18727 = "" A18728 = "" A18729 = "" A18730 = "" -A18731 = "" A18732 = "" A18733 = "" A18734 = "" A18735 = "" A18736 = "" A18737 = "" A18738 = "" A18739 = "" A18740 = "" -A18741 = "" A18742 = "" A18743 = "" A18744 = "" A18745 = "" A18746 = "" A18747 = "" A18748 = "" A18749 = "" A18750 = "" -A18751 = "" A18752 = "" A18753 = "" A18754 = "" A18755 = "" A18756 = "" A18757 = "" A18758 = "" A18759 = "" A18760 = "" -A18761 = "" A18762 = "" A18763 = "" A18764 = "" A18765 = "" A18766 = "" A18767 = "" A18768 = "" A18769 = "" A18770 = "" -A18771 = "" A18772 = "" A18773 = "" A18774 = "" A18775 = "" A18776 = "" A18777 = "" A18778 = "" A18779 = "" A18780 = "" -A18781 = "" A18782 = "" A18783 = "" A18784 = "" A18785 = "" A18786 = "" A18787 = "" A18788 = "" A18789 = "" A18790 = "" -A18791 = "" A18792 = "" A18793 = "" A18794 = "" A18795 = "" A18796 = "" A18797 = "" A18798 = "" A18799 = "" A18800 = "" -A18801 = "" A18802 = "" A18803 = "" A18804 = "" A18805 = "" A18806 = "" A18807 = "" A18808 = "" A18809 = "" A18810 = "" -A18811 = "" A18812 = "" A18813 = "" A18814 = "" A18815 = "" A18816 = "" A18817 = "" A18818 = "" A18819 = "" A18820 = "" -A18821 = "" A18822 = "" A18823 = "" A18824 = "" A18825 = "" A18826 = "" A18827 = "" A18828 = "" A18829 = "" A18830 = "" -A18831 = "" A18832 = "" A18833 = "" A18834 = "" A18835 = "" A18836 = "" A18837 = "" A18838 = "" A18839 = "" A18840 = "" -A18841 = "" A18842 = "" A18843 = "" A18844 = "" A18845 = "" A18846 = "" A18847 = "" A18848 = "" A18849 = "" A18850 = "" -A18851 = "" A18852 = "" A18853 = "" A18854 = "" A18855 = "" A18856 = "" A18857 = "" A18858 = "" A18859 = "" A18860 = "" -A18861 = "" A18862 = "" A18863 = "" A18864 = "" A18865 = "" A18866 = "" A18867 = "" A18868 = "" A18869 = "" A18870 = "" -A18871 = "" A18872 = "" A18873 = "" A18874 = "" A18875 = "" A18876 = "" A18877 = "" A18878 = "" A18879 = "" A18880 = "" -A18881 = "" A18882 = "" A18883 = "" A18884 = "" A18885 = "" A18886 = "" A18887 = "" A18888 = "" A18889 = "" A18890 = "" -A18891 = "" A18892 = "" A18893 = "" A18894 = "" A18895 = "" A18896 = "" A18897 = "" A18898 = "" A18899 = "" A18900 = "" -A18901 = "" A18902 = "" A18903 = "" A18904 = "" A18905 = "" A18906 = "" A18907 = "" A18908 = "" A18909 = "" A18910 = "" -A18911 = "" A18912 = "" A18913 = "" A18914 = "" A18915 = "" A18916 = "" A18917 = "" A18918 = "" A18919 = "" A18920 = "" -A18921 = "" A18922 = "" A18923 = "" A18924 = "" A18925 = "" A18926 = "" A18927 = "" A18928 = "" A18929 = "" A18930 = "" -A18931 = "" A18932 = "" A18933 = "" A18934 = "" A18935 = "" A18936 = "" A18937 = "" A18938 = "" A18939 = "" A18940 = "" -A18941 = "" A18942 = "" A18943 = "" A18944 = "" A18945 = "" A18946 = "" A18947 = "" A18948 = "" A18949 = "" A18950 = "" -A18951 = "" A18952 = "" A18953 = "" A18954 = "" A18955 = "" A18956 = "" A18957 = "" A18958 = "" A18959 = "" A18960 = "" -A18961 = "" A18962 = "" A18963 = "" A18964 = "" A18965 = "" A18966 = "" A18967 = "" A18968 = "" A18969 = "" A18970 = "" -A18971 = "" A18972 = "" A18973 = "" A18974 = "" A18975 = "" A18976 = "" A18977 = "" A18978 = "" A18979 = "" A18980 = "" -A18981 = "" A18982 = "" A18983 = "" A18984 = "" A18985 = "" A18986 = "" A18987 = "" A18988 = "" A18989 = "" A18990 = "" -A18991 = "" A18992 = "" A18993 = "" A18994 = "" A18995 = "" A18996 = "" A18997 = "" A18998 = "" A18999 = "" A19000 = "" -A19001 = "" A19002 = "" A19003 = "" A19004 = "" A19005 = "" A19006 = "" A19007 = "" A19008 = "" A19009 = "" A19010 = "" -A19011 = "" A19012 = "" A19013 = "" A19014 = "" A19015 = "" A19016 = "" A19017 = "" A19018 = "" A19019 = "" A19020 = "" -A19021 = "" A19022 = "" A19023 = "" A19024 = "" A19025 = "" A19026 = "" A19027 = "" A19028 = "" A19029 = "" A19030 = "" -A19031 = "" A19032 = "" A19033 = "" A19034 = "" A19035 = "" A19036 = "" A19037 = "" A19038 = "" A19039 = "" A19040 = "" -A19041 = "" A19042 = "" A19043 = "" A19044 = "" A19045 = "" A19046 = "" A19047 = "" A19048 = "" A19049 = "" A19050 = "" -A19051 = "" A19052 = "" A19053 = "" A19054 = "" A19055 = "" A19056 = "" A19057 = "" A19058 = "" A19059 = "" A19060 = "" -A19061 = "" A19062 = "" A19063 = "" A19064 = "" A19065 = "" A19066 = "" A19067 = "" A19068 = "" A19069 = "" A19070 = "" -A19071 = "" A19072 = "" A19073 = "" A19074 = "" A19075 = "" A19076 = "" A19077 = "" A19078 = "" A19079 = "" A19080 = "" -A19081 = "" A19082 = "" A19083 = "" A19084 = "" A19085 = "" A19086 = "" A19087 = "" A19088 = "" A19089 = "" A19090 = "" -A19091 = "" A19092 = "" A19093 = "" A19094 = "" A19095 = "" A19096 = "" A19097 = "" A19098 = "" A19099 = "" A19100 = "" -A19101 = "" A19102 = "" A19103 = "" A19104 = "" A19105 = "" A19106 = "" A19107 = "" A19108 = "" A19109 = "" A19110 = "" -A19111 = "" A19112 = "" A19113 = "" A19114 = "" A19115 = "" A19116 = "" A19117 = "" A19118 = "" A19119 = "" A19120 = "" -A19121 = "" A19122 = "" A19123 = "" A19124 = "" A19125 = "" A19126 = "" A19127 = "" A19128 = "" A19129 = "" A19130 = "" -A19131 = "" A19132 = "" A19133 = "" A19134 = "" A19135 = "" A19136 = "" A19137 = "" A19138 = "" A19139 = "" A19140 = "" -A19141 = "" A19142 = "" A19143 = "" A19144 = "" A19145 = "" A19146 = "" A19147 = "" A19148 = "" A19149 = "" A19150 = "" -A19151 = "" A19152 = "" A19153 = "" A19154 = "" A19155 = "" A19156 = "" A19157 = "" A19158 = "" A19159 = "" A19160 = "" -A19161 = "" A19162 = "" A19163 = "" A19164 = "" A19165 = "" A19166 = "" A19167 = "" A19168 = "" A19169 = "" A19170 = "" -A19171 = "" A19172 = "" A19173 = "" A19174 = "" A19175 = "" A19176 = "" A19177 = "" A19178 = "" A19179 = "" A19180 = "" -A19181 = "" A19182 = "" A19183 = "" A19184 = "" A19185 = "" A19186 = "" A19187 = "" A19188 = "" A19189 = "" A19190 = "" -A19191 = "" A19192 = "" A19193 = "" A19194 = "" A19195 = "" A19196 = "" A19197 = "" A19198 = "" A19199 = "" A19200 = "" -A19201 = "" A19202 = "" A19203 = "" A19204 = "" A19205 = "" A19206 = "" A19207 = "" A19208 = "" A19209 = "" A19210 = "" -A19211 = "" A19212 = "" A19213 = "" A19214 = "" A19215 = "" A19216 = "" A19217 = "" A19218 = "" A19219 = "" A19220 = "" -A19221 = "" A19222 = "" A19223 = "" A19224 = "" A19225 = "" A19226 = "" A19227 = "" A19228 = "" A19229 = "" A19230 = "" -A19231 = "" A19232 = "" A19233 = "" A19234 = "" A19235 = "" A19236 = "" A19237 = "" A19238 = "" A19239 = "" A19240 = "" -A19241 = "" A19242 = "" A19243 = "" A19244 = "" A19245 = "" A19246 = "" A19247 = "" A19248 = "" A19249 = "" A19250 = "" -A19251 = "" A19252 = "" A19253 = "" A19254 = "" A19255 = "" A19256 = "" A19257 = "" A19258 = "" A19259 = "" A19260 = "" -A19261 = "" A19262 = "" A19263 = "" A19264 = "" A19265 = "" A19266 = "" A19267 = "" A19268 = "" A19269 = "" A19270 = "" -A19271 = "" A19272 = "" A19273 = "" A19274 = "" A19275 = "" A19276 = "" A19277 = "" A19278 = "" A19279 = "" A19280 = "" -A19281 = "" A19282 = "" A19283 = "" A19284 = "" A19285 = "" A19286 = "" A19287 = "" A19288 = "" A19289 = "" A19290 = "" -A19291 = "" A19292 = "" A19293 = "" A19294 = "" A19295 = "" A19296 = "" A19297 = "" A19298 = "" A19299 = "" A19300 = "" -A19301 = "" A19302 = "" A19303 = "" A19304 = "" A19305 = "" A19306 = "" A19307 = "" A19308 = "" A19309 = "" A19310 = "" -A19311 = "" A19312 = "" A19313 = "" A19314 = "" A19315 = "" A19316 = "" A19317 = "" A19318 = "" A19319 = "" A19320 = "" -A19321 = "" A19322 = "" A19323 = "" A19324 = "" A19325 = "" A19326 = "" A19327 = "" A19328 = "" A19329 = "" A19330 = "" -A19331 = "" A19332 = "" A19333 = "" A19334 = "" A19335 = "" A19336 = "" A19337 = "" A19338 = "" A19339 = "" A19340 = "" -A19341 = "" A19342 = "" A19343 = "" A19344 = "" A19345 = "" A19346 = "" A19347 = "" A19348 = "" A19349 = "" A19350 = "" -A19351 = "" A19352 = "" A19353 = "" A19354 = "" A19355 = "" A19356 = "" A19357 = "" A19358 = "" A19359 = "" A19360 = "" -A19361 = "" A19362 = "" A19363 = "" A19364 = "" A19365 = "" A19366 = "" A19367 = "" A19368 = "" A19369 = "" A19370 = "" -A19371 = "" A19372 = "" A19373 = "" A19374 = "" A19375 = "" A19376 = "" A19377 = "" A19378 = "" A19379 = "" A19380 = "" -A19381 = "" A19382 = "" A19383 = "" A19384 = "" A19385 = "" A19386 = "" A19387 = "" A19388 = "" A19389 = "" A19390 = "" -A19391 = "" A19392 = "" A19393 = "" A19394 = "" A19395 = "" A19396 = "" A19397 = "" A19398 = "" A19399 = "" A19400 = "" -A19401 = "" A19402 = "" A19403 = "" A19404 = "" A19405 = "" A19406 = "" A19407 = "" A19408 = "" A19409 = "" A19410 = "" -A19411 = "" A19412 = "" A19413 = "" A19414 = "" A19415 = "" A19416 = "" A19417 = "" A19418 = "" A19419 = "" A19420 = "" -A19421 = "" A19422 = "" A19423 = "" A19424 = "" A19425 = "" A19426 = "" A19427 = "" A19428 = "" A19429 = "" A19430 = "" -A19431 = "" A19432 = "" A19433 = "" A19434 = "" A19435 = "" A19436 = "" A19437 = "" A19438 = "" A19439 = "" A19440 = "" -A19441 = "" A19442 = "" A19443 = "" A19444 = "" A19445 = "" A19446 = "" A19447 = "" A19448 = "" A19449 = "" A19450 = "" -A19451 = "" A19452 = "" A19453 = "" A19454 = "" A19455 = "" A19456 = "" A19457 = "" A19458 = "" A19459 = "" A19460 = "" -A19461 = "" A19462 = "" A19463 = "" A19464 = "" A19465 = "" A19466 = "" A19467 = "" A19468 = "" A19469 = "" A19470 = "" -A19471 = "" A19472 = "" A19473 = "" A19474 = "" A19475 = "" A19476 = "" A19477 = "" A19478 = "" A19479 = "" A19480 = "" -A19481 = "" A19482 = "" A19483 = "" A19484 = "" A19485 = "" A19486 = "" A19487 = "" A19488 = "" A19489 = "" A19490 = "" -A19491 = "" A19492 = "" A19493 = "" A19494 = "" A19495 = "" A19496 = "" A19497 = "" A19498 = "" A19499 = "" A19500 = "" -A19501 = "" A19502 = "" A19503 = "" A19504 = "" A19505 = "" A19506 = "" A19507 = "" A19508 = "" A19509 = "" A19510 = "" -A19511 = "" A19512 = "" A19513 = "" A19514 = "" A19515 = "" A19516 = "" A19517 = "" A19518 = "" A19519 = "" A19520 = "" -A19521 = "" A19522 = "" A19523 = "" A19524 = "" A19525 = "" A19526 = "" A19527 = "" A19528 = "" A19529 = "" A19530 = "" -A19531 = "" A19532 = "" A19533 = "" A19534 = "" A19535 = "" A19536 = "" A19537 = "" A19538 = "" A19539 = "" A19540 = "" -A19541 = "" A19542 = "" A19543 = "" A19544 = "" A19545 = "" A19546 = "" A19547 = "" A19548 = "" A19549 = "" A19550 = "" -A19551 = "" A19552 = "" A19553 = "" A19554 = "" A19555 = "" A19556 = "" A19557 = "" A19558 = "" A19559 = "" A19560 = "" -A19561 = "" A19562 = "" A19563 = "" A19564 = "" A19565 = "" A19566 = "" A19567 = "" A19568 = "" A19569 = "" A19570 = "" -A19571 = "" A19572 = "" A19573 = "" A19574 = "" A19575 = "" A19576 = "" A19577 = "" A19578 = "" A19579 = "" A19580 = "" -A19581 = "" A19582 = "" A19583 = "" A19584 = "" A19585 = "" A19586 = "" A19587 = "" A19588 = "" A19589 = "" A19590 = "" -A19591 = "" A19592 = "" A19593 = "" A19594 = "" A19595 = "" A19596 = "" A19597 = "" A19598 = "" A19599 = "" A19600 = "" -A19601 = "" A19602 = "" A19603 = "" A19604 = "" A19605 = "" A19606 = "" A19607 = "" A19608 = "" A19609 = "" A19610 = "" -A19611 = "" A19612 = "" A19613 = "" A19614 = "" A19615 = "" A19616 = "" A19617 = "" A19618 = "" A19619 = "" A19620 = "" -A19621 = "" A19622 = "" A19623 = "" A19624 = "" A19625 = "" A19626 = "" A19627 = "" A19628 = "" A19629 = "" A19630 = "" -A19631 = "" A19632 = "" A19633 = "" A19634 = "" A19635 = "" A19636 = "" A19637 = "" A19638 = "" A19639 = "" A19640 = "" -A19641 = "" A19642 = "" A19643 = "" A19644 = "" A19645 = "" A19646 = "" A19647 = "" A19648 = "" A19649 = "" A19650 = "" -A19651 = "" A19652 = "" A19653 = "" A19654 = "" A19655 = "" A19656 = "" A19657 = "" A19658 = "" A19659 = "" A19660 = "" -A19661 = "" A19662 = "" A19663 = "" A19664 = "" A19665 = "" A19666 = "" A19667 = "" A19668 = "" A19669 = "" A19670 = "" -A19671 = "" A19672 = "" A19673 = "" A19674 = "" A19675 = "" A19676 = "" A19677 = "" A19678 = "" A19679 = "" A19680 = "" -A19681 = "" A19682 = "" A19683 = "" A19684 = "" A19685 = "" A19686 = "" A19687 = "" A19688 = "" A19689 = "" A19690 = "" -A19691 = "" A19692 = "" A19693 = "" A19694 = "" A19695 = "" A19696 = "" A19697 = "" A19698 = "" A19699 = "" A19700 = "" -A19701 = "" A19702 = "" A19703 = "" A19704 = "" A19705 = "" A19706 = "" A19707 = "" A19708 = "" A19709 = "" A19710 = "" -A19711 = "" A19712 = "" A19713 = "" A19714 = "" A19715 = "" A19716 = "" A19717 = "" A19718 = "" A19719 = "" A19720 = "" -A19721 = "" A19722 = "" A19723 = "" A19724 = "" A19725 = "" A19726 = "" A19727 = "" A19728 = "" A19729 = "" A19730 = "" -A19731 = "" A19732 = "" A19733 = "" A19734 = "" A19735 = "" A19736 = "" A19737 = "" A19738 = "" A19739 = "" A19740 = "" -A19741 = "" A19742 = "" A19743 = "" A19744 = "" A19745 = "" A19746 = "" A19747 = "" A19748 = "" A19749 = "" A19750 = "" -A19751 = "" A19752 = "" A19753 = "" A19754 = "" A19755 = "" A19756 = "" A19757 = "" A19758 = "" A19759 = "" A19760 = "" -A19761 = "" A19762 = "" A19763 = "" A19764 = "" A19765 = "" A19766 = "" A19767 = "" A19768 = "" A19769 = "" A19770 = "" -A19771 = "" A19772 = "" A19773 = "" A19774 = "" A19775 = "" A19776 = "" A19777 = "" A19778 = "" A19779 = "" A19780 = "" -A19781 = "" A19782 = "" A19783 = "" A19784 = "" A19785 = "" A19786 = "" A19787 = "" A19788 = "" A19789 = "" A19790 = "" -A19791 = "" A19792 = "" A19793 = "" A19794 = "" A19795 = "" A19796 = "" A19797 = "" A19798 = "" A19799 = "" A19800 = "" -A19801 = "" A19802 = "" A19803 = "" A19804 = "" A19805 = "" A19806 = "" A19807 = "" A19808 = "" A19809 = "" A19810 = "" -A19811 = "" A19812 = "" A19813 = "" A19814 = "" A19815 = "" A19816 = "" A19817 = "" A19818 = "" A19819 = "" A19820 = "" -A19821 = "" A19822 = "" A19823 = "" A19824 = "" A19825 = "" A19826 = "" A19827 = "" A19828 = "" A19829 = "" A19830 = "" -A19831 = "" A19832 = "" A19833 = "" A19834 = "" A19835 = "" A19836 = "" A19837 = "" A19838 = "" A19839 = "" A19840 = "" -A19841 = "" A19842 = "" A19843 = "" A19844 = "" A19845 = "" A19846 = "" A19847 = "" A19848 = "" A19849 = "" A19850 = "" -A19851 = "" A19852 = "" A19853 = "" A19854 = "" A19855 = "" A19856 = "" A19857 = "" A19858 = "" A19859 = "" A19860 = "" -A19861 = "" A19862 = "" A19863 = "" A19864 = "" A19865 = "" A19866 = "" A19867 = "" A19868 = "" A19869 = "" A19870 = "" -A19871 = "" A19872 = "" A19873 = "" A19874 = "" A19875 = "" A19876 = "" A19877 = "" A19878 = "" A19879 = "" A19880 = "" -A19881 = "" A19882 = "" A19883 = "" A19884 = "" A19885 = "" A19886 = "" A19887 = "" A19888 = "" A19889 = "" A19890 = "" -A19891 = "" A19892 = "" A19893 = "" A19894 = "" A19895 = "" A19896 = "" A19897 = "" A19898 = "" A19899 = "" A19900 = "" -A19901 = "" A19902 = "" A19903 = "" A19904 = "" A19905 = "" A19906 = "" A19907 = "" A19908 = "" A19909 = "" A19910 = "" -A19911 = "" A19912 = "" A19913 = "" A19914 = "" A19915 = "" A19916 = "" A19917 = "" A19918 = "" A19919 = "" A19920 = "" -A19921 = "" A19922 = "" A19923 = "" A19924 = "" A19925 = "" A19926 = "" A19927 = "" A19928 = "" A19929 = "" A19930 = "" -A19931 = "" A19932 = "" A19933 = "" A19934 = "" A19935 = "" A19936 = "" A19937 = "" A19938 = "" A19939 = "" A19940 = "" -A19941 = "" A19942 = "" A19943 = "" A19944 = "" A19945 = "" A19946 = "" A19947 = "" A19948 = "" A19949 = "" A19950 = "" -A19951 = "" A19952 = "" A19953 = "" A19954 = "" A19955 = "" A19956 = "" A19957 = "" A19958 = "" A19959 = "" A19960 = "" -A19961 = "" A19962 = "" A19963 = "" A19964 = "" A19965 = "" A19966 = "" A19967 = "" A19968 = "" A19969 = "" A19970 = "" -A19971 = "" A19972 = "" A19973 = "" A19974 = "" A19975 = "" A19976 = "" A19977 = "" A19978 = "" A19979 = "" A19980 = "" -A19981 = "" A19982 = "" A19983 = "" A19984 = "" A19985 = "" A19986 = "" A19987 = "" A19988 = "" A19989 = "" A19990 = "" -A19991 = "" A19992 = "" A19993 = "" A19994 = "" A19995 = "" A19996 = "" A19997 = "" A19998 = "" A19999 = "" -> - <name><family>Boss</family> <given>Big</given></name> - <email>chief@foo.com</email> - <link subordinates="one.worker two.worker three.worker four.worker five.worker"/> - </person> - - <person id="one.worker"> - <name><family>Worker</family> <given>One</given></name> - <email>one@foo.com</email> - <link manager="Big.Boss"/> - </person> - - <person id="two.worker"> - <name><family>Worker</family> <given>Two</given></name> - <email>two@foo.com</email> - <link manager="Big.Boss"/> - </person> - - <person id="three.worker"> - <name><family>Worker</family> <given>Three</given></name> - <email>three@foo.com</email> - <link manager="Big.Boss"/> - </person> - - <person id="four.worker"> - <name><family>Worker</family> <given>Four</given></name> - <email>four@foo.com</email> - <link manager="Big.Boss"/> - </person> - - <person id="five.worker"> - <name><family>Worker</family> <given>Five</given></name> - <email>five@foo.com</email> - <link manager="Big.Boss"/> - </person> - -</personnel> diff --git a/test/jaxp/javax/xml/jaxp/unittest/parsers/DosTest3.xml b/test/jaxp/javax/xml/jaxp/unittest/parsers/DosTest3.xml deleted file mode 100644 index 58d82c93c39..00000000000 --- a/test/jaxp/javax/xml/jaxp/unittest/parsers/DosTest3.xml +++ /dev/null @@ -1,42 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<personnel> - -<person id="Big.Boss" A100 = "" -A101 = "" A102 = "" A103 = "" -> - <name><family>Boss</family> <given>Big</given></name> - <email>chief@foo.com</email> - <link subordinates="one.worker two.worker three.worker four.worker five.worker"/> - </person> - - <person id="one.worker"> - <name><family>Worker</family> <given>One</given></name> - <email>one@foo.com</email> - <link manager="Big.Boss"/> - </person> - - <person id="two.worker"> - <name><family>Worker</family> <given>Two</given></name> - <email>two@foo.com</email> - <link manager="Big.Boss"/> - </person> - - <person id="three.worker"> - <name><family>Worker</family> <given>Three</given></name> - <email>three@foo.com</email> - <link manager="Big.Boss"/> - </person> - - <person id="four.worker"> - <name><family>Worker</family> <given>Four</given></name> - <email>four@foo.com</email> - <link manager="Big.Boss"/> - </person> - - <person id="five.worker"> - <name><family>Worker</family> <given>Five</given></name> - <email>five@foo.com</email> - <link manager="Big.Boss"/> - </person> - -</personnel> diff --git a/test/jaxp/javax/xml/jaxp/unittest/parsers/entity.xml b/test/jaxp/javax/xml/jaxp/unittest/parsers/entity.xml deleted file mode 100644 index 167c0abae0d..00000000000 --- a/test/jaxp/javax/xml/jaxp/unittest/parsers/entity.xml +++ /dev/null @@ -1,8 +0,0 @@ -<?xml version="1.0" encoding='UTF-8'?> -<!DOCTYPE author [ -<!ELEMENT author ANY> -<!ENTITY writer "Jan Egil Refsnes."> -<!ENTITY copyright "Copyright XML101."> -<!ENTITY something "ABC"> -]> -<author>&writer;©right;&something;&something;</author> diff --git a/test/jaxp/javax/xml/jaxp/unittest/parsers/entity64K.xml b/test/jaxp/javax/xml/jaxp/unittest/parsers/entity64K.xml deleted file mode 100644 index 0b41c20695b..00000000000 --- a/test/jaxp/javax/xml/jaxp/unittest/parsers/entity64K.xml +++ /dev/null @@ -1,4 +0,0 @@ -<!DOCTYPE author [ -<!ELEMENT author ANY> -<!ENTITY s "ABC"> -]> <author>&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;&s;</author> diff --git a/test/jaxp/javax/xml/jaxp/unittest/stream/EventsTest/EventFilterSupportTest.java b/test/jaxp/javax/xml/jaxp/unittest/stream/EventsTest/EventFilterSupportTest.java index afccf08e9b6..a9594ee7529 100644 --- a/test/jaxp/javax/xml/jaxp/unittest/stream/EventsTest/EventFilterSupportTest.java +++ b/test/jaxp/javax/xml/jaxp/unittest/stream/EventsTest/EventFilterSupportTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -123,6 +123,7 @@ private static XMLEventReader createXmlReader(int max) throws XMLStreamException { TestInputStream ts = new TestInputStream(max); XMLInputFactory xif = XMLInputFactory.newInstance(); + xif.setProperty("jdk.xml.maxElementDepth", "100000"); XMLEventReader reader = xif.createXMLEventReader(ts); return xif.createFilteredReader(reader, new TagFilter(max)); } From 08c1f44eef56e1b6e6960596f6664fbd973c3d7e Mon Sep 17 00:00:00 2001 From: "David M. Lloyd" <david.lloyd@redhat.com> Date: Wed, 27 Nov 2024 01:03:33 +0000 Subject: [PATCH 267/311] 8341028: Do not use lambdas or method refs for verifyConstantPool Reviewed-by: adinn, liach --- .../impl/verifier/ParserVerifier.java | 112 +++++++++++------- 1 file changed, 70 insertions(+), 42 deletions(-) diff --git a/src/java.base/share/classes/jdk/internal/classfile/impl/verifier/ParserVerifier.java b/src/java.base/share/classes/jdk/internal/classfile/impl/verifier/ParserVerifier.java index b7ddaace116..f860fb4a1bd 100644 --- a/src/java.base/share/classes/jdk/internal/classfile/impl/verifier/ParserVerifier.java +++ b/src/java.base/share/classes/jdk/internal/classfile/impl/verifier/ParserVerifier.java @@ -34,10 +34,9 @@ import java.util.Collection; import java.util.HashSet; import java.util.List; -import java.util.function.Consumer; +import java.util.stream.Collectors; import java.util.function.Function; import java.util.function.ToIntFunction; -import java.util.stream.Collectors; import jdk.internal.classfile.impl.BoundAttribute; import jdk.internal.classfile.impl.Util; @@ -65,50 +64,79 @@ List<VerifyError> verify() { private void verifyConstantPool(List<VerifyError> errors) { for (var cpe : classModel.constantPool()) { - Consumer<Runnable> check = c -> { - try { - c.run(); - } catch (VerifyError|Exception e) { - errors.add(new VerifyError("%s at constant pool index %d in %s".formatted(e.getMessage(), cpe.index(), toString(classModel)))); - } - }; - check.accept(switch (cpe) { - case DoubleEntry de -> de::doubleValue; - case FloatEntry fe -> fe::floatValue; - case IntegerEntry ie -> ie::intValue; - case LongEntry le -> le::longValue; - case Utf8Entry ue -> ue::stringValue; - case ConstantDynamicEntry cde -> cde::asSymbol; - case InvokeDynamicEntry ide -> ide::asSymbol; - case ClassEntry ce -> ce::asSymbol; - case StringEntry se -> se::stringValue; - case MethodHandleEntry mhe -> mhe::asSymbol; - case MethodTypeEntry mte -> mte::asSymbol; - case FieldRefEntry fre -> { - check.accept(fre.owner()::asSymbol); - check.accept(fre::typeSymbol); - yield () -> verifyFieldName(fre.name().stringValue()); - } - case InterfaceMethodRefEntry imre -> { - check.accept(imre.owner()::asSymbol); - check.accept(imre::typeSymbol); - yield () -> verifyMethodName(imre.name().stringValue()); - } - case MethodRefEntry mre -> { - check.accept(mre.owner()::asSymbol); - check.accept(mre::typeSymbol); - yield () -> verifyMethodName(mre.name().stringValue()); - } - case ModuleEntry me -> me::asSymbol; - case NameAndTypeEntry nate -> { - check.accept(nate.name()::stringValue); - yield () -> nate.type().stringValue(); + try { + switch (cpe) { + case DoubleEntry de -> de.doubleValue(); + case FloatEntry fe -> fe.floatValue(); + case IntegerEntry ie -> ie.intValue(); + case LongEntry le -> le.longValue(); + case Utf8Entry ue -> ue.stringValue(); + case ConstantDynamicEntry cde -> cde.asSymbol(); + case InvokeDynamicEntry ide -> ide.asSymbol(); + case ClassEntry ce -> ce.asSymbol(); + case StringEntry se -> se.stringValue(); + case MethodHandleEntry mhe -> mhe.asSymbol(); + case MethodTypeEntry mte -> mte.asSymbol(); + case FieldRefEntry fre -> { + try { + fre.owner().asSymbol(); + } catch (VerifyError|Exception e) { + errors.add(cpeVerifyError(cpe, e)); + } + try { + fre.typeSymbol(); + } catch (VerifyError|Exception e) { + errors.add(cpeVerifyError(cpe, e)); + } + verifyFieldName(fre.name().stringValue()); + } + case InterfaceMethodRefEntry imre -> { + try { + imre.owner().asSymbol(); + } catch (VerifyError|Exception e) { + errors.add(cpeVerifyError(cpe, e)); + } + try { + imre.typeSymbol(); + } catch (VerifyError|Exception e) { + errors.add(cpeVerifyError(cpe, e)); + } + verifyMethodName(imre.name().stringValue()); + } + case MethodRefEntry mre -> { + try { + mre.owner().asSymbol(); + } catch (VerifyError|Exception e) { + errors.add(cpeVerifyError(cpe, e)); + } + try { + mre.typeSymbol(); + } catch (VerifyError|Exception e) { + errors.add(cpeVerifyError(cpe, e)); + } + verifyMethodName(mre.name().stringValue()); + } + case ModuleEntry me -> me.asSymbol(); + case NameAndTypeEntry nate -> { + try { + nate.name().stringValue(); + } catch (VerifyError|Exception e) { + errors.add(cpeVerifyError(cpe, e)); + } + nate.type().stringValue(); + } + case PackageEntry pe -> pe.asSymbol(); } - case PackageEntry pe -> pe::asSymbol; - }); + } catch (VerifyError|Exception e) { + errors.add(cpeVerifyError(cpe, e)); + } } } + private VerifyError cpeVerifyError(final PoolEntry cpe, final Throwable e) { + return new VerifyError("%s at constant pool index %d in %s".formatted(e.getMessage(), cpe.index(), toString(classModel))); + } + private void verifyFieldName(String name) { if (name.length() == 0 || name.chars().anyMatch(ch -> switch(ch) { case '.', ';', '[', '/' -> true; From 1f6144ef26096da46ca04f188afb483ea237bb0e Mon Sep 17 00:00:00 2001 From: Kim Barrett <kbarrett@openjdk.org> Date: Wed, 27 Nov 2024 06:43:05 +0000 Subject: [PATCH 268/311] 8345050: Fix -Wzero-as-null-pointer warning in MemPointer ctor Reviewed-by: chagedorn, shade --- src/hotspot/share/opto/mempointer.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/hotspot/share/opto/mempointer.hpp b/src/hotspot/share/opto/mempointer.hpp index 1e5b2c00b88..100fbfc71bd 100644 --- a/src/hotspot/share/opto/mempointer.hpp +++ b/src/hotspot/share/opto/mempointer.hpp @@ -596,7 +596,7 @@ class MemPointer : public StackObj { if (_trace.is_trace_pointer()) { tty->print_cr("MemPointer::MemPointer:"); tty->print("mem: "); mem->dump(); - _mem->in(MemNode::Address)->dump_bfs(5, 0, "d"); + _mem->in(MemNode::Address)->dump_bfs(5, nullptr, "d"); _decomposed_form.print_on(tty); } #endif From 57ee3ba7e1a2b436f6666b9465a4651f7baca7e3 Mon Sep 17 00:00:00 2001 From: Quan Anh Mai <qamai@openjdk.org> Date: Wed, 27 Nov 2024 07:35:51 +0000 Subject: [PATCH 269/311] 8344912: Sharpen the return type of various internal methods in jdk.internal.foreign Reviewed-by: mcimadamore --- .../foreign/AbstractMemorySegmentImpl.java | 13 +-- .../jdk/internal/foreign/ArenaImpl.java | 11 +- .../foreign/MappedMemorySegmentImpl.java | 4 +- .../internal/foreign/MemorySessionImpl.java | 2 +- .../foreign/NativeMemorySegmentImpl.java | 2 +- .../foreign/SegmentBulkOperations.java | 2 +- .../internal/foreign/SegmentFactories.java | 101 +++++++----------- .../foreign/abi/fallback/FallbackLinker.java | 1 - 8 files changed, 54 insertions(+), 82 deletions(-) diff --git a/src/java.base/share/classes/jdk/internal/foreign/AbstractMemorySegmentImpl.java b/src/java.base/share/classes/jdk/internal/foreign/AbstractMemorySegmentImpl.java index c3673dace8d..97417efaa8c 100644 --- a/src/java.base/share/classes/jdk/internal/foreign/AbstractMemorySegmentImpl.java +++ b/src/java.base/share/classes/jdk/internal/foreign/AbstractMemorySegmentImpl.java @@ -141,15 +141,14 @@ public final MemorySegment reinterpret(Arena arena, Consumer<MemorySegment> clea MemorySessionImpl.toMemorySession(arena), cleanup); } - public MemorySegment reinterpretInternal(Class<?> callerClass, long newSize, Scope scope, Consumer<MemorySegment> cleanup) { + private NativeMemorySegmentImpl reinterpretInternal(Class<?> callerClass, long newSize, MemorySessionImpl scope, Consumer<MemorySegment> cleanup) { Reflection.ensureNativeAccess(callerClass, MemorySegment.class, "reinterpret", false); Utils.checkNonNegativeArgument(newSize, "newSize"); if (!isNative()) throw new UnsupportedOperationException("Not a native segment"); Runnable action = cleanup != null ? () -> cleanup.accept(SegmentFactories.makeNativeSegmentUnchecked(address(), newSize)) : null; - return SegmentFactories.makeNativeSegmentUnchecked(address(), newSize, - (MemorySessionImpl)scope, readOnly, action); + return SegmentFactories.makeNativeSegmentUnchecked(address(), newSize, scope, readOnly, action); } private AbstractMemorySegmentImpl asSliceNoCheck(long offset, long newSize) { @@ -332,10 +331,6 @@ public void checkAccess(long offset, long length, boolean readOnly) { checkBounds(offset, length); } - public void checkValidState() { - sessionImpl().checkValidState(); - } - @ForceInline public final void checkEnclosingLayout(long offset, MemoryLayout enclosing, boolean readOnly) { checkAccess(offset, enclosing.byteSize(), readOnly); @@ -394,7 +389,7 @@ public RuntimeException apply(String s, List<Number> numbers) { } @Override - public Scope scope() { + public MemorySessionImpl scope() { return scope; } @@ -539,7 +534,7 @@ private static long length(Buffer b, int scaleShifts) { } @ForceInline - private static AbstractMemorySegmentImpl nativeSegment(Buffer b, long offset, long length) { + private static NativeMemorySegmentImpl nativeSegment(Buffer b, long offset, long length) { if (!b.isDirect()) { throw new IllegalArgumentException("The provided heap buffer is not backed by an array."); } diff --git a/src/java.base/share/classes/jdk/internal/foreign/ArenaImpl.java b/src/java.base/share/classes/jdk/internal/foreign/ArenaImpl.java index 027aed5f8cc..948cc7c2acf 100644 --- a/src/java.base/share/classes/jdk/internal/foreign/ArenaImpl.java +++ b/src/java.base/share/classes/jdk/internal/foreign/ArenaImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -50,14 +50,15 @@ public void close() { session.close(); } - public MemorySegment allocateNoInit(long byteSize, long byteAlignment) { + public NativeMemorySegmentImpl allocateNoInit(long byteSize, long byteAlignment) { Utils.checkAllocationSizeAndAlign(byteSize, byteAlignment); return SegmentFactories.allocateSegment(byteSize, byteAlignment, session, shouldReserveMemory); } @Override - public MemorySegment allocate(long byteSize, long byteAlignment) { - MemorySegment segment = allocateNoInit(byteSize, byteAlignment); - return segment.fill((byte)0); + public NativeMemorySegmentImpl allocate(long byteSize, long byteAlignment) { + NativeMemorySegmentImpl segment = allocateNoInit(byteSize, byteAlignment); + segment.fill((byte)0); + return segment; } } diff --git a/src/java.base/share/classes/jdk/internal/foreign/MappedMemorySegmentImpl.java b/src/java.base/share/classes/jdk/internal/foreign/MappedMemorySegmentImpl.java index 181a560c5f0..f0ae76829ff 100644 --- a/src/java.base/share/classes/jdk/internal/foreign/MappedMemorySegmentImpl.java +++ b/src/java.base/share/classes/jdk/internal/foreign/MappedMemorySegmentImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2020, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -35,7 +35,7 @@ * memory mapped segment, such as the file descriptor associated with the mapping. This information is crucial * in order to correctly reconstruct a byte buffer object from the segment (see {@link #makeByteBuffer()}). */ -final class MappedMemorySegmentImpl extends NativeMemorySegmentImpl { +public final class MappedMemorySegmentImpl extends NativeMemorySegmentImpl { private final UnmapperProxy unmapper; diff --git a/src/java.base/share/classes/jdk/internal/foreign/MemorySessionImpl.java b/src/java.base/share/classes/jdk/internal/foreign/MemorySessionImpl.java index 541a0907e4c..8f576625500 100644 --- a/src/java.base/share/classes/jdk/internal/foreign/MemorySessionImpl.java +++ b/src/java.base/share/classes/jdk/internal/foreign/MemorySessionImpl.java @@ -85,7 +85,7 @@ public abstract sealed class MemorySessionImpl int acquireCount; - public Arena asArena() { + public ArenaImpl asArena() { return new ArenaImpl(this); } diff --git a/src/java.base/share/classes/jdk/internal/foreign/NativeMemorySegmentImpl.java b/src/java.base/share/classes/jdk/internal/foreign/NativeMemorySegmentImpl.java index c2043cf4267..1c726acd2e1 100644 --- a/src/java.base/share/classes/jdk/internal/foreign/NativeMemorySegmentImpl.java +++ b/src/java.base/share/classes/jdk/internal/foreign/NativeMemorySegmentImpl.java @@ -36,7 +36,7 @@ * Implementation for native memory segments. A native memory segment is essentially a wrapper around * a native long address. */ -sealed class NativeMemorySegmentImpl extends AbstractMemorySegmentImpl permits MappedMemorySegmentImpl { +public sealed class NativeMemorySegmentImpl extends AbstractMemorySegmentImpl permits MappedMemorySegmentImpl { final long min; diff --git a/src/java.base/share/classes/jdk/internal/foreign/SegmentBulkOperations.java b/src/java.base/share/classes/jdk/internal/foreign/SegmentBulkOperations.java index 773b8e57440..11f1914a707 100644 --- a/src/java.base/share/classes/jdk/internal/foreign/SegmentBulkOperations.java +++ b/src/java.base/share/classes/jdk/internal/foreign/SegmentBulkOperations.java @@ -62,7 +62,7 @@ public static MemorySegment fill(AbstractMemorySegmentImpl dst, byte value) { dst.checkReadOnly(false); if (dst.length == 0) { // Implicit state check - dst.checkValidState(); + dst.sessionImpl().checkValidState(); } else if (dst.length < NATIVE_THRESHOLD_FILL) { // 0 <= length < FILL_NATIVE_LIMIT : 0...0X...XXXX diff --git a/src/java.base/share/classes/jdk/internal/foreign/SegmentFactories.java b/src/java.base/share/classes/jdk/internal/foreign/SegmentFactories.java index a9d803055c5..4ab14aa845f 100644 --- a/src/java.base/share/classes/jdk/internal/foreign/SegmentFactories.java +++ b/src/java.base/share/classes/jdk/internal/foreign/SegmentFactories.java @@ -57,11 +57,9 @@ public class SegmentFactories { // associated with MemorySegment::ofAddress. @ForceInline - public static MemorySegment makeNativeSegmentUnchecked(long min, - long byteSize, - MemorySessionImpl sessionImpl, - boolean readOnly, - Runnable action) { + public static NativeMemorySegmentImpl makeNativeSegmentUnchecked(long min, long byteSize, + MemorySessionImpl sessionImpl, + boolean readOnly, Runnable action) { ensureInitialized(); if (action == null) { sessionImpl.checkValidState(); @@ -72,19 +70,19 @@ public static MemorySegment makeNativeSegmentUnchecked(long min, } @ForceInline - public static MemorySegment makeNativeSegmentUnchecked(long min, long byteSize, MemorySessionImpl sessionImpl) { + public static NativeMemorySegmentImpl makeNativeSegmentUnchecked(long min, long byteSize, MemorySessionImpl sessionImpl) { ensureInitialized(); sessionImpl.checkValidState(); return new NativeMemorySegmentImpl(min, byteSize, false, sessionImpl); } @ForceInline - public static MemorySegment makeNativeSegmentUnchecked(long min, long byteSize) { + public static NativeMemorySegmentImpl makeNativeSegmentUnchecked(long min, long byteSize) { ensureInitialized(); return new NativeMemorySegmentImpl(min, byteSize, false, MemorySessionImpl.GLOBAL_SESSION); } - public static MemorySegment fromArray(byte[] arr) { + public static OfByte fromArray(byte[] arr) { ensureInitialized(); Objects.requireNonNull(arr); long byteSize = (long)arr.length * Utils.BaseAndScale.BYTE.scale(); @@ -92,7 +90,7 @@ public static MemorySegment fromArray(byte[] arr) { MemorySessionImpl.createHeap(arr)); } - public static MemorySegment fromArray(short[] arr) { + public static OfShort fromArray(short[] arr) { ensureInitialized(); Objects.requireNonNull(arr); long byteSize = (long)arr.length * Utils.BaseAndScale.SHORT.scale(); @@ -100,7 +98,7 @@ public static MemorySegment fromArray(short[] arr) { MemorySessionImpl.createHeap(arr)); } - public static MemorySegment fromArray(int[] arr) { + public static OfInt fromArray(int[] arr) { ensureInitialized(); Objects.requireNonNull(arr); long byteSize = (long)arr.length * Utils.BaseAndScale.INT.scale(); @@ -108,7 +106,7 @@ public static MemorySegment fromArray(int[] arr) { MemorySessionImpl.createHeap(arr)); } - public static MemorySegment fromArray(char[] arr) { + public static OfChar fromArray(char[] arr) { ensureInitialized(); Objects.requireNonNull(arr); long byteSize = (long)arr.length * Utils.BaseAndScale.CHAR.scale(); @@ -116,7 +114,7 @@ public static MemorySegment fromArray(char[] arr) { MemorySessionImpl.createHeap(arr)); } - public static MemorySegment fromArray(float[] arr) { + public static OfFloat fromArray(float[] arr) { ensureInitialized(); Objects.requireNonNull(arr); long byteSize = (long)arr.length * Utils.BaseAndScale.FLOAT.scale(); @@ -124,7 +122,7 @@ public static MemorySegment fromArray(float[] arr) { MemorySessionImpl.createHeap(arr)); } - public static MemorySegment fromArray(double[] arr) { + public static OfDouble fromArray(double[] arr) { ensureInitialized(); Objects.requireNonNull(arr); long byteSize = (long)arr.length * Utils.BaseAndScale.DOUBLE.scale(); @@ -132,7 +130,7 @@ public static MemorySegment fromArray(double[] arr) { MemorySessionImpl.createHeap(arr)); } - public static MemorySegment fromArray(long[] arr) { + public static OfLong fromArray(long[] arr) { ensureInitialized(); Objects.requireNonNull(arr); long byteSize = (long)arr.length * Utils.BaseAndScale.LONG.scale(); @@ -142,64 +140,43 @@ public static MemorySegment fromArray(long[] arr) { // Buffer conversion factories - public static AbstractMemorySegmentImpl arrayOfByteSegment(Object base, - long offset, - long length, - boolean readOnly, - MemorySessionImpl bufferScope) { - return new HeapMemorySegmentImpl.OfByte(offset, base, length, readOnly, bufferScope); + public static OfByte arrayOfByteSegment(Object base, long offset, long length, + boolean readOnly, MemorySessionImpl bufferScope) { + return new OfByte(offset, base, length, readOnly, bufferScope); } - public static AbstractMemorySegmentImpl arrayOfShortSegment(Object base, - long offset, - long length, - boolean readOnly, - MemorySessionImpl bufferScope) { - return new HeapMemorySegmentImpl.OfShort(offset, base, length, readOnly, bufferScope); + public static OfShort arrayOfShortSegment(Object base, long offset, long length, + boolean readOnly, MemorySessionImpl bufferScope) { + return new OfShort(offset, base, length, readOnly, bufferScope); } - public static AbstractMemorySegmentImpl arrayOfCharSegment(Object base, - long offset, - long length, - boolean readOnly, - MemorySessionImpl bufferScope) { - return new HeapMemorySegmentImpl.OfChar(offset, base, length, readOnly, bufferScope); + public static OfChar arrayOfCharSegment(Object base, long offset, long length, + boolean readOnly, MemorySessionImpl bufferScope) { + return new OfChar(offset, base, length, readOnly, bufferScope); } - public static AbstractMemorySegmentImpl arrayOfIntSegment(Object base, - long offset, - long length, - boolean readOnly, - MemorySessionImpl bufferScope) { - return new HeapMemorySegmentImpl.OfInt(offset, base, length, readOnly, bufferScope); + public static OfInt arrayOfIntSegment(Object base, long offset, long length, + boolean readOnly, MemorySessionImpl bufferScope) { + return new OfInt(offset, base, length, readOnly, bufferScope); } - public static AbstractMemorySegmentImpl arrayOfFloatSegment(Object base, - long offset, - long length, - boolean readOnly, - MemorySessionImpl bufferScope) { - return new HeapMemorySegmentImpl.OfFloat(offset, base, length, readOnly, bufferScope); + public static OfFloat arrayOfFloatSegment(Object base, long offset, long length, + boolean readOnly, MemorySessionImpl bufferScope) { + return new OfFloat(offset, base, length, readOnly, bufferScope); } - public static AbstractMemorySegmentImpl arrayOfLongSegment(Object base, - long offset, - long length, - boolean readOnly, - MemorySessionImpl bufferScope) { - return new HeapMemorySegmentImpl.OfLong(offset, base, length, readOnly, bufferScope); + public static OfLong arrayOfLongSegment(Object base, long offset, long length, + boolean readOnly, MemorySessionImpl bufferScope) { + return new OfLong(offset, base, length, readOnly, bufferScope); } - public static AbstractMemorySegmentImpl arrayOfDoubleSegment(Object base, - long offset, - long length, - boolean readOnly, - MemorySessionImpl bufferScope) { - return new HeapMemorySegmentImpl.OfDouble(offset, base, length, readOnly, bufferScope); + public static OfDouble arrayOfDoubleSegment(Object base, long offset, long length, + boolean readOnly, MemorySessionImpl bufferScope) { + return new OfDouble(offset, base, length, readOnly, bufferScope); } - public static MemorySegment allocateSegment(long byteSize, long byteAlignment, MemorySessionImpl sessionImpl, - boolean shouldReserve) { + public static NativeMemorySegmentImpl allocateSegment(long byteSize, long byteAlignment, MemorySessionImpl sessionImpl, + boolean shouldReserve) { ensureInitialized(); sessionImpl.checkValidState(); if (VM.isDirectMemoryPageAligned()) { @@ -215,7 +192,7 @@ public static MemorySegment allocateSegment(long byteSize, long byteAlignment, M long buf = allocateMemoryWrapper(alignedSize); long alignedBuf = Utils.alignUp(buf, byteAlignment); - AbstractMemorySegmentImpl segment = new NativeMemorySegmentImpl(buf, alignedSize, + NativeMemorySegmentImpl segment = new NativeMemorySegmentImpl(buf, alignedSize, false, sessionImpl); sessionImpl.addOrCleanupIfFail(new MemorySessionImpl.ResourceList.ResourceCleanup() { @Override @@ -228,7 +205,7 @@ public void cleanup() { }); if (alignedSize != byteSize) { long delta = alignedBuf - buf; - segment = segment.asSlice(delta, byteSize); + segment = (NativeMemorySegmentImpl) segment.asSlice(delta, byteSize); } return segment; } @@ -241,10 +218,10 @@ private static long allocateMemoryWrapper(long size) { } } - public static MemorySegment mapSegment(long size, UnmapperProxy unmapper, boolean readOnly, MemorySessionImpl sessionImpl) { + public static MappedMemorySegmentImpl mapSegment(long size, UnmapperProxy unmapper, boolean readOnly, MemorySessionImpl sessionImpl) { ensureInitialized(); if (unmapper != null) { - AbstractMemorySegmentImpl segment = + MappedMemorySegmentImpl segment = new MappedMemorySegmentImpl(unmapper.address(), unmapper, size, readOnly, sessionImpl); MemorySessionImpl.ResourceList.ResourceCleanup resource = diff --git a/src/java.base/share/classes/jdk/internal/foreign/abi/fallback/FallbackLinker.java b/src/java.base/share/classes/jdk/internal/foreign/abi/fallback/FallbackLinker.java index 59d3810ecc0..607a29e2ddf 100644 --- a/src/java.base/share/classes/jdk/internal/foreign/abi/fallback/FallbackLinker.java +++ b/src/java.base/share/classes/jdk/internal/foreign/abi/fallback/FallbackLinker.java @@ -46,7 +46,6 @@ import static java.lang.invoke.MethodHandles.foldArguments; import java.lang.invoke.MethodType; import java.lang.ref.Reference; -import java.nio.ByteOrder; import java.util.ArrayList; import java.util.List; import java.util.Map; From 4ae6ce61ea187d6b7aea87cb5ef9e955452affd3 Mon Sep 17 00:00:00 2001 From: Alan Bateman <alanb@openjdk.org> Date: Wed, 27 Nov 2024 07:58:49 +0000 Subject: [PATCH 270/311] 8344300: Implement JEP 499: Structured Concurrency (Fourth Preview) Reviewed-by: vklang --- .../share/classes/jdk/internal/javac/PreviewFeature.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/java.base/share/classes/jdk/internal/javac/PreviewFeature.java b/src/java.base/share/classes/jdk/internal/javac/PreviewFeature.java index b8db00998c0..deb786b42bd 100644 --- a/src/java.base/share/classes/jdk/internal/javac/PreviewFeature.java +++ b/src/java.base/share/classes/jdk/internal/javac/PreviewFeature.java @@ -72,7 +72,7 @@ public enum Feature { IMPLICIT_CLASSES, @JEP(number=487, title="Scoped Values", status="Fourth Preview") SCOPED_VALUES, - @JEP(number=480, title="Structured Concurrency", status="Third Preview") + @JEP(number=499, title="Structured Concurrency", status="Fourth Preview") STRUCTURED_CONCURRENCY, CLASSFILE_API, STREAM_GATHERERS, From 96388be1b59f90d226438917c6f5400bb0af5106 Mon Sep 17 00:00:00 2001 From: Abhishek Kumar <abhiscxk@openjdk.org> Date: Wed, 27 Nov 2024 08:24:01 +0000 Subject: [PATCH 271/311] 8345004: [BACKOUT] GTK & Nimbus LAF: Tabbed pane's background color is not expected one when change the opaque checkbox. Reviewed-by: psadhukhan, kizune --- .../java/swing/plaf/gtk/GTKLookAndFeel.java | 7 ---- .../sun/java/swing/plaf/gtk/GTKPainter.java | 33 +++++++-------- .../swing/plaf/nimbus/SynthPainterImpl.java | 39 ++++++++---------- .../classes/javax/swing/plaf/nimbus/skin.laf | 10 +---- .../swing/plaf/synth/SynthTabbedPaneUI.java | 41 +------------------ test/jdk/ProblemList.txt | 1 + 6 files changed, 35 insertions(+), 96 deletions(-) diff --git a/src/java.desktop/share/classes/com/sun/java/swing/plaf/gtk/GTKLookAndFeel.java b/src/java.desktop/share/classes/com/sun/java/swing/plaf/gtk/GTKLookAndFeel.java index 9490dc6bdff..480b8bacb30 100644 --- a/src/java.desktop/share/classes/com/sun/java/swing/plaf/gtk/GTKLookAndFeel.java +++ b/src/java.desktop/share/classes/com/sun/java/swing/plaf/gtk/GTKLookAndFeel.java @@ -356,8 +356,6 @@ protected void initComponentDefaults(UIDefaults table) { Double defaultCaretAspectRatio = Double.valueOf(0.025); Color caretColor = table.getColor("caretColor"); Color controlText = table.getColor("controlText"); - Color tabbedPaneBg = new ColorUIResource(238, 238, 238); - Color unselectedTabColor = new ColorUIResource(255, 255, 255); Object fieldInputMap = new UIDefaults.LazyInputMap(new Object[] { "ctrl C", DefaultEditorKit.copyAction, @@ -1029,11 +1027,6 @@ public Object createValue(UIDefaults table) { "TabbedPane.selectedLabelShift", 3, "TabbedPane.font", new FontLazyValue(Region.TABBED_PANE), "TabbedPane.selectedTabPadInsets", new InsetsUIResource(2, 2, 0, 1), - "TabbedPane.selected", tabbedPaneBg, - "TabbedPane.contentOpaque", Boolean.TRUE, - "TabbedPane.tabsOpaque", Boolean.TRUE, - "TabbedPane.contentAreaColor", tabbedPaneBg, - "TabbedPane.unselectedBackground", unselectedTabColor, "Table.scrollPaneBorder", zeroBorder, "Table.background", tableBg, diff --git a/src/java.desktop/share/classes/com/sun/java/swing/plaf/gtk/GTKPainter.java b/src/java.desktop/share/classes/com/sun/java/swing/plaf/gtk/GTKPainter.java index ea27a2a6e0d..fa28eb3ca71 100644 --- a/src/java.desktop/share/classes/com/sun/java/swing/plaf/gtk/GTKPainter.java +++ b/src/java.desktop/share/classes/com/sun/java/swing/plaf/gtk/GTKPainter.java @@ -935,27 +935,22 @@ public void paintTabbedPaneTabBackground(SynthContext context, Graphics g, int x, int y, int w, int h, int tabIndex) { + Region id = context.getRegion(); + int state = context.getComponentState(); + int gtkState = ((state & SynthConstants.SELECTED) != 0 ? + SynthConstants.ENABLED : SynthConstants.PRESSED); JTabbedPane pane = (JTabbedPane)context.getComponent(); - if (UIManager.getBoolean("TabbedPane.tabsOpaque") || pane.isOpaque()) { - Region id = context.getRegion(); - int state = context.getComponentState(); - int gtkState = ((state & SynthConstants.SELECTED) != 0 ? - SynthConstants.ENABLED : SynthConstants.PRESSED); - int placement = pane.getTabPlacement(); - - // Fill the tab rect area - g.fillRect(x, y, w, h); + int placement = pane.getTabPlacement(); - synchronized (UNIXToolkit.GTK_LOCK) { - if (!ENGINE.paintCachedImage(g, x, y, w, h, - id, gtkState, placement, tabIndex)) { - PositionType side = POSITIONS[placement - 1]; - ENGINE.startPainting(g, x, y, w, h, - id, gtkState, placement, tabIndex); - ENGINE.paintExtension(g, context, id, gtkState, - ShadowType.OUT, "tab", x, y, w, h, side, tabIndex); - ENGINE.finishPainting(); - } + synchronized (UNIXToolkit.GTK_LOCK) { + if (!ENGINE.paintCachedImage(g, x, y, w, h, + id, gtkState, placement, tabIndex)) { + PositionType side = POSITIONS[placement - 1]; + ENGINE.startPainting(g, x, y, w, h, + id, gtkState, placement, tabIndex); + ENGINE.paintExtension(g, context, id, gtkState, + ShadowType.OUT, "tab", x, y, w, h, side, tabIndex); + ENGINE.finishPainting(); } } } diff --git a/src/java.desktop/share/classes/javax/swing/plaf/nimbus/SynthPainterImpl.java b/src/java.desktop/share/classes/javax/swing/plaf/nimbus/SynthPainterImpl.java index 96ef2541c7b..ca19a74b6ac 100644 --- a/src/java.desktop/share/classes/javax/swing/plaf/nimbus/SynthPainterImpl.java +++ b/src/java.desktop/share/classes/javax/swing/plaf/nimbus/SynthPainterImpl.java @@ -2111,27 +2111,24 @@ public void paintTabbedPaneTabBackground(SynthContext context, Graphics g, public void paintTabbedPaneTabBackground(SynthContext context, Graphics g, int x, int y, int w, int h, int tabIndex, int orientation) { - JTabbedPane pane = (JTabbedPane)context.getComponent(); - if (UIManager.getBoolean("TabbedPane.tabsOpaque") || pane.isOpaque()) { - if (orientation == JTabbedPane.LEFT) { - AffineTransform transform = new AffineTransform(); - transform.scale(-1, 1); - transform.rotate(Math.toRadians(90)); - paintBackground(context, g, y, x, h, w, transform); - } else if (orientation == JTabbedPane.RIGHT) { - AffineTransform transform = new AffineTransform(); - transform.rotate(Math.toRadians(90)); - transform.translate(0, -(x + w)); - paintBackground(context, g, y, 0, h, w, transform); - } else if (orientation == JTabbedPane.BOTTOM) { - AffineTransform transform = new AffineTransform(); - transform.translate(x, y); - transform.scale(1, -1); - transform.translate(0, -h); - paintBackground(context, g, 0, 0, w, h, transform); - } else { - paintBackground(context, g, x, y, w, h, null); - } + if (orientation == JTabbedPane.LEFT) { + AffineTransform transform = new AffineTransform(); + transform.scale(-1, 1); + transform.rotate(Math.toRadians(90)); + paintBackground(context, g, y, x, h, w, transform); + } else if (orientation == JTabbedPane.RIGHT) { + AffineTransform transform = new AffineTransform(); + transform.rotate(Math.toRadians(90)); + transform.translate(0, -(x + w)); + paintBackground(context, g, y, 0, h, w, transform); + } else if (orientation == JTabbedPane.BOTTOM) { + AffineTransform transform = new AffineTransform(); + transform.translate(x, y); + transform.scale(1, -1); + transform.translate(0, -h); + paintBackground(context, g, 0, 0, w, h, transform); + } else { + paintBackground(context, g, x, y, w, h, null); } } diff --git a/src/java.desktop/share/classes/javax/swing/plaf/nimbus/skin.laf b/src/java.desktop/share/classes/javax/swing/plaf/nimbus/skin.laf index 1d486f9fe06..38e8530983a 100644 --- a/src/java.desktop/share/classes/javax/swing/plaf/nimbus/skin.laf +++ b/src/java.desktop/share/classes/javax/swing/plaf/nimbus/skin.laf @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="UTF-8"?> <!-- - Copyright (c) 1998, 2024, Oracle and/or its affiliates. All rights reserved. + Copyright (c) 1998, 2017, Oracle and/or its affiliates. All rights reserved. DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. This code is free software; you can redistribute it and/or modify it @@ -83,9 +83,6 @@ <uiColor name="nimbusDisabledText"> <matte red="142" green="143" blue="145" alpha="255" hueOffset="0.0" saturationOffset="0.0" brightnessOffset="0.0" alphaOffset="0"/> </uiColor> - <uiColor name="nimbusTabbedPaneContentArea"> - <matte red="238" green="238" blue="238" alpha="255" hueOffset="0.0" saturationOffset="0.0" brightnessOffset="0.0" alphaOffset="0"/> - </uiColor> <uiColor name="nimbusLightBackground"> <matte red="255" green="255" blue="255" alpha="255" hueOffset="0.0" saturationOffset="0.0" brightnessOffset="0.0" alphaOffset="0"/> </uiColor> @@ -21649,11 +21646,6 @@ <uiProperty name="tabOverlap" type="INT" value="-1"/> <uiProperty name="extendTabsToBase" type="BOOLEAN" value="true"/> <uiProperty name="useBasicArrows" type="BOOLEAN" value="true"/> - <uiProperty name="contentOpaque" type="BOOLEAN" value="true"/> - <uiProperty name="tabsOpaque" type="BOOLEAN" value="true"/> - <uiProperty name="contentAreaColor" type="COLOR"> - <matte red="238" green="238" blue="238" alpha="255" uiDefaultParentName="nimbusTabbedPaneContentArea" hueOffset="0.0" saturationOffset="0.0" brightnessOffset="0.0" alphaOffset="0"/> - </uiProperty> <uiProperty name="shadow" type="COLOR"> <matte red="142" green="143" blue="145" alpha="255" uiDefaultParentName="nimbusDisabledText" hueOffset="0.0" saturationOffset="0.0" brightnessOffset="0.0" alphaOffset="0"/> </uiProperty> diff --git a/src/java.desktop/share/classes/javax/swing/plaf/synth/SynthTabbedPaneUI.java b/src/java.desktop/share/classes/javax/swing/plaf/synth/SynthTabbedPaneUI.java index 3378ef9e8b3..1eed3c4ad14 100644 --- a/src/java.desktop/share/classes/javax/swing/plaf/synth/SynthTabbedPaneUI.java +++ b/src/java.desktop/share/classes/javax/swing/plaf/synth/SynthTabbedPaneUI.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2021, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,7 +26,6 @@ package javax.swing.plaf.synth; import java.awt.Component; -import java.awt.Color; import java.awt.Font; import java.awt.FontMetrics; import java.awt.Graphics; @@ -122,12 +121,6 @@ public class SynthTabbedPaneUI extends BasicTabbedPaneUI private boolean selectedTabIsPressed = false; - // Background color for selected tab and content pane - private Color selectColor; - // Background color for unselected tabs - private Color unselectedBackground; - private boolean contentOpaque = true; - /** * * Constructs a {@code SynthTabbedPaneUI}. @@ -153,9 +146,6 @@ private boolean scrollableTabLayoutEnabled() { */ @Override protected void installDefaults() { - selectColor = UIManager.getColor("TabbedPane.selected"); - contentOpaque = UIManager.getBoolean("TabbedPane.contentOpaque"); - unselectedBackground = UIManager.getColor("TabbedPane.unselectedBackground"); updateStyle(tabPane); } @@ -647,12 +637,6 @@ private void paintTab(SynthContext ss, Graphics g, } } - if (isSelected) { - g.setColor(selectColor); - } else { - g.setColor(getUnselectedBackgroundAt(tabIndex)); - } - tabContext.getPainter().paintTabbedPaneTabBackground(tabContext, g, x, y, width, height, tabIndex, placement); tabContext.getPainter().paintTabbedPaneTabBorder(tabContext, g, @@ -675,14 +659,6 @@ private void paintTab(SynthContext ss, Graphics g, } } - private Color getUnselectedBackgroundAt(int index) { - Color color = tabPane.getBackgroundAt(index); - if (color instanceof UIResource && unselectedBackground != null) { - return unselectedBackground; - } - return color; - } - private void layoutLabel(SynthContext ss, int tabPlacement, FontMetrics metrics, int tabIndex, String title, Icon icon, @@ -760,21 +736,6 @@ private void paintContentBorder(SynthContext ss, Graphics g, h -= (y - insets.top); } SynthLookAndFeel.updateSubregion(ss, g, new Rectangle(x, y, w, h)); - - if (tabPane.getTabCount() > 0 && (contentOpaque || tabPane.isOpaque())) { - // Fill region behind content area - Color color = UIManager.getColor("TabbedPane.contentAreaColor"); - if (color != null) { - g.setColor(color); - } else if (selectColor == null || selectedIndex == -1) { - g.setColor(tabPane.getBackground()); - } else { - g.setColor(selectColor); - } - // fill content area rect for both GTK and Nimbus LAF here - g.fillRect(x, y, w, h); - } - ss.getPainter().paintTabbedPaneContentBackground(ss, g, x, y, w, h); ss.getPainter().paintTabbedPaneContentBorder(ss, g, x, y, w, h); diff --git a/test/jdk/ProblemList.txt b/test/jdk/ProblemList.txt index 63cfb2a338f..7e4191a734f 100644 --- a/test/jdk/ProblemList.txt +++ b/test/jdk/ProblemList.txt @@ -791,6 +791,7 @@ jdk/jfr/jvm/TestWaste.java 8282427 generic- javax/swing/JFileChooser/6698013/bug6698013.java 8024419 macosx-all javax/swing/JColorChooser/8065098/bug8065098.java 8065647 macosx-all javax/swing/JTabbedPane/4666224/bug4666224.java 8144124 macosx-all +javax/swing/JTabbedPane/TestJTabbedPaneOpaqueColor.java 8345090 windows-all,linux-all javax/swing/SwingUtilities/TestTextPosInPrint.java 8227025 windows-all java/awt/event/MouseEvent/SpuriousExitEnter/SpuriousExitEnter_1.java 7131438,8022539 generic-all From b3986bdbdbafabde5beb15300444034363723449 Mon Sep 17 00:00:00 2001 From: Emanuel Peter <epeter@openjdk.org> Date: Wed, 27 Nov 2024 09:15:57 +0000 Subject: [PATCH 272/311] 8344118: C2 SuperWord: add VectorThroughputForIterationCount benchmark Reviewed-by: kvn, jbhateja, chagedorn --- .../VectorThroughputForIterationCount.java | 436 ++++++++++++++++++ 1 file changed, 436 insertions(+) create mode 100644 test/micro/org/openjdk/bench/vm/compiler/VectorThroughputForIterationCount.java diff --git a/test/micro/org/openjdk/bench/vm/compiler/VectorThroughputForIterationCount.java b/test/micro/org/openjdk/bench/vm/compiler/VectorThroughputForIterationCount.java new file mode 100644 index 00000000000..79f693b16d9 --- /dev/null +++ b/test/micro/org/openjdk/bench/vm/compiler/VectorThroughputForIterationCount.java @@ -0,0 +1,436 @@ +/* + * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package org.openjdk.bench.vm.compiler; + +import org.openjdk.jmh.annotations.*; +import org.openjdk.jmh.infra.*; + +import java.util.concurrent.TimeUnit; +import java.util.Random; + +// Note: I commented out the short, char, float and double benchmarks, so it only takes 5h instead of 12h. +// The goal is to track the performance of various loop sizes, and see the effect of pre/post loops. + +@BenchmarkMode(Mode.AverageTime) +@OutputTimeUnit(TimeUnit.NANOSECONDS) +@State(Scope.Thread) +@Warmup(iterations = 2, time = 500, timeUnit = TimeUnit.MILLISECONDS) +@Measurement(iterations = 3, time = 500, timeUnit = TimeUnit.MILLISECONDS) +@Fork(value = 1) +public abstract class VectorThroughputForIterationCount { + @Param({ "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", + "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", + "20", "21", "22", "23", "24", "25", "26", "27", "28", "29", + "30", "31", "32", "33", "34", "35", "36", "37", "38", "39", + "40", "41", "42", "43", "44", "45", "46", "47", "48", "49", + "50", "51", "52", "53", "54", "55", "56", "57", "58", "59", + "60", "61", "62", "63", "64", "65", "66", "67", "68", "69", + "70", "71", "72", "73", "74", "75", "76", "77", "78", "79", + "80", "81", "82", "83", "84", "85", "86", "87", "88", "89", + "90", "91", "92", "93", "94", "95", "96", "97", "98", "99", + "100","101","102","103","104","105","106","107","108","109", + "110","111","112","113","114","115","116","117","118","119", + "120","121","122","123","124","125","126","127","128","129", + "130","131","132","133","134","135","136","137","138","139", + "140","141","142","143","144","145","146","147","148","149", + "150","151","152","153","154","155","156","157","158","159", + "160","161","162","163","164","165","166","167","168","169", + "170","171","172","173","174","175","176","177","178","179", + "180","181","182","183","184","185","186","187","188","189", + "190","191","192","193","194","195","196","197","198","199", + "200","201","202","203","204","205","206","207","208","209", + "210","211","212","213","214","215","216","217","218","219", + "220","221","222","223","224","225","226","227","228","229", + "230","231","232","233","234","235","236","237","238","239", + "240","241","242","243","244","245","246","247","248","249", + "250","251","252","253","254","255","256","257","258","259", + "260","261","262","263","264","265","266","267","268","269", + "270","271","272","273","274","275","276","277","278","279", + "280","281","282","283","284","285","286","287","288","289", + "290","291","292","293","294","295","296","297","298","299", + "300", + // Above, the "small loops". + // Below, some "medium" to "large" loops. + "1000", "3000", "10000"}) + // Number of iterations spent in a loop. + public static int ITERATION_COUNT; + + // Add enough slack so we can play with offsets / alignment. + public static int CONTAINER_SIZE = 20_000; + + private byte[] aB; + private byte[] bB; + private byte[] rB; + + private short[] aS; + private short[] bS; + private short[] rS; + + private char[] aC; + private char[] bC; + private char[] rC; + + private int[] aI; + private int[] bI; + private int[] rI; + + private long[] aL; + private long[] bL; + private long[] rL; + + private float[] aF; + private float[] bF; + private float[] rF; + + private double[] aD; + private double[] bD; + private double[] rD; + + @Param({"1024"}) + // Number of times we run the loop, possibly with different offsets. + public static int REPETITIONS; + + @Param({"true", "false"}) + public static boolean RANDOMIZE_OFFSETS; + + @Param({"0"}) + // If RANDOMIZE_OFFSETS is disabled, use this offset: + public static int FIXED_OFFSET; + + // A different offset for each repetition of the loop. Depending on + // RANDOMIZE_OFFSETS, the values are random or all FIXED_OFFSET. + private int[] offsets; + + @Param("42") + private int seed; + private Random r = new Random(seed); + + @Setup + public void init() { + aI = new int[CONTAINER_SIZE]; + bI = new int[CONTAINER_SIZE]; + rI = new int[CONTAINER_SIZE]; + + aL = new long[CONTAINER_SIZE]; + bL = new long[CONTAINER_SIZE]; + rL = new long[CONTAINER_SIZE]; + + aS = new short[CONTAINER_SIZE]; + bS = new short[CONTAINER_SIZE]; + rS = new short[CONTAINER_SIZE]; + + aC = new char[CONTAINER_SIZE]; + bC = new char[CONTAINER_SIZE]; + rC = new char[CONTAINER_SIZE]; + + aB = new byte[CONTAINER_SIZE]; + bB = new byte[CONTAINER_SIZE]; + rB = new byte[CONTAINER_SIZE]; + + aF = new float[CONTAINER_SIZE]; + bF = new float[CONTAINER_SIZE]; + rF = new float[CONTAINER_SIZE]; + + aD = new double[CONTAINER_SIZE]; + bD = new double[CONTAINER_SIZE]; + rD = new double[CONTAINER_SIZE]; + + for (int i = 0; i < CONTAINER_SIZE; i++) { + aB[i] = (byte) r.nextInt(); + bB[i] = (byte) r.nextInt(); + + aS[i] = (short) r.nextInt(); + bS[i] = (short) r.nextInt(); + + aC[i] = (char) r.nextInt(); + bC[i] = (char) r.nextInt(); + + aI[i] = r.nextInt(); + bI[i] = r.nextInt(); + + aL[i] = r.nextLong(); + bL[i] = r.nextLong(); + + aF[i] = r.nextFloat(); + bF[i] = r.nextFloat(); + + aD[i] = r.nextDouble(); + bD[i] = r.nextDouble(); + } + + offsets = new int[REPETITIONS]; + if (RANDOMIZE_OFFSETS) { + for (int i = 0; i < REPETITIONS; i++) { + // Make sure it is predictable and uniform. + offsets[i] = i % 64; + } + } else { + for (int i = 0; i < REPETITIONS; i++) { + offsets[i] = FIXED_OFFSET; + } + } + } + + @Benchmark + public void bench001B_aligned_computeBound() { + for (int r = 0; r < REPETITIONS; r++) { + int init = offsets[r]; + int limit = init + ITERATION_COUNT; + for (int i = init; i < limit; i++) { + // Have multiple MUL operations to make loop compute bound (more compute than load/store) + rB[i] = (byte)(aB[i] * aB[i] * aB[i] * aB[i]); + } + } + } + + @Benchmark + public void bench011B_aligned_memoryBound() { + for (int r = 0; r < REPETITIONS; r++) { + int init = offsets[r]; + int limit = init + ITERATION_COUNT; + for (int i = init; i < limit; i++) { + rB[i] = (byte)(aB[i] + bB[i]); + } + } + } + + @Benchmark + public void bench021B_unaligned_memoryBound() { + for (int r = 0; r < REPETITIONS; r++) { + int init = offsets[r]; + int limit = init + ITERATION_COUNT; + for (int i = init; i < limit; i++) { + rB[i] = (byte)(aB[i+1] + bB[i+2]); + } + } + } + +// @Benchmark +// public void bench002S_aligned_computeBound() { +// for (int r = 0; r < REPETITIONS; r++) { +// int init = offsets[r]; +// int limit = init + ITERATION_COUNT; +// for (int i = init; i < limit; i++) { +// // Have multiple MUL operations to make loop compute bound (more compute than load/store) +// rS[i] = (short)(aS[i] * aS[i] * aS[i] * aS[i]); +// } +// } +// } +// +// @Benchmark +// public void bench012S_aligned_memoryBound() { +// for (int r = 0; r < REPETITIONS; r++) { +// int init = offsets[r]; +// int limit = init + ITERATION_COUNT; +// for (int i = init; i < limit; i++) { +// rS[i] = (short)(aS[i] + bS[i]); +// } +// } +// } +// +// @Benchmark +// public void bench022S_unaligned_memoryBound() { +// for (int r = 0; r < REPETITIONS; r++) { +// int init = offsets[r]; +// int limit = init + ITERATION_COUNT; +// for (int i = init; i < limit; i++) { +// rS[i] = (short)(aS[i+1] + bS[i+2]); +// } +// } +// } +// +// @Benchmark +// public void bench003C_aligned_computeBound() { +// for (int r = 0; r < REPETITIONS; r++) { +// int init = offsets[r]; +// int limit = init + ITERATION_COUNT; +// for (int i = init; i < limit; i++) { +// // Have multiple MUL operations to make loop compute bound (more compute than load/store) +// rC[i] = (char)(aC[i] * aC[i] * aC[i] * aC[i]); +// } +// } +// } +// +// @Benchmark +// public void bench013C_aligned_memoryBound() { +// for (int r = 0; r < REPETITIONS; r++) { +// int init = offsets[r]; +// int limit = init + ITERATION_COUNT; +// for (int i = init; i < limit; i++) { +// rC[i] = (char)(aC[i] + bC[i]); +// } +// } +// } +// +// @Benchmark +// public void bench023C_unaligned_memoryBound() { +// for (int r = 0; r < REPETITIONS; r++) { +// int init = offsets[r]; +// int limit = init + ITERATION_COUNT; +// for (int i = init; i < limit; i++) { +// rC[i] = (char)(aC[i+1] + bC[i+2]); +// } +// } +// } + + @Benchmark + public void bench004I_aligned_computeBound() { + for (int r = 0; r < REPETITIONS; r++) { + int init = offsets[r]; + int limit = init + ITERATION_COUNT; + for (int i = init; i < limit; i++) { + // Have multiple MUL operations to make loop compute bound (more compute than load/store) + rI[i] = (int)(aI[i] * aI[i] * aI[i] * aI[i]); + } + } + } + + @Benchmark + public void bench014I_aligned_memoryBound() { + for (int r = 0; r < REPETITIONS; r++) { + int init = offsets[r]; + int limit = init + ITERATION_COUNT; + for (int i = init; i < limit; i++) { + rI[i] = (int)(aI[i] + bI[i]); + } + } + } + + @Benchmark + public void bench024I_unaligned_memoryBound() { + for (int r = 0; r < REPETITIONS; r++) { + int init = offsets[r]; + int limit = init + ITERATION_COUNT; + for (int i = init; i < limit; i++) { + rI[i] = (int)(aI[i+1] + bI[i+2]); + } + } + } + + @Benchmark + public void bench005L_aligned_computeBound() { + for (int r = 0; r < REPETITIONS; r++) { + int init = offsets[r]; + int limit = init + ITERATION_COUNT; + for (int i = init; i < limit; i++) { + // Have multiple MUL operations to make loop compute bound (more compute than load/store) + rL[i] = (long)(aL[i] * aL[i] * aL[i] * aL[i]); + } + } + } + + @Benchmark + public void bench015L_aligned_memoryBound() { + for (int r = 0; r < REPETITIONS; r++) { + int init = offsets[r]; + int limit = init + ITERATION_COUNT; + for (int i = init; i < limit; i++) { + rL[i] = (long)(aL[i] + bL[i]); + } + } + } + + @Benchmark + public void bench025L_unaligned_memoryBound() { + for (int r = 0; r < REPETITIONS; r++) { + int init = offsets[r]; + int limit = init + ITERATION_COUNT; + for (int i = init; i < limit; i++) { + rL[i] = (long)(aL[i+1] + bL[i+2]); + } + } + } + +// @Benchmark +// public void bench006F_aligned_computeBound() { +// for (int r = 0; r < REPETITIONS; r++) { +// int init = offsets[r]; +// int limit = init + ITERATION_COUNT; +// for (int i = init; i < limit; i++) { +// // Have multiple MUL operations to make loop compute bound (more compute than load/store) +// rF[i] = (float)(aF[i] * aF[i] * aF[i] * aF[i]); +// } +// } +// } +// +// @Benchmark +// public void bench016F_aligned_memoryBound() { +// for (int r = 0; r < REPETITIONS; r++) { +// int init = offsets[r]; +// int limit = init + ITERATION_COUNT; +// for (int i = init; i < limit; i++) { +// rF[i] = (float)(aF[i] + bF[i]); +// } +// } +// } +// +// @Benchmark +// public void bench026F_unaligned_memoryBound() { +// for (int r = 0; r < REPETITIONS; r++) { +// int init = offsets[r]; +// int limit = init + ITERATION_COUNT; +// for (int i = init; i < limit; i++) { +// rF[i] = (float)(aF[i+1] + bF[i+2]); +// } +// } +// } +// +// @Benchmark +// public void bench007D_aligned_computeBound() { +// for (int r = 0; r < REPETITIONS; r++) { +// int init = offsets[r]; +// int limit = init + ITERATION_COUNT; +// for (int i = init; i < limit; i++) { +// // Have multiple MUL operations to make loop compute bound (more compute than load/store) +// rD[i] = (double)(aD[i] * aD[i] * aD[i] * aD[i]); +// } +// } +// } +// +// @Benchmark +// public void bench017D_aligned_memoryBound() { +// for (int r = 0; r < REPETITIONS; r++) { +// int init = offsets[r]; +// int limit = init + ITERATION_COUNT; +// for (int i = init; i < limit; i++) { +// rD[i] = (double)(aD[i] + bD[i]); +// } +// } +// } +// +// @Benchmark +// public void bench027D_unaligned_memoryBound() { +// for (int r = 0; r < REPETITIONS; r++) { +// int init = offsets[r]; +// int limit = init + ITERATION_COUNT; +// for (int i = init; i < limit; i++) { +// rD[i] = (double)(aD[i+1] + bD[i+2]); +// } +// } +// } + + @Fork(value = 1, jvmArgs = { + "-XX:+UseSuperWord" + }) + public static class SuperWord extends VectorThroughputForIterationCount {} +} From 82137db24da7e922c18036eca80291abce5d8bf1 Mon Sep 17 00:00:00 2001 From: Fei Yang <fyang@openjdk.org> Date: Wed, 27 Nov 2024 10:26:09 +0000 Subject: [PATCH 273/311] 8345047: RISC-V: Remove explicit use of AvoidUnalignedAccesses in interpreter Reviewed-by: mli, fjiang --- src/hotspot/cpu/riscv/interp_masm_riscv.cpp | 23 ++++------------ src/hotspot/cpu/riscv/templateTable_riscv.cpp | 26 ++++++------------- 2 files changed, 13 insertions(+), 36 deletions(-) diff --git a/src/hotspot/cpu/riscv/interp_masm_riscv.cpp b/src/hotspot/cpu/riscv/interp_masm_riscv.cpp index 897222ef995..ece872ac034 100644 --- a/src/hotspot/cpu/riscv/interp_masm_riscv.cpp +++ b/src/hotspot/cpu/riscv/interp_masm_riscv.cpp @@ -179,15 +179,10 @@ void InterpreterMacroAssembler::check_and_handle_earlyret(Register java_thread) void InterpreterMacroAssembler::get_unsigned_2_byte_index_at_bcp(Register reg, int bcp_offset) { assert(bcp_offset >= 0, "bcp is still pointing to start of bytecode"); - if (AvoidUnalignedAccesses && (bcp_offset % 2)) { - lbu(t1, Address(xbcp, bcp_offset)); - lbu(reg, Address(xbcp, bcp_offset + 1)); - slli(t1, t1, 8); - add(reg, reg, t1); - } else { - lhu(reg, Address(xbcp, bcp_offset)); - revb_h_h_u(reg, reg); - } + lbu(t1, Address(xbcp, bcp_offset)); + lbu(reg, Address(xbcp, bcp_offset + 1)); + slli(t1, t1, 8); + add(reg, reg, t1); } void InterpreterMacroAssembler::get_dispatch() { @@ -200,15 +195,7 @@ void InterpreterMacroAssembler::get_cache_index_at_bcp(Register index, size_t index_size) { assert(bcp_offset > 0, "bcp is still pointing to start of bytecode"); if (index_size == sizeof(u2)) { - if (AvoidUnalignedAccesses) { - assert_different_registers(index, tmp); - load_unsigned_byte(index, Address(xbcp, bcp_offset)); - load_unsigned_byte(tmp, Address(xbcp, bcp_offset + 1)); - slli(tmp, tmp, 8); - add(index, index, tmp); - } else { - load_unsigned_short(index, Address(xbcp, bcp_offset)); - } + load_short_misaligned(index, Address(xbcp, bcp_offset), tmp, false); } else if (index_size == sizeof(u4)) { load_int_misaligned(index, Address(xbcp, bcp_offset), tmp, false); } else if (index_size == sizeof(u1)) { diff --git a/src/hotspot/cpu/riscv/templateTable_riscv.cpp b/src/hotspot/cpu/riscv/templateTable_riscv.cpp index 52b33c62616..62dc952bde0 100644 --- a/src/hotspot/cpu/riscv/templateTable_riscv.cpp +++ b/src/hotspot/cpu/riscv/templateTable_riscv.cpp @@ -292,15 +292,10 @@ void TemplateTable::bipush() { void TemplateTable::sipush() { transition(vtos, itos); - if (AvoidUnalignedAccesses) { - __ load_signed_byte(x10, at_bcp(1)); - __ load_unsigned_byte(t1, at_bcp(2)); - __ slli(x10, x10, 8); - __ add(x10, x10, t1); - } else { - __ load_unsigned_short(x10, at_bcp(1)); - __ revb_h_h(x10, x10); // reverse bytes in half-word and sign-extend - } + __ load_signed_byte(x10, at_bcp(1)); + __ load_unsigned_byte(t1, at_bcp(2)); + __ slli(x10, x10, 8); + __ add(x10, x10, t1); } void TemplateTable::ldc(LdcType type) { @@ -1626,15 +1621,10 @@ void TemplateTable::branch(bool is_jsr, bool is_wide) { // load branch displacement if (!is_wide) { - if (AvoidUnalignedAccesses) { - __ lb(x12, at_bcp(1)); - __ lbu(t1, at_bcp(2)); - __ slli(x12, x12, 8); - __ add(x12, x12, t1); - } else { - __ lhu(x12, at_bcp(1)); - __ revb_h_h(x12, x12); // reverse bytes in half-word and sign-extend - } + __ lb(x12, at_bcp(1)); + __ lbu(t1, at_bcp(2)); + __ slli(x12, x12, 8); + __ add(x12, x12, t1); } else { __ lwu(x12, at_bcp(1)); __ revb_w_w(x12, x12); // reverse bytes in word and sign-extend From eb0d1ce9487df000b4675901cc0d18f6a1c86348 Mon Sep 17 00:00:00 2001 From: Andrew Haley <aph@openjdk.org> Date: Wed, 27 Nov 2024 10:27:58 +0000 Subject: [PATCH 274/311] 8344355: Register corruption in MacroAssembler::lookup_secondary_supers_table_var: x86-64 only Reviewed-by: vlivanov, martin, dlong, asemenov --- src/hotspot/cpu/x86/macroAssembler_x86.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/hotspot/cpu/x86/macroAssembler_x86.cpp b/src/hotspot/cpu/x86/macroAssembler_x86.cpp index 08e089455f2..c08e535ee0e 100644 --- a/src/hotspot/cpu/x86/macroAssembler_x86.cpp +++ b/src/hotspot/cpu/x86/macroAssembler_x86.cpp @@ -4912,6 +4912,10 @@ void MacroAssembler::population_count(Register dst, Register src, } bind(done); } +#ifdef ASSERT + mov64(scratch1, 0xCafeBabeDeadBeef); + movq(scratch2, scratch1); +#endif } // Ensure that the inline code and the stub are using the same registers. @@ -5113,6 +5117,7 @@ void MacroAssembler::lookup_secondary_supers_table_var(Register r_sub_klass, const Register r_array_base = *available_regs++; // Get the first array index that can contain super_klass into r_array_index. + // Note: Clobbers r_array_base and slot. population_count(r_array_index, r_array_index, /*temp2*/r_array_base, /*temp3*/slot); // NB! r_array_index is off by 1. It is compensated by keeping r_array_base off by 1 word. @@ -5130,7 +5135,7 @@ void MacroAssembler::lookup_secondary_supers_table_var(Register r_sub_klass, jccb(Assembler::equal, L_success); // Restore slot to its true value - xorl(slot, (u1)(Klass::SECONDARY_SUPERS_TABLE_SIZE - 1)); // slot ^ 63 === 63 - slot (mod 64) + movb(slot, Address(r_super_klass, Klass::hash_slot_offset())); // Linear probe. Rotate the bitmap so that the next bit to test is // in Bit 1. From 461ffafeba459c077f1c2d9c5037305b71a8bc2a Mon Sep 17 00:00:00 2001 From: Jorn Vernee <jvernee@openjdk.org> Date: Wed, 27 Nov 2024 12:20:51 +0000 Subject: [PATCH 275/311] 8331735: UpcallLinker::on_exit races with GC when copying frame anchor 8343144: UpcallLinker::on_entry racingly clears pending exception with GC safepoints 8286875: ProgrammableUpcallHandler::on_entry/on_exit access thread fields from native Reviewed-by: dholmes, eosterlund, aboldtch --- src/hotspot/share/prims/upcallLinker.cpp | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/src/hotspot/share/prims/upcallLinker.cpp b/src/hotspot/share/prims/upcallLinker.cpp index 7511e278c69..cdc4e44a981 100644 --- a/src/hotspot/share/prims/upcallLinker.cpp +++ b/src/hotspot/share/prims/upcallLinker.cpp @@ -84,16 +84,16 @@ JavaThread* UpcallLinker::on_entry(UpcallStub::FrameData* context) { // since it can potentially block. context->new_handles = JNIHandleBlock::allocate_block(thread); - // clear any pending exception in thread (native calls start with no exception pending) - thread->clear_pending_exception(); - // The call to transition_from_native below contains a safepoint check // which needs the code cache to be writable. MACOS_AARCH64_ONLY(ThreadWXEnable wx(WXWrite, thread)); // After this, we are officially in Java Code. This needs to be done before we change any of the thread local // info, since we cannot find oops before the new information is set up completely. - ThreadStateTransition::transition_from_native(thread, _thread_in_Java, true /* check_asyncs */); + ThreadStateTransition::transition_from_native(thread, _thread_in_Java, false /* check_asyncs */); + + // clear any pending exception in thread, in case someone forgot to check it after a JNI API call. + thread->clear_pending_exception(); context->old_handles = thread->active_handles(); @@ -119,20 +119,16 @@ void UpcallLinker::on_exit(UpcallStub::FrameData* context) { // restore previous handle block thread->set_active_handles(context->old_handles); - thread->frame_anchor()->zap(); - debug_only(thread->dec_java_call_counter()); + thread->frame_anchor()->copy(&context->jfa); + // Old thread-local info. has been restored. We are now back in native code. ThreadStateTransition::transition_from_java(thread, _thread_in_native); - thread->frame_anchor()->copy(&context->jfa); - // Release handles after we are marked as being in native code again, since this // operation might block JNIHandleBlock::release_block(context->new_handles, thread); - - assert(!thread->has_pending_exception(), "Upcall can not throw an exception"); } void UpcallLinker::handle_uncaught_exception(oop exception) { From 494806286f126b29b7fc6eb217fa2ae26f295072 Mon Sep 17 00:00:00 2001 From: Casper Norrbin <cnorrbin@openjdk.org> Date: Wed, 27 Nov 2024 12:27:31 +0000 Subject: [PATCH 276/311] 8318127: align_up has potential overflow Reviewed-by: kbarrett, dlong --- src/hotspot/share/utilities/align.hpp | 4 ++- .../gtest/runtime/test_os_reserve_between.cpp | 4 +-- test/hotspot/gtest/utilities/test_align.cpp | 35 +++++++++++++++++-- 3 files changed, 38 insertions(+), 5 deletions(-) diff --git a/src/hotspot/share/utilities/align.hpp b/src/hotspot/share/utilities/align.hpp index 4640f05e4d0..935781a5561 100644 --- a/src/hotspot/share/utilities/align.hpp +++ b/src/hotspot/share/utilities/align.hpp @@ -72,7 +72,9 @@ constexpr T align_down(T size, A alignment) { template<typename T, typename A, ENABLE_IF(std::is_integral<T>::value)> constexpr T align_up(T size, A alignment) { - T adjusted = checked_cast<T>(size + alignment_mask(alignment)); + T mask = checked_cast<T>(alignment_mask(alignment)); + assert(size <= std::numeric_limits<T>::max() - mask, "overflow"); + T adjusted = size + mask; return align_down(adjusted, alignment); } diff --git a/test/hotspot/gtest/runtime/test_os_reserve_between.cpp b/test/hotspot/gtest/runtime/test_os_reserve_between.cpp index aad6acc095a..16e1bdd1b21 100644 --- a/test/hotspot/gtest/runtime/test_os_reserve_between.cpp +++ b/test/hotspot/gtest/runtime/test_os_reserve_between.cpp @@ -304,12 +304,12 @@ TEST_VM(os, attempt_reserve_memory_randomization_cornercases) { // Zero-sized range test_attempt_reserve_memory_between(nullptr, nullptr, ps, ag, false, Expect::failure()); test_attempt_reserve_memory_between((char*)(3 * G), (char*)(3 * G), ps, ag, false, Expect::dontcare(), __LINE__); - test_attempt_reserve_memory_between((char*)SIZE_MAX, (char*)SIZE_MAX, ps, ag, false, Expect::failure(), __LINE__); + test_attempt_reserve_memory_between((char*)SIZE_MAX-ag, (char*)SIZE_MAX-ag, ps, ag, false, Expect::failure(), __LINE__); test_attempt_reserve_memory_between(nullptr, nullptr, ps, ag, true, Expect::failure()); test_attempt_reserve_memory_between((char*)(3 * G), (char*)(3 * G), ps, ag, true, Expect::dontcare(), __LINE__); test_attempt_reserve_memory_between((char*)(3 * G), (char*)(3 * G), ps, ag, true, Expect::dontcare(), __LINE__); - test_attempt_reserve_memory_between((char*)SIZE_MAX, (char*)SIZE_MAX, ps, ag, true, Expect::failure(), __LINE__); + test_attempt_reserve_memory_between((char*)SIZE_MAX-ag, (char*)SIZE_MAX-ag, ps, ag, true, Expect::failure(), __LINE__); // Full size // Note: paradoxically, success is not guaranteed here, since a significant portion of the attach points diff --git a/test/hotspot/gtest/utilities/test_align.cpp b/test/hotspot/gtest/utilities/test_align.cpp index f5e6b9d9646..4efcf14a7f0 100644 --- a/test/hotspot/gtest/utilities/test_align.cpp +++ b/test/hotspot/gtest/utilities/test_align.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,6 +23,7 @@ #include "precompiled.hpp" #include "utilities/align.hpp" +#include "utilities/checkedCast.hpp" #include "utilities/formatBuffer.hpp" #include "utilities/globalDefinitions.hpp" #include "unittest.hpp" @@ -30,7 +31,7 @@ #include <limits> // A few arbitrarily chosen values to test the align functions on. -static constexpr uint64_t values[] = {1, 3, 10, 345, 1023, 1024, 1025, 23909034, INT_MAX, uint64_t(-1) / 2, uint64_t(-1) / 2 + 100, uint64_t(-1)}; +static constexpr uint64_t values[] = {1, 3, 10, 345, 1023, 1024, 1025, 23909034, INT_MAX, uint64_t(-1) / 2, uint64_t(-1) / 2 + 100, ~(uint64_t(1) << 62)}; template <typename T> static constexpr T max_alignment() { @@ -195,3 +196,33 @@ TEST(Align, alignments) { test_alignments<int8_t, int8_t>(); } + +#ifdef ASSERT +template <typename T, typename A> +static void test_fail_alignment() { + A alignment = max_alignment<A>(); + T value = align_down(std::numeric_limits<T>::max(), alignment) + 1; + // Aligning up would overflow, as there is not enough room for alignment + T aligned = align_up(value, alignment); +} + +TEST_VM_ASSERT(Align, fail_alignments_same_size) { + test_fail_alignment<uint64_t, uint64_t>(); +} + +TEST_VM_ASSERT(Align, fail_alignments_unsigned_signed) { + test_fail_alignment<uint32_t, int32_t>(); +} + +TEST_VM_ASSERT(Align, fail_alignments_signed_unsigned) { + test_fail_alignment<int64_t, int32_t>(); +} + +TEST_VM_ASSERT(Align, fail_alignments_small_large) { + test_fail_alignment<uint8_t, uint64_t>(); +} + +TEST_VM_ASSERT(Align, fail_alignments_large_small) { + test_fail_alignment<uint64_t, uint8_t>(); +} +#endif // ASSERT From 4a22c1fefc879ee50ef032e741e92357284a09bf Mon Sep 17 00:00:00 2001 From: Alexey Semenyuk <asemenyuk@openjdk.org> Date: Wed, 27 Nov 2024 12:42:34 +0000 Subject: [PATCH 277/311] 8344770: Switch jpackage unit tests to use JUnit5 Reviewed-by: almatvee --- .../jpackage/internal/AppImageFileTest.java | 190 +++++---- .../internal/ApplicationLayoutTest.java | 49 ++- .../internal/CompareDottedVersionTest.java | 111 ----- .../jpackage/internal/DeployParamsTest.java | 73 +--- .../jpackage/internal/DottedVersionTest.java | 308 ++++++++------ .../jdk/jpackage/internal/EnquoterTest.java | 57 ++- .../internal/InvalidDottedVersionTest.java | 72 ---- .../internal/OverridableResourceTest.java | 383 ++++++++++++------ .../jdk/jpackage/internal/PathGroupTest.java | 115 +++--- .../internal/PlatformVersionTest.java | 130 +++--- .../jpackage/internal/ToolValidatorTest.java | 23 +- 11 files changed, 757 insertions(+), 754 deletions(-) delete mode 100644 test/jdk/tools/jpackage/junit/jdk.jpackage/jdk/jpackage/internal/CompareDottedVersionTest.java delete mode 100644 test/jdk/tools/jpackage/junit/jdk.jpackage/jdk/jpackage/internal/InvalidDottedVersionTest.java diff --git a/test/jdk/tools/jpackage/junit/jdk.jpackage/jdk/jpackage/internal/AppImageFileTest.java b/test/jdk/tools/jpackage/junit/jdk.jpackage/jdk/jpackage/internal/AppImageFileTest.java index 4ecadf86005..64acd24040e 100644 --- a/test/jdk/tools/jpackage/junit/jdk.jpackage/jdk/jpackage/internal/AppImageFileTest.java +++ b/test/jdk/tools/jpackage/junit/jdk.jpackage/jdk/jpackage/internal/AppImageFileTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -31,16 +31,18 @@ import java.util.List; import java.util.Map; import java.util.LinkedHashMap; -import org.junit.Assert; -import org.junit.Test; -import org.junit.Rule; -import org.junit.rules.TemporaryFolder; -import org.junit.function.ThrowingRunnable; +import java.util.stream.Stream; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertThrowsExactly; +import static org.junit.jupiter.api.Assertions.assertTrue; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.io.TempDir; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; -public class AppImageFileTest { - @Rule - public final TemporaryFolder tempFolder = new TemporaryFolder(); +public class AppImageFileTest { @Test public void testIdentity() throws IOException { @@ -51,7 +53,7 @@ public void testIdentity() throws IOException { params.put(Arguments.CLIOptions.DESCRIPTION.getId(), "Duck is the King"); AppImageFile aif = create(params); - Assert.assertEquals("Foo", aif.getLauncherName()); + assertEquals("Foo", aif.getLauncherName()); } @Test @@ -73,60 +75,79 @@ public void testInvalidCommandLine() throws IOException { create(params); } - @Test - public void testInavlidXml() throws IOException { - assertInvalid(() -> createFromXml("<foo/>")); - assertInvalid(() -> createFromXml("<jpackage-state/>")); - assertInvalid(() -> createFromXml(JPACKAGE_STATE_OPEN, "</jpackage-state>")); - assertInvalid(() -> createFromXml( - JPACKAGE_STATE_OPEN, - "<main-launcher></main-launcher>", - "</jpackage-state>")); - assertInvalid(() -> createFromXml( - JPACKAGE_STATE_OPEN, - "<main-launcher>Foo</main-launcher>", - "<main-class></main-class>", - "</jpackage-state>")); - assertInvalid(() -> createFromXml( - JPACKAGE_STATE_OPEN, - "<launcher>A</launcher>", - "<launcher>B</launcher>", - "</jpackage-state>")); + @ParameterizedTest + @MethodSource + public void testInavlidXml(String[] xmlData) throws IOException { + Exception ex = assertThrowsExactly(RuntimeException.class, () -> createFromXml(xmlData)); + assertTrue(ex.getMessage().contains("generated by another jpackage version or malformed")); + assertTrue(ex.getMessage().endsWith(".jpackage.xml\"")); } - @Test - public void testValidXml() throws IOException { - Assert.assertEquals("Foo", (createFromXml( - JPACKAGE_STATE_OPEN, - "<app-version>1.0</app-version>", - "<main-launcher>Foo</main-launcher>", - "<main-class>main.Class</main-class>", - "<signed>false</signed>", - "<app-store>false</app-store>", - "</jpackage-state>")).getLauncherName()); - - Assert.assertEquals("Boo", (createFromXml( - JPACKAGE_STATE_OPEN, - "<app-version>1.0</app-version>", - "<main-launcher>Boo</main-launcher>", - "<main-launcher>Bar</main-launcher>", - "<main-class>main.Class</main-class>", - "<signed>false</signed>", - "<app-store>false</app-store>", - "</jpackage-state>")).getLauncherName()); - - var file = createFromXml( - JPACKAGE_STATE_OPEN, - "<app-version>1.0</app-version>", - "<main-launcher>Foo</main-launcher>", - "<main-class>main.Class</main-class>", - "<signed>false</signed>", - "<app-store>false</app-store>", - "<launcher></launcher>", - "</jpackage-state>"); - Assert.assertEquals("Foo", file.getLauncherName()); - - Assert.assertEquals(0, file.getAddLaunchers().size()); + private static Stream<org.junit.jupiter.params.provider.Arguments> testInavlidXml() { + return Stream.of( + makeArguments((Object)new String[] {"<foo/>"}), + makeArguments((Object)new String[] {"<jpackage-state/>"}), + makeArguments((Object)new String[] {JPACKAGE_STATE_OPEN, "</jpackage-state>"}), + makeArguments((Object)new String[] { + JPACKAGE_STATE_OPEN, + "<main-launcher></main-launcher>", + "</jpackage-state>" + }), + makeArguments((Object)new String[] { + JPACKAGE_STATE_OPEN, + "<main-launcher>Foo</main-launcher>", + "<main-class></main-class>", + "</jpackage-state>" + }), + makeArguments((Object)new String[] { + JPACKAGE_STATE_OPEN, + "<launcher>A</launcher>", + "<launcher>B</launcher>", + "</jpackage-state>" + }) + ); + } + + @ParameterizedTest + @MethodSource + public void testValidXml(String expectedLauncherName, String xmlData[]) throws IOException { + var file = createFromXml(xmlData); + assertEquals(expectedLauncherName, file.getLauncherName()); + assertTrue(file.getAddLaunchers().isEmpty()); + } + + private static Stream<org.junit.jupiter.params.provider.Arguments> testValidXml() { + return Stream.of( + makeArguments("Foo", List.of( + JPACKAGE_STATE_OPEN, + "<app-version>1.0</app-version>", + "<main-launcher>Foo</main-launcher>", + "<main-class>main.Class</main-class>", + "<signed>false</signed>", + "<app-store>false</app-store>", + "</jpackage-state>").toArray(String[]::new) + ), + makeArguments("Boo", List.of( + JPACKAGE_STATE_OPEN, + "<app-version>1.0</app-version>", + "<main-launcher>Boo</main-launcher>", + "<main-launcher>Bar</main-launcher>", + "<main-class>main.Class</main-class>", + "<signed>false</signed>", + "<app-store>false</app-store>", + "</jpackage-state>").toArray(String[]::new) + ), + makeArguments("duke", List.of( + JPACKAGE_STATE_OPEN, + "<app-version>1.0</app-version>", + "<main-launcher>duke</main-launcher>", + "<main-class>main.Class</main-class>", + "<signed>false</signed>", + "<app-store>false</app-store>", + "<launcher></launcher>", + "</jpackage-state>").toArray(String[]::new) + ) + ); } @Test @@ -137,7 +158,7 @@ public void testMainLauncherName() throws IOException { params.put("description", "Duck App Description"); AppImageFile aif = create(params); - Assert.assertEquals("Foo", aif.getLauncherName()); + assertEquals("Foo", aif.getLauncherName()); } @Test @@ -148,7 +169,7 @@ public void testMainClass() throws IOException { params.put("description", "Duck App Description"); AppImageFile aif = create(params); - Assert.assertEquals("main.Class", aif.getMainClass()); + assertEquals("main.Class", aif.getMainClass()); } @Test @@ -160,7 +181,7 @@ public void testMacSign() throws IOException { params.put("mac-sign", Boolean.TRUE); AppImageFile aif = create(params); - Assert.assertTrue(aif.isSigned()); + assertTrue(aif.isSigned()); } @Test @@ -172,10 +193,10 @@ public void testCopyAsSigned() throws IOException { params.put("mac-sign", Boolean.FALSE); AppImageFile aif = create(params); - Assert.assertFalse(aif.isSigned()); + assertFalse(aif.isSigned()); aif = aif.copyAsSigned(); - Assert.assertTrue(aif.isSigned()); + assertTrue(aif.isSigned()); } @Test @@ -187,7 +208,7 @@ public void testMacAppStore() throws IOException { params.put("mac-app-store", Boolean.TRUE); AppImageFile aif = create(params); - Assert.assertTrue(aif.isAppStore()); + assertTrue(aif.isAppStore()); } @Test @@ -210,32 +231,22 @@ public void testAddLaunchers() throws IOException { AppImageFile aif = create(params); List<AppImageFile.LauncherInfo> addLaunchers = aif.getAddLaunchers(); - Assert.assertEquals(2, addLaunchers.size()); + assertEquals(2, addLaunchers.size()); List<String> names = new ArrayList<>(); names.add(addLaunchers.get(0).getName()); names.add(addLaunchers.get(1).getName()); - Assert.assertTrue(names.contains("Launcher2Name")); - Assert.assertTrue(names.contains("Launcher3Name")); + assertTrue(names.contains("Launcher2Name")); + assertTrue(names.contains("Launcher3Name")); } private AppImageFile create(Map<String, Object> params) throws IOException { - AppImageFile.save(tempFolder.getRoot().toPath(), params); - return AppImageFile.load(tempFolder.getRoot().toPath()); - } - - private void assertInvalid(ThrowingRunnable action) { - Exception ex = Assert.assertThrows(RuntimeException.class, action); - Assert.assertTrue(ex instanceof RuntimeException); - Assert.assertTrue(ex.getMessage() - .contains("generated by another jpackage version or malformed")); - Assert.assertTrue(ex.getMessage() - .endsWith(".jpackage.xml\"")); + AppImageFile.save(tempFolder, params); + return AppImageFile.load(tempFolder); } private AppImageFile createFromXml(String... xmlData) throws IOException { - Path directory = tempFolder.getRoot().toPath(); - Path path = AppImageFile.getPathInAppImage(directory); + Path path = AppImageFile.getPathInAppImage(tempFolder); path.toFile().mkdirs(); Files.delete(path); @@ -246,11 +257,18 @@ private AppImageFile createFromXml(String... xmlData) throws IOException { Files.write(path, data, StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING); - AppImageFile image = AppImageFile.load(directory); + AppImageFile image = AppImageFile.load(tempFolder); return image; } - private final static String JPACKAGE_STATE_OPEN = String.format( + static org.junit.jupiter.params.provider.Arguments makeArguments(Object ... args) { + return org.junit.jupiter.params.provider.Arguments.of(args); + } + + @TempDir + private Path tempFolder; + + private static final String JPACKAGE_STATE_OPEN = String.format( "<jpackage-state platform=\"%s\" version=\"%s\">", AppImageFile.getPlatform(), AppImageFile.getVersion()); diff --git a/test/jdk/tools/jpackage/junit/jdk.jpackage/jdk/jpackage/internal/ApplicationLayoutTest.java b/test/jdk/tools/jpackage/junit/jdk.jpackage/jdk/jpackage/internal/ApplicationLayoutTest.java index b047a6d64d7..58bf733c855 100644 --- a/test/jdk/tools/jpackage/junit/jdk.jpackage/jdk/jpackage/internal/ApplicationLayoutTest.java +++ b/test/jdk/tools/jpackage/junit/jdk.jpackage/jdk/jpackage/internal/ApplicationLayoutTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,31 +26,44 @@ import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; -import org.junit.Test; -import org.junit.Rule; -import org.junit.rules.TemporaryFolder; -import static org.junit.Assert.assertTrue; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.io.TempDir; +import static org.junit.jupiter.api.Assertions.assertTrue; public class ApplicationLayoutTest { - @Rule - public final TemporaryFolder tempFolder = new TemporaryFolder(); + private Path newFolder(Path folderName, String ... extraFolderNames) throws IOException { + var path = tempFolder.resolve(folderName); + Files.createDirectories(path); + for (var extraFolderName : extraFolderNames) { + path = path.resolve(extraFolderName); + Files.createDirectories(path); + } + return path; + } + + private Path newFile(Path fileName) throws IOException { + var path = tempFolder.resolve(fileName); + Files.createDirectories(path.getParent()); + Files.createFile(path); + return path; + } private void fillLinuxAppImage() throws IOException { - appImage = tempFolder.newFolder("Foo").toPath(); + appImage = newFolder(Path.of("Foo")); Path base = appImage.getFileName(); - tempFolder.newFolder(base.toString(), "bin"); - tempFolder.newFolder(base.toString(), "lib", "app", "mods"); - tempFolder.newFolder(base.toString(), "lib", "runtime", "bin"); - tempFolder.newFile(base.resolve("bin/Foo").toString()); - tempFolder.newFile(base.resolve("lib/app/Foo.cfg").toString()); - tempFolder.newFile(base.resolve("lib/app/hello.jar").toString()); - tempFolder.newFile(base.resolve("lib/Foo.png").toString()); - tempFolder.newFile(base.resolve("lib/libapplauncher.so").toString()); - tempFolder.newFile(base.resolve("lib/runtime/bin/java").toString()); + newFolder(base, "bin"); + newFolder(base, "lib", "app", "mods"); + newFolder(base, "lib", "runtime", "bin"); + newFile(base.resolve("bin/Foo")); + newFile(base.resolve("lib/app/Foo.cfg")); + newFile(base.resolve("lib/app/hello.jar")); + newFile(base.resolve("lib/Foo.png")); + newFile(base.resolve("lib/libapplauncher.so")); + newFile(base.resolve("lib/runtime/bin/java")); } @Test @@ -84,5 +97,7 @@ private void assertApplicationLayout(ApplicationLayout layout) throws IOExceptio assertTrue(Files.isRegularFile(layout.runtimeDirectory().resolve("bin/java"))); } + @TempDir + private Path tempFolder; private Path appImage; } diff --git a/test/jdk/tools/jpackage/junit/jdk.jpackage/jdk/jpackage/internal/CompareDottedVersionTest.java b/test/jdk/tools/jpackage/junit/jdk.jpackage/jdk/jpackage/internal/CompareDottedVersionTest.java deleted file mode 100644 index d77b4e85eb7..00000000000 --- a/test/jdk/tools/jpackage/junit/jdk.jpackage/jdk/jpackage/internal/CompareDottedVersionTest.java +++ /dev/null @@ -1,111 +0,0 @@ -/* - * Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package jdk.jpackage.internal; - -import java.util.ArrayList; -import java.util.List; -import java.util.function.Function; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.Parameterized; -import org.junit.runners.Parameterized.Parameters; -import static org.junit.Assert.assertEquals; - -@RunWith(Parameterized.class) -public class CompareDottedVersionTest { - - public CompareDottedVersionTest(boolean greedy, String version1, - String version2, int result) { - this.version1 = version1; - this.version2 = version2; - this.expectedResult = result; - - if (greedy) { - createTestee = DottedVersion::greedy; - } else { - createTestee = DottedVersion::lazy; - } - } - - @Parameters - public static List<Object[]> data() { - List<Object[]> data = new ArrayList<>(); - for (var greedy : List.of(true, false)) { - data.addAll(List.of(new Object[][] { - { greedy, "00.0.0", "0", 0 }, - { greedy, "00.0.0", "0.000", 0 }, - { greedy, "0.035", "0.0035", 0 }, - { greedy, "0.035", "0.0035.0", 0 }, - { greedy, "1", "1", 0 }, - { greedy, "2", "2.0", 0 }, - { greedy, "2.00", "2.0", 0 }, - { greedy, "1.2.3.4", "1.2.3.4.5", -1 }, - { greedy, "1.2.3.4", "1.2.3.4.0.1", -1 }, - { greedy, "34", "33", 1 }, - { greedy, "34.0.78", "34.1.78", -1 } - })); - } - - data.addAll(List.of(new Object[][] { - { false, "", "1", -1 }, - { false, "", "0", 0 }, - { false, "0", "", 0 }, - { false, "1.2.4-R4", "1.2.4-R5", 0 }, - { false, "1.2.4.-R4", "1.2.4.R5", 0 }, - { false, "7+1", "7+4", 0 }, - { false, "2+14", "2-14", 0 }, - { false, "23.4.RC4", "23.3.RC10", 1 }, - { false, "77." + "9".repeat(1000), "77." + "9".repeat(1000 -1) + "8", 1 }, - })); - - return data; - } - - @Test - public void testIt() { - int actualResult = compare(version1, version2); - assertEquals(expectedResult, actualResult); - - int actualNegateResult = compare(version2, version1); - assertEquals(actualResult, -1 * actualNegateResult); - } - - private int compare(String x, String y) { - int result = DottedVersion.compareComponents(createTestee.apply(x), createTestee.apply(y)); - - if (result < 0) { - return -1; - } - - if (result > 0) { - return 1; - } - - return 0; - } - - private final String version1; - private final String version2; - private final int expectedResult; - private final Function<String, DottedVersion> createTestee; -} diff --git a/test/jdk/tools/jpackage/junit/jdk.jpackage/jdk/jpackage/internal/DeployParamsTest.java b/test/jdk/tools/jpackage/junit/jdk.jpackage/jdk/jpackage/internal/DeployParamsTest.java index 18ca8836790..e4db8f5c0a5 100644 --- a/test/jdk/tools/jpackage/junit/jdk.jpackage/jdk/jpackage/internal/DeployParamsTest.java +++ b/test/jdk/tools/jpackage/junit/jdk.jpackage/jdk/jpackage/internal/DeployParamsTest.java @@ -22,20 +22,14 @@ */ package jdk.jpackage.internal; -import org.hamcrest.BaseMatcher; -import org.hamcrest.Description; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; -import org.junit.rules.TemporaryFolder; +import static org.junit.jupiter.api.Assertions.assertThrowsExactly; +import static org.junit.jupiter.api.Assertions.assertTrue; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; -public class DeployParamsTest { - - @Rule - public final TemporaryFolder tempFolder = new TemporaryFolder(); - @Rule - public final ExpectedException thrown = ExpectedException.none(); +public class DeployParamsTest { @Test public void testValidAppName() throws PackagerException { @@ -48,58 +42,13 @@ public void testValidAppName() throws PackagerException { setAppNameAndValidate("Test - Name !!!"); } - @Test - public void testInvalidAppName() throws PackagerException { - initForInvalidAppNamePackagerException(); + @ParameterizedTest + @ValueSource(strings = {"Test\nName", "Test\rName", "TestName\\", "Test \" Name"}) + public void testInvalidAppName(String appName) throws PackagerException { initParamsAppName(); - setAppNameAndValidate("Test\nName"); - } - - @Test - public void testInvalidAppName2() throws PackagerException { - initForInvalidAppNamePackagerException(); - initParamsAppName(); - setAppNameAndValidate("Test\rName"); - } - - @Test - public void testInvalidAppName3() throws PackagerException { - initForInvalidAppNamePackagerException(); - initParamsAppName(); - setAppNameAndValidate("TestName\\"); - } - - @Test - public void testInvalidAppName4() throws PackagerException { - initForInvalidAppNamePackagerException(); - initParamsAppName(); - setAppNameAndValidate("Test \" Name"); - } - - private void initForInvalidAppNamePackagerException() { - thrown.expect(PackagerException.class); - - String msg = "Error: Invalid Application name"; - - // Unfortunately org.hamcrest.core.StringStartsWith is not available - // with older junit, DIY - - // thrown.expectMessage(startsWith("Error: Invalid Application name")); - thrown.expectMessage(new BaseMatcher() { - @Override - @SuppressWarnings("unchecked") - public boolean matches(Object o) { - if (o instanceof String) { - return ((String) o).startsWith(msg); - } - return false; - } + var ex = assertThrowsExactly(PackagerException.class, () -> setAppNameAndValidate(appName)); - @Override - public void describeTo(Description d) { - d.appendText(msg); - } - }); + assertTrue(ex.getMessage().startsWith("Error: Invalid Application name")); } // Returns deploy params initialized to pass all validation, except for diff --git a/test/jdk/tools/jpackage/junit/jdk.jpackage/jdk/jpackage/internal/DottedVersionTest.java b/test/jdk/tools/jpackage/junit/jdk.jpackage/jdk/jpackage/internal/DottedVersionTest.java index 0443fdf64e7..c9c2b018556 100644 --- a/test/jdk/tools/jpackage/junit/jdk.jpackage/jdk/jpackage/internal/DottedVersionTest.java +++ b/test/jdk/tools/jpackage/junit/jdk.jpackage/jdk/jpackage/internal/DottedVersionTest.java @@ -22,174 +22,224 @@ */ package jdk.jpackage.internal; -import java.util.Collections; +import java.util.ArrayList; import java.util.List; import java.util.function.Function; import java.util.stream.Stream; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; -import org.junit.runner.RunWith; -import org.junit.runners.Parameterized; - -@RunWith(Parameterized.class) -public class DottedVersionTest { - - public DottedVersionTest(boolean greedy) { - this.greedy = greedy; - if (greedy) { - createTestee = DottedVersion::greedy; - } else { - createTestee = DottedVersion::lazy; - } - } - - @Parameterized.Parameters - public static List<Object[]> data() { - return List.of(new Object[] { true }, new Object[] { false }); - } +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertThrowsExactly; +import static org.junit.jupiter.api.Assertions.assertTrue; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.EnumSource; +import org.junit.jupiter.params.provider.MethodSource; - @Rule - public ExpectedException exceptionRule = ExpectedException.none(); +public class DottedVersionTest { - private static class CtorTester { + public record TestConfig(String input, + Function<String, DottedVersion> createVersion, String expectedSuffix, + int expectedComponentCount, String expectedToComponent) { - CtorTester(String input, boolean greedy, String expectedSuffix, - int expectedComponentCount, String expectedToComponent) { - this.input = input; - this.greedy = greedy; - this.expectedSuffix = expectedSuffix; - this.expectedComponentCount = expectedComponentCount; - this.expectedToComponent = expectedToComponent; + TestConfig(String input, Type type, int expectedComponentCount, String expectedToComponent) { + this(input, type.createVersion, "", expectedComponentCount, expectedToComponent); } - CtorTester(String input, boolean greedy, int expectedComponentCount, - String expectedToComponent) { - this(input, greedy, "", expectedComponentCount, expectedToComponent); + TestConfig(String input, Type type, int expectedComponentCount) { + this(input, type.createVersion, "", expectedComponentCount, input); } - CtorTester(String input, boolean greedy, int expectedComponentCount) { - this(input, greedy, "", expectedComponentCount, input); + static TestConfig greedy(String input, int expectedComponentCount, String expectedToComponent) { + return new TestConfig(input, Type.GREEDY.createVersion, "", expectedComponentCount, expectedToComponent); } - static CtorTester greedy(String input, int expectedComponentCount, - String expectedToComponent) { - return new CtorTester(input, true, "", expectedComponentCount, expectedToComponent); + static TestConfig greedy(String input, int expectedComponentCount) { + return new TestConfig(input, Type.GREEDY.createVersion, "", expectedComponentCount, input); } - static CtorTester greedy(String input, int expectedComponentCount) { - return new CtorTester(input, true, "", expectedComponentCount, input); + static TestConfig lazy(String input, String expectedSuffix, int expectedComponentCount, String expectedToComponent) { + return new TestConfig(input, Type.LAZY.createVersion, expectedSuffix, expectedComponentCount, expectedToComponent); } + } - static CtorTester lazy(String input, String expectedSuffix, int expectedComponentCount, - String expectedToComponent) { - return new CtorTester(input, false, expectedSuffix, expectedComponentCount, - expectedToComponent); - } + @ParameterizedTest + @MethodSource + public void testValid(TestConfig cfg) { + var dv = cfg.createVersion.apply(cfg.input()); + assertEquals(cfg.expectedSuffix(), dv.getUnprocessedSuffix()); + assertEquals(cfg.expectedComponentCount(), dv.getComponents().length); + assertEquals(cfg.expectedToComponent(), dv.toComponentsString()); + } - void run() { - DottedVersion dv; - if (greedy) { - dv = DottedVersion.greedy(input); - } else { - dv = DottedVersion.lazy(input); - } - - assertEquals(expectedSuffix, dv.getUnprocessedSuffix()); - assertEquals(expectedComponentCount, dv.getComponents().length); - assertEquals(expectedToComponent, dv.toComponentsString()); + private static List<TestConfig> testValid() { + List<TestConfig> data = new ArrayList<>(); + for (var type : Type.values()) { + data.addAll(List.of( + new TestConfig("1.0", type, 2), + new TestConfig("1", type, 1), + new TestConfig("2.20034.045", type, 3, "2.20034.45"), + new TestConfig("2.234.0", type, 3), + new TestConfig("0", type, 1), + new TestConfig("0.1", type, 2), + new TestConfig("9".repeat(1000), type, 1), + new TestConfig("00.0.0", type, 3, "0.0.0") + )); } - private final String input; - private final boolean greedy; - private final String expectedSuffix; - private final int expectedComponentCount; - private final String expectedToComponent; + data.addAll(List.of( + TestConfig.lazy("1.-1", ".-1", 1, "1"), + TestConfig.lazy("5.", ".", 1, "5"), + TestConfig.lazy("4.2.", ".", 2, "4.2"), + TestConfig.lazy("3..2", "..2", 1, "3"), + TestConfig.lazy("3......2", "......2", 1, "3"), + TestConfig.lazy("2.a", ".a", 1, "2"), + TestConfig.lazy("a", "a", 0, ""), + TestConfig.lazy("2..a", "..a", 1, "2"), + TestConfig.lazy("0a", "a", 1, "0"), + TestConfig.lazy("120a", "a", 1, "120"), + TestConfig.lazy("120abc", "abc", 1, "120"), + TestConfig.lazy(".", ".", 0, ""), + TestConfig.lazy("....", "....", 0, ""), + TestConfig.lazy(" ", " ", 0, ""), + TestConfig.lazy(" 1", " 1", 0, ""), + TestConfig.lazy("678. 2", ". 2", 1, "678"), + TestConfig.lazy("+1", "+1", 0, ""), + TestConfig.lazy("-1", "-1", 0, ""), + TestConfig.lazy("-0", "-0", 0, ""), + TestConfig.lazy("+0", "+0", 0, "") + )); + + return data; } - @Test - public void testValid() { - final List<CtorTester> validStrings = List.of( - new CtorTester("1.0", greedy, 2), - new CtorTester("1", greedy, 1), - new CtorTester("2.20034.045", greedy, 3, "2.20034.45"), - new CtorTester("2.234.0", greedy, 3), - new CtorTester("0", greedy, 1), - new CtorTester("0.1", greedy, 2), - new CtorTester("9".repeat(1000), greedy, 1), - new CtorTester("00.0.0", greedy, 3, "0.0.0") - ); + @ParameterizedTest + @MethodSource + public void testInvalid(String str) { + assertThrowsExactly(IllegalArgumentException.class, () -> new DottedVersion(str)); + } - final List<CtorTester> validLazyStrings; - if (greedy) { - validLazyStrings = Collections.emptyList(); - } else { - validLazyStrings = List.of( - CtorTester.lazy("1.-1", ".-1", 1, "1"), - CtorTester.lazy("5.", ".", 1, "5"), - CtorTester.lazy("4.2.", ".", 2, "4.2"), - CtorTester.lazy("3..2", "..2", 1, "3"), - CtorTester.lazy("3......2", "......2", 1, "3"), - CtorTester.lazy("2.a", ".a", 1, "2"), - CtorTester.lazy("a", "a", 0, ""), - CtorTester.lazy("2..a", "..a", 1, "2"), - CtorTester.lazy("0a", "a", 1, "0"), - CtorTester.lazy("120a", "a", 1, "120"), - CtorTester.lazy("120abc", "abc", 1, "120"), - CtorTester.lazy(".", ".", 0, ""), - CtorTester.lazy("....", "....", 0, ""), - CtorTester.lazy(" ", " ", 0, ""), - CtorTester.lazy(" 1", " 1", 0, ""), - CtorTester.lazy("678. 2", ". 2", 1, "678"), - CtorTester.lazy("+1", "+1", 0, ""), - CtorTester.lazy("-1", "-1", 0, ""), - CtorTester.lazy("-0", "-0", 0, ""), - CtorTester.lazy("+0", "+0", 0, "") - ); - } + private static Stream<String> testInvalid() { + return Stream.of( + "1.-1", + "5.", + "4.2.", + "3..2", + "2.a", + "0a", + ".", + " ", + " 1", + "1. 2", + "+1", + "-1", + "-0", + "+0" + ); + } - Stream.concat(validStrings.stream(), validLazyStrings.stream()).forEach(CtorTester::run); + @ParameterizedTest + @EnumSource(Type.class) + public void testNull(Type type) { + assertThrowsExactly(NullPointerException.class, () -> type.createVersion.apply(null)); } @Test - public void testNull() { - exceptionRule.expect(NullPointerException.class); - createTestee.apply(null); + public void testEmptyGreedy() { + assertThrowsExactly(IllegalArgumentException.class, () -> DottedVersion.greedy(""), "Version may not be empty string"); } @Test - public void testEmpty() { - if (greedy) { - exceptionRule.expect(IllegalArgumentException.class); - exceptionRule.expectMessage("Version may not be empty string"); - createTestee.apply(""); - } else { - assertEquals(0, createTestee.apply("").getComponents().length); - } + public void testEmptyLazy() { + assertEquals(0, DottedVersion.lazy("").getComponents().length); } - @Test - public void testEquals() { - DottedVersion dv = createTestee.apply("1.0"); + @ParameterizedTest + @EnumSource(Type.class) + public void testEquals(Type type) { + DottedVersion dv = type.createVersion.apply("1.0"); assertFalse(dv.equals(null)); - assertFalse(dv.equals(Integer.valueOf(1))); + assertFalse(dv.equals(1)); + assertFalse(dv.equals(dv.toString())); for (var ver : List.of("3", "3.4", "3.0.0")) { - DottedVersion a = createTestee.apply(ver); - DottedVersion b = createTestee.apply(ver); + DottedVersion a = type.createVersion.apply(ver); + DottedVersion b = type.createVersion.apply(ver); assertTrue(a.equals(b)); assertTrue(b.equals(a)); } + } - if (!greedy) { - assertTrue(createTestee.apply("3.6+67").equals(createTestee.apply("3.6+67"))); - assertFalse(createTestee.apply("3.6+67").equals(createTestee.apply("3.6+067"))); + @Test + public void testEqualsLazy() { + assertTrue(DottedVersion.lazy("3.6+67").equals(DottedVersion.lazy("3.6+67"))); + assertFalse(DottedVersion.lazy("3.6+67").equals(DottedVersion.lazy("3.6+067"))); + } + + private static List<Object[]> testCompare() { + List<Object[]> data = new ArrayList<>(); + for (var type : Type.values()) { + data.addAll(List.of(new Object[][] { + { type, "00.0.0", "0", 0 }, + { type, "00.0.0", "0.000", 0 }, + { type, "0.035", "0.0035", 0 }, + { type, "0.035", "0.0035.0", 0 }, + { type, "1", "1", 0 }, + { type, "2", "2.0", 0 }, + { type, "2.00", "2.0", 0 }, + { type, "1.2.3.4", "1.2.3.4.5", -1 }, + { type, "1.2.3.4", "1.2.3.4.0.1", -1 }, + { type, "34", "33", 1 }, + { type, "34.0.78", "34.1.78", -1 } + })); + } + + data.addAll(List.of(new Object[][] { + { Type.LAZY, "", "1", -1 }, + { Type.LAZY, "", "0", 0 }, + { Type.LAZY, "0", "", 0 }, + { Type.LAZY, "1.2.4-R4", "1.2.4-R5", 0 }, + { Type.LAZY, "1.2.4.-R4", "1.2.4.R5", 0 }, + { Type.LAZY, "7+1", "7+4", 0 }, + { Type.LAZY, "2+14", "2-14", 0 }, + { Type.LAZY, "23.4.RC4", "23.3.RC10", 1 }, + { Type.LAZY, "77." + "9".repeat(1000), "77." + "9".repeat(1000 -1) + "8", 1 }, + })); + + return data; + } + + @ParameterizedTest + @MethodSource + public void testCompare(Type type, String version1, String version2, int expectedResult) { + final int actualResult = compare(type, version1, version2); + assertEquals(expectedResult, actualResult); + + final int actualNegateResult = compare(type, version2, version1); + assertEquals(actualResult, -1 * actualNegateResult); + } + + private int compare(Type type, String x, String y) { + int result = DottedVersion.compareComponents(type.createVersion.apply(x), type.createVersion.apply(y)); + + if (result < 0) { + return -1; } + + if (result > 0) { + return 1; + } + + return 0; } - private final boolean greedy; - private final Function<String, DottedVersion> createTestee; + public enum Type { + GREEDY(DottedVersion::greedy), + LAZY(DottedVersion::lazy); + + Type(Function<String, DottedVersion> createVersion) { + this.createVersion = createVersion; + } + + private final Function<String, DottedVersion> createVersion; + } } diff --git a/test/jdk/tools/jpackage/junit/jdk.jpackage/jdk/jpackage/internal/EnquoterTest.java b/test/jdk/tools/jpackage/junit/jdk.jpackage/jdk/jpackage/internal/EnquoterTest.java index 7d58dd483c8..95b0e54a0cd 100644 --- a/test/jdk/tools/jpackage/junit/jdk.jpackage/jdk/jpackage/internal/EnquoterTest.java +++ b/test/jdk/tools/jpackage/junit/jdk.jpackage/jdk/jpackage/internal/EnquoterTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,30 +23,49 @@ package jdk.jpackage.internal; -import static org.junit.Assert.assertEquals; -import org.junit.Test; +import java.util.stream.Stream; +import static org.junit.jupiter.api.Assertions.assertEquals; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; + public class EnquoterTest { - @Test - public void testForShellLiterals() { - var enquoter = Enquoter.forShellLiterals(); + @ParameterizedTest + @MethodSource + public void testForShellLiterals(String expected, String input) { + var actual = Enquoter.forShellLiterals().applyTo(input); + assertEquals(expected, actual); + } - assertEquals(null, "''", enquoter.applyTo("")); - assertEquals(null, "'foo'", enquoter.applyTo("foo")); - assertEquals(null, "' foo '", enquoter.applyTo(" foo ")); - assertEquals(null, "'foo bar'", enquoter.applyTo("foo bar")); - assertEquals(null, "'foo\\' bar'", enquoter.applyTo("foo' bar")); + @ParameterizedTest + @MethodSource + public void testForPropertyValues(String expected, String input) { + var actual = Enquoter.forPropertyValues().applyTo(input); + assertEquals(expected, actual); } - @Test - public void testForPropertyValues() { - var enquoter = Enquoter.forPropertyValues(); + private static Stream<org.junit.jupiter.params.provider.Arguments> testForShellLiterals() { + return Stream.of( + makeArguments("''", ""), + makeArguments("'foo'", "foo"), + makeArguments("' foo '", " foo "), + makeArguments("'foo bar'", "foo bar"), + makeArguments("'foo\\' bar'", "foo' bar") + ); + } + + private static Stream<org.junit.jupiter.params.provider.Arguments> testForPropertyValues() { + return Stream.of( + makeArguments("", ""), + makeArguments("foo", "foo"), + makeArguments("\" foo \"", " foo "), + makeArguments("\"foo bar\"", "foo bar"), + makeArguments("\"foo' bar\"", "foo' bar") + ); + } - assertEquals(null, "", enquoter.applyTo("")); - assertEquals(null, "foo", enquoter.applyTo("foo")); - assertEquals(null, "\" foo \"", enquoter.applyTo(" foo ")); - assertEquals(null, "\"foo bar\"", enquoter.applyTo("foo bar")); - assertEquals(null, "\"foo' bar\"", enquoter.applyTo("foo' bar")); + static org.junit.jupiter.params.provider.Arguments makeArguments(Object ... args) { + return org.junit.jupiter.params.provider.Arguments.of(args); } } diff --git a/test/jdk/tools/jpackage/junit/jdk.jpackage/jdk/jpackage/internal/InvalidDottedVersionTest.java b/test/jdk/tools/jpackage/junit/jdk.jpackage/jdk/jpackage/internal/InvalidDottedVersionTest.java deleted file mode 100644 index b0b866e41fb..00000000000 --- a/test/jdk/tools/jpackage/junit/jdk.jpackage/jdk/jpackage/internal/InvalidDottedVersionTest.java +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright (c) 2019, 2023, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package jdk.jpackage.internal; - -import java.util.List; -import java.util.stream.Collectors; -import java.util.stream.Stream; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; -import org.junit.runner.RunWith; -import org.junit.runners.Parameterized; -import org.junit.runners.Parameterized.Parameters; - -@RunWith(Parameterized.class) -public class InvalidDottedVersionTest { - - public InvalidDottedVersionTest(String version) { - this.version = version; - } - - @Parameters - public static List<Object[]> data() { - return Stream.of( - "1.-1", - "5.", - "4.2.", - "3..2", - "2.a", - "0a", - ".", - " ", - " 1", - "1. 2", - "+1", - "-1", - "-0", - "+0" - ).map(version -> new Object[] { version }).collect(Collectors.toList()); - } - - @Rule - public ExpectedException exceptionRule = ExpectedException.none(); - - @Test - public void testIt() { - exceptionRule.expect(IllegalArgumentException.class); - new DottedVersion(version); - } - - private final String version; -} diff --git a/test/jdk/tools/jpackage/junit/jdk.jpackage/jdk/jpackage/internal/OverridableResourceTest.java b/test/jdk/tools/jpackage/junit/jdk.jpackage/jdk/jpackage/internal/OverridableResourceTest.java index 02bb56c7d7f..a45d6e8c5a3 100644 --- a/test/jdk/tools/jpackage/junit/jdk.jpackage/jdk/jpackage/internal/OverridableResourceTest.java +++ b/test/jdk/tools/jpackage/junit/jdk.jpackage/jdk/jpackage/internal/OverridableResourceTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,60 +23,106 @@ package jdk.jpackage.internal; +import java.io.BufferedReader; import java.io.IOException; -import java.io.InputStream; +import java.io.InputStreamReader; import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Path; +import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; +import java.util.Objects; +import java.util.stream.Stream; import jdk.internal.util.OperatingSystem; +import static jdk.jpackage.internal.OverridableResource.Source.DefaultResource; +import static jdk.jpackage.internal.OverridableResource.Source.ResourceDir; import jdk.jpackage.internal.resources.ResourceLocator; -import static org.hamcrest.CoreMatchers.is; -import static org.hamcrest.CoreMatchers.not; -import static org.junit.Assert.assertArrayEquals; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.assertThat; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.TemporaryFolder; +import static org.junit.jupiter.api.Assertions.assertArrayEquals; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotEquals; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertTrue; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.io.TempDir; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; +import org.junit.jupiter.params.provider.ValueSource; + public class OverridableResourceTest { - @Rule - public final TemporaryFolder tempFolder = new TemporaryFolder(); + private static String[] saveResource(ResourceWriter resourceWriter, Path dstPath) throws IOException { + switch (dstPath.getFileName().toString()) { + case "file" -> { + return resourceWriter.saveToFile(dstPath); + } + case "dir" -> { + return resourceWriter.saveInDir(dstPath); + } + default -> { + throw new IllegalArgumentException(); + } + } + } - @Test - public void testDefault() throws IOException { - byte[] actualBytes = saveToFile(new OverridableResource(DEFAULT_NAME)); + private static String[] saveResource( + OverridableResource resource, Path dstPath, boolean dstFileOverwrite) + throws IOException { + return saveResource(buildResourceWriter(resource).dstFileOverwrite(dstFileOverwrite), dstPath); + } + + private static List<Object[]> data() { + List<Object[]> data = new ArrayList<>(); - try (InputStream is = ResourceLocator.class.getResourceAsStream( - DEFAULT_NAME)) { - assertArrayEquals(is.readAllBytes(), actualBytes); + for (var dstPath : List.of("file", "dir")) { + for (var dstFileOverwrite : List.of(true, false)) { + data.add(new Object[]{Path.of(dstPath), dstFileOverwrite}); + } } - } - @Test - public void testDefaultWithSubstitution() throws IOException { - OverridableResource resource = new OverridableResource(DEFAULT_NAME); + for (var dstPath : List.of("dir/file", "dir/dir")) { + data.add(new Object[]{Path.of(dstPath), false}); + } + + return data; + } - List<String> linesBeforeSubstitution = convertToStringList(saveToFile( - resource)); + @ParameterizedTest + @MethodSource("data") + public void testDefault(Path dstPath, boolean dstFileOverwrite, + @TempDir Path tempFolder) throws IOException { + final String[] content = saveResource( + new OverridableResource(DEFAULT_NAME), tempFolder.resolve( + dstPath), dstFileOverwrite); + + try (var resource = ResourceLocator.class.getResourceAsStream(DEFAULT_NAME); + var isr = new InputStreamReader(resource, StandardCharsets.ISO_8859_1); + var br = new BufferedReader(isr)) { + assertArrayEquals(br.lines().toArray(String[]::new), content); + } + } + @ParameterizedTest + @MethodSource("data") + public void testDefaultWithSubstitution(Path dstPath, boolean dstFileOverwrite, + @TempDir Path tempFolder) throws IOException { if (SUBSTITUTION_DATA.size() != 1) { // Test setup issue throw new IllegalArgumentException( "Substitution map should contain only a single entry"); } + OverridableResource resource = new OverridableResource(DEFAULT_NAME); + + var linesBeforeSubstitution = List.of(saveResource(resource, tempFolder.resolve(dstPath), dstFileOverwrite)); + resource.setSubstitutionData(SUBSTITUTION_DATA); - List<String> linesAfterSubstitution = convertToStringList(saveToFile( - resource)); + var linesAfterSubstitution = List.of(saveResource(resource, tempFolder.resolve(dstPath), dstFileOverwrite)); assertEquals(linesBeforeSubstitution.size(), linesAfterSubstitution.size()); @@ -103,130 +149,239 @@ public void testDefaultWithSubstitution() throws IOException { assertTrue(linesMismatch); } - @Test - public void testCustom() throws IOException { - testCustom(DEFAULT_NAME); - } - - @Test - public void testCustomNoDefault() throws IOException { - testCustom(null); + private static Stream<Object[]> dataWithResourceName() { + return data().stream().flatMap(origArgs -> { + return Stream.of(ResourceName.values()).map(defaultName -> { + Object[] args = new Object[origArgs.length + 1]; + args[0] = defaultName; + System.arraycopy(origArgs, 0, args, 1, origArgs.length); + return args; + }); + }); } - private void testCustom(String defaultName) throws IOException { + @ParameterizedTest + @MethodSource("dataWithResourceName") + public void testResourceDir(ResourceName defaultName, Path dstPath, + boolean dstFileOverwrite, @TempDir Path tempFolder) throws IOException { List<String> expectedResourceData = List.of("A", "B", "C"); - Path customFile = createCustomFile("foo", expectedResourceData); + Path customFile = tempFolder.resolve("hello"); + Files.write(customFile, expectedResourceData); - List<String> actualResourceData = convertToStringList(saveToFile( - new OverridableResource(defaultName) + final var actualResourceData = saveResource(buildResourceWriter( + new OverridableResource(defaultName.value) .setPublicName(customFile.getFileName()) - .setResourceDir(customFile.getParent()))); + .setResourceDir(customFile.getParent()) + ).dstFileOverwrite(dstFileOverwrite).expectedSource(ResourceDir), + tempFolder.resolve(dstPath)); - assertArrayEquals(expectedResourceData.toArray(String[]::new), - actualResourceData.toArray(String[]::new)); + assertArrayEquals(expectedResourceData.toArray(String[]::new), actualResourceData); } - @Test - public void testCustomtWithSubstitution() throws IOException { - testCustomtWithSubstitution(DEFAULT_NAME); - } - - @Test - public void testCustomtWithSubstitutionNoDefault() throws IOException { - testCustomtWithSubstitution(null); - } - - private void testCustomtWithSubstitution(String defaultName) throws IOException { + @ParameterizedTest + @MethodSource("dataWithResourceName") + public void testResourceDirWithSubstitution(ResourceName defaultName, Path dstPath, + boolean dstFileOverwrite, @TempDir Path tempFolder) throws IOException { final List<String> resourceData = List.of("A", "[BB]", "C", "Foo", "Foo", "GoodbyeHello", "_B"); - final Path customFile = createCustomFile("foo", resourceData); - final Map<String, String> substitutionData = new HashMap(Map.of("B", - "Bar", "Foo", "B", "_B", "JJ")); + final Path customFile = tempFolder.resolve("hello"); + Files.write(customFile, resourceData); + + final Map<String, String> substitutionData = new HashMap<>(Map.of( + "B", "Bar", + "Foo", "B", + "_B", "JJ")); substitutionData.put("Hello", null); final List<String> expectedResourceData = List.of("A", "[BarBar]", "C", "Bar", "Bar", "Goodbye", "JJ"); - final List<String> actualResourceData = convertToStringList(saveToFile( - new OverridableResource(defaultName) - .setPublicName(customFile.getFileName()) + final var actualResourceData = saveResource(buildResourceWriter( + new OverridableResource(defaultName.value) .setSubstitutionData(substitutionData) - .setResourceDir(customFile.getParent()))); - assertArrayEquals(expectedResourceData.toArray(String[]::new), - actualResourceData.toArray(String[]::new)); + .setPublicName(customFile.getFileName()) + .setResourceDir(customFile.getParent()) + ).dstFileOverwrite(dstFileOverwrite).expectedSource(ResourceDir), + tempFolder.resolve(dstPath)); + + assertArrayEquals(expectedResourceData.toArray(String[]::new), actualResourceData); + } + + // Test it can derive a file in the resource dir from the name of the output file if the public name is not set + @ParameterizedTest + @ValueSource(booleans = {true, false}) + public void testPublicNameNotSet(boolean namesMatch, @TempDir Path tempFolder) throws IOException { + final List<String> expectedResourceData = List.of("A", "B", "C"); - // Don't call setPublicName() - final Path dstFile = tempFolder.newFolder().toPath().resolve(customFile.getFileName()); - new OverridableResource(defaultName) + final Path customFile = tempFolder.resolve("hello"); + Files.write(customFile, expectedResourceData); + + final Path outputDir = tempFolder.resolve("output"); + + var resourceWriter = buildResourceWriter( + new OverridableResource(null).setResourceDir(customFile.getParent())); + + if (namesMatch) { + final var actualResourceData = resourceWriter + .expectedSource(ResourceDir) + .saveToFile(outputDir.resolve(customFile.getFileName())); + assertArrayEquals(expectedResourceData.toArray(String[]::new), actualResourceData); + } else { + final var actualResourceData = resourceWriter + .expectedSource(null) + .saveToFile(outputDir.resolve("another")); + assertNull(actualResourceData); + } + } + + // Test setSubstitutionData() stores a copy of passed in data + @Test + public void testSubstitutionDataCopied(@TempDir Path tempFolder) throws IOException { + final Path customFile = tempFolder.resolve("hello"); + Files.write(customFile, List.of("Hello")); + + final Map<String, String> substitutionData = new HashMap<>(Map.of("Hello", "Goodbye")); + + var resource = new OverridableResource(null) .setSubstitutionData(substitutionData) - .setResourceDir(customFile.getParent()) - .saveToFile(dstFile); - assertArrayEquals(expectedResourceData.toArray(String[]::new), - convertToStringList(Files.readAllBytes(dstFile)).toArray( - String[]::new)); - - // Verify setSubstitutionData() stores a copy of passed in data - Map<String, String> substitutionData2 = new HashMap(substitutionData); - var resource = new OverridableResource(defaultName) + .setPublicName(customFile.getFileName()) .setResourceDir(customFile.getParent()); - resource.setSubstitutionData(substitutionData2); - substitutionData2.clear(); - Files.delete(dstFile); - resource.saveToFile(dstFile); - assertArrayEquals(expectedResourceData.toArray(String[]::new), - convertToStringList(Files.readAllBytes(dstFile)).toArray( - String[]::new)); + final var resourceWriter = buildResourceWriter(resource).expectedSource(ResourceDir); + + var contents = resourceWriter.saveToFile(tempFolder.resolve("output")); + assertArrayEquals(new String[] { "Goodbye" }, contents); + + substitutionData.put("Hello", "Ciao"); + contents = resourceWriter.saveToFile(tempFolder.resolve("output")); + assertArrayEquals(new String[] { "Goodbye" }, contents); + + resource.setSubstitutionData(substitutionData); + contents = resourceWriter.saveToFile(tempFolder.resolve("output")); + assertArrayEquals(new String[] { "Ciao" }, contents); } @Test - public void testNoDefault() throws IOException { - Path dstFolder = tempFolder.newFolder().toPath(); - Path dstFile = dstFolder.resolve(Path.of("foo", "bar")); + public void testNoDefault(@TempDir Path tempFolder) throws IOException { + var resourceWriter = buildResourceWriter(new OverridableResource(null)).expectedSource(null); + assertEquals(null, resourceWriter.saveInDir(tempFolder)); - new OverridableResource(null).saveToFile(dstFile); + var dstDir = tempFolder.resolve("foo"); + assertEquals(null, resourceWriter.saveInDir(dstDir)); + assertFalse(Files.exists(dstDir)); + } - assertFalse(dstFile.toFile().exists()); + enum ResourceName { + DEFAULT_NAME(OverridableResourceTest.DEFAULT_NAME), + NULL_NAME(null); + + ResourceName(String value) { + this.value = value; + } + + private final String value; } - private final static String DEFAULT_NAME; - private final static Map<String, String> SUBSTITUTION_DATA; + private static final String DEFAULT_NAME; + private static final Map<String, String> SUBSTITUTION_DATA; static { - if (OperatingSystem.isWindows()) { - DEFAULT_NAME = "WinLauncher.template"; - SUBSTITUTION_DATA = Map.of("COMPANY_NAME", "Foo9090345"); - } else if (OperatingSystem.isLinux()) { - DEFAULT_NAME = "template.control"; - SUBSTITUTION_DATA = Map.of("APPLICATION_PACKAGE", "Package1967"); - } else if (OperatingSystem.isMacOS()) { - DEFAULT_NAME = "Info-lite.plist.template"; - SUBSTITUTION_DATA = Map.of("DEPLOY_BUNDLE_IDENTIFIER", "12345"); - } else { - throw new IllegalArgumentException("Unknown platform: " + OperatingSystem.current()); + switch (OperatingSystem.current()) { + case WINDOWS -> { + DEFAULT_NAME = "WinLauncher.template"; + SUBSTITUTION_DATA = Map.of("COMPANY_NAME", "Foo9090345"); + } + + case LINUX -> { + DEFAULT_NAME = "template.control"; + SUBSTITUTION_DATA = Map.of("APPLICATION_PACKAGE", "Package1967"); + } + + case MACOS -> { + DEFAULT_NAME = "Info-lite.plist.template"; + SUBSTITUTION_DATA = Map.of("DEPLOY_BUNDLE_IDENTIFIER", "12345"); + } + + default -> { + throw new IllegalArgumentException("Unsupported platform: " + OperatingSystem.current()); + } } } - private byte[] saveToFile(OverridableResource resource) throws IOException { - Path dstFile = tempFolder.newFile().toPath(); - resource.saveToFile(dstFile); - assertThat(0, is(not(dstFile.toFile().length()))); + static class ResourceWriter { - return Files.readAllBytes(dstFile); - } + ResourceWriter(OverridableResource resource) { + this.resource = Objects.requireNonNull(resource); + } + + ResourceWriter expectedSource(OverridableResource.Source v) { + expectedSource = v; + return this; + } + + ResourceWriter dstFileOverwrite(boolean v) { + dstFileOverwrite = v; + return this; + } + + String[] saveInDir(Path dstDir) throws IOException { + Path dstFile; + if (expectedSource != null) { + if (!Files.exists(dstDir)) { + Files.createDirectories(dstDir); + } + dstFile = Files.createTempFile(dstDir, null, null); + } else if (!Files.exists(dstDir)) { + dstFile = dstDir.resolve("nonexistant"); + } else { + dstFile = Files.createTempFile(dstDir, null, null); + Files.delete(dstFile); + } + return saveToFile(dstFile); + } + + String[] saveToFile(Path dstFile) throws IOException { + saveResource(dstFile); + if (expectedSource == null) { + return null; + } else { + return Files.readAllLines(dstFile).toArray(String[]::new); + } + } + + private void saveResource(Path dstFile) throws IOException { + if (dstFileOverwrite && !Files.exists(dstFile)) { + Files.writeString(dstFile, "abcABC"); + } else if (!dstFileOverwrite && Files.exists(dstFile)) { + Files.delete(dstFile); + } - private Path createCustomFile(String publicName, List<String> data) throws - IOException { - Path resourceFolder = tempFolder.newFolder().toPath(); - Path customFile = resourceFolder.resolve(publicName); + final byte[] dstFileContent; + if (expectedSource == null && Files.exists(dstFile)) { + dstFileContent = Files.readAllBytes(dstFile); + } else { + dstFileContent = null; + } - Files.write(customFile, data); + var actualSource = resource.saveToFile(dstFile); + assertEquals(expectedSource, actualSource); + if (actualSource != null) { + assertNotEquals(0, Files.size(dstFile)); + } else if (dstFileContent == null) { + assertFalse(Files.exists(dstFile)); + } else { + var actualDstFileContent = Files.readAllBytes(dstFile); + assertArrayEquals(dstFileContent, actualDstFileContent); + } + } - return customFile; + final OverridableResource resource; + OverridableResource.Source expectedSource = DefaultResource; + boolean dstFileOverwrite; } - private static List<String> convertToStringList(byte[] data) { - return List.of(new String(data, StandardCharsets.UTF_8).split("\\R")); + private static ResourceWriter buildResourceWriter(OverridableResource resource) { + return new ResourceWriter(resource); } } diff --git a/test/jdk/tools/jpackage/junit/jdk.jpackage/jdk/jpackage/internal/PathGroupTest.java b/test/jdk/tools/jpackage/junit/jdk.jpackage/jdk/jpackage/internal/PathGroupTest.java index c14bdf3cb60..5913f257db5 100644 --- a/test/jdk/tools/jpackage/junit/jdk.jpackage/jdk/jpackage/internal/PathGroupTest.java +++ b/test/jdk/tools/jpackage/junit/jdk.jpackage/jdk/jpackage/internal/PathGroupTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -32,29 +32,24 @@ import java.util.Map; import java.util.function.Consumer; import java.util.function.UnaryOperator; -import java.util.stream.Collectors; import java.util.stream.Stream; -import static org.hamcrest.CoreMatchers.equalTo; -import static org.hamcrest.CoreMatchers.not; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertArrayEquals; -import static org.junit.Assert.assertThat; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.TemporaryFolder; +import static org.junit.jupiter.api.Assertions.assertArrayEquals; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotEquals; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.junit.jupiter.api.Assertions.assertThrowsExactly; +import static org.junit.jupiter.api.Assertions.assertTrue; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.io.TempDir; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.MethodSource; public class PathGroupTest { - @Rule - public final TemporaryFolder tempFolder = new TemporaryFolder(); - - @Test(expected = NullPointerException.class) public void testNullId() { - new PathGroup(Map.of()).getPath(null); + assertThrowsExactly(NullPointerException.class, () -> new PathGroup(Map.of()).getPath(null)); } @Test @@ -82,8 +77,10 @@ public void testRootsSinglePath() { @Test public void testDuplicatedRoots() { - final PathGroup pg = new PathGroup(Map.of("main", PATH_FOO, "another", - PATH_FOO, "root", PATH_EMPTY)); + final PathGroup pg = new PathGroup(Map.of( + "main", PATH_FOO, + "another", PATH_FOO, + "root", PATH_EMPTY)); List<Path> paths = pg.paths(); paths = paths.stream().sorted().toList(); @@ -100,8 +97,10 @@ public void testDuplicatedRoots() { @Test public void testRoots() { - final PathGroup pg = new PathGroup(Map.of(1, Path.of("foo"), 2, Path.of( - "foo", "bar"), 3, Path.of("foo", "bar", "buz"))); + final PathGroup pg = new PathGroup(Map.of( + 1, Path.of("foo"), + 2, Path.of("foo", "bar"), + 3, Path.of("foo", "bar", "buz"))); List<Path> paths = pg.paths(); assertEquals(3, paths.size()); @@ -116,13 +115,15 @@ public void testRoots() { @Test public void testResolveAt() { - final PathGroup pg = new PathGroup(Map.of(0, PATH_FOO, 1, PATH_BAR, 2, - PATH_EMPTY)); + final PathGroup pg = new PathGroup(Map.of( + 0, PATH_FOO, + 1, PATH_BAR, + 2, PATH_EMPTY)); final Path aPath = Path.of("a"); final PathGroup pg2 = pg.resolveAt(aPath); - assertThat(pg, not(equalTo(pg2))); + assertNotEquals(pg, pg2); List<Path> paths = pg.paths(); assertEquals(3, paths.size()); @@ -139,29 +140,31 @@ public void testResolveAt() { assertEquals(aPath, pg2.roots().get(0)); } - @Test - public void testTransform() throws IOException { - for (var transform : TransformType.values()) { - testTransform(false, transform); - } - } + enum TransformType { COPY, MOVE, HANDLER }; - @Test - public void testTransformWithExcludes() throws IOException { - for (var transform : TransformType.values()) { - testTransform(true, transform); - } + private static Stream<Object[]> testTransform() { + return Stream.of(TransformType.values()).flatMap(transform -> { + return Stream.of(true, false).map(withExcludes -> { + return new Object[]{withExcludes,transform}; + }); + }); } - enum TransformType { Copy, Move, Handler }; + @ParameterizedTest + @MethodSource("testTransform") + public void testTransform(boolean withExcludes, TransformType transform, @TempDir Path tempDir) throws IOException { + + final Path srcDir = tempDir.resolve("src"); + Files.createDirectories(srcDir); - private void testTransform(boolean withExcludes, TransformType transform) - throws IOException { - final PathGroup pg = new PathGroup(Map.of(0, PATH_FOO, 1, PATH_BAR, 2, - PATH_EMPTY, 3, PATH_BAZ)); + final Path dstDir = tempDir.resolve("dst"); + Files.createDirectories(dstDir); - final Path srcDir = tempFolder.newFolder().toPath(); - final Path dstDir = tempFolder.newFolder().toPath(); + final PathGroup pg = new PathGroup(Map.of( + 0, PATH_FOO, + 1, PATH_BAR, + 2, PATH_EMPTY, + 3, PATH_BAZ)); Files.createDirectories(srcDir.resolve(PATH_FOO).resolve("a/b/c/d")); Files.createFile(srcDir.resolve(PATH_FOO).resolve("a/b/c/file1")); @@ -181,7 +184,7 @@ private void testTransform(boolean withExcludes, TransformType transform) var srcFilesBeforeTransform = walkFiles(srcDir); - if (transform == TransformType.Handler) { + if (transform == TransformType.HANDLER) { List<Map.Entry<Path, Path>> copyFile = new ArrayList<>(); List<Path> createDirectory = new ArrayList<>(); src.transform(dst, new PathGroup.TransformHandler() { @@ -231,9 +234,9 @@ public void createDirectory(Path dir) throws IOException { return; } - if (transform == TransformType.Copy) { + if (transform == TransformType.COPY) { src.copy(dst); - } else if (transform == TransformType.Move) { + } else if (transform == TransformType.MOVE) { src.move(dst); } @@ -248,30 +251,28 @@ public void createDirectory(Path dir) throws IOException { } UnaryOperator<Path[]> removeExcludes = paths -> { return Stream.of(paths) - .filter(path -> !excludedPaths.stream().anyMatch( - path::startsWith)) - .collect(Collectors.toList()).toArray(Path[]::new); + .filter(path -> !excludedPaths.stream().anyMatch(path::startsWith)) + .toArray(Path[]::new); }; var dstFiles = walkFiles(dstDir); assertArrayEquals(removeExcludes.apply(srcFilesBeforeTransform), dstFiles); - if (transform == TransformType.Copy) { + if (transform == TransformType.COPY) { assertArrayEquals(dstFiles, removeExcludes.apply(walkFiles(srcDir))); - } else if (transform == TransformType.Move) { + } else if (transform == TransformType.MOVE) { assertFalse(Files.exists(srcDir)); } } private static Path[] walkFiles(Path root) throws IOException { try (var files = Files.walk(root)) { - return files.map(root::relativize).sorted().collect( - Collectors.toList()).toArray(Path[]::new); + return files.map(root::relativize).sorted().toArray(Path[]::new); } } - private final static Path PATH_FOO = Path.of("foo"); - private final static Path PATH_BAR = Path.of("bar"); - private final static Path PATH_BAZ = Path.of("baz"); - private final static Path PATH_EMPTY = Path.of(""); + private static final Path PATH_FOO = Path.of("foo"); + private static final Path PATH_BAR = Path.of("bar"); + private static final Path PATH_BAZ = Path.of("baz"); + private static final Path PATH_EMPTY = Path.of(""); } diff --git a/test/jdk/tools/jpackage/junit/jdk.jpackage/jdk/jpackage/internal/PlatformVersionTest.java b/test/jdk/tools/jpackage/junit/jdk.jpackage/jdk/jpackage/internal/PlatformVersionTest.java index b17a98a1783..21aea35220b 100644 --- a/test/jdk/tools/jpackage/junit/jdk.jpackage/jdk/jpackage/internal/PlatformVersionTest.java +++ b/test/jdk/tools/jpackage/junit/jdk.jpackage/jdk/jpackage/internal/PlatformVersionTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,95 +23,76 @@ package jdk.jpackage.internal; import java.lang.reflect.InvocationTargetException; -import java.util.ArrayList; -import java.util.List; import java.util.function.Function; -import java.util.stream.Collectors; -import java.util.stream.Stream; import java.lang.reflect.Method; -import static org.junit.Assert.assertEquals; -import org.junit.Rule; -import org.junit.Test; -import org.junit.rules.ExpectedException; -import org.junit.runner.RunWith; -import org.junit.runners.Parameterized; -import org.junit.runners.Parameterized.Parameters; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrowsExactly; +import static org.junit.jupiter.api.Assumptions.assumeTrue; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; -@RunWith(Parameterized.class) public class PlatformVersionTest { - public PlatformVersionTest(Function<String, DottedVersion> parser, - String version, boolean valid) { - this.parser = parser; - this.version = version; - this.valid = valid; + @ParameterizedTest + @ValueSource(strings = { + "0.0", + "255.255", + "0.0.0", + "255.255.65535", + "0.0.0.0", + "255.255.65535.999999" + }) + public void testValidMsiProductVersion(String version) { + testImpl(PlatformVersion.WIN_MSI_PRODUCT_VERSION_CLASS, version, true); } - @Parameters - public static List<Object[]> data() { - List<Object[]> data = new ArrayList<>(); - addTo(data, WIN_MSI_PRODUCT_VERSION_PARSER, true, - "0.0", - "255.255", - "0.0.0", - "255.255.65535", - "0.0.0.0", - "255.255.65535.999999" - ); - - addTo(data, WIN_MSI_PRODUCT_VERSION_PARSER, false, - "0", - "256.01", - "255.256", - "255.255.65536", - "1.2.3.4.5" - ); - - addTo(data, MAC_CFBUNDLE_VERSION_PARSER, true, - "1", - "1.2", - "1.2.3" - ); - - addTo(data, MAC_CFBUNDLE_VERSION_PARSER, false, - "0", - "0.1", - "1.2.3.4" - ); - - return data; + @ParameterizedTest + @ValueSource(strings = { + "0", + "256.01", + "255.256", + "255.255.65536", + "1.2.3.4.5" + }) + public void testInvalidMsiProductVersion(String version) { + testImpl(PlatformVersion.WIN_MSI_PRODUCT_VERSION_CLASS, version, false); } - private static void addTo(List<Object[]> data, - Function<String, DottedVersion> parser, boolean valid, - String... values) { - if (parser != null) { - data.addAll(Stream.of(values).map(version -> new Object[]{parser, - version, valid}).collect(Collectors.toList())); - } + @ParameterizedTest + @ValueSource(strings = {"1", "1.2", "1.2.3"}) + public void testValidCfBundleVersion(String version) { + testImpl(PlatformVersion.MAC_CFBUNDLE_VERSION_CLASS, version, true); } - @Rule - public ExpectedException exceptionRule = ExpectedException.none(); + @ParameterizedTest + @ValueSource(strings = {"0", "0.1", "1.2.3.4"}) + public void testInvalidCfBundleVersion(String version) { + testImpl(PlatformVersion.MAC_CFBUNDLE_VERSION_CLASS, version, false); + } - @Test - public void testIt() { + private static void testImpl(PlatformVersion parser, String version, boolean valid) { + assumeTrue(parser.parser != null); if (valid) { - assertEquals(parser.apply(version).toString(), version); + assertEquals(parser.parse(version).toString(), version); } else { - exceptionRule.expect(IllegalArgumentException.class); - parser.apply(version); + assertThrowsExactly(IllegalArgumentException.class, () -> parser.parse(version)); } } - private final Function<String, DottedVersion> parser; - private final String version; - private final boolean valid; + enum PlatformVersion { + MAC_CFBUNDLE_VERSION_CLASS("jdk.jpackage.internal.CFBundleVersion"), + WIN_MSI_PRODUCT_VERSION_CLASS("jdk.jpackage.internal.MsiVersion"); - private final static Function<String, DottedVersion> MAC_CFBUNDLE_VERSION_PARSER = findParser( - "jdk.jpackage.internal.CFBundleVersion"); - private final static Function<String, DottedVersion> WIN_MSI_PRODUCT_VERSION_PARSER = findParser( - "jdk.jpackage.internal.MsiVersion"); + PlatformVersion(String className) { + parser = findParser(className); + } + + DottedVersion parse(String versionString) { + return parser.apply(versionString); + } + + private Function<String, DottedVersion> parser; + } private static Function<String, DottedVersion> findParser(String className) { try { @@ -124,8 +105,8 @@ private static Function<String, DottedVersion> findParser(String className) { throw new RuntimeException(ex); } catch (InvocationTargetException ex) { Throwable causeEx = ex.getCause(); - if (causeEx instanceof RuntimeException) { - throw (RuntimeException)causeEx; + if (causeEx instanceof RuntimeException rtEx) { + throw rtEx; } throw new RuntimeException(causeEx); } @@ -136,4 +117,5 @@ private static Function<String, DottedVersion> findParser(String className) { throw new IllegalArgumentException(ex); } } + } diff --git a/test/jdk/tools/jpackage/junit/jdk.jpackage/jdk/jpackage/internal/ToolValidatorTest.java b/test/jdk/tools/jpackage/junit/jdk.jpackage/jdk/jpackage/internal/ToolValidatorTest.java index eaddbb9eaa9..9731deafe02 100644 --- a/test/jdk/tools/jpackage/junit/jdk.jpackage/jdk/jpackage/internal/ToolValidatorTest.java +++ b/test/jdk/tools/jpackage/junit/jdk.jpackage/jdk/jpackage/internal/ToolValidatorTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,12 +25,10 @@ import java.nio.file.Path; import jdk.internal.util.OperatingSystem; -import static org.hamcrest.CoreMatchers.is; -import static org.hamcrest.CoreMatchers.not; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertThat; -import org.junit.Test; +import static org.junit.jupiter.api.Assertions.assertNotEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; +import org.junit.jupiter.api.Test; public class ToolValidatorTest { @@ -70,11 +68,10 @@ public void testVersionParserUsage() { new DottedVersion("8")).setVersionParser(unused -> "10").validate()); } - private static void assertValidationFailure(ConfigException v, - boolean withCause) { + private static void assertValidationFailure(ConfigException v, boolean withCause) { assertNotNull(v); - assertThat("", is(not(v.getMessage().strip()))); - assertThat("", is(not(v.advice.strip()))); + assertNotEquals("", v.getMessage().strip()); + assertNotEquals("", v.getAdvice().strip()); if (withCause) { assertNotNull(v.getCause()); } else { @@ -82,8 +79,8 @@ private static void assertValidationFailure(ConfigException v, } } - private final static String TOOL_JAVA; - private final static String TOOL_UNKNOWN = Path.of(System.getProperty( + private static final String TOOL_JAVA; + private static final String TOOL_UNKNOWN = Path.of(System.getProperty( "java.home"), "bin").toString(); static { From a1473ec302f1e9d22ebb2417fff3bee21134d6f5 Mon Sep 17 00:00:00 2001 From: Per Minborg <pminborg@openjdk.org> Date: Wed, 27 Nov 2024 13:26:36 +0000 Subject: [PATCH 278/311] 8294432: Add provisions to calculate hash values from MemorySegments Reviewed-by: mcimadamore --- .../foreign/SegmentBulkOperations.java | 90 +++++++++++ .../TestSegmentBulkOperationsContentHash.java | 147 ++++++++++++++++++ .../java/lang/foreign/SegmentBulkHash.java | 101 ++++++++++++ 3 files changed, 338 insertions(+) create mode 100644 test/jdk/java/foreign/TestSegmentBulkOperationsContentHash.java create mode 100644 test/micro/org/openjdk/bench/java/lang/foreign/SegmentBulkHash.java diff --git a/src/java.base/share/classes/jdk/internal/foreign/SegmentBulkOperations.java b/src/java.base/share/classes/jdk/internal/foreign/SegmentBulkOperations.java index 11f1914a707..d928f8fc425 100644 --- a/src/java.base/share/classes/jdk/internal/foreign/SegmentBulkOperations.java +++ b/src/java.base/share/classes/jdk/internal/foreign/SegmentBulkOperations.java @@ -28,7 +28,9 @@ import jdk.internal.misc.ScopedMemoryAccess; import jdk.internal.util.Architecture; import jdk.internal.util.ArraysSupport; +import jdk.internal.util.ByteArrayLittleEndian; import jdk.internal.vm.annotation.ForceInline; +import jdk.internal.vm.annotation.Stable; import java.lang.foreign.MemorySegment; @@ -156,6 +158,94 @@ public static void copy(AbstractMemorySegmentImpl src, long srcOffset, } } + private static final @Stable int[] POWERS_OF_31 = new int[]{ + 0x0000001f, 0x000003c1, 0x0000745f, 0x000e1781, + 0x01b4d89f, 0x34e63b41, 0x67e12cdf, 0x94446f01}; + + /** + * {@return a 32-bit hash value calculated from the content in the provided + * {@code segment} between the provided offsets} + * <p> + * The method is implemented as a 32-bit polynomial hash function equivalent to: + * {@snippet lang=java : + * final long length = toOffset - fromOffset; + * segment.checkBounds(fromOffset, length); + * int result = 1; + * for (long i = fromOffset; i < toOffset; i++) { + * result = 31 * result + segment.get(JAVA_BYTE, i); + * } + * return result; + * } + * but is potentially more performant. + * + * @param segment from which a content hash should be computed + * @param fromOffset starting offset (inclusive) in the segment + * @param toOffset ending offset (non-inclusive) in the segment + * @throws WrongThreadException if this method is called from a thread {@code T}, + * such that {@code srcSegment.isAccessibleBy(T) == false} + * @throws IllegalStateException if the {@linkplain MemorySegment#scope() scope} + * associated with {@code segment} is not + * {@linkplain MemorySegment.Scope#isAlive() alive} + * @throws IndexOutOfBoundsException if either {@code fromOffset} or {@code toOffset} + * are {@code > segment.byteSize} + * @throws IndexOutOfBoundsException if either {@code fromOffset} or {@code toOffset} + * are {@code < 0} + * @throws IndexOutOfBoundsException if {@code toOffset - fromOffset} is {@code < 0} + */ + @ForceInline + public static int contentHash(AbstractMemorySegmentImpl segment, long fromOffset, long toOffset) { + final long length = toOffset - fromOffset; + segment.checkBounds(fromOffset, length); + if (length == 0) { + // The state has to be checked explicitly for zero-length segments + segment.scope.checkValidState(); + return 1; + } + int result = 1; + final long longBytes = length & ((1L << 62) - 8); + final long limit = fromOffset + longBytes; + for (; fromOffset < limit; fromOffset += 8) { + long val = SCOPED_MEMORY_ACCESS.getLongUnaligned(segment.sessionImpl(), segment.unsafeGetBase(), segment.unsafeGetOffset() + fromOffset, !Architecture.isLittleEndian()); + result = result * POWERS_OF_31[7] + + ((byte) (val >>> 56)) * POWERS_OF_31[6] + + ((byte) (val >>> 48)) * POWERS_OF_31[5] + + ((byte) (val >>> 40)) * POWERS_OF_31[4] + + ((byte) (val >>> 32)) * POWERS_OF_31[3] + + ((byte) (val >>> 24)) * POWERS_OF_31[2] + + ((byte) (val >>> 16)) * POWERS_OF_31[1] + + ((byte) (val >>> 8)) * POWERS_OF_31[0] + + ((byte) val); + } + int remaining = (int) (length - longBytes); + // 0...0X00 + if (remaining >= 4) { + int val = SCOPED_MEMORY_ACCESS.getIntUnaligned(segment.sessionImpl(), segment.unsafeGetBase(), segment.unsafeGetOffset() + fromOffset, !Architecture.isLittleEndian()); + result = result * POWERS_OF_31[3] + + ((byte) (val >>> 24)) * POWERS_OF_31[2] + + ((byte) (val >>> 16)) * POWERS_OF_31[1] + + ((byte) (val >>> 8)) * POWERS_OF_31[0] + + ((byte) val); + fromOffset += 4; + remaining -= 4; + } + // 0...00X0 + if (remaining >= 2) { + short val = SCOPED_MEMORY_ACCESS.getShortUnaligned(segment.sessionImpl(), segment.unsafeGetBase(), segment.unsafeGetOffset() + fromOffset, !Architecture.isLittleEndian()); + result = result * POWERS_OF_31[1] + + ((byte) (val >>> 8)) * POWERS_OF_31[0] + + ((byte) val); + fromOffset += 2; + remaining -= 2; + } + // 0...000X + if (remaining == 1) { + byte val = SCOPED_MEMORY_ACCESS.getByte(segment.sessionImpl(), segment.unsafeGetBase(), segment.unsafeGetOffset() + fromOffset); + result = result * POWERS_OF_31[0] + + val; + } + return result; + } + @ForceInline public static long mismatch(AbstractMemorySegmentImpl src, long srcFromOffset, long srcToOffset, AbstractMemorySegmentImpl dst, long dstFromOffset, long dstToOffset) { diff --git a/test/jdk/java/foreign/TestSegmentBulkOperationsContentHash.java b/test/jdk/java/foreign/TestSegmentBulkOperationsContentHash.java new file mode 100644 index 00000000000..96b73e7eee6 --- /dev/null +++ b/test/jdk/java/foreign/TestSegmentBulkOperationsContentHash.java @@ -0,0 +1,147 @@ +/* + * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @summary Test SegmentBulkOperations::contentHash + * @modules java.base/jdk.internal.foreign + * @run junit TestSegmentBulkOperationsContentHash + */ + +import jdk.internal.foreign.AbstractMemorySegmentImpl; +import jdk.internal.foreign.SegmentBulkOperations; +import org.junit.jupiter.api.Disabled; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; + +import java.lang.foreign.Arena; +import java.lang.foreign.MemorySegment; +import java.lang.foreign.ValueLayout; +import java.util.Arrays; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.atomic.AtomicReference; +import java.util.stream.IntStream; +import java.util.stream.Stream; + +import static org.junit.jupiter.api.Assertions.*; + +final class TestSegmentBulkOperationsContentHash { + + @ParameterizedTest + @MethodSource("sizes") + @Disabled + void testHashValues(int len) { + try (var arena = Arena.ofConfined()) { + for (int i = Byte.MIN_VALUE; i <= Byte.MAX_VALUE ; i++) { + var segment = arena.allocate(len); + segment.fill((byte) i); + int hash = hash(segment); + int expected = Arrays.hashCode(segment.toArray(ValueLayout.JAVA_BYTE)); + assertEquals(expected, hash, Arrays.toString(segment.toArray(ValueLayout.JAVA_BYTE))); + } + } + } + + @ParameterizedTest + @MethodSource("sizes") + void testOffsets(int len) { + if (len < 2) { + return; + } + try (var arena = Arena.ofConfined()) { + for (int i = Byte.MIN_VALUE; i <= Byte.MAX_VALUE ; i++) { + var segment = arena.allocate(len); + segment.fill((byte) i); + int hash = hash(segment, 1, segment.byteSize() - 1); + MemorySegment slice = segment.asSlice(1, segment.byteSize() - 2); + byte[] arr = slice.toArray(ValueLayout.JAVA_BYTE); + System.out.println(Arrays.toString(arr)); + int expected = Arrays.hashCode(arr); + assertEquals(expected, hash, Arrays.toString(segment.toArray(ValueLayout.JAVA_BYTE))); + } + } + } + + @ParameterizedTest + @MethodSource("sizes") + void testOutOfBounds(int len) { + try (var arena = Arena.ofConfined()) { + var segment = arena.allocate(len); + assertThrows(IndexOutOfBoundsException.class, + () -> hash(segment, 0, segment.byteSize() + 1)); + assertThrows(IndexOutOfBoundsException.class, + () -> hash(segment, 0, -1)); + assertThrows(IndexOutOfBoundsException.class, + () -> hash(segment, -1, 0)); + if (len > 2) { + assertThrows(IndexOutOfBoundsException.class, + () -> hash(segment, 2, 1)); + } + } + } + + @ParameterizedTest + @MethodSource("sizes") + void testConfinement(int len) { + try (var arena = Arena.ofConfined()) { + var segment = arena.allocate(len); + AtomicReference<RuntimeException> ex = new AtomicReference<>(); + CompletableFuture<Void> future = CompletableFuture.runAsync(() -> { + try { + hash(segment); + } catch (RuntimeException e) { + ex.set(e); + } + }); + future.join(); + assertInstanceOf(WrongThreadException.class, ex.get()); + } + } + + @ParameterizedTest + @MethodSource("sizes") + void testScope(int len) { + var arena = Arena.ofConfined(); + var segment = arena.allocate(len); + arena.close(); + assertThrows(IllegalStateException.class, () -> hash(segment)); + } + + private static int hash(MemorySegment segment) { + return hash(segment, 0, segment.byteSize()); + } + + private static int hash(MemorySegment segment, long fromOffset, long toOffset) { + return SegmentBulkOperations.contentHash((AbstractMemorySegmentImpl) segment, fromOffset, toOffset); + } + + private static final int MAX_SIZE = 1 << 10; + + private static Stream<Arguments> sizes() { + return IntStream.of(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 23, 32, 63, 128, 256, 511, MAX_SIZE) + .boxed() + .map(Arguments::of); + } + +} diff --git a/test/micro/org/openjdk/bench/java/lang/foreign/SegmentBulkHash.java b/test/micro/org/openjdk/bench/java/lang/foreign/SegmentBulkHash.java new file mode 100644 index 00000000000..927a7d3fb1f --- /dev/null +++ b/test/micro/org/openjdk/bench/java/lang/foreign/SegmentBulkHash.java @@ -0,0 +1,101 @@ +/* + * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +package org.openjdk.bench.java.lang.foreign; + +import jdk.internal.foreign.AbstractMemorySegmentImpl; +import jdk.internal.foreign.SegmentBulkOperations; +import org.openjdk.jmh.annotations.Benchmark; +import org.openjdk.jmh.annotations.BenchmarkMode; +import org.openjdk.jmh.annotations.Fork; +import org.openjdk.jmh.annotations.Measurement; +import org.openjdk.jmh.annotations.Mode; +import org.openjdk.jmh.annotations.OutputTimeUnit; +import org.openjdk.jmh.annotations.Param; +import org.openjdk.jmh.annotations.Scope; +import org.openjdk.jmh.annotations.Setup; +import org.openjdk.jmh.annotations.State; +import org.openjdk.jmh.annotations.Warmup; + +import java.lang.foreign.Arena; +import java.lang.foreign.MemorySegment; +import java.util.Arrays; +import java.util.Random; +import java.util.concurrent.TimeUnit; + +import static java.lang.foreign.ValueLayout.JAVA_BYTE; + +@BenchmarkMode(Mode.AverageTime) +@Warmup(iterations = 5, time = 500, timeUnit = TimeUnit.MILLISECONDS) +@Measurement(iterations = 10, time = 500, timeUnit = TimeUnit.MILLISECONDS) +@State(Scope.Thread) +@OutputTimeUnit(TimeUnit.NANOSECONDS) +@Fork(value = 3, jvmArgs = {"--add-exports=java.base/jdk.internal.foreign=ALL-UNNAMED"}) +public class SegmentBulkHash { + + @Param({"8", "64"}) + public int ELEM_SIZE; + + byte[] array; + AbstractMemorySegmentImpl heapSegment; + AbstractMemorySegmentImpl nativeSegment; + + @Setup + public void setup() { + // Always use the same alignment regardless of size + nativeSegment = (AbstractMemorySegmentImpl) Arena.ofAuto().allocate(ELEM_SIZE, 16); + var rnd = new Random(42); + for (int i = 0; i < ELEM_SIZE; i++) { + nativeSegment.set(JAVA_BYTE, i, (byte) rnd.nextInt(Byte.MIN_VALUE, Byte.MAX_VALUE)); + } + array = nativeSegment.toArray(JAVA_BYTE); + heapSegment = (AbstractMemorySegmentImpl) MemorySegment.ofArray(array); + } + + @Benchmark + public int array() { + return Arrays.hashCode(array); + } + + @Benchmark + public int heapSegment() { + return SegmentBulkOperations.contentHash(heapSegment, 0, ELEM_SIZE); + } + + @Benchmark + public int nativeSegment() { + return SegmentBulkOperations.contentHash(nativeSegment, 0, ELEM_SIZE); + } + + @Benchmark + public int nativeSegmentJava() { + int result = 1; + for (long i = 0; i < ELEM_SIZE; i++) { + result = 31 * result + nativeSegment.get(JAVA_BYTE, i); + } + return result; + } + +} + From ac3bbf7ddc1f6a55682264d66282e6ee8825f47a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Volkan=20Yaz=C4=B1c=C4=B1?= <volkan.yazici@oracle.com> Date: Wed, 27 Nov 2024 13:49:51 +0000 Subject: [PATCH 279/311] 8344856: Remove calls to SecurityManager and doPrivileged in sun.net.www.protocol.ftp.FtpURLConnection after JEP 486 integration Reviewed-by: dfuchs --- .../net/www/protocol/ftp/FtpURLConnection.java | 18 ++++-------------- 1 file changed, 4 insertions(+), 14 deletions(-) diff --git a/src/java.base/share/classes/sun/net/www/protocol/ftp/FtpURLConnection.java b/src/java.base/share/classes/sun/net/www/protocol/ftp/FtpURLConnection.java index f559cc5b820..493fda1c1b3 100644 --- a/src/java.base/share/classes/sun/net/www/protocol/ftp/FtpURLConnection.java +++ b/src/java.base/share/classes/sun/net/www/protocol/ftp/FtpURLConnection.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1994, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1994, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -43,7 +43,6 @@ import java.util.List; import java.util.StringTokenizer; import java.security.Permission; -import java.util.Properties; import sun.net.NetworkClient; import sun.net.util.IPAddressUtil; import sun.net.www.MessageHeader; @@ -53,7 +52,6 @@ import sun.net.ftp.FtpClient; import sun.net.ftp.FtpProtocolException; import sun.net.www.ParseUtil; -import sun.security.action.GetPropertyAction; /** @@ -226,13 +224,7 @@ public synchronized void connect() throws IOException { /** * Do we have to use a proxy? */ - @SuppressWarnings("removal") - ProxySelector sel = java.security.AccessController.doPrivileged( - new java.security.PrivilegedAction<ProxySelector>() { - public ProxySelector run() { - return ProxySelector.getDefault(); - } - }); + ProxySelector sel = ProxySelector.getDefault(); if (sel != null) { URI uri = sun.net.www.ParseUtil.toURI(url); final List<Proxy> proxies; @@ -293,10 +285,8 @@ public ProxySelector run() { if (user == null) { user = "anonymous"; - Properties props = GetPropertyAction.privilegedGetProperties(); - String vers = props.getProperty("java.version"); - password = props.getProperty("ftp.protocol.user", - "Java" + vers + "@"); + String vers = System.getProperty("java.version"); + password = System.getProperty("ftp.protocol.user", "Java" + vers + "@"); } try { ftp = FtpClient.create(); From 0b704a2279ddc5f2c00e64099310554b8c8529b8 Mon Sep 17 00:00:00 2001 From: Nizar Benalla <nbenalla@openjdk.org> Date: Wed, 27 Nov 2024 15:33:54 +0000 Subject: [PATCH 280/311] 8343239: Javadoc marks non-preview type as preview if it's the subtype of a preview type Reviewed-by: liach, hannesw --- .../internal/doclets/toolkit/util/Utils.java | 1 - .../doclet/testPreview/TestPreview.java | 64 ++++++++++++++++++- 2 files changed, 61 insertions(+), 4 deletions(-) diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/Utils.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/Utils.java index c29feec1712..0cdf04fb779 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/Utils.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/toolkit/util/Utils.java @@ -2485,7 +2485,6 @@ public PreviewSummary declaredUsingPreviewAPIs(Element el) { usedInDeclaration.addAll(types2Classes(tpe.getBounds())); } usedInDeclaration.addAll(types2Classes(List.of(te.getSuperclass()))); - usedInDeclaration.addAll(types2Classes(te.getInterfaces())); usedInDeclaration.addAll(types2Classes(te.getPermittedSubclasses())); usedInDeclaration.addAll(types2Classes(te.getRecordComponents().stream().map(Element::asType).toList())); //TODO: annotations on record components??? } diff --git a/test/langtools/jdk/javadoc/doclet/testPreview/TestPreview.java b/test/langtools/jdk/javadoc/doclet/testPreview/TestPreview.java index 7022b02ee88..df0e0910151 100644 --- a/test/langtools/jdk/javadoc/doclet/testPreview/TestPreview.java +++ b/test/langtools/jdk/javadoc/doclet/testPreview/TestPreview.java @@ -24,20 +24,24 @@ /* * @test * @bug 8250768 8261976 8277300 8282452 8287597 8325325 8325874 8297879 - * 8331947 8281533 8318416 + * 8331947 8281533 8343239 8318416 * @summary test generated docs for items declared using preview - * @library ../../lib + * @library /tools/lib ../../lib * @modules jdk.javadoc/jdk.javadoc.internal.tool * jdk.javadoc/jdk.javadoc.internal.doclets.formats.html.resources:+open - * @build javadoc.tester.* + * @build toolbox.ToolBox javadoc.tester.* * @run main TestPreview */ +import java.io.IOException; import java.nio.file.Path; import java.nio.file.Paths; + import javadoc.tester.JavadocTester; +import toolbox.ToolBox; public class TestPreview extends JavadocTester { + ToolBox tb = new ToolBox(); public static void main(String... args) throws Exception { var tester = new TestPreview(); @@ -185,6 +189,60 @@ public void testPreviewAPIJavadoc() { checkOutput("preview-list.html", false, "supportMethod"); } + // 8343239 pre-existing permanent API that is later retrofitted + // to extend a @PreviewFeature interface should not be flagged as a preview feature + @Test + public void nonPreviewExtendsPreview(Path base) throws IOException { + + Path src = base.resolve("src"); + tb.writeJavaFiles(src, """ + package p; + import jdk.internal.javac.PreviewFeature; + + /** + * Preview feature + */ + @PreviewFeature(feature= PreviewFeature.Feature.TEST) + public interface CoreInterface { + } + """, """ + package p; + + /** + * Non preview feature + */ + public interface NonPreviewExtendsPreview extends CoreInterface { + default int getNumber() { + return 0; + } + } + """); + javadoc("-d", "out-non-preview-extends-preview", + "--add-exports", "java.base/jdk.internal.javac=ALL-UNNAMED", + "--source-path", + src.toString(), + "p"); + checkExit(Exit.OK); + checkOutput("p/NonPreviewExtendsPreview.html", false, + """ + <code>NonPreviewExtendsPreview</code> relies on preview features of the Java platform: + """, + """ + <code>NonPreviewExtendsPreview</code> refers to one or more preview APIs: + """); + checkOutput("p/CoreInterface.html", true, + """ + <div class="horizontal-scroll"> + <div class="type-signature"><span class="modifiers">public interface </span><span class="element-name type-name-label">CoreInterface</span></div> + <div class="preview-block" id="preview-p.CoreInterface"><span class="preview-label"><code>CoreInterface</code> is a preview API of the Java platform.</span> + <div class="preview-comment">Programs can only use <code>CoreInterface</code> when preview features are enabled.</div> + <div class="preview-comment">Preview features may be removed in a future release, or upgraded to permanent features of the Java platform.</div> + </div> + <div class="block">Preview feature</div> + </div> + """); + } + @Test public void test8277300() { javadoc("-d", "out-8277300", From b89cba7517b5b7373988d15f3a22c412455e5cbd Mon Sep 17 00:00:00 2001 From: Nizar Benalla <nbenalla@openjdk.org> Date: Wed, 27 Nov 2024 15:36:02 +0000 Subject: [PATCH 281/311] 8342808: Javadoc should add whitespace between type parameters Reviewed-by: hannesw --- .../doclets/formats/html/ClassWriter.java | 13 +++++++-- .../doclets/formats/html/HtmlLinkFactory.java | 11 +++++--- .../doclets/formats/html/Signatures.java | 11 +------- .../formats/html/markup/HtmlStyles.java | 8 ------ .../formats/html/resources/stylesheet.css | 1 - .../TestGenericTypeLink.java | 23 ++++++++------- .../testInheritance/TestInheritance.java | 4 +-- .../doclet/testInterface/TestInterface.java | 8 +++--- .../TestMethodSignature.java | 28 +++++++++---------- .../TestNewLanguageFeatures.java | 2 +- .../TestTypeAnnotations.java | 26 ++++++++--------- .../testTypeParams/TestTypeParameters.java | 4 +-- 12 files changed, 66 insertions(+), 73 deletions(-) diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ClassWriter.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ClassWriter.java index 7b271485f1f..d934a9aab63 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ClassWriter.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/ClassWriter.java @@ -57,7 +57,6 @@ import jdk.javadoc.internal.html.Content; import jdk.javadoc.internal.html.ContentBuilder; import jdk.javadoc.internal.html.HtmlAttr; -import jdk.javadoc.internal.html.HtmlTag; import jdk.javadoc.internal.html.HtmlTree; import jdk.javadoc.internal.html.Text; @@ -78,6 +77,9 @@ public class ClassWriter extends SubWriterHolderWriter { "java.lang.constant.ConstantDesc", "java.io.Serializable"); + /* Length threshold to determine whether to insert whitespace between type parameters */ + protected static final int LONG_TYPE_PARAM = 8; + protected final TypeElement typeElement; protected final ClassTree classTree; @@ -459,9 +461,16 @@ private Content getTypeParameters() { .linkToSelf(false); // Let's not link to ourselves in the header content.add("<"); var first = true; + boolean longTypeParams = typeParams.stream() + .map(t -> getLink(linkInfo.forType(t.asType()))) + .anyMatch(t -> t.charCount() > ClassWriter.LONG_TYPE_PARAM); for (TypeParameterElement t : typeParams) { if (!first) { - content.add(",").add(HtmlTree.WBR()); + if (longTypeParams) { + content.add(", "); + } else { + content.add(",").add(HtmlTree.WBR()); + } } var typeParamLink = getLink(linkInfo.forType(t.asType())); content.add(needsId diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlLinkFactory.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlLinkFactory.java index cca5c821c67..54da5af14a9 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlLinkFactory.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/HtmlLinkFactory.java @@ -401,12 +401,15 @@ protected Content getTypeParameterLinks(HtmlLinkInfo linkInfo) { } links.add("<"); boolean many = false; + boolean longTypeParams = vars.stream() + .map(t -> getLink(linkInfo.forType(t))) + .anyMatch(t -> t.charCount() > ClassWriter.LONG_TYPE_PARAM); for (TypeMirror t : vars) { if (many) { - links.add(","); - links.add(HtmlTree.WBR()); - if (linkInfo.addLineBreaksInTypeParameters()) { - links.add(Text.NL); + if (longTypeParams) { + links.add(", "); + } else { + links.add(",").add(HtmlTree.WBR()); } } links.add(getLink(linkInfo.forType(t))); diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/Signatures.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/Signatures.java index 872fb2dcabe..2a411050000 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/Signatures.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/Signatures.java @@ -355,9 +355,6 @@ static class MemberSignature { private Content parameters; private Content exceptions; - // Threshold for length of type parameters before switching from inline to block representation. - private static final int TYPE_PARAMS_MAX_INLINE_LENGTH = 50; - // Threshold for combined length of modifiers, type params and return type before breaking // it up with a line break before the return type. private static final int RETURN_TYPE_MAX_LINE_LENGTH = 50; @@ -532,13 +529,7 @@ private int appendTypeParameters(Content target, int lastLineSeparator) { // Apply different wrapping strategies for type parameters // depending on the combined length of type parameters and return type. // Note return type will be null if this is a constructor. - int typeParamLength = typeParameters.charCount(); - - if (typeParamLength >= TYPE_PARAMS_MAX_INLINE_LENGTH) { - target.add(HtmlTree.SPAN(HtmlStyles.typeParametersLong, typeParameters)); - } else { - target.add(HtmlTree.SPAN(HtmlStyles.typeParameters, typeParameters)); - } + target.add(HtmlTree.SPAN(HtmlStyles.typeParameters, typeParameters)); int lineLength = target.charCount() - lastLineSeparator; int newLastLineSeparator = lastLineSeparator; diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/markup/HtmlStyles.java b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/markup/HtmlStyles.java index 6199e6a72a3..358f490334b 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/markup/HtmlStyles.java +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/markup/HtmlStyles.java @@ -708,14 +708,6 @@ public enum HtmlStyles implements HtmlStyle { */ typeParameters, - /** - * The class of a {@code span} containing type parameters in the signature of an element, - * used when the type parameters are too long to be displayed inline. - * @implNote - * The threshold for choosing between {@code typeParameters} and {@code typeParametersLong} - * is 50 characters. - */ - typeParametersLong, //</editor-fold> //<editor-fold desc="search index and results"> diff --git a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/stylesheet.css b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/stylesheet.css index f8c9b38f122..bdf84dc0f97 100644 --- a/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/stylesheet.css +++ b/src/jdk.javadoc/share/classes/jdk/javadoc/internal/doclets/formats/html/resources/stylesheet.css @@ -793,7 +793,6 @@ div.block { .type-signature { margin-top: 0; } -.member-signature .type-parameters-long, .member-signature .parameters, .member-signature .exceptions { display: inline-block; diff --git a/test/langtools/jdk/javadoc/doclet/testGenericTypeLink/TestGenericTypeLink.java b/test/langtools/jdk/javadoc/doclet/testGenericTypeLink/TestGenericTypeLink.java index d8bf1fc2bdf..b7f1a95ae1e 100644 --- a/test/langtools/jdk/javadoc/doclet/testGenericTypeLink/TestGenericTypeLink.java +++ b/test/langtools/jdk/javadoc/doclet/testGenericTypeLink/TestGenericTypeLink.java @@ -74,15 +74,15 @@ r interface in java.util" class="external-link">List</a><? extends <a href="h <li><code><a href="http://example.com/docs/api/java.base/java/util/Map.html" title="\ class or interface in java.util" class="external-link">Map</a><<a href="http://ex\ ample.com/docs/api/java.base/java/lang/String.html" title="class or interface in jav\ - a.lang" class="external-link">String</a>,<wbr>? extends <a href="http://example.com/\ + a.lang" class="external-link">String</a>, ? extends <a href="http://example.com/\ docs/api/java.base/java/lang/CharSequence.html" title="class or interface in java.la\ ng" class="external-link">CharSequence</a>></code></li> <li><code><a href="http://example.com/docs/api/java.base/java/util/Map.html" title="\ class or interface in java.util" class="external-link">Map</a><<a href="http://ex\ ample.com/docs/api/java.base/java/lang/String.html" title="class or interface in jav\ - a.lang" class="external-link">String</a>,<wbr>? super <a href="A.html" title="class \ + a.lang" class="external-link">String</a>, ? super <a href="A.html" title="class \ in pkg1">A</a><<a href="http://example.com/docs/api/java.base/java/lang/String.ht\ - ml" title="class or interface in java.lang" class="external-link">String</a>,<wbr>? \ + ml" title="class or interface in java.lang" class="external-link">String</a>, ? \ extends <a href="http://example.com/docs/api/java.base/java/lang/RuntimeException.ht\ ml" title="class or interface in java.lang" class="external-link">RuntimeException</\ a>>></code></li> @@ -97,7 +97,7 @@ class or interface in java.util" class="external-link">Map</a><<a href="http: """ <div class="block"><code><a href="A.html" title="class in pkg1">A</a><<a href="h\ ttp://example.com/docs/api/java.base/java/lang/String.html" title="class or interfa\ - ce in java.lang" class="external-link">String</a>,<wbr><a href="A.SomeException.htm\ + ce in java.lang" class="external-link">String</a>, <a href="A.SomeException.htm\ l" title="class in pkg1">A.SomeException</a>></code> <a href="http://example.com/docs/api/java.base/java/util/Map.html" title="class or\ interface in java.util" class="external-link">link to generic type with label</a>\ @@ -109,7 +109,7 @@ interface in java.util" class="external-link">link to generic type with label</a <ul class="tag-list-long"> <li><code><a href="A.html" title="class in pkg1">A</a><<a href="http://example.c\ om/docs/api/java.base/java/lang/String.html" title="class or interface in java.lang\ - " class="external-link">String</a>,<wbr><a href="A.SomeException.html" title="class\ + " class="external-link">String</a>, <a href="A.SomeException.html" title="class\ in pkg1">A.SomeException</a>></code></li> <li><a href="http://example.com/docs/api/java.base/java/util/List.html" title="clas\ s or interface in java.util" class="external-link">Link to generic type with label<\ @@ -126,17 +126,17 @@ s or interface in java.util" class="external-link">Link to generic type with lab <ul class="tag-list-long"> <li><code><a href="A.html" title="class in pkg1">A</a><<a href="http://exampl\ e.com/docs/api/java.base/java/lang/String.html" title="class or interface in jav\ - a.lang" class="external-link">String</a>,<wbr><a href="http://example.com/docs/a\ + a.lang" class="external-link">String</a>, <a href="http://example.com/docs/a\ pi/java.base/java/lang/RuntimeException.html" title="class or interface in java.\ lang" class="external-link">RuntimeException</a>>.<a href="A.Inner.html" titl\ e="class in pkg1">Inner</a></code></li> <li><code><a href="A.html" title="class in pkg1">A</a><<a href="A.html" title\ ="class in pkg1">A</a><<a href="http://example.com/docs/api/java.base/java/la\ ng/String.html" title="class or interface in java.lang" class="external-link">St\ - ring</a>,<wbr><a href="http://example.com/docs/api/java.base/java/lang/RuntimeEx\ + ring</a>, <a href="http://example.com/docs/api/java.base/java/lang/RuntimeEx\ ception.html" title="class or interface in java.lang" class="external-link">Runt\ - imeException</a>>.<a href="A.Inner.html" title="class in pkg1">Inner</a>,<wbr\ - ><a href="A.SomeException.html" title="class in pkg1">A.SomeException</a>></c\ + imeException</a>>.<a href="A.Inner.html" title="class in pkg1">Inner</a>, \ + <a href="A.SomeException.html" title="class in pkg1">A.SomeException</a>></c\ ode></li> </ul> </dd> @@ -148,8 +148,8 @@ s or interface in java.util" class="external-link">Link to generic type with lab /a></code></span></div> <div class="block">Here's a generic link: <code><a href="A.html" title="class in\ pkg1">A</a><<a href="http://example.com/docs/api/java.base/java/lang/Object.\ - html" title="class or interface in java.lang" class="external-link">Object</a>,<\ - wbr><a href="http://example.com/docs/api/java.base/java/lang/RuntimeException.ht\ + html" title="class or interface in java.lang" class="external-link">Object</a>, \ + <a href="http://example.com/docs/api/java.base/java/lang/RuntimeException.ht\ ml" title="class or interface in java.lang" class="external-link">RuntimeExcepti\ on</a>>.<a href="A.Inner.html" title="class in pkg1">Inner</a>"""); } @@ -213,4 +213,3 @@ public void testInvalidLinks() { </dl>"""); } } - diff --git a/test/langtools/jdk/javadoc/doclet/testInheritance/TestInheritance.java b/test/langtools/jdk/javadoc/doclet/testInheritance/TestInheritance.java index fc08c53467c..5ebb5157ecb 100644 --- a/test/langtools/jdk/javadoc/doclet/testInheritance/TestInheritance.java +++ b/test/langtools/jdk/javadoc/doclet/testInheritance/TestInheritance.java @@ -95,8 +95,8 @@ public class D<R, S> extends B<S, B> { private D() { } } <div class="inheritance">pkg.B<O,<wbr>P></div>"""); checkOrder("pkg/C.html", """ <div class="inheritance" title="Inheritance Tree">java.lang.Object - <div class="inheritance"><a href="A.html" title="class in pkg">pkg.A</a><java.lang.String,<wbr>Q> - <div class="inheritance"><a href="B.html" title="class in pkg">pkg.B</a><java.lang.String,<wbr>Q> + <div class="inheritance"><a href="A.html" title="class in pkg">pkg.A</a><java.lang.String, Q> + <div class="inheritance"><a href="B.html" title="class in pkg">pkg.B</a><java.lang.String, Q> <div class="inheritance">pkg.C<Q></div>"""); checkOrder("pkg/D.html", """ <div class="inheritance" title="Inheritance Tree">java.lang.Object diff --git a/test/langtools/jdk/javadoc/doclet/testInterface/TestInterface.java b/test/langtools/jdk/javadoc/doclet/testInterface/TestInterface.java index f213d393fdf..214f134f3ad 100644 --- a/test/langtools/jdk/javadoc/doclet/testInterface/TestInterface.java +++ b/test/langtools/jdk/javadoc/doclet/testInterface/TestInterface.java @@ -212,9 +212,9 @@ public void test2() { ator.OfInt</a><<a href="Spliterator.OfInt.html#type-param-Integer" title="type parameter in Spli\ terator.OfInt">Integer</a>>, <a href="Spliterator.OfPrimitive.html" title="in\ terface in pkg2">Spliterator.OfPrimitive</a><<a href="Spliterator.OfPrimitive\ - .html#type-param-T" title="type parameter in Spliterator.OfPrimitive">T</a>,<wbr><a href="Spl\ + .html#type-param-T" title="type parameter in Spliterator.OfPrimitive">T</a>, <a href="Spl\ iterator.OfPrimitive.html#type-param-T_CONS" title="type parameter in Spliterator.OfPrimitive">T_C\ - ONS</a>,<wbr><a href="Spliterator.OfPrimitive.html#type-param-T_SPLITR" title="type parameter in Spl\ + ONS</a>, <a href="Spliterator.OfPrimitive.html#type-param-T_SPLITR" title="type parameter in Spl\ iterator.OfPrimitive">T_SPLITR</a> extends <a href="Spliterator.OfPrimitive.html\ " title="interface in pkg2">Spliterator.OfPrimitive</a><<a href="Spliterator.\ OfPrimitive.html#type-param-T" title="type parameter in Spliterator.OfPrimitive">T</a>,<wbr><\ @@ -243,8 +243,8 @@ public void test2() { <div class="col-second even-row-color"><code><a href="Spliterator.OfPrimitive.ht\ ml" class="type-name-link" title="interface in pkg2">Spliterator.OfPrimitive</a>\ <<a href="Spliterator.OfPrimitive.html#type-param-T" title="type parameter in Spliterator.\ - OfPrimitive">T</a>,<wbr><a href="Spliterator.OfPrimitive.html#type-param-T_CONS" title="type param\ - eter in Spliterator.OfPrimitive">T_CONS</a>,<wbr><a href="Spliterator.OfPrimitiv\ + OfPrimitive">T</a>, <a href="Spliterator.OfPrimitive.html#type-param-T_CONS" title="type param\ + eter in Spliterator.OfPrimitive">T_CONS</a>, <a href="Spliterator.OfPrimitiv\ e.html#type-param-T_SPLITR" title="type parameter in Spliterator.OfPrimitive">T_SPLITR</a> extends <\ a href="Spliterator.OfPrimitive.html" title="interface in pkg2">Spliterator.OfPr\ imitive</a><<a href="Spliterator.OfPrimitive.html#type-param-T" title="type parameter in S\ diff --git a/test/langtools/jdk/javadoc/doclet/testMethodSignature/TestMethodSignature.java b/test/langtools/jdk/javadoc/doclet/testMethodSignature/TestMethodSignature.java index bda82abddb6..3a0f56962de 100644 --- a/test/langtools/jdk/javadoc/doclet/testMethodSignature/TestMethodSignature.java +++ b/test/langtools/jdk/javadoc/doclet/testMethodSignature/TestMethodSignature.java @@ -72,13 +72,13 @@ public void test() { """ <div class="member-signature"><span class="modifiers">public static</span> \ - <span class="type-parameters-long"><T1 extends java.lang.AutoCloseable,<wbr> - T2 extends java.lang.AutoCloseable,<wbr> - T3 extends java.lang.AutoCloseable,<wbr> - T4 extends java.lang.AutoCloseable,<wbr> - T5 extends java.lang.AutoCloseable,<wbr> - T6 extends java.lang.AutoCloseable,<wbr> - T7 extends java.lang.AutoCloseable,<wbr> + <span class="type-parameters"><T1 extends java.lang.AutoCloseable, \ + T2 extends java.lang.AutoCloseable, \ + T3 extends java.lang.AutoCloseable, \ + T4 extends java.lang.AutoCloseable, \ + T5 extends java.lang.AutoCloseable, \ + T6 extends java.lang.AutoCloseable, \ + T7 extends java.lang.AutoCloseable, \ T8 extends java.lang.AutoCloseable></span> <span class="return-type"><a href="C.With8Types.html" title="class in pkg">C.Wit\ h8Types</a><T1,<wbr>T2,<wbr>T3,<wbr>T4,<wbr>T5,<wbr>T6,<wbr>T7,<wbr>T8></s\ @@ -100,13 +100,13 @@ public void test() { date="a date", comments="some comment about the method below") </span><span class="modifiers">public static</span> <span class="type-param\ - eters-long"><T1 extends java.lang.AutoCloseable,<wbr> - T2 extends java.lang.AutoCloseable,<wbr> - T3 extends java.lang.AutoCloseable,<wbr> - T4 extends java.lang.AutoCloseable,<wbr> - T5 extends java.lang.AutoCloseable,<wbr> - T6 extends java.lang.AutoCloseable,<wbr> - T7 extends java.lang.AutoCloseable,<wbr> + eters"><T1 extends java.lang.AutoCloseable, \ + T2 extends java.lang.AutoCloseable, \ + T3 extends java.lang.AutoCloseable, \ + T4 extends java.lang.AutoCloseable, \ + T5 extends java.lang.AutoCloseable, \ + T6 extends java.lang.AutoCloseable, \ + T7 extends java.lang.AutoCloseable, \ T8 extends java.lang.AutoCloseable></span> <span class="return-type"><a href="C.With8Types.html" title="class in pkg">C.Wit\ h8Types</a><T1,<wbr>T2,<wbr>T3,<wbr>T4,<wbr>T5,<wbr>T6,<wbr>T7,<wbr>T8></s\ diff --git a/test/langtools/jdk/javadoc/doclet/testNewLanguageFeatures/TestNewLanguageFeatures.java b/test/langtools/jdk/javadoc/doclet/testNewLanguageFeatures/TestNewLanguageFeatures.java index eafad8c3245..531fed92bc2 100644 --- a/test/langtools/jdk/javadoc/doclet/testNewLanguageFeatures/TestNewLanguageFeatures.java +++ b/test/langtools/jdk/javadoc/doclet/testNewLanguageFeatures/TestNewLanguageFeatures.java @@ -141,7 +141,7 @@ void checkTypeParameters() { // Signature of method with type parameters """ <div class="member-signature"><span class="modifiers">public</span> <span c\ - lass="type-parameters"><T extends java.util.List,<wbr> + lass="type-parameters"><T extends java.util.List, \ V></span> <span class="return-type">java.lang.String[]</span> <span class="element-name">meth\ odThatHasTypeParameters</span><wbr><span class="parameters">(T param1, diff --git a/test/langtools/jdk/javadoc/doclet/testTypeAnnotations/TestTypeAnnotations.java b/test/langtools/jdk/javadoc/doclet/testTypeAnnotations/TestTypeAnnotations.java index 948ed22c418..81c0b4a0b09 100644 --- a/test/langtools/jdk/javadoc/doclet/testTypeAnnotations/TestTypeAnnotations.java +++ b/test/langtools/jdk/javadoc/doclet/testTypeAnnotations/TestTypeAnnotations.java @@ -94,7 +94,7 @@ class </span><span class="element-name type-name-label">ExtendsBound<K extend """ <div class="type-signature"><span class="modifiers">class </span><span class="el\ ement-name type-name-label">TwoBounds<K extends <a href="ClassParamA.html" ti\ - tle="annotation interface in typeannos">@ClassParamA</a> java.lang.String,<wbr>V\ + tle="annotation interface in typeannos">@ClassParamA</a> java.lang.String, V\ extends <a href="ClassParamB.html" title="annotation interface in typeannos">@C\ lassParamB</a> java.lang.String></span>"""); @@ -122,7 +122,7 @@ class </span><span class="element-name type-name-label">ComplexBoth<K extends """ <div class="member-signature"><span class="return-type"><a href="Parameterized.h\ tml" title="class in typeannos">Parameterized</a><<a href="FldA.html" title="\ - annotation interface in typeannos">@FldA</a> java.lang.String,<wbr><a href="FldB\ + annotation interface in typeannos">@FldA</a> java.lang.String, <a href="FldB\ .html" title="annotation interface in typeannos">@FldB</a> java.lang.String><\ /span> <span class="element-name">bothTypeArgs</span></div>""", @@ -163,8 +163,8 @@ n interface in typeannos">@FldB</a> []</span> <span class="element-name">ar >Parameterized</a><<a href="FldA.html" title="annotation interface in typeann\ os">@FldA</a> <a href="Parameterized.html" title="class in typeannos">Parameteri\ zed</a><<a href="FldA.html" title="annotation interface in typeannos">@FldA</\ - a> java.lang.String,<wbr><a href="FldB.html" title="annotation interface in type\ - annos">@FldB</a> java.lang.String>,<wbr><a href="FldB.html" title="annotation\ + a> java.lang.String, <a href="FldB.html" title="annotation interface in type\ + annos">@FldB</a> java.lang.String>, <a href="FldB.html" title="annotation\ interface in typeannos">@FldB</a> java.lang.String></span> <span class=\ "element-name">nestedParameterized</span></div>""", @@ -212,8 +212,8 @@ interface in typeannos">@FldB</a> java.lang.String></span> <span class=\ os">MtdParameterized</a><<a href="MRtnA.html" title="annotation interface in \ typeannos">@MRtnA</a> <a href="MtdParameterized.html" title="class in typeannos"\ >MtdParameterized</a><<a href="MRtnA.html" title="annotation interface in typ\ - eannos">@MRtnA</a> java.lang.String,<wbr><a href="MRtnB.html" title="annotation \ - interface in typeannos">@MRtnB</a> java.lang.String>,<wbr><a href="MRtnB.html\ + eannos">@MRtnA</a> java.lang.String, <a href="MRtnB.html" title="annotation \ + interface in typeannos">@MRtnB</a> java.lang.String>, <a href="MRtnB.html\ " title="annotation interface in typeannos">@MRtnB</a> java.lang.String></spa\ n> <span class="element-name">nestedMtdParameterized</span>()</div>"""); @@ -226,7 +226,7 @@ interface in typeannos">@MRtnB</a> java.lang.String>,<wbr><a href="MRtnB.html ass="element-name">methodExtends</span>()</div>""", """ - <div class="member-signature"><span class="type-parameters-long"><K extends <\ + <div class="member-signature"><span class="type-parameters"><K extends <\ a href="MTyParamA.html" title="annotation interface in typeannos">@MTyParamA</a>\ <a href="MtdTyParameterized.html" title="class in typeannos">MtdTyParameterized\ </a><<a href="MTyParamB.html" title="annotation interface in typeannos">@MTyP\ @@ -242,8 +242,8 @@ ation interface in typeannos">@MTyParamA</a> java.lang.String></span> """ <div class="member-signature"><span class="modifiers">public final</span> <\ - span class="type-parameters-long"><K extends <a href="MTyParamA.html" title="\ - annotation interface in typeannos">@MTyParamA</a> java.lang.String,<wbr> + span class="type-parameters"><K extends <a href="MTyParamA.html" title="\ + annotation interface in typeannos">@MTyParamA</a> java.lang.String, \ V extends <a href="MTyParamA.html" title="annotation interface in typeannos">@MT\ yParamA</a> <a href="MtdTyParameterized.html" title="class in typeannos">MtdTyPa\ rameterized</a><<a href="MTyParamB.html" title="annotation interface in typea\ @@ -256,7 +256,7 @@ annotation interface in typeannos">@MTyParamA</a> java.lang.String,<wbr> <div class="member-signature"><span class="return-type">void</span> <span c\ lass="element-name">unannotated</span><wbr><span class="parameters">(<a href="Pa\ raParameterized.html" title="class in typeannos">ParaParameterized</a><java.l\ - ang.String,<wbr>java.lang.String> a)</span></div>""", + ang.String, java.lang.String> a)</span></div>""", """ <div class="member-signature"><span class="return-type">void</span> <span c\ @@ -265,8 +265,8 @@ annotation interface in typeannos">@MTyParamA</a> java.lang.String,<wbr> a><<a href="ParamA.html" title="annotation interface in typeannos">@ParamA</a\ > <a href="ParaParameterized.html" title="class in typeannos">ParaParameterized<\ /a><<a href="ParamA.html" title="annotation interface in typeannos">@ParamA</\ - a> java.lang.String,<wbr><a href="ParamB.html" title="annotation interface in ty\ - peannos">@ParamB</a> java.lang.String>,<wbr><a href="ParamB.html" title="anno\ + a> java.lang.String, <a href="ParamB.html" title="annotation interface in ty\ + peannos">@ParamB</a> java.lang.String>, <a href="ParamB.html" title="anno\ tation interface in typeannos">@ParamB</a> java.lang.String> a)</span></\ div>""", @@ -339,7 +339,7 @@ n interface in typeannos">@ThrB</a>("m") java.lang.RuntimeException, // Test for type annotations on type parameters (TypeParameters.java). checkOutput("typeannos/TestMethods.html", true, """ - <div class="member-signature"><span class="type-parameters"><K,<wbr> + <div class="member-signature"><span class="type-parameters"><K, \ <a href="TyParaA.html" title="annotation interface in typeannos">@TyParaA</a> V \ extends <a href="TyParaA.html" title="annotation interface in typeannos">@TyPara\ A</a> java.lang.String></span> diff --git a/test/langtools/jdk/javadoc/doclet/testTypeParams/TestTypeParameters.java b/test/langtools/jdk/javadoc/doclet/testTypeParams/TestTypeParameters.java index dad610acb30..1cf2f054775 100644 --- a/test/langtools/jdk/javadoc/doclet/testTypeParams/TestTypeParameters.java +++ b/test/langtools/jdk/javadoc/doclet/testTypeParams/TestTypeParameters.java @@ -56,8 +56,8 @@ public void test1() { checkOutput("pkg/C.html", true, """ - <div class="col-first odd-row-color method-summary-table method-summary-table-ta\ - b2 method-summary-table-tab4"><code><W extends java.lang.String,<wbr> + <div class="col-first odd-row-color method-summary-table method-summary-tab\ + le-tab2 method-summary-table-tab4"><code><W extends java.lang.String, \ V extends java.util.List><br>java.lang.Object</code></div>""", "<code><T> java.lang.Object</code>"); From a491564001724da07ecb7d2e4a070c4abbd92cf5 Mon Sep 17 00:00:00 2001 From: Nizar Benalla <nbenalla@openjdk.org> Date: Wed, 27 Nov 2024 15:36:26 +0000 Subject: [PATCH 282/311] 8342836: Automatically determine that a test in the docs test root is requested Reviewed-by: ihse, erikj --- make/Main.gmk | 6 +++++- make/MainSupport.gmk | 9 +++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/make/Main.gmk b/make/Main.gmk index 25dfba7d36c..152dbf17cd3 100644 --- a/make/Main.gmk +++ b/make/Main.gmk @@ -1344,9 +1344,13 @@ test-hotspot-jtreg-native: test-hotspot_native_sanity test-hotspot-gtest: exploded-test-gtest test-jdk-jtreg-native: test-jdk_native_sanity +# Set dependencies for doc tests +$(eval $(call AddTestDependency, docs_all, docs-jdk)) +test-docs: test-docs_all + ALL_TARGETS += $(RUN_TEST_TARGETS) run-test exploded-run-test check \ test-hotspot-jtreg test-hotspot-jtreg-native test-hotspot-gtest \ - test-jdk-jtreg-native + test-jdk-jtreg-native test-docs ################################################################################ ################################################################################ diff --git a/make/MainSupport.gmk b/make/MainSupport.gmk index f1027a9b888..ca284e21dd0 100644 --- a/make/MainSupport.gmk +++ b/make/MainSupport.gmk @@ -137,6 +137,15 @@ define CleanModule $(call Clean-include, $1) endef +define AddTestDependency + test-$(strip $1): $2 + + exploded-test-$(strip $1): $2 + + ifneq ($(filter $(TEST), $1), ) + TEST_DEPS += $2 + endif +endef ################################################################################ From 35bd2f354ea50ccda325ac0c0b7d2fe66692d940 Mon Sep 17 00:00:00 2001 From: Roger Riggs <rriggs@openjdk.org> Date: Wed, 27 Nov 2024 15:40:48 +0000 Subject: [PATCH 283/311] 8344555: SM cleanup - drop reflection filter of System.security field Reviewed-by: mullan, mchung, liach --- .../share/classes/jdk/internal/reflect/Reflection.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/java.base/share/classes/jdk/internal/reflect/Reflection.java b/src/java.base/share/classes/jdk/internal/reflect/Reflection.java index 88098b11942..6b211284b4e 100644 --- a/src/java.base/share/classes/jdk/internal/reflect/Reflection.java +++ b/src/java.base/share/classes/jdk/internal/reflect/Reflection.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2001, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -61,8 +61,7 @@ public class Reflection { Constructor.class, ALL_MEMBERS, Field.class, ALL_MEMBERS, Method.class, ALL_MEMBERS, - Module.class, ALL_MEMBERS, - System.class, Set.of("security") + Module.class, ALL_MEMBERS ); methodFilterMap = Map.of(); } From 75f3ec77e46831725ef927f0dda16a4dfd24b9a7 Mon Sep 17 00:00:00 2001 From: Volodymyr Paprotski <vpaprotski@openjdk.org> Date: Wed, 27 Nov 2024 16:05:43 +0000 Subject: [PATCH 284/311] 8344766: AES/CTR slow at big payloads Reviewed-by: ascarpino, jbhateja --- .../com/sun/crypto/provider/CounterMode.java | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/src/java.base/share/classes/com/sun/crypto/provider/CounterMode.java b/src/java.base/share/classes/com/sun/crypto/provider/CounterMode.java index 3f9c8bc4bda..cdf01d433cd 100644 --- a/src/java.base/share/classes/com/sun/crypto/provider/CounterMode.java +++ b/src/java.base/share/classes/com/sun/crypto/provider/CounterMode.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -53,6 +53,10 @@ class CounterMode extends FeedbackCipher { // number of bytes in encryptedCounter already used up private int used; + // chunkSize is a multiple of block size and used to divide up + // input data to trigger the intrinsic. + private final int chunkSize; + // variables for save/restore calls private byte[] counterSave = null; private byte[] encryptedCounterSave = null; @@ -62,6 +66,7 @@ class CounterMode extends FeedbackCipher { super(embeddedCipher); counter = new byte[blockSize]; encryptedCounter = new byte[blockSize]; + chunkSize = blockSize * 6400; } /** @@ -178,7 +183,17 @@ private int crypt(byte[] in, int inOff, int len, byte[] out, int outOff) { ArrayUtil.nullAndBoundsCheck(in, inOff, len); ArrayUtil.nullAndBoundsCheck(out, outOff, len); - return implCrypt(in, inOff, len, out, outOff); + + int processed = 0; + for (; len > chunkSize; inOff += chunkSize, outOff += chunkSize, + len -= chunkSize) { + processed += implCrypt(in, inOff, chunkSize, out, outOff); + } + // note: above loop always leaves some data to process (more than zero, + // less than or equal to chunkSize) so this last call can be + // unconditional + processed += implCrypt(in, inOff, len, out, outOff); + return processed; } // Implementation of crpyt() method. Possibly replaced with a compiler intrinsic. From 0312694c46b4fb3455cde2e4d1f8746ad4df8548 Mon Sep 17 00:00:00 2001 From: Brian Burkhalter <bpb@openjdk.org> Date: Wed, 27 Nov 2024 16:14:03 +0000 Subject: [PATCH 285/311] 8344882: (bf) Temporary direct buffers should not count against the upper limit on direct buffer memory Reviewed-by: alanb --- .../share/classes/java/nio/Buffer.java | 5 +++ .../java/nio/Direct-X-Buffer.java.template | 3 +- .../jdk/internal/access/JavaNioAccess.java | 5 +++ .../share/classes/sun/nio/ch/Util.java | 33 +++++++++++++++---- test/jdk/ProblemList-Virtual.txt | 3 -- 5 files changed, 38 insertions(+), 11 deletions(-) diff --git a/src/java.base/share/classes/java/nio/Buffer.java b/src/java.base/share/classes/java/nio/Buffer.java index 39e0ff642a4..c0c2cfe80e7 100644 --- a/src/java.base/share/classes/java/nio/Buffer.java +++ b/src/java.base/share/classes/java/nio/Buffer.java @@ -847,6 +847,11 @@ public ByteBuffer newHeapByteBuffer(byte[] hb, int offset, int capacity, MemoryS return new HeapByteBuffer(hb, -1, 0, capacity, capacity, offset, segment); } + @Override + public ByteBuffer newDirectByteBuffer(long addr, int cap) { + return new DirectByteBuffer(addr, cap); + } + @ForceInline @Override public Object getBufferBase(Buffer buffer) { diff --git a/src/java.base/share/classes/java/nio/Direct-X-Buffer.java.template b/src/java.base/share/classes/java/nio/Direct-X-Buffer.java.template index dac9abbf620..0da1dc66a9a 100644 --- a/src/java.base/share/classes/java/nio/Direct-X-Buffer.java.template +++ b/src/java.base/share/classes/java/nio/Direct-X-Buffer.java.template @@ -159,9 +159,10 @@ class Direct$Type$Buffer$RW$$BO$ } // Invoked only by JNI: NewDirectByteBuffer(void*, long) + // and JavaNioAccess.newDirectByteBuffer(int). // The long-valued capacity is restricted to int range. // - private Direct$Type$Buffer(long addr, long cap) { + Direct$Type$Buffer(long addr, long cap) { super(-1, 0, checkCapacity(cap), (int)cap, null); address = addr; cleaner = null; diff --git a/src/java.base/share/classes/jdk/internal/access/JavaNioAccess.java b/src/java.base/share/classes/jdk/internal/access/JavaNioAccess.java index f2d2b7b5b65..431ffbdab53 100644 --- a/src/java.base/share/classes/jdk/internal/access/JavaNioAccess.java +++ b/src/java.base/share/classes/jdk/internal/access/JavaNioAccess.java @@ -67,6 +67,11 @@ public interface JavaNioAccess { */ ByteBuffer newHeapByteBuffer(byte[] hb, int offset, int capacity, MemorySegment segment); + /** + * Used by {@code sun.nio.ch.Util}. + */ + ByteBuffer newDirectByteBuffer(long addr, int cap); + /** * Used by {@code jdk.internal.foreign.Utils}. */ diff --git a/src/java.base/share/classes/sun/nio/ch/Util.java b/src/java.base/share/classes/sun/nio/ch/Util.java index cf411008e43..24f1ee7d769 100644 --- a/src/java.base/share/classes/sun/nio/ch/Util.java +++ b/src/java.base/share/classes/sun/nio/ch/Util.java @@ -36,11 +36,15 @@ import java.util.Iterator; import java.util.Set; +import jdk.internal.access.JavaNioAccess; +import jdk.internal.access.SharedSecrets; import jdk.internal.misc.TerminatingThreadLocal; import jdk.internal.misc.Unsafe; public class Util { + private static final JavaNioAccess NIO_ACCESS = SharedSecrets.getJavaNioAccess(); + // -- Caches -- // The number of temp buffers in our pool @@ -221,7 +225,8 @@ public static ByteBuffer getTemporaryDirectBuffer(int size) { // to remove the buffer from the cache (as this method does // below) given that we won't put the new buffer in the cache. if (isBufferTooLarge(size)) { - return ByteBuffer.allocateDirect(size); + long addr = unsafe.allocateMemory(size); + return NIO_ACCESS.newDirectByteBuffer(addr, size); } BufferCache cache = bufferCache.get(); @@ -236,7 +241,8 @@ public static ByteBuffer getTemporaryDirectBuffer(int size) { buf = cache.removeFirst(); free(buf); } - return ByteBuffer.allocateDirect(size); + long addr = unsafe.allocateMemory(size); + return NIO_ACCESS.newDirectByteBuffer(addr, size); } } @@ -247,8 +253,8 @@ public static ByteBuffer getTemporaryDirectBuffer(int size) { public static ByteBuffer getTemporaryAlignedDirectBuffer(int size, int alignment) { if (isBufferTooLarge(size)) { - return ByteBuffer.allocateDirect(size + alignment - 1) - .alignedSlice(alignment); + return getTemporaryDirectBuffer(size + alignment - 1) + .alignedSlice(alignment); } BufferCache cache = bufferCache.get(); @@ -263,8 +269,8 @@ public static ByteBuffer getTemporaryAlignedDirectBuffer(int size, free(buf); } } - return ByteBuffer.allocateDirect(size + alignment - 1) - .alignedSlice(alignment); + return getTemporaryDirectBuffer(size + alignment - 1) + .alignedSlice(alignment); } /** @@ -274,12 +280,23 @@ public static void releaseTemporaryDirectBuffer(ByteBuffer buf) { offerFirstTemporaryDirectBuffer(buf); } + /** + * Return the underling byte buffer if the given byte buffer is + * an aligned slice. + */ + private static ByteBuffer unwrapIfAlignedSlice(ByteBuffer buf) { + var parent = (ByteBuffer) ((DirectBuffer) buf).attachment(); + return (parent != null) ? parent : buf; + } + /** * Releases a temporary buffer by returning to the cache or freeing it. If * returning to the cache then insert it at the start so that it is * likely to be returned by a subsequent call to getTemporaryDirectBuffer. */ static void offerFirstTemporaryDirectBuffer(ByteBuffer buf) { + buf = unwrapIfAlignedSlice(buf); + // If the buffer is too large for the cache we don't have to // check the cache. We'll just free it. if (isBufferTooLarge(buf)) { @@ -302,6 +319,8 @@ static void offerFirstTemporaryDirectBuffer(ByteBuffer buf) { * cache in same order that they were obtained. */ static void offerLastTemporaryDirectBuffer(ByteBuffer buf) { + buf = unwrapIfAlignedSlice(buf); + // If the buffer is too large for the cache we don't have to // check the cache. We'll just free it. if (isBufferTooLarge(buf)) { @@ -321,7 +340,7 @@ static void offerLastTemporaryDirectBuffer(ByteBuffer buf) { * Frees the memory for the given direct buffer */ private static void free(ByteBuffer buf) { - ((DirectBuffer)buf).cleaner().clean(); + unsafe.freeMemory(((DirectBuffer)buf).address()); } diff --git a/test/jdk/ProblemList-Virtual.txt b/test/jdk/ProblemList-Virtual.txt index b97e444ab36..d7692b578cd 100644 --- a/test/jdk/ProblemList-Virtual.txt +++ b/test/jdk/ProblemList-Virtual.txt @@ -69,6 +69,3 @@ java/util/Properties/StoreReproducibilityTest.java 0000000 generic-all java/util/Properties/StoreReproducibilityTest.java 0000000 generic-all javax/management/ImplementationVersion/ImplVersionTest.java 0000000 generic-all javax/management/remote/mandatory/version/ImplVersionTest.java 0000000 generic-all - -# Direct buffer memory allocated before test launch -java/nio/Buffer/LimitDirectMemory.java 8342849 generic-all From 1e3a0fdb5d14550de66faa8472c883a9990a87df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonathan=20Lamp=C3=A9rth?= <jonathan.lamperth@oracle.com> Date: Wed, 27 Nov 2024 17:31:39 +0000 Subject: [PATCH 286/311] 8035271: Incorrect indentation of LineNumberTable/LocalVariableTable/Exception table/LocalVariableTypeTable/StackMapTable/RuntimeVisibleTypeAnnotations in verbose mode Reviewed-by: liach, jvernee --- .../com/sun/tools/javap/ClassWriter.java | 9 +- .../com/sun/tools/javap/CodeWriter.java | 39 ++++-- .../javap/ClassWriterTableIndentTest.java | 123 ++++++++++++++++++ 3 files changed, 153 insertions(+), 18 deletions(-) create mode 100644 test/langtools/tools/javap/ClassWriterTableIndentTest.java diff --git a/src/jdk.jdeps/share/classes/com/sun/tools/javap/ClassWriter.java b/src/jdk.jdeps/share/classes/com/sun/tools/javap/ClassWriter.java index 92a0c06c1c3..2dbc411dd6e 100644 --- a/src/jdk.jdeps/share/classes/com/sun/tools/javap/ClassWriter.java +++ b/src/jdk.jdeps/share/classes/com/sun/tools/javap/ClassWriter.java @@ -575,16 +575,9 @@ protected void writeMethod(MethodModel m) { if (options.showAllAttrs) { attrWriter.write(m.attributes()); } else if (code != null) { - if (options.showDisassembled) { + if (options.showDisassembled || options.showLineAndLocalVariableTables) { codeWriter.writeMinimal(code); } - - if (options.showLineAndLocalVariableTables) { - code.findAttribute(Attributes.lineNumberTable()) - .ifPresent(a -> attrWriter.write(a, code)); - code.findAttribute(Attributes.localVariableTable()) - .ifPresent(a -> attrWriter.write(a, code)); - } } indent(-1); diff --git a/src/jdk.jdeps/share/classes/com/sun/tools/javap/CodeWriter.java b/src/jdk.jdeps/share/classes/com/sun/tools/javap/CodeWriter.java index cb401c9f197..99d7e2c2686 100644 --- a/src/jdk.jdeps/share/classes/com/sun/tools/javap/CodeWriter.java +++ b/src/jdk.jdeps/share/classes/com/sun/tools/javap/CodeWriter.java @@ -25,16 +25,13 @@ package com.sun.tools.javap; +import java.lang.classfile.*; import java.util.ArrayList; import java.util.List; import java.util.Locale; import java.util.stream.Collectors; -import java.lang.classfile.ClassFile; -import java.lang.classfile.Opcode; import java.lang.classfile.constantpool.*; -import java.lang.classfile.Instruction; -import java.lang.classfile.MethodModel; import java.lang.classfile.attribute.CodeAttribute; import java.lang.classfile.instruction.*; @@ -260,15 +257,37 @@ private List<InstructionDetailWriter> getDetailWriters(CodeAttribute attr) { private void writeInternal(CodeAttribute attr, boolean minimal) { println("Code:"); indent(+1); - if (!minimal) { - writeVerboseHeader(attr); + if (minimal) { + writeMinimalMode(attr); + } else { + writeVerboseMode(attr); } + indent(-1); + } + + private void writeMinimalMode(CodeAttribute attr) { + if (options.showDisassembled) { + writeInstrs(attr); + writeExceptionTable(attr); + } + + if (options.showLineAndLocalVariableTables) { + writeLineAndLocalVariableTables(attr); + } + } + + private void writeVerboseMode(CodeAttribute attr) { + writeVerboseHeader(attr); writeInstrs(attr); writeExceptionTable(attr); - if (!minimal) { - attrWriter.write(attr.attributes(), attr); - } - indent(-1); + attrWriter.write(attr.attributes(), attr); + } + + private void writeLineAndLocalVariableTables(CodeAttribute attr) { + attr.findAttribute(Attributes.lineNumberTable()) + .ifPresent(a -> attrWriter.write(a, attr)); + attr.findAttribute(Attributes.localVariableTable()) + .ifPresent(a -> attrWriter.write(a, attr)); } private AttributeWriter attrWriter; diff --git a/test/langtools/tools/javap/ClassWriterTableIndentTest.java b/test/langtools/tools/javap/ClassWriterTableIndentTest.java new file mode 100644 index 00000000000..f4f4c23c826 --- /dev/null +++ b/test/langtools/tools/javap/ClassWriterTableIndentTest.java @@ -0,0 +1,123 @@ +/* + * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + * @test + * @bug 8035271 + * @summary javap incorrect indentation when LineNumberTable and LocalVariableTable written via ClassWriter + * @run main ClassWriterTableIndentTest + * @modules jdk.jdeps/com.sun.tools.javap + */ + +import java.io.PrintWriter; +import java.io.StringWriter; +import java.util.Arrays; +import java.util.List; + +public class ClassWriterTableIndentTest { + public static void main(String[] args) { + new ClassWriterTableIndentTest().run(); + } + + public void run() { + /* + * Partial expected output within a larger file. There exists another "Code: " section above, and thus we + * select the second occurrence in `findNthMatchPrecedingSpaces(output, "Code:", 1);` + * ... + * public void emptyLoop(); + * Code: + * ... + * LineNumberTable: + * line 143: 0 + * line 145: 14 + * ... + */ + List<String[]> runArgsList = List.of(new String[]{"-c", "-l"}, new String[]{"-v"}, new String[]{"-l"}); + for (String[] runArgs : runArgsList) { + String output = javap(runArgs); + int methodIntent = findNthMatchPrecedingSpaces(output, "public void emptyLoop();", 0); + int codeHeaderIndent = findNthMatchPrecedingSpaces(output, "Code:", 1); + int detailIndent = findNthMatchPrecedingSpaces(output, "LineNumberTable:", 1); + + if (codeHeaderIndent - methodIntent != 2) { + indentError(2, codeHeaderIndent - methodIntent, "Code block", "method header", runArgs); + } + + if (detailIndent - codeHeaderIndent != 2) { + indentError(2, detailIndent - codeHeaderIndent, "LineNumberTable", "code header", runArgs); + } + + if (detailIndent - methodIntent != 4) { + indentError(4, detailIndent - methodIntent, "LineNumberTable", "method header"); + } + } + if (errors > 0) { + throw new Error(errors + " found."); + } + } + + private String javap(String... args) { + StringWriter sw = new StringWriter(); + PrintWriter out = new PrintWriter(sw); + + String[] fullArgs = new String[args.length + 1]; + System.arraycopy(args, 0, fullArgs, 0, args.length); + fullArgs[args.length] = System.getProperty("test.classes") + "/EmptyLoop8035271.class"; + + int rc = com.sun.tools.javap.Main.run(fullArgs, out); + if (rc != 0) + throw new Error("javap failed. rc=" + rc); + out.close(); + System.out.println(sw); + return sw.toString(); + } + + public static int findNthMatchPrecedingSpaces(String inputString, String searchString, int occurrence) { + String[] lines = inputString.split(System.lineSeparator()); + int count = 0; + for (String line : lines) { + if (line.trim().startsWith(searchString)) { + if (count == occurrence) { + return line.indexOf(searchString); + } + count++; + } + } + throw new IllegalArgumentException("Could not find " + searchString + " in " + inputString); + } + + void indentError(int expected, int actual, String toCompare, String referencePoint, String... args) { + System.err.println(toCompare + " is not indented correctly with respect to " + referencePoint + ". Expected " + + expected + " but got " + actual + " for args: " + Arrays.toString(args)); + errors++; + } + + int errors; +} + +class EmptyLoop8035271 { + public void emptyLoop() { + for (int i = 0; i < 10; i++) { + } + } +} \ No newline at end of file From 9527586923d1e7d47d06456ed100a3d123e7a6d2 Mon Sep 17 00:00:00 2001 From: Phil Race <prr@openjdk.org> Date: Wed, 27 Nov 2024 17:32:54 +0000 Subject: [PATCH 287/311] 8345073: Remove SecurityManager checks from sun.awt.image classes Reviewed-by: azvegint, honkar --- .../sun/awt/image/ByteArrayImageSource.java | 7 --- .../sun/awt/image/FileImageSource.java | 11 ----- .../sun/awt/image/ImageConsumerQueue.java | 14 +----- .../classes/sun/awt/image/ImageFetcher.java | 40 +++++++---------- .../sun/awt/image/ImageRepresentation.java | 45 ------------------- .../sun/awt/image/InputStreamImageSource.java | 29 ------------ .../classes/sun/awt/image/ToolkitImage.java | 33 -------------- .../classes/sun/awt/image/URLImageSource.java | 25 +---------- 8 files changed, 19 insertions(+), 185 deletions(-) diff --git a/src/java.desktop/share/classes/sun/awt/image/ByteArrayImageSource.java b/src/java.desktop/share/classes/sun/awt/image/ByteArrayImageSource.java index f1beb74b2a5..ec7efe8ad70 100644 --- a/src/java.desktop/share/classes/sun/awt/image/ByteArrayImageSource.java +++ b/src/java.desktop/share/classes/sun/awt/image/ByteArrayImageSource.java @@ -43,13 +43,6 @@ public ByteArrayImageSource(byte[] data, int offset, int length) { imagelength = length; } - final boolean checkSecurity(Object context, boolean quiet) { - // No need to check security. Applets and downloaded code can - // only make byte array image once they already have a handle - // on the image data anyway... - return true; - } - protected ImageDecoder getDecoder() { InputStream is = new ByteArrayInputStream(imagedata, imageoffset, imagelength); diff --git a/src/java.desktop/share/classes/sun/awt/image/FileImageSource.java b/src/java.desktop/share/classes/sun/awt/image/FileImageSource.java index e0ec54ab36d..0f4dbff8aac 100644 --- a/src/java.desktop/share/classes/sun/awt/image/FileImageSource.java +++ b/src/java.desktop/share/classes/sun/awt/image/FileImageSource.java @@ -34,20 +34,9 @@ public class FileImageSource extends InputStreamImageSource { String imagefile; public FileImageSource(String filename) { - @SuppressWarnings("removal") - SecurityManager security = System.getSecurityManager(); - if (security != null) { - security.checkRead(filename); - } imagefile = filename; } - final boolean checkSecurity(Object context, boolean quiet) { - // File based images only ever need to be checked statically - // when the image is retrieved from the cache. - return true; - } - protected ImageDecoder getDecoder() { if (imagefile == null) { return null; diff --git a/src/java.desktop/share/classes/sun/awt/image/ImageConsumerQueue.java b/src/java.desktop/share/classes/sun/awt/image/ImageConsumerQueue.java index 0b910868501..e945a9b2b9e 100644 --- a/src/java.desktop/share/classes/sun/awt/image/ImageConsumerQueue.java +++ b/src/java.desktop/share/classes/sun/awt/image/ImageConsumerQueue.java @@ -33,8 +33,6 @@ class ImageConsumerQueue { ImageConsumer consumer; boolean interested; - Object securityContext; - boolean secure; static ImageConsumerQueue removeConsumer(ImageConsumerQueue cqbase, ImageConsumer ic, @@ -68,28 +66,18 @@ static boolean isConsumer(ImageConsumerQueue cqbase, ImageConsumer ic) { ImageConsumerQueue(InputStreamImageSource src, ImageConsumer ic) { consumer = ic; interested = true; - // ImageReps do their own security at access time. + // Leaving this code throwing SecurityException for compatibility if (ic instanceof ImageRepresentation) { ImageRepresentation ir = (ImageRepresentation) ic; if (ir.image.source != src) { throw new SecurityException("ImageRep added to wrong image source"); } - secure = true; - } else { - @SuppressWarnings("removal") - SecurityManager security = System.getSecurityManager(); - if (security != null) { - securityContext = security.getSecurityContext(); - } else { - securityContext = null; - } } } public String toString() { return ("[" + consumer + ", " + (interested ? "" : "not ") + "interested" + - (securityContext != null ? ", " + securityContext : "") + "]"); } } diff --git a/src/java.desktop/share/classes/sun/awt/image/ImageFetcher.java b/src/java.desktop/share/classes/sun/awt/image/ImageFetcher.java index 88e830a2bf5..784f947b8aa 100644 --- a/src/java.desktop/share/classes/sun/awt/image/ImageFetcher.java +++ b/src/java.desktop/share/classes/sun/awt/image/ImageFetcher.java @@ -283,29 +283,23 @@ private static void createFetchers(final FetcherInfo info) { final AppContext appContext = AppContext.getAppContext(); ThreadGroup threadGroup = appContext.getThreadGroup(); ThreadGroup fetcherThreadGroup; - try { - if (threadGroup.getParent() != null) { - // threadGroup is not the root, so we proceed - fetcherThreadGroup = threadGroup; - } else { - // threadGroup is the root ("system") ThreadGroup. - // We instead want to use its child: the "main" - // ThreadGroup. Thus, we start with the current - // ThreadGroup, and go up the tree until - // threadGroup.getParent().getParent() == null. - threadGroup = Thread.currentThread().getThreadGroup(); - ThreadGroup parent = threadGroup.getParent(); - while ((parent != null) - && (parent.getParent() != null)) { - threadGroup = parent; - parent = threadGroup.getParent(); - } - fetcherThreadGroup = threadGroup; - } - } catch (SecurityException e) { - // Not allowed access to parent ThreadGroup -- just use - // the AppContext's ThreadGroup - fetcherThreadGroup = appContext.getThreadGroup(); + if (threadGroup.getParent() != null) { + // threadGroup is not the root, so we proceed + fetcherThreadGroup = threadGroup; + } else { + // threadGroup is the root ("system") ThreadGroup. + // We instead want to use its child: the "main" + // ThreadGroup. Thus, we start with the current + // ThreadGroup, and go up the tree until + // threadGroup.getParent().getParent() == null. + threadGroup = Thread.currentThread().getThreadGroup(); + ThreadGroup parent = threadGroup.getParent(); + while ((parent != null) + && (parent.getParent() != null)) { + threadGroup = parent; + parent = threadGroup.getParent(); + } + fetcherThreadGroup = threadGroup; } final ThreadGroup fetcherGroup = fetcherThreadGroup; diff --git a/src/java.desktop/share/classes/sun/awt/image/ImageRepresentation.java b/src/java.desktop/share/classes/sun/awt/image/ImageRepresentation.java index 0d08f7ab2e9..685455acccd 100644 --- a/src/java.desktop/share/classes/sun/awt/image/ImageRepresentation.java +++ b/src/java.desktop/share/classes/sun/awt/image/ImageRepresentation.java @@ -101,9 +101,6 @@ public ImageRepresentation(ToolkitImage im, ColorModel cmodel, boolean /* REMIND: Only used for Frame.setIcon - should use ImageWatcher instead */ public synchronized void reconstruct(int flags) { - if (src != null) { - src.checkSecurity(null, false); - } int missinginfo = flags & ~availinfo; if ((availinfo & ImageObserver.ERROR) == 0 && missinginfo != 0) { numWaiters++; @@ -128,9 +125,6 @@ public synchronized void reconstruct(int flags) { } public void setDimensions(int w, int h) { - if (src != null) { - src.checkSecurity(null, false); - } image.setDimensions(w, h); @@ -190,17 +184,11 @@ protected BufferedImage createImage(ColorModel cm, } public void setProperties(Hashtable<?,?> props) { - if (src != null) { - src.checkSecurity(null, false); - } image.setProperties(props); newInfo(image, ImageObserver.PROPERTIES, 0, 0, 0, 0); } public void setColorModel(ColorModel model) { - if (src != null) { - src.checkSecurity(null, false); - } srcModel = model; // Check to see if model is INT_RGB @@ -323,9 +311,6 @@ private void convertToRGB() { } public void setHints(int h) { - if (src != null) { - src.checkSecurity(null, false); - } hints = h; } @@ -345,10 +330,6 @@ public void setPixels(int x, int y, int w, int h, int poff; int[] newLUT=null; - if (src != null) { - src.checkSecurity(null, false); - } - // REMIND: What if the model doesn't fit in default color model? synchronized (this) { if (bimage == null) { @@ -542,10 +523,6 @@ public void setPixels(int x, int y, int w, int h, ColorModel model, int lineOff=off; int poff; - if (src != null) { - src.checkSecurity(null, false); - } - // REMIND: What if the model doesn't fit in default color model? synchronized (this) { if (bimage == null) { @@ -677,9 +654,6 @@ public BufferedImage getOpaqueRGBImage() { private boolean consuming = false; public void imageComplete(int status) { - if (src != null) { - src.checkSecurity(null, false); - } boolean done; int info; switch (status) { @@ -749,9 +723,6 @@ private synchronized void decrementWaiters() { } public boolean prepare(ImageObserver iw) { - if (src != null) { - src.checkSecurity(null, false); - } if ((availinfo & ImageObserver.ERROR) != 0) { if (iw != null) { iw.imageUpdate(image, ImageObserver.ERROR|ImageObserver.ABORT, @@ -770,10 +741,6 @@ public boolean prepare(ImageObserver iw) { } public int check(ImageObserver iw) { - - if (src != null) { - src.checkSecurity(null, false); - } if ((availinfo & (ImageObserver.ERROR | ImageObserver.ALLBITS)) == 0) { addWatcher(iw); } @@ -785,9 +752,6 @@ public boolean drawToBufImage(Graphics g, ToolkitImage img, int x, int y, Color bg, ImageObserver iw) { - if (src != null) { - src.checkSecurity(null, false); - } if ((availinfo & ImageObserver.ERROR) != 0) { if (iw != null) { iw.imageUpdate(image, ImageObserver.ERROR|ImageObserver.ABORT, @@ -816,9 +780,6 @@ public boolean drawToBufImage(Graphics g, ToolkitImage img, int x, int y, int w, int h, Color bg, ImageObserver iw) { - if (src != null) { - src.checkSecurity(null, false); - } if ((availinfo & ImageObserver.ERROR) != 0) { if (iw != null) { iw.imageUpdate(image, ImageObserver.ERROR|ImageObserver.ABORT, @@ -849,9 +810,6 @@ public boolean drawToBufImage(Graphics g, ToolkitImage img, int sx1, int sy1, int sx2, int sy2, Color bg, ImageObserver iw) { - if (src != null) { - src.checkSecurity(null, false); - } if ((availinfo & ImageObserver.ERROR) != 0) { if (iw != null) { iw.imageUpdate(image, ImageObserver.ERROR|ImageObserver.ABORT, @@ -885,9 +843,6 @@ public boolean drawToBufImage(Graphics g, ToolkitImage img, { Graphics2D g2 = (Graphics2D) g; - if (src != null) { - src.checkSecurity(null, false); - } if ((availinfo & ImageObserver.ERROR) != 0) { if (iw != null) { iw.imageUpdate(image, ImageObserver.ERROR|ImageObserver.ABORT, diff --git a/src/java.desktop/share/classes/sun/awt/image/InputStreamImageSource.java b/src/java.desktop/share/classes/sun/awt/image/InputStreamImageSource.java index 1873b4b3707..5c672c66098 100644 --- a/src/java.desktop/share/classes/sun/awt/image/InputStreamImageSource.java +++ b/src/java.desktop/share/classes/sun/awt/image/InputStreamImageSource.java @@ -40,8 +40,6 @@ public abstract class InputStreamImageSource implements ImageProducer, boolean awaitingFetch = false; - abstract boolean checkSecurity(Object context, boolean quiet); - int countConsumers(ImageConsumerQueue cq) { int i = 0; while (cq != null) { @@ -83,7 +81,6 @@ synchronized void printQueues(String title) { } synchronized void addConsumer(ImageConsumer ic, boolean produce) { - checkSecurity(null, false); for (ImageDecoder id = decoders; id != null; id = id.next) { if (id.isConsumer(ic)) { // This consumer is already being fed. @@ -99,25 +96,6 @@ synchronized void addConsumer(ImageConsumer ic, boolean produce) { cq.next = consumers; consumers = cq; } else { - if (!cq.secure) { - Object context = null; - @SuppressWarnings("removal") - SecurityManager security = System.getSecurityManager(); - if (security != null) { - context = security.getSecurityContext(); - } - if (cq.securityContext == null) { - cq.securityContext = context; - } else if (!cq.securityContext.equals(context)) { - // If there are two different security contexts that both - // have a handle on the same ImageConsumer, then there has - // been a security breach and whether or not they trade - // image data is small fish compared to what they could be - // trading. Throw a Security exception anyway... - errorConsumer(cq, false); - throw new SecurityException("Applets are trading image data!"); - } - } cq.interested = true; } if (produce && decoder == null) { @@ -303,13 +281,6 @@ private void setDecoder(ImageDecoder mydecoder) { awaitingFetch = false; } while (cq != null) { - if (cq.interested) { - // Now that there is a decoder, security may have changed - // so reverify it here, just in case. - if (!checkSecurity(cq.securityContext, true)) { - errorConsumer(cq, false); - } - } cq = cq.next; } } diff --git a/src/java.desktop/share/classes/sun/awt/image/ToolkitImage.java b/src/java.desktop/share/classes/sun/awt/image/ToolkitImage.java index b1f5873f106..0192a822095 100644 --- a/src/java.desktop/share/classes/sun/awt/image/ToolkitImage.java +++ b/src/java.desktop/share/classes/sun/awt/image/ToolkitImage.java @@ -71,9 +71,6 @@ public ToolkitImage(ImageProducer is) { } public ImageProducer getSource() { - if (src != null) { - src.checkSecurity(null, false); - } return source; } @@ -88,9 +85,6 @@ public ImageProducer getSource() { * If the width isn't known, then the image is reconstructed. */ public int getWidth() { - if (src != null) { - src.checkSecurity(null, false); - } if ((availinfo & ImageObserver.WIDTH) == 0) { reconstruct(ImageObserver.WIDTH); } @@ -103,9 +97,6 @@ public int getWidth() { * notified when the data is available. */ public synchronized int getWidth(ImageObserver iw) { - if (src != null) { - src.checkSecurity(null, false); - } if ((availinfo & ImageObserver.WIDTH) == 0) { addWatcher(iw, true); if ((availinfo & ImageObserver.WIDTH) == 0) { @@ -120,9 +111,6 @@ public synchronized int getWidth(ImageObserver iw) { * If the height isn't known, then the image is reconstructed. */ public int getHeight() { - if (src != null) { - src.checkSecurity(null, false); - } if ((availinfo & ImageObserver.HEIGHT) == 0) { reconstruct(ImageObserver.HEIGHT); } @@ -135,9 +123,6 @@ public int getHeight() { * notified when the data is available. */ public synchronized int getHeight(ImageObserver iw) { - if (src != null) { - src.checkSecurity(null, false); - } if ((availinfo & ImageObserver.HEIGHT) == 0) { addWatcher(iw, true); if ((availinfo & ImageObserver.HEIGHT) == 0) { @@ -162,9 +147,6 @@ public Object getProperty(String name, ImageObserver observer) { throw new NullPointerException("null property name is not allowed"); } - if (src != null) { - src.checkSecurity(null, false); - } if (properties == null) { addWatcher(observer, true); if (properties == null) { @@ -179,16 +161,10 @@ public Object getProperty(String name, ImageObserver observer) { } public boolean hasError() { - if (src != null) { - src.checkSecurity(null, false); - } return (availinfo & ImageObserver.ERROR) != 0; } public int check(ImageObserver iw) { - if (src != null) { - src.checkSecurity(null, false); - } if ((availinfo & ImageObserver.ERROR) == 0 && ((~availinfo) & (ImageObserver.WIDTH | ImageObserver.HEIGHT | @@ -199,9 +175,6 @@ public int check(ImageObserver iw) { } public void preload(ImageObserver iw) { - if (src != null) { - src.checkSecurity(null, false); - } if ((availinfo & ImageObserver.ALLBITS) == 0) { addWatcher(iw, true); } @@ -273,9 +246,6 @@ synchronized void infoDone(int status) { } public void flush() { - if (src != null) { - src.checkSecurity(null, false); - } ImageRepresentation ir; synchronized (this) { @@ -297,9 +267,6 @@ protected ImageRepresentation makeImageRep() { } public synchronized ImageRepresentation getImageRep() { - if (src != null) { - src.checkSecurity(null, false); - } if (imagerep == null) { imagerep = makeImageRep(); } diff --git a/src/java.desktop/share/classes/sun/awt/image/URLImageSource.java b/src/java.desktop/share/classes/sun/awt/image/URLImageSource.java index 93d339e3fe1..ad9caff8639 100644 --- a/src/java.desktop/share/classes/sun/awt/image/URLImageSource.java +++ b/src/java.desktop/share/classes/sun/awt/image/URLImageSource.java @@ -55,30 +55,6 @@ public URLImageSource(URLConnection uc) { this(uc.getURL(), uc); } - final boolean checkSecurity(Object context, boolean quiet) { - // If actualHost is not null, then the host/port parameters that - // the image was actually fetched from were different than the - // host/port parameters the original URL specified for at least - // one of the download attempts. The original URL security was - // checked when the applet got a handle to the image, so we only - // need to check for the real host/port. - if (actualHost != null) { - try { - @SuppressWarnings("removal") - SecurityManager security = System.getSecurityManager(); - if (security != null) { - security.checkConnect(actualHost, actualPort, context); - } - } catch (SecurityException e) { - if (!quiet) { - throw e; - } - return false; - } - } - return true; - } - private synchronized URLConnection getConnection() throws IOException { URLConnection c; if (conn != null) { @@ -106,6 +82,7 @@ protected ImageDecoder getDecoder() { // listed in the original URL, or it can come from one other // host/port that the URL is redirected to. More than that // and we give up and just throw a SecurityException. + // This is not directly related to SecurityManager so keep it. if (actualHost != null && (!actualHost.equals(u.getHost()) || actualPort != u.getPort())) { From 880f9a7b161fc5092ece8cfe02b5c55c32baba36 Mon Sep 17 00:00:00 2001 From: Aleksei Efimov <aefimov@openjdk.org> Date: Wed, 27 Nov 2024 19:25:50 +0000 Subject: [PATCH 288/311] 8344220: Remove calls to SecurityManager and doPrivileged in java.net.InetAddress and sun.net.util.IPAddressUtil after JEP 486 integration Reviewed-by: jpai, dfuchs, alanb --- .../share/classes/java/net/InetAddress.java | 144 ++++-------------- .../classes/java/net/SocketPermission.java | 37 ++--- .../java/net/doc-files/net-properties.html | 3 +- .../net/spi/InetAddressResolverProvider.java | 22 --- .../sun/net/InetAddressCachePolicy.java | 140 +++-------------- .../classes/sun/net/util/IPAddressUtil.java | 32 ++-- 6 files changed, 84 insertions(+), 294 deletions(-) diff --git a/src/java.base/share/classes/java/net/InetAddress.java b/src/java.base/share/classes/java/net/InetAddress.java index 746ce04e8a2..e94df5a9e0a 100644 --- a/src/java.base/share/classes/java/net/InetAddress.java +++ b/src/java.base/share/classes/java/net/InetAddress.java @@ -28,8 +28,6 @@ import java.net.spi.InetAddressResolver; import java.net.spi.InetAddressResolverProvider; import java.net.spi.InetAddressResolver.LookupPolicy; -import java.security.AccessController; -import java.security.PrivilegedAction; import java.util.List; import java.util.NavigableSet; import java.util.ArrayList; @@ -62,7 +60,6 @@ import jdk.internal.misc.VM; import jdk.internal.vm.annotation.Stable; import sun.net.ResolverProviderConfiguration; -import sun.security.action.*; import sun.net.InetAddressCachePolicy; import sun.net.util.IPAddressUtil; import sun.nio.cs.UTF_8; @@ -364,11 +361,11 @@ InetAddressHolder holder() { */ static { PREFER_IPV4_STACK_VALUE = - GetPropertyAction.privilegedGetProperty("java.net.preferIPv4Stack"); + System.getProperty("java.net.preferIPv4Stack"); PREFER_IPV6_ADDRESSES_VALUE = - GetPropertyAction.privilegedGetProperty("java.net.preferIPv6Addresses"); + System.getProperty("java.net.preferIPv6Addresses"); HOSTS_FILE_NAME = - GetPropertyAction.privilegedGetProperty("jdk.net.hosts.file"); + System.getProperty("jdk.net.hosts.file"); jdk.internal.loader.BootLoader.loadLibrary("net"); SharedSecrets.setJavaNetInetAddressAccess( new JavaNetInetAddressAccess() { @@ -440,19 +437,9 @@ static boolean ipv6AddressesFirst(int lookupCharacteristics) { // Native method to check if IPv6 is available private static native boolean isIPv6Supported(); - /** - * The {@code RuntimePermission("inetAddressResolverProvider")} is - * necessary to subclass and instantiate the {@code InetAddressResolverProvider} - * class, as well as to obtain resolver from an instance of that class, - * and it is also required to obtain the operating system name resolution configurations. - */ - private static final RuntimePermission INET_ADDRESS_RESOLVER_PERMISSION = - new RuntimePermission("inetAddressResolverProvider"); - private static final ReentrantLock RESOLVER_LOCK = new ReentrantLock(); private static volatile InetAddressResolver bootstrapResolver; - @SuppressWarnings("removal") private static InetAddressResolver resolver() { InetAddressResolver cns = resolver; if (cns != null) { @@ -476,10 +463,6 @@ private static InetAddressResolver resolver() { if (HOSTS_FILE_NAME != null) { // The default resolver service is already host file resolver cns = BUILTIN_RESOLVER; - } else if (System.getSecurityManager() != null) { - PrivilegedAction<InetAddressResolver> pa = InetAddress::loadResolver; - cns = AccessController.doPrivileged( - pa, null, INET_ADDRESS_RESOLVER_PERMISSION); } else { cns = loadResolver(); } @@ -737,25 +720,8 @@ public boolean isReachable(NetworkInterface netif, int ttl, * @see InetAddress#getCanonicalHostName */ public String getHostName() { - return getHostName(true); - } - - /** - * Returns the hostname for this address. - * If the host is equal to null, then this address refers to any - * of the local machine's available network addresses. - * this is package private so SocketPermission can make calls into - * here without a security check. - * - * @return the host name for this IP address, or if the operation - * is not allowed by the security check, the textual - * representation of the IP address. - * - * @param check make security check if true - */ - String getHostName(boolean check) { if (holder().getHostName() == null) { - holder().hostName = InetAddress.getHostFromNameService(this, check); + holder().hostName = InetAddress.getHostFromNameService(this); } return holder().getHostName(); } @@ -782,45 +748,31 @@ public String getCanonicalHostName() { String value = canonicalHostName; if (value == null) canonicalHostName = value = - InetAddress.getHostFromNameService(this, true); + InetAddress.getHostFromNameService(this); return value; } /** * Returns the fully qualified domain name for the given address. * - * @param check make security check if true - * * @return the fully qualified domain name for the given IP address. - * If either the operation is not allowed by the security check - * or the system-wide resolver wasn't able to determine the + * If the system-wide resolver wasn't able to determine the * fully qualified domain name for the IP address, the textual * representation of the IP address is returned instead. */ - private static String getHostFromNameService(InetAddress addr, boolean check) { + private static String getHostFromNameService(InetAddress addr) { String host; var resolver = resolver(); try { // first lookup the hostname host = resolver.lookupByAddress(addr.getAddress()); - /* check to see if calling code is allowed to know - * the hostname for this IP address, ie, connect to the host - */ - if (check) { - @SuppressWarnings("removal") - SecurityManager sec = System.getSecurityManager(); - if (sec != null) { - sec.checkConnect(host, -1); - } - } - /* now get all the IP addresses for this hostname, * and make sure one of them matches the original IP * address. We do this to try and prevent spoofing. */ - InetAddress[] arr = InetAddress.getAllByName0(host, check); + InetAddress[] arr = InetAddress.getAllByName0(host); boolean ok = false; if (arr != null) { @@ -1613,7 +1565,7 @@ public static InetAddress[] getAllByName(String host) // and ends with square brackets, but we got something else. throw invalidIPv6LiteralException(host, true); } - return getAllByName0(host, true, true); + return getAllByName0(host, true); } private static UnknownHostException invalidIPv6LiteralException(String host, boolean wrapInBrackets) { @@ -1639,9 +1591,8 @@ public static InetAddress getLoopbackAddress() { /** * package private so SocketPermission can call it */ - static InetAddress[] getAllByName0 (String host, boolean check) - throws UnknownHostException { - return getAllByName0(host, check, true); + static InetAddress[] getAllByName0(String host) throws UnknownHostException { + return getAllByName0(host, true); } /** @@ -1682,30 +1633,16 @@ public static InetAddress ofLiteral(String ipAddressLiteral) { * Designated lookup method. * * @param host host name to look up - * @param check perform security check * @param useCache use cached value if not expired else always * perform name service lookup (and cache the result) * @return array of InetAddress(es) * @throws UnknownHostException if host name is not found */ private static InetAddress[] getAllByName0(String host, - boolean check, boolean useCache) throws UnknownHostException { /* If it gets here it is presumed to be a hostname */ - - /* make sure the connection to the host is allowed, before we - * give out a hostname - */ - if (check) { - @SuppressWarnings("removal") - SecurityManager security = System.getSecurityManager(); - if (security != null) { - security.checkConnect(host, -1); - } - } - // remove expired addresses from cache - expirySet keeps them ordered // by expiry time so we only need to iterate the prefix of the NavigableSet... long now = System.nanoTime(); @@ -1822,48 +1759,33 @@ private static final class CachedLocalHost { * @see java.net.InetAddress#getByName(java.lang.String) */ public static InetAddress getLocalHost() throws UnknownHostException { + // is cached data still valid? + CachedLocalHost clh = cachedLocalHost; + if (clh != null && (clh.expiryTime - System.nanoTime()) >= 0L) { + return clh.addr; + } - @SuppressWarnings("removal") - SecurityManager security = System.getSecurityManager(); - try { - // is cached data still valid? - CachedLocalHost clh = cachedLocalHost; - if (clh != null && (clh.expiryTime - System.nanoTime()) >= 0L) { - if (security != null) { - security.checkConnect(clh.host, -1); - } - return clh.addr; - } - - String local = impl.getLocalHostName(); - - if (security != null) { - security.checkConnect(local, -1); - } + String local = impl.getLocalHostName(); - InetAddress localAddr; - if (local.equals("localhost")) { - // shortcut for "localhost" host name - localAddr = impl.loopbackAddress(); - } else { - // call getAllByName0 without security checks and - // without using cached data - try { - localAddr = getAllByName0(local, false, false)[0]; - } catch (UnknownHostException uhe) { - // Rethrow with a more informative error message. - UnknownHostException uhe2 = + InetAddress localAddr; + if (local.equals("localhost")) { + // shortcut for "localhost" host name + localAddr = impl.loopbackAddress(); + } else { + // call getAllByName0 without using cached data + try { + localAddr = getAllByName0(local, false)[0]; + } catch (UnknownHostException uhe) { + // Rethrow with a more informative error message. + UnknownHostException uhe2 = new UnknownHostException(local + ": " + - uhe.getMessage()); - uhe2.initCause(uhe); - throw uhe2; - } + uhe.getMessage()); + uhe2.initCause(uhe); + throw uhe2; } - cachedLocalHost = new CachedLocalHost(local, localAddr); - return localAddr; - } catch (java.lang.SecurityException e) { - return impl.loopbackAddress(); } + cachedLocalHost = new CachedLocalHost(local, localAddr); + return localAddr; } /** diff --git a/src/java.base/share/classes/java/net/SocketPermission.java b/src/java.base/share/classes/java/net/SocketPermission.java index 0a2b586f7c1..0c49e6cafef 100644 --- a/src/java.base/share/classes/java/net/SocketPermission.java +++ b/src/java.base/share/classes/java/net/SocketPermission.java @@ -30,10 +30,8 @@ import java.io.ObjectOutputStream; import java.io.ObjectStreamField; import java.io.Serializable; -import java.security.AccessController; import java.security.Permission; import java.security.PermissionCollection; -import java.security.PrivilegedAction; import java.util.Collections; import java.util.Enumeration; import java.util.Locale; @@ -638,10 +636,10 @@ void getCanonName() // we have to do this check, otherwise we might not // get the fully qualified domain name if (init_with_ip) { - cname = addresses[0].getHostName(false).toLowerCase(Locale.ROOT); + cname = addresses[0].getHostName().toLowerCase(Locale.ROOT); } else { cname = InetAddress.getByName(addresses[0].getHostAddress()). - getHostName(false).toLowerCase(Locale.ROOT); + getHostName().toLowerCase(Locale.ROOT); } } catch (UnknownHostException uhe) { invalid = true; @@ -705,7 +703,7 @@ private boolean authorizedIPv4(byte[] addr) { // Following check seems unnecessary // auth = InetAddress.getAllByName0(authHost, false)[0]; authHost = hostname + '.' + authHost; - auth = InetAddress.getAllByName0(authHost, false)[0]; + auth = InetAddress.getAllByName0(authHost)[0]; if (auth.equals(InetAddress.getByAddress(addr))) { return true; } @@ -736,9 +734,8 @@ private boolean authorizedIPv6(byte[] addr) { sb.append('.'); } authHost = "auth." + sb.toString() + "IP6.ARPA"; - //auth = InetAddress.getAllByName0(authHost, false)[0]; authHost = hostname + '.' + authHost; - auth = InetAddress.getAllByName0(authHost, false)[0]; + auth = InetAddress.getAllByName0(authHost)[0]; if (auth.equals(InetAddress.getByAddress(addr))) return true; Debug debug = getDebug(); @@ -780,7 +777,7 @@ void getIP() } addresses = - new InetAddress[] {InetAddress.getAllByName0(host, false)[0]}; + new InetAddress[] {InetAddress.getAllByName0(host)[0]}; } catch (UnknownHostException uhe) { invalid = true; @@ -1191,23 +1188,15 @@ private synchronized void readObject(java.io.ObjectInputStream s) * Check the system/security property for the ephemeral port range * for this system. The suffix is either "high" or "low" */ - @SuppressWarnings("removal") private static int initEphemeralPorts(String suffix) { - return AccessController.doPrivileged( - new PrivilegedAction<>(){ - public Integer run() { - int val = Integer.getInteger( - "jdk.net.ephemeralPortRange."+suffix, -1 - ); - if (val != -1) { - return val; - } else { - return suffix.equals("low") ? - PortConfig.getLower() : PortConfig.getUpper(); - } - } - } - ); + int val = Integer.getInteger( + "jdk.net.ephemeralPortRange." + suffix, -1); + if (val != -1) { + return val; + } else { + return suffix.equals("low") ? + PortConfig.getLower() : PortConfig.getUpper(); + } } /** diff --git a/src/java.base/share/classes/java/net/doc-files/net-properties.html b/src/java.base/share/classes/java/net/doc-files/net-properties.html index a67df0c0d00..684c90a8164 100644 --- a/src/java.base/share/classes/java/net/doc-files/net-properties.html +++ b/src/java.base/share/classes/java/net/doc-files/net-properties.html @@ -279,8 +279,7 @@ <H2>Address Cache</H2> name lookups will be kept in the cache. A value of -1, or any other negative value for that matter, indicates a “cache forever” policy, while a value of 0 (zero) means no caching. The default value - is -1 (forever) if a security manager is installed, and implementation-specific - when no security manager is installed.</P> + is implementation-specific.</P> <LI><P><B>{@code networkaddress.cache.stale.ttl}</B> (default: see below)<BR> Value is an integer corresponding to the number of seconds that stale names will be kept in the cache. A name is considered stale if the TTL has expired diff --git a/src/java.base/share/classes/java/net/spi/InetAddressResolverProvider.java b/src/java.base/share/classes/java/net/spi/InetAddressResolverProvider.java index 5b032591089..a5dbc938cc2 100644 --- a/src/java.base/share/classes/java/net/spi/InetAddressResolverProvider.java +++ b/src/java.base/share/classes/java/net/spi/InetAddressResolverProvider.java @@ -98,15 +98,6 @@ public abstract class InetAddressResolverProvider { */ public abstract String name(); - /** - * The {@code RuntimePermission("inetAddressResolverProvider")} is - * necessary to subclass and instantiate the {@code InetAddressResolverProvider} class, - * as well as to obtain resolver from an instance of that class, - * and it is also required to obtain the operating system name resolution configurations. - */ - private static final RuntimePermission INET_ADDRESS_RESOLVER_PERMISSION = - new RuntimePermission("inetAddressResolverProvider"); - /** * Creates a new instance of {@code InetAddressResolverProvider}. * @@ -116,19 +107,6 @@ public abstract class InetAddressResolverProvider { * service provider. */ protected InetAddressResolverProvider() { - this(checkPermission()); - } - - private InetAddressResolverProvider(Void unused) { - } - - @SuppressWarnings("removal") - private static Void checkPermission() { - final SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - sm.checkPermission(INET_ADDRESS_RESOLVER_PERMISSION); - } - return null; } /** diff --git a/src/java.base/share/classes/sun/net/InetAddressCachePolicy.java b/src/java.base/share/classes/sun/net/InetAddressCachePolicy.java index 5c127025682..0cce06ae137 100644 --- a/src/java.base/share/classes/sun/net/InetAddressCachePolicy.java +++ b/src/java.base/share/classes/sun/net/InetAddressCachePolicy.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,11 +25,8 @@ package sun.net; -import java.security.PrivilegedAction; import java.security.Security; -import java.util.concurrent.TimeUnit; -@SuppressWarnings("removal") public final class InetAddressCachePolicy { // Controls the cache policy for successful lookups only @@ -60,11 +57,9 @@ public final class InetAddressCachePolicy { * -1: caching forever * any positive value: the number of seconds to cache an address for * - * default value is forever (FOREVER), as we let the platform do the - * caching. For security reasons, this caching is made forever when - * a security manager is set. + * default value is 30 seconds */ - private static volatile int cachePolicy = FOREVER; + private static volatile int cachePolicy = DEFAULT_POSITIVE; /* The Java-level namelookup cache stale policy: * @@ -85,40 +80,22 @@ public final class InetAddressCachePolicy { */ private static volatile int negativeCachePolicy = NEVER; - /* - * Whether or not the cache policy for successful lookups was set - * using a property (cmd line). - */ - private static boolean propertySet; - - /* - * Whether or not the cache policy for negative lookups was set - * using a property (cmd line). - */ - private static boolean propertyNegativeSet; - /* * Initialize */ static { + /* If the cache policy property is not specified + * then the default positive cache value is used. + */ Integer tmp = getProperty(cachePolicyProp, cachePolicyPropFallback); if (tmp != null) { cachePolicy = tmp < 0 ? FOREVER : tmp; - propertySet = true; - } else { - /* No properties defined for positive caching. If there is no - * security manager then use the default positive cache value. - */ - if (System.getSecurityManager() == null) { - cachePolicy = DEFAULT_POSITIVE; - } } tmp = getProperty(negativeCachePolicyProp, negativeCachePolicyPropFallback); if (tmp != null) { negativeCachePolicy = tmp < 0 ? FOREVER : tmp; - propertyNegativeSet = true; } if (cachePolicy > 0) { tmp = getProperty(cacheStalePolicyProp, @@ -130,33 +107,25 @@ public final class InetAddressCachePolicy { } private static Integer getProperty(String cachePolicyProp, - String cachePolicyPropFallback) - { - return java.security.AccessController.doPrivileged( - new PrivilegedAction<Integer>() { - public Integer run() { - try { - String tmpString = Security.getProperty( - cachePolicyProp); - if (tmpString != null) { - return Integer.valueOf(tmpString); - } - } catch (NumberFormatException ignored) { - // Ignore - } - - try { - String tmpString = System.getProperty( - cachePolicyPropFallback); - if (tmpString != null) { - return Integer.decode(tmpString); - } - } catch (NumberFormatException ignored) { - // Ignore - } - return null; - } - }); + String cachePolicyPropFallback) { + try { + String tmpString = Security.getProperty(cachePolicyProp); + if (tmpString != null) { + return Integer.valueOf(tmpString); + } + } catch (NumberFormatException ignored) { + // Ignore + } + + try { + String tmpString = System.getProperty(cachePolicyPropFallback); + if (tmpString != null) { + return Integer.decode(tmpString); + } + } catch (NumberFormatException ignored) { + // Ignore + } + return null; } public static int get() { @@ -170,63 +139,4 @@ public static int getStale() { public static int getNegative() { return negativeCachePolicy; } - - /** - * Sets the cache policy for successful lookups if the user has not - * already specified a cache policy for it using a - * command-property. - * @param newPolicy the value in seconds for how long the lookup - * should be cached - */ - public static synchronized void setIfNotSet(int newPolicy) { - /* - * When setting the new value we may want to signal that the - * cache should be flushed, though this doesn't seem strictly - * necessary. - */ - if (!propertySet) { - checkValue(newPolicy, cachePolicy); - cachePolicy = newPolicy; - } - } - - /** - * Sets the cache policy for negative lookups if the user has not - * already specified a cache policy for it using a - * command-property. - * @param newPolicy the value in seconds for how long the lookup - * should be cached - */ - public static void setNegativeIfNotSet(int newPolicy) { - /* - * When setting the new value we may want to signal that the - * cache should be flushed, though this doesn't seem strictly - * necessary. - */ - if (!propertyNegativeSet) { - // Negative caching does not seem to have any security - // implications. - // checkValue(newPolicy, negativeCachePolicy); - // but we should normalize negative policy - negativeCachePolicy = newPolicy < 0 ? FOREVER : newPolicy; - } - } - - private static void checkValue(int newPolicy, int oldPolicy) { - /* - * If malicious code gets a hold of this method, prevent - * setting the cache policy to something laxer or some - * invalid negative value. - */ - if (newPolicy == FOREVER) - return; - - if ((oldPolicy == FOREVER) || - (newPolicy < oldPolicy) || - (newPolicy < FOREVER)) { - - throw new - SecurityException("can't make InetAddress cache more lax"); - } - } } diff --git a/src/java.base/share/classes/sun/net/util/IPAddressUtil.java b/src/java.base/share/classes/sun/net/util/IPAddressUtil.java index ecd60a9ffc4..b3da295c4a7 100644 --- a/src/java.base/share/classes/sun/net/util/IPAddressUtil.java +++ b/src/java.base/share/classes/sun/net/util/IPAddressUtil.java @@ -25,8 +25,6 @@ package sun.net.util; -import sun.security.action.GetPropertyAction; - import java.io.UncheckedIOException; import java.net.Inet6Address; import java.net.InetAddress; @@ -35,9 +33,6 @@ import java.net.SocketException; import java.net.URL; import java.nio.CharBuffer; -import java.security.AccessController; -import java.security.PrivilegedExceptionAction; -import java.security.PrivilegedActionException; import java.util.Arrays; import java.util.List; import java.util.concurrent.ConcurrentHashMap; @@ -396,25 +391,23 @@ public static InetSocketAddress toScopedAddress(InetSocketAddress address) } } - @SuppressWarnings("removal") private static InetAddress findScopedAddress(InetAddress address) { - PrivilegedExceptionAction<List<InetAddress>> pa = () -> NetworkInterface.networkInterfaces() - .flatMap(NetworkInterface::inetAddresses) - .filter(a -> (a instanceof Inet6Address) - && address.equals(a) - && ((Inet6Address) a).getScopeId() != 0) - .toList(); - List<InetAddress> result; try { - result = AccessController.doPrivileged(pa); + List<InetAddress> result = NetworkInterface.networkInterfaces() + .flatMap(NetworkInterface::inetAddresses) + .filter(a -> (a instanceof Inet6Address) + && address.equals(a) + && ((Inet6Address) a).getScopeId() != 0) + .toList(); + var sz = result.size(); if (sz == 0) return null; if (sz > 1) throw new UncheckedIOException(new SocketException( - "Duplicate link local addresses: must specify scope-id")); + "Duplicate link local addresses: must specify scope-id")); return result.get(0); - } catch (PrivilegedActionException pae) { + } catch (SocketException socketException) { return null; } } @@ -927,8 +920,8 @@ public static boolean delayURLParsing() { private static final long TERMINAL_PARSE_ERROR = -2L; private static final String ALLOW_AMBIGUOUS_IPADDRESS_LITERALS_SP = "jdk.net.allowAmbiguousIPAddressLiterals"; - private static final boolean ALLOW_AMBIGUOUS_IPADDRESS_LITERALS_SP_VALUE = Boolean.valueOf( - GetPropertyAction.privilegedGetProperty(ALLOW_AMBIGUOUS_IPADDRESS_LITERALS_SP, "false")); + private static final boolean ALLOW_AMBIGUOUS_IPADDRESS_LITERALS_SP_VALUE = + Boolean.getBoolean(ALLOW_AMBIGUOUS_IPADDRESS_LITERALS_SP); private static class MASKS { private static final String DELAY_URL_PARSING_SP = "jdk.net.url.delayParsing"; private static final boolean DELAY_URL_PARSING_SP_VALUE; @@ -939,8 +932,7 @@ private static class MASKS { static final long L_SCOPE_MASK; static final long H_SCOPE_MASK; static { - var value = GetPropertyAction.privilegedGetProperty( - DELAY_URL_PARSING_SP, "false"); + var value = System.getProperty(DELAY_URL_PARSING_SP, "false"); DELAY_URL_PARSING_SP_VALUE = value.isEmpty() || Boolean.parseBoolean(value); if (DELAY_URL_PARSING_SP_VALUE) { From 15378a785356bdf574e557633d36591f5cfc1610 Mon Sep 17 00:00:00 2001 From: Casper Norrbin <cnorrbin@openjdk.org> Date: Wed, 27 Nov 2024 19:51:17 +0000 Subject: [PATCH 289/311] 8345126: [BACKOUT] JDK-8318127: align_up has potential overflow Reviewed-by: iklam --- src/hotspot/share/utilities/align.hpp | 4 +-- .../gtest/runtime/test_os_reserve_between.cpp | 4 +-- test/hotspot/gtest/utilities/test_align.cpp | 35 ++----------------- 3 files changed, 5 insertions(+), 38 deletions(-) diff --git a/src/hotspot/share/utilities/align.hpp b/src/hotspot/share/utilities/align.hpp index 935781a5561..4640f05e4d0 100644 --- a/src/hotspot/share/utilities/align.hpp +++ b/src/hotspot/share/utilities/align.hpp @@ -72,9 +72,7 @@ constexpr T align_down(T size, A alignment) { template<typename T, typename A, ENABLE_IF(std::is_integral<T>::value)> constexpr T align_up(T size, A alignment) { - T mask = checked_cast<T>(alignment_mask(alignment)); - assert(size <= std::numeric_limits<T>::max() - mask, "overflow"); - T adjusted = size + mask; + T adjusted = checked_cast<T>(size + alignment_mask(alignment)); return align_down(adjusted, alignment); } diff --git a/test/hotspot/gtest/runtime/test_os_reserve_between.cpp b/test/hotspot/gtest/runtime/test_os_reserve_between.cpp index 16e1bdd1b21..aad6acc095a 100644 --- a/test/hotspot/gtest/runtime/test_os_reserve_between.cpp +++ b/test/hotspot/gtest/runtime/test_os_reserve_between.cpp @@ -304,12 +304,12 @@ TEST_VM(os, attempt_reserve_memory_randomization_cornercases) { // Zero-sized range test_attempt_reserve_memory_between(nullptr, nullptr, ps, ag, false, Expect::failure()); test_attempt_reserve_memory_between((char*)(3 * G), (char*)(3 * G), ps, ag, false, Expect::dontcare(), __LINE__); - test_attempt_reserve_memory_between((char*)SIZE_MAX-ag, (char*)SIZE_MAX-ag, ps, ag, false, Expect::failure(), __LINE__); + test_attempt_reserve_memory_between((char*)SIZE_MAX, (char*)SIZE_MAX, ps, ag, false, Expect::failure(), __LINE__); test_attempt_reserve_memory_between(nullptr, nullptr, ps, ag, true, Expect::failure()); test_attempt_reserve_memory_between((char*)(3 * G), (char*)(3 * G), ps, ag, true, Expect::dontcare(), __LINE__); test_attempt_reserve_memory_between((char*)(3 * G), (char*)(3 * G), ps, ag, true, Expect::dontcare(), __LINE__); - test_attempt_reserve_memory_between((char*)SIZE_MAX-ag, (char*)SIZE_MAX-ag, ps, ag, true, Expect::failure(), __LINE__); + test_attempt_reserve_memory_between((char*)SIZE_MAX, (char*)SIZE_MAX, ps, ag, true, Expect::failure(), __LINE__); // Full size // Note: paradoxically, success is not guaranteed here, since a significant portion of the attach points diff --git a/test/hotspot/gtest/utilities/test_align.cpp b/test/hotspot/gtest/utilities/test_align.cpp index 4efcf14a7f0..f5e6b9d9646 100644 --- a/test/hotspot/gtest/utilities/test_align.cpp +++ b/test/hotspot/gtest/utilities/test_align.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -23,7 +23,6 @@ #include "precompiled.hpp" #include "utilities/align.hpp" -#include "utilities/checkedCast.hpp" #include "utilities/formatBuffer.hpp" #include "utilities/globalDefinitions.hpp" #include "unittest.hpp" @@ -31,7 +30,7 @@ #include <limits> // A few arbitrarily chosen values to test the align functions on. -static constexpr uint64_t values[] = {1, 3, 10, 345, 1023, 1024, 1025, 23909034, INT_MAX, uint64_t(-1) / 2, uint64_t(-1) / 2 + 100, ~(uint64_t(1) << 62)}; +static constexpr uint64_t values[] = {1, 3, 10, 345, 1023, 1024, 1025, 23909034, INT_MAX, uint64_t(-1) / 2, uint64_t(-1) / 2 + 100, uint64_t(-1)}; template <typename T> static constexpr T max_alignment() { @@ -196,33 +195,3 @@ TEST(Align, alignments) { test_alignments<int8_t, int8_t>(); } - -#ifdef ASSERT -template <typename T, typename A> -static void test_fail_alignment() { - A alignment = max_alignment<A>(); - T value = align_down(std::numeric_limits<T>::max(), alignment) + 1; - // Aligning up would overflow, as there is not enough room for alignment - T aligned = align_up(value, alignment); -} - -TEST_VM_ASSERT(Align, fail_alignments_same_size) { - test_fail_alignment<uint64_t, uint64_t>(); -} - -TEST_VM_ASSERT(Align, fail_alignments_unsigned_signed) { - test_fail_alignment<uint32_t, int32_t>(); -} - -TEST_VM_ASSERT(Align, fail_alignments_signed_unsigned) { - test_fail_alignment<int64_t, int32_t>(); -} - -TEST_VM_ASSERT(Align, fail_alignments_small_large) { - test_fail_alignment<uint8_t, uint64_t>(); -} - -TEST_VM_ASSERT(Align, fail_alignments_large_small) { - test_fail_alignment<uint64_t, uint8_t>(); -} -#endif // ASSERT From f6d29909bb5cce0a73945c9fccc9c3fa7d4804fd Mon Sep 17 00:00:00 2001 From: Ioi Lam <iklam@openjdk.org> Date: Wed, 27 Nov 2024 20:10:28 +0000 Subject: [PATCH 290/311] 8344824: CDS dump crashes when member_method of a lambda proxy is null Reviewed-by: ccheung, matsaave --- src/hotspot/share/cds/archiveBuilder.hpp | 10 ++ src/hotspot/share/cds/archiveUtils.hpp | 29 ++++- src/hotspot/share/cds/lambdaFormInvokers.cpp | 2 +- .../share/cds/lambdaProxyClassDictionary.hpp | 14 +-- src/hotspot/share/cds/runTimeClassInfo.cpp | 2 +- src/hotspot/share/cds/runTimeClassInfo.hpp | 12 +- test/hotspot/jtreg/TEST.groups | 1 + .../cds/appcds/LambdaInvokeVirtual.java | 108 ++++++++++++++++++ 8 files changed, 159 insertions(+), 19 deletions(-) create mode 100644 test/hotspot/jtreg/runtime/cds/appcds/LambdaInvokeVirtual.java diff --git a/src/hotspot/share/cds/archiveBuilder.hpp b/src/hotspot/share/cds/archiveBuilder.hpp index 39fffc26c37..e42b2f478ec 100644 --- a/src/hotspot/share/cds/archiveBuilder.hpp +++ b/src/hotspot/share/cds/archiveBuilder.hpp @@ -343,10 +343,20 @@ class ArchiveBuilder : public StackObj { template <typename T> u4 any_to_offset_u4(T p) const { + assert(p != nullptr, "must not be null"); uintx offset = any_to_offset((address)p); return to_offset_u4(offset); } + template <typename T> + u4 any_or_null_to_offset_u4(T p) const { + if (p == nullptr) { + return 0; + } else { + return any_to_offset_u4<T>(p); + } + } + template <typename T> T offset_to_buffered(u4 offset) const { return (T)offset_to_buffered_address(offset); diff --git a/src/hotspot/share/cds/archiveUtils.hpp b/src/hotspot/share/cds/archiveUtils.hpp index ee1135b70fa..723332c40e5 100644 --- a/src/hotspot/share/cds/archiveUtils.hpp +++ b/src/hotspot/share/cds/archiveUtils.hpp @@ -259,16 +259,33 @@ class ArchiveUtils { static bool has_aot_initialized_mirror(InstanceKlass* src_ik); template <typename T> static Array<T>* archive_array(GrowableArray<T>* tmp_array); + // The following functions translate between a u4 offset and an address in the + // the range of the mapped CDS archive (e.g., Metaspace::is_in_shared_metaspace()). + // Since the first 16 bytes in this range are dummy data (see ArchiveBuilder::reserve_buffer()), + // we know that offset 0 never represents a valid object. As a result, an offset of 0 + // is used to encode a nullptr. + // + // Use the "archived_address_or_null" variants if a nullptr may be encoded. + // offset must represent an object of type T in the mapped shared space. Return // a direct pointer to this object. - template <typename T> T static from_offset(u4 offset) { + template <typename T> T static offset_to_archived_address(u4 offset) { + assert(offset != 0, "sanity"); T p = (T)(SharedBaseAddress + offset); assert(Metaspace::is_in_shared_metaspace(p), "must be"); return p; } + template <typename T> T static offset_to_archived_address_or_null(u4 offset) { + if (offset == 0) { + return nullptr; + } else { + return offset_to_archived_address<T>(offset); + } + } + // p must be an archived object. Get its offset from SharedBaseAddress - template <typename T> static u4 to_offset(T p) { + template <typename T> static u4 archived_address_to_offset(T p) { uintx pn = (uintx)p; uintx base = (uintx)SharedBaseAddress; assert(Metaspace::is_in_shared_metaspace(p), "must be"); @@ -277,6 +294,14 @@ class ArchiveUtils { assert(offset <= MAX_SHARED_DELTA, "range check"); return static_cast<u4>(offset); } + + template <typename T> static u4 archived_address_or_null_to_offset(T p) { + if (p == nullptr) { + return 0; + } else { + return archived_address_to_offset<T>(p); + } + } }; class HeapRootSegments { diff --git a/src/hotspot/share/cds/lambdaFormInvokers.cpp b/src/hotspot/share/cds/lambdaFormInvokers.cpp index 5455a5e66f2..7765bc26aa3 100644 --- a/src/hotspot/share/cds/lambdaFormInvokers.cpp +++ b/src/hotspot/share/cds/lambdaFormInvokers.cpp @@ -254,7 +254,7 @@ void LambdaFormInvokers::read_static_archive_invokers() { if (_static_archive_invokers != nullptr) { for (int i = 0; i < _static_archive_invokers->length(); i++) { u4 offset = _static_archive_invokers->at(i); - Array<char>* line = ArchiveUtils::from_offset<Array<char>*>(offset); + Array<char>* line = ArchiveUtils::offset_to_archived_address<Array<char>*>(offset); char* str = line->adr_at(0); append(str); } diff --git a/src/hotspot/share/cds/lambdaProxyClassDictionary.hpp b/src/hotspot/share/cds/lambdaProxyClassDictionary.hpp index 2a9f87681db..bd163fc551d 100644 --- a/src/hotspot/share/cds/lambdaProxyClassDictionary.hpp +++ b/src/hotspot/share/cds/lambdaProxyClassDictionary.hpp @@ -143,7 +143,7 @@ class RunTimeLambdaProxyClassKey { u4 invoked_name = b->any_to_offset_u4(key.invoked_name()); u4 invoked_type = b->any_to_offset_u4(key.invoked_type()); u4 method_type = b->any_to_offset_u4(key.method_type()); - u4 member_method = b->any_to_offset_u4(key.member_method()); + u4 member_method = b->any_or_null_to_offset_u4(key.member_method()); // could be null u4 instantiated_method_type = b->any_to_offset_u4(key.instantiated_method_type()); return RunTimeLambdaProxyClassKey(caller_ik, invoked_name, invoked_type, method_type, @@ -158,12 +158,12 @@ class RunTimeLambdaProxyClassKey { Symbol* instantiated_method_type) { // All parameters must be in shared space, or else you'd get an assert in // ArchiveUtils::to_offset(). - return RunTimeLambdaProxyClassKey(ArchiveUtils::to_offset(caller_ik), - ArchiveUtils::to_offset(invoked_name), - ArchiveUtils::to_offset(invoked_type), - ArchiveUtils::to_offset(method_type), - ArchiveUtils::to_offset(member_method), - ArchiveUtils::to_offset(instantiated_method_type)); + return RunTimeLambdaProxyClassKey(ArchiveUtils::archived_address_to_offset(caller_ik), + ArchiveUtils::archived_address_to_offset(invoked_name), + ArchiveUtils::archived_address_to_offset(invoked_type), + ArchiveUtils::archived_address_to_offset(method_type), + ArchiveUtils::archived_address_or_null_to_offset(member_method), // could be null + ArchiveUtils::archived_address_to_offset(instantiated_method_type)); } unsigned int hash() const; diff --git a/src/hotspot/share/cds/runTimeClassInfo.cpp b/src/hotspot/share/cds/runTimeClassInfo.cpp index 5ad9c14d13e..0acd89b5bce 100644 --- a/src/hotspot/share/cds/runTimeClassInfo.cpp +++ b/src/hotspot/share/cds/runTimeClassInfo.cpp @@ -79,7 +79,7 @@ InstanceKlass* RunTimeClassInfo::klass() const { if (ArchiveBuilder::is_active() && ArchiveBuilder::current()->is_in_buffer_space((address)this)) { return ArchiveBuilder::current()->offset_to_buffered<InstanceKlass*>(_klass_offset); } else { - return ArchiveUtils::from_offset<InstanceKlass*>(_klass_offset); + return ArchiveUtils::offset_to_archived_address<InstanceKlass*>(_klass_offset); } } diff --git a/src/hotspot/share/cds/runTimeClassInfo.hpp b/src/hotspot/share/cds/runTimeClassInfo.hpp index e3c1ad4f8fe..ca60e11736d 100644 --- a/src/hotspot/share/cds/runTimeClassInfo.hpp +++ b/src/hotspot/share/cds/runTimeClassInfo.hpp @@ -52,15 +52,15 @@ class RunTimeClassInfo { struct RTVerifierConstraint { u4 _name; u4 _from_name; - Symbol* name() { return ArchiveUtils::from_offset<Symbol*>(_name); } - Symbol* from_name() { return ArchiveUtils::from_offset<Symbol*>(_from_name); } + Symbol* name() { return ArchiveUtils::offset_to_archived_address<Symbol*>(_name); } + Symbol* from_name() { return ArchiveUtils::offset_to_archived_address<Symbol*>(_from_name); } }; struct RTLoaderConstraint { u4 _name; char _loader_type1; char _loader_type2; - Symbol* constraint_name() { return ArchiveUtils::from_offset<Symbol*>(_name); } + Symbol* constraint_name() { return ArchiveUtils::offset_to_archived_address<Symbol*>(_name); } }; struct RTEnumKlassStaticFields { int _num; @@ -177,11 +177,7 @@ class RunTimeClassInfo { InstanceKlass* nest_host() { assert(!ArchiveBuilder::is_active(), "not called when dumping archive"); - if (_nest_host_offset == 0) { - return nullptr; - } else { - return ArchiveUtils::from_offset<InstanceKlass*>(_nest_host_offset); - } + return ArchiveUtils::offset_to_archived_address_or_null<InstanceKlass*>(_nest_host_offset); } RTLoaderConstraint* loader_constraints() { diff --git a/test/hotspot/jtreg/TEST.groups b/test/hotspot/jtreg/TEST.groups index 718ecf610f1..d04ed90ae07 100644 --- a/test/hotspot/jtreg/TEST.groups +++ b/test/hotspot/jtreg/TEST.groups @@ -462,6 +462,7 @@ hotspot_appcds_dynamic = \ -runtime/cds/appcds/ExtraSymbols.java \ -runtime/cds/appcds/LambdaContainsOldInf.java \ -runtime/cds/appcds/LambdaEagerInit.java \ + -runtime/cds/appcds/LambdaInvokeVirtual.java \ -runtime/cds/appcds/LambdaProxyClasslist.java \ -runtime/cds/appcds/LambdaVerificationFailedDuringDump.java \ -runtime/cds/appcds/LambdaWithJavaAgent.java \ diff --git a/test/hotspot/jtreg/runtime/cds/appcds/LambdaInvokeVirtual.java b/test/hotspot/jtreg/runtime/cds/appcds/LambdaInvokeVirtual.java new file mode 100644 index 00000000000..8d59d202bbd --- /dev/null +++ b/test/hotspot/jtreg/runtime/cds/appcds/LambdaInvokeVirtual.java @@ -0,0 +1,108 @@ +/* + * Copyright (c) 2021, 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + * + */ + +/* + * @test + * @bug 8344824 + * @summary CDS dump crashes when member_method of a lambda proxy is null + * @requires vm.cds + * @library /test/lib + * @build LambdaInvokeVirtual + * @run driver jdk.test.lib.helpers.ClassFileInstaller -jar LambdaInvokeVirtualApp.jar LambdaInvokeVirtualApp MyFunctionalInterface + * @run driver LambdaInvokeVirtual + */ + +import java.lang.invoke.MethodHandle; +import java.lang.invoke.MethodHandles; +import java.lang.invoke.MethodType; +import jdk.test.lib.cds.CDSOptions; +import jdk.test.lib.cds.CDSTestUtils; +import jdk.test.lib.helpers.ClassFileInstaller; +import jdk.test.lib.process.OutputAnalyzer; + +public class LambdaInvokeVirtual { + + public static void main(String[] args) throws Exception { + String appJar = ClassFileInstaller.getJarPath("LambdaInvokeVirtualApp.jar"); + String mainClass = LambdaInvokeVirtualApp.class.getName(); + String namePrefix = "LambdaInvokeVirtualApp"; + String classList = namePrefix + ".list"; + String archiveName = namePrefix + ".jsa"; + + // dump class list + CDSTestUtils.dumpClassList(classList, "-cp", appJar, mainClass); + + // create archive with the class list + CDSOptions opts = (new CDSOptions()) + .addPrefix("-XX:ExtraSharedClassListFile=" + classList, + "-cp", appJar, + "-Xlog:cds,cds+class=debug") + .setArchiveName(archiveName); + CDSTestUtils.createArchiveAndCheck(opts); + + // run with archive + CDSOptions runOpts = (new CDSOptions()) + .addPrefix("-cp", appJar) + .setArchiveName(archiveName) + .setUseVersion(false) + .addSuffix(mainClass); + OutputAnalyzer output = CDSTestUtils.runWithArchive(runOpts); + output.shouldHaveExitValue(0); + } +} + +interface MyFunctionalInterface { + Object invokeMethodReference(String s, char c1, char c2) throws Throwable; +} + +class LambdaInvokeVirtualApp { + private static MethodHandle createMethodHandle() throws NoSuchMethodException, IllegalAccessException { + MethodHandles.Lookup lookup = MethodHandles.lookup(); + MethodType mt = MethodType.methodType(String.class, char.class, char.class); + return lookup.findVirtual(String.class, "replace", mt); + } + + public static void main(String argv[]) throws Throwable { + MethodHandle ms = createMethodHandle(); + MyFunctionalInterface instance = ms::invoke; + +/* + The above is compiled into this bytecode. Note that the MethodHandle is of type REF_invokeVirtual + + invokedynamic InvokeDynamic REF_invokeStatic:Method java/lang/invoke/LambdaMetafactory.metafactory:"(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodType;Ljava/lang/invoke/MethodHandle;Ljava/lang/invoke/MethodType;)Ljava/lang/invoke/CallSite;":invokeMethodReference:"(Ljava/lang/invoke/MethodHandle;)LMyFunctionalInterface;" { + MethodType "(Ljava/lang/String;CC)Ljava/lang/Object;", + MethodHandle REF_invokeVirtual:Method java/lang/invoke/MethodHandle.invoke:"(Ljava/lang/String;CC)Ljava/lang/Object;", + MethodType "(Ljava/lang/String;CC)Ljava/lang/Object;" + }; + +*/ + + Object result = instance.invokeMethodReference("some string to search", 's', 'o'); + String expected = "oome otring to oearch"; + if (!result.equals(expected)) { + throw new RuntimeException("Expected \"" + expected + "\" but got \"" + + result + "\""); + } + } +} From 8ad0b2afe3c6f574b0cd3e31c10946c19045a308 Mon Sep 17 00:00:00 2001 From: Phil Race <prr@openjdk.org> Date: Wed, 27 Nov 2024 22:10:07 +0000 Subject: [PATCH 291/311] 8345001: java/awt/doc-files/FocusSpec.html has SecurityManager references Reviewed-by: azvegint, kizune --- .../classes/java/awt/doc-files/FocusSpec.html | 22 ------------------- 1 file changed, 22 deletions(-) diff --git a/src/java.desktop/share/classes/java/awt/doc-files/FocusSpec.html b/src/java.desktop/share/classes/java/awt/doc-files/FocusSpec.html index 94a4a7abdac..9694c123e50 100644 --- a/src/java.desktop/share/classes/java/awt/doc-files/FocusSpec.html +++ b/src/java.desktop/share/classes/java/awt/doc-files/FocusSpec.html @@ -986,8 +986,6 @@ <h2>Focus and PropertyChangeListener</h2> the <code>KeyboardFocusManager</code>'s context, even though the focus owner, focused Window, active Window, and current focus cycle root comprise the global focus state shared by all contexts. -We believe this is less intrusive than requiring client code to pass -a security check before installing a <code>PropertyChangeListener</code>. <p> Component supports the following focus-related properties: @@ -1195,26 +1193,6 @@ <h2>Replacing DefaultKeyboardFocusManager</h2> VetoableChangeListeners, and other concepts discussed in this document before resorting to a full replacement of the <code>KeyboardFocusManager</code>. <p> -First note that, because unhindered access to Components in other -contexts represents a security hole, the SecurityManager must grant a -new permission, "replaceKeyboardFocusManager", before client code is -permitted to replace the <code>KeyboardFocusManager</code> with an arbitrary -subclass instance. Because of the security check, replacing the -<code>KeyboardFocusManager</code> is not an option for applications that will be -deployed in environments with a SecurityManager, such as applets in a -browser. -<p> -Once installed, a <code>KeyboardFocusManager</code> instance has -access to the global focus state via a set of protected functions. -The <code>KeyboardFocusManager</code> can only call these functions -if it is installed in the calling thread's context. This ensures -that malicious code cannot circumvent the security check in -<code>KeyboardFocusManager.setCurrentFocusManager</code>. -A <code>KeyboardFocusManager</code> should always work with -the global focus state instead of the context focus state. -Failure to do this will lead to incorrect behavior of the -<code>KeyboardFocusManager</code>. -<p> The primary responsibility of a <code>KeyboardFocusManager</code> is the dispatch of the following events: From cf5ee0bda2e50d91673ff6bfa2d6d1dbb96fa99b Mon Sep 17 00:00:00 2001 From: Phil Race <prr@openjdk.org> Date: Wed, 27 Nov 2024 22:10:25 +0000 Subject: [PATCH 292/311] 8342280: Deprecate for removal java.awt.AWTPermission Reviewed-by: azvegint, kizune --- .../share/classes/java/awt/AWTPermission.java | 3 +++ .../classes/java/awt/doc-files/Modality.html | 17 +---------------- 2 files changed, 4 insertions(+), 16 deletions(-) diff --git a/src/java.desktop/share/classes/java/awt/AWTPermission.java b/src/java.desktop/share/classes/java/awt/AWTPermission.java index 53a5ebfa204..87ef53d1481 100644 --- a/src/java.desktop/share/classes/java/awt/AWTPermission.java +++ b/src/java.desktop/share/classes/java/awt/AWTPermission.java @@ -37,6 +37,7 @@ * @apiNote * This permission cannot be used for controlling access to resources * as the Security Manager is no longer supported. + * Consequently this class is deprecated for removal in a future release. * * @see java.security.BasicPermission * @see java.security.Permission @@ -46,7 +47,9 @@ * * @author Marianne Mueller * @author Roland Schemers + * @deprecated There is no replacement for this class. */ +@Deprecated(since="24", forRemoval=true) public final class AWTPermission extends BasicPermission { /** diff --git a/src/java.desktop/share/classes/java/awt/doc-files/Modality.html b/src/java.desktop/share/classes/java/awt/doc-files/Modality.html index 88f9911cbc3..c9aa3e146a3 100644 --- a/src/java.desktop/share/classes/java/awt/doc-files/Modality.html +++ b/src/java.desktop/share/classes/java/awt/doc-files/Modality.html @@ -46,7 +46,6 @@ <h1>The AWT Modality</h1> <li><a href="#ShowHideBlocking">Show/hide blocking</a></li> <li><a href="#ModalExclusion">Modal exclusion</a></li> <li><a href="#Related">Related AWT features</a></li> - <li><a href="#Security">Security</a></li> <li><a href="#PlatformSupport">Platform support</a></li> <li><a href="#Compatibility">Compatibility</a></li> <li><a href="#Examples">Examples</a></li> @@ -128,7 +127,6 @@ <h2>Modality types</h2> so a toolkit-modal dialog shown from an applet may affect other applets and all windows of the browser instance which embeds the Java runtime environment for this toolkit. - See the security section below. </li></ol> <p> Modality priority is arranged by the strength of blocking: modeless, @@ -331,21 +329,8 @@ <h2>Related AWT features</h2> If the modal dialog to be hidden does not have focus, the active window remains unchanged. - <a id="Security"></a> - <h2>Security</h2> - - <p> - A special <code>AWTPermission</code>, <code>"toolkitModality"</code>, - is required to show toolkit-modal - dialogs. This would prevent, for example, blocking a browser or - Java Web Start (JWS) by modal dialogs shown from applets. - </p><p> - The same permission is required to exclude a window from toolkit modality. - This would prevent, for example, a dialog shown from an applet not to be - blocked by a browser's or JWS's modal dialog. - <a id="PlatformSupport"></a> - </p><h2>Platform support</h2> + <h2>Platform support</h2> <p> Two <code>java.awt.Toolkit</code> methods allow you to check whether From f51363e0277210d2b2f6cdb4d2bf6c732a02c76a Mon Sep 17 00:00:00 2001 From: Ioi Lam <iklam@openjdk.org> Date: Thu, 28 Nov 2024 01:15:15 +0000 Subject: [PATCH 293/311] 8344913: Improve -Xlog:cds+map+oop logging for Java mirrors Reviewed-by: dholmes, ccheung --- src/hotspot/share/cds/archiveBuilder.cpp | 96 ++++++++++++++++--- .../jtreg/runtime/cds/CDSMapReader.java | 6 +- 2 files changed, 87 insertions(+), 15 deletions(-) diff --git a/src/hotspot/share/cds/archiveBuilder.cpp b/src/hotspot/share/cds/archiveBuilder.cpp index 36a17813d32..1cd9d13c3ba 100644 --- a/src/hotspot/share/cds/archiveBuilder.cpp +++ b/src/hotspot/share/cds/archiveBuilder.cpp @@ -1294,10 +1294,15 @@ class ArchiveBuilder::CDSMapLogger : AllStatic { if (source_oop != nullptr) { // This is a regular oop that got archived. - print_oop_with_requested_addr_cr(&st, source_oop, false); + // Don't print the requested addr again as we have just printed it at the beginning of the line. + // Example: + // 0x00000007ffd27938: @@ Object (0xfffa4f27) java.util.HashMap + print_oop_info_cr(&st, source_oop, /*print_requested_addr=*/false); byte_size = source_oop->size() * BytesPerWord; } else if ((byte_size = ArchiveHeapWriter::get_filler_size_at(start)) > 0) { // We have a filler oop, which also does not exist in BufferOffsetToSourceObjectTable. + // Example: + // 0x00000007ffc3ffd8: @@ Object filler 40 bytes st.print_cr("filler " SIZE_FORMAT " bytes", byte_size); } else { ShouldNotReachHere(); @@ -1315,7 +1320,7 @@ class ArchiveBuilder::CDSMapLogger : AllStatic { // ArchivedFieldPrinter is used to print the fields of archived objects. We can't // use _source_obj->print_on(), because we want to print the oop fields - // in _source_obj with their requested addresses using print_oop_with_requested_addr_cr(). + // in _source_obj with their requested addresses using print_oop_info_cr(). class ArchivedFieldPrinter : public FieldClosure { ArchiveHeapInfo* _heap_info; outputStream* _st; @@ -1331,8 +1336,14 @@ class ArchiveBuilder::CDSMapLogger : AllStatic { switch (ft) { case T_ARRAY: case T_OBJECT: - fd->print_on(_st); // print just the name and offset - print_oop_with_requested_addr_cr(_st, _source_obj->obj_field(fd->offset())); + { + fd->print_on(_st); // print just the name and offset + oop obj = _source_obj->obj_field(fd->offset()); + if (java_lang_Class::is_instance(obj)) { + obj = HeapShared::scratch_java_mirror(obj); + } + print_oop_info_cr(_st, obj); + } break; default: if (ArchiveHeapWriter::is_marked_as_native_pointer(_heap_info, _source_obj, fd->offset())) { @@ -1388,14 +1399,54 @@ class ArchiveBuilder::CDSMapLogger : AllStatic { objArrayOop source_obj_array = objArrayOop(source_oop); for (int i = 0; i < source_obj_array->length(); i++) { st.print(" -%4d: ", i); - print_oop_with_requested_addr_cr(&st, source_obj_array->obj_at(i)); + oop obj = source_obj_array->obj_at(i); + if (java_lang_Class::is_instance(obj)) { + obj = HeapShared::scratch_java_mirror(obj); + } + print_oop_info_cr(&st, obj); } } else { st.print_cr(" - fields (" SIZE_FORMAT " words):", source_oop->size()); ArchivedFieldPrinter print_field(heap_info, &st, source_oop, buffered_addr); InstanceKlass::cast(source_klass)->print_nonstatic_fields(&print_field); + + if (java_lang_Class::is_instance(source_oop)) { + oop scratch_mirror = source_oop; + st.print(" - signature: "); + print_class_signature_for_mirror(&st, scratch_mirror); + st.cr(); + + Klass* src_klass = java_lang_Class::as_Klass(scratch_mirror); + if (src_klass != nullptr && src_klass->is_instance_klass()) { + oop rr = HeapShared::scratch_resolved_references(InstanceKlass::cast(src_klass)->constants()); + st.print(" - archived_resolved_references: "); + print_oop_info_cr(&st, rr); + + // We need to print the fields in the scratch_mirror, not the original mirror. + // (if a class is not aot-initialized, static fields in its scratch mirror will be cleared). + assert(scratch_mirror == HeapShared::scratch_java_mirror(src_klass->java_mirror()), "sanity"); + st.print_cr("- ---- static fields (%d):", java_lang_Class::static_oop_field_count(scratch_mirror)); + InstanceKlass::cast(src_klass)->do_local_static_fields(&print_field); + } + } + } + } + } + + static void print_class_signature_for_mirror(outputStream* st, oop scratch_mirror) { + assert(java_lang_Class::is_instance(scratch_mirror), "sanity"); + if (java_lang_Class::is_primitive(scratch_mirror)) { + for (int i = T_BOOLEAN; i < T_VOID+1; i++) { + BasicType bt = (BasicType)i; + if (!is_reference_type(bt) && scratch_mirror == HeapShared::scratch_java_mirror(bt)) { + oop orig_mirror = Universe::java_mirror(bt); + java_lang_Class::print_signature(orig_mirror, st); + return; + } } + ShouldNotReachHere(); } + java_lang_Class::print_signature(scratch_mirror, st); } static void log_heap_roots() { @@ -1403,22 +1454,23 @@ class ArchiveBuilder::CDSMapLogger : AllStatic { if (st.is_enabled()) { for (int i = 0; i < HeapShared::pending_roots()->length(); i++) { st.print("roots[%4d]: ", i); - print_oop_with_requested_addr_cr(&st, HeapShared::pending_roots()->at(i)); + print_oop_info_cr(&st, HeapShared::pending_roots()->at(i)); } } } - // The output looks like this. The first number is the requested address. The second number is - // the narrowOop version of the requested address. - // 0x00000007ffc7e840 (0xfff8fd08) java.lang.Class + // Example output: + // - The first number is the requested address (if print_requested_addr == true) + // - The second number is the narrowOop version of the requested address (if UseCompressedOops == true) + // 0x00000007ffc7e840 (0xfff8fd08) java.lang.Class Ljava/util/Array; // 0x00000007ffc000f8 (0xfff8001f) [B length: 11 - static void print_oop_with_requested_addr_cr(outputStream* st, oop source_oop, bool print_addr = true) { + static void print_oop_info_cr(outputStream* st, oop source_oop, bool print_requested_addr = true) { if (source_oop == nullptr) { st->print_cr("null"); } else { ResourceMark rm; oop requested_obj = ArchiveHeapWriter::source_obj_to_requested_obj(source_oop); - if (print_addr) { + if (print_requested_addr) { st->print(PTR_FORMAT " ", p2i(requested_obj)); } if (UseCompressedOops) { @@ -1428,7 +1480,27 @@ class ArchiveBuilder::CDSMapLogger : AllStatic { int array_len = arrayOop(source_oop)->length(); st->print_cr("%s length: %d", source_oop->klass()->external_name(), array_len); } else { - st->print_cr("%s", source_oop->klass()->external_name()); + st->print("%s", source_oop->klass()->external_name()); + + if (java_lang_String::is_instance(source_oop)) { + st->print(" "); + java_lang_String::print(source_oop, st); + } else if (java_lang_Class::is_instance(source_oop)) { + oop scratch_mirror = source_oop; + + st->print(" "); + print_class_signature_for_mirror(st, scratch_mirror); + + Klass* src_klass = java_lang_Class::as_Klass(scratch_mirror); + if (src_klass != nullptr && src_klass->is_instance_klass()) { + InstanceKlass* buffered_klass = + ArchiveBuilder::current()->get_buffered_addr(InstanceKlass::cast(src_klass)); + if (buffered_klass->has_aot_initialized_mirror()) { + st->print(" (aot-inited)"); + } + } + } + st->cr(); } } } diff --git a/test/hotspot/jtreg/runtime/cds/CDSMapReader.java b/test/hotspot/jtreg/runtime/cds/CDSMapReader.java index 98532163136..f9fc4c222cb 100644 --- a/test/hotspot/jtreg/runtime/cds/CDSMapReader.java +++ b/test/hotspot/jtreg/runtime/cds/CDSMapReader.java @@ -38,7 +38,7 @@ The map file contains patterns like this for the heap objects: ====================================================================== -0x00000000ffe00000: @@ Object (0xffe00000) java.lang.String +0x00000000ffe00000: @@ Object (0xffe00000) java.lang.String "" - klass: 'java/lang/String' 0x0000000800010220 - fields (3 words): - private 'hash' 'I' @12 0 (0x00000000) @@ -149,11 +149,11 @@ public static class Field { // (one address) // 0x00000007ffc00000: @@ Object java.lang.String - static Pattern objPattern1 = Pattern.compile("^0x([0-9a-f]+): @@ Object (.*)"); + static Pattern objPattern1 = Pattern.compile("^0x([0-9a-f]+): @@ Object ([^ ]*)"); // (two addresses) // 0x00000007ffc00000: @@ Object (0xfff80000) java.lang.String - static Pattern objPattern2 = Pattern.compile("^0x([0-9a-f]+): @@ Object [(]0x([0-9a-f]+)[)] (.*)"); + static Pattern objPattern2 = Pattern.compile("^0x([0-9a-f]+): @@ Object [(]0x([0-9a-f]+)[)] ([^ ]*)"); // - klass: 'java/lang/String' 0x0000000800010290 static Pattern instanceObjKlassPattern = Pattern.compile("^ - klass: '([^']+)' 0x([0-9a-f]+)"); From 8485cb1ca1fa4885ddaf8381ebf862bbb233f090 Mon Sep 17 00:00:00 2001 From: Ioi Lam <iklam@openjdk.org> Date: Thu, 28 Nov 2024 01:20:27 +0000 Subject: [PATCH 294/311] 8344822: CDS BulkLoaderTest.java#dynamic fails with COH Reviewed-by: dholmes, ccheung --- .../aotClassLinking/BulkLoaderTest.java | 6 +-- .../cds/appcds/applications/JavacBench.java | 4 +- test/lib/jdk/test/lib/cds/CDSAppTester.java | 38 ++++++++++++++++++- 3 files changed, 42 insertions(+), 6 deletions(-) diff --git a/test/hotspot/jtreg/runtime/cds/appcds/aotClassLinking/BulkLoaderTest.java b/test/hotspot/jtreg/runtime/cds/appcds/aotClassLinking/BulkLoaderTest.java index 49544f50032..6e7473c59c1 100644 --- a/test/hotspot/jtreg/runtime/cds/appcds/aotClassLinking/BulkLoaderTest.java +++ b/test/hotspot/jtreg/runtime/cds/appcds/aotClassLinking/BulkLoaderTest.java @@ -41,9 +41,10 @@ * @requires vm.cds.supports.aot.class.linking * @library /test/jdk/lib/testlibrary /test/lib * @build InitiatingLoaderTester - * @build BulkLoaderTest + * @build jdk.test.whitebox.WhiteBox BulkLoaderTest * @run driver jdk.test.lib.helpers.ClassFileInstaller -jar BulkLoaderTestApp.jar BulkLoaderTestApp MyUtil InitiatingLoaderTester - * @run driver BulkLoaderTest DYNAMIC + * @run driver jdk.test.lib.helpers.ClassFileInstaller jdk.test.whitebox.WhiteBox + * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xbootclasspath/a:. BulkLoaderTest DYNAMIC */ import java.io.File; @@ -80,7 +81,6 @@ public static void main(String[] args) throws Exception { // Run without archived FMG -- fail to load { String extraVmArgs[] = { - "-Xshare:on", "-Xlog:cds", "-Djdk.module.showModuleResolution=true" }; diff --git a/test/hotspot/jtreg/runtime/cds/appcds/applications/JavacBench.java b/test/hotspot/jtreg/runtime/cds/appcds/applications/JavacBench.java index 50696c8c1fc..a95119f1a47 100644 --- a/test/hotspot/jtreg/runtime/cds/appcds/applications/JavacBench.java +++ b/test/hotspot/jtreg/runtime/cds/appcds/applications/JavacBench.java @@ -35,7 +35,9 @@ * @summary Run JavacBenchApp with the classic dynamic archive workflow * @requires vm.cds * @library /test/lib - * @run driver JavacBench DYNAMIC + * @build jdk.test.whitebox.WhiteBox + * @run driver jdk.test.lib.helpers.ClassFileInstaller jdk.test.whitebox.WhiteBox + * @run main/othervm -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI -Xbootclasspath/a:. JavacBench DYNAMIC */ import jdk.test.lib.cds.CDSAppTester; diff --git a/test/lib/jdk/test/lib/cds/CDSAppTester.java b/test/lib/jdk/test/lib/cds/CDSAppTester.java index d83c3c36e41..3a2fc1e1f69 100644 --- a/test/lib/jdk/test/lib/cds/CDSAppTester.java +++ b/test/lib/jdk/test/lib/cds/CDSAppTester.java @@ -28,6 +28,7 @@ import jdk.test.lib.process.ProcessTools; import jdk.test.lib.process.OutputAnalyzer; import jdk.test.lib.StringArrayUtils; +import jdk.test.whitebox.WhiteBox; import jtreg.SkippedException; /* @@ -43,6 +44,7 @@ abstract public class CDSAppTester { private final String staticArchiveFileLog; private final String dynamicArchiveFile; private final String dynamicArchiveFileLog; + private final String tempBaseArchiveFile; private int numProductionRuns = 0; public CDSAppTester(String name) { @@ -58,6 +60,7 @@ public CDSAppTester(String name) { staticArchiveFileLog = staticArchiveFile + ".log"; dynamicArchiveFile = name() + ".dynamic.jsa"; dynamicArchiveFileLog = dynamicArchiveFile + ".log"; + tempBaseArchiveFile = name() + ".temp-base.jsa"; } private String productionRunLog() { @@ -189,9 +192,37 @@ private OutputAnalyzer dumpStaticArchive() throws Exception { return executeAndCheck(cmdLine, runMode, staticArchiveFile, staticArchiveFileLog); } + // Creating a dynamic CDS archive (with -XX:ArchiveClassesAtExit=<foo>.jsa) requires that the current + // JVM process is using a static archive (which is usually the default CDS archive included in the JDK). + // However, if the JDK doesn't include a default CDS archive that's compatible with the set of + // VM options used by this test, we need to create a temporary static archive to be used with -XX:ArchiveClassesAtExit. + private String getBaseArchiveForDynamicArchive() throws Exception { + WhiteBox wb = WhiteBox.getWhiteBox(); + if (wb.isSharingEnabled()) { + // This current JVM is able to use a default CDS archive included by the JDK, so + // if we launch a JVM child process (with the same set of options as the current JVM), + // that process is also able to use the same default CDS archive for creating + // a dynamic archive. + return null; + } else { + // This current JVM is unable to use a default CDS archive, so let's create a temporary + // static archive to be used with -XX:ArchiveClassesAtExit. + File f = new File(tempBaseArchiveFile); + if (!f.exists()) { + CDSOptions opts = new CDSOptions(); + opts.setArchiveName(tempBaseArchiveFile); + opts.addSuffix("-Djava.class.path="); + OutputAnalyzer out = CDSTestUtils.createArchive(opts); + CDSTestUtils.checkBaseDump(out); + } + return tempBaseArchiveFile; + } + } + private OutputAnalyzer dumpDynamicArchive() throws Exception { RunMode runMode = RunMode.DUMP_DYNAMIC; String[] cmdLine = new String[0]; + String baseArchive = getBaseArchiveForDynamicArchive(); if (isDynamicWorkflow()) { // "classic" dynamic archive cmdLine = StringArrayUtils.concat(vmArgs(runMode), @@ -204,6 +235,9 @@ private OutputAnalyzer dumpDynamicArchive() throws Exception { "cds+resolve=debug", "class+load=debug")); } + if (baseArchive != null) { + cmdLine = StringArrayUtils.concat(cmdLine, "-XX:SharedArchiveFile=" + baseArchive); + } cmdLine = StringArrayUtils.concat(cmdLine, appCommandLine(runMode)); return executeAndCheck(cmdLine, runMode, dynamicArchiveFile, dynamicArchiveFileLog); } @@ -227,9 +261,9 @@ public OutputAnalyzer productionRun(String[] extraVmArgs, String[] extraAppArgs) logToFile(productionRunLog(), "cds")); if (isStaticWorkflow()) { - cmdLine = StringArrayUtils.concat(cmdLine, "-XX:SharedArchiveFile=" + staticArchiveFile); + cmdLine = StringArrayUtils.concat(cmdLine, "-Xshare:on", "-XX:SharedArchiveFile=" + staticArchiveFile); } else if (isDynamicWorkflow()) { - cmdLine = StringArrayUtils.concat(cmdLine, "-XX:SharedArchiveFile=" + dynamicArchiveFile); + cmdLine = StringArrayUtils.concat(cmdLine, "-Xshare:on", "-XX:SharedArchiveFile=" + dynamicArchiveFile); } if (extraVmArgs != null) { From a0df0a527fc3a6954fc08651947a5cfe1455e652 Mon Sep 17 00:00:00 2001 From: Amit Kumar <amitkumar@openjdk.org> Date: Thu, 28 Nov 2024 02:05:45 +0000 Subject: [PATCH 295/311] 8340731: Cleanup remaining IA64 references in hotspot code Reviewed-by: dholmes, aph --- src/hotspot/os/bsd/os_bsd.cpp | 6 +--- src/hotspot/os/linux/hugepages.cpp | 3 +- src/hotspot/os/linux/os_linux.cpp | 33 ++++++------------- src/hotspot/os/posix/signals_posix.cpp | 7 ---- src/hotspot/share/opto/chaitin.cpp | 1 - src/hotspot/share/opto/generateOptoStub.cpp | 4 --- src/hotspot/share/opto/memnode.hpp | 4 +-- src/hotspot/share/opto/output.cpp | 2 +- .../share/runtime/abstract_vm_version.cpp | 1 - src/hotspot/share/runtime/deoptimization.cpp | 6 +--- src/hotspot/share/runtime/frame.hpp | 7 ++-- src/hotspot/share/runtime/javaCalls.cpp | 5 --- src/hotspot/share/runtime/os.hpp | 3 +- src/hotspot/share/runtime/relocator.cpp | 2 +- .../share/utilities/elfFuncDescTable.cpp | 5 ++- .../share/utilities/elfFuncDescTable.hpp | 5 ++- src/hotspot/share/utilities/macros.hpp | 12 ------- 17 files changed, 25 insertions(+), 81 deletions(-) diff --git a/src/hotspot/os/bsd/os_bsd.cpp b/src/hotspot/os/bsd/os_bsd.cpp index a1887aa5975..8185797563c 100644 --- a/src/hotspot/os/bsd/os_bsd.cpp +++ b/src/hotspot/os/bsd/os_bsd.cpp @@ -229,8 +229,6 @@ size_t os::rss() { // Cpu architecture string #if defined(ZERO) static char cpu_arch[] = ZERO_LIBARCH; -#elif defined(IA64) -static char cpu_arch[] = "ia64"; #elif defined(IA32) static char cpu_arch[] = "i386"; #elif defined(AMD64) @@ -1192,8 +1190,6 @@ void * os::dll_load(const char *filename, char *ebuf, int ebuflen) { static Elf32_Half running_arch_code=EM_386; #elif (defined AMD64) static Elf32_Half running_arch_code=EM_X86_64; - #elif (defined IA64) - static Elf32_Half running_arch_code=EM_IA_64; #elif (defined __powerpc64__) static Elf32_Half running_arch_code=EM_PPC64; #elif (defined __powerpc__) @@ -1214,7 +1210,7 @@ void * os::dll_load(const char *filename, char *ebuf, int ebuflen) { static Elf32_Half running_arch_code=EM_68K; #else #error Method os::dll_load requires that one of following is defined:\ - IA32, AMD64, IA64, __powerpc__, ARM, S390, ALPHA, MIPS, MIPSEL, PARISC, M68K + IA32, AMD64, __powerpc__, ARM, S390, ALPHA, MIPS, MIPSEL, PARISC, M68K #endif // Identify compatibility class for VM's architecture and library's architecture diff --git a/src/hotspot/os/linux/hugepages.cpp b/src/hotspot/os/linux/hugepages.cpp index b71593487cf..c04ff7a4ca0 100644 --- a/src/hotspot/os/linux/hugepages.cpp +++ b/src/hotspot/os/linux/hugepages.cpp @@ -55,8 +55,7 @@ static size_t scan_default_hugepagesize() { // large_page_size on Linux is used to round up heap size. x86 uses either // 2M or 4M page, depending on whether PAE (Physical Address Extensions) - // mode is enabled. AMD64/EM64T uses 2M page in 64bit mode. IA64 can use - // page as large as 1G. + // mode is enabled. AMD64/EM64T uses 2M page in 64bit mode. // // Here we try to figure out page size by parsing /proc/meminfo and looking // for a line with the following format: diff --git a/src/hotspot/os/linux/os_linux.cpp b/src/hotspot/os/linux/os_linux.cpp index b2b9a798119..d51ca8a5ffb 100644 --- a/src/hotspot/os/linux/os_linux.cpp +++ b/src/hotspot/os/linux/os_linux.cpp @@ -461,26 +461,17 @@ bool os::Linux::get_tick_information(CPUPerfTicks* pticks, int which_logical_cpu } #ifndef SYS_gettid -// i386: 224, ia64: 1105, amd64: 186, sparc: 143 - #ifdef __ia64__ - #define SYS_gettid 1105 +// i386: 224, amd64: 186, sparc: 143 + #if defined(__i386__) + #define SYS_gettid 224 + #elif defined(__amd64__) + #define SYS_gettid 186 + #elif defined(__sparc__) + #define SYS_gettid 143 #else - #ifdef __i386__ - #define SYS_gettid 224 - #else - #ifdef __amd64__ - #define SYS_gettid 186 - #else - #ifdef __sparc__ - #define SYS_gettid 143 - #else - #error define gettid for the arch - #endif - #endif - #endif + #error "Define SYS_gettid for this architecture" #endif -#endif - +#endif // SYS_gettid // pid_t gettid() // @@ -1778,8 +1769,6 @@ void * os::dll_load(const char *filename, char *ebuf, int ebuflen) { static Elf32_Half running_arch_code=EM_386; #elif (defined AMD64) || (defined X32) static Elf32_Half running_arch_code=EM_X86_64; -#elif (defined IA64) - static Elf32_Half running_arch_code=EM_IA_64; #elif (defined __sparc) && (defined _LP64) static Elf32_Half running_arch_code=EM_SPARCV9; #elif (defined __sparc) && (!defined _LP64) @@ -1812,7 +1801,7 @@ void * os::dll_load(const char *filename, char *ebuf, int ebuflen) { static Elf32_Half running_arch_code=EM_LOONGARCH; #else #error Method os::dll_load requires that one of following is defined:\ - AARCH64, ALPHA, ARM, AMD64, IA32, IA64, LOONGARCH64, M68K, MIPS, MIPSEL, PARISC, __powerpc__, __powerpc64__, RISCV, S390, SH, __sparc + AARCH64, ALPHA, ARM, AMD64, IA32, LOONGARCH64, M68K, MIPS, MIPSEL, PARISC, __powerpc__, __powerpc64__, RISCV, S390, SH, __sparc #endif // Identify compatibility class for VM's architecture and library's architecture @@ -2719,8 +2708,6 @@ void os::get_summary_cpu_info(char* cpuinfo, size_t length) { strncpy(cpuinfo, "ARM", length); #elif defined(IA32) strncpy(cpuinfo, "x86_32", length); -#elif defined(IA64) - strncpy(cpuinfo, "IA64", length); #elif defined(PPC) strncpy(cpuinfo, "PPC64", length); #elif defined(RISCV) diff --git a/src/hotspot/os/posix/signals_posix.cpp b/src/hotspot/os/posix/signals_posix.cpp index bbf122fabfb..ddc7a05c2ff 100644 --- a/src/hotspot/os/posix/signals_posix.cpp +++ b/src/hotspot/os/posix/signals_posix.cpp @@ -960,10 +960,6 @@ static bool get_signal_code_description(const siginfo_t* si, enum_sigcode_desc_t { SIGILL, ILL_PRVREG, "ILL_PRVREG", "Privileged register." }, { SIGILL, ILL_COPROC, "ILL_COPROC", "Coprocessor error." }, { SIGILL, ILL_BADSTK, "ILL_BADSTK", "Internal stack error." }, -#if defined(IA64) && defined(LINUX) - { SIGILL, ILL_BADIADDR, "ILL_BADIADDR", "Unimplemented instruction address" }, - { SIGILL, ILL_BREAK, "ILL_BREAK", "Application Break instruction" }, -#endif { SIGFPE, FPE_INTDIV, "FPE_INTDIV", "Integer divide by zero." }, { SIGFPE, FPE_INTOVF, "FPE_INTOVF", "Integer overflow." }, { SIGFPE, FPE_FLTDIV, "FPE_FLTDIV", "Floating-point divide by zero." }, @@ -977,9 +973,6 @@ static bool get_signal_code_description(const siginfo_t* si, enum_sigcode_desc_t #if defined(AIX) // no explanation found what keyerr would be { SIGSEGV, SEGV_KEYERR, "SEGV_KEYERR", "key error" }, -#endif -#if defined(IA64) && !defined(AIX) - { SIGSEGV, SEGV_PSTKOVF, "SEGV_PSTKOVF", "Paragraph stack overflow" }, #endif { SIGBUS, BUS_ADRALN, "BUS_ADRALN", "Invalid address alignment." }, { SIGBUS, BUS_ADRERR, "BUS_ADRERR", "Nonexistent physical address." }, diff --git a/src/hotspot/share/opto/chaitin.cpp b/src/hotspot/share/opto/chaitin.cpp index 6252e31d898..c9d1491afc5 100644 --- a/src/hotspot/share/opto/chaitin.cpp +++ b/src/hotspot/share/opto/chaitin.cpp @@ -956,7 +956,6 @@ void PhaseChaitin::gather_lrg_masks( bool after_aggressive ) { // Each entry is reg_pressure_per_value,number_of_regs // RegL RegI RegFlags RegF RegD INTPRESSURE FLOATPRESSURE // IA32 2 1 1 1 1 6 6 - // IA64 1 1 1 1 1 50 41 // SPARC 2 2 2 2 2 48 (24) 52 (26) // SPARCV9 2 2 2 2 2 48 (24) 52 (26) // AMD64 1 1 1 1 1 14 15 diff --git a/src/hotspot/share/opto/generateOptoStub.cpp b/src/hotspot/share/opto/generateOptoStub.cpp index 2e3dc878c84..b6f09dcc439 100644 --- a/src/hotspot/share/opto/generateOptoStub.cpp +++ b/src/hotspot/share/opto/generateOptoStub.cpp @@ -224,10 +224,6 @@ void GraphKit::gen_stub(address C_function, store_to_memory(control(), adr_sp, null(), T_ADDRESS, MemNode::unordered); // Clear last_Java_pc store_to_memory(control(), adr_last_Java_pc, null(), T_ADDRESS, MemNode::unordered); -#if (defined(IA64) && !defined(AIX)) - Node* adr_last_Java_fp = basic_plus_adr(top(), thread, in_bytes(JavaThread::last_Java_fp_offset())); - store_to_memory(control(), adr_last_Java_fp, null(), T_ADDRESS, MemNode::unordered); -#endif // For is-fancy-jump, the C-return value is also the branch target Node* target = map()->in(TypeFunc::Parms); diff --git a/src/hotspot/share/opto/memnode.hpp b/src/hotspot/share/opto/memnode.hpp index 83ac80c043f..ee9db7d1cac 100644 --- a/src/hotspot/share/opto/memnode.hpp +++ b/src/hotspot/share/opto/memnode.hpp @@ -196,7 +196,7 @@ class LoadNode : public MemNode { // non-pinned LoadNode by the pinned LoadNode. ControlDependency _control_dependency; - // On platforms with weak memory ordering (e.g., PPC, Ia64) we distinguish + // On platforms with weak memory ordering (e.g., PPC) we distinguish // loads that can be reordered, and such requiring acquire semantics to // adhere to the Java specification. The required behaviour is stored in // this field. @@ -566,7 +566,7 @@ class LoadNKlassNode : public LoadNNode { // Store value; requires Store, Address and Value class StoreNode : public MemNode { private: - // On platforms with weak memory ordering (e.g., PPC, Ia64) we distinguish + // On platforms with weak memory ordering (e.g., PPC) we distinguish // stores that can be reordered, and such requiring release semantics to // adhere to the Java specification. The required behaviour is stored in // this field. diff --git a/src/hotspot/share/opto/output.cpp b/src/hotspot/share/opto/output.cpp index fa781bf23a6..ee91dc4323a 100644 --- a/src/hotspot/share/opto/output.cpp +++ b/src/hotspot/share/opto/output.cpp @@ -383,7 +383,7 @@ bool PhaseOutput::need_stack_bang(int frame_size_in_bytes) const { bool PhaseOutput::need_register_stack_bang() const { // Determine if we need to generate a register stack overflow check. // This is only used on architectures which have split register - // and memory stacks (ie. IA64). + // and memory stacks. // Bang if the method is not a stub function and has java calls return (C->stub_function() == nullptr && C->has_java_calls()); } diff --git a/src/hotspot/share/runtime/abstract_vm_version.cpp b/src/hotspot/share/runtime/abstract_vm_version.cpp index 96da109dafe..590d164366b 100644 --- a/src/hotspot/share/runtime/abstract_vm_version.cpp +++ b/src/hotspot/share/runtime/abstract_vm_version.cpp @@ -187,7 +187,6 @@ const char* Abstract_VM_Version::vm_release() { #define CPU AARCH64_ONLY("aarch64") \ AMD64_ONLY("amd64") \ IA32_ONLY("x86") \ - IA64_ONLY("ia64") \ S390_ONLY("s390") \ RISCV64_ONLY("riscv64") #endif // !ZERO diff --git a/src/hotspot/share/runtime/deoptimization.cpp b/src/hotspot/share/runtime/deoptimization.cpp index 10fd83750d4..1558f3c9bce 100644 --- a/src/hotspot/share/runtime/deoptimization.cpp +++ b/src/hotspot/share/runtime/deoptimization.cpp @@ -607,9 +607,6 @@ Deoptimization::UnrollBlock* Deoptimization::fetch_unroll_info_helper(JavaThread // where it will be very difficult to figure out what went wrong. Better // to die an early death here than some very obscure death later when the // trail is cold. - // Note: on ia64 this guarantee can be fooled by frames with no memory stack - // in that it will fail to detect a problem when there is one. This needs - // more work in tiger timeframe. guarantee(array->unextended_sp() == unpack_sp, "vframe_array_head must contain the vframeArray to unpack"); int number_of_frames = array->frames(); @@ -2342,8 +2339,7 @@ JRT_ENTRY(void, Deoptimization::uncommon_trap_inner(JavaThread* current, jint tr } // Setting +ProfileTraps fixes the following, on all platforms: - // 4852688: ProfileInterpreter is off by default for ia64. The result is - // infinite heroic-opt-uncommon-trap/deopt/recompile cycles, since the + // The result is infinite heroic-opt-uncommon-trap/deopt/recompile cycles, since the // recompile relies on a MethodData* to record heroic opt failures. // Whether the interpreter is producing MDO data or not, we also need diff --git a/src/hotspot/share/runtime/frame.hpp b/src/hotspot/share/runtime/frame.hpp index fe531cff8a6..0363d7305d2 100644 --- a/src/hotspot/share/runtime/frame.hpp +++ b/src/hotspot/share/runtime/frame.hpp @@ -164,10 +164,9 @@ class frame { void patch_pc(Thread* thread, address pc); // Every frame needs to return a unique id which distinguishes it from all other frames. - // For sparc and ia32 use sp. ia64 can have memory frames that are empty so multiple frames - // will have identical sp values. For ia64 the bsp (fp) value will serve. No real frame - // should have an id() of null so it is a distinguishing value for an unmatchable frame. - // We also have relationals which allow comparing a frame to anoth frame's id() allow + // For sparc and ia32 use sp. + // No real frame should have an id() of null so it is a distinguishing value for an unmatchable frame. + // We also have relationals which allow comparing a frame to another frame's id() allowing // us to distinguish younger (more recent activation) from older (less recent activations) // A null id is only valid when comparing for equality. diff --git a/src/hotspot/share/runtime/javaCalls.cpp b/src/hotspot/share/runtime/javaCalls.cpp index b3b7b6f6834..e8f647fe484 100644 --- a/src/hotspot/share/runtime/javaCalls.cpp +++ b/src/hotspot/share/runtime/javaCalls.cpp @@ -116,11 +116,6 @@ JavaCallWrapper::~JavaCallWrapper() { ThreadStateTransition::transition_from_java(_thread, _thread_in_vm); // State has been restored now make the anchor frame visible for the profiler. - // Do this after the transition because this allows us to put an assert - // the Java->vm transition which checks to see that stack is not walkable - // on sparc/ia64 which will catch violations of the resetting of last_Java_frame - // invariants (i.e. _flags always cleared on return to Java) - _thread->frame_anchor()->copy(&_anchor); // Release handles after we are marked as being inside the VM again, since this diff --git a/src/hotspot/share/runtime/os.hpp b/src/hotspot/share/runtime/os.hpp index 8e4a214b691..0bc543957c9 100644 --- a/src/hotspot/share/runtime/os.hpp +++ b/src/hotspot/share/runtime/os.hpp @@ -859,8 +859,7 @@ class os: AllStatic { // We don't attempt to become a debugger, so we only follow frames if that // does not require a lookup in the unwind table, which is part of the binary // file but may be unsafe to read after a fatal error. So on x86, we can - // only walk stack if %ebp is used as frame pointer; on ia64, it's not - // possible to walk C stack without having the unwind table. + // only walk stack if %ebp is used as frame pointer. static bool is_first_C_frame(frame *fr); static frame get_sender_for_C_frame(frame *fr); diff --git a/src/hotspot/share/runtime/relocator.cpp b/src/hotspot/share/runtime/relocator.cpp index 5b5ff2b83e6..dc244ce920d 100644 --- a/src/hotspot/share/runtime/relocator.cpp +++ b/src/hotspot/share/runtime/relocator.cpp @@ -200,7 +200,7 @@ bool Relocator::handle_code_changes() { bool Relocator::is_opcode_lookupswitch(Bytecodes::Code bc) { switch (bc) { case Bytecodes::_tableswitch: return false; - case Bytecodes::_lookupswitch: // not rewritten on ia64 + case Bytecodes::_lookupswitch: case Bytecodes::_fast_linearswitch: // rewritten _lookupswitch case Bytecodes::_fast_binaryswitch: return true; // rewritten _lookupswitch default: ShouldNotReachHere(); diff --git a/src/hotspot/share/utilities/elfFuncDescTable.cpp b/src/hotspot/share/utilities/elfFuncDescTable.cpp index bd9beb202c6..d23a1da68f4 100644 --- a/src/hotspot/share/utilities/elfFuncDescTable.cpp +++ b/src/hotspot/share/utilities/elfFuncDescTable.cpp @@ -34,11 +34,10 @@ ElfFuncDescTable::ElfFuncDescTable(FILE* file, Elf_Shdr shdr, int index) : _section(file, shdr), _file(file), _index(index) { assert(file, "null file handle"); // The actual function address (i.e. function entry point) is always the - // first value in the function descriptor (on IA64 and PPC64 they look as follows): + // first value in the function descriptor (on PPC64 they look as follows): // PPC64: [function entry point, TOC pointer, environment pointer] - // IA64 : [function entry point, GP (global pointer) value] // Unfortunately 'shdr.sh_entsize' doesn't always seem to contain this size (it's zero on PPC64) so we can't assert - // assert(IA64_ONLY(2) PPC64_ONLY(3) * sizeof(address) == shdr.sh_entsize, "Size mismatch for '.opd' section entries"); + // assert(PPC64_ONLY(3) * sizeof(address) == shdr.sh_entsize, "Size mismatch for '.opd' section entries"); _status = _section.status(); } diff --git a/src/hotspot/share/utilities/elfFuncDescTable.hpp b/src/hotspot/share/utilities/elfFuncDescTable.hpp index a0e67611554..daba24ee626 100644 --- a/src/hotspot/share/utilities/elfFuncDescTable.hpp +++ b/src/hotspot/share/utilities/elfFuncDescTable.hpp @@ -35,9 +35,8 @@ /* -On PowerPC-64 (and other architectures like for example IA64) a pointer to a -function is not just a plain code address, but instead a pointer to a so called -function descriptor (which is simply a structure containing 3 pointers). +On PowerPC-64 a pointer to a function is not just a plain code address, but instead a pointer +to a so-called function descriptor (which is simply a structure containing 3 pointers). This fact is also reflected in the ELF ABI for PowerPC-64. On architectures like x86 or SPARC, the ELF symbol table contains the start diff --git a/src/hotspot/share/utilities/macros.hpp b/src/hotspot/share/utilities/macros.hpp index 23094c9e8c4..b14905ff8e2 100644 --- a/src/hotspot/share/utilities/macros.hpp +++ b/src/hotspot/share/utilities/macros.hpp @@ -458,18 +458,6 @@ #define NOT_IA32(code) code #endif -// This is a REALLY BIG HACK, but on AIX <sys/systemcfg.h> unconditionally defines IA64. -// At least on AIX 7.1 this is a real problem because 'systemcfg.h' is indirectly included -// by 'pthread.h' and other common system headers. - -#if defined(IA64) && !defined(AIX) -#define IA64_ONLY(code) code -#define NOT_IA64(code) -#else -#define IA64_ONLY(code) -#define NOT_IA64(code) code -#endif - #ifdef AMD64 #define AMD64_ONLY(code) code #define NOT_AMD64(code) From 1a07d542ec810282eb78653698d098a24b35686f Mon Sep 17 00:00:00 2001 From: David Holmes <dholmes@openjdk.org> Date: Thu, 28 Nov 2024 02:24:55 +0000 Subject: [PATCH 296/311] 8343703: Symbol name cleanups after JEP 479 Reviewed-by: kbarrett, amenkov --- src/hotspot/share/include/jvm.h | 7 --- src/hotspot/share/prims/jvmtiAgent.cpp | 39 +++++++-------- src/hotspot/share/runtime/os.cpp | 32 ++++-------- src/hotspot/share/runtime/os.hpp | 6 +-- .../share/native/libjava/NativeLibraries.c | 50 +++++++------------ 5 files changed, 46 insertions(+), 88 deletions(-) diff --git a/src/hotspot/share/include/jvm.h b/src/hotspot/share/include/jvm.h index bc46a2cf852..474d5baa487 100644 --- a/src/hotspot/share/include/jvm.h +++ b/src/hotspot/share/include/jvm.h @@ -1147,13 +1147,6 @@ JVM_GetClassFileVersion(JNIEnv *env, jclass current); JNIEXPORT jboolean JNICALL JVM_PrintWarningAtDynamicAgentLoad(void); -#define JNI_ONLOAD_SYMBOLS {"JNI_OnLoad"} -#define JNI_ONUNLOAD_SYMBOLS {"JNI_OnUnload"} -#define JVM_ONLOAD_SYMBOLS {"JVM_OnLoad"} -#define AGENT_ONLOAD_SYMBOLS {"Agent_OnLoad"} -#define AGENT_ONUNLOAD_SYMBOLS {"Agent_OnUnload"} -#define AGENT_ONATTACH_SYMBOLS {"Agent_OnAttach"} - /* * This structure is used by the launcher to get the default thread * stack size from the VM using JNI_GetDefaultJavaVMInitArgs() with a diff --git a/src/hotspot/share/prims/jvmtiAgent.cpp b/src/hotspot/share/prims/jvmtiAgent.cpp index 6dd205082a0..06702773d58 100644 --- a/src/hotspot/share/prims/jvmtiAgent.cpp +++ b/src/hotspot/share/prims/jvmtiAgent.cpp @@ -27,7 +27,6 @@ #include "cds/cds_globals.hpp" #include "cds/cdsConfig.hpp" #include "jni.h" -#include "jvm.h" #include "jvm_io.h" #include "jvmtifiles/jvmtiEnv.hpp" #include "prims/jvmtiEnvBase.hpp" @@ -268,10 +267,10 @@ static void assert_preload(const JvmtiAgent* agent) { // For statically linked agents we can't rely on os_lib == nullptr because // statically linked agents could have a handle of RTLD_DEFAULT which == 0 on some platforms. // If this function returns true, then agent->is_static_lib() && agent->is_loaded(). -static bool load_agent_from_executable(JvmtiAgent* agent, const char* on_load_symbols[], size_t num_symbol_entries) { +static bool load_agent_from_executable(JvmtiAgent* agent, const char* on_load_symbol) { DEBUG_ONLY(assert_preload(agent);) - assert(on_load_symbols != nullptr, "invariant"); - return os::find_builtin_agent(agent, &on_load_symbols[0], num_symbol_entries); + assert(on_load_symbol != nullptr, "invariant"); + return os::find_builtin_agent(agent, on_load_symbol); } // Load the library from the absolute path of the agent, if available. @@ -310,7 +309,7 @@ static void* load_agent_from_relative_path(JvmtiAgent* agent, bool vm_exit_on_er } // For absolute and relative paths. -static void* load_library(JvmtiAgent* agent, const char* on_symbols[], size_t num_symbol_entries, bool vm_exit_on_error) { +static void* load_library(JvmtiAgent* agent, bool vm_exit_on_error) { return agent->is_absolute_path() ? load_agent_from_absolute_path(agent, vm_exit_on_error) : load_agent_from_relative_path(agent, vm_exit_on_error); } @@ -321,12 +320,11 @@ extern "C" { } // Find the OnLoad entry point for -agentlib: -agentpath: -Xrun agents. -// num_symbol_entries must be passed-in since only the caller knows the number of symbols in the array. -static OnLoadEntry_t lookup_On_Load_entry_point(JvmtiAgent* agent, const char* on_load_symbols[], size_t num_symbol_entries) { +static OnLoadEntry_t lookup_On_Load_entry_point(JvmtiAgent* agent, const char* on_load_symbol) { assert(agent != nullptr, "invariant"); if (!agent->is_loaded()) { - if (!load_agent_from_executable(agent, on_load_symbols, num_symbol_entries)) { - void* const library = load_library(agent, on_load_symbols, num_symbol_entries, /* vm exit on error */ true); + if (!load_agent_from_executable(agent, on_load_symbol)) { + void* const library = load_library(agent, /* vm exit on error */ true); assert(library != nullptr, "invariant"); agent->set_os_lib(library); agent->set_loaded(); @@ -334,17 +332,15 @@ static OnLoadEntry_t lookup_On_Load_entry_point(JvmtiAgent* agent, const char* o } assert(agent->is_loaded(), "invariant"); // Find the OnLoad function. - return CAST_TO_FN_PTR(OnLoadEntry_t, os::find_agent_function(agent, false, on_load_symbols, num_symbol_entries)); + return CAST_TO_FN_PTR(OnLoadEntry_t, os::find_agent_function(agent, false, on_load_symbol)); } static OnLoadEntry_t lookup_JVM_OnLoad_entry_point(JvmtiAgent* lib) { - const char* on_load_symbols[] = JVM_ONLOAD_SYMBOLS; - return lookup_On_Load_entry_point(lib, on_load_symbols, sizeof(on_load_symbols) / sizeof(char*)); + return lookup_On_Load_entry_point(lib, "JVM_OnLoad"); } static OnLoadEntry_t lookup_Agent_OnLoad_entry_point(JvmtiAgent* agent) { - const char* on_load_symbols[] = AGENT_ONLOAD_SYMBOLS; - return lookup_On_Load_entry_point(agent, on_load_symbols, sizeof(on_load_symbols) / sizeof(char*)); + return lookup_On_Load_entry_point(agent, "Agent_OnLoad"); } void JvmtiAgent::convert_xrun_agent() { @@ -499,14 +495,13 @@ static bool invoke_Agent_OnAttach(JvmtiAgent* agent, outputStream* st) { assert(agent->is_dynamic(), "invariant"); assert(st != nullptr, "invariant"); assert(JvmtiEnvBase::get_phase() == JVMTI_PHASE_LIVE, "not in live phase!"); - const char* on_attach_symbols[] = AGENT_ONATTACH_SYMBOLS; - const size_t num_symbol_entries = ARRAY_SIZE(on_attach_symbols); + const char* on_attach_symbol = "Agent_OnAttach"; void* library = nullptr; bool previously_loaded; - if (load_agent_from_executable(agent, &on_attach_symbols[0], num_symbol_entries)) { + if (load_agent_from_executable(agent, on_attach_symbol)) { previously_loaded = JvmtiAgentList::is_static_lib_loaded(agent->name()); } else { - library = load_library(agent, &on_attach_symbols[0], num_symbol_entries, /* vm_exit_on_error */ false); + library = load_library(agent, /* vm_exit_on_error */ false); if (library == nullptr) { st->print_cr("%s was not loaded.", agent->name()); if (*ebuf != '\0') { @@ -531,10 +526,10 @@ static bool invoke_Agent_OnAttach(JvmtiAgent* agent, outputStream* st) { assert(agent->is_loaded(), "invariant"); // The library was loaded so we attempt to lookup and invoke the Agent_OnAttach function. OnAttachEntry_t on_attach_entry = CAST_TO_FN_PTR(OnAttachEntry_t, - os::find_agent_function(agent, false, &on_attach_symbols[0], num_symbol_entries)); + os::find_agent_function(agent, false, on_attach_symbol)); if (on_attach_entry == nullptr) { - st->print_cr("%s is not available in %s", on_attach_symbols[0], agent->name()); + st->print_cr("%s is not available in %s", on_attach_symbol, agent->name()); unload_library(agent, library); return false; } @@ -629,10 +624,10 @@ extern "C" { } void JvmtiAgent::unload() { - const char* on_unload_symbols[] = AGENT_ONUNLOAD_SYMBOLS; + const char* on_unload_symbol = "Agent_OnUnload"; // Find the Agent_OnUnload function. Agent_OnUnload_t unload_entry = CAST_TO_FN_PTR(Agent_OnUnload_t, - os::find_agent_function(this, false, &on_unload_symbols[0], ARRAY_SIZE(on_unload_symbols))); + os::find_agent_function(this, false, on_unload_symbol)); if (unload_entry != nullptr) { // Invoke the Agent_OnUnload function JavaThread* thread = JavaThread::current(); diff --git a/src/hotspot/share/runtime/os.cpp b/src/hotspot/share/runtime/os.cpp index d8e539ca115..deb2c30500c 100644 --- a/src/hotspot/share/runtime/os.cpp +++ b/src/hotspot/share/runtime/os.cpp @@ -546,49 +546,35 @@ void* os::native_java_library() { * executable if agent_lib->is_static_lib() == true or in the shared library * referenced by 'handle'. */ -void* os::find_agent_function(JvmtiAgent *agent_lib, bool check_lib, - const char *syms[], size_t syms_len) { +void* os::find_agent_function(JvmtiAgent *agent_lib, bool check_lib, const char *sym) { assert(agent_lib != nullptr, "sanity check"); - const char *lib_name; void *handle = agent_lib->os_lib(); void *entryName = nullptr; - char *agent_function_name; - size_t i; // If checking then use the agent name otherwise test is_static_lib() to // see how to process this lookup - lib_name = ((check_lib || agent_lib->is_static_lib()) ? agent_lib->name() : nullptr); - for (i = 0; i < syms_len; i++) { - agent_function_name = build_agent_function_name(syms[i], lib_name, agent_lib->is_absolute_path()); - if (agent_function_name == nullptr) { - break; - } + const char *lib_name = ((check_lib || agent_lib->is_static_lib()) ? agent_lib->name() : nullptr); + + char* agent_function_name = build_agent_function_name(sym, lib_name, agent_lib->is_absolute_path()); + if (agent_function_name != nullptr) { entryName = dll_lookup(handle, agent_function_name); FREE_C_HEAP_ARRAY(char, agent_function_name); - if (entryName != nullptr) { - break; - } } return entryName; } // See if the passed in agent is statically linked into the VM image. -bool os::find_builtin_agent(JvmtiAgent* agent, const char *syms[], - size_t syms_len) { - void *ret; - void *proc_handle; - void *save_handle; - +bool os::find_builtin_agent(JvmtiAgent* agent, const char* sym) { assert(agent != nullptr, "sanity check"); if (agent->name() == nullptr) { return false; } - proc_handle = get_default_process_handle(); + void* proc_handle = get_default_process_handle(); // Check for Agent_OnLoad/Attach_lib_name function - save_handle = agent->os_lib(); + void* save_handle = agent->os_lib(); // We want to look in this process' symbol table. agent->set_os_lib(proc_handle); - ret = find_agent_function(agent, true, syms, syms_len); + void* ret = find_agent_function(agent, true, sym); if (ret != nullptr) { // Found an entry point like Agent_OnLoad_lib_name so we have a static agent agent->set_static_lib(); diff --git a/src/hotspot/share/runtime/os.hpp b/src/hotspot/share/runtime/os.hpp index 0bc543957c9..2e52440ead4 100644 --- a/src/hotspot/share/runtime/os.hpp +++ b/src/hotspot/share/runtime/os.hpp @@ -777,12 +777,10 @@ class os: AllStatic { static void* get_default_process_handle(); // Check for static linked agent library - static bool find_builtin_agent(JvmtiAgent *agent_lib, const char *syms[], - size_t syms_len); + static bool find_builtin_agent(JvmtiAgent* agent_lib, const char* sym); // Find agent entry point - static void *find_agent_function(JvmtiAgent *agent_lib, bool check_lib, - const char *syms[], size_t syms_len); + static void* find_agent_function(JvmtiAgent* agent_lib, bool check_lib, const char* sym); // Provide wrapper versions of these functions to guarantee NUL-termination // in all cases. diff --git a/src/java.base/share/native/libjava/NativeLibraries.c b/src/java.base/share/native/libjava/NativeLibraries.c index df5ff343d61..b6624eccd1d 100644 --- a/src/java.base/share/native/libjava/NativeLibraries.c +++ b/src/java.base/share/native/libjava/NativeLibraries.c @@ -64,45 +64,31 @@ static jboolean initIDs(JNIEnv *env) */ static void *findJniFunction(JNIEnv *env, void *handle, const char *cname, jboolean isLoad) { - const char *onLoadSymbols[] = JNI_ONLOAD_SYMBOLS; - const char *onUnloadSymbols[] = JNI_ONUNLOAD_SYMBOLS; - const char **syms; - int symsLen; + const char *sym; void *entryName = NULL; char *jniFunctionName; - int i; size_t len; // Check for JNI_On(Un)Load<_libname> function - if (isLoad) { - syms = onLoadSymbols; - symsLen = sizeof(onLoadSymbols) / sizeof(char *); - } else { - syms = onUnloadSymbols; - symsLen = sizeof(onUnloadSymbols) / sizeof(char *); + sym = isLoad ? "JNI_OnLoad" : "JNI_OnUnload"; + + // sym + '_' + cname + '\0' + if ((len = strlen(sym) + (cname != NULL ? (strlen(cname) + 1) : 0) + 1) > + FILENAME_MAX) { + goto done; } - for (i = 0; i < symsLen; i++) { - // cname + sym + '_' + '\0' - if ((len = (cname != NULL ? strlen(cname) : 0) + strlen(syms[i]) + 2) > - FILENAME_MAX) { - goto done; - } - jniFunctionName = malloc(len); - if (jniFunctionName == NULL) { - JNU_ThrowOutOfMemoryError(env, NULL); - goto done; - } - strcpy(jniFunctionName, syms[i]); - if (cname != NULL) { - strcat(jniFunctionName, "_"); - strcat(jniFunctionName, cname); - } - entryName = JVM_FindLibraryEntry(handle, jniFunctionName); - free(jniFunctionName); - if(entryName) { - break; - } + jniFunctionName = malloc(len); + if (jniFunctionName == NULL) { + JNU_ThrowOutOfMemoryError(env, NULL); + goto done; + } + strcpy(jniFunctionName, sym); + if (cname != NULL) { + strcat(jniFunctionName, "_"); + strcat(jniFunctionName, cname); } + entryName = JVM_FindLibraryEntry(handle, jniFunctionName); + free(jniFunctionName); done: return entryName; From ce9d543eb1bf26592320fae650fe15638d6d30cf Mon Sep 17 00:00:00 2001 From: Quan Anh Mai <qamai@openjdk.org> Date: Thu, 28 Nov 2024 06:57:51 +0000 Subject: [PATCH 297/311] 8345119: Some java/foreign tests wrongly assume aligned memory Reviewed-by: mcimadamore, jvernee --- test/jdk/java/foreign/TestByteBuffer.java | 28 +++++++++---------- .../jdk/java/foreign/TestDereferencePath.java | 4 +-- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/test/jdk/java/foreign/TestByteBuffer.java b/test/jdk/java/foreign/TestByteBuffer.java index 77b3dd3b105..a77f97018ca 100644 --- a/test/jdk/java/foreign/TestByteBuffer.java +++ b/test/jdk/java/foreign/TestByteBuffer.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -171,7 +171,7 @@ static <Z extends Buffer> void checkBytes(MemorySegment base, SequenceLayout lay @Test public void testOffheap() { try (Arena arena = Arena.ofConfined()) { - MemorySegment segment = arena.allocate(tuples);; + MemorySegment segment = arena.allocate(tuples); initTuples(segment, tuples.elementCount()); ByteBuffer bb = segment.asByteBuffer(); @@ -385,7 +385,7 @@ static void checkByteArrayAlignment(MemoryLayout layout) { public void testScopedBuffer(Function<ByteBuffer, Buffer> bufferFactory, @NoInjection Method method, Object[] args) { Buffer bb; try (Arena arena = Arena.ofConfined()) { - MemorySegment segment = arena.allocate(bytes);; + MemorySegment segment = arena.allocate(bytes); bb = bufferFactory.apply(segment.asByteBuffer()); } //outside of session!! @@ -411,7 +411,7 @@ public void testScopedBuffer(Function<ByteBuffer, Buffer> bufferFactory, @NoInje public void testScopedBufferAndVarHandle(VarHandle bufferHandle) { ByteBuffer bb; try (Arena arena = Arena.ofConfined()) { - MemorySegment segment = arena.allocate(bytes);; + MemorySegment segment = arena.allocate(bytes, Long.BYTES); bb = segment.asByteBuffer(); for (Map.Entry<MethodHandle, Object[]> e : varHandleMembers(bb, bufferHandle).entrySet()) { MethodHandle handle = e.getKey().bindTo(bufferHandle) @@ -445,7 +445,7 @@ public void testScopedBufferAndVarHandle(VarHandle bufferHandle) { @Test(dataProvider = "bufferOps") public void testDirectBuffer(Function<ByteBuffer, Buffer> bufferFactory, @NoInjection Method method, Object[] args) { try (Arena arena = Arena.ofConfined()) { - MemorySegment segment = arena.allocate(bytes);; + MemorySegment segment = arena.allocate(bytes); Buffer bb = bufferFactory.apply(segment.asByteBuffer()); assertTrue(bb.isDirect()); DirectBuffer directBuffer = ((DirectBuffer)bb); @@ -458,7 +458,7 @@ public void testDirectBuffer(Function<ByteBuffer, Buffer> bufferFactory, @NoInje @Test(dataProvider="resizeOps") public void testResizeOffheap(Consumer<MemorySegment> checker, Consumer<MemorySegment> initializer, SequenceLayout seq) { try (Arena arena = Arena.ofConfined()) { - MemorySegment segment = arena.allocate(seq);; + MemorySegment segment = arena.allocate(seq); initializer.accept(segment); checker.accept(segment); } @@ -496,7 +496,7 @@ public void testResizeRoundtripHeap(Consumer<MemorySegment> checker, Consumer<Me @Test(dataProvider="resizeOps") public void testResizeRoundtripNative(Consumer<MemorySegment> checker, Consumer<MemorySegment> initializer, SequenceLayout seq) { try (Arena arena = Arena.ofConfined()) { - MemorySegment segment = arena.allocate(seq);; + MemorySegment segment = arena.allocate(seq); initializer.accept(segment); MemorySegment second = MemorySegment.ofBuffer(segment.asByteBuffer()); checker.accept(second); @@ -507,7 +507,7 @@ public void testResizeRoundtripNative(Consumer<MemorySegment> checker, Consumer< public void testBufferOnClosedSession() { MemorySegment leaked; try (Arena arena = Arena.ofConfined()) { - leaked = arena.allocate(bytes);; + leaked = arena.allocate(bytes); } ByteBuffer byteBuffer = leaked.asByteBuffer(); // ok byteBuffer.get(); // should throw @@ -615,7 +615,7 @@ public void testCopyHeapToNative(Consumer<MemorySegment> checker, Consumer<Memor checkByteArrayAlignment(seq.elementLayout()); int bytes = (int)seq.byteSize(); try (Arena arena = Arena.ofConfined()) { - MemorySegment nativeArray = arena.allocate(bytes, 1);; + MemorySegment nativeArray = arena.allocate(bytes, 1); MemorySegment heapArray = MemorySegment.ofArray(new byte[bytes]); initializer.accept(heapArray); nativeArray.copyFrom(heapArray); @@ -628,7 +628,7 @@ public void testCopyNativeToHeap(Consumer<MemorySegment> checker, Consumer<Memor checkByteArrayAlignment(seq.elementLayout()); int bytes = (int)seq.byteSize(); try (Arena arena = Arena.ofConfined()) { - MemorySegment nativeArray = arena.allocate(seq);; + MemorySegment nativeArray = arena.allocate(seq); MemorySegment heapArray = MemorySegment.ofArray(new byte[bytes]); initializer.accept(nativeArray); heapArray.copyFrom(nativeArray); @@ -700,7 +700,7 @@ public void bufferProperties(ByteBuffer bb, Predicate<MemorySegment> _unused) { @Test public void testRoundTripAccess() { try (Arena arena = Arena.ofConfined()) { - MemorySegment ms = arena.allocate(4, 1);; + MemorySegment ms = arena.allocate(4, 1); MemorySegment msNoAccess = ms.asReadOnly(); MemorySegment msRoundTrip = MemorySegment.ofBuffer(msNoAccess.asByteBuffer()); assertEquals(msRoundTrip.scope(), ms.scope()); @@ -741,7 +741,7 @@ public void closeableArenas(Supplier<Arena> arenaSupplier) throws IOException { tmp.deleteOnExit(); try (FileChannel channel = FileChannel.open(tmp.toPath(), StandardOpenOption.READ, StandardOpenOption.WRITE) ; Arena arena = arenaSupplier.get()) { - MemorySegment segment = arena.allocate(10, 1);; + MemorySegment segment = arena.allocate(10, 1); for (int i = 0; i < 10; i++) { segment.set(JAVA_BYTE, i, (byte) i); } @@ -780,7 +780,7 @@ public void testIOOnClosedSegmentBuffer(Supplier<Arena> arenaSupplier) throws IO @Test public void buffersAndArraysFromSlices() { try (Arena arena = Arena.ofShared()) { - MemorySegment segment = arena.allocate(16, 1);; + MemorySegment segment = arena.allocate(16, 1); int newSize = 8; var slice = segment.asSlice(4, newSize); @@ -798,7 +798,7 @@ public void buffersAndArraysFromSlices() { @Test public void viewsFromSharedSegment() { try (Arena arena = Arena.ofShared()) { - MemorySegment segment = arena.allocate(16, 1);; + MemorySegment segment = arena.allocate(16, 1); var byteBuffer = segment.asByteBuffer(); byteBuffer.asReadOnlyBuffer(); byteBuffer.slice(0, 8); diff --git a/test/jdk/java/foreign/TestDereferencePath.java b/test/jdk/java/foreign/TestDereferencePath.java index 116f2d318fc..e2281cde235 100644 --- a/test/jdk/java/foreign/TestDereferencePath.java +++ b/test/jdk/java/foreign/TestDereferencePath.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -173,7 +173,7 @@ void badDerefMisAligned() { ValueLayout.ADDRESS.withTargetLayout(ValueLayout.JAVA_INT).withName("x")); try (Arena arena = Arena.ofConfined()) { - MemorySegment segment = arena.allocate(struct.byteSize() + 1).asSlice(1); + MemorySegment segment = arena.allocate(struct.byteSize() + 1, struct.byteAlignment()).asSlice(1); VarHandle vhX = struct.varHandle(PathElement.groupElement("x"), PathElement.dereferenceElement()); vhX.set(segment, 0L, 42); // should throw } From 81c44e5eb469ceed555a982e65feefcfde340a0b Mon Sep 17 00:00:00 2001 From: Jaikiran Pai <jpai@openjdk.org> Date: Thu, 28 Nov 2024 07:54:00 +0000 Subject: [PATCH 298/311] 8344908: URLClassPath should not propagate IllegalArgumentException when finding resources in classpath URLs Reviewed-by: alanb --- .../jdk/internal/loader/URLClassPath.java | 6 +- .../share/classes/sun/net/www/ParseUtil.java | 1 + .../jdk/internal/loader/FileURLMapper.java | 27 ++- .../jdk/internal/loader/FileURLMapper.java | 25 ++- .../URLClassPath/ClassPathUnusableURLs.java | 188 ++++++++++++++++++ 5 files changed, 225 insertions(+), 22 deletions(-) create mode 100644 test/jdk/jdk/internal/loader/URLClassPath/ClassPathUnusableURLs.java diff --git a/src/java.base/share/classes/jdk/internal/loader/URLClassPath.java b/src/java.base/share/classes/jdk/internal/loader/URLClassPath.java index 75418111f74..06e3442c244 100644 --- a/src/java.base/share/classes/jdk/internal/loader/URLClassPath.java +++ b/src/java.base/share/classes/jdk/internal/loader/URLClassPath.java @@ -903,7 +903,11 @@ private static class FileLoader extends Loader { private FileLoader(URL url) throws IOException { super(url); String path = url.getFile().replace('/', File.separatorChar); - path = ParseUtil.decode(path); + try { + path = ParseUtil.decode(path); + } catch (IllegalArgumentException iae) { + throw new IOException(iae); + } dir = (new File(path)).getCanonicalFile(); @SuppressWarnings("deprecation") var _unused = normalizedBase = new URL(getBaseURL(), "."); diff --git a/src/java.base/share/classes/sun/net/www/ParseUtil.java b/src/java.base/share/classes/sun/net/www/ParseUtil.java index def688ad96a..3a35f86ab88 100644 --- a/src/java.base/share/classes/sun/net/www/ParseUtil.java +++ b/src/java.base/share/classes/sun/net/www/ParseUtil.java @@ -171,6 +171,7 @@ private static byte unescape(String s, int i) { * Returns a new String constructed from the specified String by replacing * the URL escape sequences and UTF8 encoding with the characters they * represent. + * @throws IllegalArgumentException if {@code s} could not be decoded */ public static String decode(String s) { int n = s.length(); diff --git a/src/java.base/unix/classes/jdk/internal/loader/FileURLMapper.java b/src/java.base/unix/classes/jdk/internal/loader/FileURLMapper.java index 6507b2961b9..79d0c6faf5b 100644 --- a/src/java.base/unix/classes/jdk/internal/loader/FileURLMapper.java +++ b/src/java.base/unix/classes/jdk/internal/loader/FileURLMapper.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2003, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,8 +25,10 @@ package jdk.internal.loader; +import java.io.IOException; import java.net.URL; import java.io.File; + import sun.net.www.ParseUtil; /** @@ -40,12 +42,12 @@ * @author Michael McMahon */ -public class FileURLMapper { +final class FileURLMapper { - URL url; - String path; + private final URL url; + private String path; - public FileURLMapper (URL url) { + FileURLMapper(URL url) { this.url = url; } @@ -53,15 +55,18 @@ public FileURLMapper (URL url) { * @return the platform specific path corresponding to the URL * so long as the URL does not contain a hostname in the authority field. */ - - public String getPath () { + String getPath() throws IOException { if (path != null) { return path; } String host = url.getHost(); if (host == null || host.isEmpty() || "localhost".equalsIgnoreCase(host)) { path = url.getFile(); - path = ParseUtil.decode(path); + try { + path = ParseUtil.decode(path); + } catch (IllegalArgumentException iae) { + throw new IOException(iae); + } } return path; } @@ -69,12 +74,12 @@ public String getPath () { /** * Checks whether the file identified by the URL exists. */ - public boolean exists () { - String s = getPath (); + boolean exists() throws IOException { + String s = getPath(); if (s == null) { return false; } else { - File f = new File (s); + File f = new File(s); return f.exists(); } } diff --git a/src/java.base/windows/classes/jdk/internal/loader/FileURLMapper.java b/src/java.base/windows/classes/jdk/internal/loader/FileURLMapper.java index 0053cf70e9d..b72bc31b206 100644 --- a/src/java.base/windows/classes/jdk/internal/loader/FileURLMapper.java +++ b/src/java.base/windows/classes/jdk/internal/loader/FileURLMapper.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2003, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,8 +25,10 @@ package jdk.internal.loader; +import java.io.IOException; import java.net.URL; import java.io.File; + import sun.net.www.ParseUtil; /** @@ -36,12 +38,12 @@ * @author Michael McMahon */ -public class FileURLMapper { +final class FileURLMapper { - URL url; - String file; + private final URL url; + private String file; - public FileURLMapper (URL url) { + FileURLMapper (URL url) { this.url = url; } @@ -49,8 +51,7 @@ public FileURLMapper (URL url) { * @return the platform specific path corresponding to the URL, and in particular * returns a UNC when the authority contains a hostname */ - - public String getPath () { + String getPath() throws IOException { if (file != null) { return file; } @@ -63,13 +64,17 @@ public String getPath () { return file; } String path = url.getFile().replace('/', '\\'); - file = ParseUtil.decode(path); + try { + file = ParseUtil.decode(path); + } catch (IllegalArgumentException iae) { + throw new IOException(iae); + } return file; } - public boolean exists() { + boolean exists() throws IOException { String path = getPath(); - File f = new File (path); + File f = new File(path); return f.exists(); } } diff --git a/test/jdk/jdk/internal/loader/URLClassPath/ClassPathUnusableURLs.java b/test/jdk/jdk/internal/loader/URLClassPath/ClassPathUnusableURLs.java new file mode 100644 index 00000000000..420425f37fc --- /dev/null +++ b/test/jdk/jdk/internal/loader/URLClassPath/ClassPathUnusableURLs.java @@ -0,0 +1,188 @@ +/* + * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +import java.io.OutputStream; +import java.net.URL; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.Arrays; +import java.util.Enumeration; +import java.util.jar.JarEntry; +import java.util.jar.JarOutputStream; +import java.util.jar.Manifest; + +import jdk.internal.loader.Resource; +import jdk.internal.loader.URLClassPath; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; +import static java.nio.charset.StandardCharsets.US_ASCII; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assumptions.abort; + +/* + * @test + * @bug 8344908 + * @summary verify that when locating resources, the URLClassPath can function properly + * without throwing unexpected exceptions when any URL in the classpath is unusable + * @modules java.base/jdk.internal.loader + * @run junit ClassPathUnusableURLs + */ +public class ClassPathUnusableURLs { + + private static final Path SCRATCH_DIR = Path.of(".").normalize(); + private static final String RESOURCE_NAME = "foo.txt"; + private static final String SMILEY_EMOJI = "\uD83D\uDE00"; + + private static Path ASCII_DIR; + private static Path EMOJI_DIR; + private static Path JAR_FILE_IN_EMOJI_DIR; + private static int NUM_EXPECTED_LOCATED_RESOURCES; + + + @BeforeAll + static void beforeAll() throws Exception { + try { + EMOJI_DIR = Files.createTempDirectory(SCRATCH_DIR, SMILEY_EMOJI); + } catch (IllegalArgumentException iae) { + iae.printStackTrace(); // for debug purpose + // if we can't create a directory with an emoji in its path name, + // then skip the entire test + abort("Skipping test since emoji directory couldn't be created: " + iae); + } + // successful creation of the dir, continue with the test + Files.createFile(EMOJI_DIR.resolve(RESOURCE_NAME)); + + ASCII_DIR = Files.createTempDirectory(SCRATCH_DIR, "test-urlclasspath"); + Files.createFile(ASCII_DIR.resolve(RESOURCE_NAME)); + + // create a jar file containing the resource + JAR_FILE_IN_EMOJI_DIR = Files.createTempDirectory(SCRATCH_DIR, SMILEY_EMOJI) + .resolve("foo.jar"); + final Manifest manifest = new Manifest(); + manifest.getMainAttributes().putValue("Manifest-Version", "1.0"); + try (OutputStream fos = Files.newOutputStream(JAR_FILE_IN_EMOJI_DIR); + JarOutputStream jos = new JarOutputStream(fos, manifest)) { + + final JarEntry jarEntry = new JarEntry(RESOURCE_NAME); + jos.putNextEntry(jarEntry); + jos.write("hello".getBytes(US_ASCII)); + jos.closeEntry(); + } + // Even if the resource is present in more than one classpath element, + // we expect it to be found by the URLClassPath only in the path which has just ascii + // characters. URLClassPath currently doesn't have the ability to serve resources + // from paths containing emoji character(s). + NUM_EXPECTED_LOCATED_RESOURCES = 1; + } + + /** + * Constructs a URLClassPath and then exercises the URLClassPath.findResource() + * and URLClassPath.findResources() methods and expects them to return the expected + * resources. + */ + @Test + void testFindResource() { + // start an empty URL classpath + final URLClassPath urlc = new URLClassPath(new URL[0]); + final String[] classpathElements = getClassPathElements(); + try { + // use addFile() to construct classpath + for (final String path : classpathElements) { + urlc.addFile(path); + } + // findResource() + assertNotNull(urlc.findResource(RESOURCE_NAME), "findResource() failed to locate" + + " resource: " + RESOURCE_NAME + " in classpath: " + + Arrays.toString(classpathElements)); + // findResources() + final Enumeration<URL> locatedResources = urlc.findResources(RESOURCE_NAME); + assertNotNull(locatedResources, "findResources() failed to" + + " locate resource: " + RESOURCE_NAME + " in classpath: " + + Arrays.toString(classpathElements)); + int numFound = 0; + while (locatedResources.hasMoreElements()) { + System.out.println("located " + locatedResources.nextElement() + + " for resource " + RESOURCE_NAME); + numFound++; + } + assertEquals(NUM_EXPECTED_LOCATED_RESOURCES, numFound, + "unexpected number of resources located for " + RESOURCE_NAME); + } finally { + urlc.closeLoaders(); + } + } + + /** + * Constructs a URLClassPath and then exercises the URLClassPath.getResource() + * and URLClassPath.getResources() methods and expects them to return the expected + * resources. + */ + @Test + void testGetResource() { + // start an empty URL classpath + final URLClassPath urlc = new URLClassPath(new URL[0]); + final String[] classpathElements = getClassPathElements(); + try { + // use addFile() to construct classpath + for (final String path : classpathElements) { + urlc.addFile(path); + } + // getResource() + assertNotNull(urlc.getResource(RESOURCE_NAME), "getResource() failed to locate" + + " resource: " + RESOURCE_NAME + " in classpath: " + + Arrays.toString(classpathElements)); + // getResources() + final Enumeration<Resource> locatedResources = urlc.getResources(RESOURCE_NAME); + assertNotNull(locatedResources, "getResources() failed to" + + " locate resource: " + RESOURCE_NAME + " in classpath: " + + Arrays.toString(classpathElements)); + int numFound = 0; + while (locatedResources.hasMoreElements()) { + System.out.println("located " + locatedResources.nextElement().getURL() + + " for resource " + RESOURCE_NAME); + numFound++; + } + assertEquals(NUM_EXPECTED_LOCATED_RESOURCES, numFound, + "unexpected number of resources located for " + RESOURCE_NAME); + } finally { + urlc.closeLoaders(); + } + } + + private static String[] getClassPathElements() { + // Maintain the order - in context of this test, paths with emojis + // or those which can't serve the resource should come before the + // path that can serve the resource. + return new String[]{ + // non-existent path + ASCII_DIR.resolve("non-existent").toString(), + // existing emoji dir + EMOJI_DIR.toString(), + // existing jar file in a emoji dir + JAR_FILE_IN_EMOJI_DIR.toString(), + // existing ascii dir + ASCII_DIR.toString() + }; + } +} From 103338534f71309e4cc0ba289075fab768e66cd4 Mon Sep 17 00:00:00 2001 From: Per Minborg <pminborg@openjdk.org> Date: Thu, 28 Nov 2024 07:59:48 +0000 Subject: [PATCH 299/311] 8344967: Some tests in TestFill do not use the test parameter Reviewed-by: jvernee --- test/jdk/java/foreign/TestFill.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/jdk/java/foreign/TestFill.java b/test/jdk/java/foreign/TestFill.java index e5f69587f2f..d9bde891120 100644 --- a/test/jdk/java/foreign/TestFill.java +++ b/test/jdk/java/foreign/TestFill.java @@ -87,7 +87,7 @@ void testValues(int value) { @MethodSource("sizes") void testReadOnly(int len) { try (var arena = Arena.ofConfined()) { - var segment = arena.allocate(10).asReadOnly(); + var segment = arena.allocate(len).asReadOnly(); assertThrows(IllegalArgumentException.class, () -> segment.fill(VALUE)); } } @@ -96,7 +96,7 @@ void testReadOnly(int len) { @MethodSource("sizes") void testConfinement(int len) { try (var arena = Arena.ofConfined()) { - var segment = arena.allocate(10); + var segment = arena.allocate(len); AtomicReference<RuntimeException> ex = new AtomicReference<>(); CompletableFuture<Void> future = CompletableFuture.runAsync(() -> { try { From e096660a18905bf1394d722790c5c3883e55dedc Mon Sep 17 00:00:00 2001 From: SendaoYan <syan@openjdk.org> Date: Thu, 28 Nov 2024 09:06:34 +0000 Subject: [PATCH 300/311] 8345043: [ASAN] methodMatcher.cpp report reading from a region of size 0 [-Werror=stringop-overread] Reviewed-by: kbarrett, dholmes --- src/hotspot/share/compiler/methodMatcher.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/hotspot/share/compiler/methodMatcher.cpp b/src/hotspot/share/compiler/methodMatcher.cpp index 1a0ade2fadb..0bd5cdd8501 100644 --- a/src/hotspot/share/compiler/methodMatcher.cpp +++ b/src/hotspot/share/compiler/methodMatcher.cpp @@ -219,21 +219,22 @@ bool MethodMatcher::match(Symbol* candidate, Symbol* match, Mode match_mode) con static MethodMatcher::Mode check_mode(char name[], const char*& error_msg) { int match = MethodMatcher::Exact; + size_t len = strlen(name); if (name[0] == '*') { - if (strlen(name) == 1) { + if (len == 1) { return MethodMatcher::Any; } match |= MethodMatcher::Suffix; - memmove(name, name + 1, strlen(name + 1) + 1); + memmove(name, name + 1, len); // Include terminating nul in move. + len--; } - size_t len = strlen(name); if (len > 0 && name[len - 1] == '*') { match |= MethodMatcher::Prefix; name[--len] = '\0'; } - if (strlen(name) == 0) { + if (len == 0) { error_msg = "** Not a valid pattern"; return MethodMatcher::Any; } From d791f4b98d93e5fc64e3191402cc5091e0553592 Mon Sep 17 00:00:00 2001 From: SendaoYan <syan@openjdk.org> Date: Thu, 28 Nov 2024 09:29:49 +0000 Subject: [PATCH 301/311] 8341585: Test java/foreign/TestUpcallStress.java should mark as /native Reviewed-by: luhenry, pminborg --- test/jdk/java/foreign/TestUpcallStress.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/jdk/java/foreign/TestUpcallStress.java b/test/jdk/java/foreign/TestUpcallStress.java index b7a53dd6c01..d910723b559 100644 --- a/test/jdk/java/foreign/TestUpcallStress.java +++ b/test/jdk/java/foreign/TestUpcallStress.java @@ -31,7 +31,7 @@ * @build NativeTestHelper CallGeneratorHelper TestUpcallBase * @bug 8337753 * - * @run testng/othervm/timeout=3200 + * @run testng/native/othervm/timeout=3200 * -Xcheck:jni * -XX:+IgnoreUnrecognizedVMOptions * -XX:-VerifyDependencies From 56f1e4ef0524515c7f1ad65bc3f08a0e8dd0a29a Mon Sep 17 00:00:00 2001 From: Aleksey Shipilev <shade@openjdk.org> Date: Thu, 28 Nov 2024 09:35:51 +0000 Subject: [PATCH 302/311] 8344093: Implement JEP 501: Deprecate the 32-bit x86 Port for Removal Reviewed-by: ihse, simonis, dholmes --- .github/workflows/main.yml | 22 +--------------------- doc/building.html | 7 +++---- doc/building.md | 6 ++---- make/autoconf/platform.m4 | 16 ++++++++-------- 4 files changed, 14 insertions(+), 37 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index aed03f55536..210d53be658 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -36,7 +36,7 @@ on: platforms: description: 'Platform(s) to execute on (comma separated, e.g. "linux-x64, macos, aarch64")' required: true - default: 'linux-x64, linux-x86-hs, linux-x64-variants, linux-cross-compile, alpine-linux-x64, macos-x64, macos-aarch64, windows-x64, windows-aarch64, docs' + default: 'linux-x64, linux-x64-variants, linux-cross-compile, alpine-linux-x64, macos-x64, macos-aarch64, windows-x64, windows-aarch64, docs' configure-arguments: description: 'Additional configure arguments' required: false @@ -62,7 +62,6 @@ jobs: EXCLUDED_PLATFORMS: 'alpine-linux-x64' outputs: linux-x64: ${{ steps.include.outputs.linux-x64 }} - linux-x86-hs: ${{ steps.include.outputs.linux-x86-hs }} linux-x64-variants: ${{ steps.include.outputs.linux-x64-variants }} linux-cross-compile: ${{ steps.include.outputs.linux-cross-compile }} alpine-linux-x64: ${{ steps.include.outputs.alpine-linux-x64 }} @@ -145,7 +144,6 @@ jobs: } echo "linux-x64=$(check_platform linux-x64 linux x64)" >> $GITHUB_OUTPUT - echo "linux-x86-hs=$(check_platform linux-x86-hs linux x86)" >> $GITHUB_OUTPUT echo "linux-x64-variants=$(check_platform linux-x64-variants variants)" >> $GITHUB_OUTPUT echo "linux-cross-compile=$(check_platform linux-cross-compile cross-compile)" >> $GITHUB_OUTPUT echo "alpine-linux-x64=$(check_platform alpine-linux-x64 alpine-linux x64)" >> $GITHUB_OUTPUT @@ -170,24 +168,6 @@ jobs: make-arguments: ${{ github.event.inputs.make-arguments }} if: needs.prepare.outputs.linux-x64 == 'true' - build-linux-x86-hs: - name: linux-x86-hs - needs: prepare - uses: ./.github/workflows/build-linux.yml - with: - platform: linux-x86 - make-target: 'hotspot' - gcc-major-version: '10' - gcc-package-suffix: '-multilib' - apt-architecture: 'i386' - # Some multilib libraries do not have proper inter-dependencies, so we have to - # install their dependencies manually. - apt-extra-packages: 'libfreetype-dev:i386 libtiff-dev:i386 libcupsimage2-dev:i386 libffi-dev:i386' - extra-conf-options: '--with-target-bits=32 --enable-fallback-linker --enable-libffi-bundling' - configure-arguments: ${{ github.event.inputs.configure-arguments }} - make-arguments: ${{ github.event.inputs.make-arguments }} - if: needs.prepare.outputs.linux-x86-hs == 'true' - build-linux-x64-hs-nopch: name: linux-x64-hs-nopch needs: prepare diff --git a/doc/building.html b/doc/building.html index 63af224584a..cd73863f879 100644 --- a/doc/building.html +++ b/doc/building.html @@ -329,8 +329,8 @@ <h3 id="building-on-x86">Building on x86</h3> <p>Even for 32-bit builds, it is recommended to use a 64-bit build machine, and instead create a 32-bit target using <code>--with-target-bits=32</code>.</p> -<p>Note: The Windows 32-bit x86 port is deprecated and may be removed in -a future release.</p> +<p>Note: The 32-bit x86 port is deprecated and may be removed in a +future release.</p> <h3 id="building-on-aarch64">Building on aarch64</h3> <p>At a minimum, a machine with 8 cores is advisable, as well as 8 GB of RAM. (The more cores to use, the more memory you need.) At least 6 GB of @@ -393,8 +393,7 @@ <h2 id="operating-system-requirements">Operating System to list successes or failures of building on different platforms.</p> <h3 id="windows">Windows</h3> <p>Windows XP is not a supported platform, but all newer Windows should -be able to build the JDK. (Note: The Windows 32-bit x86 port is -deprecated and may be removed in a future release.)</p> +be able to build the JDK.</p> <p>On Windows, it is important that you pay attention to the instructions in the <a href="#special-considerations">Special Considerations</a>.</p> diff --git a/doc/building.md b/doc/building.md index 466e8d7edf8..99bc509dc70 100644 --- a/doc/building.md +++ b/doc/building.md @@ -134,8 +134,7 @@ space is required. Even for 32-bit builds, it is recommended to use a 64-bit build machine, and instead create a 32-bit target using `--with-target-bits=32`. -Note: The Windows 32-bit x86 port is deprecated and may be removed in a future -release. +Note: The 32-bit x86 port is deprecated and may be removed in a future release. ### Building on aarch64 @@ -191,8 +190,7 @@ on different platforms. ### Windows Windows XP is not a supported platform, but all newer Windows should be able to -build the JDK. (Note: The Windows 32-bit x86 port is deprecated and may be -removed in a future release.) +build the JDK. On Windows, it is important that you pay attention to the instructions in the [Special Considerations](#special-considerations). diff --git a/make/autoconf/platform.m4 b/make/autoconf/platform.m4 index 3f977058a51..5b363e0704a 100644 --- a/make/autoconf/platform.m4 +++ b/make/autoconf/platform.m4 @@ -666,14 +666,14 @@ AC_DEFUN([PLATFORM_CHECK_DEPRECATION], [ AC_ARG_ENABLE(deprecated-ports, [AS_HELP_STRING([--enable-deprecated-ports@<:@=yes/no@:>@], [Suppress the error when configuring for a deprecated port @<:@no@:>@])]) - # if test "x$OPENJDK_TARGET_CPU" = xx86; then - # if test "x$enable_deprecated_ports" = "xyes"; then - # AC_MSG_WARN([The x86 port is deprecated and may be removed in a future release.]) - # else - # AC_MSG_ERROR(m4_normalize([The 32-bit x86 port is deprecated and may be removed in a future release. - # Use --enable-deprecated-ports=yes to suppress this error.])) - # fi - # fi + if test "x$OPENJDK_TARGET_CPU" = xx86; then + if test "x$enable_deprecated_ports" = "xyes"; then + AC_MSG_WARN([The 32-bit x86 port is deprecated and may be removed in a future release.]) + else + AC_MSG_ERROR(m4_normalize([The 32-bit x86 port is deprecated and may be removed in a future release. + Use --enable-deprecated-ports=yes to suppress this error.])) + fi + fi ]) AC_DEFUN_ONCE([PLATFORM_SETUP_OPENJDK_BUILD_OS_VERSION], From d33ad07c32f23aee799750c9964ab26d0cbe56f4 Mon Sep 17 00:00:00 2001 From: Kevin Walls <kevinw@openjdk.org> Date: Thu, 28 Nov 2024 09:54:25 +0000 Subject: [PATCH 303/311] 8334493: Remove SecurityManager Permissions infrastructure from DiagnosticCommands Reviewed-by: lmesnik, alanb, coleenp --- src/hotspot/os/linux/mallocInfoDcmd.hpp | 6 +- src/hotspot/os/linux/trimCHeapDCmd.hpp | 6 +- .../classfile/classLoaderHierarchyDCmd.hpp | 7 +- .../share/classfile/classLoaderStats.hpp | 6 - src/hotspot/share/jfr/dcmd/jfrDcmds.hpp | 30 +-- .../share/logging/logDiagnosticCommand.hpp | 5 - .../share/memory/metaspace/metaspaceDCmd.hpp | 7 +- src/hotspot/share/nmt/nmtDCmd.hpp | 7 +- .../share/services/diagnosticCommand.cpp | 3 +- .../share/services/diagnosticCommand.hpp | 175 ------------------ .../share/services/diagnosticFramework.cpp | 2 +- .../share/services/diagnosticFramework.hpp | 32 +--- src/hotspot/share/services/management.cpp | 4 - .../management/DiagnosticCommandMBean.java | 22 +-- .../internal/DiagnosticCommandImpl.java | 40 ---- .../internal/DiagnosticCommandInfo.java | 48 +---- .../libmanagement_ext/DiagnosticCommandImpl.c | 12 +- 17 files changed, 16 insertions(+), 396 deletions(-) diff --git a/src/hotspot/os/linux/mallocInfoDcmd.hpp b/src/hotspot/os/linux/mallocInfoDcmd.hpp index 9f52d83fba3..f2559fa1571 100644 --- a/src/hotspot/os/linux/mallocInfoDcmd.hpp +++ b/src/hotspot/os/linux/mallocInfoDcmd.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -41,10 +41,6 @@ class MallocInfoDcmd : public DCmd { static const char* impact() { return "Low"; } - static const JavaPermission permission() { - JavaPermission p = { "java.lang.management.ManagementPermission", "monitor", nullptr }; - return p; - } void execute(DCmdSource source, TRAPS) override; }; diff --git a/src/hotspot/os/linux/trimCHeapDCmd.hpp b/src/hotspot/os/linux/trimCHeapDCmd.hpp index 32a49798ea8..53b94f4bb56 100644 --- a/src/hotspot/os/linux/trimCHeapDCmd.hpp +++ b/src/hotspot/os/linux/trimCHeapDCmd.hpp @@ -1,6 +1,6 @@ /* * Copyright (c) 2021 SAP SE. All rights reserved. - * Copyright (c) 2021, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2021, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -42,10 +42,6 @@ class TrimCLibcHeapDCmd : public DCmd { static const char* impact() { return "Low"; } - static const JavaPermission permission() { - JavaPermission p = { "java.lang.management.ManagementPermission", "control", nullptr }; - return p; - } virtual void execute(DCmdSource source, TRAPS); }; diff --git a/src/hotspot/share/classfile/classLoaderHierarchyDCmd.hpp b/src/hotspot/share/classfile/classLoaderHierarchyDCmd.hpp index 26c765443c9..cd89c9cb978 100644 --- a/src/hotspot/share/classfile/classLoaderHierarchyDCmd.hpp +++ b/src/hotspot/share/classfile/classLoaderHierarchyDCmd.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2018 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -46,11 +46,6 @@ class ClassLoaderHierarchyDCmd: public DCmdWithParser { static const char* impact() { return "Medium: Depends on number of class loaders and classes loaded."; } - static const JavaPermission permission() { - JavaPermission p = {"java.lang.management.ManagementPermission", - "monitor", nullptr}; - return p; - } static int num_arguments() { return 3; } virtual void execute(DCmdSource source, TRAPS); diff --git a/src/hotspot/share/classfile/classLoaderStats.hpp b/src/hotspot/share/classfile/classLoaderStats.hpp index 4818ddff609..06d375b3e9b 100644 --- a/src/hotspot/share/classfile/classLoaderStats.hpp +++ b/src/hotspot/share/classfile/classLoaderStats.hpp @@ -58,12 +58,6 @@ class ClassLoaderStatsDCmd : public DCmd { static int num_arguments() { return 0; } - - static const JavaPermission permission() { - JavaPermission p = {"java.lang.management.ManagementPermission", - "monitor", nullptr}; - return p; - } }; diff --git a/src/hotspot/share/jfr/dcmd/jfrDcmds.hpp b/src/hotspot/share/jfr/dcmd/jfrDcmds.hpp index 45e1addeb87..8e7dad5a20c 100644 --- a/src/hotspot/share/jfr/dcmd/jfrDcmds.hpp +++ b/src/hotspot/share/jfr/dcmd/jfrDcmds.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -59,10 +59,6 @@ class JfrStartFlightRecordingDCmd : public JfrDCmd { static const char* impact() { return "Medium: Depending on the settings for a recording, the impact can range from low to high."; } - static const JavaPermission permission() { - JavaPermission p = {"java.lang.management.ManagementPermission", "monitor", nullptr}; - return p; - } virtual const char* javaClass() const { return "jdk/jfr/internal/dcmd/DCmdStart"; } @@ -84,10 +80,6 @@ class JfrDumpFlightRecordingDCmd : public JfrDCmd { static const char* impact() { return "Low"; } - static const JavaPermission permission() { - JavaPermission p = {"java.lang.management.ManagementPermission", "monitor", nullptr}; - return p; - } virtual const char* javaClass() const { return "jdk/jfr/internal/dcmd/DCmdDump"; } @@ -109,10 +101,6 @@ class JfrCheckFlightRecordingDCmd : public JfrDCmd { static const char* impact() { return "Low"; } - static const JavaPermission permission() { - JavaPermission p = {"java.lang.management.ManagementPermission", "monitor", nullptr}; - return p; - } virtual const char* javaClass() const { return "jdk/jfr/internal/dcmd/DCmdCheck"; } @@ -134,10 +122,6 @@ class JfrStopFlightRecordingDCmd : public JfrDCmd { static const char* impact() { return "Low"; } - static const JavaPermission permission() { - JavaPermission p = {"java.lang.management.ManagementPermission", "monitor", nullptr}; - return p; - } virtual const char* javaClass() const { return "jdk/jfr/internal/dcmd/DCmdStop"; } @@ -159,10 +143,6 @@ class JfrViewFlightRecordingDCmd : public JfrDCmd { static const char* impact() { return "Medium"; } - static const JavaPermission permission() { - JavaPermission p = {"java.lang.management.ManagementPermission", "monitor", nullptr}; - return p; - } virtual const char* javaClass() const { return "jdk/jfr/internal/dcmd/DCmdView"; } @@ -184,10 +164,6 @@ class JfrQueryFlightRecordingDCmd : public JfrDCmd { static const char* impact() { return "Medium"; } - static const JavaPermission permission() { - JavaPermission p = {"java.lang.management.ManagementPermission", "monitor", nullptr}; - return p; - } virtual const char* javaClass() const { return "jdk/jfr/internal/dcmd/DCmdQuery"; } @@ -225,10 +201,6 @@ class JfrConfigureFlightRecorderDCmd : public DCmdWithParser { static const char* impact() { return "Low"; } - static const JavaPermission permission() { - JavaPermission p = {"java.lang.management.ManagementPermission", "monitor", nullptr}; - return p; - } static int num_arguments() { return 10; } virtual void execute(DCmdSource source, TRAPS); virtual void print_help(const char* name) const; diff --git a/src/hotspot/share/logging/logDiagnosticCommand.hpp b/src/hotspot/share/logging/logDiagnosticCommand.hpp index e63509bea9e..a27832306b7 100644 --- a/src/hotspot/share/logging/logDiagnosticCommand.hpp +++ b/src/hotspot/share/logging/logDiagnosticCommand.hpp @@ -58,11 +58,6 @@ class LogDiagnosticCommand : public DCmdWithParser { static const char* description() { return "Lists current log configuration, enables/disables/configures a log output, or rotates all logs."; } - - static const JavaPermission permission() { - JavaPermission p = {"java.lang.management.ManagementPermission", "control", nullptr}; - return p; - } }; #endif // SHARE_LOGGING_LOGDIAGNOSTICCOMMAND_HPP diff --git a/src/hotspot/share/memory/metaspace/metaspaceDCmd.hpp b/src/hotspot/share/memory/metaspace/metaspaceDCmd.hpp index 453b6721202..69377057950 100644 --- a/src/hotspot/share/memory/metaspace/metaspaceDCmd.hpp +++ b/src/hotspot/share/memory/metaspace/metaspaceDCmd.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2018, 2020 SAP SE. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -52,11 +52,6 @@ class MetaspaceDCmd : public DCmdWithParser { static const char* impact() { return "Medium: Depends on number of classes loaded."; } - static const JavaPermission permission() { - JavaPermission p = {"java.lang.management.ManagementPermission", - "monitor", nullptr}; - return p; - } static int num_arguments() { return 8; } virtual void execute(DCmdSource source, TRAPS); }; diff --git a/src/hotspot/share/nmt/nmtDCmd.hpp b/src/hotspot/share/nmt/nmtDCmd.hpp index c70d17a481f..2a9f9be49bb 100644 --- a/src/hotspot/share/nmt/nmtDCmd.hpp +++ b/src/hotspot/share/nmt/nmtDCmd.hpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -53,11 +53,6 @@ class NMTDCmd: public DCmdWithParser { static const char* impact() { return "Medium"; } - static const JavaPermission permission() { - JavaPermission p = {"java.lang.management.ManagementPermission", - "monitor", nullptr}; - return p; - } virtual void execute(DCmdSource source, TRAPS); private: diff --git a/src/hotspot/share/services/diagnosticCommand.cpp b/src/hotspot/share/services/diagnosticCommand.cpp index b807a42661c..b081ce29e26 100644 --- a/src/hotspot/share/services/diagnosticCommand.cpp +++ b/src/hotspot/share/services/diagnosticCommand.cpp @@ -151,8 +151,7 @@ void DCmd::register_dcmds(){ DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<CompilationMemoryStatisticDCmd>(full_export, true, false)); // Enhanced JMX Agent Support - // These commands won't be exported via the DiagnosticCommandMBean until an - // appropriate permission is created for them + // These commands not currently exported via the DiagnosticCommandMBean uint32_t jmx_agent_export_flags = DCmd_Source_Internal | DCmd_Source_AttachAPI; DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<JMXStartRemoteDCmd>(jmx_agent_export_flags, true,false)); DCmdFactory::register_DCmdFactory(new DCmdFactoryImpl<JMXStartLocalDCmd>(jmx_agent_export_flags, true,false)); diff --git a/src/hotspot/share/services/diagnosticCommand.hpp b/src/hotspot/share/services/diagnosticCommand.hpp index 92e5849cbcd..30b2be2a61b 100644 --- a/src/hotspot/share/services/diagnosticCommand.hpp +++ b/src/hotspot/share/services/diagnosticCommand.hpp @@ -64,11 +64,6 @@ class VersionDCmd : public DCmd { return "Print JVM version information."; } static const char* impact() { return "Low"; } - static const JavaPermission permission() { - JavaPermission p = {"java.util.PropertyPermission", - "java.vm.version", "read"}; - return p; - } virtual void execute(DCmdSource source, TRAPS); }; @@ -80,11 +75,6 @@ class CommandLineDCmd : public DCmd { return "Print the command line used to start this VM instance."; } static const char* impact() { return "Low"; } - static const JavaPermission permission() { - JavaPermission p = {"java.lang.management.ManagementPermission", - "monitor", nullptr}; - return p; - } virtual void execute(DCmdSource source, TRAPS) { Arguments::print_on(_output); } @@ -101,11 +91,6 @@ class PrintSystemPropertiesDCmd : public DCmd { static const char* impact() { return "Low"; } - static const JavaPermission permission() { - JavaPermission p = {"java.util.PropertyPermission", - "*", "read"}; - return p; - } virtual void execute(DCmdSource source, TRAPS); }; @@ -123,11 +108,6 @@ class PrintVMFlagsDCmd : public DCmdWithParser { static const char* impact() { return "Low"; } - static const JavaPermission permission() { - JavaPermission p = {"java.lang.management.ManagementPermission", - "monitor", nullptr}; - return p; - } virtual void execute(DCmdSource source, TRAPS); }; @@ -146,11 +126,6 @@ class SetVMFlagDCmd : public DCmdWithParser { static const char* impact() { return "Low"; } - static const JavaPermission permission() { - JavaPermission p = {"java.lang.management.ManagementPermission", - "control", nullptr}; - return p; - } virtual void execute(DCmdSource source, TRAPS); }; @@ -164,11 +139,6 @@ class JVMTIDataDumpDCmd : public DCmd { static const char* impact() { return "High"; } - static const JavaPermission permission() { - JavaPermission p = {"java.lang.management.ManagementPermission", - "monitor", nullptr}; - return p; - } virtual void execute(DCmdSource source, TRAPS); }; @@ -186,11 +156,6 @@ class JVMTIAgentLoadDCmd : public DCmdWithParser { return "Load JVMTI native agent."; } static const char* impact() { return "Low"; } - static const JavaPermission permission() { - JavaPermission p = {"java.lang.management.ManagementPermission", - "control", nullptr}; - return p; - } virtual void execute(DCmdSource source, TRAPS); }; #endif // INCLUDE_JVMTI @@ -208,11 +173,6 @@ class VMDynamicLibrariesDCmd : public DCmd { static const char* impact() { return "Low"; } - static const JavaPermission permission() { - JavaPermission p = {"java.lang.management.ManagementPermission", - "monitor", nullptr}; - return p; - } virtual void execute(DCmdSource source, TRAPS); }; @@ -240,11 +200,6 @@ class VMInfoDCmd : public DCmd { return "Print information about JVM environment and status."; } static const char* impact() { return "Low"; } - static const JavaPermission permission() { - JavaPermission p = {"java.lang.management.ManagementPermission", - "monitor", nullptr}; - return p; - } virtual void execute(DCmdSource source, TRAPS); }; @@ -284,11 +239,6 @@ class HeapInfoDCmd : public DCmd { static const char* impact() { return "Medium"; } - static const JavaPermission permission() { - JavaPermission p = {"java.lang.management.ManagementPermission", - "monitor", nullptr}; - return p; - } virtual void execute(DCmdSource source, TRAPS); }; @@ -303,11 +253,6 @@ class FinalizerInfoDCmd : public DCmd { static const char* impact() { return "Medium"; } - static const JavaPermission permission() { - JavaPermission p = {"java.lang.management.ManagementPermission", - "monitor", nullptr}; - return p; - } virtual void execute(DCmdSource source, TRAPS); }; @@ -334,11 +279,6 @@ class HeapDumpDCmd : public DCmdWithParser { return "High: Depends on Java heap size and content. " "Request a full GC unless the '-all' option is specified."; } - static const JavaPermission permission() { - JavaPermission p = {"java.lang.management.ManagementPermission", - "monitor", nullptr}; - return p; - } virtual void execute(DCmdSource source, TRAPS); }; #endif // INCLUDE_SERVICES @@ -360,11 +300,6 @@ class ClassHistogramDCmd : public DCmdWithParser { static const char* impact() { return "High: Depends on Java heap size and content."; } - static const JavaPermission permission() { - JavaPermission p = {"java.lang.management.ManagementPermission", - "monitor", nullptr}; - return p; - } virtual void execute(DCmdSource source, TRAPS); }; @@ -387,11 +322,6 @@ class ClassHierarchyDCmd : public DCmdWithParser { static const char* impact() { return "Medium: Depends on number of loaded classes."; } - static const JavaPermission permission() { - JavaPermission p = {"java.lang.management.ManagementPermission", - "monitor", nullptr}; - return p; - } virtual void execute(DCmdSource source, TRAPS); }; @@ -412,11 +342,6 @@ class DumpSharedArchiveDCmd: public DCmdWithParser { static const char* impact() { return "Medium: Pause time depends on number of loaded classes"; } - static const JavaPermission permission() { - JavaPermission p = {"java.lang.management.ManagementPermission", - "monitor", nullptr}; - return p; - } virtual void execute(DCmdSource source, TRAPS); }; #endif // INCLUDE_CDS @@ -436,11 +361,6 @@ class ThreadDumpDCmd : public DCmdWithParser { static const char* impact() { return "Medium: Depends on the number of threads."; } - static const JavaPermission permission() { - JavaPermission p = {"java.lang.management.ManagementPermission", - "monitor", nullptr}; - return p; - } virtual void execute(DCmdSource source, TRAPS); }; @@ -546,12 +466,6 @@ class JMXStatusDCmd : public DCmd { return "Print the management agent status."; } - static const JavaPermission permission() { - JavaPermission p = {"java.lang.management.ManagementPermission", - "monitor", nullptr}; - return p; - } - virtual void execute(DCmdSource source, TRAPS); }; @@ -568,11 +482,6 @@ class CompileQueueDCmd : public DCmd { static const char* impact() { return "Low"; } - static const JavaPermission permission() { - JavaPermission p = {"java.lang.management.ManagementPermission", - "monitor", nullptr}; - return p; - } virtual void execute(DCmdSource source, TRAPS); }; @@ -592,11 +501,6 @@ class PerfMapDCmd : public DCmdWithParser { static const char* impact() { return "Low"; } - static const JavaPermission permission() { - JavaPermission p = {"java.lang.management.ManagementPermission", - "monitor", nullptr}; - return p; - } virtual void execute(DCmdSource source, TRAPS); }; #endif // LINUX @@ -613,11 +517,6 @@ class CodeListDCmd : public DCmd { static const char* impact() { return "Medium"; } - static const JavaPermission permission() { - JavaPermission p = {"java.lang.management.ManagementPermission", - "monitor", nullptr}; - return p; - } virtual void execute(DCmdSource source, TRAPS); }; @@ -633,11 +532,6 @@ class CodeCacheDCmd : public DCmd { static const char* impact() { return "Low"; } - static const JavaPermission permission() { - JavaPermission p = {"java.lang.management.ManagementPermission", - "monitor", nullptr}; - return p; - } virtual void execute(DCmdSource source, TRAPS); }; @@ -659,11 +553,6 @@ class CodeHeapAnalyticsDCmd : public DCmdWithParser { return "Low: Depends on code heap size and content. " "Holds CodeCache_lock during analysis step, usually sub-second duration."; } - static const JavaPermission permission() { - JavaPermission p = {"java.lang.management.ManagementPermission", - "monitor", nullptr}; - return p; - } virtual void execute(DCmdSource source, TRAPS); }; //---< END >--- CodeHeap State Analytics. @@ -680,11 +569,6 @@ class CompilerDirectivesPrintDCmd : public DCmd { static const char* impact() { return "Low"; } - static const JavaPermission permission() { - JavaPermission p = {"java.lang.management.ManagementPermission", - "monitor", nullptr}; - return p; - } virtual void execute(DCmdSource source, TRAPS); }; @@ -700,11 +584,6 @@ class CompilerDirectivesRemoveDCmd : public DCmd { static const char* impact() { return "Low"; } - static const JavaPermission permission() { - JavaPermission p = {"java.lang.management.ManagementPermission", - "control", nullptr}; - return p; - } virtual void execute(DCmdSource source, TRAPS); }; @@ -723,11 +602,6 @@ class CompilerDirectivesAddDCmd : public DCmdWithParser { static const char* impact() { return "Low"; } - static const JavaPermission permission() { - JavaPermission p = {"java.lang.management.ManagementPermission", - "control", nullptr}; - return p; - } virtual void execute(DCmdSource source, TRAPS); }; @@ -743,11 +617,6 @@ class CompilerDirectivesClearDCmd : public DCmd { static const char* impact() { return "Low"; } - static const JavaPermission permission() { - JavaPermission p = {"java.lang.management.ManagementPermission", - "control", nullptr}; - return p; - } virtual void execute(DCmdSource source, TRAPS); }; @@ -809,11 +678,6 @@ class SymboltableDCmd : public DCmdWithParser { static const char* impact() { return "Medium: Depends on Java content."; } - static const JavaPermission permission() { - JavaPermission p = {"java.lang.management.ManagementPermission", - "monitor", nullptr}; - return p; - } virtual void execute(DCmdSource source, TRAPS); }; @@ -832,11 +696,6 @@ class StringtableDCmd : public DCmdWithParser { static const char* impact() { return "Medium: Depends on Java content."; } - static const JavaPermission permission() { - JavaPermission p = {"java.lang.management.ManagementPermission", - "monitor", nullptr}; - return p; - } virtual void execute(DCmdSource source, TRAPS); }; @@ -855,11 +714,6 @@ class SystemDictionaryDCmd : public DCmdWithParser { static const char* impact() { return "Medium: Depends on Java content."; } - static const JavaPermission permission() { - JavaPermission p = {"java.lang.management.ManagementPermission", - "monitor", nullptr}; - return p; - } virtual void execute(DCmdSource source, TRAPS); }; @@ -878,11 +732,6 @@ class ClassesDCmd : public DCmdWithParser { static const char* impact() { return "Medium: Depends on number of loaded classes."; } - static const JavaPermission permission() { - JavaPermission p = {"java.lang.management.ManagementPermission", - "monitor", nullptr}; - return p; - } virtual void execute(DCmdSource source, TRAPS); }; @@ -902,11 +751,6 @@ class EventLogDCmd : public DCmdWithParser { static const char* impact() { return "Low: Depends on event log size. "; } - static const JavaPermission permission() { - JavaPermission p = {"java.lang.management.ManagementPermission", - "monitor", nullptr}; - return p; - } virtual void execute(DCmdSource source, TRAPS); }; @@ -929,10 +773,6 @@ class ThreadDumpToFileDCmd : public DCmdWithParser { static const char* impact() { return "Medium: Depends on the number of threads."; } - static const JavaPermission permission() { - JavaPermission p = {"java.lang.management.ManagementPermission", "monitor", nullptr}; - return p; - } virtual void execute(DCmdSource source, TRAPS); }; @@ -952,11 +792,6 @@ class CompilationMemoryStatisticDCmd: public DCmdWithParser { static const char* impact() { return "Medium: Pause time depends on number of compiled methods"; } - static const JavaPermission permission() { - JavaPermission p = {"java.lang.management.ManagementPermission", - "monitor", nullptr}; - return p; - } virtual void execute(DCmdSource source, TRAPS); }; @@ -970,11 +805,6 @@ class SystemMapDCmd : public DCmd { return "Prints an annotated process memory map of the VM process (linux and Windows only)."; } static const char* impact() { return "Medium; can be high for very large java heaps."; } - static const JavaPermission permission() { - JavaPermission p = {"java.lang.management.ManagementPermission", - "control", nullptr}; - return p; - } virtual void execute(DCmdSource source, TRAPS); }; @@ -988,11 +818,6 @@ class SystemDumpMapDCmd : public DCmdWithParser { return "Dumps an annotated process memory map to an output file (linux and Windows only)."; } static const char* impact() { return "Medium; can be high for very large java heaps."; } - static const JavaPermission permission() { - JavaPermission p = {"java.lang.management.ManagementPermission", - "control", nullptr}; - return p; - } virtual void execute(DCmdSource source, TRAPS); }; diff --git a/src/hotspot/share/services/diagnosticFramework.cpp b/src/hotspot/share/services/diagnosticFramework.cpp index 16f074c9cb5..27870d9d933 100644 --- a/src/hotspot/share/services/diagnosticFramework.cpp +++ b/src/hotspot/share/services/diagnosticFramework.cpp @@ -587,7 +587,7 @@ GrowableArray<DCmdInfo*>* DCmdFactory::DCmdInfo_list(DCmdSource source ) { if (!factory->is_hidden() && (factory->export_flags() & source)) { array->append(new DCmdInfo(factory->name(), factory->description(), factory->impact(), - factory->permission(), factory->num_arguments(), + factory->num_arguments(), factory->is_enabled())); } factory = factory->next(); diff --git a/src/hotspot/share/services/diagnosticFramework.hpp b/src/hotspot/share/services/diagnosticFramework.hpp index 357482ec5a1..16a7ecbe48e 100644 --- a/src/hotspot/share/services/diagnosticFramework.hpp +++ b/src/hotspot/share/services/diagnosticFramework.hpp @@ -40,16 +40,6 @@ enum DCmdSource { DCmd_Source_MBean = 0x04U // invocation via a MBean }; -// Warning: strings referenced by the JavaPermission struct are passed to -// the native part of the JDK. Avoid use of dynamically allocated strings -// that could be de-allocated before the JDK native code had time to -// convert them into Java Strings. -struct JavaPermission { - const char* _class; - const char* _name; - const char* _action; -}; - // CmdLine is the class used to handle a command line containing a single // diagnostic command and its arguments. It provides methods to access the // command name and the beginning of the arguments. The class is also @@ -127,23 +117,20 @@ class DCmdInfo : public ResourceObj { const char* const _name; /* Name of the diagnostic command */ const char* const _description; /* Short description */ const char* const _impact; /* Impact on the JVM */ - const JavaPermission _permission; /* Java Permission required to execute this command if any */ const int _num_arguments; /* Number of supported options or arguments */ const bool _is_enabled; /* True if the diagnostic command can be invoked, false otherwise */ public: DCmdInfo(const char* name, const char* description, const char* impact, - JavaPermission permission, int num_arguments, bool enabled) - : _name(name), _description(description), _impact(impact), _permission(permission), + : _name(name), _description(description), _impact(impact), _num_arguments(num_arguments), _is_enabled(enabled) {} const char* name() const { return _name; } bool name_equals(const char* cmd_name) const; const char* description() const { return _description; } const char* impact() const { return _impact; } - const JavaPermission& permission() const { return _permission; } int num_arguments() const { return _num_arguments; } bool is_enabled() const { return _is_enabled; } }; @@ -261,19 +248,6 @@ class DCmd : public AnyObj { // impact depends on the heap size. static const char* impact() { return "Low: No impact"; } - // The permission() method returns the description of Java Permission. This - // permission is required when the diagnostic command is invoked via the - // DiagnosticCommandMBean. The rationale for this permission check is that - // the DiagnosticCommandMBean can be used to perform remote invocations of - // diagnostic commands through the PlatformMBeanServer. The (optional) Java - // Permission associated with each diagnostic command should ease the work - // of system administrators to write policy files granting permissions to - // execute diagnostic commands to remote users. Any diagnostic command with - // a potential impact on security should overwrite this method. - static const JavaPermission permission() { - JavaPermission p = {nullptr, nullptr, nullptr}; - return p; - } // num_arguments() is used by the DCmdFactoryImpl::get_num_arguments() template functions. // All subclasses should override this to report the actual number of arguments. static int num_arguments() { return 0; } @@ -387,7 +361,6 @@ class DCmdFactory: public CHeapObj<mtInternal> { virtual const char* name() const = 0; virtual const char* description() const = 0; virtual const char* impact() const = 0; - virtual const JavaPermission permission() const = 0; virtual const char* disabled_message() const = 0; // Register a DCmdFactory to make a diagnostic command available. // Once registered, a diagnostic command must not be unregistered. @@ -431,9 +404,6 @@ template <class DCmdClass> class DCmdFactoryImpl : public DCmdFactory { const char* impact() const { return DCmdClass::impact(); } - const JavaPermission permission() const { - return DCmdClass::permission(); - } const char* disabled_message() const { return DCmdClass::disabled_message(); } diff --git a/src/hotspot/share/services/management.cpp b/src/hotspot/share/services/management.cpp index 7729fb08808..8b8efc577cb 100644 --- a/src/hotspot/share/services/management.cpp +++ b/src/hotspot/share/services/management.cpp @@ -2013,10 +2013,6 @@ JVM_ENTRY(void, jmm_GetDiagnosticCommandInfo(JNIEnv *env, jobjectArray cmds, infoArray[i].name = info->name(); infoArray[i].description = info->description(); infoArray[i].impact = info->impact(); - JavaPermission p = info->permission(); - infoArray[i].permission_class = p._class; - infoArray[i].permission_name = p._name; - infoArray[i].permission_action = p._action; infoArray[i].num_arguments = info->num_arguments(); infoArray[i].enabled = info->is_enabled(); } diff --git a/src/jdk.management/share/classes/com/sun/management/DiagnosticCommandMBean.java b/src/jdk.management/share/classes/com/sun/management/DiagnosticCommandMBean.java index 4e64e17f45f..d5fedf93855 100644 --- a/src/jdk.management/share/classes/com/sun/management/DiagnosticCommandMBean.java +++ b/src/jdk.management/share/classes/com/sun/management/DiagnosticCommandMBean.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -138,26 +138,6 @@ * <td>True if the diagnostic command is enabled, false otherwise</td> * </tr> * <tr> - * <th scope="row">dcmd.permissionClass</th><td>String</td> - * <td>Some diagnostic command might require a specific permission to be - * executed, in addition to the MBeanPermission to invoke their - * associated MBean operation. This field returns the fully qualified - * name of the permission class or null if no permission is required - * </td> - * </tr> - * <tr> - * <th scope="row">dcmd.permissionName</th><td>String</td> - * <td>The fist argument of the permission required to execute this - * diagnostic command or null if no permission is required</td> - * </tr> - * <tr> - * <th scope="row">dcmd.permissionAction</th><td>String</td> - * <td>The second argument of the permission required to execute this - * diagnostic command or null if the permission constructor has only - * one argument (like the ManagementPermission) or if no permission - * is required</td> - * </tr> - * <tr> * <th scope="row">dcmd.arguments</th><td>Descriptor</td> * <td>A Descriptor instance containing the descriptions of options and * arguments supported by the diagnostic command (see below)</td> diff --git a/src/jdk.management/share/classes/com/sun/management/internal/DiagnosticCommandImpl.java b/src/jdk.management/share/classes/com/sun/management/internal/DiagnosticCommandImpl.java index 6e456c7ad02..89c292b37d0 100644 --- a/src/jdk.management/share/classes/com/sun/management/internal/DiagnosticCommandImpl.java +++ b/src/jdk.management/share/classes/com/sun/management/internal/DiagnosticCommandImpl.java @@ -28,7 +28,6 @@ import com.sun.management.DiagnosticCommandMBean; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; -import java.security.Permission; import java.util.*; import javax.management.Attribute; import javax.management.AttributeList; @@ -104,48 +103,12 @@ private class Wrapper { String name; String cmd; DiagnosticCommandInfo info; - Permission permission; Wrapper(String name, String cmd, DiagnosticCommandInfo info) throws InstantiationException { this.name = name; this.cmd = cmd; this.info = info; - this.permission = null; - Exception cause = null; - if (info.getPermissionClass() != null) { - try { - Class<?> c = Class.forName(info.getPermissionClass()); - if (info.getPermissionAction() == null) { - try { - Constructor<?> constructor = c.getConstructor(String.class); - permission = (Permission) constructor.newInstance(info.getPermissionName()); - - } catch (InstantiationException | IllegalAccessException - | IllegalArgumentException | InvocationTargetException - | NoSuchMethodException | SecurityException ex) { - cause = ex; - } - } - if (permission == null) { - try { - Constructor<?> constructor = c.getConstructor(String.class, String.class); - permission = (Permission) constructor.newInstance( - info.getPermissionName(), - info.getPermissionAction()); - } catch (InstantiationException | IllegalAccessException - | IllegalArgumentException | InvocationTargetException - | NoSuchMethodException | SecurityException ex) { - cause = ex; - } - } - } catch (ClassNotFoundException ex) { } - if (permission == null) { - InstantiationException iex = - new InstantiationException("Unable to instantiate required permission"); - iex.initCause(cause); - } - } } public String execute(String[] args) { @@ -297,9 +260,6 @@ private Descriptor commandDescriptor(Wrapper w) throws IllegalArgumentException map.put("dcmd.name", w.info.getName()); map.put("dcmd.description", w.info.getDescription()); map.put("dcmd.vmImpact", w.info.getImpact()); - map.put("dcmd.permissionClass", w.info.getPermissionClass()); - map.put("dcmd.permissionName", w.info.getPermissionName()); - map.put("dcmd.permissionAction", w.info.getPermissionAction()); map.put("dcmd.enabled", w.info.isEnabled()); StringBuilder sb = new StringBuilder(); sb.append("help "); diff --git a/src/jdk.management/share/classes/com/sun/management/internal/DiagnosticCommandInfo.java b/src/jdk.management/share/classes/com/sun/management/internal/DiagnosticCommandInfo.java index 1184a40b64c..90632e5332d 100644 --- a/src/jdk.management/share/classes/com/sun/management/internal/DiagnosticCommandInfo.java +++ b/src/jdk.management/share/classes/com/sun/management/internal/DiagnosticCommandInfo.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -38,9 +38,6 @@ class DiagnosticCommandInfo { private final String name; private final String description; private final String impact; - private final String permissionClass; - private final String permissionName; - private final String permissionAction; private final boolean enabled; private final List<DiagnosticCommandArgumentInfo> arguments; @@ -73,43 +70,6 @@ String getImpact() { return impact; } - /** - * Returns the name of the permission class required to be allowed - * to invoke the diagnostic command, or null if no permission - * is required. - * - * @return the name of the permission class name required to be allowed - * to invoke the diagnostic command, or null if no permission - * is required - */ - String getPermissionClass() { - return permissionClass; - } - - /** - * Returns the permission name required to be allowed to invoke the - * diagnostic command, or null if no permission is required. - * - * @return the permission name required to be allowed to invoke the - * diagnostic command, or null if no permission is required - */ - String getPermissionName() { - return permissionName; - } - - /** - * Returns the permission action required to be allowed to invoke the - * diagnostic command, or null if no permission is required or - * if the permission has no action specified. - * - * @return the permission action required to be allowed to invoke the - * diagnostic command, or null if no permission is required or - * if the permission has no action specified - */ - String getPermissionAction() { - return permissionAction; - } - /** * Returns {@code true} if the diagnostic command is enabled, * {@code false} otherwise. The enabled/disabled @@ -134,17 +94,13 @@ List<DiagnosticCommandArgumentInfo> getArgumentsInfo() { } DiagnosticCommandInfo(String name, String description, - String impact, String permissionClass, - String permissionName, String permissionAction, + String impact, boolean enabled, List<DiagnosticCommandArgumentInfo> arguments) { this.name = name; this.description = description; this.impact = impact; - this.permissionClass = permissionClass; - this.permissionName = permissionName; - this.permissionAction = permissionAction; this.enabled = enabled; this.arguments = arguments; } diff --git a/src/jdk.management/share/native/libmanagement_ext/DiagnosticCommandImpl.c b/src/jdk.management/share/native/libmanagement_ext/DiagnosticCommandImpl.c index b931c6e9893..6c0554a5c32 100644 --- a/src/jdk.management/share/native/libmanagement_ext/DiagnosticCommandImpl.c +++ b/src/jdk.management/share/native/libmanagement_ext/DiagnosticCommandImpl.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -191,10 +191,9 @@ Java_com_sun_management_internal_DiagnosticCommandImpl_getDiagnosticCommandInfo } jmm_interface_management_ext->GetDiagnosticCommandInfo(env, commands, dcmd_info_array); for (i=0; i<num_commands; i++) { - // Ensure capacity for 6 + 3 local refs: + // Ensure capacity for 6 local refs: // 6 => jname, jdesc, jimpact, cmd, args, obj - // 3 => permission class, name, action - (*env)->PushLocalFrame(env, 6 + 3); + (*env)->PushLocalFrame(env, 6); cmd = (*env)->GetObjectArrayElement(env, commands, i); args = getDiagnosticCommandArgumentInfoArray(env, @@ -218,11 +217,8 @@ Java_com_sun_management_internal_DiagnosticCommandImpl_getDiagnosticCommandInfo obj = JNU_NewObjectByName(env, "com/sun/management/internal/DiagnosticCommandInfo", - "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;ZLjava/util/List;)V", + "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;ZLjava/util/List;)V", jname, jdesc, jimpact, - dcmd_info_array[i].permission_class==NULL?NULL:(*env)->NewStringUTF(env,dcmd_info_array[i].permission_class), - dcmd_info_array[i].permission_name==NULL?NULL:(*env)->NewStringUTF(env,dcmd_info_array[i].permission_name), - dcmd_info_array[i].permission_action==NULL?NULL:(*env)->NewStringUTF(env,dcmd_info_array[i].permission_action), dcmd_info_array[i].enabled, args); if (obj == NULL) { From edfe28541a6ed94357f873aa69778c7eba707cbb Mon Sep 17 00:00:00 2001 From: Robbin Ehn <rehn@openjdk.org> Date: Thu, 28 Nov 2024 12:05:23 +0000 Subject: [PATCH 304/311] 8344306: RISC-V: Add zicond Reviewed-by: fyang, luhenry, mli --- src/hotspot/cpu/riscv/assembler_riscv.hpp | 32 ++++ .../cpu/riscv/c1_LIRAssembler_riscv.cpp | 1 + .../cpu/riscv/c2_MacroAssembler_riscv.cpp | 46 +++++- .../cpu/riscv/c2_MacroAssembler_riscv.hpp | 1 - src/hotspot/cpu/riscv/globals_riscv.hpp | 1 + .../cpu/riscv/macroAssembler_riscv.cpp | 141 ++++++++++++++++++ .../cpu/riscv/macroAssembler_riscv.hpp | 11 ++ src/hotspot/cpu/riscv/vm_version_riscv.hpp | 4 + .../os_cpu/linux_riscv/riscv_hwprobe.cpp | 3 + .../gtest/riscv/test_assembler_riscv.cpp | 109 ++++++++++++++ 10 files changed, 344 insertions(+), 5 deletions(-) create mode 100644 test/hotspot/gtest/riscv/test_assembler_riscv.cpp diff --git a/src/hotspot/cpu/riscv/assembler_riscv.hpp b/src/hotspot/cpu/riscv/assembler_riscv.hpp index 7334ec675e3..31713d7362a 100644 --- a/src/hotspot/cpu/riscv/assembler_riscv.hpp +++ b/src/hotspot/cpu/riscv/assembler_riscv.hpp @@ -3107,6 +3107,38 @@ enum Nf { #undef INSN +// -------------- Zicond Instruction Definitions -------------- +// Zicond conditional operations extension + private: + enum CZERO_OP : unsigned int { + CZERO_NEZ = 0b111, + CZERO_EQZ = 0b101 + }; + + template <CZERO_OP OP_VALUE> + void czero(Register Rd, Register Rs1, Register Rs2) { + assert_cond(UseZicond); + uint32_t insn = 0; + patch ((address)&insn, 6, 0, 0b0110011); // bits: 7, name: 0x33, attr: ['OP'] + patch_reg((address)&insn, 7, Rd); // bits: 5, name: 'rd' + patch ((address)&insn, 14, 12, OP_VALUE); // bits: 3, name: 0x7, attr: ['CZERO.NEZ'] / 0x5, attr: ['CZERO.EQZ']} + patch_reg((address)&insn, 15, Rs1); // bits: 5, name: 'rs1', attr: ['value'] + patch_reg((address)&insn, 20, Rs2); // bits: 5, name: 'rs2', attr: ['condition'] + patch ((address)&insn, 31, 25, 0b0000111); // bits: 7, name: 0x7, attr: ['CZERO'] + emit_int32(insn); + } + + public: + // Moves zero to a register rd, if the condition rs2 is equal to zero, otherwise moves rs1 to rd. + void czero_eqz(Register rd, Register rs1_value, Register rs2_condition) { + czero<CZERO_EQZ>(rd, rs1_value, rs2_condition); + } + + // Moves zero to a register rd, if the condition rs2 is nonzero, otherwise moves rs1 to rd. + void czero_nez(Register rd, Register rs1_value, Register rs2_condition) { + czero<CZERO_NEZ>(rd, rs1_value, rs2_condition); + } + // -------------- ZCB Instruction Definitions -------------- // Zcb additional C instructions private: diff --git a/src/hotspot/cpu/riscv/c1_LIRAssembler_riscv.cpp b/src/hotspot/cpu/riscv/c1_LIRAssembler_riscv.cpp index eb715227f7e..b7edd3d231f 100644 --- a/src/hotspot/cpu/riscv/c1_LIRAssembler_riscv.cpp +++ b/src/hotspot/cpu/riscv/c1_LIRAssembler_riscv.cpp @@ -870,6 +870,7 @@ void LIR_Assembler::emit_op3(LIR_Op3* op) { } } +// Consider using cmov (Zicond) void LIR_Assembler::cmove(LIR_Condition condition, LIR_Opr opr1, LIR_Opr opr2, LIR_Opr result, BasicType type, LIR_Opr cmp_opr1, LIR_Opr cmp_opr2) { Label label; diff --git a/src/hotspot/cpu/riscv/c2_MacroAssembler_riscv.cpp b/src/hotspot/cpu/riscv/c2_MacroAssembler_riscv.cpp index 49efb619093..2125f67cf9d 100644 --- a/src/hotspot/cpu/riscv/c2_MacroAssembler_riscv.cpp +++ b/src/hotspot/cpu/riscv/c2_MacroAssembler_riscv.cpp @@ -2003,10 +2003,48 @@ void C2_MacroAssembler::enc_cmpEqNe_imm0_branch(int cmpFlag, Register op1, Label } void C2_MacroAssembler::enc_cmove(int cmpFlag, Register op1, Register op2, Register dst, Register src) { - Label L; - cmp_branch(cmpFlag ^ (1 << neg_cond_bits), op1, op2, L); - mv(dst, src); - bind(L); + bool is_unsigned = (cmpFlag & unsigned_branch_mask) == unsigned_branch_mask; + int op_select = cmpFlag & (~unsigned_branch_mask); + + switch (op_select) { + case BoolTest::eq: + cmov_eq(op1, op2, dst, src); + break; + case BoolTest::ne: + cmov_ne(op1, op2, dst, src); + break; + case BoolTest::le: + if (is_unsigned) { + cmov_leu(op1, op2, dst, src); + } else { + cmov_le(op1, op2, dst, src); + } + break; + case BoolTest::ge: + if (is_unsigned) { + cmov_geu(op1, op2, dst, src); + } else { + cmov_ge(op1, op2, dst, src); + } + break; + case BoolTest::lt: + if (is_unsigned) { + cmov_ltu(op1, op2, dst, src); + } else { + cmov_lt(op1, op2, dst, src); + } + break; + case BoolTest::gt: + if (is_unsigned) { + cmov_gtu(op1, op2, dst, src); + } else { + cmov_gt(op1, op2, dst, src); + } + break; + default: + assert(false, "unsupported compare condition"); + ShouldNotReachHere(); + } } // Set dst to NaN if any NaN input. diff --git a/src/hotspot/cpu/riscv/c2_MacroAssembler_riscv.hpp b/src/hotspot/cpu/riscv/c2_MacroAssembler_riscv.hpp index 2d14f98780d..a8eb0df419c 100644 --- a/src/hotspot/cpu/riscv/c2_MacroAssembler_riscv.hpp +++ b/src/hotspot/cpu/riscv/c2_MacroAssembler_riscv.hpp @@ -98,7 +98,6 @@ // refer to conditional_branches and float_conditional_branches static const int bool_test_bits = 3; - static const int neg_cond_bits = 2; static const int unsigned_branch_mask = 1 << bool_test_bits; static const int double_branch_mask = 1 << bool_test_bits; diff --git a/src/hotspot/cpu/riscv/globals_riscv.hpp b/src/hotspot/cpu/riscv/globals_riscv.hpp index ffbb7c58911..6772fae50ca 100644 --- a/src/hotspot/cpu/riscv/globals_riscv.hpp +++ b/src/hotspot/cpu/riscv/globals_riscv.hpp @@ -110,6 +110,7 @@ define_pd_global(intx, InlineSmallCode, 1000); product(bool, UseZicbom, false, EXPERIMENTAL, "Use Zicbom instructions") \ product(bool, UseZicbop, false, EXPERIMENTAL, "Use Zicbop instructions") \ product(bool, UseZicboz, false, EXPERIMENTAL, "Use Zicboz instructions") \ + product(bool, UseZicond, false, DIAGNOSTIC, "Use Zicond instructions") \ product(bool, UseZihintpause, false, EXPERIMENTAL, \ "Use Zihintpause instructions") \ product(bool, UseZtso, false, EXPERIMENTAL, "Assume Ztso memory model") \ diff --git a/src/hotspot/cpu/riscv/macroAssembler_riscv.cpp b/src/hotspot/cpu/riscv/macroAssembler_riscv.cpp index cf3c851a7ec..c39a086838d 100644 --- a/src/hotspot/cpu/riscv/macroAssembler_riscv.cpp +++ b/src/hotspot/cpu/riscv/macroAssembler_riscv.cpp @@ -1128,6 +1128,147 @@ void MacroAssembler::wrap_label(Register r1, Register r2, Label &L, #undef INSN +// cmov +void MacroAssembler::cmov_eq(Register cmp1, Register cmp2, Register dst, Register src) { + if (UseZicond) { + xorr(t0, cmp1, cmp2); + czero_eqz(dst, dst, t0); + czero_nez(t0 , src, t0); + orr(dst, dst, t0); + return; + } + Label no_set; + bne(cmp1, cmp2, no_set); + mv(dst, src); + bind(no_set); +} + +void MacroAssembler::cmov_ne(Register cmp1, Register cmp2, Register dst, Register src) { + if (UseZicond) { + xorr(t0, cmp1, cmp2); + czero_nez(dst, dst, t0); + czero_eqz(t0 , src, t0); + orr(dst, dst, t0); + return; + } + Label no_set; + beq(cmp1, cmp2, no_set); + mv(dst, src); + bind(no_set); +} + +void MacroAssembler::cmov_le(Register cmp1, Register cmp2, Register dst, Register src) { + if (UseZicond) { + slt(t0, cmp2, cmp1); + czero_eqz(dst, dst, t0); + czero_nez(t0, src, t0); + orr(dst, dst, t0); + return; + } + Label no_set; + bgt(cmp1, cmp2, no_set); + mv(dst, src); + bind(no_set); +} + +void MacroAssembler::cmov_leu(Register cmp1, Register cmp2, Register dst, Register src) { + if (UseZicond) { + sltu(t0, cmp2, cmp1); + czero_eqz(dst, dst, t0); + czero_nez(t0, src, t0); + orr(dst, dst, t0); + return; + } + Label no_set; + bgtu(cmp1, cmp2, no_set); + mv(dst, src); + bind(no_set); +} + +void MacroAssembler::cmov_ge(Register cmp1, Register cmp2, Register dst, Register src) { + if (UseZicond) { + slt(t0, cmp1, cmp2); + czero_eqz(dst, dst, t0); + czero_nez(t0, src, t0); + orr(dst, dst, t0); + return; + } + Label no_set; + blt(cmp1, cmp2, no_set); + mv(dst, src); + bind(no_set); +} + +void MacroAssembler::cmov_geu(Register cmp1, Register cmp2, Register dst, Register src) { + if (UseZicond) { + sltu(t0, cmp1, cmp2); + czero_eqz(dst, dst, t0); + czero_nez(t0, src, t0); + orr(dst, dst, t0); + return; + } + Label no_set; + bltu(cmp1, cmp2, no_set); + mv(dst, src); + bind(no_set); +} + +void MacroAssembler::cmov_lt(Register cmp1, Register cmp2, Register dst, Register src) { + if (UseZicond) { + slt(t0, cmp1, cmp2); + czero_nez(dst, dst, t0); + czero_eqz(t0, src, t0); + orr(dst, dst, t0); + return; + } + Label no_set; + bge(cmp1, cmp2, no_set); + mv(dst, src); + bind(no_set); +} + +void MacroAssembler::cmov_ltu(Register cmp1, Register cmp2, Register dst, Register src) { + if (UseZicond) { + sltu(t0, cmp1, cmp2); + czero_nez(dst, dst, t0); + czero_eqz(t0, src, t0); + orr(dst, dst, t0); + return; + } + Label no_set; + bgeu(cmp1, cmp2, no_set); + mv(dst, src); + bind(no_set); +} + +void MacroAssembler::cmov_gt(Register cmp1, Register cmp2, Register dst, Register src) { + if (UseZicond) { + slt(t0, cmp2, cmp1); + czero_nez(dst, dst, t0); + czero_eqz(t0, src, t0); + orr(dst, dst, t0); + return; + } + Label no_set; + ble(cmp1, cmp2, no_set); + mv(dst, src); + bind(no_set); +} + +void MacroAssembler::cmov_gtu(Register cmp1, Register cmp2, Register dst, Register src) { + if (UseZicond) { + sltu(t0, cmp2, cmp1); + czero_nez(dst, dst, t0); + czero_eqz(t0, src, t0); + orr(dst, dst, t0); + return; + } + Label no_set; + bleu(cmp1, cmp2, no_set); + mv(dst, src); + bind(no_set); +} + // Float compare branch instructions #define INSN(NAME, FLOATCMP, BRANCH) \ diff --git a/src/hotspot/cpu/riscv/macroAssembler_riscv.hpp b/src/hotspot/cpu/riscv/macroAssembler_riscv.hpp index 54f7127106b..cbf69e93c5c 100644 --- a/src/hotspot/cpu/riscv/macroAssembler_riscv.hpp +++ b/src/hotspot/cpu/riscv/macroAssembler_riscv.hpp @@ -626,6 +626,17 @@ class MacroAssembler: public Assembler { void bltz(Register Rs, const address dest); void bgtz(Register Rs, const address dest); + void cmov_eq(Register cmp1, Register cmp2, Register dst, Register src); + void cmov_ne(Register cmp1, Register cmp2, Register dst, Register src); + void cmov_le(Register cmp1, Register cmp2, Register dst, Register src); + void cmov_leu(Register cmp1, Register cmp2, Register dst, Register src); + void cmov_ge(Register cmp1, Register cmp2, Register dst, Register src); + void cmov_geu(Register cmp1, Register cmp2, Register dst, Register src); + void cmov_lt(Register cmp1, Register cmp2, Register dst, Register src); + void cmov_ltu(Register cmp1, Register cmp2, Register dst, Register src); + void cmov_gt(Register cmp1, Register cmp2, Register dst, Register src); + void cmov_gtu(Register cmp1, Register cmp2, Register dst, Register src); + public: // We try to follow risc-v asm menomics. // But as we don't layout a reachable GOT, diff --git a/src/hotspot/cpu/riscv/vm_version_riscv.hpp b/src/hotspot/cpu/riscv/vm_version_riscv.hpp index 8fdde0094f4..e08838c3a6f 100644 --- a/src/hotspot/cpu/riscv/vm_version_riscv.hpp +++ b/src/hotspot/cpu/riscv/vm_version_riscv.hpp @@ -116,6 +116,8 @@ class VM_Version : public Abstract_VM_Version { // // Zfh Half-Precision Floating-Point instructions // + // Zicond Conditional operations + // // Zicsr Control and Status Register (CSR) Instructions // Zifencei Instruction-Fetch Fence // Zic64b Cache blocks must be 64 bytes in size, naturally aligned in the address space. @@ -164,6 +166,7 @@ class VM_Version : public Abstract_VM_Version { decl(ext_Zvbb , "Zvbb" , RV_NO_FLAG_BIT, true , UPDATE_DEFAULT(UseZvbb)) \ decl(ext_Zvfh , "Zvfh" , RV_NO_FLAG_BIT, true , UPDATE_DEFAULT(UseZvfh)) \ decl(ext_Zvkn , "Zvkn" , RV_NO_FLAG_BIT, true , UPDATE_DEFAULT(UseZvkn)) \ + decl(ext_Zicond , "Zicond" , RV_NO_FLAG_BIT, true , UPDATE_DEFAULT(UseZicond)) \ decl(mvendorid , "VendorId" , RV_NO_FLAG_BIT, false, NO_UPDATE_DEFAULT) \ decl(marchid , "ArchId" , RV_NO_FLAG_BIT, false, NO_UPDATE_DEFAULT) \ decl(mimpid , "ImpId" , RV_NO_FLAG_BIT, false, NO_UPDATE_DEFAULT) \ @@ -223,6 +226,7 @@ class VM_Version : public Abstract_VM_Version { RV_ENABLE_EXTENSION(UseZicbom) \ RV_ENABLE_EXTENSION(UseZicbop) \ RV_ENABLE_EXTENSION(UseZicboz) \ + RV_ENABLE_EXTENSION(UseZicond) \ RV_ENABLE_EXTENSION(UseZihintpause) \ static void useRVA23U64Profile(); diff --git a/src/hotspot/os_cpu/linux_riscv/riscv_hwprobe.cpp b/src/hotspot/os_cpu/linux_riscv/riscv_hwprobe.cpp index 2020e2fdb24..f785d935393 100644 --- a/src/hotspot/os_cpu/linux_riscv/riscv_hwprobe.cpp +++ b/src/hotspot/os_cpu/linux_riscv/riscv_hwprobe.cpp @@ -181,6 +181,9 @@ void RiscvHwprobe::add_features_from_query_result() { if (is_set(RISCV_HWPROBE_KEY_IMA_EXT_0, RISCV_HWPROBE_EXT_ZVFH)) { VM_Version::ext_Zvfh.enable_feature(); } + if (is_set(RISCV_HWPROBE_KEY_IMA_EXT_0, RISCV_HWPROBE_EXT_ZICOND)) { + VM_Version::ext_Zicond.enable_feature(); + } if (is_valid(RISCV_HWPROBE_KEY_CPUPERF_0)) { VM_Version::unaligned_access.enable_feature( query[RISCV_HWPROBE_KEY_CPUPERF_0].value & RISCV_HWPROBE_MISALIGNED_MASK); diff --git a/test/hotspot/gtest/riscv/test_assembler_riscv.cpp b/test/hotspot/gtest/riscv/test_assembler_riscv.cpp new file mode 100644 index 00000000000..152b997b3c8 --- /dev/null +++ b/test/hotspot/gtest/riscv/test_assembler_riscv.cpp @@ -0,0 +1,109 @@ +/* + * Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2024, Rivos Inc. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +#include "precompiled.hpp" + +#if (defined(RISCV) || defined(RISCV64)) && !defined(ZERO) + +#include "asm/assembler.inline.hpp" +#include "asm/macroAssembler.hpp" +#include "memory/resourceArea.hpp" +#include "runtime/orderAccess.hpp" +#include "unittest.hpp" + +typedef int64_t (*zicond_func)(int64_t cmp1, int64_t cmp2, int64_t dst, int64_t src); +typedef void (MacroAssembler::*cmov_func)(Register cmp1, Register cmp2, Register dst, Register src); + +class CmovTester { + public: + static void test(cmov_func func, int64_t a0, int64_t a1, int64_t a2, int64_t a3, int64_t result) { + BufferBlob* bb = BufferBlob::create("riscvTest", 128); + CodeBuffer code(bb); + MacroAssembler _masm(&code); + address entry = _masm.pc(); + { + ((&_masm)->*func)(c_rarg0, c_rarg1, c_rarg2, c_rarg3); + _masm.mv(c_rarg0, c_rarg2); + _masm.ret(); + } + _masm.flush(); + OrderAccess::cross_modify_fence(); + int64_t ret = ((zicond_func)entry)(a0, a1, a2, a3); + ASSERT_EQ(ret, result); + BufferBlob::free(bb); + } +}; + +void run_cmov_tests() { + // If 42(a0) eq 42(a1): assign dest(a2/66) the src(a3/77), expect result: 77 + CmovTester::test(&MacroAssembler::cmov_eq, 42, 42, 66, 77, 77); + // If 41(a0) eq 42(a1): assign dest(a2/66) the src(a3/77), expect result: 66 + CmovTester::test(&MacroAssembler::cmov_eq, 41, 42, 66, 77, 66); + + CmovTester::test(&MacroAssembler::cmov_ne, 41, 42, 66, 77, 77); + CmovTester::test(&MacroAssembler::cmov_ne, 42, 42, 66, 77, 66); + + CmovTester::test(&MacroAssembler::cmov_le, 41, 42, 66, 77, 77); + CmovTester::test(&MacroAssembler::cmov_le, 42, 42, 66, 77, 77); + CmovTester::test(&MacroAssembler::cmov_le, 42, -1, 66, 77, 66); + + CmovTester::test(&MacroAssembler::cmov_leu, 41, 42, 66, 77, 77); + CmovTester::test(&MacroAssembler::cmov_leu, 42, 42, 66, 77, 77); + CmovTester::test(&MacroAssembler::cmov_leu, -1, 42, 66, 77, 66); + + CmovTester::test(&MacroAssembler::cmov_ge, 43, 42, 66, 77, 77); + CmovTester::test(&MacroAssembler::cmov_ge, 42, 42, 66, 77, 77); + CmovTester::test(&MacroAssembler::cmov_ge, -1, 42, 66, 77, 66); + + CmovTester::test(&MacroAssembler::cmov_geu, 43, 42, 66, 77, 77); + CmovTester::test(&MacroAssembler::cmov_geu, 42, 42, 66, 77, 77); + CmovTester::test(&MacroAssembler::cmov_geu, 42, -1, 66, 77, 66); + + CmovTester::test(&MacroAssembler::cmov_lt, 41, 42, 66, 77, 77); + CmovTester::test(&MacroAssembler::cmov_lt, 42, 42, 66, 77, 66); + CmovTester::test(&MacroAssembler::cmov_lt, 42, -1, 66, 77, 66); + + CmovTester::test(&MacroAssembler::cmov_ltu, 41, 42, 66, 77, 77); + CmovTester::test(&MacroAssembler::cmov_ltu, 42, 42, 66, 77, 66); + CmovTester::test(&MacroAssembler::cmov_ltu, -1, 42, 66, 77, 66); + + CmovTester::test(&MacroAssembler::cmov_gt, 43, 42, 66, 77, 77); + CmovTester::test(&MacroAssembler::cmov_gt, 42, 42, 66, 77, 66); + CmovTester::test(&MacroAssembler::cmov_gt, -1, 42, 66, 77, 66); + + CmovTester::test(&MacroAssembler::cmov_gtu, 43, 42, 66, 77, 77); + CmovTester::test(&MacroAssembler::cmov_gtu, 42, 42, 66, 77, 66); + CmovTester::test(&MacroAssembler::cmov_gtu, 42, -1, 66, 77, 66); +} + +TEST_VM(RiscV, cmov) { + run_cmov_tests(); + if (UseZicond) { + UseZicond = false; + run_cmov_tests(); + UseZicond = true; + } +} + +#endif // RISCV From db535c86bc56b89b7213b3b097d80935fe9e8516 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C5=A0t=C4=9Bp=C3=A1n=20Schejbal?= <stepan@safara.cz> Date: Thu, 28 Nov 2024 13:12:45 +0000 Subject: [PATCH 305/311] 8313367: SunMSCAPI cannot read Local Computer certs w/o Windows elevation Reviewed-by: weijun --- .../windows/native/libsunmscapi/security.cpp | 12 ++++++--- test/jdk/sun/security/mscapi/AllTypes.java | 27 +++---------------- 2 files changed, 11 insertions(+), 28 deletions(-) diff --git a/src/jdk.crypto.mscapi/windows/native/libsunmscapi/security.cpp b/src/jdk.crypto.mscapi/windows/native/libsunmscapi/security.cpp index 4787708779d..747db000158 100644 --- a/src/jdk.crypto.mscapi/windows/native/libsunmscapi/security.cpp +++ b/src/jdk.crypto.mscapi/windows/native/libsunmscapi/security.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -444,7 +444,7 @@ JNIEXPORT void JNICALL Java_sun_security_mscapi_CKeyStore_loadKeysOrCertificateC } else if (jCertStoreLocation == KEYSTORE_LOCATION_LOCALMACHINE) { hCertStore = ::CertOpenStore(CERT_STORE_PROV_SYSTEM_A, 0, NULL, - CERT_SYSTEM_STORE_LOCAL_MACHINE, pszCertStoreName); + CERT_SYSTEM_STORE_LOCAL_MACHINE | CERT_STORE_MAXIMUM_ALLOWED_FLAG, pszCertStoreName); } else { PP("jCertStoreLocation is not a valid value"); @@ -798,11 +798,15 @@ JNIEXPORT jbyteArray JNICALL Java_sun_security_mscapi_CSignature_signHash ::CryptGetProvParam((HCRYPTPROV)hCryptProv, PP_CONTAINER, //deprecated (BYTE *)pbData, &cbData, 0); + DWORD keysetType = 0; + DWORD keysetTypeLen = sizeof(keysetType); + ::CryptGetProvParam((HCRYPTPROV)hCryptProv, PP_KEYSET_TYPE, //deprecated + (BYTE*)&keysetType, &keysetTypeLen, 0); + // Acquire an alternative CSP handle if (::CryptAcquireContext(&hCryptProvAlt, LPCSTR(pbData), NULL, //deprecated - PROV_RSA_AES, 0) == FALSE) + PROV_RSA_AES, 0 | keysetType) == FALSE) { - ThrowException(env, SIGNATURE_EXCEPTION, GetLastError()); __leave; } diff --git a/test/jdk/sun/security/mscapi/AllTypes.java b/test/jdk/sun/security/mscapi/AllTypes.java index f9c98860702..9f5fb2f13d6 100644 --- a/test/jdk/sun/security/mscapi/AllTypes.java +++ b/test/jdk/sun/security/mscapi/AllTypes.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2022, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -45,33 +45,12 @@ public static void main(String[] args) throws Exception { var nr = test("windows-root"); var nmu = test("windows-my-currentuser"); var nru = test("windows-root-currentuser"); - var hasAdminPrivileges = detectIfRunningWithAdminPrivileges(); - var nmm = adminTest("windows-my-localmachine", hasAdminPrivileges); - var nrm = adminTest("windows-root-localmachine", hasAdminPrivileges); + var nmm = test("windows-my-localmachine"); + var nrm = test("windows-root-localmachine"); Asserts.assertEQ(nm, nmu); Asserts.assertEQ(nr, nru); } - private static boolean detectIfRunningWithAdminPrivileges() { - try { - Process p = Runtime.getRuntime().exec("reg query \"HKU\\S-1-5-19\""); - p.waitFor(); - return (p.exitValue() == 0); - } - catch (Exception ex) { - System.out.println("Warning: unable to detect admin privileges, assuming none"); - return false; - } - } - - private static List<String> adminTest(String type, boolean hasAdminPrivileges) throws Exception { - if (hasAdminPrivileges) { - return test(type); - } - System.out.println("Ignoring: " + type + " as it requires admin privileges"); - return null; - } - private static List<String> test(String type) throws Exception { var stdType = "Windows-" + type.substring(8).toUpperCase(Locale.ROOT); SecurityTools.keytool("-storetype " + type + " -list") From 1e086b1d7305769b59271e2fa428c003216dd52a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johan=20Sj=C3=B6len?= <jsjolen@openjdk.org> Date: Thu, 28 Nov 2024 13:15:10 +0000 Subject: [PATCH 306/311] 8340103: Add internal set_flag function to VMATree Reviewed-by: stuefe, azafari, gziemski --- src/hotspot/share/nmt/nmtTreap.hpp | 36 +++++ src/hotspot/share/nmt/vmatree.cpp | 105 +++++++++++++- src/hotspot/share/nmt/vmatree.hpp | 55 +++++-- test/hotspot/gtest/nmt/test_vmatree.cpp | 184 +++++++++++++++++++++++- 4 files changed, 366 insertions(+), 14 deletions(-) diff --git a/src/hotspot/share/nmt/nmtTreap.hpp b/src/hotspot/share/nmt/nmtTreap.hpp index 70063497439..b6be654f127 100644 --- a/src/hotspot/share/nmt/nmtTreap.hpp +++ b/src/hotspot/share/nmt/nmtTreap.hpp @@ -234,6 +234,10 @@ class Treap { this->remove_all(); } + int size() { + return _node_count; + } + void upsert(const K& k, const V& v) { TreapNode* found = find(_root, k); if (found != nullptr) { @@ -304,6 +308,38 @@ class Treap { return candidate; } + TreapNode* closest_gt(const K& key) { + TreapNode* candidate = nullptr; + TreapNode* pos = _root; + while (pos != nullptr) { + int cmp_r = COMPARATOR::cmp(pos->key(), key); + if (cmp_r > 0) { + // Found a match, try to find a better one. + candidate = pos; + pos = pos->_left; + } else if (cmp_r <= 0) { + pos = pos->_right; + } + } + return candidate; + } + + struct Range { + TreapNode* start; + TreapNode* end; + Range(TreapNode* start, TreapNode* end) + : start(start), end(end) {} + }; + + // Return the range [start, end) + // where start->key() <= addr < end->key(). + // Failure to find the range leads to start and/or end being null. + Range find_enclosing_range(K addr) { + TreapNode* start = closest_leq(addr); + TreapNode* end = closest_gt(addr); + return Range(start, end); + } + // Visit all TreapNodes in ascending key order. template<typename F> void visit_in_order(F f) const { diff --git a/src/hotspot/share/nmt/vmatree.cpp b/src/hotspot/share/nmt/vmatree.cpp index 65a5bdb94ae..ec4f405f1c9 100644 --- a/src/hotspot/share/nmt/vmatree.cpp +++ b/src/hotspot/share/nmt/vmatree.cpp @@ -26,6 +26,7 @@ #include "precompiled.hpp" #include "logging/log.hpp" #include "nmt/vmatree.hpp" +#include "utilities/globalDefinitions.hpp" #include "utilities/growableArray.hpp" const VMATree::RegionData VMATree::empty_regiondata{NativeCallStackStorage::StackIndex{}, mtNone}; @@ -82,12 +83,12 @@ VMATree::SummaryDiff VMATree::register_mapping(position A, position B, StateType // Unless we know better, let B's outgoing state be the outgoing state of the node at or preceding A. // Consider the case where the found node is the start of a region enclosing [A,B) - stB.out = leqA_n->val().out; + stB.out = out_state(leqA_n); // Direct address match. if (leqA_n->key() == A) { // Take over in state from old address. - stA.in = leqA_n->val().in; + stA.in = in_state(leqA_n); // We may now be able to merge two regions: // If the node's old state matches the new, it becomes a noop. That happens, for example, @@ -113,7 +114,7 @@ VMATree::SummaryDiff VMATree::register_mapping(position A, position B, StateType // We add a new node, but only if there would be a state change. If there would not be a // state change, we just omit the node. // That happens, for example, when reserving within an already reserved region with identical metadata. - stA.in = leqA_n->val().out; // .. and the region's prior state is the incoming state + stA.in = out_state(leqA_n); // .. and the region's prior state is the incoming state if (stA.is_noop()) { // Nothing to do. } else { @@ -134,7 +135,7 @@ VMATree::SummaryDiff VMATree::register_mapping(position A, position B, StateType // outgoing state. _tree.visit_range_in_order(A + 1, B + 1, [&](TreapNode* head) { int cmp_B = PositionComparator::cmp(head->key(), B); - stB.out = head->val().out; + stB.out = out_state(head); if (cmp_B < 0) { // Record all nodes preceding B. to_be_deleted_inbetween_a_b.push({head->key(), head->val()}); @@ -215,3 +216,99 @@ VMATree::SummaryDiff VMATree::register_mapping(position A, position B, StateType } return diff; } + +#ifdef ASSERT +void VMATree::print_on(outputStream* out) { + visit_in_order([&](TreapNode* current) { + out->print(SIZE_FORMAT " (%s) - %s - ", current->key(), NMTUtil::tag_to_name(out_state(current).mem_tag()), + statetype_to_string(out_state(current).type())); + }); + out->cr(); +} +#endif + +VMATree::SummaryDiff VMATree::set_tag(const position start, const size size, const MemTag tag) { + auto pos = [](TreapNode* n) { return n->key(); }; + position from = start; + position end = from+size; + size_t remsize = size; + VMATreap::Range range(nullptr, nullptr); + + // Find the next range to adjust and set range, remsize and from + // appropriately. If it returns false, there is no valid next range. + auto find_next_range = [&]() -> bool { + range = _tree.find_enclosing_range(from); + if ((range.start == nullptr && range.end == nullptr) || + (range.start != nullptr && range.end == nullptr)) { + // There is no range containing the starting address + assert(range.start->val().out.type() == StateType::Released, "must be"); + return false; + } else if (range.start == nullptr && range.end != nullptr) { + position found_end = pos(range.end); + if (found_end >= end) { + // The found address is outside of our range, we can end now. + return false; + } + // There is at least one range [found_end, ?) which starts within [start, end) + // Use this as the range instead. + range = _tree.find_enclosing_range(found_end); + remsize = end - found_end; + from = found_end; + } + return true; + }; + + bool success = find_next_range(); + if (!success) return SummaryDiff(); + assert(range.start != nullptr && range.end != nullptr, "must be"); + + end = MIN2(from + remsize, pos(range.end)); + IntervalState& out = out_state(range.start); + StateType type = out.type(); + + SummaryDiff diff; + // Ignore any released ranges, these must be mtNone and have no stack + if (type != StateType::Released) { + RegionData new_data = RegionData(out.stack(), tag); + SummaryDiff result = register_mapping(from, end, type, new_data); + diff.add(result); + } + + remsize = remsize - (end - from); + from = end; + + // If end < from + sz then there are multiple ranges for which to set the flag. + while (end < from + remsize) { + // Using register_mapping may invalidate the already found range, so we must + // use find_next_range repeatedly + bool success = find_next_range(); + if (!success) return diff; + assert(range.start != nullptr && range.end != nullptr, "must be"); + + end = MIN2(from + remsize, pos(range.end)); + IntervalState& out = out_state(range.start); + StateType type = out.type(); + + if (type != StateType::Released) { + RegionData new_data = RegionData(out.stack(), tag); + SummaryDiff result = register_mapping(from, end, type, new_data); + diff.add(result); + } + remsize = remsize - (end - from); + from = end; + } + + return diff; +} + +#ifdef ASSERT +void VMATree::SummaryDiff::print_on(outputStream* out) { + for (int i = 0; i < mt_number_of_tags; i++) { + if (tag[i].reserve == 0 && tag[i].commit == 0) { + continue; + } + out->print_cr("Tag %s R: " INT64_FORMAT " C: " INT64_FORMAT, NMTUtil::tag_to_enum_name((MemTag)i), tag[i].reserve, + tag[i].commit); + } +} +#endif diff --git a/src/hotspot/share/nmt/vmatree.hpp b/src/hotspot/share/nmt/vmatree.hpp index cfb3c8ab524..75f814c81c0 100644 --- a/src/hotspot/share/nmt/vmatree.hpp +++ b/src/hotspot/share/nmt/vmatree.hpp @@ -26,10 +26,11 @@ #ifndef SHARE_NMT_VMATREE_HPP #define SHARE_NMT_VMATREE_HPP +#include "nmt/memTag.hpp" #include "nmt/nmtNativeCallStackStorage.hpp" #include "nmt/nmtTreap.hpp" -#include "runtime/os.hpp" #include "utilities/globalDefinitions.hpp" +#include "utilities/ostream.hpp" #include <cstdint> // A VMATree stores a sequence of points on the natural number line. @@ -42,6 +43,7 @@ class VMATree { // A position in memory. public: using position = size_t; + using size = size_t; class PositionComparator { public: @@ -140,6 +142,14 @@ class VMATree { private: VMATreap _tree; + static IntervalState& in_state(TreapNode* node) { + return node->val().in; + } + + static IntervalState& out_state(TreapNode* node) { + return node->val().out; + } + // AddressState saves the necessary information for performing online summary accounting. struct AddressState { position address; @@ -162,6 +172,7 @@ class VMATree { delta reserve; delta commit; }; + struct SummaryDiff { SingleDiff tag[mt_number_of_tags]; SummaryDiff() { @@ -169,26 +180,47 @@ class VMATree { tag[i] = SingleDiff{0, 0}; } } + + void add(SummaryDiff& other) { + for (int i = 0; i < mt_number_of_tags; i++) { + tag[i].reserve += other.tag[i].reserve; + tag[i].commit += other.tag[i].commit; + } + } + +#ifdef ASSERT + void print_on(outputStream* out); +#endif }; private: SummaryDiff register_mapping(position A, position B, StateType state, const RegionData& metadata, bool use_tag_inplace = false); public: - SummaryDiff reserve_mapping(position from, position sz, const RegionData& metadata) { - return register_mapping(from, from + sz, StateType::Reserved, metadata, false); + SummaryDiff reserve_mapping(position from, size size, const RegionData& metadata) { + return register_mapping(from, from + size, StateType::Reserved, metadata, false); + } + + SummaryDiff commit_mapping(position from, size size, const RegionData& metadata, bool use_tag_inplace = false) { + return register_mapping(from, from + size, StateType::Committed, metadata, use_tag_inplace); } - SummaryDiff commit_mapping(position from, position sz, const RegionData& metadata, bool use_tag_inplace = false) { - return register_mapping(from, from + sz, StateType::Committed, metadata, use_tag_inplace); + // Given an interval and a tag, find all reserved and committed ranges at least + // partially contained within that interval and set their tag to the one provided. + // This may cause merging and splitting of ranges. + // Released regions are ignored. + SummaryDiff set_tag(position from, size size, MemTag tag); + + SummaryDiff uncommit_mapping(position from, size size, const RegionData& metadata) { + return register_mapping(from, from + size, StateType::Reserved, metadata, true); } - SummaryDiff uncommit_mapping(position from, position sz, const RegionData& metadata) { - return register_mapping(from, from + sz, StateType::Reserved, metadata, true); + SummaryDiff release_mapping(position from, size size) { + return register_mapping(from, from + size, StateType::Released, VMATree::empty_regiondata); } - SummaryDiff release_mapping(position from, position sz) { - return register_mapping(from, from + sz, StateType::Released, VMATree::empty_regiondata); + VMATreap& tree() { + return _tree; } public: @@ -196,6 +228,11 @@ class VMATree { void visit_in_order(F f) const { _tree.visit_in_order(f); } + +#ifdef ASSERT + void print_on(outputStream* out); +#endif + }; #endif diff --git a/test/hotspot/gtest/nmt/test_vmatree.cpp b/test/hotspot/gtest/nmt/test_vmatree.cpp index d7a9a5fcff7..3a61e0c7cca 100644 --- a/test/hotspot/gtest/nmt/test_vmatree.cpp +++ b/test/hotspot/gtest/nmt/test_vmatree.cpp @@ -284,6 +284,188 @@ TEST_VM_F(NMTVMATreeTest, LowLevel) { } } +TEST_VM_F(NMTVMATreeTest, SetTag) { + using State = VMATree::StateType; + struct testrange { + VMATree::position from; + VMATree::position to; + MemTag tag; + NCS::StackIndex stack; + State state; + }; + + // Take a sorted list of testranges and check that those and only those are found in the tree. + auto expect_equivalent_form = [&](auto& expected, VMATree& tree) { + // With auto& our arrays do not deteriorate to pointers but are kept as testrange[N] + // so this actually works! + int len = sizeof(expected) / sizeof(testrange); + VMATree::position previous_to = 0; + for (int i = 0; i < len; i++) { + testrange expect = expected[i]; + assert(previous_to == 0 || previous_to <= expect.from, "the expected list must be sorted"); + previous_to = expect.to; + + VMATree::VMATreap::Range found = tree.tree().find_enclosing_range(expect.from); + ASSERT_NE(nullptr, found.start); + ASSERT_NE(nullptr, found.end); + // Same region + EXPECT_EQ(expect.from, found.start->key()); + EXPECT_EQ(expect.to, found.end->key()); + // Same tag + EXPECT_EQ(expect.tag, found.start->val().out.mem_tag()); + EXPECT_EQ(expect.tag, found.end->val().in.mem_tag()); + // Same stack + EXPECT_EQ(expect.stack, found.start->val().out.stack()); + EXPECT_EQ(expect.stack, found.end->val().in.stack()); + // Same state + EXPECT_EQ(expect.state, found.start->val().out.type()); + EXPECT_EQ(expect.state, found.end->val().in.type()); + } + // expected must cover all nodes + EXPECT_EQ(len+1, tree.tree().size()); + }; + NCS::StackIndex si = NCS::StackIndex(); + Tree::RegionData rd(si, mtNone); + + { // The gc/cds case with only reserved data + testrange expected[2]{ + { 0, 500, mtGC, si, State::Reserved}, + {500, 600, mtClassShared, si, State::Reserved} + }; + VMATree tree; + + tree.reserve_mapping(0, 600, rd); + + tree.set_tag(0, 500, mtGC); + tree.set_tag(500, 100, mtClassShared); + expect_equivalent_form(expected, tree); + } + + { // Now let's add in some committed data + testrange expected[]{ + { 0, 100, mtGC, si, State::Reserved}, + {100, 225, mtGC, si, State::Committed}, + {225, 500, mtGC, si, State::Reserved}, + {500, 550, mtClassShared, si, State::Reserved}, + {550, 560, mtClassShared, si, State::Committed}, + {560, 565, mtClassShared, si, State::Reserved}, + {565, 575, mtClassShared, si, State::Committed}, + {575, 600, mtClassShared, si, State::Reserved} + }; + VMATree tree; + + tree.reserve_mapping(0, 600, rd); + // The committed areas + tree.commit_mapping(100, 125, rd); + tree.commit_mapping(550, 10, rd); + tree.commit_mapping(565, 10, rd); + // OK, set tag + tree.set_tag(0, 500, mtGC); + tree.set_tag(500, 100, mtClassShared); + expect_equivalent_form(expected, tree); + } + + { // Setting the tag for adjacent regions with same stacks should merge the regions + testrange expected[]{ + {0, 200, mtGC, si, State::Reserved} + }; + VMATree tree; + Tree::RegionData gc(si, mtGC); + Tree::RegionData compiler(si, mtCompiler); + tree.reserve_mapping(0, 100, gc); + tree.reserve_mapping(100, 100, compiler); + tree.set_tag(0, 200, mtGC); + expect_equivalent_form(expected, tree); + } + + { // Setting the tag for adjacent regions with different stacks should NOT merge the regions + NCS::StackIndex si1 = 1; + NCS::StackIndex si2 = 2; + testrange expected[]{ + { 0, 100, mtGC, si1, State::Reserved}, + {100, 200, mtGC, si2, State::Reserved} + }; + VMATree tree; + Tree::RegionData gc(si1, mtGC); + Tree::RegionData compiler(si2, mtCompiler); + tree.reserve_mapping(0, 100, gc); + tree.reserve_mapping(100, 100, compiler); + tree.set_tag(0, 200, mtGC); + expect_equivalent_form(expected, tree); + } + + { // Setting the tag in the middle of a range causes a split + testrange expected[]{ + { 0, 100, mtCompiler, si, State::Reserved}, + {100, 150, mtGC, si, State::Reserved}, + {150, 200, mtCompiler, si, State::Reserved} + }; + VMATree tree; + Tree::RegionData compiler(si, mtCompiler); + tree.reserve_mapping(0, 200, compiler); + tree.set_tag(100, 50, mtGC); + expect_equivalent_form(expected, tree); + } + + { // Setting the tag in between two ranges causes a split + testrange expected[]{ + { 0, 75, mtGC, si, State::Reserved}, + { 75, 125, mtClass, si, State::Reserved}, + {125, 200, mtCompiler, si, State::Reserved}, + }; + VMATree tree; + Tree::RegionData gc(si, mtGC); + Tree::RegionData compiler(si, mtCompiler); + tree.reserve_mapping(0, 100, gc); + tree.reserve_mapping(100, 100, compiler); + tree.set_tag(75, 50, mtClass); + expect_equivalent_form(expected, tree); + } + + { // Holes in the address range are acceptable and untouched + testrange expected[]{ + { 0, 50, mtGC, si, State::Reserved}, + {50, 75, mtNone, si, State::Released}, + {75, 80, mtGC, si, State::Reserved}, + {80, 100, mtClassShared, si, State::Reserved} + }; + VMATree tree; + Tree::RegionData class_shared(si, mtClassShared); + tree.reserve_mapping(0, 50, class_shared); + tree.reserve_mapping(75, 25, class_shared); + tree.set_tag(0, 80, mtGC); + expect_equivalent_form(expected, tree); + } + + { // Check that setting tag with 'hole' not consisting of any regions work + testrange expected[]{ + {10, 20, mtCompiler, si, State::Reserved} + }; + VMATree tree; + Tree::RegionData class_shared(si, mtClassShared); + tree.reserve_mapping(10, 10, class_shared); + tree.set_tag(0, 100, mtCompiler); + expect_equivalent_form(expected, tree); + } + + { // Check that multiple holes still work + testrange expected[]{ + { 0, 1, mtGC, si, State::Reserved}, + { 1, 50, mtNone, si, State::Released}, + {50, 75, mtGC, si, State::Reserved}, + {75, 99, mtNone, si, State::Released}, + {99, 100, mtGC, si, State::Reserved} + }; + VMATree tree; + Tree::RegionData class_shared(si, mtClassShared); + tree.reserve_mapping(0, 100, class_shared); + tree.release_mapping(1, 49); + tree.release_mapping(75, 24); + tree.set_tag(0, 100, mtGC); + expect_equivalent_form(expected, tree); + } +} + // Tests for summary accounting TEST_VM_F(NMTVMATreeTest, SummaryAccounting) { { // Fully enclosed re-reserving works correctly. @@ -330,7 +512,7 @@ TEST_VM_F(NMTVMATreeTest, SummaryAccounting) { diff = all_diff.tag[NMTUtil::tag_to_index(mtTest)]; EXPECT_EQ(100, diff.reserve); } - { // Adjacent reserved mappings with different flags + { // Adjacent reserved mappings with different tags Tree::RegionData rd(NCS::StackIndex(), mtTest); Tree::RegionData rd2(NCS::StackIndex(), mtNMT); Tree tree; From 7dc00d39b4e184a59cbcd644d22db61b1abe8a4b Mon Sep 17 00:00:00 2001 From: Christian Hagedorn <chagedorn@openjdk.org> Date: Thu, 28 Nov 2024 13:58:14 +0000 Subject: [PATCH 307/311] 8345154: IGV: Show Parse and Assertion Predicate type as extra label Reviewed-by: rcastanedalo --- src/hotspot/share/opto/ifnode.cpp | 4 ++-- .../filters/customNodeInfo.filter | 24 +++++++++++++++++++ 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/src/hotspot/share/opto/ifnode.cpp b/src/hotspot/share/opto/ifnode.cpp index c0ed3f7e5d4..677cf5b7d60 100644 --- a/src/hotspot/share/opto/ifnode.cpp +++ b/src/hotspot/share/opto/ifnode.cpp @@ -2213,10 +2213,10 @@ void ParsePredicateNode::dump_spec(outputStream* st) const { st->print("Loop "); break; case Deoptimization::DeoptReason::Reason_profile_predicate: - st->print("Profiled_Loop "); + st->print("Profiled Loop "); break; case Deoptimization::DeoptReason::Reason_loop_limit_check: - st->print("Loop_Limit_Check "); + st->print("Loop Limit Check "); break; default: fatal("unknown kind"); diff --git a/src/utils/IdealGraphVisualizer/ServerCompiler/src/main/resources/com/sun/hotspot/igv/servercompiler/filters/customNodeInfo.filter b/src/utils/IdealGraphVisualizer/ServerCompiler/src/main/resources/com/sun/hotspot/igv/servercompiler/filters/customNodeInfo.filter index bcdd86ba7d3..f94f06ab284 100644 --- a/src/utils/IdealGraphVisualizer/ServerCompiler/src/main/resources/com/sun/hotspot/igv/servercompiler/filters/customNodeInfo.filter +++ b/src/utils/IdealGraphVisualizer/ServerCompiler/src/main/resources/com/sun/hotspot/igv/servercompiler/filters/customNodeInfo.filter @@ -34,3 +34,27 @@ editProperty(matches("name", "CallLeafDirect|CallLeafDirectVector|CallLeafNoFPDi // Show pre/main/post at CountedLoopNodes. editProperty(hasProperty("loop_kind"), ["loop_kind"], "extra_label", function(loop_kind) { return loop_kind[0]; }); + +// Show Parse Predicate type. +function parsePredicateInfo(dump_spec) { + // It's easier to match with ".*" because type "Loop" can also be found in type "Loop Limit Check" and "Profiled Loop". + // Matching with ".*" also requires us to exclude the optional "#useless" string at the end. + var predicateMatch = /#(.*)(#useless)?/.exec(dump_spec); + if (predicateMatch != null) { + return predicateMatch[1].trim(); + } + return null; +} +editProperty(matches("name", "ParsePredicate"), ["dump_spec"], "extra_label", + function(dump_spec) { return parsePredicateInfo(dump_spec[0]);}); + +// Show Assertion Predicate type. +function assertionPredicateInfo(dump_spec) { + var predicateMatch = /#((Init|Last) Value Assertion Predicate)/.exec(dump_spec); + if (predicateMatch != null) { + return predicateMatch[1]; + } + return null; +} +editProperty(matches("name", "If|RangeCheck"), ["dump_spec"], "extra_label", + function(dump_spec) { return assertionPredicateInfo(dump_spec[0]);}); From 3b21a298c29d88720f6bfb2dc1f3305b6a3db307 Mon Sep 17 00:00:00 2001 From: Daniel Fuchs <dfuchs@openjdk.org> Date: Thu, 28 Nov 2024 14:17:15 +0000 Subject: [PATCH 308/311] 8345175: Further cleanup in java.logging and jdk.internal.logger after JEP 486 integration Reviewed-by: alanb, coffeys --- .../jdk/internal/logger/LoggerFinderLoader.java | 4 ---- .../share/classes/java/util/logging/LogManager.java | 13 ++++--------- 2 files changed, 4 insertions(+), 13 deletions(-) diff --git a/src/java.base/share/classes/jdk/internal/logger/LoggerFinderLoader.java b/src/java.base/share/classes/jdk/internal/logger/LoggerFinderLoader.java index 36edb918712..72fe24c25bb 100644 --- a/src/java.base/share/classes/jdk/internal/logger/LoggerFinderLoader.java +++ b/src/java.base/share/classes/jdk/internal/logger/LoggerFinderLoader.java @@ -148,8 +148,6 @@ public Logger getLogger(String name, Module module) { private static System.LoggerFinder loadLoggerFinder() { System.LoggerFinder result; try { - // Iterator iterates with the access control context stored - // at ServiceLoader creation time. final Iterator<System.LoggerFinder> iterator = findLoggerFinderProviders(); if (iterator.hasNext()) { @@ -197,8 +195,6 @@ private static System.LoggerFinder loadDefaultImplementation() { DefaultLoggerFinder result = null; try { - // Iterator iterates with the access control context stored - // at ServiceLoader creation time. if (iterator.hasNext()) { result = iterator.next(); } diff --git a/src/java.logging/share/classes/java/util/logging/LogManager.java b/src/java.logging/share/classes/java/util/logging/LogManager.java index 0b7a854dddf..9c9c708a062 100644 --- a/src/java.logging/share/classes/java/util/logging/LogManager.java +++ b/src/java.logging/share/classes/java/util/logging/LogManager.java @@ -164,7 +164,7 @@ public class LogManager { // LoggerContext for system loggers and user loggers private final LoggerContext systemContext = new SystemLoggerContext(); private final LoggerContext userContext = new LoggerContext(); - // non final field - make it volatile to make sure that other threads + // non-final field - make it volatile to make sure that other threads // will see the new value once ensureLogManagerInitialized() has finished // executing. private volatile Logger rootLogger; @@ -312,7 +312,6 @@ protected LogManager() { */ private boolean initializedCalled = false; private volatile boolean initializationDone = false; - @SuppressWarnings("removal") final void ensureLogManagerInitialized() { final LogManager owner = this; if (initializationDone || owner != manager) { @@ -422,15 +421,11 @@ private void readPrimordialConfiguration() { // must be called while holding con } } - // LoggerContext maps from AppContext - private WeakHashMap<Object, LoggerContext> contextsMap = null; - // Returns the LoggerContext for the user code (i.e. application or AppContext). // Loggers are isolated from each AppContext. private LoggerContext getUserContext() { - LoggerContext context = null; - // for standalone app, return userContext - return context != null ? context : userContext; + // return userContext + return userContext; } // The system context. @@ -447,7 +442,7 @@ private List<LoggerContext> contexts() { // Find or create a specified logger instance. If a logger has // already been created with the given name it is returned. - // Otherwise a new logger instance is created and registered + // Otherwise, a new logger instance is created and registered // in the LogManager global namespace. // This method will always return a non-null Logger object. // Synchronization is not required here. All synchronization for From fd742af0b76bdd7e6e14bd02ddc0d9bd921c90b2 Mon Sep 17 00:00:00 2001 From: Kevin Walls <kevinw@openjdk.org> Date: Thu, 28 Nov 2024 17:16:41 +0000 Subject: [PATCH 309/311] 8344394: Remove SecurityManager and related calls from java.management.rmi Reviewed-by: amenkov --- src/java.base/share/classes/module-info.java | 1 - .../remote/rmi/RMIConnectionImpl.java | 222 +++++------------- .../management/remote/rmi/RMIConnector.java | 127 +++++----- .../remote/rmi/RMIJRMPServerImpl.java | 4 +- 4 files changed, 114 insertions(+), 240 deletions(-) diff --git a/src/java.base/share/classes/module-info.java b/src/java.base/share/classes/module-info.java index 5a44adeb294..c3bcbed4e3b 100644 --- a/src/java.base/share/classes/module-info.java +++ b/src/java.base/share/classes/module-info.java @@ -315,7 +315,6 @@ exports sun.reflect.misc to java.desktop, java.management, - java.management.rmi, java.rmi, java.sql.rowset; exports sun.security.internal.interfaces to diff --git a/src/java.management.rmi/share/classes/javax/management/remote/rmi/RMIConnectionImpl.java b/src/java.management.rmi/share/classes/javax/management/remote/rmi/RMIConnectionImpl.java index cb318dc65b2..9c0b3d56214 100644 --- a/src/java.management.rmi/share/classes/javax/management/remote/rmi/RMIConnectionImpl.java +++ b/src/java.management.rmi/share/classes/javax/management/remote/rmi/RMIConnectionImpl.java @@ -29,24 +29,17 @@ import java.rmi.MarshalledObject; import java.rmi.UnmarshalException; import java.rmi.server.Unreferenced; -import java.security.AccessControlContext; -import java.security.AccessController; -import java.security.Permission; -import java.security.Permissions; -import java.security.PrivilegedAction; import java.security.PrivilegedActionException; -import java.security.PrivilegedExceptionAction; -import java.security.ProtectionDomain; import java.util.Arrays; import java.util.Collections; import java.util.Map; import java.util.Set; +import java.util.concurrent.CompletionException; import javax.management.*; import javax.management.remote.JMXServerErrorException; import javax.management.remote.NotificationResult; import javax.security.auth.Subject; -import sun.reflect.misc.ReflectUtil; import static javax.management.remote.rmi.RMIConnector.Util.cast; import com.sun.jmx.remote.internal.ServerCommunicatorAdmin; @@ -94,7 +87,6 @@ public class RMIConnectionImpl implements RMIConnection, Unreferenced { * <code>RMIServerImpl</code>. Can be null, equivalent to an * empty map. */ - @SuppressWarnings("removal") public RMIConnectionImpl(RMIServerImpl rmiServer, String connectionId, ClassLoader defaultClassLoader, @@ -111,54 +103,13 @@ public RMIConnectionImpl(RMIServerImpl rmiServer, this.mbeanServer = rmiServer.getMBeanServer(); final ClassLoader dcl = defaultClassLoader; - - ClassLoaderRepository repository = AccessController.doPrivileged( - new PrivilegedAction<ClassLoaderRepository>() { - public ClassLoaderRepository run() { - return mbeanServer.getClassLoaderRepository(); - } - }, - withPermissions(new MBeanPermission("*", "getClassLoaderRepository")) - ); - this.classLoaderWithRepository = AccessController.doPrivileged( - new PrivilegedAction<ClassLoaderWithRepository>() { - public ClassLoaderWithRepository run() { - return new ClassLoaderWithRepository( - repository, - dcl); - } - }, - withPermissions(new RuntimePermission("createClassLoader")) - ); - - this.defaultContextClassLoader = - AccessController.doPrivileged( - new PrivilegedAction<ClassLoader>() { - @Override - public ClassLoader run() { - return new CombinedClassLoader(Thread.currentThread().getContextClassLoader(), - dcl); - } - }); - - serverCommunicatorAdmin = new - RMIServerCommunicatorAdmin(EnvHelp.getServerConnectionTimeout(env)); - + ClassLoaderRepository repository = mbeanServer.getClassLoaderRepository(); + classLoaderWithRepository = new ClassLoaderWithRepository(repository, dcl); + defaultContextClassLoader = new CombinedClassLoader(Thread.currentThread().getContextClassLoader(), dcl); + serverCommunicatorAdmin = new RMIServerCommunicatorAdmin(EnvHelp.getServerConnectionTimeout(env)); this.env = env; } - @SuppressWarnings("removal") - private static AccessControlContext withPermissions(Permission ... perms){ - Permissions col = new Permissions(); - - for (Permission thePerm : perms ) { - col.add(thePerm); - } - - final ProtectionDomain pd = new ProtectionDomain(null, col); - return new AccessControlContext( new ProtectionDomain[] { pd }); - } - private synchronized ServerNotifForwarder getServerNotifFwd() { // Lazily created when first use. Mainly when // addNotificationListener is first called. @@ -397,7 +348,7 @@ public ObjectInstance createMBean(String className, +", unwrapping params with MBean extended ClassLoader."); values = nullIsEmpty(unwrap(params, - getClassLoader(loaderName), + mbeanServer.getClassLoader(loaderName), defaultClassLoader, Object[].class,delegationSubject)); @@ -1249,7 +1200,6 @@ public void removeNotificationListener(ObjectName name, } } - @SuppressWarnings("removal") public NotificationResult fetchNotifications(long clientSequenceNumber, int maxNotifications, long timeout) @@ -1274,19 +1224,22 @@ public NotificationResult fetchNotifications(long clientSequenceNumber, + "returns null to force the client to stop fetching"); return null; } - final long csn = clientSequenceNumber; - final int mn = maxNotifications; - final long t = timeout; - PrivilegedAction<NotificationResult> action = - new PrivilegedAction<NotificationResult>() { - public NotificationResult run() { - return getServerNotifFwd().fetchNotifs(csn, t, mn); - } - }; + if (subject == null) { - return action.run(); + return getServerNotifFwd().fetchNotifs(clientSequenceNumber, timeout, maxNotifications); } else { - return Subject.doAs(subject, action); + try { + return Subject.callAs(subject, () -> getServerNotifFwd().fetchNotifs(clientSequenceNumber, timeout, maxNotifications)); + } catch (CompletionException ce) { + Throwable thr = ce.getCause(); + if (thr instanceof SecurityException se) { + throw se; + } else if (thr instanceof IOException ioe) { + throw ioe; + } else { + throw new RuntimeException(thr); + } + } } } finally { serverCommunicatorAdmin.rspOutgoing(); @@ -1311,25 +1264,6 @@ public String toString() { // private classes //------------------------------------------------------------------------ - private class PrivilegedOperation - implements PrivilegedExceptionAction<Object> { - - public PrivilegedOperation(int operation, Object[] params) { - this.operation = operation; - this.params = params; - } - - public Object run() throws Exception { - return doOperation(operation, params); - } - - private int operation; - private Object[] params; - } - - //------------------------------------------------------------------------ - // private classes - //------------------------------------------------------------------------ private class RMIServerCommunicatorAdmin extends ServerCommunicatorAdmin { public RMIServerCommunicatorAdmin(long timeout) { super(timeout); @@ -1352,44 +1286,13 @@ protected void doStop() { // private methods //------------------------------------------------------------------------ - @SuppressWarnings("removal") - private ClassLoader getClassLoader(final ObjectName name) - throws InstanceNotFoundException { - try { - return - AccessController.doPrivileged( - new PrivilegedExceptionAction<ClassLoader>() { - public ClassLoader run() throws InstanceNotFoundException { - return mbeanServer.getClassLoader(name); - } - }, - withPermissions(new MBeanPermission("*", "getClassLoader")) - ); - } catch (PrivilegedActionException pe) { - throw (InstanceNotFoundException) extractException(pe); - } - } - - @SuppressWarnings("removal") private ClassLoader getClassLoaderFor(final ObjectName name) throws InstanceNotFoundException { - try { - return (ClassLoader) - AccessController.doPrivileged( - new PrivilegedExceptionAction<Object>() { - public Object run() throws InstanceNotFoundException { - return mbeanServer.getClassLoaderFor(name); - } - }, - withPermissions(new MBeanPermission("*", "getClassLoaderFor")) - ); - } catch (PrivilegedActionException pe) { - throw (InstanceNotFoundException) extractException(pe); - } + + return mbeanServer.getClassLoaderFor(name); } /** @throws UnsupportedOperationException {@inheritDoc} */ - @SuppressWarnings("removal") private Object doPrivilegedOperation(final int operation, final Object[] params, final Subject delegationSubject) @@ -1402,10 +1305,9 @@ private Object doPrivilegedOperation(final int operation, } serverCommunicatorAdmin.reqIncoming(); try { - PrivilegedOperation op = new PrivilegedOperation(operation, params); if (subject == null) { try { - return op.run(); + return doOperation(operation, params); } catch (Exception e) { if (e instanceof RuntimeException) { throw (RuntimeException) e; @@ -1414,7 +1316,20 @@ private Object doPrivilegedOperation(final int operation, } } } else { - return Subject.doAs(subject, op); + try { + return Subject.callAs(subject, () -> doOperation(operation, params)); + } catch (CompletionException ce) { + Throwable thr = ce.getCause(); + if (thr instanceof SecurityException se) { + throw se; + } else if (thr instanceof IOException ioe) { + throw ioe; + } else if (thr instanceof Exception e1) { + throw new PrivilegedActionException(e1); + } else { + throw new RuntimeException(thr); + } + } } } catch (Error e) { throw new JMXServerErrorException(e.toString(),e); @@ -1545,24 +1460,15 @@ private Object doOperation(int operation, Object[] params) } } - private static class SetCcl implements PrivilegedExceptionAction<ClassLoader> { - private final ClassLoader classLoader; - - SetCcl(ClassLoader classLoader) { - this.classLoader = classLoader; - } - - public ClassLoader run() { - Thread currentThread = Thread.currentThread(); - ClassLoader old = currentThread.getContextClassLoader(); - if (classLoader != old) { - currentThread.setContextClassLoader(classLoader); - } - return old; + private static ClassLoader setCcl(ClassLoader classLoader) { + Thread currentThread = Thread.currentThread(); + ClassLoader old = currentThread.getContextClassLoader(); + if (classLoader != old) { + currentThread.setContextClassLoader(classLoader); } + return old; } - @SuppressWarnings("removal") private <T> T unwrap(final MarshalledObject<?> mo, final ClassLoader cl, final Class<T> wrappedClass, @@ -1578,32 +1484,33 @@ private <T> T unwrap(final MarshalledObject<?> mo, return null; } try { - final ClassLoader old = AccessController.doPrivileged(new SetCcl(cl)); + ClassLoader old = setCcl(cl); try { if (subject != null) { - return Subject.doAs(subject, (PrivilegedExceptionAction<T>) () -> wrappedClass.cast(mo.get())); + try { + return Subject.callAs(subject, () -> wrappedClass.cast(mo.get())); + } catch (CompletionException ce) { + Throwable thr = ce.getCause(); + if (thr instanceof Exception e) { + throw e; + } else { + throw new RuntimeException(thr); + } + } } else { return wrappedClass.cast(mo.get()); } } finally { - AccessController.doPrivileged(new SetCcl(old)); + setCcl(old); } - } catch (PrivilegedActionException pe) { - Exception e = extractException(pe); + } catch (Exception e) { if (e instanceof IOException) { throw (IOException) e; } - if (e instanceof ClassNotFoundException) { - throw new UnmarshalException(e.toString(), e); - } logger.warning("unwrap", "Failed to unmarshall object: " + e); logger.debug("unwrap", e); - }catch (ClassNotFoundException ex) { - logger.warning("unwrap", "Failed to unmarshall object: " + ex); - logger.debug("unwrap", ex); - throw new UnmarshalException(ex.toString(), ex); + throw new UnmarshalException(e.toString(), e); } - return null; } private <T> T unwrap(final MarshalledObject<?> mo, @@ -1616,18 +1523,10 @@ private <T> T unwrap(final MarshalledObject<?> mo, return null; } try { - @SuppressWarnings("removal") - ClassLoader orderCL = AccessController.doPrivileged( - new PrivilegedExceptionAction<ClassLoader>() { - public ClassLoader run() throws Exception { - return new CombinedClassLoader(Thread.currentThread().getContextClassLoader(), - new OrderClassLoaders(cl1, cl2)); - } - } - ); + ClassLoader orderCL = new CombinedClassLoader(Thread.currentThread().getContextClassLoader(), + new OrderClassLoaders(cl1, cl2)); return unwrap(mo, orderCL, wrappedClass,delegationSubject); - } catch (PrivilegedActionException pe) { - Exception e = extractException(pe); + } catch (Exception e) { if (e instanceof IOException) { throw (IOException) e; } @@ -1815,7 +1714,6 @@ private CombinedClassLoader(ClassLoader parent, ClassLoader defaultCL) { @Override protected Class<?> loadClass(String name, boolean resolve) throws ClassNotFoundException { - ReflectUtil.checkPackageAccess(name); try { super.loadClass(name, resolve); } catch(Exception e) { diff --git a/src/java.management.rmi/share/classes/javax/management/remote/rmi/RMIConnector.java b/src/java.management.rmi/share/classes/javax/management/remote/rmi/RMIConnector.java index 24b9f1055b7..47089dcd252 100644 --- a/src/java.management.rmi/share/classes/javax/management/remote/rmi/RMIConnector.java +++ b/src/java.management.rmi/share/classes/javax/management/remote/rmi/RMIConnector.java @@ -54,9 +54,6 @@ import java.rmi.server.RemoteObject; import java.rmi.server.RemoteObjectInvocationHandler; import java.rmi.server.RemoteRef; -import java.security.AccessController; -import java.security.PrivilegedAction; -import java.security.PrivilegedExceptionAction; import java.security.ProtectionDomain; import java.util.Arrays; import java.util.Collections; @@ -102,7 +99,6 @@ import javax.rmi.ssl.SslRMIClientSocketFactory; import javax.security.auth.Subject; import jdk.internal.module.Modules; -import sun.reflect.misc.ReflectUtil; import sun.rmi.server.UnicastRef2; import sun.rmi.transport.LiveRef; import java.io.NotSerializableException; @@ -1856,7 +1852,6 @@ private static final class ObjectInputStreamWithLoader protected Class<?> resolveClass(ObjectStreamClass classDesc) throws IOException, ClassNotFoundException { String name = classDesc.getName(); - ReflectUtil.checkPackageAccess(name); return Class.forName(name, false, Objects.requireNonNull(loader)); } @@ -1964,51 +1959,7 @@ public Object invoke(Remote obj, Method method, "\4\0\1\0\14\0\0"; final byte[] pRefByteCode = NoCallStackClassLoader.stringToBytes(pRefByteCodeString); - PrivilegedExceptionAction<Constructor<?>> action = - new PrivilegedExceptionAction<Constructor<?>>() { - public Constructor<?> run() throws Exception { - Class<RMIConnector> thisClass = RMIConnector.class; - ClassLoader thisLoader = thisClass.getClassLoader(); - ProtectionDomain thisProtectionDomain = - thisClass.getProtectionDomain(); - - String proxyRefCName = ProxyRef.class.getName(); - ClassLoader cl = - new NoCallStackClassLoader(pRefClassName, - pRefByteCode, - new String[] { proxyRefCName }, - thisLoader, - thisProtectionDomain); - - Module jmxModule = ProxyRef.class.getModule(); - Module rmiModule = RemoteRef.class.getModule(); - - String pkg = packageOf(pRefClassName); - assert pkg != null && pkg.length() > 0 && - !pkg.equals(packageOf(proxyRefCName)); - - ModuleDescriptor descriptor = - ModuleDescriptor.newModule("jdk.remoteref", Set.of(SYNTHETIC)) - .packages(Set.of(pkg)) - .build(); - Module m = Modules.defineModule(cl, descriptor, null); - - // jdk.remoteref needs to read to java.base and jmxModule - Modules.addReads(m, Object.class.getModule()); - Modules.addReads(m, jmxModule); - Modules.addReads(m, rmiModule); - - // jdk.remoteref needs access to ProxyRef class - Modules.addExports(jmxModule, packageOf(proxyRefCName), m); - - // java.management needs to instantiate the fabricated RemoteRef class - Modules.addReads(jmxModule, m); - Modules.addExports(m, pkg, jmxModule); - - Class<?> c = cl.loadClass(pRefClassName); - return c.getConstructor(RemoteRef.class); - } - }; + Class<?> serverStubClass; try { @@ -2026,9 +1977,48 @@ public Constructor<?> run() throws Exception { Constructor<?> constr; try { stubClass = Class.forName(rmiConnectionImplStubClassName); - @SuppressWarnings("removal") - Constructor<?> tmp = (Constructor<?>) AccessController.doPrivileged(action); - constr = tmp; + + Class<RMIConnector> thisClass = RMIConnector.class; + ClassLoader thisLoader = thisClass.getClassLoader(); + ProtectionDomain thisProtectionDomain = + thisClass.getProtectionDomain(); + + String proxyRefCName = ProxyRef.class.getName(); + ClassLoader cl = + new NoCallStackClassLoader(pRefClassName, + pRefByteCode, + new String[] { proxyRefCName }, + thisLoader, + thisProtectionDomain); + + Module jmxModule = ProxyRef.class.getModule(); + Module rmiModule = RemoteRef.class.getModule(); + + String pkg = packageOf(pRefClassName); + assert pkg != null && pkg.length() > 0 && + !pkg.equals(packageOf(proxyRefCName)); + + ModuleDescriptor descriptor = + ModuleDescriptor.newModule("jdk.remoteref", Set.of(SYNTHETIC)) + .packages(Set.of(pkg)) + .build(); + Module m = Modules.defineModule(cl, descriptor, null); + + // jdk.remoteref needs to read to java.base and jmxModule + Modules.addReads(m, Object.class.getModule()); + Modules.addReads(m, jmxModule); + Modules.addReads(m, rmiModule); + + // jdk.remoteref needs access to ProxyRef class + Modules.addExports(jmxModule, packageOf(proxyRefCName), m); + + // java.management needs to instantiate the fabricated RemoteRef class + Modules.addReads(jmxModule, m); + Modules.addExports(m, pkg, jmxModule); + + Class<?> c = cl.loadClass(pRefClassName); + + constr = c.getConstructor(RemoteRef.class); } catch (Exception e) { logger.error("<clinit>", "Failed to initialize proxy reference constructor "+ @@ -2172,33 +2162,22 @@ private static int base64toInt(char c) { //-------------------------------------------------------------------- // Private stuff - Find / Set default class loader //-------------------------------------------------------------------- - @SuppressWarnings("removal") private ClassLoader pushDefaultClassLoader() { final Thread t = Thread.currentThread(); final ClassLoader old = t.getContextClassLoader(); - if (defaultClassLoader != null) - AccessController.doPrivileged(new PrivilegedAction<Void>() { - public Void run() { - if (t.getContextClassLoader() != defaultClassLoader) { - t.setContextClassLoader(defaultClassLoader); - } - return null; - } - }); - return old; + if (defaultClassLoader != null) { + if (t.getContextClassLoader() != defaultClassLoader) { + t.setContextClassLoader(defaultClassLoader); + } + } + return old; } - @SuppressWarnings("removal") private void popDefaultClassLoader(final ClassLoader old) { - AccessController.doPrivileged(new PrivilegedAction<Void>() { - public Void run() { - Thread t = Thread.currentThread(); - if (t.getContextClassLoader() != old) { - t.setContextClassLoader(old); - } - return null; - } - }); + Thread t = Thread.currentThread(); + if (t.getContextClassLoader() != old) { + t.setContextClassLoader(old); + } } //-------------------------------------------------------------------- diff --git a/src/java.management.rmi/share/classes/javax/management/remote/rmi/RMIJRMPServerImpl.java b/src/java.management.rmi/share/classes/javax/management/remote/rmi/RMIJRMPServerImpl.java index d51ca2cd26e..44e85f1bde2 100644 --- a/src/java.management.rmi/share/classes/javax/management/remote/rmi/RMIJRMPServerImpl.java +++ b/src/java.management.rmi/share/classes/javax/management/remote/rmi/RMIJRMPServerImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -43,7 +43,6 @@ import java.util.Arrays; import java.util.Set; import java.util.stream.Collectors; -import sun.reflect.misc.ReflectUtil; import sun.rmi.server.UnicastServerRef; import sun.rmi.server.UnicastServerRef2; import sun.rmi.transport.LiveRef; @@ -119,7 +118,6 @@ else if(credentialsFilter != null){ else if (credentialsTypes != null) { allowedTypes = Arrays.stream(credentialsTypes).filter( s -> s!= null).collect(Collectors.toSet()); - allowedTypes.forEach(ReflectUtil::checkPackageAccess); cFilter = this::newClientCheckInput; } else { allowedTypes = null; From 43000a34d5ba6e2e997893a90dac0fe6693611cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eirik=20Bj=C3=B8rsn=C3=B8s?= <eirbjo@openjdk.org> Date: Thu, 28 Nov 2024 17:38:07 +0000 Subject: [PATCH 310/311] 8345075: java.lang.module.ModuleDescriptor constructor could be made private Reviewed-by: alanb --- .../java/lang/module/ModuleDescriptor.java | 26 +++++++++---------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/src/java.base/share/classes/java/lang/module/ModuleDescriptor.java b/src/java.base/share/classes/java/lang/module/ModuleDescriptor.java index b38d1b0cc87..4b43a457b88 100644 --- a/src/java.base/share/classes/java/lang/module/ModuleDescriptor.java +++ b/src/java.base/share/classes/java/lang/module/ModuleDescriptor.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2009, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2009, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -1312,18 +1312,18 @@ private ModuleDescriptor(String name, * Creates a module descriptor from its components. * The arguments are pre-validated and sets are unmodifiable sets. */ - ModuleDescriptor(String name, - Version version, - Set<Modifier> modifiers, - Set<Requires> requires, - Set<Exports> exports, - Set<Opens> opens, - Set<String> uses, - Set<Provides> provides, - Set<String> packages, - String mainClass, - int hashCode, - boolean unused) { + private ModuleDescriptor(String name, + Version version, + Set<Modifier> modifiers, + Set<Requires> requires, + Set<Exports> exports, + Set<Opens> opens, + Set<String> uses, + Set<Provides> provides, + Set<String> packages, + String mainClass, + int hashCode, + boolean unused) { this.name = name; this.version = version; this.rawVersionString = null; From 959fa4a1a35a1bb650ec5888efaf3d0fc8cfb025 Mon Sep 17 00:00:00 2001 From: Aleksei Efimov <aefimov@openjdk.org> Date: Thu, 28 Nov 2024 17:43:27 +0000 Subject: [PATCH 311/311] 8344299: SM cleanup in javax.naming modules Reviewed-by: alanb, dfuchs --- .../sun/security/util/SecurityConstants.java | 4 -- .../classes/com/sun/jndi/ldap/ClientId.java | 6 +- .../classes/com/sun/jndi/ldap/Connection.java | 11 ++- .../classes/com/sun/jndi/ldap/EventQueue.java | 2 +- .../sun/jndi/ldap/LdapBindingEnumeration.java | 17 +---- .../classes/com/sun/jndi/ldap/LdapCtx.java | 13 +--- .../sun/jndi/ldap/LdapDnsProviderService.java | 26 ++----- .../com/sun/jndi/ldap/LdapPoolManager.java | 60 +++++----------- .../sun/jndi/ldap/LdapSearchEnumeration.java | 17 +---- .../classes/com/sun/jndi/ldap/LdapURL.java | 9 +-- .../sun/jndi/ldap/NamingEventNotifier.java | 2 +- .../share/classes/com/sun/jndi/ldap/Obj.java | 21 ++++-- .../com/sun/jndi/ldap/VersionHelper.java | 72 ------------------- .../javax/naming/ldap/StartTlsRequest.java | 24 +------ .../naming/ldap/spi/LdapDnsProvider.java | 19 ----- .../javax/naming/spi/NamingManager.java | 21 +----- .../provider/certpath/ldap/JdkLDAP.java | 27 +++---- .../provider/certpath/ldap/LDAPCertStore.java | 8 +-- .../certpath/ldap/LDAPCertStoreImpl.java | 11 ++- .../jndi/dns/DNSDatagramChannelFactory.java | 8 +-- .../com/sun/jndi/dns/DnsContextFactory.java | 49 ++----------- .../classes/com/sun/jndi/dns/DnsUrl.java | 10 +-- .../jndi/rmi/registry/RegistryContext.java | 24 ------- .../com/sun/jndi/url/rmi/rmiURLContext.java | 9 +-- 24 files changed, 88 insertions(+), 382 deletions(-) delete mode 100644 src/java.naming/share/classes/com/sun/jndi/ldap/VersionHelper.java diff --git a/src/java.base/share/classes/sun/security/util/SecurityConstants.java b/src/java.base/share/classes/sun/security/util/SecurityConstants.java index 21ec592c766..9d49bbba0a1 100644 --- a/src/java.base/share/classes/sun/security/util/SecurityConstants.java +++ b/src/java.base/share/classes/sun/security/util/SecurityConstants.java @@ -96,10 +96,6 @@ private SecurityConstants () { public static final RuntimePermission GET_PD_PERMISSION = new RuntimePermission("getProtectionDomain"); - // java.lang.Class, java.lang.ClassLoader, java.lang.Thread - public static final RuntimePermission GET_CLASSLOADER_PERMISSION = - new RuntimePermission("getClassLoader"); - // java.lang.Thread public static final RuntimePermission GET_STACK_TRACE_PERMISSION = new RuntimePermission("getStackTrace"); diff --git a/src/java.naming/share/classes/com/sun/jndi/ldap/ClientId.java b/src/java.naming/share/classes/com/sun/jndi/ldap/ClientId.java index 7348692ad30..20a8cdcf148 100644 --- a/src/java.naming/share/classes/com/sun/jndi/ldap/ClientId.java +++ b/src/java.naming/share/classes/com/sun/jndi/ldap/ClientId.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -84,8 +84,8 @@ class ClientId { if ((socketFactory != null) && !socketFactory.equals(LdapCtx.DEFAULT_SSL_FACTORY)) { try { - Class<?> socketFactoryClass = - Obj.helper.loadClass(socketFactory); + Class<?> socketFactoryClass = Class.forName(socketFactory, + true, Thread.currentThread().getContextClassLoader()); this.sockComparator = socketFactoryClass.getMethod( "compare", new Class<?>[]{Object.class, Object.class}); Method getDefault = socketFactoryClass.getMethod( diff --git a/src/java.naming/share/classes/com/sun/jndi/ldap/Connection.java b/src/java.naming/share/classes/com/sun/jndi/ldap/Connection.java index f270a34d5b7..8166fe97a4a 100644 --- a/src/java.naming/share/classes/com/sun/jndi/ldap/Connection.java +++ b/src/java.naming/share/classes/com/sun/jndi/ldap/Connection.java @@ -44,8 +44,6 @@ import java.lang.reflect.Method; import java.lang.reflect.InvocationTargetException; -import java.security.AccessController; -import java.security.PrivilegedAction; import java.security.cert.Certificate; import java.security.cert.X509Certificate; import java.util.Arrays; @@ -183,10 +181,8 @@ public final class Connection implements Runnable { = hostnameVerificationDisabledValue(); private static boolean hostnameVerificationDisabledValue() { - PrivilegedAction<String> act = () -> System.getProperty( + String prop = System.getProperty( "com.sun.jndi.ldap.object.disableEndpointIdentification"); - @SuppressWarnings("removal") - String prop = AccessController.doPrivileged(act); if (prop == null) { return false; } @@ -259,7 +255,7 @@ void setBound() { throw ce; } - worker = Obj.helper.createThread(this); + worker = new Thread(this); worker.setDaemon(true); worker.start(); } @@ -313,7 +309,8 @@ private SocketFactory getSocketFactory(String socketFactoryName) throws Exceptio } @SuppressWarnings("unchecked") Class<? extends SocketFactory> socketFactoryClass = - (Class<? extends SocketFactory>) Obj.helper.loadClass(socketFactoryName); + (Class<? extends SocketFactory>) Class.forName(socketFactoryName, + true, Thread.currentThread().getContextClassLoader()); Method getDefault = socketFactoryClass.getMethod("getDefault"); SocketFactory factory = (SocketFactory) getDefault.invoke(null, new Object[]{}); diff --git a/src/java.naming/share/classes/com/sun/jndi/ldap/EventQueue.java b/src/java.naming/share/classes/com/sun/jndi/ldap/EventQueue.java index 3d88e179894..4f1cb9ec6a7 100644 --- a/src/java.naming/share/classes/com/sun/jndi/ldap/EventQueue.java +++ b/src/java.naming/share/classes/com/sun/jndi/ldap/EventQueue.java @@ -71,7 +71,7 @@ private static class QueueElement { // package private EventQueue() { - qThread = Obj.helper.createThread(this); + qThread = new Thread(this); qThread.setDaemon(true); // not a user thread qThread.start(); } diff --git a/src/java.naming/share/classes/com/sun/jndi/ldap/LdapBindingEnumeration.java b/src/java.naming/share/classes/com/sun/jndi/ldap/LdapBindingEnumeration.java index 53a33a57097..5259cb63801 100644 --- a/src/java.naming/share/classes/com/sun/jndi/ldap/LdapBindingEnumeration.java +++ b/src/java.naming/share/classes/com/sun/jndi/ldap/LdapBindingEnumeration.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,10 +25,6 @@ package com.sun.jndi.ldap; -import java.security.AccessControlContext; -import java.security.AccessController; -import java.security.PrivilegedActionException; -import java.security.PrivilegedExceptionAction; import java.util.Vector; import javax.naming.*; import javax.naming.directory.*; @@ -41,16 +37,12 @@ final class LdapBindingEnumeration extends AbstractLdapNamingEnumeration<Binding> { - @SuppressWarnings("removal") - private final AccessControlContext acc = AccessController.getContext(); - LdapBindingEnumeration(LdapCtx homeCtx, LdapResult answer, Name remain, Continuation cont) throws NamingException { super(homeCtx, answer, remain, cont); } - @SuppressWarnings("removal") @Override protected Binding createItem(String dn, Attributes attrs, Vector<Control> respCtls) @@ -61,12 +53,7 @@ final class LdapBindingEnumeration if (attrs.get(Obj.JAVA_ATTRIBUTES[Obj.CLASSNAME]) != null) { // serialized object or object reference - try { - PrivilegedExceptionAction<Object> pa = () -> Obj.decodeObject(attrs); - obj = AccessController.doPrivileged(pa, acc); - } catch (PrivilegedActionException e) { - throw (NamingException)e.getException(); - } + obj = Obj.decodeObject(attrs); } if (obj == null) { // DirContext object diff --git a/src/java.naming/share/classes/com/sun/jndi/ldap/LdapCtx.java b/src/java.naming/share/classes/com/sun/jndi/ldap/LdapCtx.java index 27ecb9e4ca1..0695894f300 100644 --- a/src/java.naming/share/classes/com/sun/jndi/ldap/LdapCtx.java +++ b/src/java.naming/share/classes/com/sun/jndi/ldap/LdapCtx.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -32,8 +32,6 @@ import javax.naming.ldap.LdapName; import javax.naming.ldap.Rdn; -import java.security.AccessController; -import java.security.PrivilegedAction; import java.util.Arrays; import java.util.Collections; import java.util.Locale; @@ -220,7 +218,7 @@ static final class SearchArgs { // System property value private static final String ALLOWED_MECHS_SP_VALUE = - getMechsAllowedToSendCredentials(); + System.getProperty(ALLOWED_MECHS_SP); // Set of authentication mechanisms allowed by the system property private static final Set<String> MECHS_ALLOWED_BY_SP = @@ -2706,13 +2704,6 @@ public void reconnect(Control[] connCtls) throws NamingException { ensureOpen(); // open or reauthenticated } - // Load 'mechsAllowedToSendCredentials' system property value - @SuppressWarnings("removal") - private static String getMechsAllowedToSendCredentials() { - PrivilegedAction<String> pa = () -> System.getProperty(ALLOWED_MECHS_SP); - return System.getSecurityManager() == null ? pa.run() : AccessController.doPrivileged(pa); - } - // Get set of allowed authentication mechanism names from the property value private static Set<String> getMechsFromPropertyValue(String propValue) { if (propValue == null || propValue.isBlank()) { diff --git a/src/java.naming/share/classes/com/sun/jndi/ldap/LdapDnsProviderService.java b/src/java.naming/share/classes/com/sun/jndi/ldap/LdapDnsProviderService.java index 9330782f48c..da9c66489ad 100644 --- a/src/java.naming/share/classes/com/sun/jndi/ldap/LdapDnsProviderService.java +++ b/src/java.naming/share/classes/com/sun/jndi/ldap/LdapDnsProviderService.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,14 +25,11 @@ package com.sun.jndi.ldap; -import java.security.AccessController; -import java.security.PrivilegedAction; import java.util.*; import java.util.concurrent.locks.ReentrantLock; import javax.naming.NamingException; import javax.naming.ldap.spi.LdapDnsProvider; import javax.naming.ldap.spi.LdapDnsProviderResult; -import sun.security.util.SecurityConstants; /** * The {@code LdapDnsProviderService} is responsible for creating and providing @@ -50,25 +47,10 @@ final class LdapDnsProviderService { /** * Creates a new instance of LdapDnsProviderService */ - @SuppressWarnings("removal") private LdapDnsProviderService() { - SecurityManager sm = System.getSecurityManager(); - if (sm == null) { - providers = ServiceLoader.load( - LdapDnsProvider.class, - ClassLoader.getSystemClassLoader()); - } else { - final PrivilegedAction<ServiceLoader<LdapDnsProvider>> pa = - () -> ServiceLoader.load( - LdapDnsProvider.class, - ClassLoader.getSystemClassLoader()); - - providers = AccessController.doPrivileged( - pa, - null, - new RuntimePermission("ldapDnsProvider"), - SecurityConstants.GET_CLASSLOADER_PERMISSION); - } + providers = ServiceLoader.load( + LdapDnsProvider.class, + ClassLoader.getSystemClassLoader()); } /** diff --git a/src/java.naming/share/classes/com/sun/jndi/ldap/LdapPoolManager.java b/src/java.naming/share/classes/com/sun/jndi/ldap/LdapPoolManager.java index ef122351437..384e1ace289 100644 --- a/src/java.naming/share/classes/com/sun/jndi/ldap/LdapPoolManager.java +++ b/src/java.naming/share/classes/com/sun/jndi/ldap/LdapPoolManager.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2002, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2002, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -34,8 +34,6 @@ import javax.naming.ldap.Control; import javax.naming.NamingException; import javax.naming.CommunicationException; -import java.security.AccessController; -import java.security.PrivilegedAction; import com.sun.jndi.ldap.pool.PoolCleaner; import com.sun.jndi.ldap.pool.Pool; @@ -60,10 +58,10 @@ public final class LdapPoolManager { "com.sun.jndi.ldap.connect.pool.debug"; public static final boolean debug = - "all".equalsIgnoreCase(getProperty(DEBUG, null)); + "all".equalsIgnoreCase(System.getProperty(DEBUG)); public static final boolean trace = debug || - "fine".equalsIgnoreCase(getProperty(DEBUG, null)); + "fine".equalsIgnoreCase(System.getProperty(DEBUG)); // ---------- System properties for connection pooling @@ -120,16 +118,16 @@ public final class LdapPoolManager { private static final Pool[] pools = new Pool[3]; static { - maxSize = getInteger(MAX_POOL_SIZE, DEFAULT_MAX_POOL_SIZE); + maxSize = Integer.getInteger(MAX_POOL_SIZE, DEFAULT_MAX_POOL_SIZE); - prefSize = getInteger(PREF_POOL_SIZE, DEFAULT_PREF_POOL_SIZE); + prefSize = Integer.getInteger(PREF_POOL_SIZE, DEFAULT_PREF_POOL_SIZE); - initSize = getInteger(INIT_POOL_SIZE, DEFAULT_INIT_POOL_SIZE); + initSize = Integer.getInteger(INIT_POOL_SIZE, DEFAULT_INIT_POOL_SIZE); - idleTimeout = getLong(POOL_TIMEOUT, DEFAULT_TIMEOUT); + idleTimeout = Long.getLong(POOL_TIMEOUT, DEFAULT_TIMEOUT); // Determine supported authentication mechanisms - String str = getProperty(POOL_AUTH, DEFAULT_AUTH_MECHS); + String str = System.getProperty(POOL_AUTH, DEFAULT_AUTH_MECHS); StringTokenizer parser = new StringTokenizer(str); int count = parser.countTokens(); String mech; @@ -147,7 +145,7 @@ public final class LdapPoolManager { } // Determine supported protocols - str= getProperty(POOL_PROTOCOL, DEFAULT_PROTOCOLS); + str = System.getProperty(POOL_PROTOCOL, DEFAULT_PROTOCOLS); parser = new StringTokenizer(str); count = parser.countTokens(); String proto; @@ -171,20 +169,15 @@ public final class LdapPoolManager { } } - @SuppressWarnings("removal") private static void startCleanerThread() { // Create cleaner to expire idle connections - PrivilegedAction<Void> pa = new PrivilegedAction<Void>() { - public Void run() { - Thread t = InnocuousThread.newSystemThread( - "LDAP PoolCleaner", - new PoolCleaner(idleTimeout, pools)); - assert t.getContextClassLoader() == null; - t.setDaemon(true); - t.start(); - return null; - }}; - AccessController.doPrivileged(pa); + Thread t = InnocuousThread.newSystemThread( + "LDAP PoolCleaner", + new PoolCleaner(idleTimeout, pools)); + assert t.getContextClassLoader() == null; + t.setDaemon(true); + t.start(); + } // Cannot instantiate one of these @@ -252,7 +245,8 @@ static boolean isPoolingAllowed(String socketFactory, OutputStream trace, if ((socketFactory != null) && !socketFactory.equals(LdapCtx.DEFAULT_SSL_FACTORY)) { try { - Class<?> socketFactoryClass = Obj.helper.loadClass(socketFactory); + Class<?> socketFactoryClass = Class.forName(socketFactory, true, + Thread.currentThread().getContextClassLoader()); Class<?>[] interfaces = socketFactoryClass.getInterfaces(); for (int i = 0; i < interfaces.length; i++) { if (interfaces[i].getCanonicalName().equals(COMPARATOR)) { @@ -399,22 +393,4 @@ private static void d(String msg, String o) { System.err.println("LdapPoolManager: " + msg + o); } } - - @SuppressWarnings("removal") - private static final String getProperty(final String propName, final String defVal) { - PrivilegedAction<String> pa = () -> System.getProperty(propName, defVal); - return AccessController.doPrivileged(pa); - } - - @SuppressWarnings("removal") - private static final int getInteger(final String propName, final int defVal) { - PrivilegedAction<Integer> pa = () -> Integer.getInteger(propName, defVal); - return AccessController.doPrivileged(pa); - } - - @SuppressWarnings("removal") - private static final long getLong(final String propName, final long defVal) { - PrivilegedAction<Long> pa = () -> Long.getLong(propName, defVal); - return AccessController.doPrivileged(pa); - } } diff --git a/src/java.naming/share/classes/com/sun/jndi/ldap/LdapSearchEnumeration.java b/src/java.naming/share/classes/com/sun/jndi/ldap/LdapSearchEnumeration.java index 50f26851892..6f1981df102 100644 --- a/src/java.naming/share/classes/com/sun/jndi/ldap/LdapSearchEnumeration.java +++ b/src/java.naming/share/classes/com/sun/jndi/ldap/LdapSearchEnumeration.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,10 +25,6 @@ package com.sun.jndi.ldap; -import java.security.AccessControlContext; -import java.security.AccessController; -import java.security.PrivilegedActionException; -import java.security.PrivilegedExceptionAction; import java.util.Vector; import javax.naming.*; import javax.naming.directory.*; @@ -45,9 +41,6 @@ final class LdapSearchEnumeration private Name startName; // prefix of names of search results private LdapCtx.SearchArgs searchArgs = null; - @SuppressWarnings("removal") - private final AccessControlContext acc = AccessController.getContext(); - LdapSearchEnumeration(LdapCtx homeCtx, LdapResult search_results, String starter, LdapCtx.SearchArgs args, Continuation cont) throws NamingException { @@ -61,7 +54,6 @@ final class LdapSearchEnumeration searchArgs = args; } - @SuppressWarnings("removal") @Override protected SearchResult createItem(String dn, Attributes attrs, Vector<Control> respCtls) @@ -121,12 +113,7 @@ protected SearchResult createItem(String dn, Attributes attrs, if (attrs.get(Obj.JAVA_ATTRIBUTES[Obj.CLASSNAME]) != null) { // Entry contains Java-object attributes (ser/ref object) // serialized object or object reference - try { - PrivilegedExceptionAction<Object> pea = () -> Obj.decodeObject(attrs); - obj = AccessController.doPrivileged(pea, acc); - } catch (PrivilegedActionException e) { - throw (NamingException)e.getException(); - } + obj = Obj.decodeObject(attrs); } if (obj == null) { obj = new LdapCtx(homeCtx, dn); diff --git a/src/java.naming/share/classes/com/sun/jndi/ldap/LdapURL.java b/src/java.naming/share/classes/com/sun/jndi/ldap/LdapURL.java index f26e086d6a7..140f025b779 100644 --- a/src/java.naming/share/classes/com/sun/jndi/ldap/LdapURL.java +++ b/src/java.naming/share/classes/com/sun/jndi/ldap/LdapURL.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -29,8 +29,6 @@ import java.net.MalformedURLException; import java.io.UnsupportedEncodingException; import java.net.URI; -import java.security.AccessController; -import java.security.PrivilegedAction; import java.util.Locale; import java.util.StringTokenizer; import com.sun.jndi.toolkit.url.Uri; @@ -73,12 +71,9 @@ public final class LdapURL extends Uri { public static final ParseMode PARSE_MODE; static { - PrivilegedAction<String> action = () -> - System.getProperty(PARSE_MODE_PROP, DEFAULT_PARSE_MODE.toString()); ParseMode parseMode = DEFAULT_PARSE_MODE; try { - @SuppressWarnings("removal") - String mode = AccessController.doPrivileged(action); + String mode = System.getProperty(PARSE_MODE_PROP, DEFAULT_PARSE_MODE.toString()); parseMode = ParseMode.valueOf(mode.toUpperCase(Locale.ROOT)); } catch (Throwable t) { parseMode = DEFAULT_PARSE_MODE; diff --git a/src/java.naming/share/classes/com/sun/jndi/ldap/NamingEventNotifier.java b/src/java.naming/share/classes/com/sun/jndi/ldap/NamingEventNotifier.java index 27b83b91515..40a8173b768 100644 --- a/src/java.naming/share/classes/com/sun/jndi/ldap/NamingEventNotifier.java +++ b/src/java.naming/share/classes/com/sun/jndi/ldap/NamingEventNotifier.java @@ -86,7 +86,7 @@ final class NamingEventNotifier implements Runnable { namingListeners = new Vector<>(); namingListeners.addElement(firstListener); - worker = Obj.helper.createThread(this); + worker = new Thread(this); worker.setDaemon(true); // not a user thread worker.start(); } diff --git a/src/java.naming/share/classes/com/sun/jndi/ldap/Obj.java b/src/java.naming/share/classes/com/sun/jndi/ldap/Obj.java index 0d28928559f..5e34f954302 100644 --- a/src/java.naming/share/classes/com/sun/jndi/ldap/Obj.java +++ b/src/java.naming/share/classes/com/sun/jndi/ldap/Obj.java @@ -57,8 +57,19 @@ final class Obj { private Obj () {}; // Make sure no one can create one - // package private; used by Connection - static VersionHelper helper = VersionHelper.getVersionHelper(); + /** + * Determines whether objects may be deserialized or reconstructed from a content of + * 'javaSerializedData', 'javaRemoteLocation' or 'javaReferenceAddress' LDAP attributes. + */ + private static final boolean trustSerialData; + + static { + // System property to control whether classes are allowed to be loaded from + // 'javaSerializedData', 'javaRemoteLocation' or 'javaReferenceAddress' attributes. + String trustSerialDataSp = System.getProperty( + "com.sun.jndi.ldap.object.trustSerialData", "false"); + trustSerialData = "true".equalsIgnoreCase(trustSerialDataSp); + } // LDAP attributes used to support Java objects. static final String[] JAVA_ATTRIBUTES = { @@ -233,14 +244,14 @@ static Object decodeObject(Attributes attrs) String[] codebases = getCodebases(attrs.get(JAVA_ATTRIBUTES[CODEBASE])); try { if ((attr = attrs.get(JAVA_ATTRIBUTES[SERIALIZED_DATA])) != null) { - if (!VersionHelper.isSerialDataAllowed()) { + if (!trustSerialData) { throw new NamingException("Object deserialization is not allowed"); } ClassLoader cl = Thread.currentThread().getContextClassLoader(); return deserializeObject((byte[])attr.get(), cl); } else if ((attr = attrs.get(JAVA_ATTRIBUTES[REMOTE_LOC])) != null) { // javaRemoteLocation attribute (RMI stub will be created) - if (!VersionHelper.isSerialDataAllowed()) { + if (!trustSerialData) { throw new NamingException("Object deserialization is not allowed"); } // For backward compatibility only @@ -471,7 +482,7 @@ private static Reference decodeReference(Attributes attrs, } else if (val.charAt(start) == separator) { // Check if deserialization of binary RefAddr is allowed from // 'javaReferenceAddress' LDAP attribute. - if (!VersionHelper.isSerialDataAllowed()) { + if (!trustSerialData) { throw new NamingException("Object deserialization is not allowed"); } diff --git a/src/java.naming/share/classes/com/sun/jndi/ldap/VersionHelper.java b/src/java.naming/share/classes/com/sun/jndi/ldap/VersionHelper.java deleted file mode 100644 index bb888a1457a..00000000000 --- a/src/java.naming/share/classes/com/sun/jndi/ldap/VersionHelper.java +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. Oracle designates this - * particular file as subject to the "Classpath" exception as provided - * by Oracle in the LICENSE file that accompanied this code. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ - -package com.sun.jndi.ldap; - -public final class VersionHelper { - - private static final VersionHelper helper = new VersionHelper(); - - /** - * Determines whether objects may be deserialized or reconstructed from a content of - * 'javaSerializedData', 'javaRemoteLocation' or 'javaReferenceAddress' LDAP attributes. - */ - private static final boolean trustSerialData; - - static { - // System property to control whether classes are allowed to be loaded from - // 'javaSerializedData', 'javaRemoteLocation' or 'javaReferenceAddress' attributes. - String trustSerialDataSp = System.getProperty( - "com.sun.jndi.ldap.object.trustSerialData", "false"); - trustSerialData = "true".equalsIgnoreCase(trustSerialDataSp); - } - - private VersionHelper() { - } - - static VersionHelper getVersionHelper() { - return helper; - } - - /** - * Returns true if deserialization or reconstruction of objects from - * 'javaSerializedData', 'javaRemoteLocation' and 'javaReferenceAddress' - * LDAP attributes is allowed. - * - * @return true if deserialization is allowed; false - otherwise - */ - public static boolean isSerialDataAllowed() { - return trustSerialData; - } - - Class<?> loadClass(String className) throws ClassNotFoundException { - return Class.forName(className, true, - Thread.currentThread().getContextClassLoader()); - } - - Thread createThread(Runnable r) { - return new Thread(r); - } -} diff --git a/src/java.naming/share/classes/javax/naming/ldap/StartTlsRequest.java b/src/java.naming/share/classes/javax/naming/ldap/StartTlsRequest.java index 1e519609484..1e45ff511c5 100644 --- a/src/java.naming/share/classes/javax/naming/ldap/StartTlsRequest.java +++ b/src/java.naming/share/classes/javax/naming/ldap/StartTlsRequest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,13 +26,10 @@ package javax.naming.ldap; import java.util.Iterator; -import java.security.AccessController; -import java.security.PrivilegedAction; import javax.naming.ConfigurationException; import javax.naming.NamingException; import com.sun.naming.internal.VersionHelper; import java.util.ServiceLoader; -import java.util.ServiceConfigurationError; /** * This class implements the LDAPv3 Extended Request for StartTLS as @@ -181,10 +178,10 @@ public ExtendedResponse createExtendedResponse(String id, byte[] berValue, StartTlsResponse resp = null; ServiceLoader<StartTlsResponse> sl = ServiceLoader.load( - StartTlsResponse.class, getContextClassLoader()); + StartTlsResponse.class, Thread.currentThread().getContextClassLoader()); Iterator<StartTlsResponse> iter = sl.iterator(); - while (resp == null && privilegedHasNext(iter)) { + while (resp == null && iter.hasNext()) { resp = iter.next(); } if (resp != null) { @@ -216,20 +213,5 @@ private ConfigurationException wrapException(Exception e) { return ce; } - /* - * Acquire the class loader associated with this thread. - */ - @SuppressWarnings("removal") - private final ClassLoader getContextClassLoader() { - PrivilegedAction<ClassLoader> pa = Thread.currentThread()::getContextClassLoader; - return AccessController.doPrivileged(pa); - } - - @SuppressWarnings("removal") - private static final boolean privilegedHasNext(final Iterator<StartTlsResponse> iter) { - PrivilegedAction<Boolean> pa = iter::hasNext; - return AccessController.doPrivileged(pa); - } - private static final long serialVersionUID = 4441679576360753397L; } diff --git a/src/java.naming/share/classes/javax/naming/ldap/spi/LdapDnsProvider.java b/src/java.naming/share/classes/javax/naming/ldap/spi/LdapDnsProvider.java index 0cb240a891c..21fbca5d1e7 100644 --- a/src/java.naming/share/classes/javax/naming/ldap/spi/LdapDnsProvider.java +++ b/src/java.naming/share/classes/javax/naming/ldap/spi/LdapDnsProvider.java @@ -53,29 +53,10 @@ */ public abstract class LdapDnsProvider { - // The {@code RuntimePermission("ldapDnsProvider")} is - // necessary to subclass and instantiate the {@code LdapDnsProvider} class. - private static final RuntimePermission DNSPROVIDER_PERMISSION = - new RuntimePermission("ldapDnsProvider"); - /** * Creates a new instance of {@code LdapDnsProvider}. */ protected LdapDnsProvider() { - this(checkPermission()); - } - - private LdapDnsProvider(Void unused) { - // nothing to do. - } - - private static Void checkPermission() { - @SuppressWarnings("removal") - final SecurityManager sm = System.getSecurityManager(); - if (sm != null) { - sm.checkPermission(DNSPROVIDER_PERMISSION); - } - return null; } /** diff --git a/src/java.naming/share/classes/javax/naming/spi/NamingManager.java b/src/java.naming/share/classes/javax/naming/spi/NamingManager.java index 4d57b541ec1..83f0ec2dd78 100644 --- a/src/java.naming/share/classes/javax/naming/spi/NamingManager.java +++ b/src/java.naming/share/classes/javax/naming/spi/NamingManager.java @@ -25,8 +25,6 @@ package javax.naming.spi; -import java.security.AccessController; -import java.security.PrivilegedAction; import java.util.*; import javax.naming.*; @@ -471,7 +469,6 @@ private static Object getURLObject(String scheme, Object urlInfo, * @see javax.naming.InitialContext * @see javax.naming.directory.InitialDirContext */ - @SuppressWarnings("removal") public static Context getInitialContext(Hashtable<?,?> env) throws NamingException { ClassLoader loader; @@ -492,16 +489,8 @@ public static Context getInitialContext(Hashtable<?,?> env) throw ne; } - if (System.getSecurityManager() == null) { - loader = Thread.currentThread().getContextClassLoader(); - if (loader == null) loader = ClassLoader.getSystemClassLoader(); - } else { - PrivilegedAction<ClassLoader> pa = () -> { - ClassLoader cl = Thread.currentThread().getContextClassLoader(); - return (cl == null) ? ClassLoader.getSystemClassLoader() : cl; - }; - loader = AccessController.doPrivileged(pa); - } + loader = Thread.currentThread().getContextClassLoader(); + if (loader == null) loader = ClassLoader.getSystemClassLoader(); var key = FACTORIES_CACHE.sub(className); try { @@ -570,12 +559,6 @@ public static synchronized void setInitialContextFactoryBuilder( if (initctx_factory_builder != null) throw new IllegalStateException( "InitialContextFactoryBuilder already set"); - - @SuppressWarnings("removal") - SecurityManager security = System.getSecurityManager(); - if (security != null) { - security.checkSetFactory(); - } initctx_factory_builder = builder; } diff --git a/src/java.naming/share/classes/sun/security/provider/certpath/ldap/JdkLDAP.java b/src/java.naming/share/classes/sun/security/provider/certpath/ldap/JdkLDAP.java index d03a4f06221..b42c6971126 100644 --- a/src/java.naming/share/classes/sun/security/provider/certpath/ldap/JdkLDAP.java +++ b/src/java.naming/share/classes/sun/security/provider/certpath/ldap/JdkLDAP.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -69,25 +69,20 @@ public Object newInstance(Object ctrParamObj) } } - @SuppressWarnings("removal") public JdkLDAP() { super("JdkLDAP", PROVIDER_VER, "JdkLDAP Provider (implements LDAP CertStore)"); final Provider p = this; - PrivilegedAction<Void> pa = () -> { - HashMap<String, String> attrs = new HashMap<>(2); - attrs.put("LDAPSchema", "RFC2587"); - attrs.put("ImplementedIn", "Software"); + HashMap<String, String> attrs = new HashMap<>(2); + attrs.put("LDAPSchema", "RFC2587"); + attrs.put("ImplementedIn", "Software"); - /* - * CertStore - * attrs: LDAPSchema, ImplementedIn - */ - putService(new ProviderService(p, "CertStore", - "LDAP", "sun.security.provider.certpath.ldap.LDAPCertStore", - null, attrs)); - return null; - }; - AccessController.doPrivileged(pa); + /* + * CertStore + * attrs: LDAPSchema, ImplementedIn + */ + putService(new ProviderService(p, "CertStore", + "LDAP", "sun.security.provider.certpath.ldap.LDAPCertStore", + null, attrs)); } } diff --git a/src/java.naming/share/classes/sun/security/provider/certpath/ldap/LDAPCertStore.java b/src/java.naming/share/classes/sun/security/provider/certpath/ldap/LDAPCertStore.java index 7ff6dc8d925..b12e53cb7ec 100644 --- a/src/java.naming/share/classes/sun/security/provider/certpath/ldap/LDAPCertStore.java +++ b/src/java.naming/share/classes/sun/security/provider/certpath/ldap/LDAPCertStore.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -136,12 +136,6 @@ public LDAPCertStore(CertStoreParameters params) + params.getClass().getName() + " passed"); } - @SuppressWarnings("removal") - SecurityManager security = System.getSecurityManager(); - if (security != null) { - security.checkConnect(serverName, port); - } - Key k = new Key(serverName, port); LDAPCertStoreImpl lci = certStoreCache.get(k); if (lci == null) { diff --git a/src/java.naming/share/classes/sun/security/provider/certpath/ldap/LDAPCertStoreImpl.java b/src/java.naming/share/classes/sun/security/provider/certpath/ldap/LDAPCertStoreImpl.java index 39a787bf4fb..8f18e04760a 100644 --- a/src/java.naming/share/classes/sun/security/provider/certpath/ldap/LDAPCertStoreImpl.java +++ b/src/java.naming/share/classes/sun/security/provider/certpath/ldap/LDAPCertStoreImpl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2023, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -97,9 +97,7 @@ final class LDAPCertStoreImpl { "sun.security.certpath.ldap.disable.app.resource.files"; static { - @SuppressWarnings("removal") - String s = AccessController.doPrivileged( - (PrivilegedAction<String>) () -> System.getProperty(PROP_LIFETIME)); + String s = System.getProperty(PROP_LIFETIME); if (s != null) { LIFETIME = Integer.parseInt(s); // throws NumberFormatException } else { @@ -172,9 +170,8 @@ private void createInitialDirContext(String server, int port) env.put(Context.PROVIDER_URL, url); // If property is set to true, disable application resource file lookup. - @SuppressWarnings("removal") - boolean disableAppResourceFiles = AccessController.doPrivileged( - (PrivilegedAction<Boolean>) () -> Boolean.getBoolean(PROP_DISABLE_APP_RESOURCE_FILES)); + boolean disableAppResourceFiles = + Boolean.getBoolean(PROP_DISABLE_APP_RESOURCE_FILES); if (disableAppResourceFiles) { if (debug != null) { debug.println("LDAPCertStore disabling app resource files"); diff --git a/src/jdk.naming.dns/share/classes/com/sun/jndi/dns/DNSDatagramChannelFactory.java b/src/jdk.naming.dns/share/classes/com/sun/jndi/dns/DNSDatagramChannelFactory.java index 73585c23f86..a278987ad3b 100644 --- a/src/jdk.naming.dns/share/classes/com/sun/jndi/dns/DNSDatagramChannelFactory.java +++ b/src/jdk.naming.dns/share/classes/com/sun/jndi/dns/DNSDatagramChannelFactory.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -29,8 +29,6 @@ import java.net.ProtocolFamily; import java.net.InetSocketAddress; import java.nio.channels.DatagramChannel; -import java.security.AccessController; -import java.security.PrivilegedExceptionAction; import java.util.Objects; import java.util.Random; @@ -52,11 +50,9 @@ private EphemeralPortRange() {} } private static int findFirstFreePort() { - PrivilegedExceptionAction<DatagramSocket> action = () -> new DatagramSocket(0); int port; try { - @SuppressWarnings({"deprecated", "removal"}) - DatagramSocket ds = AccessController.doPrivileged(action); + DatagramSocket ds = new DatagramSocket(0); try (DatagramSocket ds1 = ds) { port = ds1.getLocalPort(); } diff --git a/src/jdk.naming.dns/share/classes/com/sun/jndi/dns/DnsContextFactory.java b/src/jdk.naming.dns/share/classes/com/sun/jndi/dns/DnsContextFactory.java index 7b8a30a52d0..645fac074e5 100644 --- a/src/jdk.naming.dns/share/classes/com/sun/jndi/dns/DnsContextFactory.java +++ b/src/jdk.naming.dns/share/classes/com/sun/jndi/dns/DnsContextFactory.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2021, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -90,9 +90,8 @@ public static DnsContext getContext(String domain, * Public for use by product test suite. */ public static boolean platformServersAvailable() { - return !filterNameServers( - ResolverConfiguration.open().nameservers(), true - ).isEmpty(); + return !ResolverConfiguration + .open().nameservers().isEmpty(); } private static Context urlToContext(String url, Hashtable<?,?> env) @@ -145,8 +144,8 @@ private static String[] serversForUrls(DnsUrl[] urls) // No server or port given, so look to underlying platform. // ResolverConfiguration does some limited caching, so the // following is reasonably efficient even if called rapid-fire. - List<String> platformServers = filterNameServers( - ResolverConfiguration.open().nameservers(), false); + List<String> platformServers = + ResolverConfiguration.open().nameservers(); if (!platformServers.isEmpty()) { servers.addAll(platformServers); continue; // on to next URL (if any, which is unlikely) @@ -216,42 +215,4 @@ private static String getInitCtxUrl(Hashtable<?,?> env) { String url = (String) env.get(Context.PROVIDER_URL); return ((url != null) ? url : DEFAULT_URL); } - - /** - * Removes any DNS server that's not permitted to access - * @param input the input server[:port] list, must not be null - * @param oneIsEnough return output once there exists one ok - * @return the filtered list, all non-permitted input removed - */ - private static List<String> filterNameServers(List<String> input, boolean oneIsEnough) { - @SuppressWarnings("removal") - SecurityManager security = System.getSecurityManager(); - if (security == null || input == null || input.isEmpty()) { - return input; - } else { - List<String> output = new ArrayList<>(); - for (String platformServer: input) { - int colon = platformServer.indexOf(':', - platformServer.indexOf(']') + 1); - - int p = (colon < 0) - ? DEFAULT_PORT - : Integer.parseInt( - platformServer.substring(colon + 1)); - String s = (colon < 0) - ? platformServer - : platformServer.substring(0, colon); - try { - security.checkConnect(s, p); - output.add(platformServer); - if (oneIsEnough) { - return output; - } - } catch (SecurityException se) { - continue; - } - } - return output; - } - } } diff --git a/src/jdk.naming.dns/share/classes/com/sun/jndi/dns/DnsUrl.java b/src/jdk.naming.dns/share/classes/com/sun/jndi/dns/DnsUrl.java index 5d5703c85eb..6c6b42021c9 100644 --- a/src/jdk.naming.dns/share/classes/com/sun/jndi/dns/DnsUrl.java +++ b/src/jdk.naming.dns/share/classes/com/sun/jndi/dns/DnsUrl.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2000, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -29,8 +29,6 @@ import java.net.MalformedURLException; import java.net.URI; import java.net.URISyntaxException; -import java.security.AccessController; -import java.security.PrivilegedAction; import java.util.Locale; import java.util.StringTokenizer; @@ -65,12 +63,10 @@ public class DnsUrl extends Uri { public static final ParseMode PARSE_MODE; static { - PrivilegedAction<String> action = () -> - System.getProperty(PARSE_MODE_PROP, DEFAULT_PARSE_MODE.toString()); ParseMode parseMode = DEFAULT_PARSE_MODE; try { - @SuppressWarnings("removal") - String mode = AccessController.doPrivileged(action); + String mode = System.getProperty( + PARSE_MODE_PROP, DEFAULT_PARSE_MODE.toString()); parseMode = ParseMode.valueOf(mode.toUpperCase(Locale.ROOT)); } catch (Throwable t) { parseMode = DEFAULT_PARSE_MODE; diff --git a/src/jdk.naming.rmi/share/classes/com/sun/jndi/rmi/registry/RegistryContext.java b/src/jdk.naming.rmi/share/classes/com/sun/jndi/rmi/registry/RegistryContext.java index 5becceb8294..e5090cbaae1 100644 --- a/src/jdk.naming.rmi/share/classes/com/sun/jndi/rmi/registry/RegistryContext.java +++ b/src/jdk.naming.rmi/share/classes/com/sun/jndi/rmi/registry/RegistryContext.java @@ -58,11 +58,6 @@ public class RegistryContext implements Context, Referenceable { Reference reference = null; // ref used to create this context, if any - // Environment property that, if set, indicates that a security - // manager should be installed (if none is already in place). - public static final String SECURITY_MGR = - "java.naming.rmi.security.manager"; - /** * Returns a context for the registry at a given host and port. * If "host" is null, uses default host. @@ -77,9 +72,6 @@ public RegistryContext(String host, int port, Hashtable<?, ?> env) environment = (env == null) ? new Hashtable<String, Object>(5) : (Hashtable<String, Object>) env; - if (environment.get(SECURITY_MGR) != null) { - installSecurityMgr(); - } // chop off '[' and ']' in an IPv6 literal address if ((host != null) && (host.charAt(0) == '[')) { @@ -295,9 +287,6 @@ public Object removeFromEnvironment(String propName) public Object addToEnvironment(String propName, Object propVal) throws NamingException { - if (propName.equals(SECURITY_MGR)) { - installSecurityMgr(); - } return environment.put(propName, propVal); } @@ -412,19 +401,6 @@ private static Registry getRegistry(String host, int port, } } - /** - * Attempts to install a security manager if none is currently in - * place. - */ - @SuppressWarnings("removal") - private static void installSecurityMgr() { - - try { - System.setSecurityManager(new SecurityManager()); - } catch (Exception e) { - } - } - /** * Encodes an object prior to binding it in the registry. First, * NamingManager.getStateToBind() is invoked. If the resulting diff --git a/src/jdk.naming.rmi/share/classes/com/sun/jndi/url/rmi/rmiURLContext.java b/src/jdk.naming.rmi/share/classes/com/sun/jndi/url/rmi/rmiURLContext.java index cfa66ed9174..c2972a87092 100644 --- a/src/jdk.naming.rmi/share/classes/com/sun/jndi/url/rmi/rmiURLContext.java +++ b/src/jdk.naming.rmi/share/classes/com/sun/jndi/url/rmi/rmiURLContext.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2022, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2024, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -26,8 +26,6 @@ package com.sun.jndi.url.rmi; import java.net.URI; -import java.security.AccessController; -import java.security.PrivilegedAction; import java.util.Hashtable; import java.util.Locale; @@ -57,12 +55,9 @@ public class rmiURLContext extends GenericURLContext { public static final ParseMode PARSE_MODE; static { - PrivilegedAction<String> action = () -> - System.getProperty(PARSE_MODE_PROP, DEFAULT_PARSE_MODE.toString()); ParseMode parseMode = DEFAULT_PARSE_MODE; try { - @SuppressWarnings("removal") - String mode = AccessController.doPrivileged(action); + String mode = System.getProperty(PARSE_MODE_PROP, DEFAULT_PARSE_MODE.toString()); parseMode = ParseMode.valueOf(mode.toUpperCase(Locale.ROOT)); } catch (Throwable t) { parseMode = DEFAULT_PARSE_MODE;